From 034dd340b08be1f2f0477ad16131d609f9dbd53c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 30 Aug 2026 09:22:00 -0700 Subject: Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace Pull tracing fixes from Steven Rostedt: - Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. * tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Stop remote reader update when page swap fails tracing: Fix retry exhaustion in simple ring buffer reader swap tracing/user_events: Clear copied tracing state before fork duplication samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify eventfs: Initialize ei->children and ei->list in init_ei() tracing: Fix use-after-free in trace_pipe read on sub-buffer order change tracing: Fix crash passing ERR_PTR to kthread_stop() tracing: Fix use-after-free with same-name named triggers tracing: Fix logged instance name on creation failure --- drivers/net/wireless/realtek/Kconfig | 21 + drivers/net/wireless/realtek/Makefile | 12 + drivers/net/wireless/realtek/rtl818x/Kconfig | 89 + drivers/net/wireless/realtek/rtl818x/Makefile | 3 + .../net/wireless/realtek/rtl818x/rtl8180/Makefile | 6 + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 1991 + .../net/wireless/realtek/rtl818x/rtl8180/grf5101.c | 187 + .../net/wireless/realtek/rtl818x/rtl8180/grf5101.h | 25 + .../net/wireless/realtek/rtl818x/rtl8180/max2820.c | 165 + .../net/wireless/realtek/rtl818x/rtl8180/max2820.h | 25 + .../net/wireless/realtek/rtl818x/rtl8180/rtl8180.h | 186 + .../net/wireless/realtek/rtl818x/rtl8180/rtl8225.c | 767 + .../net/wireless/realtek/rtl818x/rtl8180/rtl8225.h | 24 + .../wireless/realtek/rtl818x/rtl8180/rtl8225se.c | 430 + .../wireless/realtek/rtl818x/rtl8180/rtl8225se.h | 58 + .../net/wireless/realtek/rtl818x/rtl8180/sa2400.c | 225 + .../net/wireless/realtek/rtl818x/rtl8180/sa2400.h | 33 + .../net/wireless/realtek/rtl818x/rtl8187/Makefile | 6 + drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 1697 + .../net/wireless/realtek/rtl818x/rtl8187/leds.c | 242 + .../net/wireless/realtek/rtl818x/rtl8187/leds.h | 56 + .../net/wireless/realtek/rtl818x/rtl8187/rfkill.c | 61 + .../net/wireless/realtek/rtl818x/rtl8187/rfkill.h | 9 + .../net/wireless/realtek/rtl818x/rtl8187/rtl8187.h | 210 + .../net/wireless/realtek/rtl818x/rtl8187/rtl8225.c | 1044 + .../net/wireless/realtek/rtl818x/rtl8187/rtl8225.h | 41 + drivers/net/wireless/realtek/rtl818x/rtl818x.h | 402 + drivers/net/wireless/realtek/rtl8xxxu/8188e.c | 1886 + drivers/net/wireless/realtek/rtl8xxxu/8188f.c | 1766 + drivers/net/wireless/realtek/rtl8xxxu/8192c.c | 742 + drivers/net/wireless/realtek/rtl8xxxu/8192e.c | 1768 + drivers/net/wireless/realtek/rtl8xxxu/8192f.c | 2092 + drivers/net/wireless/realtek/rtl8xxxu/8710b.c | 1876 + drivers/net/wireless/realtek/rtl8xxxu/8723a.c | 649 + drivers/net/wireless/realtek/rtl8xxxu/8723b.c | 1759 + drivers/net/wireless/realtek/rtl8xxxu/Kconfig | 37 + drivers/net/wireless/realtek/rtl8xxxu/Makefile | 6 + drivers/net/wireless/realtek/rtl8xxxu/core.c | 8295 +++ drivers/net/wireless/realtek/rtl8xxxu/regs.h | 1384 + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2181 + drivers/net/wireless/realtek/rtlwifi/Kconfig | 171 + drivers/net/wireless/realtek/rtlwifi/Makefile | 35 + drivers/net/wireless/realtek/rtlwifi/base.c | 2735 + drivers/net/wireless/realtek/rtlwifi/base.h | 129 + .../wireless/realtek/rtlwifi/btcoexist/Makefile | 10 + .../realtek/rtlwifi/btcoexist/halbt_precomp.h | 64 + .../realtek/rtlwifi/btcoexist/halbtc8192e2ant.c | 3196 ++ .../realtek/rtlwifi/btcoexist/halbtc8192e2ant.h | 163 + .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | 3437 ++ .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.h | 203 + .../realtek/rtlwifi/btcoexist/halbtc8723b2ant.c | 4240 ++ .../realtek/rtlwifi/btcoexist/halbtc8723b2ant.h | 183 + .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 2967 + .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.h | 171 + .../realtek/rtlwifi/btcoexist/halbtc8821a2ant.c | 4205 ++ .../realtek/rtlwifi/btcoexist/halbtc8821a2ant.h | 211 + .../rtlwifi/btcoexist/halbtc8822bwifionly.c | 44 + .../rtlwifi/btcoexist/halbtc8822bwifionly.h | 14 + .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 1893 + .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 824 + .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c | 521 + .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.h | 54 + drivers/net/wireless/realtek/rtlwifi/cam.c | 321 + drivers/net/wireless/realtek/rtlwifi/cam.h | 28 + drivers/net/wireless/realtek/rtlwifi/core.c | 1958 + drivers/net/wireless/realtek/rtlwifi/core.h | 66 + drivers/net/wireless/realtek/rtlwifi/debug.c | 514 + drivers/net/wireless/realtek/rtlwifi/debug.h | 209 + drivers/net/wireless/realtek/rtlwifi/efuse.c | 1373 + drivers/net/wireless/realtek/rtlwifi/efuse.h | 98 + drivers/net/wireless/realtek/rtlwifi/pci.c | 2386 + drivers/net/wireless/realtek/rtlwifi/pci.h | 282 + drivers/net/wireless/realtek/rtlwifi/ps.c | 983 + drivers/net/wireless/realtek/rtlwifi/ps.h | 28 + drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h | 72 + drivers/net/wireless/realtek/rtlwifi/rc.c | 318 + drivers/net/wireless/realtek/rtlwifi/rc.h | 26 + drivers/net/wireless/realtek/rtlwifi/regd.c | 434 + drivers/net/wireless/realtek/rtlwifi/regd.h | 41 + .../wireless/realtek/rtlwifi/rtl8188ee/Makefile | 14 + .../net/wireless/realtek/rtlwifi/rtl8188ee/def.h | 183 + .../net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 1784 + .../net/wireless/realtek/rtlwifi/rtl8188ee/dm.h | 260 + .../net/wireless/realtek/rtlwifi/rtl8188ee/fw.c | 721 + .../net/wireless/realtek/rtlwifi/rtl8188ee/fw.h | 233 + .../net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 2515 + .../net/wireless/realtek/rtlwifi/rtl8188ee/hw.h | 41 + .../net/wireless/realtek/rtlwifi/rtl8188ee/led.c | 111 + .../net/wireless/realtek/rtlwifi/rtl8188ee/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8188ee/phy.c | 2293 + .../net/wireless/realtek/rtlwifi/rtl8188ee/phy.h | 211 + .../wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c | 83 + .../wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h | 289 + .../net/wireless/realtek/rtlwifi/rtl8188ee/reg.h | 2249 + .../net/wireless/realtek/rtlwifi/rtl8188ee/rf.c | 486 + .../net/wireless/realtek/rtlwifi/rtl8188ee/rf.h | 20 + .../net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 390 + .../net/wireless/realtek/rtlwifi/rtl8188ee/table.c | 615 + .../net/wireless/realtek/rtlwifi/rtl8188ee/table.h | 19 + .../net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 832 + .../net/wireless/realtek/rtlwifi/rtl8188ee/trx.h | 801 + .../net/wireless/realtek/rtlwifi/rtl8192c/Makefile | 8 + .../wireless/realtek/rtlwifi/rtl8192c/dm_common.c | 1738 + .../wireless/realtek/rtlwifi/rtl8192c/dm_common.h | 121 + .../wireless/realtek/rtlwifi/rtl8192c/fw_common.c | 770 + .../wireless/realtek/rtlwifi/rtl8192c/fw_common.h | 75 + .../net/wireless/realtek/rtlwifi/rtl8192c/main.c | 13 + .../wireless/realtek/rtlwifi/rtl8192c/phy_common.c | 1615 + .../wireless/realtek/rtlwifi/rtl8192c/phy_common.h | 227 + .../wireless/realtek/rtlwifi/rtl8192ce/Makefile | 12 + .../net/wireless/realtek/rtlwifi/rtl8192ce/def.h | 113 + .../net/wireless/realtek/rtlwifi/rtl8192ce/dm.c | 84 + .../net/wireless/realtek/rtlwifi/rtl8192ce/dm.h | 60 + .../net/wireless/realtek/rtlwifi/rtl8192ce/hw.c | 2324 + .../net/wireless/realtek/rtlwifi/rtl8192ce/hw.h | 53 + .../net/wireless/realtek/rtlwifi/rtl8192ce/led.c | 106 + .../net/wireless/realtek/rtlwifi/rtl8192ce/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192ce/phy.c | 517 + .../net/wireless/realtek/rtlwifi/rtl8192ce/phy.h | 116 + .../net/wireless/realtek/rtlwifi/rtl8192ce/reg.h | 2030 + .../net/wireless/realtek/rtlwifi/rtl8192ce/rf.c | 482 + .../net/wireless/realtek/rtlwifi/rtl8192ce/rf.h | 16 + .../net/wireless/realtek/rtlwifi/rtl8192ce/sw.c | 370 + .../net/wireless/realtek/rtlwifi/rtl8192ce/table.c | 1195 + .../net/wireless/realtek/rtlwifi/rtl8192ce/table.h | 30 + .../net/wireless/realtek/rtlwifi/rtl8192ce/trx.c | 686 + .../net/wireless/realtek/rtlwifi/rtl8192ce/trx.h | 531 + .../wireless/realtek/rtlwifi/rtl8192cu/Makefile | 13 + .../net/wireless/realtek/rtlwifi/rtl8192cu/def.h | 20 + .../net/wireless/realtek/rtlwifi/rtl8192cu/dm.c | 90 + .../net/wireless/realtek/rtlwifi/rtl8192cu/dm.h | 9 + .../net/wireless/realtek/rtlwifi/rtl8192cu/hw.c | 2171 + .../net/wireless/realtek/rtlwifi/rtl8192cu/hw.h | 83 + .../net/wireless/realtek/rtlwifi/rtl8192cu/led.c | 80 + .../net/wireless/realtek/rtlwifi/rtl8192cu/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192cu/mac.c | 747 + .../net/wireless/realtek/rtlwifi/rtl8192cu/mac.h | 132 + .../net/wireless/realtek/rtlwifi/rtl8192cu/phy.c | 509 + .../net/wireless/realtek/rtlwifi/rtl8192cu/phy.h | 24 + .../net/wireless/realtek/rtlwifi/rtl8192cu/reg.h | 4 + .../net/wireless/realtek/rtlwifi/rtl8192cu/rf.c | 442 + .../net/wireless/realtek/rtlwifi/rtl8192cu/rf.h | 23 + .../net/wireless/realtek/rtlwifi/rtl8192cu/sw.c | 385 + .../net/wireless/realtek/rtlwifi/rtl8192cu/table.c | 1862 + .../net/wireless/realtek/rtlwifi/rtl8192cu/table.h | 45 + .../net/wireless/realtek/rtlwifi/rtl8192cu/trx.c | 644 + .../net/wireless/realtek/rtlwifi/rtl8192cu/trx.h | 397 + .../net/wireless/realtek/rtlwifi/rtl8192d/Makefile | 11 + .../net/wireless/realtek/rtlwifi/rtl8192d/def.h | 175 + .../wireless/realtek/rtlwifi/rtl8192d/dm_common.c | 1061 + .../wireless/realtek/rtlwifi/rtl8192d/dm_common.h | 79 + .../wireless/realtek/rtlwifi/rtl8192d/fw_common.c | 370 + .../wireless/realtek/rtlwifi/rtl8192d/fw_common.h | 49 + .../wireless/realtek/rtlwifi/rtl8192d/hw_common.c | 1220 + .../wireless/realtek/rtlwifi/rtl8192d/hw_common.h | 24 + .../net/wireless/realtek/rtlwifi/rtl8192d/main.c | 9 + .../wireless/realtek/rtlwifi/rtl8192d/phy_common.c | 856 + .../wireless/realtek/rtlwifi/rtl8192d/phy_common.h | 111 + .../net/wireless/realtek/rtlwifi/rtl8192d/reg.h | 1393 + .../wireless/realtek/rtlwifi/rtl8192d/rf_common.c | 359 + .../wireless/realtek/rtlwifi/rtl8192d/rf_common.h | 13 + .../wireless/realtek/rtlwifi/rtl8192d/trx_common.c | 516 + .../wireless/realtek/rtlwifi/rtl8192d/trx_common.h | 405 + .../wireless/realtek/rtlwifi/rtl8192de/Makefile | 13 + .../net/wireless/realtek/rtlwifi/rtl8192de/dm.c | 184 + .../net/wireless/realtek/rtlwifi/rtl8192de/dm.h | 10 + .../net/wireless/realtek/rtlwifi/rtl8192de/fw.c | 320 + .../net/wireless/realtek/rtlwifi/rtl8192de/fw.h | 10 + .../net/wireless/realtek/rtlwifi/rtl8192de/hw.c | 1087 + .../net/wireless/realtek/rtlwifi/rtl8192de/hw.h | 29 + .../net/wireless/realtek/rtlwifi/rtl8192de/led.c | 114 + .../net/wireless/realtek/rtlwifi/rtl8192de/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 2726 + .../net/wireless/realtek/rtlwifi/rtl8192de/phy.h | 89 + .../net/wireless/realtek/rtlwifi/rtl8192de/rf.c | 227 + .../net/wireless/realtek/rtlwifi/rtl8192de/rf.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 397 + .../net/wireless/realtek/rtlwifi/rtl8192de/sw.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192de/table.c | 1663 + .../net/wireless/realtek/rtlwifi/rtl8192de/table.h | 30 + .../net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 314 + .../net/wireless/realtek/rtlwifi/rtl8192de/trx.h | 136 + .../wireless/realtek/rtlwifi/rtl8192du/Makefile | 13 + .../net/wireless/realtek/rtlwifi/rtl8192du/dm.c | 120 + .../net/wireless/realtek/rtlwifi/rtl8192du/dm.h | 10 + .../net/wireless/realtek/rtlwifi/rtl8192du/fw.c | 63 + .../net/wireless/realtek/rtlwifi/rtl8192du/fw.h | 9 + .../net/wireless/realtek/rtlwifi/rtl8192du/hw.c | 1212 + .../net/wireless/realtek/rtlwifi/rtl8192du/hw.h | 22 + .../net/wireless/realtek/rtlwifi/rtl8192du/led.c | 10 + .../net/wireless/realtek/rtlwifi/rtl8192du/led.h | 9 + .../net/wireless/realtek/rtlwifi/rtl8192du/phy.c | 3118 + .../net/wireless/realtek/rtlwifi/rtl8192du/phy.h | 31 + .../net/wireless/realtek/rtlwifi/rtl8192du/rf.c | 240 + .../net/wireless/realtek/rtlwifi/rtl8192du/rf.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192du/sw.c | 398 + .../net/wireless/realtek/rtlwifi/rtl8192du/table.c | 1675 + .../net/wireless/realtek/rtlwifi/rtl8192du/table.h | 29 + .../net/wireless/realtek/rtlwifi/rtl8192du/trx.c | 373 + .../net/wireless/realtek/rtlwifi/rtl8192du/trx.h | 60 + .../wireless/realtek/rtlwifi/rtl8192ee/Makefile | 15 + .../net/wireless/realtek/rtlwifi/rtl8192ee/def.h | 71 + .../net/wireless/realtek/rtlwifi/rtl8192ee/dm.c | 1086 + .../net/wireless/realtek/rtlwifi/rtl8192ee/dm.h | 229 + .../net/wireless/realtek/rtlwifi/rtl8192ee/fw.c | 863 + .../net/wireless/realtek/rtlwifi/rtl8192ee/fw.h | 159 + .../net/wireless/realtek/rtlwifi/rtl8192ee/hw.c | 2609 + .../net/wireless/realtek/rtlwifi/rtl8192ee/hw.h | 41 + .../net/wireless/realtek/rtlwifi/rtl8192ee/led.c | 105 + .../net/wireless/realtek/rtlwifi/rtl8192ee/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192ee/phy.c | 3164 + .../net/wireless/realtek/rtlwifi/rtl8192ee/phy.h | 130 + .../wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c | 90 + .../wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h | 318 + .../net/wireless/realtek/rtlwifi/rtl8192ee/reg.h | 2211 + .../net/wireless/realtek/rtlwifi/rtl8192ee/rf.c | 129 + .../net/wireless/realtek/rtlwifi/rtl8192ee/rf.h | 13 + .../net/wireless/realtek/rtlwifi/rtl8192ee/sw.c | 378 + .../net/wireless/realtek/rtlwifi/rtl8192ee/table.c | 858 + .../net/wireless/realtek/rtlwifi/rtl8192ee/table.h | 21 + .../net/wireless/realtek/rtlwifi/rtl8192ee/trx.c | 1045 + .../net/wireless/realtek/rtlwifi/rtl8192ee/trx.h | 744 + .../wireless/realtek/rtlwifi/rtl8192se/Makefile | 14 + .../net/wireless/realtek/rtlwifi/rtl8192se/def.h | 431 + .../net/wireless/realtek/rtlwifi/rtl8192se/dm.c | 717 + .../net/wireless/realtek/rtlwifi/rtl8192se/dm.h | 67 + .../net/wireless/realtek/rtlwifi/rtl8192se/fw.c | 616 + .../net/wireless/realtek/rtlwifi/rtl8192se/fw.h | 350 + .../net/wireless/realtek/rtlwifi/rtl8192se/hw.c | 2512 + .../net/wireless/realtek/rtlwifi/rtl8192se/hw.h | 53 + .../net/wireless/realtek/rtlwifi/rtl8192se/led.c | 106 + .../net/wireless/realtek/rtlwifi/rtl8192se/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8192se/phy.c | 1610 + .../net/wireless/realtek/rtlwifi/rtl8192se/phy.h | 77 + .../net/wireless/realtek/rtlwifi/rtl8192se/reg.h | 1143 + .../net/wireless/realtek/rtlwifi/rtl8192se/rf.c | 507 + .../net/wireless/realtek/rtlwifi/rtl8192se/rf.h | 18 + .../net/wireless/realtek/rtlwifi/rtl8192se/sw.c | 418 + .../net/wireless/realtek/rtlwifi/rtl8192se/table.c | 607 + .../net/wireless/realtek/rtlwifi/rtl8192se/table.h | 31 + .../net/wireless/realtek/rtlwifi/rtl8192se/trx.c | 638 + .../net/wireless/realtek/rtlwifi/rtl8192se/trx.h | 24 + .../wireless/realtek/rtlwifi/rtl8723ae/Makefile | 17 + .../net/wireless/realtek/rtlwifi/rtl8723ae/btc.h | 15 + .../net/wireless/realtek/rtlwifi/rtl8723ae/def.h | 160 + .../net/wireless/realtek/rtlwifi/rtl8723ae/dm.c | 840 + .../net/wireless/realtek/rtlwifi/rtl8723ae/dm.h | 110 + .../net/wireless/realtek/rtlwifi/rtl8723ae/fw.c | 581 + .../net/wireless/realtek/rtlwifi/rtl8723ae/fw.h | 41 + .../realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c | 515 + .../realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h | 133 + .../wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c | 1756 + .../wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h | 138 + .../net/wireless/realtek/rtlwifi/rtl8723ae/hw.c | 2393 + .../net/wireless/realtek/rtlwifi/rtl8723ae/hw.h | 46 + .../net/wireless/realtek/rtlwifi/rtl8723ae/led.c | 114 + .../net/wireless/realtek/rtlwifi/rtl8723ae/led.h | 11 + .../net/wireless/realtek/rtlwifi/rtl8723ae/phy.c | 1665 + .../net/wireless/realtek/rtlwifi/rtl8723ae/phy.h | 180 + .../wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c | 90 + .../wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h | 318 + .../net/wireless/realtek/rtlwifi/rtl8723ae/reg.h | 2098 + .../net/wireless/realtek/rtlwifi/rtl8723ae/rf.c | 491 + .../net/wireless/realtek/rtlwifi/rtl8723ae/rf.h | 17 + .../net/wireless/realtek/rtlwifi/rtl8723ae/sw.c | 386 + .../net/wireless/realtek/rtlwifi/rtl8723ae/table.c | 704 + .../net/wireless/realtek/rtlwifi/rtl8723ae/table.h | 20 + .../net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 687 + .../net/wireless/realtek/rtlwifi/rtl8723ae/trx.h | 534 + .../wireless/realtek/rtlwifi/rtl8723be/Makefile | 15 + .../net/wireless/realtek/rtlwifi/rtl8723be/def.h | 62 + .../net/wireless/realtek/rtlwifi/rtl8723be/dm.c | 1266 + .../net/wireless/realtek/rtlwifi/rtl8723be/dm.h | 248 + .../net/wireless/realtek/rtlwifi/rtl8723be/fw.c | 685 + .../net/wireless/realtek/rtlwifi/rtl8723be/fw.h | 123 + .../net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 2718 + .../net/wireless/realtek/rtlwifi/rtl8723be/hw.h | 41 + .../net/wireless/realtek/rtlwifi/rtl8723be/led.c | 112 + .../net/wireless/realtek/rtlwifi/rtl8723be/led.h | 12 + .../net/wireless/realtek/rtlwifi/rtl8723be/phy.c | 2656 + .../net/wireless/realtek/rtlwifi/rtl8723be/phy.h | 113 + .../wireless/realtek/rtlwifi/rtl8723be/pwrseq.c | 84 + .../wireless/realtek/rtlwifi/rtl8723be/pwrseq.h | 401 + .../net/wireless/realtek/rtlwifi/rtl8723be/reg.h | 2273 + .../net/wireless/realtek/rtlwifi/rtl8723be/rf.c | 489 + .../net/wireless/realtek/rtlwifi/rtl8723be/rf.h | 20 + .../net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 394 + .../net/wireless/realtek/rtlwifi/rtl8723be/table.c | 597 + .../net/wireless/realtek/rtlwifi/rtl8723be/table.h | 19 + .../net/wireless/realtek/rtlwifi/rtl8723be/trx.c | 743 + .../net/wireless/realtek/rtlwifi/rtl8723be/trx.h | 646 + .../wireless/realtek/rtlwifi/rtl8723com/Makefile | 8 + .../realtek/rtlwifi/rtl8723com/dm_common.c | 43 + .../realtek/rtlwifi/rtl8723com/dm_common.h | 11 + .../realtek/rtlwifi/rtl8723com/fw_common.c | 217 + .../realtek/rtlwifi/rtl8723com/fw_common.h | 70 + .../net/wireless/realtek/rtlwifi/rtl8723com/main.c | 11 + .../realtek/rtlwifi/rtl8723com/phy_common.c | 411 + .../realtek/rtlwifi/rtl8723com/phy_common.h | 66 + .../wireless/realtek/rtlwifi/rtl8821ae/Makefile | 15 + .../net/wireless/realtek/rtlwifi/rtl8821ae/def.h | 269 + .../net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | 2795 + .../net/wireless/realtek/rtlwifi/rtl8821ae/dm.h | 293 + .../net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 1901 + .../net/wireless/realtek/rtlwifi/rtl8821ae/fw.h | 293 + .../net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 4028 ++ .../net/wireless/realtek/rtlwifi/rtl8821ae/hw.h | 48 + .../net/wireless/realtek/rtlwifi/rtl8821ae/led.c | 191 + .../net/wireless/realtek/rtlwifi/rtl8821ae/led.h | 14 + .../net/wireless/realtek/rtlwifi/rtl8821ae/phy.c | 4787 ++ .../net/wireless/realtek/rtlwifi/rtl8821ae/phy.h | 236 + .../wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c | 160 + .../wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h | 716 + .../net/wireless/realtek/rtlwifi/rtl8821ae/reg.h | 2444 + .../net/wireless/realtek/rtlwifi/rtl8821ae/rf.c | 440 + .../net/wireless/realtek/rtlwifi/rtl8821ae/rf.h | 20 + .../net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 446 + .../net/wireless/realtek/rtlwifi/rtl8821ae/table.c | 4033 ++ .../net/wireless/realtek/rtlwifi/rtl8821ae/table.h | 34 + .../net/wireless/realtek/rtlwifi/rtl8821ae/trx.c | 990 + .../net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 652 + drivers/net/wireless/realtek/rtlwifi/stats.c | 247 + drivers/net/wireless/realtek/rtlwifi/stats.h | 20 + drivers/net/wireless/realtek/rtlwifi/usb.c | 1075 + drivers/net/wireless/realtek/rtlwifi/usb.h | 142 + drivers/net/wireless/realtek/rtlwifi/wifi.h | 3038 + drivers/net/wireless/realtek/rtw88/Kconfig | 271 + drivers/net/wireless/realtek/rtw88/Makefile | 113 + drivers/net/wireless/realtek/rtw88/bf.c | 418 + drivers/net/wireless/realtek/rtw88/bf.h | 124 + drivers/net/wireless/realtek/rtw88/coex.c | 4205 ++ drivers/net/wireless/realtek/rtw88/coex.h | 433 + drivers/net/wireless/realtek/rtw88/debug.c | 1375 + drivers/net/wireless/realtek/rtw88/debug.h | 76 + drivers/net/wireless/realtek/rtw88/efuse.c | 187 + drivers/net/wireless/realtek/rtw88/efuse.h | 29 + drivers/net/wireless/realtek/rtw88/fw.c | 2471 + drivers/net/wireless/realtek/rtw88/fw.h | 900 + drivers/net/wireless/realtek/rtw88/hci.h | 289 + drivers/net/wireless/realtek/rtw88/led.c | 74 + drivers/net/wireless/realtek/rtw88/led.h | 25 + drivers/net/wireless/realtek/rtw88/mac.c | 1421 + drivers/net/wireless/realtek/rtw88/mac.h | 51 + drivers/net/wireless/realtek/rtw88/mac80211.c | 997 + drivers/net/wireless/realtek/rtw88/main.c | 2514 + drivers/net/wireless/realtek/rtw88/main.h | 2287 + drivers/net/wireless/realtek/rtw88/pci.c | 1940 + drivers/net/wireless/realtek/rtw88/pci.h | 280 + drivers/net/wireless/realtek/rtw88/phy.c | 2699 + drivers/net/wireless/realtek/rtw88/phy.h | 204 + drivers/net/wireless/realtek/rtw88/ps.c | 343 + drivers/net/wireless/realtek/rtw88/ps.h | 28 + drivers/net/wireless/realtek/rtw88/reg.h | 1004 + drivers/net/wireless/realtek/rtw88/regd.c | 541 + drivers/net/wireless/realtek/rtw88/regd.h | 73 + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2008 + drivers/net/wireless/realtek/rtw88/rtw8703b.h | 102 + .../net/wireless/realtek/rtw88/rtw8703b_tables.c | 902 + .../net/wireless/realtek/rtw88/rtw8703b_tables.h | 14 + drivers/net/wireless/realtek/rtw88/rtw8723cs.c | 34 + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 2212 + drivers/net/wireless/realtek/rtw88/rtw8723d.h | 39 + .../net/wireless/realtek/rtw88/rtw8723d_table.c | 1196 + .../net/wireless/realtek/rtw88/rtw8723d_table.h | 15 + drivers/net/wireless/realtek/rtw88/rtw8723de.c | 32 + drivers/net/wireless/realtek/rtw88/rtw8723ds.c | 41 + drivers/net/wireless/realtek/rtw88/rtw8723du.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 789 + drivers/net/wireless/realtek/rtw88/rtw8723x.h | 524 + drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1125 + drivers/net/wireless/realtek/rtw88/rtw8812a.h | 10 + .../net/wireless/realtek/rtw88/rtw8812a_table.c | 2812 + .../net/wireless/realtek/rtw88/rtw8812a_table.h | 26 + drivers/net/wireless/realtek/rtw88/rtw8812au.c | 94 + drivers/net/wireless/realtek/rtw88/rtw8814a.c | 2271 + drivers/net/wireless/realtek/rtw88/rtw8814a.h | 62 + .../net/wireless/realtek/rtw88/rtw8814a_table.c | 23930 ++++++++ .../net/wireless/realtek/rtw88/rtw8814a_table.h | 40 + drivers/net/wireless/realtek/rtw88/rtw8814ae.c | 31 + drivers/net/wireless/realtek/rtw88/rtw8814au.c | 54 + drivers/net/wireless/realtek/rtw88/rtw8821a.c | 1231 + drivers/net/wireless/realtek/rtw88/rtw8821a.h | 10 + .../net/wireless/realtek/rtw88/rtw8821a_table.c | 2350 + .../net/wireless/realtek/rtw88/rtw8821a_table.h | 21 + drivers/net/wireless/realtek/rtw88/rtw8821au.c | 78 + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2071 + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 287 + .../net/wireless/realtek/rtw88/rtw8821c_table.c | 7504 +++ .../net/wireless/realtek/rtw88/rtw8821c_table.h | 16 + drivers/net/wireless/realtek/rtw88/rtw8821ce.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8821cs.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8821cu.c | 62 + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2621 + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 189 + .../net/wireless/realtek/rtw88/rtw8822b_table.c | 22204 +++++++ .../net/wireless/realtek/rtw88/rtw8822b_table.h | 20 + drivers/net/wireless/realtek/rtw88/rtw8822be.c | 32 + drivers/net/wireless/realtek/rtw88/rtw8822bs.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8822bu.c | 104 + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 5451 ++ drivers/net/wireless/realtek/rtw88/rtw8822c.h | 429 + .../net/wireless/realtek/rtw88/rtw8822c_table.c | 46105 +++++++++++++++ .../net/wireless/realtek/rtw88/rtw8822c_table.h | 21 + drivers/net/wireless/realtek/rtw88/rtw8822ce.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8822cs.c | 36 + drivers/net/wireless/realtek/rtw88/rtw8822cu.c | 46 + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 1990 + drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 175 + drivers/net/wireless/realtek/rtw88/rx.c | 333 + drivers/net/wireless/realtek/rtw88/rx.h | 65 + drivers/net/wireless/realtek/rtw88/sar.c | 114 + drivers/net/wireless/realtek/rtw88/sar.h | 22 + drivers/net/wireless/realtek/rtw88/sdio.c | 1443 + drivers/net/wireless/realtek/rtw88/sdio.h | 178 + drivers/net/wireless/realtek/rtw88/sec.c | 145 + drivers/net/wireless/realtek/rtw88/sec.h | 40 + drivers/net/wireless/realtek/rtw88/tx.c | 746 + drivers/net/wireless/realtek/rtw88/tx.h | 143 + drivers/net/wireless/realtek/rtw88/usb.c | 1392 + drivers/net/wireless/realtek/rtw88/usb.h | 103 + drivers/net/wireless/realtek/rtw88/util.c | 208 + drivers/net/wireless/realtek/rtw88/util.h | 43 + drivers/net/wireless/realtek/rtw88/wow.c | 913 + drivers/net/wireless/realtek/rtw88/wow.h | 58 + drivers/net/wireless/realtek/rtw89/Kconfig | 222 + drivers/net/wireless/realtek/rtw89/Makefile | 110 + drivers/net/wireless/realtek/rtw89/acpi.c | 1281 + drivers/net/wireless/realtek/rtw89/acpi.h | 298 + drivers/net/wireless/realtek/rtw89/cam.c | 1276 + drivers/net/wireless/realtek/rtw89/cam.h | 481 + drivers/net/wireless/realtek/rtw89/chan.c | 3535 ++ drivers/net/wireless/realtek/rtw89/chan.h | 220 + drivers/net/wireless/realtek/rtw89/coex.c | 13370 +++++ drivers/net/wireless/realtek/rtw89/coex.h | 460 + drivers/net/wireless/realtek/rtw89/core.c | 7738 +++ drivers/net/wireless/realtek/rtw89/core.h | 9391 +++ drivers/net/wireless/realtek/rtw89/debug.c | 5725 ++ drivers/net/wireless/realtek/rtw89/debug.h | 102 + drivers/net/wireless/realtek/rtw89/efuse.c | 521 + drivers/net/wireless/realtek/rtw89/efuse.h | 43 + drivers/net/wireless/realtek/rtw89/efuse_be.c | 655 + drivers/net/wireless/realtek/rtw89/fw.c | 12910 +++++ drivers/net/wireless/realtek/rtw89/fw.h | 5935 ++ drivers/net/wireless/realtek/rtw89/led.c | 139 + drivers/net/wireless/realtek/rtw89/led.h | 37 + drivers/net/wireless/realtek/rtw89/led_mc.c | 81 + drivers/net/wireless/realtek/rtw89/mac.c | 7550 +++ drivers/net/wireless/realtek/rtw89/mac.h | 1932 + drivers/net/wireless/realtek/rtw89/mac80211.c | 2068 + drivers/net/wireless/realtek/rtw89/mac_be.c | 3368 ++ drivers/net/wireless/realtek/rtw89/pci.c | 4896 ++ drivers/net/wireless/realtek/rtw89/pci.h | 1950 + drivers/net/wireless/realtek/rtw89/pci_be.c | 910 + drivers/net/wireless/realtek/rtw89/phy.c | 9065 +++ drivers/net/wireless/realtek/rtw89/phy.h | 1245 + drivers/net/wireless/realtek/rtw89/phy_be.c | 1991 + drivers/net/wireless/realtek/rtw89/ps.c | 601 + drivers/net/wireless/realtek/rtw89/ps.h | 52 + drivers/net/wireless/realtek/rtw89/reg.h | 11104 ++++ drivers/net/wireless/realtek/rtw89/regd.c | 1210 + drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2740 + drivers/net/wireless/realtek/rtw89/rtw8851b.h | 76 + drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c | 3788 ++ drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h | 34 + .../wireless/realtek/rtw89/rtw8851b_rfk_table.c | 499 + .../wireless/realtek/rtw89/rtw8851b_rfk_table.h | 38 + .../net/wireless/realtek/rtw89/rtw8851b_table.c | 14917 +++++ .../net/wireless/realtek/rtw89/rtw8851b_table.h | 18 + drivers/net/wireless/realtek/rtw89/rtw8851be.c | 105 + drivers/net/wireless/realtek/rtw89/rtw8851bu.c | 72 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2502 + drivers/net/wireless/realtek/rtw89/rtw8852a.h | 110 + drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 3870 ++ drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h | 28 + .../wireless/realtek/rtw89/rtw8852a_rfk_table.c | 1607 + .../wireless/realtek/rtw89/rtw8852a_rfk_table.h | 86 + .../net/wireless/realtek/rtw89/rtw8852a_table.c | 51012 +++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852a_table.h | 17 + drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 107 + drivers/net/wireless/realtek/rtw89/rtw8852au.c | 86 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1100 + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 15 + .../net/wireless/realtek/rtw89/rtw8852b_common.c | 2101 + .../net/wireless/realtek/rtw89/rtw8852b_common.h | 400 + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 4220 ++ drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 34 + .../wireless/realtek/rtw89/rtw8852b_rfk_table.c | 794 + .../wireless/realtek/rtw89/rtw8852b_rfk_table.h | 62 + .../net/wireless/realtek/rtw89/rtw8852b_table.c | 22928 ++++++++ .../net/wireless/realtek/rtw89/rtw8852b_table.h | 18 + drivers/net/wireless/realtek/rtw89/rtw8852be.c | 109 + drivers/net/wireless/realtek/rtw89/rtw8852bt.c | 957 + drivers/net/wireless/realtek/rtw89/rtw8852bt.h | 15 + drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c | 4283 ++ drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h | 34 + .../wireless/realtek/rtw89/rtw8852bt_rfk_table.c | 490 + .../wireless/realtek/rtw89/rtw8852bt_rfk_table.h | 38 + drivers/net/wireless/realtek/rtw89/rtw8852bte.c | 111 + drivers/net/wireless/realtek/rtw89/rtw8852bu.c | 86 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3303 ++ drivers/net/wireless/realtek/rtw89/rtw8852c.h | 107 + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 4462 ++ drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h | 37 + .../wireless/realtek/rtw89/rtw8852c_rfk_table.c | 781 + .../wireless/realtek/rtw89/rtw8852c_rfk_table.h | 67 + .../net/wireless/realtek/rtw89/rtw8852c_table.c | 57160 +++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_table.h | 19 + drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 134 + drivers/net/wireless/realtek/rtw89/rtw8852cu.c | 146 + drivers/net/wireless/realtek/rtw89/rtw8922a.c | 3375 ++ drivers/net/wireless/realtek/rtw89/rtw8922a.h | 74 + drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c | 381 + drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h | 18 + drivers/net/wireless/realtek/rtw89/rtw8922ae.c | 124 + drivers/net/wireless/realtek/rtw89/rtw8922au.c | 87 + drivers/net/wireless/realtek/rtw89/rtw8922d.c | 3865 ++ drivers/net/wireless/realtek/rtw89/rtw8922d.h | 83 + drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c | 402 + drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h | 23 + drivers/net/wireless/realtek/rtw89/rtw8922de.c | 124 + drivers/net/wireless/realtek/rtw89/sar.c | 911 + drivers/net/wireless/realtek/rtw89/sar.h | 44 + drivers/net/wireless/realtek/rtw89/ser.c | 858 + drivers/net/wireless/realtek/rtw89/ser.h | 15 + drivers/net/wireless/realtek/rtw89/txrx.h | 892 + drivers/net/wireless/realtek/rtw89/usb.c | 1324 + drivers/net/wireless/realtek/rtw89/usb.h | 101 + drivers/net/wireless/realtek/rtw89/util.c | 162 + drivers/net/wireless/realtek/rtw89/util.h | 99 + drivers/net/wireless/realtek/rtw89/wow.c | 1847 + drivers/net/wireless/realtek/rtw89/wow.h | 141 + 531 files changed, 681894 insertions(+) create mode 100644 drivers/net/wireless/realtek/Kconfig create mode 100644 drivers/net/wireless/realtek/Makefile create mode 100644 drivers/net/wireless/realtek/rtl818x/Kconfig create mode 100644 drivers/net/wireless/realtek/rtl818x/Makefile create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h create mode 100644 drivers/net/wireless/realtek/rtl818x/rtl818x.h create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8188e.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8188f.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8192c.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8192e.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8192f.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8710b.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8723a.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/8723b.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/Kconfig create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/Makefile create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/core.c create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/regs.h create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/Kconfig create mode 100644 drivers/net/wireless/realtek/rtlwifi/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/base.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/base.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/cam.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/cam.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/core.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/core.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/debug.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/debug.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/efuse.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/efuse.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/pci.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/pci.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/ps.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/ps.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rc.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rc.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/regd.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/regd.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/stats.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/stats.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/usb.c create mode 100644 drivers/net/wireless/realtek/rtlwifi/usb.h create mode 100644 drivers/net/wireless/realtek/rtlwifi/wifi.h create mode 100644 drivers/net/wireless/realtek/rtw88/Kconfig create mode 100644 drivers/net/wireless/realtek/rtw88/Makefile create mode 100644 drivers/net/wireless/realtek/rtw88/bf.c create mode 100644 drivers/net/wireless/realtek/rtw88/bf.h create mode 100644 drivers/net/wireless/realtek/rtw88/coex.c create mode 100644 drivers/net/wireless/realtek/rtw88/coex.h create mode 100644 drivers/net/wireless/realtek/rtw88/debug.c create mode 100644 drivers/net/wireless/realtek/rtw88/debug.h create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.c create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.h create mode 100644 drivers/net/wireless/realtek/rtw88/fw.c create mode 100644 drivers/net/wireless/realtek/rtw88/fw.h create mode 100644 drivers/net/wireless/realtek/rtw88/hci.h create mode 100644 drivers/net/wireless/realtek/rtw88/led.c create mode 100644 drivers/net/wireless/realtek/rtw88/led.h create mode 100644 drivers/net/wireless/realtek/rtw88/mac.c create mode 100644 drivers/net/wireless/realtek/rtw88/mac.h create mode 100644 drivers/net/wireless/realtek/rtw88/mac80211.c create mode 100644 drivers/net/wireless/realtek/rtw88/main.c create mode 100644 drivers/net/wireless/realtek/rtw88/main.h create mode 100644 drivers/net/wireless/realtek/rtw88/pci.c create mode 100644 drivers/net/wireless/realtek/rtw88/pci.h create mode 100644 drivers/net/wireless/realtek/rtw88/phy.c create mode 100644 drivers/net/wireless/realtek/rtw88/phy.h create mode 100644 drivers/net/wireless/realtek/rtw88/ps.c create mode 100644 drivers/net/wireless/realtek/rtw88/ps.h create mode 100644 drivers/net/wireless/realtek/rtw88/reg.h create mode 100644 drivers/net/wireless/realtek/rtw88/regd.c create mode 100644 drivers/net/wireless/realtek/rtw88/regd.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723cs.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723d.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723d.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723d_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723d_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723de.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723ds.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814a.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814a.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814a_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814a_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814ae.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8814au.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821c.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821c.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821c_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821c_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821ce.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cs.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822be.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bs.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.h create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822ce.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cs.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.c create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.h create mode 100644 drivers/net/wireless/realtek/rtw88/rx.c create mode 100644 drivers/net/wireless/realtek/rtw88/rx.h create mode 100644 drivers/net/wireless/realtek/rtw88/sar.c create mode 100644 drivers/net/wireless/realtek/rtw88/sar.h create mode 100644 drivers/net/wireless/realtek/rtw88/sdio.c create mode 100644 drivers/net/wireless/realtek/rtw88/sdio.h create mode 100644 drivers/net/wireless/realtek/rtw88/sec.c create mode 100644 drivers/net/wireless/realtek/rtw88/sec.h create mode 100644 drivers/net/wireless/realtek/rtw88/tx.c create mode 100644 drivers/net/wireless/realtek/rtw88/tx.h create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h create mode 100644 drivers/net/wireless/realtek/rtw88/util.c create mode 100644 drivers/net/wireless/realtek/rtw88/util.h create mode 100644 drivers/net/wireless/realtek/rtw88/wow.c create mode 100644 drivers/net/wireless/realtek/rtw88/wow.h create mode 100644 drivers/net/wireless/realtek/rtw89/Kconfig create mode 100644 drivers/net/wireless/realtek/rtw89/Makefile create mode 100644 drivers/net/wireless/realtek/rtw89/acpi.c create mode 100644 drivers/net/wireless/realtek/rtw89/acpi.h create mode 100644 drivers/net/wireless/realtek/rtw89/cam.c create mode 100644 drivers/net/wireless/realtek/rtw89/cam.h create mode 100644 drivers/net/wireless/realtek/rtw89/chan.c create mode 100644 drivers/net/wireless/realtek/rtw89/chan.h create mode 100644 drivers/net/wireless/realtek/rtw89/coex.c create mode 100644 drivers/net/wireless/realtek/rtw89/coex.h create mode 100644 drivers/net/wireless/realtek/rtw89/core.c create mode 100644 drivers/net/wireless/realtek/rtw89/core.h create mode 100644 drivers/net/wireless/realtek/rtw89/debug.c create mode 100644 drivers/net/wireless/realtek/rtw89/debug.h create mode 100644 drivers/net/wireless/realtek/rtw89/efuse.c create mode 100644 drivers/net/wireless/realtek/rtw89/efuse.h create mode 100644 drivers/net/wireless/realtek/rtw89/efuse_be.c create mode 100644 drivers/net/wireless/realtek/rtw89/fw.c create mode 100644 drivers/net/wireless/realtek/rtw89/fw.h create mode 100644 drivers/net/wireless/realtek/rtw89/led.c create mode 100644 drivers/net/wireless/realtek/rtw89/led.h create mode 100644 drivers/net/wireless/realtek/rtw89/led_mc.c create mode 100644 drivers/net/wireless/realtek/rtw89/mac.c create mode 100644 drivers/net/wireless/realtek/rtw89/mac.h create mode 100644 drivers/net/wireless/realtek/rtw89/mac80211.c create mode 100644 drivers/net/wireless/realtek/rtw89/mac_be.c create mode 100644 drivers/net/wireless/realtek/rtw89/pci.c create mode 100644 drivers/net/wireless/realtek/rtw89/pci.h create mode 100644 drivers/net/wireless/realtek/rtw89/pci_be.c create mode 100644 drivers/net/wireless/realtek/rtw89/phy.c create mode 100644 drivers/net/wireless/realtek/rtw89/phy.h create mode 100644 drivers/net/wireless/realtek/rtw89/phy_be.c create mode 100644 drivers/net/wireless/realtek/rtw89/ps.c create mode 100644 drivers/net/wireless/realtek/rtw89/ps.h create mode 100644 drivers/net/wireless/realtek/rtw89/reg.h create mode 100644 drivers/net/wireless/realtek/rtw89/regd.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851be.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851bu.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852ae.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852au.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_common.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_common.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852be.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bte.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852bu.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_table.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852ce.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852cu.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922a.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922a.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922ae.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922au.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922d.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922d.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922de.c create mode 100644 drivers/net/wireless/realtek/rtw89/sar.c create mode 100644 drivers/net/wireless/realtek/rtw89/sar.h create mode 100644 drivers/net/wireless/realtek/rtw89/ser.c create mode 100644 drivers/net/wireless/realtek/rtw89/ser.h create mode 100644 drivers/net/wireless/realtek/rtw89/txrx.h create mode 100644 drivers/net/wireless/realtek/rtw89/usb.c create mode 100644 drivers/net/wireless/realtek/rtw89/usb.h create mode 100644 drivers/net/wireless/realtek/rtw89/util.c create mode 100644 drivers/net/wireless/realtek/rtw89/util.h create mode 100644 drivers/net/wireless/realtek/rtw89/wow.c create mode 100644 drivers/net/wireless/realtek/rtw89/wow.h (limited to 'drivers/net/wireless/realtek') diff --git a/drivers/net/wireless/realtek/Kconfig b/drivers/net/wireless/realtek/Kconfig new file mode 100644 index 000000000..4a1f0e64d --- /dev/null +++ b/drivers/net/wireless/realtek/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only +config WLAN_VENDOR_REALTEK + bool "Realtek devices" + default y + help + If you have a wireless card belonging to this class, say Y. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all the + questions about these cards. If you say Y, you will be asked for + your specific card in the following questions. + +if WLAN_VENDOR_REALTEK + +source "drivers/net/wireless/realtek/rtl818x/Kconfig" +source "drivers/net/wireless/realtek/rtlwifi/Kconfig" +source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig" +source "drivers/net/wireless/realtek/rtw88/Kconfig" +source "drivers/net/wireless/realtek/rtw89/Kconfig" + +endif # WLAN_VENDOR_REALTEK diff --git a/drivers/net/wireless/realtek/Makefile b/drivers/net/wireless/realtek/Makefile new file mode 100644 index 000000000..ab25419f5 --- /dev/null +++ b/drivers/net/wireless/realtek/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for the Linux Wireless network device drivers for Realtek units +# + +obj-$(CONFIG_RTL8180) += rtl818x/ +obj-$(CONFIG_RTL8187) += rtl818x/ +obj-$(CONFIG_RTLWIFI) += rtlwifi/ +obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/ +obj-$(CONFIG_RTW88) += rtw88/ +obj-$(CONFIG_RTW89) += rtw89/ + diff --git a/drivers/net/wireless/realtek/rtl818x/Kconfig b/drivers/net/wireless/realtek/rtl818x/Kconfig new file mode 100644 index 000000000..603812c9a --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/Kconfig @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# RTL818X Wireless LAN device configuration +# +config RTL8180 + tristate "Realtek 8180/8185/8187SE PCI support" + depends on MAC80211 && PCI + select EEPROM_93CX6 + help + This is a driver for RTL8180, RTL8185 and RTL8187SE based cards. + These are PCI based chips found in cards such as: + + (RTL8185 802.11g) + A-Link WL54PC + + (RTL8180 802.11b) + Belkin F5D6020 v3 + Belkin F5D6020 v3 + Dlink DWL-610 + Dlink DWL-510 + Netgear MA521 + Level-One WPC-0101 + Acer Aspire 1357 LMi + VCTnet PC-11B1 + Ovislink AirLive WL-1120PCM + Mentor WL-PCI + Linksys WPC11 v4 + TrendNET TEW-288PI + D-Link DWL-520 Rev D + Repotec RP-WP7126 + TP-Link TL-WN250/251 + Zonet ZEW1000 + Longshine LCS-8031-R + HomeLine HLW-PCC200 + GigaFast WF721-AEX + Planet WL-3553 + Encore ENLWI-PCI1-NT + TrendNET TEW-266PC + Gigabyte GN-WLMR101 + Siemens-fujitsu Amilo D1840W + Edimax EW-7126 + PheeNet WL-11PCIR + Tonze PC-2100T + Planet WL-8303 + Dlink DWL-650 v M1 + Edimax EW-7106 + Q-Tec 770WC + Topcom Skyr@cer 4011b + Roper FreeLan 802.11b (edition 2004) + Wistron Neweb Corp CB-200B + Pentagram HorNET + QTec 775WC + TwinMOS Booming B Series + Micronet SP906BB + Sweex LC700010 + Surecom EP-9428 + Safecom SWLCR-1100 + + Thanks to Realtek for their support! + +config RTL8187 + tristate "Realtek 8187 and 8187B USB support" + depends on MAC80211 && USB + select EEPROM_93CX6 + help + This is a driver for RTL8187 and RTL8187B based cards. + These are USB based chips found in devices such as: + + Netgear WG111v2 + Level 1 WNC-0301USB + Micronet SP907GK V5 + Encore ENUWI-G2 + Trendnet TEW-424UB + ASUS P5B Deluxe/P5K Premium motherboards + Toshiba Satellite Pro series of laptops + Asus Wireless Link + Linksys WUSB54GC-EU v2 + (v1 = rt73usb; v3 is rt2070-based, + use staging/rt3070 or try rt2800usb) + + Thanks to Realtek for their support! + +# If possible, automatically enable LEDs for RTL8187. + +config RTL8187_LEDS + bool + depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187) + default y + diff --git a/drivers/net/wireless/realtek/rtl818x/Makefile b/drivers/net/wireless/realtek/rtl818x/Makefile new file mode 100644 index 000000000..e03afcbf8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_RTL8180) += rtl8180/ +obj-$(CONFIG_RTL8187) += rtl8187/ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile b/drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile new file mode 100644 index 000000000..1044105c2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +rtl818x_pci-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o + +obj-$(CONFIG_RTL8180) += rtl818x_pci.o + +ccflags-y += -I $(src)/.. diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c new file mode 100644 index 000000000..4a5989172 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -0,0 +1,1991 @@ + +/* Linux device driver for RTL8180 / RTL8185 / RTL8187SE + * + * Copyright 2007 Michael Wu + * Copyright 2007,2014 Andrea Merello + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + * + ************************************************************************ + * + * The driver was extended to the RTL8187SE in 2014 by + * Andrea Merello + * + * based also on: + * - portions of rtl8187se Linux staging driver, Copyright Realtek corp. + * (available in drivers/staging/rtl8187se directory of Linux 3.14) + * - other GPL, unpublished (until now), Linux driver code, + * Copyright Larry Finger + * + * A huge thanks goes to Sara V. Nari who forgives me when I'm + * sitting in front of my laptop at evening, week-end, night... + * + * A special thanks goes to Antonio Cuni, who helped me with + * some python userspace stuff I used to debug RTL8187SE code, and who + * bought a laptop with an unsupported Wi-Fi card some years ago... + * + * Thanks to Larry Finger for writing some code for rtl8187se and for + * his suggestions. + * + * Thanks to Dan Carpenter for reviewing my initial patch and for his + * suggestions. + * + * Thanks to Bernhard Schiffner for his help in testing and for his + * suggestions. + * + ************************************************************************ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rtl8180.h" +#include "rtl8225.h" +#include "sa2400.h" +#include "max2820.h" +#include "grf5101.h" +#include "rtl8225se.h" + +MODULE_AUTHOR("Michael Wu "); +MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("RTL8180 / RTL8185 / RTL8187SE PCI wireless driver"); +MODULE_LICENSE("GPL"); + +static const struct pci_device_id rtl8180_table[] = { + + /* rtl8187se */ + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8199) }, + + /* rtl8185 */ + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, + { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, + { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) }, + + /* rtl8180 */ + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) }, + { PCI_DEVICE(0x1799, 0x6001) }, + { PCI_DEVICE(0x1799, 0x6020) }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, + { PCI_DEVICE(0x1186, 0x3301) }, + { PCI_DEVICE(0x1432, 0x7106) }, + { } +}; + +MODULE_DEVICE_TABLE(pci, rtl8180_table); + +static const struct ieee80211_rate rtl818x_rates[] = { + { .bitrate = 10, .hw_value = 0, }, + { .bitrate = 20, .hw_value = 1, }, + { .bitrate = 55, .hw_value = 2, }, + { .bitrate = 110, .hw_value = 3, }, + { .bitrate = 60, .hw_value = 4, }, + { .bitrate = 90, .hw_value = 5, }, + { .bitrate = 120, .hw_value = 6, }, + { .bitrate = 180, .hw_value = 7, }, + { .bitrate = 240, .hw_value = 8, }, + { .bitrate = 360, .hw_value = 9, }, + { .bitrate = 480, .hw_value = 10, }, + { .bitrate = 540, .hw_value = 11, }, +}; + +static const struct ieee80211_channel rtl818x_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + +/* Queues for rtl8187se card + * + * name | reg | queue + * BC | 7 | 6 + * MG | 1 | 0 + * HI | 6 | 1 + * VO | 5 | 2 + * VI | 4 | 3 + * BE | 3 | 4 + * BK | 2 | 5 + * + * The complete map for DMA kick reg using use all queue is: + * static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = + * {1, 6, 5, 4, 3, 2, 7}; + * + * .. but.. Because for mac80211 4 queues are enough for QoS we use this + * + * name | reg | queue + * BC | 7 | 4 <- currently not used yet + * MG | 1 | x <- Not used + * HI | 6 | x <- Not used + * VO | 5 | 0 <- used + * VI | 4 | 1 <- used + * BE | 3 | 2 <- used + * BK | 2 | 3 <- used + * + * Beacon queue could be used, but this is not finished yet. + * + * I thougth about using the other two queues but I decided not to do this: + * + * - I'm unsure whether the mac80211 will ever try to use more than 4 queues + * by itself. + * + * - I could route MGMT frames (currently sent over VO queue) to the MGMT + * queue but since mac80211 will do not know about it, I will probably gain + * some HW priority whenever the VO queue is not empty, but this gain is + * limited by the fact that I had to stop the mac80211 queue whenever one of + * the VO or MGMT queues is full, stopping also submitting of MGMT frame + * to the driver. + * + * - I don't know how to set in the HW the contention window params for MGMT + * and HI-prio queues. + */ + +static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = {5, 4, 3, 2, 7}; + +/* Queues for rtl8180/rtl8185 cards + * + * name | reg | prio + * BC | 7 | 3 + * HI | 6 | 0 + * NO | 5 | 1 + * LO | 4 | 2 + * + * The complete map for DMA kick reg using all queue is: + * static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {6, 5, 4, 7}; + * + * .. but .. Because the mac80211 needs at least 4 queues for QoS or + * otherwise QoS can't be done, we use just one. + * Beacon queue could be used, but this is not finished yet. + * Actual map is: + * + * name | reg | prio + * BC | 7 | 1 <- currently not used yet. + * HI | 6 | x <- not used + * NO | 5 | x <- not used + * LO | 4 | 0 <- used + */ + +static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {4, 7}; + +/* LNA gain table for rtl8187se */ +static const u8 rtl8187se_lna_gain[4] = {02, 17, 29, 39}; + +void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + int i = 10; + u32 buf; + + buf = (data << 8) | addr; + + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80); + while (i--) { + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf); + if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF)) + return; + } +} + +static void rtl8180_handle_rx(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl818x_rx_cmd_desc *cmd_desc; + unsigned int count = 32; + u8 agc, sq; + s8 signal = 1; + dma_addr_t mapping; + + while (count--) { + void *entry = priv->rx_ring + priv->rx_idx * priv->rx_ring_sz; + struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; + u32 flags, flags2, flags3 = 0; + u64 tsft; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + struct rtl8187se_rx_desc *desc = entry; + + flags = le32_to_cpu(desc->flags); + /* if ownership flag is set, then we can trust the + * HW has written other fields. We must not trust + * other descriptor data read before we checked (read) + * the ownership flag + */ + rmb(); + flags3 = le32_to_cpu(desc->flags3); + flags2 = le32_to_cpu(desc->flags2); + tsft = le64_to_cpu(desc->tsft); + } else { + struct rtl8180_rx_desc *desc = entry; + + flags = le32_to_cpu(desc->flags); + /* same as above */ + rmb(); + flags2 = le32_to_cpu(desc->flags2); + tsft = le64_to_cpu(desc->tsft); + } + + if (flags & RTL818X_RX_DESC_FLAG_OWN) + return; + + if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | + RTL818X_RX_DESC_FLAG_FOF | + RTL818X_RX_DESC_FLAG_RX_ERR))) + goto done; + else { + struct ieee80211_rx_status rx_status = {0}; + struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); + + if (unlikely(!new_skb)) + goto done; + + mapping = dma_map_single(&priv->pdev->dev, + skb_tail_pointer(new_skb), + MAX_RX_SIZE, DMA_FROM_DEVICE); + + if (dma_mapping_error(&priv->pdev->dev, mapping)) { + kfree_skb(new_skb); + dev_err(&priv->pdev->dev, "RX DMA map error\n"); + + goto done; + } + + dma_unmap_single(&priv->pdev->dev, + *((dma_addr_t *)skb->cb), + MAX_RX_SIZE, DMA_FROM_DEVICE); + skb_put(skb, flags & 0xFFF); + + rx_status.antenna = (flags2 >> 15) & 1; + rx_status.rate_idx = (flags >> 20) & 0xF; + agc = (flags2 >> 17) & 0x7F; + + switch (priv->chip_family) { + case RTL818X_CHIP_FAMILY_RTL8185: + if (rx_status.rate_idx > 3) + signal = -clamp_t(u8, agc, 25, 90) - 9; + else + signal = -clamp_t(u8, agc, 30, 95); + break; + case RTL818X_CHIP_FAMILY_RTL8180: + sq = flags2 & 0xff; + signal = priv->rf->calc_rssi(agc, sq); + break; + case RTL818X_CHIP_FAMILY_RTL8187SE: + /* OFDM measure reported by HW is signed, + * in 0.5dBm unit, with zero centered @ -41dBm + * input signal. + */ + if (rx_status.rate_idx > 3) { + signal = (s8)((flags3 >> 16) & 0xff); + signal = signal / 2 - 41; + } else { + int idx, bb; + + idx = (agc & 0x60) >> 5; + bb = (agc & 0x1F) * 2; + /* bias + BB gain + LNA gain */ + signal = 4 - bb - rtl8187se_lna_gain[idx]; + } + break; + } + rx_status.signal = signal; + rx_status.freq = dev->conf.chandef.chan->center_freq; + rx_status.band = dev->conf.chandef.chan->band; + rx_status.mactime = tsft; + rx_status.flag |= RX_FLAG_MACTIME_START; + if (flags & RTL818X_RX_DESC_FLAG_SPLCP) + rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE; + if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(dev, skb); + + skb = new_skb; + priv->rx_buf[priv->rx_idx] = skb; + *((dma_addr_t *) skb->cb) = mapping; + } + + done: + cmd_desc = entry; + cmd_desc->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); + cmd_desc->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | + MAX_RX_SIZE); + if (priv->rx_idx == 31) + cmd_desc->flags |= + cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); + priv->rx_idx = (priv->rx_idx + 1) % 32; + } +} + +static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u32 flags = le32_to_cpu(entry->flags); + + if (flags & RTL818X_TX_DESC_FLAG_OWN) + return; + + ring->idx = (ring->idx + 1) % ring->entries; + skb = __skb_dequeue(&ring->queue); + dma_unmap_single(&priv->pdev->dev, le32_to_cpu(entry->tx_buf), + skb->len, DMA_TO_DEVICE); + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && + (flags & RTL818X_TX_DESC_FLAG_TX_OK)) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = (flags & 0xFF) + 1; + + ieee80211_tx_status_irqsafe(dev, skb); + if (ring->entries - skb_queue_len(&ring->queue) == 2) + ieee80211_wake_queue(dev, prio); + } +} + +static irqreturn_t rtl8187se_interrupt(int irq, void *dev_id) +{ + struct ieee80211_hw *dev = dev_id; + struct rtl8180_priv *priv = dev->priv; + u32 reg; + unsigned long flags; + static int desc_err; + + spin_lock_irqsave(&priv->lock, flags); + /* Note: 32-bit interrupt status */ + reg = rtl818x_ioread32(priv, &priv->map->INT_STATUS_SE); + if (unlikely(reg == 0xFFFFFFFF)) { + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; + } + + rtl818x_iowrite32(priv, &priv->map->INT_STATUS_SE, reg); + + if (reg & IMR_TIMEOUT1) + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + + if (reg & (IMR_TBDOK | IMR_TBDER)) + rtl8180_handle_tx(dev, 4); + + if (reg & (IMR_TVODOK | IMR_TVODER)) + rtl8180_handle_tx(dev, 0); + + if (reg & (IMR_TVIDOK | IMR_TVIDER)) + rtl8180_handle_tx(dev, 1); + + if (reg & (IMR_TBEDOK | IMR_TBEDER)) + rtl8180_handle_tx(dev, 2); + + if (reg & (IMR_TBKDOK | IMR_TBKDER)) + rtl8180_handle_tx(dev, 3); + + if (reg & (IMR_ROK | IMR_RER | RTL818X_INT_SE_RX_DU | IMR_RQOSOK)) + rtl8180_handle_rx(dev); + /* The interface sometimes generates several RX DMA descriptor errors + * at startup. Do not report these. + */ + if ((reg & RTL818X_INT_SE_RX_DU) && desc_err++ > 2) + if (net_ratelimit()) + wiphy_err(dev->wiphy, "No RX DMA Descriptor avail\n"); + + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; +} + +static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) +{ + struct ieee80211_hw *dev = dev_id; + struct rtl8180_priv *priv = dev->priv; + u16 reg; + + spin_lock(&priv->lock); + reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); + if (unlikely(reg == 0xFFFF)) { + spin_unlock(&priv->lock); + return IRQ_HANDLED; + } + + rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); + + if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) + rtl8180_handle_tx(dev, 1); + + if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) + rtl8180_handle_tx(dev, 0); + + if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) + rtl8180_handle_rx(dev); + + spin_unlock(&priv->lock); + + return IRQ_HANDLED; +} + +static void rtl8180_tx(struct ieee80211_hw *dev, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring; + struct rtl8180_tx_desc *entry; + unsigned int prio = 0; + unsigned long flags; + unsigned int idx, hw_prio; + + dma_addr_t mapping; + u32 tx_flags; + u8 rc_flags; + u16 plcp_len = 0; + __le16 rts_duration = 0; + /* do arithmetic and then convert to le16 */ + u16 frame_duration = 0; + + /* rtl8180/rtl8185 only has one useable tx queue */ + if (dev->queues > IEEE80211_AC_BK) + prio = skb_get_queue_mapping(skb); + ring = &priv->tx_ring[prio]; + + mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + + if (dma_mapping_error(&priv->pdev->dev, mapping)) { + kfree_skb(skb); + dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); + return; + } + + tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | + RTL818X_TX_DESC_FLAG_LS | + (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | + skb->len; + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) + tx_flags |= RTL818X_TX_DESC_FLAG_DMA | + RTL818X_TX_DESC_FLAG_NO_ENC; + + rc_flags = info->control.rates[0].flags; + + /* HW will perform RTS-CTS when only RTS flags is set. + * HW will perform CTS-to-self when both RTS and CTS flags are set. + * RTS rate and RTS duration will be used also for CTS-to-self. + */ + if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { + tx_flags |= RTL818X_TX_DESC_FLAG_RTS; + tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + rts_duration = ieee80211_rts_duration(dev, priv->vif, + skb->len, info); + } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + tx_flags |= RTL818X_TX_DESC_FLAG_RTS | RTL818X_TX_DESC_FLAG_CTS; + tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + rts_duration = ieee80211_ctstoself_duration(dev, priv->vif, + skb->len, info); + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { + unsigned int remainder; + + plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), + (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); + remainder = (16 * (skb->len + 4)) % + ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); + if (remainder <= 6) + plcp_len |= 1 << 15; + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + __le16 duration; + /* SIFS time (required by HW) is already included by + * ieee80211_generic_frame_duration + */ + duration = ieee80211_generic_frame_duration(dev, priv->vif, + NL80211_BAND_2GHZ, skb->len, + ieee80211_get_tx_rate(dev, info)); + + frame_duration = priv->ack_time + le16_to_cpu(duration); + } + + spin_lock_irqsave(&priv->lock, flags); + + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) + priv->seqno += 0x10; + hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(priv->seqno); + } + + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + entry = &ring->desc[idx]; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + entry->frame_duration = cpu_to_le16(frame_duration); + entry->frame_len_se = cpu_to_le16(skb->len); + + /* tpc polarity */ + entry->flags3 = cpu_to_le16(1<<4); + } else + entry->frame_len = cpu_to_le32(skb->len); + + entry->rts_duration = rts_duration; + entry->plcp_len = cpu_to_le16(plcp_len); + entry->tx_buf = cpu_to_le32(mapping); + + entry->retry_limit = info->control.rates[0].count - 1; + + /* We must be sure that tx_flags is written last because the HW + * looks at it to check if the rest of data is valid or not + */ + wmb(); + entry->flags = cpu_to_le32(tx_flags); + /* We must be sure this has been written before followings HW + * register write, because this write will made the HW attempts + * to DMA the just-written data + */ + wmb(); + + __skb_queue_tail(&ring->queue, skb); + if (ring->entries - skb_queue_len(&ring->queue) < 2) + ieee80211_stop_queue(dev, prio); + + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + /* just poll: rings are stopped with TPPollStop reg */ + hw_prio = rtl8187se_queues_map[prio]; + rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, + (1 << hw_prio)); + } else { + hw_prio = rtl8180_queues_map[prio]; + rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, + (1 << hw_prio) | /* ring to poll */ + (1<<1) | (1<<2));/* stopped rings */ + } +} + +static void rtl8180_set_anaparam3(struct rtl8180_priv *priv, u16 anaparam3) +{ + u8 reg; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + + rtl818x_iowrite16(priv, &priv->map->ANAPARAM3, anaparam3); + + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + +void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2) +{ + u8 reg; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); + + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + +void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) +{ + u8 reg; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); +} + +static void rtl8187se_mac_config(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u8 reg; + + rtl818x_iowrite32(priv, REG_ADDR4(0x1F0), 0); + rtl818x_ioread32(priv, REG_ADDR4(0x1F0)); + rtl818x_iowrite32(priv, REG_ADDR4(0x1F4), 0); + rtl818x_ioread32(priv, REG_ADDR4(0x1F4)); + rtl818x_iowrite8(priv, REG_ADDR1(0x1F8), 0); + rtl818x_ioread8(priv, REG_ADDR1(0x1F8)); + /* Enable DA10 TX power saving */ + reg = rtl818x_ioread8(priv, &priv->map->PHY_PR); + rtl818x_iowrite8(priv, &priv->map->PHY_PR, reg | 0x04); + /* Power */ + rtl818x_iowrite16(priv, PI_DATA_REG, 0x1000); + rtl818x_iowrite16(priv, SI_DATA_REG, 0x1000); + /* AFE - default to power ON */ + rtl818x_iowrite16(priv, REG_ADDR2(0x370), 0x0560); + rtl818x_iowrite16(priv, REG_ADDR2(0x372), 0x0560); + rtl818x_iowrite16(priv, REG_ADDR2(0x374), 0x0DA4); + rtl818x_iowrite16(priv, REG_ADDR2(0x376), 0x0DA4); + rtl818x_iowrite16(priv, REG_ADDR2(0x378), 0x0560); + rtl818x_iowrite16(priv, REG_ADDR2(0x37A), 0x0560); + rtl818x_iowrite16(priv, REG_ADDR2(0x37C), 0x00EC); + rtl818x_iowrite16(priv, REG_ADDR2(0x37E), 0x00EC); + rtl818x_iowrite8(priv, REG_ADDR1(0x24E), 0x01); + /* unknown, needed for suspend to RAM resume */ + rtl818x_iowrite8(priv, REG_ADDR1(0x0A), 0x72); +} + +static void rtl8187se_set_antenna_config(struct ieee80211_hw *dev, u8 def_ant, + bool diversity) +{ + struct rtl8180_priv *priv = dev->priv; + + rtl8225_write_phy_cck(dev, 0x0C, 0x09); + if (diversity) { + if (def_ant == 1) { + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00); + rtl8225_write_phy_cck(dev, 0x11, 0xBB); + rtl8225_write_phy_cck(dev, 0x01, 0xC7); + rtl8225_write_phy_ofdm(dev, 0x0D, 0x54); + rtl8225_write_phy_ofdm(dev, 0x18, 0xB2); + } else { /* main antenna */ + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); + rtl8225_write_phy_cck(dev, 0x11, 0x9B); + rtl8225_write_phy_cck(dev, 0x01, 0xC7); + rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C); + rtl8225_write_phy_ofdm(dev, 0x18, 0xB2); + } + } else { /* disable antenna diversity */ + if (def_ant == 1) { + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00); + rtl8225_write_phy_cck(dev, 0x11, 0xBB); + rtl8225_write_phy_cck(dev, 0x01, 0x47); + rtl8225_write_phy_ofdm(dev, 0x0D, 0x54); + rtl8225_write_phy_ofdm(dev, 0x18, 0x32); + } else { /* main antenna */ + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); + rtl8225_write_phy_cck(dev, 0x11, 0x9B); + rtl8225_write_phy_cck(dev, 0x01, 0x47); + rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C); + rtl8225_write_phy_ofdm(dev, 0x18, 0x32); + } + } + /* priv->curr_ant = def_ant; */ +} + +static void rtl8180_int_enable(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + rtl818x_iowrite32(priv, &priv->map->IMR, + IMR_TBDER | IMR_TBDOK | + IMR_TVODER | IMR_TVODOK | + IMR_TVIDER | IMR_TVIDOK | + IMR_TBEDER | IMR_TBEDOK | + IMR_TBKDER | IMR_TBKDOK | + IMR_RDU | IMR_RER | + IMR_ROK | IMR_RQOSOK); + } else { + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + } +} + +static void rtl8180_int_disable(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + rtl818x_iowrite32(priv, &priv->map->IMR, 0); + } else { + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + } +} + +static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, + u32 basic_mask) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg; + u32 resp_mask; + u8 basic_max; + u8 resp_max, resp_min; + + resp_mask = basic_mask; + /* IEEE80211 says the response rate should be equal to the highest basic + * rate that is not faster than received frame. But it says also that if + * the basic rate set does not contains any rate for the current + * modulation class then mandatory rate set must be used for that + * modulation class. Eventually add OFDM mandatory rates.. + */ + if ((resp_mask & 0xf) == resp_mask) + resp_mask |= 0x150; /* 6, 12, 24Mbps */ + + switch (priv->chip_family) { + + case RTL818X_CHIP_FAMILY_RTL8180: + /* in 8180 this is NOT a BITMAP */ + basic_max = fls(basic_mask) - 1; + reg = rtl818x_ioread16(priv, &priv->map->BRSR); + reg &= ~3; + reg |= basic_max; + rtl818x_iowrite16(priv, &priv->map->BRSR, reg); + break; + + case RTL818X_CHIP_FAMILY_RTL8185: + resp_max = fls(resp_mask) - 1; + resp_min = ffs(resp_mask) - 1; + /* in 8185 this is a BITMAP */ + rtl818x_iowrite16(priv, &priv->map->BRSR, basic_mask); + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (resp_max << 4) | + resp_min); + break; + + case RTL818X_CHIP_FAMILY_RTL8187SE: + /* in 8187se this is a BITMAP. BRSR reg actually sets + * response rates. + */ + rtl818x_iowrite16(priv, &priv->map->BRSR_8187SE, resp_mask); + break; + } +} + +static void rtl8180_config_cardbus(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg16; + u8 reg8; + + reg8 = rtl818x_ioread8(priv, &priv->map->CONFIG3); + reg8 |= 1 << 1; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg8); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + rtl818x_iowrite16(priv, FEMR_SE, 0xffff); + } else { + reg16 = rtl818x_ioread16(priv, &priv->map->FEMR); + reg16 |= (1 << 15) | (1 << 14) | (1 << 4); + rtl818x_iowrite16(priv, &priv->map->FEMR, reg16); + } + +} + +static int rtl8180_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg; + u32 reg32; + + rtl818x_iowrite8(priv, &priv->map->CMD, 0); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(10); + + /* reset */ + rtl8180_int_disable(dev); + rtl818x_ioread8(priv, &priv->map->CMD); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= (1 << 1); + reg |= RTL818X_CMD_RESET; + rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(200); + + /* check success of reset */ + if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { + wiphy_err(dev->wiphy, "reset timeout!\n"); + return -ETIMEDOUT; + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); + rtl818x_ioread8(priv, &priv->map->CMD); + msleep(200); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { + rtl8180_config_cardbus(dev); + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); + else + rtl818x_iowrite8(priv, &priv->map->MSR, 0); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) + rtl8180_set_anaparam(priv, priv->anaparam); + + rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); + /* mac80211 queue have higher prio for lower index. The last queue + * (that mac80211 is not aware of) is reserved for beacons (and have + * the highest priority on the NIC) + */ + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) { + rtl818x_iowrite32(priv, &priv->map->TBDA, + priv->tx_ring[1].dma); + rtl818x_iowrite32(priv, &priv->map->TLPDA, + priv->tx_ring[0].dma); + } else { + rtl818x_iowrite32(priv, &priv->map->TBDA, + priv->tx_ring[4].dma); + rtl818x_iowrite32(priv, &priv->map->TVODA, + priv->tx_ring[0].dma); + rtl818x_iowrite32(priv, &priv->map->TVIDA, + priv->tx_ring[1].dma); + rtl818x_iowrite32(priv, &priv->map->TBEDA, + priv->tx_ring[2].dma); + rtl818x_iowrite32(priv, &priv->map->TBKDA, + priv->tx_ring[3].dma); + } + + /* TODO: necessary? specs indicate not */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); + } + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */ + + /* TODO: turn off hw wep on rtl8180 */ + + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0); + } else { + rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); + + rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { + /* TODO: set ClkRun enable? necessary? */ + reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + /* fix eccessive IFS after CTS-to-self */ + if (priv->map_pio) { + u8 reg; + + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); + rtl818x_iowrite8(priv, REG_ADDR1(0xff), 0x35); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + } else + rtl818x_iowrite8(priv, REG_ADDR1(0x1ff), 0x35); + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + + /* the set auto rate fallback bitmask from 1M to 54 Mb/s */ + rtl818x_iowrite16(priv, ARFR, 0xFFF); + rtl818x_ioread16(priv, ARFR); + + /* stop unused queus (no dma alloc) */ + rtl818x_iowrite8(priv, &priv->map->TPPOLL_STOP, + RTL818x_TPPOLL_STOP_MG | RTL818x_TPPOLL_STOP_HI); + + rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0x00); + rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50); + + rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0); + + /* some black magic here.. */ + rtl8187se_mac_config(dev); + + rtl818x_iowrite16(priv, RFSW_CTRL, 0x569A); + rtl818x_ioread16(priv, RFSW_CTRL); + + rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_ON); + rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_ON); + rtl8180_set_anaparam3(priv, RTL8225SE_ANAPARAM3); + + + rtl818x_iowrite8(priv, &priv->map->CONFIG5, + rtl818x_ioread8(priv, &priv->map->CONFIG5) & 0x7F); + + /*probably this switch led on */ + rtl818x_iowrite8(priv, &priv->map->PGSELECT, + rtl818x_ioread8(priv, &priv->map->PGSELECT) | 0x08); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1BFF); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x4003); + + /* the reference code mac hardcode table write + * this reg by doing byte-wide accesses. + * It does it just for lowest and highest byte.. + */ + reg32 = rtl818x_ioread32(priv, &priv->map->RF_PARA); + reg32 &= 0x00ffff00; + reg32 |= 0xb8000054; + rtl818x_iowrite32(priv, &priv->map->RF_PARA, reg32); + } else + /* stop unused queus (no dma alloc) */ + rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, + (1<<1) | (1<<2)); + + priv->rf->init(dev); + + /* default basic rates are 1,2 Mbps for rtl8180. 1,2,6,9,12,18,24 Mbps + * otherwise. bitmask 0x3 and 0x01f3 respectively. + * NOTE: currenty rtl8225 RF code changes basic rates, so we need to do + * this after rf init. + * TODO: try to find out whether RF code really needs to do this.. + */ + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) + rtl8180_conf_basic_rates(dev, 0x3); + else + rtl8180_conf_basic_rates(dev, 0x1f3); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + rtl8187se_set_antenna_config(dev, + priv->antenna_diversity_default, + priv->antenna_diversity_en); + return 0; +} + +static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl818x_rx_cmd_desc *entry; + int i; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + priv->rx_ring_sz = sizeof(struct rtl8187se_rx_desc); + else + priv->rx_ring_sz = sizeof(struct rtl8180_rx_desc); + + priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev, + priv->rx_ring_sz * 32, + &priv->rx_ring_dma, GFP_KERNEL); + if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { + wiphy_err(dev->wiphy, "Cannot allocate RX ring\n"); + return -ENOMEM; + } + + priv->rx_idx = 0; + + for (i = 0; i < 32; i++) { + struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } + priv->rx_buf[i] = skb; + mapping = (dma_addr_t *)skb->cb; + *mapping = dma_map_single(&priv->pdev->dev, + skb_tail_pointer(skb), MAX_RX_SIZE, + DMA_FROM_DEVICE); + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); + priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } + + entry->rx_buf = cpu_to_le32(*mapping); + entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | + MAX_RX_SIZE); + } + entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); + return 0; +} + +static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + for (i = 0; i < 32; i++) { + struct sk_buff *skb = priv->rx_buf[i]; + if (!skb) + continue; + + dma_unmap_single(&priv->pdev->dev, *((dma_addr_t *)skb->cb), + MAX_RX_SIZE, DMA_FROM_DEVICE); + kfree_skb(skb); + } + + dma_free_coherent(&priv->pdev->dev, priv->rx_ring_sz * 32, + priv->rx_ring, priv->rx_ring_dma); + priv->rx_ring = NULL; +} + +static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, + unsigned int prio, unsigned int entries) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_desc *ring; + dma_addr_t dma; + int i; + + ring = dma_alloc_coherent(&priv->pdev->dev, sizeof(*ring) * entries, + &dma, GFP_KERNEL); + if (!ring || (unsigned long)ring & 0xFF) { + wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n", + prio); + return -ENOMEM; + } + + priv->tx_ring[prio].desc = ring; + priv->tx_ring[prio].dma = dma; + priv->tx_ring[prio].idx = 0; + priv->tx_ring[prio].entries = entries; + skb_queue_head_init(&priv->tx_ring[prio].queue); + + for (i = 0; i < entries; i++) + ring[i].next_tx_desc = + cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); + + return 0; +} + +static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + dma_unmap_single(&priv->pdev->dev, le32_to_cpu(entry->tx_buf), + skb->len, DMA_TO_DEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + dma_free_coherent(&priv->pdev->dev, + sizeof(*ring->desc) * ring->entries, ring->desc, + ring->dma); + ring->desc = NULL; +} + +static int rtl8180_start(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int ret, i; + u32 reg; + + ret = rtl8180_init_rx_ring(dev); + if (ret) + goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) + goto err_free_rings; + + ret = rtl8180_init_hw(dev); + if (ret) + goto err_free_rings; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + ret = request_irq(priv->pdev->irq, rtl8187se_interrupt, + IRQF_SHARED, KBUILD_MODNAME, dev); + } else { + ret = request_irq(priv->pdev->irq, rtl8180_interrupt, + IRQF_SHARED, KBUILD_MODNAME, dev); + } + + if (ret) { + wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); + goto err_free_rings; + } + + rtl8180_int_enable(dev); + + /* in rtl8187se at MAR regs offset there is the management + * TX descriptor DMA addres.. + */ + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) { + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); + } + + reg = RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + (7 << 8 /* MAX RX DMA */) | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) + reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; + else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) + ? RTL818X_RX_CONF_CSDM1 : 0; + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) + ? RTL818X_RX_CONF_CSDM2 : 0; + } else { + reg &= ~(RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2); + } + + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + + /* CW is not on per-packet basis. + * in rtl8185 the CW_VALUE reg is used. + * in rtl8187se the AC param regs are used. + */ + reg &= ~RTL818X_CW_CONF_PERPACKET_CW; + /* retry limit IS on per-packet basis. + * the short and long retry limit in TX_CONF + * reg are ignored + */ + reg |= RTL818X_CW_CONF_PERPACKET_RETRY; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + /* TX antenna and TX gain are not on per-packet basis. + * TX Antenna is selected by ANTSEL reg (RX in BB regs). + * TX gain is selected with CCK_TX_AGC and OFDM_TX_AGC regs + */ + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL; + reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + /* disable early TX */ + rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f); + } + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg |= (6 << 21 /* MAX TX DMA */) | + RTL818X_TX_CONF_NO_ICV; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + reg |= 1<<30; /* "duration procedure mode" */ + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) + reg &= ~RTL818X_TX_CONF_PROBE_DTS; + else + reg &= ~RTL818X_TX_CONF_HW_SEQNUM; + + reg &= ~RTL818X_TX_CONF_DISCW; + + /* different meaning, same value on both rtl8185 and rtl8180 */ + reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg |= RTL818X_CMD_RX_ENABLE; + reg |= RTL818X_CMD_TX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + return 0; + + err_free_rings: + rtl8180_free_rx_ring(dev); + for (i = 0; i < (dev->queues + 1); i++) + if (priv->tx_ring[i].desc) + rtl8180_free_tx_ring(dev, i); + + return ret; +} + +static void rtl8180_stop(struct ieee80211_hw *dev, bool suspend) +{ + struct rtl8180_priv *priv = dev->priv; + u8 reg; + int i; + + rtl8180_int_disable(dev); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= ~RTL818X_CMD_TX_ENABLE; + reg &= ~RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + priv->rf->stop(dev); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + free_irq(priv->pdev->irq, dev); + + rtl8180_free_rx_ring(dev); + for (i = 0; i < (dev->queues + 1); i++) + rtl8180_free_tx_ring(dev, i); +} + +static u64 rtl8180_get_tsf(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8180_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + +static void rtl8180_beacon_work(struct work_struct *work) +{ + struct rtl8180_vif *vif_priv = + container_of(work, struct rtl8180_vif, beacon_work.work); + struct ieee80211_vif *vif = + container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); + struct ieee80211_hw *dev = vif_priv->dev; + struct ieee80211_mgmt *mgmt; + struct sk_buff *skb; + + /* don't overflow the tx ring */ + if (ieee80211_queue_stopped(dev, 0)) + goto resched; + + /* grab a fresh beacon */ + skb = ieee80211_beacon_get(dev, vif, 0); + if (!skb) + goto resched; + + /* + * update beacon timestamp w/ TSF value + * TODO: make hardware update beacon timestamp + */ + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev, vif)); + + /* TODO: use actual beacon queue */ + skb_set_queue_mapping(skb, 0); + + rtl8180_tx(dev, NULL, skb); + +resched: + /* + * schedule next beacon + * TODO: use hardware support for beacon timing + */ + schedule_delayed_work(&vif_priv->beacon_work, + usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); +} + +static int rtl8180_add_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_vif *vif_priv; + + /* + * We only support one active interface at a time. + */ + if (priv->vif) + return -EBUSY; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + break; + default: + return -EOPNOTSUPP; + } + + priv->vif = vif; + + /* Initialize driver private area */ + vif_priv = (struct rtl8180_vif *)&vif->drv_priv; + vif_priv->dev = dev; + INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work); + vif_priv->enable_beacon = false; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], + le32_to_cpu(*(__le32 *)vif->addr)); + rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], + le16_to_cpu(*(__le16 *)(vif->addr + 4))); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + return 0; +} + +static void rtl8180_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8180_priv *priv = dev->priv; + priv->vif = NULL; +} + +static int rtl8180_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) +{ + struct rtl8180_priv *priv = dev->priv; + struct ieee80211_conf *conf = &dev->conf; + + priv->rf->set_chan(dev, conf); + + return 0; +} + +static void rtl8187se_conf_ac_parm(struct ieee80211_hw *dev, u8 queue) +{ + const struct ieee80211_tx_queue_params *params; + struct rtl8180_priv *priv = dev->priv; + + /* hw value */ + u32 ac_param; + + u8 aifs; + u8 txop; + u8 cw_min, cw_max; + + params = &priv->queue_param[queue]; + + cw_min = fls(params->cw_min); + cw_max = fls(params->cw_max); + + aifs = 10 + params->aifs * priv->slot_time; + + /* TODO: check if txop HW is in us (mult by 32) */ + txop = params->txop; + + ac_param = txop << AC_PARAM_TXOP_LIMIT_SHIFT | + cw_max << AC_PARAM_ECW_MAX_SHIFT | + cw_min << AC_PARAM_ECW_MIN_SHIFT | + aifs << AC_PARAM_AIFS_SHIFT; + + switch (queue) { + case IEEE80211_AC_BK: + rtl818x_iowrite32(priv, &priv->map->AC_BK_PARAM, ac_param); + break; + case IEEE80211_AC_BE: + rtl818x_iowrite32(priv, &priv->map->AC_BE_PARAM, ac_param); + break; + case IEEE80211_AC_VI: + rtl818x_iowrite32(priv, &priv->map->AC_VI_PARAM, ac_param); + break; + case IEEE80211_AC_VO: + rtl818x_iowrite32(priv, &priv->map->AC_VO_PARAM, ac_param); + break; + } +} + +static int rtl8180_conf_tx(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cw_min, cw_max; + + /* nothing to do ? */ + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) + return 0; + + cw_min = fls(params->cw_min); + cw_max = fls(params->cw_max); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + priv->queue_param[queue] = *params; + rtl8187se_conf_ac_parm(dev, queue); + } else + rtl818x_iowrite8(priv, &priv->map->CW_VAL, + (cw_max << 4) | cw_min); + return 0; +} + +static void rtl8180_conf_erp(struct ieee80211_hw *dev, + struct ieee80211_bss_conf *info) +{ + struct rtl8180_priv *priv = dev->priv; + u8 sifs, difs; + int eifs; + u8 hw_eifs; + + /* TODO: should we do something ? */ + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) + return; + + /* I _hope_ this means 10uS for the HW. + * In reference code it is 0x22 for + * both rtl8187L and rtl8187SE + */ + sifs = 0x22; + + if (info->use_short_slot) + priv->slot_time = 9; + else + priv->slot_time = 20; + + /* 10 is SIFS time in uS */ + difs = 10 + 2 * priv->slot_time; + eifs = 10 + difs + priv->ack_time; + + /* HW should use 4uS units for EIFS (I'm sure for rtl8185)*/ + hw_eifs = DIV_ROUND_UP(eifs, 4); + + + rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); + rtl818x_iowrite8(priv, &priv->map->SIFS, sifs); + rtl818x_iowrite8(priv, &priv->map->DIFS, difs); + + /* from reference code. set ack timeout reg = eifs reg */ + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, hw_eifs); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + rtl818x_iowrite8(priv, &priv->map->EIFS_8187SE, hw_eifs); + else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { + /* rtl8187/rtl8185 HW bug. After EIFS is elapsed, + * the HW still wait for DIFS. + * HW uses 4uS units for EIFS. + */ + hw_eifs = DIV_ROUND_UP(eifs - difs, 4); + + rtl818x_iowrite8(priv, &priv->map->EIFS, hw_eifs); + } +} + +static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_vif *vif_priv; + int i; + u8 reg; + + vif_priv = (struct rtl8180_vif *)&vif->drv_priv; + + if (changed & BSS_CHANGED_BSSID) { + rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->BSSID[0], + le16_to_cpu(*(__le16 *)info->bssid)); + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->BSSID[2], + le32_to_cpu(*(__le32 *)(info->bssid + 2))); + + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg = RTL818X_MSR_ADHOC; + else + reg = RTL818X_MSR_INFRA; + } else + reg = RTL818X_MSR_NO_LINK; + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + reg |= RTL818X_MSR_ENEDCA; + + rtl818x_iowrite8(priv, &priv->map->MSR, reg); + } + + if (changed & BSS_CHANGED_BASIC_RATES) + rtl8180_conf_basic_rates(dev, info->basic_rates); + + if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) { + + /* when preamble changes, acktime duration changes, and erp must + * be recalculated. ACK time is calculated at lowest rate. + * Since mac80211 include SIFS time we remove it (-10) + */ + priv->ack_time = + le16_to_cpu(ieee80211_generic_frame_duration(dev, + priv->vif, + NL80211_BAND_2GHZ, 10, + &priv->rates[0])) - 10; + + rtl8180_conf_erp(dev, info); + + /* mac80211 supplies aifs_n to driver and calls + * conf_tx callback whether aifs_n changes, NOT + * when aifs changes. + * Aifs should be recalculated if slot changes. + */ + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + for (i = 0; i < 4; i++) + rtl8187se_conf_ac_parm(dev, i); + } + } + + if (changed & BSS_CHANGED_BEACON_ENABLED) + vif_priv->enable_beacon = info->enable_beacon; + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { + cancel_delayed_work_sync(&vif_priv->beacon_work); + if (vif_priv->enable_beacon) + schedule_work(&vif_priv->beacon_work.work); + } +} + +static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, + struct netdev_hw_addr_list *mc_list) +{ + return netdev_hw_addr_list_count(mc_list); +} + +static void rtl8180_configure_filter(struct ieee80211_hw *dev, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct rtl8180_priv *priv = dev->priv; + + if (changed_flags & FIF_FCSFAIL) + priv->rx_conf ^= RTL818X_RX_CONF_FCS; + if (changed_flags & FIF_CONTROL) + priv->rx_conf ^= RTL818X_RX_CONF_CTRL; + if (changed_flags & FIF_OTHER_BSS) + priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; + if (*total_flags & FIF_ALLMULTI || multicast > 0) + priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; + else + priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; + + *total_flags = 0; + + if (priv->rx_conf & RTL818X_RX_CONF_FCS) + *total_flags |= FIF_FCSFAIL; + if (priv->rx_conf & RTL818X_RX_CONF_CTRL) + *total_flags |= FIF_CONTROL; + if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) + *total_flags |= FIF_OTHER_BSS; + if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) + *total_flags |= FIF_ALLMULTI; + + rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); +} + +static const struct ieee80211_ops rtl8180_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .tx = rtl8180_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .start = rtl8180_start, + .stop = rtl8180_stop, + .add_interface = rtl8180_add_interface, + .remove_interface = rtl8180_remove_interface, + .config = rtl8180_config, + .bss_info_changed = rtl8180_bss_info_changed, + .conf_tx = rtl8180_conf_tx, + .prepare_multicast = rtl8180_prepare_multicast, + .configure_filter = rtl8180_configure_filter, + .get_tsf = rtl8180_get_tsf, +}; + +static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct rtl8180_priv *priv = eeprom->data; + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct rtl8180_priv *priv = eeprom->data; + u8 reg = 2 << 6; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); +} + +static void rtl8180_eeprom_read(struct rtl8180_priv *priv) +{ + struct eeprom_93cx6 eeprom = {}; + int eeprom_cck_table_adr; + u16 eeprom_val; + int i; + + eeprom.data = priv; + eeprom.register_read = rtl8180_eeprom_register_read; + eeprom.register_write = rtl8180_eeprom_register_write; + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) + eeprom.width = PCI_EEPROM_WIDTH_93C66; + else + eeprom.width = PCI_EEPROM_WIDTH_93C46; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_PROGRAM); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); + eeprom_val &= 0xFF; + priv->rf_type = eeprom_val; + + eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); + priv->csthreshold = eeprom_val >> 8; + + eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)priv->mac_addr, 3); + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + eeprom_cck_table_adr = 0x30; + else + eeprom_cck_table_adr = 0x10; + + /* CCK TX power */ + for (i = 0; i < 14; i += 2) { + u16 txpwr; + eeprom_93cx6_read(&eeprom, eeprom_cck_table_adr + (i >> 1), + &txpwr); + priv->channels[i].hw_value = txpwr & 0xFF; + priv->channels[i + 1].hw_value = txpwr >> 8; + } + + /* OFDM TX power */ + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { + for (i = 0; i < 14; i += 2) { + u16 txpwr; + eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); + priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; + priv->channels[i + 1].hw_value |= txpwr & 0xFF00; + } + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { + __le32 anaparam; + eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); + priv->anaparam = le32_to_cpu(anaparam); + eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); + } + + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { + eeprom_93cx6_read(&eeprom, 0x3F, &eeprom_val); + priv->antenna_diversity_en = !!(eeprom_val & 0x100); + priv->antenna_diversity_default = (eeprom_val & 0xC00) == 0x400; + + eeprom_93cx6_read(&eeprom, 0x7C, &eeprom_val); + priv->xtal_out = eeprom_val & 0xF; + priv->xtal_in = (eeprom_val & 0xF0) >> 4; + priv->xtal_cal = !!(eeprom_val & 0x1000); + priv->thermal_meter_val = (eeprom_val & 0xF00) >> 8; + priv->thermal_meter_en = !!(eeprom_val & 0x2000); + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + +static int rtl8180_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct ieee80211_hw *dev; + struct rtl8180_priv *priv; + unsigned long mem_len; + unsigned int io_len; + int err; + const char *chip_name, *rf_name = NULL; + u32 reg; + + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n", + pci_name(pdev)); + return err; + } + + err = pci_request_regions(pdev, KBUILD_MODNAME); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n", + pci_name(pdev)); + goto err_disable_dev; + } + + io_len = pci_resource_len(pdev, 0); + mem_len = pci_resource_len(pdev, 1); + + if (mem_len < sizeof(struct rtl818x_csr) || + io_len < sizeof(struct rtl818x_csr)) { + printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n", + pci_name(pdev)); + err = -ENOMEM; + goto err_free_reg; + } + + if ((err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) || + (err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)))) { + printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n", + pci_name(pdev)); + goto err_free_reg; + } + + pci_set_master(pdev); + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops); + if (!dev) { + printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n", + pci_name(pdev)); + err = -ENOMEM; + goto err_free_reg; + } + + priv = dev->priv; + priv->pdev = pdev; + + dev->max_rates = 1; + SET_IEEE80211_DEV(dev, &pdev->dev); + pci_set_drvdata(pdev, dev); + + priv->map_pio = false; + priv->map = pci_iomap(pdev, 1, mem_len); + if (!priv->map) { + priv->map = pci_iomap(pdev, 0, io_len); + priv->map_pio = true; + } + + if (!priv->map) { + dev_err(&pdev->dev, "Cannot map device memory/PIO\n"); + err = -ENOMEM; + goto err_free_dev; + } + + BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); + BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); + + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); + + priv->band.band = NL80211_BAND_2GHZ; + priv->band.channels = priv->channels; + priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); + priv->band.bitrates = priv->rates; + priv->band.n_bitrates = 4; + dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band; + + ieee80211_hw_set(dev, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(dev, RX_INCLUDES_FCS); + + dev->vif_data_size = sizeof(struct rtl8180_vif); + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + dev->max_signal = 65; + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg &= RTL818X_TX_CONF_HWVER_MASK; + switch (reg) { + case RTL818X_TX_CONF_R8180_ABCD: + chip_name = "RTL8180"; + priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180; + break; + + case RTL818X_TX_CONF_R8180_F: + chip_name = "RTL8180vF"; + priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180; + break; + + case RTL818X_TX_CONF_R8185_ABC: + chip_name = "RTL8185"; + priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; + break; + + case RTL818X_TX_CONF_R8185_D: + chip_name = "RTL8185vD"; + priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; + break; + + case RTL818X_TX_CONF_RTL8187SE: + chip_name = "RTL8187SE"; + if (priv->map_pio) { + dev_err(&pdev->dev, + "MMIO failed. PIO not supported on RTL8187SE\n"); + err = -ENOMEM; + goto err_iounmap; + } + priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE; + break; + + default: + printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", + pci_name(pdev), reg >> 25); + err = -ENODEV; + goto err_iounmap; + } + + /* we declare to MAC80211 all the queues except for beacon queue + * that will be eventually handled by DRV. + * TX rings are arranged in such a way that lower is the IDX, + * higher is the priority, in order to achieve direct mapping + * with mac80211, however the beacon queue is an exception and it + * is mapped on the highst tx ring IDX. + */ + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + dev->queues = RTL8187SE_NR_TX_QUEUES - 1; + else + dev->queues = RTL8180_NR_TX_QUEUES - 1; + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { + priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); + pci_try_set_mwi(pdev); + } + + if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) + ieee80211_hw_set(dev, SIGNAL_DBM); + else + ieee80211_hw_set(dev, SIGNAL_UNSPEC); + + wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + rtl8180_eeprom_read(priv); + + switch (priv->rf_type) { + case 1: rf_name = "Intersil"; + break; + case 2: rf_name = "RFMD"; + break; + case 3: priv->rf = &sa2400_rf_ops; + break; + case 4: priv->rf = &max2820_rf_ops; + break; + case 5: priv->rf = &grf5101_rf_ops; + break; + case 9: + if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) + priv->rf = rtl8187se_detect_rf(dev); + else + priv->rf = rtl8180_detect_rf(dev); + break; + case 10: + rf_name = "RTL8255"; + break; + default: + printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", + pci_name(pdev), priv->rf_type); + err = -ENODEV; + goto err_iounmap; + } + + if (!priv->rf) { + printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n", + pci_name(pdev), rf_name); + err = -ENODEV; + goto err_iounmap; + } + + if (!is_valid_ether_addr(priv->mac_addr)) { + printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" + " randomly generated MAC addr\n", pci_name(pdev)); + eth_random_addr(priv->mac_addr); + } + SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr); + + spin_lock_init(&priv->lock); + + err = ieee80211_register_hw(dev); + if (err) { + printk(KERN_ERR "%s (rtl8180): Cannot register device\n", + pci_name(pdev)); + goto err_iounmap; + } + + wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", + priv->mac_addr, chip_name, priv->rf->name); + + return 0; + + err_iounmap: + pci_iounmap(pdev, priv->map); + + err_free_dev: + ieee80211_free_hw(dev); + + err_free_reg: + pci_release_regions(pdev); + + err_disable_dev: + pci_disable_device(pdev); + return err; +} + +static void rtl8180_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *dev = pci_get_drvdata(pdev); + struct rtl8180_priv *priv; + + if (!dev) + return; + + ieee80211_unregister_hw(dev); + + priv = dev->priv; + + pci_iounmap(pdev, priv->map); + pci_release_regions(pdev); + pci_disable_device(pdev); + ieee80211_free_hw(dev); +} + +#define rtl8180_suspend NULL +#define rtl8180_resume NULL + +static SIMPLE_DEV_PM_OPS(rtl8180_pm_ops, rtl8180_suspend, rtl8180_resume); + +static struct pci_driver rtl8180_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8180_table, + .probe = rtl8180_probe, + .remove = rtl8180_remove, + .driver.pm = &rtl8180_pm_ops, +}; + +module_pci_driver(rtl8180_driver); diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c new file mode 100644 index 000000000..fda6ba796 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Radio tuning for GCT GRF5101 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#include +#include +#include + +#include "rtl8180.h" +#include "grf5101.h" + +static const int grf5101_encode[] = { + 0x0, 0x8, 0x4, 0xC, + 0x2, 0xA, 0x6, 0xE, + 0x1, 0x9, 0x5, 0xD, + 0x3, 0xB, 0x7, 0xF +}; + +static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + phy_config = grf5101_encode[(data >> 8) & 0xF]; + phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4; + phy_config |= grf5101_encode[data & 0xF] << 8; + phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12; + phy_config |= (addr & 1) << 16; + phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24; + + /* MAC will bang bits to the chip */ + phy_config |= 0x90000000; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(3); +} + +static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant = GRF5101_ANTENNA; + + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); +} + +static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) +{ + if (agc > 60) + return 65; + + /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ + return 65 * agc / 60; +} + +static void grf5101_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); + u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; + u32 chan = channel - 1; + + /* set TX power */ + write_grf5101(dev, 0x15, 0x0); + write_grf5101(dev, 0x06, txpw); + write_grf5101(dev, 0x15, 0x10); + write_grf5101(dev, 0x15, 0x0); + + /* set frequency */ + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x0B, chan); + write_grf5101(dev, 0x07, 0x1000); + + grf5101_write_phy_antenna(dev, channel); +} + +static void grf5101_rf_stop(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u32 anaparam; + + anaparam = priv->anaparam; + anaparam &= 0x000fffff; + anaparam |= 0x3f900000; + rtl8180_set_anaparam(priv, anaparam); + + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x1f, 0x45); + write_grf5101(dev, 0x1f, 0x5); + write_grf5101(dev, 0x00, 0x8e4); +} + +static void grf5101_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + rtl8180_set_anaparam(priv, priv->anaparam); + + write_grf5101(dev, 0x1f, 0x0); + write_grf5101(dev, 0x1f, 0x0); + write_grf5101(dev, 0x1f, 0x40); + write_grf5101(dev, 0x1f, 0x60); + write_grf5101(dev, 0x1f, 0x61); + write_grf5101(dev, 0x1f, 0x61); + write_grf5101(dev, 0x00, 0xae4); + write_grf5101(dev, 0x1f, 0x1); + write_grf5101(dev, 0x1f, 0x41); + write_grf5101(dev, 0x1f, 0x61); + + write_grf5101(dev, 0x01, 0x1a23); + write_grf5101(dev, 0x02, 0x4971); + write_grf5101(dev, 0x03, 0x41de); + write_grf5101(dev, 0x04, 0x2d80); + write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */ + write_grf5101(dev, 0x06, 0x0); + write_grf5101(dev, 0x07, 0x0); + write_grf5101(dev, 0x08, 0x7533); + write_grf5101(dev, 0x09, 0xc401); + write_grf5101(dev, 0x0a, 0x0); + write_grf5101(dev, 0x0c, 0x1c7); + write_grf5101(dev, 0x0d, 0x29d3); + write_grf5101(dev, 0x0e, 0x2e8); + write_grf5101(dev, 0x10, 0x192); + write_grf5101(dev, 0x11, 0x248); + write_grf5101(dev, 0x12, 0x0); + write_grf5101(dev, 0x13, 0x20c4); + write_grf5101(dev, 0x14, 0xf4fc); + write_grf5101(dev, 0x15, 0x0); + write_grf5101(dev, 0x16, 0x1500); + + write_grf5101(dev, 0x07, 0x1000); + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0xa8); + rtl8180_write_phy(dev, 3, 0x0); + rtl8180_write_phy(dev, 4, 0xc0); + rtl8180_write_phy(dev, 5, 0x90); + rtl8180_write_phy(dev, 6, 0x1e); + rtl8180_write_phy(dev, 7, 0x64); + + grf5101_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x88); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */ + else + rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */ + + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); + + rtl8180_write_phy(dev, 0x19, 0x0); + rtl8180_write_phy(dev, 0x1a, 0xa0); + rtl8180_write_phy(dev, 0x1b, 0x44); +} + +const struct rtl818x_rf_ops grf5101_rf_ops = { + .name = "GCT", + .init = grf5101_rf_init, + .stop = grf5101_rf_stop, + .set_chan = grf5101_rf_set_channel, + .calc_rssi = grf5101_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h new file mode 100644 index 000000000..91ff3185c --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef RTL8180_GRF5101_H +#define RTL8180_GRF5101_H + +/* + * Radio tuning for GCT GRF5101 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#define GRF5101_ANTENNA 0xA3 + +extern const struct rtl818x_rf_ops grf5101_rf_ops; + +#endif /* RTL8180_GRF5101_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c new file mode 100644 index 000000000..27d04fec3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Radio tuning for Maxim max2820 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#include +#include +#include + +#include "rtl8180.h" +#include "max2820.h" + +static const u32 max2820_chan[] = { + 12, /* CH 1 */ + 17, + 22, + 27, + 32, + 37, + 42, + 47, + 52, + 57, + 62, + 67, + 72, + 84, /* CH 14 */ +}; + +static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + phy_config = 0x90 + (data & 0xf); + phy_config <<= 16; + phy_config += addr; + phy_config <<= 8; + phy_config += (data >> 4) & 0xff; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(1); +} + +static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant; + + ant = MAXIM_ANTENNA; + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); +} + +static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) +{ + bool odd; + + odd = !!(agc & 1); + + agc >>= 1; + if (odd) + agc += 76; + else + agc += 66; + + /* TODO: change addends above to avoid mult / div below */ + return 65 * agc / 100; +} + +static void max2820_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = conf ? + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1; + unsigned int chan_idx = channel - 1; + u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; + u32 chan = max2820_chan[chan_idx]; + + /* While philips SA2400 drive the PA bias from + * sa2400, for MAXIM we do this directly from BB */ + rtl8180_write_phy(dev, 3, txpw); + + max2820_write_phy_antenna(dev, channel); + write_max2820(dev, 3, chan); +} + +static void max2820_rf_stop(struct ieee80211_hw *dev) +{ + rtl8180_write_phy(dev, 3, 0x8); + write_max2820(dev, 1, 0); +} + + +static void max2820_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + /* MAXIM from netbsd driver */ + write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */ + write_max2820(dev, 1, 0x01e); /* enable register */ + write_max2820(dev, 2, 0x001); /* synt register */ + + max2820_rf_set_channel(dev, NULL); + + write_max2820(dev, 4, 0x313); /* rx register */ + + /* PA is driven directly by the BB, we keep the MAXIM bias + * at the highest value in case that setting it to lower + * values may introduce some further attenuation somewhere.. + */ + write_max2820(dev, 5, 0x00f); + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0x88); /* sys1 */ + rtl8180_write_phy(dev, 3, 0x08); /* txagc */ + rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */ + rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */ + rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */ + rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */ + + max2820_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x88); /* trl */ + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc7); + else + rtl8180_write_phy(dev, 0x12, 0x47); + + rtl8180_write_phy(dev, 0x13, 0x9b); + + rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */ + rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */ + + max2820_rf_set_channel(dev, NULL); +} + +const struct rtl818x_rf_ops max2820_rf_ops = { + .name = "Maxim", + .init = max2820_rf_init, + .stop = max2820_rf_stop, + .set_chan = max2820_rf_set_channel, + .calc_rssi = max2820_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h new file mode 100644 index 000000000..4cb800d2d --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef RTL8180_MAX2820_H +#define RTL8180_MAX2820_H + +/* + * Radio tuning for Maxim max2820 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#define MAXIM_ANTENNA 0xb3 + +extern const struct rtl818x_rf_ops max2820_rf_ops; + +#endif /* RTL8180_MAX2820_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h new file mode 100644 index 000000000..2ff00800d --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RTL8180_H +#define RTL8180_H + +#include "rtl818x.h" + +#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD + +#define RF_PARAM_ANALOGPHY (1 << 0) +#define RF_PARAM_ANTBDEFAULT (1 << 1) +#define RF_PARAM_CARRIERSENSE1 (1 << 2) +#define RF_PARAM_CARRIERSENSE2 (1 << 3) + +#define BB_ANTATTEN_CHAN14 0x0C +#define BB_ANTENNA_B 0x40 + +#define BB_HOST_BANG (1 << 30) +#define BB_HOST_BANG_EN (1 << 2) +#define BB_HOST_BANG_CLK (1 << 1) +#define BB_HOST_BANG_DATA 1 + +#define ANAPARAM_TXDACOFF_SHIFT 27 +#define ANAPARAM_PWR0_SHIFT 28 +#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT) +#define ANAPARAM_PWR1_SHIFT 20 +#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) + +/* rtl8180/rtl8185 have 3 queue + beacon queue. + * mac80211 can use just one, + beacon = 2 tot. + */ +#define RTL8180_NR_TX_QUEUES 2 + +/* rtl8187SE have 6 queues + beacon queues + * mac80211 can use 4 QoS data queue, + beacon = 5 tot + */ +#define RTL8187SE_NR_TX_QUEUES 5 + +/* for array static allocation, it is the max of above */ +#define RTL818X_NR_TX_QUEUES 5 + +struct rtl8180_tx_desc { + __le32 flags; + __le16 rts_duration; + __le16 plcp_len; + __le32 tx_buf; + union{ + __le32 frame_len; + struct { + __le16 frame_len_se; + __le16 frame_duration; + } __packed; + } __packed; + __le32 next_tx_desc; + u8 cw; + u8 retry_limit; + u8 agc; + u8 flags2; + /* rsvd for 8180/8185. + * valid for 8187se but we dont use it + */ + u32 reserved; + /* all rsvd for 8180/8185 */ + __le16 flags3; + __le16 frag_qsize; +} __packed; + +struct rtl818x_rx_cmd_desc { + __le32 flags; + u32 reserved; + __le32 rx_buf; +} __packed; + +struct rtl8180_rx_desc { + __le32 flags; + __le32 flags2; + __le64 tsft; + +} __packed; + +struct rtl8187se_rx_desc { + __le32 flags; + __le64 tsft; + __le32 flags2; + __le32 flags3; + u32 reserved[3]; +} __packed; + +struct rtl8180_tx_ring { + struct rtl8180_tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; +}; + +struct rtl8180_vif { + struct ieee80211_hw *dev; + + /* beaconing */ + struct delayed_work beacon_work; + bool enable_beacon; +}; + +struct rtl8180_priv { + /* common between rtl818x drivers */ + struct rtl818x_csr __iomem *map; + const struct rtl818x_rf_ops *rf; + struct ieee80211_vif *vif; + + /* rtl8180 driver specific */ + bool map_pio; + spinlock_t lock; + void *rx_ring; + u8 rx_ring_sz; + dma_addr_t rx_ring_dma; + unsigned int rx_idx; + struct sk_buff *rx_buf[32]; + struct rtl8180_tx_ring tx_ring[RTL818X_NR_TX_QUEUES]; + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_supported_band band; + struct ieee80211_tx_queue_params queue_param[4]; + struct pci_dev *pdev; + u32 rx_conf; + u8 slot_time; + u16 ack_time; + + enum { + RTL818X_CHIP_FAMILY_RTL8180, + RTL818X_CHIP_FAMILY_RTL8185, + RTL818X_CHIP_FAMILY_RTL8187SE, + } chip_family; + u32 anaparam; + u16 rfparam; + u8 csthreshold; + u8 mac_addr[ETH_ALEN]; + u8 rf_type; + u8 xtal_out; + u8 xtal_in; + u8 xtal_cal; + u8 thermal_meter_val; + u8 thermal_meter_en; + u8 antenna_diversity_en; + u8 antenna_diversity_default; + /* sequence # */ + u16 seqno; +}; + +void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); +void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); +void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2); + +static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, const u8 __iomem *addr) +{ + return ioread8(addr); +} + +static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, const __le16 __iomem *addr) +{ + return ioread16(addr); +} + +static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, const __le32 __iomem *addr) +{ + return ioread32(addr); +} + +static inline void rtl818x_iowrite8(struct rtl8180_priv *priv, + u8 __iomem *addr, u8 val) +{ + iowrite8(val, addr); +} + +static inline void rtl818x_iowrite16(struct rtl8180_priv *priv, + __le16 __iomem *addr, u16 val) +{ + iowrite16(val, addr); +} + +static inline void rtl818x_iowrite32(struct rtl8180_priv *priv, + __le32 __iomem *addr, u32 val) +{ + iowrite32(val, addr); +} + +#endif /* RTL8180_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c new file mode 100644 index 000000000..470a869e6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c @@ -0,0 +1,767 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Radio tuning for RTL8225 on RTL8180 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8180 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + */ + +#include +#include +#include + +#include "rtl8180.h" +#include "rtl8225.h" + +static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg80, reg84, reg82; + u32 bangdata; + int i; + + bangdata = (data << 4) | (addr & 0xf); + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); + + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + for (i = 15; i >= 0; i--) { + u16 reg = reg80; + + if (bangdata & (1 << i)) + reg |= 1; + + if (i & 1) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + + if (!(i & 1)) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); +} + +static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg80, reg82, reg84, out; + int i; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400; + + reg80 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(4); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(5); + + for (i = 4; i >= 0; i--) { + u16 reg = reg80 | ((addr >> i) & 1); + + if (!(i & 1)) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + if (i & 1) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + } + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + out = 0; + for (i = 11; i >= 0; i--) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(1); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) + out |= 1 << i; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 2)); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); + + return out; +} + +static const u16 rtl8225bcd_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb +}; + +static const u8 rtl8225_agc[] = { + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const u8 rtl8225_gain[] = { + 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */ + 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */ + 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */ + 0x33, 0x80, 0x79, 0xc5, /* -78dbm */ + 0x43, 0x78, 0x76, 0xc5, /* -74dbm */ + 0x53, 0x60, 0x73, 0xc5, /* -70dbm */ + 0x63, 0x58, 0x70, 0xc5, /* -66dbm */ +}; + +static const u8 rtl8225_threshold[] = { + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd +}; + +static const u8 rtl8225_tx_gain_cck_ofdm[] = { + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e +}; + +static const u8 rtl8225_tx_power_cck[] = { + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 +}; + +static const u8 rtl8225_tx_power_cck_ch14[] = { + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225_tx_power_ofdm[] = { + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 +}; + +static const u32 rtl8225_chan[] = { + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 +}; + +static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xFF; + ofdm_power = priv->channels[channel - 1].hw_value >> 8; + + cck_power = min(cck_power, (u8)35); + ofdm_power = min(ofdm_power, (u8)35); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); + + if (channel == 14) + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; + else + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + msleep(1); /* FIXME: optional? */ + + /* TODO: use set_anaparam2 dev.c_func*/ + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1); + + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; + + rtl8225_write_phy_ofdm(dev, 5, *tmp); + rtl8225_write_phy_ofdm(dev, 7, *tmp); + + msleep(1); +} + +static void rtl8225_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); + + /* host_pci_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(200); /* FIXME: ehh?? */ + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); + + /* TODO: check if we need really to change BRSR to do RF config */ + rtl818x_ioread16(priv, &priv->map->BRSR); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write(dev, 0x0, 0x067); + rtl8225_write(dev, 0x1, 0xFE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8BE); + rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */ + rtl8225_write(dev, 0x6, 0xAE6); + rtl8225_write(dev, 0x7, rtl8225_chan[0]); + rtl8225_write(dev, 0x8, 0x01F); + rtl8225_write(dev, 0x9, 0x334); + rtl8225_write(dev, 0xA, 0xFD4); + rtl8225_write(dev, 0xB, 0x391); + rtl8225_write(dev, 0xC, 0x050); + rtl8225_write(dev, 0xD, 0x6DB); + rtl8225_write(dev, 0xE, 0x029); + rtl8225_write(dev, 0xF, 0x914); msleep(1); + + rtl8225_write(dev, 0x2, 0xC4D); msleep(100); + + rtl8225_write(dev, 0x0, 0x127); + + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x027); + rtl8225_write(dev, 0x0, 0x22F); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1); + + rtl8225_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + rtl8225_write(dev, 0x0c, 0x50); + /* set OFDM initial gain */ + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]); + /* set CCK threshold */ + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]); +} + +static const u8 rtl8225z2_tx_power_cck_ch14[] = { + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225z2_tx_power_cck_B[] = { + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 +}; + +static const u8 rtl8225z2_tx_power_cck_A[] = { + 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 +}; + +static const u8 rtl8225z2_tx_power_cck[] = { + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 +}; + +static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xFF; + ofdm_power = priv->channels[channel - 1].hw_value >> 8; + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else if (cck_power == 12) + tmp = rtl8225z2_tx_power_cck_B; + else if (cck_power == 13) + tmp = rtl8225z2_tx_power_cck_A; + else + tmp = rtl8225z2_tx_power_cck; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + cck_power = min(cck_power, (u8)35); + if (cck_power == 13 || cck_power == 14) + cck_power = 12; + if (cck_power >= 15) + cck_power -= 2; + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power); + rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK); + msleep(1); + + ofdm_power = min(ofdm_power, (u8)35); + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power); + + rtl8225_write_phy_ofdm(dev, 2, 0x62); + rtl8225_write_phy_ofdm(dev, 5, 0x00); + rtl8225_write_phy_ofdm(dev, 6, 0x40); + rtl8225_write_phy_ofdm(dev, 7, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x40); + + msleep(1); +} + +static const u16 rtl8225z2_rxgain[] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009, + 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141, + 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183, + 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244, + 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288, + 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345, + 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389, + 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393, + 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb +}; + +static void rtl8225z2_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); + + /* host_pci_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(200); /* FIXME: ehh?? */ + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008); + + /* TODO: check if we need really to change BRSR to do RF config */ + rtl818x_ioread16(priv, &priv->map->BRSR); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + rtl8225_write(dev, 0x0, 0x0B7); msleep(1); + rtl8225_write(dev, 0x1, 0xEE0); msleep(1); + rtl8225_write(dev, 0x2, 0x44D); msleep(1); + rtl8225_write(dev, 0x3, 0x441); msleep(1); + rtl8225_write(dev, 0x4, 0x8C3); msleep(1); + rtl8225_write(dev, 0x5, 0xC72); msleep(1); + rtl8225_write(dev, 0x6, 0x0E6); msleep(1); + rtl8225_write(dev, 0x7, 0x82A); msleep(1); + rtl8225_write(dev, 0x8, 0x03F); msleep(1); + rtl8225_write(dev, 0x9, 0x335); msleep(1); + rtl8225_write(dev, 0xa, 0x9D4); msleep(1); + rtl8225_write(dev, 0xb, 0x7BB); msleep(1); + rtl8225_write(dev, 0xc, 0x850); msleep(1); + rtl8225_write(dev, 0xd, 0xCDF); msleep(1); + rtl8225_write(dev, 0xe, 0x02B); msleep(1); + rtl8225_write(dev, 0xf, 0x114); msleep(100); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0C4D); + msleep(200); + rtl8225_write(dev, 0x02, 0x044D); + msleep(100); + /* TODO: readd calibration failure message when the calibration + check works */ + } + + rtl8225_write(dev, 0x0, 0x1B7); + rtl8225_write(dev, 0x3, 0x002); + rtl8225_write(dev, 0x5, 0x004); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x0B7); msleep(100); + rtl8225_write(dev, 0x2, 0xC4D); + + msleep(200); + rtl8225_write(dev, 0x2, 0x44D); + msleep(100); + + rtl8225_write(dev, 0x00, 0x2BF); + rtl8225_write(dev, 0xFF, 0xFFFF); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */ + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1); + + rtl8225z2_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); +} + +static void rtl8225_rf_stop(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u8 reg; + + rtl8225_write(dev, 0x4, 0x1f); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); +} + +static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int chan = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); + + if (priv->rf->init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, chan); + else + rtl8225z2_rf_set_tx_power(dev, chan); + + rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); + msleep(10); +} + +static const struct rtl818x_rf_ops rtl8225_ops = { + .name = "rtl8225", + .init = rtl8225_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel, +}; + +static const struct rtl818x_rf_ops rtl8225z2_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel, +}; + +const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u16 reg8, reg9; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + msleep(100); + + rtl8225_write(dev, 0, 0x1B7); + + reg8 = rtl8225_read(dev, 8); + reg9 = rtl8225_read(dev, 9); + + rtl8225_write(dev, 0, 0x0B7); + + if (reg8 != 0x588 || reg9 != 0x700) + return &rtl8225_ops; + + return &rtl8225z2_ops; +} diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h new file mode 100644 index 000000000..de7727b74 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RTL8180_RTL8225_H +#define RTL8180_RTL8225_H + +#define RTL8225_ANAPARAM_ON 0xa0000b59 +#define RTL8225_ANAPARAM2_ON 0x860dec11 +#define RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8225_ANAPARAM2_OFF 0x840dec11 + +const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *); + +static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data); +} + +static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data | 0x10000); +} + +#endif /* RTL8180_RTL8225_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c new file mode 100644 index 000000000..e1bf41c27 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Radio tuning for RTL8225 on RTL8187SE + * + * Copyright 2009 Larry Finger + * Copyright 2014 Andrea Merello + * + * Based on the r8180 and Realtek r8187se drivers, which are: + * Copyright 2004-2005 Andrea Merello , et al. + * + * Also based on the rtl8187 driver, which is: + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + */ + +#include + +#include "rtl8180.h" +#include "rtl8225se.h" + +#define PFX "rtl8225 (se) " + +static const u32 RF_GAIN_TABLE[] = { + 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, + 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, + 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, + 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, + 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 +}; + +static const u8 cck_ofdm_gain_settings[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, +}; + +static const u32 rtl8225se_chan[] = { + 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380, + 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A, +}; + +static const u8 ZEBRA_AGC[] = { + 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, + 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, + 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, + 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, + 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, + 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, + 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, + 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, + 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, + 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, + 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, + 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F +}; + +static const u8 OFDM_CONFIG[] = { + 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, + 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, + 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, + 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, + 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, + 0xD8, 0x3C, 0x7B, 0x10, 0x10 +}; + +static void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data, + u8 len, bool write) +{ + struct rtl8180_priv *priv = dev->priv; + int i; + u8 tmp; + + do { + for (i = 0; i < 5; i++) { + tmp = rtl818x_ioread8(priv, SW_3W_CMD1); + if (!(tmp & 0x3)) + break; + udelay(10); + } + if (i == 5) + wiphy_err(dev->wiphy, PFX + "CmdReg: 0x%x RE/WE bits aren't clear\n", tmp); + + tmp = rtl818x_ioread8(priv, &priv->map->rf_sw_config) | 0x02; + rtl818x_iowrite8(priv, &priv->map->rf_sw_config, tmp); + + tmp = rtl818x_ioread8(priv, REG_ADDR1(0x84)) & 0xF7; + rtl818x_iowrite8(priv, REG_ADDR1(0x84), tmp); + if (write) { + if (len == 16) { + rtl818x_iowrite16(priv, SW_3W_DB0, + *(u16 *)data); + } else if (len == 64) { + rtl818x_iowrite32(priv, SW_3W_DB0_4, + *((u32 *)data)); + rtl818x_iowrite32(priv, SW_3W_DB1_4, + *((u32 *)(data + 4))); + } else + wiphy_err(dev->wiphy, PFX + "Unimplemented length\n"); + } else { + rtl818x_iowrite16(priv, SW_3W_DB0, *(u16 *)data); + } + if (write) + tmp = 2; + else + tmp = 1; + rtl818x_iowrite8(priv, SW_3W_CMD1, tmp); + for (i = 0; i < 5; i++) { + tmp = rtl818x_ioread8(priv, SW_3W_CMD1); + if (!(tmp & 0x3)) + break; + udelay(10); + } + rtl818x_iowrite8(priv, SW_3W_CMD1, 0); + if (!write) { + *((u16 *)data) = rtl818x_ioread16(priv, SI_DATA_REG); + *((u16 *)data) &= 0x0FFF; + } + } while (0); +} + +static u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr) +{ + u32 dataread = addr & 0x0F; + rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0); + return dataread; +} + +static void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + u32 outdata = (data << 4) | (u32)(addr & 0x0F); + rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1); +} + + +static void rtl8225se_write_zebra_agc(struct ieee80211_hw *dev) +{ + int i; + + for (i = 0; i < 128; i++) { + rtl8225se_write_phy_ofdm(dev, 0xF, ZEBRA_AGC[i]); + rtl8225se_write_phy_ofdm(dev, 0xE, i+0x80); + rtl8225se_write_phy_ofdm(dev, 0xE, 0); + } +} + +static void rtl8187se_write_ofdm_config(struct ieee80211_hw *dev) +{ + /* write OFDM_CONFIG table */ + int i; + + for (i = 0; i < 60; i++) + rtl8225se_write_phy_ofdm(dev, i, OFDM_CONFIG[i]); + +} + +static void rtl8225sez2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8180_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + + cck_power = priv->channels[channel - 1].hw_value & 0xFF; + if (cck_power > 35) + cck_power = 35; + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + cck_ofdm_gain_settings[cck_power]); + + usleep_range(1000, 5000); + ofdm_power = priv->channels[channel - 1].hw_value >> 8; + if (ofdm_power > 35) + ofdm_power = 35; + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + cck_ofdm_gain_settings[ofdm_power]); + if (ofdm_power < 12) { + rtl8225se_write_phy_ofdm(dev, 7, 0x5C); + rtl8225se_write_phy_ofdm(dev, 9, 0x5C); + } + if (ofdm_power < 18) { + rtl8225se_write_phy_ofdm(dev, 7, 0x54); + rtl8225se_write_phy_ofdm(dev, 9, 0x54); + } else { + rtl8225se_write_phy_ofdm(dev, 7, 0x50); + rtl8225se_write_phy_ofdm(dev, 9, 0x50); + } + + usleep_range(1000, 5000); +} + +static void rtl8187se_write_rf_gain(struct ieee80211_hw *dev) +{ + int i; + + for (i = 0; i <= 36; i++) { + rtl8187se_rf_writereg(dev, 0x01, i); mdelay(1); + rtl8187se_rf_writereg(dev, 0x02, RF_GAIN_TABLE[i]); mdelay(1); + } +} + +static void rtl8187se_write_initial_gain(struct ieee80211_hw *dev, + int init_gain) +{ + switch (init_gain) { + default: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); + break; + case 2: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); + break; + case 3: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); + break; + case 4: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); + break; + case 5: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); + break; + case 6: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); + break; + case 7: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0xA6); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); + break; + case 8: + rtl8225se_write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x24, 0xB6); mdelay(1); + rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); + break; + } +} + +void rtl8225se_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u32 rf23, rf24; + u8 d_cut = 0; + u8 tmp; + + /* Page 1 */ + rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); + rf23 = rtl8187se_rf_readreg(dev, 0x08); mdelay(1); + rf24 = rtl8187se_rf_readreg(dev, 0x09); mdelay(1); + if (rf23 == 0x0818 && rf24 == 0x070C) + d_cut = 1; + + wiphy_info(dev->wiphy, "RTL8225-SE version %s\n", + d_cut ? "D" : "not-D"); + + /* Page 0: reg 0 - 15 */ + rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); + rtl8187se_rf_writereg(dev, 0x01, 0x06E0); mdelay(1); + rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); + rtl8187se_rf_writereg(dev, 0x03, 0x07F1); mdelay(1); + rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(1); + rtl8187se_rf_writereg(dev, 0x05, 0x0C72); mdelay(1); + rtl8187se_rf_writereg(dev, 0x06, 0x0AE6); mdelay(1); + rtl8187se_rf_writereg(dev, 0x07, 0x00CA); mdelay(1); + rtl8187se_rf_writereg(dev, 0x08, 0x0E1C); mdelay(1); + rtl8187se_rf_writereg(dev, 0x09, 0x02F0); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0A, 0x09D0); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0B, 0x01BA); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0C, 0x0640); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0E, 0x0020); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0F, 0x0990); mdelay(1); + /* page 1: reg 16-30 */ + rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); + rtl8187se_rf_writereg(dev, 0x03, 0x0806); mdelay(1); + rtl8187se_rf_writereg(dev, 0x04, 0x03A7); mdelay(1); + rtl8187se_rf_writereg(dev, 0x05, 0x059B); mdelay(1); + rtl8187se_rf_writereg(dev, 0x06, 0x0081); mdelay(1); + rtl8187se_rf_writereg(dev, 0x07, 0x01A0); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0B, 0x0418); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0C, 0x0FBE); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(1); + if (d_cut) + rtl8187se_rf_writereg(dev, 0x0E, 0x0807); + else + rtl8187se_rf_writereg(dev, 0x0E, 0x0806); + mdelay(1); + rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); mdelay(1); + rtl8187se_rf_writereg(dev, 0x00, 0x01D7); mdelay(1); + rtl8187se_rf_writereg(dev, 0x03, 0x0E00); mdelay(1); + rtl8187se_rf_writereg(dev, 0x04, 0x0E50); mdelay(1); + + rtl8187se_write_rf_gain(dev); + + rtl8187se_rf_writereg(dev, 0x05, 0x0203); mdelay(1); + rtl8187se_rf_writereg(dev, 0x06, 0x0200); mdelay(1); + rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); + rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(11); + rtl8187se_rf_writereg(dev, 0x00, 0x0037); mdelay(11); + rtl8187se_rf_writereg(dev, 0x04, 0x0160); mdelay(11); + rtl8187se_rf_writereg(dev, 0x07, 0x0080); mdelay(11); + rtl8187se_rf_writereg(dev, 0x02, 0x088D); msleep(221); + rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); + rtl8187se_rf_writereg(dev, 0x07, 0x0000); mdelay(1); + rtl8187se_rf_writereg(dev, 0x07, 0x0180); mdelay(1); + rtl8187se_rf_writereg(dev, 0x07, 0x0220); mdelay(1); + rtl8187se_rf_writereg(dev, 0x07, 0x03E0); mdelay(1); + rtl8187se_rf_writereg(dev, 0x06, 0x00C1); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); + if (priv->xtal_cal) { + tmp = (priv->xtal_in << 4) | (priv->xtal_out << 1) | + (1 << 11) | (1 << 9); + rtl8187se_rf_writereg(dev, 0x0F, tmp); + wiphy_info(dev->wiphy, "Xtal cal\n"); + mdelay(1); + } else { + wiphy_info(dev->wiphy, "NO Xtal cal\n"); + rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); + mdelay(1); + } + /* page 0 */ + rtl8187se_rf_writereg(dev, 0x00, 0x00BF); mdelay(1); + rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); + rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); + rtl8187se_rf_writereg(dev, 0x04, 0x0975); msleep(31); + rtl8187se_rf_writereg(dev, 0x00, 0x0197); mdelay(1); + rtl8187se_rf_writereg(dev, 0x05, 0x05AB); mdelay(1); + + rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); + rtl8187se_rf_writereg(dev, 0x01, 0x0000); mdelay(1); + rtl8187se_rf_writereg(dev, 0x02, 0x0000); mdelay(1); + /* power save parameters */ + /* TODO: move to dev.c */ + rtl818x_iowrite8(priv, REG_ADDR1(0x024E), + rtl818x_ioread8(priv, REG_ADDR1(0x24E)) & 0x9F); + rtl8225se_write_phy_cck(dev, 0x00, 0xC8); + rtl8225se_write_phy_cck(dev, 0x06, 0x1C); + rtl8225se_write_phy_cck(dev, 0x10, 0x78); + rtl8225se_write_phy_cck(dev, 0x2E, 0xD0); + rtl8225se_write_phy_cck(dev, 0x2F, 0x06); + rtl8225se_write_phy_cck(dev, 0x01, 0x46); + + /* power control */ + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x10); + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x1B); + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); + rtl8225se_write_phy_ofdm(dev, 0x00, 0x12); + + rtl8225se_write_zebra_agc(dev); + + rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); + + rtl8187se_write_ofdm_config(dev); + + /* turn on RF */ + rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); + rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); + /* turn on RF again */ + rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); + rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); + /* turn on BB */ + rtl8225se_write_phy_ofdm(dev, 0x10, 0x40); + rtl8225se_write_phy_ofdm(dev, 0x12, 0x40); + + rtl8187se_write_initial_gain(dev, 4); +} + +void rtl8225se_rf_stop(struct ieee80211_hw *dev) +{ + /* checked for 8187se */ + struct rtl8180_priv *priv = dev->priv; + + /* turn off BB RXIQ matrix to cut off rx signal */ + rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); + rtl8225se_write_phy_ofdm(dev, 0x12, 0x00); + /* turn off RF */ + rtl8187se_rf_writereg(dev, 0x04, 0x0000); + rtl8187se_rf_writereg(dev, 0x00, 0x0000); + + usleep_range(1000, 5000); + /* turn off A/D and D/A */ + rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_OFF); + rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_OFF); +} + +void rtl8225se_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + int chan = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); + + rtl8225sez2_rf_set_tx_power(dev, chan); + rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); + if ((rtl8187se_rf_readreg(dev, 0x7) & 0x0F80) != + rtl8225se_chan[chan - 1]) + rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); + usleep_range(10000, 20000); +} + +static const struct rtl818x_rf_ops rtl8225se_ops = { + .name = "rtl8225-se", + .init = rtl8225se_rf_init, + .stop = rtl8225se_rf_stop, + .set_chan = rtl8225se_rf_set_channel, +}; + +const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *dev) +{ + return &rtl8225se_ops; +} diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h new file mode 100644 index 000000000..f00972661 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Definitions for RTL8187SE hardware + * + * Copyright 2009 Larry Finger + * Copyright 2014 Andrea Merello + * + * Based on the r8180 and Realtek r8187se drivers, which are: + * Copyright 2004-2005 Andrea Merello , et al. + * + * Also based on the rtl8187 driver, which is: + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + */ + +#ifndef RTL8187SE_RTL8225_H +#define RTL8187SE_RTL8225_H + +#define RTL8225SE_ANAPARAM_ON 0xb0054d00 +#define RTL8225SE_ANAPARAM2_ON 0x000004c6 + +/* all off except PLL */ +#define RTL8225SE_ANAPARAM_OFF 0xb0054dec +/* all on including PLL */ +#define RTL8225SE_ANAPARAM_OFF2 0xb0054dfc + +#define RTL8225SE_ANAPARAM2_OFF 0x00ff04c6 + +#define RTL8225SE_ANAPARAM3 0x10 + +enum rtl8187se_power_state { + RTL8187SE_POWER_ON, + RTL8187SE_POWER_OFF, + RTL8187SE_POWER_SLEEP +}; + +static inline void rtl8225se_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data); +} + +static inline void rtl8225se_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u8 data) +{ + rtl8180_write_phy(dev, addr, data | 0x10000); +} + + +const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *); +void rtl8225se_rf_stop(struct ieee80211_hw *dev); +void rtl8225se_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf); +void rtl8225se_rf_conf_erp(struct ieee80211_hw *dev, + struct ieee80211_bss_conf *info); +void rtl8225se_rf_init(struct ieee80211_hw *dev); + +#endif /* RTL8187SE_RTL8225_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c new file mode 100644 index 000000000..dd12f5cdb --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Radio tuning for Philips SA2400 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#include +#include +#include + +#include "rtl8180.h" +#include "sa2400.h" + +static const u32 sa2400_chan[] = { + 0x00096c, /* ch1 */ + 0x080970, + 0x100974, + 0x180978, + 0x000980, + 0x080984, + 0x100988, + 0x18098c, + 0x000994, + 0x080998, + 0x10099c, + 0x1809a0, + 0x0009a8, + 0x0009b4, /* ch 14 */ +}; + +static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8180_priv *priv = dev->priv; + u32 phy_config; + + /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */ + phy_config = 0xb0000000; + + phy_config |= ((u32)(addr & 0xf)) << 24; + phy_config |= data & 0xffffff; + + rtl818x_iowrite32(priv, + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); + + msleep(3); +} + +static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) +{ + struct rtl8180_priv *priv = dev->priv; + u8 ant = SA2400_ANTENNA; + + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) + ant |= BB_ANTENNA_B; + + if (chan == 14) + ant |= BB_ANTATTEN_CHAN14; + + rtl8180_write_phy(dev, 0x10, ant); + +} + +static u8 sa2400_rf_rssi_map[] = { + 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, + 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, + 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, + 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, + 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, + 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, + 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, + 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, + 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, + 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, +}; + +static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) +{ + if (sq == 0x80) + return 1; + + if (sq > 78) + return 32; + + /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ + return 65 * sa2400_rf_rssi_map[sq] / 100; +} + +static void sa2400_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8180_priv *priv = dev->priv; + int channel = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); + u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; + u32 chan = sa2400_chan[channel - 1]; + + write_sa2400(dev, 7, txpw); + + sa2400_write_phy_antenna(dev, channel); + + write_sa2400(dev, 0, chan); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); +} + +static void sa2400_rf_stop(struct ieee80211_hw *dev) +{ + write_sa2400(dev, 4, 0); +} + +static void sa2400_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + u32 anaparam, txconf; + u8 firdac; + int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY; + + anaparam = priv->anaparam; + anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT); + anaparam &= ~ANAPARAM_PWR1_MASK; + anaparam &= ~ANAPARAM_PWR0_MASK; + + if (analogphy) { + anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT; + firdac = 0; + } else { + anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT); + anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT); + firdac = 1 << SA2400_REG4_FIRDAC_SHIFT; + } + + rtl8180_set_anaparam(priv, anaparam); + + write_sa2400(dev, 0, sa2400_chan[0]); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); + write_sa2400(dev, 4, 0x19340 | firdac); + write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15); + write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */ + + if (!analogphy) + write_sa2400(dev, 4, 0x1938c); /*???*/ + + write_sa2400(dev, 4, 0x19340 | firdac); + + write_sa2400(dev, 0, sa2400_chan[0]); + write_sa2400(dev, 1, 0xbb50); + write_sa2400(dev, 2, 0x80); + write_sa2400(dev, 3, 0); + write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */ + + /* new from rtl8180 embedded driver (rtl8181 project) */ + write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */ + write_sa2400(dev, 8, 0); /* VCO */ + + if (analogphy) { + rtl8180_set_anaparam(priv, anaparam | + (1 << ANAPARAM_TXDACOFF_SHIFT)); + + txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + txconf | RTL818X_TX_CONF_LOOPBACK_CONT); + + write_sa2400(dev, 4, 0x19341); /* calibrates DC */ + + /* a 5us sleep is required here, + * we rely on the 3ms delay introduced in write_sa2400 */ + write_sa2400(dev, 4, 0x19345); + + /* a 20us sleep is required here, + * we rely on the 3ms delay introduced in write_sa2400 */ + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf); + + rtl8180_set_anaparam(priv, anaparam); + } + /* end new code */ + + write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */ + + /* baseband configuration */ + rtl8180_write_phy(dev, 0, 0x98); + rtl8180_write_phy(dev, 3, 0x38); + rtl8180_write_phy(dev, 4, 0xe0); + rtl8180_write_phy(dev, 5, 0x90); + rtl8180_write_phy(dev, 6, 0x1a); + rtl8180_write_phy(dev, 7, 0x64); + + sa2400_write_phy_antenna(dev, 1); + + rtl8180_write_phy(dev, 0x11, 0x80); + + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & + RTL818X_CONFIG2_ANTENNA_DIV) + rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */ + else + rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */ + + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); + + rtl8180_write_phy(dev, 0x19, 0x0); + rtl8180_write_phy(dev, 0x1a, 0xa0); +} + +const struct rtl818x_rf_ops sa2400_rf_ops = { + .name = "Philips", + .init = sa2400_rf_init, + .stop = sa2400_rf_stop, + .set_chan = sa2400_rf_set_channel, + .calc_rssi = sa2400_rf_calc_rssi, +}; diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h new file mode 100644 index 000000000..ef6565b20 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef RTL8180_SA2400_H +#define RTL8180_SA2400_H + +/* + * Radio tuning for Philips SA2400 on RTL8180 + * + * Copyright 2007 Andrea Merello + * + * Code from the BSD driver and the rtl8181 project have been + * very useful to understand certain things + * + * I want to thanks the Authors of such projects and the Ndiswrapper + * project Authors. + * + * A special Big Thanks also is for all people who donated me cards, + * making possible the creation of the original rtl8180 driver + * from which this code is derived! + */ + +#define SA2400_ANTENNA 0x91 +#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8 +#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28 +#define SA2400_ANAPARAM_PWR0_ON 0x3 + +/* RX sensitivity in dbm */ +#define SA2400_MAX_SENS 85 + +#define SA2400_REG4_FIRDAC_SHIFT 7 + +extern const struct rtl818x_rf_ops sa2400_rf_ops; + +#endif /* RTL8180_SA2400_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile b/drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile new file mode 100644 index 000000000..3deded2c0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o + +obj-$(CONFIG_RTL8187) += rtl8187.o + +ccflags-y += -I $(src)/.. diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c new file mode 100644 index 000000000..a76671218 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -0,0 +1,1697 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Linux device driver for RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * The driver was extended to the RTL8187B in 2008 by: + * Herton Ronaldo Krzesinski + * Hin-Tak Leung + * Larry Finger + * + * Magic delays and register offsets below are taken from the original + * r8187 driver sources. Thanks to Realtek for their support! + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8225.h" +#ifdef CONFIG_RTL8187_LEDS +#include "leds.h" +#endif +#include "rfkill.h" + +MODULE_AUTHOR("Michael Wu "); +MODULE_AUTHOR("Andrea Merello "); +MODULE_AUTHOR("Herton Ronaldo Krzesinski "); +MODULE_AUTHOR("Hin-Tak Leung "); +MODULE_AUTHOR("Larry Finger "); +MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); +MODULE_LICENSE("GPL"); + +static const struct usb_device_id rtl8187_table[] = { + /* Asus */ + {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, + /* Belkin */ + {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B}, + /* Realtek */ + {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, + /* Surecom */ + {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, + /* Logitech */ + {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, + /* Netgear */ + {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B}, + /* HP */ + {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B}, + /* Sphairon Access Systems GmbH */ + {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, + /* Dick Smith Electronics */ + {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, + /* Abocom */ + {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, + /* Qcom */ + {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, + /* AirLive */ + {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, + /* Linksys */ + {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8187_table); + +static const struct ieee80211_rate rtl818x_rates[] = { + { .bitrate = 10, .hw_value = 0, }, + { .bitrate = 20, .hw_value = 1, }, + { .bitrate = 55, .hw_value = 2, }, + { .bitrate = 110, .hw_value = 3, }, + { .bitrate = 60, .hw_value = 4, }, + { .bitrate = 90, .hw_value = 5, }, + { .bitrate = 120, .hw_value = 6, }, + { .bitrate = 180, .hw_value = 7, }, + { .bitrate = 240, .hw_value = 8, }, + { .bitrate = 360, .hw_value = 9, }, + { .bitrate = 480, .hw_value = 10, }, + { .bitrate = 540, .hw_value = 11, }, +}; + +static const struct ieee80211_channel rtl818x_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + +static void rtl8187_iowrite_async_cb(struct urb *urb) +{ + kfree(urb->context); +} + +static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, + void *data, u16 len) +{ + struct usb_ctrlrequest *dr; + struct urb *urb; + struct rtl8187_async_write_data { + u8 data[4]; + struct usb_ctrlrequest dr; + } *buf; + int rc; + + buf = kmalloc_obj(*buf, GFP_ATOMIC); + if (!buf) + return; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree(buf); + return; + } + + dr = &buf->dr; + + dr->bRequestType = RTL8187_REQT_WRITE; + dr->bRequest = RTL8187_REQ_SET_REG; + dr->wValue = addr; + dr->wIndex = 0; + dr->wLength = cpu_to_le16(len); + + memcpy(buf, data, len); + + usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), + (unsigned char *)dr, buf, len, + rtl8187_iowrite_async_cb, buf); + usb_anchor_urb(urb, &priv->anchored); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + kfree(buf); + usb_unanchor_urb(urb); + } + usb_free_urb(urb); +} + +static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, + __le32 *addr, u32 val) +{ + __le32 buf = cpu_to_le32(val); + + rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr), + &buf, sizeof(buf)); +} + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8187_priv *priv = dev->priv; + + data <<= 8; + data |= addr | 0x80; + + rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF); +} + +static void rtl8187_tx_cb(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = info->rate_driver_data[0]; + struct rtl8187_priv *priv = hw->priv; + + skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : + sizeof(struct rtl8187_tx_hdr)); + ieee80211_tx_info_clear_status(info); + + if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + if (priv->is_rtl8187b) { + skb_queue_tail(&priv->b_tx_status.queue, skb); + + /* queue is "full", discard last items */ + while (skb_queue_len(&priv->b_tx_status.queue) > 5) { + struct sk_buff *old_skb; + + dev_dbg(&priv->udev->dev, + "transmit status queue full\n"); + + old_skb = skb_dequeue(&priv->b_tx_status.queue); + ieee80211_tx_status_irqsafe(hw, old_skb); + } + return; + } else { + info->flags |= IEEE80211_TX_STAT_ACK; + } + } + if (priv->is_rtl8187b) + ieee80211_tx_status_irqsafe(hw, skb); + else { + /* Retry information for the RTI8187 is only available by + * reading a register in the device. We are in interrupt mode + * here, thus queue the skb and finish on a work queue. */ + skb_queue_tail(&priv->b_tx_status.queue, skb); + ieee80211_queue_delayed_work(hw, &priv->work, 0); + } +} + +static void rtl8187_tx(struct ieee80211_hw *dev, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *tx_hdr = (struct ieee80211_hdr *)(skb->data); + unsigned int ep; + void *buf; + struct urb *urb; + __le16 rts_dur = 0; + u32 flags; + int rc; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree_skb(skb); + return; + } + + flags = skb->len; + flags |= RTL818X_TX_DESC_FLAG_NO_ENC; + + flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; + if (ieee80211_has_morefrags(tx_hdr->frame_control)) + flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; + + /* HW will perform RTS-CTS when only RTS flags is set. + * HW will perform CTS-to-self when both RTS and CTS flags are set. + * RTS rate and RTS duration will be used also for CTS-to-self. + */ + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + flags |= RTL818X_TX_DESC_FLAG_RTS; + flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + rts_dur = ieee80211_rts_duration(dev, priv->vif, + skb->len, info); + } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + flags |= RTL818X_TX_DESC_FLAG_RTS | RTL818X_TX_DESC_FLAG_CTS; + flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; + rts_dur = ieee80211_ctstoself_duration(dev, priv->vif, + skb->len, info); + } + + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) + priv->seqno += 0x10; + tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno); + } + + if (!priv->is_rtl8187b) { + struct rtl8187_tx_hdr *hdr = skb_push(skb, sizeof(*hdr)); + hdr->flags = cpu_to_le32(flags); + hdr->len = 0; + hdr->rts_duration = rts_dur; + hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); + buf = hdr; + + ep = 2; + } else { + /* fc needs to be calculated before skb_push() */ + unsigned int epmap[4] = { 6, 7, 5, 4 }; + u16 fc = le16_to_cpu(tx_hdr->frame_control); + + struct rtl8187b_tx_hdr *hdr = skb_push(skb, sizeof(*hdr)); + struct ieee80211_rate *txrate = + ieee80211_get_tx_rate(dev, info); + memset(hdr, 0, sizeof(*hdr)); + hdr->flags = cpu_to_le32(flags); + hdr->rts_duration = rts_dur; + hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); + hdr->tx_duration = + ieee80211_generic_frame_duration(dev, priv->vif, + info->band, + skb->len, txrate); + buf = hdr; + + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) + ep = 12; + else + ep = epmap[skb_get_queue_mapping(skb)]; + } + + info->rate_driver_data[0] = dev; + info->rate_driver_data[1] = urb; + + usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), + buf, skb->len, rtl8187_tx_cb, skb); + urb->transfer_flags |= URB_ZERO_PACKET; + usb_anchor_urb(urb, &priv->anchored); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + usb_unanchor_urb(urb); + kfree_skb(skb); + } + usb_free_urb(urb); +} + +static void rtl8187_rx_cb(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; + struct ieee80211_hw *dev = info->dev; + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_rx_status rx_status = { 0 }; + int rate, signal; + u32 flags; + unsigned long f; + + spin_lock_irqsave(&priv->rx_queue.lock, f); + __skb_unlink(skb, &priv->rx_queue); + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + + if (unlikely(urb->status)) + goto free_skb; + + if (!priv->is_rtl8187b) { + struct rtl8187_rx_hdr *hdr; + + if (skb->len < sizeof(struct rtl8187_rx_hdr)) + goto free_skb; + + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling + * constants are derived from the output of p54usb. + */ + signal = -4 - ((27 * hdr->agc) >> 6); + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { + struct rtl8187b_rx_hdr *hdr; + + if (skb->len < sizeof(struct rtl8187b_rx_hdr)) + goto free_skb; + + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. + * In testing, none of these quantities show qualitative + * agreement with AP signal strength, except for the AGC, + * which is inversely proportional to the strength of the + * signal. In the following, the signal strength + * is derived from the AGC. The arbitrary scaling constants + * are chosen to make the results close to the values obtained + * for a BCM4312 using b43 as the driver. The noise is ignored + * for now. + */ + flags = le32_to_cpu(hdr->flags); + signal = 14 - hdr->agc / 2; + rx_status.antenna = (hdr->rssi >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } + + rx_status.signal = signal; + priv->signal = signal; + rate = (flags >> 20) & 0xF; + skb_trim(skb, flags & 0x0FFF); + rx_status.rate_idx = rate; + rx_status.freq = dev->conf.chandef.chan->center_freq; + rx_status.band = dev->conf.chandef.chan->band; + rx_status.flag |= RX_FLAG_MACTIME_START; + if (flags & RTL818X_RX_DESC_FLAG_SPLCP) + rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE; + if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(dev, skb); + + skb = dev_alloc_skb(RTL8187_MAX_RX); + if (unlikely(!skb)) { + /* TODO check rx queue length and refill *somewhere* */ + return; + } + + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = urb; + info->dev = dev; + urb->transfer_buffer = skb_tail_pointer(skb); + urb->context = skb; + skb_queue_tail(&priv->rx_queue, skb); + + usb_anchor_urb(urb, &priv->anchored); + if (usb_submit_urb(urb, GFP_ATOMIC)) { + usb_unanchor_urb(urb); + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } + return; + +free_skb: + dev_kfree_skb_irq(skb); + return; +} + +static int rtl8187_init_urbs(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct urb *entry = NULL; + struct sk_buff *skb; + struct rtl8187_rx_info *info; + int ret = 0; + + while (skb_queue_len(&priv->rx_queue) < 32) { + skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err; + } + entry = usb_alloc_urb(0, GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto err; + } + usb_fill_bulk_urb(entry, priv->udev, + usb_rcvbulkpipe(priv->udev, + priv->is_rtl8187b ? 3 : 1), + skb_tail_pointer(skb), + RTL8187_MAX_RX, rtl8187_rx_cb, skb); + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = entry; + info->dev = dev; + skb_queue_tail(&priv->rx_queue, skb); + usb_anchor_urb(entry, &priv->anchored); + ret = usb_submit_urb(entry, GFP_KERNEL); + if (ret) { + skb_unlink(skb, &priv->rx_queue); + usb_unanchor_urb(entry); + usb_put_urb(entry); + goto err; + } + usb_put_urb(entry); + } + return ret; + +err: + kfree_skb(skb); + usb_kill_anchored_urbs(&priv->anchored); + return ret; +} + +static void rtl8187b_status_cb(struct urb *urb) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)urb->context; + struct rtl8187_priv *priv = hw->priv; + u64 val; + unsigned int cmd_type; + + if (unlikely(urb->status)) + return; + + /* + * Read from status buffer: + * + * bits [30:31] = cmd type: + * - 0 indicates tx beacon interrupt + * - 1 indicates tx close descriptor + * + * In the case of tx beacon interrupt: + * [0:9] = Last Beacon CW + * [10:29] = reserved + * [30:31] = 00b + * [32:63] = Last Beacon TSF + * + * If it's tx close descriptor: + * [0:7] = Packet Retry Count + * [8:14] = RTS Retry Count + * [15] = TOK + * [16:27] = Sequence No + * [28] = LS + * [29] = FS + * [30:31] = 01b + * [32:47] = unused (reserved?) + * [48:63] = MAC Used Time + */ + val = le64_to_cpu(priv->b_tx_status.buf); + + cmd_type = (val >> 30) & 0x3; + if (cmd_type == 1) { + unsigned int pkt_rc, seq_no; + bool tok; + struct sk_buff *skb, *iter; + struct ieee80211_hdr *ieee80211hdr; + unsigned long flags; + + pkt_rc = val & 0xFF; + tok = val & (1 << 15); + seq_no = (val >> 16) & 0xFFF; + + spin_lock_irqsave(&priv->b_tx_status.queue.lock, flags); + skb = NULL; + skb_queue_reverse_walk(&priv->b_tx_status.queue, iter) { + ieee80211hdr = (struct ieee80211_hdr *)iter->data; + + /* + * While testing, it was discovered that the seq_no + * doesn't actually contains the sequence number. + * Instead of returning just the 12 bits of sequence + * number, hardware is returning entire sequence control + * (fragment number plus sequence number) in a 12 bit + * only field overflowing after some time. As a + * workaround, just consider the lower bits, and expect + * it's unlikely we wrongly ack some sent data + */ + if ((le16_to_cpu(ieee80211hdr->seq_ctrl) + & 0xFFF) == seq_no) { + skb = iter; + break; + } + } + if (skb) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + __skb_unlink(skb, &priv->b_tx_status.queue); + if (tok) + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.rates[0].count = pkt_rc + 1; + + ieee80211_tx_status_irqsafe(hw, skb); + } + spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags); + } + + usb_anchor_urb(urb, &priv->anchored); + if (usb_submit_urb(urb, GFP_ATOMIC)) + usb_unanchor_urb(urb); +} + +static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct urb *entry; + int ret = 0; + + entry = usb_alloc_urb(0, GFP_KERNEL); + if (!entry) + return -ENOMEM; + + usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9), + &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf), + rtl8187b_status_cb, dev); + + usb_anchor_urb(entry, &priv->anchored); + ret = usb_submit_urb(entry, GFP_KERNEL); + if (ret) + usb_unanchor_urb(entry); + usb_free_urb(entry); + + return ret; +} + +static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon) +{ + u32 anaparam, anaparam2; + u8 anaparam3, reg; + + if (!priv->is_rtl8187b) { + if (rfon) { + anaparam = RTL8187_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON; + } else { + anaparam = RTL8187_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF; + } + } else { + if (rfon) { + anaparam = RTL8187B_RTL8225_ANAPARAM_ON; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON; + } else { + anaparam = RTL8187B_RTL8225_ANAPARAM_OFF; + anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF; + anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF; + } + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + reg |= RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); + if (priv->is_rtl8187b) + rtl818x_iowrite8(priv, &priv->map->ANAPARAM3A, anaparam3); + reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); +} + +static int rtl8187_cmd_reset(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u8 reg; + int i; + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= (1 << 1); + reg |= RTL818X_CMD_RESET; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + i = 10; + do { + msleep(2); + if (!(rtl818x_ioread8(priv, &priv->map->CMD) & + RTL818X_CMD_RESET)) + break; + } while (--i); + + if (!i) { + wiphy_err(dev->wiphy, "Reset timeout!\n"); + return -ETIMEDOUT; + } + + /* reload registers from eeprom */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); + + i = 10; + do { + msleep(4); + if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) & + RTL818X_EEPROM_CMD_CONFIG)) + break; + } while (--i); + + if (!i) { + wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int rtl8187_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u8 reg; + int res; + + /* reset */ + rtl8187_set_anaparam(priv, true); + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + msleep(200); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00); + msleep(200); + + res = rtl8187_cmd_reset(dev); + if (res) + return res; + + rtl8187_set_anaparam(priv, true); + + /* setup card */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); + + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 1); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + + rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); + reg &= 0x3F; + reg |= 0x80; + rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0); + + // TODO: set RESP_RATE and BRSR properly + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + + /* host_usb_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); + reg = rtl818x_ioread8(priv, (u8 *)0xFE53); + rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80); + msleep(100); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); + msleep(100); + + priv->rf->init(dev); + + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); + rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); + rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); + rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + + return 0; +} + +static const u8 rtl8187b_reg_table[][3] = { + {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0}, + {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0}, + {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0}, + {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0}, + + {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1}, + {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1}, + {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, + {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, + {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1}, + + {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2}, + {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2}, + {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2}, + {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2}, + {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2}, + {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2}, + {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, + + {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0}, + {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, + {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, + {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, + {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, + + {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, + {0x8F, 0x00, 0} +}; + +static int rtl8187b_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int res, i; + u8 reg; + + rtl8187_set_anaparam(priv, true); + + /* Reset PLL sequence on 8187B. Realtek note: reduces power + * consumption about 30 mA */ + rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); + reg = rtl818x_ioread8(priv, (u8 *)0xFF62); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); + rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); + + res = rtl8187_cmd_reset(dev); + if (res) + return res; + + rtl8187_set_anaparam(priv, true); + + /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as + * RESP_RATE on 8187L in Realtek sources: each bit should be each + * one of the 12 rates, all are enabled */ + rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF); + + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg |= RTL818X_CW_CONF_PERPACKET_RETRY; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + /* Auto Rate Fallback Register (ARFR): 1M-54M setting */ + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1); + + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); + rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, + RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) { + rtl818x_iowrite8_idx(priv, + (u8 *)(uintptr_t) + (rtl8187b_reg_table[i][0] | 0xFF00), + rtl8187b_reg_table[i][1], + rtl8187b_reg_table[i][2]); + } + + rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50); + rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0); + + rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1); + rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001); + + /* RFSW_CTRL register */ + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); + msleep(100); + + priv->rf->init(dev); + + reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4); + rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); + rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00); + rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01); + + reg = rtl818x_ioread8(priv, (u8 *)0xFFDB); + rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2)); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3); + rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3); + rtl818x_iowrite8(priv, (u8 *)0xFF61, 0); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1); + rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10); + rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2); + + rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B); + + rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1); + + priv->slot_time = 0x9; + priv->aifsn[0] = 2; /* AIFSN[AC_VO] */ + priv->aifsn[1] = 2; /* AIFSN[AC_VI] */ + priv->aifsn[2] = 7; /* AIFSN[AC_BK] */ + priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ + rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); + + /* ENEDCA flag must always be set, transmit issues? */ + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); + + return 0; +} + +static void rtl8187_work(struct work_struct *work) +{ + /* The RTL8187 returns the retry count through register 0xFFFA. In + * addition, it appears to be a cumulative retry count, not the + * value for the current TX packet. When multiple TX entries are + * waiting in the queue, the retry count will be the total for all. + * The "error" may matter for purposes of rate setting, but there is + * no other choice with this hardware. + */ + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + work.work); + struct ieee80211_tx_info *info; + struct ieee80211_hw *dev = priv->dev; + static u16 retry; + u16 tmp; + u16 avg_retry; + int length; + + mutex_lock(&priv->conf_mutex); + tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); + length = skb_queue_len(&priv->b_tx_status.queue); + if (unlikely(!length)) + length = 1; + if (unlikely(tmp < retry)) + tmp = retry; + avg_retry = (tmp - retry) / length; + while (skb_queue_len(&priv->b_tx_status.queue) > 0) { + struct sk_buff *old_skb; + + old_skb = skb_dequeue(&priv->b_tx_status.queue); + info = IEEE80211_SKB_CB(old_skb); + info->status.rates[0].count = avg_retry + 1; + if (info->status.rates[0].count > RETRY_COUNT) + info->flags &= ~IEEE80211_TX_STAT_ACK; + ieee80211_tx_status_irqsafe(dev, old_skb); + } + retry = tmp; + mutex_unlock(&priv->conf_mutex); +} + +static int rtl8187_start(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u32 reg; + int ret; + + mutex_lock(&priv->conf_mutex); + + ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : + rtl8187b_init_hw(dev); + if (ret) + goto rtl8187_start_exit; + + init_usb_anchor(&priv->anchored); + priv->dev = dev; + + if (priv->is_rtl8187b) { + reg = RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC | + RTL818X_RX_CONF_BSSID | + (7 << 13 /* RX FIFO threshold NONE */) | + (7 << 10 /* MAX RX DMA */) | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_ONLYERLPKT; + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + RTL818X_TX_CONF_HW_SEQNUM | + RTL818X_TX_CONF_DISREQQSIZE | + (RETRY_COUNT << 8 /* short retry limit */) | + (RETRY_COUNT << 0 /* long retry limit */) | + (7 << 21 /* MAX TX DMA */)); + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; + ret = rtl8187b_init_status_urb(dev); + if (ret) + usb_kill_anchored_urbs(&priv->anchored); + goto rtl8187_start_exit; + } + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); + + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; + + reg = RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_BSSID | + RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_DATA | + (7 << 13 /* RX FIFO threshold NONE */) | + (7 << 10 /* MAX RX DMA */) | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_NICMAC; + + priv->rx_conf = reg; + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg &= ~RTL818X_CW_CONF_PERPACKET_CW; + reg |= RTL818X_CW_CONF_PERPACKET_RETRY; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + reg = RTL818X_TX_CONF_CW_MIN | + (7 << 21 /* MAX TX DMA */) | + RTL818X_TX_CONF_NO_ICV; + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg |= RTL818X_CMD_TX_ENABLE; + reg |= RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + INIT_DELAYED_WORK(&priv->work, rtl8187_work); + +rtl8187_start_exit: + mutex_unlock(&priv->conf_mutex); + return ret; +} + +static void rtl8187_stop(struct ieee80211_hw *dev, bool suspend) +{ + struct rtl8187_priv *priv = dev->priv; + struct sk_buff *skb; + u32 reg; + + mutex_lock(&priv->conf_mutex); + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= ~RTL818X_CMD_TX_ENABLE; + reg &= ~RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + priv->rf->stop(dev); + rtl8187_set_anaparam(priv, false); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + usb_kill_anchored_urbs(&priv->anchored); + + while ((skb = skb_dequeue(&priv->b_tx_status.queue))) + dev_kfree_skb_any(skb); + + mutex_unlock(&priv->conf_mutex); + + if (!priv->is_rtl8187b) + cancel_delayed_work_sync(&priv->work); +} + +static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + + +static void rtl8187_beacon_work(struct work_struct *work) +{ + struct rtl8187_vif *vif_priv = + container_of(work, struct rtl8187_vif, beacon_work.work); + struct ieee80211_vif *vif = + container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); + struct ieee80211_hw *dev = vif_priv->dev; + struct ieee80211_mgmt *mgmt; + struct sk_buff *skb; + + /* don't overflow the tx ring */ + if (ieee80211_queue_stopped(dev, 0)) + goto resched; + + /* grab a fresh beacon */ + skb = ieee80211_beacon_get(dev, vif, 0); + if (!skb) + goto resched; + + /* + * update beacon timestamp w/ TSF value + * TODO: make hardware update beacon timestamp + */ + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif)); + + /* TODO: use actual beacon queue */ + skb_set_queue_mapping(skb, 0); + + rtl8187_tx(dev, NULL, skb); + +resched: + /* + * schedule next beacon + * TODO: use hardware support for beacon timing + */ + schedule_delayed_work(&vif_priv->beacon_work, + usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); +} + + +static int rtl8187_add_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; + int i; + int ret = -EOPNOTSUPP; + + mutex_lock(&priv->conf_mutex); + if (priv->vif) + goto exit; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + break; + default: + goto exit; + } + + ret = 0; + priv->vif = vif; + + /* Initialize driver private area */ + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + vif_priv->dev = dev; + INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work); + vif_priv->enable_beacon = false; + + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->MAC[i], + ((u8 *)vif->addr)[i]); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + +exit: + mutex_unlock(&priv->conf_mutex); + return ret; +} + +static void rtl8187_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + mutex_lock(&priv->conf_mutex); + priv->vif = NULL; + mutex_unlock(&priv->conf_mutex); +} + +static int rtl8187_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) +{ + struct rtl8187_priv *priv = dev->priv; + struct ieee80211_conf *conf = &dev->conf; + u32 reg; + + mutex_lock(&priv->conf_mutex); + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + /* Enable TX loopback on MAC level to avoid TX during channel + * changes, as this has be seen to causes problems and the + * card will stop work until next reset + */ + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + reg | RTL818X_TX_CONF_LOOPBACK_MAC); + priv->rf->set_chan(dev, conf); + msleep(10); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); + rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); + mutex_unlock(&priv->conf_mutex); + return 0; +} + +/* + * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for + * example. Thus we have to use raw values for AC_*_PARAM register addresses. + */ +static __le32 *rtl8187b_ac_addr[4] = { + (__le32 *) 0xFFF0, /* AC_VO */ + (__le32 *) 0xFFF4, /* AC_VI */ + (__le32 *) 0xFFFC, /* AC_BK */ + (__le32 *) 0xFFF8, /* AC_BE */ +}; + +#define SIFS_TIME 0xa + +static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, + bool use_short_preamble) +{ + if (priv->is_rtl8187b) { + u8 difs, eifs; + u16 ack_timeout; + int queue; + + if (use_short_slot) { + priv->slot_time = 0x9; + difs = 0x1c; + eifs = 0x53; + } else { + priv->slot_time = 0x14; + difs = 0x32; + eifs = 0x5b; + } + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); + rtl818x_iowrite8(priv, &priv->map->DIFS, difs); + + /* + * BRSR+1 on 8187B is in fact EIFS register + * Value in units of 4 us + */ + rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs); + + /* + * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout + * register. In units of 4 us like eifs register + * ack_timeout = ack duration + plcp + difs + preamble + */ + ack_timeout = 112 + 48 + difs; + if (use_short_preamble) + ack_timeout += 72; + else + ack_timeout += 144; + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, + DIV_ROUND_UP(ack_timeout, 4)); + + for (queue = 0; queue < 4; queue++) + rtl818x_iowrite8(priv, (u8 *) rtl8187b_ac_addr[queue], + priv->aifsn[queue] * priv->slot_time + + SIFS_TIME); + } else { + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + if (use_short_slot) { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); + } else { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); + } + } +} + +static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed) +{ + struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; + int i; + u8 reg; + + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + + if (changed & BSS_CHANGED_BSSID) { + mutex_lock(&priv->conf_mutex); + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->BSSID[i], + info->bssid[i]); + + if (priv->is_rtl8187b) + reg = RTL818X_MSR_ENEDCA; + else + reg = 0; + + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg |= RTL818X_MSR_ADHOC; + else + reg |= RTL818X_MSR_INFRA; + } + else + reg |= RTL818X_MSR_NO_LINK; + + rtl818x_iowrite8(priv, &priv->map->MSR, reg); + + mutex_unlock(&priv->conf_mutex); + } + + if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) + rtl8187_conf_erp(priv, info->use_short_slot, + info->use_short_preamble); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + vif_priv->enable_beacon = info->enable_beacon; + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { + cancel_delayed_work_sync(&vif_priv->beacon_work); + if (vif_priv->enable_beacon) + schedule_work(&vif_priv->beacon_work.work); + } + +} + +static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, + struct netdev_hw_addr_list *mc_list) +{ + return netdev_hw_addr_list_count(mc_list); +} + +static void rtl8187_configure_filter(struct ieee80211_hw *dev, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct rtl8187_priv *priv = dev->priv; + + if (changed_flags & FIF_FCSFAIL) + priv->rx_conf ^= RTL818X_RX_CONF_FCS; + if (changed_flags & FIF_CONTROL) + priv->rx_conf ^= RTL818X_RX_CONF_CTRL; + if (*total_flags & FIF_OTHER_BSS || + *total_flags & FIF_ALLMULTI || multicast > 0) + priv->rx_conf |= RTL818X_RX_CONF_MONITOR; + else + priv->rx_conf &= ~RTL818X_RX_CONF_MONITOR; + + *total_flags = 0; + + if (priv->rx_conf & RTL818X_RX_CONF_FCS) + *total_flags |= FIF_FCSFAIL; + if (priv->rx_conf & RTL818X_RX_CONF_CTRL) + *total_flags |= FIF_CONTROL; + if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) { + *total_flags |= FIF_OTHER_BSS; + *total_flags |= FIF_ALLMULTI; + } + + rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); +} + +static int rtl8187_conf_tx(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cw_min, cw_max; + + if (queue > 3) + return -EINVAL; + + cw_min = fls(params->cw_min); + cw_max = fls(params->cw_max); + + if (priv->is_rtl8187b) { + priv->aifsn[queue] = params->aifs; + + /* + * This is the structure of AC_*_PARAM registers in 8187B: + * - TXOP limit field, bit offset = 16 + * - ECWmax, bit offset = 12 + * - ECWmin, bit offset = 8 + * - AIFS, bit offset = 0 + */ + rtl818x_iowrite32(priv, rtl8187b_ac_addr[queue], + (params->txop << 16) | (cw_max << 12) | + (cw_min << 8) | (params->aifs * + priv->slot_time + SIFS_TIME)); + } else { + if (queue != 0) + return -EINVAL; + + rtl818x_iowrite8(priv, &priv->map->CW_VAL, + cw_min | (cw_max << 4)); + } + return 0; +} + + +static const struct ieee80211_ops rtl8187_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .tx = rtl8187_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .start = rtl8187_start, + .stop = rtl8187_stop, + .add_interface = rtl8187_add_interface, + .remove_interface = rtl8187_remove_interface, + .config = rtl8187_config, + .bss_info_changed = rtl8187_bss_info_changed, + .prepare_multicast = rtl8187_prepare_multicast, + .configure_filter = rtl8187_configure_filter, + .conf_tx = rtl8187_conf_tx, + .rfkill_poll = rtl8187_rfkill_poll, + .get_tsf = rtl8187_get_tsf, +}; + +static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = RTL818X_EEPROM_CMD_PROGRAM; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); + udelay(10); +} + +static int rtl8187_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct ieee80211_hw *dev; + struct rtl8187_priv *priv; + struct eeprom_93cx6 eeprom = {}; + struct ieee80211_channel *channel; + const char *chip_name; + u16 txpwr, reg; + u16 product_id = le16_to_cpu(udev->descriptor.idProduct); + int err, i; + u8 mac_addr[ETH_ALEN]; + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); + if (!dev) { + printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n"); + return -ENOMEM; + } + + priv = dev->priv; + priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); + + /* allocate "DMA aware" buffer for register accesses */ + priv->io_dmabuf = kmalloc_obj(*priv->io_dmabuf); + if (!priv->io_dmabuf) { + err = -ENOMEM; + goto err_free_dev; + } + mutex_init(&priv->io_mutex); + mutex_init(&priv->conf_mutex); + + SET_IEEE80211_DEV(dev, &intf->dev); + usb_set_intfdata(intf, dev); + priv->udev = udev; + + skb_queue_head_init(&priv->rx_queue); + + BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); + BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); + + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); + priv->map = (struct rtl818x_csr *)0xFF00; + + priv->band.band = NL80211_BAND_2GHZ; + priv->band.channels = priv->channels; + priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); + priv->band.bitrates = priv->rates; + priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); + dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band; + + + ieee80211_hw_set(dev, RX_INCLUDES_FCS); + ieee80211_hw_set(dev, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(dev, SIGNAL_DBM); + /* Initialize rate-control variables */ + dev->max_rates = 1; + dev->max_rate_tries = RETRY_COUNT; + + eeprom.data = dev; + eeprom.register_read = rtl8187_eeprom_register_read; + eeprom.register_write = rtl8187_eeprom_register_write; + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) + eeprom.width = PCI_EEPROM_WIDTH_93C66; + else + eeprom.width = PCI_EEPROM_WIDTH_93C46; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + udelay(10); + + eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, + (__le16 __force *)mac_addr, 3); + if (!is_valid_ether_addr(mac_addr)) { + printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " + "generated MAC address\n"); + eth_random_addr(mac_addr); + } + SET_IEEE80211_PERM_ADDR(dev, mac_addr); + + channel = priv->channels; + for (i = 0; i < 3; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, + &priv->txpwr_base); + + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); + /* 0 means asic B-cut, we should use SW 3 wire + * bit-by-bit banging for radio. 1 means we can use + * USB specific request to write radio registers */ + priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + if (!priv->is_rtl8187b) { + u32 reg32; + reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF); + reg32 &= RTL818X_TX_CONF_HWVER_MASK; + switch (reg32) { + case RTL818X_TX_CONF_R8187vD_B: + /* Some RTL8187B devices have a USB ID of 0x8187 + * detect them here */ + chip_name = "RTL8187BvB(early)"; + priv->is_rtl8187b = 1; + priv->hw_rev = RTL8187BvB; + break; + case RTL818X_TX_CONF_R8187vD: + chip_name = "RTL8187vD"; + break; + default: + chip_name = "RTL8187vB (default)"; + } + } else { + /* + * Force USB request to write radio registers for 8187B, Realtek + * only uses it in their sources + */ + /*if (priv->asic_rev == 0) { + printk(KERN_WARNING "rtl8187: Forcing use of USB " + "requests to write to radio registers\n"); + priv->asic_rev = 1; + }*/ + switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) { + case RTL818X_R8187B_B: + chip_name = "RTL8187BvB"; + priv->hw_rev = RTL8187BvB; + break; + case RTL818X_R8187B_D: + chip_name = "RTL8187BvD"; + priv->hw_rev = RTL8187BvD; + break; + case RTL818X_R8187B_E: + chip_name = "RTL8187BvE"; + priv->hw_rev = RTL8187BvE; + break; + default: + chip_name = "RTL8187BvB (default)"; + priv->hw_rev = RTL8187BvB; + } + } + + if (!priv->is_rtl8187b) { + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, + RTL8187_EEPROM_TXPWR_CHAN_6 + i, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + } else { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6, + &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + + eeprom_93cx6_read(&eeprom, 0x0A, &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + + eeprom_93cx6_read(&eeprom, 0x1C, &txpwr); + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } + /* Handle the differing rfkill GPIO bit in different models */ + priv->rfkill_mask = RFKILL_MASK_8187_89_97; + if (product_id == 0x8197 || product_id == 0x8198) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®); + if (reg & 0xFF00) + priv->rfkill_mask = RFKILL_MASK_8198; + } + dev->vif_data_size = sizeof(struct rtl8187_vif); + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) ; + + wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) + printk(KERN_INFO "rtl8187: inconsistency between id with OEM" + " info!\n"); + + priv->rf = rtl8187_detect_rf(dev); + dev->extra_tx_headroom = (!priv->is_rtl8187b) ? + sizeof(struct rtl8187_tx_hdr) : + sizeof(struct rtl8187b_tx_hdr); + if (!priv->is_rtl8187b) + dev->queues = 1; + else + dev->queues = 4; + + err = ieee80211_register_hw(dev); + if (err) { + printk(KERN_ERR "rtl8187: Cannot register device\n"); + goto err_free_dmabuf; + } + skb_queue_head_init(&priv->b_tx_status.queue); + + wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", + mac_addr, chip_name, priv->asic_rev, priv->rf->name, + priv->rfkill_mask); + +#ifdef CONFIG_RTL8187_LEDS + eeprom_93cx6_read(&eeprom, 0x3F, ®); + reg &= 0xFF; + rtl8187_leds_init(dev, reg); +#endif + rtl8187_rfkill_init(dev); + + return 0; + + err_free_dmabuf: + kfree(priv->io_dmabuf); + usb_set_intfdata(intf, NULL); + err_free_dev: + ieee80211_free_hw(dev); + return err; +} + +static void rtl8187_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *dev = usb_get_intfdata(intf); + struct rtl8187_priv *priv; + + if (!dev) + return; + +#ifdef CONFIG_RTL8187_LEDS + rtl8187_leds_exit(dev); +#endif + rtl8187_rfkill_exit(dev); + ieee80211_unregister_hw(dev); + + priv = dev->priv; + usb_reset_device(priv->udev); + kfree(priv->io_dmabuf); + ieee80211_free_hw(dev); +} + +static struct usb_driver rtl8187_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8187_table, + .probe = rtl8187_probe, + .disconnect = rtl8187_disconnect, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(rtl8187_driver); diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c new file mode 100644 index 000000000..f7d95c962 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Linux LED driver for RTL8187 + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Thanks to Realtek for their support! + */ + +#ifdef CONFIG_RTL8187_LEDS + +#include +#include +#include + +#include "rtl8187.h" +#include "leds.h" + +static void led_turn_on(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_on.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +static void led_turn_off(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_off.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +/* Callback from the LED subsystem. */ +static void rtl8187_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, + led_dev); + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv; + static bool radio_on; + + if (!hw) + return; + priv = hw->priv; + if (led->is_radio) { + if (brightness == LED_FULL) { + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + radio_on = true; + } else if (radio_on) { + radio_on = false; + cancel_delayed_work(&priv->led_on); + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + } + } else if (radio_on) { + if (brightness == LED_OFF) { + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + /* The LED is off for 1/20 sec - it just blinks. */ + ieee80211_queue_delayed_work(hw, &priv->led_on, + HZ / 20); + } else + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + } +} + +static int rtl8187_register_led(struct ieee80211_hw *dev, + struct rtl8187_led *led, const char *name, + const char *default_trigger, u8 ledpin, + bool is_radio) +{ + int err; + struct rtl8187_priv *priv = dev->priv; + + if (led->dev) + return -EEXIST; + if (!default_trigger) + return -EINVAL; + led->dev = dev; + led->ledpin = ledpin; + led->is_radio = is_radio; + strscpy(led->name, name, sizeof(led->name)); + + led->led_dev.name = led->name; + led->led_dev.default_trigger = default_trigger; + led->led_dev.brightness_set = rtl8187_led_brightness_set; + + err = led_classdev_register(&priv->udev->dev, &led->led_dev); + if (err) { + printk(KERN_INFO "LEDs: Failed to register %s\n", name); + led->dev = NULL; + return err; + } + return 0; +} + +static void rtl8187_unregister_led(struct rtl8187_led *led) +{ + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv = hw->priv; + + led_classdev_unregister(&led->led_dev); + flush_delayed_work(&priv->led_off); + led->dev = NULL; +} + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) +{ + struct rtl8187_priv *priv = dev->priv; + char name[RTL8187_LED_MAX_NAME_LEN + 1]; + u8 ledpin; + int err; + + /* According to the vendor driver, the LED operation depends on the + * customer ID encoded in the EEPROM + */ + printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid); + switch (custid) { + case EEPROM_CID_RSVD0: + case EEPROM_CID_RSVD1: + case EEPROM_CID_SERCOMM_PS: + case EEPROM_CID_QMI: + case EEPROM_CID_DELL: + case EEPROM_CID_TOSHIBA: + ledpin = LED_PIN_GPIO0; + break; + case EEPROM_CID_ALPHA0: + ledpin = LED_PIN_LED0; + break; + case EEPROM_CID_HW: + ledpin = LED_PIN_HW; + break; + default: + ledpin = LED_PIN_GPIO0; + } + + INIT_DELAYED_WORK(&priv->led_on, led_turn_on); + INIT_DELAYED_WORK(&priv->led_off, led_turn_off); + + snprintf(name, sizeof(name), + "rtl8187-%s::radio", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_radio, name, + ieee80211_get_radio_led_name(dev), ledpin, true); + if (err) + return; + + snprintf(name, sizeof(name), + "rtl8187-%s::tx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_tx, name, + ieee80211_get_tx_led_name(dev), ledpin, false); + if (err) + goto err_tx; + + snprintf(name, sizeof(name), + "rtl8187-%s::rx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_rx, name, + ieee80211_get_rx_led_name(dev), ledpin, false); + if (!err) + return; + + /* registration of RX LED failed - unregister */ + rtl8187_unregister_led(&priv->led_tx); +err_tx: + rtl8187_unregister_led(&priv->led_radio); +} + +void rtl8187_leds_exit(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + + rtl8187_unregister_led(&priv->led_radio); + rtl8187_unregister_led(&priv->led_rx); + rtl8187_unregister_led(&priv->led_tx); + cancel_delayed_work_sync(&priv->led_off); + cancel_delayed_work_sync(&priv->led_on); +} +#endif /* def CONFIG_RTL8187_LEDS */ + diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h new file mode 100644 index 000000000..5565cbf92 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Definitions for RTL8187 leds + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef RTL8187_LED_H +#define RTL8187_LED_H + +#ifdef CONFIG_RTL8187_LEDS + +#define RTL8187_LED_MAX_NAME_LEN 21 + +#include +#include + +enum { + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_GPIO0, + LED_PIN_HW +}; + +enum { + EEPROM_CID_RSVD0 = 0x00, + EEPROM_CID_RSVD1 = 0xFF, + EEPROM_CID_ALPHA0 = 0x01, + EEPROM_CID_SERCOMM_PS = 0x02, + EEPROM_CID_HW = 0x03, + EEPROM_CID_TOSHIBA = 0x04, + EEPROM_CID_QMI = 0x07, + EEPROM_CID_DELL = 0x08 +}; + +struct rtl8187_led { + struct ieee80211_hw *dev; + /* The LED class device */ + struct led_classdev led_dev; + /* The pin/method used to control the led */ + u8 ledpin; + /* The unique name string for this LED device. */ + char name[RTL8187_LED_MAX_NAME_LEN + 1]; + /* If the LED is radio or tx/rx */ + bool is_radio; +}; + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); +void rtl8187_leds_exit(struct ieee80211_hw *dev); + +#endif /* def CONFIG_RTL8187_LEDS */ + +#endif /* RTL8187_LED_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c new file mode 100644 index 000000000..c57a4742b --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Linux RFKILL support for RTL8187 + * + * Copyright (c) 2009 Herton Ronaldo Krzesinski + * + * Based on the RFKILL handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Thanks to Realtek for their support! + */ + +#include +#include +#include + +#include "rtl8187.h" +#include "rfkill.h" + +static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) +{ + u8 gpio; + + gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); + rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask); + gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); + + return gpio & priv->rfkill_mask; +} + +void rtl8187_rfkill_init(struct ieee80211_hw *hw) +{ + struct rtl8187_priv *priv = hw->priv; + + priv->rfkill_off = rtl8187_is_radio_enabled(priv); + printk(KERN_INFO "rtl8187: wireless switch is %s\n", + priv->rfkill_off ? "on" : "off"); + wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off); + wiphy_rfkill_start_polling(hw->wiphy); +} + +void rtl8187_rfkill_poll(struct ieee80211_hw *hw) +{ + bool enabled; + struct rtl8187_priv *priv = hw->priv; + + mutex_lock(&priv->conf_mutex); + enabled = rtl8187_is_radio_enabled(priv); + if (unlikely(enabled != priv->rfkill_off)) { + priv->rfkill_off = enabled; + printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n", + enabled ? "on" : "off"); + wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); + } + mutex_unlock(&priv->conf_mutex); +} + +void rtl8187_rfkill_exit(struct ieee80211_hw *hw) +{ + wiphy_rfkill_stop_polling(hw->wiphy); +} diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h new file mode 100644 index 000000000..c493e59ee --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RTL8187_RFKILL_H +#define RTL8187_RFKILL_H + +void rtl8187_rfkill_init(struct ieee80211_hw *hw); +void rtl8187_rfkill_poll(struct ieee80211_hw *hw); +void rtl8187_rfkill_exit(struct ieee80211_hw *hw); + +#endif /* RTL8187_RFKILL_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h new file mode 100644 index 000000000..36f3460cc --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Definitions for RTL8187 hardware + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + */ + +#ifndef RTL8187_H +#define RTL8187_H + +#include + +#include "rtl818x.h" +#include "leds.h" + +#define RTL8187_EEPROM_TXPWR_BASE 0x05 +#define RTL8187_EEPROM_MAC_ADDR 0x07 +#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ +#define RTL8187_EEPROM_SELECT_GPIO 0x3B + +#define RTL8187_REQT_READ 0xC0 +#define RTL8187_REQT_WRITE 0x40 +#define RTL8187_REQ_GET_REG 0x05 +#define RTL8187_REQ_SET_REG 0x05 + +#define RTL8187_MAX_RX 0x9C4 + +#define RFKILL_MASK_8187_89_97 0x2 +#define RFKILL_MASK_8198 0x4 + +#define RETRY_COUNT 7 + +struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +}; + +struct rtl8187_rx_hdr { + __le32 flags; + u8 noise; + u8 signal; + u8 agc; + u8 reserved; + __le64 mac_time; +} __packed; + +struct rtl8187b_rx_hdr { + __le32 flags; + __le64 mac_time; + u8 sq; + u8 rssi; + u8 agc; + u8 flags2; + __le16 snr_long2end; + s8 pwdb_g12; + u8 fot; +} __packed; + +/* {rtl8187,rtl8187b}_tx_info is in skb */ + +struct rtl8187_tx_hdr { + __le32 flags; + __le16 rts_duration; + __le16 len; + __le32 retry; +} __packed; + +struct rtl8187b_tx_hdr { + __le32 flags; + __le16 rts_duration; + __le16 len; + __le32 unused_1; + __le16 unused_2; + __le16 tx_duration; + __le32 unused_3; + __le32 retry; + __le32 unused_4[2]; +} __packed; + +enum { + DEVICE_RTL8187, + DEVICE_RTL8187B +}; + +struct rtl8187_vif { + struct ieee80211_hw *dev; + + /* beaconing */ + struct delayed_work beacon_work; + bool enable_beacon; +}; + +struct rtl8187_priv { + /* common between rtl818x drivers */ + struct rtl818x_csr *map; + const struct rtl818x_rf_ops *rf; + struct ieee80211_vif *vif; + + /* The mutex protects the TX loopback state. + * Any attempt to set channels concurrently locks the device. + */ + struct mutex conf_mutex; + + /* rtl8187 specific */ + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_supported_band band; + struct usb_device *udev; + u32 rx_conf; + struct usb_anchor anchored; + struct delayed_work work; + struct ieee80211_hw *dev; +#ifdef CONFIG_RTL8187_LEDS + struct rtl8187_led led_radio; + struct rtl8187_led led_tx; + struct rtl8187_led led_rx; + struct delayed_work led_on; + struct delayed_work led_off; +#endif + u16 txpwr_base; + u8 asic_rev; + u8 is_rtl8187b; + enum { + RTL8187BvB, + RTL8187BvD, + RTL8187BvE + } hw_rev; + struct sk_buff_head rx_queue; + u8 signal; + u8 noise; + u8 slot_time; + u8 aifsn[4]; + u8 rfkill_mask; + struct { + union { + __le64 buf; + u8 dummy1[L1_CACHE_BYTES]; + } ____cacheline_aligned; + struct sk_buff_head queue; + } b_tx_status; /* This queue is used by both -b and non-b devices */ + struct mutex io_mutex; + union { + u8 bits8; + __le16 bits16; + __le32 bits32; + u8 dummy2[L1_CACHE_BYTES]; + } *io_dmabuf ____cacheline_aligned; + bool rfkill_off; + u16 seqno; +}; + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); + +u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 idx); + +static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr) +{ + return rtl818x_ioread8_idx(priv, addr, 0); +} + +u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, + __le16 *addr, u8 idx); + +static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr) +{ + return rtl818x_ioread16_idx(priv, addr, 0); +} + +u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, + __le32 *addr, u8 idx); + +static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) +{ + return rtl818x_ioread32_idx(priv, addr, 0); +} + +void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 val, u8 idx); + +static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) +{ + rtl818x_iowrite8_idx(priv, addr, val, 0); +} + +void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, + __le16 *addr, u16 val, u8 idx); + +static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, + u16 val) +{ + rtl818x_iowrite16_idx(priv, addr, val, 0); +} + +void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, + __le32 *addr, u32 val, u8 idx); + +static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, + u32 val) +{ + rtl818x_iowrite32_idx(priv, addr, val, 0); +} + +#endif /* RTL8187_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c new file mode 100644 index 000000000..4efab907a --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c @@ -0,0 +1,1044 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Radio tuning for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Magic delays, register offsets, and phy value tables below are + * taken from the original r8187 driver sources. Thanks to Realtek + * for their support! + */ + +#include +#include + +#include "rtl8187.h" +#include "rtl8225.h" + +u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 idx) +{ + u8 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), 500); + + val = priv->io_dmabuf->bits8; + mutex_unlock(&priv->io_mutex); + + return val; +} + +u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, + __le16 *addr, u8 idx) +{ + __le16 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), 500); + + val = priv->io_dmabuf->bits16; + mutex_unlock(&priv->io_mutex); + + return le16_to_cpu(val); +} + +u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, + __le32 *addr, u8 idx) +{ + __le32 val; + + mutex_lock(&priv->io_mutex); + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), 500); + + val = priv->io_dmabuf->bits32; + mutex_unlock(&priv->io_mutex); + + return le32_to_cpu(val); +} + +void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, + u8 *addr, u8 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits8 = val; + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), 500); + + mutex_unlock(&priv->io_mutex); +} + +void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, + __le16 *addr, u16 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits16 = cpu_to_le16(val); + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), 500); + + mutex_unlock(&priv->io_mutex); +} + +void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, + __le32 *addr, u32 val, u8 idx) +{ + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits32 = cpu_to_le32(val); + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), 500); + + mutex_unlock(&priv->io_mutex); +} + +static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg84, reg82; + u32 bangdata; + int i; + + bangdata = (data << 4) | (addr & 0xf); + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); + + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + for (i = 15; i >= 0; i--) { + u16 reg = reg80 | (bangdata & (1 << i)) >> i; + + if (i & 1) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + + if (!(i & 1)) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); +} + +static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~(0x3 << 2); + reg84 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits16 = data; + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), + 500); + + mutex_unlock(&priv->io_mutex); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); +} + +static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + + if (priv->asic_rev) + rtl8225_write_8051(dev, addr, cpu_to_le16(data)); + else + rtl8225_write_bitbang(dev, addr, data); +} + +static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84, out; + int i; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(4); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(5); + + for (i = 4; i >= 0; i--) { + u16 reg = reg80 | ((addr >> i) & 1); + + if (!(i & 1)) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + + if (i & 1) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + + out = 0; + for (i = 11; i >= 0; i--) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(1); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) + out |= 1 << i; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); + + return out; +} + +static const u16 rtl8225bcd_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb +}; + +static const u8 rtl8225_agc[] = { + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const u8 rtl8225_gain[] = { + 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */ + 0x33, 0x80, 0x79, 0xc5, /* -78dBm */ + 0x43, 0x78, 0x76, 0xc5, /* -74dBm */ + 0x53, 0x60, 0x73, 0xc5, /* -70dBm */ + 0x63, 0x58, 0x70, 0xc5, /* -66dBm */ +}; + +static const u8 rtl8225_threshold[] = { + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd +}; + +static const u8 rtl8225_tx_gain_cck_ofdm[] = { + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e +}; + +static const u8 rtl8225_tx_power_cck[] = { + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 +}; + +static const u8 rtl8225_tx_power_cck_ch14[] = { + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225_tx_power_ofdm[] = { + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 +}; + +static const u32 rtl8225_chan[] = { + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 +}; + +static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power = min(cck_power, (u8)11); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); + + if (channel == 14) + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; + else + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + msleep(1); // FIXME: optional? + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, + RTL8187_RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 6, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x00); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1); + + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; + + rtl8225_write_phy_ofdm(dev, 5, *tmp); + rtl8225_write_phy_ofdm(dev, 7, *tmp); + + msleep(1); +} + +static void rtl8225_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x067); + rtl8225_write(dev, 0x1, 0xFE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x486); + rtl8225_write(dev, 0x5, 0xBC0); + rtl8225_write(dev, 0x6, 0xAE6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x01F); + rtl8225_write(dev, 0x9, 0x334); + rtl8225_write(dev, 0xA, 0xFD4); + rtl8225_write(dev, 0xB, 0x391); + rtl8225_write(dev, 0xC, 0x050); + rtl8225_write(dev, 0xD, 0x6DB); + rtl8225_write(dev, 0xE, 0x029); + rtl8225_write(dev, 0xF, 0x914); msleep(100); + + rtl8225_write(dev, 0x2, 0xC4D); msleep(200); + rtl8225_write(dev, 0x2, 0x44D); msleep(200); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0c4d); + msleep(200); + rtl8225_write(dev, 0x02, 0x044d); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", + rtl8225_read(dev, 6)); + } + + rtl8225_write(dev, 0x0, 0x127); + + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x027); + rtl8225_write(dev, 0x0, 0x22F); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); + + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); + rtl8225_write_phy_cck(dev, 0x03, 0x20); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); + rtl8225_write_phy_cck(dev, 0x05, 0x12); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); + rtl8225_write_phy_cck(dev, 0x07, 0x78); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); + rtl8225_write_phy_cck(dev, 0x11, 0x88); + rtl8225_write_phy_cck(dev, 0x12, 0x47); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); + rtl8225_write_phy_cck(dev, 0x42, 0x15); + rtl8225_write_phy_cck(dev, 0x43, 0x18); + rtl8225_write_phy_cck(dev, 0x44, 0x1f); + rtl8225_write_phy_cck(dev, 0x45, 0x1e); + rtl8225_write_phy_cck(dev, 0x46, 0x1a); + rtl8225_write_phy_cck(dev, 0x47, 0x15); + rtl8225_write_phy_cck(dev, 0x48, 0x10); + rtl8225_write_phy_cck(dev, 0x49, 0x0a); + rtl8225_write_phy_cck(dev, 0x4a, 0x05); + rtl8225_write_phy_cck(dev, 0x4b, 0x02); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); + + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); + + rtl8225_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); + + /* set sensitivity */ + rtl8225_write(dev, 0x0c, 0x50); + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); +} + +static const u8 rtl8225z2_agc[] = { + 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f, + 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37, + 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, + 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07, + 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, + 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, + 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 +}; +static const u8 rtl8225z2_ofdm[] = { + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26, + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3, + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f, + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, + 0x6d, 0x3c, 0xfb, 0x07 +}; + +static const u8 rtl8225z2_tx_power_cck_ch14[] = { + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225z2_tx_power_cck[] = { + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04, + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 +}; + +static const u8 rtl8225z2_tx_gain_cck_ofdm[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 +}; + +static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power = min(cck_power, (u8)15); + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; + ofdm_power += priv->txpwr_base >> 4; + ofdm_power = min(ofdm_power, (u8)35); + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else + tmp = rtl8225z2_tx_power_cck; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225z2_tx_gain_cck_ofdm[cck_power]); + msleep(1); + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, + RTL8187_RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 5, 0x00); + rtl8225_write_phy_ofdm(dev, 6, 0x40); + rtl8225_write_phy_ofdm(dev, 7, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x40); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225z2_tx_gain_cck_ofdm[ofdm_power]); + msleep(1); +} + +static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + int i; + + cck_power = priv->channels[channel - 1].hw_value & 0xF; + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + + if (ofdm_power > 15) + ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25; + else + ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10; + ofdm_power += (priv->txpwr_base >> 4) & 0xF; + ofdm_power = min(ofdm_power, (u8)35); + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else + tmp = rtl8225z2_tx_power_cck; + + if (priv->hw_rev == RTL8187BvB) { + if (cck_power <= 6) + ; /* do nothing */ + else if (cck_power <= 11) + tmp += 8; + else + tmp += 16; + } else { + if (cck_power <= 5) + ; /* do nothing */ + else if (cck_power <= 11) + tmp += 8; + else if (cck_power <= 17) + tmp += 16; + else + tmp += 24; + } + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1); + msleep(1); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1); + if (priv->hw_rev == RTL8187BvB) { + if (ofdm_power <= 11) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x60); + rtl8225_write_phy_ofdm(dev, 0x89, 0x60); + } else { + rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); + rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); + } + } else { + if (ofdm_power <= 11) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); + rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); + } else if (ofdm_power <= 17) { + rtl8225_write_phy_ofdm(dev, 0x87, 0x54); + rtl8225_write_phy_ofdm(dev, 0x89, 0x54); + } else { + rtl8225_write_phy_ofdm(dev, 0x87, 0x50); + rtl8225_write_phy_ofdm(dev, 0x89, 0x50); + } + } + msleep(1); +} + +static const u16 rtl8225z2_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb +}; + +static const u8 rtl8225z2_gain_bg[] = { + 0x23, 0x15, 0xa5, /* -82-1dBm */ + 0x23, 0x15, 0xb5, /* -82-2dBm */ + 0x23, 0x15, 0xc5, /* -82-3dBm */ + 0x33, 0x15, 0xc5, /* -78dBm */ + 0x43, 0x15, 0xc5, /* -74dBm */ + 0x53, 0x15, 0xc5, /* -70dBm */ + 0x63, 0x15, 0xc5 /* -66dBm */ +}; + +static void rtl8225z2_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x2BF); + rtl8225_write(dev, 0x1, 0xEE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8C3); + rtl8225_write(dev, 0x5, 0xC72); + rtl8225_write(dev, 0x6, 0x0E6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x03F); + rtl8225_write(dev, 0x9, 0x335); + rtl8225_write(dev, 0xa, 0x9D4); + rtl8225_write(dev, 0xb, 0x7BB); + rtl8225_write(dev, 0xc, 0x850); + rtl8225_write(dev, 0xd, 0xCDF); + rtl8225_write(dev, 0xe, 0x02B); + rtl8225_write(dev, 0xf, 0x114); + msleep(100); + + rtl8225_write(dev, 0x0, 0x1B7); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x3, 0x080); + rtl8225_write(dev, 0x5, 0x004); + rtl8225_write(dev, 0x0, 0x0B7); + rtl8225_write(dev, 0x2, 0xc4D); + + msleep(200); + rtl8225_write(dev, 0x2, 0x44D); + msleep(100); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0C4D); + msleep(200); + rtl8225_write(dev, 0x02, 0x044D); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", + rtl8225_read(dev, 6)); + } + + msleep(200); + + rtl8225_write(dev, 0x0, 0x2BF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); + rtl8225_write_phy_ofdm(dev, 0x11, 0x07); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); + rtl8225_write_phy_ofdm(dev, 0x21, 0x17); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); + rtl8225_write_phy_ofdm(dev, 0x25, 0x00); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); + + rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); + rtl8225_write_phy_ofdm(dev, 0x21, 0x37); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); + rtl8225_write_phy_cck(dev, 0x03, 0x20); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); + rtl8225_write_phy_cck(dev, 0x05, 0x12); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); + rtl8225_write_phy_cck(dev, 0x07, 0x78); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); + rtl8225_write_phy_cck(dev, 0x11, 0x88); + rtl8225_write_phy_cck(dev, 0x12, 0x47); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); + rtl8225_write_phy_cck(dev, 0x42, 0x15); + rtl8225_write_phy_cck(dev, 0x43, 0x18); + rtl8225_write_phy_cck(dev, 0x44, 0x36); + rtl8225_write_phy_cck(dev, 0x45, 0x35); + rtl8225_write_phy_cck(dev, 0x46, 0x2e); + rtl8225_write_phy_cck(dev, 0x47, 0x25); + rtl8225_write_phy_cck(dev, 0x48, 0x1c); + rtl8225_write_phy_cck(dev, 0x49, 0x12); + rtl8225_write_phy_cck(dev, 0x4a, 0x09); + rtl8225_write_phy_cck(dev, 0x4b, 0x04); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); + + rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); + + rtl8225z2_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); +} + +static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x0B7); + rtl8225_write(dev, 0x1, 0xEE0); + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x3, 0x441); + rtl8225_write(dev, 0x4, 0x8C3); + rtl8225_write(dev, 0x5, 0xC72); + rtl8225_write(dev, 0x6, 0x0E6); + rtl8225_write(dev, 0x7, 0x82A); + rtl8225_write(dev, 0x8, 0x03F); + rtl8225_write(dev, 0x9, 0x335); + rtl8225_write(dev, 0xa, 0x9D4); + rtl8225_write(dev, 0xb, 0x7BB); + rtl8225_write(dev, 0xc, 0x850); + rtl8225_write(dev, 0xd, 0xCDF); + rtl8225_write(dev, 0xe, 0x02B); + rtl8225_write(dev, 0xf, 0x114); + + rtl8225_write(dev, 0x0, 0x1B7); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x3, 0x080); + rtl8225_write(dev, 0x5, 0x004); + rtl8225_write(dev, 0x0, 0x0B7); + + rtl8225_write(dev, 0x2, 0xC4D); + + rtl8225_write(dev, 0x2, 0x44D); + rtl8225_write(dev, 0x0, 0x2BF); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03); + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07); + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); + + rtl8225_write_phy_ofdm(dev, 0x80, 0x12); + for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]); + rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i); + rtl8225_write_phy_ofdm(dev, 0xE, 0); + } + rtl8225_write_phy_ofdm(dev, 0x80, 0x10); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) + rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]); + + rtl8225_write_phy_ofdm(dev, 0x97, 0x46); + rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); + rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); + rtl8225_write_phy_cck(dev, 0xc1, 0x88); +} + +static void rtl8225_rf_stop(struct ieee80211_hw *dev) +{ + rtl8225_write(dev, 0x4, 0x1f); +} + +static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + int chan = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); + + if (priv->rf->init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, chan); + else if (priv->rf->init == rtl8225z2_rf_init) + rtl8225z2_rf_set_tx_power(dev, chan); + else + rtl8225z2_b_rf_set_tx_power(dev, chan); + + rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); + msleep(10); +} + +static const struct rtl818x_rf_ops rtl8225_ops = { + .name = "rtl8225", + .init = rtl8225_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +static const struct rtl818x_rf_ops rtl8225z2_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +static const struct rtl818x_rf_ops rtl8225z2_b_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_b_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) +{ + u16 reg8, reg9; + struct rtl8187_priv *priv = dev->priv; + + if (!priv->is_rtl8187b) { + rtl8225_write(dev, 0, 0x1B7); + + reg8 = rtl8225_read(dev, 8); + reg9 = rtl8225_read(dev, 9); + + rtl8225_write(dev, 0, 0x0B7); + + if (reg8 != 0x588 || reg9 != 0x700) + return &rtl8225_ops; + + return &rtl8225z2_ops; + } else + return &rtl8225z2_b_ops; +} diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h new file mode 100644 index 000000000..b9475e6ea --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Radio tuning definitions for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + */ + +#ifndef RTL8187_RTL8225_H +#define RTL8187_RTL8225_H + +#define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59 +#define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312 +#define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11 + +#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658 +#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52 +#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00 +#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658 +#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50 +#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00 + +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); + +static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data); +} + +static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data | 0x10000); +} + +#endif /* RTL8187_RTL8225_H */ diff --git a/drivers/net/wireless/realtek/rtl818x/rtl818x.h b/drivers/net/wireless/realtek/rtl818x/rtl818x.h new file mode 100644 index 000000000..597f41af8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl818x/rtl818x.h @@ -0,0 +1,402 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Definitions for RTL818x hardware + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + */ + +#ifndef RTL818X_H +#define RTL818X_H + +struct rtl818x_csr { + + u8 MAC[6]; + u8 reserved_0[2]; + + union { + __le32 MAR[2]; /* 0x8 */ + + struct{ /* rtl8187se */ + u8 rf_sw_config; /* 0x8 */ + u8 reserved_01[3]; + __le32 TMGDA; /* 0xc */ + } __packed; + } __packed; + + union { /* 0x10 */ + struct { + u8 RX_FIFO_COUNT; + u8 reserved_1; + u8 TX_FIFO_COUNT; + u8 BQREQ; + } __packed; + + __le32 TBKDA; /* for 8187se */ + } __packed; + + __le32 TBEDA; /* 0x14 - for rtl8187se */ + + __le32 TSFT[2]; + + union { /* 0x20 */ + __le32 TLPDA; + __le32 TVIDA; /* for 8187se */ + } __packed; + + union { /* 0x24 */ + __le32 TNPDA; + __le32 TVODA; /* for 8187se */ + } __packed; + + /* hi pri ring for all cards */ + __le32 THPDA; /* 0x28 */ + + union { /* 0x2c */ + struct { + u8 reserved_2a; + u8 EIFS_8187SE; + } __packed; + + __le16 BRSR; + } __packed; + + u8 BSSID[6]; /* 0x2e */ + + union { /* 0x34 */ + struct { + u8 RESP_RATE; + u8 EIFS; + } __packed; + __le16 BRSR_8187SE; + } __packed; + + u8 reserved_3[1]; /* 0x36 */ + u8 CMD; /* 0x37 */ +#define RTL818X_CMD_TX_ENABLE (1 << 2) +#define RTL818X_CMD_RX_ENABLE (1 << 3) +#define RTL818X_CMD_RESET (1 << 4) + u8 reserved_4[4]; /* 0x38 */ + union { + struct { + __le16 INT_MASK; + __le16 INT_STATUS; + } __packed; + + __le32 INT_STATUS_SE; /* 0x3c */ + } __packed; +/* status bits for rtl8187 and rtl8180/8185 */ +#define RTL818X_INT_RX_OK (1 << 0) +#define RTL818X_INT_RX_ERR (1 << 1) +#define RTL818X_INT_TXL_OK (1 << 2) +#define RTL818X_INT_TXL_ERR (1 << 3) +#define RTL818X_INT_RX_DU (1 << 4) +#define RTL818X_INT_RX_FO (1 << 5) +#define RTL818X_INT_TXN_OK (1 << 6) +#define RTL818X_INT_TXN_ERR (1 << 7) +#define RTL818X_INT_TXH_OK (1 << 8) +#define RTL818X_INT_TXH_ERR (1 << 9) +#define RTL818X_INT_TXB_OK (1 << 10) +#define RTL818X_INT_TXB_ERR (1 << 11) +#define RTL818X_INT_ATIM (1 << 12) +#define RTL818X_INT_BEACON (1 << 13) +#define RTL818X_INT_TIME_OUT (1 << 14) +#define RTL818X_INT_TX_FO (1 << 15) +/* status bits for rtl8187se */ +#define RTL818X_INT_SE_TIMER3 (1 << 0) +#define RTL818X_INT_SE_TIMER2 (1 << 1) +#define RTL818X_INT_SE_RQ0SOR (1 << 2) +#define RTL818X_INT_SE_TXBED_OK (1 << 3) +#define RTL818X_INT_SE_TXBED_ERR (1 << 4) +#define RTL818X_INT_SE_TXBE_OK (1 << 5) +#define RTL818X_INT_SE_TXBE_ERR (1 << 6) +#define RTL818X_INT_SE_RX_OK (1 << 7) +#define RTL818X_INT_SE_RX_ERR (1 << 8) +#define RTL818X_INT_SE_TXL_OK (1 << 9) +#define RTL818X_INT_SE_TXL_ERR (1 << 10) +#define RTL818X_INT_SE_RX_DU (1 << 11) +#define RTL818X_INT_SE_RX_FIFO (1 << 12) +#define RTL818X_INT_SE_TXN_OK (1 << 13) +#define RTL818X_INT_SE_TXN_ERR (1 << 14) +#define RTL818X_INT_SE_TXH_OK (1 << 15) +#define RTL818X_INT_SE_TXH_ERR (1 << 16) +#define RTL818X_INT_SE_TXB_OK (1 << 17) +#define RTL818X_INT_SE_TXB_ERR (1 << 18) +#define RTL818X_INT_SE_ATIM_TO (1 << 19) +#define RTL818X_INT_SE_BK_TO (1 << 20) +#define RTL818X_INT_SE_TIMER1 (1 << 21) +#define RTL818X_INT_SE_TX_FIFO (1 << 22) +#define RTL818X_INT_SE_WAKEUP (1 << 23) +#define RTL818X_INT_SE_BK_DMA (1 << 24) +#define RTL818X_INT_SE_TMGD_OK (1 << 30) + __le32 TX_CONF; /* 0x40 */ +#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) +#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17) +#define RTL818X_TX_CONF_NO_ICV (1 << 19) +#define RTL818X_TX_CONF_DISCW (1 << 20) +#define RTL818X_TX_CONF_SAT_HWPLCP (1 << 24) +#define RTL818X_TX_CONF_R8180_ABCD (2 << 25) +#define RTL818X_TX_CONF_R8180_F (3 << 25) +#define RTL818X_TX_CONF_R8185_ABC (4 << 25) +#define RTL818X_TX_CONF_R8185_D (5 << 25) +#define RTL818X_TX_CONF_R8187vD (5 << 25) +#define RTL818X_TX_CONF_R8187vD_B (6 << 25) +#define RTL818X_TX_CONF_RTL8187SE (6 << 25) +#define RTL818X_TX_CONF_HWVER_MASK (7 << 25) +#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28) +#define RTL818X_TX_CONF_PROBE_DTS (1 << 29) +#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30) +#define RTL818X_TX_CONF_CW_MIN (1 << 31) + __le32 RX_CONF; +#define RTL818X_RX_CONF_MONITOR (1 << 0) +#define RTL818X_RX_CONF_NICMAC (1 << 1) +#define RTL818X_RX_CONF_MULTICAST (1 << 2) +#define RTL818X_RX_CONF_BROADCAST (1 << 3) +#define RTL818X_RX_CONF_FCS (1 << 5) +#define RTL818X_RX_CONF_DATA (1 << 18) +#define RTL818X_RX_CONF_CTRL (1 << 19) +#define RTL818X_RX_CONF_MGMT (1 << 20) +#define RTL818X_RX_CONF_ADDR3 (1 << 21) +#define RTL818X_RX_CONF_PM (1 << 22) +#define RTL818X_RX_CONF_BSSID (1 << 23) +#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28) +#define RTL818X_RX_CONF_CSDM1 (1 << 29) +#define RTL818X_RX_CONF_CSDM2 (1 << 30) +#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31) + __le32 INT_TIMEOUT; + __le32 TBDA; + u8 EEPROM_CMD; +#define RTL818X_EEPROM_CMD_READ (1 << 0) +#define RTL818X_EEPROM_CMD_WRITE (1 << 1) +#define RTL818X_EEPROM_CMD_CK (1 << 2) +#define RTL818X_EEPROM_CMD_CS (1 << 3) +#define RTL818X_EEPROM_CMD_NORMAL (0 << 6) +#define RTL818X_EEPROM_CMD_LOAD (1 << 6) +#define RTL818X_EEPROM_CMD_PROGRAM (2 << 6) +#define RTL818X_EEPROM_CMD_CONFIG (3 << 6) + u8 CONFIG0; + u8 CONFIG1; + u8 CONFIG2; +#define RTL818X_CONFIG2_ANTENNA_DIV (1 << 6) + __le32 ANAPARAM; + u8 MSR; +#define RTL818X_MSR_NO_LINK (0 << 2) +#define RTL818X_MSR_ADHOC (1 << 2) +#define RTL818X_MSR_INFRA (2 << 2) +#define RTL818X_MSR_MASTER (3 << 2) +#define RTL818X_MSR_ENEDCA (4 << 2) + u8 CONFIG3; +#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6) +#define RTL818X_CONFIG3_GNT_SELECT (1 << 7) + u8 CONFIG4; +#define RTL818X_CONFIG4_POWEROFF (1 << 6) +#define RTL818X_CONFIG4_VCOOFF (1 << 7) + u8 TESTR; + u8 reserved_9[2]; + u8 PGSELECT; + u8 SECURITY; + __le32 ANAPARAM2; + u8 reserved_10[8]; + __le32 IMR; /* 0x6c - Interrupt mask reg for 8187se */ +#define IMR_TMGDOK ((1 << 30)) +#define IMR_DOT11HINT ((1 << 25)) /* 802.11h Measurement Interrupt */ +#define IMR_BCNDMAINT ((1 << 24)) /* Beacon DMA Interrupt */ +#define IMR_WAKEINT ((1 << 23)) /* Wake Up Interrupt */ +#define IMR_TXFOVW ((1 << 22)) /* Tx FIFO Overflow */ +#define IMR_TIMEOUT1 ((1 << 21)) /* Time Out Interrupt 1 */ +#define IMR_BCNINT ((1 << 20)) /* Beacon Time out */ +#define IMR_ATIMINT ((1 << 19)) /* ATIM Time Out */ +#define IMR_TBDER ((1 << 18)) /* Tx Beacon Descriptor Error */ +#define IMR_TBDOK ((1 << 17)) /* Tx Beacon Descriptor OK */ +#define IMR_THPDER ((1 << 16)) /* Tx High Priority Descriptor Error */ +#define IMR_THPDOK ((1 << 15)) /* Tx High Priority Descriptor OK */ +#define IMR_TVODER ((1 << 14)) /* Tx AC_VO Descriptor Error Int */ +#define IMR_TVODOK ((1 << 13)) /* Tx AC_VO Descriptor OK Interrupt */ +#define IMR_FOVW ((1 << 12)) /* Rx FIFO Overflow Interrupt */ +#define IMR_RDU ((1 << 11)) /* Rx Descriptor Unavailable */ +#define IMR_TVIDER ((1 << 10)) /* Tx AC_VI Descriptor Error */ +#define IMR_TVIDOK ((1 << 9)) /* Tx AC_VI Descriptor OK Interrupt */ +#define IMR_RER ((1 << 8)) /* Rx Error Interrupt */ +#define IMR_ROK ((1 << 7)) /* Receive OK Interrupt */ +#define IMR_TBEDER ((1 << 6)) /* Tx AC_BE Descriptor Error */ +#define IMR_TBEDOK ((1 << 5)) /* Tx AC_BE Descriptor OK */ +#define IMR_TBKDER ((1 << 4)) /* Tx AC_BK Descriptor Error */ +#define IMR_TBKDOK ((1 << 3)) /* Tx AC_BK Descriptor OK */ +#define IMR_RQOSOK ((1 << 2)) /* Rx QoS OK Interrupt */ +#define IMR_TIMEOUT2 ((1 << 1)) /* Time Out Interrupt 2 */ +#define IMR_TIMEOUT3 ((1 << 0)) /* Time Out Interrupt 3 */ + __le16 BEACON_INTERVAL; /* 0x70 */ + __le16 ATIM_WND; /* 0x72 */ + __le16 BEACON_INTERVAL_TIME; /* 0x74 */ + __le16 ATIMTR_INTERVAL; /* 0x76 */ + u8 PHY_DELAY; /* 0x78 */ + u8 CARRIER_SENSE_COUNTER; /* 0x79 */ + u8 reserved_11[2]; /* 0x7a */ + u8 PHY[4]; /* 0x7c */ + __le16 RFPinsOutput; /* 0x80 */ + __le16 RFPinsEnable; /* 0x82 */ + __le16 RFPinsSelect; /* 0x84 */ + __le16 RFPinsInput; /* 0x86 */ + __le32 RF_PARA; /* 0x88 */ + __le32 RF_TIMING; /* 0x8c */ + u8 GP_ENABLE; /* 0x90 */ + u8 GPIO0; /* 0x91 */ + u8 GPIO1; /* 0x92 */ + u8 TPPOLL_STOP; /* 0x93 - rtl8187se only */ +#define RTL818x_TPPOLL_STOP_BQ (1 << 7) +#define RTL818x_TPPOLL_STOP_VI (1 << 4) +#define RTL818x_TPPOLL_STOP_VO (1 << 5) +#define RTL818x_TPPOLL_STOP_BE (1 << 3) +#define RTL818x_TPPOLL_STOP_BK (1 << 2) +#define RTL818x_TPPOLL_STOP_MG (1 << 1) +#define RTL818x_TPPOLL_STOP_HI (1 << 6) + + __le32 HSSI_PARA; /* 0x94 */ + u8 reserved_13[4]; /* 0x98 */ + u8 TX_AGC_CTL; /* 0x9c */ +#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN (1 << 0) +#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1) +#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2) + u8 TX_GAIN_CCK; + u8 TX_GAIN_OFDM; + u8 TX_ANTENNA; + u8 reserved_14[16]; + u8 WPA_CONF; + u8 reserved_15[3]; + u8 SIFS; + u8 DIFS; + u8 SLOT; + u8 reserved_16[5]; + u8 CW_CONF; +#define RTL818X_CW_CONF_PERPACKET_CW (1 << 0) +#define RTL818X_CW_CONF_PERPACKET_RETRY (1 << 1) + u8 CW_VAL; + u8 RATE_FALLBACK; +#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7) + u8 ACM_CONTROL; + u8 reserved_17[24]; + u8 CONFIG5; + u8 TX_DMA_POLLING; + u8 PHY_PR; + u8 reserved_18; + __le16 CWR; + u8 RETRY_CTR; + u8 reserved_19[3]; + __le16 INT_MIG; +/* RTL818X_R8187B_*: magic numbers from ioregisters */ +#define RTL818X_R8187B_B 0 +#define RTL818X_R8187B_D 1 +#define RTL818X_R8187B_E 2 + __le32 RDSAR; + __le16 TID_AC_MAP; + u8 reserved_20[4]; + union { + __le16 ANAPARAM3; /* 0xee */ + u8 ANAPARAM3A; /* for rtl8187 */ + }; + +#define AC_PARAM_TXOP_LIMIT_SHIFT 16 +#define AC_PARAM_ECW_MAX_SHIFT 12 +#define AC_PARAM_ECW_MIN_SHIFT 8 +#define AC_PARAM_AIFS_SHIFT 0 + + __le32 AC_VO_PARAM; /* 0xf0 */ + + union { /* 0xf4 */ + __le32 AC_VI_PARAM; + __le16 FEMR; + } __packed; + + union{ /* 0xf8 */ + __le32 AC_BE_PARAM; /* rtl8187se */ + struct{ + u8 reserved_21[2]; + __le16 TALLY_CNT; /* 0xfa */ + } __packed; + } __packed; + + union { + u8 TALLY_SEL; /* 0xfc */ + __le32 AC_BK_PARAM; + + } __packed; + +} __packed; + +/* These are addresses with NON-standard usage. + * They have offsets very far from this struct. + * I don't like to introduce a ton of "reserved".. + * They are for RTL8187SE + */ +#define REG_ADDR1(addr) ((u8 __iomem *)priv->map + (addr)) +#define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + ((addr) >> 1)) +#define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + ((addr) >> 2)) + +#define FEMR_SE REG_ADDR2(0x1D4) +#define ARFR REG_ADDR2(0x1E0) +#define RFSW_CTRL REG_ADDR2(0x272) +#define SW_3W_DB0 REG_ADDR2(0x274) +#define SW_3W_DB0_4 REG_ADDR4(0x274) +#define SW_3W_DB1 REG_ADDR2(0x278) +#define SW_3W_DB1_4 REG_ADDR4(0x278) +#define SW_3W_CMD1 REG_ADDR1(0x27D) +#define PI_DATA_REG REG_ADDR2(0x360) +#define SI_DATA_REG REG_ADDR2(0x362) + +struct rtl818x_rf_ops { + char *name; + void (*init)(struct ieee80211_hw *); + void (*stop)(struct ieee80211_hw *); + void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); + u8 (*calc_rssi)(u8 agc, u8 sq); +}; + +/** + * enum rtl818x_tx_desc_flags - Tx/Rx flags are common between RTL818X chips + * + * @RTL818X_TX_DESC_FLAG_NO_ENC: Disable hardware based encryption. + * @RTL818X_TX_DESC_FLAG_TX_OK: TX frame was ACKed. + * @RTL818X_TX_DESC_FLAG_SPLCP: Use short preamble. + * @RTL818X_TX_DESC_FLAG_MOREFRAG: More fragments follow. + * @RTL818X_TX_DESC_FLAG_CTS: Use CTS-to-self protection. + * @RTL818X_TX_DESC_FLAG_RTS: Use RTS/CTS protection. + * @RTL818X_TX_DESC_FLAG_LS: Last segment of the frame. + * @RTL818X_TX_DESC_FLAG_FS: First segment of the frame. + */ +enum rtl818x_tx_desc_flags { + RTL818X_TX_DESC_FLAG_NO_ENC = (1 << 15), + RTL818X_TX_DESC_FLAG_TX_OK = (1 << 15), + RTL818X_TX_DESC_FLAG_SPLCP = (1 << 16), + RTL818X_TX_DESC_FLAG_RX_UNDER = (1 << 16), + RTL818X_TX_DESC_FLAG_MOREFRAG = (1 << 17), + RTL818X_TX_DESC_FLAG_CTS = (1 << 18), + RTL818X_TX_DESC_FLAG_RTS = (1 << 23), + RTL818X_TX_DESC_FLAG_LS = (1 << 28), + RTL818X_TX_DESC_FLAG_FS = (1 << 29), + RTL818X_TX_DESC_FLAG_DMA = (1 << 30), + RTL818X_TX_DESC_FLAG_OWN = (1 << 31) +}; + +enum rtl818x_rx_desc_flags { + RTL818X_RX_DESC_FLAG_ICV_ERR = (1 << 12), + RTL818X_RX_DESC_FLAG_CRC32_ERR = (1 << 13), + RTL818X_RX_DESC_FLAG_PM = (1 << 14), + RTL818X_RX_DESC_FLAG_RX_ERR = (1 << 15), + RTL818X_RX_DESC_FLAG_BCAST = (1 << 16), + RTL818X_RX_DESC_FLAG_PAM = (1 << 17), + RTL818X_RX_DESC_FLAG_MCAST = (1 << 18), + RTL818X_RX_DESC_FLAG_QOS = (1 << 19), /* RTL8187(B) only */ + RTL818X_RX_DESC_FLAG_TRSW = (1 << 24), /* RTL8187(B) only */ + RTL818X_RX_DESC_FLAG_SPLCP = (1 << 25), + RTL818X_RX_DESC_FLAG_FOF = (1 << 26), + RTL818X_RX_DESC_FLAG_DMA_FAIL = (1 << 27), + RTL818X_RX_DESC_FLAG_LS = (1 << 28), + RTL818X_RX_DESC_FLAG_FS = (1 << 29), + RTL818X_RX_DESC_FLAG_EOR = (1 << 30), + RTL818X_RX_DESC_FLAG_OWN = (1 << 31) +}; + +#endif /* RTL818X_H */ diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8188e.c b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c new file mode 100644 index 000000000..fea5aec9c --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c @@ -0,0 +1,1886 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8188e specific subdriver + * + * Copyright (c) 2014 - 2016 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8188e_mac_init_table[] = { + {0x026, 0x41}, {0x027, 0x35}, {0x040, 0x00}, {0x421, 0x0f}, + {0x428, 0x0a}, {0x429, 0x10}, {0x430, 0x00}, {0x431, 0x01}, + {0x432, 0x02}, {0x433, 0x04}, {0x434, 0x05}, {0x435, 0x06}, + {0x436, 0x07}, {0x437, 0x08}, {0x438, 0x00}, {0x439, 0x00}, + {0x43a, 0x01}, {0x43b, 0x02}, {0x43c, 0x04}, {0x43d, 0x05}, + {0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01}, + {0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f}, + {0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72}, + {0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x480, 0x08}, + {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, {0x4cd, 0xff}, + {0x4ce, 0x01}, {0x4d3, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, + {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, + {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, + {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, + {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, + {0x516, 0x0a}, {0x525, 0x4f}, {0x550, 0x10}, {0x551, 0x10}, + {0x559, 0x02}, {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, + {0x609, 0x2a}, {0x620, 0xff}, {0x621, 0xff}, {0x622, 0xff}, + {0x623, 0xff}, {0x624, 0xff}, {0x625, 0xff}, {0x626, 0xff}, + {0x627, 0xff}, {0x63c, 0x08}, {0x63d, 0x08}, {0x63e, 0x0c}, + {0x63f, 0x0c}, {0x640, 0x40}, {0x652, 0x20}, {0x66e, 0x05}, + {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, {0x703, 0x87}, + {0x708, 0x21}, {0x709, 0x43}, {0x70a, 0x65}, {0x70b, 0x87}, + {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_reg32val rtl8188eu_phy_init_table[] = { + {0x800, 0x80040000}, {0x804, 0x00000003}, + {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, + {0x810, 0x10001331}, {0x814, 0x020c3d10}, + {0x818, 0x02200385}, {0x81c, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x00000000}, {0x82c, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83c, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84c, 0x00000000}, + {0x850, 0x00000000}, {0x854, 0x00000000}, + {0x858, 0x569a11a9}, {0x85c, 0x01000014}, + {0x860, 0x66f60110}, {0x864, 0x061f0649}, + {0x868, 0x00000000}, {0x86c, 0x27272700}, + {0x870, 0x07000760}, {0x874, 0x25004000}, + {0x878, 0x00000808}, {0x87c, 0x00000000}, + {0x880, 0xb0000c1c}, {0x884, 0x00000001}, + {0x888, 0x00000000}, {0x88c, 0xccc000c0}, + {0x890, 0x00000800}, {0x894, 0xfffffffe}, + {0x898, 0x40302010}, {0x89c, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90c, 0x81121111}, + {0x910, 0x00000002}, {0x914, 0x00000201}, + {0xa00, 0x00d047c8}, {0xa04, 0x80ff800c}, + {0xa08, 0x8c838300}, {0xa0c, 0x2e7f120f}, + {0xa10, 0x9500bb7e}, {0xa14, 0x1114d028}, + {0xa18, 0x00881117}, {0xa1c, 0x89140f00}, + {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317}, + {0xa28, 0x00000204}, {0xa2c, 0x00d30000}, + {0xa70, 0x101fbf00}, {0xa74, 0x00000007}, + {0xa78, 0x00000900}, {0xa7c, 0x225b0606}, + {0xa80, 0x218075b1}, {0xb2c, 0x80000000}, + {0xc00, 0x48071d40}, {0xc04, 0x03a05611}, + {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c}, + {0xc10, 0x08800000}, {0xc14, 0x40000100}, + {0xc18, 0x08800000}, {0xc1c, 0x40000100}, + {0xc20, 0x00000000}, {0xc24, 0x00000000}, + {0xc28, 0x00000000}, {0xc2c, 0x00000000}, + {0xc30, 0x69e9ac47}, {0xc34, 0x469652af}, + {0xc38, 0x49795994}, {0xc3c, 0x0a97971c}, + {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7}, + {0xc48, 0xec020107}, {0xc4c, 0x007f037f}, + {0xc50, 0x69553420}, {0xc54, 0x43bc0094}, + {0xc58, 0x00013169}, {0xc5c, 0x00250492}, + {0xc60, 0x00000000}, {0xc64, 0x7112848b}, + {0xc68, 0x47c00bff}, {0xc6c, 0x00000036}, + {0xc70, 0x2c7f000d}, {0xc74, 0x020610db}, + {0xc78, 0x0000001f}, {0xc7c, 0x00b91612}, + {0xc80, 0x390000e4}, {0xc84, 0x21f60000}, + {0xc88, 0x40000100}, {0xc8c, 0x20200000}, + {0xc90, 0x00091521}, {0xc94, 0x00000000}, + {0xc98, 0x00121820}, {0xc9c, 0x00007f7f}, + {0xca0, 0x00000000}, {0xca4, 0x000300a0}, + {0xca8, 0x00000000}, {0xcac, 0x00000000}, + {0xcb0, 0x00000000}, {0xcb4, 0x00000000}, + {0xcb8, 0x00000000}, {0xcbc, 0x28000000}, + {0xcc0, 0x00000000}, {0xcc4, 0x00000000}, + {0xcc8, 0x00000000}, {0xccc, 0x00000000}, + {0xcd0, 0x00000000}, {0xcd4, 0x00000000}, + {0xcd8, 0x64b22427}, {0xcdc, 0x00766932}, + {0xce0, 0x00222222}, {0xce4, 0x00000000}, + {0xce8, 0x37644302}, {0xcec, 0x2f97d40c}, + {0xd00, 0x00000740}, {0xd04, 0x00020401}, + {0xd08, 0x0000907f}, {0xd0c, 0x20010201}, + {0xd10, 0xa0633333}, {0xd14, 0x3333bc43}, + {0xd18, 0x7a8f5b6f}, {0xd2c, 0xcc979975}, + {0xd30, 0x00000000}, {0xd34, 0x80608000}, + {0xd38, 0x00000000}, {0xd3c, 0x00127353}, + {0xd40, 0x00000000}, {0xd44, 0x00000000}, + {0xd48, 0x00000000}, {0xd4c, 0x00000000}, + {0xd50, 0x6437140a}, {0xd54, 0x00000000}, + {0xd58, 0x00000282}, {0xd5c, 0x30032064}, + {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, + {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, + {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, + {0xd78, 0x000e3c24}, {0xe00, 0x2d2d2d2d}, + {0xe04, 0x2d2d2d2d}, {0xe08, 0x0390272d}, + {0xe10, 0x2d2d2d2d}, {0xe14, 0x2d2d2d2d}, + {0xe18, 0x2d2d2d2d}, {0xe1c, 0x2d2d2d2d}, + {0xe28, 0x00000000}, {0xe30, 0x1000dc1f}, + {0xe34, 0x10008c1f}, {0xe38, 0x02140102}, + {0xe3c, 0x681604c2}, {0xe40, 0x01007c00}, + {0xe44, 0x01004800}, {0xe48, 0xfb000000}, + {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f}, + {0xe54, 0x10008c1f}, {0xe58, 0x02140102}, + {0xe5c, 0x28160d05}, {0xe60, 0x00000048}, + {0xe68, 0x001b25a4}, {0xe6c, 0x00c00014}, + {0xe70, 0x00c00014}, {0xe74, 0x01000014}, + {0xe78, 0x01000014}, {0xe7c, 0x01000014}, + {0xe80, 0x01000014}, {0xe84, 0x00c00014}, + {0xe88, 0x01000014}, {0xe8c, 0x00c00014}, + {0xed0, 0x00c00014}, {0xed4, 0x00c00014}, + {0xed8, 0x00c00014}, {0xedc, 0x00000014}, + {0xee0, 0x00000014}, {0xee8, 0x21555448}, + {0xeec, 0x01c00014}, {0xf14, 0x00000003}, + {0xf4c, 0x00000000}, {0xf00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8188e_agc_table[] = { + {0xc78, 0xfb000001}, {0xc78, 0xfb010001}, + {0xc78, 0xfb020001}, {0xc78, 0xfb030001}, + {0xc78, 0xfb040001}, {0xc78, 0xfb050001}, + {0xc78, 0xfa060001}, {0xc78, 0xf9070001}, + {0xc78, 0xf8080001}, {0xc78, 0xf7090001}, + {0xc78, 0xf60a0001}, {0xc78, 0xf50b0001}, + {0xc78, 0xf40c0001}, {0xc78, 0xf30d0001}, + {0xc78, 0xf20e0001}, {0xc78, 0xf10f0001}, + {0xc78, 0xf0100001}, {0xc78, 0xef110001}, + {0xc78, 0xee120001}, {0xc78, 0xed130001}, + {0xc78, 0xec140001}, {0xc78, 0xeb150001}, + {0xc78, 0xea160001}, {0xc78, 0xe9170001}, + {0xc78, 0xe8180001}, {0xc78, 0xe7190001}, + {0xc78, 0xe61a0001}, {0xc78, 0xe51b0001}, + {0xc78, 0xe41c0001}, {0xc78, 0xe31d0001}, + {0xc78, 0xe21e0001}, {0xc78, 0xe11f0001}, + {0xc78, 0x8a200001}, {0xc78, 0x89210001}, + {0xc78, 0x88220001}, {0xc78, 0x87230001}, + {0xc78, 0x86240001}, {0xc78, 0x85250001}, + {0xc78, 0x84260001}, {0xc78, 0x83270001}, + {0xc78, 0x82280001}, {0xc78, 0x6b290001}, + {0xc78, 0x6a2a0001}, {0xc78, 0x692b0001}, + {0xc78, 0x682c0001}, {0xc78, 0x672d0001}, + {0xc78, 0x662e0001}, {0xc78, 0x652f0001}, + {0xc78, 0x64300001}, {0xc78, 0x63310001}, + {0xc78, 0x62320001}, {0xc78, 0x61330001}, + {0xc78, 0x46340001}, {0xc78, 0x45350001}, + {0xc78, 0x44360001}, {0xc78, 0x43370001}, + {0xc78, 0x42380001}, {0xc78, 0x41390001}, + {0xc78, 0x403a0001}, {0xc78, 0x403b0001}, + {0xc78, 0x403c0001}, {0xc78, 0x403d0001}, + {0xc78, 0x403e0001}, {0xc78, 0x403f0001}, + {0xc78, 0xfb400001}, {0xc78, 0xfb410001}, + {0xc78, 0xfb420001}, {0xc78, 0xfb430001}, + {0xc78, 0xfb440001}, {0xc78, 0xfb450001}, + {0xc78, 0xfb460001}, {0xc78, 0xfb470001}, + {0xc78, 0xfb480001}, {0xc78, 0xfa490001}, + {0xc78, 0xf94a0001}, {0xc78, 0xf84b0001}, + {0xc78, 0xf74c0001}, {0xc78, 0xf64d0001}, + {0xc78, 0xf54e0001}, {0xc78, 0xf44f0001}, + {0xc78, 0xf3500001}, {0xc78, 0xf2510001}, + {0xc78, 0xf1520001}, {0xc78, 0xf0530001}, + {0xc78, 0xef540001}, {0xc78, 0xee550001}, + {0xc78, 0xed560001}, {0xc78, 0xec570001}, + {0xc78, 0xeb580001}, {0xc78, 0xea590001}, + {0xc78, 0xe95a0001}, {0xc78, 0xe85b0001}, + {0xc78, 0xe75c0001}, {0xc78, 0xe65d0001}, + {0xc78, 0xe55e0001}, {0xc78, 0xe45f0001}, + {0xc78, 0xe3600001}, {0xc78, 0xe2610001}, + {0xc78, 0xc3620001}, {0xc78, 0xc2630001}, + {0xc78, 0xc1640001}, {0xc78, 0x8b650001}, + {0xc78, 0x8a660001}, {0xc78, 0x89670001}, + {0xc78, 0x88680001}, {0xc78, 0x87690001}, + {0xc78, 0x866a0001}, {0xc78, 0x856b0001}, + {0xc78, 0x846c0001}, {0xc78, 0x676d0001}, + {0xc78, 0x666e0001}, {0xc78, 0x656f0001}, + {0xc78, 0x64700001}, {0xc78, 0x63710001}, + {0xc78, 0x62720001}, {0xc78, 0x61730001}, + {0xc78, 0x60740001}, {0xc78, 0x46750001}, + {0xc78, 0x45760001}, {0xc78, 0x44770001}, + {0xc78, 0x43780001}, {0xc78, 0x42790001}, + {0xc78, 0x417a0001}, {0xc78, 0x407b0001}, + {0xc78, 0x407c0001}, {0xc78, 0x407d0001}, + {0xc78, 0x407e0001}, {0xc78, 0x407f0001}, + {0xc50, 0x69553422}, {0xc50, 0x69553420}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8188eu_radioa_init_table[] = { + {0x00, 0x00030000}, {0x08, 0x00084000}, + {0x18, 0x00000407}, {0x19, 0x00000012}, + {0x1e, 0x00080009}, {0x1f, 0x00000880}, + {0x2f, 0x0001a060}, {0x3f, 0x00000000}, + {0x42, 0x000060c0}, {0x57, 0x000d0000}, + {0x58, 0x000be180}, {0x67, 0x00001552}, + {0x83, 0x00000000}, {0xb0, 0x000ff8fc}, + {0xb1, 0x00054400}, {0xb2, 0x000ccc19}, + {0xb4, 0x00043003}, {0xb6, 0x0004953e}, + {0xb7, 0x0001c718}, {0xb8, 0x000060ff}, + {0xb9, 0x00080001}, {0xba, 0x00040000}, + {0xbb, 0x00000400}, {0xbf, 0x000c0000}, + {0xc2, 0x00002400}, {0xc3, 0x00000009}, + {0xc4, 0x00040c91}, {0xc5, 0x00099999}, + {0xc6, 0x000000a3}, {0xc7, 0x00088820}, + {0xc8, 0x00076c06}, {0xc9, 0x00000000}, + {0xca, 0x00080000}, {0xdf, 0x00000180}, + {0xef, 0x000001a0}, {0x51, 0x0006b27d}, + {0x52, 0x0007e49d}, /* Set to 0x0007e4dd for SDIO */ + {0x53, 0x00000073}, {0x56, 0x00051ff3}, + {0x35, 0x00000086}, {0x35, 0x00000186}, + {0x35, 0x00000286}, {0x36, 0x00001c25}, + {0x36, 0x00009c25}, {0x36, 0x00011c25}, + {0x36, 0x00019c25}, {0xb6, 0x00048538}, + {0x18, 0x00000c07}, {0x5a, 0x0004bd00}, + {0x19, 0x000739d0}, {0x34, 0x0000adf3}, + {0x34, 0x00009df0}, {0x34, 0x00008ded}, + {0x34, 0x00007dea}, {0x34, 0x00006de7}, + {0x34, 0x000054ee}, {0x34, 0x000044eb}, + {0x34, 0x000034e8}, {0x34, 0x0000246b}, + {0x34, 0x00001468}, {0x34, 0x0000006d}, + {0x00, 0x00030159}, {0x84, 0x00068200}, + {0x86, 0x000000ce}, {0x87, 0x00048a00}, + {0x8e, 0x00065540}, {0x8f, 0x00088000}, + {0xef, 0x000020a0}, {0x3b, 0x000f02b0}, + {0x3b, 0x000ef7b0}, {0x3b, 0x000d4fb0}, + {0x3b, 0x000cf060}, {0x3b, 0x000b0090}, + {0x3b, 0x000a0080}, {0x3b, 0x00090080}, + {0x3b, 0x0008f780}, {0x3b, 0x000722b0}, + {0x3b, 0x0006f7b0}, {0x3b, 0x00054fb0}, + {0x3b, 0x0004f060}, {0x3b, 0x00030090}, + {0x3b, 0x00020080}, {0x3b, 0x00010080}, + {0x3b, 0x0000f780}, {0xef, 0x000000a0}, + {0x00, 0x00010159}, {0x18, 0x0000f407}, + {0xFE, 0x00000000}, {0xFE, 0x00000000}, + {0x1F, 0x00080003}, {0xFE, 0x00000000}, + {0xFE, 0x00000000}, {0x1E, 0x00000001}, + {0x1F, 0x00080000}, {0x00, 0x00033e60}, + {0xff, 0xffffffff} +}; + +#define PERENTRY 23 +#define RETRYSIZE 5 +#define RATESIZE 28 +#define TX_RPT2_ITEM_SIZE 8 + +static const u8 retry_penalty[PERENTRY][RETRYSIZE + 1] = { + {5, 4, 3, 2, 0, 3}, /* 92 , idx=0 */ + {6, 5, 4, 3, 0, 4}, /* 86 , idx=1 */ + {6, 5, 4, 2, 0, 4}, /* 81 , idx=2 */ + {8, 7, 6, 4, 0, 6}, /* 75 , idx=3 */ + {10, 9, 8, 6, 0, 8}, /* 71 , idx=4 */ + {10, 9, 8, 4, 0, 8}, /* 66 , idx=5 */ + {10, 9, 8, 2, 0, 8}, /* 62 , idx=6 */ + {10, 9, 8, 0, 0, 8}, /* 59 , idx=7 */ + {18, 17, 16, 8, 0, 16}, /* 53 , idx=8 */ + {26, 25, 24, 16, 0, 24}, /* 50 , idx=9 */ + {34, 33, 32, 24, 0, 32}, /* 47 , idx=0x0a */ + {34, 31, 28, 20, 0, 32}, /* 43 , idx=0x0b */ + {34, 31, 27, 18, 0, 32}, /* 40 , idx=0x0c */ + {34, 31, 26, 16, 0, 32}, /* 37 , idx=0x0d */ + {34, 30, 22, 16, 0, 32}, /* 32 , idx=0x0e */ + {34, 30, 24, 16, 0, 32}, /* 26 , idx=0x0f */ + {49, 46, 40, 16, 0, 48}, /* 20 , idx=0x10 */ + {49, 45, 32, 0, 0, 48}, /* 17 , idx=0x11 */ + {49, 45, 22, 18, 0, 48}, /* 15 , idx=0x12 */ + {49, 40, 24, 16, 0, 48}, /* 12 , idx=0x13 */ + {49, 32, 18, 12, 0, 48}, /* 9 , idx=0x14 */ + {49, 22, 18, 14, 0, 48}, /* 6 , idx=0x15 */ + {49, 16, 16, 0, 0, 48} /* 3, idx=0x16 */ +}; + +static const u8 pt_penalty[RETRYSIZE + 1] = {34, 31, 30, 24, 0, 32}; + +static const u8 retry_penalty_idx_normal[2][RATESIZE] = { + { /* RSSI>TH */ + 4, 4, 4, 5, + 4, 4, 5, 7, 7, 7, 8, 0x0a, + 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d, + 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f + }, + { /* RSSITH */ + 4, 4, 4, 5, + 4, 4, 5, 7, 7, 7, 8, 0x0a, + 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d, + 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f + }, + { /* RSSIudev->dev; + u32 sys_cfg, vendor; + int ret = 0; + + strscpy(priv->chip_name, "8188EU", sizeof(priv->chip_name)); + priv->rtl_chip = RTL8188E; + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + priv->has_wifi = 1; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + return -EOPNOTSUPP; + } + + /* + * TODO: At a glance, I cut requires a different firmware, + * different initialisation tables, and no software rate + * control. The vendor driver is not configured to handle + * I cut chips by default. Are there any in the wild? + */ + if (priv->chip_cut == 8) { + dev_info(dev, "RTL8188EU cut I is not supported. Please complain about it at linux-wireless@vger.kernel.org.\n"); + return -EOPNOTSUPP; + } + + vendor = sys_cfg & SYS_CFG_VENDOR_ID; + rtl8xxxu_identify_vendor_1bit(priv, vendor); + + ret = rtl8xxxu_config_endpoints_no_sie(priv); + + return ret; +} + +static void rtl8188eu_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u32 val32, rsr; + u8 opmode; + int sec_ch_above, channel; + int i; + + opmode = rtl8xxxu_read8(priv, REG_BW_OPMODE); + rsr = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + channel = hw->conf.chandef.chan->hw_value; + + switch (hw->conf.chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + opmode |= BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + break; + case NL80211_CHAN_WIDTH_40: + if (hw->conf.chandef.center_freq1 > + hw->conf.chandef.chan->center_freq) { + sec_ch_above = 1; + channel += 2; + } else { + sec_ch_above = 0; + channel -= 2; + } + + opmode &= ~BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + rsr &= ~RSR_RSC_BANDWIDTH_40M; + if (sec_ch_above) + rsr |= RSR_RSC_LOWER_SUB_CHANNEL; + else + rsr |= RSR_RSC_UPPER_SUB_CHANNEL; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, rsr); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + /* + * Set Control channel to upper or lower. These settings + * are required only for 40MHz + */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); + val32 &= ~CCK0_SIDEBAND; + if (!sec_ch_above) + val32 |= CCK0_SIDEBAND; + rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM1_LSTF); + val32 &= ~OFDM_LSTF_PRIME_CH_MASK; /* 0xc00 */ + if (sec_ch_above) + val32 |= OFDM_LSTF_PRIME_CH_LOW; + else + val32 |= OFDM_LSTF_PRIME_CH_HIGH; + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE); + val32 &= ~(FPGA0_PS_LOWER_CHANNEL | FPGA0_PS_UPPER_CHANNEL); + if (sec_ch_above) + val32 |= FPGA0_PS_UPPER_CHANNEL; + else + val32 |= FPGA0_PS_LOWER_CHANNEL; + rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32); + break; + + default: + break; + } + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + u32p_replace_bits(&val32, channel, MODE_AG_CHANNEL_MASK); + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) + val32 |= MODE_AG_BW_40MHZ_8723B; + else + val32 |= MODE_AG_BW_20MHZ_8723B; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } +} + +static void rtl8188eu_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u8 agg_ctrl, usb_spec; + + usb_spec = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION); + usb_spec &= ~USB_SPEC_USB_AGG_ENABLE; + rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, usb_spec); + + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); +} + +static int rtl8188eu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8188eu_efuse *efuse = &priv->efuse_wifi.efuse8188eu; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + + priv->default_crystal_cap = efuse->xtal_k & 0x3f; + + return 0; +} + +static void rtl8188eu_reset_8051(struct rtl8xxxu_priv *priv) +{ + u16 sys_func; + + sys_func = rtl8xxxu_read16(priv, REG_SYS_FUNC); + sys_func &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); + + sys_func |= SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); +} + +static int rtl8188eu_load_firmware(struct rtl8xxxu_priv *priv) +{ + const char *fw_name; + int ret; + + fw_name = "rtlwifi/rtl8188eufw.bin"; + + ret = rtl8xxxu_load_firmware(priv, fw_name); + + return ret; +} + +static void rtl8188eu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* + * Per vendor driver, run power sequence before init of RF + */ + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + val8 = SYS_FUNC_USBA | SYS_FUNC_USBD | + SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + rtl8xxxu_init_phy_regs(priv, rtl8188eu_phy_init_table); + rtl8xxxu_init_phy_regs(priv, rtl8188e_agc_table); +} + +static int rtl8188eu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + return rtl8xxxu_init_phy_rf(priv, rtl8188eu_radioa_init_table, RF_A); +} + +static int rtl8188eu_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_e94, reg_e9c; + int result = 0; + + /* Path A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x30008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8214032a); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + + return result; +} + +static int rtl8188eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32; + int result = 0; + + /* Leave IQK mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Enable path A PA in TX IQK mode */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf117b); + + /* Enter IQK mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* TX IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x81004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x30008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160804); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else + goto out; + + val32 = 0x80007c00 | + (reg_e94 & 0x03ff0000) | ((reg_e9c >> 16) & 0x03ff); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* Modify RX IQK mode table */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ffa); + + /* Enter IQK mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* IQK setting */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* Path A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x30008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x10008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160c05); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160c05); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path A RX IQK failed!\n", + __func__); + +out: + return result; +} + +static void rtl8188eu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32; + int path_a_ok; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_CCK0_AFE_SETTING + }; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + if (t == 0) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1); + priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI); + } + + if (!priv->pi_enabled) { + /* Switch BB to PI mode to do IQ Calibration. */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000100); + } + + /* MAC settings */ + rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); + + val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); + u32p_replace_bits(&val32, 0xf, 0x0f000000); + rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); + + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22204000); + + if (!priv->no_pape) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_SW_CTRL); + val32 |= (FPGA0_RF_PAPE | + (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT)); + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32); + } + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_RF_INT_OE); + val32 &= ~BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, val32); + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); + val32 &= ~BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); + + /* Page B init */ + rtl8xxxu_write32(priv, REG_CONFIG_ANT_A, 0x0f600000); + + /* IQ calibration setting */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x81004800); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8188eu_iqk_path_a(priv); + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A TX IQK failed!\n", __func__); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8188eu_rx_iqk_path_a(priv); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A RX IQK failed!\n", __func__); + + /* Back to BB mode, load original value */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + if (t == 0) + return; + + if (!priv->pi_enabled) { + /* Switch back BB to SI mode after finishing IQ Calibration */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000000); + } + + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Restore RX initial gain */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00032ed3); + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); +} + +static void rtl8188eu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok; + u32 reg_e94, reg_e9c, reg_ea4, reg_eac; + u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + bool simu; + + memset(result, 0, sizeof(result)); + result[3][0] = 0x100; + result[3][2] = 0x100; + result[3][4] = 0x100; + result[3][6] = 0x100; + + candidate = -1; + + path_a_ok = false; + + for (i = 0; i < 3; i++) { + rtl8188eu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_simularity_compare(priv, + result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_simularity_compare(priv, + result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_simularity_compare(priv, + result, 1, 2); + if (simu) + candidate = 1; + else + candidate = 3; + } + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + priv->rege94 = reg_e94; + reg_e9c = result[candidate][1]; + priv->rege9c = reg_e9c; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + priv->regeb4 = reg_eb4; + reg_ebc = result[candidate][5]; + priv->regebc = reg_ebc; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, + "%s: e94=%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", + __func__, reg_e94, reg_e9c, reg_ea4, reg_eac, + reg_eb4, reg_ebc, reg_ec4, reg_ecc); + path_a_ok = true; + } else { + reg_e94 = 0x100; + reg_eb4 = 0x100; + priv->rege94 = 0x100; + priv->regeb4 = 0x100; + reg_e9c = 0x0; + reg_ebc = 0x0; + priv->rege9c = 0x0; + priv->regebc = 0x0; + } + + if (reg_e94 && candidate >= 0) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); +} + +static void rtl8188e_disabled_to_emu(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 &= ~(APS_FSMCO_HW_SUSPEND | APS_FSMCO_PCIE); + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); +} + +static int rtl8188e_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + u16 val16; + int count, ret = 0; + + /* wait till 0x04[17] = 1 power ready*/ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* reset baseband */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~(SYS_FUNC_BBRSTB | SYS_FUNC_BB_GLB_RSTN); + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + /*0x24[23] = 2b'01 schmit trigger */ + val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL); + val32 |= BIT(23); + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32); + + /* 0x04[15] = 0 disable HWPDN (control by DRV)*/ + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 &= ~APS_FSMCO_HW_POWERDOWN; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + /*0x04[12:11] = 2b'00 disable WL suspend*/ + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 &= ~(APS_FSMCO_HW_SUSPEND | APS_FSMCO_PCIE); + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + /* set, then poll until 0 */ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_MAC_ENABLE; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* LDO normal mode*/ + val8 = rtl8xxxu_read8(priv, REG_LPLDO_CTRL); + val8 &= ~BIT(4); + rtl8xxxu_write8(priv, REG_LPLDO_CTRL, val8); + +exit: + return ret; +} + +static int rtl8188eu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* Turn off RF */ + val8 = rtl8xxxu_read8(priv, REG_RF_CTRL); + val8 &= ~RF_ENABLE; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + /* LDO Sleep mode */ + val8 = rtl8xxxu_read8(priv, REG_LPLDO_CTRL); + val8 |= BIT(4); + rtl8xxxu_write8(priv, REG_LPLDO_CTRL, val8); + + return 0; +} + +static int rtl8188eu_emu_to_disabled(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u16 val16; + u8 val8; + + val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL); + val32 |= BIT(23); + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32); + + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 &= ~APS_FSMCO_PCIE; + val16 |= APS_FSMCO_HW_SUSPEND; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x00); + + val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG + 1); + val8 &= ~BIT(4); + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG + 1, val8); + + /* Set USB suspend enable local register 0xfe10[4]=1 */ + val8 = rtl8xxxu_read8(priv, 0xfe10); + val8 |= BIT(4); + rtl8xxxu_write8(priv, 0xfe10, val8); + + return 0; +} + +static int rtl8188eu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u8 val8; + u16 val16; + u32 val32; + int retry, retval; + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x7f); + + retry = 100; + retval = -EBUSY; + /* Poll 32 bit wide REG_SCH_TX_CMD for 0 to ensure no TX is pending. */ + do { + val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); + if (!val32) { + retval = 0; + break; + } + } while (retry--); + + if (!retry) { + dev_warn(dev, "Failed to flush TX queue\n"); + retval = -EBUSY; + goto out; + } + + /* Disable CCK and OFDM, clock gated */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + udelay(2); + + /* Reset MAC TRX */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= 0xff; + val16 &= ~(CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | CR_SECURITY_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); + val8 |= DUAL_TSF_TX_OK; + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); + +out: + return retval; +} + +static int rtl8188eu_power_on(struct rtl8xxxu_priv *priv) +{ + u16 val16; + int ret; + + rtl8188e_disabled_to_emu(priv); + + ret = rtl8188e_emu_to_active(priv); + if (ret) + goto exit; + + /* + * Enable MAC DMA/WMAC/SCHEDULE/SEC block + * Set CR bit10 to enable 32k calibration. + * We do not set CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE here + * due to a hardware bug in the 88E, requiring those to be + * set after REG_TRXFF_BNDY is set. If not the RXFF bundary + * will get set to a larger buffer size than the real buffer + * size. + */ + val16 = (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + +exit: + return ret; +} + +static void rtl8188eu_power_off(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + rtl8xxxu_flush_fifo(priv); + + val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); + val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); + + rtl8188eu_active_to_lps(priv); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + /* Reset MCU */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + /* 32K_CTRL looks to be very 8188e specific */ + val8 = rtl8xxxu_read8(priv, REG_32K_CTRL); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_32K_CTRL, val8); + + rtl8188eu_active_to_emu(priv); + rtl8188eu_emu_to_disabled(priv); + + /* Reset MCU IO Wrapper */ + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 &= ~BIT(3); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 |= BIT(3); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + /* Vendor driver refers to GPIO_IN */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_PIN_CTRL); + /* Vendor driver refers to GPIO_OUT */ + rtl8xxxu_write8(priv, REG_GPIO_PIN_CTRL + 1, val8); + rtl8xxxu_write8(priv, REG_GPIO_PIN_CTRL + 2, 0xff); + + val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL); + rtl8xxxu_write8(priv, REG_GPIO_IO_SEL, val8 << 4); + val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL + 1); + rtl8xxxu_write8(priv, REG_GPIO_IO_SEL + 1, val8 | 0x0f); + + /* + * Set LNA, TRSW, EX_PA Pin to output mode + * Referred to as REG_BB_PAD_CTRL in 8188eu vendor driver + */ + rtl8xxxu_write32(priv, REG_PAD_CTRL1, 0x00080808); + + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x00); + + rtl8xxxu_write32(priv, REG_GPIO_MUXCFG, 0x00000000); +} + +static void rtl8188e_enable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); + val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_TX_A; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static void rtl8188e_disable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + /* Power down RF module */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); + + rtl8188eu_active_to_emu(priv); +} + +static void rtl8188e_usb_quirks(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + /* + * Technically this is not a USB quirk, but a chip quirk. + * This has to be done after REG_TRXFF_BNDY is set, see + * rtl8188eu_power_on() for details. + */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + rtl8xxxu_gen2_usb_quirks(priv); + + /* Pre-TX enable WEP/TKIP security */ + rtl8xxxu_write8(priv, REG_EARLY_MODE_CONTROL_8188E + 3, 0x01); +} + +static s8 rtl8188e_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + /* only use lna 0/1/2/3/7 */ + static const s8 lna_gain_table_0[8] = {17, -1, -13, -29, -32, -35, -38, -41}; + /* only use lna 3/7 */ + static const s8 lna_gain_table_1[8] = {29, 20, 12, 3, -6, -15, -24, -33}; + + u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; + s8 rx_pwr_all = 0x00; + u8 vga_idx, lna_idx; + s8 lna_gain = 0; + + lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); + vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); + + if (priv->chip_cut >= 8) /* cut I */ /* SMIC */ + lna_gain = lna_gain_table_0[lna_idx]; + else /* TSMC */ + lna_gain = lna_gain_table_1[lna_idx]; + + rx_pwr_all = lna_gain - (2 * vga_idx); + + return rx_pwr_all; +} + +static int rtl8188eu_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG2); + + if (brightness == LED_OFF) { + ledcfg &= ~LEDCFG2_HW_LED_CONTROL; + ledcfg |= LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE; + } else if (brightness == LED_ON) { + ledcfg &= ~(LEDCFG2_HW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE); + ledcfg |= LEDCFG2_SW_LED_CONTROL; + } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { + ledcfg &= ~LEDCFG2_SW_LED_DISABLE; + ledcfg |= LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE; + } + + rtl8xxxu_write8(priv, REG_LEDCFG2, ledcfg); + + return 0; +} + +static void rtl8188e_set_tx_rpt_timing(struct rtl8xxxu_ra_info *ra, u8 timing) +{ + u8 idx; + + for (idx = 0; idx < 5; idx++) + if (dynamic_tx_rpt_timing[idx] == ra->rpt_time) + break; + + if (timing == DEFAULT_TIMING) { + idx = 0; /* 200ms */ + } else if (timing == INCREASE_TIMING) { + if (idx < 5) + idx++; + } else if (timing == DECREASE_TIMING) { + if (idx > 0) + idx--; + } + + ra->rpt_time = dynamic_tx_rpt_timing[idx]; +} + +static void rtl8188e_rate_down(struct rtl8xxxu_ra_info *ra) +{ + u8 rate_id = ra->pre_rate; + u8 lowest_rate = ra->lowest_rate; + u8 highest_rate = ra->highest_rate; + s8 i; + + if (rate_id > highest_rate) { + rate_id = highest_rate; + } else if (ra->rate_sgi) { + ra->rate_sgi = 0; + } else if (rate_id > lowest_rate) { + if (rate_id > 0) { + for (i = rate_id - 1; i >= lowest_rate; i--) { + if (ra->ra_use_rate & BIT(i)) { + rate_id = i; + goto rate_down_finish; + } + } + } + } else if (rate_id <= lowest_rate) { + rate_id = lowest_rate; + } + +rate_down_finish: + if (ra->ra_waiting_counter == 1) { + ra->ra_waiting_counter++; + ra->ra_pending_counter++; + } else if (ra->ra_waiting_counter > 1) { + ra->ra_waiting_counter = 0; + ra->ra_pending_counter = 0; + } + + if (ra->ra_pending_counter >= 4) + ra->ra_pending_counter = 4; + + ra->ra_drop_after_down = 1; + + ra->decision_rate = rate_id; + + rtl8188e_set_tx_rpt_timing(ra, DECREASE_TIMING); +} + +static void rtl8188e_rate_up(struct rtl8xxxu_ra_info *ra) +{ + u8 rate_id = ra->pre_rate; + u8 highest_rate = ra->highest_rate; + u8 i; + + if (ra->ra_waiting_counter == 1) { + ra->ra_waiting_counter = 0; + ra->ra_pending_counter = 0; + } else if (ra->ra_waiting_counter > 1) { + ra->pre_rssi_sta_ra = ra->rssi_sta_ra; + goto rate_up_finish; + } + + rtl8188e_set_tx_rpt_timing(ra, DEFAULT_TIMING); + + if (rate_id < highest_rate) { + for (i = rate_id + 1; i <= highest_rate; i++) { + if (ra->ra_use_rate & BIT(i)) { + rate_id = i; + goto rate_up_finish; + } + } + } else if (rate_id == highest_rate) { + if (ra->sgi_enable && !ra->rate_sgi) + ra->rate_sgi = 1; + else if (!ra->sgi_enable) + ra->rate_sgi = 0; + } else { /* rate_id > ra->highest_rate */ + rate_id = highest_rate; + } + +rate_up_finish: + if (ra->ra_waiting_counter == (4 + pending_for_rate_up_fail[ra->ra_pending_counter])) + ra->ra_waiting_counter = 0; + else + ra->ra_waiting_counter++; + + ra->decision_rate = rate_id; +} + +static void rtl8188e_reset_ra_counter(struct rtl8xxxu_ra_info *ra) +{ + u8 rate_id = ra->decision_rate; + + ra->nsc_up = (n_threshold_high[rate_id] + n_threshold_low[rate_id]) >> 1; + ra->nsc_down = (n_threshold_high[rate_id] + n_threshold_low[rate_id]) >> 1; +} + +static void rtl8188e_rate_decision(struct rtl8xxxu_ra_info *ra) +{ + struct rtl8xxxu_priv *priv = container_of(ra, struct rtl8xxxu_priv, ra_info); + const u8 *retry_penalty_idx_0; + const u8 *retry_penalty_idx_1; + const u8 *retry_penalty_up_idx; + u8 rate_id, penalty_id1, penalty_id2; + int i; + + if (ra->total == 0) + return; + + if (ra->ra_drop_after_down) { + ra->ra_drop_after_down--; + + rtl8188e_reset_ra_counter(ra); + + return; + } + + if (priv->chip_cut == 8) { /* cut I */ + retry_penalty_idx_0 = retry_penalty_idx_cut_i[0]; + retry_penalty_idx_1 = retry_penalty_idx_cut_i[1]; + retry_penalty_up_idx = retry_penalty_up_idx_cut_i; + } else { + retry_penalty_idx_0 = retry_penalty_idx_normal[0]; + retry_penalty_idx_1 = retry_penalty_idx_normal[1]; + retry_penalty_up_idx = retry_penalty_up_idx_normal; + } + + if (ra->rssi_sta_ra < (ra->pre_rssi_sta_ra - 3) || + ra->rssi_sta_ra > (ra->pre_rssi_sta_ra + 3)) { + ra->pre_rssi_sta_ra = ra->rssi_sta_ra; + ra->ra_waiting_counter = 0; + ra->ra_pending_counter = 0; + } + + /* Start RA decision */ + if (ra->pre_rate > ra->highest_rate) + rate_id = ra->highest_rate; + else + rate_id = ra->pre_rate; + + /* rate down */ + if (ra->rssi_sta_ra > rssi_threshold[rate_id]) + penalty_id1 = retry_penalty_idx_0[rate_id]; + else + penalty_id1 = retry_penalty_idx_1[rate_id]; + + for (i = 0; i < 5; i++) + ra->nsc_down += ra->retry[i] * retry_penalty[penalty_id1][i]; + + if (ra->nsc_down > (ra->total * retry_penalty[penalty_id1][5])) + ra->nsc_down -= ra->total * retry_penalty[penalty_id1][5]; + else + ra->nsc_down = 0; + + /* rate up */ + penalty_id2 = retry_penalty_up_idx[rate_id]; + + for (i = 0; i < 5; i++) + ra->nsc_up += ra->retry[i] * retry_penalty[penalty_id2][i]; + + if (ra->nsc_up > (ra->total * retry_penalty[penalty_id2][5])) + ra->nsc_up -= ra->total * retry_penalty[penalty_id2][5]; + else + ra->nsc_up = 0; + + if (ra->nsc_down < n_threshold_low[rate_id] || + ra->drop > dropping_necessary[rate_id]) { + rtl8188e_rate_down(ra); + + rtl8xxxu_update_ra_report(&priv->ra_report, ra->decision_rate, + ra->rate_sgi, priv->ra_report.txrate.bw); + } else if (ra->nsc_up > n_threshold_high[rate_id]) { + rtl8188e_rate_up(ra); + + rtl8xxxu_update_ra_report(&priv->ra_report, ra->decision_rate, + ra->rate_sgi, priv->ra_report.txrate.bw); + } + + if (ra->decision_rate == ra->pre_rate) + ra->dynamic_tx_rpt_timing_counter++; + else + ra->dynamic_tx_rpt_timing_counter = 0; + + if (ra->dynamic_tx_rpt_timing_counter >= 4) { + /* Rate didn't change 4 times, extend RPT timing */ + rtl8188e_set_tx_rpt_timing(ra, INCREASE_TIMING); + ra->dynamic_tx_rpt_timing_counter = 0; + } + + ra->pre_rate = ra->decision_rate; + + rtl8188e_reset_ra_counter(ra); +} + +static void rtl8188e_power_training_try_state(struct rtl8xxxu_ra_info *ra) +{ + ra->pt_try_state = 0; + switch (ra->pt_mode_ss) { + case 3: + if (ra->decision_rate >= DESC_RATE_MCS13) + ra->pt_try_state = 1; + break; + case 2: + if (ra->decision_rate >= DESC_RATE_MCS5) + ra->pt_try_state = 1; + break; + case 1: + if (ra->decision_rate >= DESC_RATE_48M) + ra->pt_try_state = 1; + break; + case 0: + if (ra->decision_rate >= DESC_RATE_11M) + ra->pt_try_state = 1; + break; + default: + break; + } + + if (ra->rssi_sta_ra < 48) { + ra->pt_stage = 0; + } else if (ra->pt_try_state == 1) { + if ((ra->pt_stop_count >= 10) || + (ra->pt_pre_rssi > ra->rssi_sta_ra + 5) || + (ra->pt_pre_rssi < ra->rssi_sta_ra - 5) || + (ra->decision_rate != ra->pt_pre_rate)) { + if (ra->pt_stage == 0) + ra->pt_stage = 1; + else if (ra->pt_stage == 1) + ra->pt_stage = 3; + else + ra->pt_stage = 5; + + ra->pt_pre_rssi = ra->rssi_sta_ra; + ra->pt_stop_count = 0; + } else { + ra->ra_stage = 0; + ra->pt_stop_count++; + } + } else { + ra->pt_stage = 0; + ra->ra_stage = 0; + } + + ra->pt_pre_rate = ra->decision_rate; + + /* TODO: implement the "false alarm" statistics for this */ + /* Disable power training when noisy environment */ + /* if (p_dm_odm->is_disable_power_training) { */ + if (1) { + ra->pt_stage = 0; + ra->ra_stage = 0; + ra->pt_stop_count = 0; + } +} + +static void rtl8188e_power_training_decision(struct rtl8xxxu_ra_info *ra) +{ + u8 temp_stage; + u32 numsc; + u32 num_total; + u8 stage_id; + u8 j; + + numsc = 0; + num_total = ra->total * pt_penalty[5]; + for (j = 0; j <= 4; j++) { + numsc += ra->retry[j] * pt_penalty[j]; + + if (numsc > num_total) + break; + } + + j >>= 1; + temp_stage = (ra->pt_stage + 1) >> 1; + if (temp_stage > j) + stage_id = temp_stage - j; + else + stage_id = 0; + + ra->pt_smooth_factor = (ra->pt_smooth_factor >> 1) + + (ra->pt_smooth_factor >> 2) + + stage_id * 16 + 2; + if (ra->pt_smooth_factor > 192) + ra->pt_smooth_factor = 192; + stage_id = ra->pt_smooth_factor >> 6; + temp_stage = stage_id * 2; + if (temp_stage != 0) + temp_stage--; + if (ra->drop > 3) + temp_stage = 0; + ra->pt_stage = temp_stage; +} + +void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb) +{ + u32 *_rx_desc = (u32 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16)); + struct rtl8xxxu_rxdesc16 *rx_desc = (struct rtl8xxxu_rxdesc16 *)_rx_desc; + struct device *dev = &priv->udev->dev; + struct rtl8xxxu_ra_info *ra = &priv->ra_info; + u32 tx_rpt_len = rx_desc->pktlen & 0x3ff; + u32 items = tx_rpt_len / TX_RPT2_ITEM_SIZE; + u64 macid_valid = ((u64)_rx_desc[5] << 32) | _rx_desc[4]; + u32 macid; + u8 *rpt = skb->data; + bool valid; + u16 min_rpt_time = 0x927c; + + dev_dbg(dev, "%s: len: %d items: %d\n", __func__, tx_rpt_len, items); + + /* We only use macid 0, so only the first item is relevant. + * AP mode will use more of them if it's ever implemented. + */ + if (!priv->vifs[0] || priv->vifs[0]->type == NL80211_IFTYPE_STATION) + items = 1; + + for (macid = 0; macid < items; macid++) { + valid = false; + + if (macid < 64) + valid = macid_valid & BIT(macid); + + if (valid) { + ra->retry[0] = le16_to_cpu(*(__le16 *)rpt); + ra->retry[1] = rpt[2]; + ra->retry[2] = rpt[3]; + ra->retry[3] = rpt[4]; + ra->retry[4] = rpt[5]; + ra->drop = rpt[6]; + ra->total = ra->retry[0] + ra->retry[1] + ra->retry[2] + + ra->retry[3] + ra->retry[4] + ra->drop; + + if (ra->total > 0) { + if (ra->ra_stage < 5) + rtl8188e_rate_decision(ra); + else if (ra->ra_stage == 5) + rtl8188e_power_training_try_state(ra); + else /* ra->ra_stage == 6 */ + rtl8188e_power_training_decision(ra); + + if (ra->ra_stage <= 5) + ra->ra_stage++; + else + ra->ra_stage = 0; + } + } else if (macid == 0) { + dev_warn(dev, "%s: TX report item 0 not valid\n", __func__); + } + + dev_dbg(dev, "%s: valid: %d retry: %d %d %d %d %d drop: %d\n", + __func__, valid, + ra->retry[0], ra->retry[1], ra->retry[2], + ra->retry[3], ra->retry[4], ra->drop); + + if (min_rpt_time > ra->rpt_time) + min_rpt_time = ra->rpt_time; + + rpt += TX_RPT2_ITEM_SIZE; + } + + if (min_rpt_time != ra->pre_min_rpt_time) { + rtl8xxxu_write16(priv, REG_TX_REPORT_TIME, min_rpt_time); + ra->pre_min_rpt_time = min_rpt_time; + } +} + +static void rtl8188e_arfb_refresh(struct rtl8xxxu_ra_info *ra) +{ + s8 i; + + ra->ra_use_rate = ra->rate_mask; + + /* Highest rate */ + if (ra->ra_use_rate) { + for (i = RATESIZE; i >= 0; i--) { + if (ra->ra_use_rate & BIT(i)) { + ra->highest_rate = i; + break; + } + } + } else { + ra->highest_rate = 0; + } + + /* Lowest rate */ + if (ra->ra_use_rate) { + for (i = 0; i < RATESIZE; i++) { + if (ra->ra_use_rate & BIT(i)) { + ra->lowest_rate = i; + break; + } + } + } else { + ra->lowest_rate = 0; + } + + if (ra->highest_rate > DESC_RATE_MCS7) + ra->pt_mode_ss = 3; + else if (ra->highest_rate > DESC_RATE_54M) + ra->pt_mode_ss = 2; + else if (ra->highest_rate > DESC_RATE_11M) + ra->pt_mode_ss = 1; + else + ra->pt_mode_ss = 0; +} + +static void +rtl8188e_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, + u8 macid) +{ + struct rtl8xxxu_ra_info *ra = &priv->ra_info; + + ra->rate_id = rateid; + ra->rate_mask = ramask; + ra->sgi_enable = sgi; + + rtl8188e_arfb_refresh(ra); +} + +static void rtl8188e_ra_set_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi) +{ + priv->ra_info.rssi_sta_ra = rssi; +} + +void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra) +{ + ra->decision_rate = DESC_RATE_MCS7; + ra->pre_rate = DESC_RATE_MCS7; + ra->highest_rate = DESC_RATE_MCS7; + ra->lowest_rate = 0; + ra->rate_id = 0; + ra->rate_mask = 0xfffff; + ra->rssi_sta_ra = 0; + ra->pre_rssi_sta_ra = 0; + ra->sgi_enable = 0; + ra->ra_use_rate = 0xfffff; + ra->nsc_down = (n_threshold_high[DESC_RATE_MCS7] + n_threshold_low[DESC_RATE_MCS7]) / 2; + ra->nsc_up = (n_threshold_high[DESC_RATE_MCS7] + n_threshold_low[DESC_RATE_MCS7]) / 2; + ra->rate_sgi = 0; + ra->rpt_time = 0x927c; + ra->drop = 0; + ra->retry[0] = 0; + ra->retry[1] = 0; + ra->retry[2] = 0; + ra->retry[3] = 0; + ra->retry[4] = 0; + ra->total = 0; + ra->ra_waiting_counter = 0; + ra->ra_pending_counter = 0; + ra->ra_drop_after_down = 0; + + ra->pt_try_state = 0; + ra->pt_stage = 5; + ra->pt_smooth_factor = 192; + ra->pt_stop_count = 0; + ra->pt_pre_rate = 0; + ra->pt_pre_rssi = 0; + ra->pt_mode_ss = 0; + ra->ra_stage = 0; +} + +struct rtl8xxxu_fileops rtl8188eu_fops = { + .identify_chip = rtl8188eu_identify_chip, + .parse_efuse = rtl8188eu_parse_efuse, + .load_firmware = rtl8188eu_load_firmware, + .power_on = rtl8188eu_power_on, + .power_off = rtl8188eu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8188eu_reset_8051, + .llt_init = rtl8xxxu_init_llt_table, + .init_phy_bb = rtl8188eu_init_phy_bb, + .init_phy_rf = rtl8188eu_init_phy_rf, + .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, + .phy_iq_calibrate = rtl8188eu_phy_iq_calibrate, + .config_channel = rtl8188eu_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc16, + .parse_phystats = rtl8723au_rx_parse_phystats, + .init_aggregation = rtl8188eu_init_aggregation, + .enable_rf = rtl8188e_enable_rf, + .disable_rf = rtl8188e_disable_rf, + .usb_quirks = rtl8188e_usb_quirks, + .set_tx_power = rtl8188f_set_tx_power, + .update_rate_mask = rtl8188e_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8188e_ra_set_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v3, + .set_crystal_cap = rtl8188f_set_crystal_cap, + .cck_rssi = rtl8188e_cck_rssi, + .led_classdev_brightness_set = rtl8188eu_led_brightness_set, + .writeN_block_size = 196, + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), + .has_tx_report = 1, + .init_reg_pkt_life_time = 1, + .gen2_thermal_meter = 1, + .hw_feature_report = 0, + .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + /* + * Use 9K for 8188e normal chip + * Max RX buffer = 10K - max(TxReportSize(64*8), WOLPattern(16*24)) + */ + .trxff_boundary = 0x25ff, + .pbp_rx = PBP_PAGE_SIZE_128, + .pbp_tx = PBP_PAGE_SIZE_128, + .mactable = rtl8188e_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8188E, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8188E, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8188E, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8188E, + .last_llt_entry = 175, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8188f.c b/drivers/net/wireless/realtek/rtl8xxxu/8188f.c new file mode 100644 index 000000000..5556aad1a --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8188f.c @@ -0,0 +1,1766 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8188f specific subdriver + * + * Copyright (c) 2022 Bitterblue Smith + * + * Portions copied from existing rtl8xxxu code: + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8188f_mac_init_table[] = { + {0x024, 0xDF}, {0x025, 0x07}, {0x02B, 0x1C}, {0x283, 0x20}, + {0x421, 0x0F}, {0x428, 0x0A}, {0x429, 0x10}, {0x430, 0x00}, + {0x431, 0x00}, {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, + {0x435, 0x05}, {0x436, 0x07}, {0x437, 0x08}, {0x43C, 0x04}, + {0x43D, 0x05}, {0x43E, 0x07}, {0x43F, 0x08}, {0x440, 0x5D}, + {0x441, 0x01}, {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, + {0x446, 0x00}, {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xF0}, + {0x44A, 0x0F}, {0x44B, 0x3E}, {0x44C, 0x10}, {0x44D, 0x00}, + {0x44E, 0x00}, {0x44F, 0x00}, {0x450, 0x00}, {0x451, 0xF0}, + {0x452, 0x0F}, {0x453, 0x00}, {0x456, 0x5E}, {0x460, 0x44}, + {0x461, 0x44}, {0x4BC, 0xC0}, {0x4C8, 0xFF}, {0x4C9, 0x08}, + {0x4CC, 0xFF}, {0x4CD, 0xFF}, {0x4CE, 0x01}, {0x500, 0x26}, + {0x501, 0xA2}, {0x502, 0x2F}, {0x503, 0x00}, {0x504, 0x28}, + {0x505, 0xA3}, {0x506, 0x5E}, {0x507, 0x00}, {0x508, 0x2B}, + {0x509, 0xA4}, {0x50A, 0x5E}, {0x50B, 0x00}, {0x50C, 0x4F}, + {0x50D, 0xA4}, {0x50E, 0x00}, {0x50F, 0x00}, {0x512, 0x1C}, + {0x514, 0x0A}, {0x516, 0x0A}, {0x525, 0x4F}, {0x550, 0x10}, + {0x551, 0x10}, {0x559, 0x02}, {0x55C, 0x28}, {0x55D, 0xFF}, + {0x605, 0x30}, {0x608, 0x0E}, {0x609, 0x2A}, {0x620, 0xFF}, + {0x621, 0xFF}, {0x622, 0xFF}, {0x623, 0xFF}, {0x624, 0xFF}, + {0x625, 0xFF}, {0x626, 0xFF}, {0x627, 0xFF}, {0x638, 0x28}, + {0x63C, 0x0A}, {0x63D, 0x0A}, {0x63E, 0x0E}, {0x63F, 0x0E}, + {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xC8}, + {0x66E, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, + {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70A, 0x65}, + {0x70B, 0x87}, + {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_reg32val rtl8188fu_phy_init_table[] = { + {0x800, 0x80045700}, {0x804, 0x00000001}, + {0x808, 0x0000FC00}, {0x80C, 0x0000000A}, + {0x810, 0x10001331}, {0x814, 0x020C3D10}, + {0x818, 0x00200385}, {0x81C, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x00000000}, {0x82C, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83C, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84C, 0x00000000}, + {0x850, 0x00030000}, {0x854, 0x00000000}, + {0x858, 0x569A569A}, {0x85C, 0x569A569A}, + {0x860, 0x00000130}, {0x864, 0x00000000}, + {0x868, 0x00000000}, {0x86C, 0x27272700}, + {0x870, 0x00000000}, {0x874, 0x25004000}, + {0x878, 0x00000808}, {0x87C, 0x004F0201}, + {0x880, 0xB0000B1E}, {0x884, 0x00000007}, + {0x888, 0x00000000}, {0x88C, 0xCCC000C0}, + {0x890, 0x00000800}, {0x894, 0xFFFFFFFE}, + {0x898, 0x40302010}, {0x89C, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90C, 0x81121111}, + {0x910, 0x00000002}, {0x914, 0x00000201}, + {0x948, 0x99000000}, {0x94C, 0x00000010}, + {0x950, 0x20003000}, {0x954, 0x4A880000}, + {0x958, 0x4BC5D87A}, {0x95C, 0x04EB9B79}, + {0x96C, 0x00000003}, {0xA00, 0x00D047C8}, + {0xA04, 0x80FF800C}, {0xA08, 0x8C898300}, + {0xA0C, 0x2E7F120F}, {0xA10, 0x9500BB78}, + {0xA14, 0x1114D028}, {0xA18, 0x00881117}, + {0xA1C, 0x89140F00}, {0xA20, 0xD1D80000}, + {0xA24, 0x5A7DA0BD}, {0xA28, 0x0000223B}, + {0xA2C, 0x00D30000}, {0xA70, 0x101FBF00}, + {0xA74, 0x00000007}, {0xA78, 0x00000900}, + {0xA7C, 0x225B0606}, {0xA80, 0x218075B1}, + {0xA84, 0x00120000}, {0xA88, 0x040C0000}, + {0xA8C, 0x12345678}, {0xA90, 0xABCDEF00}, + {0xA94, 0x001B1B89}, {0xA98, 0x05100000}, + {0xA9C, 0x3F000000}, {0xAA0, 0x00000000}, + {0xB2C, 0x00000000}, {0xC00, 0x48071D40}, + {0xC04, 0x03A05611}, {0xC08, 0x000000E4}, + {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000}, + {0xC14, 0x40000100}, {0xC18, 0x08800000}, + {0xC1C, 0x40000100}, {0xC20, 0x00000000}, + {0xC24, 0x00000000}, {0xC28, 0x00000000}, + {0xC2C, 0x00000000}, {0xC30, 0x69E9CC4A}, + {0xC34, 0x31000040}, {0xC38, 0x21688080}, + {0xC3C, 0x00001714}, {0xC40, 0x1F78403F}, + {0xC44, 0x00010036}, {0xC48, 0xEC020107}, + {0xC4C, 0x007F037F}, {0xC50, 0x69553420}, + {0xC54, 0x43BC0094}, {0xC58, 0x00013169}, + {0xC5C, 0x00250492}, {0xC60, 0x00000000}, + {0xC64, 0x7112848B}, {0xC68, 0x47C07BFF}, + {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D}, + {0xC74, 0x020600DB}, {0xC78, 0x0000001F}, + {0xC7C, 0x00B91612}, {0xC80, 0x390000E4}, + {0xC84, 0x11F60000}, + {0xC88, 0x40000100}, {0xC8C, 0x20200000}, + {0xC90, 0x00091521}, {0xC94, 0x00000000}, + {0xC98, 0x00121820}, {0xC9C, 0x00007F7F}, + {0xCA0, 0x00000000}, {0xCA4, 0x000300A0}, + {0xCA8, 0x00000000}, {0xCAC, 0x00000000}, + {0xCB0, 0x00000000}, {0xCB4, 0x00000000}, + {0xCB8, 0x00000000}, {0xCBC, 0x28000000}, + {0xCC0, 0x00000000}, {0xCC4, 0x00000000}, + {0xCC8, 0x00000000}, {0xCCC, 0x00000000}, + {0xCD0, 0x00000000}, {0xCD4, 0x00000000}, + {0xCD8, 0x64B22427}, {0xCDC, 0x00766932}, + {0xCE0, 0x00222222}, {0xCE4, 0x10000000}, + {0xCE8, 0x37644302}, {0xCEC, 0x2F97D40C}, + {0xD00, 0x04030740}, {0xD04, 0x40020401}, + {0xD08, 0x0000907F}, {0xD0C, 0x20010201}, + {0xD10, 0xA0633333}, {0xD14, 0x3333BC53}, + {0xD18, 0x7A8F5B6F}, {0xD2C, 0xCB979975}, + {0xD30, 0x00000000}, {0xD34, 0x80608000}, + {0xD38, 0x98000000}, {0xD3C, 0x40127353}, + {0xD40, 0x00000000}, {0xD44, 0x00000000}, + {0xD48, 0x00000000}, {0xD4C, 0x00000000}, + {0xD50, 0x6437140A}, {0xD54, 0x00000000}, + {0xD58, 0x00000282}, {0xD5C, 0x30032064}, + {0xD60, 0x4653DE68}, {0xD64, 0x04518A3C}, + {0xD68, 0x00002101}, {0xD6C, 0x2A201C16}, + {0xD70, 0x1812362E}, {0xD74, 0x322C2220}, + {0xD78, 0x000E3C24}, {0xE00, 0x2D2D2D2D}, + {0xE04, 0x2D2D2D2D}, {0xE08, 0x0390272D}, + {0xE10, 0x2D2D2D2D}, {0xE14, 0x2D2D2D2D}, + {0xE18, 0x2D2D2D2D}, {0xE1C, 0x2D2D2D2D}, + {0xE28, 0x00000000}, {0xE30, 0x1000DC1F}, + {0xE34, 0x10008C1F}, {0xE38, 0x02140102}, + {0xE3C, 0x681604C2}, {0xE40, 0x01007C00}, + {0xE44, 0x01004800}, {0xE48, 0xFB000000}, + {0xE4C, 0x000028D1}, {0xE50, 0x1000DC1F}, + {0xE54, 0x10008C1F}, {0xE58, 0x02140102}, + {0xE5C, 0x28160D05}, {0xE60, 0x00000008}, + {0xE60, 0x021400A0}, {0xE64, 0x281600A0}, + {0xE6C, 0x01C00010}, {0xE70, 0x01C00010}, + {0xE74, 0x02000010}, {0xE78, 0x02000010}, + {0xE7C, 0x02000010}, {0xE80, 0x02000010}, + {0xE84, 0x01C00010}, {0xE88, 0x02000010}, + {0xE8C, 0x01C00010}, {0xED0, 0x01C00010}, + {0xED4, 0x01C00010}, {0xED8, 0x01C00010}, + {0xEDC, 0x00000010}, {0xEE0, 0x00000010}, + {0xEEC, 0x03C00010}, {0xF14, 0x00000003}, + {0xF4C, 0x00000000}, {0xF00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8188f_agc_table[] = { + {0xC78, 0xFC000001}, {0xC78, 0xFB010001}, + {0xC78, 0xFA020001}, {0xC78, 0xF9030001}, + {0xC78, 0xF8040001}, {0xC78, 0xF7050001}, + {0xC78, 0xF6060001}, {0xC78, 0xF5070001}, + {0xC78, 0xF4080001}, {0xC78, 0xF3090001}, + {0xC78, 0xF20A0001}, {0xC78, 0xF10B0001}, + {0xC78, 0xF00C0001}, {0xC78, 0xEF0D0001}, + {0xC78, 0xEE0E0001}, {0xC78, 0xED0F0001}, + {0xC78, 0xEC100001}, {0xC78, 0xEB110001}, + {0xC78, 0xEA120001}, {0xC78, 0xE9130001}, + {0xC78, 0xE8140001}, {0xC78, 0xE7150001}, + {0xC78, 0xE6160001}, {0xC78, 0xE5170001}, + {0xC78, 0xE4180001}, {0xC78, 0xE3190001}, + {0xC78, 0xE21A0001}, {0xC78, 0xE11B0001}, + {0xC78, 0xE01C0001}, {0xC78, 0xC21D0001}, + {0xC78, 0xC11E0001}, {0xC78, 0xC01F0001}, + {0xC78, 0xA5200001}, {0xC78, 0xA4210001}, + {0xC78, 0xA3220001}, {0xC78, 0xA2230001}, + {0xC78, 0xA1240001}, {0xC78, 0xA0250001}, + {0xC78, 0x65260001}, {0xC78, 0x64270001}, + {0xC78, 0x63280001}, {0xC78, 0x62290001}, + {0xC78, 0x612A0001}, {0xC78, 0x442B0001}, + {0xC78, 0x432C0001}, {0xC78, 0x422D0001}, + {0xC78, 0x412E0001}, {0xC78, 0x402F0001}, + {0xC78, 0x21300001}, {0xC78, 0x20310001}, + {0xC78, 0x05320001}, {0xC78, 0x04330001}, + {0xC78, 0x03340001}, {0xC78, 0x02350001}, + {0xC78, 0x01360001}, {0xC78, 0x00370001}, + {0xC78, 0x00380001}, {0xC78, 0x00390001}, + {0xC78, 0x003A0001}, {0xC78, 0x003B0001}, + {0xC78, 0x003C0001}, {0xC78, 0x003D0001}, + {0xC78, 0x003E0001}, {0xC78, 0x003F0001}, + {0xC50, 0x69553422}, {0xC50, 0x69553420}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8188fu_radioa_init_table[] = { + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x18, 0x00000407}, {0x19, 0x00000012}, + {0x1B, 0x00001C6C}, + {0x1E, 0x00080009}, {0x1F, 0x00000880}, + {0x2F, 0x0001A060}, {0x3F, 0x00028000}, + {0x42, 0x000060C0}, {0x57, 0x000D0000}, + {0x58, 0x000C0160}, {0x67, 0x00001552}, + {0x83, 0x00000000}, {0xB0, 0x000FF9F0}, + {0xB1, 0x00022218}, {0xB2, 0x00034C00}, + {0xB4, 0x0004484B}, {0xB5, 0x0000112A}, + {0xB6, 0x0000053E}, {0xB7, 0x00010408}, + {0xB8, 0x00010200}, {0xB9, 0x00080001}, + {0xBA, 0x00040001}, {0xBB, 0x00000400}, + {0xBF, 0x000C0000}, {0xC2, 0x00002400}, + {0xC3, 0x00000009}, {0xC4, 0x00040C91}, + {0xC5, 0x00099999}, {0xC6, 0x000000A3}, + {0xC7, 0x0008F820}, {0xC8, 0x00076C06}, + {0xC9, 0x00000000}, {0xCA, 0x00080000}, + {0xDF, 0x00000180}, {0xEF, 0x000001A0}, + {0x51, 0x000E8333}, {0x52, 0x000FAC2C}, + {0x53, 0x00000103}, {0x56, 0x000517F0}, + {0x35, 0x00000099}, {0x35, 0x00000199}, + {0x35, 0x00000299}, {0x36, 0x00000064}, + {0x36, 0x00008064}, {0x36, 0x00010064}, + {0x36, 0x00018064}, {0x18, 0x00000C07}, + {0x5A, 0x00048000}, {0x19, 0x000739D0}, + {0x34, 0x0000ADD6}, {0x34, 0x00009DD3}, + {0x34, 0x00008CF4}, {0x34, 0x00007CF1}, + {0x34, 0x00006CEE}, {0x34, 0x00005CEB}, + {0x34, 0x00004CCE}, {0x34, 0x00003CCB}, + {0x34, 0x00002CC8}, {0x34, 0x00001C4B}, + {0x34, 0x00000C48}, + {0x00, 0x00030159}, {0x84, 0x00048000}, + {0x86, 0x0000002A}, {0x87, 0x00000025}, + {0x8E, 0x00065540}, {0x8F, 0x00088000}, + {0xEF, 0x000020A0}, {0x3B, 0x000F0F00}, + {0x3B, 0x000E0B00}, {0x3B, 0x000D0900}, + {0x3B, 0x000C0700}, {0x3B, 0x000B0600}, + {0x3B, 0x000A0400}, {0x3B, 0x00090200}, + {0x3B, 0x00080000}, {0x3B, 0x0007BF00}, + {0x3B, 0x00060B00}, {0x3B, 0x0005C900}, + {0x3B, 0x00040700}, {0x3B, 0x00030600}, + {0x3B, 0x0002D500}, {0x3B, 0x00010200}, + {0x3B, 0x0000E000}, {0xEF, 0x000000A0}, + {0xEF, 0x00000010}, {0x3B, 0x0000C0A8}, + {0x3B, 0x00010400}, {0xEF, 0x00000000}, + {0xEF, 0x00080000}, {0x30, 0x00010000}, + {0x31, 0x0000000F}, {0x32, 0x00007EFE}, + {0xEF, 0x00000000}, {0x00, 0x00010159}, + {0x18, 0x0000FC07}, {0xFE, 0x00000000}, + {0xFE, 0x00000000}, {0x1F, 0x00080003}, + {0xFE, 0x00000000}, {0xFE, 0x00000000}, + {0x1E, 0x00000001}, {0x1F, 0x00080000}, + {0x00, 0x00033D95}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8188fu_cut_b_radioa_init_table[] = { + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x18, 0x00000407}, {0x19, 0x00000012}, + {0x1B, 0x00001C6C}, + {0x1E, 0x00080009}, {0x1F, 0x00000880}, + {0x2F, 0x0001A060}, {0x3F, 0x00028000}, + {0x42, 0x000060C0}, {0x57, 0x000D0000}, + {0x58, 0x000C0160}, {0x67, 0x00001552}, + {0x83, 0x00000000}, {0xB0, 0x000FF9F0}, + {0xB1, 0x00022218}, {0xB2, 0x00034C00}, + {0xB4, 0x0004484B}, {0xB5, 0x0000112A}, + {0xB6, 0x0000053E}, {0xB7, 0x00010408}, + {0xB8, 0x00010200}, {0xB9, 0x00080001}, + {0xBA, 0x00040001}, {0xBB, 0x00000400}, + {0xBF, 0x000C0000}, {0xC2, 0x00002400}, + {0xC3, 0x00000009}, {0xC4, 0x00040C91}, + {0xC5, 0x00099999}, {0xC6, 0x000000A3}, + {0xC7, 0x0008F820}, {0xC8, 0x00076C06}, + {0xC9, 0x00000000}, {0xCA, 0x00080000}, + {0xDF, 0x00000180}, {0xEF, 0x000001A0}, + {0x51, 0x000E8231}, {0x52, 0x000FAC2C}, + {0x53, 0x00000141}, {0x56, 0x000517F0}, + {0x35, 0x00000090}, {0x35, 0x00000190}, + {0x35, 0x00000290}, {0x36, 0x00001064}, + {0x36, 0x00009064}, {0x36, 0x00011064}, + {0x36, 0x00019064}, {0x18, 0x00000C07}, + {0x5A, 0x00048000}, {0x19, 0x000739D0}, + {0x34, 0x0000ADD2}, {0x34, 0x00009DD0}, + {0x34, 0x00008CF3}, {0x34, 0x00007CF0}, + {0x34, 0x00006CED}, {0x34, 0x00005CD2}, + {0x34, 0x00004CCF}, {0x34, 0x00003CCC}, + {0x34, 0x00002CC9}, {0x34, 0x00001C4C}, + {0x34, 0x00000C49}, + {0x00, 0x00030159}, {0x84, 0x00048000}, + {0x86, 0x0000002A}, {0x87, 0x00000025}, + {0x8E, 0x00065540}, {0x8F, 0x00088000}, + {0xEF, 0x000020A0}, {0x3B, 0x000F0F00}, + {0x3B, 0x000E0B00}, {0x3B, 0x000D0900}, + {0x3B, 0x000C0700}, {0x3B, 0x000B0600}, + {0x3B, 0x000A0400}, {0x3B, 0x00090200}, + {0x3B, 0x00080000}, {0x3B, 0x0007BF00}, + {0x3B, 0x00060B00}, {0x3B, 0x0005C900}, + {0x3B, 0x00040700}, {0x3B, 0x00030600}, + {0x3B, 0x0002D500}, {0x3B, 0x00010200}, + {0x3B, 0x0000E000}, {0xEF, 0x000000A0}, + {0xEF, 0x00000010}, {0x3B, 0x0000C0A8}, + {0x3B, 0x00010400}, {0xEF, 0x00000000}, + {0xEF, 0x00080000}, {0x30, 0x00010000}, + {0x31, 0x0000000F}, {0x32, 0x00007EFE}, + {0xEF, 0x00000000}, {0x00, 0x00010159}, + {0x18, 0x0000FC07}, {0xFE, 0x00000000}, + {0xFE, 0x00000000}, {0x1F, 0x00080003}, + {0xFE, 0x00000000}, {0xFE, 0x00000000}, + {0x1E, 0x00000001}, {0x1F, 0x00080000}, + {0x00, 0x00033D95}, + {0xff, 0xffffffff} +}; + +static int rtl8188fu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 sys_cfg, vendor; + int ret = 0; + + strscpy(priv->chip_name, "8188FU", sizeof(priv->chip_name)); + priv->rtl_chip = RTL8188F; + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + priv->has_wifi = 1; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + ret = -ENOTSUPP; + goto out; + } + + vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK; + rtl8xxxu_identify_vendor_2bits(priv, vendor); + + ret = rtl8xxxu_config_endpoints_no_sie(priv); + +out: + return ret; +} + +void rtl8188f_channel_to_group(int channel, int *group, int *cck_group) +{ + if (channel < 3) + *group = 0; + else if (channel < 6) + *group = 1; + else if (channel < 9) + *group = 2; + else if (channel < 12) + *group = 3; + else + *group = 4; + + if (channel == 14) + *cck_group = 5; + else + *cck_group = *group; +} + +void +rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) +{ + u32 val32, ofdm, mcs; + u8 cck, ofdmbase, mcsbase; + int group, cck_group; + + rtl8188f_channel_to_group(channel, &group, &cck_group); + + cck = priv->cck_tx_power_index_A[cck_group]; + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); + val32 &= 0xffff00ff; + val32 |= (cck << 8); + rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xff; + val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + ofdmbase = priv->ht40_1s_tx_power_index_A[group]; + ofdmbase += priv->ofdm_tx_power_diff[0].a; + ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm); + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_A[group]; + if (ht40) + /* This diff is always 0 - not used in 8188FU. */ + mcsbase += priv->ht40_tx_power_diff[0].a; + else + mcsbase += priv->ht20_tx_power_diff[0].a; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs); +} + +/* A workaround to eliminate the 2400MHz, 2440MHz, 2480MHz spur of 8188F. */ +static void rtl8188f_spur_calibration(struct rtl8xxxu_priv *priv, u8 channel) +{ + static const u32 frequencies[14 + 1] = { + [5] = 0xFCCD, + [6] = 0xFC4D, + [7] = 0xFFCD, + [8] = 0xFF4D, + [11] = 0xFDCD, + [13] = 0xFCCD, + [14] = 0xFF9A + }; + + static const u32 reg_d40[14 + 1] = { + [5] = 0x06000000, + [6] = 0x00000600, + [13] = 0x06000000 + }; + + static const u32 reg_d44[14 + 1] = { + [11] = 0x04000000 + }; + + static const u32 reg_d4c[14 + 1] = { + [7] = 0x06000000, + [8] = 0x00000380, + [14] = 0x00180000 + }; + + const u8 threshold = 0x16; + bool do_notch, hw_ctrl, sw_ctrl, hw_ctrl_s1 = 0, sw_ctrl_s1 = 0; + u32 val32, initial_gain, reg948; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_D_SYNC_PATH); + val32 |= GENMASK(28, 24); + rtl8xxxu_write32(priv, REG_OFDM0_RX_D_SYNC_PATH, val32); + + /* enable notch filter */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_D_SYNC_PATH); + val32 |= BIT(9); + rtl8xxxu_write32(priv, REG_OFDM0_RX_D_SYNC_PATH, val32); + + if (channel <= 14 && frequencies[channel] > 0) { + reg948 = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + hw_ctrl = reg948 & BIT(6); + sw_ctrl = !hw_ctrl; + + if (hw_ctrl) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); + val32 &= GENMASK(5, 3); + hw_ctrl_s1 = val32 == BIT(3); + } else if (sw_ctrl) { + sw_ctrl_s1 = !(reg948 & BIT(9)); + } + + if (hw_ctrl_s1 || sw_ctrl_s1) { + initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + + /* Disable CCK block */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE_CCK; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = initial_gain & ~OFDM0_X_AGC_CORE1_IGI_MASK; + val32 |= 0x30; + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); + + /* disable 3-wire */ + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + + /* Setup PSD */ + rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, frequencies[channel]); + + /* Start PSD */ + rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, 0x400000 | frequencies[channel]); + + msleep(30); + + do_notch = rtl8xxxu_read32(priv, REG_FPGA0_PSD_REPORT) >= threshold; + + /* turn off PSD */ + rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, frequencies[channel]); + + /* enable 3-wire */ + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccc000c0); + + /* Enable CCK block */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= FPGA_RF_MODE_CCK; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, initial_gain); + + if (do_notch) { + rtl8xxxu_write32(priv, REG_OFDM1_CSI_FIX_MASK1, reg_d40[channel]); + rtl8xxxu_write32(priv, REG_OFDM1_CSI_FIX_MASK2, reg_d44[channel]); + rtl8xxxu_write32(priv, 0xd48, 0x0); + rtl8xxxu_write32(priv, 0xd4c, reg_d4c[channel]); + + /* enable CSI mask */ + val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING); + val32 |= BIT(28); + rtl8xxxu_write32(priv, REG_OFDM1_CFO_TRACKING, val32); + + return; + } + } + } + + /* disable CSI mask function */ + val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING); + val32 &= ~BIT(28); + rtl8xxxu_write32(priv, REG_OFDM1_CFO_TRACKING, val32); +} + +static void rtl8188fu_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u32 val32; + u8 channel, subchannel; + bool sec_ch_above; + + channel = (u8)hw->conf.chandef.chan->hw_value; + + /* Set channel */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_CHANNEL_MASK; + val32 |= channel; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + + /* Spur calibration */ + rtl8188f_spur_calibration(priv, channel); + + /* Set bandwidth mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE; + val32 |= hw->conf.chandef.width == NL80211_CHAN_WIDTH_40; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 &= ~FPGA_RF_MODE; + val32 |= hw->conf.chandef.width == NL80211_CHAN_WIDTH_40; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + /* RXADC CLK */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= GENMASK(10, 8); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* TXDAC CLK */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= BIT(14) | BIT(12); + val32 &= ~BIT(13); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* small BW */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + val32 &= ~GENMASK(31, 30); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + /* adc buffer clk */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + val32 &= ~BIT(29); + val32 |= BIT(28); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + /* adc buffer clk */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_AFE); + val32 &= ~BIT(29); + val32 |= BIT(28); + rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_AFE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~BIT(19); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~GENMASK(23, 20); + val32 |= BIT(21); + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 || + hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) + val32 |= BIT(20); + else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) + val32 |= BIT(22); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) { + if (hw->conf.chandef.center_freq1 > + hw->conf.chandef.chan->center_freq) { + sec_ch_above = 1; + channel += 2; + } else { + sec_ch_above = 0; + channel -= 2; + } + + /* Set Control channel to upper or lower. */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); + val32 &= ~CCK0_SIDEBAND; + if (!sec_ch_above) + val32 |= CCK0_SIDEBAND; + rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); + + val32 = rtl8xxxu_read32(priv, REG_DATA_SUBCHANNEL); + val32 &= ~GENMASK(3, 0); + if (sec_ch_above) + subchannel = 2; + else + subchannel = 1; + val32 |= subchannel; + rtl8xxxu_write32(priv, REG_DATA_SUBCHANNEL, val32); + + val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + val32 &= ~RSR_RSC_BANDWIDTH_40M; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32); + } + + /* RF TRX_BW */ + val32 = channel; + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 || + hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) + val32 |= MODE_AG_BW_20MHZ_8723B; + else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) + val32 |= MODE_AG_BW_40MHZ_8723B; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + + /* FILTER BW&RC Corner (ACPR) */ + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 || + hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) + val32 = 0x00065; + else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) + val32 = 0x00025; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RXG_MIX_SWBW, val32); + + if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 || + hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) + val32 = 0x0; + else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) + val32 = 0x01000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_BB2, val32); + + /* RC Corner */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00140); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_G2, 0x01c6c); +} + +static void rtl8188fu_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u8 agg_ctrl, rxdma_mode, usb_tx_agg_desc_num = 6; + u32 agg_rx, val32; + + /* TX aggregation */ + val32 = rtl8xxxu_read32(priv, REG_DWBCN0_CTRL_8188F); + val32 &= ~(0xf << 4); + val32 |= usb_tx_agg_desc_num << 4; + rtl8xxxu_write32(priv, REG_DWBCN0_CTRL_8188F, val32); + rtl8xxxu_write8(priv, REG_DWBCN1_CTRL_8723B, usb_tx_agg_desc_num << 1); + + /* RX aggregation */ + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + + agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); + agg_rx &= ~RXDMA_USB_AGG_ENABLE; + agg_rx &= ~0xFF0F; /* reset agg size and timeout */ + + rxdma_mode = rtl8xxxu_read8(priv, REG_RXDMA_PRO_8723B); + rxdma_mode &= ~BIT(1); + + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); + rtl8xxxu_write8(priv, REG_RXDMA_PRO_8723B, rxdma_mode); +} + +static void rtl8188fu_init_statistics(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + /* Time duration for NHM unit: 4us, 0xc350=200ms */ + rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350); + rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff); + rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50); + rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff); + + /* TH8 */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 |= 0xff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Enable CCK */ + val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B); + val32 &= ~(BIT(8) | BIT(9) | BIT(10)); + val32 |= BIT(8); + rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32); + + /* Max power amongst all RX antennas */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC); + val32 |= BIT(7); + rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); +} + +#define TX_POWER_INDEX_MAX 0x3F +#define TX_POWER_INDEX_DEFAULT_CCK 0x22 +#define TX_POWER_INDEX_DEFAULT_HT40 0x27 + +static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8188fu_efuse *efuse = &priv->efuse_wifi.efuse8188fu; + int i; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + + for (i = 0; i < ARRAY_SIZE(priv->cck_tx_power_index_A); i++) { + if (priv->cck_tx_power_index_A[i] > TX_POWER_INDEX_MAX) + priv->cck_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_CCK; + } + + for (i = 0; i < ARRAY_SIZE(priv->ht40_1s_tx_power_index_A); i++) { + if (priv->ht40_1s_tx_power_index_A[i] > TX_POWER_INDEX_MAX) + priv->ht40_1s_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_HT40; + } + + priv->ofdm_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; + priv->ht20_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + + priv->default_crystal_cap = efuse->xtal_k & 0x3f; + + return 0; +} + +static int rtl8188fu_load_firmware(struct rtl8xxxu_priv *priv) +{ + const char *fw_name; + int ret; + + fw_name = "rtlwifi/rtl8188fufw.bin"; + + ret = rtl8xxxu_load_firmware(priv, fw_name); + + return ret; +} + +static void rtl8188fu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + /* Enable BB and RF */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* + * Per vendor driver, run power sequence before init of RF + */ + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + usleep_range(10, 20); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_IQADJ_G1, 0x780); + + val8 = SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_USBA | SYS_FUNC_USBD; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + rtl8xxxu_init_phy_regs(priv, rtl8188fu_phy_init_table); + rtl8xxxu_init_phy_regs(priv, rtl8188f_agc_table); +} + +static int rtl8188fu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + int ret; + + if (priv->chip_cut == 1) + ret = rtl8xxxu_init_phy_rf(priv, rtl8188fu_cut_b_radioa_init_table, RF_A); + else + ret = rtl8xxxu_init_phy_rf(priv, rtl8188fu_radioa_init_table, RF_A); + + return ret; +} + +void rtl8188f_phy_lc_calibrate(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u32 rf_amode, lstf; + int i; + + /* Check continuous TX and Packet TX */ + lstf = rtl8xxxu_read32(priv, REG_OFDM1_LSTF); + + if (lstf & OFDM_LSTF_MASK) { + /* Disable all continuous TX */ + val32 = lstf & ~OFDM_LSTF_MASK; + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32); + } else { + /* Deal with Packet TX case */ + /* block all queues */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + } + + /* Read original RF mode Path A */ + rf_amode = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + + /* Start LC calibration */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, rf_amode | 0x08000); + + for (i = 0; i < 100; i++) { + if ((rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG) & 0x08000) == 0) + break; + msleep(10); + } + + if (i == 100) + dev_warn(&priv->udev->dev, "LC calibration timed out.\n"); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, rf_amode); + + /* Restore original parameters */ + if (lstf & OFDM_LSTF_MASK) + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, lstf); + else /* Deal with Packet TX case */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static int rtl8188fu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result) +{ + u32 reg_eac, reg_e94, reg_e9c, val32; + int result = 0; + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Enable path A PA in TX IQK mode + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7); + + /* PA,PAD gain adjust */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a); + + /* enter IQK mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ff); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(25); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); + + /* save LOK result */ + *lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + + return result; +} + +static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32; + int result = 0; + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Enable path A PA in TX IQK mode + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); + + /* PA,PAD gain adjust */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Tx IQK setting + */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x30008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160fff); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(25); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else /* If TX not OK, ignore RX */ + goto out; + + val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) | + ((reg_e9c & 0x3ff0000) >> 16); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* + * Modify RX IQK mode table + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); + + /* + * PA, PAD setting + */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x51000); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * RX IQK setting + */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x30008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x10008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281613ff); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(25); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); + + /* reload LOK value */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000)) + result |= 0x02; + +out: + return result; +} + +static void rtl8188fu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32, rx_initial_gain, lok_result; + u32 path_sel_bb, path_sel_rf; + int path_a_ok; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE + }; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + rx_initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + if (t == 0) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1); + priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI); + } + + /* save RF path */ + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1); + + /* BB setting */ + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x25204000); + + /* MAC settings */ + val32 = rtl8xxxu_read32(priv, REG_TX_PTCL_CTRL); + val32 |= 0x00ff0000; + rtl8xxxu_write32(priv, REG_TX_PTCL_CTRL, val32); + + /* IQ calibration setting */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0xff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8188fu_iqk_path_a(priv, &lok_result); + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0xff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + break; + } + } + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8188fu_rx_iqk_path_a(priv, lok_result); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A IQK failed!\n", __func__); + + /* Back to BB mode, load original value */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0xff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + if (t == 0) + return; + + if (!priv->pi_enabled) { + /* + * Switch back BB to SI mode after finishing + * IQ Calibration + */ + val32 = 0x01000000; + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, val32); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, val32); + } + + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Reload RF path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf); + + /* Restore RX initial gain */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + val32 &= 0xffffff00; + val32 |= 0x50; + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + val32 &= 0xffffff00; + val32 |= rx_initial_gain & 0xff; + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); +} + +static void rtl8188fu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok; + u32 reg_e94, reg_e9c, reg_ea4, reg_eac; + u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + s32 reg_tmp = 0; + bool simu; + u32 path_sel_bb, path_sel_rf; + + /* Save RF path */ + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1); + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + + for (i = 0; i < 3; i++) { + rtl8188fu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2); + if (simu) { + candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp) + candidate = 3; + else + candidate = -1; + } + } + } + + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + priv->rege94 = reg_e94; + reg_e9c = result[candidate][1]; + priv->rege9c = reg_e9c; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + priv->regeb4 = reg_eb4; + reg_ebc = result[candidate][5]; + priv->regebc = reg_ebc; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, + "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", + __func__, reg_e94, reg_e9c, + reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); + path_a_ok = true; + } else { + reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; + reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; + } + + if (reg_e94 && candidate >= 0) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf); +} + +static void rtl8188f_disabled_to_emu(struct rtl8xxxu_priv *priv) +{ + u16 val8; + + /* 0x04[12:11] = 2b'01enable WL suspend */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~((APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND) >> 8); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode */ + val8 = rtl8xxxu_read8(priv, 0xc4); + val8 &= ~BIT(4); + rtl8xxxu_write8(priv, 0xc4, val8); +} + +static int rtl8188f_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* Disable SW LPS */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(APS_FSMCO_SW_LPS >> 8); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* wait till 0x04[17] = 1 power ready */ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* Disable HWPDN */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(APS_FSMCO_HW_POWERDOWN >> 8); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* Disable WL suspend */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(APS_FSMCO_HW_SUSPEND >> 8); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* set, then poll until 0 */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= APS_FSMCO_MAC_ENABLE >> 8; + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* 0x27<=35 to reduce RF noise */ + val8 = rtl8xxxu_write8(priv, 0x27, 0x35); +exit: + return ret; +} + +static int rtl8188fu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0); + + /* 0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */ + val8 = rtl8xxxu_read8(priv, 0x4e); + val8 &= ~BIT(7); + rtl8xxxu_write8(priv, 0x4e, val8); + + /* 0x27 <= 34, xtal_qsel = 0 to xtal bring up */ + rtl8xxxu_write8(priv, 0x27, 0x34); + + /* 0x04[9] = 1 turn off MAC by HW state machine */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= APS_FSMCO_MAC_OFF >> 8; + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_OFF) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + +exit: + return ret; +} + +static int rtl8188fu_emu_to_disabled(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* 0x04[12:11] = 2b'01 enable WL suspend */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~((APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND) >> 8); + val8 |= APS_FSMCO_HW_SUSPEND >> 8; + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode */ + val8 = rtl8xxxu_read8(priv, 0xc4); + val8 |= BIT(4); + rtl8xxxu_write8(priv, 0xc4, val8); + + return 0; +} + +static int rtl8188fu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u8 val8; + u16 val16; + u32 val32; + int retry, retval; + + /* set RPWM IMR */ + val8 = rtl8xxxu_read8(priv, REG_FTIMR + 1); + val8 |= IMR0_CPWM >> 8; + rtl8xxxu_write8(priv, REG_FTIMR + 1, val8); + + /* Tx Pause */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + retry = 100; + retval = -EBUSY; + + /* + * Poll 32 bit wide REG_SCH_TX_CMD for 0x00000000 to ensure no TX is pending. + */ + do { + val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); + if (!val32) { + retval = 0; + break; + } + } while (retry--); + + if (!retry) { + dev_warn(dev, "Failed to flush TX queue\n"); + retval = -EBUSY; + goto out; + } + + /* Disable CCK and OFDM, clock gated */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + udelay(2); + + /* Whole BB is reset */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BB_GLB_RSTN; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + /* Reset MAC TRX */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= 0x3f; + val16 &= ~(CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | CR_SECURITY_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + /* Respond TxOK to scheduler */ + val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); + val8 |= DUAL_TSF_TX_OK; + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); + +out: + return retval; +} + +static int rtl8188fu_power_on(struct rtl8xxxu_priv *priv) +{ + u16 val16; + int ret; + + rtl8188f_disabled_to_emu(priv); + + ret = rtl8188f_emu_to_active(priv); + if (ret) + goto exit; + + rtl8xxxu_write8(priv, REG_CR, 0); + + val16 = rtl8xxxu_read16(priv, REG_CR); + + val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + +exit: + return ret; +} + +static void rtl8188fu_power_off(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + rtl8xxxu_flush_fifo(priv); + + val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG); + val16 &= ~BIT(12); + rtl8xxxu_write16(priv, REG_GPIO_MUXCFG, val16); + + rtl8xxxu_write32(priv, REG_HISR0, 0xFFFFFFFF); + rtl8xxxu_write32(priv, REG_HISR1, 0xFFFFFFFF); + + /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ + val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); + val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + rtl8188fu_active_to_lps(priv); + + /* Reset MCU */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8188fu_active_to_emu(priv); + rtl8188fu_emu_to_disabled(priv); +} + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8188F 0xee +#define PPG_BB_GAIN_2G_TX_OFFSET_MASK 0x0f + +static void rtl8188f_enable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u8 pg_pwrtrim = 0xff, val8; + s8 bb_gain; + + /* Somehow this is not found in the efuse we read earlier. */ + rtl8xxxu_read_efuse8(priv, PPG_BB_GAIN_2G_TXA_OFFSET_8188F, &pg_pwrtrim); + + if (pg_pwrtrim != 0xff) { + bb_gain = pg_pwrtrim & PPG_BB_GAIN_2G_TX_OFFSET_MASK; + + if (bb_gain == PPG_BB_GAIN_2G_TX_OFFSET_MASK) + bb_gain = 0; + else if (bb_gain & 1) + bb_gain = bb_gain >> 1; + else + bb_gain = -(bb_gain >> 1); + + val8 = abs(bb_gain); + if (bb_gain > 0) + val8 |= BIT(5); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55); + val32 &= ~0xfc000; + val32 |= val8 << 14; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55, val32); + } + + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); + val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_TX_A; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static void rtl8188f_disable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + /* Power down RF module */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); +} + +static void rtl8188f_usb_quirks(struct rtl8xxxu_priv *priv) +{ + u16 val16; + u32 val32; + + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + val32 = rtl8xxxu_read32(priv, REG_TXDMA_OFFSET_CHK); + val32 |= TXDMA_OFFSET_DROP_DATA_EN; + rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32); +} + +#define XTAL1 GENMASK(22, 17) +#define XTAL0 GENMASK(16, 11) + +void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + u32 val32; + + if (crystal_cap == cfo->crystal_cap) + return; + + val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL); + + dev_dbg(&priv->udev->dev, + "%s: Adjusting crystal cap from 0x%x (actually 0x%lx 0x%lx) to 0x%x\n", + __func__, + cfo->crystal_cap, + FIELD_GET(XTAL1, val32), + FIELD_GET(XTAL0, val32), + crystal_cap); + + val32 &= ~(XTAL1 | XTAL0); + val32 |= FIELD_PREP(XTAL1, crystal_cap) | + FIELD_PREP(XTAL0, crystal_cap); + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32); + + cfo->crystal_cap = crystal_cap; +} + +static s8 rtl8188f_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; + s8 rx_pwr_all = 0x00; + u8 vga_idx, lna_idx; + + lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); + vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); + + switch (lna_idx) { + case 7: + if (vga_idx <= 27) + rx_pwr_all = -100 + 2 * (27 - vga_idx); + else + rx_pwr_all = -100; + break; + case 5: + rx_pwr_all = -74 + 2 * (21 - vga_idx); + break; + case 3: + rx_pwr_all = -60 + 2 * (20 - vga_idx); + break; + case 1: + rx_pwr_all = -44 + 2 * (19 - vga_idx); + break; + default: + break; + } + + return rx_pwr_all; +} + +struct rtl8xxxu_fileops rtl8188fu_fops = { + .identify_chip = rtl8188fu_identify_chip, + .parse_efuse = rtl8188fu_parse_efuse, + .load_firmware = rtl8188fu_load_firmware, + .power_on = rtl8188fu_power_on, + .power_off = rtl8188fu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8xxxu_reset_8051, + .llt_init = rtl8xxxu_auto_llt_table, + .init_phy_bb = rtl8188fu_init_phy_bb, + .init_phy_rf = rtl8188fu_init_phy_rf, + .phy_init_antenna_selection = rtl8723bu_phy_init_antenna_selection, + .phy_lc_calibrate = rtl8188f_phy_lc_calibrate, + .phy_iq_calibrate = rtl8188fu_phy_iq_calibrate, + .config_channel = rtl8188fu_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc24, + .parse_phystats = rtl8723au_rx_parse_phystats, + .init_aggregation = rtl8188fu_init_aggregation, + .init_statistics = rtl8188fu_init_statistics, + .init_burst = rtl8xxxu_init_burst, + .enable_rf = rtl8188f_enable_rf, + .disable_rf = rtl8188f_disable_rf, + .usb_quirks = rtl8188f_usb_quirks, + .set_tx_power = rtl8188f_set_tx_power, + .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8xxxu_gen2_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v2, + .set_crystal_cap = rtl8188f_set_crystal_cap, + .cck_rssi = rtl8188f_cck_rssi, + .writeN_block_size = 128, + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), + .has_s0s1 = 1, + .has_tx_report = 1, + .gen2_thermal_meter = 1, + .needs_full_init = 1, + .init_reg_rxfltmap = 1, + .init_reg_pkt_life_time = 1, + .init_reg_hmtfr = 1, + .hw_feature_report = 1, + .ampdu_max_time = 0x70, + .ustime_tsf_edca = 0x28, + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 16, + .max_sec_cam_num = 16, + .supports_concurrent = 1, + .adda_1t_init = 0x03c00014, + .adda_1t_path_on = 0x03c00014, + .trxff_boundary = 0x3f7f, + .pbp_rx = PBP_PAGE_SIZE_256, + .pbp_tx = PBP_PAGE_SIZE_256, + .mactable = rtl8188f_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8188F, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8188F, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8188F, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8188F, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/8192c.c new file mode 100644 index 000000000..508322a8f --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8192c.c @@ -0,0 +1,742 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8188c/8188r/8192c specific subdriver + * + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +#ifdef CONFIG_RTL8XXXU_UNTESTED +static struct rtl8xxxu_power_base rtl8192c_power_base = { + .reg_0e00 = 0x07090c0c, + .reg_0e04 = 0x01020405, + .reg_0e08 = 0x00000000, + .reg_086c = 0x00000000, + + .reg_0e10 = 0x0b0c0c0e, + .reg_0e14 = 0x01030506, + .reg_0e18 = 0x0b0c0d0e, + .reg_0e1c = 0x01030509, + + .reg_0830 = 0x07090c0c, + .reg_0834 = 0x01020405, + .reg_0838 = 0x00000000, + .reg_086c_2 = 0x00000000, + + .reg_083c = 0x0b0c0d0e, + .reg_0848 = 0x01030509, + .reg_084c = 0x0b0c0d0e, + .reg_0868 = 0x01030509, +}; + +static struct rtl8xxxu_power_base rtl8188r_power_base = { + .reg_0e00 = 0x06080808, + .reg_0e04 = 0x00040406, + .reg_0e08 = 0x00000000, + .reg_086c = 0x00000000, + + .reg_0e10 = 0x04060608, + .reg_0e14 = 0x00020204, + .reg_0e18 = 0x04060608, + .reg_0e1c = 0x00020204, + + .reg_0830 = 0x06080808, + .reg_0834 = 0x00040406, + .reg_0838 = 0x00000000, + .reg_086c_2 = 0x00000000, + + .reg_083c = 0x04060608, + .reg_0848 = 0x00020204, + .reg_084c = 0x04060608, + .reg_0868 = 0x00020204, +}; + +static const struct rtl8xxxu_reg8val rtl8192cu_mac_init_table[] = { + {0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00}, + {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, + {0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00}, + {0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05}, + {0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01}, + {0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f}, + {0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72}, + {0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08}, + {0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, + {0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, + {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, + {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, + {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, + {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, + {0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16}, + {0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00}, + {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02}, + {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, + {0x652, 0x20}, {0x652, 0x20}, {0x63c, 0x08}, {0x63d, 0x08}, + {0x63e, 0x0c}, {0x63f, 0x0c}, {0x66e, 0x05}, {0x700, 0x21}, + {0x701, 0x43}, {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, + {0x709, 0x43}, {0x70a, 0x65}, {0x70b, 0x87}, + {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_rfregval rtl8192cu_radioa_2t_init_table[] = { + {0x00, 0x00030159}, {0x01, 0x00031284}, + {0x02, 0x00098000}, {0x03, 0x00018c63}, + {0x04, 0x000210e7}, {0x09, 0x0002044f}, + {0x0a, 0x0001adb1}, {0x0b, 0x00054867}, + {0x0c, 0x0008992e}, {0x0d, 0x0000e52c}, + {0x0e, 0x00039ce7}, {0x0f, 0x00000451}, + {0x19, 0x00000000}, {0x1a, 0x00010255}, + {0x1b, 0x00060a00}, {0x1c, 0x000fc378}, + {0x1d, 0x000a1250}, {0x1e, 0x0004445f}, + {0x1f, 0x00080001}, {0x20, 0x0000b614}, + {0x21, 0x0006c000}, {0x22, 0x00000000}, + {0x23, 0x00001558}, {0x24, 0x00000060}, + {0x25, 0x00000483}, {0x26, 0x0004f000}, + {0x27, 0x000ec7d9}, {0x28, 0x000577c0}, + {0x29, 0x00004783}, {0x2a, 0x00000001}, + {0x2b, 0x00021334}, {0x2a, 0x00000000}, + {0x2b, 0x00000054}, {0x2a, 0x00000001}, + {0x2b, 0x00000808}, {0x2b, 0x00053333}, + {0x2c, 0x0000000c}, {0x2a, 0x00000002}, + {0x2b, 0x00000808}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000003}, + {0x2b, 0x00000808}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000004}, + {0x2b, 0x00000808}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000005}, + {0x2b, 0x00000808}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000006}, + {0x2b, 0x00000709}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000007}, + {0x2b, 0x00000709}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000008}, + {0x2b, 0x0000060a}, {0x2b, 0x0004b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000009}, + {0x2b, 0x0000060a}, {0x2b, 0x00053333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000a}, + {0x2b, 0x0000060a}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000b}, + {0x2b, 0x0000060a}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000c}, + {0x2b, 0x0000060a}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000d}, + {0x2b, 0x0000060a}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000e}, + {0x2b, 0x0000050b}, {0x2b, 0x00066666}, + {0x2c, 0x0000001a}, {0x2a, 0x000e0000}, + {0x10, 0x0004000f}, {0x11, 0x000e31fc}, + {0x10, 0x0006000f}, {0x11, 0x000ff9f8}, + {0x10, 0x0002000f}, {0x11, 0x000203f9}, + {0x10, 0x0003000f}, {0x11, 0x000ff500}, + {0x10, 0x00000000}, {0x11, 0x00000000}, + {0x10, 0x0008000f}, {0x11, 0x0003f100}, + {0x10, 0x0009000f}, {0x11, 0x00023100}, + {0x12, 0x00032000}, {0x12, 0x00071000}, + {0x12, 0x000b0000}, {0x12, 0x000fc000}, + {0x13, 0x000287b3}, {0x13, 0x000244b7}, + {0x13, 0x000204ab}, {0x13, 0x0001c49f}, + {0x13, 0x00018493}, {0x13, 0x0001429b}, + {0x13, 0x00010299}, {0x13, 0x0000c29c}, + {0x13, 0x000081a0}, {0x13, 0x000040ac}, + {0x13, 0x00000020}, {0x14, 0x0001944c}, + {0x14, 0x00059444}, {0x14, 0x0009944c}, + {0x14, 0x000d9444}, {0x15, 0x0000f424}, + {0x15, 0x0004f424}, {0x15, 0x0008f424}, + {0x15, 0x000cf424}, {0x16, 0x000e0330}, + {0x16, 0x000a0330}, {0x16, 0x00060330}, + {0x16, 0x00020330}, {0x00, 0x00010159}, + {0x18, 0x0000f401}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0x1f, 0x00080003}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0x1e, 0x00044457}, {0x1f, 0x00080000}, + {0x00, 0x00030159}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192cu_radiob_2t_init_table[] = { + {0x00, 0x00030159}, {0x01, 0x00031284}, + {0x02, 0x00098000}, {0x03, 0x00018c63}, + {0x04, 0x000210e7}, {0x09, 0x0002044f}, + {0x0a, 0x0001adb1}, {0x0b, 0x00054867}, + {0x0c, 0x0008992e}, {0x0d, 0x0000e52c}, + {0x0e, 0x00039ce7}, {0x0f, 0x00000451}, + {0x12, 0x00032000}, {0x12, 0x00071000}, + {0x12, 0x000b0000}, {0x12, 0x000fc000}, + {0x13, 0x000287af}, {0x13, 0x000244b7}, + {0x13, 0x000204ab}, {0x13, 0x0001c49f}, + {0x13, 0x00018493}, {0x13, 0x00014297}, + {0x13, 0x00010295}, {0x13, 0x0000c298}, + {0x13, 0x0000819c}, {0x13, 0x000040a8}, + {0x13, 0x0000001c}, {0x14, 0x0001944c}, + {0x14, 0x00059444}, {0x14, 0x0009944c}, + {0x14, 0x000d9444}, {0x15, 0x0000f424}, + {0x15, 0x0004f424}, {0x15, 0x0008f424}, + {0x15, 0x000cf424}, {0x16, 0x000e0330}, + {0x16, 0x000a0330}, {0x16, 0x00060330}, + {0x16, 0x00020330}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192cu_radioa_1t_init_table[] = { + {0x00, 0x00030159}, {0x01, 0x00031284}, + {0x02, 0x00098000}, {0x03, 0x00018c63}, + {0x04, 0x000210e7}, {0x09, 0x0002044f}, + {0x0a, 0x0001adb1}, {0x0b, 0x00054867}, + {0x0c, 0x0008992e}, {0x0d, 0x0000e52c}, + {0x0e, 0x00039ce7}, {0x0f, 0x00000451}, + {0x19, 0x00000000}, {0x1a, 0x00010255}, + {0x1b, 0x00060a00}, {0x1c, 0x000fc378}, + {0x1d, 0x000a1250}, {0x1e, 0x0004445f}, + {0x1f, 0x00080001}, {0x20, 0x0000b614}, + {0x21, 0x0006c000}, {0x22, 0x00000000}, + {0x23, 0x00001558}, {0x24, 0x00000060}, + {0x25, 0x00000483}, {0x26, 0x0004f000}, + {0x27, 0x000ec7d9}, {0x28, 0x000577c0}, + {0x29, 0x00004783}, {0x2a, 0x00000001}, + {0x2b, 0x00021334}, {0x2a, 0x00000000}, + {0x2b, 0x00000054}, {0x2a, 0x00000001}, + {0x2b, 0x00000808}, {0x2b, 0x00053333}, + {0x2c, 0x0000000c}, {0x2a, 0x00000002}, + {0x2b, 0x00000808}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000003}, + {0x2b, 0x00000808}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000004}, + {0x2b, 0x00000808}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000005}, + {0x2b, 0x00000808}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000006}, + {0x2b, 0x00000709}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000007}, + {0x2b, 0x00000709}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000008}, + {0x2b, 0x0000060a}, {0x2b, 0x0004b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000009}, + {0x2b, 0x0000060a}, {0x2b, 0x00053333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000a}, + {0x2b, 0x0000060a}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000b}, + {0x2b, 0x0000060a}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000c}, + {0x2b, 0x0000060a}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000d}, + {0x2b, 0x0000060a}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000e}, + {0x2b, 0x0000050b}, {0x2b, 0x00066666}, + {0x2c, 0x0000001a}, {0x2a, 0x000e0000}, + {0x10, 0x0004000f}, {0x11, 0x000e31fc}, + {0x10, 0x0006000f}, {0x11, 0x000ff9f8}, + {0x10, 0x0002000f}, {0x11, 0x000203f9}, + {0x10, 0x0003000f}, {0x11, 0x000ff500}, + {0x10, 0x00000000}, {0x11, 0x00000000}, + {0x10, 0x0008000f}, {0x11, 0x0003f100}, + {0x10, 0x0009000f}, {0x11, 0x00023100}, + {0x12, 0x00032000}, {0x12, 0x00071000}, + {0x12, 0x000b0000}, {0x12, 0x000fc000}, + {0x13, 0x000287b3}, {0x13, 0x000244b7}, + {0x13, 0x000204ab}, {0x13, 0x0001c49f}, + {0x13, 0x00018493}, {0x13, 0x0001429b}, + {0x13, 0x00010299}, {0x13, 0x0000c29c}, + {0x13, 0x000081a0}, {0x13, 0x000040ac}, + {0x13, 0x00000020}, {0x14, 0x0001944c}, + {0x14, 0x00059444}, {0x14, 0x0009944c}, + {0x14, 0x000d9444}, {0x15, 0x0000f405}, + {0x15, 0x0004f405}, {0x15, 0x0008f405}, + {0x15, 0x000cf405}, {0x16, 0x000e0330}, + {0x16, 0x000a0330}, {0x16, 0x00060330}, + {0x16, 0x00020330}, {0x00, 0x00010159}, + {0x18, 0x0000f401}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0x1f, 0x00080003}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0x1e, 0x00044457}, {0x1f, 0x00080000}, + {0x00, 0x00030159}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8188ru_radioa_1t_highpa_table[] = { + {0x00, 0x00030159}, {0x01, 0x00031284}, + {0x02, 0x00098000}, {0x03, 0x00018c63}, + {0x04, 0x000210e7}, {0x09, 0x0002044f}, + {0x0a, 0x0001adb0}, {0x0b, 0x00054867}, + {0x0c, 0x0008992e}, {0x0d, 0x0000e529}, + {0x0e, 0x00039ce7}, {0x0f, 0x00000451}, + {0x19, 0x00000000}, {0x1a, 0x00000255}, + {0x1b, 0x00060a00}, {0x1c, 0x000fc378}, + {0x1d, 0x000a1250}, {0x1e, 0x0004445f}, + {0x1f, 0x00080001}, {0x20, 0x0000b614}, + {0x21, 0x0006c000}, {0x22, 0x0000083c}, + {0x23, 0x00001558}, {0x24, 0x00000060}, + {0x25, 0x00000483}, {0x26, 0x0004f000}, + {0x27, 0x000ec7d9}, {0x28, 0x000977c0}, + {0x29, 0x00004783}, {0x2a, 0x00000001}, + {0x2b, 0x00021334}, {0x2a, 0x00000000}, + {0x2b, 0x00000054}, {0x2a, 0x00000001}, + {0x2b, 0x00000808}, {0x2b, 0x00053333}, + {0x2c, 0x0000000c}, {0x2a, 0x00000002}, + {0x2b, 0x00000808}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000003}, + {0x2b, 0x00000808}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000004}, + {0x2b, 0x00000808}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000005}, + {0x2b, 0x00000808}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000006}, + {0x2b, 0x00000709}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000007}, + {0x2b, 0x00000709}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000008}, + {0x2b, 0x0000060a}, {0x2b, 0x0004b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000009}, + {0x2b, 0x0000060a}, {0x2b, 0x00053333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000a}, + {0x2b, 0x0000060a}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000b}, + {0x2b, 0x0000060a}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000c}, + {0x2b, 0x0000060a}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000d}, + {0x2b, 0x0000060a}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000e}, + {0x2b, 0x0000050b}, {0x2b, 0x00066666}, + {0x2c, 0x0000001a}, {0x2a, 0x000e0000}, + {0x10, 0x0004000f}, {0x11, 0x000e31fc}, + {0x10, 0x0006000f}, {0x11, 0x000ff9f8}, + {0x10, 0x0002000f}, {0x11, 0x000203f9}, + {0x10, 0x0003000f}, {0x11, 0x000ff500}, + {0x10, 0x00000000}, {0x11, 0x00000000}, + {0x10, 0x0008000f}, {0x11, 0x0003f100}, + {0x10, 0x0009000f}, {0x11, 0x00023100}, + {0x12, 0x000d8000}, {0x12, 0x00090000}, + {0x12, 0x00051000}, {0x12, 0x00012000}, + {0x13, 0x00028fb4}, {0x13, 0x00024fa8}, + {0x13, 0x000207a4}, {0x13, 0x0001c3b0}, + {0x13, 0x000183a4}, {0x13, 0x00014398}, + {0x13, 0x000101a4}, {0x13, 0x0000c198}, + {0x13, 0x000080a4}, {0x13, 0x00004098}, + {0x13, 0x00000000}, {0x14, 0x0001944c}, + {0x14, 0x00059444}, {0x14, 0x0009944c}, + {0x14, 0x000d9444}, {0x15, 0x0000f405}, + {0x15, 0x0004f405}, {0x15, 0x0008f405}, + {0x15, 0x000cf405}, {0x16, 0x000e0330}, + {0x16, 0x000a0330}, {0x16, 0x00060330}, + {0x16, 0x00020330}, {0x00, 0x00010159}, + {0x18, 0x0000f401}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0x1f, 0x00080003}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0x1e, 0x00044457}, {0x1f, 0x00080000}, + {0x00, 0x00030159}, + {0xff, 0xffffffff} +}; + +static int rtl8192cu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 val32, bonding, sys_cfg, vendor; + int ret = 0; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + ret = -ENOTSUPP; + goto out; + } + + if (sys_cfg & SYS_CFG_TYPE_ID) { + bonding = rtl8xxxu_read32(priv, REG_HPON_FSM); + bonding &= HPON_FSM_BONDING_MASK; + if (bonding == HPON_FSM_BONDING_1T2R) { + strscpy(priv->chip_name, "8191CU", sizeof(priv->chip_name)); + priv->tx_paths = 1; + priv->usb_interrupts = 1; + priv->rtl_chip = RTL8191C; + } else { + strscpy(priv->chip_name, "8192CU", sizeof(priv->chip_name)); + priv->tx_paths = 2; + priv->usb_interrupts = 0; + priv->rtl_chip = RTL8192C; + } + priv->rf_paths = 2; + priv->rx_paths = 2; + } else { + strscpy(priv->chip_name, "8188CU", sizeof(priv->chip_name)); + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + priv->rtl_chip = RTL8188C; + priv->usb_interrupts = 0; + } + priv->has_wifi = 1; + + vendor = sys_cfg & SYS_CFG_VENDOR_ID; + rtl8xxxu_identify_vendor_1bit(priv, vendor); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); + priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); + + rtl8xxxu_config_endpoints_sie(priv); + + /* + * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX + */ + if (!priv->ep_tx_count) + ret = rtl8xxxu_config_endpoints_no_sie(priv); + +out: + return ret; +} + +static int rtl8192cu_load_firmware(struct rtl8xxxu_priv *priv) +{ + const char *fw_name; + int ret; + + if (!priv->vendor_umc) + fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; + else if (priv->chip_cut || priv->rtl_chip == RTL8192C) + fw_name = "rtlwifi/rtl8192cufw_B.bin"; + else + fw_name = "rtlwifi/rtl8192cufw_A.bin"; + + ret = rtl8xxxu_load_firmware(priv, fw_name); + + return ret; +} + +static int rtl8192cu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8192cu_efuse *efuse = &priv->efuse_wifi.efuse8192; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, + efuse->cck_tx_power_index_A, + sizeof(efuse->cck_tx_power_index_A)); + memcpy(priv->cck_tx_power_index_B, + efuse->cck_tx_power_index_B, + sizeof(efuse->cck_tx_power_index_B)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->ht40_1s_tx_power_index_A, + sizeof(efuse->ht40_1s_tx_power_index_A)); + memcpy(priv->ht40_1s_tx_power_index_B, + efuse->ht40_1s_tx_power_index_B, + sizeof(efuse->ht40_1s_tx_power_index_B)); + memcpy(priv->ht40_2s_tx_power_index_diff, + efuse->ht40_2s_tx_power_index_diff, + sizeof(efuse->ht40_2s_tx_power_index_diff)); + + memcpy(priv->ht20_tx_power_index_diff, + efuse->ht20_tx_power_index_diff, + sizeof(efuse->ht20_tx_power_index_diff)); + memcpy(priv->ofdm_tx_power_index_diff, + efuse->ofdm_tx_power_index_diff, + sizeof(efuse->ofdm_tx_power_index_diff)); + + memcpy(priv->ht40_max_power_offset, + efuse->ht40_max_power_offset, + sizeof(efuse->ht40_max_power_offset)); + memcpy(priv->ht20_max_power_offset, + efuse->ht20_max_power_offset, + sizeof(efuse->ht20_max_power_offset)); + + priv->power_base = &rtl8192c_power_base; + + if (efuse->rf_regulatory & 0x20) { + strscpy(priv->chip_name, "8188RU", sizeof(priv->chip_name)); + priv->rtl_chip = RTL8188R; + priv->hi_pa = 1; + priv->no_pape = 1; + priv->power_base = &rtl8188r_power_base; + } + + return 0; +} + +static int rtl8192cu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + const struct rtl8xxxu_rfregval *rftable; + int ret; + + if (priv->rtl_chip == RTL8188R) { + rftable = rtl8188ru_radioa_1t_highpa_table; + ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A); + } else if (priv->rf_paths == 1) { + rftable = rtl8192cu_radioa_1t_init_table; + ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A); + } else { + rftable = rtl8192cu_radioa_2t_init_table; + ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A); + if (ret) + goto exit; + rftable = rtl8192cu_radiob_2t_init_table; + ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_B); + } + +exit: + return ret; +} + +static int rtl8192cu_power_on(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + u32 val32; + int i; + + for (i = 100; i; i--) { + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO); + if (val8 & APS_FSMCO_PFM_ALDN) + break; + } + + if (!i) { + pr_info("%s: Poll failed\n", __func__); + return -ENODEV; + } + + /* + * RSV_CTRL 0x001C[7:0] = 0x00, unlock ISO/CLK/Power control register + */ + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0); + rtl8xxxu_write8(priv, REG_SPS0_CTRL, 0x2b); + udelay(100); + + val8 = rtl8xxxu_read8(priv, REG_LDOV12D_CTRL); + if (!(val8 & LDOV12D_ENABLE)) { + pr_info("%s: Enabling LDOV12D (%02x)\n", __func__, val8); + val8 |= LDOV12D_ENABLE; + rtl8xxxu_write8(priv, REG_LDOV12D_CTRL, val8); + + udelay(100); + + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 &= ~SYS_ISO_MD2PP; + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + } + + /* + * Auto enable WLAN + */ + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 |= APS_FSMCO_MAC_ENABLE; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + for (i = 1000; i; i--) { + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + if (!(val16 & APS_FSMCO_MAC_ENABLE)) + break; + } + if (!i) { + pr_info("%s: FSMCO_MAC_ENABLE poll failed\n", __func__); + return -EBUSY; + } + + /* + * Enable radio, GPIO, LED + */ + val16 = APS_FSMCO_HW_SUSPEND | APS_FSMCO_ENABLE_POWERDOWN | + APS_FSMCO_PFM_ALDN; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + /* + * Release RF digital isolation + */ + val16 = rtl8xxxu_read16(priv, REG_SYS_ISO_CTRL); + val16 &= ~SYS_ISO_DIOR; + rtl8xxxu_write16(priv, REG_SYS_ISO_CTRL, val16); + + val8 = rtl8xxxu_read8(priv, REG_APSD_CTRL); + val8 &= ~APSD_CTRL_OFF; + rtl8xxxu_write8(priv, REG_APSD_CTRL, val8); + for (i = 200; i; i--) { + val8 = rtl8xxxu_read8(priv, REG_APSD_CTRL); + if (!(val8 & APSD_CTRL_OFF_STATUS)) + break; + } + + if (!i) { + pr_info("%s: APSD_CTRL poll failed\n", __func__); + return -EBUSY; + } + + /* + * Enable MAC DMA/WMAC/SCHEDULE/SEC block + */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | CR_PROTOCOL_ENABLE | + CR_SCHEDULE_ENABLE | CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + rtl8xxxu_write8(priv, 0xfe10, 0x19); + + /* + * Workaround for 8188RU LNA power leakage problem. + */ + if (priv->rtl_chip == RTL8188R) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM); + val32 &= ~BIT(1); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32); + } + return 0; +} + +static void rtl8192cu_power_off(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u16 val16; + u8 val8; + int i; + + /* + * Workaround for 8188RU LNA power leakage problem. + */ + if (priv->rtl_chip == RTL8188R) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM); + val32 |= BIT(1); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32); + } + + /* _DisableRFAFEAndResetBB */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, 0xff, 0); + + rtl8xxxu_write8_set(priv, REG_APSD_CTRL, APSD_CTRL_OFF); + rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, FPGA0_RF_PARM_CLK_GATE); + + rtl8xxxu_write8(priv, REG_SYS_FUNC, + SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_BB_GLB_RSTN); + rtl8xxxu_write8(priv, REG_SYS_FUNC, SYS_FUNC_USBA | SYS_FUNC_USBD); + + /* _ResetDigitalProcedure1 */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_DL_READY) { + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8xxxu_write8(priv, REG_FWIMR, 0x20); + + rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20); + + for (i = 0; i < 100; i++) { + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + if (!(val16 & SYS_FUNC_CPU_ENABLE)) + break; + + fsleep(50); + } + + if (i == 100) { + rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, + (SYS_FUNC_HWPDN | SYS_FUNC_ELDR) >> 8); + msleep(10); + } + } + + val8 = (SYS_FUNC_HWPDN | SYS_FUNC_ELDR | SYS_FUNC_CPU_ENABLE) >> 8; + rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8); + + /* _DisableGPIO */ + rtl8xxxu_write16(priv, REG_GPIO_PIN_CTRL + 2, 0); + val32 = rtl8xxxu_read32(priv, REG_GPIO_PIN_CTRL) & 0xffff00ff; + val32 |= (val32 & 0xff) << 8; + val32 |= 0x00ff0000; + rtl8xxxu_write32(priv, REG_GPIO_PIN_CTRL, val32); + + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG + 3, 0); + val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG + 2) & 0xff0f; + val16 |= (val16 & 0xf) << 4; + val16 |= 0x0780; + rtl8xxxu_write16(priv, REG_GPIO_MUXCFG + 2, val16); + + /* _DisableAnalog */ + val8 = 0x23; + if (priv->vendor_umc && priv->chip_cut == 1) + val8 |= BIT(3); + rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8); + + val16 = APS_FSMCO_HOST | APS_FSMCO_HW_SUSPEND | APS_FSMCO_PFM_ALDN; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); +} + +static int rtl8192cu_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG0); + + if (brightness == LED_OFF) + ledcfg = LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE; + else if (brightness == LED_ON) + ledcfg = LEDCFG2_SW_LED_CONTROL; + else if (brightness == RTL8XXXU_HW_LED_CONTROL) + ledcfg = LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE; + + rtl8xxxu_write8(priv, REG_LEDCFG0, ledcfg); + + return 0; +} + +struct rtl8xxxu_fileops rtl8192cu_fops = { + .identify_chip = rtl8192cu_identify_chip, + .parse_efuse = rtl8192cu_parse_efuse, + .load_firmware = rtl8192cu_load_firmware, + .power_on = rtl8192cu_power_on, + .power_off = rtl8192cu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8xxxu_reset_8051, + .llt_init = rtl8xxxu_init_llt_table, + .init_phy_bb = rtl8xxxu_gen1_init_phy_bb, + .init_phy_rf = rtl8192cu_init_phy_rf, + .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, + .phy_iq_calibrate = rtl8xxxu_gen1_phy_iq_calibrate, + .config_channel = rtl8xxxu_gen1_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc16, + .parse_phystats = rtl8723au_rx_parse_phystats, + .init_aggregation = rtl8xxxu_gen1_init_aggregation, + .enable_rf = rtl8xxxu_gen1_enable_rf, + .disable_rf = rtl8xxxu_gen1_disable_rf, + .usb_quirks = rtl8xxxu_gen1_usb_quirks, + .set_tx_power = rtl8xxxu_gen1_set_tx_power, + .update_rate_mask = rtl8xxxu_update_rate_mask, + .report_connect = rtl8xxxu_gen1_report_connect, + .report_rssi = rtl8xxxu_gen1_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v1, + .cck_rssi = rtl8723a_cck_rssi, + .led_classdev_brightness_set = rtl8192cu_led_brightness_set, + .writeN_block_size = 128, + .rx_agg_buf_size = 16000, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), + .supports_ap = 1, + .hw_feature_report = 0, + .max_macid_num = 32, + .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + .adda_2t_path_on_a = 0x04db25a4, + .adda_2t_path_on_b = 0x0b1b25a4, + .trxff_boundary = 0x27ff, + .pbp_rx = PBP_PAGE_SIZE_128, + .pbp_tx = PBP_PAGE_SIZE_128, + .mactable = rtl8192cu_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM, + .page_num_hi = TX_PAGE_NUM_HI_PQ, + .page_num_lo = TX_PAGE_NUM_LO_PQ, + .page_num_norm = TX_PAGE_NUM_NORM_PQ, +}; +#endif diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/8192e.c new file mode 100644 index 000000000..690ace303 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8192e.c @@ -0,0 +1,1768 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8192e specific subdriver + * + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8192e_mac_init_table[] = { + {0x011, 0xeb}, {0x012, 0x07}, {0x014, 0x75}, {0x303, 0xa7}, + {0x428, 0x0a}, {0x429, 0x10}, {0x430, 0x00}, {0x431, 0x00}, + {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, + {0x436, 0x07}, {0x437, 0x08}, {0x43c, 0x04}, {0x43d, 0x05}, + {0x43e, 0x07}, {0x43f, 0x08}, {0x440, 0x5d}, {0x441, 0x01}, + {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, {0x446, 0x00}, + {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xf0}, {0x44a, 0x0f}, + {0x44b, 0x3e}, {0x44c, 0x10}, {0x44d, 0x00}, {0x44e, 0x00}, + {0x44f, 0x00}, {0x450, 0x00}, {0x451, 0xf0}, {0x452, 0x0f}, + {0x453, 0x00}, {0x456, 0x5e}, {0x460, 0x66}, {0x461, 0x66}, + {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, {0x4cd, 0xff}, + {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, {0x502, 0x2f}, + {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, {0x506, 0x5e}, + {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, {0x50a, 0x5e}, + {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, {0x50e, 0x00}, + {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, {0x516, 0x0a}, + {0x525, 0x4f}, {0x540, 0x12}, {0x541, 0x64}, {0x550, 0x10}, + {0x551, 0x10}, {0x559, 0x02}, {0x55c, 0x50}, {0x55d, 0xff}, + {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, {0x620, 0xff}, + {0x621, 0xff}, {0x622, 0xff}, {0x623, 0xff}, {0x624, 0xff}, + {0x625, 0xff}, {0x626, 0xff}, {0x627, 0xff}, {0x638, 0x50}, + {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e}, {0x63f, 0x0e}, + {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xc8}, + {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, + {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70a, 0x65}, + {0x70b, 0x87}, + {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_reg32val rtl8192eu_phy_init_table[] = { + {0x800, 0x80040000}, {0x804, 0x00000003}, + {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, + {0x810, 0x10001331}, {0x814, 0x020c3d10}, + {0x818, 0x02220385}, {0x81c, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x01000100}, {0x82c, 0x00390204}, + {0x830, 0x32323232}, {0x834, 0x30303030}, + {0x838, 0x30303030}, {0x83c, 0x30303030}, + {0x840, 0x00010000}, {0x844, 0x00010000}, + {0x848, 0x28282828}, {0x84c, 0x28282828}, + {0x850, 0x00000000}, {0x854, 0x00000000}, + {0x858, 0x009a009a}, {0x85c, 0x01000014}, + {0x860, 0x66f60000}, {0x864, 0x061f0000}, + {0x868, 0x30303030}, {0x86c, 0x30303030}, + {0x870, 0x00000000}, {0x874, 0x55004200}, + {0x878, 0x08080808}, {0x87c, 0x00000000}, + {0x880, 0xb0000c1c}, {0x884, 0x00000001}, + {0x888, 0x00000000}, {0x88c, 0xcc0000c0}, + {0x890, 0x00000800}, {0x894, 0xfffffffe}, + {0x898, 0x40302010}, {0x900, 0x00000000}, + {0x904, 0x00000023}, {0x908, 0x00000000}, + {0x90c, 0x81121313}, {0x910, 0x806c0001}, + {0x914, 0x00000001}, {0x918, 0x00000000}, + {0x91c, 0x00010000}, {0x924, 0x00000001}, + {0x928, 0x00000000}, {0x92c, 0x00000000}, + {0x930, 0x00000000}, {0x934, 0x00000000}, + {0x938, 0x00000000}, {0x93c, 0x00000000}, + {0x940, 0x00000000}, {0x944, 0x00000000}, + {0x94c, 0x00000008}, {0xa00, 0x00d0c7c8}, + {0xa04, 0x81ff000c}, {0xa08, 0x8c838300}, + {0xa0c, 0x2e68120f}, {0xa10, 0x95009b78}, + {0xa14, 0x1114d028}, {0xa18, 0x00881117}, + {0xa1c, 0x89140f00}, {0xa20, 0x1a1b0000}, + {0xa24, 0x090e1317}, {0xa28, 0x00000204}, + {0xa2c, 0x00d30000}, {0xa70, 0x101fff00}, + {0xa74, 0x00000007}, {0xa78, 0x00000900}, + {0xa7c, 0x225b0606}, {0xa80, 0x218075b1}, + {0xb38, 0x00000000}, {0xc00, 0x48071d40}, + {0xc04, 0x03a05633}, {0xc08, 0x000000e4}, + {0xc0c, 0x6c6c6c6c}, {0xc10, 0x08800000}, + {0xc14, 0x40000100}, {0xc18, 0x08800000}, + {0xc1c, 0x40000100}, {0xc20, 0x00000000}, + {0xc24, 0x00000000}, {0xc28, 0x00000000}, + {0xc2c, 0x00000000}, {0xc30, 0x69e9ac47}, + {0xc34, 0x469652af}, {0xc38, 0x49795994}, + {0xc3c, 0x0a97971c}, {0xc40, 0x1f7c403f}, + {0xc44, 0x000100b7}, {0xc48, 0xec020107}, + {0xc4c, 0x007f037f}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0xc50, 0x00340220}, +#else + {0xc50, 0x00340020}, +#endif + {0xc54, 0x0080801f}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0xc58, 0x00000220}, +#else + {0xc58, 0x00000020}, +#endif + {0xc5c, 0x00248492}, {0xc60, 0x00000000}, + {0xc64, 0x7112848b}, {0xc68, 0x47c00bff}, + {0xc6c, 0x00000036}, {0xc70, 0x00000600}, + {0xc74, 0x02013169}, {0xc78, 0x0000001f}, + {0xc7c, 0x00b91612}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0xc80, 0x2d4000b5}, +#else + {0xc80, 0x40000100}, +#endif + {0xc84, 0x21f60000}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0xc88, 0x2d4000b5}, +#else + {0xc88, 0x40000100}, +#endif + {0xc8c, 0xa0e40000}, {0xc90, 0x00121820}, + {0xc94, 0x00000000}, {0xc98, 0x00121820}, + {0xc9c, 0x00007f7f}, {0xca0, 0x00000000}, + {0xca4, 0x000300a0}, {0xca8, 0x00000000}, + {0xcac, 0x00000000}, {0xcb0, 0x00000000}, + {0xcb4, 0x00000000}, {0xcb8, 0x00000000}, + {0xcbc, 0x28000000}, {0xcc0, 0x00000000}, + {0xcc4, 0x00000000}, {0xcc8, 0x00000000}, + {0xccc, 0x00000000}, {0xcd0, 0x00000000}, + {0xcd4, 0x00000000}, {0xcd8, 0x64b22427}, + {0xcdc, 0x00766932}, {0xce0, 0x00222222}, + {0xce4, 0x00040000}, {0xce8, 0x77644302}, + {0xcec, 0x2f97d40c}, {0xd00, 0x00080740}, + {0xd04, 0x00020403}, {0xd08, 0x0000907f}, + {0xd0c, 0x20010201}, {0xd10, 0xa0633333}, + {0xd14, 0x3333bc43}, {0xd18, 0x7a8f5b6b}, + {0xd1c, 0x0000007f}, {0xd2c, 0xcc979975}, + {0xd30, 0x00000000}, {0xd34, 0x80608000}, + {0xd38, 0x00000000}, {0xd3c, 0x00127353}, + {0xd40, 0x00000000}, {0xd44, 0x00000000}, + {0xd48, 0x00000000}, {0xd4c, 0x00000000}, + {0xd50, 0x6437140a}, {0xd54, 0x00000000}, + {0xd58, 0x00000282}, {0xd5c, 0x30032064}, + {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, + {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, + {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, + {0xd78, 0x000e3c24}, {0xd80, 0x01081008}, + {0xd84, 0x00000800}, {0xd88, 0xf0b50000}, + {0xe00, 0x30303030}, {0xe04, 0x30303030}, + {0xe08, 0x03903030}, {0xe10, 0x30303030}, + {0xe14, 0x30303030}, {0xe18, 0x30303030}, + {0xe1c, 0x30303030}, {0xe28, 0x00000000}, + {0xe30, 0x1000dc1f}, {0xe34, 0x10008c1f}, + {0xe38, 0x02140102}, {0xe3c, 0x681604c2}, + {0xe40, 0x01007c00}, {0xe44, 0x01004800}, + {0xe48, 0xfb000000}, {0xe4c, 0x000028d1}, + {0xe50, 0x1000dc1f}, {0xe54, 0x10008c1f}, + {0xe58, 0x02140102}, {0xe5c, 0x28160d05}, + {0xe60, 0x00000008}, {0xe68, 0x0fc05656}, + {0xe6c, 0x03c09696}, {0xe70, 0x03c09696}, + {0xe74, 0x0c005656}, {0xe78, 0x0c005656}, + {0xe7c, 0x0c005656}, {0xe80, 0x0c005656}, + {0xe84, 0x03c09696}, {0xe88, 0x0c005656}, + {0xe8c, 0x03c09696}, {0xed0, 0x03c09696}, + {0xed4, 0x03c09696}, {0xed8, 0x03c09696}, + {0xedc, 0x0000d6d6}, {0xee0, 0x0000d6d6}, + {0xeec, 0x0fc01616}, {0xee4, 0xb0000c1c}, + {0xee8, 0x00000001}, {0xf14, 0x00000003}, + {0xf4c, 0x00000000}, {0xf00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8xxx_agc_8192eu_std_table[] = { + {0xc78, 0xfb000001}, {0xc78, 0xfb010001}, + {0xc78, 0xfb020001}, {0xc78, 0xfb030001}, + {0xc78, 0xfb040001}, {0xc78, 0xfb050001}, + {0xc78, 0xfa060001}, {0xc78, 0xf9070001}, + {0xc78, 0xf8080001}, {0xc78, 0xf7090001}, + {0xc78, 0xf60a0001}, {0xc78, 0xf50b0001}, + {0xc78, 0xf40c0001}, {0xc78, 0xf30d0001}, + {0xc78, 0xf20e0001}, {0xc78, 0xf10f0001}, + {0xc78, 0xf0100001}, {0xc78, 0xef110001}, + {0xc78, 0xee120001}, {0xc78, 0xed130001}, + {0xc78, 0xec140001}, {0xc78, 0xeb150001}, + {0xc78, 0xea160001}, {0xc78, 0xe9170001}, + {0xc78, 0xe8180001}, {0xc78, 0xe7190001}, + {0xc78, 0xc81a0001}, {0xc78, 0xc71b0001}, + {0xc78, 0xc61c0001}, {0xc78, 0x071d0001}, + {0xc78, 0x061e0001}, {0xc78, 0x051f0001}, + {0xc78, 0x04200001}, {0xc78, 0x03210001}, + {0xc78, 0xaa220001}, {0xc78, 0xa9230001}, + {0xc78, 0xa8240001}, {0xc78, 0xa7250001}, + {0xc78, 0xa6260001}, {0xc78, 0x85270001}, + {0xc78, 0x84280001}, {0xc78, 0x83290001}, + {0xc78, 0x252a0001}, {0xc78, 0x242b0001}, + {0xc78, 0x232c0001}, {0xc78, 0x222d0001}, + {0xc78, 0x672e0001}, {0xc78, 0x662f0001}, + {0xc78, 0x65300001}, {0xc78, 0x64310001}, + {0xc78, 0x63320001}, {0xc78, 0x62330001}, + {0xc78, 0x61340001}, {0xc78, 0x45350001}, + {0xc78, 0x44360001}, {0xc78, 0x43370001}, + {0xc78, 0x42380001}, {0xc78, 0x41390001}, + {0xc78, 0x403a0001}, {0xc78, 0x403b0001}, + {0xc78, 0x403c0001}, {0xc78, 0x403d0001}, + {0xc78, 0x403e0001}, {0xc78, 0x403f0001}, + {0xc78, 0xfb400001}, {0xc78, 0xfb410001}, + {0xc78, 0xfb420001}, {0xc78, 0xfb430001}, + {0xc78, 0xfb440001}, {0xc78, 0xfb450001}, + {0xc78, 0xfa460001}, {0xc78, 0xf9470001}, + {0xc78, 0xf8480001}, {0xc78, 0xf7490001}, + {0xc78, 0xf64a0001}, {0xc78, 0xf54b0001}, + {0xc78, 0xf44c0001}, {0xc78, 0xf34d0001}, + {0xc78, 0xf24e0001}, {0xc78, 0xf14f0001}, + {0xc78, 0xf0500001}, {0xc78, 0xef510001}, + {0xc78, 0xee520001}, {0xc78, 0xed530001}, + {0xc78, 0xec540001}, {0xc78, 0xeb550001}, + {0xc78, 0xea560001}, {0xc78, 0xe9570001}, + {0xc78, 0xe8580001}, {0xc78, 0xe7590001}, + {0xc78, 0xe65a0001}, {0xc78, 0xe55b0001}, + {0xc78, 0xe45c0001}, {0xc78, 0xe35d0001}, + {0xc78, 0xe25e0001}, {0xc78, 0xe15f0001}, + {0xc78, 0x8a600001}, {0xc78, 0x89610001}, + {0xc78, 0x88620001}, {0xc78, 0x87630001}, + {0xc78, 0x86640001}, {0xc78, 0x85650001}, + {0xc78, 0x84660001}, {0xc78, 0x83670001}, + {0xc78, 0x82680001}, {0xc78, 0x6b690001}, + {0xc78, 0x6a6a0001}, {0xc78, 0x696b0001}, + {0xc78, 0x686c0001}, {0xc78, 0x676d0001}, + {0xc78, 0x666e0001}, {0xc78, 0x656f0001}, + {0xc78, 0x64700001}, {0xc78, 0x63710001}, + {0xc78, 0x62720001}, {0xc78, 0x61730001}, + {0xc78, 0x49740001}, {0xc78, 0x48750001}, + {0xc78, 0x47760001}, {0xc78, 0x46770001}, + {0xc78, 0x45780001}, {0xc78, 0x44790001}, + {0xc78, 0x437a0001}, {0xc78, 0x427b0001}, + {0xc78, 0x417c0001}, {0xc78, 0x407d0001}, + {0xc78, 0x407e0001}, {0xc78, 0x407f0001}, + {0xc50, 0x00040022}, {0xc50, 0x00040020}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_reg32val rtl8xxx_agc_8192eu_highpa_table[] = { + {0xc78, 0xfa000001}, {0xc78, 0xf9010001}, + {0xc78, 0xf8020001}, {0xc78, 0xf7030001}, + {0xc78, 0xf6040001}, {0xc78, 0xf5050001}, + {0xc78, 0xf4060001}, {0xc78, 0xf3070001}, + {0xc78, 0xf2080001}, {0xc78, 0xf1090001}, + {0xc78, 0xf00a0001}, {0xc78, 0xef0b0001}, + {0xc78, 0xee0c0001}, {0xc78, 0xed0d0001}, + {0xc78, 0xec0e0001}, {0xc78, 0xeb0f0001}, + {0xc78, 0xea100001}, {0xc78, 0xe9110001}, + {0xc78, 0xe8120001}, {0xc78, 0xe7130001}, + {0xc78, 0xe6140001}, {0xc78, 0xe5150001}, + {0xc78, 0xe4160001}, {0xc78, 0xe3170001}, + {0xc78, 0xe2180001}, {0xc78, 0xe1190001}, + {0xc78, 0x8a1a0001}, {0xc78, 0x891b0001}, + {0xc78, 0x881c0001}, {0xc78, 0x871d0001}, + {0xc78, 0x861e0001}, {0xc78, 0x851f0001}, + {0xc78, 0x84200001}, {0xc78, 0x83210001}, + {0xc78, 0x82220001}, {0xc78, 0x6a230001}, + {0xc78, 0x69240001}, {0xc78, 0x68250001}, + {0xc78, 0x67260001}, {0xc78, 0x66270001}, + {0xc78, 0x65280001}, {0xc78, 0x64290001}, + {0xc78, 0x632a0001}, {0xc78, 0x622b0001}, + {0xc78, 0x612c0001}, {0xc78, 0x602d0001}, + {0xc78, 0x472e0001}, {0xc78, 0x462f0001}, + {0xc78, 0x45300001}, {0xc78, 0x44310001}, + {0xc78, 0x43320001}, {0xc78, 0x42330001}, + {0xc78, 0x41340001}, {0xc78, 0x40350001}, + {0xc78, 0x40360001}, {0xc78, 0x40370001}, + {0xc78, 0x40380001}, {0xc78, 0x40390001}, + {0xc78, 0x403a0001}, {0xc78, 0x403b0001}, + {0xc78, 0x403c0001}, {0xc78, 0x403d0001}, + {0xc78, 0x403e0001}, {0xc78, 0x403f0001}, + {0xc78, 0xfa400001}, {0xc78, 0xf9410001}, + {0xc78, 0xf8420001}, {0xc78, 0xf7430001}, + {0xc78, 0xf6440001}, {0xc78, 0xf5450001}, + {0xc78, 0xf4460001}, {0xc78, 0xf3470001}, + {0xc78, 0xf2480001}, {0xc78, 0xf1490001}, + {0xc78, 0xf04a0001}, {0xc78, 0xef4b0001}, + {0xc78, 0xee4c0001}, {0xc78, 0xed4d0001}, + {0xc78, 0xec4e0001}, {0xc78, 0xeb4f0001}, + {0xc78, 0xea500001}, {0xc78, 0xe9510001}, + {0xc78, 0xe8520001}, {0xc78, 0xe7530001}, + {0xc78, 0xe6540001}, {0xc78, 0xe5550001}, + {0xc78, 0xe4560001}, {0xc78, 0xe3570001}, + {0xc78, 0xe2580001}, {0xc78, 0xe1590001}, + {0xc78, 0x8a5a0001}, {0xc78, 0x895b0001}, + {0xc78, 0x885c0001}, {0xc78, 0x875d0001}, + {0xc78, 0x865e0001}, {0xc78, 0x855f0001}, + {0xc78, 0x84600001}, {0xc78, 0x83610001}, + {0xc78, 0x82620001}, {0xc78, 0x6a630001}, + {0xc78, 0x69640001}, {0xc78, 0x68650001}, + {0xc78, 0x67660001}, {0xc78, 0x66670001}, + {0xc78, 0x65680001}, {0xc78, 0x64690001}, + {0xc78, 0x636a0001}, {0xc78, 0x626b0001}, + {0xc78, 0x616c0001}, {0xc78, 0x606d0001}, + {0xc78, 0x476e0001}, {0xc78, 0x466f0001}, + {0xc78, 0x45700001}, {0xc78, 0x44710001}, + {0xc78, 0x43720001}, {0xc78, 0x42730001}, + {0xc78, 0x41740001}, {0xc78, 0x40750001}, + {0xc78, 0x40760001}, {0xc78, 0x40770001}, + {0xc78, 0x40780001}, {0xc78, 0x40790001}, + {0xc78, 0x407a0001}, {0xc78, 0x407b0001}, + {0xc78, 0x407c0001}, {0xc78, 0x407d0001}, + {0xc78, 0x407e0001}, {0xc78, 0x407f0001}, + {0xc50, 0x00040222}, {0xc50, 0x00040220}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192eu_radioa_init_table[] = { + {0x7f, 0x00000082}, {0x81, 0x0003fc00}, + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x18, 0x00000407}, {0x19, 0x00000012}, + {0x1b, 0x00000064}, {0x1e, 0x00080009}, + {0x1f, 0x00000880}, {0x2f, 0x0001a060}, + {0x3f, 0x00000000}, {0x42, 0x000060c0}, + {0x57, 0x000d0000}, {0x58, 0x000be180}, + {0x67, 0x00001552}, {0x83, 0x00000000}, + {0xb0, 0x000ff9f1}, {0xb1, 0x00055418}, + {0xb2, 0x0008cc00}, {0xb4, 0x00043083}, + {0xb5, 0x00008166}, {0xb6, 0x0000803e}, + {0xb7, 0x0001c69f}, {0xb8, 0x0000407f}, + {0xb9, 0x00080001}, {0xba, 0x00040001}, + {0xbb, 0x00000400}, {0xbf, 0x000c0000}, + {0xc2, 0x00002400}, {0xc3, 0x00000009}, + {0xc4, 0x00040c91}, {0xc5, 0x00099999}, + {0xc6, 0x000000a3}, {0xc7, 0x00088820}, + {0xc8, 0x00076c06}, {0xc9, 0x00000000}, + {0xca, 0x00080000}, {0xdf, 0x00000180}, + {0xef, 0x000001a0}, {0x51, 0x00069545}, + {0x52, 0x0007e45e}, {0x53, 0x00000071}, + {0x56, 0x00051ff3}, {0x35, 0x000000a8}, + {0x35, 0x000001e2}, {0x35, 0x000002a8}, + {0x36, 0x00001c24}, {0x36, 0x00009c24}, + {0x36, 0x00011c24}, {0x36, 0x00019c24}, + {0x18, 0x00000c07}, {0x5a, 0x00048000}, + {0x19, 0x000739d0}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x34, 0x0000a093}, {0x34, 0x0000908f}, + {0x34, 0x0000808c}, {0x34, 0x0000704d}, + {0x34, 0x0000604a}, {0x34, 0x00005047}, + {0x34, 0x0000400a}, {0x34, 0x00003007}, + {0x34, 0x00002004}, {0x34, 0x00001001}, + {0x34, 0x00000000}, +#else + /* Regular */ + {0x34, 0x0000add7}, {0x34, 0x00009dd4}, + {0x34, 0x00008dd1}, {0x34, 0x00007dce}, + {0x34, 0x00006dcb}, {0x34, 0x00005dc8}, + {0x34, 0x00004dc5}, {0x34, 0x000034cc}, + {0x34, 0x0000244f}, {0x34, 0x0000144c}, + {0x34, 0x00000014}, +#endif + {0x00, 0x00030159}, + {0x84, 0x00068180}, + {0x86, 0x0000014e}, + {0x87, 0x00048e00}, + {0x8e, 0x00065540}, + {0x8f, 0x00088000}, + {0xef, 0x000020a0}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x3b, 0x000f07b0}, +#else + {0x3b, 0x000f02b0}, +#endif + {0x3b, 0x000ef7b0}, {0x3b, 0x000d4fb0}, + {0x3b, 0x000cf060}, {0x3b, 0x000b0090}, + {0x3b, 0x000a0080}, {0x3b, 0x00090080}, + {0x3b, 0x0008f780}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x3b, 0x000787b0}, +#else + {0x3b, 0x00078730}, +#endif + {0x3b, 0x00060fb0}, {0x3b, 0x0005ffa0}, + {0x3b, 0x00040620}, {0x3b, 0x00037090}, + {0x3b, 0x00020080}, {0x3b, 0x0001f060}, + {0x3b, 0x0000ffb0}, {0xef, 0x000000a0}, + {0xfe, 0x00000000}, {0x18, 0x0000fc07}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0x1e, 0x00000001}, {0x1f, 0x00080000}, + {0x00, 0x00033e70}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192eu_radiob_init_table[] = { + {0x7f, 0x00000082}, {0x81, 0x0003fc00}, + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x18, 0x00000407}, {0x19, 0x00000012}, + {0x1b, 0x00000064}, {0x1e, 0x00080009}, + {0x1f, 0x00000880}, {0x2f, 0x0001a060}, + {0x3f, 0x00000000}, {0x42, 0x000060c0}, + {0x57, 0x000d0000}, {0x58, 0x000be180}, + {0x67, 0x00001552}, {0x7f, 0x00000082}, + {0x81, 0x0003f000}, {0x83, 0x00000000}, + {0xdf, 0x00000180}, {0xef, 0x000001a0}, + {0x51, 0x00069545}, {0x52, 0x0007e42e}, + {0x53, 0x00000071}, {0x56, 0x00051ff3}, + {0x35, 0x000000a8}, {0x35, 0x000001e0}, + {0x35, 0x000002a8}, {0x36, 0x00001ca8}, + {0x36, 0x00009c24}, {0x36, 0x00011c24}, + {0x36, 0x00019c24}, {0x18, 0x00000c07}, + {0x5a, 0x00048000}, {0x19, 0x000739d0}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x34, 0x0000a093}, {0x34, 0x0000908f}, + {0x34, 0x0000808c}, {0x34, 0x0000704d}, + {0x34, 0x0000604a}, {0x34, 0x00005047}, + {0x34, 0x0000400a}, {0x34, 0x00003007}, + {0x34, 0x00002004}, {0x34, 0x00001001}, + {0x34, 0x00000000}, +#else + {0x34, 0x0000add7}, {0x34, 0x00009dd4}, + {0x34, 0x00008dd1}, {0x34, 0x00007dce}, + {0x34, 0x00006dcb}, {0x34, 0x00005dc8}, + {0x34, 0x00004dc5}, {0x34, 0x000034cc}, + {0x34, 0x0000244f}, {0x34, 0x0000144c}, + {0x34, 0x00000014}, +#endif + {0x00, 0x00030159}, {0x84, 0x00068180}, + {0x86, 0x000000ce}, {0x87, 0x00048a00}, + {0x8e, 0x00065540}, {0x8f, 0x00088000}, + {0xef, 0x000020a0}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x3b, 0x000f07b0}, +#else + {0x3b, 0x000f02b0}, +#endif + + {0x3b, 0x000ef7b0}, {0x3b, 0x000d4fb0}, + {0x3b, 0x000cf060}, {0x3b, 0x000b0090}, + {0x3b, 0x000a0080}, {0x3b, 0x00090080}, + {0x3b, 0x0008f780}, +#ifdef EXT_PA_8192EU + /* External PA or external LNA */ + {0x3b, 0x000787b0}, +#else + {0x3b, 0x00078730}, +#endif + {0x3b, 0x00060fb0}, {0x3b, 0x0005ffa0}, + {0x3b, 0x00040620}, {0x3b, 0x00037090}, + {0x3b, 0x00020080}, {0x3b, 0x0001f060}, + {0x3b, 0x0000ffb0}, {0xef, 0x000000a0}, + {0x00, 0x00010159}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0x1e, 0x00000001}, + {0x1f, 0x00080000}, {0x00, 0x00033e70}, + {0xff, 0xffffffff} +}; + +static int rtl8192eu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 val32, bonding, sys_cfg, vendor; + int ret = 0; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + ret = -ENOTSUPP; + goto out; + } + + bonding = rtl8xxxu_read32(priv, REG_HPON_FSM); + bonding &= HPON_FSM_BONDING_MASK; + if (bonding == HPON_FSM_BONDING_1T2R) { + strscpy(priv->chip_name, "8191EU", sizeof(priv->chip_name)); + priv->tx_paths = 1; + priv->rtl_chip = RTL8191E; + } else { + strscpy(priv->chip_name, "8192EU", sizeof(priv->chip_name)); + priv->tx_paths = 2; + priv->rtl_chip = RTL8192E; + } + priv->rf_paths = 2; + priv->rx_paths = 2; + priv->has_wifi = 1; + + vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK; + rtl8xxxu_identify_vendor_2bits(priv, vendor); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); + priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); + + rtl8xxxu_config_endpoints_sie(priv); + + /* + * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX + */ + if (!priv->ep_tx_count) + ret = rtl8xxxu_config_endpoints_no_sie(priv); + +out: + return ret; +} + +static void +rtl8192e_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) +{ + u32 val32, ofdm, mcs; + u8 cck, ofdmbase, mcsbase; + int group, tx_idx; + + tx_idx = 0; + group = rtl8xxxu_gen2_channel_to_group(channel); + + cck = priv->cck_tx_power_index_A[group]; + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); + val32 &= 0xffff00ff; + val32 |= (cck << 8); + rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xff; + val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + ofdmbase = priv->ht40_1s_tx_power_index_A[group]; + ofdmbase += priv->ofdm_tx_power_diff[tx_idx].a; + ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm); + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_A[group]; + if (ht40) + mcsbase += priv->ht40_tx_power_diff[tx_idx++].a; + else + mcsbase += priv->ht20_tx_power_diff[tx_idx++].a; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs); + + if (priv->tx_paths > 1) { + cck = priv->cck_tx_power_index_B[group]; + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK1_55_MCS32); + val32 &= 0xff; + val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK1_55_MCS32, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xffffff00; + val32 |= cck; + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + ofdmbase = priv->ht40_1s_tx_power_index_B[group]; + ofdmbase += priv->ofdm_tx_power_diff[tx_idx].b; + ofdm = ofdmbase | ofdmbase << 8 | + ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE18_06, ofdm); + rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE54_24, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_B[group]; + if (ht40) + mcsbase += priv->ht40_tx_power_diff[tx_idx++].b; + else + mcsbase += priv->ht20_tx_power_diff[tx_idx++].b; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS03_MCS00, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS07_MCS04, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS11_MCS08, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, mcs); + } +} + +static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu; + int i; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + memcpy(priv->cck_tx_power_index_B, efuse->tx_power_index_B.cck_base, + sizeof(efuse->tx_power_index_B.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + memcpy(priv->ht40_1s_tx_power_index_B, + efuse->tx_power_index_B.ht40_base, + sizeof(efuse->tx_power_index_B.ht40_base)); + + priv->ht20_tx_power_diff[0].a = + efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + priv->ht20_tx_power_diff[0].b = + efuse->tx_power_index_B.ht20_ofdm_1s_diff.b; + + priv->ht40_tx_power_diff[0].a = 0; + priv->ht40_tx_power_diff[0].b = 0; + + for (i = 1; i < RTL8723B_TX_COUNT; i++) { + priv->ofdm_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ofdm; + priv->ofdm_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ofdm; + + priv->ht20_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht20; + priv->ht20_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht20; + + priv->ht40_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht40; + priv->ht40_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht40; + } + + priv->default_crystal_cap = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f; + + return 0; +} + +static int rtl8192eu_load_firmware(struct rtl8xxxu_priv *priv) +{ + const char *fw_name; + int ret; + + fw_name = "rtlwifi/rtl8192eu_nic.bin"; + + ret = rtl8xxxu_load_firmware(priv, fw_name); + + return ret; +} + +static void rtl8192eu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* 6. 0x1f[7:0] = 0x07 */ + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= (SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_DIO_RF | + SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB); + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + rtl8xxxu_init_phy_regs(priv, rtl8192eu_phy_init_table); + + if (priv->hi_pa) + rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8192eu_highpa_table); + else + rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8192eu_std_table); +} + +static int rtl8192eu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + int ret; + + ret = rtl8xxxu_init_phy_rf(priv, rtl8192eu_radioa_init_table, RF_A); + if (ret) + goto exit; + + ret = rtl8xxxu_init_phy_rf(priv, rtl8192eu_radiob_init_table, RF_B); + +exit: + return ret; +} + +static int rtl8192eu_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_e94, reg_e9c; + int result = 0; + + /* + * TX IQK + * PA/PAD controlled by 0x0 + */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00180); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07f77); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* Path A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82140303); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x68160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + + return result; +} + +static int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32; + int result = 0; + + /* Leave IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00); + + /* Enable path A PA in TX IQK mode */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); + + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf1173); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x511e0); + + /* Enter IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* TX IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8216031f); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x6816031f); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) { + result |= 0x01; + } else { + /* PA/PAD controlled by 0x0 */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); + goto out; + } + + val32 = 0x80007c00 | + (reg_e94 & 0x03ff0000) | ((reg_e9c >> 16) & 0x03ff); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* Modify RX IQK mode table */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); + + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf7ff2); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x510e0); + + /* Enter IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* IQK setting */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* Path A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821608ff); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281608ff); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a891); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path A RX IQK failed!\n", + __func__); + +out: + return result; +} + +static int rtl8192eu_iqk_path_b(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_eb4, reg_ebc; + int result = 0; + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00180); + + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x20000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0x07f77); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* Path B IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82140303); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x68160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(1); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + + if (!(reg_eac & BIT(31)) && + ((reg_eb4 & 0x03ff0000) != 0x01420000) && + ((reg_ebc & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else + dev_warn(&priv->udev->dev, "%s: Path B IQK failed!\n", + __func__); + + return result; +} + +static int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc, val32; + int result = 0; + + /* Leave IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + + /* Enable path A PA in TX IQK mode */ + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf1173); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x511e0); + + /* Enter IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* TX IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x8216031f); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x6816031f); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + + if (!(reg_eac & BIT(31)) && + ((reg_eb4 & 0x03ff0000) != 0x01420000) && + ((reg_ebc & 0x03ff0000) != 0x00420000)) { + result |= 0x01; + } else { + /* + * PA/PAD controlled by 0x0 + * Vendor driver restores RF_A here which I believe is a bug + */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180); + goto out; + } + + val32 = 0x80007c00 | + (reg_eb4 & 0x03ff0000) | ((reg_ebc >> 16) & 0x03ff); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* Modify RX IQK mode table */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf7ff2); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x510e0); + + /* Enter IQK mode */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* IQK setting */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* Path A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x18008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821608ff); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281608ff); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a891); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); + reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180); + + if (!(reg_eac & BIT(30)) && + ((reg_ec4 & 0x03ff0000) != 0x01320000) && + ((reg_ecc & 0x03ff0000) != 0x00360000)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n", + __func__); + +out: + return result; +} + +static void rtl8192eu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32; + int path_a_ok, path_b_ok; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_CCK0_AFE_SETTING + }; + u8 xa_agc = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1) & 0xff; + u8 xb_agc = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1) & 0xff; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + /* MAC settings */ + rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); + + val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); + val32 |= 0x0f000000; + rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); + + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22208200); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_SW_CTRL); + val32 |= (FPGA0_RF_PAPE | (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT)); + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_RF_INT_OE); + val32 |= BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, val32); + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); + val32 |= BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8192eu_iqk_path_a(priv); + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A TX IQK failed!\n", __func__); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8192eu_rx_iqk_path_a(priv); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A RX IQK failed!\n", __func__); + + if (priv->rf_paths > 1) { + /* Path A into standby */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x10000); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* Turn Path B ADDA on */ + rtl8xxxu_path_adda_on(priv, adda_regs, false); + + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8192eu_iqk_path_b(priv); + if (path_b_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + result[t][4] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + result[t][5] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_b_ok) + dev_dbg(dev, "%s: Path B IQK failed!\n", __func__); + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8192eu_rx_iqk_path_b(priv); + if (path_b_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_B_2); + result[t][6] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_B_2); + result[t][7] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_b_ok) + dev_dbg(dev, "%s: Path B RX IQK failed!\n", __func__); + } + + /* Back to BB mode, load original value */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); + + if (t) { + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Restore RX initial gain */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + val32 &= 0xffffff00; + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | 0x50); + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | xa_agc); + + if (priv->rf_paths > 1) { + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1); + val32 &= 0xffffff00; + rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, + val32 | 0x50); + rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, + val32 | xb_agc); + } + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); + } +} + +static void rtl8192eu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok, path_b_ok; + u32 reg_e94, reg_e9c, reg_ea4, reg_eac; + u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + bool simu; + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + path_b_ok = false; + + for (i = 0; i < 3; i++) { + rtl8192eu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 1, 2); + if (simu) + candidate = 1; + else + candidate = 3; + } + } + + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + priv->rege94 = reg_e94; + reg_e9c = result[candidate][1]; + priv->rege9c = reg_e9c; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + priv->regeb4 = reg_eb4; + reg_ebc = result[candidate][5]; + priv->regebc = reg_ebc; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, + "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", + __func__, reg_e94, reg_e9c, + reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); + path_a_ok = true; + path_b_ok = true; + } else { + reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; + reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; + } + + if (reg_e94 && candidate >= 0) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + if (priv->rf_paths > 1) + rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, + candidate, (reg_ec4 == 0)); + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); +} + +/* + * This is needed for 8723bu as well, presumable + */ +static void rtl8192e_crystal_afe_adjust(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + + /* + * 40Mhz crystal source, MAC 0x28[2]=0 + */ + val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL); + val8 &= 0xfb; + rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8); + + val32 = rtl8xxxu_read32(priv, REG_AFE_CTRL4); + val32 &= 0xfffffc7f; + rtl8xxxu_write32(priv, REG_AFE_CTRL4, val32); + + /* + * 92e AFE parameter + * AFE PLL KVCO selection, MAC 0x28[6]=1 + */ + val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL); + val8 &= 0xbf; + rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8); + + /* + * AFE PLL KVCO selection, MAC 0x78[21]=0 + */ + val32 = rtl8xxxu_read32(priv, REG_AFE_CTRL4); + val32 &= 0xffdfffff; + rtl8xxxu_write32(priv, REG_AFE_CTRL4, val32); +} + +static void rtl8192e_disabled_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* Clear suspend enable and power down enable*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(4)); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); +} + +static int rtl8192e_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* disable HWPDN 0x04[15]=0*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~BIT(7); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* disable SW LPS 0x04[10]= 0 */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~BIT(2); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* disable WL suspend*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(4)); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* wait till 0x04[17] = 1 power ready*/ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* We should be able to optimize the following three entries into one */ + + /* release WLON reset 0x04[16]= 1*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8); + + /* set, then poll until 0 */ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_MAC_ENABLE; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + +exit: + return ret; +} + +static int rtl8192eu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u8 val8; + u16 val16; + u32 val32; + int retry, retval; + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + retry = 100; + retval = -EBUSY; + /* + * Poll 32 bit wide 0x05f8 for 0x00000000 to ensure no TX is pending. + */ + do { + val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); + if (!val32) { + retval = 0; + break; + } + } while (retry--); + + if (!retry) { + dev_warn(dev, "Failed to flush TX queue\n"); + retval = -EBUSY; + goto out; + } + + /* Disable CCK and OFDM, clock gated */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + udelay(2); + + /* Reset whole BB */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BB_GLB_RSTN; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + /* Reset MAC TRX */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 &= 0xff00; + val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 &= ~CR_SECURITY_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); + val8 |= DUAL_TSF_TX_OK; + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); + +out: + return retval; +} + +static int rtl8192eu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + int count, ret = 0; + + /* Turn off RF */ + val8 = rtl8xxxu_read8(priv, REG_RF_CTRL); + val8 &= ~RF_ENABLE; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + /* Switch DPDT_SEL_P output from register 0x65[2] */ + val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); + val8 &= ~LEDCFG2_DPDT_SELECT; + rtl8xxxu_write8(priv, REG_LEDCFG2, val8); + + /* 0x0005[1] = 1 turn off MAC by HW state machine*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + if ((val8 & BIT(1)) == 0) + break; + udelay(10); + } + + if (!count) { + dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", + __func__); + ret = -EBUSY; + goto exit; + } + +exit: + return ret; +} + +static int rtl8192eu_emu_to_disabled(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* 0x04[12:11] = 01 enable WL suspend */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(4)); + val8 |= BIT(3); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + return 0; +} + +static int rtl8192eu_power_on(struct rtl8xxxu_priv *priv) +{ + u16 val16; + u32 val32; + int ret; + + val32 = rtl8xxxu_read32(priv, REG_SYS_CFG); + if (val32 & SYS_CFG_SPS_LDO_SEL) { + rtl8xxxu_write8(priv, REG_LDO_SW_CTRL, 0xc3); + } else { + /* + * Raise 1.2V voltage + */ + val32 = rtl8xxxu_read32(priv, REG_8192E_LDOV12_CTRL); + val32 &= 0xff0fffff; + val32 |= 0x00500000; + rtl8xxxu_write32(priv, REG_8192E_LDOV12_CTRL, val32); + rtl8xxxu_write8(priv, REG_LDO_SW_CTRL, 0x83); + } + + /* + * Adjust AFE before enabling PLL + */ + rtl8192e_crystal_afe_adjust(priv); + rtl8192e_disabled_to_emu(priv); + + ret = rtl8192e_emu_to_active(priv); + if (ret) + goto exit; + + rtl8xxxu_write16(priv, REG_CR, 0x0000); + + /* + * Enable MAC DMA/WMAC/SCHEDULE/SEC block + * Set CR bit10 to enable 32k calibration. + */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + +exit: + return ret; +} + +static void rtl8192eu_power_off(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + rtl8xxxu_flush_fifo(priv); + + val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); + val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); + + rtl8192eu_active_to_lps(priv); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + /* Reset MCU */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8xxxu_reset_8051(priv); + + rtl8192eu_active_to_emu(priv); + rtl8192eu_emu_to_disabled(priv); +} + +static void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u8 val8; + + val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); + val32 |= (BIT(22) | BIT(23)); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); + + val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); + val8 |= BIT(5); + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); + + /* + * WLAN action by PTA + */ + rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04); + + val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); + val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; + rtl8xxxu_write32(priv, REG_PWR_DATA, val32); + + val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); + val32 |= (BIT(0) | BIT(1)); + rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); + + rtl8xxxu_write8(priv, REG_RFE_CTRL_ANTA_SRC, 0x77); + + val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); + val32 &= ~BIT(24); + val32 |= BIT(23); + rtl8xxxu_write32(priv, REG_LEDCFG0, val32); + + /* + * Fix external switch Main->S1, Aux->S0 + */ + val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); + + /* + * Fix transmission failure of rtl8192e. + */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static s8 rtl8192e_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + static const s8 lna_gain_table_0[8] = {15, 9, -10, -21, -23, -27, -43, -44}; + static const s8 lna_gain_table_1[8] = {24, 18, 13, -4, -11, -18, -31, -36}; + + u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; + s8 rx_pwr_all = 0x00; + u8 vga_idx, lna_idx; + s8 lna_gain = 0; + + lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); + vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); + + if (priv->cck_agc_report_type == 0) + lna_gain = lna_gain_table_0[lna_idx]; + else + lna_gain = lna_gain_table_1[lna_idx]; + + rx_pwr_all = lna_gain - (2 * vga_idx); + + return rx_pwr_all; +} + +static int rtl8192eu_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG1); + + if (brightness == LED_OFF) { + ledcfg &= ~LEDCFG1_HW_LED_CONTROL; + ledcfg |= LEDCFG1_LED_DISABLE; + } else if (brightness == LED_ON) { + ledcfg &= ~(LEDCFG1_HW_LED_CONTROL | LEDCFG1_LED_DISABLE); + } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { + ledcfg &= ~LEDCFG1_LED_DISABLE; + ledcfg |= LEDCFG1_HW_LED_CONTROL; + } + + rtl8xxxu_write8(priv, REG_LEDCFG1, ledcfg); + + return 0; +} + +struct rtl8xxxu_fileops rtl8192eu_fops = { + .identify_chip = rtl8192eu_identify_chip, + .parse_efuse = rtl8192eu_parse_efuse, + .load_firmware = rtl8192eu_load_firmware, + .power_on = rtl8192eu_power_on, + .power_off = rtl8192eu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8xxxu_reset_8051, + .llt_init = rtl8xxxu_auto_llt_table, + .init_phy_bb = rtl8192eu_init_phy_bb, + .init_phy_rf = rtl8192eu_init_phy_rf, + .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, + .phy_iq_calibrate = rtl8192eu_phy_iq_calibrate, + .config_channel = rtl8xxxu_gen2_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc24, + .parse_phystats = rtl8723au_rx_parse_phystats, + .enable_rf = rtl8192e_enable_rf, + .disable_rf = rtl8xxxu_gen2_disable_rf, + .usb_quirks = rtl8xxxu_gen2_usb_quirks, + .set_tx_power = rtl8192e_set_tx_power, + .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8xxxu_gen2_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v2, + .set_crystal_cap = rtl8723a_set_crystal_cap, + .cck_rssi = rtl8192e_cck_rssi, + .led_classdev_brightness_set = rtl8192eu_led_brightness_set, + .writeN_block_size = 128, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), + .has_s0s1 = 0, + .gen2_thermal_meter = 1, + .needs_full_init = 1, + .hw_feature_report = 0, + .supports_ap = 1, + .max_macid_num = 128, + .max_sec_cam_num = 64, + .adda_1t_init = 0x0fc01616, + .adda_1t_path_on = 0x0fc01616, + .adda_2t_path_on_a = 0x0fc01616, + .adda_2t_path_on_b = 0x0fc01616, + .trxff_boundary = 0x3cff, + .mactable = rtl8192e_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8192E, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8192E, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8192E, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8192E, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8192f.c b/drivers/net/wireless/realtek/rtl8xxxu/8192f.c new file mode 100644 index 000000000..5f076da4b --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8192f.c @@ -0,0 +1,2092 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8192fu specific subdriver + * + * Copyright (c) 2023 Bitterblue Smith + * + * Portions copied from existing rtl8xxxu code: + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8192f_mac_init_table[] = { + {0x420, 0x00}, {0x422, 0x78}, {0x428, 0x0a}, {0x429, 0x10}, + {0x430, 0x00}, {0x431, 0x00}, {0x432, 0x00}, {0x433, 0x01}, + {0x434, 0x04}, {0x435, 0x05}, {0x436, 0x07}, {0x437, 0x08}, + {0x43c, 0x04}, {0x43d, 0x05}, {0x43e, 0x07}, {0x43f, 0x08}, + {0x440, 0x5d}, {0x441, 0x01}, {0x442, 0x00}, {0x444, 0x10}, + {0x445, 0xf0}, {0x446, 0x0e}, {0x447, 0x1f}, {0x448, 0x00}, + {0x449, 0x00}, {0x44a, 0x00}, {0x44b, 0x00}, {0x44c, 0x10}, + {0x44d, 0xf0}, {0x44e, 0x0e}, {0x44f, 0x00}, {0x450, 0x00}, + {0x451, 0x00}, {0x452, 0x00}, {0x453, 0x00}, {0x480, 0x20}, + {0x49c, 0x30}, {0x49d, 0xf0}, {0x49e, 0x03}, {0x49f, 0x3e}, + {0x4a0, 0x00}, {0x4a1, 0x00}, {0x4a2, 0x00}, {0x4a3, 0x00}, + {0x4a4, 0x15}, {0x4a5, 0xf0}, {0x4a6, 0x01}, {0x4a7, 0x0e}, + {0x4a8, 0xe0}, {0x4a9, 0x00}, {0x4aa, 0x00}, {0x4ab, 0x00}, + {0x2448, 0x06}, {0x244a, 0x06}, {0x244c, 0x06}, {0x244e, 0x06}, + {0x4c7, 0x80}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4ca, 0x3c}, + {0x4cb, 0x3c}, {0x4cc, 0xff}, {0x4cd, 0xff}, {0x4ce, 0x01}, + {0x500, 0x26}, {0x501, 0xa2}, {0x502, 0x2f}, {0x503, 0x00}, + {0x504, 0x28}, {0x505, 0xa3}, {0x506, 0x5e}, {0x507, 0x00}, + {0x508, 0x2b}, {0x509, 0xa4}, {0x50a, 0x5e}, {0x50b, 0x00}, + {0x50c, 0x4f}, {0x50d, 0xa4}, {0x50e, 0x00}, {0x50f, 0x00}, + {0x512, 0x1c}, {0x514, 0x0a}, {0x516, 0x0a}, {0x521, 0x2f}, + {0x525, 0x0f}, {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, + {0x55c, 0x50}, {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, + {0x609, 0x2a}, {0x60c, 0x18}, {0x620, 0xff}, {0x621, 0xff}, + {0x622, 0xff}, {0x623, 0xff}, {0x624, 0xff}, {0x625, 0xff}, + {0x626, 0xff}, {0x627, 0xff}, {0x638, 0x50}, {0x63c, 0x0a}, + {0x63d, 0x0a}, {0x63e, 0x0e}, {0x63f, 0x0e}, {0x640, 0x40}, + {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xc8}, {0x66e, 0x05}, + {0x6a0, 0xff}, {0x6a1, 0xff}, {0x6a2, 0xff}, {0x6a3, 0xff}, + {0x6a4, 0xff}, {0x6a5, 0xff}, {0x6de, 0x84}, {0x700, 0x21}, + {0x701, 0x43}, {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, + {0x709, 0x43}, {0x70a, 0x65}, {0x70b, 0x87}, {0x718, 0x40}, + {0x7c0, 0x38}, {0x7c2, 0x0f}, {0x7c3, 0xc0}, {0x073, 0x04}, + {0x7c4, 0x77}, {0x024, 0xc7}, {0x7ec, 0xff}, {0x7ed, 0xff}, + {0x7ee, 0xff}, {0x7ef, 0xff}, + {0xffff, 0xff}, +}; + +/* If updating the phy init table, also update rtl8192f_revise_cck_tx_psf(). */ +static const struct rtl8xxxu_reg32val rtl8192fu_phy_init_table[] = { + {0x800, 0x80006C00}, {0x804, 0x00004001}, + {0x808, 0x0000FC00}, {0x80C, 0x00000000}, + {0x810, 0x20200322}, {0x814, 0x020C3910}, + {0x818, 0x00000385}, {0x81C, 0x07000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x01000100}, {0x82C, 0x00390204}, + {0x830, 0x25252525}, {0x834, 0x25252525}, + {0x838, 0x25252525}, {0x83C, 0x25252525}, + {0x840, 0x00010000}, {0x844, 0x00010000}, + {0x848, 0x25252525}, {0x84C, 0x25252525}, + {0x850, 0x00031FE0}, {0x854, 0x00000000}, + {0x858, 0x569A569A}, {0x85C, 0x00400040}, + {0x860, 0x66F60000}, {0x864, 0x061F0000}, + {0x868, 0x25252525}, {0x86C, 0x25252525}, + {0x870, 0x00000300}, {0x874, 0x04003400}, + {0x878, 0x08080808}, {0x87C, 0x004F0201}, + {0x880, 0xD8001402}, {0x884, 0xC0000120}, + {0x888, 0x00000000}, {0x88C, 0xCC0000C0}, + {0x890, 0x00000000}, {0x894, 0xFFFFFFFE}, + {0x898, 0x40302010}, {0x89C, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000F00}, {0x90C, 0x81121313}, + {0x910, 0x024C0000}, {0x914, 0x00000000}, + {0x918, 0x00000000}, {0x91C, 0x00000000}, + {0x920, 0x00000000}, {0x924, 0x00000000}, + {0x928, 0x00000000}, {0x92C, 0x00000000}, + {0x930, 0x88000000}, {0x934, 0x00000245}, + {0x938, 0x00024588}, {0x93C, 0x00000000}, + {0x940, 0x000007FF}, {0x944, 0x3F3F0000}, + {0x948, 0x000001A3}, {0x94C, 0x20200008}, + {0x950, 0x00338A98}, {0x954, 0x00000000}, + {0x958, 0xCBCAD87A}, {0x95C, 0x06EB5735}, + {0x960, 0x00000000}, {0x964, 0x00000000}, + {0x968, 0x00000000}, {0x96C, 0x00000003}, + {0x970, 0x00000000}, {0x974, 0x00000000}, + {0x978, 0x00000000}, {0x97C, 0x10030000}, + {0x980, 0x00000000}, {0x984, 0x02800280}, + {0x988, 0x020A5704}, {0x98C, 0x1461C826}, + {0x990, 0x0001469E}, {0x994, 0x008858D1}, + {0x998, 0x400086C9}, {0x99C, 0x44444242}, + {0x9A0, 0x00000000}, {0x9A4, 0x00000000}, + {0x9A8, 0x00000000}, {0x9AC, 0xC0000000}, + {0xA00, 0x00D047C8}, {0xA04, 0xC1FF0008}, + {0xA08, 0x88838300}, {0xA0C, 0x2E20100F}, + {0xA10, 0x9500BB78}, {0xA14, 0x11144028}, + {0xA18, 0x00881117}, {0xA1C, 0x89140F00}, + {0xA20, 0xE82C0001}, {0xA24, 0x64B80C1C}, + {0xA28, 0x00158810}, {0xA2C, 0x10BB8000}, + {0xA70, 0x00008000}, {0xA74, 0x80800100}, + {0xA78, 0x000089F0}, {0xA7C, 0x225B0606}, + {0xA80, 0x20803210}, {0xA84, 0x00200200}, + {0xA88, 0x00000000}, {0xA8C, 0x00000000}, + {0xA90, 0x00000000}, {0xA94, 0x00000000}, + {0xA98, 0x00000000}, {0xA9C, 0x00460000}, + {0xAA0, 0x00000000}, {0xAA4, 0x00020014}, + {0xAA8, 0xBA0A0008}, {0xAAC, 0x01235667}, + {0xAB0, 0x00000000}, {0xAB4, 0x00201402}, + {0xAB8, 0x0000001C}, {0xABC, 0x0000F7FF}, + {0xAC0, 0xD4C0A742}, {0xAC4, 0x00000000}, + {0xAC8, 0x00000F08}, {0xACC, 0x00000F07}, + {0xAD0, 0xA1052A10}, {0xAD4, 0x0D9D8452}, + {0xAD8, 0x9E024024}, {0xADC, 0x0023C001}, + {0xAE0, 0x00000391}, {0xB2C, 0x00000000}, + {0xC00, 0x00000080}, {0xC04, 0x6F005433}, + {0xC08, 0x000004E4}, {0xC0C, 0x6C6C6C6C}, + {0xC10, 0x22000000}, {0xC14, 0x40000100}, + {0xC18, 0x22000000}, {0xC1C, 0x40000100}, + {0xC20, 0x00000000}, {0xC24, 0x40000100}, + {0xC28, 0x00000000}, {0xC2C, 0x40000100}, + {0xC30, 0x0401E809}, {0xC34, 0x30000020}, + {0xC38, 0x23808080}, {0xC3C, 0x00002F44}, + {0xC40, 0x1CF8403F}, {0xC44, 0x000100C7}, + {0xC48, 0xEC060106}, {0xC4C, 0x007F037F}, + {0xC50, 0x00E48020}, {0xC54, 0x04008017}, + {0xC58, 0x00000020}, {0xC5C, 0x00708492}, + {0xC60, 0x09280200}, {0xC64, 0x5014838B}, + {0xC68, 0x47C006C7}, {0xC6C, 0x00000035}, + {0xC70, 0x00001007}, {0xC74, 0x02815269}, + {0xC78, 0x0FE07F1F}, {0xC7C, 0x00B91612}, + {0xC80, 0x40000100}, {0xC84, 0x32000000}, + {0xC88, 0x40000100}, {0xC8C, 0xA0240000}, + {0xC90, 0x400E161E}, {0xC94, 0x00000F00}, + {0xC98, 0x400E161E}, {0xC9C, 0x0000BDC8}, + {0xCA0, 0x00000000}, {0xCA4, 0x098300A0}, + {0xCA8, 0x00006B00}, {0xCAC, 0x87F45B1A}, + {0xCB0, 0x0000002D}, {0xCB4, 0x00000000}, + {0xCB8, 0x00000000}, {0xCBC, 0x28100200}, + {0xCC0, 0x0010A3D0}, {0xCC4, 0x00000F7D}, + {0xCC8, 0x00000000}, {0xCCC, 0x00000000}, + {0xCD0, 0x593659AD}, {0xCD4, 0xB7545121}, + {0xCD8, 0x64B22427}, {0xCDC, 0x00766932}, + {0xCE0, 0x40201000}, {0xCE4, 0x00000000}, + {0xCE8, 0x40E04407}, {0xCEC, 0x2E572000}, + {0xD00, 0x000D8780}, {0xD04, 0x40020403}, + {0xD08, 0x0002907F}, {0xD0C, 0x20010201}, + {0xD10, 0x06288888}, {0xD14, 0x8888367B}, + {0xD18, 0x7D806DB3}, {0xD1C, 0x0000007F}, + {0xD20, 0x567600B8}, {0xD24, 0x0000018B}, + {0xD28, 0xD513FF7D}, {0xD2C, 0xCC979975}, + {0xD30, 0x04928000}, {0xD34, 0x40608000}, + {0xD38, 0x88DDA000}, {0xD3C, 0x00026EE2}, + {0xD50, 0x67270001}, {0xD54, 0x20500000}, + {0xD58, 0x16161616}, {0xD5C, 0x71F20064}, + {0xD60, 0x4653DA60}, {0xD64, 0x3E718A3C}, + {0xD68, 0x00000183}, {0xD7C, 0x00000000}, + {0xD80, 0x50000000}, {0xD84, 0x31310400}, + {0xD88, 0xF5B50000}, {0xD8C, 0x00000000}, + {0xD90, 0x00000000}, {0xD94, 0x44BBBB44}, + {0xD98, 0x44BB44FF}, {0xD9C, 0x06033688}, + {0xE00, 0x25252525}, {0xE04, 0x25252525}, + {0xE08, 0x25252525}, {0xE10, 0x25252525}, + {0xE14, 0x25252525}, {0xE18, 0x25252525}, + {0xE1C, 0x25252525}, {0xE20, 0x00000000}, + {0xE24, 0x00200000}, {0xE28, 0x00000000}, + {0xE2C, 0x00000000}, {0xE30, 0x01007C00}, + {0xE34, 0x01004800}, {0xE38, 0x10008C0F}, + {0xE3C, 0x3C008C0F}, {0xE40, 0x01007C00}, + {0xE44, 0x00000000}, {0xE48, 0x00000000}, + {0xE4C, 0x00000000}, {0xE50, 0x01007C00}, + {0xE54, 0x01004800}, {0xE58, 0x10008C0F}, + {0xE5C, 0x3C008C0F}, {0xE60, 0x02100000}, + {0xE64, 0xBBBBBBBB}, {0xE68, 0x40404040}, + {0xE6C, 0x80408040}, {0xE70, 0x80408040}, + {0xE74, 0x40404040}, {0xE78, 0x00400040}, + {0xE7C, 0x40404040}, {0xE80, 0x00FF0000}, + {0xE84, 0x80408040}, {0xE88, 0x40404040}, + {0xE8C, 0x80408040}, {0xED0, 0x80408040}, + {0xED4, 0x80408040}, {0xED8, 0x80408040}, + {0xEDC, 0xC040C040}, {0xEE0, 0xC040C040}, + {0xEE4, 0x00400040}, {0xEE8, 0xD8001402}, + {0xEEC, 0xC0000120}, {0xEF0, 0x02000B09}, + {0xEF4, 0x00000001}, {0xEF8, 0x00000000}, + {0xF00, 0x00000300}, {0xF04, 0x00000002}, + {0xF08, 0x00007D0C}, {0xF0C, 0x0000A907}, + {0xF10, 0x00005807}, {0xF14, 0x00000003}, + {0xF18, 0x07D003E8}, {0xF1C, 0x8000001F}, + {0xF20, 0x00000000}, {0xF24, 0x00000000}, + {0xF28, 0x00000000}, {0xF2C, 0x00000000}, + {0xF30, 0x00000000}, {0xF34, 0x00000000}, + {0xF38, 0x00030055}, {0xF3C, 0x0000003A}, + {0xF40, 0x00000002}, {0xF44, 0x00000000}, + {0xF48, 0x00000000}, {0xF4C, 0x0B000000}, + {0xF50, 0x00000000}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8192f_agc_table[] = { + {0xC78, 0x0FA0001F}, {0xC78, 0x0FA0011F}, + {0xC78, 0x0FA0021F}, {0xC78, 0x0FA0031F}, + {0xC78, 0x0FA0041F}, {0xC78, 0x0FA0051F}, + {0xC78, 0x0F90061F}, {0xC78, 0x0F80071F}, + {0xC78, 0x0F70081F}, {0xC78, 0x0F60091F}, + {0xC78, 0x0F500A1F}, {0xC78, 0x0F400B1F}, + {0xC78, 0x0F300C1F}, {0xC78, 0x0F200D1F}, + {0xC78, 0x0F100E1F}, {0xC78, 0x0F000F1F}, + {0xC78, 0x0EF0101F}, {0xC78, 0x0EE0111F}, + {0xC78, 0x0ED0121F}, {0xC78, 0x0EC0131F}, + {0xC78, 0x0EB0141F}, {0xC78, 0x0EA0151F}, + {0xC78, 0x0E90161F}, {0xC78, 0x0E80171F}, + {0xC78, 0x0E70181F}, {0xC78, 0x0E60191F}, + {0xC78, 0x0E501A1F}, {0xC78, 0x0E401B1F}, + {0xC78, 0x0E301C1F}, {0xC78, 0x0C701D1F}, + {0xC78, 0x0C601E1F}, {0xC78, 0x0C501F1F}, + {0xC78, 0x0C40201F}, {0xC78, 0x0C30211F}, + {0xC78, 0x0A60221F}, {0xC78, 0x0A50231F}, + {0xC78, 0x0A40241F}, {0xC78, 0x0A30251F}, + {0xC78, 0x0860261F}, {0xC78, 0x0850271F}, + {0xC78, 0x0840281F}, {0xC78, 0x0830291F}, + {0xC78, 0x06702A1F}, {0xC78, 0x06602B1F}, + {0xC78, 0x06502C1F}, {0xC78, 0x06402D1F}, + {0xC78, 0x06302E1F}, {0xC78, 0x04602F1F}, + {0xC78, 0x0450301F}, {0xC78, 0x0440311F}, + {0xC78, 0x0430321F}, {0xC78, 0x0260331F}, + {0xC78, 0x0250341F}, {0xC78, 0x0240351F}, + {0xC78, 0x0230361F}, {0xC78, 0x0050371F}, + {0xC78, 0x0040381F}, {0xC78, 0x0030391F}, + {0xC78, 0x00203A1F}, {0xC78, 0x00103B1F}, + {0xC78, 0x00003C1F}, {0xC78, 0x00003D1F}, + {0xC78, 0x00003E1F}, {0xC78, 0x00003F1F}, + + {0xC78, 0x0FA0401F}, {0xC78, 0x0FA0411F}, + {0xC78, 0x0FA0421F}, {0xC78, 0x0FA0431F}, + {0xC78, 0x0F90441F}, {0xC78, 0x0F80451F}, + {0xC78, 0x0F70461F}, {0xC78, 0x0F60471F}, + {0xC78, 0x0F50481F}, {0xC78, 0x0F40491F}, + {0xC78, 0x0F304A1F}, {0xC78, 0x0F204B1F}, + {0xC78, 0x0F104C1F}, {0xC78, 0x0F004D1F}, + {0xC78, 0x0EF04E1F}, {0xC78, 0x0EE04F1F}, + {0xC78, 0x0ED0501F}, {0xC78, 0x0EC0511F}, + {0xC78, 0x0EB0521F}, {0xC78, 0x0EA0531F}, + {0xC78, 0x0E90541F}, {0xC78, 0x0E80551F}, + {0xC78, 0x0E70561F}, {0xC78, 0x0E60571F}, + {0xC78, 0x0E50581F}, {0xC78, 0x0E40591F}, + {0xC78, 0x0E305A1F}, {0xC78, 0x0E205B1F}, + {0xC78, 0x0E105C1F}, {0xC78, 0x0C505D1F}, + {0xC78, 0x0C405E1F}, {0xC78, 0x0C305F1F}, + {0xC78, 0x0C20601F}, {0xC78, 0x0C10611F}, + {0xC78, 0x0A40621F}, {0xC78, 0x0A30631F}, + {0xC78, 0x0A20641F}, {0xC78, 0x0A10651F}, + {0xC78, 0x0840661F}, {0xC78, 0x0830671F}, + {0xC78, 0x0820681F}, {0xC78, 0x0810691F}, + {0xC78, 0x06506A1F}, {0xC78, 0x06406B1F}, + {0xC78, 0x06306C1F}, {0xC78, 0x06206D1F}, + {0xC78, 0x06106E1F}, {0xC78, 0x04406F1F}, + {0xC78, 0x0430701F}, {0xC78, 0x0420711F}, + {0xC78, 0x0410721F}, {0xC78, 0x0240731F}, + {0xC78, 0x0230741F}, {0xC78, 0x0220751F}, + {0xC78, 0x0210761F}, {0xC78, 0x0030771F}, + {0xC78, 0x0020781F}, {0xC78, 0x0010791F}, + {0xC78, 0x00007A1F}, {0xC78, 0x00007B1F}, + {0xC78, 0x00007C1F}, {0xC78, 0x00007D1F}, + {0xC78, 0x00007E1F}, {0xC78, 0x00007F1F}, + + {0xC78, 0x0FA0801F}, {0xC78, 0x0FA0811F}, + {0xC78, 0x0FA0821F}, {0xC78, 0x0FA0831F}, + {0xC78, 0x0FA0841F}, {0xC78, 0x0FA0851F}, + {0xC78, 0x0F90861F}, {0xC78, 0x0F80871F}, + {0xC78, 0x0F70881F}, {0xC78, 0x0F60891F}, + {0xC78, 0x0F508A1F}, {0xC78, 0x0F408B1F}, + {0xC78, 0x0F308C1F}, {0xC78, 0x0F208D1F}, + {0xC78, 0x0F108E1F}, {0xC78, 0x0B908F1F}, + {0xC78, 0x0B80901F}, {0xC78, 0x0B70911F}, + {0xC78, 0x0B60921F}, {0xC78, 0x0B50931F}, + {0xC78, 0x0B40941F}, {0xC78, 0x0B30951F}, + {0xC78, 0x0B20961F}, {0xC78, 0x0B10971F}, + {0xC78, 0x0B00981F}, {0xC78, 0x0AF0991F}, + {0xC78, 0x0AE09A1F}, {0xC78, 0x0AD09B1F}, + {0xC78, 0x0AC09C1F}, {0xC78, 0x0AB09D1F}, + {0xC78, 0x0AA09E1F}, {0xC78, 0x0A909F1F}, + {0xC78, 0x0A80A01F}, {0xC78, 0x0A70A11F}, + {0xC78, 0x0A60A21F}, {0xC78, 0x0A50A31F}, + {0xC78, 0x0A40A41F}, {0xC78, 0x0A30A51F}, + {0xC78, 0x0A20A61F}, {0xC78, 0x0A10A71F}, + {0xC78, 0x0A00A81F}, {0xC78, 0x0830A91F}, + {0xC78, 0x0820AA1F}, {0xC78, 0x0810AB1F}, + {0xC78, 0x0800AC1F}, {0xC78, 0x0640AD1F}, + {0xC78, 0x0630AE1F}, {0xC78, 0x0620AF1F}, + {0xC78, 0x0610B01F}, {0xC78, 0x0600B11F}, + {0xC78, 0x0430B21F}, {0xC78, 0x0420B31F}, + {0xC78, 0x0410B41F}, {0xC78, 0x0400B51F}, + {0xC78, 0x0230B61F}, {0xC78, 0x0220B71F}, + {0xC78, 0x0210B81F}, {0xC78, 0x0200B91F}, + {0xC78, 0x0000BA1F}, {0xC78, 0x0000BB1F}, + {0xC78, 0x0000BC1F}, {0xC78, 0x0000BD1F}, + {0xC78, 0x0000BE1F}, {0xC78, 0x0000BF1F}, + {0xC50, 0x00E48024}, {0xC50, 0x00E48020}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192fu_radioa_init_table[] = { + {0x00, 0x30000}, {0x18, 0x0FC07}, {0x81, 0x0FC00}, {0x82, 0x003C0}, + {0x84, 0x00005}, {0x86, 0xA33A5}, {0x87, 0x00000}, {0x88, 0x58010}, + {0x8E, 0x64540}, {0x8F, 0x282D8}, {0x51, 0x02C06}, {0x52, 0x7A007}, + {0x53, 0x10061}, {0x54, 0x60018}, {0x55, 0x82020}, {0x56, 0x08CC6}, + {0x57, 0x2CC00}, {0x58, 0x00000}, {0x5A, 0x50000}, {0x5B, 0x00006}, + {0x5C, 0x00015}, {0x65, 0x20000}, {0x6E, 0x38319}, {0xF5, 0x43180}, + {0xEF, 0x00002}, {0x33, 0x00301}, {0x33, 0x1032A}, {0x33, 0x2032A}, + {0xEF, 0x00000}, {0xDF, 0x00002}, {0x35, 0x00000}, {0xF0, 0x08008}, + {0xEF, 0x00800}, {0x33, 0x0040E}, {0x33, 0x04845}, {0x33, 0x08848}, + {0x33, 0x0C84B}, {0x33, 0x1088A}, {0x33, 0x14C50}, {0x33, 0x18C8E}, + {0x33, 0x1CCCD}, {0x33, 0x20CD0}, {0x33, 0x24CD3}, {0x33, 0x28CD6}, + {0x33, 0x4002B}, {0x33, 0x4402E}, {0x33, 0x48846}, {0x33, 0x4C849}, + {0x33, 0x50888}, {0x33, 0x54CC6}, {0x33, 0x58CC9}, {0x33, 0x5CCCC}, + {0x33, 0x60CCF}, {0x33, 0x64CD2}, {0x33, 0x68CD5}, {0xEF, 0x00000}, + {0xEF, 0x00400}, {0x33, 0x01C23}, {0x33, 0x05C23}, {0x33, 0x09D23}, + {0x33, 0x0DD23}, {0x33, 0x11FA3}, {0x33, 0x15FA3}, {0x33, 0x19FAB}, + {0x33, 0x1DFAB}, {0xEF, 0x00000}, {0xEF, 0x00200}, {0x33, 0x00030}, + {0x33, 0x04030}, {0x33, 0x08030}, {0x33, 0x0C030}, {0x33, 0x10030}, + {0x33, 0x14030}, {0x33, 0x18030}, {0x33, 0x1C030}, {0x33, 0x20030}, + {0x33, 0x24030}, {0x33, 0x28030}, {0x33, 0x2C030}, {0x33, 0x30030}, + {0x33, 0x34030}, {0x33, 0x38030}, {0x33, 0x3C030}, {0xEF, 0x00000}, + {0xEF, 0x00100}, {0x33, 0x44001}, {0x33, 0x48001}, {0x33, 0x4C001}, + {0x33, 0x50001}, {0x33, 0x54001}, {0x33, 0x58001}, {0x33, 0x5C001}, + {0x33, 0x60001}, {0x33, 0x64001}, {0x33, 0x68001}, {0x33, 0x6C001}, + {0x33, 0x70001}, {0x33, 0x74001}, {0x33, 0x78001}, {0x33, 0x04000}, + {0x33, 0x08000}, {0x33, 0x0C000}, {0x33, 0x10000}, {0x33, 0x14000}, + {0x33, 0x18001}, {0x33, 0x1C002}, {0x33, 0x20002}, {0x33, 0x24002}, + {0x33, 0x28002}, {0x33, 0x2C002}, {0x33, 0x30002}, {0x33, 0x34002}, + {0x33, 0x38002}, {0xEF, 0x00000}, {0x84, 0x00000}, {0xEF, 0x80010}, + {0x30, 0x20000}, {0x31, 0x0006F}, {0x32, 0x01FF7}, {0xEF, 0x00000}, + {0x84, 0x00000}, {0xEF, 0x80000}, {0x30, 0x30000}, {0x31, 0x0006F}, + {0x32, 0xF1DF3}, {0xEF, 0x00000}, {0x84, 0x00000}, {0xEF, 0x80000}, + {0x30, 0x38000}, {0x31, 0x0006F}, {0x32, 0xF1FF2}, {0xEF, 0x00000}, + {0x1B, 0x746CE}, {0xEF, 0x20000}, {0x33, 0x30000}, {0x33, 0x38000}, + {0x33, 0x70000}, {0x33, 0x78000}, {0xEF, 0x00000}, {0xDF, 0x08000}, + {0xB0, 0xFFBCB}, {0xB3, 0x06000}, {0xB7, 0x18DF0}, {0xB8, 0x38FF0}, + {0xC9, 0x00600}, {0xDF, 0x00000}, {0xB1, 0x33B8F}, {0xB2, 0x33762}, + {0xB4, 0x141F0}, {0xB5, 0x14080}, {0xB6, 0x12425}, {0xB9, 0xC0008}, + {0xBA, 0x40005}, {0xC2, 0x02C01}, {0xC3, 0x0000B}, {0xC4, 0x81E2F}, + {0xC5, 0x5C28F}, {0xC6, 0x000A0}, {0xCA, 0x02000}, {0xFE, 0x00000}, + {0x18, 0x08C07}, {0xFE, 0x00000}, {0xFE, 0x00000}, {0xFE, 0x00000}, + {0x00, 0x31DD5}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8192fu_radiob_init_table[] = { + {0x00, 0x30000}, {0x81, 0x0FC00}, {0x82, 0x003C0}, {0x84, 0x00005}, + {0x86, 0xA33A5}, {0x87, 0x00000}, {0x88, 0x58010}, {0x8E, 0x64540}, + {0x8F, 0x282D8}, {0x51, 0x02C06}, {0x52, 0x7A007}, {0x53, 0x10061}, + {0x54, 0x60018}, {0x55, 0x82020}, {0x56, 0x08CC6}, {0x57, 0x2CC00}, + {0x58, 0x00000}, {0x5A, 0x50000}, {0x5B, 0x00006}, {0x5C, 0x00015}, + {0x65, 0x20000}, {0x6E, 0x38319}, {0xF5, 0x43180}, {0xEF, 0x00002}, + {0x33, 0x00301}, {0x33, 0x1032A}, {0x33, 0x2032A}, {0xEF, 0x00000}, + {0xDF, 0x00002}, {0x35, 0x00000}, {0xF0, 0x08008}, {0xEF, 0x00800}, + {0x33, 0x0040E}, {0x33, 0x04845}, {0x33, 0x08848}, {0x33, 0x0C84B}, + {0x33, 0x1088A}, {0x33, 0x14CC8}, {0x33, 0x18CCB}, {0x33, 0x1CCCE}, + {0x33, 0x20CD1}, {0x33, 0x24CD4}, {0x33, 0x28CD7}, {0x33, 0x4002B}, + {0x33, 0x4402E}, {0x33, 0x48846}, {0x33, 0x4C849}, {0x33, 0x50888}, + {0x33, 0x54CC6}, {0x33, 0x58CC9}, {0x33, 0x5CCCC}, {0x33, 0x60CCF}, + {0x33, 0x64CD2}, {0x33, 0x68CD5}, {0xEF, 0x00000}, {0xEF, 0x00400}, + {0x33, 0x01D23}, {0x33, 0x05D23}, {0x33, 0x09FA3}, {0x33, 0x0DFA3}, + {0x33, 0x11D2B}, {0x33, 0x15D2B}, {0x33, 0x19FAB}, {0x33, 0x1DFAB}, + {0xEF, 0x00000}, {0xEF, 0x00200}, {0x33, 0x00030}, {0x33, 0x04030}, + {0x33, 0x08030}, {0x33, 0x0C030}, {0x33, 0x10030}, {0x33, 0x14030}, + {0x33, 0x18030}, {0x33, 0x1C030}, {0x33, 0x20030}, {0x33, 0x24030}, + {0x33, 0x28030}, {0x33, 0x2C030}, {0x33, 0x30030}, {0x33, 0x34030}, + {0x33, 0x38030}, {0x33, 0x3C030}, {0xEF, 0x00000}, {0xEF, 0x00100}, + {0x33, 0x44000}, {0x33, 0x48000}, {0x33, 0x4C000}, {0x33, 0x50000}, + {0x33, 0x54000}, {0x33, 0x58000}, {0x33, 0x5C000}, {0x33, 0x60000}, + {0x33, 0x64000}, {0x33, 0x68000}, {0x33, 0x6C000}, {0x33, 0x70000}, + {0x33, 0x74000}, {0x33, 0x78000}, {0x33, 0x04000}, {0x33, 0x08000}, + {0x33, 0x0C000}, {0x33, 0x10000}, {0x33, 0x14000}, {0x33, 0x18000}, + {0x33, 0x1C001}, {0x33, 0x20001}, {0x33, 0x24001}, {0x33, 0x28001}, + {0x33, 0x2C001}, {0x33, 0x30001}, {0x33, 0x34001}, {0x33, 0x38001}, + {0xEF, 0x00000}, {0x84, 0x00000}, {0xEF, 0x80010}, {0x30, 0x20000}, + {0x31, 0x0006F}, {0x32, 0x01FF7}, {0xEF, 0x00000}, {0x84, 0x00000}, + {0xEF, 0x80000}, {0x30, 0x30000}, {0x31, 0x0006F}, {0x32, 0xF1DF3}, + {0xEF, 0x00000}, {0x84, 0x00000}, {0xEF, 0x80000}, {0x30, 0x38000}, + {0x31, 0x0006F}, {0x32, 0xF1FF2}, {0xEF, 0x00000}, {0x1B, 0x746CE}, + {0xEF, 0x20000}, {0x33, 0x30000}, {0x33, 0x38000}, {0x33, 0x70000}, + {0x33, 0x78000}, {0xEF, 0x00000}, {0x00, 0x31DD5}, + {0xff, 0xffffffff} +}; + +static int rtl8192fu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 sys_cfg, vendor, val32; + + strscpy(priv->chip_name, "8192FU", sizeof(priv->chip_name)); + priv->rtl_chip = RTL8192F; + priv->rf_paths = 2; + priv->rx_paths = 2; + priv->tx_paths = 2; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + return -EOPNOTSUPP; + } + + val32 = rtl8xxxu_read32(priv, REG_MULTI_FUNC_CTRL); + priv->has_wifi = u32_get_bits(val32, MULTI_WIFI_FUNC_EN); + priv->has_bluetooth = u32_get_bits(val32, MULTI_BT_FUNC_EN); + priv->has_gps = u32_get_bits(val32, MULTI_GPS_FUNC_EN); + priv->is_multi_func = 1; + + vendor = sys_cfg & SYS_CFG_VENDOR_ID; + rtl8xxxu_identify_vendor_1bit(priv, vendor); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); + priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); + + return rtl8xxxu_config_endpoints_no_sie(priv); +} + +static void +rtl8192f_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) +{ + u8 cck, ofdmbase, mcsbase; + u32 val32, ofdm, mcs; + int group, cck_group; + + rtl8188f_channel_to_group(channel, &group, &cck_group); + + cck = priv->cck_tx_power_index_A[cck_group]; + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_CCK1_MCS32, 0x00007f00, cck); + + val32 = (cck << 16) | (cck << 8) | cck; + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, + 0x7f7f7f00, val32); + + ofdmbase = priv->ht40_1s_tx_power_index_A[group]; + ofdmbase += priv->ofdm_tx_power_diff[RF_A].a; + ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_RATE18_06, 0x7f7f7f7f, ofdm); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_RATE54_24, 0x7f7f7f7f, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_A[group]; + if (ht40) + mcsbase += priv->ht40_tx_power_diff[RF_A].a; + else + mcsbase += priv->ht20_tx_power_diff[RF_A].a; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_MCS03_MCS00, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_MCS07_MCS04, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_MCS11_MCS08, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_A_MCS15_MCS12, 0x7f7f7f7f, mcs); + + if (priv->tx_paths == 1) + return; + + cck = priv->cck_tx_power_index_B[cck_group]; + + val32 = (cck << 16) | (cck << 8) | cck; + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_CCK1_55_MCS32, + 0x7f7f7f00, val32); + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, + 0x0000007f, cck); + + ofdmbase = priv->ht40_1s_tx_power_index_B[group]; + ofdmbase += priv->ofdm_tx_power_diff[RF_B].b; + ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_RATE18_06, 0x7f7f7f7f, ofdm); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_RATE54_24, 0x7f7f7f7f, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_B[group]; + if (ht40) + mcsbase += priv->ht40_tx_power_diff[RF_B].b; + else + mcsbase += priv->ht20_tx_power_diff[RF_B].b; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_MCS03_MCS00, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_MCS07_MCS04, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_MCS11_MCS08, 0x7f7f7f7f, mcs); + rtl8xxxu_write32_mask(priv, REG_TX_AGC_B_MCS15_MCS12, 0x7f7f7f7f, mcs); +} + +static void rtl8192f_revise_cck_tx_psf(struct rtl8xxxu_priv *priv, u8 channel) +{ + if (channel == 13) { + /* Special value for channel 13 */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xf8fe0001); + /* Normal values */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); + rtl8xxxu_write16(priv, REG_CCK0_DEBUG_PORT, 0x8810); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); + } else if (channel == 14) { + /* Normal value */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); + /* Special values for channel 14 */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x0000B81C); + rtl8xxxu_write16(priv, REG_CCK0_DEBUG_PORT, 0x0000); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x00003667); + } else { + /* Restore normal values from the phy init table */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); + rtl8xxxu_write16(priv, REG_CCK0_DEBUG_PORT, 0x8810); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); + } +} + +static void rtl8192fu_config_kfree(struct rtl8xxxu_priv *priv, u8 channel) +{ + u8 bb_gain[3] = { EFUSE_UNDEFINED, EFUSE_UNDEFINED, EFUSE_UNDEFINED }; + u8 bb_gain_path_mask[2] = { 0x0f, 0xf0 }; + enum rtl8xxxu_rfpath rfpath; + u8 bb_gain_for_path; + u8 channel_idx = 0; + + if (channel >= 1 && channel <= 3) + channel_idx = 0; + if (channel >= 4 && channel <= 9) + channel_idx = 1; + if (channel >= 10 && channel <= 14) + channel_idx = 2; + + rtl8xxxu_read_efuse8(priv, 0x1ee, &bb_gain[1]); + rtl8xxxu_read_efuse8(priv, 0x1ec, &bb_gain[0]); + rtl8xxxu_read_efuse8(priv, 0x1ea, &bb_gain[2]); + + if (bb_gain[1] == EFUSE_UNDEFINED) + return; + + if (bb_gain[0] == EFUSE_UNDEFINED) + bb_gain[0] = bb_gain[1]; + + if (bb_gain[2] == EFUSE_UNDEFINED) + bb_gain[2] = bb_gain[1]; + + for (rfpath = RF_A; rfpath < priv->rf_paths; rfpath++) { + /* power_trim based on 55[19:14] */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_UNKNOWN_55, + BIT(5), 1); + + /* enable 55[14] for 0.5db step */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_GAIN_CTRL, + BIT(18), 1); + + /* enter power_trim debug mode */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_GAIN_CCA, + BIT(7), 1); + + /* write enable */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_WE_LUT, BIT(7), 1); + + bb_gain_for_path = (bb_gain[channel_idx] & bb_gain_path_mask[rfpath]); + bb_gain_for_path >>= __ffs(bb_gain_path_mask[rfpath]); + + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3, + 0x70000, channel_idx * 2); + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3, + 0x3f, bb_gain_for_path); + + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3, + 0x70000, channel_idx * 2 + 1); + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3, + 0x3f, bb_gain_for_path); + + /* leave power_trim debug mode */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_GAIN_CCA, + BIT(7), 0); + + /* write disable */ + rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_WE_LUT, BIT(7), 0); + } +} + +static void rtl8192fu_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + bool ht40 = conf_is_ht40(&hw->conf); + u8 channel, subchannel = 0; + bool sec_ch_above = 0; + u32 val32; + + channel = (u8)hw->conf.chandef.chan->hw_value; + + if (conf_is_ht40_plus(&hw->conf)) { + sec_ch_above = 1; + channel += 2; + subchannel = 2; + } else if (conf_is_ht40_minus(&hw->conf)) { + sec_ch_above = 0; + channel -= 2; + subchannel = 1; + } + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + + rtl8192f_revise_cck_tx_psf(priv, channel); + + /* Set channel */ + val32 &= ~(BIT(18) | BIT(17)); /* select the 2.4G band(?) */ + u32p_replace_bits(&val32, channel, 0xff); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + if (priv->rf_paths > 1) + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_MODE_AG, val32); + + rtl8192fu_config_kfree(priv, channel); + + rtl8xxxu_write8(priv, REG_DATA_SUBCHANNEL, subchannel); + + /* small BW */ + rtl8xxxu_write32_clear(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, GENMASK(31, 30)); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_RF_MODE, FPGA_RF_MODE, ht40); + rtl8xxxu_write32_mask(priv, REG_FPGA1_RF_MODE, FPGA_RF_MODE, ht40); + + /* ADC clock = 160M */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_RF_MODE, GENMASK(10, 8), 4); + + /* DAC clock = 80M */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_RF_MODE, BIT(13) | BIT(12), 2); + + /* ADC buffer clk */ + rtl8xxxu_write32_mask(priv, REG_ANTDIV_PARA1, BIT(27) | BIT(26), 2); + + if (ht40) + /* Set Control channel to upper or lower. */ + rtl8xxxu_write32_mask(priv, REG_CCK0_SYSTEM, + CCK0_SIDEBAND, !sec_ch_above); + + /* Enable CCK */ + rtl8xxxu_write32_set(priv, REG_FPGA0_RF_MODE, FPGA_RF_MODE_CCK); + + /* RF TRX_BW */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + if (ht40) + val32 |= MODE_AG_BW_40MHZ_8723B; + else + val32 |= MODE_AG_BW_20MHZ_8723B; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + if (priv->rf_paths > 1) + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_MODE_AG, val32); + + /* Modify RX DFIR parameters */ + rtl8xxxu_write32_mask(priv, REG_TAP_UPD_97F, BIT(21) | BIT(20), 2); + + rtl8xxxu_write32_mask(priv, REG_DOWNSAM_FACTOR, BIT(29) | BIT(28), 2); + + if (ht40) + val32 = 0x3; + else + val32 = 0x1a3; + rtl8xxxu_write32_mask(priv, REG_RX_DFIR_MOD_97F, 0x1ff, val32); +} + +static void rtl8192fu_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u32 agg_rx; + u8 agg_ctrl; + + /* RX aggregation */ + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + + agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); + agg_rx &= ~RXDMA_USB_AGG_ENABLE; + agg_rx &= ~0xFF0F; /* reset agg size and timeout */ + + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); +} + +static int rtl8192fu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8192fu_efuse *efuse = &priv->efuse_wifi.efuse8192fu; + int i; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + memcpy(priv->cck_tx_power_index_B, efuse->tx_power_index_B.cck_base, + sizeof(efuse->tx_power_index_B.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + memcpy(priv->ht40_1s_tx_power_index_B, + efuse->tx_power_index_B.ht40_base, + sizeof(efuse->tx_power_index_B.ht40_base)); + + priv->ht20_tx_power_diff[0].a = + efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + priv->ht20_tx_power_diff[0].b = + efuse->tx_power_index_B.ht20_ofdm_1s_diff.b; + + priv->ht40_tx_power_diff[0].a = 0; + priv->ht40_tx_power_diff[0].b = 0; + + for (i = 1; i < RTL8723B_TX_COUNT; i++) { + priv->ofdm_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ofdm; + priv->ofdm_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ofdm; + + priv->ht20_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht20; + priv->ht20_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht20; + + priv->ht40_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht40; + priv->ht40_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht40; + } + + priv->default_crystal_cap = efuse->xtal_k & 0x3f; + + priv->rfe_type = efuse->rfe_option & 0x1f; + + if (priv->rfe_type != 5 && priv->rfe_type != 1) + dev_warn(&priv->udev->dev, + "%s: RFE type %d was not tested. Please send an email to linux-wireless@vger.kernel.org about this.\n", + __func__, priv->rfe_type); + + return 0; +} + +static int rtl8192fu_load_firmware(struct rtl8xxxu_priv *priv) +{ + return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8192fufw.bin"); +} + +static void rtl8192fu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + /* Enable BB and RF */ + rtl8xxxu_write16_set(priv, REG_SYS_FUNC, + SYS_FUNC_BBRSTB | SYS_FUNC_BB_GLB_RSTN); + + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); + + /* To Fix MAC loopback mode fail. */ + rtl8xxxu_write8(priv, REG_LDOHCI12_CTRL, 0xf); + rtl8xxxu_write8(priv, REG_SYS_SWR_CTRL2 + 1, 0xe9); + + rtl8xxxu_init_phy_regs(priv, rtl8192fu_phy_init_table); + + rtl8xxxu_init_phy_regs(priv, rtl8192f_agc_table); +} + +static int rtl8192fu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + int ret; + + ret = rtl8xxxu_init_phy_rf(priv, rtl8192fu_radioa_init_table, RF_A); + if (ret) + return ret; + + return rtl8xxxu_init_phy_rf(priv, rtl8192fu_radiob_init_table, RF_B); +} + +static void rtl8192f_phy_lc_calibrate(struct rtl8xxxu_priv *priv) +{ + u32 backup_mask = BIT(31) | BIT(30); + u32 backup; + u32 val32; + + /* Aries's NarrowBand */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + backup = u32_get_bits(val32, backup_mask); + + u32p_replace_bits(&val32, 0, backup_mask); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + rtl8188f_phy_lc_calibrate(priv); + + /* Aries's NarrowBand */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + u32p_replace_bits(&val32, backup, backup_mask); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + /* reset OFDM state */ + rtl8xxxu_write32_clear(priv, REG_FPGA0_RF_MODE, FPGA_RF_MODE_OFDM); + rtl8xxxu_write32_set(priv, REG_FPGA0_RF_MODE, FPGA_RF_MODE_OFDM); +} + +static int rtl8192fu_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_e94, reg_e9c, val32; + u32 rf_0x58_i, rf_0x58_q; + u8 rfe = priv->rfe_type; + int result = 0; + int ktime, i; + + /* Leave IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44ffbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(4), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(11), 1); + if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) + val32 = 0x30; + else + val32 = 0xe9; + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_PAD_TXG, 0x003ff, val32); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8214000f); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28140000); + + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00e62911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_TXA) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + /* reload 0xdf and CCK_IND off */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_WE_LUT, BIT(4), 1); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXMOD); + rf_0x58_i = u32_get_bits(val32, 0xfc000); + rf_0x58_q = u32_get_bits(val32, 0x003f0); + + for (i = 0; i < 8; i++) { + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3, + 0x1c000, i); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3, + 0x00fc0, rf_0x58_i); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3, + 0x0003f, rf_0x58_q); + } + + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, BIT(14), 0); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_WE_LUT, BIT(4), 0); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00810, 0); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + + return result; +} + +static int rtl8192fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32; + int result = 0; + int ktime; + + /* Leave IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(1), 1); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_P1, 0); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(11), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_PAD_TXG, 0x003ff, 0x27); + + /* Enter IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160027); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000); + + /* Tx IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0086a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_TXA) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) { + result |= 0x01; + } else { /* If TX not OK, ignore RX */ + /* PA/PAD controlled by 0x0 */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, + BIT(11), 0); + + return result; + } + + val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) | ((reg_e9c & 0x3ff0000) >> 16); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* Modify RX IQK mode table */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + /* PA/PAD control by 0x56, and set = 0x0 */ + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(1), 1); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_P1, 0); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(11), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_PAD_TXG, 0x003ff, 0x1e0); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44ffbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + + /* Enter IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82170000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28170000); + + /* RX IQK setting */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a8d1); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_RXA) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + /* Leave IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_GAIN_CCA, BIT(11), 0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_P1, 0x02000); + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000)) + result |= 0x02; + + return result; +} + +static int rtl8192fu_iqk_path_b(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_eb4, reg_ebc, val32; + u32 rf_0x58_i, rf_0x58_q; + u8 rfe = priv->rfe_type; + int result = 0; + int ktime, i; + + /* PA/PAD controlled by 0x0 */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44ffbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(4), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(11), 1); + if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_PAD_TXG, + 0x003ff, 0x30); + else + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_PAD_TXG, + 0x00fff, 0xe9); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* Path B IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x8214000F); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28140000); + + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00e62911); + + /* One shot, path B LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_TXB) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + + /* reload 0xdf and CCK_IND off */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_WE_LUT, BIT(4), 1); + + val32 = rtl8xxxu_read_rfreg(priv, RF_B, RF6052_REG_TXMOD); + rf_0x58_i = u32_get_bits(val32, 0xfc000); + rf_0x58_q = u32_get_bits(val32, 0x003f0); + + for (i = 0; i < 8; i++) { + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3, + 0x1c000, i); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3, + 0x00fc0, rf_0x58_i); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3, + 0x0003f, rf_0x58_q); + } + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_AC, BIT(14), 0); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_WE_LUT, BIT(4), 0); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00810, 0); + + if (!(reg_eac & BIT(31)) && + ((reg_eb4 & 0x03ff0000) != 0x01420000) && + ((reg_ebc & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else + dev_warn(&priv->udev->dev, "%s: Path B IQK failed!\n", + __func__); + + return result; +} + +static int rtl8192fu_rx_iqk_path_b(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc, val32; + int result = 0; + int ktime; + + /* Leave IQK mode */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(1), 1); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_P1, 0); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(11), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_PAD_TXG, 0x003ff, 0x67); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44ffbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* path-B IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82160027); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28160000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0086a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_TXB) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + + if (!(reg_eac & BIT(31)) && + ((reg_eb4 & 0x03ff0000) != 0x01420000) && + ((reg_ebc & 0x03ff0000) != 0x00420000)) { + result |= 0x01; + } else { + /* PA/PAD controlled by 0x0 */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, + BIT(11), 0); + + return result; + } + + val32 = 0x80007c00 | (reg_eb4 & 0x03ff0000) | ((reg_ebc >> 16) & 0x03ff); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* Modify RX IQK mode table */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(1), 1); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_P1, 0); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(11), 1); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_PAD_TXG, 0x003ff, 0x1e0); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0); + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44ffbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + + /* Path B IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x18008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82170000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28170000); + + /* IQK setting */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800); + + mdelay(15); + + ktime = 0; + while (rtl8xxxu_read32(priv, REG_IQK_RPT_RXB) == 0 && ktime < 21) { + mdelay(5); + ktime += 5; + } + + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); + reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(11), 0); + rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_GAIN_CCA, BIT(1), 0); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_P1, 0x02000); + + if (!(reg_eac & BIT(30)) && + ((reg_ec4 & 0x03ff0000) != 0x01320000) && + ((reg_ecc & 0x03ff0000) != 0x00360000)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n", + __func__); + + return result; +} + +static void rtl8192fu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + static const u32 adda_regs[2] = { + REG_ANAPWR1, REG_RX_WAIT_CCA + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_DPDT_CTRL, REG_RFE_CTRL_ANTA_SRC, + REG_RFE_CTRL_ANT_SRC2, REG_CCK0_AFE_SETTING + }; + u32 rx_initial_gain_a, rx_initial_gain_b; + struct device *dev = &priv->udev->dev; + int path_a_ok, path_b_ok; + u8 rfe = priv->rfe_type; + int retry = 2; + u32 i, val32; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rx_initial_gain_a = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + rx_initial_gain_b = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1); + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + ARRAY_SIZE(adda_regs)); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + /* Instead of rtl8xxxu_path_adda_on */ + rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, BIT(31)); + + /* MAC settings */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + rtl8xxxu_write8_clear(priv, REG_GPIO_MUXCFG, GPIO_MUXCFG_IO_SEL_ENBT); + + if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) { + /* in ePA IQK, rfe_func_config & SW both pull down */ + /* path A */ + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x1, 0x0); + + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF00, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x4, 0x0); + + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF000, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x8, 0x0); + + /* path B */ + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC2, 0xF0, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x20000, 0x0); + + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC2, 0xF0000, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x100000, 0x0); + + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC3, 0xF000, 0x7); + rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x8000000, 0x0); + } + + if (priv->rf_paths > 1) { + /* path B standby */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x000000); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0x10000); + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000); + } + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8192fu_iqk_path_a(priv); + + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][0] = 0x100; + result[t][1] = 0x0; + } + } + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8192fu_rx_iqk_path_a(priv); + + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][2] = 0x100; + result[t][3] = 0x0; + } + } + + if (!path_a_ok) + dev_warn(dev, "%s: Path A IQK failed!\n", __func__); + + if (priv->rf_paths > 1) { + for (i = 0; i < retry; i++) { + path_b_ok = rtl8192fu_iqk_path_b(priv); + + if (path_b_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + result[t][4] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + result[t][5] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][4] = 0x100; + result[t][5] = 0x0; + } + } + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8192fu_rx_iqk_path_b(priv); + + if (path_b_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); + result[t][6] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); + result[t][7] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][6] = 0x100; + result[t][7] = 0x0; + } + } + + if (!path_b_ok) + dev_warn(dev, "%s: Path B IQK failed!\n", __func__); + } + + /* Back to BB mode, load original value */ + rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0); + + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xcc0000c0); + + rtl8xxxu_write32(priv, REG_ANAPWR1, 0x44bbbb44); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x80408040); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005433); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000004e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04003400); + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + ARRAY_SIZE(adda_regs)); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, priv->bb_backup, RTL8XXXU_BB_REGS); + + rtl8xxxu_write32_clear(priv, REG_FPGA0_XCD_RF_PARM, BIT(31)); + + /* Restore RX initial gain */ + rtl8xxxu_write32_mask(priv, REG_OFDM0_XA_AGC_CORE1, 0xff, 0x50); + rtl8xxxu_write32_mask(priv, REG_OFDM0_XA_AGC_CORE1, 0xff, + rx_initial_gain_a & 0xff); + if (priv->rf_paths > 1) { + rtl8xxxu_write32_mask(priv, REG_OFDM0_XB_AGC_CORE1, 0xff, 0x50); + rtl8xxxu_write32_mask(priv, REG_OFDM0_XB_AGC_CORE1, 0xff, + rx_initial_gain_b & 0xff); + } +} + +static void rtl8192fu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + s32 reg_e94, reg_e9c, reg_ea4, reg_eac; + s32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + struct device *dev = &priv->udev->dev; + u32 path_a_0xdf, path_a_0x35; + u32 path_b_0xdf, path_b_0x35; + bool path_a_ok, path_b_ok; + u8 rfe = priv->rfe_type; + u32 rfe_path_select; + int result[4][8]; /* last is final result */ + int i, candidate; + s32 reg_tmp = 0; + bool simu; + u32 val32; + + rfe_path_select = rtl8xxxu_read32(priv, REG_RFE_PATH_SELECT); + + path_a_0xdf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + path_a_0x35 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_P1); + path_b_0xdf = rtl8xxxu_read_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA); + path_b_0x35 = rtl8xxxu_read_rfreg(priv, RF_B, RF6052_REG_GAIN_P1); + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + path_b_ok = false; + + for (i = 0; i < 3; i++) { + rtl8192fu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2); + if (simu) { + candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp) + candidate = 3; + else + candidate = -1; + } + } + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + reg_e9c = result[candidate][1]; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + reg_ebc = result[candidate][5]; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, "%s: e94=%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%c\n", + __func__, reg_e94, reg_e9c, reg_ea4, reg_eac, + reg_eb4, reg_ebc, reg_ec4, reg_ecc); + + path_a_ok = true; + path_b_ok = true; + } + + rtl8xxxu_write32_mask(priv, REG_TX_IQK_TONE_A, 0x3ff00000, 0x100); + rtl8xxxu_write32_mask(priv, REG_NP_ANTA, 0x3ff, 0); + rtl8xxxu_write32_mask(priv, REG_TX_IQK_TONE_B, 0x3ff00000, 0x100); + rtl8xxxu_write32_mask(priv, REG_TAP_UPD_97F, 0x3ff, 0); + + if (candidate >= 0) { + if (reg_e94) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + if (reg_eb4) + rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, + candidate, (reg_ec4 == 0)); + } + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, path_a_0xdf); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_P1, path_a_0x35); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, path_b_0xdf); + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_P1, path_b_0x35); + + if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) { + rtl8xxxu_write32_set(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x70000); + rtl8xxxu_write32_clear(priv, REG_LEDCFG0, 0x6c00000); + rtl8xxxu_write32_set(priv, REG_PAD_CTRL1, BIT(29) | BIT(28)); + rtl8xxxu_write32_clear(priv, REG_SW_GPIO_SHARE_CTRL_0, + 0x600000 | BIT(4)); + + /* + * Originally: + * odm_set_bb_reg(dm, R_0x944, BIT(11) | 0x1F, 0x3F); + * + * It clears bit 11 and sets bits 0..4. The mask doesn't cover + * bit 5 so it's not modified. Is that what it's supposed to + * accomplish? + */ + val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); + val32 &= ~BIT(11); + val32 |= 0x1f; + rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); + + if (rfe == 7) { + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, + 0xfffff, 0x23200); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC2, + 0xfffff, 0x23200); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC1, + 0xf000, 0x3); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC3, + 0xf000, 0x3); + } else { + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, + 0xfffff, 0x22200); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC2, + 0xfffff, 0x22200); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC1, + 0xf000, 0x2); + rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANT_SRC3, + 0xf000, 0x2); + } + + rtl8xxxu_write32_clear(priv, REG_RFE_OPT62, BIT(2)); + + if (rfe == 7) + rtl8xxxu_write32(priv, REG_RFE_OPT, 0x03000003); + + rtl8xxxu_write32(priv, REG_RFE_PATH_SELECT, rfe_path_select); + } +} + +static void rtl8192fu_disabled_to_emu(struct rtl8xxxu_priv *priv) +{ + rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, + APS_FSMCO_HW_POWERDOWN | APS_FSMCO_HW_SUSPEND); + + rtl8xxxu_write32_clear(priv, REG_GPIO_INTM, BIT(16)); + + rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, + APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND); +} + +static int rtl8192fu_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u16 val16; + int count; + + /* enable LDOA12 MACRO block for all interface */ + rtl8xxxu_write8_set(priv, REG_LDOA15_CTRL, LDOA15_ENABLE); + + /* disable BT_GPS_SEL pins */ + rtl8xxxu_write32_clear(priv, REG_PAD_CTRL1, BIT(28)); + + mdelay(1); + + /* release analog Ips to digital */ + rtl8xxxu_write8_clear(priv, REG_SYS_ISO_CTRL, SYS_ISO_ANALOG_IPS); + + val16 = APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND | APS_FSMCO_SW_LPS; + rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, val16); + + /* wait till 0x04[17] = 1 power ready */ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) + return -EBUSY; + + rtl8xxxu_write32_set(priv, REG_APS_FSMCO, APS_FSMCO_WLON_RESET); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & (APS_FSMCO_MAC_ENABLE | APS_FSMCO_MAC_OFF)) == 0) + break; + + udelay(10); + } + + if (!count) + return -EBUSY; + + /* SWR OCP enable */ + rtl8xxxu_write32_set(priv, REG_AFE_MISC, BIT(18)); + + rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); + + rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, + APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND); + + /* 0x7c[31]=1, LDO has max output capability */ + rtl8xxxu_write32_set(priv, REG_LDO_SW_CTRL, BIT(31)); + + rtl8xxxu_write16_set(priv, REG_APS_FSMCO, APS_FSMCO_MAC_ENABLE); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) + break; + + udelay(10); + } + + if (!count) + return -EBUSY; + + /* Enable WL control XTAL setting */ + rtl8xxxu_write8_set(priv, REG_AFE_MISC, AFE_MISC_WL_XTAL_CTRL); + + /* Enable falling edge triggering interrupt */ + rtl8xxxu_write16_set(priv, REG_GPIO_INTM, GPIO_INTM_EDGE_TRIG_IRQ); + + /* Enable GPIO9 data mode */ + rtl8xxxu_write16_clear(priv, REG_GPIO_IO_SEL_2, GPIO_IO_SEL_2_GPIO09_IRQ); + + /* Enable GPIO9 input mode */ + rtl8xxxu_write16_clear(priv, REG_GPIO_IO_SEL_2, GPIO_IO_SEL_2_GPIO09_INPUT); + + /* Enable HSISR GPIO[C:0] interrupt */ + rtl8xxxu_write8_set(priv, REG_HSIMR, BIT(0)); + + /* RF HW ON/OFF Enable */ + rtl8xxxu_write8_clear(priv, REG_MULTI_FUNC_CTRL, MULTI_WIFI_HW_ROF_EN); + + /* Register Lock Disable */ + rtl8xxxu_write8_set(priv, REG_RSV_CTRL, BIT(7)); + + /* For GPIO9 internal pull high setting */ + rtl8xxxu_write16_set(priv, REG_MULTI_FUNC_CTRL, BIT(14)); + + /* reset RF path S1 */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0); + + /* reset RF path S0 */ + rtl8xxxu_write8(priv, REG_AFE_CTRL4 + 3, 0); + + /* enable RF path S1 */ + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_SDMRSTB | RF_RSTB | RF_ENABLE); + + /* enable RF path S0 */ + rtl8xxxu_write8(priv, REG_AFE_CTRL4 + 3, RF_SDMRSTB | RF_RSTB | RF_ENABLE); + + /* AFE_Ctrl */ + rtl8xxxu_write8_set(priv, REG_RSVD_1, BIT(5)); + + /* AFE_Ctrl */ + rtl8xxxu_write8(priv, REG_RSVD_4, 0xcc); + + /* AFE_Ctrl 0x24[4:3]=00 for xtal gmn */ + rtl8xxxu_write8_clear(priv, REG_AFE_XTAL_CTRL, BIT(4) | BIT(3)); + + /* GPIO_A[31:0] Pull down software register */ + rtl8xxxu_write32(priv, REG_GPIO_A0, 0xffffffff); + + /* GPIO_B[7:0] Pull down software register */ + rtl8xxxu_write8(priv, REG_GPIO_B0, 0xff); + + /* Register Lock Enable */ + rtl8xxxu_write8_clear(priv, REG_RSV_CTRL, BIT(7)); + + return 0; +} + +static int rtl8192fu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u32 val32; + int count; + + /* Reset BB, RF enter Power Down mode */ + rtl8xxxu_write8_clear(priv, REG_SYS_FUNC, SYS_FUNC_BBRSTB); + + /* Enable rising edge triggering interrupt */ + rtl8xxxu_write16_clear(priv, REG_GPIO_INTM, GPIO_INTM_EDGE_TRIG_IRQ); + + /* release WLON reset */ + rtl8xxxu_write32_set(priv, REG_APS_FSMCO, APS_FSMCO_WLON_RESET); + + /* turn off MAC by HW state machine */ + rtl8xxxu_write16_set(priv, REG_APS_FSMCO, APS_FSMCO_MAC_OFF); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_OFF) == 0) + break; + + udelay(10); + } + + if (!count) + return -EBUSY; + + /* analog Ips to digital, 1:isolation */ + rtl8xxxu_write8_set(priv, REG_SYS_ISO_CTRL, SYS_ISO_ANALOG_IPS); + + /* disable LDOA12 MACRO block */ + rtl8xxxu_write8_clear(priv, REG_LDOA15_CTRL, LDOA15_ENABLE); + + return 0; +} + +static int rtl8192fu_emu_to_disabled(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + /* SOP option to disable BG/MB */ + rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20); + + /* 0x04[12:11] = 2b'01 enable WL suspend */ + val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO); + val16 &= ~APS_FSMCO_PCIE; + val16 |= APS_FSMCO_HW_SUSPEND; + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); + + /* enable GPIO9 as EXT WAKEUP */ + rtl8xxxu_write32_set(priv, REG_GPIO_INTM, BIT(16)); + + return 0; +} + +static int rtl8192fu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u16 val16; + u32 val32; + int retry; + + /* Tx Pause */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + retry = 100; + + /* Poll 32 bit wide REG_SCH_TX_CMD for 0 to ensure no TX is pending. */ + do { + val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); + if (!val32) + break; + + udelay(10); + } while (retry--); + + if (!retry) { + dev_warn(dev, "%s: Failed to flush TX queue\n", __func__); + return -EBUSY; + } + + /* Disable CCK and OFDM, clock gated */ + rtl8xxxu_write8_clear(priv, REG_SYS_FUNC, SYS_FUNC_BBRSTB); + + udelay(2); + + /* Whole BB is reset */ + rtl8xxxu_write8_clear(priv, REG_SYS_FUNC, SYS_FUNC_BB_GLB_RSTN); + + /* Reset MAC TRX */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 &= 0xff00; + val16 |= CR_HCI_RXDMA_ENABLE | CR_HCI_TXDMA_ENABLE; + val16 &= ~CR_SECURITY_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + /* Respond TxOK to scheduler */ + rtl8xxxu_write8_set(priv, REG_DUAL_TSF_RST, DUAL_TSF_TX_OK); + + return 0; +} + +static int rtl8192fu_power_on(struct rtl8xxxu_priv *priv) +{ + u16 val16; + int ret; + + rtl8xxxu_write8(priv, REG_USB_ACCESS_TIMEOUT, 0x80); + + rtl8192fu_disabled_to_emu(priv); + + ret = rtl8192fu_emu_to_active(priv); + if (ret) + return ret; + + rtl8xxxu_write16(priv, REG_CR, 0); + + val16 = rtl8xxxu_read16(priv, REG_CR); + + val16 |= CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + return 0; +} + +static void rtl8192fu_power_off(struct rtl8xxxu_priv *priv) +{ + rtl8xxxu_flush_fifo(priv); + + /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ + rtl8xxxu_write8_clear(priv, REG_TX_REPORT_CTRL, + TX_REPORT_CTRL_TIMER_ENABLE); + + /* stop rx */ + rtl8xxxu_write8(priv, REG_CR, 0x00); + + rtl8192fu_active_to_lps(priv); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + /* Reset MCU */ + rtl8xxxu_write16_clear(priv, REG_SYS_FUNC, SYS_FUNC_CPU_ENABLE); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8192fu_active_to_emu(priv); + rtl8192fu_emu_to_disabled(priv); +} + +static void rtl8192f_reset_8051(struct rtl8xxxu_priv *priv) +{ + rtl8xxxu_write8_clear(priv, REG_RSV_CTRL, BIT(1)); + + rtl8xxxu_write8_clear(priv, REG_RSV_CTRL + 1, BIT(0)); + + rtl8xxxu_write16_clear(priv, REG_SYS_FUNC, SYS_FUNC_CPU_ENABLE); + + rtl8xxxu_write8_clear(priv, REG_RSV_CTRL, BIT(1)); + + rtl8xxxu_write8_set(priv, REG_RSV_CTRL + 1, BIT(0)); + + rtl8xxxu_write16_set(priv, REG_SYS_FUNC, SYS_FUNC_CPU_ENABLE); +} + +static void rtl8192f_enable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); + val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_RX_B | + OFDM_RF_PATH_TX_A | OFDM_RF_PATH_TX_B; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static void rtl8192f_disable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + /* Power down RF module */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); +} + +static void rtl8192f_usb_quirks(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + rtl8xxxu_gen2_usb_quirks(priv); + + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); +} + +#define XTAL1 GENMASK(6, 1) +#define XTAL0 GENMASK(30, 25) + +static void rtl8192f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + u32 xtal1, xtal0; + + if (crystal_cap == cfo->crystal_cap) + return; + + xtal1 = rtl8xxxu_read32(priv, REG_AFE_PLL_CTRL); + xtal0 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL); + + dev_dbg(&priv->udev->dev, + "%s: Adjusting crystal cap from 0x%x (actually 0x%x 0x%x) to 0x%x\n", + __func__, + cfo->crystal_cap, + u32_get_bits(xtal1, XTAL1), + u32_get_bits(xtal0, XTAL0), + crystal_cap); + + u32p_replace_bits(&xtal1, crystal_cap, XTAL1); + u32p_replace_bits(&xtal0, crystal_cap, XTAL0); + rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, xtal1); + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, xtal0); + + cfo->crystal_cap = crystal_cap; +} + +static s8 rtl8192f_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + struct jaguar2_phy_stats_type0 *phy_stats0 = (struct jaguar2_phy_stats_type0 *)phy_stats; + u8 lna_idx = (phy_stats0->lna_h << 3) | phy_stats0->lna_l; + u8 vga_idx = phy_stats0->vga; + s8 rx_pwr_all; + + switch (lna_idx) { + case 7: + rx_pwr_all = -44 - (2 * vga_idx); + break; + case 5: + rx_pwr_all = -28 - (2 * vga_idx); + break; + case 3: + rx_pwr_all = -10 - (2 * vga_idx); + break; + case 0: + rx_pwr_all = 14 - (2 * vga_idx); + break; + default: + rx_pwr_all = 0; + break; + } + + return rx_pwr_all; +} + +static int rtl8192fu_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u32 ledcfg; + + /* Values obtained by observing the USB traffic from the Windows driver. */ + rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_0, 0x20080); + rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x1b0000); + + ledcfg = rtl8xxxu_read32(priv, REG_LEDCFG0); + + /* Comfast CF-826F uses LED1. Asus USB-N13 C1 uses LED0. Set both. */ + + u32p_replace_bits(&ledcfg, LED_GPIO_ENABLE, LEDCFG0_LED2EN); + u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED0_IO_MODE); + u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED1_IO_MODE); + + if (brightness == LED_OFF) { + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); + } else if (brightness == LED_ON) { + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); + u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED0SV); + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); + u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED1SV); + } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { + u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, + LEDCFG0_LED0CM); + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); + u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, + LEDCFG0_LED1CM); + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); + } + + rtl8xxxu_write32(priv, REG_LEDCFG0, ledcfg); + + return 0; +} + +struct rtl8xxxu_fileops rtl8192fu_fops = { + .identify_chip = rtl8192fu_identify_chip, + .parse_efuse = rtl8192fu_parse_efuse, + .load_firmware = rtl8192fu_load_firmware, + .power_on = rtl8192fu_power_on, + .power_off = rtl8192fu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8192f_reset_8051, + .llt_init = rtl8xxxu_auto_llt_table, + .init_phy_bb = rtl8192fu_init_phy_bb, + .init_phy_rf = rtl8192fu_init_phy_rf, + .phy_lc_calibrate = rtl8192f_phy_lc_calibrate, + .phy_iq_calibrate = rtl8192fu_phy_iq_calibrate, + .config_channel = rtl8192fu_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc24, + .parse_phystats = jaguar2_rx_parse_phystats, + .init_aggregation = rtl8192fu_init_aggregation, + .init_burst = rtl8xxxu_init_burst, + .enable_rf = rtl8192f_enable_rf, + .disable_rf = rtl8192f_disable_rf, + .usb_quirks = rtl8192f_usb_quirks, + .set_tx_power = rtl8192f_set_tx_power, + .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8xxxu_gen2_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v2, + .set_crystal_cap = rtl8192f_set_crystal_cap, + .cck_rssi = rtl8192f_cck_rssi, + .led_classdev_brightness_set = rtl8192fu_led_brightness_set, + .writeN_block_size = 254, + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), + .has_tx_report = 1, + .gen2_thermal_meter = 1, + .needs_full_init = 1, + .init_reg_rxfltmap = 1, + .init_reg_pkt_life_time = 1, + .init_reg_hmtfr = 1, + .hw_feature_report = 1, + .ampdu_max_time = 0x5e, + .ustime_tsf_edca = 0x50, + .max_aggr_num = 0x1f1f, + .supports_ap = 1, + .max_macid_num = 128, + .max_sec_cam_num = 64, + .trxff_boundary = 0x3f3f, + .pbp_rx = PBP_PAGE_SIZE_256, + .pbp_tx = PBP_PAGE_SIZE_256, + .mactable = rtl8192f_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8192F, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8192F, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8192F, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8192F, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8710b.c b/drivers/net/wireless/realtek/rtl8xxxu/8710b.c new file mode 100644 index 000000000..a87e692bf --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8710b.c @@ -0,0 +1,1876 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8710bu aka 8188gu specific subdriver + * + * Copyright (c) 2023 Bitterblue Smith + * + * Portions copied from existing rtl8xxxu code: + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8710b_mac_init_table[] = { + {0x421, 0x0F}, {0x428, 0x0A}, {0x429, 0x10}, {0x430, 0x00}, + {0x431, 0x00}, {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, + {0x435, 0x05}, {0x436, 0x07}, {0x437, 0x08}, {0x43C, 0x04}, + {0x43D, 0x05}, {0x43E, 0x07}, {0x43F, 0x08}, {0x440, 0x5D}, + {0x441, 0x01}, {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, + {0x446, 0x00}, {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xF0}, + {0x44A, 0x0F}, {0x44B, 0x3E}, {0x44C, 0x10}, {0x44D, 0x00}, + {0x44E, 0x00}, {0x44F, 0x00}, {0x450, 0x00}, {0x451, 0xF0}, + {0x452, 0x0F}, {0x453, 0x00}, {0x456, 0x5E}, {0x460, 0x66}, + {0x461, 0x66}, {0x4C8, 0xFF}, {0x4C9, 0x08}, {0x4CC, 0xFF}, + {0x4CD, 0xFF}, {0x4CE, 0x01}, {0x500, 0x26}, {0x501, 0xA2}, + {0x502, 0x2F}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xA3}, + {0x506, 0x5E}, {0x507, 0x00}, {0x508, 0x2B}, {0x509, 0xA4}, + {0x50A, 0x5E}, {0x50B, 0x00}, {0x50C, 0x4F}, {0x50D, 0xA4}, + {0x50E, 0x00}, {0x50F, 0x00}, {0x512, 0x1C}, {0x514, 0x0A}, + {0x516, 0x0A}, {0x525, 0x4F}, {0x550, 0x10}, {0x551, 0x10}, + {0x559, 0x02}, {0x55C, 0x28}, {0x55D, 0xFF}, {0x605, 0x30}, + {0x608, 0x0E}, {0x609, 0x2A}, {0x620, 0xFF}, {0x621, 0xFF}, + {0x622, 0xFF}, {0x623, 0xFF}, {0x624, 0xFF}, {0x625, 0xFF}, + {0x626, 0xFF}, {0x627, 0xFF}, {0x638, 0x28}, {0x63C, 0x0A}, + {0x63D, 0x0A}, {0x63E, 0x0C}, {0x63F, 0x0C}, {0x640, 0x40}, + {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xC8}, {0x66A, 0xB0}, + {0x66E, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, + {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70A, 0x65}, + {0x70B, 0x87}, + {0xffff, 0xff}, +}; + +/* If updating the phy init tables, also update rtl8710b_revise_cck_tx_psf(). */ +static const struct rtl8xxxu_reg32val rtl8710bu_qfn48m_u_phy_init_table[] = { + {0x800, 0x80045700}, {0x804, 0x00000001}, + {0x808, 0x00FC8000}, {0x80C, 0x0000000A}, + {0x810, 0x10001331}, {0x814, 0x020C3D10}, + {0x818, 0x00200385}, {0x81C, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x00000000}, {0x82C, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83C, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84C, 0x00000000}, + {0x850, 0x00030000}, {0x854, 0x00000000}, + {0x858, 0x7E1A569A}, {0x85C, 0x569A569A}, + {0x860, 0x00000130}, {0x864, 0x20000000}, + {0x868, 0x00000000}, {0x86C, 0x27272700}, + {0x870, 0x00050000}, {0x874, 0x25005000}, + {0x878, 0x00000808}, {0x87C, 0x004F0201}, + {0x880, 0xB0000B1E}, {0x884, 0x00000007}, + {0x888, 0x00000000}, {0x88C, 0xCCC400C0}, + {0x890, 0x00000800}, {0x894, 0xFFFFFFFE}, + {0x898, 0x40302010}, {0x89C, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90C, 0x81121111}, + {0x910, 0x00000402}, {0x914, 0x00000201}, + {0x920, 0x18C6318C}, {0x924, 0x0000018C}, + {0x948, 0x99000000}, {0x94C, 0x00000010}, + {0x950, 0x00003000}, {0x954, 0x5A880000}, + {0x958, 0x4BC6D87A}, {0x95C, 0x04EB9B79}, + {0x96C, 0x00000003}, {0x970, 0x00000000}, + {0x974, 0x00000000}, {0x978, 0x00000000}, + {0x97C, 0x13000000}, {0x980, 0x00000000}, + {0xA00, 0x00D046C8}, {0xA04, 0x80FF800C}, + {0xA08, 0x84838300}, {0xA0C, 0x2E20100F}, + {0xA10, 0x9500BB78}, {0xA14, 0x1114D028}, + {0xA18, 0x00881117}, {0xA1C, 0x89140F00}, + {0xA20, 0xE82C0001}, {0xA24, 0x64B80C1C}, + {0xA28, 0x00008810}, {0xA2C, 0x00D30000}, + {0xA70, 0x101FBF00}, {0xA74, 0x00000007}, + {0xA78, 0x00000900}, {0xA7C, 0x225B0606}, + {0xA80, 0x218075B1}, {0xA84, 0x00200000}, + {0xA88, 0x040C0000}, {0xA8C, 0x12345678}, + {0xA90, 0xABCDEF00}, {0xA94, 0x001B1B89}, + {0xA98, 0x00000000}, {0xA9C, 0x80020000}, + {0xAA0, 0x00000000}, {0xAA4, 0x0000000C}, + {0xAA8, 0xCA110058}, {0xAAC, 0x01235667}, + {0xAB0, 0x00000000}, {0xAB4, 0x20201402}, + {0xB2C, 0x00000000}, {0xC00, 0x48071D40}, + {0xC04, 0x03A05611}, {0xC08, 0x000000E4}, + {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000}, + {0xC14, 0x40000100}, {0xC18, 0x08800000}, + {0xC1C, 0x40000100}, {0xC20, 0x00000000}, + {0xC24, 0x00000000}, {0xC28, 0x00000000}, + {0xC2C, 0x00000000}, {0xC30, 0x69E9AC4A}, + {0xC34, 0x31000040}, {0xC38, 0x21688080}, + {0xC3C, 0x0000170C}, {0xC40, 0x1F78403F}, + {0xC44, 0x00010036}, {0xC48, 0xEC020107}, + {0xC4C, 0x007F037F}, {0xC50, 0x69553420}, + {0xC54, 0x43BC0094}, {0xC58, 0x00013169}, + {0xC5C, 0x00250492}, {0xC60, 0x00280A00}, + {0xC64, 0x7112848B}, {0xC68, 0x47C074FF}, + {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D}, + {0xC74, 0x020600DB}, {0xC78, 0x0000001F}, + {0xC7C, 0x00B91612}, {0xC80, 0x390000E4}, + {0xC84, 0x11F60000}, {0xC88, 0x1051B75F}, + {0xC8C, 0x20200109}, {0xC90, 0x00091521}, + {0xC94, 0x00000000}, {0xC98, 0x00121820}, + {0xC9C, 0x00007F7F}, {0xCA0, 0x00011000}, + {0xCA4, 0x800000A0}, {0xCA8, 0x84E6C606}, + {0xCAC, 0x00000060}, {0xCB0, 0x00000000}, + {0xCB4, 0x00000000}, {0xCB8, 0x00000000}, + {0xCBC, 0x28000000}, {0xCC0, 0x1051B75F}, + {0xCC4, 0x00000109}, {0xCC8, 0x000442D6}, + {0xCCC, 0x00000000}, {0xCD0, 0x000001C8}, + {0xCD4, 0x001C8000}, {0xCD8, 0x00000100}, + {0xCDC, 0x40100000}, {0xCE0, 0x00222220}, + {0xCE4, 0x10000000}, {0xCE8, 0x37644302}, + {0xCEC, 0x2F97D40C}, {0xD00, 0x04030740}, + {0xD04, 0x40020401}, {0xD08, 0x0000907F}, + {0xD0C, 0x20010201}, {0xD10, 0xA0633333}, + {0xD14, 0x3333BC53}, {0xD18, 0x7A8F5B6F}, + {0xD2C, 0xCB979975}, {0xD30, 0x00000000}, + {0xD34, 0x40608000}, {0xD38, 0x88000000}, + {0xD3C, 0xC0127353}, {0xD40, 0x00000000}, + {0xD44, 0x00000000}, {0xD48, 0x00000000}, + {0xD4C, 0x00000000}, {0xD50, 0x00006528}, + {0xD54, 0x00000000}, {0xD58, 0x00000282}, + {0xD5C, 0x30032064}, {0xD60, 0x4653DE68}, + {0xD64, 0x04518A3C}, {0xD68, 0x00002101}, + {0xE00, 0x2D2D2D2D}, {0xE04, 0x2D2D2D2D}, + {0xE08, 0x0390272D}, {0xE10, 0x2D2D2D2D}, + {0xE14, 0x2D2D2D2D}, {0xE18, 0x2D2D2D2D}, + {0xE1C, 0x2D2D2D2D}, {0xE28, 0x00000000}, + {0xE30, 0x1000DC1F}, {0xE34, 0x10008C1F}, + {0xE38, 0x02140102}, {0xE3C, 0x681604C2}, + {0xE40, 0x01007C00}, {0xE44, 0x01004800}, + {0xE48, 0xFB000000}, {0xE4C, 0x000028D1}, + {0xE50, 0x1000DC1F}, {0xE54, 0x10008C1F}, + {0xE58, 0x02140102}, {0xE5C, 0x28160D05}, + {0xE60, 0x0000C008}, {0xE68, 0x001B25A4}, + {0xE64, 0x281600A0}, {0xE6C, 0x01C00010}, + {0xE70, 0x01C00010}, {0xE74, 0x02000010}, + {0xE78, 0x02000010}, {0xE7C, 0x02000010}, + {0xE80, 0x02000010}, {0xE84, 0x01C00010}, + {0xE88, 0x02000010}, {0xE8C, 0x01C00010}, + {0xED0, 0x01C00010}, {0xED4, 0x01C00010}, + {0xED8, 0x01C00010}, {0xEDC, 0x00000010}, + {0xEE0, 0x00000010}, {0xEEC, 0x03C00010}, + {0xF14, 0x00000003}, {0xF00, 0x00100300}, + {0xF08, 0x0000800B}, {0xF0C, 0x0000F007}, + {0xF10, 0x0000A487}, {0xF1C, 0x80000064}, + {0xF38, 0x00030155}, {0xF3C, 0x0000003A}, + {0xF4C, 0x13000000}, {0xF50, 0x00000000}, + {0xF18, 0x00000000}, + {0xffff, 0xffffffff}, +}; + +/* If updating the phy init tables, also update rtl8710b_revise_cck_tx_psf(). */ +static const struct rtl8xxxu_reg32val rtl8710bu_qfn48m_s_phy_init_table[] = { + {0x800, 0x80045700}, {0x804, 0x00000001}, + {0x808, 0x00FC8000}, {0x80C, 0x0000000A}, + {0x810, 0x10001331}, {0x814, 0x020C3D10}, + {0x818, 0x00200385}, {0x81C, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390204}, + {0x828, 0x00000000}, {0x82C, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83C, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84C, 0x00000000}, + {0x850, 0x00030000}, {0x854, 0x00000000}, + {0x858, 0x7E1A569A}, {0x85C, 0x569A569A}, + {0x860, 0x00000130}, {0x864, 0x20000000}, + {0x868, 0x00000000}, {0x86C, 0x27272700}, + {0x870, 0x00050000}, {0x874, 0x25005000}, + {0x878, 0x00000808}, {0x87C, 0x004F0201}, + {0x880, 0xB0000B1E}, {0x884, 0x00000007}, + {0x888, 0x00000000}, {0x88C, 0xCCC400C0}, + {0x890, 0x00000800}, {0x894, 0xFFFFFFFE}, + {0x898, 0x40302010}, {0x89C, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90C, 0x81121111}, + {0x910, 0x00000402}, {0x914, 0x00000201}, + {0x920, 0x18C6318C}, {0x924, 0x0000018C}, + {0x948, 0x99000000}, {0x94C, 0x00000010}, + {0x950, 0x00003000}, {0x954, 0x5A880000}, + {0x958, 0x4BC6D87A}, {0x95C, 0x04EB9B79}, + {0x96C, 0x00000003}, {0x970, 0x00000000}, + {0x974, 0x00000000}, {0x978, 0x00000000}, + {0x97C, 0x13000000}, {0x980, 0x00000000}, + {0xA00, 0x00D046C8}, {0xA04, 0x80FF800C}, + {0xA08, 0x84838300}, {0xA0C, 0x2A20100F}, + {0xA10, 0x9500BB78}, {0xA14, 0x1114D028}, + {0xA18, 0x00881117}, {0xA1C, 0x89140F00}, + {0xA20, 0xE82C0001}, {0xA24, 0x64B80C1C}, + {0xA28, 0x00008810}, {0xA2C, 0x00D30000}, + {0xA70, 0x101FBF00}, {0xA74, 0x00000007}, + {0xA78, 0x00000900}, {0xA7C, 0x225B0606}, + {0xA80, 0x218075B1}, {0xA84, 0x00200000}, + {0xA88, 0x040C0000}, {0xA8C, 0x12345678}, + {0xA90, 0xABCDEF00}, {0xA94, 0x001B1B89}, + {0xA98, 0x00000000}, {0xA9C, 0x80020000}, + {0xAA0, 0x00000000}, {0xAA4, 0x0000000C}, + {0xAA8, 0xCA110058}, {0xAAC, 0x01235667}, + {0xAB0, 0x00000000}, {0xAB4, 0x20201402}, + {0xB2C, 0x00000000}, {0xC00, 0x48071D40}, + {0xC04, 0x03A05611}, {0xC08, 0x000000E4}, + {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000}, + {0xC14, 0x40000100}, {0xC18, 0x08800000}, + {0xC1C, 0x40000100}, {0xC20, 0x00000000}, + {0xC24, 0x00000000}, {0xC28, 0x00000000}, + {0xC2C, 0x00000000}, {0xC30, 0x69E9AC4A}, + {0xC34, 0x31000040}, {0xC38, 0x21688080}, + {0xC3C, 0x0000170C}, {0xC40, 0x1F78403F}, + {0xC44, 0x00010036}, {0xC48, 0xEC020107}, + {0xC4C, 0x007F037F}, {0xC50, 0x69553420}, + {0xC54, 0x43BC0094}, {0xC58, 0x00013169}, + {0xC5C, 0x00250492}, {0xC60, 0x00280A00}, + {0xC64, 0x7112848B}, {0xC68, 0x47C074FF}, + {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D}, + {0xC74, 0x020600DB}, {0xC78, 0x0000001F}, + {0xC7C, 0x00B91612}, {0xC80, 0x390000E4}, + {0xC84, 0x11F60000}, {0xC88, 0x1051B75F}, + {0xC8C, 0x20200109}, {0xC90, 0x00091521}, + {0xC94, 0x00000000}, {0xC98, 0x00121820}, + {0xC9C, 0x00007F7F}, {0xCA0, 0x00011000}, + {0xCA4, 0x800000A0}, {0xCA8, 0x84E6C606}, + {0xCAC, 0x00000060}, {0xCB0, 0x00000000}, + {0xCB4, 0x00000000}, {0xCB8, 0x00000000}, + {0xCBC, 0x28000000}, {0xCC0, 0x1051B75F}, + {0xCC4, 0x00000109}, {0xCC8, 0x000442D6}, + {0xCCC, 0x00000000}, {0xCD0, 0x000001C8}, + {0xCD4, 0x001C8000}, {0xCD8, 0x00000100}, + {0xCDC, 0x40100000}, {0xCE0, 0x00222220}, + {0xCE4, 0x10000000}, {0xCE8, 0x37644302}, + {0xCEC, 0x2F97D40C}, {0xD00, 0x04030740}, + {0xD04, 0x40020401}, {0xD08, 0x0000907F}, + {0xD0C, 0x20010201}, {0xD10, 0xA0633333}, + {0xD14, 0x3333BC53}, {0xD18, 0x7A8F5B6F}, + {0xD2C, 0xCB979975}, {0xD30, 0x00000000}, + {0xD34, 0x40608000}, {0xD38, 0x88000000}, + {0xD3C, 0xC0127353}, {0xD40, 0x00000000}, + {0xD44, 0x00000000}, {0xD48, 0x00000000}, + {0xD4C, 0x00000000}, {0xD50, 0x00006528}, + {0xD54, 0x00000000}, {0xD58, 0x00000282}, + {0xD5C, 0x30032064}, {0xD60, 0x4653DE68}, + {0xD64, 0x04518A3C}, {0xD68, 0x00002101}, + {0xE00, 0x2D2D2D2D}, {0xE04, 0x2D2D2D2D}, + {0xE08, 0x0390272D}, {0xE10, 0x2D2D2D2D}, + {0xE14, 0x2D2D2D2D}, {0xE18, 0x2D2D2D2D}, + {0xE1C, 0x2D2D2D2D}, {0xE28, 0x00000000}, + {0xE30, 0x1000DC1F}, {0xE34, 0x10008C1F}, + {0xE38, 0x02140102}, {0xE3C, 0x681604C2}, + {0xE40, 0x01007C00}, {0xE44, 0x01004800}, + {0xE48, 0xFB000000}, {0xE4C, 0x000028D1}, + {0xE50, 0x1000DC1F}, {0xE54, 0x10008C1F}, + {0xE58, 0x02140102}, {0xE5C, 0x28160D05}, + {0xE60, 0x0000C008}, {0xE68, 0x001B25A4}, + {0xE64, 0x281600A0}, {0xE6C, 0x01C00010}, + {0xE70, 0x01C00010}, {0xE74, 0x02000010}, + {0xE78, 0x02000010}, {0xE7C, 0x02000010}, + {0xE80, 0x02000010}, {0xE84, 0x01C00010}, + {0xE88, 0x02000010}, {0xE8C, 0x01C00010}, + {0xED0, 0x01C00010}, {0xED4, 0x01C00010}, + {0xED8, 0x01C00010}, {0xEDC, 0x00000010}, + {0xEE0, 0x00000010}, {0xEEC, 0x03C00010}, + {0xF14, 0x00000003}, {0xF00, 0x00100300}, + {0xF08, 0x0000800B}, {0xF0C, 0x0000F007}, + {0xF10, 0x0000A487}, {0xF1C, 0x80000064}, + {0xF38, 0x00030155}, {0xF3C, 0x0000003A}, + {0xF4C, 0x13000000}, {0xF50, 0x00000000}, + {0xF18, 0x00000000}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8710b_agc_table[] = { + {0xC78, 0xFC000001}, {0xC78, 0xFB010001}, + {0xC78, 0xFA020001}, {0xC78, 0xF9030001}, + {0xC78, 0xF8040001}, {0xC78, 0xF7050001}, + {0xC78, 0xF6060001}, {0xC78, 0xF5070001}, + {0xC78, 0xF4080001}, {0xC78, 0xF3090001}, + {0xC78, 0xF20A0001}, {0xC78, 0xF10B0001}, + {0xC78, 0xF00C0001}, {0xC78, 0xEF0D0001}, + {0xC78, 0xEE0E0001}, {0xC78, 0xED0F0001}, + {0xC78, 0xEC100001}, {0xC78, 0xEB110001}, + {0xC78, 0xEA120001}, {0xC78, 0xE9130001}, + {0xC78, 0xE8140001}, {0xC78, 0xE7150001}, + {0xC78, 0xE6160001}, {0xC78, 0xE5170001}, + {0xC78, 0xE4180001}, {0xC78, 0xE3190001}, + {0xC78, 0xE21A0001}, {0xC78, 0xE11B0001}, + {0xC78, 0xE01C0001}, {0xC78, 0xC31D0001}, + {0xC78, 0xC21E0001}, {0xC78, 0xC11F0001}, + {0xC78, 0xC0200001}, {0xC78, 0xA3210001}, + {0xC78, 0xA2220001}, {0xC78, 0xA1230001}, + {0xC78, 0xA0240001}, {0xC78, 0x86250001}, + {0xC78, 0x85260001}, {0xC78, 0x84270001}, + {0xC78, 0x83280001}, {0xC78, 0x82290001}, + {0xC78, 0x812A0001}, {0xC78, 0x802B0001}, + {0xC78, 0x632C0001}, {0xC78, 0x622D0001}, + {0xC78, 0x612E0001}, {0xC78, 0x602F0001}, + {0xC78, 0x42300001}, {0xC78, 0x41310001}, + {0xC78, 0x40320001}, {0xC78, 0x23330001}, + {0xC78, 0x22340001}, {0xC78, 0x21350001}, + {0xC78, 0x20360001}, {0xC78, 0x02370001}, + {0xC78, 0x01380001}, {0xC78, 0x00390001}, + {0xC78, 0x003A0001}, {0xC78, 0x003B0001}, + {0xC78, 0x003C0001}, {0xC78, 0x003D0001}, + {0xC78, 0x003E0001}, {0xC78, 0x003F0001}, + {0xC78, 0xF7400001}, {0xC78, 0xF7410001}, + {0xC78, 0xF7420001}, {0xC78, 0xF7430001}, + {0xC78, 0xF7440001}, {0xC78, 0xF7450001}, + {0xC78, 0xF7460001}, {0xC78, 0xF7470001}, + {0xC78, 0xF7480001}, {0xC78, 0xF6490001}, + {0xC78, 0xF34A0001}, {0xC78, 0xF24B0001}, + {0xC78, 0xF14C0001}, {0xC78, 0xF04D0001}, + {0xC78, 0xD14E0001}, {0xC78, 0xD04F0001}, + {0xC78, 0xB5500001}, {0xC78, 0xB4510001}, + {0xC78, 0xB3520001}, {0xC78, 0xB2530001}, + {0xC78, 0xB1540001}, {0xC78, 0xB0550001}, + {0xC78, 0xAF560001}, {0xC78, 0xAE570001}, + {0xC78, 0xAD580001}, {0xC78, 0xAC590001}, + {0xC78, 0xAB5A0001}, {0xC78, 0xAA5B0001}, + {0xC78, 0xA95C0001}, {0xC78, 0xA85D0001}, + {0xC78, 0xA75E0001}, {0xC78, 0xA65F0001}, + {0xC78, 0xA5600001}, {0xC78, 0xA4610001}, + {0xC78, 0xA3620001}, {0xC78, 0xA2630001}, + {0xC78, 0xA1640001}, {0xC78, 0xA0650001}, + {0xC78, 0x87660001}, {0xC78, 0x86670001}, + {0xC78, 0x85680001}, {0xC78, 0x84690001}, + {0xC78, 0x836A0001}, {0xC78, 0x826B0001}, + {0xC78, 0x816C0001}, {0xC78, 0x806D0001}, + {0xC78, 0x636E0001}, {0xC78, 0x626F0001}, + {0xC78, 0x61700001}, {0xC78, 0x60710001}, + {0xC78, 0x42720001}, {0xC78, 0x41730001}, + {0xC78, 0x40740001}, {0xC78, 0x23750001}, + {0xC78, 0x22760001}, {0xC78, 0x21770001}, + {0xC78, 0x20780001}, {0xC78, 0x03790001}, + {0xC78, 0x027A0001}, {0xC78, 0x017B0001}, + {0xC78, 0x007C0001}, {0xC78, 0x007D0001}, + {0xC78, 0x007E0001}, {0xC78, 0x007F0001}, + {0xC50, 0x69553422}, {0xC50, 0x69553420}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8710bu_qfn48m_u_radioa_init_table[] = { + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x17, 0x00000000}, {0x18, 0x00000C01}, + {0x19, 0x000739D2}, {0x1C, 0x00000C4C}, + {0x1B, 0x00000C6C}, {0x1E, 0x00080009}, + {0x1F, 0x00000880}, {0x2F, 0x0001A060}, + {0x3F, 0x00015000}, {0x42, 0x000060C0}, + {0x57, 0x000D0000}, {0x58, 0x000C0160}, + {0x67, 0x00001552}, {0x83, 0x00000000}, + {0xB0, 0x000FF9F0}, {0xB1, 0x00010018}, + {0xB2, 0x00054C00}, {0xB4, 0x0004486B}, + {0xB5, 0x0000112A}, {0xB6, 0x0000053E}, + {0xB7, 0x00014408}, {0xB8, 0x00010200}, + {0xB9, 0x00080801}, {0xBA, 0x00040001}, + {0xBB, 0x00000400}, {0xBF, 0x000C0000}, + {0xC2, 0x00002400}, {0xC3, 0x00000009}, + {0xC4, 0x00040C91}, {0xC5, 0x00099999}, + {0xC6, 0x000000A3}, {0xC7, 0x00088820}, + {0xC8, 0x00076C06}, {0xC9, 0x00000000}, + {0xCA, 0x00080000}, {0xDF, 0x00000180}, + {0xEF, 0x000001A8}, {0x3D, 0x00000003}, + {0x3D, 0x00080003}, {0x51, 0x000F1E69}, + {0x52, 0x000FBF6C}, {0x53, 0x0000032F}, + {0x54, 0x00055007}, {0x56, 0x000517F0}, + {0x35, 0x000000F4}, {0x35, 0x00000179}, + {0x35, 0x000002F4}, {0x36, 0x00000BF8}, + {0x36, 0x00008BF8}, {0x36, 0x00010BF8}, + {0x36, 0x00018BF8}, {0x18, 0x00000C01}, + {0x5A, 0x00048000}, {0x5A, 0x00048000}, + {0x34, 0x0000ADF5}, {0x34, 0x00009DF2}, + {0x34, 0x00008DEF}, {0x34, 0x00007DEC}, + {0x34, 0x00006DE9}, {0x34, 0x00005CEC}, + {0x34, 0x00004CE9}, {0x34, 0x00003C6C}, + {0x34, 0x00002C69}, {0x34, 0x0000106E}, + {0x34, 0x0000006B}, {0x84, 0x00048000}, + {0x87, 0x00000065}, {0x8E, 0x00065540}, + {0xDF, 0x00000110}, {0x86, 0x0000002A}, + {0x8F, 0x00088000}, {0x81, 0x0003FD80}, + {0xEF, 0x00082000}, {0x3B, 0x000F0F00}, + {0x3B, 0x000E0E00}, {0x3B, 0x000DFE00}, + {0x3B, 0x000C0D00}, {0x3B, 0x000B0C00}, + {0x3B, 0x000A0500}, {0x3B, 0x00090400}, + {0x3B, 0x00080000}, {0x3B, 0x00070F00}, + {0x3B, 0x00060E00}, {0x3B, 0x00050A00}, + {0x3B, 0x00040D00}, {0x3B, 0x00030C00}, + {0x3B, 0x00020500}, {0x3B, 0x00010400}, + {0x3B, 0x00000000}, {0xEF, 0x00080000}, + {0xEF, 0x00088000}, {0x3B, 0x00000170}, + {0x3B, 0x000C0030}, {0xEF, 0x00080000}, + {0xEF, 0x00080000}, {0x30, 0x00010000}, + {0x31, 0x0000000F}, {0x32, 0x00047EFE}, + {0xEF, 0x00000000}, {0x00, 0x00010159}, + {0x18, 0x0000FC01}, {0xFE, 0x00000000}, + {0x00, 0x00033D95}, + {0xff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8710bu_qfn48m_s_radioa_init_table[] = { + {0x00, 0x00030000}, {0x08, 0x00008400}, + {0x17, 0x00000000}, {0x18, 0x00000C01}, + {0x19, 0x000739D2}, {0x1C, 0x00000C4C}, + {0x1B, 0x00000C6C}, {0x1E, 0x00080009}, + {0x1F, 0x00000880}, {0x2F, 0x0001A060}, + {0x3F, 0x00015000}, {0x42, 0x000060C0}, + {0x57, 0x000D0000}, {0x58, 0x000C0160}, + {0x67, 0x00001552}, {0x83, 0x00000000}, + {0xB0, 0x000FF9F0}, {0xB1, 0x00010018}, + {0xB2, 0x00054C00}, {0xB4, 0x0004486B}, + {0xB5, 0x0000112A}, {0xB6, 0x0000053E}, + {0xB7, 0x00014408}, {0xB8, 0x00010200}, + {0xB9, 0x00080801}, {0xBA, 0x00040001}, + {0xBB, 0x00000400}, {0xBF, 0x000C0000}, + {0xC2, 0x00002400}, {0xC3, 0x00000009}, + {0xC4, 0x00040C91}, {0xC5, 0x00099999}, + {0xC6, 0x000000A3}, {0xC7, 0x00088820}, + {0xC8, 0x00076C06}, {0xC9, 0x00000000}, + {0xCA, 0x00080000}, {0xDF, 0x00000180}, + {0xEF, 0x000001A8}, {0x3D, 0x00000003}, + {0x3D, 0x00080003}, {0x51, 0x000F1E69}, + {0x52, 0x000FBF6C}, {0x53, 0x0000032F}, + {0x54, 0x00055007}, {0x56, 0x000517F0}, + {0x35, 0x000000F4}, {0x35, 0x00000179}, + {0x35, 0x000002F4}, {0x36, 0x00000BF8}, + {0x36, 0x00008BF8}, {0x36, 0x00010BF8}, + {0x36, 0x00018BF8}, {0x18, 0x00000C01}, + {0x5A, 0x00048000}, {0x5A, 0x00048000}, + {0x34, 0x0000ADF5}, {0x34, 0x00009DF2}, + {0x34, 0x00008DEF}, {0x34, 0x00007DEC}, + {0x34, 0x00006DE9}, {0x34, 0x00005CEC}, + {0x34, 0x00004CE9}, {0x34, 0x00003C6C}, + {0x34, 0x00002C69}, {0x34, 0x0000106E}, + {0x34, 0x0000006B}, {0x84, 0x00048000}, + {0x87, 0x00000065}, {0x8E, 0x00065540}, + {0xDF, 0x00000110}, {0x86, 0x0000002A}, + {0x8F, 0x00088000}, {0x81, 0x0003FD80}, + {0xEF, 0x00082000}, {0x3B, 0x000F0F00}, + {0x3B, 0x000E0E00}, {0x3B, 0x000DFE00}, + {0x3B, 0x000C0D00}, {0x3B, 0x000B0C00}, + {0x3B, 0x000A0500}, {0x3B, 0x00090400}, + {0x3B, 0x00080000}, {0x3B, 0x00070F00}, + {0x3B, 0x00060E00}, {0x3B, 0x00050A00}, + {0x3B, 0x00040D00}, {0x3B, 0x00030C00}, + {0x3B, 0x00020500}, {0x3B, 0x00010400}, + {0x3B, 0x00000000}, {0xEF, 0x00080000}, + {0xEF, 0x00088000}, {0x3B, 0x000000B0}, + {0x3B, 0x000C0030}, {0xEF, 0x00080000}, + {0xEF, 0x00080000}, {0x30, 0x00010000}, + {0x31, 0x0000000F}, {0x32, 0x00047EFE}, + {0xEF, 0x00000000}, {0x00, 0x00010159}, + {0x18, 0x0000FC01}, {0xFE, 0x00000000}, + {0x00, 0x00033D95}, + {0xff, 0xffffffff} +}; + +static u32 rtl8710b_indirect_read32(struct rtl8xxxu_priv *priv, u32 addr) +{ + struct device *dev = &priv->udev->dev; + u32 val32, value = 0xffffffff; + u8 polling_count = 0xff; + + if (!IS_ALIGNED(addr, 4)) { + dev_warn(dev, "%s: Aborting because 0x%x is not a multiple of 4.\n", + __func__, addr); + return value; + } + + mutex_lock(&priv->syson_indirect_access_mutex); + + rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, addr); + rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, NORMAL_REG_READ_OFFSET); + + do + val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); + while ((val32 & BIT(31)) && (--polling_count > 0)); + + if (polling_count == 0) + dev_warn(dev, "%s: Failed to read from 0x%x, 0x806c = 0x%x\n", + __func__, addr, val32); + else + value = rtl8xxxu_read32(priv, REG_USB_HOST_INDIRECT_DATA_8710B); + + mutex_unlock(&priv->syson_indirect_access_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ) + dev_info(dev, "%s(%04x) = 0x%08x\n", __func__, addr, value); + + return value; +} + +static void rtl8710b_indirect_write32(struct rtl8xxxu_priv *priv, u32 addr, u32 val) +{ + struct device *dev = &priv->udev->dev; + u8 polling_count = 0xff; + u32 val32; + + if (!IS_ALIGNED(addr, 4)) { + dev_warn(dev, "%s: Aborting because 0x%x is not a multiple of 4.\n", + __func__, addr); + return; + } + + mutex_lock(&priv->syson_indirect_access_mutex); + + rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, addr); + rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_DATA_8710B, val); + rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, NORMAL_REG_WRITE_OFFSET); + + do + val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); + while ((val32 & BIT(31)) && (--polling_count > 0)); + + if (polling_count == 0) + dev_warn(dev, "%s: Failed to write 0x%x to 0x%x, 0x806c = 0x%x\n", + __func__, val, addr, val32); + + mutex_unlock(&priv->syson_indirect_access_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(dev, "%s(%04x) = 0x%08x\n", __func__, addr, val); +} + +static u32 rtl8710b_read_syson_reg(struct rtl8xxxu_priv *priv, u32 addr) +{ + return rtl8710b_indirect_read32(priv, addr | SYSON_REG_BASE_ADDR_8710B); +} + +static void rtl8710b_write_syson_reg(struct rtl8xxxu_priv *priv, u32 addr, u32 val) +{ + rtl8710b_indirect_write32(priv, addr | SYSON_REG_BASE_ADDR_8710B, val); +} + +static int rtl8710b_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data) +{ + u32 val32; + int i; + + /* Write Address */ + rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, offset); + + rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, EFUSE_READ_OFFSET); + + /* Poll for data read */ + val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); + for (i = 0; i < RTL8XXXU_MAX_REG_POLL; i++) { + val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); + if (!(val32 & BIT(31))) + break; + } + + if (i == RTL8XXXU_MAX_REG_POLL) + return -EIO; + + val32 = rtl8xxxu_read32(priv, REG_USB_HOST_INDIRECT_DATA_8710B); + + *data = val32 & 0xff; + return 0; +} + +#define EEPROM_PACKAGE_TYPE_8710B 0xF8 +#define PACKAGE_QFN48M_U 0xee +#define PACKAGE_QFN48M_S 0xfe + +static int rtl8710bu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 cfg0, cfg2, vendor; + u8 package_type = 0x7; /* a nonsense value */ + + sprintf(priv->chip_name, "8710BU"); + priv->rtl_chip = RTL8710B; + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + priv->has_wifi = 1; + + cfg0 = rtl8710b_read_syson_reg(priv, REG_SYS_SYSTEM_CFG0_8710B); + priv->chip_cut = cfg0 & 0xf; + + if (cfg0 & BIT(16)) { + dev_info(dev, "%s: Unsupported test chip\n", __func__); + return -EOPNOTSUPP; + } + + vendor = u32_get_bits(cfg0, 0xc0); + + /* SMIC and TSMC are swapped compared to rtl8xxxu_identify_vendor_2bits */ + switch (vendor) { + case 0: + sprintf(priv->chip_vendor, "SMIC"); + priv->vendor_smic = 1; + break; + case 1: + sprintf(priv->chip_vendor, "TSMC"); + break; + case 2: + sprintf(priv->chip_vendor, "UMC"); + priv->vendor_umc = 1; + break; + default: + sprintf(priv->chip_vendor, "unknown"); + break; + } + + rtl8710b_read_efuse8(priv, EEPROM_PACKAGE_TYPE_8710B, &package_type); + + if (package_type == 0xff) { + dev_warn(dev, "Package type is undefined. Assuming it based on the vendor.\n"); + + if (priv->vendor_umc) { + package_type = PACKAGE_QFN48M_U; + } else if (priv->vendor_smic) { + package_type = PACKAGE_QFN48M_S; + } else { + dev_warn(dev, "The vendor is neither UMC nor SMIC. Assuming the package type is QFN48M_U.\n"); + + /* + * In this case the vendor driver doesn't set + * the package type to anything, which is the + * same as setting it to PACKAGE_DEFAULT (0). + */ + package_type = PACKAGE_QFN48M_U; + } + } else if (package_type != PACKAGE_QFN48M_S && + package_type != PACKAGE_QFN48M_U) { + dev_warn(dev, "Failed to read the package type. Assuming it's the default QFN48M_U.\n"); + + /* + * In this case the vendor driver actually sets it to + * PACKAGE_DEFAULT, but that selects the same values + * from the init tables as PACKAGE_QFN48M_U. + */ + package_type = PACKAGE_QFN48M_U; + } + + priv->package_type = package_type; + + dev_dbg(dev, "Package type: 0x%x\n", package_type); + + cfg2 = rtl8710b_read_syson_reg(priv, REG_SYS_SYSTEM_CFG2_8710B); + priv->rom_rev = cfg2 & 0xf; + + return rtl8xxxu_config_endpoints_no_sie(priv); +} + +static void rtl8710b_revise_cck_tx_psf(struct rtl8xxxu_priv *priv, u8 channel) +{ + if (channel == 13) { + /* Normal values */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); + rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00008810); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); + /* Special value for channel 13 */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xd1d80001); + } else if (channel == 14) { + /* Special values for channel 14 */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x0000B81C); + rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00000000); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x00003667); + /* Normal value */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); + } else { + /* Restore normal values from the phy init table */ + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); + rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00008810); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); + rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); + } +} + +static void rtl8710bu_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + bool ht40 = conf_is_ht40(&hw->conf); + u8 channel, subchannel = 0; + bool sec_ch_above = 0; + u32 val32; + u16 val16; + + channel = (u8)hw->conf.chandef.chan->hw_value; + + if (conf_is_ht40_plus(&hw->conf)) { + sec_ch_above = 1; + channel += 2; + subchannel = 2; + } else if (conf_is_ht40_minus(&hw->conf)) { + sec_ch_above = 0; + channel -= 2; + subchannel = 1; + } + + /* Set channel */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + u32p_replace_bits(&val32, channel, MODE_AG_CHANNEL_MASK); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + + rtl8710b_revise_cck_tx_psf(priv, channel); + + /* Set bandwidth mode */ + val16 = rtl8xxxu_read16(priv, REG_WMAC_TRXPTCL_CTL); + val16 &= ~WMAC_TRXPTCL_CTL_BW_MASK; + if (ht40) + val16 |= WMAC_TRXPTCL_CTL_BW_40; + rtl8xxxu_write16(priv, REG_WMAC_TRXPTCL_CTL, val16); + + rtl8xxxu_write8(priv, REG_DATA_SUBCHANNEL, subchannel); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + u32p_replace_bits(&val32, ht40, FPGA_RF_MODE); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + u32p_replace_bits(&val32, ht40, FPGA_RF_MODE); + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + if (ht40) { + /* Set Control channel to upper or lower. */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); + u32p_replace_bits(&val32, !sec_ch_above, CCK0_SIDEBAND); + rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); + } + + /* RXADC CLK */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= GENMASK(10, 8); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* TXDAC CLK */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= BIT(14) | BIT(12); + val32 &= ~BIT(13); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* small BW */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + val32 &= ~GENMASK(31, 30); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + /* adc buffer clk */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + val32 &= ~BIT(29); + val32 |= BIT(28); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + /* adc buffer clk */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_AFE); + val32 &= ~BIT(29); + val32 |= BIT(28); + rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_AFE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); + val32 &= ~BIT(30); + val32 |= BIT(29); + rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); + + if (ht40) { + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~BIT(19); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~GENMASK(23, 20); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~GENMASK(27, 24); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + /* RF TRX_BW */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + val32 |= MODE_AG_BW_40MHZ_8723B; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + } else { + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 |= BIT(19); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~GENMASK(23, 20); + val32 |= BIT(23); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); + val32 &= ~GENMASK(27, 24); + val32 |= BIT(27) | BIT(25); + rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); + + /* RF TRX_BW */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + val32 |= MODE_AG_BW_20MHZ_8723B; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + } +} + +static void rtl8710bu_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u32 agg_rx; + u8 agg_ctrl; + + /* RX aggregation */ + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + + agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); + agg_rx &= ~RXDMA_USB_AGG_ENABLE; + agg_rx &= ~0xFF0F; /* reset agg size and timeout */ + + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); +} + +static void rtl8710bu_init_statistics(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + /* Time duration for NHM unit: 4us, 0xc350=200ms */ + rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350); + rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff); + rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50); + rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff); + + /* TH8 */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 |= 0xff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Enable CCK */ + val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B); + val32 &= ~(BIT(8) | BIT(9) | BIT(10)); + val32 |= BIT(8); + rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32); + + /* Max power amongst all RX antennas */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC); + val32 |= BIT(7); + rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); +} + +static int rtl8710b_read_efuse(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u8 val8, word_mask, header, extheader; + u16 efuse_addr, offset; + int i, ret = 0; + u32 val32; + + val32 = rtl8710b_read_syson_reg(priv, REG_SYS_EEPROM_CTRL0_8710B); + priv->boot_eeprom = u32_get_bits(val32, EEPROM_BOOT); + priv->has_eeprom = u32_get_bits(val32, EEPROM_ENABLE); + + /* Default value is 0xff */ + memset(priv->efuse_wifi.raw, 0xff, EFUSE_MAP_LEN); + + efuse_addr = 0; + while (efuse_addr < EFUSE_REAL_CONTENT_LEN_8723A) { + u16 map_addr; + + ret = rtl8710b_read_efuse8(priv, efuse_addr++, &header); + if (ret || header == 0xff) + goto exit; + + if ((header & 0x1f) == 0x0f) { /* extended header */ + offset = (header & 0xe0) >> 5; + + ret = rtl8710b_read_efuse8(priv, efuse_addr++, &extheader); + if (ret) + goto exit; + + /* All words disabled */ + if ((extheader & 0x0f) == 0x0f) + continue; + + offset |= ((extheader & 0xf0) >> 1); + word_mask = extheader & 0x0f; + } else { + offset = (header >> 4) & 0x0f; + word_mask = header & 0x0f; + } + + /* Get word enable value from PG header */ + + /* We have 8 bits to indicate validity */ + map_addr = offset * 8; + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (word_mask & BIT(i)) { + map_addr += 2; + continue; + } + + ret = rtl8710b_read_efuse8(priv, efuse_addr++, &val8); + if (ret) + goto exit; + if (map_addr >= EFUSE_MAP_LEN - 1) { + dev_warn(dev, "%s: Illegal map_addr (%04x), efuse corrupt!\n", + __func__, map_addr); + ret = -EINVAL; + goto exit; + } + priv->efuse_wifi.raw[map_addr++] = val8; + + ret = rtl8710b_read_efuse8(priv, efuse_addr++, &val8); + if (ret) + goto exit; + priv->efuse_wifi.raw[map_addr++] = val8; + } + } + +exit: + + return ret; +} + +static int rtl8710bu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8710bu_efuse *efuse = &priv->efuse_wifi.efuse8710bu; + + if (efuse->rtl_id != cpu_to_le16(0x8195)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + + priv->ofdm_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; + priv->ht20_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + + priv->default_crystal_cap = efuse->xtal_k & 0x3f; + + return 0; +} + +static int rtl8710bu_load_firmware(struct rtl8xxxu_priv *priv) +{ + if (priv->vendor_smic) { + return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8710bufw_SMIC.bin"); + } else if (priv->vendor_umc) { + return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8710bufw_UMC.bin"); + } else { + dev_err(&priv->udev->dev, "We have no suitable firmware for this chip.\n"); + return -1; + } +} + +static void rtl8710bu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + const struct rtl8xxxu_reg32val *phy_init_table; + u32 val32; + + /* Enable BB and RF */ + val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); + val32 |= GENMASK(17, 16) | GENMASK(26, 24); + rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); + + if (priv->package_type == PACKAGE_QFN48M_U) + phy_init_table = rtl8710bu_qfn48m_u_phy_init_table; + else + phy_init_table = rtl8710bu_qfn48m_s_phy_init_table; + + rtl8xxxu_init_phy_regs(priv, phy_init_table); + + rtl8xxxu_init_phy_regs(priv, rtl8710b_agc_table); +} + +static int rtl8710bu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + const struct rtl8xxxu_rfregval *radioa_init_table; + + if (priv->package_type == PACKAGE_QFN48M_U) + radioa_init_table = rtl8710bu_qfn48m_u_radioa_init_table; + else + radioa_init_table = rtl8710bu_qfn48m_s_radioa_init_table; + + return rtl8xxxu_init_phy_rf(priv, radioa_init_table, RF_A); +} + +static int rtl8710bu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result) +{ + u32 reg_eac, reg_e94, reg_e9c, val32, path_sel_bb; + int result = 0; + + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x99000000); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Enable path A PA in TX IQK mode + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7); + + /* PA,PAD gain adjust */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 |= BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); + u32p_replace_bits(&val32, 0x1ed, 0x00fff); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); + + /* enter IQK mode */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ff); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160c06); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x02002911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 &= ~BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + + /* save LOK result */ + *lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + + return result; +} + +static int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32, path_sel_bb, tmp; + int result = 0; + + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x99000000); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* modify RXIQK mode table */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); + + /* PA,PAD gain adjust */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 |= BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); + u32p_replace_bits(&val32, 0xf, 0x003e0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8216129f); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160c00); + + /* + * Tx IQK setting + */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) { + result |= 0x01; + } else { /* If TX not OK, ignore RX */ + + /* reload RF path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 &= ~BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + + return result; + } + + val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) | ((reg_e9c & 0x3ff0000) >> 16); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* + * Modify RX IQK mode table + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); + + /* + * PA, PAD setting + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 |= BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); + u32p_replace_bits(&val32, 0x2a, 0x00fff); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * RX IQK setting + */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); + + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x2816169f); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(10); + + /* reload RF path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); + val32 &= ~BIT(11); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); + + /* reload LOK value */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + tmp = (reg_eac & 0x03ff0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000) && + (((reg_ea4 & 0x03ff0000) >> 16) < 0x11a) && + (((reg_ea4 & 0x03ff0000) >> 16) > 0xe6) && + (tmp < 0x1a)) + result |= 0x02; + + return result; +} + +static void rtl8710bu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32, rx_initial_gain, lok_result; + u32 path_sel_bb, path_sel_rf; + int path_a_ok; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_CCK0_AFE_SETTING + }; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + rx_initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + if (t == 0) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1); + priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI); + } + + if (!priv->pi_enabled) { + /* Switch BB to PI mode to do IQ Calibration */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000100); + } + + /* MAC settings */ + val32 = rtl8xxxu_read32(priv, REG_TX_PTCL_CTRL); + val32 |= 0x00ff0000; + rtl8xxxu_write32(priv, REG_TX_PTCL_CTRL, val32); + + /* save RF path */ + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1); + + /* BB setting */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); + val32 |= 0x0f000000; + rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x03c00010); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05601); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x25204000); + + /* IQ calibration setting */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0x808000, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8710bu_iqk_path_a(priv, &lok_result); + + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][0] = 0x100; + result[t][1] = 0x0; + } + } + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8710bu_rx_iqk_path_a(priv, lok_result); + + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + break; + } else { + result[t][2] = 0x100; + result[t][3] = 0x0; + } + } + + if (!path_a_ok) + dev_warn(dev, "%s: Path A IQK failed!\n", __func__); + + /* Back to BB mode, load original value */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + u32p_replace_bits(&val32, 0, 0xffffff00); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + if (t == 0) + return; + + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Reload RF path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf); + + /* Restore RX initial gain */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + u32p_replace_bits(&val32, 0x50, 0x000000ff); + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + u32p_replace_bits(&val32, rx_initial_gain & 0xff, 0x000000ff); + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); +} + +static void rtl8710bu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok; + s32 reg_e94, reg_e9c, reg_ea4, reg_eac; + s32 reg_tmp = 0; + bool simu; + u32 path_sel_bb; + + /* Save RF path */ + path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + + for (i = 0; i < 3; i++) { + rtl8710bu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2); + if (simu) { + candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp) + candidate = 3; + else + candidate = -1; + } + } + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + reg_e9c = result[candidate][1]; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, "%s: e94=%x e9c=%x ea4=%x eac=%x\n", + __func__, reg_e94, reg_e9c, reg_ea4, reg_eac); + + path_a_ok = true; + + if (reg_e94) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + } + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); +} + +static int rtl8710b_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + int count, ret = 0; + + /* AFE power mode selection: 1: LDO mode, 0: Power-cut mode */ + val8 = rtl8xxxu_read8(priv, 0x5d); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, 0x5d, val8); + + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC_8710B); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_SYS_FUNC_8710B, val8); + + rtl8xxxu_write8(priv, 0x56, 0x0e); + + val8 = rtl8xxxu_read8(priv, 0x20); + val8 |= BIT(0); + rtl8xxxu_write8(priv, 0x20, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val8 = rtl8xxxu_read8(priv, 0x20); + if (!(val8 & BIT(0))) + break; + + udelay(10); + } + + if (!count) + ret = -EBUSY; + + return ret; +} + +static int rtl8710bu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* Turn off RF */ + val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); + val32 &= ~GENMASK(26, 24); + rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); + + /* BB reset */ + val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); + val32 &= ~GENMASK(17, 16); + rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); + + /* Turn off MAC by HW state machine */ + val8 = rtl8xxxu_read8(priv, 0x20); + val8 |= BIT(1); + rtl8xxxu_write8(priv, 0x20, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val8 = rtl8xxxu_read8(priv, 0x20); + if ((val8 & BIT(1)) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) + ret = -EBUSY; + + return ret; +} + +static int rtl8710bu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u8 val8; + u16 val16; + u32 val32; + int retry, retval; + + /* Tx Pause */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + retry = 100; + retval = -EBUSY; + /* + * Poll 32 bit wide REG_SCH_TX_CMD for 0x00000000 to ensure no TX is pending. + */ + do { + val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); + if (!val32) { + retval = 0; + break; + } + udelay(10); + } while (retry--); + + if (!retry) { + dev_warn(dev, "Failed to flush TX queue\n"); + retval = -EBUSY; + return retval; + } + + /* Disable CCK and OFDM, clock gated */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + udelay(2); + + /* Whole BB is reset */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BB_GLB_RSTN; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + /* Reset MAC TRX */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 &= 0xff00; + val16 |= CR_HCI_RXDMA_ENABLE | CR_HCI_TXDMA_ENABLE; + val16 &= ~CR_SECURITY_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + /* Respond TxOK to scheduler */ + val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); + val8 |= DUAL_TSF_TX_OK; + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); + + return retval; +} + +static int rtl8710bu_power_on(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u16 val16; + u8 val8; + int ret; + + rtl8xxxu_write8(priv, REG_USB_ACCESS_TIMEOUT, 0x80); + + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 &= ~BIT(5); + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC_8710B); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_SYS_FUNC_8710B, val8); + + val8 = rtl8xxxu_read8(priv, 0x20); + val8 |= BIT(0); + rtl8xxxu_write8(priv, 0x20, val8); + + rtl8xxxu_write8(priv, REG_AFE_CTRL_8710B, 0); + + val8 = rtl8xxxu_read8(priv, REG_WL_STATUS_8710B); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_WL_STATUS_8710B, val8); + + ret = rtl8710b_emu_to_active(priv); + if (ret) + return ret; + + rtl8xxxu_write16(priv, REG_CR, 0); + + val16 = rtl8xxxu_read16(priv, REG_CR); + + val16 |= CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + /* Enable hardware sequence number. */ + val8 = rtl8xxxu_read8(priv, REG_HWSEQ_CTRL); + val8 |= 0x7f; + rtl8xxxu_write8(priv, REG_HWSEQ_CTRL, val8); + + udelay(2); + + /* + * Technically the rest was in the rtl8710bu_hal_init function, + * not the power_on function, but it's fine because we only + * call power_on from init_device. + */ + + val8 = rtl8xxxu_read8(priv, 0xfef9); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, 0xfef9, val8); + + /* Clear the 0x40000138[5] to prevent CM4 Suspend */ + val32 = rtl8710b_read_syson_reg(priv, 0x138); + val32 &= ~BIT(5); + rtl8710b_write_syson_reg(priv, 0x138, val32); + + return ret; +} + +static void rtl8710bu_power_off(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u8 val8; + + rtl8xxxu_flush_fifo(priv); + + rtl8xxxu_write32(priv, REG_HISR0_8710B, 0xffffffff); + rtl8xxxu_write32(priv, REG_HIMR0_8710B, 0x0); + + /* Set the 0x40000138[5] to allow CM4 Suspend */ + val32 = rtl8710b_read_syson_reg(priv, 0x138); + val32 |= BIT(5); + rtl8710b_write_syson_reg(priv, 0x138, val32); + + /* Stop rx */ + rtl8xxxu_write8(priv, REG_CR, 0x00); + + rtl8710bu_active_to_lps(priv); + + /* Reset MCU ? */ + val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B, 0x00); + + rtl8710bu_active_to_emu(priv); +} + +static void rtl8710b_reset_8051(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); + + udelay(50); + + val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); +} + +static void rtl8710b_enable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); + val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_TX_A; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static void rtl8710b_disable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + /* Power down RF module */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); +} + +static void rtl8710b_usb_quirks(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + rtl8xxxu_gen2_usb_quirks(priv); + + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); +} + +#define XTAL1 GENMASK(29, 24) +#define XTAL0 GENMASK(23, 18) + +static void rtl8710b_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + u32 val32; + + if (crystal_cap == cfo->crystal_cap) + return; + + val32 = rtl8710b_read_syson_reg(priv, REG_SYS_XTAL_CTRL0_8710B); + + dev_dbg(&priv->udev->dev, + "%s: Adjusting crystal cap from 0x%x (actually 0x%x 0x%x) to 0x%x\n", + __func__, + cfo->crystal_cap, + u32_get_bits(val32, XTAL1), + u32_get_bits(val32, XTAL0), + crystal_cap); + + u32p_replace_bits(&val32, crystal_cap, XTAL1); + u32p_replace_bits(&val32, crystal_cap, XTAL0); + rtl8710b_write_syson_reg(priv, REG_SYS_XTAL_CTRL0_8710B, val32); + + cfo->crystal_cap = crystal_cap; +} + +static s8 rtl8710b_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + struct jaguar2_phy_stats_type0 *phy_stats0 = (struct jaguar2_phy_stats_type0 *)phy_stats; + u8 lna_idx = (phy_stats0->lna_h << 3) | phy_stats0->lna_l; + u8 vga_idx = phy_stats0->vga; + s8 rx_pwr_all = 0x00; + + switch (lna_idx) { + case 7: + rx_pwr_all = -52 - (2 * vga_idx); + break; + case 6: + rx_pwr_all = -42 - (2 * vga_idx); + break; + case 5: + rx_pwr_all = -36 - (2 * vga_idx); + break; + case 3: + rx_pwr_all = -12 - (2 * vga_idx); + break; + case 2: + rx_pwr_all = 0 - (2 * vga_idx); + break; + default: + rx_pwr_all = 0; + break; + } + + return rx_pwr_all; +} + +struct rtl8xxxu_fileops rtl8710bu_fops = { + .identify_chip = rtl8710bu_identify_chip, + .parse_efuse = rtl8710bu_parse_efuse, + .load_firmware = rtl8710bu_load_firmware, + .power_on = rtl8710bu_power_on, + .power_off = rtl8710bu_power_off, + .read_efuse = rtl8710b_read_efuse, + .reset_8051 = rtl8710b_reset_8051, + .llt_init = rtl8xxxu_auto_llt_table, + .init_phy_bb = rtl8710bu_init_phy_bb, + .init_phy_rf = rtl8710bu_init_phy_rf, + .phy_lc_calibrate = rtl8188f_phy_lc_calibrate, + .phy_iq_calibrate = rtl8710bu_phy_iq_calibrate, + .config_channel = rtl8710bu_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc24, + .parse_phystats = jaguar2_rx_parse_phystats, + .init_aggregation = rtl8710bu_init_aggregation, + .init_statistics = rtl8710bu_init_statistics, + .init_burst = rtl8xxxu_init_burst, + .enable_rf = rtl8710b_enable_rf, + .disable_rf = rtl8710b_disable_rf, + .usb_quirks = rtl8710b_usb_quirks, + .set_tx_power = rtl8188f_set_tx_power, + .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8xxxu_gen2_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v2, + .set_crystal_cap = rtl8710b_set_crystal_cap, + .cck_rssi = rtl8710b_cck_rssi, + .writeN_block_size = 4, + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), + .has_tx_report = 1, + .gen2_thermal_meter = 1, + .needs_full_init = 1, + .init_reg_rxfltmap = 1, + .init_reg_pkt_life_time = 1, + .init_reg_hmtfr = 1, + .hw_feature_report = 0, /* TODO, it's different */ + .ampdu_max_time = 0x5e, + /* + * The RTL8710BU vendor driver uses 0x50 here and it works fine, + * but in rtl8xxxu 0x50 causes slow upload and random packet loss. Why? + */ + .ustime_tsf_edca = 0x28, + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 16, + .max_sec_cam_num = 32, + .adda_1t_init = 0x03c00016, + .adda_1t_path_on = 0x03c00016, + .trxff_boundary = 0x3f7f, + .pbp_rx = PBP_PAGE_SIZE_256, + .pbp_tx = PBP_PAGE_SIZE_256, + .mactable = rtl8710b_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8723B, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8723B, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8723B, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8723a.c b/drivers/net/wireless/realtek/rtl8xxxu/8723a.c new file mode 100644 index 000000000..18e038b82 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8723a.c @@ -0,0 +1,649 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8723a specific subdriver + * + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static struct rtl8xxxu_power_base rtl8723a_power_base = { + .reg_0e00 = 0x0a0c0c0c, + .reg_0e04 = 0x02040608, + .reg_0e08 = 0x00000000, + .reg_086c = 0x00000000, + + .reg_0e10 = 0x0a0c0d0e, + .reg_0e14 = 0x02040608, + .reg_0e18 = 0x0a0c0d0e, + .reg_0e1c = 0x02040608, + + .reg_0830 = 0x0a0c0c0c, + .reg_0834 = 0x02040608, + .reg_0838 = 0x00000000, + .reg_086c_2 = 0x00000000, + + .reg_083c = 0x0a0c0d0e, + .reg_0848 = 0x02040608, + .reg_084c = 0x0a0c0d0e, + .reg_0868 = 0x02040608, +}; + +static const struct rtl8xxxu_reg8val rtl8723au_mac_init_table[] = { + {0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00}, + {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, + {0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00}, + {0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05}, + {0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01}, + {0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f}, + {0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72}, + {0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08}, + {0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, + {0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, + {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, + {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, + {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, + {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, + {0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16}, + {0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00}, + {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02}, + {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, + {0x652, 0x20}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e}, + {0x63f, 0x0e}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43}, + {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, + {0x70a, 0x65}, {0x70b, 0x87}, {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_rfregval rtl8723au_radioa_1t_init_table[] = { + {0x00, 0x00030159}, {0x01, 0x00031284}, + {0x02, 0x00098000}, {0x03, 0x00039c63}, + {0x04, 0x000210e7}, {0x09, 0x0002044f}, + {0x0a, 0x0001a3f1}, {0x0b, 0x00014787}, + {0x0c, 0x000896fe}, {0x0d, 0x0000e02c}, + {0x0e, 0x00039ce7}, {0x0f, 0x00000451}, + {0x19, 0x00000000}, {0x1a, 0x00030355}, + {0x1b, 0x00060a00}, {0x1c, 0x000fc378}, + {0x1d, 0x000a1250}, {0x1e, 0x0000024f}, + {0x1f, 0x00000000}, {0x20, 0x0000b614}, + {0x21, 0x0006c000}, {0x22, 0x00000000}, + {0x23, 0x00001558}, {0x24, 0x00000060}, + {0x25, 0x00000483}, {0x26, 0x0004f000}, + {0x27, 0x000ec7d9}, {0x28, 0x00057730}, + {0x29, 0x00004783}, {0x2a, 0x00000001}, + {0x2b, 0x00021334}, {0x2a, 0x00000000}, + {0x2b, 0x00000054}, {0x2a, 0x00000001}, + {0x2b, 0x00000808}, {0x2b, 0x00053333}, + {0x2c, 0x0000000c}, {0x2a, 0x00000002}, + {0x2b, 0x00000808}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000003}, + {0x2b, 0x00000808}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000004}, + {0x2b, 0x00000808}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000005}, + {0x2b, 0x00000808}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000006}, + {0x2b, 0x00000709}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000007}, + {0x2b, 0x00000709}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000008}, + {0x2b, 0x0000060a}, {0x2b, 0x0004b333}, + {0x2c, 0x0000000d}, {0x2a, 0x00000009}, + {0x2b, 0x0000060a}, {0x2b, 0x00053333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000a}, + {0x2b, 0x0000060a}, {0x2b, 0x0005b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000b}, + {0x2b, 0x0000060a}, {0x2b, 0x00063333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000c}, + {0x2b, 0x0000060a}, {0x2b, 0x0006b333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000d}, + {0x2b, 0x0000060a}, {0x2b, 0x00073333}, + {0x2c, 0x0000000d}, {0x2a, 0x0000000e}, + {0x2b, 0x0000050b}, {0x2b, 0x00066666}, + {0x2c, 0x0000001a}, {0x2a, 0x000e0000}, + {0x10, 0x0004000f}, {0x11, 0x000e31fc}, + {0x10, 0x0006000f}, {0x11, 0x000ff9f8}, + {0x10, 0x0002000f}, {0x11, 0x000203f9}, + {0x10, 0x0003000f}, {0x11, 0x000ff500}, + {0x10, 0x00000000}, {0x11, 0x00000000}, + {0x10, 0x0008000f}, {0x11, 0x0003f100}, + {0x10, 0x0009000f}, {0x11, 0x00023100}, + {0x12, 0x00032000}, {0x12, 0x00071000}, + {0x12, 0x000b0000}, {0x12, 0x000fc000}, + {0x13, 0x000287b3}, {0x13, 0x000244b7}, + {0x13, 0x000204ab}, {0x13, 0x0001c49f}, + {0x13, 0x00018493}, {0x13, 0x0001429b}, + {0x13, 0x00010299}, {0x13, 0x0000c29c}, + {0x13, 0x000081a0}, {0x13, 0x000040ac}, + {0x13, 0x00000020}, {0x14, 0x0001944c}, + {0x14, 0x00059444}, {0x14, 0x0009944c}, + {0x14, 0x000d9444}, {0x15, 0x0000f474}, + {0x15, 0x0004f477}, {0x15, 0x0008f455}, + {0x15, 0x000cf455}, {0x16, 0x00000339}, + {0x16, 0x00040339}, {0x16, 0x00080339}, + {0x16, 0x000c0366}, {0x00, 0x00010159}, + {0x18, 0x0000f401}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0x1f, 0x00000003}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0x1e, 0x00000247}, {0x1f, 0x00000000}, + {0x00, 0x00030159}, + {0xff, 0xffffffff} +}; + +static int rtl8723au_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 val32, sys_cfg, vendor; + int ret = 0; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + ret = -ENOTSUPP; + goto out; + } + + strscpy(priv->chip_name, "8723AU", sizeof(priv->chip_name)); + priv->usb_interrupts = 1; + priv->rtl_chip = RTL8723A; + + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + + val32 = rtl8xxxu_read32(priv, REG_MULTI_FUNC_CTRL); + if (val32 & MULTI_WIFI_FUNC_EN) + priv->has_wifi = 1; + if (val32 & MULTI_BT_FUNC_EN) + priv->has_bluetooth = 1; + if (val32 & MULTI_GPS_FUNC_EN) + priv->has_gps = 1; + priv->is_multi_func = 1; + + vendor = sys_cfg & SYS_CFG_VENDOR_ID; + rtl8xxxu_identify_vendor_1bit(priv, vendor); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); + priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); + + rtl8xxxu_config_endpoints_sie(priv); + + /* + * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX + */ + if (!priv->ep_tx_count) + ret = rtl8xxxu_config_endpoints_no_sie(priv); + +out: + return ret; +} + +static int rtl8723au_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8723au_efuse *efuse = &priv->efuse_wifi.efuse8723; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, + efuse->cck_tx_power_index_A, + sizeof(efuse->cck_tx_power_index_A)); + memcpy(priv->cck_tx_power_index_B, + efuse->cck_tx_power_index_B, + sizeof(efuse->cck_tx_power_index_B)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->ht40_1s_tx_power_index_A, + sizeof(efuse->ht40_1s_tx_power_index_A)); + memcpy(priv->ht40_1s_tx_power_index_B, + efuse->ht40_1s_tx_power_index_B, + sizeof(efuse->ht40_1s_tx_power_index_B)); + + memcpy(priv->ht20_tx_power_index_diff, + efuse->ht20_tx_power_index_diff, + sizeof(efuse->ht20_tx_power_index_diff)); + memcpy(priv->ofdm_tx_power_index_diff, + efuse->ofdm_tx_power_index_diff, + sizeof(efuse->ofdm_tx_power_index_diff)); + + memcpy(priv->ht40_max_power_offset, + efuse->ht40_max_power_offset, + sizeof(efuse->ht40_max_power_offset)); + memcpy(priv->ht20_max_power_offset, + efuse->ht20_max_power_offset, + sizeof(efuse->ht20_max_power_offset)); + + if (priv->efuse_wifi.efuse8723.version >= 0x01) + priv->default_crystal_cap = priv->efuse_wifi.efuse8723.xtal_k & 0x3f; + else + priv->fops->set_crystal_cap = NULL; + + priv->power_base = &rtl8723a_power_base; + + return 0; +} + +static int rtl8723au_load_firmware(struct rtl8xxxu_priv *priv) +{ + const char *fw_name; + int ret; + + switch (priv->chip_cut) { + case 0: + fw_name = "rtlwifi/rtl8723aufw_A.bin"; + break; + case 1: + if (priv->enable_bluetooth) + fw_name = "rtlwifi/rtl8723aufw_B.bin"; + else + fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin"; + + break; + default: + return -EINVAL; + } + + ret = rtl8xxxu_load_firmware(priv, fw_name); + return ret; +} + +static int rtl8723au_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + int ret; + + ret = rtl8xxxu_init_phy_rf(priv, rtl8723au_radioa_1t_init_table, RF_A); + + /* Reduce 80M spur */ + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, 0x0381808d); + rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff83); + rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff82); + rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff83); + + return ret; +} + +static int rtl8723a_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* 0x20[0] = 1 enable LDOA12 MACRO block for all interface*/ + val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); + val8 |= LDOA15_ENABLE; + rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); + + /* 0x67[0] = 0 to disable BT_GPS_SEL pins*/ + val8 = rtl8xxxu_read8(priv, 0x0067); + val8 &= ~BIT(4); + rtl8xxxu_write8(priv, 0x0067, val8); + + mdelay(1); + + /* 0x00[5] = 0 release analog Ips to digital, 1:isolation */ + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 &= ~SYS_ISO_ANALOG_IPS; + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + + /* disable SW LPS 0x04[10]= 0 */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~BIT(2); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* wait till 0x04[17] = 1 power ready*/ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* We should be able to optimize the following three entries into one */ + + /* release WLON reset 0x04[16]= 1*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8); + + /* disable HWPDN 0x04[15]= 0*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~BIT(7); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* disable WL suspend*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(4)); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* set, then poll until 0 */ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_MAC_ENABLE; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* 0x4C[23] = 0x4E[7] = 1, switch DPDT_SEL_P output from WL BB */ + /* + * Note: Vendor driver actually clears this bit, despite the + * documentation claims it's being set! + */ + val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); + val8 |= LEDCFG2_DPDT_SELECT; + val8 &= ~LEDCFG2_DPDT_SELECT; + rtl8xxxu_write8(priv, REG_LEDCFG2, val8); + +exit: + return ret; +} + +static int rtl8723au_power_on(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + u32 val32; + int ret; + + /* + * RSV_CTRL 0x001C[7:0] = 0x00, unlock ISO/CLK/Power control register + */ + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0); + + rtl8xxxu_disabled_to_emu(priv); + + ret = rtl8723a_emu_to_active(priv); + if (ret) + goto exit; + + /* + * 0x0004[19] = 1, reset 8051 + */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2); + val8 |= BIT(3); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8); + + /* + * Enable MAC DMA/WMAC/SCHEDULE/SEC block + * Set CR bit10 to enable 32k calibration. + */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + /* For EFuse PG */ + val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL); + val32 &= ~(BIT(28) | BIT(29) | BIT(30)); + val32 |= (0x06 << 28); + rtl8xxxu_write32(priv, REG_EFUSE_CTRL, val32); +exit: + return ret; +} + +static int rtl8723au_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + int count, ret = 0; + + /* Start of rtl8723AU_card_enable_flow */ + /* Act to Cardemu sequence*/ + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0); + + /* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */ + val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); + val8 &= ~LEDCFG2_DPDT_SELECT; + rtl8xxxu_write8(priv, REG_LEDCFG2, val8); + + /* 0x0005[1] = 1 turn off MAC by HW state machine*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + if ((val8 & BIT(1)) == 0) + break; + udelay(10); + } + + if (!count) { + dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", + __func__); + ret = -EBUSY; + goto exit; + } + + /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */ + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 |= SYS_ISO_ANALOG_IPS; + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + + /* 0x0020[0] = 0 disable LDOA12 MACRO block*/ + val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); + val8 &= ~LDOA15_ENABLE; + rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); + +exit: + return ret; +} + +static int rtl8723au_emu_to_disabled(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */ + rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20); + + /* 0x04[12:11] = 01 enable WL suspend */ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~BIT(4); + val8 |= BIT(3); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= BIT(7); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); + + return 0; +} + +static void rtl8723au_power_off(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + rtl8xxxu_flush_fifo(priv); + + rtl8xxxu_active_to_lps(priv); + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + /* Reset MCU */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8723au_active_to_emu(priv); + rtl8723au_emu_to_disabled(priv); + + /* Reset MCU IO Wrapper */ + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + /* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */ + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); +} + +#define XTAL1 GENMASK(23, 18) +#define XTAL0 GENMASK(17, 12) + +void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + u32 val32; + + if (crystal_cap == cfo->crystal_cap) + return; + + val32 = rtl8xxxu_read32(priv, REG_MAC_PHY_CTRL); + + dev_dbg(&priv->udev->dev, + "%s: Adjusting crystal cap from 0x%x (actually 0x%lx 0x%lx) to 0x%x\n", + __func__, + cfo->crystal_cap, + FIELD_GET(XTAL1, val32), + FIELD_GET(XTAL0, val32), + crystal_cap); + + val32 &= ~(XTAL1 | XTAL0); + val32 |= FIELD_PREP(XTAL1, crystal_cap) | + FIELD_PREP(XTAL0, crystal_cap); + rtl8xxxu_write32(priv, REG_MAC_PHY_CTRL, val32); + + cfo->crystal_cap = crystal_cap; +} + +s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; + s8 rx_pwr_all = 0x00; + + switch (cck_agc_rpt & 0xc0) { + case 0xc0: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x80: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x40: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x00: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + + return rx_pwr_all; +} + +static int rtl8723au_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG2); + + if (brightness == LED_OFF) { + ledcfg &= ~LEDCFG2_HW_LED_CONTROL; + ledcfg |= LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE; + } else if (brightness == LED_ON) { + ledcfg &= ~(LEDCFG2_HW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE); + ledcfg |= LEDCFG2_SW_LED_CONTROL; + } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { + ledcfg &= ~LEDCFG2_SW_LED_DISABLE; + ledcfg |= LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE; + } + + rtl8xxxu_write8(priv, REG_LEDCFG2, ledcfg); + + return 0; +} + +struct rtl8xxxu_fileops rtl8723au_fops = { + .identify_chip = rtl8723au_identify_chip, + .parse_efuse = rtl8723au_parse_efuse, + .load_firmware = rtl8723au_load_firmware, + .power_on = rtl8723au_power_on, + .power_off = rtl8723au_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8xxxu_reset_8051, + .llt_init = rtl8xxxu_init_llt_table, + .init_phy_bb = rtl8xxxu_gen1_init_phy_bb, + .init_phy_rf = rtl8723au_init_phy_rf, + .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, + .phy_iq_calibrate = rtl8xxxu_gen1_phy_iq_calibrate, + .config_channel = rtl8xxxu_gen1_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc16, + .parse_phystats = rtl8723au_rx_parse_phystats, + .init_aggregation = rtl8xxxu_gen1_init_aggregation, + .enable_rf = rtl8xxxu_gen1_enable_rf, + .disable_rf = rtl8xxxu_gen1_disable_rf, + .usb_quirks = rtl8xxxu_gen1_usb_quirks, + .set_tx_power = rtl8xxxu_gen1_set_tx_power, + .update_rate_mask = rtl8xxxu_update_rate_mask, + .report_connect = rtl8xxxu_gen1_report_connect, + .report_rssi = rtl8xxxu_gen1_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v1, + .set_crystal_cap = rtl8723a_set_crystal_cap, + .cck_rssi = rtl8723a_cck_rssi, + .led_classdev_brightness_set = rtl8723au_led_brightness_set, + .writeN_block_size = 1024, + .rx_agg_buf_size = 16000, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), + .hw_feature_report = 0, + .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + .adda_2t_path_on_a = 0x04db25a4, + .adda_2t_path_on_b = 0x0b1b25a4, + .trxff_boundary = 0x27ff, + .pbp_rx = PBP_PAGE_SIZE_128, + .pbp_tx = PBP_PAGE_SIZE_128, + .mactable = rtl8723au_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM, + .page_num_hi = TX_PAGE_NUM_HI_PQ, + .page_num_lo = TX_PAGE_NUM_LO_PQ, + .page_num_norm = TX_PAGE_NUM_NORM_PQ, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/8723b.c new file mode 100644 index 000000000..24c6d8ae7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/8723b.c @@ -0,0 +1,1759 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver - 8723b specific subdriver + * + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include "regs.h" +#include "rtl8xxxu.h" + +static const struct rtl8xxxu_reg8val rtl8723b_mac_init_table[] = { + {0x02f, 0x30}, {0x035, 0x00}, {0x039, 0x08}, {0x04e, 0xe0}, + {0x064, 0x00}, {0x067, 0x20}, {0x428, 0x0a}, {0x429, 0x10}, + {0x430, 0x00}, {0x431, 0x00}, + {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, + {0x436, 0x07}, {0x437, 0x08}, {0x43c, 0x04}, {0x43d, 0x05}, + {0x43e, 0x07}, {0x43f, 0x08}, {0x440, 0x5d}, {0x441, 0x01}, + {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, {0x446, 0x00}, + {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xf0}, {0x44a, 0x0f}, + {0x44b, 0x3e}, {0x44c, 0x10}, {0x44d, 0x00}, {0x44e, 0x00}, + {0x44f, 0x00}, {0x450, 0x00}, {0x451, 0xf0}, {0x452, 0x0f}, + {0x453, 0x00}, {0x456, 0x5e}, {0x460, 0x66}, {0x461, 0x66}, + {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, + {0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, + {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, + {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, + {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, + {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, + {0x516, 0x0a}, {0x525, 0x4f}, + {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55c, 0x50}, + {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, + {0x620, 0xff}, {0x621, 0xff}, {0x622, 0xff}, {0x623, 0xff}, + {0x624, 0xff}, {0x625, 0xff}, {0x626, 0xff}, {0x627, 0xff}, + {0x638, 0x50}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e}, + {0x63f, 0x0e}, {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, + {0x652, 0xc8}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43}, + {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, + {0x70a, 0x65}, {0x70b, 0x87}, {0x765, 0x18}, {0x76e, 0x04}, + {0xffff, 0xff}, +}; + +static const struct rtl8xxxu_reg32val rtl8723b_phy_1t_init_table[] = { + {0x800, 0x80040000}, {0x804, 0x00000003}, + {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, + {0x810, 0x10001331}, {0x814, 0x020c3d10}, + {0x818, 0x02200385}, {0x81c, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00190204}, + {0x828, 0x00000000}, {0x82c, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83c, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84c, 0x00000000}, + {0x850, 0x00000000}, {0x854, 0x00000000}, + {0x858, 0x569a11a9}, {0x85c, 0x01000014}, + {0x860, 0x66f60110}, {0x864, 0x061f0649}, + {0x868, 0x00000000}, {0x86c, 0x27272700}, + {0x870, 0x07000760}, {0x874, 0x25004000}, + {0x878, 0x00000808}, {0x87c, 0x00000000}, + {0x880, 0xb0000c1c}, {0x884, 0x00000001}, + {0x888, 0x00000000}, {0x88c, 0xccc000c0}, + {0x890, 0x00000800}, {0x894, 0xfffffffe}, + {0x898, 0x40302010}, {0x89c, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90c, 0x81121111}, + {0x910, 0x00000002}, {0x914, 0x00000201}, + {0xa00, 0x00d047c8}, {0xa04, 0x80ff800c}, + {0xa08, 0x8c838300}, {0xa0c, 0x2e7f120f}, + {0xa10, 0x9500bb78}, {0xa14, 0x1114d028}, + {0xa18, 0x00881117}, {0xa1c, 0x89140f00}, + {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317}, + {0xa28, 0x00000204}, {0xa2c, 0x00d30000}, + {0xa70, 0x101fbf00}, {0xa74, 0x00000007}, + {0xa78, 0x00000900}, {0xa7c, 0x225b0606}, + {0xa80, 0x21806490}, {0xb2c, 0x00000000}, + {0xc00, 0x48071d40}, {0xc04, 0x03a05611}, + {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c}, + {0xc10, 0x08800000}, {0xc14, 0x40000100}, + {0xc18, 0x08800000}, {0xc1c, 0x40000100}, + {0xc20, 0x00000000}, {0xc24, 0x00000000}, + {0xc28, 0x00000000}, {0xc2c, 0x00000000}, + {0xc30, 0x69e9ac44}, {0xc34, 0x469652af}, + {0xc38, 0x49795994}, {0xc3c, 0x0a97971c}, + {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7}, + {0xc48, 0xec020107}, {0xc4c, 0x007f037f}, + {0xc50, 0x69553420}, {0xc54, 0x43bc0094}, + {0xc58, 0x00013149}, {0xc5c, 0x00250492}, + {0xc60, 0x00000000}, {0xc64, 0x7112848b}, + {0xc68, 0x47c00bff}, {0xc6c, 0x00000036}, + {0xc70, 0x2c7f000d}, {0xc74, 0x020610db}, + {0xc78, 0x0000001f}, {0xc7c, 0x00b91612}, + {0xc80, 0x390000e4}, {0xc84, 0x20f60000}, + {0xc88, 0x40000100}, {0xc8c, 0x20200000}, + {0xc90, 0x00020e1a}, {0xc94, 0x00000000}, + {0xc98, 0x00020e1a}, {0xc9c, 0x00007f7f}, + {0xca0, 0x00000000}, {0xca4, 0x000300a0}, + {0xca8, 0x00000000}, {0xcac, 0x00000000}, + {0xcb0, 0x00000000}, {0xcb4, 0x00000000}, + {0xcb8, 0x00000000}, {0xcbc, 0x28000000}, + {0xcc0, 0x00000000}, {0xcc4, 0x00000000}, + {0xcc8, 0x00000000}, {0xccc, 0x00000000}, + {0xcd0, 0x00000000}, {0xcd4, 0x00000000}, + {0xcd8, 0x64b22427}, {0xcdc, 0x00766932}, + {0xce0, 0x00222222}, {0xce4, 0x00000000}, + {0xce8, 0x37644302}, {0xcec, 0x2f97d40c}, + {0xd00, 0x00000740}, {0xd04, 0x40020401}, + {0xd08, 0x0000907f}, {0xd0c, 0x20010201}, + {0xd10, 0xa0633333}, {0xd14, 0x3333bc53}, + {0xd18, 0x7a8f5b6f}, {0xd2c, 0xcc979975}, + {0xd30, 0x00000000}, {0xd34, 0x80608000}, + {0xd38, 0x00000000}, {0xd3c, 0x00127353}, + {0xd40, 0x00000000}, {0xd44, 0x00000000}, + {0xd48, 0x00000000}, {0xd4c, 0x00000000}, + {0xd50, 0x6437140a}, {0xd54, 0x00000000}, + {0xd58, 0x00000282}, {0xd5c, 0x30032064}, + {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, + {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, + {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, + {0xd78, 0x000e3c24}, {0xe00, 0x2d2d2d2d}, + {0xe04, 0x2d2d2d2d}, {0xe08, 0x0390272d}, + {0xe10, 0x2d2d2d2d}, {0xe14, 0x2d2d2d2d}, + {0xe18, 0x2d2d2d2d}, {0xe1c, 0x2d2d2d2d}, + {0xe28, 0x00000000}, {0xe30, 0x1000dc1f}, + {0xe34, 0x10008c1f}, {0xe38, 0x02140102}, + {0xe3c, 0x681604c2}, {0xe40, 0x01007c00}, + {0xe44, 0x01004800}, {0xe48, 0xfb000000}, + {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f}, + {0xe54, 0x10008c1f}, {0xe58, 0x02140102}, + {0xe5c, 0x28160d05}, {0xe60, 0x00000008}, + {0xe68, 0x001b2556}, {0xe6c, 0x00c00096}, + {0xe70, 0x00c00096}, {0xe74, 0x01000056}, + {0xe78, 0x01000014}, {0xe7c, 0x01000056}, + {0xe80, 0x01000014}, {0xe84, 0x00c00096}, + {0xe88, 0x01000056}, {0xe8c, 0x00c00096}, + {0xed0, 0x00c00096}, {0xed4, 0x00c00096}, + {0xed8, 0x00c00096}, {0xedc, 0x000000d6}, + {0xee0, 0x000000d6}, {0xeec, 0x01c00016}, + {0xf14, 0x00000003}, {0xf4c, 0x00000000}, + {0xf00, 0x00000300}, + {0x820, 0x01000100}, {0x800, 0x83040000}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8xxx_agc_8723bu_table[] = { + {0xc78, 0xfd000001}, {0xc78, 0xfc010001}, + {0xc78, 0xfb020001}, {0xc78, 0xfa030001}, + {0xc78, 0xf9040001}, {0xc78, 0xf8050001}, + {0xc78, 0xf7060001}, {0xc78, 0xf6070001}, + {0xc78, 0xf5080001}, {0xc78, 0xf4090001}, + {0xc78, 0xf30a0001}, {0xc78, 0xf20b0001}, + {0xc78, 0xf10c0001}, {0xc78, 0xf00d0001}, + {0xc78, 0xef0e0001}, {0xc78, 0xee0f0001}, + {0xc78, 0xed100001}, {0xc78, 0xec110001}, + {0xc78, 0xeb120001}, {0xc78, 0xea130001}, + {0xc78, 0xe9140001}, {0xc78, 0xe8150001}, + {0xc78, 0xe7160001}, {0xc78, 0xe6170001}, + {0xc78, 0xe5180001}, {0xc78, 0xe4190001}, + {0xc78, 0xe31a0001}, {0xc78, 0xa51b0001}, + {0xc78, 0xa41c0001}, {0xc78, 0xa31d0001}, + {0xc78, 0x671e0001}, {0xc78, 0x661f0001}, + {0xc78, 0x65200001}, {0xc78, 0x64210001}, + {0xc78, 0x63220001}, {0xc78, 0x4a230001}, + {0xc78, 0x49240001}, {0xc78, 0x48250001}, + {0xc78, 0x47260001}, {0xc78, 0x46270001}, + {0xc78, 0x45280001}, {0xc78, 0x44290001}, + {0xc78, 0x432a0001}, {0xc78, 0x422b0001}, + {0xc78, 0x292c0001}, {0xc78, 0x282d0001}, + {0xc78, 0x272e0001}, {0xc78, 0x262f0001}, + {0xc78, 0x0a300001}, {0xc78, 0x09310001}, + {0xc78, 0x08320001}, {0xc78, 0x07330001}, + {0xc78, 0x06340001}, {0xc78, 0x05350001}, + {0xc78, 0x04360001}, {0xc78, 0x03370001}, + {0xc78, 0x02380001}, {0xc78, 0x01390001}, + {0xc78, 0x013a0001}, {0xc78, 0x013b0001}, + {0xc78, 0x013c0001}, {0xc78, 0x013d0001}, + {0xc78, 0x013e0001}, {0xc78, 0x013f0001}, + {0xc78, 0xfc400001}, {0xc78, 0xfb410001}, + {0xc78, 0xfa420001}, {0xc78, 0xf9430001}, + {0xc78, 0xf8440001}, {0xc78, 0xf7450001}, + {0xc78, 0xf6460001}, {0xc78, 0xf5470001}, + {0xc78, 0xf4480001}, {0xc78, 0xf3490001}, + {0xc78, 0xf24a0001}, {0xc78, 0xf14b0001}, + {0xc78, 0xf04c0001}, {0xc78, 0xef4d0001}, + {0xc78, 0xee4e0001}, {0xc78, 0xed4f0001}, + {0xc78, 0xec500001}, {0xc78, 0xeb510001}, + {0xc78, 0xea520001}, {0xc78, 0xe9530001}, + {0xc78, 0xe8540001}, {0xc78, 0xe7550001}, + {0xc78, 0xe6560001}, {0xc78, 0xe5570001}, + {0xc78, 0xe4580001}, {0xc78, 0xe3590001}, + {0xc78, 0xa65a0001}, {0xc78, 0xa55b0001}, + {0xc78, 0xa45c0001}, {0xc78, 0xa35d0001}, + {0xc78, 0x675e0001}, {0xc78, 0x665f0001}, + {0xc78, 0x65600001}, {0xc78, 0x64610001}, + {0xc78, 0x63620001}, {0xc78, 0x62630001}, + {0xc78, 0x61640001}, {0xc78, 0x48650001}, + {0xc78, 0x47660001}, {0xc78, 0x46670001}, + {0xc78, 0x45680001}, {0xc78, 0x44690001}, + {0xc78, 0x436a0001}, {0xc78, 0x426b0001}, + {0xc78, 0x286c0001}, {0xc78, 0x276d0001}, + {0xc78, 0x266e0001}, {0xc78, 0x256f0001}, + {0xc78, 0x24700001}, {0xc78, 0x09710001}, + {0xc78, 0x08720001}, {0xc78, 0x07730001}, + {0xc78, 0x06740001}, {0xc78, 0x05750001}, + {0xc78, 0x04760001}, {0xc78, 0x03770001}, + {0xc78, 0x02780001}, {0xc78, 0x01790001}, + {0xc78, 0x017a0001}, {0xc78, 0x017b0001}, + {0xc78, 0x017c0001}, {0xc78, 0x017d0001}, + {0xc78, 0x017e0001}, {0xc78, 0x017f0001}, + {0xc50, 0x69553422}, + {0xc50, 0x69553420}, + {0x824, 0x00390204}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregval rtl8723bu_radioa_1t_init_table[] = { + {0x00, 0x00010000}, {0xb0, 0x000dffe0}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0xb1, 0x00000018}, + {0xfe, 0x00000000}, {0xfe, 0x00000000}, + {0xfe, 0x00000000}, {0xb2, 0x00084c00}, + {0xb5, 0x0000d2cc}, {0xb6, 0x000925aa}, + {0xb7, 0x00000010}, {0xb8, 0x0000907f}, + {0x5c, 0x00000002}, {0x7c, 0x00000002}, + {0x7e, 0x00000005}, {0x8b, 0x0006fc00}, + {0xb0, 0x000ff9f0}, {0x1c, 0x000739d2}, + {0x1e, 0x00000000}, {0xdf, 0x00000780}, + {0x50, 0x00067435}, + /* + * The 8723bu vendor driver indicates that bit 8 should be set in + * 0x51 for package types TFBGA90, TFBGA80, and TFBGA79. However + * they never actually check the package type - and just default + * to not setting it. + */ + {0x51, 0x0006b04e}, + {0x52, 0x000007d2}, {0x53, 0x00000000}, + {0x54, 0x00050400}, {0x55, 0x0004026e}, + {0xdd, 0x0000004c}, {0x70, 0x00067435}, + /* + * 0x71 has same package type condition as for register 0x51 + */ + {0x71, 0x0006b04e}, + {0x72, 0x000007d2}, {0x73, 0x00000000}, + {0x74, 0x00050400}, {0x75, 0x0004026e}, + {0xef, 0x00000100}, {0x34, 0x0000add7}, + {0x35, 0x00005c00}, {0x34, 0x00009dd4}, + {0x35, 0x00005000}, {0x34, 0x00008dd1}, + {0x35, 0x00004400}, {0x34, 0x00007dce}, + {0x35, 0x00003800}, {0x34, 0x00006cd1}, + {0x35, 0x00004400}, {0x34, 0x00005cce}, + {0x35, 0x00003800}, {0x34, 0x000048ce}, + {0x35, 0x00004400}, {0x34, 0x000034ce}, + {0x35, 0x00003800}, {0x34, 0x00002451}, + {0x35, 0x00004400}, {0x34, 0x0000144e}, + {0x35, 0x00003800}, {0x34, 0x00000051}, + {0x35, 0x00004400}, {0xef, 0x00000000}, + {0xef, 0x00000100}, {0xed, 0x00000010}, + {0x44, 0x0000add7}, {0x44, 0x00009dd4}, + {0x44, 0x00008dd1}, {0x44, 0x00007dce}, + {0x44, 0x00006cc1}, {0x44, 0x00005cce}, + {0x44, 0x000044d1}, {0x44, 0x000034ce}, + {0x44, 0x00002451}, {0x44, 0x0000144e}, + {0x44, 0x00000051}, {0xef, 0x00000000}, + {0xed, 0x00000000}, {0x7f, 0x00020080}, + {0xef, 0x00002000}, {0x3b, 0x000380ef}, + {0x3b, 0x000302fe}, {0x3b, 0x00028ce6}, + {0x3b, 0x000200bc}, {0x3b, 0x000188a5}, + {0x3b, 0x00010fbc}, {0x3b, 0x00008f71}, + {0x3b, 0x00000900}, {0xef, 0x00000000}, + {0xed, 0x00000001}, {0x40, 0x000380ef}, + {0x40, 0x000302fe}, {0x40, 0x00028ce6}, + {0x40, 0x000200bc}, {0x40, 0x000188a5}, + {0x40, 0x00010fbc}, {0x40, 0x00008f71}, + {0x40, 0x00000900}, {0xed, 0x00000000}, + {0x82, 0x00080000}, {0x83, 0x00008000}, + {0x84, 0x00048d80}, {0x85, 0x00068000}, + {0xa2, 0x00080000}, {0xa3, 0x00008000}, + {0xa4, 0x00048d80}, {0xa5, 0x00068000}, + {0xed, 0x00000002}, {0xef, 0x00000002}, + {0x56, 0x00000032}, {0x76, 0x00000032}, + {0x01, 0x00000780}, + {0xff, 0xffffffff} +}; + +static int rtl8723bu_identify_chip(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 val32, sys_cfg, vendor; + int ret = 0; + + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { + dev_info(dev, "Unsupported test chip\n"); + ret = -ENOTSUPP; + goto out; + } + + strscpy(priv->chip_name, "8723BU", sizeof(priv->chip_name)); + priv->rtl_chip = RTL8723B; + priv->rf_paths = 1; + priv->rx_paths = 1; + priv->tx_paths = 1; + + val32 = rtl8xxxu_read32(priv, REG_MULTI_FUNC_CTRL); + if (val32 & MULTI_WIFI_FUNC_EN) + priv->has_wifi = 1; + if (val32 & MULTI_BT_FUNC_EN) + priv->has_bluetooth = 1; + if (val32 & MULTI_GPS_FUNC_EN) + priv->has_gps = 1; + priv->is_multi_func = 1; + + vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK; + rtl8xxxu_identify_vendor_2bits(priv, vendor); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); + priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); + + rtl8xxxu_config_endpoints_sie(priv); + + /* + * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX + */ + if (!priv->ep_tx_count) + ret = rtl8xxxu_config_endpoints_no_sie(priv); + +out: + return ret; +} + +static void rtl8723bu_write_btreg(struct rtl8xxxu_priv *priv, u8 reg, u8 data) +{ + struct h2c_cmd h2c; + int reqnum = 0; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER; + h2c.bt_mp_oper.operreq = 0 | (reqnum << 4); + h2c.bt_mp_oper.opcode = BT_MP_OP_WRITE_REG_VALUE; + h2c.bt_mp_oper.data = data; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_mp_oper)); + + reqnum++; + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER; + h2c.bt_mp_oper.operreq = 0 | (reqnum << 4); + h2c.bt_mp_oper.opcode = BT_MP_OP_WRITE_REG_VALUE; + h2c.bt_mp_oper.addr = reg; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_mp_oper)); +} + +static void rtl8723bu_reset_8051(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 sys_func; + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL); + val8 &= ~BIT(1); + rtl8xxxu_write8(priv, REG_RSV_CTRL, val8); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + sys_func = rtl8xxxu_read16(priv, REG_SYS_FUNC); + sys_func &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL); + val8 &= ~BIT(1); + rtl8xxxu_write8(priv, REG_RSV_CTRL, val8); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + sys_func |= SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); +} + +static void +rtl8723b_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) +{ + u32 val32, ofdm, mcs; + u8 cck, ofdmbase, mcsbase; + int group, tx_idx; + + tx_idx = 0; + group = rtl8xxxu_gen2_channel_to_group(channel); + + cck = priv->cck_tx_power_index_B[group]; + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); + val32 &= 0xffff00ff; + val32 |= (cck << 8); + rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xff; + val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + ofdmbase = priv->ht40_1s_tx_power_index_B[group]; + ofdmbase += priv->ofdm_tx_power_diff[tx_idx].b; + ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm); + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm); + + mcsbase = priv->ht40_1s_tx_power_index_B[group]; + if (ht40) + mcsbase += priv->ht40_tx_power_diff[tx_idx++].b; + else + mcsbase += priv->ht20_tx_power_diff[tx_idx++].b; + mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs); + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs); +} + +static int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv) +{ + struct rtl8723bu_efuse *efuse = &priv->efuse_wifi.efuse8723bu; + int i; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; + + ether_addr_copy(priv->mac_addr, efuse->mac_addr); + + memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, + sizeof(efuse->tx_power_index_A.cck_base)); + memcpy(priv->cck_tx_power_index_B, efuse->tx_power_index_B.cck_base, + sizeof(efuse->tx_power_index_B.cck_base)); + + memcpy(priv->ht40_1s_tx_power_index_A, + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + memcpy(priv->ht40_1s_tx_power_index_B, + efuse->tx_power_index_B.ht40_base, + sizeof(efuse->tx_power_index_B.ht40_base)); + + priv->ofdm_tx_power_diff[0].a = + efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; + priv->ofdm_tx_power_diff[0].b = + efuse->tx_power_index_B.ht20_ofdm_1s_diff.a; + + priv->ht20_tx_power_diff[0].a = + efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + priv->ht20_tx_power_diff[0].b = + efuse->tx_power_index_B.ht20_ofdm_1s_diff.b; + + priv->ht40_tx_power_diff[0].a = 0; + priv->ht40_tx_power_diff[0].b = 0; + + for (i = 1; i < RTL8723B_TX_COUNT; i++) { + priv->ofdm_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ofdm; + priv->ofdm_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ofdm; + + priv->ht20_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht20; + priv->ht20_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht20; + + priv->ht40_tx_power_diff[i].a = + efuse->tx_power_index_A.pwr_diff[i - 1].ht40; + priv->ht40_tx_power_diff[i].b = + efuse->tx_power_index_B.pwr_diff[i - 1].ht40; + } + + priv->default_crystal_cap = priv->efuse_wifi.efuse8723bu.xtal_k & 0x3f; + + return 0; +} + +static int rtl8723bu_load_firmware(struct rtl8xxxu_priv *priv) +{ + return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8723bu_nic.bin"); +} + +static void rtl8723bu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00); + + /* 6. 0x1f[7:0] = 0x07 */ + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + /* Why? */ + rtl8xxxu_write8(priv, REG_SYS_FUNC, 0xe3); + rtl8xxxu_write8(priv, REG_AFE_XTAL_CTRL + 1, 0x80); + rtl8xxxu_init_phy_regs(priv, rtl8723b_phy_1t_init_table); + + rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8723bu_table); +} + +static int rtl8723bu_init_phy_rf(struct rtl8xxxu_priv *priv) +{ + int ret; + + ret = rtl8xxxu_init_phy_rf(priv, rtl8723bu_radioa_1t_init_table, RF_A); + /* + * PHY LCK + */ + rtl8xxxu_write_rfreg(priv, RF_A, 0xb0, 0xdfbe0); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, 0x8c01); + msleep(200); + rtl8xxxu_write_rfreg(priv, RF_A, 0xb0, 0xdffe0); + + return ret; +} + +void rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_PAD_CTRL1); + val32 &= ~(BIT(20) | BIT(24)); + rtl8xxxu_write32(priv, REG_PAD_CTRL1, val32); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_MUXCFG); + val32 &= ~BIT(4); + rtl8xxxu_write32(priv, REG_GPIO_MUXCFG, val32); + + val32 = rtl8xxxu_read32(priv, REG_GPIO_MUXCFG); + val32 |= BIT(3); + rtl8xxxu_write32(priv, REG_GPIO_MUXCFG, val32); + + val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); + val32 |= BIT(24); + rtl8xxxu_write32(priv, REG_LEDCFG0, val32); + + val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); + val32 &= ~BIT(23); + rtl8xxxu_write32(priv, REG_LEDCFG0, val32); + + val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); + val32 |= (BIT(0) | BIT(1)); + rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); + + val32 = rtl8xxxu_read32(priv, REG_RFE_CTRL_ANTA_SRC); + val32 &= 0xffffff00; + val32 |= 0x77; + rtl8xxxu_write32(priv, REG_RFE_CTRL_ANTA_SRC, val32); + + val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); + val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; + rtl8xxxu_write32(priv, REG_PWR_DATA, val32); +} + +static int rtl8723bu_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_e94, reg_e9c, path_sel, val32; + int result = 0; + + path_sel = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Enable path A PA in TX IQK mode + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0003f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xc7f87); + + /* + * Tx IQK setting + */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ea); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28110000); + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * The vendor driver indicates the USB module is always using + * S0S1 path 1 for the 8723bu. This may be different for 8192eu + */ + if (priv->rf_paths > 1) + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); + else + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); + + /* + * Bit 12 seems to be BT_GRANT, and is only found in the 8723bu. + * No trace of this in the 8192eu or 8188eu vendor drivers. + */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(1); + + /* Restore Ant Path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); +#ifdef RTL8723BU_BT + /* GNT_BT = 1 */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); +#endif + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + val32 = (reg_e9c >> 16) & 0x3ff; + if (val32 & 0x200) + val32 = 0x400 - val32; + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000) && + ((reg_e94 & 0x03ff0000) < 0x01100000) && + ((reg_e94 & 0x03ff0000) > 0x00f00000) && + val32 < 0xf) + result |= 0x01; + else /* If TX not OK, ignore RX */ + goto out; + +out: + return result; +} + +static int rtl8723bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_ea4, reg_eac, reg_e94, reg_e9c, path_sel, val32; + int result = 0; + + path_sel = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * Enable path A PA in TX IQK mode + */ + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7fb7); + + /* + * Tx IQK setting + */ + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160ff0); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28110000); + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* + * The vendor driver indicates the USB module is always using + * S0S1 path 1 for the 8723bu. This may be different for 8192eu + */ + if (priv->rf_paths > 1) + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); + else + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); + + /* + * Bit 12 seems to be BT_GRANT, and is only found in the 8723bu. + * No trace of this in the 8192eu or 8188eu vendor drivers. + */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(1); + + /* Restore Ant Path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); +#ifdef RTL8723BU_BT + /* GNT_BT = 1 */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); +#endif + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + + val32 = (reg_e9c >> 16) & 0x3ff; + if (val32 & 0x200) + val32 = 0x400 - val32; + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000) && + ((reg_e94 & 0x03ff0000) < 0x01100000) && + ((reg_e94 & 0x03ff0000) > 0x00f00000) && + val32 < 0xf) + result |= 0x01; + else /* If TX not OK, ignore RX */ + goto out; + + val32 = 0x80007c00 | (reg_e94 &0x3ff0000) | + ((reg_e9c & 0x3ff0000) >> 16); + rtl8xxxu_write32(priv, REG_TX_IQK, val32); + + /* + * Modify RX IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7d77); + + /* + * PA, PAD setting + */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0xf80); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55, 0x4021f); + + /* + * RX IQK setting + */ + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); + + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82110000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x2816001f); + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a8d1); + + /* + * Enter IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + if (priv->rf_paths > 1) + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); + else + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); + + /* + * Disable BT + */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(1); + + /* Restore Ant Path */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); +#ifdef RTL8723BU_BT + /* GNT_BT = 1 */ + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); +#endif + + /* + * Leave IQK mode + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x780); + + val32 = (reg_eac >> 16) & 0x3ff; + if (val32 & 0x200) + val32 = 0x400 - val32; + + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000) && + ((reg_ea4 & 0x03ff0000) < 0x01100000) && + ((reg_ea4 & 0x03ff0000) > 0x00f00000) && + val32 < 0xf) + result |= 0x02; + else /* If TX not OK, ignore RX */ + goto out; +out: + return result; +} + +static void rtl8723bu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32; + int path_a_ok /*, path_b_ok */; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE + }; + u8 xa_agc = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1) & 0xff; + u8 xb_agc = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1) & 0xff; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + /* MAC settings */ + rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); + + val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); + val32 |= 0x0f000000; + rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); + + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22204000); + + /* + * RX IQ calibration setting for 8723B D cut large current issue + * when leaving IPS + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7fb7); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED); + val32 |= 0x20; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED, val32); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_43, 0x60fbd); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8723bu_iqk_path_a(priv); + if (path_a_ok == 0x01) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A TX IQK failed!\n", __func__); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8723bu_rx_iqk_path_a(priv); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + + break; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A RX IQK failed!\n", __func__); + + if (priv->tx_paths > 1) { +#if 1 + dev_warn(dev, "%s: Path B not supported\n", __func__); +#else + + /* + * Path A into standby + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x10000); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + val32 |= 0x80800000; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + /* Turn Path B ADDA on */ + rtl8xxxu_path_adda_on(priv, adda_regs, false); + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8xxxu_iqk_path_b(priv); + if (path_b_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + result[t][4] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + result[t][5] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_b_ok) + dev_dbg(dev, "%s: Path B IQK failed!\n", __func__); + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8723bu_rx_iqk_path_b(priv); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_B_2); + result[t][6] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_B_2); + result[t][7] = (val32 >> 16) & 0x3ff; + break; + } + } + + if (!path_b_ok) + dev_dbg(dev, "%s: Path B RX IQK failed!\n", __func__); +#endif + } + + /* Back to BB mode, load original value */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 &= 0x000000ff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + + if (t) { + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Restore RX initial gain */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); + val32 &= 0xffffff00; + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | 0x50); + rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | xa_agc); + + if (priv->tx_paths > 1) { + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1); + val32 &= 0xffffff00; + rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, + val32 | 0x50); + rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, + val32 | xb_agc); + } + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); + } +} + +static void rtl8723bu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok, path_b_ok; + u32 reg_e94, reg_e9c, reg_ea4, reg_eac; + u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u32 val32, bt_control; + s32 reg_tmp = 0; + bool simu; + + rtl8xxxu_gen2_prepare_calibrate(priv, 1); + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + path_b_ok = false; + + bt_control = rtl8xxxu_read32(priv, REG_BT_CONTROL_8723BU); + + for (i = 0; i < 3; i++) { + rtl8723bu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_gen2_simularity_compare(priv, + result, 1, 2); + if (simu) { + candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp) + candidate = 3; + else + candidate = -1; + } + } + } + + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + priv->rege94 = reg_e94; + reg_e9c = result[candidate][1]; + priv->rege9c = reg_e9c; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + priv->regeb4 = reg_eb4; + reg_ebc = result[candidate][5]; + priv->regebc = reg_ebc; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, + "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", + __func__, reg_e94, reg_e9c, + reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); + path_a_ok = true; + path_b_ok = true; + } else { + reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; + reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; + } + + if (reg_e94 && candidate >= 0) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + if (priv->tx_paths > 1 && reg_eb4) + rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, + candidate, (reg_ec4 == 0)); + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); + + rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, bt_control); + + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); + val32 |= 0x80000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x18000); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xe6177); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED); + val32 |= 0x20; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED, val32); + rtl8xxxu_write_rfreg(priv, RF_A, 0x43, 0x300bd); + + if (priv->rf_paths > 1) + dev_dbg(dev, "%s: 8723BU 2T not supported\n", __func__); + + rtl8xxxu_gen2_prepare_calibrate(priv, 0); +} + +static int rtl8723bu_active_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + u32 val32; + int count, ret = 0; + + /* Turn off RF */ + rtl8xxxu_write8(priv, REG_RF_CTRL, 0); + + /* Enable rising edge triggering interrupt */ + val16 = rtl8xxxu_read16(priv, REG_GPIO_INTM); + val16 &= ~GPIO_INTM_EDGE_TRIG_IRQ; + rtl8xxxu_write16(priv, REG_GPIO_INTM, val16); + + /* Release WLON reset 0x04[16]= 1*/ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_WLON_RESET; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + /* 0x0005[1] = 1 turn off MAC by HW state machine*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + if ((val8 & BIT(1)) == 0) + break; + udelay(10); + } + + if (!count) { + dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", + __func__); + ret = -EBUSY; + goto exit; + } + + /* Enable BT control XTAL setting */ + val8 = rtl8xxxu_read8(priv, REG_AFE_MISC); + val8 &= ~AFE_MISC_WL_XTAL_CTRL; + rtl8xxxu_write8(priv, REG_AFE_MISC, val8); + + /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */ + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 |= SYS_ISO_ANALOG_IPS; + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + + /* 0x0020[0] = 0 disable LDOA12 MACRO block*/ + val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); + val8 &= ~LDOA15_ENABLE; + rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); + +exit: + return ret; +} + +static int rtl8723b_emu_to_active(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + int count, ret = 0; + + /* 0x20[0] = 1 enable LDOA12 MACRO block for all interface */ + val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); + val8 |= LDOA15_ENABLE; + rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); + + /* 0x67[0] = 0 to disable BT_GPS_SEL pins*/ + val8 = rtl8xxxu_read8(priv, 0x0067); + val8 &= ~BIT(4); + rtl8xxxu_write8(priv, 0x0067, val8); + + mdelay(1); + + /* 0x00[5] = 0 release analog Ips to digital, 1:isolation */ + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); + val8 &= ~SYS_ISO_ANALOG_IPS; + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); + + /* Disable SW LPS 0x04[10]= 0 */ + val32 = rtl8xxxu_read8(priv, REG_APS_FSMCO); + val32 &= ~APS_FSMCO_SW_LPS; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + /* Wait until 0x04[17] = 1 power ready */ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if (val32 & BIT(17)) + break; + + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* We should be able to optimize the following three entries into one */ + + /* Release WLON reset 0x04[16]= 1*/ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_WLON_RESET; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + /* Disable HWPDN 0x04[15]= 0*/ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 &= ~APS_FSMCO_HW_POWERDOWN; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + /* Disable WL suspend*/ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 &= ~(APS_FSMCO_HW_SUSPEND | APS_FSMCO_PCIE); + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + /* Set, then poll until 0 */ + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + val32 |= APS_FSMCO_MAC_ENABLE; + rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); + + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); + if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { + ret = 0; + break; + } + udelay(10); + } + + if (!count) { + ret = -EBUSY; + goto exit; + } + + /* Enable WL control XTAL setting */ + val8 = rtl8xxxu_read8(priv, REG_AFE_MISC); + val8 |= AFE_MISC_WL_XTAL_CTRL; + rtl8xxxu_write8(priv, REG_AFE_MISC, val8); + + /* Enable falling edge triggering interrupt */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 1); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_GPIO_INTM + 1, val8); + + /* Enable GPIO9 interrupt mode */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL_2 + 1); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_GPIO_IO_SEL_2 + 1, val8); + + /* Enable GPIO9 input mode */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL_2); + val8 &= ~BIT(1); + rtl8xxxu_write8(priv, REG_GPIO_IO_SEL_2, val8); + + /* Enable HSISR GPIO[C:0] interrupt */ + val8 = rtl8xxxu_read8(priv, REG_HSIMR); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_HSIMR, val8); + + /* Enable HSISR GPIO9 interrupt */ + val8 = rtl8xxxu_read8(priv, REG_HSIMR + 2); + val8 |= BIT(1); + rtl8xxxu_write8(priv, REG_HSIMR + 2, val8); + + val8 = rtl8xxxu_read8(priv, REG_MULTI_FUNC_CTRL); + val8 |= MULTI_WIFI_HW_ROF_EN; + rtl8xxxu_write8(priv, REG_MULTI_FUNC_CTRL, val8); + + /* For GPIO9 internal pull high setting BIT(14) */ + val8 = rtl8xxxu_read8(priv, REG_MULTI_FUNC_CTRL + 1); + val8 |= BIT(6); + rtl8xxxu_write8(priv, REG_MULTI_FUNC_CTRL + 1, val8); + +exit: + return ret; +} + +static int rtl8723bu_power_on(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + u32 val32; + int ret; + + rtl8xxxu_disabled_to_emu(priv); + + ret = rtl8723b_emu_to_active(priv); + if (ret) + goto exit; + + /* + * Enable MAC DMA/WMAC/SCHEDULE/SEC block + * Set CR bit10 to enable 32k calibration. + */ + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | + CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | + CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | + CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | + CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); + rtl8xxxu_write16(priv, REG_CR, val16); + + /* + * BT coexist power on settings. This is identical for 1 and 2 + * antenna parts. + */ + rtl8xxxu_write8(priv, REG_PAD_CTRL1 + 3, 0x20); + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BBRSTB | SYS_FUNC_BB_GLB_RSTN; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + rtl8xxxu_write8(priv, REG_BT_CONTROL_8723BU + 1, 0x18); + rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04); + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00); + /* Antenna inverse */ + rtl8xxxu_write8(priv, 0xfe08, 0x01); + + val16 = rtl8xxxu_read16(priv, REG_PWR_DATA); + val16 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; + rtl8xxxu_write16(priv, REG_PWR_DATA, val16); + + val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); + val32 |= LEDCFG0_DPDT_SELECT; + rtl8xxxu_write32(priv, REG_LEDCFG0, val32); + + val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); + val8 &= ~PAD_CTRL1_SW_DPDT_SEL_DATA; + rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); +exit: + return ret; +} + +static void rtl8723bu_power_off(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 val16; + + rtl8xxxu_flush_fifo(priv); + + /* + * Disable TX report timer + */ + val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); + val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); + + rtl8xxxu_write8(priv, REG_CR, 0x0000); + + rtl8xxxu_active_to_lps(priv); + + /* Reset Firmware if running in RAM */ + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) + rtl8xxxu_firmware_self_reset(priv); + + /* Reset MCU */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + /* Reset MCU ready status */ + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); + + rtl8723bu_active_to_emu(priv); + + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 |= BIT(3); /* APS_FSMCO_HW_SUSPEND */ + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); +} + +static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv) +{ + struct h2c_cmd h2c; + u32 val32; + u8 val8; + + val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); + val32 |= (BIT(22) | BIT(23)); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); + + /* + * No indication anywhere as to what 0x0790 does. The 2 antenna + * vendor code preserves bits 6-7 here. + */ + rtl8xxxu_write8(priv, 0x0790, 0x05); + /* + * 0x0778 seems to be related to enabling the number of antennas + * In the vendor driver halbtc8723b2ant_InitHwConfig() sets it + * to 0x03, while halbtc8723b1ant_InitHwConfig() sets it to 0x01 + */ + rtl8xxxu_write8(priv, 0x0778, 0x01); + + val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); + val8 |= BIT(5); + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_IQADJ_G1, 0x780); + + rtl8723bu_write_btreg(priv, 0x3c, 0x15); /* BT TRx Mask on */ + + /* + * Set BT grant to low + */ + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.bt_grant.cmd = H2C_8723B_BT_GRANT; + h2c.bt_grant.data = 0; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_grant)); + + /* + * WLAN action by PTA + */ + rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x0c); + + /* + * BT select S0/S1 controlled by WiFi + */ + val8 = rtl8xxxu_read8(priv, 0x0067); + val8 |= BIT(5); + rtl8xxxu_write8(priv, 0x0067, val8); + + val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); + val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; + rtl8xxxu_write32(priv, REG_PWR_DATA, val32); + + /* + * Bits 6/7 are marked in/out ... but for what? + */ + rtl8xxxu_write8(priv, 0x0974, 0xff); + + val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); + val32 |= (BIT(0) | BIT(1)); + rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); + + rtl8xxxu_write8(priv, REG_RFE_CTRL_ANTA_SRC, 0x77); + + val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); + val32 &= ~BIT(24); + val32 |= BIT(23); + rtl8xxxu_write32(priv, REG_LEDCFG0, val32); + + /* + * Fix external switch Main->S1, Aux->S0 + */ + val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.ant_sel_rsv.cmd = H2C_8723B_ANT_SEL_RSV; + h2c.ant_sel_rsv.ant_inverse = 1; + h2c.ant_sel_rsv.int_switch_type = 0; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.ant_sel_rsv)); + + /* + * Different settings per different antenna position. + * Antenna Position: | Normal Inverse + * -------------------------------------------------- + * Antenna switch to BT: | 0x280, 0x00 + * Antenna switch to WiFi: | 0x0, 0x280 + * Antenna switch to PTA: | 0x200, 0x80 + */ + rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x80); + + /* + * Software control, antenna at WiFi side + */ + rtl8723bu_set_ps_tdma(priv, 0x08, 0x00, 0x00, 0x00, 0x00); + + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.bt_info.cmd = H2C_8723B_BT_INFO; + h2c.bt_info.data = BIT(0); + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_info)); + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.ignore_wlan.cmd = H2C_8723B_BT_IGNORE_WLANACT; + h2c.ignore_wlan.data = 0; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.ignore_wlan)); +} + +static void rtl8723bu_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u32 agg_rx; + u8 agg_ctrl; + + /* + * For now simply disable RX aggregation + */ + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + + agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); + agg_rx &= ~RXDMA_USB_AGG_ENABLE; + agg_rx &= ~0xff0f; + + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); +} + +static void rtl8723bu_init_statistics(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + /* Time duration for NHM unit: 4us, 0x2710=40ms */ + rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0x2710); + rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff); + rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff52); + rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff); + /* TH8 */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); + val32 |= 0xff; + rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); + /* Enable CCK */ + val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B); + val32 |= BIT(8) | BIT(9) | BIT(10); + rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32); + /* Max power amongst all RX antennas */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC); + val32 |= BIT(7); + rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); +} + +static s8 rtl8723b_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) +{ + u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; + s8 rx_pwr_all = 0x00; + u8 vga_idx, lna_idx; + + lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); + vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); + + switch (lna_idx) { + case 6: + rx_pwr_all = -34 - (2 * vga_idx); + break; + case 4: + rx_pwr_all = -14 - (2 * vga_idx); + break; + case 1: + rx_pwr_all = 6 - (2 * vga_idx); + break; + case 0: + rx_pwr_all = 16 - (2 * vga_idx); + break; + default: + break; + } + + return rx_pwr_all; +} + +static int rtl8723bu_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); + u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG2); + + ledcfg &= LEDCFG2_DPDT_SELECT; + + if (brightness == LED_OFF) + ledcfg |= LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE; + else if (brightness == LED_ON) + ledcfg |= LEDCFG2_SW_LED_CONTROL; + else if (brightness == RTL8XXXU_HW_LED_CONTROL) + ledcfg |= LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE; + + rtl8xxxu_write8(priv, REG_LEDCFG2, ledcfg); + + return 0; +} + +struct rtl8xxxu_fileops rtl8723bu_fops = { + .identify_chip = rtl8723bu_identify_chip, + .parse_efuse = rtl8723bu_parse_efuse, + .load_firmware = rtl8723bu_load_firmware, + .power_on = rtl8723bu_power_on, + .power_off = rtl8723bu_power_off, + .read_efuse = rtl8xxxu_read_efuse, + .reset_8051 = rtl8723bu_reset_8051, + .llt_init = rtl8xxxu_auto_llt_table, + .init_phy_bb = rtl8723bu_init_phy_bb, + .init_phy_rf = rtl8723bu_init_phy_rf, + .phy_init_antenna_selection = rtl8723bu_phy_init_antenna_selection, + .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, + .phy_iq_calibrate = rtl8723bu_phy_iq_calibrate, + .config_channel = rtl8xxxu_gen2_config_channel, + .parse_rx_desc = rtl8xxxu_parse_rxdesc24, + .parse_phystats = rtl8723au_rx_parse_phystats, + .init_aggregation = rtl8723bu_init_aggregation, + .init_statistics = rtl8723bu_init_statistics, + .init_burst = rtl8xxxu_init_burst, + .enable_rf = rtl8723b_enable_rf, + .disable_rf = rtl8xxxu_gen2_disable_rf, + .usb_quirks = rtl8xxxu_gen2_usb_quirks, + .set_tx_power = rtl8723b_set_tx_power, + .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, + .report_connect = rtl8xxxu_gen2_report_connect, + .report_rssi = rtl8xxxu_gen2_report_rssi, + .fill_txdesc = rtl8xxxu_fill_txdesc_v2, + .set_crystal_cap = rtl8723a_set_crystal_cap, + .cck_rssi = rtl8723b_cck_rssi, + .led_classdev_brightness_set = rtl8723bu_led_brightness_set, + .writeN_block_size = 1024, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), + .has_s0s1 = 1, + .has_tx_report = 1, + .gen2_thermal_meter = 1, + .needs_full_init = 1, + .init_reg_hmtfr = 1, + .hw_feature_report = 0, + .ampdu_max_time = 0x5e, + .ustime_tsf_edca = 0x50, + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 128, + .max_sec_cam_num = 64, + .adda_1t_init = 0x01c00014, + .adda_1t_path_on = 0x01c00014, + .adda_2t_path_on_a = 0x01c00014, + .adda_2t_path_on_b = 0x01c00014, + .trxff_boundary = 0x3f7f, + .pbp_rx = PBP_PAGE_SIZE_256, + .pbp_tx = PBP_PAGE_SIZE_256, + .mactable = rtl8723b_mac_init_table, + .total_page_num = TX_TOTAL_PAGE_NUM_8723B, + .page_num_hi = TX_PAGE_NUM_HI_PQ_8723B, + .page_num_lo = TX_PAGE_NUM_LO_PQ_8723B, + .page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B, +}; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig new file mode 100644 index 000000000..14d034336 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# RTL8XXXU Wireless LAN device configuration +# +config RTL8XXXU + tristate "Realtek 802.11n USB wireless chips support" + depends on MAC80211 && USB + depends on LEDS_CLASS + help + This is an alternative driver for various Realtek RTL8XXX + parts written to utilize the Linux mac80211 stack. + The driver is known to work with a number of RTL8723AU, + RL8188CU, RTL8188RU, RTL8191CU, RTL8192CU, RTL8723BU, RTL8192EU, + RTL8188FU, RTL8188EU, RTL8710BU (aka RTL8188GU), and RTL8192FU + devices. + + This driver is under development and has a limited feature + set. In particular it does not yet support 40MHz channels + and power management. However it should have a smaller + memory footprint than the vendor drivers and benefits + from the in kernel mac80211 stack. + + It can coexist with the rtlwifi driver but you will need + to control which module you wish to load. + + To compile this driver as a module, choose M here: the module will + be called rtl8xxxu. If unsure, say N. + +config RTL8XXXU_UNTESTED + bool "Include support for untested Realtek 8xxx USB devices (EXPERIMENTAL)" + depends on RTL8XXXU + help + This option enables detection of Realtek 8723/8188/8191/8192 WiFi + USB devices which have not been tested directly by the driver + author or reported to be working by third parties. + + Please report your results! diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Makefile b/drivers/net/wireless/realtek/rtl8xxxu/Makefile new file mode 100644 index 000000000..580a2fa67 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_RTL8XXXU) += rtl8xxxu.o + +rtl8xxxu-y := core.o 8192e.o 8723b.o \ + 8723a.o 8192c.o 8188f.o \ + 8188e.o 8710b.o 8192f.o diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c new file mode 100644 index 000000000..bddbd0990 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -0,0 +1,8295 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * RTL8XXXU mac80211 USB driver + * + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This driver was written as a replacement for the vendor provided + * rtl8723au driver. As the Realtek 8xxx chips are very similar in + * their programming interface, I have started adding support for + * additional 8xxx chips like the 8192cu, 8188cus, etc. + */ + +#include +#include +#include "regs.h" +#include "rtl8xxxu.h" + +#define DRIVER_NAME "rtl8xxxu" + +int rtl8xxxu_debug; +static bool rtl8xxxu_dma_aggregation; +static int rtl8xxxu_dma_agg_timeout = -1; +static int rtl8xxxu_dma_agg_pages = -1; + +MODULE_AUTHOR("Jes Sorensen "); +MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B_NoBT.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8188eufw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192eu_nic.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8723bu_nic.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8188fufw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8710bufw_SMIC.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8710bufw_UMC.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192fufw.bin"); + +module_param_named(debug, rtl8xxxu_debug, int, 0600); +MODULE_PARM_DESC(debug, "Set debug mask"); +module_param_named(dma_aggregation, rtl8xxxu_dma_aggregation, bool, 0600); +MODULE_PARM_DESC(dma_aggregation, "Enable DMA packet aggregation"); +module_param_named(dma_agg_timeout, rtl8xxxu_dma_agg_timeout, int, 0600); +MODULE_PARM_DESC(dma_agg_timeout, "Set DMA aggregation timeout (range 1-127)"); +module_param_named(dma_agg_pages, rtl8xxxu_dma_agg_pages, int, 0600); +MODULE_PARM_DESC(dma_agg_pages, "Set DMA aggregation pages (range 1-127, 0 to disable)"); + +#define USB_VENDOR_ID_REALTEK 0x0bda +#define RTL8XXXU_RX_URBS 32 +#define RTL8XXXU_RX_URB_PENDING_WATER 8 +#define RTL8XXXU_TX_URBS 64 +#define RTL8XXXU_TX_URB_LOW_WATER 25 +#define RTL8XXXU_TX_URB_HIGH_WATER 32 + +static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv, + struct rtl8xxxu_rx_urb *rx_urb); + +static struct ieee80211_rate rtl8xxxu_rates[] = { + { .bitrate = 10, .hw_value = DESC_RATE_1M, .flags = 0 }, + { .bitrate = 20, .hw_value = DESC_RATE_2M, .flags = 0 }, + { .bitrate = 55, .hw_value = DESC_RATE_5_5M, .flags = 0 }, + { .bitrate = 110, .hw_value = DESC_RATE_11M, .flags = 0 }, + { .bitrate = 60, .hw_value = DESC_RATE_6M, .flags = 0 }, + { .bitrate = 90, .hw_value = DESC_RATE_9M, .flags = 0 }, + { .bitrate = 120, .hw_value = DESC_RATE_12M, .flags = 0 }, + { .bitrate = 180, .hw_value = DESC_RATE_18M, .flags = 0 }, + { .bitrate = 240, .hw_value = DESC_RATE_24M, .flags = 0 }, + { .bitrate = 360, .hw_value = DESC_RATE_36M, .flags = 0 }, + { .bitrate = 480, .hw_value = DESC_RATE_48M, .flags = 0 }, + { .bitrate = 540, .hw_value = DESC_RATE_54M, .flags = 0 }, +}; + +static struct ieee80211_channel rtl8xxxu_channels_2g[] = { + { .band = NL80211_BAND_2GHZ, .center_freq = 2412, + .hw_value = 1, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2417, + .hw_value = 2, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2422, + .hw_value = 3, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2427, + .hw_value = 4, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2432, + .hw_value = 5, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2437, + .hw_value = 6, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2442, + .hw_value = 7, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2447, + .hw_value = 8, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2452, + .hw_value = 9, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2457, + .hw_value = 10, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2462, + .hw_value = 11, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2467, + .hw_value = 12, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2472, + .hw_value = 13, .max_power = 30 }, + { .band = NL80211_BAND_2GHZ, .center_freq = 2484, + .hw_value = 14, .max_power = 30 } +}; + +static struct ieee80211_supported_band rtl8xxxu_supported_band = { + .channels = rtl8xxxu_channels_2g, + .n_channels = ARRAY_SIZE(rtl8xxxu_channels_2g), + .bitrates = rtl8xxxu_rates, + .n_bitrates = ARRAY_SIZE(rtl8xxxu_rates), +}; + +static const struct rtl8xxxu_reg32val rtl8723a_phy_1t_init_table[] = { + {0x800, 0x80040000}, {0x804, 0x00000003}, + {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, + {0x810, 0x10001331}, {0x814, 0x020c3d10}, + {0x818, 0x02200385}, {0x81c, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390004}, + {0x828, 0x00000000}, {0x82c, 0x00000000}, + {0x830, 0x00000000}, {0x834, 0x00000000}, + {0x838, 0x00000000}, {0x83c, 0x00000000}, + {0x840, 0x00010000}, {0x844, 0x00000000}, + {0x848, 0x00000000}, {0x84c, 0x00000000}, + {0x850, 0x00000000}, {0x854, 0x00000000}, + {0x858, 0x569a569a}, {0x85c, 0x001b25a4}, + {0x860, 0x66f60110}, {0x864, 0x061f0130}, + {0x868, 0x00000000}, {0x86c, 0x32323200}, + {0x870, 0x07000760}, {0x874, 0x22004000}, + {0x878, 0x00000808}, {0x87c, 0x00000000}, + {0x880, 0xc0083070}, {0x884, 0x000004d5}, + {0x888, 0x00000000}, {0x88c, 0xccc000c0}, + {0x890, 0x00000800}, {0x894, 0xfffffffe}, + {0x898, 0x40302010}, {0x89c, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90c, 0x81121111}, + {0xa00, 0x00d047c8}, {0xa04, 0x80ff000c}, + {0xa08, 0x8c838300}, {0xa0c, 0x2e68120f}, + {0xa10, 0x9500bb78}, {0xa14, 0x11144028}, + {0xa18, 0x00881117}, {0xa1c, 0x89140f00}, + {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317}, + {0xa28, 0x00000204}, {0xa2c, 0x00d30000}, + {0xa70, 0x101fbf00}, {0xa74, 0x00000007}, + {0xa78, 0x00000900}, + {0xc00, 0x48071d40}, {0xc04, 0x03a05611}, + {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c}, + {0xc10, 0x08800000}, {0xc14, 0x40000100}, + {0xc18, 0x08800000}, {0xc1c, 0x40000100}, + {0xc20, 0x00000000}, {0xc24, 0x00000000}, + {0xc28, 0x00000000}, {0xc2c, 0x00000000}, + {0xc30, 0x69e9ac44}, {0xc34, 0x469652af}, + {0xc38, 0x49795994}, {0xc3c, 0x0a97971c}, + {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7}, + {0xc48, 0xec020107}, {0xc4c, 0x007f037f}, + {0xc50, 0x69543420}, {0xc54, 0x43bc0094}, + {0xc58, 0x69543420}, {0xc5c, 0x433c0094}, + {0xc60, 0x00000000}, {0xc64, 0x7112848b}, + {0xc68, 0x47c00bff}, {0xc6c, 0x00000036}, + {0xc70, 0x2c7f000d}, {0xc74, 0x018610db}, + {0xc78, 0x0000001f}, {0xc7c, 0x00b91612}, + {0xc80, 0x40000100}, {0xc84, 0x20f60000}, + {0xc88, 0x40000100}, {0xc8c, 0x20200000}, + {0xc90, 0x00121820}, {0xc94, 0x00000000}, + {0xc98, 0x00121820}, {0xc9c, 0x00007f7f}, + {0xca0, 0x00000000}, {0xca4, 0x00000080}, + {0xca8, 0x00000000}, {0xcac, 0x00000000}, + {0xcb0, 0x00000000}, {0xcb4, 0x00000000}, + {0xcb8, 0x00000000}, {0xcbc, 0x28000000}, + {0xcc0, 0x00000000}, {0xcc4, 0x00000000}, + {0xcc8, 0x00000000}, {0xccc, 0x00000000}, + {0xcd0, 0x00000000}, {0xcd4, 0x00000000}, + {0xcd8, 0x64b22427}, {0xcdc, 0x00766932}, + {0xce0, 0x00222222}, {0xce4, 0x00000000}, + {0xce8, 0x37644302}, {0xcec, 0x2f97d40c}, + {0xd00, 0x00080740}, {0xd04, 0x00020401}, + {0xd08, 0x0000907f}, {0xd0c, 0x20010201}, + {0xd10, 0xa0633333}, {0xd14, 0x3333bc43}, + {0xd18, 0x7a8f5b6b}, {0xd2c, 0xcc979975}, + {0xd30, 0x00000000}, {0xd34, 0x80608000}, + {0xd38, 0x00000000}, {0xd3c, 0x00027293}, + {0xd40, 0x00000000}, {0xd44, 0x00000000}, + {0xd48, 0x00000000}, {0xd4c, 0x00000000}, + {0xd50, 0x6437140a}, {0xd54, 0x00000000}, + {0xd58, 0x00000000}, {0xd5c, 0x30032064}, + {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, + {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, + {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, + {0xd78, 0x000e3c24}, {0xe00, 0x2a2a2a2a}, + {0xe04, 0x2a2a2a2a}, {0xe08, 0x03902a2a}, + {0xe10, 0x2a2a2a2a}, {0xe14, 0x2a2a2a2a}, + {0xe18, 0x2a2a2a2a}, {0xe1c, 0x2a2a2a2a}, + {0xe28, 0x00000000}, {0xe30, 0x1000dc1f}, + {0xe34, 0x10008c1f}, {0xe38, 0x02140102}, + {0xe3c, 0x681604c2}, {0xe40, 0x01007c00}, + {0xe44, 0x01004800}, {0xe48, 0xfb000000}, + {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f}, + {0xe54, 0x10008c1f}, {0xe58, 0x02140102}, + {0xe5c, 0x28160d05}, {0xe60, 0x00000008}, + {0xe68, 0x001b25a4}, {0xe6c, 0x631b25a0}, + {0xe70, 0x631b25a0}, {0xe74, 0x081b25a0}, + {0xe78, 0x081b25a0}, {0xe7c, 0x081b25a0}, + {0xe80, 0x081b25a0}, {0xe84, 0x631b25a0}, + {0xe88, 0x081b25a0}, {0xe8c, 0x631b25a0}, + {0xed0, 0x631b25a0}, {0xed4, 0x631b25a0}, + {0xed8, 0x631b25a0}, {0xedc, 0x001b25a0}, + {0xee0, 0x001b25a0}, {0xeec, 0x6b1b25a0}, + {0xf14, 0x00000003}, {0xf4c, 0x00000000}, + {0xf00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8192cu_phy_2t_init_table[] = { + {0x024, 0x0011800f}, {0x028, 0x00ffdb83}, + {0x800, 0x80040002}, {0x804, 0x00000003}, + {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, + {0x810, 0x10000330}, {0x814, 0x020c3d10}, + {0x818, 0x02200385}, {0x81c, 0x00000000}, + {0x820, 0x01000100}, {0x824, 0x00390004}, + {0x828, 0x01000100}, {0x82c, 0x00390004}, + {0x830, 0x27272727}, {0x834, 0x27272727}, + {0x838, 0x27272727}, {0x83c, 0x27272727}, + {0x840, 0x00010000}, {0x844, 0x00010000}, + {0x848, 0x27272727}, {0x84c, 0x27272727}, + {0x850, 0x00000000}, {0x854, 0x00000000}, + {0x858, 0x569a569a}, {0x85c, 0x0c1b25a4}, + {0x860, 0x66e60230}, {0x864, 0x061f0130}, + {0x868, 0x27272727}, {0x86c, 0x2b2b2b27}, + {0x870, 0x07000700}, {0x874, 0x22184000}, + {0x878, 0x08080808}, {0x87c, 0x00000000}, + {0x880, 0xc0083070}, {0x884, 0x000004d5}, + {0x888, 0x00000000}, {0x88c, 0xcc0000c0}, + {0x890, 0x00000800}, {0x894, 0xfffffffe}, + {0x898, 0x40302010}, {0x89c, 0x00706050}, + {0x900, 0x00000000}, {0x904, 0x00000023}, + {0x908, 0x00000000}, {0x90c, 0x81121313}, + {0xa00, 0x00d047c8}, {0xa04, 0x80ff000c}, + {0xa08, 0x8c838300}, {0xa0c, 0x2e68120f}, + {0xa10, 0x9500bb78}, {0xa14, 0x11144028}, + {0xa18, 0x00881117}, {0xa1c, 0x89140f00}, + {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317}, + {0xa28, 0x00000204}, {0xa2c, 0x00d30000}, + {0xa70, 0x101fbf00}, {0xa74, 0x00000007}, + {0xc00, 0x48071d40}, {0xc04, 0x03a05633}, + {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c}, + {0xc10, 0x08800000}, {0xc14, 0x40000100}, + {0xc18, 0x08800000}, {0xc1c, 0x40000100}, + {0xc20, 0x00000000}, {0xc24, 0x00000000}, + {0xc28, 0x00000000}, {0xc2c, 0x00000000}, + {0xc30, 0x69e9ac44}, {0xc34, 0x469652cf}, + {0xc38, 0x49795994}, {0xc3c, 0x0a97971c}, + {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7}, + {0xc48, 0xec020107}, {0xc4c, 0x007f037f}, + {0xc50, 0x69543420}, {0xc54, 0x43bc0094}, + {0xc58, 0x69543420}, {0xc5c, 0x433c0094}, + {0xc60, 0x00000000}, {0xc64, 0x5116848b}, + {0xc68, 0x47c00bff}, {0xc6c, 0x00000036}, + {0xc70, 0x2c7f000d}, {0xc74, 0x2186115b}, + {0xc78, 0x0000001f}, {0xc7c, 0x00b99612}, + {0xc80, 0x40000100}, {0xc84, 0x20f60000}, + {0xc88, 0x40000100}, {0xc8c, 0xa0e40000}, + {0xc90, 0x00121820}, {0xc94, 0x00000000}, + {0xc98, 0x00121820}, {0xc9c, 0x00007f7f}, + {0xca0, 0x00000000}, {0xca4, 0x00000080}, + {0xca8, 0x00000000}, {0xcac, 0x00000000}, + {0xcb0, 0x00000000}, {0xcb4, 0x00000000}, + {0xcb8, 0x00000000}, {0xcbc, 0x28000000}, + {0xcc0, 0x00000000}, {0xcc4, 0x00000000}, + {0xcc8, 0x00000000}, {0xccc, 0x00000000}, + {0xcd0, 0x00000000}, {0xcd4, 0x00000000}, + {0xcd8, 0x64b22427}, {0xcdc, 0x00766932}, + {0xce0, 0x00222222}, {0xce4, 0x00000000}, + {0xce8, 0x37644302}, {0xcec, 0x2f97d40c}, + {0xd00, 0x00080740}, {0xd04, 0x00020403}, + {0xd08, 0x0000907f}, {0xd0c, 0x20010201}, + {0xd10, 0xa0633333}, {0xd14, 0x3333bc43}, + {0xd18, 0x7a8f5b6b}, {0xd2c, 0xcc979975}, + {0xd30, 0x00000000}, {0xd34, 0x80608000}, + {0xd38, 0x00000000}, {0xd3c, 0x00027293}, + {0xd40, 0x00000000}, {0xd44, 0x00000000}, + {0xd48, 0x00000000}, {0xd4c, 0x00000000}, + {0xd50, 0x6437140a}, {0xd54, 0x00000000}, + {0xd58, 0x00000000}, {0xd5c, 0x30032064}, + {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, + {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, + {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, + {0xd78, 0x000e3c24}, {0xe00, 0x2a2a2a2a}, + {0xe04, 0x2a2a2a2a}, {0xe08, 0x03902a2a}, + {0xe10, 0x2a2a2a2a}, {0xe14, 0x2a2a2a2a}, + {0xe18, 0x2a2a2a2a}, {0xe1c, 0x2a2a2a2a}, + {0xe28, 0x00000000}, {0xe30, 0x1000dc1f}, + {0xe34, 0x10008c1f}, {0xe38, 0x02140102}, + {0xe3c, 0x681604c2}, {0xe40, 0x01007c00}, + {0xe44, 0x01004800}, {0xe48, 0xfb000000}, + {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f}, + {0xe54, 0x10008c1f}, {0xe58, 0x02140102}, + {0xe5c, 0x28160d05}, {0xe60, 0x00000010}, + {0xe68, 0x001b25a4}, {0xe6c, 0x63db25a4}, + {0xe70, 0x63db25a4}, {0xe74, 0x0c1b25a4}, + {0xe78, 0x0c1b25a4}, {0xe7c, 0x0c1b25a4}, + {0xe80, 0x0c1b25a4}, {0xe84, 0x63db25a4}, + {0xe88, 0x0c1b25a4}, {0xe8c, 0x63db25a4}, + {0xed0, 0x63db25a4}, {0xed4, 0x63db25a4}, + {0xed8, 0x63db25a4}, {0xedc, 0x001b25a4}, + {0xee0, 0x001b25a4}, {0xeec, 0x6fdb25a4}, + {0xf14, 0x00000003}, {0xf4c, 0x00000000}, + {0xf00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8188ru_phy_1t_highpa_table[] = { + {0x024, 0x0011800f}, {0x028, 0x00ffdb83}, + {0x040, 0x000c0004}, {0x800, 0x80040000}, + {0x804, 0x00000001}, {0x808, 0x0000fc00}, + {0x80c, 0x0000000a}, {0x810, 0x10005388}, + {0x814, 0x020c3d10}, {0x818, 0x02200385}, + {0x81c, 0x00000000}, {0x820, 0x01000100}, + {0x824, 0x00390204}, {0x828, 0x00000000}, + {0x82c, 0x00000000}, {0x830, 0x00000000}, + {0x834, 0x00000000}, {0x838, 0x00000000}, + {0x83c, 0x00000000}, {0x840, 0x00010000}, + {0x844, 0x00000000}, {0x848, 0x00000000}, + {0x84c, 0x00000000}, {0x850, 0x00000000}, + {0x854, 0x00000000}, {0x858, 0x569a569a}, + {0x85c, 0x001b25a4}, {0x860, 0x66e60230}, + {0x864, 0x061f0130}, {0x868, 0x00000000}, + {0x86c, 0x20202000}, {0x870, 0x03000300}, + {0x874, 0x22004000}, {0x878, 0x00000808}, + {0x87c, 0x00ffc3f1}, {0x880, 0xc0083070}, + {0x884, 0x000004d5}, {0x888, 0x00000000}, + {0x88c, 0xccc000c0}, {0x890, 0x00000800}, + {0x894, 0xfffffffe}, {0x898, 0x40302010}, + {0x89c, 0x00706050}, {0x900, 0x00000000}, + {0x904, 0x00000023}, {0x908, 0x00000000}, + {0x90c, 0x81121111}, {0xa00, 0x00d047c8}, + {0xa04, 0x80ff000c}, {0xa08, 0x8c838300}, + {0xa0c, 0x2e68120f}, {0xa10, 0x9500bb78}, + {0xa14, 0x11144028}, {0xa18, 0x00881117}, + {0xa1c, 0x89140f00}, {0xa20, 0x15160000}, + {0xa24, 0x070b0f12}, {0xa28, 0x00000104}, + {0xa2c, 0x00d30000}, {0xa70, 0x101fbf00}, + {0xa74, 0x00000007}, {0xc00, 0x48071d40}, + {0xc04, 0x03a05611}, {0xc08, 0x000000e4}, + {0xc0c, 0x6c6c6c6c}, {0xc10, 0x08800000}, + {0xc14, 0x40000100}, {0xc18, 0x08800000}, + {0xc1c, 0x40000100}, {0xc20, 0x00000000}, + {0xc24, 0x00000000}, {0xc28, 0x00000000}, + {0xc2c, 0x00000000}, {0xc30, 0x69e9ac44}, + {0xc34, 0x469652cf}, {0xc38, 0x49795994}, + {0xc3c, 0x0a97971c}, {0xc40, 0x1f7c403f}, + {0xc44, 0x000100b7}, {0xc48, 0xec020107}, + {0xc4c, 0x007f037f}, {0xc50, 0x6954342e}, + {0xc54, 0x43bc0094}, {0xc58, 0x6954342f}, + {0xc5c, 0x433c0094}, {0xc60, 0x00000000}, + {0xc64, 0x5116848b}, {0xc68, 0x47c00bff}, + {0xc6c, 0x00000036}, {0xc70, 0x2c46000d}, + {0xc74, 0x018610db}, {0xc78, 0x0000001f}, + {0xc7c, 0x00b91612}, {0xc80, 0x24000090}, + {0xc84, 0x20f60000}, {0xc88, 0x24000090}, + {0xc8c, 0x20200000}, {0xc90, 0x00121820}, + {0xc94, 0x00000000}, {0xc98, 0x00121820}, + {0xc9c, 0x00007f7f}, {0xca0, 0x00000000}, + {0xca4, 0x00000080}, {0xca8, 0x00000000}, + {0xcac, 0x00000000}, {0xcb0, 0x00000000}, + {0xcb4, 0x00000000}, {0xcb8, 0x00000000}, + {0xcbc, 0x28000000}, {0xcc0, 0x00000000}, + {0xcc4, 0x00000000}, {0xcc8, 0x00000000}, + {0xccc, 0x00000000}, {0xcd0, 0x00000000}, + {0xcd4, 0x00000000}, {0xcd8, 0x64b22427}, + {0xcdc, 0x00766932}, {0xce0, 0x00222222}, + {0xce4, 0x00000000}, {0xce8, 0x37644302}, + {0xcec, 0x2f97d40c}, {0xd00, 0x00080740}, + {0xd04, 0x00020401}, {0xd08, 0x0000907f}, + {0xd0c, 0x20010201}, {0xd10, 0xa0633333}, + {0xd14, 0x3333bc43}, {0xd18, 0x7a8f5b6b}, + {0xd2c, 0xcc979975}, {0xd30, 0x00000000}, + {0xd34, 0x80608000}, {0xd38, 0x00000000}, + {0xd3c, 0x00027293}, {0xd40, 0x00000000}, + {0xd44, 0x00000000}, {0xd48, 0x00000000}, + {0xd4c, 0x00000000}, {0xd50, 0x6437140a}, + {0xd54, 0x00000000}, {0xd58, 0x00000000}, + {0xd5c, 0x30032064}, {0xd60, 0x4653de68}, + {0xd64, 0x04518a3c}, {0xd68, 0x00002101}, + {0xd6c, 0x2a201c16}, {0xd70, 0x1812362e}, + {0xd74, 0x322c2220}, {0xd78, 0x000e3c24}, + {0xe00, 0x24242424}, {0xe04, 0x24242424}, + {0xe08, 0x03902024}, {0xe10, 0x24242424}, + {0xe14, 0x24242424}, {0xe18, 0x24242424}, + {0xe1c, 0x24242424}, {0xe28, 0x00000000}, + {0xe30, 0x1000dc1f}, {0xe34, 0x10008c1f}, + {0xe38, 0x02140102}, {0xe3c, 0x681604c2}, + {0xe40, 0x01007c00}, {0xe44, 0x01004800}, + {0xe48, 0xfb000000}, {0xe4c, 0x000028d1}, + {0xe50, 0x1000dc1f}, {0xe54, 0x10008c1f}, + {0xe58, 0x02140102}, {0xe5c, 0x28160d05}, + {0xe60, 0x00000008}, {0xe68, 0x001b25a4}, + {0xe6c, 0x631b25a0}, {0xe70, 0x631b25a0}, + {0xe74, 0x081b25a0}, {0xe78, 0x081b25a0}, + {0xe7c, 0x081b25a0}, {0xe80, 0x081b25a0}, + {0xe84, 0x631b25a0}, {0xe88, 0x081b25a0}, + {0xe8c, 0x631b25a0}, {0xed0, 0x631b25a0}, + {0xed4, 0x631b25a0}, {0xed8, 0x631b25a0}, + {0xedc, 0x001b25a0}, {0xee0, 0x001b25a0}, + {0xeec, 0x6b1b25a0}, {0xee8, 0x31555448}, + {0xf14, 0x00000003}, {0xf4c, 0x00000000}, + {0xf00, 0x00000300}, + {0xffff, 0xffffffff}, +}; + +static const struct rtl8xxxu_reg32val rtl8xxx_agc_standard_table[] = { + {0xc78, 0x7b000001}, {0xc78, 0x7b010001}, + {0xc78, 0x7b020001}, {0xc78, 0x7b030001}, + {0xc78, 0x7b040001}, {0xc78, 0x7b050001}, + {0xc78, 0x7a060001}, {0xc78, 0x79070001}, + {0xc78, 0x78080001}, {0xc78, 0x77090001}, + {0xc78, 0x760a0001}, {0xc78, 0x750b0001}, + {0xc78, 0x740c0001}, {0xc78, 0x730d0001}, + {0xc78, 0x720e0001}, {0xc78, 0x710f0001}, + {0xc78, 0x70100001}, {0xc78, 0x6f110001}, + {0xc78, 0x6e120001}, {0xc78, 0x6d130001}, + {0xc78, 0x6c140001}, {0xc78, 0x6b150001}, + {0xc78, 0x6a160001}, {0xc78, 0x69170001}, + {0xc78, 0x68180001}, {0xc78, 0x67190001}, + {0xc78, 0x661a0001}, {0xc78, 0x651b0001}, + {0xc78, 0x641c0001}, {0xc78, 0x631d0001}, + {0xc78, 0x621e0001}, {0xc78, 0x611f0001}, + {0xc78, 0x60200001}, {0xc78, 0x49210001}, + {0xc78, 0x48220001}, {0xc78, 0x47230001}, + {0xc78, 0x46240001}, {0xc78, 0x45250001}, + {0xc78, 0x44260001}, {0xc78, 0x43270001}, + {0xc78, 0x42280001}, {0xc78, 0x41290001}, + {0xc78, 0x402a0001}, {0xc78, 0x262b0001}, + {0xc78, 0x252c0001}, {0xc78, 0x242d0001}, + {0xc78, 0x232e0001}, {0xc78, 0x222f0001}, + {0xc78, 0x21300001}, {0xc78, 0x20310001}, + {0xc78, 0x06320001}, {0xc78, 0x05330001}, + {0xc78, 0x04340001}, {0xc78, 0x03350001}, + {0xc78, 0x02360001}, {0xc78, 0x01370001}, + {0xc78, 0x00380001}, {0xc78, 0x00390001}, + {0xc78, 0x003a0001}, {0xc78, 0x003b0001}, + {0xc78, 0x003c0001}, {0xc78, 0x003d0001}, + {0xc78, 0x003e0001}, {0xc78, 0x003f0001}, + {0xc78, 0x7b400001}, {0xc78, 0x7b410001}, + {0xc78, 0x7b420001}, {0xc78, 0x7b430001}, + {0xc78, 0x7b440001}, {0xc78, 0x7b450001}, + {0xc78, 0x7a460001}, {0xc78, 0x79470001}, + {0xc78, 0x78480001}, {0xc78, 0x77490001}, + {0xc78, 0x764a0001}, {0xc78, 0x754b0001}, + {0xc78, 0x744c0001}, {0xc78, 0x734d0001}, + {0xc78, 0x724e0001}, {0xc78, 0x714f0001}, + {0xc78, 0x70500001}, {0xc78, 0x6f510001}, + {0xc78, 0x6e520001}, {0xc78, 0x6d530001}, + {0xc78, 0x6c540001}, {0xc78, 0x6b550001}, + {0xc78, 0x6a560001}, {0xc78, 0x69570001}, + {0xc78, 0x68580001}, {0xc78, 0x67590001}, + {0xc78, 0x665a0001}, {0xc78, 0x655b0001}, + {0xc78, 0x645c0001}, {0xc78, 0x635d0001}, + {0xc78, 0x625e0001}, {0xc78, 0x615f0001}, + {0xc78, 0x60600001}, {0xc78, 0x49610001}, + {0xc78, 0x48620001}, {0xc78, 0x47630001}, + {0xc78, 0x46640001}, {0xc78, 0x45650001}, + {0xc78, 0x44660001}, {0xc78, 0x43670001}, + {0xc78, 0x42680001}, {0xc78, 0x41690001}, + {0xc78, 0x406a0001}, {0xc78, 0x266b0001}, + {0xc78, 0x256c0001}, {0xc78, 0x246d0001}, + {0xc78, 0x236e0001}, {0xc78, 0x226f0001}, + {0xc78, 0x21700001}, {0xc78, 0x20710001}, + {0xc78, 0x06720001}, {0xc78, 0x05730001}, + {0xc78, 0x04740001}, {0xc78, 0x03750001}, + {0xc78, 0x02760001}, {0xc78, 0x01770001}, + {0xc78, 0x00780001}, {0xc78, 0x00790001}, + {0xc78, 0x007a0001}, {0xc78, 0x007b0001}, + {0xc78, 0x007c0001}, {0xc78, 0x007d0001}, + {0xc78, 0x007e0001}, {0xc78, 0x007f0001}, + {0xc78, 0x3800001e}, {0xc78, 0x3801001e}, + {0xc78, 0x3802001e}, {0xc78, 0x3803001e}, + {0xc78, 0x3804001e}, {0xc78, 0x3805001e}, + {0xc78, 0x3806001e}, {0xc78, 0x3807001e}, + {0xc78, 0x3808001e}, {0xc78, 0x3c09001e}, + {0xc78, 0x3e0a001e}, {0xc78, 0x400b001e}, + {0xc78, 0x440c001e}, {0xc78, 0x480d001e}, + {0xc78, 0x4c0e001e}, {0xc78, 0x500f001e}, + {0xc78, 0x5210001e}, {0xc78, 0x5611001e}, + {0xc78, 0x5a12001e}, {0xc78, 0x5e13001e}, + {0xc78, 0x6014001e}, {0xc78, 0x6015001e}, + {0xc78, 0x6016001e}, {0xc78, 0x6217001e}, + {0xc78, 0x6218001e}, {0xc78, 0x6219001e}, + {0xc78, 0x621a001e}, {0xc78, 0x621b001e}, + {0xc78, 0x621c001e}, {0xc78, 0x621d001e}, + {0xc78, 0x621e001e}, {0xc78, 0x621f001e}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_reg32val rtl8xxx_agc_highpa_table[] = { + {0xc78, 0x7b000001}, {0xc78, 0x7b010001}, + {0xc78, 0x7b020001}, {0xc78, 0x7b030001}, + {0xc78, 0x7b040001}, {0xc78, 0x7b050001}, + {0xc78, 0x7b060001}, {0xc78, 0x7b070001}, + {0xc78, 0x7b080001}, {0xc78, 0x7a090001}, + {0xc78, 0x790a0001}, {0xc78, 0x780b0001}, + {0xc78, 0x770c0001}, {0xc78, 0x760d0001}, + {0xc78, 0x750e0001}, {0xc78, 0x740f0001}, + {0xc78, 0x73100001}, {0xc78, 0x72110001}, + {0xc78, 0x71120001}, {0xc78, 0x70130001}, + {0xc78, 0x6f140001}, {0xc78, 0x6e150001}, + {0xc78, 0x6d160001}, {0xc78, 0x6c170001}, + {0xc78, 0x6b180001}, {0xc78, 0x6a190001}, + {0xc78, 0x691a0001}, {0xc78, 0x681b0001}, + {0xc78, 0x671c0001}, {0xc78, 0x661d0001}, + {0xc78, 0x651e0001}, {0xc78, 0x641f0001}, + {0xc78, 0x63200001}, {0xc78, 0x62210001}, + {0xc78, 0x61220001}, {0xc78, 0x60230001}, + {0xc78, 0x46240001}, {0xc78, 0x45250001}, + {0xc78, 0x44260001}, {0xc78, 0x43270001}, + {0xc78, 0x42280001}, {0xc78, 0x41290001}, + {0xc78, 0x402a0001}, {0xc78, 0x262b0001}, + {0xc78, 0x252c0001}, {0xc78, 0x242d0001}, + {0xc78, 0x232e0001}, {0xc78, 0x222f0001}, + {0xc78, 0x21300001}, {0xc78, 0x20310001}, + {0xc78, 0x06320001}, {0xc78, 0x05330001}, + {0xc78, 0x04340001}, {0xc78, 0x03350001}, + {0xc78, 0x02360001}, {0xc78, 0x01370001}, + {0xc78, 0x00380001}, {0xc78, 0x00390001}, + {0xc78, 0x003a0001}, {0xc78, 0x003b0001}, + {0xc78, 0x003c0001}, {0xc78, 0x003d0001}, + {0xc78, 0x003e0001}, {0xc78, 0x003f0001}, + {0xc78, 0x7b400001}, {0xc78, 0x7b410001}, + {0xc78, 0x7b420001}, {0xc78, 0x7b430001}, + {0xc78, 0x7b440001}, {0xc78, 0x7b450001}, + {0xc78, 0x7b460001}, {0xc78, 0x7b470001}, + {0xc78, 0x7b480001}, {0xc78, 0x7a490001}, + {0xc78, 0x794a0001}, {0xc78, 0x784b0001}, + {0xc78, 0x774c0001}, {0xc78, 0x764d0001}, + {0xc78, 0x754e0001}, {0xc78, 0x744f0001}, + {0xc78, 0x73500001}, {0xc78, 0x72510001}, + {0xc78, 0x71520001}, {0xc78, 0x70530001}, + {0xc78, 0x6f540001}, {0xc78, 0x6e550001}, + {0xc78, 0x6d560001}, {0xc78, 0x6c570001}, + {0xc78, 0x6b580001}, {0xc78, 0x6a590001}, + {0xc78, 0x695a0001}, {0xc78, 0x685b0001}, + {0xc78, 0x675c0001}, {0xc78, 0x665d0001}, + {0xc78, 0x655e0001}, {0xc78, 0x645f0001}, + {0xc78, 0x63600001}, {0xc78, 0x62610001}, + {0xc78, 0x61620001}, {0xc78, 0x60630001}, + {0xc78, 0x46640001}, {0xc78, 0x45650001}, + {0xc78, 0x44660001}, {0xc78, 0x43670001}, + {0xc78, 0x42680001}, {0xc78, 0x41690001}, + {0xc78, 0x406a0001}, {0xc78, 0x266b0001}, + {0xc78, 0x256c0001}, {0xc78, 0x246d0001}, + {0xc78, 0x236e0001}, {0xc78, 0x226f0001}, + {0xc78, 0x21700001}, {0xc78, 0x20710001}, + {0xc78, 0x06720001}, {0xc78, 0x05730001}, + {0xc78, 0x04740001}, {0xc78, 0x03750001}, + {0xc78, 0x02760001}, {0xc78, 0x01770001}, + {0xc78, 0x00780001}, {0xc78, 0x00790001}, + {0xc78, 0x007a0001}, {0xc78, 0x007b0001}, + {0xc78, 0x007c0001}, {0xc78, 0x007d0001}, + {0xc78, 0x007e0001}, {0xc78, 0x007f0001}, + {0xc78, 0x3800001e}, {0xc78, 0x3801001e}, + {0xc78, 0x3802001e}, {0xc78, 0x3803001e}, + {0xc78, 0x3804001e}, {0xc78, 0x3805001e}, + {0xc78, 0x3806001e}, {0xc78, 0x3807001e}, + {0xc78, 0x3808001e}, {0xc78, 0x3c09001e}, + {0xc78, 0x3e0a001e}, {0xc78, 0x400b001e}, + {0xc78, 0x440c001e}, {0xc78, 0x480d001e}, + {0xc78, 0x4c0e001e}, {0xc78, 0x500f001e}, + {0xc78, 0x5210001e}, {0xc78, 0x5611001e}, + {0xc78, 0x5a12001e}, {0xc78, 0x5e13001e}, + {0xc78, 0x6014001e}, {0xc78, 0x6015001e}, + {0xc78, 0x6016001e}, {0xc78, 0x6217001e}, + {0xc78, 0x6218001e}, {0xc78, 0x6219001e}, + {0xc78, 0x621a001e}, {0xc78, 0x621b001e}, + {0xc78, 0x621c001e}, {0xc78, 0x621d001e}, + {0xc78, 0x621e001e}, {0xc78, 0x621f001e}, + {0xffff, 0xffffffff} +}; + +static const struct rtl8xxxu_rfregs rtl8xxxu_rfregs[] = { + { /* RF_A */ + .hssiparm1 = REG_FPGA0_XA_HSSI_PARM1, + .hssiparm2 = REG_FPGA0_XA_HSSI_PARM2, + .lssiparm = REG_FPGA0_XA_LSSI_PARM, + .hspiread = REG_HSPI_XA_READBACK, + .lssiread = REG_FPGA0_XA_LSSI_READBACK, + .rf_sw_ctrl = REG_FPGA0_XA_RF_SW_CTRL, + }, + { /* RF_B */ + .hssiparm1 = REG_FPGA0_XB_HSSI_PARM1, + .hssiparm2 = REG_FPGA0_XB_HSSI_PARM2, + .lssiparm = REG_FPGA0_XB_LSSI_PARM, + .hspiread = REG_HSPI_XB_READBACK, + .lssiread = REG_FPGA0_XB_LSSI_READBACK, + .rf_sw_ctrl = REG_FPGA0_XB_RF_SW_CTRL, + }, +}; + +const u32 rtl8xxxu_iqk_phy_iq_bb_reg[RTL8XXXU_BB_REGS] = { + REG_OFDM0_XA_RX_IQ_IMBALANCE, + REG_OFDM0_XB_RX_IQ_IMBALANCE, + REG_OFDM0_ENERGY_CCA_THRES, + REG_OFDM0_AGC_RSSI_TABLE, + REG_OFDM0_XA_TX_IQ_IMBALANCE, + REG_OFDM0_XB_TX_IQ_IMBALANCE, + REG_OFDM0_XC_TX_AFE, + REG_OFDM0_XD_TX_AFE, + REG_OFDM0_RX_IQ_EXT_ANTA +}; + +u8 rtl8xxxu_read8(struct rtl8xxxu_priv *priv, u16 addr) +{ + struct usb_device *udev = priv->udev; + int len; + u8 data; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_READ, + addr, 0, &priv->usb_buf.val8, sizeof(u8), + RTW_USB_CONTROL_MSG_TIMEOUT); + data = priv->usb_buf.val8; + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ) + dev_info(&udev->dev, "%s(%04x) = 0x%02x, len %i\n", + __func__, addr, data, len); + return data; +} + +u16 rtl8xxxu_read16(struct rtl8xxxu_priv *priv, u16 addr) +{ + struct usb_device *udev = priv->udev; + int len; + u16 data; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_READ, + addr, 0, &priv->usb_buf.val16, sizeof(u16), + RTW_USB_CONTROL_MSG_TIMEOUT); + data = le16_to_cpu(priv->usb_buf.val16); + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ) + dev_info(&udev->dev, "%s(%04x) = 0x%04x, len %i\n", + __func__, addr, data, len); + return data; +} + +u32 rtl8xxxu_read32(struct rtl8xxxu_priv *priv, u16 addr) +{ + struct usb_device *udev = priv->udev; + int len; + u32 data; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_READ, + addr, 0, &priv->usb_buf.val32, sizeof(u32), + RTW_USB_CONTROL_MSG_TIMEOUT); + data = le32_to_cpu(priv->usb_buf.val32); + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ) + dev_info(&udev->dev, "%s(%04x) = 0x%08x, len %i\n", + __func__, addr, data, len); + return data; +} + +int rtl8xxxu_write8(struct rtl8xxxu_priv *priv, u16 addr, u8 val) +{ + struct usb_device *udev = priv->udev; + int ret; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + priv->usb_buf.val8 = val; + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE, + addr, 0, &priv->usb_buf.val8, sizeof(u8), + RTW_USB_CONTROL_MSG_TIMEOUT); + + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(&udev->dev, "%s(%04x) = 0x%02x\n", + __func__, addr, val); + return ret; +} + +int rtl8xxxu_write16(struct rtl8xxxu_priv *priv, u16 addr, u16 val) +{ + struct usb_device *udev = priv->udev; + int ret; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + priv->usb_buf.val16 = cpu_to_le16(val); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE, + addr, 0, &priv->usb_buf.val16, sizeof(u16), + RTW_USB_CONTROL_MSG_TIMEOUT); + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(&udev->dev, "%s(%04x) = 0x%04x\n", + __func__, addr, val); + return ret; +} + +int rtl8xxxu_write32(struct rtl8xxxu_priv *priv, u16 addr, u32 val) +{ + struct usb_device *udev = priv->udev; + int ret; + + if (priv->rtl_chip == RTL8710B && addr <= 0xff) + addr |= 0x8000; + + mutex_lock(&priv->usb_buf_mutex); + priv->usb_buf.val32 = cpu_to_le32(val); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE, + addr, 0, &priv->usb_buf.val32, sizeof(u32), + RTW_USB_CONTROL_MSG_TIMEOUT); + mutex_unlock(&priv->usb_buf_mutex); + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(&udev->dev, "%s(%04x) = 0x%08x\n", + __func__, addr, val); + return ret; +} + +int rtl8xxxu_write8_set(struct rtl8xxxu_priv *priv, u16 addr, u8 bits) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, addr); + val8 |= bits; + return rtl8xxxu_write8(priv, addr, val8); +} + +int rtl8xxxu_write8_clear(struct rtl8xxxu_priv *priv, u16 addr, u8 bits) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, addr); + val8 &= ~bits; + return rtl8xxxu_write8(priv, addr, val8); +} + +int rtl8xxxu_write16_set(struct rtl8xxxu_priv *priv, u16 addr, u16 bits) +{ + u16 val16; + + val16 = rtl8xxxu_read16(priv, addr); + val16 |= bits; + return rtl8xxxu_write16(priv, addr, val16); +} + +int rtl8xxxu_write16_clear(struct rtl8xxxu_priv *priv, u16 addr, u16 bits) +{ + u16 val16; + + val16 = rtl8xxxu_read16(priv, addr); + val16 &= ~bits; + return rtl8xxxu_write16(priv, addr, val16); +} + +int rtl8xxxu_write32_set(struct rtl8xxxu_priv *priv, u16 addr, u32 bits) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, addr); + val32 |= bits; + return rtl8xxxu_write32(priv, addr, val32); +} + +int rtl8xxxu_write32_clear(struct rtl8xxxu_priv *priv, u16 addr, u32 bits) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, addr); + val32 &= ~bits; + return rtl8xxxu_write32(priv, addr, val32); +} + +int rtl8xxxu_write32_mask(struct rtl8xxxu_priv *priv, u16 addr, + u32 mask, u32 val) +{ + u32 orig, new, shift; + + shift = __ffs(mask); + + orig = rtl8xxxu_read32(priv, addr); + new = (orig & ~mask) | ((val << shift) & mask); + return rtl8xxxu_write32(priv, addr, new); +} + +int rtl8xxxu_write_rfreg_mask(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg, + u32 mask, u32 val) +{ + u32 orig, new, shift; + + shift = __ffs(mask); + + orig = rtl8xxxu_read_rfreg(priv, path, reg); + new = (orig & ~mask) | ((val << shift) & mask); + return rtl8xxxu_write_rfreg(priv, path, reg, new); +} + +static int +rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len) +{ + struct usb_device *udev = priv->udev; + int blocksize = priv->fops->writeN_block_size; + int ret, i, count, remainder; + + count = len / blocksize; + remainder = len % blocksize; + + for (i = 0; i < count; i++) { + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE, + addr, 0, buf, blocksize, + RTW_USB_CONTROL_MSG_TIMEOUT); + if (ret != blocksize) + goto write_error; + + addr += blocksize; + buf += blocksize; + } + + if (remainder) { + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE, + addr, 0, buf, remainder, + RTW_USB_CONTROL_MSG_TIMEOUT); + if (ret != remainder) + goto write_error; + } + + return len; + +write_error: + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(&udev->dev, + "%s: Failed to write block at addr: %04x size: %04x\n", + __func__, addr, blocksize); + return -EAGAIN; +} + +u32 rtl8xxxu_read_rfreg(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg) +{ + u32 hssia, val32, retval; + + hssia = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM2); + if (path != RF_A) + val32 = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hssiparm2); + else + val32 = hssia; + + val32 &= ~FPGA0_HSSI_PARM2_ADDR_MASK; + val32 |= (reg << FPGA0_HSSI_PARM2_ADDR_SHIFT); + val32 |= FPGA0_HSSI_PARM2_EDGE_READ; + hssia &= ~FPGA0_HSSI_PARM2_EDGE_READ; + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM2, hssia); + + udelay(10); + + rtl8xxxu_write32(priv, rtl8xxxu_rfregs[path].hssiparm2, val32); + udelay(100); + + hssia |= FPGA0_HSSI_PARM2_EDGE_READ; + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM2, hssia); + udelay(10); + + val32 = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hssiparm1); + if (val32 & FPGA0_HSSI_PARM1_PI) + retval = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hspiread); + else + retval = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].lssiread); + + retval &= 0xfffff; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_RFREG_READ) + dev_info(&priv->udev->dev, "%s(%02x) = 0x%06x\n", + __func__, reg, retval); + return retval; +} + +/* + * The RTL8723BU driver indicates that registers 0xb2 and 0xb6 can + * have write issues in high temperature conditions. We may have to + * retry writing them. + */ +int rtl8xxxu_write_rfreg(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg, u32 data) +{ + int ret, retval; + u32 dataaddr, val32; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_RFREG_WRITE) + dev_info(&priv->udev->dev, "%s(%02x) = 0x%06x\n", + __func__, reg, data); + + data &= FPGA0_LSSI_PARM_DATA_MASK; + dataaddr = (reg << FPGA0_LSSI_PARM_ADDR_SHIFT) | data; + + if (priv->rtl_chip == RTL8192E) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE); + val32 &= ~0x20000; + rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32); + } + + /* Use XB for path B */ + ret = rtl8xxxu_write32(priv, rtl8xxxu_rfregs[path].lssiparm, dataaddr); + if (ret != sizeof(dataaddr)) + retval = -EIO; + else + retval = 0; + + udelay(1); + + if (priv->rtl_chip == RTL8192E) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE); + val32 |= 0x20000; + rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32); + } + + return retval; +} + +static int +rtl8xxxu_gen1_h2c_cmd(struct rtl8xxxu_priv *priv, struct h2c_cmd *h2c, int len) +{ + struct device *dev = &priv->udev->dev; + int mbox_nr, retry, retval = 0; + int mbox_reg, mbox_ext_reg; + u8 val8; + + mutex_lock(&priv->h2c_mutex); + + mbox_nr = priv->next_mbox; + mbox_reg = REG_HMBOX_0 + (mbox_nr * 4); + mbox_ext_reg = REG_HMBOX_EXT_0 + (mbox_nr * 2); + + /* + * MBOX ready? + */ + retry = 100; + do { + val8 = rtl8xxxu_read8(priv, REG_HMTFR); + if (!(val8 & BIT(mbox_nr))) + break; + } while (retry--); + + if (!retry) { + dev_info(dev, "%s: Mailbox busy\n", __func__); + retval = -EBUSY; + goto error; + } + + /* + * Need to swap as it's being swapped again by rtl8xxxu_write16/32() + */ + if (len > sizeof(u32)) { + rtl8xxxu_write16(priv, mbox_ext_reg, le16_to_cpu(h2c->raw.ext)); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C) + dev_info(dev, "H2C_EXT %04x\n", + le16_to_cpu(h2c->raw.ext)); + } + rtl8xxxu_write32(priv, mbox_reg, le32_to_cpu(h2c->raw.data)); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C) + dev_info(dev, "H2C %08x\n", le32_to_cpu(h2c->raw.data)); + + priv->next_mbox = (mbox_nr + 1) % H2C_MAX_MBOX; + +error: + mutex_unlock(&priv->h2c_mutex); + return retval; +} + +int +rtl8xxxu_gen2_h2c_cmd(struct rtl8xxxu_priv *priv, struct h2c_cmd *h2c, int len) +{ + struct device *dev = &priv->udev->dev; + int mbox_nr, retry, retval = 0; + int mbox_reg, mbox_ext_reg; + u8 val8; + + mutex_lock(&priv->h2c_mutex); + + mbox_nr = priv->next_mbox; + mbox_reg = REG_HMBOX_0 + (mbox_nr * 4); + mbox_ext_reg = REG_HMBOX_EXT0_8723B + (mbox_nr * 4); + + /* + * MBOX ready? + */ + retry = 100; + do { + val8 = rtl8xxxu_read8(priv, REG_HMTFR); + if (!(val8 & BIT(mbox_nr))) + break; + } while (retry--); + + if (!retry) { + dev_info(dev, "%s: Mailbox busy\n", __func__); + retval = -EBUSY; + goto error; + } + + /* + * Need to swap as it's being swapped again by rtl8xxxu_write16/32() + */ + if (len > sizeof(u32)) { + rtl8xxxu_write32(priv, mbox_ext_reg, + le32_to_cpu(h2c->raw_wide.ext)); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C) + dev_info(dev, "H2C_EXT %08x\n", + le32_to_cpu(h2c->raw_wide.ext)); + } + rtl8xxxu_write32(priv, mbox_reg, le32_to_cpu(h2c->raw.data)); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C) + dev_info(dev, "H2C %08x\n", le32_to_cpu(h2c->raw.data)); + + priv->next_mbox = (mbox_nr + 1) % H2C_MAX_MBOX; + +error: + mutex_unlock(&priv->h2c_mutex); + return retval; +} + +void rtl8xxxu_gen1_enable_rf(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u32 val32; + + val8 = rtl8xxxu_read8(priv, REG_SPS0_CTRL); + val8 |= BIT(0) | BIT(3); + rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_PARM); + val32 &= ~(BIT(4) | BIT(5)); + val32 |= BIT(3); + if (priv->rf_paths == 2) { + val32 &= ~(BIT(20) | BIT(21)); + val32 |= BIT(19); + } + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_PARM, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + if (priv->tx_paths == 2) + val32 |= OFDM_RF_PATH_TX_A | OFDM_RF_PATH_TX_B; + else if (priv->rtl_chip == RTL8192C || priv->rtl_chip == RTL8191C) + val32 |= OFDM_RF_PATH_TX_B; + else + val32 |= OFDM_RF_PATH_TX_A; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE_JAPAN; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + if (priv->rf_paths == 2) + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x63db25a0); + else + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x631b25a0); + + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x32d95); + if (priv->rf_paths == 2) + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0x32d95); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +void rtl8xxxu_gen1_disable_rf(struct rtl8xxxu_priv *priv) +{ + u8 sps0; + u32 val32; + + sps0 = rtl8xxxu_read8(priv, REG_SPS0_CTRL); + + /* RF RX code for preamble power saving */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_PARM); + val32 &= ~(BIT(3) | BIT(4) | BIT(5)); + if (priv->rf_paths == 2) + val32 &= ~(BIT(19) | BIT(20) | BIT(21)); + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_PARM, val32); + + /* Disable TX for four paths */ + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~OFDM_RF_PATH_TX_MASK; + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + /* Enable power saving */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= FPGA_RF_MODE_JAPAN; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* AFE control register to power down bits [30:22] */ + if (priv->rf_paths == 2) + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00db25a0); + else + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x001b25a0); + + /* Power down RF module */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); + if (priv->rf_paths == 2) + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0); + + sps0 &= ~(BIT(0) | BIT(3)); + rtl8xxxu_write8(priv, REG_SPS0_CTRL, sps0); +} + +static void rtl8xxxu_stop_tx_beacon(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_FWHW_TXQ_CTRL + 2); + val8 &= ~BIT(6); + rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL + 2, val8); + + rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 1, 0x64); + val8 = rtl8xxxu_read8(priv, REG_TBTT_PROHIBIT + 2); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 2, val8); +} + +static void rtl8xxxu_start_tx_beacon(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_FWHW_TXQ_CTRL + 2); + val8 |= EN_BCNQ_DL >> 16; + rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL + 2, val8); + + rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 1, 0x80); + val8 = rtl8xxxu_read8(priv, REG_TBTT_PROHIBIT + 2); + val8 &= 0xF0; + rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 2, val8); +} + + +/* + * The rtl8723a has 3 channel groups for its efuse settings. It only + * supports the 2.4GHz band, so channels 1 - 14: + * group 0: channels 1 - 3 + * group 1: channels 4 - 9 + * group 2: channels 10 - 14 + * + * Note: We index from 0 in the code + */ +static int rtl8xxxu_gen1_channel_to_group(int channel) +{ + int group; + + if (channel < 4) + group = 0; + else if (channel < 10) + group = 1; + else + group = 2; + + return group; +} + +/* + * Valid for rtl8723bu and rtl8192eu + */ +int rtl8xxxu_gen2_channel_to_group(int channel) +{ + int group; + + if (channel < 3) + group = 0; + else if (channel < 6) + group = 1; + else if (channel < 9) + group = 2; + else if (channel < 12) + group = 3; + else + group = 4; + + return group; +} + +void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u32 val32, rsr; + u8 val8, opmode; + bool ht = true; + int sec_ch_above, channel; + int i; + + opmode = rtl8xxxu_read8(priv, REG_BW_OPMODE); + rsr = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + channel = hw->conf.chandef.chan->hw_value; + + switch (hw->conf.chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + ht = false; + fallthrough; + case NL80211_CHAN_WIDTH_20: + opmode |= BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_ANALOG2); + val32 |= FPGA0_ANALOG2_20MHZ; + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG2, val32); + break; + case NL80211_CHAN_WIDTH_40: + if (hw->conf.chandef.center_freq1 > + hw->conf.chandef.chan->center_freq) { + sec_ch_above = 1; + channel += 2; + } else { + sec_ch_above = 0; + channel -= 2; + } + + opmode &= ~BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + rsr &= ~RSR_RSC_BANDWIDTH_40M; + if (!sec_ch_above) + rsr |= RSR_RSC_UPPER_SUB_CHANNEL; + else + rsr |= RSR_RSC_LOWER_SUB_CHANNEL; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, rsr); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + /* + * Set Control channel to upper or lower. These settings + * are required only for 40MHz + */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); + val32 &= ~CCK0_SIDEBAND; + if (!sec_ch_above) + val32 |= CCK0_SIDEBAND; + rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM1_LSTF); + val32 &= ~OFDM_LSTF_PRIME_CH_MASK; /* 0xc00 */ + if (sec_ch_above) + val32 |= OFDM_LSTF_PRIME_CH_LOW; + else + val32 |= OFDM_LSTF_PRIME_CH_HIGH; + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_ANALOG2); + val32 &= ~FPGA0_ANALOG2_20MHZ; + rtl8xxxu_write32(priv, REG_FPGA0_ANALOG2, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE); + val32 &= ~(FPGA0_PS_LOWER_CHANNEL | FPGA0_PS_UPPER_CHANNEL); + if (sec_ch_above) + val32 |= FPGA0_PS_UPPER_CHANNEL; + else + val32 |= FPGA0_PS_LOWER_CHANNEL; + rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32); + break; + + default: + break; + } + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_CHANNEL_MASK; + val32 |= channel; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } + + if (ht) + val8 = 0x0e; + else + val8 = 0x0a; + + rtl8xxxu_write8(priv, REG_SIFS_CCK + 1, val8); + rtl8xxxu_write8(priv, REG_SIFS_OFDM + 1, val8); + + rtl8xxxu_write16(priv, REG_R2T_SIFS, 0x0808); + rtl8xxxu_write16(priv, REG_T2T_SIFS, 0x0a0a); + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) + val32 |= MODE_AG_CHANNEL_20MHZ; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } +} + +void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u32 val32; + u8 val8, subchannel; + u16 rf_mode_bw; + bool ht = true; + int sec_ch_above, channel; + int i; + + rf_mode_bw = rtl8xxxu_read16(priv, REG_WMAC_TRXPTCL_CTL); + rf_mode_bw &= ~WMAC_TRXPTCL_CTL_BW_MASK; + channel = hw->conf.chandef.chan->hw_value; + +/* Hack */ + subchannel = 0; + + switch (hw->conf.chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + ht = false; + fallthrough; + case NL80211_CHAN_WIDTH_20: + rf_mode_bw |= WMAC_TRXPTCL_CTL_BW_20; + subchannel = 0; + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 &= ~FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); + val32 &= ~(BIT(30) | BIT(31)); + rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); + + break; + case NL80211_CHAN_WIDTH_40: + rf_mode_bw |= WMAC_TRXPTCL_CTL_BW_40; + + if (hw->conf.chandef.center_freq1 > + hw->conf.chandef.chan->center_freq) { + sec_ch_above = 1; + channel += 2; + subchannel = 2; + } else { + sec_ch_above = 0; + channel -= 2; + subchannel = 1; + } + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); + val32 |= FPGA_RF_MODE; + rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); + + /* + * Set Control channel to upper or lower. These settings + * are required only for 40MHz + */ + val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); + val32 &= ~CCK0_SIDEBAND; + if (!sec_ch_above) + val32 |= CCK0_SIDEBAND; + rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM1_LSTF); + val32 &= ~OFDM_LSTF_PRIME_CH_MASK; /* 0xc00 */ + if (sec_ch_above) + val32 |= OFDM_LSTF_PRIME_CH_LOW; + else + val32 |= OFDM_LSTF_PRIME_CH_HIGH; + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE); + val32 &= ~(FPGA0_PS_LOWER_CHANNEL | FPGA0_PS_UPPER_CHANNEL); + if (sec_ch_above) + val32 |= FPGA0_PS_UPPER_CHANNEL; + else + val32 |= FPGA0_PS_LOWER_CHANNEL; + rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32); + break; + case NL80211_CHAN_WIDTH_80: + rf_mode_bw |= WMAC_TRXPTCL_CTL_BW_80; + break; + default: + break; + } + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_CHANNEL_MASK; + val32 |= channel; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } + + rtl8xxxu_write16(priv, REG_WMAC_TRXPTCL_CTL, rf_mode_bw); + rtl8xxxu_write8(priv, REG_DATA_SUBCHANNEL, subchannel); + + if (ht) + val8 = 0x0e; + else + val8 = 0x0a; + + rtl8xxxu_write8(priv, REG_SIFS_CCK + 1, val8); + rtl8xxxu_write8(priv, REG_SIFS_OFDM + 1, val8); + + rtl8xxxu_write16(priv, REG_R2T_SIFS, 0x0808); + rtl8xxxu_write16(priv, REG_T2T_SIFS, 0x0a0a); + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); + val32 &= ~MODE_AG_BW_MASK; + switch(hw->conf.chandef.width) { + case NL80211_CHAN_WIDTH_80: + val32 |= MODE_AG_BW_80MHZ_8723B; + break; + case NL80211_CHAN_WIDTH_40: + val32 |= MODE_AG_BW_40MHZ_8723B; + break; + default: + val32 |= MODE_AG_BW_20MHZ_8723B; + break; + } + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } +} + +void +rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) +{ + struct rtl8xxxu_power_base *power_base = priv->power_base; + u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS]; + u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS]; + u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b; + u8 val8, base; + int group, i; + + group = rtl8xxxu_gen1_channel_to_group(channel); + + cck[0] = priv->cck_tx_power_index_A[group]; + cck[1] = priv->cck_tx_power_index_B[group]; + + if (priv->hi_pa) { + if (cck[0] > 0x20) + cck[0] = 0x20; + if (cck[1] > 0x20) + cck[1] = 0x20; + } + + ofdm[0] = priv->ht40_1s_tx_power_index_A[group]; + ofdm[1] = priv->ht40_1s_tx_power_index_B[group]; + + ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a; + ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b; + + mcsbase[0] = ofdm[0]; + mcsbase[1] = ofdm[1]; + if (!ht40) { + mcsbase[0] += priv->ht20_tx_power_index_diff[group].a; + mcsbase[1] += priv->ht20_tx_power_index_diff[group].b; + } + + if (priv->tx_paths > 1) { + if (ofdm[0] > priv->ht40_2s_tx_power_index_diff[group].a) + ofdm[0] -= priv->ht40_2s_tx_power_index_diff[group].a; + if (ofdm[1] > priv->ht40_2s_tx_power_index_diff[group].b) + ofdm[1] -= priv->ht40_2s_tx_power_index_diff[group].b; + } + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_CHANNEL) + dev_info(&priv->udev->dev, + "%s: Setting TX power CCK A: %02x, " + "CCK B: %02x, OFDM A: %02x, OFDM B: %02x\n", + __func__, cck[0], cck[1], ofdm[0], ofdm[1]); + + for (i = 0; i < RTL8723A_MAX_RF_PATHS; i++) { + if (cck[i] > RF6052_MAX_TX_PWR) + cck[i] = RF6052_MAX_TX_PWR; + if (ofdm[i] > RF6052_MAX_TX_PWR) + ofdm[i] = RF6052_MAX_TX_PWR; + } + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); + val32 &= 0xffff00ff; + val32 |= (cck[0] << 8); + rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xff; + val32 |= ((cck[0] << 8) | (cck[0] << 16) | (cck[0] << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); + val32 &= 0xffffff00; + val32 |= cck[1]; + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK1_55_MCS32); + val32 &= 0xff; + val32 |= ((cck[1] << 8) | (cck[1] << 16) | (cck[1] << 24)); + rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK1_55_MCS32, val32); + + ofdm_a = ofdmbase[0] | ofdmbase[0] << 8 | + ofdmbase[0] << 16 | ofdmbase[0] << 24; + ofdm_b = ofdmbase[1] | ofdmbase[1] << 8 | + ofdmbase[1] << 16 | ofdmbase[1] << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, + ofdm_a + power_base->reg_0e00); + rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE18_06, + ofdm_b + power_base->reg_0830); + + rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, + ofdm_a + power_base->reg_0e04); + rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE54_24, + ofdm_b + power_base->reg_0834); + + mcs_a = mcsbase[0] | mcsbase[0] << 8 | + mcsbase[0] << 16 | mcsbase[0] << 24; + mcs_b = mcsbase[1] | mcsbase[1] << 8 | + mcsbase[1] << 16 | mcsbase[1] << 24; + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, + mcs_a + power_base->reg_0e10); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS03_MCS00, + mcs_b + power_base->reg_083c); + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, + mcs_a + power_base->reg_0e14); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS07_MCS04, + mcs_b + power_base->reg_0848); + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, + mcs_a + power_base->reg_0e18); + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS11_MCS08, + mcs_b + power_base->reg_084c); + + rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, + mcs_a + power_base->reg_0e1c); + val8 = u32_get_bits(mcs_a + power_base->reg_0e1c, 0xff000000); + for (i = 0; i < 3; i++) { + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); + rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8); + } + + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, + mcs_b + power_base->reg_0868); + val8 = u32_get_bits(mcs_b + power_base->reg_0868, 0xff000000); + for (i = 0; i < 3; i++) { + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); + rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8); + } +} + +static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv, + enum nl80211_iftype linktype, int port_num) +{ + u8 val8, type; + + switch (linktype) { + case NL80211_IFTYPE_UNSPECIFIED: + type = MSR_LINKTYPE_NONE; + break; + case NL80211_IFTYPE_ADHOC: + type = MSR_LINKTYPE_ADHOC; + break; + case NL80211_IFTYPE_STATION: + type = MSR_LINKTYPE_STATION; + break; + case NL80211_IFTYPE_AP: + type = MSR_LINKTYPE_AP; + break; + default: + return; + } + + switch (port_num) { + case 0: + val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x0c; + val8 |= type; + break; + case 1: + val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x03; + val8 |= type << 2; + break; + default: + return; + } + + rtl8xxxu_write8(priv, REG_MSR, val8); +} + +static void +rtl8xxxu_set_retry(struct rtl8xxxu_priv *priv, u16 short_retry, u16 long_retry) +{ + u16 val16; + + val16 = ((short_retry << RETRY_LIMIT_SHORT_SHIFT) & + RETRY_LIMIT_SHORT_MASK) | + ((long_retry << RETRY_LIMIT_LONG_SHIFT) & + RETRY_LIMIT_LONG_MASK); + + rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16); +} + +static void +rtl8xxxu_set_spec_sifs(struct rtl8xxxu_priv *priv, u16 cck, u16 ofdm) +{ + u16 val16; + + val16 = ((cck << SPEC_SIFS_CCK_SHIFT) & SPEC_SIFS_CCK_MASK) | + ((ofdm << SPEC_SIFS_OFDM_SHIFT) & SPEC_SIFS_OFDM_MASK); + + rtl8xxxu_write16(priv, REG_SPEC_SIFS, val16); +} + +static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + char cut = 'A' + priv->chip_cut; + + dev_info(dev, + "RTL%s rev %c (%s) romver %d, %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n", + priv->chip_name, cut, priv->chip_vendor, priv->rom_rev, + priv->tx_paths, priv->rx_paths, priv->ep_tx_count, + priv->has_wifi, priv->has_bluetooth, priv->has_gps, + priv->hi_pa); + + dev_info(dev, "RTL%s MAC: %pM\n", priv->chip_name, priv->mac_addr); +} + +void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor) +{ + if (vendor) { + strscpy(priv->chip_vendor, "UMC", sizeof(priv->chip_vendor)); + priv->vendor_umc = 1; + } else { + strscpy(priv->chip_vendor, "TSMC", sizeof(priv->chip_vendor)); + } +} + +void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor) +{ + switch (vendor) { + case SYS_CFG_VENDOR_ID_TSMC: + strscpy(priv->chip_vendor, "TSMC", sizeof(priv->chip_vendor)); + break; + case SYS_CFG_VENDOR_ID_SMIC: + strscpy(priv->chip_vendor, "SMIC", sizeof(priv->chip_vendor)); + priv->vendor_smic = 1; + break; + case SYS_CFG_VENDOR_ID_UMC: + strscpy(priv->chip_vendor, "UMC", sizeof(priv->chip_vendor)); + priv->vendor_umc = 1; + break; + default: + strscpy(priv->chip_vendor, "unknown", sizeof(priv->chip_vendor)); + } +} + +void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv) +{ + u16 val16; + + val16 = rtl8xxxu_read16(priv, REG_NORMAL_SIE_EP_TX); + + if (val16 & NORMAL_SIE_EP_TX_HIGH_MASK) { + priv->ep_tx_high_queue = 1; + priv->ep_tx_count++; + } + + if (val16 & NORMAL_SIE_EP_TX_NORMAL_MASK) { + priv->ep_tx_normal_queue = 1; + priv->ep_tx_count++; + } + + if (val16 & NORMAL_SIE_EP_TX_LOW_MASK) { + priv->ep_tx_low_queue = 1; + priv->ep_tx_count++; + } +} + +int rtl8xxxu_config_endpoints_no_sie(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + + switch (priv->nr_out_eps) { + case 6: + case 5: + case 4: + case 3: + priv->ep_tx_low_queue = 1; + priv->ep_tx_count++; + fallthrough; + case 2: + priv->ep_tx_normal_queue = 1; + priv->ep_tx_count++; + fallthrough; + case 1: + priv->ep_tx_high_queue = 1; + priv->ep_tx_count++; + break; + default: + dev_info(dev, "Unsupported USB TX end-points\n"); + return -ENOTSUPP; + } + + return 0; +} + +int +rtl8xxxu_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data) +{ + int i; + u8 val8; + u32 val32; + + /* Write Address */ + rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 1, offset & 0xff); + val8 = rtl8xxxu_read8(priv, REG_EFUSE_CTRL + 2); + val8 &= 0xfc; + val8 |= (offset >> 8) & 0x03; + rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 2, val8); + + val8 = rtl8xxxu_read8(priv, REG_EFUSE_CTRL + 3); + rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 3, val8 & 0x7f); + + /* Poll for data read */ + val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL); + for (i = 0; i < RTL8XXXU_MAX_REG_POLL; i++) { + val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL); + if (val32 & BIT(31)) + break; + } + + if (i == RTL8XXXU_MAX_REG_POLL) + return -EIO; + + udelay(50); + val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL); + + *data = val32 & 0xff; + return 0; +} + +int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int i, ret = 0; + u8 val8, word_mask, header, extheader; + u16 val16, efuse_addr, offset; + u32 val32; + + val16 = rtl8xxxu_read16(priv, REG_9346CR); + if (val16 & EEPROM_ENABLE) + priv->has_eeprom = 1; + if (val16 & EEPROM_BOOT) + priv->boot_eeprom = 1; + + if (priv->is_multi_func) { + val32 = rtl8xxxu_read32(priv, REG_EFUSE_TEST); + val32 = (val32 & ~EFUSE_SELECT_MASK) | EFUSE_WIFI_SELECT; + rtl8xxxu_write32(priv, REG_EFUSE_TEST, val32); + } + + dev_dbg(dev, "Booting from %s\n", + priv->boot_eeprom ? "EEPROM" : "EFUSE"); + + rtl8xxxu_write8(priv, REG_EFUSE_ACCESS, EFUSE_ACCESS_ENABLE); + + /* 1.2V Power: From VDDON with Power Cut(0x0000[15]), default valid */ + val16 = rtl8xxxu_read16(priv, REG_SYS_ISO_CTRL); + if (!(val16 & SYS_ISO_PWC_EV12V)) { + val16 |= SYS_ISO_PWC_EV12V; + rtl8xxxu_write16(priv, REG_SYS_ISO_CTRL, val16); + } + /* Reset: 0x0000[28], default valid */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + if (!(val16 & SYS_FUNC_ELDR)) { + val16 |= SYS_FUNC_ELDR; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + } + + /* + * Clock: Gated(0x0008[5]) 8M(0x0008[1]) clock from ANA, default valid + */ + val16 = rtl8xxxu_read16(priv, REG_SYS_CLKR); + if (!(val16 & SYS_CLK_LOADER_ENABLE) || !(val16 & SYS_CLK_ANA8M)) { + val16 |= (SYS_CLK_LOADER_ENABLE | SYS_CLK_ANA8M); + rtl8xxxu_write16(priv, REG_SYS_CLKR, val16); + } + + /* Default value is 0xff */ + memset(priv->efuse_wifi.raw, 0xff, EFUSE_MAP_LEN); + + efuse_addr = 0; + while (efuse_addr < EFUSE_REAL_CONTENT_LEN_8723A) { + u16 map_addr; + + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &header); + if (ret || header == 0xff) + goto exit; + + if ((header & 0x1f) == 0x0f) { /* extended header */ + offset = (header & 0xe0) >> 5; + + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, + &extheader); + if (ret) + goto exit; + /* All words disabled */ + if ((extheader & 0x0f) == 0x0f) + continue; + + offset |= ((extheader & 0xf0) >> 1); + word_mask = extheader & 0x0f; + } else { + offset = (header >> 4) & 0x0f; + word_mask = header & 0x0f; + } + + /* Get word enable value from PG header */ + + /* We have 8 bits to indicate validity */ + map_addr = offset * 8; + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (word_mask & BIT(i)) { + map_addr += 2; + continue; + } + + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); + if (ret) + goto exit; + if (map_addr >= EFUSE_MAP_LEN - 1) { + dev_warn(dev, "%s: Illegal map_addr (%04x), " + "efuse corrupt!\n", + __func__, map_addr); + ret = -EINVAL; + goto exit; + } + priv->efuse_wifi.raw[map_addr++] = val8; + + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); + if (ret) + goto exit; + priv->efuse_wifi.raw[map_addr++] = val8; + } + } + +exit: + rtl8xxxu_write8(priv, REG_EFUSE_ACCESS, EFUSE_ACCESS_DISABLE); + + return ret; +} + +static void rtl8xxxu_dump_efuse(struct rtl8xxxu_priv *priv) +{ + dev_info(&priv->udev->dev, + "Dumping efuse for RTL%s (0x%02x bytes):\n", + priv->chip_name, EFUSE_MAP_LEN); + + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, + priv->efuse_wifi.raw, EFUSE_MAP_LEN, true); +} + +static ssize_t read_file_efuse(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct rtl8xxxu_priv *priv = file_inode(file)->i_private; + + return simple_read_from_buffer(user_buf, count, ppos, + priv->efuse_wifi.raw, EFUSE_MAP_LEN); +} + +static const struct debugfs_short_fops fops_efuse = { + .read = read_file_efuse, +}; + +static void rtl8xxxu_debugfs_init(struct rtl8xxxu_priv *priv) +{ + struct dentry *phydir; + + phydir = debugfs_create_dir("rtl8xxxu", priv->hw->wiphy->debugfsdir); + debugfs_create_file("efuse", 0400, phydir, priv, &fops_efuse); +} + +void rtl8xxxu_reset_8051(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u16 sys_func; + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + sys_func = rtl8xxxu_read16(priv, REG_SYS_FUNC); + sys_func &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); + + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); + val8 |= BIT(0); + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); + + sys_func |= SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); +} + +static int rtl8xxxu_start_firmware(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u16 reg_mcu_fw_dl; + int ret = 0, i; + u32 val32; + + if (priv->rtl_chip == RTL8710B) + reg_mcu_fw_dl = REG_8051FW_CTRL_V1_8710B; + else + reg_mcu_fw_dl = REG_MCU_FW_DL; + + /* Poll checksum report */ + for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) { + val32 = rtl8xxxu_read32(priv, reg_mcu_fw_dl); + if (val32 & MCU_FW_DL_CSUM_REPORT) + break; + } + + if (i == RTL8XXXU_FIRMWARE_POLL_MAX) { + dev_warn(dev, "Firmware checksum poll timed out\n"); + ret = -EAGAIN; + goto exit; + } + + val32 = rtl8xxxu_read32(priv, reg_mcu_fw_dl); + val32 |= MCU_FW_DL_READY; + val32 &= ~MCU_WINT_INIT_READY; + rtl8xxxu_write32(priv, reg_mcu_fw_dl, val32); + + /* + * Reset the 8051 in order for the firmware to start running, + * otherwise it won't come up on the 8192eu + */ + priv->fops->reset_8051(priv); + + /* Wait for firmware to become ready */ + for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) { + val32 = rtl8xxxu_read32(priv, reg_mcu_fw_dl); + if (val32 & MCU_WINT_INIT_READY) + break; + + udelay(100); + } + + if (i == RTL8XXXU_FIRMWARE_POLL_MAX) { + dev_warn(dev, "Firmware failed to start\n"); + ret = -EAGAIN; + goto exit; + } + + /* + * Init H2C command + */ + if (priv->fops->init_reg_hmtfr) + rtl8xxxu_write8(priv, REG_HMTFR, 0x0f); +exit: + return ret; +} + +static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv) +{ + int pages, remainder, i, ret; + u16 reg_fw_start_address; + u16 reg_mcu_fw_dl; + u8 val8; + u16 val16; + u32 val32; + u8 *fwptr; + + if (priv->rtl_chip == RTL8192F) + reg_fw_start_address = REG_FW_START_ADDRESS_8192F; + else + reg_fw_start_address = REG_FW_START_ADDRESS; + + if (priv->rtl_chip == RTL8710B) { + reg_mcu_fw_dl = REG_8051FW_CTRL_V1_8710B; + } else { + reg_mcu_fw_dl = REG_MCU_FW_DL; + + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC + 1); + val8 |= 4; + rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8); + + /* 8051 enable */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + } + + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl); + if (val8 & MCU_FW_RAM_SEL) { + dev_info(&priv->udev->dev, + "Firmware is already running, resetting the MCU.\n"); + rtl8xxxu_write8(priv, reg_mcu_fw_dl, 0x00); + priv->fops->reset_8051(priv); + } + + /* MCU firmware download enable */ + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl); + val8 |= MCU_FW_DL_ENABLE; + rtl8xxxu_write8(priv, reg_mcu_fw_dl, val8); + + /* 8051 reset */ + val32 = rtl8xxxu_read32(priv, reg_mcu_fw_dl); + val32 &= ~BIT(19); + rtl8xxxu_write32(priv, reg_mcu_fw_dl, val32); + + if (priv->rtl_chip == RTL8710B) { + /* We must set 0x8090[8]=1 before download FW. */ + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl + 1); + val8 |= BIT(0); + rtl8xxxu_write8(priv, reg_mcu_fw_dl + 1, val8); + } + + /* Reset firmware download checksum */ + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl); + val8 |= MCU_FW_DL_CSUM_REPORT; + rtl8xxxu_write8(priv, reg_mcu_fw_dl, val8); + + pages = priv->fw_size / RTL_FW_PAGE_SIZE; + remainder = priv->fw_size % RTL_FW_PAGE_SIZE; + + fwptr = priv->fw_data->data; + + for (i = 0; i < pages; i++) { + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl + 2) & 0xF8; + val8 |= i; + rtl8xxxu_write8(priv, reg_mcu_fw_dl + 2, val8); + + ret = rtl8xxxu_writeN(priv, reg_fw_start_address, + fwptr, RTL_FW_PAGE_SIZE); + if (ret != RTL_FW_PAGE_SIZE) { + ret = -EAGAIN; + goto fw_abort; + } + + fwptr += RTL_FW_PAGE_SIZE; + } + + if (remainder) { + val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl + 2) & 0xF8; + val8 |= i; + rtl8xxxu_write8(priv, reg_mcu_fw_dl + 2, val8); + ret = rtl8xxxu_writeN(priv, reg_fw_start_address, + fwptr, remainder); + if (ret != remainder) { + ret = -EAGAIN; + goto fw_abort; + } + } + + ret = 0; +fw_abort: + /* MCU firmware download disable */ + val16 = rtl8xxxu_read16(priv, reg_mcu_fw_dl); + val16 &= ~MCU_FW_DL_ENABLE; + rtl8xxxu_write16(priv, reg_mcu_fw_dl, val16); + + return ret; +} + +int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name) +{ + struct device *dev = &priv->udev->dev; + const struct firmware *fw; + int ret = 0; + u16 signature; + + dev_info(dev, "%s: Loading firmware %s\n", DRIVER_NAME, fw_name); + if (request_firmware(&fw, fw_name, &priv->udev->dev)) { + dev_warn(dev, "request_firmware(%s) failed\n", fw_name); + ret = -EAGAIN; + goto exit; + } + if (!fw) { + dev_warn(dev, "Firmware data not available\n"); + ret = -EINVAL; + goto exit; + } + + priv->fw_data = kmemdup(fw->data, fw->size, GFP_KERNEL); + if (!priv->fw_data) { + ret = -ENOMEM; + goto exit; + } + priv->fw_size = fw->size - sizeof(struct rtl8xxxu_firmware_header); + + signature = le16_to_cpu(priv->fw_data->signature); + switch (signature & 0xfff0) { + case 0x92e0: + case 0x92c0: + case 0x88e0: + case 0x88c0: + case 0x5300: + case 0x2300: + case 0x88f0: + case 0x10b0: + case 0x92f0: + break; + default: + ret = -EINVAL; + dev_warn(dev, "%s: Invalid firmware signature: 0x%04x\n", + __func__, signature); + } + + dev_info(dev, "Firmware revision %i.%i (signature 0x%04x)\n", + le16_to_cpu(priv->fw_data->major_version), + priv->fw_data->minor_version, signature); + +exit: + release_firmware(fw); + return ret; +} + +void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv) +{ + u16 val16; + int i = 100; + + /* Inform 8051 to perform reset */ + rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20); + + for (i = 100; i > 0; i--) { + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + + if (!(val16 & SYS_FUNC_CPU_ENABLE)) { + dev_dbg(&priv->udev->dev, + "%s: Firmware self reset success!\n", __func__); + break; + } + udelay(50); + } + + if (!i) { + /* Force firmware reset */ + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 &= ~SYS_FUNC_CPU_ENABLE; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + } +} + +static int +rtl8xxxu_init_mac(struct rtl8xxxu_priv *priv) +{ + const struct rtl8xxxu_reg8val *array = priv->fops->mactable; + int i, ret; + u16 reg; + u8 val; + + for (i = 0; ; i++) { + reg = array[i].reg; + val = array[i].val; + + if (reg == 0xffff && val == 0xff) + break; + + ret = rtl8xxxu_write8(priv, reg, val); + if (ret != 1) { + dev_warn(&priv->udev->dev, + "Failed to initialize MAC " + "(reg: %04x, val %02x)\n", reg, val); + return -EAGAIN; + } + } + + switch (priv->rtl_chip) { + case RTL8188C: + case RTL8188R: + case RTL8191C: + case RTL8192C: + case RTL8723A: + rtl8xxxu_write8(priv, REG_MAX_AGGR_NUM, 0x0a); + break; + case RTL8188E: + rtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, 0x0707); + break; + default: + break; + } + + return 0; +} + +int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv, + const struct rtl8xxxu_reg32val *array) +{ + int i, ret; + u16 reg; + u32 val; + + for (i = 0; ; i++) { + reg = array[i].reg; + val = array[i].val; + + if (reg == 0xffff && val == 0xffffffff) + break; + + ret = rtl8xxxu_write32(priv, reg, val); + if (ret != sizeof(val)) { + dev_warn(&priv->udev->dev, + "Failed to initialize PHY\n"); + return -EAGAIN; + } + udelay(1); + } + + return 0; +} + +void rtl8xxxu_gen1_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u8 val8, ldoa15, ldov12d, lpldo, ldohci12; + u16 val16; + u32 val32; + + val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL); + udelay(2); + val8 |= AFE_PLL_320_ENABLE; + rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8); + udelay(2); + + rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL + 1, 0xff); + udelay(2); + + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); + val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB; + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); + + val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL); + val32 &= ~AFE_XTAL_RF_GATE; + if (priv->has_bluetooth) + val32 &= ~AFE_XTAL_BT_GATE; + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32); + + /* 6. 0x1f[7:0] = 0x07 */ + val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; + rtl8xxxu_write8(priv, REG_RF_CTRL, val8); + + if (priv->hi_pa) + rtl8xxxu_init_phy_regs(priv, rtl8188ru_phy_1t_highpa_table); + else if (priv->tx_paths == 2) + rtl8xxxu_init_phy_regs(priv, rtl8192cu_phy_2t_init_table); + else + rtl8xxxu_init_phy_regs(priv, rtl8723a_phy_1t_init_table); + + if (priv->rtl_chip == RTL8188R && priv->hi_pa && + priv->vendor_umc && priv->chip_cut == 1) + rtl8xxxu_write8(priv, REG_OFDM0_AGC_PARM1 + 2, 0x50); + + if (priv->hi_pa) + rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_highpa_table); + else + rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_standard_table); + + ldoa15 = LDOA15_ENABLE | LDOA15_OBUF; + ldov12d = LDOV12D_ENABLE | BIT(2) | (2 << LDOV12D_VADJ_SHIFT); + ldohci12 = 0x57; + lpldo = 1; + val32 = (lpldo << 24) | (ldohci12 << 16) | (ldov12d << 8) | ldoa15; + rtl8xxxu_write32(priv, REG_LDOA15_CTRL, val32); +} + +/* + * Most of this is black magic retrieved from the old rtl8723au driver + */ +static int rtl8xxxu_init_phy_bb(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + priv->fops->init_phy_bb(priv); + + if (priv->tx_paths == 1 && priv->rx_paths == 2) { + /* + * For 1T2R boards, patch the registers. + * + * It looks like 8191/2 1T2R boards use path B for TX + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_TX_INFO); + val32 &= ~(BIT(0) | BIT(1)); + val32 |= BIT(1); + rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, val32); + + val32 = rtl8xxxu_read32(priv, REG_FPGA1_TX_INFO); + val32 &= ~0x300033; + val32 |= 0x200022; + rtl8xxxu_write32(priv, REG_FPGA1_TX_INFO, val32); + + val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); + val32 &= ~CCK0_AFE_RX_MASK; + val32 &= 0x00ffffff; + val32 |= 0x40000000; + val32 |= CCK0_AFE_RX_ANT_B; + rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); + val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); + val32 |= (OFDM_RF_PATH_RX_A | OFDM_RF_PATH_RX_B | + OFDM_RF_PATH_TX_B); + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGC_PARM1); + val32 &= ~(BIT(4) | BIT(5)); + val32 |= BIT(4); + rtl8xxxu_write32(priv, REG_OFDM0_AGC_PARM1, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_CCK_RFON); + val32 &= ~(BIT(27) | BIT(26)); + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_TX_CCK_RFON, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_CCK_BBON); + val32 &= ~(BIT(27) | BIT(26)); + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_TX_CCK_BBON, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_OFDM_RFON); + val32 &= ~(BIT(27) | BIT(26)); + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_TX_OFDM_RFON, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_OFDM_BBON); + val32 &= ~(BIT(27) | BIT(26)); + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_TX_OFDM_BBON, val32); + + val32 = rtl8xxxu_read32(priv, REG_TX_TO_TX); + val32 &= ~(BIT(27) | BIT(26)); + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_TX_TO_TX, val32); + } + + if (priv->fops->set_crystal_cap) + priv->fops->set_crystal_cap(priv, priv->default_crystal_cap); + + if (priv->rtl_chip == RTL8192E) + rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, 0x000f81fb); + + return 0; +} + +static int rtl8xxxu_init_rf_regs(struct rtl8xxxu_priv *priv, + const struct rtl8xxxu_rfregval *array, + enum rtl8xxxu_rfpath path) +{ + int i, ret; + u8 reg; + u32 val; + + for (i = 0; ; i++) { + reg = array[i].reg; + val = array[i].val; + + if (reg == 0xff && val == 0xffffffff) + break; + + switch (reg) { + case 0xfe: + msleep(50); + continue; + case 0xfd: + mdelay(5); + continue; + case 0xfc: + mdelay(1); + continue; + case 0xfb: + udelay(50); + continue; + case 0xfa: + udelay(5); + continue; + case 0xf9: + udelay(1); + continue; + } + + ret = rtl8xxxu_write_rfreg(priv, path, reg, val); + if (ret) { + dev_warn(&priv->udev->dev, + "Failed to initialize RF\n"); + return -EAGAIN; + } + udelay(1); + } + + return 0; +} + +int rtl8xxxu_init_phy_rf(struct rtl8xxxu_priv *priv, + const struct rtl8xxxu_rfregval *table, + enum rtl8xxxu_rfpath path) +{ + u32 val32; + u16 val16, rfsi_rfenv; + u16 reg_sw_ctrl, reg_int_oe, reg_hssi_parm2; + + switch (path) { + case RF_A: + reg_sw_ctrl = REG_FPGA0_XA_RF_SW_CTRL; + reg_int_oe = REG_FPGA0_XA_RF_INT_OE; + reg_hssi_parm2 = REG_FPGA0_XA_HSSI_PARM2; + break; + case RF_B: + reg_sw_ctrl = REG_FPGA0_XB_RF_SW_CTRL; + reg_int_oe = REG_FPGA0_XB_RF_INT_OE; + reg_hssi_parm2 = REG_FPGA0_XB_HSSI_PARM2; + break; + default: + dev_err(&priv->udev->dev, "%s:Unsupported RF path %c\n", + __func__, path + 'A'); + return -EINVAL; + } + /* For path B, use XB */ + rfsi_rfenv = rtl8xxxu_read16(priv, reg_sw_ctrl); + rfsi_rfenv &= FPGA0_RF_RFENV; + + /* + * These two we might be able to optimize into one + */ + val32 = rtl8xxxu_read32(priv, reg_int_oe); + val32 |= BIT(20); /* 0x10 << 16 */ + rtl8xxxu_write32(priv, reg_int_oe, val32); + udelay(1); + + val32 = rtl8xxxu_read32(priv, reg_int_oe); + val32 |= BIT(4); + rtl8xxxu_write32(priv, reg_int_oe, val32); + udelay(1); + + /* + * These two we might be able to optimize into one + */ + val32 = rtl8xxxu_read32(priv, reg_hssi_parm2); + val32 &= ~FPGA0_HSSI_3WIRE_ADDR_LEN; + rtl8xxxu_write32(priv, reg_hssi_parm2, val32); + udelay(1); + + val32 = rtl8xxxu_read32(priv, reg_hssi_parm2); + val32 &= ~FPGA0_HSSI_3WIRE_DATA_LEN; + rtl8xxxu_write32(priv, reg_hssi_parm2, val32); + udelay(1); + + rtl8xxxu_init_rf_regs(priv, table, path); + + /* For path B, use XB */ + val16 = rtl8xxxu_read16(priv, reg_sw_ctrl); + val16 &= ~FPGA0_RF_RFENV; + val16 |= rfsi_rfenv; + rtl8xxxu_write16(priv, reg_sw_ctrl, val16); + + return 0; +} + +static int rtl8xxxu_llt_write(struct rtl8xxxu_priv *priv, u8 address, u8 data) +{ + int ret = -EBUSY; + int count = 0; + u32 value; + + value = LLT_OP_WRITE | address << 8 | data; + + rtl8xxxu_write32(priv, REG_LLT_INIT, value); + + do { + value = rtl8xxxu_read32(priv, REG_LLT_INIT); + if ((value & LLT_OP_MASK) == LLT_OP_INACTIVE) { + ret = 0; + break; + } + } while (count++ < 20); + + return ret; +} + +int rtl8xxxu_init_llt_table(struct rtl8xxxu_priv *priv) +{ + int ret; + int i, last_entry; + u8 last_tx_page; + + last_tx_page = priv->fops->total_page_num; + + if (priv->fops->last_llt_entry) + last_entry = priv->fops->last_llt_entry; + else + last_entry = 255; + + for (i = 0; i < last_tx_page; i++) { + ret = rtl8xxxu_llt_write(priv, i, i + 1); + if (ret) + goto exit; + } + + ret = rtl8xxxu_llt_write(priv, last_tx_page, 0xff); + if (ret) + goto exit; + + /* Mark remaining pages as a ring buffer */ + for (i = last_tx_page + 1; i < last_entry; i++) { + ret = rtl8xxxu_llt_write(priv, i, (i + 1)); + if (ret) + goto exit; + } + + /* Let last entry point to the start entry of ring buffer */ + ret = rtl8xxxu_llt_write(priv, last_entry, last_tx_page + 1); + if (ret) + goto exit; + +exit: + return ret; +} + +int rtl8xxxu_auto_llt_table(struct rtl8xxxu_priv *priv) +{ + u32 val32; + int ret = 0; + int i; + + val32 = rtl8xxxu_read32(priv, REG_AUTO_LLT); + val32 |= AUTO_LLT_INIT_LLT; + rtl8xxxu_write32(priv, REG_AUTO_LLT, val32); + + for (i = 500; i; i--) { + val32 = rtl8xxxu_read32(priv, REG_AUTO_LLT); + if (!(val32 & AUTO_LLT_INIT_LLT)) + break; + usleep_range(2, 4); + } + + if (!i) { + ret = -EBUSY; + dev_warn(&priv->udev->dev, "LLT table init failed\n"); + } + + return ret; +} + +static int rtl8xxxu_init_queue_priority(struct rtl8xxxu_priv *priv) +{ + u16 val16, hi, lo; + u16 hiq, mgq, bkq, beq, viq, voq; + int hip, mgp, bkp, bep, vip, vop; + int ret = 0; + u32 val32; + + switch (priv->ep_tx_count) { + case 1: + if (priv->ep_tx_high_queue) { + hi = TRXDMA_QUEUE_HIGH; + } else if (priv->ep_tx_low_queue) { + hi = TRXDMA_QUEUE_LOW; + } else if (priv->ep_tx_normal_queue) { + hi = TRXDMA_QUEUE_NORMAL; + } else { + hi = 0; + ret = -EINVAL; + } + + hiq = hi; + mgq = hi; + bkq = hi; + beq = hi; + viq = hi; + voq = hi; + + hip = 0; + mgp = 0; + bkp = 0; + bep = 0; + vip = 0; + vop = 0; + break; + case 2: + if (priv->ep_tx_high_queue && priv->ep_tx_low_queue) { + hi = TRXDMA_QUEUE_HIGH; + lo = TRXDMA_QUEUE_LOW; + } else if (priv->ep_tx_normal_queue && priv->ep_tx_low_queue) { + hi = TRXDMA_QUEUE_NORMAL; + lo = TRXDMA_QUEUE_LOW; + } else if (priv->ep_tx_high_queue && priv->ep_tx_normal_queue) { + hi = TRXDMA_QUEUE_HIGH; + lo = TRXDMA_QUEUE_NORMAL; + } else { + ret = -EINVAL; + hi = 0; + lo = 0; + } + + hiq = hi; + mgq = hi; + bkq = lo; + beq = lo; + viq = hi; + voq = hi; + + hip = 0; + mgp = 0; + bkp = 1; + bep = 1; + vip = 0; + vop = 0; + break; + case 3: + beq = TRXDMA_QUEUE_LOW; + bkq = TRXDMA_QUEUE_LOW; + viq = TRXDMA_QUEUE_NORMAL; + voq = TRXDMA_QUEUE_HIGH; + mgq = TRXDMA_QUEUE_HIGH; + hiq = TRXDMA_QUEUE_HIGH; + + hip = hiq ^ 3; + mgp = mgq ^ 3; + bkp = bkq ^ 3; + bep = beq ^ 3; + vip = viq ^ 3; + vop = viq ^ 3; + break; + default: + ret = -EINVAL; + } + + /* + * None of the vendor drivers are configuring the beacon + * queue here .... why? + */ + if (!ret) { + /* Only RTL8192F seems to do it like this. */ + if (priv->rtl_chip == RTL8192F) { + val32 = rtl8xxxu_read32(priv, REG_TRXDMA_CTRL); + val32 &= 0x7; + val32 |= (voq << TRXDMA_CTRL_VOQ_SHIFT_8192F) | + (viq << TRXDMA_CTRL_VIQ_SHIFT_8192F) | + (beq << TRXDMA_CTRL_BEQ_SHIFT_8192F) | + (bkq << TRXDMA_CTRL_BKQ_SHIFT_8192F) | + (mgq << TRXDMA_CTRL_MGQ_SHIFT_8192F) | + (hiq << TRXDMA_CTRL_HIQ_SHIFT_8192F); + rtl8xxxu_write32(priv, REG_TRXDMA_CTRL, val32); + } else { + val16 = rtl8xxxu_read16(priv, REG_TRXDMA_CTRL); + val16 &= 0x7; + val16 |= (voq << TRXDMA_CTRL_VOQ_SHIFT) | + (viq << TRXDMA_CTRL_VIQ_SHIFT) | + (beq << TRXDMA_CTRL_BEQ_SHIFT) | + (bkq << TRXDMA_CTRL_BKQ_SHIFT) | + (mgq << TRXDMA_CTRL_MGQ_SHIFT) | + (hiq << TRXDMA_CTRL_HIQ_SHIFT); + rtl8xxxu_write16(priv, REG_TRXDMA_CTRL, val16); + } + + priv->pipe_out[TXDESC_QUEUE_VO] = + usb_sndbulkpipe(priv->udev, priv->out_ep[vop]); + priv->pipe_out[TXDESC_QUEUE_VI] = + usb_sndbulkpipe(priv->udev, priv->out_ep[vip]); + priv->pipe_out[TXDESC_QUEUE_BE] = + usb_sndbulkpipe(priv->udev, priv->out_ep[bep]); + priv->pipe_out[TXDESC_QUEUE_BK] = + usb_sndbulkpipe(priv->udev, priv->out_ep[bkp]); + priv->pipe_out[TXDESC_QUEUE_BEACON] = + usb_sndbulkpipe(priv->udev, priv->out_ep[0]); + priv->pipe_out[TXDESC_QUEUE_MGNT] = + usb_sndbulkpipe(priv->udev, priv->out_ep[mgp]); + priv->pipe_out[TXDESC_QUEUE_HIGH] = + usb_sndbulkpipe(priv->udev, priv->out_ep[hip]); + priv->pipe_out[TXDESC_QUEUE_CMD] = + usb_sndbulkpipe(priv->udev, priv->out_ep[0]); + } + + return ret; +} + +void rtl8xxxu_fill_iqk_matrix_a(struct rtl8xxxu_priv *priv, bool iqk_ok, + int result[][8], int candidate, bool tx_only) +{ + u32 oldval, x, tx0_a, reg; + int y, tx0_c; + u32 val32; + + if (!iqk_ok) + return; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE); + oldval = val32 >> 22; + + x = result[candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xfffffc00; + tx0_a = (x * oldval) >> 8; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE); + val32 &= ~0x3ff; + val32 |= tx0_a; + rtl8xxxu_write32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES); + val32 &= ~BIT(31); + if ((x * oldval >> 7) & 0x1) + val32 |= BIT(31); + rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32); + + y = result[candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xfffffc00; + tx0_c = (y * oldval) >> 8; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XC_TX_AFE); + val32 &= ~0xf0000000; + val32 |= (((tx0_c & 0x3c0) >> 6) << 28); + rtl8xxxu_write32(priv, REG_OFDM0_XC_TX_AFE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE); + val32 &= ~0x003f0000; + val32 |= ((tx0_c & 0x3f) << 16); + rtl8xxxu_write32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES); + val32 &= ~BIT(29); + if ((y * oldval >> 7) & 0x1) + val32 |= BIT(29); + rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32); + + if (tx_only) { + dev_dbg(&priv->udev->dev, "%s: only TX\n", __func__); + return; + } + + reg = result[candidate][2]; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE); + val32 &= ~0x3ff; + val32 |= (reg & 0x3ff); + rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE, val32); + + reg = result[candidate][3] & 0x3F; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE); + val32 &= ~0xfc00; + val32 |= ((reg << 10) & 0xfc00); + rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE, val32); + + reg = (result[candidate][3] >> 6) & 0xF; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_IQ_EXT_ANTA); + val32 &= ~0xf0000000; + val32 |= (reg << 28); + rtl8xxxu_write32(priv, REG_OFDM0_RX_IQ_EXT_ANTA, val32); +} + +void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv, bool iqk_ok, + int result[][8], int candidate, bool tx_only) +{ + u32 oldval, x, tx1_a, reg; + int y, tx1_c; + u32 val32; + + if (!iqk_ok) + return; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE); + oldval = val32 >> 22; + + x = result[candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xfffffc00; + tx1_a = (x * oldval) >> 8; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE); + val32 &= ~0x3ff; + val32 |= tx1_a; + rtl8xxxu_write32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES); + val32 &= ~BIT(27); + if ((x * oldval >> 7) & 0x1) + val32 |= BIT(27); + rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32); + + y = result[candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xfffffc00; + tx1_c = (y * oldval) >> 8; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XD_TX_AFE); + val32 &= ~0xf0000000; + val32 |= (((tx1_c & 0x3c0) >> 6) << 28); + rtl8xxxu_write32(priv, REG_OFDM0_XD_TX_AFE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE); + val32 &= ~0x003f0000; + val32 |= ((tx1_c & 0x3f) << 16); + rtl8xxxu_write32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE, val32); + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES); + val32 &= ~BIT(25); + if ((y * oldval >> 7) & 0x1) + val32 |= BIT(25); + rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32); + + if (tx_only) { + dev_dbg(&priv->udev->dev, "%s: only TX\n", __func__); + return; + } + + reg = result[candidate][6]; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE); + val32 &= ~0x3ff; + val32 |= (reg & 0x3ff); + rtl8xxxu_write32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE, val32); + + reg = result[candidate][7] & 0x3f; + + val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE); + val32 &= ~0xfc00; + val32 |= ((reg << 10) & 0xfc00); + rtl8xxxu_write32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE, val32); + + reg = (result[candidate][7] >> 6) & 0xf; + + if (priv->rtl_chip == RTL8192F) { + rtl8xxxu_write32_mask(priv, REG_RXIQB_EXT, 0x000000f0, reg); + } else { + val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGC_RSSI_TABLE); + val32 &= ~0x0000f000; + val32 |= (reg << 12); + rtl8xxxu_write32(priv, REG_OFDM0_AGC_RSSI_TABLE, val32); + } +} + +#define MAX_TOLERANCE 5 + +bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv, + int result[][8], int c1, int c2) +{ + u32 i, j, diff, simubitmap, bound = 0; + int candidate[2] = {-1, -1}; /* for path A and path B */ + bool retval = true; + + if (priv->tx_paths > 1) + bound = 8; + else + bound = 4; + + simubitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simubitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + candidate[(i / 4)] = c1; + else + simubitmap = simubitmap | (1 << i); + } else { + simubitmap = simubitmap | (1 << i); + } + } + } + + if (simubitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (candidate[i] >= 0) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = result[candidate[i]][j]; + retval = false; + } + } + return retval; + } else if (!(simubitmap & 0x0f)) { + /* path A OK */ + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + } else if (!(simubitmap & 0xf0) && priv->tx_paths > 1) { + /* path B OK */ + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + } + + return false; +} + +bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, + int result[][8], int c1, int c2) +{ + u32 i, j, diff, simubitmap, bound = 0; + int candidate[2] = {-1, -1}; /* for path A and path B */ + int tmp1, tmp2; + bool retval = true; + + if (priv->tx_paths > 1) + bound = 8; + else + bound = 4; + + simubitmap = 0; + + for (i = 0; i < bound; i++) { + if (i & 1) { + if ((result[c1][i] & 0x00000200)) + tmp1 = result[c1][i] | 0xfffffc00; + else + tmp1 = result[c1][i]; + + if ((result[c2][i]& 0x00000200)) + tmp2 = result[c2][i] | 0xfffffc00; + else + tmp2 = result[c2][i]; + } else { + tmp1 = result[c1][i]; + tmp2 = result[c2][i]; + } + + diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simubitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + candidate[(i / 4)] = c1; + else + simubitmap = simubitmap | (1 << i); + } else { + simubitmap = simubitmap | (1 << i); + } + } + } + + if (simubitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (candidate[i] >= 0) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = result[candidate[i]][j]; + retval = false; + } + } + return retval; + } else { + if (!(simubitmap & 0x03)) { + /* path A TX OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + + if (!(simubitmap & 0x0c)) { + /* path A RX OK */ + for (i = 2; i < 4; i++) + result[3][i] = result[c1][i]; + } + + if (!(simubitmap & 0x30) && priv->tx_paths > 1) { + /* path B TX OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + + if (!(simubitmap & 0xc0) && priv->tx_paths > 1) { + /* path B RX OK */ + for (i = 6; i < 8; i++) + result[3][i] = result[c1][i]; + } + } + + return false; +} + +void +rtl8xxxu_save_mac_regs(struct rtl8xxxu_priv *priv, const u32 *reg, u32 *backup) +{ + int i; + + for (i = 0; i < (RTL8XXXU_MAC_REGS - 1); i++) + backup[i] = rtl8xxxu_read8(priv, reg[i]); + + backup[i] = rtl8xxxu_read32(priv, reg[i]); +} + +void rtl8xxxu_restore_mac_regs(struct rtl8xxxu_priv *priv, + const u32 *reg, u32 *backup) +{ + int i; + + for (i = 0; i < (RTL8XXXU_MAC_REGS - 1); i++) + rtl8xxxu_write8(priv, reg[i], backup[i]); + + rtl8xxxu_write32(priv, reg[i], backup[i]); +} + +void rtl8xxxu_save_regs(struct rtl8xxxu_priv *priv, const u32 *regs, + u32 *backup, int count) +{ + int i; + + for (i = 0; i < count; i++) + backup[i] = rtl8xxxu_read32(priv, regs[i]); +} + +void rtl8xxxu_restore_regs(struct rtl8xxxu_priv *priv, const u32 *regs, + u32 *backup, int count) +{ + int i; + + for (i = 0; i < count; i++) + rtl8xxxu_write32(priv, regs[i], backup[i]); +} + + +void rtl8xxxu_path_adda_on(struct rtl8xxxu_priv *priv, const u32 *regs, + bool path_a_on) +{ + u32 path_on; + int i; + + if (priv->tx_paths == 1) { + path_on = priv->fops->adda_1t_path_on; + rtl8xxxu_write32(priv, regs[0], priv->fops->adda_1t_init); + } else { + path_on = path_a_on ? priv->fops->adda_2t_path_on_a : + priv->fops->adda_2t_path_on_b; + + rtl8xxxu_write32(priv, regs[0], path_on); + } + + for (i = 1 ; i < RTL8XXXU_ADDA_REGS ; i++) + rtl8xxxu_write32(priv, regs[i], path_on); +} + +void rtl8xxxu_mac_calibration(struct rtl8xxxu_priv *priv, + const u32 *regs, u32 *backup) +{ + int i = 0; + + rtl8xxxu_write8(priv, regs[i], 0x3f); + + for (i = 1 ; i < (RTL8XXXU_MAC_REGS - 1); i++) + rtl8xxxu_write8(priv, regs[i], (u8)(backup[i] & ~BIT(3))); + + rtl8xxxu_write8(priv, regs[i], (u8)(backup[i] & ~BIT(5))); +} + +static int rtl8xxxu_iqk_path_a(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4, val32; + int result = 0; + + /* path-A IQK setting */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1f); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x10008c1f); + rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82140102); + + val32 = (priv->rf_paths > 1) ? 0x28160202 : + /*IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202: */ + 0x28160502; + rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, val32); + + /* path-B IQK setting */ + if (priv->rf_paths > 1) { + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x10008c22); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x10008c22); + rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82140102); + rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28160202); + } + + /* LO calibration setting */ + rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x001028d1); + + /* One shot, path A LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); + rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); + + mdelay(1); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); + reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); + reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); + + if (!(reg_eac & BIT(28)) && + ((reg_e94 & 0x03ff0000) != 0x01420000) && + ((reg_e9c & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else /* If TX not OK, ignore RX */ + goto out; + + /* If TX is OK, check whether RX is OK */ + if (!(reg_eac & BIT(27)) && + ((reg_ea4 & 0x03ff0000) != 0x01320000) && + ((reg_eac & 0x03ff0000) != 0x00360000)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path A RX IQK failed!\n", + __func__); +out: + return result; +} + +static int rtl8xxxu_iqk_path_b(struct rtl8xxxu_priv *priv) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + int result = 0; + + /* One shot, path B LOK & IQK */ + rtl8xxxu_write32(priv, REG_IQK_AGC_CONT, 0x00000002); + rtl8xxxu_write32(priv, REG_IQK_AGC_CONT, 0x00000000); + + mdelay(1); + + /* Check failed */ + reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); + reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); + reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); + + if (!(reg_eac & BIT(31)) && + ((reg_eb4 & 0x03ff0000) != 0x01420000) && + ((reg_ebc & 0x03ff0000) != 0x00420000)) + result |= 0x01; + else + goto out; + + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03ff0000) >> 16) != 0x132) && + (((reg_ecc & 0x03ff0000) >> 16) != 0x36)) + result |= 0x02; + else + dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n", + __func__); +out: + return result; +} + +static void rtl8xxxu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, + int result[][8], int t) +{ + struct device *dev = &priv->udev->dev; + u32 i, val32; + int path_a_ok, path_b_ok; + int retry = 2; + static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { + REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, + REG_RX_WAIT_CCA, REG_TX_CCK_RFON, + REG_TX_CCK_BBON, REG_TX_OFDM_RFON, + REG_TX_OFDM_BBON, REG_TX_TO_RX, + REG_TX_TO_TX, REG_RX_CCK, + REG_RX_OFDM, REG_RX_WAIT_RIFS, + REG_RX_TO_RX, REG_STANDBY, + REG_SLEEP, REG_PMPD_ANAEN + }; + static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { + REG_TXPAUSE, REG_BEACON_CTRL, + REG_BEACON_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { + REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, + REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, + REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, + REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE + }; + + /* + * Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + if (t == 0) { + /* Save ADDA parameters, turn Path A ADDA on */ + rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + rtl8xxxu_save_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + } + + rtl8xxxu_path_adda_on(priv, adda_regs, true); + + if (t == 0) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1); + if (val32 & FPGA0_HSSI_PARM1_PI) + priv->pi_enabled = 1; + } + + if (!priv->pi_enabled) { + /* Switch BB to PI mode to do IQ Calibration. */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000100); + } + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 &= ~FPGA_RF_MODE_CCK; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); + rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22204000); + + if (!priv->no_pape) { + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_SW_CTRL); + val32 |= (FPGA0_RF_PAPE | + (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT)); + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32); + } + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_RF_INT_OE); + val32 &= ~BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, val32); + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); + val32 &= ~BIT(10); + rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); + + if (priv->tx_paths > 1) { + rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00010000); + rtl8xxxu_write32(priv, REG_FPGA0_XB_LSSI_PARM, 0x00010000); + } + + /* MAC settings */ + rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); + + /* Page B init */ + rtl8xxxu_write32(priv, REG_CONFIG_ANT_A, 0x00080000); + + if (priv->tx_paths > 1) + rtl8xxxu_write32(priv, REG_CONFIG_ANT_B, 0x00080000); + + /* IQ calibration setting */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); + rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); + + for (i = 0; i < retry; i++) { + path_a_ok = rtl8xxxu_iqk_path_a(priv); + if (path_a_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_BEFORE_IQK_A_2); + result[t][2] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_RX_POWER_AFTER_IQK_A_2); + result[t][3] = (val32 >> 16) & 0x3ff; + break; + } else if (i == (retry - 1) && path_a_ok == 0x01) { + /* TX IQK OK */ + dev_dbg(dev, "%s: Path A IQK Only Tx Success!!\n", + __func__); + + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_BEFORE_IQK_A); + result[t][0] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, + REG_TX_POWER_AFTER_IQK_A); + result[t][1] = (val32 >> 16) & 0x3ff; + } + } + + if (!path_a_ok) + dev_dbg(dev, "%s: Path A IQK failed!\n", __func__); + + if (priv->tx_paths > 1) { + /* + * Path A into standby + */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x0); + rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00010000); + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); + + /* Turn Path B ADDA on */ + rtl8xxxu_path_adda_on(priv, adda_regs, false); + + for (i = 0; i < retry; i++) { + path_b_ok = rtl8xxxu_iqk_path_b(priv); + if (path_b_ok == 0x03) { + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + result[t][4] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + result[t][5] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); + result[t][6] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); + result[t][7] = (val32 >> 16) & 0x3ff; + break; + } else if (i == (retry - 1) && path_b_ok == 0x01) { + /* TX IQK OK */ + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); + result[t][4] = (val32 >> 16) & 0x3ff; + val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); + result[t][5] = (val32 >> 16) & 0x3ff; + } + } + + if (!path_b_ok) + dev_dbg(dev, "%s: Path B IQK failed!\n", __func__); + } + + /* Back to BB mode, load original value */ + rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0); + + if (t) { + if (!priv->pi_enabled) { + /* + * Switch back BB to SI mode after finishing + * IQ Calibration + */ + val32 = 0x01000000; + rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, val32); + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, val32); + } + + /* Reload ADDA power saving parameters */ + rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, + RTL8XXXU_ADDA_REGS); + + /* Reload MAC parameters */ + rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); + + /* Reload BB parameters */ + rtl8xxxu_restore_regs(priv, iqk_bb_regs, + priv->bb_backup, RTL8XXXU_BB_REGS); + + /* Restore RX initial gain */ + rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00032ed3); + + if (priv->tx_paths > 1) { + rtl8xxxu_write32(priv, REG_FPGA0_XB_LSSI_PARM, + 0x00032ed3); + } + + /* Load 0xe30 IQC default value */ + rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); + rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); + } +} + +void rtl8xxxu_gen2_prepare_calibrate(struct rtl8xxxu_priv *priv, u8 start) +{ + struct h2c_cmd h2c; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.bt_wlan_calibration.cmd = H2C_8723B_BT_WLAN_CALIBRATION; + h2c.bt_wlan_calibration.data = start; + + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_wlan_calibration)); +} + +void rtl8xxxu_gen1_phy_iq_calibrate(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + int result[4][8]; /* last is final result */ + int i, candidate; + bool path_a_ok, path_b_ok; + u32 reg_e94, reg_e9c, reg_ea4, reg_eac; + u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; + s32 reg_tmp = 0; + bool simu; + + memset(result, 0, sizeof(result)); + candidate = -1; + + path_a_ok = false; + path_b_ok = false; + + rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + + for (i = 0; i < 3; i++) { + rtl8xxxu_phy_iqcalibrate(priv, result, i); + + if (i == 1) { + simu = rtl8xxxu_simularity_compare(priv, result, 0, 1); + if (simu) { + candidate = 0; + break; + } + } + + if (i == 2) { + simu = rtl8xxxu_simularity_compare(priv, result, 0, 2); + if (simu) { + candidate = 0; + break; + } + + simu = rtl8xxxu_simularity_compare(priv, result, 1, 2); + if (simu) { + candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp) + candidate = 3; + else + candidate = -1; + } + } + } + + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + + if (candidate >= 0) { + reg_e94 = result[candidate][0]; + priv->rege94 = reg_e94; + reg_e9c = result[candidate][1]; + priv->rege9c = reg_e9c; + reg_ea4 = result[candidate][2]; + reg_eac = result[candidate][3]; + reg_eb4 = result[candidate][4]; + priv->regeb4 = reg_eb4; + reg_ebc = result[candidate][5]; + priv->regebc = reg_ebc; + reg_ec4 = result[candidate][6]; + reg_ecc = result[candidate][7]; + dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); + dev_dbg(dev, + "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", + __func__, reg_e94, reg_e9c, + reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); + path_a_ok = true; + path_b_ok = true; + } else { + reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; + reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; + } + + if (reg_e94 && candidate >= 0) + rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, + candidate, (reg_ea4 == 0)); + + if (priv->tx_paths > 1 && reg_eb4) + rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, + candidate, (reg_ec4 == 0)); + + rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, + priv->bb_recovery_backup, RTL8XXXU_BB_REGS); +} + +void rtl8723a_phy_lc_calibrate(struct rtl8xxxu_priv *priv) +{ + u32 val32; + u32 rf_amode, rf_bmode = 0, lstf; + + /* Check continuous TX and Packet TX */ + lstf = rtl8xxxu_read32(priv, REG_OFDM1_LSTF); + + if (lstf & OFDM_LSTF_MASK) { + /* Disable all continuous TX */ + val32 = lstf & ~OFDM_LSTF_MASK; + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32); + + /* Read original RF mode Path A */ + rf_amode = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_AC); + + /* Set RF mode to standby Path A */ + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, + (rf_amode & 0x8ffff) | 0x10000); + + /* Path-B */ + if (priv->tx_paths > 1) { + rf_bmode = rtl8xxxu_read_rfreg(priv, RF_B, + RF6052_REG_AC); + + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, + (rf_bmode & 0x8ffff) | 0x10000); + } + } else { + /* Deal with Packet TX case */ + /* block all queues */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + } + + /* Start LC calibration */ + if (priv->fops->has_s0s1) + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, 0xdfbe0); + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); + val32 |= 0x08000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); + + msleep(100); + + if (priv->fops->has_s0s1) + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, 0xdffe0); + + /* Restore original parameters */ + if (lstf & OFDM_LSTF_MASK) { + /* Path-A */ + rtl8xxxu_write32(priv, REG_OFDM1_LSTF, lstf); + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, rf_amode); + + /* Path-B */ + if (priv->tx_paths > 1) + rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, + rf_bmode); + } else /* Deal with Packet TX case */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); +} + +static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv, int port_num) +{ + int i; + u16 reg; + + switch (port_num) { + case 0: + reg = REG_MACID; + break; + case 1: + reg = REG_MACID1; + break; + default: + WARN_ONCE(1, "%s: invalid port_num\n", __func__); + return -EINVAL; + } + + for (i = 0; i < ETH_ALEN; i++) + rtl8xxxu_write8(priv, reg + i, priv->vifs[port_num]->addr[i]); + + return 0; +} + +static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid, int port_num) +{ + int i; + u16 reg; + + dev_dbg(&priv->udev->dev, "%s: (%pM)\n", __func__, bssid); + + switch (port_num) { + case 0: + reg = REG_BSSID; + break; + case 1: + reg = REG_BSSID1; + break; + default: + WARN_ONCE(1, "%s: invalid port_num\n", __func__); + return -EINVAL; + } + + for (i = 0; i < ETH_ALEN; i++) + rtl8xxxu_write8(priv, reg + i, bssid[i]); + + return 0; +} + +static void +rtl8xxxu_set_ampdu_factor(struct rtl8xxxu_priv *priv, u8 ampdu_factor) +{ + u8 vals[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + u8 max_agg = 0xf; + int i; + + ampdu_factor = 1 << (ampdu_factor + 2); + if (ampdu_factor > max_agg) + ampdu_factor = max_agg; + + for (i = 0; i < 4; i++) { + if ((vals[i] & 0xf0) > (ampdu_factor << 4)) + vals[i] = (vals[i] & 0x0f) | (ampdu_factor << 4); + + if ((vals[i] & 0x0f) > ampdu_factor) + vals[i] = (vals[i] & 0xf0) | ampdu_factor; + + rtl8xxxu_write8(priv, REG_AGGLEN_LMT + i, vals[i]); + } +} + +static void rtl8xxxu_set_ampdu_min_space(struct rtl8xxxu_priv *priv, u8 density) +{ + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_AMPDU_MIN_SPACE); + val8 &= 0xf8; + val8 |= density; + rtl8xxxu_write8(priv, REG_AMPDU_MIN_SPACE, val8); +} + +int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv) +{ + u8 val8; + u8 val32; + int count, ret = 0; + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + /* + * Poll - wait for RX packet to complete + */ + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { + val32 = rtl8xxxu_read32(priv, 0x5f8); + if (!val32) + break; + udelay(10); + } + + if (!count) { + dev_warn(&priv->udev->dev, + "%s: RX poll timed out (0x05f8)\n", __func__); + ret = -EBUSY; + goto exit; + } + + /* Disable CCK and OFDM, clock gated */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BBRSTB; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + udelay(2); + + /* Reset baseband */ + val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); + val8 &= ~SYS_FUNC_BB_GLB_RSTN; + rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); + + /* Reset MAC TRX */ + val8 = rtl8xxxu_read8(priv, REG_CR); + val8 = CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE; + rtl8xxxu_write8(priv, REG_CR, val8); + + /* Reset MAC TRX */ + val8 = rtl8xxxu_read8(priv, REG_CR + 1); + val8 &= ~BIT(1); /* CR_SECURITY_ENABLE */ + rtl8xxxu_write8(priv, REG_CR + 1, val8); + + /* Respond TX OK to scheduler */ + val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); + val8 |= DUAL_TSF_TX_OK; + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); + +exit: + return ret; +} + +void rtl8xxxu_disabled_to_emu(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* Clear suspend enable and power down enable*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(7)); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); + + /* 0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ + val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); + val8 &= ~BIT(0); + rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); + + /* 0x04[12:11] = 11 enable WL suspend*/ + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); + val8 &= ~(BIT(3) | BIT(4)); + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); +} + +int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv) +{ + struct device *dev = &priv->udev->dev; + u32 val32; + int retry, retval; + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + val32 = rtl8xxxu_read32(priv, REG_RXPKT_NUM); + val32 |= RXPKT_NUM_RW_RELEASE_EN; + rtl8xxxu_write32(priv, REG_RXPKT_NUM, val32); + + retry = 100; + retval = -EBUSY; + + do { + val32 = rtl8xxxu_read32(priv, REG_RXPKT_NUM); + if (val32 & RXPKT_NUM_RXDMA_IDLE) { + retval = 0; + break; + } + } while (retry--); + + rtl8xxxu_write16(priv, REG_RQPN_NPQ, 0); + rtl8xxxu_write32(priv, REG_RQPN, 0x80000000); + mdelay(2); + + if (!retry) + dev_warn(dev, "Failed to flush FIFO\n"); + + return retval; +} + +void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv) +{ + /* Fix USB interface interference issue */ + rtl8xxxu_write8(priv, 0xfe40, 0xe0); + rtl8xxxu_write8(priv, 0xfe41, 0x8d); + rtl8xxxu_write8(priv, 0xfe42, 0x80); + /* + * This sets TXDMA_OFFSET_DROP_DATA_EN (bit 9) as well as bits + * 8 and 5, for which I have found no documentation. + */ + rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, 0xfd0320); + + /* + * Solve too many protocol error on USB bus. + * Can't do this for 8188/8192 UMC A cut parts + */ + if (!(!priv->chip_cut && priv->vendor_umc)) { + rtl8xxxu_write8(priv, 0xfe40, 0xe6); + rtl8xxxu_write8(priv, 0xfe41, 0x94); + rtl8xxxu_write8(priv, 0xfe42, 0x80); + + rtl8xxxu_write8(priv, 0xfe40, 0xe0); + rtl8xxxu_write8(priv, 0xfe41, 0x19); + rtl8xxxu_write8(priv, 0xfe42, 0x80); + + rtl8xxxu_write8(priv, 0xfe40, 0xe5); + rtl8xxxu_write8(priv, 0xfe41, 0x91); + rtl8xxxu_write8(priv, 0xfe42, 0x80); + + rtl8xxxu_write8(priv, 0xfe40, 0xe2); + rtl8xxxu_write8(priv, 0xfe41, 0x81); + rtl8xxxu_write8(priv, 0xfe42, 0x80); + } +} + +void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_TXDMA_OFFSET_CHK); + val32 |= TXDMA_OFFSET_DROP_DATA_EN; + rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32); +} + +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) +{ + struct h2c_cmd h2c; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + h2c.b_type_dma.cmd = H2C_8723B_B_TYPE_TDMA; + h2c.b_type_dma.data1 = arg1; + h2c.b_type_dma.data2 = arg2; + h2c.b_type_dma.data3 = arg3; + h2c.b_type_dma.data4 = arg4; + h2c.b_type_dma.data5 = arg5; + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_type_dma)); +} + +void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv) +{ + u32 val32; + + val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); + val32 &= ~(BIT(22) | BIT(23)); + rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); +} + +static void rtl8xxxu_init_queue_reserved_page(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_fileops *fops = priv->fops; + u32 hq, lq, nq, eq, pubq; + u32 val32; + + hq = 0; + lq = 0; + nq = 0; + eq = 0; + pubq = 0; + + if (priv->ep_tx_high_queue) + hq = fops->page_num_hi; + if (priv->ep_tx_low_queue) + lq = fops->page_num_lo; + if (priv->ep_tx_normal_queue) + nq = fops->page_num_norm; + + val32 = (nq << RQPN_NPQ_SHIFT) | (eq << RQPN_EPQ_SHIFT); + rtl8xxxu_write32(priv, REG_RQPN_NPQ, val32); + + pubq = fops->total_page_num - hq - lq - nq - 1; + + val32 = RQPN_LOAD; + val32 |= (hq << RQPN_HI_PQ_SHIFT); + val32 |= (lq << RQPN_LO_PQ_SHIFT); + val32 |= (pubq << RQPN_PUB_PQ_SHIFT); + + rtl8xxxu_write32(priv, REG_RQPN, val32); +} + +void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv) +{ + u8 val8; + + /* + * For USB high speed set 512B packets + */ + val8 = rtl8xxxu_read8(priv, REG_RXDMA_PRO_8723B); + u8p_replace_bits(&val8, 1, RXDMA_PRO_DMA_BURST_SIZE); + u8p_replace_bits(&val8, 3, RXDMA_PRO_DMA_BURST_CNT); + val8 |= RXDMA_PRO_DMA_MODE; + rtl8xxxu_write8(priv, REG_RXDMA_PRO_8723B, val8); + + /* + * Enable single packet AMPDU + */ + val8 = rtl8xxxu_read8(priv, REG_HT_SINGLE_AMPDU_8723B); + val8 |= HT_SINGLE_AMPDU_ENABLE; + rtl8xxxu_write8(priv, REG_HT_SINGLE_AMPDU_8723B, val8); + + rtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, priv->fops->max_aggr_num); + rtl8xxxu_write8(priv, REG_AMPDU_MAX_TIME_8723B, + priv->fops->ampdu_max_time); + rtl8xxxu_write32(priv, REG_AGGLEN_LMT, 0xffffffff); + rtl8xxxu_write8(priv, REG_RX_PKT_LIMIT, 0x18); + rtl8xxxu_write8(priv, REG_PIFS, 0x00); + if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8710B || + priv->rtl_chip == RTL8192F) { + rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL, FWHW_TXQ_CTRL_AMPDU_RETRY); + rtl8xxxu_write32(priv, REG_FAST_EDCA_CTRL, 0x03086666); + } + rtl8xxxu_write8(priv, REG_USTIME_TSF_8723B, priv->fops->ustime_tsf_edca); + rtl8xxxu_write8(priv, REG_USTIME_EDCA, priv->fops->ustime_tsf_edca); + + /* to prevent mac is reseted by bus. */ + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL); + val8 |= RSV_CTRL_WLOCK_1C | RSV_CTRL_DIS_PRST; + rtl8xxxu_write8(priv, REG_RSV_CTRL, val8); +} + +static u8 rtl8xxxu_acquire_macid(struct rtl8xxxu_priv *priv) +{ + u8 macid; + + macid = find_first_zero_bit(priv->mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM); + if (macid < RTL8XXXU_MAX_MAC_ID_NUM) + set_bit(macid, priv->mac_id_map); + + return macid; +} + +static void rtl8xxxu_release_macid(struct rtl8xxxu_priv *priv, u8 macid) +{ + clear_bit(macid, priv->mac_id_map); +} + +static inline u8 rtl8xxxu_get_macid(struct rtl8xxxu_priv *priv, + struct ieee80211_sta *sta) +{ + struct rtl8xxxu_sta_info *sta_info; + + if (!sta) + return 0; + + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + if (!sta_info) + return 0; + + return sta_info->macid; +} + +static void rtl8xxxu_request_hw_feature(struct rtl8xxxu_priv *priv) +{ + if (!priv->fops->hw_feature_report) + return; + + rtl8xxxu_write8(priv, REG_C2HEVT_MSG_NORMAL, C2H_HW_FEATURE_DUMP); +} + +static int rtl8xxxu_dump_hw_feature(struct rtl8xxxu_priv *priv) +{ + static const u8 bw_map[8] = { 0, 0, 160, 5, 10, 20, 40, 80 }; + struct rtl8xxxu_hw_feature *hw_feature = &priv->hw_feature; + u8 feature[13]; + int i, ret; + u8 id, bw; + + if (!priv->fops->hw_feature_report) { + hw_feature->max_bw = 40; + return 0; + } + + ret = read_poll_timeout(rtl8xxxu_read8, id, + id == C2H_HW_FEATURE_REPORT, + 10000, 800000, false, + priv, REG_C2HEVT_MSG_NORMAL); + if (ret) + return ret; + + for (i = 0; i < ARRAY_SIZE(feature); i++) + feature[i] = rtl8xxxu_read8(priv, REG_C2HEVT_MSG_NORMAL + 2 + i); + + rtl8xxxu_write8(priv, REG_C2HEVT_MSG_NORMAL, 0); + + bw = u8_get_bits(feature[6], GENMASK(2, 0)); + + hw_feature->max_bw = bw_map[bw]; + + return 0; +} + +static int rtl8xxxu_init_device(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + struct rtl8xxxu_fileops *fops = priv->fops; + bool macpower; + int ret; + u8 val8; + u16 val16; + u32 val32; + + /* Check if MAC is already powered on */ + val8 = rtl8xxxu_read8(priv, REG_CR); + val16 = rtl8xxxu_read16(priv, REG_SYS_CLKR); + + /* + * Fix 92DU-VC S3 hang with the reason is that secondary mac is not + * initialized. First MAC returns 0xea, second MAC returns 0x00 + */ + if (val8 == 0xea || !(val16 & SYS_CLK_MAC_CLK_ENABLE)) + macpower = false; + else + macpower = true; + + if (fops->needs_full_init) + macpower = false; + + ret = fops->power_on(priv); + if (ret < 0) { + dev_warn(dev, "%s: Failed power on\n", __func__); + goto exit; + } + + if (!macpower) + rtl8xxxu_init_queue_reserved_page(priv); + + ret = rtl8xxxu_init_queue_priority(priv); + dev_dbg(dev, "%s: init_queue_priority %i\n", __func__, ret); + if (ret) + goto exit; + + /* + * Set RX page boundary + */ + rtl8xxxu_write16(priv, REG_TRXFF_BNDY + 2, fops->trxff_boundary); + + rtl8xxxu_request_hw_feature(priv); + + for (int retry = 5; retry >= 0 ; retry--) { + ret = rtl8xxxu_download_firmware(priv); + dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret); + if (ret != -EAGAIN) + break; + if (retry) + dev_dbg(dev, "%s: retry firmware download\n", __func__); + } + if (ret) + goto exit; + ret = rtl8xxxu_start_firmware(priv); + dev_dbg(dev, "%s: start_firmware %i\n", __func__, ret); + if (ret) + goto exit; + + ret = rtl8xxxu_dump_hw_feature(priv); + if (ret) { + dev_err(dev, "failed to dump hw feature\n"); + goto exit; + } + + if (fops->phy_init_antenna_selection) + fops->phy_init_antenna_selection(priv); + + ret = rtl8xxxu_init_mac(priv); + + dev_dbg(dev, "%s: init_mac %i\n", __func__, ret); + if (ret) + goto exit; + + ret = rtl8xxxu_init_phy_bb(priv); + dev_dbg(dev, "%s: init_phy_bb %i\n", __func__, ret); + if (ret) + goto exit; + + ret = fops->init_phy_rf(priv); + if (ret) + goto exit; + + /* Mac APLL Setting */ + if (priv->rtl_chip == RTL8192F) + rtl8xxxu_write16_set(priv, REG_AFE_CTRL4, BIT(4) | BIT(15)); + + /* RFSW Control - clear bit 14 ?? */ + if (priv->rtl_chip != RTL8723B && priv->rtl_chip != RTL8192E && + priv->rtl_chip != RTL8188E && priv->rtl_chip != RTL8710B && + priv->rtl_chip != RTL8192F) + rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, 0x00000003); + + val32 = FPGA0_RF_TRSW | FPGA0_RF_TRSWB | FPGA0_RF_ANTSW | + FPGA0_RF_ANTSWB | + ((FPGA0_RF_ANTSW | FPGA0_RF_ANTSWB) << FPGA0_RF_BD_CTRL_SHIFT); + if (!priv->no_pape) { + val32 |= (FPGA0_RF_PAPE | + (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT)); + } + rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32); + + /* 0x860[6:5]= 00 - why? - this sets antenna B */ + if (priv->rtl_chip != RTL8192E && priv->rtl_chip != RTL8188E && + priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192F) + rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, 0x66f60210); + + if (!macpower) { + /* + * Set TX buffer boundary + */ + val8 = fops->total_page_num + 1; + + rtl8xxxu_write8(priv, REG_TXPKTBUF_BCNQ_BDNY, val8); + rtl8xxxu_write8(priv, REG_TXPKTBUF_MGQ_BDNY, val8); + rtl8xxxu_write8(priv, REG_TXPKTBUF_WMAC_LBK_BF_HD, val8); + rtl8xxxu_write8(priv, REG_TRXFF_BNDY, val8); + rtl8xxxu_write8(priv, REG_TDECTRL + 1, val8); + } + + /* + * The vendor drivers set PBP for all devices, except 8192e. + * There is no explanation for this in any of the sources. + */ + val8 = (fops->pbp_rx << PBP_PAGE_SIZE_RX_SHIFT) | + (fops->pbp_tx << PBP_PAGE_SIZE_TX_SHIFT); + if (priv->rtl_chip != RTL8192E) + rtl8xxxu_write8(priv, REG_PBP, val8); + + dev_dbg(dev, "%s: macpower %i\n", __func__, macpower); + if (!macpower) { + ret = fops->llt_init(priv); + if (ret) { + dev_warn(dev, "%s: LLT table init failed\n", __func__); + goto exit; + } + + /* + * Chip specific quirks + */ + fops->usb_quirks(priv); + + /* + * Enable TX report and TX report timer for 8723bu/8188eu/... + */ + if (fops->has_tx_report) { + /* + * The RTL8188EU has two types of TX reports: + * rpt_sel=1: + * One report for one frame. We can use this for frames + * with IEEE80211_TX_CTL_REQ_TX_STATUS. + * rpt_sel=2: + * One report for many frames transmitted over a period + * of time. (This is what REG_TX_REPORT_TIME is for.) The + * report includes the number of frames transmitted + * successfully, and the number of unsuccessful + * transmissions. We use this for software rate control. + * + * Bit 0 of REG_TX_REPORT_CTRL is required for both types. + * Bit 1 (TX_REPORT_CTRL_TIMER_ENABLE) is required for + * type 2. + */ + val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); + if (priv->rtl_chip == RTL8188E) + val8 |= BIT(0); + val8 |= TX_REPORT_CTRL_TIMER_ENABLE; + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); + /* Set MAX RPT MACID */ + rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL + 1, 0x02); + /* TX report Timer. Unit: 32us */ + rtl8xxxu_write16(priv, REG_TX_REPORT_TIME, 0xcdf0); + + /* tmp ps ? */ + val8 = rtl8xxxu_read8(priv, 0xa3); + val8 &= 0xf8; + rtl8xxxu_write8(priv, 0xa3, val8); + } + + if (priv->rtl_chip == RTL8710B || priv->rtl_chip == RTL8192F) + rtl8xxxu_write8(priv, REG_EARLY_MODE_CONTROL_8710B, 0); + } + + /* + * Unit in 8 bytes. + * Get Rx PHY status in order to report RSSI and others. + */ + rtl8xxxu_write8(priv, REG_RX_DRVINFO_SZ, 4); + + if (priv->rtl_chip == RTL8192E) { + rtl8xxxu_write32(priv, REG_HIMR0, 0x00); + rtl8xxxu_write32(priv, REG_HIMR1, 0x00); + } else if (priv->rtl_chip == RTL8188F) { + rtl8xxxu_write32(priv, REG_HISR0, 0xffffffff); + rtl8xxxu_write32(priv, REG_HISR1, 0xffffffff); + } else if (priv->rtl_chip == RTL8188E) { + rtl8xxxu_write32(priv, REG_HISR0, 0xffffffff); + val32 = IMR0_PSTIMEOUT | IMR0_TBDER | IMR0_CPWM | IMR0_CPWM2; + rtl8xxxu_write32(priv, REG_HIMR0, val32); + val32 = IMR1_TXERR | IMR1_RXERR | IMR1_TXFOVW | IMR1_RXFOVW; + rtl8xxxu_write32(priv, REG_HIMR1, val32); + val8 = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION); + val8 |= USB_SPEC_INT_BULK_SELECT; + rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, val8); + } else if (priv->rtl_chip == RTL8710B) { + rtl8xxxu_write32(priv, REG_HIMR0_8710B, 0); + } else if (priv->rtl_chip != RTL8192F) { + /* + * Enable all interrupts - not obvious USB needs to do this + */ + rtl8xxxu_write32(priv, REG_HISR, 0xffffffff); + rtl8xxxu_write32(priv, REG_HIMR, 0xffffffff); + } + + /* + * Configure initial WMAC settings + */ + val32 = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_MCAST | RCR_ACCEPT_BCAST | + RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL | + RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC; + rtl8xxxu_write32(priv, REG_RCR, val32); + priv->regrcr = val32; + + if (fops->init_reg_rxfltmap) { + /* Accept all data frames */ + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff); + + /* + * Since ADF is removed from RCR, ps-poll will not be indicate to driver, + * RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll. + */ + rtl8xxxu_write16(priv, REG_RXFLTMAP1, 0x400); + + /* Accept all management frames */ + rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff); + } else { + /* + * Accept all multicast + */ + rtl8xxxu_write32(priv, REG_MAR, 0xffffffff); + rtl8xxxu_write32(priv, REG_MAR + 4, 0xffffffff); + } + + /* + * Init adaptive controls + */ + val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + val32 &= ~RESPONSE_RATE_BITMAP_ALL; + val32 |= RESPONSE_RATE_RRSR_CCK_ONLY_1M; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32); + + /* CCK = 0x0a, OFDM = 0x10 */ + rtl8xxxu_set_spec_sifs(priv, 0x10, 0x10); + rtl8xxxu_set_retry(priv, 0x30, 0x30); + rtl8xxxu_set_spec_sifs(priv, 0x0a, 0x10); + + /* + * Init EDCA + */ + rtl8xxxu_write16(priv, REG_MAC_SPEC_SIFS, 0x100a); + + /* Set CCK SIFS */ + rtl8xxxu_write16(priv, REG_SIFS_CCK, 0x100a); + + /* Set OFDM SIFS */ + rtl8xxxu_write16(priv, REG_SIFS_OFDM, 0x100a); + + /* TXOP */ + rtl8xxxu_write32(priv, REG_EDCA_BE_PARAM, 0x005ea42b); + rtl8xxxu_write32(priv, REG_EDCA_BK_PARAM, 0x0000a44f); + rtl8xxxu_write32(priv, REG_EDCA_VI_PARAM, 0x005ea324); + rtl8xxxu_write32(priv, REG_EDCA_VO_PARAM, 0x002fa226); + + /* Set data auto rate fallback retry count */ + rtl8xxxu_write32(priv, REG_DARFRC, 0x00000000); + rtl8xxxu_write32(priv, REG_DARFRC + 4, 0x10080404); + rtl8xxxu_write32(priv, REG_RARFRC, 0x04030201); + rtl8xxxu_write32(priv, REG_RARFRC + 4, 0x08070605); + + val8 = rtl8xxxu_read8(priv, REG_FWHW_TXQ_CTRL); + val8 |= FWHW_TXQ_CTRL_AMPDU_RETRY; + rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL, val8); + + /* Set ACK timeout */ + rtl8xxxu_write8(priv, REG_ACKTO, 0x40); + + /* + * Initialize beacon parameters + */ + val16 = BEACON_DISABLE_TSF_UPDATE | (BEACON_DISABLE_TSF_UPDATE << 8); + rtl8xxxu_write16(priv, REG_BEACON_CTRL, val16); + rtl8xxxu_write16(priv, REG_TBTT_PROHIBIT, 0x6404); + if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8710B && + priv->rtl_chip != RTL8192F) + /* Firmware will control REG_DRVERLYINT when power saving is enable, */ + /* so don't set this register on STA mode. */ + rtl8xxxu_write8(priv, REG_DRIVER_EARLY_INT, DRIVER_EARLY_INT_TIME); + rtl8xxxu_write8(priv, REG_BEACON_DMA_TIME, BEACON_DMA_ATIME_INT_TIME); + rtl8xxxu_write16(priv, REG_BEACON_TCFG, 0x660F); + + /* + * Initialize burst parameters + */ + if (priv->fops->init_burst) + priv->fops->init_burst(priv); + + if (fops->init_aggregation) + fops->init_aggregation(priv); + + if (fops->init_reg_pkt_life_time) { + rtl8xxxu_write16(priv, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ + rtl8xxxu_write16(priv, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ + } + + /* + * Enable CCK and OFDM block + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + val32 |= (FPGA_RF_MODE_CCK | FPGA_RF_MODE_OFDM); + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + + /* + * Invalidate all CAM entries - bit 30 is undocumented + */ + rtl8xxxu_write32(priv, REG_CAM_CMD, CAM_CMD_POLLING | BIT(30)); + + /* + * Start out with default power levels for channel 6, 20MHz + */ + fops->set_tx_power(priv, 1, false); + + /* Let the 8051 take control of antenna setting */ + if (priv->rtl_chip != RTL8192E && priv->rtl_chip != RTL8188F && + priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192C) { + val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); + val8 |= LEDCFG2_DPDT_SELECT; + rtl8xxxu_write8(priv, REG_LEDCFG2, val8); + } + + rtl8xxxu_write8(priv, REG_HWSEQ_CTRL, 0xff); + + /* Disable BAR - not sure if this has any effect on USB */ + rtl8xxxu_write32(priv, REG_BAR_MODE_CTRL, 0x0201ffff); + + if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8188E && + priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192F) + rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0); + + if (fops->init_statistics) + fops->init_statistics(priv); + + if (priv->rtl_chip == RTL8192E) { + /* + * 0x4c6[3] 1: RTS BW = Data BW + * 0: RTS BW depends on CCA / secondary CCA result. + */ + val8 = rtl8xxxu_read8(priv, REG_QUEUE_CTRL); + val8 &= ~BIT(3); + rtl8xxxu_write8(priv, REG_QUEUE_CTRL, val8); + /* + * Reset USB mode switch setting + */ + rtl8xxxu_write8(priv, REG_ACLK_MON, 0x00); + } else if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8188E || + priv->rtl_chip == RTL8192F) { + /* + * Init GPIO settings for 8188f, 8188e, 8192f + */ + val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); + val8 &= ~GPIO_MUXCFG_IO_SEL_ENBT; + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); + } + + if (priv->rtl_chip == RTL8188F) + /* CCK PD */ + rtl8xxxu_write8(priv, REG_CCK_PD_THRESH, CCK_PD_TYPE1_LV1_TH); + + fops->phy_lc_calibrate(priv); + + fops->phy_iq_calibrate(priv); + + /* + * This should enable thermal meter + */ + if (fops->gen2_thermal_meter) { + if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8710B) { + val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_T_METER_8723B); + val32 |= 0x30000; + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_T_METER_8723B, val32); + } else { + rtl8xxxu_write_rfreg(priv, + RF_A, RF6052_REG_T_METER_8723B, 0x37cf8); + } + } else { + rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_T_METER, 0x60); + } + + /* Set NAV_UPPER to 30000us */ + val8 = ((30000 + NAV_UPPER_UNIT - 1) / NAV_UPPER_UNIT); + rtl8xxxu_write8(priv, REG_NAV_UPPER, val8); + + if (priv->rtl_chip == RTL8723A) { + /* + * 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, + * but we need to find root cause. + * This is 8723au only. + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); + if ((val32 & 0xff000000) != 0x83000000) { + val32 |= FPGA_RF_MODE_CCK; + rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); + } + } else if (priv->rtl_chip == RTL8192E || priv->rtl_chip == RTL8188E) { + rtl8xxxu_write8(priv, REG_USB_HRPWM, 0x00); + } + + val32 = rtl8xxxu_read32(priv, REG_FWHW_TXQ_CTRL); + val32 |= FWHW_TXQ_CTRL_XMIT_MGMT_ACK; + /* ack for xmit mgmt frames. */ + rtl8xxxu_write32(priv, REG_FWHW_TXQ_CTRL, val32); + + if (priv->rtl_chip == RTL8192E) { + /* + * Fix LDPC rx hang issue. + */ + val32 = rtl8xxxu_read32(priv, REG_AFE_MISC); + rtl8xxxu_write8(priv, REG_8192E_LDOV12_CTRL, 0x75); + val32 &= 0xfff00fff; + val32 |= 0x0007e000; + rtl8xxxu_write32(priv, REG_AFE_MISC, val32); + + /* + * 0x824[9] = 0x82C[9] = 0xA80[7] those registers setting + * should be equal or CCK RSSI report may be incorrect + */ + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM2); + priv->cck_agc_report_type = + u32_get_bits(val32, FPGA0_HSSI_PARM2_CCK_HIGH_PWR); + + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_HSSI_PARM2); + if (priv->cck_agc_report_type != + u32_get_bits(val32, FPGA0_HSSI_PARM2_CCK_HIGH_PWR)) { + if (priv->cck_agc_report_type) + val32 |= FPGA0_HSSI_PARM2_CCK_HIGH_PWR; + else + val32 &= ~FPGA0_HSSI_PARM2_CCK_HIGH_PWR; + rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM2, val32); + } + + val32 = rtl8xxxu_read32(priv, REG_AGC_RPT); + if (priv->cck_agc_report_type) + val32 |= AGC_RPT_CCK; + else + val32 &= ~AGC_RPT_CCK; + rtl8xxxu_write32(priv, REG_AGC_RPT, val32); + } + + if (priv->rtl_chip == RTL8710B) { + /* + * 0x76D[5:4] is Port0,Port1 Enable Bit. + * This is only for 8710B, 2b'00 for MP and 2b'11 for Normal Driver + */ + val8 = rtl8xxxu_read8(priv, REG_PORT_CONTROL_8710B); + val8 |= BIT(5) | BIT(4); + rtl8xxxu_write8(priv, REG_PORT_CONTROL_8710B, val8); + + /* Set 0x5c[8] and [2:0] = 1, LDO mode */ + val32 = rtl8xxxu_read32(priv, REG_WL_RF_PSS_8710B); + val32 |= 0x107; + rtl8xxxu_write32(priv, REG_WL_RF_PSS_8710B, val32); + } + + val32 = rtl8xxxu_read32(priv, 0xa9c); + priv->cck_new_agc = u32_get_bits(val32, BIT(17)); + + /* Initialise the center frequency offset tracking */ + if (priv->fops->set_crystal_cap) { + val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING); + priv->cfo_tracking.atc_status = val32 & CFO_TRACKING_ATC_STATUS; + priv->cfo_tracking.adjust = true; + priv->cfo_tracking.crystal_cap = priv->default_crystal_cap; + } + + if (priv->rtl_chip == RTL8188E) + rtl8188e_ra_info_init_all(&priv->ra_info); + + set_bit(RTL8XXXU_BC_MC_MACID, priv->mac_id_map); + set_bit(RTL8XXXU_BC_MC_MACID1, priv->mac_id_map); + +exit: + return ret; +} + +static void rtl8xxxu_cam_write(struct rtl8xxxu_priv *priv, + struct ieee80211_key_conf *key, const u8 *mac) +{ + u32 cmd, val32, addr, ctrl; + int j, i, tmp_debug; + + tmp_debug = rtl8xxxu_debug; + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_KEY) + rtl8xxxu_debug |= RTL8XXXU_DEBUG_REG_WRITE; + + /* + * This is a bit of a hack - the lower bits of the cipher + * suite selector happens to match the cipher index in the CAM + */ + addr = key->hw_key_idx << CAM_CMD_KEY_SHIFT; + ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID; + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + ctrl |= BIT(6); + + for (j = 5; j >= 0; j--) { + switch (j) { + case 0: + val32 = ctrl | (mac[0] << 16) | (mac[1] << 24); + break; + case 1: + val32 = mac[2] | (mac[3] << 8) | + (mac[4] << 16) | (mac[5] << 24); + break; + default: + i = (j - 2) << 2; + val32 = key->key[i] | (key->key[i + 1] << 8) | + key->key[i + 2] << 16 | key->key[i + 3] << 24; + break; + } + + rtl8xxxu_write32(priv, REG_CAM_WRITE, val32); + cmd = CAM_CMD_POLLING | CAM_CMD_WRITE | (addr + j); + rtl8xxxu_write32(priv, REG_CAM_CMD, cmd); + udelay(100); + } + + rtl8xxxu_debug = tmp_debug; +} + +static +int rtl8xxxu_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, + u32 *rx_ant) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + *tx_ant = BIT(priv->tx_paths) - 1; + *rx_ant = BIT(priv->rx_paths) - 1; + + return 0; +} + +static int rtl8xxxu_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + schedule_delayed_work(&priv->update_beacon_work, 0); + + return 0; +} + +static void rtl8xxxu_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, const u8 *mac) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); + val8 |= BEACON_DISABLE_TSF_UPDATE; + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); +} + +static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u8 val8; + + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); + val8 &= ~BEACON_DISABLE_TSF_UPDATE; + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); +} + +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, + u8 macid) +{ + struct h2c_cmd h2c; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.ramask.cmd = H2C_SET_RATE_MASK; + h2c.ramask.mask_lo = cpu_to_le16(ramask & 0xffff); + h2c.ramask.mask_hi = cpu_to_le16(ramask >> 16); + + h2c.ramask.arg = 0x80; + if (sgi) + h2c.ramask.arg |= 0x20; + + dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x, size %zi\n", + __func__, ramask, h2c.ramask.arg, sizeof(h2c.ramask)); + rtl8xxxu_gen1_h2c_cmd(priv, &h2c, sizeof(h2c.ramask)); +} + +void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, + u8 macid) +{ + struct h2c_cmd h2c; + u8 bw; + + if (txbw_40mhz) + bw = RTL8XXXU_CHANNEL_WIDTH_40; + else + bw = RTL8XXXU_CHANNEL_WIDTH_20; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.b_macid_cfg.cmd = H2C_8723B_MACID_CFG_RAID; + h2c.b_macid_cfg.ramask0 = ramask & 0xff; + h2c.b_macid_cfg.ramask1 = (ramask >> 8) & 0xff; + h2c.b_macid_cfg.ramask2 = (ramask >> 16) & 0xff; + h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff; + h2c.b_macid_cfg.macid = macid; + + h2c.b_macid_cfg.data1 = rateid; + if (sgi) + h2c.b_macid_cfg.data1 |= BIT(7); + + h2c.b_macid_cfg.data2 = bw; + + dev_dbg(&priv->udev->dev, "%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n", + __func__, ramask, rateid, sgi, sizeof(h2c.b_macid_cfg)); + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_macid_cfg)); +} + +void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, + u8 macid, u8 role, bool connect) +{ + struct h2c_cmd h2c; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.joinbss.cmd = H2C_JOIN_BSS_REPORT; + + if (connect) + h2c.joinbss.data = H2C_JOIN_BSS_CONNECT; + else + h2c.joinbss.data = H2C_JOIN_BSS_DISCONNECT; + + rtl8xxxu_gen1_h2c_cmd(priv, &h2c, sizeof(h2c.joinbss)); +} + +void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, + u8 macid, u8 role, bool connect) +{ + /* + * The firmware turns on the rate control when it knows it's + * connected to a network. + */ + struct h2c_cmd h2c; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT; + if (connect) + h2c.media_status_rpt.parm |= BIT(0); + else + h2c.media_status_rpt.parm &= ~BIT(0); + + h2c.media_status_rpt.parm |= ((role << 4) & 0xf0); + h2c.media_status_rpt.macid = macid; + + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt)); +} + +void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi) +{ + struct h2c_cmd h2c; + const int h2c_size = 4; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.rssi_report.cmd = H2C_SET_RSSI; + h2c.rssi_report.macid = macid; + h2c.rssi_report.rssi = rssi; + + rtl8xxxu_gen1_h2c_cmd(priv, &h2c, h2c_size); +} + +void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi) +{ + struct h2c_cmd h2c; + int h2c_size = sizeof(h2c.rssi_report); + + if (priv->rtl_chip == RTL8723B) + h2c_size = 4; + + memset(&h2c, 0, sizeof(struct h2c_cmd)); + + h2c.rssi_report.cmd = H2C_8723B_RSSI_SETTING; + h2c.rssi_report.macid = macid; + h2c.rssi_report.rssi = rssi; + + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, h2c_size); +} + +void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u8 agg_ctrl, usb_spec, page_thresh, timeout; + + usb_spec = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION); + usb_spec &= ~USB_SPEC_USB_AGG_ENABLE; + rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, usb_spec); + + agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); + agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; + + if (!rtl8xxxu_dma_aggregation) { + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + return; + } + + agg_ctrl |= TRXDMA_CTRL_RXDMA_AGG_EN; + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + + /* + * The number of packets we can take looks to be buffer size / 512 + * which matches the 512 byte rounding we have to do when de-muxing + * the packets. + * + * Sample numbers from the vendor driver: + * USB High-Speed mode values: + * RxAggBlockCount = 8 : 512 byte unit + * RxAggBlockTimeout = 6 + * RxAggPageCount = 48 : 128 byte unit + * RxAggPageTimeout = 4 or 6 (absolute time 34ms/(2^6)) + */ + + page_thresh = (priv->fops->rx_agg_buf_size / 512); + if (rtl8xxxu_dma_agg_pages >= 0) { + if (rtl8xxxu_dma_agg_pages <= page_thresh) + timeout = page_thresh; + else if (rtl8xxxu_dma_agg_pages <= 6) + dev_err(&priv->udev->dev, + "%s: dma_agg_pages=%i too small, minimum is 6\n", + __func__, rtl8xxxu_dma_agg_pages); + else + dev_err(&priv->udev->dev, + "%s: dma_agg_pages=%i larger than limit %i\n", + __func__, rtl8xxxu_dma_agg_pages, page_thresh); + } + rtl8xxxu_write8(priv, REG_RXDMA_AGG_PG_TH, page_thresh); + /* + * REG_RXDMA_AGG_PG_TH + 1 seems to be the timeout register on + * gen2 chips and rtl8188eu. The rtl8723au seems unhappy if we + * don't set it, so better set both. + */ + timeout = 4; + + if (rtl8xxxu_dma_agg_timeout >= 0) { + if (rtl8xxxu_dma_agg_timeout <= 127) + timeout = rtl8xxxu_dma_agg_timeout; + else + dev_err(&priv->udev->dev, + "%s: Invalid dma_agg_timeout: %i\n", + __func__, rtl8xxxu_dma_agg_timeout); + } + + rtl8xxxu_write8(priv, REG_RXDMA_AGG_PG_TH + 1, timeout); + rtl8xxxu_write8(priv, REG_USB_DMA_AGG_TO, timeout); + priv->rx_buf_aggregation = 1; +} + +static const struct ieee80211_rate rtl8xxxu_legacy_ratetable[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg) +{ + struct ieee80211_hw *hw = priv->hw; + u32 val32; + u8 rate_idx = 0; + + rate_cfg &= RESPONSE_RATE_BITMAP_ALL; + + val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) + val32 &= RESPONSE_RATE_RRSR_INIT_5G; + else + val32 &= RESPONSE_RATE_RRSR_INIT_2G; + val32 |= rate_cfg; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32); + + dev_dbg(&priv->udev->dev, "%s: rates %08x\n", __func__, rate_cfg); + + if (rate_cfg) + rate_idx = __fls(rate_cfg); + + rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx); +} + +static u16 +rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta) +{ + u16 network_type = WIRELESS_MODE_UNKNOWN; + + if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) { + if (sta->deflink.vht_cap.vht_supported) + network_type = WIRELESS_MODE_AC; + else if (sta->deflink.ht_cap.ht_supported) + network_type = WIRELESS_MODE_N_5G; + + network_type |= WIRELESS_MODE_A; + } else { + if (sta->deflink.vht_cap.vht_supported) + network_type = WIRELESS_MODE_AC; + else if (sta->deflink.ht_cap.ht_supported) + network_type = WIRELESS_MODE_N_24G; + + if (sta->deflink.supp_rates[0] <= 0xf) + network_type |= WIRELESS_MODE_B; + else if (sta->deflink.supp_rates[0] & 0xf) + network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G); + else + network_type |= WIRELESS_MODE_G; + } + + return network_type; +} + +static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time) +{ + u32 reg_edca_param[IEEE80211_NUM_ACS] = { + [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM, + [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM, + [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM, + [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM, + }; + u32 val32; + u16 wireless_mode = 0; + u8 aifs, aifsn, sifs; + int i; + + for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) { + struct ieee80211_sta *sta; + + if (!priv->vifs[i]) + continue; + + rcu_read_lock(); + sta = ieee80211_find_sta(priv->vifs[i], priv->vifs[i]->bss_conf.bssid); + if (sta) + wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta); + rcu_read_unlock(); + + if (wireless_mode) + break; + } + + if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ || + (wireless_mode & WIRELESS_MODE_N_24G)) + sifs = 16; + else + sifs = 10; + + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + val32 = rtl8xxxu_read32(priv, reg_edca_param[i]); + + /* It was set in conf_tx. */ + aifsn = val32 & 0xff; + + /* aifsn not set yet or already fixed */ + if (aifsn < 2 || aifsn > 15) + continue; + + aifs = aifsn * slot_time + sifs; + + val32 &= ~0xff; + val32 |= aifs; + rtl8xxxu_write32(priv, reg_edca_param[i], val32); + } +} + +void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt, + u8 rate, u8 sgi, u8 bw) +{ + rarpt->txrate.flags = 0; + + if (rate <= DESC_RATE_54M) { + rarpt->txrate.legacy = rtl8xxxu_legacy_ratetable[rate].bitrate; + } else if (rate >= DESC_RATE_MCS0 && rate <= DESC_RATE_MCS15) { + rarpt->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (rate < DESC_RATE_MCS8) + rarpt->txrate.nss = 1; + else + rarpt->txrate.nss = 2; + + rarpt->txrate.mcs = rate - DESC_RATE_MCS0; + + if (sgi) + rarpt->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + + rarpt->txrate.bw = bw; + } else { + return; + } + + rarpt->bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate); + rarpt->desc_rate = rate; +} + +static void +rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, u64 changed) +{ + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + struct rtl8xxxu_sta_info *sta_info; + struct ieee80211_sta *sta; + struct rtl8xxxu_ra_report *rarpt; + u8 val8, macid; + u32 val32; + + rarpt = &priv->ra_report; + + if (changed & BSS_CHANGED_ASSOC) { + dev_dbg(dev, "Changed ASSOC: %i!\n", vif->cfg.assoc); + + rtl8xxxu_set_linktype(priv, vif->type, rtlvif->port_num); + + if (vif->cfg.assoc) { + u32 ramask; + int sgi = 0; + u8 highest_rate; + u8 bw; + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (!sta) { + dev_info(dev, "%s: ASSOC no sta found\n", + __func__); + rcu_read_unlock(); + goto error; + } + macid = rtl8xxxu_get_macid(priv, sta); + + if (sta->deflink.ht_cap.ht_supported) + dev_info(dev, "%s: HT supported\n", __func__); + if (sta->deflink.vht_cap.vht_supported) + dev_info(dev, "%s: VHT supported\n", __func__); + + /* TODO: Set bits 28-31 for rate adaptive id */ + ramask = (sta->deflink.supp_rates[0] & 0xfff) | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12 | + sta->deflink.ht_cap.mcs.rx_mask[1] << 20; + if (sta->deflink.ht_cap.cap & + (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) + sgi = 1; + + highest_rate = fls(ramask) - 1; + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + bw = RATE_INFO_BW_40; + else + bw = RATE_INFO_BW_20; + + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT; + rcu_read_unlock(); + + rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw); + + priv->fops->update_rate_mask(priv, ramask, 0, sgi, + bw == RATE_INFO_BW_40, macid); + + rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff); + + if (rtlvif->port_num == 0) + rtl8xxxu_stop_tx_beacon(priv); + + /* joinbss sequence */ + rtl8xxxu_write16(priv, REG_BCN_PSR_RPT, + 0xc000 | vif->cfg.aid); + + priv->fops->report_connect(priv, 0, H2C_MACID_ROLE_AP, true); + } else { + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); + val8 |= BEACON_DISABLE_TSF_UPDATE; + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); + + priv->fops->report_connect(priv, 0, H2C_MACID_ROLE_AP, false); + } + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + dev_dbg(dev, "Changed ERP_PREAMBLE: Use short preamble %i\n", + bss_conf->use_short_preamble); + val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET); + if (bss_conf->use_short_preamble) + val32 |= RSR_ACK_SHORT_PREAMBLE; + else + val32 &= ~RSR_ACK_SHORT_PREAMBLE; + rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + dev_dbg(dev, "Changed ERP_SLOT: short_slot_time %i\n", + bss_conf->use_short_slot); + + if (bss_conf->use_short_slot) + val8 = 9; + else + val8 = 20; + rtl8xxxu_write8(priv, REG_SLOT, val8); + + rtl8xxxu_set_aifs(priv, val8); + } + + if (changed & BSS_CHANGED_BSSID) { + dev_dbg(dev, "Changed BSSID!\n"); + rtl8xxxu_set_bssid(priv, bss_conf->bssid, rtlvif->port_num); + } + + if (changed & BSS_CHANGED_BASIC_RATES) { + dev_dbg(dev, "Changed BASIC_RATES!\n"); + rtl8xxxu_set_basic_rates(priv, bss_conf->basic_rates); + } + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + if (bss_conf->enable_beacon) { + rtl8xxxu_start_tx_beacon(priv); + schedule_delayed_work(&priv->update_beacon_work, 0); + } else { + rtl8xxxu_stop_tx_beacon(priv); + } + } + + if (changed & BSS_CHANGED_BEACON) + schedule_delayed_work(&priv->update_beacon_work, 0); + +error: + return; +} + +static int rtl8xxxu_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + + dev_dbg(dev, "Start AP mode\n"); + rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, rtlvif->port_num); + rtl8xxxu_write16(priv, REG_BCN_INTERVAL, vif->bss_conf.beacon_int); + priv->fops->report_connect(priv, RTL8XXXU_BC_MC_MACID, 0, true); + + return 0; +} + +static u32 rtl8xxxu_80211_to_rtl_queue(u32 queue) +{ + u32 rtlqueue; + + switch (queue) { + case IEEE80211_AC_VO: + rtlqueue = TXDESC_QUEUE_VO; + break; + case IEEE80211_AC_VI: + rtlqueue = TXDESC_QUEUE_VI; + break; + case IEEE80211_AC_BE: + rtlqueue = TXDESC_QUEUE_BE; + break; + case IEEE80211_AC_BK: + rtlqueue = TXDESC_QUEUE_BK; + break; + default: + rtlqueue = TXDESC_QUEUE_BE; + } + + return rtlqueue; +} + +static u32 rtl8xxxu_queue_select(struct ieee80211_hdr *hdr, struct sk_buff *skb) +{ + u32 queue; + + if (unlikely(ieee80211_is_beacon(hdr->frame_control))) + queue = TXDESC_QUEUE_BEACON; + else if (ieee80211_is_mgmt(hdr->frame_control)) + queue = TXDESC_QUEUE_MGNT; + else + queue = rtl8xxxu_80211_to_rtl_queue(skb_get_queue_mapping(skb)); + + return queue; +} + +/* + * Despite newer chips 8723b/8812/8821 having a larger TX descriptor + * format. The descriptor checksum is still only calculated over the + * initial 32 bytes of the descriptor! + */ +static void rtl8xxxu_calc_tx_desc_csum(struct rtl8xxxu_txdesc32 *tx_desc) +{ + __le16 *ptr = (__le16 *)tx_desc; + u16 csum = 0; + int i; + + /* + * Clear csum field before calculation, as the csum field is + * in the middle of the struct. + */ + tx_desc->csum = cpu_to_le16(0); + + for (i = 0; i < (sizeof(struct rtl8xxxu_txdesc32) / sizeof(u16)); i++) + csum = csum ^ le16_to_cpu(ptr[i]); + + tx_desc->csum |= cpu_to_le16(csum); +} + +static void rtl8xxxu_free_tx_resources(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_tx_urb *tx_urb, *tmp; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_urb_lock, flags); + list_for_each_entry_safe(tx_urb, tmp, &priv->tx_urb_free_list, list) { + list_del(&tx_urb->list); + priv->tx_urb_free_count--; + usb_free_urb(&tx_urb->urb); + } + spin_unlock_irqrestore(&priv->tx_urb_lock, flags); +} + +static struct rtl8xxxu_tx_urb * +rtl8xxxu_alloc_tx_urb(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_tx_urb *tx_urb; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_urb_lock, flags); + tx_urb = list_first_entry_or_null(&priv->tx_urb_free_list, + struct rtl8xxxu_tx_urb, list); + if (tx_urb) { + list_del(&tx_urb->list); + priv->tx_urb_free_count--; + if (priv->tx_urb_free_count < RTL8XXXU_TX_URB_LOW_WATER && + !priv->tx_stopped) { + priv->tx_stopped = true; + ieee80211_stop_queues(priv->hw); + } + } + + spin_unlock_irqrestore(&priv->tx_urb_lock, flags); + + return tx_urb; +} + +static void rtl8xxxu_free_tx_urb(struct rtl8xxxu_priv *priv, + struct rtl8xxxu_tx_urb *tx_urb) +{ + unsigned long flags; + + INIT_LIST_HEAD(&tx_urb->list); + + spin_lock_irqsave(&priv->tx_urb_lock, flags); + + list_add(&tx_urb->list, &priv->tx_urb_free_list); + priv->tx_urb_free_count++; + if (priv->tx_urb_free_count > RTL8XXXU_TX_URB_HIGH_WATER && + priv->tx_stopped) { + priv->tx_stopped = false; + ieee80211_wake_queues(priv->hw); + } + + spin_unlock_irqrestore(&priv->tx_urb_lock, flags); +} + +static void rtl8xxxu_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct ieee80211_tx_info *tx_info; + struct ieee80211_hw *hw; + struct rtl8xxxu_priv *priv; + struct rtl8xxxu_tx_urb *tx_urb = + container_of(urb, struct rtl8xxxu_tx_urb, urb); + + tx_info = IEEE80211_SKB_CB(skb); + hw = tx_info->rate_driver_data[0]; + priv = hw->priv; + + skb_pull(skb, priv->fops->tx_desc_size); + + ieee80211_tx_info_clear_status(tx_info); + tx_info->status.rates[0].idx = -1; + tx_info->status.rates[0].count = 0; + + if (!urb->status) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(hw, skb); + + rtl8xxxu_free_tx_urb(priv, tx_urb); +} + +static void rtl8xxxu_dump_action(struct device *dev, + struct ieee80211_hdr *hdr, unsigned int skb_len) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)hdr; + u16 cap, timeout; + + if (!(rtl8xxxu_debug & RTL8XXXU_DEBUG_ACTION)) + return; + + if (skb_len < IEEE80211_MIN_ACTION_SIZE(action_code)) + return; + + switch (mgmt->u.action.action_code) { + case WLAN_ACTION_ADDBA_RESP: + if (skb_len < IEEE80211_MIN_ACTION_SIZE(addba_resp)) + break; + + cap = le16_to_cpu(mgmt->u.action.addba_resp.capab); + timeout = le16_to_cpu(mgmt->u.action.addba_resp.timeout); + dev_info(dev, "WLAN_ACTION_ADDBA_RESP: " + "timeout %i, tid %02x, buf_size %02x, policy %02x, " + "status %02x\n", + timeout, + (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2, + (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6, + (cap >> 1) & 0x1, + le16_to_cpu(mgmt->u.action.addba_resp.status)); + break; + case WLAN_ACTION_ADDBA_REQ: + if (skb_len < IEEE80211_MIN_ACTION_SIZE(addba_req)) + break; + + cap = le16_to_cpu(mgmt->u.action.addba_req.capab); + timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout); + dev_info(dev, "WLAN_ACTION_ADDBA_REQ: " + "timeout %i, tid %02x, buf_size %02x, policy %02x\n", + timeout, + (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2, + (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6, + (cap >> 1) & 0x1); + break; + default: + dev_info(dev, "action frame %02x\n", + mgmt->u.action.action_code); + break; + } +} + +/* + * Fill in v1 (gen1) specific TX descriptor bits. + * This format is used on 8188cu/8192cu/8723au + */ +void +rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, + bool short_preamble, bool ampdu_enable, u32 rts_rate, + u8 macid) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u32 rate = 0; + u16 seq_number; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) + dev_info(dev, "%s: TX rate: %d, pkt size %u\n", + __func__, rate, le16_to_cpu(tx_desc->pkt_size)); + + seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + + tx_desc->txdw5 = cpu_to_le32(rate); + + if (ieee80211_is_data(hdr->frame_control)) + tx_desc->txdw5 |= cpu_to_le32(0x0001ff00); + + tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC32_SEQ_SHIFT); + + if (ampdu_enable && test_bit(tid, priv->tid_tx_operational)) + tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_ENABLE); + else + tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_BREAK); + + if (ieee80211_is_mgmt(hdr->frame_control)) { + tx_desc->txdw5 = cpu_to_le32(rate); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_USE_DRIVER_RATE); + tx_desc->txdw5 |= cpu_to_le32(6 << TXDESC32_RETRY_LIMIT_SHIFT); + tx_desc->txdw5 |= cpu_to_le32(TXDESC32_RETRY_LIMIT_ENABLE); + } + + if (ieee80211_is_data_qos(hdr->frame_control)) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_QOS); + + if (conf_is_ht40(&hw->conf)) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC_DATA_BW); + + if (conf_is_ht40_minus(&hw->conf)) + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_UPPER); + else + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_LOWER); + } + } + + if (short_preamble) + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_SHORT_PREAMBLE); + + if (sgi) + tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI); + + /* + * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled + */ + tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT); + if (ampdu_enable || tx_info->control.use_rts) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); + } else if (tx_info->control.use_cts_prot) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); + } +} + +/* + * Fill in v2 (gen2) specific TX descriptor bits. + * This format is used on 8192eu/8723bu + */ +void +rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, + bool short_preamble, bool ampdu_enable, u32 rts_rate, + u8 macid) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + struct rtl8xxxu_txdesc40 *tx_desc40; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u32 rate = 0; + u16 seq_number; + + tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) + dev_info(dev, "%s: TX rate: %d, pkt size %u\n", + __func__, rate, le16_to_cpu(tx_desc40->pkt_size)); + + tx_desc40->txdw1 |= cpu_to_le32(macid << TXDESC40_MACID_SHIFT); + + seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + + tx_desc40->txdw4 = cpu_to_le32(rate); + if (ieee80211_is_data(hdr->frame_control)) { + tx_desc40->txdw4 |= cpu_to_le32(0x1f << + TXDESC40_DATA_RATE_FB_SHIFT); + } + + tx_desc40->txdw9 = cpu_to_le32((u32)seq_number << TXDESC40_SEQ_SHIFT); + + if (ampdu_enable && test_bit(tid, priv->tid_tx_operational)) + tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_ENABLE); + else + tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_BREAK); + + if (ieee80211_is_mgmt(hdr->frame_control)) { + tx_desc40->txdw4 = cpu_to_le32(rate); + tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_USE_DRIVER_RATE); + tx_desc40->txdw4 |= + cpu_to_le32(6 << TXDESC40_RETRY_LIMIT_SHIFT); + tx_desc40->txdw4 |= cpu_to_le32(TXDESC40_RETRY_LIMIT_ENABLE); + } + + if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) + tx_desc40->txdw8 |= cpu_to_le32(TXDESC40_HW_SEQ_ENABLE); + + if (short_preamble) + tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE); + + tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT); + + /* + * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled + */ + if (ampdu_enable || tx_info->control.use_rts) { + tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE); + tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE); + } else if (tx_info->control.use_cts_prot) { + /* + * For some reason the vendor driver doesn't set + * TXDESC40_HW_RTS_ENABLE for CTS to SELF + */ + tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_CTS_SELF_ENABLE); + } +} + +/* + * Fill in v3 (gen1) specific TX descriptor bits. + * This format is a hybrid between the v1 and v2 formats, only seen + * on 8188eu devices so far. + */ +void +rtl8xxxu_fill_txdesc_v3(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, + bool short_preamble, bool ampdu_enable, u32 rts_rate, + u8 macid) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + struct rtl8xxxu_ra_info *ra = &priv->ra_info; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u32 rate = 0; + u16 seq_number; + + seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + + if (ieee80211_is_data(hdr->frame_control)) { + rate = ra->decision_rate; + tx_desc->txdw5 = cpu_to_le32(rate); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_USE_DRIVER_RATE); + tx_desc->txdw4 |= le32_encode_bits(ra->pt_stage, TXDESC32_PT_STAGE_MASK); + /* Data/RTS rate FB limit */ + tx_desc->txdw5 |= cpu_to_le32(0x0001ff00); + } + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) + dev_info(dev, "%s: TX rate: %d, pkt size %d\n", + __func__, rate, le16_to_cpu(tx_desc->pkt_size)); + + tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC32_SEQ_SHIFT); + + if (ampdu_enable && test_bit(tid, priv->tid_tx_operational)) + tx_desc->txdw2 |= cpu_to_le32(TXDESC40_AGG_ENABLE); + else + tx_desc->txdw2 |= cpu_to_le32(TXDESC40_AGG_BREAK); + + if (ieee80211_is_mgmt(hdr->frame_control)) { + tx_desc->txdw5 = cpu_to_le32(rate); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_USE_DRIVER_RATE); + tx_desc->txdw5 |= cpu_to_le32(6 << TXDESC32_RETRY_LIMIT_SHIFT); + tx_desc->txdw5 |= cpu_to_le32(TXDESC32_RETRY_LIMIT_ENABLE); + } + + if (ieee80211_is_data_qos(hdr->frame_control)) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_QOS); + + if (conf_is_ht40(&hw->conf)) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC_DATA_BW); + + if (conf_is_ht40_minus(&hw->conf)) + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_UPPER); + else + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_LOWER); + } + } + + if (short_preamble) + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_SHORT_PREAMBLE); + + if (sgi && ra->rate_sgi) + tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI); + + /* + * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled + */ + tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT); + if (ampdu_enable || tx_info->control.use_rts) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); + } else if (tx_info->control.use_cts_prot) { + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE); + tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); + } + + tx_desc->txdw2 |= cpu_to_le32(TXDESC_ANTENNA_SELECT_A | + TXDESC_ANTENNA_SELECT_B); + tx_desc->txdw7 |= cpu_to_le16(TXDESC_ANTENNA_SELECT_C >> 16); +} + +static void rtl8xxxu_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct rtl8xxxu_priv *priv = hw->priv; + struct rtl8xxxu_txdesc32 *tx_desc; + struct rtl8xxxu_tx_urb *tx_urb; + struct ieee80211_sta *sta = NULL; + struct ieee80211_vif *vif = tx_info->control.vif; + struct rtl8xxxu_vif *rtlvif = vif ? (struct rtl8xxxu_vif *)vif->drv_priv : NULL; + struct device *dev = &priv->udev->dev; + u32 queue, rts_rate; + u16 pktlen = skb->len; + int tx_desc_size = priv->fops->tx_desc_size; + u8 macid; + int ret; + bool ampdu_enable, sgi = false, short_preamble = false, bmc = false; + + if (skb_headroom(skb) < tx_desc_size) { + dev_warn(dev, + "%s: Not enough headroom (%i) for tx descriptor\n", + __func__, skb_headroom(skb)); + goto error; + } + + if (unlikely(skb->len > (65535 - tx_desc_size))) { + dev_warn(dev, "%s: Trying to send over-sized skb (%i)\n", + __func__, skb->len); + goto error; + } + + tx_urb = rtl8xxxu_alloc_tx_urb(priv); + if (!tx_urb) { + dev_warn(dev, "%s: Unable to allocate tx urb\n", __func__); + goto error; + } + + if (ieee80211_is_action(hdr->frame_control)) + rtl8xxxu_dump_action(dev, hdr, skb->len); + + tx_info->rate_driver_data[0] = hw; + + if (control && control->sta) + sta = control->sta; + + queue = rtl8xxxu_queue_select(hdr, skb); + + tx_desc = skb_push(skb, tx_desc_size); + + memset(tx_desc, 0, tx_desc_size); + tx_desc->pkt_size = cpu_to_le16(pktlen); + tx_desc->pkt_offset = tx_desc_size; + + /* These bits mean different things to the RTL8192F. */ + if (priv->rtl_chip != RTL8192F) + tx_desc->txdw0 = + TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT; + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + tx_desc->txdw0 |= TXDESC_BROADMULTICAST; + bmc = true; + } + + + tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT); + macid = rtl8xxxu_get_macid(priv, sta); + + if (tx_info->control.hw_key) { + switch (tx_info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + tx_desc->txdw1 |= cpu_to_le32(TXDESC_SEC_RC4); + break; + case WLAN_CIPHER_SUITE_CCMP: + tx_desc->txdw1 |= cpu_to_le32(TXDESC_SEC_AES); + break; + default: + break; + } + if (bmc && rtlvif && rtlvif->hw_key_idx != 0xff) { + tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID); + macid = rtlvif->hw_key_idx; + } + } + + /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */ + ampdu_enable = false; + if (ieee80211_is_data_qos(hdr->frame_control) && sta) { + if (sta->deflink.ht_cap.ht_supported) { + u32 ampdu, val32; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + + ampdu = (u32)sta->deflink.ht_cap.ampdu_density; + val32 = ampdu << TXDESC_AMPDU_DENSITY_SHIFT; + tx_desc->txdw2 |= cpu_to_le32(val32); + + ampdu_enable = true; + + if (!test_bit(tid, priv->tx_aggr_started) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) + if (!ieee80211_start_tx_ba_session(sta, tid, 0)) + set_bit(tid, priv->tx_aggr_started); + } + } + + if (ieee80211_is_data_qos(hdr->frame_control) && + sta && sta->deflink.ht_cap.cap & + (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) + sgi = true; + + if (sta && vif && vif->bss_conf.use_short_preamble) + short_preamble = true; + + if (skb->len > hw->wiphy->rts_threshold) + tx_info->control.use_rts = true; + + if (sta && vif && vif->bss_conf.use_cts_prot) + tx_info->control.use_cts_prot = true; + + if (ampdu_enable || tx_info->control.use_rts || + tx_info->control.use_cts_prot) + rts_rate = DESC_RATE_24M; + else + rts_rate = 0; + + priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble, + ampdu_enable, rts_rate, macid); + + rtl8xxxu_calc_tx_desc_csum(tx_desc); + + /* avoid zero checksum make tx hang */ + if (priv->rtl_chip == RTL8710B || priv->rtl_chip == RTL8192F) + tx_desc->csum = ~tx_desc->csum; + + usb_fill_bulk_urb(&tx_urb->urb, priv->udev, priv->pipe_out[queue], + skb->data, skb->len, rtl8xxxu_tx_complete, skb); + + usb_anchor_urb(&tx_urb->urb, &priv->tx_anchor); + ret = usb_submit_urb(&tx_urb->urb, GFP_ATOMIC); + if (ret) { + usb_unanchor_urb(&tx_urb->urb); + rtl8xxxu_free_tx_urb(priv, tx_urb); + goto error; + } + return; +error: + dev_kfree_skb(skb); +} + +static void rtl8xxxu_send_beacon_frame(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif, 0); + struct device *dev = &priv->udev->dev; + int retry; + u8 val8; + + /* BCN_VALID, write 1 to clear, cleared by SW */ + val8 = rtl8xxxu_read8(priv, REG_TDECTRL + 2); + val8 |= BIT_BCN_VALID >> 16; + rtl8xxxu_write8(priv, REG_TDECTRL + 2, val8); + + /* SW_BCN_SEL - Port0 */ + val8 = rtl8xxxu_read8(priv, REG_DWBCN1_CTRL_8723B + 2); + val8 &= ~(BIT_SW_BCN_SEL >> 16); + rtl8xxxu_write8(priv, REG_DWBCN1_CTRL_8723B + 2, val8); + + if (skb) + rtl8xxxu_tx(hw, NULL, skb); + + retry = 100; + do { + val8 = rtl8xxxu_read8(priv, REG_TDECTRL + 2); + if (val8 & (BIT_BCN_VALID >> 16)) + break; + usleep_range(10, 20); + } while (--retry); + + if (!retry) + dev_err(dev, "%s: Failed to read beacon valid bit\n", __func__); +} + +static void rtl8xxxu_update_beacon_work_callback(struct work_struct *work) +{ + struct rtl8xxxu_priv *priv = + container_of(work, struct rtl8xxxu_priv, update_beacon_work.work); + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_vif *vif = priv->vifs[0]; + + if (!vif) { + WARN_ONCE(true, "no vif to update beacon\n"); + return; + } + + if (vif->bss_conf.csa_active) { + if (ieee80211_beacon_cntdwn_is_complete(vif, 0)) { + ieee80211_csa_finish(vif, 0); + return; + } + schedule_delayed_work(&priv->update_beacon_work, + msecs_to_jiffies(vif->bss_conf.beacon_int)); + } + rtl8xxxu_send_beacon_frame(hw, vif); +} + +static inline bool rtl8xxxu_is_packet_match_bssid(struct rtl8xxxu_priv *priv, + struct ieee80211_hdr *hdr, + int port_num) +{ + return priv->vifs[port_num] && + priv->vifs[port_num]->type == NL80211_IFTYPE_STATION && + priv->vifs[port_num]->cfg.assoc && + ether_addr_equal(priv->vifs[port_num]->bss_conf.bssid, hdr->addr2); +} + +static inline bool rtl8xxxu_is_sta_sta(struct rtl8xxxu_priv *priv) +{ + return (priv->vifs[0] && priv->vifs[0]->cfg.assoc && + priv->vifs[0]->type == NL80211_IFTYPE_STATION) && + (priv->vifs[1] && priv->vifs[1]->cfg.assoc && + priv->vifs[1]->type == NL80211_IFTYPE_STATION); +} + +void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err) +{ + if (phy_stats->sgi_en) + rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + if (rxmcs < DESC_RATE_6M) { + /* + * Handle PHY stats for CCK rates + */ + rx_status->signal = priv->fops->cck_rssi(priv, phy_stats); + } else { + bool parse_cfo = priv->fops->set_crystal_cap && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && + !rtl8xxxu_is_sta_sta(priv) && + (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || + rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + + if (parse_cfo) { + priv->cfo_tracking.cfo_tail[0] = phy_stats->path_cfotail[0]; + priv->cfo_tracking.cfo_tail[1] = phy_stats->path_cfotail[1]; + + priv->cfo_tracking.packet_count++; + } + + rx_status->signal = + (phy_stats->cck_sig_qual_ofdm_pwdb_all >> 1) - 110; + } +} + +static void jaguar2_rx_parse_phystats_type0(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct jaguar2_phy_stats_type0 *phy_stats0, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err) +{ + s8 rx_power = phy_stats0->pwdb - 110; + + if (!priv->cck_new_agc) + rx_power = priv->fops->cck_rssi(priv, (struct rtl8723au_phy_stats *)phy_stats0); + + rx_status->signal = rx_power; +} + +static void jaguar2_rx_parse_phystats_type1(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct jaguar2_phy_stats_type1 *phy_stats1, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err) +{ + bool parse_cfo = priv->fops->set_crystal_cap && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && + !rtl8xxxu_is_sta_sta(priv) && + (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || + rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + u8 pwdb_max = 0, rxsc; + int rx_path; + + if (parse_cfo) { + /* Only path-A and path-B have CFO tail and short CFO */ + priv->cfo_tracking.cfo_tail[RF_A] = phy_stats1->cfo_tail[RF_A]; + priv->cfo_tracking.cfo_tail[RF_B] = phy_stats1->cfo_tail[RF_B]; + + priv->cfo_tracking.packet_count++; + } + + for (rx_path = 0; rx_path < priv->rx_paths; rx_path++) + pwdb_max = max(pwdb_max, phy_stats1->pwdb[rx_path]); + + rx_status->signal = pwdb_max - 110; + + if (rxmcs >= DESC_RATE_6M && rxmcs <= DESC_RATE_54M) + rxsc = phy_stats1->l_rxsc; + else + rxsc = phy_stats1->ht_rxsc; + + if (phy_stats1->rf_mode == 0 || rxsc == 1 || rxsc == 2) + rx_status->bw = RATE_INFO_BW_20; + else + rx_status->bw = RATE_INFO_BW_40; +} + +static void jaguar2_rx_parse_phystats_type2(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct jaguar2_phy_stats_type2 *phy_stats2, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err) +{ + u8 pwdb_max = 0; + int rx_path; + + for (rx_path = 0; rx_path < priv->rx_paths; rx_path++) + pwdb_max = max(pwdb_max, phy_stats2->pwdb[rx_path]); + + rx_status->signal = pwdb_max - 110; +} + +void jaguar2_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err) +{ + struct jaguar2_phy_stats_type0 *phy_stats0 = (struct jaguar2_phy_stats_type0 *)phy_stats; + struct jaguar2_phy_stats_type1 *phy_stats1 = (struct jaguar2_phy_stats_type1 *)phy_stats; + struct jaguar2_phy_stats_type2 *phy_stats2 = (struct jaguar2_phy_stats_type2 *)phy_stats; + + switch (phy_stats0->page_num) { + case 0: + /* CCK */ + jaguar2_rx_parse_phystats_type0(priv, rx_status, phy_stats0, + rxmcs, hdr, crc_icv_err); + break; + case 1: + /* OFDM */ + jaguar2_rx_parse_phystats_type1(priv, rx_status, phy_stats1, + rxmcs, hdr, crc_icv_err); + break; + case 2: + /* Also OFDM but different (how?) */ + jaguar2_rx_parse_phystats_type2(priv, rx_status, phy_stats2, + rxmcs, hdr, crc_icv_err); + break; + default: + return; + } +} + +static void rtl8xxxu_free_rx_resources(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_rx_urb *rx_urb, *tmp; + unsigned long flags; + + spin_lock_irqsave(&priv->rx_urb_lock, flags); + + list_for_each_entry_safe(rx_urb, tmp, + &priv->rx_urb_pending_list, list) { + list_del(&rx_urb->list); + priv->rx_urb_pending_count--; + usb_free_urb(&rx_urb->urb); + } + + spin_unlock_irqrestore(&priv->rx_urb_lock, flags); +} + +static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv, + struct rtl8xxxu_rx_urb *rx_urb) +{ + struct sk_buff *skb; + unsigned long flags; + + spin_lock_irqsave(&priv->rx_urb_lock, flags); + + if (!priv->shutdown) { + list_add_tail(&rx_urb->list, &priv->rx_urb_pending_list); + priv->rx_urb_pending_count++; + /* + * Arm the worker under rx_urb_lock so this is atomic with the + * shutdown check: moving it out of the lock would let a + * completion arm the work after rtl8xxxu_stop() canceled it. + */ + if (priv->rx_urb_pending_count > RTL8XXXU_RX_URB_PENDING_WATER) + schedule_work(&priv->rx_urb_wq); + } else { + skb = (struct sk_buff *)rx_urb->urb.context; + dev_kfree_skb_irq(skb); + usb_free_urb(&rx_urb->urb); + } + + spin_unlock_irqrestore(&priv->rx_urb_lock, flags); +} + +static void rtl8xxxu_rx_urb_work(struct work_struct *work) +{ + struct rtl8xxxu_priv *priv; + struct rtl8xxxu_rx_urb *rx_urb, *tmp; + struct list_head local; + struct sk_buff *skb; + unsigned long flags; + int ret; + + priv = container_of(work, struct rtl8xxxu_priv, rx_urb_wq); + INIT_LIST_HEAD(&local); + + spin_lock_irqsave(&priv->rx_urb_lock, flags); + + list_splice_init(&priv->rx_urb_pending_list, &local); + priv->rx_urb_pending_count = 0; + + spin_unlock_irqrestore(&priv->rx_urb_lock, flags); + + list_for_each_entry_safe(rx_urb, tmp, &local, list) { + list_del_init(&rx_urb->list); + ret = rtl8xxxu_submit_rx_urb(priv, rx_urb); + /* + * If out of memory or temporary error, put it back on the + * queue and try again. Otherwise the device is dead/gone + * and we should drop it. + */ + switch (ret) { + case 0: + break; + case -ENOMEM: + case -EAGAIN: + rtl8xxxu_queue_rx_urb(priv, rx_urb); + break; + default: + dev_warn(&priv->udev->dev, + "failed to requeue urb with error %i\n", ret); + skb = (struct sk_buff *)rx_urb->urb.context; + dev_kfree_skb(skb); + usb_free_urb(&rx_urb->urb); + } + } +} + +/* + * The RTL8723BU/RTL8192EU vendor driver use coexistence table type + * 0-7 to represent writing different combinations of register values + * to REG_BT_COEX_TABLEs. It's for different kinds of coexistence use + * cases which Realtek doesn't provide detail for these settings. Keep + * this aligned with vendor driver for easier maintenance. + */ +static +void rtl8723bu_set_coex_with_type(struct rtl8xxxu_priv *priv, u8 type) +{ + switch (type) { + case 0: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 1: + case 3: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 2: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 4: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaa5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 5: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaa5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 6: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 7: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + default: + break; + } +} + +static +void rtl8723bu_update_bt_link_info(struct rtl8xxxu_priv *priv, u8 bt_info) +{ + struct rtl8xxxu_btcoex *btcoex = &priv->bt_coex; + + if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) + btcoex->c2h_bt_inquiry = true; + else + btcoex->c2h_bt_inquiry = false; + + if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { + btcoex->bt_status = BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE; + btcoex->has_sco = false; + btcoex->has_hid = false; + btcoex->has_pan = false; + btcoex->has_a2dp = false; + } else { + if ((bt_info & 0x1f) == BT_INFO_8723B_1ANT_B_CONNECTION) + btcoex->bt_status = BT_8723B_1ANT_STATUS_CONNECTED_IDLE; + else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) + btcoex->bt_status = BT_8723B_1ANT_STATUS_SCO_BUSY; + else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) + btcoex->bt_status = BT_8723B_1ANT_STATUS_ACL_BUSY; + else + btcoex->bt_status = BT_8723B_1ANT_STATUS_MAX; + + if (bt_info & BT_INFO_8723B_1ANT_B_FTP) + btcoex->has_pan = true; + else + btcoex->has_pan = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) + btcoex->has_a2dp = true; + else + btcoex->has_a2dp = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_HID) + btcoex->has_hid = true; + else + btcoex->has_hid = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) + btcoex->has_sco = true; + else + btcoex->has_sco = false; + } + + if (!btcoex->has_a2dp && !btcoex->has_sco && + !btcoex->has_pan && btcoex->has_hid) + btcoex->hid_only = true; + else + btcoex->hid_only = false; + + if (!btcoex->has_sco && !btcoex->has_pan && + !btcoex->has_hid && btcoex->has_a2dp) + btcoex->has_a2dp = true; + else + btcoex->has_a2dp = false; + + if (btcoex->bt_status == BT_8723B_1ANT_STATUS_SCO_BUSY || + btcoex->bt_status == BT_8723B_1ANT_STATUS_ACL_BUSY) + btcoex->bt_busy = true; + else + btcoex->bt_busy = false; +} + +static inline bool rtl8xxxu_is_assoc(struct rtl8xxxu_priv *priv) +{ + return (priv->vifs[0] && priv->vifs[0]->cfg.assoc) || + (priv->vifs[1] && priv->vifs[1]->cfg.assoc); +} + +static +void rtl8723bu_handle_bt_inquiry(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_btcoex *btcoex; + + btcoex = &priv->bt_coex; + + if (!rtl8xxxu_is_assoc(priv)) { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 0); + } else if (btcoex->has_sco || btcoex->has_hid || btcoex->has_a2dp) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else if (btcoex->has_pan) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x3f, 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 7); + } +} + +static +void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_btcoex *btcoex; + + btcoex = &priv->bt_coex; + + if (rtl8xxxu_is_assoc(priv)) { + u32 val32 = 0; + u32 high_prio_tx = 0, high_prio_rx = 0; + + val32 = rtl8xxxu_read32(priv, 0x770); + high_prio_tx = val32 & 0x0000ffff; + high_prio_rx = (val32 & 0xffff0000) >> 16; + + if (btcoex->bt_busy) { + if (btcoex->hid_only) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x20, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 5); + } else if (btcoex->a2dp_only) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else if ((btcoex->has_a2dp && btcoex->has_pan) || + (btcoex->has_hid && btcoex->has_a2dp && + btcoex->has_pan)) { + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, + 0x3, 0x10, 0x10); + rtl8723bu_set_coex_with_type(priv, 4); + } else if (btcoex->has_hid && btcoex->has_a2dp) { + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, + 0x3, 0x10, 0x10); + rtl8723bu_set_coex_with_type(priv, 3); + } else { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + if (high_prio_tx + high_prio_rx <= 60) + rtl8723bu_set_coex_with_type(priv, 2); + else + rtl8723bu_set_coex_with_type(priv, 7); + } + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 0); + } +} + +static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) +{ + struct rtl8xxxu_priv *priv; + struct rtl8723bu_c2h *c2h; + struct sk_buff *skb = NULL; + u8 bt_info = 0; + struct rtl8xxxu_btcoex *btcoex; + struct rtl8xxxu_ra_report *rarpt; + u8 bw; + + priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work); + btcoex = &priv->bt_coex; + rarpt = &priv->ra_report; + + while (!skb_queue_empty(&priv->c2hcmd_queue)) { + skb = skb_dequeue(&priv->c2hcmd_queue); + + c2h = (struct rtl8723bu_c2h *)skb->data; + + switch (c2h->id) { + case C2H_8723B_BT_INFO: + bt_info = c2h->bt_info.bt_info; + + rtl8723bu_update_bt_link_info(priv, bt_info); + if (btcoex->c2h_bt_inquiry) { + rtl8723bu_handle_bt_inquiry(priv); + break; + } + rtl8723bu_handle_bt_info(priv); + break; + case C2H_8723B_RA_REPORT: + bw = rarpt->txrate.bw; + + if (skb->len >= offsetofend(typeof(*c2h), ra_report.bw)) { + if (c2h->ra_report.bw == RTL8XXXU_CHANNEL_WIDTH_40) + bw = RATE_INFO_BW_40; + else + bw = RATE_INFO_BW_20; + } + + rtl8xxxu_update_ra_report(rarpt, c2h->ra_report.rate, + c2h->ra_report.sgi, bw); + break; + default: + break; + } + + dev_kfree_skb(skb); + } +} + +static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, + struct sk_buff *skb) +{ + struct rtl8723bu_c2h *c2h = (struct rtl8723bu_c2h *)skb->data; + struct device *dev = &priv->udev->dev; + int len; + + len = skb->len - 2; + + dev_dbg(dev, "C2H ID %02x seq %02x, len %02x source %02x\n", + c2h->id, c2h->seq, len, c2h->bt_info.response_source); + + switch(c2h->id) { + case C2H_8723B_BT_INFO: + if (c2h->bt_info.response_source > + BT_INFO_SRC_8723B_BT_ACTIVE_SEND) + dev_dbg(dev, "C2H_BT_INFO WiFi only firmware\n"); + else + dev_dbg(dev, "C2H_BT_INFO BT/WiFi coexist firmware\n"); + + if (c2h->bt_info.bt_has_reset) + dev_dbg(dev, "BT has been reset\n"); + if (c2h->bt_info.tx_rx_mask) + dev_dbg(dev, "BT TRx mask\n"); + + break; + case C2H_8723B_BT_MP_INFO: + dev_dbg(dev, "C2H_MP_INFO ext ID %02x, status %02x\n", + c2h->bt_mp_info.ext_id, c2h->bt_mp_info.status); + break; + case C2H_8723B_RA_REPORT: + dev_dbg(dev, + "C2H RA RPT: rate %02x, unk %i, macid %02x, noise %i\n", + c2h->ra_report.rate, c2h->ra_report.sgi, + c2h->ra_report.macid, c2h->ra_report.noisy_state); + break; + default: + dev_info(dev, "Unhandled C2H event %02x seq %02x\n", + c2h->id, c2h->seq); + print_hex_dump(KERN_INFO, "C2H content: ", DUMP_PREFIX_NONE, + 16, 1, c2h->raw.payload, len, false); + break; + } + + skb_queue_tail(&priv->c2hcmd_queue, skb); + + schedule_work(&priv->c2hcmd_work); +} + +static void rtl8188e_c2hcmd_callback(struct work_struct *work) +{ + struct rtl8xxxu_priv *priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work); + struct device *dev = &priv->udev->dev; + struct sk_buff *skb = NULL; + struct rtl8xxxu_rxdesc16 *rx_desc; + + while (!skb_queue_empty(&priv->c2hcmd_queue)) { + skb = skb_dequeue(&priv->c2hcmd_queue); + + rx_desc = (struct rtl8xxxu_rxdesc16 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16)); + + switch (rx_desc->rpt_sel) { + case 1: + dev_dbg(dev, "C2H TX report type 1\n"); + + break; + case 2: + dev_dbg(dev, "C2H TX report type 2\n"); + + rtl8188e_handle_ra_tx_report2(priv, skb); + + break; + case 3: + dev_dbg(dev, "C2H USB interrupt report\n"); + + break; + default: + dev_warn(dev, "%s: rpt_sel should not be %d\n", + __func__, rx_desc->rpt_sel); + + break; + } + + dev_kfree_skb(skb); + } +} + +#define rtl8xxxu_iterate_vifs_atomic(priv, iterator, data) \ + ieee80211_iterate_active_interfaces_atomic((priv)->hw, \ + IEEE80211_IFACE_ITER_NORMAL, iterator, data) + +struct rtl8xxxu_rx_update_rssi_data { + struct rtl8xxxu_priv *priv; + struct ieee80211_hdr *hdr; + struct ieee80211_rx_status *rx_status; + u8 *bssid; +}; + +static void rtl8xxxu_rx_update_rssi_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtl8xxxu_rx_update_rssi_data *iter_data = data; + struct ieee80211_sta *sta; + struct ieee80211_hdr *hdr = iter_data->hdr; + struct rtl8xxxu_priv *priv = iter_data->priv; + struct rtl8xxxu_sta_info *sta_info; + struct ieee80211_rx_status *rx_status = iter_data->rx_status; + u8 *bssid = iter_data->bssid; + + if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) + return; + + if (!(ether_addr_equal(vif->addr, hdr->addr1) || + ieee80211_is_beacon(hdr->frame_control))) + return; + + sta = ieee80211_find_sta_by_ifaddr(priv->hw, hdr->addr2, + vif->addr); + if (!sta) + return; + + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + ewma_rssi_add(&sta_info->avg_rssi, -rx_status->signal); +} + +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) +{ + __le16 fc = hdr->frame_control; + u8 *bssid; + + if (ieee80211_has_tods(fc)) + bssid = hdr->addr1; + else if (ieee80211_has_fromds(fc)) + bssid = hdr->addr2; + else + bssid = hdr->addr3; + + return bssid; +} + +static void rtl8xxxu_rx_update_rssi(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct ieee80211_hdr *hdr) +{ + struct rtl8xxxu_rx_update_rssi_data data = {}; + + if (ieee80211_is_ctl(hdr->frame_control)) + return; + + data.priv = priv; + data.hdr = hdr; + data.rx_status = rx_status; + data.bssid = get_hdr_bssid(hdr); + + rtl8xxxu_iterate_vifs_atomic(priv, rtl8xxxu_rx_update_rssi_iter, &data); +} + +int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_rx_status *rx_status; + struct rtl8xxxu_rxdesc16 *rx_desc; + struct rtl8723au_phy_stats *phy_stats; + struct sk_buff *next_skb = NULL; + __le32 *_rx_desc_le; + u32 *_rx_desc; + int drvinfo_sz, desc_shift; + int i, pkt_cnt, pkt_len, urb_len, pkt_offset; + + urb_len = skb->len; + pkt_cnt = 0; + + if (urb_len < sizeof(struct rtl8xxxu_rxdesc16)) { + kfree_skb(skb); + return RX_TYPE_ERROR; + } + + do { + rx_desc = (struct rtl8xxxu_rxdesc16 *)skb->data; + _rx_desc_le = (__le32 *)skb->data; + _rx_desc = (u32 *)skb->data; + + for (i = 0; + i < (sizeof(struct rtl8xxxu_rxdesc16) / sizeof(u32)); i++) + _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); + + /* + * Only read pkt_cnt from the header if we're parsing the + * first packet + */ + if (!pkt_cnt) + pkt_cnt = rx_desc->pkt_cnt; + pkt_len = rx_desc->pktlen; + + drvinfo_sz = rx_desc->drvinfo_sz * 8; + desc_shift = rx_desc->shift; + pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift + + sizeof(struct rtl8xxxu_rxdesc16), 128); + + /* + * Only clone the skb if there's enough data at the end to + * at least cover the rx descriptor + */ + if (pkt_cnt > 1 && + urb_len >= (pkt_offset + sizeof(struct rtl8xxxu_rxdesc16))) + next_skb = skb_clone(skb, GFP_ATOMIC); + + rx_status = IEEE80211_SKB_RXCB(skb); + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + + skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16)); + + if (rx_desc->rpt_sel) { + skb_queue_tail(&priv->c2hcmd_queue, skb); + schedule_work(&priv->c2hcmd_work); + } else { + struct ieee80211_hdr *hdr; + + phy_stats = (struct rtl8723au_phy_stats *)skb->data; + + skb_pull(skb, drvinfo_sz + desc_shift); + + skb_trim(skb, pkt_len); + + hdr = (struct ieee80211_hdr *)skb->data; + if (rx_desc->phy_stats) { + priv->fops->parse_phystats( + priv, rx_status, phy_stats, + rx_desc->rxmcs, + hdr, + rx_desc->crc32 || rx_desc->icverr); + if (!rx_desc->crc32 && !rx_desc->icverr) + rtl8xxxu_rx_update_rssi(priv, + rx_status, + hdr); + } else { + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + } + + rx_status->mactime = rx_desc->tsfl; + rx_status->flag |= RX_FLAG_MACTIME_START; + + if (!rx_desc->swdec && + rx_desc->security != RX_DESC_ENC_NONE) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (rx_desc->crc32) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (rx_desc->bw) + rx_status->bw = RATE_INFO_BW_40; + + if (rx_desc->rxht) { + rx_status->encoding = RX_ENC_HT; + rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0; + } else { + rx_status->rate_idx = rx_desc->rxmcs; + } + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + ieee80211_rx_irqsafe(hw, skb); + } + + skb = next_skb; + if (skb) + skb_pull(next_skb, pkt_offset); + + pkt_cnt--; + urb_len -= pkt_offset; + next_skb = NULL; + } while (skb && pkt_cnt > 0 && + urb_len >= sizeof(struct rtl8xxxu_rxdesc16)); + + return RX_TYPE_DATA_PKT; +} + +int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_rx_status *rx_status; + struct rtl8xxxu_rxdesc24 *rx_desc; + struct rtl8723au_phy_stats *phy_stats; + struct sk_buff *next_skb = NULL; + __le32 *_rx_desc_le; + u32 *_rx_desc; + int drvinfo_sz, desc_shift; + int i, pkt_len, urb_len, pkt_offset; + + urb_len = skb->len; + + if (urb_len < sizeof(struct rtl8xxxu_rxdesc24)) { + kfree_skb(skb); + return RX_TYPE_ERROR; + } + + do { + rx_desc = (struct rtl8xxxu_rxdesc24 *)skb->data; + _rx_desc_le = (__le32 *)skb->data; + _rx_desc = (u32 *)skb->data; + + for (i = 0; i < (sizeof(struct rtl8xxxu_rxdesc24) / sizeof(u32)); i++) + _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); + + pkt_len = rx_desc->pktlen; + + drvinfo_sz = rx_desc->drvinfo_sz * 8; + desc_shift = rx_desc->shift; + pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift + + sizeof(struct rtl8xxxu_rxdesc24), 8); + + /* + * Only clone the skb if there's enough data at the end to + * at least cover the rx descriptor + */ + if (urb_len >= (pkt_offset + sizeof(struct rtl8xxxu_rxdesc24))) + next_skb = skb_clone(skb, GFP_ATOMIC); + + rx_status = IEEE80211_SKB_RXCB(skb); + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + + skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc24)); + + phy_stats = (struct rtl8723au_phy_stats *)skb->data; + + skb_pull(skb, drvinfo_sz + desc_shift); + + skb_trim(skb, pkt_len); + + if (rx_desc->rpt_sel) { + struct device *dev = &priv->udev->dev; + dev_dbg(dev, "%s: C2H packet\n", __func__); + rtl8723bu_handle_c2h(priv, skb); + } else { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (rx_desc->phy_stats) { + priv->fops->parse_phystats(priv, rx_status, phy_stats, + rx_desc->rxmcs, hdr, + rx_desc->crc32 || rx_desc->icverr); + if (!rx_desc->crc32 && !rx_desc->icverr) + rtl8xxxu_rx_update_rssi(priv, + rx_status, + hdr); + } else { + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + } + + rx_status->mactime = rx_desc->tsfl; + rx_status->flag |= RX_FLAG_MACTIME_START; + + if (!rx_desc->swdec && + rx_desc->security != RX_DESC_ENC_NONE) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (rx_desc->crc32) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (rx_desc->bw) + rx_status->bw = RATE_INFO_BW_40; + + if (rx_desc->rxmcs >= DESC_RATE_MCS0) { + rx_status->encoding = RX_ENC_HT; + rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0; + } else { + rx_status->rate_idx = rx_desc->rxmcs; + } + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + ieee80211_rx_irqsafe(hw, skb); + } + + skb = next_skb; + if (skb) + skb_pull(next_skb, pkt_offset); + + urb_len -= pkt_offset; + next_skb = NULL; + } while (skb && urb_len >= sizeof(struct rtl8xxxu_rxdesc24)); + + return RX_TYPE_DATA_PKT; +} + +static void rtl8xxxu_rx_complete(struct urb *urb) +{ + struct rtl8xxxu_rx_urb *rx_urb = + container_of(urb, struct rtl8xxxu_rx_urb, urb); + struct ieee80211_hw *hw = rx_urb->hw; + struct rtl8xxxu_priv *priv = hw->priv; + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct device *dev = &priv->udev->dev; + + skb_put(skb, urb->actual_length); + + if (urb->status == 0) { + priv->fops->parse_rx_desc(priv, skb); + + skb = NULL; + rx_urb->urb.context = NULL; + rtl8xxxu_queue_rx_urb(priv, rx_urb); + } else { + dev_dbg(dev, "%s: status %i\n", __func__, urb->status); + goto cleanup; + } + return; + +cleanup: + usb_free_urb(urb); + dev_kfree_skb(skb); +} + +static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv, + struct rtl8xxxu_rx_urb *rx_urb) +{ + struct rtl8xxxu_fileops *fops = priv->fops; + struct sk_buff *skb; + int skb_size; + int ret, rx_desc_sz; + + rx_desc_sz = fops->rx_desc_size; + + if (priv->rx_buf_aggregation && fops->rx_agg_buf_size) { + skb_size = fops->rx_agg_buf_size; + skb_size += (rx_desc_sz + sizeof(struct rtl8723au_phy_stats)); + } else { + skb_size = IEEE80211_MAX_FRAME_LEN + rx_desc_sz; + } + + skb = __netdev_alloc_skb(NULL, skb_size, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + memset(skb->data, 0, rx_desc_sz); + usb_fill_bulk_urb(&rx_urb->urb, priv->udev, priv->pipe_in, skb->data, + skb_size, rtl8xxxu_rx_complete, skb); + usb_anchor_urb(&rx_urb->urb, &priv->rx_anchor); + ret = usb_submit_urb(&rx_urb->urb, GFP_ATOMIC); + if (ret) + usb_unanchor_urb(&rx_urb->urb); + return ret; +} + +static void rtl8xxxu_int_complete(struct urb *urb) +{ + struct rtl8xxxu_priv *priv = (struct rtl8xxxu_priv *)urb->context; + struct device *dev = &priv->udev->dev; + int ret; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_INTERRUPT) + dev_dbg(dev, "%s: status %i\n", __func__, urb->status); + if (urb->status == 0) { + usb_anchor_urb(urb, &priv->int_anchor); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + usb_unanchor_urb(urb); + } else { + dev_dbg(dev, "%s: Error %i\n", __func__, urb->status); + } +} + + +static int rtl8xxxu_submit_int_urb(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct urb *urb; + u32 val32; + int ret; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return -ENOMEM; + + usb_fill_int_urb(urb, priv->udev, priv->pipe_interrupt, + priv->int_buf, USB_INTR_CONTENT_LENGTH, + rtl8xxxu_int_complete, priv, 1); + usb_anchor_urb(urb, &priv->int_anchor); + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) { + usb_unanchor_urb(urb); + goto error; + } + + val32 = rtl8xxxu_read32(priv, REG_USB_HIMR); + val32 |= USB_HIMR_CPWM; + rtl8xxxu_write32(priv, REG_USB_HIMR, val32); + +error: + usb_free_urb(urb); + return ret; +} + +static void rtl8xxxu_switch_ports(struct rtl8xxxu_priv *priv) +{ + u8 macid[ETH_ALEN], bssid[ETH_ALEN], macid_1[ETH_ALEN], bssid_1[ETH_ALEN]; + u8 msr, bcn_ctrl, bcn_ctrl_1, atimwnd[2], atimwnd_1[2]; + struct rtl8xxxu_vif *rtlvif; + u8 tsftr[8], tsftr_1[8]; + int i; + + msr = rtl8xxxu_read8(priv, REG_MSR); + bcn_ctrl = rtl8xxxu_read8(priv, REG_BEACON_CTRL); + bcn_ctrl_1 = rtl8xxxu_read8(priv, REG_BEACON_CTRL_1); + + for (i = 0; i < ARRAY_SIZE(atimwnd); i++) + atimwnd[i] = rtl8xxxu_read8(priv, REG_ATIMWND + i); + for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++) + atimwnd_1[i] = rtl8xxxu_read8(priv, REG_ATIMWND_1 + i); + + for (i = 0; i < ARRAY_SIZE(tsftr); i++) + tsftr[i] = rtl8xxxu_read8(priv, REG_TSFTR + i); + for (i = 0; i < ARRAY_SIZE(tsftr); i++) + tsftr_1[i] = rtl8xxxu_read8(priv, REG_TSFTR1 + i); + + for (i = 0; i < ARRAY_SIZE(macid); i++) + macid[i] = rtl8xxxu_read8(priv, REG_MACID + i); + + for (i = 0; i < ARRAY_SIZE(bssid); i++) + bssid[i] = rtl8xxxu_read8(priv, REG_BSSID + i); + + for (i = 0; i < ARRAY_SIZE(macid_1); i++) + macid_1[i] = rtl8xxxu_read8(priv, REG_MACID1 + i); + + for (i = 0; i < ARRAY_SIZE(bssid_1); i++) + bssid_1[i] = rtl8xxxu_read8(priv, REG_BSSID1 + i); + + /* disable bcn function, disable update TSF */ + rtl8xxxu_write8(priv, REG_BEACON_CTRL, (bcn_ctrl & + (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE); + rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, (bcn_ctrl_1 & + (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE); + + /* switch msr */ + msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2); + rtl8xxxu_write8(priv, REG_MSR, msr); + + /* write port0 */ + rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1 & ~BEACON_FUNCTION_ENABLE); + for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++) + rtl8xxxu_write8(priv, REG_ATIMWND + i, atimwnd_1[i]); + for (i = 0; i < ARRAY_SIZE(tsftr_1); i++) + rtl8xxxu_write8(priv, REG_TSFTR + i, tsftr_1[i]); + for (i = 0; i < ARRAY_SIZE(macid_1); i++) + rtl8xxxu_write8(priv, REG_MACID + i, macid_1[i]); + for (i = 0; i < ARRAY_SIZE(bssid_1); i++) + rtl8xxxu_write8(priv, REG_BSSID + i, bssid_1[i]); + + /* write port1 */ + rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl & ~BEACON_FUNCTION_ENABLE); + for (i = 0; i < ARRAY_SIZE(atimwnd); i++) + rtl8xxxu_write8(priv, REG_ATIMWND_1 + i, atimwnd[i]); + for (i = 0; i < ARRAY_SIZE(tsftr); i++) + rtl8xxxu_write8(priv, REG_TSFTR1 + i, tsftr[i]); + for (i = 0; i < ARRAY_SIZE(macid); i++) + rtl8xxxu_write8(priv, REG_MACID1 + i, macid[i]); + for (i = 0; i < ARRAY_SIZE(bssid); i++) + rtl8xxxu_write8(priv, REG_BSSID1 + i, bssid[i]); + + /* write bcn ctl */ + rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1); + rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl); + swap(priv->vifs[0], priv->vifs[1]); + + /* priv->vifs[0] is NULL here, based on how this function is currently + * called from rtl8xxxu_add_interface(). + * When this function will be used in the future for a different + * scenario, please check whether vifs[0] or vifs[1] can be NULL and if + * necessary add code to set port_num = 1. + */ + rtlvif = (struct rtl8xxxu_vif *)priv->vifs[1]->drv_priv; + rtlvif->port_num = 1; +} + +static int rtl8xxxu_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + int port_num; + u8 val8; + + if (!priv->vifs[0]) + port_num = 0; + else if (!priv->vifs[1]) + port_num = 1; + else + return -EOPNOTSUPP; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (port_num == 0) { + rtl8xxxu_stop_tx_beacon(priv); + + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); + val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE | + BEACON_DISABLE_TSF_UPDATE; + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); + } + break; + case NL80211_IFTYPE_AP: + if (port_num == 1) { + rtl8xxxu_switch_ports(priv); + port_num = 0; + } + + rtl8xxxu_write8(priv, REG_BEACON_CTRL, + BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID); + rtl8xxxu_write8(priv, REG_ATIMWND, 0x0c); /* 12ms */ + rtl8xxxu_write16(priv, REG_TSFTR_SYN_OFFSET, 0x7fff); /* ~32ms */ + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, DUAL_TSF_RESET_TSF0); + + /* enable BCN0 function */ + rtl8xxxu_write8(priv, REG_BEACON_CTRL, + BEACON_DISABLE_TSF_UPDATE | + BEACON_FUNCTION_ENABLE | BEACON_CTRL_MBSSID | + BEACON_CTRL_TX_BEACON_RPT); + + /* select BCN on port 0 */ + val8 = rtl8xxxu_read8(priv, REG_CCK_CHECK); + val8 &= ~BIT_BCN_PORT_SEL; + rtl8xxxu_write8(priv, REG_CCK_CHECK, val8); + break; + default: + return -EOPNOTSUPP; + } + + priv->vifs[port_num] = vif; + rtlvif->port_num = port_num; + rtlvif->hw_key_idx = 0xff; + + rtl8xxxu_set_linktype(priv, vif->type, port_num); + ether_addr_copy(priv->mac_addr, vif->addr); + rtl8xxxu_set_mac(priv, port_num); + + return 0; +} + +static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + + dev_dbg(&priv->udev->dev, "%s\n", __func__); + + priv->vifs[rtlvif->port_num] = NULL; +} + +static int rtl8xxxu_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + int ret = 0, channel; + bool ht40; + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_CHANNEL) + dev_info(dev, + "%s: channel: %i (changed %08x chandef.width %02x)\n", + __func__, hw->conf.chandef.chan->hw_value, + changed, hw->conf.chandef.width); + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + switch (hw->conf.chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + ht40 = false; + break; + case NL80211_CHAN_WIDTH_40: + ht40 = true; + break; + default: + ret = -ENOTSUPP; + goto exit; + } + + channel = hw->conf.chandef.chan->hw_value; + + priv->fops->set_tx_power(priv, channel, ht40); + + priv->fops->config_channel(hw); + } + +exit: + return ret; +} + +static int rtl8xxxu_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *param) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + u32 val32; + u8 aifs, acm_ctrl, acm_bit; + + aifs = param->aifs; + + val32 = aifs | + fls(param->cw_min) << EDCA_PARAM_ECW_MIN_SHIFT | + fls(param->cw_max) << EDCA_PARAM_ECW_MAX_SHIFT | + (u32)param->txop << EDCA_PARAM_TXOP_SHIFT; + + acm_ctrl = rtl8xxxu_read8(priv, REG_ACM_HW_CTRL); + dev_dbg(dev, + "%s: IEEE80211 queue %02x val %08x, acm %i, acm_ctrl %02x\n", + __func__, queue, val32, param->acm, acm_ctrl); + + switch (queue) { + case IEEE80211_AC_VO: + acm_bit = ACM_HW_CTRL_VO; + rtl8xxxu_write32(priv, REG_EDCA_VO_PARAM, val32); + break; + case IEEE80211_AC_VI: + acm_bit = ACM_HW_CTRL_VI; + rtl8xxxu_write32(priv, REG_EDCA_VI_PARAM, val32); + break; + case IEEE80211_AC_BE: + acm_bit = ACM_HW_CTRL_BE; + rtl8xxxu_write32(priv, REG_EDCA_BE_PARAM, val32); + break; + case IEEE80211_AC_BK: + acm_bit = ACM_HW_CTRL_BK; + rtl8xxxu_write32(priv, REG_EDCA_BK_PARAM, val32); + break; + default: + acm_bit = 0; + break; + } + + if (param->acm) + acm_ctrl |= acm_bit; + else + acm_ctrl &= ~acm_bit; + rtl8xxxu_write8(priv, REG_ACM_HW_CTRL, acm_ctrl); + + return 0; +} + +static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) +{ + struct rtl8xxxu_priv *priv = hw->priv; + u32 rcr = priv->regrcr; + + dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n", + __func__, changed_flags, *total_flags); + + /* + * FIF_ALLMULTI ignored as all multicast frames are accepted (REG_MAR) + */ + + if (*total_flags & FIF_FCSFAIL) + rcr |= RCR_ACCEPT_CRC32; + else + rcr &= ~RCR_ACCEPT_CRC32; + + /* + * FIF_PLCPFAIL not supported? + */ + + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) + rcr &= ~(RCR_CHECK_BSSID_BEACON | RCR_CHECK_BSSID_MATCH); + else + rcr |= RCR_CHECK_BSSID_BEACON | RCR_CHECK_BSSID_MATCH; + + if (priv->vifs[0] && priv->vifs[0]->type == NL80211_IFTYPE_AP) + rcr &= ~(RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON); + + if (*total_flags & FIF_CONTROL) + rcr |= RCR_ACCEPT_CTRL_FRAME; + else + rcr &= ~RCR_ACCEPT_CTRL_FRAME; + + if (*total_flags & FIF_OTHER_BSS) + rcr |= RCR_ACCEPT_AP; + else + rcr &= ~RCR_ACCEPT_AP; + + if (*total_flags & FIF_PSPOLL) + rcr |= RCR_ACCEPT_PM; + else + rcr &= ~RCR_ACCEPT_PM; + + /* + * FIF_PROBE_REQ ignored as probe requests always seem to be accepted + */ + + rtl8xxxu_write32(priv, REG_RCR, rcr); + priv->regrcr = rcr; + + *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC | + FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL | + FIF_PROBE_REQ); +} + +static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, + u32 rts) +{ + if (rts > 2347 && rts != (u32)-1) + return -EINVAL; + + return 0; +} + +static int rtl8xxxu_get_free_sec_cam(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + return find_first_zero_bit(priv->cam_map, priv->fops->max_sec_cam_num); +} + +static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + u8 mac_addr[ETH_ALEN]; + u8 val8; + u16 val16; + u32 val32; + int retval = -EOPNOTSUPP; + + dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n", + __func__, cmd, key->cipher, key->keyidx); + + if (key->keyidx > 3) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + + break; + case WLAN_CIPHER_SUITE_CCMP: + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + case WLAN_CIPHER_SUITE_TKIP: + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + default: + return -EOPNOTSUPP; + } + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + dev_dbg(dev, "%s: pairwise key\n", __func__); + ether_addr_copy(mac_addr, sta->addr); + } else { + dev_dbg(dev, "%s: group key\n", __func__); + ether_addr_copy(mac_addr, vif->bss_conf.bssid); + } + + val16 = rtl8xxxu_read16(priv, REG_CR); + val16 |= CR_SECURITY_ENABLE; + rtl8xxxu_write16(priv, REG_CR, val16); + + val8 = SEC_CFG_TX_SEC_ENABLE | SEC_CFG_TXBC_USE_DEFKEY | + SEC_CFG_RX_SEC_ENABLE | SEC_CFG_RXBC_USE_DEFKEY; + val8 |= SEC_CFG_TX_USE_DEFKEY | SEC_CFG_RX_USE_DEFKEY; + rtl8xxxu_write8(priv, REG_SECURITY_CFG, val8); + + switch (cmd) { + case SET_KEY: + + retval = rtl8xxxu_get_free_sec_cam(hw); + if (retval < 0) + return -EOPNOTSUPP; + + key->hw_key_idx = retval; + + if (vif->type == NL80211_IFTYPE_AP && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + rtlvif->hw_key_idx = key->hw_key_idx; + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + rtl8xxxu_cam_write(priv, key, mac_addr); + set_bit(key->hw_key_idx, priv->cam_map); + retval = 0; + break; + case DISABLE_KEY: + rtl8xxxu_write32(priv, REG_CAM_WRITE, 0x00000000); + val32 = CAM_CMD_POLLING | CAM_CMD_WRITE | + key->hw_key_idx << CAM_CMD_KEY_SHIFT; + rtl8xxxu_write32(priv, REG_CAM_CMD, val32); + rtlvif->hw_key_idx = 0xff; + clear_bit(key->hw_key_idx, priv->cam_map); + retval = 0; + break; + default: + dev_warn(dev, "%s: Unsupported command %02x\n", __func__, cmd); + } + + return retval; +} + +static int +rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + u8 ampdu_factor, ampdu_density; + struct ieee80211_sta *sta = params->sta; + u16 tid = params->tid; + enum ieee80211_ampdu_mlme_action action = params->action; + + switch (action) { + case IEEE80211_AMPDU_TX_START: + dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_START\n", __func__); + ampdu_factor = sta->deflink.ht_cap.ampdu_factor; + ampdu_density = sta->deflink.ht_cap.ampdu_density; + rtl8xxxu_set_ampdu_factor(priv, ampdu_factor); + rtl8xxxu_set_ampdu_min_space(priv, ampdu_density); + dev_dbg(dev, + "Changed HT: ampdu_factor %02x, ampdu_density %02x\n", + ampdu_factor, ampdu_density); + return IEEE80211_AMPDU_TX_START_IMMEDIATE; + case IEEE80211_AMPDU_TX_STOP_CONT: + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP\n", __func__); + rtl8xxxu_set_ampdu_factor(priv, 0); + rtl8xxxu_set_ampdu_min_space(priv, 0); + clear_bit(tid, priv->tx_aggr_started); + clear_bit(tid, priv->tid_tx_operational); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_OPERATIONAL\n", __func__); + set_bit(tid, priv->tid_tx_operational); + break; + case IEEE80211_AMPDU_RX_START: + dev_dbg(dev, "%s: IEEE80211_AMPDU_RX_START\n", __func__); + break; + case IEEE80211_AMPDU_RX_STOP: + dev_dbg(dev, "%s: IEEE80211_AMPDU_RX_STOP\n", __func__); + break; + default: + break; + } + return 0; +} + +static void +rtl8xxxu_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct station_info *sinfo) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + sinfo->txrate = priv->ra_report.txrate; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +} + +static u8 rtl8xxxu_signal_to_snr(int signal) +{ + if (signal < RTL8XXXU_NOISE_FLOOR_MIN) + signal = RTL8XXXU_NOISE_FLOOR_MIN; + else if (signal > 0) + signal = 0; + return (u8)(signal - RTL8XXXU_NOISE_FLOOR_MIN); +} + +static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv, + int signal, struct ieee80211_sta *sta, + bool force) +{ + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct ieee80211_hw *hw = priv->hw; + u16 wireless_mode; + u8 rssi_level, ratr_idx; + u8 txbw_40mhz; + u8 snr, snr_thresh_high, snr_thresh_low; + u8 go_up_gap = 5; + u8 macid = rtl8xxxu_get_macid(priv, sta); + + rssi_level = sta_info->rssi_level; + snr = rtl8xxxu_signal_to_snr(signal); + snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH; + snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW; + txbw_40mhz = (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) ? 1 : 0; + + switch (rssi_level) { + case RTL8XXXU_RATR_STA_MID: + snr_thresh_high += go_up_gap; + break; + case RTL8XXXU_RATR_STA_LOW: + snr_thresh_high += go_up_gap; + snr_thresh_low += go_up_gap; + break; + default: + break; + } + + if (snr > snr_thresh_high) + rssi_level = RTL8XXXU_RATR_STA_HIGH; + else if (snr > snr_thresh_low) + rssi_level = RTL8XXXU_RATR_STA_MID; + else + rssi_level = RTL8XXXU_RATR_STA_LOW; + + if (rssi_level != sta_info->rssi_level || force) { + int sgi = 0; + u32 rate_bitmap = 0; + + rate_bitmap = (sta->deflink.supp_rates[0] & 0xfff) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20); + if (sta->deflink.ht_cap.cap & + (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) + sgi = 1; + + wireless_mode = rtl8xxxu_wireless_mode(hw, sta); + switch (wireless_mode) { + case WIRELESS_MODE_B: + ratr_idx = RATEID_IDX_B; + if (rate_bitmap & 0x0000000c) + rate_bitmap &= 0x0000000d; + else + rate_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_A: + case WIRELESS_MODE_G: + ratr_idx = RATEID_IDX_G; + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) + rate_bitmap &= 0x00000f00; + else + rate_bitmap &= 0x00000ff0; + break; + case (WIRELESS_MODE_B | WIRELESS_MODE_G): + ratr_idx = RATEID_IDX_BG; + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) + rate_bitmap &= 0x00000f00; + else if (rssi_level == RTL8XXXU_RATR_STA_MID) + rate_bitmap &= 0x00000ff0; + else + rate_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + case (WIRELESS_MODE_G | WIRELESS_MODE_N_24G): + case (WIRELESS_MODE_A | WIRELESS_MODE_N_5G): + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_GN_N2SS; + else + ratr_idx = RATEID_IDX_GN_N1SS; + break; + case (WIRELESS_MODE_B | WIRELESS_MODE_G | WIRELESS_MODE_N_24G): + case (WIRELESS_MODE_B | WIRELESS_MODE_N_24G): + if (txbw_40mhz) { + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_BGN_40M_2SS; + else + ratr_idx = RATEID_IDX_BGN_40M_1SS; + } else { + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_BGN_20M_2SS_BN; + else + ratr_idx = RATEID_IDX_BGN_20M_1SS_BN; + } + + if (priv->tx_paths == 2 && priv->rx_paths == 2) { + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) { + rate_bitmap &= 0x0f8f0000; + } else if (rssi_level == RTL8XXXU_RATR_STA_MID) { + rate_bitmap &= 0x0f8ff000; + } else { + if (txbw_40mhz) + rate_bitmap &= 0x0f8ff015; + else + rate_bitmap &= 0x0f8ff005; + } + } else { + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) { + rate_bitmap &= 0x000f0000; + } else if (rssi_level == RTL8XXXU_RATR_STA_MID) { + rate_bitmap &= 0x000ff000; + } else { + if (txbw_40mhz) + rate_bitmap &= 0x000ff015; + else + rate_bitmap &= 0x000ff005; + } + } + break; + default: + ratr_idx = RATEID_IDX_BGN_40M_2SS; + rate_bitmap &= 0x0fffffff; + break; + } + + sta_info->rssi_level = rssi_level; + priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz, macid); + } +} + +static void rtl8xxxu_set_atc_status(struct rtl8xxxu_priv *priv, bool atc_status) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + u32 val32; + + if (atc_status == cfo->atc_status) + return; + + cfo->atc_status = atc_status; + + val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING); + if (atc_status) + val32 |= CFO_TRACKING_ATC_STATUS; + else + val32 &= ~CFO_TRACKING_ATC_STATUS; + rtl8xxxu_write32(priv, REG_OFDM1_CFO_TRACKING, val32); +} + +/* Central frequency offset correction */ +static void rtl8xxxu_track_cfo(struct rtl8xxxu_priv *priv) +{ + struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; + int cfo_khz_a, cfo_khz_b, cfo_average; + int crystal_cap; + + if (!rtl8xxxu_is_assoc(priv)) { + /* Reset */ + cfo->adjust = true; + + if (cfo->crystal_cap > priv->default_crystal_cap) + priv->fops->set_crystal_cap(priv, cfo->crystal_cap - 1); + else if (cfo->crystal_cap < priv->default_crystal_cap) + priv->fops->set_crystal_cap(priv, cfo->crystal_cap + 1); + + rtl8xxxu_set_atc_status(priv, true); + + return; + } + + if (cfo->packet_count == cfo->packet_count_pre) + /* No new information. */ + return; + + cfo->packet_count_pre = cfo->packet_count; + + /* CFO_tail[1:0] is S(8,7), (num_subcarrier>>7) x 312.5K = CFO value(K Hz) */ + cfo_khz_a = (int)((cfo->cfo_tail[0] * 3125) / 10) >> 7; + cfo_khz_b = (int)((cfo->cfo_tail[1] * 3125) / 10) >> 7; + + if (priv->tx_paths == 1) + cfo_average = cfo_khz_a; + else + cfo_average = (cfo_khz_a + cfo_khz_b) / 2; + + dev_dbg(&priv->udev->dev, "cfo_average: %d\n", cfo_average); + + if (cfo->adjust) { + if (abs(cfo_average) < CFO_TH_XTAL_LOW) + cfo->adjust = false; + } else { + if (abs(cfo_average) > CFO_TH_XTAL_HIGH) + cfo->adjust = true; + } + + /* + * TODO: We should return here only if bluetooth is enabled. + * See the vendor drivers for how to determine that. + */ + if (priv->has_bluetooth) + return; + + if (!cfo->adjust) + return; + + crystal_cap = cfo->crystal_cap; + + if (cfo_average > CFO_TH_XTAL_LOW) + crystal_cap++; + else if (cfo_average < -CFO_TH_XTAL_LOW) + crystal_cap--; + + crystal_cap = clamp(crystal_cap, 0, 0x3f); + + priv->fops->set_crystal_cap(priv, crystal_cap); + + rtl8xxxu_set_atc_status(priv, abs(cfo_average) >= CFO_TH_ATC); +} + +static void rtl8xxxu_ra_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct rtl8xxxu_priv *priv = data; + int signal = -ewma_rssi_read(&sta_info->avg_rssi); + + priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta), + rtl8xxxu_signal_to_snr(signal)); + rtl8xxxu_refresh_rate_mask(priv, signal, sta, false); +} + +struct rtl8xxxu_stas_entry { + struct list_head list; + struct ieee80211_sta *sta; +}; + +struct rtl8xxxu_iter_stas_data { + struct rtl8xxxu_priv *priv; + struct list_head list; +}; + +static void rtl8xxxu_collect_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtl8xxxu_iter_stas_data *iter_stas = data; + struct rtl8xxxu_stas_entry *stas_entry; + + stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC); + if (!stas_entry) + return; + + stas_entry->sta = sta; + list_add_tail(&stas_entry->list, &iter_stas->list); +} + +static void rtl8xxxu_watchdog_callback(struct work_struct *work) +{ + + struct rtl8xxxu_iter_stas_data iter_data; + struct rtl8xxxu_stas_entry *sta_entry, *tmp; + struct rtl8xxxu_priv *priv; + + priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work); + iter_data.priv = priv; + INIT_LIST_HEAD(&iter_data.list); + + mutex_lock(&priv->sta_mutex); + ieee80211_iterate_stations_atomic(priv->hw, rtl8xxxu_collect_sta_iter, + &iter_data); + list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, list) { + list_del_init(&sta_entry->list); + rtl8xxxu_ra_iter(priv, sta_entry->sta); + kfree(sta_entry); + } + mutex_unlock(&priv->sta_mutex); + + if (priv->fops->set_crystal_cap) + rtl8xxxu_track_cfo(priv); + + schedule_delayed_work(&priv->ra_watchdog, 2 * HZ); +} + +static int rtl8xxxu_start(struct ieee80211_hw *hw) +{ + struct rtl8xxxu_priv *priv = hw->priv; + struct rtl8xxxu_rx_urb *rx_urb; + struct rtl8xxxu_tx_urb *tx_urb; + struct sk_buff *skb; + unsigned long flags; + int ret, i; + + ret = 0; + + init_usb_anchor(&priv->rx_anchor); + init_usb_anchor(&priv->tx_anchor); + init_usb_anchor(&priv->int_anchor); + + priv->fops->enable_rf(priv); + if (priv->usb_interrupts) { + ret = rtl8xxxu_submit_int_urb(hw); + if (ret) + goto exit; + } + + for (i = 0; i < RTL8XXXU_TX_URBS; i++) { + tx_urb = kmalloc_obj(struct rtl8xxxu_tx_urb); + if (!tx_urb) { + if (!i) + ret = -ENOMEM; + + goto error_out; + } + usb_init_urb(&tx_urb->urb); + INIT_LIST_HEAD(&tx_urb->list); + tx_urb->hw = hw; + list_add(&tx_urb->list, &priv->tx_urb_free_list); + priv->tx_urb_free_count++; + } + + priv->tx_stopped = false; + + spin_lock_irqsave(&priv->rx_urb_lock, flags); + priv->shutdown = false; + spin_unlock_irqrestore(&priv->rx_urb_lock, flags); + + for (i = 0; i < RTL8XXXU_RX_URBS; i++) { + rx_urb = kmalloc_obj(struct rtl8xxxu_rx_urb); + if (!rx_urb) { + if (!i) + ret = -ENOMEM; + + goto error_out; + } + usb_init_urb(&rx_urb->urb); + INIT_LIST_HEAD(&rx_urb->list); + rx_urb->hw = hw; + + ret = rtl8xxxu_submit_rx_urb(priv, rx_urb); + if (ret) { + if (ret != -ENOMEM) { + skb = (struct sk_buff *)rx_urb->urb.context; + dev_kfree_skb(skb); + } + rtl8xxxu_queue_rx_urb(priv, rx_urb); + } + } + + schedule_delayed_work(&priv->ra_watchdog, 2 * HZ); +exit: + /* + * Accept all data and mgmt frames + */ + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff); + rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff); + + rtl8xxxu_write32_mask(priv, REG_OFDM0_XA_AGC_CORE1, + OFDM0_X_AGC_CORE1_IGI_MASK, 0x1e); + + return ret; + +error_out: + rtl8xxxu_free_tx_resources(priv); + /* + * Disable all data and mgmt frames + */ + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000); + rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0x0000); + + return ret; +} + +static void rtl8xxxu_stop(struct ieee80211_hw *hw, bool suspend) +{ + struct rtl8xxxu_priv *priv = hw->priv; + unsigned long flags; + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0x0000); + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000); + + spin_lock_irqsave(&priv->rx_urb_lock, flags); + priv->shutdown = true; + spin_unlock_irqrestore(&priv->rx_urb_lock, flags); + + /* + * Cancel before killing rx_anchor: the worker re-anchors every URB + * it drained via rtl8xxxu_submit_rx_urb(), so a worker still running + * after the kill could submit a URB that escapes it. + */ + cancel_work_sync(&priv->rx_urb_wq); + + usb_kill_anchored_urbs(&priv->rx_anchor); + usb_kill_anchored_urbs(&priv->tx_anchor); + if (priv->usb_interrupts) + usb_kill_anchored_urbs(&priv->int_anchor); + + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); + + priv->fops->disable_rf(priv); + + /* + * Disable interrupts + */ + if (priv->usb_interrupts) + rtl8xxxu_write32(priv, REG_USB_HIMR, 0); + + cancel_work_sync(&priv->c2hcmd_work); + cancel_delayed_work_sync(&priv->ra_watchdog); + cancel_delayed_work_sync(&priv->update_beacon_work); + + rtl8xxxu_free_rx_resources(priv); + rtl8xxxu_free_tx_resources(priv); +} + +static int rtl8xxxu_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + + mutex_lock(&priv->sta_mutex); + ewma_rssi_init(&sta_info->avg_rssi); + if (vif->type == NL80211_IFTYPE_AP) { + sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT; + sta_info->macid = rtl8xxxu_acquire_macid(priv); + if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM) { + mutex_unlock(&priv->sta_mutex); + return -ENOSPC; + } + + rtl8xxxu_refresh_rate_mask(priv, 0, sta, true); + priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true); + } else { + switch (rtlvif->port_num) { + case 0: + sta_info->macid = RTL8XXXU_BC_MC_MACID; + break; + case 1: + sta_info->macid = RTL8XXXU_BC_MC_MACID1; + break; + default: + break; + } + } + mutex_unlock(&priv->sta_mutex); + + return 0; +} + +static int rtl8xxxu_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + + mutex_lock(&priv->sta_mutex); + if (vif->type == NL80211_IFTYPE_AP) + rtl8xxxu_release_macid(priv, sta_info->macid); + mutex_unlock(&priv->sta_mutex); + + return 0; +} + +static const struct ieee80211_ops rtl8xxxu_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .tx = rtl8xxxu_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .add_interface = rtl8xxxu_add_interface, + .remove_interface = rtl8xxxu_remove_interface, + .config = rtl8xxxu_config, + .conf_tx = rtl8xxxu_conf_tx, + .bss_info_changed = rtl8xxxu_bss_info_changed, + .start_ap = rtl8xxxu_start_ap, + .configure_filter = rtl8xxxu_configure_filter, + .set_rts_threshold = rtl8xxxu_set_rts_threshold, + .start = rtl8xxxu_start, + .stop = rtl8xxxu_stop, + .sw_scan_start = rtl8xxxu_sw_scan_start, + .sw_scan_complete = rtl8xxxu_sw_scan_complete, + .set_key = rtl8xxxu_set_key, + .ampdu_action = rtl8xxxu_ampdu_action, + .sta_statistics = rtl8xxxu_sta_statistics, + .get_antenna = rtl8xxxu_get_antenna, + .set_tim = rtl8xxxu_set_tim, + .sta_add = rtl8xxxu_sta_add, + .sta_remove = rtl8xxxu_sta_remove, +}; + +static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv, + struct usb_interface *interface) +{ + struct usb_interface_descriptor *interface_desc; + struct usb_host_interface *host_interface; + struct usb_endpoint_descriptor *endpoint; + struct device *dev = &priv->udev->dev; + int i, j = 0, endpoints; + u8 dir, xtype, num; + int ret = 0; + + host_interface = interface->cur_altsetting; + interface_desc = &host_interface->desc; + endpoints = interface_desc->bNumEndpoints; + + for (i = 0; i < endpoints; i++) { + endpoint = &host_interface->endpoint[i].desc; + + dir = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + num = usb_endpoint_num(endpoint); + xtype = usb_endpoint_type(endpoint); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB) + dev_dbg(dev, + "%s: endpoint: dir %02x, # %02x, type %02x\n", + __func__, dir, num, xtype); + if (usb_endpoint_dir_in(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB) + dev_dbg(dev, "%s: in endpoint num %i\n", + __func__, num); + + if (priv->pipe_in) { + dev_warn(dev, + "%s: Too many IN pipes\n", __func__); + ret = -EINVAL; + goto exit; + } + + priv->pipe_in = usb_rcvbulkpipe(priv->udev, num); + } + + if (usb_endpoint_dir_in(endpoint) && + usb_endpoint_xfer_int(endpoint)) { + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB) + dev_dbg(dev, "%s: interrupt endpoint num %i\n", + __func__, num); + + if (priv->pipe_interrupt) { + dev_warn(dev, "%s: Too many INTERRUPT pipes\n", + __func__); + ret = -EINVAL; + goto exit; + } + + priv->pipe_interrupt = usb_rcvintpipe(priv->udev, num); + } + + if (usb_endpoint_dir_out(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB) + dev_dbg(dev, "%s: out endpoint num %i\n", + __func__, num); + if (j >= RTL8XXXU_OUT_ENDPOINTS) { + dev_warn(dev, + "%s: Too many OUT pipes\n", __func__); + ret = -EINVAL; + goto exit; + } + priv->out_ep[j++] = num; + } + } +exit: + priv->nr_out_eps = j; + return ret; +} + +static void rtl8xxxu_init_led(struct rtl8xxxu_priv *priv) +{ + struct led_classdev *led = &priv->led_cdev; + + if (!priv->fops->led_classdev_brightness_set) + return; + + led->brightness_set_blocking = priv->fops->led_classdev_brightness_set; + + snprintf(priv->led_name, sizeof(priv->led_name), + "rtl8xxxu-usb%s", dev_name(&priv->udev->dev)); + led->name = priv->led_name; + led->max_brightness = RTL8XXXU_HW_LED_CONTROL; + + if (led_classdev_register(&priv->udev->dev, led)) + return; + + priv->led_registered = true; + + led->brightness = led->max_brightness; + priv->fops->led_classdev_brightness_set(led, led->brightness); +} + +static void rtl8xxxu_deinit_led(struct rtl8xxxu_priv *priv) +{ + struct led_classdev *led = &priv->led_cdev; + + if (!priv->led_registered) + return; + + priv->fops->led_classdev_brightness_set(led, LED_OFF); + led_classdev_unregister(led); +} + +static const struct ieee80211_iface_limit rtl8xxxu_limits[] = { + { .max = 2, .types = BIT(NL80211_IFTYPE_STATION), }, + { .max = 1, .types = BIT(NL80211_IFTYPE_AP), }, +}; + +static const struct ieee80211_iface_combination rtl8xxxu_combinations[] = { + { + .limits = rtl8xxxu_limits, + .n_limits = ARRAY_SIZE(rtl8xxxu_limits), + .max_interfaces = 2, + .num_different_channels = 1, + }, +}; + +static int rtl8xxxu_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct rtl8xxxu_priv *priv; + struct ieee80211_hw *hw; + struct usb_device *udev; + struct ieee80211_supported_band *sband; + int ret; + int untested = 1; + + udev = interface_to_usbdev(interface); + + switch (id->idVendor) { + case USB_VENDOR_ID_REALTEK: + switch(id->idProduct) { + case 0x0179: + case 0x1724: + case 0x8176: + case 0x8178: + case 0x817f: + case 0x818b: + case 0xf179: + case 0x8179: + case 0xb711: + case 0xf192: + case 0x2005: + untested = 0; + break; + } + break; + case 0x7392: + if (id->idProduct == 0x7811 || id->idProduct == 0xa611 || id->idProduct == 0xb811) + untested = 0; + break; + case 0x050d: + if (id->idProduct == 0x1004) + untested = 0; + break; + case 0x20f4: + if (id->idProduct == 0x648b) + untested = 0; + break; + case 0x2001: + if (id->idProduct == 0x3308) + untested = 0; + break; + case 0x2357: + if (id->idProduct == 0x0109 || id->idProduct == 0x010c || + id->idProduct == 0x0135) + untested = 0; + break; + case 0x0b05: + if (id->idProduct == 0x18f1) + untested = 0; + break; + default: + break; + } + + if (untested) { + rtl8xxxu_debug |= RTL8XXXU_DEBUG_EFUSE; + dev_info(&udev->dev, + "This Realtek USB WiFi dongle (0x%04x:0x%04x) is untested!\n", + id->idVendor, id->idProduct); + dev_info(&udev->dev, + "Please report results to Jes.Sorensen@gmail.com\n"); + } + + hw = ieee80211_alloc_hw(sizeof(struct rtl8xxxu_priv), &rtl8xxxu_ops); + if (!hw) + return -ENOMEM; + + priv = hw->priv; + priv->hw = hw; + priv->udev = udev; + priv->fops = (struct rtl8xxxu_fileops *)id->driver_info; + mutex_init(&priv->usb_buf_mutex); + mutex_init(&priv->syson_indirect_access_mutex); + mutex_init(&priv->h2c_mutex); + mutex_init(&priv->sta_mutex); + INIT_LIST_HEAD(&priv->tx_urb_free_list); + spin_lock_init(&priv->tx_urb_lock); + INIT_LIST_HEAD(&priv->rx_urb_pending_list); + spin_lock_init(&priv->rx_urb_lock); + INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work); + INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback); + INIT_DELAYED_WORK(&priv->update_beacon_work, rtl8xxxu_update_beacon_work_callback); + skb_queue_head_init(&priv->c2hcmd_queue); + + usb_set_intfdata(interface, hw); + + ret = rtl8xxxu_parse_usb(priv, interface); + if (ret) + goto err_set_intfdata; + + ret = priv->fops->identify_chip(priv); + if (ret) { + dev_err(&udev->dev, "Fatal - failed to identify chip\n"); + goto err_set_intfdata; + } + + hw->wiphy->available_antennas_tx = BIT(priv->tx_paths) - 1; + hw->wiphy->available_antennas_rx = BIT(priv->rx_paths) - 1; + + if (priv->rtl_chip == RTL8188E) + INIT_WORK(&priv->c2hcmd_work, rtl8188e_c2hcmd_callback); + else + INIT_WORK(&priv->c2hcmd_work, rtl8xxxu_c2hcmd_callback); + + ret = priv->fops->read_efuse(priv); + if (ret) { + dev_err(&udev->dev, "Fatal - failed to read EFuse\n"); + goto err_set_intfdata; + } + + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) + rtl8xxxu_dump_efuse(priv); + + ret = priv->fops->parse_efuse(priv); + if (ret) { + dev_err(&udev->dev, "Fatal - failed to parse EFuse\n"); + goto err_set_intfdata; + } + + rtl8xxxu_print_chipinfo(priv); + + ret = priv->fops->load_firmware(priv); + if (ret) { + dev_err(&udev->dev, "Fatal - failed to load firmware\n"); + goto err_set_intfdata; + } + + ret = rtl8xxxu_init_device(hw); + if (ret) + goto err_set_intfdata; + + hw->vif_data_size = sizeof(struct rtl8xxxu_vif); + hw->sta_data_size = sizeof(struct rtl8xxxu_sta_info); + + hw->wiphy->max_scan_ssids = 1; + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + if (priv->fops->max_macid_num) + hw->wiphy->max_ap_assoc_sta = priv->fops->max_macid_num - 1; + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + if (priv->fops->supports_ap) + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); + hw->queues = 4; + + hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; + + if (priv->fops->supports_concurrent) { + hw->wiphy->iface_combinations = rtl8xxxu_combinations; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtl8xxxu_combinations); + } + + sband = &rtl8xxxu_supported_band; + sband->ht_cap.ht_supported = true; + sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + sband->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20; + + if (priv->hw_feature.max_bw >= 40) { + sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; + sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } else { + dev_info(&udev->dev, "hardware doesn't support HT40\n"); + } + + memset(&sband->ht_cap.mcs, 0, sizeof(sband->ht_cap.mcs)); + sband->ht_cap.mcs.rx_mask[0] = 0xff; + sband->ht_cap.mcs.rx_mask[4] = 0x01; + if (priv->rf_paths > 1) + sband->ht_cap.mcs.rx_mask[1] = 0xff; + sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; + + hw->wiphy->rts_threshold = 2347; + + SET_IEEE80211_DEV(priv->hw, &interface->dev); + SET_IEEE80211_PERM_ADDR(hw, priv->mac_addr); + + hw->extra_tx_headroom = priv->fops->tx_desc_size; + ieee80211_hw_set(hw, SIGNAL_DBM); + + /* + * The firmware handles rate control, except for RTL8188EU, + * where we handle the rate control in the driver. + */ + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, MFP_CAPABLE); + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + ret = ieee80211_register_hw(priv->hw); + if (ret) { + dev_err(&udev->dev, "%s: Failed to register: %i\n", + __func__, ret); + goto err_set_intfdata; + } + + rtl8xxxu_init_led(priv); + rtl8xxxu_debugfs_init(priv); + + return 0; + +err_set_intfdata: + usb_set_intfdata(interface, NULL); + + kfree(priv->fw_data); + mutex_destroy(&priv->usb_buf_mutex); + mutex_destroy(&priv->syson_indirect_access_mutex); + mutex_destroy(&priv->h2c_mutex); + + ieee80211_free_hw(hw); + + return ret; +} + +static void rtl8xxxu_disconnect(struct usb_interface *interface) +{ + struct rtl8xxxu_priv *priv; + struct ieee80211_hw *hw; + + hw = usb_get_intfdata(interface); + priv = hw->priv; + + rtl8xxxu_deinit_led(priv); + + ieee80211_unregister_hw(hw); + + priv->fops->power_off(priv); + + usb_set_intfdata(interface, NULL); + + dev_info(&priv->udev->dev, "disconnecting\n"); + + kfree(priv->fw_data); + mutex_destroy(&priv->usb_buf_mutex); + mutex_destroy(&priv->syson_indirect_access_mutex); + mutex_destroy(&priv->h2c_mutex); + + if (priv->udev->state != USB_STATE_NOTATTACHED) { + dev_info(&priv->udev->dev, + "Device still attached, trying to reset\n"); + usb_reset_device(priv->udev); + } + ieee80211_free_hw(hw); +} + +static const struct usb_device_id dev_table[] = { +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8724, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8723au_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1724, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8723au_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x0724, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8723au_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* TP-Link TL-WN822N v4 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* D-Link DWA-131 rev E1, tested by David Patiño */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Tested by Myckel Habets */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xb720, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8723bu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa611, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8723bu_fops}, +/* RTL8188FU */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xf179, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188fu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8179, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* Tested by Hans de Goede - rtl8188etv */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x0179, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* Sitecom rtl8188eus */ +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0076, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* D-Link USB-GO-N150 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3311, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* D-Link DWA-125 REV D1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330f, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* D-Link DWA-123 REV D1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3310, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* D-Link DWA-121 rev B1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* Abocom - Abocom */ +{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8179, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* Elecom WDC-150SU2M */ +{USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4008, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* TP-Link TL-WN722N v2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* TP-Link TL-WN727N v5.21 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0111, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* MERCUSYS MW150US v2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0102, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* ASUS USB-N10 Nano B1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x18f0, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, + /* Edimax EW-7811Un V2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb811, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* Rosewill USB-N150 Nano */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xffef, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8188eu_fops}, +/* RTL8710BU aka RTL8188GU (not to be confused with RTL8188GTVU) */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xb711, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8710bu_fops}, +/* TOTOLINK N150UA V5 / N150UA-B */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x2005, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8710bu_fops}, +/* Comfast CF-826F */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xf192, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +/* Asus USB-N13 rev C1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x18f1, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +/* EDIMAX EW-7722UTn V3 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb722, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x318b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +/* TP-Link TL-WN823N V2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0135, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +/* D-Link AN3U rev. A1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3328, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, +#ifdef CONFIG_RTL8XXXU_UNTESTED +/* Still supported by rtlwifi */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8178, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817f, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x819a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8754, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Tested by Larry Finger */ +{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7811, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Tested by Andrea Merello */ +{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1004, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Tested by Jocelyn Mayer */ +{USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x648b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Tested by Stefano Bravi */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3308, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Currently untested 8188 series devices */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x018a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8191, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8170, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8177, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817d, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817e, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8186, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x317f, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0631, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x094c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1102, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x11f2, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe033, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8189, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9041, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9043, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ba, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1e1e, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x5088, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0052, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x005c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0eb0, 0x9071, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x103c, 0x1629, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3357, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3358, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3359, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0x4902, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2e, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xed17, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x4855, 0x0090, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x4856, 0x0091, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x9846, 0x9041, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0xcdab, 0x8010, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff7, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff9, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffa, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff8, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffb, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffc, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0x1201, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* Currently untested 8192 series devices */ +{USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0950, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x2102, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x2103, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x341f, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe033, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe035, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ab, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0061, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0070, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0077, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016d, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x07aa, 0x0056, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8178, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9021, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0xf001, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x2e2e, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0019, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0020, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3307, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3309, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330d, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x624d, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x4855, 0x0091, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, +/* found in rtl8192eu vendor driver */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* D-Link DWA-131 rev C1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3312, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* TP-Link TL-WN8200ND V2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0126, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UM */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UH */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0104, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +#endif +{ } +}; + +static struct usb_driver rtl8xxxu_driver = { + .name = DRIVER_NAME, + .probe = rtl8xxxu_probe, + .disconnect = rtl8xxxu_disconnect, + .id_table = dev_table, + .no_dynamic_id = 1, + .disable_hub_initiated_lpm = 1, +}; + +MODULE_DEVICE_TABLE(usb, dev_table); + +module_usb_driver(rtl8xxxu_driver); diff --git a/drivers/net/wireless/realtek/rtl8xxxu/regs.h b/drivers/net/wireless/realtek/rtl8xxxu/regs.h new file mode 100644 index 000000000..eafaef143 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/regs.h @@ -0,0 +1,1384 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Register definitions taken from original Realtek rtl8723au driver + */ + +/* 0x0000 ~ 0x00FF System Configuration */ +#define REG_SYS_ISO_CTRL 0x0000 +#define SYS_ISO_MD2PP BIT(0) +#define SYS_ISO_ANALOG_IPS BIT(5) +#define SYS_ISO_DIOR BIT(9) +#define SYS_ISO_PWC_EV25V BIT(14) +#define SYS_ISO_PWC_EV12V BIT(15) + +#define REG_SYS_FUNC 0x0002 +#define SYS_FUNC_BBRSTB BIT(0) +#define SYS_FUNC_BB_GLB_RSTN BIT(1) +#define SYS_FUNC_USBA BIT(2) +#define SYS_FUNC_UPLL BIT(3) +#define SYS_FUNC_USBD BIT(4) +#define SYS_FUNC_DIO_PCIE BIT(5) +#define SYS_FUNC_PCIEA BIT(6) +#define SYS_FUNC_PPLL BIT(7) +#define SYS_FUNC_PCIED BIT(8) +#define SYS_FUNC_DIOE BIT(9) +#define SYS_FUNC_CPU_ENABLE BIT(10) +#define SYS_FUNC_DCORE BIT(11) +#define SYS_FUNC_ELDR BIT(12) +#define SYS_FUNC_DIO_RF BIT(13) +#define SYS_FUNC_HWPDN BIT(14) +#define SYS_FUNC_MREGEN BIT(15) + +#define REG_APS_FSMCO 0x0004 +#define APS_FSMCO_PFM_ALDN BIT(1) +#define APS_FSMCO_PFM_WOWL BIT(3) +#define APS_FSMCO_ENABLE_POWERDOWN BIT(4) +#define APS_FSMCO_MAC_ENABLE BIT(8) +#define APS_FSMCO_MAC_OFF BIT(9) +#define APS_FSMCO_SW_LPS BIT(10) +#define APS_FSMCO_HW_SUSPEND BIT(11) +#define APS_FSMCO_PCIE BIT(12) +#define APS_FSMCO_HOST BIT(14) +#define APS_FSMCO_HW_POWERDOWN BIT(15) +#define APS_FSMCO_WLON_RESET BIT(16) + +#define REG_SYS_CLKR 0x0008 +#define SYS_CLK_ANAD16V_ENABLE BIT(0) +#define SYS_CLK_ANA8M BIT(1) +#define SYS_CLK_MACSLP BIT(4) +#define SYS_CLK_LOADER_ENABLE BIT(5) +#define SYS_CLK_80M_SSC_DISABLE BIT(7) +#define SYS_CLK_80M_SSC_ENABLE_HO BIT(8) +#define SYS_CLK_PHY_SSC_RSTB BIT(9) +#define SYS_CLK_SEC_CLK_ENABLE BIT(10) +#define SYS_CLK_MAC_CLK_ENABLE BIT(11) +#define SYS_CLK_ENABLE BIT(12) +#define SYS_CLK_RING_CLK_ENABLE BIT(13) + +#define REG_9346CR 0x000a +#define EEPROM_BOOT BIT(4) +#define EEPROM_ENABLE BIT(5) + +#define REG_EE_VPD 0x000c +#define REG_AFE_MISC 0x0010 +#define AFE_MISC_WL_XTAL_CTRL BIT(6) + +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_8192E_LDOV12_CTRL 0x0014 +#define REG_SYS_SWR_CTRL2 0x0014 +#define REG_RSV_CTRL 0x001c +#define RSV_CTRL_WLOCK_1C BIT(5) +#define RSV_CTRL_DIS_PRST BIT(6) + +#define REG_RF_CTRL 0x001f +#define RF_ENABLE BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define REG_LDOA15_CTRL 0x0020 +#define LDOA15_ENABLE BIT(0) +#define LDOA15_STANDBY BIT(1) +#define LDOA15_OBUF BIT(2) +#define LDOA15_REG_VOS BIT(3) +#define LDOA15_VOADJ_SHIFT 4 + +#define REG_LDOV12D_CTRL 0x0021 +#define LDOV12D_ENABLE BIT(0) +#define LDOV12D_STANDBY BIT(1) +#define LDOV12D_VADJ_SHIFT 4 + +#define REG_LDOHCI12_CTRL 0x0022 + +#define REG_LPLDO_CTRL 0x0023 +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) + +#define REG_AFE_XTAL_CTRL 0x0024 +#define AFE_XTAL_ENABLE BIT(0) +#define AFE_XTAL_B_SELECT BIT(1) +#define AFE_XTAL_GATE_USB BIT(8) +#define AFE_XTAL_GATE_AFE BIT(11) +#define AFE_XTAL_RF_GATE BIT(14) +#define AFE_XTAL_GATE_DIG BIT(17) +#define AFE_XTAL_BT_GATE BIT(20) + +/* + * 0x0028 is also known as REG_AFE_CTRL2 on 8723bu/8192eu + */ +#define REG_AFE_PLL_CTRL 0x0028 +#define AFE_PLL_ENABLE BIT(0) +#define AFE_PLL_320_ENABLE BIT(1) +#define APE_PLL_FREF_SELECT BIT(2) +#define AFE_PLL_EDGE_SELECT BIT(3) +#define AFE_PLL_WDOGB BIT(4) +#define AFE_PLL_LPF_ENABLE BIT(5) + +#define REG_MAC_PHY_CTRL 0x002c + +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define EFUSE_TRPT BIT(7) + /* 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */ +#define EFUSE_CELL_SEL (BIT(8) | BIT(9)) +#define EFUSE_LDOE25_ENABLE BIT(31) +#define EFUSE_SELECT_MASK 0x0300 +#define EFUSE_WIFI_SELECT 0x0000 +#define EFUSE_BT0_SELECT 0x0100 +#define EFUSE_BT1_SELECT 0x0200 +#define EFUSE_BT2_SELECT 0x0300 + +#define EFUSE_ACCESS_ENABLE 0x69 /* RTL8723 only */ +#define EFUSE_ACCESS_DISABLE 0x00 /* RTL8723 only */ + +#define REG_PWR_DATA 0x0038 +#define PWR_DATA_EEPRPAD_RFE_CTRL_EN BIT(11) + +#define REG_CAL_TIMER 0x003c +#define REG_ACLK_MON 0x003e +#define REG_GPIO_MUXCFG 0x0040 +#define GPIO_MUXCFG_IO_SEL_ENBT BIT(5) +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define GPIO_INTM_EDGE_TRIG_IRQ BIT(9) + +#define REG_LEDCFG0 0x004c +#define LEDCFG0_LED0CM GENMASK(2, 0) +#define LEDCFG0_LED1CM GENMASK(10, 8) +#define LED_MODE_SW_CTRL 0x0 +#define LED_MODE_TX_OR_RX_EVENTS 0x3 +#define LEDCFG0_LED0SV BIT(3) +#define LEDCFG0_LED1SV BIT(11) +#define LED_SW_OFF 0x0 +#define LED_SW_ON 0x1 +#define LEDCFG0_LED0_IO_MODE BIT(7) +#define LEDCFG0_LED1_IO_MODE BIT(15) +#define LED_IO_MODE_OUTPUT 0x0 +#define LED_IO_MODE_INPUT 0x1 +#define LEDCFG0_LED2EN BIT(21) +#define LED_GPIO_DISABLE 0x0 +#define LED_GPIO_ENABLE 0x1 +#define LEDCFG0_DPDT_SELECT BIT(23) +#define REG_LEDCFG1 0x004d +#define LEDCFG1_HW_LED_CONTROL BIT(1) +#define LEDCFG1_LED_DISABLE BIT(7) +#define REG_LEDCFG2 0x004e +#define LEDCFG2_HW_LED_CONTROL BIT(1) +#define LEDCFG2_HW_LED_ENABLE BIT(5) +#define LEDCFG2_SW_LED_DISABLE BIT(3) +#define LEDCFG2_SW_LED_CONTROL BIT(5) +#define LEDCFG2_DPDT_SELECT BIT(7) +#define REG_LEDCFG3 0x004f +#define REG_LEDCFG REG_LEDCFG2 +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */ +#define REG_GPIO_PIN_CTRL_2 0x0060 +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */ +#define REG_GPIO_IO_SEL_2 0x0062 +#define GPIO_IO_SEL_2_GPIO09_INPUT BIT(1) +#define GPIO_IO_SEL_2_GPIO09_IRQ BIT(9) + +/* RTL8723B */ +#define REG_PAD_CTRL1 0x0064 +#define PAD_CTRL1_SW_DPDT_SEL_DATA BIT(0) + +/* RTL8723 only WIFI/BT/GPS Multi-Function control source. */ +#define REG_MULTI_FUNC_CTRL 0x0068 + +#define MULTI_FN_WIFI_HW_PWRDOWN_EN BIT(0) /* Enable GPIO[9] as WiFi HW + powerdown source */ +#define MULTI_FN_WIFI_HW_PWRDOWN_SL BIT(1) /* WiFi HW powerdown polarity + control */ +#define MULTI_WIFI_FUNC_EN BIT(2) /* WiFi function enable */ + +#define MULTI_WIFI_HW_ROF_EN BIT(3) /* Enable GPIO[9] as WiFi RF HW + powerdown source */ +#define MULTI_BT_HW_PWRDOWN_EN BIT(16) /* Enable GPIO[11] as BT HW + powerdown source */ +#define MULTI_BT_HW_PWRDOWN_SL BIT(17) /* BT HW powerdown polarity + control */ +#define MULTI_BT_FUNC_EN BIT(18) /* BT function enable */ +#define MULTI_BT_HW_ROF_EN BIT(19) /* Enable GPIO[11] as BT/GPS + RF HW powerdown source */ +#define MULTI_GPS_HW_PWRDOWN_EN BIT(20) /* Enable GPIO[10] as GPS HW + powerdown source */ +#define MULTI_GPS_HW_PWRDOWN_SL BIT(21) /* GPS HW powerdown polarity + control */ +#define MULTI_GPS_FUNC_EN BIT(22) /* GPS function enable */ + +#define REG_AFE_CTRL4 0x0078 /* 8192eu/8723bu */ +#define REG_LDO_SW_CTRL 0x007c /* 8192eu */ + +#define REG_MCU_FW_DL 0x0080 +#define MCU_FW_DL_ENABLE BIT(0) +#define MCU_FW_DL_READY BIT(1) +#define MCU_FW_DL_CSUM_REPORT BIT(2) +#define MCU_MAC_INIT_READY BIT(3) +#define MCU_BB_INIT_READY BIT(4) +#define MCU_RF_INIT_READY BIT(5) +#define MCU_WINT_INIT_READY BIT(6) +#define MCU_FW_RAM_SEL BIT(7) /* 1: RAM, 0:ROM */ +#define MCU_CP_RESET BIT(23) + +#define REG_HMBOX_EXT_0 0x0088 +#define REG_HMBOX_EXT_1 0x008a +#define REG_HMBOX_EXT_2 0x008c +#define REG_HMBOX_EXT_3 0x008e + +#define REG_RSVD_1 0x0097 + +/* Interrupt registers for 8192e/8723bu/8812 */ +#define REG_HIMR0 0x00b0 +#define IMR0_TXCCK BIT(30) /* TXRPT interrupt when CCX bit + of the packet is set */ +#define IMR0_PSTIMEOUT BIT(29) /* Power Save Time Out Int */ +#define IMR0_GTINT4 BIT(28) /* Set when GTIMER4 expires */ +#define IMR0_GTINT3 BIT(27) /* Set when GTIMER3 expires */ +#define IMR0_TBDER BIT(26) /* Transmit Beacon0 Error */ +#define IMR0_TBDOK BIT(25) /* Transmit Beacon0 OK */ +#define IMR0_TSF_BIT32_TOGGLE BIT(24) /* TSF Timer BIT32 toggle + indication interrupt */ +#define IMR0_BCNDMAINT0 BIT(20) /* Beacon DMA Interrupt 0 */ +#define IMR0_BCNDERR0 BIT(16) /* Beacon Queue DMA Error 0 */ +#define IMR0_HSISR_IND_ON_INT BIT(15) /* HSISR Indicator (HSIMR & + HSISR is true) */ +#define IMR0_BCNDMAINT_E BIT(14) /* Beacon DMA Interrupt + Extension for Win7 */ +#define IMR0_ATIMEND BIT(12) /* CTWidnow End or + ATIM Window End */ +#define IMR0_HISR1_IND_INT BIT(11) /* HISR1 Indicator + (HISR1 & HIMR1 is true) */ +#define IMR0_C2HCMD BIT(10) /* CPU to Host Command INT + Status, Write 1 to clear */ +#define IMR0_CPWM2 BIT(9) /* CPU power Mode exchange INT + Status, Write 1 to clear */ +#define IMR0_CPWM BIT(8) /* CPU power Mode exchange INT + Status, Write 1 to clear */ +#define IMR0_HIGHDOK BIT(7) /* High Queue DMA OK */ +#define IMR0_MGNTDOK BIT(6) /* Management Queue DMA OK */ +#define IMR0_BKDOK BIT(5) /* AC_BK DMA OK */ +#define IMR0_BEDOK BIT(4) /* AC_BE DMA OK */ +#define IMR0_VIDOK BIT(3) /* AC_VI DMA OK */ +#define IMR0_VODOK BIT(2) /* AC_VO DMA OK */ +#define IMR0_RDU BIT(1) /* Rx Descriptor Unavailable */ +#define IMR0_ROK BIT(0) /* Receive DMA OK */ +#define REG_HISR0 0x00b4 +#define REG_HIMR1 0x00b8 +#define IMR1_BCNDMAINT7 BIT(27) /* Beacon DMA Interrupt 7 */ +#define IMR1_BCNDMAINT6 BIT(26) /* Beacon DMA Interrupt 6 */ +#define IMR1_BCNDMAINT5 BIT(25) /* Beacon DMA Interrupt 5 */ +#define IMR1_BCNDMAINT4 BIT(24) /* Beacon DMA Interrupt 4 */ +#define IMR1_BCNDMAINT3 BIT(23) /* Beacon DMA Interrupt 3 */ +#define IMR1_BCNDMAINT2 BIT(22) /* Beacon DMA Interrupt 2 */ +#define IMR1_BCNDMAINT1 BIT(21) /* Beacon DMA Interrupt 1 */ +#define IMR1_BCNDERR7 BIT(20) /* Beacon Queue DMA Err Int 7 */ +#define IMR1_BCNDERR6 BIT(19) /* Beacon Queue DMA Err Int 6 */ +#define IMR1_BCNDERR5 BIT(18) /* Beacon Queue DMA Err Int 5 */ +#define IMR1_BCNDERR4 BIT(17) /* Beacon Queue DMA Err Int 4 */ +#define IMR1_BCNDERR3 BIT(16) /* Beacon Queue DMA Err Int 3 */ +#define IMR1_BCNDERR2 BIT(15) /* Beacon Queue DMA Err Int 2 */ +#define IMR1_BCNDERR1 BIT(14) /* Beacon Queue DMA Err Int 1 */ +#define IMR1_ATIMEND_E BIT(13) /* ATIM Window End Extension + for Win7 */ +#define IMR1_TXERR BIT(11) /* Tx Error Flag Int Status, + write 1 to clear */ +#define IMR1_RXERR BIT(10) /* Rx Error Flag Int Status, + write 1 to clear */ +#define IMR1_TXFOVW BIT(9) /* Transmit FIFO Overflow */ +#define IMR1_RXFOVW BIT(8) /* Receive FIFO Overflow */ +#define REG_HISR1 0x00bc + +/* Host suspend counter on FPGA platform */ +#define REG_HOST_SUSP_CNT 0x00bc +/* Efuse access protection for RTL8723 */ +#define REG_EFUSE_ACCESS 0x00cf +#define REG_BIST_SCAN 0x00d0 +#define REG_BIST_RPT 0x00d4 +#define REG_BIST_ROM_RPT 0x00d8 +#define REG_RSVD_4 0x00dc +#define REG_USB_SIE_INTF 0x00e0 +#define REG_PCIE_MIO_INTF 0x00e4 +#define REG_PCIE_MIO_INTD 0x00e8 +#define REG_HPON_FSM 0x00ec +#define HPON_FSM_BONDING_MASK (BIT(22) | BIT(23)) +#define HPON_FSM_BONDING_1T2R BIT(22) +#define REG_SYS_CFG 0x00f0 +#define SYS_CFG_XCLK_VLD BIT(0) +#define SYS_CFG_ACLK_VLD BIT(1) +#define SYS_CFG_UCLK_VLD BIT(2) +#define SYS_CFG_PCLK_VLD BIT(3) +#define SYS_CFG_PCIRSTB BIT(4) +#define SYS_CFG_V15_VLD BIT(5) +#define SYS_CFG_TRP_B15V_EN BIT(7) +#define SYS_CFG_SW_OFFLOAD_EN BIT(7) /* For chips with IOL support */ +#define SYS_CFG_SIC_IDLE BIT(8) +#define SYS_CFG_BD_MAC2 BIT(9) +#define SYS_CFG_BD_MAC1 BIT(10) +#define SYS_CFG_IC_MACPHY_MODE BIT(11) +#define SYS_CFG_CHIP_VER (BIT(12) | BIT(13) | BIT(14) | BIT(15)) +#define SYS_CFG_BT_FUNC BIT(16) +#define SYS_CFG_VENDOR_ID BIT(19) +#define SYS_CFG_VENDOR_EXT_MASK (BIT(18) | BIT(19)) +#define SYS_CFG_VENDOR_ID_TSMC 0 +#define SYS_CFG_VENDOR_ID_SMIC BIT(18) +#define SYS_CFG_VENDOR_ID_UMC BIT(19) +#define SYS_CFG_PAD_HWPD_IDN BIT(22) +#define SYS_CFG_TRP_VAUX_EN BIT(23) +#define SYS_CFG_TRP_BT_EN BIT(24) +#define SYS_CFG_SPS_LDO_SEL BIT(24) /* 8192eu */ +#define SYS_CFG_BD_PKG_SEL BIT(25) +#define SYS_CFG_BD_HCI_SEL BIT(26) +#define SYS_CFG_TYPE_ID BIT(27) +#define SYS_CFG_RTL_ID BIT(23) /* TestChip ID, + 1:Test(RLE); 0:MP(RL) */ +#define SYS_CFG_SPS_SEL BIT(24) /* 1:LDO regulator mode; + 0:Switching regulator mode*/ +#define SYS_CFG_CHIP_VERSION_MASK 0xf000 /* Bit 12 - 15 */ + +#define REG_GPIO_OUTSTS 0x00f4 /* For RTL8723 only. */ +#define GPIO_EFS_HCI_SEL (BIT(0) | BIT(1)) +#define GPIO_PAD_HCI_SEL (BIT(2) | BIT(3)) +#define GPIO_HCI_SEL (BIT(4) | BIT(5)) +#define GPIO_PKG_SEL_HCI BIT(6) +#define GPIO_FEN_GPS BIT(7) +#define GPIO_FEN_BT BIT(8) +#define GPIO_FEN_WL BIT(9) +#define GPIO_FEN_PCI BIT(10) +#define GPIO_FEN_USB BIT(11) +#define GPIO_BTRF_HWPDN_N BIT(12) +#define GPIO_WLRF_HWPDN_N BIT(13) +#define GPIO_PDN_BT_N BIT(14) +#define GPIO_PDN_GPS_N BIT(15) +#define GPIO_BT_CTL_HWPDN BIT(16) +#define GPIO_GPS_CTL_HWPDN BIT(17) +#define GPIO_PPHY_SUSB BIT(20) +#define GPIO_UPHY_SUSB BIT(21) +#define GPIO_PCI_SUSEN BIT(22) +#define GPIO_USB_SUSEN BIT(23) +#define GPIO_RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) + +#define REG_SYS_CFG2 0x00fc /* 8192eu */ + +/* 0x0100 ~ 0x01FF MACTOP General Configuration */ +#define REG_CR 0x0100 +#define CR_HCI_TXDMA_ENABLE BIT(0) +#define CR_HCI_RXDMA_ENABLE BIT(1) +#define CR_TXDMA_ENABLE BIT(2) +#define CR_RXDMA_ENABLE BIT(3) +#define CR_PROTOCOL_ENABLE BIT(4) +#define CR_SCHEDULE_ENABLE BIT(5) +#define CR_MAC_TX_ENABLE BIT(6) +#define CR_MAC_RX_ENABLE BIT(7) +#define CR_SW_BEACON_ENABLE BIT(8) +#define CR_SECURITY_ENABLE BIT(9) +#define CR_CALTIMER_ENABLE BIT(10) + +/* Media Status Register */ +#define REG_MSR 0x0102 +#define MSR_LINKTYPE_MASK 0x3 +#define MSR_LINKTYPE_NONE 0x0 +#define MSR_LINKTYPE_ADHOC 0x1 +#define MSR_LINKTYPE_STATION 0x2 +#define MSR_LINKTYPE_AP 0x3 + +#define REG_PBP 0x0104 +#define PBP_PAGE_SIZE_RX_SHIFT 0 +#define PBP_PAGE_SIZE_TX_SHIFT 4 +#define PBP_PAGE_SIZE_64 0x0 +#define PBP_PAGE_SIZE_128 0x1 +#define PBP_PAGE_SIZE_256 0x2 +#define PBP_PAGE_SIZE_512 0x3 +#define PBP_PAGE_SIZE_1024 0x4 + +/* 8188eu IOL magic */ +#define REG_PKT_BUF_ACCESS_CTRL 0x0106 +#define PKT_BUF_ACCESS_CTRL_TX 0x69 +#define PKT_BUF_ACCESS_CTRL_RX 0xa5 + +#define REG_TRXDMA_CTRL 0x010c +#define TRXDMA_CTRL_RXDMA_AGG_EN BIT(2) +#define TRXDMA_CTRL_VOQ_SHIFT 4 +#define TRXDMA_CTRL_VIQ_SHIFT 6 +#define TRXDMA_CTRL_BEQ_SHIFT 8 +#define TRXDMA_CTRL_BKQ_SHIFT 10 +#define TRXDMA_CTRL_MGQ_SHIFT 12 +#define TRXDMA_CTRL_HIQ_SHIFT 14 +#define TRXDMA_CTRL_VOQ_SHIFT_8192F 4 +#define TRXDMA_CTRL_VIQ_SHIFT_8192F 7 +#define TRXDMA_CTRL_BEQ_SHIFT_8192F 10 +#define TRXDMA_CTRL_BKQ_SHIFT_8192F 13 +#define TRXDMA_CTRL_MGQ_SHIFT_8192F 16 +#define TRXDMA_CTRL_HIQ_SHIFT_8192F 19 +#define TRXDMA_QUEUE_LOW 1 +#define TRXDMA_QUEUE_NORMAL 2 +#define TRXDMA_QUEUE_HIGH 3 + +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011c +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012c +#define REG_CPWM 0x012f +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTIMR 0x0138 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015c +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017c +/* 8188EU */ +#define REG_32K_CTRL 0x0194 +#define REG_C2HEVT_MSG_NORMAL 0x01a0 +#define C2H_HW_FEATURE_REPORT 0x19 +#define C2H_HW_FEATURE_DUMP 0xfd +/* 8192EU/8723BU/8812 */ +#define REG_C2HEVT_CMD_ID_8723B 0x01ae +#define REG_C2HEVT_CLEAR 0x01af +#define REG_C2HEVT_MSG_TEST 0x01b8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMTHR 0x01c8 +#define REG_HMTFR 0x01cc +#define REG_HMBOX_0 0x01d0 +#define REG_HMBOX_1 0x01d4 +#define REG_HMBOX_2 0x01d8 +#define REG_HMBOX_3 0x01dc + +#define REG_LLT_INIT 0x01e0 +#define LLT_OP_INACTIVE 0x0 +#define LLT_OP_WRITE (0x1 << 30) +#define LLT_OP_READ (0x2 << 30) +#define LLT_OP_MASK (0x3 << 30) + +#define REG_BB_ACCESS_CTRL 0x01e8 +#define REG_BB_ACCESS_DATA 0x01ec + +#define REG_HMBOX_EXT0_8723B 0x01f0 +#define REG_HMBOX_EXT1_8723B 0x01f4 +#define REG_HMBOX_EXT2_8723B 0x01f8 +#define REG_HMBOX_EXT3_8723B 0x01fc + +/* 0x0200 ~ 0x027F TXDMA Configuration */ +#define REG_RQPN 0x0200 +#define RQPN_HI_PQ_SHIFT 0 +#define RQPN_LO_PQ_SHIFT 8 +#define RQPN_PUB_PQ_SHIFT 16 +#define RQPN_LOAD BIT(31) + +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define BIT_BCN_VALID BIT(16) + +#define REG_DWBCN0_CTRL_8188F REG_TDECTRL + +#define REG_TXDMA_OFFSET_CHK 0x020c +#define TXDMA_OFFSET_DROP_DATA_EN BIT(9) +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 +#define RQPN_NPQ_SHIFT 0 +#define RQPN_EPQ_SHIFT 16 + +#define REG_AUTO_LLT 0x0224 +#define AUTO_LLT_INIT_LLT BIT(16) + +#define REG_DWBCN1_CTRL_8723B 0x0228 +#define BIT_SW_BCN_SEL BIT(20) + +/* 0x0280 ~ 0x02FF RXDMA Configuration */ +#define REG_RXDMA_AGG_PG_TH 0x0280 /* 0-7 : USB DMA size bits + 8-14: USB DMA timeout + 15 : Aggregation enable + Only seems to be used + on 8723bu/8192eu */ +#define RXDMA_USB_AGG_ENABLE BIT(31) +#define REG_RXPKT_NUM 0x0284 +#define RXPKT_NUM_RXDMA_IDLE BIT(17) +#define RXPKT_NUM_RW_RELEASE_EN BIT(18) +#define REG_RXDMA_STATUS 0x0288 + +/* Presumably only found on newer chips such as 8723bu */ +#define REG_RX_DMA_CTRL_8723B 0x0286 +#define REG_RXDMA_PRO_8723B 0x0290 +#define RXDMA_PRO_DMA_MODE BIT(1) /* Set to 0x1. */ +#define RXDMA_PRO_DMA_BURST_CNT GENMASK(3, 2) /* Set to 0x3. */ +#define RXDMA_PRO_DMA_BURST_SIZE GENMASK(5, 4) /* Set to 0x1. */ + +#define REG_EARLY_MODE_CONTROL_8710B 0x02bc + +#define REG_RF_BB_CMD_ADDR 0x02c0 +#define REG_RF_BB_CMD_DATA 0x02c4 + +/* spec version 11 */ +/* 0x0400 ~ 0x047F Protocol Configuration */ +/* 8192c, 8192d */ +#define REG_VOQ_INFO 0x0400 +#define REG_VIQ_INFO 0x0404 +#define REG_BEQ_INFO 0x0408 +#define REG_BKQ_INFO 0x040c +/* 8188e, 8723a, 8812a, 8821a, 8192e, 8723b */ +#define REG_Q0_INFO 0x400 +#define REG_Q1_INFO 0x404 +#define REG_Q2_INFO 0x408 +#define REG_Q3_INFO 0x40c + +#define REG_MGQ_INFO 0x0410 +#define REG_HGQ_INFO 0x0414 +#define REG_BCNQ_INFO 0x0418 + +#define REG_CPU_MGQ_INFORMATION 0x041c +#define REG_FWHW_TXQ_CTRL 0x0420 +#define FWHW_TXQ_CTRL_AMPDU_RETRY BIT(7) +#define FWHW_TXQ_CTRL_XMIT_MGMT_ACK BIT(12) +#define EN_BCNQ_DL BIT(22) + +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_LIFETIME_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 + +#define REG_SPEC_SIFS 0x0428 +#define SPEC_SIFS_CCK_MASK 0x00ff +#define SPEC_SIFS_CCK_SHIFT 0 +#define SPEC_SIFS_OFDM_MASK 0xff00 +#define SPEC_SIFS_OFDM_SHIFT 8 + +#define REG_RETRY_LIMIT 0x042a +#define RETRY_LIMIT_LONG_SHIFT 0 +#define RETRY_LIMIT_LONG_MASK 0x003f +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_SHORT_MASK 0x3f00 + +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RESPONSE_RATE_SET 0x0440 +#define RESPONSE_RATE_BITMAP_ALL 0xfffff +#define RESPONSE_RATE_RRSR_CCK_ONLY_1M 0xffff1 +#define RESPONSE_RATE_RRSR_INIT_2G 0x15f +#define RESPONSE_RATE_RRSR_INIT_5G 0x150 +#define RSR_1M BIT(0) +#define RSR_2M BIT(1) +#define RSR_5_5M BIT(2) +#define RSR_11M BIT(3) +#define RSR_6M BIT(4) +#define RSR_9M BIT(5) +#define RSR_12M BIT(6) +#define RSR_18M BIT(7) +#define RSR_24M BIT(8) +#define RSR_36M BIT(9) +#define RSR_48M BIT(10) +#define RSR_54M BIT(11) +#define RSR_MCS0 BIT(12) +#define RSR_MCS1 BIT(13) +#define RSR_MCS2 BIT(14) +#define RSR_MCS3 BIT(15) +#define RSR_MCS4 BIT(16) +#define RSR_MCS5 BIT(17) +#define RSR_MCS6 BIT(18) +#define RSR_MCS7 BIT(19) +#define RSR_RSC_LOWER_SUB_CHANNEL BIT(21) /* 0x200000 */ +#define RSR_RSC_UPPER_SUB_CHANNEL BIT(22) /* 0x400000 */ +#define RSR_RSC_BANDWIDTH_40M (RSR_RSC_UPPER_SUB_CHANNEL | \ + RSR_RSC_LOWER_SUB_CHANNEL) +#define RSR_ACK_SHORT_PREAMBLE BIT(23) + +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044c +#define REG_ARFR3 0x0450 +#define REG_CCK_CHECK 0x0454 +#define BIT_BCN_PORT_SEL BIT(5) +#define REG_AMPDU_MAX_TIME_8723B 0x0456 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045c +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045d +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +/* 8723bu */ +#define REG_DATA_SUBCHANNEL 0x0483 +/* 8723au */ +#define REG_INIDATA_RATE_SEL 0x0484 +/* MACID_SLEEP_1/3 for 8723b, 8192e, 8812a, 8821a */ +#define REG_MACID_SLEEP_3_8732B 0x0484 +#define REG_MACID_SLEEP_1_8732B 0x0488 + +#define REG_POWER_STATUS 0x04a4 +#define REG_POWER_STAGE1 0x04b4 +#define REG_POWER_STAGE2 0x04b8 +#define REG_AMPDU_BURST_MODE_8723B 0x04bc +#define REG_PKT_VO_VI_LIFE_TIME 0x04c0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04c2 +#define REG_STBC_SETTING 0x04c4 +#define REG_QUEUE_CTRL 0x04c6 +#define REG_HT_SINGLE_AMPDU_8723B 0x04c7 +#define HT_SINGLE_AMPDU_ENABLE BIT(7) +#define REG_PROT_MODE_CTRL 0x04c8 +#define REG_MAX_AGGR_NUM 0x04ca +#define REG_RTS_MAX_AGGR_NUM 0x04cb +#define REG_BAR_MODE_CTRL 0x04cc +#define REG_RA_TRY_RATE_AGG_LMT 0x04cf +/* MACID_DROP for 8723a */ +#define REG_MACID_DROP_8732A 0x04d0 +/* EARLY_MODE_CONTROL 8188e */ +#define REG_EARLY_MODE_CONTROL_8188E 0x04d0 +/* MACID_SLEEP_2 for 8723b, 8192e, 8812a, 8821a */ +#define REG_MACID_SLEEP_2_8732B 0x04d0 +#define REG_MACID_SLEEP 0x04d4 +#define REG_NQOS_SEQ 0x04dc +#define REG_QOS_SEQ 0x04de +#define REG_NEED_CPU_HANDLE 0x04e0 +#define REG_PKT_LOSE_RPT 0x04e1 +#define REG_PTCL_ERR_STATUS 0x04e2 +#define REG_TX_REPORT_CTRL 0x04ec +#define TX_REPORT_CTRL_TIMER_ENABLE BIT(1) + +#define REG_TX_REPORT_TIME 0x04f0 +#define REG_DUMMY 0x04fc + +/* 0x0500 ~ 0x05FF EDCA Configuration */ +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050c +#define EDCA_PARAM_ECW_MIN_SHIFT 8 +#define EDCA_PARAM_ECW_MAX_SHIFT 12 +#define EDCA_PARAM_TXOP_SHIFT 16 +#define REG_BEACON_TCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CCK 0x0514 +#define REG_SIFS_OFDM 0x0516 +#define REG_TSFTR_SYN_OFFSET 0x0518 +#define REG_AGGR_BREAK_TIME 0x051a +#define REG_SLOT 0x051b +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 + +#define REG_BEACON_CTRL 0x0550 +#define REG_BEACON_CTRL_1 0x0551 +#define BEACON_ATIM BIT(0) +#define BEACON_CTRL_MBSSID BIT(1) +#define BEACON_CTRL_TX_BEACON_RPT BIT(2) +#define BEACON_FUNCTION_ENABLE BIT(3) +#define BEACON_DISABLE_TSF_UPDATE BIT(4) + +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define DUAL_TSF_RESET_TSF0 BIT(0) +#define DUAL_TSF_RESET_TSF1 BIT(1) +#define DUAL_TSF_RESET_P2P BIT(4) +#define DUAL_TSF_TX_OK BIT(5) + +/* The same as REG_MBSSID_BCN_SPACE */ +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 + +#define REG_DRIVER_EARLY_INT 0x0558 +#define DRIVER_EARLY_INT_TIME 5 + +#define REG_BEACON_DMA_TIME 0x0559 +#define BEACON_DMA_ATIME_INT_TIME 2 + +#define REG_ATIMWND 0x055a +#define REG_USTIME_TSF_8723B 0x055c +#define REG_BCN_MAX_ERR 0x055d +#define REG_RXTSF_OFFSET_CCK 0x055e +#define REG_RXTSF_OFFSET_OFDM 0x055f +#define REG_TSFTR 0x0560 +#define REG_TSFTR1 0x0568 +#define REG_INIT_TSFTR 0x0564 +#define REG_ATIMWND_1 0x0570 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACM_HW_CTRL 0x05c0 +#define ACM_HW_CTRL_BK BIT(0) +#define ACM_HW_CTRL_BE BIT(1) +#define ACM_HW_CTRL_VI BIT(2) +#define ACM_HW_CTRL_VO BIT(3) +#define REG_ACM_RST_CTRL 0x05c1 +#define REG_ACMAVG 0x05c2 +#define REG_VO_ADMTIME 0x05c4 +#define REG_VI_ADMTIME 0x05c6 +#define REG_BE_ADMTIME 0x05c8 +#define REG_EDCA_RANDOM_GEN 0x05cc +#define REG_SCH_TXCMD 0x05d0 + +/* define REG_FW_TSF_SYNC_CNT 0x04a0 */ +#define REG_SCH_TX_CMD 0x05f8 +#define REG_FW_RESET_TSF_CNT_1 0x05fc +#define REG_FW_RESET_TSF_CNT_0 0x05fd +#define REG_FW_BCN_DIS_CNT 0x05fe + +/* 0x0600 ~ 0x07FF WMAC Configuration */ +#define REG_APSD_CTRL 0x0600 +#define APSD_CTRL_OFF BIT(6) +#define APSD_CTRL_OFF_STATUS BIT(7) +#define REG_BW_OPMODE 0x0603 +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define REG_TCR 0x0604 + +/* Receive Configuration Register */ +#define REG_RCR 0x0608 +#define RCR_ACCEPT_AP BIT(0) /* Accept all unicast packet */ +#define RCR_ACCEPT_PHYS_MATCH BIT(1) /* Accept phys match packet */ +#define RCR_ACCEPT_MCAST BIT(2) +#define RCR_ACCEPT_BCAST BIT(3) +#define RCR_ACCEPT_ADDR3 BIT(4) /* Accept address 3 match + packet */ +#define RCR_ACCEPT_PM BIT(5) /* Accept power management + packet */ +#define RCR_CHECK_BSSID_MATCH BIT(6) /* Accept BSSID match packet */ +#define RCR_CHECK_BSSID_BEACON BIT(7) /* Accept BSSID match packet + (Rx beacon, probe rsp) */ +#define RCR_ACCEPT_CRC32 BIT(8) /* Accept CRC32 error packet */ +#define RCR_ACCEPT_ICV BIT(9) /* Accept ICV error packet */ +#define RCR_ACCEPT_DATA_FRAME BIT(11) /* Accept all data pkt or use + REG_RXFLTMAP2 */ +#define RCR_ACCEPT_CTRL_FRAME BIT(12) /* Accept all control pkt or use + REG_RXFLTMAP1 */ +#define RCR_ACCEPT_MGMT_FRAME BIT(13) /* Accept all mgmt pkt or use + REG_RXFLTMAP0 */ +#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */ +#define RCR_UC_DATA_PKT_INT_ENABLE BIT(16) /* Enable unicast data packet + interrupt */ +#define RCR_BM_DATA_PKT_INT_ENABLE BIT(17) /* Enable broadcast data packet + interrupt */ +#define RCR_TIM_PARSER_ENABLE BIT(18) /* Enable RX beacon TIM parser*/ +#define RCR_MFBEN BIT(22) +#define RCR_LSIG_ENABLE BIT(23) /* Enable LSIG TXOP Protection + function. Search KEYCAM for + each rx packet to check if + LSIGEN bit is set. */ +#define RCR_MULTI_BSSID_ENABLE BIT(24) /* Enable Multiple BssId */ +#define RCR_FORCE_ACK BIT(26) +#define RCR_ACCEPT_BA_SSN BIT(27) /* Accept BA SSN */ +#define RCR_APPEND_PHYSTAT BIT(28) +#define RCR_APPEND_ICV BIT(29) +#define RCR_APPEND_MIC BIT(30) +#define RCR_APPEND_FCS BIT(31) /* WMAC append FCS after */ + +#define REG_RX_PKT_LIMIT 0x060c +#define REG_RX_DLK_TIME 0x060d +#define REG_RX_DRVINFO_SZ 0x060f + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063a + +/* 20100719 Joseph: Hardware register definition change. (HW datasheet v54) */ + /* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ +#define REG_R2T_SIFS 0x063c + /* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ +#define REG_T2T_SIFS 0x063e +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +/* WMA, BA, CCX */ +#define REG_NAV_CTRL 0x0650 +/* In units of 128us */ +#define REG_NAV_UPPER 0x0652 +#define NAV_UPPER_UNIT 128 + +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 +#define WMAC_TRXPTCL_CTL_BW_MASK (BIT(7) | BIT(8)) +#define WMAC_TRXPTCL_CTL_BW_20 0 +#define WMAC_TRXPTCL_CTL_BW_40 BIT(7) +#define WMAC_TRXPTCL_CTL_BW_80 BIT(8) + +/* Security */ +#define REG_CAM_CMD 0x0670 +#define CAM_CMD_POLLING BIT(31) +#define CAM_CMD_WRITE BIT(16) +#define CAM_CMD_KEY_SHIFT 3 +#define REG_CAM_WRITE 0x0674 +#define CAM_WRITE_VALID BIT(15) +#define REG_CAM_READ 0x0678 +#define REG_CAM_DEBUG 0x067c +#define REG_SECURITY_CFG 0x0680 +#define SEC_CFG_TX_USE_DEFKEY BIT(0) +#define SEC_CFG_RX_USE_DEFKEY BIT(1) +#define SEC_CFG_TX_SEC_ENABLE BIT(2) +#define SEC_CFG_RX_SEC_ENABLE BIT(3) +#define SEC_CFG_SKBYA2 BIT(4) +#define SEC_CFG_NO_SKMC BIT(5) +#define SEC_CFG_TXBC_USE_DEFKEY BIT(6) +#define SEC_CFG_RXBC_USE_DEFKEY BIT(7) + +/* Power */ +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069c + +/* + * RX Filters: each bit corresponds to the numerical value of the subtype. + * If it is set the subtype frame type is passed. The filter is only used when + * the RCR_ACCEPT_DATA_FRAME, RCR_ACCEPT_CTRL_FRAME, RCR_ACCEPT_MGMT_FRAME bit + * in the RCR are low. + * + * Example: Beacon subtype is binary 1000 which is decimal 8 so we have to set + * bit 8 (0x100) in REG_RXFLTMAP0 to enable reception. + */ +#define REG_RXFLTMAP0 0x06a0 /* Management frames */ +#define REG_RXFLTMAP1 0x06a2 /* Control frames */ +#define REG_RXFLTMAP2 0x06a4 /* Data frames */ + +#define REG_BCN_PSR_RPT 0x06a8 +#define REG_CALB32K_CTRL 0x06ac +#define REG_PKT_MON_CTRL 0x06b4 +#define REG_BT_COEX_TABLE1 0x06c0 +#define REG_BT_COEX_TABLE2 0x06c4 +#define REG_BT_COEX_TABLE3 0x06c8 +#define REG_BT_COEX_TABLE4 0x06cc +#define REG_WMAC_RESP_TXINFO 0x06d8 + +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 + +/* + * This seems to be 8723bu specific + */ +#define REG_BT_CONTROL_8723BU 0x0764 +#define BT_CONTROL_BT_GRANT BIT(12) + +#define REG_PORT_CONTROL_8710B 0x076d +#define REG_WLAN_ACT_CONTROL_8723B 0x076e + +#define REG_FPGA0_RF_MODE 0x0800 +#define FPGA_RF_MODE BIT(0) +#define FPGA_RF_MODE_JAPAN BIT(1) +#define FPGA_RF_MODE_CCK BIT(24) +#define FPGA_RF_MODE_OFDM BIT(25) + +#define REG_FPGA0_TX_INFO 0x0804 +#define FPGA0_TX_INFO_OFDM_PATH_A BIT(0) +#define FPGA0_TX_INFO_OFDM_PATH_B BIT(1) +#define FPGA0_TX_INFO_OFDM_PATH_C BIT(2) +#define FPGA0_TX_INFO_OFDM_PATH_D BIT(3) +#define REG_FPGA0_PSD_FUNC 0x0808 +#define REG_FPGA0_TX_GAIN 0x080c +#define REG_FPGA0_RF_TIMING1 0x0810 +#define REG_FPGA0_RF_TIMING2 0x0814 +#define REG_FPGA0_POWER_SAVE 0x0818 +#define FPGA0_PS_LOWER_CHANNEL BIT(26) +#define FPGA0_PS_UPPER_CHANNEL BIT(27) + +#define REG_FPGA0_XA_HSSI_PARM1 0x0820 /* RF 3 wire register */ +#define FPGA0_HSSI_PARM1_PI BIT(8) +#define REG_FPGA0_XA_HSSI_PARM2 0x0824 +#define REG_FPGA0_XB_HSSI_PARM1 0x0828 +#define REG_FPGA0_XB_HSSI_PARM2 0x082c +#define FPGA0_HSSI_3WIRE_DATA_LEN 0x800 +#define FPGA0_HSSI_3WIRE_ADDR_LEN 0x400 +#define FPGA0_HSSI_PARM2_ADDR_SHIFT 23 +#define FPGA0_HSSI_PARM2_ADDR_MASK 0x7f800000 /* 0xff << 23 */ +#define FPGA0_HSSI_PARM2_CCK_HIGH_PWR BIT(9) +#define FPGA0_HSSI_PARM2_EDGE_READ BIT(31) + +#define REG_TX_AGC_B_RATE18_06 0x0830 +#define REG_TX_AGC_B_RATE54_24 0x0834 +#define REG_TX_AGC_B_CCK1_55_MCS32 0x0838 +#define REG_TX_AGC_B_MCS03_MCS00 0x083c + +#define REG_FPGA0_XA_LSSI_PARM 0x0840 +#define REG_FPGA0_XB_LSSI_PARM 0x0844 +#define FPGA0_LSSI_PARM_ADDR_SHIFT 20 +#define FPGA0_LSSI_PARM_ADDR_MASK 0x0ff00000 +#define FPGA0_LSSI_PARM_DATA_MASK 0x000fffff + +#define REG_TX_AGC_B_MCS07_MCS04 0x0848 +#define REG_TX_AGC_B_MCS11_MCS08 0x084c + +#define REG_FPGA0_XCD_SWITCH_CTRL 0x085c + +#define REG_FPGA0_XA_RF_INT_OE 0x0860 /* RF Channel switch */ +#define REG_FPGA0_XB_RF_INT_OE 0x0864 +#define FPGA0_INT_OE_ANTENNA_AB_OPEN 0x000 +#define FPGA0_INT_OE_ANTENNA_A BIT(8) +#define FPGA0_INT_OE_ANTENNA_B BIT(9) +#define FPGA0_INT_OE_ANTENNA_MASK (FPGA0_INT_OE_ANTENNA_A | \ + FPGA0_INT_OE_ANTENNA_B) + +#define REG_TX_AGC_B_MCS15_MCS12 0x0868 +#define REG_TX_AGC_B_CCK11_A_CCK2_11 0x086c + +#define REG_FPGA0_XAB_RF_SW_CTRL 0x0870 +#define REG_FPGA0_XA_RF_SW_CTRL 0x0870 /* 16 bit */ +#define REG_FPGA0_XB_RF_SW_CTRL 0x0872 /* 16 bit */ +#define REG_FPGA0_XCD_RF_SW_CTRL 0x0874 +#define REG_FPGA0_XC_RF_SW_CTRL 0x0874 /* 16 bit */ +#define REG_FPGA0_XD_RF_SW_CTRL 0x0876 /* 16 bit */ +#define FPGA0_RF_3WIRE_DATA BIT(0) +#define FPGA0_RF_3WIRE_CLOC BIT(1) +#define FPGA0_RF_3WIRE_LOAD BIT(2) +#define FPGA0_RF_3WIRE_RW BIT(3) +#define FPGA0_RF_3WIRE_MASK 0xf +#define FPGA0_RF_RFENV BIT(4) +#define FPGA0_RF_TRSW BIT(5) /* Useless now */ +#define FPGA0_RF_TRSWB BIT(6) +#define FPGA0_RF_ANTSW BIT(8) +#define FPGA0_RF_ANTSWB BIT(9) +#define FPGA0_RF_PAPE BIT(10) +#define FPGA0_RF_PAPE5G BIT(11) +#define FPGA0_RF_BD_CTRL_SHIFT 16 + +#define REG_FPGA0_XAB_RF_PARM 0x0878 /* Antenna select path in ODM */ +#define REG_FPGA0_XA_RF_PARM 0x0878 /* 16 bit */ +#define REG_FPGA0_XB_RF_PARM 0x087a /* 16 bit */ +#define REG_FPGA0_XCD_RF_PARM 0x087c +#define REG_FPGA0_XC_RF_PARM 0x087c /* 16 bit */ +#define REG_FPGA0_XD_RF_PARM 0x087e /* 16 bit */ +#define FPGA0_RF_PARM_RFA_ENABLE BIT(1) +#define FPGA0_RF_PARM_RFB_ENABLE BIT(17) +#define FPGA0_RF_PARM_CLK_GATE BIT(31) + +#define REG_FPGA0_ANALOG1 0x0880 +#define REG_FPGA0_ANALOG2 0x0884 +#define FPGA0_ANALOG2_20MHZ BIT(10) +#define REG_FPGA0_ANALOG3 0x0888 +#define REG_FPGA0_ANALOG4 0x088c + +#define REG_NHM_TH9_TH10_8723B 0x0890 +#define REG_NHM_TIMER_8723B 0x0894 +#define REG_NHM_TH3_TO_TH0_8723B 0x0898 +#define REG_NHM_TH7_TO_TH4_8723B 0x089c + +#define REG_FPGA0_XA_LSSI_READBACK 0x08a0 /* Tranceiver LSSI Readback */ +#define REG_FPGA0_XB_LSSI_READBACK 0x08a4 +#define REG_FPGA0_PSD_REPORT 0x08b4 +#define REG_HSPI_XA_READBACK 0x08b8 /* Transceiver A HSPI read */ +#define REG_HSPI_XB_READBACK 0x08bc /* Transceiver B HSPI read */ + +#define REG_FPGA1_RF_MODE 0x0900 + +#define REG_FPGA1_TX_INFO 0x090c +#define FPGA1_TX_ANT_MASK 0x0000000f +#define FPGA1_TX_ANT_L_MASK 0x000000f0 +#define FPGA1_TX_ANT_NON_HT_MASK 0x00000f00 +#define FPGA1_TX_ANT_HT1_MASK 0x0000f000 +#define FPGA1_TX_ANT_HT2_MASK 0x000f0000 +#define FPGA1_TX_ANT_HT_S1_MASK 0x00f00000 +#define FPGA1_TX_ANT_NON_HT_S1_MASK 0x0f000000 +#define FPGA1_TX_OFDM_TXSC_MASK 0x30000000 + +#define REG_ANT_MAPPING1 0x0914 +#define REG_RFE_OPT 0x0920 +#define REG_DPDT_CTRL 0x092c /* 8723BU */ +#define REG_RFE_CTRL_ANTA_SRC 0x0930 /* 8723BU */ +#define REG_RFE_CTRL_ANT_SRC1 0x0934 +#define REG_RFE_CTRL_ANT_SRC2 0x0938 +#define REG_RFE_CTRL_ANT_SRC3 0x093c +#define REG_RFE_PATH_SELECT 0x0940 /* 8723BU */ +#define REG_RFE_BUFFER 0x0944 /* 8723BU */ +#define REG_S0S1_PATH_SWITCH 0x0948 /* 8723BU */ +#define REG_RX_DFIR_MOD_97F 0x0948 +#define REG_OFDM_RX_DFIR 0x954 +#define REG_RFE_OPT62 0x0968 + +#define REG_CCK0_SYSTEM 0x0a00 +#define CCK0_SIDEBAND BIT(4) + +#define REG_CCK0_AFE_SETTING 0x0a04 +#define CCK0_AFE_RX_MASK 0x0f000000 +#define CCK0_AFE_TX_MASK 0xf0000000 +#define CCK0_AFE_RX_ANT_A 0 +#define CCK0_AFE_RX_ANT_B BIT(26) +#define CCK0_AFE_RX_ANT_C BIT(27) +#define CCK0_AFE_RX_ANT_D (BIT(26) | BIT(27)) +#define CCK0_AFE_RX_ANT_OPTION_A 0 +#define CCK0_AFE_RX_ANT_OPTION_B BIT(24) +#define CCK0_AFE_RX_ANT_OPTION_C BIT(25) +#define CCK0_AFE_RX_ANT_OPTION_D (BIT(24) | BIT(25)) +#define CCK0_AFE_TX_ANT_A BIT(31) +#define CCK0_AFE_TX_ANT_B BIT(30) + +#define REG_CCK_ANTDIV_PARA2 0x0a04 +#define REG_BB_POWER_SAVE4 0x0a74 + +/* 8188eu */ +#define REG_LNA_SWITCH 0x0b2c +#define LNA_SWITCH_DISABLE_CSCG BIT(22) +#define LNA_SWITCH_OUTPUT_CG BIT(31) + +#define REG_CCK_PD_THRESH 0x0a0a +#define CCK_PD_TYPE1_LV0_TH 0x40 +#define CCK_PD_TYPE1_LV1_TH 0x83 +#define CCK_PD_TYPE1_LV2_TH 0xcd +#define CCK_PD_TYPE1_LV3_TH 0xdd +#define CCK_PD_TYPE1_LV4_TH 0xed + +#define REG_CCK0_TX_FILTER1 0x0a20 +#define REG_CCK0_TX_FILTER2 0x0a24 +#define REG_CCK0_DEBUG_PORT 0x0a28 /* debug port and Tx filter3 */ +#define REG_AGC_RPT 0xa80 +#define AGC_RPT_CCK BIT(7) +#define REG_CCK0_TX_FILTER3 0x0aac + +#define REG_CONFIG_ANT_A 0x0b68 +#define REG_CONFIG_ANT_B 0x0b6c + +#define REG_OFDM0_TRX_PATH_ENABLE 0x0c04 +#define OFDM_RF_PATH_RX_MASK 0x0f +#define OFDM_RF_PATH_RX_A BIT(0) +#define OFDM_RF_PATH_RX_B BIT(1) +#define OFDM_RF_PATH_RX_C BIT(2) +#define OFDM_RF_PATH_RX_D BIT(3) +#define OFDM_RF_PATH_TX_MASK 0xf0 +#define OFDM_RF_PATH_TX_A BIT(4) +#define OFDM_RF_PATH_TX_B BIT(5) +#define OFDM_RF_PATH_TX_C BIT(6) +#define OFDM_RF_PATH_TX_D BIT(7) + +#define REG_OFDM0_TR_MUX_PAR 0x0c08 + +#define REG_OFDM0_FA_RSTC 0x0c0c + +#define REG_DOWNSAM_FACTOR 0x0c10 + +#define REG_OFDM0_XA_RX_AFE 0x0c10 +#define REG_OFDM0_XA_RX_IQ_IMBALANCE 0x0c14 +#define REG_OFDM0_XB_RX_IQ_IMBALANCE 0x0c1c + +#define REG_OFDM0_ENERGY_CCA_THRES 0x0c4c + +#define REG_OFDM0_RX_D_SYNC_PATH 0x0c40 +#define OFDM0_SYNC_PATH_NOTCH_FILTER BIT(1) + +#define REG_OFDM0_XA_AGC_CORE1 0x0c50 +#define REG_OFDM0_XA_AGC_CORE2 0x0c54 +#define REG_OFDM0_XB_AGC_CORE1 0x0c58 +#define REG_OFDM0_XB_AGC_CORE2 0x0c5c +#define REG_OFDM0_XC_AGC_CORE1 0x0c60 +#define REG_OFDM0_XC_AGC_CORE2 0x0c64 +#define REG_OFDM0_XD_AGC_CORE1 0x0c68 +#define REG_OFDM0_XD_AGC_CORE2 0x0c6c +#define OFDM0_X_AGC_CORE1_IGI_MASK 0x0000007F + +#define REG_OFDM0_AGC_PARM1 0x0c70 + +#define REG_OFDM0_AGC_RSSI_TABLE 0x0c78 + +#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80 +#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88 +#define REG_OFDM0_XC_TX_IQ_IMBALANCE 0x0c90 +#define REG_OFDM0_XD_TX_IQ_IMBALANCE 0x0c98 + +#define REG_OFDM0_XC_TX_AFE 0x0c94 +#define REG_OFDM0_XD_TX_AFE 0x0c9c + +#define REG_OFDM0_RX_IQ_EXT_ANTA 0x0ca0 + +/* 8188eu */ +#define REG_ANTDIV_PARA1 0x0ca4 + +#define REG_RXIQB_EXT 0x0ca8 + +/* 8723bu */ +#define REG_OFDM0_TX_PSDO_NOISE_WEIGHT 0x0ce4 + +#define REG_OFDM1_LSTF 0x0d00 +#define OFDM_LSTF_PRIME_CH_LOW BIT(10) +#define OFDM_LSTF_PRIME_CH_HIGH BIT(11) +#define OFDM_LSTF_PRIME_CH_MASK (OFDM_LSTF_PRIME_CH_LOW | \ + OFDM_LSTF_PRIME_CH_HIGH) +#define OFDM_LSTF_CONTINUE_TX BIT(28) +#define OFDM_LSTF_SINGLE_CARRIER BIT(29) +#define OFDM_LSTF_SINGLE_TONE BIT(30) +#define OFDM_LSTF_MASK 0x70000000 + +#define REG_OFDM1_TRX_PATH_ENABLE 0x0d04 +#define REG_OFDM1_CFO_TRACKING 0x0d2c +#define CFO_TRACKING_ATC_STATUS BIT(11) +#define REG_OFDM1_CSI_FIX_MASK1 0x0d40 +#define REG_OFDM1_CSI_FIX_MASK2 0x0d44 + +#define REG_ANAPWR1 0x0d94 + +#define REG_TX_AGC_A_RATE18_06 0x0e00 +#define REG_TX_AGC_A_RATE54_24 0x0e04 +#define REG_TX_AGC_A_CCK1_MCS32 0x0e08 +#define REG_TX_AGC_A_MCS03_MCS00 0x0e10 +#define REG_TX_AGC_A_MCS07_MCS04 0x0e14 +#define REG_TX_AGC_A_MCS11_MCS08 0x0e18 +#define REG_TX_AGC_A_MCS15_MCS12 0x0e1c + +#define REG_NP_ANTA 0x0e20 + +#define REG_TAP_UPD_97F 0x0e24 + +#define REG_FPGA0_IQK 0x0e28 + +#define REG_TX_IQK_TONE_A 0x0e30 +#define REG_RX_IQK_TONE_A 0x0e34 +#define REG_TX_IQK_PI_A 0x0e38 +#define REG_RX_IQK_PI_A 0x0e3c + +#define REG_TX_IQK 0x0e40 +#define REG_RX_IQK 0x0e44 +#define REG_IQK_AGC_PTS 0x0e48 +#define REG_IQK_AGC_RSP 0x0e4c +#define REG_TX_IQK_TONE_B 0x0e50 +#define REG_RX_IQK_TONE_B 0x0e54 +#define REG_TX_IQK_PI_B 0x0e58 +#define REG_RX_IQK_PI_B 0x0e5c +#define REG_IQK_AGC_CONT 0x0e60 + +#define REG_BLUETOOTH 0x0e6c +#define REG_RX_WAIT_CCA 0x0e70 +#define REG_TX_CCK_RFON 0x0e74 +#define REG_TX_CCK_BBON 0x0e78 +#define REG_TX_OFDM_RFON 0x0e7c +#define REG_TX_OFDM_BBON 0x0e80 +#define REG_TX_TO_RX 0x0e84 +#define REG_TX_TO_TX 0x0e88 +#define REG_RX_CCK 0x0e8c + +#define REG_TX_POWER_BEFORE_IQK_A 0x0e94 +#define REG_IQK_RPT_TXA 0x0e98 +#define REG_TX_POWER_AFTER_IQK_A 0x0e9c + +#define REG_RX_POWER_BEFORE_IQK_A 0x0ea0 +#define REG_RX_POWER_BEFORE_IQK_A_2 0x0ea4 +#define REG_RX_POWER_AFTER_IQK_A 0x0ea8 +#define REG_IQK_RPT_RXA 0x0ea8 +#define REG_RX_POWER_AFTER_IQK_A_2 0x0eac + +#define REG_TX_POWER_BEFORE_IQK_B 0x0eb4 +#define REG_IQK_RPT_TXB 0x0eb8 +#define REG_TX_POWER_AFTER_IQK_B 0x0ebc + +#define REG_RX_POWER_BEFORE_IQK_B 0x0ec0 +#define REG_RX_POWER_BEFORE_IQK_B_2 0x0ec4 +#define REG_RX_POWER_AFTER_IQK_B 0x0ec8 +#define REG_IQK_RPT_RXB 0x0ec8 +#define REG_RX_POWER_AFTER_IQK_B_2 0x0ecc + +#define REG_RX_OFDM 0x0ed0 +#define REG_RX_WAIT_RIFS 0x0ed4 +#define REG_RX_TO_RX 0x0ed8 +#define REG_STANDBY 0x0edc +#define REG_SLEEP 0x0ee0 +#define REG_PMPD_ANAEN 0x0eec + +#define REG_FW_START_ADDRESS 0x1000 +#define REG_FW_START_ADDRESS_8192F 0x4000 + +#define REG_SW_GPIO_SHARE_CTRL_0 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_1 0x103c +#define REG_GPIO_A0 0x1050 +#define REG_GPIO_B0 0x105b + +#define REG_USB_INFO 0xfe17 +#define REG_USB_HIMR 0xfe38 +#define USB_HIMR_TIMEOUT2 BIT(31) +#define USB_HIMR_TIMEOUT1 BIT(30) +#define USB_HIMR_PSTIMEOUT BIT(29) +#define USB_HIMR_GTINT4 BIT(28) +#define USB_HIMR_GTINT3 BIT(27) +#define USB_HIMR_TXBCNERR BIT(26) +#define USB_HIMR_TXBCNOK BIT(25) +#define USB_HIMR_TSF_BIT32_TOGGLE BIT(24) +#define USB_HIMR_BCNDMAINT3 BIT(23) +#define USB_HIMR_BCNDMAINT2 BIT(22) +#define USB_HIMR_BCNDMAINT1 BIT(21) +#define USB_HIMR_BCNDMAINT0 BIT(20) +#define USB_HIMR_BCNDOK3 BIT(19) +#define USB_HIMR_BCNDOK2 BIT(18) +#define USB_HIMR_BCNDOK1 BIT(17) +#define USB_HIMR_BCNDOK0 BIT(16) +#define USB_HIMR_HSISR_IND BIT(15) +#define USB_HIMR_BCNDMAINT_E BIT(14) +/* RSVD BIT(13) */ +#define USB_HIMR_CTW_END BIT(12) +/* RSVD BIT(11) */ +#define USB_HIMR_C2HCMD BIT(10) +#define USB_HIMR_CPWM2 BIT(9) +#define USB_HIMR_CPWM BIT(8) +#define USB_HIMR_HIGHDOK BIT(7) /* High Queue DMA OK + Interrupt */ +#define USB_HIMR_MGNTDOK BIT(6) /* Management Queue DMA OK + Interrupt */ +#define USB_HIMR_BKDOK BIT(5) /* AC_BK DMA OK Interrupt */ +#define USB_HIMR_BEDOK BIT(4) /* AC_BE DMA OK Interrupt */ +#define USB_HIMR_VIDOK BIT(3) /* AC_VI DMA OK Interrupt */ +#define USB_HIMR_VODOK BIT(2) /* AC_VO DMA Interrupt */ +#define USB_HIMR_RDU BIT(1) /* Receive Descriptor + Unavailable */ +#define USB_HIMR_ROK BIT(0) /* Receive DMA OK Interrupt */ + +#define REG_USB_ACCESS_TIMEOUT 0xfe4c + +#define REG_USB_SPECIAL_OPTION 0xfe55 +#define USB_SPEC_USB_AGG_ENABLE BIT(3) /* Enable USB aggregation */ +#define USB_SPEC_INT_BULK_SELECT BIT(4) /* Use interrupt endpoint to + deliver interrupt packet. + 0: Use int, 1: use bulk */ +#define REG_USB_HRPWM 0xfe58 +#define REG_USB_DMA_AGG_TO 0xfe5b +#define REG_USB_AGG_TIMEOUT 0xfe5c +#define REG_USB_AGG_THRESH 0xfe5d + +#define REG_NORMAL_SIE_VID 0xfe60 /* 0xfe60 - 0xfe61 */ +#define REG_NORMAL_SIE_PID 0xfe62 /* 0xfe62 - 0xfe63 */ +#define REG_NORMAL_SIE_OPTIONAL 0xfe64 +#define REG_NORMAL_SIE_EP 0xfe65 /* 0xfe65 - 0xfe67 */ +#define REG_NORMAL_SIE_EP_TX 0xfe66 +#define NORMAL_SIE_EP_TX_HIGH_MASK 0x000f +#define NORMAL_SIE_EP_TX_NORMAL_MASK 0x00f0 +#define NORMAL_SIE_EP_TX_LOW_MASK 0x0f00 + +#define REG_NORMAL_SIE_PHY 0xfe68 /* 0xfe68 - 0xfe6b */ +#define REG_NORMAL_SIE_OPTIONAL2 0xfe6c +#define REG_NORMAL_SIE_GPS_EP 0xfe6d /* RTL8723 only */ +#define REG_NORMAL_SIE_MAC_ADDR 0xfe70 /* 0xfe70 - 0xfe75 */ +#define REG_NORMAL_SIE_STRING 0xfe80 /* 0xfe80 - 0xfedf */ + +/* + * 8710B register addresses between 0x00 and 0xff must have 0x8000 + * added to them. We take care of that in the rtl8xxxu_read{8,16,32} + * and rtl8xxxu_write{8,16,32} functions. + */ +#define REG_SYS_FUNC_8710B 0x0004 +#define REG_AFE_CTRL_8710B 0x0050 +#define REG_WL_RF_PSS_8710B 0x005c +#define REG_EFUSE_INDIRECT_CTRL_8710B 0x006c +#define NORMAL_REG_READ_OFFSET 0x83000000 +#define NORMAL_REG_WRITE_OFFSET 0x84000000 +#define EFUSE_READ_OFFSET 0x85000000 +#define EFUSE_WRITE_OFFSET 0x86000000 +#define REG_HIMR0_8710B 0x0080 +#define REG_HISR0_8710B 0x0084 +/* + * 8710B uses this instead of REG_MCU_FW_DL, but at least bits + * 0-7 have the same meaning. + */ +#define REG_8051FW_CTRL_V1_8710B 0x0090 +#define REG_USB_HOST_INDIRECT_DATA_8710B 0x009c +#define REG_WL_STATUS_8710B 0x00f0 +#define REG_USB_HOST_INDIRECT_ADDR_8710B 0x00f8 + +/* + * 8710B registers which must be accessed through rtl8710b_read_syson_reg + * and rtl8710b_write_syson_reg. + */ +#define SYSON_REG_BASE_ADDR_8710B 0x40000000 +#define REG_SYS_XTAL_CTRL0_8710B 0x060 +#define REG_SYS_EEPROM_CTRL0_8710B 0x0e0 +#define REG_SYS_SYSTEM_CFG0_8710B 0x1f0 +#define REG_SYS_SYSTEM_CFG1_8710B 0x1f4 +#define REG_SYS_SYSTEM_CFG2_8710B 0x1f8 + +/* RF6052 registers */ +#define RF6052_REG_AC 0x00 +#define RF6052_REG_IQADJ_G1 0x01 +#define RF6052_REG_IQADJ_G2 0x02 +#define RF6052_REG_BS_PA_APSET_G1_G4 0x03 +#define RF6052_REG_BS_PA_APSET_G5_G8 0x04 +#define RF6052_REG_POW_TRSW 0x05 +#define RF6052_REG_GAIN_RX 0x06 +#define RF6052_REG_GAIN_TX 0x07 +#define RF6052_REG_TXM_IDAC 0x08 +#define RF6052_REG_IPA_G 0x09 +#define RF6052_REG_TXBIAS_G 0x0a +#define RF6052_REG_TXPA_AG 0x0b +#define RF6052_REG_IPA_A 0x0c +#define RF6052_REG_TXBIAS_A 0x0d +#define RF6052_REG_BS_PA_APSET_G9_G11 0x0e +#define RF6052_REG_BS_IQGEN 0x0f +#define RF6052_REG_MODE1 0x10 +#define RF6052_REG_MODE2 0x11 +#define RF6052_REG_RX_AGC_HP 0x12 +#define RF6052_REG_TX_AGC 0x13 +#define RF6052_REG_BIAS 0x14 +#define RF6052_REG_IPA 0x15 +#define RF6052_REG_TXBIAS 0x16 +#define RF6052_REG_POW_ABILITY 0x17 +#define RF6052_REG_MODE_AG 0x18 /* RF channel and BW switch */ +#define MODE_AG_CHANNEL_MASK 0x3ff +#define MODE_AG_CHANNEL_20MHZ BIT(10) +#define MODE_AG_BW_MASK (BIT(10) | BIT(11)) +#define MODE_AG_BW_20MHZ_8723B (BIT(10) | BIT(11)) +#define MODE_AG_BW_40MHZ_8723B BIT(10) +#define MODE_AG_BW_80MHZ_8723B 0 + +#define RF6052_REG_TOP 0x19 +#define RF6052_REG_RX_G1 0x1a +#define RF6052_REG_RX_G2 0x1b +#define RF6052_REG_RX_BB2 0x1c +#define RF6052_REG_RX_BB1 0x1d +#define RF6052_REG_RCK1 0x1e +#define RF6052_REG_RCK2 0x1f +#define RF6052_REG_TX_G1 0x20 +#define RF6052_REG_TX_G2 0x21 +#define RF6052_REG_TX_G3 0x22 +#define RF6052_REG_TX_BB1 0x23 +#define RF6052_REG_T_METER 0x24 +#define RF6052_REG_SYN_G1 0x25 /* RF TX Power control */ +#define RF6052_REG_SYN_G2 0x26 /* RF TX Power control */ +#define RF6052_REG_SYN_G3 0x27 /* RF TX Power control */ +#define RF6052_REG_SYN_G4 0x28 /* RF TX Power control */ +#define RF6052_REG_SYN_G5 0x29 /* RF TX Power control */ +#define RF6052_REG_SYN_G6 0x2a /* RF TX Power control */ +#define RF6052_REG_SYN_G7 0x2b /* RF TX Power control */ +#define RF6052_REG_SYN_G8 0x2c /* RF TX Power control */ + +#define RF6052_REG_RCK_OS 0x30 /* RF TX PA control */ + +#define RF6052_REG_TXPA_G1 0x31 /* RF TX PA control */ +#define RF6052_REG_TXPA_G2 0x32 /* RF TX PA control */ +#define RF6052_REG_TXPA_G3 0x33 /* RF TX PA control */ + +/* + * NextGen regs: 8723BU + */ +#define RF6052_REG_GAIN_P1 0x35 +#define RF6052_REG_T_METER_8723B 0x42 +#define RF6052_REG_UNKNOWN_43 0x43 +#define RF6052_REG_UNKNOWN_55 0x55 +#define RF6052_REG_PAD_TXG 0x56 +#define RF6052_REG_TXMOD 0x58 +#define RF6052_REG_RXG_MIX_SWBW 0x87 +#define RF6052_REG_S0S1 0xb0 +#define RF6052_REG_GAIN_CCA 0xdf +#define RF6052_REG_UNKNOWN_ED 0xed +#define RF6052_REG_WE_LUT 0xef +#define RF6052_REG_GAIN_CTRL 0xf5 diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h new file mode 100644 index 000000000..eeb18eb0e --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -0,0 +1,2181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Register definitions taken from original Realtek rtl8723au driver + */ + +#include +#include +#include + +#define RTL8XXXU_DEBUG_REG_WRITE 0x01 +#define RTL8XXXU_DEBUG_REG_READ 0x02 +#define RTL8XXXU_DEBUG_RFREG_WRITE 0x04 +#define RTL8XXXU_DEBUG_RFREG_READ 0x08 +#define RTL8XXXU_DEBUG_CHANNEL 0x10 +#define RTL8XXXU_DEBUG_TX 0x20 +#define RTL8XXXU_DEBUG_TX_DUMP 0x40 +#define RTL8XXXU_DEBUG_RX 0x80 +#define RTL8XXXU_DEBUG_RX_DUMP 0x100 +#define RTL8XXXU_DEBUG_USB 0x200 +#define RTL8XXXU_DEBUG_KEY 0x400 +#define RTL8XXXU_DEBUG_H2C 0x800 +#define RTL8XXXU_DEBUG_ACTION 0x1000 +#define RTL8XXXU_DEBUG_EFUSE 0x2000 +#define RTL8XXXU_DEBUG_INTERRUPT 0x4000 + +#define RTW_USB_CONTROL_MSG_TIMEOUT 500 +#define RTL8XXXU_MAX_REG_POLL 500 +#define USB_INTR_CONTENT_LENGTH 56 + +#define RTL8XXXU_OUT_ENDPOINTS 6 + +#define REALTEK_USB_READ 0xc0 +#define REALTEK_USB_WRITE 0x40 +#define REALTEK_USB_CMD_REQ 0x05 +#define REALTEK_USB_CMD_IDX 0x00 + +#define TX_TOTAL_PAGE_NUM 0xf8 +#define TX_TOTAL_PAGE_NUM_8188F 0xf7 +#define TX_TOTAL_PAGE_NUM_8188E 0xa9 +#define TX_TOTAL_PAGE_NUM_8192E 0xf3 +#define TX_TOTAL_PAGE_NUM_8723B 0xf7 +#define TX_TOTAL_PAGE_NUM_8192F 0xf7 +/* (HPQ + LPQ + NPQ + PUBQ) = TX_TOTAL_PAGE_NUM */ +#define TX_PAGE_NUM_PUBQ 0xe7 +#define TX_PAGE_NUM_HI_PQ 0x0c +#define TX_PAGE_NUM_LO_PQ 0x02 +#define TX_PAGE_NUM_NORM_PQ 0x02 + +#define TX_PAGE_NUM_PUBQ_8188F 0xe5 +#define TX_PAGE_NUM_HI_PQ_8188F 0x0c +#define TX_PAGE_NUM_LO_PQ_8188F 0x02 +#define TX_PAGE_NUM_NORM_PQ_8188F 0x02 + +#define TX_PAGE_NUM_PUBQ_8188E 0x47 +#define TX_PAGE_NUM_HI_PQ_8188E 0x29 +#define TX_PAGE_NUM_LO_PQ_8188E 0x1c +#define TX_PAGE_NUM_NORM_PQ_8188E 0x1c + +#define TX_PAGE_NUM_PUBQ_8192E 0xe7 +#define TX_PAGE_NUM_HI_PQ_8192E 0x08 +#define TX_PAGE_NUM_LO_PQ_8192E 0x0c +#define TX_PAGE_NUM_NORM_PQ_8192E 0x00 + +#define TX_PAGE_NUM_PUBQ_8723B 0xe7 +#define TX_PAGE_NUM_HI_PQ_8723B 0x0c +#define TX_PAGE_NUM_LO_PQ_8723B 0x02 +#define TX_PAGE_NUM_NORM_PQ_8723B 0x02 + +#define TX_PAGE_NUM_PUBQ_8192F 0xde +#define TX_PAGE_NUM_HI_PQ_8192F 0x08 +#define TX_PAGE_NUM_LO_PQ_8192F 0x08 +#define TX_PAGE_NUM_NORM_PQ_8192F 0x08 + +#define RTL_FW_PAGE_SIZE 4096 +#define RTL8XXXU_FIRMWARE_POLL_MAX 1000 + +#define RTL8723A_CHANNEL_GROUPS 3 +#define RTL8723A_MAX_RF_PATHS 2 +#define RTL8723B_CHANNEL_GROUPS 6 +#define RTL8723B_TX_COUNT 4 +#define RTL8723B_MAX_RF_PATHS 4 +#define RTL8XXXU_MAX_CHANNEL_GROUPS 6 +#define RF6052_MAX_TX_PWR 0x3f + +#define EFUSE_MAP_LEN 512 +#define EFUSE_MAX_SECTION_8723A 64 +#define EFUSE_REAL_CONTENT_LEN_8723A 512 +#define EFUSE_BT_MAP_LEN_8723A 1024 +#define EFUSE_MAX_WORD_UNIT 4 +#define EFUSE_UNDEFINED 0xff + +enum rtl8xxxu_rtl_chip { + RTL8192S = 0x81920, + RTL8191S = 0x81910, + RTL8192C = 0x8192c, + RTL8191C = 0x8191c, + RTL8188C = 0x8188c, + RTL8188R = 0x81889, + RTL8192D = 0x8192d, + RTL8723A = 0x8723a, + RTL8188E = 0x8188e, + RTL8812 = 0x88120, + RTL8821 = 0x88210, + RTL8192E = 0x8192e, + RTL8191E = 0x8191e, + RTL8723B = 0x8723b, + RTL8814A = 0x8814a, + RTL8881A = 0x8881a, + RTL8821B = 0x8821b, + RTL8822B = 0x8822b, + RTL8703B = 0x8703b, + RTL8195A = 0x8195a, + RTL8188F = 0x8188f, + RTL8710B = 0x8710b, + RTL8192F = 0x8192f, +}; + +enum rtl8xxxu_rx_type { + RX_TYPE_DATA_PKT = 0, + RX_TYPE_C2H = 1, + RX_TYPE_ERROR = -1 +}; + +enum rtl8xxxu_rx_desc_enc { + RX_DESC_ENC_NONE = 0, + RX_DESC_ENC_WEP40 = 1, + RX_DESC_ENC_TKIP_WO_MIC = 2, + RX_DESC_ENC_TKIP_MIC = 3, + RX_DESC_ENC_AES = 4, + RX_DESC_ENC_WEP104 = 5, +}; + +struct rtl8xxxu_rxdesc16 { +#ifdef __LITTLE_ENDIAN + u32 pktlen:14; + u32 crc32:1; + u32 icverr:1; + u32 drvinfo_sz:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phy_stats:1; + u32 swdec:1; + u32 ls:1; + u32 fs:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:4; + u32 amsdu:1; + u32 paggr:1; + u32 faggr:1; + u32 a1fit:4; + u32 a2fit:4; + u32 pam:1; + u32 pwr:1; + u32 md:1; + u32 mf:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 pkt_cnt:8; + u32 reserved:6; + u32 nextind:1; + u32 reserved0:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 gf:1; + u32 splcp:1; + u32 bw:1; + u32 htc:1; + u32 eosp:1; + u32 bssidfit:2; + u32 rpt_sel:2; /* 8188e */ + u32 reserved1:14; + u32 unicastwake:1; + u32 magicwake:1; + + u32 pattern0match:1; + u32 pattern1match:1; + u32 pattern2match:1; + u32 pattern3match:1; + u32 pattern4match:1; + u32 pattern5match:1; + u32 pattern6match:1; + u32 pattern7match:1; + u32 pattern8match:1; + u32 pattern9match:1; + u32 patternamatch:1; + u32 patternbmatch:1; + u32 patterncmatch:1; + u32 reserved2:19; +#else + u32 own:1; + u32 eor:1; + u32 fs:1; + u32 ls:1; + u32 swdec:1; + u32 phy_stats:1; + u32 shift:2; + u32 qos:1; + u32 security:3; + u32 drvinfo_sz:4; + u32 icverr:1; + u32 crc32:1; + u32 pktlen:14; + + u32 bc:1; + u32 mc:1; + u32 type:2; + u32 mf:1; + u32 md:1; + u32 pwr:1; + u32 pam:1; + u32 a2fit:4; + u32 a1fit:4; + u32 faggr:1; + u32 paggr:1; + u32 amsdu:1; + u32 hwrsvd:4; + u32 tid:4; + u32 macid:5; + + u32 reserved0:1; + u32 nextind:1; + u32 reserved:6; + u32 pkt_cnt:8; + u32 frag:4; + u32 seq:12; + + u32 magicwake:1; + u32 unicastwake:1; + u32 reserved1:14; + u32 rpt_sel:2; /* 8188e */ + u32 bssidfit:2; + u32 eosp:1; + u32 htc:1; + u32 bw:1; + u32 splcp:1; + u32 gf:1; + u32 rxht:1; + u32 rxmcs:6; + + u32 reserved2:19; + u32 patterncmatch:1; + u32 patternbmatch:1; + u32 patternamatch:1; + u32 pattern9match:1; + u32 pattern8match:1; + u32 pattern7match:1; + u32 pattern6match:1; + u32 pattern5match:1; + u32 pattern4match:1; + u32 pattern3match:1; + u32 pattern2match:1; + u32 pattern1match:1; + u32 pattern0match:1; +#endif + u32 tsfl; +#if 0 + u32 bassn:12; + u32 bavld:1; + u32 reserved3:19; +#endif +}; + +struct rtl8xxxu_rxdesc24 { +#ifdef __LITTLE_ENDIAN + u32 pktlen:14; + u32 crc32:1; + u32 icverr:1; + u32 drvinfo_sz:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phy_stats:1; + u32 swdec:1; + u32 ls:1; + u32 fs:1; + u32 eor:1; + u32 own:1; + + u32 macid:7; + u32 dummy1_0:1; + u32 tid:4; + u32 dummy1_1:1; + u32 amsdu:1; + u32 rxid_match:1; + u32 paggr:1; + u32 a1fit:4; /* 16 */ + u32 chkerr:1; + u32 ipver:1; + u32 tcpudp:1; + u32 chkvld:1; + u32 pam:1; + u32 pwr:1; + u32 more_data:1; + u32 more_frag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 rx_is_qos:1; /* 16 */ + u32 dummy2_0:1; + u32 wlanhd_iv_len:6; + u32 dummy2_1:4; + u32 rpt_sel:1; + u32 dummy2_2:3; + + u32 rxmcs:7; + u32 dummy3_0:3; + u32 htc:1; + u32 eosp:1; + u32 bssidfit:2; + u32 dummy3_1:2; + u32 usb_agg_pktnum:8; /* 16 */ + u32 dummy3_2:5; + u32 pattern_match:1; + u32 unicast_match:1; + u32 magic_match:1; + + u32 splcp:1; + u32 ldcp:1; + u32 stbc:1; + u32 dummy4_0:1; + u32 bw:2; + u32 dummy4_1:26; +#else + u32 own:1; + u32 eor:1; + u32 fs:1; + u32 ls:1; + u32 swdec:1; + u32 phy_stats:1; + u32 shift:2; + u32 qos:1; + u32 security:3; + u32 drvinfo_sz:4; + u32 icverr:1; + u32 crc32:1; + u32 pktlen:14; + + u32 bc:1; + u32 mc:1; + u32 type:2; + u32 mf:1; + u32 md:1; + u32 pwr:1; + u32 pam:1; + u32 a2fit:4; + u32 a1fit:4; + u32 faggr:1; + u32 paggr:1; + u32 amsdu:1; + u32 hwrsvd:4; + u32 tid:4; + u32 macid:5; + + u32 dummy2_2:3; + u32 rpt_sel:1; + u32 dummy2_1:4; + u32 wlanhd_iv_len:6; + u32 dummy2_0:1; + u32 rx_is_qos:1; + u32 frag:4; /* 16 */ + u32 seq:12; + + u32 magic_match:1; + u32 unicast_match:1; + u32 pattern_match:1; + u32 dummy3_2:5; + u32 usb_agg_pktnum:8; + u32 dummy3_1:2; /* 16 */ + u32 bssidfit:2; + u32 eosp:1; + u32 htc:1; + u32 dummy3_0:3; + u32 rxmcs:7; + + u32 dumm4_1:26; + u32 bw:2; + u32 dummy4_0:1; + u32 stbc:1; + u32 ldcp:1; + u32 splcp:1; +#endif + u32 tsfl; +}; + +struct rtl8xxxu_txdesc32 { + __le16 pkt_size; + u8 pkt_offset; + u8 txdw0; + __le32 txdw1; + __le32 txdw2; + __le32 txdw3; + __le32 txdw4; + __le32 txdw5; + __le32 txdw6; + __le16 csum; + __le16 txdw7; +}; + +struct rtl8xxxu_txdesc40 { + __le16 pkt_size; + u8 pkt_offset; + u8 txdw0; + __le32 txdw1; + __le32 txdw2; + __le32 txdw3; + __le32 txdw4; + __le32 txdw5; + __le32 txdw6; + __le16 csum; + __le16 txdw7; + __le32 txdw8; + __le32 txdw9; +}; + +/* CCK Rates, TxHT = 0 */ +#define DESC_RATE_1M 0x00 +#define DESC_RATE_2M 0x01 +#define DESC_RATE_5_5M 0x02 +#define DESC_RATE_11M 0x03 + +/* OFDM Rates, TxHT = 0 */ +#define DESC_RATE_6M 0x04 +#define DESC_RATE_9M 0x05 +#define DESC_RATE_12M 0x06 +#define DESC_RATE_18M 0x07 +#define DESC_RATE_24M 0x08 +#define DESC_RATE_36M 0x09 +#define DESC_RATE_48M 0x0a +#define DESC_RATE_54M 0x0b + +/* MCS Rates, TxHT = 1 */ +#define DESC_RATE_MCS0 0x0c +#define DESC_RATE_MCS1 0x0d +#define DESC_RATE_MCS2 0x0e +#define DESC_RATE_MCS3 0x0f +#define DESC_RATE_MCS4 0x10 +#define DESC_RATE_MCS5 0x11 +#define DESC_RATE_MCS6 0x12 +#define DESC_RATE_MCS7 0x13 +#define DESC_RATE_MCS8 0x14 +#define DESC_RATE_MCS9 0x15 +#define DESC_RATE_MCS10 0x16 +#define DESC_RATE_MCS11 0x17 +#define DESC_RATE_MCS12 0x18 +#define DESC_RATE_MCS13 0x19 +#define DESC_RATE_MCS14 0x1a +#define DESC_RATE_MCS15 0x1b +#define DESC_RATE_MCS15_SG 0x1c +#define DESC_RATE_MCS32 0x20 + +#define TXDESC_OFFSET_SZ 0 +#define TXDESC_OFFSET_SHT 16 +#if 0 +#define TXDESC_BMC BIT(24) +#define TXDESC_LSG BIT(26) +#define TXDESC_FSG BIT(27) +#define TXDESC_OWN BIT(31) +#else +#define TXDESC_BROADMULTICAST BIT(0) +#define TXDESC_HTC BIT(1) +#define TXDESC_LAST_SEGMENT BIT(2) +#define TXDESC_FIRST_SEGMENT BIT(3) +#define TXDESC_LINIP BIT(4) +#define TXDESC_NO_ACM BIT(5) +#define TXDESC_GF BIT(6) +#define TXDESC_OWN BIT(7) +#endif + +/* Word 1 */ +/* + * Bits 0-7 differ dependent on chip generation. For 8723au bits 5/6 are + * aggregation enable and break respectively. For 8723bu, bits 0-7 are macid. + */ +#define TXDESC_PKT_OFFSET_SZ 0 +#define TXDESC32_AGG_ENABLE BIT(5) +#define TXDESC32_AGG_BREAK BIT(6) +#define TXDESC40_MACID_SHIFT 0 +#define TXDESC40_MACID_MASK 0x00f0 +#define TXDESC_QUEUE_SHIFT 8 +#define TXDESC_QUEUE_MASK 0x1f00 +#define TXDESC_QUEUE_BK 0x2 +#define TXDESC_QUEUE_BE 0x0 +#define TXDESC_QUEUE_VI 0x5 +#define TXDESC_QUEUE_VO 0x7 +#define TXDESC_QUEUE_BEACON 0x10 +#define TXDESC_QUEUE_HIGH 0x11 +#define TXDESC_QUEUE_MGNT 0x12 +#define TXDESC_QUEUE_CMD 0x13 +#define TXDESC_QUEUE_MAX (TXDESC_QUEUE_CMD + 1) +#define TXDESC40_RDG_NAV_EXT BIT(13) +#define TXDESC40_LSIG_TXOP_ENABLE BIT(14) +#define TXDESC40_PIFS BIT(15) + +#define DESC_RATE_ID_SHIFT 16 +#define DESC_RATE_ID_MASK 0xf +#define TXDESC_NAVUSEHDR BIT(20) +#define TXDESC_EN_DESC_ID BIT(21) +#define TXDESC_SEC_RC4 0x00400000 +#define TXDESC_SEC_AES 0x00c00000 +#define TXDESC_PKT_OFFSET_SHIFT 26 +#define TXDESC_AGG_EN BIT(29) +#define TXDESC_HWPC BIT(31) + +/* Word 2 */ +#define TXDESC40_PAID_SHIFT 0 +#define TXDESC40_PAID_MASK 0x1ff +#define TXDESC40_CCA_RTS_SHIFT 10 +#define TXDESC40_CCA_RTS_MASK 0xc00 +#define TXDESC40_AGG_ENABLE BIT(12) +#define TXDESC40_RDG_ENABLE BIT(13) +#define TXDESC40_AGG_BREAK BIT(16) +#define TXDESC40_MORE_FRAG BIT(17) +#define TXDESC40_RAW BIT(18) +#define TXDESC32_ACK_REPORT BIT(19) +#define TXDESC40_SPE_RPT BIT(19) +#define TXDESC_AMPDU_DENSITY_SHIFT 20 +#define TXDESC40_BT_INT BIT(23) +#define TXDESC40_GID_SHIFT 24 +#define TXDESC_ANTENNA_SELECT_A BIT(24) +#define TXDESC_ANTENNA_SELECT_B BIT(25) + +/* Word 3 */ +#define TXDESC40_USE_DRIVER_RATE BIT(8) +#define TXDESC40_CTS_SELF_ENABLE BIT(11) +#define TXDESC40_RTS_CTS_ENABLE BIT(12) +#define TXDESC40_HW_RTS_ENABLE BIT(13) +#define TXDESC32_SEQ_SHIFT 16 +#define TXDESC32_SEQ_MASK 0x0fff0000 + +/* Word 4 */ +#define TXDESC32_RTS_RATE_SHIFT 0 +#define TXDESC32_RTS_RATE_MASK 0x3f +#define TXDESC32_QOS BIT(6) +#define TXDESC32_HW_SEQ_ENABLE BIT(7) +#define TXDESC32_USE_DRIVER_RATE BIT(8) +#define TXDESC_DISABLE_DATA_FB BIT(10) +#define TXDESC32_CTS_SELF_ENABLE BIT(11) +#define TXDESC32_RTS_CTS_ENABLE BIT(12) +#define TXDESC32_HW_RTS_ENABLE BIT(13) +#define TXDESC32_PT_STAGE_MASK GENMASK(17, 15) +#define TXDESC_PRIME_CH_OFF_LOWER BIT(20) +#define TXDESC_PRIME_CH_OFF_UPPER BIT(21) +#define TXDESC32_SHORT_PREAMBLE BIT(24) +#define TXDESC_DATA_BW BIT(25) +#define TXDESC_RTS_DATA_BW BIT(27) +#define TXDESC_RTS_PRIME_CH_OFF_LOWER BIT(28) +#define TXDESC_RTS_PRIME_CH_OFF_UPPER BIT(29) +#define TXDESC40_DATA_RATE_FB_SHIFT 8 +#define TXDESC40_DATA_RATE_FB_MASK 0x00001f00 +#define TXDESC40_RETRY_LIMIT_ENABLE BIT(17) +#define TXDESC40_RETRY_LIMIT_SHIFT 18 +#define TXDESC40_RETRY_LIMIT_MASK 0x00fc0000 +#define TXDESC40_RTS_RATE_SHIFT 24 +#define TXDESC40_RTS_RATE_MASK 0x3f000000 + +/* Word 5 */ +#define TXDESC40_SHORT_PREAMBLE BIT(4) +#define TXDESC32_SHORT_GI BIT(6) +#define TXDESC_CCX_TAG BIT(7) +#define TXDESC32_RETRY_LIMIT_ENABLE BIT(17) +#define TXDESC32_RETRY_LIMIT_SHIFT 18 +#define TXDESC32_RETRY_LIMIT_MASK 0x00fc0000 + +/* Word 6 */ +#define TXDESC_MAX_AGG_SHIFT 11 +#define TXDESC_USB_TX_AGG_SHIT 24 + +/* Word 7 */ +#define TXDESC_ANTENNA_SELECT_C BIT(29) + +/* Word 8 */ +#define TXDESC40_HW_SEQ_ENABLE BIT(15) + +/* Word 9 */ +#define TXDESC40_SEQ_SHIFT 12 +#define TXDESC40_SEQ_MASK 0x00fff000 + +struct phy_rx_agc_info { +#ifdef __LITTLE_ENDIAN + u8 gain:7, trsw:1; +#else + u8 trsw:1, gain:7; +#endif +}; + +#define CCK_AGC_RPT_LNA_IDX_MASK GENMASK(7, 5) +#define CCK_AGC_RPT_VGA_IDX_MASK GENMASK(4, 0) + +struct rtl8723au_phy_stats { + struct phy_rx_agc_info path_agc[RTL8723A_MAX_RF_PATHS]; + u8 ch_corr[RTL8723A_MAX_RF_PATHS]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 reserved_1; + u8 noise_power_db_msb; + s8 path_cfotail[RTL8723A_MAX_RF_PATHS]; + u8 pcts_mask[RTL8723A_MAX_RF_PATHS]; + s8 stream_rxevm[RTL8723A_MAX_RF_PATHS]; + u8 path_rxsnr[RTL8723A_MAX_RF_PATHS]; + u8 noise_power_db_lsb; + u8 reserved_2[3]; + u8 stream_csi[RTL8723A_MAX_RF_PATHS]; + u8 stream_target_csi[RTL8723A_MAX_RF_PATHS]; + s8 sig_evm; + u8 reserved_3; + +#ifdef __LITTLE_ENDIAN + u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ + u8 sgi_en:1; + u8 rxsc:2; + u8 idle_long:1; + u8 r_ant_train_en:1; + u8 antenna_select_b:1; + u8 antenna_select:1; +#else /* _BIG_ENDIAN_ */ + u8 antenna_select:1; + u8 antenna_select_b:1; + u8 r_ant_train_en:1; + u8 idle_long:1; + u8 rxsc:2; + u8 sgi_en:1; + u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ +#endif +}; + +struct jaguar2_phy_stats_type0 { + /* DW0 */ + u8 page_num; + u8 pwdb; +#ifdef __LITTLE_ENDIAN + u8 gain: 6; + u8 rsvd_0: 1; + u8 trsw: 1; +#else + u8 trsw: 1; + u8 rsvd_0: 1; + u8 gain: 6; +#endif + u8 rsvd_1; + + /* DW1 */ + u8 rsvd_2; +#ifdef __LITTLE_ENDIAN + u8 rxsc: 4; + u8 agc_table: 4; +#else + u8 agc_table: 4; + u8 rxsc: 4; +#endif + u8 channel; + u8 band; + + /* DW2 */ + u16 length; +#ifdef __LITTLE_ENDIAN + u8 antidx_a: 3; + u8 antidx_b: 3; + u8 rsvd_3: 2; + u8 antidx_c: 3; + u8 antidx_d: 3; + u8 rsvd_4:2; +#else + u8 rsvd_3: 2; + u8 antidx_b: 3; + u8 antidx_a: 3; + u8 rsvd_4:2; + u8 antidx_d: 3; + u8 antidx_c: 3; +#endif + + /* DW3 */ + u8 signal_quality; +#ifdef __LITTLE_ENDIAN + u8 vga:5; + u8 lna_l:3; + u8 bb_power:6; + u8 rsvd_9:1; + u8 lna_h:1; +#else + u8 lna_l:3; + u8 vga:5; + u8 lna_h:1; + u8 rsvd_9:1; + u8 bb_power:6; +#endif + u8 rsvd_5; + + /* DW4 */ + u32 rsvd_6; + + /* DW5 */ + u32 rsvd_7; + + /* DW6 */ + u32 rsvd_8; +} __packed; + +struct jaguar2_phy_stats_type1 { + /* DW0 and DW1 */ + u8 page_num; + u8 pwdb[4]; +#ifdef __LITTLE_ENDIAN + u8 l_rxsc: 4; + u8 ht_rxsc: 4; +#else + u8 ht_rxsc: 4; + u8 l_rxsc: 4; +#endif + u8 channel; +#ifdef __LITTLE_ENDIAN + u8 band: 2; + u8 rsvd_0: 1; + u8 hw_antsw_occu: 1; + u8 gnt_bt: 1; + u8 ldpc: 1; + u8 stbc: 1; + u8 beamformed: 1; +#else + u8 beamformed: 1; + u8 stbc: 1; + u8 ldpc: 1; + u8 gnt_bt: 1; + u8 hw_antsw_occu: 1; + u8 rsvd_0: 1; + u8 band: 2; +#endif + + /* DW2 */ + u16 lsig_length; +#ifdef __LITTLE_ENDIAN + u8 antidx_a: 3; + u8 antidx_b: 3; + u8 rsvd_1: 2; + u8 antidx_c: 3; + u8 antidx_d: 3; + u8 rsvd_2: 2; +#else + u8 rsvd_1: 2; + u8 antidx_b: 3; + u8 antidx_a: 3; + u8 rsvd_2: 2; + u8 antidx_d: 3; + u8 antidx_c: 3; +#endif + + /* DW3 */ + u8 paid; +#ifdef __LITTLE_ENDIAN + u8 paid_msb: 1; + u8 gid: 6; + u8 rsvd_3: 1; +#else + u8 rsvd_3: 1; + u8 gid: 6; + u8 paid_msb: 1; +#endif + u8 intf_pos; +#ifdef __LITTLE_ENDIAN + u8 intf_pos_msb: 1; + u8 rsvd_4: 2; + u8 nb_intf_flag: 1; + u8 rf_mode: 2; + u8 rsvd_5: 2; +#else + u8 rsvd_5: 2; + u8 rf_mode: 2; + u8 nb_intf_flag: 1; + u8 rsvd_4: 2; + u8 intf_pos_msb: 1; +#endif + + /* DW4 */ + s8 rxevm[4]; /* s(8,1) */ + + /* DW5 */ + s8 cfo_tail[4]; /* s(8,7) */ + + /* DW6 */ + s8 rxsnr[4]; /* s(8,1) */ +} __packed; + +struct jaguar2_phy_stats_type2 { + /* DW0 ane DW1 */ + u8 page_num; + u8 pwdb[4]; +#ifdef __LITTLE_ENDIAN + u8 l_rxsc: 4; + u8 ht_rxsc: 4; +#else + u8 ht_rxsc: 4; + u8 l_rxsc: 4; +#endif + u8 channel; +#ifdef __LITTLE_ENDIAN + u8 band: 2; + u8 rsvd_0: 1; + u8 hw_antsw_occu: 1; + u8 gnt_bt: 1; + u8 ldpc: 1; + u8 stbc: 1; + u8 beamformed: 1; +#else + u8 beamformed: 1; + u8 stbc: 1; + u8 ldpc: 1; + u8 gnt_bt: 1; + u8 hw_antsw_occu: 1; + u8 rsvd_0: 1; + u8 band: 2; +#endif + + /* DW2 */ +#ifdef __LITTLE_ENDIAN + u8 shift_l_map: 6; + u8 rsvd_1: 2; +#else + u8 rsvd_1: 2; + u8 shift_l_map: 6; +#endif + u8 cnt_pw2cca; +#ifdef __LITTLE_ENDIAN + u8 agc_table_a: 4; + u8 agc_table_b: 4; + u8 agc_table_c: 4; + u8 agc_table_d: 4; +#else + u8 agc_table_b: 4; + u8 agc_table_a: 4; + u8 agc_table_d: 4; + u8 agc_table_c: 4; +#endif + + /* DW3 ~ DW6*/ + u8 cnt_cca2agc_rdy; +#ifdef __LITTLE_ENDIAN + u8 gain_a: 6; + u8 rsvd_2: 1; + u8 trsw_a: 1; + u8 gain_b: 6; + u8 rsvd_3: 1; + u8 trsw_b: 1; + u8 gain_c: 6; + u8 rsvd_4: 1; + u8 trsw_c: 1; + u8 gain_d: 6; + u8 rsvd_5: 1; + u8 trsw_d: 1; + u8 aagc_step_a: 2; + u8 aagc_step_b: 2; + u8 aagc_step_c: 2; + u8 aagc_step_d: 2; +#else + u8 trsw_a: 1; + u8 rsvd_2: 1; + u8 gain_a: 6; + u8 trsw_b: 1; + u8 rsvd_3: 1; + u8 gain_b: 6; + u8 trsw_c: 1; + u8 rsvd_4: 1; + u8 gain_c: 6; + u8 trsw_d: 1; + u8 rsvd_5: 1; + u8 gain_d: 6; + u8 aagc_step_d: 2; + u8 aagc_step_c: 2; + u8 aagc_step_b: 2; + u8 aagc_step_a: 2; +#endif + u8 ht_aagc_gain[4]; + u8 dagc_gain[4]; +#ifdef __LITTLE_ENDIAN + u8 counter: 6; + u8 rsvd_6: 2; + u8 syn_count: 5; + u8 rsvd_7:3; +#else + u8 rsvd_6: 2; + u8 counter: 6; + u8 rsvd_7:3; + u8 syn_count: 5; +#endif +} __packed; + +/* + * Regs to backup + */ +#define RTL8XXXU_ADDA_REGS 16 +#define RTL8XXXU_MAC_REGS 4 +#define RTL8XXXU_BB_REGS 9 + +struct rtl8xxxu_firmware_header { + __le16 signature; /* 92C0: test chip; 92C, + 88C0: test chip; + 88C1: MP A-cut; + 92C1: MP A-cut */ + u8 category; /* AP/NIC and USB/PCI */ + u8 function; + + __le16 major_version; /* FW Version */ + u8 minor_version; /* FW Subversion, default 0x00 */ + u8 reserved1; + + u8 month; /* Release time Month field */ + u8 date; /* Release time Date field */ + u8 hour; /* Release time Hour field */ + u8 minute; /* Release time Minute field */ + + __le16 ramcodesize; /* Size of RAM code */ + u16 reserved2; + + __le32 svn_idx; /* SVN entry index */ + u32 reserved3; + + u32 reserved4; + u32 reserved5; + + u8 data[]; +}; + +/* + * 8723au/8192cu/8188ru required base power index offset tables. + */ +struct rtl8xxxu_power_base { + u32 reg_0e00; + u32 reg_0e04; + u32 reg_0e08; + u32 reg_086c; + + u32 reg_0e10; + u32 reg_0e14; + u32 reg_0e18; + u32 reg_0e1c; + + u32 reg_0830; + u32 reg_0834; + u32 reg_0838; + u32 reg_086c_2; + + u32 reg_083c; + u32 reg_0848; + u32 reg_084c; + u32 reg_0868; +}; + +/* + * The 8723au has 3 channel groups: 1-3, 4-9, and 10-14 + */ +struct rtl8723au_idx { +#ifdef __LITTLE_ENDIAN + int a:4; + int b:4; +#else + int b:4; + int a:4; +#endif +} __attribute__((packed)); + +struct rtl8723au_efuse { + __le16 rtl_id; + u8 res0[0xe]; + u8 cck_tx_power_index_A[3]; /* 0x10 */ + u8 cck_tx_power_index_B[3]; + u8 ht40_1s_tx_power_index_A[3]; /* 0x16 */ + u8 ht40_1s_tx_power_index_B[3]; + /* + * The following entries are half-bytes split as: + * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed + */ + struct rtl8723au_idx ht20_tx_power_index_diff[3]; + struct rtl8723au_idx ofdm_tx_power_index_diff[3]; + struct rtl8723au_idx ht40_max_power_offset[3]; + struct rtl8723au_idx ht20_max_power_offset[3]; + u8 channel_plan; /* 0x28 */ + u8 tssi_a; + u8 thermal_meter; + u8 rf_regulatory; + u8 rf_option_2; + u8 rf_option_3; + u8 rf_option_4; + u8 res7; + u8 version /* 0x30 */; + u8 customer_id_major; + u8 customer_id_minor; + u8 xtal_k; + u8 chipset; /* 0x34 */ + u8 res8[0x82]; + u8 vid; /* 0xb7 */ + u8 res9; + u8 pid; /* 0xb9 */ + u8 res10[0x0c]; + u8 mac_addr[ETH_ALEN]; /* 0xc6 */ + u8 res11[2]; + u8 vendor_name[7]; + u8 res12[2]; + u8 device_name[0x29]; /* 0xd7 */ +}; + +struct rtl8192cu_efuse { + __le16 rtl_id; + __le16 hpon; + u8 res0[2]; + __le16 clk; + __le16 testr; + __le16 vid; + __le16 did; + __le16 svid; + __le16 smid; /* 0x10 */ + u8 res1[4]; + u8 mac_addr[ETH_ALEN]; /* 0x16 */ + u8 res2[2]; + u8 vendor_name[7]; + u8 res3[3]; + u8 device_name[0x14]; /* 0x28 */ + u8 res4[0x1e]; /* 0x3c */ + u8 cck_tx_power_index_A[3]; /* 0x5a */ + u8 cck_tx_power_index_B[3]; + u8 ht40_1s_tx_power_index_A[3]; /* 0x60 */ + u8 ht40_1s_tx_power_index_B[3]; + /* + * The following entries are half-bytes split as: + * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed + */ + struct rtl8723au_idx ht40_2s_tx_power_index_diff[3]; + struct rtl8723au_idx ht20_tx_power_index_diff[3]; /* 0x69 */ + struct rtl8723au_idx ofdm_tx_power_index_diff[3]; + struct rtl8723au_idx ht40_max_power_offset[3]; /* 0x6f */ + struct rtl8723au_idx ht20_max_power_offset[3]; + u8 channel_plan; /* 0x75 */ + u8 tssi_a; + u8 tssi_b; + u8 thermal_meter; /* xtal_k */ /* 0x78 */ + u8 rf_regulatory; + u8 rf_option_2; + u8 rf_option_3; + u8 rf_option_4; + u8 res5[1]; /* 0x7d */ + u8 version; + u8 customer_id; +}; + +struct rtl8723bu_pwr_idx { +#ifdef __LITTLE_ENDIAN + int ht20:4; + int ht40:4; + int ofdm:4; + int cck:4; +#else + int cck:4; + int ofdm:4; + int ht40:4; + int ht20:4; +#endif +} __attribute__((packed)); + +struct rtl8723bu_efuse_tx_power { + u8 cck_base[6]; + u8 ht40_base[5]; + struct rtl8723au_idx ht20_ofdm_1s_diff; + struct rtl8723bu_pwr_idx pwr_diff[3]; + u8 dummy5g[24]; /* max channel group (14) + power diff offset (10) */ +}; + +struct rtl8723bu_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + struct rtl8723bu_efuse_tx_power tx_power_index_A; /* 0x10 */ + struct rtl8723bu_efuse_tx_power tx_power_index_B; /* 0x3a */ + struct rtl8723bu_efuse_tx_power tx_power_index_C; /* 0x64 */ + struct rtl8723bu_efuse_tx_power tx_power_index_D; /* 0x8e */ + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g; /* 0xbd */ + u8 res2[3]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 res3[2]; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 res4[9]; + u8 usb_optional_function; + u8 res5[0x1e]; + u8 res6[2]; + u8 serial[0x0b]; /* 0xf5 */ + u8 vid; /* 0x100 */ + u8 res7; + u8 pid; + u8 res8[4]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 res9[2]; + u8 vendor_name[0x07]; + u8 res10[2]; + u8 device_name[0x14]; + u8 res11[0xcf]; + u8 package_type; /* 0x1fb */ + u8 res12[0x4]; +}; + +struct rtl8192eu_efuse_tx_power { + u8 cck_base[6]; + u8 ht40_base[5]; + struct rtl8723au_idx ht20_ofdm_1s_diff; + struct rtl8723bu_pwr_idx pwr_diff[3]; + u8 dummy5g[24]; /* max channel group (14) + power diff offset (10) */ +}; + +struct rtl8192eu_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */ + struct rtl8192eu_efuse_tx_power tx_power_index_B; /* 0x3a */ + u8 res2[0x54]; + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g; /* 0xbd */ + u8 res3[1]; + u8 lna_type_5g; /* 0xbf */ + u8 res4[1]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 res5[3]; + u8 rf_antenna_option; /* 0xc9 */ + u8 res6[6]; + u8 vid; /* 0xd0 */ + u8 res7[1]; + u8 pid; /* 0xd2 */ + u8 res8[1]; + u8 usb_optional_function; + u8 res9[2]; + u8 mac_addr[ETH_ALEN]; /* 0xd7 */ + u8 device_info[80]; + u8 res11[3]; + u8 unknown[0x0d]; /* 0x130 */ + u8 res12[0xc3]; +}; + +struct rtl8188fu_efuse_tx_power { + u8 cck_base[6]; + u8 ht40_base[5]; + /* a: ofdm; b: ht20 */ + struct rtl8723au_idx ht20_ofdm_1s_diff; +}; + +struct rtl8188fu_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + struct rtl8188fu_efuse_tx_power tx_power_index_A; /* 0x10 */ + u8 res1[0x9c]; /* 0x1c */ + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 res2[5]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 res3[2]; + u8 kfree_thermal_k_on; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code; + u8 res4[4]; + u8 vid; /* 0xd0 */ + u8 res5[1]; + u8 pid; /* 0xd2 */ + u8 res6[1]; + u8 usb_optional_function; + u8 res7[2]; + u8 mac_addr[ETH_ALEN]; /* 0xd7 */ + u8 res8[2]; + u8 vendor_name[7]; + u8 res9[2]; + u8 device_name[7]; /* 0xe8 */ + u8 res10[0x41]; + u8 unknown[0x0d]; /* 0x130 */ + u8 res11[0xc3]; +}; + +struct rtl8188eu_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */ + u8 res1[0x7e]; /* 0x3a */ + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 res2[5]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 res3[3]; + u8 rf_antenna_option; /* 0xc9 */ + u8 res4[6]; + u8 vid; /* 0xd0 */ + u8 res5[1]; + u8 pid; /* 0xd2 */ + u8 res6[1]; + u8 usb_optional_function; + u8 res7[2]; + u8 mac_addr[ETH_ALEN]; /* 0xd7 */ + u8 res8[2]; + u8 vendor_name[7]; + u8 res9[2]; + u8 device_name[0x0b]; /* 0xe8 */ + u8 res10[2]; + u8 serial[0x0b]; /* 0xf5 */ + u8 res11[0x30]; + u8 unknown[0x0d]; /* 0x130 */ + u8 res12[0xc3]; +} __packed; + +struct rtl8710bu_efuse { + __le16 rtl_id; + u8 res0[0x1e]; + struct rtl8188fu_efuse_tx_power tx_power_index_A; /* 0x20 */ + u8 res1[0x9c]; /* 0x2c */ + u8 channel_plan; /* 0xc8 */ + u8 xtal_k; /* 0xc9 */ + u8 thermal_meter; /* 0xca */ + u8 res2[0x4f]; + u8 mac_addr[ETH_ALEN]; /* 0x11a */ + u8 res3[0x11]; + u8 rf_board_option; /* 0x131 */ + u8 res4[2]; + u8 eeprom_version; /* 0x134 */ + u8 eeprom_customer_id; /* 0x135 */ + u8 res5[5]; + u8 country_code; /* 0x13b */ + u8 res6[0x84]; + u8 vid[2]; /* 0x1c0 */ + u8 pid[2]; /* 0x1c2 */ + u8 res7[0x3c]; +} __packed; + +struct rtl8192fu_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */ + struct rtl8192eu_efuse_tx_power tx_power_index_B; /* 0x3a */ + u8 res2[0x54]; + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; /* 0xb9 */ + u8 thermal_meter; /* 0xba */ + u8 iqk_lck; /* 0xbb */ + u8 pa_type; /* 0xbc */ + u8 lna_type_2g; /* 0xbd */ + u8 res3[1]; + u8 lna_type_5g; /* 0xbf */ + u8 res4[1]; + u8 rf_board_option; /* 0xc1 */ + u8 rf_feature_option; /* 0xc2 */ + u8 rf_bt_setting; /* 0xc3 */ + u8 eeprom_version; /* 0xc4 */ + u8 eeprom_customer_id; /* 0xc5 */ + u8 res5[3]; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; /* 0xca */ + u8 country_code; /* 0xcb */ + u8 res6[52]; + u8 vid[2]; /* 0x100 */ + u8 pid[2]; /* 0x102 */ + u8 usb_optional_function; /* 0x104 */ + u8 res7[2]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 device_info[80]; /* 0x10d */ + u8 res9[163]; +} __packed; + +struct rtl8xxxu_reg8val { + u16 reg; + u8 val; +}; + +struct rtl8xxxu_reg32val { + u16 reg; + u32 val; +}; + +struct rtl8xxxu_rfregval { + u8 reg; + u32 val; +}; + +enum rtl8xxxu_rfpath { + RF_A = 0, + RF_B = 1, +}; + +struct rtl8xxxu_rfregs { + u16 hssiparm1; + u16 hssiparm2; + u16 lssiparm; + u16 hspiread; + u16 lssiread; + u16 rf_sw_ctrl; +}; + +#define H2C_MAX_MBOX 4 +#define H2C_EXT BIT(7) +#define H2C_JOIN_BSS_DISCONNECT 0 +#define H2C_JOIN_BSS_CONNECT 1 + +#define H2C_MACID_ROLE_STA 1 +#define H2C_MACID_ROLE_AP 2 + +/* + * H2C (firmware) commands differ between the older generation chips + * 8188[cr]u, 819[12]cu, and 8723au, and the more recent chips 8723bu, + * 8192[de]u, 8192eu, and 8812. + */ +enum h2c_cmd_8723a { + H2C_SET_POWER_MODE = 1, + H2C_JOIN_BSS_REPORT = 2, + H2C_SET_RSSI = 5, + H2C_SET_RATE_MASK = (6 | H2C_EXT), +}; + +enum h2c_cmd_8723b { + /* + * Common Class: 000 + */ + H2C_8723B_RSVD_PAGE = 0x00, + H2C_8723B_MEDIA_STATUS_RPT = 0x01, + H2C_8723B_SCAN_ENABLE = 0x02, + H2C_8723B_KEEP_ALIVE = 0x03, + H2C_8723B_DISCON_DECISION = 0x04, + H2C_8723B_PSD_OFFLOAD = 0x05, + H2C_8723B_AP_OFFLOAD = 0x08, + H2C_8723B_BCN_RSVDPAGE = 0x09, + H2C_8723B_PROBERSP_RSVDPAGE = 0x0A, + H2C_8723B_FCS_RSVDPAGE = 0x10, + H2C_8723B_FCS_INFO = 0x11, + H2C_8723B_AP_WOW_GPIO_CTRL = 0x13, + + /* + * PoweSave Class: 001 + */ + H2C_8723B_SET_PWR_MODE = 0x20, + H2C_8723B_PS_TUNING_PARA = 0x21, + H2C_8723B_PS_TUNING_PARA2 = 0x22, + H2C_8723B_P2P_LPS_PARAM = 0x23, + H2C_8723B_P2P_PS_OFFLOAD = 0x24, + H2C_8723B_PS_SCAN_ENABLE = 0x25, + H2C_8723B_SAP_PS_ = 0x26, + H2C_8723B_INACTIVE_PS_ = 0x27, + H2C_8723B_FWLPS_IN_IPS_ = 0x28, + + /* + * Dynamic Mechanism Class: 010 + */ + H2C_8723B_MACID_CFG_RAID = 0x40, + H2C_8723B_TXBF = 0x41, + H2C_8723B_RSSI_SETTING = 0x42, + H2C_8723B_AP_REQ_TXRPT = 0x43, + H2C_8723B_INIT_RATE_COLLECT = 0x44, + + /* + * BT Class: 011 + */ + H2C_8723B_B_TYPE_TDMA = 0x60, + H2C_8723B_BT_INFO = 0x61, + H2C_8723B_FORCE_BT_TXPWR = 0x62, + H2C_8723B_BT_IGNORE_WLANACT = 0x63, + H2C_8723B_DAC_SWING_VALUE = 0x64, + H2C_8723B_ANT_SEL_RSV = 0x65, + H2C_8723B_WL_OPMODE = 0x66, + H2C_8723B_BT_MP_OPER = 0x67, + H2C_8723B_BT_CONTROL = 0x68, + H2C_8723B_BT_WIFI_CTRL = 0x69, + H2C_8723B_BT_FW_PATCH = 0x6a, + H2C_8723B_BT_WLAN_CALIBRATION = 0x6d, + H2C_8723B_BT_GRANT = 0x6e, + + /* + * WOWLAN Class: 100 + */ + H2C_8723B_WOWLAN = 0x80, + H2C_8723B_REMOTE_WAKE_CTRL = 0x81, + H2C_8723B_AOAC_GLOBAL_INFO = 0x82, + H2C_8723B_AOAC_RSVD_PAGE = 0x83, + H2C_8723B_AOAC_RSVD_PAGE2 = 0x84, + H2C_8723B_D0_SCAN_OFFLOAD_CTRL = 0x85, + H2C_8723B_D0_SCAN_OFFLOAD_INFO = 0x86, + H2C_8723B_CHNL_SWITCH_OFFLOAD = 0x87, + + H2C_8723B_RESET_TSF = 0xC0, +}; + + +struct h2c_cmd { + union { + struct { + u8 cmd; + u8 data[7]; + } __packed cmd; + struct { + __le32 data; + __le16 ext; + } __packed raw; + struct { + __le32 data; + __le32 ext; + } __packed raw_wide; + struct { + u8 cmd; + u8 data; + } __packed joinbss; + struct { + u8 cmd; + __le16 mask_hi; + u8 arg; + __le16 mask_lo; + } __packed ramask; + struct { + u8 cmd; + u8 parm; + u8 macid; + u8 macid_end; + } __packed media_status_rpt; + struct { + u8 cmd; + u8 macid; + /* + * [0:4] - RAID + * [7] - SGI + */ + u8 data1; + /* + * [0:1] - Bandwidth + * [3] - No Update + * [4:5] - VHT enable + * [6] - DISPT + * [7] - DISRA + */ + u8 data2; + u8 ramask0; + u8 ramask1; + u8 ramask2; + u8 ramask3; + } __packed b_macid_cfg; + struct { + u8 cmd; + u8 data1; + u8 data2; + u8 data3; + u8 data4; + u8 data5; + } __packed b_type_dma; + struct { + u8 cmd; + u8 data; + } __packed bt_info; + struct { + u8 cmd; + u8 operreq; + u8 opcode; + u8 data; + u8 addr; + } __packed bt_mp_oper; + struct { + u8 cmd; + u8 data; + } __packed bt_wlan_calibration; + struct { + u8 cmd; + u8 data; + } __packed ignore_wlan; + struct { + u8 cmd; + u8 ant_inverse; + u8 int_switch_type; + } __packed ant_sel_rsv; + struct { + u8 cmd; + u8 data; + } __packed bt_grant; + struct { + u8 cmd; + u8 macid; + u8 unknown0; + u8 rssi; + /* + * [0] - is_rx + * [1] - stbc_en + * [2] - noisy_decision + * [6] - bf_en + */ + u8 data; + /* + * [0:6] - ra_th_offset + * [7] - ra_offset_direction + */ + u8 ra_th_offset; + u8 unknown1; + u8 unknown2; + } __packed rssi_report; + }; +}; + +enum c2h_evt_8723b { + C2H_8723B_DEBUG = 0, + C2H_8723B_TSF = 1, + C2H_8723B_AP_RPT_RSP = 2, + C2H_8723B_CCX_TX_RPT = 3, + C2H_8723B_BT_RSSI = 4, + C2H_8723B_BT_OP_MODE = 5, + C2H_8723B_EXT_RA_RPT = 6, + C2H_8723B_BT_INFO = 9, + C2H_8723B_HW_INFO_EXCH = 0x0a, + C2H_8723B_BT_MP_INFO = 0x0b, + C2H_8723B_RA_REPORT = 0x0c, + C2H_8723B_FW_DEBUG = 0xff, +}; + +enum bt_info_src_8723b { + BT_INFO_SRC_8723B_WIFI_FW = 0x0, + BT_INFO_SRC_8723B_BT_RSP = 0x1, + BT_INFO_SRC_8723B_BT_ACTIVE_SEND = 0x2, +}; + +enum bt_mp_oper_opcode_8723b { + BT_MP_OP_GET_BT_VERSION = 0x00, + BT_MP_OP_RESET = 0x01, + BT_MP_OP_TEST_CTRL = 0x02, + BT_MP_OP_SET_BT_MODE = 0x03, + BT_MP_OP_SET_CHNL_TX_GAIN = 0x04, + BT_MP_OP_SET_PKT_TYPE_LEN = 0x05, + BT_MP_OP_SET_PKT_CNT_L_PL_TYPE = 0x06, + BT_MP_OP_SET_PKT_CNT_H_PKT_INTV = 0x07, + BT_MP_OP_SET_PKT_HEADER = 0x08, + BT_MP_OP_SET_WHITENCOEFF = 0x09, + BT_MP_OP_SET_BD_ADDR_L = 0x0a, + BT_MP_OP_SET_BD_ADDR_H = 0x0b, + BT_MP_OP_WRITE_REG_ADDR = 0x0c, + BT_MP_OP_WRITE_REG_VALUE = 0x0d, + BT_MP_OP_GET_BT_STATUS = 0x0e, + BT_MP_OP_GET_BD_ADDR_L = 0x0f, + BT_MP_OP_GET_BD_ADDR_H = 0x10, + BT_MP_OP_READ_REG = 0x11, + BT_MP_OP_SET_TARGET_BD_ADDR_L = 0x12, + BT_MP_OP_SET_TARGET_BD_ADDR_H = 0x13, + BT_MP_OP_SET_TX_POWER_CALIBRATION = 0x14, + BT_MP_OP_GET_RX_PKT_CNT_L = 0x15, + BT_MP_OP_GET_RX_PKT_CNT_H = 0x16, + BT_MP_OP_GET_RX_ERROR_BITS_L = 0x17, + BT_MP_OP_GET_RX_ERROR_BITS_H = 0x18, + BT_MP_OP_GET_RSSI = 0x19, + BT_MP_OP_GET_CFO_HDR_QUALITY_L = 0x1a, + BT_MP_OP_GET_CFO_HDR_QUALITY_H = 0x1b, + BT_MP_OP_GET_TARGET_BD_ADDR_L = 0x1c, + BT_MP_OP_GET_TARGET_BD_ADDR_H = 0x1d, + BT_MP_OP_GET_AFH_MAP_L = 0x1e, + BT_MP_OP_GET_AFH_MAP_M = 0x1f, + BT_MP_OP_GET_AFH_MAP_H = 0x20, + BT_MP_OP_GET_AFH_STATUS = 0x21, + BT_MP_OP_SET_TRACKING_INTERVAL = 0x22, + BT_MP_OP_SET_THERMAL_METER = 0x23, + BT_MP_OP_ENABLE_CFO_TRACKING = 0x24, +}; + +enum rtl8xxxu_bw_mode { + RTL8XXXU_CHANNEL_WIDTH_20 = 0, + RTL8XXXU_CHANNEL_WIDTH_40 = 1, + RTL8XXXU_CHANNEL_WIDTH_80 = 2, + RTL8XXXU_CHANNEL_WIDTH_160 = 3, + RTL8XXXU_CHANNEL_WIDTH_80_80 = 4, + RTL8XXXU_CHANNEL_WIDTH_MAX = 5, +}; + +struct rtl8723bu_c2h { + u8 id; + u8 seq; + union { + struct { + u8 payload[0]; + } __packed raw; + struct { + u8 ext_id; + u8 status:4; + u8 retlen:4; + u8 opcode_ver:4; + u8 req_num:4; + u8 payload[2]; + } __packed bt_mp_info; + struct { + u8 response_source:4; + u8 dummy0_0:4; + + u8 bt_info; + + u8 retry_count:4; + u8 dummy2_0:1; + u8 bt_page:1; + u8 tx_rx_mask:1; + u8 dummy2_2:1; + + u8 rssi; + + u8 basic_rate:1; + u8 bt_has_reset:1; + u8 dummy4_1:1; + u8 ignore_wlan:1; + u8 auto_report:1; + u8 dummy4_2:3; + + u8 a4; + u8 a5; + } __packed bt_info; + struct { + u8 rate:7; + u8 sgi:1; + u8 macid; + u8 ldpc:1; + u8 txbf:1; + u8 noisy_state:1; + u8 dummy2_0:5; + u8 dummy3_0; + u8 dummy4_0; + u8 dummy5_0; + u8 bw; + } __packed ra_report; + }; +} __packed; + +struct rtl8xxxu_fileops; + +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0, + /* Sub-Element */ + WIRELESS_MODE_B = BIT(0), + WIRELESS_MODE_G = BIT(1), + WIRELESS_MODE_A = BIT(2), + WIRELESS_MODE_N_24G = BIT(3), + WIRELESS_MODE_N_5G = BIT(4), + WIRELESS_AUTO = BIT(5), + WIRELESS_MODE_AC = BIT(6), + WIRELESS_MODE_MAX = 0x7F, +}; + +/* from rtlwifi/wifi.h */ +enum ratr_table_mode_new { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +}; + +#define BT_INFO_8723B_1ANT_B_FTP BIT(7) +#define BT_INFO_8723B_1ANT_B_A2DP BIT(6) +#define BT_INFO_8723B_1ANT_B_HID BIT(5) +#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT(4) +#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT(3) +#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT(2) +#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT(1) +#define BT_INFO_8723B_1ANT_B_CONNECTION BIT(0) + +enum _BT_8723B_1ANT_STATUS { + BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_1ANT_STATUS_INQ_PAGE = 0x2, + BT_8723B_1ANT_STATUS_ACL_BUSY = 0x3, + BT_8723B_1ANT_STATUS_SCO_BUSY = 0x4, + BT_8723B_1ANT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_1ANT_STATUS_MAX +}; + +struct rtl8xxxu_btcoex { + u8 bt_status; + bool bt_busy; + bool has_sco; + bool has_a2dp; + bool has_hid; + bool has_pan; + bool hid_only; + bool a2dp_only; + bool c2h_bt_inquiry; +}; + +#define RTL8XXXU_RATR_STA_INIT 0 +#define RTL8XXXU_RATR_STA_HIGH 1 +#define RTL8XXXU_RATR_STA_MID 2 +#define RTL8XXXU_RATR_STA_LOW 3 + +#define RTL8XXXU_NOISE_FLOOR_MIN -100 +#define RTL8XXXU_SNR_THRESH_HIGH 50 +#define RTL8XXXU_SNR_THRESH_LOW 20 + +struct rtl8xxxu_ra_report { + struct rate_info txrate; + u32 bit_rate; + u8 desc_rate; +}; + +struct rtl8xxxu_ra_info { + u8 rate_id; + u32 rate_mask; + u32 ra_use_rate; + u8 rate_sgi; + u8 rssi_sta_ra; /* Percentage */ + u8 pre_rssi_sta_ra; + u8 sgi_enable; + u8 decision_rate; + u8 pre_rate; + u8 highest_rate; + u8 lowest_rate; + u32 nsc_up; + u32 nsc_down; + u32 total; + u16 retry[5]; + u16 drop; + u16 rpt_time; + u16 pre_min_rpt_time; + u8 dynamic_tx_rpt_timing_counter; + u8 ra_waiting_counter; + u8 ra_pending_counter; + u8 ra_drop_after_down; + u8 pt_try_state; /* 0 trying state, 1 for decision state */ + u8 pt_stage; /* 0~6 */ + u8 pt_stop_count; /* Stop PT counter */ + u8 pt_pre_rate; /* if rate change do PT */ + u8 pt_pre_rssi; /* if RSSI change 5% do PT */ + u8 pt_mode_ss; /* decide which rate should do PT */ + u8 ra_stage; /* StageRA, decide how many times RA will be done between PT */ + u8 pt_smooth_factor; +}; + +#define CFO_TH_XTAL_HIGH 20 /* kHz */ +#define CFO_TH_XTAL_LOW 10 /* kHz */ +#define CFO_TH_ATC 80 /* kHz */ + +struct rtl8xxxu_cfo_tracking { + bool adjust; + bool atc_status; + int cfo_tail[2]; + u8 crystal_cap; + u32 packet_count; + u32 packet_count_pre; +}; + +#define RTL8XXXU_HW_LED_CONTROL 2 +#define RTL8XXXU_MAX_MAC_ID_NUM 128 +#define RTL8XXXU_BC_MC_MACID 0 +#define RTL8XXXU_BC_MC_MACID1 1 +#define RTL8XXXU_MAX_SEC_CAM_NUM 64 + +struct rtl8xxxu_hw_feature { + u8 max_bw; +}; + +struct rtl8xxxu_priv { + struct ieee80211_hw *hw; + struct usb_device *udev; + struct rtl8xxxu_fileops *fops; + + struct rtl8xxxu_hw_feature hw_feature; + + spinlock_t tx_urb_lock; + struct list_head tx_urb_free_list; + int tx_urb_free_count; + bool tx_stopped; + + spinlock_t rx_urb_lock; + struct list_head rx_urb_pending_list; + int rx_urb_pending_count; + bool shutdown; + struct work_struct rx_urb_wq; + + u8 mac_addr[ETH_ALEN]; + char chip_name[8]; + char chip_vendor[8]; + u8 cck_tx_power_index_A[RTL8XXXU_MAX_CHANNEL_GROUPS]; + u8 cck_tx_power_index_B[RTL8XXXU_MAX_CHANNEL_GROUPS]; + u8 ht40_1s_tx_power_index_A[RTL8XXXU_MAX_CHANNEL_GROUPS]; + u8 ht40_1s_tx_power_index_B[RTL8XXXU_MAX_CHANNEL_GROUPS]; + /* + * The following entries are half-bytes split as: + * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed + */ + struct rtl8723au_idx ht40_2s_tx_power_index_diff[ + RTL8723A_CHANNEL_GROUPS]; + struct rtl8723au_idx ht20_tx_power_index_diff[RTL8723A_CHANNEL_GROUPS]; + struct rtl8723au_idx ofdm_tx_power_index_diff[RTL8723A_CHANNEL_GROUPS]; + struct rtl8723au_idx ht40_max_power_offset[RTL8723A_CHANNEL_GROUPS]; + struct rtl8723au_idx ht20_max_power_offset[RTL8723A_CHANNEL_GROUPS]; + /* + * Newer generation chips only keep power diffs per TX count, + * not per channel group. + */ + struct rtl8723au_idx ofdm_tx_power_diff[RTL8723B_TX_COUNT]; + struct rtl8723au_idx ht20_tx_power_diff[RTL8723B_TX_COUNT]; + struct rtl8723au_idx ht40_tx_power_diff[RTL8723B_TX_COUNT]; + struct rtl8xxxu_power_base *power_base; + u8 package_type; + u32 chip_cut:4; + u32 rom_rev:4; + u32 is_multi_func:1; + u32 has_wifi:1; + u32 has_bluetooth:1; + u32 enable_bluetooth:1; + u32 has_gps:1; + u32 hi_pa:1; + u32 vendor_umc:1; + u32 vendor_smic:1; + u32 has_polarity_ctrl:1; + u32 has_eeprom:1; + u32 boot_eeprom:1; + u32 usb_interrupts:1; + u32 ep_tx_high_queue:1; + u32 ep_tx_normal_queue:1; + u32 ep_tx_low_queue:1; + u32 rx_buf_aggregation:1; + u32 cck_agc_report_type:1; + u32 cck_new_agc:1; + u8 default_crystal_cap; + u8 rfe_type; + unsigned int pipe_interrupt; + unsigned int pipe_in; + unsigned int pipe_out[TXDESC_QUEUE_MAX]; + u8 out_ep[RTL8XXXU_OUT_ENDPOINTS]; + u8 ep_tx_count; + u8 rf_paths; + u8 rx_paths; + u8 tx_paths; + u32 rege94; + u32 rege9c; + u32 regeb4; + u32 regebc; + u32 regrcr; + int next_mbox; + int nr_out_eps; + + /* Ensure no added or deleted stas while iterating */ + struct mutex sta_mutex; + struct mutex h2c_mutex; + /* Protect the indirect register accesses of RTL8710BU. */ + struct mutex syson_indirect_access_mutex; + + struct usb_anchor rx_anchor; + struct usb_anchor tx_anchor; + struct usb_anchor int_anchor; + struct rtl8xxxu_firmware_header *fw_data; + size_t fw_size; + struct mutex usb_buf_mutex; + union { + __le32 val32; + __le16 val16; + u8 val8; + } usb_buf; + union { + u8 raw[EFUSE_MAP_LEN]; + struct rtl8723au_efuse efuse8723; + struct rtl8723bu_efuse efuse8723bu; + struct rtl8192cu_efuse efuse8192; + struct rtl8192eu_efuse efuse8192eu; + struct rtl8188fu_efuse efuse8188fu; + struct rtl8188eu_efuse efuse8188eu; + struct rtl8710bu_efuse efuse8710bu; + struct rtl8192fu_efuse efuse8192fu; + } efuse_wifi; + u32 adda_backup[RTL8XXXU_ADDA_REGS]; + u32 mac_backup[RTL8XXXU_MAC_REGS]; + u32 bb_backup[RTL8XXXU_BB_REGS]; + u32 bb_recovery_backup[RTL8XXXU_BB_REGS]; + enum rtl8xxxu_rtl_chip rtl_chip; + u8 pi_enabled:1; + u8 no_pape:1; + u8 int_buf[USB_INTR_CONTENT_LENGTH]; + DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS); + DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS); + + struct ieee80211_vif *vifs[2]; + struct delayed_work ra_watchdog; + struct work_struct c2hcmd_work; + struct sk_buff_head c2hcmd_queue; + struct delayed_work update_beacon_work; + struct rtl8xxxu_btcoex bt_coex; + struct rtl8xxxu_ra_report ra_report; + struct rtl8xxxu_cfo_tracking cfo_tracking; + struct rtl8xxxu_ra_info ra_info; + + bool led_registered; + char led_name[32]; + struct led_classdev led_cdev; + DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM); + DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM); +}; + +DECLARE_EWMA(rssi, 10, 16); + +struct rtl8xxxu_sta_info { + struct ieee80211_sta *sta; + struct ieee80211_vif *vif; + + u8 macid; + struct ewma_rssi avg_rssi; + u8 rssi_level; +}; + +struct rtl8xxxu_vif { + int port_num; + u8 hw_key_idx; +}; + +struct rtl8xxxu_rx_urb { + struct urb urb; + struct ieee80211_hw *hw; + struct list_head list; +}; + +struct rtl8xxxu_tx_urb { + struct urb urb; + struct ieee80211_hw *hw; + struct list_head list; +}; + +struct rtl8xxxu_fileops { + int (*identify_chip) (struct rtl8xxxu_priv *priv); + int (*read_efuse) (struct rtl8xxxu_priv *priv); + int (*parse_efuse) (struct rtl8xxxu_priv *priv); + int (*load_firmware) (struct rtl8xxxu_priv *priv); + int (*power_on) (struct rtl8xxxu_priv *priv); + void (*power_off) (struct rtl8xxxu_priv *priv); + void (*reset_8051) (struct rtl8xxxu_priv *priv); + int (*llt_init) (struct rtl8xxxu_priv *priv); + void (*init_phy_bb) (struct rtl8xxxu_priv *priv); + int (*init_phy_rf) (struct rtl8xxxu_priv *priv); + void (*phy_init_antenna_selection) (struct rtl8xxxu_priv *priv); + void (*phy_lc_calibrate) (struct rtl8xxxu_priv *priv); + void (*phy_iq_calibrate) (struct rtl8xxxu_priv *priv); + void (*config_channel) (struct ieee80211_hw *hw); + int (*parse_rx_desc) (struct rtl8xxxu_priv *priv, struct sk_buff *skb); + void (*parse_phystats) (struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err); + void (*init_aggregation) (struct rtl8xxxu_priv *priv); + void (*init_statistics) (struct rtl8xxxu_priv *priv); + void (*init_burst) (struct rtl8xxxu_priv *priv); + void (*enable_rf) (struct rtl8xxxu_priv *priv); + void (*disable_rf) (struct rtl8xxxu_priv *priv); + void (*usb_quirks) (struct rtl8xxxu_priv *priv); + void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel, + bool ht40); + void (*update_rate_mask) (struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, + u8 macid); + void (*report_connect) (struct rtl8xxxu_priv *priv, + u8 macid, u8 role, bool connect); + void (*report_rssi) (struct rtl8xxxu_priv *priv, u8 macid, u8 rssi); + void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, + bool short_preamble, bool ampdu_enable, + u32 rts_rate, u8 macid); + void (*set_crystal_cap) (struct rtl8xxxu_priv *priv, u8 crystal_cap); + s8 (*cck_rssi) (struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats); + int (*led_classdev_brightness_set) (struct led_classdev *led_cdev, + enum led_brightness brightness); + int writeN_block_size; + int rx_agg_buf_size; + char tx_desc_size; + char rx_desc_size; + u8 has_s0s1:1; + u8 has_tx_report:1; + u8 gen2_thermal_meter:1; + u8 needs_full_init:1; + u8 init_reg_rxfltmap:1; + u8 init_reg_pkt_life_time:1; + u8 init_reg_hmtfr:1; + u8 supports_concurrent:1; + u8 hw_feature_report:1; + u8 ampdu_max_time; + u8 ustime_tsf_edca; + u16 max_aggr_num; + u8 supports_ap:1; + u16 max_macid_num; + u16 max_sec_cam_num; + u32 adda_1t_init; + u32 adda_1t_path_on; + u32 adda_2t_path_on_a; + u32 adda_2t_path_on_b; + u16 trxff_boundary; + u8 pbp_rx; + u8 pbp_tx; + const struct rtl8xxxu_reg8val *mactable; + u8 total_page_num; + u8 page_num_hi; + u8 page_num_lo; + u8 page_num_norm; + u8 last_llt_entry; +}; + +extern int rtl8xxxu_debug; + +extern const u32 rtl8xxxu_iqk_phy_iq_bb_reg[]; +u8 rtl8xxxu_read8(struct rtl8xxxu_priv *priv, u16 addr); +u16 rtl8xxxu_read16(struct rtl8xxxu_priv *priv, u16 addr); +u32 rtl8xxxu_read32(struct rtl8xxxu_priv *priv, u16 addr); +int rtl8xxxu_write8(struct rtl8xxxu_priv *priv, u16 addr, u8 val); +int rtl8xxxu_write16(struct rtl8xxxu_priv *priv, u16 addr, u16 val); +int rtl8xxxu_write32(struct rtl8xxxu_priv *priv, u16 addr, u32 val); +int rtl8xxxu_write8_set(struct rtl8xxxu_priv *priv, u16 addr, u8 bits); +int rtl8xxxu_write8_clear(struct rtl8xxxu_priv *priv, u16 addr, u8 bits); +int rtl8xxxu_write16_set(struct rtl8xxxu_priv *priv, u16 addr, u16 bits); +int rtl8xxxu_write16_clear(struct rtl8xxxu_priv *priv, u16 addr, u16 bits); +int rtl8xxxu_write32_set(struct rtl8xxxu_priv *priv, u16 addr, u32 bits); +int rtl8xxxu_write32_clear(struct rtl8xxxu_priv *priv, u16 addr, u32 bits); +int rtl8xxxu_write32_mask(struct rtl8xxxu_priv *priv, u16 addr, + u32 mask, u32 val); + +u32 rtl8xxxu_read_rfreg(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg); +int rtl8xxxu_write_rfreg(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg, u32 data); +int rtl8xxxu_write_rfreg_mask(struct rtl8xxxu_priv *priv, + enum rtl8xxxu_rfpath path, u8 reg, + u32 mask, u32 val); +void rtl8xxxu_save_regs(struct rtl8xxxu_priv *priv, const u32 *regs, + u32 *backup, int count); +void rtl8xxxu_restore_regs(struct rtl8xxxu_priv *priv, const u32 *regs, + u32 *backup, int count); +void rtl8xxxu_save_mac_regs(struct rtl8xxxu_priv *priv, + const u32 *reg, u32 *backup); +void rtl8xxxu_restore_mac_regs(struct rtl8xxxu_priv *priv, + const u32 *reg, u32 *backup); +void rtl8xxxu_path_adda_on(struct rtl8xxxu_priv *priv, const u32 *regs, + bool path_a_on); +void rtl8xxxu_mac_calibration(struct rtl8xxxu_priv *priv, + const u32 *regs, u32 *backup); +void rtl8xxxu_fill_iqk_matrix_a(struct rtl8xxxu_priv *priv, bool iqk_ok, + int result[][8], int candidate, bool tx_only); +void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv, bool iqk_ok, + int result[][8], int candidate, bool tx_only); +int rtl8xxxu_init_phy_rf(struct rtl8xxxu_priv *priv, + const struct rtl8xxxu_rfregval *table, + enum rtl8xxxu_rfpath path); +int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv, + const struct rtl8xxxu_reg32val *array); +int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name); +void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv); +void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor); +void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor); +void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv); +int rtl8xxxu_config_endpoints_no_sie(struct rtl8xxxu_priv *priv); +int rtl8xxxu_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data); +int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv); +void rtl8xxxu_reset_8051(struct rtl8xxxu_priv *priv); +int rtl8xxxu_auto_llt_table(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen2_prepare_calibrate(struct rtl8xxxu_priv *priv, u8 start); +void rtl8723a_phy_lc_calibrate(struct rtl8xxxu_priv *priv); +void rtl8188f_phy_lc_calibrate(struct rtl8xxxu_priv *priv); +int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv); +int rtl8xxxu_gen2_h2c_cmd(struct rtl8xxxu_priv *priv, + struct h2c_cmd *h2c, int len); +int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv); +void rtl8xxxu_disabled_to_emu(struct rtl8xxxu_priv *priv); +int rtl8xxxu_init_llt_table(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen1_phy_iq_calibrate(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen1_init_phy_bb(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, + int channel, bool ht40); +void rtl8188f_channel_to_group(int channel, int *group, int *cck_group); +void rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv, + int channel, bool ht40); +void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw); +void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw); +void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv); +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, u8 macid); +void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi, int txbw_40mhz, u8 macid); +void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, + u8 macid, u8 role, bool connect); +void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, + u8 macid, u8 role, bool connect); +void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi); +void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi); +void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen1_enable_rf(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen1_disable_rf(struct rtl8xxxu_priv *priv); +void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv); +void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv); +int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb); +int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb); +void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err); +void jaguar2_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, + u32 rxmcs, struct ieee80211_hdr *hdr, + bool crc_icv_err); +int rtl8xxxu_gen2_channel_to_group(int channel); +bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv, + int result[][8], int c1, int c2); +bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, + int result[][8], int c1, int c2); +void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, + bool short_preamble, bool ampdu_enable, + u32 rts_rate, u8 macid); +void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, + bool short_preamble, bool ampdu_enable, + u32 rts_rate, u8 macid); +void rtl8xxxu_fill_txdesc_v3(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *tx_info, + struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, + bool short_preamble, bool ampdu_enable, + u32 rts_rate, u8 macid); +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5); +void rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv); +void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap); +void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap); +s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats); +void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt, + u8 rate, u8 sgi, u8 bw); +void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra); +void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb); + +extern struct rtl8xxxu_fileops rtl8192fu_fops; +extern struct rtl8xxxu_fileops rtl8710bu_fops; +extern struct rtl8xxxu_fileops rtl8188fu_fops; +extern struct rtl8xxxu_fileops rtl8188eu_fops; +extern struct rtl8xxxu_fileops rtl8192cu_fops; +extern struct rtl8xxxu_fileops rtl8192eu_fops; +extern struct rtl8xxxu_fileops rtl8723au_fops; +extern struct rtl8xxxu_fileops rtl8723bu_fops; diff --git a/drivers/net/wireless/realtek/rtlwifi/Kconfig b/drivers/net/wireless/realtek/rtlwifi/Kconfig new file mode 100644 index 000000000..1e66c1bf7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/Kconfig @@ -0,0 +1,171 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig RTL_CARDS + tristate "Realtek rtlwifi family of devices" + depends on MAC80211 && (PCI || USB) + default y + help + This option will enable support for the Realtek mac80211-based + wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de, + rtl8723ae, rtl8723be, rtl8188ee, rtl8192ee, and rtl8821ae share + some common code. + +if RTL_CARDS + +config RTL8192CE + tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter" + depends on PCI + select RTL8192C_COMMON + select RTLWIFI + select RTLWIFI_PCI + help + This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192ce + +config RTL8192SE + tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + help + This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192se + +config RTL8192DE + tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter" + depends on PCI + select RTL8192D_COMMON + select RTLWIFI + select RTLWIFI_PCI + help + This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192de + +config RTL8723AE + tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + select RTL8723_COMMON + select RTLBTCOEXIST + help + This is the driver for Realtek RTL8723AE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8723ae + +config RTL8723BE + tristate "Realtek RTL8723BE PCIe Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + select RTL8723_COMMON + select RTLBTCOEXIST + help + This is the driver for Realtek RTL8723BE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8723be + +config RTL8188EE + tristate "Realtek RTL8188EE Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + help + This is the driver for Realtek RTL8188EE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8188ee + +config RTL8192EE + tristate "Realtek RTL8192EE Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + select RTLBTCOEXIST + help + This is the driver for Realtek RTL8192EE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192ee + +config RTL8821AE + tristate "Realtek RTL8821AE/RTL8812AE Wireless Network Adapter" + depends on PCI + select RTLWIFI + select RTLWIFI_PCI + select RTLBTCOEXIST + help + This is the driver for Realtek RTL8821AE/RTL8812AE 802.11ac PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8821ae + +config RTL8192CU + tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" + depends on USB + select RTLWIFI + select RTLWIFI_USB + select RTL8192C_COMMON + help + This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192cu + +config RTL8192DU + tristate "Realtek RTL8192DU USB Wireless Network Adapter" + depends on USB + select RTLWIFI + select RTLWIFI_USB + select RTL8192D_COMMON + help + This is the driver for Realtek RTL8192DU 802.11n USB + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192du + +config RTLWIFI + tristate + select FW_LOADER + +config RTLWIFI_PCI + tristate + +config RTLWIFI_USB + tristate + +config RTLWIFI_DEBUG + bool "Debugging output for rtlwifi driver family" + depends on RTLWIFI + default y + help + To use the module option that sets the dynamic-debugging level for, + the front-end driver, this parameter must be "Y". For memory-limited + systems, choose "N". If in doubt, choose "Y". + +config RTL8192C_COMMON + tristate + depends on RTL8192CE || RTL8192CU + default y + +config RTL8192D_COMMON + tristate + +config RTL8723_COMMON + tristate + depends on RTL8723AE || RTL8723BE + default y + +config RTLBTCOEXIST + tristate + depends on RTL8723AE || RTL8723BE || RTL8821AE || RTL8192EE + default y + +endif diff --git a/drivers/net/wireless/realtek/rtlwifi/Makefile b/drivers/net/wireless/realtek/rtlwifi/Makefile new file mode 100644 index 000000000..9cf32277c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/Makefile @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_RTLWIFI) += rtlwifi.o +rtlwifi-objs := \ + base.o \ + cam.o \ + core.o \ + debug.o \ + efuse.o \ + ps.o \ + rc.o \ + regd.o \ + stats.o + +rtl8192c_common-objs += \ + +obj-$(CONFIG_RTLWIFI_PCI) += rtl_pci.o +rtl_pci-objs := pci.o + +obj-$(CONFIG_RTLWIFI_USB) += rtl_usb.o +rtl_usb-objs := usb.o + +obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ +obj-$(CONFIG_RTL8192CE) += rtl8192ce/ +obj-$(CONFIG_RTL8192CU) += rtl8192cu/ +obj-$(CONFIG_RTL8192SE) += rtl8192se/ +obj-$(CONFIG_RTL8192D_COMMON) += rtl8192d/ +obj-$(CONFIG_RTL8192DE) += rtl8192de/ +obj-$(CONFIG_RTL8192DU) += rtl8192du/ +obj-$(CONFIG_RTL8723AE) += rtl8723ae/ +obj-$(CONFIG_RTL8723BE) += rtl8723be/ +obj-$(CONFIG_RTL8188EE) += rtl8188ee/ +obj-$(CONFIG_RTLBTCOEXIST) += btcoexist/ +obj-$(CONFIG_RTL8723_COMMON) += rtl8723com/ +obj-$(CONFIG_RTL8821AE) += rtl8821ae/ +obj-$(CONFIG_RTL8192EE) += rtl8192ee/ diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c new file mode 100644 index 000000000..9e98c01bb --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -0,0 +1,2735 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "rc.h" +#include "base.h" +#include "efuse.h" +#include "cam.h" +#include "ps.h" +#include "regd.h" +#include "pci.h" +#include +#include +#include + +/* + *NOTICE!!!: This file will be very big, we should + *keep it clear under following roles: + * + *This file include following parts, so, if you add new + *functions into this file, please check which part it + *should includes. or check if you should add new part + *for this file: + * + *1) mac80211 init functions + *2) tx information functions + *3) functions called by core.c + *4) wq & timer callback functions + *5) frame process functions + *6) IOT functions + *7) sysfs functions + *8) vif functions + *9) ... + */ + +/********************************************************* + * + * mac80211 init functions + * + *********************************************************/ +static struct ieee80211_channel rtl_channeltable_2g[] = { + {.center_freq = 2412, .hw_value = 1,}, + {.center_freq = 2417, .hw_value = 2,}, + {.center_freq = 2422, .hw_value = 3,}, + {.center_freq = 2427, .hw_value = 4,}, + {.center_freq = 2432, .hw_value = 5,}, + {.center_freq = 2437, .hw_value = 6,}, + {.center_freq = 2442, .hw_value = 7,}, + {.center_freq = 2447, .hw_value = 8,}, + {.center_freq = 2452, .hw_value = 9,}, + {.center_freq = 2457, .hw_value = 10,}, + {.center_freq = 2462, .hw_value = 11,}, + {.center_freq = 2467, .hw_value = 12,}, + {.center_freq = 2472, .hw_value = 13,}, + {.center_freq = 2484, .hw_value = 14,}, +}; + +static struct ieee80211_channel rtl_channeltable_5g[] = { + {.center_freq = 5180, .hw_value = 36,}, + {.center_freq = 5200, .hw_value = 40,}, + {.center_freq = 5220, .hw_value = 44,}, + {.center_freq = 5240, .hw_value = 48,}, + {.center_freq = 5260, .hw_value = 52,}, + {.center_freq = 5280, .hw_value = 56,}, + {.center_freq = 5300, .hw_value = 60,}, + {.center_freq = 5320, .hw_value = 64,}, + {.center_freq = 5500, .hw_value = 100,}, + {.center_freq = 5520, .hw_value = 104,}, + {.center_freq = 5540, .hw_value = 108,}, + {.center_freq = 5560, .hw_value = 112,}, + {.center_freq = 5580, .hw_value = 116,}, + {.center_freq = 5600, .hw_value = 120,}, + {.center_freq = 5620, .hw_value = 124,}, + {.center_freq = 5640, .hw_value = 128,}, + {.center_freq = 5660, .hw_value = 132,}, + {.center_freq = 5680, .hw_value = 136,}, + {.center_freq = 5700, .hw_value = 140,}, + {.center_freq = 5745, .hw_value = 149,}, + {.center_freq = 5765, .hw_value = 153,}, + {.center_freq = 5785, .hw_value = 157,}, + {.center_freq = 5805, .hw_value = 161,}, + {.center_freq = 5825, .hw_value = 165,}, +}; + +static struct ieee80211_rate rtl_ratetable_2g[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static struct ieee80211_rate rtl_ratetable_5g[] = { + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static const struct ieee80211_supported_band rtl_band_2ghz = { + .band = NL80211_BAND_2GHZ, + + .channels = rtl_channeltable_2g, + .n_channels = ARRAY_SIZE(rtl_channeltable_2g), + + .bitrates = rtl_ratetable_2g, + .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g), + + .ht_cap = {0}, +}; + +static struct ieee80211_supported_band rtl_band_5ghz = { + .band = NL80211_BAND_5GHZ, + + .channels = rtl_channeltable_5g, + .n_channels = ARRAY_SIZE(rtl_channeltable_5g), + + .bitrates = rtl_ratetable_5g, + .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g), + + .ht_cap = {0}, +}; + +static const u8 tid_to_ac[] = { + 2, /* IEEE80211_AC_BE */ + 3, /* IEEE80211_AC_BK */ + 3, /* IEEE80211_AC_BK */ + 2, /* IEEE80211_AC_BE */ + 1, /* IEEE80211_AC_VI */ + 1, /* IEEE80211_AC_VI */ + 0, /* IEEE80211_AC_VO */ + 0, /* IEEE80211_AC_VO */ +}; + +u8 rtl_tid_to_ac(u8 tid) +{ + return tid_to_ac[tid]; +} +EXPORT_SYMBOL_GPL(rtl_tid_to_ac); + +static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, + struct ieee80211_sta_ht_cap *ht_cap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + ht_cap->ht_supported = true; + ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + + if (rtlpriv->rtlhal.disable_amsdu_8k) + ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; + + /* + *Maximum length of AMPDU that the STA can receive. + *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + */ + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + + /*Minimum MPDU start spacing , */ + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + /*hw->wiphy->bands[NL80211_BAND_2GHZ] + *base on ant_num + *rx_mask: RX mask + *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7 + *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15 + *if rx_ant >= 3 rx_mask[2]= 0xff; + *if BW_40 rx_mask[4]= 0x01; + *highest supported RX rate + */ + if (rtlpriv->dm.supp_phymode_switch) { + pr_info("Support phy mode switch\n"); + + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); + } else { + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_2T2R) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "1T2R or 2T2R\n"); + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = + cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); + } else if (get_rf_type(rtlphy) == RF_1T1R) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); + + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0x00; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = + cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); + } + } +} + +static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw, + struct ieee80211_sta_vht_cap *vht_cap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!(rtlpriv->cfg->spec_ver & RTL_SPEC_SUPPORT_VHT)) + return; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE || + rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { + u16 mcs_map; + + vht_cap->vht_supported = true; + vht_cap->cap = + IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | + IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_TXSTBC | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_HTC_VHT | + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | + IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN | + 0; + + mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; + + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.rx_highest = + cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_highest = + cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + u16 mcs_map; + + vht_cap->vht_supported = true; + vht_cap->cap = + IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | + IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_TXSTBC | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_HTC_VHT | + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | + IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN | + 0; + + mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; + + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.rx_highest = + cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_highest = + cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9); + } +} + +static void _rtl_init_mac80211(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_supported_band *sband; + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && + rtlhal->bandset == BAND_ON_BOTH) { + /* 1: 2.4 G bands */ + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[NL80211_BAND_2GHZ]); + + /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[NL80211_BAND_2GHZ]), &rtl_band_2ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; + + /* 2: 5 G bands */ + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[NL80211_BAND_5GHZ]); + + /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[NL80211_BAND_5GHZ]), &rtl_band_5ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + _rtl_init_hw_vht_capab(hw, &sband->vht_cap); + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[NL80211_BAND_2GHZ]); + + /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[NL80211_BAND_2GHZ]), + &rtl_band_2ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; + } else if (rtlhal->current_bandtype == BAND_ON_5G) { + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[NL80211_BAND_5GHZ]); + + /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[NL80211_BAND_5GHZ]), + &rtl_band_5ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + _rtl_init_hw_vht_capab(hw, &sband->vht_cap); + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; + } else { + pr_err("Err BAND %d\n", + rtlhal->current_bandtype); + } + } + /* <5> set hw caps */ + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, RX_INCLUDES_FCS); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, MFP_CAPABLE); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + + /* swlps or hwlps has been set in diff chip in init_sw_vars */ + if (rtlpriv->psc.swctrl_lps) { + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, PS_NULLFUNC_STACK); + } + if (rtlpriv->psc.fwctrl_lps) { + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + } + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + + hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + + hw->wiphy->rts_threshold = 2347; + + hw->queues = AC_MAX; + hw->extra_tx_headroom = RTL_TX_HEADER_SIZE; + + /* TODO: Correct this value for our hw */ + hw->max_listen_interval = MAX_LISTEN_INTERVAL; + hw->max_rate_tries = MAX_RATE_TRIES; + /* hw->max_rates = 1; */ + hw->sta_data_size = sizeof(struct rtl_sta_info); + +/* wowlan is not supported by kernel if CONFIG_PM is not defined */ +#ifdef CONFIG_PM + if (rtlpriv->psc.wo_wlan_mode) { + if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_MAGIC_PACKET) + rtlpriv->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT; + if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_PATTERN_MATCH) { + rtlpriv->wowlan.n_patterns = + MAX_SUPPORT_WOL_PATTERN_NUM; + rtlpriv->wowlan.pattern_min_len = MIN_WOL_PATTERN_SIZE; + rtlpriv->wowlan.pattern_max_len = MAX_WOL_PATTERN_SIZE; + } + hw->wiphy->wowlan = &rtlpriv->wowlan; + } +#endif + + /* <6> mac address */ + if (is_valid_ether_addr(rtlefuse->dev_addr)) { + SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr); + } else { + u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 }; + + get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1); + SET_IEEE80211_PERM_ADDR(hw, rtlmac1); + } +} + +static void rtl_watchdog_wq_callback(struct work_struct *work); +static void rtl_fwevt_wq_callback(struct work_struct *work); +static void rtl_c2hcmd_wq_callback(struct work_struct *work); + +static int _rtl_init_deferred_work(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct workqueue_struct *wq; + + wq = alloc_workqueue("%s", WQ_UNBOUND, 0, rtlpriv->cfg->name); + if (!wq) + return -ENOMEM; + + /* <1> timer */ + timer_setup(&rtlpriv->works.watchdog_timer, + rtl_watch_dog_timer_callback, 0); + + /* <2> work queue */ + rtlpriv->works.hw = hw; + rtlpriv->works.rtl_wq = wq; + + INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, + rtl_watchdog_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, + rtl_ips_nic_off_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ps_work, rtl_swlps_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, + rtl_swlps_rfon_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq, rtl_fwevt_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.c2hcmd_wq, rtl_c2hcmd_wq_callback); + return 0; +} + +void rtl_deinit_deferred_work(struct ieee80211_hw *hw, bool ips_wq) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + timer_delete_sync(&rtlpriv->works.watchdog_timer); + + cancel_delayed_work_sync(&rtlpriv->works.watchdog_wq); + if (ips_wq) + cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); + else + cancel_delayed_work_sync(&rtlpriv->works.ips_nic_off_wq); + cancel_delayed_work_sync(&rtlpriv->works.ps_work); + cancel_delayed_work_sync(&rtlpriv->works.ps_rfon_wq); + cancel_delayed_work_sync(&rtlpriv->works.fwevt_wq); + cancel_delayed_work_sync(&rtlpriv->works.c2hcmd_wq); +} +EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work); + +void rtl_init_rfkill(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + bool radio_state; + bool blocked; + u8 valid = 0; + + /*set init state to on */ + rtlpriv->rfkill.rfkill_state = true; + wiphy_rfkill_set_hw_state(hw->wiphy, 0); + + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + + if (valid) { + pr_info("rtlwifi: wireless switch is %s\n", + rtlpriv->rfkill.rfkill_state ? "on" : "off"); + + rtlpriv->rfkill.rfkill_state = radio_state; + + blocked = rtlpriv->rfkill.rfkill_state != 1; + wiphy_rfkill_set_hw_state(hw->wiphy, blocked); + } + + wiphy_rfkill_start_polling(hw->wiphy); +} +EXPORT_SYMBOL(rtl_init_rfkill); + +void rtl_deinit_rfkill(struct ieee80211_hw *hw) +{ + wiphy_rfkill_stop_polling(hw->wiphy); +} +EXPORT_SYMBOL_GPL(rtl_deinit_rfkill); + +int rtl_init_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + /* <1> init mac80211 */ + _rtl_init_mac80211(hw); + rtlmac->hw = hw; + + /* <2> rate control register */ + hw->rate_control_algorithm = "rtl_rc"; + + /* + * <3> init CRDA must come after init + * mac80211 hw in _rtl_init_mac80211. + */ + if (rtl_regd_init(hw, rtl_reg_notifier)) { + pr_err("REGD init failed\n"); + return 1; + } + + /* <4> locks */ + mutex_init(&rtlpriv->locks.conf_mutex); + mutex_init(&rtlpriv->locks.ips_mutex); + mutex_init(&rtlpriv->locks.lps_mutex); + spin_lock_init(&rtlpriv->locks.irq_th_lock); + spin_lock_init(&rtlpriv->locks.h2c_lock); + spin_lock_init(&rtlpriv->locks.rf_ps_lock); + spin_lock_init(&rtlpriv->locks.rf_lock); + spin_lock_init(&rtlpriv->locks.waitq_lock); + spin_lock_init(&rtlpriv->locks.entry_list_lock); + spin_lock_init(&rtlpriv->locks.scan_list_lock); + spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); + spin_lock_init(&rtlpriv->locks.fw_ps_lock); + spin_lock_init(&rtlpriv->locks.iqk_lock); + /* <5> init list */ + INIT_LIST_HEAD(&rtlpriv->entry_list); + INIT_LIST_HEAD(&rtlpriv->scan_list.list); + skb_queue_head_init(&rtlpriv->tx_report.queue); + skb_queue_head_init(&rtlpriv->c2hcmd_queue); + + rtlmac->link_state = MAC80211_NOLINK; + + /* <6> init deferred work */ + return _rtl_init_deferred_work(hw); +} +EXPORT_SYMBOL_GPL(rtl_init_core); + +static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw); +static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw, + bool timeout); + +void rtl_deinit_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_c2hcmd_launcher(hw, 0); + rtl_free_entries_from_scan_list(hw); + rtl_free_entries_from_ack_queue(hw, false); + if (rtlpriv->works.rtl_wq) { + destroy_workqueue(rtlpriv->works.rtl_wq); + rtlpriv->works.rtl_wq = NULL; + } +} +EXPORT_SYMBOL_GPL(rtl_deinit_core); + +void rtl_init_rx_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); +} +EXPORT_SYMBOL_GPL(rtl_init_rx_config); + +/********************************************************* + * + * tx information functions + * + *********************************************************/ +static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rate_flag = info->control.rates[0].flags; + + tcb_desc->use_shortpreamble = false; + + /* 1M can only use Long Preamble. 11B spec */ + if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]) + return; + else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + tcb_desc->use_shortpreamble = true; + + return; +} + +static void _rtl_query_shortgi(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 rate_flag = info->control.rates[0].flags; + u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0; + u8 sgi_80 = 0, bw_80 = 0; + + tcb_desc->use_shortgi = false; + + if (sta == NULL) + return; + + sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + + if (!sta->deflink.ht_cap.ht_supported && + !sta->deflink.vht_cap.vht_supported) + return; + + if (!sgi_40 && !sgi_20) + return; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + bw_80 = mac->bw_80; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; + bw_80 = sta->deflink.vht_cap.vht_supported; + } + + if (bw_80) { + if (sgi_80) + tcb_desc->use_shortgi = true; + else + tcb_desc->use_shortgi = false; + } else { + if (bw_40 && sgi_40) + tcb_desc->use_shortgi = true; + else if (!bw_40 && sgi_20) + tcb_desc->use_shortgi = true; + } + + if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) + tcb_desc->use_shortgi = false; +} + +static void _rtl_query_protection_mode(struct ieee80211_hw *hw, + struct rtl_tcb_desc *tcb_desc, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rate_flag = info->control.rates[0].flags; + + /* Common Settings */ + tcb_desc->rts_stbc = false; + tcb_desc->cts_enable = false; + tcb_desc->rts_sc = 0; + tcb_desc->rts_bw = false; + tcb_desc->rts_use_shortpreamble = false; + tcb_desc->rts_use_shortgi = false; + + if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { + /* Use CTS-to-SELF in protection mode. */ + tcb_desc->rts_enable = true; + tcb_desc->cts_enable = true; + tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; + } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { + /* Use RTS-CTS in protection mode. */ + tcb_desc->rts_enable = true; + tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; + } +} + +u8 rtl_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index, + enum wireless_mode wirelessmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 ret = 0; + + switch (rate_index) { + case RATR_INX_WIRELESS_NGB: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_BGN_40M_1SS; + else + ret = RATEID_IDX_BGN_40M_2SS; + ; break; + case RATR_INX_WIRELESS_N: + case RATR_INX_WIRELESS_NG: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_GN_N1SS; + else + ret = RATEID_IDX_GN_N2SS; + ; break; + case RATR_INX_WIRELESS_NB: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_BGN_20M_1SS_BN; + else + ret = RATEID_IDX_BGN_20M_2SS_BN; + ; break; + case RATR_INX_WIRELESS_GB: + ret = RATEID_IDX_BG; + break; + case RATR_INX_WIRELESS_G: + ret = RATEID_IDX_G; + break; + case RATR_INX_WIRELESS_B: + ret = RATEID_IDX_B; + break; + case RATR_INX_WIRELESS_MC: + if (wirelessmode == WIRELESS_MODE_B || + wirelessmode == WIRELESS_MODE_G || + wirelessmode == WIRELESS_MODE_N_24G || + wirelessmode == WIRELESS_MODE_AC_24G) + ret = RATEID_IDX_BG; + else + ret = RATEID_IDX_G; + break; + case RATR_INX_WIRELESS_AC_5N: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_VHT_1SS; + else + ret = RATEID_IDX_VHT_2SS; + break; + case RATR_INX_WIRELESS_AC_24N: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_VHT_1SS; + else + ret = RATEID_IDX_VHT_2SS; + } else { + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_MIX1; + else + ret = RATEID_IDX_MIX2; + } + break; + default: + ret = RATEID_IDX_BGN_40M_2SS; + break; + } + return ret; +} +EXPORT_SYMBOL(rtl_mrate_idx_to_arfr_id); + +static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct rtl_tcb_desc *tcb_desc) +{ +#define SET_RATE_ID(rate_id) \ + ({typeof(rate_id) _id = rate_id; \ + ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \ + rtl_mrate_idx_to_arfr_id(hw, _id, \ + (sta_entry ? sta_entry->wireless_mode : \ + WIRELESS_MODE_G)) : \ + _id); }) + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u8 ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC); + + if (sta) { + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + ratr_index = sta_entry->ratr_index; + } + if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { + if (mac->opmode == NL80211_IFTYPE_STATION) { + tcb_desc->ratr_index = 0; + } else if (mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + if (tcb_desc->multicast || tcb_desc->broadcast) { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; + tcb_desc->use_driver_rate = 1; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_MC); + } else { + tcb_desc->ratr_index = ratr_index; + } + } else if (mac->opmode == NL80211_IFTYPE_AP) { + tcb_desc->ratr_index = ratr_index; + } + } + + if (rtlpriv->dm.useramask) { + tcb_desc->ratr_index = ratr_index; + /* TODO we will differentiate adhoc and station future */ + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + tcb_desc->mac_id = 0; + + if (sta && + (rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID)) + ; /* use sta_entry->ratr_index */ + else if (mac->mode == WIRELESS_MODE_AC_5G) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_AC_5N); + else if (mac->mode == WIRELESS_MODE_AC_24G) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_AC_24N); + else if (mac->mode == WIRELESS_MODE_N_24G) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_NGB); + else if (mac->mode == WIRELESS_MODE_N_5G) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_NG); + else if (mac->mode & WIRELESS_MODE_G) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_GB); + else if (mac->mode & WIRELESS_MODE_B) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_B); + else if (mac->mode & WIRELESS_MODE_A) + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_G); + + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (NULL != sta) { + if (sta->aid > 0) + tcb_desc->mac_id = sta->aid + 1; + else + tcb_desc->mac_id = 1; + } else { + tcb_desc->mac_id = 0; + } + } + } +#undef SET_RATE_ID +} + +static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + tcb_desc->packet_bw = false; + if (!sta) + return; + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + if (!(sta->deflink.ht_cap.ht_supported) || + !(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + return; + } else if (mac->opmode == NL80211_IFTYPE_STATION) { + if (!mac->bw_40 || !(sta->deflink.ht_cap.ht_supported)) + return; + } + if (tcb_desc->multicast || tcb_desc->broadcast) + return; + + /*use legency rate, shall use 20MHz */ + if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]) + return; + + tcb_desc->packet_bw = HT_CHANNEL_WIDTH_20_40; + + if (rtlpriv->cfg->spec_ver & RTL_SPEC_SUPPORT_VHT) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + if (!(sta->deflink.vht_cap.vht_supported)) + return; + } else if (mac->opmode == NL80211_IFTYPE_STATION) { + if (!mac->bw_80 || + !(sta->deflink.vht_cap.vht_supported)) + return; + } + if (tcb_desc->hw_rate <= + rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]) + return; + tcb_desc->packet_bw = HT_CHANNEL_WIDTH_80; + } +} + +static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 hw_rate; + u16 tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); + + if ((get_rf_type(rtlphy) == RF_2T2R) && + (tx_mcs_map & 0x000c) != 0x000c) { + if ((tx_mcs_map & 0x000c) >> 2 == + IEEE80211_VHT_MCS_SUPPORT_0_7) + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS7]; + else if ((tx_mcs_map & 0x000c) >> 2 == + IEEE80211_VHT_MCS_SUPPORT_0_8) + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS8]; + else + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9]; + } else { + if ((tx_mcs_map & 0x0003) == + IEEE80211_VHT_MCS_SUPPORT_0_7) + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7]; + else if ((tx_mcs_map & 0x0003) == + IEEE80211_VHT_MCS_SUPPORT_0_8) + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS8]; + else + hw_rate = + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9]; + } + + return hw_rate; +} + +static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 hw_rate; + + if (get_rf_type(rtlphy) == RF_2T2R && + sta->deflink.ht_cap.mcs.rx_mask[1] != 0) + hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]; + else + hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]; + + return hw_rate; +} + +/* mac80211's rate_idx is like this: + * + * 2.4G band:rx_status->band == NL80211_BAND_2GHZ + * + * B/G rate: + * (rx_status->flag & RX_FLAG_HT) = 0, + * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11, + * + * N rate: + * (rx_status->flag & RX_FLAG_HT) = 1, + * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15 + * + * 5G band:rx_status->band == NL80211_BAND_5GHZ + * A rate: + * (rx_status->flag & RX_FLAG_HT) = 0, + * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7, + * + * N rate: + * (rx_status->flag & RX_FLAG_HT) = 1, + * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15 + * + * VHT rates: + * DESC_RATEVHT1SS_MCS0-->DESC_RATEVHT1SS_MCS9 ==> idx is 0-->9 + * DESC_RATEVHT2SS_MCS0-->DESC_RATEVHT2SS_MCS9 ==> idx is 0-->9 + */ +int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht, + u8 desc_rate) +{ + int rate_idx; + + if (isvht) { + switch (desc_rate) { + case DESC_RATEVHT1SS_MCS0: + rate_idx = 0; + break; + case DESC_RATEVHT1SS_MCS1: + rate_idx = 1; + break; + case DESC_RATEVHT1SS_MCS2: + rate_idx = 2; + break; + case DESC_RATEVHT1SS_MCS3: + rate_idx = 3; + break; + case DESC_RATEVHT1SS_MCS4: + rate_idx = 4; + break; + case DESC_RATEVHT1SS_MCS5: + rate_idx = 5; + break; + case DESC_RATEVHT1SS_MCS6: + rate_idx = 6; + break; + case DESC_RATEVHT1SS_MCS7: + rate_idx = 7; + break; + case DESC_RATEVHT1SS_MCS8: + rate_idx = 8; + break; + case DESC_RATEVHT1SS_MCS9: + rate_idx = 9; + break; + case DESC_RATEVHT2SS_MCS0: + rate_idx = 0; + break; + case DESC_RATEVHT2SS_MCS1: + rate_idx = 1; + break; + case DESC_RATEVHT2SS_MCS2: + rate_idx = 2; + break; + case DESC_RATEVHT2SS_MCS3: + rate_idx = 3; + break; + case DESC_RATEVHT2SS_MCS4: + rate_idx = 4; + break; + case DESC_RATEVHT2SS_MCS5: + rate_idx = 5; + break; + case DESC_RATEVHT2SS_MCS6: + rate_idx = 6; + break; + case DESC_RATEVHT2SS_MCS7: + rate_idx = 7; + break; + case DESC_RATEVHT2SS_MCS8: + rate_idx = 8; + break; + case DESC_RATEVHT2SS_MCS9: + rate_idx = 9; + break; + default: + rate_idx = 0; + break; + } + return rate_idx; + } + if (false == isht) { + if (NL80211_BAND_2GHZ == hw->conf.chandef.chan->band) { + switch (desc_rate) { + case DESC_RATE1M: + rate_idx = 0; + break; + case DESC_RATE2M: + rate_idx = 1; + break; + case DESC_RATE5_5M: + rate_idx = 2; + break; + case DESC_RATE11M: + rate_idx = 3; + break; + case DESC_RATE6M: + rate_idx = 4; + break; + case DESC_RATE9M: + rate_idx = 5; + break; + case DESC_RATE12M: + rate_idx = 6; + break; + case DESC_RATE18M: + rate_idx = 7; + break; + case DESC_RATE24M: + rate_idx = 8; + break; + case DESC_RATE36M: + rate_idx = 9; + break; + case DESC_RATE48M: + rate_idx = 10; + break; + case DESC_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 0; + break; + } + } else { + switch (desc_rate) { + case DESC_RATE6M: + rate_idx = 0; + break; + case DESC_RATE9M: + rate_idx = 1; + break; + case DESC_RATE12M: + rate_idx = 2; + break; + case DESC_RATE18M: + rate_idx = 3; + break; + case DESC_RATE24M: + rate_idx = 4; + break; + case DESC_RATE36M: + rate_idx = 5; + break; + case DESC_RATE48M: + rate_idx = 6; + break; + case DESC_RATE54M: + rate_idx = 7; + break; + default: + rate_idx = 0; + break; + } + } + } else { + switch (desc_rate) { + case DESC_RATEMCS0: + rate_idx = 0; + break; + case DESC_RATEMCS1: + rate_idx = 1; + break; + case DESC_RATEMCS2: + rate_idx = 2; + break; + case DESC_RATEMCS3: + rate_idx = 3; + break; + case DESC_RATEMCS4: + rate_idx = 4; + break; + case DESC_RATEMCS5: + rate_idx = 5; + break; + case DESC_RATEMCS6: + rate_idx = 6; + break; + case DESC_RATEMCS7: + rate_idx = 7; + break; + case DESC_RATEMCS8: + rate_idx = 8; + break; + case DESC_RATEMCS9: + rate_idx = 9; + break; + case DESC_RATEMCS10: + rate_idx = 10; + break; + case DESC_RATEMCS11: + rate_idx = 11; + break; + case DESC_RATEMCS12: + rate_idx = 12; + break; + case DESC_RATEMCS13: + rate_idx = 13; + break; + case DESC_RATEMCS14: + rate_idx = 14; + break; + case DESC_RATEMCS15: + rate_idx = 15; + break; + default: + rate_idx = 0; + break; + } + } + return rate_idx; +} +EXPORT_SYMBOL(rtlwifi_rate_mapping); + +static u8 _rtl_get_tx_hw_rate(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_rate *r = &info->status.rates[0]; + struct ieee80211_rate *txrate; + u8 hw_value = 0x0; + + if (r->flags & IEEE80211_TX_RC_MCS) { + /* HT MCS0-15 */ + hw_value = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15] - 15 + + r->idx; + } else if (r->flags & IEEE80211_TX_RC_VHT_MCS) { + /* VHT MCS0-9, NSS */ + if (ieee80211_rate_get_vht_nss(r) == 2) + hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9]; + else + hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9]; + + hw_value = hw_value - 9 + ieee80211_rate_get_vht_mcs(r); + } else { + /* legacy */ + txrate = ieee80211_get_tx_rate(hw, info); + + if (txrate) + hw_value = txrate->hw_value; + } + + /* check 5G band */ + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G && + hw_value < rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M]) + hw_value = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M]; + + return hw_value; +} + +void rtl_get_tcb_desc(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) +{ +#define SET_RATE_ID(rate_id) \ + ({typeof(rate_id) _id = rate_id; \ + ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \ + rtl_mrate_idx_to_arfr_id(hw, _id, \ + (sta_entry ? sta_entry->wireless_mode : \ + WIRELESS_MODE_G)) : \ + _id); }) + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + struct rtl_sta_info *sta_entry = + (sta ? (struct rtl_sta_info *)sta->drv_priv : NULL); + + __le16 fc = rtl_get_fc(skb); + + tcb_desc->hw_rate = _rtl_get_tx_hw_rate(hw, info); + + if (rtl_is_tx_report_skb(hw, skb)) + tcb_desc->use_spe_rpt = 1; + + if (ieee80211_is_data(fc)) { + /* + *we set data rate INX 0 + *in rtl_rc.c if skb is special data or + *mgt which need low data rate. + */ + + /* + *So tcb_desc->hw_rate is just used for + *special data and mgt frames + */ + if (info->control.rates[0].idx == 0 || + ieee80211_is_nullfunc(fc)) { + tcb_desc->use_driver_rate = true; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_MC); + + tcb_desc->disable_ratefallback = 1; + } else { + /* + *because hw will nerver use hw_rate + *when tcb_desc->use_driver_rate = false + *so we never set highest N rate here, + *and N rate will all be controlled by FW + *when tcb_desc->use_driver_rate = false + */ + if (sta && sta->deflink.vht_cap.vht_supported) { + tcb_desc->hw_rate = + _rtl_get_vht_highest_n_rate(hw, sta); + } else { + if (sta && sta->deflink.ht_cap.ht_supported) { + tcb_desc->hw_rate = + _rtl_get_highest_n_rate(hw, sta); + } else { + if (rtlmac->mode == WIRELESS_MODE_B) { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]; + } else { + tcb_desc->hw_rate = + rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]; + } + } + } + } + + if (is_multicast_ether_addr(hdr->addr1)) + tcb_desc->multicast = 1; + else if (is_broadcast_ether_addr(hdr->addr1)) + tcb_desc->broadcast = 1; + + _rtl_txrate_selectmode(hw, sta, tcb_desc); + _rtl_query_bandwidth_mode(hw, sta, tcb_desc); + _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); + _rtl_query_shortgi(hw, sta, tcb_desc, info); + _rtl_query_protection_mode(hw, tcb_desc, info); + } else { + tcb_desc->use_driver_rate = true; + tcb_desc->ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC); + tcb_desc->disable_ratefallback = 1; + tcb_desc->mac_id = 0; + tcb_desc->packet_bw = false; + } +#undef SET_RATE_ID +} +EXPORT_SYMBOL(rtl_get_tcb_desc); + +bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + __le16 fc = rtl_get_fc(skb); + + if (ieee80211_is_auth(fc)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + + mac->link_state = MAC80211_LINKING; + /* Dul mac */ + rtlpriv->phy.need_iqk = true; + + } + + return true; +} +EXPORT_SYMBOL_GPL(rtl_tx_mgmt_proc); + +struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, u8 *sa, + u8 *bssid, u16 tid); + +static void process_agg_start(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u16 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_rx_status rx_status = { 0 }; + struct sk_buff *skb_delba = NULL; + + skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid); + if (skb_delba) { + rx_status.freq = hw->conf.chandef.chan->center_freq; + rx_status.band = hw->conf.chandef.chan->band; + rx_status.flag |= RX_FLAG_DECRYPTED; + rx_status.flag |= RX_FLAG_MACTIME_START; + rx_status.rate_idx = 0; + rx_status.signal = 50 + 10; + memcpy(IEEE80211_SKB_RXCB(skb_delba), + &rx_status, sizeof(rx_status)); + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, + "fake del\n", + skb_delba->data, + skb_delba->len); + ieee80211_rx_irqsafe(hw, skb_delba); + } +} + +bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt; + __le16 fc = rtl_get_fc(skb); + + if (!ieee80211_is_action(fc)) + return true; + + mgmt = (void *)skb->data; + if (skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) + return true; + + switch (mgmt->u.action.category) { + case ACT_CAT_BA: + switch (mgmt->u.action.action_code) { + case ACT_ADDBAREQ: + if (mac->act_scanning) + return false; + + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "%s ACT_ADDBAREQ From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n", + skb->data, skb->len); + if (!is_tx) { + struct ieee80211_sta *sta = NULL; + struct rtl_sta_info *sta_entry = NULL; + struct rtl_tid_data *tid_data; + u16 capab = 0, tid = 0; + + if (skb->len < IEEE80211_MIN_ACTION_SIZE(addba_req)) + return true; + + rcu_read_lock(); + sta = rtl_find_sta(hw, hdr->addr3); + if (sta == NULL) { + rtl_dbg(rtlpriv, COMP_SEND | COMP_RECV, + DBG_DMESG, "sta is NULL\n"); + rcu_read_unlock(); + return true; + } + + sta_entry = + (struct rtl_sta_info *)sta->drv_priv; + capab = + le16_to_cpu(mgmt->u.action.addba_req.capab); + tid = (capab & + IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; + if (tid >= MAX_TID_COUNT) { + rcu_read_unlock(); + return true; + } + tid_data = &sta_entry->tids[tid]; + if (tid_data->agg.rx_agg_state == + RTL_RX_AGG_START) + process_agg_start(hw, hdr, tid); + rcu_read_unlock(); + } + break; + case ACT_ADDBARSP: + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); + break; + case ACT_DELBA: + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "ACT_ADDBADEL From :%pM\n", hdr->addr2); + break; + } + break; + default: + break; + } + + return true; +} +EXPORT_SYMBOL_GPL(rtl_action_proc); + +static void setup_special_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc, + int type) +{ + struct ieee80211_hw *hw = rtlpriv->hw; + + rtlpriv->ra.is_special_data = true; + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_special_packet_notify( + rtlpriv, type); + rtl_lps_leave(hw, false); + ppsc->last_delaylps_stamp_jiffies = jiffies; +} + +static const u8 *rtl_skb_ether_type_ptr(struct ieee80211_hw *hw, + struct sk_buff *skb, bool is_enc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); + u8 encrypt_header_len = 0; + u8 offset; + + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case WEP40_ENCRYPTION: + case WEP104_ENCRYPTION: + encrypt_header_len = 4;/*WEP_IV_LEN*/ + break; + case TKIP_ENCRYPTION: + encrypt_header_len = 8;/*TKIP_IV_LEN*/ + break; + case AESCCMP_ENCRYPTION: + encrypt_header_len = 8;/*CCMP_HDR_LEN;*/ + break; + default: + break; + } + + offset = mac_hdr_len + SNAP_SIZE; + if (is_enc) + offset += encrypt_header_len; + + return skb->data + offset; +} + +/*should call before software enc*/ +u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, + bool is_enc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + __le16 fc = rtl_get_fc(skb); + u16 ether_type; + const u8 *ether_type_ptr; + const struct iphdr *ip; + + if (!ieee80211_is_data(fc)) + goto end; + + ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, is_enc); + ether_type = be16_to_cpup((__be16 *)ether_type_ptr); + + if (ETH_P_IP == ether_type) { + ip = (struct iphdr *)((u8 *)ether_type_ptr + + PROTOC_TYPE_SIZE); + if (IPPROTO_UDP == ip->protocol) { + struct udphdr *udp = (struct udphdr *)((u8 *)ip + + (ip->ihl << 2)); + if (((((u8 *)udp)[1] == 68) && + (((u8 *)udp)[3] == 67)) || + ((((u8 *)udp)[1] == 67) && + (((u8 *)udp)[3] == 68))) { + /* 68 : UDP BOOTP client + * 67 : UDP BOOTP server + */ + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), + DBG_DMESG, "dhcp %s !!\n", + (is_tx) ? "Tx" : "Rx"); + + if (is_tx) + setup_special_tx(rtlpriv, ppsc, + PACKET_DHCP); + + return true; + } + } + } else if (ETH_P_ARP == ether_type) { + if (is_tx) + setup_special_tx(rtlpriv, ppsc, PACKET_ARP); + + return true; + } else if (ETH_P_PAE == ether_type) { + /* EAPOL is seens as in-4way */ + rtlpriv->btcoexist.btc_info.in_4way = true; + rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; + + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); + + if (is_tx) { + rtlpriv->ra.is_special_data = true; + rtl_lps_leave(hw, false); + ppsc->last_delaylps_stamp_jiffies = jiffies; + + setup_special_tx(rtlpriv, ppsc, PACKET_EAPOL); + } + + return true; + } else if (ETH_P_IPV6 == ether_type) { + /* TODO: Handle any IPv6 cases that need special handling. + * For now, always return false + */ + goto end; + } + +end: + rtlpriv->ra.is_special_data = false; + return false; +} +EXPORT_SYMBOL_GPL(rtl_is_special_data); + +void rtl_tx_ackqueue(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_report *tx_report = &rtlpriv->tx_report; + + __skb_queue_tail(&tx_report->queue, skb); +} +EXPORT_SYMBOL_GPL(rtl_tx_ackqueue); + +static void rtl_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, + bool ack) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_info *info; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + if (ack) { + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: ack\n"); + info->flags |= IEEE80211_TX_STAT_ACK; + } else { + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: not ack\n"); + info->flags &= ~IEEE80211_TX_STAT_ACK; + } + ieee80211_tx_status_irqsafe(hw, skb); +} + +bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + u16 ether_type; + const u8 *ether_type_ptr; + __le16 fc = rtl_get_fc(skb); + + ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, true); + ether_type = be16_to_cpup((__be16 *)ether_type_ptr); + + if (ether_type == ETH_P_PAE || ieee80211_is_nullfunc(fc)) + return true; + + return false; +} + +static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw, + struct rtlwifi_tx_info *tx_info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_report *tx_report = &rtlpriv->tx_report; + u16 sn; + + /* SW_DEFINE[11:8] are reserved (driver fills zeros) + * SW_DEFINE[7:2] are used by driver + * SW_DEFINE[1:0] are reserved for firmware (driver fills zeros) + */ + sn = (atomic_inc_return(&tx_report->sn) & 0x003F) << 2; + + tx_report->last_sent_sn = sn; + tx_report->last_sent_time = jiffies; + tx_info->sn = sn; + tx_info->send_time = tx_report->last_sent_time; + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Send TX-Report sn=0x%X\n", sn); + + return sn; +} + +void rtl_set_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc, + struct ieee80211_hw *hw, struct rtlwifi_tx_info *tx_info) +{ + if (ptcb_desc->use_spe_rpt) { + u16 sn = rtl_get_tx_report_sn(hw, tx_info); + + SET_TX_DESC_SPE_RPT(pdesc, 1); + SET_TX_DESC_SW_DEFINE(pdesc, sn); + } +} +EXPORT_SYMBOL_GPL(rtl_set_tx_report); + +void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_report *tx_report = &rtlpriv->tx_report; + struct rtlwifi_tx_info *tx_info; + struct sk_buff_head *queue = &tx_report->queue; + struct sk_buff *skb; + u16 sn; + u8 st, retry; + + if (rtlpriv->cfg->spec_ver & RTL_SPEC_EXT_C2H) { + sn = GET_TX_REPORT_SN_V2(tmp_buf); + st = GET_TX_REPORT_ST_V2(tmp_buf); + retry = GET_TX_REPORT_RETRY_V2(tmp_buf); + } else { + sn = GET_TX_REPORT_SN_V1(tmp_buf); + st = GET_TX_REPORT_ST_V1(tmp_buf); + retry = GET_TX_REPORT_RETRY_V1(tmp_buf); + } + + tx_report->last_recv_sn = sn; + + skb_queue_walk(queue, skb) { + tx_info = rtl_tx_skb_cb_info(skb); + if (tx_info->sn == sn) { + skb_unlink(skb, queue); + rtl_tx_status(hw, skb, st == 0); + break; + } + } + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n", + st, sn, retry); +} +EXPORT_SYMBOL_GPL(rtl_tx_report_handler); + +bool rtl_check_tx_report_acked(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_report *tx_report = &rtlpriv->tx_report; + + if (tx_report->last_sent_sn == tx_report->last_recv_sn) + return true; + + if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) { + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_WARNING, + "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n", + tx_report->last_sent_sn, tx_report->last_recv_sn); + return true; /* 3 sec. (timeout) seen as acked */ + } + + return false; +} + +void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + + for (i = 0; i < wait_ms; i++) { + if (rtl_check_tx_report_acked(hw)) + break; + usleep_range(1000, 2000); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); + } +} + +u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum wireless_mode wirelessmode, + struct ieee80211_tx_queue_params *param) +{ + u32 reg = 0; + u8 sifstime = 10; + u8 slottime = 20; + + /* AIFS = AIFSN * slot time + SIFS */ + switch (wirelessmode) { + case WIRELESS_MODE_A: + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + case WIRELESS_MODE_AC_5G: + case WIRELESS_MODE_AC_24G: + sifstime = 16; + slottime = 9; + break; + case WIRELESS_MODE_G: + slottime = (vif->bss_conf.use_short_slot ? 9 : 20); + break; + default: + break; + } + + reg |= (param->txop & 0x7FF) << 16; + reg |= (fls(param->cw_max) & 0xF) << 12; + reg |= (fls(param->cw_min) & 0xF) << 8; + reg |= (param->aifs & 0x0F) * slottime + sifstime; + + return reg; +} +EXPORT_SYMBOL_GPL(rtl_get_hal_edca_param); + +/********************************************************* + * + * functions called by core.c + * + *********************************************************/ +int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tid_data *tid_data; + struct rtl_sta_info *sta_entry = NULL; + + if (sta == NULL) + return -EINVAL; + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + tid_data = &sta_entry->tids[tid]; + + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, + *ssn); + + tid_data->agg.agg_state = RTL_AGG_START; + + return IEEE80211_AMPDU_TX_START_IMMEDIATE; +} + +int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *sta_entry = NULL; + + if (sta == NULL) + return -EINVAL; + + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; + + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + return 0; +} + +int rtl_rx_agg_start(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tid_data *tid_data; + struct rtl_sta_info *sta_entry = NULL; + u8 reject_agg; + + if (sta == NULL) + return -EINVAL; + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + if (rtlpriv->cfg->ops->get_btc_status()) { + rtlpriv->btcoexist.btc_ops->btc_get_ampdu_cfg(rtlpriv, + &reject_agg, + NULL, NULL); + if (reject_agg) + return -EINVAL; + } + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + tid_data = &sta_entry->tids[tid]; + + rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); + + tid_data->agg.rx_agg_state = RTL_RX_AGG_START; + return 0; +} + +int rtl_rx_agg_stop(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *sta_entry = NULL; + + if (sta == NULL) + return -EINVAL; + + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + sta_entry->tids[tid].agg.rx_agg_state = RTL_RX_AGG_STOP; + + return 0; +} + +int rtl_tx_agg_oper(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *sta_entry = NULL; + + if (sta == NULL) + return -EINVAL; + + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); + + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; + + return 0; +} + +void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv) +{ + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + u8 reject_agg = 0, ctrl_agg_size = 0, agg_size = 0; + + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg, + &ctrl_agg_size, &agg_size); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d", + reject_agg, ctrl_agg_size, agg_size); + + rtlpriv->hw->max_rx_aggregation_subframes = + (ctrl_agg_size ? agg_size : IEEE80211_MAX_AMPDU_BUF_HT); +} +EXPORT_SYMBOL(rtl_rx_ampdu_apply); + +/********************************************************* + * + * wq & timer callback functions + * + *********************************************************/ +/* this function is used for roaming */ +void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control) && + !ieee80211_is_probe_resp(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (skb->len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + rtlpriv->link_info.bcn_rx_inperiod++; +} +EXPORT_SYMBOL_GPL(rtl_beacon_statistic); + +static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_bssid_entry *entry, *next; + + list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) { + list_del(&entry->list); + kfree(entry); + rtlpriv->scan_list.num--; + } +} + +static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw, + bool chk_timeout) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_report *tx_report = &rtlpriv->tx_report; + struct sk_buff_head *queue = &tx_report->queue; + struct sk_buff *skb, *tmp; + struct rtlwifi_tx_info *tx_info; + + skb_queue_walk_safe(queue, skb, tmp) { + tx_info = rtl_tx_skb_cb_info(skb); + if (chk_timeout && + time_after(tx_info->send_time + HZ, jiffies)) + continue; + skb_unlink(skb, queue); + rtl_tx_status(hw, skb, false); + } +} + +void rtl_scan_list_expire(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_bssid_entry *entry, *next; + unsigned long flags; + + spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); + + list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) { + /* 180 seconds */ + if (jiffies_to_msecs(jiffies - entry->age) < 180000) + continue; + + list_del(&entry->list); + rtlpriv->scan_list.num--; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "BSSID=%pM is expire in scan list (total=%d)\n", + entry->bssid, rtlpriv->scan_list.num); + kfree(entry); + } + + spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags); + + rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num; +} + +void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + unsigned long flags; + + struct rtl_bssid_entry *entry = NULL, *iter; + + /* check if it is scanning */ + if (!mac->act_scanning) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control) && + !ieee80211_is_probe_resp(hdr->frame_control)) + return; + + spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); + + list_for_each_entry(iter, &rtlpriv->scan_list.list, list) { + if (memcmp(iter->bssid, hdr->addr3, ETH_ALEN) == 0) { + list_del_init(&iter->list); + entry = iter; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Update BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); + break; + } + } + + if (!entry) { + entry = kmalloc_obj(*entry, GFP_ATOMIC); + + if (!entry) + goto label_err; + + memcpy(entry->bssid, hdr->addr3, ETH_ALEN); + rtlpriv->scan_list.num++; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Add BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); + } + + entry->age = jiffies; + + list_add_tail(&entry->list, &rtlpriv->scan_list.list); + +label_err: + spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags); +} +EXPORT_SYMBOL(rtl_collect_scan_list); + +static void rtl_watchdog_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + watchdog_wq.work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + bool busytraffic = false; + bool tx_busy_traffic = false; + bool rx_busy_traffic = false; + bool higher_busytraffic = false; + bool higher_busyrxtraffic = false; + u8 idx, tid; + u32 rx_cnt_inp4eriod = 0; + u32 tx_cnt_inp4eriod = 0; + u32 aver_rx_cnt_inperiod = 0; + u32 aver_tx_cnt_inperiod = 0; + u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0}; + u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0}; + + if (is_hal_stop(rtlhal)) + return; + + /* <1> Determine if action frame is allowed */ + if (mac->link_state > MAC80211_NOLINK) { + if (mac->cnt_after_linked < 20) + mac->cnt_after_linked++; + } else { + mac->cnt_after_linked = 0; + } + + /* <2> to check if traffic busy, if + * busytraffic we don't change channel + */ + if (mac->link_state >= MAC80211_LINKED) { + /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */ + for (idx = 0; idx <= 2; idx++) { + rtlpriv->link_info.num_rx_in4period[idx] = + rtlpriv->link_info.num_rx_in4period[idx + 1]; + rtlpriv->link_info.num_tx_in4period[idx] = + rtlpriv->link_info.num_tx_in4period[idx + 1]; + } + rtlpriv->link_info.num_rx_in4period[3] = + rtlpriv->link_info.num_rx_inperiod; + rtlpriv->link_info.num_tx_in4period[3] = + rtlpriv->link_info.num_tx_inperiod; + for (idx = 0; idx <= 3; idx++) { + rx_cnt_inp4eriod += + rtlpriv->link_info.num_rx_in4period[idx]; + tx_cnt_inp4eriod += + rtlpriv->link_info.num_tx_in4period[idx]; + } + aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4; + aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4; + + /* (2) check traffic busy */ + if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) { + busytraffic = true; + if (aver_rx_cnt_inperiod > aver_tx_cnt_inperiod) + rx_busy_traffic = true; + else + tx_busy_traffic = false; + } + + /* Higher Tx/Rx data. */ + if (aver_rx_cnt_inperiod > 4000 || + aver_tx_cnt_inperiod > 4000) { + higher_busytraffic = true; + + /* Extremely high Rx data. */ + if (aver_rx_cnt_inperiod > 5000) + higher_busyrxtraffic = true; + } + + /* check every tid's tx traffic */ + for (tid = 0; tid <= 7; tid++) { + for (idx = 0; idx <= 2; idx++) + rtlpriv->link_info.tidtx_in4period[tid][idx] = + rtlpriv->link_info.tidtx_in4period[tid] + [idx + 1]; + rtlpriv->link_info.tidtx_in4period[tid][3] = + rtlpriv->link_info.tidtx_inperiod[tid]; + + for (idx = 0; idx <= 3; idx++) + tidtx_inp4eriod[tid] += + rtlpriv->link_info.tidtx_in4period[tid][idx]; + aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4; + if (aver_tidtx_inperiod[tid] > 5000) + rtlpriv->link_info.higher_busytxtraffic[tid] = + true; + else + rtlpriv->link_info.higher_busytxtraffic[tid] = + false; + } + + /* PS is controlled by coex. */ + if (rtlpriv->cfg->ops->get_btc_status() && + rtlpriv->btcoexist.btc_ops->btc_is_bt_ctrl_lps(rtlpriv)) + goto label_lps_done; + + if (rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod > 8 || + rtlpriv->link_info.num_rx_inperiod > 2) + rtl_lps_leave(hw, true); + else + rtl_lps_enter(hw, true); + +label_lps_done: + ; + } + + for (tid = 0; tid <= 7; tid++) + rtlpriv->link_info.tidtx_inperiod[tid] = 0; + + rtlpriv->link_info.busytraffic = busytraffic; + rtlpriv->link_info.higher_busytraffic = higher_busytraffic; + rtlpriv->link_info.rx_busy_traffic = rx_busy_traffic; + rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic; + rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; + + rtlpriv->stats.txbytesunicast_inperiod = + rtlpriv->stats.txbytesunicast - + rtlpriv->stats.txbytesunicast_last; + rtlpriv->stats.rxbytesunicast_inperiod = + rtlpriv->stats.rxbytesunicast - + rtlpriv->stats.rxbytesunicast_last; + rtlpriv->stats.txbytesunicast_last = rtlpriv->stats.txbytesunicast; + rtlpriv->stats.rxbytesunicast_last = rtlpriv->stats.rxbytesunicast; + + rtlpriv->stats.txbytesunicast_inperiod_tp = + (u32)(rtlpriv->stats.txbytesunicast_inperiod * 8 / 2 / + 1024 / 1024); + rtlpriv->stats.rxbytesunicast_inperiod_tp = + (u32)(rtlpriv->stats.rxbytesunicast_inperiod * 8 / 2 / + 1024 / 1024); + + /* <3> DM */ + if (!rtlpriv->cfg->mod_params->disable_watchdog) + rtlpriv->cfg->ops->dm_watchdog(hw); + + /* <4> roaming */ + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + if ((rtlpriv->link_info.bcn_rx_inperiod + + rtlpriv->link_info.num_rx_inperiod) == 0) { + rtlpriv->link_info.roam_times++; + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "AP off for %d s\n", + (rtlpriv->link_info.roam_times * 2)); + + /* if we can't recv beacon for 10s, + * we should reconnect this AP + */ + if (rtlpriv->link_info.roam_times >= 5) { + pr_err("AP off, try to reconnect now\n"); + rtlpriv->link_info.roam_times = 0; + ieee80211_connection_loss( + rtlpriv->mac80211.vif); + } + } else { + rtlpriv->link_info.roam_times = 0; + } + } + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv); + + if (rtlpriv->btcoexist.btc_info.in_4way) { + if (time_after(jiffies, rtlpriv->btcoexist.btc_info.in_4way_ts + + msecs_to_jiffies(IN_4WAY_TIMEOUT_TIME))) + rtlpriv->btcoexist.btc_info.in_4way = false; + } + + rtlpriv->link_info.num_rx_inperiod = 0; + rtlpriv->link_info.num_tx_inperiod = 0; + rtlpriv->link_info.bcn_rx_inperiod = 0; + + /* <6> scan list */ + rtl_scan_list_expire(hw); + + /* <7> check ack queue */ + rtl_free_entries_from_ack_queue(hw, true); +} + +void rtl_watch_dog_timer_callback(struct timer_list *t) +{ + struct rtl_priv *rtlpriv = timer_container_of(rtlpriv, t, + works.watchdog_timer); + + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.watchdog_wq, 0); + + mod_timer(&rtlpriv->works.watchdog_timer, + jiffies + MSECS(RTL_WATCH_DOG_TIME)); +} + +static void rtl_fwevt_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + fwevt_wq.work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->cfg->ops->c2h_command_handle(hw); +} + +static void rtl_c2h_content_parsing(struct ieee80211_hw *hw, + struct sk_buff *skb); + +static bool rtl_c2h_fast_cmd(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + u8 cmd_id = GET_C2H_CMD_ID(skb->data); + + switch (cmd_id) { + case C2H_BT_MP: + return true; + default: + break; + } + + return false; +} + +void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtl_c2h_fast_cmd(hw, skb)) { + rtl_c2h_content_parsing(hw, skb); + kfree_skb(skb); + return; + } + + /* enqueue */ + skb_queue_tail(&rtlpriv->c2hcmd_queue, skb); + + /* wake up wq */ + queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0); +} +EXPORT_SYMBOL(rtl_c2hcmd_enqueue); + +static void rtl_c2h_content_parsing(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + const struct rtl_hal_ops *hal_ops = rtlpriv->cfg->ops; + const struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + u8 cmd_id, cmd_len; + u8 *cmd_buf = NULL; + + cmd_id = GET_C2H_CMD_ID(skb->data); + cmd_len = skb->len - C2H_DATA_OFFSET; + cmd_buf = GET_C2H_DATA_PTR(skb->data); + + switch (cmd_id) { + case C2H_DBG: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n"); + break; + case C2H_TXBF: + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_TXBF!!\n"); + break; + case C2H_TX_REPORT: + rtl_tx_report_handler(hw, cmd_buf, cmd_len); + break; + case C2H_RA_RPT: + if (hal_ops->c2h_ra_report_handler) + hal_ops->c2h_ra_report_handler(hw, cmd_buf, cmd_len); + break; + case C2H_BT_INFO: + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_INFO!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btinfo_notify(rtlpriv, cmd_buf, cmd_len); + break; + case C2H_BT_MP: + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_MP!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btmpinfo_notify(rtlpriv, cmd_buf, cmd_len); + break; + default: + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id); + break; + } +} + +void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct sk_buff *skb; + int i; + + for (i = 0; i < 200; i++) { + /* dequeue a task */ + skb = skb_dequeue(&rtlpriv->c2hcmd_queue); + + /* do it */ + if (!skb) + break; + + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", + *((u8 *)skb->cb)); + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG, + "C2H data: ", skb->data, skb->len); + + if (exec) + rtl_c2h_content_parsing(hw, skb); + + /* free */ + dev_kfree_skb_any(skb); + } +} + +static void rtl_c2hcmd_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + c2hcmd_wq.work); + struct ieee80211_hw *hw = rtlworks->hw; + + rtl_c2hcmd_launcher(hw, 1); +} + +/********************************************************* + * + * frame process functions + * + *********************************************************/ +u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie) +{ + struct ieee80211_mgmt *mgmt = (void *)data; + u8 *pos, *end; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + while (pos < end) { + if (pos + 2 + pos[1] > end) + return NULL; + + if (pos[0] == ie) + return pos; + + pos += 2 + pos[1]; + } + return NULL; +} + +/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */ +/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */ +static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw, + enum ieee80211_smps_mode smps, + u8 *da, u8 *bssid) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct sk_buff *skb; + struct ieee80211_mgmt *action_frame; + + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) + + hw->extra_tx_headroom); + if (!skb) + return NULL; + + skb_reserve(skb, hw->extra_tx_headroom); + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps)); + memcpy(action_frame->da, da, ETH_ALEN); + memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); + memcpy(action_frame->bssid, bssid, ETH_ALEN); + action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); + action_frame->u.action.category = WLAN_CATEGORY_HT; + action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS; + switch (smps) { + case IEEE80211_SMPS_AUTOMATIC:/* 0 */ + case IEEE80211_SMPS_NUM_MODES:/* 4 */ + WARN_ON(1); + fallthrough; + case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ + action_frame->u.action.ht_smps.smps_control = + WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ + break; + case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ + action_frame->u.action.ht_smps.smps_control = + WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ + break; + case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ + action_frame->u.action.ht_smps.smps_control = + WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ + break; + } + + return skb; +} + +int rtl_send_smps_action(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + enum ieee80211_smps_mode smps) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct sk_buff *skb = NULL; + struct rtl_tcb_desc tcb_desc; + u8 bssid[ETH_ALEN] = {0}; + + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + + if (rtlpriv->mac80211.act_scanning) + goto err_free; + + if (!sta) + goto err_free; + + if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) + goto err_free; + + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + goto err_free; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) + memcpy(bssid, rtlpriv->efuse.dev_addr, ETH_ALEN); + else + memcpy(bssid, rtlpriv->mac80211.bssid, ETH_ALEN); + + skb = rtl_make_smps_action(hw, smps, sta->addr, bssid); + /* this is a type = mgmt * stype = action frame */ + if (skb) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_sta_info *sta_entry = + (struct rtl_sta_info *) sta->drv_priv; + sta_entry->mimo_ps = smps; + /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); */ + + info->control.rates[0].idx = 0; + info->band = hw->conf.chandef.chan->band; + rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); + } + return 1; + +err_free: + return 0; +} +EXPORT_SYMBOL(rtl_send_smps_action); + +void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} +EXPORT_SYMBOL(rtl_phy_scan_operation_backup); + +/* because mac80211 have issues when can receive del ba + * so here we just make a fake del_ba if we receive a ba_req + * but rx_agg was opened to let mac80211 release some ba + * related resources, so please this del_ba for tx + */ +struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, + u8 *sa, u8 *bssid, u16 tid) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct sk_buff *skb; + struct ieee80211_mgmt *action_frame; + u16 params; + + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) + + hw->extra_tx_headroom); + if (!skb) + return NULL; + + skb_reserve(skb, hw->extra_tx_headroom); + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(delba)); + memcpy(action_frame->sa, sa, ETH_ALEN); + memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN); + memcpy(action_frame->bssid, bssid, ETH_ALEN); + action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); + action_frame->u.action.category = WLAN_CATEGORY_BACK; + action_frame->u.action.action_code = WLAN_ACTION_DELBA; + params = (u16)(1 << 11); /* bit 11 initiator */ + params |= (u16)(tid << 12); /* bit 15:12 TID number */ + + action_frame->u.action.delba.params = cpu_to_le16(params); + action_frame->u.action.delba.reason_code = + cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); + + return skb; +} + +/********************************************************* + * + * IOT functions + * + *********************************************************/ +static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw, + struct octet_string vendor_ie) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool matched = false; + static u8 athcap_1[] = { 0x00, 0x03, 0x7F }; + static u8 athcap_2[] = { 0x00, 0x13, 0x74 }; + static u8 broadcap_1[] = { 0x00, 0x10, 0x18 }; + static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 }; + static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 }; + static u8 racap[] = { 0x00, 0x0c, 0x43 }; + static u8 ciscocap[] = { 0x00, 0x40, 0x96 }; + static u8 marvcap[] = { 0x00, 0x50, 0x43 }; + + if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 || + memcmp(vendor_ie.octet, athcap_2, 3) == 0) { + rtlpriv->mac80211.vendor = PEER_ATH; + matched = true; + } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 || + memcmp(vendor_ie.octet, broadcap_2, 3) == 0 || + memcmp(vendor_ie.octet, broadcap_3, 3) == 0) { + rtlpriv->mac80211.vendor = PEER_BROAD; + matched = true; + } else if (memcmp(vendor_ie.octet, racap, 3) == 0) { + rtlpriv->mac80211.vendor = PEER_RAL; + matched = true; + } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) { + rtlpriv->mac80211.vendor = PEER_CISCO; + matched = true; + } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) { + rtlpriv->mac80211.vendor = PEER_MARV; + matched = true; + } + + return matched; +} + +static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data, + unsigned int len) +{ + struct ieee80211_mgmt *mgmt = (void *)data; + struct octet_string vendor_ie; + u8 *pos, *end; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + while (pos < end) { + if (pos[0] == 221) { + vendor_ie.length = pos[1]; + vendor_ie.octet = &pos[2]; + if (rtl_chk_vendor_ouisub(hw, vendor_ie)) + return true; + } + + if (pos + 2 + pos[1] > end) + return false; + + pos += 2 + pos[1]; + } + return false; +} + +void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = (void *)data; + u32 vendor = PEER_UNKNOWN; + + static u8 ap3_1[3] = { 0x00, 0x14, 0xbf }; + static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 }; + static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e }; + static u8 ap4_1[3] = { 0x00, 0x90, 0xcc }; + static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e }; + static u8 ap4_3[3] = { 0x00, 0x18, 0x02 }; + static u8 ap4_4[3] = { 0x00, 0x17, 0x3f }; + static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf }; + static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 }; + static u8 ap5_2[3] = { 0x00, 0x21, 0x91 }; + static u8 ap5_3[3] = { 0x00, 0x24, 0x01 }; + static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 }; + static u8 ap5_5[3] = { 0x00, 0x17, 0x9A }; + static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 }; + static u8 ap6_1[3] = { 0x00, 0x17, 0x94 }; + static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 }; + + if (mac->opmode != NL80211_IFTYPE_STATION) + return; + + if (mac->link_state == MAC80211_NOLINK) { + mac->vendor = PEER_UNKNOWN; + return; + } + + if (mac->cnt_after_linked > 2) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + if (rtl_find_221_ie(hw, data, len)) + vendor = mac->vendor; + + if ((memcmp(mac->bssid, ap5_1, 3) == 0) || + (memcmp(mac->bssid, ap5_2, 3) == 0) || + (memcmp(mac->bssid, ap5_3, 3) == 0) || + (memcmp(mac->bssid, ap5_4, 3) == 0) || + (memcmp(mac->bssid, ap5_5, 3) == 0) || + (memcmp(mac->bssid, ap5_6, 3) == 0) || + vendor == PEER_ATH) { + vendor = PEER_ATH; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); + } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || + (memcmp(mac->bssid, ap4_5, 3) == 0) || + (memcmp(mac->bssid, ap4_1, 3) == 0) || + (memcmp(mac->bssid, ap4_2, 3) == 0) || + (memcmp(mac->bssid, ap4_3, 3) == 0) || + vendor == PEER_RAL) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); + vendor = PEER_RAL; + } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || + vendor == PEER_CISCO) { + vendor = PEER_CISCO; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); + } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || + (memcmp(mac->bssid, ap3_2, 3) == 0) || + (memcmp(mac->bssid, ap3_3, 3) == 0) || + vendor == PEER_BROAD) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); + vendor = PEER_BROAD; + } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || + vendor == PEER_MARV) { + vendor = PEER_MARV; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); + } + + mac->vendor = vendor; +} +EXPORT_SYMBOL_GPL(rtl_recognize_peer); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +static int __init rtl_core_module_init(void) +{ + BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION); + BUILD_BUG_ON(MAX_RATE_SECTION_NUM != MAX_RATE_SECTION); + BUILD_BUG_ON(MAX_BASE_NUM_IN_PHY_REG_PG_24G != MAX_RATE_SECTION); + BUILD_BUG_ON(MAX_BASE_NUM_IN_PHY_REG_PG_5G != (MAX_RATE_SECTION - 1)); + + if (rtl_rate_control_register()) + pr_err("rtl: Unable to register rtl_rc, use default RC !!\n"); + + /* add debugfs */ + rtl_debugfs_add_topdir(); + + return 0; +} + +static void __exit rtl_core_module_exit(void) +{ + /*RC*/ + rtl_rate_control_unregister(); + + /* remove debugfs */ + rtl_debugfs_remove_topdir(); +} + +module_init(rtl_core_module_init); +module_exit(rtl_core_module_exit); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h new file mode 100644 index 000000000..f3a6a43a4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/base.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_BASE_H__ +#define __RTL_BASE_H__ + +enum ap_peer { + PEER_UNKNOWN = 0, + PEER_RTL = 1, + PEER_RTL_92SE = 2, + PEER_BROAD = 3, + PEER_RAL = 4, + PEER_ATH = 5, + PEER_CISCO = 6, + PEER_MARV = 7, + PEER_AIRGO = 9, + PEER_MAX = 10, +}; + +#define RTL_DUMMY_OFFSET 0 +#define RTL_DUMMY_UNIT 8 +#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) +#define RTL_TX_DESC_SIZE 32 +#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE) + +#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ +#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ + +#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9 867 /* Mbps */ +#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS7 650 /* Mbps */ +#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS9 780 /* Mbps */ +#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS7 585 /* Mbps */ + +#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9 434 /* Mbps */ +#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS7 325 /* Mbps */ +#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */ +#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */ + +#define FRAME_OFFSET_FRAME_CONTROL 0 +#define FRAME_OFFSET_DURATION 2 +#define FRAME_OFFSET_ADDRESS1 4 +#define FRAME_OFFSET_ADDRESS2 10 +#define FRAME_OFFSET_ADDRESS3 16 +#define FRAME_OFFSET_SEQUENCE 22 +#define FRAME_OFFSET_ADDRESS4 24 +#define MAX_LISTEN_INTERVAL 10 +#define MAX_RATE_TRIES 4 + +#define SET_80211_PS_POLL_AID(_hdr, _val) \ + (*(u16 *)((u8 *)(_hdr) + 2) = _val) +#define SET_80211_PS_POLL_BSSID(_hdr, _val) \ + ether_addr_copy(((u8 *)(_hdr)) + 4, (u8 *)(_val)) +#define SET_80211_PS_POLL_TA(_hdr, _val) \ + ether_addr_copy(((u8 *)(_hdr))+10, (u8 *)(_val)) + +#define SET_80211_HDR_ADDRESS1(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val)) +#define SET_80211_HDR_ADDRESS2(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) +#define SET_80211_HDR_ADDRESS3(_hdr, _val) \ + CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) + +#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \ + le32p_replace_bits((__le32 *)(__pdesc + 8), __val, BIT(19)) +#define SET_TX_DESC_SW_DEFINE(__pdesc, __val) \ + le32p_replace_bits((__le32 *)(__pdesc + 24), __val, GENMASK(11, 0)) + +int rtl_init_core(struct ieee80211_hw *hw); +void rtl_deinit_core(struct ieee80211_hw *hw); +void rtl_init_rx_config(struct ieee80211_hw *hw); +void rtl_init_rfkill(struct ieee80211_hw *hw); +void rtl_deinit_rfkill(struct ieee80211_hw *hw); + +void rtl_watch_dog_timer_callback(struct timer_list *t); +void rtl_deinit_deferred_work(struct ieee80211_hw *hw, bool ips_wq); + +bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); +int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, + bool isvht, u8 desc_rate); +bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); +u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, + bool is_enc); + +void rtl_tx_ackqueue(struct ieee80211_hw *hw, struct sk_buff *skb); +bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb); +void rtl_set_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc, + struct ieee80211_hw *hw, struct rtlwifi_tx_info *info); +void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, + u8 c2h_cmd_len); +bool rtl_check_tx_report_acked(struct ieee80211_hw *hw); +void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms); +u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum wireless_mode wirelessmode, + struct ieee80211_tx_queue_params *param); + +void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); +void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb); +void rtl_scan_list_expire(struct ieee80211_hw *hw); +int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); +int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid); +int rtl_tx_agg_oper(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid); +int rtl_rx_agg_start(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid); +int rtl_rx_agg_stop(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u16 tid); +void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv); +void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec); +void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb); + +u8 rtl_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index, + enum wireless_mode wirelessmode); +void rtl_get_tcb_desc(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); + +int rtl_send_smps_action(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + enum ieee80211_smps_mode smps); +u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); +void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); +u8 rtl_tid_to_ac(u8 tid); +void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile b/drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile new file mode 100644 index 000000000..d15c58737 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +btcoexist-objs := halbtc8192e2ant.o \ + halbtc8723b1ant.o \ + halbtc8723b2ant.o \ + halbtc8821a1ant.o \ + halbtc8821a2ant.o \ + halbtcoutsrc.o \ + rtl_btc.o + +obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h new file mode 100644 index 000000000..30a254807 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2007-2011 Realtek Corporation.*/ + +#ifndef __HALBT_PRECOMP_H__ +#define __HALBT_PRECOMP_H__ +/************************************************************* + * include files + *************************************************************/ +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" + +#include "halbtcoutsrc.h" + +/* Interface type */ +#define RT_PCI_INTERFACE 1 +#define RT_USB_INTERFACE 2 +#define RT_SDIO_INTERFACE 3 +#define DEV_BUS_TYPE RT_PCI_INTERFACE + +#include "halbtc8192e2ant.h" +#include "halbtc8723b1ant.h" +#include "halbtc8723b2ant.h" +#include "halbtc8821a2ant.h" +#include "halbtc8821a1ant.h" + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#endif /* __HALBT_PRECOMP_H__ */ diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c new file mode 100644 index 000000000..edcd3c879 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c @@ -0,0 +1,3196 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2012 Realtek Corporation.*/ + +/************************************************************** + * include files + **************************************************************/ +#include "halbt_precomp.h" +/************************************************************** + * Global variables, these are static variables + **************************************************************/ +static struct coex_dm_8192e_2ant glcoex_dm_8192e_2ant; +static struct coex_dm_8192e_2ant *coex_dm = &glcoex_dm_8192e_2ant; +static struct coex_sta_8192e_2ant glcoex_sta_8192e_2ant; +static struct coex_sta_8192e_2ant *coex_sta = &glcoex_sta_8192e_2ant; + +static const char *const glbt_info_src_8192e_2ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8192e_2ant = 20130902; +static u32 glcoex_ver_8192e_2ant = 0x34; + +/************************************************************** + * local function proto type if needed + **************************************************************/ +/************************************************************** + * local function start with btc8192e2ant_ + **************************************************************/ +static u8 btc8192e2ant_bt_rssi_state(struct btc_coexist *btcoexist, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + int bt_rssi = 0; + u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + + bt_rssi = coex_sta->bt_rssi; + + if (level_num == 2) { + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= + (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_HIGH; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else { + if (bt_rssi < rssi_thresh) + bt_rssi_state = BTC_RSSI_STATE_LOW; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi thresh error!!\n"); + return coex_sta->pre_bt_rssi_state; + } + + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= + (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else if ((coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (bt_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_HIGH; + else if (bt_rssi < rssi_thresh) + bt_rssi_state = BTC_RSSI_STATE_LOW; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + } else { + if (bt_rssi < rssi_thresh1) + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } + + coex_sta->pre_bt_rssi_state = bt_rssi_state; + + return bt_rssi_state; +} + +static u8 btc8192e2ant_wifi_rssi_state(struct btc_coexist *btcoexist, + u8 index, u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + int wifi_rssi = 0; + u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + + if (level_num == 2) { + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= + (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else { + if (wifi_rssi < rssi_thresh) + wifi_rssi_state = BTC_RSSI_STATE_LOW; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI thresh error!!\n"); + return coex_sta->pre_wifi_rssi_state[index]; + } + + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= + (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (wifi_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + else if (wifi_rssi < rssi_thresh) + wifi_rssi_state = BTC_RSSI_STATE_LOW; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + } else { + if (wifi_rssi < rssi_thresh1) + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } + + coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + + return wifi_rssi_state; +} + +static void btc8192e2ant_monitor_bt_enable_disable(struct btc_coexist + *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static bool pre_bt_disabled; + static u32 bt_disable_cnt; + bool bt_active = true, bt_disabled = false; + + /* This function check if bt is disabled */ + + if (coex_sta->high_priority_tx == 0 && + coex_sta->high_priority_rx == 0 && + coex_sta->low_priority_tx == 0 && + coex_sta->low_priority_rx == 0) + bt_active = false; + + if (coex_sta->high_priority_tx == 0xffff && + coex_sta->high_priority_rx == 0xffff && + coex_sta->low_priority_tx == 0xffff && + coex_sta->low_priority_rx == 0xffff) + bt_active = false; + + if (bt_active) { + bt_disable_cnt = 0; + bt_disabled = false; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, + &bt_disabled); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is enabled !!\n"); + } else { + bt_disable_cnt++; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bt all counters = 0, %d times!!\n", + bt_disable_cnt); + if (bt_disable_cnt >= 2) { + bt_disabled = true; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, + &bt_disabled); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is disabled !!\n"); + } + } + if (pre_bt_disabled != bt_disabled) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is from %s to %s!!\n", + (pre_bt_disabled ? "disabled" : "enabled"), + (bt_disabled ? "disabled" : "enabled")); + pre_bt_disabled = bt_disabled; + } +} + +static u32 btc8192e2ant_decide_ra_mask(struct btc_coexist *btcoexist, + u8 ss_type, u32 ra_mask_type) +{ + u32 dis_ra_mask = 0x0; + + switch (ra_mask_type) { + case 0: /* normal mode */ + if (ss_type == 2) + dis_ra_mask = 0x0; /* enable 2ss */ + else + dis_ra_mask = 0xfff00000; /* disable 2ss */ + break; + case 1: /* disable cck 1/2 */ + if (ss_type == 2) + dis_ra_mask = 0x00000003; /* enable 2ss */ + else + dis_ra_mask = 0xfff00003; /* disable 2ss */ + break; + case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */ + if (ss_type == 2) + dis_ra_mask = 0x0001f1f7; /* enable 2ss */ + else + dis_ra_mask = 0xfff1f1f7; /* disable 2ss */ + break; + default: + break; + } + + return dis_ra_mask; +} + +static void btc8192e2ant_update_ra_mask(struct btc_coexist *btcoexist, + bool force_exec, u32 dis_rate_mask) +{ + coex_dm->cur_ra_mask = dis_rate_mask; + + if (force_exec || (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) + btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK, + &coex_dm->cur_ra_mask); + coex_dm->pre_ra_mask = coex_dm->cur_ra_mask; +} + +static void btc8192e2ant_auto_rate_fallback_retry(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + bool wifi_under_b_mode = false; + + coex_dm->cur_arfr_type = type; + + if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { + switch (coex_dm->cur_arfr_type) { + case 0: /* normal mode */ + btcoexist->btc_write_4byte(btcoexist, 0x430, + coex_dm->backup_arfr_cnt1); + btcoexist->btc_write_4byte(btcoexist, 0x434, + coex_dm->backup_arfr_cnt2); + break; + case 1: + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + if (wifi_under_b_mode) { + btcoexist->btc_write_4byte(btcoexist, 0x430, + 0x0); + btcoexist->btc_write_4byte(btcoexist, 0x434, + 0x01010101); + } else { + btcoexist->btc_write_4byte(btcoexist, 0x430, + 0x0); + btcoexist->btc_write_4byte(btcoexist, 0x434, + 0x04030201); + } + break; + default: + break; + } + } + + coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; +} + +static void btc8192e2ant_retry_limit(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_retry_limit_type = type; + + if (force_exec || (coex_dm->pre_retry_limit_type != + coex_dm->cur_retry_limit_type)) { + switch (coex_dm->cur_retry_limit_type) { + case 0: /* normal mode */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, + coex_dm->backup_retry_limit); + break; + case 1: /* retry limit = 8 */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; +} + +static void btc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_ampdu_time_type = type; + + if (force_exec || (coex_dm->pre_ampdu_time_type != + coex_dm->cur_ampdu_time_type)) { + switch (coex_dm->cur_ampdu_time_type) { + case 0: /* normal mode */ + btcoexist->btc_write_1byte(btcoexist, 0x456, + coex_dm->backup_ampdu_maxtime); + break; + case 1: /* AMPDU time = 0x38 * 32us */ + btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); + break; + default: + break; + } + } + + coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; +} + +static void btc8192e2ant_limited_tx(struct btc_coexist *btcoexist, + bool force_exec, u8 ra_mask_type, + u8 arfr_type, u8 retry_limit_type, + u8 ampdu_time_type) +{ + u32 dis_ra_mask = 0x0; + + coex_dm->cur_ra_mask_type = ra_mask_type; + dis_ra_mask = + btc8192e2ant_decide_ra_mask(btcoexist, coex_dm->cur_ss_type, + ra_mask_type); + btc8192e2ant_update_ra_mask(btcoexist, force_exec, dis_ra_mask); + btc8192e2ant_auto_rate_fallback_retry(btcoexist, force_exec, arfr_type); + btc8192e2ant_retry_limit(btcoexist, force_exec, retry_limit_type); + btc8192e2ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type); +} + +static void btc8192e2ant_limited_rx(struct btc_coexist *btcoexist, + bool force_exec, bool rej_ap_agg_pkt, + bool bt_ctrl_agg_buf_size, + u8 agg_buf_size) +{ + bool reject_rx_agg = rej_ap_agg_pkt; + bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rx_agg_size = agg_buf_size; + + /********************************************* + * Rx Aggregation related setting + *********************************************/ + btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, + &reject_rx_agg); + /* decide BT control aggregation buf size or not */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, + &bt_ctrl_rx_agg_size); + /* aggregation buf size, only work + * when BT control Rx aggregation size. + */ + btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); + /* real update aggregation setting */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +static void btc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u32 reg_hp_txrx, reg_lp_txrx, u32tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; + + reg_hp_txrx = 0x770; + reg_lp_txrx = 0x774; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); + reg_hp_tx = u32tmp & MASKLWORD; + reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); + reg_lp_tx = u32tmp & MASKLWORD; + reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", + reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", + reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + + /* reset counter */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static void btc8192e2ant_query_bt_info(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + h2c_parameter[0] |= BIT0; /* trigger */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + +static +bool btc8192e2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ + static bool pre_wifi_busy = false, pre_under_4way = false, + pre_bt_hs_on = false; + bool wifi_busy = false, under_4way = false, bt_hs_on = false; + bool wifi_connected = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (wifi_connected) { + if (wifi_busy != pre_wifi_busy) { + pre_wifi_busy = wifi_busy; + return true; + } + if (under_4way != pre_under_4way) { + pre_under_4way = under_4way; + return true; + } + if (bt_hs_on != pre_bt_hs_on) { + pre_bt_hs_on = bt_hs_on; + return true; + } + } + + return false; +} + +static void btc8192e2ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + + /* work around for HS mode. */ + if (bt_hs_on) { + bt_link_info->pan_exist = true; + bt_link_info->bt_link_exist = true; + } + + /* check if Sco only */ + if (bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->sco_only = true; + else + bt_link_info->sco_only = false; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && + bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->a2dp_only = true; + else + bt_link_info->a2dp_only = false; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->pan_only = true; + else + bt_link_info->pan_only = false; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + bt_link_info->hid_exist) + bt_link_info->hid_only = true; + else + bt_link_info->hid_only = false; +} + +static u8 btc8192e2ant_action_algorithm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + bool bt_hs_on = false; + u8 algorithm = BT_8192E_2ANT_COEX_ALGO_UNDEFINED; + u8 num_of_diff_profile = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + if (!bt_link_info->bt_link_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "No BT link exists!!!\n"); + return algorithm; + } + + if (bt_link_info->sco_exist) + num_of_diff_profile++; + if (bt_link_info->hid_exist) + num_of_diff_profile++; + if (bt_link_info->pan_exist) + num_of_diff_profile++; + if (bt_link_info->a2dp_exist) + num_of_diff_profile++; + + if (num_of_diff_profile == 1) { + if (bt_link_info->sco_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "SCO only\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } else { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "HID only\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "A2DP only\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "PAN(HS) only\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "PAN(EDR) only\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANEDR; + } + } + } + } else if (num_of_diff_profile == 2) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "SCO + HID\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "SCO + A2DP ==> SCO\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + PAN(HS)\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_SCO_PAN; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + if (stack_info->num_of_hid >= 2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID*2 + A2DP\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID + A2DP\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_HID_A2DP; + } + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID + PAN(HS)\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "A2DP + PAN(HS)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "A2DP + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } else if (num_of_diff_profile == 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "SCO + HID + A2DP ==> HID\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + HID + PAN(HS)\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + HID + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_SCO_PAN; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + A2DP + PAN(HS)\n"); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO + A2DP + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID + A2DP + PAN(HS)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "HID + A2DP + PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } else if (num_of_diff_profile >= 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "ErrorSCO+HID+A2DP+PAN(HS)\n"); + + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "SCO+HID+A2DP+PAN(EDR)\n"); + algorithm = + BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +static void btc8192e2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist, + u8 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + /* There are several type of dacswing + * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + */ + h2c_parameter[0] = dac_swing_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); +} + +static void btc8192e2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, + u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = dec_bt_pwr_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] decrease Bt Power level = %d, FW write 0x62 = 0x%x\n", + dec_bt_pwr_lvl, h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); +} + +static void btc8192e2ant_dec_bt_pwr(struct btc_coexist *btcoexist, + bool force_exec, u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s Dec BT power level = %d\n", + force_exec ? "force to" : "", dec_bt_pwr_lvl); + coex_dm->cur_dec_bt_pwr = dec_bt_pwr_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], preBtDecPwrLvl=%d, curBtDecPwrLvl=%d\n", + coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr); + } + btc8192e2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr); + + coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr; +} + +static void btc8192e2ant_set_bt_auto_report(struct btc_coexist *btcoexist, + bool enable_auto_report) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = 0; + + if (enable_auto_report) + h2c_parameter[0] |= BIT0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n", + (enable_auto_report ? "Enabled!!" : "Disabled!!"), + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); +} + +static void btc8192e2ant_bt_auto_report(struct btc_coexist *btcoexist, + bool force_exec, + bool enable_auto_report) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s BT Auto report = %s\n", + (force_exec ? "force to" : ""), + ((enable_auto_report) ? "Enabled" : "Disabled")); + coex_dm->cur_bt_auto_report = enable_auto_report; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] bPreBtAutoReport=%d, bCurBtAutoReport=%d\n", + coex_dm->pre_bt_auto_report, + coex_dm->cur_bt_auto_report); + + if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) + return; + } + btc8192e2ant_set_bt_auto_report(btcoexist, + coex_dm->cur_bt_auto_report); + + coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; +} + +static void btc8192e2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, + bool force_exec, u8 fw_dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s set FW Dac Swing level = %d\n", + (force_exec ? "force to" : ""), fw_dac_swing_lvl); + coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n", + coex_dm->pre_fw_dac_swing_lvl, + coex_dm->cur_fw_dac_swing_lvl); + + if (coex_dm->pre_fw_dac_swing_lvl == + coex_dm->cur_fw_dac_swing_lvl) + return; + } + + btc8192e2ant_set_fw_dac_swing_level(btcoexist, + coex_dm->cur_fw_dac_swing_lvl); + + coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; +} + +static void btc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist, + bool rx_rf_shrink_on) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (rx_rf_shrink_on) { + /* Shrink RF Rx LPF corner */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Shrink RF Rx LPF corner!!\n"); + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, + 0xfffff, 0xffffc); + } else { + /* Resume RF Rx LPF corner + * After initialized, we can use coex_dm->btRf0x1eBackup + */ + if (btcoexist->initialized) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Resume RF Rx LPF corner!!\n"); + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, + 0xfffff, + coex_dm->bt_rf0x1e_backup); + } + } +} + +static void btc8192e2ant_rf_shrink(struct btc_coexist *btcoexist, + bool force_exec, bool rx_rf_shrink_on) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Rx RF Shrink = %s\n", + (force_exec ? "force to" : ""), + ((rx_rf_shrink_on) ? "ON" : "OFF")); + coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex]bPreRfRxLpfShrink=%d,bCurRfRxLpfShrink=%d\n", + coex_dm->pre_rf_rx_lpf_shrink, + coex_dm->cur_rf_rx_lpf_shrink); + + if (coex_dm->pre_rf_rx_lpf_shrink == + coex_dm->cur_rf_rx_lpf_shrink) + return; + } + btc8192e2ant_set_sw_rf_rx_lpf_corner(btcoexist, + coex_dm->cur_rf_rx_lpf_shrink); + + coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink; +} + +static void btc8192e2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, + u32 level) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 val = (u8)level; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Write SwDacSwing = 0x%x\n", level); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val); +} + +static void btc8192e2ant_set_sw_full_swing(struct btc_coexist *btcoexist, + bool sw_dac_swing_on, + u32 sw_dac_swing_lvl) +{ + if (sw_dac_swing_on) + btc8192e2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl); + else + btc8192e2ant_set_dac_swing_reg(btcoexist, 0x18); +} + +static void btc8192e2ant_dac_swing(struct btc_coexist *btcoexist, + bool force_exec, bool dac_swing_on, + u32 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn DacSwing=%s, dac_swing_lvl = 0x%x\n", + (force_exec ? "force to" : ""), + ((dac_swing_on) ? "ON" : "OFF"), dac_swing_lvl); + coex_dm->cur_dac_swing_on = dac_swing_on; + coex_dm->cur_dac_swing_lvl = dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl = 0x%x, ", + coex_dm->pre_dac_swing_on, + coex_dm->pre_dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "bCurDacSwingOn=%d, curDacSwingLvl = 0x%x\n", + coex_dm->cur_dac_swing_on, + coex_dm->cur_dac_swing_lvl); + + if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && + (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl)) + return; + } + mdelay(30); + btc8192e2ant_set_sw_full_swing(btcoexist, dac_swing_on, dac_swing_lvl); + + coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; + coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; +} + +static void btc8192e2ant_set_agc_table(struct btc_coexist *btcoexist, + bool agc_table_en) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + /* BB AGC Gain Table */ + if (agc_table_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BB Agc Table On!\n"); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x0a1A0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x091B0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x081C0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x071D0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x061E0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x051F0001); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BB Agc Table Off!\n"); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001); + btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001); + } +} + +static void btc8192e2ant_agc_table(struct btc_coexist *btcoexist, + bool force_exec, bool agc_table_en) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s %s Agc Table\n", + (force_exec ? "force to" : ""), + ((agc_table_en) ? "Enable" : "Disable")); + coex_dm->cur_agc_table_en = agc_table_en; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n", + coex_dm->pre_agc_table_en, + coex_dm->cur_agc_table_en); + + if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en) + return; + } + btc8192e2ant_set_agc_table(btcoexist, agc_table_en); + + coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en; +} + +static void btc8192e2ant_set_coex_table(struct btc_coexist *btcoexist, + u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); + btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); + btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); + btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); + btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8192e2ant_coex_table(struct btc_coexist *btcoexist, + bool force_exec, u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, ", + (force_exec ? "force to" : ""), val0x6c0); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", + val0x6c4, val0x6c8, val0x6cc); + coex_dm->cur_val0x6c0 = val0x6c0; + coex_dm->cur_val0x6c4 = val0x6c4; + coex_dm->cur_val0x6c8 = val0x6c8; + coex_dm->cur_val0x6cc = val0x6cc; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c4 = 0x%x, ", + coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", + coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c4 = 0x%x\n", + coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", + coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc); + + if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && + (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && + (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && + (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) + return; + } + btc8192e2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8, + val0x6cc); + + coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; + coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; + coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; + coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void btc8192e2ant_coex_table_with_type(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + switch (type) { + case 0: + btc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 1: + btc8192e2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + btc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5ffb5ffb, 0xffffff, 0x3); + break; + case 3: + btc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff, + 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 4: + btc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff, + 0x5ffb5ffb, 0xffffff, 0x3); + break; + default: + break; + } +} + +static void btc8192e2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, + bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + if (enable) + h2c_parameter[0] |= BIT0; /* function enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex]set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void btc8192e2ant_ignore_wlan_act(struct btc_coexist *btcoexist, + bool force_exec, bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Ignore WlanAct %s\n", + (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); + coex_dm->cur_ignore_wlan_act = enable; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreIgnoreWlanAct = %d ", + coex_dm->pre_ignore_wlan_act); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "bCurIgnoreWlanAct = %d!!\n", + coex_dm->cur_ignore_wlan_act); + + if (coex_dm->pre_ignore_wlan_act == + coex_dm->cur_ignore_wlan_act) + return; + } + btc8192e2ant_set_fw_ignore_wlan_act(btcoexist, enable); + + coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8192e2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1, + u8 byte2, u8 byte3, u8 byte4, u8 byte5) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + u8 h2c_parameter[5] = {0}; + + h2c_parameter[0] = byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = byte5; + + coex_dm->ps_tdma_para[0] = byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = byte5; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n", + h2c_parameter[0], + h2c_parameter[1] << 24 | h2c_parameter[2] << 16 | + h2c_parameter[3] << 8 | h2c_parameter[4]); + + btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8192e2ant_sw_mechanism1(struct btc_coexist *btcoexist, + bool shrink_rx_lpf, bool low_penalty_ra, + bool limited_dig, bool btlan_constrain) +{ + btc8192e2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf); +} + +static void btc8192e2ant_sw_mechanism2(struct btc_coexist *btcoexist, + bool agc_table_shift, bool adc_backoff, + bool sw_dac_swing, u32 dac_swing_lvl) +{ + btc8192e2ant_agc_table(btcoexist, NORMAL_EXEC, agc_table_shift); + btc8192e2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing, + dac_swing_lvl); +} + +static void btc8192e2ant_ps_tdma(struct btc_coexist *btcoexist, + bool force_exec, bool turn_on, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn %s PS TDMA, type=%d\n", + (force_exec ? "force to" : ""), + (turn_on ? "ON" : "OFF"), type); + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", + coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", + coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); + + if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && + (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) + return; + } + if (turn_on) { + switch (type) { + case 1: + default: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, + 0x1a, 0xe1, 0x90); + break; + case 2: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, + 0x12, 0xe1, 0x90); + break; + case 3: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, 0x90); + break; + case 4: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0xf1, 0x90); + break; + case 5: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, + 0x1a, 0x60, 0x90); + break; + case 6: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, + 0x12, 0x60, 0x90); + break; + case 7: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0x70, 0x90); + break; + case 8: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10, + 0x3, 0x70, 0x90); + break; + case 9: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, + 0x1a, 0xe1, 0x10); + break; + case 10: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, + 0x12, 0xe1, 0x10); + break; + case 11: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, 0x10); + break; + case 12: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0xf1, 0x10); + break; + case 13: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, + 0x1a, 0xe0, 0x10); + break; + case 14: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, + 0x12, 0xe0, 0x10); + break; + case 15: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf0, 0x10); + break; + case 16: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, + 0x3, 0xf0, 0x10); + break; + case 17: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20, + 0x03, 0x10, 0x10); + break; + case 18: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, + 0x5, 0xe1, 0x90); + break; + case 19: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0xe1, 0x90); + break; + case 20: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0x60, 0x90); + break; + case 21: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x03, 0x70, 0x90); + break; + case 71: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, + 0x1a, 0xe1, 0x90); + break; + } + } else { + /* disable PS tdma */ + switch (type) { + default: + case 0: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, 0x0, + 0x0, 0x0); + btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4); + break; + case 1: + btc8192e2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x8, 0x0); + mdelay(5); + btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20); + break; + } + } + + /* update pre state */ + coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; + coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static void btc8192e2ant_set_switch_ss_type(struct btc_coexist *btcoexist, + u8 ss_type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 mimops = BTC_MIMO_PS_DYNAMIC; + u32 dis_ra_mask = 0x0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], REAL set SS Type = %d\n", ss_type); + + dis_ra_mask = btc8192e2ant_decide_ra_mask(btcoexist, ss_type, + coex_dm->cur_ra_mask_type); + btc8192e2ant_update_ra_mask(btcoexist, FORCE_EXEC, dis_ra_mask); + + if (ss_type == 1) { + btc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); + /* switch ofdm path */ + btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x11); + btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x1); + btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81111111); + /* switch cck patch */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x1); + btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x81); + mimops = BTC_MIMO_PS_STATIC; + } else if (ss_type == 2) { + btc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); + btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x33); + btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x3); + btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81121313); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x0); + btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x41); + mimops = BTC_MIMO_PS_DYNAMIC; + } + /* set rx 1ss or 2ss */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops); +} + +static void btc8192e2ant_switch_ss_type(struct btc_coexist *btcoexist, + bool force_exec, u8 new_ss_type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s Switch SS Type = %d\n", + (force_exec ? "force to" : ""), new_ss_type); + coex_dm->cur_ss_type = new_ss_type; + + if (!force_exec) { + if (coex_dm->pre_ss_type == coex_dm->cur_ss_type) + return; + } + btc8192e2ant_set_switch_ss_type(btcoexist, coex_dm->cur_ss_type); + + coex_dm->pre_ss_type = coex_dm->cur_ss_type; +} + +static void btc8192e2ant_coex_all_off(struct btc_coexist *btcoexist) +{ + /* fw all off */ + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + + /* hw all off */ + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + /* force to reset coex mechanism */ + + btc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, 0); + + btc8192e2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + btc8192e2ant_switch_ss_type(btcoexist, FORCE_EXEC, 2); + + btc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static void btc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ + bool low_pwr_disable = true; + + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static bool btc8192e2ant_is_common_action(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool common = false, wifi_connected = false, wifi_busy = false; + bool bt_hs_on = false, low_pwr_disable = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (bt_link_info->sco_exist || bt_link_info->hid_exist) + btc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 0, 0, 0); + else + btc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + + if (!wifi_connected) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non-connected idle!!\n"); + + if ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) || + (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status)) { + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + } else { + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8192e2ant_sw_mechanism1(btcoexist, false, false, false, + false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, false, + 0x18); + + common = true; + } else { + if (BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Wifi connected + BT non connected-idle!!\n"); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, + NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + + common = true; + } else if (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status) { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (bt_hs_on) + return false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Wifi connected + BT connected-idle!!\n"); + + btc8192e2ant_switch_ss_type(btcoexist, + NORMAL_EXEC, 2); + btc8192e2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, + false, 0); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, + NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + + common = true; + } else { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (wifi_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Wifi Connected-Busy + BT Busy!!\n"); + common = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Wifi Connected-Idle + BT Busy!!\n"); + + btc8192e2ant_switch_ss_type(btcoexist, + NORMAL_EXEC, 1); + btc8192e2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, + 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 21); + btc8192e2ant_fw_dac_swing_lvl(btcoexist, + NORMAL_EXEC, 6); + btc8192e2ant_dec_bt_pwr(btcoexist, + NORMAL_EXEC, 0); + btc8192e2ant_sw_mechanism1(btcoexist, false, + false, false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, + false, false, 0x18); + common = true; + } + } + } + return common; +} + +static void btc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, + bool sco_hid, bool tx_pause, + u8 max_interval) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static int up, dn, m, n, wait_cnt; + u8 retry_cnt = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], TdmaDurationAdjust()\n"); + + if (!coex_dm->auto_tdma_adjust) { + coex_dm->auto_tdma_adjust = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], first run TdmaDurationAdjust()!!\n"); + if (sco_hid) { + if (tx_pause) { + if (max_interval == 1) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 13); + coex_dm->tdma_adj_type = 13; + } else if (max_interval == 2) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 14); + coex_dm->tdma_adj_type = 14; + } else { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->tdma_adj_type = 15; + } + } else { + if (max_interval == 1) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 9); + coex_dm->tdma_adj_type = 9; + } else if (max_interval == 2) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 10); + coex_dm->tdma_adj_type = 10; + } else { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->tdma_adj_type = 11; + } + } + } else { + if (tx_pause) { + if (max_interval == 1) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 5); + coex_dm->tdma_adj_type = 5; + } else if (max_interval == 2) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 6); + coex_dm->tdma_adj_type = 6; + } else { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->tdma_adj_type = 7; + } + } else { + if (max_interval == 1) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 1); + coex_dm->tdma_adj_type = 1; + } else if (max_interval == 2) { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 2); + coex_dm->tdma_adj_type = 2; + } else { + btc8192e2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->tdma_adj_type = 3; + } + } + } + + up = 0; + dn = 0; + m = 1; + n = 3; + wait_cnt = 0; + } else { + /* accquire the BT TRx retry count from BT_Info byte2 */ + retry_cnt = coex_sta->bt_retry_cnt; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], retry_cnt = %d\n", retry_cnt); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_cnt=%d\n", + up, dn, m, n, wait_cnt); + wait_cnt++; + /* no retry in the last 2-second duration */ + if (retry_cnt == 0) { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if (up >= n) { + wait_cnt = 0; + n = 3; + up = 0; + dn = 0; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex]Increase wifi duration!!\n"); + } + } else if (retry_cnt <= 3) { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) { + if (wait_cnt <= 2) + m++; + else + m = 1; + + if (m >= 20) + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_cnt = 0; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Reduce wifi duration for retry<3\n"); + } + } else { + if (wait_cnt == 1) + m++; + else + m = 1; + + if (m >= 20) + m = 20; + + n = 3*m; + up = 0; + dn = 0; + wait_cnt = 0; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Decrease wifi duration for retryCounter>3!!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], max Interval = %d\n", max_interval); + } + + /* if current PsTdma not match with + * the recorded one (when scan, dhcp...), + * then we have to adjust it back to the previous record one. + */ + if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) { + bool scan = false, link = false, roam = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PsTdma type mismatch!!!, "); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "curPsTdma=%d, recordPsTdma=%d\n", + coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (!scan && !link && !roam) + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, coex_dm->tdma_adj_type); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"); + } +} + +/* SCO only or SCO+PAN(HS) */ +static void btc8192e2ant_action_sco(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x6); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x6); + } + } +} + +static void btc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x6); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x6); + } + } +} + +static void btc8192e2ant_action_hid(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ +static void btc8192e2ant_action_a2dp(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + bool long_dist = false; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW || + bt_rssi_state == BTC_RSSI_STATE_STAY_LOW) && + (wifi_rssi_state == BTC_RSSI_STATE_LOW || + wifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], A2dp, wifi/bt rssi both LOW!!\n"); + long_dist = true; + } + if (long_dist) { + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true, + 0x4); + } else { + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, + 0x8); + } + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (long_dist) + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + else + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + if (long_dist) { + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 17); + coex_dm->auto_tdma_adjust = false; + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else { + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, + true, 1); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, + false, 1); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, + false, 1); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + } + } + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 2); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, false, 2); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_tdma_duration_adjust(btcoexist, false, false, 2); + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + } + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + true, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + true, 0x6); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + true, 0x6); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + true, 0x6); + } + } +} + +static void btc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); + } + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* PAN(HS) only */ +static void btc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + } + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* PAN(EDR)+A2DP */ +static void btc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 3); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_tdma_duration_adjust(btcoexist, false, false, 3); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_tdma_duration_adjust(btcoexist, false, false, 3); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 10); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* HID+A2DP+PAN(EDR) */ +static void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8192e2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 3); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state = BTC_RSSI_STATE_HIGH; + u32 wifi_bw; + + wifi_rssi_state = btc8192e2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8192e2ant_bt_rssi_state(btcoexist, 3, 34, 42); + + btc8192e2ant_switch_ss_type(btcoexist, NORMAL_EXEC, 1); + btc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + btc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3); + + if ((bt_rssi_state == BTC_RSSI_STATE_LOW) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 2); + } else if ((bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2); + } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 4); + btc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8192e2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8192e2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 algorithm = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism()===>\n"); + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], return for Manual CTRL <===\n"); + return; + } + + if (coex_sta->under_ips) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + return; + } + + algorithm = btc8192e2ant_action_algorithm(btcoexist); + if (coex_sta->c2h_bt_inquiry_page && + (BT_8192E_2ANT_COEX_ALGO_PANHS != algorithm)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is under inquiry/page scan !!\n"); + btc8192e2ant_action_bt_inquiry(btcoexist); + return; + } + + coex_dm->cur_algorithm = algorithm; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm); + + if (btc8192e2ant_is_common_action(btcoexist)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant common\n"); + coex_dm->auto_tdma_adjust = false; + } else { + if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex] preAlgorithm=%d, curAlgorithm=%d\n", + coex_dm->pre_algorithm, + coex_dm->cur_algorithm); + coex_dm->auto_tdma_adjust = false; + } + switch (coex_dm->cur_algorithm) { + case BT_8192E_2ANT_COEX_ALGO_SCO: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = SCO\n"); + btc8192e2ant_action_sco(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_SCO_PAN: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = SCO+PAN(EDR)\n"); + btc8192e2ant_action_sco_pan(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = HID\n"); + btc8192e2ant_action_hid(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = A2DP\n"); + btc8192e2ant_action_a2dp(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = A2DP+PAN(HS)\n"); + btc8192e2ant_action_a2dp_pan_hs(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = PAN(EDR)\n"); + btc8192e2ant_action_pan_edr(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = HS mode\n"); + btc8192e2ant_action_pan_hs(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = PAN+A2DP\n"); + btc8192e2ant_action_pan_edr_a2dp(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = PAN(EDR)+HID\n"); + btc8192e2ant_action_pan_edr_hid(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = HID+A2DP+PAN\n"); + btc8192e2ant_action_hid_a2dp_pan_edr(btcoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = HID+A2DP\n"); + btc8192e2ant_action_hid_a2dp(btcoexist); + break; + default: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Action 2-Ant, algorithm = unknown!!\n"); + /* btc8192e2ant_coex_all_off(btcoexist); */ + break; + } + coex_dm->pre_algorithm = coex_dm->cur_algorithm; + } +} + +static void btc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist, + bool backup) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u16 u16tmp = 0; + u8 u8tmp = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 2Ant Init HW Config!!\n"); + + if (backup) { + /* backup rf 0x1e value */ + coex_dm->bt_rf0x1e_backup = + btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, + 0x1e, 0xfffff); + + coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist, + 0x430); + coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist, + 0x434); + coex_dm->backup_retry_limit = btcoexist->btc_read_2byte( + btcoexist, + 0x42a); + coex_dm->backup_ampdu_maxtime = btcoexist->btc_read_1byte( + btcoexist, + 0x456); + } + + /* antenna sw ctrl to bt */ + btcoexist->btc_write_1byte(btcoexist, 0x4f, 0x6); + btcoexist->btc_write_1byte(btcoexist, 0x944, 0x24); + btcoexist->btc_write_4byte(btcoexist, 0x930, 0x700700); + btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20); + if (btcoexist->chip_interface == BTC_INTF_USB) + btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30430004); + else + btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30030004); + + btc8192e2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + + /* antenna switch control parameter */ + btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555); + + /* coex parameters */ + btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); + /* 0x790[5:0] = 0x5 */ + u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); + u8tmp &= 0xc0; + u8tmp |= 0x5; + btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); + + /* enable counter statistics */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + /* enable PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x40, 0x20); + /* enable mailbox interface */ + u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x40); + u16tmp |= BIT9; + btcoexist->btc_write_2byte(btcoexist, 0x40, u16tmp); + + /* enable PTA I2C mailbox */ + u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x101); + u8tmp |= BIT4; + btcoexist->btc_write_1byte(btcoexist, 0x101, u8tmp); + + /* enable bt clock when wifi is disabled. */ + u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x93); + u8tmp |= BIT0; + btcoexist->btc_write_1byte(btcoexist, 0x93, u8tmp); + /* enable bt clock when suspend. */ + u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x7); + u8tmp |= BIT0; + btcoexist->btc_write_1byte(btcoexist, 0x7, u8tmp); +} + +/************************************************************ + * extern function start with ex_btc8192e2ant_ + ************************************************************/ + +void ex_btc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist) +{ + btc8192e2ant_init_hwconfig(btcoexist, true); +} + +void ex_btc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Coex Mechanism Init!!\n"); + btc8192e2ant_init_coex_dm(btcoexist); +} + +void ex_btc8192e2ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; + u16 u16tmp[4]; + u32 u32tmp[4]; + bool roam = false, scan = false, link = false, wifi_under_5g = false; + bool bt_hs_on = false, wifi_busy = false; + int wifi_rssi = 0, bt_hs_rssi = 0; + u32 wifi_bw, wifi_traffic_dir; + u8 wifi_dot11_chnl, wifi_hs_chnl; + u32 fw_ver = 0, bt_patch_ver = 0; + + seq_puts(m, "\n ============[BT Coexist info]============"); + + if (btcoexist->manual_control) { + seq_puts(m, "\n ===========[Under Manual Control]==========="); + seq_puts(m, "\n =========================================="); + } + + seq_printf(m, "\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", + board_info->pg_ant_num, board_info->btdm_ant_num); + + seq_printf(m, "\n %-35s = %s / %d", "BT stack/ hci ext ver", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + seq_printf(m, "\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", + "CoexVer/ FwVer/ PatchVer", + glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant, + fw_ver, bt_patch_ver, bt_patch_ver); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, + &wifi_dot11_chnl); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsMode(HsChnl)", + wifi_dot11_chnl, bt_hs_on, wifi_hs_chnl); + + seq_printf(m, "\n %-35s = %3ph ", + "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + seq_printf(m, "\n %-35s = %d/ %d", + "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "Wifi link/ roam/ scan", link, roam, scan); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + &wifi_traffic_dir); + seq_printf(m, "\n %-35s = %s / %s/ %s ", + "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), + ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : + (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), + ((!wifi_busy) ? "idle" : + ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? + "uplink" : "downlink"))); + + seq_printf(m, "\n %-35s = [%s/ %d/ %d] ", + "BT [status/ rssi/ retryCnt]", + ((btcoexist->bt_info.bt_disabled) ? ("disabled") : + ((coex_sta->c2h_bt_inquiry_page) ? + ("inquiry/page scan") : + ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) ? "non-connected idle" : + ((BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status) ? "connected-idle" : "busy")))), + coex_sta->bt_rssi, coex_sta->bt_retry_cnt); + + seq_printf(m, "\n %-35s = %d / %d / %d / %d", + "SCO/HID/PAN/A2DP", stack_info->sco_exist, + stack_info->hid_exist, stack_info->pan_exist, + stack_info->a2dp_exist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); + + bt_info_ext = coex_sta->bt_info_ext; + seq_printf(m, "\n %-35s = %s", + "BT Info A2DP rate", + (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); + + for (i = 0; i < BT_INFO_SRC_8192E_2ANT_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + seq_printf(m, "\n %-35s = %7ph(%d)", + glbt_info_src_8192e_2ant[i], + coex_sta->bt_info_c2h[i], + coex_sta->bt_info_c2h_cnt[i]); + } + } + + seq_printf(m, "\n %-35s = %s/%s", + "PS state, IPS/LPS", + ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), + ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); + + seq_printf(m, "\n %-35s = 0x%x ", "SS Type", + coex_dm->cur_ss_type); + + /* Sw mechanism */ + seq_printf(m, "\n %-35s", + "============[Sw mechanism]============"); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, + coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); + seq_printf(m, "\n %-35s = %d/ %d/ %d(0x%x) ", + "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", + coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, + coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); + + seq_printf(m, "\n %-35s = 0x%x ", "Rate Mask", + btcoexist->bt_info.ra_mask); + + /* Fw mechanism */ + seq_printf(m, "\n %-35s", + "============[Fw mechanism]============"); + + ps_tdma_case = coex_dm->cur_ps_tdma; + seq_printf(m, + "\n %-35s = %5ph case-%d (auto:%d)", + "PS TDMA", coex_dm->ps_tdma_para, + ps_tdma_case, coex_dm->auto_tdma_adjust); + + seq_printf(m, "\n %-35s = %d/ %d ", + "DecBtPwr/ IgnWlanAct", + coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act); + + /* Hw setting */ + seq_printf(m, "\n %-35s", + "============[Hw setting]============"); + + seq_printf(m, "\n %-35s = 0x%x", + "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); + + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, + coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit, + coex_dm->backup_ampdu_maxtime); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); + u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "0x430/0x434/0x42a/0x456", + u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc04); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xd04); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x90c); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0xc04/ 0xd04/ 0x90c", u32tmp[0], u32tmp[1], u32tmp[2]); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); + seq_printf(m, "\n %-35s = 0x%x", "0x778", u8tmp[0]); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c); + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x92c/ 0x930", (u8tmp[0]), u32tmp[0]); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x40/ 0x4f", u8tmp[0], u8tmp[1]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); + seq_printf(m, "\n %-35s = 0x%x", "0xc50(dig)", + u32tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); + seq_printf(m, + "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", + u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); + + seq_printf(m, "\n %-35s = %d/ %d", + "0x770(hp rx[31:16]/tx[15:0])", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + seq_printf(m, "\n %-35s = %d/ %d", + "0x774(lp rx[31:16]/tx[15:0])", + coex_sta->low_priority_rx, coex_sta->low_priority_tx); + if (btcoexist->auto_report_2ant) + btc8192e2ant_monitor_bt_ctr(btcoexist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); +} + +void ex_btc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_IPS_ENTER == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS ENTER notify\n"); + coex_sta->under_ips = true; + btc8192e2ant_coex_all_off(btcoexist); + } else if (BTC_IPS_LEAVE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS LEAVE notify\n"); + coex_sta->under_ips = false; + } +} + +void ex_btc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_LPS_ENABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS ENABLE notify\n"); + coex_sta->under_lps = true; + } else if (BTC_LPS_DISABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS DISABLE notify\n"); + coex_sta->under_lps = false; + } +} + +void ex_btc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_SCAN_START == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + else if (BTC_SCAN_FINISH == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); +} + +void ex_btc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_ASSOCIATE_START == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + else if (BTC_ASSOCIATE_FINISH == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); +} + +void ex_btc8192e2ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[3] = {0}; + u32 wifi_bw; + u8 wifi_center_chnl; + + if (btcoexist->manual_control || + btcoexist->stop_coex_dm || + btcoexist->bt_info.bt_disabled) + return; + + if (BTC_MEDIA_CONNECT == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA connect notify\n"); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA disconnect notify\n"); + + /* only 2.4G we need to inform bt the chnl mask */ + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, + &wifi_center_chnl); + if ((BTC_MEDIA_CONNECT == type) && + (wifi_center_chnl <= 14)) { + h2c_parameter[0] = 0x1; + h2c_parameter[1] = wifi_center_chnl; + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + } + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x66 = 0x%x\n", + h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | + h2c_parameter[2]); + + btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_btc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (type == BTC_PACKET_DHCP) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], DHCP Packet notify\n"); +} + +void ex_btc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmp_buf, u8 length) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 bt_info = 0; + u8 i, rsp_source = 0; + bool bt_busy = false, limited_dig = false; + bool wifi_connected = false; + + coex_sta->c2h_bt_info_req_sent = false; + + rsp_source = tmp_buf[0] & 0xf; + if (rsp_source >= BT_INFO_SRC_8192E_2ANT_MAX) + rsp_source = BT_INFO_SRC_8192E_2ANT_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Bt info[%d], length=%d, hex data = [", + rsp_source, length); + for (i = 0; i < length; i++) { + coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; + if (i == 1) + bt_info = tmp_buf[i]; + if (i == length-1) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x]\n", tmp_buf[i]); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x, ", tmp_buf[i]); + } + + if (BT_INFO_SRC_8192E_2ANT_WIFI_FW != rsp_source) { + /* [3:0] */ + coex_sta->bt_retry_cnt = + coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + + coex_sta->bt_rssi = + coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + + coex_sta->bt_info_ext = + coex_sta->bt_info_c2h[rsp_source][4]; + + /* Here we need to resend some wifi info to BT + * because bt is reset and loss of the info. + */ + if ((coex_sta->bt_info_ext & BIT1)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "bit1, send wifi BW&Chnl to BT!!\n"); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + if (wifi_connected) + ex_btc8192e2ant_media_status_notify( + btcoexist, + BTC_MEDIA_CONNECT); + else + ex_btc8192e2ant_media_status_notify( + btcoexist, + BTC_MEDIA_DISCONNECT); + } + + if ((coex_sta->bt_info_ext & BIT3)) { + if (!btcoexist->manual_control && + !btcoexist->stop_coex_dm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "bit3, BT NOT ignore Wlan active!\n"); + btc8192e2ant_ignore_wlan_act(btcoexist, + FORCE_EXEC, + false); + } + } else { + /* BT already NOT ignore Wlan active, + * do nothing here. + */ + } + + if (!btcoexist->auto_report_2ant) { + if (!(coex_sta->bt_info_ext & BIT4)) + btc8192e2ant_bt_auto_report(btcoexist, + FORCE_EXEC, + true); + } + } + + /* check BIT2 first ==> check if bt is under inquiry or page scan */ + if (bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE) + coex_sta->c2h_bt_inquiry_page = true; + else + coex_sta->c2h_bt_inquiry_page = false; + + /* set link exist status */ + if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) { + coex_sta->bt_link_exist = false; + coex_sta->pan_exist = false; + coex_sta->a2dp_exist = false; + coex_sta->hid_exist = false; + coex_sta->sco_exist = false; + } else {/* connection exists */ + coex_sta->bt_link_exist = true; + if (bt_info & BT_INFO_8192E_2ANT_B_FTP) + coex_sta->pan_exist = true; + else + coex_sta->pan_exist = false; + if (bt_info & BT_INFO_8192E_2ANT_B_A2DP) + coex_sta->a2dp_exist = true; + else + coex_sta->a2dp_exist = false; + if (bt_info & BT_INFO_8192E_2ANT_B_HID) + coex_sta->hid_exist = true; + else + coex_sta->hid_exist = false; + if (bt_info & BT_INFO_8192E_2ANT_B_SCO_ESCO) + coex_sta->sco_exist = true; + else + coex_sta->sco_exist = false; + } + + btc8192e2ant_update_bt_link_info(btcoexist); + + if (!(bt_info & BT_INFO_8192E_2ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Non-Connected idle!!!\n"); + } else if (bt_info == BT_INFO_8192E_2ANT_B_CONNECTION) { + coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bt_infoNotify(), BT Connected-idle!!!\n"); + } else if ((bt_info & BT_INFO_8192E_2ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8192E_2ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_SCO_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bt_infoNotify(), BT SCO busy!!!\n"); + } else if (bt_info & BT_INFO_8192E_2ANT_B_ACL_BUSY) { + coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_ACL_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bt_infoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_MAX; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex]bt_infoNotify(), BT Non-Defined state!!!\n"); + } + + if ((BT_8192E_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || + (BT_8192E_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || + (BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { + bt_busy = true; + limited_dig = true; + } else { + bt_busy = false; + limited_dig = false; + } + + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + coex_dm->limited_dig = limited_dig; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); + + btc8192e2ant_run_coexist_mechanism(btcoexist); +} + +void ex_btc8192e2ant_halt_notify(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n"); + + btc8192e2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + ex_btc8192e2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_btc8192e2ant_periodical(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static u8 dis_ver_info_cnt; + u32 fw_ver = 0, bt_patch_ver = 0; + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "=======================Periodical=======================\n"); + if (dis_ver_info_cnt <= 5) { + dis_ver_info_cnt += 1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "************************************************\n"); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + board_info->pg_ant_num, board_info->btdm_ant_num, + board_info->btdm_ant_pos); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "BT stack/ hci ext ver = %s / %d\n", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, + &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant, + fw_ver, bt_patch_ver, bt_patch_ver); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "************************************************\n"); + } + + if (!btcoexist->auto_report_2ant) { + btc8192e2ant_query_bt_info(btcoexist); + btc8192e2ant_monitor_bt_ctr(btcoexist); + btc8192e2ant_monitor_bt_enable_disable(btcoexist); + } else { + if (btc8192e2ant_is_wifi_status_changed(btcoexist) || + coex_dm->auto_tdma_adjust) + btc8192e2ant_run_coexist_mechanism(btcoexist); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h new file mode 100644 index 000000000..41ac0d5dc --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2012 Realtek Corporation.*/ + +/***************************************************************** + * The following is for 8192E 2Ant BT Co-exist definition + *****************************************************************/ +#define BT_INFO_8192E_2ANT_B_FTP BIT7 +#define BT_INFO_8192E_2ANT_B_A2DP BIT6 +#define BT_INFO_8192E_2ANT_B_HID BIT5 +#define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8192E_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2 + +enum bt_info_src_8192e_2ant { + BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8192E_2ANT_MAX +}; + +enum bt_8192e_2ant_bt_status { + BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8192E_2ANT_BT_STATUS_MAX +}; + +enum bt_8192e_2ant_coex_algo { + BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8192E_2ANT_COEX_ALGO_SCO = 0x1, + BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2, + BT_8192E_2ANT_COEX_ALGO_HID = 0x3, + BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4, + BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5, + BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6, + BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7, + BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8, + BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9, + BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa, + BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb, + BT_8192E_2ANT_COEX_ALGO_MAX = 0xc +}; + +struct coex_dm_8192e_2ant { + /* fw mechanism */ + u8 pre_dec_bt_pwr; + u8 cur_dec_bt_pwr; + u8 pre_fw_dac_swing_lvl; + u8 cur_fw_dac_swing_lvl; + bool cur_ignore_wlan_act; + bool pre_ignore_wlan_act; + u8 pre_ps_tdma; + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + u8 tdma_adj_type; + bool reset_tdma_adjust; + bool auto_tdma_adjust; + bool pre_ps_tdma_on; + bool cur_ps_tdma_on; + bool pre_bt_auto_report; + bool cur_bt_auto_report; + + /* sw mechanism */ + bool pre_rf_rx_lpf_shrink; + bool cur_rf_rx_lpf_shrink; + u32 bt_rf0x1e_backup; + bool pre_low_penalty_ra; + bool cur_low_penalty_ra; + bool pre_dac_swing_on; + u32 pre_dac_swing_lvl; + bool cur_dac_swing_on; + u32 cur_dac_swing_lvl; + bool pre_adc_back_off; + bool cur_adc_back_off; + bool pre_agc_table_en; + bool cur_agc_table_en; + u32 pre_val0x6c0; + u32 cur_val0x6c0; + u32 pre_val0x6c4; + u32 cur_val0x6c4; + u32 pre_val0x6c8; + u32 cur_val0x6c8; + u8 pre_val0x6cc; + u8 cur_val0x6cc; + bool limited_dig; + + u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */ + u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */ + u16 backup_retry_limit; + u8 backup_ampdu_maxtime; + + /* algorithm related */ + u8 pre_algorithm; + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + + u8 pre_ss_type; + u8 cur_ss_type; + + u32 pre_ra_mask; + u32 cur_ra_mask; + u8 cur_ra_mask_type; + u8 pre_arfr_type; + u8 cur_arfr_type; + u8 pre_retry_limit_type; + u8 cur_retry_limit_type; + u8 pre_ampdu_time_type; + u8 cur_ampdu_time_type; +}; + +struct coex_sta_8192e_2ant { + bool bt_link_exist; + bool sco_exist; + bool a2dp_exist; + bool hid_exist; + bool pan_exist; + + bool under_lps; + bool under_ips; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 bt_rssi; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + bool c2h_bt_info_req_sent; + u8 bt_info_c2h[BT_INFO_SRC_8192E_2ANT_MAX][10]; + u32 bt_info_c2h_cnt[BT_INFO_SRC_8192E_2ANT_MAX]; + bool c2h_bt_inquiry_page; + u8 bt_retry_cnt; + u8 bt_info_ext; +}; + +/**************************************************************** + * The following is interface which will notify coex module. + ****************************************************************/ +void ex_btc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist); +void ex_btc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_btc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8192e2ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmpbuf, u8 length); +void ex_btc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8192e2ant_halt_notify(struct btc_coexist *btcoexist); +void ex_btc8192e2ant_periodical(struct btc_coexist *btcoexist); +void ex_btc8192e2ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c new file mode 100644 index 000000000..379193b24 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -0,0 +1,3437 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2012 Realtek Corporation.*/ + +/*************************************************************** + * Description: + * + * This file is for RTL8723B Co-exist mechanism + * + * History + * 2012/11/15 Cosa first check in. + * + ***************************************************************/ + +/*************************************************************** + * include files + ***************************************************************/ +#include "halbt_precomp.h" +/*************************************************************** + * Global variables, these are static variables + ***************************************************************/ +static struct coex_dm_8723b_1ant glcoex_dm_8723b_1ant; +static struct coex_dm_8723b_1ant *coex_dm = &glcoex_dm_8723b_1ant; +static struct coex_sta_8723b_1ant glcoex_sta_8723b_1ant; +static struct coex_sta_8723b_1ant *coex_sta = &glcoex_sta_8723b_1ant; + +static const char *const glbt_info_src_8723b_1ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8723b_1ant = 20130918; +static u32 glcoex_ver_8723b_1ant = 0x47; + +/*************************************************************** + * local function proto type if needed + ***************************************************************/ +/*************************************************************** + * local function start with halbtc8723b1ant_ + ***************************************************************/ + +static void halbtc8723b1ant_updatera_mask(struct btc_coexist *btcoexist, + bool force_exec, u32 dis_rate_mask) +{ + coex_dm->curra_mask = dis_rate_mask; + + if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask)) + btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK, + &coex_dm->curra_mask); + + coex_dm->prera_mask = coex_dm->curra_mask; +} + +static void btc8723b1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + bool wifi_under_bmode = false; + + coex_dm->cur_arfr_type = type; + + if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { + switch (coex_dm->cur_arfr_type) { + case 0: /* normal mode */ + btcoexist->btc_write_4byte(btcoexist, 0x430, + coex_dm->backup_arfr_cnt1); + btcoexist->btc_write_4byte(btcoexist, 0x434, + coex_dm->backup_arfr_cnt2); + break; + case 1: + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_bmode); + if (wifi_under_bmode) { + btcoexist->btc_write_4byte(btcoexist, + 0x430, 0x0); + btcoexist->btc_write_4byte(btcoexist, + 0x434, 0x01010101); + } else { + btcoexist->btc_write_4byte(btcoexist, + 0x430, 0x0); + btcoexist->btc_write_4byte(btcoexist, + 0x434, 0x04030201); + } + break; + default: + break; + } + } + + coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; +} + +static void halbtc8723b1ant_retry_limit(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_retry_limit_type = type; + + if (force_exec || (coex_dm->pre_retry_limit_type != + coex_dm->cur_retry_limit_type)) { + switch (coex_dm->cur_retry_limit_type) { + case 0: /* normal mode */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, + coex_dm->backup_retry_limit); + break; + case 1: /* retry limit = 8 */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; +} + +static void halbtc8723b1ant_ampdu_maxtime(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_ampdu_time_type = type; + + if (force_exec || (coex_dm->pre_ampdu_time_type != + coex_dm->cur_ampdu_time_type)) { + switch (coex_dm->cur_ampdu_time_type) { + case 0: /* normal mode */ + btcoexist->btc_write_1byte(btcoexist, 0x456, + coex_dm->backup_ampdu_max_time); + break; + case 1: /* AMPDU timw = 0x38 * 32us */ + btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); + break; + default: + break; + } + } + + coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; +} + +static void halbtc8723b1ant_limited_tx(struct btc_coexist *btcoexist, + bool force_exec, u8 ra_masktype, + u8 arfr_type, u8 retry_limit_type, + u8 ampdu_time_type) +{ + switch (ra_masktype) { + case 0: /* normal mode */ + halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 0x0); + break; + case 1: /* disable cck 1/2 */ + halbtc8723b1ant_updatera_mask(btcoexist, force_exec, + 0x00000003); + break; + /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */ + case 2: + halbtc8723b1ant_updatera_mask(btcoexist, force_exec, + 0x0001f1f7); + break; + default: + break; + } + + btc8723b1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type); + halbtc8723b1ant_retry_limit(btcoexist, force_exec, retry_limit_type); + halbtc8723b1ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type); +} + +static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist, + bool force_exec, bool rej_ap_agg_pkt, + bool bt_ctrl_agg_buf_size, + u8 agg_buf_size) +{ + bool reject_rx_agg = rej_ap_agg_pkt; + bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rxaggsize = agg_buf_size; + + /********************************************** + * Rx Aggregation related setting + **********************************************/ + btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, + &reject_rx_agg); + /* decide BT control aggregation buf size or not */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, + &bt_ctrl_rx_agg_size); + /* aggregation buf size, only work + * when BT control Rx aggregation size. + */ + btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxaggsize); + /* real update aggregation setting */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist) +{ + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + /* trigger */ + h2c_parameter[0] |= BIT(0); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + +static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ + u32 reg_hp_txrx, reg_lp_txrx, u32tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0; + u32 reg_lp_tx = 0, reg_lp_rx = 0; + static u32 num_of_bt_counter_chk; + + reg_hp_txrx = 0x770; + reg_lp_txrx = 0x774; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); + reg_hp_tx = u32tmp & MASKLWORD; + reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); + reg_lp_tx = u32tmp & MASKLWORD; + reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + if ((coex_sta->low_priority_tx > 1050) && + (!coex_sta->c2h_bt_inquiry_page)) + coex_sta->pop_event_cnt++; + + /* reset counter */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); + + /* This part is for wifi FW and driver to update BT's status as + * disabled. + * + * The flow is as the following + * 1. disable BT + * 2. if all BT Tx/Rx counter = 0, after 6 sec we query bt info + * 3. Because BT will not rsp from mailbox, so wifi fw will know BT is + * disabled + * + * 4. FW will rsp c2h for BT that driver will know BT is disabled. + */ + if ((reg_hp_tx == 0) && (reg_hp_rx == 0) && (reg_lp_tx == 0) && + (reg_lp_rx == 0)) { + num_of_bt_counter_chk++; + if (num_of_bt_counter_chk == 3) + halbtc8723b1ant_query_bt_info(btcoexist); + } else { + num_of_bt_counter_chk = 0; + } +} + +static void halbtc8723b1ant_monitor_wifi_ctr(struct btc_coexist *btcoexist) +{ + s32 wifi_rssi = 0; + bool wifi_busy = false, wifi_under_b_mode = false; + static u8 cck_lock_counter; + u32 total_cnt; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + + if (coex_sta->under_ips) { + coex_sta->crc_ok_cck = 0; + coex_sta->crc_ok_11g = 0; + coex_sta->crc_ok_11n = 0; + coex_sta->crc_ok_11n_agg = 0; + + coex_sta->crc_err_cck = 0; + coex_sta->crc_err_11g = 0; + coex_sta->crc_err_11n = 0; + coex_sta->crc_err_11n_agg = 0; + } else { + coex_sta->crc_ok_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf88); + coex_sta->crc_ok_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf94); + coex_sta->crc_ok_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf90); + coex_sta->crc_ok_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfb8); + + coex_sta->crc_err_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf84); + coex_sta->crc_err_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf96); + coex_sta->crc_err_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf92); + coex_sta->crc_err_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfba); + } + + /* reset counter */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0); + + if ((wifi_busy) && (wifi_rssi >= 30) && (!wifi_under_b_mode)) { + total_cnt = coex_sta->crc_ok_cck + coex_sta->crc_ok_11g + + coex_sta->crc_ok_11n + coex_sta->crc_ok_11n_agg; + + if ((coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) || + (coex_dm->bt_status == + BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) || + (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY)) { + if (coex_sta->crc_ok_cck > + (total_cnt - coex_sta->crc_ok_cck)) { + if (cck_lock_counter < 3) + cck_lock_counter++; + } else { + if (cck_lock_counter > 0) + cck_lock_counter--; + } + + } else { + if (cck_lock_counter > 0) + cck_lock_counter--; + } + } else { + if (cck_lock_counter > 0) + cck_lock_counter--; + } + + if (!coex_sta->pre_ccklock) { + if (cck_lock_counter >= 3) + coex_sta->cck_lock = true; + else + coex_sta->cck_lock = false; + } else { + if (cck_lock_counter == 0) + coex_sta->cck_lock = false; + else + coex_sta->cck_lock = true; + } + + if (coex_sta->cck_lock) + coex_sta->cck_ever_lock = true; + + coex_sta->pre_ccklock = coex_sta->cck_lock; +} + +static bool btc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ + static bool pre_wifi_busy; + static bool pre_under_4way, pre_bt_hs_on; + bool wifi_busy = false, under_4way = false, bt_hs_on = false; + bool wifi_connected = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (wifi_connected) { + if (wifi_busy != pre_wifi_busy) { + pre_wifi_busy = wifi_busy; + return true; + } + if (under_4way != pre_under_4way) { + pre_under_4way = under_4way; + return true; + } + if (bt_hs_on != pre_bt_hs_on) { + pre_bt_hs_on = bt_hs_on; + return true; + } + } + + return false; +} + +static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + bt_link_info->bt_hi_pri_link_exist = coex_sta->bt_hi_pri_link_exist; + + /* work around for HS mode. */ + if (bt_hs_on) { + bt_link_info->pan_exist = true; + bt_link_info->bt_link_exist = true; + } + + /* check if Sco only */ + if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->sco_only = true; + else + bt_link_info->sco_only = false; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->a2dp_only = true; + else + bt_link_info->a2dp_only = false; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->pan_only = true; + else + bt_link_info->pan_only = false; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && bt_link_info->hid_exist) + bt_link_info->hid_only = true; + else + bt_link_info->hid_only = false; +} + +static void halbtc8723b1ant_set_bt_auto_report(struct btc_coexist *btcoexist, + bool enable_auto_report) +{ + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = 0; + + if (enable_auto_report) + h2c_parameter[0] |= BIT(0); + + btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); +} + +static void halbtc8723b1ant_bt_auto_report(struct btc_coexist *btcoexist, + bool force_exec, + bool enable_auto_report) +{ + coex_dm->cur_bt_auto_report = enable_auto_report; + + if (!force_exec) { + if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) + return; + } + halbtc8723b1ant_set_bt_auto_report(btcoexist, + coex_dm->cur_bt_auto_report); + + coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; +} + +static void btc8723b1ant_set_sw_pen_tx_rate_adapt(struct btc_coexist *btcoexist, + bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[6] = {0}; + + h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */ + + if (low_penalty_ra) { + h2c_parameter[1] |= BIT0; + /* normal rate except MCS7/6/5, OFDM54/48/36 */ + h2c_parameter[2] = 0x00; + h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */ + h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */ + h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */ + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set WiFi Low-Penalty Retry: %s", + (low_penalty_ra ? "ON!!" : "OFF!!")); + + btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void halbtc8723b1ant_low_penalty_ra(struct btc_coexist *btcoexist, + bool force_exec, bool low_penalty_ra) +{ + coex_dm->cur_low_penalty_ra = low_penalty_ra; + + if (!force_exec) { + if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) + return; + } + btc8723b1ant_set_sw_pen_tx_rate_adapt(btcoexist, + coex_dm->cur_low_penalty_ra); + + coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void halbtc8723b1ant_set_coex_table(struct btc_coexist *btcoexist, + u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); + btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); + btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); + btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); + btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void halbtc8723b1ant_coex_table(struct btc_coexist *btcoexist, + bool force_exec, u32 val0x6c0, + u32 val0x6c4, u32 val0x6c8, + u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6cc = 0x%x\n", + (force_exec ? "force to" : ""), + val0x6c0, val0x6c4, val0x6cc); + coex_dm->cur_val0x6c0 = val0x6c0; + coex_dm->cur_val0x6c4 = val0x6c4; + coex_dm->cur_val0x6c8 = val0x6c8; + coex_dm->cur_val0x6cc = val0x6cc; + + if (!force_exec) { + if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && + (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && + (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && + (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) + return; + } + halbtc8723b1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, + val0x6c8, val0x6cc); + + coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; + coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; + coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; + coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_sta->coex_table_type = type; + + switch (type) { + case 0: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 4: + if ((coex_sta->cck_ever_lock) && (coex_sta->scan_ap_num <= 5)) + halbtc8723b1ant_coex_table(btcoexist, force_exec, + 0x55555555, 0xaaaa5a5a, + 0xffffff, 0x3); + else + halbtc8723b1ant_coex_table(btcoexist, force_exec, + 0x55555555, 0x5a5a5a5a, + 0xffffff, 0x3); + break; + case 5: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0x5aaa5a5a, 0xffffff, 0x3); + break; + case 6: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 7: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 8: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +static void +halbtc8723b1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, + bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + if (enable) + h2c_parameter[0] |= BIT0; /* function enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist, + bool force_exec, bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Ignore WlanAct %s\n", + (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); + coex_dm->cur_ignore_wlan_act = enable; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n", + coex_dm->pre_ignore_wlan_act, + coex_dm->cur_ignore_wlan_act); + + if (coex_dm->pre_ignore_wlan_act == + coex_dm->cur_ignore_wlan_act) + return; + } + halbtc8723b1ant_set_fw_ignore_wlan_act(btcoexist, enable); + + coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void halbtc8723b1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, + u8 byte1, u8 byte2, u8 byte3, + u8 byte4, u8 byte5) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[5] = {0}; + u8 real_byte1 = byte1, real_byte5 = byte5; + bool ap_enable = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + + if (ap_enable) { + if ((byte1 & BIT4) && !(byte1 & BIT5)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW for 1Ant AP mode\n"); + real_byte1 &= ~BIT4; + real_byte1 |= BIT5; + + real_byte5 |= BIT5; + real_byte5 &= ~BIT6; + } + } + + h2c_parameter[0] = real_byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = real_byte5; + + coex_dm->ps_tdma_para[0] = real_byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = real_byte5; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + h2c_parameter[0], + h2c_parameter[1] << 24 | + h2c_parameter[2] << 16 | + h2c_parameter[3] << 8 | + h2c_parameter[4]); + + btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void halbtc8723b1ant_set_lps_rpwm(struct btc_coexist *btcoexist, + u8 lps_val, u8 rpwm_val) +{ + u8 lps = lps_val; + u8 rpwm = rpwm_val; + + btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); + btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); +} + +static void halbtc8723b1ant_lps_rpwm(struct btc_coexist *btcoexist, + bool force_exec, + u8 lps_val, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n", + (force_exec ? "force to" : ""), lps_val, rpwm_val); + coex_dm->cur_lps = lps_val; + coex_dm->cur_rpwm = rpwm_val; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS-RxBeaconMode = 0x%x , LPS-RPWM = 0x%x!!\n", + coex_dm->cur_lps, coex_dm->cur_rpwm); + + if ((coex_dm->pre_lps == coex_dm->cur_lps) && + (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS-RPWM_Last = 0x%x , LPS-RPWM_Now = 0x%x!!\n", + coex_dm->pre_rpwm, coex_dm->cur_rpwm); + + return; + } + } + halbtc8723b1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); + + coex_dm->pre_lps = coex_dm->cur_lps; + coex_dm->pre_rpwm = coex_dm->cur_rpwm; +} + +static void halbtc8723b1ant_sw_mechanism(struct btc_coexist *btcoexist, + bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra); + + halbtc8723b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void halbtc8723b1ant_set_ant_path(struct btc_coexist *btcoexist, + u8 ant_pos_type, bool force_exec, + bool init_hw_cfg, bool wifi_off) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_board_info *board_info = &btcoexist->board_info; + u32 fw_ver = 0, u32tmp = 0, cnt_bt_cal_chk = 0; + bool pg_ext_switch = false; + bool use_ext_switch = false; + bool is_in_mp_mode = false; + u8 h2c_parameter[2] = {0}, u8tmp = 0; + + coex_dm->cur_ant_pos_type = ant_pos_type; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch); + /* [31:16] = fw ver, [15:0] = fw sub ver */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + + if ((fw_ver < 0xc0000) || pg_ext_switch) + use_ext_switch = true; + + if (init_hw_cfg) { + /* WiFi TRx Mask on */ + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x780); + /* remove due to interrupt is disabled that polling c2h will + * fail and delay 100ms. + */ + + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to HIGH */ + h2c_parameter[0] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, + h2c_parameter); + } else { + /* set grant_bt to high */ + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + } + /* set wlan_act control by PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + /* BT select s0/s1 is controlled by BT */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x39, 0x8, 0x1); + btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); + btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); + } else if (wifi_off) { + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to HIGH */ + h2c_parameter[0] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, + h2c_parameter); + } else { + /* set grant_bt to high */ + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + } + /* set wlan_act to always low */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, + &is_in_mp_mode); + if (!is_in_mp_mode) + /* BT select s0/s1 is controlled by BT */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, + 0x20, 0x0); + else + /* BT select s0/s1 is controlled by WiFi */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, + 0x20, 0x1); + + /* 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL + * BT Vendor 0xac=0xf002 + */ + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u32tmp &= ~BIT23; + u32tmp &= ~BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + } else { + /* Use H2C to set GNT_BT to LOW */ + if (fw_ver >= 0x180000) { + if (btcoexist->btc_read_1byte(btcoexist, 0x765) != 0) { + h2c_parameter[0] = 0; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, + h2c_parameter); + } + } else { + /* BT calibration check */ + while (cnt_bt_cal_chk <= 20) { + u8tmp = btcoexist->btc_read_1byte(btcoexist, + 0x49d); + cnt_bt_cal_chk++; + if (u8tmp & BIT(0)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], ########### BT is calibrating (wait cnt=%d) ###########\n", + cnt_bt_cal_chk); + mdelay(50); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)**********\n", + cnt_bt_cal_chk); + break; + } + } + + /* set grant_bt to PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x0); + } + + if (btcoexist->btc_read_1byte(btcoexist, 0x76e) != 0xc) { + /* set wlan_act control by PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); + } + + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x67, 0x20, + 0x1); /* BT select s0/s1 is controlled by WiFi */ + } + + if (use_ext_switch) { + if (init_hw_cfg) { + /* 0x4c[23] = 0, 0x4c[24] = 1 + * Antenna control by WL/BT + */ + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u32tmp &= ~BIT23; + u32tmp |= BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + + /* fixed internal switch S1->WiFi, S0->BT */ + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); + + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) { + /* tell firmware "no antenna inverse" */ + h2c_parameter[0] = 0; + /* ext switch type */ + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } else { + /* tell firmware "antenna inverse" */ + h2c_parameter[0] = 1; + /* ext switch type */ + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } + } + + if (force_exec || + (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) { + /* ext switch setting */ + switch (ant_pos_type) { + case BTC_ANT_PATH_WIFI: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x1); + else + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x2); + break; + case BTC_ANT_PATH_BT: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x2); + else + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x1); + break; + default: + case BTC_ANT_PATH_PTA: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x1); + else + btcoexist->btc_write_1byte_bitmask( + btcoexist, 0x92c, 0x3, 0x2); + break; + } + } + } else { + if (init_hw_cfg) { + /* 0x4c[23] = 1, 0x4c[24] = 0, + * Antenna control by 0x64 + */ + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u32tmp |= BIT23; + u32tmp &= ~BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + + /* Fix Ext switch Main->S1, Aux->S0 */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, + 0x0); + + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) { + /* tell firmware "no antenna inverse" */ + h2c_parameter[0] = 0; + /* internal switch type */ + h2c_parameter[1] = 0; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } else { + /* tell firmware "antenna inverse" */ + h2c_parameter[0] = 1; + /* internal switch type */ + h2c_parameter[1] = 0; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } + } + + if (force_exec || + (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) { + /* internal switch setting */ + switch (ant_pos_type) { + case BTC_ANT_PATH_WIFI: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x0); + else + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x280); + break; + case BTC_ANT_PATH_BT: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x280); + else + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x0); + break; + default: + case BTC_ANT_PATH_PTA: + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x200); + else + btcoexist->btc_write_4byte(btcoexist, + 0x948, 0x80); + break; + } + } + } + + coex_dm->pre_ant_pos_type = coex_dm->cur_ant_pos_type; +} + +static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, + bool force_exec, bool turn_on, u8 type) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_busy = false; + u8 rssi_adjust_val = 0; + u8 ps_tdma_byte0_val = 0x51; + u8 ps_tdma_byte3_val = 0x10; + u8 ps_tdma_byte4_val = 0x50; + s8 wifi_duration_adjust = 0x0; + static bool pre_wifi_busy; + + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (wifi_busy != pre_wifi_busy) { + force_exec = true; + pre_wifi_busy = wifi_busy; + } + + if (!force_exec) { + if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && + (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) + return; + } + + if (coex_sta->scan_ap_num <= 5) { + wifi_duration_adjust = 5; + + if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + } else if (coex_sta->scan_ap_num >= 40) { + wifi_duration_adjust = -15; + + if (coex_sta->a2dp_bit_pool < 35) + wifi_duration_adjust = -5; + else if (coex_sta->a2dp_bit_pool < 45) + wifi_duration_adjust = -10; + } else if (coex_sta->scan_ap_num >= 20) { + wifi_duration_adjust = -10; + + if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + } else { + wifi_duration_adjust = 0; + + if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + } + + if ((type == 1) || (type == 2) || (type == 9) || (type == 11) || + (type == 101) || (type == 102) || (type == 109) || (type == 111)) { + if (!coex_sta->force_lps_on) { + /* Native power save TDMA, only for A2DP-only case + * 1/2/9/11 while wifi noisy threshold > 30 + */ + + /* no null-pkt */ + ps_tdma_byte0_val = 0x61; + /* no tx-pause at BT-slot */ + ps_tdma_byte3_val = 0x11; + /* 0x778 = d/1 toggle, no dynamic slot */ + ps_tdma_byte4_val = 0x10; + } else { + /* null-pkt */ + ps_tdma_byte0_val = 0x51; + /* tx-pause at BT-slot */ + ps_tdma_byte3_val = 0x10; + /* 0x778 = d/1 toggle, dynamic slot */ + ps_tdma_byte4_val = 0x50; + } + } else if ((type == 3) || (type == 13) || (type == 14) || + (type == 103) || (type == 113) || (type == 114)) { + /* null-pkt */ + ps_tdma_byte0_val = 0x51; + /* tx-pause at BT-slot */ + ps_tdma_byte3_val = 0x10; + /* 0x778 = d/1 toggle, no dynamic slot */ + ps_tdma_byte4_val = 0x10; + } else { /* native power save case */ + /* no null-pkt */ + ps_tdma_byte0_val = 0x61; + /* no tx-pause at BT-slot */ + ps_tdma_byte3_val = 0x11; + /* 0x778 = d/1 toggle, no dynamic slot */ + ps_tdma_byte4_val = 0x11; + /* psTdmaByte4Va is not define for 0x778 = d/1, 1/1 case */ + } + + /* if (bt_link_info->slave_role) */ + if ((bt_link_info->slave_role) && (bt_link_info->a2dp_exist)) + /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */ + ps_tdma_byte4_val = ps_tdma_byte4_val | 0x1; + + if (type > 100) { + /* set antenna control by SW */ + ps_tdma_byte0_val = ps_tdma_byte0_val | 0x82; + /* set antenna no toggle, control by antenna diversity */ + ps_tdma_byte3_val = ps_tdma_byte3_val | 0x60; + } + + if (turn_on) { + switch (type) { + default: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a, + 0x1a, 0x0, + ps_tdma_byte4_val); + break; + case 1: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, + 0x3a + wifi_duration_adjust, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + + rssi_adjust_val = 11; + break; + case 2: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, + 0x2d + wifi_duration_adjust, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 3: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x30, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 4: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, + 0x3, 0x14, 0x0); + break; + case 5: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x1f, 0x3, + ps_tdma_byte3_val, 0x11); + break; + case 6: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x20, 0x3, + ps_tdma_byte3_val, 0x11); + break; + case 7: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc, + 0x5, 0x0, 0x0); + break; + case 8: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, + 0x3, 0x10, 0x0); + break; + case 9: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 10: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, + 0xa, 0x0, 0x40); + break; + case 11: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 12: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a, + 0x0a, 0x0, 0x50); + break; + case 13: + if (coex_sta->scan_ap_num <= 3) + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x40, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + else + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 14: + if (coex_sta->scan_ap_num <= 3) + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, 0x51, 0x30, 0x3, 0x10, 0x50); + else + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 15: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, + 0x3, 0x8, 0x0); + break; + case 16: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, + 0x3, 0x10, 0x0); + break; + case 18: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, + 0x3, 0x10, 0x0); + break; + case 20: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x3f, 0x03, + ps_tdma_byte3_val, 0x10); + break; + case 21: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, + 0x03, 0x11, 0x11); + break; + case 22: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x25, 0x03, + ps_tdma_byte3_val, 0x10); + break; + case 23: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x3, 0x31, 0x18); + break; + case 24: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x3, 0x31, 0x18); + break; + case 25: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, + 0x3, 0x31, 0x18); + break; + case 26: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, + 0x3, 0x31, 0x18); + break; + case 27: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x3, 0x31, 0x98); + break; + case 28: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25, + 0x3, 0x31, 0x0); + break; + case 29: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a, + 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30, + 0x3, 0x10, 0x10); + break; + case 31: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a, + 0x1a, 0, 0x58); + break; + case 32: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x35, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 33: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x35, 0x3, + ps_tdma_byte3_val, 0x10); + break; + case 34: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a, + 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a, + 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12, + 0x3, 0x14, 0x50); + break; + case 40: + /* SoftAP only with no sta associated,BT disable ,TDMA + * mode for power saving + * + * here softap mode screen off will cost 70-80mA for + * phone + */ + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18, + 0x00, 0x10, 0x24); + break; + + case 101: + /* for 1-Ant translate to 2-Ant */ + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, + 0x3a + wifi_duration_adjust, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 102: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, + 0x2d + wifi_duration_adjust, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 103: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x3a, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 105: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x15, 0x3, + ps_tdma_byte3_val, 0x11); + break; + case 106: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x20, 0x3, + ps_tdma_byte3_val, 0x11); + break; + case 109: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 111: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 113: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 114: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x21, 0x3, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 120: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x3f, 0x03, + ps_tdma_byte3_val, 0x10); + break; + case 122: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x25, 0x03, + ps_tdma_byte3_val, 0x10); + break; + case 132: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x25, 0x03, + ps_tdma_byte3_val, ps_tdma_byte4_val); + break; + case 133: + halbtc8723b1ant_set_fw_ps_tdma( + btcoexist, ps_tdma_byte0_val, 0x25, 0x03, + ps_tdma_byte3_val, 0x11); + break; + } + } else { + /* disable PS tdma */ + switch (type) { + case 8: /* PTA Control */ + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, + 0x0, 0x0, 0x0); + halbtc8723b1ant_set_ant_path(btcoexist, + BTC_ANT_PATH_PTA, + FORCE_EXEC, + false, false); + break; + case 0: + default: + /* Software control, Antenna at BT side */ + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, + 0x0, 0x0, 0x0); + break; + case 1: /* 2-Ant, 0x778=3, antenna control by ant diversity */ + halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x48, 0x0); + break; + } + } + rssi_adjust_val = 0; + btcoexist->btc_set(btcoexist, + BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, + &rssi_adjust_val); + + /* update pre state */ + coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; + coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static +void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, + u8 wifi_status) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static s32 up, dn, m, n, wait_count; + /* 0: no change, +1: increase WiFi duration, + * -1: decrease WiFi duration + */ + s32 result; + u8 retry_count = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], TdmaDurationAdjustForAcl()\n"); + + if ((wifi_status == + BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) || + (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) || + (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)) { + if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && + coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } + return; + } + + if (!coex_dm->auto_tdma_adjust) { + coex_dm->auto_tdma_adjust = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], first run TdmaDurationAdjust()!!\n"); + + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } else { + /* acquire the BT TRx retry count from BT_Info byte2 */ + retry_count = coex_sta->bt_retry_cnt; + + if ((coex_sta->low_priority_tx) > 1050 || + (coex_sta->low_priority_rx) > 1250) + retry_count++; + + result = 0; + wait_count++; + /* no retry in the last 2-second duration */ + if (retry_count == 0) { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if (up >= n) { + /* if retry count during continuous n*2 seconds + * is 0, enlarge WiFi duration + */ + wait_count = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Increase wifi duration!!\n"); + } + } else if (retry_count <= 3) { + /* <=3 retry in the last 2-second duration */ + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) { + /* if continuous 2 retry count(every 2 seconds) + * >0 and < 3, reduce WiFi duration + */ + if (wait_count <= 2) + /* avoid loop between the two levels */ + m++; + else + m = 1; + + if (m >= 20) + /* maximum of m = 20 ' will recheck if + * need to adjust wifi duration in + * maximum time interval 120 seconds + */ + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); + } + } else { + /* retry count > 3, once retry count > 3, to reduce + * WiFi duration + */ + if (wait_count == 1) + /* to avoid loop between the two levels */ + m++; + else + m = 1; + + if (m >= 20) + /* maximum of m = 20 ' will recheck if need to + * adjust wifi duration in maximum time interval + * 120 seconds + */ + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); + } + + if (result == -1) { + if (coex_dm->cur_ps_tdma == 1) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 2) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (coex_dm->cur_ps_tdma == 9) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 11) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (coex_dm->cur_ps_tdma == 9) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 2) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = 1; + } + } + + if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && + coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) { + /* recover to previous adjust type */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + coex_dm->ps_tdma_du_adj_type); + } + } +} + +static void halbtc8723b1ant_ps_tdma_chk_pwr_save(struct btc_coexist *btcoexist, + bool new_ps_state) +{ + u8 lps_mode = 0x0; + + btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); + + if (lps_mode) { + /* already under LPS state */ + if (new_ps_state) { + /* keep state under LPS, do nothing. */ + } else { + /* will leave LPS state, turn off psTdma first */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + false, 0); + } + } else { + /* NO PS state */ + if (new_ps_state) { + /* will enter LPS state, turn off psTdma first */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + false, 0); + } else { + /* keep state under NO PS state, do nothing. */ + } + } +} + +static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, + u8 ps_type, u8 lps_val, + u8 rpwm_val) +{ + bool low_pwr_disable = false; + + switch (ps_type) { + case BTC_PS_WIFI_NATIVE: + /* recover to original 32k low power setting */ + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + coex_sta->force_lps_on = false; + break; + case BTC_PS_LPS_ON: + halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, true); + halbtc8723b1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, + rpwm_val); + /* when coex force to enter LPS, do not enter 32k low power */ + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + /* power save must executed before psTdma */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); + coex_sta->force_lps_on = true; + break; + case BTC_PS_LPS_OFF: + halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, false); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + coex_sta->force_lps_on = false; + break; + default: + break; + } +} + +static void halbtc8723b1ant_action_wifi_only(struct btc_coexist *btcoexist) +{ + halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + FORCE_EXEC, false, false); +} + +/* check if BT is disabled */ +static void halbtc8723b1ant_monitor_bt_enable_disable(struct btc_coexist + *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static u32 bt_disable_cnt; + bool bt_active = true, bt_disabled = false; + + if (coex_sta->high_priority_tx == 0 && + coex_sta->high_priority_rx == 0 && coex_sta->low_priority_tx == 0 && + coex_sta->low_priority_rx == 0) + bt_active = false; + if (coex_sta->high_priority_tx == 0xffff && + coex_sta->high_priority_rx == 0xffff && + coex_sta->low_priority_tx == 0xffff && + coex_sta->low_priority_rx == 0xffff) + bt_active = false; + if (bt_active) { + bt_disable_cnt = 0; + bt_disabled = false; + } else { + bt_disable_cnt++; + if (bt_disable_cnt >= 2) + bt_disabled = true; + } + if (coex_sta->bt_disabled != bt_disabled) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is from %s to %s!!\n", + (coex_sta->bt_disabled ? "disabled" : "enabled"), + (bt_disabled ? "disabled" : "enabled")); + + coex_sta->bt_disabled = bt_disabled; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, + &bt_disabled); + if (bt_disabled) { + halbtc8723b1ant_action_wifi_only(btcoexist); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, + NULL); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, + NULL); + } + } +} + +/***************************************************** + * + * Non-Software Coex Mechanism start + * + *****************************************************/ + +static void halbtc8723b1ant_action_bt_whck_test(struct btc_coexist *btcoexist) +{ + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, + 0x0); + + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, + false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist) +{ + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, + false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); +} + +static void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist) +{ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); +} + +static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_connected = false, ap_enable = false; + bool wifi_busy = false, bt_busy = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + if (coex_sta->bt_abnormal_scan) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + } else if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) { + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + } else if (bt_link_info->sco_exist || bt_link_info->hid_exist || + bt_link_info->a2dp_exist) { + /* SCO/HID/A2DP busy */ + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + if (coex_sta->c2h_bt_remote_name_req) + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + 33); + else + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + 32); + + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else if (bt_link_info->pan_exist || wifi_busy) { + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + if (coex_sta->c2h_bt_remote_name_req) + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + 33); + else + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + 32); + + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else { + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + } +} + +static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, + u8 wifi_status) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_connected = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + /* tdma and coex table */ + if (bt_link_info->sco_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); + } else { + /* HID */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); + } +} + +static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy( + struct btc_coexist *btcoexist, + u8 wifi_status) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + if ((coex_sta->low_priority_rx >= 950) && (!coex_sta->under_ips)) + bt_link_info->slave_role = true; + else + bt_link_info->slave_role = false; + + if (bt_link_info->hid_only) { /* HID */ + btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status); + coex_dm->auto_tdma_adjust = false; + return; + } else if (bt_link_info->a2dp_only) { /* A2DP */ + if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + coex_dm->auto_tdma_adjust = false; + } else { + btc8723b1ant_tdma_dur_adj_for_acl(btcoexist, + wifi_status); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + coex_dm->auto_tdma_adjust = true; + } + } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) || + (bt_link_info->hid_exist && bt_link_info->a2dp_exist && + bt_link_info->pan_exist)) { + /* A2DP + PAN(OPP,FTP), HID + A2DP + PAN(OPP,FTP) */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + coex_dm->auto_tdma_adjust = false; + } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { + /* HID + A2DP */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + coex_dm->auto_tdma_adjust = false; + + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else if (bt_link_info->pan_only || + (bt_link_info->hid_exist && bt_link_info->pan_exist)) { + /* PAN(OPP,FTP), HID + PAN(OPP,FTP) */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + coex_dm->auto_tdma_adjust = false; + } else { + /* BT no-profile busy (0x9) */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + coex_dm->auto_tdma_adjust = false; + } +} + +static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist) +{ + /* power save state */ + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, + false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void +btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { + if (bt_link_info->a2dp_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else if (bt_link_info->pan_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 22); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 20); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + } + } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || + coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY){ + btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static void +btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) || + (bt_link_info->a2dp_exist)) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); + } else if (bt_link_info->pan_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2); + } +} + +static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { + if (bt_link_info->a2dp_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else if (bt_link_info->pan_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 22); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 20); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } + } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || + coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { + btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static void halbtc8723b1ant_action_wifi_connected_special_packet( + struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_busy = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + /* no special packet process for both WiFi and BT very busy */ + if ((wifi_busy) && + ((bt_link_info->pan_exist) || (coex_sta->num_of_profile >= 2))) + return; + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); + } else if (bt_link_info->a2dp_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else if (bt_link_info->pan_exist) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_busy = false; + bool scan = false, link = false, roam = false; + bool under_4way = false, ap_enable = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect()===>\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + if (under_4way) { + halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (scan || link || roam) { + if (scan) + btc8723b1ant_action_wifi_conn_scan(btcoexist); + else + halbtc8723b1ant_action_wifi_connected_special_packet( + btcoexist); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + /* power save state */ + if (!ap_enable && + coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY && + !btcoexist->bt_link_info.hid_only) { + if (btcoexist->bt_link_info.a2dp_only) { + if (!wifi_busy) { + halbtc8723b1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { /* busy */ + if (coex_sta->scan_ap_num >= + BT_8723B_1ANT_WIFI_NOISY_THRESH) + /* no force LPS, no PS-TDMA, + * use pure TDMA + */ + halbtc8723b1ant_power_save_state( + btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + else + halbtc8723b1ant_power_save_state( + btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + } else if ((!coex_sta->pan_exist) && (!coex_sta->a2dp_exist) && + (!coex_sta->hid_exist)) + halbtc8723b1ant_power_save_state( + btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8723b1ant_power_save_state(btcoexist, + BTC_PS_LPS_ON, + 0x50, 0x4); + } else { + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } + /* tdma and coex table */ + if (!wifi_busy) { + if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { + halbtc8723b1ant_action_wifi_connected_bt_acl_busy( + btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } else if (coex_dm->bt_status == + BT_8723B_1ANT_BT_STATUS_SCO_BUSY || + coex_dm->bt_status == + BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { + btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, + BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 2); + } + } else { + if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { + halbtc8723b1ant_action_wifi_connected_bt_acl_busy( + btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } else if (coex_dm->bt_status == + BT_8723B_1ANT_BT_STATUS_SCO_BUSY || + coex_dm->bt_status == + BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { + btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } else { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 32); + halbtc8723b1ant_set_ant_path(btcoexist, + BTC_ANT_PATH_PTA, + NORMAL_EXEC, false, false); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } + } +} + +static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_connected = false, bt_hs_on = false, wifi_busy = false; + bool increase_scan_dev_num = false; + bool bt_ctrl_agg_buf_size = false; + bool miracast_plus_bt = false; + u8 agg_buf_size = 5; + u8 iot_peer = BTC_IOT_PEER_UNKNOWN; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + u32 wifi_bw; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism()===>\n"); + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); + return; + } + + if (btcoexist->stop_coex_dm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); + return; + } + + if (coex_sta->under_ips) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + return; + } + + if (coex_sta->bt_whck_test) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + halbtc8723b1ant_action_bt_whck_test(btcoexist); + return; + } + + if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY || + coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || + coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) + increase_scan_dev_num = true; + + btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, + &increase_scan_dev_num); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + + if (num_of_wifi_link >= 2 || + wifi_link_status & WIFI_P2P_GO_CONNECTED) { + if (bt_link_info->bt_link_exist) { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, + 0, 1); + miracast_plus_bt = true; + } else { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, + 0, 0); + miracast_plus_bt = false; + } + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + + if ((bt_link_info->a2dp_exist || wifi_busy) && + (coex_sta->c2h_bt_inquiry_page)) + halbtc8723b1ant_action_bt_inquiry(btcoexist); + else + halbtc8723b1ant_action_wifi_multiport(btcoexist); + + return; + } + + miracast_plus_bt = false; + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (bt_link_info->bt_link_exist && wifi_connected) { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 0, 1); + + btcoexist->btc_get(btcoexist, BTC_GET_U1_IOT_PEER, &iot_peer); + + if (iot_peer != BTC_IOT_PEER_CISCO && + iot_peer != BTC_IOT_PEER_BROADCOM) { + bool sco_exist = bt_link_info->sco_exist; + + halbtc8723b1ant_limited_rx(btcoexist, + NORMAL_EXEC, sco_exist, + false, 0x5); + } else { + if (bt_link_info->sco_exist) { + halbtc8723b1ant_limited_rx(btcoexist, + NORMAL_EXEC, true, + false, 0x5); + } else { + if (wifi_bw == BTC_WIFI_BW_HT40) + halbtc8723b1ant_limited_rx( + btcoexist, NORMAL_EXEC, false, + true, 0x10); + else + halbtc8723b1ant_limited_rx( + btcoexist, NORMAL_EXEC, false, + true, 0x8); + } + } + + halbtc8723b1ant_sw_mechanism(btcoexist, true); + } else { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, + 0x5); + + halbtc8723b1ant_sw_mechanism(btcoexist, false); + } + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + if (coex_sta->c2h_bt_inquiry_page) { + halbtc8723b1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + halbtc8723b1ant_action_hs(btcoexist); + return; + } + + if (!wifi_connected) { + bool scan = false, link = false, roam = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is non connected-idle !!!\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (scan || link || roam) { + if (scan) + btc8723b1ant_action_wifi_not_conn_scan( + btcoexist); + else + btc8723b1ant_act_wifi_not_conn_asso_auth( + btcoexist); + } else { + btc8723b1ant_action_wifi_not_conn(btcoexist); + } + } else { /* wifi LPS/Busy */ + halbtc8723b1ant_action_wifi_connected(btcoexist); + } +} + +/* force coex mechanism to reset */ +static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + /* sw all off */ + halbtc8723b1ant_sw_mechanism(btcoexist, false); + + coex_sta->pop_event_cnt = 0; +} + +static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist, + bool backup, bool wifi_only) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u32 u32tmp = 0; + u8 u8tmpa = 0, u8tmpb = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 1Ant Init HW Config!!\n"); + + /* 0xf0[15:12] --> Chip Cut information */ + coex_sta->cut_version = + (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4; + /* enable TBTT interrupt */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8, 0x1); + + /* 0x790[5:0] = 0x5 */ + btcoexist->btc_write_1byte(btcoexist, 0x790, 0x5); + + /* Enable counter statistics */ + btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); + + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + + /* Antenna config */ + if (wifi_only) + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI, + FORCE_EXEC, true, false); + else + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + FORCE_EXEC, true, false); + + /* PTA parameter */ + halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + u32tmp, u8tmpa, u8tmpb); +} + +/************************************************************** + * extern function start with ex_btc8723b1ant_ + **************************************************************/ +void ex_btc8723b1ant_power_on_setting(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_board_info *board_info = &btcoexist->board_info; + u8 u8tmp = 0x0; + u16 u16tmp = 0x0; + u32 value; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "xxxxxxxxxxxxxxxx Execute 8723b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n"); + + btcoexist->stop_coex_dm = true; + + btcoexist->btc_write_1byte(btcoexist, 0x67, 0x20); + + /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */ + u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2); + btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT0 | BIT1); + + /* set GRAN_BT = 1 */ + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + /* set WLAN_ACT = 0 */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + /* S0 or S1 setting and Local register setting(By the setting fw can get + * ant number, S0/S1, ... info) + * + * Local setting bit define + * BIT0: "0" for no antenna inverse; "1" for antenna inverse + * BIT1: "0" for internal switch; "1" for external switch + * BIT2: "0" for one antenna; "1" for two antenna + * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and + * BIT2 = 0 + */ + if (btcoexist->chip_interface == BTC_INTF_USB) { + /* fixed at S0 for USB interface */ + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); + + u8tmp |= 0x1; /* antenna inverse */ + btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp); + + board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; + } else { + /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ + if (board_info->single_ant_path == 0) { + /* set to S1 */ + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x280); + board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; + value = 1; + } else if (board_info->single_ant_path == 1) { + /* set to S0 */ + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); + u8tmp |= 0x1; /* antenna inverse */ + board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; + value = 0; + } + + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, + &value); + + if (btcoexist->chip_interface == BTC_INTF_PCI) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384, + u8tmp); + else if (btcoexist->chip_interface == BTC_INTF_SDIO) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, + u8tmp); + } +} + + +void ex_btc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist, + bool wifi_only) +{ + halbtc8723b1ant_init_hw_config(btcoexist, true, wifi_only); + btcoexist->stop_coex_dm = false; +} + +void ex_btc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Coex Mechanism Init!!\n"); + + btcoexist->stop_coex_dm = false; + + halbtc8723b1ant_init_coex_dm(btcoexist); + + halbtc8723b1ant_query_bt_info(btcoexist); +} + +void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0; + u16 u16tmp[4]; + u32 u32tmp[4]; + bool roam = false, scan = false; + bool link = false, wifi_under_5g = false; + bool bt_hs_on = false, wifi_busy = false; + s32 wifi_rssi = 0, bt_hs_rssi = 0; + u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck, wifi_link_status; + u8 wifi_dot11_chnl, wifi_hs_chnl; + u32 fw_ver = 0, bt_patch_ver = 0; + + seq_puts(m, "\n ============[BT Coexist info]============"); + + if (btcoexist->manual_control) { + seq_puts(m, "\n ============[Under Manual Control]=========="); + seq_puts(m, "\n =========================================="); + } + if (btcoexist->stop_coex_dm) { + seq_puts(m, "\n ============[Coex is STOPPED]============"); + seq_puts(m, "\n =========================================="); + } + + seq_printf(m, "\n %-35s = %d/ %d/ %d", + "Ant PG Num/ Ant Mech/ Ant Pos:", + board_info->pg_ant_num, board_info->btdm_ant_num, + board_info->btdm_ant_pos); + + seq_printf(m, "\n %-35s = %s / %d", + "BT stack/ hci ext ver", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + seq_printf(m, "\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", + "CoexVer/ FwVer/ PatchVer", + glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant, + fw_ver, bt_patch_ver, bt_patch_ver); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, + &wifi_dot11_chnl); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsChnl(HsMode)", + wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); + + seq_printf(m, "\n %-35s = %3ph ", + "H2C Wifi inform bt chnl Info", + coex_dm->wifi_chnl_info); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + seq_printf(m, "\n %-35s = %d/ %d", + "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "Wifi link/ roam/ scan", link, roam, scan); + + btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G, + &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + &wifi_traffic_dir); + + seq_printf(m, "\n %-35s = %s / %s/ %s ", + "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), + ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" : + ((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20")), + ((!wifi_busy) ? "idle" : + ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ? + "uplink" : "downlink"))); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d", + "sta/vwifi/hs/p2pGo/p2pGc", + ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0)); + + seq_printf(m, "\n %-35s = [%s/ %d/ %d] ", + "BT [status/ rssi/ retryCnt]", + ((coex_sta->bt_disabled) ? ("disabled") : + ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : + ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) ? + "non-connected idle" : + ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status) ? + "connected-idle" : "busy")))), + coex_sta->bt_rssi, coex_sta->bt_retry_cnt); + + seq_printf(m, "\n %-35s = %d / %d / %d / %d", + "SCO/HID/PAN/A2DP", bt_link_info->sco_exist, + bt_link_info->hid_exist, bt_link_info->pan_exist, + bt_link_info->a2dp_exist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); + + bt_info_ext = coex_sta->bt_info_ext; + seq_printf(m, "\n %-35s = %s", + "BT Info A2DP rate", + (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate"); + + for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + seq_printf(m, "\n %-35s = %7ph(%d)", + glbt_info_src_8723b_1ant[i], + coex_sta->bt_info_c2h[i], + coex_sta->bt_info_c2h_cnt[i]); + } + } + seq_printf(m, "\n %-35s = %s/%s, (0x%x/0x%x)", + "PS state, IPS/LPS, (lps/rpwm)", + ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), + ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")), + btcoexist->bt_info.lps_val, + btcoexist->bt_info.rpwm_val); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); + + if (!btcoexist->manual_control) { + /* Sw mechanism */ + seq_printf(m, "\n %-35s", + "============[Sw mechanism]============"); + + seq_printf(m, "\n %-35s = %d/", + "SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra); + + seq_printf(m, "\n %-35s = %s/ %s/ %d ", + "DelBA/ BtCtrlAgg/ AggSize", + (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), + (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), + btcoexist->bt_info.agg_buf_size); + + seq_printf(m, "\n %-35s = 0x%x ", + "Rate Mask", btcoexist->bt_info.ra_mask); + + /* Fw mechanism */ + seq_printf(m, "\n %-35s", + "============[Fw mechanism]============"); + + pstdmacase = coex_dm->cur_ps_tdma; + seq_printf(m, "\n %-35s = %5ph case-%d (auto:%d)", + "PS TDMA", coex_dm->ps_tdma_para, + pstdmacase, coex_dm->auto_tdma_adjust); + + seq_printf(m, "\n %-35s = %d ", + "IgnWlanAct", coex_dm->cur_ignore_wlan_act); + + seq_printf(m, "\n %-35s = 0x%x ", + "Latest error condition(should be 0)", + coex_dm->error_condition); + } + + seq_printf(m, "\n %-35s = %d", + "Coex Table Type", coex_sta->coex_table_type); + + /* Hw setting */ + seq_printf(m, "\n %-35s", + "============[Hw setting]============"); + + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, + coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit, + coex_dm->backup_ampdu_max_time); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); + u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "0x430/0x434/0x42a/0x456", + u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0], + (u32tmp[1] & 0x3e000000) >> 25); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x948/ 0x67[5] / 0x765", + u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", + u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "0x38[11]/0x40/0x4c[24:23]/0x64[0]", + ((u8tmp[0] & 0x8) >> 3), u8tmp[1], + ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); + u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + + fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) + + ((u32tmp[1] & 0xffff0000) >> 16) + + (u32tmp[1] & 0xffff) + + (u32tmp[2] & 0xffff) + + ((u32tmp[3] & 0xffff0000) >> 16) + + (u32tmp[3] & 0xffff); + fa_cck = (u8tmp[0] << 8) + u8tmp[1]; + + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "OFDM-CCA/OFDM-FA/CCK-FA", + u32tmp[0] & 0xffff, fa_ofdm, fa_cck); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x6c0/0x6c4/0x6c8(coexTable)", + u32tmp[0], u32tmp[1], u32tmp[2]); + + seq_printf(m, "\n %-35s = %d/ %d", + "0x770(high-pri rx/tx)", coex_sta->high_priority_rx, + coex_sta->high_priority_tx); + seq_printf(m, "\n %-35s = %d/ %d", + "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, + coex_sta->low_priority_tx); + if (btcoexist->auto_report_1ant) + halbtc8723b1ant_monitor_bt_ctr(btcoexist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); +} + +void ex_btc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + + if (BTC_IPS_ENTER == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS ENTER notify\n"); + coex_sta->under_ips = true; + + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + FORCE_EXEC, false, true); + /* set PTA control */ + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + halbtc8723b1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + } else if (BTC_IPS_LEAVE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS LEAVE notify\n"); + coex_sta->under_ips = false; + + halbtc8723b1ant_init_hw_config(btcoexist, false, false); + halbtc8723b1ant_init_coex_dm(btcoexist); + halbtc8723b1ant_query_bt_info(btcoexist); + } +} + +void ex_btc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + + if (BTC_LPS_ENABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS ENABLE notify\n"); + coex_sta->under_lps = true; + } else if (BTC_LPS_DISABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS DISABLE notify\n"); + coex_sta->under_lps = false; + } +} + +void ex_btc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false, bt_hs_on = false; + u8 u8tmpa, u8tmpb; + u32 u32tmp; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + bool bt_ctrl_agg_buf_size = false; + u8 agg_buf_size = 5; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + + if (type == BTC_SCAN_START) { + coex_sta->wifi_is_high_pri_task = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + /* Force antenna setup for no scan result issue */ + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + FORCE_EXEC, false, false); + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + u32tmp, u8tmpa, u8tmpb); + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, + &coex_sta->scan_ap_num); + } + + if (coex_sta->bt_disabled) + return; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + halbtc8723b1ant_query_bt_info(btcoexist); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if (num_of_wifi_link >= 2) { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + halbtc8723b1ant_action_wifi_multiport(btcoexist); + return; + } + + if (coex_sta->c2h_bt_inquiry_page) { + halbtc8723b1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + halbtc8723b1ant_action_hs(btcoexist); + return; + } + + if (BTC_SCAN_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + if (!wifi_connected) + /* non-connected scan */ + btc8723b1ant_action_wifi_not_conn_scan(btcoexist); + else + /* wifi is connected */ + btc8723b1ant_action_wifi_conn_scan(btcoexist); + } else if (BTC_SCAN_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + if (!wifi_connected) + /* non-connected scan */ + btc8723b1ant_action_wifi_not_conn(btcoexist); + else + halbtc8723b1ant_action_wifi_connected(btcoexist); + } +} + +void ex_btc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false, bt_hs_on = false; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + bool bt_ctrl_agg_buf_size = false, under_4way = false; + u8 agg_buf_size = 5; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + + if (type == BTC_ASSOCIATE_START) { + coex_sta->wifi_is_high_pri_task = true; + + /* Force antenna setup for no scan result issue */ + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + FORCE_EXEC, false, false); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + coex_dm->arp_cnt = 0; + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status>>16; + if (num_of_wifi_link >= 2) { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + halbtc8723b1ant_action_wifi_multiport(btcoexist); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + if (coex_sta->c2h_bt_inquiry_page) { + halbtc8723b1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + halbtc8723b1ant_action_hs(btcoexist); + return; + } + + if (BTC_ASSOCIATE_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + btc8723b1ant_act_wifi_not_conn_asso_auth(btcoexist); + } else if (BTC_ASSOCIATE_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + if (!wifi_connected) + /* non-connected scan */ + btc8723b1ant_action_wifi_not_conn(btcoexist); + else + halbtc8723b1ant_action_wifi_connected(btcoexist); + } +} + +void ex_btc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[3] = {0}; + u32 wifi_bw; + u8 wifi_central_chnl; + bool wifi_under_b_mode = false; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + + if (type == BTC_MEDIA_CONNECT) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA connect notify\n"); + /* Force antenna setup for no scan result issue */ + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + FORCE_EXEC, false, false); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + + /* Set CCK Tx/Rx high Pri except 11b mode */ + if (wifi_under_b_mode) { + btcoexist->btc_write_1byte(btcoexist, 0x6cd, + 0x00); /* CCK Tx */ + btcoexist->btc_write_1byte(btcoexist, 0x6cf, + 0x00); /* CCK Rx */ + } else { + btcoexist->btc_write_1byte(btcoexist, 0x6cd, + 0x00); /* CCK Tx */ + btcoexist->btc_write_1byte(btcoexist, 0x6cf, + 0x10); /* CCK Rx */ + } + + coex_dm->backup_arfr_cnt1 = + btcoexist->btc_read_4byte(btcoexist, 0x430); + coex_dm->backup_arfr_cnt2 = + btcoexist->btc_read_4byte(btcoexist, 0x434); + coex_dm->backup_retry_limit = + btcoexist->btc_read_2byte(btcoexist, 0x42a); + coex_dm->backup_ampdu_max_time = + btcoexist->btc_read_1byte(btcoexist, 0x456); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA disconnect notify\n"); + coex_dm->arp_cnt = 0; + + btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */ + btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */ + + coex_sta->cck_ever_lock = false; + } + + /* only 2.4G we need to inform bt the chnl mask */ + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, + &wifi_central_chnl); + + if (type == BTC_MEDIA_CONNECT && wifi_central_chnl <= 14) { + h2c_parameter[0] = 0x0; + h2c_parameter[1] = wifi_central_chnl; + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + } + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x66 = 0x%x\n", + h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | + h2c_parameter[2]); + + btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_btc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool bt_hs_on = false; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + bool bt_ctrl_agg_buf_size = false, under_4way = false; + u8 agg_buf_size = 5; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + + if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || + type == BTC_PACKET_ARP) { + if (type == BTC_PACKET_ARP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], special Packet ARP notify\n"); + + coex_dm->arp_cnt++; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ARP Packet Count = %d\n", + coex_dm->arp_cnt); + + if ((coex_dm->arp_cnt >= 10) && (!under_4way)) + /* if APR PKT > 10 after connect, do not go to + * ActionWifiConnectedSpecificPacket(btcoexist) + */ + coex_sta->wifi_is_high_pri_task = false; + else + coex_sta->wifi_is_high_pri_task = true; + } else { + coex_sta->wifi_is_high_pri_task = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], special Packet DHCP or EAPOL notify\n"); + } + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], special Packet [Type = %d] notify\n", + type); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if (num_of_wifi_link >= 2) { + halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + halbtc8723b1ant_action_wifi_multiport(btcoexist); + return; + } + + coex_sta->special_pkt_period_cnt = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + if (coex_sta->c2h_bt_inquiry_page) { + halbtc8723b1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + halbtc8723b1ant_action_hs(btcoexist); + return; + } + + if (BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], special Packet(%d) notify\n", type); + halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); + } +} + +void ex_btc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmp_buf, u8 length) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 bt_info = 0; + u8 i, rsp_source = 0; + bool wifi_connected = false; + bool bt_busy = false; + + coex_sta->c2h_bt_info_req_sent = false; + + rsp_source = tmp_buf[0] & 0xf; + if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX) + rsp_source = BT_INFO_SRC_8723B_1ANT_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Bt info[%d], length=%d, hex data = [", + rsp_source, length); + for (i = 0; i < length; i++) { + coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; + if (i == 1) + bt_info = tmp_buf[i]; + if (i == length - 1) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x]\n", tmp_buf[i]); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x, ", tmp_buf[i]); + } + + /* if 0xff, it means BT is under WHCK test */ + if (bt_info == 0xff) + coex_sta->bt_whck_test = true; + else + coex_sta->bt_whck_test = false; + + if (rsp_source != BT_INFO_SRC_8723B_1ANT_WIFI_FW) { + coex_sta->bt_retry_cnt = /* [3:0] */ + coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + + if (coex_sta->bt_retry_cnt >= 1) + coex_sta->pop_event_cnt++; + + if (coex_sta->bt_info_c2h[rsp_source][2] & 0x20) + coex_sta->c2h_bt_remote_name_req = true; + else + coex_sta->c2h_bt_remote_name_req = false; + + coex_sta->bt_rssi = + coex_sta->bt_info_c2h[rsp_source][3] * 2 - 90; + + coex_sta->bt_info_ext = + coex_sta->bt_info_c2h[rsp_source][4]; + + if (coex_sta->bt_info_c2h[rsp_source][1] == 0x49) { + coex_sta->a2dp_bit_pool = + coex_sta->bt_info_c2h[rsp_source][6]; + } else { + coex_sta->a2dp_bit_pool = 0; + } + + coex_sta->bt_tx_rx_mask = + (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, + &coex_sta->bt_tx_rx_mask); + + if (!coex_sta->bt_tx_rx_mask) { + /* BT into is responded by BT FW and BT RF REG + * 0x3C != 0x15 => Need to switch BT TRx Mask + */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n"); + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x3c, 0x15); + + /* BT TRx Mask lock 0x2c[0], 0x30[0] = 0 */ + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x2c, 0x7c44); + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x30, 0x7c44); + } + + /* Here we need to resend some wifi info to BT + * because bt is reset and loss of the info. + */ + if (coex_sta->bt_info_ext & BIT1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + if (wifi_connected) + ex_btc8723b1ant_media_status_notify(btcoexist, + BTC_MEDIA_CONNECT); + else + ex_btc8723b1ant_media_status_notify(btcoexist, + BTC_MEDIA_DISCONNECT); + } + + if (coex_sta->bt_info_ext & BIT3) { + if (!btcoexist->manual_control && + !btcoexist->stop_coex_dm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit3 check, set BT NOT ignore Wlan active!!\n"); + halbtc8723b1ant_ignore_wlan_act(btcoexist, + FORCE_EXEC, + false); + } + } else { + /* BT already NOT ignore Wlan active, do nothing here.*/ + } + if (!btcoexist->auto_report_1ant) { + if (coex_sta->bt_info_ext & BIT4) { + /* BT auto report already enabled, do nothing */ + } else { + halbtc8723b1ant_bt_auto_report(btcoexist, + FORCE_EXEC, + true); + } + } + } + + /* check BIT2 first ==> check if bt is under inquiry or page scan */ + if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) + coex_sta->c2h_bt_inquiry_page = true; + else + coex_sta->c2h_bt_inquiry_page = false; + + coex_sta->num_of_profile = 0; + + /* set link exist status */ + if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { + coex_sta->bt_link_exist = false; + coex_sta->pan_exist = false; + coex_sta->a2dp_exist = false; + coex_sta->hid_exist = false; + coex_sta->sco_exist = false; + + coex_sta->bt_hi_pri_link_exist = false; + } else { + /* connection exists */ + coex_sta->bt_link_exist = true; + if (bt_info & BT_INFO_8723B_1ANT_B_FTP) { + coex_sta->pan_exist = true; + coex_sta->num_of_profile++; + } else { + coex_sta->pan_exist = false; + } + if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) { + coex_sta->a2dp_exist = true; + coex_sta->num_of_profile++; + } else { + coex_sta->a2dp_exist = false; + } + if (bt_info & BT_INFO_8723B_1ANT_B_HID) { + coex_sta->hid_exist = true; + coex_sta->num_of_profile++; + } else { + coex_sta->hid_exist = false; + } + if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) { + coex_sta->sco_exist = true; + coex_sta->num_of_profile++; + } else { + coex_sta->sco_exist = false; + } + + if ((!coex_sta->hid_exist) && + (!coex_sta->c2h_bt_inquiry_page) && + (!coex_sta->sco_exist)) { + if (coex_sta->high_priority_tx + + coex_sta->high_priority_rx >= + 160) { + coex_sta->hid_exist = true; + coex_sta->wrong_profile_notification++; + coex_sta->num_of_profile++; + bt_info = bt_info | 0x28; + } + } + + /* Add Hi-Pri Tx/Rx counter to avoid false detection */ + if (((coex_sta->hid_exist) || (coex_sta->sco_exist)) && + (coex_sta->high_priority_tx + coex_sta->high_priority_rx >= + 160) && + (!coex_sta->c2h_bt_inquiry_page)) + coex_sta->bt_hi_pri_link_exist = true; + + if ((bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) && + (coex_sta->num_of_profile == 0)) { + if (coex_sta->low_priority_tx + + coex_sta->low_priority_rx >= + 160) { + coex_sta->pan_exist = true; + coex_sta->num_of_profile++; + coex_sta->wrong_profile_notification++; + bt_info = bt_info | 0x88; + } + } + } + + halbtc8723b1ant_update_bt_link_info(btcoexist); + + /* mask profile bit for connect-ilde identification + * ( for CSR case: A2DP idle --> 0x41) + */ + bt_info = bt_info & 0x1f; + + if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n"); + /* connection exists but no busy */ + } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) { + coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); + } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); + } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) { + if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) + coex_dm->auto_tdma_adjust = false; + + coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_MAX; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n"); + } + + if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || + (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || + (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) + bt_busy = true; + else + bt_busy = false; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + halbtc8723b1ant_run_coexist_mechanism(btcoexist); +} + +void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u32 u32tmp; + u8 u8tmpa, u8tmpb, u8tmpc; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RF Status notify\n"); + + if (type == BTC_RF_ON) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RF is turned ON!!\n"); + btcoexist->stop_coex_dm = false; + } else if (type == BTC_RF_OFF) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RF is turned OFF!!\n"); + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + FORCE_EXEC, false, true); + + halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + btcoexist->stop_coex_dm = true; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); + u8tmpc = btcoexist->btc_read_1byte(btcoexist, 0x76e); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", + u32tmp, u8tmpa, u8tmpb, u8tmpc); + } +} + +void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n"); + + btcoexist->stop_coex_dm = true; + + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, FORCE_EXEC, + false, true); + + halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); + + ex_btc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); + + btcoexist->stop_coex_dm = true; +} + +void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n"); + + if (BTC_WIFI_PNP_SLEEP == pnp_state) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to SLEEP\n"); + halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + FORCE_EXEC, false, true); + halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + + /* Driver do not leave IPS/LPS when driver is going to sleep, so + * BTCoexistence think wifi is still under IPS/LPS + * + * BT should clear UnderIPS/UnderLPS state to avoid mismatch + * state after wakeup. + */ + coex_sta->under_ips = false; + coex_sta->under_lps = false; + btcoexist->stop_coex_dm = true; + } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to WAKE UP\n"); + btcoexist->stop_coex_dm = false; + halbtc8723b1ant_init_hw_config(btcoexist, false, false); + halbtc8723b1ant_init_coex_dm(btcoexist); + halbtc8723b1ant_query_bt_info(btcoexist); + } +} + +void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ==========================Periodical===========================\n"); + + if (!btcoexist->auto_report_1ant) { + halbtc8723b1ant_query_bt_info(btcoexist); + halbtc8723b1ant_monitor_bt_enable_disable(btcoexist); + } else { + halbtc8723b1ant_monitor_bt_ctr(btcoexist); + halbtc8723b1ant_monitor_wifi_ctr(btcoexist); + + if ((coex_sta->high_priority_tx + coex_sta->high_priority_rx < 50) && + bt_link_info->hid_exist) + bt_link_info->hid_exist = false; + + if (btc8723b1ant_is_wifi_status_changed(btcoexist) || + coex_dm->auto_tdma_adjust) { + halbtc8723b1ant_run_coexist_mechanism(btcoexist); + } + coex_sta->special_pkt_period_cnt++; + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h new file mode 100644 index 000000000..a4506d838 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2012 Realtek Corporation.*/ + +/********************************************************************** + * The following is for 8723B 1ANT BT Co-exist definition + **********************************************************************/ +#define BT_INFO_8723B_1ANT_B_FTP BIT7 +#define BT_INFO_8723B_1ANT_B_A2DP BIT6 +#define BT_INFO_8723B_1ANT_B_HID BIT5 +#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723B_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0)) ? true : false) + +#define BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT 2 + +#define BT_8723B_1ANT_WIFI_NOISY_THRESH 50 + +enum _BT_INFO_SRC_8723B_1ANT { + BT_INFO_SRC_8723B_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8723B_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723B_1ANT_MAX +}; + +enum _BT_8723B_1ANT_BT_STATUS { + BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8723B_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8723B_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_1ANT_BT_STATUS_MAX +}; + +enum _BT_8723B_1ANT_WIFI_STATUS { + BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8723B_1ANT_WIFI_STATUS_MAX +}; + +enum _BT_8723B_1ANT_COEX_ALGO { + BT_8723B_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723B_1ANT_COEX_ALGO_SCO = 0x1, + BT_8723B_1ANT_COEX_ALGO_HID = 0x2, + BT_8723B_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8723B_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8723B_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8723B_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8723B_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8723B_1ANT_COEX_ALGO_MAX = 0xb, +}; + +struct coex_dm_8723b_1ant { + /* hw setting */ + u8 pre_ant_pos_type; + u8 cur_ant_pos_type; + /* fw mechanism */ + bool cur_ignore_wlan_act; + bool pre_ignore_wlan_act; + u8 pre_ps_tdma; + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + u8 ps_tdma_du_adj_type; + bool auto_tdma_adjust; + bool pre_ps_tdma_on; + bool cur_ps_tdma_on; + bool pre_bt_auto_report; + bool cur_bt_auto_report; + u8 pre_lps; + u8 cur_lps; + u8 pre_rpwm; + u8 cur_rpwm; + + /* sw mechanism */ + bool pre_low_penalty_ra; + bool cur_low_penalty_ra; + u32 pre_val0x6c0; + u32 cur_val0x6c0; + u32 pre_val0x6c4; + u32 cur_val0x6c4; + u32 pre_val0x6c8; + u32 cur_val0x6c8; + u8 pre_val0x6cc; + u8 cur_val0x6cc; + bool limited_dig; + + u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */ + u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */ + u16 backup_retry_limit; + u8 backup_ampdu_max_time; + + /* algorithm related */ + u8 pre_algorithm; + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + + u32 prera_mask; + u32 curra_mask; + u8 pre_arfr_type; + u8 cur_arfr_type; + u8 pre_retry_limit_type; + u8 cur_retry_limit_type; + u8 pre_ampdu_time_type; + u8 cur_ampdu_time_type; + u32 arp_cnt; + + u8 error_condition; +}; + +struct coex_sta_8723b_1ant { + bool bt_disabled; + bool bt_link_exist; + bool sco_exist; + bool a2dp_exist; + bool hid_exist; + bool pan_exist; + bool bt_hi_pri_link_exist; + u8 num_of_profile; + bool bt_abnormal_scan; + + bool under_lps; + bool under_ips; + u32 special_pkt_period_cnt; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 bt_rssi; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + bool bt_tx_rx_mask; + bool c2h_bt_info_req_sent; + u8 bt_info_c2h[BT_INFO_SRC_8723B_1ANT_MAX][10]; + u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_1ANT_MAX]; + bool bt_whck_test; + bool c2h_bt_inquiry_page; + bool c2h_bt_remote_name_req; + bool wifi_is_high_pri_task; + u8 bt_retry_cnt; + u8 bt_info_ext; + u8 scan_ap_num; + bool cck_ever_lock; + u8 coex_table_type; + bool force_lps_on; + u32 pop_event_cnt; + + u32 crc_ok_cck; + u32 crc_ok_11g; + u32 crc_ok_11n; + u32 crc_ok_11n_agg; + + u32 crc_err_cck; + u32 crc_err_11g; + u32 crc_err_11n; + u32 crc_err_11n_agg; + + bool cck_lock; + bool pre_ccklock; + + u32 wrong_profile_notification; + + u8 a2dp_bit_pool; + u8 cut_version; +}; + +/************************************************************************* + * The following is interface which will notify coex module. + *************************************************************************/ +void ex_btc8723b1ant_power_on_setting(struct btc_coexist *btcoexist); +void ex_btc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist, + bool wifi_only); +void ex_btc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_btc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmpbuf, u8 length); +void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist); +void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate); +void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist); +void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m); +void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c new file mode 100644 index 000000000..7a71f0630 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c @@ -0,0 +1,4240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2012 Realtek Corporation.*/ + +/*************************************************************** + * Description: + * + * This file is for RTL8723B Co-exist mechanism + * + * History + * 2012/11/15 Cosa first check in. + * + **************************************************************/ +/************************************************************** + * include files + **************************************************************/ +#include "halbt_precomp.h" +/************************************************************** + * Global variables, these are static variables + **************************************************************/ +static struct coex_dm_8723b_2ant glcoex_dm_8723b_2ant; +static struct coex_dm_8723b_2ant *coex_dm = &glcoex_dm_8723b_2ant; +static struct coex_sta_8723b_2ant glcoex_sta_8723b_2ant; +static struct coex_sta_8723b_2ant *coex_sta = &glcoex_sta_8723b_2ant; + +static const char *const glbt_info_src_8723b_2ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8723b_2ant = 20131113; +static u32 glcoex_ver_8723b_2ant = 0x3f; + +/************************************************************** + * local function proto type if needed + **************************************************************/ +/************************************************************** + * local function start with btc8723b2ant_ + **************************************************************/ +static u8 btc8723b2ant_bt_rssi_state(struct btc_coexist *btcoexist, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + s32 bt_rssi = 0; + u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + + bt_rssi = coex_sta->bt_rssi; + + if (level_num == 2) { + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else { + if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi thresh error!!\n"); + return coex_sta->pre_bt_rssi_state; + } + + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else if ((coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (bt_rssi >= rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Medium\n"); + } + } else { + if (bt_rssi < rssi_thresh1) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } + + coex_sta->pre_bt_rssi_state = bt_rssi_state; + + return bt_rssi_state; +} + +static u8 btc8723b2ant_wifi_rssi_state(struct btc_coexist *btcoexist, + u8 index, u8 level_num, + u8 rssi_thresh, u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + s32 wifi_rssi = 0; + u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + + if (level_num == 2) { + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else { + if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI thresh error!!\n"); + return coex_sta->pre_wifi_rssi_state[index]; + } + + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (wifi_rssi >= rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Medium\n"); + } + } else { + if (wifi_rssi < rssi_thresh1) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } + + coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + + return wifi_rssi_state; +} + +static +void btc8723b2ant_limited_rx(struct btc_coexist *btcoexist, bool force_exec, + bool rej_ap_agg_pkt, bool bt_ctrl_agg_buf_size, + u8 agg_buf_size) +{ + bool reject_rx_agg = rej_ap_agg_pkt; + bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rx_agg_size = agg_buf_size; + + /* ============================================ */ + /* Rx Aggregation related setting */ + /* ============================================ */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, + &reject_rx_agg); + /* decide BT control aggregation buf size or not */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, + &bt_ctrl_rx_agg_size); + /* aggregate buf size, only work when BT control Rx aggregate size */ + btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); + /* real update aggregation setting */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u32 reg_hp_txrx, reg_lp_txrx, u32tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0; + u32 reg_lp_tx = 0, reg_lp_rx = 0; + + reg_hp_txrx = 0x770; + reg_lp_txrx = 0x774; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); + reg_hp_tx = u32tmp & MASKLWORD; + reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); + reg_lp_tx = u32tmp & MASKLWORD; + reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + if ((coex_sta->low_priority_tx > 1050) && + (!coex_sta->c2h_bt_inquiry_page)) + coex_sta->pop_event_cnt++; + + if ((coex_sta->low_priority_rx >= 950) && + (coex_sta->low_priority_rx >= coex_sta->low_priority_tx) && + (!coex_sta->under_ips)) + bt_link_info->slave_role = true; + else + bt_link_info->slave_role = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], High Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Low Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + + /* reset counter */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static void btc8723b2ant_monitor_wifi_ctr(struct btc_coexist *btcoexist) +{ + if (coex_sta->under_ips) { + coex_sta->crc_ok_cck = 0; + coex_sta->crc_ok_11g = 0; + coex_sta->crc_ok_11n = 0; + coex_sta->crc_ok_11n_agg = 0; + + coex_sta->crc_err_cck = 0; + coex_sta->crc_err_11g = 0; + coex_sta->crc_err_11n = 0; + coex_sta->crc_err_11n_agg = 0; + } else { + coex_sta->crc_ok_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf88); + coex_sta->crc_ok_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf94); + coex_sta->crc_ok_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf90); + coex_sta->crc_ok_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfb8); + + coex_sta->crc_err_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf84); + coex_sta->crc_err_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf96); + coex_sta->crc_err_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf92); + coex_sta->crc_err_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfba); + } + + /* reset counter */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0); +} + +static void btc8723b2ant_query_bt_info(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + h2c_parameter[0] |= BIT0; /* trigger */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + +static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ + static bool pre_wifi_busy; + static bool pre_under_4way; + static bool pre_bt_hs_on; + bool wifi_busy = false, under_4way = false, bt_hs_on = false; + bool wifi_connected = false; + u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH; + u8 tmp; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (wifi_connected) { + if (wifi_busy != pre_wifi_busy) { + pre_wifi_busy = wifi_busy; + return true; + } + + if (under_4way != pre_under_4way) { + pre_under_4way = under_4way; + return true; + } + + if (bt_hs_on != pre_bt_hs_on) { + pre_bt_hs_on = bt_hs_on; + return true; + } + + tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + wifi_rssi_state = + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, tmp, 0); + + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_LOW)) + return true; + } + + return false; +} + +static void btc8723b2ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + + /* work around for HS mode. */ + if (bt_hs_on) { + bt_link_info->pan_exist = true; + bt_link_info->bt_link_exist = true; + } + + /* check if Sco only */ + if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->sco_only = true; + else + bt_link_info->sco_only = false; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->a2dp_only = true; + else + bt_link_info->a2dp_only = false; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->pan_only = true; + else + bt_link_info->pan_only = false; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && bt_link_info->hid_exist) + bt_link_info->hid_only = true; + else + bt_link_info->hid_only = false; +} + +static u8 btc8723b2ant_action_algorithm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + u8 algorithm = BT_8723B_2ANT_COEX_ALGO_UNDEFINED; + u8 num_of_diff_profile = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + if (!bt_link_info->bt_link_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], No BT link exists!!!\n"); + return algorithm; + } + + if (bt_link_info->sco_exist) + num_of_diff_profile++; + if (bt_link_info->hid_exist) + num_of_diff_profile++; + if (bt_link_info->pan_exist) + num_of_diff_profile++; + if (bt_link_info->a2dp_exist) + num_of_diff_profile++; + + if (num_of_diff_profile == 1) { + if (bt_link_info->sco_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO only\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; + } else { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], HID only\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], A2DP only\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], PAN(HS) only\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], PAN(EDR) only\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR; + } + } + } + } else if (num_of_diff_profile == 2) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + HID\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + A2DP ==> SCO\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + PAN(HS)\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + PAN(EDR)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], HID + A2DP\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + PAN(HS)\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + PAN(EDR)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], A2DP + PAN(HS)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex],A2DP + PAN(EDR)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } else if (num_of_diff_profile == 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + HID + A2DP ==> HID\n"); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + PAN(HS)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + PAN(EDR)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + A2DP + PAN(HS)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + A2DP + PAN(HS)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + A2DP + PAN(EDR)\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } else if (num_of_diff_profile >= 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); + algorithm = + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + return algorithm; +} + +static void btc8723b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist, + u8 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + /* There are several type of dacswing + * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + */ + h2c_parameter[0] = dac_swing_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); +} + +static void btc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, + u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = dec_bt_pwr_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], decrease Bt Power Level : %u\n", dec_bt_pwr_lvl); + + btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); +} + +static void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist, + bool force_exec, u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Dec BT power level = %u\n", dec_bt_pwr_lvl); + coex_dm->cur_dec_bt_pwr_lvl = dec_bt_pwr_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PreDecBtPwrLvl=%d, CurDecBtPwrLvl=%d\n", + coex_dm->pre_dec_bt_pwr_lvl, + coex_dm->cur_dec_bt_pwr_lvl); + + if (coex_dm->pre_dec_bt_pwr_lvl == coex_dm->cur_dec_bt_pwr_lvl) + return; + } + btc8723b2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr_lvl); + + coex_dm->pre_dec_bt_pwr_lvl = coex_dm->cur_dec_bt_pwr_lvl; +} + +static +void halbtc8723b2ant_set_bt_auto_report(struct btc_coexist *btcoexist, + bool enable_auto_report) +{ + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = 0; + + if (enable_auto_report) + h2c_parameter[0] |= BIT(0); + + btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); +} + +static +void btc8723b2ant_bt_auto_report(struct btc_coexist *btcoexist, + bool force_exec, bool enable_auto_report) +{ + coex_dm->cur_bt_auto_report = enable_auto_report; + + if (!force_exec) { + if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) + return; + } + halbtc8723b2ant_set_bt_auto_report(btcoexist, + coex_dm->cur_bt_auto_report); + + coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; +} + +static void btc8723b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, + bool force_exec, u8 fw_dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s set FW Dac Swing level = %d\n", + (force_exec ? "force to" : ""), fw_dac_swing_lvl); + coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n", + coex_dm->pre_fw_dac_swing_lvl, + coex_dm->cur_fw_dac_swing_lvl); + + if (coex_dm->pre_fw_dac_swing_lvl == + coex_dm->cur_fw_dac_swing_lvl) + return; + } + + btc8723b2ant_set_fw_dac_swing_level(btcoexist, + coex_dm->cur_fw_dac_swing_lvl); + coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; +} + +static void btc8723b_set_penalty_txrate(struct btc_coexist *btcoexist, + bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[6] = {0}; + + h2c_parameter[0] = 0x6; /* op_code, 0x6 = Retry_Penalty */ + + if (low_penalty_ra) { + h2c_parameter[1] |= BIT0; + /* normal rate except MCS7/6/5, OFDM54/48/36 */ + h2c_parameter[2] = 0x00; + h2c_parameter[3] = 0xf4; /* MCS7 or OFDM54 */ + h2c_parameter[4] = 0xf5; /* MCS6 or OFDM48 */ + h2c_parameter[5] = 0xf6; /* MCS5 or OFDM36 */ + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set WiFi Low-Penalty Retry: %s", + (low_penalty_ra ? "ON!!" : "OFF!!")); + + btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void btc8723b2ant_low_penalty_ra(struct btc_coexist *btcoexist, + bool force_exec, bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn LowPenaltyRA = %s\n", + (force_exec ? "force to" : ""), (low_penalty_ra ? + "ON" : "OFF")); + coex_dm->cur_low_penalty_ra = low_penalty_ra; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n", + coex_dm->pre_low_penalty_ra, + coex_dm->cur_low_penalty_ra); + + if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) + return; + } + btc8723b_set_penalty_txrate(btcoexist, coex_dm->cur_low_penalty_ra); + + coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void btc8723b2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, + u32 level) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 val = (u8) level; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Write SwDacSwing = 0x%x\n", level); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val); +} + +static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex, + bool sw_dac_swing_on, + u32 sw_dac_swing_lvl) +{ + if (sw_dac_swing_on) + btc8723b2ant_set_dac_swing_reg(btcoex, sw_dac_swing_lvl); + else + btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); +} + +static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, + bool force_exec, bool dac_swing_on, + u32 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn DacSwing=%s, dac_swing_lvl=0x%x\n", + (force_exec ? "force to" : ""), + (dac_swing_on ? "ON" : "OFF"), dac_swing_lvl); + coex_dm->cur_dac_swing_on = dac_swing_on; + coex_dm->cur_dac_swing_lvl = dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n", + coex_dm->pre_dac_swing_on, + coex_dm->pre_dac_swing_lvl, + coex_dm->cur_dac_swing_on, + coex_dm->cur_dac_swing_lvl); + + if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && + (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl)) + return; + } + mdelay(30); + btc8723b2ant_set_sw_fulltime_dac_swing(btcoexist, dac_swing_on, + dac_swing_lvl); + + coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; + coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; +} + +static void btc8723b2ant_set_coex_table(struct btc_coexist *btcoexist, + u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0); + btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4); + btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8); + btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc); + btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8723b2ant_coex_table(struct btc_coexist *btcoexist, + bool force_exec, u32 val0x6c0, + u32 val0x6c4, u32 val0x6c8, + u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + force_exec ? "force to" : "", + val0x6c0, val0x6c4, val0x6c8, val0x6cc); + coex_dm->cur_val0x6c0 = val0x6c0; + coex_dm->cur_val0x6c4 = val0x6c4; + coex_dm->cur_val0x6c8 = val0x6c8; + coex_dm->cur_val0x6cc = val0x6cc; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], preVal0x6c0=0x%x, preVal0x6c4=0x%x, preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n", + coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4, + coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x, curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n", + coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4, + coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc); + + if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && + (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && + (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && + (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) + return; + } + btc8723b2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, + val0x6c8, val0x6cc); + + coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; + coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; + coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; + coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void btc8723b2ant_coex_table_with_type(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + switch (type) { + case 0: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x55555555, 0xffffff, 0x3); + break; + case 1: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5afa5afa, 0xffffff, 0x3); + break; + case 2: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x5ada5ada, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 3: + btc8723b2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + btc8723b2ant_coex_table(btcoexist, force_exec, 0xffffffff, + 0xffffffff, 0xffffff, 0x3); + break; + case 5: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0x5fff5fff, 0xffffff, 0x3); + break; + case 6: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 8: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + btc8723b2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, + bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + if (enable) + h2c_parameter[0] |= BIT0; /* function enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void btc8723b2ant_set_lps_rpwm(struct btc_coexist *btcoexist, + u8 lps_val, u8 rpwm_val) +{ + u8 lps = lps_val; + u8 rpwm = rpwm_val; + + btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); + btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); +} + +static void btc8723b2ant_lps_rpwm(struct btc_coexist *btcoexist, + bool force_exec, u8 lps_val, u8 rpwm_val) +{ + coex_dm->cur_lps = lps_val; + coex_dm->cur_rpwm = rpwm_val; + + if (!force_exec) { + if ((coex_dm->pre_lps == coex_dm->cur_lps) && + (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) + return; + } + btc8723b2ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); + + coex_dm->pre_lps = coex_dm->cur_lps; + coex_dm->pre_rpwm = coex_dm->cur_rpwm; +} + +static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist, + bool force_exec, bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Ignore WlanAct %s\n", + (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); + coex_dm->cur_ignore_wlan_act = enable; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n", + coex_dm->pre_ignore_wlan_act, + coex_dm->cur_ignore_wlan_act); + + if (coex_dm->pre_ignore_wlan_act == + coex_dm->cur_ignore_wlan_act) + return; + } + btc8723b2ant_set_fw_ignore_wlan_act(btcoexist, enable); + + coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1, + u8 byte2, u8 byte3, u8 byte4, u8 byte5) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[5]; + if ((coex_sta->a2dp_exist) && (coex_sta->hid_exist)) + byte5 = byte5 | 0x1; + + h2c_parameter[0] = byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = byte5; + + coex_dm->ps_tdma_para[0] = byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = byte5; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", + h2c_parameter[0], + h2c_parameter[1] << 24 | h2c_parameter[2] << 16 | + h2c_parameter[3] << 8 | h2c_parameter[4]); + + btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8723b2ant_sw_mechanism(struct btc_coexist *btcoexist, + bool shrink_rx_lpf, bool low_penalty_ra, + bool limited_dig, bool bt_lna_constrain) +{ + btc8723b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist, + u8 antpos_type, bool init_hwcfg, + bool wifi_off) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u32 fw_ver = 0, u32tmp = 0; + bool pg_ext_switch = false; + bool use_ext_switch = false; + u8 h2c_parameter[2] = {0}; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + + if ((fw_ver < 0xc0000) || pg_ext_switch) + use_ext_switch = true; + + if (init_hwcfg) { + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x39, 0x8, 0x1); + btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); + btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); + + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to High to avoid A2DP click */ + h2c_parameter[0] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, + h2c_parameter); + } else { + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + } + + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); + + /* WiFi TRx Mask off */ + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, + 0x1, 0xfffff, 0x0); + + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { + /* tell firmware "no antenna inverse" */ + h2c_parameter[0] = 0; + } else { + /* tell firmware "antenna inverse" */ + h2c_parameter[0] = 1; + } + + if (use_ext_switch) { + /* ext switch type */ + h2c_parameter[1] = 1; + } else { + /* int switch type */ + h2c_parameter[1] = 0; + } + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, h2c_parameter); + } else { + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to "Control by PTA"*/ + h2c_parameter[0] = 0; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, + h2c_parameter); + } else { + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x0); + } + } + + /* ext switch setting */ + if (use_ext_switch) { + if (init_hwcfg) { + /* 0x4c[23] = 0, 0x4c[24] = 1 Ant controlled by WL/BT */ + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u32tmp &= ~BIT23; + u32tmp |= BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + } + + /* fixed internal switch S1->WiFi, S0->BT */ + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); + else + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); + + switch (antpos_type) { + case BTC_ANT_WIFI_AT_MAIN: + /* ext switch main at wifi */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, + 0x3, 0x1); + break; + case BTC_ANT_WIFI_AT_AUX: + /* ext switch aux at wifi */ + btcoexist->btc_write_1byte_bitmask(btcoexist, + 0x92c, 0x3, 0x2); + break; + } + } else { + /* internal switch */ + if (init_hwcfg) { + /* 0x4c[23] = 0, 0x4c[24] = 1 Ant controlled by WL/BT */ + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u32tmp |= BIT23; + u32tmp &= ~BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + } + + /* fixed ext switch, S1->Main, S0->Aux */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x0); + switch (antpos_type) { + case BTC_ANT_WIFI_AT_MAIN: + /* fixed internal switch S1->WiFi, S0->BT */ + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); + break; + case BTC_ANT_WIFI_AT_AUX: + /* fixed internal switch S0->WiFi, S1->BT */ + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); + break; + } + } +} + +static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, + bool turn_on, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u8 wifi_rssi_state, bt_rssi_state; + s8 wifi_duration_adjust = 0x0; + u8 tdma_byte4_modify = 0x0; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn %s PS TDMA, type=%d\n", + (force_exec ? "force to" : ""), + (turn_on ? "ON" : "OFF"), type); + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + if (!(BTC_RSSI_HIGH(wifi_rssi_state) && + BTC_RSSI_HIGH(bt_rssi_state)) && turn_on) { + /* for WiFi RSSI low or BT RSSI low */ + type = type + 100; + coex_dm->is_switch_to_1dot5_ant = true; + } else { + coex_dm->is_switch_to_1dot5_ant = false; + } + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", + coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", + coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); + + if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && + (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) + return; + } + + if (coex_sta->scan_ap_num <= 5) { + if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + else if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else + wifi_duration_adjust = 5; + } else if (coex_sta->scan_ap_num <= 20) { + if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + else if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else + wifi_duration_adjust = 0; + } else if (coex_sta->scan_ap_num <= 40) { + if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + else if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else + wifi_duration_adjust = -5; + } else { + if (coex_sta->a2dp_bit_pool >= 45) + wifi_duration_adjust = -15; + else if (coex_sta->a2dp_bit_pool >= 35) + wifi_duration_adjust = -10; + else + wifi_duration_adjust = -10; + } + + if ((bt_link_info->slave_role) && (bt_link_info->a2dp_exist)) + /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */ + tdma_byte4_modify = 0x1; + + if (turn_on) { + switch (type) { + case 1: + default: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, 0x90 | tdma_byte4_modify); + break; + case 2: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x2d, + 0x03, 0xf1, 0x90 | tdma_byte4_modify); + break; + case 3: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, + 0x90 | tdma_byte4_modify); + break; + case 4: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x03, 0xf1, + 0x90 | tdma_byte4_modify); + break; + case 5: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x3c, + 0x3, 0x70, 0x90 | tdma_byte4_modify); + break; + case 6: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x2d, + 0x3, 0x70, 0x90 | tdma_byte4_modify); + break; + case 7: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0x70, + 0x90 | tdma_byte4_modify); + break; + case 8: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10, + 0x3, 0x70, + 0x90 | tdma_byte4_modify); + break; + case 9: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x3c + wifi_duration_adjust, + 0x03, 0xf1, 0x90 | tdma_byte4_modify); + break; + case 10: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x2d, + 0x03, 0xf1, 0x90 | tdma_byte4_modify); + break; + case 11: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, + 0x90 | tdma_byte4_modify); + break; + case 12: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0xf1, + 0x90 | tdma_byte4_modify); + break; + case 13: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x3c, + 0x3, 0x70, 0x90 | tdma_byte4_modify); + break; + case 14: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x2d, + 0x3, 0x70, 0x90 | tdma_byte4_modify); + break; + case 15: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0x70, + 0x90 | tdma_byte4_modify); + break; + case 16: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0x70, + 0x90 | tdma_byte4_modify); + break; + case 17: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f, + 0x2f, 0x60, 0x90); + break; + case 18: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, 0x5, + 0xe1, 0x90); + break; + case 19: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0xe1, 0x90); + break; + case 20: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0x60, 0x90); + break; + case 21: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x03, 0x70, 0x90); + break; + + case 23: + case 123: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x35, + 0x03, 0x71, 0x10); + break; + case 71: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xe3, 0x3c + wifi_duration_adjust, + 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 113: + case 171: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xd3, 0x3a + wifi_duration_adjust, + 0x03, 0x70, 0x50 | tdma_byte4_modify); + break; + case 102: + case 106: + case 110: + case 114: + btc8723b2ant_set_fw_ps_tdma( + btcoexist, 0xd3, 0x2d + wifi_duration_adjust, + 0x03, 0x70, 0x50 | tdma_byte4_modify); + break; + case 103: + case 107: + case 111: + case 115: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1c, + 0x03, 0x70, + 0x50 | tdma_byte4_modify); + break; + case 104: + case 108: + case 112: + case 116: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x10, + 0x03, 0x70, + 0x50 | tdma_byte4_modify); + break; + case 109: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, + 0x90 | tdma_byte4_modify); + break; + case 121: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x03, 0x70, + 0x90 | tdma_byte4_modify); + break; + case 22: + case 122: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x35, + 0x03, 0x71, 0x11); + break; + } + } else { + /* disable PS tdma */ + switch (type) { + case 0: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x40, 0x0); + break; + case 1: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x48, 0x0); + break; + default: + btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x40, 0x0); + break; + } + } + + /* update pre state */ + coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; + coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static void btc8723b2ant_ps_tdma_check_for_power_save_state( + struct btc_coexist *btcoexist, bool new_ps_state) +{ + u8 lps_mode = 0x0; + + btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); + + if (lps_mode) { + /* already under LPS state */ + if (new_ps_state) { + /* keep state under LPS, do nothing. */ + } else { + /* will leave LPS state, turn off psTdma first */ + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } + } else { + /* NO PS state */ + if (new_ps_state) { + /* will enter LPS state, turn off psTdma first */ + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } else { + /* keep state under NO PS state, do nothing. */ + } + } +} + +static void btc8723b2ant_power_save_state(struct btc_coexist *btcoexist, + u8 ps_type, u8 lps_val, u8 rpwm_val) +{ + bool low_pwr_disable = false; + + switch (ps_type) { + case BTC_PS_WIFI_NATIVE: + /* recover to original 32k low power setting */ + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + coex_sta->force_lps_on = false; + break; + case BTC_PS_LPS_ON: + btc8723b2ant_ps_tdma_check_for_power_save_state(btcoexist, + true); + btc8723b2ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, + rpwm_val); + /* when coex force to enter LPS, do not enter 32k low power */ + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + /* power save must executed before psTdma */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); + coex_sta->force_lps_on = true; + break; + case BTC_PS_LPS_OFF: + btc8723b2ant_ps_tdma_check_for_power_save_state(btcoexist, + false); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + coex_sta->force_lps_on = false; + break; + default: + break; + } +} + +static void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist) +{ + /* fw all off */ + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, false); + + /* hw all off */ + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + /* force to reset coex mechanism*/ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + btc8723b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, 0); + + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, false); + + coex_sta->pop_event_cnt = 0; +} + +static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false; + bool low_pwr_disable = true; + bool scan = false, link = false, roam = false; + + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if (coex_sta->bt_abnormal_scan) { + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3); + } else if (scan || link || roam) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi link process + BT Inq/Page!!\n"); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + } else if (wifi_connected) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT Inq/Page!!\n"); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } + btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, false); +} + +static void btc8723b2ant_action_wifi_link_process(struct btc_coexist + *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u32 u32tmp; + u8 u8tmpa, u8tmpb; + + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, false); + + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x76e); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 0x948 = 0x%x, 0x765 = 0x%x, 0x76e = 0x%x\n", + u32tmp, u8tmpa, u8tmpb); +} + +static bool btc8723b2ant_action_wifi_idle_process(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 wifi_rssi_state1; + u8 ap_num = 0; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset - coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset - coex_dm->switch_thres_offset; + btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); + + /* office environment */ + if (BTC_RSSI_HIGH(wifi_rssi_state1) && (coex_sta->hid_exist) && + (coex_sta->a2dp_exist)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi idle process for BT HID+A2DP exist!!\n"); + + btc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, true, 0x6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, + false); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + return true; + } + + btc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, true, 0x18); + return false; +} + +static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool common = false, wifi_connected = false; + bool wifi_busy = false; + bool bt_hs_on = false, low_pwr_disable = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (!wifi_connected) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, + false, false, 0x8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non-connected idle!!\n"); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x0); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, + false); + + common = true; + } else { + if (BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, + false, false, 0x8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT non connected-idle!!\n"); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x0); + btc8723b2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 0xb); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + + common = true; + } else if (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status) { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (bt_hs_on) + return false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT connected-idle!!\n"); + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, + false, false, 0x8); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x0); + btc8723b2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 0xb); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + + common = true; + } else { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (wifi_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Busy + BT Busy!!\n"); + common = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Idle + BT Busy!!\n"); + + common = + btc8723b2ant_action_wifi_idle_process( + btcoexist); + } + } + } + + return common; +} + +static void btc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, + bool sco_hid, bool tx_pause, + u8 max_interval) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static s32 up, dn, m, n, wait_count; + /*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/ + s32 result; + u8 retry_count = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], TdmaDurationAdjust()\n"); + + if (!coex_dm->auto_tdma_adjust) { + coex_dm->auto_tdma_adjust = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], first run TdmaDurationAdjust()!!\n"); + if (sco_hid) { + if (tx_pause) { + if (max_interval == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 13); + coex_dm->ps_tdma_du_adj_type = 13; + } else if (max_interval == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (max_interval == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } + } else { + if (max_interval == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (max_interval == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (max_interval == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } + } + } else { + if (tx_pause) { + if (max_interval == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (max_interval == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (max_interval == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } + } else { + if (max_interval == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = 1; + } else if (max_interval == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (max_interval == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } + } + } + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } else { + /*accquire the BT TRx retry count from BT_Info byte2*/ + retry_count = coex_sta->bt_retry_cnt; + + if ((coex_sta->low_priority_tx) > 1050 || + (coex_sta->low_priority_rx) > 1250) + retry_count++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], retry_count = %d\n", retry_count); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_count=%d\n", + up, dn, m, n, wait_count); + result = 0; + wait_count++; + /* no retry in the last 2-second duration*/ + if (retry_count == 0) { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if (up >= n) { + /* if retry count during continuous n*2 + * seconds is 0, enlarge WiFi duration + */ + wait_count = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Increase wifi duration!!\n"); + } /* <=3 retry in the last 2-second duration*/ + } else if (retry_count <= 3) { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) { + /* if continuous 2 retry count(every 2 + * seconds) >0 and < 3, reduce WiFi duration + */ + if (wait_count <= 2) + /* avoid loop between the two levels */ + m++; + else + m = 1; + + if (m >= 20) + /* maximum of m = 20 ' will recheck if + * need to adjust wifi duration in + * maximum time interval 120 seconds + */ + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retry_counter<3!!\n"); + } + } else { + /* retry count > 3, once retry count > 3, to reduce + * WiFi duration + */ + if (wait_count == 1) + /* to avoid loop between the two levels */ + m++; + else + m = 1; + + if (m >= 20) + /* maximum of m = 20 ' will recheck if need to + * adjust wifi duration in maximum time interval + * 120 seconds + */ + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retry_counter>3!!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], max Interval = %d\n", max_interval); + if (max_interval == 1) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 71) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 13); + coex_dm->ps_tdma_du_adj_type = 13; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 5); + coex_dm->ps_tdma_du_adj_type = + 5; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 13); + coex_dm->ps_tdma_du_adj_type = + 13; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 71); + coex_dm->ps_tdma_du_adj_type = 71; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + + if (result == -1) { + if (coex_dm->cur_ps_tdma == 71) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = + 1; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = + 1; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 71); + coex_dm->ps_tdma_du_adj_type = + 71; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = + 9; + } + } + } + } else if (max_interval == 2) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } + } + } + } else if (max_interval == 3) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8723b2ant_ps_tdma(btcoexist, + NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 1) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8723b2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } + } + } + } + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], max Interval = %d\n", max_interval); + + /* if current PsTdma not match with the recorded one (scan, dhcp, ...), + * then we have to adjust it back to the previous recorded one. + */ + if (coex_dm->cur_ps_tdma != coex_dm->ps_tdma_du_adj_type) { + bool scan = false, link = false, roam = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PsTdma type mismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + coex_dm->cur_ps_tdma, coex_dm->ps_tdma_du_adj_type); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (!scan && !link && !roam) + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + coex_dm->ps_tdma_du_adj_type); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"); + } +} + +/* SCO only or SCO+PAN(HS) */ +static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist) +{ + u8 bt_rssi_state; + u32 wifi_bw; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8723b2ant_bt_rssi_state( + btcoexist, 2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset, + 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (BTC_WIFI_BW_LEGACY == wifi_bw) + /* for SCO quality at 11b/g mode */ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + else + /* for SCO quality & wifi performance balance at 11n mode */ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8); + + /* for voice quality */ + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, true, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, true, + false, false); + } +} + +static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist) +{ + u8 bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (wifi_bw == BTC_WIFI_BW_LEGACY) + /* for HID at 11b/g mode */ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + else + /* for HID quality & wifi performance balance at 11n mode */ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 9); + + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); + else + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + + /* sw mechanism */ + if (wifi_bw == BTC_WIFI_BW_HT40) + btc8723b2ant_sw_mechanism(btcoexist, true, true, false, false); + else + btc8723b2ant_sw_mechanism(btcoexist, false, true, false, false); +} + +/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ +static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 ap_num = 0; + u8 tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, 40, 0); + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); + + /* define the office environment */ + /* driver don't know AP num in Linux, so we will never enter this if */ + if (ap_num >= 10 && BTC_RSSI_HIGH(wifi_rssi_state1)) { + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x0); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } + return; + } + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) + btc8723b2ant_tdma_duration_adjust(btcoexist, false, + false, 1); + else + btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 1); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } +} + +static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 2); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } +} + +static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 10); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); + else + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } +} + +/* PAN(HS) only */ +static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist) +{ + u8 bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } +} + +/* PAN(EDR) + A2DP */ +static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + else + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 12); + if (BTC_WIFI_BW_HT40 == wifi_bw) + btc8723b2ant_tdma_duration_adjust(btcoexist, false, + true, 3); + else + btc8723b2ant_tdma_duration_adjust(btcoexist, false, + false, 3); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, false, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, false, + false, false); + } +} + +static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 14); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 3); + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x780); + } else { + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 6); + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x0); + } + btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2); + } else { + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x0); + btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, true, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, true, + false, false); + } +} + +/* HID + A2DP + PAN(EDR) */ +static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 2, tmp, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 14); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + if (BTC_WIFI_BW_HT40 == wifi_bw) + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + true, 2); + else + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + false, 3); + } else { + btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 3); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, true, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, true, + false, false); + } +} + +static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + u8 ap_num = 0; + u8 tmp = BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + + btc8723b2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, 1, 2, + tmp, 0); + tmp = BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES - + coex_dm->switch_thres_offset; + bt_rssi_state = btc8723b2ant_bt_rssi_state(btcoexist, 3, tmp, 37); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8723b2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true, 0x5); + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else if (BTC_RSSI_MEDIUM(bt_rssi_state)) + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else { + /* only 802.11N mode we have to dec bt power to 4 degree */ + if (BTC_RSSI_HIGH(bt_rssi_state)) { + /* need to check ap Number of Not */ + if (ap_num < 10) + btc8723b2ant_dec_bt_pwr(btcoexist, + NORMAL_EXEC, 4); + else + btc8723b2ant_dec_bt_pwr(btcoexist, + NORMAL_EXEC, 2); + } else if (BTC_RSSI_MEDIUM(bt_rssi_state)) { + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + } else { + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } + } + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 14); + btc8723b2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + if (BTC_RSSI_HIGH(bt_rssi_state)) { + if (ap_num < 10) + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + false, 1); + else + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + false, 3); + } else { + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 18); + btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); + btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); + btcoexist->btc_write_4byte(btcoexist, 0x430, 0x0); + btcoexist->btc_write_4byte(btcoexist, 0x434, 0x01010000); + + if (ap_num < 10) + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + true, 1); + else + btc8723b2ant_tdma_duration_adjust(btcoexist, true, + true, 3); + } + + /* sw mechanism */ + if (BTC_WIFI_BW_HT40 == wifi_bw) { + btc8723b2ant_sw_mechanism(btcoexist, true, true, + false, false); + } else { + btc8723b2ant_sw_mechanism(btcoexist, false, true, + false, false); + } +} + +static void btc8723b2ant_action_wifi_multi_port(struct btc_coexist *btcoexist) +{ + btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8723b2ant_sw_mechanism(btcoexist, false, false, false, false); + + /* hw all off */ + btc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + + btc8723b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +} + +static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 algorithm = 0; + u32 num_of_wifi_link = 0; + u32 wifi_link_status = 0; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool miracast_plus_bt = false; + bool scan = false, link = false, roam = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism()===>\n"); + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); + return; + } + + if (coex_sta->under_ips) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + return; + } + + algorithm = btc8723b2ant_action_algorithm(btcoexist); + if (coex_sta->c2h_bt_inquiry_page && + (BT_8723B_2ANT_COEX_ALGO_PANHS != algorithm)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is under inquiry/page scan !!\n"); + btc8723b2ant_action_bt_inquiry(btcoexist); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (scan || link || roam) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], WiFi is under Link Process !!\n"); + btc8723b2ant_action_wifi_link_process(btcoexist); + return; + } + + /* for P2P */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + + if ((num_of_wifi_link >= 2) || + (wifi_link_status & WIFI_P2P_GO_CONNECTED)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "############# [BTCoex], Multi-Port num_of_wifi_link = %d, wifi_link_status = 0x%x\n", + num_of_wifi_link, wifi_link_status); + + if (bt_link_info->bt_link_exist) + miracast_plus_bt = true; + else + miracast_plus_bt = false; + + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + btc8723b2ant_action_wifi_multi_port(btcoexist); + + return; + } + + miracast_plus_bt = false; + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + + coex_dm->cur_algorithm = algorithm; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Algorithm = %d\n", + coex_dm->cur_algorithm); + + if (btc8723b2ant_is_common_action(btcoexist)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant common\n"); + coex_dm->auto_tdma_adjust = false; + } else { + if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + coex_dm->pre_algorithm, + coex_dm->cur_algorithm); + coex_dm->auto_tdma_adjust = false; + } + switch (coex_dm->cur_algorithm) { + case BT_8723B_2ANT_COEX_ALGO_SCO: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = SCO\n"); + btc8723b2ant_action_sco(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID\n"); + btc8723b2ant_action_hid(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = A2DP\n"); + btc8723b2ant_action_a2dp(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS)\n"); + btc8723b2ant_action_a2dp_pan_hs(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)\n"); + btc8723b2ant_action_pan_edr(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HS mode\n"); + btc8723b2ant_action_pan_hs(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP\n"); + btc8723b2ant_action_pan_edr_a2dp(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID\n"); + btc8723b2ant_action_pan_edr_hid(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN\n"); + btc8723b2ant_action_hid_a2dp_pan_edr(btcoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP\n"); + btc8723b2ant_action_hid_a2dp(btcoexist); + break; + default: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"); + btc8723b2ant_coex_alloff(btcoexist); + break; + } + coex_dm->pre_algorithm = coex_dm->cur_algorithm; + } +} + +static void btc8723b2ant_wifioff_hwcfg(struct btc_coexist *btcoexist) +{ + bool is_in_mp_mode = false; + u8 h2c_parameter[2] = {0}; + u32 fw_ver = 0; + + /* set wlan_act to low */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + /* WiFi standby while GNT_BT 0 -> 1 */ + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to HIGH */ + h2c_parameter[0] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, h2c_parameter); + } else { + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, + &is_in_mp_mode); + if (!is_in_mp_mode) + /* BT select s0/s1 is controlled by BT */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0); + else + /* BT select s0/s1 is controlled by WiFi */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); +} + +/********************************************************************* + * extern function start with ex_btc8723b2ant_ + *********************************************************************/ +void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 u8tmp = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 2Ant Init HW Config!!\n"); + coex_dm->bt_rf0x1e_backup = + btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff); + + /* 0x790[5:0] = 0x5 */ + u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); + u8tmp &= 0xc0; + u8tmp |= 0x5; + btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); + + /* Antenna config */ + btc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN, + true, false); + coex_sta->dis_ver_info_cnt = 0; + + /* PTA parameter */ + btc8723b2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + + /* Enable counter statistics */ + /* 0x76e[3] = 1, WLAN_ACT controlled by PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); + btcoexist->auto_report_2ant = true; +} + +void ex_btc8723b2ant_power_on_setting(struct btc_coexist *btcoexist) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u16 u16tmp = 0x0; + u32 value = 0; + + btcoexist->btc_write_1byte(btcoexist, 0x67, 0x20); + + /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly */ + u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2); + btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT0 | BIT1); + + btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); + + if (btcoexist->chip_interface == BTC_INTF_USB) { + /* fixed at S0 for USB interface */ + board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; + } else { + /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ + if (board_info->single_ant_path == 0) { + /* set to S1 */ + board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; + } else if (board_info->single_ant_path == 1) { + /* set to S0 */ + board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; + } + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, + &value); + } +} + +void ex_btc8723b2ant_pre_load_firmware(struct btc_coexist *btcoexist) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */ + + /** + * S0 or S1 setting and Local register setting(By this fw can get + * ant number, S0/S1, ... info) + * + * Local setting bit define + * BIT0: "0" : no antenna inverse; "1" : antenna inverse + * BIT1: "0" : internal switch; "1" : external switch + * BIT2: "0" : one antenna; "1" : two antennas + * + * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and + * BIT2 = 0 + */ + if (btcoexist->chip_interface == BTC_INTF_USB) { + /* fixed at S0 for USB interface */ + u8tmp |= 0x1; /* antenna inverse */ + btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp); + } else { + /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ + if (board_info->single_ant_path == 0) { + } else if (board_info->single_ant_path == 1) { + /* set to S0 */ + u8tmp |= 0x1; /* antenna inverse */ + } + + if (btcoexist->chip_interface == BTC_INTF_PCI) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384, + u8tmp); + else if (btcoexist->chip_interface == BTC_INTF_SDIO) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, + u8tmp); + } +} + +void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Coex Mechanism Init!!\n"); + btc8723b2ant_init_coex_dm(btcoexist); +} + +void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; + u32 u32tmp[4]; + bool roam = false, scan = false; + bool link = false, wifi_under_5g = false; + bool bt_hs_on = false, wifi_busy = false; + s32 wifi_rssi = 0, bt_hs_rssi = 0; + u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; + u8 wifi_dot11_chnl, wifi_hs_chnl; + u32 fw_ver = 0, bt_patch_ver = 0; + u8 ap_num = 0; + + seq_puts(m, "\n ============[BT Coexist info]============"); + + if (btcoexist->manual_control) { + seq_puts(m, "\n ==========[Under Manual Control]============"); + seq_puts(m, "\n =========================================="); + } + + seq_printf(m, "\n %-35s = %d/ %d ", + "Ant PG number/ Ant mechanism:", + board_info->pg_ant_num, board_info->btdm_ant_num); + + seq_printf(m, "\n %-35s = %s / %d", + "BT stack/ hci ext ver", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + seq_printf(m, "\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", + "CoexVer/ FwVer/ PatchVer", + glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, + fw_ver, bt_patch_ver, bt_patch_ver); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, + &wifi_dot11_chnl); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsChnl(HsMode)", + wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); + + seq_printf(m, "\n %-35s = %3ph ", + "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); + seq_printf(m, "\n %-35s = %d/ %d/ %d", + "Wifi rssi/ HS rssi/ AP#", wifi_rssi, bt_hs_rssi, ap_num); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "Wifi link/ roam/ scan", link, roam, scan); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + &wifi_traffic_dir); + seq_printf(m, "\n %-35s = %s / %s/ %s ", + "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), + ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" : + (((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20"))), + ((!wifi_busy) ? "idle" : + ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ? + "uplink" : "downlink"))); + + seq_printf(m, "\n %-35s = %d / %d / %d / %d", + "SCO/HID/PAN/A2DP", + bt_link_info->sco_exist, bt_link_info->hid_exist, + bt_link_info->pan_exist, bt_link_info->a2dp_exist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); + + bt_info_ext = coex_sta->bt_info_ext; + seq_printf(m, "\n %-35s = %s", + "BT Info A2DP rate", + (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate"); + + for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + seq_printf(m, "\n %-35s = %7ph(%d)", + glbt_info_src_8723b_2ant[i], + coex_sta->bt_info_c2h[i], + coex_sta->bt_info_c2h_cnt[i]); + } + } + + seq_printf(m, "\n %-35s = %s/%s", + "PS state, IPS/LPS", + ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), + ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); + + /* Sw mechanism */ + seq_printf(m, + "\n %-35s", "============[Sw mechanism]============"); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, + coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); + seq_printf(m, "\n %-35s = %d/ %d/ %d(0x%x) ", + "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", + coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, + coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); + + /* Fw mechanism */ + seq_printf(m, "\n %-35s", + "============[Fw mechanism]============"); + + ps_tdma_case = coex_dm->cur_ps_tdma; + seq_printf(m, "\n %-35s = %5ph case-%d (auto:%d)", + "PS TDMA", coex_dm->ps_tdma_para, + ps_tdma_case, coex_dm->auto_tdma_adjust); + + seq_printf(m, "\n %-35s = %d/ %d ", + "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr_lvl, + coex_dm->cur_ignore_wlan_act); + + /* Hw setting */ + seq_printf(m, "\n %-35s", + "============[Hw setting]============"); + + seq_printf(m, "\n %-35s = 0x%x", + "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x778/0x880[29:25]", u8tmp[0], + (u32tmp[0] & 0x3e000000) >> 25); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x948/ 0x67[5] / 0x765", + u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", + u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "0x38[11]/0x40/0x4c[24:23]/0x64[0]", + ((u8tmp[0] & 0x8) >> 3), u8tmp[1], + ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); + u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); + + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); + u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + + fa_ofdm = ((u32tmp[0]&0xffff0000) >> 16) + + ((u32tmp[1]&0xffff0000) >> 16) + + (u32tmp[1] & 0xffff) + + (u32tmp[2] & 0xffff) + + ((u32tmp[3]&0xffff0000) >> 16) + + (u32tmp[3] & 0xffff); + fa_cck = (u8tmp[0] << 8) + u8tmp[1]; + + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "OFDM-CCA/OFDM-FA/CCK-FA", + u32tmp[0] & 0xffff, fa_ofdm, fa_cck); + + u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); + u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); + u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); + u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", + u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); + + seq_printf(m, "\n %-35s = %d/ %d", + "0x770(high-pri rx/tx)", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + seq_printf(m, "\n %-35s = %d/ %d", + "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, + coex_sta->low_priority_tx); + if (btcoexist->auto_report_2ant) + btc8723b2ant_monitor_bt_ctr(btcoexist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); +} + +void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_IPS_ENTER == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS ENTER notify\n"); + coex_sta->under_ips = true; + btc8723b2ant_wifioff_hwcfg(btcoexist); + btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + btc8723b2ant_coex_alloff(btcoexist); + } else if (BTC_IPS_LEAVE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS LEAVE notify\n"); + coex_sta->under_ips = false; + ex_btc8723b2ant_init_hwconfig(btcoexist); + btc8723b2ant_init_coex_dm(btcoexist); + btc8723b2ant_query_bt_info(btcoexist); + } +} + +void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_LPS_ENABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS ENABLE notify\n"); + coex_sta->under_lps = true; + } else if (BTC_LPS_DISABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS DISABLE notify\n"); + coex_sta->under_lps = false; + } +} + +void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u32 u32tmp; + u8 u8tmpa, u8tmpb; + + u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x76e); + + if (BTC_SCAN_START == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + else if (BTC_SCAN_FINISH == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, + &coex_sta->scan_ap_num); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u32tmp, u8tmpa, u8tmpb); +} + +void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_ASSOCIATE_START == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + else if (BTC_ASSOCIATE_FINISH == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); +} + +void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[3] = {0}; + u32 wifi_bw; + u8 wifi_central_chnl; + u8 ap_num = 0; + + if (BTC_MEDIA_CONNECT == type) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA connect notify\n"); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA disconnect notify\n"); + + /* only 2.4G we need to inform bt the chnl mask */ + btcoexist->btc_get(btcoexist, + BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl); + if ((BTC_MEDIA_CONNECT == type) && + (wifi_central_chnl <= 14)) { + h2c_parameter[0] = 0x1; + h2c_parameter[1] = wifi_central_chnl; + btcoexist->btc_get(btcoexist, + BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + h2c_parameter[2] = 0x30; + } else { + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, + &ap_num); + if (ap_num < 10) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + } + } + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x66=0x%x\n", + h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | + h2c_parameter[2]); + + btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (type == BTC_PACKET_DHCP) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], DHCP Packet notify\n"); +} + +void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmpbuf, u8 length) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 bt_info = 0; + u8 i, rsp_source = 0; + bool bt_busy = false, limited_dig = false; + bool wifi_connected = false; + + coex_sta->c2h_bt_info_req_sent = false; + + rsp_source = tmpbuf[0]&0xf; + if (rsp_source >= BT_INFO_SRC_8723B_2ANT_MAX) + rsp_source = BT_INFO_SRC_8723B_2ANT_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Bt info[%d], length=%d, hex data=[", + rsp_source, length); + for (i = 0; i < length; i++) { + coex_sta->bt_info_c2h[rsp_source][i] = tmpbuf[i]; + if (i == 1) + bt_info = tmpbuf[i]; + if (i == length - 1) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x]\n", tmpbuf[i]); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x, ", tmpbuf[i]); + } + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n"); + return; + } + + if (BT_INFO_SRC_8723B_2ANT_WIFI_FW != rsp_source) { + coex_sta->bt_retry_cnt = + coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + + if (coex_sta->bt_retry_cnt >= 1) + coex_sta->pop_event_cnt++; + + coex_sta->bt_rssi = + coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + + coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4]; + + if (coex_sta->bt_info_c2h[rsp_source][2] & 0x20) + coex_sta->c2h_bt_remote_name_req = true; + else + coex_sta->c2h_bt_remote_name_req = false; + + if (coex_sta->bt_info_c2h[rsp_source][1] == 0x49) + coex_sta->a2dp_bit_pool = + coex_sta->bt_info_c2h[rsp_source][6]; + else + coex_sta->a2dp_bit_pool = 0; + + /* Here we need to resend some wifi info to BT + * because BT is reset and loss of the info. + */ + if ((coex_sta->bt_info_ext & BIT1)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + if (wifi_connected) + ex_btc8723b2ant_media_status_notify( + btcoexist, + BTC_MEDIA_CONNECT); + else + ex_btc8723b2ant_media_status_notify( + btcoexist, + BTC_MEDIA_DISCONNECT); + } + + if ((coex_sta->bt_info_ext & BIT3)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); + btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, + false); + } else { + /* BT already NOT ignore Wlan active, do nothing here.*/ + } + if (!btcoexist->auto_report_2ant) { + if (!(coex_sta->bt_info_ext & BIT4)) + btc8723b2ant_bt_auto_report(btcoexist, + FORCE_EXEC, true); + } + } + + /* check BIT2 first ==> check if bt is under inquiry or page scan */ + if (bt_info & BT_INFO_8723B_2ANT_B_INQ_PAGE) + coex_sta->c2h_bt_inquiry_page = true; + else + coex_sta->c2h_bt_inquiry_page = false; + + if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { + /* set link exist status */ + coex_sta->bt_link_exist = false; + coex_sta->pan_exist = false; + coex_sta->a2dp_exist = false; + coex_sta->hid_exist = false; + coex_sta->sco_exist = false; + } else { + /* connection exists */ + coex_sta->bt_link_exist = true; + if (bt_info & BT_INFO_8723B_2ANT_B_FTP) + coex_sta->pan_exist = true; + else + coex_sta->pan_exist = false; + if (bt_info & BT_INFO_8723B_2ANT_B_A2DP) + coex_sta->a2dp_exist = true; + else + coex_sta->a2dp_exist = false; + if (bt_info & BT_INFO_8723B_2ANT_B_HID) + coex_sta->hid_exist = true; + else + coex_sta->hid_exist = false; + if (bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) + coex_sta->sco_exist = true; + else + coex_sta->sco_exist = false; + + if ((!coex_sta->hid_exist) && + (!coex_sta->c2h_bt_inquiry_page) && + (!coex_sta->sco_exist)) { + if (coex_sta->high_priority_tx + + coex_sta->high_priority_rx >= 160) { + coex_sta->hid_exist = true; + bt_info = bt_info | 0x28; + } + } + } + + btc8723b2ant_update_bt_link_info(btcoexist); + + if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); + /* connection exists but no busy */ + } else if (bt_info == BT_INFO_8723B_2ANT_B_CONNECTION) { + coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); + } else if ((bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8723B_2ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); + } else if (bt_info&BT_INFO_8723B_2ANT_B_ACL_BUSY) { + coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_MAX; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); + } + + if ((BT_8723B_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || + (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || + (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { + bt_busy = true; + limited_dig = true; + } else { + bt_busy = false; + limited_dig = false; + } + + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + coex_dm->limited_dig = limited_dig; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); + + btc8723b2ant_run_coexist_mechanism(btcoexist); +} + +void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n"); + + btc8723b2ant_wifioff_hwcfg(btcoexist); + btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + ex_btc8723b2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_btc8723b2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n"); + + if (pnp_state == BTC_WIFI_PNP_SLEEP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to SLEEP\n"); + + /* Driver do not leave IPS/LPS when driver is going to sleep, so + * BTCoexistence think wifi is still under IPS/LPS + * + * BT should clear UnderIPS/UnderLPS state to avoid mismatch + * state after wakeup. + */ + coex_sta->under_ips = false; + coex_sta->under_lps = false; + } else if (pnp_state == BTC_WIFI_PNP_WAKE_UP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to WAKE UP\n"); + ex_btc8723b2ant_init_hwconfig(btcoexist); + btc8723b2ant_init_coex_dm(btcoexist); + btc8723b2ant_query_bt_info(btcoexist); + } +} + +void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ==========================Periodical===========================\n"); + + if (coex_sta->dis_ver_info_cnt <= 5) { + coex_sta->dis_ver_info_cnt += 1; + if (coex_sta->dis_ver_info_cnt == 3) { + /* Antenna config to set 0x765 = 0x0 (GNT_BT control by + * PTA) after initial + */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Set GNT_BT control by PTA\n"); + btc8723b2ant_set_ant_path( + btcoexist, BTC_ANT_WIFI_AT_MAIN, false, false); + } + } + + if (!btcoexist->auto_report_2ant) { + btc8723b2ant_query_bt_info(btcoexist); + } else { + btc8723b2ant_monitor_bt_ctr(btcoexist); + btc8723b2ant_monitor_wifi_ctr(btcoexist); + + /* for some BT speakers that High-Priority pkts appear before + * playing, this will cause HID exist + */ + if ((coex_sta->high_priority_tx + + coex_sta->high_priority_rx < 50) && + (bt_link_info->hid_exist)) + bt_link_info->hid_exist = false; + + if (btc8723b2ant_is_wifi_status_changed(btcoexist) || + coex_dm->auto_tdma_adjust) + btc8723b2ant_run_coexist_mechanism(btcoexist); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h new file mode 100644 index 000000000..08aad6ef4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2012 Realtek Corporation.*/ + +#ifndef _HAL8723B_2_ANT +#define _HAL8723B_2_ANT + +/************************************************************************ + * The following is for 8723B 2Ant BT Co-exist definition + ************************************************************************/ +#define BT_INFO_8723B_2ANT_B_FTP BIT7 +#define BT_INFO_8723B_2ANT_B_A2DP BIT6 +#define BT_INFO_8723B_2ANT_B_HID BIT5 +#define BT_INFO_8723B_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723B_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723B_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723B_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723B_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT 2 + +/* WiFi RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation */ +#define BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES 42 +/* BT RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation */ +#define BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES 46 + +enum BT_INFO_SRC_8723B_2ANT { + BT_INFO_SRC_8723B_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8723B_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723B_2ANT_MAX +}; + +enum BT_8723B_2ANT_BT_STATUS { + BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8723B_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8723B_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_2ANT_BT_STATUS_MAX +}; + +enum BT_8723B_2ANT_COEX_ALGO { + BT_8723B_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723B_2ANT_COEX_ALGO_SCO = 0x1, + BT_8723B_2ANT_COEX_ALGO_HID = 0x2, + BT_8723B_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8723B_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8723B_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8723B_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8723B_2ANT_COEX_ALGO_MAX = 0xb, +}; + +struct coex_dm_8723b_2ant { + /* fw mechanism */ + bool pre_dec_bt_pwr_lvl; + bool cur_dec_bt_pwr_lvl; + u8 pre_fw_dac_swing_lvl; + u8 cur_fw_dac_swing_lvl; + bool cur_ignore_wlan_act; + bool pre_ignore_wlan_act; + u8 pre_ps_tdma; + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + u8 ps_tdma_du_adj_type; + bool reset_tdma_adjust; + bool auto_tdma_adjust; + bool pre_ps_tdma_on; + bool cur_ps_tdma_on; + bool pre_bt_auto_report; + bool cur_bt_auto_report; + + /* sw mechanism */ + bool pre_rf_rx_lpf_shrink; + bool cur_rf_rx_lpf_shrink; + u32 bt_rf0x1e_backup; + bool pre_low_penalty_ra; + bool cur_low_penalty_ra; + bool pre_dac_swing_on; + u32 pre_dac_swing_lvl; + bool cur_dac_swing_on; + u32 cur_dac_swing_lvl; + bool pre_adc_back_off; + bool cur_adc_back_off; + bool pre_agc_table_en; + bool cur_agc_table_en; + u32 pre_val0x6c0; + u32 cur_val0x6c0; + u32 pre_val0x6c4; + u32 cur_val0x6c4; + u32 pre_val0x6c8; + u32 cur_val0x6c8; + u8 pre_val0x6cc; + u8 cur_val0x6cc; + bool limited_dig; + + /* algorithm related */ + u8 pre_algorithm; + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + + u8 pre_lps; + u8 cur_lps; + u8 pre_rpwm; + u8 cur_rpwm; + + bool is_switch_to_1dot5_ant; + u8 switch_thres_offset; +}; + +struct coex_sta_8723b_2ant { + bool bt_link_exist; + bool sco_exist; + bool a2dp_exist; + bool hid_exist; + bool pan_exist; + bool bt_abnormal_scan; + + bool under_lps; + bool under_ips; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 bt_rssi; + bool bt_tx_rx_mask; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + bool c2h_bt_info_req_sent; + u8 bt_info_c2h[BT_INFO_SRC_8723B_2ANT_MAX][10]; + u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_2ANT_MAX]; + bool c2h_bt_inquiry_page; + bool c2h_bt_remote_name_req; + u8 bt_retry_cnt; + u8 bt_info_ext; + u32 pop_event_cnt; + u8 scan_ap_num; + + u32 crc_ok_cck; + u32 crc_ok_11g; + u32 crc_ok_11n; + u32 crc_ok_11n_agg; + + u32 crc_err_cck; + u32 crc_err_11g; + u32 crc_err_11n; + u32 crc_err_11n_agg; + bool force_lps_on; + + u8 dis_ver_info_cnt; + + u8 a2dp_bit_pool; +}; + +/********************************************************************* + * The following is interface which will notify coex module. + *********************************************************************/ +void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); +void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmpbuf, u8 length); +void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist); +void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist); +void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m); +void ex_btc8723b2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); +void ex_btc8723b2ant_pre_load_firmware(struct btc_coexist *btcoexist); +void ex_btc8723b2ant_power_on_setting(struct btc_coexist *btcoexist); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c new file mode 100644 index 000000000..67d0b9aee --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c @@ -0,0 +1,2967 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2012 Realtek Corporation.*/ + +/************************************************************** + * Description: + * + * This file is for RTL8821A Co-exist mechanism + * + * History + * 2012/11/15 Cosa first check in. + * + **************************************************************/ + +/************************************************************** + * include files + **************************************************************/ +#include "halbt_precomp.h" +/************************************************************** + * Global variables, these are static variables + **************************************************************/ +static struct coex_dm_8821a_1ant glcoex_dm_8821a_1ant; +static struct coex_dm_8821a_1ant *coex_dm = &glcoex_dm_8821a_1ant; +static struct coex_sta_8821a_1ant glcoex_sta_8821a_1ant; +static struct coex_sta_8821a_1ant *coex_sta = &glcoex_sta_8821a_1ant; +static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, + u8 wifi_status); + +static const char *const glbt_info_src_8821a_1ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8821a_1ant = 20130816; +static u32 glcoex_ver_8821a_1ant = 0x41; + +/************************************************************** + * local function proto type if needed + * + * local function start with btc8821a1ant_ + **************************************************************/ +static u8 btc8821a1ant_bt_rssi_state(struct btc_coexist *btcoexist, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + long bt_rssi = 0; + u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + + bt_rssi = coex_sta->bt_rssi; + + if (level_num == 2) { + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else { + if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi thresh error!!\n"); + return coex_sta->pre_bt_rssi_state; + } + + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else if ((coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (bt_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Medium\n"); + } + } else { + if (bt_rssi < rssi_thresh1) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } + coex_sta->pre_bt_rssi_state = bt_rssi_state; + + return bt_rssi_state; +} + +static u8 btc8821a1ant_wifi_rssi_state(struct btc_coexist *btcoexist, + u8 index, u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + long wifi_rssi = 0; + u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + + if (level_num == 2) { + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else { + if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI thresh error!!\n"); + return coex_sta->pre_wifi_rssi_state[index]; + } + + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (wifi_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Medium\n"); + } + } else { + if (wifi_rssi < rssi_thresh1) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } + coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + + return wifi_rssi_state; +} + +static void btc8821a1ant_update_ra_mask(struct btc_coexist *btcoexist, + bool force_exec, u32 dis_rate_mask) +{ + coex_dm->cur_ra_mask = dis_rate_mask; + + if (force_exec || + (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) { + btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK, + &coex_dm->cur_ra_mask); + } + coex_dm->pre_ra_mask = coex_dm->cur_ra_mask; +} + +static void btc8821a1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + bool wifi_under_b_mode = false; + + coex_dm->cur_arfr_type = type; + + if (force_exec || + (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { + switch (coex_dm->cur_arfr_type) { + case 0: /* normal mode */ + btcoexist->btc_write_4byte(btcoexist, 0x430, + coex_dm->backup_arfr_cnt1); + btcoexist->btc_write_4byte(btcoexist, 0x434, + coex_dm->backup_arfr_cnt2); + break; + case 1: + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + if (wifi_under_b_mode) { + btcoexist->btc_write_4byte(btcoexist, 0x430, + 0x0); + btcoexist->btc_write_4byte(btcoexist, 0x434, + 0x01010101); + } else { + btcoexist->btc_write_4byte(btcoexist, 0x430, + 0x0); + btcoexist->btc_write_4byte(btcoexist, 0x434, + 0x04030201); + } + break; + default: + break; + } + } + + coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; +} + +static void btc8821a1ant_retry_limit(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_retry_limit_type = type; + + if (force_exec || + (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) { + switch (coex_dm->cur_retry_limit_type) { + case 0: /* normal mode */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, + coex_dm->backup_retry_limit); + break; + case 1: /* retry limit = 8 */ + btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; +} + +static void btc8821a1ant_ampdu_max_time(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_dm->cur_ampdu_time_type = type; + + if (force_exec || + (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) { + switch (coex_dm->cur_ampdu_time_type) { + case 0: /* normal mode */ + btcoexist->btc_write_1byte(btcoexist, 0x456, + coex_dm->backup_ampdu_max_time); + break; + case 1: /* AMPDU time = 0x38 * 32us */ + btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); + break; + default: + break; + } + } + + coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; +} + +static void btc8821a1ant_limited_tx(struct btc_coexist *btcoexist, + bool force_exec, u8 ra_mask_type, + u8 arfr_type, u8 retry_limit_type, + u8 ampdu_time_type) +{ + switch (ra_mask_type) { + case 0: /* normal mode */ + btc8821a1ant_update_ra_mask(btcoexist, force_exec, 0x0); + break; + case 1: /* disable cck 1/2 */ + btc8821a1ant_update_ra_mask(btcoexist, force_exec, + 0x00000003); + break; + case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */ + btc8821a1ant_update_ra_mask(btcoexist, force_exec, + 0x0001f1f7); + break; + default: + break; + } + + btc8821a1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type); + btc8821a1ant_retry_limit(btcoexist, force_exec, retry_limit_type); + btc8821a1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type); +} + +static void btc8821a1ant_limited_rx(struct btc_coexist *btcoexist, + bool force_exec, bool rej_ap_agg_pkt, + bool bt_ctrl_agg_buf_size, u8 agg_buf_size) +{ + bool reject_rx_agg = rej_ap_agg_pkt; + bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rx_agg_size = agg_buf_size; + + /* Rx Aggregation related setting */ + btcoexist->btc_set(btcoexist, + BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg); + /* decide BT control aggregation buf size or not */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, + &bt_ctrl_rx_agg_size); + /* aggregation buf size, only work when BT control Rx agg size */ + btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); + /* real update aggregation setting */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +static void btc8821a1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ + u32 reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; + + reg_hp_tx_rx = 0x770; + reg_lp_tx_rx = 0x774; + + u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx); + reg_hp_tx = u4_tmp & MASKLWORD; + reg_hp_rx = (u4_tmp & MASKHWORD) >> 16; + + u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx); + reg_lp_tx = u4_tmp & MASKLWORD; + reg_lp_rx = (u4_tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + /* reset counter */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static void btc8821a1ant_query_bt_info(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + h2c_parameter[0] |= BIT0; /* trigger */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + +static void btc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + + /* work around for HS mode */ + if (bt_hs_on) { + bt_link_info->pan_exist = true; + bt_link_info->bt_link_exist = true; + } + + /* check if Sco only */ + if (bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->sco_only = true; + else + bt_link_info->sco_only = false; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && + bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->a2dp_only = true; + else + bt_link_info->a2dp_only = false; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->pan_only = true; + else + bt_link_info->pan_only = false; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + bt_link_info->hid_exist) + bt_link_info->hid_only = true; + else + bt_link_info->hid_only = false; +} + +static u8 btc8821a1ant_action_algorithm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + u8 algorithm = BT_8821A_1ANT_COEX_ALGO_UNDEFINED; + u8 num_of_diff_profile = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + if (!bt_link_info->bt_link_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], No BT link exists!!!\n"); + return algorithm; + } + + if (bt_link_info->sco_exist) + num_of_diff_profile++; + if (bt_link_info->hid_exist) + num_of_diff_profile++; + if (bt_link_info->pan_exist) + num_of_diff_profile++; + if (bt_link_info->a2dp_exist) + num_of_diff_profile++; + + if (num_of_diff_profile == 1) { + if (bt_link_info->sco_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = SCO only\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } else { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = HID only\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = A2DP only\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = PAN(HS) only\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = PAN(EDR) only\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR; + } + } + } + } else if (num_of_diff_profile == 2) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = SCO + HID\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + PAN(EDR)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = HID + A2DP\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = HID + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = HID + PAN(EDR)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = A2DP + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = A2DP + PAN(EDR)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } else if (num_of_diff_profile == 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } else if (num_of_diff_profile >= 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n"); + + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + return algorithm; +} + +static void btc8821a1ant_set_sw_penalty_tx_rate(struct btc_coexist *btcoexist, + bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[6] = {0}; + + h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty*/ + + if (low_penalty_ra) { + h2c_parameter[1] |= BIT0; + /* normal rate except MCS7/6/5, OFDM54/48/36 */ + h2c_parameter[2] = 0x00; + h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */ + h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */ + h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */ + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set WiFi Low-Penalty Retry: %s", + (low_penalty_ra ? "ON!!" : "OFF!!")); + + btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void btc8821a1ant_low_penalty_ra(struct btc_coexist *btcoexist, + bool force_exec, bool low_penalty_ra) +{ + coex_dm->cur_low_penalty_ra = low_penalty_ra; + + if (!force_exec) { + if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) + return; + } + btc8821a1ant_set_sw_penalty_tx_rate(btcoexist, + coex_dm->cur_low_penalty_ra); + + coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void btc8821a1ant_set_coex_table(struct btc_coexist *btcoexist, + u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); + btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); + btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); + btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); + btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8821a1ant_coex_table(struct btc_coexist *btcoexist, + bool force_exec, u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", + (force_exec ? "force to" : ""), val0x6c0, val0x6c4, + val0x6c8, val0x6cc); + coex_dm->cur_val_0x6c0 = val0x6c0; + coex_dm->cur_val_0x6c4 = val0x6c4; + coex_dm->cur_val_0x6c8 = val0x6c8; + coex_dm->cur_val_0x6cc = val0x6cc; + + if (!force_exec) { + if ((coex_dm->pre_val_0x6c0 == coex_dm->cur_val_0x6c0) && + (coex_dm->pre_val_0x6c4 == coex_dm->cur_val_0x6c4) && + (coex_dm->pre_val_0x6c8 == coex_dm->cur_val_0x6c8) && + (coex_dm->pre_val_0x6cc == coex_dm->cur_val_0x6cc)) + return; + } + btc8821a1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, + val0x6c8, val0x6cc); + + coex_dm->pre_val_0x6c0 = coex_dm->cur_val_0x6c0; + coex_dm->pre_val_0x6c4 = coex_dm->cur_val_0x6c4; + coex_dm->pre_val_0x6c8 = coex_dm->cur_val_0x6c8; + coex_dm->pre_val_0x6cc = coex_dm->cur_val_0x6cc; +} + +static void btc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + switch (type) { + case 0: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x55555555, 0xffffff, 0x3); + break; + case 1: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 5: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, + 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 6: + btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, + 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 7: + btc8821a1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, + bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + if (enable) + h2c_parameter[0] |= BIT0; /* function enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void btc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist, + bool force_exec, bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Ignore WlanAct %s\n", + (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); + coex_dm->cur_ignore_wlan_act = enable; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n", + coex_dm->pre_ignore_wlan_act, + coex_dm->cur_ignore_wlan_act); + + if (coex_dm->pre_ignore_wlan_act == + coex_dm->cur_ignore_wlan_act) + return; + } + btc8821a1ant_set_fw_ignore_wlan_act(btcoexist, enable); + + coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8821a1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1, + u8 byte2, u8 byte3, u8 byte4, u8 byte5) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[5] = {0}; + u8 real_byte1 = byte1, real_byte5 = byte5; + bool ap_enable = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + + if (ap_enable) { + if (byte1 & BIT4 && !(byte1 & BIT5)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW for 1Ant AP mode\n"); + real_byte1 &= ~BIT4; + real_byte1 |= BIT5; + + real_byte5 |= BIT5; + real_byte5 &= ~BIT6; + } + } + + h2c_parameter[0] = real_byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = real_byte5; + + coex_dm->ps_tdma_para[0] = real_byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = real_byte5; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + h2c_parameter[0], + h2c_parameter[1] << 24 | + h2c_parameter[2] << 16 | + h2c_parameter[3] << 8 | + h2c_parameter[4]); + btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8821a1ant_set_lps_rpwm(struct btc_coexist *btcoexist, + u8 lps_val, u8 rpwm_val) +{ + u8 lps = lps_val; + u8 rpwm = rpwm_val; + + btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); + btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); +} + +static void btc8821a1ant_lps_rpwm(struct btc_coexist *btcoexist, + bool force_exec, u8 lps_val, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n", + (force_exec ? "force to" : ""), lps_val, rpwm_val); + coex_dm->cur_lps = lps_val; + coex_dm->cur_rpwm = rpwm_val; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS-RxBeaconMode = 0x%x, LPS-RPWM = 0x%x!!\n", + coex_dm->cur_lps, coex_dm->cur_rpwm); + + if ((coex_dm->pre_lps == coex_dm->cur_lps) && + (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS-RPWM_Last = 0x%x, LPS-RPWM_Now = 0x%x!!\n", + coex_dm->pre_rpwm, coex_dm->cur_rpwm); + + return; + } + } + btc8821a1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); + + coex_dm->pre_lps = coex_dm->cur_lps; + coex_dm->pre_rpwm = coex_dm->cur_rpwm; +} + +static void btc8821a1ant_sw_mechanism(struct btc_coexist *btcoexist, + bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra); + + btc8821a1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void btc8821a1ant_set_ant_path(struct btc_coexist *btcoexist, + u8 ant_pos_type, bool init_hw_cfg, + bool wifi_off) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u32 u4_tmp = 0; + u8 h2c_parameter[2] = {0}; + + if (init_hw_cfg) { + /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */ + u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u4_tmp &= ~BIT23; + u4_tmp |= BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp); + + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x975, 0x3, 0x3); + btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77); + + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { + /* tell firmware "antenna inverse" + * WRONG firmware antenna control code, need fw to fix + */ + h2c_parameter[0] = 1; + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } else { + /* tell firmware "no antenna inverse" + * WRONG firmware antenna control code, need fw to fix + */ + h2c_parameter[0] = 0; + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } + } else if (wifi_off) { + /* 0x4c[24:23] = 00, Set Antenna control + * by BT_RFE_CTRL BT Vendor 0xac = 0xf002 + */ + u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u4_tmp &= ~BIT23; + u4_tmp &= ~BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp); + + /* 0x765 = 0x18 */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3); + } else { + /* 0x765 = 0x0 */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); + } + + /* ext switch setting */ + switch (ant_pos_type) { + case BTC_ANT_PATH_WIFI: + btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77); + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x1); + else + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x2); + break; + case BTC_ANT_PATH_BT: + btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77); + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x2); + else + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x1); + break; + default: + case BTC_ANT_PATH_PTA: + btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x66); + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x1); + else + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, + 0x30, 0x2); + break; + } +} + +static void btc8821a1ant_ps_tdma(struct btc_coexist *btcoexist, + bool force_exec, bool turn_on, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 rssi_adjust_val = 0; + + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + if (!force_exec) { + if (coex_dm->cur_ps_tdma_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ********** TDMA(on, %d) **********\n", + coex_dm->cur_ps_tdma); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ********** TDMA(off, %d) **********\n", + coex_dm->cur_ps_tdma); + } + if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && + (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) + return; + } + if (turn_on) { + switch (type) { + default: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a, + 0x1a, 0x0, 0x50); + break; + case 1: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a, + 0x03, 0x10, 0x50); + rssi_adjust_val = 11; + break; + case 2: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b, + 0x03, 0x10, 0x50); + rssi_adjust_val = 14; + break; + case 3: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d, + 0x1d, 0x0, 0x10); + break; + case 4: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, + 0x3, 0x14, 0x0); + rssi_adjust_val = 17; + break; + case 5: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15, + 0x3, 0x11, 0x10); + break; + case 6: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20, + 0x3, 0x11, 0x13); + break; + case 7: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc, + 0x5, 0x0, 0x0); + break; + case 8: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, + 0x3, 0x10, 0x0); + break; + case 9: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21, + 0x3, 0x10, 0x50); + rssi_adjust_val = 18; + break; + case 10: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, + 0xa, 0x0, 0x40); + break; + case 11: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15, + 0x03, 0x10, 0x50); + rssi_adjust_val = 20; + break; + case 12: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a, + 0x0a, 0x0, 0x50); + break; + case 13: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x12, + 0x12, 0x0, 0x50); + break; + case 14: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1e, + 0x3, 0x10, 0x14); + break; + case 15: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, + 0x3, 0x8, 0x0); + break; + case 16: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, + 0x3, 0x10, 0x0); + rssi_adjust_val = 18; + break; + case 18: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, + 0x3, 0x10, 0x0); + rssi_adjust_val = 14; + break; + case 20: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35, + 0x03, 0x11, 0x10); + break; + case 21: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, + 0x03, 0x11, 0x11); + break; + case 22: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, + 0x03, 0x11, 0x10); + break; + case 23: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x3, 0x31, 0x18); + rssi_adjust_val = 22; + break; + case 24: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x3, 0x31, 0x18); + rssi_adjust_val = 22; + break; + case 25: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, + 0x3, 0x31, 0x18); + rssi_adjust_val = 22; + break; + case 26: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, + 0x3, 0x31, 0x18); + rssi_adjust_val = 22; + break; + case 27: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x3, 0x31, 0x98); + rssi_adjust_val = 22; + break; + case 28: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25, + 0x3, 0x31, 0x0); + break; + case 29: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a, + 0x1a, 0x1, 0x10); + break; + case 30: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30, + 0x3, 0x10, 0x10); + break; + case 31: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a, + 0x1a, 0, 0x58); + break; + case 32: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35, + 0x3, 0x11, 0x11); + break; + case 33: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25, + 0x3, 0x30, 0x90); + break; + case 34: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a, + 0x1a, 0x0, 0x10); + break; + case 35: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a, + 0x1a, 0x0, 0x10); + break; + case 36: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12, + 0x3, 0x14, 0x50); + break; + case 40: + /* SoftAP only with no sta associated, BT disable, TDMA + * mode for power saving + * + * here softap mode screen off will cost 70-80mA for + * phone + */ + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18, + 0x00, 0x10, 0x24); + break; + case 41: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15, + 0x3, 0x11, 0x11); + break; + case 42: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x20, + 0x3, 0x11, 0x11); + break; + case 43: + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30, + 0x3, 0x10, 0x11); + break; + } + } else { + /* disable PS tdma */ + switch (type) { + case 8: + /* PTA Control */ + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, 0x0, + 0x0, 0x0); + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + false, false); + break; + case 0: + default: + /* Software control, Antenna at BT side */ + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x0, 0x0); + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + false, false); + break; + case 9: + /* Software control, Antenna at WiFi side */ + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x0, 0x0); + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI, + false, false); + break; + case 10: + /* under 5G */ + btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x8, 0x0); + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + false, false); + break; + } + } + rssi_adjust_val = 0; + btcoexist->btc_set(btcoexist, + BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val); + + /* update pre state */ + coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; + coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static bool btc8821a1ant_is_common_action(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool common = false, wifi_connected = false, wifi_busy = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (!wifi_connected && + BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n"); + btc8821a1ant_sw_mechanism(btcoexist, false); + + common = true; + } else if (wifi_connected && + (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT non connected-idle!!\n"); + btc8821a1ant_sw_mechanism(btcoexist, false); + + common = true; + } else if (!wifi_connected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n"); + btc8821a1ant_sw_mechanism(btcoexist, false); + + common = true; + } else if (wifi_connected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT connected-idle!!\n"); + btc8821a1ant_sw_mechanism(btcoexist, false); + + common = true; + } else if (!wifi_connected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE != + coex_dm->bt_status)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non connected-idle + BT Busy!!\n"); + btc8821a1ant_sw_mechanism(btcoexist, false); + + common = true; + } else { + if (wifi_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Busy + BT Busy!!\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Idle + BT Busy!!\n"); + } + + common = false; + } + + return common; +} + +static void btc8821a1ant_ps_tdma_check_for_pwr_save(struct btc_coexist *btcoex, + bool new_ps_state) +{ + u8 lps_mode = 0x0; + + btcoex->btc_get(btcoex, BTC_GET_U1_LPS_MODE, &lps_mode); + + if (lps_mode) { + /* already under LPS state */ + if (new_ps_state) { + /* keep state under LPS, do nothing */ + } else { + /* will leave LPS state, turn off psTdma first */ + btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0); + } + } else { + /* NO PS state*/ + if (new_ps_state) { + /* will enter LPS state, turn off psTdma first */ + btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0); + } else { + /* keep state under NO PS state, do nothing */ + } + } +} + +static void btc8821a1ant_power_save_state(struct btc_coexist *btcoexist, + u8 ps_type, u8 lps_val, u8 rpwm_val) +{ + bool low_pwr_disable = false; + + switch (ps_type) { + case BTC_PS_WIFI_NATIVE: + /* recover to original 32k low power setting */ + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + break; + case BTC_PS_LPS_ON: + btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, + true); + btc8821a1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, + rpwm_val); + /* when coex force to enter LPS, do not enter 32k low power */ + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + /* power save must executed before psTdma */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); + break; + case BTC_PS_LPS_OFF: + btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, false); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + break; + default: + break; + } +} + +static void btc8821a1ant_coex_under_5g(struct btc_coexist *btcoexist) +{ + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a1ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true); + + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 10); + + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 5); +} + +/*********************************************** + * + * Software Coex Mechanism start + * + ***********************************************/ + +/* SCO only or SCO+PAN(HS) */ +static void btc8821a1ant_action_sco(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, true); +} + +static void btc8821a1ant_action_hid(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, true); +} + +/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ +static void btc8821a1ant_action_a2dp(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, false); +} + +static void btc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, false); +} + +static void btc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, false); +} + +/* PAN(HS) only */ +static void btc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, false); +} + +/* PAN(EDR)+A2DP */ +static void btc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, false); +} + +static void btc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, true); +} + +/* HID+A2DP+PAN(EDR) */ +static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, true); +} + +static void btc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ + btc8821a1ant_sw_mechanism(btcoexist, true); +} + +/*********************************************** + * + * Non-Software Coex Mechanism start + * + ***********************************************/ +static +void btc8821a1ant_action_wifi_multi_port(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + /* tdma and coex table */ + if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) { + if (bt_link_info->a2dp_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + } else if (bt_link_info->a2dp_exist && + bt_link_info->pan_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } + } else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == + coex_dm->bt_status)) { + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static +void btc8821a1ant_action_wifi_not_connected_asso_auth( + struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, + 0x0); + + /* tdma and coex table */ + if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + } else if ((bt_link_info->a2dp_exist) || (bt_link_info->pan_exist)) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + + +static void btc8821a1ant_action_hs(struct btc_coexist *btcoexist) +{ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2); +} + +static void btc8821a1ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_connected = false; + bool ap_enable = false; + bool wifi_busy = false, bt_busy = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) { + btc8821a1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + } else if ((bt_link_info->sco_exist) || (bt_link_info->a2dp_exist) || + (bt_link_info->hid_only)) { + /* SCO/HID-only busy */ + btc8821a1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else if ((bt_link_info->a2dp_exist) && (bt_link_info->hid_exist)) { + /* A2DP+HID busy */ + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + } else if ((bt_link_info->pan_exist) || (wifi_busy)) { + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else { + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + } +} + +static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, + u8 wifi_status) +{ + /* tdma and coex table */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); +} + +static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist, + u8 wifi_status) +{ + u8 bt_rssi_state; + + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + bt_rssi_state = btc8821a1ant_bt_rssi_state(btcoexist, 2, 28, 0); + + if (bt_link_info->hid_only) { + /* HID */ + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + wifi_status); + coex_dm->auto_tdma_adjust = false; + return; + } else if (bt_link_info->a2dp_only) { + /* A2DP */ + if (wifi_status == BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + coex_dm->auto_tdma_adjust = false; + } else if ((bt_rssi_state != BTC_RSSI_STATE_HIGH) && + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + } else { + /* for low BT RSSI */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + coex_dm->auto_tdma_adjust = false; + } + } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { + /* HID+A2DP (no need to consider BT RSSI) */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->auto_tdma_adjust = false; + + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + } else if ((bt_link_info->pan_only) || + (bt_link_info->hid_exist && bt_link_info->pan_exist)) { + /* PAN(OPP, FTP), HID+PAN(OPP, FTP) */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6); + coex_dm->auto_tdma_adjust = false; + } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) || + (bt_link_info->hid_exist && bt_link_info->a2dp_exist && + bt_link_info->pan_exist)) { + /* A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP) */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 43); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + coex_dm->auto_tdma_adjust = false; + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + coex_dm->auto_tdma_adjust = false; + } +} + +static +void btc8821a1ant_action_wifi_not_connected(struct btc_coexist *btcoexist) +{ + /* power save state */ + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + /* tdma and coex table */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8821a1ant_act_wifi_not_conn_scan(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + /* tdma and coex table */ + if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) { + if (bt_link_info->a2dp_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + } else if (bt_link_info->a2dp_exist && + bt_link_info->pan_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } + } else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == + coex_dm->bt_status)) { + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static +void btc8821a1ant_action_wifi_connected_scan(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + /* power save state */ + btc8821a1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + /* tdma and coex table */ + if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { + if (bt_link_info->a2dp_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 1); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 4); + } + } else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) || + (coex_dm->bt_status == + BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY)) { + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static void btc8821a1ant_act_wifi_conn_sp_pkt(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + /* tdma and coex table */ + if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) || + (bt_link_info->a2dp_exist)) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } + + if ((bt_link_info->hid_exist) && (bt_link_info->a2dp_exist)) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); + } else if (bt_link_info->pan_exist) { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } +} + +static void btc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_busy = false; + bool scan = false, link = false, roam = false; + bool under_4way = false; + bool ap_enable = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect()===>\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + if (under_4way) { + btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + if (scan || link || roam) { + if (scan) + btc8821a1ant_action_wifi_connected_scan(btcoexist); + else + btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); + return; + } + + /* power save state*/ + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == + coex_dm->bt_status && !ap_enable && + !btcoexist->bt_link_info.hid_only) { + if (!wifi_busy && btcoexist->bt_link_info.a2dp_only) + /* A2DP */ + btc8821a1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + btc8821a1ant_power_save_state(btcoexist, BTC_PS_LPS_ON, + 0x50, 0x4); + } else { + btc8821a1ant_power_save_state(btcoexist, + BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } + + /* tdma and coex table */ + if (!wifi_busy) { + if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { + btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY == + coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == + coex_dm->bt_status)) { + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 2); + } + } else { + if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { + btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY == + coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == + coex_dm->bt_status)) { + btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } else { + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 2); + } + } +} + +static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 algorithm = 0; + + algorithm = btc8821a1ant_action_algorithm(btcoexist); + coex_dm->cur_algorithm = algorithm; + + if (!btc8821a1ant_is_common_action(btcoexist)) { + switch (coex_dm->cur_algorithm) { + case BT_8821A_1ANT_COEX_ALGO_SCO: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = SCO\n"); + btc8821a1ant_action_sco(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = HID\n"); + btc8821a1ant_action_hid(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = A2DP\n"); + btc8821a1ant_action_a2dp(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = A2DP+PAN(HS)\n"); + btc8821a1ant_action_a2dp_pan_hs(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = PAN(EDR)\n"); + btc8821a1ant_action_pan_edr(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = HS mode\n"); + btc8821a1ant_action_pan_hs(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = PAN+A2DP\n"); + btc8821a1ant_action_pan_edr_a2dp(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = PAN(EDR)+HID\n"); + btc8821a1ant_action_pan_edr_hid(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = HID+A2DP+PAN\n"); + btc8821a1ant_action_hid_a2dp_pan_edr(btcoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = HID+A2DP\n"); + btc8821a1ant_action_hid_a2dp(btcoexist); + break; + default: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action algorithm = coexist All Off!!\n"); + /*btc8821a1ant_coex_all_off(btcoexist);*/ + break; + } + coex_dm->pre_algorithm = coex_dm->cur_algorithm; + } +} + +static void btc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_connected = false, bt_hs_on = false; + bool increase_scan_dev_num = false; + bool bt_ctrl_agg_buf_size = false; + u8 agg_buf_size = 5; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + bool wifi_under_5g = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism()===>\n"); + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); + return; + } + + if (btcoexist->stop_coex_dm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); + return; + } + + if (coex_sta->under_ips) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) + increase_scan_dev_num = true; + + btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, + &increase_scan_dev_num); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if ((num_of_wifi_link >= 2) || + (wifi_link_status & WIFI_P2P_GO_CONNECTED)) { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + btc8821a1ant_action_wifi_multi_port(btcoexist); + return; + } + + if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + } else { + if (wifi_connected) { + btc8821a1ant_wifi_rssi_state(btcoexist, 1, 2, + 30, 0); + btc8821a1ant_limited_tx(btcoexist, + NORMAL_EXEC, 1, 1, + 0, 1); + } else { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, + 0, 0, 0, 0); + } + } + + if (bt_link_info->sco_exist) { + bt_ctrl_agg_buf_size = true; + agg_buf_size = 0x3; + } else if (bt_link_info->hid_exist) { + bt_ctrl_agg_buf_size = true; + agg_buf_size = 0x5; + } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) { + bt_ctrl_agg_buf_size = true; + agg_buf_size = 0x8; + } + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + + btc8821a1ant_run_sw_coex_mech(btcoexist); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + if (coex_sta->c2h_bt_inquiry_page) { + btc8821a1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + btc8821a1ant_action_hs(btcoexist); + return; + } + + if (!wifi_connected) { + bool scan = false, link = false, roam = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is non connected-idle !!!\n"); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (scan || link || roam) { + if (scan) + btc8821a1ant_act_wifi_not_conn_scan(btcoexist); + else + btc8821a1ant_action_wifi_not_connected_asso_auth( + btcoexist); + } else { + btc8821a1ant_action_wifi_not_connected(btcoexist); + } + } else { + /* wifi LPS/Busy */ + btc8821a1ant_action_wifi_connected(btcoexist); + } +} + +static void btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + /* force to reset coex mechanism + * sw all off + */ + btc8821a1ant_sw_mechanism(btcoexist, false); + + btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); +} + +static void btc8821a1ant_init_hw_config(struct btc_coexist *btcoexist, + bool back_up, bool wifi_only) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 u1_tmp = 0; + bool wifi_under_5g = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 1Ant Init HW Config!!\n"); + + if (wifi_only) + return; + + if (back_up) { + coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist, + 0x430); + coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist, + 0x434); + coex_dm->backup_retry_limit = + btcoexist->btc_read_2byte(btcoexist, 0x42a); + coex_dm->backup_ampdu_max_time = + btcoexist->btc_read_1byte(btcoexist, 0x456); + } + + /* 0x790[5:0] = 0x5 */ + u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); + u1_tmp &= 0xc0; + u1_tmp |= 0x5; + btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + + /* Antenna config */ + if (wifi_under_5g) + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, + true, false); + else + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, + true, false); + /* PTA parameter */ + btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + + /* Enable counter statistics + * 0x76e[3] =1, WLAN_Act control by PTA + */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); + btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); +} + +/************************************************************** + * extern function start with ex_btc8821a1ant_ + **************************************************************/ +void ex_btc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist, bool wifionly) +{ + btc8821a1ant_init_hw_config(btcoexist, true, wifionly); + btcoexist->auto_report_1ant = true; +} + +void ex_btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Coex Mechanism Init!!\n"); + + btcoexist->stop_coex_dm = false; + + btc8821a1ant_init_coex_dm(btcoexist); + + btc8821a1ant_query_bt_info(btcoexist); +} + +void ex_btc8821a1ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0; + u16 u2_tmp[4]; + u32 u4_tmp[4]; + bool roam = false, scan = false, link = false, wifi_under_5g = false; + bool bt_hs_on = false, wifi_busy = false; + long wifi_rssi = 0, bt_hs_rssi = 0; + u32 wifi_bw, wifi_traffic_dir; + u8 wifi_dot11_chnl, wifi_hs_chnl; + u32 fw_ver = 0, bt_patch_ver = 0; + + seq_puts(m, "\n ============[BT Coexist info]============"); + + if (btcoexist->manual_control) { + seq_puts(m, "\n ============[Under Manual Control]============"); + seq_puts(m, "\n =========================================="); + } + if (btcoexist->stop_coex_dm) { + seq_puts(m, "\n ============[Coex is STOPPED]============"); + seq_puts(m, "\n =========================================="); + } + + seq_printf(m, "\n %-35s = %d/ %d/ %d", + "Ant PG Num/ Ant Mech/ Ant Pos:", + board_info->pg_ant_num, + board_info->btdm_ant_num, + board_info->btdm_ant_pos); + + seq_printf(m, "\n %-35s = %s / %d", "BT stack/ hci ext ver", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, + &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + seq_printf(m, "\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", + "CoexVer/ FwVer/ PatchVer", + glcoex_ver_date_8821a_1ant, + glcoex_ver_8821a_1ant, + fw_ver, bt_patch_ver, + bt_patch_ver); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, + &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, + &wifi_dot11_chnl); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, + &wifi_hs_chnl); + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsChnl(HsMode)", + wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); + + seq_printf(m, "\n %-35s = %3ph ", + "H2C Wifi inform bt chnl Info", + coex_dm->wifi_chnl_info); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + seq_printf(m, "\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", + (int)wifi_rssi, (int)bt_hs_rssi); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan", + link, roam, scan); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, + &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, + &wifi_bw); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, + &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + &wifi_traffic_dir); + seq_printf(m, "\n %-35s = %s / %s/ %s ", "Wifi status", + (wifi_under_5g ? "5G" : "2.4G"), + ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" : + (((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20"))), + ((!wifi_busy) ? "idle" : + ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ? + "uplink" : "downlink"))); + seq_printf(m, "\n %-35s = [%s/ %d/ %d] ", + "BT [status/ rssi/ retryCnt]", + ((coex_sta->bt_disabled) ? ("disabled") : + ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : + ((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == + coex_dm->bt_status) ? + "non-connected idle" : + ((BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == + coex_dm->bt_status) ? + "connected-idle" : "busy")))), + coex_sta->bt_rssi, coex_sta->bt_retry_cnt); + + seq_printf(m, "\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", + bt_link_info->sco_exist, + bt_link_info->hid_exist, + bt_link_info->pan_exist, + bt_link_info->a2dp_exist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); + + bt_info_ext = coex_sta->bt_info_ext; + seq_printf(m, "\n %-35s = %s", + "BT Info A2DP rate", + (bt_info_ext & BIT0) ? + "Basic rate" : "EDR rate"); + + for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + seq_printf(m, "\n %-35s = %7ph(%d)", + glbt_info_src_8821a_1ant[i], + coex_sta->bt_info_c2h[i], + coex_sta->bt_info_c2h_cnt[i]); + } + } + seq_printf(m, "\n %-35s = %s/%s, (0x%x/0x%x)", + "PS state, IPS/LPS, (lps/rpwm)", + ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), + ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")), + btcoexist->bt_info.lps_val, + btcoexist->bt_info.rpwm_val); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); + + if (!btcoexist->manual_control) { + /* Sw mechanism*/ + seq_printf(m, "\n %-35s", + "============[Sw mechanism]============"); + + seq_printf(m, "\n %-35s = %d", "SM[LowPenaltyRA]", + coex_dm->cur_low_penalty_ra); + + seq_printf(m, "\n %-35s = %s/ %s/ %d ", + "DelBA/ BtCtrlAgg/ AggSize", + (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), + (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), + btcoexist->bt_info.agg_buf_size); + seq_printf(m, "\n %-35s = 0x%x ", "Rate Mask", + btcoexist->bt_info.ra_mask); + + /* Fw mechanism */ + seq_printf(m, "\n %-35s", + "============[Fw mechanism]============"); + + ps_tdma_case = coex_dm->cur_ps_tdma; + seq_printf(m, "\n %-35s = %5ph case-%d (auto:%d)", + "PS TDMA", + coex_dm->ps_tdma_para, + ps_tdma_case, + coex_dm->auto_tdma_adjust); + + seq_printf(m, "\n %-35s = 0x%x ", + "Latest error condition(should be 0)", + coex_dm->error_condition); + + seq_printf(m, "\n %-35s = %d ", "IgnWlanAct", + coex_dm->cur_ignore_wlan_act); + } + + /* Hw setting */ + seq_printf(m, "\n %-35s", "============[Hw setting]============"); + + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "backup ARFR1/ARFR2/RL/AMaxTime", + coex_dm->backup_arfr_cnt1, + coex_dm->backup_arfr_cnt2, + coex_dm->backup_retry_limit, + coex_dm->backup_ampdu_max_time); + + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); + u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); + u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); + seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", + "0x430/0x434/0x42a/0x456", + u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]); + + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]", + u1_tmp[0], (u4_tmp[0] & 0x3e000000) >> 25); + + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db); + seq_printf(m, "\n %-35s = 0x%x", "0x8db[6:5]", + ((u1_tmp[0] & 0x60) >> 5)); + + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975); + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]", + (u4_tmp[0] & 0x30000000) >> 28, + u4_tmp[0] & 0xff, + u1_tmp[0] & 0x3); + + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x40/0x4c[24:23]/0x64[0]", + u1_tmp[0], ((u4_tmp[0] & 0x01800000) >> 23), + u1_tmp[1] & 0x1); + + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", + u4_tmp[0], u1_tmp[0]); + + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); + seq_printf(m, "\n %-35s = 0x%x", "0xc50(dig)", + u4_tmp[0] & 0xff); + + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48); + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d); + u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA", + u4_tmp[0], (u1_tmp[0] << 8) + u1_tmp[1]); + + u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); + u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); + u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); + u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", + u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]); + + seq_printf(m, "\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + seq_printf(m, "\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", + coex_sta->low_priority_rx, coex_sta->low_priority_tx); + if (btcoexist->auto_report_1ant) + btc8821a1ant_monitor_bt_ctr(btcoexist); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); +} + +void ex_btc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_under_5g = false; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if (BTC_IPS_ENTER == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS ENTER notify\n"); + coex_sta->under_ips = true; + btc8821a1ant_set_ant_path(btcoexist, + BTC_ANT_PATH_BT, false, true); + /* set PTA control */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + btc8821a1ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + } else if (BTC_IPS_LEAVE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS LEAVE notify\n"); + coex_sta->under_ips = false; + + btc8821a1ant_init_hw_config(btcoexist, false, false); + btc8821a1ant_init_coex_dm(btcoexist); + btc8821a1ant_query_bt_info(btcoexist); + } +} + +void ex_btc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + + if (BTC_LPS_ENABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS ENABLE notify\n"); + coex_sta->under_lps = true; + } else if (BTC_LPS_DISABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS DISABLE notify\n"); + coex_sta->under_lps = false; + } +} + +void ex_btc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false, bt_hs_on = false; + bool bt_ctrl_agg_buf_size = false; + bool wifi_under_5g = false; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + u8 agg_buf_size = 5; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm) + return; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if (type == BTC_SCAN_START) { + coex_sta->wifi_is_high_pri_task = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + + /* Force antenna setup for no scan result issue */ + btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + } + + if (coex_sta->bt_disabled) + return; + + btcoexist->btc_get(btcoexist, + BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + + btc8821a1ant_query_bt_info(btcoexist); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if (num_of_wifi_link >= 2) { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + btc8821a1ant_action_wifi_multi_port(btcoexist); + return; + } + + if (coex_sta->c2h_bt_inquiry_page) { + btc8821a1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + btc8821a1ant_action_hs(btcoexist); + return; + } + + if (BTC_SCAN_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + if (!wifi_connected) { + /* non-connected scan */ + btc8821a1ant_act_wifi_not_conn_scan(btcoexist); + } else { + /* wifi is connected */ + btc8821a1ant_action_wifi_connected_scan(btcoexist); + } + } else if (BTC_SCAN_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + if (!wifi_connected) { + /* non-connected scan */ + btc8821a1ant_action_wifi_not_connected(btcoexist); + } else { + btc8821a1ant_action_wifi_connected(btcoexist); + } + } +} + +void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false, bt_hs_on = false; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + bool bt_ctrl_agg_buf_size = false; + bool wifi_under_5g = false; + u8 agg_buf_size = 5; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if (type == BTC_ASSOCIATE_START) { + coex_sta->wifi_is_high_pri_task = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + coex_dm->arp_cnt = 0; + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); + coex_dm->arp_cnt = 0; + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if (num_of_wifi_link >= 2) { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + btc8821a1ant_action_wifi_multi_port(btcoexist); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + if (coex_sta->c2h_bt_inquiry_page) { + btc8821a1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + btc8821a1ant_action_hs(btcoexist); + return; + } + + if (BTC_ASSOCIATE_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + btc8821a1ant_act_wifi_not_conn_scan(btcoexist); + } else if (BTC_ASSOCIATE_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); + + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + if (!wifi_connected) { + /* non-connected scan */ + btc8821a1ant_action_wifi_not_connected(btcoexist); + } else { + btc8821a1ant_action_wifi_connected(btcoexist); + } + } +} + +void ex_btc8821a1ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[3] = {0}; + u32 wifi_bw; + u8 wifi_central_chnl; + bool wifi_under_5g = false; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if (BTC_MEDIA_CONNECT == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA connect notify\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA disconnect notify\n"); + coex_dm->arp_cnt = 0; + } + + /* only 2.4G we need to inform bt the chnl mask */ + btcoexist->btc_get(btcoexist, + BTC_GET_U1_WIFI_CENTRAL_CHNL, + &wifi_central_chnl); + if ((type == BTC_MEDIA_CONNECT) && + (wifi_central_chnl <= 14)) { + h2c_parameter[0] = 0x0; + h2c_parameter[1] = wifi_central_chnl; + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + } + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x66 = 0x%x\n", + h2c_parameter[0] << 16 | + h2c_parameter[1] << 8 | + h2c_parameter[2]); + + btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool bt_hs_on = false; + bool bt_ctrl_agg_buf_size = false; + bool wifi_under_5g = false; + u32 wifi_link_status = 0; + u32 num_of_wifi_link = 0; + u8 agg_buf_size = 5; + + if (btcoexist->manual_control || btcoexist->stop_coex_dm || + coex_sta->bt_disabled) + return; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || + type == BTC_PACKET_ARP) { + coex_sta->wifi_is_high_pri_task = true; + + if (type == BTC_PACKET_ARP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], specific Packet ARP notify\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], specific Packet DHCP or EAPOL notify\n"); + } + } else { + coex_sta->wifi_is_high_pri_task = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], specific Packet [Type = %d] notify\n", + type); + } + + coex_sta->special_pkt_period_cnt = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + if (num_of_wifi_link >= 2) { + btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); + btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, + bt_ctrl_agg_buf_size, agg_buf_size); + btc8821a1ant_action_wifi_multi_port(btcoexist); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + if (coex_sta->c2h_bt_inquiry_page) { + btc8821a1ant_action_bt_inquiry(btcoexist); + return; + } else if (bt_hs_on) { + btc8821a1ant_action_hs(btcoexist); + return; + } + + if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || + type == BTC_PACKET_ARP) { + if (type == BTC_PACKET_ARP) { + coex_dm->arp_cnt++; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ARP Packet Count = %d\n", + coex_dm->arp_cnt); + if (coex_dm->arp_cnt >= 10) + /* if APR PKT > 10 after connect, do not go to + * btc8821a1ant_act_wifi_conn_sp_pkt + */ + return; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], special Packet(%d) notify\n", type); + btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); + } +} + +void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmp_buf, u8 length) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 i; + u8 bt_info = 0; + u8 rsp_source = 0; + bool wifi_connected = false; + bool bt_busy = false; + bool wifi_under_5g = false; + + coex_sta->c2h_bt_info_req_sent = false; + + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + + rsp_source = tmp_buf[0] & 0xf; + if (rsp_source >= BT_INFO_SRC_8821A_1ANT_MAX) + rsp_source = BT_INFO_SRC_8821A_1ANT_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Bt info[%d], length = %d, hex data = [", + rsp_source, length); + for (i = 0; i < length; i++) { + coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; + if (i == 1) + bt_info = tmp_buf[i]; + if (i == length - 1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x]\n", tmp_buf[i]); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x, ", tmp_buf[i]); + } + } + + if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) { + /* [3:0] */ + coex_sta->bt_retry_cnt = + coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + + coex_sta->bt_rssi = + coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + + coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4]; + + coex_sta->bt_tx_rx_mask = + (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, + &coex_sta->bt_tx_rx_mask); + if (!coex_sta->bt_tx_rx_mask) { + /* BT into is responded by BT FW and BT RF REG 0x3C != + * 0x15 => Need to switch BT TRx Mask + */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n"); + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x3c, 0x15); + } + + /* Here we need to resend some wifi info to BT + * because bt is reset and lost the info + */ + if (coex_sta->bt_info_ext & BIT1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + if (wifi_connected) { + ex_btc8821a1ant_media_status_notify(btcoexist, + BTC_MEDIA_CONNECT); + } else { + ex_btc8821a1ant_media_status_notify(btcoexist, + BTC_MEDIA_DISCONNECT); + } + } + + if ((coex_sta->bt_info_ext & BIT3) && !wifi_under_5g) { + if (!btcoexist->manual_control && + !btcoexist->stop_coex_dm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); + btc8821a1ant_ignore_wlan_act(btcoexist, + FORCE_EXEC, + false); + } + } + } + + /* check BIT2 first ==> check if bt is under inquiry or page scan */ + if (bt_info & BT_INFO_8821A_1ANT_B_INQ_PAGE) + coex_sta->c2h_bt_inquiry_page = true; + else + coex_sta->c2h_bt_inquiry_page = false; + + /* set link exist status */ + if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) { + coex_sta->bt_link_exist = false; + coex_sta->pan_exist = false; + coex_sta->a2dp_exist = false; + coex_sta->hid_exist = false; + coex_sta->sco_exist = false; + } else { + /* connection exists */ + coex_sta->bt_link_exist = true; + if (bt_info & BT_INFO_8821A_1ANT_B_FTP) + coex_sta->pan_exist = true; + else + coex_sta->pan_exist = false; + if (bt_info & BT_INFO_8821A_1ANT_B_A2DP) + coex_sta->a2dp_exist = true; + else + coex_sta->a2dp_exist = false; + if (bt_info & BT_INFO_8821A_1ANT_B_HID) + coex_sta->hid_exist = true; + else + coex_sta->hid_exist = false; + if (bt_info & BT_INFO_8821A_1ANT_B_SCO_ESCO) + coex_sta->sco_exist = true; + else + coex_sta->sco_exist = false; + } + + btc8821a1ant_update_bt_link_info(btcoexist); + + /* mask profile bit for connect-ilde identification + * (for CSR case: A2DP idle --> 0x41) + */ + bt_info = bt_info & 0x1f; + + if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); + } else if (bt_info == BT_INFO_8821A_1ANT_B_CONNECTION) { + /* connection exists but no busy */ + coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); + } else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8821A_1ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); + } else if (bt_info & BT_INFO_8821A_1ANT_B_ACL_BUSY) { + if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) + coex_dm->auto_tdma_adjust = false; + coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_MAX; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); + } + + if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) + bt_busy = true; + else + bt_busy = false; + btcoexist->btc_set(btcoexist, + BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + btc8821a1ant_run_coexist_mechanism(btcoexist); +} + +void ex_btc8821a1ant_halt_notify(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_under_5g = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Halt notify\n"); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + + btcoexist->stop_coex_dm = true; + + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false, true); + btc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); + + ex_btc8821a1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_btc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_under_5g = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); + btc8821a1ant_coex_under_5g(btcoexist); + return; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify\n"); + + if (BTC_WIFI_PNP_SLEEP == pnp_state) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to SLEEP\n"); + /* BT should clear UnderIPS/UnderLPS state to avoid mismatch + * state after wakeup. + */ + coex_sta->under_ips = false; + coex_sta->under_lps = false; + btcoexist->stop_coex_dm = true; + btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false, + true); + } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to WAKE UP\n"); + btcoexist->stop_coex_dm = false; + btc8821a1ant_init_hw_config(btcoexist, false, false); + btc8821a1ant_init_coex_dm(btcoexist); + btc8821a1ant_query_bt_info(btcoexist); + } +} + +void ex_btc8821a1ant_periodical(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static u8 dis_ver_info_cnt; + u32 fw_ver = 0, bt_patch_ver = 0; + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ==========================Periodical===========================\n"); + + if (dis_ver_info_cnt <= 5) { + dis_ver_info_cnt += 1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ****************************************************************\n"); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + board_info->pg_ant_num, + board_info->btdm_ant_num, + board_info->btdm_ant_pos); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT stack/ hci ext ver = %s / %d\n", + stack_info->profile_notified ? "Yes" : "No", + stack_info->hci_version); + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, + &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + glcoex_ver_date_8821a_1ant, + glcoex_ver_8821a_1ant, + fw_ver, bt_patch_ver, + bt_patch_ver); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ****************************************************************\n"); + } + + if (!btcoexist->auto_report_1ant) { + btc8821a1ant_query_bt_info(btcoexist); + btc8821a1ant_monitor_bt_ctr(btcoexist); + } else { + coex_sta->special_pkt_period_cnt++; + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h new file mode 100644 index 000000000..a63fb79a9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2012 Realtek Corporation.*/ + +/*=========================================== + * The following is for 8821A 1ANT BT Co-exist definition + *=========================================== + */ +#define BT_INFO_8821A_1ANT_B_FTP BIT7 +#define BT_INFO_8821A_1ANT_B_A2DP BIT6 +#define BT_INFO_8821A_1ANT_B_HID BIT5 +#define BT_INFO_8821A_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8821A_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8821A_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8821A_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8821A_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0)) ? true : false) + +#define BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT 2 + +enum _BT_INFO_SRC_8821A_1ANT { + BT_INFO_SRC_8821A_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8821A_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8821A_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8821A_1ANT_MAX +}; + +enum _BT_8821A_1ANT_BT_STATUS { + BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8821A_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8821A_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8821A_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8821A_1ANT_BT_STATUS_MAX +}; + +enum _BT_8821A_1ANT_WIFI_STATUS { + BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8821A_1ANT_WIFI_STATUS_MAX +}; + +enum BT_8821A_1ANT_COEX_ALGO { + BT_8821A_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8821A_1ANT_COEX_ALGO_SCO = 0x1, + BT_8821A_1ANT_COEX_ALGO_HID = 0x2, + BT_8821A_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8821A_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8821A_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8821A_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8821A_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8821A_1ANT_COEX_ALGO_MAX = 0xb, +}; + +struct coex_dm_8821a_1ant { + /* fw mechanism */ + bool cur_ignore_wlan_act; + bool pre_ignore_wlan_act; + u8 pre_ps_tdma; + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + u8 tdma_adj_type; + bool auto_tdma_adjust; + bool pre_ps_tdma_on; + bool cur_ps_tdma_on; + bool pre_bt_auto_report; + bool cur_bt_auto_report; + u8 pre_lps; + u8 cur_lps; + u8 pre_rpwm; + u8 cur_rpwm; + + /* sw mechanism */ + bool pre_low_penalty_ra; + bool cur_low_penalty_ra; + u32 pre_val_0x6c0; + u32 cur_val_0x6c0; + u32 pre_val_0x6c4; + u32 cur_val_0x6c4; + u32 pre_val_0x6c8; + u32 cur_val_0x6c8; + u8 pre_val_0x6cc; + u8 cur_val_0x6cc; + /* Auto Rate Fallback Retry cnt */ + u32 backup_arfr_cnt1; + /* Auto Rate Fallback Retry cnt */ + u32 backup_arfr_cnt2; + u16 backup_retry_limit; + u8 backup_ampdu_max_time; + + /* algorithm related */ + u8 pre_algorithm; + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + + u32 pre_ra_mask; + u32 cur_ra_mask; + u8 pre_arfr_type; + u8 cur_arfr_type; + u8 pre_retry_limit_type; + u8 cur_retry_limit_type; + u8 pre_ampdu_time_type; + u8 cur_ampdu_time_type; + u32 arp_cnt; + + u8 error_condition; +}; + +struct coex_sta_8821a_1ant { + bool bt_disabled; + bool bt_link_exist; + bool sco_exist; + bool a2dp_exist; + bool hid_exist; + bool pan_exist; + + bool under_lps; + bool under_ips; + u32 special_pkt_period_cnt; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 bt_rssi; + bool bt_tx_rx_mask; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + bool c2h_bt_info_req_sent; + u8 bt_info_c2h[BT_INFO_SRC_8821A_1ANT_MAX][10]; + u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_1ANT_MAX]; + bool c2h_bt_inquiry_page; + bool wifi_is_high_pri_task; + u8 bt_retry_cnt; + u8 bt_info_ext; +}; + +/*=========================================== + * The following is interface which will notify coex module. + *=========================================== + */ +void ex_btc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist, + bool wifi_only); +void ex_btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_btc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void ex_btc8821a1ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type); +void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmpbuf, u8 length); +void ex_btc8821a1ant_halt_notify(struct btc_coexist *btcoexist); +void ex_btc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate); +void ex_btc8821a1ant_periodical(struct btc_coexist *btcoexist); +void ex_btc8821a1ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m); +void ex_btc8821a1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code, + u8 op_len, u8 *data); +void ex_btc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c new file mode 100644 index 000000000..c5b8df58d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c @@ -0,0 +1,4205 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2012 Realtek Corporation.*/ + +/************************************************************ + * Description: + * + * This file is for RTL8821A Co-exist mechanism + * + * History + * 2012/08/22 Cosa first check in. + * 2012/11/14 Cosa Revise for 8821A 2Ant out sourcing. + * + ************************************************************/ + +/************************************************************ + * include files + ************************************************************/ +#include "halbt_precomp.h" +/************************************************************ + * Global variables, these are static variables + ************************************************************/ +static struct coex_dm_8821a_2ant glcoex_dm_8821a_2ant; +static struct coex_dm_8821a_2ant *coex_dm = &glcoex_dm_8821a_2ant; +static struct coex_sta_8821a_2ant glcoex_sta_8821a_2ant; +static struct coex_sta_8821a_2ant *coex_sta = &glcoex_sta_8821a_2ant; + +static const char *const glbt_info_src_8821a_2ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8821a_2ant = 20130618; +static u32 glcoex_ver_8821a_2ant = 0x5050; + +/************************************************************ + * local function proto type if needed + * + * local function start with btc8821a2ant_ + ************************************************************/ +static u8 btc8821a2ant_bt_rssi_state(struct btc_coexist *btcoexist, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + long bt_rssi = 0; + u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + + bt_rssi = coex_sta->bt_rssi; + + if (level_num == 2) { + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= + rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else { + if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi thresh error!!\n"); + return coex_sta->pre_bt_rssi_state; + } + + if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= + (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Low\n"); + } + } else if ((coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_bt_rssi_state == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (bt_rssi >= + (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { + bt_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to High\n"); + } else if (bt_rssi < rssi_thresh) { + bt_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Low\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at Medium\n"); + } + } else { + if (bt_rssi < rssi_thresh1) { + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state switch to Medium\n"); + } else { + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT Rssi state stay at High\n"); + } + } + } + + coex_sta->pre_bt_rssi_state = bt_rssi_state; + + return bt_rssi_state; +} + +static u8 btc8821a2ant_wifi_rssi_state(struct btc_coexist *btcoexist, + u8 index, u8 level_num, + u8 rssi_thresh, u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + long wifi_rssi = 0; + u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + + if (level_num == 2) { + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= + (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else { + if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI thresh error!!\n"); + return coex_sta->pre_wifi_rssi_state[index]; + } + + if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_LOW) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= + (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Low\n"); + } + } else if ((coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_MEDIUM) || + (coex_sta->pre_wifi_rssi_state[index] == + BTC_RSSI_STATE_STAY_MEDIUM)) { + if (wifi_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to High\n"); + } else if (wifi_rssi < rssi_thresh) { + wifi_rssi_state = BTC_RSSI_STATE_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Low\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at Medium\n"); + } + } else { + if (wifi_rssi < rssi_thresh1) { + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state switch to Medium\n"); + } else { + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi RSSI state stay at High\n"); + } + } + } + coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + + return wifi_rssi_state; +} + +static +void btc8821a2ant_limited_rx(struct btc_coexist *btcoexist, bool force_exec, + bool rej_ap_agg_pkt, bool bt_ctrl_agg_buf_size, + u8 agg_buf_size) +{ + bool reject_rx_agg = rej_ap_agg_pkt; + bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rx_agg_size = agg_buf_size; + + /* Rx Aggregation related setting */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, + &reject_rx_agg); + /* decide BT control aggregation buf size or not */ + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, + &bt_ctrl_rx_agg_size); + /* aggregation buf size, works when BT control Rx aggregation size */ + btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); + /* real update aggregation setting */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +static void btc8821a2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u32 reg_hp_txrx, reg_lp_txrx, u4tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; + + reg_hp_txrx = 0x770; + reg_lp_txrx = 0x774; + + u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); + reg_hp_tx = u4tmp & MASKLWORD; + reg_hp_rx = (u4tmp & MASKHWORD) >> 16; + + u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); + reg_lp_tx = u4tmp & MASKLWORD; + reg_lp_rx = (u4tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + if ((coex_sta->low_priority_rx >= 950) && + (coex_sta->low_priority_rx >= coex_sta->low_priority_tx) && + (!coex_sta->under_ips)) + bt_link_info->slave_role = true; + else + bt_link_info->slave_role = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", + reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", + reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + + /* reset counter */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static void btc8821a2ant_monitor_wifi_ctr(struct btc_coexist *btcoexist) +{ + if (coex_sta->under_ips) { + coex_sta->crc_ok_cck = 0; + coex_sta->crc_ok_11g = 0; + coex_sta->crc_ok_11n = 0; + coex_sta->crc_ok_11n_agg = 0; + + coex_sta->crc_err_cck = 0; + coex_sta->crc_err_11g = 0; + coex_sta->crc_err_11n = 0; + coex_sta->crc_err_11n_agg = 0; + } else { + coex_sta->crc_ok_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf88); + coex_sta->crc_ok_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf94); + coex_sta->crc_ok_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf90); + coex_sta->crc_ok_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfb8); + + coex_sta->crc_err_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf84); + coex_sta->crc_err_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf96); + coex_sta->crc_err_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf92); + coex_sta->crc_err_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfba); + } + + /* reset counter */ + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0); +} + +static void btc8821a2ant_query_bt_info(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + h2c_parameter[0] |= BIT0; /* trigger */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", + h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + +static bool btc8821a2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ + static bool pre_wifi_busy = true; + static bool pre_under_4way = true; + static bool pre_bt_hs_on = true; + bool wifi_busy = false, under_4way = false, bt_hs_on = false; + bool wifi_connected = false; + u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, + &under_4way); + + if (wifi_connected) { + if (wifi_busy != pre_wifi_busy) { + pre_wifi_busy = wifi_busy; + return true; + } + if (under_4way != pre_under_4way) { + pre_under_4way = under_4way; + return true; + } + if (bt_hs_on != pre_bt_hs_on) { + pre_bt_hs_on = bt_hs_on; + return true; + } + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 3, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_LOW)) + return true; + } + + return false; +} + +static void btc8821a2ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + + /* work around for HS mode. */ + if (bt_hs_on) { + bt_link_info->pan_exist = true; + bt_link_info->bt_link_exist = true; + } + + /* check if Sco only */ + if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->sco_only = true; + else + bt_link_info->sco_only = false; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->a2dp_only = true; + else + bt_link_info->a2dp_only = false; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && !bt_link_info->hid_exist) + bt_link_info->pan_only = true; + else + bt_link_info->pan_only = false; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && bt_link_info->hid_exist) + bt_link_info->hid_only = true; + else + bt_link_info->hid_only = false; +} + +static u8 btc8821a2ant_action_algorithm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool bt_hs_on = false; + u8 algorithm = BT_8821A_2ANT_COEX_ALGO_UNDEFINED; + u8 num_of_diff_profile = 0; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + + if (!bt_link_info->bt_link_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], No BT link exists!!!\n"); + return algorithm; + } + + if (bt_link_info->sco_exist) + num_of_diff_profile++; + if (bt_link_info->hid_exist) + num_of_diff_profile++; + if (bt_link_info->pan_exist) + num_of_diff_profile++; + if (bt_link_info->a2dp_exist) + num_of_diff_profile++; + + if (num_of_diff_profile == 1) { + if (bt_link_info->sco_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO only\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], HID only\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], A2DP only\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], PAN(HS) only\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], PAN(EDR) only\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR; + } + } + } + } else if (num_of_diff_profile == 2) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + HID\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else if (bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + A2DP ==> SCO\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else if (bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + PAN(HS)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + PAN(EDR)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], HID + A2DP\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + PAN(HS)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + PAN(EDR)\n"); + algorithm = + BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], A2DP + PAN(HS)\n"); + algorithm = + BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], A2DP + PAN(EDR)\n"); + algorithm = + BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } else if (num_of_diff_profile == 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->a2dp_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCO + HID + A2DP ==> HID\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else if (bt_link_info->hid_exist && + bt_link_info->pan_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + PAN(HS)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + PAN(EDR)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } else if (bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + A2DP + PAN(HS)\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } else { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + A2DP + PAN(HS)\n"); + algorithm = + BT_8821A_2ANT_COEX_ALGO_HID_A2DP; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], HID + A2DP + PAN(EDR)\n"); + algorithm = + BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } else if (num_of_diff_profile >= 3) { + if (bt_link_info->sco_exist) { + if (bt_link_info->hid_exist && + bt_link_info->pan_exist && + bt_link_info->a2dp_exist) { + if (bt_hs_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"); + + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } + } + return algorithm; +} + +static void btc8821a2ant_set_fw_dac_swing_lvl(struct btc_coexist *btcoexist, + u8 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + /* There are several type of dacswing + * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + */ + h2c_parameter[0] = dac_swing_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); +} + +static void btc8821a2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, + u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = dec_bt_pwr_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], decrease Bt Power Level : %u, FW write 0x62 = 0x%x\n", + dec_bt_pwr_lvl, h2c_parameter[0]); + + btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); +} + +static void btc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist, + bool force_exec, u8 dec_bt_pwr_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s Dec BT power level = %u\n", + (force_exec ? "force to" : ""), dec_bt_pwr_lvl); + coex_dm->cur_dec_bt_pwr_lvl = dec_bt_pwr_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_dec_bt_pwr_lvl = %d, cur_dec_bt_pwr_lvl = %d\n", + coex_dm->pre_dec_bt_pwr_lvl, + coex_dm->cur_dec_bt_pwr_lvl); + + if (coex_dm->pre_dec_bt_pwr_lvl == coex_dm->cur_dec_bt_pwr_lvl) + return; + } + btc8821a2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr_lvl); + + coex_dm->pre_dec_bt_pwr_lvl = coex_dm->cur_dec_bt_pwr_lvl; +} + +static void btc8821a2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, + bool force_exec, u8 fw_dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s set FW Dac Swing level = %d\n", + (force_exec ? "force to" : ""), fw_dac_swing_lvl); + coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_fw_dac_swing_lvl = %d, cur_fw_dac_swing_lvl = %d\n", + coex_dm->pre_fw_dac_swing_lvl, + coex_dm->cur_fw_dac_swing_lvl); + + if (coex_dm->pre_fw_dac_swing_lvl == + coex_dm->cur_fw_dac_swing_lvl) + return; + } + + btc8821a2ant_set_fw_dac_swing_lvl(btcoexist, + coex_dm->cur_fw_dac_swing_lvl); + + coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; +} + +static void btc8821a2ant_set_sw_penalty_tx_rate_adaptive( + struct btc_coexist *btcoexist, bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[6] = {0}; + + h2c_parameter[0] = 0x6; /* opCode, 0x6 = Retry_Penalty */ + + if (low_penalty_ra) { + h2c_parameter[1] |= BIT0; + /* normal rate except MCS7/6/5, OFDM54/48/36 */ + h2c_parameter[2] = 0x00; + /* MCS7 or OFDM54 */ + h2c_parameter[3] = 0xf5; + /* MCS6 or OFDM48 */ + h2c_parameter[4] = 0xa0; + /* MCS5 or OFDM36 */ + h2c_parameter[5] = 0xa0; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set WiFi Low-Penalty Retry: %s", + (low_penalty_ra ? "ON!!" : "OFF!!")); + + btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void btc8821a2ant_low_penalty_ra(struct btc_coexist *btcoexist, + bool force_exec, bool low_penalty_ra) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn LowPenaltyRA = %s\n", + (force_exec ? "force to" : ""), + ((low_penalty_ra) ? "ON" : "OFF")); + coex_dm->cur_low_penalty_ra = low_penalty_ra; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_low_penalty_ra = %d, cur_low_penalty_ra = %d\n", + coex_dm->pre_low_penalty_ra, + coex_dm->cur_low_penalty_ra); + + if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) + return; + } + btc8821a2ant_set_sw_penalty_tx_rate_adaptive(btcoexist, + coex_dm->cur_low_penalty_ra); + + coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void btc8821a2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, + u32 level) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 val = (u8)level; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Write SwDacSwing = 0x%x\n", level); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc5b, 0x3e, val); +} + +static void btc8821a2ant_set_sw_full_dac_swing(struct btc_coexist *btcoexist, + bool sw_dac_swing_on, + u32 sw_dac_swing_lvl) +{ + if (sw_dac_swing_on) + btc8821a2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl); + else + btc8821a2ant_set_dac_swing_reg(btcoexist, 0x18); +} + +static void btc8821a2ant_dac_swing(struct btc_coexist *btcoexist, + bool force_exec, bool dac_swing_on, + u32 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn DacSwing = %s, dac_swing_lvl = 0x%x\n", + (force_exec ? "force to" : ""), + ((dac_swing_on) ? "ON" : "OFF"), + dac_swing_lvl); + coex_dm->cur_dac_swing_on = dac_swing_on; + coex_dm->cur_dac_swing_lvl = dac_swing_lvl; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_dac_swing_on = %d, pre_dac_swing_lvl = 0x%x, cur_dac_swing_on = %d, cur_dac_swing_lvl = 0x%x\n", + coex_dm->pre_dac_swing_on, + coex_dm->pre_dac_swing_lvl, + coex_dm->cur_dac_swing_on, + coex_dm->cur_dac_swing_lvl); + + if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && + (coex_dm->pre_dac_swing_lvl == + coex_dm->cur_dac_swing_lvl)) + return; + } + mdelay(30); + btc8821a2ant_set_sw_full_dac_swing(btcoexist, dac_swing_on, + dac_swing_lvl); + + coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; + coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; +} + +static void btc8821a2ant_set_coex_table(struct btc_coexist *btcoexist, + u32 val0x6c0, u32 val0x6c4, + u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); + btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); + btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); + btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); + btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8821a2ant_coex_table(struct btc_coexist *btcoexist, + bool force_exec, u32 val0x6c0, + u32 val0x6c4, u32 val0x6c8, u8 val0x6cc) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", + (force_exec ? "force to" : ""), + val0x6c0, val0x6c4, val0x6c8, val0x6cc); + coex_dm->cur_val0x6c0 = val0x6c0; + coex_dm->cur_val0x6c4 = val0x6c4; + coex_dm->cur_val0x6c8 = val0x6c8; + coex_dm->cur_val0x6cc = val0x6cc; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_val0x6c0 = 0x%x, pre_val0x6c4 = 0x%x, pre_val0x6c8 = 0x%x, pre_val0x6cc = 0x%x !!\n", + coex_dm->pre_val0x6c0, + coex_dm->pre_val0x6c4, + coex_dm->pre_val0x6c8, + coex_dm->pre_val0x6cc); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], cur_val0x6c0 = 0x%x, cur_val0x6c4 = 0x%x, cur_val0x6c8 = 0x%x, cur_val0x6cc = 0x%x !!\n", + coex_dm->cur_val0x6c0, + coex_dm->cur_val0x6c4, + coex_dm->cur_val0x6c8, + coex_dm->cur_val0x6cc); + + if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && + (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && + (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && + (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) + return; + } + btc8821a2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8, + val0x6cc); + + coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; + coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; + coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; + coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void btc8821a2ant_coex_table_with_type(struct btc_coexist *btcoexist, + bool force_exec, u8 type) +{ + coex_sta->coex_table_type = type; + + switch (type) { + case 0: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x55555555, 0xffffff, 0x3); + break; + case 1: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55555555, + 0x5afa5afa, 0xffffff, 0x3); + break; + case 2: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x5ada5ada, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 3: + btc8821a2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + btc8821a2ant_coex_table(btcoexist, force_exec, 0xffffffff, + 0xffffffff, 0xffffff, 0x3); + break; + case 5: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0x5fff5fff, 0xffffff, 0x3); + break; + case 6: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, + 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 8: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, + 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x55dd55dd, + 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 16: + btc8821a2ant_coex_table(btcoexist, force_exec, 0x5fdf5fdf, + 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 17: + btc8821a2ant_coex_table(btcoexist, force_exec, 0xfafafafa, + 0xfafafafa, 0xffffff, 0x3); + break; + default: + break; + } +} + +static void btc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex, + bool enable) +{ + struct rtl_priv *rtlpriv = btcoex->adapter; + u8 h2c_parameter[1] = {0}; + + if (enable) + h2c_parameter[0] |= BIT0; /* function enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", + h2c_parameter[0]); + + btcoex->btc_fill_h2c(btcoex, 0x63, 1, h2c_parameter); +} + +static void btc8821a2ant_set_lps_rpwm(struct btc_coexist *btcoexist, u8 lps_val, + u8 rpwm_val) +{ + u8 lps = lps_val; + u8 rpwm = rpwm_val; + + btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); + btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); +} + +static void btc8821a2ant_lps_rpwm(struct btc_coexist *btcoexist, + bool force_exec, u8 lps_val, u8 rpwm_val) +{ + coex_dm->cur_lps = lps_val; + coex_dm->cur_rpwm = rpwm_val; + + if (!force_exec) { + if ((coex_dm->pre_lps == coex_dm->cur_lps) && + (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) + return; + } + btc8821a2ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); + + coex_dm->pre_lps = coex_dm->cur_lps; + coex_dm->pre_rpwm = coex_dm->cur_rpwm; +} + +static void btc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist, + bool force_exec, bool enable) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn Ignore WlanAct %s\n", + (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); + coex_dm->cur_ignore_wlan_act = enable; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n", + coex_dm->pre_ignore_wlan_act, + coex_dm->cur_ignore_wlan_act); + + if (coex_dm->pre_ignore_wlan_act == + coex_dm->cur_ignore_wlan_act) + return; + } + btc8821a2ant_set_fw_ignore_wlan_act(btcoexist, enable); + + coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8821a2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, + u8 byte1, u8 byte2, u8 byte3, + u8 byte4, u8 byte5) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[5]; + + h2c_parameter[0] = byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = byte5; + + coex_dm->ps_tdma_para[0] = byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = byte5; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n", + h2c_parameter[0], + h2c_parameter[1] << 24 | + h2c_parameter[2] << 16 | + h2c_parameter[3] << 8 | + h2c_parameter[4]); + + btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8821a2ant_sw_mechanism1(struct btc_coexist *btcoexist, + bool shrink_rx_lpf, bool low_penalty_ra, + bool limited_dig, bool bt_lna_constrain) +{ + btc8821a2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void btc8821a2ant_sw_mechanism2(struct btc_coexist *btcoexist, + bool agc_table_shift, bool adc_back_off, + bool sw_dac_swing, u32 dac_swing_lvl) +{ + btc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing, + dac_swing_lvl); +} + +static void btc8821a2ant_set_ant_path(struct btc_coexist *btcoexist, + u8 ant_pos_type, bool init_hw_cfg, + bool wifi_off) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u32 u4tmp = 0; + u8 h2c_parameter[2] = {0}; + + if (init_hw_cfg) { + /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */ + u4tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u4tmp &= ~BIT23; + u4tmp |= BIT24; + btcoexist->btc_write_4byte(btcoexist, 0x4c, u4tmp); + + btcoexist->btc_write_4byte(btcoexist, 0x974, 0x3ff); + + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { + /* tell firmware "antenna inverse" ==> WRONG firmware + * antenna control code ==>need fw to fix + */ + h2c_parameter[0] = 1; + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } else { + /* tell firmware "no antenna inverse" ==> WRONG firmware + * antenna control code ==>need fw to fix + */ + h2c_parameter[0] = 0; + h2c_parameter[1] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, + h2c_parameter); + } + } + + /* ext switch setting */ + switch (ant_pos_type) { + case BTC_ANT_WIFI_AT_MAIN: + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x1); + break; + case BTC_ANT_WIFI_AT_AUX: + btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x2); + break; + } +} + +static void btc8821a2ant_ps_tdma(struct btc_coexist *btcoexist, + bool force_exec, bool turn_on, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + u8 wifi_rssi_state, bt_rssi_state; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, + BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + if (!(BTC_RSSI_HIGH(wifi_rssi_state) && + BTC_RSSI_HIGH(bt_rssi_state)) && + turn_on) { + /* for WiFi RSSI low or BT RSSI low */ + type = type + 100; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], %s turn %s PS TDMA, type = %d\n", + (force_exec ? "force to" : ""), (turn_on ? "ON" : "OFF"), + type); + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + if (!force_exec) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_ps_tdma_on = %d, cur_ps_tdma_on = %d!!\n", + coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_ps_tdma = %d, cur_ps_tdma = %d!!\n", + coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); + + if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && + (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) + return; + } + if (turn_on) { + switch (type) { + case 1: + default: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, 0x90); + break; + case 2: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x2d, + 0x03, 0xf1, 0x90); + break; + case 3: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, 0x90); + break; + case 4: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x03, 0xf1, 0x90); + break; + case 5: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x3, 0x70, 0x90); + break; + case 6: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x2d, + 0x3, 0x70, 0x90); + break; + case 7: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0x70, 0x90); + break; + case 8: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10, + 0x3, 0x70, 0x90); + break; + case 9: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, 0x90); + break; + case 10: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x2d, + 0x03, 0xf1, 0x90); + break; + case 11: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0xf1, 0x90); + break; + case 12: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0xf1, 0x90); + break; + case 13: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x3, 0x70, 0x90); + break; + case 14: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x2d, + 0x3, 0x70, 0x90); + break; + case 15: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, + 0x3, 0x70, 0x90); + break; + case 16: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, + 0x3, 0x70, 0x90); + break; + case 17: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f, + 0x2f, 0x60, 0x90); + break; + case 18: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, 0x5, + 0xe1, 0x90); + break; + case 19: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0xe1, 0x90); + break; + case 20: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, + 0x25, 0x60, 0x90); + break; + case 21: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x03, 0x70, 0x90); + break; + case 23: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1e, + 0x03, 0xf0, 0x14); + break; + case 24: + case 124: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x3c, + 0x03, 0x70, 0x50); + break; + case 25: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x14, + 0x03, 0xf1, 0x90); + break; + case 26: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x30, + 0x03, 0xf1, 0x90); + break; + case 71: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 171: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x3a, + 0x03, 0x70, 0x50); + break; + case 102: + case 106: + case 110: + case 114: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x2d, + 0x03, 0x70, 0x50); + break; + case 103: + case 107: + case 111: + case 115: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1c, + 0x03, 0x70, 0x50); + break; + case 104: + case 108: + case 112: + case 116: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x10, + 0x03, 0x70, 0x50); + break; + case 109: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0xf1, 0x90); + break; + case 113: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x3c, + 0x03, 0x70, 0x90); + break; + case 121: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, + 0x03, 0x70, 0x90); + break; + case 22: + case 122: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x35, + 0x03, 0x71, 0x11); + break; + case 123: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1c, + 0x03, 0x70, 0x54); + break; + case 125: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x14, + 0x03, 0x70, 0x50); + break; + case 126: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x30, + 0x03, 0x70, 0x50); + break; + } + } else { + /* disable PS tdma */ + switch (type) { + case 0: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x40, 0x0); + break; + case 1: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x48, 0x0); + break; + default: + btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, + 0x40, 0x0); + break; + } + } + + /* update pre state */ + coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; + coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static void +btc8821a2ant_ps_tdma_check_for_power_save_state(struct btc_coexist *btcoexist, + bool new_ps_state) +{ + u8 lps_mode = 0x0; + + btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); + + if (lps_mode) { + /* already under LPS state */ + if (new_ps_state) { + /* keep state under LPS, do nothing */ + } else { + /* will leave LPS state, turn off psTdma first */ + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } + } else { + /* NO PS state */ + if (new_ps_state) { + /* will enter LPS state, turn off psTdma first */ + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } else { + /* keep state under NO PS state, do nothing */ + } + } +} + +static void btc8821a2ant_power_save_state(struct btc_coexist *btcoexist, + u8 ps_type, u8 lps_val, u8 rpwm_val) +{ + bool low_pwr_disable = false; + + switch (ps_type) { + case BTC_PS_WIFI_NATIVE: + /* recover to original 32k low power setting */ + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + coex_sta->force_lps_on = false; + break; + case BTC_PS_LPS_ON: + btc8821a2ant_ps_tdma_check_for_power_save_state(btcoexist, + true); + btc8821a2ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, + rpwm_val); + /* when coex force to enter LPS, do not enter 32k low power */ + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + /* power save must executed before psTdma */ + btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); + coex_sta->force_lps_on = true; + break; + case BTC_PS_LPS_OFF: + btc8821a2ant_ps_tdma_check_for_power_save_state(btcoexist, + false); + btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + coex_sta->force_lps_on = false; + break; + default: + break; + } +} + +static void btc8821a2ant_coex_all_off(struct btc_coexist *btcoexist) +{ + /* fw all off */ + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + + /* hw all off */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8821a2ant_coex_under_5g(struct btc_coexist *btcoexist) +{ + btc8821a2ant_coex_all_off(btcoexist); + btc8821a2ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true); +} + +static void btc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + /* force to reset coex mechanism */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, 0); + + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static void btc8821a2ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool wifi_connected = false; + bool low_pwr_disable = true; + bool scan = false, link = false, roam = false; + + btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if (scan || link || roam) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi link process + BT Inq/Page!!\n"); + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + } else if (wifi_connected) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT Inq/Page!!\n"); + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi no-link + BT Inq/Page!!\n"); + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + } + + btc8821a2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static void btc8821a2ant_action_wifi_link_process(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 u8tmpa, u8tmpb; + + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 15); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); + + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + + u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); + u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x76e); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 0x765=0x%x, 0x76e=0x%x\n", u8tmpa, u8tmpb); +} + +static bool btc8821a2ant_action_wifi_idle_process(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 wifi_rssi_state1; + u8 ap_num = 0; + + btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES - 20, 0); + btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); + + /* define the office environment */ + if (BTC_RSSI_HIGH(wifi_rssi_state1) && (coex_sta->hid_exist) && + (coex_sta->a2dp_exist)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi idle process for BT HID+A2DP exist!!\n"); + + btc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, true, 0x6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, + false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, + 0x18); + + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + return true; + } else if (coex_sta->pan_exist) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi idle process for BT PAN exist!!\n"); + + btc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, true, 0x6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, + false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, + 0x18); + + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + return true; + } + btc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, true, 0x18); + return false; +} + +static bool btc8821a2ant_is_common_action(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + bool common = false, wifi_connected = false, wifi_busy = false; + bool low_pwr_disable = false; + bool bt_hs_on = false; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (!wifi_connected) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, + 0x8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi non-connected idle!!\n"); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x0); + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, + false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, + 0x18); + + common = true; + } else { + if (BT_8821A_2ANT_BT_STATUS_IDLE == + coex_dm->bt_status) { + low_pwr_disable = false; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, + false, false, 0x8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT non connected-idle!!\n"); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x0); + btc8821a2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + + btc8821a2ant_power_save_state( + btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 0xb); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + + common = true; + } else if (BT_8821A_2ANT_BT_STATUS_CON_IDLE == + coex_dm->bt_status) { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (bt_hs_on) + return false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi connected + BT connected-idle!!\n"); + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, + false, false, 0x8); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, + 0xfffff, 0x0); + btc8821a2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 0); + + btc8821a2ant_power_save_state( + btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, + 0xb); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + common = true; + } else { + low_pwr_disable = true; + btcoexist->btc_set(btcoexist, + BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + + if (wifi_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Busy + BT Busy!!\n"); + common = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Wifi Connected-Idle + BT Busy!!\n"); + common = + btc8821a2ant_action_wifi_idle_process( + btcoexist); + } + } + } + return common; +} + +static void btc8821a2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, + bool sco_hid, bool tx_pause, + u8 max_interval) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static long up, dn, m, n, wait_count; + /* 0 : no change + * +1: increase WiFi duration + * -1: decrease WiFi duration + */ + int result; + u8 retry_count = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], TdmaDurationAdjust()\n"); + + if (coex_dm->auto_tdma_adjust) { + coex_dm->auto_tdma_adjust = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], first run TdmaDurationAdjust()!!\n"); + if (sco_hid) { + if (tx_pause) { + if (max_interval == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 13); + coex_dm->ps_tdma_du_adj_type = 13; + } else if (max_interval == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } + } else { + if (max_interval == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (max_interval == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } + } + } else { + if (tx_pause) { + if (max_interval == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (max_interval == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } + } else { + if (max_interval == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 1); + coex_dm->ps_tdma_du_adj_type = 1; + } else if (max_interval == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } + } + } + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } else { + /* accquire the BT TRx retry count from BT_Info byte2 */ + retry_count = coex_sta->bt_retry_cnt; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], retry_count = %d\n", retry_count); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], up = %d, dn = %d, m = %d, n = %d, wait_count = %d\n", + (int)up, (int)dn, (int)m, (int)n, (int)wait_count); + result = 0; + wait_count++; + + if (retry_count == 0) { + /* no retry in the last 2-second duration */ + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if (up >= n) { + /* if (retry count == 0) for 2*n seconds, + * make WiFi duration wider + */ + wait_count = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Increase wifi duration!!\n"); + } + } else if (retry_count <= 3) { + /* <=3 retry in the last 2-second duration */ + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) { + /* if retry count < 3 for 2*2 seconds, + * shrink wifi duration + */ + if (wait_count <= 2) + m++; /* avoid bounce in two levels */ + else + m = 1; + /* m max value is 20, max time is 120 second, + * recheck if adjust WiFi duration. + */ + if (m >= 20) + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); + } + } else { + /* retry count > 3, if retry count > 3 happens once, + * shrink WiFi duration + */ + if (wait_count == 1) + m++; /* avoid bounce in two levels */ + else + m = 1; + /* m max value is 20, max time is 120 second, + * recheck if adjust WiFi duration. + */ + if (m >= 20) + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], max Interval = %d\n", max_interval); + + if (max_interval == 1) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 71) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 5); + coex_dm->ps_tdma_du_adj_type = 5; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 13); + coex_dm->ps_tdma_du_adj_type = 13; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 5); + coex_dm->ps_tdma_du_adj_type = + 5; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 13); + coex_dm->ps_tdma_du_adj_type = + 13; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 71); + coex_dm->ps_tdma_du_adj_type = 71; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 9); + coex_dm->ps_tdma_du_adj_type = 9; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + + if (result == -1) { + if (coex_dm->cur_ps_tdma == 71) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = + 1; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 1); + coex_dm->ps_tdma_du_adj_type = + 1; + } else if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 71); + coex_dm->ps_tdma_du_adj_type = + 71; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->ps_tdma_du_adj_type = + 9; + } + } + } + } else if (max_interval == 2) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 6); + coex_dm->ps_tdma_du_adj_type = 6; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 14); + coex_dm->ps_tdma_du_adj_type = 14; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 6); + coex_dm->ps_tdma_du_adj_type = + 6; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->ps_tdma_du_adj_type = + 14; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 2); + coex_dm->ps_tdma_du_adj_type = 2; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 10); + coex_dm->ps_tdma_du_adj_type = 10; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 2); + coex_dm->ps_tdma_du_adj_type = + 2; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 10); + coex_dm->ps_tdma_du_adj_type = + 10; + } + } + } + } else if (max_interval == 3) { + if (tx_pause) { + if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 7); + coex_dm->ps_tdma_du_adj_type = 7; + } else if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 8); + coex_dm->ps_tdma_du_adj_type = 8; + } + if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 15); + coex_dm->ps_tdma_du_adj_type = 15; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 16); + coex_dm->ps_tdma_du_adj_type = 16; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 8); + coex_dm->ps_tdma_du_adj_type = + 8; + } else if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 16); + coex_dm->ps_tdma_du_adj_type = + 16; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 7); + coex_dm->ps_tdma_du_adj_type = + 7; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 15); + coex_dm->ps_tdma_du_adj_type = + 15; + } + } + } else { + if (coex_dm->cur_ps_tdma == 5) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 6) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 7) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 3); + coex_dm->ps_tdma_du_adj_type = 3; + } else if (coex_dm->cur_ps_tdma == 8) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 4); + coex_dm->ps_tdma_du_adj_type = 4; + } + if (coex_dm->cur_ps_tdma == 13) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 14) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 15) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 11); + coex_dm->ps_tdma_du_adj_type = 11; + } else if (coex_dm->cur_ps_tdma == 16) { + btc8821a2ant_ps_tdma(btcoexist, + NORMAL_EXEC, true, 12); + coex_dm->ps_tdma_du_adj_type = 12; + } + if (result == -1) { + if (coex_dm->cur_ps_tdma == 1) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 4); + coex_dm->ps_tdma_du_adj_type = + 4; + } else if (coex_dm->cur_ps_tdma == 9) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 12); + coex_dm->ps_tdma_du_adj_type = + 12; + } + } else if (result == 1) { + if (coex_dm->cur_ps_tdma == 4) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 3) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 2) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 3); + coex_dm->ps_tdma_du_adj_type = + 3; + } else if (coex_dm->cur_ps_tdma == 12) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 11) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } else if (coex_dm->cur_ps_tdma == 10) { + btc8821a2ant_ps_tdma( + btcoexist, NORMAL_EXEC, + true, 11); + coex_dm->ps_tdma_du_adj_type = + 11; + } + } + } + } + } + + /* if current PsTdma not match with the recorded one + * (when scan, dhcp...), then we have to adjust it back to + * the previous recorded one. + */ + if (coex_dm->cur_ps_tdma != coex_dm->ps_tdma_du_adj_type) { + bool scan = false, link = false, roam = false; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], PsTdma type mismatch!!!, cur_ps_tdma = %d, recordPsTdma = %d\n", + coex_dm->cur_ps_tdma, coex_dm->ps_tdma_du_adj_type); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (!scan && !link && !roam) { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, + coex_dm->ps_tdma_du_adj_type); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"); + } + } +} + +/* SCO only or SCO+PAN(HS)*/ +static void btc8821a2ant_action_sco(struct btc_coexist *btcoexist) +{ + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + u8 wifi_rssi_state, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + /* for SCO quality at 11b/g mode */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } else { + /* for SCO quality & wifi performance balance at 11n mode */ + if (wifi_bw == BTC_WIFI_BW_HT40) { + btc8821a2ant_coex_table_with_type(btcoexist, + NORMAL_EXEC, 8); + } else { + if (bt_link_info->sco_only) + btc8821a2ant_coex_table_with_type( + btcoexist, NORMAL_EXEC, 17); + else + btc8821a2ant_coex_table_with_type( + btcoexist, NORMAL_EXEC, 12); + } + } + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + /* for voice quality */ + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + + /* sw mechanism */ + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + true, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + true, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + true, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + true, 0x18); + } + } +} + +static void btc8821a2ant_action_hid(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + /* for HID at 11b/g mode */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + } else { + /* for HID quality & wifi performance balance at 11n mode */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); + } + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 24); + + if (wifi_bw == BTC_WIFI_BW_HT40) { + /* sw mechanism */ + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + /* sw mechanism */ + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ +static void btc8821a2ant_action_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; + u8 ap_num = 0; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + if ((ap_num >= 10) && BTC_RSSI_HIGH(wifi_rssi_state1) && + BTC_RSSI_HIGH(bt_rssi_state)) { + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, + 0x0); + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, + 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + true, 0x6); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + true, 0x6); + } + return; + } + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + /* preserve identical branches for further fine-tuning */ + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + } else { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + } + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + btc8821a2ant_tdma_duration_adjust(btcoexist, false, true, 2); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 10); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + /* preserve identical branches for further fine-tuning */ + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 26); + else + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 26); + + /* sw mechanism */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* PAN(HS) only */ +static void btc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* PAN(EDR)+A2DP */ +static void btc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + else + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 12); + + if (wifi_bw == BTC_WIFI_BW_HT40) + btc8821a2ant_tdma_duration_adjust(btcoexist, false, + true, 3); + else + btc8821a2ant_tdma_duration_adjust(btcoexist, false, + false, 3); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 13); + btc8821a2ant_tdma_duration_adjust(btcoexist, false, true, 3); + } + + /* sw mechanism */ + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, false, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + /* preserve identical branches for further fine-tuning */ + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + /* for HID at 11b/g mode */ + btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, + 0x5a5f5a5f, 0xffff, 0x3); + } else { + /* for HID quality & wifi performance balance at 11n mode */ + btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, + 0x5a5f5a5f, 0xffff, 0x3); + } + + if (wifi_bw == BTC_WIFI_BW_HT40) { + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 3); + /* fw mechanism */ + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 10); + } else { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + } + + /* sw mechanism */ + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + /* fw mechanism */ + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); + } else { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); + } + + /* sw mechanism */ + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +/* HID+A2DP+PAN(EDR) */ +static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ + u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; + u32 wifi_bw; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + wifi_rssi_state1 = btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifi_rssi_state1) && BTC_RSSI_HIGH(bt_rssi_state)) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 14); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + if (wifi_bw == BTC_WIFI_BW_HT40) + btc8821a2ant_tdma_duration_adjust(btcoexist, true, + true, 3); + else + btc8821a2ant_tdma_duration_adjust(btcoexist, true, + false, 3); + } else { + btc8821a2ant_tdma_duration_adjust(btcoexist, true, true, 3); + } + + /* sw mechanism */ + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ + u32 wifi_bw; + u8 wifi_rssi_state, bt_rssi_state; + u8 ap_num = 0; + + wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0); + btc8821a2ant_wifi_rssi_state(btcoexist, 1, 2, + BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, + 3, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 37); + + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true, 0x5); + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + if (BTC_RSSI_HIGH(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else if (BTC_RSSI_MEDIUM(bt_rssi_state)) + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + else + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } else { + /* only 802.11N mode we have to dec bt power to 4 degree */ + if (BTC_RSSI_HIGH(bt_rssi_state)) { + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, + &ap_num); + if (ap_num < 10) + btc8821a2ant_dec_bt_pwr(btcoexist, + NORMAL_EXEC, 4); + else + btc8821a2ant_dec_bt_pwr(btcoexist, + NORMAL_EXEC, 2); + } else if (BTC_RSSI_MEDIUM(bt_rssi_state)) { + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2); + } else { + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + } + } + + if (wifi_bw == BTC_WIFI_BW_LEGACY) { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, + 0x0, 0x0); + } else { + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 14); + btc8821a2ant_power_save_state(btcoexist, BTC_PS_LPS_ON, 0x50, + 0x4); + } + + /* preserve identical branches for further fine-tuning */ + if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || + (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + } else { + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 23); + } + + /* sw mechanism */ + if (wifi_bw == BTC_WIFI_BW_HT40) { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, true, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } else { + if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || + (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, true, false, + false, 0x18); + } else { + btc8821a2ant_sw_mechanism1(btcoexist, false, true, + false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, + false, 0x18); + } + } +} + +static void btc8821a2ant_action_wifi_multi_port(struct btc_coexist *btcoexist) +{ + btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0); + + /* sw all off */ + btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false); + btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + + /* hw all off */ + btc8821a2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); + + btc8821a2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +} + +static void btc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; + bool wifi_under_5g = false; + u8 algorithm = 0; + u32 num_of_wifi_link = 0; + u32 wifi_link_status = 0; + bool miracast_plus_bt = false; + bool scan = false, link = false, roam = false; + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Manual control!!!\n"); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + + if (wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n"); + btc8821a2ant_coex_under_5g(btcoexist); + return; + } + + if (coex_sta->under_ips) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], wifi is under IPS !!!\n"); + return; + } + + algorithm = btc8821a2ant_action_algorithm(btcoexist); + if (coex_sta->c2h_bt_inquiry_page && + (BT_8821A_2ANT_COEX_ALGO_PANHS != algorithm)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT is under inquiry/page scan !!\n"); + btc8821a2ant_action_bt_inquiry(btcoexist); + return; + } + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + + if (scan || link || roam) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], WiFi is under Link Process !!\n"); + btc8821a2ant_action_wifi_link_process(btcoexist); + return; + } + + /* for P2P */ + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, + &wifi_link_status); + num_of_wifi_link = wifi_link_status >> 16; + + if ((num_of_wifi_link >= 2) || + (wifi_link_status & WIFI_P2P_GO_CONNECTED)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "############# [BTCoex], Multi-Port num_of_wifi_link = %d, wifi_link_status = 0x%x\n", + num_of_wifi_link, wifi_link_status); + + if (bt_link_info->bt_link_exist) + miracast_plus_bt = true; + else + miracast_plus_bt = false; + + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + btc8821a2ant_action_wifi_multi_port(btcoexist); + + return; + } + + miracast_plus_bt = false; + btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + + coex_dm->cur_algorithm = algorithm; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm); + + if (btc8821a2ant_is_common_action(btcoexist)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant common\n"); + coex_dm->auto_tdma_adjust = true; + } else { + if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], pre_algorithm = %d, cur_algorithm = %d\n", + coex_dm->pre_algorithm, + coex_dm->cur_algorithm); + coex_dm->auto_tdma_adjust = false; + } + switch (coex_dm->cur_algorithm) { + case BT_8821A_2ANT_COEX_ALGO_SCO: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = SCO\n"); + btc8821a2ant_action_sco(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID\n"); + btc8821a2ant_action_hid(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = A2DP\n"); + btc8821a2ant_action_a2dp(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS)\n"); + btc8821a2ant_action_a2dp_pan_hs(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)\n"); + btc8821a2ant_action_pan_edr(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANHS: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HS mode\n"); + btc8821a2ant_action_pan_hs(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP\n"); + btc8821a2ant_action_pan_edr_a2dp(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR_HID: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID\n"); + btc8821a2ant_action_pan_edr_hid(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN\n"); + btc8821a2ant_act_hid_a2dp_pan_edr(btcoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID_A2DP: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP\n"); + btc8821a2ant_action_hid_a2dp(btcoexist); + break; + default: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"); + btc8821a2ant_coex_all_off(btcoexist); + break; + } + coex_dm->pre_algorithm = coex_dm->cur_algorithm; + } +} + +static void btc8821a2ant_wifi_off_hw_cfg(struct btc_coexist *btcoexist) +{ + u8 h2c_parameter[2] = {0}; + u32 fw_ver = 0; + + /* set wlan_act to low */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + + /* WiFi goto standby while GNT_BT 0-->1 */ + btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + if (fw_ver >= 0x180000) { + /* Use H2C to set GNT_BT to HIGH */ + h2c_parameter[0] = 1; + btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, h2c_parameter); + } else { + btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); + } +} + +/************************************************************** + * extern function start with ex_btc8821a2ant_ + **************************************************************/ +void ex_btc8821a2ant_init_hwconfig(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 u1tmp = 0; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], 2Ant Init HW Config!!\n"); + + /* backup rf 0x1e value */ + coex_dm->bt_rf0x1e_backup = + btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff); + + /* 0x790[5:0] = 0x5 */ + u1tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); + u1tmp &= 0xc0; + u1tmp |= 0x5; + btcoexist->btc_write_1byte(btcoexist, 0x790, u1tmp); + + /* Antenna config */ + btc8821a2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN, true, false); + coex_sta->dis_ver_info_cnt = 0; + + /* PTA parameter */ + btc8821a2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); + + /* Enable counter statistics */ + /* 0x76e[3] = 1, WLAN_Act control by PTA */ + btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); + btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); + btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); +} + +void ex_btc8821a2ant_pre_load_firmware(struct btc_coexist *btcoexist) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */ + + /** + * S0 or S1 setting and Local register setting(By the setting fw can get + * ant number, S0/S1, ... info) + * + * Local setting bit define + * BIT0: "0" for no antenna inverse; "1" for antenna inverse + * BIT1: "0" for internal switch; "1" for external switch + * BIT2: "0" for one antenna; "1" for two antenna + * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and + * BIT2=0 + */ + if (btcoexist->chip_interface == BTC_INTF_USB) { + /* fixed at S0 for USB interface */ + u8tmp |= 0x1; /* antenna inverse */ + btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp); + } else { + /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ + if (board_info->single_ant_path == 0) { + } else if (board_info->single_ant_path == 1) { + /* set to S0 */ + u8tmp |= 0x1; /* antenna inverse */ + } + + if (btcoexist->chip_interface == BTC_INTF_PCI) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384, + u8tmp); + else if (btcoexist->chip_interface == BTC_INTF_SDIO) + btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, + u8tmp); + } +} + +void ex_btc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Coex Mechanism Init!!\n"); + + btc8821a2ant_init_coex_dm(btcoexist); +} + +void ex_btc8821a2ant_display_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct btc_board_info *board_info = &btcoexist->board_info; + struct btc_stack_info *stack_info = &btcoexist->stack_info; + u8 u1tmp[4], i, bt_info_ext, ps_tdma_case = 0; + u32 u4tmp[4]; + bool roam = false, scan = false, link = false, wifi_under_5g = false; + bool bt_hs_on = false, wifi_busy = false; + long wifi_rssi = 0, bt_hs_rssi = 0; + u32 wifi_bw, wifi_traffic_dir; + u8 wifi_dot_11_chnl, wifi_hs_chnl; + u32 fw_ver = 0, bt_patch_ver = 0; + + seq_puts(m, "\n ============[BT Coexist info]============"); + + seq_printf(m, "\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", + board_info->pg_ant_num, board_info->btdm_ant_num); + + if (btcoexist->manual_control) { + seq_printf(m, "\n %-35s", "[Action Manual control]!!"); + } + + seq_printf(m, "\n %-35s = %s / %d", "BT stack/ hci ext ver", + ((stack_info->profile_notified) ? "Yes" : "No"), + stack_info->hci_version); + + btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + seq_printf(m, "\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", + "CoexVer/ FwVer/ PatchVer", + glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant, + fw_ver, bt_patch_ver, bt_patch_ver); + + btcoexist->btc_get(btcoexist, + BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, + BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_dot_11_chnl); + btcoexist->btc_get(btcoexist, + BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsMode(HsChnl)", + wifi_dot_11_chnl, bt_hs_on, wifi_hs_chnl); + + seq_printf(m, "\n %-35s = %3ph ", + "H2C Wifi inform bt chnl Info", + coex_dm->wifi_chnl_info); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + seq_printf(m, "\n %-35s = %ld/ %ld", "Wifi rssi/ HS rssi", + wifi_rssi, bt_hs_rssi); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan", + link, roam, scan); + + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + btcoexist->btc_get(btcoexist, + BTC_GET_U4_WIFI_BW, &wifi_bw); + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, + BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifi_traffic_dir); + seq_printf(m, "\n %-35s = %s / %s/ %s ", "Wifi status", + (wifi_under_5g ? "5G" : "2.4G"), + ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : + (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), + ((!wifi_busy) ? "idle" : + ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? + "uplink" : "downlink"))); + + if (stack_info->profile_notified) { + seq_printf(m, "\n %-35s = %d / %d / %d / %d", + "SCO/HID/PAN/A2DP", + stack_info->sco_exist, stack_info->hid_exist, + stack_info->pan_exist, stack_info->a2dp_exist); + + btcoexist->btc_disp_dbg_msg(btcoexist, + BTC_DBG_DISP_BT_LINK_INFO, + m); + } + + bt_info_ext = coex_sta->bt_info_ext; + seq_printf(m, "\n %-35s = %s", "BT Info A2DP rate", + (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); + + for (i = 0; i < BT_INFO_SRC_8821A_2ANT_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + seq_printf(m, "\n %-35s = %7ph(%d)", + glbt_info_src_8821a_2ant[i], + coex_sta->bt_info_c2h[i], + coex_sta->bt_info_c2h_cnt[i]); + } + } + + seq_printf(m, "\n %-35s = %s/%s", + "PS state, IPS/LPS", + ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), + ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); + + /* Sw mechanism*/ + seq_printf(m, "\n %-35s", + "============[Sw mechanism]============"); + seq_printf(m, "\n %-35s = %d/ %d/ %d(0x%x) ", + "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", + coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, + coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); + + /* Fw mechanism*/ + seq_printf(m, "\n %-35s", + "============[Fw mechanism]============"); + + if (!btcoexist->manual_control) { + ps_tdma_case = coex_dm->cur_ps_tdma; + seq_printf(m, "\n %-35s = %5ph case-%d", + "PS TDMA", + coex_dm->ps_tdma_para, ps_tdma_case); + + seq_printf(m, "\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", + coex_dm->cur_dec_bt_pwr_lvl, + coex_dm->cur_ignore_wlan_act); + } + + /* Hw setting*/ + seq_printf(m, "\n %-35s", "============[Hw setting]============"); + + seq_printf(m, "\n %-35s = 0x%x", "RF-A, 0x1e initVal", + coex_dm->bt_rf0x1e_backup); + + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); + u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x ", + "0x778 (W_Act)/ 0x6cc (CoTab Sel)", + u1tmp[0], u1tmp[1]); + + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db); + u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xc5b); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x8db(ADC)/0xc5b[29:25](DAC)", + ((u1tmp[0] & 0x60) >> 5), ((u1tmp[1] & 0x3e) >> 1)); + + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)", + u4tmp[0] & 0xff, ((u4tmp[0] & 0x30000000) >> 28)); + + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); + u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x974); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x40/ 0x4c[24:23]/ 0x974", + u1tmp[0], ((u4tmp[0] & 0x01800000) >> 23), u4tmp[1]); + + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0x550(bcn ctrl)/0x522", + u4tmp[0], u1tmp[0]); + + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa0a); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "0xc50(DIG)/0xa0a(CCK-TH)", + u4tmp[0], u1tmp[0]); + + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48); + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); + u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x", + "OFDM-FA/ CCK-FA", + u4tmp[0], (u1tmp[0] << 8) + u1tmp[1]); + + u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); + u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); + u4tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); + seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", + "0x6c0/0x6c4/0x6c8", + u4tmp[0], u4tmp[1], u4tmp[2]); + + seq_printf(m, "\n %-35s = %d/ %d", + "0x770 (hi-pri Rx/Tx)", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + seq_printf(m, "\n %-35s = %d/ %d", + "0x774(low-pri Rx/Tx)", + coex_sta->low_priority_rx, coex_sta->low_priority_tx); + + /* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang*/ + u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x41b); + seq_printf(m, "\n %-35s = 0x%x", + "0x41b (mgntQ hang chk == 0xf)", + u1tmp[0]); + + btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); +} + +void ex_btc8821a2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_IPS_ENTER == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS ENTER notify\n"); + coex_sta->under_ips = true; + btc8821a2ant_wifi_off_hw_cfg(btcoexist); + btc8821a2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + btc8821a2ant_coex_all_off(btcoexist); + } else if (BTC_IPS_LEAVE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], IPS LEAVE notify\n"); + coex_sta->under_ips = false; + ex_btc8821a2ant_init_hwconfig(btcoexist); + btc8821a2ant_init_coex_dm(btcoexist); + btc8821a2ant_query_bt_info(btcoexist); + } +} + +void ex_btc8821a2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_LPS_ENABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS ENABLE notify\n"); + coex_sta->under_lps = true; + } else if (BTC_LPS_DISABLE == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], LPS DISABLE notify\n"); + coex_sta->under_lps = false; + } +} + +void ex_btc8821a2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_SCAN_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN START notify\n"); + } else if (BTC_SCAN_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], SCAN FINISH notify\n"); + } +} + +void ex_btc8821a2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (BTC_ASSOCIATE_START == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT START notify\n"); + } else if (BTC_ASSOCIATE_FINISH == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], CONNECT FINISH notify\n"); + } +} + +void ex_btc8821a2ant_media_status_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 h2c_parameter[3] = {0}; + u32 wifi_bw; + u8 wifi_central_chnl; + u8 ap_num = 0; + + if (BTC_MEDIA_CONNECT == type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA connect notify\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], MEDIA disconnect notify\n"); + } + + /* only 2.4G we need to inform bt the chnl mask */ + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, + &wifi_central_chnl); + if ((BTC_MEDIA_CONNECT == type) && + (wifi_central_chnl <= 14)) { + h2c_parameter[0] = 0x1; + h2c_parameter[1] = wifi_central_chnl; + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + if (wifi_bw == BTC_WIFI_BW_HT40) { + h2c_parameter[2] = 0x30; + } else { + h2c_parameter[2] = 0x20; + if (ap_num < 10) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + } + } + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], FW write 0x66 = 0x%x\n", + h2c_parameter[0] << 16 | + h2c_parameter[1] << 8 | + h2c_parameter[2]); + + btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_btc8821a2ant_special_packet_notify(struct btc_coexist *btcoexist, + u8 type) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (type == BTC_PACKET_DHCP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], DHCP Packet notify\n"); + } +} + +void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmp_buf, u8 length) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 bt_info = 0; + u8 i, rsp_source = 0; + bool bt_busy = false, limited_dig = false; + bool wifi_connected = false, wifi_under_5g = false; + + coex_sta->c2h_bt_info_req_sent = false; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, + &wifi_connected); + + rsp_source = tmp_buf[0] & 0xf; + if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX) + rsp_source = BT_INFO_SRC_8821A_2ANT_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Bt info[%d], length = %d, hex data = [", + rsp_source, length); + for (i = 0; i < length; i++) { + coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; + if (i == 1) + bt_info = tmp_buf[i]; + if (i == length - 1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x]\n", tmp_buf[i]); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "0x%02x, ", tmp_buf[i]); + } + } + + if (btcoexist->manual_control) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n"); + return; + } + + if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) { + /* [3:0] */ + coex_sta->bt_retry_cnt = + coex_sta->bt_info_c2h[rsp_source][2]&0xf; + + coex_sta->bt_rssi = + coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + + coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4]; + + coex_sta->bt_tx_rx_mask = + (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, + &coex_sta->bt_tx_rx_mask); + if (coex_sta->bt_tx_rx_mask) { + /* BT into is responded by BT FW and BT RF REG 0x3C != + * 0x01 => Need to switch BT TRx Mask + */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x01\n"); + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x3c, 0x01); + } + + /* Here we need to resend some wifi info to BT + * because bt is reset and loss of the info + */ + if ((coex_sta->bt_info_ext & BIT1)) { + btcoexist->btc_get(btcoexist, + BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + if (wifi_connected) { + ex_btc8821a2ant_media_status_notify(btcoexist, + BTC_MEDIA_CONNECT); + } else { + ex_btc8821a2ant_media_status_notify(btcoexist, + BTC_MEDIA_DISCONNECT); + } + + } + + if (!btcoexist->manual_control && !wifi_under_5g) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info = 0x%x!!\n", + coex_sta->bt_info_ext); + if ((coex_sta->bt_info_ext & BIT(3))) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit3=1, wifi_connected=%d\n", + wifi_connected); + if (wifi_connected) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); + btc8821a2ant_ignore_wlan_act(btcoexist, + FORCE_EXEC, + false); + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BT ext info bit3=0, wifi_connected=%d\n", + wifi_connected); + /* BT already NOT ignore Wlan active, do nothing + * here. + */ + if (!wifi_connected) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_LOUD, + "[BTCoex], BT ext info bit3 check, set BT to ignore Wlan active!!\n"); + btc8821a2ant_ignore_wlan_act( + btcoexist, FORCE_EXEC, true); + } + } + } + } + + /* check BIT2 first ==> check if bt is under inquiry or page scan*/ + if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) { + coex_sta->c2h_bt_inquiry_page = true; + } else { + coex_sta->c2h_bt_inquiry_page = false; + } + /* set link exist status */ + if (!(bt_info & BT_INFO_8821A_2ANT_B_CONNECTION)) { + coex_sta->bt_link_exist = false; + coex_sta->pan_exist = false; + coex_sta->a2dp_exist = false; + coex_sta->hid_exist = false; + coex_sta->sco_exist = false; + } else { /* connection exists */ + coex_sta->bt_link_exist = true; + if (bt_info & BT_INFO_8821A_2ANT_B_FTP) + coex_sta->pan_exist = true; + else + coex_sta->pan_exist = false; + if (bt_info & BT_INFO_8821A_2ANT_B_A2DP) + coex_sta->a2dp_exist = true; + else + coex_sta->a2dp_exist = false; + if (bt_info & BT_INFO_8821A_2ANT_B_HID) + coex_sta->hid_exist = true; + else + coex_sta->hid_exist = false; + if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO) + coex_sta->sco_exist = true; + else + coex_sta->sco_exist = false; + + if ((!coex_sta->hid_exist) && + (!coex_sta->c2h_bt_inquiry_page) && + (!coex_sta->sco_exist)) { + if (coex_sta->high_priority_tx + + coex_sta->high_priority_rx >= 160) + coex_sta->hid_exist = true; + } + } + + btc8821a2ant_update_bt_link_info(btcoexist); + + if (!(bt_info & BT_INFO_8821A_2ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); + } else if (bt_info == BT_INFO_8821A_2ANT_B_CONNECTION) { + /* connection exists but no busy */ + coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); + } else if ((bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8821A_2ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_SCO_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); + } else if (bt_info & BT_INFO_8821A_2ANT_B_ACL_BUSY) { + coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_ACL_BUSY; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_MAX; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); + } + + if ((coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_ACL_BUSY) || + (coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_SCO_BUSY) || + (coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY)) { + bt_busy = true; + limited_dig = true; + } else { + bt_busy = false; + limited_dig = false; + } + + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + + coex_dm->limited_dig = limited_dig; + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); + + btc8821a2ant_run_coexist_mechanism(btcoexist); +} + +void ex_btc8821a2ant_halt_notify(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Halt notify\n"); + + btc8821a2ant_wifi_off_hw_cfg(btcoexist); + btc8821a2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); + ex_btc8821a2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_btc8821a2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n"); + + if (pnp_state == BTC_WIFI_PNP_SLEEP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to SLEEP\n"); + } else if (pnp_state == BTC_WIFI_PNP_WAKE_UP) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Pnp notify to WAKE UP\n"); + ex_btc8821a2ant_init_hwconfig(btcoexist); + btc8821a2ant_init_coex_dm(btcoexist); + btc8821a2ant_query_bt_info(btcoexist); + } +} + +void ex_btc8821a2ant_periodical(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], ==========================Periodical===========================\n"); + + if (coex_sta->dis_ver_info_cnt <= 5) { + coex_sta->dis_ver_info_cnt += 1; + if (coex_sta->dis_ver_info_cnt == 3) { + /* Antenna config to set 0x765 = 0x0 (GNT_BT control by + * PTA) after initial + */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Set GNT_BT control by PTA\n"); + btc8821a2ant_set_ant_path(btcoexist, + BTC_ANT_WIFI_AT_MAIN, false, false); + } + } + + if (btcoexist->auto_report_2ant) { + btc8821a2ant_query_bt_info(btcoexist); + } else { + btc8821a2ant_monitor_bt_ctr(btcoexist); + btc8821a2ant_monitor_wifi_ctr(btcoexist); + + if (btc8821a2ant_is_wifi_status_changed(btcoexist) || + coex_dm->auto_tdma_adjust) + btc8821a2ant_run_coexist_mechanism(btcoexist); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h new file mode 100644 index 000000000..3df0ee8bd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2012 Realtek Corporation.*/ + +/*=========================================== + * The following is for 8821A 2Ant BT Co-exist definition + *=========================================== +*/ +#define BT_INFO_8821A_2ANT_B_FTP BIT7 +#define BT_INFO_8821A_2ANT_B_A2DP BIT6 +#define BT_INFO_8821A_2ANT_B_HID BIT5 +#define BT_INFO_8821A_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8821A_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8821A_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8821A_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8821A_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT 2 + +/* WiFi RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation */ +#define BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES 42 +/* BT RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation */ +#define BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES 46 + +enum _BT_INFO_SRC_8821A_2ANT { + BT_INFO_SRC_8821A_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8821A_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8821A_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8821A_2ANT_MAX +}; + +enum _BT_8821A_2ANT_BT_STATUS { + BT_8821A_2ANT_BT_STATUS_IDLE = 0x0, + BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1, + BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8821A_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8821A_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8821A_2ANT_BT_STATUS_MAX +}; + +enum _BT_8821A_2ANT_COEX_ALGO { + BT_8821A_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8821A_2ANT_COEX_ALGO_SCO = 0x1, + BT_8821A_2ANT_COEX_ALGO_HID = 0x2, + BT_8821A_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8821A_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8821A_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8821A_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8821A_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8821A_2ANT_COEX_ALGO_MAX = 0xb, +}; + +struct coex_dm_8821a_2ant { + /* fw mechanism */ + bool pre_dec_bt_pwr_lvl; + bool cur_dec_bt_pwr_lvl; + u8 pre_fw_dac_swing_lvl; + u8 cur_fw_dac_swing_lvl; + bool cur_ignore_wlan_act; + bool pre_ignore_wlan_act; + u8 pre_ps_tdma; + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + u8 ps_tdma_du_adj_type; + bool reset_tdma_adjust; + bool auto_tdma_adjust; + bool pre_ps_tdma_on; + bool cur_ps_tdma_on; + bool pre_bt_auto_report; + bool cur_bt_auto_report; + + /* sw mechanism */ + bool pre_rf_rx_lpf_shrink; + bool cur_rf_rx_lpf_shrink; + u32 bt_rf0x1e_backup; + bool pre_low_penalty_ra; + bool cur_low_penalty_ra; + bool pre_dac_swing_on; + u32 pre_dac_swing_lvl; + bool cur_dac_swing_on; + u32 cur_dac_swing_lvl; + bool pre_adc_back_off; + bool cur_adc_back_off; + bool pre_agc_table_en; + bool cur_agc_table_en; + u32 pre_val0x6c0; + u32 cur_val0x6c0; + u32 pre_val0x6c4; + u32 cur_val0x6c4; + u32 pre_val0x6c8; + u32 cur_val0x6c8; + u8 pre_val0x6cc; + u8 cur_val0x6cc; + bool limited_dig; + + /* algorithm related */ + u8 pre_algorithm; + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + u8 pre_lps; + u8 cur_lps; + u8 pre_rpwm; + u8 cur_rpwm; +}; + +struct coex_sta_8821a_2ant { + bool bt_link_exist; + bool sco_exist; + bool a2dp_exist; + bool hid_exist; + bool pan_exist; + bool under_lps; + bool under_ips; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 bt_rssi; + bool bt_tx_rx_mask; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + bool c2h_bt_info_req_sent; + u8 bt_info_c2h[BT_INFO_SRC_8821A_2ANT_MAX][10]; + u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_2ANT_MAX]; + bool c2h_bt_inquiry_page; + u8 bt_retry_cnt; + u8 bt_info_ext; + + u32 crc_ok_cck; + u32 crc_ok_11g; + u32 crc_ok_11n; + u32 crc_ok_11n_agg; + + u32 crc_err_cck; + u32 crc_err_11g; + u32 crc_err_11n; + u32 crc_err_11n_agg; + + u8 coex_table_type; + bool force_lps_on; + + u8 dis_ver_info_cnt; +}; + +/*=========================================== + * The following is interface which will notify coex module. + *=========================================== + */ +void +ex_btc8821a2ant_init_hwconfig( + struct btc_coexist *btcoexist + ); +void +ex_btc8821a2ant_init_coex_dm( + struct btc_coexist *btcoexist + ); +void +ex_btc8821a2ant_ips_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_lps_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_scan_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_connect_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_media_status_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_special_packet_notify( + struct btc_coexist *btcoexist, + u8 type + ); +void +ex_btc8821a2ant_bt_info_notify( + struct btc_coexist *btcoexist, + u8 *tmp_buf, + u8 length + ); +void +ex_btc8821a2ant_halt_notify( + struct btc_coexist *btcoexist + ); +void +ex_btc8821a2ant_periodical( + struct btc_coexist *btcoexist + ); +void +ex_btc8821a2ant_display_coex_info( + struct btc_coexist *btcoexist, + struct seq_file *m + ); +void ex_btc8821a2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); +void ex_btc8821a2ant_pre_load_firmware(struct btc_coexist *btcoexist); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.c new file mode 100644 index 000000000..145d6f9c0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2016-2017 Realtek Corporation.*/ + +#include "halbt_precomp.h" + +void ex_hal8822b_wifi_only_hw_config(struct wifi_only_cfg *wifionlycfg) +{ + /*BB control*/ + halwifionly_phy_set_bb_reg(wifionlycfg, 0x4c, 0x01800000, 0x2); + /*SW control*/ + halwifionly_phy_set_bb_reg(wifionlycfg, 0xcb4, 0xff, 0x77); + /*antenna mux switch */ + halwifionly_phy_set_bb_reg(wifionlycfg, 0x974, 0x300, 0x3); + + halwifionly_phy_set_bb_reg(wifionlycfg, 0x1990, 0x300, 0x0); + + halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x80000, 0x0); + /*switch to WL side controller and gnt_wl gnt_bt debug signal */ + halwifionly_phy_set_bb_reg(wifionlycfg, 0x70, 0xff000000, 0x0e); + /*gnt_wl=1 , gnt_bt=0*/ + halwifionly_phy_set_bb_reg(wifionlycfg, 0x1704, 0xffffffff, 0x7700); + halwifionly_phy_set_bb_reg(wifionlycfg, 0x1700, 0xffffffff, 0xc00f0038); +} + +void ex_hal8822b_wifi_only_scannotify(struct wifi_only_cfg *wifionlycfg, + u8 is_5g) +{ + hal8822b_wifi_only_switch_antenna(wifionlycfg, is_5g); +} + +void ex_hal8822b_wifi_only_switchbandnotify(struct wifi_only_cfg *wifionlycfg, + u8 is_5g) +{ + hal8822b_wifi_only_switch_antenna(wifionlycfg, is_5g); +} + +void hal8822b_wifi_only_switch_antenna(struct wifi_only_cfg *wifionlycfg, + u8 is_5g) +{ + if (is_5g) + halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x300, 0x1); + else + halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x300, 0x2); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.h new file mode 100644 index 000000000..5fc66cea7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8822bwifionly.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2016-2017 Realtek Corporation.*/ + +#ifndef __INC_HAL8822BWIFIONLYHWCFG_H +#define __INC_HAL8822BWIFIONLYHWCFG_H + +void ex_hal8822b_wifi_only_hw_config(struct wifi_only_cfg *wifionlycfg); +void ex_hal8822b_wifi_only_scannotify(struct wifi_only_cfg *wifionlycfg, + u8 is_5g); +void ex_hal8822b_wifi_only_switchbandnotify(struct wifi_only_cfg *wifionlycfg, + u8 is_5g); +void hal8822b_wifi_only_switch_antenna(struct wifi_only_cfg *wifionlycfg, + u8 is_5g); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c new file mode 100644 index 000000000..478cca33e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c @@ -0,0 +1,1893 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2007-2013 Realtek Corporation.*/ + +#include "halbt_precomp.h" + +/*************************************************** + * Debug related function + ***************************************************/ + +static const char *const gl_btc_wifi_bw_string[] = { + "11bg", + "HT20", + "HT40", + "HT80", + "HT160" +}; + +static const char *const gl_btc_wifi_freq_string[] = { + "2.4G", + "5G" +}; + +static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist) +{ + if (!btcoexist->binded || NULL == btcoexist->adapter) + return false; + + return true; +} + +static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv) +{ + if (rtlpriv->link_info.busytraffic) + return true; + else + return false; +} + +static void halbtc_dbg_init(void) +{ +} + +/*************************************************** + * helper function + ***************************************************/ +static bool is_any_client_connect_to_ap(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_mac *mac = rtl_mac(rtlpriv); + bool ret = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT || + mac->opmode == NL80211_IFTYPE_AP) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + if (!list_empty(&rtlpriv->entry_list)) + ret = true; + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + } + return ret; +} + +static bool halbtc_legacy(struct rtl_priv *adapter) +{ + struct rtl_priv *rtlpriv = adapter; + struct rtl_mac *mac = rtl_mac(rtlpriv); + + bool is_legacy = false; + + if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G)) + is_legacy = true; + + return is_legacy; +} + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter) +{ + struct rtl_priv *rtlpriv = adapter; + + if (rtlpriv->link_info.tx_busy_traffic) + return true; + else + return false; +} + +static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 wifi_bw = BTC_WIFI_BW_HT20; + + if (halbtc_legacy(rtlpriv)) { + wifi_bw = BTC_WIFI_BW_LEGACY; + } else { + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + wifi_bw = BTC_WIFI_BW_HT20; + break; + case HT_CHANNEL_WIDTH_20_40: + wifi_bw = BTC_WIFI_BW_HT40; + break; + case HT_CHANNEL_WIDTH_80: + wifi_bw = BTC_WIFI_BW_HT80; + break; + } + } + + return wifi_bw; +} + +static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 chnl = 1; + + if (rtlphy->current_channel != 0) + chnl = rtlphy->current_channel; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "%s:%d\n", __func__, chnl); + return chnl; +} + +static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) +{ + return rtlpriv->btcoexist.btc_info.single_ant_path; +} + +static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) +{ + return rtlpriv->btcoexist.btc_info.bt_type; +} + +static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) +{ + u8 num; + + if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) + num = 2; + else + num = 1; + + return num; +} + +static u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + return rtlhal->package_type; +} + +static +u8 rtl_get_hwpg_rfe_type(struct rtl_priv *rtlpriv) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + return rtlhal->rfe_type; +} + +static +bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist) +{ + if (IS_HARDWARE_TYPE_8812(btcoexist->adapter)) + return false; + else + return true; +} + +static +bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code, + u8 *cmd, u32 len, unsigned long wait_ms) +{ + struct rtl_priv *rtlpriv; + const u8 oper_ver = 0; + u8 req_num; + + if (!halbtc_is_hw_mailbox_exist(btcoexist)) + return false; + + if (wait_ms) /* before h2c to avoid race condition */ + reinit_completion(&btcoexist->bt_mp_comp); + + rtlpriv = btcoexist->adapter; + + /* fill req_num by op_code, and rtl_btc_btmpinfo_notify() use it + * to know message type + */ + switch (op_code) { + case BT_OP_GET_BT_VERSION: + req_num = BT_SEQ_GET_BT_VERSION; + break; + case BT_OP_GET_AFH_MAP_L: + req_num = BT_SEQ_GET_AFH_MAP_L; + break; + case BT_OP_GET_AFH_MAP_M: + req_num = BT_SEQ_GET_AFH_MAP_M; + break; + case BT_OP_GET_AFH_MAP_H: + req_num = BT_SEQ_GET_AFH_MAP_H; + break; + case BT_OP_GET_BT_COEX_SUPPORTED_FEATURE: + req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE; + break; + case BT_OP_GET_BT_COEX_SUPPORTED_VERSION: + req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION; + break; + case BT_OP_GET_BT_ANT_DET_VAL: + req_num = BT_SEQ_GET_BT_ANT_DET_VAL; + break; + case BT_OP_GET_BT_BLE_SCAN_PARA: + req_num = BT_SEQ_GET_BT_BLE_SCAN_PARA; + break; + case BT_OP_GET_BT_BLE_SCAN_TYPE: + req_num = BT_SEQ_GET_BT_BLE_SCAN_TYPE; + break; + case BT_OP_GET_BT_DEVICE_INFO: + req_num = BT_SEQ_GET_BT_DEVICE_INFO; + break; + case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL: + req_num = BT_SEQ_GET_BT_FORB_SLOT_VAL; + break; + case BT_OP_WRITE_REG_ADDR: + case BT_OP_WRITE_REG_VALUE: + case BT_OP_READ_REG: + default: + req_num = BT_SEQ_DONT_CARE; + break; + } + + cmd[0] |= (oper_ver & 0x0f); /* Set OperVer */ + cmd[0] |= ((req_num << 4) & 0xf0); /* Set ReqNum */ + cmd[1] = op_code; + rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, len, cmd); + + /* wait? */ + if (!wait_ms) + return true; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms); + + if (wait_for_completion_timeout(&btcoexist->bt_mp_comp, + msecs_to_jiffies(wait_ms)) == 0) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "btmpinfo wait (req_num=%d) timeout\n", req_num); + + return false; /* timeout */ + } + + return true; +} + +static void halbtc_leave_lps(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv; + bool ap_enable = false; + + rtlpriv = btcoexist->adapter; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + + if (ap_enable) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "%s()<--dont leave lps under AP mode\n", __func__); + return; + } + + btcoexist->bt_info.bt_ctrl_lps = true; + btcoexist->bt_info.bt_lps_on = false; + /* FIXME: Context is unclear. Is it allowed to block? */ + rtl_lps_leave(rtlpriv->mac80211.hw, false); +} + +static void halbtc_enter_lps(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv; + bool ap_enable = false; + + rtlpriv = btcoexist->adapter; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, + &ap_enable); + + if (ap_enable) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "%s()<--dont enter lps under AP mode\n", __func__); + return; + } + + btcoexist->bt_info.bt_ctrl_lps = true; + btcoexist->bt_info.bt_lps_on = true; + /* FIXME: Context is unclear. Is it allowed to block? */ + rtl_lps_enter(rtlpriv->mac80211.hw, false); +} + +static void halbtc_normal_lps(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv; + + rtlpriv = btcoexist->adapter; + + if (btcoexist->bt_info.bt_ctrl_lps) { + btcoexist->bt_info.bt_lps_on = false; + /* FIXME: Context is unclear. Is it allowed to block? */ + rtl_lps_leave(rtlpriv->mac80211.hw, false); + btcoexist->bt_info.bt_ctrl_lps = false; + } +} + +static void halbtc_pre_normal_lps(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (btcoexist->bt_info.bt_ctrl_lps) { + btcoexist->bt_info.bt_lps_on = false; + /* FIXME: Context is unclear. Is it allowed to block? */ + rtl_lps_leave(rtlpriv->mac80211.hw, false); + } +} + +static void halbtc_post_normal_lps(struct btc_coexist *btcoexist) +{ + if (btcoexist->bt_info.bt_ctrl_lps) + btcoexist->bt_info.bt_ctrl_lps = false; +} + +static void halbtc_leave_low_power(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_normal_low_power(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_disable_low_power(struct btc_coexist *btcoexist, + bool low_pwr_disable) +{ + /* TODO: original/leave 32k low power */ + btcoexist->bt_info.bt_disable_low_pwr = low_pwr_disable; +} + +static void halbtc_aggregation_check(struct btc_coexist *btcoexist) +{ + bool need_to_act = false; + static unsigned long pre_time; + unsigned long cur_time = 0; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + /* To void continuous deleteBA=>addBA=>deleteBA=>addBA + * This function is not allowed to continuous called + * It can only be called after 8 seconds + */ + + cur_time = jiffies; + if (jiffies_to_msecs(cur_time - pre_time) <= 8000) { + /* over 8 seconds you can execute this function again. */ + return; + } + pre_time = cur_time; + + if (btcoexist->bt_info.reject_agg_pkt) { + need_to_act = true; + btcoexist->bt_info.pre_reject_agg_pkt = + btcoexist->bt_info.reject_agg_pkt; + } else { + if (btcoexist->bt_info.pre_reject_agg_pkt) { + need_to_act = true; + btcoexist->bt_info.pre_reject_agg_pkt = + btcoexist->bt_info.reject_agg_pkt; + } + + if (btcoexist->bt_info.pre_bt_ctrl_agg_buf_size != + btcoexist->bt_info.bt_ctrl_agg_buf_size) { + need_to_act = true; + btcoexist->bt_info.pre_bt_ctrl_agg_buf_size = + btcoexist->bt_info.bt_ctrl_agg_buf_size; + } + + if (btcoexist->bt_info.bt_ctrl_agg_buf_size) { + if (btcoexist->bt_info.pre_agg_buf_size != + btcoexist->bt_info.agg_buf_size) { + need_to_act = true; + } + btcoexist->bt_info.pre_agg_buf_size = + btcoexist->bt_info.agg_buf_size; + } + + if (need_to_act) + rtl_rx_ampdu_apply(rtlpriv); + } +} + +static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist) +{ + u8 cmd_buffer[4] = {0}; + + if (btcoexist->bt_info.bt_real_fw_ver) + goto label_done; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_VERSION, + cmd_buffer, 4, 200); + +label_done: + return btcoexist->bt_info.bt_real_fw_ver; +} + +static u32 halbtc_get_bt_coex_supported_feature(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + if (btcoexist->bt_info.bt_supported_feature) + goto label_done; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, + BT_OP_GET_BT_COEX_SUPPORTED_FEATURE, + cmd_buffer, 4, 200); + +label_done: + return btcoexist->bt_info.bt_supported_feature; +} + +static u32 halbtc_get_bt_coex_supported_version(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + if (btcoexist->bt_info.bt_supported_version) + goto label_done; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, + BT_OP_GET_BT_COEX_SUPPORTED_VERSION, + cmd_buffer, 4, 200); + +label_done: + return btcoexist->bt_info.bt_supported_version; +} + +static u32 halbtc_get_bt_device_info(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, + BT_OP_GET_BT_DEVICE_INFO, + cmd_buffer, 4, 200); + + return btcoexist->bt_info.bt_device_info; +} + +static u32 halbtc_get_bt_forbidden_slot_val(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, + BT_OP_GET_BT_FORBIDDEN_SLOT_VAL, + cmd_buffer, 4, 200); + + return btcoexist->bt_info.bt_forb_slot_val; +} + +static u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist) +{ + /* return value: + * [31:16] => connected port number + * [15:0] => port connected bit define + */ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u32 ret_val = 0; + u32 port_connected_status = 0, num_of_connected_port = 0; + + if (mac->opmode == NL80211_IFTYPE_STATION && + mac->link_state >= MAC80211_LINKED) { + port_connected_status |= WIFI_STA_CONNECTED; + num_of_connected_port++; + } + /* AP & ADHOC & MESH */ + if (is_any_client_connect_to_ap(btcoexist)) { + port_connected_status |= WIFI_AP_CONNECTED; + num_of_connected_port++; + } + /* TODO: P2P Connected Status */ + + ret_val = (num_of_connected_port << 16) | port_connected_status; + + return ret_val; +} + +static s32 halbtc_get_wifi_rssi(struct rtl_priv *rtlpriv) +{ + return rtlpriv->dm.undec_sm_pwdb; +} + +static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + bool *bool_tmp = (bool *)out_buf; + int *s32_tmp = (int *)out_buf; + u32 *u32_tmp = (u32 *)out_buf; + u8 *u8_tmp = (u8 *)out_buf; + bool tmp = false; + bool ret = true; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return false; + + switch (get_type) { + case BTC_GET_BL_HS_OPERATION: + *bool_tmp = false; + ret = false; + break; + case BTC_GET_BL_HS_CONNECTING: + *bool_tmp = false; + ret = false; + break; + case BTC_GET_BL_WIFI_CONNECTED: + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && + rtlpriv->mac80211.link_state >= MAC80211_LINKED) + tmp = true; + if (is_any_client_connect_to_ap(btcoexist)) + tmp = true; + *bool_tmp = tmp; + break; + case BTC_GET_BL_WIFI_DUAL_BAND_CONNECTED: + *u8_tmp = BTC_MULTIPORT_SCC; + break; + case BTC_GET_BL_WIFI_BUSY: + if (halbtc_is_wifi_busy(rtlpriv)) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_SCAN: + if (mac->act_scanning) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_LINK: + if (mac->link_state == MAC80211_LINKING) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_ROAM: + if (mac->link_state == MAC80211_LINKING) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_4_WAY_PROGRESS: + *bool_tmp = rtlpriv->btcoexist.btc_info.in_4way; + break; + case BTC_GET_BL_WIFI_UNDER_5G: + if (rtlhal->current_bandtype == BAND_ON_5G) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_AP_MODE_ENABLE: + if (mac->opmode == NL80211_IFTYPE_AP) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION: + if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm) + *bool_tmp = false; + else + *bool_tmp = true; + break; + case BTC_GET_BL_WIFI_UNDER_B_MODE: + if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) + *bool_tmp = true; + else + *bool_tmp = false; + break; + case BTC_GET_BL_EXT_SWITCH: + *bool_tmp = false; + break; + case BTC_GET_BL_WIFI_IS_IN_MP_MODE: + *bool_tmp = false; + break; + case BTC_GET_BL_IS_ASUS_8723B: + *bool_tmp = false; + break; + case BTC_GET_BL_RF4CE_CONNECTED: + *bool_tmp = false; + break; + case BTC_GET_S4_WIFI_RSSI: + *s32_tmp = halbtc_get_wifi_rssi(rtlpriv); + break; + case BTC_GET_S4_HS_RSSI: + *s32_tmp = 0; + ret = false; + break; + case BTC_GET_U4_WIFI_BW: + *u32_tmp = halbtc_get_wifi_bw(btcoexist); + break; + case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: + if (halbtc_is_wifi_uplink(rtlpriv)) + *u32_tmp = BTC_WIFI_TRAFFIC_TX; + else + *u32_tmp = BTC_WIFI_TRAFFIC_RX; + break; + case BTC_GET_U4_WIFI_FW_VER: + *u32_tmp = (rtlhal->fw_version << 16) | rtlhal->fw_subversion; + break; + case BTC_GET_U4_WIFI_LINK_STATUS: + *u32_tmp = halbtc_get_wifi_link_status(btcoexist); + break; + case BTC_GET_U4_BT_PATCH_VER: + *u32_tmp = halbtc_get_bt_patch_version(btcoexist); + break; + case BTC_GET_U4_VENDOR: + *u32_tmp = BTC_VENDOR_OTHER; + break; + case BTC_GET_U4_SUPPORTED_VERSION: + *u32_tmp = halbtc_get_bt_coex_supported_version(btcoexist); + break; + case BTC_GET_U4_SUPPORTED_FEATURE: + *u32_tmp = halbtc_get_bt_coex_supported_feature(btcoexist); + break; + case BTC_GET_U4_BT_DEVICE_INFO: + *u32_tmp = halbtc_get_bt_device_info(btcoexist); + break; + case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL: + *u32_tmp = halbtc_get_bt_forbidden_slot_val(btcoexist); + break; + case BTC_GET_U4_WIFI_IQK_TOTAL: + *u32_tmp = + btcoexist->btc_phydm_query_phy_counter(btcoexist, + DM_INFO_IQK_ALL); + break; + case BTC_GET_U4_WIFI_IQK_OK: + *u32_tmp = + btcoexist->btc_phydm_query_phy_counter(btcoexist, + DM_INFO_IQK_OK); + break; + case BTC_GET_U4_WIFI_IQK_FAIL: + *u32_tmp = + btcoexist->btc_phydm_query_phy_counter(btcoexist, + DM_INFO_IQK_NG); + break; + case BTC_GET_U1_WIFI_DOT11_CHNL: + *u8_tmp = rtlphy->current_channel; + break; + case BTC_GET_U1_WIFI_CENTRAL_CHNL: + *u8_tmp = halbtc_get_wifi_central_chnl(btcoexist); + break; + case BTC_GET_U1_WIFI_HS_CHNL: + *u8_tmp = 0; + ret = false; + break; + case BTC_GET_U1_AP_NUM: + *u8_tmp = rtlpriv->btcoexist.btc_info.ap_num; + break; + case BTC_GET_U1_ANT_TYPE: + *u8_tmp = (u8)BTC_ANT_TYPE_0; + break; + case BTC_GET_U1_IOT_PEER: + *u8_tmp = 0; + break; + + /************* 1Ant **************/ + case BTC_GET_U1_LPS_MODE: + *u8_tmp = btcoexist->pwr_mode_val[0]; + break; + + default: + ret = false; + break; + } + + return ret; +} + +static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; + bool *bool_tmp = (bool *)in_buf; + u8 *u8_tmp = (u8 *)in_buf; + u32 *u32_tmp = (u32 *)in_buf; + bool ret = true; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return false; + + switch (set_type) { + /* set some bool type variables. */ + case BTC_SET_BL_BT_DISABLE: + btcoexist->bt_info.bt_disabled = *bool_tmp; + break; + case BTC_SET_BL_BT_TRAFFIC_BUSY: + btcoexist->bt_info.bt_busy = *bool_tmp; + break; + case BTC_SET_BL_BT_LIMITED_DIG: + btcoexist->bt_info.limited_dig = *bool_tmp; + break; + case BTC_SET_BL_FORCE_TO_ROAM: + btcoexist->bt_info.force_to_roam = *bool_tmp; + break; + case BTC_SET_BL_TO_REJ_AP_AGG_PKT: + btcoexist->bt_info.reject_agg_pkt = *bool_tmp; + break; + case BTC_SET_BL_BT_CTRL_AGG_SIZE: + btcoexist->bt_info.bt_ctrl_agg_buf_size = *bool_tmp; + break; + case BTC_SET_BL_INC_SCAN_DEV_NUM: + btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; + break; + case BTC_SET_BL_BT_TX_RX_MASK: + btcoexist->bt_info.bt_tx_rx_mask = *bool_tmp; + break; + case BTC_SET_BL_MIRACAST_PLUS_BT: + btcoexist->bt_info.miracast_plus_bt = *bool_tmp; + break; + /* set some u1Byte type variables. */ + case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON: + btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp; + break; + case BTC_SET_U1_AGG_BUF_SIZE: + btcoexist->bt_info.agg_buf_size = *u8_tmp; + break; + + /* the following are some action which will be triggered */ + case BTC_SET_ACT_GET_BT_RSSI: + ret = false; + break; + case BTC_SET_ACT_AGGREGATE_CTRL: + halbtc_aggregation_check(btcoexist); + break; + + /* 1Ant */ + case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE: + btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp; + break; + case BTC_SET_UI_SCAN_SIG_COMPENSATION: + break; + case BTC_SET_U1_LPS_VAL: + btcoexist->bt_info.lps_val = *u8_tmp; + break; + case BTC_SET_U1_RPWM_VAL: + btcoexist->bt_info.rpwm_val = *u8_tmp; + break; + /* the following are some action which will be triggered */ + case BTC_SET_ACT_LEAVE_LPS: + halbtc_leave_lps(btcoexist); + break; + case BTC_SET_ACT_ENTER_LPS: + halbtc_enter_lps(btcoexist); + break; + case BTC_SET_ACT_NORMAL_LPS: + halbtc_normal_lps(btcoexist); + break; + case BTC_SET_ACT_PRE_NORMAL_LPS: + halbtc_pre_normal_lps(btcoexist); + break; + case BTC_SET_ACT_POST_NORMAL_LPS: + halbtc_post_normal_lps(btcoexist); + break; + case BTC_SET_ACT_DISABLE_LOW_POWER: + halbtc_disable_low_power(btcoexist, *bool_tmp); + break; + case BTC_SET_ACT_UPDATE_RAMASK: + btcoexist->bt_info.ra_mask = *u32_tmp; + break; + case BTC_SET_ACT_SEND_MIMO_PS: + break; + case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/ + break; + case BTC_SET_ACT_CTRL_BT_COEX: + break; + case BTC_SET_ACT_CTRL_8723B_ANT: + break; + default: + break; + } + + return ret; +} + +static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist, + struct seq_file *m) +{ +} + +static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ +} + +static void halbtc_display_wifi_status(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + s32 wifi_rssi = 0, bt_hs_rssi = 0; + bool scan = false, link = false, roam = false, wifi_busy = false; + bool wifi_under_b_mode = false; + bool wifi_under_5g = false; + u32 wifi_bw = BTC_WIFI_BW_HT20; + u32 wifi_traffic_dir = BTC_WIFI_TRAFFIC_TX; + u32 wifi_freq = BTC_FREQ_2_4G; + u32 wifi_link_status = 0x0; + bool bt_hs_on = false, under_ips = false, under_lps = false; + bool low_power = false, dc_mode = false; + u8 wifi_chnl = 0, wifi_hs_chnl = 0; + u8 ap_num = 0; + + wifi_link_status = halbtc_get_wifi_link_status(btcoexist); + seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d", + "STA/vWifi/HS/p2pGo/p2pGc", + ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0), + ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0)); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_chnl); + btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + seq_printf(m, "\n %-35s = %d / %d(%d)", + "Dot11 channel / HsChnl(High Speed)", + wifi_chnl, wifi_hs_chnl, bt_hs_on); + + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); + seq_printf(m, "\n %-35s = %d/ %d", + "Wifi rssi/ HS rssi", + wifi_rssi - 100, bt_hs_rssi - 100); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + seq_printf(m, "\n %-35s = %d/ %d/ %d ", + "Wifi link/ roam/ scan", + link, roam, scan); + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + &wifi_traffic_dir); + btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); + wifi_freq = (wifi_under_5g ? BTC_FREQ_5G : BTC_FREQ_2_4G); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + + seq_printf(m, "\n %-35s = %s / %s/ %s/ AP=%d ", + "Wifi freq/ bw/ traffic", + gl_btc_wifi_freq_string[wifi_freq], + ((wifi_under_b_mode) ? "11b" : + gl_btc_wifi_bw_string[wifi_bw]), + ((!wifi_busy) ? "idle" : ((BTC_WIFI_TRAFFIC_TX == + wifi_traffic_dir) ? "uplink" : + "downlink")), + ap_num); + + /* power status */ + dc_mode = true; /*TODO*/ + under_ips = rtlpriv->psc.inactive_pwrstate == ERFOFF ? 1 : 0; + under_lps = rtlpriv->psc.dot11_psmode == EACTIVE ? 0 : 1; + low_power = 0; /*TODO*/ + seq_printf(m, "\n %-35s = %s%s%s%s", + "Power Status", + (dc_mode ? "DC mode" : "AC mode"), + (under_ips ? ", IPS ON" : ""), + (under_lps ? ", LPS ON" : ""), + (low_power ? ", 32k" : "")); + + seq_printf(m, + "\n %-35s = %6ph (0x%x/0x%x)", + "Power mode cmd(lps/rpwm)", + btcoexist->pwr_mode_val, + btcoexist->bt_info.lps_val, + btcoexist->bt_info.rpwm_val); +} + +/************************************************************ + * IO related function + ************************************************************/ +static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + return rtl_read_byte(rtlpriv, reg_addr); +} + +static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + return rtl_read_word(rtlpriv, reg_addr); +} + +static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + return rtl_read_dword(rtlpriv, reg_addr); +} + +static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, + u32 bit_mask, u8 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 original_value, bit_shift = 0; + u8 i; + + if (bit_mask != MASKDWORD) {/*if not "double word" write*/ + original_value = rtl_read_byte(rtlpriv, reg_addr); + for (i = 0; i <= 7; i++) { + if ((bit_mask>>i) & 0x1) + break; + } + bit_shift = i; + data = (original_value & (~bit_mask)) | + ((data << bit_shift) & bit_mask); + } + rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_write_word(rtlpriv, reg_addr, data); +} + +static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data) +{ + struct btc_coexist *btcoexist = + (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_write_dword(rtlpriv, reg_addr, data); +} + +static void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, + u8 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + if (btcoexist->chip_interface == BTC_INTF_SDIO) + ; + else if (btcoexist->chip_interface == BTC_INTF_PCI) + rtl_write_byte(rtlpriv, reg_addr, data); + else if (btcoexist->chip_interface == BTC_INTF_USB) + rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask, + u32 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask); +} + +static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, + u32 bit_mask, u32 data) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, + u32 bit_mask) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask); +} + +static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id, + u32 cmd_len, u8 *cmd_buf) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + + rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id, + cmd_len, cmd_buf); +} + +void halbtc_send_wifi_port_id_cmd(void *bt_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + u8 cmd_buf[1] = {0}; /* port id [2:0] = 0 */ + + rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, H2C_BT_PORT_ID, + 1, cmd_buf); +} + +void halbtc_set_default_port_id_cmd(void *bt_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct ieee80211_hw *hw = rtlpriv->mac80211.hw; + + if (!rtlpriv->cfg->ops->set_default_port_id_cmd) + return; + + rtlpriv->cfg->ops->set_default_port_id_cmd(hw); +} + +static +void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer1[4] = {0}; + u8 cmd_buffer2[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + *((__le16 *)&cmd_buffer1[2]) = cpu_to_le16((u16)set_val); + if (!halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_VALUE, + cmd_buffer1, 4, 200)) + return; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + cmd_buffer2[2] = reg_type; + *((u8 *)&cmd_buffer2[3]) = (u8)offset; + halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_ADDR, + cmd_buffer2, 4, 200); +} + +static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type, + struct seq_file *m) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; + + switch (disp_type) { + case BTC_DBG_DISP_COEX_STATISTICS: + halbtc_display_coex_statistics(btcoexist, m); + break; + case BTC_DBG_DISP_BT_LINK_INFO: + halbtc_display_bt_link_info(btcoexist, m); + break; + case BTC_DBG_DISP_WIFI_STATUS: + halbtc_display_wifi_status(btcoexist, m); + break; + default: + break; + } +} + +static u32 halbtc_get_bt_reg(void *btc_context, u8 reg_type, u32 offset) +{ + return 0; +} + +static bool halbtc_under_ips(struct btc_coexist *btcoexist) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + enum rf_pwrstate rtstate; + + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + if (rtstate != ERFON && + ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + return true; + } + } + + return false; +} + +static +u32 halbtc_get_phydm_version(void *btc_context) +{ + return 0; +} + +static +void halbtc_phydm_modify_ra_pcr_threshold(void *btc_context, + u8 ra_offset_direction, + u8 ra_threshold_offset) +{ +} + +static +u32 halbtc_phydm_query_phy_counter(void *btc_context, enum dm_info_query dm_id) +{ + return 0; +} + +static u8 halbtc_get_ant_det_val_from_bt(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_ANT_DET_VAL, + cmd_buffer, 4, 200); + + /* need wait completion to return correct value */ + + return btcoexist->bt_info.bt_ant_det_val; +} + +static u8 halbtc_get_ble_scan_type_from_bt(void *btc_context) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_TYPE, + cmd_buffer, 4, 200); + + /* need wait completion to return correct value */ + + return btcoexist->bt_info.bt_ble_scan_type; +} + +static u32 halbtc_get_ble_scan_para_from_bt(void *btc_context, u8 scan_type) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[4] = {0}; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_PARA, + cmd_buffer, 4, 200); + + /* need wait completion to return correct value */ + + return btcoexist->bt_info.bt_ble_scan_para; +} + +static bool halbtc_get_bt_afh_map_from_bt(void *btc_context, u8 map_type, + u8 *afh_map) +{ + struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; + u8 cmd_buffer[2] = {0}; + bool ret; + u32 *afh_map_l = (u32 *)afh_map; + u32 *afh_map_m = (u32 *)(afh_map + 4); + u16 *afh_map_h = (u16 *)(afh_map + 8); + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_L, + cmd_buffer, 2, 200); + if (!ret) + goto exit; + + *afh_map_l = btcoexist->bt_info.afh_map_l; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_M, + cmd_buffer, 2, 200); + if (!ret) + goto exit; + + *afh_map_m = btcoexist->bt_info.afh_map_m; + + /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */ + ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_H, + cmd_buffer, 2, 200); + if (!ret) + goto exit; + + *afh_map_h = btcoexist->bt_info.afh_map_h; + +exit: + return ret; +} + +/***************************************************************** + * Extern functions called by other module + *****************************************************************/ +bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return false; + + halbtc_dbg_init(); + + btcoexist->btc_read_1byte = halbtc_read_1byte; + btcoexist->btc_write_1byte = halbtc_write_1byte; + btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte; + btcoexist->btc_read_2byte = halbtc_read_2byte; + btcoexist->btc_write_2byte = halbtc_write_2byte; + btcoexist->btc_read_4byte = halbtc_read_4byte; + btcoexist->btc_write_4byte = halbtc_write_4byte; + btcoexist->btc_write_local_reg_1byte = halbtc_write_local_reg_1byte; + + btcoexist->btc_set_bb_reg = halbtc_set_bbreg; + btcoexist->btc_get_bb_reg = halbtc_get_bbreg; + + btcoexist->btc_set_rf_reg = halbtc_set_rfreg; + btcoexist->btc_get_rf_reg = halbtc_get_rfreg; + + btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd; + btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg; + + btcoexist->btc_get = halbtc_get; + btcoexist->btc_set = halbtc_set; + btcoexist->btc_set_bt_reg = halbtc_set_bt_reg; + btcoexist->btc_get_bt_reg = halbtc_get_bt_reg; + + btcoexist->bt_info.bt_ctrl_buf_size = false; + btcoexist->bt_info.agg_buf_size = 5; + + btcoexist->bt_info.increase_scan_dev_num = false; + + btcoexist->btc_get_bt_coex_supported_feature = + halbtc_get_bt_coex_supported_feature; + btcoexist->btc_get_bt_coex_supported_version = + halbtc_get_bt_coex_supported_version; + btcoexist->btc_get_bt_phydm_version = halbtc_get_phydm_version; + btcoexist->btc_phydm_modify_ra_pcr_threshold = + halbtc_phydm_modify_ra_pcr_threshold; + btcoexist->btc_phydm_query_phy_counter = halbtc_phydm_query_phy_counter; + btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt; + btcoexist->btc_get_ble_scan_type_from_bt = + halbtc_get_ble_scan_type_from_bt; + btcoexist->btc_get_ble_scan_para_from_bt = + halbtc_get_ble_scan_para_from_bt; + btcoexist->btc_get_bt_afh_map_from_bt = + halbtc_get_bt_afh_map_from_bt; + + init_completion(&btcoexist->bt_mp_comp); + + return true; +} + +bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv) +{ + struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv); + struct wifi_only_haldata *wifionly_haldata; + + if (!wifionly_cfg) + return false; + + wifionly_cfg->adapter = rtlpriv; + + switch (rtlpriv->rtlhal.interface) { + case INTF_PCI: + wifionly_cfg->chip_interface = WIFIONLY_INTF_PCI; + break; + case INTF_USB: + wifionly_cfg->chip_interface = WIFIONLY_INTF_USB; + break; + default: + wifionly_cfg->chip_interface = WIFIONLY_INTF_UNKNOWN; + break; + } + + wifionly_haldata = &wifionly_cfg->haldata_info; + + wifionly_haldata->customer_id = CUSTOMER_NORMAL; + wifionly_haldata->efuse_pg_antnum = rtl_get_hwpg_ant_num(rtlpriv); + wifionly_haldata->efuse_pg_antpath = + rtl_get_hwpg_single_ant_path(rtlpriv); + wifionly_haldata->rfe_type = rtl_get_hwpg_rfe_type(rtlpriv); + wifionly_haldata->ant_div_cfg = 0; + + return true; +} + +bool exhalbtc_bind_bt_coex_withadapter(void *adapter) +{ + struct rtl_priv *rtlpriv = adapter; + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + u8 ant_num, chip_type, single_ant_path; + + if (!btcoexist) + return false; + + if (btcoexist->binded) + return false; + + switch (rtlpriv->rtlhal.interface) { + case INTF_PCI: + btcoexist->chip_interface = BTC_INTF_PCI; + break; + case INTF_USB: + btcoexist->chip_interface = BTC_INTF_USB; + break; + default: + btcoexist->chip_interface = BTC_INTF_UNKNOWN; + break; + } + + btcoexist->binded = true; + btcoexist->statistics.cnt_bind++; + + btcoexist->adapter = adapter; + + btcoexist->stack_info.profile_notified = false; + + btcoexist->bt_info.bt_ctrl_agg_buf_size = false; + btcoexist->bt_info.agg_buf_size = 5; + + btcoexist->bt_info.increase_scan_dev_num = false; + btcoexist->bt_info.miracast_plus_bt = false; + + chip_type = rtl_get_hwpg_bt_type(rtlpriv); + exhalbtc_set_chip_type(btcoexist, chip_type); + ant_num = rtl_get_hwpg_ant_num(rtlpriv); + exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num); + + /* set default antenna position to main port */ + btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; + + single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv); + exhalbtc_set_single_ant_path(btcoexist, single_ant_path); + + if (rtl_get_hwpg_package_type(rtlpriv) == 0) + btcoexist->board_info.tfbga_package = false; + else if (rtl_get_hwpg_package_type(rtlpriv) == 1) + btcoexist->board_info.tfbga_package = false; + else + btcoexist->board_info.tfbga_package = true; + + if (btcoexist->board_info.tfbga_package) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Package Type = TFBGA\n"); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[BTCoex], Package Type = Non-TFBGA\n"); + + btcoexist->board_info.rfe_type = rtl_get_hwpg_rfe_type(rtlpriv); + btcoexist->board_info.ant_div_cfg = 0; + + return true; +} + +void exhalbtc_power_on_setting(struct btc_coexist *btcoexist) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + btcoexist->statistics.cnt_power_on++; + + if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_power_on_setting(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_power_on_setting(btcoexist); + } +} + +void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + btcoexist->statistics.cnt_pre_load_firmware++; + + if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_pre_load_firmware(btcoexist); + } +} + +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + btcoexist->statistics.cnt_init_hw_config++; + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_init_hwconfig(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_init_hwconfig(btcoexist, wifi_only); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_init_hwconfig(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_init_hwconfig(btcoexist, wifi_only); + } else if (IS_HARDWARE_TYPE_8723A(btcoexist->adapter)) { + /* 8723A has no this function */ + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_init_hwconfig(btcoexist); + } +} + +void exhalbtc_init_hw_config_wifi_only(struct wifi_only_cfg *wifionly_cfg) +{ +} + +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + btcoexist->statistics.cnt_init_coex_dm++; + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_init_coex_dm(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_init_coex_dm(btcoexist); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_init_coex_dm(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_init_coex_dm(btcoexist); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_init_coex_dm(btcoexist); + } + + btcoexist->initialized = true; +} + +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ + u8 ips_type; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_ips_notify++; + if (btcoexist->manual_control) + return; + + if (ERFOFF == type) + ips_type = BTC_IPS_ENTER; + else + ips_type = BTC_IPS_LEAVE; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_ips_notify(btcoexist, ips_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_ips_notify(btcoexist, ips_type); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_ips_notify(btcoexist, ips_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_ips_notify(btcoexist, ips_type); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_ips_notify(btcoexist, ips_type); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ + u8 lps_type; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_lps_notify++; + if (btcoexist->manual_control) + return; + + if (EACTIVE == type) + lps_type = BTC_LPS_DISABLE; + else + lps_type = BTC_LPS_ENABLE; + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_lps_notify(btcoexist, lps_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_lps_notify(btcoexist, lps_type); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_lps_notify(btcoexist, lps_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_lps_notify(btcoexist, lps_type); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_lps_notify(btcoexist, lps_type); + } +} + +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ + u8 scan_type; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_scan_notify++; + if (btcoexist->manual_control) + return; + + if (type) + scan_type = BTC_SCAN_START; + else + scan_type = BTC_SCAN_FINISH; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_scan_notify(btcoexist, scan_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_scan_notify(btcoexist, scan_type); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_scan_notify(btcoexist, scan_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_scan_notify(btcoexist, scan_type); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_scan_notify(btcoexist, scan_type); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_scan_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg, + u8 is_5g) +{ +} + +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) +{ + u8 asso_type; + bool wifi_under_5g; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_connect_notify++; + if (btcoexist->manual_control) + return; + + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); + + if (action) + asso_type = BTC_ASSOCIATE_START; + else + asso_type = BTC_ASSOCIATE_FINISH; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_connect_notify(btcoexist, asso_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_connect_notify(btcoexist, asso_type); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_connect_notify(btcoexist, asso_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_connect_notify(btcoexist, asso_type); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_connect_notify(btcoexist, asso_type); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, + enum rt_media_status media_status) +{ + u8 status; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_media_status_notify++; + if (btcoexist->manual_control) + return; + + if (RT_MEDIA_CONNECT == media_status) + status = BTC_MEDIA_CONNECT; + else + status = BTC_MEDIA_DISCONNECT; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_media_status_notify(btcoexist, status); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_media_status_notify(btcoexist, status); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_media_status_notify(btcoexist, status); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_media_status_notify(btcoexist, status); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_media_status_notify(btcoexist, status); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type) +{ + u8 packet_type; + + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_special_packet_notify++; + if (btcoexist->manual_control) + return; + + if (pkt_type == PACKET_DHCP) { + packet_type = BTC_PACKET_DHCP; + } else if (pkt_type == PACKET_EAPOL) { + packet_type = BTC_PACKET_EAPOL; + } else if (pkt_type == PACKET_ARP) { + packet_type = BTC_PACKET_ARP; + } else { + packet_type = BTC_PACKET_UNKNOWN; + return; + } + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_special_packet_notify(btcoexist, + packet_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_special_packet_notify(btcoexist, + packet_type); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_special_packet_notify(btcoexist, + packet_type); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_special_packet_notify(btcoexist, + packet_type); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_special_packet_notify(btcoexist, + packet_type); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, + u8 *tmp_buf, u8 length) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_bt_info_notify++; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_bt_info_notify(btcoexist, tmp_buf, + length); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_bt_info_notify(btcoexist, tmp_buf, + length); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf, + length); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_bt_info_notify(btcoexist, tmp_buf, + length); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_bt_info_notify(btcoexist, tmp_buf, + length); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_halt_notify(struct btc_coexist *btcoexist) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_halt_notify(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_halt_notify(btcoexist); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_halt_notify(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_halt_notify(btcoexist); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_halt_notify(btcoexist); + } + + btcoexist->binded = false; +} + +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + /* currently only 1ant we have to do the notification, + * once pnp is notified to sleep state, we have to leave LPS that + * we can sleep normally. + */ + + if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_pnp_notify(btcoexist, pnp_state); + else if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_pnp_notify(btcoexist, pnp_state); + } else if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_pnp_notify(btcoexist, pnp_state); + else if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_pnp_notify(btcoexist, pnp_state); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + } +} + +void exhalbtc_periodical(struct btc_coexist *btcoexist) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + btcoexist->statistics.cnt_periodical++; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_periodical(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + if (!halbtc_under_ips(btcoexist)) + ex_btc8821a1ant_periodical(btcoexist); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_periodical(btcoexist); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_periodical(btcoexist); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_periodical(btcoexist); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + btcoexist->stack_info.min_bt_rssi = bt_rssi; +} + +void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type) +{ + switch (chip_type) { + default: + case BT_2WIRE: + case BT_ISSC_3WIRE: + case BT_ACCEL: + case BT_RTL8756: + btcoexist->board_info.bt_chip_type = BTC_CHIP_UNDEF; + break; + case BT_CSR_BC4: + btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC4; + break; + case BT_CSR_BC8: + btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC8; + break; + case BT_RTL8723A: + btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723A; + break; + case BT_RTL8821A: + btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8821; + break; + case BT_RTL8723B: + btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723B; + break; + } +} + +void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + if (BT_COEX_ANT_TYPE_PG == type) { + btcoexist->board_info.pg_ant_num = ant_num; + btcoexist->board_info.btdm_ant_num = ant_num; + } else if (BT_COEX_ANT_TYPE_ANTDIV == type) { + btcoexist->board_info.btdm_ant_num = ant_num; + } else if (type == BT_COEX_ANT_TYPE_DETECTED) { + btcoexist->board_info.btdm_ant_num = ant_num; + if (rtlpriv->cfg->mod_params->ant_sel == 1) + btcoexist->board_info.btdm_ant_pos = + BTC_ANTENNA_AT_AUX_PORT; + else + btcoexist->board_info.btdm_ant_pos = + BTC_ANTENNA_AT_MAIN_PORT; + } +} + +/* Currently used by 8723b only, S0 or S1 */ +void exhalbtc_set_single_ant_path(struct btc_coexist *btcoexist, + u8 single_ant_path) +{ + btcoexist->board_info.single_ant_path = single_ant_path; +} + +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + halbtc_leave_low_power(btcoexist); + + if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8821a2ant_display_coex_info(btcoexist, m); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8821a1ant_display_coex_info(btcoexist, m); + } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8723b2ant_display_coex_info(btcoexist, m); + else if (btcoexist->board_info.btdm_ant_num == 1) + ex_btc8723b1ant_display_coex_info(btcoexist, m); + } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) { + if (btcoexist->board_info.btdm_ant_num == 2) + ex_btc8192e2ant_display_coex_info(btcoexist, m); + } + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_switch_band_notify(struct btc_coexist *btcoexist, u8 type) +{ + if (!halbtc_is_bt_coexist_available(btcoexist)) + return; + + if (btcoexist->manual_control) + return; + + halbtc_leave_low_power(btcoexist); + + halbtc_normal_low_power(btcoexist); +} + +void exhalbtc_switch_band_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg, + u8 is_5g) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h new file mode 100644 index 000000000..d8d88a989 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h @@ -0,0 +1,824 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __HALBTC_OUT_SRC_H__ +#define __HALBTC_OUT_SRC_H__ + +#include "../wifi.h" + +#define NORMAL_EXEC false +#define FORCE_EXEC true + +#define BTC_RF_OFF 0x0 +#define BTC_RF_ON 0x1 + +#define BTC_RF_A RF90_PATH_A +#define BTC_RF_B RF90_PATH_B +#define BTC_RF_C RF90_PATH_C +#define BTC_RF_D RF90_PATH_D + +#define BTC_SMSP SINGLEMAC_SINGLEPHY +#define BTC_DMDP DUALMAC_DUALPHY +#define BTC_DMSP DUALMAC_SINGLEPHY +#define BTC_MP_UNKNOWN 0xff + +#define IN +#define OUT + +#define BT_TMP_BUF_SIZE 100 + +#define BT_COEX_ANT_TYPE_PG 0 +#define BT_COEX_ANT_TYPE_ANTDIV 1 +#define BT_COEX_ANT_TYPE_DETECTED 2 + +#define BTC_MIMO_PS_STATIC 0 +#define BTC_MIMO_PS_DYNAMIC 1 + +#define BTC_RATE_DISABLE 0 +#define BTC_RATE_ENABLE 1 + +/* single Antenna definition */ +#define BTC_ANT_PATH_WIFI 0 +#define BTC_ANT_PATH_BT 1 +#define BTC_ANT_PATH_PTA 2 +#define BTC_ANT_PATH_WIFI5G 3 +#define BTC_ANT_PATH_AUTO 4 +/* dual Antenna definition */ +#define BTC_ANT_WIFI_AT_MAIN 0 +#define BTC_ANT_WIFI_AT_AUX 1 +/* coupler Antenna definition */ +#define BTC_ANT_WIFI_AT_CPL_MAIN 0 +#define BTC_ANT_WIFI_AT_CPL_AUX 1 + +enum btc_bt_reg_type { + BTC_BT_REG_RF = 0, + BTC_BT_REG_MODEM = 1, + BTC_BT_REG_BLUEWIZE = 2, + BTC_BT_REG_VENDOR = 3, + BTC_BT_REG_LE = 4, + BTC_BT_REG_MAX +}; + +enum btc_chip_interface { + BTC_INTF_UNKNOWN = 0, + BTC_INTF_PCI = 1, + BTC_INTF_USB = 2, + BTC_INTF_SDIO = 3, + BTC_INTF_GSPI = 4, + BTC_INTF_MAX +}; + +enum btc_chip_type { + BTC_CHIP_UNDEF = 0, + BTC_CHIP_CSR_BC4 = 1, + BTC_CHIP_CSR_BC8 = 2, + BTC_CHIP_RTL8723A = 3, + BTC_CHIP_RTL8821 = 4, + BTC_CHIP_RTL8723B = 5, + BTC_CHIP_MAX +}; + +enum btc_msg_type { + BTC_MSG_INTERFACE = 0x0, + BTC_MSG_ALGORITHM = 0x1, + BTC_MSG_MAX +}; + +/* following is for BTC_MSG_INTERFACE */ +#define INTF_INIT BIT0 +#define INTF_NOTIFY BIT2 + +/* following is for BTC_ALGORITHM */ +#define ALGO_BT_RSSI_STATE BIT0 +#define ALGO_WIFI_RSSI_STATE BIT1 +#define ALGO_BT_MONITOR BIT2 +#define ALGO_TRACE BIT3 +#define ALGO_TRACE_FW BIT4 +#define ALGO_TRACE_FW_DETAIL BIT5 +#define ALGO_TRACE_FW_EXEC BIT6 +#define ALGO_TRACE_SW BIT7 +#define ALGO_TRACE_SW_DETAIL BIT8 +#define ALGO_TRACE_SW_EXEC BIT9 + +/* following is for wifi link status */ +#define WIFI_STA_CONNECTED BIT0 +#define WIFI_AP_CONNECTED BIT1 +#define WIFI_HS_CONNECTED BIT2 +#define WIFI_P2P_GO_CONNECTED BIT3 +#define WIFI_P2P_GC_CONNECTED BIT4 + +#define BTC_RSSI_HIGH(_rssi_) \ + ((_rssi_ == BTC_RSSI_STATE_HIGH || \ + _rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? true : false) +#define BTC_RSSI_MEDIUM(_rssi_) \ + ((_rssi_ == BTC_RSSI_STATE_MEDIUM || \ + _rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? true : false) +#define BTC_RSSI_LOW(_rssi_) \ + ((_rssi_ == BTC_RSSI_STATE_LOW || \ + _rssi_ == BTC_RSSI_STATE_STAY_LOW) ? true : false) + +enum btc_power_save_type { + BTC_PS_WIFI_NATIVE = 0, + BTC_PS_LPS_ON = 1, + BTC_PS_LPS_OFF = 2, + BTC_PS_LPS_MAX +}; + +struct btc_board_info { + /* The following is some board information */ + u8 bt_chip_type; + u8 pg_ant_num; /* pg ant number */ + u8 btdm_ant_num; /* ant number for btdm */ + u8 btdm_ant_pos; + u8 single_ant_path; /* current used for 8723b only, 1=>s0, 0=>s1 */ + bool tfbga_package; + + u8 rfe_type; + u8 ant_div_cfg; + u8 customer_id; +}; + +enum btc_dbg_opcode { + BTC_DBG_SET_COEX_NORMAL = 0x0, + BTC_DBG_SET_COEX_WIFI_ONLY = 0x1, + BTC_DBG_SET_COEX_BT_ONLY = 0x2, + BTC_DBG_MAX +}; + +enum btc_rssi_state { + BTC_RSSI_STATE_HIGH = 0x0, + BTC_RSSI_STATE_MEDIUM = 0x1, + BTC_RSSI_STATE_LOW = 0x2, + BTC_RSSI_STATE_STAY_HIGH = 0x3, + BTC_RSSI_STATE_STAY_MEDIUM = 0x4, + BTC_RSSI_STATE_STAY_LOW = 0x5, + BTC_RSSI_MAX +}; + +enum btc_wifi_role { + BTC_ROLE_STATION = 0x0, + BTC_ROLE_AP = 0x1, + BTC_ROLE_IBSS = 0x2, + BTC_ROLE_HS_MODE = 0x3, + BTC_ROLE_MAX +}; + +enum btc_wireless_freq { + BTC_FREQ_2_4G = 0x0, + BTC_FREQ_5G = 0x1, + BTC_FREQ_MAX +}; + +enum btc_wifi_bw_mode { + BTC_WIFI_BW_LEGACY = 0x0, + BTC_WIFI_BW_HT20 = 0x1, + BTC_WIFI_BW_HT40 = 0x2, + BTC_WIFI_BW_HT80 = 0x3, + BTC_WIFI_BW_MAX +}; + +enum btc_wifi_traffic_dir { + BTC_WIFI_TRAFFIC_TX = 0x0, + BTC_WIFI_TRAFFIC_RX = 0x1, + BTC_WIFI_TRAFFIC_MAX +}; + +enum btc_wifi_pnp { + BTC_WIFI_PNP_WAKE_UP = 0x0, + BTC_WIFI_PNP_SLEEP = 0x1, + BTC_WIFI_PNP_SLEEP_KEEP_ANT = 0x2, + BTC_WIFI_PNP_MAX +}; + +enum btc_iot_peer { + BTC_IOT_PEER_UNKNOWN = 0, + BTC_IOT_PEER_REALTEK = 1, + BTC_IOT_PEER_REALTEK_92SE = 2, + BTC_IOT_PEER_BROADCOM = 3, + BTC_IOT_PEER_RALINK = 4, + BTC_IOT_PEER_ATHEROS = 5, + BTC_IOT_PEER_CISCO = 6, + BTC_IOT_PEER_MERU = 7, + BTC_IOT_PEER_MARVELL = 8, + BTC_IOT_PEER_REALTEK_SOFTAP = 9, + BTC_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */ + BTC_IOT_PEER_AIRGO = 11, + BTC_IOT_PEER_REALTEK_JAGUAR_BCUTAP = 12, + BTC_IOT_PEER_REALTEK_JAGUAR_CCUTAP = 13, + BTC_IOT_PEER_MAX, +}; + +/* for 8723b-d cut large current issue */ +enum bt_wifi_coex_state { + BTC_WIFI_STAT_INIT, + BTC_WIFI_STAT_IQK, + BTC_WIFI_STAT_NORMAL_OFF, + BTC_WIFI_STAT_MP_OFF, + BTC_WIFI_STAT_NORMAL, + BTC_WIFI_STAT_ANT_DIV, + BTC_WIFI_STAT_MAX +}; + +enum bt_ant_type { + BTC_ANT_TYPE_0, + BTC_ANT_TYPE_1, + BTC_ANT_TYPE_2, + BTC_ANT_TYPE_3, + BTC_ANT_TYPE_4, + BTC_ANT_TYPE_MAX +}; + +enum btc_get_type { + /* type bool */ + BTC_GET_BL_HS_OPERATION, + BTC_GET_BL_HS_CONNECTING, + BTC_GET_BL_WIFI_CONNECTED, + BTC_GET_BL_WIFI_DUAL_BAND_CONNECTED, + BTC_GET_BL_WIFI_BUSY, + BTC_GET_BL_WIFI_SCAN, + BTC_GET_BL_WIFI_LINK, + BTC_GET_BL_WIFI_DHCP, + BTC_GET_BL_WIFI_SOFTAP_IDLE, + BTC_GET_BL_WIFI_SOFTAP_LINKING, + BTC_GET_BL_WIFI_IN_EARLY_SUSPEND, + BTC_GET_BL_WIFI_ROAM, + BTC_GET_BL_WIFI_4_WAY_PROGRESS, + BTC_GET_BL_WIFI_UNDER_5G, + BTC_GET_BL_WIFI_AP_MODE_ENABLE, + BTC_GET_BL_WIFI_ENABLE_ENCRYPTION, + BTC_GET_BL_WIFI_UNDER_B_MODE, + BTC_GET_BL_EXT_SWITCH, + BTC_GET_BL_WIFI_IS_IN_MP_MODE, + BTC_GET_BL_IS_ASUS_8723B, + BTC_GET_BL_FW_READY, + BTC_GET_BL_RF4CE_CONNECTED, + + /* type s4Byte */ + BTC_GET_S4_WIFI_RSSI, + BTC_GET_S4_HS_RSSI, + + /* type u32 */ + BTC_GET_U4_WIFI_BW, + BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + BTC_GET_U4_WIFI_FW_VER, + BTC_GET_U4_WIFI_LINK_STATUS, + BTC_GET_U4_BT_PATCH_VER, + BTC_GET_U4_VENDOR, + BTC_GET_U4_SUPPORTED_VERSION, + BTC_GET_U4_SUPPORTED_FEATURE, + BTC_GET_U4_BT_DEVICE_INFO, + BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL, + BTC_GET_U4_WIFI_IQK_TOTAL, + BTC_GET_U4_WIFI_IQK_OK, + BTC_GET_U4_WIFI_IQK_FAIL, + + /* type u1Byte */ + BTC_GET_U1_WIFI_DOT11_CHNL, + BTC_GET_U1_WIFI_CENTRAL_CHNL, + BTC_GET_U1_WIFI_HS_CHNL, + BTC_GET_U1_MAC_PHY_MODE, + BTC_GET_U1_AP_NUM, + BTC_GET_U1_ANT_TYPE, + BTC_GET_U1_IOT_PEER, + + /* for 1Ant */ + BTC_GET_U1_LPS_MODE, + BTC_GET_BL_BT_SCO_BUSY, + + /* for test mode */ + BTC_GET_DRIVER_TEST_CFG, + BTC_GET_MAX +}; + +enum btc_vendor { + BTC_VENDOR_LENOVO, + BTC_VENDOR_ASUS, + BTC_VENDOR_OTHER +}; + +enum btc_set_type { + /* type bool */ + BTC_SET_BL_BT_DISABLE, + BTC_SET_BL_BT_TRAFFIC_BUSY, + BTC_SET_BL_BT_LIMITED_DIG, + BTC_SET_BL_FORCE_TO_ROAM, + BTC_SET_BL_TO_REJ_AP_AGG_PKT, + BTC_SET_BL_BT_CTRL_AGG_SIZE, + BTC_SET_BL_INC_SCAN_DEV_NUM, + BTC_SET_BL_BT_TX_RX_MASK, + BTC_SET_BL_MIRACAST_PLUS_BT, + + /* type u1Byte */ + BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, + BTC_SET_UI_SCAN_SIG_COMPENSATION, + BTC_SET_U1_AGG_BUF_SIZE, + + /* type trigger some action */ + BTC_SET_ACT_GET_BT_RSSI, + BTC_SET_ACT_AGGREGATE_CTRL, + BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, + BTC_SET_MIMO_PS_MODE, + + /********* for 1Ant **********/ + /* type bool */ + BTC_SET_BL_BT_SCO_BUSY, + /* type u1Byte */ + BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, + BTC_SET_U1_LPS_VAL, + BTC_SET_U1_RPWM_VAL, + BTC_SET_U1_1ANT_LPS, + BTC_SET_U1_1ANT_RPWM, + /* type trigger some action */ + BTC_SET_ACT_LEAVE_LPS, + BTC_SET_ACT_ENTER_LPS, + BTC_SET_ACT_NORMAL_LPS, + BTC_SET_ACT_PRE_NORMAL_LPS, + BTC_SET_ACT_POST_NORMAL_LPS, + BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, + BTC_SET_ACT_DISABLE_LOW_POWER, + BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL, + BTC_SET_ACT_UPDATE_RAMASK, + BTC_SET_ACT_SEND_MIMO_PS, + /* BT Coex related */ + BTC_SET_ACT_CTRL_BT_INFO, + BTC_SET_ACT_CTRL_BT_COEX, + BTC_SET_ACT_CTRL_8723B_ANT, + /***************************/ + BTC_SET_MAX +}; + +enum btc_dbg_disp_type { + BTC_DBG_DISP_COEX_STATISTICS = 0x0, + BTC_DBG_DISP_BT_LINK_INFO = 0x1, + BTC_DBG_DISP_BT_FW_VER = 0x2, + BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3, + BTC_DBG_DISP_WIFI_STATUS = 0x04, + BTC_DBG_DISP_MAX +}; + +enum btc_notify_type_ips { + BTC_IPS_LEAVE = 0x0, + BTC_IPS_ENTER = 0x1, + BTC_IPS_MAX +}; + +enum btc_notify_type_lps { + BTC_LPS_DISABLE = 0x0, + BTC_LPS_ENABLE = 0x1, + BTC_LPS_MAX +}; + +enum btc_notify_type_scan { + BTC_SCAN_FINISH = 0x0, + BTC_SCAN_START = 0x1, + BTC_SCAN_START_2G = 0x2, + BTC_SCAN_MAX +}; + +enum btc_notify_type_switchband { + BTC_NOT_SWITCH = 0x0, + BTC_SWITCH_TO_24G = 0x1, + BTC_SWITCH_TO_5G = 0x2, + BTC_SWITCH_TO_24G_NOFORSCAN = 0x3, + BTC_SWITCH_MAX +}; + +enum btc_notify_type_associate { + BTC_ASSOCIATE_FINISH = 0x0, + BTC_ASSOCIATE_START = 0x1, + BTC_ASSOCIATE_5G_FINISH = 0x2, + BTC_ASSOCIATE_5G_START = 0x3, + BTC_ASSOCIATE_MAX +}; + +enum btc_notify_type_media_status { + BTC_MEDIA_DISCONNECT = 0x0, + BTC_MEDIA_CONNECT = 0x1, + BTC_MEDIA_MAX +}; + +enum btc_notify_type_special_packet { + BTC_PACKET_UNKNOWN = 0x0, + BTC_PACKET_DHCP = 0x1, + BTC_PACKET_ARP = 0x2, + BTC_PACKET_EAPOL = 0x3, + BTC_PACKET_MAX +}; + +enum hci_ext_bt_operation { + HCI_BT_OP_NONE = 0x0, + HCI_BT_OP_INQUIRY_START = 0x1, + HCI_BT_OP_INQUIRY_FINISH = 0x2, + HCI_BT_OP_PAGING_START = 0x3, + HCI_BT_OP_PAGING_SUCCESS = 0x4, + HCI_BT_OP_PAGING_UNSUCCESS = 0x5, + HCI_BT_OP_PAIRING_START = 0x6, + HCI_BT_OP_PAIRING_FINISH = 0x7, + HCI_BT_OP_BT_DEV_ENABLE = 0x8, + HCI_BT_OP_BT_DEV_DISABLE = 0x9, + HCI_BT_OP_MAX +}; + +enum btc_notify_type_stack_operation { + BTC_STACK_OP_NONE = 0x0, + BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, + BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2, + BTC_STACK_OP_MAX +}; + +enum { + BTC_CCK_1, + BTC_CCK_2, + BTC_CCK_5_5, + BTC_CCK_11, + BTC_OFDM_6, + BTC_OFDM_9, + BTC_OFDM_12, + BTC_OFDM_18, + BTC_OFDM_24, + BTC_OFDM_36, + BTC_OFDM_48, + BTC_OFDM_54, + BTC_MCS_0, + BTC_MCS_1, + BTC_MCS_2, + BTC_MCS_3, + BTC_MCS_4, + BTC_MCS_5, + BTC_MCS_6, + BTC_MCS_7, + BTC_MCS_8, + BTC_MCS_9, + BTC_MCS_10, + BTC_MCS_11, + BTC_MCS_12, + BTC_MCS_13, + BTC_MCS_14, + BTC_MCS_15, + BTC_MCS_16, + BTC_MCS_17, + BTC_MCS_18, + BTC_MCS_19, + BTC_MCS_20, + BTC_MCS_21, + BTC_MCS_22, + BTC_MCS_23, + BTC_MCS_24, + BTC_MCS_25, + BTC_MCS_26, + BTC_MCS_27, + BTC_MCS_28, + BTC_MCS_29, + BTC_MCS_30, + BTC_MCS_31, + BTC_VHT_1SS_MCS_0, + BTC_VHT_1SS_MCS_1, + BTC_VHT_1SS_MCS_2, + BTC_VHT_1SS_MCS_3, + BTC_VHT_1SS_MCS_4, + BTC_VHT_1SS_MCS_5, + BTC_VHT_1SS_MCS_6, + BTC_VHT_1SS_MCS_7, + BTC_VHT_1SS_MCS_8, + BTC_VHT_1SS_MCS_9, + BTC_VHT_2SS_MCS_0, + BTC_VHT_2SS_MCS_1, + BTC_VHT_2SS_MCS_2, + BTC_VHT_2SS_MCS_3, + BTC_VHT_2SS_MCS_4, + BTC_VHT_2SS_MCS_5, + BTC_VHT_2SS_MCS_6, + BTC_VHT_2SS_MCS_7, + BTC_VHT_2SS_MCS_8, + BTC_VHT_2SS_MCS_9, + BTC_VHT_3SS_MCS_0, + BTC_VHT_3SS_MCS_1, + BTC_VHT_3SS_MCS_2, + BTC_VHT_3SS_MCS_3, + BTC_VHT_3SS_MCS_4, + BTC_VHT_3SS_MCS_5, + BTC_VHT_3SS_MCS_6, + BTC_VHT_3SS_MCS_7, + BTC_VHT_3SS_MCS_8, + BTC_VHT_3SS_MCS_9, + BTC_VHT_4SS_MCS_0, + BTC_VHT_4SS_MCS_1, + BTC_VHT_4SS_MCS_2, + BTC_VHT_4SS_MCS_3, + BTC_VHT_4SS_MCS_4, + BTC_VHT_4SS_MCS_5, + BTC_VHT_4SS_MCS_6, + BTC_VHT_4SS_MCS_7, + BTC_VHT_4SS_MCS_8, + BTC_VHT_4SS_MCS_9, + BTC_MCS_32, + BTC_UNKNOWN, + BTC_PKT_MGNT, + BTC_PKT_CTRL, + BTC_PKT_UNKNOWN, + BTC_PKT_NOT_FOR_ME, + BTC_RATE_MAX +}; + +enum { + BTC_MULTIPORT_SCC, + BTC_MULTIPORT_MCC_2CHANNEL, + BTC_MULTIPORT_MCC_2BAND, + BTC_MULTIPORT_MAX +}; + +struct btc_bt_info { + bool bt_disabled; + u8 rssi_adjust_for_agc_table_on; + u8 rssi_adjust_for_1ant_coex_type; + bool pre_bt_ctrl_agg_buf_size; + bool bt_busy; + u8 pre_agg_buf_size; + u8 agg_buf_size; + bool limited_dig; + bool pre_reject_agg_pkt; + bool reject_agg_pkt; + bool bt_ctrl_buf_size; + bool increase_scan_dev_num; + bool miracast_plus_bt; + bool bt_ctrl_agg_buf_size; + bool bt_tx_rx_mask; + u16 bt_hci_ver; + u16 bt_real_fw_ver; + u8 bt_fw_ver; + u32 bt_get_fw_ver; + + bool bt_disable_low_pwr; + + /* the following is for 1Ant solution */ + bool bt_ctrl_lps; + bool bt_pwr_save_mode; + bool bt_lps_on; + bool force_to_roam; + u8 force_exec_pwr_cmd_cnt; + u8 lps_val; + u8 rpwm_val; + u32 ra_mask; + + u32 afh_map_l; + u32 afh_map_m; + u16 afh_map_h; + u32 bt_supported_feature; + u32 bt_supported_version; + u32 bt_device_info; + u32 bt_forb_slot_val; + u8 bt_ant_det_val; + u8 bt_ble_scan_type; + u32 bt_ble_scan_para; +}; + +struct btc_stack_info { + bool profile_notified; + u16 hci_version; /* stack hci version */ + u8 num_of_link; + bool bt_link_exist; + bool sco_exist; + bool acl_exist; + bool a2dp_exist; + bool hid_exist; + u8 num_of_hid; + bool pan_exist; + bool unknown_acl_exist; + s8 min_bt_rssi; +}; + +struct btc_statistics { + u32 cnt_bind; + u32 cnt_init_hw_config; + u32 cnt_init_coex_dm; + u32 cnt_ips_notify; + u32 cnt_lps_notify; + u32 cnt_scan_notify; + u32 cnt_connect_notify; + u32 cnt_media_status_notify; + u32 cnt_special_packet_notify; + u32 cnt_bt_info_notify; + u32 cnt_periodical; + u32 cnt_coex_dm_switch; + u32 cnt_stack_operation_notify; + u32 cnt_dbg_ctrl; + u32 cnt_pre_load_firmware; + u32 cnt_power_on; +}; + +struct btc_bt_link_info { + bool bt_link_exist; + bool bt_hi_pri_link_exist; + bool sco_exist; + bool sco_only; + bool a2dp_exist; + bool a2dp_only; + bool hid_exist; + bool hid_only; + bool pan_exist; + bool pan_only; + bool slave_role; + bool acl_busy; +}; + +enum btc_antenna_pos { + BTC_ANTENNA_AT_MAIN_PORT = 0x1, + BTC_ANTENNA_AT_AUX_PORT = 0x2, +}; + +enum btc_mp_h2c_op_code { + BT_OP_GET_BT_VERSION = 0, + BT_OP_WRITE_REG_ADDR = 12, + BT_OP_WRITE_REG_VALUE = 13, + BT_OP_READ_REG = 17, + BT_OP_GET_AFH_MAP_L = 30, + BT_OP_GET_AFH_MAP_M = 31, + BT_OP_GET_AFH_MAP_H = 32, + BT_OP_GET_BT_COEX_SUPPORTED_FEATURE = 42, + BT_OP_GET_BT_COEX_SUPPORTED_VERSION = 43, + BT_OP_GET_BT_ANT_DET_VAL = 44, + BT_OP_GET_BT_BLE_SCAN_PARA = 45, + BT_OP_GET_BT_BLE_SCAN_TYPE = 46, + BT_OP_GET_BT_DEVICE_INFO = 48, + BT_OP_GET_BT_FORBIDDEN_SLOT_VAL = 49, + BT_OP_MAX +}; + +enum btc_mp_h2c_req_num { + /* 4 bits only */ + BT_SEQ_DONT_CARE = 0, + BT_SEQ_GET_BT_VERSION = 0xE, + BT_SEQ_GET_AFH_MAP_L = 0x5, + BT_SEQ_GET_AFH_MAP_M = 0x6, + BT_SEQ_GET_AFH_MAP_H = 0x9, + BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE = 0x7, + BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION = 0x8, + BT_SEQ_GET_BT_ANT_DET_VAL = 0x2, + BT_SEQ_GET_BT_BLE_SCAN_PARA = 0x3, + BT_SEQ_GET_BT_BLE_SCAN_TYPE = 0x4, + BT_SEQ_GET_BT_DEVICE_INFO = 0xA, + BT_SEQ_GET_BT_FORB_SLOT_VAL = 0xB, +}; + +struct btc_coexist { + /* make sure only one adapter can bind the data context */ + bool binded; + /* default adapter */ + void *adapter; + struct btc_board_info board_info; + /* some bt info referenced by non-bt module */ + struct btc_bt_info bt_info; + struct btc_stack_info stack_info; + enum btc_chip_interface chip_interface; + struct btc_bt_link_info bt_link_info; + + /* boolean variables to replace BT_AUTO_REPORT_ONLY_XXXXY_ZANT + * configuration parameters + */ + bool auto_report_1ant; + bool auto_report_2ant; + bool dbg_mode_1ant; + bool dbg_mode_2ant; + bool initialized; + bool stop_coex_dm; + bool manual_control; + struct btc_statistics statistics; + u8 pwr_mode_val[10]; + + struct completion bt_mp_comp; + + /* function pointers - io related */ + u8 (*btc_read_1byte)(void *btc_context, u32 reg_addr); + void (*btc_write_1byte)(void *btc_context, u32 reg_addr, u32 data); + void (*btc_write_1byte_bitmask)(void *btc_context, u32 reg_addr, + u32 bit_mask, u8 data1b); + u16 (*btc_read_2byte)(void *btc_context, u32 reg_addr); + void (*btc_write_2byte)(void *btc_context, u32 reg_addr, u16 data); + u32 (*btc_read_4byte)(void *btc_context, u32 reg_addr); + void (*btc_write_4byte)(void *btc_context, u32 reg_addr, u32 data); + + void (*btc_write_local_reg_1byte)(void *btc_context, u32 reg_addr, + u8 data); + void (*btc_set_bb_reg)(void *btc_context, u32 reg_addr, + u32 bit_mask, u32 data); + u32 (*btc_get_bb_reg)(void *btc_context, u32 reg_addr, + u32 bit_mask); + void (*btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr, + u32 bit_mask, u32 data); + u32 (*btc_get_rf_reg)(void *btc_context, u8 rf_path, + u32 reg_addr, u32 bit_mask); + + void (*btc_fill_h2c)(void *btc_context, u8 element_id, + u32 cmd_len, u8 *cmd_buffer); + + void (*btc_disp_dbg_msg)(void *btcoexist, u8 disp_type, + struct seq_file *m); + + bool (*btc_get)(void *btcoexist, u8 get_type, void *out_buf); + bool (*btc_set)(void *btcoexist, u8 set_type, void *in_buf); + + void (*btc_set_bt_reg)(void *btc_context, u8 reg_type, u32 offset, + u32 value); + u32 (*btc_get_bt_reg)(void *btc_context, u8 reg_type, u32 offset); + u32 (*btc_get_bt_coex_supported_feature)(void *btcoexist); + u32 (*btc_get_bt_coex_supported_version)(void *btcoexist); + u32 (*btc_get_bt_phydm_version)(void *btcoexist); + void (*btc_phydm_modify_ra_pcr_threshold)(void *btcoexist, + u8 ra_offset_direction, + u8 ra_threshold_offset); + u32 (*btc_phydm_query_phy_counter)(void *btcoexist, + enum dm_info_query dm_id); + u8 (*btc_get_ant_det_val_from_bt)(void *btcoexist); + u8 (*btc_get_ble_scan_type_from_bt)(void *btcoexist); + u32 (*btc_get_ble_scan_para_from_bt)(void *btcoexist, u8 scan_type); + bool (*btc_get_bt_afh_map_from_bt)(void *btcoexist, u8 map_type, + u8 *afh_map); +}; + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter); + +#define rtl_btc_coexist(rtlpriv) \ + ((struct btc_coexist *)((rtlpriv)->btcoexist.btc_context)) +#define rtl_btc_wifi_only(rtlpriv) \ + ((struct wifi_only_cfg *)((rtlpriv)->btcoexist.wifi_only_context)) + +struct wifi_only_cfg; + +bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv); +bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv); +bool exhalbtc_bind_bt_coex_withadapter(void *adapter); +void exhalbtc_power_on_setting(struct btc_coexist *btcoexist); +void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist); +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only); +void exhalbtc_init_hw_config_wifi_only(struct wifi_only_cfg *wifionly_cfg); +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist); +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_scan_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg, + u8 is_5g); +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, + enum rt_media_status media_status); +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, + u8 length); +void exhalbtc_halt_notify(struct btc_coexist *btcoexist); +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); +void exhalbtc_periodical(struct btc_coexist *btcoexist); +void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi); +void exhalbtc_set_bt_exist(struct btc_coexist *btcoexist, bool bt_exist); +void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type); +void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num); +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist, + struct seq_file *m); +void exhalbtc_switch_band_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_switch_band_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg, + u8 is_5g); +void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, + u8 *rssi_wifi, u8 *rssi_bt); +void exhalbtc_lps_leave(struct btc_coexist *btcoexist); +void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist); +void exhalbtc_set_single_ant_path(struct btc_coexist *btcoexist, + u8 single_ant_path); +void halbtc_send_wifi_port_id_cmd(void *bt_context); +void halbtc_set_default_port_id_cmd(void *bt_context); + +/* The following are used by wifi_only case */ +enum wifionly_chip_interface { + WIFIONLY_INTF_UNKNOWN = 0, + WIFIONLY_INTF_PCI = 1, + WIFIONLY_INTF_USB = 2, + WIFIONLY_INTF_SDIO = 3, + WIFIONLY_INTF_MAX +}; + +enum wifionly_customer_id { + CUSTOMER_NORMAL = 0, + CUSTOMER_HP_1 = 1, +}; + +struct wifi_only_haldata { + u16 customer_id; + u8 efuse_pg_antnum; + u8 efuse_pg_antpath; + u8 rfe_type; + u8 ant_div_cfg; +}; + +struct wifi_only_cfg { + void *adapter; + struct wifi_only_haldata haldata_info; + enum wifionly_chip_interface chip_interface; +}; + +static inline +void halwifionly_phy_set_bb_reg(struct wifi_only_cfg *wifi_conly_cfg, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)wifi_conly_cfg->adapter; + + rtl_set_bbreg(rtlpriv->hw, regaddr, bitmask, data); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c new file mode 100644 index 000000000..bcd8bc270 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include +#include + +#include "rtl_btc.h" +#include "halbt_precomp.h" + +static struct rtl_btc_ops rtl_btc_operation = { + .btc_init_variables = rtl_btc_init_variables, + .btc_init_variables_wifi_only = rtl_btc_init_variables_wifi_only, + .btc_deinit_variables = rtl_btc_deinit_variables, + .btc_init_hal_vars = rtl_btc_init_hal_vars, + .btc_power_on_setting = rtl_btc_power_on_setting, + .btc_init_hw_config = rtl_btc_init_hw_config, + .btc_init_hw_config_wifi_only = rtl_btc_init_hw_config_wifi_only, + .btc_ips_notify = rtl_btc_ips_notify, + .btc_lps_notify = rtl_btc_lps_notify, + .btc_scan_notify = rtl_btc_scan_notify, + .btc_scan_notify_wifi_only = rtl_btc_scan_notify_wifi_only, + .btc_connect_notify = rtl_btc_connect_notify, + .btc_mediastatus_notify = rtl_btc_mediastatus_notify, + .btc_periodical = rtl_btc_periodical, + .btc_halt_notify = rtl_btc_halt_notify, + .btc_btinfo_notify = rtl_btc_btinfo_notify, + .btc_btmpinfo_notify = rtl_btc_btmpinfo_notify, + .btc_is_limited_dig = rtl_btc_is_limited_dig, + .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, + .btc_is_bt_disabled = rtl_btc_is_bt_disabled, + .btc_special_packet_notify = rtl_btc_special_packet_notify, + .btc_switch_band_notify = rtl_btc_switch_band_notify, + .btc_switch_band_notify_wifi_only = rtl_btc_switch_band_notify_wifionly, + .btc_record_pwr_mode = rtl_btc_record_pwr_mode, + .btc_get_lps_val = rtl_btc_get_lps_val, + .btc_get_rpwm_val = rtl_btc_get_rpwm_val, + .btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps, + .btc_is_bt_lps_on = rtl_btc_is_bt_lps_on, + .btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg, + .btc_display_bt_coex_info = rtl_btc_display_bt_coex_info, +}; + +void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) { + seq_puts(m, "btc_coexist context is NULL!\n"); + return; + } + + exhalbtc_display_bt_coex_info(btcoexist, m); +} + +void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + u8 safe_len; + + if (!btcoexist) + return; + + safe_len = sizeof(btcoexist->pwr_mode_val); + + if (safe_len > len) + safe_len = len; + + memcpy(btcoexist->pwr_mode_val, buf, safe_len); +} + +u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return 0; + + return btcoexist->bt_info.lps_val; +} + +u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return 0; + + return btcoexist->bt_info.rpwm_val; +} + +bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return false; + + return btcoexist->bt_info.bt_ctrl_lps; +} + +bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return false; + + return btcoexist->bt_info.bt_lps_on; +} + +void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg, + u8 *ctrl_agg_size, u8 *agg_size) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) { + *reject_agg = false; + *ctrl_agg_size = false; + return; + } + + if (reject_agg) + *reject_agg = btcoexist->bt_info.reject_agg_pkt; + if (ctrl_agg_size) + *ctrl_agg_size = btcoexist->bt_info.bt_ctrl_agg_buf_size; + if (agg_size) + *agg_size = btcoexist->bt_info.agg_buf_size; +} + +static void rtl_btc_alloc_variable(struct rtl_priv *rtlpriv, bool wifi_only) +{ + if (wifi_only) + rtlpriv->btcoexist.wifi_only_context = + kzalloc_obj(struct wifi_only_cfg); + else + rtlpriv->btcoexist.btc_context = + kzalloc_obj(struct btc_coexist); +} + +static void rtl_btc_free_variable(struct rtl_priv *rtlpriv) +{ + kfree(rtlpriv->btcoexist.btc_context); + rtlpriv->btcoexist.btc_context = NULL; + + kfree(rtlpriv->btcoexist.wifi_only_context); + rtlpriv->btcoexist.wifi_only_context = NULL; +} + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv) +{ + rtl_btc_alloc_variable(rtlpriv, false); + + exhalbtc_initlize_variables(rtlpriv); + exhalbtc_bind_bt_coex_withadapter(rtlpriv); +} + +void rtl_btc_init_variables_wifi_only(struct rtl_priv *rtlpriv) +{ + rtl_btc_alloc_variable(rtlpriv, true); + + exhalbtc_initlize_variables_wifi_only(rtlpriv); +} + +void rtl_btc_deinit_variables(struct rtl_priv *rtlpriv) +{ + rtl_btc_free_variable(rtlpriv); +} + +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv) +{ + /* move ant_num, bt_type and single_ant_path to + * exhalbtc_bind_bt_coex_withadapter() + */ +} + +void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_power_on_setting(btcoexist); +} + +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + u8 bt_exist; + + bt_exist = rtl_get_hwpg_bt_exist(rtlpriv); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "%s, bt_exist is %d\n", __func__, bt_exist); + + if (!btcoexist) + return; + + exhalbtc_init_hw_config(btcoexist, !bt_exist); + exhalbtc_init_coex_dm(btcoexist); +} + +void rtl_btc_init_hw_config_wifi_only(struct rtl_priv *rtlpriv) +{ + struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv); + + if (!wifionly_cfg) + return; + + exhalbtc_init_hw_config_wifi_only(wifionly_cfg); +} + +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_ips_notify(btcoexist, type); + + if (type == ERFON) { + /* In some situation, it doesn't scan after leaving IPS, and + * this will cause btcoex in wrong state. + */ + exhalbtc_scan_notify(btcoexist, 1); + exhalbtc_scan_notify(btcoexist, 0); + } +} + +void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_lps_notify(btcoexist, type); +} + +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_scan_notify(btcoexist, scantype); +} + +void rtl_btc_scan_notify_wifi_only(struct rtl_priv *rtlpriv, u8 scantype) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv); + u8 is_5g = (rtlhal->current_bandtype == BAND_ON_5G); + + if (!wifionly_cfg) + return; + + exhalbtc_scan_notify_wifi_only(wifionly_cfg, is_5g); +} + +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_connect_notify(btcoexist, action); +} + +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, + enum rt_media_status mstatus) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_mediastatus_notify(btcoexist, mstatus); +} + +void rtl_btc_periodical(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + /*rtl_bt_dm_monitor();*/ + exhalbtc_periodical(btcoexist); +} + +void rtl_btc_halt_notify(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_halt_notify(btcoexist); +} + +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + exhalbtc_bt_info_notify(btcoexist, tmp_buf, length); +} + +void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + u8 extid, seq; + u16 bt_real_fw_ver; + u8 bt_fw_ver; + u8 *data; + + if (!btcoexist) + return; + + if ((length < 4) || (!tmp_buf)) + return; + + extid = tmp_buf[0]; + /* not response from BT FW then exit*/ + if (extid != 1) /* C2H_TRIG_BY_BT_FW = 1 */ + return; + + seq = tmp_buf[2] >> 4; + data = &tmp_buf[3]; + + /* BT Firmware version response */ + switch (seq) { + case BT_SEQ_GET_BT_VERSION: + bt_real_fw_ver = tmp_buf[3] | (tmp_buf[4] << 8); + bt_fw_ver = tmp_buf[5]; + + btcoexist->bt_info.bt_real_fw_ver = bt_real_fw_ver; + btcoexist->bt_info.bt_fw_ver = bt_fw_ver; + break; + case BT_SEQ_GET_AFH_MAP_L: + btcoexist->bt_info.afh_map_l = le32_to_cpu(*(__le32 *)data); + break; + case BT_SEQ_GET_AFH_MAP_M: + btcoexist->bt_info.afh_map_m = le32_to_cpu(*(__le32 *)data); + break; + case BT_SEQ_GET_AFH_MAP_H: + btcoexist->bt_info.afh_map_h = le16_to_cpu(*(__le16 *)data); + break; + case BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE: + btcoexist->bt_info.bt_supported_feature = tmp_buf[3] | + (tmp_buf[4] << 8); + break; + case BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION: + btcoexist->bt_info.bt_supported_version = tmp_buf[3] | + (tmp_buf[4] << 8); + break; + case BT_SEQ_GET_BT_ANT_DET_VAL: + btcoexist->bt_info.bt_ant_det_val = tmp_buf[3]; + break; + case BT_SEQ_GET_BT_BLE_SCAN_PARA: + btcoexist->bt_info.bt_ble_scan_para = tmp_buf[3] | + (tmp_buf[4] << 8) | + (tmp_buf[5] << 16) | + (tmp_buf[6] << 24); + break; + case BT_SEQ_GET_BT_BLE_SCAN_TYPE: + btcoexist->bt_info.bt_ble_scan_type = tmp_buf[3]; + break; + case BT_SEQ_GET_BT_DEVICE_INFO: + btcoexist->bt_info.bt_device_info = + le32_to_cpu(*(__le32 *)data); + break; + case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL: + btcoexist->bt_info.bt_forb_slot_val = + le32_to_cpu(*(__le32 *)data); + break; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "btmpinfo complete req_num=%d\n", seq); + + complete(&btcoexist->bt_mp_comp); +} + +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return false; + + return btcoexist->bt_info.limited_dig; +} + +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv) +{ + bool bt_change_edca = false; + u32 cur_edca_val; + u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b; + u32 edca_hs; + u32 edca_addr = 0x504; + + cur_edca_val = rtl_read_dword(rtlpriv, edca_addr); + if (halbtc_is_wifi_uplink(rtlpriv)) { + if (cur_edca_val != edca_bt_hs_uplink) { + edca_hs = edca_bt_hs_uplink; + bt_change_edca = true; + } + } else { + if (cur_edca_val != edca_bt_hs_downlink) { + edca_hs = edca_bt_hs_downlink; + bt_change_edca = true; + } + } + + if (bt_change_edca) + rtl_write_dword(rtlpriv, edca_addr, edca_hs); + + return true; +} + +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return true; + + /* It seems 'bt_disabled' is never be initialized or set. */ + if (btcoexist->bt_info.bt_disabled) + return true; + else + return false; +} + +void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + + if (!btcoexist) + return; + + return exhalbtc_special_packet_notify(btcoexist, pkt_type); +} + +void rtl_btc_switch_band_notify(struct rtl_priv *rtlpriv, u8 band_type, + bool scanning) +{ + struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv); + u8 type = BTC_NOT_SWITCH; + + if (!btcoexist) + return; + + switch (band_type) { + case BAND_ON_2_4G: + if (scanning) + type = BTC_SWITCH_TO_24G; + else + type = BTC_SWITCH_TO_24G_NOFORSCAN; + break; + + case BAND_ON_5G: + type = BTC_SWITCH_TO_5G; + break; + } + + if (type != BTC_NOT_SWITCH) + exhalbtc_switch_band_notify(btcoexist, type); +} + +void rtl_btc_switch_band_notify_wifionly(struct rtl_priv *rtlpriv, u8 band_type, + bool scanning) +{ + struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv); + u8 is_5g = (band_type == BAND_ON_5G); + + if (!wifionly_cfg) + return; + + exhalbtc_switch_band_notify_wifi_only(wifionly_cfg, is_5g); +} + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) +{ + return &rtl_btc_operation; +} +EXPORT_SYMBOL(rtl_btc_get_ops_pointer); + + +enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum rt_media_status m_status = RT_MEDIA_DISCONNECT; + + u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; + + if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) + m_status = RT_MEDIA_CONNECT; + + return m_status; +} + +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv) +{ + return rtlpriv->btcoexist.btc_info.btcoexist; +} + +MODULE_AUTHOR("Page He "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h new file mode 100644 index 000000000..bf2cf8505 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL_BTC_H__ +#define __RTL_BTC_H__ + +#include "halbt_precomp.h" + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv); +void rtl_btc_init_variables_wifi_only(struct rtl_priv *rtlpriv); +void rtl_btc_deinit_variables(struct rtl_priv *rtlpriv); +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); +void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv); +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); +void rtl_btc_init_hw_config_wifi_only(struct rtl_priv *rtlpriv); +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); +void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type); +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); +void rtl_btc_scan_notify_wifi_only(struct rtl_priv *rtlpriv, u8 scantype); +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, + enum rt_media_status mstatus); +void rtl_btc_periodical(struct rtl_priv *rtlpriv); +void rtl_btc_halt_notify(struct rtl_priv *rtlpriv); +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); +void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length); +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); +void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type); +void rtl_btc_switch_band_notify(struct rtl_priv *rtlpriv, u8 band_type, + bool scanning); +void rtl_btc_switch_band_notify_wifionly(struct rtl_priv *rtlpriv, u8 band_type, + bool scanning); +void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m); +void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len); +u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv); +u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv); +bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv); +bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv); +void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg, + u8 *ctrl_agg_size, u8 *agg_size); + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); + +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv); + +enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/cam.c b/drivers/net/wireless/realtek/rtlwifi/cam.c new file mode 100644 index 000000000..f9d0d1394 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/cam.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "cam.h" +#include + +void rtl_cam_reset_sec_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->sec.use_defaultkey = false; + rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION; + rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION; + memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN); + memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE); + rtlpriv->sec.pairwise_key = NULL; +} + +static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, + const u8 *mac_addr, u8 *key_cont_128, + u16 us_config) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 target_command; + u32 target_content = 0; + int entry_i; + + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :", + key_cont_128, 16); + + /* 0-1 config + mac, 2-5 fill 128key,6-7 are reserved */ + for (entry_i = CAM_CONTENT_COUNT - 1; entry_i >= 0; entry_i--) { + target_command = entry_i + CAM_CONTENT_COUNT * entry_no; + target_command = target_command | BIT(31) | BIT(16); + + if (entry_i == 0) { + target_content = (u32) (*(mac_addr + 0)) << 16 | + (u32) (*(mac_addr + 1)) << 24 | (u32) us_config; + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The Key ID is %d\n", entry_no); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); + + } else if (entry_i == 1) { + + target_content = (u32) (*(mac_addr + 5)) << 24 | + (u32) (*(mac_addr + 4)) << 16 | + (u32) (*(mac_addr + 3)) << 8 | + (u32) (*(mac_addr + 2)); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); + + } else { + + target_content = + (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) << + 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2)) + << 16 | + (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8 + | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0)); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], + target_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); + } + } + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "after set key, usconfig:%x\n", us_config); +} + +u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, const u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content) +{ + u32 us_config; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); + + if (ul_key_id == TOTAL_CAM_ENTRY) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ulKeyId exceed!\n"); + return 0; + } + + if (ul_default_key == 1) + us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2); + else + us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id; + + rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, + (u8 *)key_content, us_config); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "end\n"); + + return 1; + +} +EXPORT_SYMBOL(rtl_cam_add_one_entry); + +int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, + u8 *mac_addr, u32 ul_key_id) +{ + u32 ul_command; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); + + ul_command = ul_key_id * CAM_CONTENT_COUNT; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, 0); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); + + return 0; + +} +EXPORT_SYMBOL(rtl_cam_delete_one_entry); + +void rtl_cam_reset_all_entry(struct ieee80211_hw *hw) +{ + u32 ul_command; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + ul_command = BIT(31) | BIT(30); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); +} +EXPORT_SYMBOL(rtl_cam_reset_all_entry); + +void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 ul_command; + u32 ul_content; + u32 ul_enc_algo; + + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case WEP40_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40]; + break; + case WEP104_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104]; + break; + case TKIP_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP]; + break; + case AESCCMP_ENCRYPTION: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + break; + default: + ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + } + + ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2); + + ul_content |= BIT(15); + ul_command = CAM_CONTENT_COUNT * uc_index; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); +} +EXPORT_SYMBOL(rtl_cam_mark_invalid); + +void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 ul_command; + u32 ul_content; + u32 ul_encalgo; + u8 entry_i; + + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case WEP40_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40]; + break; + case WEP104_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104]; + break; + case TKIP_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP]; + break; + case AESCCMP_ENCRYPTION: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + break; + default: + ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + } + + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + + if (entry_i == 0) { + ul_content = + (uc_index & 0x03) | ((u16) (ul_encalgo) << 2); + ul_content |= BIT(15); + + } else { + ul_content = 0; + } + + ul_command = CAM_CONTENT_COUNT * uc_index + entry_i; + ul_command = ul_command | BIT(31) | BIT(16); + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A0: %x\n", __func__, ul_command); + } + +} +EXPORT_SYMBOL(rtl_cam_empty_entry); + +u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4; + u8 entry_idx = 0; + u8 i, *addr; + + if (NULL == sta_addr) { + pr_err("sta_addr is NULL.\n"); + return TOTAL_CAM_ENTRY; + } + /* Does STA already exist? */ + for (i = 4; i < TOTAL_CAM_ENTRY; i++) { + addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; + if (ether_addr_equal_unaligned(addr, sta_addr)) + return i; + } + /* Get a free CAM entry. */ + for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { + if ((bitmap & BIT(0)) == 0) { + pr_err("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx); + rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; + memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], + sta_addr, ETH_ALEN); + return entry_idx; + } + bitmap = bitmap >> 1; + } + return TOTAL_CAM_ENTRY; +} +EXPORT_SYMBOL(rtl_cam_get_free_entry); + +void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 bitmap; + u8 i, *addr; + + if (NULL == sta_addr) { + pr_err("sta_addr is NULL.\n"); + return; + } + + if (is_zero_ether_addr(sta_addr)) { + pr_err("sta_addr is %pM\n", sta_addr); + return; + } + /* Does STA already exist? */ + for (i = 4; i < TOTAL_CAM_ENTRY; i++) { + addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; + bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i; + if (((bitmap & BIT(0)) == BIT(0)) && + (ether_addr_equal_unaligned(addr, sta_addr))) { + /* Remove from HW Security CAM */ + eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); + rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "&&&&&&&&&del entry %d\n", i); + } + } + return; +} +EXPORT_SYMBOL(rtl_cam_del_entry); diff --git a/drivers/net/wireless/realtek/rtlwifi/cam.h b/drivers/net/wireless/realtek/rtlwifi/cam.h new file mode 100644 index 000000000..144807a40 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/cam.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_CAM_H_ +#define __RTL_CAM_H_ + +#define CAM_CONTENT_COUNT 8 + +#define CFG_VALID BIT(15) + +#define PAIRWISE_KEYIDX 0 +#define CAM_PAIRWISE_KEY_POSITION 4 + +#define CAM_CONFIG_NO_USEDK 0 + +void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); +u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, const u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content); +int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id); +void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); +void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); +void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); +u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr); +void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c new file mode 100644 index 000000000..22633c301 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/core.c @@ -0,0 +1,1958 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "core.h" +#include "cam.h" +#include "base.h" +#include "ps.h" +#include "pwrseqcmd.h" + +#include "btcoexist/rtl_btc.h" +#include +#include +#include + +u8 channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177 /* Band 4 */ +}; +EXPORT_SYMBOL(channel5g); + +u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = { + 42, 58, 106, 122, 138, 155, 171 +}; +EXPORT_SYMBOL(channel5g_80m); + +void rtl_addr_delay(u32 addr) +{ + if (addr == 0xfe) + mdelay(50); + else if (addr == 0xfd) + msleep(5); + else if (addr == 0xfc) + msleep(1); + else if (addr == 0xfb) + usleep_range(50, 100); + else if (addr == 0xfa) + usleep_range(5, 10); + else if (addr == 0xf9) + usleep_range(1, 2); +} +EXPORT_SYMBOL(rtl_addr_delay); + +void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, + u32 mask, u32 data) +{ + if (addr >= 0xf9 && addr <= 0xfe) { + rtl_addr_delay(addr); + } else { + rtl_set_rfreg(hw, rfpath, addr, mask, data); + udelay(1); + } +} +EXPORT_SYMBOL(rtl_rfreg_delay); + +static void rtl_fw_do_work(const struct firmware *firmware, void *context, + bool is_wow) +{ + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + if (!firmware) { + if (rtlpriv->cfg->alt_fw_name) { + err = request_firmware(&firmware, + rtlpriv->cfg->alt_fw_name, + rtlpriv->io.dev); + pr_info("Loading alternative firmware %s\n", + rtlpriv->cfg->alt_fw_name); + if (!err) + goto found_alt; + } + pr_err("Selected firmware is not available\n"); + rtlpriv->max_fw_size = 0; + goto exit; + } +found_alt: + if (firmware->size > rtlpriv->max_fw_size) { + pr_err("Firmware is too big!\n"); + release_firmware(firmware); + goto exit; + } + if (!is_wow) { + memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, + firmware->size); + rtlpriv->rtlhal.fwsize = firmware->size; + } else { + memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data, + firmware->size); + rtlpriv->rtlhal.wowlan_fwsize = firmware->size; + } + release_firmware(firmware); + +exit: + complete(&rtlpriv->firmware_loading_complete); +} + +void rtl_fw_cb(const struct firmware *firmware, void *context) +{ + rtl_fw_do_work(firmware, context, false); +} +EXPORT_SYMBOL(rtl_fw_cb); + +void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context) +{ + rtl_fw_do_work(firmware, context, true); +} +EXPORT_SYMBOL(rtl_wowlan_fw_cb); + +/*mutex for start & stop is must here. */ +static int rtl_op_start(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (!is_hal_stop(rtlhal)) + return 0; + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + return 0; + mutex_lock(&rtlpriv->locks.conf_mutex); + err = rtlpriv->intf_ops->adapter_start(hw); + if (!err) + rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer); + mutex_unlock(&rtlpriv->locks.conf_mutex); + return err; +} + +static void rtl_op_stop(struct ieee80211_hw *hw, bool suspend) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool support_remote_wakeup = false; + + if (is_hal_stop(rtlhal)) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&support_remote_wakeup)); + /* here is must, because adhoc do stop and start, + * but stop with RFOFF may cause something wrong, + * like adhoc TP + */ + if (unlikely(ppsc->rfpwr_state == ERFOFF)) + rtl_ips_nic_on(hw); + + mutex_lock(&rtlpriv->locks.conf_mutex); + /* if wowlan supported, DON'T clear connected info */ + if (!(support_remote_wakeup && + rtlhal->enter_pnp_sleep)) { + mac->link_state = MAC80211_NOLINK; + eth_zero_addr(mac->bssid); + mac->vendor = PEER_UNKNOWN; + + /* reset sec info */ + rtl_cam_reset_sec_info(hw); + + rtl_deinit_deferred_work(hw, false); + } + rtlpriv->intf_ops->adapter_stop(hw); + + mutex_unlock(&rtlpriv->locks.conf_mutex); +} + +static void rtl_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_tcb_desc tcb_desc; + + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + + if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) + goto err_free; + + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + goto err_free; + + if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb)) + rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc); + return; + +err_free: + dev_kfree_skb_any(skb); +} + +static int rtl_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + int err = 0; + u8 retry_limit = 0x30; + + if (mac->vif) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "vif has been set!! mac->vif = 0x%p\n", mac->vif); + return -EOPNOTSUPP; + } + + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + + rtl_ips_nic_on(hw); + + mutex_lock(&rtlpriv->locks.conf_mutex); + switch (ieee80211_vif_type_p2p(vif)) { + case NL80211_IFTYPE_P2P_CLIENT: + mac->p2p = P2P_ROLE_CLIENT; + fallthrough; + case NL80211_IFTYPE_STATION: + if (mac->beacon_enabled == 1) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_STATION\n"); + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]); + } + break; + case NL80211_IFTYPE_ADHOC: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_ADHOC\n"); + + mac->link_state = MAC80211_LINKED; + rtlpriv->cfg->ops->set_bcn_reg(hw); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + mac->basic_rates = 0xfff; + else + mac->basic_rates = 0xff0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)(&mac->basic_rates)); + + retry_limit = 0x07; + break; + case NL80211_IFTYPE_P2P_GO: + mac->p2p = P2P_ROLE_GO; + fallthrough; + case NL80211_IFTYPE_AP: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_AP\n"); + + mac->link_state = MAC80211_LINKED; + rtlpriv->cfg->ops->set_bcn_reg(hw); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + mac->basic_rates = 0xfff; + else + mac->basic_rates = 0xff0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)(&mac->basic_rates)); + + retry_limit = 0x07; + break; + case NL80211_IFTYPE_MESH_POINT: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_MESH_POINT\n"); + + mac->link_state = MAC80211_LINKED; + rtlpriv->cfg->ops->set_bcn_reg(hw); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + mac->basic_rates = 0xfff; + else + mac->basic_rates = 0xff0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)(&mac->basic_rates)); + + retry_limit = 0x07; + break; + default: + pr_err("operation mode %d is not supported!\n", + vif->type); + err = -EOPNOTSUPP; + goto out; + } + + if (mac->p2p) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p role %x\n", vif->type); + mac->basic_rates = 0xff0;/*disable cck rate for p2p*/ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)(&mac->basic_rates)); + } + mac->vif = vif; + mac->opmode = vif->type; + rtlpriv->cfg->ops->set_network_type(hw, vif->type); + memcpy(mac->mac_addr, vif->addr, ETH_ALEN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + + mac->retry_long = retry_limit; + mac->retry_short = retry_limit; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + (u8 *)(&retry_limit)); +out: + mutex_unlock(&rtlpriv->locks.conf_mutex); + return err; +} + +static void rtl_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + mutex_lock(&rtlpriv->locks.conf_mutex); + + /* Free beacon resources */ + if (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) { + if (mac->beacon_enabled == 1) { + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]); + } + } + + /* + *Note: We assume NL80211_IFTYPE_UNSPECIFIED as + *NO LINK for our hardware. + */ + mac->p2p = 0; + mac->vif = NULL; + mac->link_state = MAC80211_NOLINK; + eth_zero_addr(mac->bssid); + mac->vendor = PEER_UNKNOWN; + mac->opmode = NL80211_IFTYPE_UNSPECIFIED; + rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); + + mutex_unlock(&rtlpriv->locks.conf_mutex); +} + +static int rtl_op_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype new_type, bool p2p) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int ret; + + rtl_op_remove_interface(hw, vif); + + vif->type = new_type; + vif->p2p = p2p; + ret = rtl_op_add_interface(hw, vif); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p %x\n", p2p); + return ret; +} + +#ifdef CONFIG_PM +static u16 crc16_ccitt(u8 data, u16 crc) +{ + u8 shift_in, data_bit, crc_bit11, crc_bit4, crc_bit15; + u8 i; + u16 result; + + for (i = 0; i < 8; i++) { + crc_bit15 = ((crc & BIT(15)) ? 1 : 0); + data_bit = (data & (BIT(0) << i) ? 1 : 0); + shift_in = crc_bit15 ^ data_bit; + + result = crc << 1; + if (shift_in == 0) + result &= (~BIT(0)); + else + result |= BIT(0); + + crc_bit11 = ((crc & BIT(11)) ? 1 : 0) ^ shift_in; + if (crc_bit11 == 0) + result &= (~BIT(12)); + else + result |= BIT(12); + + crc_bit4 = ((crc & BIT(4)) ? 1 : 0) ^ shift_in; + if (crc_bit4 == 0) + result &= (~BIT(5)); + else + result |= BIT(5); + + crc = result; + } + + return crc; +} + +static u16 _calculate_wol_pattern_crc(u8 *pattern, u16 len) +{ + u16 crc = 0xffff; + u32 i; + + for (i = 0; i < len; i++) + crc = crc16_ccitt(pattern[i], crc); + + crc = ~crc; + + return crc; +} + +static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wow) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = &rtlpriv->mac80211; + struct cfg80211_pkt_pattern *patterns = wow->patterns; + struct rtl_wow_pattern rtl_pattern; + const u8 *pattern_os, *mask_os; + u8 mask[MAX_WOL_BIT_MASK_SIZE] = {0}; + u8 content[MAX_WOL_PATTERN_SIZE] = {0}; + u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 multicast_addr1[2] = {0x33, 0x33}; + u8 multicast_addr2[3] = {0x01, 0x00, 0x5e}; + u8 i, mask_len; + u16 j, len; + + for (i = 0; i < wow->n_patterns; i++) { + memset(&rtl_pattern, 0, sizeof(struct rtl_wow_pattern)); + memset(mask, 0, MAX_WOL_BIT_MASK_SIZE); + if (patterns[i].pattern_len < 0 || + patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_WARNING, + "Pattern[%d] is too long\n", i); + continue; + } + pattern_os = patterns[i].pattern; + mask_len = DIV_ROUND_UP(patterns[i].pattern_len, 8); + mask_os = patterns[i].mask; + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "pattern content\n", pattern_os, + patterns[i].pattern_len); + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "mask content\n", mask_os, mask_len); + /* 1. unicast? multicast? or broadcast? */ + if (memcmp(pattern_os, broadcast_addr, 6) == 0) + rtl_pattern.type = BROADCAST_PATTERN; + else if (memcmp(pattern_os, multicast_addr1, 2) == 0 || + memcmp(pattern_os, multicast_addr2, 3) == 0) + rtl_pattern.type = MULTICAST_PATTERN; + else if (memcmp(pattern_os, mac->mac_addr, 6) == 0) + rtl_pattern.type = UNICAST_PATTERN; + else + rtl_pattern.type = UNKNOWN_TYPE; + + /* 2. translate mask_from_os to mask_for_hw */ + +/****************************************************************************** + * pattern from OS uses 'ethenet frame', like this: + + | 6 | 6 | 2 | 20 | Variable | 4 | + |--------+--------+------+-----------+------------+-----| + | 802.3 Mac Header | IP Header | TCP Packet | FCS | + | DA | SA | Type | + + * BUT, packet catched by our HW is in '802.11 frame', begin from LLC, + + | 24 or 30 | 6 | 2 | 20 | Variable | 4 | + |-------------------+--------+------+-----------+------------+-----| + | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | + | Others | Tpye | + + * Therefore, we need translate mask_from_OS to mask_to_hw. + * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, + * because new mask[0~5] means 'SA', but our HW packet begins from LLC, + * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. + ******************************************************************************/ + + /* Shift 6 bits */ + for (j = 0; j < mask_len - 1; j++) { + mask[j] = mask_os[j] >> 6; + mask[j] |= (mask_os[j + 1] & 0x3F) << 2; + } + mask[j] = (mask_os[j] >> 6) & 0x3F; + /* Set bit 0-5 to zero */ + mask[0] &= 0xC0; + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "mask to hw\n", mask, mask_len); + for (j = 0; j < (MAX_WOL_BIT_MASK_SIZE + 1) / 4; j++) { + rtl_pattern.mask[j] = mask[j * 4]; + rtl_pattern.mask[j] |= (mask[j * 4 + 1] << 8); + rtl_pattern.mask[j] |= (mask[j * 4 + 2] << 16); + rtl_pattern.mask[j] |= (mask[j * 4 + 3] << 24); + } + + /* To get the wake up pattern from the mask. + * We do not count first 12 bits which means + * DA[6] and SA[6] in the pattern to match HW design. + */ + len = 0; + for (j = 12; j < patterns[i].pattern_len; j++) { + if ((mask_os[j / 8] >> (j % 8)) & 0x01) { + content[len] = pattern_os[j]; + len++; + } + } + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "pattern to hw\n", content, len); + /* 3. calculate crc */ + rtl_pattern.crc = _calculate_wol_pattern_crc(content, len); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "CRC_Remainder = 0x%x\n", rtl_pattern.crc); + + /* 4. write crc & mask_for_hw to hw */ + rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i); + } + rtl_write_byte(rtlpriv, 0x698, wow->n_patterns); +} + +static int rtl_op_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wow) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + if (WARN_ON(!wow)) + return -EINVAL; + + /* to resolve s4 can not wake up*/ + rtlhal->last_suspend_sec = ktime_get_real_seconds(); + + if ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) && wow->n_patterns) + _rtl_add_wowlan_patterns(hw, wow); + + rtlhal->driver_is_goingto_unload = true; + rtlhal->enter_pnp_sleep = true; + + rtl_lps_leave(hw, true); + rtl_op_stop(hw, false); + device_set_wakeup_enable(wiphy_dev(hw->wiphy), true); + return 0; +} + +static int rtl_op_resume(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + time64_t now; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + rtlhal->driver_is_goingto_unload = false; + rtlhal->enter_pnp_sleep = false; + rtlhal->wake_from_pnp_sleep = true; + + /* to resolve s4 can not wake up*/ + now = ktime_get_real_seconds(); + if (now - rtlhal->last_suspend_sec < 5) + return -1; + + rtl_op_start(hw); + device_set_wakeup_enable(wiphy_dev(hw->wiphy), false); + ieee80211_resume_disconnect(mac->vif); + rtlhal->wake_from_pnp_sleep = false; + return 0; +} +#endif + +static int rtl_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct ieee80211_conf *conf = &hw->conf; + + if (mac->skip_scan) + return 1; + + mutex_lock(&rtlpriv->locks.conf_mutex); + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2)*/ + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); + } + + /*For IPS */ + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + if (hw->conf.flags & IEEE80211_CONF_IDLE) + rtl_ips_nic_off(hw); + else + rtl_ips_nic_on(hw); + } else { + /* + *although rfoff may not cause by ips, but we will + *check the reason in set_rf_power_state function + */ + if (unlikely(ppsc->rfpwr_state == ERFOFF)) + rtl_ips_nic_on(hw); + } + + /*For LPS */ + if ((changed & IEEE80211_CONF_CHANGE_PS) && + rtlpriv->psc.swctrl_lps && !rtlpriv->psc.fwctrl_lps) { + cancel_delayed_work(&rtlpriv->works.ps_work); + cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); + if (conf->flags & IEEE80211_CONF_PS) { + rtlpriv->psc.sw_ps_enabled = true; + /* sleep here is must, or we may recv the beacon and + * cause mac80211 into wrong ps state, this will cause + * power save nullfunc send fail, and further cause + * pkt loss, So sleep must quickly but not immediatly + * because that will cause nullfunc send by mac80211 + * fail, and cause pkt loss, we have tested that 5mA + * is worked very well */ + if (!rtlpriv->psc.multi_buffered) + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ps_work, + MSECS(5)); + } else { + rtl_swlps_rf_awake(hw); + rtlpriv->psc.sw_ps_enabled = false; + } + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL && + !rtlpriv->proximity.proxim_on) { + struct ieee80211_channel *channel = hw->conf.chandef.chan; + enum nl80211_chan_width width = hw->conf.chandef.width; + enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + u8 wide_chan = (u8) channel->hw_value; + + /* channel_type is for 20&40M */ + if (width < NL80211_CHAN_WIDTH_80) + channel_type = + cfg80211_get_chandef_type(&hw->conf.chandef); + if (mac->act_scanning) + mac->n_channels++; + + /* + *because we should back channel to + *current_network.chan in scanning, + *So if set_chan == current_network.chan + *we should set it. + *because mac80211 tell us wrong bw40 + *info for cisco1253 bw20, so we modify + *it here based on UPPER & LOWER + */ + + if (width >= NL80211_CHAN_WIDTH_80) { + if (width == NL80211_CHAN_WIDTH_80) { + u32 center = hw->conf.chandef.center_freq1; + u32 primary = + (u32)hw->conf.chandef.chan->center_freq; + + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_80; + mac->bw_80 = true; + mac->bw_40 = true; + if (center > primary) { + mac->cur_80_prime_sc = + PRIME_CHNL_OFFSET_LOWER; + if (center - primary == 10) { + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_UPPER; + + wide_chan += 2; + } else if (center - primary == 30) { + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_LOWER; + + wide_chan += 6; + } + } else { + mac->cur_80_prime_sc = + PRIME_CHNL_OFFSET_UPPER; + if (primary - center == 10) { + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_LOWER; + + wide_chan -= 2; + } else if (primary - center == 30) { + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_UPPER; + + wide_chan -= 6; + } + } + } + } else { + switch (channel_type) { + case NL80211_CHAN_HT20: + case NL80211_CHAN_NO_HT: + /* SC */ + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_DONT_CARE; + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_20; + mac->bw_40 = false; + mac->bw_80 = false; + break; + case NL80211_CHAN_HT40MINUS: + /* SC */ + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_UPPER; + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_20_40; + mac->bw_40 = true; + mac->bw_80 = false; + + /*wide channel */ + wide_chan -= 2; + + break; + case NL80211_CHAN_HT40PLUS: + /* SC */ + mac->cur_40_prime_sc = + PRIME_CHNL_OFFSET_LOWER; + rtlphy->current_chan_bw = + HT_CHANNEL_WIDTH_20_40; + mac->bw_40 = true; + mac->bw_80 = false; + + /*wide channel */ + wide_chan += 2; + + break; + default: + mac->bw_40 = false; + mac->bw_80 = false; + pr_err("switch case %#x not processed\n", + channel_type); + break; + } + } + + if (wide_chan <= 0) + wide_chan = 1; + + /* In scanning, when before we offchannel we may send a ps=1 + * null to AP, and then we may send a ps = 0 null to AP quickly, + * but first null may have caused AP to put lots of packet to + * hw tx buffer. These packets must be tx'd before we go off + * channel so we must delay more time to let AP flush these + * packets before going offchannel, or dis-association or + * delete BA will be caused by AP + */ + if (rtlpriv->mac80211.offchan_delay) { + rtlpriv->mac80211.offchan_delay = false; + mdelay(50); + } + + rtlphy->current_channel = wide_chan; + + rtlpriv->cfg->ops->switch_channel(hw); + rtlpriv->cfg->ops->set_channel_access(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, channel_type); + } + + mutex_unlock(&rtlpriv->locks.conf_mutex); + + return 0; +} + +static void rtl_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, u64 multicast) +{ + bool update_rcr = false; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + *new_flags &= RTL_SUPPORTED_FILTERS; + if (0 == changed_flags) + return; + + /*TODO: we disable broadcast now, so enable here */ + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | + rtlpriv->cfg->maps[MAC_RCR_AB]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive multicast frame\n"); + } else { + mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | + rtlpriv->cfg->maps[MAC_RCR_AB]); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive multicast frame\n"); + } + update_rcr = true; + } + + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive FCS error frame\n"); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive FCS error frame\n"); + } + if (!update_rcr) + update_rcr = true; + } + + /* if ssid not set to hw don't check bssid + * here just used for linked scanning, & linked + * and nolink check bssid is set in set network_type + */ + if (changed_flags & FIF_BCN_PRBRESP_PROMISC && + mac->link_state >= MAC80211_LINKED) { + if (mac->opmode != NL80211_IFTYPE_AP && + mac->opmode != NL80211_IFTYPE_MESH_POINT) { + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) + rtlpriv->cfg->ops->set_chk_bssid(hw, false); + else + rtlpriv->cfg->ops->set_chk_bssid(hw, true); + if (update_rcr) + update_rcr = false; + } + } + + if (changed_flags & FIF_CONTROL) { + if (*new_flags & FIF_CONTROL) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive control frame.\n"); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive control frame.\n"); + } + if (!update_rcr) + update_rcr = true; + } + + if (changed_flags & FIF_OTHER_BSS) { + if (*new_flags & FIF_OTHER_BSS) { + mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive other BSS's frame.\n"); + } else { + mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive other BSS's frame.\n"); + } + if (!update_rcr) + update_rcr = true; + } + + if (update_rcr) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(&mac->rx_conf)); +} + +static int rtl_op_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry; + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_add_tail(&sta_entry->list, &rtlpriv->entry_list); + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + sta_entry->wireless_mode = WIRELESS_MODE_G; + if (sta->deflink.supp_rates[0] <= 0xf) + sta_entry->wireless_mode = WIRELESS_MODE_B; + if (sta->deflink.ht_cap.ht_supported) + sta_entry->wireless_mode = WIRELESS_MODE_N_24G; + + if (vif->type == NL80211_IFTYPE_ADHOC) + sta_entry->wireless_mode = WIRELESS_MODE_G; + } else if (rtlhal->current_bandtype == BAND_ON_5G) { + sta_entry->wireless_mode = WIRELESS_MODE_A; + if (sta->deflink.ht_cap.ht_supported) + sta_entry->wireless_mode = WIRELESS_MODE_N_5G; + if (sta->deflink.vht_cap.vht_supported) + sta_entry->wireless_mode = WIRELESS_MODE_AC_5G; + + if (vif->type == NL80211_IFTYPE_ADHOC) + sta_entry->wireless_mode = WIRELESS_MODE_A; + } + /*disable cck rate for p2p*/ + if (mac->p2p) + sta->deflink.supp_rates[0] &= 0xfffffff0; + + memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "Add sta addr is %pM\n", sta->addr); + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); + } + + return 0; +} + +static int rtl_op_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *sta_entry; + + if (sta) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "Remove sta addr is %pM\n", sta->addr); + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + sta_entry->wireless_mode = 0; + sta_entry->ratr_index = 0; + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_del(&sta_entry->list); + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + } + return 0; +} + +static int _rtl_get_hal_qnum(u16 queue) +{ + int qnum; + + switch (queue) { + case 0: + qnum = AC3_VO; + break; + case 1: + qnum = AC2_VI; + break; + case 2: + qnum = AC0_BE; + break; + case 3: + qnum = AC1_BK; + break; + default: + qnum = AC0_BE; + break; + } + return qnum; +} + +/* + *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3 + *for rtl819x BE = 0, BK = 1, VI = 2, VO = 3 + */ +static int rtl_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *param) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + int aci; + + if (queue >= AC_MAX) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "queue number %d is incorrect!\n", queue); + return -EINVAL; + } + + aci = _rtl_get_hal_qnum(queue); + mac->ac[aci].aifs = param->aifs; + mac->ac[aci].cw_min = cpu_to_le16(param->cw_min); + mac->ac[aci].cw_max = cpu_to_le16(param->cw_max); + mac->ac[aci].tx_op = cpu_to_le16(param->txop); + memcpy(&mac->edca_param[aci], param, sizeof(*param)); + rtlpriv->cfg->ops->set_qos(hw, aci); + return 0; +} + +static void send_beacon_frame(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct sk_buff *skb = ieee80211_beacon_get(hw, vif, 0); + struct rtl_tcb_desc tcb_desc; + + if (skb) { + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc); + } +} + +void rtl_update_beacon_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, update_beacon_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_vif *vif = rtlpriv->mac80211.vif; + + if (!vif) { + WARN_ONCE(true, "no vif to update beacon\n"); + return; + } + + mutex_lock(&rtlpriv->locks.conf_mutex); + send_beacon_frame(hw, vif); + mutex_unlock(&rtlpriv->locks.conf_mutex); +} +EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback); + +static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u64 changed) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + mutex_lock(&rtlpriv->locks.conf_mutex); + if (vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT) { + if (changed & BSS_CHANGED_BEACON || + (changed & BSS_CHANGED_BEACON_ENABLED && + bss_conf->enable_beacon)) { + if (mac->beacon_enabled == 0) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_BEACON_ENABLED\n"); + + /*start hw beacon interrupt. */ + /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ + mac->beacon_enabled = 1; + rtlpriv->cfg->ops->update_interrupt_mask(hw, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS], 0); + + if (rtlpriv->cfg->ops->linked_set_reg) + rtlpriv->cfg->ops->linked_set_reg(hw); + send_beacon_frame(hw, vif); + } + } + if ((changed & BSS_CHANGED_BEACON_ENABLED && + !bss_conf->enable_beacon)) { + if (mac->beacon_enabled == 1) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "ADHOC DISABLE BEACON\n"); + + mac->beacon_enabled = 0; + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS]); + } + } + if (changed & BSS_CHANGED_BEACON_INT) { + rtl_dbg(rtlpriv, COMP_BEACON, DBG_TRACE, + "BSS_CHANGED_BEACON_INT\n"); + mac->beacon_interval = bss_conf->beacon_int; + rtlpriv->cfg->ops->set_bcn_intv(hw); + } + } + + /*TODO: reference to enum ieee80211_bss_change */ + if (changed & BSS_CHANGED_ASSOC) { + u8 mstatus; + + if (vif->cfg.assoc) { + struct ieee80211_sta *sta = NULL; + u8 keep_alive = 10; + + mstatus = RT_MEDIA_CONNECT; + /* we should reset all sec info & cam + * before set cam after linked, we should not + * reset in disassoc, that will cause tkip->wep + * fail because some flag will be wrong */ + /* reset sec info */ + rtl_cam_reset_sec_info(hw); + /* reset cam to fix wep fail issue + * when change from wpa to wep */ + rtl_cam_reset_all_entry(hw); + + mac->link_state = MAC80211_LINKED; + mac->cnt_after_linked = 0; + mac->assoc_id = vif->cfg.aid; + memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); + + if (rtlpriv->cfg->ops->linked_set_reg) + rtlpriv->cfg->ops->linked_set_reg(hw); + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); + if (!sta) { + rcu_read_unlock(); + goto out; + } + rtl_dbg(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, + "send PS STATIC frame\n"); + if (rtlpriv->dm.supp_phymode_switch) { + if (sta->deflink.ht_cap.ht_supported) + rtl_send_smps_action(hw, sta, + IEEE80211_SMPS_STATIC); + } + + if (rtlhal->current_bandtype == BAND_ON_5G) { + mac->mode = WIRELESS_MODE_A; + } else { + if (sta->deflink.supp_rates[0] <= 0xf) + mac->mode = WIRELESS_MODE_B; + else + mac->mode = WIRELESS_MODE_G; + } + + if (sta->deflink.ht_cap.ht_supported) { + if (rtlhal->current_bandtype == BAND_ON_2_4G) + mac->mode = WIRELESS_MODE_N_24G; + else + mac->mode = WIRELESS_MODE_N_5G; + } + + if (sta->deflink.vht_cap.vht_supported) { + if (rtlhal->current_bandtype == BAND_ON_5G) + mac->mode = WIRELESS_MODE_AC_5G; + else + mac->mode = WIRELESS_MODE_AC_24G; + } + + if (vif->type == NL80211_IFTYPE_STATION) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, + true); + rcu_read_unlock(); + + /* to avoid AP Disassociation caused by inactivity */ + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_KEEP_ALIVE, + (u8 *)(&keep_alive)); + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_ASSOC\n"); + } else { + struct cfg80211_bss *bss = NULL; + + mstatus = RT_MEDIA_DISCONNECT; + + if (mac->link_state == MAC80211_LINKED) + rtl_lps_leave(hw, true); + if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE) + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + mac->link_state = MAC80211_NOLINK; + + bss = cfg80211_get_bss(hw->wiphy, NULL, + (u8 *)mac->bssid, NULL, 0, + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_OFF); + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid = %pMF\n", mac->bssid); + + if (bss) { + cfg80211_unlink_bss(hw->wiphy, bss); + cfg80211_put_bss(hw->wiphy, bss); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "cfg80211_unlink !!\n"); + } + + eth_zero_addr(mac->bssid); + mac->vendor = PEER_UNKNOWN; + mac->mode = 0; + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_UN_ASSOC\n"); + } + rtlpriv->cfg->ops->set_network_type(hw, vif->type); + /* For FW LPS: + * To tell firmware we have connected or disconnected + */ + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)(&mstatus)); + ppsc->report_linked = (mstatus == RT_MEDIA_CONNECT) ? + true : false; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify( + rtlpriv, mstatus); + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_CTS_PROT\n"); + mac->use_cts_protect = bss_conf->use_cts_prot; + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble); + + mac->short_preamble = bss_conf->use_short_preamble; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, + (u8 *)(&mac->short_preamble)); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_SLOT\n"); + + if (bss_conf->use_short_slot) + mac->slot_time = RTL_SLOT_TIME_9; + else + mac->slot_time = RTL_SLOT_TIME_20; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)(&mac->slot_time)); + } + + if (changed & BSS_CHANGED_HT) { + struct ieee80211_sta *sta = NULL; + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_HT\n"); + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); + if (sta) { + if (sta->deflink.ht_cap.ampdu_density > + mac->current_ampdu_density) + mac->current_ampdu_density = + sta->deflink.ht_cap.ampdu_density; + if (sta->deflink.ht_cap.ampdu_factor < + mac->current_ampdu_factor) + mac->current_ampdu_factor = + sta->deflink.ht_cap.ampdu_factor; + } + rcu_read_unlock(); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, + (u8 *)(&mac->max_mss_density)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, + &mac->current_ampdu_factor); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, + &mac->current_ampdu_density); + } + + if (changed & BSS_CHANGED_BSSID) { + u32 basic_rates; + struct ieee80211_sta *sta = NULL; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, + (u8 *)bss_conf->bssid); + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid: %pM\n", bss_conf->bssid); + + mac->vendor = PEER_UNKNOWN; + memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); + if (!sta) { + rcu_read_unlock(); + goto out; + } + + if (rtlhal->current_bandtype == BAND_ON_5G) { + mac->mode = WIRELESS_MODE_A; + } else { + if (sta->deflink.supp_rates[0] <= 0xf) + mac->mode = WIRELESS_MODE_B; + else + mac->mode = WIRELESS_MODE_G; + } + + if (sta->deflink.ht_cap.ht_supported) { + if (rtlhal->current_bandtype == BAND_ON_2_4G) + mac->mode = WIRELESS_MODE_N_24G; + else + mac->mode = WIRELESS_MODE_N_5G; + } + + if (sta->deflink.vht_cap.vht_supported) { + if (rtlhal->current_bandtype == BAND_ON_5G) + mac->mode = WIRELESS_MODE_AC_5G; + else + mac->mode = WIRELESS_MODE_AC_24G; + } + + /* just station need it, because ibss & ap mode will + * set in sta_add, and will be NULL here */ + if (vif->type == NL80211_IFTYPE_STATION) { + struct rtl_sta_info *sta_entry; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + sta_entry->wireless_mode = mac->mode; + } + + if (sta->deflink.ht_cap.ht_supported) { + mac->ht_enable = true; + + /* + * for cisco 1252 bw20 it's wrong + * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { + * mac->bw_40 = true; + * } + * */ + } + + if (sta->deflink.vht_cap.vht_supported) + mac->vht_enable = true; + + if (changed & BSS_CHANGED_BASIC_RATES) { + /* for 5G must << RATE_6M_INDEX = 4, + * because 5G have no cck rate*/ + if (rtlhal->current_bandtype == BAND_ON_5G) + basic_rates = sta->deflink.supp_rates[1] << 4; + else + basic_rates = sta->deflink.supp_rates[0]; + + mac->basic_rates = basic_rates; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)(&basic_rates)); + } + rcu_read_unlock(); + } +out: + mutex_unlock(&rtlpriv->locks.conf_mutex); +} + +static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u64 tsf; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&tsf)); + return tsf; +} + +static void rtl_op_set_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u64 tsf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; + + mac->tsf = tsf; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&bibss)); +} + +static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp = 0; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *)(&tmp)); +} + +static void rtl_op_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + switch (cmd) { + case STA_NOTIFY_SLEEP: + break; + case STA_NOTIFY_AWAKE: + break; + default: + break; + } +} + +static int rtl_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_sta *sta = params->sta; + enum ieee80211_ampdu_mlme_action action = params->action; + u16 tid = params->tid; + u16 *ssn = ¶ms->ssn; + + switch (action) { + case IEEE80211_AMPDU_TX_START: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); + return rtl_tx_agg_start(hw, vif, sta, tid, ssn); + case IEEE80211_AMPDU_TX_STOP_CONT: + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); + return rtl_tx_agg_stop(hw, vif, sta, tid); + case IEEE80211_AMPDU_TX_OPERATIONAL: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); + rtl_tx_agg_oper(hw, sta, tid); + break; + case IEEE80211_AMPDU_RX_START: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); + return rtl_rx_agg_start(hw, sta, tid); + case IEEE80211_AMPDU_RX_STOP: + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); + return rtl_rx_agg_stop(hw, sta, tid); + default: + pr_err("IEEE80211_AMPDU_ERR!!!!:\n"); + return -EOPNOTSUPP; + } + return 0; +} + +static void rtl_op_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + mac->act_scanning = true; + if (rtlpriv->link_info.higher_busytraffic) { + mac->skip_scan = true; + return; + } + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 1); + else if (rtlpriv->btcoexist.btc_ops) + rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv, + 1); + + if (mac->link_state == MAC80211_LINKED) { + rtl_lps_leave(hw, true); + mac->link_state = MAC80211_LINKED_SCANNING; + } else { + rtl_ips_nic_on(hw); + } + + /* Dul mac */ + rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; + + rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); + rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0); +} + +static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + mac->act_scanning = false; + mac->skip_scan = false; + + rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num; + + if (rtlpriv->link_info.higher_busytraffic) + return; + + /* p2p will use 1/6/11 to scan */ + if (mac->n_channels == 3) + mac->p2p_in_use = true; + else + mac->p2p_in_use = false; + mac->n_channels = 0; + /* Dul mac */ + rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; + + if (mac->link_state == MAC80211_LINKED_SCANNING) { + mac->link_state = MAC80211_LINKED; + if (mac->opmode == NL80211_IFTYPE_STATION) { + /* fix fwlps issue */ + rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); + } + } + + rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 0); + else if (rtlpriv->btcoexist.btc_ops) + rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv, + 0); +} + +static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 key_type = NO_ENCRYPTION; + u8 key_idx; + bool group_key = false; + bool wep_only = false; + int err = 0; + u8 mac_addr[ETH_ALEN]; + u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + rtlpriv->btcoexist.btc_info.in_4way = false; + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not open hw encryption\n"); + return -ENOSPC; /*User disabled HW-crypto */ + } + /* To support IBSS, use sw-crypto for GTK */ + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -ENOSPC; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); + rtlpriv->sec.being_setkey = true; + rtl_ips_nic_on(hw); + mutex_lock(&rtlpriv->locks.conf_mutex); + /* <1> get encryption alg */ + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + key_type = WEP40_ENCRYPTION; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); + break; + case WLAN_CIPHER_SUITE_WEP104: + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); + key_type = WEP104_ENCRYPTION; + break; + case WLAN_CIPHER_SUITE_TKIP: + key_type = TKIP_ENCRYPTION; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); + break; + case WLAN_CIPHER_SUITE_CCMP: + key_type = AESCCMP_ENCRYPTION; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + /* HW don't support CMAC encryption, + * use software CMAC encryption + */ + key_type = AESCMAC_ENCRYPTION; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "HW don't support CMAC encryption, use software CMAC encryption\n"); + err = -EOPNOTSUPP; + goto out_unlock; + default: + pr_err("alg_err:%x!!!!:\n", key->cipher); + goto out_unlock; + } + if (key_type == WEP40_ENCRYPTION || + key_type == WEP104_ENCRYPTION || + vif->type == NL80211_IFTYPE_ADHOC) + rtlpriv->sec.use_defaultkey = true; + + /* <2> get key_idx */ + key_idx = (u8) (key->keyidx); + if (key_idx > 3) + goto out_unlock; + /* <3> if pairwise key enable_hw_sec */ + group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); + + /* wep always be group key, but there are two conditions: + * 1) wep only: is just for wep enc, in this condition + * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION + * will be true & enable_hw_sec will be set when wep + * ke setting. + * 2) wep(group) + AES(pairwise): some AP like cisco + * may use it, in this condition enable_hw_sec will not + * be set when wep key setting */ + /* we must reset sec_info after lingked before set key, + * or some flag will be wrong*/ + if (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT) { + if (!group_key || key_type == WEP40_ENCRYPTION || + key_type == WEP104_ENCRYPTION) { + if (group_key) + wep_only = true; + rtlpriv->cfg->ops->enable_hw_sec(hw); + } + } else { + if (!group_key || vif->type == NL80211_IFTYPE_ADHOC || + rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { + if (rtlpriv->sec.pairwise_enc_algorithm == + NO_ENCRYPTION && + (key_type == WEP40_ENCRYPTION || + key_type == WEP104_ENCRYPTION)) + wep_only = true; + rtlpriv->sec.pairwise_enc_algorithm = key_type; + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); + rtlpriv->cfg->ops->enable_hw_sec(hw); + } + } + /* <4> set key based on cmd */ + switch (cmd) { + case SET_KEY: + if (wep_only) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set WEP(group/pairwise) key\n"); + /* Pairwise key with an assigned MAC address. */ + rtlpriv->sec.pairwise_enc_algorithm = key_type; + rtlpriv->sec.group_enc_algorithm = key_type; + /*set local buf about wep key. */ + memcpy(rtlpriv->sec.key_buf[key_idx], + key->key, key->keylen); + rtlpriv->sec.key_len[key_idx] = key->keylen; + eth_zero_addr(mac_addr); + } else if (group_key) { /* group key */ + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + /* group key */ + rtlpriv->sec.group_enc_algorithm = key_type; + /*set local buf about group key. */ + memcpy(rtlpriv->sec.key_buf[key_idx], + key->key, key->keylen); + rtlpriv->sec.key_len[key_idx] = key->keylen; + eth_broadcast_addr(mac_addr); + } else { /* pairwise key */ + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set pairwise key\n"); + if (!sta) { + WARN_ONCE(true, + "rtlwifi: pairwise key without mac_addr\n"); + + err = -EOPNOTSUPP; + goto out_unlock; + } + /* Pairwise key with an assigned MAC address. */ + rtlpriv->sec.pairwise_enc_algorithm = key_type; + /*set local buf about pairwise key. */ + memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX], + key->key, key->keylen); + rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen; + rtlpriv->sec.pairwise_key = + rtlpriv->sec.key_buf[PAIRWISE_KEYIDX]; + memcpy(mac_addr, sta->addr, ETH_ALEN); + } + rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr, + group_key, key_type, wep_only, + false); + /* <5> tell mac80211 do something: */ + /*must use sw generate IV, or can not work !!!!. */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + key->hw_key_idx = key_idx; + if (key_type == TKIP_ENCRYPTION) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + /*use software CCMP encryption for management frames (MFP) */ + if (key_type == AESCCMP_ENCRYPTION) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + case DISABLE_KEY: + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "disable key delete one entry\n"); + /*set local buf about wep key. */ + if (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT) { + if (sta) + rtl_cam_del_entry(hw, sta->addr); + } + memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); + rtlpriv->sec.key_len[key_idx] = 0; + eth_zero_addr(mac_addr); + /* + *mac80211 will delete entries one by one, + *so don't use rtl_cam_reset_all_entry + *or clear all entry here. + */ + rtl_wait_tx_report_acked(hw, 500); /* wait 500ms for TX ack */ + + rtl_cam_delete_one_entry(hw, mac_addr, key_idx); + break; + default: + pr_err("cmd_err:%x!!!!:\n", cmd); + } +out_unlock: + mutex_unlock(&rtlpriv->locks.conf_mutex); + rtlpriv->sec.being_setkey = false; + return err; +} + +static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + bool radio_state; + bool blocked; + u8 valid = 0; + + if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) + return; + + mutex_lock(&rtlpriv->locks.conf_mutex); + + /*if Radio On return true here */ + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + + if (valid) { + if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) { + rtlpriv->rfkill.rfkill_state = radio_state; + + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); + + blocked = !rtlpriv->rfkill.rfkill_state; + wiphy_rfkill_set_hw_state(hw->wiphy, blocked); + } + } + + mutex_unlock(&rtlpriv->locks.conf_mutex); +} + +/* this function is called by mac80211 to flush tx buffer + * before switch channle or power save, or tx buffer packet + * maybe send after offchannel or rf sleep, this may cause + * dis-association by AP */ +static void rtl_op_flush(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 queues, + bool drop) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->intf_ops->flush) + rtlpriv->intf_ops->flush(hw, queues, drop); +} + +static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) + schedule_work(&rtlpriv->works.update_beacon_work); + + return 0; +} + +/* Description: + * This routine deals with the Power Configuration CMD + * parsing for RTL8723/RTL8188E Series IC. + * Assumption: + * We should follow specific format that was released from HW SD. + */ +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, + u8 faversion, u8 interface_type, + struct wlan_pwr_cfg pwrcfgcmd[]) +{ + struct wlan_pwr_cfg cfg_cmd; + bool polling_bit = false; + u32 ary_idx = 0; + u8 value = 0; + u32 offset = 0; + u32 polling_count = 0; + u32 max_polling_cnt = 5000; + + do { + cfg_cmd = pwrcfgcmd[ary_idx]; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", + __func__, + GET_PWR_CFG_OFFSET(cfg_cmd), + GET_PWR_CFG_CUT_MASK(cfg_cmd), + GET_PWR_CFG_FAB_MASK(cfg_cmd), + GET_PWR_CFG_INTF_MASK(cfg_cmd), + GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), + GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); + + if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && + (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && + (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { + switch (GET_PWR_CFG_CMD(cfg_cmd)) { + case PWR_CMD_READ: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); + break; + case PWR_CMD_WRITE: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s(): PWR_CMD_WRITE\n", __func__); + offset = GET_PWR_CFG_OFFSET(cfg_cmd); + + /*Read the value from system register*/ + value = rtl_read_byte(rtlpriv, offset); + value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); + value |= (GET_PWR_CFG_VALUE(cfg_cmd) & + GET_PWR_CFG_MASK(cfg_cmd)); + + /*Write the value back to system register*/ + rtl_write_byte(rtlpriv, offset, value); + break; + case PWR_CMD_POLLING: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); + polling_bit = false; + offset = GET_PWR_CFG_OFFSET(cfg_cmd); + + do { + value = rtl_read_byte(rtlpriv, offset); + + value &= GET_PWR_CFG_MASK(cfg_cmd); + if (value == + (GET_PWR_CFG_VALUE(cfg_cmd) & + GET_PWR_CFG_MASK(cfg_cmd))) + polling_bit = true; + else + udelay(10); + + if (polling_count++ > max_polling_cnt) + return false; + } while (!polling_bit); + break; + case PWR_CMD_DELAY: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_DELAY\n", __func__); + if (GET_PWR_CFG_VALUE(cfg_cmd) == + PWRSEQ_DELAY_US) + udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); + else + mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); + break; + case PWR_CMD_END: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_END\n", __func__); + return true; + default: + WARN_ONCE(true, + "rtlwifi: rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); + break; + } + } + ary_idx++; + } while (1); + + return true; +} +EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing); + +bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + unsigned long flags; + struct sk_buff *pskb = NULL; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + pskb = __skb_dequeue(&ring->queue); + if (pskb) + dev_kfree_skb_irq(pskb); + + /*this is wrong, fill_tx_cmddesc needs update*/ + pdesc = &ring->desc[0]; + + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb); + + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + + return true; +} +EXPORT_SYMBOL(rtl_cmd_send_packet); + +void rtl_init_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->ledctl.sw_led0 = LED_PIN_LED0; + rtlpriv->ledctl.sw_led1 = LED_PIN_LED1; +} +EXPORT_SYMBOL(rtl_init_sw_leds); + +const struct ieee80211_ops rtl_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .start = rtl_op_start, + .stop = rtl_op_stop, + .tx = rtl_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .add_interface = rtl_op_add_interface, + .remove_interface = rtl_op_remove_interface, + .change_interface = rtl_op_change_interface, +#ifdef CONFIG_PM + .suspend = rtl_op_suspend, + .resume = rtl_op_resume, +#endif + .config = rtl_op_config, + .configure_filter = rtl_op_configure_filter, + .set_key = rtl_op_set_key, + .conf_tx = rtl_op_conf_tx, + .bss_info_changed = rtl_op_bss_info_changed, + .get_tsf = rtl_op_get_tsf, + .set_tsf = rtl_op_set_tsf, + .reset_tsf = rtl_op_reset_tsf, + .sta_notify = rtl_op_sta_notify, + .ampdu_action = rtl_op_ampdu_action, + .sw_scan_start = rtl_op_sw_scan_start, + .sw_scan_complete = rtl_op_sw_scan_complete, + .rfkill_poll = rtl_op_rfkill_poll, + .sta_add = rtl_op_sta_add, + .sta_remove = rtl_op_sta_remove, + .flush = rtl_op_flush, + .set_tim = rtl_op_set_tim, +}; +EXPORT_SYMBOL_GPL(rtl_ops); + +bool rtl_btc_status_false(void) +{ + return false; +} +EXPORT_SYMBOL_GPL(rtl_btc_status_false); + +void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + dm_digtable->dig_enable_flag = true; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable->cur_igvalue = cur_igvalue; + dm_digtable->pre_igvalue = 0; + dm_digtable->cur_sta_cstate = DIG_STA_DISCONNECT; + dm_digtable->presta_cstate = DIG_STA_DISCONNECT; + dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable->rx_gain_max = DM_DIG_MAX; + dm_digtable->rx_gain_min = DM_DIG_MIN; + dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable->pre_cck_cca_thres = 0xff; + dm_digtable->cur_cck_cca_thres = 0x83; + dm_digtable->forbidden_igi = DM_DIG_MIN; + dm_digtable->large_fa_hit = 0; + dm_digtable->recover_cnt = 0; + dm_digtable->dig_min_0 = 0x25; + dm_digtable->dig_min_1 = 0x25; + dm_digtable->media_connect_0 = false; + dm_digtable->media_connect_1 = false; + rtlpriv->dm.dm_initialgain_enable = true; + dm_digtable->bt30_cur_igi = 0x32; + dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + dm_digtable->pre_cck_fa_state = 0; + dm_digtable->cur_cck_fa_state = 0; +} +EXPORT_SYMBOL(rtl_dm_diginit); diff --git a/drivers/net/wireless/realtek/rtlwifi/core.h b/drivers/net/wireless/realtek/rtlwifi/core.h new file mode 100644 index 000000000..45225d89a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/core.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_CORE_H__ +#define __RTL_CORE_H__ + +#define RTL_SUPPORTED_FILTERS \ + (FIF_ALLMULTI | FIF_CONTROL | \ + FIF_OTHER_BSS | \ + FIF_FCSFAIL | \ + FIF_BCN_PRBRESP_PROMISC) + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX 0x3e +#define DM_DIG_MIN 0x1e +#define DM_DIG_MAX_AP 0x32 +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +enum cck_packet_detection_threshold { + CCK_PD_STAGE_LOWRSSI = 0, + CCK_PD_STAGE_HIGHRSSI = 1, + CCK_FA_STAGE_LOW = 2, + CCK_FA_STAGE_HIGH = 3, + CCK_PD_STAGE_MAX = 4, +}; + +enum dm_dig_ext_port_alg_e { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_connect_e { + DIG_STA_DISCONNECT, + DIG_STA_CONNECT, + DIG_STA_BEFORE_CONNECT, + DIG_MULTISTA_DISCONNECT, + DIG_MULTISTA_CONNECT, + DIG_AP_DISCONNECT, + DIG_AP_CONNECT, + DIG_AP_ADD_STATION, + DIG_CONNECT_MAX +}; + +extern const struct ieee80211_ops rtl_ops; + +void rtl_init_sw_leds(struct ieee80211_hw *hw); +void rtl_fw_cb(const struct firmware *firmware, void *context); +void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context); +void rtl_addr_delay(u32 addr); +void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, + u32 mask, u32 data); +bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); +bool rtl_btc_status_false(void); +void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval); +void rtl_update_beacon_work_callback(struct work_struct *work); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c new file mode 100644 index 000000000..9eb26dfe4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -0,0 +1,514 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "cam.h" + +#include +#include + +#ifdef CONFIG_RTLWIFI_DEBUG +void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *fmt, ...) +{ + if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && + level <= rtlpriv->cfg->mod_params->debug_level)) { + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_info("%pV", &vaf); + + va_end(args); + } +} +EXPORT_SYMBOL_GPL(_rtl_dbg_print); + +void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *titlestring, + const void *hexdata, int hexdatalen) +{ + if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) && + ((level) <= rtlpriv->cfg->mod_params->debug_level))) { + pr_info("In process \"%s\" (pid %i): %s\n", + current->comm, current->pid, titlestring); + print_hex_dump_bytes("", DUMP_PREFIX_NONE, + hexdata, hexdatalen); + } +} +EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); + +struct rtl_debugfs_priv { + struct rtl_priv *rtlpriv; + int (*cb_read)(struct seq_file *m, void *v); + ssize_t (*cb_write)(struct file *filp, const char __user *buffer, + size_t count, loff_t *loff); + u32 cb_data; +}; + +static struct dentry *debugfs_topdir; + +static int rtl_debug_get_common(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + + return debugfs_priv->cb_read(m, v); +} + +static int dl_debug_open_common(struct inode *inode, struct file *file) +{ + return single_open(file, rtl_debug_get_common, inode->i_private); +} + +static const struct file_operations file_ops_common = { + .open = dl_debug_open_common, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int rtl_debug_get_mac_page(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + u32 page = debugfs_priv->cb_data; + int i, n; + int max = 0xff; + + for (n = 0; n <= max; ) { + seq_printf(m, "\n%8.8x ", n + page); + for (i = 0; i < 4 && n <= max; i++, n += 4) + seq_printf(m, "%8.8x ", + rtl_read_dword(rtlpriv, (page | n))); + } + seq_puts(m, "\n"); + return 0; +} + +#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \ +static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \ + .cb_read = rtl_debug_get_mac_page, \ + .cb_data = addr, \ +} + +RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000); +RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100); +RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200); +RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300); +RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400); +RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500); +RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600); +RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700); +RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000); +RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100); +RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200); +RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300); +RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400); +RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500); +RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600); +RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700); + +static int rtl_debug_get_bb_page(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + struct ieee80211_hw *hw = rtlpriv->hw; + u32 page = debugfs_priv->cb_data; + int i, n; + int max = 0xff; + + for (n = 0; n <= max; ) { + seq_printf(m, "\n%8.8x ", n + page); + for (i = 0; i < 4 && n <= max; i++, n += 4) + seq_printf(m, "%8.8x ", + rtl_get_bbreg(hw, (page | n), 0xffffffff)); + } + seq_puts(m, "\n"); + return 0; +} + +#define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \ +static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \ + .cb_read = rtl_debug_get_bb_page, \ + .cb_data = addr, \ +} + +RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800); +RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900); +RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00); +RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00); +RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00); +RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00); +RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00); +RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00); +RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800); +RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900); +RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00); +RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00); +RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00); +RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00); +RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00); +RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00); + +static int rtl_debug_get_reg_rf(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + struct ieee80211_hw *hw = rtlpriv->hw; + enum radio_path rfpath = debugfs_priv->cb_data; + int i, n; + int max = 0x40; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + max = 0xff; + + seq_printf(m, "\nPATH(%d)", rfpath); + + for (n = 0; n <= max; ) { + seq_printf(m, "\n%8.8x ", n); + for (i = 0; i < 4 && n <= max; n += 1, i++) + seq_printf(m, "%8.8x ", + rtl_get_rfreg(hw, rfpath, n, 0xffffffff)); + } + seq_puts(m, "\n"); + return 0; +} + +#define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \ +static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \ + .cb_read = rtl_debug_get_reg_rf, \ + .cb_data = addr, \ +} + +RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A); +RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B); + +static int rtl_debug_get_cam_register(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + int start = debugfs_priv->cb_data; + u32 target_cmd = 0; + u32 target_val = 0; + u8 entry_i = 0; + u32 ulstatus; + int i = 100, j = 0; + int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11); + + /* This dump the current register page */ + seq_printf(m, + "\n#################### SECURITY CAM (%d-%d) ##################\n", + start, end - 1); + + for (j = start; j < end; j++) { + seq_printf(m, "\nD: %2x > ", j); + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + /* polling bit, and No Write enable, and address */ + target_cmd = entry_i + CAM_CONTENT_COUNT * j; + target_cmd = target_cmd | BIT(31); + + /* Check polling bit is clear */ + while ((i--) >= 0) { + ulstatus = + rtl_read_dword(rtlpriv, + rtlpriv->cfg->maps[RWCAM]); + if (ulstatus & BIT(31)) + continue; + else + break; + } + + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], + target_cmd); + target_val = rtl_read_dword(rtlpriv, + rtlpriv->cfg->maps[RCAMO]); + seq_printf(m, "%8.8x ", target_val); + } + } + seq_puts(m, "\n"); + return 0; +} + +#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \ +static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \ + .cb_read = rtl_debug_get_cam_register, \ + .cb_data = addr, \ +} + +RTL_DEBUG_IMPL_CAM_SERIES(1, 0); +RTL_DEBUG_IMPL_CAM_SERIES(2, 11); +RTL_DEBUG_IMPL_CAM_SERIES(3, 22); + +static int rtl_debug_get_btcoex(struct seq_file *m, void *v) +{ + struct rtl_debugfs_priv *debugfs_priv = m->private; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv, + m); + + seq_puts(m, "\n"); + + return 0; +} + +static struct rtl_debugfs_priv rtl_debug_priv_btcoex = { + .cb_read = rtl_debug_get_btcoex, + .cb_data = 0, +}; + +static ssize_t rtl_debugfs_set_write_reg(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtl_debugfs_priv *debugfs_priv = filp->private_data; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + char tmp[32 + 1]; + int tmp_len; + u32 addr, val, len; + int num; + + if (count < 3) + return -EFAULT; + + tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); + + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; + + tmp[tmp_len] = '\0'; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) + return -EINVAL; + + switch (len) { + case 1: + rtl_write_byte(rtlpriv, addr, (u8)val); + break; + case 2: + rtl_write_word(rtlpriv, addr, (u16)val); + break; + case 4: + rtl_write_dword(rtlpriv, addr, val); + break; + default: + /*printk("error write length=%d", len);*/ + break; + } + + return count; +} + +static struct rtl_debugfs_priv rtl_debug_priv_write_reg = { + .cb_write = rtl_debugfs_set_write_reg, +}; + +static ssize_t rtl_debugfs_set_write_h2c(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtl_debugfs_priv *debugfs_priv = filp->private_data; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + struct ieee80211_hw *hw = rtlpriv->hw; + char tmp[32 + 1]; + int tmp_len; + u8 h2c_len, h2c_data_packed[8]; + int h2c_data[8]; /* idx 0: cmd */ + int i; + + if (count < 3) + return -EFAULT; + + tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); + + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; + + tmp[tmp_len] = '\0'; + + h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X", + &h2c_data[0], &h2c_data[1], + &h2c_data[2], &h2c_data[3], + &h2c_data[4], &h2c_data[5], + &h2c_data[6], &h2c_data[7]); + + if (h2c_len == 0) + return -EINVAL; + + for (i = 0; i < h2c_len; i++) + h2c_data_packed[i] = (u8)h2c_data[i]; + + rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0], + h2c_len - 1, + &h2c_data_packed[1]); + + return count; +} + +static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = { + .cb_write = rtl_debugfs_set_write_h2c, +}; + +static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtl_debugfs_priv *debugfs_priv = filp->private_data; + struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; + struct ieee80211_hw *hw = rtlpriv->hw; + char tmp[32 + 1]; + int tmp_len; + int num; + int path; + u32 addr, bitmask, data; + + if (count < 3) + return -EFAULT; + + tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); + + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; + + tmp[tmp_len] = '\0'; + + num = sscanf(tmp, "%X %X %X %X", + &path, &addr, &bitmask, &data); + + if (num != 4) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "Format is \n"); + return -EINVAL; + } + + rtl_set_rfreg(hw, path, addr, bitmask, data); + + return count; +} + +static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = { + .cb_write = rtl_debugfs_set_write_rfreg, +}; + +static int rtl_debugfs_close(struct inode *inode, struct file *filp) +{ + return 0; +} + +static ssize_t rtl_debugfs_common_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtl_debugfs_priv *debugfs_priv = filp->private_data; + + return debugfs_priv->cb_write(filp, buffer, count, loff); +} + +static const struct file_operations file_ops_common_write = { + .owner = THIS_MODULE, + .write = rtl_debugfs_common_write, + .open = simple_open, + .release = rtl_debugfs_close, +}; + +#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \ + do { \ + rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \ + debugfs_create_file(#name, mode, parent, \ + &rtl_debug_priv_ ##name, \ + &file_ops_ ##fopname); \ + } while (0) + +#define RTL_DEBUGFS_ADD(name) \ + RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common) +#define RTL_DEBUGFS_ADD_W(name) \ + RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write) + +void rtl_debug_add_one(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct dentry *parent; + + snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr); + + rtlpriv->dbg.debugfs_dir = + debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir); + + parent = rtlpriv->dbg.debugfs_dir; + + RTL_DEBUGFS_ADD(mac_0); + RTL_DEBUGFS_ADD(mac_1); + RTL_DEBUGFS_ADD(mac_2); + RTL_DEBUGFS_ADD(mac_3); + RTL_DEBUGFS_ADD(mac_4); + RTL_DEBUGFS_ADD(mac_5); + RTL_DEBUGFS_ADD(mac_6); + RTL_DEBUGFS_ADD(mac_7); + RTL_DEBUGFS_ADD(bb_8); + RTL_DEBUGFS_ADD(bb_9); + RTL_DEBUGFS_ADD(bb_a); + RTL_DEBUGFS_ADD(bb_b); + RTL_DEBUGFS_ADD(bb_c); + RTL_DEBUGFS_ADD(bb_d); + RTL_DEBUGFS_ADD(bb_e); + RTL_DEBUGFS_ADD(bb_f); + RTL_DEBUGFS_ADD(mac_10); + RTL_DEBUGFS_ADD(mac_11); + RTL_DEBUGFS_ADD(mac_12); + RTL_DEBUGFS_ADD(mac_13); + RTL_DEBUGFS_ADD(mac_14); + RTL_DEBUGFS_ADD(mac_15); + RTL_DEBUGFS_ADD(mac_16); + RTL_DEBUGFS_ADD(mac_17); + RTL_DEBUGFS_ADD(bb_18); + RTL_DEBUGFS_ADD(bb_19); + RTL_DEBUGFS_ADD(bb_1a); + RTL_DEBUGFS_ADD(bb_1b); + RTL_DEBUGFS_ADD(bb_1c); + RTL_DEBUGFS_ADD(bb_1d); + RTL_DEBUGFS_ADD(bb_1e); + RTL_DEBUGFS_ADD(bb_1f); + RTL_DEBUGFS_ADD(rf_a); + RTL_DEBUGFS_ADD(rf_b); + + RTL_DEBUGFS_ADD(cam_1); + RTL_DEBUGFS_ADD(cam_2); + RTL_DEBUGFS_ADD(cam_3); + + RTL_DEBUGFS_ADD(btcoex); + + RTL_DEBUGFS_ADD_W(write_reg); + RTL_DEBUGFS_ADD_W(write_h2c); + RTL_DEBUGFS_ADD_W(write_rfreg); +} +EXPORT_SYMBOL_GPL(rtl_debug_add_one); + +void rtl_debug_remove_one(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir); + rtlpriv->dbg.debugfs_dir = NULL; +} +EXPORT_SYMBOL_GPL(rtl_debug_remove_one); + +void rtl_debugfs_add_topdir(void) +{ + debugfs_topdir = debugfs_create_dir("rtlwifi", NULL); +} + +void rtl_debugfs_remove_topdir(void) +{ + debugfs_remove_recursive(debugfs_topdir); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h new file mode 100644 index 000000000..1c0bcf8ec --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/debug.h @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_DEBUG_H__ +#define __RTL_DEBUG_H__ + +/*-------------------------------------------------------------- + Debug level +--------------------------------------------------------------*/ +/* + *Fatal bug. + *For example, Tx/Rx/IO locked up, + *memory access violation, + *resource allocation failed, + *unexpected HW behavior, HW BUG + *and so on. + */ +/*#define DBG_EMERG 0 */ + +/* + *Abnormal, rare, or unexpeted cases. + *For example, Packet/IO Ctl canceled, + *device suprisely unremoved and so on. + */ +#define DBG_WARNING 2 + +/* + *Normal case driver developer should + *open, we can see link status like + *assoc/AddBA/DHCP/adapter start and + *so on basic and useful infromations. + */ +#define DBG_DMESG 3 + +/* + *Normal case with useful information + *about current SW or HW state. + *For example, Tx/Rx descriptor to fill, + *Tx/Rx descriptor completed status, + *SW protocol state change, dynamic + *mechanism state change and so on. + */ +#define DBG_LOUD 4 + +/* + *Normal case with detail execution + *flow or information. + */ +#define DBG_TRACE 5 + +/*-------------------------------------------------------------- + Define the rt_trace components +--------------------------------------------------------------*/ +#define COMP_ERR BIT(0) +#define COMP_FW BIT(1) +#define COMP_INIT BIT(2) /*For init/deinit */ +#define COMP_RECV BIT(3) /*For Rx. */ +#define COMP_SEND BIT(4) /*For Tx. */ +#define COMP_MLME BIT(5) /*For MLME. */ +#define COMP_SCAN BIT(6) /*For Scan. */ +#define COMP_INTR BIT(7) /*For interrupt Related. */ +#define COMP_LED BIT(8) /*For LED. */ +#define COMP_SEC BIT(9) /*For sec. */ +#define COMP_BEACON BIT(10) /*For beacon. */ +#define COMP_RATE BIT(11) /*For rate. */ +#define COMP_RXDESC BIT(12) /*For rx desc. */ +#define COMP_DIG BIT(13) /*For DIG */ +#define COMP_TXAGC BIT(14) /*For Tx power */ +#define COMP_HIPWR BIT(15) /*For High Power Mechanism */ +#define COMP_POWER BIT(16) /*For lps/ips/aspm. */ +#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */ +#define COMP_BB_POWERSAVING BIT(18) +#define COMP_SWAS BIT(19) /*For SW Antenna Switch */ +#define COMP_RF BIT(20) /*For RF. */ +#define COMP_TURBO BIT(21) /*For EDCA TURBO. */ +#define COMP_RATR BIT(22) +#define COMP_CMD BIT(23) +#define COMP_EFUSE BIT(24) +#define COMP_QOS BIT(25) +#define COMP_MAC80211 BIT(26) +#define COMP_REGD BIT(27) +#define COMP_CHAN BIT(28) +#define COMP_USB BIT(29) +#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */ +#define COMP_BT_COEXIST BIT(30) +#define COMP_IQK BIT(31) +#define COMP_TX_REPORT BIT_ULL(32) + +/*-------------------------------------------------------------- + Define the rt_print components +--------------------------------------------------------------*/ +/* Define EEPROM and EFUSE check module bit*/ +#define EEPROM_W BIT(0) +#define EFUSE_PG BIT(1) +#define EFUSE_READ_ALL BIT(2) + +/* Define init check for module bit*/ +#define INIT_EEPROM BIT(0) +#define INIT_TXPOWER BIT(1) +#define INIT_IQK BIT(2) +#define INIT_RF BIT(3) + +/* Define PHY-BB/RF/MAC check module bit */ +#define PHY_BBR BIT(0) +#define PHY_BBW BIT(1) +#define PHY_RFR BIT(2) +#define PHY_RFW BIT(3) +#define PHY_MACR BIT(4) +#define PHY_MACW BIT(5) +#define PHY_ALLR BIT(6) +#define PHY_ALLW BIT(7) +#define PHY_TXPWR BIT(8) +#define PHY_PWRDIFF BIT(9) + +/* Define Dynamic Mechanism check module bit --> FDM */ +#define WA_IOT BIT(0) +#define DM_PWDB BIT(1) +#define DM_MONITOR BIT(2) +#define DM_DIG BIT(3) +#define DM_EDCA_TURBO BIT(4) + +#define DM_PWDB BIT(1) + +enum dbgp_flag_e { + FQOS = 0, + FTX = 1, + FRX = 2, + FSEC = 3, + FMGNT = 4, + FMLME = 5, + FRESOURCE = 6, + FBEACON = 7, + FISR = 8, + FPHY = 9, + FMP = 10, + FEEPROM = 11, + FPWR = 12, + FDM = 13, + FDBGCTRL = 14, + FC2H = 15, + FBT = 16, + FINIT = 17, + FIOCTL = 18, + DBGP_TYPE_MAX +}; + +#ifdef CONFIG_RTLWIFI_DEBUG + +struct rtl_priv; + +__printf(4, 5) +void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *fmt, ...); + +void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *titlestring, + const void *hexdata, int hexdatalen); + +#define rtl_dbg(rtlpriv, comp, level, fmt, ...) \ + _rtl_dbg_print(rtlpriv, comp, level, \ + fmt, ##__VA_ARGS__) + +#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ + _rtl_dbg_print(rtlpriv, dbgtype, dbgflag, fmt, ##__VA_ARGS__) + +#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ + _hexdatalen) \ + _rtl_dbg_print_data(rtlpriv, _comp, _level, \ + _titlestring, _hexdata, _hexdatalen) + +#else + +struct rtl_priv; + +__printf(4, 5) +static inline void rtl_dbg(struct rtl_priv *rtlpriv, + u64 comp, int level, + const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RTPRINT(struct rtl_priv *rtlpriv, + int dbgtype, int dbgflag, + const char *fmt, ...) +{ +} + +static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv, + u64 comp, int level, + const char *titlestring, + const void *hexdata, size_t hexdatalen) +{ +} + +#endif + +#ifdef CONFIG_RTLWIFI_DEBUG +void rtl_debug_add_one(struct ieee80211_hw *hw); +void rtl_debug_remove_one(struct ieee80211_hw *hw); +void rtl_debugfs_add_topdir(void); +void rtl_debugfs_remove_topdir(void); +#else +#define rtl_debug_add_one(hw) +#define rtl_debug_remove_one(hw) +#define rtl_debugfs_add_topdir() +#define rtl_debugfs_remove_topdir() +#endif +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c new file mode 100644 index 000000000..6518e77b8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c @@ -0,0 +1,1373 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "efuse.h" +#include "pci.h" +#include + +static const u8 PGPKT_DATA_SIZE = 8; +static const int EFUSE_MAX_SIZE = 512; + +#define START_ADDRESS 0x1000 +#define REG_MCUFWDL 0x0080 + +static const struct rtl_efuse_ops efuse_ops = { + .efuse_onebyte_read = efuse_one_byte_read, + .efuse_logical_map_read = efuse_shadow_read, +}; + +static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, + u8 *value); +static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, + u16 *value); +static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset, + u32 *value); +static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset, + u8 value); +static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset, + u16 value); +static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, + u32 value); +static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, + u8 data); +static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); +static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, + u8 *data); +static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, + u8 word_en, u8 *data); +static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, + u8 *targetdata); +static u8 enable_efuse_data_write(struct ieee80211_hw *hw, + u16 efuse_addr, u8 word_en, u8 *data); +static u16 efuse_get_current_size(struct ieee80211_hw *hw); +static u8 efuse_calculate_word_cnts(u8 word_en); + +void efuse_initialize(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bytetemp; + u8 temp; + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1); + temp = bytetemp | 0x20; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp); + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1); + temp = bytetemp & 0xFE; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp); + + bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3); + temp = bytetemp | 0x80; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp); + + rtl_write_byte(rtlpriv, 0x2F8, 0x3); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); + +} + +u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 data; + u8 bytetemp; + u8 temp; + u32 k = 0; + const u32 efuse_len = + rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; + + if (address < efuse_len) { + temp = address & 0xFF; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + temp); + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + temp = bytetemp & 0x7F; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, + temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + while (!(bytetemp & 0x80)) { + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg-> + maps[EFUSE_CTRL] + 3); + k++; + if (k == 1000) + break; + } + data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + return data; + } else + return 0xFF; + +} +EXPORT_SYMBOL(efuse_read_1byte); + +void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bytetemp; + u8 temp; + u32 k = 0; + const u32 efuse_len = + rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); + + if (address < efuse_len) { + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); + + temp = address & 0xFF; + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + temp); + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + + temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + temp = bytetemp | 0x80; + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp); + + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + + while (bytetemp & 0x80) { + bytetemp = rtl_read_byte(rtlpriv, + rtlpriv->cfg-> + maps[EFUSE_CTRL] + 3); + k++; + if (k == 100) { + k = 0; + break; + } + } + } + +} + +void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 max_attempts = 10000; + u32 value32; + u8 readbyte; + u16 retry; + + /* + * In case of USB devices, transfer speeds are limited, hence + * efuse I/O reads could be (way) slower. So, decrease (a lot) + * the read attempts in case of failures. + */ + if (rtlpriv->rtlhal.interface == INTF_USB) + max_attempts = 10; + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + (_offset & 0xff)); + readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); + + readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, + (readbyte & 0x7f)); + + retry = 0; + value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < max_attempts)) { + value32 = rtl_read_dword(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL]); + retry++; + } + + udelay(50); + value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + + *pbuf = (u8) (value32 & 0xff); +} +EXPORT_SYMBOL_GPL(read_efuse_byte); + +void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *efuse_tbl; + u8 rtemp8[1]; + u16 efuse_addr = 0; + u8 offset, wren; + u8 u1temp = 0; + u16 i; + u16 j; + const u16 efuse_max_section = + rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; + const u32 efuse_len = + rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; + u16 **efuse_word; + u16 efuse_utilized = 0; + u8 efuse_usage; + + if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: Invalid offset(%#x) with read bytes(%#x)!!\n", + __func__, _offset, _size_byte); + return; + } + + /* allocate memory for efuse_tbl and efuse_word */ + efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], + GFP_ATOMIC); + if (!efuse_tbl) + return; + efuse_word = kcalloc(EFUSE_MAX_WORD_UNIT, sizeof(u16 *), GFP_ATOMIC); + if (!efuse_word) + goto out; + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16), + GFP_ATOMIC); + if (!efuse_word[i]) + goto done; + } + + for (i = 0; i < efuse_max_section; i++) + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + efuse_word[j][i] = 0xFFFF; + + read_efuse_byte(hw, efuse_addr, rtemp8); + if (*rtemp8 != 0xFF) { + efuse_utilized++; + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); + efuse_addr++; + } + + while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) { + /* Check PG header for section num. */ + if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */ + u1temp = ((*rtemp8 & 0xE0) >> 5); + read_efuse_byte(hw, efuse_addr, rtemp8); + + if ((*rtemp8 & 0x0F) == 0x0F) { + efuse_addr++; + read_efuse_byte(hw, efuse_addr, rtemp8); + + if (*rtemp8 != 0xFF && + (efuse_addr < efuse_len)) { + efuse_addr++; + } + continue; + } else { + offset = ((*rtemp8 & 0xF0) >> 1) | u1temp; + wren = (*rtemp8 & 0x0F); + efuse_addr++; + } + } else { + offset = ((*rtemp8 >> 4) & 0x0f); + wren = (*rtemp8 & 0x0f); + } + + if (offset < efuse_max_section) { + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + "offset-%d Worden=%x\n", offset, wren); + + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + if (!(wren & 0x01)) { + RTPRINT(rtlpriv, FEEPROM, + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); + + read_efuse_byte(hw, efuse_addr, rtemp8); + efuse_addr++; + efuse_utilized++; + efuse_word[i][offset] = + (*rtemp8 & 0xff); + + if (efuse_addr >= efuse_len) + break; + + RTPRINT(rtlpriv, FEEPROM, + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); + + read_efuse_byte(hw, efuse_addr, rtemp8); + efuse_addr++; + efuse_utilized++; + efuse_word[i][offset] |= + (((u16)*rtemp8 << 8) & 0xff00); + + if (efuse_addr >= efuse_len) + break; + } + + wren >>= 1; + } + } + + RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); + read_efuse_byte(hw, efuse_addr, rtemp8); + if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) { + efuse_utilized++; + efuse_addr++; + } + } + + for (i = 0; i < efuse_max_section; i++) { + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { + efuse_tbl[(i * 8) + (j * 2)] = + (efuse_word[j][i] & 0xff); + efuse_tbl[(i * 8) + ((j * 2) + 1)] = + ((efuse_word[j][i] >> 8) & 0xff); + } + } + + for (i = 0; i < _size_byte; i++) + pbuf[i] = efuse_tbl[_offset + i]; + + rtlefuse->efuse_usedbytes = efuse_utilized; + efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len); + rtlefuse->efuse_usedpercentage = efuse_usage; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, + (u8 *)&efuse_utilized); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, + &efuse_usage); +done: + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) + kfree(efuse_word[i]); + kfree(efuse_word); +out: + kfree(efuse_tbl); +} + +bool efuse_shadow_update_chk(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 section_idx, i, base; + u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used; + bool wordchanged, result = true; + + for (section_idx = 0; section_idx < 16; section_idx++) { + base = section_idx * 8; + wordchanged = false; + + for (i = 0; i < 8; i = i + 2) { + if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i] || + rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i + 1] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i + + 1]) { + words_need++; + wordchanged = true; + } + } + + if (wordchanged) + hdr_num++; + } + + totalbytes = hdr_num + words_need * 2; + efuse_used = rtlefuse->efuse_usedbytes; + + if ((totalbytes + efuse_used) >= + (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) + result = false; + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + __func__, totalbytes, hdr_num, words_need, efuse_used); + + return result; +} + +void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value) +{ + if (type == 1) + efuse_shadow_read_1byte(hw, offset, (u8 *)value); + else if (type == 2) + efuse_shadow_read_2byte(hw, offset, (u16 *)value); + else if (type == 4) + efuse_shadow_read_4byte(hw, offset, value); + +} +EXPORT_SYMBOL(efuse_shadow_read); + +void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, + u32 value) +{ + if (type == 1) + efuse_shadow_write_1byte(hw, offset, (u8) value); + else if (type == 2) + efuse_shadow_write_2byte(hw, offset, (u16) value); + else if (type == 4) + efuse_shadow_write_4byte(hw, offset, value); + +} + +bool efuse_shadow_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u16 i, offset, base; + u8 word_en = 0x0F; + u8 first_pg = false; + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + + if (!efuse_shadow_update_chk(hw)) { + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse out of capacity!!\n"); + return false; + } + efuse_power_switch(hw, true, true); + + for (offset = 0; offset < 16; offset++) { + + word_en = 0x0F; + base = offset * 8; + + for (i = 0; i < 8; i++) { + if (first_pg) { + word_en &= ~(BIT(i / 2)); + + rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; + } else { + + if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] != + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) { + word_en &= ~(BIT(i / 2)); + + rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; + } + } + } + + if (word_en != 0x0F) { + u8 tmpdata[8]; + + memcpy(tmpdata, + &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], + 8); + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, + "U-efuse\n", tmpdata, 8); + + if (!efuse_pg_packet_write(hw, (u8) offset, word_en, + tmpdata)) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "PG section(%#x) fail!!\n", offset); + break; + } + } + } + + efuse_power_switch(hw, true, false); + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + + memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + return true; +} + +void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + if (rtlefuse->autoload_failflag) + memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), + 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + else + efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); + + memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], + &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); + +} +EXPORT_SYMBOL(rtl_efuse_shadow_map_update); + +void efuse_force_write_vendor_id(struct ieee80211_hw *hw) +{ + u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF }; + + efuse_power_switch(hw, true, true); + + efuse_pg_packet_write(hw, 1, 0xD, tmpdata); + + efuse_power_switch(hw, true, false); + +} + +void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx) +{ +} + +static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, + u16 offset, u8 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; +} + +static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, + u16 offset, u16 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; + +} + +static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, + u16 offset, u32 *value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16; + *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24; +} + +static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, + u16 offset, u8 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value; +} + +static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, + u16 offset, u16 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF; + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8; + +} + +static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, + u16 offset, u32 value) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = + (u8) (value & 0x000000FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = + (u8) ((value >> 8) & 0x0000FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] = + (u8) ((value >> 16) & 0x00FF); + rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] = + (u8) ((value >> 24) & 0xFF); + +} + +int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmpidx = 0; + int result; + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, + (u8) (addr & 0xff)); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + ((u8) ((addr >> 8) & 0x03)) | + (rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 2) & + 0xFC)); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); + + while (!(0x80 & rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) + && (tmpidx < 100)) { + tmpidx++; + } + + if (tmpidx < 100) { + *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); + result = true; + } else { + *data = 0xff; + result = false; + } + return result; +} +EXPORT_SYMBOL(efuse_one_byte_read); + +static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmpidx = 0; + + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "Addr = %x Data=%x\n", addr, data); + + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, + (rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + + 2) & 0xFC) | (u8) ((addr >> 8) & 0x03)); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data); + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2); + + while ((0x80 & rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) + && (tmpidx < 100)) { + tmpidx++; + } + + if (tmpidx < 100) + return true; + return false; +} + +static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + efuse_power_switch(hw, false, true); + read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse); + efuse_power_switch(hw, false, false); +} + +static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, + u8 efuse_data, u8 offset, u8 *tmpdata, + u8 *readstate) +{ + bool dataempty = true; + u8 hoffset; + u8 tmpidx; + u8 hworden; + u8 word_cnts; + + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + word_cnts = efuse_calculate_word_cnts(hworden); + + if (hoffset == offset) { + for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { + if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx, + &efuse_data)) { + tmpdata[tmpidx] = efuse_data; + if (efuse_data != 0xff) + dataempty = false; + } + } + + if (!dataempty) { + *readstate = PG_STATE_DATA; + } else { + *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; + *readstate = PG_STATE_HEADER; + } + + } else { + *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; + *readstate = PG_STATE_HEADER; + } +} + +static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) +{ + u8 readstate = PG_STATE_HEADER; + + bool continual = true; + + u8 efuse_data, word_cnts = 0; + u16 efuse_addr = 0; + u8 tmpdata[8]; + + if (data == NULL) + return false; + if (offset > 15) + return false; + + memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); + memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); + + while (continual && (efuse_addr < EFUSE_MAX_SIZE)) { + if (readstate & PG_STATE_HEADER) { + if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) + && (efuse_data != 0xFF)) + efuse_read_data_case1(hw, &efuse_addr, + efuse_data, offset, + tmpdata, &readstate); + else + continual = false; + } else if (readstate & PG_STATE_DATA) { + efuse_word_enable_data_read(0, tmpdata, data); + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + readstate = PG_STATE_HEADER; + } + + } + + if ((data[0] == 0xff) && (data[1] == 0xff) && + (data[2] == 0xff) && (data[3] == 0xff) && + (data[4] == 0xff) && (data[5] == 0xff) && + (data[6] == 0xff) && (data[7] == 0xff)) + return false; + else + return true; + +} + +static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, + u8 efuse_data, u8 offset, + int *continual, u8 *write_state, + struct pgpkt_struct *target_pkt, + int *repeat_times, int *result, u8 word_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct tmp_pkt; + int dataempty = true; + u8 originaldata[8 * sizeof(u8)]; + u8 badworden = 0x0F; + u8 match_word_en, tmp_word_en; + u8 tmpindex; + u8 tmp_header = efuse_data; + u8 tmp_word_cnts; + + tmp_pkt.offset = (tmp_header >> 4) & 0x0F; + tmp_pkt.word_en = tmp_header & 0x0F; + tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); + + if (tmp_pkt.offset != target_pkt->offset) { + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; + *write_state = PG_STATE_HEADER; + } else { + for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { + if (efuse_one_byte_read(hw, + (*efuse_addr + 1 + tmpindex), + &efuse_data) && + (efuse_data != 0xFF)) + dataempty = false; + } + + if (!dataempty) { + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; + *write_state = PG_STATE_HEADER; + } else { + match_word_en = 0x0F; + if (!((target_pkt->word_en & BIT(0)) | + (tmp_pkt.word_en & BIT(0)))) + match_word_en &= (~BIT(0)); + + if (!((target_pkt->word_en & BIT(1)) | + (tmp_pkt.word_en & BIT(1)))) + match_word_en &= (~BIT(1)); + + if (!((target_pkt->word_en & BIT(2)) | + (tmp_pkt.word_en & BIT(2)))) + match_word_en &= (~BIT(2)); + + if (!((target_pkt->word_en & BIT(3)) | + (tmp_pkt.word_en & BIT(3)))) + match_word_en &= (~BIT(3)); + + if ((match_word_en & 0x0F) != 0x0F) { + badworden = + enable_efuse_data_write(hw, + *efuse_addr + 1, + tmp_pkt.word_en, + target_pkt->data); + + if (0x0F != (badworden & 0x0F)) { + u8 reorg_offset = offset; + u8 reorg_worden = badworden; + + efuse_pg_packet_write(hw, reorg_offset, + reorg_worden, + originaldata); + } + + tmp_word_en = 0x0F; + if ((target_pkt->word_en & BIT(0)) ^ + (match_word_en & BIT(0))) + tmp_word_en &= (~BIT(0)); + + if ((target_pkt->word_en & BIT(1)) ^ + (match_word_en & BIT(1))) + tmp_word_en &= (~BIT(1)); + + if ((target_pkt->word_en & BIT(2)) ^ + (match_word_en & BIT(2))) + tmp_word_en &= (~BIT(2)); + + if ((target_pkt->word_en & BIT(3)) ^ + (match_word_en & BIT(3))) + tmp_word_en &= (~BIT(3)); + + if ((tmp_word_en & 0x0F) != 0x0F) { + *efuse_addr = efuse_get_current_size(hw); + target_pkt->offset = offset; + target_pkt->word_en = tmp_word_en; + } else { + *continual = false; + } + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *continual = false; + *result = false; + } + } else { + *efuse_addr += (2 * tmp_word_cnts) + 1; + target_pkt->offset = offset; + target_pkt->word_en = word_en; + *write_state = PG_STATE_HEADER; + } + } + } + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); +} + +static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, + int *continual, u8 *write_state, + struct pgpkt_struct target_pkt, + int *repeat_times, int *result) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct tmp_pkt; + u8 pg_header; + u8 tmp_header; + u8 originaldata[8 * sizeof(u8)]; + u8 tmp_word_cnts; + u8 badworden = 0x0F; + + pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en; + efuse_one_byte_write(hw, *efuse_addr, pg_header); + efuse_one_byte_read(hw, *efuse_addr, &tmp_header); + + if (tmp_header == pg_header) { + *write_state = PG_STATE_DATA; + } else if (tmp_header == 0xFF) { + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *continual = false; + *result = false; + } + } else { + tmp_pkt.offset = (tmp_header >> 4) & 0x0F; + tmp_pkt.word_en = tmp_header & 0x0F; + + tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); + + memset(originaldata, 0xff, 8 * sizeof(u8)); + + if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) { + badworden = enable_efuse_data_write(hw, + *efuse_addr + 1, + tmp_pkt.word_en, + originaldata); + + if (0x0F != (badworden & 0x0F)) { + u8 reorg_offset = tmp_pkt.offset; + u8 reorg_worden = badworden; + + efuse_pg_packet_write(hw, reorg_offset, + reorg_worden, + originaldata); + *efuse_addr = efuse_get_current_size(hw); + } else { + *efuse_addr = *efuse_addr + + (tmp_word_cnts * 2) + 1; + } + } else { + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; + } + + *write_state = PG_STATE_HEADER; + *repeat_times += 1; + if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { + *continual = false; + *result = false; + } + + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + "efuse PG_STATE_HEADER-2\n"); + } +} + +static int efuse_pg_packet_write(struct ieee80211_hw *hw, + u8 offset, u8 word_en, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct pgpkt_struct target_pkt; + u8 write_state = PG_STATE_HEADER; + int continual = true, result = true; + u16 efuse_addr = 0; + u8 efuse_data; + u8 target_word_cnts = 0; + u8 badworden = 0x0F; + static int repeat_times; + + if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - + rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + "efuse_pg_packet_write error\n"); + return false; + } + + target_pkt.offset = offset; + target_pkt.word_en = word_en; + + memset(target_pkt.data, 0xFF, 8 * sizeof(u8)); + + efuse_word_enable_data_read(word_en, data, target_pkt.data); + target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); + + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); + + while (continual && (efuse_addr < (EFUSE_MAX_SIZE - + rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { + if (write_state == PG_STATE_HEADER) { + badworden = 0x0F; + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + "efuse PG_STATE_HEADER\n"); + + if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && + (efuse_data != 0xFF)) + efuse_write_data_case1(hw, &efuse_addr, + efuse_data, offset, + &continual, + &write_state, + &target_pkt, + &repeat_times, &result, + word_en); + else + efuse_write_data_case2(hw, &efuse_addr, + &continual, + &write_state, + target_pkt, + &repeat_times, + &result); + + } else if (write_state == PG_STATE_DATA) { + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + "efuse PG_STATE_DATA\n"); + badworden = + enable_efuse_data_write(hw, efuse_addr + 1, + target_pkt.word_en, + target_pkt.data); + + if ((badworden & 0x0F) == 0x0F) { + continual = false; + } else { + efuse_addr = + efuse_addr + (2 * target_word_cnts) + 1; + + target_pkt.offset = offset; + target_pkt.word_en = badworden; + target_word_cnts = + efuse_calculate_word_cnts(target_pkt. + word_en); + write_state = PG_STATE_HEADER; + repeat_times++; + if (repeat_times > EFUSE_REPEAT_THRESHOLD_) { + continual = false; + result = false; + } + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, + "efuse PG_STATE_HEADER-3\n"); + } + } + } + + if (efuse_addr >= (EFUSE_MAX_SIZE - + rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse_addr(%#x) Out of size!!\n", efuse_addr); + } + + return true; +} + +static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, + u8 *targetdata) +{ + if (!(word_en & BIT(0))) { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + + if (!(word_en & BIT(1))) { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + + if (!(word_en & BIT(2))) { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + + if (!(word_en & BIT(3))) { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + +static u8 enable_efuse_data_write(struct ieee80211_hw *hw, + u16 efuse_addr, u8 word_en, u8 *data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 tmpaddr; + u16 start_addr = efuse_addr; + u8 badworden = 0x0F; + u8 tmpdata[8]; + + memset(tmpdata, 0xff, PGPKT_DATA_SIZE); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); + + if (!(word_en & BIT(0))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[0]); + efuse_one_byte_write(hw, start_addr++, data[1]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]); + if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) + badworden &= (~BIT(0)); + } + + if (!(word_en & BIT(1))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[2]); + efuse_one_byte_write(hw, start_addr++, data[3]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]); + if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) + badworden &= (~BIT(1)); + } + + if (!(word_en & BIT(2))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[4]); + efuse_one_byte_write(hw, start_addr++, data[5]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]); + if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) + badworden &= (~BIT(2)); + } + + if (!(word_en & BIT(3))) { + tmpaddr = start_addr; + efuse_one_byte_write(hw, start_addr++, data[6]); + efuse_one_byte_write(hw, start_addr++, data[7]); + + efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]); + efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]); + if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) + badworden &= (~BIT(3)); + } + + return badworden; +} + +void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tempval; + u16 tmpv16; + + if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) { + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && + rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) { + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69); + } else { + tmpv16 = + rtl_read_word(rtlpriv, + rtlpriv->cfg->maps[SYS_ISO_CTRL]); + if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { + tmpv16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V]; + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_ISO_CTRL], + tmpv16); + } + } + tmpv16 = rtl_read_word(rtlpriv, + rtlpriv->cfg->maps[SYS_FUNC_EN]); + if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) { + tmpv16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR]; + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_FUNC_EN], tmpv16); + } + + tmpv16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]); + if ((!(tmpv16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) || + (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) { + tmpv16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] | + rtlpriv->cfg->maps[EFUSE_ANA8M]); + rtl_write_word(rtlpriv, + rtlpriv->cfg->maps[SYS_CLK], tmpv16); + } + } + + if (pwrstate) { + if (write) { + tempval = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + + 3); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6)); + tempval |= (VOLTAGE_V25 << 3); + } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { + tempval &= 0x0F; + tempval |= (VOLTAGE_V25 << 4); + } + + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + 3, + (tempval | 0x80)); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], + 0x03); + } + } else { + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && + rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_ACCESS], 0); + + if (write) { + tempval = rtl_read_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + + 3); + rtl_write_byte(rtlpriv, + rtlpriv->cfg->maps[EFUSE_TEST] + 3, + (tempval & 0x7F)); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], + 0x02); + } + } +} +EXPORT_SYMBOL(efuse_power_switch); + +static u16 efuse_get_current_size(struct ieee80211_hw *hw) +{ + int continual = true; + u16 efuse_addr = 0; + u8 hworden; + u8 efuse_data, word_cnts; + + while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && + (efuse_addr < EFUSE_MAX_SIZE)) { + if (efuse_data != 0xFF) { + hworden = efuse_data & 0x0F; + word_cnts = efuse_calculate_word_cnts(hworden); + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + } else { + continual = false; + } + } + + return efuse_addr; +} + +static u8 efuse_calculate_word_cnts(u8 word_en) +{ + u8 word_cnts = 0; + + if (!(word_en & BIT(0))) + word_cnts++; + if (!(word_en & BIT(1))) + word_cnts++; + if (!(word_en & BIT(2))) + word_cnts++; + if (!(word_en & BIT(3))) + word_cnts++; + return word_cnts; +} + +int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, + int max_size, u8 *hwinfo, const int *params) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + struct device *dev = &rtlpcipriv->dev.pdev->dev; + u16 eeprom_id; + u16 i, usvalue; + + switch (rtlefuse->epromtype) { + case EEPROM_BOOT_EFUSE: + rtl_efuse_shadow_map_update(hw); + break; + + case EEPROM_93C46: + pr_err("RTL8XXX did not boot from eeprom, check it !!\n"); + return 1; + + default: + dev_warn(dev, "no efuse data\n"); + return 1; + } + + memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], max_size); + + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", + hwinfo, max_size); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != params[0]) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtlefuse->autoload_failflag = true; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag) + return 1; + + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[params[1]]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]]; + rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]]; + rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]]; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROMId = 0x%4x\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[params[5] + i]; + *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + + rtlefuse->eeprom_channelplan = *&hwinfo[params[6]]; + rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]]; + rtlefuse->txpwr_fromeprom = true; + rtlefuse->eeprom_oemid = *&hwinfo[params[8]]; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + + /* set channel plan to world wide 13 */ + rtlefuse->channel_plan = params[9]; + + return 0; +} +EXPORT_SYMBOL_GPL(rtl_get_hwinfo); + +static void _rtl_fw_block_write_usb(struct ieee80211_hw *hw, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 start = START_ADDRESS; + u32 n; + + while (size > 0) { + if (size >= 64) + n = 64; + else if (size >= 8) + n = 8; + else + n = 1; + + rtl_write_chunk(rtlpriv, start, n, buffer); + + start += n; + buffer += n; + size -= n; + } +} + +void rtl_fw_block_write(struct ieee80211_hw *hw, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + if (rtlpriv->rtlhal.interface == INTF_PCI) { + for (i = 0; i < size; i++) + rtl_write_byte(rtlpriv, (START_ADDRESS + i), + *(buffer + i)); + } else if (rtlpriv->rtlhal.interface == INTF_USB) { + _rtl_fw_block_write_usb(hw, buffer, size); + } +} +EXPORT_SYMBOL_GPL(rtl_fw_block_write); + +void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, u8 *buffer, + u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8)(page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + rtl_fw_block_write(hw, buffer, size); +} +EXPORT_SYMBOL_GPL(rtl_fw_page_write); + +void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8)(fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} +EXPORT_SYMBOL_GPL(rtl_fill_dummy); + +void rtl_efuse_ops_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->efuse.efuse_ops = &efuse_ops; +} +EXPORT_SYMBOL_GPL(rtl_efuse_ops_init); diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.h b/drivers/net/wireless/realtek/rtlwifi/efuse.h new file mode 100644 index 000000000..e250ffb0f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_EFUSE_H_ +#define __RTL_EFUSE_H_ + +#define EFUSE_IC_ID_OFFSET 506 + +#define EFUSE_MAX_WORD_UNIT 4 + +#define EFUSE_INIT_MAP 0 +#define EFUSE_MODIFY_MAP 1 + +#define PG_STATE_HEADER 0x01 +#define PG_STATE_WORD_0 0x02 +#define PG_STATE_WORD_1 0x04 +#define PG_STATE_WORD_2 0x08 +#define PG_STATE_WORD_3 0x10 +#define PG_STATE_DATA 0x20 + +#define EFUSE_REPEAT_THRESHOLD_ 3 +#define EFUSE_ERROE_HANDLE 1 + +struct efuse_map { + u8 offset; + u8 word_start; + u8 byte_start; + u8 byte_cnts; +}; + +struct pgpkt_struct { + u8 offset; + u8 word_en; + u8 data[8]; +}; + +enum efuse_data_item { + EFUSE_CHIP_ID = 0, + EFUSE_LDO_SETTING, + EFUSE_CLK_SETTING, + EFUSE_SDIO_SETTING, + EFUSE_CCCR, + EFUSE_SDIO_MODE, + EFUSE_OCR, + EFUSE_F0CIS, + EFUSE_F1CIS, + EFUSE_MAC_ADDR, + EFUSE_EEPROM_VER, + EFUSE_CHAN_PLAN, + EFUSE_TXPW_TAB +}; + +enum { + VOLTAGE_V25 = 0x03, + LDOE25_SHIFT = 28, +}; + +struct efuse_priv { + u8 id[2]; + u8 ldo_setting[2]; + u8 clk_setting[2]; + u8 cccr; + u8 sdio_mode; + u8 ocr[3]; + u8 cis0[17]; + u8 cis1[48]; + u8 mac_addr[6]; + u8 eeprom_verno; + u8 channel_plan; + u8 tx_power_b[14]; + u8 tx_power_g[14]; +}; + +void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); +void efuse_initialize(struct ieee80211_hw *hw); +u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); +int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data); +void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); +void read_efuse(struct ieee80211_hw *hw, u16 _offset, + u16 _size_byte, u8 *pbuf); +void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value); +void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 value); +bool efuse_shadow_update(struct ieee80211_hw *hw); +bool efuse_shadow_update_chk(struct ieee80211_hw *hw); +void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); +void efuse_force_write_vendor_id(struct ieee80211_hw *hw); +void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); +void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate); +int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, + int max_size, u8 *hwinfo, const int *params); +void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen); +void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, u8 *buffer, + u32 size); +void rtl_fw_block_write(struct ieee80211_hw *hw, u8 *buffer, u32 size); +void rtl_efuse_ops_init(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c new file mode 100644 index 000000000..d3b79d0d3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -0,0 +1,2386 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "core.h" +#include "pci.h" +#include "base.h" +#include "ps.h" +#include "efuse.h" +#include +#include +#include + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PCI basic driver for rtlwifi"); + +static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { + INTEL_VENDOR_ID, + ATI_VENDOR_ID, + AMD_VENDOR_ID, + SIS_VENDOR_ID +}; + +static const u8 ac_to_hwq[] = { + VO_QUEUE, + VI_QUEUE, + BE_QUEUE, + BK_QUEUE +}; + +static const struct pci_device_id rtl_aspm_quirks[] = { + /* ASUSTek F441U/X555UQ */ + { PCI_DEVICE_SUB(PCI_VENDOR_ID_REALTEK, 0xb723, 0x11ad, 0x1723) }, + /* Razer Blade 14 2017 */ + { PCI_DEVICE_SUB(PCI_VENDOR_ID_REALTEK, 0xb723, 0x17aa, 0xb736) }, + {} +}; + +static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + __le16 fc = rtl_get_fc(skb); + u8 queue_index = skb_get_queue_mapping(skb); + struct ieee80211_hdr *hdr; + + if (unlikely(ieee80211_is_beacon(fc))) + return BEACON_QUEUE; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return MGNT_QUEUE; + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) + if (ieee80211_is_nullfunc(fc)) + return HIGH_QUEUE; + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { + hdr = rtl_get_hdr(skb); + + if (is_multicast_ether_addr(hdr->addr1) || + is_broadcast_ether_addr(hdr->addr1)) + return HIGH_QUEUE; + } + + return ac_to_hwq[queue_index]; +} + +/* Update PCI dependent default settings*/ +static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + u16 init_aspm; + + ppsc->reg_rfps_level = 0; + ppsc->support_aspm = false; + + /*Update PCI ASPM setting */ + switch (rtlpci->const_pci_aspm) { + case 0: + /*No ASPM */ + break; + + case 1: + /*ASPM dynamically enabled/disable. */ + ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM; + break; + + case 2: + /*ASPM with Clock Req dynamically enabled/disable. */ + ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 3: + /* Always enable ASPM and Clock Req + * from initialization to halt. + */ + ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM); + ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 4: + /* Always enable ASPM without Clock Req + * from initialization to halt. + */ + ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM | + RT_RF_OFF_LEVL_CLK_REQ); + ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM; + break; + } + + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + + /*Update Radio OFF setting */ + switch (rtlpci->const_hwsw_rfoff_d3) { + case 1: + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + break; + + case 2: + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + break; + + case 3: + ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3; + break; + } + + /*Set HW definition to determine if it supports ASPM. */ + switch (rtlpci->const_support_pciaspm) { + case 0: + /*Not support ASPM. */ + ppsc->support_aspm = false; + break; + case 1: + /*Support ASPM. */ + ppsc->support_aspm = true; + ppsc->support_backdoor = true; + break; + case 2: + /*ASPM value set by chipset. */ + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) + ppsc->support_aspm = true; + break; + default: + pr_err("switch case %#x not processed\n", + rtlpci->const_support_pciaspm); + break; + } + + /* toshiba aspm issue, toshiba will set aspm selfly + * so we should not set aspm in driver + */ + pcie_capability_read_word(rtlpci->pdev, PCI_EXP_LNKCTL, &init_aspm); + if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE && + ((u8)init_aspm) == (PCI_EXP_LNKCTL_ASPM_L0S | + PCI_EXP_LNKCTL_ASPM_L1 | PCI_EXP_LNKCTL_CCC)) + ppsc->support_aspm = false; + +} + +static bool _rtl_pci_platform_switch_device_pci_aspm( + struct ieee80211_hw *hw, + u8 value) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + value &= PCI_EXP_LNKCTL_ASPMC; + + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) + value |= PCI_EXP_LNKCTL_CCC; + + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC | value, + value); + + return false; +} + +/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ +static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + value &= PCI_EXP_LNKCTL_CLKREQ_EN; + + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN, + value); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) + udelay(100); +} + +/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ +static void __rtl_pci_disable_aspm(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + /*Retrieve original configuration settings. */ + u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; + u16 aspmlevel = 0; + u16 tmp_u1b = 0; + + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); + + return; + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + _rtl_pci_switch_clk_req(hw, 0x0); + } + + /*for promising device will in L0 state after an I/O. */ + pcie_capability_read_word(rtlpci->pdev, PCI_EXP_LNKCTL, &tmp_u1b); + + /*Set corresponding value. */ + aspmlevel |= PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1; + linkctrl_reg &= ~aspmlevel; + + _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); +} + +static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if (!ppsc->support_aspm) + return; + + __rtl_pci_disable_aspm(hw); +} + +/*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for + *power saving We should follow the sequence to enable + *RTL8192SE first then enable Pci Bridge ASPM + *or the system will show bluescreen. + */ +static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; + u16 aspmlevel; + u8 u_device_aspmsetting; + + if (!ppsc->support_aspm) + return; + + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); + return; + } + + /*Get ASPM level (with/without Clock Req) */ + aspmlevel = rtlpci->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; + + /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/ + /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */ + + u_device_aspmsetting |= aspmlevel; + + _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & + RT_RF_OFF_LEVL_CLK_REQ) ? + PCI_EXP_LNKCTL_CLKREQ_EN : 0); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + } + udelay(100); +} + +static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + bool status = false; + u8 offset_e0; + unsigned int offset_e4; + + pci_write_config_byte(rtlpci->pdev, 0xe0, 0xa0); + + pci_read_config_byte(rtlpci->pdev, 0xe0, &offset_e0); + + if (offset_e0 == 0xA0) { + pci_read_config_dword(rtlpci->pdev, 0xe4, &offset_e4); + if (offset_e4 & BIT(23)) + status = true; + } + + return status; +} + +static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + + u8 tmp; + u16 linkctrl_reg; + + /*Link Control Register */ + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg); + pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); + + pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); + + tmp = 0x17; + pci_write_config_byte(pdev, 0x70f, tmp); +} + +static void rtl_pci_init_aspm(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + _rtl_pci_update_default_setting(hw); + + /* + * Certain pci devices are known to output large + * amounts of PCIe AER errors during and after boot up, causing + * heavy lags, poor network throughput, and occasional lock-ups. + */ + if (pci_match_id(rtl_aspm_quirks, rtlpci->pdev)) { + __rtl_pci_disable_aspm(hw); + ppsc->support_aspm = false; + } + + if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) { + /*Always enable ASPM & Clock Req. */ + rtl_pci_enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM); + } +} + +static void _rtl_pci_io_handler_init(struct device *dev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->io.dev = dev; + + rtlpriv->io.write8 = pci_write8_async; + rtlpriv->io.write16 = pci_write16_async; + rtlpriv->io.write32 = pci_write32_async; + + rtlpriv->io.read8 = pci_read8_sync; + rtlpriv->io.read16 = pci_read16_sync; + rtlpriv->io.read32 = pci_read32_sync; +} + +static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_tcb_desc *tcb_desc, u8 tid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct sk_buff *next_skb; + u8 additionlen = FCS_LEN; + + /* here open is 4, wep/tkip is 8, aes is 12*/ + if (info->control.hw_key) + additionlen += info->control.hw_key->icv_len; + + /* The most skb num is 6 */ + tcb_desc->empkt_num = 0; + spin_lock_bh(&rtlpriv->locks.waitq_lock); + skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) { + struct ieee80211_tx_info *next_info; + + next_info = IEEE80211_SKB_CB(next_skb); + if (next_info->flags & IEEE80211_TX_CTL_AMPDU) { + tcb_desc->empkt_len[tcb_desc->empkt_num] = + next_skb->len + additionlen; + tcb_desc->empkt_num++; + } else { + break; + } + + if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid], + next_skb)) + break; + + if (tcb_desc->empkt_num >= rtlhal->max_earlymode_num) + break; + } + spin_unlock_bh(&rtlpriv->locks.waitq_lock); + + return true; +} + +/* just for early mode now */ +static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct sk_buff *skb = NULL; + struct ieee80211_tx_info *info = NULL; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int tid; + + if (!rtlpriv->rtlhal.earlymode_enable) + return; + + /* we just use em for BE/BK/VI/VO */ + for (tid = 7; tid >= 0; tid--) { + u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + + while (!mac->act_scanning && + rtlpriv->psc.rfpwr_state == ERFON) { + struct rtl_tcb_desc tcb_desc; + + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + + spin_lock(&rtlpriv->locks.waitq_lock); + if (!skb_queue_empty(&mac->skb_waitq[tid]) && + (ring->entries - skb_queue_len(&ring->queue) > + rtlhal->max_earlymode_num)) { + skb = skb_dequeue(&mac->skb_waitq[tid]); + } else { + spin_unlock(&rtlpriv->locks.waitq_lock); + break; + } + spin_unlock(&rtlpriv->locks.waitq_lock); + + /* Some macaddr can't do early mode. like + * multicast/broadcast/no_qos data + */ + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + _rtl_update_earlymode_info(hw, skb, + &tcb_desc, tid); + + rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc); + } + } +} + +static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct sk_buff *skb; + struct ieee80211_tx_info *info; + __le16 fc; + u8 tid; + u8 *entry; + + if (rtlpriv->use_new_trx_flow) + entry = (u8 *)(&ring->buffer_desc[ring->idx]); + else + entry = (u8 *)(&ring->desc[ring->idx]); + + if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx)) + return; + ring->idx = (ring->idx + 1) % ring->entries; + + skb = __skb_dequeue(&ring->queue); + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + + /* remove early mode header */ + if (rtlpriv->rtlhal.earlymode_enable) + skb_pull(skb, EM_HDR_LEN); + + rtl_dbg(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *)(skb->data + 22)); + + if (prio == TXCMD_QUEUE) { + dev_kfree_skb(skb); + goto tx_status_ok; + } + + /* for sw LPS, just after NULL skb send out, we can + * sure AP knows we are sleeping, we should not let + * rf sleep + */ + fc = rtl_get_fc(skb); + if (ieee80211_is_nullfunc(fc)) { + if (ieee80211_has_pm(fc)) { + rtlpriv->mac80211.offchan_delay = true; + rtlpriv->psc.state_inap = true; + } else { + rtlpriv->psc.state_inap = false; + } + } + if (ieee80211_is_action(fc)) { + struct ieee80211_mgmt *action_frame = (void *)skb->data; + + if (skb->len >= IEEE80211_MIN_ACTION_SIZE(action_code) && + action_frame->u.action.action_code == + WLAN_HT_ACTION_SMPS) { + dev_kfree_skb(skb); + goto tx_status_ok; + } + } + + /* update tid tx pkt num */ + tid = rtl_get_tid(skb); + if (tid <= 7) + rtlpriv->link_info.tidtx_inperiod[tid]++; + + info = IEEE80211_SKB_CB(skb); + + if (likely(!ieee80211_is_nullfunc(fc))) { + ieee80211_tx_info_clear_status(info); + info->flags |= IEEE80211_TX_STAT_ACK; + /*info->status.rates[0].count = 1; */ + ieee80211_tx_status_irqsafe(hw, skb); + } else { + rtl_tx_ackqueue(hw, skb); + } + + if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); + + ieee80211_wake_queue(hw, skb_get_queue_mapping(skb)); + } +tx_status_ok: + skb = NULL; + } + + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + rtlpriv->link_info.num_rx_inperiod > 2) + rtl_lps_leave(hw, false); +} + +static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, + struct sk_buff *new_skb, u8 *entry, + int rxring_idx, int desc_idx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 bufferaddress; + u8 tmp_one = 1; + struct sk_buff *skb; + + if (likely(new_skb)) { + skb = new_skb; + goto remap; + } + skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (!skb) + return 0; + +remap: + /* just set skb->cb to mapping addr for pci_unmap_single use */ + *((dma_addr_t *)skb->cb) = + dma_map_single(&rtlpci->pdev->dev, skb_tail_pointer(skb), + rtlpci->rxbuffersize, DMA_FROM_DEVICE); + bufferaddress = *((dma_addr_t *)skb->cb); + if (dma_mapping_error(&rtlpci->pdev->dev, bufferaddress)) { + if (!new_skb) + kfree_skb(skb); + return 0; + } + rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; + if (rtlpriv->use_new_trx_flow) { + /* skb->cb may be 64 bit address */ + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RX_PREPARE, + (u8 *)(dma_addr_t *)skb->cb); + } else { + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RXBUFF_ADDR, + (u8 *)&bufferaddress); + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RXPKT_LEN, + (u8 *)&rtlpci->rxbuffersize); + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RXOWN, + (u8 *)&tmp_one); + } + return 1; +} + +/* inorder to receive 8K AMSDU we have set skb to + * 9100bytes in init rx ring, but if this packet is + * not a AMSDU, this large packet will be sent to + * TCP/IP directly, this cause big packet ping fail + * like: "ping -s 65507", so here we will realloc skb + * based on the true size of packet, Mac80211 + * Probably will do it better, but does not yet. + * + * Some platform will fail when alloc skb sometimes. + * in this condition, we will send the old skb to + * mac80211 directly, this will not cause any other + * issues, but only this packet will be lost by TCP/IP + */ +static void _rtl_pci_rx_to_mac80211(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct ieee80211_rx_status rx_status) +{ + if (unlikely(!rtl_action_proc(hw, skb, false))) { + dev_kfree_skb_any(skb); + } else { + struct sk_buff *uskb = NULL; + + uskb = dev_alloc_skb(skb->len + 128); + if (likely(uskb)) { + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + skb_put_data(uskb, skb->data, skb->len); + dev_kfree_skb_any(skb); + ieee80211_rx_irqsafe(hw, uskb); + } else { + ieee80211_rx_irqsafe(hw, skb); + } + } +} + +/*hsisr interrupt handler*/ +static void _rtl_pci_hs_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR], + rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR]) | + rtlpci->sys_irq_mask); +} + +static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int rxring_idx = RTL_PCI_RX_MPDU_QUEUE; + struct ieee80211_rx_status rx_status = { 0 }; + unsigned int count = rtlpci->rxringcount; + u8 own; + u8 tmp_one; + bool unicast = false; + u8 hw_queue = 0; + unsigned int rx_remained_cnt = 0; + struct rtl_stats stats = { + .signal = 0, + .rate = 0, + }; + + /*RX NORMAL PKT */ + while (count--) { + struct ieee80211_hdr *hdr; + __le16 fc; + u16 len; + /*rx buffer descriptor */ + struct rtl_rx_buffer_desc *buffer_desc = NULL; + /*if use new trx flow, it means wifi info */ + struct rtl_rx_desc *pdesc = NULL; + /*rx pkt */ + struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ + rtlpci->rx_ring[rxring_idx].idx]; + struct sk_buff *new_skb; + + if (rtlpriv->use_new_trx_flow) { + if (rx_remained_cnt == 0) + rx_remained_cnt = + rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw, + hw_queue); + if (rx_remained_cnt == 0) + return; + buffer_desc = &rtlpci->rx_ring[rxring_idx].buffer_desc[ + rtlpci->rx_ring[rxring_idx].idx]; + pdesc = (struct rtl_rx_desc *)skb->data; + } else { /* rx descriptor */ + pdesc = &rtlpci->rx_ring[rxring_idx].desc[ + rtlpci->rx_ring[rxring_idx].idx]; + + own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, + false, + HW_DESC_OWN); + if (own) /* wait data to be filled by hardware */ + return; + } + + /* Reaching this point means: data is filled already + * AAAAAAttention !!! + * We can NOT access 'skb' before 'pci_unmap_single' + */ + dma_unmap_single(&rtlpci->pdev->dev, *((dma_addr_t *)skb->cb), + rtlpci->rxbuffersize, DMA_FROM_DEVICE); + + /* get a new skb - if fail, old one will be reused */ + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) + goto no_new; + memset(&rx_status, 0, sizeof(rx_status)); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, + &rx_status, (u8 *)pdesc, skb); + + if (rtlpriv->use_new_trx_flow) + rtlpriv->cfg->ops->rx_check_dma_ok(hw, + (u8 *)buffer_desc, + hw_queue); + + len = rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, false, + HW_DESC_RXPKT_LEN); + + if (skb->end - skb->tail > len) { + skb_put(skb, len); + if (rtlpriv->use_new_trx_flow) + skb_reserve(skb, stats.rx_drvinfo_size + + stats.rx_bufshift + 24); + else + skb_reserve(skb, stats.rx_drvinfo_size + + stats.rx_bufshift); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "skb->end - skb->tail = %d, len is %d\n", + skb->end - skb->tail, len); + dev_kfree_skb_any(skb); + goto new_trx_end; + } + /* handle command packet here */ + if (stats.packet_report_type == C2H_PACKET) { + rtl_c2hcmd_enqueue(hw, skb); + goto new_trx_end; + } + + /* NOTICE This can not be use for mac80211, + * this is done in mac80211 code, + * if done here sec DHCP will fail + * skb_trim(skb, skb->len - 4); + */ + + hdr = rtl_get_hdr(skb); + fc = rtl_get_fc(skb); + + if (!stats.crc && !stats.hwerror && (skb->len > FCS_LEN)) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, + sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else if (is_multicast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + rtl_is_special_data(hw, skb, false, true); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + + rtl_collect_scan_list(hw, skb); + + /* static bcn for roaming */ + rtl_beacon_statistic(hw, skb); + rtl_p2p_info(hw, (void *)skb->data, skb->len); + /* for sw lps */ + rtl_swlps_beacon(hw, (void *)skb->data, skb->len); + rtl_recognize_peer(hw, (void *)skb->data, skb->len); + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP && + rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G && + (ieee80211_is_beacon(fc) || + ieee80211_is_probe_resp(fc))) { + dev_kfree_skb_any(skb); + } else { + _rtl_pci_rx_to_mac80211(hw, skb, rx_status); + } + } else { + /* drop packets with errors or those too short */ + dev_kfree_skb_any(skb); + } +new_trx_end: + if (rtlpriv->use_new_trx_flow) { + rtlpci->rx_ring[hw_queue].next_rx_rp += 1; + rtlpci->rx_ring[hw_queue].next_rx_rp %= + RTL_PCI_MAX_RX_COUNT; + + rx_remained_cnt--; + rtl_write_word(rtlpriv, 0x3B4, + rtlpci->rx_ring[hw_queue].next_rx_rp); + } + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + rtlpriv->link_info.num_rx_inperiod > 2) + rtl_lps_leave(hw, false); + skb = new_skb; +no_new: + if (rtlpriv->use_new_trx_flow) { + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, + rxring_idx, + rtlpci->rx_ring[rxring_idx].idx)) { + if (new_skb) + dev_kfree_skb_any(skb); + } + } else { + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, + rxring_idx, + rtlpci->rx_ring[rxring_idx].idx)) { + if (new_skb) + dev_kfree_skb_any(skb); + } + if (rtlpci->rx_ring[rxring_idx].idx == + rtlpci->rxringcount - 1) + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, + false, + HW_DESC_RXERO, + (u8 *)&tmp_one); + } + rtlpci->rx_ring[rxring_idx].idx = + (rtlpci->rx_ring[rxring_idx].idx + 1) % + rtlpci->rxringcount; + } +} + +static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) +{ + struct ieee80211_hw *hw = dev_id; + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flags; + struct rtl_int intvec = {0}; + + irqreturn_t ret = IRQ_HANDLED; + + if (rtlpci->irq_enabled == 0) + return ret; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + rtlpriv->cfg->ops->disable_interrupt(hw); + + /*read ISR: 4/8bytes */ + rtlpriv->cfg->ops->interrupt_recognized(hw, &intvec); + + /*Shared IRQ or HW disappeared */ + if (!intvec.inta || intvec.inta == 0xffff) + goto done; + + /*<1> beacon related */ + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon ok interrupt!\n"); + + if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon err interrupt!\n"); + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "prepare beacon for interrupt!\n"); + tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); + } + + /*<2> Tx related */ + if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Manage ok interrupt!\n"); + _rtl_pci_tx_isr(hw, MGNT_QUEUE); + } + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "HIGH_QUEUE ok interrupt!\n"); + _rtl_pci_tx_isr(hw, HIGH_QUEUE); + } + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BK Tx OK interrupt!\n"); + _rtl_pci_tx_isr(hw, BK_QUEUE); + } + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BE TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, BE_QUEUE); + } + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "VI TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, VI_QUEUE); + } + + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Vo TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, VO_QUEUE); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { + if (intvec.intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "H2C TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, H2C_QUEUE); + } + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "CMD TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, TXCMD_QUEUE); + } + } + + /*<3> Rx related */ + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); + _rtl_pci_rx_interrupt(hw); + } + + if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "rx descriptor unavailable!\n"); + _rtl_pci_rx_interrupt(hw); + } + + if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); + _rtl_pci_rx_interrupt(hw); + } + + /*<4> fw related*/ + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { + if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "firmware interrupt!\n"); + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.fwevt_wq, 0); + } + } + + /*<5> hsisr related*/ + /* Only 8188EE & 8723BE Supported. + * If Other ICs Come in, System will corrupt, + * because maps[RTL_IMR_HSISR_IND] & maps[MAC_HSISR] + * are not initialized + */ + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE || + rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) { + if (unlikely(intvec.inta & + rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "hsisr interrupt!\n"); + _rtl_pci_hs_interrupt(hw); + } + } + + if (rtlpriv->rtlhal.earlymode_enable) + tasklet_schedule(&rtlpriv->works.irq_tasklet); + +done: + rtlpriv->cfg->ops->enable_interrupt(hw); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return ret; +} + +static void _rtl_pci_irq_tasklet(struct tasklet_struct *t) +{ + struct rtl_priv *rtlpriv = from_tasklet(rtlpriv, t, works.irq_tasklet); + struct ieee80211_hw *hw = rtlpriv->hw; + _rtl_pci_tx_chk_waitq(hw); +} + +static void _rtl_pci_prepare_bcn_tasklet(struct tasklet_struct *t) +{ + struct rtl_priv *rtlpriv = from_tasklet(rtlpriv, t, + works.irq_prepare_bcn_tasklet); + struct ieee80211_hw *hw = rtlpriv->hw; + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl8192_tx_ring *ring = NULL; + struct ieee80211_hdr *hdr = NULL; + struct ieee80211_tx_info *info = NULL; + struct sk_buff *pskb = NULL; + struct rtl_tx_desc *pdesc = NULL; + struct rtl_tcb_desc tcb_desc; + /*This is for new trx flow*/ + struct rtl_tx_buffer_desc *pbuffer_desc = NULL; + u8 temp_one = 1; + u8 *entry; + + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + pskb = __skb_dequeue(&ring->queue); + if (rtlpriv->use_new_trx_flow) + entry = (u8 *)(&ring->buffer_desc[ring->idx]); + else + entry = (u8 *)(&ring->desc[ring->idx]); + if (pskb) { + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + pskb->len, DMA_TO_DEVICE); + kfree_skb(pskb); + } + + /*NB: the beacon data buffer must be 32-bit aligned. */ + pskb = ieee80211_beacon_get(hw, mac->vif, 0); + if (!pskb) + return; + hdr = rtl_get_hdr(pskb); + info = IEEE80211_SKB_CB(pskb); + pdesc = &ring->desc[0]; + if (rtlpriv->use_new_trx_flow) + pbuffer_desc = &ring->buffer_desc[0]; + + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, + (u8 *)pbuffer_desc, info, NULL, pskb, + BEACON_QUEUE, &tcb_desc); + + __skb_queue_tail(&ring->queue, pskb); + + if (rtlpriv->use_new_trx_flow) { + temp_one = 4; + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pbuffer_desc, true, + HW_DESC_OWN, (u8 *)&temp_one); + } else { + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, + &temp_one); + } +} + +static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 i; + u16 desc_num; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) + desc_num = TX_DESC_NUM_92E; + else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) + desc_num = TX_DESC_NUM_8822B; + else + desc_num = RT_TXDESC_NUM; + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + rtlpci->txringcount[i] = desc_num; + + /*we just alloc 2 desc for beacon queue, + *because we just need first desc in hw beacon. + */ + rtlpci->txringcount[BEACON_QUEUE] = 2; + + /*BE queue need more descriptor for performance + *consideration or, No more tx desc will happen, + *and may cause mac80211 mem leakage. + */ + if (!rtl_priv(hw)->use_new_trx_flow) + rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE; + + rtlpci->rxbuffersize = 9100; /*2048/1024; */ + rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT; /*64; */ +} + +static void _rtl_pci_init_struct(struct ieee80211_hw *hw, + struct pci_dev *pdev) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpci->up_first_time = true; + rtlpci->being_init_adapter = false; + + rtlhal->hw = hw; + rtlpci->pdev = pdev; + + /*Tx/Rx related var */ + _rtl_pci_init_trx_var(hw); + + /*IBSS*/ + mac->beacon_interval = 100; + + /*AMPDU*/ + mac->min_space_cfg = 0; + mac->max_mss_density = 0; + /*set sane AMPDU defaults */ + mac->current_ampdu_density = 7; + mac->current_ampdu_factor = 3; + + /*Retry Limit*/ + mac->retry_short = 7; + mac->retry_long = 7; + + /*QOS*/ + rtlpci->acm_method = EACMWAY2_SW; + + /*task */ + tasklet_setup(&rtlpriv->works.irq_tasklet, _rtl_pci_irq_tasklet); + tasklet_setup(&rtlpriv->works.irq_prepare_bcn_tasklet, + _rtl_pci_prepare_bcn_tasklet); + INIT_WORK(&rtlpriv->works.lps_change_work, + rtl_lps_change_work_callback); +} + +static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, + unsigned int prio, unsigned int entries) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_tx_buffer_desc *buffer_desc; + struct rtl_tx_desc *desc; + dma_addr_t buffer_desc_dma, desc_dma; + u32 nextdescaddress; + int i; + + /* alloc tx buffer desc for new trx flow*/ + if (rtlpriv->use_new_trx_flow) { + buffer_desc = + dma_alloc_coherent(&rtlpci->pdev->dev, + sizeof(*buffer_desc) * entries, + &buffer_desc_dma, GFP_KERNEL); + + if (!buffer_desc || (unsigned long)buffer_desc & 0xFF) { + pr_err("Cannot allocate TX ring (prio = %d)\n", + prio); + return -ENOMEM; + } + + rtlpci->tx_ring[prio].buffer_desc = buffer_desc; + rtlpci->tx_ring[prio].buffer_desc_dma = buffer_desc_dma; + + rtlpci->tx_ring[prio].cur_tx_rp = 0; + rtlpci->tx_ring[prio].cur_tx_wp = 0; + } + + /* alloc dma for this ring */ + desc = dma_alloc_coherent(&rtlpci->pdev->dev, sizeof(*desc) * entries, + &desc_dma, GFP_KERNEL); + + if (!desc || (unsigned long)desc & 0xFF) { + pr_err("Cannot allocate TX ring (prio = %d)\n", prio); + return -ENOMEM; + } + + rtlpci->tx_ring[prio].desc = desc; + rtlpci->tx_ring[prio].dma = desc_dma; + + rtlpci->tx_ring[prio].idx = 0; + rtlpci->tx_ring[prio].entries = entries; + skb_queue_head_init(&rtlpci->tx_ring[prio].queue); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, desc); + + /* init every desc in this ring */ + if (!rtlpriv->use_new_trx_flow) { + for (i = 0; i < entries; i++) { + nextdescaddress = (u32)desc_dma + + ((i + 1) % entries) * + sizeof(*desc); + + rtlpriv->cfg->ops->set_desc(hw, (u8 *)&desc[i], + true, + HW_DESC_TX_NEXTDESC_ADDR, + (u8 *)&nextdescaddress); + } + } + return 0; +} + +static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + + if (rtlpriv->use_new_trx_flow) { + struct rtl_rx_buffer_desc *entry = NULL; + /* alloc dma for this ring */ + rtlpci->rx_ring[rxring_idx].buffer_desc = + dma_alloc_coherent(&rtlpci->pdev->dev, + sizeof(*rtlpci->rx_ring[rxring_idx].buffer_desc) * + rtlpci->rxringcount, + &rtlpci->rx_ring[rxring_idx].dma, GFP_KERNEL); + if (!rtlpci->rx_ring[rxring_idx].buffer_desc || + (ulong)rtlpci->rx_ring[rxring_idx].buffer_desc & 0xFF) { + pr_err("Cannot allocate RX ring\n"); + return -ENOMEM; + } + + /* init every desc in this ring */ + rtlpci->rx_ring[rxring_idx].idx = 0; + for (i = 0; i < rtlpci->rxringcount; i++) { + entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; + if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, + rxring_idx, i)) + return -ENOMEM; + } + } else { + struct rtl_rx_desc *entry = NULL; + u8 tmp_one = 1; + /* alloc dma for this ring */ + rtlpci->rx_ring[rxring_idx].desc = + dma_alloc_coherent(&rtlpci->pdev->dev, + sizeof(*rtlpci->rx_ring[rxring_idx].desc) * + rtlpci->rxringcount, + &rtlpci->rx_ring[rxring_idx].dma, GFP_KERNEL); + if (!rtlpci->rx_ring[rxring_idx].desc || + (unsigned long)rtlpci->rx_ring[rxring_idx].desc & 0xFF) { + pr_err("Cannot allocate RX ring\n"); + return -ENOMEM; + } + + /* init every desc in this ring */ + rtlpci->rx_ring[rxring_idx].idx = 0; + + for (i = 0; i < rtlpci->rxringcount; i++) { + entry = &rtlpci->rx_ring[rxring_idx].desc[i]; + if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, + rxring_idx, i)) + return -ENOMEM; + } + + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RXERO, &tmp_one); + } + return 0; +} + +static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, + unsigned int prio) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + /* free every desc in this ring */ + while (skb_queue_len(&ring->queue)) { + u8 *entry; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + if (rtlpriv->use_new_trx_flow) + entry = (u8 *)(&ring->buffer_desc[ring->idx]); + else + entry = (u8 *)(&ring->desc[ring->idx]); + + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + /* free dma of this ring */ + dma_free_coherent(&rtlpci->pdev->dev, + sizeof(*ring->desc) * ring->entries, ring->desc, + ring->dma); + ring->desc = NULL; + if (rtlpriv->use_new_trx_flow) { + dma_free_coherent(&rtlpci->pdev->dev, + sizeof(*ring->buffer_desc) * ring->entries, + ring->buffer_desc, ring->buffer_desc_dma); + ring->buffer_desc = NULL; + } +} + +static void _rtl_pci_free_rx_ring(struct ieee80211_hw *hw, int rxring_idx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int i; + + /* free every desc in this ring */ + for (i = 0; i < rtlpci->rxringcount; i++) { + struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[i]; + + if (!skb) + continue; + dma_unmap_single(&rtlpci->pdev->dev, *((dma_addr_t *)skb->cb), + rtlpci->rxbuffersize, DMA_FROM_DEVICE); + kfree_skb(skb); + } + + /* free dma of this ring */ + if (rtlpriv->use_new_trx_flow) { + dma_free_coherent(&rtlpci->pdev->dev, + sizeof(*rtlpci->rx_ring[rxring_idx].buffer_desc) * + rtlpci->rxringcount, + rtlpci->rx_ring[rxring_idx].buffer_desc, + rtlpci->rx_ring[rxring_idx].dma); + rtlpci->rx_ring[rxring_idx].buffer_desc = NULL; + } else { + dma_free_coherent(&rtlpci->pdev->dev, + sizeof(*rtlpci->rx_ring[rxring_idx].desc) * + rtlpci->rxringcount, + rtlpci->rx_ring[rxring_idx].desc, + rtlpci->rx_ring[rxring_idx].dma); + rtlpci->rx_ring[rxring_idx].desc = NULL; + } +} + +static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int ret; + int i, rxring_idx; + + /* rxring_idx 0:RX_MPDU_QUEUE + * rxring_idx 1:RX_CMD_QUEUE + */ + for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) { + ret = _rtl_pci_init_rx_ring(hw, rxring_idx); + if (ret) + return ret; + } + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { + ret = _rtl_pci_init_tx_ring(hw, i, rtlpci->txringcount[i]); + if (ret) + goto err_free_rings; + } + + return 0; + +err_free_rings: + for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) + _rtl_pci_free_rx_ring(hw, rxring_idx); + + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + if (rtlpci->tx_ring[i].desc || + rtlpci->tx_ring[i].buffer_desc) + _rtl_pci_free_tx_ring(hw, i); + + return 1; +} + +static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw) +{ + u32 i, rxring_idx; + + /*free rx rings */ + for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) + _rtl_pci_free_rx_ring(hw, rxring_idx); + + /*free tx rings */ + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) + _rtl_pci_free_tx_ring(hw, i); + + return 0; +} + +int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int i, rxring_idx; + unsigned long flags; + u8 tmp_one = 1; + u32 bufferaddress; + /* rxring_idx 0:RX_MPDU_QUEUE */ + /* rxring_idx 1:RX_CMD_QUEUE */ + for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) { + /* force the rx_ring[RX_MPDU_QUEUE/ + * RX_CMD_QUEUE].idx to the first one + *new trx flow, do nothing + */ + if (!rtlpriv->use_new_trx_flow && + rtlpci->rx_ring[rxring_idx].desc) { + struct rtl_rx_desc *entry = NULL; + + rtlpci->rx_ring[rxring_idx].idx = 0; + for (i = 0; i < rtlpci->rxringcount; i++) { + entry = &rtlpci->rx_ring[rxring_idx].desc[i]; + bufferaddress = + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + false, HW_DESC_RXBUFF_ADDR); + memset((u8 *)entry, 0, + sizeof(*rtlpci->rx_ring + [rxring_idx].desc));/*clear one entry*/ + if (rtlpriv->use_new_trx_flow) { + rtlpriv->cfg->ops->set_desc(hw, + (u8 *)entry, false, + HW_DESC_RX_PREPARE, + (u8 *)&bufferaddress); + } else { + rtlpriv->cfg->ops->set_desc(hw, + (u8 *)entry, false, + HW_DESC_RXBUFF_ADDR, + (u8 *)&bufferaddress); + rtlpriv->cfg->ops->set_desc(hw, + (u8 *)entry, false, + HW_DESC_RXPKT_LEN, + (u8 *)&rtlpci->rxbuffersize); + rtlpriv->cfg->ops->set_desc(hw, + (u8 *)entry, false, + HW_DESC_RXOWN, + (u8 *)&tmp_one); + } + } + rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, + HW_DESC_RXERO, (u8 *)&tmp_one); + } + rtlpci->rx_ring[rxring_idx].idx = 0; + } + + /*after reset, release previous pending packet, + *and force the tx idx to the first one + */ + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { + if (rtlpci->tx_ring[i].desc || + rtlpci->tx_ring[i].buffer_desc) { + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i]; + + while (skb_queue_len(&ring->queue)) { + u8 *entry; + struct sk_buff *skb = + __skb_dequeue(&ring->queue); + if (rtlpriv->use_new_trx_flow) + entry = (u8 *)(&ring->buffer_desc + [ring->idx]); + else + entry = (u8 *)(&ring->desc[ring->idx]); + + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + dev_kfree_skb_irq(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + if (rtlpriv->use_new_trx_flow) { + rtlpci->tx_ring[i].cur_tx_rp = 0; + rtlpci->tx_ring[i].cur_tx_wp = 0; + } + + ring->idx = 0; + ring->entries = rtlpci->txringcount[i]; + } + } + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + return 0; +} + +static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *sta_entry = NULL; + u8 tid = rtl_get_tid(skb); + __le16 fc = rtl_get_fc(skb); + + if (!sta) + return false; + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + + if (!rtlpriv->rtlhal.earlymode_enable) + return false; + if (ieee80211_is_nullfunc(fc)) + return false; + if (ieee80211_is_qos_nullfunc(fc)) + return false; + if (ieee80211_is_pspoll(fc)) + return false; + if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) + return false; + if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) + return false; + if (tid > 7) + return false; + + /* maybe every tid should be checked */ + if (!rtlpriv->link_info.higher_busytxtraffic[tid]) + return false; + + spin_lock_bh(&rtlpriv->locks.waitq_lock); + skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb); + spin_unlock_bh(&rtlpriv->locks.waitq_lock); + + return true; +} + +static int rtl_pci_tx(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + struct rtl_tx_buffer_desc *ptx_bd_desc = NULL; + u16 idx; + u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb); + unsigned long flags; + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = rtl_get_fc(skb); + u8 *pda_addr = hdr->addr1; + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 own; + u8 temp_one = 1; + + if (ieee80211_is_mgmt(fc)) + rtl_tx_mgmt_proc(hw, skb); + + if (rtlpriv->psc.sw_ps_enabled) { + if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && + !ieee80211_has_pm(fc)) + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); + } + + rtl_action_proc(hw, skb, true); + + if (is_multicast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesmulticast += skb->len; + else if (is_broadcast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesbroadcast += skb->len; + else + rtlpriv->stats.txbytesunicast += skb->len; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + ring = &rtlpci->tx_ring[hw_queue]; + if (hw_queue != BEACON_QUEUE) { + if (rtlpriv->use_new_trx_flow) + idx = ring->cur_tx_wp; + else + idx = (ring->idx + skb_queue_len(&ring->queue)) % + ring->entries; + } else { + idx = 0; + } + + pdesc = &ring->desc[idx]; + if (rtlpriv->use_new_trx_flow) { + ptx_bd_desc = &ring->buffer_desc[idx]; + } else { + own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, + true, HW_DESC_OWN); + + if (own == 1 && hw_queue != BEACON_QUEUE) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, + flags); + return skb->len; + } + } + + if (rtlpriv->cfg->ops->get_available_desc && + rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail\n"); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return skb->len; + } + + if (ieee80211_is_data(fc)) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); + + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, + (u8 *)ptx_bd_desc, info, sta, skb, hw_queue, ptcb_desc); + + __skb_queue_tail(&ring->queue, skb); + + if (rtlpriv->use_new_trx_flow) { + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, + HW_DESC_OWN, &hw_queue); + } else { + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, + HW_DESC_OWN, &temp_one); + } + + if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && + hw_queue != BEACON_QUEUE) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); + + ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); + } + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, hw_queue); + + return 0; +} + +static void rtl_pci_flush(struct ieee80211_hw *hw, u32 queues, bool drop) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 i = 0; + int queue_id; + struct rtl8192_tx_ring *ring; + + if (mac->skip_scan) + return; + + for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) { + u32 queue_len; + + if (((queues >> queue_id) & 0x1) == 0) { + queue_id--; + continue; + } + ring = &pcipriv->dev.tx_ring[queue_id]; + queue_len = skb_queue_len(&ring->queue); + if (queue_len == 0 || queue_id == BEACON_QUEUE || + queue_id == TXCMD_QUEUE) { + queue_id--; + continue; + } else { + msleep(20); + i++; + } + + /* we just wait 1s for all queues */ + if (rtlpriv->psc.rfpwr_state == ERFOFF || + is_hal_stop(rtlhal) || i >= 200) + return; + } +} + +static void rtl_pci_deinit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + _rtl_pci_deinit_trx_ring(hw); + + synchronize_irq(rtlpci->pdev->irq); + tasklet_kill(&rtlpriv->works.irq_tasklet); + tasklet_kill(&rtlpriv->works.irq_prepare_bcn_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); +} + +static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +{ + int err; + + _rtl_pci_init_struct(hw, pdev); + + err = _rtl_pci_init_trx_ring(hw); + if (err) { + pr_err("tx ring initialization failed\n"); + return err; + } + + return 0; +} + +static int rtl_pci_start(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + + int err; + + rtl_pci_reset_trx_ring(hw); + + rtlpci->driver_is_goingto_unload = false; + if (rtlpriv->cfg->ops->get_btc_status && + rtlpriv->cfg->ops->get_btc_status()) { + rtlpriv->btcoexist.btc_info.ap_num = 36; + btc_ops->btc_init_variables(rtlpriv); + btc_ops->btc_init_hal_vars(rtlpriv); + } else if (btc_ops) { + btc_ops->btc_init_variables_wifi_only(rtlpriv); + } + + err = rtlpriv->cfg->ops->hw_init(hw); + if (err) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Failed to config hardware!\n"); + kfree(rtlpriv->btcoexist.btc_context); + kfree(rtlpriv->btcoexist.wifi_only_context); + return err; + } + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + &rtlmac->retry_long); + + rtlpriv->cfg->ops->enable_interrupt(hw); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); + + rtl_init_rx_config(hw); + + /*should be after adapter start and interrupt enable. */ + set_hal_start(rtlhal); + + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + rtlpci->up_first_time = false; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); + return 0; +} + +static void rtl_pci_stop(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flags; + u8 rf_timeout = 0; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_halt_notify(rtlpriv); + + if (rtlpriv->btcoexist.btc_ops) + rtlpriv->btcoexist.btc_ops->btc_deinit_variables(rtlpriv); + + /*should be before disable interrupt&adapter + *and will do it immediately. + */ + set_hal_stop(rtlhal); + + rtlpci->driver_is_goingto_unload = true; + rtlpriv->cfg->ops->disable_interrupt(hw); + cancel_work_sync(&rtlpriv->works.lps_change_work); + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + while (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + if (rf_timeout > 100) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + break; + } + mdelay(1); + rf_timeout++; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + } + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + + rtlpriv->cfg->ops->hw_disable(hw); + /* some things are not needed if firmware not available */ + if (!rtlpriv->max_fw_size) + return; + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + + rtl_pci_enable_aspm(hw); +} + +static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct pci_dev *bridge_pdev = pdev->bus->self; + u16 venderid; + u16 deviceid; + u8 revisionid; + u16 irqline; + u8 tmp; + + pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN; + venderid = pdev->vendor; + deviceid = pdev->device; + pci_read_config_byte(pdev, 0x8, &revisionid); + pci_read_config_word(pdev, 0x3C, &irqline); + + /* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses + * r8192e_pci, and RTL8192SE, which uses this driver. If the + * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then + * the correct driver is r8192e_pci, thus this routine should + * return false. + */ + if (deviceid == RTL_PCI_8192SE_DID && + revisionid == RTL_PCI_REVISION_ID_8192PCIE) + return false; + + if (deviceid == RTL_PCI_8192_DID || + deviceid == RTL_PCI_0044_DID || + deviceid == RTL_PCI_0047_DID || + deviceid == RTL_PCI_8192SE_DID || + deviceid == RTL_PCI_8174_DID || + deviceid == RTL_PCI_8173_DID || + deviceid == RTL_PCI_8172_DID || + deviceid == RTL_PCI_8171_DID) { + switch (revisionid) { + case RTL_PCI_REVISION_ID_8192PCIE: + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; + return false; + case RTL_PCI_REVISION_ID_8192SE: + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; + break; + } + } else if (deviceid == RTL_PCI_8723AE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8723AE PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); + } else if (deviceid == RTL_PCI_8192CET_DID || + deviceid == RTL_PCI_8192CE_DID || + deviceid == RTL_PCI_8191CE_DID || + deviceid == RTL_PCI_8188CE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); + } else if (deviceid == RTL_PCI_8192DE_DID || + deviceid == RTL_PCI_8192DE_DID2) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); + } else if (deviceid == RTL_PCI_8188EE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8188EE\n"); + } else if (deviceid == RTL_PCI_8723BE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8723BE\n"); + } else if (deviceid == RTL_PCI_8192EE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8192EE\n"); + } else if (deviceid == RTL_PCI_8821AE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8821AE\n"); + } else if (deviceid == RTL_PCI_8812AE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8812AE\n"); + } else if (deviceid == RTL_PCI_8822BE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8822BE; + rtlhal->bandset = BAND_ON_BOTH; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8822BE\n"); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); + + rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { + if (revisionid == 0 || revisionid == 1) { + if (revisionid == 0) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); + rtlhal->interfaceindex = 0; + } else if (revisionid == 1) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC1\n"); + rtlhal->interfaceindex = 1; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + venderid, deviceid, revisionid); + rtlhal->interfaceindex = 0; + } + } + + switch (rtlhal->hw_type) { + case HARDWARE_TYPE_RTL8192EE: + case HARDWARE_TYPE_RTL8822BE: + /* use new trx flow */ + rtlpriv->use_new_trx_flow = true; + break; + + default: + rtlpriv->use_new_trx_flow = false; + break; + } + + /*find bus info */ + pcipriv->ndis_adapter.busnumber = pdev->bus->number; + pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); + pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); + + /*find bridge info */ + pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN; + /* some ARM have no bridge_pdev and will crash here + * so we should check if bridge_pdev is NULL + */ + if (bridge_pdev) { + /*find bridge info if available */ + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { + pcipriv->ndis_adapter.pcibridge_vendor = tmp; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Pci Bridge Vendor is found index: %d\n", + tmp); + break; + } + } + } + + if (pcipriv->ndis_adapter.pcibridge_vendor != + PCI_BRIDGE_VENDOR_UNKNOWN) { + pcipriv->ndis_adapter.pcibridge_busnum = + bridge_pdev->bus->number; + pcipriv->ndis_adapter.pcibridge_devnum = + PCI_SLOT(bridge_pdev->devfn); + pcipriv->ndis_adapter.pcibridge_funcnum = + PCI_FUNC(bridge_pdev->devfn); + + if (pcipriv->ndis_adapter.pcibridge_vendor == + PCI_BRIDGE_VENDOR_AMD) { + pcipriv->ndis_adapter.amd_l1_patch = + rtl_pci_get_amd_l1_patch(hw); + } + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.amd_l1_patch); + + rtl_pci_parse_configuration(pdev, hw); + + return true; +} + +static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + int ret; + + ret = pci_enable_msi(rtlpci->pdev); + if (ret < 0) + return ret; + + ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, + IRQF_SHARED, KBUILD_MODNAME, hw); + if (ret < 0) { + pci_disable_msi(rtlpci->pdev); + return ret; + } + + rtlpci->using_msi = true; + + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "MSI Interrupt Mode!\n"); + return 0; +} + +static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + int ret; + + ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, + IRQF_SHARED, KBUILD_MODNAME, hw); + if (ret < 0) + return ret; + + rtlpci->using_msi = false; + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "Pin-based Interrupt Mode!\n"); + return 0; +} + +static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + int ret; + + if (rtlpci->msi_support) { + ret = rtl_pci_intr_mode_msi(hw); + if (ret < 0) + ret = rtl_pci_intr_mode_legacy(hw); + } else { + ret = rtl_pci_intr_mode_legacy(hw); + } + return ret; +} + +static void platform_enable_dma64(struct pci_dev *pdev, bool dma64) +{ + u8 value; + + pci_read_config_byte(pdev, 0x719, &value); + + /* 0x719 Bit5 is DMA64 bit fetch. */ + if (dma64) + value |= BIT(5); + else + value &= ~BIT(5); + + pci_write_config_byte(pdev, 0x719, value); +} + +int rtl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct ieee80211_hw *hw = NULL; + + struct rtl_priv *rtlpriv = NULL; + struct rtl_pci_priv *pcipriv = NULL; + struct rtl_pci *rtlpci; + unsigned long pmem_start, pmem_len, pmem_flags; + int err; + + err = pci_enable_device(pdev); + if (err) { + WARN_ONCE(true, "%s : Cannot enable new PCI device\n", + pci_name(pdev)); + return err; + } + + if (((struct rtl_hal_cfg *)id->driver_data)->mod_params->dma64 && + !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { + if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { + WARN_ONCE(true, + "Unable to obtain 64bit DMA for consistent allocations\n"); + err = -ENOMEM; + goto fail1; + } + + platform_enable_dma64(pdev, true); + } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { + if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) { + WARN_ONCE(true, + "rtlwifi: Unable to obtain 32bit DMA for consistent allocations\n"); + err = -ENOMEM; + goto fail1; + } + + platform_enable_dma64(pdev, false); + } + + pci_set_master(pdev); + + hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) + + sizeof(struct rtl_priv), &rtl_ops); + if (!hw) { + WARN_ONCE(true, + "%s : ieee80211 alloc failed\n", pci_name(pdev)); + err = -ENOMEM; + goto fail1; + } + + SET_IEEE80211_DEV(hw, &pdev->dev); + pci_set_drvdata(pdev, hw); + + rtlpriv = hw->priv; + rtlpriv->hw = hw; + pcipriv = (void *)rtlpriv->priv; + pcipriv->dev.pdev = pdev; + init_completion(&rtlpriv->firmware_loading_complete); + /*proximity init here*/ + rtlpriv->proximity.proxim_on = false; + + pcipriv = (void *)rtlpriv->priv; + pcipriv->dev.pdev = pdev; + + /* init cfg & intf_ops */ + rtlpriv->rtlhal.interface = INTF_PCI; + rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); + rtlpriv->intf_ops = &rtl_pci_ops; + rtl_efuse_ops_init(hw); + + /* MEM map */ + err = pci_request_regions(pdev, KBUILD_MODNAME); + if (err) { + WARN_ONCE(true, "rtlwifi: Can't obtain PCI resources\n"); + goto fail1; + } + + pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); + pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id); + pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id); + + /*shared mem start */ + rtlpriv->io.pci_mem_start = + (unsigned long)pci_iomap(pdev, + rtlpriv->cfg->bar_id, pmem_len); + if (rtlpriv->io.pci_mem_start == 0) { + WARN_ONCE(true, "rtlwifi: Can't map PCI mem\n"); + err = -ENOMEM; + goto fail2; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); + + /* Disable Clk Request */ + pci_write_config_byte(pdev, 0x81, 0); + /* leave D3 mode */ + pci_write_config_byte(pdev, 0x44, 0); + pci_write_config_byte(pdev, 0x04, 0x06); + pci_write_config_byte(pdev, 0x04, 0x07); + + /* find adapter */ + if (!_rtl_pci_find_adapter(pdev, hw)) { + err = -ENODEV; + goto fail2; + } + + /* Init IO handler */ + _rtl_pci_io_handler_init(&pdev->dev, hw); + + /*like read eeprom and so on */ + rtlpriv->cfg->ops->read_eeprom_info(hw); + + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + pr_err("Can't init_sw_vars\n"); + err = -ENODEV; + goto fail2; + } + rtl_init_sw_leds(hw); + + /*aspm */ + rtl_pci_init_aspm(hw); + + /* Init mac80211 sw */ + err = rtl_init_core(hw); + if (err) { + pr_err("Can't allocate sw for mac80211\n"); + goto fail3; + } + + /* Init PCI sw */ + err = rtl_pci_init(hw, pdev); + if (err) { + pr_err("Failed to init PCI\n"); + goto fail4; + } + + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); + err = -ENODEV; + goto fail5; + } + rtlpriv->mac80211.mac80211_registered = 1; + + /* add for debug */ + rtl_debug_add_one(hw); + + /*init rfkill */ + rtl_init_rfkill(hw); /* Init PCI sw */ + + rtlpci = rtl_pcidev(pcipriv); + err = rtl_pci_intr_mode_decide(hw); + if (err) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); + goto fail6; + } + rtlpci->irq_alloc = 1; + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + +fail6: + rtl_deinit_rfkill(hw); + rtl_debug_remove_one(hw); + ieee80211_unregister_hw(hw); +fail5: + rtl_pci_deinit(hw); +fail4: + rtl_deinit_core(hw); +fail3: + wait_for_completion(&rtlpriv->firmware_loading_complete); + rtlpriv->cfg->ops->deinit_sw_vars(hw); + +fail2: + if (rtlpriv->io.pci_mem_start != 0) + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + + pci_release_regions(pdev); + +fail1: + if (hw) + ieee80211_free_hw(hw); + pci_disable_device(pdev); + + return err; +} +EXPORT_SYMBOL(rtl_pci_probe); + +void rtl_pci_disconnect(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); + clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /* remove form debug */ + rtl_debug_remove_one(hw); + + /*ieee80211_unregister_hw will call ops_stop */ + if (rtlmac->mac80211_registered == 1) { + ieee80211_unregister_hw(hw); + rtlmac->mac80211_registered = 0; + } else { + rtl_deinit_deferred_work(hw, false); + rtlpriv->intf_ops->adapter_stop(hw); + } + rtlpriv->cfg->ops->disable_interrupt(hw); + + /*deinit rfkill */ + rtl_deinit_rfkill(hw); + + rtl_pci_deinit(hw); + rtl_deinit_core(hw); + rtlpriv->cfg->ops->deinit_sw_vars(hw); + + if (rtlpci->irq_alloc) { + free_irq(rtlpci->pdev->irq, hw); + rtlpci->irq_alloc = 0; + } + + if (rtlpci->using_msi) + pci_disable_msi(rtlpci->pdev); + + if (rtlpriv->io.pci_mem_start != 0) { + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + pci_release_regions(pdev); + } + + pci_disable_device(pdev); + + rtl_pci_disable_aspm(hw); + + pci_set_drvdata(pdev, NULL); + + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtl_pci_disconnect); + +#ifdef CONFIG_PM_SLEEP +/*************************************** + * kernel pci power state define: + * PCI_D0 ((pci_power_t __force) 0) + * PCI_D1 ((pci_power_t __force) 1) + * PCI_D2 ((pci_power_t __force) 2) + * PCI_D3hot ((pci_power_t __force) 3) + * PCI_D3cold ((pci_power_t __force) 4) + * PCI_UNKNOWN ((pci_power_t __force) 5) + + * This function is called when system + * goes into suspend state mac80211 will + * call rtl_mac_stop() from the mac80211 + * suspend function first, So there is + * no need to call hw_disable here. + ****************************************/ +int rtl_pci_suspend(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->cfg->ops->hw_suspend(hw); + rtl_deinit_rfkill(hw); + + return 0; +} +EXPORT_SYMBOL(rtl_pci_suspend); + +int rtl_pci_resume(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->cfg->ops->hw_resume(hw); + rtl_init_rfkill(hw); + return 0; +} +EXPORT_SYMBOL(rtl_pci_resume); +#endif /* CONFIG_PM_SLEEP */ + +const struct rtl_intf_ops rtl_pci_ops = { + .adapter_start = rtl_pci_start, + .adapter_stop = rtl_pci_stop, + .adapter_tx = rtl_pci_tx, + .flush = rtl_pci_flush, + .reset_trx_ring = rtl_pci_reset_trx_ring, + .waitq_insert = rtl_pci_tx_chk_waitq_insert, + + .disable_aspm = rtl_pci_disable_aspm, + .enable_aspm = rtl_pci_enable_aspm, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h new file mode 100644 index 000000000..e8fa022df --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/pci.h @@ -0,0 +1,282 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_PCI_H__ +#define __RTL_PCI_H__ + +#include +/* 1: MSDU packet queue, + * 2: Rx Command Queue + */ +#define RTL_PCI_RX_MPDU_QUEUE 0 +#define RTL_PCI_RX_CMD_QUEUE 1 +#define RTL_PCI_MAX_RX_QUEUE 2 + +#define RTL_PCI_MAX_RX_COUNT 512/*64*/ +#define RTL_PCI_MAX_TX_QUEUE_COUNT 9 + +#define RT_TXDESC_NUM 128 +#define TX_DESC_NUM_92E 512 +#define TX_DESC_NUM_8822B 512 +#define RT_TXDESC_NUM_BE_QUEUE 256 + +#define BK_QUEUE 0 +#define BE_QUEUE 1 +#define VI_QUEUE 2 +#define VO_QUEUE 3 +#define BEACON_QUEUE 4 +#define TXCMD_QUEUE 5 +#define MGNT_QUEUE 6 +#define HIGH_QUEUE 7 +#define HCCA_QUEUE 8 +#define H2C_QUEUE TXCMD_QUEUE /* In 8822B */ + +#define RTL_PCI_DEVICE(vend, dev, cfg) \ + .vendor = (vend), \ + .device = (dev), \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID,\ + .driver_data = (kernel_ulong_t)&(cfg) + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */ +#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */ +#define RTL_PCI_8174_DID 0x8174 /*8192 SE */ +#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ +#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ +#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ +#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */ +#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ +#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ +#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ +#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */ +#define RTL_PCI_700F_DID 0x700F +#define RTL_PCI_701F_DID 0x701F +#define RTL_PCI_DLINK_DID 0x3304 +#define RTL_PCI_8723AE_DID 0x8723 /*8723e */ +#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */ +#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */ +#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */ +#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */ +#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */ +#define RTL_PCI_8192DE_DID 0x8193 /*8192de */ +#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/ +#define RTL_PCI_8188EE_DID 0x8179 /*8188ee*/ +#define RTL_PCI_8723BE_DID 0xB723 /*8723be*/ +#define RTL_PCI_8192EE_DID 0x818B /*8192ee*/ +#define RTL_PCI_8821AE_DID 0x8821 /*8821ae*/ +#define RTL_PCI_8812AE_DID 0x8812 /*8812ae*/ +#define RTL_PCI_8822BE_DID 0xB822 /*8822be*/ + +/*8192 support 16 pages of IO registers*/ +#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 +#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000 +#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000 + +#define RTL_PCI_REVISION_ID_8190PCI 0x00 +#define RTL_PCI_REVISION_ID_8192PCIE 0x01 +#define RTL_PCI_REVISION_ID_8192SE 0x10 +#define RTL_PCI_REVISION_ID_8192CE 0x1 +#define RTL_PCI_REVISION_ID_8192DE 0x0 + +#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */ + PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/ + PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/ + PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/ + PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/ + PCI_BRIDGE_VENDOR_MAX, +}; + +/* In new TRX flow, Buffer_desc is new concept + * But TX wifi info == TX descriptor in old flow + * RX wifi info == RX descriptor in old flow + */ +struct rtl_tx_buffer_desc { + u32 dword[4 * (1 << (BUFDESC_SEG_NUM + 1))]; +} __packed; + +struct rtl_tx_desc { + u32 dword[16]; +} __packed; + +struct rtl_rx_buffer_desc { /*rx buffer desc*/ + u32 dword[4]; +} __packed; + +struct rtl_rx_desc { /*old: rx desc new: rx wifi info*/ + u32 dword[8]; +} __packed; + +struct rtl_tx_cmd_desc { + u32 dword[16]; +} __packed; + +struct rtl8192_tx_ring { + struct rtl_tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; + /*add for new trx flow*/ + struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/ + dma_addr_t buffer_desc_dma; /*tx bufferd desc dma memory*/ + u16 cur_tx_wp; /* current_tx_write_point */ + u16 cur_tx_rp; /* current_tx_read_point */ +}; + +struct rtl8192_rx_ring { + struct rtl_rx_desc *desc; + dma_addr_t dma; + unsigned int idx; + struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT]; + /*add for new trx flow*/ + struct rtl_rx_buffer_desc *buffer_desc; /*rx buffer descriptor*/ + u16 next_rx_rp; /* next_rx_read_point */ +}; + +struct rtl_pci { + struct pci_dev *pdev; + bool irq_enabled; + + bool driver_is_goingto_unload; + bool up_first_time; + bool first_init; + bool being_init_adapter; + bool init_ready; + + /*Tx */ + struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT]; + int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT]; + u32 transmit_config; + + /*Rx */ + struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE]; + int rxringcount; + u16 rxbuffersize; + u32 receive_config; + + /*irq */ + u8 irq_alloc; + u32 irq_mask[4]; /* 0-1: normal, 2: unused, 3: h2c */ + u32 sys_irq_mask; + + /*Bcn control register setting */ + u32 reg_bcn_ctrl_val; + + /*ASPM*/ u8 const_pci_aspm; + u8 const_hwsw_rfoff_d3; + u8 const_support_pciaspm; + /*pci-e bridge */ + u8 const_hostpci_aspm_setting; + /*pci-e device */ + u8 const_devicepci_aspm_setting; + /* If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + */ + bool support_aspm; + bool support_backdoor; + + /*QOS & EDCA */ + enum acm_method acm_method; + + u16 shortretry_limit; + u16 longretry_limit; + + /* MSI support */ + bool msi_support; + bool using_msi; + /* interrupt clear before set */ + bool int_clear; +}; + +struct mp_adapter { + u8 linkctrl_reg; + + u8 busnumber; + u8 devnumber; + u8 funcnumber; + + u8 pcibridge_busnum; + u8 pcibridge_devnum; + u8 pcibridge_funcnum; + + u8 pcibridge_vendor; + + bool amd_l1_patch; +}; + +struct rtl_pci_priv { + struct bt_coexist_info bt_coexist; + struct rtl_led_ctl ledctl; + struct rtl_pci dev; + struct mp_adapter ndis_adapter; +}; + +#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv)) +#define rtl_pcidev(pcipriv) (&((pcipriv)->dev)) + +int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw); + +extern const struct rtl_intf_ops rtl_pci_ops; + +int rtl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +void rtl_pci_disconnect(struct pci_dev *pdev); +#ifdef CONFIG_PM_SLEEP +int rtl_pci_suspend(struct device *dev); +int rtl_pci_resume(struct device *dev); +#endif /* CONFIG_PM_SLEEP */ +static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return readb((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return readw((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return readl((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) +{ + writeb(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write16_async(struct rtl_priv *rtlpriv, + u32 addr, u16 val) +{ + writew(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline void pci_write32_async(struct rtl_priv *rtlpriv, + u32 addr, u32 val) +{ + writel(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); +} + +static inline u16 calc_fifo_space(u16 rp, u16 wp, u16 size) +{ + if (rp <= wp) + return size - 1 + rp - wp; + return rp - wp - 1; +} + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c new file mode 100644 index 000000000..bcab12c3b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -0,0 +1,983 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "base.h" +#include "ps.h" +#include +#include "btcoexist/rtl_btc.h" + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + /*<1> reset trx ring */ + if (rtlhal->interface == INTF_PCI) + rtlpriv->intf_ops->reset_trx_ring(hw); + + if (is_hal_stop(rtlhal)) + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Driver is already down!\n"); + + /*<2> Enable Adapter */ + if (rtlpriv->cfg->ops->hw_init(hw)) + return false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + &rtlmac->retry_long); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + rtlpriv->cfg->ops->switch_channel(hw); + rtlpriv->cfg->ops->set_channel_access(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, + cfg80211_get_chandef_type(&hw->conf.chandef)); + + /*<3> Enable Interrupt */ + rtlpriv->cfg->ops->enable_interrupt(hw); + + /* */ + rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer); + + return true; +} +EXPORT_SYMBOL(rtl_ps_enable_nic); + +bool rtl_ps_disable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /*<1> Stop all timer */ + rtl_deinit_deferred_work(hw, true); + + /*<2> Disable Interrupt */ + rtlpriv->cfg->ops->disable_interrupt(hw); + tasklet_kill(&rtlpriv->works.irq_tasklet); + + /*<3> Disable Adapter */ + rtlpriv->cfg->ops->hw_disable(hw); + + return true; +} +EXPORT_SYMBOL(rtl_ps_disable_nic); + +static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, + enum rf_pwrstate state_toset, + u32 changesource) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool actionallowed = false; + u16 rfwait_cnt = 0; + + /*Only one thread can change + *the RF state at one time, and others + *should wait to be executed. + */ + while (true) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "RF Change in progress! Wait to set..state_toset(%d).\n", + state_toset); + + /* Set RF after the previous action is done. */ + while (ppsc->rfchange_inprogress) { + rfwait_cnt++; + mdelay(1); + /*Wait too long, return false to avoid + *to be stuck here. + */ + if (rfwait_cnt > 100) + return false; + } + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + break; + } + } + + switch (state_toset) { + case ERFON: + ppsc->rfoff_reason &= (~changesource); + + if ((changesource == RF_CHANGE_BY_HW) && + (ppsc->hwradiooff)) { + ppsc->hwradiooff = false; + } + + if (!ppsc->rfoff_reason) { + ppsc->rfoff_reason = 0; + actionallowed = true; + } + + break; + + case ERFOFF: + + if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) { + ppsc->hwradiooff = true; + } + + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + + case ERFSLEEP: + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + + default: + pr_err("switch case %#x not processed\n", state_toset); + break; + } + + if (actionallowed) + rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + return actionallowed; +} + +static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + ppsc->swrf_processing = true; + + if (ppsc->inactive_pwrstate == ERFON && + rtlhal->interface == INTF_PCI) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, + RF_CHANGE_BY_IPS); + + if (ppsc->inactive_pwrstate == ERFOFF && + rtlhal->interface == INTF_PCI) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + ppsc->swrf_processing = false; +} + +void rtl_ips_nic_off_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + ips_nic_off_wq.work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + if (mac->opmode != NL80211_IFTYPE_STATION) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not station return\n"); + return; + } + + if (mac->p2p_in_use) + return; + + if (mac->link_state > MAC80211_NOLINK) + return; + + if (is_hal_stop(rtlhal)) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->cfg->ops->bt_coex_off_before_lps) + rtlpriv->cfg->ops->bt_coex_off_before_lps(hw); + + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + /* + *Do not enter IPS in the following conditions: + *(1) RF is already OFF or Sleep + *(2) swrf_processing (indicates the IPS is still under going) + *(3) Connectted (only disconnected can trigger IPS) + *(4) IBSS (send Beacon) + *(5) AP mode (send Beacon) + *(6) monitor mode (rcv packet) + */ + + if (rtstate == ERFON && + !ppsc->swrf_processing && + (mac->link_state == MAC80211_NOLINK) && + !mac->act_scanning) { + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "IPSEnter(): Turn off RF\n"); + + ppsc->inactive_pwrstate = ERFOFF; + ppsc->in_powersavemode = true; + + /* call before RF off */ + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + + /*rtl_pci_reset_trx_ring(hw); */ + _rtl_ps_inactive_ps(hw); + } + } +} + +void rtl_ips_nic_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* because when link with ap, mac80211 will ask us + * to disable nic quickly after scan before linking, + * this will cause link failed, so we delay 100ms here + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ips_nic_off_wq, MSECS(100)); +} + +/* NOTICE: any opmode should exc nic_on, or disable without + * nic_on may something wrong, like adhoc TP + */ +void rtl_ips_nic_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + cancel_delayed_work_sync(&rtlpriv->works.ips_nic_off_wq); + + mutex_lock(&rtlpriv->locks.ips_mutex); + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + if (rtstate != ERFON && + !ppsc->swrf_processing && + ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { + + ppsc->inactive_pwrstate = ERFON; + ppsc->in_powersavemode = false; + _rtl_ps_inactive_ps(hw); + /* call after RF on */ + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + } + } + mutex_unlock(&rtlpriv->locks.ips_mutex); +} +EXPORT_SYMBOL_GPL(rtl_ips_nic_on); + +/*for FW LPS*/ + +/* + *Determine if we can set Fw into PS mode + *in current condition.Return TRUE if it + *can enter PS mode. + */ +static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u32 ps_timediff; + + ps_timediff = jiffies_to_msecs(jiffies - + ppsc->last_delaylps_stamp_jiffies); + + if (ps_timediff < 2000) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); + return false; + } + + if (mac->link_state != MAC80211_LINKED) + return false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return false; + + return true; +} + +/* Change current and default preamble mode.*/ +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool enter_fwlps; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE) + return; + + /* Update power save mode configured. */ + ppsc->dot11_psmode = rt_psmode; + + /* + * + *1. Enter PS mode + * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode + * cmd to set Fw into PS mode. + *2. Leave PS mode + * Send H2C fw_pwrmode cmd to Fw to set Fw into Active + * mode and set RPWM to turn RF on. + */ + + if ((ppsc->fwctrl_lps) && ppsc->report_linked) { + if (ppsc->dot11_psmode == EACTIVE) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); + enter_fwlps = false; + ppsc->pwr_mode = FW_PS_ACTIVE_MODE; + ppsc->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + if (ppsc->p2p_ps_info.opp_ps) + rtl_p2p_ps_cmd(hw , P2P_PS_ENABLE); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + } else { + if (rtl_get_fwlps_doze(hw)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + enter_fwlps = true; + ppsc->pwr_mode = ppsc->fwctrl_psmode; + ppsc->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + + } else { + /* Reset the power save related parameters. */ + ppsc->dot11_psmode = EACTIVE; + } + } + } +} + +/* Interrupt safe routine to enter the leisure power save mode.*/ +static void rtl_lps_enter_core(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!ppsc->fwctrl_lps) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if (mac->cnt_after_linked < 5) + return; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + mutex_lock(&rtlpriv->locks.lps_mutex); + + /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because + * bt_ccoexist may ask to enter lps. + * In normal case, this constraint move to rtl_lps_set_psmode(). + */ + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Enter 802.11 power save mode...\n"); + rtl_lps_set_psmode(hw, EAUTOPS); + + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* Interrupt safe routine to leave the leisure power save mode.*/ +static void rtl_lps_leave_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + mutex_lock(&rtlpriv->locks.lps_mutex); + + if (ppsc->fwctrl_lps) { + if (ppsc->dot11_psmode != EACTIVE) { + + /*FIX ME */ + /*rtlpriv->cfg->ops->enable_interrupt(hw); */ + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Busy Traffic,Leave 802.11 power save..\n"); + + rtl_lps_set_psmode(hw, EACTIVE); + } + } + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* For sw LPS*/ +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + struct ieee80211_tim_ie *tim_ie; + u8 *tim; + u8 tim_len; + bool u_buffed; + bool m_buffed; + + if (mac->opmode != NL80211_IFTYPE_STATION) + return; + + if (!rtlpriv->psc.swctrl_lps) + return; + + if (rtlpriv->mac80211.link_state != MAC80211_LINKED) + return; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if (rtlpriv->psc.fwctrl_lps) + return; + + if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + rtlpriv->psc.last_beacon = jiffies; + + tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); + if (!tim) + return; + + if (tim[1] < sizeof(*tim_ie)) + return; + + tim_len = tim[1]; + tim_ie = (struct ieee80211_tim_ie *) &tim[2]; + + if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) + rtlpriv->psc.dtim_counter = tim_ie->dtim_count; + + /* Check whenever the PHY can be turned off again. */ + + /* 1. What about buffered unicast traffic for our AID? */ + u_buffed = ieee80211_check_tim(tim_ie, tim_len, + rtlpriv->mac80211.assoc_id, false); + + /* 2. Maybe the AP wants to send multicast/broadcast data? */ + m_buffed = tim_ie->bitmap_ctrl & 0x01; + rtlpriv->psc.multi_buffered = m_buffed; + + /* unicast will process by mac80211 through + * set ~IEEE80211_CONF_PS, So we just check + * multicast frames here */ + if (!m_buffed) { + /* back to low-power land. and delay is + * prevent null power save frame tx fail */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ps_work, MSECS(5)); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); + } +} +EXPORT_SYMBOL_GPL(rtl_swlps_beacon); + +void rtl_swlps_rf_awake(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (!rtlpriv->psc.swctrl_lps) + return; + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +void rtl_swlps_rfon_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + ps_rfon_wq.work); + struct ieee80211_hw *hw = rtlworks->hw; + + rtl_swlps_rf_awake(hw); +} + +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 sleep_intv; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if ((rtlpriv->sec.being_setkey) || + (mac->opmode == NL80211_IFTYPE_ADHOC)) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (rtlpriv->psc.rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return; + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + /* here is power save alg, when this beacon is DTIM + * we will set sleep time to dtim_period * n; + * when this beacon is not DTIM, we will set sleep + * time to sleep_intv = rtlpriv->psc.dtim_counter or + * MAX_SW_LPS_SLEEP_INTV(default set to 5) */ + + if (rtlpriv->psc.dtim_counter == 0) { + if (hw->conf.ps_dtim_period == 1) + sleep_intv = hw->conf.ps_dtim_period * 2; + else + sleep_intv = hw->conf.ps_dtim_period; + } else { + sleep_intv = rtlpriv->psc.dtim_counter; + } + + if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) + sleep_intv = MAX_SW_LPS_SLEEP_INTV; + + /* this print should always be dtim_conter = 0 & + * sleep = dtim_period, that meaons, we should + * awake before every dtim */ + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); + + /* we tested that 40ms is enough for sw & hw sw delay */ + queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, + MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); +} + +void rtl_lps_change_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, lps_change_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->enter_ps) + rtl_lps_enter_core(hw); + else + rtl_lps_leave_core(hw); +} +EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback); + +void rtl_lps_enter(struct ieee80211_hw *hw, bool may_block) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (may_block) + return rtl_lps_enter_core(hw); + rtlpriv->enter_ps = true; + schedule_work(&rtlpriv->works.lps_change_work); +} +EXPORT_SYMBOL_GPL(rtl_lps_enter); + +void rtl_lps_leave(struct ieee80211_hw *hw, bool may_block) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (may_block) + return rtl_lps_leave_core(hw); + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); +} +EXPORT_SYMBOL_GPL(rtl_lps_leave); + +void rtl_swlps_wq_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = container_of(work, struct rtl_works, + ps_work.work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* we can sleep after ps null send ok */ + if (rtlpriv->psc.state_inap) + rtl_swlps_rf_sleep(hw); +} + +static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + u8 noa_num, index , i, noa_index = 0; + bool find_p2p_ie = false , find_p2p_ps_ie = false; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + ie = NULL; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + return; + + if (pos[0] == 221 && pos[1] > 4) { + if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) { + ie = pos + 2+4; + break; + } + } + pos += 2 + pos[1]; + } + + if (ie == NULL) + return; + find_p2p_ie = true; + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = le16_to_cpu(*((__le16 *)&ie[1])); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + find_p2p_ps_ie = true; + if ((noa_len - 2) % 13 != 0) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } else { + noa_num = (noa_len - 2) / 13; + if (noa_num > P2P_MAX_NOA_NUM) + noa_num = P2P_MAX_NOA_NUM; + + } + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "update NOA ie.\n"); + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + *(u8 *)(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + p2pinfo->noa_interval[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + p2pinfo->noa_start_time[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } + + if (find_p2p_ie) { + if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) && + (!find_p2p_ps_ie)) + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } +} + +static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); + u8 noa_num, index , i , noa_index = 0; + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + + pos = (u8 *)&mgmt->u.action.category; + end = data + len; + ie = NULL; + + if (pos[0] == 0x7f) { + if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0) + ie = pos + 3+4; + } + + if (ie == NULL) + return; + + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = le16_to_cpu(*(__le16 *)&ie[1]); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", + ie, noa_len); + if ((noa_len - 2) % 13 != 0) { + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } else { + noa_num = (noa_len - 2) / 13; + if (noa_num > P2P_MAX_NOA_NUM) + noa_num = P2P_MAX_NOA_NUM; + + } + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + *(u8 *)(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + p2pinfo->noa_interval[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + p2pinfo->noa_start_time[i] = + le32_to_cpu(*(__le32 *)(ie + index)); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } +} + +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); + + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state); + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + p2pinfo->noa_index = 0; + p2pinfo->ctwindow = 0; + p2pinfo->opp_ps = 0; + p2pinfo->noa_num = 0; + p2pinfo->p2p_ps_mode = P2P_PS_NONE; + if (rtlps->fw_current_inpsmode) { + if (rtlps->smart_ps == 0) { + rtlps->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + + } + break; + case P2P_PS_ENABLE: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + + if (p2pinfo->ctwindow > 0) { + if (rtlps->smart_ps != 0) { + rtlps->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + } + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + + } + break; + case P2P_PS_SCAN: + case P2P_PS_SCAN_DONE: + case P2P_PS_ALLSTASLEEP: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + } + break; + default: + break; + } + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "ctwindow %x oppps %x\n", + p2pinfo->ctwindow, p2pinfo->opp_ps); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "count %x duration %x index %x interval %x start time %x noa num %x\n", + p2pinfo->noa_count_type[0], + p2pinfo->noa_duration[0], + p2pinfo->noa_index, + p2pinfo->noa_interval[0], + p2pinfo->noa_start_time[0], + p2pinfo->noa_num); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); +} + +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + + if (!mac->p2p) + return; + if (mac->link_state != MAC80211_LINKED) + return; + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + /* check if this really is a beacon */ + if (!(ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_action(hdr->frame_control))) + return; + + if (ieee80211_is_action(hdr->frame_control)) + rtl_p2p_action_ie(hw , data , len - FCS_LEN); + else + rtl_p2p_noa_ie(hw , data , len - FCS_LEN); +} +EXPORT_SYMBOL_GPL(rtl_p2p_info); diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.h b/drivers/net/wireless/realtek/rtlwifi/ps.h new file mode 100644 index 000000000..b37a929de --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/ps.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_RTL_PCI_PS_H__ +#define __REALTEK_RTL_PCI_PS_H__ + +#define MAX_SW_LPS_SLEEP_INTV 5 + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw); +bool rtl_ps_disable_nic(struct ieee80211_hw *hw); +void rtl_ips_nic_off(struct ieee80211_hw *hw); +void rtl_ips_nic_on(struct ieee80211_hw *hw); +void rtl_ips_nic_off_wq_callback(struct work_struct *work); +void rtl_lps_enter(struct ieee80211_hw *hw, bool may_block); +void rtl_lps_leave(struct ieee80211_hw *hw, bool may_block); + +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode); + +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_swlps_wq_callback(struct work_struct *work); +void rtl_swlps_rfon_wq_callback(struct work_struct *work); +void rtl_swlps_rf_awake(struct ieee80211_hw *hw); +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state); +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_lps_change_work_callback(struct work_struct *work); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h b/drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h new file mode 100644 index 000000000..db1765c6f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_PWRSEQCMD_H__ +#define __RTL8723E_PWRSEQCMD_H__ + +#include "wifi.h" +/*--------------------------------------------- + * 3 The value of cmd: 4 bits + *--------------------------------------------- + */ +#define PWR_CMD_READ 0x00 +#define PWR_CMD_WRITE 0x01 +#define PWR_CMD_POLLING 0x02 +#define PWR_CMD_DELAY 0x03 +#define PWR_CMD_END 0x04 + +/* define the base address of each block */ +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + +enum pwrseq_delay_unit { + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +}; + +struct wlan_pwr_cfg { + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +}; + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) +#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) +#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) +#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) +#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) + +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, + u8 fab_version, u8 interface_type, + struct wlan_pwr_cfg pwrcfgcmd[]); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c new file mode 100644 index 000000000..dcfaa9819 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rc.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "base.h" +#include "rc.h" + +/* + *Finds the highest rate index we can use + *if skb is special data like DHCP/EAPOL, we set should + *it to lowest rate CCK_1M, otherwise we set rate to + *highest rate based on wireless mode used for iwconfig + *show Tx rate. + */ +static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct sk_buff *skb, bool not_data) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 nss; + struct ieee80211_tx_rate rate; + + switch (get_rf_type(rtlphy)) { + case RF_4T4R: + nss = 4; + break; + case RF_3T3R: + nss = 3; + break; + case RF_2T2R: + nss = 2; + break; + default: + nss = 1; + break; + } + + /* + *this rate is no use for true rate, firmware + *will control rate at all it just used for + *1.show in iwconfig in B/G mode + *2.in rtl_get_tcb_desc when we check rate is + * 1M we will not use FW rate but user rate. + */ + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + + if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) || + not_data) { + return 0; + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (wireless_mode == WIRELESS_MODE_B) { + return B_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_G) { + return G_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_24G) { + if (nss == 1) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_24G) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) { + ieee80211_rate_set_vht(&rate, + AC_MODE_MCS8_RIX, + nss); + goto out; + } else { + ieee80211_rate_set_vht(&rate, + AC_MODE_MCS9_RIX, + nss); + goto out; + } + } + return 0; + } else { + if (wireless_mode == WIRELESS_MODE_A) { + return A_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_5G) { + if (nss == 1) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_5G) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) { + ieee80211_rate_set_vht(&rate, + AC_MODE_MCS8_RIX, + nss); + goto out; + } else { + ieee80211_rate_set_vht(&rate, + AC_MODE_MCS9_RIX, + nss); + goto out; + } + } + return 0; + } + } + +out: + return rate.idx; +} + +static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct ieee80211_tx_rate *rate, + struct ieee80211_tx_rate_control *txrc, + u8 tries, s8 rix, int rtsctsenable, + bool not_data) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; + + if (sta) { + sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + rate->count = tries; + rate->idx = rix >= 0x00 ? rix : 0x00; + + if (!not_data) { + if (txrc->short_preamble) + rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta && (sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (sta && sta->deflink.vht_cap.vht_supported) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + } else { + if (mac->bw_80) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + else if (mac->bw_40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + } + + if (sgi_20 || sgi_40 || sgi_80) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + if (sta && sta->deflink.ht_cap.ht_supported && + (wireless_mode == WIRELESS_MODE_N_5G || + wireless_mode == WIRELESS_MODE_N_24G)) + rate->flags |= IEEE80211_TX_RC_MCS; + if (sta && sta->deflink.vht_cap.vht_supported && + (wireless_mode == WIRELESS_MODE_AC_5G || + wireless_mode == WIRELESS_MODE_AC_24G || + wireless_mode == WIRELESS_MODE_AC_ONLY)) + rate->flags |= IEEE80211_TX_RC_VHT_MCS; + } +} + +static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, + void *priv_sta, + struct ieee80211_tx_rate_control *txrc) +{ + struct rtl_priv *rtlpriv = ppriv; + struct sk_buff *skb = txrc->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rates = tx_info->control.rates; + __le16 fc = rtl_get_fc(skb); + u8 try_per_rate, i, rix; + bool not_data = !ieee80211_is_data(fc); + + rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data); + try_per_rate = 1; + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc, + try_per_rate, rix, 1, not_data); + + if (!not_data) { + for (i = 1; i < 4; i++) + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i], + txrc, i, (rix - i), 1, + not_data); + } +} + +static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, + struct rtl_sta_info *sta_entry, u16 tid) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->act_scanning) + return false; + + if (mac->opmode == NL80211_IFTYPE_STATION && + mac->cnt_after_linked < 3) + return false; + + if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) + return true; + + return false; +} + +/*mac80211 Rate Control callbacks*/ +static void rtl_tx_status(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = rtl_get_fc(skb); + struct rtl_sta_info *sta_entry; + + if (!priv_sta || !ieee80211_is_data(fc)) + return; + + if (rtl_is_special_data(mac->hw, skb, true, true)) + return; + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + return; + + if (sta) { + /* Check if aggregation has to be enabled for this tid */ + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + if (sta->deflink.ht_cap.ht_supported && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 tid = rtl_get_tid(skb); + + if (_rtl_tx_aggr_check(rtlpriv, sta_entry, + tid)) { + sta_entry->tids[tid].agg.agg_state = + RTL_AGG_PROGRESS; + ieee80211_start_tx_ba_session(sta, tid, + 5000); + } + } + } + } +} + +static void rtl_rate_init(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta) +{ +} + +static void rtl_rate_update(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta, + u32 changed) +{ +} + +static void *rtl_rate_alloc(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + return rtlpriv; +} + +static void rtl_rate_free(void *rtlpriv) +{ + return; +} + +static void *rtl_rate_alloc_sta(void *ppriv, + struct ieee80211_sta *sta, gfp_t gfp) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_rate_priv *rate_priv; + + rate_priv = kzalloc_obj(*rate_priv, gfp); + if (!rate_priv) + return NULL; + + rtlpriv->rate_priv = rate_priv; + + return rate_priv; +} + +static void rtl_rate_free_sta(void *rtlpriv, + struct ieee80211_sta *sta, void *priv_sta) +{ + struct rtl_rate_priv *rate_priv = priv_sta; + + kfree(rate_priv); +} + +static const struct rate_control_ops rtl_rate_ops = { + .name = "rtl_rc", + .alloc = rtl_rate_alloc, + .free = rtl_rate_free, + .alloc_sta = rtl_rate_alloc_sta, + .free_sta = rtl_rate_free_sta, + .rate_init = rtl_rate_init, + .rate_update = rtl_rate_update, + .tx_status = rtl_tx_status, + .get_rate = rtl_get_rate, +}; + +int rtl_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rtl_rate_ops); +} + +void rtl_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rtl_rate_ops); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.h b/drivers/net/wireless/realtek/rtlwifi/rc.h new file mode 100644 index 000000000..1c0a17370 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_RC_H__ +#define __RTL_RC_H__ + +#define B_MODE_MAX_RIX 3 +#define G_MODE_MAX_RIX 11 +#define A_MODE_MAX_RIX 7 + +/* in mac80211 mcs0-mcs15 is idx0-idx15*/ +#define N_MODE_MCS7_RIX 7 +#define N_MODE_MCS15_RIX 15 + +#define AC_MODE_MCS7_RIX 7 +#define AC_MODE_MCS8_RIX 8 +#define AC_MODE_MCS9_RIX 9 + +struct rtl_rate_priv { + u8 ht_cap; +}; + +int rtl_rate_control_register(void); +void rtl_rate_control_unregister(void); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c new file mode 100644 index 000000000..fd967006b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/regd.c @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "regd.h" + +static struct country_code_to_enum_rd all_countries[] = { + {COUNTRY_CODE_FCC, "US"}, + {COUNTRY_CODE_IC, "US"}, + {COUNTRY_CODE_ETSI, "EC"}, + {COUNTRY_CODE_SPAIN, "EC"}, + {COUNTRY_CODE_FRANCE, "EC"}, + {COUNTRY_CODE_MKK, "JP"}, + {COUNTRY_CODE_MKK1, "JP"}, + {COUNTRY_CODE_ISRAEL, "EC"}, + {COUNTRY_CODE_TELEC, "JP"}, + {COUNTRY_CODE_MIC, "JP"}, + {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, + {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, + {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, + {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"}, +}; + +/* + *Only these channels all allow active + *scan on all world regulatory domains + */ +#define RTL819x_2GHZ_CH01_11 \ + REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) + +/* + *We enable active scan on these a case + *by case basis by regulatory domain + */ +#define RTL819x_2GHZ_CH12_13 \ + REG_RULE(2467-10, 2472+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) + +#define RTL819x_2GHZ_CH14 \ + REG_RULE(2484-10, 2484+10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_OFDM) + +/* 5G chan 36 - chan 64*/ +#define RTL819x_5GHZ_5150_5350 \ + REG_RULE(5150-10, 5350+10, 80, 0, 30, 0) +/* 5G chan 100 - chan 165*/ +#define RTL819x_5GHZ_5470_5850 \ + REG_RULE(5470-10, 5850+10, 80, 0, 30, 0) +/* 5G chan 149 - chan 165*/ +#define RTL819x_5GHZ_5725_5850 \ + REG_RULE(5725-10, 5850+10, 80, 0, 30, 0) + +#define RTL819x_5GHZ_ALL \ + (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) + +static const struct ieee80211_regdomain rtl_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13 = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_no_midband = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_60_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5470_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + } +}; + +static bool _rtl_is_radar_freq(u16 center_freq) +{ + return center_freq >= 5260 && center_freq <= 5700; +} + +static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (_rtl_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + reg_rule = freq_reg_info(wiphy, + ch->center_freq); + if (IS_ERR(reg_rule)) + continue; + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan on Ch 12 and 13 */ +static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + + if (!wiphy->bands[NL80211_BAND_2GHZ]) + return; + sband = wiphy->bands[NL80211_BAND_2GHZ]; + + /* + *If no country IE has been received always enable active scan + *on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + *If a country IE has been received check its rule for this + *channel first before enabling active scan. The passive scan + *would have been enforced by the initial processing of our + *custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +/* + *Always apply Radar/DFS rules on + *freq range 5260 MHz - 5700 MHz + */ +static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!_rtl_is_radar_freq(ch->center_freq)) + continue; + + /* + *We always enable radar detection/DFS on this + *frequency range. Additionally we also apply on + *this frequency range: + *- If STA mode does not yet have DFS supports disable + * active scanning + *- If adhoc mode does not support DFS yet then disable + * adhoc in the frequency. + *- If AP mode does not yet support radar detection/DFS + *do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct rtl_regulatory *reg) +{ + _rtl_reg_apply_beaconing_flags(wiphy, initiator); + _rtl_reg_apply_active_scan_flags(wiphy, initiator); + return; +} + +static int _rtl_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct rtl_regulatory *reg) +{ + /* We always apply this */ + _rtl_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); + break; + } + + return 0; +} + +static const struct ieee80211_regdomain *_rtl_regdomain_select( + struct rtl_regulatory *reg) +{ + switch (reg->country_code) { + case COUNTRY_CODE_FCC: + return &rtl_regdom_no_midband; + case COUNTRY_CODE_IC: + return &rtl_regdom_11; + case COUNTRY_CODE_TELEC_NETGEAR: + return &rtl_regdom_60_64; + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: + return &rtl_regdom_12_13; + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_TELEC: + case COUNTRY_CODE_MIC: + return &rtl_regdom_14_60_64; + case COUNTRY_CODE_GLOBAL_DOMAIN: + return &rtl_regdom_14; + case COUNTRY_CODE_WORLD_WIDE_13: + case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: + return &rtl_regdom_12_13_5g_all; + default: + return &rtl_regdom_no_midband; + } +} + +static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, + struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request * + request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; + wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + regd = _rtl_regdomain_select(reg); + wiphy_apply_custom_regulatory(wiphy, regd); + _rtl_reg_apply_radar_flags(wiphy); + _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(all_countries); i++) { + if (all_countries[i].countrycode == countrycode) + return &all_countries[i]; + } + return NULL; +} + +static u8 channel_plan_to_country_code(u8 channelplan) +{ + switch (channelplan) { + case 0x20: + case 0x21: + return COUNTRY_CODE_WORLD_WIDE_13; + case 0x22: + return COUNTRY_CODE_IC; + case 0x25: + return COUNTRY_CODE_ETSI; + case 0x32: + return COUNTRY_CODE_TELEC_NETGEAR; + case 0x41: + return COUNTRY_CODE_GLOBAL_DOMAIN; + case 0x7f: + return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL; + default: + return COUNTRY_CODE_MAX; /*Error*/ + } +} + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct wiphy *wiphy = hw->wiphy; + struct country_code_to_enum_rd *country = NULL; + + if (!wiphy) + return -EINVAL; + + /* init country_code from efuse channel plan */ + rtlpriv->regd.country_code = + channel_plan_to_country_code(rtlpriv->efuse.channel_plan); + + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM regdomain: 0x%0x country code: %d\n", + rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); + + if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); + + rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; + } + + country = _rtl_regd_find_country(rtlpriv->regd.country_code); + + if (country) { + rtlpriv->regd.alpha2[0] = country->iso_name[0]; + rtlpriv->regd.alpha2[1] = country->iso_name[1]; + } else { + rtlpriv->regd.alpha2[0] = '0'; + rtlpriv->regd.alpha2[1] = '0'; + } + + rtl_dbg(rtlpriv, COMP_REGD, DBG_TRACE, + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); + + _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); + + return 0; +} + +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); + + _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.h b/drivers/net/wireless/realtek/rtlwifi/regd.h new file mode 100644 index 000000000..3ba068511 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/regd.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_REGD_H__ +#define __RTL_REGD_H__ + +/* for kernel 3.14 , both value are changed to IEEE80211_CHAN_NO_IR*/ +#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR + +struct country_code_to_enum_rd { + u16 countrycode; + const char *iso_name; +}; + +enum country_code_type_t { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + COUNTRY_CODE_WORLD_WIDE_13_5G_ALL = 13, + + /*add new channel plan above this line */ + COUNTRY_CODE_MAX +}; + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier) (struct wiphy *wiphy, + struct regulatory_request *request)); +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile new file mode 100644 index 000000000..5ea368e8e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8188ee-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + pwrseq.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8188EE) += rtl8188ee.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h new file mode 100644 index 000000000..edcca42c7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92C_DEF_H__ +#define __RTL92C_DEF_H__ + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +#define C2H_RX_CMD_HDR_LEN 8 + +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) + +/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 + * [7] Manufacturer: TSMC=0, UMC=1 + * [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 + * [3] Chip type: TEST=0, NORMAL=1 + * [2:0] IC type: 81xxC=0, 8723=1, 92D=2 + */ +#define CHIP_8723 BIT(0) +#define CHIP_92D BIT(1) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(12)|BIT(13))) +#define E_CUT_VERSION BIT(14) + +/* MASK */ +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + +/* Get element */ +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_81XXC(version) \ + ((GET_CVID_IC_TYPE(version) == 0) ? true : false) +#define IS_8723_SERIES(version) \ + ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false) +#define IS_92D(version) \ + ((GET_CVID_IC_TYPE(version) == CHIP_92D) ? true : false) + +#define IS_NORMAL_CHIP(version) \ + ((GET_CVID_CHIP_TYPE(version)) ? true : false) +#define IS_NORMAL_CHIP92D(version) \ + ((GET_CVID_CHIP_TYPE(version)) ? true : false) + +#define IS_1T1R(version) \ + ((GET_CVID_RF_TYPE(version)) ? false : true) +#define IS_1T2R(version) \ + ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false) +#define IS_2T2R(version) \ + ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false) +#define IS_CHIP_VENDOR_UMC(version) \ + ((GET_CVID_MANUFACTUER(version)) ? true : false) + +#define IS_92C_SERIAL(version) \ + ((IS_81XXC(version) && IS_2T2R(version)) ? true : false) +#define IS_81XXC_VENDOR_UMC_B_CUT(version) \ + (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ + ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true \ + : false) : false) : false) + +enum version_8188e { + VERSION_TEST_CHIP_88E = 0x00, + VERSION_NORMAL_CHIP_88E = 0x01, + VERSION_UNKNOWN = 0xFF, +}; + +enum rtl819x_loopback_e { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc92c_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, + DESC92C_RATEMCS15_SG = 0x1c, + DESC92C_RATEMCS32 = 0x20, +}; + +struct phy_sts_cck_8192s_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c new file mode 100644 index 000000000..f749d19ec --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c @@ -0,0 +1,1784 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "trx.h" + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB */ + 0x6b8001ae, /* 3, +4.5dB */ + 0x65400195, /* 4, +4.0dB */ + 0x5fc0017f, /* 5, +3.5dB */ + 0x5a400169, /* 6, +3.0dB */ + 0x55400155, /* 7, +2.5dB */ + 0x50800142, /* 8, +2.0dB */ + 0x4c000130, /* 9, +1.5dB */ + 0x47c0011f, /* 10, +1.0dB */ + 0x43c0010f, /* 11, +0.5dB */ + 0x40000100, /* 12, +0dB */ + 0x3c8000f2, /* 13, -0.5dB */ + 0x390000e4, /* 14, -1.0dB */ + 0x35c000d7, /* 15, -1.5dB */ + 0x32c000cb, /* 16, -2.0dB */ + 0x300000c0, /* 17, -2.5dB */ + 0x2d4000b5, /* 18, -3.0dB */ + 0x2ac000ab, /* 19, -3.5dB */ + 0x288000a2, /* 20, -4.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x24000090, /* 22, -5.0dB */ + 0x22000088, /* 23, -5.5dB */ + 0x20000080, /* 24, -6.0dB */ + 0x1e400079, /* 25, -6.5dB */ + 0x1c800072, /* 26, -7.0dB */ + 0x1b00006c, /* 27. -7.5dB */ + 0x19800066, /* 28, -8.0dB */ + 0x18000060, /* 29, -8.5dB */ + 0x16c0005b, /* 30, -9.0dB */ + 0x15800056, /* 31, -9.5dB */ + 0x14400051, /* 32, -10.0dB */ + 0x1300004c, /* 33, -10.5dB */ + 0x12000048, /* 34, -11.0dB */ + 0x11000044, /* 35, -11.5dB */ + 0x10000040, /* 36, -12.0dB */ + 0x0f00003c, /* 37, -12.5dB */ + 0x0e400039, /* 38, -13.0dB */ + 0x0d800036, /* 39, -13.5dB */ + 0x0cc00033, /* 40, -14.0dB */ + 0x0c000030, /* 41, -14.5dB */ + 0x0b40002d, /* 42, -15.0dB */ +}; + +static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ +}; + +static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ +}; + +#define CAL_SWING_OFF(_off, _dir, _size, _del) \ + do { \ + for (_off = 0; _off < _size; _off++) { \ + if (_del < thermal_threshold[_dir][_off]) { \ + if (_off != 0) \ + _off--; \ + break; \ + } \ + } \ + if (_off >= _size) \ + _off = _size - 1; \ + } while (0) + +static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw, + u8 ofdm_index, u8 rfpath, + long iqk_result_x, long iqk_result_y) +{ + long ele_a = 0, ele_d, ele_c = 0, value32; + + ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22; + + if (iqk_result_x != 0) { + if ((iqk_result_x & 0x00000200) != 0) + iqk_result_x = iqk_result_x | 0xFFFFFC00; + ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF; + + if ((iqk_result_y & 0x00000200) != 0) + iqk_result_y = iqk_result_y | 0xFFFFFC00; + ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF; + + switch (rfpath) { + case RF90_PATH_A: + value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + value32); + break; + case RF90_PATH_B: + value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, + value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32); + value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), + value32); + break; + default: + break; + } + } else { + switch (rfpath) { + case RF90_PATH_A: + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, ofdmswing_table[ofdm_index]); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(24), 0x00); + break; + case RF90_PATH_B: + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, ofdmswing_table[ofdm_index]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(28), 0x00); + break; + default: + break; + } + } +} + +void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw, + u8 type, u8 *pdirection, u32 *poutwrite_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 pwr_val = 0; + u8 cck_base = rtldm->swing_idx_cck_base; + u8 cck_val = rtldm->swing_idx_cck; + u8 ofdm_base = rtldm->swing_idx_ofdm_base[0]; + u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A]; + + if (type == 0) { + if (ofdm_val <= ofdm_base) { + *pdirection = 1; + pwr_val = ofdm_base - ofdm_val; + } else { + *pdirection = 2; + pwr_val = ofdm_base - ofdm_val; + } + } else if (type == 1) { + if (cck_val <= cck_base) { + *pdirection = 1; + pwr_val = cck_base - cck_val; + } else { + *pdirection = 2; + pwr_val = cck_val - cck_base; + } + } + + if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) + pwr_val = TXPWRTRACK_MAX_IDX; + + *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) | + (pwr_val << 24); +} + +static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rfpath, u8 channel_mapped_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + + if (method == TXAGC) { + if (rtldm->swing_flag_ofdm || + rtldm->swing_flag_cck) { + rtl88e_phy_set_txpower_level(hw, + rtlphy->current_channel); + rtldm->swing_flag_ofdm = false; + rtldm->swing_flag_cck = false; + } + } else if (method == BBSWING) { + if (!rtldm->cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cck_tbl_ch1_13[rtldm->swing_idx_cck][0]); + rtl_write_byte(rtlpriv, 0xa23, + cck_tbl_ch1_13[rtldm->swing_idx_cck][1]); + rtl_write_byte(rtlpriv, 0xa24, + cck_tbl_ch1_13[rtldm->swing_idx_cck][2]); + rtl_write_byte(rtlpriv, 0xa25, + cck_tbl_ch1_13[rtldm->swing_idx_cck][3]); + rtl_write_byte(rtlpriv, 0xa26, + cck_tbl_ch1_13[rtldm->swing_idx_cck][4]); + rtl_write_byte(rtlpriv, 0xa27, + cck_tbl_ch1_13[rtldm->swing_idx_cck][5]); + rtl_write_byte(rtlpriv, 0xa28, + cck_tbl_ch1_13[rtldm->swing_idx_cck][6]); + rtl_write_byte(rtlpriv, 0xa29, + cck_tbl_ch1_13[rtldm->swing_idx_cck][7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cck_tbl_ch14[rtldm->swing_idx_cck][0]); + rtl_write_byte(rtlpriv, 0xa23, + cck_tbl_ch14[rtldm->swing_idx_cck][1]); + rtl_write_byte(rtlpriv, 0xa24, + cck_tbl_ch14[rtldm->swing_idx_cck][2]); + rtl_write_byte(rtlpriv, 0xa25, + cck_tbl_ch14[rtldm->swing_idx_cck][3]); + rtl_write_byte(rtlpriv, 0xa26, + cck_tbl_ch14[rtldm->swing_idx_cck][4]); + rtl_write_byte(rtlpriv, 0xa27, + cck_tbl_ch14[rtldm->swing_idx_cck][5]); + rtl_write_byte(rtlpriv, 0xa28, + cck_tbl_ch14[rtldm->swing_idx_cck][6]); + rtl_write_byte(rtlpriv, 0xa29, + cck_tbl_ch14[rtldm->swing_idx_cck][7]); + } + + if (rfpath == RF90_PATH_A) { + rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath], + rfpath, rtlphy->iqk_matrix + [channel_mapped_index]. + value[0][0], + rtlphy->iqk_matrix + [channel_mapped_index]. + value[0][1]); + } else if (rfpath == RF90_PATH_B) { + rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath], + rfpath, rtlphy->iqk_matrix + [channel_mapped_index]. + value[0][4], + rtlphy->iqk_matrix + [channel_mapped_index]. + value[0][5]); + } + } else { + return; + } +} + +static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + long rssi_val_min = 0; + + if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) && + (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undec_sm_pwdb > + rtlpriv->dm.undec_sm_pwdb) ? + rtlpriv->dm.undec_sm_pwdb : + rtlpriv->dm.entry_min_undec_sm_pwdb; + else + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT || + dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_dig->curmultista_cstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + + return (u8)rssi_val_min; +} + +static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); + + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff); + falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD); + falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff); + falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16); + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD); + falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | + ((ret_value&0xFF00)>>8); + + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail + + falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca + + falsealm_cnt->cnt_cck_cca; + + rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1); + rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0); + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); +} + +static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u8 cur_cck_cca_thresh; + + if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) { + dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw); + if (dm_dig->rssi_val_min > 25) { + cur_cck_cca_thresh = 0xcd; + } else if ((dm_dig->rssi_val_min <= 25) && + (dm_dig->rssi_val_min > 10)) { + cur_cck_cca_thresh = 0x83; + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh); + + dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh; + dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres; + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres); +} + +static void rtl88e_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u8 dig_dynamic_min, dig_maxofmin; + bool bfirstconnect; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dm_dig->cur_igvalue; + + if (!rtlpriv->dm.dm_initialgain_enable) + return; + if (!dm_dig->dig_enable_flag) + return; + if (mac->act_scanning) + return; + + if (mac->link_state >= MAC80211_LINKED) + dm_dig->cur_sta_cstate = DIG_STA_CONNECT; + else + dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT; + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) + dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT; + + dm_dig_max = DM_DIG_MAX; + dm_dig_min = DM_DIG_MIN; + dig_maxofmin = DM_DIG_MAX_AP; + dig_dynamic_min = dm_dig->dig_min_0; + bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) && + !dm_dig->media_connect_0; + + dm_dig->rssi_val_min = + rtl88e_dm_initial_gain_min_pwdb(hw); + + if (mac->link_state >= MAC80211_LINKED) { + if ((dm_dig->rssi_val_min + 20) > dm_dig_max) + dm_dig->rx_gain_max = dm_dig_max; + else if ((dm_dig->rssi_val_min + 20) < dm_dig_min) + dm_dig->rx_gain_max = dm_dig_min; + else + dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20; + + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) { + dig_dynamic_min = dm_dig->antdiv_rssi_max; + } else { + if (dm_dig->rssi_val_min < dm_dig_min) + dig_dynamic_min = dm_dig_min; + else if (dm_dig->rssi_val_min < dig_maxofmin) + dig_dynamic_min = dig_maxofmin; + else + dig_dynamic_min = dm_dig->rssi_val_min; + } + } else { + dm_dig->rx_gain_max = dm_dig_max; + dig_dynamic_min = dm_dig_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); + } + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { + dm_dig->large_fa_hit++; + if (dm_dig->forbidden_igi < current_igi) { + dm_dig->forbidden_igi = current_igi; + dm_dig->large_fa_hit = 1; + } + + if (dm_dig->large_fa_hit >= 3) { + if ((dm_dig->forbidden_igi + 1) > + dm_dig->rx_gain_max) + dm_dig->rx_gain_min = + dm_dig->rx_gain_max; + else + dm_dig->rx_gain_min = + dm_dig->forbidden_igi + 1; + dm_dig->recover_cnt = 3600; + } + } else { + if (dm_dig->recover_cnt != 0) { + dm_dig->recover_cnt--; + } else { + if (dm_dig->large_fa_hit == 0) { + if ((dm_dig->forbidden_igi - 1) < + dig_dynamic_min) { + dm_dig->forbidden_igi = dig_dynamic_min; + dm_dig->rx_gain_min = dig_dynamic_min; + } else { + dm_dig->forbidden_igi--; + dm_dig->rx_gain_min = + dm_dig->forbidden_igi + 1; + } + } else if (dm_dig->large_fa_hit == 3) { + dm_dig->large_fa_hit = 0; + } + } + } + + if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) { + if (bfirstconnect) { + current_igi = dm_dig->rssi_val_min; + } else { + if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) + current_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + current_igi--; + } + } else { + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all > 8000) + current_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all < 500) + current_igi--; + } + + if (current_igi > DM_DIG_FA_UPPER) + current_igi = DM_DIG_FA_UPPER; + else if (current_igi < DM_DIG_FA_LOWER) + current_igi = DM_DIG_FA_LOWER; + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + current_igi = DM_DIG_FA_UPPER; + + dm_dig->cur_igvalue = current_igi; + rtl88e_dm_write_dig(hw); + dm_dig->media_connect_0 = + ((mac->link_state >= MAC80211_LINKED) ? true : false); + dm_dig->dig_min_0 = dig_dynamic_min; + + rtl88e_dm_cck_packet_detection_thresh(hw); +} + +static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = + rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n"); + } else if ((undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undec_sm_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n"); + } else if (undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != + rtlpriv->dm.last_dtp_lvl)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +void rtl88e_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", + dm_dig->cur_igvalue, dm_dig->pre_igvalue, + dm_dig->back_val); + + if (dm_dig->cur_igvalue > 0x3f) + dm_dig->cur_igvalue = 0x3f; + if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_dig->cur_igvalue); + + dm_dig->pre_igvalue = dm_dig->cur_igvalue; + } +} + +static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *drv_priv; + static u64 last_record_txok_cnt; + static u64 last_record_rxok_cnt; + long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; + + if (rtlhal->oem_id == RT_CID_819X_HP) { + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + cur_txok_cnt = rtlpriv->stats.txbytesunicast - + last_record_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - + last_record_rxok_cnt; + last_record_txok_cnt = cur_txok_cnt; + last_record_rxok_cnt = cur_rxok_cnt; + + if (cur_rxok_cnt > (cur_txok_cnt * 6)) + rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015); + else + rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015); + } + + /* AP & ADHOC & MESH */ + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { + if (drv_priv->rssi_stat.undec_sm_pwdb < + tmp_entry_min_pwdb) + tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; + if (drv_priv->rssi_stat.undec_sm_pwdb > + tmp_entry_max_pwdb) + tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + /* If associated entry is found */ + if (tmp_entry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n", + tmp_entry_max_pwdb, tmp_entry_max_pwdb); + } else { + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + } + /* If associated entry is found */ + if (tmp_entry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n", + tmp_entry_min_pwdb, tmp_entry_min_pwdb); + } else { + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + } + /* Indicate Rx signal strength to FW. */ + if (!rtlpriv->dm.useramask) + rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb); +} + +void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} + +static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + static u32 last_bt_edca_ul; + static u32 last_bt_edca_dl; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + bool bt_change_edca = false; + + if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) || + (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) { + rtlpriv->dm.current_turbo_edca = false; + last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul; + last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl; + } + + if (rtlpriv->btcoexist.bt_edca_ul != 0) { + edca_be_ul = rtlpriv->btcoexist.bt_edca_ul; + bt_change_edca = true; + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + return; + } + if ((bt_change_edca) || + ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting))) { + + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + &tmp); + rtlpriv->dm.current_turbo_edca = false; + } + } + + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset; + u8 thermalvalue_avg_count = 0; + u32 thermalvalue_avg = 0; + long ele_d, temp_cck; + s8 ofdm_index[2], cck_index = 0, + ofdm_index_old[2] = {0, 0}, cck_index_old = 0; + int i = 0; + /*bool is2t = false;*/ + + u8 ofdm_min_index = 6, rf = 1; + /*u8 index_for_channel;*/ + enum _power_dec_inc {power_dec, power_inc}; + + /*0.1 the following TWO tables decide the + *final index of OFDM/CCK swing table + */ + static const s8 delta_swing_table_idx[2][15] = { + {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, + {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10} + }; + static const u8 thermal_threshold[2][15] = { + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27}, + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25} + }; + + /*Initilization (7 steps in total) */ + rtlpriv->dm.txpower_trackinginit = true; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "%s\n", __func__); + + thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, + 0xfc00); + if (!thermalvalue) + return; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter); + + /*1. Query OFDM Default Setting: Path A*/ + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) & + MASKOFDM_D; + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8)i; + rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0]); + break; + } + } + + /*2.Query CCK default setting From 0xa24*/ + temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.cck_inch14) { + if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) { + cck_index_old = (u8)i; + rtldm->swing_idx_cck_base = (u8)i; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); + break; + } + } else { + if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) { + cck_index_old = (u8)i; + rtldm->swing_idx_cck_base = (u8)i; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); + break; + } + } + } + + /*3 Initialize ThermalValues of RFCalibrateInfo*/ + if (!rtldm->thermalvalue) { + rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + + /*4 Calculate average thermal meter*/ + rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue; + rtldm->thermalvalue_avg_index++; + if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E) + rtldm->thermalvalue_avg_index = 0; + + for (i = 0; i < AVG_THERMAL_NUM_88E; i++) { + if (rtldm->thermalvalue_avg[i]) { + thermalvalue_avg += rtldm->thermalvalue_avg[i]; + thermalvalue_avg_count++; + } + } + + if (thermalvalue_avg_count) + thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count); + + /* 5 Calculate delta, delta_LCK, delta_IQK.*/ + if (rtlhal->reloadtxpowerindex) { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + rtlhal->reloadtxpowerindex = false; + rtlpriv->dm.done_txpower = false; + } else if (rtlpriv->dm.done_txpower) { + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + } else { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + } + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk); + /* 6 If necessary, do LCK.*/ + if (delta_lck >= 8) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl88e_phy_lc_calibrate(hw); + } + + /* 7 If necessary, move the index of + * swing table to adjust Tx power. + */ + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + + /* 7.1 Get the final CCK_index and OFDM_index for each + * swing table. + */ + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM, + delta); + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtldm->ofdm_index[i] + + delta_swing_table_idx[power_inc][offset]; + cck_index = rtldm->cck_index + + delta_swing_table_idx[power_inc][offset]; + } else { + CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM, + delta); + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtldm->ofdm_index[i] + + delta_swing_table_idx[power_dec][offset]; + cck_index = rtldm->cck_index + + delta_swing_table_idx[power_dec][offset]; + } + + /* 7.2 Handle boundary conditions of index.*/ + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE-1) + ofdm_index[i] = OFDM_TABLE_SIZE-1; + else if (rtldm->ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE-1) + cck_index = CCK_TABLE_SIZE-1; + else if (cck_index < 0) + cck_index = 0; + + /*7.3Configure the Swing Table to adjust Tx Power.*/ + if (rtlpriv->dm.txpower_track_control) { + rtldm->done_txpower = true; + rtldm->swing_idx_ofdm[RF90_PATH_A] = + (u8)ofdm_index[RF90_PATH_A]; + rtldm->swing_idx_cck = cck_index; + if (rtldm->swing_idx_ofdm_cur != + rtldm->swing_idx_ofdm[0]) { + rtldm->swing_idx_ofdm_cur = + rtldm->swing_idx_ofdm[0]; + rtldm->swing_flag_ofdm = true; + } + + if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) { + rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck; + rtldm->swing_flag_cck = true; + } + + dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0); + } + } + + if (delta_iqk >= 8) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl88e_phy_iq_calibrate(hw, false); + } + + if (rtldm->txpower_track_control) + rtldm->thermalvalue = thermalvalue; + rtldm->txpowercount = 0; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n"); +} + +static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackinginit = false; + rtlpriv->dm.txpowercount = 0; + rtlpriv->dm.txpower_track_control = true; + + rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12; + rtlpriv->dm.swing_idx_ofdm_cur = 12; + rtlpriv->dm.swing_flag_ofdm = false; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "rtlpriv->dm.txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); +} + +void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16), + 0x03); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 88E Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + return; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking !!\n"); + dm_txpower_track_cb_therm(hw); + rtlpriv->dm.tm_trigger = 0; + } +} + +void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; +} + +static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &rtlpriv->ra; + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + struct ieee80211_sta *sta = NULL; + + if (is_hal_stop(rtlhal)) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver is going to unload\n"); + return; + } + + if (!rtlpriv->dm.useramask) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver does not control rate adaptive mask\n"); + return; + } + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->dm.undec_sm_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undec_sm_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld\n", + rtlpriv->dm.undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI_LEVEL = %d\n", p_ra->ratr_state); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); + + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, + p_ra->ratr_state, + true); + rcu_read_unlock(); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + dm_pstable->pre_ccastate = CCA_MAX; + dm_pstable->cur_ccasate = CCA_MAX; + dm_pstable->pre_rfstate = RF_MAX; + dm_pstable->cur_rfstate = RF_MAX; + dm_pstable->rssi_val_min = 0; +} + +static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw, + u8 ant) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + u32 default_ant, optional_ant; + + if (pfat_table->rx_idle_ant != ant) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "need to update rx idle ant\n"); + if (ant == MAIN_ANT) { + default_ant = + (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ? + MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; + optional_ant = + (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ? + AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; + } else { + default_ant = + (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ? + AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; + optional_ant = + (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ? + MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; + } + + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) { + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(5) | BIT(4) | BIT(3), default_ant); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(8) | BIT(7) | BIT(6), optional_ant); + rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N, + BIT(14) | BIT(13) | BIT(12), + default_ant); + rtl_set_bbreg(hw, DM_REG_RESP_TX_11N, + BIT(6) | BIT(7), default_ant); + } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) { + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(5) | BIT(4) | BIT(3), default_ant); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(8) | BIT(7) | BIT(6), optional_ant); + } + } + pfat_table->rx_idle_ant = ant; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n", + (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT")); +} + +static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw, + u8 ant, u32 mac_id) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + u8 target_ant; + + if (ant == MAIN_ANT) + target_ant = MAIN_ANT_CG_TRX; + else + target_ant = AUX_ANT_CG_TRX; + + pfat_table->antsel_a[mac_id] = target_ant & BIT(0); + pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1; + pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n", + (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT")); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n", + pfat_table->antsel_c[mac_id], + pfat_table->antsel_b[mac_id], + pfat_table->antsel_a[mac_id]); +} + +static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw) +{ + u32 value32; + + /*MAC Setting*/ + value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD); + rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, + MASKDWORD, value32 | (BIT(23) | BIT(25))); + /*Pin Setting*/ + rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1); + /*OFDM Setting*/ + rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0); + /*CCK Setting*/ + rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1); + rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); + rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT); + rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201); +} + +static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw) +{ + u32 value32; + + /*MAC Setting*/ + value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD); + rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD, + value32 | (BIT(23) | BIT(25))); + /*Pin Setting*/ + rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1); + /*OFDM Setting*/ + rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0); + /*CCK Setting*/ + rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1); + rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); + /*TX Setting*/ + rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0); + rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT); + rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201); +} + +static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw) +{ + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + u32 ant_combination = 2; + u32 value32, i; + + for (i = 0; i < 6; i++) { + pfat_table->bssid[i] = 0; + pfat_table->ant_sum[i] = 0; + pfat_table->ant_cnt[i] = 0; + pfat_table->ant_ave[i] = 0; + } + pfat_table->train_idx = 0; + pfat_table->fat_state = FAT_NORMAL_STATE; + + /*MAC Setting*/ + value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD); + rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, + MASKDWORD, value32 | (BIT(23) | BIT(25))); + value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD); + rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, + MASKDWORD, value32 | (BIT(16) | BIT(17))); + rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, + MASKLWORD, 0); + rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N, + MASKDWORD, 0); + + /*Pin Setting*/ + rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0); + rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1); + + /*OFDM Setting*/ + rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0); + /*antenna mapping table*/ + rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1); + rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2); + + /*TX Setting*/ + rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(5) | BIT(4) | BIT(3), 0); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(8) | BIT(7) | BIT(6), 1); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, + BIT(2) | BIT(1) | BIT(0), (ant_combination - 1)); + + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1); +} + +static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtl88e_dm_rx_hw_antena_div_init(hw); + else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + rtl88e_dm_trx_hw_antenna_div_init(hw); + else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV) + rtl88e_dm_fast_training_init(hw); + +} + +void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, + u8 *pdesc, u32 mac_id) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + __le32 *pdesc32 = (__le32 *)pdesc; + + if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) || + (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) { + set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]); + set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]); + set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]); + } +} + +void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw, + u8 antsel_tr_mux, u32 mac_id, + u32 rx_pwdb_all) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) { + if (antsel_tr_mux == MAIN_ANT_CG_TRX) { + pfat_table->main_ant_sum[mac_id] += rx_pwdb_all; + pfat_table->main_ant_cnt[mac_id]++; + } else { + pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all; + pfat_table->aux_ant_cnt[mac_id]++; + } + } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) { + if (antsel_tr_mux == MAIN_ANT_CGCS_RX) { + pfat_table->main_ant_sum[mac_id] += rx_pwdb_all; + pfat_table->main_ant_cnt[mac_id]++; + } else { + pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all; + pfat_table->aux_ant_cnt[mac_id]++; + } + } +} + +static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_sta_info *drv_priv; + struct fast_ant_training *pfat_table = &rtldm->fat_table; + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u32 i, min_rssi = 0xff, ant_div_max_rssi = 0; + u32 max_rssi = 0, local_min_rssi, local_max_rssi; + u32 main_rssi, aux_rssi; + u8 rx_idle_ant = 0, target_ant = 7; + + /*for sta its self*/ + i = 0; + main_rssi = (pfat_table->main_ant_cnt[i] != 0) ? + (pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0; + aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ? + (pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0; + target_ant = (main_rssi == aux_rssi) ? + pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ? + MAIN_ANT : AUX_ANT); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "main_ant_sum %d main_ant_cnt %d\n", + pfat_table->main_ant_sum[i], + pfat_table->main_ant_cnt[i]); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "aux_ant_sum %d aux_ant_cnt %d\n", + pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n", + main_rssi, aux_rssi); + local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi; + if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40)) + ant_div_max_rssi = local_max_rssi; + if (local_max_rssi > max_rssi) + max_rssi = local_max_rssi; + + if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0)) + main_rssi = aux_rssi; + else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0)) + aux_rssi = main_rssi; + + local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi; + if (local_min_rssi < min_rssi) { + min_rssi = local_min_rssi; + rx_idle_ant = target_ant; + } + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + rtl88e_dm_update_tx_ant(hw, target_ant, i); + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { + i++; + main_rssi = (pfat_table->main_ant_cnt[i] != 0) ? + (pfat_table->main_ant_sum[i] / + pfat_table->main_ant_cnt[i]) : 0; + aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ? + (pfat_table->aux_ant_sum[i] / + pfat_table->aux_ant_cnt[i]) : 0; + target_ant = (main_rssi == aux_rssi) ? + pfat_table->rx_idle_ant : ((main_rssi >= + aux_rssi) ? MAIN_ANT : AUX_ANT); + + local_max_rssi = (main_rssi > aux_rssi) ? + main_rssi : aux_rssi; + if ((local_max_rssi > ant_div_max_rssi) && + (local_max_rssi < 40)) + ant_div_max_rssi = local_max_rssi; + if (local_max_rssi > max_rssi) + max_rssi = local_max_rssi; + + if ((pfat_table->rx_idle_ant == MAIN_ANT) && + (main_rssi == 0)) + main_rssi = aux_rssi; + else if ((pfat_table->rx_idle_ant == AUX_ANT) && + (aux_rssi == 0)) + aux_rssi = main_rssi; + + local_min_rssi = (main_rssi > aux_rssi) ? + aux_rssi : main_rssi; + if (local_min_rssi < min_rssi) { + min_rssi = local_min_rssi; + rx_idle_ant = target_ant; + } + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + rtl88e_dm_update_tx_ant(hw, target_ant, i); + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + } + + for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) { + pfat_table->main_ant_sum[i] = 0; + pfat_table->aux_ant_sum[i] = 0; + pfat_table->main_ant_cnt[i] = 0; + pfat_table->aux_ant_cnt[i] = 0; + } + + rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant); + + dm_dig->antdiv_rssi_max = ant_div_max_rssi; + dm_dig->rssi_max = max_rssi; +} + +static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_sta_info *drv_priv; + struct fast_ant_training *pfat_table = &rtldm->fat_table; + u32 value32, i, j = 0; + + if (mac->link_state >= MAC80211_LINKED) { + for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) { + if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM) + pfat_table->train_idx = 0; + else + pfat_table->train_idx++; + + if (pfat_table->train_idx == 0) { + value32 = (mac->mac_addr[5] << 8) | + mac->mac_addr[4]; + rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, + MASKLWORD, value32); + + value32 = (mac->mac_addr[3] << 24) | + (mac->mac_addr[2] << 16) | + (mac->mac_addr[1] << 8) | + mac->mac_addr[0]; + rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N, + MASKDWORD, value32); + break; + } + + if (rtlpriv->mac80211.opmode != + NL80211_IFTYPE_STATION) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, + &rtlpriv->entry_list, list) { + j++; + if (j != pfat_table->train_idx) + continue; + + value32 = (drv_priv->mac_addr[5] << 8) | + drv_priv->mac_addr[4]; + rtl_set_bbreg(hw, + DM_REG_ANT_TRAIN_PARA2_11N, + MASKLWORD, value32); + + value32 = (drv_priv->mac_addr[3] << 24) | + (drv_priv->mac_addr[2] << 16) | + (drv_priv->mac_addr[1] << 8) | + drv_priv->mac_addr[0]; + rtl_set_bbreg(hw, + DM_REG_ANT_TRAIN_PARA1_11N, + MASKDWORD, value32); + break; + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + /*find entry, break*/ + if (j == pfat_table->train_idx) + break; + } + } + } +} + +static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + u32 i, max_rssi = 0; + u8 target_ant = 2; + bool bpkt_filter_match = false; + + if (pfat_table->fat_state == FAT_TRAINING_STATE) { + for (i = 0; i < 7; i++) { + if (pfat_table->ant_cnt[i] == 0) { + pfat_table->ant_ave[i] = 0; + } else { + pfat_table->ant_ave[i] = + pfat_table->ant_sum[i] / + pfat_table->ant_cnt[i]; + bpkt_filter_match = true; + } + + if (pfat_table->ant_ave[i] > max_rssi) { + max_rssi = pfat_table->ant_ave[i]; + target_ant = (u8) i; + } + } + + if (!bpkt_filter_match) { + rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, + BIT(16), 0); + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0); + } else { + rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, + BIT(16), 0); + rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) | + BIT(7) | BIT(6), target_ant); + rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, + BIT(21), 1); + + pfat_table->antsel_a[pfat_table->train_idx] = + target_ant & BIT(0); + pfat_table->antsel_b[pfat_table->train_idx] = + (target_ant & BIT(1)) >> 1; + pfat_table->antsel_c[pfat_table->train_idx] = + (target_ant & BIT(2)) >> 2; + + if (target_ant == 0) + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0); + } + + for (i = 0; i < 7; i++) { + pfat_table->ant_sum[i] = 0; + pfat_table->ant_cnt[i] = 0; + } + + pfat_table->fat_state = FAT_NORMAL_STATE; + return; + } + + if (pfat_table->fat_state == FAT_NORMAL_STATE) { + rtl88e_set_next_mac_address_target(hw); + + pfat_table->fat_state = FAT_TRAINING_STATE; + rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1); + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1); + + mod_timer(&rtlpriv->works.fast_antenna_training_timer, + jiffies + MSECS(RTL_WATCH_DOG_TIME)); + } +} + +void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t) +{ + struct rtl_priv *rtlpriv = + timer_container_of(rtlpriv, t, + works.fast_antenna_training_timer); + struct ieee80211_hw *hw = rtlpriv->hw; + + rtl88e_dm_fast_ant_training(hw); +} + +static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + + if (mac->link_state < MAC80211_LINKED) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n"); + if (pfat_table->becomelinked) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "need to turn off HW AntDiv\n"); + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0); + rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N, + BIT(15), 0); + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, + BIT(21), 0); + pfat_table->becomelinked = + (mac->link_state == MAC80211_LINKED) ? + true : false; + } + return; + } else { + if (!pfat_table->becomelinked) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Need to turn on HW AntDiv\n"); + rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1); + rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N, + BIT(15), 1); + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, + BIT(21), 1); + pfat_table->becomelinked = + (mac->link_state >= MAC80211_LINKED) ? + true : false; + } + } + + if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) || + (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)) + rtl88e_dm_hw_ant_div(hw); + else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV) + rtl88e_dm_fast_ant_training(hw); +} + +void rtl88e_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl_dm_diginit(hw, cur_igvalue); + rtl88e_dm_init_dynamic_txpower(hw); + rtl88e_dm_init_edca_turbo(hw); + rtl88e_dm_init_rate_adaptive_mask(hw); + rtl88e_dm_init_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); + rtl88e_dm_antenna_div_init(hw); +} + +void rtl88e_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) { + rtl88e_dm_pwdb_monitor(hw); + rtl88e_dm_dig(hw); + rtl88e_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl88e_dm_check_txpower_tracking(hw); + rtl88e_dm_refresh_rate_adaptive_mask(hw); + rtl88e_dm_check_edca_turbo(hw); + rtl88e_dm_antenna_diversity(hw); + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h new file mode 100644 index 000000000..eb8090cae --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL88E_DM_H__ +#define __RTL88E_DM_H__ + +#define MAIN_ANT 0 +#define AUX_ANT 1 +#define MAIN_ANT_CG_TRX 1 +#define AUX_ANT_CG_TRX 0 +#define MAIN_ANT_CGCS_RX 0 +#define AUX_ANT_CGCS_RX 1 + +/*RF REG LIST*/ +#define DM_REG_RF_MODE_11N 0x00 +#define DM_REG_RF_0B_11N 0x0B +#define DM_REG_CHNBW_11N 0x18 +#define DM_REG_T_METER_11N 0x24 +#define DM_REG_RF_25_11N 0x25 +#define DM_REG_RF_26_11N 0x26 +#define DM_REG_RF_27_11N 0x27 +#define DM_REG_RF_2B_11N 0x2B +#define DM_REG_RF_2C_11N 0x2C +#define DM_REG_RXRF_A3_11N 0x3C +#define DM_REG_T_METER_92D_11N 0x42 +#define DM_REG_T_METER_88E_11N 0x42 + +/*BB REG LIST*/ +/*PAGE 8 */ +#define DM_REG_BB_CTRL_11N 0x800 +#define DM_REG_RF_PIN_11N 0x804 +#define DM_REG_PSD_CTRL_11N 0x808 +#define DM_REG_TX_ANT_CTRL_11N 0x80C +#define DM_REG_BB_PWR_SAV5_11N 0x818 +#define DM_REG_CCK_RPT_FORMAT_11N 0x824 +#define DM_REG_RX_DEFAULT_A_11N 0x858 +#define DM_REG_RX_DEFAULT_B_11N 0x85A +#define DM_REG_BB_PWR_SAV3_11N 0x85C +#define DM_REG_ANTSEL_CTRL_11N 0x860 +#define DM_REG_RX_ANT_CTRL_11N 0x864 +#define DM_REG_PIN_CTRL_11N 0x870 +#define DM_REG_BB_PWR_SAV1_11N 0x874 +#define DM_REG_ANTSEL_PATH_11N 0x878 +#define DM_REG_BB_3WIRE_11N 0x88C +#define DM_REG_SC_CNT_11N 0x8C4 +#define DM_REG_PSD_DATA_11N 0x8B4 +/*PAGE 9*/ +#define DM_REG_ANT_MAPPING1_11N 0x914 +#define DM_REG_ANT_MAPPING2_11N 0x918 +/*PAGE A*/ +#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define DM_REG_CCK_CCA_11N 0xA0A +#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define DM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define DM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define DM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define DM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define DM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define DM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define DM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define DM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define DM_REG_CCK_FA_RST_11N 0xA2C +#define DM_REG_CCK_FA_MSB_11N 0xA58 +#define DM_REG_CCK_FA_LSB_11N 0xA5C +#define DM_REG_CCK_CCA_CNT_11N 0xA60 +#define DM_REG_BB_PWR_SAV4_11N 0xA74 +/*PAGE B */ +#define DM_REG_LNA_SWITCH_11N 0xB2C +#define DM_REG_PATH_SWITCH_11N 0xB30 +#define DM_REG_RSSI_CTRL_11N 0xB38 +#define DM_REG_CONFIG_ANTA_11N 0xB68 +#define DM_REG_RSSI_BT_11N 0xB9C +/*PAGE C */ +#define DM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define DM_REG_RX_PATH_11N 0xC04 +#define DM_REG_TRMUX_11N 0xC08 +#define DM_REG_OFDM_FA_RSTC_11N 0xC0C +#define DM_REG_RXIQI_MATRIX_11N 0xC14 +#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define DM_REG_IGI_A_11N 0xC50 +#define DM_REG_ANTDIV_PARA2_11N 0xC54 +#define DM_REG_IGI_B_11N 0xC58 +#define DM_REG_ANTDIV_PARA3_11N 0xC5C +#define DM_REG_BB_PWR_SAV2_11N 0xC70 +#define DM_REG_RX_OFF_11N 0xC7C +#define DM_REG_TXIQK_MATRIXA_11N 0xC80 +#define DM_REG_TXIQK_MATRIXB_11N 0xC88 +#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define DM_REG_ANTDIV_PARA1_11N 0xCA4 +#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/*PAGE D */ +#define DM_REG_OFDM_FA_RSTD_11N 0xD00 +#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8 +/*PAGE E */ +#define DM_REG_TXAGC_A_6_18_11N 0xE00 +#define DM_REG_TXAGC_A_24_54_11N 0xE04 +#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define DM_REG_FPGA0_IQK_11N 0xE28 +#define DM_REG_TXIQK_TONE_A_11N 0xE30 +#define DM_REG_RXIQK_TONE_A_11N 0xE34 +#define DM_REG_TXIQK_PI_A_11N 0xE38 +#define DM_REG_RXIQK_PI_A_11N 0xE3C +#define DM_REG_TXIQK_11N 0xE40 +#define DM_REG_RXIQK_11N 0xE44 +#define DM_REG_IQK_AGC_PTS_11N 0xE48 +#define DM_REG_IQK_AGC_RSP_11N 0xE4C +#define DM_REG_BLUETOOTH_11N 0xE6C +#define DM_REG_RX_WAIT_CCA_11N 0xE70 +#define DM_REG_TX_CCK_RFON_11N 0xE74 +#define DM_REG_TX_CCK_BBON_11N 0xE78 +#define DM_REG_OFDM_RFON_11N 0xE7C +#define DM_REG_OFDM_BBON_11N 0xE80 +#define DM_REG_TX2RX_11N 0xE84 +#define DM_REG_TX2TX_11N 0xE88 +#define DM_REG_RX_CCK_11N 0xE8C +#define DM_REG_RX_OFDM_11N 0xED0 +#define DM_REG_RX_WAIT_RIFS_11N 0xED4 +#define DM_REG_RX2RX_11N 0xED8 +#define DM_REG_STANDBY_11N 0xEDC +#define DM_REG_SLEEP_11N 0xEE0 +#define DM_REG_PMPD_ANAEN_11N 0xEEC + +/*MAC REG LIST*/ +#define DM_REG_BB_RST_11N 0x02 +#define DM_REG_ANTSEL_PIN_11N 0x4C +#define DM_REG_EARLY_MODE_11N 0x4D0 +#define DM_REG_RSSI_MONITOR_11N 0x4FE +#define DM_REG_EDCA_VO_11N 0x500 +#define DM_REG_EDCA_VI_11N 0x504 +#define DM_REG_EDCA_BE_11N 0x508 +#define DM_REG_EDCA_BK_11N 0x50C +#define DM_REG_TXPAUSE_11N 0x522 +#define DM_REG_RESP_TX_11N 0x6D8 +#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + + +/*DIG Related*/ +#define DM_BIT_IGI_11N 0x0000007F + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 43 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x3e +#define DM_DIG_FA_LOWER 0x1e +#define DM_DIG_FA_TH0 0x200 +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 + +#define RXPATHSELECTION_SS_TH_W 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TXPWRTRACK_MAX_IDX 6 + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; + +}; + +enum FAT_STATE { + FAT_NORMAL_STATE = 0, + FAT_TRAINING_STATE = 1, +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum pwr_track_control_method { + BBSWING, + TXAGC +}; + +void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, + u8 *pdesc, u32 mac_id); +void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw, + u8 antsel_tr_mux, u32 mac_id, + u32 rx_pwdb_all); +void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t); +void rtl88e_dm_init(struct ieee80211_hw *hw); +void rtl88e_dm_watchdog(struct ieee80211_hw *hw); +void rtl88e_dm_write_dig(struct ieee80211_hw *hw); +void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw, + u8 type, u8 *pdirection, u32 *poutwrite_val); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c new file mode 100644 index 000000000..9a9f9e14f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c @@ -0,0 +1,721 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "../efuse.h" +#include "reg.h" +#include "def.h" +#include "fw.h" + +static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } +} + +static void _rtl88e_write_fw(struct ieee80211_hw *hw, + enum version_8188e version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *bufferptr = (u8 *)buffer; + u32 pagenums, remainsize; + u32 page, offset; + + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); + + rtl_fill_dummy(bufferptr, &size); + + pagenums = size / FW_8192C_PAGE_SIZE; + remainsize = size % FW_8192C_PAGE_SIZE; + + if (pagenums > 8) + pr_err("Page numbers should not greater then 8\n"); + + for (page = 0; page < pagenums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remainsize) { + offset = pagenums * FW_8192C_PAGE_SIZE; + page = pagenums; + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); + } +} + +static int _rtl88e_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + pr_err("chksum report fail! REG_MCUFWDL:0x%08x .\n", + value32); + goto exit; + } + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + rtl88e_firmware_selfreset(hw); + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) + return 0; + + udelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", + value32); + +exit: + return err; +} + +int rtl88e_download_fw(struct ieee80211_hw *hw, + bool buse_wake_on_wlan_fw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtlwifi_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8188e version = rtlhal->version; + + if (!rtlhal->pfirmware) + return 1; + + pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware; + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = rtlhal->pfirmware; + fwsize = rtlhal->fwsize; + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "normal Firmware SIZE %d\n", fwsize); + + if (IS_FW_HEADER_EXIST(pfwheader)) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Firmware Version(%d), Signature(%#x), Size(%d)\n", + pfwheader->version, pfwheader->signature, + (int)sizeof(struct rtlwifi_firmware_header)); + + pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); + fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); + } + + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + rtl88e_firmware_selfreset(hw); + } + _rtl88e_enable_fw_download(hw, true); + _rtl88e_write_fw(hw, version, pfwdata, fwsize); + _rtl88e_enable_fw_download(hw, false); + + err = _rtl88e_fw_free_to_go(hw); + if (err) + pr_err("Firmware is not ready to run!\n"); + + return 0; +} + +static bool _rtl88e_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + return true; + return false; +} + +static void _rtl88e_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, + u8 *cmd_b) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool write_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limit = 100; + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!write_sucess) { + wait_writeh2c_limit--; + if (wait_writeh2c_limit == 0) { + pr_err("Write H2C fail because no trigger for FW INT!\n"); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", boxnum); + break; + } + isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, + cmd_b + buf_index, cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), + cmd_b + buf_index+3, cmd_len-3); + memcpy((u8 *)(boxcontent) + 1, + cmd_b + buf_index, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", cmd_len); + break; + } + + write_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8188ee: error H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl88e_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + + return; +} + +void rtl88e_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2)))); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2))); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "8051Reset88E(): 8051 reset success\n"); + +} + +void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_88E_PWEMODE_LENGTH] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); + + set_h2ccmd_pwrmode_parm_mode(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM=2.*/ + set_h2ccmd_pwrmode_parm_rlbm(u1_h2c_set_pwrmode, rlbm); + set_h2ccmd_pwrmode_parm_smart_ps(u1_h2c_set_pwrmode, + (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1); + set_h2ccmd_pwrmode_parm_awake_interval(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + set_h2ccmd_pwrmode_parm_all_queue_uapsd(u1_h2c_set_pwrmode, 0); + if (mode == FW_PS_ACTIVE_MODE) + power_state |= FW_PWR_STATE_ACTIVE; + else + power_state |= FW_PWR_STATE_RF_OFF; + + set_h2ccmd_pwrmode_parm_pwr_state(u1_h2c_set_pwrmode, power_state); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_88E_PWEMODE_LENGTH); + rtl88e_fill_h2c_cmd(hw, H2C_88E_SETPWRMODE, + H2C_88E_PWEMODE_LENGTH, u1_h2c_set_pwrmode); +} + +void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = { 0 }; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl88e_fill_h2c_cmd(hw, H2C_88E_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} + +void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, + u8 ap_offload_enable) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 u1_apoffload_parm[H2C_88E_AP_OFFLOAD_LENGTH] = { 0 }; + + SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable); + SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid); + SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0); + + rtl88e_fill_h2c_cmd(hw, H2C_88E_AP_OFFLOAD, + H2C_88E_AP_OFFLOAD_LENGTH, u1_apoffload_parm); + +} + +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[5] = { 0 }; + bool b_dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *---------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1rsvdpageloc, 3); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3); + rtl88e_fill_h2c_cmd(hw, H2C_88E_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +/*Should check FW support p2p or not.*/ +static void rtl88e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = { ctwindow}; + + rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); + +} + +void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl88e_set_p2p_ctw_period_cmd(hw, ctwindow); + } + + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low+(50*1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_OFFLOAD, 1, + (u8 *)p2p_ps_offload); + +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h new file mode 100644 index 000000000..79f095e47 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_SIZE 0x8000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x5FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 3000 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((le16_to_cpu(_pfwhdr->signature) & 0xFFFF) == 0x88E1) +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_88E_RSVDPAGE_LOC_LEN 5 +#define H2C_88E_PWEMODE_LENGTH 5 +#define H2C_88E_JOINBSSRPT_LENGTH 1 +#define H2C_88E_AP_OFFLOAD_LENGTH 3 +#define H2C_88E_WOWLAN_LENGTH 3 +#define H2C_88E_KEEP_ALIVE_CTRL_LENGTH 3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_88E_REMOTE_WAKE_CTRL_LEN 1 +#else +#define H2C_88E_REMOTE_WAKE_CTRL_LEN 3 +#endif +#define H2C_88E_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_88E_AOAC_RSVDPAGE_LOC_LEN 7 + +/* Fw PS state for RPWM. +*BIT[2:0] = HW state +*BIT[3] = Protocol PS state, +*1: register active state , 0: register sleep state +*BIT[4] = sub-state +*/ +#define FW_PS_GO_ON BIT(0) +#define FW_PS_TX_NULL BIT(1) +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_DPS BIT(0) +#define FW_PS_LCLK (FW_PS_DPS) +#define FW_PS_RF_OFF BIT(1) +#define FW_PS_ALL_ON BIT(2) +#define FW_PS_ST_ACTIVE BIT(3) +#define FW_PS_ISR_ENABLE BIT(4) +#define FW_PS_IMR_ENABLE BIT(5) + + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + + /* 88E RPWM value*/ + /* BIT[0] = 1: 32k, 0: 40M*/ +#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/ +#define FW_PS_CLOCK_ON 0 /*40M*/ + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/ +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) +#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x)) +#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x)) +#define FW_PS_ISR_VAL(x) ((x) & 0x70) +#define FW_PS_IMR_MASK(x) ((x) & 0xDF) +#define FW_PS_KEEP_IMR(x) ((x) & 0x20) + +#define FW_PS_STATE_S0 (FW_PS_DPS) +#define FW_PS_STATE_S1 (FW_PS_LCLK) +#define FW_PS_STATE_S2 (FW_PS_RF_OFF) +#define FW_PS_STATE_S3 (FW_PS_ALL_ON) +#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON)) +/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/ +#define FW_PS_STATE_ALL_ON_88E (FW_PS_CLOCK_ON) +/* (FW_PS_RF_ON)*/ +#define FW_PS_STATE_RF_ON_88E (FW_PS_CLOCK_ON) +/* 0x0*/ +#define FW_PS_STATE_RF_OFF_88E (FW_PS_CLOCK_ON) +/* (FW_PS_STATE_RF_OFF)*/ +#define FW_PS_STATE_RF_OFF_LOW_PWR_88E (FW_PS_CLOCK_OFF) + +#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4) +#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3) +#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2) +#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1) + +/* For 88E H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) +#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON)) +#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON)) +#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE)) +#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40) + +#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) + +#define IS_IN_LOW_POWER_STATE_88E(fwpsstate) \ + (FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8188e_h2c_cmd { + H2C_88E_RSVDPAGE = 0, + H2C_88E_JOINBSSRPT = 1, + H2C_88E_SCAN = 2, + H2C_88E_KEEP_ALIVE_CTRL = 3, + H2C_88E_DISCONNECT_DECISION = 4, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_88E_WO_WLAN = 5, +#endif + H2C_88E_INIT_OFFLOAD = 6, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_88E_REMOTE_WAKE_CTRL = 7, +#endif + H2C_88E_AP_OFFLOAD = 8, + H2C_88E_BCN_RSVDPAGE = 9, + H2C_88E_PROBERSP_RSVDPAGE = 10, + + H2C_88E_SETPWRMODE = 0x20, + H2C_88E_PS_TUNING_PARA = 0x21, + H2C_88E_PS_TUNING_PARA2 = 0x22, + H2C_88E_PS_LPS_PARA = 0x23, + H2C_88E_P2P_PS_OFFLOAD = 024, + +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) + H2C_88E_WO_WLAN = 0x80, + H2C_88E_REMOTE_WAKE_CTRL = 0x81, + H2C_88E_AOAC_GLOBAL_INFO = 0x82, + H2C_88E_AOAC_RSVDPAGE = 0x83, +#endif + /*Not defined in new 88E H2C CMD Format*/ + H2C_88E_RA_MASK, + H2C_88E_SELECTIVE_SUSPEND_ROF_CMD, + H2C_88E_P2P_PS_MODE, + H2C_88E_PSD_RESULT, + /*Not defined CTW CMD for P2P yet*/ + H2C_88E_P2P_PS_CTW_CMD, + MAX_88E_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 2, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 3, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 4, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 5, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 6, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE(__cmd, 7, 1, __value) +#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value) +#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__cmd, __value) \ + SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value) + + +static inline void set_h2ccmd_pwrmode_parm_mode(u8 *__ph2ccmd, u8 __val) +{ + *(u8 *)(__ph2ccmd) = __val; +} + +static inline void set_h2ccmd_pwrmode_parm_rlbm(u8 *__cmd, u8 __value) +{ + u8p_replace_bits(__cmd + 1, __value, GENMASK(3, 0)); +} + +static inline void set_h2ccmd_pwrmode_parm_smart_ps(u8 *__cmd, u8 __value) +{ + u8p_replace_bits(__cmd + 1, __value, GENMASK(7, 4)); +} + +static inline void set_h2ccmd_pwrmode_parm_awake_interval(u8 *__cmd, u8 __value) +{ + *(u8 *)(__cmd + 2) = __value; +} + +static inline void set_h2ccmd_pwrmode_parm_all_queue_uapsd(u8 *__cmd, + u8 __value) +{ + *(u8 *)(__cmd + 3) = __value; +} + +static inline void set_h2ccmd_pwrmode_parm_pwr_state(u8 *__cmd, u8 __value) +{ + *(u8 *)(__cmd + 4) = __value; +} + +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val; + +/* AP_OFFLOAD */ +#define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \ + *(u8 *)__cmd = __value; +#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value; +#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__cmd, __value) \ + *(u8 *)(__cmd + 2) = __value; +#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__cmd, __value) \ + *(u8 *)(__cmd + 3) = __value; + +int rtl88e_download_fw(struct ieee80211_hw *hw, + bool buse_wake_on_wlan_fw); +void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer); +void rtl88e_firmware_selfreset(struct ieee80211_hw *hw); +void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, + u8 ap_offload_enable); +void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c new file mode 100644 index 000000000..53c32e1de --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -0,0 +1,2515 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "../pwrseqcmd.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "hw.h" +#include "pwrseq.h" + +#define LLT_CONFIG 5 + +static void _rtl88ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl88ee_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl88ee_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl88ee_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; + unsigned long flags; + + skb_queue_head_init(&free_list); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + __skb_queue_tail(&free_list, skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); +} + +static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw, + u8 rpwm_val, bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_support_remote_wake_up; + u32 count = 0, isr_regaddr, content; + bool schedule_timer = b_need_turn_off_ckk; + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&b_support_remote_wake_up)); + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + return; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + break; + } + } + + if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw, + u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + schedule_timer = true; + break; + } + } + + if (schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != + FW_PS_STATE_RF_OFF_LOW_PWR_88E) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + &rpwm_val); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } +} + +static void _rtl88ee_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK); + _rtl88ee_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl88ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR_88E; + _rtl88ee_set_fw_clock_off(hw, rpwm_val); +} + +void rtl88ee_fw_clk_off_timer_callback(struct timer_list *t) +{ + struct rtl_priv *rtlpriv = timer_container_of(rtlpriv, t, + works.fw_clockoff_timer); + struct ieee80211_hw *hw = rtlpriv->hw; + + _rtl88ee_set_fw_ps_rf_off_low_power(hw); +} + +static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON_88E|FW_PS_ACK);/* RF on */ + _rtl88ee_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + &fw_pwrmode); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + &fw_pwrmode); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } +} + +static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + &ppsc->fwctrl_psmode); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl88ee_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF_88E; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + &ppsc->fwctrl_psmode); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); + } +} + +void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + break; } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *)(val)) = tsf; + break; } + case HAL_DEF_WOWLAN: + break; + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *)val)[0]; + u8 rate_index = 0; + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (b_rate_cfg >> 8) & 0xff); + while (b_rate_cfg > 0x1) { + b_rate_cfg = (b_rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + &e_aci); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)*val; + reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2); + if (short_preamble) { + reg_tmp |= 0x02; + rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + + 2, reg_tmp); + } else { + reg_tmp |= 0xFD; + rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + + 2, reg_tmp); + } + break; } + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *val); + break; + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + + min_spacing_to_set = *val; + if (min_spacing_to_set <= 7) { + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *val; + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + + factor_toset = *val; + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + + } + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *val; + rtl88e_dm_init_edca_turbo(hw); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + &e_aci); + break; } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *val; + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = acm_ctrl | + ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + pr_err("switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; } + case HW_VAR_RCR: + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + break; + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = *val; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *val; + break; + case HW_VAR_IO_CMD: + rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7)); + } + break; } + case HW_VAR_H2C_FW_PWRMODE: + rtl88e_set_fw_pwrmode_cmd(hw, *val); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_RESUME_CLK_ON: + _rtl88ee_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION:{ + bool enter_fwlps = *((bool *)val); + + if (enter_fwlps) + _rtl88ee_fwlps_enter(hw); + else + _rtl88ee_fwlps_leave(hw); + + break; } + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = *val; + u8 tmp_regcr, tmp_reg422, bcnvalid_reg; + u8 count = 0, dlbcn_count = 0; + bool b_recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = + rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + if (tmp_reg422 & BIT(6)) + b_recover = true; + + do { + bcnvalid_reg = rtl_read_byte(rtlpriv, + REG_TDECTRL+2); + rtl_write_byte(rtlpriv, REG_TDECTRL+2, + (bcnvalid_reg | BIT(0))); + _rtl88ee_return_beacon_queue_skb(hw); + + rtl88e_set_fw_rsvdpagepkt(hw, 0); + bcnvalid_reg = rtl_read_byte(rtlpriv, + REG_TDECTRL+2); + count = 0; + while (!(bcnvalid_reg & BIT(0)) && count < 20) { + count++; + udelay(10); + bcnvalid_reg = + rtl_read_byte(rtlpriv, REG_TDECTRL+2); + } + dlbcn_count++; + } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + + if (bcnvalid_reg & BIT(0)) + rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0)); + + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) { + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + } + + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); + break; } + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl88e_set_p2p_ps_offload_cmd(hw, *val); + break; + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + break; } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = *val; + + if (btype_ibss) + _rtl88ee_stop_tx_beacon(hw); + + _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl88ee_resume_tx_beacon(hw); + break; } + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl88e_fill_h2c_cmd(hw, H2C_88E_KEEP_ALIVE_CTRL, + 2, array); + break; } + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +static bool _rtl88ee_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | + _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl88ee_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxpage; + bool status; + + maxpage = 0xAF; + txpktbuf_bndy = 0xAB; + + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x01); + rtl_write_dword(rtlpriv, REG_RQPN, 0x80730d29); + + /*0x2600 MaxRxBuff=10k-max(TxReportSize(64*8), WOLPattern(16*24)) */ + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x25FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl88ee_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + status = _rtl88ee_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = _rtl88ee_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + status = _rtl88ee_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + return true; +} + +static void _rtl88ee_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl88ee_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl88ee_sw_led_on(hw, pin0); + else + rtl88ee_sw_led_off(hw, pin0); +} + +static bool _rtl88ee_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 bytetmp; + u16 wordtmp; + + /*Disable XTAL OUTPUT for power saving. YJ,add,111206. */ + bytetmp = rtl_read_byte(rtlpriv, REG_XCK_OUT_CTRL) & (~BIT(0)); + rtl_write_byte(rtlpriv, REG_XCK_OUT_CTRL, bytetmp); + /*Auto Power Down to CHIP-off State*/ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7)); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + /* HW Power on sequence */ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, + PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, + RTL8188EE_NIC_ENABLE_FLOW)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "init MAC Fail as rtl_hal_pwrseqcmdparsing\n"); + return false; + } + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4); + rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp); + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp|BIT(2)); + + bytetmp = rtl_read_byte(rtlpriv, REG_WATCH_DOG+1); + rtl_write_byte(rtlpriv, REG_WATCH_DOG+1, bytetmp|BIT(7)); + + bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1, bytetmp|BIT(1)); + + bytetmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL); + rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, bytetmp|BIT(1)|BIT(0)); + rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL+1, 2); + rtl_write_word(rtlpriv, REG_TX_RPT_TIME, 0xcdf0); + + /*Add for wake up online*/ + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); + + rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp|BIT(3)); + bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG+1); + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+1, (bytetmp & (~BIT(4)))); + rtl_write_byte(rtlpriv, 0x367, 0x80); + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + rtl_write_byte(rtlpriv, REG_CR+1, 0x06); + rtl_write_byte(rtlpriv, MSR, 0x00); + + if (!rtlhal->mac_func_enable) { + if (!_rtl88ee_llt_table_init(hw)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "LLT table init fail\n"); + return false; + } + } + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xE771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + /* if we want to support 64 bit DMA, we should set it here, + * but now we do not support 64 bit DMA + */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0);/*Enable RX DMA */ + + if (rtlhal->earlymode_enable) {/*Early mode enable*/ + bytetmp = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL); + bytetmp |= 0x1f; + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, bytetmp); + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL+3, 0x81); + } + _rtl88ee_gen_refresh_led_state(hw); + return true; +} + +static void _rtl88ee_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_prsr; + + reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); +} + +static void _rtl88ee_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 tmp1byte = 0; + u32 tmp4byte = 0, count = 0; + + rtl_write_word(rtlpriv, 0x354, 0x8104); + rtl_write_word(rtlpriv, 0x358, 0x24); + + rtl_write_word(rtlpriv, 0x350, 0x70c); + rtl_write_byte(rtlpriv, 0x352, 0x2); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count = 0; + while (tmp1byte && count < 20) { + udelay(10); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count++; + } + if (0 == tmp1byte) { + tmp4byte = rtl_read_dword(rtlpriv, 0x34c); + rtl_write_dword(rtlpriv, 0x348, tmp4byte|BIT(31)); + rtl_write_word(rtlpriv, 0x350, 0xf70c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + } + + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count = 0; + while (tmp1byte && count < 20) { + udelay(10); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count++; + } + + rtl_write_word(rtlpriv, 0x350, 0x718); + rtl_write_byte(rtlpriv, 0x352, 0x2); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count = 0; + while (tmp1byte && count < 20) { + udelay(10); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count++; + } + + if (ppsc->support_backdoor || (0 == tmp1byte)) { + tmp4byte = rtl_read_dword(rtlpriv, 0x34c); + rtl_write_dword(rtlpriv, 0x348, tmp4byte|BIT(11)|BIT(12)); + rtl_write_word(rtlpriv, 0x350, 0xf718); + rtl_write_byte(rtlpriv, 0x352, 0x1); + } + + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count = 0; + while (tmp1byte && count < 20) { + udelay(10); + tmp1byte = rtl_read_byte(rtlpriv, 0x352); + count++; + } +} + +void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +int rtl88ee_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + int err = 0; + u8 tmp_u1b, u1byte; + unsigned long flags; + + rtlpriv->rtlhal.being_init_adapter = true; + /* As this function can take a very long time (up to 350 ms) + * and can be called with irqs disabled, reenable the irqs + * to let the other devices continue being serviced. + * + * It is safe doing so since our own interrupts will only be enabled + * in a subsequent step. + */ + local_save_flags(flags); + local_irq_enable(); + rtlhal->fw_ready = false; + + rtlpriv->intf_ops->disable_aspm(hw); + + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1); + u1byte = rtl_read_byte(rtlpriv, REG_CR); + if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) { + rtlhal->mac_func_enable = true; + } else { + rtlhal->mac_func_enable = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E; + } + + rtstatus = _rtl88ee_init_mac(hw); + if (!rtstatus) { + pr_info("Init MAC failed\n"); + err = 1; + goto exit; + } + + err = rtl88e_download_fw(hw, false); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + goto exit; + } + rtlhal->fw_ready = true; + /*fw related variable initialize */ + rtlhal->last_hmeboxnum = 0; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + ppsc->fw_current_inpsmode = false; + + rtl88e_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 + */ + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + + rtl88e_phy_bb_config(hw); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl88e_phy_rf_config(hw); + + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[0] = rtlphy->rfreg_chnlval[0] & 0xfff00fff; + + _rtl88ee_hw_configure(hw); + rtl_cam_reset_all_entry(hw); + rtl88ee_enable_hw_security_config(hw); + + rtlhal->mac_func_enable = true; + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl88ee_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + if (ppsc->rfpwr_state == ERFON) { + if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) || + ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) && + (rtlhal->oem_id == RT_CID_819X_HP))) { + rtl88e_phy_set_rfpath_switch(hw, true); + rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT; + } else { + rtl88e_phy_set_rfpath_switch(hw, false); + rtlpriv->dm.fat_table.rx_idle_ant = AUX_ANT; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "rx idle ant %s\n", + (rtlpriv->dm.fat_table.rx_idle_ant == MAIN_ANT) ? + ("MAIN_ANT") : ("AUX_ANT")); + + if (rtlphy->iqk_initialized) { + rtl88e_phy_iq_calibrate(hw, true); + } else { + rtl88e_phy_iq_calibrate(hw, false); + rtlphy->iqk_initialized = true; + } + + rtl88e_dm_check_txpower_tracking(hw); + rtl88e_phy_lc_calibrate(hw); + } + + tmp_u1b = efuse_read_1byte(hw, 0x1FA); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n"); + } + + if (!(tmp_u1b & BIT(4))) { + tmp_u1b = rtl_read_byte(rtlpriv, 0x16); + tmp_u1b &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); + udelay(10); + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "under 1.5V\n"); + } + rtl_write_byte(rtlpriv, REG_NAV_CTRL+2, ((30000+127)/128)); + rtl88e_dm_init(hw); +exit: + local_irq_restore(flags); + rtlpriv->rtlhal.being_init_adapter = false; + return err; +} + +static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8188e version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + version = (enum version_8188e) VERSION_TEST_CHIP_88E; + } else { + version = NORMAL_CHIP; + version = version | ((value32 & TYPE_ID) ? RF_TYPE_2T2R : 0); + version = version | ((value32 & VENDOR_ID) ? + CHIP_VENDOR_UMC : 0); + } + + rtlphy->rf_type = RF_1T1R; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl88ee_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl88ee_stop_tx_beacon(hw); + _rtl88ee_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl88ee_resume_tx_beacon(hw); + _rtl88ee_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, MSR, bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + } + +} + +int rtl88ee_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl88ee_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP && + type != NL80211_IFTYPE_MESH_POINT) + rtl88ee_set_check_bssid(hw, true); + } else { + rtl88ee_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here + * because mac80211 will send pkt when scan + */ +void rtl88ee_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl88e_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8188ee: invalid aci: %d !\n", aci); + break; + } +} + +void rtl88ee_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, + rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, + rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; + /* there are some C2H CMDs have been sent + * before system interrupt is enabled, e.g., C2H, CPWM. + * So we need to clear all C2H events that FW has notified, + * otherwise FW won't schedule any commands anymore. + */ + rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0); + /*enable system interrupt*/ + rtl_write_dword(rtlpriv, REG_HSIMR, + rtlpci->sys_irq_mask & 0xFFFFFFFF); +} + +void rtl88ee_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + u32 count = 0; + rtlhal->mac_func_enable = false; + rtlpriv->intf_ops->enable_aspm(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n"); + u1b_tmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL); + rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, u1b_tmp & (~BIT(1))); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + while (!(u1b_tmp & BIT(1)) && (count++ < 100)) { + udelay(10); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + count++; + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF); + + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, + RTL8188EE_NIC_LPS_ENTER_FLOW); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) + rtl88e_firmware_selfreset(hw); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL); + rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0)))); + + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8188EE_NIC_DISABLE_FLOW); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3)))); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(3))); + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); + + u1b_tmp = rtl_read_byte(rtlpriv, GPIO_IN); + rtl_write_byte(rtlpriv, GPIO_OUT, u1b_tmp); + rtl_write_byte(rtlpriv, GPIO_IO_SEL, 0x7F); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL, (u1b_tmp << 4) | u1b_tmp); + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL+1); + rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL+1, u1b_tmp | 0x0F); + + rtl_write_dword(rtlpriv, REG_GPIO_IO_SEL_2+2, 0x00080808); +} + +void rtl88ee_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8188ee card disable\n"); + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + + _rtl88ee_set_media_status(hw, opmode); + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl88ee_poweroff_adapter(hw); + + /* after power off we should do iqk again */ + rtlpriv->phy.iqk_initialized = false; +} + +void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); + + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); + +} + +void rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl88ee_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtlpci->reg_bcn_ctrl_val |= BIT(3); + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); + /*rtl88ee_enable_interrupt(hw);*/ +} + +void rtl88ee_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + /*rtl88ee_disable_interrupt(hw);*/ + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + /*rtl88ee_enable_interrupt(hw);*/ +} + +void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl88ee_disable_interrupt(hw); + rtl88ee_enable_interrupt(hw); +} + +static u8 _rtl88e_get_chnl_group(u8 chnl) +{ + u8 group = 0; + + if (chnl < 3) + group = 0; + else if (chnl < 6) + group = 1; + else if (chnl < 9) + group = 2; + else if (chnl < 12) + group = 3; + else if (chnl < 14) + group = 4; + else if (chnl == 14) + group = 5; + + return group; +} + +static void set_24g_base(struct txpower_info_2g *pwrinfo24g, u32 rfpath) +{ + int group, txcnt; + + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwrinfo24g->index_cck_base[rfpath][group] = 0x2D; + pwrinfo24g->index_bw40_base[rfpath][group] = 0x2D; + } + for (txcnt = 0; txcnt < MAX_TX_COUNT; txcnt++) { + if (txcnt == 0) { + pwrinfo24g->bw20_diff[rfpath][0] = 0x02; + pwrinfo24g->ofdm_diff[rfpath][0] = 0x04; + } else { + pwrinfo24g->bw20_diff[rfpath][txcnt] = 0xFE; + pwrinfo24g->bw40_diff[rfpath][txcnt] = 0xFE; + pwrinfo24g->cck_diff[rfpath][txcnt] = 0xFE; + pwrinfo24g->ofdm_diff[rfpath][txcnt] = 0xFE; + } + } +} + +static void read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pwrinfo24g, + struct txpower_info_5g *pwrinfo5g, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 rfpath, eeaddr = EEPROM_TX_PWR_INX, group, txcnt = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM88E():PROMContent[0x%x]=0x%x\n", + (eeaddr + 1), hwinfo[eeaddr + 1]); + if (0xFF == hwinfo[eeaddr+1]) /*YJ,add,120316*/ + autoload_fail = true; + + if (autoload_fail) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) { + /* 2.4G default value */ + set_24g_base(pwrinfo24g, rfpath); + } + return; + } + + for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) { + /*2.4G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwrinfo24g->index_cck_base[rfpath][group] = + hwinfo[eeaddr++]; + if (pwrinfo24g->index_cck_base[rfpath][group] == 0xFF) + pwrinfo24g->index_cck_base[rfpath][group] = + 0x2D; + } + for (group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++) { + pwrinfo24g->index_bw40_base[rfpath][group] = + hwinfo[eeaddr++]; + if (pwrinfo24g->index_bw40_base[rfpath][group] == 0xFF) + pwrinfo24g->index_bw40_base[rfpath][group] = + 0x2D; + } + pwrinfo24g->bw40_diff[rfpath][0] = 0; + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->bw20_diff[rfpath][0] = 0x02; + } else { + pwrinfo24g->bw20_diff[rfpath][0] = + (hwinfo[eeaddr]&0xf0)>>4; + /*bit sign number to 8 bit sign number*/ + if (pwrinfo24g->bw20_diff[rfpath][0] & BIT(3)) + pwrinfo24g->bw20_diff[rfpath][0] |= 0xF0; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->ofdm_diff[rfpath][0] = 0x04; + } else { + pwrinfo24g->ofdm_diff[rfpath][0] = + (hwinfo[eeaddr]&0x0f); + /*bit sign number to 8 bit sign number*/ + if (pwrinfo24g->ofdm_diff[rfpath][0] & BIT(3)) + pwrinfo24g->ofdm_diff[rfpath][0] |= 0xF0; + } + pwrinfo24g->cck_diff[rfpath][0] = 0; + eeaddr++; + for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) { + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->bw40_diff[rfpath][txcnt] = 0xFE; + } else { + pwrinfo24g->bw40_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0xf0)>>4; + if (pwrinfo24g->bw40_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo24g->bw40_diff[rfpath][txcnt] |= + 0xF0; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->bw20_diff[rfpath][txcnt] = + 0xFE; + } else { + pwrinfo24g->bw20_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0x0f); + if (pwrinfo24g->bw20_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo24g->bw20_diff[rfpath][txcnt] |= + 0xF0; + } + eeaddr++; + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->ofdm_diff[rfpath][txcnt] = 0xFE; + } else { + pwrinfo24g->ofdm_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0xf0)>>4; + if (pwrinfo24g->ofdm_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo24g->ofdm_diff[rfpath][txcnt] |= + 0xF0; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo24g->cck_diff[rfpath][txcnt] = 0xFE; + } else { + pwrinfo24g->cck_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0x0f); + if (pwrinfo24g->cck_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo24g->cck_diff[rfpath][txcnt] |= + 0xF0; + } + eeaddr++; + } + + /*5G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) { + pwrinfo5g->index_bw40_base[rfpath][group] = + hwinfo[eeaddr++]; + if (pwrinfo5g->index_bw40_base[rfpath][group] == 0xFF) + pwrinfo5g->index_bw40_base[rfpath][group] = + 0xFE; + } + + pwrinfo5g->bw40_diff[rfpath][0] = 0; + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo5g->bw20_diff[rfpath][0] = 0; + } else { + pwrinfo5g->bw20_diff[rfpath][0] = + (hwinfo[eeaddr]&0xf0)>>4; + if (pwrinfo5g->bw20_diff[rfpath][0] & BIT(3)) + pwrinfo5g->bw20_diff[rfpath][0] |= 0xF0; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo5g->ofdm_diff[rfpath][0] = 0x04; + } else { + pwrinfo5g->ofdm_diff[rfpath][0] = (hwinfo[eeaddr]&0x0f); + if (pwrinfo5g->ofdm_diff[rfpath][0] & BIT(3)) + pwrinfo5g->ofdm_diff[rfpath][0] |= 0xF0; + } + eeaddr++; + for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) { + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo5g->bw40_diff[rfpath][txcnt] = 0xFE; + } else { + pwrinfo5g->bw40_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0xf0)>>4; + if (pwrinfo5g->bw40_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo5g->bw40_diff[rfpath][txcnt] |= + 0xF0; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo5g->bw20_diff[rfpath][txcnt] = 0xFE; + } else { + pwrinfo5g->bw20_diff[rfpath][txcnt] = + (hwinfo[eeaddr]&0x0f); + if (pwrinfo5g->bw20_diff[rfpath][txcnt] & + BIT(3)) + pwrinfo5g->bw20_diff[rfpath][txcnt] |= + 0xF0; + } + eeaddr++; + } + + if (hwinfo[eeaddr] == 0xFF) { + pwrinfo5g->ofdm_diff[rfpath][1] = 0xFE; + pwrinfo5g->ofdm_diff[rfpath][2] = 0xFE; + } else { + pwrinfo5g->ofdm_diff[rfpath][1] = + (hwinfo[eeaddr]&0xf0)>>4; + pwrinfo5g->ofdm_diff[rfpath][2] = + (hwinfo[eeaddr]&0x0f); + } + eeaddr++; + + if (hwinfo[eeaddr] == 0xFF) + pwrinfo5g->ofdm_diff[rfpath][3] = 0xFE; + else + pwrinfo5g->ofdm_diff[rfpath][3] = (hwinfo[eeaddr]&0x0f); + eeaddr++; + + for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) { + if (pwrinfo5g->ofdm_diff[rfpath][txcnt] == 0xFF) + pwrinfo5g->ofdm_diff[rfpath][txcnt] = 0xFE; + else if (pwrinfo5g->ofdm_diff[rfpath][txcnt] & BIT(3)) + pwrinfo5g->ofdm_diff[rfpath][txcnt] |= 0xF0; + } + } +} + +static noinline_for_stack void +_rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwrinfo24g; + struct txpower_info_5g pwrinfo5g; + u8 rf_path, index; + u8 i; + + read_power_value_fromprom(hw, &pwrinfo24g, + &pwrinfo5g, autoload_fail, hwinfo); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl88e_get_chnl_group(i+1); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + pwrinfo24g.index_cck_base[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pwrinfo24g.index_bw40_base[rf_path][index]; + rtlefuse->txpwr_ht20diff[rf_path][i] = + pwrinfo24g.bw20_diff[rf_path][0]; + rtlefuse->txpwr_legacyhtdiff[rf_path][i] = + pwrinfo24g.ofdm_diff[rf_path][0]; + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i]); + } + } + + if (!autoload_fail) + rtlefuse->eeprom_thermalmeter = + hwinfo[EEPROM_THERMAL_METER_88E]; + else + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + + if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) { + rtlefuse->apk_thermalmeterignore = true; + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + } + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + + if (!autoload_fail) { + rtlefuse->eeprom_regulatory = + hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/ + if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) + rtlefuse->eeprom_regulatory = 0; + } else { + rtlefuse->eeprom_regulatory = 0; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); +} + +static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int params[] = {RTL8188E_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13}; + u8 *hwinfo; + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + if (rtlefuse->eeprom_oemid == 0xFF) + rtlefuse->eeprom_oemid = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + /*tx power*/ + _rtl88ee_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + rtlefuse->txpwr_fromeprom = true; + + rtl8188ee_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + + /*board type*/ + rtlefuse->board_type = + ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5); + rtlhal->board_type = rtlefuse->board_type; + /*Wake on wlan*/ + rtlefuse->wowlan_enable = + ((hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & 0x40) >> 6); + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_88E]; + if (hwinfo[EEPROM_XTAL_88E]) + rtlefuse->crystalcap = 0x20; + /*antenna diversity*/ + rtlefuse->antenna_div_cfg = + (hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3; + if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) + rtlefuse->antenna_div_cfg = 0; + if (rtlpriv->btcoexist.eeprom_bt_coexist != 0 && + rtlpriv->btcoexist.eeprom_bt_ant_num == ANT_X1) + rtlefuse->antenna_div_cfg = 0; + + rtlefuse->antenna_div_type = hwinfo[EEPROM_RF_ANTENNA_OPT_88E]; + if (rtlefuse->antenna_div_type == 0xFF) + rtlefuse->antenna_div_type = 0x01; + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV || + rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtlefuse->antenna_div_cfg = 1; + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8179) { + if (rtlefuse->eeprom_svid == 0x1025) { + rtlhal->oem_id = RT_CID_819X_ACER; + } else if ((rtlefuse->eeprom_svid == 0x10EC && + rtlefuse->eeprom_smid == 0x0179) || + (rtlefuse->eeprom_svid == 0x17AA && + rtlefuse->eeprom_smid == 0x0179)) { + rtlhal->oem_id = RT_CID_819X_LENOVO; + } else if (rtlefuse->eeprom_svid == 0x103c && + rtlefuse->eeprom_smid == 0x197d) { + rtlhal->oem_id = RT_CID_819X_HP; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + + } + } +exit: + kfree(hwinfo); +} + +static void _rtl88ee_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpriv->ledctl.led_opendrain = true; + + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl88ee_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl88ee_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl88ee_hal_customized_behavior(hw); +} + +static void rtl88ee_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 b_nmode = mac->ht_enable; + /*u8 mimo_ps = IEEE80211_SMPS_OFF;*/ + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + u32 ratr_mask; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + b_nmode = 1; + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) && + (rtlpriv->btcoexist.bt_cur_state) && + (rtlpriv->btcoexist.bt_ant_isolation) && + ((rtlpriv->btcoexist.bt_service == BT_SCO) || + (rtlpriv->btcoexist.bt_service == BT_BUSY))) + ratr_value &= 0x0fffcfc0; + else + ratr_value &= 0x0FFFFFFF; + + if (b_nmode && + ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool b_shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + /*u8 mimo_ps = IEEE80211_SMPS_OFF;*/ + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f8ff000; + else + ratr_bitmap &= 0x0f8ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f8ff000; + else + ratr_bitmap &= 0x0f8ff005; + } + } + /*}*/ + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + + if (macid == 0) + b_shortgi = true; + else if (macid == 1) + b_shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4]); + rtl88e_fill_h2c_cmd(hw, H2C_88E_RA_MASK, 5, rate_mask); + _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl88ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl88ee_update_hal_rate_table(hw, sta); +} + +void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate e_rfpowerstate_toset; + u32 u4tmp; + bool b_actuallyset = false; + + if (rtlpriv->rtlhal.being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + u4tmp = rtl_read_dword(rtlpriv, REG_GPIO_OUTPUT); + e_rfpowerstate_toset = (u4tmp & BIT(31)) ? ERFON : ERFOFF; + + if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + b_actuallyset = true; + } else if ((!ppsc->hwradiooff) && + (e_rfpowerstate_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + *valid = 1; + return !ppsc->hwradiooff; + +} + +void rtl88ee_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + pr_err("switch case %#x not processed\n", + enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + entry_id = + rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} + +static void rtl8188ee_bt_var_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->btcoexist.bt_coexistence = + rtlpriv->btcoexist.eeprom_bt_coexist; + rtlpriv->btcoexist.bt_ant_num = rtlpriv->btcoexist.eeprom_bt_ant_num; + rtlpriv->btcoexist.bt_coexist_type = rtlpriv->btcoexist.eeprom_bt_type; + + if (rtlpriv->btcoexist.reg_bt_iso == 2) + rtlpriv->btcoexist.bt_ant_isolation = + rtlpriv->btcoexist.eeprom_bt_ant_isol; + else + rtlpriv->btcoexist.bt_ant_isolation = + rtlpriv->btcoexist.reg_bt_iso; + + rtlpriv->btcoexist.bt_radio_shared_type = + rtlpriv->btcoexist.eeprom_bt_radio_shared; + + if (rtlpriv->btcoexist.bt_coexistence) { + if (rtlpriv->btcoexist.reg_bt_sco == 1) + rtlpriv->btcoexist.bt_service = BT_OTHER_ACTION; + else if (rtlpriv->btcoexist.reg_bt_sco == 2) + rtlpriv->btcoexist.bt_service = BT_SCO; + else if (rtlpriv->btcoexist.reg_bt_sco == 4) + rtlpriv->btcoexist.bt_service = BT_BUSY; + else if (rtlpriv->btcoexist.reg_bt_sco == 5) + rtlpriv->btcoexist.bt_service = BT_OTHERBUSY; + else + rtlpriv->btcoexist.bt_service = BT_IDLE; + + rtlpriv->btcoexist.bt_edca_ul = 0; + rtlpriv->btcoexist.bt_edca_dl = 0; + rtlpriv->btcoexist.bt_rssi_state = 0xff; + } +} + +void rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + + if (!auto_load_fail) { + rtlpriv->btcoexist.eeprom_bt_coexist = + ((hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & 0xe0) >> 5); + if (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] == 0xFF) + rtlpriv->btcoexist.eeprom_bt_coexist = 0; + value = hwinfo[EEPROM_RF_BT_SETTING_88E]; + rtlpriv->btcoexist.eeprom_bt_type = ((value & 0xe) >> 1); + rtlpriv->btcoexist.eeprom_bt_ant_num = (value & 0x1); + rtlpriv->btcoexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4); + rtlpriv->btcoexist.eeprom_bt_radio_shared = + ((value & 0x20) >> 5); + } else { + rtlpriv->btcoexist.eeprom_bt_coexist = 0; + rtlpriv->btcoexist.eeprom_bt_type = BT_2WIRE; + rtlpriv->btcoexist.eeprom_bt_ant_num = ANT_X2; + rtlpriv->btcoexist.eeprom_bt_ant_isol = 0; + rtlpriv->btcoexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; + } + + rtl8188ee_bt_var_init(hw); +} + +void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 u1_tmp; + + if (rtlpriv->btcoexist.bt_coexistence && + ((rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) || + rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC8)) { + if (rtlpriv->btcoexist.bt_ant_isolation) + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + + u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) & BIT(0); + u1_tmp = u1_tmp | + ((rtlpriv->btcoexist.bt_ant_isolation == 1) ? + 0 : BIT((1)) | + ((rtlpriv->btcoexist.bt_service == BT_SCO) ? + 0 : BIT(2))); + rtl_write_byte(rtlpriv, 0x4fd, u1_tmp); + + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa); + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040); + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010); + + /* Config to 1T1R. */ + if (rtlphy->rf_type == RF_1T1R) { + u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE); + u1_tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp); + + u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE); + u1_tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp); + } + } +} + +void rtl88ee_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl88ee_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h new file mode 100644 index 000000000..fd09b0712 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92CE_HW_H__ +#define __RTL92CE_HW_H__ + +void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw); +void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl88ee_hw_init(struct ieee80211_hw *hw); +void rtl88ee_card_disable(struct ieee80211_hw *hw); +void rtl88ee_enable_interrupt(struct ieee80211_hw *hw); +void rtl88ee_disable_interrupt(struct ieee80211_hw *hw); +int rtl88ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl88ee_set_qos(struct ieee80211_hw *hw, int aci); +void rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl88ee_set_beacon_interval(struct ieee80211_hw *hw); +void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl88ee_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +void rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw); +void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw); +void rtl88ee_suspend(struct ieee80211_hw *hw); +void rtl88ee_resume(struct ieee80211_hw *hw); +void rtl88ee_fw_clk_off_timer_callback(struct timer_list *t); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c new file mode 100644 index 000000000..b57ba4590 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl88ee_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +void rtl88ee_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) { + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, + (ledcfg & 0xFE)); + } else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + ledcfg &= 0x10; + rtl_write_byte(rtlpriv, REG_LEDCFG1, (ledcfg | BIT(3))); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl88ee_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl88ee_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl88ee_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl88ee_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", + ledaction); + _rtl88ee_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h new file mode 100644 index 000000000..e5cc35d4c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl88ee_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl88ee_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl88ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c new file mode 100644 index 000000000..0fab3a0c7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c @@ -0,0 +1,2293 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" + +static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); +static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw, + u8 configtype); +static void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +static bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, u32 para1, + u32 para2, u32 msdelay); +static bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); + +static long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl88e_phy_set_io(struct ieee80211_hw *hw); + +u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, + regaddr, originalvalue); + + return returnvalue; + +} + +void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} + +u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + + original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + return readback_value; +} + +void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl88e_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + + _rtl88e_phy_rf_serial_write(hw, rfpath, regaddr, data); + + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0xff; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + pr_err("return all one\n"); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + udelay(10); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + udelay(120); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSIREADBACKDATA); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); + return retvalue; +} + +static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + pr_err("stop\n"); + return; + } + offset &= 0xff; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); +} + +bool rtl88e_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = _rtl88e_phy_config_mac_with_headerfile(hw); + + rtl_write_byte(rtlpriv, 0x04CA, 0x0B); + return rtstatus; +} + +bool rtl88e_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u8 b_reg_hwparafile = 1; + u32 tmp; + _rtl88e_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTN | FEN_BBRSTB); + tmp = rtl_read_dword(rtlpriv, 0x4c); + rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); + if (b_reg_hwparafile == 1) + rtstatus = _rtl88e_phy_bb8188e_config_parafile(hw); + return rtstatus; +} + +bool rtl88e_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl88e_phy_rf6052_config(hw); +} + +static bool _rtl88e_check_condition(struct ieee80211_hw *hw, + const u32 condition) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 _board = rtlefuse->board_type; /*need efuse define*/ + u32 _interface = rtlhal->interface; + u32 _platform = 0x08;/*SupportPlatform */ + u32 cond; + + if (condition == 0xCDCDCDCD) + return true; + + cond = condition & 0xFF; + if ((_board & cond) == 0 && cond != 0x1F) + return false; + + cond = condition & 0xFF00; + cond = cond >> 8; + if ((_interface & cond) == 0 && cond != 0x07) + return false; + + cond = condition & 0xFF0000; + cond = cond >> 16; + if ((_platform & cond) == 0 && cond != 0x0F) + return false; + return true; +} + +static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw, u32 addr, + u32 data, enum radio_path rfpath, + u32 regaddr) +{ + if (addr == 0xffe) { + mdelay(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + rtl_set_rfreg(hw, rfpath, regaddr, + RFREG_OFFSET_MASK, + data); + udelay(1); + } +} + +static void _rtl8188e_config_rf_radio_a(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1000; /*RF Content: radio_a_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl8188e_config_rf_reg(hw, addr, data, RF90_PATH_A, + addr | maskforphyset); +} + +static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + if (addr == 0xfe) { + mdelay(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + rtl_set_bbreg(hw, addr, MASKDWORD, data); + udelay(1); + } +} + +static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + rtstatus = phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + + if (!rtlefuse->autoload_failflag) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = + phy_config_bb_with_pghdr(hw, BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = + phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = + (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200)); + + return true; +} + +static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8188EMACPHY_Array\n"); + arraylength = RTL8188EEMAC_1T_ARRAYLEN; + ptrarray = RTL8188EEMAC_1T_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Img:RTL8188EEMAC_1T_ARRAY LEN %d\n", arraylength); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); + return true; +} + +#define READ_NEXT_PAIR(v1, v2, i) \ + do { \ + i += 2; v1 = array_table[i]; \ + v2 = array_table[i+1]; \ + } while (0) + +static void handle_branch1(struct ieee80211_hw *hw, u16 arraylen, + u32 *array_table) +{ + u32 v1; + u32 v2; + int i; + + for (i = 0; i < arraylen; i = i + 2) { + v1 = array_table[i]; + v2 = array_table[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl8188e_config_bb_reg(hw, v1, v2); + } else { /*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= arraylen - 2) + break; + + if (!_rtl88e_check_condition(hw, array_table[i])) { + /*Discard the following (offset, data) pairs*/ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + i -= 2; /* prevent from for-loop += 2*/ + } else { /* Configure matched pairs and skip + * to end of if-else. + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < arraylen - 2) { + _rtl8188e_config_bb_reg(hw, v1, v2); + READ_NEXT_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + } + } + } +} + +static void handle_branch2(struct ieee80211_hw *hw, u16 arraylen, + u32 *array_table) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 v1; + u32 v2; + int i; + + for (i = 0; i < arraylen; i = i + 2) { + v1 = array_table[i]; + v2 = array_table[i+1]; + if (v1 < 0xCDCDCDCD) { + rtl_set_bbreg(hw, array_table[i], MASKDWORD, + array_table[i + 1]); + udelay(1); + continue; + } else { /*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= arraylen - 2) + break; + + if (!_rtl88e_check_condition(hw, array_table[i])) { + /*Discard the following (offset, data) pairs*/ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + i -= 2; /* prevent from for-loop += 2*/ + } else { /* Configure matched pairs and skip + * to end of if-else. + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < arraylen - 2) { + rtl_set_bbreg(hw, array_table[i], + MASKDWORD, + array_table[i + 1]); + udelay(1); + READ_NEXT_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + } + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", + array_table[i], array_table[i + 1]); + } +} + +static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + u32 *array_table; + u16 arraylen; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + arraylen = RTL8188EEPHY_REG_1TARRAYLEN; + array_table = RTL8188EEPHY_REG_1TARRAY; + handle_branch1(hw, arraylen, array_table); + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + arraylen = RTL8188EEAGCTAB_1TARRAYLEN; + array_table = RTL8188EEAGCTAB_1TARRAY; + handle_branch2(hw, arraylen, array_table); + } + return true; +} + +static void store_pwrindex_rate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + int count = rtlphy->pwrgroup_cnt; + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[count][0] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][0]); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[count][1] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][1]); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[count][6] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][6]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[count][7] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][7]); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[count][2] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][2]); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[count][3] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][3]); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[count][4] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][4]); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[count][5] = data; + if (get_rf_type(rtlphy) == RF_1T1R) { + count++; + rtlphy->pwrgroup_cnt = count; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][5]); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[count][8] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][8]); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[count][9] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][9]); + } + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[count][14] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][14]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[count][15] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][15]); + } + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[count][10] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][10]); + } + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[count][11] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][11]); + } + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[count][12] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][12]); + } + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[count][13] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + count, + rtlphy->mcs_txpwrlevel_origoffset[count][13]); + if (get_rf_type(rtlphy) != RF_1T1R) { + count++; + rtlphy->pwrgroup_cnt = count; + } + } +} + +static bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw, u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_reg_page; + u16 phy_reg_page_len; + u32 v1 = 0, v2 = 0; + + phy_reg_page_len = RTL8188EEPHY_REG_ARRAY_PGLEN; + phy_reg_page = RTL8188EEPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_page_len; i = i + 3) { + v1 = phy_reg_page[i]; + v2 = phy_reg_page[i+1]; + + if (v1 < 0xcdcdcdcd) { + if (phy_reg_page[i] == 0xfe) + mdelay(50); + else if (phy_reg_page[i] == 0xfd) + mdelay(5); + else if (phy_reg_page[i] == 0xfc) + mdelay(1); + else if (phy_reg_page[i] == 0xfb) + udelay(50); + else if (phy_reg_page[i] == 0xfa) + udelay(5); + else if (phy_reg_page[i] == 0xf9) + udelay(1); + + store_pwrindex_rate_offset(hw, phy_reg_page[i], + phy_reg_page[i + 1], + phy_reg_page[i + 2]); + continue; + } else { + if (!_rtl88e_check_condition(hw, + phy_reg_page[i])) { + /*don't need the hw_body*/ + i += 2; /* skip the pair of expression*/ + /* to protect 'i+1' 'i+2' not overrun */ + if (i >= phy_reg_page_len - 2) + break; + + v1 = phy_reg_page[i]; + v2 = phy_reg_page[i+1]; + while (v2 != 0xDEAD && + i < phy_reg_page_len - 5) { + i += 3; + v1 = phy_reg_page[i]; + v2 = phy_reg_page[i+1]; + } + } + } + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +#define READ_NEXT_RF_PAIR(v1, v2, i) \ +do { \ + i += 2; \ + v1 = radioa_array_table[i]; \ + v2 = radioa_array_table[i+1]; \ +} while (0) + +static void process_path_a(struct ieee80211_hw *hw, + u16 radioa_arraylen, + u32 *radioa_array_table) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 v1, v2; + int i; + + for (i = 0; i < radioa_arraylen; i = i + 2) { + v1 = radioa_array_table[i]; + v2 = radioa_array_table[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl8188e_config_rf_radio_a(hw, v1, v2); + } else { /*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= radioa_arraylen - 2) + break; + + if (!_rtl88e_check_condition(hw, radioa_array_table[i])) { + /*Discard the following (offset, data) pairs*/ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < radioa_arraylen - 2) { + READ_NEXT_RF_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + } else { /* Configure matched pairs and + * skip to end of if-else. + */ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < radioa_arraylen - 2) { + _rtl8188e_config_rf_radio_a(hw, v1, v2); + READ_NEXT_RF_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && + i < radioa_arraylen - 2) + READ_NEXT_RF_PAIR(v1, v2, i); + } + } + } + + if (rtlhal->oem_id == RT_CID_819X_HP) + _rtl8188e_config_rf_radio_a(hw, 0x52, 0x7E4BD); +} + +bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 *radioa_array_table; + u16 radioa_arraylen; + + radioa_arraylen = RTL8188EE_RADIOA_1TARRAYLEN; + radioa_array_table = RTL8188EE_RADIOA_1TARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Radio_A:RTL8188EE_RADIOA_1TARRAY %d\n", radioa_arraylen); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + process_path_a(hw, radioa_arraylen, radioa_array_table); + break; + case RF90_PATH_B: + case RF90_PATH_C: + case RF90_PATH_D: + break; + } + return true; +} + +void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, + MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, + MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +static void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = + RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; +} + +void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl88e_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl88e_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl88e_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void handle_path_a(struct rtl_efuse *rtlefuse, u8 index, + u8 *cckpowerlevel, u8 *ofdmpowerlevel, + u8 *bw20powerlevel, u8 *bw40powerlevel) +{ + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + /*-8~7 */ + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][index] > 0x0f) + bw20powerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] - + (~(rtlefuse->txpwr_ht20diff[RF90_PATH_A][index]) + 1); + else + bw20powerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] + + rtlefuse->txpwr_ht20diff[RF90_PATH_A][index]; + if (rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index] > 0xf) + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] - + (~(rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index])+1); + else + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index]; + bw40powerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; +} + +static void _rtl88e_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel, + u8 *bw20powerlevel, u8 *bw40powerlevel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + u8 rf_path = 0; + + for (rf_path = 0; rf_path < 2; rf_path++) { + if (rf_path == RF90_PATH_A) { + handle_path_a(rtlefuse, index, cckpowerlevel, + ofdmpowerlevel, bw20powerlevel, + bw40powerlevel); + } else if (rf_path == RF90_PATH_B) { + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + bw20powerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] + + rtlefuse->txpwr_ht20diff[RF90_PATH_B][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][index]; + bw40powerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } + } + +} + +static void _rtl88e_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel, u8 *bw20powerlevel, + u8 *bw40powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; + rtlphy->cur_bw20_txpwridx = bw20powerlevel[0]; + rtlphy->cur_bw40_txpwridx = bw40powerlevel[0]; + +} + +void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[MAX_TX_COUNT] = {0}; + u8 ofdmpowerlevel[MAX_TX_COUNT] = {0}; + u8 bw20powerlevel[MAX_TX_COUNT] = {0}; + u8 bw40powerlevel[MAX_TX_COUNT] = {0}; + + if (!rtlefuse->txpwr_fromeprom) + return; + _rtl88e_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0], + &bw20powerlevel[0], &bw40powerlevel[0]); + _rtl88e_ccxpower_index_check(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0], + &bw20powerlevel[0], &bw40powerlevel[0]); + rtl88e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl88e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], + &bw20powerlevel[0], + &bw40powerlevel[0], channel); +} + +static long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/ + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/ + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl88e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); +} + +void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl88e_phy_set_bw_mode_callback(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "false driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 delay; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl88e_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + WARN_ONCE((rtlphy->current_channel > 14), + "rtl8188ee: WIRELESS_MODE_G but channel>14"); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl88e_phy_sw_chnl_callback(hw); + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false schedule workitem current channel %d\n", + rtlphy->current_channel); + rtlphy->sw_chnl_inprogress = false; + } else { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl88e_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8188ee: illegal channel for Zebra: %d\n", channel); + + _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + pr_err("Invalid 'stage' = %d, Check it!\n", + *stage); + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) + return true; + (*stage)++; + (*step) = 0; + continue; + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl88e_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8188ee: cmdtable cannot be NULL.\n"); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +static u8 _rtl88e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000); + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + return result; +} + +static u8 _rtl88e_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl88e_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32temp; + u8 result = 0x00; + + /*Get TXIMR Setting*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x81004800); + + /*path a IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x30008c1c); + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160804); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + u32temp = 0x80007C00 | (reg_e94&0x3FF0000) | + ((reg_e9c&0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); + /*RX IQK*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /*path a IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x30008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1c); + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c05); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c05); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static void _rtl88e_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl88e_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl88e_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl88e_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl88e_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl88e_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *addareg, bool is_patha_on, bool is2t) +{ + u32 pathon; + u32 i; + + pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (!is2t) { + pathon = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon); +} + +static void _rtl88e_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i = 0; + + rtl_write_byte(rtlpriv, macreg[i], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8) (macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} + +static void _rtl88e_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl88e_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static bool _rtl88e_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else if (!(simularity_bitmap & 0xF0) && is2t) { + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } + +} + +static void _rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, + 0x870, 0x860, 0x864, 0x800 + }; + const u32 retrycount = 2; + + if (t == 0) { + _rtl88e_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl88e_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + } + _rtl88e_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->rfpi_enable = + (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + } + + if (!rtlphy->rfpi_enable) + _rtl88e_phy_pi_mode_switch(hw, true); + /*BB Setting*/ + rtl_set_bbreg(hw, 0x800, BIT(24), 0x00); + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + + rtl_set_bbreg(hw, 0x870, BIT(10), 0x01); + rtl_set_bbreg(hw, 0x870, BIT(26), 0x01); + rtl_set_bbreg(hw, 0x860, BIT(10), 0x00); + rtl_set_bbreg(hw, 0x864, BIT(10), 0x00); + + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + _rtl88e_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl88e_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x01) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Tx IQK Success!!\n"); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + } + + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl88e_phy_path_a_rx_iqk(hw, is2t); + if (patha_ok == 0x03) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Rx IQK Success!!\n"); + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path a RX iqk fail!!!\n"); + } + } + + if (0 == patha_ok) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A IQK Success!!\n"); + if (is2t) { + _rtl88e_phy_path_a_standby(hw); + _rtl88e_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl88e_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + + if (t != 0) { + if (!rtlphy->rfpi_enable) + _rtl88e_phy_pi_mode_switch(hw, false); + _rtl88e_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl88e_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + _rtl88e_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "88ee IQK Finish!!\n"); +} + +static void _rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); +} + +static void _rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + + if (is_hal_stop(rtlhal)) { + u8 u1btmp; + u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); + rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); + rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); + + /* We use the RF definition of MAIN and AUX, + * left antenna and right antenna repectively. + * Default output at AUX. + */ + if (bmain) { + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(14) | BIT(13) | BIT(12), 0); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(4) | BIT(3), 0); + if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0); + } else { + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(14) | BIT(13) | BIT(12), 1); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(4) | BIT(3), 1); + if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1); + } + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, + reg_tmp = 0; + bool is12simular, is13simular, is23simular; + u32 iqk_bb_reg[9] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + _rtl88e_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); + return; + } + + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + if (get_rf_type(rtlphy) == RF_2T2R) + _rtl88e_phy_iq_calibrate(hw, result, i, true); + else + _rtl88e_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = + _rtl88e_phy_simularity_compare(hw, result, 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = + _rtl88e_phy_simularity_compare(hw, result, 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = + _rtl88e_phy_simularity_compare(hw, result, 1, 2); + if (is23simular) { + final_candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + } + if (final_candidate != 0xff) { + reg_e94 = result[final_candidate][0]; + reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + reg_eb4 = result[final_candidate][4]; + reg_ebc = result[final_candidate][5]; + rtlphy->reg_eb4 = reg_eb4; + rtlphy->reg_ebc = reg_ebc; + rtlphy->reg_e94 = reg_e94; + rtlphy->reg_e9c = reg_e9c; + b_patha_ok = true; + } else { + rtlphy->reg_e94 = 0x100; + rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = 0x0; + rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ + _rtl88e_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (final_candidate != 0xFF) { + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix[0].value[0][i] = + result[final_candidate][i]; + rtlphy->iqk_matrix[0].iqk_done = true; + + } + _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); +} + +void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); + + _rtl88e_phy_lc_calibrate(hw, false); + + rtlphy->lck_inprogress = false; +} + +void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + _rtl88e_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", iotype); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl88e_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl88e_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + /*rtl92c_dm_write_dig(hw);*/ + rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel); + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = 0x17; + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + +static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl88ee_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl88ee_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && + (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl88ee_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + case ERFSLEEP:{ + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl88ee_phy_set_rf_sleep(hw); + break; + } + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl88ee_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h new file mode 100644 index 000000000..8157ef419 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +/* MAX_TX_COUNT must always set to 4, otherwise read efuse + * table secquence will be wrong. + */ +#define MAX_TX_COUNT 4 + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define INDEX_MAPPING_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +enum _ANT_DIV_TYPE { + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, +}; + +u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); +bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); +bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); +void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c new file mode 100644 index 000000000..d69497bf5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../pwrseqcmd.h" +#include "pwrseq.h" + +/* drivers should parse below arrays and do the corresponding actions */ +/*3 Power on Array*/ +struct wlan_pwr_cfg rtl8188ee_power_on_flow[RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_CARDEMU_TO_ACT + RTL8188EE_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8188ee_radio_off_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_ACT_TO_CARDEMU + RTL8188EE_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8188ee_card_disable_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_ACT_TO_CARDEMU + RTL8188EE_TRANS_CARDEMU_TO_CARDDIS + RTL8188EE_TRANS_END +}; + +/*3 Card Enable Array*/ +struct wlan_pwr_cfg rtl8188ee_card_enable_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_CARDDIS_TO_CARDEMU + RTL8188EE_TRANS_CARDEMU_TO_ACT + RTL8188EE_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8188ee_suspend_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_ACT_TO_CARDEMU + RTL8188EE_TRANS_CARDEMU_TO_SUS + RTL8188EE_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8188ee_resume_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_SUS_TO_CARDEMU + RTL8188EE_TRANS_CARDEMU_TO_ACT + RTL8188EE_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8188ee_hwpdn_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + RTL8188EE_TRANS_ACT_TO_CARDEMU + RTL8188EE_TRANS_CARDEMU_TO_PDN + RTL8188EE_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8188ee_enter_lps_flow[RTL8188EE_TRANS_ACT_TO_LPS_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8188EE_TRANS_ACT_TO_LPS + RTL8188EE_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8188ee_leave_lps_flow[RTL8188EE_TRANS_LPS_TO_ACT_STEPS + + RTL8188EE_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8188EE_TRANS_LPS_TO_ACT + RTL8188EE_TRANS_END +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h new file mode 100644 index 000000000..42e222c17 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL8723E_PWRSEQ_H__ +#define __RTL8723E_PWRSEQ_H__ + +#include "../pwrseqcmd.h" +/* Check document WM-20110607-Paul-RTL8188EE_Power_Architecture-R02.vsd + * There are 6 HW Power States: + * 0: POFF--Power Off + * 1: PDN--Power Down + * 2: CARDEMU--Card Emulation + * 3: ACT--Active Mode + * 4: LPS--Low Power State + * 5: SUS--Suspend + * + * The transision from different states are defined below + * TRANS_CARDEMU_TO_ACT + * TRANS_ACT_TO_CARDEMU + * TRANS_CARDEMU_TO_SUS + * TRANS_SUS_TO_CARDEMU + * TRANS_CARDEMU_TO_PDN + * TRANS_ACT_TO_LPS + * TRANS_LPS_TO_ACT + * + * TRANS_END + * PWR SEQ Version: rtl8188ee_PwrSeq_V09.h + */ + +#define RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS 10 +#define RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS 10 +#define RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS 10 +#define RTL8188EE_TRANS_SUS_TO_CARDEMU_STEPS 10 +#define RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS 10 +#define RTL8188EE_TRANS_PDN_TO_CARDEMU_STEPS 10 +#define RTL8188EE_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8188EE_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8188EE_TRANS_END_STEPS 1 + +/* The following macros have the following format: + * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value + * comments }, + */ +#define RTL8188EE_TRANS_CARDEMU_TO_ACT \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1) \ + /* wait till 0x04[17] = 1 power ready*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0)|BIT(1), 0 \ + /* 0x02[1:0] = 0 reset BB*/}, \ + {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \ + /*0x24[23] = 2b'01 schmit trigger */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0 \ + /* 0x04[15] = 0 disable HWPDN (control by DRV)*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), 0 \ + /*0x04[12:11] = 2b'00 disable WL suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0) \ + /*0x04[8] = 1 polling until return 0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0 \ + /*wait till 0x04[8] = 0*/}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \ + /*LDO normal mode*/}, \ + {0x0074, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \ + /*SDIO Driving*/}, + +#define RTL8188EE_TRANS_ACT_TO_CARDEMU \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*0x1F[7:0] = 0 turn off RF*/}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \ + /*LDO Sleep mode*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1) \ + /*0x04[9] = 1 turn off MAC by HW state machine*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0 \ + /*wait till 0x04[9] = 0 polling until return 0 to disable*/}, + +#define RTL8188EE_TRANS_CARDEMU_TO_SUS \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3) \ + /*0x04[12:11] = 2b'01enable WL suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4) \ + /*0x04[12:11] = 2b'11enable WL suspend for PCIe*/}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, BIT(7) \ + /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */},\ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \ + /*Clear SIC_EN register 0x40[12] = 1'b0 */}, \ + {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \ + /*Set USB suspend enable local register 0xfe10[4]=1 */}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0) \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0 \ + /*wait power state to suspend*/}, + +#define RTL8188EE_TRANS_SUS_TO_CARDEMU \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1) \ + /*wait power state to suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), 0 \ + /*0x04[12:11] = 2b'00 disable WL suspend*/}, + +#define RTL8188EE_TRANS_CARDEMU_TO_CARDDIS \ + {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \ + /*0x24[23] = 2b'01 schmit trigger */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) \ + /*0x04[12:11] = 2b'01 enable WL suspend*/}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */},\ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \ + /*Clear SIC_EN register 0x40[12] = 1'b0 */}, \ + {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \ + /*Set USB suspend enable local register 0xfe10[4]=1 */}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0) \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0 \ + /*wait power state to suspend*/}, + +#define RTL8188EE_TRANS_CARDDIS_TO_CARDEMU \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1) \ + /*wait power state to suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0 \ + /*0x04[12:11] = 2b'00 disable WL suspend*/}, + +#define RTL8188EE_TRANS_CARDEMU_TO_PDN \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0/* 0x04[16] = 0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \ + /* 0x04[15] = 1*/}, + +#define RTL8188EE_TRANS_PDN_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0/* 0x04[15] = 0*/}, + +#define RTL8188EE_TRANS_ACT_TO_LPS \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F \ + /*Tx Pause*/}, \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0 \ + /*CCK and OFDM are disabled,and clock are gated*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US \ + /*Delay 1us*/}, \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F \ + /*Reset MAC TRX*/}, \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0 \ + /*check if removed later*/}, \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5) \ + /*Respond TxOK to scheduler*/}, + + +#define RTL8188EE_TRANS_LPS_TO_ACT \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*SDIO RPWM*/}, \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*USB RPWM*/}, \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*PCIe RPWM*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS \ + /*Delay*/}, \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \ + /*. 0x08[4] = 0 switch TSF to 40M*/}, \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0 \ + /*Polling 0x109[7]=0 TSF in 40M*/}, \ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0 \ + /*. 0x29[7:6] = 2b'00 enable BB clock*/}, \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1) \ + /*. 0x101[1] = 1*/}, \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*. 0x100[7:0] = 0xFF enable WMAC TRX*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0) \ + /*. 0x02[1:0] = 2b'11 enable BB macro*/}, \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*. 0x522 = 0*/}, + +#define RTL8188EE_TRANS_END \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + 0, PWR_CMD_END, 0, 0} + +extern struct wlan_pwr_cfg rtl8188ee_power_on_flow + [RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_radio_off_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_card_disable_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_card_enable_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_suspend_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_resume_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_hwpdn_flow + [RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_enter_lps_flow + [RTL8188EE_TRANS_ACT_TO_LPS_STEPS + + RTL8188EE_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8188ee_leave_lps_flow + [RTL8188EE_TRANS_LPS_TO_ACT_STEPS + + RTL8188EE_TRANS_END_STEPS]; + +/* RTL8723 Power Configuration CMDs for PCIe interface */ +#define RTL8188EE_NIC_PWR_ON_FLOW rtl8188ee_power_on_flow +#define RTL8188EE_NIC_RF_OFF_FLOW rtl8188ee_radio_off_flow +#define RTL8188EE_NIC_DISABLE_FLOW rtl8188ee_card_disable_flow +#define RTL8188EE_NIC_ENABLE_FLOW rtl8188ee_card_enable_flow +#define RTL8188EE_NIC_SUSPEND_FLOW rtl8188ee_suspend_flow +#define RTL8188EE_NIC_RESUME_FLOW rtl8188ee_resume_flow +#define RTL8188EE_NIC_PDN_FLOW rtl8188ee_hwpdn_flow +#define RTL8188EE_NIC_LPS_ENTER_FLOW rtl8188ee_enter_lps_flow +#define RTL8188EE_NIC_LPS_LEAVE_FLOW rtl8188ee_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h new file mode 100644 index 000000000..0fc8db891 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h @@ -0,0 +1,2249 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92C_REG_H__ +#define __RTL92C_REG_H__ + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +/* 1.5v for 8188EE test chip, 1.4v for MP chip */ +#define REG_AFE_LDO_CTRL 0x0027 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 +#define REG_GPIO_IO_SEL_2 0x0062 +#define REG_GPIO_OUTPUT 0x006c +#define REG_AFE_XTAL_CTRL_EXT 0x0078 +#define REG_XCK_OUT_CTRL 0x007c +#define REG_MCUFWDL 0x0080 +#define REG_WOL_EVENT 0x0081 +#define REG_MCUTSTCFG 0x0084 + +#define REG_HIMR 0x00B0 +#define REG_HISR 0x00B4 +#define REG_HIMRE 0x00B8 +#define REG_HISRE 0x00BC + +#define REG_EFUSE_ACCESS 0x00CF + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C + +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 +#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_32K_CTRL 0x0194 +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +/* FW shall update this register before + * FW write RXPKT_RELEASE_POLL to 1 + */ +#define REG_FW_UPD_RDPTR 0x0284 +/* Control the RX DMA.*/ +#define REG_RXDMA_CONTROL 0x0286 +/* The number of packets in RXPKTBUF. */ +#define REG_RXPKT_NUM 0x0287 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 + +#define REG_DBI 0x0348 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_WATCH_DOG 0x0368 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 +#define REG_TXPKT_EMPTY 0x041A + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_EARLY_MODE_CONTROL 0x04D0 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_NUM 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +/*8723/8188E Host System Interrupt + *Mask Register (offset 0x58, 32 byte) + */ +#define HSIMR_GPIO12_0_INT_EN BIT(0) +#define HSIMR_SPS_OCP_INT_EN BIT(5) +#define HSIMR_RON_INT_EN BIT(6) +#define HSIMR_PDN_INT_EN BIT(7) +#define HSIMR_GPIO9_INT_EN BIT(25) + +/* 8723/8188E Host System Interrupt + * Status Register (offset 0x5C, 32 byte) + */ +#define HSISR_GPIO12_0_INT BIT(0) +#define HSISR_SPS_OCP_INT BIT(5) +#define HSISR_RON_INT_EN BIT(6) +#define HSISR_PDNINT BIT(7) +#define HSISR_GPIO9_INT BIT(25) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +/********************************************* +* 8188 IMR/ISR bits +**********************************************/ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +/* TXRPT interrupt when CCX bit of the packet is set */ +#define IMR_TXCCK BIT(30) +/* Power Save Time Out Interrupt */ +#define IMR_PSTIMEOUT BIT(29) +/* When GTIMER4 expires, this bit is set to 1 */ +#define IMR_GTINT4 BIT(28) +/* When GTIMER3 expires, this bit is set to 1 */ +#define IMR_GTINT3 BIT(27) +/* Transmit Beacon0 Error */ +#define IMR_TBDER BIT(26) +/* Transmit Beacon0 OK */ +#define IMR_TBDOK BIT(25) +/* TSF Timer BIT32 toggle indication interrupt */ +#define IMR_TSF_BIT32_TOGGLE BIT(24) +/* Beacon DMA Interrupt 0 */ +#define IMR_BCNDMAINT0 BIT(20) +/* Beacon Queue DMA OK0 */ +#define IMR_BCNDOK0 BIT(16) +/* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */ +#define IMR_HSISR_IND_ON_INT BIT(15) +/* Beacon DMA Interrupt Extension for Win7 */ +#define IMR_BCNDMAINT_E BIT(14) +/* CTWidnow End or ATIM Window End */ +#define IMR_ATIMEND BIT(12) +/* HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1)*/ +#define IMR_HISR1_IND_INT BIT(11) +/* CPU to Host Command INT Status, Write 1 clear */ +#define IMR_C2HCMD BIT(10) +/* CPU power Mode exchange INT Status, Write 1 clear */ +#define IMR_CPWM2 BIT(9) +/* CPU power Mode exchange INT Status, Write 1 clear */ +#define IMR_CPWM BIT(8) +/* High Queue DMA OK */ +#define IMR_HIGHDOK BIT(7) +/* Management Queue DMA OK */ +#define IMR_MGNTDOK BIT(6) +/* AC_BK DMA OK */ +#define IMR_BKDOK BIT(5) +/* AC_BE DMA OK */ +#define IMR_BEDOK BIT(4) +/* AC_VI DMA OK */ +#define IMR_VIDOK BIT(3) +/* AC_VO DMA OK */ +#define IMR_VODOK BIT(2) +/* Rx Descriptor Unavailable */ +#define IMR_RDU BIT(1) +/* Receive DMA OK */ +#define IMR_ROK BIT(0) + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +/* Beacon DMA Interrupt 7 */ +#define IMR_BCNDMAINT7 BIT(27) +/* Beacon DMA Interrupt 6 */ +#define IMR_BCNDMAINT6 BIT(26) +/* Beacon DMA Interrupt 5 */ +#define IMR_BCNDMAINT5 BIT(25) +/* Beacon DMA Interrupt 4 */ +#define IMR_BCNDMAINT4 BIT(24) +/* Beacon DMA Interrupt 3 */ +#define IMR_BCNDMAINT3 BIT(23) +/* Beacon DMA Interrupt 2 */ +#define IMR_BCNDMAINT2 BIT(22) +/* Beacon DMA Interrupt 1 */ +#define IMR_BCNDMAINT1 BIT(21) +/* Beacon Queue DMA OK Interrup 7 */ +#define IMR_BCNDOK7 BIT(20) +/* Beacon Queue DMA OK Interrup 6 */ +#define IMR_BCNDOK6 BIT(19) +/* Beacon Queue DMA OK Interrup 5 */ +#define IMR_BCNDOK5 BIT(18) +/* Beacon Queue DMA OK Interrup 4 */ +#define IMR_BCNDOK4 BIT(17) +/* Beacon Queue DMA OK Interrup 3 */ +#define IMR_BCNDOK3 BIT(16) +/* Beacon Queue DMA OK Interrup 2 */ +#define IMR_BCNDOK2 BIT(15) +/* Beacon Queue DMA OK Interrup 1 */ +#define IMR_BCNDOK1 BIT(14) +/* ATIM Window End Extension for Win7 */ +#define IMR_ATIMEND_E BIT(13) +/* Tx Error Flag Interrupt Status, write 1 clear. */ +#define IMR_TXERR BIT(11) +/* Rx Error Flag INT Status, Write 1 clear */ +#define IMR_RXERR BIT(10) +/* Transmit FIFO Overflow */ +#define IMR_TXFOVW BIT(9) +/* Receive FIFO Overflow */ +#define IMR_RXFOVW BIT(8) + +#define HWSET_MAX_SIZE 512 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 256 +/* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte.*/ +#define EFUSE_OOB_PROTECT_BYTES 18 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x18 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8188E_EEPROM_ID 0x8129 + +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_TXPOWERCCK 0x10 +#define EEPROM_TXPOWERHT40_1S 0x16 +#define EEPROM_TXPOWERHT20DIFF 0x1B +#define EEPROM_TXPOWER_OFDMDIFF 0x1B + +#define EEPROM_TX_PWR_INX 0x10 + +#define EEPROM_CHANNELPLAN 0xB8 +#define EEPROM_XTAL_88E 0xB9 +#define EEPROM_THERMAL_METER_88E 0xBA +#define EEPROM_IQK_LCK_88E 0xBB + +#define EEPROM_RF_BOARD_OPTION_88E 0xC1 +#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 +#define EEPROM_RF_BT_SETTING_88E 0xC3 +#define EEPROM_VERSION 0xC4 +#define EEPROM_CUSTOMER_ID 0xC5 +#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 + +#define EEPROM_MAC_ADDR 0xD0 +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 175/*255 88e*/ + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define REG_SC_CNT 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 +#define RCCK0_CCA_CNT 0xa60 + +/* PageB(0xB00) */ +#define RPDP_ANTA 0xb00 +#define RPDP_ANTA_4 0xb04 +#define RPDP_ANTA_8 0xb08 +#define RPDP_ANTA_C 0xb0c +#define RPDP_ANTA_10 0xb10 +#define RPDP_ANTA_14 0xb14 +#define RPDP_ANTA_18 0xb18 +#define RPDP_ANTA_1C 0xb1c +#define RPDP_ANTA_20 0xb20 +#define RPDP_ANTA_24 0xb24 + +#define RCONFIG_PMPD_ANTA 0xb28 +#define RCONFIG_RAM64x16 0xb2c + +#define RBNDA 0xb30 +#define RHSSIPAR 0xb34 + +#define RCONFIG_ANTA 0xb68 +#define RCONFIG_ANTB 0xb6c + +#define RPDP_ANTB 0xb70 +#define RPDP_ANTB_4 0xb74 +#define RPDP_ANTB_8 0xb78 +#define RPDP_ANTB_C 0xb7c +#define RPDP_ANTB_10 0xb80 +#define RPDP_ANTB_14 0xb84 +#define RPDP_ANTB_18 0xb88 +#define RPDP_ANTB_1C 0xb8c +#define RPDP_ANTB_20 0xb90 +#define RPDP_ANTB_24 0xb94 + +#define RCONFIG_PMPD_ANTB 0xb98 + +#define RBNDB 0xba0 + +#define RAPK 0xbd8 +#define RPM_RX0_ANTA 0xbdc +#define RPM_RX1_ANTA 0xbe0 +#define RPM_RX2_ANTA 0xbe4 +#define RPM_RX3_ANTA 0xbe8 +#define RPM_RX0_ANTB 0xbec +#define RPM_RX1_ANTB 0xbf0 +#define RPM_RX2_ANTB 0xbf4 +#define RPM_RX3_ANTB 0xbf8 + +/*Page C*/ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RFPGA0_IQK 0xe28 +#define RTX_IQK_TONE_A 0xe30 +#define RRX_IQK_TONE_A 0xe34 +#define RTX_IQK_PI_A 0xe38 +#define RRX_IQK_PI_A 0xe3c + +#define RTX_IQK 0xe40 +#define RRX_IQK 0xe44 +#define RIQK_AGC_PTS 0xe48 +#define RIQK_AGC_RSP 0xe4c +#define RTX_IQK_TONE_B 0xe50 +#define RRX_IQK_TONE_B 0xe54 +#define RTX_IQK_PI_B 0xe58 +#define RRX_IQK_PI_B 0xe5c +#define RIQK_AGC_CONT 0xe60 + +#define RBLUE_TOOTH 0xe6c +#define RRX_WAIT_CCA 0xe70 +#define RTX_CCK_RFON 0xe74 +#define RTX_CCK_BBON 0xe78 +#define RTX_OFDM_RFON 0xe7c +#define RTX_OFDM_BBON 0xe80 +#define RTX_TO_RX 0xe84 +#define RTX_TO_TX 0xe88 +#define RRX_CCK 0xe8c + +#define RTX_POWER_BEFORE_IQK_A 0xe94 +#define RTX_POWER_AFTER_IQK_A 0xe9c + +#define RRX_POWER_BEFORE_IQK_A 0xea0 +#define RRX_POWER_BEFORE_IQK_A_2 0xea4 +#define RRX_POWER_AFTER_IQK_A 0xea8 +#define RRX_POWER_AFTER_IQK_A_2 0xeac + +#define RTX_POWER_BEFORE_IQK_B 0xeb4 +#define RTX_POWER_AFTER_IQK_B 0xebc + +#define RRX_POWER_BEFORE_IQK_B 0xec0 +#define RRX_POWER_BEFORE_IQK_B_2 0xec4 +#define RRX_POWER_AFTER_IQK_B 0xec8 +#define RRX_POWER_AFTER_IQK_B_2 0xecc + +#define RRX_OFDM 0xed0 +#define RRX_WAIT_RIFS 0xed4 +#define RRX_TO_RX 0xed8 +#define RSTANDBY 0xedc +#define RSLEEP 0xee0 +#define RPMPD_ANAEN 0xeec + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) \ + ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCKRXRFSETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#define REG_UN_used_register 0x01bf + +/* WOL bit information */ +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0) +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1) +#define HAL92C_WOL_DISASSOC_EVENT BIT(2) +#define HAL92C_WOL_DEAUTH_EVENT BIT(3) +#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_FW_DISCONNECT BIT(4) +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c new file mode 100644 index 000000000..24dc7011b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl88e_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10) | BIT(11)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + u8 direction; + u32 pwrtrac_value; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *)(&tx_agc[idx1]); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + if (direction == 1) { + tx_agc[0] += pwrtrac_value; + tx_agc[1] += pwrtrac_value; + } else if (direction == 2) { + tx_agc[0] -= pwrtrac_value; + tx_agc[1] -= pwrtrac_value; + } + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + /*tmpval = tmpval & 0xff00ffff;*/ + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl88e_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 powerbase0, powerbase1; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerbase0 = ppowerlevel_ofdm[i]; + + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + powerlevel[i] = ppowerlevel_bw20[i]; + else + powerlevel[i] = ppowerlevel_bw40[i]; + + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | + (powerbase1 << 16) | (powerbase1 << 8) | powerbase1; + + *(mcsbase + i) = powerbase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); + } +} + +static void _rtl88e_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4], pwr_diff = 0, customer_pwr_diff; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeval = + rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) { + chnlgroup = 0; + } else { + if (channel < 3) + chnlgroup = 0; + else if (channel < 6) + chnlgroup = 1; + else if (channel < 9) + chnlgroup = 2; + else if (channel < 12) + chnlgroup = 3; + else if (channel < 14) + chnlgroup = 4; + else if (channel == 14) + chnlgroup = 5; + } + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + + break; + case 2: + writeval = + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); + } + + if (index < 2) + pwr_diff = + rtlefuse->txpwr_legacyhtdiff[rf][channel-1]; + else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + pwr_diff = + rtlefuse->txpwr_ht20diff[rf][channel-1]; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) + customer_pwr_diff = + rtlefuse->pwrgroup_ht40[rf][channel-1]; + else + customer_pwr_diff = + rtlefuse->pwrgroup_ht20[rf][channel-1]; + + if (pwr_diff > customer_pwr_diff) + pwr_diff = 0; + else + pwr_diff = customer_pwr_diff - pwr_diff; + + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_diff_limit[i] > pwr_diff) + pwr_diff_limit[i] = pwr_diff; + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit); + + writeval = customer_limit + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + default: + chnlgroup = 0; + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeval = writeval - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl88e_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = value[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + } +} + +void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + u8 direction; + u32 pwrtrac_value; + + rtl88e_phy_get_power_base(hw, ppowerlevel_ofdm, + ppowerlevel_bw20, ppowerlevel_bw40, + channel, &powerbase0[0], &powerbase1[0]); + + rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + + for (index = 0; index < 6; index++) { + _rtl88e_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + if (direction == 1) { + writeval[0] += pwrtrac_value; + writeval[1] += pwrtrac_value; + } else if (direction == 2) { + writeval[0] -= pwrtrac_value; + writeval[1] -= pwrtrac_value; + } + _rtl88e_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl88e_phy_rf6052_config_parafile(hw); +} + +static bool _rtl88e_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl88e_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl88e_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h new file mode 100644 index 000000000..05e27b40b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92C_RF_H__ +#define __RTL92C_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, + u8 channel); +bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c new file mode 100644 index 000000000..79c6e0901 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "trx.h" +#include "led.h" +#include "table.h" + +#include +#include + +static void rtl88e_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /* ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl88e_init_sw_vars(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tid; + char *fw_name; + + rtl8188ee_bt_reg_init(hw); + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(15); + + /* compatible 5G band 88ce just 2.4G band & smsp */ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | + RCR_ADF | + RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = + (u32)(IMR_PSTIMEOUT | + IMR_HSISR_IND_ON_INT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0); + rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + if (!rtlpriv->psc.inactiveps) + pr_info("rtl8188ee: Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("rtl8188ee: FW Power Save off (module option)\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl88e_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_info("Can't alloc buffer for fw.\n"); + return 1; + } + + fw_name = "rtlwifi/rtl8188efw.bin"; + rtlpriv->max_fw_size = 0x8000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_info("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + rtlpriv->rtlhal.max_earlymode_num = 10; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + + /*low power */ + rtlpriv->psc.low_power_enable = false; + if (rtlpriv->psc.low_power_enable) { + timer_setup(&rtlpriv->works.fw_clockoff_timer, + rtl88ee_fw_clk_off_timer_callback, 0); + } + + timer_setup(&rtlpriv->works.fast_antenna_training_timer, + rtl88e_dm_fast_antenna_training_callback, 0); + return err; +} + +static void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } + + if (rtlpriv->psc.low_power_enable) + timer_delete_sync(&rtlpriv->works.fw_clockoff_timer); + + timer_delete_sync(&rtlpriv->works.fast_antenna_training_timer); +} + +/* get bt coexist status */ +static bool rtl88e_get_btc_status(void) +{ + return false; +} + +static const struct rtl_hal_ops rtl8188ee_hal_ops = { + .init_sw_vars = rtl88e_init_sw_vars, + .deinit_sw_vars = rtl88e_deinit_sw_vars, + .read_eeprom_info = rtl88ee_read_eeprom_info, + .interrupt_recognized = rtl88ee_interrupt_recognized,/*need check*/ + .hw_init = rtl88ee_hw_init, + .hw_disable = rtl88ee_card_disable, + .hw_suspend = rtl88ee_suspend, + .hw_resume = rtl88ee_resume, + .enable_interrupt = rtl88ee_enable_interrupt, + .disable_interrupt = rtl88ee_disable_interrupt, + .set_network_type = rtl88ee_set_network_type, + .set_chk_bssid = rtl88ee_set_check_bssid, + .set_qos = rtl88ee_set_qos, + .set_bcn_reg = rtl88ee_set_beacon_related_registers, + .set_bcn_intv = rtl88ee_set_beacon_interval, + .update_interrupt_mask = rtl88ee_update_interrupt_mask, + .get_hw_reg = rtl88ee_get_hw_reg, + .set_hw_reg = rtl88ee_set_hw_reg, + .update_rate_tbl = rtl88ee_update_hal_rate_tbl, + .fill_tx_desc = rtl88ee_tx_fill_desc, + .fill_tx_cmddesc = rtl88ee_tx_fill_cmddesc, + .query_rx_desc = rtl88ee_rx_query_desc, + .set_channel_access = rtl88ee_update_channel_access_setting, + .radio_onoff_checking = rtl88ee_gpio_radio_on_off_checking, + .set_bw_mode = rtl88e_phy_set_bw_mode, + .switch_channel = rtl88e_phy_sw_chnl, + .dm_watchdog = rtl88e_dm_watchdog, + .scan_operation_backup = rtl88e_phy_scan_operation_backup, + .set_rf_power_state = rtl88e_phy_set_rf_power_state, + .led_control = rtl88ee_led_control, + .set_desc = rtl88ee_set_desc, + .get_desc = rtl88ee_get_desc, + .is_tx_desc_closed = rtl88ee_is_tx_desc_closed, + .tx_polling = rtl88ee_tx_polling, + .enable_hw_sec = rtl88ee_enable_hw_security_config, + .set_key = rtl88ee_set_key, + .get_bbreg = rtl88e_phy_query_bb_reg, + .set_bbreg = rtl88e_phy_set_bb_reg, + .get_rfreg = rtl88e_phy_query_rf_reg, + .set_rfreg = rtl88e_phy_set_rf_reg, + .get_btc_status = rtl88e_get_btc_status, +}; + +static struct rtl_mod_params rtl88ee_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = false, + .msi_support = true, + .aspm_support = 1, + .debug_level = 0, + .debug_mask = 0, +}; + +static const struct rtl_hal_cfg rtl88ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl88e_pci", + .ops = &rtl8188ee_hal_ops, + .mod_params = &rtl88ee_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + .maps[MAC_HSISR] = REG_HSISR, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, +/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/ + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, +/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/ +/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/ + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IMR_HSISR_IND] = IMR_HSISR_IND_ON_INT, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static const struct pci_device_id rtl88ee_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8179, rtl88ee_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl88ee_pci_ids); + +MODULE_AUTHOR("zhiyuan_yang "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin"); + +module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl88ee_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl88ee_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl88ee_mod_params.msi_support, bool, 0444); +module_param_named(aspm, rtl88ee_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl88ee_mod_params.disable_watchdog, + bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl88ee_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl88ee_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl88ee_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c new file mode 100644 index 000000000..a3c312c3e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c @@ -0,0 +1,615 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "table.h" +u32 RTL8188EEPHY_REG_1TARRAY[] = { + 0x800, 0x80040000, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x02200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569A11A9, + 0x85C, 0x01000014, + 0x860, 0x66F60110, + 0x864, 0x061F0649, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x07000760, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x00000000, + 0x880, 0xB0000C1C, + 0x884, 0x00000001, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000002, + 0x914, 0x00000201, + 0xA00, 0x00D047C8, + 0xA04, 0x80FF000C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7F120F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B1, + 0xB2C, 0x80000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x08800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC47, + 0xC34, 0x469652AF, + 0xC38, 0x49795994, + 0xC3C, 0x0A97971C, + 0xC40, 0x1F7C403F, + 0xC44, 0x000100B7, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00013169, + 0xC5C, 0x00250492, + 0xC60, 0x00000000, + 0xC64, 0x7112848B, + 0xC68, 0x47C00BFF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020610DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0xC84, 0x20F60000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00091521, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00000000, + 0xCA4, 0x000300A0, + 0xCA8, 0x00000000, + 0xCAC, 0x00000000, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x64B22427, + 0xCDC, 0x00766932, + 0xCE0, 0x00222222, + 0xCE4, 0x00000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00000740, + 0xD04, 0x00020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC43, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCC979975, + 0xD30, 0x00000000, + 0xD34, 0x80608000, + 0xD38, 0x00000000, + 0xD3C, 0x00127353, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x6437140A, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xD6C, 0x2A201C16, + 0xD70, 0x1812362E, + 0xD74, 0x322C2220, + 0xD78, 0x000E3C24, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE68, 0x001B25A4, + 0xE6C, 0x00C00014, + 0xE70, 0x00C00014, + 0xE74, 0x01000014, + 0xE78, 0x01000014, + 0xE7C, 0x01000014, + 0xE80, 0x01000014, + 0xE84, 0x00C00014, + 0xE88, 0x01000014, + 0xE8C, 0x00C00014, + 0xED0, 0x00C00014, + 0xED4, 0x00C00014, + 0xED8, 0x00C00014, + 0xEDC, 0x00000014, + 0xEE0, 0x00000014, + 0xEEC, 0x01C00014, + 0xF14, 0x00000003, + 0xF4C, 0x00000000, + 0xF00, 0x00000300, + +}; + +u32 RTL8188EEPHY_REG_ARRAY_PG[] = { + 0xE00, 0xFFFFFFFF, 0x06070809, + 0xE04, 0xFFFFFFFF, 0x02020405, + 0xE08, 0x0000FF00, 0x00000006, + 0x86C, 0xFFFFFF00, 0x00020400, + 0xE10, 0xFFFFFFFF, 0x08090A0B, + 0xE14, 0xFFFFFFFF, 0x01030607, + 0xE18, 0xFFFFFFFF, 0x08090A0B, + 0xE1C, 0xFFFFFFFF, 0x01030607, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x02020202, + 0xE04, 0xFFFFFFFF, 0x00020202, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x04040404, + 0xE14, 0xFFFFFFFF, 0x00020404, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x02020202, + 0xE04, 0xFFFFFFFF, 0x00020202, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x04040404, + 0xE14, 0xFFFFFFFF, 0x00020404, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x02020202, + 0xE04, 0xFFFFFFFF, 0x00020202, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x04040404, + 0xE14, 0xFFFFFFFF, 0x00020404, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + 0xE00, 0xFFFFFFFF, 0x00000000, + 0xE04, 0xFFFFFFFF, 0x00000000, + 0xE08, 0x0000FF00, 0x00000000, + 0x86C, 0xFFFFFF00, 0x00000000, + 0xE10, 0xFFFFFFFF, 0x00000000, + 0xE14, 0xFFFFFFFF, 0x00000000, + 0xE18, 0xFFFFFFFF, 0x00000000, + 0xE1C, 0xFFFFFFFF, 0x00000000, + +}; + +u32 RTL8188EE_RADIOA_1TARRAY[] = { + 0x000, 0x00030000, + 0x008, 0x00084000, + 0x018, 0x00000407, + 0x019, 0x00000012, + 0x01E, 0x00080009, + 0x01F, 0x00000880, + 0x02F, 0x0001A060, + 0x03F, 0x00000000, + 0x042, 0x000060C0, + 0x057, 0x000D0000, + 0x058, 0x000BE180, + 0x067, 0x00001552, + 0x083, 0x00000000, + 0x0B0, 0x000FF8FC, + 0x0B1, 0x00054400, + 0x0B2, 0x000CCC19, + 0x0B4, 0x00043003, + 0x0B6, 0x0004953E, + 0x0B7, 0x0001C718, + 0x0B8, 0x000060FF, + 0x0B9, 0x00080001, + 0x0BA, 0x00040000, + 0x0BB, 0x00000400, + 0x0BF, 0x000C0000, + 0x0C2, 0x00002400, + 0x0C3, 0x00000009, + 0x0C4, 0x00040C91, + 0x0C5, 0x00099999, + 0x0C6, 0x000000A3, + 0x0C7, 0x00088820, + 0x0C8, 0x00076C06, + 0x0C9, 0x00000000, + 0x0CA, 0x00080000, + 0x0DF, 0x00000180, + 0x0EF, 0x000001A0, + 0x051, 0x0006B27D, + 0x052, 0x0007E49D, + 0x053, 0x00000073, + 0x056, 0x00051FF3, + 0x035, 0x00000086, + 0x035, 0x00000186, + 0x035, 0x00000286, + 0x036, 0x00001C25, + 0x036, 0x00009C25, + 0x036, 0x00011C25, + 0x036, 0x00019C25, + 0x0B6, 0x00048538, + 0x018, 0x00000C07, + 0x05A, 0x0004BD00, + 0x019, 0x000739D0, + 0x034, 0x0000ADF3, + 0x034, 0x00009DF0, + 0x034, 0x00008DED, + 0x034, 0x00007DEA, + 0x034, 0x00006DE7, + 0x034, 0x000054EE, + 0x034, 0x000044EB, + 0x034, 0x000034E8, + 0x034, 0x0000246B, + 0x034, 0x00001468, + 0x034, 0x0000006D, + 0x000, 0x00030159, + 0x084, 0x00068200, + 0x086, 0x000000CE, + 0x087, 0x00048A00, + 0x08E, 0x00065540, + 0x08F, 0x00088000, + 0x0EF, 0x000020A0, + 0x03B, 0x000F02B0, + 0x03B, 0x000EF7B0, + 0x03B, 0x000D4FB0, + 0x03B, 0x000CF060, + 0x03B, 0x000B0090, + 0x03B, 0x000A0080, + 0x03B, 0x00090080, + 0x03B, 0x0008F780, + 0x03B, 0x000722B0, + 0x03B, 0x0006F7B0, + 0x03B, 0x00054FB0, + 0x03B, 0x0004F060, + 0x03B, 0x00030090, + 0x03B, 0x00020080, + 0x03B, 0x00010080, + 0x03B, 0x0000F780, + 0x0EF, 0x000000A0, + 0x000, 0x00010159, + 0x018, 0x0000F407, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x01F, 0x00080003, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x01E, 0x00000001, + 0x01F, 0x00080000, + 0x000, 0x00033E60, + +}; + +u32 RTL8188EEMAC_1T_ARRAY[] = { + 0x026, 0x00000041, + 0x027, 0x00000035, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000001, + 0x432, 0x00000002, + 0x433, 0x00000004, + 0x434, 0x00000005, + 0x435, 0x00000006, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43A, 0x00000001, + 0x43B, 0x00000002, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000006, + 0x43F, 0x00000007, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000F0, + 0x446, 0x0000000F, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000A8, + 0x45A, 0x00000072, + 0x45B, 0x000000B9, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x480, 0x00000008, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4D3, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x652, 0x00000020, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + +}; + +u32 RTL8188EEAGCTAB_1TARRAY[] = { + 0xC78, 0xFB000001, + 0xC78, 0xFB010001, + 0xC78, 0xFB020001, + 0xC78, 0xFB030001, + 0xC78, 0xFB040001, + 0xC78, 0xFB050001, + 0xC78, 0xFA060001, + 0xC78, 0xF9070001, + 0xC78, 0xF8080001, + 0xC78, 0xF7090001, + 0xC78, 0xF60A0001, + 0xC78, 0xF50B0001, + 0xC78, 0xF40C0001, + 0xC78, 0xF30D0001, + 0xC78, 0xF20E0001, + 0xC78, 0xF10F0001, + 0xC78, 0xF0100001, + 0xC78, 0xEF110001, + 0xC78, 0xEE120001, + 0xC78, 0xED130001, + 0xC78, 0xEC140001, + 0xC78, 0xEB150001, + 0xC78, 0xEA160001, + 0xC78, 0xE9170001, + 0xC78, 0xE8180001, + 0xC78, 0xE7190001, + 0xC78, 0xE61A0001, + 0xC78, 0xE51B0001, + 0xC78, 0xE41C0001, + 0xC78, 0xE31D0001, + 0xC78, 0xE21E0001, + 0xC78, 0xE11F0001, + 0xC78, 0x8A200001, + 0xC78, 0x89210001, + 0xC78, 0x88220001, + 0xC78, 0x87230001, + 0xC78, 0x86240001, + 0xC78, 0x85250001, + 0xC78, 0x84260001, + 0xC78, 0x83270001, + 0xC78, 0x82280001, + 0xC78, 0x6B290001, + 0xC78, 0x6A2A0001, + 0xC78, 0x692B0001, + 0xC78, 0x682C0001, + 0xC78, 0x672D0001, + 0xC78, 0x662E0001, + 0xC78, 0x652F0001, + 0xC78, 0x64300001, + 0xC78, 0x63310001, + 0xC78, 0x62320001, + 0xC78, 0x61330001, + 0xC78, 0x46340001, + 0xC78, 0x45350001, + 0xC78, 0x44360001, + 0xC78, 0x43370001, + 0xC78, 0x42380001, + 0xC78, 0x41390001, + 0xC78, 0x403A0001, + 0xC78, 0x403B0001, + 0xC78, 0x403C0001, + 0xC78, 0x403D0001, + 0xC78, 0x403E0001, + 0xC78, 0x403F0001, + 0xC78, 0xFB400001, + 0xC78, 0xFB410001, + 0xC78, 0xFB420001, + 0xC78, 0xFB430001, + 0xC78, 0xFB440001, + 0xC78, 0xFB450001, + 0xC78, 0xFB460001, + 0xC78, 0xFB470001, + 0xC78, 0xFB480001, + 0xC78, 0xFA490001, + 0xC78, 0xF94A0001, + 0xC78, 0xF84B0001, + 0xC78, 0xF74C0001, + 0xC78, 0xF64D0001, + 0xC78, 0xF54E0001, + 0xC78, 0xF44F0001, + 0xC78, 0xF3500001, + 0xC78, 0xF2510001, + 0xC78, 0xF1520001, + 0xC78, 0xF0530001, + 0xC78, 0xEF540001, + 0xC78, 0xEE550001, + 0xC78, 0xED560001, + 0xC78, 0xEC570001, + 0xC78, 0xEB580001, + 0xC78, 0xEA590001, + 0xC78, 0xE95A0001, + 0xC78, 0xE85B0001, + 0xC78, 0xE75C0001, + 0xC78, 0xE65D0001, + 0xC78, 0xE55E0001, + 0xC78, 0xE45F0001, + 0xC78, 0xE3600001, + 0xC78, 0xE2610001, + 0xC78, 0xC3620001, + 0xC78, 0xC2630001, + 0xC78, 0xC1640001, + 0xC78, 0x8B650001, + 0xC78, 0x8A660001, + 0xC78, 0x89670001, + 0xC78, 0x88680001, + 0xC78, 0x87690001, + 0xC78, 0x866A0001, + 0xC78, 0x856B0001, + 0xC78, 0x846C0001, + 0xC78, 0x676D0001, + 0xC78, 0x666E0001, + 0xC78, 0x656F0001, + 0xC78, 0x64700001, + 0xC78, 0x63710001, + 0xC78, 0x62720001, + 0xC78, 0x61730001, + 0xC78, 0x60740001, + 0xC78, 0x46750001, + 0xC78, 0x45760001, + 0xC78, 0x44770001, + 0xC78, 0x43780001, + 0xC78, 0x42790001, + 0xC78, 0x417A0001, + 0xC78, 0x407B0001, + 0xC78, 0x407C0001, + 0xC78, 0x407D0001, + 0xC78, 0x407E0001, + 0xC78, 0x407F0001, + +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h new file mode 100644 index 000000000..df6065602 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92CE_TABLE__H_ +#define __RTL92CE_TABLE__H_ + +#include +#define RTL8188EEPHY_REG_1TARRAYLEN 382 +extern u32 RTL8188EEPHY_REG_1TARRAY[]; +#define RTL8188EEPHY_REG_ARRAY_PGLEN 264 +extern u32 RTL8188EEPHY_REG_ARRAY_PG[]; +#define RTL8188EE_RADIOA_1TARRAYLEN 190 +extern u32 RTL8188EE_RADIOA_1TARRAY[]; +#define RTL8188EEMAC_1T_ARRAYLEN 180 +extern u32 RTL8188EEMAC_1T_ARRAY[]; +#define RTL8188EEAGCTAB_1TARRAYLEN 256 +extern u32 RTL8188EEAGCTAB_1TARRAY[]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c new file mode 100644 index 000000000..d094163a9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c @@ -0,0 +1,832 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "trx.h" +#include "led.h" +#include "dm.h" +#include "phy.h" + +static u8 _rtl88ee_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstatus, __le32 *pdesc, + struct rx_fwinfo_88e *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct phy_sts_cck_8192s_t *cck_buf; + struct phy_status_rpt *phystrpt = + (struct phy_status_rpt *)p_drvinfo; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstatus->is_cck; + u8 lan_idx, vga_idx; + + /* Record it for next packet processing */ + pstatus->packet_matchbssid = bpacket_match_bssid; + pstatus->packet_toself = bpacket_toself; + pstatus->packet_beacon = packet_beacon; + pstatus->rx_mimo_signalquality[0] = -1; + pstatus->rx_mimo_signalquality[1] = -1; + + if (is_cck) { + u8 cck_highpwr; + u8 cck_agc_rpt; + /* CCK Driver info Structure is not the same as OFDM packet. */ + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + cck_agc_rpt = cck_buf->cck_agc_rpt; + + /* (1)Hardware does not provide RSSI for CCK + * (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = + (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + else + cck_highpwr = false; + + lan_idx = ((cck_agc_rpt & 0xE0) >> 5); + vga_idx = (cck_agc_rpt & 0x1f); + switch (lan_idx) { + case 7: + if (vga_idx <= 27) + /*VGA_idx = 27~2*/ + rx_pwr_all = -100 + 2*(27-vga_idx); + else + rx_pwr_all = -100; + break; + case 6: + /*VGA_idx = 2~0*/ + rx_pwr_all = -48 + 2*(2-vga_idx); + break; + case 5: + /*VGA_idx = 7~5*/ + rx_pwr_all = -42 + 2*(7-vga_idx); + break; + case 4: + /*VGA_idx = 7~4*/ + rx_pwr_all = -36 + 2*(7-vga_idx); + break; + case 3: + /*VGA_idx = 7~0*/ + rx_pwr_all = -24 + 2*(7-vga_idx); + break; + case 2: + if (cck_highpwr) + /*VGA_idx = 5~0*/ + rx_pwr_all = -12 + 2*(5-vga_idx); + else + rx_pwr_all = -6 + 2*(5-vga_idx); + break; + case 1: + rx_pwr_all = 8-2*vga_idx; + break; + case 0: + rx_pwr_all = 14-2*vga_idx; + break; + default: + break; + } + rx_pwr_all += 6; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + /* CCK gain is smaller than OFDM/MCS gain, */ + /* so we add gain diff by experiences, the val is 6 */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same + * gain index with OFDM. + */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + if (!cck_highpwr) { + if (pwdb_all >= 80) + pwdb_all = ((pwdb_all-80)<<1) + + ((pwdb_all-80)>>1) + 80; + else if ((pwdb_all <= 78) && (pwdb_all >= 20)) + pwdb_all += 3; + if (pwdb_all > 100) + pwdb_all = 100; + } + + pstatus->rx_pwdb_all = pwdb_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (bpacket_match_bssid) { + u8 sq; + + if (pstatus->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstatus->signalquality = sq; + pstatus->rx_mimo_signalquality[0] = sq; + pstatus->rx_mimo_signalquality[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & + 0x3f) * 2) - 110; + + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + + /* Get Rx snr value in DB */ + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + /* Record Signal Strength for next packet */ + if (bpacket_match_bssid) + pstatus->rx_mimo_signalstrength[i] = (u8)rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstatus->rx_pwdb_all = pwdb_all; + pstatus->rxpower = rx_pwr_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 && + pstatus->rate <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (bpacket_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream onlyi + */ + if (i == 0) + pstatus->signalquality = + (u8)(evm & 0xff); + pstatus->rx_mimo_signalquality[i] = + (u8)(evm & 0xff); + } + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); + /*HW antenna diversity*/ + rtldm->fat_table.antsel_rx_keep_0 = phystrpt->ant_sel; + rtldm->fat_table.antsel_rx_keep_1 = phystrpt->ant_sel_b; + rtldm->fat_table.antsel_rx_keep_2 = phystrpt->antsel_rx_keep_2; +} + +static void _rtl88ee_smart_antenna(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 antsel_tr_mux; + struct fast_ant_training *pfat_table = &rtldm->fat_table; + + if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV) { + if (pfat_table->fat_state == FAT_TRAINING_STATE) { + if (pstatus->packet_toself) { + antsel_tr_mux = + (pfat_table->antsel_rx_keep_2 << 2) | + (pfat_table->antsel_rx_keep_1 << 1) | + pfat_table->antsel_rx_keep_0; + pfat_table->ant_sum[antsel_tr_mux] += + pstatus->rx_pwdb_all; + pfat_table->ant_cnt[antsel_tr_mux]++; + } + } + } else if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) || + (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)) { + if (pstatus->packet_toself || pstatus->packet_matchbssid) { + antsel_tr_mux = (pfat_table->antsel_rx_keep_2 << 2) | + (pfat_table->antsel_rx_keep_1 << 1) | + pfat_table->antsel_rx_keep_0; + rtl88e_dm_ant_sel_statistics(hw, antsel_tr_mux, 0, + pstatus->rx_pwdb_all); + } + + } +} + +static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, + __le32 *pdesc, + struct rx_fwinfo_88e *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + __le16 fc; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + praddr = hdr->addr1; + psaddr = ieee80211_get_SA(hdr); + memcpy(pstatus->psaddr, psaddr, ETH_ALEN); + + packet_matchbssid = ((!ieee80211_is_ctl(fc)) && + (ether_addr_equal(mac->bssid, ieee80211_has_tods(fc) ? + hdr->addr1 : ieee80211_has_fromds(fc) ? + hdr->addr2 : hdr->addr3)) && + (!pstatus->hwerror) && + (!pstatus->crc) && (!pstatus->icv)); + + packet_toself = packet_matchbssid && + (ether_addr_equal(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(hdr->frame_control)) + packet_beacon = true; + else + packet_beacon = false; + + _rtl88ee_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + _rtl88ee_smart_antenna(hw, pstatus); + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void rtl88ee_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + __le32 *virtualaddress) +{ + u32 dwtmp = 0; + memset(virtualaddress, 0, 8); + + set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp%4) ? (4-dwtmp%4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[1]; + } + set_earlymode_len0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp%4) ? (4-dwtmp%4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[3]; + } + set_earlymode_len1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp%4) ? (4-dwtmp%4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[5]; + } + set_earlymode_len2_1(virtualaddress, dwtmp & 0xF); + set_earlymode_len2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp%4) ? (4-dwtmp%4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[7]; + } + set_earlymode_len3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp%4) ? (4-dwtmp%4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[9]; + } + set_earlymode_len4(virtualaddress, dwtmp); +} + +bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rx_fwinfo_88e *p_drvinfo; + struct ieee80211_hdr *hdr; + u8 wake_match; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_physt(pdesc); + + status->packet_report_type = (u8)get_rx_status_desc_rpt_sel(pdesc); + if (status->packet_report_type == TX_REPORT2) + status->length = (u16)get_rx_rpt2_desc_pkt_len(pdesc); + else + status->length = (u16)get_rx_desc_pkt_len(pdesc); + status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + status->icv = (u16)get_rx_desc_icv(pdesc); + status->crc = (u16)get_rx_desc_crc32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !get_rx_desc_swdec(pdesc); + status->rate = (u8)get_rx_desc_rxmcs(pdesc); + status->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + status->isampdu = (bool) (get_rx_desc_paggr(pdesc) == 1); + status->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) && + (get_rx_desc_faggr(pdesc) == 1)); + if (status->packet_report_type == NORMAL_RX) + status->timestamp_low = get_rx_desc_tsfl(pdesc); + status->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc); + status->is_ht = (bool)get_rx_desc_rxht(pdesc); + + status->is_cck = RTL8188_RX_HAL_IS_CCK_RATE(status->rate); + + status->macid = get_rx_desc_macid(pdesc); + if (get_rx_status_desc_pattern_match(pdesc)) + wake_match = BIT(2); + else if (get_rx_status_desc_magic_match(pdesc)) + wake_match = BIT(1); + else if (get_rx_status_desc_unicast_match(pdesc)) + wake_match = BIT(0); + else + wake_match = 0; + if (wake_match) + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + * Notice: this is diff with windows define + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, + false, status->rate); + + rx_status->mactime = status->timestamp_low; + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_88e *)(skb->data + + status->rx_bufshift); + + _rtl88ee_translate_rx_signal_stuff(hw, + skb, status, pdesc, + p_drvinfo); + } + rx_status->signal = status->recvsignalpower + 10; + if (status->packet_report_type == TX_REPORT2) { + status->macid_valid_entry[0] = + get_rx_rpt2_desc_macid_valid_1(pdesc); + status->macid_valid_entry[1] = + get_rx_rpt2_desc_macid_valid_2(pdesc); + } + return true; +} + +void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *txbd, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) + +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u16 seq_number; + __le16 fc = hdr->frame_control; + unsigned int buf_len = 0; + unsigned int skb_len = skb->len; + u8 fw_qsel = _rtl88ee_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 bw_40 = 0; + u8 short_gi = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + buf_len = skb->len; + mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_88e)); + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + set_tx_desc_pkt_offset(pdesc, 1); + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN + + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + rtl88ee_insert_emcontent(ptcb_desc, + (__le32 *)(skb->data)); + } + } else { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + } + + ptcb_desc->use_driver_rate = true; + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + if (ptcb_desc->hw_rate > DESC92C_RATEMCS0) + short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; + else + short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + + set_tx_desc_data_shortgi(pdesc, short_gi); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + set_tx_desc_rts_enable(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, 0); + set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_rts_stbc(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_bw(pdesc, 0); + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, + ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (ptcb_desc->tx_enable_sw_calc_duration) + set_tx_desc_nav_use_hdr(pdesc, 1); + + if (bw_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb_len); + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf; + + keyconf = info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + + } + } + + set_tx_desc_queue_sel(pdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ? + 1 : 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /*set_tx_desc_pwr_status(pdesc, pwr_status);*/ + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + /*set_tx_desc_rts_rate(pdesc, 0x08); */ + /* set_tx_desc_tx_rate(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + set_tx_desc_tx_buffer_size(pdesc, (u16)buf_len); + set_tx_desc_tx_buffer_address(pdesc, mapping); + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->ratr_index); + } + if (ieee80211_is_data_qos(fc)) + set_tx_desc_qos(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + + rtl88e_dm_set_tx_ant_by_tx_info(hw, pdesc8, ptcb_desc->mac_id); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + __le32 *pdesc = (__le32 *)pdesc8; + + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_tx_rate(pdesc, DESC92C_RATE1M); + + set_tx_desc_seq(pdesc, 0); + + set_tx_desc_linip(pdesc, 0); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_offset(pdesc, 0x20); + + set_tx_desc_use_rate(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) + set_tx_desc_hwseq_en(pdesc, 1); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", + pdesc, TX_DESC_SIZE); +} + +void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, + bool istx, u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8188ee: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8188ee: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl88ee_get_desc(struct ieee80211_hw *hw, + u8 *pdesc8, bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(pdesc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(pdesc); + break; + default: + WARN_ONCE(true, "rtl8188ee: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(pdesc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(pdesc); + break; + default: + WARN_ONCE(true, "rtl8188ee: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl88ee_get_desc(hw, entry, true, HW_DESC_OWN); + + /*beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h new file mode 100644 index 000000000..aae654b0e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h @@ -0,0 +1,801 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2013 Realtek Corporation.*/ + +#ifndef __RTL92CE_TRX_H__ +#define __RTL92CE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(19, 16)); +} + +static inline void set_tx_desc_nav_use_hdr(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, BIT(20)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(30, 26)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(12)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(13)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_antsel_a(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(24)); +} + +static inline void set_tx_desc_antsel_b(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(25)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, GENMASK(27, 16)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(31)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_qos(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(6)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(13)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(21, 20)); +} + +static inline void set_tx_desc_tx_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(25)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(26)); +} + +static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, BIT(27)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(29, 28)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(31, 30)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, BIT(6)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 6, __val, GENMASK(15, 11)); +} + +static inline void set_tx_desc_antsel_c(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 7, __val, BIT(29)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 7, __val, GENMASK(15, 0)); +} + +static inline int get_tx_desc_tx_buffer_size(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 7), GENMASK(15, 0)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 8) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 8)); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline int get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(13, 0)); +} + +static inline int get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(14)); +} + +static inline int get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(15)); +} + +static inline int get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(19, 16)); +} + +static inline int get_rx_desc_security(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(22, 20)); +} + +static inline int get_rx_desc_qos(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(23)); +} + +static inline int get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(25, 24)); +} + +static inline int get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(26)); +} + +static inline int get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(27)); +} + +static inline int get_rx_desc_ls(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(28)); +} + +static inline int get_rx_desc_fs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(29)); +} + +static inline int get_rx_desc_eor(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(30)); +} + +static inline int get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_rx_desc_macid(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(5, 0)); +} + +static inline int get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(14)); +} + +static inline int get_rx_desc_faggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline int get_rx_desc_a1_fit(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(19, 16)); +} + +static inline int get_rx_desc_a2_fit(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(23, 20)); +} + +static inline int get_rx_desc_pam(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(24)); +} + +static inline int get_rx_desc_pwr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(25)); +} + +static inline int get_rx_desc_md(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(26)); +} + +static inline int get_rx_desc_mf(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(27)); +} + +static inline int get_rx_desc_type(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(29, 28)); +} + +static inline int get_rx_desc_mc(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(30)); +} + +static inline int get_rx_desc_bc(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(31)); +} + +static inline int get_rx_desc_seq(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 2), GENMASK(11, 0)); +} + +static inline int get_rx_desc_frag(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 2), GENMASK(15, 12)); +} + +static inline int get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0)); +} + +static inline int get_rx_desc_rxht(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(6)); +} + +static inline int get_rx_status_desc_rx_gf(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(7)); +} + +static inline int get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(8)); +} + +static inline int get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(9)); +} + +static inline int get_rx_desc_htc(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(10)); +} + +static inline int get_rx_status_desc_eosp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(11)); +} + +static inline int get_rx_status_desc_bssid_fit(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(13, 12)); +} + +static inline int get_rx_status_desc_rpt_sel(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(15, 14)); +} + +static inline int get_rx_status_desc_pattern_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(29)); +} + +static inline int get_rx_status_desc_unicast_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(30)); +} + +static inline int get_rx_status_desc_magic_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(31)); +} + +static inline u32 get_rx_desc_iv1(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 4)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 5)); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 6)); +} + +static inline u32 get_rx_desc_buff_addr64(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 7)); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +static inline void set_rx_desc_buff_addr64(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 7) = cpu_to_le32(__val); +} + +/* TX report 2 format in Rx desc*/ + +static inline int get_rx_rpt2_desc_pkt_len(__le32 *__status) +{ + return le32_get_bits(*(__status), GENMASK(8, 0)); +} + +static inline u32 get_rx_rpt2_desc_macid_valid_1(__le32 *__status) +{ + return le32_to_cpu(*(__status + 4)); +} + +static inline u32 get_rx_rpt2_desc_macid_valid_2(__le32 *__status) +{ + return le32_to_cpu(*(__status + 5)); +} + +static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(3, 0)); +} + +static inline void set_earlymode_len0(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(15, 4)); +} + +static inline void set_earlymode_len1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(27, 16)); +} + +static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(31, 28)); +} + +static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr + 1, __value, GENMASK(7, 0)); +} + +static inline void set_earlymode_len3(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr + 1, __value, GENMASK(19, 8)); +} + +static inline void set_earlymode_len4(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr + 1, __value, GENMASK(31, 20)); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, int _size) +{ + if (_size > TX_DESC_NEXT_DESC_OFFSET) + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); + else + memset(__pdesc, 0, _size); +} + +#define RTL8188_RX_HAL_IS_CCK_RATE(rxmcs)\ + (rxmcs == DESC92C_RATE1M ||\ + rxmcs == DESC92C_RATE2M ||\ + rxmcs == DESC92C_RATE5_5M ||\ + rxmcs == DESC92C_RATE11M) + +struct phy_status_rpt { + u8 padding[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 rsvd_1;/* ch_corr_msb; */ + u8 noise_power_db_msb; + u8 path_cfotail[2]; + u8 pcts_mask[2]; + u8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 rsvd_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + u8 sig_evm; + u8 rsvd_3; +#if defined(__LITTLE_ENDIAN) + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ + u8 sgi_en:1; + u8 rxsc:2; + u8 idle_long:1; + u8 r_ant_train_en:1; + u8 ant_sel_b:1; + u8 ant_sel:1; +#else /* __BIG_ENDIAN */ + u8 ant_sel:1; + u8 ant_sel_b:1; + u8 r_ant_train_en:1; + u8 idle_long:1; + u8 rxsc:2; + u8 sgi_en:1; + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ +#endif +} __packed; + +struct rx_fwinfo_88e { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_88e { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:6; + u32 rsvd0:2; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rdg_en:1; + u32 bar_retryht:2; + u32 agg_break:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 bt_int:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_ssn:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 pwr_status:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 sw_offset30:8; + u32 sw_offset31:4; + u32 rsvd1:1; + u32 antsel_c:1; + u32 null_0:1; + u32 null_1:1; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_88e { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:6; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *txbd, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, + bool istx, u8 desc_name, u8 *val); +u64 rtl88ee_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile new file mode 100644 index 000000000..40f075527 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192c-common-objs := \ + main.o \ + dm_common.o \ + fw_common.o \ + phy_common.o + +obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c-common.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c new file mode 100644 index 000000000..d92aad60e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c @@ -0,0 +1,1738 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include +#include "dm_common.h" +#include "phy_common.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" + +#define BT_RSSI_STATE_NORMAL_POWER BIT(0) +#define BT_RSSI_STATE_AMDPU_OFF BIT(1) +#define BT_RSSI_STATE_SPECIAL_LOW BIT(2) +#define BT_RSSI_STATE_BG_EDCA_LOW BIT(3) +#define BT_RSSI_STATE_TXPOWER_LOW BIT(4) +#define BT_MASK 0x00ffffff + +#define RTLPRIV (struct rtl_priv *) +#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ + ((RTLPRIV(_priv))->mac80211.opmode == \ + NL80211_IFTYPE_ADHOC) ? \ + ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \ + ((RTLPRIV(_priv))->dm.undec_sm_pwdb) + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, + 0x788001e2, + 0x71c001c7, + 0x6b8001ae, + 0x65400195, + 0x5fc0017f, + 0x5a400169, + 0x55400155, + 0x50800142, + 0x4c000130, + 0x47c0011f, + 0x43c0010f, + 0x40000100, + 0x3c8000f2, + 0x390000e4, + 0x35c000d7, + 0x32c000cb, + 0x300000c0, + 0x2d4000b5, + 0x2ac000ab, + 0x288000a2, + 0x26000098, + 0x24000090, + 0x22000088, + 0x20000080, + 0x1e400079, + 0x1c800072, + 0x1b00006c, + 0x19800066, + 0x18000060, + 0x16c0005b, + 0x15800056, + 0x14400051, + 0x1300004c, + 0x12000048, + 0x11000044, + 0x10000040, +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} +}; + +static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + +void dm_restorepowerindex(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 index; + + for (index = 0; index < 6; index++) + rtl_write_byte(rtlpriv, power_index_reg[index], + rtlpriv->dm.powerindex_backup[index]); +} +EXPORT_SYMBOL_GPL(dm_restorepowerindex); + +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 index; + + for (index = 0; index < 6; index++) + rtl_write_byte(rtlpriv, power_index_reg[index], value); +} +EXPORT_SYMBOL_GPL(dm_writepowerindex); + +void dm_savepowerindex(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 index; + u8 tmp; + + for (index = 0; index < 6; index++) { + tmp = rtl_read_byte(rtlpriv, power_index_reg[index]); + rtlpriv->dm.powerindex_backup[index] = tmp; + } +} +EXPORT_SYMBOL_GPL(dm_savepowerindex); + +static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + long rssi_val_min = 0; + + if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && + (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undec_sm_pwdb > + rtlpriv->dm.undec_sm_pwdb) ? + rtlpriv->dm.undec_sm_pwdb : + rtlpriv->dm.entry_min_undec_sm_pwdb; + else + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || + dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + + if (rssi_val_min > 100) + rssi_val_min = 100; + return (u8)rssi_val_min; +} + +static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); + + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + u8 value_igi = dm_digtable->cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = DM_DIG_FA_UPPER; + + dm_digtable->cur_igvalue = value_igi; + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *digtable = &rtlpriv->dm_digtable; + u32 isbt; + + /* modify DIG lower bound, deal with abnormally large false alarm */ + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { + digtable->large_fa_hit++; + if (digtable->forbidden_igi < digtable->cur_igvalue) { + digtable->forbidden_igi = digtable->cur_igvalue; + digtable->large_fa_hit = 1; + } + + if (digtable->large_fa_hit >= 3) { + if ((digtable->forbidden_igi + 1) > + digtable->rx_gain_max) + digtable->rx_gain_min = digtable->rx_gain_max; + else + digtable->rx_gain_min = (digtable->forbidden_igi + 1); + digtable->recover_cnt = 3600; /* 3600=2hr */ + } + } else { + /* Recovery mechanism for IGI lower bound */ + if (digtable->recover_cnt != 0) { + digtable->recover_cnt--; + } else { + if (digtable->large_fa_hit == 0) { + if ((digtable->forbidden_igi-1) < DM_DIG_MIN) { + digtable->forbidden_igi = DM_DIG_MIN; + digtable->rx_gain_min = DM_DIG_MIN; + } else { + digtable->forbidden_igi--; + digtable->rx_gain_min = digtable->forbidden_igi + 1; + } + } else if (digtable->large_fa_hit == 3) { + digtable->large_fa_hit = 0; + } + } + } + if (rtlpriv->falsealm_cnt.cnt_all < 250) { + isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01; + + if (!isbt) { + if (rtlpriv->falsealm_cnt.cnt_all > + digtable->fa_lowthresh) { + if ((digtable->back_val - 2) < + digtable->back_range_min) + digtable->back_val = digtable->back_range_min; + else + digtable->back_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < + digtable->fa_lowthresh) { + if ((digtable->back_val + 2) > + digtable->back_range_max) + digtable->back_val = digtable->back_range_max; + else + digtable->back_val += 2; + } + } else { + digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + } + } else { + /* Adjust initial gain by false alarm */ + if (rtlpriv->falsealm_cnt.cnt_all > 1000) + digtable->cur_igvalue = digtable->pre_igvalue + 2; + else if (rtlpriv->falsealm_cnt.cnt_all > 750) + digtable->cur_igvalue = digtable->pre_igvalue + 1; + else if (rtlpriv->falsealm_cnt.cnt_all < 500) + digtable->cur_igvalue = digtable->pre_igvalue - 1; + } + + /* Check initial gain by upper/lower bound */ + if (digtable->cur_igvalue > digtable->rx_gain_max) + digtable->cur_igvalue = digtable->rx_gain_max; + + if (digtable->cur_igvalue < digtable->rx_gain_min) + digtable->cur_igvalue = digtable->rx_gain_min; + + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 initialized; /* initialized to false */ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; + bool multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + multi_sta = true; + + if (!multi_sta || + dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) { + initialized = false; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (!initialized) { + initialized = true; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable->cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable->rssi_lowthresh) && + (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable->dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable->cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable->rssi_highthresh) { + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable->cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "curmultista_cstate = %x dig_ext_port_stage %x\n", + dm_digtable->curmultista_cstate, + dm_digtable->dig_ext_port_stage); +} + +static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "presta_cstate = %x, cursta_cstate = %x\n", + dm_digtable->presta_cstate, dm_digtable->cursta_cstate); + if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || + dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || + dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + dm_digtable->rssi_val_min = + rtl92c_dm_initial_gain_min_pwdb(hw); + if (dm_digtable->rssi_val_min > 100) + dm_digtable->rssi_val_min = 100; + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable->rssi_val_min = 0; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->cur_igvalue = 0x20; + dm_digtable->pre_igvalue = 0; + rtl92c_dm_write_dig(hw); + } +} + +static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); + if (dm_digtable->rssi_val_min > 100) + dm_digtable->rssi_val_min = 100; + + if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (dm_digtable->rssi_val_min <= 25) + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } else { + if (dm_digtable->rssi_val_min <= 20) + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } + } else { + dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { + if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) || + (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX)) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + + dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; + } +} + +static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (mac->act_scanning) + return; + + if (mac->link_state >= MAC80211_LINKED) + dm_digtable->cursta_cstate = DIG_STA_CONNECT; + else + dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; + + dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + + rtl92c_dm_initial_gain_sta(hw); + rtl92c_dm_initial_gain_multi_sta(hw); + rtl92c_dm_cck_packet_detection_thresh(hw); + + dm_digtable->presta_cstate = dm_digtable->cursta_cstate; +} + +static void rtl92c_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.dm_initialgain_enable) + return; + if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG)) + return; + + rtl92c_dm_ctrl_initgain_by_twoport(hw); +} + +static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.interface == INTF_USB && + rtlpriv->rtlhal.board_type & 0x1) { + dm_savepowerindex(hw); + rtlpriv->dm.dynamic_txpower_enable = true; + } else { + rtlpriv->dm.dynamic_txpower_enable = false; + } + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +void rtl92c_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, + dm_digtable->back_val); + + if (rtlpriv->rtlhal.interface == INTF_USB && + !dm_digtable->dig_enable_flag) { + dm_digtable->pre_igvalue = 0x17; + return; + } + dm_digtable->cur_igvalue -= 1; + if (dm_digtable->cur_igvalue < DM_DIG_MIN) + dm_digtable->cur_igvalue = DM_DIG_MIN; + + if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable->cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable->cur_igvalue); + + dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_WARNING, + "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, + dm_digtable->rssi_val_min, dm_digtable->back_val, + dm_digtable->rx_gain_max, dm_digtable->rx_gain_min, + dm_digtable->large_fa_hit, dm_digtable->forbidden_igi); +} +EXPORT_SYMBOL(rtl92c_dm_write_dig); + +static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + if (mac->link_state != MAC80211_LINKED) + return; + + if (mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_AP) { + /* TODO: Handle ADHOC and AP Mode */ + } + + if (tmpentry_max_pwdb != 0) + rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; + else + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + + if (tmpentry_min_pwdb != 0xff) + rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; + else + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + +/* TODO: + * if (mac->opmode == NL80211_IFTYPE_STATION) { + * if (rtlpriv->rtlhal.fw_ready) { + * u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16); + * rtl8192c_set_rssi_cmd(hw, param); + * } + * } + */ +} + +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} +EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo); + +static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + static u32 last_bt_edca_ul; + static u32 last_bt_edca_dl; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + bool bt_change_edca = false; + + if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) || + (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) { + rtlpriv->dm.current_turbo_edca = false; + last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul; + last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl; + } + + if (rtlpriv->btcoexist.bt_edca_ul != 0) { + edca_be_ul = rtlpriv->btcoexist.bt_edca_ul; + bt_change_edca = true; + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + return; + } + + if ((!mac->ht_enable) && (!rtlpriv->btcoexist.bt_coexistence)) { + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting))) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + &tmp); + rtlpriv->dm.current_turbo_edca = false; + } + } + + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw + *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk; + long ele_a, ele_d, temp_cck, val_x, value32; + long val_y, ele_c = 0; + u8 ofdm_index[2], ofdm_index_old[2] = {0, 0}, cck_index_old = 0; + s8 cck_index = 0; + int i; + bool is2t = IS_92C_SERIAL(rtlhal->version); + s8 txpwr_level[3] = {0, 0, 0}; + u8 ofdm_min_index = 6, rf; + + rtlpriv->dm.txpower_trackinginit = true; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "%s\n", __func__); + + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter); + + rtl92c_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0]); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & + MASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1]); + break; + } + } + } + + temp_cck = + rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.cck_inch14) { + if (memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); + break; + } + } else { + if (memcmp((void *)&temp_cck, + (void *) + &cckswing_table_ch1ch13[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); + break; + } + } + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + /* Handle USB High PA boards */ + + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk); + + if (delta_lck > 1) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92c_phy_lc_calibrate(hw); + } + + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] -= delta; + rtlpriv->dm.cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] += delta; + rtlpriv->dm.cck_index += delta; + } + + if (is2t) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "temp OFDM_A_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i] + + 1; + cck_index = rtlpriv->dm.cck_index + 1; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i]; + cck_index = rtlpriv->dm.cck_index; + } + + for (i = 0; i < rf; i++) { + if (txpwr_level[i] >= 0 && + txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse-> + eeprom_thermalmeter) { + ofdm_index[i] += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 + && thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > + rtlefuse->eeprom_thermalmeter + && delta > 5) { + ofdm_index[i] -= 1; + } + } + + if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse->eeprom_thermalmeter) { + cck_index += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 && + thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > rtlefuse->eeprom_thermalmeter + && delta > 5) { + cck_index -= 1; + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) + ofdm_index[i] = OFDM_TABLE_SIZE - 1; + + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + + if (is2t) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "new OFDM_A_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], cck_index); + } + } + + if (rtlpriv->dm.txpower_track_control && delta != 0) { + ele_d = + (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->reg_e94; + val_y = rtlphy->reg_e9c; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(29), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31) | BIT(29), 0x00); + } + + if (!rtlpriv->dm.cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[cck_index] + [7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[cck_index] + [7]); + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & + 0xFFC00000) >> 22; + + val_x = rtlphy->reg_eb4; + val_y = rtlphy->reg_ebc; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & + 0x00003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(25), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index + [1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27) | BIT(25), 0x00); + } + + } + } + + if (delta_iqk > 3) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92c_phy_iq_calibrate(hw, false); + } + + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); + +} + +static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackinginit = false; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); +} + +static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) +{ + rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl92c_dm_check_txpower_tracking_thermal_meter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, + 0x60); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 92S Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + return; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking direct call!!\n"); + rtl92c_dm_txpower_tracking_directcall(hw); + rtlpriv->dm.tm_trigger = 0; + } +} + +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_check_txpower_tracking_thermal_meter(hw); +} +EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking); + +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + +} +EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask); + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + dm_pstable->pre_ccastate = CCA_MAX; + dm_pstable->cur_ccasate = CCA_MAX; + dm_pstable->pre_rfstate = RF_MAX; + dm_pstable->cur_rfstate = RF_MAX; + dm_pstable->rssi_val_min = 0; +} + +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + if (!rtlpriv->reg_init) { + rtlpriv->reg_874 = (rtl_get_bbreg(hw, + RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & + 0xF000) >> 12; + + rtlpriv->reg_init = true; + } + + if (!bforce_in_normal) { + if (dm_pstable->rssi_val_min != 0) { + if (dm_pstable->pre_rfstate == RF_NORMAL) { + if (dm_pstable->rssi_val_min >= 30) + dm_pstable->cur_rfstate = RF_SAVE; + else + dm_pstable->cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable->rssi_val_min <= 25) + dm_pstable->cur_rfstate = RF_NORMAL; + else + dm_pstable->cur_rfstate = RF_SAVE; + } + } else { + dm_pstable->cur_rfstate = RF_MAX; + } + } else { + dm_pstable->cur_rfstate = RF_NORMAL; + } + + if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { + if (dm_pstable->cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, rtlpriv->reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + rtlpriv->reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + rtlpriv->reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + } + + dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; + } +} +EXPORT_SYMBOL(rtl92c_dm_rf_saving); + +static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /* Determine the minimum RSSI */ + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + dm_pstable->rssi_val_min = 0; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable->rssi_val_min = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } else { + dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } + } else { + dm_pstable->rssi_val_min = + rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } + + /* Power Saving for 92C */ + if (IS_92C_SERIAL(rtlhal->version)) + ;/* rtl92c_dm_1r_cca(hw); */ + else + rtl92c_dm_rf_saving(hw, false); +} + +void rtl92c_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG; + rtlpriv->dm.undec_sm_pwdb = -1; + rtlpriv->dm.undec_sm_cck = -1; + rtlpriv->dm.dm_initialgain_enable = true; + rtl_dm_diginit(hw, 0x20); + + rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE; + rtl92c_dm_init_dynamic_txpower(hw); + + rtl92c_dm_init_edca_turbo(hw); + rtl92c_dm_init_rate_adaptive_mask(hw); + rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS; + rtl92c_dm_initialize_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); + + rtlpriv->dm.ofdm_pkt_cnt = 0; + rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT; +} +EXPORT_SYMBOL(rtl92c_dm_init); + +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); + } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_NORMAL) + dm_restorepowerindex(hw); + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) + dm_writepowerindex(hw, 0x14); + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL2) + dm_writepowerindex(hw, 0x10); + } + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +void rtl92c_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *) (&fw_ps_awake)); + + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && + fw_ps_awake) + && (!ppsc->rfchange_inprogress)) { + rtl92c_dm_pwdb_monitor(hw); + rtl92c_dm_dig(hw); + rtl92c_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_bb_powersaving(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl92c_dm_check_txpower_tracking(hw); + /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ + rtl92c_dm_bt_coexist(hw); + rtl92c_dm_check_edca_turbo(hw); + } +} +EXPORT_SYMBOL(rtl92c_dm_watchdog); + +u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long undec_sm_pwdb; + u8 curr_bt_rssi_state = 0x00; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); + } else { + if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0) + undec_sm_pwdb = 100; + else + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + + /* Check RSSI to determine HighPower/NormalPower state for + * BT coexistence. */ + if (undec_sm_pwdb >= 67) + curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); + else if (undec_sm_pwdb < 62) + curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; + + /* Check RSSI to determine AMPDU setting for BT coexistence. */ + if (undec_sm_pwdb >= 40) + curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); + else if (undec_sm_pwdb <= 32) + curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; + + /* Marked RSSI state. It will be used to determine BT coexistence + * setting later. */ + if (undec_sm_pwdb < 35) + curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; + else + curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); + + /* Check BT state related to BT_Idle in B/G mode. */ + if (undec_sm_pwdb < 15) + curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; + else + curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); + + if (curr_bt_rssi_state != rtlpriv->btcoexist.bt_rssi_state) { + rtlpriv->btcoexist.bt_rssi_state = curr_bt_rssi_state; + return true; + } else { + return false; + } +} +EXPORT_SYMBOL(rtl92c_bt_rssi_state_change); + +static bool rtl92c_bt_state_change(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u32 polling, ratio_tx, ratio_pri; + u32 bt_tx, bt_pri; + u8 bt_state; + u8 cur_service_type; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) + return false; + + bt_state = rtl_read_byte(rtlpriv, 0x4fd); + bt_tx = rtl_read_dword(rtlpriv, 0x488) & BT_MASK; + bt_pri = rtl_read_dword(rtlpriv, 0x48c) & BT_MASK; + polling = rtl_read_dword(rtlpriv, 0x490); + + if (bt_tx == BT_MASK && bt_pri == BT_MASK && + polling == 0xffffffff && bt_state == 0xff) + return false; + + bt_state &= BIT(0); + if (bt_state != rtlpriv->btcoexist.bt_cur_state) { + rtlpriv->btcoexist.bt_cur_state = bt_state; + + if (rtlpriv->btcoexist.reg_bt_sco == 3) { + rtlpriv->btcoexist.bt_service = BT_IDLE; + + bt_state = bt_state | + ((rtlpriv->btcoexist.bt_ant_isolation == 1) ? + 0 : BIT(1)) | BIT(2); + rtl_write_byte(rtlpriv, 0x4fd, bt_state); + } + return true; + } + + ratio_tx = bt_tx * 1000 / polling; + ratio_pri = bt_pri * 1000 / polling; + rtlpriv->btcoexist.ratio_tx = ratio_tx; + rtlpriv->btcoexist.ratio_pri = ratio_pri; + + if (bt_state && rtlpriv->btcoexist.reg_bt_sco == 3) { + + if ((ratio_tx < 30) && (ratio_pri < 30)) + cur_service_type = BT_IDLE; + else if ((ratio_pri > 110) && (ratio_pri < 250)) + cur_service_type = BT_SCO; + else if ((ratio_tx >= 200) && (ratio_pri >= 200)) + cur_service_type = BT_BUSY; + else if ((ratio_tx >= 350) && (ratio_tx < 500)) + cur_service_type = BT_OTHERBUSY; + else if (ratio_tx >= 500) + cur_service_type = BT_PAN; + else + cur_service_type = BT_OTHER_ACTION; + + if (cur_service_type != rtlpriv->btcoexist.bt_service) { + rtlpriv->btcoexist.bt_service = cur_service_type; + bt_state = bt_state | + ((rtlpriv->btcoexist.bt_ant_isolation == 1) ? + 0 : BIT(1)) | + ((rtlpriv->btcoexist.bt_service != BT_IDLE) ? + 0 : BIT(2)); + + /* Add interrupt migration when bt is not ini + * idle state (no traffic). */ + if (rtlpriv->btcoexist.bt_service != BT_IDLE) { + rtl_write_word(rtlpriv, 0x504, 0x0ccc); + rtl_write_byte(rtlpriv, 0x506, 0x54); + rtl_write_byte(rtlpriv, 0x507, 0x54); + } else { + rtl_write_byte(rtlpriv, 0x506, 0x00); + rtl_write_byte(rtlpriv, 0x507, 0x00); + } + + rtl_write_byte(rtlpriv, 0x4fd, bt_state); + return true; + } + } + + return false; + +} + +static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static bool media_connect; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { + media_connect = false; + } else { + if (!media_connect) { + media_connect = true; + return true; + } + media_connect = true; + } + + return false; +} + +static void rtl92c_bt_set_normal(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->btcoexist.bt_service == BT_OTHERBUSY) { + rtlpriv->btcoexist.bt_edca_ul = 0x5ea72b; + rtlpriv->btcoexist.bt_edca_dl = 0x5ea72b; + } else if (rtlpriv->btcoexist.bt_service == BT_BUSY) { + rtlpriv->btcoexist.bt_edca_ul = 0x5eb82f; + rtlpriv->btcoexist.bt_edca_dl = 0x5eb82f; + } else if (rtlpriv->btcoexist.bt_service == BT_SCO) { + if (rtlpriv->btcoexist.ratio_tx > 160) { + rtlpriv->btcoexist.bt_edca_ul = 0x5ea72f; + rtlpriv->btcoexist.bt_edca_dl = 0x5ea72f; + } else { + rtlpriv->btcoexist.bt_edca_ul = 0x5ea32b; + rtlpriv->btcoexist.bt_edca_dl = 0x5ea42b; + } + } else { + rtlpriv->btcoexist.bt_edca_ul = 0; + rtlpriv->btcoexist.bt_edca_dl = 0; + } + + if ((rtlpriv->btcoexist.bt_service != BT_IDLE) && + (rtlpriv->mac80211.mode == WIRELESS_MODE_G || + (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) && + (rtlpriv->btcoexist.bt_rssi_state & + BT_RSSI_STATE_BG_EDCA_LOW)) { + rtlpriv->btcoexist.bt_edca_ul = 0x5eb82b; + rtlpriv->btcoexist.bt_edca_dl = 0x5eb82b; + } +} + +static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw, u8 tmp1byte) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Only enable HW BT coexist when BT in "Busy" state. */ + if (rtlpriv->mac80211.vendor == PEER_CISCO && + rtlpriv->btcoexist.bt_service == BT_OTHER_ACTION) { + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + } else { + if ((rtlpriv->btcoexist.bt_service == BT_BUSY) && + (rtlpriv->btcoexist.bt_rssi_state & + BT_RSSI_STATE_NORMAL_POWER)) { + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + } else if ((rtlpriv->btcoexist.bt_service == + BT_OTHER_ACTION) && (rtlpriv->mac80211.mode < + WIRELESS_MODE_N_24G) && + (rtlpriv->btcoexist.bt_rssi_state & + BT_RSSI_STATE_SPECIAL_LOW)) { + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + } else { + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte); + } + } + + if (rtlpriv->btcoexist.bt_service == BT_PAN) + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100); + else + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0); + + if (rtlpriv->btcoexist.bt_rssi_state & + BT_RSSI_STATE_NORMAL_POWER) { + rtl92c_bt_set_normal(hw); + } else { + rtlpriv->btcoexist.bt_edca_ul = 0; + rtlpriv->btcoexist.bt_edca_dl = 0; + } + + if (rtlpriv->btcoexist.bt_service != BT_IDLE) { + rtlpriv->cfg->ops->set_rfreg(hw, + RF90_PATH_A, + 0x1e, + 0xf0, 0xf); + } else { + rtlpriv->cfg->ops->set_rfreg(hw, + RF90_PATH_A, 0x1e, 0xf0, + rtlpriv->btcoexist.bt_rfreg_origin_1e); + } + + if (!rtlpriv->dm.dynamic_txpower_enable) { + if (rtlpriv->btcoexist.bt_service != BT_IDLE) { + if (rtlpriv->btcoexist.bt_rssi_state & + BT_RSSI_STATE_TXPOWER_LOW) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_BT2; + } else { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_BT1; + } + } else { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_NORMAL; + } + rtl92c_phy_set_txpower_level(hw, + rtlpriv->phy.current_channel); + } +} + +static void rtl92c_check_bt_change(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp1byte = 0; + + if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version) && + rtlpriv->btcoexist.bt_coexistence) + tmp1byte |= BIT(5); + if (rtlpriv->btcoexist.bt_cur_state) { + if (rtlpriv->btcoexist.bt_ant_isolation) + rtl92c_bt_ant_isolation(hw, tmp1byte); + } else { + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte); + rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0, + rtlpriv->btcoexist.bt_rfreg_origin_1e); + + rtlpriv->btcoexist.bt_edca_ul = 0; + rtlpriv->btcoexist.bt_edca_dl = 0; + } +} + +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool wifi_connect_change; + bool bt_state_change; + bool rssi_state_change; + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) { + wifi_connect_change = rtl92c_bt_wifi_connect_change(hw); + bt_state_change = rtl92c_bt_state_change(hw); + rssi_state_change = rtl92c_bt_rssi_state_change(hw); + + if (wifi_connect_change || bt_state_change || rssi_state_change) + rtl92c_check_bt_change(hw); + } +} +EXPORT_SYMBOL(rtl92c_dm_bt_coexist); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h new file mode 100644 index 000000000..c4ce9fc96 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92COMMON_DM_H__ +#define __RTL92COMMON_DM_H__ + +#include "../wifi.h" +#include "../rtl8192ce/def.h" +#include "../rtl8192ce/reg.h" +#include "fw_common.h" + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +#define DYNAMIC_FUNC_DISABLE 0x0 +#define DYNAMIC_FUNC_DIG BIT(0) +#define DYNAMIC_FUNC_HP BIT(1) +#define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/ +#define DYNAMIC_FUNC_BT BIT(3) +#define DYNAMIC_FUNC_ANT_DIV BIT(4) + +#define RSSI_CCK 0 +#define RSSI_OFDM 1 +#define RSSI_DEFAULT 2 + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +void rtl92c_dm_init(struct ieee80211_hw *hw); +void rtl92c_dm_watchdog(struct ieee80211_hw *hw); +void rtl92c_dm_write_dig(struct ieee80211_hw *hw); +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); +void dm_savepowerindex(struct ieee80211_hw *hw); +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); +void dm_restorepowerindex(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c new file mode 100644 index 000000000..b618f07f2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c @@ -0,0 +1,770 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "../efuse.h" +#include "../rtl8192ce/reg.h" +#include "../rtl8192ce/def.h" +#include "fw_common.h" +#include + +static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { + u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + + if (enable) + value32 |= MCUFWDL_EN; + else + value32 &= ~MCUFWDL_EN; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { + u8 tmp; + + if (enable) { + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } + } +} + +static void _rtl92c_write_fw(struct ieee80211_hw *hw, + enum version_8192c version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_version_b; + u8 *bufferptr = (u8 *)buffer; + + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); + is_version_b = IS_NORMAL_CHIP(version); + if (is_version_b) { + u32 pagenums, remainsize; + u32 page, offset; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) + rtl_fill_dummy(bufferptr, &size); + + pagenums = size / FW_8192C_PAGE_SIZE; + remainsize = size % FW_8192C_PAGE_SIZE; + + if (pagenums > 4) + pr_err("Page numbers should not greater then 4\n"); + + for (page = 0; page < pagenums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remainsize) { + offset = pagenums * FW_8192C_PAGE_SIZE; + page = pagenums; + rtl_fw_page_write(hw, page, (bufferptr + offset), + remainsize); + } + } else { + rtl_fw_block_write(hw, buffer, size); + } +} + +static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + pr_err("chksum report fail! REG_MCUFWDL:0x%08x .\n", + value32); + goto exit; + } + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) + return 0; + + mdelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + pr_err("Polling FW ready fail! REG_MCUFWDL:0x%08x.\n", + value32); + +exit: + return err; +} + +int rtl92c_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtlwifi_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192c version = rtlhal->version; + + if (!rtlhal->pfirmware) + return 1; + + pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware; + pfwdata = (u8 *)rtlhal->pfirmware; + fwsize = rtlhal->fwsize; + if (IS_FW_HEADER_EXIST(pfwheader)) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Firmware Version(%d), Signature(%#x),Size(%d)\n", + pfwheader->version, pfwheader->signature, + (int)sizeof(struct rtlwifi_firmware_header)); + + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); + fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); + } + + _rtl92c_enable_fw_download(hw, true); + _rtl92c_write_fw(hw, version, pfwdata, fwsize); + _rtl92c_enable_fw_download(hw, false); + + err = _rtl92c_fw_free_to_go(hw); + if (err) + pr_err("Firmware is not ready to run!\n"); + + return 0; +} +EXPORT_SYMBOL(rtl92c_download_fw); + +static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr, val_mcutst_1; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); + + if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) + result = true; + return result; +} + +static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + pr_err("Write H2C fail because no trigger for FW INT!\n"); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", boxnum); + break; + } + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 1); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 2); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index, 2); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index + 2, 2); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index, 2); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index + 2, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", cmd_len); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8192c-common: return H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + + return; +} +EXPORT_SYMBOL(rtl92c_fill_h2c_cmd); + +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + u8 delay = 100; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) { + WARN_ONCE(true, "rtl8192c-common: 8051 reset fail.\n"); + break; + } + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } +} +EXPORT_SYMBOL(rtl92c_firmware_selfreset); + +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, + (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); +} +EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); + +#define BEACON_PG 0 /*->1*/ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5*/ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *)) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[3] = { 0 }; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1rsvdpageloc, 3); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + + if (cmd_send_packet) + rtstatus = cmd_send_packet(hw, skb); + else + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", + u1rsvdpageloc, 3); + rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} +EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt); + +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = { 0 }; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} +EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd); + +static void rtl92c_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = { ctwindow}; + + rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); +} + +/* refactored routine */ +static void set_noa_data(struct rtl_priv *rtlpriv, + struct rtl_p2p_ps_info *p2pinfo, + struct p2p_ps_offload_t *p2p_ps_offload) +{ + int i; + u32 start_time, tsf_low; + + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num ; i++) { + /* To control the reg setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low+(50*1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } +} + +void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u16 ctwindow; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl92c_set_p2p_ctw_period_cmd(hw, ctwindow); + } + /* call refactored routine */ + set_noa_data(rtlpriv, p2pinfo, p2p_ps_offload); + + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, + BIT(4)); + + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); + +} +EXPORT_SYMBOL_GPL(rtl92c_set_p2p_ps_offload_cmd); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h new file mode 100644 index 000000000..706fc753d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C__FW__COMMON__H__ +#define __RTL92C__FW__COMMON__H__ + +#define FW_8192C_SIZE 0x3000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x1FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 100 +#define NORMAL_CHIP BIT(4) +#define H2C_92C_KEEP_ALIVE_CTRL 48 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\ + (le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x88C0) + +#define CUT_VERSION_MASK (BIT(6)|BIT(7)) +#define CHIP_VENDOR_UMC BIT(5) +#define CHIP_VENDOR_UMC_B_CUT BIT(6) /* Chip version for ECO */ +#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) +#define RF_TYPE_MASK (BIT(0)|BIT(1)) +#define GET_CVID_RF_TYPE(version) \ + ((version) & RF_TYPE_MASK) +#define GET_CVID_CUT_VERSION(version) \ + ((version) & CUT_VERSION_MASK) +#define IS_NORMAL_CHIP(version) \ + ((version & NORMAL_CHIP) ? true : false) +#define IS_2T2R(version) \ + (((GET_CVID_RF_TYPE(version)) == \ + CHIP_92C_BITMASK) ? true : false) +#define IS_92C_SERIAL(version) \ + ((IS_2T2R(version)) ? true : false) +#define IS_CHIP_VENDOR_UMC(version) \ + ((version & CHIP_VENDOR_UMC) ? true : false) +#define IS_VENDOR_UMC_A_CUT(version) \ + ((IS_CHIP_VENDOR_UMC(version)) ? \ + ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) +#define IS_81XXC_VENDOR_UMC_B_CUT(version) \ + ((IS_CHIP_VENDOR_UMC(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + CHIP_VENDOR_UMC_B_CUT) ? true : false) : false) + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val + +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_rsvdpagepkt + (struct ieee80211_hw *hw, + bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *)); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len); +void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c new file mode 100644 index 000000000..97ad21c39 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Georgia "); +MODULE_AUTHOR("Ziv Huang "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c new file mode 100644 index 000000000..3730613a3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c @@ -0,0 +1,1615 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../rtl8192ce/reg.h" +#include "../rtl8192ce/def.h" +#include "dm_common.h" +#include "fw_common.h" +#include "phy_common.h" +#include + +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + + return returnvalue; +} +EXPORT_SYMBOL(rtl92c_phy_query_bb_reg); + +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} +EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); + +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + WARN_ONCE(true, "rtl8192c-common: _rtl92c_phy_fw_rf_serial_read deprecated!\n"); + return 0; +} +EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); + +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + WARN_ONCE(true, "rtl8192c-common: _rtl92c_phy_fw_rf_serial_write deprecated!\n"); +} +EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); + +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0x3f; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + pr_err("return all one\n"); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + mdelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + mdelay(1); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + mdelay(1); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSIREADBACKDATA); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, + retvalue); + return retvalue; +} +EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); + +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + pr_err("stop\n"); + return; + } + offset &= 0x3f; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, + data_and_addr); +} +EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); + +static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); + rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); + rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); + rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); +} + +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtlpriv->cfg->ops->phy_rf6052_config(hw); +} +EXPORT_SYMBOL(rtl92c_phy_rf_config); + +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + if (rtlphy->rf_type == RF_1T2R) { + _rtl92c_phy_bb_config_1t(hw); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); + } + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = + (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200)); + + return true; +} + +EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); + +void _rtl92c_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][0]); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][1]); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][6]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][7]); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][2]); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][3]); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][4]); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][5]); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][8]); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][9]); + } + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][14]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][15]); + } + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][10]); + } + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][11]); + } + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][12]); + } + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][13]); + + rtlphy->pwrgroup_cnt++; + } +} +EXPORT_SYMBOL(_rtl92c_store_pwrindex_diffrate_offset); + +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->default_initialgain[0] = + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; + +} +EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); + +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx + + rtlefuse->legacy_ht_txpowerdiff; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (get_rf_type(rtlphy) == RF_2T2R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (!rtlefuse->txpwr_fromeprom) + return; + _rtl92c_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0]); + _rtl92c_ccxpower_index_check(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], + channel); +} +EXPORT_SYMBOL(rtl92c_phy_set_txpower_level); + +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 idx; + u8 rf_path; + u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_B, + power_indbm); + u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_N_24G, + power_indbm); + if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) + ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; + else + ofdmtxpwridx = 0; + rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE, + "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx); + for (idx = 0; idx < 14; idx++) { + for (rf_path = 0; rf_path < 2; rf_path++) { + rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; + rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = + ofdmtxpwridx; + rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = + ofdmtxpwridx; + } + } + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + return true; +} +EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); + +u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) +{ + u8 txpwridx; + long offset; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + + if ((power_indbm - offset) > 0) + txpwridx = (u8)((power_indbm - offset) * 2); + else + txpwridx = 0; + + if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) + txpwridx = MAX_TXPWR_IDX_NMODE_92S; + + return txpwridx; +} +EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_idx); + +long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} +EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); + +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "false driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} +EXPORT_SYMBOL(rtl92c_phy_set_bw_mode); + +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 delay; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92c_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} +EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); + +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + WARN_ONCE((rtlphy->current_channel > 14), + "rtl8192c-common: WIRELESS_MODE_G but channel>14"); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92c_phy_sw_chnl_callback(hw); + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false schedule workitem\n"); + rtlphy->sw_chnl_inprogress = false; + } else { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} +EXPORT_SYMBOL(rtl92c_phy_sw_chnl); + +static void _rtl92c_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { + if (channel == 6 && + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, + MASKDWORD, 0x00255); + } else { + u32 backuprf0x1A = + (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, + RFREG_OFFSET_MASK); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, + backuprf0x1A); + } + } +} + +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8192c-common: cmdtable cannot be NULL.\n"); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8192c-common: illegal channel for Zebra: %d\n", channel); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + pr_err("Invalid 'stage' = %d, Check it!\n", + *stage); + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92c_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16) currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + _rtl92c_phy_sw_rf_seting(hw, channel); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) +{ + return true; +} +EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath); + +static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, + config_pathb ? 0x28160202 : 0x28160502); + + if (config_pathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); + } + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *addareg, bool is_patha_on, bool is2t) +{ + u32 pathon; + u32 i; + + pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (!is2t) { + pathon = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon); +} + +static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i = 0; + + rtl_write_byte(rtlpriv, macreg[i], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8)(macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5)))); +} + +static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else if (!(simularity_bitmap & 0xF0) && is2t) { + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } +} + +static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + const u32 retrycount = 2; + + if (t == 0) { + rtl_get_bbreg(hw, 0x800, MASKDWORD); + + _rtl92c_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } + _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->rfpi_enable = + (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + + if (!rtlphy->rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, true); + if (t == 0) { + rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); + rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); + rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x03) { + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & 0x3FF0000) >> + 16; + result[t][1] = + (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; + + } + + if (is2t) { + _rtl92c_phy_path_a_standby(hw); + _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92c_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); + rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + if (t != 0) { + if (!rtlphy->rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, false); + _rtl92c_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } +} + +static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, + s8 delta, bool is2t) +{ +} + +static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) { + rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); + else + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, + reg_tmp = 0; + bool is12simular, is13simular, is23simular; + u32 iqk_bb_reg[10] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + _rtl92c_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); + return; + } + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + b_pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_iq_calibrate(hw, result, i, true); + else + _rtl92c_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92c_phy_simularity_compare(hw, + result, 1, + 2); + if (is23simular) + final_candidate = 1; + else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; + rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; + rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; + reg_ec4 = result[final_candidate][6]; + b_patha_ok = true; + b_pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ + _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (IS_92C_SERIAL(rtlhal->version)) { + if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ + _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, + result, + final_candidate, + (reg_ec4 == 0)); + } + _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); +} +EXPORT_SYMBOL(rtl92c_phy_iq_calibrate); + +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + rtlpriv->cfg->ops->phy_lc_calibrate(hw, true); + else + rtlpriv->cfg->ops->phy_lc_calibrate(hw, false); +} +EXPORT_SYMBOL(rtl92c_phy_lc_calibrate); + +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_ap_calibrate(hw, delta, true); + else + _rtl92c_phy_ap_calibrate(hw, delta, false); +} +EXPORT_SYMBOL(rtl92c_phy_ap_calibrate); + +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_set_rfpath_switch(hw, bmain, true); + else + _rtl92c_phy_set_rfpath_switch(hw, bmain, false); +} +EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch); + +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", iotype); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92c_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} +EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); + +void rtl92c_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92c_dm_write_dig(hw); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = 0x17; + rtl92c_dm_write_dig(hw); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} +EXPORT_SYMBOL(rtl92c_phy_set_io); + +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} +EXPORT_SYMBOL(rtl92ce_phy_set_rf_on); + +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + u32 u4b_tmp; + u8 delay = 5; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4b_tmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Switch RF timeout !!!.\n"); + return; + } + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} +EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h new file mode 100644 index 000000000..e64d377df --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_PHY_COMMON_H__ +#define __RTL92C_PHY_COMMON_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define MAX_TOLERANCE 5 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define IQK_DELAY_TIME 1 +#define RF90_PATH_MAX 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, + u16 beaconinterval); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, + u32 rfpath); +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); +void rtl92c_bb_block_on(struct ieee80211_hw *hw); +long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); +bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); +u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw); +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +void _rtl92c_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile new file mode 100644 index 000000000..bc307ccc5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192ce-objs := \ + dm.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192CE) += rtl8192ce.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h new file mode 100644 index 000000000..34486bd3e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_DEF_H__ +#define __RTL92C_DEF_H__ + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +#define RX_SMOOTH_FACTOR 20 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +#define CHIP_VER_B BIT(4) +#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) +#define CHIP_BONDING_92C_1T2R 0x1 +#define RF_TYPE_1T2R BIT(1) +#define CHIP_92C_BITMASK BIT(0) +#define CHIP_UNKNOWN BIT(7) +#define CHIP_92C_1T2R 0x03 +#define CHIP_92C 0x01 +#define CHIP_88C 0x00 + +enum version_8192c { + VERSION_A_CHIP_92C = 0x01, + VERSION_A_CHIP_88C = 0x00, + VERSION_B_CHIP_92C = 0x11, + VERSION_B_CHIP_88C = 0x10, + VERSION_TEST_CHIP_88C = 0x00, + VERSION_TEST_CHIP_92C = 0x01, + VERSION_NORMAL_TSMC_CHIP_88C = 0x10, + VERSION_NORMAL_TSMC_CHIP_92C = 0x11, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33, + VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34, + VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73, + VERSION_UNKNOWN = 0x88, +}; + +enum rtl819x_loopback_e { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +struct phy_sts_cck_8192s_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c new file mode 100644 index 000000000..34a730a0d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8192c/fw_common.h" + +void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); + } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h new file mode 100644 index 000000000..eab42c1bd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_DM_H__ +#define __RTL92C_DM_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +void rtl92c_dm_init(struct ieee80211_hw *hw); +void rtl92c_dm_watchdog(struct ieee80211_hw *hw); +void rtl92c_dm_write_dig(struct ieee80211_hw *hw); +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); +void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c new file mode 100644 index 000000000..4354ae67a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c @@ -0,0 +1,2324 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8192c/dm_common.h" +#include "../rtl8192c/fw_common.h" +#include "../rtl8192c/phy_common.h" +#include "dm.h" +#include "led.h" +#include "hw.h" + +#define LLT_CONFIG 5 + +static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *) (val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *) (val)) = tsf; + + break; + } + case HAL_DEF_WOWLAN: + break; + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + + rate_cfg &= 0x15f; + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (rate_cfg >> 8) & 0xff); + while (rate_cfg > 0x1) { + rate_cfg = (rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *) val)); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + &e_aci); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)*val; + + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + + min_spacing_to_set = *val; + if (min_spacing_to_set <= 7) { + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *val; + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; + u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; + + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == + BT_CSR_BC4)) + p_regtoset = regtoset_bt; + else + p_regtoset = regtoset_normal; + + factor_toset = *(val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + + } + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *(val); + + rtl92c_dm_init_edca_turbo(hw); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + (&e_aci)); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *(val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + pr_err("switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = val[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *val; + break; + case HW_VAR_IO_CMD: + rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *val); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + *val | BIT(7)); + } + + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = *val; + + if ((psmode != FW_PS_ACTIVE_MODE) && + (!IS_92C_SERIAL(rtlhal->version))) { + rtl92c_dm_rf_saving(hw, true); + } + + rtl92c_set_fw_pwrmode_cmd(hw, *val); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = *val; + u8 tmp_regcr, tmp_reg422; + bool recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = + rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + + rtl92c_set_fw_rsvdpagepkt(hw, NULL); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (recover) { + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + } + + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl92c_set_fw_joinbss_report_cmd(hw, *val); + + break; + } + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl92c_set_p2p_ps_offload_cmd(hw, *val); + break; + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = val[0]; + + if (btype_ibss) + _rtl92ce_stop_tx_beacon(hw); + + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32) & 0xffffffff)); + + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl92ce_resume_tx_beacon(hw); + + break; + + } + case HW_VAR_FW_LPS_ACTION: { + bool enter_fwlps = *((bool *)val); + u8 rpwm_val, fw_pwrmode; + bool fw_current_inps; + + if (enter_fwlps) { + rpwm_val = 0x02; /* RF off */ + fw_current_inps = true; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &ppsc->fwctrl_psmode); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + &rpwm_val); + } else { + rpwm_val = 0x0C; /* RF on */ + fw_pwrmode = FW_PS_ACTIVE_MODE; + fw_current_inps = false; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + &rpwm_val); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &fw_pwrmode); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } + break; } + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2, array); + break; } + default: + pr_err("switch case %d not processed\n", variable); + break; + } +} + +static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxpage; + bool status; + +#if LLT_CONFIG == 1 + maxpage = 255; + txpktbuf_bndy = 252; +#elif LLT_CONFIG == 2 + maxpage = 127; + txpktbuf_bndy = 124; +#elif LLT_CONFIG == 3 + maxpage = 255; + txpktbuf_bndy = 174; +#elif LLT_CONFIG == 4 + maxpage = 255; + txpktbuf_bndy = 246; +#elif LLT_CONFIG == 5 + maxpage = 255; + txpktbuf_bndy = 246; +#endif + +#if LLT_CONFIG == 1 + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c); + rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c); +#elif LLT_CONFIG == 2 + rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010); +#elif LLT_CONFIG == 3 + rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484); +#elif LLT_CONFIG == 4 + rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c); +#elif LLT_CONFIG == 5 + rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29); +#endif + + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl92ce_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = _rtl92ce_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + status = _rtl92ce_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + return true; +} + +static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpci->up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92ce_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92ce_sw_led_on(hw, pin0); + else + rtl92ce_sw_led_off(hw, pin0); +} + +static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + if (rtlpriv->btcoexist.bt_coexistence) { + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_APS_FSMCO); + value32 |= (SOP_ABG | SOP_AMB | XOP_BTCK); + rtl_write_dword(rtlpriv, REG_APS_FSMCO, value32); + } + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); + + if (rtlpriv->btcoexist.bt_coexistence) { + u32 u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); + + u4b_tmp &= (~0x00024800); + rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); + } + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); + udelay(2); + + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + udelay(2); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(2); + + retry = 0; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); + + while ((bytetmp & BIT(0)) && retry < 1000) { + retry++; + udelay(50); + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); + udelay(50); + } + + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); + + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); + udelay(2); + + if (rtlpriv->btcoexist.bt_coexistence) { + bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2) & 0xfd; + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, bytetmp); + } + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (!_rtl92ce_llt_table_init(hw)) + return false; + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77); + else + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && (bytetmp & BIT(7))); + + _rtl92ce_gen_refresh_led_state(hw); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true; +} + +static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_bw_opmode; + u32 reg_prsr; + + reg_bw_opmode = BW_OPMODE_20MHZ; + reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); + + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); + else + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) { + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); + } else { + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); + else + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); + + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + +} + +static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + + if (ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); + +} + +int rtl92ce_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool rtstatus = true; + bool is92c; + int err; + u8 tmp_u1b; + unsigned long flags; + + rtlpci->being_init_adapter = true; + + /* Since this function can take a very long time (up to 350 ms) + * and can be called with irqs disabled, reenable the irqs + * to let the other devices continue being serviced. + * + * It is safe doing so since our own interrupts will only be enabled + * in a subsequent step. + */ + local_save_flags(flags); + local_irq_enable(); + + rtlhal->fw_ready = false; + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl92ce_init_mac(hw); + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + goto exit; + } + + err = rtl92c_download_fw(hw); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + goto exit; + } + + rtlhal->fw_ready = true; + rtlhal->last_hmeboxnum = 0; + rtl92c_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl92c_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl92c_phy_rf_config(hw); + if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && + !IS_92C_SERIAL(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); + } else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); + rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); + rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); + } + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + _rtl92ce_hw_configure(hw); + rtl_cam_reset_all_entry(hw); + rtl92ce_enable_hw_security_config(hw); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl92ce_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + rtl8192ce_bt_hw_init(hw); + + if (ppsc->rfpwr_state == ERFON) { + rtl92c_phy_set_rfpath_switch(hw, 1); + if (rtlphy->iqk_initialized) { + rtl92c_phy_iq_calibrate(hw, true); + } else { + rtl92c_phy_iq_calibrate(hw, false); + rtlphy->iqk_initialized = true; + } + + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_phy_lc_calibrate(hw); + } + + is92c = IS_92C_SERIAL(rtlhal->version); + tmp_u1b = efuse_read_1byte(hw, 0x1FA); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); + } + + if (!(tmp_u1b & BIT(1)) && is92c) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n"); + } + + if (!(tmp_u1b & BIT(4))) { + tmp_u1b = rtl_read_byte(rtlpriv, 0x16); + tmp_u1b &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); + udelay(10); + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); + } + rtl92c_dm_init(hw); +exit: + local_irq_restore(flags); + rtlpci->being_init_adapter = false; + return err; +} + +static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8192c version = VERSION_UNKNOWN; + u32 value32; + const char *versionid; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : + VERSION_A_CHIP_88C; + } else { + version = (enum version_8192c) (CHIP_VER_B | + ((value32 & TYPE_ID) ? CHIP_92C_BITMASK : 0) | + ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); + if ((!IS_CHIP_VENDOR_UMC(version)) && (value32 & + CHIP_VER_RTL_MASK)) { + version = (enum version_8192c)(version | + ((((value32 & CHIP_VER_RTL_MASK) == BIT(12)) + ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | + CHIP_VENDOR_UMC)); + } + if (IS_92C_SERIAL(version)) { + value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); + version = (enum version_8192c)(version | + ((CHIP_BONDING_IDENTIFIER(value32) + == CHIP_BONDING_92C_1T2R) ? + RF_TYPE_1T2R : 0)); + } + } + + switch (version) { + case VERSION_B_CHIP_92C: + versionid = "B_CHIP_92C"; + break; + case VERSION_B_CHIP_88C: + versionid = "B_CHIP_88C"; + break; + case VERSION_A_CHIP_92C: + versionid = "A_CHIP_92C"; + break; + case VERSION_A_CHIP_88C: + versionid = "A_CHIP_88C"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: + versionid = "A_CUT_92C_1T2R"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: + versionid = "A_CUT_92C"; + break; + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: + versionid = "A_CUT_88C"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: + versionid = "B_CUT_92C_1T2R"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: + versionid = "B_CUT_92C"; + break; + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: + versionid = "B_CUT_88C"; + break; + default: + versionid = "Unknown. Bug?"; + break; + } + + pr_info("Chip Version ID: %s\n", versionid); + + switch (version & 0x3) { + case CHIP_88C: + rtlphy->rf_type = RF_1T1R; + break; + case CHIP_92C: + rtlphy->rf_type = RF_2T2R; + break; + case CHIP_92C_1T2R: + rtlphy->rf_type = RF_1T2R; + break; + default: + rtlphy->rf_type = RF_1T1R; + pr_err("ERROR RF_Type is set!!\n"); + break; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + bt_msr &= 0xfc; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Mesh Point!\n"); + break; + default: + pr_err("Network type %d not supported!\n", type); + return 1; + + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state does not matter here. + */ + if (mode != MSR_AP && + rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl92ce_stop_tx_beacon(hw); + _rtl92ce_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl92ce_resume_tx_beacon(hw); + _rtl92ce_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + rtl_write_byte(rtlpriv, MSR, bt_msr | mode); + + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *) (®_rcr)); + _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *) (®_rcr)); + } + +} + +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92ce_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP && + type != NL80211_IFTYPE_MESH_POINT) + rtl92ce_set_check_bssid(hw, true); + } else { + rtl92ce_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl92c_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */ + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8192ce: invalid aci: %d !\n", aci); + break; + } +} + +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + rtlpci->irq_enabled = false; +} + +static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 u1b_tmp; + u32 u4b_tmp; + + rtlpriv->intf_ops->enable_aspm(hw); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) + rtl92c_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); + if ((rtlpriv->btcoexist.bt_coexistence) && + ((rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) || + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC8))) { + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00F30000 | + (u1b_tmp << 8)); + } else { + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | + (u1b_tmp << 8)); + } + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + if (!IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + if (rtlpriv->btcoexist.bt_coexistence) { + u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); + u4b_tmp |= 0x03824800; + rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); + } else { + rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); + } + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); +} + +void rtl92ce_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92ce_set_media_status(hw, opmode); + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl92ce_poweroff_adapter(hw); + + /* after power off we should do iqk again */ + rtlpriv->phy.iqk_initialized = false; +} + +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); +} + +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl92ce_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl92ce_enable_interrupt(hw); +} + +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92ce_disable_interrupt(hw); + rtl92ce_enable_interrupt(hw); +} + +static noinline_for_stack void +_rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail && + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i] != 0xff && + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + i] != 0xff) { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + + i]; + } else { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail && + hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i] != 0xff) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0); + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail && + hwinfo[EEPROM_TXPWR_GROUP + i] != 0xff && + hwinfo[EEPROM_TXPWR_GROUP + 3 + i] != 0xff) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf0) >> 4); + } + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); + } + } + + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + + if (!autoload_fail && + hwinfo[EEPROM_TXPOWERHT20DIFF + index] != 0xff) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + + index = rtl92c_get_chnl_group((u8)i); + + if (!autoload_fail && + hwinfo[EEPROM_TXPOWER_OFDMDIFF + index] != 0xff) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); + + if (!autoload_fail && hwinfo[RF_OPTION1] != 0xff) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); + + if (!autoload_fail && + hwinfo[EEPROM_TSSI_A] != 0xff && + hwinfo[EEPROM_TSSI_B] != 0xff) { + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; + } else { + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); + + if (!autoload_fail && hwinfo[EEPROM_THERMAL_METER] != 0xff) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->apk_thermalmeterignore = true; + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); +} + +static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13}; + u8 *hwinfo; + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + _rtl92ce_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + + rtl8192ce_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) + rtlhal->oem_id = RT_CID_819X_HP; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } + } +exit: + kfree(hwinfo); +} + +static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92ce_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl92ce_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl92ce_hal_customized_behavior(hw); +} + +static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 nmode = mac->ht_enable; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + u32 ratr_mask; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) && + (rtlpriv->btcoexist.bt_cur_state) && + (rtlpriv->btcoexist.bt_ant_isolation) && + ((rtlpriv->btcoexist.bt_service == BT_SCO) || + (rtlpriv->btcoexist.bt_service == BT_BUSY))) + ratr_value &= 0x0fffcfc0; + else + ratr_value &= 0x0FFFFFFF; + + if (nmode && ((curtxbw_40mhz && + curshortgi_40mhz) || (!curtxbw_40mhz && + curshortgi_20mhz))) { + + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SGI_40) ? 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %5phC\n", + ratr_index, ratr_bitmap, rate_mask); + rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); +} + +void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92ce_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl92ce_update_hal_rate_table(hw, sta); +} + +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp; + bool actuallyset = false; + unsigned long flag; + + if (rtlpci->being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG)&~(BIT(3))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; + + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + actuallyset = true; + } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + actuallyset = true; + } + + if (actuallyset) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + *valid = 1; + return !ppsc->hwradiooff; + +} + +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + pr_err("switch case %#x not processed\n", + enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec. + key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} + +static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->btcoexist.bt_coexistence = + rtlpriv->btcoexist.eeprom_bt_coexist; + rtlpriv->btcoexist.bt_ant_num = + rtlpriv->btcoexist.eeprom_bt_ant_num; + rtlpriv->btcoexist.bt_coexist_type = + rtlpriv->btcoexist.eeprom_bt_type; + + if (rtlpriv->btcoexist.reg_bt_iso == 2) + rtlpriv->btcoexist.bt_ant_isolation = + rtlpriv->btcoexist.eeprom_bt_ant_isol; + else + rtlpriv->btcoexist.bt_ant_isolation = + rtlpriv->btcoexist.reg_bt_iso; + + rtlpriv->btcoexist.bt_radio_shared_type = + rtlpriv->btcoexist.eeprom_bt_radio_shared; + + if (rtlpriv->btcoexist.bt_coexistence) { + if (rtlpriv->btcoexist.reg_bt_sco == 1) + rtlpriv->btcoexist.bt_service = BT_OTHER_ACTION; + else if (rtlpriv->btcoexist.reg_bt_sco == 2) + rtlpriv->btcoexist.bt_service = BT_SCO; + else if (rtlpriv->btcoexist.reg_bt_sco == 4) + rtlpriv->btcoexist.bt_service = BT_BUSY; + else if (rtlpriv->btcoexist.reg_bt_sco == 5) + rtlpriv->btcoexist.bt_service = BT_OTHERBUSY; + else + rtlpriv->btcoexist.bt_service = BT_IDLE; + + rtlpriv->btcoexist.bt_edca_ul = 0; + rtlpriv->btcoexist.bt_edca_dl = 0; + rtlpriv->btcoexist.bt_rssi_state = 0xff; + } +} + +void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val; + + if (!auto_load_fail) { + rtlpriv->btcoexist.eeprom_bt_coexist = + ((hwinfo[RF_OPTION1] & 0xe0) >> 5); + val = hwinfo[RF_OPTION4]; + rtlpriv->btcoexist.eeprom_bt_type = ((val & 0xe) >> 1); + rtlpriv->btcoexist.eeprom_bt_ant_num = (val & 0x1); + rtlpriv->btcoexist.eeprom_bt_ant_isol = ((val & 0x10) >> 4); + rtlpriv->btcoexist.eeprom_bt_radio_shared = + ((val & 0x20) >> 5); + } else { + rtlpriv->btcoexist.eeprom_bt_coexist = 0; + rtlpriv->btcoexist.eeprom_bt_type = BT_2WIRE; + rtlpriv->btcoexist.eeprom_bt_ant_num = ANT_X2; + rtlpriv->btcoexist.eeprom_bt_ant_isol = 0; + rtlpriv->btcoexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; + } + + rtl8192ce_bt_var_init(hw); +} + +void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + u8 u1_tmp; + + if (rtlpriv->btcoexist.bt_coexistence && + ((rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) || + rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC8)) { + + if (rtlpriv->btcoexist.bt_ant_isolation) + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + + u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) & BIT(0); + u1_tmp = u1_tmp | + ((rtlpriv->btcoexist.bt_ant_isolation == 1) ? + 0 : BIT(1)) | + ((rtlpriv->btcoexist.bt_service == BT_SCO) ? + 0 : BIT(2)); + rtl_write_byte(rtlpriv, 0x4fd, u1_tmp); + + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa); + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040); + rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010); + + /* Config to 1T1R. */ + if (rtlphy->rf_type == RF_1T1R) { + u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE); + u1_tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp); + + u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE); + u1_tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp); + } + } +} + +void rtl92ce_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl92ce_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h new file mode 100644 index 000000000..fa1049d16 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_HW_H__ +#define __RTL92CE_HW_H__ + +static inline u8 rtl92c_get_chnl_group(u8 chnl) +{ + u8 group; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + return group; +} + +void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl92ce_hw_init(struct ieee80211_hw *hw); +void rtl92ce_card_disable(struct ieee80211_hw *hw); +void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); +void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); +int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw); +void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw); +void rtl92ce_suspend(struct ieee80211_hw *hw); +void rtl92ce_resume(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c new file mode 100644 index 000000000..9d3ffed13 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + pr_info("switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92ce_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl92ce_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl92ce_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", + ledaction); + _rtl92ce_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h new file mode 100644 index 000000000..66dc28d62 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c new file mode 100644 index 000000000..fa70a7d55 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c @@ -0,0 +1,517 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "hw.h" +#include "phy.h" +#include "../rtl8192c/phy_common.h" +#include "rf.h" +#include "dm.h" +#include "../rtl8192c/dm_common.h" +#include "../rtl8192c/fw_common.h" +#include "table.h" + +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, regaddr); + } else { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } + + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is92c = IS_92C_SERIAL(rtlhal->version); + bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + + if (is92c) + rtl_write_byte(rtlpriv, 0x14, 0x71); + else + rtl_write_byte(rtlpriv, 0x04CA, 0x0A); + return rtstatus; +} + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regvaldw; + u8 reg_hwparafile = 1; + + _rtl92c_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTN | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + if (reg_hwparafile == 1) + rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + + _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = RTL8192CEMAC_2T_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + agctab_arraylen = AGCTAB_2TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_2TARRAY; + phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_2TARRAY; + } else { + agctab_arraylen = AGCTAB_1TARRAYLENGTH; + agctab_array_table = RTL8192CEAGCTAB_1TARRAY; + phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH; + phy_regarray_table = RTL8192CEPHY_REG_1TARRAY; + } + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + rtl_addr_delay(phy_regarray_table[i]); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + } + return true; +} + +bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH; + phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + rtl_addr_delay(phy_regarray_table_pg[i]); + + _rtl92c_store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + + int i; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) { + radioa_arraylen = RADIOA_2TARRAYLENGTH; + radioa_array_table = RTL8192CERADIOA_2TARRAY; + radiob_arraylen = RADIOB_2TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_2TARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); + } else { + radioa_arraylen = RADIOA_1TARRAYLENGTH; + radioa_array_table = RTL8192CE_RADIOA_1TARRAY; + radiob_arraylen = RADIOB_1TARRAYLENGTH; + radiob_array_table = RTL8192CE_RADIOB_1TARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + } + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + } + break; + case RF90_PATH_C: + case RF90_PATH_D: + pr_info("Incorrect rfpath %#x\n", rfpath); + break; + default: + pr_info("switch case %#x not processed\n", rfpath); + break; + } + return true; +} + +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_info("unknown bandwidth: %#X\n", rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); +} + +void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON:{ + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl92ce_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + } + case ERFOFF:{ + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + } + case ERFSLEEP:{ + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl92c_phy_set_rf_sleep(hw); + break; + } + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h new file mode 100644 index 000000000..c7a0d4c77 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define MAX_TOLERANCE 5 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define IQK_DELAY_TIME 1 + +#define RF90_PATH_MAX 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel); +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, + u32 rfpath); +bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); +void rtl92c_bb_block_on(struct ieee80211_hw *hw); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 offset); +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, u32 data); +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +void _rtl92c_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h new file mode 100644 index 000000000..431277ef1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h @@ -0,0 +1,2030 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_REG_H__ +#define __RTL92C_REG_H__ + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c + +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */ +#define REG_GPIO_PIN_CTRL_2 0x0060 +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */ +#define REG_GPIO_IO_SEL_2 0x0062 +/* RTL8723 WIFI/BT/GPS Multi-Function control source. */ +#define REG_MULTI_FUNC_CTRL 0x0068 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only.*/ + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_C2HEVT_CLEAR 0x01BF +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_SIFS_CCK 0x0514 +#define REG_SIFS_OFDM 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +/* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ +#define REG_R2T_SIFS 0x063C +/* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ +#define REG_T2T_SIFS 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 +#define MSR_MASK 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \ + | RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_C2HCMD BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x12 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8192_EEPROM_ID 0x8129 + +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_VID 0x0A +#define EEPROM_DID 0x0C +#define EEPROM_SVID 0x0E +#define EEPROM_SMID 0x10 + +#define EEPROM_MAC_ADDR 0x16 + +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F +#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 + +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 +#define EEPROM_XTAL_K 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_CHANNEL_PLAN 0x7D +#define EEPROM_VERSION 0x7E +#define EEPROM_CUSTOMER_ID 0x7F + +#define EEPROM_PWRDIFF 0x54 + +#define EEPROM_TXPOWERCCK 0x5A +#define EEPROM_TXPOWERHT40_1S 0x60 +#define EEPROM_TXPOWERHT40_2SDIFF 0x66 +#define EEPROM_TXPOWERHT20DIFF 0x69 +#define EEPROM_TXPOWER_OFDMDIFF 0x6C + +#define EEPROM_TXPWR_GROUP 0x6F + +#define EEPROM_CHANNELPLAN 0x75 + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_FCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYSTS BIT(28) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) +#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_OFFSET 16 +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE 128 +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE +#define EFUSE_MAX_SECTION 16 + +#define WL_HWPDN_EN BIT(0) + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) \ + (((_offset) >= 0x800) && ((_offset) <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c new file mode 100644 index 000000000..8508a711d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c @@ -0,0 +1,482 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = (rtlphy->mcs_offset[0][6]) + + (rtlphy->mcs_offset[0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_offset[0][14]) + + (rtlphy->mcs_offset[0][15] << 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + tmpval = tmpval & 0xff00ffff; + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerbase0, powerbase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerbase0 = powerlevel[i] + legacy_pwrdiff; + + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | + (powerbase1 << 16) | (powerbase1 << 8) | powerbase1; + + *(mcsbase + i) = powerbase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); + } +} + +static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4]; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeval = rtlphy->mcs_offset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + case 1: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + writeval = ((index < 2) ? powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 40MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + } else { + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->pwrgroup_cnt == 4) + chnlgroup++; + } + + writeval = rtlphy->mcs_offset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + } + break; + case 2: + writeval = + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + [chnlgroup][index + + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> + (i * 8)); + + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht40[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht20[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); + + writeval = customer_limit + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + default: + chnlgroup = 0; + writeval = rtlphy->mcs_offset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeval = writeval - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = value[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + + writeval = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + + for (i = 0; i < 3; i++) { + writeval = (writeval > 6) ? (writeval - 6) : 0; + rtl_write_byte(rtlpriv, (u32) (regoffset + i), + (u8)writeval); + } + } + } +} + +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + + rtl92c_phy_get_power_base(hw, ppowerlevel, + channel, &powerbase0[0], &powerbase1[0]); + + for (index = 0; index < 6; index++) { + _rtl92c_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + + _rtl92c_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl92ce_phy_rf6052_config_parafile(hw); + +} + +static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h new file mode 100644 index 000000000..6fa70224d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_RF_H__ +#define __RTL92C_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_PATH 2 + +void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c new file mode 100644 index 000000000..f06b159f9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8192c/dm_common.h" +#include "../rtl8192c/fw_common.h" +#include "../rtl8192c/phy_common.h" +#include "hw.h" +#include "rf.h" +#include "trx.h" +#include "led.h" + +#include + +static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + * */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl92c_init_sw_vars(struct ieee80211_hw *hw) +{ + int err; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + char *fw_name; + + rtl8192ce_bt_reg_init(hw); + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + /* compatible 5G band 88ce just 2.4G band & smsp */ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_AMF | + RCR_ADF | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0); + + rtlpci->irq_mask[0] = + (u32) (IMR_ROK | + IMR_VODOK | + IMR_VIDOK | + IMR_BEDOK | + IMR_BKDOK | + IMR_MGNTDOK | + IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0); + + rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("rtl8192ce: Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("rtl8192ce: FW Power Save off (module option)\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 */ + rtl92c_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw\n"); + return 1; + } + + /* request fw */ + if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && + !IS_92C_SERIAL(rtlhal->version)) + fw_name = "rtlwifi/rtl8192cfwU.bin"; + else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) + fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + else + fw_name = "rtlwifi/rtl8192cfw.bin"; + + rtlpriv->max_fw_size = 0x4000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + return 0; +} + +static void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +static const struct rtl_hal_ops rtl8192ce_hal_ops = { + .init_sw_vars = rtl92c_init_sw_vars, + .deinit_sw_vars = rtl92c_deinit_sw_vars, + .read_eeprom_info = rtl92ce_read_eeprom_info, + .interrupt_recognized = rtl92ce_interrupt_recognized, + .hw_init = rtl92ce_hw_init, + .hw_disable = rtl92ce_card_disable, + .hw_suspend = rtl92ce_suspend, + .hw_resume = rtl92ce_resume, + .enable_interrupt = rtl92ce_enable_interrupt, + .disable_interrupt = rtl92ce_disable_interrupt, + .set_network_type = rtl92ce_set_network_type, + .set_chk_bssid = rtl92ce_set_check_bssid, + .set_qos = rtl92ce_set_qos, + .set_bcn_reg = rtl92ce_set_beacon_related_registers, + .set_bcn_intv = rtl92ce_set_beacon_interval, + .update_interrupt_mask = rtl92ce_update_interrupt_mask, + .get_hw_reg = rtl92ce_get_hw_reg, + .set_hw_reg = rtl92ce_set_hw_reg, + .update_rate_tbl = rtl92ce_update_hal_rate_tbl, + .fill_tx_desc = rtl92ce_tx_fill_desc, + .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, + .query_rx_desc = rtl92ce_rx_query_desc, + .set_channel_access = rtl92ce_update_channel_access_setting, + .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking, + .set_bw_mode = rtl92c_phy_set_bw_mode, + .switch_channel = rtl92c_phy_sw_chnl, + .dm_watchdog = rtl92c_dm_watchdog, + .scan_operation_backup = rtl_phy_scan_operation_backup, + .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .led_control = rtl92ce_led_control, + .set_desc = rtl92ce_set_desc, + .get_desc = rtl92ce_get_desc, + .is_tx_desc_closed = rtl92ce_is_tx_desc_closed, + .tx_polling = rtl92ce_tx_polling, + .enable_hw_sec = rtl92ce_enable_hw_security_config, + .set_key = rtl92ce_set_key, + .get_bbreg = rtl92c_phy_query_bb_reg, + .set_bbreg = rtl92c_phy_set_bb_reg, + .set_rfreg = rtl92ce_phy_set_rf_reg, + .get_rfreg = rtl92c_phy_query_rf_reg, + .phy_rf6052_config = rtl92ce_phy_rf6052_config, + .phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower, + .phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower, + .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, + .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, + .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, + .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, + .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, + .get_btc_status = rtl_btc_status_false, +}; + +static struct rtl_mod_params rtl92ce_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .aspm_support = 1, + .debug_level = 0, + .debug_mask = 0, +}; + +static const struct rtl_hal_cfg rtl92ce_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92c_pci", + .ops = &rtl8192ce_hal_ops, + .mod_params = &rtl92ce_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, +}; + +static const struct pci_device_id rtl92ce_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin"); + +module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92ce_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92ce_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444); +module_param_named(aspm, rtl92ce_mod_params.aspm_support, int, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl92ce_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92ce_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl92ce_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c new file mode 100644 index 000000000..58878db40 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c @@ -0,0 +1,1195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "table.h" + +u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x2b2b2b27, + 0x870, 0x07000700, + 0x874, 0x22184000, + 0x878, 0x08080808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c1b25a4, + 0xe78, 0x0c1b25a4, + 0xe7c, 0x0c1b25a4, + 0xe80, 0x0c1b25a4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c1b25a4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000700, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x0a0c0c0c, + 0xe04, 0xffffffff, 0x02040608, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0e, + 0xe14, 0xffffffff, 0x02040608, + 0xe18, 0xffffffff, 0x0a0c0d0e, + 0xe1c, 0xffffffff, 0x02040608, + 0x830, 0xffffffff, 0x0a0c0c0c, + 0x834, 0xffffffff, 0x02040608, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0a0c0d0e, + 0x848, 0xffffffff, 0x02040608, + 0x84c, 0xffffffff, 0x0a0c0d0e, + 0x868, 0xffffffff, 0x02040608, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x06060606, + 0xe1c, 0xffffffff, 0x00020406, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x06060606, + 0x868, 0xffffffff, 0x00020406, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, +}; + +u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = { + 0x0, +}; + +u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000088, + 0x461, 0x00000088, + 0x462, 0x00000006, + 0x463, 0x00000003, + 0x4c8, 0x00000004, + 0x4c9, 0x00000008, + 0x4cc, 0x00000002, + 0x4cd, 0x00000028, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000020, + 0x547, 0x00000000, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h new file mode 100644 index 000000000..473af27f8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_TABLE__H_ +#define __RTL92CE_TABLE__H_ + +#include + +#define PHY_REG_2TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH]; +#define PHY_REG_1TARRAY_LENGTH 374 +extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH]; +#define PHY_REG_ARRAY_PGLENGTH 192 +extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH]; +#define RADIOA_2TARRAYLENGTH 282 +extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH]; +#define RADIOB_2TARRAYLENGTH 78 +extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH]; +#define RADIOA_1TARRAYLENGTH 282 +extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH]; +#define RADIOB_1TARRAYLENGTH 1 +extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 162 +extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_2TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH]; +#define AGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c new file mode 100644 index 000000000..ed151754f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c @@ -0,0 +1,686 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" + +static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_sts_cck_8192s_t *cck_buf; + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 evm, pwdb_all, rf_rx_num = 0; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck_rate; + + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs); + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->is_cck = is_cck_rate; + pstats->packet_beacon = packet_beacon; + pstats->rx_mimo_sig_qual[0] = -1; + pstats->rx_mimo_sig_qual[1] = -1; + + if (is_cck_rate) { + u8 report, cck_highpwr; + + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + else + cck_highpwr = false; + + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + /* CCK gain is smaller than OFDM/MCS gain, + * so we add gain diff by experiences, + * the val is 6 + */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same + * gain index with OFDM. + */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (packet_match_bssid) { + u8 sq; + + if (pstats->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstats->signalquality = sq; + pstats->rx_mimo_sig_qual[0] = sq; + pstats->rx_mimo_sig_qual[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = + ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + /* Get Rx snr value in DB */ + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + /* Record Signal Strength for next packet */ + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 && + pstats->rate <= DESC_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (packet_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream only + */ + if (i == 0) + pstats->signalquality = + (u8)(evm & 0xff); + pstats->rx_mimo_sig_qual[i] = (u8)(evm & 0xff); + } + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck_rate) + pstats->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, total_rssi /= rf_rx_num)); +} + +static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + __le16 fc; + u16 type, c_fc; + bool packet_matchbssid, packet_toself, packet_beacon = false; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + c_fc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + + packet_matchbssid = + ((IEEE80211_FTYPE_CTL != type) && + ether_addr_equal(mac->bssid, + (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + + packet_toself = packet_matchbssid && + ether_addr_equal(praddr, rtlefuse->dev_addr); + + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + + _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + + rtl_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc8, struct sk_buff *skb) +{ + struct rx_fwinfo_92c *p_drvinfo; + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc8; + struct ieee80211_hdr *hdr; + __le32 *p_desc = (__le32 *)p_desc8; + u32 phystatus = get_rx_desc_physt(p_desc); + + stats->length = (u16)get_rx_desc_pkt_len(p_desc); + stats->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(p_desc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8)(get_rx_desc_shift(p_desc) & 0x03); + stats->icv = (u16)get_rx_desc_icv(p_desc); + stats->crc = (u16)get_rx_desc_crc32(p_desc); + stats->hwerror = (stats->crc | stats->icv); + stats->decrypted = !get_rx_desc_swdec(p_desc); + stats->rate = (u8)get_rx_desc_rxmcs(p_desc); + stats->shortpreamble = (u16)get_rx_desc_splcp(p_desc); + stats->isampdu = (bool)(get_rx_desc_paggr(p_desc) == 1); + stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(p_desc) == 1) && + (get_rx_desc_faggr(p_desc) == 1)); + stats->timestamp_low = get_rx_desc_tsfl(p_desc); + stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(p_desc); + stats->is_ht = (bool)get_rx_desc_rxht(p_desc); + + stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc->rxmcs); + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size + + stats->rx_bufshift); + + if (stats->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (stats->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (stats->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set stats->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (stats->decrypted) { + if ((_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag &= ~RX_FLAG_DECRYPTED; + else + rx_status->flag |= RX_FLAG_DECRYPTED; + } + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + * Notice: this is diff with windows define + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht, + false, stats->rate); + + rx_status->mactime = stats->timestamp_low; + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + + stats->rx_bufshift); + + _rtl92ce_translate_rx_signal_stuff(hw, + skb, stats, pdesc, + p_drvinfo); + } + + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->recvsignalpower + 10; + + return true; +} + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + __le32 *pdesc = (__le32 *)pdesc8; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + u8 bw_40 = 0; + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + rcu_read_lock(); + sta = get_sta(hw, mac->vif, mac->bssid); + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + if (sta) + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; + } + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); + + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_92c)); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_tx_rate(pdesc, tcb_desc->hw_rate); + + if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) + set_tx_desc_data_shortgi(pdesc, 1); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_break(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + + set_tx_desc_rts_enable(pdesc, ((tcb_desc->rts_enable && + !tcb_desc-> + cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, + ((tcb_desc->rts_enable + || tcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_cts2self(pdesc, ((tcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_rts_stbc(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, tcb_desc->rts_rate); + set_tx_desc_rts_bw(pdesc, 0); + set_tx_desc_rts_sc(pdesc, tcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, + ((tcb_desc->rts_rate <= DESC_RATE54M) ? + (tcb_desc->rts_use_shortpreamble ? 1 : 0) + : (tcb_desc->rts_use_shortgi ? 1 : 0))); + + if (bw_40) { + if (tcb_desc->packet_bw) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb->len); + + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + + } + } + + set_tx_desc_pkt_id(pdesc, 0); + set_tx_desc_queue_sel(pdesc, fw_qsel); + + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, 0); + set_tx_desc_use_rate(pdesc, tcb_desc->use_driver_rate ? 1 : 0); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + } + rcu_read_unlock(); + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + + set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(pdesc, tcb_desc->ratr_index); + set_tx_desc_macid(pdesc, tcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + tcb_desc->ratr_index); + set_tx_desc_macid(pdesc, tcb_desc->ratr_index); + } + + if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_pkt_id(pdesc, 8); + } + + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + __le32 *pdesc = (__le32 *)pdesc8; + + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + set_tx_desc_tx_rate(pdesc, DESC_RATE1M); + + set_tx_desc_seq(pdesc, 0); + + set_tx_desc_linip(pdesc, 0); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_offset(pdesc, 0x20); + + set_tx_desc_use_rate(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_pkt_id(pdesc, 8); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); +} + +void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx, + u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + wmb(); + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8192ce: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + wmb(); + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8192ce: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl92ce_get_desc(struct ieee80211_hw *hw, u8 *p_desc8, + bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *p_desc = (__le32 *)p_desc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(p_desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(p_desc); + break; + default: + WARN_ONCE(true, "rtl8192ce: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(p_desc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(p_desc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(p_desc); + break; + default: + WARN_ONCE(true, "rtl8192ce: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl92ce_get_desc(hw, entry, true, HW_DESC_OWN); + + /*beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h new file mode 100644 index 000000000..f3ffe3d98 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h @@ -0,0 +1,531 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_TRX_H__ +#define __RTL92CE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +/* macros to read/write various fields in RX or TX descriptors */ + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_agg_break(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(5)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(7)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16)); +} + +static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_qos(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(6)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(7)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(13)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(25)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(26)); +} + +static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(27)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(6)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 8) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 8))); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline int get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(13, 0)); +} + +static inline int get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(14)); +} + +static inline int get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(15)); +} + +static inline int get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(19, 16)); +} + +static inline int get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(25, 24)); +} + +static inline int get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(26)); +} + +static inline int get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(27)); +} + +static inline int get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 1)), BIT(14)); +} + +static inline int get_rx_desc_faggr(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 1)), BIT(15)); +} + +static inline int get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 3)), GENMASK(5, 0)); +} + +static inline int get_rx_desc_rxht(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 3)), BIT(6)); +} + +static inline int get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 3)), BIT(8)); +} + +static inline int get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*((__pdesc + 3)), BIT(9)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 5))); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 6))); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, int _size) +{ + memset(__pdesc, 0, min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET)); +} + +struct rx_fwinfo_92c { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_92c { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_92c { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); +u64 rtl92ce_get_desc(struct ieee80211_hw *hw, u8 *p_desc, + bool istx, u8 desc_name); +bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile new file mode 100644 index 000000000..8b3921fd2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192cu-objs := \ + dm.o \ + hw.o \ + led.o \ + mac.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192CU) += rtl8192cu.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h new file mode 100644 index 000000000..4757f93b8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../rtl8192ce/def.h" + +/*------------------------------------------------------------------------- + * Chip specific + *-------------------------------------------------------------------------*/ +#define NORMAL_CHIP BIT(4) +#define CHIP_VENDOR_UMC BIT(5) +#define CHIP_VENDOR_UMC_B_CUT BIT(6) + +#define IS_92C_1T2R(version) \ + (((version) & CHIP_92C_1T2R) == CHIP_92C_1T2R) + +#define IS_VENDOR_UMC(version) \ + (((version) & CHIP_VENDOR_UMC) ? true : false) + +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c new file mode 100644 index 000000000..982387269 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" + +void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); + } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_NORMAL) + dm_restorepowerindex(hw); + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) + dm_writepowerindex(hw, 0x14); + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL2) + dm_writepowerindex(hw, 0x10); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h new file mode 100644 index 000000000..2befc2f4e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../rtl8192ce/dm.h" + +void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); +void dm_savepowerindex(struct ieee80211_hw *hw); +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); +void dm_restorepowerindex(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c new file mode 100644 index 000000000..989e7cff8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c @@ -0,0 +1,2171 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../cam.h" +#include "../ps.h" +#include "../usb.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8192c/phy_common.h" +#include "mac.h" +#include "dm.h" +#include "../rtl8192c/dm_common.h" +#include "../rtl8192c/fw_common.h" +#include "hw.h" +#include "../rtl8192ce/hw.h" +#include "trx.h" +#include "led.h" +#include "table.h" + +static void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + + rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH; + rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY; + if (IS_HIGHT_PA(rtlefuse->board_type)) { + rtlphy->hwparam_tables[PHY_REG_PG].length = + RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH; + rtlphy->hwparam_tables[PHY_REG_PG].pdata = + RTL8192CUPHY_REG_ARRAY_PG_HP; + } else { + rtlphy->hwparam_tables[PHY_REG_PG].length = + RTL8192CUPHY_REG_ARRAY_PGLENGTH; + rtlphy->hwparam_tables[PHY_REG_PG].pdata = + RTL8192CUPHY_REG_ARRAY_PG; + } + /* 2T */ + rtlphy->hwparam_tables[PHY_REG_2T].length = + RTL8192CUPHY_REG_2TARRAY_LENGTH; + rtlphy->hwparam_tables[PHY_REG_2T].pdata = + RTL8192CUPHY_REG_2TARRAY; + rtlphy->hwparam_tables[RADIOA_2T].length = + RTL8192CURADIOA_2TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOA_2T].pdata = + RTL8192CURADIOA_2TARRAY; + rtlphy->hwparam_tables[RADIOB_2T].length = + RTL8192CURADIOB_2TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_2T].pdata = + RTL8192CU_RADIOB_2TARRAY; + rtlphy->hwparam_tables[AGCTAB_2T].length = + RTL8192CUAGCTAB_2TARRAYLENGTH; + rtlphy->hwparam_tables[AGCTAB_2T].pdata = + RTL8192CUAGCTAB_2TARRAY; + /* 1T */ + if (IS_HIGHT_PA(rtlefuse->board_type)) { + rtlphy->hwparam_tables[PHY_REG_1T].length = + RTL8192CUPHY_REG_1T_HPARRAYLENGTH; + rtlphy->hwparam_tables[PHY_REG_1T].pdata = + RTL8192CUPHY_REG_1T_HPARRAY; + rtlphy->hwparam_tables[RADIOA_1T].length = + RTL8192CURADIOA_1T_HPARRAYLENGTH; + rtlphy->hwparam_tables[RADIOA_1T].pdata = + RTL8192CURADIOA_1T_HPARRAY; + rtlphy->hwparam_tables[RADIOB_1T].length = + RTL8192CURADIOB_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_1T].pdata = + RTL8192CU_RADIOB_1TARRAY; + rtlphy->hwparam_tables[AGCTAB_1T].length = + RTL8192CUAGCTAB_1T_HPARRAYLENGTH; + rtlphy->hwparam_tables[AGCTAB_1T].pdata = + RTL8192CUAGCTAB_1T_HPARRAY; + } else { + rtlphy->hwparam_tables[PHY_REG_1T].length = + RTL8192CUPHY_REG_1TARRAY_LENGTH; + rtlphy->hwparam_tables[PHY_REG_1T].pdata = + RTL8192CUPHY_REG_1TARRAY; + rtlphy->hwparam_tables[RADIOA_1T].length = + RTL8192CURADIOA_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOA_1T].pdata = + RTL8192CU_RADIOA_1TARRAY; + rtlphy->hwparam_tables[RADIOB_1T].length = + RTL8192CURADIOB_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_1T].pdata = + RTL8192CU_RADIOB_1TARRAY; + rtlphy->hwparam_tables[AGCTAB_1T].length = + RTL8192CUAGCTAB_1TARRAYLENGTH; + rtlphy->hwparam_tables[AGCTAB_1T].pdata = + RTL8192CUAGCTAB_1TARRAY; + } +} + +static noinline_for_stack void +_rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + + i]; + } else { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + for (i = 0; i < 3; i++) { + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0); + } + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); + } + } + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf0) >> 4); + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); + } + } + for (i = 0; i < 14; i++) { + index = rtl92c_get_chnl_group((u8)i); + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + index = rtl92c_get_chnl_group((u8)i); + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); + if (!autoload_fail) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); + if (!autoload_fail) { + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; + } else { + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); + if (!autoload_fail) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + if (rtlefuse->eeprom_thermalmeter < 0x06 || + rtlefuse->eeprom_thermalmeter > 0x1c) + rtlefuse->eeprom_thermalmeter = 0x12; + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->apk_thermalmeterignore = true; + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); +} + +static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boardtype; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + boardtype = ((contents[EEPROM_RF_OPT1]) & + BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/ + } else { + boardtype = contents[EEPROM_RF_OPT4]; + boardtype &= BOARD_TYPE_TEST_MASK; + } + rtlefuse->board_type = boardtype; + if (IS_HIGHT_PA(rtlefuse->board_type)) + rtlefuse->external_pa = 1; + pr_info("Board Type %x\n", rtlefuse->board_type); +} + +static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + 0}; + u8 *hwinfo; + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + _rtl92cu_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, hwinfo); + _rtl92cu_read_board_type(hw, hwinfo); + + rtlefuse->txpwr_fromeprom = true; + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) + rtlhal->oem_id = RT_CID_819X_HP; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } + } +exit: + kfree(hwinfo); +} + +static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); +} + +void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + if (!IS_NORMAL_CHIP(rtlhal->version)) + return; + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? + EEPROM_93C46 : EEPROM_BOOT_EFUSE; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", + tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); + rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", + tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); + _rtl92cu_read_adapter_info(hw); + _rtl92cu_hal_customized_behavior(hw); + return; +} + +static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int status = 0; + u16 value16; + u8 value8; + /* polling autoload done. */ + u32 pollingcount = 0; + + do { + if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Autoload Done!\n"); + break; + } + if (pollingcount++ > 100) { + pr_err("Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); + return -ENODEV; + } + } while (true); + /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); + /* Power on when re-enter from IPS/Radio off/card disable */ + /* enable SPS into PWM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + udelay(100); + value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); + if (0 == (value8 & LDV12_EN)) { + value8 |= LDV12_EN; + rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", + value8); + udelay(100); + value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); + value8 &= ~ISO_MD2PP; + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8); + } + /* auto enable WLAN */ + pollingcount = 0; + value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO); + value16 |= APFM_ONMAC; + rtl_write_word(rtlpriv, REG_APS_FSMCO, value16); + do { + if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) { + pr_info("MAC auto ON okay!\n"); + break; + } + if (pollingcount++ > 1000) { + pr_err("Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); + return -ENODEV; + } + } while (true); + /* Enable Radio ,GPIO ,and LED function */ + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812); + /* release RF digital isolation */ + value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); + value16 &= ~ISO_DIOR; + rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16); + /* Reconsider when to do this operation after asking HWSD. */ + pollingcount = 0; + rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv, + REG_APSD_CTRL) & ~BIT(6))); + do { + pollingcount++; + } while ((pollingcount < 200) && + (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7))); + /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ + value16 = rtl_read_word(rtlpriv, REG_CR); + value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | + PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); + rtl_write_word(rtlpriv, REG_CR, value16); + return status; +} + +static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool ischipn = IS_NORMAL_CHIP(rtlhal->version); + u32 outepnum = (u32)out_ep_num; + u32 numhq = 0; + u32 numlq = 0; + u32 numnq = 0; + u32 numpubq; + u32 value32; + u8 value8; + u32 txqpagenum, txqpageunit, txqremaininpage; + + numpubq = (ischipn) ? CHIP_B_PAGE_NUM_PUBQ : + CHIP_A_PAGE_NUM_PUBQ; + txqpagenum = TX_TOTAL_PAGE_NUMBER - numpubq; + + txqpageunit = txqpagenum / outepnum; + txqremaininpage = txqpagenum % outepnum; + if (queue_sel & TX_SELE_HQ) + numhq = txqpageunit; + if (queue_sel & TX_SELE_LQ) + numlq = txqpageunit; + /* HIGH priority queue always present in the configuration of + * 2 out-ep. Remainder pages have assigned to High queue. + */ + if (outepnum > 1 && txqremaininpage) + numhq += txqremaininpage; + /* NOTE: This step done before writing REG_RQPN. */ + if (ischipn) { + if (queue_sel & TX_SELE_NQ) + numnq = txqpageunit; + value8 = (u8)_NPQ(numnq); + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); + } + /* TX DMA */ + value32 = _HPQ(numhq) | _LPQ(numlq) | _PUBQ(numpubq) | LD_RQPN; + rtl_write_dword(rtlpriv, REG_RQPN, value32); +} + +static void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 txpktbuf_bndy = TX_PAGE_BOUNDARY; + u8 value8; + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy); + rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); + value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128); + rtl_write_byte(rtlpriv, REG_PBP, value8); +} + +static void _rtl92c_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq, + u16 bkq, u16 viq, u16 voq, + u16 mgtq, u16 hiq) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7); + + value16 |= _TXDMA_BEQ_MAP(beq) | _TXDMA_BKQ_MAP(bkq) | + _TXDMA_VIQ_MAP(viq) | _TXDMA_VOQ_MAP(voq) | + _TXDMA_MGQ_MAP(mgtq) | _TXDMA_HIQ_MAP(hiq); + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); +} + +static void _rtl92cu_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + u16 value; + + switch (queue_sel) { + case TX_SELE_HQ: + value = QUEUE_HIGH; + break; + case TX_SELE_LQ: + value = QUEUE_LOW; + break; + case TX_SELE_NQ: + value = QUEUE_NORMAL; + break; + default: + WARN_ON(1); /* Shall not reach here! */ + return; + } + _rtl92c_init_chipn_reg_priority(hw, value, value, value, value, + value, value); + pr_info("Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92cu_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + u16 beq, bkq, viq, voq, mgtq, hiq; + u16 valuehi; + u16 valuelow; + + switch (queue_sel) { + default: + WARN_ON(1); + fallthrough; + case (TX_SELE_HQ | TX_SELE_LQ): + valuehi = QUEUE_HIGH; + valuelow = QUEUE_LOW; + break; + case (TX_SELE_NQ | TX_SELE_LQ): + valuehi = QUEUE_NORMAL; + valuelow = QUEUE_LOW; + break; + case (TX_SELE_HQ | TX_SELE_NQ): + valuehi = QUEUE_HIGH; + valuelow = QUEUE_NORMAL; + break; + } + + beq = valuelow; + bkq = valuelow; + viq = valuehi; + voq = valuehi; + mgtq = valuehi; + hiq = valuehi; + + _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); + pr_info("Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92cu_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + u16 beq, bkq, viq, voq, mgtq, hiq; + + beq = QUEUE_LOW; + bkq = QUEUE_LOW; + viq = QUEUE_NORMAL; + voq = QUEUE_HIGH; + mgtq = QUEUE_HIGH; + hiq = QUEUE_HIGH; + + _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); + pr_info("Tx queue select :0x%02x..\n", queue_sel); +} + +static void _rtl92cu_init_chipn_queue_priority(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + switch (out_ep_num) { + case 1: + _rtl92cu_init_chipn_one_out_ep_priority(hw, queue_sel); + break; + case 2: + _rtl92cu_init_chipn_two_out_ep_priority(hw, queue_sel); + break; + case 3: + _rtl92cu_init_chipn_three_out_ep_priority(hw, queue_sel); + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } +} + +static void _rtl92cu_init_chipt_queue_priority(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + u8 hq_sele = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (out_ep_num) { + case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */ + hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ | HQSEL_HIQ; + break; + case 1: + if (TX_SELE_LQ == queue_sel) { + /* map all endpoint to Low queue */ + hq_sele = 0; + } else if (TX_SELE_HQ == queue_sel) { + /* map all endpoint to High queue */ + hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ | + HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ; + } + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } + rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); + pr_info("Tx queue select :0x%02x..\n", hq_sele); +} + +static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_init_chipn_queue_priority(hw, out_ep_num, queue_sel); + else + _rtl92cu_init_chipt_queue_priority(hw, out_ep_num, queue_sel); +} + +static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) +{ + u16 value16; + u32 value32; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + value32 = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS | + RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | + RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&value32)); + /* Accept all multicast address */ + rtl_write_dword(rtlpriv, REG_MAR, 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xFFFFFFFF); + /* Accept all management frames */ + value16 = 0xFFFF; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, + (u8 *)(&value16)); + /* Reject all control frame - default value is 0 */ + value16 = 0x0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, + (u8 *)(&value16)); + /* Accept all data frames */ + value16 = 0xFFFF; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DATA_FILTER, + (u8 *)(&value16)); +} + +static void _rtl92cu_init_beacon_parameters(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); + + /* TODO: Remove these magic number */ + rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404); + rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); + rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); + /* Change beacon AIFS to the largest number + * beacause test chip does not contension before sending beacon. + */ + if (IS_NORMAL_CHIP(rtlhal->version)) + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); + else + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); +} + +static int _rtl92cu_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + int err = 0; + u32 boundary = TX_PAGE_BOUNDARY; + u8 out_ep_nums = rtlusb->out_ep_nums; + u8 queue_sel = rtlusb->out_queue_sel; + + err = _rtl92cu_init_power_on(hw); + + if (err) { + pr_err("Failed to init power on!\n"); + return err; + } + if (!rtl92c_init_llt_table(hw, boundary)) { + pr_err("Failed to init LLT Table!\n"); + return -EINVAL; + } + _rtl92cu_init_queue_reserved_page(hw, out_ep_nums, queue_sel); + _rtl92c_init_trx_buffer(hw); + _rtl92cu_init_queue_priority(hw, out_ep_nums, queue_sel); + /* Get Rx PHY status in order to report RSSI and others. */ + rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE); + rtl92c_init_interrupt(hw); + rtl92c_init_network_type(hw); + _rtl92cu_init_wmac_setting(hw); + rtl92c_init_adaptive_ctrl(hw); + rtl92c_init_edca(hw); + rtl92c_init_rate_fallback(hw); + rtl92c_init_retry_function(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); + rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); + _rtl92cu_init_beacon_parameters(hw); + rtl92c_init_ampdu_aggregation(hw); + rtl92c_init_beacon_max_error(hw); + return err; +} + +void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value = 0x0; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open sw encryption\n"); + return; + } + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + if (IS_NORMAL_CHIP(rtlhal->version)) + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static void _rtl92cu_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + /* To Fix MAC loopback mode fail. */ + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); + rtl_write_byte(rtlpriv, 0x15, 0xe9); + /* HW SEQ CTRL */ + /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + /* fixed USB interface interference issue */ + rtl_write_byte(rtlpriv, 0xfe40, 0xe0); + rtl_write_byte(rtlpriv, 0xfe41, 0x8d); + rtl_write_byte(rtlpriv, 0xfe42, 0x80); + rtlusb->reg_bcn_ctrl_val = 0x18; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); +} + +static void _initpabias(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 pa_setting; + + /* FIXED PA current issue */ + pa_setting = efuse_read_1byte(hw, 0x1FA); + if (!(pa_setting & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406); + } + if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) && + IS_92C_SERIAL(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406); + } + if (!(pa_setting & BIT(4))) { + pa_setting = rtl_read_byte(rtlpriv, 0x16); + pa_setting &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90); + } +} + +int rtl92cu_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + int err = 0; + unsigned long flags; + + /* As this function can take a very long time (up to 350 ms) + * and can be called with irqs disabled, reenable the irqs + * to let the other devices continue being serviced. + * + * It is safe doing so since our own interrupts will only be enabled + * in a subsequent step. + */ + local_save_flags(flags); + local_irq_enable(); + + rtlhal->fw_ready = false; + rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; + err = _rtl92cu_init_mac(hw); + if (err) { + pr_err("init mac failed!\n"); + goto exit; + } + err = rtl92c_download_fw(hw); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + goto exit; + } + + rtlhal->fw_ready = true; + rtlhal->last_hmeboxnum = 0; /* h2c */ + _rtl92cu_phy_param_tab_init(hw); + rtl92cu_phy_mac_config(hw); + rtl92cu_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl92c_phy_rf_config(hw); + if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && + !IS_92C_SERIAL(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); + } + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl92cu_bb_block_on(hw); + rtl_cam_reset_all_entry(hw); + rtl92cu_enable_hw_security_config(hw); + ppsc->rfpwr_state = ERFON; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + if (ppsc->rfpwr_state == ERFON) { + rtl92c_phy_set_rfpath_switch(hw, 1); + if (rtlphy->iqk_initialized) { + rtl92c_phy_iq_calibrate(hw, true); + } else { + rtl92c_phy_iq_calibrate(hw, false); + rtlphy->iqk_initialized = true; + } + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_phy_lc_calibrate(hw); + } + _rtl92cu_hw_configure(hw); + _initpabias(hw); + rtl92c_dm_init(hw); +exit: + local_irq_disable(); + local_irq_restore(flags); + return err; +} + +static void disable_rfafeandresetbb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/************************************** +a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue +b. RF path 0 offset 0x00 = 0x00 disable RF +c. APSD_CTRL 0x600[7:0] = 0x40 +d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine +e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine +***************************************/ + u8 erfpath = 0, value8 = 0; + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, (enum radio_path)erfpath, 0x0, MASKBYTE0, 0x0); + + value8 |= APSDOFF; + rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/ + value8 = 0; + value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/ + value8 &= (~FEN_BB_GLB_RSTN); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/ +} + +static void _resetdigitalprocedure1(struct ieee80211_hw *hw, bool withouthwsm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->fw_version <= 0x20) { + /***************************** + f. MCUFWDL 0x80[7:0]=0 reset MCU ready status + g. SYS_FUNC_EN 0x02[10]= 0 reset MCU reg, (8051 reset) + h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC reg, DCORE + i. SYS_FUNC_EN 0x02[10]= 1 enable MCU reg, (8051 enable) + ******************************/ + u16 valu16 = 0; + + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 & + (~FEN_CPUEN))); /* reset MCU ,8051 */ + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF; + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | + (FEN_HWPDN|FEN_ELDR))); /* reset MAC */ + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | + FEN_CPUEN)); /* enable MCU ,8051 */ + } else { + u8 retry_cnts = 0; + + /* IF fw in RAM code, do reset */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + /* 8051 reset by self */ + rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); + while ((retry_cnts++ < 100) && + (FEN_CPUEN & rtl_read_word(rtlpriv, + REG_SYS_FUNC_EN))) { + udelay(50); + } + if (retry_cnts >= 100) { + pr_err("8051 reset failed!.........................\n"); + /* if 8051 reset fail, reset MAC. */ + rtl_write_byte(rtlpriv, + REG_SYS_FUNC_EN + 1, + 0x50); + udelay(100); + } + } + /* Reset MAC and Enable 8051 */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + } + if (withouthwsm) { + /***************************** + Without HW auto state machine + g.SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock + h.AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL + i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK + j.SYS_ISu_CTRL 0x00[7:0] = 0xF9 isolated digital to PON + ******************************/ + rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F); + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9); + } +} + +static void _resetdigitalprocedure2(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/***************************** +k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction +l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock +m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON +******************************/ + rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82); +} + +static void _disablegpio(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/*************************************** +j. GPIO_PIN_CTRL 0x44[31:0]=0x000 +k. Value = GPIO_PIN_CTRL[7:0] +l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level +m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 +n. LEDCFG 0x4C[15:0] = 0x8080 +***************************************/ + u8 value8; + u16 value16; + u32 value32; + + /* 1. Disable GPIO[7:0] */ + rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000); + value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; + value8 = (u8)(value32&0x000000FF); + value32 |= ((value8<<8) | 0x00FF0000); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32); + /* 2. Disable GPIO[10:8] */ + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00); + value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F; + value8 = (u8)(value16&0x000F); + value16 |= ((value8<<4) | 0x0780); + rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16); + /* 3. Disable LED0 & 1 */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); +} + +static void disable_analog(struct ieee80211_hw *hw, bool withouthwsm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value16 = 0; + u8 value8 = 0; + + if (withouthwsm) { + /***************************** + n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power + o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power + r. When driver call disable, the ASIC will turn off remaining + clock automatically + ******************************/ + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); + value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); + value8 &= (~LDV12_EN); + rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); + } + +/***************************** +h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode +i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend +******************************/ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); +} + +static void carddisable_hwsm(struct ieee80211_hw *hw) +{ + /* ==== RF Off Sequence ==== */ + disable_rfafeandresetbb(hw); + /* ==== Reset digital sequence ====== */ + _resetdigitalprocedure1(hw, false); + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _disablegpio(hw); + /* ==== Disable analog sequence === */ + disable_analog(hw, false); +} + +static void carddisablewithout_hwsm(struct ieee80211_hw *hw) +{ + /*==== RF Off Sequence ==== */ + disable_rfafeandresetbb(hw); + /* ==== Reset digital sequence ====== */ + _resetdigitalprocedure1(hw, true); + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _disablegpio(hw); + /* ==== Reset digital sequence ====== */ + _resetdigitalprocedure2(hw); + /* ==== Disable analog sequence === */ + disable_analog(hw, true); +} + +static void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlusb->reg_bcn_ctrl_val |= set_bits; + rtlusb->reg_bcn_ctrl_val &= ~clear_bits; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); +} + +static void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 tmp1byte = 0; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, + rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6)); + } +} + +static void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 tmp1byte = 0; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, + rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6))); + } +} + +static void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1)); + else + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); +} + +static void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0); + else + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); +} + +static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + + bt_msr &= 0xfc; + if (type == NL80211_IFTYPE_UNSPECIFIED || type == + NL80211_IFTYPE_STATION) { + _rtl92cu_stop_tx_beacon(hw); + _rtl92cu_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { + _rtl92cu_resume_tx_beacon(hw); + _rtl92cu_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", + type); + } + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not supported!\n", type); + goto error_out; + } + rtl_write_byte(rtlpriv, MSR, bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & MSR_MASK) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +error_out: + return 1; +} + +void rtl92cu_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92cu_set_media_status(hw, opmode); + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + if (rtlusb->disablehwsm) + carddisable_hwsm(hw); + else + carddisablewithout_hwsm(hw); + + /* after power off we should do iqk again */ + rtlpriv->phy.iqk_initialized = false; +} + +void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 reg_rcr; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + + if (check_bssid) { + u8 tmp; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + tmp = BIT(4); + } else { + reg_rcr |= RCR_CBSSID; + tmp = BIT(4) | BIT(5); + } + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *) (®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); + } else { + u8 tmp; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + tmp = BIT(4); + } else { + reg_rcr &= ~RCR_CBSSID; + tmp = BIT(4) | BIT(5); + } + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *) (®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); + } +} + +/*========================================================================== */ + +int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92cu_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92cu_set_check_bssid(hw, true); + } else { + rtl92cu_set_check_bssid(hw, false); + } + + return 0; +} + +static void _beacon_function_enable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00); + rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F); +} + +void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + u32 value32; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + _rtl92cu_init_beacon_parameters(hw); + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + /* + * Force beacon frame transmission even after receiving beacon frame + * from other ad hoc STA + * + * + * Reset TSF Timer to zero, added by Roger. 2008.06.24 + */ + value32 = rtl_read_dword(rtlpriv, REG_TCR); + value32 &= ~TSFRST; + rtl_write_dword(rtlpriv, REG_TCR, value32); + value32 |= TSFRST; + rtl_write_dword(rtlpriv, REG_TCR, value32); + rtl_dbg(rtlpriv, COMP_INIT | COMP_BEACON, DBG_LOUD, + "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", + value32); + /* TODO: Modify later (Find the right parameters) + * NOTE: Fix test chip's bug (about contention windows's randomness) */ + if ((mac->opmode == NL80211_IFTYPE_ADHOC) || + (mac->opmode == NL80211_IFTYPE_MESH_POINT) || + (mac->opmode == NL80211_IFTYPE_AP)) { + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); + } + _beacon_function_enable(hw); +} + +void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); +} + +void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ +} + +void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = mac->rx_conf; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + *((u64 *)(val)) = tsf; + break; + } + case HW_VAR_MGT_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); + break; + case HW_VAR_CTRL_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); + break; + case HW_VAR_DATA_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); + break; + case HAL_DEF_WOWLAN: + break; + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +static bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + /* Currently nothing happens here. + * Traffic stops after some seconds in WPA2 802.11n mode. + * Maybe because rtl8192cu chip should be set from here? + * If I understand correctly, the realtek vendor driver sends some urbs + * if its "here". + * + * This is maybe necessary: + * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, skb); + */ + dev_kfree_skb(skb); + + return true; +} + +void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx = 0; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + + rate_cfg &= 0x15f; + /* TODO */ + /* if (mac->current_network.vender == HT_IOT_PEER_CISCO + * && ((rate_cfg & 0x150) == 0)) { + * rate_cfg |= 0x010; + * } */ + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (rate_cfg >> 8) & 0xff); + while (rate_cfg > 0x1) { + rate_cfg >>= 1; + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]); + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); + rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + &e_aci); + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)*val; + + reg_tmp = 0; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *val; + if (min_spacing_to_set <= 7) { + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case NO_ENCRYPTION: + case AESCCMP_ENCRYPTION: + sec_min_space = 0; + break; + case WEP40_ENCRYPTION: + case WEP104_ENCRYPTION: + case TKIP_ENCRYPTION: + sec_min_space = 6; + break; + default: + sec_min_space = 7; + break; + } + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + *val = min_spacing_to_set; + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *val; + density_to_set &= 0x1f; + mac->min_space_cfg &= 0x07; + mac->min_space_cfg |= (density_to_set << 3); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + factor_toset = *val; + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) + | (factor_toset << 4); + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) + | (factor_toset); + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + } + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *val; + u32 u4b_ac_param; + u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); + u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); + u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); + + u4b_ac_param = (u32) mac->ac[e_aci].aifs; + u4b_ac_param |= (u32) ((cw_min & 0xF) << + AC_PARAM_ECW_MIN_OFFSET); + u4b_ac_param |= (u32) ((cw_max & 0xF) << + AC_PARAM_ECW_MAX_OFFSET); + u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "queue:%x, ac_param:%x\n", + e_aci, u4b_ac_param); + switch (e_aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, + u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, + u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, + u4b_ac_param); + break; + default: + WARN_ONCE(true, "rtl8192cu: invalid aci: %d !\n", + e_aci); + break; + } + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + mac->rx_conf = ((u32 *) (val))[0]; + rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, + "### Set RCR(0x%08x) ###\n", mac->rx_conf); + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = val[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + rtl_dbg(rtlpriv, COMP_MLME, DBG_DMESG, + "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", + retry_limit); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *val; + break; + case HW_VAR_IO_CMD: + rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *val); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); + + if (rpwm_val & BIT(7)) + rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val); + else + rtl_write_byte(rtlpriv, REG_USB_HRPWM, + *val | BIT(7)); + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = *val; + + if ((psmode != FW_PS_ACTIVE_MODE) && + (!IS_92C_SERIAL(rtlhal->version))) + rtl92c_dm_rf_saving(hw, true); + rtl92c_set_fw_pwrmode_cmd(hw, (*val)); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = *val; + u8 tmp_reg422; + bool recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AID, NULL); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x03); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + tmp_reg422 = rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + rtl92c_set_fw_rsvdpagepkt(hw, + &usb_cmd_send_packet); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); + if (recover) + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 | BIT(6)); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + } + rtl92c_set_fw_joinbss_report_cmd(hw, (*val)); + break; + } + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, + (u2btmp | mac->assoc_id)); + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = val[0]; + + if (btype_ibss) + _rtl92cu_stop_tx_beacon(hw); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); + rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & + 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); + if (btype_ibss) + _rtl92cu_resume_tx_beacon(hw); + break; + } + case HW_VAR_MGT_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val); + mac->rx_mgt_filter = *(u16 *)val; + break; + case HW_VAR_CTRL_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val); + mac->rx_ctrl_filter = *(u16 *)val; + break; + case HW_VAR_DATA_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); + mac->rx_data_filter = *(u16 *)val; + break; + case HW_VAR_KEEP_ALIVE:{ + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2, + array); + break; + } + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 nmode = mac->ht_enable; + u8 mimo_ps = IEEE80211_SMPS_OFF; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + if (mimo_ps == IEEE80211_SMPS_STATIC) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + ratr_value &= 0x0FFFFFFF; + + if (nmode && ((curtxbw_40mhz && + curshortgi_40mhz) || (!curtxbw_40mhz && + curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curshortgi_40mhz = curtxbw_40mhz && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + u8 mimo_ps = IEEE80211_SMPS_OFF; + + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (mimo_ps == IEEE80211_SMPS_STATIC) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %5phC\n", + ratr_index, ratr_bitmap, rate_mask); + memcpy(rtlpriv->rate_mask, rate_mask, 5); + /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a + * "scheduled while atomic" if called directly */ + schedule_work(&rtlpriv->works.fill_h2c_cmd); + + if (macid != 0) + sta_entry->ratr_index = ratr_index; +} + +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92cu_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl92cu_update_hal_rate_table(hw, sta); +} + +void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; + u8 u1tmp = 0; + bool actuallyset = false; + unsigned long flag = 0; + /* to do - usb autosuspend */ + u8 usb_autosuspend = 0; + + if (ppsc->swrf_processing) + return false; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + cur_rfstate = ppsc->rfpwr_state; + if (usb_autosuspend) { + /* to do................... */ + } else { + if (ppsc->pwrdown_mode) { + u1tmp = rtl_read_byte(rtlpriv, REG_HSISR); + e_rfpowerstate_toset = (u1tmp & BIT(7)) ? + ERFOFF : ERFON; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); + } else { + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, + rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG) & ~(BIT(3))); + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? + ERFON : ERFOFF; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "GPIO_IN=%02x\n", u1tmp); + } + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", + e_rfpowerstate_toset); + } + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + ppsc->hwradiooff = false; + actuallyset = true; + } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == + ERFOFF)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio OFF\n"); + ppsc->hwradiooff = true; + actuallyset = true; + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", + ppsc->hwradiooff, e_rfpowerstate_toset); + } + if (actuallyset) { + ppsc->hwradiooff = true; + if (e_rfpowerstate_toset == ERFON) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3)) + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + } + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + /* For power down module, we need to enable register block + * contrl reg at 0x1c. Then enable power down control bit + * of register 0x04 BIT4 and BIT15 as 1. + */ + if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) { + /* Enable register area 0x0-0xc. */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812); + } + if (e_rfpowerstate_toset == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + } + } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { + /* Enter D3 or ASPM after GPIO had been done. */ + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + *valid = 1; + return !ppsc->hwradiooff; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h new file mode 100644 index 000000000..5c48c3fd4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CU_HW_H__ +#define __RTL92CU_HW_H__ + +#define H2C_RA_MASK 6 + +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define RX_PAGE_SIZE_REG_VALUE PBP_128 +/* Note: We will divide number of page equally for each queue + * other than public queue! */ +#define TX_TOTAL_PAGE_NUMBER 0xF8 +#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1) + +#define CHIP_B_PAGE_NUM_PUBQ 0xE7 + +/* For Test Chip Setting + * (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */ +#define CHIP_A_PAGE_NUM_PUBQ 0x7E + +/* For Chip A Setting */ +#define WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_CHIP_A_TX_PAGE_BOUNDARY \ + (WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ + +#define WMM_CHIP_A_PAGE_NUM_PUBQ 0xA3 +#define WMM_CHIP_A_PAGE_NUM_HPQ 0x29 +#define WMM_CHIP_A_PAGE_NUM_LPQ 0x29 + +/* Note: For Chip B Setting ,modify later */ +#define WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_CHIP_B_TX_PAGE_BOUNDARY \ + (WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ + +#define WMM_CHIP_B_PAGE_NUM_PUBQ 0xB0 +#define WMM_CHIP_B_PAGE_NUM_HPQ 0x29 +#define WMM_CHIP_B_PAGE_NUM_LPQ 0x1C +#define WMM_CHIP_B_PAGE_NUM_NPQ 0x1C + +#define BOARD_TYPE_NORMAL_MASK 0xE0 +#define BOARD_TYPE_TEST_MASK 0x0F + +/* should be renamed and moved to another file */ +enum _BOARD_TYPE_8192CUSB { + BOARD_USB_DONGLE = 0, /* USB dongle */ + BOARD_USB_HIGH_PA = 1, /* USB dongle - high power PA */ + BOARD_MINICARD = 2, /* Minicard */ + BOARD_USB_SOLO = 3, /* USB solo-Slim module */ + BOARD_USB_COMBO = 4, /* USB Combo-Slim module */ +}; + +#define IS_HIGHT_PA(boardtype) \ + ((boardtype == BOARD_USB_HIGH_PA) ? true : false) + +#define RTL92C_DRIVER_INFO_SIZE 4 +void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw); +int rtl92cu_hw_init(struct ieee80211_hw *hw); +void rtl92cu_card_disable(struct ieee80211_hw *hw); +int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); + +void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); +void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c new file mode 100644 index 000000000..bfc07efd0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../usb.h" +#include "reg.h" +#include "led.h" + +void rtl92cu_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl92cu_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl92cu_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h new file mode 100644 index 000000000..8175f8bdd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CU_LED_H__ +#define __RTL92CU_LED_H__ + +void rtl92cu_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92cu_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c new file mode 100644 index 000000000..a76f2dc8a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c @@ -0,0 +1,747 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../usb.h" +#include "../ps.h" +#include "../cam.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "mac.h" +#include "trx.h" +#include "../rtl8192c/fw_common.h" + +#include + +/* macro to shorten lines */ + +#define LINK_Q ui_link_quality +#define RX_EVM rx_evm_percentage +#define RX_SIGQ rx_mimo_sig_qual + +void rtl92c_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + enum version_8192c chip_version = VERSION_UNKNOWN; + const char *versionid; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C : + VERSION_TEST_CHIP_88C; + } else { + /* Normal mass production chip. */ + chip_version = NORMAL_CHIP; + chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0); + chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + if (IS_VENDOR_UMC(chip_version)) + chip_version |= ((value32 & CHIP_VER_RTL_MASK) ? + CHIP_VENDOR_UMC_B_CUT : 0); + if (IS_92C_SERIAL(chip_version)) { + value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); + chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) == + CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0); + } + } + rtlhal->version = (enum version_8192c)chip_version; + pr_info("Chip version 0x%x\n", chip_version); + switch (rtlhal->version) { + case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: + versionid = "NORMAL_B_CHIP_92C"; + break; + case VERSION_NORMAL_TSMC_CHIP_92C: + versionid = "NORMAL_TSMC_CHIP_92C"; + break; + case VERSION_NORMAL_TSMC_CHIP_88C: + versionid = "NORMAL_TSMC_CHIP_88C"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: + versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: + versionid = "NORMAL_UMC_CHIP_92C_A_CUT"; + break; + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: + versionid = "NORMAL_UMC_CHIP_88C_A_CUT"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: + versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT"; + break; + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: + versionid = "NORMAL_UMC_CHIP_92C_B_CUT"; + break; + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: + versionid = "NORMAL_UMC_CHIP_88C_B_CUT"; + break; + case VERSION_TEST_CHIP_92C: + versionid = "TEST_CHIP_92C"; + break; + case VERSION_TEST_CHIP_88C: + versionid = "TEST_CHIP_88C"; + break; + default: + versionid = "UNKNOWN"; + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + + if (IS_92C_SERIAL(rtlhal->version)) + rtlphy->rf_type = + (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; + else + rtlphy->rf_type = RF_1T1R; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : + rtlphy->rf_type == RF_1T2R ? "RF_1T2R" : "RF_1T1R"); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); +} + +/** + * rtl92c_llt_write - LLT table write access + * @hw: Pointer to the ieee80211_hw structure. + * @address: LLT logical address. + * @data: LLT data content + * + * Realtek hardware access function. + * + */ +bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n", + address, _LLT_OP_VALUE(value)); + status = false; + break; + } + } while (++count); + return status; +} + +/** + * rtl92c_init_llt_table - Init LLT table + * @hw: Pointer to the ieee80211_hw structure. + * @boundary: Page boundary. + * + * Realtek hardware access function. + */ +bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary) +{ + bool rst = true; + u32 i; + + for (i = 0; i < (boundary - 1); i++) { + rst = rtl92c_llt_write(hw, i , i + 1); + if (!rst) { + pr_err("===> %s #1 fail\n", __func__); + return rst; + } + } + /* end of list */ + rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF); + if (!rst) { + pr_err("===> %s #2 fail\n", __func__); + return rst; + } + /* Make the other pages as ring buffer + * This ring buffer is used as beacon buffer if we config this MAC + * as two MAC transfer. + * Otherwise used as local loopback buffer. + */ + for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) { + rst = rtl92c_llt_write(hw, i, (i + 1)); + if (!rst) { + pr_err("===> %s #3 fail\n", __func__); + return rst; + } + } + /* Let last entry point to the start entry of ring buffer */ + rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary); + if (!rst) { + pr_err("===> %s #4 fail\n", __func__); + return rst; + } + return rst; +} + +void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + pr_err("illegal switch case\n"); + enc_algo = CAM_TKIP; + break; + } + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry\n"); + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec. + key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } + } +} + +u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS); +} + +void rtl92c_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + if (IS_HARDWARE_TYPE_8192CE(rtlpriv)) { + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & + 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & + 0xFFFFFFFF); + } else { + rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] & + 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] & + 0xFFFFFFFF); + } +} + +void rtl92c_init_interrupt(struct ieee80211_hw *hw) +{ + rtl92c_enable_interrupt(hw); +} + +void rtl92c_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); +} + +void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl92c_dm_init_edca_turbo(hw); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, (u8 *)&aci); +} + +void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size); +} + +int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + u8 value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + value = NT_NO_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + value = NT_LINK_AD_HOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + value = NT_LINK_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + value = NT_AS_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Set Network type to AP!\n"); + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Network type %d not supported!\n", type); + return -EOPNOTSUPP; + } + rtl_write_byte(rtlpriv, MSR, value); + return 0; +} + +void rtl92c_init_network_type(struct ieee80211_hw *hw) +{ + rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED); +} + +void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw) +{ + u16 value16; + u32 value32; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Response Rate Set */ + value32 = rtl_read_dword(rtlpriv, REG_RRSR); + value32 &= ~RATE_BITMAP_ALL; + value32 |= RATE_RRSR_CCK_ONLY_1M; + rtl_write_dword(rtlpriv, REG_RRSR, value32); + /* SIFS (used in NAV) */ + value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); + rtl_write_word(rtlpriv, REG_SPEC_SIFS, value16); + /* Retry Limit */ + value16 = _LRL(0x30) | _SRL(0x30); + rtl_write_dword(rtlpriv, REG_RL, value16); +} + +void rtl92c_init_rate_fallback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Set Data Auto Rate Fallback Retry Count register. */ + rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC+4, 0x10080404); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201); + rtl_write_dword(rtlpriv, REG_RARFRC+4, 0x08070605); +} + +static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs, + u8 ctx_sifs) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs); + rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs); +} + +static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs, + u8 ctx_sifs) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs); + rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs); +} + +void rtl92c_init_edca_param(struct ieee80211_hw *hw, + u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs) +{ + /* sequence: VO, VI, BE, BK ==> the same as 92C hardware design. + * referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function. + */ + u32 value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + value = (u32)aifs; + value |= ((u32)cw_min & 0xF) << 8; + value |= ((u32)cw_max & 0xF) << 12; + value |= (u32)txop << 16; + /* 92C hardware register sequence is the same as queue number. */ + rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value); +} + +void rtl92c_init_edca(struct ieee80211_hw *hw) +{ + u16 value16; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* disable EDCCA count down, to reduce collison and retry */ + value16 = rtl_read_word(rtlpriv, REG_RD_CTRL); + value16 |= DIS_EDCA_CNT_DWN; + rtl_write_word(rtlpriv, REG_RD_CTRL, value16); + /* Update SIFS timing. ?????????? + * pHalData->SifsTime = 0x0e0e0a0a; */ + rtl92c_set_cck_sifs(hw, 0xa, 0xa); + rtl92c_set_ofdm_sifs(hw, 0xe, 0xe); + /* Set CCK/OFDM SIFS to be 10us. */ + rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a); + rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010); + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204); + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004); + /* TXOP */ + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B); + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F); + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324); + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226); + /* PIFS */ + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + /* AGGR BREAK TIME Register */ + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02); + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02); +} + +void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + /* init AMPDU aggregation number, tuning for Tx's TP, */ + rtl_write_word(rtlpriv, 0x4CA, 0x0708); +} + +void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF); +} + +void rtl92c_init_rdg_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF); + rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); + rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); +} + +void rtl92c_init_retry_function(struct ieee80211_hw *hw) +{ + u8 value8; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL); + value8 |= EN_AMPDU_RTY_NEW; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8); + /* Set ACK timeout */ + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); +} + +void rtl92c_disable_fast_edca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0); +} + +void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T; + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value); +} + +/*==============================================================*/ + +static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92c *p_desc, + struct rx_fwinfo_92c *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct phy_sts_cck_8192s_t *cck_buf; + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool in_powersavemode = false; + bool is_cck_rate; + __le32 *pdesc = (__le32 *)p_desc; + + is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc->rxmcs); + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; + pstats->RX_SIGQ[0] = -1; + pstats->RX_SIGQ[1] = -1; + if (is_cck_rate) { + u8 report, cck_highpwr; + + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + if (!in_powersavemode) + cck_highpwr = rtlphy->cck_high_power; + else + cck_highpwr = false; + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + if (packet_match_bssid) { + u8 sq; + + if (pstats->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + pstats->signalquality = sq; + pstats->RX_SIGQ[0] = sq; + pstats->RX_SIGQ[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + rx_pwr[i] = + ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + if (get_rx_desc_rx_mcs(pdesc) && + get_rx_desc_rx_mcs(pdesc) >= DESC_RATEMCS8 && + get_rx_desc_rx_mcs(pdesc) <= DESC_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + if (packet_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8) (evm & 0xff); + pstats->RX_SIGQ[i] = + (u8) (evm & 0xff); + } + } + } + if (is_cck_rate) + pstats->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, total_rssi /= rf_rx_num)); +} + +void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + __le16 fc; + u16 type, cpu_fc; + bool packet_matchbssid, packet_toself, packet_beacon = false; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + cpu_fc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + packet_matchbssid = + ((IEEE80211_FTYPE_CTL != type) && + ether_addr_equal(mac->bssid, + (cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + + packet_toself = packet_matchbssid && + ether_addr_equal(praddr, rtlefuse->dev_addr); + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + rtl_process_phyinfo(hw, tmp_buf, pstats); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h new file mode 100644 index 000000000..dd76a0582 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_MAC_H__ +#define __RTL92C_MAC_H__ + +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 +#define DRIVER_EARLY_INT_TIME 0x05 +#define BCN_DMA_ATIME_INT_TIME 0x02 + +void rtl92c_read_chip_version(struct ieee80211_hw *hw); +bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data); +bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary); +void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); +void rtl92c_enable_interrupt(struct ieee80211_hw *hw); +void rtl92c_disable_interrupt(struct ieee80211_hw *hw); +void rtl92c_set_qos(struct ieee80211_hw *hw, int aci); + +/*--------------------------------------------------------------- + * Hardware init functions + *---------------------------------------------------------------*/ +void rtl92c_init_interrupt(struct ieee80211_hw *hw); +void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size); + +int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92c_init_network_type(struct ieee80211_hw *hw); +void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw); +void rtl92c_init_rate_fallback(struct ieee80211_hw *hw); + +void rtl92c_init_edca_param(struct ieee80211_hw *hw, + u16 queue, + u16 txop, + u8 ecwmax, + u8 ecwmin, + u8 aifs); + +void rtl92c_init_edca(struct ieee80211_hw *hw); +void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw); +void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw); +void rtl92c_init_rdg_setting(struct ieee80211_hw *hw); +void rtl92c_init_retry_function(struct ieee80211_hw *hw); + +void rtl92c_disable_fast_edca(struct ieee80211_hw *hw); +void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T); + +u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); + +struct rx_fwinfo_92c { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct rx_desc_92c { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + u32 macid:5; /* word 1 */ + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + u32 seq:12; /* word 2 */ + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + u32 rxmcs:6; /* word 3 */ + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + u32 iv1; /* word 4 */ + u32 tsfl; /* word 5 */ + u32 bufferaddress; /* word 6 */ + u32 bufferaddress64; /* word 7 */ +} __packed; + +enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc, + unsigned int + skb_queue); +void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo); + +/*--------------------------------------------------------------- + * Card disable functions + *---------------------------------------------------------------*/ + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c new file mode 100644 index 000000000..0b8cb7e61 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8192c/phy_common.h" +#include "rf.h" +#include "dm.h" +#include "../rtl8192c/dm_common.h" +#include "../rtl8192c/fw_common.h" +#include "table.h" + +u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, regaddr); + } else { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + return readback_value; +} + +void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) +{ + bool rtstatus; + + rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw); + return rtstatus; +} + +bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regval32; + u8 b_reg_hwparafile = 1; + + _rtl92c_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) | + BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | + FEN_BB_GLB_RSTN | FEN_BBRSTB); + regval32 = rtl_read_dword(rtlpriv, 0x87c); + rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31))); + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_ARRAY\n"); + arraylength = rtlphy->hwparam_tables[MAC_REG].length ; + ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CUMAC_2T_ARRAY\n"); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (IS_92C_SERIAL(rtlhal->version)) { + agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length; + agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata; + phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length; + phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata; + } else { + agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length; + agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata; + phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length; + phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata; + } + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + rtl_addr_delay(phy_regarray_table[i]); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The phy_regarray_table[0] is %x Rtl819XPHY_REGARRAY[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl819XPHY_REGARRAY[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + } + return true; +} + +bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + rtlphy->pwrgroup_cnt = 0; + phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length; + phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata; + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + rtl_addr_delay(phy_regarray_table_pg[i]); + _rtl92c_store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + int i; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (IS_92C_SERIAL(rtlhal->version)) { + radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length; + radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata; + radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; + radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_A:RTL8192CURADIOA_2TARRAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_B:RTL8192CU_RADIOB_2TARRAY\n"); + } else { + radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; + radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; + radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; + radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_A:RTL8192CU_RADIOA_1TARRAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio_B:RTL8192CU_RADIOB_1TARRAY\n"); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + } + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + } + break; + case RF90_PATH_C: + case RF90_PATH_D: + pr_err("switch case %#x not processed\n", rfpath); + break; + default: + break; + } + return true; +} + +void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); +} + +void rtl92cu_bb_block_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + mutex_lock(&rtlpriv->io.bb_mutex); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + mutex_unlock(&rtlpriv->io.bb_mutex); +} + +void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + mdelay(100); + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 init_count = 0; + + do { + init_count++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (init_count < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl92ce_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, + queue_id, + skb_queue_len(&ring->queue)); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + return false; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl92c_phy_set_rf_sleep(hw); + break; + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h new file mode 100644 index 000000000..a3cc980c4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../rtl8192ce/phy.h" + +void rtl92cu_bb_block_on(struct ieee80211_hw *hw); +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); +bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw); +u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask); +void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); +bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h new file mode 100644 index 000000000..b4b6cde23 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../rtl8192ce/reg.h" diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c new file mode 100644 index 000000000..288033f02 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c @@ -0,0 +1,442 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = { 0, 0 }, tmpval = 0; + u8 idx1, idx2; + u8 *ptr; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + if (tx_agc[idx1] > 0x20 && rtlefuse->external_pa) + tx_agc[idx1] = 0x20; + } + } else { + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) { + tx_agc[RF90_PATH_A] = 0x10101010; + tx_agc[RF90_PATH_B] = 0x10101010; + } else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL2) { + tx_agc[RF90_PATH_A] = 0x00000000; + tx_agc[RF90_PATH_B] = 0x00000000; + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = (rtlphy->mcs_offset[0][6]) + + (rtlphy->mcs_offset[0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + tmpval = (rtlphy->mcs_offset[0][14]) + + (rtlphy->mcs_offset[0][15] << 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + } + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + if (mac->mode == WIRELESS_MODE_B) + tmpval = tmpval & 0xff00ffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerbase0, powerbase1; + u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerbase0 = powerlevel[i] + legacy_pwrdiff; + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); + } + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | + (powerbase1 << 16) | (powerbase1 << 8) | powerbase1; + *(mcsbase + i) = powerbase1; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); + } +} + +static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4]; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + writeval = rtlphy->mcs_offset + [chnlgroup][index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance,writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + chnlgroup++; + else + chnlgroup += 4; + } + writeval = rtlphy->mcs_offset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : + powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + case 2: + writeval = ((index < 2) ? powerbase0[rf] : + powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory,writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + case 3: + chnlgroup = 0; + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHzrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + [chnlgroup][index + (rf ? 8 : 0)] + & (0x7f << (i * 8))) >> (i * 8)); + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]) + pwr_diff_limit[i] = rtlefuse-> + pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); + writeval = customer_limit + ((index < 2) ? + powerbase0[rf] : powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + default: + chnlgroup = 0; + writeval = rtlphy->mcs_offset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writevalrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + break; + } + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) + writeval = 0x14141414; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL2) + writeval = 0x00000000; + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = value[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << (i * 8))) >> + (i * 8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + writeval = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + for (i = 0; i < 3; i++) { + if (i != 2) + writeval = (writeval > 8) ? + (writeval - 8) : 0; + else + writeval = (writeval > 6) ? + (writeval - 6) : 0; + rtl_write_byte(rtlpriv, (u32)(regoffset + i), + (u8)writeval); + } + } + } +} + +void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index = 0; + + rtl92c_phy_get_power_base(hw, ppowerlevel, + channel, &powerbase0[0], &powerbase1[0]); + for (index = 0; index < 6; index++) { + _rtl92c_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + _rtl92c_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool rtstatus = true; + u8 b_reg_hwparafile = 1; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_rf6052_config_parafile(hw); + return rtstatus; +} + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + pphyreg = &rtlphy->phyreg_def[rfpath]; + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_B: + rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + goto phy_rf_cfg_fail; + } + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); +phy_rf_cfg_fail: + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h new file mode 100644 index 000000000..2661e5f8f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CU_RF_H__ +#define __RTL92CU_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_PATH 2 + +void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c new file mode 100644 index 000000000..9480823af --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../usb.h" +#include "../efuse.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "mac.h" +#include "dm.h" +#include "rf.h" +#include "trx.h" +#include "led.h" +#include "hw.h" +#include "../rtl8192c/fw_common.h" +#include + +MODULE_AUTHOR("Georgia "); +MODULE_AUTHOR("Ziv Huang "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin"); + +static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + char *fw_name; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = kmalloc(0x4000, GFP_KERNEL); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw\n"); + return 1; + } + if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && + !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { + fw_name = "rtlwifi/rtl8192cufw_A.bin"; + } else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) { + fw_name = "rtlwifi/rtl8192cufw_B.bin"; + } else { + fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; + } + pr_info("Loading firmware %s\n", fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, + fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + if (err) { + kfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } + return err; +} + +static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + kfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +static bool rtl92cu_get_btc_status(void) +{ + return false; +} + +static const struct rtl_hal_ops rtl8192cu_hal_ops = { + .init_sw_vars = rtl92cu_init_sw_vars, + .deinit_sw_vars = rtl92cu_deinit_sw_vars, + .read_chip_version = rtl92c_read_chip_version, + .read_eeprom_info = rtl92cu_read_eeprom_info, + .enable_interrupt = rtl92c_enable_interrupt, + .disable_interrupt = rtl92c_disable_interrupt, + .hw_init = rtl92cu_hw_init, + .hw_disable = rtl92cu_card_disable, + .set_network_type = rtl92cu_set_network_type, + .set_chk_bssid = rtl92cu_set_check_bssid, + .set_qos = rtl92c_set_qos, + .set_bcn_reg = rtl92cu_set_beacon_related_registers, + .set_bcn_intv = rtl92cu_set_beacon_interval, + .update_interrupt_mask = rtl92cu_update_interrupt_mask, + .get_hw_reg = rtl92cu_get_hw_reg, + .set_hw_reg = rtl92cu_set_hw_reg, + .update_rate_tbl = rtl92cu_update_hal_rate_tbl, + .fill_tx_desc = rtl92cu_tx_fill_desc, + .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, + .query_rx_desc = rtl92cu_rx_query_desc, + .set_channel_access = rtl92cu_update_channel_access_setting, + .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking, + .set_bw_mode = rtl92c_phy_set_bw_mode, + .switch_channel = rtl92c_phy_sw_chnl, + .dm_watchdog = rtl92c_dm_watchdog, + .scan_operation_backup = rtl_phy_scan_operation_backup, + .set_rf_power_state = rtl92cu_phy_set_rf_power_state, + .led_control = rtl92cu_led_control, + .enable_hw_sec = rtl92cu_enable_hw_security_config, + .set_key = rtl92c_set_key, + .get_bbreg = rtl92c_phy_query_bb_reg, + .set_bbreg = rtl92c_phy_set_bb_reg, + .get_rfreg = rtl92cu_phy_query_rf_reg, + .set_rfreg = rtl92cu_phy_set_rf_reg, + .phy_rf6052_config = rtl92cu_phy_rf6052_config, + .phy_rf6052_set_cck_txpower = rtl92cu_phy_rf6052_set_cck_txpower, + .phy_rf6052_set_ofdm_txpower = rtl92cu_phy_rf6052_set_ofdm_txpower, + .config_bb_with_headerfile = _rtl92cu_phy_config_bb_with_headerfile, + .config_bb_with_pgheaderfile = _rtl92cu_phy_config_bb_with_pgheaderfile, + .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, + .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, + .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, + .fill_h2c_cmd = rtl92c_fill_h2c_cmd, + .get_btc_status = rtl92cu_get_btc_status, +}; + +static struct rtl_mod_params rtl92cu_mod_params = { + .sw_crypto = 0, + .debug_level = 0, + .debug_mask = 0, +}; + +module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92cu_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92cu_mod_params.debug_mask, ullong, 0644); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); + +static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { + /* rx */ + .rx_urb_num = RTL92C_NUM_RX_URBS, + .rx_max_size = RTL92C_SIZE_MAX_RX_BUFFER, + .usb_rx_hdl = rtl8192cu_rx_hdl, + .usb_rx_segregate_hdl = NULL, + /* tx */ + .usb_tx_cleanup = rtl8192c_tx_cleanup, + .usb_tx_post_hdl = rtl8192c_tx_post_hdl, + .usb_tx_aggregate_hdl = rtl8192c_tx_aggregate_hdl, + /* endpoint mapping */ + .usb_endpoint_mapping = rtl8192cu_endpoint_mapping, + .usb_mq_to_hwq = rtl8192cu_mq_to_hwq, +}; + +static const struct rtl_hal_cfg rtl92cu_hal_cfg = { + .name = "rtl92c_usb", + .alt_fw_name = "rtlwifi/rtl8192cufw.bin", + .ops = &rtl8192cu_hal_ops, + .mod_params = &rtl92cu_mod_params, + .usb_interface_cfg = &rtl92cu_interface_cfg, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, +}; + +#define USB_VENDOR_ID_REALTEK 0x0bda + +/* 2010-10-19 DID_USB_V3.4 */ +static const struct usb_device_id rtl8192c_usb_ids[] = { + + /*=== Realtek demoboard ===*/ + /* Default ID */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, + + /****** 8188CU ********/ + /* RTL8188CTV */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x018a, rtl92cu_hal_cfg)}, + /* 8188CE-VAU USB minCard */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, + /* 8188cu 1*1 dongle */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8176, rtl92cu_hal_cfg)}, + /* 8188cu 1*1 dongle, (b/g mode only) */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, + /* 8188cu Slim Solo */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817a, rtl92cu_hal_cfg)}, + /* 8188cu Slim Combo */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, + /* 8188RU High-power USB Dongle */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)}, + /* 8188CE-VAU USB minCard (b/g mode only) */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, + /* 8188RU in Alfa AWUS036NHR */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, + /* RTL8188CUS-VL */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x819a, rtl92cu_hal_cfg)}, + /* 8188 Combo for BC4 */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, + + /****** 8192CU ********/ + /* 8192cu 2*2 */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8178, rtl92cu_hal_cfg)}, + /* 8192CE-VAU USB minCard */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, + + /*=== Customer ID ===*/ + /****** 8188CU ********/ + {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ + {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ + {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ + {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ + {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0846, 0x9043, rtl92cu_hal_cfg)}, /*NG WNA1000Mv2*/ + {RTL_USB_DEVICE(0x0b05, 0x17ba, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ + {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x0070, rtl92cu_hal_cfg)}, /*Sitecom - 150N */ + {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/ + {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ + /* HP - Lite-On ,8188CUS Slim Combo */ + {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ + {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ + {RTL_USB_DEVICE(0x2019, 0x4902, rtl92cu_hal_cfg)}, /*Planex - Etop*/ + {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ + /*SW-WF02-AD15 -Abocom*/ + {RTL_USB_DEVICE(0x2019, 0xab2e, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ + {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ + {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ + {RTL_USB_DEVICE(0x13d3, 0x3358, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ + /* Russian customer -Azwave (8188CE-VAU b/g mode only) */ + {RTL_USB_DEVICE(0x13d3, 0x3359, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x4855, 0x0090, rtl92cu_hal_cfg)}, /* Feixun */ + {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ + {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ + + /****** 8188 RU ********/ + /* Netcore */ + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x317f, rtl92cu_hal_cfg)}, + + /****** 8188CUS Slim Solo********/ + {RTL_USB_DEVICE(0x04f2, 0xaff7, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaff9, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffa, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x0846, 0x9042, rtl92cu_hal_cfg)}, /*On Netwrks N150MA*/ + + /****** 8188CUS Slim Combo ********/ + {RTL_USB_DEVICE(0x04f2, 0xaff8, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffb, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffc, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/ + + /****** 8192CU ********/ + {RTL_USB_DEVICE(0x050d, 0x1004, rtl92cu_hal_cfg)}, /*Belcom-SurfN300*/ + {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/ + {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/ + {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ + {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ + {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ + {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ + {RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/ + {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ + {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ + {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ + {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ + {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2001, 0x330d, rtl92cu_hal_cfg)}, /*D-Link DWA-131 */ + {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ + {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ + {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/ + {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids); + +static int rtl8192cu_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtl_usb_probe(intf, id, &rtl92cu_hal_cfg); +} + +static struct usb_driver rtl8192cu_driver = { + .name = "rtl8192cu", + .probe = rtl8192cu_probe, + .disconnect = rtl_usb_disconnect, + .id_table = rtl8192c_usb_ids, + +#ifdef CONFIG_PM + /* .suspend = rtl_usb_suspend, */ + /* .resume = rtl_usb_resume, */ + /* .reset_resume = rtl8192c_resume, */ +#endif /* CONFIG_PM */ + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(rtl8192cu_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c new file mode 100644 index 000000000..addeac90e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c @@ -0,0 +1,1862 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "table.h" + +u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10000330, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x2b2b2b27, + 0x870, 0x07000700, + 0x874, 0x22184000, + 0x878, 0x08080808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x2186115b, + 0xc78, 0x0000001f, + 0xc7c, 0x00b99612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0xa0e40000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c1b25a4, + 0xe78, 0x0c1b25a4, + 0xe7c, 0x0c1b25a4, + 0xe80, 0x0c1b25a4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c1b25a4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10000330, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000700, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00000740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000008, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x07090c0c, + 0xe04, 0xffffffff, 0x01020405, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0b0c0c0e, + 0xe14, 0xffffffff, 0x01030506, + 0xe18, 0xffffffff, 0x0b0c0d0e, + 0xe1c, 0xffffffff, 0x01030509, + 0x830, 0xffffffff, 0x07090c0c, + 0x834, 0xffffffff, 0x01020405, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0b0c0d0e, + 0x848, 0xffffffff, 0x01030509, + 0x84c, 0xffffffff, 0x0b0c0d0e, + 0x868, 0xffffffff, 0x01030509, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000577c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287b3, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x0001429b, + 0x013, 0x00010299, + 0x013, 0x0000c29c, + 0x013, 0x000081a0, + 0x013, 0x000040ac, + 0x013, 0x00000020, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, +}; + +u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000577c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287b3, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x0001429b, + 0x013, 0x00010299, + 0x013, 0x0000c29c, + 0x013, 0x000081a0, + 0x013, 0x000040ac, + 0x013, 0x00000020, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f405, + 0x015, 0x0004f405, + 0x015, 0x0008f405, + 0x015, 0x000cf405, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH] = { + 0x0, +}; + +u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x00000008, + 0x63d, 0x00000008, + 0x63e, 0x0000000c, + 0x63f, 0x0000000c, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CUPHY_REG_1T_HPARRAY[RTL8192CUPHY_REG_1T_HPARRAYLENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x040, 0x000c0004, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x20202000, + 0x870, 0x03000300, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00ffc3f1, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x15160000, + 0xa24, 0x070b0f12, + 0xa28, 0x00000104, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x6954342e, + 0xc54, 0x43bc0094, + 0xc58, 0x6954342f, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c46000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x24000090, + 0xc84, 0x20f60000, + 0xc88, 0x24000090, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x24242424, + 0xe04, 0x24242424, + 0xe08, 0x03902024, + 0xe10, 0x24242424, + 0xe14, 0x24242424, + 0xe18, 0x24242424, + 0xe1c, 0x24242424, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000008, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xee8, 0x31555448, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_ARRAY_PG_HP[RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH] = { + 0xe00, 0xffffffff, 0x06080808, + 0xe04, 0xffffffff, 0x00040406, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x04060608, + 0xe14, 0xffffffff, 0x00020204, + 0xe18, 0xffffffff, 0x04060608, + 0xe1c, 0xffffffff, 0x00020204, + 0x830, 0xffffffff, 0x06080808, + 0x834, 0xffffffff, 0x00040406, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x04060608, + 0x848, 0xffffffff, 0x00020204, + 0x84c, 0xffffffff, 0x04060608, + 0x868, 0xffffffff, 0x00020204, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CURADIOA_1T_HPARRAY[RTL8192CURADIOA_1T_HPARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e529, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00000255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x0000083c, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x000d8000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x00028fb4, + 0x013, 0x00024fa8, + 0x013, 0x000207a4, + 0x013, 0x0001c798, + 0x013, 0x000183a4, + 0x013, 0x00014398, + 0x013, 0x000101a4, + 0x013, 0x0000c198, + 0x013, 0x000080a4, + 0x013, 0x00004098, + 0x013, 0x00000000, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f405, + 0x015, 0x0004f405, + 0x015, 0x0008f405, + 0x015, 0x000cf405, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CUAGCTAB_1T_HPARRAY[RTL8192CUAGCTAB_1T_HPARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7b070001, + 0xc78, 0x7b080001, + 0xc78, 0x7a090001, + 0xc78, 0x790a0001, + 0xc78, 0x780b0001, + 0xc78, 0x770c0001, + 0xc78, 0x760d0001, + 0xc78, 0x750e0001, + 0xc78, 0x740f0001, + 0xc78, 0x73100001, + 0xc78, 0x72110001, + 0xc78, 0x71120001, + 0xc78, 0x70130001, + 0xc78, 0x6f140001, + 0xc78, 0x6e150001, + 0xc78, 0x6d160001, + 0xc78, 0x6c170001, + 0xc78, 0x6b180001, + 0xc78, 0x6a190001, + 0xc78, 0x691a0001, + 0xc78, 0x681b0001, + 0xc78, 0x671c0001, + 0xc78, 0x661d0001, + 0xc78, 0x651e0001, + 0xc78, 0x641f0001, + 0xc78, 0x63200001, + 0xc78, 0x62210001, + 0xc78, 0x61220001, + 0xc78, 0x60230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7b460001, + 0xc78, 0x7b470001, + 0xc78, 0x7b480001, + 0xc78, 0x7a490001, + 0xc78, 0x794a0001, + 0xc78, 0x784b0001, + 0xc78, 0x774c0001, + 0xc78, 0x764d0001, + 0xc78, 0x754e0001, + 0xc78, 0x744f0001, + 0xc78, 0x73500001, + 0xc78, 0x72510001, + 0xc78, 0x71520001, + 0xc78, 0x70530001, + 0xc78, 0x6f540001, + 0xc78, 0x6e550001, + 0xc78, 0x6d560001, + 0xc78, 0x6c570001, + 0xc78, 0x6b580001, + 0xc78, 0x6a590001, + 0xc78, 0x695a0001, + 0xc78, 0x685b0001, + 0xc78, 0x675c0001, + 0xc78, 0x665d0001, + 0xc78, 0x655e0001, + 0xc78, 0x645f0001, + 0xc78, 0x63600001, + 0xc78, 0x62610001, + 0xc78, 0x61620001, + 0xc78, 0x60630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h new file mode 100644 index 000000000..efc89f7db --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CU_TABLE__H_ +#define __RTL92CU_TABLE__H_ + +#include + +#define RTL8192CUPHY_REG_2TARRAY_LENGTH 374 +extern u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH]; +#define RTL8192CUPHY_REG_1TARRAY_LENGTH 374 +extern u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH]; + +#define RTL8192CUPHY_REG_ARRAY_PGLENGTH 336 +extern u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH]; + +#define RTL8192CURADIOA_2TARRAYLENGTH 282 +extern u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH]; +#define RTL8192CURADIOB_2TARRAYLENGTH 78 +extern u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH]; +#define RTL8192CURADIOA_1TARRAYLENGTH 282 +extern u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH]; +#define RTL8192CURADIOB_1TARRAYLENGTH 1 +extern u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH]; + +#define RTL8192CUMAC_2T_ARRAYLENGTH 172 +extern u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH]; + +#define RTL8192CUAGCTAB_2TARRAYLENGTH 320 +extern u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH]; +#define RTL8192CUAGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH]; + +#define RTL8192CUPHY_REG_1T_HPARRAYLENGTH 378 +extern u32 RTL8192CUPHY_REG_1T_HPARRAY[RTL8192CUPHY_REG_1T_HPARRAYLENGTH]; + +#define RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH 336 +extern u32 RTL8192CUPHY_REG_ARRAY_PG_HP[RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH]; + +#define RTL8192CURADIOA_1T_HPARRAYLENGTH 282 +extern u32 RTL8192CURADIOA_1T_HPARRAY[RTL8192CURADIOA_1T_HPARRAYLENGTH]; +#define RTL8192CUAGCTAB_1T_HPARRAYLENGTH 320 +extern u32 RTL8192CUAGCTAB_1T_HPARRAY[RTL8192CUAGCTAB_1T_HPARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c new file mode 100644 index 000000000..d6c35e8d0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c @@ -0,0 +1,644 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../usb.h" +#include "../ps.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "mac.h" +#include "trx.h" +#include "../rtl8192c/fw_common.h" + +static int configvertoutep(struct ieee80211_hw *hw) +{ + u8 ep_cfg, txqsele; + u8 ep_nums = 0; + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->out_queue_sel = 0; + ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL); + ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT; + switch (ep_cfg) { + case 0: /* 2 bulk OUT, 1 bulk IN */ + case 3: + rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_LQ; + ep_nums = 2; + break; + case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */ + case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */ + txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS); + if (txqsele & 0x0F) /* /map all endpoint to High queue */ + rtlusb->out_queue_sel = TX_SELE_HQ; + else if (txqsele&0xF0) /* map all endpoint to Low queue */ + rtlusb->out_queue_sel = TX_SELE_LQ; + ep_nums = 1; + break; + default: + break; + } + return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; +} + +static int configvernoutep(struct ieee80211_hw *hw) +{ + u8 ep_cfg; + u8 ep_nums = 0; + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->out_queue_sel = 0; + /* Normal and High queue */ + ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1)); + if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_HQ; + ep_nums++; + } + if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_NQ; + ep_nums++; + } + /* Low queue */ + ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2)); + if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_LQ; + ep_nums++; + } + return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; +} + +static void twooutepmapping(struct ieee80211_hw *hw, bool is_chip8, + bool bwificfg, struct rtl_ep_map *ep_map) +{ + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (bwificfg) { /* for WMM */ + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB Chip-B & WMM Setting.....\n"); + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; + } else { /* typical setting */ + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB typical Setting.....\n"); + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; + } +} + +static void threeoutepmapping(struct ieee80211_hw *hw, bool bwificfg, + struct rtl_ep_map *ep_map) +{ + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (bwificfg) { /* for WMM */ + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB 3EP Setting for WMM.....\n"); + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[2]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; + } else { /* typical setting */ + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB 3EP Setting for typical.....\n"); + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[2]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[2]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; + } +} + +static void oneoutepmapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map) +{ + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; +} + +static int _out_ep_mapping(struct ieee80211_hw *hw) +{ + int err = 0; + bool ischipn, bwificfg = false; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + struct rtl_ep_map *ep_map = &(rtlusb->ep_map); + + ischipn = IS_NORMAL_CHIP(rtlhal->version); + switch (rtlusb->out_ep_nums) { + case 2: + twooutepmapping(hw, ischipn, bwificfg, ep_map); + break; + case 3: + /* Test chip doesn't support three out EPs. */ + if (!ischipn) { + err = -EINVAL; + goto err_out; + } + threeoutepmapping(hw, ischipn, ep_map); + break; + case 1: + oneoutepmapping(hw, ep_map); + break; + default: + err = -EINVAL; + break; + } +err_out: + return err; + +} + +/* endpoint mapping */ +int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int error = 0; + + if (likely(IS_NORMAL_CHIP(rtlhal->version))) + error = configvernoutep(hw); + else + error = configvertoutep(hw); + if (error) + goto err_out; + error = _out_ep_mapping(hw); + if (error) + goto err_out; +err_out: + return error; +} + +u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) +{ + u16 hw_queue_index; + + if (unlikely(ieee80211_is_beacon(fc))) { + hw_queue_index = RTL_TXQ_BCN; + goto out; + } + if (ieee80211_is_mgmt(fc)) { + hw_queue_index = RTL_TXQ_MGT; + goto out; + } + switch (mac80211_queue_index) { + case 0: + hw_queue_index = RTL_TXQ_VO; + break; + case 1: + hw_queue_index = RTL_TXQ_VI; + break; + case 2: + hw_queue_index = RTL_TXQ_BE; + break; + case 3: + hw_queue_index = RTL_TXQ_BK; + break; + default: + hw_queue_index = RTL_TXQ_BE; + WARN_ONCE(true, "rtl8192cu: QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index); + break; + } +out: + return hw_queue_index; +} + +static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, + __le16 fc, u16 mac80211_queue_index) +{ + enum rtl_desc_qsel qsel; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (unlikely(ieee80211_is_beacon(fc))) { + qsel = QSLT_BEACON; + goto out; + } + if (ieee80211_is_mgmt(fc)) { + qsel = QSLT_MGNT; + goto out; + } + switch (mac80211_queue_index) { + case 0: /* VO */ + qsel = QSLT_VO; + rtl_dbg(rtlpriv, COMP_USB, DBG_DMESG, + "VO queue, set qsel = 0x%x\n", QSLT_VO); + break; + case 1: /* VI */ + qsel = QSLT_VI; + rtl_dbg(rtlpriv, COMP_USB, DBG_DMESG, + "VI queue, set qsel = 0x%x\n", QSLT_VI); + break; + case 3: /* BK */ + qsel = QSLT_BK; + rtl_dbg(rtlpriv, COMP_USB, DBG_DMESG, + "BK queue, set qsel = 0x%x\n", QSLT_BK); + break; + case 2: /* BE */ + default: + qsel = QSLT_BE; + rtl_dbg(rtlpriv, COMP_USB, DBG_DMESG, + "BE queue, set qsel = 0x%x\n", QSLT_BE); + break; + } +out: + return qsel; +} + +/* =============================================================== */ + +/*---------------------------------------------------------------------- + * + * Rx handler + * + *---------------------------------------------------------------------- */ +bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rx_fwinfo_92c *p_drvinfo; + struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc8; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_phy_status(pdesc); + + stats->length = (u16)get_rx_desc_pkt_len(pdesc); + stats->rx_drvinfo_size = (u8)get_rx_desc_drvinfo_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + stats->icv = (u16)get_rx_desc_icv(pdesc); + stats->crc = (u16)get_rx_desc_crc32(pdesc); + stats->hwerror = (stats->crc | stats->icv); + stats->decrypted = !get_rx_desc_swdec(pdesc); + stats->rate = (u8)get_rx_desc_rx_mcs(pdesc); + stats->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + stats->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) && + (get_rx_desc_faggr(pdesc) == 1)); + stats->timestamp_low = get_rx_desc_tsfl(pdesc); + stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc); + stats->is_ht = (bool)get_rx_desc_rx_ht(pdesc); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + if (get_rx_desc_crc32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (!get_rx_desc_swdec(pdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (get_rx_desc_bw(pdesc)) + rx_status->bw = RATE_INFO_BW_40; + if (get_rx_desc_rx_ht(pdesc)) + rx_status->encoding = RX_ENC_HT; + rx_status->flag |= RX_FLAG_MACTIME_START; + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht, + false, stats->rate); + rx_status->mactime = get_rx_desc_tsfl(pdesc); + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + + stats->rx_bufshift); + rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->recvsignalpower + 10; + return true; +} + +#define RTL_RX_DRV_INFO_UNIT 8 + +static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status = + (struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb); + u32 skb_len, pkt_len, drvinfo_len; + struct rtl_priv *rtlpriv = rtl_priv(hw); + __le32 *rxdesc; + struct rtl_stats stats = { + .signal = 0, + .rate = 0, + }; + struct rx_fwinfo_92c *p_drvinfo; + bool bv; + __le16 fc; + struct ieee80211_hdr *hdr; + + memset(rx_status, 0, sizeof(*rx_status)); + rxdesc = (__le32 *)skb->data; + skb_len = skb->len; + drvinfo_len = (get_rx_desc_drvinfo_size(rxdesc) * RTL_RX_DRV_INFO_UNIT); + pkt_len = get_rx_desc_pkt_len(rxdesc); + /* TODO: Error recovery. drop this skb or something. */ + WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len)); + stats.length = (u16)get_rx_desc_pkt_len(rxdesc); + stats.rx_drvinfo_size = (u8)get_rx_desc_drvinfo_size(rxdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats.rx_bufshift = (u8)(get_rx_desc_shift(rxdesc) & 0x03); + stats.icv = (u16)get_rx_desc_icv(rxdesc); + stats.crc = (u16)get_rx_desc_crc32(rxdesc); + stats.hwerror = (stats.crc | stats.icv); + stats.decrypted = !get_rx_desc_swdec(rxdesc); + stats.rate = (u8)get_rx_desc_rx_mcs(rxdesc); + stats.shortpreamble = (u16)get_rx_desc_splcp(rxdesc); + stats.isampdu = (bool)((get_rx_desc_paggr(rxdesc) == 1) && + (get_rx_desc_faggr(rxdesc) == 1)); + stats.timestamp_low = get_rx_desc_tsfl(rxdesc); + stats.rx_is40mhzpacket = (bool)get_rx_desc_bw(rxdesc); + stats.is_ht = (bool)get_rx_desc_rx_ht(rxdesc); + /* TODO: is center_freq changed when doing scan? */ + /* TODO: Shall we add protection or just skip those two step? */ + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + if (get_rx_desc_crc32(rxdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (!get_rx_desc_swdec(rxdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (get_rx_desc_bw(rxdesc)) + rx_status->bw = RATE_INFO_BW_40; + if (get_rx_desc_rx_ht(rxdesc)) + rx_status->encoding = RX_ENC_HT; + /* Data rate */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats.is_ht, + false, stats.rate); + /* There is a phy status after this rx descriptor. */ + if (get_rx_desc_phy_status(rxdesc)) { + p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE); + rtl92c_translate_rx_signal_stuff(hw, skb, &stats, + (struct rx_desc_92c *)rxdesc, p_drvinfo); + } + skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE)); + hdr = rtl_get_hdr(skb); + fc = hdr->frame_control; + bv = ieee80211_is_probe_resp(fc); + if (bv) + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Got probe response frame\n"); + if (ieee80211_is_beacon(fc)) + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n"); + if (ieee80211_is_data(fc)) + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n", + fc, + (u32)hdr->addr1[0], (u32)hdr->addr1[1], + (u32)hdr->addr1[2], (u32)hdr->addr1[3], + (u32)hdr->addr1[4], (u32)hdr->addr1[5]); + ieee80211_rx(hw, skb); +} + +void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb) +{ + _rtl_rx_process(hw, skb); +} + +/*---------------------------------------------------------------------- + * + * Tx handler + * + *---------------------------------------------------------------------- */ +void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb) +{ +} + +int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb) +{ + return 0; +} + +struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list) +{ + return skb_dequeue(list); +} + +/*======================================== trx ===============================*/ + +static void _rtl_fill_usb_tx_desc(__le32 *txdesc) +{ + set_tx_desc_own(txdesc, 1); + set_tx_desc_last_seg(txdesc, 1); + set_tx_desc_first_seg(txdesc, 1); +} + +/* + * For HW recovery information + */ +static void _rtl_tx_desc_checksum(__le32 *txdesc) +{ + __le16 *ptr = (__le16 *)txdesc; + u16 checksum = 0; + u32 index; + + /* Clear first */ + set_tx_desc_tx_desc_checksum(txdesc, 0); + for (index = 0; index < 16; index++) + checksum = checksum ^ le16_to_cpu(*(ptr + index)); + set_tx_desc_tx_desc_checksum(txdesc, checksum); +} + +void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 queue_index, + struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_sta_info *sta_entry; + u8 agg_state = RTL_AGG_STOP; + u8 ampdu_density = 0; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 rate_flag = info->control.rates[0].flags; + u16 pktlen = skb->len; + enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc, + skb_get_queue_mapping(skb)); + u8 *txdesc8; + __le32 *txdesc; + u8 tid; + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); + txdesc8 = skb_push(skb, RTL_TX_HEADER_SIZE); + txdesc = (__le32 *)txdesc8; + memset(txdesc, 0, RTL_TX_HEADER_SIZE); + set_tx_desc_pkt_size(txdesc, pktlen); + set_tx_desc_linip(txdesc, 0); + set_tx_desc_pkt_offset(txdesc, RTL_DUMMY_OFFSET); + set_tx_desc_offset(txdesc, RTL_TX_HEADER_SIZE); + set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate); + if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) + set_tx_desc_data_shortgi(txdesc, 1); + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + tid = ieee80211_get_tid(hdr); + if (tid < MAX_TID_COUNT) + agg_state = sta_entry->tids[tid].agg.agg_state; + ampdu_density = sta->deflink.ht_cap.ampdu_density; + } + + if (agg_state == RTL_AGG_OPERATIONAL && + info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(txdesc, 1); + set_tx_desc_max_agg_num(txdesc, 0x14); + set_tx_desc_ampdu_density(txdesc, ampdu_density); + tcb_desc->rts_enable = 1; + tcb_desc->rts_rate = DESC_RATE24M; + } else { + set_tx_desc_agg_break(txdesc, 1); + } + set_tx_desc_seq(txdesc, seq_number); + set_tx_desc_rts_enable(txdesc, + ((tcb_desc->rts_enable && + !tcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(txdesc, + ((tcb_desc->rts_enable || + tcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_cts2self(txdesc, ((tcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_rts_stbc(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); + set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate); + set_tx_desc_rts_bw(txdesc, 0); + set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc); + set_tx_desc_rts_short(txdesc, + ((tcb_desc->rts_rate <= DESC_RATE54M) ? + (tcb_desc->rts_use_shortpreamble ? 1 : 0) + : (tcb_desc->rts_use_shortgi ? 1 : 0))); + if (mac->bw_40) { + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { + set_tx_desc_data_bw(txdesc, 1); + set_tx_desc_data_sc(txdesc, 3); + } else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){ + set_tx_desc_data_bw(txdesc, 1); + set_tx_desc_data_sc(txdesc, mac->cur_40_prime_sc); + } else { + set_tx_desc_data_bw(txdesc, 0); + set_tx_desc_data_sc(txdesc, 0); + } + } else { + set_tx_desc_data_bw(txdesc, 0); + set_tx_desc_data_sc(txdesc, 0); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(txdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(txdesc, 0x3); + break; + default: + set_tx_desc_sec_type(txdesc, 0x0); + break; + } + } + set_tx_desc_pkt_id(txdesc, 0); + set_tx_desc_queue_sel(txdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(txdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(txdesc, 0xF); + set_tx_desc_disable_fb(txdesc, 0); + set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate ? 1 : 0); + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function\n"); + set_tx_desc_rdg_enable(txdesc, 1); + set_tx_desc_htc(txdesc, 1); + } + } + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index); + set_tx_desc_macid(txdesc, tcb_desc->mac_id); + } else { + set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index); + set_tx_desc_macid(txdesc, tcb_desc->ratr_index); + } + if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && + ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en(txdesc, 1); + set_tx_desc_pkt_id(txdesc, 8); + } + if (ieee80211_has_morefrags(fc)) + set_tx_desc_more_frag(txdesc, 1); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + set_tx_desc_bmc(txdesc, 1); + _rtl_fill_usb_tx_desc(txdesc); + _rtl_tx_desc_checksum(txdesc); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n"); +} + +void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 fw_queue = QSLT_BEACON; + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + __le32 *pdesc = (__le32 *)pdesc8; + + memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); + set_tx_desc_offset(pdesc, RTL_TX_HEADER_SIZE); + set_tx_desc_tx_rate(pdesc, DESC_RATE1M); + set_tx_desc_seq(pdesc, 0); + set_tx_desc_linip(pdesc, 0); + set_tx_desc_queue_sel(pdesc, fw_queue); + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + set_tx_desc_own(pdesc, 1); + set_tx_desc_pkt_size(pdesc, (u16)skb->len); + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + set_tx_desc_offset(pdesc, 0x20); + set_tx_desc_use_rate(pdesc, 1); + if (!ieee80211_is_data_qos(fc)) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_pkt_id(pdesc, 8); + } + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content", + pdesc, RTL_TX_DESC_SIZE); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h new file mode 100644 index 000000000..09e61dc0f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h @@ -0,0 +1,397 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CU_TRX_H__ +#define __RTL92CU_TRX_H__ + +#define RTL92C_NUM_RX_URBS 8 +#define RTL92C_NUM_TX_URBS 32 + +#define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ +#define RX_DRV_INFO_SIZE_UNIT 8 + +enum usb_rx_agg_mode { + USB_RX_AGG_DISABLE, + USB_RX_AGG_DMA, + USB_RX_AGG_USB, + USB_RX_AGG_DMA_USB +}; + +#define TX_SELE_HQ BIT(0) /* High Queue */ +#define TX_SELE_LQ BIT(1) /* Low Queue */ +#define TX_SELE_NQ BIT(2) /* Normal Queue */ + +#define RTL_USB_TX_AGG_NUM_DESC 5 + +#define RTL_USB_RX_AGG_PAGE_NUM 4 +#define RTL_USB_RX_AGG_PAGE_TIMEOUT 3 + +#define RTL_USB_RX_AGG_BLOCK_NUM 5 +#define RTL_USB_RX_AGG_BLOCK_TIMEOUT 3 + +/*======================== rx status =========================================*/ + +struct rx_drv_info_92c { + /* + * Driver info contain PHY status and other variabel size info + * PHY Status content as below + */ + + /* DWORD 0 */ + u8 gain_trsw[4]; + + /* DWORD 1 */ + u8 pwdb_all; + u8 cfosho[4]; + + /* DWORD 2 */ + u8 cfotail[4]; + + /* DWORD 3 */ + s8 rxevm[2]; + s8 rxsnr[4]; + + /* DWORD 4 */ + u8 pdsnr[2]; + + /* DWORD 5 */ + u8 csi_current[2]; + u8 csi_target[2]; + + /* DWORD 6 */ + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +/* macros to read various fields in RX descriptor */ + +/* DWORD 0 */ +static inline u32 get_rx_desc_pkt_len(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, GENMASK(13, 0)); +} + +static inline u32 get_rx_desc_crc32(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, BIT(14)); +} + +static inline u32 get_rx_desc_icv(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, BIT(15)); +} + +static inline u32 get_rx_desc_drvinfo_size(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, GENMASK(19, 16)); +} + +static inline u32 get_rx_desc_shift(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, GENMASK(25, 24)); +} + +static inline u32 get_rx_desc_phy_status(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, BIT(26)); +} + +static inline u32 get_rx_desc_swdec(__le32 *__rxdesc) +{ + return le32_get_bits(*__rxdesc, BIT(27)); +} + + +/* DWORD 1 */ +static inline u32 get_rx_desc_paggr(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 1), BIT(14)); +} + +static inline u32 get_rx_desc_faggr(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 1), BIT(15)); +} + + +/* DWORD 3 */ +static inline u32 get_rx_desc_rx_mcs(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 3), GENMASK(5, 0)); +} + +static inline u32 get_rx_desc_rx_ht(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 3), BIT(6)); +} + +static inline u32 get_rx_desc_splcp(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 3), BIT(8)); +} + +static inline u32 get_rx_desc_bw(__le32 *__rxdesc) +{ + return le32_get_bits(*(__rxdesc + 3), BIT(9)); +} + + +/* DWORD 5 */ +static inline u32 get_rx_desc_tsfl(__le32 *__rxdesc) +{ + return le32_to_cpu(*((__rxdesc + 5))); +} + + +/*======================= tx desc ============================================*/ + +/* macros to set various fields in TX descriptor */ + +/* Dword 0 */ +static inline void set_tx_desc_pkt_size(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(31)); +} + + +/* Dword 1 */ +static inline void set_tx_desc_macid(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, GENMASK(4, 0)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, BIT(5)); +} + +static inline void set_tx_desc_agg_break(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, BIT(6)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, BIT(7)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, GENMASK(19, 16)); +} + +static inline void set_tx_desc_nav_use_hdr(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, BIT(20)); +} + +static inline void set_tx_desc_sec_type(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, GENMASK(30, 26)); +} + + +/* Dword 2 */ +static inline void set_tx_desc_more_frag(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 2), __value, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 2), __value, GENMASK(22, 20)); +} + + +/* Dword 3 */ +static inline void set_tx_desc_seq(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 3), __value, GENMASK(27, 16)); +} + +static inline void set_tx_desc_pkt_id(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 3), __value, GENMASK(31, 28)); +} + + +/* Dword 4 */ +static inline void set_tx_desc_rts_rate(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, GENMASK(4, 0)); +} + +static inline void set_tx_desc_qos(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(6)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(7)); +} + +static inline void set_tx_desc_use_rate(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(13)); +} + +static inline void set_tx_desc_data_sc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, GENMASK(21, 20)); +} + +static inline void set_tx_desc_data_bw(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(25)); +} + +static inline void set_tx_desc_rts_short(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(26)); +} + +static inline void set_tx_desc_rts_bw(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, BIT(27)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, GENMASK(29, 28)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, GENMASK(31, 30)); +} + + +/* Dword 5 */ +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(6)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 5), __value, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 5), __value, GENMASK(16, 13)); +} + + +/* Dword 6 */ +static inline void set_tx_desc_max_agg_num(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 6), __value, GENMASK(15, 11)); +} + + +/* Dword 7 */ +static inline void set_tx_desc_tx_desc_checksum(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 7), __value, GENMASK(15, 0)); +} + + +int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw); +u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index); +bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb); +void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb); +void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb); +int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb); +struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *, + struct sk_buff_head *); +void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 queue_index, + struct rtl_tcb_desc *tcb_desc); +void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile new file mode 100644 index 000000000..beebdfa3f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192d-common-objs := \ + dm_common.o \ + fw_common.o \ + hw_common.o \ + main.o \ + phy_common.o \ + rf_common.o \ + trx_common.o + +obj-$(CONFIG_RTL8192D_COMMON) += rtl8192d-common.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h new file mode 100644 index 000000000..21726d9b4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_DEF_H__ +#define __RTL92D_DEF_H__ + +/* Min Spacing related settings. */ +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_PATH 2 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define RX_SMOOTH_FACTOR 20 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +enum version_8192d { + VERSION_TEST_CHIP_88C = 0x0000, + VERSION_TEST_CHIP_92C = 0x0020, + VERSION_TEST_UMC_CHIP_8723 = 0x0081, + VERSION_NORMAL_TSMC_CHIP_88C = 0x0008, + VERSION_NORMAL_TSMC_CHIP_92C = 0x0028, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x0018, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x0088, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x00a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x0098, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x1088, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x10a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x1090, + VERSION_TEST_CHIP_92D_SINGLEPHY = 0x0022, + VERSION_TEST_CHIP_92D_DUALPHY = 0x0002, + VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x002a, + VERSION_NORMAL_CHIP_92D_DUALPHY = 0x000a, + VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x202a, + VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x200a, + VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0x302a, + VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x300a, + VERSION_NORMAL_CHIP_92D_E_CUT_SINGLEPHY = 0x402a, + VERSION_NORMAL_CHIP_92D_E_CUT_DUALPHY = 0x400a, +}; + +/* for 92D */ +#define CHIP_92D_SINGLEPHY BIT(9) + +/* Chip specific */ +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_88C_USB_MCARD 0x2 +#define CHIP_BONDING_88C_USB_HP 0x1 + +/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 */ +/* [7] Manufacturer: TSMC=0, UMC=1 */ +/* [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 */ +/* [3] Chip type: TEST=0, NORMAL=1 */ +/* [2:0] IC type: 81xxC=0, 8723=1, 92D=2 */ +#define CHIP_8723 BIT(0) +#define CHIP_92D BIT(1) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define CHIP_92D_B_CUT BIT(12) +#define CHIP_92D_C_CUT BIT(13) +#define CHIP_92D_D_CUT (BIT(13)|BIT(12)) +#define CHIP_92D_E_CUT BIT(14) + +/* MASK */ +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + + +/* Get element */ +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? \ + false : true) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == \ + RF_TYPE_1T2R) ? true : false) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == \ + RF_TYPE_2T2R) ? true : false) + +#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? \ + (IS_2T2R(version) ? true : false) : false) +#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == \ + CHIP_92D) ? true : false) +#define IS_92D_C_CUT(version) ((IS_92D(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + CHIP_92D_C_CUT) ? true : false) : false) +#define IS_92D_D_CUT(version) ((IS_92D(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + CHIP_92D_D_CUT) ? true : false) : false) +#define IS_92D_E_CUT(version) ((IS_92D(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + CHIP_92D_E_CUT) ? true : false) : false) + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum channel_plan { + CHPL_FCC = 0, + CHPL_IC = 1, + CHPL_ETSI = 2, + CHPL_SPAIN = 3, + CHPL_FRANCE = 4, + CHPL_MKK = 5, + CHPL_MKK1 = 6, + CHPL_ISRAEL = 7, + CHPL_TELEC = 8, + CHPL_GLOBAL = 9, + CHPL_WORLD = 10, +}; + +struct phy_sts_cck_8192d { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +struct txpower_info { + u8 cck_index[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40_1sindex[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40_2sindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht20indexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ofdmindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht20maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 tssi_a[3]; /* 5GL/5GM/5GH */ + u8 tssi_b[3]; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c new file mode 100644 index 000000000..20373ce99 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c @@ -0,0 +1,1061 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy_common.h" +#include "dm_common.h" + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB */ + 0x6b8001ae, /* 3, +4.5dB */ + 0x65400195, /* 4, +4.0dB */ + 0x5fc0017f, /* 5, +3.5dB */ + 0x5a400169, /* 6, +3.0dB */ + 0x55400155, /* 7, +2.5dB */ + 0x50800142, /* 8, +2.0dB */ + 0x4c000130, /* 9, +1.5dB */ + 0x47c0011f, /* 10, +1.0dB */ + 0x43c0010f, /* 11, +0.5dB */ + 0x40000100, /* 12, +0dB */ + 0x3c8000f2, /* 13, -0.5dB */ + 0x390000e4, /* 14, -1.0dB */ + 0x35c000d7, /* 15, -1.5dB */ + 0x32c000cb, /* 16, -2.0dB */ + 0x300000c0, /* 17, -2.5dB */ + 0x2d4000b5, /* 18, -3.0dB */ + 0x2ac000ab, /* 19, -3.5dB */ + 0x288000a2, /* 20, -4.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x24000090, /* 22, -5.0dB */ + 0x22000088, /* 23, -5.5dB */ + 0x20000080, /* 24, -6.0dB */ + 0x1e400079, /* 25, -6.5dB */ + 0x1c800072, /* 26, -7.0dB */ + 0x1b00006c, /* 27. -7.5dB */ + 0x19800066, /* 28, -8.0dB */ + 0x18000060, /* 29, -8.5dB */ + 0x16c0005b, /* 30, -9.0dB */ + 0x15800056, /* 31, -9.5dB */ + 0x14400051, /* 32, -10.0dB */ + 0x1300004c, /* 33, -10.5dB */ + 0x12000048, /* 34, -11.0dB */ + 0x11000044, /* 35, -11.5dB */ + 0x10000040, /* 36, -12.0dB */ + 0x0f00003c, /* 37, -12.5dB */ + 0x0e400039, /* 38, -13.0dB */ + 0x0d800036, /* 39, -13.5dB */ + 0x0cc00033, /* 40, -14.0dB */ + 0x0c000030, /* 41, -14.5dB */ + 0x0b40002d, /* 42, -15.0dB */ +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */ +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ +}; + +static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw) +{ + static const u8 index_mapping[RX_INDEX_MAPPING_NUM] = { + 0x0f, 0x0f, 0x0d, 0x0c, 0x0b, + 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x04, 0x03, 0x02 + }; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i, idx; + u32 u4tmp; + + idx = rtlpriv->efuse.eeprom_thermalmeter - rtlpriv->dm.thermalvalue_rxgain; + u4tmp = index_mapping[idx] << 12; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "===> Rx Gain %x\n", u4tmp); + + for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) + rtl_set_rfreg(hw, i, 0x3C, RFREG_OFFSET_MASK, + (rtlpriv->phy.reg_rf3c[i] & ~0xF000) | u4tmp); +} + +static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg, + u8 *cck_index_old) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long flag = 0; + const u8 *cckswing; + long temp_cck; + int i; + + /* Query CCK default setting From 0xa24 */ + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, + MASKDWORD) & MASKCCK; + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.cck_inch14) + cckswing = &cckswing_table_ch14[i][2]; + else + cckswing = &cckswing_table_ch1ch13[i][2]; + + if (temp_cck == le32_to_cpu(*((__le32 *)cckswing))) { + *cck_index_old = (u8)i; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); + break; + } + } + *temp_cckg = temp_cck; +} + +static void rtl92d_bandtype_5G(struct rtl_hal *rtlhal, u8 *ofdm_index, + bool *internal_pa, u8 thermalvalue, u8 delta, + u8 rf, struct rtl_efuse *rtlefuse, + struct rtl_priv *rtlpriv, struct rtl_phy *rtlphy, + const u8 index_mapping[5][INDEX_MAPPING_NUM], + const u8 index_mapping_pa[8][INDEX_MAPPING_NUM]) +{ + u8 offset = 0; + u8 index; + int i; + + for (i = 0; i < rf; i++) { + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) /* MAC 1 5G */ + *internal_pa = rtlefuse->internal_pa_5g[1]; + else + *internal_pa = rtlefuse->internal_pa_5g[i]; + + if (*internal_pa) { + if (rtlhal->interfaceindex == 1 || i == rf) + offset = 4; + else + offset = 0; + if (rtlphy->current_channel >= 100 && + rtlphy->current_channel <= 165) + offset += 2; + } else { + if (rtlhal->interfaceindex == 1 || i == rf) + offset = 2; + else + offset = 0; + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) + offset++; + + if (*internal_pa) { + if (delta > INDEX_MAPPING_NUM - 1) + index = index_mapping_pa[offset] + [INDEX_MAPPING_NUM - 1]; + else + index = + index_mapping_pa[offset][delta]; + } else { + if (delta > INDEX_MAPPING_NUM - 1) + index = + index_mapping[offset][INDEX_MAPPING_NUM - 1]; + else + index = index_mapping[offset][delta]; + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + if (*internal_pa && thermalvalue > 0x12) { + ofdm_index[i] = rtlpriv->dm.ofdm_index[i] - + ((delta / 2) * 3 + (delta % 2)); + } else { + ofdm_index[i] -= index; + } + } else { + ofdm_index[i] += index; + } + } +} + +static void +rtl92d_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw) +{ + static const u8 index_mapping[5][INDEX_MAPPING_NUM] = { + /* 5G, path A/MAC 0, decrease power */ + {0, 1, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18}, + /* 5G, path A/MAC 0, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, decrease power */ + {0, 2, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18}, + /* 5G, path B/MAC 1, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + /* 2.4G, for decreas power */ + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10}, + }; + static const u8 index_mapping_internal_pa[8][INDEX_MAPPING_NUM] = { + /* 5G, path A/MAC 0, ch36-64, decrease power */ + {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16}, + /* 5G, path A/MAC 0, ch36-64, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path A/MAC 0, ch100-165, decrease power */ + {0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 15}, + /* 5G, path A/MAC 0, ch100-165, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, ch36-64, decrease power */ + {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16}, + /* 5G, path B/MAC 1, ch36-64, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, ch100-165, decrease power */ + {0, 1, 2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 14}, + /* 5G, path B/MAC 1, ch100-165, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + }; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_dm *dm = &rtlpriv->dm; + u8 thermalvalue, delta, delta_lck, delta_iqk, delta_rxgain; + u8 ofdm_min_index = 6, ofdm_min_index_internal_pa = 3, rf; + long ele_a = 0, ele_d, temp_cck, val_x, value32; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + u8 offset, thermalvalue_avg_count = 0; + u8 ofdm_index_old[2] = {0, 0}; + u32 thermalvalue_avg = 0; + bool internal_pa = false; + long val_y, ele_c = 0; + s8 cck_index_old = 0; + u8 indexforchannel; + u8 ofdm_index[2]; + s8 cck_index = 0; + u8 index, swing; + int i; + + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel); + + dm->txpower_trackinginit = true; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n"); + + thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, + dm->thermalvalue, rtlefuse->eeprom_thermalmeter); + + if (!thermalvalue) + goto exit; + + if (is2t) + rf = 2; + else + rf = 1; + + if (dm->thermalvalue && !rtlhal->reloadtxpowerindex) + goto old_index_done; + + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8)i; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0]); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD); + ele_d &= MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[1] = (u8)i; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1]); + break; + } + } + } + + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl92d_bandtype_2_4G(hw, &temp_cck, &cck_index_old); + } else { + temp_cck = 0x090e1317; + cck_index_old = 12; + } + + if (!dm->thermalvalue) { + dm->thermalvalue = rtlefuse->eeprom_thermalmeter; + dm->thermalvalue_lck = thermalvalue; + dm->thermalvalue_iqk = thermalvalue; + dm->thermalvalue_rxgain = rtlefuse->eeprom_thermalmeter; + + for (i = 0; i < rf; i++) + dm->ofdm_index[i] = ofdm_index_old[i]; + + dm->cck_index = cck_index_old; + } + + if (rtlhal->reloadtxpowerindex) { + for (i = 0; i < rf; i++) + dm->ofdm_index[i] = ofdm_index_old[i]; + + dm->cck_index = cck_index_old; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "reload ofdm index for band switch\n"); + } + +old_index_done: + for (i = 0; i < rf; i++) + ofdm_index[i] = dm->ofdm_index[i]; + + dm->thermalvalue_avg[dm->thermalvalue_avg_index] = thermalvalue; + dm->thermalvalue_avg_index++; + + if (dm->thermalvalue_avg_index == AVG_THERMAL_NUM) + dm->thermalvalue_avg_index = 0; + + for (i = 0; i < AVG_THERMAL_NUM; i++) { + if (dm->thermalvalue_avg[i]) { + thermalvalue_avg += dm->thermalvalue_avg[i]; + thermalvalue_avg_count++; + } + } + + if (thermalvalue_avg_count) + thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count); + + if (rtlhal->reloadtxpowerindex) { + delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter); + rtlhal->reloadtxpowerindex = false; + dm->done_txpower = false; + } else if (dm->done_txpower) { + delta = abs_diff(thermalvalue, dm->thermalvalue); + } else { + delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter); + } + + delta_lck = abs_diff(thermalvalue, dm->thermalvalue_lck); + delta_iqk = abs_diff(thermalvalue, dm->thermalvalue_iqk); + delta_rxgain = abs_diff(thermalvalue, dm->thermalvalue_rxgain); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, dm->thermalvalue, rtlefuse->eeprom_thermalmeter, + delta, delta_lck, delta_iqk); + + if (delta_lck > rtlefuse->delta_lck && rtlefuse->delta_lck != 0) { + dm->thermalvalue_lck = thermalvalue; + rtlpriv->cfg->ops->phy_lc_calibrate(hw, is2t); + } + + if (delta == 0 || !dm->txpower_track_control) + goto check_delta; + + dm->done_txpower = true; + delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter); + + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + offset = 4; + if (delta > INDEX_MAPPING_NUM - 1) + index = index_mapping[offset][INDEX_MAPPING_NUM - 1]; + else + index = index_mapping[offset][delta]; + + if (thermalvalue > dm->thermalvalue) { + for (i = 0; i < rf; i++) + ofdm_index[i] -= delta; + + cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] += index; + + cck_index += index; + } + } else if (rtlhal->current_bandtype == BAND_ON_5G) { + rtl92d_bandtype_5G(rtlhal, ofdm_index, &internal_pa, + thermalvalue, delta, rf, rtlefuse, rtlpriv, + rtlphy, index_mapping, + index_mapping_internal_pa); + } + + if (is2t) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n", + dm->ofdm_index[0], dm->ofdm_index[1], dm->cck_index); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "temp OFDM_A_index=0x%x, cck_index = 0x%x\n", + dm->ofdm_index[0], dm->cck_index); + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) { + ofdm_index[i] = OFDM_TABLE_SIZE_92D - 1; + } else if (internal_pa || + rtlhal->current_bandtype == BAND_ON_2_4G) { + if (ofdm_index[i] < ofdm_min_index_internal_pa) + ofdm_index[i] = ofdm_min_index_internal_pa; + } else if (ofdm_index[i] < ofdm_min_index) { + ofdm_index[i] = ofdm_min_index; + } + } + + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + } + + if (is2t) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], cck_index); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "new OFDM_A_index=0x%x, cck_index = 0x%x\n", + ofdm_index[0], cck_index); + } + + ele_d = (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->iqk_matrix[indexforchannel].value[0][0]; + val_y = rtlphy->iqk_matrix[indexforchannel].value[0][1]; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + /* new element C = element D x Y */ + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + /* write new elements A, C, D to regC80 and + * regC94, element B is always 0 + */ + value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), value32); + + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00); + } + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n", + rtlhal->interfaceindex, + val_x, val_y, ele_a, ele_c, ele_d, + val_x, val_y); + + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* Adjust CCK according to IQK result */ + for (i = 0; i < 8; i++) { + if (dm->cck_inch14) + swing = cckswing_table_ch14[cck_index][i]; + else + swing = cckswing_table_ch1ch13[cck_index][i]; + + rtl_write_byte(rtlpriv, 0xa22 + i, swing); + } + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & 0xFFC00000) >> 22; + val_x = rtlphy->iqk_matrix[indexforchannel].value[0][4]; + val_y = rtlphy->iqk_matrix[indexforchannel].value[0][5]; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + /* consider minus */ + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + /* new element C = element D x Y */ + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x00003FF; + + /* write new elements A, C, D to regC88 + * and regC9C, element B is always 0 + */ + value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, ofdmswing_table[ofdm_index[1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), 0x00); + } + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n", + val_x, val_y, ele_a, ele_c, ele_d, val_x, val_y); + } + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", + rtl_get_bbreg(hw, 0xc80, MASKDWORD), + rtl_get_bbreg(hw, 0xc94, MASKDWORD), + rtl_get_rfreg(hw, RF90_PATH_A, 0x24, RFREG_OFFSET_MASK)); + +check_delta: + if (delta_iqk > rtlefuse->delta_iqk && rtlefuse->delta_iqk != 0) { + rtl92d_phy_reset_iqk_result(hw); + dm->thermalvalue_iqk = thermalvalue; + rtlpriv->cfg->ops->phy_iq_calibrate(hw); + } + + if (delta_rxgain > 0 && rtlhal->current_bandtype == BAND_ON_5G && + thermalvalue <= rtlefuse->eeprom_thermalmeter) { + dm->thermalvalue_rxgain = thermalvalue; + rtl92d_dm_rxgain_tracking_thermalmeter(hw); + } + + if (dm->txpower_track_control) + dm->thermalvalue = thermalvalue; + +exit: + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); +} + +void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackinginit = false; + rtlpriv->dm.txpower_track_control = true; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); +} +EXPORT_SYMBOL_GPL(rtl92d_dm_initialize_txpower_tracking); + +void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | + BIT(16), 0x03); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 92S Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking direct call!!\n"); + rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); + rtlpriv->dm.tm_trigger = 0; + } +} +EXPORT_SYMBOL_GPL(rtl92d_dm_check_txpower_tracking_thermal_meter); + +void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + unsigned long flag = 0; + u32 ret_value; + + /* hold ofdm counter */ + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */ + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /* hold page D counter */ + + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff; + falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff; + falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff; + + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } else { + falsealm_cnt->cnt_cck_fail = 0; + } + + falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + + falsealm_cnt->cnt_cck_fail; + + /* reset false alarm counter registers */ + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + + /* update ofdm counter */ + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0); /* update page C counter */ + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0); /* update page D counter */ + + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) { + /* reset cck counter */ + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + /* enable cck counter */ + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n", + falsealm_cnt->cnt_fast_fsync_fail, + falsealm_cnt->cnt_sb_search_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, + falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, + falsealm_cnt->cnt_all); +} +EXPORT_SYMBOL_GPL(rtl92d_dm_false_alarm_counter_statistics); + +void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + + /* Determine the minimum RSSI */ + if (mac->link_state < MAC80211_LINKED && + rtlpriv->dm.entry_min_undec_sm_pwdb == 0) { + de_digtable->min_undec_pwdb_for_dm = 0; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "Not connected to any\n"); + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + de_digtable->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.entry_min_undec_sm_pwdb); + } else { + de_digtable->min_undec_pwdb_for_dm = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "STA Default Port PWDB = 0x%x\n", + de_digtable->min_undec_pwdb_for_dm); + } + } else { + de_digtable->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Ext Port or disconnect PWDB = 0x%x\n", + de_digtable->min_undec_pwdb_for_dm); + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + de_digtable->min_undec_pwdb_for_dm); +} +EXPORT_SYMBOL_GPL(rtl92d_dm_find_minimum_rssi); + +static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + unsigned long flag = 0; + + if (de_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (de_digtable->min_undec_pwdb_for_dm <= 25) + de_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + de_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } else { + if (de_digtable->min_undec_pwdb_for_dm <= 20) + de_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + de_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } + } else { + de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + } + if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) { + if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } else { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", + de_digtable->cursta_cstate == DIG_STA_CONNECT ? + "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", + de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + "Low RSSI " : "High RSSI "); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n", + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)); +} + +void rtl92d_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + de_digtable->cur_igvalue, de_digtable->pre_igvalue, + de_digtable->back_val); + if (!de_digtable->dig_enable_flag) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); + de_digtable->pre_igvalue = 0x17; + return; + } + if (de_digtable->pre_igvalue != de_digtable->cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + de_digtable->cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + de_digtable->cur_igvalue); + de_digtable->pre_igvalue = de_digtable->cur_igvalue; + } +} +EXPORT_SYMBOL_GPL(rtl92d_dm_write_dig); + +static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) +{ + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED && + rtlpriv->mac80211.vendor == PEER_CISCO) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); + if (de_digtable->last_min_undec_pwdb_for_dm >= 50 && + de_digtable->min_undec_pwdb_for_dm < 50) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Early Mode Off\n"); + } else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 && + de_digtable->min_undec_pwdb_for_dm > 55) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Early Mode On\n"); + } + } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); + } +} + +void rtl92d_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + u8 value_igi = de_digtable->cur_igvalue; + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); + if (rtlpriv->rtlhal.earlymode_enable) { + rtl92d_early_mode_enabled(rtlpriv); + de_digtable->last_min_undec_pwdb_for_dm = + de_digtable->min_undec_pwdb_for_dm; + } + if (!rtlpriv->dm.dm_initialgain_enable) + return; + + /* because we will send data pkt when scanning + * this will cause some ap like gear-3700 wep TP + * lower if we return here, this is the diff of + * mac80211 driver vs ieee80211 driver + */ + /* if (rtlpriv->mac80211.act_scanning) + * return; + */ + + /* Not STA mode return tmp */ + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); + /* Decide the current status and if modify initial gain or not */ + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) + de_digtable->cursta_cstate = DIG_STA_CONNECT; + else + de_digtable->cursta_cstate = DIG_STA_DISCONNECT; + + /* adjust initial gain according to false alarm counter */ + if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable->large_fa_hit, de_digtable->forbidden_igi); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_DIG() Before: Recover_cnt=%d, rx_gain_min=%x\n", + de_digtable->recover_cnt, de_digtable->rx_gain_min); + + /* deal with abnormally large false alarm */ + if (falsealm_cnt->cnt_all > 10000) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_DIG(): Abnormally false alarm case\n"); + + de_digtable->large_fa_hit++; + if (de_digtable->forbidden_igi < de_digtable->cur_igvalue) { + de_digtable->forbidden_igi = de_digtable->cur_igvalue; + de_digtable->large_fa_hit = 1; + } + if (de_digtable->large_fa_hit >= 3) { + if ((de_digtable->forbidden_igi + 1) > DM_DIG_MAX) + de_digtable->rx_gain_min = DM_DIG_MAX; + else + de_digtable->rx_gain_min = + (de_digtable->forbidden_igi + 1); + de_digtable->recover_cnt = 3600; /* 3600=2hr */ + } + } else { + /* Recovery mechanism for IGI lower bound */ + if (de_digtable->recover_cnt != 0) { + de_digtable->recover_cnt--; + } else { + if (de_digtable->large_fa_hit == 0) { + if ((de_digtable->forbidden_igi - 1) < + DM_DIG_FA_LOWER) { + de_digtable->forbidden_igi = + DM_DIG_FA_LOWER; + de_digtable->rx_gain_min = + DM_DIG_FA_LOWER; + + } else { + de_digtable->forbidden_igi--; + de_digtable->rx_gain_min = + (de_digtable->forbidden_igi + 1); + } + } else if (de_digtable->large_fa_hit == 3) { + de_digtable->large_fa_hit = 0; + } + } + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable->large_fa_hit, de_digtable->forbidden_igi); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_DIG() After: recover_cnt=%d, rx_gain_min=%x\n", + de_digtable->recover_cnt, de_digtable->rx_gain_min); + + if (value_igi > DM_DIG_MAX) + value_igi = DM_DIG_MAX; + else if (value_igi < de_digtable->rx_gain_min) + value_igi = de_digtable->rx_gain_min; + de_digtable->cur_igvalue = value_igi; + rtl92d_dm_write_dig(hw); + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) + rtl92d_dm_cck_packet_detection_thresh(hw); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n"); +} +EXPORT_SYMBOL_GPL(rtl92d_dm_dig); + +void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} +EXPORT_SYMBOL_GPL(rtl92d_dm_init_edca_turbo); + +void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + const u32 edca_be_ul = 0x5ea42b; + const u32 edca_be_dl = 0x5ea42b; + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + goto exit; + } + + if (!rtlpriv->dm.is_any_nonbepkts && + !rtlpriv->dm.disable_framebursting) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + &tmp); + rtlpriv->dm.current_turbo_edca = false; + } + } + +exit: + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} +EXPORT_SYMBOL_GPL(rtl92d_dm_check_edca_turbo); + +void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *ra = &rtlpriv->ra; + + ra->ratr_state = DM_RATR_STA_INIT; + ra->pre_ratr_state = DM_RATR_STA_INIT; + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; +} +EXPORT_SYMBOL_GPL(rtl92d_dm_init_rate_adaptive_mask); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h new file mode 100644 index 000000000..a146fc975 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_DM_COMMON_H__ +#define __RTL92D_DM_COMMON_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define OFDM_TABLE_SIZE_92D 43 +#define CCK_TABLE_LENGTH 33 + +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x100 +#define DM_DIG_FA_TH1 0x400 +#define DM_DIG_FA_TH2 0x600 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define INDEX_MAPPING_NUM 13 + +enum dm_1r_cca { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw); +void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw); +void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw); +void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw); +void rtl92d_dm_write_dig(struct ieee80211_hw *hw); +void rtl92d_dm_dig(struct ieee80211_hw *hw); +void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw); +void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c new file mode 100644 index 000000000..a255a5061 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../efuse.h" +#include "def.h" +#include "reg.h" +#include "fw_common.h" + +bool rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv) +{ + return !!(rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY); +} +EXPORT_SYMBOL_GPL(rtl92d_is_fw_downloaded); + +void rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + /* Reserved for fw extension. + * 0x81[7] is used for mac0 status , + * so don't write this reg here + * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + */ + } +} +EXPORT_SYMBOL_GPL(rtl92d_enable_fw_download); + +void rtl92d_write_fw(struct ieee80211_hw *hw, + enum version_8192d version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 *bufferptr = buffer; + u32 pagenums, remainsize; + u32 page, offset; + + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) + rtl_fill_dummy(bufferptr, &size); + + pagenums = size / FW_8192D_PAGE_SIZE; + remainsize = size % FW_8192D_PAGE_SIZE; + + if (pagenums > 8) + pr_err("Page numbers should not greater then 8\n"); + + for (page = 0; page < pagenums; page++) { + offset = page * FW_8192D_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192D_PAGE_SIZE); + } + + if (remainsize) { + offset = pagenums * FW_8192D_PAGE_SIZE; + page = pagenums; + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); + } +} +EXPORT_SYMBOL_GPL(rtl92d_write_fw); + +int rtl92d_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { + pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n", + value32); + return -EIO; + } + + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + return 0; +} +EXPORT_SYMBOL_GPL(rtl92d_fw_free_to_go); + +#define RTL_USB_DELAY_FACTOR 60 + +void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 u1b_tmp; + u8 delay = 100; + + if (rtlhal->interface == INTF_USB) { + delay *= RTL_USB_DELAY_FACTOR; + + rtl_write_byte(rtlpriv, REG_FSIMR, 0); + + /* We need to disable other HRCV INT to influence 8051 reset. */ + rtl_write_byte(rtlpriv, REG_FWIMR, 0x20); + + /* Close mask to prevent incorrect FW write operation. */ + rtl_write_byte(rtlpriv, REG_FTIMR, 0); + } + + /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */ + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & (FEN_CPUEN >> 8)) { + delay--; + if (delay == 0) + break; + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } + + if (rtlhal->interface == INTF_USB) { + if ((u1b_tmp & (FEN_CPUEN >> 8)) && delay == 0) + rtl_write_byte(rtlpriv, REG_FWIMR, 0); + } + + WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "=====> 8051 reset success (%d)\n", delay); +} +EXPORT_SYMBOL_GPL(rtl92d_firmware_selfreset); + +int rtl92d_fw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 counter; + + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n"); + /* polling for FW ready */ + counter = 0; + do { + if (rtlhal->interfaceindex == 0) { + if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & + MAC0_READY) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", + rtl_read_byte(rtlpriv, + FW_MAC0_READY)); + return 0; + } + udelay(5); + } else { + if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & + MAC1_READY) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", + rtl_read_byte(rtlpriv, + FW_MAC1_READY)); + return 0; + } + udelay(5); + } + } while (counter++ < POLLING_READY_TIMEOUT_COUNT); + + if (rtlhal->interfaceindex == 0) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC0_READY)); + } else { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC1_READY)); + } + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", + rtl_read_dword(rtlpriv, REG_MCUFWDL)); + return -1; +} +EXPORT_SYMBOL_GPL(rtl92d_fw_init); + +static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 boxcontent[4], boxextcontent[2]; + u16 box_reg = 0, box_extreg = 0; + u8 wait_writeh2c_limit = 100; + bool bwrite_success = false; + u8 wait_h2c_limit = 100; + u32 h2c_waitcounter = 0; + bool isfw_read = false; + unsigned long flag; + u8 u1b_tmp; + u8 boxnum; + u8 idx; + + if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Return as RF is off!!!\n"); + return; + } + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_success) { + wait_writeh2c_limit--; + if (wait_writeh2c_limit == 0) { + pr_err("Write H2C fail because no trigger for FW INT!\n"); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + if (boxnum > 3) { + pr_err("boxnum %#x too big\n", boxnum); + break; + } + + box_reg = REG_HMEBOX_0 + boxnum * SIZE_OF_REG_HMEBOX; + box_extreg = REG_HMEBOX_EXT_0 + boxnum * SIZE_OF_REG_HMEBOX_EXT; + + isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limit--; + if (wait_h2c_limit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1 ... 3: + /* BOX: | ID | A0 | A1 | A2 | + * BOX_EXT: --- N/A ------ + */ + boxcontent[0] &= ~BIT(7); + memcpy(boxcontent + 1, cmdbuffer, cmd_len); + + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + case 4 ... 5: + /* * ID ext = ID | BIT(7) + * BOX: | ID ext | A2 | A3 | A4 | + * BOX_EXT: | A0 | A1 | + */ + boxcontent[0] |= BIT(7); + memcpy(boxextcontent, cmdbuffer, 2); + memcpy(boxcontent + 1, cmdbuffer + 2, cmd_len - 2); + + for (idx = 0; idx < 2; idx++) + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + default: + pr_err("switch case %#x not processed\n", cmd_len); + break; + } + + bwrite_success = true; + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} +EXPORT_SYMBOL_GPL(rtl92d_fill_h2c_cmd); + +void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = {0}; + + u1_joinbssrpt_parm[0] = mstatus; + rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} +EXPORT_SYMBOL_GPL(rtl92d_set_fw_joinbss_report_cmd); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h new file mode 100644 index 000000000..4b73e0bd4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_FW_COMMON_H__ +#define __RTL92D_FW_COMMON_H__ + +#define FW_8192D_START_ADDRESS 0x1000 +#define FW_8192D_PAGE_SIZE 4096 +#define FW_8192D_POLLING_TIMEOUT_COUNT 1000 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3) + +/* Firmware Header(8-byte alinment required) */ +/* --- LONG WORD 0 ---- */ +#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr) \ + le32_get_bits(*(__le32 *)__fwhdr, GENMASK(15, 0)) +#define GET_FIRMWARE_HDR_VERSION(__fwhdr) \ + le32_get_bits(*(__le32 *)((__fwhdr) + 4), GENMASK(15, 0)) +#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr) \ + le32_get_bits(*(__le32 *)((__fwhdr) + 4), GENMASK(23, 16)) + +#define RAID_MASK GENMASK(31, 28) +#define RATE_MASK_MASK GENMASK(27, 0) +#define SHORT_GI_MASK BIT(5) +#define MACID_MASK GENMASK(4, 0) + +struct rtl92d_rate_mask_h2c { + __le32 rate_mask_and_raid; + u8 macid_and_short_gi; +} __packed; + +bool rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv); +void rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable); +void rtl92d_write_fw(struct ieee80211_hw *hw, + enum version_8192d version, u8 *buffer, u32 size); +int rtl92d_fw_free_to_go(struct ieee80211_hw *hw); +void rtl92d_firmware_selfreset(struct ieee80211_hw *hw); +int rtl92d_fw_init(struct ieee80211_hw *hw); +void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c new file mode 100644 index 000000000..cfefbe863 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c @@ -0,0 +1,1220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../cam.h" +#include "../efuse.h" +#include "../pci.h" +#include "../regd.h" +#include "def.h" +#include "reg.h" +#include "dm_common.h" +#include "fw_common.h" +#include "hw_common.h" +#include "phy_common.h" + +void rtl92d_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} +EXPORT_SYMBOL_GPL(rtl92d_stop_tx_beacon); + +void rtl92d_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} +EXPORT_SYMBOL_GPL(rtl92d_resume_tx_beacon); + +void rtl92d_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + *((u64 *)(val)) = tsf; + break; + } + case HW_VAR_INT_MIGRATION: + *((bool *)(val)) = rtlpriv->dm.interrupt_migration; + break; + case HW_VAR_INT_AC: + *((bool *)(val)) = rtlpriv->dm.disable_tx_int; + break; + case HAL_DEF_WOWLAN: + break; + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_get_hw_reg); + +void rtl92d_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + case HW_VAR_BASIC_RATE: { + u16 rate_cfg = ((u16 *)val)[0]; + u8 rate_index = 0; + + rate_cfg = rate_cfg & 0x15f; + if (mac->vendor == PEER_CISCO && + ((rate_cfg & 0x150) == 0)) + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (rate_cfg >> 8) & 0xff); + while (rate_cfg > 0x1) { + rate_cfg = (rate_cfg >> 1); + rate_index++; + } + if (rtlhal->fw_version > 0xe) + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME: { + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + for (e_aci = 0; e_aci < AC_MAX; e_aci++) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (&e_aci)); + break; + } + case HW_VAR_ACK_PREAMBLE: { + u8 reg_tmp; + u8 short_preamble = (bool)(*val); + + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE: { + u8 min_spacing_to_set; + + min_spacing_to_set = *val; + if (min_spacing_to_set <= 7) { + mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) | + min_spacing_to_set); + *val = min_spacing_to_set; + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY: { + u8 density_to_set; + + density_to_set = *val; + mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; + mac->min_space_cfg |= (density_to_set << 3); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + break; + } + case HW_VAR_AMPDU_FACTOR: { + u8 factor_toset; + u32 regtoset; + u8 *ptmp_byte = NULL; + u8 index; + + if (rtlhal->macphymode == DUALMAC_DUALPHY) + regtoset = 0xb9726641; + else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) + regtoset = 0x66626641; + else + regtoset = 0xb972a841; + factor_toset = *val; + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + for (index = 0; index < 4; index++) { + ptmp_byte = (u8 *)(®toset) + index; + if ((*ptmp_byte & 0xf0) > + (factor_toset << 4)) + *ptmp_byte = (*ptmp_byte & 0x0f) + | (factor_toset << 4); + if ((*ptmp_byte & 0x0f) > factor_toset) + *ptmp_byte = (*ptmp_byte & 0xf0) + | (factor_toset); + } + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoset); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; + } + case HW_VAR_RETRY_LIMIT: { + u8 retry_limit = val[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *val; + break; + case HW_VAR_IO_CMD: + rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *val); + break; + case HW_VAR_SET_RPWM: + rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (val)); + break; + case HW_VAR_H2C_FW_PWRMODE: + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_AID: { + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + break; + } + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_set_hw_reg); + +bool rtl92d_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_OP_VALUE(value) == _LLT_NO_ACTIVE) + break; + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + return status; +} +EXPORT_SYMBOL_GPL(rtl92d_llt_write); + +void rtl92d_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The SECR-value %x\n", sec_reg_value); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} +EXPORT_SYMBOL_GPL(rtl92d_enable_hw_security_config); + +/* don't set REG_EDCA_BE_PARAM here because + * mac80211 will send pkt when scan + */ +void rtl92d_set_qos(struct ieee80211_hw *hw, int aci) +{ + rtl92d_dm_init_edca_turbo(hw); +} +EXPORT_SYMBOL_GPL(rtl92d_set_qos); + +static enum version_8192d _rtl92d_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum version_8192d version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (!(value32 & 0x000f0000)) { + version = VERSION_TEST_CHIP_92D_SINGLEPHY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n"); + } else { + version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n"); + } + return version; +} + +static void _rtl92d_readpowervalue_fromprom(struct txpower_info *pwrinfo, + u8 *efuse, bool autoloadfail) +{ + u32 rfpath, eeaddr, group, offset, offset1, offset2; + u8 i, val8; + + memset(pwrinfo, 0, sizeof(struct txpower_info)); + if (autoloadfail) { + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + if (group < CHANNEL_GROUP_MAX_2G) { + pwrinfo->cck_index[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_2G; + pwrinfo->ht40_1sindex[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_2G; + } else { + pwrinfo->ht40_1sindex[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_5G; + } + pwrinfo->ht40_2sindexdiff[rfpath][group] = + EEPROM_DEFAULT_HT40_2SDIFF; + pwrinfo->ht20indexdiff[rfpath][group] = + EEPROM_DEFAULT_HT20_DIFF; + pwrinfo->ofdmindexdiff[rfpath][group] = + EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + pwrinfo->ht40maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT40_PWRMAXOFFSET; + pwrinfo->ht20maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT20_PWRMAXOFFSET; + } + } + for (i = 0; i < 3; i++) { + pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; + pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; + } + return; + } + + /* Maybe autoload OK,buf the tx power index value is not filled. + * If we find it, we set it to default value. + */ + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + for (group = 0; group < CHANNEL_GROUP_MAX_2G; group++) { + eeaddr = EEPROM_CCK_TX_PWR_INX_2G + (rfpath * 3) + group; + + pwrinfo->cck_index[rfpath][group] = + efuse[eeaddr] == 0xFF ? + (eeaddr > 0x7B ? + EEPROM_DEFAULT_TXPOWERLEVEL_5G : + EEPROM_DEFAULT_TXPOWERLEVEL_2G) : + efuse[eeaddr]; + } + } + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + offset1 = group / 3; + offset2 = group % 3; + eeaddr = EEPROM_HT40_1S_TX_PWR_INX_2G + (rfpath * 3); + eeaddr += offset2 + offset1 * 21; + + pwrinfo->ht40_1sindex[rfpath][group] = + efuse[eeaddr] == 0xFF ? + (eeaddr > 0x7B ? + EEPROM_DEFAULT_TXPOWERLEVEL_5G : + EEPROM_DEFAULT_TXPOWERLEVEL_2G) : + efuse[eeaddr]; + } + } + + /* These just for 92D efuse offset. */ + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + offset1 = group / 3; + offset2 = group % 3; + offset = offset2 + offset1 * 21; + + val8 = efuse[EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G + offset]; + if (val8 != 0xFF) + pwrinfo->ht40_2sindexdiff[rfpath][group] = + (val8 >> (rfpath * 4)) & 0xF; + else + pwrinfo->ht40_2sindexdiff[rfpath][group] = + EEPROM_DEFAULT_HT40_2SDIFF; + + val8 = efuse[EEPROM_HT20_TX_PWR_INX_DIFF_2G + offset]; + if (val8 != 0xFF) + pwrinfo->ht20indexdiff[rfpath][group] = + (val8 >> (rfpath * 4)) & 0xF; + else + pwrinfo->ht20indexdiff[rfpath][group] = + EEPROM_DEFAULT_HT20_DIFF; + + val8 = efuse[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + offset]; + if (val8 != 0xFF) + pwrinfo->ofdmindexdiff[rfpath][group] = + (val8 >> (rfpath * 4)) & 0xF; + else + pwrinfo->ofdmindexdiff[rfpath][group] = + EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + + val8 = efuse[EEPROM_HT40_MAX_PWR_OFFSET_2G + offset]; + if (val8 != 0xFF) + pwrinfo->ht40maxoffset[rfpath][group] = + (val8 >> (rfpath * 4)) & 0xF; + else + pwrinfo->ht40maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT40_PWRMAXOFFSET; + + val8 = efuse[EEPROM_HT20_MAX_PWR_OFFSET_2G + offset]; + if (val8 != 0xFF) + pwrinfo->ht20maxoffset[rfpath][group] = + (val8 >> (rfpath * 4)) & 0xF; + else + pwrinfo->ht20maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT20_PWRMAXOFFSET; + } + } + + if (efuse[EEPROM_TSSI_A_5G] != 0xFF) { + /* 5GL */ + pwrinfo->tssi_a[0] = efuse[EEPROM_TSSI_A_5G] & 0x3F; + pwrinfo->tssi_b[0] = efuse[EEPROM_TSSI_B_5G] & 0x3F; + /* 5GM */ + pwrinfo->tssi_a[1] = efuse[EEPROM_TSSI_AB_5G] & 0x3F; + pwrinfo->tssi_b[1] = (efuse[EEPROM_TSSI_AB_5G] & 0xC0) >> 6 | + (efuse[EEPROM_TSSI_AB_5G + 1] & 0x0F) << 2; + /* 5GH */ + pwrinfo->tssi_a[2] = (efuse[EEPROM_TSSI_AB_5G + 1] & 0xF0) >> 4 | + (efuse[EEPROM_TSSI_AB_5G + 2] & 0x03) << 4; + pwrinfo->tssi_b[2] = (efuse[EEPROM_TSSI_AB_5G + 2] & 0xFC) >> 2; + } else { + for (i = 0; i < 3; i++) { + pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; + pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; + } + } +} + +static void _rtl92d_read_txpower_info(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info pwrinfo; + u8 tempval[2], i, pwr, diff; + u32 ch, rfpath, group; + + _rtl92d_readpowervalue_fromprom(&pwrinfo, hwinfo, autoload_fail); + if (!autoload_fail) { + /* bit0~2 */ + rtlefuse->eeprom_regulatory = (hwinfo[EEPROM_RF_OPT1] & 0x7); + rtlefuse->eeprom_thermalmeter = + hwinfo[EEPROM_THERMAL_METER] & 0x1f; + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_K]; + tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03; + tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2; + rtlefuse->txpwr_fromeprom = true; + if (IS_92D_D_CUT(rtlpriv->rtlhal.version) || + IS_92D_E_CUT(rtlpriv->rtlhal.version)) { + rtlefuse->internal_pa_5g[0] = + !((hwinfo[EEPROM_TSSI_A_5G] & BIT(6)) >> 6); + rtlefuse->internal_pa_5g[1] = + !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Is D cut,Internal PA0 %d Internal PA1 %d\n", + rtlefuse->internal_pa_5g[0], + rtlefuse->internal_pa_5g[1]); + } + rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; + rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; + } else { + rtlefuse->eeprom_regulatory = 0; + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->crystalcap = EEPROM_DEFAULT_CRYSTALCAP; + tempval[0] = 3; + tempval[1] = tempval[0]; + } + + /* Use default value to fill parameters if + * efuse is not filled on some place. + */ + + /* ThermalMeter from EEPROM */ + if (rtlefuse->eeprom_thermalmeter < 0x06 || + rtlefuse->eeprom_thermalmeter > 0x1c) + rtlefuse->eeprom_thermalmeter = 0x12; + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + + /* check XTAL_K */ + if (rtlefuse->crystalcap == 0xFF) + rtlefuse->crystalcap = 0; + if (rtlefuse->eeprom_regulatory > 3) + rtlefuse->eeprom_regulatory = 0; + + for (i = 0; i < 2; i++) { + switch (tempval[i]) { + case 0: + tempval[i] = 5; + break; + case 1: + tempval[i] = 4; + break; + case 2: + tempval[i] = 3; + break; + case 3: + default: + tempval[i] = 0; + break; + } + } + + rtlefuse->delta_iqk = tempval[0]; + if (tempval[1] > 0) + rtlefuse->delta_lck = tempval[1] - 1; + if (rtlefuse->eeprom_c9 == 0xFF) + rtlefuse->eeprom_c9 = 0x00; + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory); + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "CrystalCap = 0x%x\n", rtlefuse->crystalcap); + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "Delta_IQK = 0x%x Delta_LCK = 0x%x\n", + rtlefuse->delta_iqk, rtlefuse->delta_lck); + + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { + group = rtl92d_get_chnlgroup_fromarray((u8)ch); + if (ch < CHANNEL_MAX_NUMBER_2G) + rtlefuse->txpwrlevel_cck[rfpath][ch] = + pwrinfo.cck_index[rfpath][group]; + rtlefuse->txpwrlevel_ht40_1s[rfpath][ch] = + pwrinfo.ht40_1sindex[rfpath][group]; + rtlefuse->txpwr_ht20diff[rfpath][ch] = + pwrinfo.ht20indexdiff[rfpath][group]; + rtlefuse->txpwr_legacyhtdiff[rfpath][ch] = + pwrinfo.ofdmindexdiff[rfpath][group]; + rtlefuse->pwrgroup_ht20[rfpath][ch] = + pwrinfo.ht20maxoffset[rfpath][group]; + rtlefuse->pwrgroup_ht40[rfpath][ch] = + pwrinfo.ht40maxoffset[rfpath][group]; + pwr = pwrinfo.ht40_1sindex[rfpath][group]; + diff = pwrinfo.ht40_2sindexdiff[rfpath][group]; + rtlefuse->txpwrlevel_ht40_2s[rfpath][ch] = + (pwr > diff) ? (pwr - diff) : 0; + } + } +} + +static void _rtl92d_read_macphymode_from_prom(struct ieee80211_hw *hw, + u8 *content) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_single_mac = true; + + if (rtlhal->interface == INTF_PCI) + is_single_mac = !!(content[EEPROM_MAC_FUNCTION] & BIT(3)); + else if (rtlhal->interface == INTF_USB) + is_single_mac = !(content[EEPROM_ENDPOINT_SETTING] & BIT(0)); + + if (is_single_mac) { + rtlhal->macphymode = SINGLEMAC_SINGLEPHY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MacPhyMode SINGLEMAC_SINGLEPHY\n"); + } else { + rtlhal->macphymode = DUALMAC_DUALPHY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MacPhyMode DUALMAC_DUALPHY\n"); + } +} + +static void _rtl92d_read_macphymode_and_bandtype(struct ieee80211_hw *hw, + u8 *content) +{ + _rtl92d_read_macphymode_from_prom(hw, content); + rtl92d_phy_config_macphymode(hw); + rtl92d_phy_config_macphymode_info(hw); +} + +static void _rtl92d_efuse_update_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum version_8192d chipver = rtlpriv->rtlhal.version; + u8 cutvalue[2]; + u16 chipvalue; + + read_efuse_byte(hw, EEPROME_CHIP_VERSION_H, &cutvalue[1]); + read_efuse_byte(hw, EEPROME_CHIP_VERSION_L, &cutvalue[0]); + chipvalue = (cutvalue[1] << 8) | cutvalue[0]; + switch (chipvalue) { + case 0xAA55: + chipver |= CHIP_92D_C_CUT; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n"); + break; + case 0x9966: + chipver |= CHIP_92D_D_CUT; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); + break; + case 0xCC33: + case 0x33CC: + chipver |= CHIP_92D_E_CUT; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "E-CUT!!!\n"); + break; + default: + chipver |= CHIP_92D_D_CUT; + pr_err("Unknown CUT!\n"); + break; + } + rtlpriv->rtlhal.version = chipver; +} + +static void _rtl92d_read_adapter_info(struct ieee80211_hw *hw) +{ + static const int params_pci[] = { + RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR_MAC0_92D, + EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13 + }; + static const int params_usb[] = { + RTL8190_EEPROM_ID, EEPROM_VID_USB, EEPROM_PID_USB, + EEPROM_VID_USB, EEPROM_PID_USB, EEPROM_MAC_ADDR_MAC0_92DU, + EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13 + }; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + const int *params = params_pci; + u8 *hwinfo; + + if (rtlhal->interface == INTF_USB) + params = params_usb; + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + _rtl92d_efuse_update_chip_version(hw); + _rtl92d_read_macphymode_and_bandtype(hw, hwinfo); + + /* Read Permanent MAC address for 2nd interface */ + if (rtlhal->interfaceindex != 0) + ether_addr_copy(rtlefuse->dev_addr, + &hwinfo[EEPROM_MAC_ADDR_MAC1_92D]); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, + rtlefuse->dev_addr); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + _rtl92d_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); + + /* Read Channel Plan */ + switch (rtlhal->bandset) { + case BAND_ON_2_4G: + rtlefuse->channel_plan = COUNTRY_CODE_TELEC; + break; + case BAND_ON_5G: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + case BAND_ON_BOTH: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + default: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + } + rtlefuse->txpwr_fromeprom = true; +exit: + kfree(hwinfo); +} + +void rtl92d_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92d_read_chip_version(hw); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + rtlefuse->autoload_status = tmp_u1b; + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + + rtlefuse->autoload_failflag = false; + _rtl92d_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } +} +EXPORT_SYMBOL_GPL(rtl92d_read_eeprom_info); + +static void rtl92d_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + enum wireless_mode wirelessmode; + u8 curtxbw_40mhz = mac->bw_40; + u8 nmode = mac->ht_enable; + u8 curshortgi_40mhz; + u8 curshortgi_20mhz; + u32 tmp_ratr_value; + u8 ratr_index = 0; + u16 shortgi_rate; + u32 ratr_value; + u32 ratr_mask; + + curshortgi_40mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + curshortgi_20mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + wirelessmode = mac->mode; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_A: + ratr_value &= 0x00000FF0; + break; + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) { + ratr_mask = 0x000ff005; + } else { + ratr_mask = 0x0f0ff005; + } + + ratr_value &= ratr_mask; + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + ratr_value &= 0x0FFFFFFF; + if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static void rtl92d_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl92d_rate_mask_h2c rate_mask = {}; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_sta_info *sta_entry = NULL; + enum wireless_mode wirelessmode; + bool shortgi = false; + u8 curshortgi_40mhz; + u8 curshortgi_20mhz; + u8 curtxbw_40mhz; + u32 ratr_bitmap; + u8 ratr_index; + u8 macid = 0; + u8 mimo_ps; + + curtxbw_40mhz = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; + curshortgi_40mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + curshortgi_20mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + mimo_ps = sta_entry->mimo_ps; + wirelessmode = sta_entry->wireless_mode; + + if (mac->opmode == NL80211_IFTYPE_STATION) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_G; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + if (wirelessmode == WIRELESS_MODE_N_24G) + ratr_index = RATR_INX_WIRELESS_NGB; + else + ratr_index = RATR_INX_WIRELESS_NG; + + if (mimo_ps == IEEE80211_SMPS_STATIC) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + + le32p_replace_bits(&rate_mask.rate_mask_and_raid, ratr_bitmap, RATE_MASK_MASK); + le32p_replace_bits(&rate_mask.rate_mask_and_raid, ratr_index, RAID_MASK); + u8p_replace_bits(&rate_mask.macid_and_short_gi, macid, MACID_MASK); + u8p_replace_bits(&rate_mask.macid_and_short_gi, shortgi, SHORT_GI_MASK); + u8p_replace_bits(&rate_mask.macid_and_short_gi, 1, BIT(7)); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %5phC\n", + ratr_index, ratr_bitmap, &rate_mask); + + if (rtlhal->interface == INTF_PCI) { + rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, sizeof(rate_mask), + (u8 *)&rate_mask); + } else { + /* rtl92d_fill_h2c_cmd() does USB I/O and will result in a + * "scheduled while atomic" if called directly + */ + memcpy(rtlpriv->rate_mask, &rate_mask, + sizeof(rtlpriv->rate_mask)); + schedule_work(&rtlpriv->works.fill_h2c_cmd); + } + + if (macid != 0) + sta_entry->ratr_index = ratr_index; +} + +void rtl92d_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92d_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl92d_update_hal_rate_table(hw, sta); +} +EXPORT_SYMBOL_GPL(rtl92d_update_hal_rate_tbl); + +void rtl92d_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} +EXPORT_SYMBOL_GPL(rtl92d_update_channel_access_setting); + +bool rtl92d_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp; + bool actuallyset = false; + unsigned long flag; + + if (rtlpriv->rtlhal.interface == INTF_PCI && + rtlpci->being_init_adapter) + return false; + if (ppsc->swrf_processing) + return false; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } + + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, + rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG) & ~(BIT(3))); + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; + if (ppsc->hwradiooff && e_rfpowerstate_toset == ERFON) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + actuallyset = true; + } else if (!ppsc->hwradiooff && e_rfpowerstate_toset == ERFOFF) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + actuallyset = true; + } + if (actuallyset) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + *valid = 1; + return !ppsc->hwradiooff; +} +EXPORT_SYMBOL_GPL(rtl92d_gpio_radio_on_off_checking); + +void rtl92d_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + static const u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static const u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + const u8 *macaddr = p_macaddr; + bool is_pairwise = false; + u32 entry_id; + + if (clear_all) { + u8 idx; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + return; + } + + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + pr_err("switch case %#x not processed\n", + enc_algo); + enc_algo = CAM_TKIP; + break; + } + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + } +} +EXPORT_SYMBOL_GPL(rtl92d_set_key); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h new file mode 100644 index 000000000..4da1bab15 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_HW_COMMON_H__ +#define __RTL92D_HW_COMMON_H__ + +void rtl92d_stop_tx_beacon(struct ieee80211_hw *hw); +void rtl92d_resume_tx_beacon(struct ieee80211_hw *hw); +void rtl92d_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92d_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +bool rtl92d_llt_write(struct ieee80211_hw *hw, u32 address, u32 data); +void rtl92d_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92d_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92d_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92d_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw); +void rtl92d_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92d_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92d_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c new file mode 100644 index 000000000..e58dc4000 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192D 802.11n common routines"); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c new file mode 100644 index 000000000..228c84ab5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c @@ -0,0 +1,856 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "def.h" +#include "reg.h" +#include "dm_common.h" +#include "phy_common.h" +#include "rf_common.h" + +static const u8 channel_all[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, + 132, 134, 136, 138, 140, 149, 151, 153, 155, + 157, 159, 161, 163, 165 +}; + +static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + newoffset = offset; + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + udelay(10); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + udelay(100); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + udelay(10); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSIREADBACKDATA); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); + return retvalue; +} + +static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 offset, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 data_and_addr; + u32 newoffset; + + newoffset = offset; + /* T65 RF */ + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); +} + +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + rtl92d_pci_lock(rtlpriv); + original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + rtl92d_pci_unlock(rtlpriv); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + return readback_value; +} +EXPORT_SYMBOL_GPL(rtl92d_phy_query_rf_reg); + +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + if (bitmask == 0) + return; + rtl92d_pci_lock(rtlpriv); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92d_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); + } + rtl92d_pci_unlock(rtlpriv); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_set_rf_reg); + +void rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + /* RF Interface Sowrtware Control */ + /* 16 LSBs if read 32-bit from 0x870 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + /* 16 LSBs if read 32-bit from 0x874 */ + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ + + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + /* RF Interface Readback Value */ + /* 16 LSBs if read 32-bit from 0x8E0 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + /* 16 LSBs if read 32-bit from 0x8E4 */ + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + /* RF Interface Output (and Enable) */ + /* 16 LSBs if read 32-bit from 0x860 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + /* 16 LSBs if read 32-bit from 0x864 */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + /* RF Interface (Output and) Enable */ + /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + /* Addr of LSSI. Write RF register by driver */ + /* LSSI Parameter */ + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + /* RF parameter */ + /* BB Band Select */ + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + /* Transceiver A~D HSSI Parameter-1 */ + /* wire control parameter1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + /* wire control parameter1 */ + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + /* Transceiver A~D HSSI Parameter-2 */ + /* wire control parameter2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + /* wire control parameter2 */ + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + /* RF switch Control */ + /* TR/Ant switch control */ + rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + + /* AGC control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + /* AGC control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + /* RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + + /*RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + /* Tx AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + + /* Tx AFE control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + /* Transceiver LSSI Readback SI mode */ + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + + /* Transceiver LSSI Readback PI mode */ + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; +} +EXPORT_SYMBOL_GPL(rtl92d_phy_init_bb_rf_register_definition); + +void rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + int index; + + if (regaddr == RTXAGC_A_RATE18_06) + index = 0; + else if (regaddr == RTXAGC_A_RATE54_24) + index = 1; + else if (regaddr == RTXAGC_A_CCK1_MCS32) + index = 6; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) + index = 7; + else if (regaddr == RTXAGC_A_MCS03_MCS00) + index = 2; + else if (regaddr == RTXAGC_A_MCS07_MCS04) + index = 3; + else if (regaddr == RTXAGC_A_MCS11_MCS08) + index = 4; + else if (regaddr == RTXAGC_A_MCS15_MCS12) + index = 5; + else if (regaddr == RTXAGC_B_RATE18_06) + index = 8; + else if (regaddr == RTXAGC_B_RATE54_24) + index = 9; + else if (regaddr == RTXAGC_B_CCK1_55_MCS32) + index = 14; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) + index = 15; + else if (regaddr == RTXAGC_B_MCS03_MCS00) + index = 10; + else if (regaddr == RTXAGC_B_MCS07_MCS04) + index = 11; + else if (regaddr == RTXAGC_B_MCS11_MCS08) + index = 12; + else if (regaddr == RTXAGC_B_MCS15_MCS12) + index = 13; + else + return; + + rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", + rtlphy->pwrgroup_cnt, index, + rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); + if (index == 13) + rtlphy->pwrgroup_cnt++; +} +EXPORT_SYMBOL_GPL(rtl92d_store_pwrindex_diffrate_offset); + +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_get_hw_reg_originalvalue); + +static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = channel - 1; + + /* 1. CCK */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* RF-A */ + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + /* RF-B */ + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + } else { + cckpowerlevel[RF90_PATH_A] = 0; + cckpowerlevel[RF90_PATH_B] = 0; + } + /* 2. OFDM for 1S or 2S */ + if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (rtlphy->rf_type == RF_2T2R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl) +{ + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < ARRAY_SIZE(channel_all); place++) { + if (channel_all[place] == chnl) { + place++; + break; + } + } + } + return place; +} + +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (!rtlefuse->txpwr_fromeprom) + return; + channel = _rtl92c_phy_get_rightchnlplace(channel); + _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + _rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_set_txpower_level); + +void rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, u8 rfpath, + u32 *pu4_regval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); + /*----Store original RFENV control type----*/ + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + *pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + *pu4_regval = + rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16); + break; + } + /*----Set RF_ENV enable----*/ + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + /*----Set RF_ENV output high----*/ + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + /* Set bit number of Address and Data for RF register */ + /* Set 1 to 4 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0); + udelay(1); + /*Set 0 to 12 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_enable_rf_env); + +void rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, + u32 *pu4_regval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n"); + /*----Restore RFENV control type----*/ + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, + *pu4_regval); + break; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n"); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_restore_rf_env); + +u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) +{ + u8 place; + + if (chnl > 14) { + for (place = 14; place < ARRAY_SIZE(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(rtl92d_get_rightchnlplace_for_iqk); + +void rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, const u32 *adda_reg, + u32 *adda_backup, u32 regnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n"); + for (i = 0; i < regnum; i++) + adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], MASKDWORD); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_save_adda_registers); + +void rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, + const u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n"); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_save_mac_registers); + +void rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, + const u32 *adda_reg, bool patha_on, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 pathon; + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n"); + pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (patha_on) + pathon = rtlpriv->rtlhal.interfaceindex == 0 ? + 0x04db25a4 : 0x0b1b25a4; + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, pathon); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_path_adda_on); + +void rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, + const u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n"); + rtl_write_byte(rtlpriv, macreg[0], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & + (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5)))); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_mac_setting_calibration); + +static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2) +{ + u32 ret; + + if (val1 >= val2) + ret = val1 - val2; + else + ret = val2 - val1; + return ret; +} + +static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(channel5g); i++) + if (channel == channel5g[i]) + return true; + return false; +} + +void rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, + const u32 *targetchnl, u32 *curvecount_val, + bool is5g, u32 *curveindex) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 smallest_abs_val = 0xffffffff, u4tmp; + u8 i, j; + u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G; + + for (i = 0; i < chnl_num; i++) { + if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1)) + continue; + curveindex[i] = 0; + for (j = 0; j < (CV_CURVE_CNT * 2); j++) { + u4tmp = _rtl92d_phy_get_abs(targetchnl[i], + curvecount_val[j]); + + if (u4tmp < smallest_abs_val) { + curveindex[i] = j; + smallest_abs_val = u4tmp; + } + } + smallest_abs_val = 0xffffffff; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n", + i, curveindex[i]); + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_calc_curvindex); + +void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "settings regs %zu default regs %d\n", + ARRAY_SIZE(rtlphy->iqk_matrix), + IQK_MATRIX_REG_NUM); + /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ + for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { + rtlphy->iqk_matrix[i].value[0][0] = 0x100; + rtlphy->iqk_matrix[i].value[0][2] = 0x100; + rtlphy->iqk_matrix[i].value[0][4] = 0x100; + rtlphy->iqk_matrix[i].value[0][6] = 0x100; + rtlphy->iqk_matrix[i].value[0][1] = 0x0; + rtlphy->iqk_matrix[i].value[0][3] = 0x0; + rtlphy->iqk_matrix[i].value[0][5] = 0x0; + rtlphy->iqk_matrix[i].value[0][7] = 0x0; + rtlphy->iqk_matrix[i].iqk_done = false; + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_reset_iqk_result); + +static void rtl92d_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *de_digtable = &rtlpriv->dm_digtable; + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + de_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92d_dm_write_dig(hw); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = de_digtable->cur_igvalue; + de_digtable->cur_igvalue = 0x37; + if (rtlpriv->rtlhal.interface == INTF_USB) + de_digtable->cur_igvalue = 0x17; + rtl92d_dm_write_dig(hw); + break; + default: + pr_err("switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); +} + +bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan\n"); + postprocessing = true; + break; + default: + pr_err("switch case %#x not processed\n", + iotype); + break; + } + } while (false); + + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + + rtl92d_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); + return true; +} +EXPORT_SYMBOL_GPL(rtl92d_phy_set_io_cmd); + +void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 offset = REG_MAC_PHY_CTRL_NORMAL; + u8 phy_ctrl = 0xf0; + + if (rtlhal->interface == INTF_USB) { + phy_ctrl = rtl_read_byte(rtlpriv, offset); + phy_ctrl &= ~(BIT(0) | BIT(1) | BIT(2)); + } + + switch (rtlhal->macphymode) { + case DUALMAC_DUALPHY: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MacPhyMode: DUALMAC_DUALPHY\n"); + rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(0) | BIT(1)); + break; + case SINGLEMAC_SINGLEPHY: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MacPhyMode: SINGLEMAC_SINGLEPHY\n"); + rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(2)); + break; + case DUALMAC_SINGLEPHY: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MacPhyMode: DUALMAC_SINGLEPHY\n"); + rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(0)); + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_config_macphymode); + +void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + switch (rtlhal->macphymode) { + case DUALMAC_SINGLEPHY: + rtlphy->rf_type = RF_2T2R; + rtlhal->version |= RF_TYPE_2T2R; + rtlhal->bandset = BAND_ON_BOTH; + rtlhal->current_bandtype = BAND_ON_2_4G; + break; + + case SINGLEMAC_SINGLEPHY: + rtlphy->rf_type = RF_2T2R; + rtlhal->version |= RF_TYPE_2T2R; + rtlhal->bandset = BAND_ON_BOTH; + rtlhal->current_bandtype = BAND_ON_2_4G; + break; + + case DUALMAC_DUALPHY: + rtlphy->rf_type = RF_1T1R; + rtlhal->version &= RF_TYPE_1T1R; + /* Now we let MAC0 run on 5G band. */ + if (rtlhal->interfaceindex == 0) { + rtlhal->bandset = BAND_ON_5G; + rtlhal->current_bandtype = BAND_ON_5G; + } else { + rtlhal->bandset = BAND_ON_2_4G; + rtlhal->current_bandtype = BAND_ON_2_4G; + } + break; + default: + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_config_macphymode_info); + +u8 rtl92d_get_chnlgroup_fromarray(u8 chnl) +{ + u8 group; + + if (channel_all[chnl] <= 3) + group = 0; + else if (channel_all[chnl] <= 9) + group = 1; + else if (channel_all[chnl] <= 14) + group = 2; + else if (channel_all[chnl] <= 44) + group = 3; + else if (channel_all[chnl] <= 54) + group = 4; + else if (channel_all[chnl] <= 64) + group = 5; + else if (channel_all[chnl] <= 112) + group = 6; + else if (channel_all[chnl] <= 126) + group = 7; + else if (channel_all[chnl] <= 140) + group = 8; + else if (channel_all[chnl] <= 153) + group = 9; + else if (channel_all[chnl] <= 159) + group = 10; + else + group = 11; + return group; +} +EXPORT_SYMBOL_GPL(rtl92d_get_chnlgroup_fromarray); + +u8 rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex) +{ + u8 group; + + if (channel_all[chnlindex] <= 3) /* Chanel 1-3 */ + group = 0; + else if (channel_all[chnlindex] <= 9) /* Channel 4-9 */ + group = 1; + else if (channel_all[chnlindex] <= 14) /* Channel 10-14 */ + group = 2; + else if (channel_all[chnlindex] <= 64) + group = 6; + else if (channel_all[chnlindex] <= 140) + group = 7; + else + group = 8; + return group; +} + +void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (rtlpriv->rtlhal.macphymode) { + case DUALMAC_DUALPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0x0); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff); + break; + case DUALMAC_SINGLEPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0xf8); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff); + break; + case SINGLEMAC_SINGLEPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0x0); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10); + rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); + break; + default: + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_config_maccoexist_rfpage); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h new file mode 100644 index 000000000..0f794557a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_PHY_COMMON_H__ +#define __RTL92D_PHY_COMMON_H__ + +#define TARGET_CHNL_NUM_5G 221 +#define TARGET_CHNL_NUM_2G 14 +#define CV_CURVE_CNT 64 +#define RT_CANNOT_IO(hw) false +#define RX_INDEX_MAPPING_NUM 15 +#define IQK_BB_REG_NUM 10 + +#define IQK_DELAY_TIME 1 +#define MAX_TOLERANCE 5 +#define MAX_TOLERANCE_92D 3 + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum rf_content { + radioa_txt = 0, + radiob_txt = 1, + radioc_txt = 2, + radiod_txt = 3 +}; + +static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.interface == INTF_USB) + return; + + if (rtlpriv->rtlhal.interfaceindex == 1) + spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag); +} + +static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.interface == INTF_USB) + return; + + if (rtlpriv->rtlhal.interfaceindex == 1) + spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock, + *flag); +} + +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +void rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +void rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, u8 rfpath, + u32 *pu4_regval); +void rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, + u32 *pu4_regval); +u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl); +void rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, const u32 *adda_reg, + u32 *adda_backup, u32 regnum); +void rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, + const u32 *macreg, u32 *macbackup); +void rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, + const u32 *adda_reg, bool patha_on, bool is2t); +void rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, + const u32 *macreg, u32 *macbackup); +void rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, + const u32 *targetchnl, u32 *curvecount_val, + bool is5g, u32 *curveindex); +void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw); +bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw); +void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw); +u8 rtl92d_get_chnlgroup_fromarray(u8 chnl); +u8 rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex); +void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw); +/* Without these declarations sparse warns about context imbalance. */ +void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag); +void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag); + +/* Without these helpers and the declarations sparse warns about + * context imbalance. + */ +static inline void rtl92d_pci_lock(struct rtl_priv *rtlpriv) +{ + if (rtlpriv->rtlhal.interface == INTF_PCI) + spin_lock(&rtlpriv->locks.rf_lock); +} + +static inline void rtl92d_pci_unlock(struct rtl_priv *rtlpriv) +{ + if (rtlpriv->rtlhal.interface == INTF_PCI) + spin_unlock(&rtlpriv->locks.rf_lock); +} + +void rtl92d_pci_lock(struct rtl_priv *rtlpriv); +void rtl92d_pci_unlock(struct rtl_priv *rtlpriv); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h new file mode 100644 index 000000000..b5b906b79 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h @@ -0,0 +1,1393 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_REG_H__ +#define __RTL92D_REG_H__ + +/* ----------------------------------------------------- */ +/* 0x0000h ~ 0x00FFh System Configuration */ +/* ----------------------------------------------------- */ +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_POWER_OFF_IN_PROCESS 0x0017 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +/* for 92d, DMDP,SMSP,DMSP contrl */ +#define REG_MAC_PHY_CTRL 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E +#define SIZE_OF_REG_HMEBOX_EXT 2 + +#define REG_EFUSE_ACCESS 0x00CF + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 + +#define REG_MAC0 0x0081 +#define REG_MAC1 0x0053 +#define FW_MAC0_READY 0x18 +#define FW_MAC1_READY 0x1A +#define MAC0_ON BIT(7) +#define MAC1_ON BIT(0) +#define MAC0_READY BIT(0) +#define MAC1_READY BIT(0) + +/* ----------------------------------------------------- */ +/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ +/* ----------------------------------------------------- */ +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTIMR 0x0138 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_C2HEVT_CLEAR 0x01BF +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC +#define SIZE_OF_REG_HMEBOX 4 + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + + +/* ----------------------------------------------------- */ +/* 0x0200h ~ 0x027Fh TXDMA Configuration */ +/* ----------------------------------------------------- */ +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +/* ----------------------------------------------------- */ +/* 0x0280h ~ 0x02FFh RXDMA Configuration */ +/* ----------------------------------------------------- */ +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +/* ----------------------------------------------------- */ +/* 0x0300h ~ 0x03FFh PCIe */ +/* ----------------------------------------------------- */ +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_DBI_WDATA 0x0348 +#define REG_DBI_RDATA 0x034C +#define REG_DBI_CTRL 0x0350 +#define REG_DBI_FLAG 0x0352 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +/* ----------------------------------------------------- */ +/* 0x0400h ~ 0x047Fh Protocol Configuration */ +/* ----------------------------------------------------- */ +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_EARLY_MODE_CONTROL 0x4D0 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +/* ----------------------------------------------------- */ +/* 0x0500h ~ 0x05FFh EDCA Configuration */ +/* ----------------------------------------------------- */ +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +/* Dual MAC Co-Existence Register */ +#define REG_DMC 0x05F0 + +/* ----------------------------------------------------- */ +/* 0x0600h ~ 0x07FFh WMAC Configuration */ +/* ----------------------------------------------------- */ +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + + +/* WMA, BA, CCX */ +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + + +/* Security */ +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +/* Power */ +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_Queue_Select_MAC0 0xFE44 +#define REG_USB_Queue_Select_MAC1 0xFE47 + +/* ----------------------------------------------------- */ +/* Redifine 8192C register definition for compatibility */ +/* ----------------------------------------------------- */ +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +/* ----------------------------------------------------- */ +/* 8192C (MSR) Media Status Register(Offset 0x4C, 8 bits)*/ +/* ----------------------------------------------------- */ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 +#define MSR_MASK 0x03 + +/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */ +/* ----------------------------------------------------- */ +/* 8192C Response Rate Set Register(offset 0x181, 24bits)*/ +/* ----------------------------------------------------- */ +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +/* ----------------------------------------------------- */ +/* 8192C Rate Definition */ +/* ----------------------------------------------------- */ +/* CCK */ +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +/* OFDM */ +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +/* MCS 1 Spatial Stream */ +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +/* MCS 2 Spatial Stream */ +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +/* CCK */ +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +/* OFDM */ +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +/* MCS 1 Spatial Stream */ +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +/* MCS 2 Spatial Stream */ +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +/* ALL CCK Rate */ +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | \ + RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | \ + RATR_18M | RATR_24M | \ + RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +/* ----------------------------------------------------- */ +/* 8192C BW_OPMODE bits (Offset 0x203, 8bit) */ +/* ----------------------------------------------------- */ +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + + +/* ----------------------------------------------------- */ +/* 8192C CAM Config Setting (offset 0x250, 1 byte) */ +/* ----------------------------------------------------- */ +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +/* 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF) */ +#define WOW_PMEN BIT0 /* Power management Enable. */ +#define WOW_WOMEN BIT1 /* WoW function on or off. */ +#define WOW_MAGIC BIT2 /* Magic packet */ +#define WOW_UWF BIT3 /* Unicast Wakeup frame. */ + +/* 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) */ +/* ----------------------------------------------------- */ +/* 8190 IMR/ISR bits (offset 0xfd, 8bits) */ +/* ----------------------------------------------------- */ +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_C2HCMD BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +/* ----------------------------------------------------- */ +/* 8192C EFUSE */ +/* ----------------------------------------------------- */ +#define HWSET_MAX_SIZE 256 +#define EFUSE_MAX_SECTION 32 +#define EFUSE_REAL_CONTENT_LEN 512 + +/* ----------------------------------------------------- */ +/* 8192C EEPROM/EFUSE share register definition. */ +/* ----------------------------------------------------- */ +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x0 +#define EEPROM_DEFAULT_THERMALMETER 0x12 + +#define EEPROM_DEFAULT_TXPOWERLEVEL_2G 0x2C +#define EEPROM_DEFAULT_TXPOWERLEVEL_5G 0x22 + +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +/* HT20<->40 default Tx Power Index Difference */ +#define EEPROM_DEFAULT_HT20_DIFF 2 +/* OFDM Tx Power index diff */ +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x4 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + + +#define RTL8192_EEPROM_ID 0x8129 +#define EEPROM_WAPI_SUPPORT 0x78 + + +#define RTL8190_EEPROM_ID 0x8129 /* 0-1 */ +#define EEPROM_HPON 0x02 /* LDO settings.2-5 */ +#define EEPROM_CLK 0x06 /* Clock settings.6-7 */ +#define EEPROM_MAC_FUNCTION 0x08 /* SE Test mode.8 */ + +#define EEPROM_VID 0x28 /* SE Vendor ID.A-B */ +#define EEPROM_DID 0x2A /* SE Device ID. C-D */ +#define EEPROM_SVID 0x2C /* SE Vendor ID.E-F */ +#define EEPROM_SMID 0x2E /* SE PCI Subsystem ID. 10-11 */ + +#define EEPROM_VID_USB 0xC +#define EEPROM_PID_USB 0xE +#define EEPROM_ENDPOINT_SETTING 0x10 +#define EEPROM_MAC_ADDR 0x16 /* SEMAC Address. 12-17 */ +#define EEPROM_MAC_ADDR_MAC0_92DU 0x19 +#define EEPROM_MAC_ADDR_MAC0_92D 0x55 +#define EEPROM_MAC_ADDR_MAC1_92D 0x5B + +/* 2.4G band Tx power index setting */ +#define EEPROM_CCK_TX_PWR_INX_2G 0x61 +#define EEPROM_HT40_1S_TX_PWR_INX_2G 0x67 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G 0x6D +#define EEPROM_HT20_TX_PWR_INX_DIFF_2G 0x70 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_2G 0x73 +#define EEPROM_HT40_MAX_PWR_OFFSET_2G 0x76 +#define EEPROM_HT20_MAX_PWR_OFFSET_2G 0x79 + +/*5GL channel 32-64 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GL 0x7C +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GL 0x82 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GL 0x85 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GL 0x88 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GL 0x8B +#define EEPROM_HT20_MAX_PWR_OFFSET_5GL 0x8E + +/* 5GM channel 100-140 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GM 0x91 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GM 0x97 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GM 0x9A +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GM 0x9D +#define EEPROM_HT40_MAX_PWR_OFFSET_5GM 0xA0 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GM 0xA3 + +/* 5GH channel 149-165 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GH 0xA6 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GH 0xAC +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GH 0xAF +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GH 0xB2 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GH 0xB5 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GH 0xB8 + +/* Map of supported channels. */ +#define EEPROM_CHANNEL_PLAN 0xBB +#define EEPROM_IQK_DELTA 0xBC +#define EEPROM_LCK_DELTA 0xBC +#define EEPROM_XTAL_K 0xBD /* [7:5] */ +#define EEPROM_TSSI_A_5G 0xBE +#define EEPROM_TSSI_B_5G 0xBF +#define EEPROM_TSSI_AB_5G 0xC0 +#define EEPROM_THERMAL_METER 0xC3 /* [4:0] */ +#define EEPROM_RF_OPT1 0xC4 +#define EEPROM_RF_OPT2 0xC5 +#define EEPROM_RF_OPT3 0xC6 +#define EEPROM_RF_OPT4 0xC7 +#define EEPROM_RF_OPT5 0xC8 +#define EEPROM_RF_OPT6 0xC9 +#define EEPROM_VERSION 0xCA +#define EEPROM_CUSTOMER_ID 0xCB +#define EEPROM_RF_OPT7 0xCC + +#define EEPROM_DEF_PART_NO 0x3FD /* Byte */ +#define EEPROME_CHIP_VERSION_L 0x3FF +#define EEPROME_CHIP_VERSION_H 0x3FE + +/* + * Current IOREG MAP + * 0x0000h ~ 0x00FFh System Configuration (256 Bytes) + * 0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) + * 0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) + * 0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) + * 0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) + * 0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) + * 0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) + * 0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) + * 0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) + */ + +/* ----------------------------------------------------- */ +/* 8192C (RCR) (Offset 0x608, 32 bits) */ +/* ----------------------------------------------------- */ +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +/* ----------------------------------------------------- */ +/* 8192C Regsiter Bit and Content definition */ +/* ----------------------------------------------------- */ +/* ----------------------------------------------------- */ +/* 0x0000h ~ 0x00FFh System Configuration */ +/* ----------------------------------------------------- */ + +/* SPS0_CTRL */ +#define SW18_FPWM BIT(3) + + +/* SYS_ISO_CTRL */ +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + + +/* SYS_FUNC_EN */ +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +/* APS_FSMCO */ +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +/* SYS_CLKR */ +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + + +/* 9346CR */ +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +/* AFE_MISC */ +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +/* RSV_CTRL */ +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +/* RF_CTRL */ +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + + +/* LDOA15_CTRL */ +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + + + +/* LDOV12D_CTRL */ +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +/* AFE_XTAL_CTRL */ +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + + +/* AFE_PLL_CTRL */ +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + + +/* EFUSE_CTRL */ +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +/* EFUSE_TEST */ +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +/* MCUFWDL */ +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define MAC1_WINTINI_RDY BIT(11) +#define CPRST BIT(23) + +/* REG_SYS_CFG */ +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define TXDMA_HIQ_MAP GENMASK(15, 14) +#define TXDMA_MGQ_MAP GENMASK(13, 12) +#define TXDMA_BKQ_MAP GENMASK(11, 10) +#define TXDMA_BEQ_MAP GENMASK(9, 8) +#define TXDMA_VIQ_MAP GENMASK(7, 6) +#define TXDMA_VOQ_MAP GENMASK(5, 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define HPQ_MASK GENMASK(7, 0) +#define LPQ_MASK GENMASK(15, 8) +#define PUBQ_MASK GENMASK(23, 16) +#define LD_RQPN BIT(31) + +#define DROP_DATA_EN BIT(9) + +/* LLT_INIT */ +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +/* ----------------------------------------------------- */ +/* 0x0400h ~ 0x047Fh Protocol Configuration */ +/* ----------------------------------------------------- */ +/* FWHW_TXQ_CTRL */ +#define EN_AMPDU_RTY_NEW BIT(7) +#define EN_BCNQ_DL BIT(22) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + + +/* ----------------------------------------------------- */ +/* 0x0500h ~ 0x05FFh EDCA Configuration */ +/* ----------------------------------------------------- */ +/* EDCA setting */ +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +/* REG_RD_CTRL */ +#define DIS_EDCA_CNT_DWN BIT(11) + +/* REG_BCN_CTRL */ +#define EN_BCN_FUNCTION BIT(3) +#define DIS_TSF_UDT BIT(4) + +/* ACMHWCTRL */ +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) + +/* ----------------------------------------------------- */ +/* 0x0600h ~ 0x07FFh WMAC Configuration */ +/* ----------------------------------------------------- */ + +/* TCR */ +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +/* SECCFG */ +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXENCENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +/* General definitions */ +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC 127 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +/* Min Spacing related settings. */ +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + + +/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ +/* 1. PMAC duplicate register due to connection: */ +/* RF_Mode, TRxRN, NumOf L-STF */ +/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ +/* 3. RF register 0x00-2E */ +/* 4. Bit Mask for BB/RF register */ +/* 5. Other defintion for BB/RF R/W */ + +/* 3. Page8(0x800) */ +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ADDALLOCKEN 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVERA_HSPI_READBACK 0x8b8 +#define TRANSCEIVERB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +/* 4. Page9(0x900) */ +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +/* 5. PageA(0xA00) */ +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESSTTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define RPDP_ANTA 0xb00 +#define RCONFIG_ANTA 0xb68 +#define RCONFIG_ANTB 0xb6c +#define RPDP_ANTB 0xb70 + +/* 6. PageC(0xC00) */ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBALANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_RXIQEXTANTA 0xca0 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +/* 7. PageD(0xD00) */ +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CFO 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCFOAB 0xdbc +#define ROFDM_TAILCFOCD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +/* 8. PageE(0xE00) */ +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RFPGA0_IQK 0xe28 +#define RTX_IQK_TONE_A 0xe30 +#define RRX_IQK_TONE_A 0xe34 +#define RTX_IQK_PI_A 0xe38 +#define RRX_IQK_PI_A 0xe3c + +#define RTX_IQK 0xe40 +#define RRX_IQK 0xe44 +#define RIQK_AGC_PTS 0xe48 +#define RIQK_AGC_RSP 0xe4c +#define RTX_IQK_TONE_B 0xe50 +#define RRX_IQK_TONE_B 0xe54 +#define RTX_IQK_PI_B 0xe58 +#define RRX_IQK_PI_B 0xe5c +#define RIQK_AGC_CONT 0xe60 + +#define RBLUE_TOOTH 0xe6c +#define RRX_WAIT_CCA 0xe70 +#define RTX_CCK_RFON 0xe74 +#define RTX_CCK_BBON 0xe78 +#define RTX_OFDM_RFON 0xe7c +#define RTX_OFDM_BBON 0xe80 +#define RTX_TO_RX 0xe84 +#define RTX_TO_TX 0xe88 +#define RRX_CCK 0xe8c + +#define RTX_POWER_BEFORE_IQK_A 0xe94 +#define RTX_POWER_AFTER_IQK_A 0xe9c + +#define RRX_POWER_BEFORE_IQK_A 0xea0 +#define RRX_POWER_BEFORE_IQK_A_2 0xea4 +#define RRX_POWER_AFTER_IQK_A 0xea8 +#define RRX_POWER_AFTER_IQK_A_2 0xeac + +#define RTX_POWER_BEFORE_IQK_B 0xeb4 +#define RTX_POWER_AFTER_IQK_B 0xebc + +#define RRX_POWER_BEFORE_IQK_B 0xec0 +#define RRX_POWER_BEFORE_IQK_B_2 0xec4 +#define RRX_POWER_AFTER_IQK_B 0xec8 +#define RRX_POWER_AFTER_IQK_B_2 0xecc + +#define MASK_IQK_RESULT 0x03ff0000 + +#define RRX_OFDM 0xed0 +#define RRX_WAIT_RIFS 0xed4 +#define RRX_TO_RX 0xed8 +#define RSTANDBY 0xedc +#define RSLEEP 0xee0 +#define RPMPD_ANAEN 0xeec + +/* RL6052 Register definition */ +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_TXPA_AG 0x0B +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define rfchannel 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 + +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 + +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +/* Bit Mask */ + +/* 2. Page8(0x800) */ +#define BRFMOD 0x1 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDRESSLENGTH 0x400 + +#define BRFSI_RFENV 0x10 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 +#define BLSSIREADBACKDATA 0xfffff +/* 4. PageA(0xA00) */ +#define BCCKSIDEBAND 0x10 + +/* Other Definition */ +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BDWORD 0xf + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c new file mode 100644 index 000000000..427d1877f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "def.h" +#include "reg.h" +#include "phy_common.h" +#include "rf_common.h" + +void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rfpath; + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] &= 0xfffff3ff; + rtlphy->rfreg_chnlval[rfpath] |= 0x0400; + + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, + BIT(10) | BIT(11), 0x01); + + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "20M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); + } + + break; + case HT_CHANNEL_WIDTH_20_40: + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] &= 0xfffff3ff; + + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, + BIT(10) | BIT(11), 0x00); + + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "40M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_bandwidth); + +void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = (rtlphy->mcs_offset[0][6]) + + (rtlphy->mcs_offset[0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + tmpval = (rtlphy->mcs_offset[0][14]) + + (rtlphy->mcs_offset[0][15] << 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *)(&tx_agc[idx1]); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); + tmpval = tx_agc[RF90_PATH_A] >> 8; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); +} +EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_cck_txpower); + +static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 powerbase0, powerbase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerbase0 = powerlevel[i] + legacy_pwrdiff; + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) | + (powerbase1 << 8) | powerbase1; + *(mcsbase + i) = powerbase1; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); + } +} + +static void _rtl92d_get_pwr_diff_limit(struct ieee80211_hw *hw, u8 channel, + u8 index, u8 rf, u8 pwr_diff_limit[4]) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 mcs_offset; + u8 limit; + int i; + + mcs_offset = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)]; + + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = (mcs_offset >> (i * 8)) & 0x7f; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) + limit = rtlefuse->pwrgroup_ht40[rf][channel - 1]; + else + limit = rtlefuse->pwrgroup_ht20[rf][channel - 1]; + + if (pwr_diff_limit[i] > limit) + pwr_diff_limit[i] = limit; + } +} + +static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 writeval = 0, customer_limit, rf; + u8 chnlgroup = 0, pwr_diff_limit[4]; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + writeval = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)]; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance\n"); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + + if (rtlphy->pwrgroup_cnt < MAX_PG_GROUP) + break; + + chnlgroup = rtl92d_phy_get_chnlgroup_bypg(channel - 1); + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + chnlgroup++; + else + chnlgroup += 4; + + writeval = rtlphy->mcs_offset + [chnlgroup][index + (rf ? 8 : 0)]; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz\n"); + break; + case 2: + writeval = 0; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "Better regulatory\n"); + break; + case 3: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf][channel - 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf][channel - 1]); + } + + _rtl92d_get_pwr_diff_limit(hw, channel, index, rf, + pwr_diff_limit); + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | + (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); + + writeval = customer_limit; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "Customer\n"); + break; + default: + writeval = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)]; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance\n"); + break; + } + + if (index < 2) + writeval += powerbase0[rf]; + else + writeval += powerbase1[rf]; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); + + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + static const u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + static const u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = pvalue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + writeval = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + for (i = 0; i < 3; i++) { + if (i != 2) + writeval = (writeval > 8) ? + (writeval - 8) : 0; + else + writeval = (writeval > 6) ? + (writeval - 6) : 0; + rtl_write_byte(rtlpriv, (u32)(regoffset + i), + (u8)writeval); + } + } + } +} + +void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + + _rtl92d_phy_get_power_base(hw, ppowerlevel, channel, + &powerbase0[0], &powerbase1[0]); + for (index = 0; index < 6; index++) { + _rtl92d_get_txpower_writeval_by_regulatory(hw, channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} +EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_ofdm_txpower); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h new file mode 100644 index 000000000..c243ec083 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_RF_COMMON_H__ +#define __RTL92D_RF_COMMON_H__ + +void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c new file mode 100644 index 000000000..9f9a34492 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c @@ -0,0 +1,516 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../stats.h" +#include "def.h" +#include "trx_common.h" + +static long _rtl92d_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +static void _rtl92d_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + __le32 *pdesc, + struct rx_fwinfo_92d *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct phy_sts_cck_8192d *cck_buf; + s8 rx_pwr_all, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck_rate; + u8 rxmcs; + + rxmcs = get_rx_desc_rxmcs(pdesc); + is_cck_rate = rxmcs <= DESC_RATE11M; + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; + pstats->rx_mimo_sig_qual[0] = -1; + pstats->rx_mimo_sig_qual[1] = -1; + + if (is_cck_rate) { + u8 report, cck_highpwr; + + cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo; + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = rtlphy->cck_high_power; + else + cck_highpwr = false; + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + /* CCK gain is smaller than OFDM/MCS gain, */ + /* so we add gain diff by experiences, the val is 6 */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same gain index with OFDM. */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + if (packet_match_bssid) { + u8 sq; + + if (pstats->rx_pwdb_all > 40) { + sq = 100; + } else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + pstats->signalquality = sq; + pstats->rx_mimo_sig_qual[0] = sq; + pstats->rx_mimo_sig_qual[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = true; + rtlpriv->dm.rfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) + - 110; + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8)rssi; + } + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + if (get_rx_desc_rxht(pdesc) && rxmcs >= DESC_RATEMCS8 && + rxmcs <= DESC_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + if (packet_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8)(evm & 0xff); + pstats->rx_mimo_sig_qual[i] = + (u8)(evm & 0xff); + } + } + } + if (is_cck_rate) + pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void rtl92d_loop_over_paths(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rfpath; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + } + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + } +} + +static void _rtl92d_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_smooth_data *ui_rssi; + u32 last_rssi, tmpval; + + if (!pstats->packet_toself && !pstats->packet_beacon) + return; + + ui_rssi = &rtlpriv->stats.ui_rssi; + + rtlpriv->stats.rssi_calculate_cnt++; + if (ui_rssi->total_num++ >= PHY_RSSI_SLID_WIN_MAX) { + ui_rssi->total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = ui_rssi->elements[ui_rssi->index]; + ui_rssi->total_val -= last_rssi; + } + ui_rssi->total_val += pstats->signalstrength; + ui_rssi->elements[ui_rssi->index++] = pstats->signalstrength; + if (ui_rssi->index >= PHY_RSSI_SLID_WIN_MAX) + ui_rssi->index = 0; + tmpval = ui_rssi->total_val / ui_rssi->total_num; + rtlpriv->stats.signal_strength = _rtl92d_translate_todbm(hw, (u8)tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + + if (!pstats->is_cck && pstats->packet_toself) + rtl92d_loop_over_paths(hw, pstats); +} + +static void _rtl92d_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * + 5 + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92d_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_AP) + return; + + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + + if (pstats->packet_toself || pstats->packet_beacon) { + if (undec_sm_pwdb < 0) + undec_sm_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32)undec_sm_pwdb) { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undec_sm_pwdb = undec_sm_pwdb + 1; + } else { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + _rtl92d_update_rxsignalstatistics(hw, pstats); + } +} + +static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int stream; + + for (stream = 0; stream < 2; stream++) { + if (pstats->rx_mimo_sig_qual[stream] != -1) { + if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { + rtlpriv->stats.rx_evm_percentage[stream] = + pstats->rx_mimo_sig_qual[stream]; + } + rtlpriv->stats.rx_evm_percentage[stream] = + ((rtlpriv->stats.rx_evm_percentage[stream] + * (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_sig_qual[stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } +} + +static void _rtl92d_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_smooth_data *ui_link_quality; + u32 last_evm, tmpval; + + if (pstats->signalquality == 0) + return; + if (!pstats->packet_toself && !pstats->packet_beacon) + return; + + ui_link_quality = &rtlpriv->stats.ui_link_quality; + + if (ui_link_quality->total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { + ui_link_quality->total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = ui_link_quality->elements[ui_link_quality->index]; + ui_link_quality->total_val -= last_evm; + } + ui_link_quality->total_val += pstats->signalquality; + ui_link_quality->elements[ui_link_quality->index++] = pstats->signalquality; + if (ui_link_quality->index >= PHY_LINKQUALITY_SLID_WIN_MAX) + ui_link_quality->index = 0; + tmpval = ui_link_quality->total_val / ui_link_quality->total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + rtl92d_loop_over_streams(hw, pstats); +} + +static void _rtl92d_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + if (!pcurrent_stats->packet_matchbssid && + !pcurrent_stats->packet_beacon) + return; + + _rtl92d_process_ui_rssi(hw, pcurrent_stats); + _rtl92d_process_pwdb(hw, pcurrent_stats); + _rtl92d_process_ui_link_quality(hw, pcurrent_stats); +} + +static void _rtl92d_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + __le32 *pdesc, + struct rx_fwinfo_92d *p_drvinfo) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + bool packet_matchbssid; + bool packet_beacon; + bool packet_toself; + u16 type, cfc; + u8 *tmp_buf; + u8 *praddr; + __le16 fc; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + cfc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + packet_matchbssid = ((type != IEEE80211_FTYPE_CTL) && + ether_addr_equal(mac->bssid, + (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + packet_toself = packet_matchbssid && + ether_addr_equal(praddr, rtlefuse->dev_addr); + packet_beacon = ieee80211_is_beacon(fc); + _rtl92d_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + _rtl92d_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92d_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + __le32 *pdesc = (__le32 *)pdesc8; + struct rx_fwinfo_92d *p_drvinfo; + u32 phystatus = get_rx_desc_physt(pdesc); + + stats->length = (u16)get_rx_desc_pkt_len(pdesc); + stats->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + stats->icv = (u16)get_rx_desc_icv(pdesc); + stats->crc = (u16)get_rx_desc_crc32(pdesc); + stats->hwerror = (stats->crc | stats->icv); + stats->decrypted = !get_rx_desc_swdec(pdesc) && + get_rx_desc_enc_type(pdesc) != RX_DESC_ENC_NONE; + stats->rate = (u8)get_rx_desc_rxmcs(pdesc); + stats->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + stats->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) && + (get_rx_desc_faggr(pdesc) == 1)); + stats->timestamp_low = get_rx_desc_tsfl(pdesc); + stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc); + stats->is_ht = (bool)get_rx_desc_rxht(pdesc); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + if (get_rx_desc_crc32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (get_rx_desc_bw(pdesc)) + rx_status->bw = RATE_INFO_BW_40; + if (get_rx_desc_rxht(pdesc)) + rx_status->encoding = RX_ENC_HT; + rx_status->flag |= RX_FLAG_MACTIME_START; + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht, + false, stats->rate); + rx_status->mactime = get_rx_desc_tsfl(pdesc); + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + + stats->rx_bufshift); + _rtl92d_translate_rx_signal_stuff(hw, skb, stats, pdesc, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->recvsignalpower + 10; + return true; +} +EXPORT_SYMBOL_GPL(rtl92d_rx_query_desc); + +void rtl92d_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx, + u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + wmb(); + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + wmb(); + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} +EXPORT_SYMBOL_GPL(rtl92d_set_desc); + +u64 rtl92d_get_desc(struct ieee80211_hw *hw, + u8 *p_desc8, bool istx, u8 desc_name) +{ + __le32 *p_desc = (__le32 *)p_desc8; + u32 ret = 0; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(p_desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(p_desc); + break; + default: + WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(p_desc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(p_desc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(p_desc); + break; + default: + WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} +EXPORT_SYMBOL_GPL(rtl92d_get_desc); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h new file mode 100644 index 000000000..528182b1e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_TRX_COMMON_H__ +#define __RTL92D_TRX_COMMON_H__ + +#define RX_DRV_INFO_SIZE_UNIT 8 + +enum rtl92d_rx_desc_enc { + RX_DESC_ENC_NONE = 0, + RX_DESC_ENC_WEP40 = 1, + RX_DESC_ENC_TKIP_WO_MIC = 2, + RX_DESC_ENC_TKIP_MIC = 3, + RX_DESC_ENC_AES = 4, + RX_DESC_ENC_WEP104 = 5, +}; + +/* macros to read/write various fields in RX or TX descriptors */ + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(5)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(7)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(30, 26)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16)); +} + +static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_qos(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(6)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(7)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(13)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(25)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(26)); +} + +static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(27)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(6)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 8) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 8)); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(13, 0)); +} + +static inline u32 get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(14)); +} + +static inline u32 get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(15)); +} + +static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(19, 16)); +} + +static inline u32 get_rx_desc_enc_type(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(22, 20)); +} + +static inline u32 get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(25, 24)); +} + +static inline u32 get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(26)); +} + +static inline u32 get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(27)); +} + +static inline u32 get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(14)); +} + +static inline u32 get_rx_desc_faggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0)); +} + +static inline u32 get_rx_desc_rxht(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(6)); +} + +static inline u32 get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(8)); +} + +static inline u32 get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(9)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 5)); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 6)); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +/* For 92D early mode */ +static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(2, 0)); +} + +static inline void set_earlymode_len0(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(15, 4)); +} + +static inline void set_earlymode_len1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(27, 16)); +} + +static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(31, 28)); +} + +static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(7, 0)); +} + +static inline void set_earlymode_len3(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8)); +} + +static inline void set_earlymode_len4(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20)); +} + +struct rx_fwinfo_92d { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; +#ifdef __LITTLE_ENDIAN + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +#else + u8 reserve:4; + u8 rxsc:2; + u8 sgi_en:1; + u8 ex_intf_flag:1; +#endif +} __packed; + +bool rtl92d_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92d_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); +u64 rtl92d_get_desc(struct ieee80211_hw *hw, + u8 *p_desc, bool istx, u8 desc_name); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile new file mode 100644 index 000000000..6482d823a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192de-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192DE) += rtl8192de.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c new file mode 100644 index 000000000..c6a2e8b22 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../core.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/fw_common.h" +#include "phy.h" +#include "dm.h" + +#define UNDEC_SM_PWDB entry_min_undec_sm_pwdb + +static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dynamic_txpower_enable = true; + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if ((!rtlpriv->dm.dynamic_txpower_enable) + || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = + rtlpriv->dm.UNDEC_SM_PWDB; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "IBSS Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = + rtlpriv->dm.UNDEC_SM_PWDB; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + if (rtlhal->current_bandtype == BAND_ON_5G) { + if (undec_sm_pwdb >= 0x33) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL2; + rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD, + "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); + } else if ((undec_sm_pwdb < 0x33) + && (undec_sm_pwdb >= 0x2b)) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD, + "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < 0x2b) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD, + "5G:TxHighPwrLevel_Normal\n"); + } + } else { + if (undec_sm_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL2; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); + } else + if ((undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) + && (undec_sm_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + } + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + } + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* AP & ADHOC & MESH will return tmp */ + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + /* Indicate Rx signal strength to FW. */ + if (rtlpriv->dm.useramask) { + u32 temp = rtlpriv->dm.undec_sm_pwdb; + + temp <<= 16; + temp |= 0x100; + /* fw v12 cmdid 5:use max macid ,for nic , + * default macid is 0 ,max macid is 1 */ + rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); + } else { + rtl_write_byte(rtlpriv, 0x4fe, + (u8) rtlpriv->dm.undec_sm_pwdb); + } +} + +void rtl92de_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl_dm_diginit(hw, 0x20); + rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER; + rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER; + rtl92d_dm_init_dynamic_txpower(hw); + rtl92d_dm_init_edca_turbo(hw); + rtl92d_dm_init_rate_adaptive_mask(hw); + rtl92d_dm_initialize_txpower_tracking(hw); +} + +void rtl92de_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fwps_awake = true; + + /* 1. RF is OFF. (No need to do DM.) + * 2. Fw is under power saving mode for FwLPS. + * (Prevent from SW/FW I/O racing.) + * 3. IPS workitem is scheduled. (Prevent from IPS sequence + * to be swapped with DM. + * 4. RFChangeInProgress is TRUE. + * (Prevent from broken by IPS/HW/SW Rf off.) */ + + if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && + fwps_awake) && (!ppsc->rfchange_inprogress)) { + rtl92d_dm_pwdb_monitor(hw); + rtl92d_dm_false_alarm_counter_statistics(hw); + rtl92d_dm_find_minimum_rssi(hw); + rtl92d_dm_dig(hw); + /* rtl92d_dm_dynamic_bb_powersaving(hw); */ + rtl92d_dm_dynamic_txpower(hw); + /* rtl92d_dm_check_txpower_tracking_thermal_meter(hw); */ + /* rtl92d_dm_refresh_rate_adaptive_mask(hw); */ + /* rtl92d_dm_interrupt_migration(hw); */ + rtl92d_dm_check_edca_turbo(hw); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h new file mode 100644 index 000000000..beade227b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_DM_H__ +#define __RTL92C_DM_H__ + +void rtl92de_dm_init(struct ieee80211_hw *hw); +void rtl92de_dm_watchdog(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c new file mode 100644 index 000000000..c8444a72f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../efuse.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/fw_common.h" +#include "fw.h" +#include "sw.h" + +int rtl92d_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192d version = rtlhal->version; + u8 value; + u32 count; + bool fw_downloaded = false, fwdl_in_process = false; + unsigned long flags; + + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) + return 1; + fwsize = rtlhal->fwsize; + pfwheader = rtlhal->pfirmware; + pfwdata = rtlhal->pfirmware; + rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); + rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); + if (IS_FW_HEADER_EXIST(pfwheader)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Shift 32 bytes for FW header!!\n"); + pfwdata = pfwdata + 32; + fwsize = fwsize - 32; + } + + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv); + if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) + fwdl_in_process = true; + else + fwdl_in_process = false; + if (fw_downloaded) { + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + goto exit; + } else if (fwdl_in_process) { + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + for (count = 0; count < 5000; count++) { + udelay(500); + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv); + if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) + fwdl_in_process = true; + else + fwdl_in_process = false; + spin_unlock_irqrestore(&globalmutex_for_fwdownload, + flags); + if (fw_downloaded) + goto exit; + else if (!fwdl_in_process) + break; + else + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Wait for another mac download fw\n"); + } + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + value = rtl_read_byte(rtlpriv, 0x1f); + value |= BIT(5); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + } else { + value = rtl_read_byte(rtlpriv, 0x1f); + value |= BIT(5); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + } + + /* If 8051 is running in RAM code, driver should + * inform Fw to reset by itself, or it will cause + * download Fw fail.*/ + /* 8051 RAM code */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl92d_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + } + rtl92d_enable_fw_download(hw, true); + rtl92d_write_fw(hw, version, pfwdata, fwsize); + rtl92d_enable_fw_download(hw, false); + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + err = rtl92d_fw_free_to_go(hw); + /* download fw over,clear 0x1f[5] */ + value = rtl_read_byte(rtlpriv, 0x1f); + value &= (~BIT(5)); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + if (err) + pr_err("fw is not ready to run!\n"); +exit: + err = rtl92d_fw_init(hw); + return err; +} + +static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 idx = 0; + unsigned long flags; + struct sk_buff *pskb; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + pskb = __skb_dequeue(&ring->queue); + kfree_skb(pskb); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + pdesc = &ring->desc[idx]; + /* discard output from call below */ + rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN); + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb); + __skb_queue_tail(&ring->queue, skb); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + return true; +} + +#define BEACON_PG 0 /*->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5 */ +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[3] = { PROBERSP_PG, PSPOLL_PG, NULL_PG }; + bool dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", + u1rsvdpageloc, 3); + skb = dev_alloc_skb(totalpacketlen); + if (!skb) { + dlok = false; + } else { + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + rtstatus = _rtl92d_cmd_send_packet(hw, skb); + + if (rtstatus) + dlok = true; + } + if (dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE", u1rsvdpageloc, 3); + rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!\n"); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h new file mode 100644 index 000000000..9e1385ac1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D__FW__H__ +#define __RTL92D__FW__H__ + +int rtl92d_download_fw(struct ieee80211_hw *hw); +void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c new file mode 100644 index 000000000..03f4314bd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -0,0 +1,1087 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/fw_common.h" +#include "../rtl8192d/hw_common.h" +#include "../rtl8192d/phy_common.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "sw.h" +#include "hw.h" + +u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 value; + + rtl_write_word(rtlpriv, REG_DBI_CTRL, (offset & 0xFFC)); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(1) | direct); + udelay(10); + value = rtl_read_dword(rtlpriv, REG_DBI_RDATA); + return value; +} + +void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, + u16 offset, u32 value, u8 direct) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_DBI_CTRL, ((offset & 0xFFC) | 0xF000)); + rtl_write_dword(rtlpriv, REG_DBI_WDATA, value); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(0) | direct); +} + +static void _rtl92de_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92de_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92de_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92de_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *) (val)) = rtlpci->receive_config; + break; + default: + rtl92d_get_hw_reg(hw, variable, val); + break; + } +} + +void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_AC_PARAM: { + u8 e_aci = *val; + rtl92d_dm_init_edca_turbo(hw); + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + &e_aci); + break; + } + case HW_VAR_ACM_CTRL: { + u8 e_aci = *val; + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + pr_err("switch case %#x not processed\n", + e_aci); + break; + } + } + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR: + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + case HW_VAR_H2C_FW_JOINBSSRPT: { + u8 mstatus = (*val); + u8 tmp_regcr, tmp_reg422; + bool recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AID, NULL); + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); + tmp_reg422 = rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + rtl92d_set_fw_rsvdpagepkt(hw, 0); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); + if (recover) + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl92d_set_fw_joinbss_report_cmd(hw, (*val)); + break; + } + case HW_VAR_CORRECT_TSF: { + u8 btype_ibss = val[0]; + + if (btype_ibss) + rtl92d_stop_tx_beacon(hw); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32) & 0xffffffff)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); + if (btype_ibss) + rtl92d_resume_tx_beacon(hw); + + break; + } + case HW_VAR_INT_MIGRATION: { + bool int_migration = *(bool *) (val); + + if (int_migration) { + /* Set interrupt migration timer and + * corresponding Tx/Rx counter. + * timer 25ns*0xfa0=100us for 0xf packets. + * 0x306:Rx, 0x307:Tx */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0xfe000fa0); + rtlpriv->dm.interrupt_migration = int_migration; + } else { + /* Reset all interrupt migration settings. */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + rtlpriv->dm.interrupt_migration = int_migration; + } + break; + } + case HW_VAR_INT_AC: { + bool disable_ac_int = *((bool *) val); + + /* Disable four ACs interrupts. */ + if (disable_ac_int) { + /* Disable VO, VI, BE and BK four AC interrupts + * to gain more efficient CPU utilization. + * When extremely highly Rx OK occurs, + * we will disable Tx interrupts. + */ + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + RT_AC_INT_MASKS); + rtlpriv->dm.disable_tx_int = disable_ac_int; + /* Enable four ACs interrupts. */ + } else { + rtlpriv->cfg->ops->update_interrupt_mask(hw, + RT_AC_INT_MASKS, 0); + rtlpriv->dm.disable_tx_int = disable_ac_int; + } + break; + } + default: + rtl92d_set_hw_reg(hw, variable, val); + break; + } +} + +static bool _rtl92de_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxpage; + bool status; + u32 value32; /* High+low page number */ + u8 value8; /* normal page number */ + + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { + maxpage = 255; + txpktbuf_bndy = 246; + value8 = 0; + value32 = 0x80bf0d29; + } else { + maxpage = 127; + txpktbuf_bndy = 123; + value8 = 0; + value32 = 0x80750005; + } + + /* Set reserved page for each queue */ + /* 11. RQPN 0x200[31:0] = 0x80BD1C1C */ + /* load RQPN */ + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); + rtl_write_dword(rtlpriv, REG_RQPN, value32); + + /* 12. TXRKTBUG_PG_BNDY 0x114[31:0] = 0x27FF00F6 */ + /* TXRKTBUG_PG_BNDY */ + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, + (rtl_read_word(rtlpriv, REG_TRXFF_BNDY + 2) << 16 | + txpktbuf_bndy)); + + /* 13. TDECTRL[15:8] 0x209[7:0] = 0xF6 */ + /* Beacon Head for TXDMA */ + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + /* 14. BCNQ_PGBNDY 0x424[7:0] = 0xF6 */ + /* BCNQ_PGBNDY */ + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + /* 15. WMAC_LBK_BF_HD 0x45D[7:0] = 0xF6 */ + /* WMAC_LBK_BF_HD */ + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + + /* Set Tx/Rx page size (Tx must be 128 Bytes, */ + /* Rx can be 64,128,256,512,1024 bytes) */ + /* 16. PBP [7:0] = 0x11 */ + /* TRX page size */ + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + + /* 17. DRV_INFO_SZ = 0x04 */ + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + /* 18. LLT_table_init(Adapter); */ + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = rtl92d_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + /* end of list */ + status = rtl92d_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + /* Make the other pages as ring buffer */ + /* This ring buffer is used as beacon buffer if we */ + /* config this MAC as two MAC transfer. */ + /* Otherwise used as local loopback buffer. */ + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = rtl92d_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + /* Let last entry point to the start entry of ring buffer */ + status = rtl92d_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + return true; +} + +static void _rtl92de_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpci->up_first_time) + return; + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92de_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92de_sw_led_on(hw, pin0); + else + rtl92de_sw_led_off(hw, pin0); +} + +static bool _rtl92de_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry; + + rtl92d_phy_set_poweron(hw); + /* Add for resume sequence of power domain according + * to power document V11. Chapter V.11.... */ + /* 0. RSV_CTRL 0x1C[7:0] = 0x00 */ + /* unlock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x05); + + /* 1. AFE_XTAL_CTRL [7:0] = 0x0F enable XTAL */ + /* 2. SPS0_CTRL 0x11[7:0] = 0x2b enable SPS into PWM mode */ + /* 3. delay (1ms) this is not necessary when initially power on */ + + /* C. Resume Sequence */ + /* a. SPS0_CTRL 0x11[7:0] = 0x2b */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + + /* b. AFE_XTAL_CTRL [7:0] = 0x0F */ + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); + + /* c. DRV runs power on init flow */ + + /* auto enable WLAN */ + /* 4. APS_FSMCO 0x04[8] = 1; wait till 0x04[8] = 0 */ + /* Power On Reset for MAC Block */ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); + udelay(2); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + udelay(2); + + /* 5. Wait while 0x04[8] == 0 goto 2, otherwise goto 1 */ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(50); + retry = 0; + while ((bytetmp & BIT(0)) && retry < 1000) { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(50); + } + + /* Enable Radio off, GPIO, and LED function */ + /* 6. APS_FSMCO 0x04[15:0] = 0x0012 when enable HWPDN */ + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); + + /* release RF digital isolation */ + /* 7. SYS_ISO_CTRL 0x01[1] = 0x0; */ + /*Set REG_SYS_ISO_CTRL 0x1=0x82 to prevent wake# problem. */ + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); + udelay(2); + + /* make sure that BB reset OK. */ + /* rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); */ + + /* Disable REG_CR before enable it to assure reset */ + rtl_write_word(rtlpriv, REG_CR, 0x0); + + /* Release MAC IO register reset */ + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + /* clear stopping tx/rx dma */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x0); + + /* rtl_write_word(rtlpriv,REG_CR+2, 0x2); */ + + /* System init */ + /* 18. LLT_table_init(Adapter); */ + if (!_rtl92de_llt_table_init(hw)) + return false; + + /* Clear interrupt and enable interrupt */ + /* 19. HISR 0x124[31:0] = 0xffffffff; */ + /* HISRE 0x12C[7:0] = 0xFF */ + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + /* 20. HIMR 0x120[31:0] |= [enable INT mask bit map]; */ + /* 21. HIMRE 0x128[7:0] = [enable INT mask bit map] */ + /* The IMR should be enabled later after all init sequence + * is finished. */ + + /* 22. PCIE configuration space configuration */ + /* 23. Ensure PCIe Device 0x80[15:0] = 0x0143 (ASPM+CLKREQ), */ + /* and PCIe gated clock function is enabled. */ + /* PCIE configuration space will be written after + * all init sequence.(Or by BIOS) */ + + rtl92d_phy_config_maccoexist_rfpage(hw); + + /* THe below section is not related to power document Vxx . */ + /* This is only useful for driver and OS setting. */ + /* -------------------Software Relative Setting---------------------- */ + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + /* Reported Tx status from HW for rate adaptive. */ + /* This should be realtive to power on step 14. But in document V11 */ + /* still not contain the description.!!! */ + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + + /* Set Tx/Rx page size (Tx must be 128 Bytes, + * Rx can be 64,128,256,512,1024 bytes) */ + /* rtl_write_byte(rtlpriv,REG_PBP, 0x11); */ + + /* Set RCR register */ + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + /* rtl_write_byte(rtlpriv,REG_RX_DRVINFO_SZ, 4); */ + + /* Set TCR register */ + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + /* disable earlymode */ + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + /* Set TX/RX descriptor physical address(from OS API). */ + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + rtlpci->tx_ring[BEACON_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, rtlpci->tx_ring[MGNT_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, rtlpci->tx_ring[VO_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, rtlpci->tx_ring[VI_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, rtlpci->tx_ring[BE_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, rtlpci->tx_ring[BK_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_HQ_DESA, rtlpci->tx_ring[HIGH_QUEUE].dma); + /* Set RX Desc Address */ + rtl_write_dword(rtlpriv, REG_RX_DESA, + rtlpci->rx_ring[RX_MPDU_QUEUE].dma); + + /* if we want to support 64 bit DMA, we should set it here, + * but now we do not support 64 bit DMA*/ + + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x33); + + /* Reset interrupt migration setting when initialization */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + /* Reconsider when to do this operation after asking HWSD. */ + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && !(bytetmp & BIT(7))); + + /* After MACIO reset,we must refresh LED state. */ + _rtl92de_gen_refresh_led_state(hw); + + /* Reset H2C protection register */ + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true; +} + +static void _rtl92de_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 reg_bw_opmode = BW_OPMODE_20MHZ; + u32 reg_rrsr; + + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + rtl_write_word(rtlpriv, REG_RL, 0x0707); + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + /* Aggregation threshold */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb9726641); + else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66626641); + else + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + /* For throughput */ + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x6666); + /* ACKTO for IOT issue. */ + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + /* Set Spec SIFS (used in NAV) */ + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + /* Set SIFS for CCK */ + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + /* Set SIFS for OFDM */ + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + /* Set Multicast Address. */ + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + switch (rtlpriv->phy.rf_type) { + case RF_1T2R: + case RF_1T1R: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); + break; + case RF_2T2R: + case RF_2T2R_GREEN: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); + break; + } +} + +static void _rtl92de_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + if (ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +int rtl92de_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool rtstatus = true; + u8 tmp_u1b; + int i; + int err; + unsigned long flags; + + rtlpci->being_init_adapter = true; + rtlpci->init_ready = false; + spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags); + /* we should do iqk after disable/enable */ + rtl92d_phy_reset_iqk_result(hw); + /* rtlpriv->intf_ops->disable_aspm(hw); */ + rtstatus = _rtl92de_init_mac(hw); + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); + return err; + } + err = rtl92d_download_fw(hw); + spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW..\n"); + return 1; + } + rtlhal->last_hmeboxnum = 0; + rtlpriv->psc.fw_current_inpsmode = false; + + tmp_u1b = rtl_read_byte(rtlpriv, 0x605); + tmp_u1b = tmp_u1b | 0x30; + rtl_write_byte(rtlpriv, 0x605, tmp_u1b); + + if (rtlhal->earlymode_enable) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EarlyMode Enabled!!!\n"); + + tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); + tmp_u1b = tmp_u1b | 0x1f; + rtl_write_byte(rtlpriv, 0x4d0, tmp_u1b); + + rtl_write_byte(rtlpriv, 0x4d3, 0x80); + + tmp_u1b = rtl_read_byte(rtlpriv, 0x605); + tmp_u1b = tmp_u1b | 0x40; + rtl_write_byte(rtlpriv, 0x605, tmp_u1b); + } + + if (mac->rdg_en) { + rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff); + rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); + rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); + } + + rtl92d_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + + rtl92d_phy_bb_config(hw); + + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + /* set before initialize RF */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + + /* config RF */ + rtl92d_phy_rf_config(hw); + + /* After read predefined TXT, we must set BB/MAC/RF + * register as our requirement */ + /* After load BB,RF params,we need do more for 92D. */ + rtl92d_update_bbrf_configuration(hw); + /* set default value after initialize RF, */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + + /*---- Set CCK and OFDM Block "ON"----*/ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + if (rtlhal->interfaceindex == 0) { + /* RFPGA0_ANALOGPARAMETER2: cck clock select, + * set to 20MHz by default */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 3); + } else { + /* Mac1 */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(11) | + BIT(10), 3); + } + + _rtl92de_hw_configure(hw); + + /* reset hw sec */ + rtl_cam_reset_all_entry(hw); + rtl92d_enable_hw_security_config(hw); + + /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ + /* TX power index for different rate set. */ + rtl92d_phy_get_hw_reg_originalvalue(hw); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + + _rtl92de_enable_aspm_back_door(hw); + /* rtlpriv->intf_ops->enable_aspm(hw); */ + + rtl92de_dm_init(hw); + rtlpci->being_init_adapter = false; + + if (ppsc->rfpwr_state == ERFON) { + rtl92d_phy_lc_calibrate(hw, IS_92D_SINGLEPHY(rtlhal->version)); + /* 5G and 2.4G must wait sometime to let RF LO ready */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + u32 tmp_rega; + for (i = 0; i < 10000; i++) { + udelay(MAX_STALL_TIME); + + tmp_rega = rtl_get_rfreg(hw, + (enum radio_path)RF90_PATH_A, + 0x2a, MASKDWORD); + + if (((tmp_rega & BIT(11)) == BIT(11))) + break; + } + /* check that loop was successful. If not, exit now */ + if (i == 10000) { + rtlpci->init_ready = false; + return 1; + } + } + } + rtlpci->init_ready = true; + return err; +} + +static int _rtl92de_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + + bt_msr &= 0xfc; + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + rtl92d_stop_tx_beacon(hw); + _rtl92de_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || + type == NL80211_IFTYPE_AP) { + rtl92d_resume_tx_beacon(hw); + _rtl92de_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); + } + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not supported!\n", type); + return 1; + } + rtl_write_byte(rtlpriv, MSR, bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & MSR_MASK) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92de_set_media_status(hw, type)) + return -EOPNOTSUPP; + + /* check bssid */ + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92de_set_check_bssid(hw, true); + } else { + rtl92de_set_check_bssid(hw, false); + } + return 0; +} + +/* do iqk or reload iqk */ +/* windows just rtl92d_phy_reload_iqk_setting in set channel, + * but it's very strict for time sequence so we add + * rtl92d_phy_reload_iqk_setting here */ +void rtl92d_linked_set_reg(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 indexforchannel; + u8 channel = rtlphy->current_channel; + + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) { + rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, + "Do IQK for channel:%d\n", channel); + rtl92d_phy_iq_calibrate(hw); + } +} + +void rtl92de_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92de_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + rtlpci->irq_enabled = false; +} + +static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1b_tmp; + unsigned long flags; + + rtlpriv->intf_ops->enable_aspm(hw); + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(15), 0); + + /* 0x20:value 05-->04 */ + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); + + /* ==== Reset digital sequence ====== */ + rtl92d_firmware_selfreset(hw); + + /* f. SYS_FUNC_EN 0x03[7:0]=0x51 reset MCU, MAC register, DCORE */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); + + /* g. MCUFWDL 0x80[1:0]=0 reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + + /* h. GPIO_PIN_CTRL 0x44[31:0]=0x000 */ + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); + + /* i. Value = GPIO_PIN_CTRL[7:0] */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); + + /* j. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); */ + /* write external PIN level */ + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, + 0x00FF0000 | (u1b_tmp << 8)); + + /* k. GPIO_MUXCFG 0x42 [15:0] = 0x0780 */ + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); + + /* l. LEDCFG 0x4C[15:0] = 0x8080 */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); + + /* ==== Disable analog sequence === */ + + /* m. AFE_PLL_CTRL[7:0] = 0x80 disable PLL */ + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + + /* n. SPS0_CTRL 0x11[7:0] = 0x22 enter PFM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + + /* o. AFE_XTAL_CTRL 0x24[7:0] = 0x0E disable XTAL, if No BT COEX */ + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); + + /* p. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + + /* ==== interface into suspend === */ + + /* q. APS_FSMCO[15:8] = 0x58 PCIe suspend mode */ + /* According to power document V11, we need to set this */ + /* value as 0x18. Otherwise, we may not L0s sometimes. */ + /* This indluences power consumption. Bases on SD1's test, */ + /* set as 0x00 do not affect power current. And if it */ + /* is set as 0x18, they had ever met auto load fail problem. */ + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "In PowerOff,reg0x%x=%X\n", + REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); + /* r. Note: for PCIe interface, PON will not turn */ + /* off m-bias and BandGap in PCIe suspend mode. */ + + /* 0x17[7] 1b': power off in process 0b' : power off over */ + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + spin_lock_irqsave(&globalmutex_power, flags); + u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1b_tmp &= (~BIT(7)); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp); + spin_unlock_irqrestore(&globalmutex_power, flags); + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); +} + +void rtl92de_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92de_set_media_status(hw, opmode); + + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + /* Power sequence for each MAC. */ + /* a. stop tx DMA */ + /* b. close RF */ + /* c. clear rx buf */ + /* d. stop rx DMA */ + /* e. reset MAC */ + + /* a. stop tx DMA */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE); + udelay(50); + + /* b. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ + + /* c. ========RF OFF sequence========== */ + /* 0x88c[23:20] = 0xf. */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + + /* APSD_CTRL 0x600[7:0] = 0x40 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + + /* Close antenna 0,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0); + + /* SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB state machine */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + + /* Mac0 can not do Global reset. Mac1 can do. */ + /* SYS_FUNC_EN 0x02[7:0] = 0xE0 reset BB state machine */ + if (rtlpriv->rtlhal.interfaceindex == 1) + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); + udelay(50); + + /* d. stop tx/rx dma before disable REG_CR (0x100) to fix */ + /* dma hang issue when disable/enable device. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); + udelay(50); + rtl_write_byte(rtlpriv, REG_CR, 0x0); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); + if (rtl92d_phy_check_poweroff(hw)) + _rtl92de_poweroff_adapter(hw); + return; +} + +void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); +} + +void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; + rtl92de_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30); + else + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20); + rtl_write_byte(rtlpriv, 0x606, 0x30); +} + +void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl92de_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl92de_enable_interrupt(hw); +} + +void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92de_disable_interrupt(hw); + rtl92de_enable_interrupt(hw); +} + +void rtl92de_suspend(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->rtlhal.macphyctl_reg = rtl_read_byte(rtlpriv, + REG_MAC_PHY_CTRL_NORMAL); +} + +void rtl92de_resume(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL, + rtlpriv->rtlhal.macphyctl_reg); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h new file mode 100644 index 000000000..bda4a1a7c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92DE_HW_H__ +#define __RTL92DE_HW_H__ + +void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl92de_hw_init(struct ieee80211_hw *hw); +void rtl92de_card_disable(struct ieee80211_hw *hw); +void rtl92de_enable_interrupt(struct ieee80211_hw *hw); +void rtl92de_disable_interrupt(struct ieee80211_hw *hw); +int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92de_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); + +void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value, + u8 direct); +u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct); +void rtl92de_suspend(struct ieee80211_hw *hw); +void rtl92de_resume(struct ieee80211_hw *hw); +void rtl92d_linked_set_reg(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c new file mode 100644 index 000000000..33aede56c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../rtl8192d/reg.h" +#include "led.h" + +void rtl92de_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + if ((rtlpriv->efuse.eeprom_did == 0x8176) || + (rtlpriv->efuse.eeprom_did == 0x8193)) + /* BIT7 of REG_LEDCFG2 should be set to + * make sure we could emit the led2. */ + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | + BIT(7) | BIT(5) | BIT(6)); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | + BIT(7) | BIT(5)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl92de_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92de_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl92de_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); + + _rtl92ce_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h new file mode 100644 index 000000000..33e544ad6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl92de_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92de_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c new file mode 100644 index 000000000..68f890050 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c @@ -0,0 +1,2726 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../core.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/rf_common.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" +#include "sw.h" +#include "hw.h" + +#define MAX_RF_IMR_INDEX 12 +#define MAX_RF_IMR_INDEX_NORMAL 13 +#define RF_REG_NUM_FOR_C_CUT_5G 6 +#define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA 7 +#define RF_REG_NUM_FOR_C_CUT_2G 5 +#define RF_CHNL_NUM_5G 19 +#define RF_CHNL_NUM_5G_40M 17 + +static u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = { + 0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0 +}; + +static u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6 +}; + +static u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8 +}; + +static u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + 0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E +}; + +static u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1), + BIT(10) | BIT(9), + BIT(18) | BIT(17) | BIT(16) | BIT(1), + BIT(2) | BIT(1), + BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) +}; + +static u8 rf_chnl_5g[RF_CHNL_NUM_5G] = { + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, 136, 140 +}; + +static u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = { + 38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114, + 118, 122, 126, 130, 134, 138 +}; +static u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = { + {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04}, + {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04} +}; + +static u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = { + {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840}, + {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840}, + {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41} +}; + +static u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF; + +static u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12} +}; + +/* [mode][patha+b][reg] */ +static u32 rf_imr_param_normal[1][3][MAX_RF_IMR_INDEX_NORMAL] = { + { + /* channel 1-14. */ + { + 0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff + }, + /* path 36-64 */ + { + 0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000, + 0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090, + 0x32c9a + }, + /* 100 -165 */ + { + 0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000, + 0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a + } + } +}; + +static u32 curveindex_5g[TARGET_CHNL_NUM_5G] = {0}; + +static u32 curveindex_2g[TARGET_CHNL_NUM_2G] = {0}; + +static u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = { + 25141, 25116, 25091, 25066, 25041, + 25016, 24991, 24966, 24941, 24917, + 24892, 24867, 24843, 24818, 24794, + 24770, 24765, 24721, 24697, 24672, + 24648, 24624, 24600, 24576, 24552, + 24528, 24504, 24480, 24457, 24433, + 24409, 24385, 24362, 24338, 24315, + 24291, 24268, 24245, 24221, 24198, + 24175, 24151, 24128, 24105, 24082, + 24059, 24036, 24013, 23990, 23967, + 23945, 23922, 23899, 23876, 23854, + 23831, 23809, 23786, 23764, 23741, + 23719, 23697, 23674, 23652, 23630, + 23608, 23586, 23564, 23541, 23519, + 23498, 23476, 23454, 23432, 23410, + 23388, 23367, 23345, 23323, 23302, + 23280, 23259, 23237, 23216, 23194, + 23173, 23152, 23130, 23109, 23088, + 23067, 23046, 23025, 23003, 22982, + 22962, 22941, 22920, 22899, 22878, + 22857, 22837, 22816, 22795, 22775, + 22754, 22733, 22713, 22692, 22672, + 22652, 22631, 22611, 22591, 22570, + 22550, 22530, 22510, 22490, 22469, + 22449, 22429, 22409, 22390, 22370, + 22350, 22336, 22310, 22290, 22271, + 22251, 22231, 22212, 22192, 22173, + 22153, 22134, 22114, 22095, 22075, + 22056, 22037, 22017, 21998, 21979, + 21960, 21941, 21921, 21902, 21883, + 21864, 21845, 21826, 21807, 21789, + 21770, 21751, 21732, 21713, 21695, + 21676, 21657, 21639, 21620, 21602, + 21583, 21565, 21546, 21528, 21509, + 21491, 21473, 21454, 21436, 21418, + 21400, 21381, 21363, 21345, 21327, + 21309, 21291, 21273, 21255, 21237, + 21219, 21201, 21183, 21166, 21148, + 21130, 21112, 21095, 21077, 21059, + 21042, 21024, 21007, 20989, 20972, + 25679, 25653, 25627, 25601, 25575, + 25549, 25523, 25497, 25471, 25446, + 25420, 25394, 25369, 25343, 25318, + 25292, 25267, 25242, 25216, 25191, + 25166 +}; + +/* channel 1~14 */ +static u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = { + 26084, 26030, 25976, 25923, 25869, 25816, 25764, + 25711, 25658, 25606, 25554, 25502, 25451, 25328 +}; + +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { + u8 dbi_direct = 0; + + /* mac1 use phy0 read radio_b. */ + /* mac0 use phy1 read radio_b. */ + if (rtlhal->during_mac1init_radioa) + dbi_direct = BIT(3); + else if (rtlhal->during_mac0init_radiob) + dbi_direct = BIT(3) | BIT(2); + originalvalue = rtl92de_read_dword_dbi(hw, (u16)regaddr, + dbi_direct); + } else { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + } + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + return returnvalue; +} + +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 dbi_direct = 0; + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + if (rtlhal->during_mac1init_radioa) + dbi_direct = BIT(3); + else if (rtlhal->during_mac0init_radiob) + /* mac0 use phy1 write radio_b. */ + dbi_direct = BIT(3) | BIT(2); + if (bitmask != MASKDWORD) { + if (rtlhal->during_mac1init_radioa || + rtlhal->during_mac0init_radiob) + originalvalue = rtl92de_read_dword_dbi(hw, + (u16) regaddr, + dbi_direct); + else + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) + rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct); + else + rtl_write_dword(rtlpriv, regaddr, data); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} + +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = rtl8192de_mac_2tarray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n"); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { + /* improve 2-stream TX EVM */ + /* rtl_write_byte(rtlpriv, 0x14,0x71); */ + /* AMPDU aggregation number 9 */ + /* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B); + } else { + /* 92D need to test to decide the num. */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07); + } + return true; +} + +static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table = NULL; + u32 *agctab_5garray_table; + u16 phy_reg_arraylen, agctab_arraylen = 0, agctab_5garraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /* Normal chip,Mac0 use AGC_TAB.txt for 2G and 5G band. */ + if (rtlhal->interfaceindex == 0) { + agctab_arraylen = AGCTAB_ARRAYLENGTH; + agctab_array_table = rtl8192de_agctab_array; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC0, Rtl819XAGCTAB_Array\n"); + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; + agctab_array_table = rtl8192de_agctab_2garray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"); + } else { + agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH; + agctab_5garray_table = rtl8192de_agctab_5garray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"); + + } + } + phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; + phy_regarray_table = rtl8192de_phy_reg_2tarray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:Rtl819XPHY_REG_Array_PG\n"); + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + rtl_addr_delay(phy_regarray_table[i]); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + if (rtlhal->interfaceindex == 0) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], + MASKDWORD, + agctab_array_table[i + 1]); + /* Add 1us delay between BB/RF register + * setting. */ + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The Rtl819XAGCTAB_Array_Table[0] is %u Rtl819XPHY_REGArray[1] is %u\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n"); + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], + MASKDWORD, + agctab_array_table[i + 1]); + /* Add 1us delay between BB/RF register + * setting. */ + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The Rtl819XAGCTAB_Array_Table[0] is %u Rtl819XPHY_REGArray[1] is %u\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Load Rtl819XAGCTAB_2GArray\n"); + } else { + for (i = 0; i < agctab_5garraylen; i = i + 2) { + rtl_set_bbreg(hw, + agctab_5garray_table[i], + MASKDWORD, + agctab_5garray_table[i + 1]); + /* Add 1us delay between BB/RF registeri + * setting. */ + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The Rtl819XAGCTAB_5GArray_Table[0] is %u Rtl819XPHY_REGArray[1] is %u\n", + agctab_5garray_table[i], + agctab_5garray_table[i + 1]); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Load Rtl819XAGCTAB_5GArray\n"); + } + } + } + return true; +} + +static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH; + phy_regarray_table_pg = rtl8192de_phy_reg_array_pg; + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + rtl_addr_delay(phy_regarray_table_pg[i]); + rtl92d_store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); + rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + + /* if (rtlphy->rf_type == RF_1T2R) { + * _rtl92c_phy_bb_config_1t(hw); + * rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); + *} */ + + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, 0x200)); + + return true; +} + +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regvaldw; + u8 value; + + rtl92d_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */ + value = rtl_read_byte(rtlpriv, REG_RF_CTRL); + rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB | + RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA | + FEN_DIO_PCIE | FEN_BB_GLB_RSTN | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))) { + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + } + + return _rtl92d_phy_bb_config(hw); +} + +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92d_phy_rf6052_config(hw); +} + +bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath) +{ + int i; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + radioa_arraylen = RADIOA_2T_ARRAYLENGTH; + radioa_array_table = rtl8192de_radioa_2tarray; + radiob_arraylen = RADIOB_2T_ARRAYLENGTH; + radiob_array_table = rtl8192de_radiob_2tarray; + if (rtlpriv->efuse.internal_pa_5g[0]) { + radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH; + radioa_array_table = rtl8192de_radioa_2t_int_paarray; + } + if (rtlpriv->efuse.internal_pa_5g[1]) { + radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH; + radiob_array_table = rtl8192de_radiob_2t_int_paarray; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); + + /* this only happens when DMDP, mac0 start on 2.4G, + * mac1 start on 5G, mac 0 has to set phy0&phy1 + * pathA or mac1 has to set phy0&phy1 pathA */ + if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> although Path A, we load radiob.txt\n"); + radioa_arraylen = radiob_arraylen; + radioa_array_table = radiob_array_table; + } + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + } + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + } + break; + case RF90_PATH_C: + case RF90_PATH_D: + pr_err("switch case %#x not processed\n", rfpath); + break; + } + return true; +} + +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + unsigned long flag = 0; + u8 reg_prsr_rsc; + u8 reg_bw_opmode; + + if (rtlphy->set_bwmode_inprogress) + return; + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "FALSE driver sleep or unload\n"); + return; + } + rtlphy->set_bwmode_inprogress = true; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + reg_prsr_rsc = (reg_prsr_rsc & 0x90) | + (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 3); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + /* Set Control channel to upper or lower. + * These settings are required only for 40MHz */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + + } + rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); +} + +static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x00); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0); +} + +static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 value8; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); + rtlhal->bandset = band; + rtlhal->current_bandtype = band; + if (IS_92D_SINGLEPHY(rtlhal->version)) + rtlhal->bandset = BAND_ON_BOTH; + /* stop RX/Tx */ + _rtl92d_phy_stop_trx_before_changeband(hw); + /* reconfig BB/RF according to wireless mode */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* BB & RF Config */ + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n"); + if (rtlhal->interfaceindex == 1) + _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + } else { + /* 5G band */ + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n"); + if (rtlhal->interfaceindex == 1) + _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + } + rtl92d_update_bbrf_configuration(hw); + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + /* 20M BW. */ + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */ + rtlhal->reloadtxpowerindex = true; + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1)); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1), value8); + } else { + value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1)); + value8 &= (~BIT(1)); + rtl_write_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1), value8); + } + mdelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n"); +} + +static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, + u8 channel, u8 rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 imr_num = MAX_RF_IMR_INDEX; + u32 rfmask = RFREG_OFFSET_MASK; + u8 group, i; + unsigned long flag = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + /* fc area 0xd2c */ + if (channel > 99) + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 2); + else + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 1); + /* leave 0 for channel1-14. */ + group = channel <= 64 ? 1 : 2; + imr_num = MAX_RF_IMR_INDEX_NORMAL; + for (i = 0; i < imr_num; i++) + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], rfmask, + rf_imr_param_normal[0][group][i]); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 1); + } else { + /* G band. */ + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Load RF IMR parameters for G band. IMR already setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); + if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Load RF IMR parameters for G band. %d\n", + rfpath); + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0xf); + imr_num = MAX_RF_IMR_INDEX_NORMAL; + for (i = 0; i < imr_num; i++) { + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], + RFREG_OFFSET_MASK, + rf_imr_param_normal[0][0][i]); + } + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN | BCCKEN, 3); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 path = rtlhal->current_bandtype == + BAND_ON_5G ? RF90_PATH_A : RF90_PATH_B; + u8 index = 0, i = 0, rfpath = RF90_PATH_A; + bool need_pwr_down = false, internal_pa = false; + u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n"); + /* config path A for 5G */ + if (rtlhal->current_bandtype == BAND_ON_5G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); + u4tmp = curveindex_5g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); + for (i = 0; i < RF_CHNL_NUM_5G; i++) { + if (channel == rf_chnl_5g[i] && channel <= 140) + index = 0; + } + for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) { + if (channel == rf_chnl_5g_40m[i] && channel <= 140) + index = 1; + } + if (channel == 149 || channel == 155 || channel == 161) + index = 2; + else if (channel == 151 || channel == 153 || channel == 163 + || channel == 165) + index = 3; + else if (channel == 157 || channel == 159) + index = 4; + + if (rtlhal->macphymode == DUALMAC_DUALPHY + && rtlhal->interfaceindex == 1) { + need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false); + rtlhal->during_mac1init_radioa = true; + /* assume no this case */ + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) { + if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, 0xE439D); + } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) { + u4tmp2 = (rf_reg_pram_c_5g[index][i] & + 0x7FF) | (u4tmp << 11); + if (channel == 36) + u4tmp2 &= ~(BIT(7) | BIT(6)); + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, u4tmp2); + } else { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, + rf_reg_pram_c_5g[index][i]); + } + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "offset 0x%x value 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], + path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK)); + } + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + if (rtlhal->during_mac1init_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + if (channel < 149) + value = 0x07; + else if (channel >= 149) + value = 0x02; + if (channel >= 36 && channel <= 64) + index = 0; + else if (channel >= 100 && channel <= 140) + index = 1; + else + index = 2; + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) /* MAC 1 5G */ + internal_pa = rtlpriv->efuse.internal_pa_5g[1]; + else + internal_pa = + rtlpriv->efuse.internal_pa_5g[rfpath]; + if (internal_pa) { + for (i = 0; + i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA; + i++) { + rtl_set_rfreg(hw, rfpath, + rf_for_c_cut_5g_internal_pa[i], + RFREG_OFFSET_MASK, + rf_pram_c_5g_int_pa[index][i]); + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "offset 0x%x value 0x%x path %d index %d\n", + rf_for_c_cut_5g_internal_pa[i], + rf_pram_c_5g_int_pa[index][i], + rfpath, index); + } + } else { + rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, + mask, value); + } + } + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); + u4tmp = curveindex_2g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); + if (channel == 1 || channel == 2 || channel == 4 || channel == 9 + || channel == 10 || channel == 11 || channel == 12) + index = 0; + else if (channel == 3 || channel == 13 || channel == 14) + index = 1; + else if (channel >= 5 && channel <= 8) + index = 2; + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + path = RF90_PATH_A; + if (rtlhal->interfaceindex == 0) { + need_pwr_down = + rtl92d_phy_enable_anotherphy(hw, true); + rtlhal->during_mac0init_radiob = true; + + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + } + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) { + if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7) + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK, + (rf_reg_param_for_c_cut_2g[index][i] | + BIT(17))); + else + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK, + rf_reg_param_for_c_cut_2g + [index][i]); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK)); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); + + rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, + RFREG_OFFSET_MASK, + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + if (rtlhal->during_mac0init_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 regeac, rege94, rege9c, regea4; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + } else { + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c22); + } + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160206); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160206); + } + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path A LOK & IQK\n", + IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); + rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); + regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); + if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && + (((rege9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & BIT(27)) && (((regea4 & 0x03FF0000) >> 16) != 0x132) && + (((regeac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, + bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 regeac, rege94, rege9c, regea4; + u8 result = 0; + u8 i; + u8 retrycount = 2; + u32 TXOKBIT = BIT(28), RXOKBIT = BIT(27); + + if (rtlhal->interfaceindex == 1) { /* PHY1 */ + TXOKBIT = BIT(31); + RXOKBIT = BIT(30); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140307); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68160960); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68110000); + } + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); + /* path-A PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x07000f60); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, 0x66e60e30); + for (i = 0; i < retrycount; i++) { + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME * 10); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); + rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); + regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); + if (!(regeac & TXOKBIT) && + (((rege94 & 0x03FF0000) >> 16) != 0x142)) { + result |= 0x01; + } else { /* if Tx not OK, ignore Rx */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A Tx IQK fail!!\n"); + continue; + } + + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & RXOKBIT) && + (((regea4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A Rx IQK fail!!\n"); + } + } + /* path A PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, + rtlphy->iqk_bb_backup[1]); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 regeac, regeb4, regebc, regec4, regecc; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); + /* One shot, path B LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); + regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); + regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); + regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); + if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && + (((regebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + if (!(regeac & BIT(30)) && (((regec4 & 0x03FF0000) >> 16) != 0x132) && + (((regecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 regeac, regeb4, regebc, regec4, regecc; + u8 result = 0; + u8 i; + u8 retrycount = 2; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68110000); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140307); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68160960); + + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); + + /* path-B PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x0f600700); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, 0x061f0d30); + + for (i = 0; i < retrycount; i++) { + /* One shot, path B LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path B LOK & IQK.\n", 10); + mdelay(IQK_DELAY_TIME * 10); + + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); + regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); + regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); + regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); + if (!(regeac & BIT(31)) && + (((regeb4 & 0x03FF0000) >> 16) != 0x142)) + result |= 0x01; + else + continue; + if (!(regeac & BIT(30)) && + (((regec4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Rx IQK fail!!\n"); + } + } + + /* path B PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, + rtlphy->iqk_bb_backup[2]); + return result; +} + +static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *adda_reg, u32 *adda_backup, + u32 regnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Reload ADDA power saving parameters !\n"); + for (i = 0; i < regnum; i++) + rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, adda_backup[i]); +} + +static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n"); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_byte(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 mode; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], + u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + static u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + static u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + const u32 retrycount = 2; + u32 bbvalue; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); + + /* Save ADDA parameters, turn Path A ADDA on */ + rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + } + rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, true); + + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22204000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + if (is2t) { + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, + 0x00010000); + rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, MASKDWORD, + 0x00010000); + } + /* MAC settings */ + rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /* Page B init */ + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000); + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Success!!\n"); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Only Tx Success!!\n"); + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + if (0x00 == patha_ok) + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n"); + if (is2t) { + _rtl92d_phy_patha_standby(hw); + /* Turn Path B ADDA on */ + rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92d_phy_pathb_iqk(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, + MASKDWORD) & 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, + MASKDWORD) & 0x3FF0000) >> 16; + result[t][6] = (rtl_get_bbreg(hw, 0xec4, + MASKDWORD) & 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xecc, + MASKDWORD) & 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Only Tx IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, + MASKDWORD) & 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, + MASKDWORD) & 0x3FF0000) >> 16; + } + } + if (0x00 == pathb_ok) + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK failed!!\n"); + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Back to BB mode, load original value!\n"); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + if (t != 0) { + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, false); + /* Reload ADDA power saving parameters */ + _rtl92d_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, IQK_ADDA_REG_NUM); + /* Reload MAC parameters */ + _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (is2t) + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + /* load 0xe30 IQC default value */ + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); +} + +static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, + long result[][8], u8 t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 patha_ok, pathb_ok; + static u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + static u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + u32 bbvalue; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + + /* Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt */ + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); + mdelay(IQK_DELAY_TIME * 20); + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); + /* Save ADDA parameters, turn Path A ADDA on */ + rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (is2t) + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + } + rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t); + /* MAC settings */ + rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (t == 0) + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, true); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + + /* Page B init */ + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000); + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x10007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + } else if (patha_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Only Tx Success!!\n"); + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); + } + if (is2t) { + /* _rtl92d_phy_patha_standby(hw); */ + /* Turn Path B ADDA on */ + rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + } else if (pathb_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Only Tx IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK failed!!\n"); + } + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Back to BB mode, load original value!\n"); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + if (t != 0) { + if (is2t) + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + /* Reload MAC parameters */ + _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, false); + /* Reload ADDA power saving parameters */ + _rtl92d_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); +} + +static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 i, j, diff, sim_bitmap, bound; + u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ + bool bresult = true; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + sim_bitmap = 0; + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - + result[c2][i]) : (result[c2][i] - result[c1][i]); + if (diff > MAX_TOLERANCE_92D) { + if ((i == 2 || i == 6) && !sim_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + sim_bitmap = sim_bitmap | (1 << i); + } else { + sim_bitmap = sim_bitmap | (1 << i); + } + } + } + if (sim_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } + if (!(sim_bitmap & 0x0F)) { /* path A OK */ + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */ + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + return false; +} + +static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 oldval_0, val_x, tx0_a, reg; + long val_y, tx0_c; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version) || + rtlhal->macphymode == DUALMAC_DUALPHY; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */ + val_x = result[final_candidate][0]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + tx0_a = (val_x * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n", + val_x, tx0_a, oldval_0); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + ((val_x * oldval_0 >> 7) & 0x1)); + val_y = result[final_candidate][1]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + /* path B IQK result + 3 */ + if (rtlhal->interfaceindex == 1 && + rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + tx0_c = (val_y * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + if (is2t) + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), + ((val_y * oldval_0 >> 7) & 0x1)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD)); + if (txonly) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); + return; + } + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 oldval_1, val_x, tx1_a, reg; + long val_y, tx1_c; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n", + iqk_ok ? "Success" : "Failed"); + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + val_x = result[final_candidate][4]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + tx1_a = (val_x * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), + ((val_x * oldval_1 >> 7) & 0x1)); + val_y = result[final_candidate][5]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + if (rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + tx1_c = (val_y * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30), + ((val_y * oldval_1 >> 7) & 0x1)); + if (txonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + long result[4][8]; + u8 i, final_candidate, indexforchannel; + bool patha_ok, pathb_ok; + long rege94, rege9c, regea4, regeac, regeb4; + long regebc, regec4, regecc, regtmp = 0; + bool is12simular, is13simular, is23simular; + unsigned long flag = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Start!!!channel %d\n", rtlphy->current_channel); + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + patha_ok = false; + pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK !!!currentband %d\n", rtlhal->current_bandtype); + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + for (i = 0; i < 3; i++) { + if (rtlhal->current_bandtype == BAND_ON_5G) { + _rtl92d_phy_iq_calibrate_5g_normal(hw, result, i); + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (IS_92D_SINGLEPHY(rtlhal->version)) + _rtl92d_phy_iq_calibrate(hw, result, i, true); + else + _rtl92d_phy_iq_calibrate(hw, result, i, false); + } + if (i == 1) { + is12simular = _rtl92d_phy_simularity_compare(hw, result, + 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92d_phy_simularity_compare(hw, result, + 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92d_phy_simularity_compare(hw, result, + 1, 2); + if (is23simular) { + final_candidate = 1; + } else { + for (i = 0; i < 8; i++) + regtmp += result[3][i]; + + if (regtmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + for (i = 0; i < 4; i++) { + rege94 = result[i][0]; + rege9c = result[i][1]; + regea4 = result[i][2]; + regeac = result[i][3]; + regeb4 = result[i][4]; + regebc = result[i][5]; + regec4 = result[i][6]; + regecc = result[i][7]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc); + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = rege94 = result[final_candidate][0]; + rtlphy->reg_e9c = rege9c = result[final_candidate][1]; + regea4 = result[final_candidate][2]; + regeac = result[final_candidate][3]; + rtlphy->reg_eb4 = regeb4 = result[final_candidate][4]; + rtlphy->reg_ebc = regebc = result[final_candidate][5]; + regec4 = result[final_candidate][6]; + regecc = result[final_candidate][7]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: final_candidate is %x\n", final_candidate); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc); + patha_ok = pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */ + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; /* Y default value */ + } + if ((rege94 != 0) /*&&(regea4 != 0) */) + _rtl92d_phy_patha_fill_iqk_matrix(hw, patha_ok, result, + final_candidate, (regea4 == 0)); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + if ((regeb4 != 0) /*&&(regec4 != 0) */) + _rtl92d_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result, + final_candidate, (regec4 == 0)); + } + if (final_candidate != 0xFF) { + indexforchannel = rtl92d_get_rightchnlplace_for_iqk( + rtlphy->current_channel); + + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix[indexforchannel]. + value[0][i] = result[final_candidate][i]; + rtlphy->iqk_matrix[indexforchannel].iqk_done = + true; + + rtl_dbg(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, + "IQK OK indexforchannel %d\n", indexforchannel); + } +} + +void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 indexforchannel; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel); + /*------Do IQK for normal chip and test chip 5G band------- */ + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", + indexforchannel, + rtlphy->iqk_matrix[indexforchannel].iqk_done); + if (0 && !rtlphy->iqk_matrix[indexforchannel].iqk_done && + rtlphy->need_iqk) { + /* Re Do IQK. */ + rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, + "Do IQK Matrix reg for channel:%d....\n", channel); + rtl92d_phy_iq_calibrate(hw); + } else { + /* Just load the value. */ + /* 2G band just load once. */ + if (((!rtlhal->load_imrandiqk_setting_for2g) && + indexforchannel == 0) || indexforchannel > 0) { + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Just Read IQK Matrix reg for channel:%d....\n", + channel); + if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0) + _rtl92d_phy_patha_fill_iqk_matrix(hw, true, + rtlphy->iqk_matrix[indexforchannel].value, 0, + rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + if ((rtlphy->iqk_matrix[ + indexforchannel].value[0][4] != 0) + /*&&(regec4 != 0) */) + _rtl92d_phy_pathb_fill_iqk_matrix(hw, + true, + rtlphy->iqk_matrix[ + indexforchannel].value, 0, + (rtlphy->iqk_matrix[ + indexforchannel].value[0][6] + == 0)); + } + } + } + rtlphy->need_iqk = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 erfpath = rtlpriv->rtlhal.current_bandtype == + BAND_ON_5G ? RF90_PATH_A : + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version) ? + RF90_PATH_B : RF90_PATH_A; + u32 u4tmp = 0, u4regvalue = 0; + bool bneed_powerdown_radio = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n", + rtlpriv->rtlhal.current_bandtype); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ + u4tmp = curveindex_5g[channel-1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 1) { + bneed_powerdown_radio = + rtl92d_phy_enable_anotherphy(hw, false); + rtlpriv->rtlhal.during_mac1init_radioa = true; + /* assume no this case */ + if (bneed_powerdown_radio) + rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + if (bneed_powerdown_radio) + rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + if (rtlpriv->rtlhal.during_mac1init_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { + u4tmp = curveindex_2g[channel-1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 0) { + bneed_powerdown_radio = + rtl92d_phy_enable_anotherphy(hw, true); + rtlpriv->rtlhal.during_mac0init_radiob = true; + if (bneed_powerdown_radio) + rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); + if (bneed_powerdown_radio) + rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + if (rtlpriv->rtlhal.during_mac0init_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tmpreg, index, rf_mode[2]; + u8 path = is2t ? 2 : 1; + u8 i; + u32 u4tmp, offset; + u32 curvecount_val[CV_CURVE_CNT * 2] = {0}; + u16 timeout = 800, timecount = 0; + + /* Check continuous TX and Packet TX */ + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + /* if Deal with contisuous TX case, disable all continuous TX */ + /* if Deal with Packet TX case, block all queues */ + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F); + for (index = 0; index < path; index++) { + /* 1. Read original RF mode */ + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rf_mode[index] = rtl_read_byte(rtlpriv, offset); + /* 2. Set RF mode = standby mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_AC, + RFREG_OFFSET_MASK, 0x010000); + if (rtlpci->init_ready) { + /* switch CV-curve control by LC-calibration */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x0); + /* 4. Set LC calibration begin */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x01); + } + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6, + RFREG_OFFSET_MASK); + while ((!(u4tmp & BIT(11))) && timecount <= timeout) { + mdelay(50); + timecount += 50; + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, + RF_SYN_G6, RFREG_OFFSET_MASK); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "PHY_LCK finish delay for %d ms=2\n", timecount); + rtl_get_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK); + if (index == 0 && rtlhal->interfaceindex == 0) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "path-A / 5G LCK\n"); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "path-B / 2.4G LCK\n"); + } + memset(curvecount_val, 0, sizeof(curvecount_val)); + /* Set LC calibration off */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x0); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n"); + /* save Curve-counting number */ + for (i = 0; i < CV_CURVE_CNT; i++) { + u32 readval = 0, readval2 = 0; + rtl_set_rfreg(hw, (enum radio_path)index, 0x3F, + 0x7f, i); + + rtl_set_rfreg(hw, (enum radio_path)index, 0x4D, + RFREG_OFFSET_MASK, 0x0); + readval = rtl_get_rfreg(hw, (enum radio_path)index, + 0x4F, RFREG_OFFSET_MASK); + curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5; + /* reg 0x4f [4:0] */ + /* reg 0x50 [19:10] */ + readval2 = rtl_get_rfreg(hw, (enum radio_path)index, + 0x50, 0xffc00); + curvecount_val[2 * i] = (((readval & 0x1F) << 10) | + readval2); + } + if (index == 0 && rtlhal->interfaceindex == 0) + rtl92d_phy_calc_curvindex(hw, targetchnl_5g, + curvecount_val, + true, curveindex_5g); + else + rtl92d_phy_calc_curvindex(hw, targetchnl_2g, + curvecount_val, + false, curveindex_2g); + /* switch CV-curve control mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x1); + } + + /* Restore original situation */ + for (index = 0; index < path; index++) { + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rtl_write_byte(rtlpriv, offset, 0x50); + rtl_write_byte(rtlpriv, offset, rf_mode[index]); + } + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + else /*Deal with Packet TX case */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00); + _rtl92d_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel); +} + +static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n"); + _rtl92d_phy_lc_calibrate_sw(hw, is2t); +} + +void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); + + _rtl92d_phy_lc_calibrate(hw, is2t); + + rtlphy->lck_inprogress = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n"); +} + +static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8192de: cmdtable cannot be NULL\n"); + return false; + } + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + postcommoncmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + rfdependcmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 0); + _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, + 0, 0, 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + } + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92d_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xffffff00) | currentcmd->para2); + if (rtlpriv->rtlhal.current_bandtype == + BAND_ON_5G) { + if (currentcmd->para2 > 99) + rtlphy->rfreg_chnlval[rfpath] = + rtlphy->rfreg_chnlval + [rfpath] | (BIT(18)); + else + rtlphy->rfreg_chnlval[rfpath] = + rtlphy->rfreg_chnlval + [rfpath] & (~BIT(18)); + rtlphy->rfreg_chnlval[rfpath] |= + (BIT(16) | BIT(8)); + } else { + rtlphy->rfreg_chnlval[rfpath] &= + ~(BIT(8) | BIT(16) | BIT(18)); + } + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + _rtl92d_phy_reload_imr_setting(hw, channel, + rfpath); + } + _rtl92d_phy_switch_rf_setting(hw, channel); + /* do IQK when all parameters are ready */ + rtl92d_phy_reload_iqk_setting(hw, channel); + break; + default: + pr_err("switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + break; + } while (true); + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 delay; + u32 timeout = 1000, timecount = 0; + u8 channel = rtlphy->current_channel; + u32 ret_value; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + return 0; + } + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && + rtlhal->bandset == BAND_ON_BOTH) { + ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + MASKDWORD); + if (rtlphy->current_channel > 14 && !(ret_value & BIT(0))) + rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G); + else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0))) + rtl92d_phy_switch_wirelessband(hw, BAND_ON_2_4G); + } + switch (rtlhal->current_bandtype) { + case BAND_ON_5G: + /* Get first channel error when change between + * 5G and 2.4G band. */ + if (WARN_ONCE(channel <= 14, "rtl8192de: 5G but channel<=14\n")) + return 0; + break; + case BAND_ON_2_4G: + /* Get first channel error when change between + * 5G and 2.4G band. */ + if (WARN_ONCE(channel > 14, "rtl8192de: 2G but channel>14\n")) + return 0; + break; + default: + WARN_ONCE(true, "rtl8192de: Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode); + break; + } + rtlphy->sw_chnl_inprogress = true; + if (channel == 0) + channel = 1; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92d_phy_sw_chnl_step_by_step(hw, + rtlphy->current_channel, + &rtlphy->sw_chnl_stage, &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +static void _rtl92d_phy_set_rfon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* a. SYS_CLKR 0x08[11] = 1 restore MAC clock */ + /* b. SPS_CTRL 0x11[7:0] = 0x2b */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + /* c. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /* RF_ON_EXCEP(d~g): */ + /* d. APSD_CTRL 0x600[7:0] = 0x00 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + /* e. SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function again */ + /* f. SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function*/ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /* g. txpause 0x522[7:0] = 0x00 enable mac tx queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 u4btmp; + u8 delay = 5; + + /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + /* b. RF path 0 offset 0x00 = 0x00 disable RF */ + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + /* c. APSD_CTRL 0x600[7:0] = 0x40 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + /* d. APSD_CTRL 0x600[7:0] = 0x00 + * APSD_CTRL 0x600[7:0] = 0x00 + * RF path 0 offset 0x00 = 0x00 + * APSD_CTRL 0x600[7:0] = 0x40 + * */ + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4btmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + /* Jump out the LPS turn off sequence to RF_ON_EXCEP */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Fail !!! Switch RF timeout\n"); + return; + } + /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + /* f. SPS_CTRL 0x11[7:0] = 0x22 */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); + /* g. SYS_CLKR 0x08[11] = 0 gated MAC clock */ +} + +bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + + bool bresult = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + if (rfpwr_state == ppsc->rfpwr_state) + return false; + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "awake, slept:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_awake_jiffies = jiffies; + _rtl92d_phy_set_rfon(hw); + } + + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + break; + case ERFOFF: + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + return false; + + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else if (rtlpci->pdev->current_state != PCI_D0) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", + i + 1, queue_id); + break; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "Set rfsleep awakened:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awakened:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_sleep_jiffies = jiffies; + _rtl92d_phy_set_rfsleep(hw); + break; + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +void rtl92d_phy_set_poweron(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flags; + u8 value8; + u16 i; + u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1); + + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, mac_reg, value8); + } else { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 &= (~BIT(1)); + rtl_write_byte(rtlpriv, mac_reg, value8); + } + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + spin_lock_irqsave(&globalmutex_power, flags); + if (rtlhal->interfaceindex == 0) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + value8 = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON); + } + value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + spin_unlock_irqrestore(&globalmutex_power, flags); + for (i = 0; i < 200; i++) { + if ((value8 & BIT(7)) == 0) { + break; + } else { + udelay(500); + spin_lock_irqsave(&globalmutex_power, flags); + value8 = rtl_read_byte(rtlpriv, + REG_POWER_OFF_IN_PROCESS); + spin_unlock_irqrestore(&globalmutex_power, + flags); + } + } + if (i == 200) + WARN_ONCE(true, "rtl8192de: Another mac power off over time\n"); + } +} + +void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rfpath, i; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); + /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* r_select_5G for path_A/B,0x878 */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0); + } + /* rssi_table_select:index 0 for 2.4G.1~3 for 5G,0xc78 */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0); + /* fc_area 0xd2c */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0); + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa); + /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */ + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, + 0x40000100); + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4) | + ((rtlefuse->eeprom_c9 & BIT(7)) << 9) | + ((rtlefuse->eeprom_c9 & BIT(5)) << 12) | + ((rtlefuse->eeprom_cc & BIT(3)) << 18)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) | + ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) | + ((rtlefuse->eeprom_cc & BIT(2)) << 3)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), 0); + } + /* 1.5V_LDO */ + } else { + /* r_select_5G for path_A/B */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1); + } + /* rssi_table_select:index 0 for 2.4G.1~3 for 5G */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1); + /* fc_area */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1); + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0); + /* TX BB gain shift,Just for testchip,0xc80,0xc88 */ + if (rtlefuse->internal_pa_5g[0]) + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + 0x20000080); + if (rtlefuse->internal_pa_5g[1]) + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, + 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, + 0x20000080); + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5))); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), + (rtlefuse->eeprom_cc & BIT(4)) >> 4); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5)) | + ((rtlefuse->eeprom_cc & BIT(7)) << 14)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(6)) >> 6)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4) | + ((rtlefuse->eeprom_cc & BIT(6)) << 10)); + } + } + /* update IQK related settings */ + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) | + BIT(26) | BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, 0xca0, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00); + + /* Update RF */ + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* MOD_AG for RF path_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) | + BIT(18), 0); + /* RF0x0b[16:14] =3b'111 */ + rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, + 0x1c000, 0x07); + } else { + /* MOD_AG for RF path_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | + BIT(16) | BIT(18), + (BIT(16) | BIT(8)) >> 8); + } + } + /* Update for all band. */ + /* DMDP */ + if (rtlphy->rf_type == RF_1T1R) { + /* Use antenna 0,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x11); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1); + + /* enable ad/da clock1 for dual-phy reg0x888 */ + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | + BIT(13), 0x3); + } else { + rtl92d_phy_enable_anotherphy(hw, false); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MAC1 use DBI to update 0x888\n"); + /* 0x888 */ + rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN, + rtl92de_read_dword_dbi(hw, + RFPGA0_ADDALLOCKEN, + BIT(3)) | BIT(12) | BIT(13), + BIT(3)); + rtl92d_phy_powerdown_anotherphy(hw, false); + } + } else { + /* Single PHY */ + /* Use antenna 0 & 1,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3); + /* disable ad/da clock1,0x888 */ + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0); + } + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C, + RFREG_OFFSET_MASK); + } + for (i = 0; i < 2; i++) + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i]); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n"); + +} + +bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1btmp; + unsigned long flags; + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON)); + return true; + } + spin_lock_irqsave(&globalmutex_power, flags); + if (rtlhal->interfaceindex == 0) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON)); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + u1btmp &= MAC1_ON; + } else { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & (~MAC1_ON)); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + u1btmp &= MAC0_ON; + } + if (u1btmp) { + spin_unlock_irqrestore(&globalmutex_power, flags); + return false; + } + u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1btmp |= BIT(7); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp); + spin_unlock_irqrestore(&globalmutex_power, flags); + return true; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h new file mode 100644 index 000000000..a9bfe54f2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_PHY_H__ +#define __RTL92D_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNA_DIVERSITY_VALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_test 6 +#define IQK_MAC_REG_NUM 4 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); +bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath); +bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +void rtl92d_phy_set_poweron(struct ieee80211_hw *hw); +bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw); +void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw); +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw); +void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c new file mode 100644 index 000000000..494b2706a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/phy_common.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "hw.h" + +bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 u1btmp; + u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; + bool bresult = true; /* true: need to enable BB/RF power */ + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); + /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); + /* Enable BB and RF power */ + rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL, + rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) | + BIT(29) | BIT(16) | BIT(17), direct); + } else { + /* We think if MAC1 is ON,then radio_a.txt + * and radio_b.txt has been load. */ + bresult = false; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); + return bresult; + +} + +void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 u1btmp; + u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); + /* check MAC0 enable or not again now, if + * enabled, not power down radio A. */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); + /* power down RF radio A according to YuNan's advice. */ + rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER, + 0x00000000, direct); + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); +} + +bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool rtstatus = true; + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 u4_regvalue = 0; + u8 rfpath; + struct bb_reg_def *pphyreg; + bool mac1_initradioa_first = false, mac0_initradiob_first = false; + bool need_pwrdown_radioa = false, need_pwrdown_radiob = false; + bool true_bpath = false; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + /* Single phy mode: use radio_a radio_b config path_A path_B */ + /* separately by MAC0, and MAC1 needn't configure RF; */ + /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */ + /* MAC1 use radio_b config 2nd PHY path_A. */ + /* DMDP,MAC0 on G band,MAC1 on A band. */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + if (rtlhal->current_bandtype == BAND_ON_2_4G && + rtlhal->interfaceindex == 0) { + /* MAC0 needs PHY1 load radio_b.txt. + * Driver use DBI to write. */ + if (rtl92d_phy_enable_anotherphy(hw, true)) { + rtlphy->num_total_rfpath = 2; + mac0_initradiob_first = true; + } else { + /* We think if MAC1 is ON,then radio_a.txt and + * radio_b.txt has been load. */ + return rtstatus; + } + } else if (rtlhal->current_bandtype == BAND_ON_5G && + rtlhal->interfaceindex == 1) { + /* MAC1 needs PHY0 load radio_a.txt. + * Driver use DBI to write. */ + if (rtl92d_phy_enable_anotherphy(hw, false)) { + rtlphy->num_total_rfpath = 2; + mac1_initradioa_first = true; + } else { + /* We think if MAC0 is ON,then radio_a.txt and + * radio_b.txt has been load. */ + return rtstatus; + } + } else if (rtlhal->interfaceindex == 1) { + /* MAC0 enabled, only init radia B. */ + true_bpath = true; + } + } + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + /* Mac1 use PHY0 write */ + if (mac1_initradioa_first) { + if (rfpath == RF90_PATH_A) { + rtlhal->during_mac1init_radioa = true; + need_pwrdown_radioa = true; + } else if (rfpath == RF90_PATH_B) { + rtlhal->during_mac1init_radioa = false; + mac1_initradioa_first = false; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } else if (mac0_initradiob_first) { + /* Mac0 use PHY1 write */ + if (rfpath == RF90_PATH_A) + rtlhal->during_mac0init_radiob = false; + if (rfpath == RF90_PATH_B) { + rtlhal->during_mac0init_radiob = true; + mac0_initradiob_first = false; + need_pwrdown_radiob = true; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } + pphyreg = &rtlphy->phyreg_def[rfpath]; + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + /* Set bit number of Address and Data for RF register */ + /* Set 1 to 4 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDRESSLENGTH, 0x0); + udelay(1); + /* Set 0 to 12 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + switch (rfpath) { + case RF90_PATH_A: + if (true_bpath) + rtstatus = rtl92d_phy_config_rf_with_headerfile( + hw, radiob_txt, + (enum radio_path)rfpath); + else + rtstatus = rtl92d_phy_config_rf_with_headerfile( + hw, radioa_txt, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = + rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, + u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, + u4_regvalue); + break; + } + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + goto phy_rf_cfg_fail; + } + + } + + /* check MAC0 enable or not again, if enabled, + * not power down radio A. */ + /* check MAC1 enable or not again, if enabled, + * not power down radio B. */ + if (need_pwrdown_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + else if (need_pwrdown_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); + return rtstatus; + +phy_rf_cfg_fail: + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h new file mode 100644 index 000000000..c097d90cc --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92D_RF_H__ +#define __RTL92D_RF_H__ + +bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c new file mode 100644 index 000000000..7612c22a9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "../base.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/hw_common.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/trx_common.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "sw.h" +#include "trx.h" +#include "led.h" + +#include + +static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + * */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) +{ + int err; + u8 tid; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + char *fw_name = "rtlwifi/rtl8192defw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpriv->dm.useramask = true; + + /* dual mac */ + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtlpriv->phy.current_channel = 36; + else + rtlpriv->phy.current_channel = 1; + + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + rtlpriv->rtlhal.disable_amsdu_8k = true; + /* No long RX - reduce fragmentation */ + rtlpci->rxbuffersize = 4096; + } + + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + rtlpci->receive_config = ( + RCR_APPFCS + | RCR_AMF + | RCR_ADF + | RCR_APP_MIC + | RCR_APP_ICV + | RCR_AICV + | RCR_ACRC32 + | RCR_AB + | RCR_AM + | RCR_APM + | RCR_APP_PHYST_RXFF + | RCR_HTC_LOC_CTRL + ); + + rtlpci->irq_mask[0] = (u32) ( + IMR_ROK + | IMR_VODOK + | IMR_VIDOK + | IMR_BEDOK + | IMR_BKDOK + | IMR_MGNTDOK + | IMR_HIGHDOK + | IMR_BDOK + | IMR_RDU + | IMR_RXFOVW + ); + + rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("FW Power Save off (module option)\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 */ + rtl92d_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw\n"); + return 1; + } + + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); + pr_info("Loading firmware file %s\n", fw_name); + + /* request fw */ + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + return 0; +} + +static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tid; + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } + for (tid = 0; tid < 8; tid++) + skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]); +} + +static const struct rtl_hal_ops rtl8192de_hal_ops = { + .init_sw_vars = rtl92d_init_sw_vars, + .deinit_sw_vars = rtl92d_deinit_sw_vars, + .read_eeprom_info = rtl92d_read_eeprom_info, + .interrupt_recognized = rtl92de_interrupt_recognized, + .hw_init = rtl92de_hw_init, + .hw_disable = rtl92de_card_disable, + .hw_suspend = rtl92de_suspend, + .hw_resume = rtl92de_resume, + .enable_interrupt = rtl92de_enable_interrupt, + .disable_interrupt = rtl92de_disable_interrupt, + .set_network_type = rtl92de_set_network_type, + .set_chk_bssid = rtl92de_set_check_bssid, + .set_qos = rtl92d_set_qos, + .set_bcn_reg = rtl92de_set_beacon_related_registers, + .set_bcn_intv = rtl92de_set_beacon_interval, + .update_interrupt_mask = rtl92de_update_interrupt_mask, + .get_hw_reg = rtl92de_get_hw_reg, + .set_hw_reg = rtl92de_set_hw_reg, + .update_rate_tbl = rtl92d_update_hal_rate_tbl, + .fill_tx_desc = rtl92de_tx_fill_desc, + .fill_tx_cmddesc = rtl92de_tx_fill_cmddesc, + .query_rx_desc = rtl92d_rx_query_desc, + .set_channel_access = rtl92d_update_channel_access_setting, + .radio_onoff_checking = rtl92d_gpio_radio_on_off_checking, + .set_bw_mode = rtl92d_phy_set_bw_mode, + .switch_channel = rtl92d_phy_sw_chnl, + .dm_watchdog = rtl92de_dm_watchdog, + .scan_operation_backup = rtl_phy_scan_operation_backup, + .set_rf_power_state = rtl92d_phy_set_rf_power_state, + .led_control = rtl92de_led_control, + .set_desc = rtl92d_set_desc, + .get_desc = rtl92d_get_desc, + .is_tx_desc_closed = rtl92de_is_tx_desc_closed, + .tx_polling = rtl92de_tx_polling, + .enable_hw_sec = rtl92d_enable_hw_security_config, + .set_key = rtl92d_set_key, + .get_bbreg = rtl92d_phy_query_bb_reg, + .set_bbreg = rtl92d_phy_set_bb_reg, + .get_rfreg = rtl92d_phy_query_rf_reg, + .set_rfreg = rtl92d_phy_set_rf_reg, + .linked_set_reg = rtl92d_linked_set_reg, + .get_btc_status = rtl_btc_status_false, + .phy_iq_calibrate = rtl92d_phy_iq_calibrate, + .phy_lc_calibrate = rtl92d_phy_lc_calibrate, +}; + +static struct rtl_mod_params rtl92de_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = true, + .fwctrl_lps = false, + .aspm_support = 1, + .debug_level = 0, + .debug_mask = 0, +}; + +static const struct rtl_hal_cfg rtl92de_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8192de", + .ops = &rtl8192de_hal_ops, + .mod_params = &rtl92de_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = RCR_AM, + .maps[MAC_RCR_AB] = RCR_AB, + .maps[MAC_RCR_ACRC32] = RCR_ACRC32, + .maps[MAC_RCR_ACF] = RCR_ACF, + .maps[MAC_RCR_AAP] = RCR_AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, /* just for 92se */ + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = 0, /* just for 92se */ + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, +}; + +static const struct pci_device_id rtl92de_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92de_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin"); + +module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92de_mod_params.debug_level, int, 0644); +module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444); +module_param_named(aspm, rtl92de_mod_params.aspm_support, int, 0444); +module_param_named(debug_mask, rtl92de_mod_params.debug_mask, ullong, 0644); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl92de_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92de_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +/* add global spin lock to solve the problem that + * Dul mac register operation on the same time */ +DEFINE_SPINLOCK(globalmutex_power); +DEFINE_SPINLOCK(globalmutex_for_fwdownload); +DEFINE_SPINLOCK(globalmutex_for_power_and_efuse); + +static int __init rtl92de_module_init(void) +{ + int ret = 0; + + ret = pci_register_driver(&rtl92de_driver); + if (ret) + WARN_ONCE(true, "rtl8192de: No device found\n"); + return ret; +} + +static void __exit rtl92de_module_exit(void) +{ + pci_unregister_driver(&rtl92de_driver); +} + +module_init(rtl92de_module_init); +module_exit(rtl92de_module_exit); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h new file mode 100644 index 000000000..19db4ce30 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92DE_SW_H__ +#define __RTL92DE_SW_H__ + +extern spinlock_t globalmutex_power; +extern spinlock_t globalmutex_for_fwdownload; +extern spinlock_t globalmutex_for_power_and_efuse; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c new file mode 100644 index 000000000..9b35c65d9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c @@ -0,0 +1,1663 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include + +#include "table.h" + +u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH] = { + 0x024, 0x0011800d, + 0x028, 0x00ffdb83, + 0x014, 0x088ba955, + 0x010, 0x49022b03, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x80706388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x272b2b2b, + 0x870, 0x07000700, + 0x874, 0x22188000, + 0x878, 0x08080808, + 0x87c, 0x00007ff8, + 0x880, 0xc0083070, + 0x884, 0x00000cd5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x40071d40, + 0xc04, 0x03a05633, + 0xc08, 0x001000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a979718, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc009e, + 0xc58, 0x69543420, + 0xc5c, 0x433c00a8, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x058610db, + 0xc78, 0x0000001f, + 0xc7c, 0x40b95612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20e00000, + 0xc90, 0x00121820, + 0xc94, 0x00000007, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b11e20, + 0xcdc, 0xe8767533, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608404, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c126da4, + 0xe78, 0x0c126da4, + 0xe7c, 0x0c126da4, + 0xe80, 0x0c126da4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c126da4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf1c, 0x00000064, + 0xf4c, 0x00000004, + 0xf00, 0x00000300, +}; + +u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH] = { + 0xe00, 0xffffffff, 0x07090c0c, + 0xe04, 0xffffffff, 0x01020405, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0b0c0c0e, + 0xe14, 0xffffffff, 0x01030506, + 0xe18, 0xffffffff, 0x0b0c0d0e, + 0xe1c, 0xffffffff, 0x01030509, + 0x830, 0xffffffff, 0x07090c0c, + 0x834, 0xffffffff, 0x01020405, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0b0c0c0e, + 0x848, 0xffffffff, 0x01030506, + 0x84c, 0xffffffff, 0x0b0c0d0e, + 0x868, 0xffffffff, 0x01030509, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008cb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057568, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008eb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ee, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ee, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x00000050, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x63e, 0x0000000e, + 0x63f, 0x0000000e, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7a420001, + 0xc78, 0x79430001, + 0xc78, 0x78440001, + 0xc78, 0x77450001, + 0xc78, 0x76460001, + 0xc78, 0x75470001, + 0xc78, 0x74480001, + 0xc78, 0x73490001, + 0xc78, 0x724a0001, + 0xc78, 0x714b0001, + 0xc78, 0x704c0001, + 0xc78, 0x6f4d0001, + 0xc78, 0x6e4e0001, + 0xc78, 0x6d4f0001, + 0xc78, 0x6c500001, + 0xc78, 0x6b510001, + 0xc78, 0x6a520001, + 0xc78, 0x69530001, + 0xc78, 0x68540001, + 0xc78, 0x67550001, + 0xc78, 0x66560001, + 0xc78, 0x65570001, + 0xc78, 0x64580001, + 0xc78, 0x63590001, + 0xc78, 0x625a0001, + 0xc78, 0x615b0001, + 0xc78, 0x605c0001, + 0xc78, 0x485d0001, + 0xc78, 0x475e0001, + 0xc78, 0x465f0001, + 0xc78, 0x45600001, + 0xc78, 0x44610001, + 0xc78, 0x43620001, + 0xc78, 0x42630001, + 0xc78, 0x41640001, + 0xc78, 0x40650001, + 0xc78, 0x27660001, + 0xc78, 0x26670001, + 0xc78, 0x25680001, + 0xc78, 0x24690001, + 0xc78, 0x236a0001, + 0xc78, 0x226b0001, + 0xc78, 0x216c0001, + 0xc78, 0x206d0001, + 0xc78, 0x206e0001, + 0xc78, 0x206f0001, + 0xc78, 0x20700001, + 0xc78, 0x20710001, + 0xc78, 0x20720001, + 0xc78, 0x20730001, + 0xc78, 0x20740001, + 0xc78, 0x20750001, + 0xc78, 0x20760001, + 0xc78, 0x20770001, + 0xc78, 0x20780001, + 0xc78, 0x20790001, + 0xc78, 0x207a0001, + 0xc78, 0x207b0001, + 0xc78, 0x207c0001, + 0xc78, 0x207d0001, + 0xc78, 0x207e0001, + 0xc78, 0x207f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x32070044, + 0xc78, 0x32080044, + 0xc78, 0x34090044, + 0xc78, 0x350a0044, + 0xc78, 0x360b0044, + 0xc78, 0x370c0044, + 0xc78, 0x380d0044, + 0xc78, 0x390e0044, + 0xc78, 0x3a0f0044, + 0xc78, 0x3e100044, + 0xc78, 0x42110044, + 0xc78, 0x44120044, + 0xc78, 0x46130044, + 0xc78, 0x4a140044, + 0xc78, 0x4e150044, + 0xc78, 0x50160044, + 0xc78, 0x55170044, + 0xc78, 0x5a180044, + 0xc78, 0x5e190044, + 0xc78, 0x641a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7a020001, + 0xc78, 0x79030001, + 0xc78, 0x78040001, + 0xc78, 0x77050001, + 0xc78, 0x76060001, + 0xc78, 0x75070001, + 0xc78, 0x74080001, + 0xc78, 0x73090001, + 0xc78, 0x720a0001, + 0xc78, 0x710b0001, + 0xc78, 0x700c0001, + 0xc78, 0x6f0d0001, + 0xc78, 0x6e0e0001, + 0xc78, 0x6d0f0001, + 0xc78, 0x6c100001, + 0xc78, 0x6b110001, + 0xc78, 0x6a120001, + 0xc78, 0x69130001, + 0xc78, 0x68140001, + 0xc78, 0x67150001, + 0xc78, 0x66160001, + 0xc78, 0x65170001, + 0xc78, 0x64180001, + 0xc78, 0x63190001, + 0xc78, 0x621a0001, + 0xc78, 0x611b0001, + 0xc78, 0x601c0001, + 0xc78, 0x481d0001, + 0xc78, 0x471e0001, + 0xc78, 0x461f0001, + 0xc78, 0x45200001, + 0xc78, 0x44210001, + 0xc78, 0x43220001, + 0xc78, 0x42230001, + 0xc78, 0x41240001, + 0xc78, 0x40250001, + 0xc78, 0x27260001, + 0xc78, 0x26270001, + 0xc78, 0x25280001, + 0xc78, 0x24290001, + 0xc78, 0x232a0001, + 0xc78, 0x222b0001, + 0xc78, 0x212c0001, + 0xc78, 0x202d0001, + 0xc78, 0x202e0001, + 0xc78, 0x202f0001, + 0xc78, 0x20300001, + 0xc78, 0x20310001, + 0xc78, 0x20320001, + 0xc78, 0x20330001, + 0xc78, 0x20340001, + 0xc78, 0x20350001, + 0xc78, 0x20360001, + 0xc78, 0x20370001, + 0xc78, 0x20380001, + 0xc78, 0x20390001, + 0xc78, 0x203a0001, + 0xc78, 0x203b0001, + 0xc78, 0x203c0001, + 0xc78, 0x203d0001, + 0xc78, 0x203e0001, + 0xc78, 0x203f0001, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x32070044, + 0xc78, 0x32080044, + 0xc78, 0x34090044, + 0xc78, 0x350a0044, + 0xc78, 0x360b0044, + 0xc78, 0x370c0044, + 0xc78, 0x380d0044, + 0xc78, 0x390e0044, + 0xc78, 0x3a0f0044, + 0xc78, 0x3e100044, + 0xc78, 0x42110044, + 0xc78, 0x44120044, + 0xc78, 0x46130044, + 0xc78, 0x4a140044, + 0xc78, 0x4e150044, + 0xc78, 0x50160044, + 0xc78, 0x55170044, + 0xc78, 0x5a180044, + 0xc78, 0x5e190044, + 0xc78, 0x641a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x6e1f0000, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h new file mode 100644 index 000000000..2a45082f4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92DE_TABLE__H_ +#define __RTL92DE_TABLE__H_ + +/*Created on 2011/ 1/14, 1:35*/ + +#define PHY_REG_2T_ARRAYLENGTH 380 +extern u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH]; +#define PHY_REG_ARRAY_PG_LENGTH 624 +extern u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH]; +#define RADIOA_2T_ARRAYLENGTH 378 +extern u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH]; +#define RADIOB_2T_ARRAYLENGTH 384 +extern u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH]; +#define RADIOA_2T_INT_PA_ARRAYLENGTH 378 +extern u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH]; +#define RADIOB_2T_INT_PA_ARRAYLENGTH 384 +extern u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 160 +extern u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_ARRAYLENGTH 386 +extern u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH]; +#define AGCTAB_5G_ARRAYLENGTH 194 +extern u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH]; +#define AGCTAB_2G_ARRAYLENGTH 194 +extern u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c new file mode 100644 index 000000000..91bf399c9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/trx_common.h" +#include "phy.h" +#include "trx.h" +#include "led.h" + +static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + u8 *virtualaddress8) +{ + __le32 *virtualaddress = (__le32 *)virtualaddress8; + + memset(virtualaddress, 0, 8); + + set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num); + set_earlymode_len0(virtualaddress, ptcb_desc->empkt_len[0]); + set_earlymode_len1(virtualaddress, ptcb_desc->empkt_len[1]); + set_earlymode_len2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF); + set_earlymode_len2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4); + set_earlymode_len3(virtualaddress, ptcb_desc->empkt_len[3]); + set_earlymode_len4(virtualaddress, ptcb_desc->empkt_len[4]); +} + +void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + __le32 *pdesc = (__le32 *)pdesc8; + u16 seq_number; + __le16 fc = hdr->frame_control; + unsigned int buf_len = 0; + unsigned int skb_len = skb->len; + u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 bw_40 = 0; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + buf_len = skb->len; + mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_92d)); + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + set_tx_desc_pkt_offset(pdesc, 1); + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN + + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_LOUD, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + _rtl92de_insert_emcontent(ptcb_desc, + (u8 *)(skb->data)); + } + } else { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + } + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (ptcb_desc->hw_rate < DESC_RATE6M) + ptcb_desc->hw_rate = DESC_RATE6M; + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) + set_tx_desc_data_shortgi(pdesc, 1); + + if (rtlhal->macphymode == DUALMAC_DUALPHY && + ptcb_desc->hw_rate == DESC_RATEMCS7) + set_tx_desc_data_shortgi(pdesc, 1); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + set_tx_desc_rts_enable(pdesc, + ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, ((ptcb_desc->rts_enable + || ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_rts_stbc(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (ptcb_desc->rts_rate < DESC_RATE6M) + ptcb_desc->rts_rate = DESC_RATE6M; + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_bw(pdesc, 0); + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, ((ptcb_desc->rts_rate <= + DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + if (bw_40) { + if (ptcb_desc->packet_bw) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb_len); + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf; + + keyconf = info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + + } + } + set_tx_desc_pkt_id(pdesc, 0); + set_tx_desc_queue_sel(pdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ? + 1 : 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + set_tx_desc_rts_rate(pdesc, 0x08); + /* set_tx_desc_tx_rate(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + set_tx_desc_tx_buffer_size(pdesc, (u16)buf_len); + set_tx_desc_tx_buffer_address(pdesc, mapping); + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->ratr_index); + } + if (ieee80211_is_data_qos(fc)) + set_tx_desc_qos(pdesc, 1); + + if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_pkt_id(pdesc, 8); + } + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 fw_queue = QSLT_BEACON; + + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + __le32 *pdesc = (__le32 *)pdesc8; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + /* 5G have no CCK rate + * Caution: The macros below are multi-line expansions. + * The braces are needed no matter what checkpatch says + */ + if (rtlhal->current_bandtype == BAND_ON_5G) { + set_tx_desc_tx_rate(pdesc, DESC_RATE6M); + } else { + set_tx_desc_tx_rate(pdesc, DESC_RATE1M); + } + set_tx_desc_seq(pdesc, 0); + set_tx_desc_linip(pdesc, 0); + set_tx_desc_queue_sel(pdesc, fw_queue); + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len); + set_tx_desc_tx_buffer_address(pdesc, mapping); + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + set_tx_desc_offset(pdesc, 0x20); + set_tx_desc_use_rate(pdesc, 1); + + if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_pkt_id(pdesc, 8); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); + wmb(); + set_tx_desc_own(pdesc, 1); +} + +bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl92d_get_desc(hw, entry, true, HW_DESC_OWN); + + /* a beacon packet will only use the first + * descriptor by defaut, and the own bit may not + * be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + else + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h new file mode 100644 index 000000000..d3c480c75 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92DE_TRX_H__ +#define __RTL92DE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size) +{ + memset((void *)__pdesc, 0, + min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET)); +} + +struct tx_desc_92d { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/Makefile new file mode 100644 index 000000000..569bfd3d5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192du-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192DU) += rtl8192du.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.c new file mode 100644 index 000000000..dd57707a9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/fw_common.h" +#include "dm.h" + +static void rtl92du_dm_init_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + dm_pstable->pre_ccastate = CCA_MAX; + dm_pstable->cur_ccasate = CCA_MAX; +} + +static void rtl92du_dm_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + int pwdb = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; + + if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY || + rtlhal->current_bandtype != BAND_ON_5G) + return; + + if (pwdb != 0) { + if (dm_pstable->pre_ccastate == CCA_2R || + dm_pstable->pre_ccastate == CCA_MAX) + dm_pstable->cur_ccasate = (pwdb >= 35) ? CCA_1R : CCA_2R; + else + dm_pstable->cur_ccasate = (pwdb <= 30) ? CCA_2R : CCA_1R; + } else { + dm_pstable->cur_ccasate = CCA_MAX; + } + + if (dm_pstable->pre_ccastate == dm_pstable->cur_ccasate) + return; + + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_TRACE, + "Old CCA state: %d new CCA state: %d\n", + dm_pstable->pre_ccastate, dm_pstable->cur_ccasate); + + if (dm_pstable->cur_ccasate == CCA_1R) { + if (rtlpriv->phy.rf_type == RF_2T2R) + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x13); + else /* Is this branch reachable? */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + } else { /* CCA_2R or CCA_MAX */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33); + } +} + +static void rtl92du_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + const u32 max_macid = 32; + u32 temp; + + /* AP & ADHOC & MESH will return tmp */ + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + + /* Indicate Rx signal strength to FW. */ + if (rtlpriv->dm.useramask) { + temp = rtlpriv->dm.undec_sm_pwdb << 16; + temp |= max_macid << 8; + + rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *)(&temp)); + } else { + rtl_write_byte(rtlpriv, 0x4fe, (u8)rtlpriv->dm.undec_sm_pwdb); + } +} + +void rtl92du_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl_dm_diginit(hw, 0x20); + rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER; + rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER; + rtl92d_dm_init_edca_turbo(hw); + rtl92du_dm_init_1r_cca(hw); + rtl92d_dm_init_rate_adaptive_mask(hw); + rtl92d_dm_initialize_txpower_tracking(hw); +} + +void rtl92du_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fwps_awake = true; + + /* 1. RF is OFF. (No need to do DM.) + * 2. Fw is under power saving mode for FwLPS. + * (Prevent from SW/FW I/O racing.) + * 3. IPS workitem is scheduled. (Prevent from IPS sequence + * to be swapped with DM. + * 4. RFChangeInProgress is TRUE. + * (Prevent from broken by IPS/HW/SW Rf off.) + */ + + if (ppsc->rfpwr_state != ERFON || fw_current_inpsmode || + !fwps_awake || ppsc->rfchange_inprogress) + return; + + rtl92du_dm_pwdb_monitor(hw); + rtl92d_dm_false_alarm_counter_statistics(hw); + rtl92d_dm_find_minimum_rssi(hw); + rtl92d_dm_dig(hw); + rtl92d_dm_check_txpower_tracking_thermal_meter(hw); + rtl92d_dm_check_edca_turbo(hw); + rtl92du_dm_1r_cca(hw); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.h new file mode 100644 index 000000000..2f283bf1e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/dm.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_DM_H__ +#define __RTL92DU_DM_H__ + +void rtl92du_dm_init(struct ieee80211_hw *hw); +void rtl92du_dm_watchdog(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.c new file mode 100644 index 000000000..f74e4e84f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/fw_common.h" +#include "fw.h" + +int rtl92du_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + enum version_8192d version = rtlhal->version; + u8 *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) + return 1; + + fwsize = rtlhal->fwsize; + pfwheader = rtlhal->pfirmware; + pfwdata = rtlhal->pfirmware; + rtlhal->fw_version = (u16)GET_FIRMWARE_HDR_VERSION(pfwheader); + rtlhal->fw_subversion = (u16)GET_FIRMWARE_HDR_SUB_VER(pfwheader); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); + + if (IS_FW_HEADER_EXIST(pfwheader)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Shift 32 bytes for FW header!!\n"); + pfwdata = pfwdata + 32; + fwsize = fwsize - 32; + } + + if (rtl92d_is_fw_downloaded(rtlpriv)) + goto exit; + + /* If 8051 is running in RAM code, driver should + * inform Fw to reset by itself, or it will cause + * download Fw fail. + */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl92d_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + } + + rtl92d_enable_fw_download(hw, true); + rtl92d_write_fw(hw, version, pfwdata, fwsize); + rtl92d_enable_fw_download(hw, false); + + err = rtl92d_fw_free_to_go(hw); + if (err) + pr_err("fw is not ready to run!\n"); +exit: + err = rtl92d_fw_init(hw); + return err; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.h new file mode 100644 index 000000000..7904bfbda --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/fw.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_FW_H__ +#define __RTL92DU_FW_H__ + +int rtl92du_download_fw(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c new file mode 100644 index 000000000..ff458fb85 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c @@ -0,0 +1,1212 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../cam.h" +#include "../usb.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/dm_common.h" +#include "../rtl8192d/fw_common.h" +#include "../rtl8192d/hw_common.h" +#include "../rtl8192d/phy_common.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "hw.h" +#include "trx.h" + +static void _rtl92du_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlusb->reg_bcn_ctrl_val |= set_bits; + rtlusb->reg_bcn_ctrl_val &= ~clear_bits; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); +} + +static void _rtl92du_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92du_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92du_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92du_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92du_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)val) = mac->rx_conf; + break; + default: + rtl92d_get_hw_reg(hw, variable, val); + break; + } +} + +void rtl92du_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + + switch (variable) { + case HW_VAR_AC_PARAM: + rtl92d_dm_init_edca_turbo(hw); + break; + case HW_VAR_ACM_CTRL: { + u8 e_aci = *val; + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&mac->ac[0].aifs); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + pr_err("%s:%d switch case %#x not processed\n", + __func__, __LINE__, e_aci); + break; + } + } + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR: + mac->rx_conf = ((u32 *)val)[0]; + rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); + break; + case HW_VAR_H2C_FW_JOINBSSRPT: { + u8 tmp_regcr, tmp_reg422; + bool recover = false; + u8 mstatus = *val; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AID, NULL); + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + tmp_regcr | ENSWBCN); + _rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION); + _rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0); + tmp_reg422 = rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & (EN_BCNQ_DL >> 16)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & ~(EN_BCNQ_DL >> 16)); + + /* We don't implement FW LPS so this is not needed. */ + /* rtl92d_set_fw_rsvdpagepkt(hw, 0); */ + + _rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0); + _rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT); + if (recover) + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + rtl_write_byte(rtlpriv, REG_CR + 1, + tmp_regcr & ~ENSWBCN); + } + rtl92d_set_fw_joinbss_report_cmd(hw, (*val)); + break; + } + case HW_VAR_CORRECT_TSF: { + u8 btype_ibss = val[0]; + + if (btype_ibss) + rtl92d_stop_tx_beacon(hw); + _rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION); + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + _rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0); + if (btype_ibss) + rtl92d_resume_tx_beacon(hw); + + break; + } + case HW_VAR_KEEP_ALIVE: + /* Avoid "switch case not processed" error. RTL8192DU doesn't + * need to do anything here, maybe. + */ + break; + default: + rtl92d_set_hw_reg(hw, variable, val); + break; + } +} + +static void _rtl92du_init_queue_reserved_page(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 txqpagenum, txqpageunit; + u32 txqremainingpage; + u32 value32 = 0; + u32 numhq = 0; + u32 numlq = 0; + u32 numnq = 0; + u32 numpubq; + + if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY) { + numpubq = NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC; + txqpagenum = TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC - numpubq; + } else { + numpubq = TEST_PAGE_NUM_PUBQ_92DU; + txqpagenum = TX_TOTAL_PAGE_NUMBER_92DU - numpubq; + } + + if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY && out_ep_num == 3) { + numhq = NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC; + numlq = NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC; + numnq = NORMAL_PAGE_NUM_NORMALQ_92D_DUAL_MAC; + } else { + txqpageunit = txqpagenum / out_ep_num; + txqremainingpage = txqpagenum % out_ep_num; + + if (queue_sel & TX_SELE_HQ) + numhq = txqpageunit; + if (queue_sel & TX_SELE_LQ) + numlq = txqpageunit; + if (queue_sel & TX_SELE_NQ) + numnq = txqpageunit; + + /* HIGH priority queue always present in the + * configuration of 2 or 3 out-ep. Remainder pages + * assigned to High queue + */ + if (out_ep_num > 1 && txqremainingpage) + numhq += txqremainingpage; + } + + /* NOTE: This step done before writing REG_RQPN. */ + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, (u8)numnq); + + /* TX DMA */ + u32p_replace_bits(&value32, numhq, HPQ_MASK); + u32p_replace_bits(&value32, numlq, LPQ_MASK); + u32p_replace_bits(&value32, numpubq, PUBQ_MASK); + value32 |= LD_RQPN; + rtl_write_dword(rtlpriv, REG_RQPN, value32); +} + +static void _rtl92du_init_tx_buffer_boundary(struct ieee80211_hw *hw, + u8 txpktbuf_bndy) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); + + /* TXRKTBUG_PG_BNDY */ + rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); + + /* Beacon Head for TXDMA */ + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); +} + +static bool _rtl92du_llt_table_init(struct ieee80211_hw *hw, u8 txpktbuf_bndy) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + bool status; + u8 maxpage; + + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + maxpage = 255; + else + maxpage = 127; + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = rtl92d_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + /* end of list */ + status = rtl92d_llt_write(hw, txpktbuf_bndy - 1, 0xFF); + if (!status) + return status; + + /* Make the other pages as ring buffer + * This ring buffer is used as beacon buffer if we + * config this MAC as two MAC transfer. + * Otherwise used as local loopback buffer. + */ + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = rtl92d_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + /* Let last entry point to the start entry of ring buffer */ + status = rtl92d_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + return true; +} + +static void _rtl92du_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq, + u16 bkq, u16 viq, u16 voq, + u16 mgtq, u16 hiq) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value16; + + value16 = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7; + u16p_replace_bits(&value16, beq, TXDMA_BEQ_MAP); + u16p_replace_bits(&value16, bkq, TXDMA_BKQ_MAP); + u16p_replace_bits(&value16, viq, TXDMA_VIQ_MAP); + u16p_replace_bits(&value16, voq, TXDMA_VOQ_MAP); + u16p_replace_bits(&value16, mgtq, TXDMA_MGQ_MAP); + u16p_replace_bits(&value16, hiq, TXDMA_HIQ_MAP); + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); +} + +static void _rtl92du_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value; + + switch (queue_sel) { + case TX_SELE_HQ: + value = QUEUE_HIGH; + break; + case TX_SELE_LQ: + value = QUEUE_LOW; + break; + case TX_SELE_NQ: + value = QUEUE_NORMAL; + break; + default: + WARN_ON(1); /* Shall not reach here! */ + return; + } + _rtl92du_init_chipn_reg_priority(hw, value, value, value, value, + value, value); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92du_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 beq, bkq, viq, voq, mgtq, hiq; + u16 valuehi, valuelow; + + switch (queue_sel) { + default: + WARN_ON(1); + fallthrough; + case (TX_SELE_HQ | TX_SELE_LQ): + valuehi = QUEUE_HIGH; + valuelow = QUEUE_LOW; + break; + case (TX_SELE_NQ | TX_SELE_LQ): + valuehi = QUEUE_NORMAL; + valuelow = QUEUE_LOW; + break; + case (TX_SELE_HQ | TX_SELE_NQ): + valuehi = QUEUE_HIGH; + valuelow = QUEUE_NORMAL; + break; + } + + beq = valuelow; + bkq = valuelow; + viq = valuehi; + voq = valuehi; + mgtq = valuehi; + hiq = valuehi; + + _rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92du_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 beq, bkq, viq, voq, mgtq, hiq; + + beq = QUEUE_LOW; + bkq = QUEUE_LOW; + viq = QUEUE_NORMAL; + voq = QUEUE_HIGH; + mgtq = QUEUE_HIGH; + hiq = QUEUE_HIGH; + + _rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92du_init_queue_priority(struct ieee80211_hw *hw, + u8 out_ep_num, + u8 queue_sel) +{ + switch (out_ep_num) { + case 1: + _rtl92du_init_chipn_one_out_ep_priority(hw, queue_sel); + break; + case 2: + _rtl92du_init_chipn_two_out_ep_priority(hw, queue_sel); + break; + case 3: + _rtl92du_init_chipn_three_out_ep_priority(hw, queue_sel); + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } +} + +static void _rtl92du_init_wmac_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + + mac->rx_conf = RCR_APM | RCR_AM | RCR_AB | RCR_ADF | RCR_APP_ICV | + RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | + RCR_APP_PHYST_RXFF | RCR_APPFCS; + + rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); + + /* Set Multicast Address. */ + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); +} + +static void _rtl92du_init_adaptive_ctrl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 val32; + + val32 = rtl_read_dword(rtlpriv, REG_RRSR); + val32 &= ~0xfffff; + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + val32 |= 0xffff0; /* No CCK */ + else + val32 |= 0xffff1; + rtl_write_dword(rtlpriv, REG_RRSR, val32); + + /* Set Spec SIFS (used in NAV) */ + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + + /* Retry limit 0x30 */ + rtl_write_word(rtlpriv, REG_RL, 0x3030); +} + +static void _rtl92du_init_edca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 val16; + + /* Disable EDCCA count down, to reduce collison and retry */ + val16 = rtl_read_word(rtlpriv, REG_RD_CTRL); + val16 |= DIS_EDCA_CNT_DWN; + rtl_write_word(rtlpriv, REG_RD_CTRL, val16); + + /* CCK SIFS shall always be 10us. */ + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x0a0a); + /* Set SIFS for OFDM */ + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204); + + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004); + + /* TXOP */ + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B); + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F); + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324); + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226); + + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + + rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x2); + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); +} + +static void _rtl92du_init_retry_function(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val8; + + val8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL); + val8 |= EN_AMPDU_RTY_NEW; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, val8); + + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); +} + +static void _rtl92du_init_operation_mode(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + rtl_write_byte(rtlpriv, REG_BWOPMODE, BW_OPMODE_20MHZ); + + switch (rtlpriv->phy.rf_type) { + case RF_1T2R: + case RF_1T1R: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); + break; + case RF_2T2R: + case RF_2T2R_GREEN: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); + break; + } + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, rtlhal->minspace_cfg); +} + +static void _rtl92du_init_beacon_parameters(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); + + rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x3c02); + rtl_write_byte(rtlpriv, REG_DRVERLYINT, 0x05); + rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x03); + + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); +} + +static void _rtl92du_init_ampdu_aggregation(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + /* Aggregation threshold */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66525541); + else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x44444441); + else + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x88728841); + + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); +} + +static bool _rtl92du_init_power_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short wordtmp; + unsigned char bytetmp; + u16 retry = 0; + + do { + if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) + break; + + if (retry++ > 1000) + return false; + } while (true); + + /* Unlock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + + /* SPS0_CTRL 0x11[7:0] = 0x2b enable SPS into PWM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + + msleep(1); + + bytetmp = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); + if ((bytetmp & LDV12_EN) == 0) { + bytetmp |= LDV12_EN; + rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, bytetmp); + + msleep(1); + + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); + bytetmp &= ~ISO_MD2PP; + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, bytetmp); + } + + /* Auto enable WLAN */ + wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO); + wordtmp |= APFM_ONMAC; + rtl_write_word(rtlpriv, REG_APS_FSMCO, wordtmp); + + wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO); + retry = 0; + while ((wordtmp & APFM_ONMAC) && retry < 1000) { + retry++; + wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO); + } + + /* Release RF digital isolation */ + wordtmp = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); + wordtmp &= ~ISO_DIOR; + rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, wordtmp); + + /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ + wordtmp = rtl_read_word(rtlpriv, REG_CR); + wordtmp |= HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | + PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC; + rtl_write_word(rtlpriv, REG_CR, wordtmp); + + return true; +} + +static bool _rtl92du_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val8; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + + val8 = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + val8 &= ~(FEN_MREGEN >> 8); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, val8); + + /* For s3/s4 may reset mac, Reg0xf8 may be set to 0, + * so reset macphy control reg here. + */ + rtl92d_phy_config_macphymode(hw); + + rtl92du_phy_set_poweron(hw); + + if (!_rtl92du_init_power_on(hw)) { + pr_err("Failed to init power on!\n"); + return false; + } + + rtl92d_phy_config_maccoexist_rfpage(hw); + + return true; +} + +int rtl92du_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 val8, txpktbuf_bndy; + int err, i; + u32 val32; + u16 val16; + + mutex_lock(rtlpriv->mutex_for_hw_init); + + /* we should do iqk after disable/enable */ + rtl92d_phy_reset_iqk_result(hw); + + if (!_rtl92du_init_mac(hw)) { + pr_err("Init MAC failed\n"); + mutex_unlock(rtlpriv->mutex_for_hw_init); + return 1; + } + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) + txpktbuf_bndy = 249; + else + txpktbuf_bndy = 123; + + if (!_rtl92du_llt_table_init(hw, txpktbuf_bndy)) { + pr_err("Init LLT failed\n"); + mutex_unlock(rtlpriv->mutex_for_hw_init); + return 1; + } + + err = rtl92du_download_fw(hw); + + /* return fail only when part number check fail */ + if (err && rtl_read_byte(rtlpriv, 0x1c5) == 0xe0) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW..\n"); + mutex_unlock(rtlpriv->mutex_for_hw_init); + return 1; + } + rtlhal->last_hmeboxnum = 0; + rtlpriv->psc.fw_current_inpsmode = false; + + rtl92du_phy_mac_config(hw); + + /* Set reserved page for each queue */ + _rtl92du_init_queue_reserved_page(hw, rtlusb->out_ep_nums, + rtlusb->out_queue_sel); + + _rtl92du_init_tx_buffer_boundary(hw, txpktbuf_bndy); + + _rtl92du_init_queue_priority(hw, rtlusb->out_ep_nums, + rtlusb->out_queue_sel); + + /* Set Tx/Rx page size (Tx must be 128 Bytes, + * Rx can be 64, 128, 256, 512, 1024 bytes) + */ + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + + /* Get Rx PHY status in order to report RSSI and others. */ + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_HIMR, 0xffffffff); + + val8 = rtl_read_byte(rtlpriv, MSR); + val8 &= ~MSR_MASK; + val8 |= MSR_INFRA; + rtl_write_byte(rtlpriv, MSR, val8); + + _rtl92du_init_wmac_setting(hw); + _rtl92du_init_adaptive_ctrl(hw); + _rtl92du_init_edca(hw); + + rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x10080404); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x08070605); + + _rtl92du_init_retry_function(hw); + /* _InitUsbAggregationSetting(padapter); no aggregation for now */ + _rtl92du_init_operation_mode(hw); + _rtl92du_init_beacon_parameters(hw); + _rtl92du_init_ampdu_aggregation(hw); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + /* unit: 256us. 256ms */ + rtl_write_word(rtlpriv, REG_PKT_VO_VI_LIFE_TIME, 0x0400); + rtl_write_word(rtlpriv, REG_PKT_BE_BK_LIFE_TIME, 0x0400); + + /* Hardware-controlled blinking. */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8282); + rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x82); + + val32 = rtl_read_dword(rtlpriv, REG_TXDMA_OFFSET_CHK); + val32 |= DROP_DATA_EN; + rtl_write_dword(rtlpriv, REG_TXDMA_OFFSET_CHK, val32); + + if (mac->rdg_en) { + rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff); + rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); + rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); + } + + for (i = 0; i < 4; i++) + rtl_write_dword(rtlpriv, REG_ARFR0 + i * 4, 0x1f8ffff0); + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + if (rtlusb->out_ep_nums == 2) + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03066666); + else + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x8888); + } else { + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x5555); + } + + val8 = rtl_read_byte(rtlpriv, 0x605); + val8 |= 0xf0; + rtl_write_byte(rtlpriv, 0x605, val8); + + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x30); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30); + rtl_write_byte(rtlpriv, 0x606, 0x30); + + /* temp for high queue and mgnt Queue corrupt in time; it may + * cause hang when sw beacon use high_Q, other frame use mgnt_Q; + * or, sw beacon use mgnt_Q, other frame use high_Q; + */ + rtl_write_byte(rtlpriv, REG_DIS_TXREQ_CLR, 0x10); + val16 = rtl_read_word(rtlpriv, REG_RD_CTRL); + val16 |= BIT(12); + rtl_write_word(rtlpriv, REG_RD_CTRL, val16); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0); + + /* usb suspend idle time count for bitfile0927 */ + val8 = rtl_read_byte(rtlpriv, 0xfe56); + val8 |= BIT(0) | BIT(1); + rtl_write_byte(rtlpriv, 0xfe56, val8); + + if (rtlhal->earlymode_enable) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EarlyMode Enabled!!!\n"); + + val8 = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL); + val8 |= 0x1f; + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, val8); + + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL + 3, 0x80); + + val8 = rtl_read_byte(rtlpriv, 0x605); + val8 |= 0x40; + rtl_write_byte(rtlpriv, 0x605, val8); + } else { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0); + } + + rtl92du_phy_bb_config(hw); + + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + /* set before initialize RF */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + + /* config RF */ + rtl92du_phy_rf_config(hw); + + /* set default value after initialize RF */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + + /* After load BB, RF params, we need to do more for 92D. */ + rtl92du_update_bbrf_configuration(hw); + + rtlphy->rfreg_chnlval[0] = + rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = + rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK); + + /*---- Set CCK and OFDM Block "ON"----*/ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + /* reset hw sec */ + rtl_cam_reset_all_entry(hw); + rtl92d_enable_hw_security_config(hw); + + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + + /* schmitt trigger, improve tx evm for 92du */ + val8 = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL); + val8 |= BIT(1); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, val8); + + /* Disable bar */ + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0xffff); + + /* Nav limit */ + rtl_write_byte(rtlpriv, REG_NAV_CTRL + 2, 0); + rtl_write_byte(rtlpriv, ROFDM0_XATXAFE + 3, 0x50); + + /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct + * TX power index for different rate set. + */ + rtl92d_phy_get_hw_reg_originalvalue(hw); + + ppsc->rfpwr_state = ERFON; + + /* do IQK for 2.4G for better scan result */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl92du_phy_iq_calibrate(hw); + + rtl92du_phy_lc_calibrate(hw, IS_92D_SINGLEPHY(rtlhal->version)); + + rtl92du_phy_init_pa_bias(hw); + + mutex_unlock(rtlpriv->mutex_for_hw_init); + + rtl92du_dm_init(hw); + + /* For 2 PORT TSF SYNC */ + rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1818); + rtlusb->reg_bcn_ctrl_val = 0x18; + + udelay(500); + + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_write_dword(rtlpriv, RFPGA1_TXINFO, + rtl_read_dword(rtlpriv, RFPGA1_TXINFO) & ~BIT(30)); + + rtl_write_dword(rtlpriv, RFPGA0_TXGAINSTAGE, + rtl_read_dword(rtlpriv, RFPGA0_TXGAINSTAGE) & ~BIT(31)); + + rtl_write_dword(rtlpriv, ROFDM0_XBTXAFE, 0xa0e40000); + } + + val32 = rtl_read_dword(rtlpriv, REG_FWHW_TXQ_CTRL); + val32 |= BIT(12); + rtl_write_dword(rtlpriv, REG_FWHW_TXQ_CTRL, val32); + + return err; +} + +static int _rtl92du_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + + bt_msr &= 0xfc; + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + rtl92d_stop_tx_beacon(hw); + _rtl92du_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || + type == NL80211_IFTYPE_AP) { + rtl92d_resume_tx_beacon(hw); + _rtl92du_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); + } + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not supported!\n", type); + return 1; + } + rtl_write_byte(rtlpriv, MSR, bt_msr); + + rtlpriv->cfg->ops->led_control(hw, ledaction); + + if ((bt_msr & MSR_MASK) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + + return 0; +} + +void rtl92du_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + + if (check_bssid) { + reg_rcr |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)®_rcr); + _rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT); + } else if (!check_bssid) { + reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + _rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)®_rcr); + } +} + +int rtl92du_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92du_set_media_status(hw, type)) + return -EOPNOTSUPP; + + /* check bssid */ + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92du_set_check_bssid(hw, true); + } else { + rtl92du_set_check_bssid(hw, false); + } + + return 0; +} + +/* do iqk or reload iqk */ +/* windows just rtl92d_phy_reload_iqk_setting in set channel, + * but it's very strict for time sequence so we add + * rtl92d_phy_reload_iqk_setting here + */ +void rtl92du_linked_set_reg(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + u8 indexforchannel; + + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) { + rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, + "Do IQK for channel:%d\n", channel); + rtl92du_phy_iq_calibrate(hw); + } +} + +void rtl92du_enable_interrupt(struct ieee80211_hw *hw) +{ + /* Nothing to do. */ +} + +void rtl92du_disable_interrupt(struct ieee80211_hw *hw) +{ + /* Nothing to do. */ +} + +static void _rtl92du_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 retry = 100; + u8 u1b_tmp; + u16 val16; + u32 val32; + + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + + /* IF fw in RAM code, do reset */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) { + rtl_write_byte(rtlpriv, REG_FSIMR, 0); + + /* We need to disable other HRCV INT to influence 8051 reset. */ + rtl_write_byte(rtlpriv, REG_FWIMR, 0x20); + + /* Close mask to prevent incorrect FW write operation. */ + rtl_write_byte(rtlpriv, REG_FTIMR, 0); + + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + + /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */ + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + while (val16 & FEN_CPUEN) { + retry--; + if (retry == 0) + break; + udelay(50); + val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + } + + if (retry == 0) { + rtl_write_byte(rtlpriv, REG_FWIMR, 0); + + /* if 8051 reset fail, reset MAC directly. */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x50); + + mdelay(10); + } + } + + /* reset MCU, MAC register, DCORE */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); + + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* Pull GPIO PIN to balance level and LED control */ + + /* Disable GPIO[7:0] */ + rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL + 2, 0x0000); + val32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL); + u32p_replace_bits(&val32, val32 & 0xff, 0x0000ff00); + u32p_replace_bits(&val32, 0xff, 0x00ff0000); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, val32); + + /* Disable GPIO[10:8] */ + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, 0); + val16 = rtl_read_word(rtlpriv, REG_GPIO_IO_SEL); + u16p_replace_bits(&val16, val16 & 0xf, 0x00f0); + u16p_replace_bits(&val16, 0xf, 0x0780); + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, val16); + + /* Disable LED 0, 1, and 2 */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8888); + rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x88); + + /* Disable analog sequence */ + + /* enter PFM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + + rtl_write_word(rtlpriv, REG_APS_FSMCO, + APDM_HOST | AFSM_HSUS | PFM_ALDN); + + /* lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "In PowerOff,reg0x%x=%X\n", + REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); + + /* 0x17[7] 1b': power off in process 0b' : power off over */ + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + mutex_lock(rtlpriv->mutex_for_power_on_off); + u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1b_tmp &= ~BIT(7); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp); + mutex_unlock(rtlpriv->mutex_for_power_on_off); + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); +} + +void rtl92du_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + u32 val32; + u16 val16; + u8 val8; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92du_set_media_status(hw, opmode); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + /* Power sequence for each MAC. */ + /* a. stop tx DMA */ + /* b. close RF */ + /* c. clear rx buf */ + /* d. stop rx DMA */ + /* e. reset MAC */ + + val16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG); + val16 &= ~BIT(12); + rtl_write_word(rtlpriv, REG_GPIO_MUXCFG, val16); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xff); + udelay(500); + rtl_write_byte(rtlpriv, REG_CR, 0); + + /* RF OFF sequence */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x00); + + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + + val8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8); + + /* Mac0 can not do Global reset. Mac1 can do. */ + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY || + rtlhal->interfaceindex == 1) { + /* before BB reset should do clock gated */ + val32 = rtl_read_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER); + val32 |= BIT(31); + rtl_write_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER, val32); + + val8 &= ~FEN_BB_GLB_RSTN; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8); + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); + if (!rtl92du_phy_check_poweroff(hw)) + return; + + _rtl92du_poweroff_adapter(hw); +} + +void rtl92du_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; + rtl92du_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30); + else + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20); + rtl_write_byte(rtlpriv, 0x606, 0x30); +} + +void rtl92du_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl92du_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl92du_enable_interrupt(hw); +} + +void rtl92du_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + /* Nothing to do here. */ +} + +void rtl92du_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Chip version reading is done in rtl92d_read_eeprom_info. */ + + rtlpriv->rtlhal.hw_type = HARDWARE_TYPE_RTL8192DU; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.h new file mode 100644 index 000000000..80ed00c90 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_HW_H__ +#define __RTL92DU_HW_H__ + +void rtl92du_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92du_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92du_read_chip_version(struct ieee80211_hw *hw); +int rtl92du_hw_init(struct ieee80211_hw *hw); +void rtl92du_card_disable(struct ieee80211_hw *hw); +void rtl92du_enable_interrupt(struct ieee80211_hw *hw); +void rtl92du_disable_interrupt(struct ieee80211_hw *hw); +int rtl92du_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92du_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92du_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92du_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92du_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92du_linked_set_reg(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.c new file mode 100644 index 000000000..6c12dfbd6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "led.h" + +void rtl92du_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + /* The hardware has control. */ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.h new file mode 100644 index 000000000..d7ebc8afc --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/led.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_LED_H__ +#define __RTL92DU_LED_H__ + +void rtl92du_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.c new file mode 100644 index 000000000..8c2167cc1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.c @@ -0,0 +1,3118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../ps.h" +#include "../core.h" +#include "../efuse.h" +#include "../usb.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/rf_common.h" +#include "phy.h" +#include "rf.h" +#include "table.h" + +#define MAX_RF_IMR_INDEX 12 +#define MAX_RF_IMR_INDEX_NORMAL 13 +#define RF_REG_NUM_FOR_C_CUT_5G 6 +#define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA 7 +#define RF_REG_NUM_FOR_C_CUT_2G 5 +#define RF_CHNL_NUM_5G 19 +#define RF_CHNL_NUM_5G_40M 17 +#define CV_CURVE_CNT 64 + +static const u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = { + 0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0 +}; + +static const u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6 +}; + +static const u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8 +}; + +static const u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + 0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E +}; + +static const u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1), + BIT(10) | BIT(9), + BIT(18) | BIT(17) | BIT(16) | BIT(1), + BIT(2) | BIT(1), + BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) +}; + +static const u8 rf_chnl_5g[RF_CHNL_NUM_5G] = { + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, 136, 140 +}; + +static const u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = { + 38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114, + 118, 122, 126, 130, 134, 138 +}; + +static const u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = { + {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04}, + {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04} +}; + +static const u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = { + {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840}, + {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840}, + {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41} +}; + +static const u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF; + +static const u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12} +}; + +/* [patha+b][reg] */ +static const u32 rf_imr_param_normal[3][MAX_RF_IMR_INDEX_NORMAL] = { + /* channels 1-14. */ + { + 0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff + }, + /* channels 36-64 */ + { + 0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000, + 0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090, + 0x32c9a + }, + /* channels 100-165 */ + { + 0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000, + 0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a + } +}; + +static const u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = { + 25141, 25116, 25091, 25066, 25041, + 25016, 24991, 24966, 24941, 24917, + 24892, 24867, 24843, 24818, 24794, + 24770, 24765, 24721, 24697, 24672, + 24648, 24624, 24600, 24576, 24552, + 24528, 24504, 24480, 24457, 24433, + 24409, 24385, 24362, 24338, 24315, + 24291, 24268, 24245, 24221, 24198, + 24175, 24151, 24128, 24105, 24082, + 24059, 24036, 24013, 23990, 23967, + 23945, 23922, 23899, 23876, 23854, + 23831, 23809, 23786, 23764, 23741, + 23719, 23697, 23674, 23652, 23630, + 23608, 23586, 23564, 23541, 23519, + 23498, 23476, 23454, 23432, 23410, + 23388, 23367, 23345, 23323, 23302, + 23280, 23259, 23237, 23216, 23194, + 23173, 23152, 23130, 23109, 23088, + 23067, 23046, 23025, 23003, 22982, + 22962, 22941, 22920, 22899, 22878, + 22857, 22837, 22816, 22795, 22775, + 22754, 22733, 22713, 22692, 22672, + 22652, 22631, 22611, 22591, 22570, + 22550, 22530, 22510, 22490, 22469, + 22449, 22429, 22409, 22390, 22370, + 22350, 22336, 22310, 22290, 22271, + 22251, 22231, 22212, 22192, 22173, + 22153, 22134, 22114, 22095, 22075, + 22056, 22037, 22017, 21998, 21979, + 21960, 21941, 21921, 21902, 21883, + 21864, 21845, 21826, 21807, 21789, + 21770, 21751, 21732, 21713, 21695, + 21676, 21657, 21639, 21620, 21602, + 21583, 21565, 21546, 21528, 21509, + 21491, 21473, 21454, 21436, 21418, + 21400, 21381, 21363, 21345, 21327, + 21309, 21291, 21273, 21255, 21237, + 21219, 21201, 21183, 21166, 21148, + 21130, 21112, 21095, 21077, 21059, + 21042, 21024, 21007, 20989, 20972, + 25679, 25653, 25627, 25601, 25575, + 25549, 25523, 25497, 25471, 25446, + 25420, 25394, 25369, 25343, 25318, + 25292, 25267, 25242, 25216, 25191, + 25166 +}; + +/* channel 1~14 */ +static const u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = { + 26084, 26030, 25976, 25923, 25869, 25816, 25764, + 25711, 25658, 25606, 25554, 25502, 25451, 25328 +}; + +u32 rtl92du_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + + if (rtlhal->during_mac1init_radioa) + regaddr |= MAC1_ACCESS_PHY0; + else if (rtlhal->during_mac0init_radiob) + regaddr |= MAC0_ACCESS_PHY1; + + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + return returnvalue; +} + +void rtl92du_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (rtlhal->during_mac1init_radioa) + regaddr |= MAC1_ACCESS_PHY0; + else if (rtlhal->during_mac0init_radiob) + regaddr |= MAC0_ACCESS_PHY1; + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = (originalvalue & (~bitmask)) | + ((data << bitshift) & bitmask); + } + + rtl_write_dword(rtlpriv, regaddr, data); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} + +/* To avoid miswrite Reg0x800 for 92D */ +static void rtl92du_phy_set_bb_reg_1byte(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift, offset; + u8 value; + + /* BitMask only support bit0~bit7 or bit8~bit15, bit16~bit23, + * bit24~bit31, should be in 1 byte scale; + */ + bitshift = calculate_bit_shift(bitmask); + offset = bitshift / 8; + + originalvalue = rtl_read_dword(rtlpriv, regaddr); + data = (originalvalue & (~bitmask)) | ((data << bitshift) & bitmask); + + value = data >> (8 * offset); + + rtl_write_byte(rtlpriv, regaddr + offset, value); +} + +bool rtl92du_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 arraylength; + const u32 *ptrarray; + u32 i; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); + + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = rtl8192du_mac_2tarray; + + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); + + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { + /* improve 2-stream TX EVM */ + /* rtl_write_byte(rtlpriv, 0x14,0x71); */ + /* AMPDU aggregation number 9 */ + /* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B); + } else { + /* 92D need to test to decide the num. */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07); + } + + return true; +} + +static bool _rtl92du_phy_config_bb(struct ieee80211_hw *hw, u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u16 phy_reg_arraylen, agctab_arraylen = 0; + const u32 *agctab_array_table = NULL; + const u32 *phy_regarray_table; + int i; + + /* Normal chip, Mac0 use AGC_TAB.txt for 2G and 5G band. */ + if (rtlhal->interfaceindex == 0) { + agctab_arraylen = AGCTAB_ARRAYLENGTH; + agctab_array_table = rtl8192du_agctab_array; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC0, Rtl819XAGCTAB_Array\n"); + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; + agctab_array_table = rtl8192du_agctab_2garray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"); + } else { + agctab_arraylen = AGCTAB_5G_ARRAYLENGTH; + agctab_array_table = rtl8192du_agctab_5garray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"); + } + } + phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; + phy_regarray_table = rtl8192du_phy_reg_2tarray; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> phy:Rtl819XPHY_REG_Array_PG\n"); + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + rtl_addr_delay(phy_regarray_table[i]); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], + MASKDWORD, agctab_array_table[i + 1]); + + /* Add 1us delay between BB/RF register setting. */ + udelay(1); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "AGC table %u %u\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Normal Chip, loaded AGC table\n"); + } + return true; +} + +static bool _rtl92du_phy_config_bb_pg(struct ieee80211_hw *hw, u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + const u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + int i; + + phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH; + phy_regarray_table_pg = rtl8192du_phy_reg_array_pg; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + rtl_addr_delay(phy_regarray_table_pg[i]); + rtl92d_store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +static bool _rtl92du_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool ret; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); + ret = _rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG); + if (!ret) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + + if (!rtlefuse->autoload_failflag) { + rtlphy->pwrgroup_cnt = 0; + ret = _rtl92du_phy_config_bb_pg(hw, BASEBAND_CONFIG_PHY_REG); + } + if (!ret) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + + ret = _rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); + if (!ret) { + pr_err("AGC Table Fail\n"); + return false; + } + + rtlphy->cck_high_power = (bool)rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200); + + return true; +} + +bool rtl92du_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + bool rtstatus; + u32 regvaldw; + u16 regval; + u8 value; + + rtl92d_phy_init_bb_rf_register_definition(hw); + + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + + /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */ + value = rtl_read_byte(rtlpriv, REG_RF_CTRL); + rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB | + RF_SDMRSTB); + + value = FEN_BB_GLB_RSTN | FEN_BBRSTB; + if (rtlhal->interface == INTF_PCI) + value |= FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE; + else if (rtlhal->interface == INTF_USB) + value |= FEN_USBA | FEN_USBD; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value); + + regvaldw = rtl_read_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER); + regvaldw &= ~BIT(31); + rtl_write_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER, regvaldw); + + /* To Fix MAC loopback mode fail. */ + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); + rtl_write_byte(rtlpriv, 0x15, 0xe9); + + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)) && + rtlhal->interface == INTF_PCI) { + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + } + + rtstatus = _rtl92du_phy_bb_config(hw); + + /* Crystal calibration */ + rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL, 0xf0, + rtlpriv->efuse.crystalcap & 0x0f); + rtl_set_bbreg(hw, REG_AFE_PLL_CTRL, 0xf0000000, + (rtlpriv->efuse.crystalcap & 0xf0) >> 4); + + return rtstatus; +} + +bool rtl92du_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92du_phy_rf6052_config(hw); +} + +bool rtl92du_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 radioa_arraylen, radiob_arraylen; + const u32 *radioa_array_table; + const u32 *radiob_array_table; + int i; + + radioa_arraylen = RADIOA_2T_ARRAYLENGTH; + radioa_array_table = rtl8192du_radioa_2tarray; + radiob_arraylen = RADIOB_2T_ARRAYLENGTH; + radiob_array_table = rtl8192du_radiob_2tarray; + if (rtlpriv->efuse.internal_pa_5g[0]) { + radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH; + radioa_array_table = rtl8192du_radioa_2t_int_paarray; + } + if (rtlpriv->efuse.internal_pa_5g[1]) { + radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH; + radiob_array_table = rtl8192du_radiob_2t_int_paarray; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); + + /* this only happens when DMDP, mac0 start on 2.4G, + * mac1 start on 5G, mac 0 has to set phy0 & phy1 + * pathA or mac1 has to set phy0 & phy1 pathA + */ + if (content == radiob_txt && rfpath == RF90_PATH_A) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " ===> althougth Path A, we load radiob.txt\n"); + radioa_arraylen = radiob_arraylen; + radioa_array_table = radiob_array_table; + } + + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + } + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + } + break; + case RF90_PATH_C: + case RF90_PATH_D: + pr_err("switch case %#x not processed\n", rfpath); + break; + } + + return true; +} + +void rtl92du_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + if (rtlphy->set_bwmode_inprogress) + return; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "FALSE driver sleep or unload\n"); + return; + } + + rtlphy->set_bwmode_inprogress = true; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + reg_prsr_rsc = (reg_prsr_rsc & 0x90) | + (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | BIT(11), 3); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + /* Set Control channel to upper or lower. + * These settings are required only for 40MHz + */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND, + mac->cur_40_prime_sc >> 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, + BIT(10) | BIT(11), 0); + rtl_set_bbreg(hw, 0x818, BIT(26) | BIT(27), + mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); +} + +static void _rtl92du_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) +{ + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN | BOFDMEN, 0); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x00); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0); +} + +static void rtl92du_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u16 basic_rates; + u32 reg_mac; + u8 value8; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); + rtlhal->bandset = band; + rtlhal->current_bandtype = band; + if (IS_92D_SINGLEPHY(rtlhal->version)) + rtlhal->bandset = BAND_ON_BOTH; + + /* stop RX/Tx */ + _rtl92du_phy_stop_trx_before_changeband(hw); + + /* reconfig BB/RF according to wireless mode */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + /* BB & RF Config */ + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n"); + else + /* 5G band */ + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n"); + + if (rtlhal->interfaceindex == 1) + _rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); + + rtl92du_update_bbrf_configuration(hw); + + basic_rates = RRSR_6M | RRSR_12M | RRSR_24M; + if (rtlhal->current_bandtype == BAND_ON_2_4G) + basic_rates |= RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, + (u8 *)&basic_rates); + + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN | BOFDMEN, 0x3); + + /* 20M BW. */ + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */ + rtlhal->reloadtxpowerindex = true; + + reg_mac = rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1; + + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, reg_mac); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, reg_mac, value8); + } else { + value8 = rtl_read_byte(rtlpriv, reg_mac); + value8 &= ~BIT(1); + rtl_write_byte(rtlpriv, reg_mac, value8); + } + mdelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n"); +} + +static void _rtl92du_phy_reload_imr_setting(struct ieee80211_hw *hw, + u8 channel, u8 rfpath) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 group, i; + + if (rtlusb->udev->speed != USB_SPEED_HIGH) + return; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, + BOFDMEN | BCCKEN, 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + + /* fc area 0xd2c */ + if (channel >= 149) + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 2); + else + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 1); + + /* leave 0 for channel1-14. */ + group = channel <= 64 ? 1 : 2; + for (i = 0; i < MAX_RF_IMR_INDEX_NORMAL; i++) + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], + RFREG_OFFSET_MASK, + rf_imr_param_normal[group][i]); + + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, + BOFDMEN | BCCKEN, 3); + } else { + /* G band. */ + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Load RF IMR parameters for G band. IMR already setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); + + if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Load RF IMR parameters for G band. %d\n", + rfpath); + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, + BOFDMEN | BCCKEN, 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0xf); + + for (i = 0; i < MAX_RF_IMR_INDEX_NORMAL; i++) { + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], + RFREG_OFFSET_MASK, + rf_imr_param_normal[0][i]); + } + + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0); + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, + BOFDMEN | BCCKEN, 3); + } + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92du_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 path = rtlhal->current_bandtype == BAND_ON_5G ? RF90_PATH_A + : RF90_PATH_B; + u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; + bool need_pwr_down = false, internal_pa = false; + u32 regb30 = rtl_get_bbreg(hw, 0xb30, BIT(27)); + u8 index = 0, i, rfpath; + + if (rtlusb->udev->speed != USB_SPEED_HIGH) + return; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n"); + /* config path A for 5G */ + if (rtlhal->current_bandtype == BAND_ON_5G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); + u4tmp = rtlpriv->curveindex_5g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); + + for (i = 0; i < RF_CHNL_NUM_5G; i++) { + if (channel == rf_chnl_5g[i] && channel <= 140) + index = 0; + } + for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) { + if (channel == rf_chnl_5g_40m[i] && channel <= 140) + index = 1; + } + if (channel == 149 || channel == 155 || channel == 161) + index = 2; + else if (channel == 151 || channel == 153 || channel == 163 || + channel == 165) + index = 3; + else if (channel == 157 || channel == 159) + index = 4; + + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) { + need_pwr_down = rtl92du_phy_enable_anotherphy(hw, false); + rtlhal->during_mac1init_radioa = true; + /* asume no this case */ + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + + /* DMDP, if band = 5G, Mac0 need to set PHY1 when regB30[27]=1 */ + if (regb30 && rtlhal->interfaceindex == 0) { + need_pwr_down = rtl92du_phy_enable_anotherphy(hw, true); + rtlhal->during_mac0init_radiob = true; + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) { + if (i == 0 && rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, 0xE439D); + } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) { + u4tmp2 = (rf_reg_pram_c_5g[index][i] & + 0x7FF) | (u4tmp << 11); + if (channel == 36) + u4tmp2 &= ~(BIT(7) | BIT(6)); + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, u4tmp2); + } else { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK, + rf_reg_pram_c_5g[index][i]); + } + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "offset 0x%x value 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], + path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + RFREG_OFFSET_MASK)); + } + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) { + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + + rtl92du_phy_powerdown_anotherphy(hw, false); + } + + if (regb30 && rtlhal->interfaceindex == 0) { + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + + rtl92du_phy_powerdown_anotherphy(hw, true); + } + + if (channel < 149) + value = 0x07; + else if (channel >= 149) + value = 0x02; + if (channel >= 36 && channel <= 64) + index = 0; + else if (channel >= 100 && channel <= 140) + index = 1; + else + index = 2; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) /* MAC 1 5G */ + internal_pa = rtlpriv->efuse.internal_pa_5g[1]; + else + internal_pa = + rtlpriv->efuse.internal_pa_5g[rfpath]; + + if (internal_pa) { + for (i = 0; + i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA; + i++) { + if (rf_for_c_cut_5g_internal_pa[i] == 0x03 && + channel >= 36 && channel <= 64) + rtl_set_rfreg(hw, rfpath, + rf_for_c_cut_5g_internal_pa[i], + RFREG_OFFSET_MASK, + 0x7bdef); + else + rtl_set_rfreg(hw, rfpath, + rf_for_c_cut_5g_internal_pa[i], + RFREG_OFFSET_MASK, + rf_pram_c_5g_int_pa[index][i]); + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "offset 0x%x value 0x%x path %d index %d\n", + rf_for_c_cut_5g_internal_pa[i], + rf_pram_c_5g_int_pa[index][i], + rfpath, index); + } + } else { + rtl_set_rfreg(hw, (enum radio_path)rfpath, RF_TXPA_AG, + mask, value); + } + } + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); + u4tmp = rtlpriv->curveindex_2g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); + + if (channel == 1 || channel == 2 || channel == 4 || + channel == 9 || channel == 10 || channel == 11 || + channel == 12) + index = 0; + else if (channel == 3 || channel == 13 || channel == 14) + index = 1; + else if (channel >= 5 && channel <= 8) + index = 2; + + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + path = RF90_PATH_A; + if (rtlhal->interfaceindex == 0) { + need_pwr_down = + rtl92du_phy_enable_anotherphy(hw, true); + rtlhal->during_mac0init_radiob = true; + + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + + /* DMDP, if band = 2G, MAC1 need to set PHY0 when regB30[27]=1 */ + if (regb30 && rtlhal->interfaceindex == 1) { + need_pwr_down = + rtl92du_phy_enable_anotherphy(hw, false); + rtlhal->during_mac1init_radioa = true; + + if (need_pwr_down) + rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + } + + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) { + if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7) + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK, + rf_reg_param_for_c_cut_2g[index][i] | + BIT(17)); + else + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK, + rf_reg_param_for_c_cut_2g + [index][i]); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + RFREG_OFFSET_MASK)); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); + + rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, + RFREG_OFFSET_MASK, + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); + + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 0) { + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + + rtl92du_phy_powerdown_anotherphy(hw, true); + } + + if (regb30 && rtlhal->interfaceindex == 1) { + if (need_pwr_down) + rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + + rtl92du_phy_powerdown_anotherphy(hw, false); + } + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92du_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 regeac, rege94, rege9c, regea4; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); + + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1f); + } else { + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c22); + } + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, + configpathb ? 0x28160202 : 0x28160502); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160206); + } + + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path A LOK & IQK\n", + IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME); + + /* Check failed */ + regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + rege94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); + rege9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); + regea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); + + if (!(regeac & BIT(28)) && + (((rege94 & 0x03FF0000) >> 16) != 0x142) && + (((rege9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & BIT(27)) && + (((regea4 & 0x03FF0000) >> 16) != 0x132) && + (((regeac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92du_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, + bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 TXOKBIT = BIT(28), RXOKBIT = BIT(27); + u32 regeac, rege94, rege9c, regea4; + u8 timeout = 20, timecount = 0; + u8 retrycount = 2; + u8 result = 0; + u8 i; + + if (rtlhal->interfaceindex == 1) { /* PHY1 */ + TXOKBIT = BIT(31); + RXOKBIT = BIT(30); + } + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140307); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160960); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68110000); + } + + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /* path-A PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x07000f60); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, 0x66e60e30); + + for (i = 0; i < retrycount; i++) { + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME * 10); + + while (timecount < timeout && + rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, BIT(26)) == 0) { + udelay(IQK_DELAY_TIME * 1000 * 2); + timecount++; + } + + timecount = 0; + while (timecount < timeout && + rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASK_IQK_RESULT) == 0) { + udelay(IQK_DELAY_TIME * 1000 * 2); + timecount++; + } + + /* Check failed */ + regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + rege94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); + rege9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); + regea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); + + if (!(regeac & TXOKBIT) && + (((rege94 & 0x03FF0000) >> 16) != 0x142)) { + result |= 0x01; + } else { /* if Tx not OK, ignore Rx */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A Tx IQK fail!!\n"); + continue; + } + + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & RXOKBIT) && + (((regea4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); + } + + /* path A PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, + rtlphy->iqk_bb_backup[1]); + + if (!(result & 0x01)) /* Tx IQK fail */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x19008c00); + + if (!(result & 0x02)) { /* Rx IQK fail */ + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x19008c00); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A Rx IQK fail!! 0xe34 = %#x\n", + rtl_get_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD)); + } + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92du_phy_pathb_iqk(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 regeac, regeb4, regebc, regec4, regecc; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path B LOK & IQK!\n"); + rtl_set_bbreg(hw, RIQK_AGC_CONT, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, RIQK_AGC_CONT, MASKDWORD, 0x00000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); + mdelay(IQK_DELAY_TIME); + + /* Check failed */ + regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + regeb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); + regebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); + regec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); + regecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); + + if (!(regeac & BIT(31)) && + (((regeb4 & 0x03FF0000) >> 16) != 0x142) && + (((regebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(regeac & BIT(30)) && + (((regec4 & 0x03FF0000) >> 16) != 0x132) && + (((regecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92du_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 regeac, regeb4, regebc, regec4, regecc; + u8 timeout = 20, timecount = 0; + u8 retrycount = 2; + u8 result = 0; + u8 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-B IQK setting!\n"); + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68110000); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82140307); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160960); + + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /* path-B PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x0f600700); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, 0x061f0d30); + + for (i = 0; i < retrycount; i++) { + /* One shot, path B LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "One shot, path A LOK & IQK!\n"); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Delay %d ms for One shot, path B LOK & IQK.\n", 10); + mdelay(IQK_DELAY_TIME * 10); + + while (timecount < timeout && + rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, BIT(29)) == 0) { + udelay(IQK_DELAY_TIME * 1000 * 2); + timecount++; + } + + timecount = 0; + while (timecount < timeout && + rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASK_IQK_RESULT) == 0) { + udelay(IQK_DELAY_TIME * 1000 * 2); + timecount++; + } + + /* Check failed */ + regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); + regeb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); + regebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); + regec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); + regecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); + + if (!(regeac & BIT(31)) && + (((regeb4 & 0x03FF0000) >> 16) != 0x142)) + result |= 0x01; + else + continue; + + if (!(regeac & BIT(30)) && + (((regec4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); + } + + /* path B PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, + rtlphy->iqk_bb_backup[2]); + + if (!(result & 0x01)) + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x19008c00); + + if (!(result & 0x02)) { + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x19008c00); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Rx IQK fail!! 0xe54 = %#x\n", + rtl_get_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD)); + } + + return result; +} + +static void _rtl92du_phy_reload_adda_registers(struct ieee80211_hw *hw, + const u32 *adda_reg, + u32 *adda_backup, u32 regnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Reload ADDA power saving parameters !\n"); + for (i = 0; i < regnum; i++) { + /* path-A/B BB to initial gain */ + if (adda_reg[i] == ROFDM0_XAAGCCORE1 || + adda_reg[i] == ROFDM0_XBAGCCORE1) + rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, 0x50); + + rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, adda_backup[i]); + } +} + +static void _rtl92du_phy_reload_mac_registers(struct ieee80211_hw *hw, + const u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n"); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92du_phy_patha_standby(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); + + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x0); + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000); +} + +static void _rtl92du_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 mode; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, MASKDWORD, mode); + rtl_set_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, MASKDWORD, mode); +} + +static void _rtl92du_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], + u8 t, bool is2t) +{ + static const u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, RBLUE_TOOTH, RRX_WAIT_CCA, + RTX_CCK_RFON, RTX_CCK_BBON, RTX_OFDM_RFON, RTX_OFDM_BBON, + RTX_TO_RX, RTX_TO_TX, RRX_CCK, RRX_OFDM, RRX_WAIT_RIFS, + RRX_TO_RX, RSTANDBY, RSLEEP, RPMPD_ANAEN + }; + static const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, REG_BCN_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + const u32 retrycount = 2; + u8 patha_ok, pathb_ok; + u32 bbvalue; + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); + + /* Save ADDA parameters, turn Path A ADDA on */ + rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + } + rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t); + + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038); + + if (t == 0) + rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92du_phy_pimode_switch(hw, true); + + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN, 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22204000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + if (is2t) { + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, + 0x00010000); + rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, MASKDWORD, + 0x00010000); + } + + /* MAC settings */ + rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + + /* Page B init */ + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x0f600000); + + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92du_phy_patha_iqk(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Success!!\n"); + result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, + MASK_IQK_RESULT); + result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, + MASK_IQK_RESULT); + result[t][2] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, + MASK_IQK_RESULT); + result[t][3] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, + MASK_IQK_RESULT); + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Only Tx Success!!\n"); + + result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, + MASK_IQK_RESULT); + result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, + MASK_IQK_RESULT); + } + } + if (patha_ok == 0x00) + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n"); + + if (is2t) { + _rtl92du_phy_patha_standby(hw); + /* Turn Path B ADDA on */ + rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92du_phy_pathb_iqk(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK Success!!\n"); + result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, + MASK_IQK_RESULT); + result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, + MASK_IQK_RESULT); + result[t][6] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, + MASK_IQK_RESULT); + result[t][7] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, + MASK_IQK_RESULT); + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Only Tx IQK Success!!\n"); + result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, + MASK_IQK_RESULT); + result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, + MASK_IQK_RESULT); + } + } + if (pathb_ok == 0x00) + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK failed!!\n"); + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Back to BB mode, load original value!\n"); + + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x000000); + + if (t != 0) { + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92du_phy_pimode_switch(hw, false); + + /* Reload ADDA power saving parameters */ + _rtl92du_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + + /* Reload MAC parameters */ + _rtl92du_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + + if (is2t) + _rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + + /* load 0xe30 IQC default value */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); +} + +static void _rtl92du_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, + long result[][8], u8 t) +{ + static const u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, RBLUE_TOOTH, RRX_WAIT_CCA, + RTX_CCK_RFON, RTX_CCK_BBON, RTX_OFDM_RFON, RTX_OFDM_BBON, + RTX_TO_RX, RTX_TO_TX, RRX_CCK, RRX_OFDM, RRX_WAIT_RIFS, + RRX_TO_RX, RSTANDBY, RSLEEP, RPMPD_ANAEN + }; + static const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, REG_BCN_CTRL_1, REG_GPIO_MUXCFG + }; + static const u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + u8 patha_ok, pathb_ok; + bool rf_path_div; + u32 bbvalue; + + /* Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt + */ + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); + + mdelay(IQK_DELAY_TIME * 20); + + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); + + /* Save ADDA parameters, turn Path A ADDA on */ + rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (is2t) + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + } + + rf_path_div = rtl_get_bbreg(hw, 0xb30, BIT(27)); + rtl92d_phy_path_adda_on(hw, adda_reg, !rf_path_div, is2t); + + if (t == 0) + rtlphy->rfpi_enable = rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92du_phy_pimode_switch(hw, true); + + /* MAC settings */ + rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + + rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN, 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + + /* Page A AP setting for IQK */ + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0); + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000); + if (is2t) { + /* Page B AP setting for IQK */ + rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0); + rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x20000000); + } + + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x10007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + patha_ok = _rtl92du_phy_patha_iqk_5g_normal(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); + result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, + MASK_IQK_RESULT); + result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, + MASK_IQK_RESULT); + result[t][2] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, + MASK_IQK_RESULT); + result[t][3] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, + MASK_IQK_RESULT); + } else if (patha_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQK Only Tx Success!!\n"); + + result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, + MASK_IQK_RESULT); + result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, + MASK_IQK_RESULT); + } else { + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x000000); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe70 = %#x\n", + rtl_get_bbreg(hw, RRX_WAIT_CCA, MASKDWORD)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "RF path A 0x0 = %#x\n", + rtl_get_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK)); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); + } + + if (is2t) { + /* _rtl92d_phy_patha_standby(hw); */ + /* Turn Path B ADDA on */ + rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + + pathb_ok = _rtl92du_phy_pathb_iqk_5g_normal(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK Success!!\n"); + result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, + MASK_IQK_RESULT); + result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, + MASK_IQK_RESULT); + result[t][6] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, + MASK_IQK_RESULT); + result[t][7] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, + MASK_IQK_RESULT); + } else if (pathb_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B Only Tx IQK Success!!\n"); + result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, + MASK_IQK_RESULT); + result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, + MASK_IQK_RESULT); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQK failed!!\n"); + } + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Back to BB mode, load original value!\n"); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0); + + if (is2t) + _rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + + /* path A IQ path to DP block */ + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x010170b8); + if (is2t) /* path B IQ path to DP block */ + rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x010170b8); + + /* Reload MAC parameters */ + _rtl92du_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92du_phy_pimode_switch(hw, false); + + /* Reload ADDA power saving parameters */ + _rtl92du_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); +} + +static bool _rtl92du_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 i, j, diff, sim_bitmap, bound, u4temp = 0; + u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + bool bresult = true; + + if (is2t) + bound = 8; + else + bound = 4; + + sim_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = abs_diff(result[c1][i], result[c2][i]); + + if (diff > MAX_TOLERANCE_92D) { + if ((i == 2 || i == 6) && !sim_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + sim_bitmap = sim_bitmap | (1 << i); + } else { + sim_bitmap = sim_bitmap | (1 << i); + } + } + } + + if (sim_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + + for (i = 0; i < bound; i++) + u4temp += result[c1][i] + result[c2][i]; + + if (u4temp == 0) /* IQK fail for c1 & c2 */ + bresult = false; + + return bresult; + } + + if (!(sim_bitmap & 0x0F)) { /* path A OK */ + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + + if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */ + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + + return false; +} + +static void _rtl92du_phy_patha_fill_iqk_matrix_5g_normal(struct ieee80211_hw *hw, + bool iqk_ok, + long result[][8], + u8 final_candidate, + bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 val_x, reg; + int val_y; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); + if (iqk_ok && final_candidate != 0xFF) { + val_x = result[final_candidate][0]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x\n", val_x); + rtl_set_bbreg(hw, RTX_IQK_TONE_A, 0x3FF0000, val_x); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0); + + val_y = result[final_candidate][1]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + + /* path B IQK result + 3 */ + if (rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%x\n", val_y); + + rtl_set_bbreg(hw, RTX_IQK_TONE_A, 0x3FF, val_y); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), 0); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe30 = 0x%x\n", + rtl_get_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD)); + + if (txonly) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); + return; + } + + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "%s: Tx/Rx fail restore default value\n", __func__); + + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x19008c00); + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x19008c00); + } +} + +static void _rtl92du_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 oldval_0, val_x, tx0_a, reg; + long val_y, tx0_c; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version) || + rtlhal->macphymode == DUALMAC_DUALPHY; + + if (rtlhal->current_bandtype == BAND_ON_5G) { + _rtl92du_phy_patha_fill_iqk_matrix_5g_normal(hw, iqk_ok, result, + final_candidate, + txonly); + return; + } + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); + if (final_candidate == 0xFF || !iqk_ok) + return; + + /* OFDM0_D */ + oldval_0 = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0xffc00000); + + val_x = result[final_candidate][0]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + + tx0_a = (val_x * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n", + val_x, tx0_a, oldval_0); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + ((val_x * oldval_0 >> 7) & 0x1)); + + val_y = result[final_candidate][1]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + + /* path B IQK result + 3 */ + if (rtlhal->interfaceindex == 1 && + rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + + tx0_c = (val_y * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, (tx0_c & 0x3C0) >> 6); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, tx0_c & 0x3F); + if (is2t) + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), + (val_y * oldval_0 >> 7) & 0x1); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD)); + + if (txonly) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); + return; + } + + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg); +} + +static void _rtl92du_phy_pathb_fill_iqk_matrix_5g_normal(struct ieee80211_hw *hw, + bool iqk_ok, + long result[][8], + u8 final_candidate, + bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 val_x, reg; + int val_y; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Path B IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); + if (iqk_ok && final_candidate != 0xFF) { + val_x = result[final_candidate][4]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x\n", val_x); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, 0x3FF0000, val_x); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), 0); + + val_y = result[final_candidate][5]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + + /* path B IQK result + 3 */ + if (rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%x\n", val_y); + + rtl_set_bbreg(hw, RTX_IQK_TONE_B, 0x3FF, val_y); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30), 0); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe50 = 0x%x\n", + rtl_get_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD)); + + if (txonly) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); + return; + } + + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "%s: Tx/Rx fail restore default value\n", __func__); + + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x19008c00); + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x19008c00); + } +} + +static void _rtl92du_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 oldval_1, val_x, tx1_a, reg; + long val_y, tx1_c; + + if (rtlhal->current_bandtype == BAND_ON_5G) { + _rtl92du_phy_pathb_fill_iqk_matrix_5g_normal(hw, iqk_ok, result, + final_candidate, + txonly); + return; + } + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n", + iqk_ok ? "Success" : "Failed"); + + if (final_candidate == 0xFF || !iqk_ok) + return; + + oldval_1 = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0xffc00000); + + val_x = result[final_candidate][4]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + + tx1_a = (val_x * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), + (val_x * oldval_1 >> 7) & 0x1); + + val_y = result[final_candidate][5]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + + if (rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + + tx1_c = (val_y * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c); + + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, (tx1_c & 0x3C0) >> 6); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, tx1_c & 0x3F); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30), + (val_y * oldval_1 >> 7) & 0x1); + + if (txonly) + return; + + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); +} + +void rtl92du_phy_iq_calibrate(struct ieee80211_hw *hw) +{ + long rege94, rege9c, regea4, regeac, regeb4; + bool is12simular, is13simular, is23simular; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + long regebc, regec4, regecc, regtmp = 0; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i, final_candidate, indexforchannel; + bool patha_ok, pathb_ok; + long result[4][8] = {}; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK:Start!!!channel %d\n", rtlphy->current_channel); + + final_candidate = 0xff; + patha_ok = false; + pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK !!!currentband %d\n", rtlhal->current_bandtype); + + for (i = 0; i < 3; i++) { + if (rtlhal->current_bandtype == BAND_ON_5G) { + _rtl92du_phy_iq_calibrate_5g_normal(hw, result, i); + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (IS_92D_SINGLEPHY(rtlhal->version)) + _rtl92du_phy_iq_calibrate(hw, result, i, true); + else + _rtl92du_phy_iq_calibrate(hw, result, i, false); + } + + if (i == 1) { + is12simular = _rtl92du_phy_simularity_compare(hw, result, + 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + + if (i == 2) { + is13simular = _rtl92du_phy_simularity_compare(hw, result, + 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + + is23simular = _rtl92du_phy_simularity_compare(hw, result, + 1, 2); + if (is23simular) { + final_candidate = 1; + } else { + for (i = 0; i < 8; i++) + regtmp += result[3][i]; + + if (regtmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + + for (i = 0; i < 4; i++) { + rege94 = result[i][0]; + rege9c = result[i][1]; + regea4 = result[i][2]; + regeac = result[i][3]; + regeb4 = result[i][4]; + regebc = result[i][5]; + regec4 = result[i][6]; + regecc = result[i][7]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc); + } + + if (final_candidate != 0xff) { + rege94 = result[final_candidate][0]; + rtlphy->reg_e94 = rege94; + rege9c = result[final_candidate][1]; + rtlphy->reg_e9c = rege9c; + regea4 = result[final_candidate][2]; + regeac = result[final_candidate][3]; + regeb4 = result[final_candidate][4]; + rtlphy->reg_eb4 = regeb4; + regebc = result[final_candidate][5]; + rtlphy->reg_ebc = regebc; + regec4 = result[final_candidate][6]; + regecc = result[final_candidate][7]; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: final_candidate is %x\n", final_candidate); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc); + + patha_ok = true; + pathb_ok = true; + } else { + rtlphy->reg_e94 = 0x100; + rtlphy->reg_eb4 = 0x100; /* X default value */ + rtlphy->reg_e9c = 0x0; + rtlphy->reg_ebc = 0x0; /* Y default value */ + } + if (rege94 != 0 /*&& regea4 != 0*/) + _rtl92du_phy_patha_fill_iqk_matrix(hw, patha_ok, result, + final_candidate, + regea4 == 0); + if (IS_92D_SINGLEPHY(rtlhal->version) && + regeb4 != 0 /*&& regec4 != 0*/) + _rtl92du_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result, + final_candidate, + regec4 == 0); + + if (final_candidate != 0xFF) { + indexforchannel = + rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel); + + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix[indexforchannel].value[0][i] = + result[final_candidate][i]; + + rtlphy->iqk_matrix[indexforchannel].iqk_done = true; + + rtl_dbg(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, + "IQK OK indexforchannel %d\n", indexforchannel); + } +} + +void rtl92du_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 indexforchannel; + bool need_iqk; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel); + /*------Do IQK for normal chip and test chip 5G band------- */ + + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", + indexforchannel, + rtlphy->iqk_matrix[indexforchannel].iqk_done); + + /* We need to do IQK if we're about to connect to a network on 5 GHz. + * On 5 GHz a channel switch outside of scanning happens only before + * connecting. + */ + need_iqk = !mac->act_scanning; + + if (!rtlphy->iqk_matrix[indexforchannel].iqk_done && need_iqk) { + rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, + "Do IQK Matrix reg for channel:%d....\n", channel); + rtl92du_phy_iq_calibrate(hw); + return; + } + + /* Just load the value. */ + /* 2G band just load once. */ + if ((!rtlhal->load_imrandiqk_setting_for2g && indexforchannel == 0) || + indexforchannel > 0) { + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Just Read IQK Matrix reg for channel:%d....\n", + channel); + + if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0) + _rtl92du_phy_patha_fill_iqk_matrix(hw, true, + rtlphy->iqk_matrix[indexforchannel].value, 0, + rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0); + + if (IS_92D_SINGLEPHY(rtlhal->version) && + rtlphy->iqk_matrix[indexforchannel].value[0][4] != 0) + _rtl92du_phy_pathb_fill_iqk_matrix(hw, true, + rtlphy->iqk_matrix[indexforchannel].value, 0, + rtlphy->iqk_matrix[indexforchannel].value[0][6] == 0); + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92du_phy_reload_lck_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u8 erfpath = rtlhal->current_bandtype == BAND_ON_5G ? RF90_PATH_A : + IS_92D_SINGLEPHY(rtlhal->version) ? RF90_PATH_B : RF90_PATH_A; + bool bneed_powerdown_radio = false; + u32 u4tmp, u4regvalue; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n", + rtlpriv->rtlhal.current_bandtype); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel); + + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ + u4tmp = rtlpriv->curveindex_5g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); + + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 1) { + bneed_powerdown_radio = + rtl92du_phy_enable_anotherphy(hw, false); + rtlpriv->rtlhal.during_mac1init_radioa = true; + /* asume no this case */ + if (bneed_powerdown_radio) + rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + + if (bneed_powerdown_radio) { + rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + rtl92du_phy_powerdown_anotherphy(hw, false); + } + } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { + u4tmp = rtlpriv->curveindex_2g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); + + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 0) { + bneed_powerdown_radio = + rtl92du_phy_enable_anotherphy(hw, true); + rtlpriv->rtlhal.during_mac0init_radiob = true; + if (bneed_powerdown_radio) + rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); + + if (bneed_powerdown_radio) { + rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + rtl92du_phy_powerdown_anotherphy(hw, true); + } + } + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); +} + +static void _rtl92du_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 curvecount_val[CV_CURVE_CNT * 2]; + u16 timeout = 800, timecount = 0; + u32 u4tmp, offset, rf_syn_g4[2]; + u8 tmpreg, index, rf_mode[2]; + u8 path = is2t ? 2 : 1; + u8 i; + + /* Check continuous TX and Packet TX */ + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + if ((tmpreg & 0x70) != 0) + /* if Deal with contisuous TX case, disable all continuous TX */ + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + /* if Deal with Packet TX case, block all queues */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F); + + for (index = 0; index < path; index++) { + /* 1. Read original RF mode */ + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rf_mode[index] = rtl_read_byte(rtlpriv, offset); + + /* 2. Set RF mode = standby mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_AC, + RFREG_OFFSET_MASK, 0x010000); + + rf_syn_g4[index] = rtl_get_rfreg(hw, index, RF_SYN_G4, + RFREG_OFFSET_MASK); + rtl_set_rfreg(hw, index, RF_SYN_G4, 0x700, 0x7); + + /* switch CV-curve control by LC-calibration */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x0); + + /* 4. Set LC calibration begin */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x01); + } + + for (index = 0; index < path; index++) { + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6, + RFREG_OFFSET_MASK); + + while ((!(u4tmp & BIT(11))) && timecount <= timeout) { + mdelay(50); + timecount += 50; + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, + RF_SYN_G6, RFREG_OFFSET_MASK); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "PHY_LCK finish delay for %d ms=2\n", timecount); + } + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + else /* Deal with Packet TX case */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00); + + for (index = 0; index < path; index++) { + rtl_get_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK); + + if (index == 0 && rtlhal->interfaceindex == 0) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "path-A / 5G LCK\n"); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "path-B / 2.4G LCK\n"); + } + + memset(curvecount_val, 0, sizeof(curvecount_val)); + + /* Set LC calibration off */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x0); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n"); + + /* save Curve-counting number */ + for (i = 0; i < CV_CURVE_CNT; i++) { + u32 readval = 0, readval2 = 0; + + rtl_set_rfreg(hw, (enum radio_path)index, 0x3F, + 0x7f, i); + + rtl_set_rfreg(hw, (enum radio_path)index, 0x4D, + RFREG_OFFSET_MASK, 0x0); + + readval = rtl_get_rfreg(hw, (enum radio_path)index, + 0x4F, RFREG_OFFSET_MASK); + curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5; + + /* reg 0x4f [4:0] */ + /* reg 0x50 [19:10] */ + readval2 = rtl_get_rfreg(hw, (enum radio_path)index, + 0x50, 0xffc00); + curvecount_val[2 * i] = (((readval & 0x1F) << 10) | + readval2); + } + + if (index == 0 && rtlhal->interfaceindex == 0) + rtl92d_phy_calc_curvindex(hw, targetchnl_5g, + curvecount_val, + true, rtlpriv->curveindex_5g); + else + rtl92d_phy_calc_curvindex(hw, targetchnl_2g, + curvecount_val, + false, rtlpriv->curveindex_2g); + + /* switch CV-curve control mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x1); + } + + /* Restore original situation */ + for (index = 0; index < path; index++) { + rtl_set_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK, + rf_syn_g4[index]); + + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rtl_write_byte(rtlpriv, offset, 0x50); + rtl_write_byte(rtlpriv, offset, rf_mode[index]); + } + + _rtl92du_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel); +} + +void rtl92du_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); + + _rtl92du_phy_lc_calibrate_sw(hw, is2t); + + rtlphy->lck_inprogress = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n"); +} + +u8 rtl92du_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + u8 channel = rtlphy->current_channel; + u32 timeout = 1000, timecount = 0; + u32 ret_value; + u8 rfpath; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + return 0; + } + + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && + rtlhal->bandset == BAND_ON_BOTH) { + ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + MASKDWORD); + if (rtlphy->current_channel > 14 && !(ret_value & BIT(0))) + rtl92du_phy_switch_wirelessband(hw, BAND_ON_5G); + else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0))) + rtl92du_phy_switch_wirelessband(hw, BAND_ON_2_4G); + } + + switch (rtlhal->current_bandtype) { + case BAND_ON_5G: + /* Get first channel error when change between + * 5G and 2.4G band. + */ + if (WARN_ONCE(channel <= 14, "rtl8192du: 5G but channel<=14\n")) + return 0; + break; + case BAND_ON_2_4G: + /* Get first channel error when change between + * 5G and 2.4G band. + */ + if (WARN_ONCE(channel > 14, "rtl8192du: 2G but channel>14\n")) + return 0; + break; + default: + WARN_ONCE(true, "rtl8192du: Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode); + break; + } + + rtlphy->sw_chnl_inprogress = true; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + + rtl92d_phy_set_txpower_level(hw, channel); + + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + u32p_replace_bits(&rtlphy->rfreg_chnlval[rfpath], + channel, 0xff); + + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { + if (channel > 99) + rtlphy->rfreg_chnlval[rfpath] |= (BIT(18)); + else + rtlphy->rfreg_chnlval[rfpath] &= ~BIT(18); + rtlphy->rfreg_chnlval[rfpath] |= (BIT(16) | BIT(8)); + } else { + rtlphy->rfreg_chnlval[rfpath] &= + ~(BIT(8) | BIT(16) | BIT(18)); + } + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + + _rtl92du_phy_reload_imr_setting(hw, channel, rfpath); + } + + _rtl92du_phy_switch_rf_setting(hw, channel); + + /* do IQK when all parameters are ready */ + rtl92du_phy_reload_iqk_setting(hw, channel); + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +static void _rtl92du_phy_set_rfon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* a. SYS_CLKR 0x08[11] = 1 restore MAC clock */ + /* b. SPS_CTRL 0x11[7:0] = 0x2b */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + + /* c. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + + /* RF_ON_EXCEP(d~g): */ + /* d. APSD_CTRL 0x600[7:0] = 0x00 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + + /* e. SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function again */ + /* f. SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function*/ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + + /* g. txpause 0x522[7:0] = 0x00 enable mac tx queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92du_phy_set_rfsleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 u4btmp; + u8 retry = 5; + + /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + /* b. RF path 0 offset 0x00 = 0x00 disable RF */ + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + + /* c. APSD_CTRL 0x600[7:0] = 0x40 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + + /* d. APSD_CTRL 0x600[7:0] = 0x00 + * APSD_CTRL 0x600[7:0] = 0x00 + * RF path 0 offset 0x00 = 0x00 + * APSD_CTRL 0x600[7:0] = 0x40 + */ + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4btmp != 0 && retry > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + retry--; + } + if (retry == 0) { + /* Jump out the LPS turn off sequence to RF_ON_EXCEP */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Fail !!! Switch RF timeout\n"); + return; + } + + /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + + /* f. SPS_CTRL 0x11[7:0] = 0x22 */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +bool rtl92du_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + bool bresult = true; + + if (rfpwr_state == ppsc->rfpwr_state) + return false; + + switch (rfpwr_state) { + case ERFON: + if (ppsc->rfpwr_state == ERFOFF && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + u32 initializecount = 0; + bool rtstatus; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "awake, slept:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_awake_jiffies = jiffies; + _rtl92du_phy_set_rfon(hw); + } + + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + break; + case ERFOFF: + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + return false; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awakened:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_sleep_jiffies = jiffies; + _rtl92du_phy_set_rfsleep(hw); + break; + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + return false; + } + + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + + return bresult; +} + +void rtl92du_phy_set_poweron(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1); + u8 value8; + u16 i; + + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, mac_reg, value8); + } else { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 &= ~BIT(1); + rtl_write_byte(rtlpriv, mac_reg, value8); + } + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + mutex_lock(rtlpriv->mutex_for_power_on_off); + if (rtlhal->interfaceindex == 0) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + value8 = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON); + } + value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + mutex_unlock(rtlpriv->mutex_for_power_on_off); + + for (i = 0; i < 200; i++) { + if ((value8 & BIT(7)) == 0) + break; + + udelay(500); + mutex_lock(rtlpriv->mutex_for_power_on_off); + value8 = rtl_read_byte(rtlpriv, + REG_POWER_OFF_IN_PROCESS); + mutex_unlock(rtlpriv->mutex_for_power_on_off); + } + if (i == 200) + WARN_ONCE(true, "rtl8192du: Another mac power off over time\n"); + } +} + +void rtl92du_update_bbrf_configuration(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rfpath, i; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); + /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* r_select_5G for path_A/B, 0x878 */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0); + } + + /* rssi_table_select: index 0 for 2.4G. 1~3 for 5G, 0xc78 */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0); + + /* fc_area 0xd2c */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0); + + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa); + + /* TX BB gain shift*1, Just for testchip, 0xc80, 0xc88 */ + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, 0x40000100); + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0); + + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038); + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4) | + ((rtlefuse->eeprom_c9 & BIT(7)) << 9) | + ((rtlefuse->eeprom_c9 & BIT(5)) << 12) | + ((rtlefuse->eeprom_cc & BIT(3)) << 18)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) | + ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) | + ((rtlefuse->eeprom_cc & BIT(2)) << 3)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), 0); + + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038); + rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x01017038); + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000); + rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x0f600000); + } + /* 1.5V_LDO */ + } else { + /* r_select_5G for path_A/B */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1); + } + + /* rssi_table_select: index 0 for 2.4G. 1~3 for 5G */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1); + + /* fc_area */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1); + + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0); + + /* TX BB gain shift, Just for testchip, 0xc80, 0xc88 */ + if (rtlefuse->internal_pa_5g[rtlhal->interfaceindex]) + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + 0x20000080); + + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + if (rtlefuse->internal_pa_5g[1]) + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, 0x20000080); + } + + rtl_set_bbreg(hw, 0xB30, BIT(27), 0); + + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5))); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), + (rtlefuse->eeprom_cc & BIT(4)) >> 4); + + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017098); + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5)) | + ((rtlefuse->eeprom_cc & BIT(7)) << 14)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(6)) >> 6)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4) | + ((rtlefuse->eeprom_cc & BIT(6)) << 10)); + + rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017098); + rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x01017098); + rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000); + rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x20000000); + } + } + + /* update IQK related settings */ + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) | + BIT(26) | BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00); + + /* Update RF */ + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* MOD_AG for RF path_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) | + BIT(18) | 0xff, 1); + + /* RF0x0b[16:14] =3b'111 */ + rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, + 0x1c000, 0x07); + } else { + /* MOD_AG for RF path_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + 0x97524); + } + + /* Set right channel on RF reg0x18 for another mac. */ + if (rtlhal->interfaceindex == 0 && rtlhal->bandset == BAND_ON_2_4G) { + /* Set MAC1 default channel if MAC1 not up. */ + if (!(rtl_read_byte(rtlpriv, REG_MAC1) & MAC1_ON)) { + rtl92du_phy_enable_anotherphy(hw, true); + rtlhal->during_mac0init_radiob = true; + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, + RFREG_OFFSET_MASK, 0x97524); + rtl92du_phy_powerdown_anotherphy(hw, true); + } + } else if (rtlhal->interfaceindex == 1 && rtlhal->bandset == BAND_ON_5G) { + /* Set MAC0 default channel */ + if (!(rtl_read_byte(rtlpriv, REG_MAC0) & MAC0_ON)) { + rtl92du_phy_enable_anotherphy(hw, false); + rtlhal->during_mac1init_radioa = true; + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, + RFREG_OFFSET_MASK, 0x87401); + rtl92du_phy_powerdown_anotherphy(hw, false); + } + } + } + + /* Update for all band. */ + /* DMDP */ + if (rtlphy->rf_type == RF_1T1R) { + /* Use antenna 0, 0xc04, 0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x11); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1); + + /* enable ad/da clock1 for dual-phy reg0x888 */ + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | + BIT(13), 0x3); + } else if (rtl92du_phy_enable_anotherphy(hw, false)) { + rtlhal->during_mac1init_radioa = true; + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, + BIT(12) | BIT(13), 0x3); + rtl92du_phy_powerdown_anotherphy(hw, false); + } + + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(19) | BIT(20), 0x0); + } else { + /* Single PHY */ + /* Use antenna 0 & 1, 0xc04, 0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3); + /* disable ad/da clock1,0x888 */ + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0); + + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(19) | BIT(20), 0x1); + } + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath, + RF_CHNLBW, + RFREG_OFFSET_MASK); + rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C, + RFREG_OFFSET_MASK); + } + + for (i = 0; i < 2; i++) + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i]); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n"); +} + +bool rtl92du_phy_check_poweroff(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1btmp; + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & ~MAC0_ON); + return true; + } + + mutex_lock(rtlpriv->mutex_for_power_on_off); + if (rtlhal->interfaceindex == 0) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & ~MAC0_ON); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + u1btmp &= MAC1_ON; + } else { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & ~MAC1_ON); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + u1btmp &= MAC0_ON; + } + if (u1btmp) { + mutex_unlock(rtlpriv->mutex_for_power_on_off); + return false; + } + u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1btmp |= BIT(7); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp); + mutex_unlock(rtlpriv->mutex_for_power_on_off); + + return true; +} + +void rtl92du_phy_init_pa_bias(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + bool is_single_mac = rtlhal->macphymode == SINGLEMAC_SINGLEPHY; + enum radio_path rf_path; + u8 val8; + + read_efuse_byte(hw, 0x3FA, &val8); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "%s: 0x3FA %#x\n", + __func__, val8); + + if (!(val8 & BIT(0)) && (is_single_mac || rtlhal->interfaceindex == 0)) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x07401); + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F425); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F425); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F425); + + /* Back to RX Mode */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x30000); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "2G PA BIAS path A\n"); + } + + if (!(val8 & BIT(1)) && (is_single_mac || rtlhal->interfaceindex == 1)) { + rf_path = rtlhal->interfaceindex == 1 ? RF90_PATH_A : RF90_PATH_B; + + rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x07401); + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F425); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F425); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F425); + + /* Back to RX Mode */ + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x30000); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "2G PA BIAS path B\n"); + } + + if (!(val8 & BIT(2)) && (is_single_mac || rtlhal->interfaceindex == 0)) { + /* 5GL_channel */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x17524); + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* 5GM_channel */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x37564); + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* 5GH_channel */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x57595); + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* Back to RX Mode */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x30000); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "5G PA BIAS path A\n"); + } + + if (!(val8 & BIT(3)) && (is_single_mac || rtlhal->interfaceindex == 1)) { + rf_path = rtlhal->interfaceindex == 1 ? RF90_PATH_A : RF90_PATH_B; + + /* 5GL_channel */ + rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x17524); + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* 5GM_channel */ + rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x37564); + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* 5GH_channel */ + rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x57595); + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496); + rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496); + + /* Back to RX Mode */ + rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x30000); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "5G PA BIAS path B\n"); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.h new file mode 100644 index 000000000..a107a5a76 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_PHY_H__ +#define __RTL92DU_PHY_H__ + +u32 rtl92du_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92du_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +bool rtl92du_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92du_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92du_phy_rf_config(struct ieee80211_hw *hw); +void rtl92du_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl92du_phy_sw_chnl(struct ieee80211_hw *hw); +bool rtl92du_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath); +bool rtl92du_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +void rtl92du_phy_set_poweron(struct ieee80211_hw *hw); +bool rtl92du_phy_check_poweroff(struct ieee80211_hw *hw); +void rtl92du_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +void rtl92du_update_bbrf_configuration(struct ieee80211_hw *hw); +void rtl92du_phy_iq_calibrate(struct ieee80211_hw *hw); +void rtl92du_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel); +void rtl92du_phy_init_pa_bias(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.c new file mode 100644 index 000000000..044dd65ea --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/phy_common.h" +#include "phy.h" +#include "rf.h" + +bool rtl92du_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + bool bresult = true; /* true: need to enable BB/RF power */ + u32 maskforphyset = 0; + u16 val16; + u8 u1btmp; + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); + + /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); + /* Enable BB and RF power */ + + maskforphyset = bmac0 ? MAC0_ACCESS_PHY1 : MAC1_ACCESS_PHY0; + + val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset); + val16 &= 0xfffc; + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset, val16); + + val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset); + val16 |= BIT(13) | BIT(0) | BIT(1); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset, val16); + } else { + /* We think if MAC1 is ON,then radio_a.txt + * and radio_b.txt has been load. + */ + bresult = false; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); + return bresult; +} + +void rtl92du_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + u32 maskforphyset = 0; + u8 u1btmp; + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); + + /* check MAC0 enable or not again now, if + * enabled, not power down radio A. + */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); + /* power down RF radio A according to YuNan's advice. */ + maskforphyset = bmac0 ? MAC0_ACCESS_PHY1 : MAC1_ACCESS_PHY0; + rtl_write_dword(rtlpriv, RFPGA0_XA_LSSIPARAMETER | maskforphyset, + 0x00000000); + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); +} + +bool rtl92du_phy_rf6052_config(struct ieee80211_hw *hw) +{ + bool mac1_initradioa_first = false, mac0_initradiob_first = false; + bool need_pwrdown_radioa = false, need_pwrdown_radiob = false; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg; + bool true_bpath = false; + bool rtstatus = true; + u32 u4_regvalue = 0; + u8 rfpath; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + /* Single phy mode: use radio_a radio_b config path_A path_B + * separately by MAC0, and MAC1 needn't configure RF; + * Dual PHY mode: MAC0 use radio_a config 1st phy path_A, + * MAC1 use radio_b config 2nd PHY path_A. + * DMDP, MAC0 on G band, MAC1 on A band. + */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + if (rtlhal->current_bandtype == BAND_ON_2_4G && + rtlhal->interfaceindex == 0) { + /* MAC0 needs PHY1 load radio_b.txt. */ + if (rtl92du_phy_enable_anotherphy(hw, true)) { + rtlphy->num_total_rfpath = 2; + mac0_initradiob_first = true; + } else { + /* We think if MAC1 is ON,then radio_a.txt and + * radio_b.txt has been load. + */ + return rtstatus; + } + } else if (rtlhal->current_bandtype == BAND_ON_5G && + rtlhal->interfaceindex == 1) { + /* MAC1 needs PHY0 load radio_a.txt. */ + if (rtl92du_phy_enable_anotherphy(hw, false)) { + rtlphy->num_total_rfpath = 2; + mac1_initradioa_first = true; + } else { + /* We think if MAC0 is ON, then radio_a.txt and + * radio_b.txt has been load. + */ + return rtstatus; + } + } else if (rtlhal->interfaceindex == 1) { + /* MAC0 enabled, only init radia B. */ + true_bpath = true; + } + } + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + /* Mac1 use PHY0 write */ + if (mac1_initradioa_first) { + if (rfpath == RF90_PATH_A) { + rtlhal->during_mac1init_radioa = true; + need_pwrdown_radioa = true; + } else if (rfpath == RF90_PATH_B) { + rtlhal->during_mac1init_radioa = false; + mac1_initradioa_first = false; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } else if (mac0_initradiob_first) { + /* Mac0 use PHY1 write */ + if (rfpath == RF90_PATH_A) + rtlhal->during_mac0init_radiob = false; + if (rfpath == RF90_PATH_B) { + rtlhal->during_mac0init_radiob = true; + mac0_initradiob_first = false; + need_pwrdown_radiob = true; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + /* Set bit number of Address and Data for RF register */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDRESSLENGTH, 0x0); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + if (true_bpath) + rtstatus = rtl92du_phy_config_rf_with_headerfile( + hw, radiob_txt, + (enum radio_path)rfpath); + else + rtstatus = rtl92du_phy_config_rf_with_headerfile( + hw, radioa_txt, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = + rtl92du_phy_config_rf_with_headerfile(hw, radiob_txt, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, + u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, + u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return rtstatus; + } + } + + /* check MAC0 enable or not again, if enabled, + * not power down radio A. + * check MAC1 enable or not again, if enabled, + * not power down radio B. + */ + if (need_pwrdown_radioa) + rtl92du_phy_powerdown_anotherphy(hw, false); + else if (need_pwrdown_radiob) + rtl92du_phy_powerdown_anotherphy(hw, true); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); + + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.h new file mode 100644 index 000000000..4a92cbdd0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_RF_H__ +#define __RTL92DU_RF_H__ + +bool rtl92du_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92du_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +void rtl92du_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c new file mode 100644 index 000000000..88e8cc590 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../usb.h" +#include "../base.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/fw_common.h" +#include "../rtl8192d/hw_common.h" +#include "../rtl8192d/phy_common.h" +#include "../rtl8192d/trx_common.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "trx.h" +#include "led.h" + +#include + +static struct usb_interface *rtl92du_get_other_intf(struct ieee80211_hw *hw) +{ + struct usb_interface *intf; + struct usb_device *udev; + u8 other_interfaceindex; + + /* See SET_IEEE80211_DEV(hw, &intf->dev); in usb.c */ + intf = container_of_const(wiphy_dev(hw->wiphy), struct usb_interface, dev); + + if (intf->altsetting[0].desc.bInterfaceNumber == 0) + other_interfaceindex = 1; + else + other_interfaceindex = 0; + + udev = interface_to_usbdev(intf); + + return usb_ifnum_to_if(udev, other_interfaceindex); +} + +static int rtl92du_init_shared_data(struct ieee80211_hw *hw) +{ + struct usb_interface *other_intf = rtl92du_get_other_intf(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *other_rtlpriv = NULL; + struct ieee80211_hw *other_hw = NULL; + + if (other_intf) + other_hw = usb_get_intfdata(other_intf); + + if (other_hw) { + /* The other interface was already probed. */ + other_rtlpriv = rtl_priv(other_hw); + rtlpriv->curveindex_2g = other_rtlpriv->curveindex_2g; + rtlpriv->curveindex_5g = other_rtlpriv->curveindex_5g; + rtlpriv->mutex_for_power_on_off = other_rtlpriv->mutex_for_power_on_off; + rtlpriv->mutex_for_hw_init = other_rtlpriv->mutex_for_hw_init; + + if (!rtlpriv->curveindex_2g || !rtlpriv->curveindex_5g || + !rtlpriv->mutex_for_power_on_off || !rtlpriv->mutex_for_hw_init) + return -ENOMEM; + + return 0; + } + + /* The other interface doesn't exist or was not probed yet. */ + rtlpriv->curveindex_2g = kcalloc(TARGET_CHNL_NUM_2G, + sizeof(*rtlpriv->curveindex_2g), + GFP_KERNEL); + rtlpriv->curveindex_5g = kcalloc(TARGET_CHNL_NUM_5G, + sizeof(*rtlpriv->curveindex_5g), + GFP_KERNEL); + rtlpriv->mutex_for_power_on_off = kzalloc_obj(*rtlpriv->mutex_for_power_on_off); + rtlpriv->mutex_for_hw_init = kzalloc_obj(*rtlpriv->mutex_for_hw_init); + + if (!rtlpriv->curveindex_2g || !rtlpriv->curveindex_5g || + !rtlpriv->mutex_for_power_on_off || !rtlpriv->mutex_for_hw_init) { + kfree(rtlpriv->curveindex_2g); + kfree(rtlpriv->curveindex_5g); + kfree(rtlpriv->mutex_for_power_on_off); + kfree(rtlpriv->mutex_for_hw_init); + rtlpriv->curveindex_2g = NULL; + rtlpriv->curveindex_5g = NULL; + rtlpriv->mutex_for_power_on_off = NULL; + rtlpriv->mutex_for_hw_init = NULL; + return -ENOMEM; + } + + mutex_init(rtlpriv->mutex_for_power_on_off); + mutex_init(rtlpriv->mutex_for_hw_init); + + return 0; +} + +static void rtl92du_deinit_shared_data(struct ieee80211_hw *hw) +{ + struct usb_interface *other_intf = rtl92du_get_other_intf(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!other_intf || !usb_get_intfdata(other_intf)) { + /* The other interface doesn't exist or was already disconnected. */ + kfree(rtlpriv->curveindex_2g); + kfree(rtlpriv->curveindex_5g); + if (rtlpriv->mutex_for_power_on_off) + mutex_destroy(rtlpriv->mutex_for_power_on_off); + if (rtlpriv->mutex_for_hw_init) + mutex_destroy(rtlpriv->mutex_for_hw_init); + kfree(rtlpriv->mutex_for_power_on_off); + kfree(rtlpriv->mutex_for_hw_init); + } +} + +static int rtl92du_init_sw_vars(struct ieee80211_hw *hw) +{ + const char *fw_name = "rtlwifi/rtl8192dufw.bin"; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + err = rtl92du_init_shared_data(hw); + if (err) + return err; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpriv->dm.useramask = true; + + /* dual mac */ + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtlpriv->phy.current_channel = 36; + else + rtlpriv->phy.current_channel = 1; + + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) + rtlpriv->rtlhal.disable_amsdu_8k = true; + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = kmalloc(0x8000, GFP_KERNEL); + if (!rtlpriv->rtlhal.pfirmware) { + err = -ENOMEM; + goto error; + } + + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DU WLAN interface\n"); + pr_info("Loading firmware file %s\n", fw_name); + + /* request fw */ + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + kfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + goto error; + } + + return 0; + +error: + rtl92du_deinit_shared_data(hw); + return err; +} + +static void rtl92du_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + kfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + + rtl92du_deinit_shared_data(hw); +} + +static const struct rtl_hal_ops rtl8192du_hal_ops = { + .init_sw_vars = rtl92du_init_sw_vars, + .deinit_sw_vars = rtl92du_deinit_sw_vars, + .read_chip_version = rtl92du_read_chip_version, + .read_eeprom_info = rtl92d_read_eeprom_info, + .hw_init = rtl92du_hw_init, + .hw_disable = rtl92du_card_disable, + .enable_interrupt = rtl92du_enable_interrupt, + .disable_interrupt = rtl92du_disable_interrupt, + .set_network_type = rtl92du_set_network_type, + .set_chk_bssid = rtl92du_set_check_bssid, + .set_qos = rtl92d_set_qos, + .set_bcn_reg = rtl92du_set_beacon_related_registers, + .set_bcn_intv = rtl92du_set_beacon_interval, + .update_interrupt_mask = rtl92du_update_interrupt_mask, + .get_hw_reg = rtl92du_get_hw_reg, + .set_hw_reg = rtl92du_set_hw_reg, + .update_rate_tbl = rtl92d_update_hal_rate_tbl, + .fill_tx_desc = rtl92du_tx_fill_desc, + .query_rx_desc = rtl92d_rx_query_desc, + .set_channel_access = rtl92d_update_channel_access_setting, + .radio_onoff_checking = rtl92d_gpio_radio_on_off_checking, + .set_bw_mode = rtl92du_phy_set_bw_mode, + .switch_channel = rtl92du_phy_sw_chnl, + .dm_watchdog = rtl92du_dm_watchdog, + .scan_operation_backup = rtl_phy_scan_operation_backup, + .set_rf_power_state = rtl92du_phy_set_rf_power_state, + .led_control = rtl92du_led_control, + .set_desc = rtl92d_set_desc, + .get_desc = rtl92d_get_desc, + .enable_hw_sec = rtl92d_enable_hw_security_config, + .set_key = rtl92d_set_key, + .get_bbreg = rtl92du_phy_query_bb_reg, + .set_bbreg = rtl92du_phy_set_bb_reg, + .get_rfreg = rtl92d_phy_query_rf_reg, + .set_rfreg = rtl92d_phy_set_rf_reg, + .linked_set_reg = rtl92du_linked_set_reg, + .fill_h2c_cmd = rtl92d_fill_h2c_cmd, + .get_btc_status = rtl_btc_status_false, + .phy_iq_calibrate = rtl92du_phy_iq_calibrate, + .phy_lc_calibrate = rtl92du_phy_lc_calibrate, +}; + +static struct rtl_mod_params rtl92du_mod_params = { + .sw_crypto = false, + .inactiveps = false, + .swctrl_lps = false, + .debug_level = 0, + .debug_mask = 0, +}; + +static const struct rtl_hal_usbint_cfg rtl92du_interface_cfg = { + /* rx */ + .rx_urb_num = 8, + .rx_max_size = 15360, + .usb_rx_hdl = NULL, + .usb_rx_segregate_hdl = NULL, + /* tx */ + .usb_tx_cleanup = rtl92du_tx_cleanup, + .usb_tx_post_hdl = rtl92du_tx_post_hdl, + .usb_tx_aggregate_hdl = rtl92du_tx_aggregate_hdl, + .usb_endpoint_mapping = rtl92du_endpoint_mapping, + .usb_mq_to_hwq = rtl92du_mq_to_hwq, +}; + +static const struct rtl_hal_cfg rtl92du_hal_cfg = { + .name = "rtl8192du", + .ops = &rtl8192du_hal_ops, + .mod_params = &rtl92du_mod_params, + .usb_interface_cfg = &rtl92du_interface_cfg, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = RCR_AM, + .maps[MAC_RCR_AB] = RCR_AB, + .maps[MAC_RCR_ACRC32] = RCR_ACRC32, + .maps[MAC_RCR_ACF] = RCR_ACF, + .maps[MAC_RCR_AAP] = RCR_AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, /* just for 92se */ + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = 0, + .maps[EFUSE_ANA8M] = 0, /* just for 92se */ + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, +}; + +module_param_named(swenc, rtl92du_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92du_mod_params.debug_level, int, 0644); +module_param_named(ips, rtl92du_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92du_mod_params.swctrl_lps, bool, 0444); +module_param_named(debug_mask, rtl92du_mod_params.debug_mask, ullong, 0644); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 0)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); + +#define USB_VENDOR_ID_REALTEK 0x0bda + +static const struct usb_device_id rtl8192d_usb_ids[] = { + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8193, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x2019, 0x4903, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x2019, 0x4904, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x07b8, 0x8193, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x20f4, 0x664b, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x04dd, 0x954f, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x04dd, 0x96a6, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x050d, 0x110a, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x050d, 0x1105, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x050d, 0x120a, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x1668, 0x8102, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x0930, 0x0a0a, rtl92du_hal_cfg)}, + {RTL_USB_DEVICE(0x2001, 0x330c, rtl92du_hal_cfg)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8192d_usb_ids); + +static int rtl8192du_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtl_usb_probe(intf, id, &rtl92du_hal_cfg); +} + +static struct usb_driver rtl8192du_driver = { + .name = "rtl8192du", + .probe = rtl8192du_probe, + .disconnect = rtl_usb_disconnect, + .id_table = rtl8192d_usb_ids, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(rtl8192du_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192DU 802.11n Dual Mac USB wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192dufw.bin"); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.c new file mode 100644 index 000000000..036701433 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.c @@ -0,0 +1,1675 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include + +#include "table.h" + +const u32 rtl8192du_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH] = { + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10001331, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60250, + 0x864, 0x061f0150, + 0x868, 0x27272727, + 0x86c, 0x272b2b2b, + 0x870, 0x07000700, + 0x874, 0x22188000, + 0x878, 0x08080808, + 0x87c, 0x0001fff8, + 0x880, 0xc0083070, + 0x884, 0x00000cd5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c8a8300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fff00, + 0xa74, 0x00000007, + 0xc00, 0x40071d40, + 0xc04, 0x03a05633, + 0xc08, 0x001000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652af, + 0xc38, 0x49795994, + 0xc3c, 0x0a979718, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc009e, + 0xc58, 0x69543420, + 0xc5c, 0x433c00a8, + 0xc60, 0x00000000, + 0xc64, 0x7112848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x258610db, + 0xc78, 0x0000001f, + 0xc7c, 0x40b95612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0xa0e40000, + 0xc90, 0x00121820, + 0xc94, 0x00000007, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b11e20, + 0xcdc, 0xe0767533, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608404, + 0xd38, 0x00000000, + 0xd3c, 0x00027353, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c126da4, + 0xe78, 0x0c126da4, + 0xe7c, 0x0c126da4, + 0xe80, 0x0c126da4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c126da4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf1c, 0x00000064, + 0xf4c, 0x00000004, + 0xf00, 0x00000300, +}; + +const u32 rtl8192du_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH] = { + 0xe00, 0xffffffff, 0x07090c0c, + 0xe04, 0xffffffff, 0x01020405, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0b0c0c0e, + 0xe14, 0xffffffff, 0x01030506, + 0xe18, 0xffffffff, 0x0b0c0d0e, + 0xe1c, 0xffffffff, 0x01030509, + 0x830, 0xffffffff, 0x07090c0c, + 0x834, 0xffffffff, 0x01020405, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0b0c0c0e, + 0x848, 0xffffffff, 0x01030506, + 0x84c, 0xffffffff, 0x0b0c0d0e, + 0x868, 0xffffffff, 0x01030509, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +const u32 rtl8192du_radioa_2tarray[RADIOA_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008cb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057568, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +const u32 rtl8192du_radiob_2tarray[RADIOB_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b4, + 0x013, 0x0000c0a8, + 0x013, 0x0000b030, + 0x013, 0x00004024, + 0x013, 0x00000018, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +const u32 rtl8192du_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff455, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008eb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ef, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +const u32 rtl8192du_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff455, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ef, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +const u32 rtl8192du_mac_2tarray[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x00000050, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000080, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x63e, 0x0000000e, + 0x63f, 0x0000000e, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, + 0x024, 0x0000000d, + 0x025, 0x00000080, + 0x026, 0x00000011, + 0x027, 0x00000000, + 0x028, 0x00000083, + 0x029, 0x000000db, + 0x02a, 0x000000ff, + 0x02b, 0x00000000, + 0x014, 0x00000055, + 0x015, 0x000000a9, + 0x016, 0x0000008b, + 0x017, 0x00000008, + 0x010, 0x00000003, + 0x011, 0x0000002b, + 0x012, 0x00000002, + 0x013, 0x00000049, +}; + +const u32 rtl8192du_agctab_array[AGCTAB_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7a420001, + 0xc78, 0x79430001, + 0xc78, 0x78440001, + 0xc78, 0x77450001, + 0xc78, 0x76460001, + 0xc78, 0x75470001, + 0xc78, 0x74480001, + 0xc78, 0x73490001, + 0xc78, 0x724a0001, + 0xc78, 0x714b0001, + 0xc78, 0x704c0001, + 0xc78, 0x6f4d0001, + 0xc78, 0x6e4e0001, + 0xc78, 0x6d4f0001, + 0xc78, 0x6c500001, + 0xc78, 0x6b510001, + 0xc78, 0x6a520001, + 0xc78, 0x69530001, + 0xc78, 0x68540001, + 0xc78, 0x67550001, + 0xc78, 0x66560001, + 0xc78, 0x65570001, + 0xc78, 0x64580001, + 0xc78, 0x63590001, + 0xc78, 0x625a0001, + 0xc78, 0x615b0001, + 0xc78, 0x605c0001, + 0xc78, 0x485d0001, + 0xc78, 0x475e0001, + 0xc78, 0x465f0001, + 0xc78, 0x45600001, + 0xc78, 0x44610001, + 0xc78, 0x43620001, + 0xc78, 0x42630001, + 0xc78, 0x41640001, + 0xc78, 0x40650001, + 0xc78, 0x27660001, + 0xc78, 0x26670001, + 0xc78, 0x25680001, + 0xc78, 0x24690001, + 0xc78, 0x236a0001, + 0xc78, 0x226b0001, + 0xc78, 0x216c0001, + 0xc78, 0x206d0001, + 0xc78, 0x206e0001, + 0xc78, 0x206f0001, + 0xc78, 0x20700001, + 0xc78, 0x20710001, + 0xc78, 0x20720001, + 0xc78, 0x20730001, + 0xc78, 0x20740001, + 0xc78, 0x20750001, + 0xc78, 0x20760001, + 0xc78, 0x20770001, + 0xc78, 0x20780001, + 0xc78, 0x20790001, + 0xc78, 0x207a0001, + 0xc78, 0x207b0001, + 0xc78, 0x207c0001, + 0xc78, 0x207d0001, + 0xc78, 0x207e0001, + 0xc78, 0x207f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x34070044, + 0xc78, 0x35080044, + 0xc78, 0x36090044, + 0xc78, 0x370a0044, + 0xc78, 0x380b0044, + 0xc78, 0x390c0044, + 0xc78, 0x3a0d0044, + 0xc78, 0x3e0e0044, + 0xc78, 0x420f0044, + 0xc78, 0x44100044, + 0xc78, 0x46110044, + 0xc78, 0x4a120044, + 0xc78, 0x4e130044, + 0xc78, 0x50140044, + 0xc78, 0x55150044, + 0xc78, 0x5a160044, + 0xc78, 0x5e170044, + 0xc78, 0x64180044, + 0xc78, 0x6e190044, + 0xc78, 0x6e1a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +const u32 rtl8192du_agctab_5garray[AGCTAB_5G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7a020001, + 0xc78, 0x79030001, + 0xc78, 0x78040001, + 0xc78, 0x77050001, + 0xc78, 0x76060001, + 0xc78, 0x75070001, + 0xc78, 0x74080001, + 0xc78, 0x73090001, + 0xc78, 0x720a0001, + 0xc78, 0x710b0001, + 0xc78, 0x700c0001, + 0xc78, 0x6f0d0001, + 0xc78, 0x6e0e0001, + 0xc78, 0x6d0f0001, + 0xc78, 0x6c100001, + 0xc78, 0x6b110001, + 0xc78, 0x6a120001, + 0xc78, 0x69130001, + 0xc78, 0x68140001, + 0xc78, 0x67150001, + 0xc78, 0x66160001, + 0xc78, 0x65170001, + 0xc78, 0x64180001, + 0xc78, 0x63190001, + 0xc78, 0x621a0001, + 0xc78, 0x611b0001, + 0xc78, 0x601c0001, + 0xc78, 0x481d0001, + 0xc78, 0x471e0001, + 0xc78, 0x461f0001, + 0xc78, 0x45200001, + 0xc78, 0x44210001, + 0xc78, 0x43220001, + 0xc78, 0x42230001, + 0xc78, 0x41240001, + 0xc78, 0x40250001, + 0xc78, 0x27260001, + 0xc78, 0x26270001, + 0xc78, 0x25280001, + 0xc78, 0x24290001, + 0xc78, 0x232a0001, + 0xc78, 0x222b0001, + 0xc78, 0x212c0001, + 0xc78, 0x202d0001, + 0xc78, 0x202e0001, + 0xc78, 0x202f0001, + 0xc78, 0x20300001, + 0xc78, 0x20310001, + 0xc78, 0x20320001, + 0xc78, 0x20330001, + 0xc78, 0x20340001, + 0xc78, 0x20350001, + 0xc78, 0x20360001, + 0xc78, 0x20370001, + 0xc78, 0x20380001, + 0xc78, 0x20390001, + 0xc78, 0x203a0001, + 0xc78, 0x203b0001, + 0xc78, 0x203c0001, + 0xc78, 0x203d0001, + 0xc78, 0x203e0001, + 0xc78, 0x203f0001, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x34070044, + 0xc78, 0x35080044, + 0xc78, 0x36090044, + 0xc78, 0x370a0044, + 0xc78, 0x380b0044, + 0xc78, 0x390c0044, + 0xc78, 0x3a0d0044, + 0xc78, 0x3e0e0044, + 0xc78, 0x420f0044, + 0xc78, 0x44100044, + 0xc78, 0x46110044, + 0xc78, 0x4a120044, + 0xc78, 0x4e130044, + 0xc78, 0x50140044, + 0xc78, 0x55150044, + 0xc78, 0x5a160044, + 0xc78, 0x5e170044, + 0xc78, 0x64180044, + 0xc78, 0x6e190044, + 0xc78, 0x6e1a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +const u32 rtl8192du_agctab_2garray[AGCTAB_2G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x6e1f0000, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.h new file mode 100644 index 000000000..b809ba511 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/table.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_TABLE_H__ +#define __RTL92DU_TABLE_H__ + +#define PHY_REG_2T_ARRAYLENGTH 372 +#define PHY_REG_ARRAY_PG_LENGTH 624 +#define RADIOA_2T_ARRAYLENGTH 378 +#define RADIOB_2T_ARRAYLENGTH 384 +#define RADIOA_2T_INT_PA_ARRAYLENGTH 378 +#define RADIOB_2T_INT_PA_ARRAYLENGTH 384 +#define MAC_2T_ARRAYLENGTH 192 +#define AGCTAB_ARRAYLENGTH 386 +#define AGCTAB_5G_ARRAYLENGTH 194 +#define AGCTAB_2G_ARRAYLENGTH 194 + +extern const u32 rtl8192du_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH]; +extern const u32 rtl8192du_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH]; +extern const u32 rtl8192du_radioa_2tarray[RADIOA_2T_ARRAYLENGTH]; +extern const u32 rtl8192du_radiob_2tarray[RADIOB_2T_ARRAYLENGTH]; +extern const u32 rtl8192du_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH]; +extern const u32 rtl8192du_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH]; +extern const u32 rtl8192du_mac_2tarray[MAC_2T_ARRAYLENGTH]; +extern const u32 rtl8192du_agctab_array[AGCTAB_ARRAYLENGTH]; +extern const u32 rtl8192du_agctab_5garray[AGCTAB_5G_ARRAYLENGTH]; +extern const u32 rtl8192du_agctab_2garray[AGCTAB_2G_ARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c new file mode 100644 index 000000000..c608c51f1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../usb.h" +#include "../rtl8192d/reg.h" +#include "../rtl8192d/def.h" +#include "../rtl8192d/trx_common.h" +#include "trx.h" + +void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb) +{ +} + +int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb) +{ + return 0; +} + +struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list) +{ + return skb_dequeue(list); +} + +static enum rtl_desc_qsel _rtl92du_hwq_to_descq(u16 queue_index) +{ + switch (queue_index) { + case RTL_TXQ_BCN: + return QSLT_BEACON; + case RTL_TXQ_MGT: + return QSLT_MGNT; + case RTL_TXQ_VO: + return QSLT_VO; + case RTL_TXQ_VI: + return QSLT_VI; + case RTL_TXQ_BK: + return QSLT_BK; + default: + case RTL_TXQ_BE: + return QSLT_BE; + } +} + +/* For HW recovery information */ +static void _rtl92du_tx_desc_checksum(__le32 *txdesc) +{ + __le16 *ptr = (__le16 *)txdesc; + u16 checksum = 0; + u32 index; + + /* Clear first */ + set_tx_desc_tx_desc_checksum(txdesc, 0); + for (index = 0; index < 16; index++) + checksum = checksum ^ le16_to_cpu(*(ptr + index)); + set_tx_desc_tx_desc_checksum(txdesc, checksum); +} + +void rtl92du_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 queue_index, + struct rtl_tcb_desc *tcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *sta_entry; + __le16 fc = hdr->frame_control; + u8 agg_state = RTL_AGG_STOP; + u16 pktlen = skb->len; + u32 rts_en, hw_rts_en; + u8 ampdu_density = 0; + u16 seq_number; + __le32 *txdesc; + u8 rate_flag; + u8 tid; + + rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); + + txdesc = (__le32 *)skb_push(skb, RTL_TX_HEADER_SIZE); + memset(txdesc, 0, RTL_TX_HEADER_SIZE); + + set_tx_desc_pkt_size(txdesc, pktlen); + set_tx_desc_linip(txdesc, 0); + set_tx_desc_pkt_offset(txdesc, RTL_DUMMY_OFFSET); + set_tx_desc_offset(txdesc, RTL_TX_HEADER_SIZE); + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (tcb_desc->hw_rate < DESC_RATE6M) + tcb_desc->hw_rate = DESC_RATE6M; + + set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate); + if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) + set_tx_desc_data_shortgi(txdesc, 1); + + if (rtlhal->macphymode == DUALMAC_DUALPHY && + tcb_desc->hw_rate == DESC_RATEMCS7) + set_tx_desc_data_shortgi(txdesc, 1); + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + tid = ieee80211_get_tid(hdr); + if (tid < MAX_TID_COUNT) + agg_state = sta_entry->tids[tid].agg.agg_state; + ampdu_density = sta->deflink.ht_cap.ampdu_density; + } + + if (agg_state == RTL_AGG_OPERATIONAL && + info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(txdesc, 1); + set_tx_desc_max_agg_num(txdesc, 0x14); + set_tx_desc_ampdu_density(txdesc, ampdu_density); + tcb_desc->rts_enable = 1; + tcb_desc->rts_rate = DESC_RATE24M; + } else { + set_tx_desc_agg_break(txdesc, 1); + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + set_tx_desc_seq(txdesc, seq_number); + + rts_en = tcb_desc->rts_enable && !tcb_desc->cts_enable; + hw_rts_en = tcb_desc->rts_enable || tcb_desc->cts_enable; + set_tx_desc_rts_enable(txdesc, rts_en); + set_tx_desc_hw_rts_enable(txdesc, hw_rts_en); + set_tx_desc_cts2self(txdesc, tcb_desc->cts_enable); + set_tx_desc_rts_stbc(txdesc, tcb_desc->rts_stbc); + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (tcb_desc->rts_rate < DESC_RATE6M) + tcb_desc->rts_rate = DESC_RATE6M; + set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate); + set_tx_desc_rts_bw(txdesc, 0); + set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc); + set_tx_desc_rts_short(txdesc, tcb_desc->rts_use_shortpreamble); + + rate_flag = info->control.rates[0].flags; + if (mac->bw_40) { + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { + set_tx_desc_data_bw(txdesc, 1); + set_tx_desc_tx_sub_carrier(txdesc, 3); + } else if (rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH) { + set_tx_desc_data_bw(txdesc, 1); + set_tx_desc_tx_sub_carrier(txdesc, mac->cur_40_prime_sc); + } else { + set_tx_desc_data_bw(txdesc, 0); + set_tx_desc_tx_sub_carrier(txdesc, 0); + } + } else { + set_tx_desc_data_bw(txdesc, 0); + set_tx_desc_tx_sub_carrier(txdesc, 0); + } + + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(txdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(txdesc, 0x3); + break; + default: + set_tx_desc_sec_type(txdesc, 0x0); + break; + } + } + + set_tx_desc_pkt_id(txdesc, 0); + set_tx_desc_queue_sel(txdesc, _rtl92du_hwq_to_descq(queue_index)); + set_tx_desc_data_rate_fb_limit(txdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(txdesc, 0xF); + set_tx_desc_disable_fb(txdesc, 0); + set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function\n"); + set_tx_desc_rdg_enable(txdesc, 1); + set_tx_desc_htc(txdesc, 1); + } + set_tx_desc_qos(txdesc, 1); + } + + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index); + set_tx_desc_macid(txdesc, tcb_desc->mac_id); + } else { + set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index); + set_tx_desc_macid(txdesc, tcb_desc->ratr_index); + } + + if (!ieee80211_is_data_qos(fc) && ppsc->leisure_ps && + ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en(txdesc, 1); + set_tx_desc_pkt_id(txdesc, 8); + } + + if (ieee80211_has_morefrags(fc)) + set_tx_desc_more_frag(txdesc, 1); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + set_tx_desc_bmc(txdesc, 1); + + set_tx_desc_own(txdesc, 1); + set_tx_desc_last_seg(txdesc, 1); + set_tx_desc_first_seg(txdesc, 1); + _rtl92du_tx_desc_checksum(txdesc); + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n"); +} + +static void _rtl92du_config_out_ep(struct ieee80211_hw *hw, u8 num_out_pipe) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u16 ep_cfg; + + rtlusb->out_queue_sel = 0; + rtlusb->out_ep_nums = 0; + + if (rtlhal->interfaceindex == 0) + ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC0); + else + ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC1); + + if (ep_cfg & 0x00f) { + rtlusb->out_queue_sel |= TX_SELE_HQ; + rtlusb->out_ep_nums++; + } + if (ep_cfg & 0x0f0) { + rtlusb->out_queue_sel |= TX_SELE_NQ; + rtlusb->out_ep_nums++; + } + if (ep_cfg & 0xf00) { + rtlusb->out_queue_sel |= TX_SELE_LQ; + rtlusb->out_ep_nums++; + } + + switch (num_out_pipe) { + case 3: + rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ | TX_SELE_LQ; + rtlusb->out_ep_nums = 3; + break; + case 2: + rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ; + rtlusb->out_ep_nums = 2; + break; + case 1: + rtlusb->out_queue_sel = TX_SELE_HQ; + rtlusb->out_ep_nums = 1; + break; + default: + break; + } +} + +static void _rtl92du_one_out_ep_mapping(struct rtl_usb *rtlusb, + struct rtl_ep_map *ep_map) +{ + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; +} + +static void _rtl92du_two_out_ep_mapping(struct rtl_usb *rtlusb, + struct rtl_ep_map *ep_map) +{ + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; +} + +static void _rtl92du_three_out_ep_mapping(struct rtl_usb *rtlusb, + struct rtl_ep_map *ep_map) +{ + ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[2]; + ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[2]; + ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1]; + ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0]; + ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0]; +} + +static int _rtl92du_out_ep_mapping(struct ieee80211_hw *hw) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_ep_map *ep_map = &rtlusb->ep_map; + + switch (rtlusb->out_ep_nums) { + case 1: + _rtl92du_one_out_ep_mapping(rtlusb, ep_map); + break; + case 2: + _rtl92du_two_out_ep_mapping(rtlusb, ep_map); + break; + case 3: + _rtl92du_three_out_ep_mapping(rtlusb, ep_map); + break; + default: + return -EINVAL; + } + + return 0; +} + +int rtl92du_endpoint_mapping(struct ieee80211_hw *hw) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + _rtl92du_config_out_ep(hw, rtlusb->out_ep_nums); + + /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */ + if (rtlusb->out_ep_nums == 1 && rtlusb->in_ep_nums != 1) + return -EINVAL; + + return _rtl92du_out_ep_mapping(hw); +} + +u16 rtl92du_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) +{ + u16 hw_queue_index; + + if (unlikely(ieee80211_is_beacon(fc))) { + hw_queue_index = RTL_TXQ_BCN; + goto out; + } + if (ieee80211_is_mgmt(fc)) { + hw_queue_index = RTL_TXQ_MGT; + goto out; + } + + switch (mac80211_queue_index) { + case 0: + hw_queue_index = RTL_TXQ_VO; + break; + case 1: + hw_queue_index = RTL_TXQ_VI; + break; + case 2: + hw_queue_index = RTL_TXQ_BE; + break; + case 3: + hw_queue_index = RTL_TXQ_BK; + break; + default: + hw_queue_index = RTL_TXQ_BE; + WARN_ONCE(true, "rtl8192du: QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index); + break; + } +out: + return hw_queue_index; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h new file mode 100644 index 000000000..8c3d24622 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Realtek Corporation.*/ + +#ifndef __RTL92DU_TRX_H__ +#define __RTL92DU_TRX_H__ + +#define TX_SELE_HQ BIT(0) /* High Queue */ +#define TX_SELE_LQ BIT(1) /* Low Queue */ +#define TX_SELE_NQ BIT(2) /* Normal Queue */ + +#define TX_TOTAL_PAGE_NUMBER_92DU 0xF8 +#define TEST_PAGE_NUM_PUBQ_92DU 0x89 +#define TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC 0x7A +#define NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC 0x5A +#define NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC 0x10 +#define NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC 0x10 +#define NORMAL_PAGE_NUM_NORMALQ_92D_DUAL_MAC 0 + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5 + +#define WMM_NORMAL_PAGE_NUM_PUBQ_92D 0x65 +#define WMM_NORMAL_PAGE_NUM_HPQ_92D 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_92D 0x30 +#define WMM_NORMAL_PAGE_NUM_NPQ_92D 0x30 + +#define WMM_NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC 0x32 +#define WMM_NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC 0x18 +#define WMM_NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC 0x18 +#define WMM_NORMAL_PAGE_NUM_NPQ_92D_DUAL_MAC 0x18 + +static inline void set_tx_desc_bmc(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits(__txdesc, __value, BIT(24)); +} + +static inline void set_tx_desc_agg_break(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 1), __value, BIT(6)); +} + +static inline void set_tx_desc_tx_desc_checksum(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 7), __value, GENMASK(15, 0)); +} + +void rtl92du_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +int rtl92du_endpoint_mapping(struct ieee80211_hw *hw); +u16 rtl92du_mq_to_hwq(__le16 fc, u16 mac80211_queue_index); +struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list); +void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb); +int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile new file mode 100644 index 000000000..12dfbeb1f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192ee-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + pwrseq.o \ + rf.o \ + sw.o \ + table.o \ + trx.o \ + + +obj-$(CONFIG_RTL8192EE) += rtl8192ee.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h new file mode 100644 index 000000000..fe1b7cdab --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_DEF_H__ +#define __RTL92E_DEF_H__ + +#define RX_DESC_NUM_92E 512 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 + +#define IS_HT_RATE(_rate) \ + (_rate >= DESC92C_RATEMCS0) +#define IS_CCK_RATE(_rate) \ + (_rate >= DESC92C_RATE1M && _rate <= DESC92C_RATE11M) +#define IS_OFDM_RATE(_rate) \ + (_rate >= DESC92C_RATE6M && _rate <= DESC92C_RATE54M) + +enum version_8192e { + VERSION_TEST_CHIP_2T2R_8192E = 0x0024, + VERSION_NORMAL_CHIP_2T2R_8192E = 0x102C, + VERSION_UNKNOWN = 0xFF, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc92c_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, +}; +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c new file mode 100644 index 000000000..0108850bb --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c @@ -0,0 +1,1086 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "trx.h" + +static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + + rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD); + falsealm_cnt->cnt_ofdm_cca = (ret_value & 0xffff); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + ret_value = rtl_get_bbreg(hw, DM_REG_SC_CNT_11N, MASKDWORD); + falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff); + falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16); + + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1); + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD); + falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | + ((ret_value & 0xFF00) >> 8); + + falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail + + falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail; + + falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca + + falsealm_cnt->cnt_cck_cca; + + /*reset false alarm counter registers*/ + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); + /*update ofdm counter*/ + rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); + /*reset CCK CCA counter*/ + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); + /*reset CCK FA counter*/ + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); +} + +static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u8 cur_cck_cca_thresh; + + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + if (dm_dig->rssi_val_min > 25) { + cur_cck_cca_thresh = 0xcd; + } else if ((dm_dig->rssi_val_min <= 25) && + (dm_dig->rssi_val_min > 10)) { + cur_cck_cca_thresh = 0x83; + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh); +} + +static void rtl92ee_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u8 dig_min_0, dig_maxofmin; + bool bfirstconnect , bfirstdisconnect; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dm_dig->cur_igvalue; + u8 offset; + + /* AP,BT */ + if (mac->act_scanning) + return; + + dig_min_0 = dm_dig->dig_min_0; + bfirstconnect = (mac->link_state >= MAC80211_LINKED) && + !dm_dig->media_connect_0; + bfirstdisconnect = (mac->link_state < MAC80211_LINKED) && + dm_dig->media_connect_0; + + dm_dig_max = 0x5a; + dm_dig_min = DM_DIG_MIN; + dig_maxofmin = DM_DIG_MAX_AP; + + if (mac->link_state >= MAC80211_LINKED) { + if ((dm_dig->rssi_val_min + 10) > dm_dig_max) + dm_dig->rx_gain_max = dm_dig_max; + else if ((dm_dig->rssi_val_min + 10) < dm_dig_min) + dm_dig->rx_gain_max = dm_dig_min; + else + dm_dig->rx_gain_max = dm_dig->rssi_val_min + 10; + + if (rtlpriv->dm.one_entry_only) { + offset = 0; + if (dm_dig->rssi_val_min - offset < dm_dig_min) + dig_min_0 = dm_dig_min; + else if (dm_dig->rssi_val_min - offset > + dig_maxofmin) + dig_min_0 = dig_maxofmin; + else + dig_min_0 = dm_dig->rssi_val_min - offset; + } else { + dig_min_0 = dm_dig_min; + } + + } else { + dm_dig->rx_gain_max = dm_dig_max; + dig_min_0 = dm_dig_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); + } + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { + if (dm_dig->large_fa_hit != 3) + dm_dig->large_fa_hit++; + if (dm_dig->forbidden_igi < current_igi) { + dm_dig->forbidden_igi = current_igi; + dm_dig->large_fa_hit = 1; + } + + if (dm_dig->large_fa_hit >= 3) { + if (dm_dig->forbidden_igi + 1 > dm_dig->rx_gain_max) + dm_dig->rx_gain_min = + dm_dig->rx_gain_max; + else + dm_dig->rx_gain_min = + dm_dig->forbidden_igi + 1; + dm_dig->recover_cnt = 3600; + } + } else { + if (dm_dig->recover_cnt != 0) { + dm_dig->recover_cnt--; + } else { + if (dm_dig->large_fa_hit < 3) { + if ((dm_dig->forbidden_igi - 1) < + dig_min_0) { + dm_dig->forbidden_igi = dig_min_0; + dm_dig->rx_gain_min = + dig_min_0; + } else { + dm_dig->forbidden_igi--; + dm_dig->rx_gain_min = + dm_dig->forbidden_igi + 1; + } + } else { + dm_dig->large_fa_hit = 0; + } + } + } + + if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5) + dm_dig->rx_gain_min = dm_dig_min; + + if (dm_dig->rx_gain_min > dm_dig->rx_gain_max) + dm_dig->rx_gain_min = dm_dig->rx_gain_max; + + if (mac->link_state >= MAC80211_LINKED) { + if (bfirstconnect) { + current_igi = min(dm_dig->rssi_val_min, dig_maxofmin); + + dm_dig->large_fa_hit = 0; + } else { + if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) + current_igi += 4; + else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + current_igi -= 2; + + if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5 && + rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + current_igi = dm_dig->rx_gain_min; + } + } else { + if (bfirstdisconnect) { + current_igi = dm_dig->rx_gain_min; + } else { + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + current_igi += 4; + else if (rtlpriv->falsealm_cnt.cnt_all > 8000) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all < 500) + current_igi -= 2; + } + } + + if (current_igi > dm_dig->rx_gain_max) + current_igi = dm_dig->rx_gain_max; + if (current_igi < dm_dig->rx_gain_min) + current_igi = dm_dig->rx_gain_min; + + rtl92ee_dm_write_dig(hw , current_igi); + dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ? + true : false); + dm_dig->dig_min_0 = dig_min_0; +} + +void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + + if (dm_dig->cur_cck_cca_thres != cur_thres) + rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11N, cur_thres); + + dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres; + dm_dig->cur_cck_cca_thres = cur_thres; +} + +void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + + if (dm_dig->stop_dig) + return; + + if (dm_dig->cur_igvalue != current_igi) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi); + if (rtlpriv->phy.rf_type != RF_1T1R) + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi); + } + dm_dig->pre_igvalue = dm_dig->cur_igvalue; + dm_dig->cur_igvalue = current_igi; +} + +static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, RA_RSSIDUMP, + rtlpriv->stats.rx_rssi_percentage[0]); + rtl_write_byte(rtlpriv, RB_RSSIDUMP, + rtlpriv->stats.rx_rssi_percentage[1]); + /*It seems the following values are not initialized. + *According to Windows code, + *these value will only be valid with JAGUAR chips + */ + /* Rx EVM */ + rtl_write_byte(rtlpriv, RS1_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[0]); + rtl_write_byte(rtlpriv, RS2_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[1]); + /* Rx SNR */ + rtl_write_byte(rtlpriv, RA_RXSNRDUMP, + (u8)(rtlpriv->stats.rx_snr_db[0])); + rtl_write_byte(rtlpriv, RB_RXSNRDUMP, + (u8)(rtlpriv->stats.rx_snr_db[1])); + /* Rx Cfo_Short */ + rtl_write_word(rtlpriv, RA_CFOSHORTDUMP, + rtlpriv->stats.rx_cfo_short[0]); + rtl_write_word(rtlpriv, RB_CFOSHORTDUMP, + rtlpriv->stats.rx_cfo_short[1]); + /* Rx Cfo_Tail */ + rtl_write_word(rtlpriv, RA_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[0]); + rtl_write_word(rtlpriv, RB_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[1]); +} + +static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + + /* Determine the minimum RSSI */ + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dm_dig->min_undec_pwdb_for_dm = 0; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "Not connected to any\n"); + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.entry_min_undec_sm_pwdb); + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "STA Default Port PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Ext Port or disconnect PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "MinUndecoratedPWDBForDM =%d\n", + rtl_dm_dig->min_undec_pwdb_for_dm); +} + +static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_dm *dm = rtl_dm(rtlpriv); + struct rtl_sta_info *drv_priv; + u8 h2c[4] = { 0 }; + long max = 0, min = 0xff; + u8 i = 0; + + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + /* AP & ADHOC & MESH */ + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { + struct rssi_sta *stat = &drv_priv->rssi_stat; + + if (stat->undec_sm_pwdb < min) + min = stat->undec_sm_pwdb; + if (stat->undec_sm_pwdb > max) + max = stat->undec_sm_pwdb; + + h2c[3] = 0; + h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF); + h2c[1] = 0x20; + h2c[0] = ++i; + rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c); + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + /* If associated entry is found */ + if (max != 0) { + dm->entry_max_undec_sm_pwdb = max; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMaxPWDB = 0x%lx(%ld)\n", max, max); + } else { + dm->entry_max_undec_sm_pwdb = 0; + } + /* If associated entry is found */ + if (min != 0xff) { + dm->entry_min_undec_sm_pwdb = min; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMinPWDB = 0x%lx(%ld)\n", min, min); + } else { + dm->entry_min_undec_sm_pwdb = 0; + } + } + + /* Indicate Rx signal strength to FW. */ + if (dm->useramask) { + h2c[3] = 0; + h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF); + h2c[1] = 0x20; + h2c[0] = 0; + rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c); + } else { + rtl_write_byte(rtlpriv, 0x4fe, dm->undec_sm_pwdb); + } + rtl92ee_rssi_dump_to_register(hw); + rtl92ee_dm_find_minimum_rssi(hw); + dm_dig->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; +} + +static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca; + + primarycca->dup_rts_flag = 0; + primarycca->intf_flag = 0; + primarycca->intf_type = 0; + primarycca->monitor_flag = 0; + primarycca->ch_offset = 0; + primarycca->mf_state = 0; +} + +static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) + return true; + + return false; +} + +void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_cur_rdlstate = false; + rtlpriv->dm.is_any_nonbepkts = false; +} + +static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; /*not sure*/ + u32 edca_be = 0x5ea42b; + bool is_cur_rdlstate; + bool b_edca_turbo_on = false; + + if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) + rtlpriv->dm.is_any_nonbepkts = true; + rtlpriv->dm.dbginfo.num_non_be_pkt = 0; + + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + /*b_bias_on_rx = false;*/ + b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) ? + true : false; + + if (rtl92ee_dm_is_edca_turbo_disable(hw)) + goto check_exit; + + if (b_edca_turbo_on) { + is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ? + true : false; + + edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul; + rtl_write_dword(rtlpriv , REG_EDCA_BE_PARAM , edca_be); + rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate; + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + } + rtlpriv->dm.current_turbo_edca = false; + } + +check_exit: + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_c50 , reg_c58; + bool fw_current_in_ps_mode = false; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_in_ps_mode)); + if (fw_current_in_ps_mode) + return; + + reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + + if (reg_c50 > 0x28 && reg_c58 > 0x28) { + if (!rtlpriv->rtlhal.pre_edcca_enable) { + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03); + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00); + rtlpriv->rtlhal.pre_edcca_enable = true; + } + } else if (reg_c50 < 0x25 && reg_c58 < 0x25) { + if (rtlpriv->rtlhal.pre_edcca_enable) { + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f); + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f); + rtlpriv->rtlhal.pre_edcca_enable = false; + } + } +} + +static void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw) +{ + rtl92ee_dm_dynamic_edcca(hw); +} + +static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw, + u8 cur_mf_state) +{ + struct dynamic_primary_cca *primarycca = &rtl_priv(hw)->primarycca; + + if (primarycca->mf_state != cur_mf_state) + rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7), + cur_mf_state); + + primarycca->mf_state = cur_mf_state; +} + +static void rtl92ee_dm_dynamic_primary_cca_check(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca; + bool is40mhz = false; + u64 ofdm_cca, ofdm_fa, bw_usc_cnt, bw_lsc_cnt; + u8 sec_ch_offset; + u8 cur_mf_state; + static u8 count_down = MONITOR_TIME; + + ofdm_cca = falsealm_cnt->cnt_ofdm_cca; + ofdm_fa = falsealm_cnt->cnt_ofdm_fail; + bw_usc_cnt = falsealm_cnt->cnt_bw_usc; + bw_lsc_cnt = falsealm_cnt->cnt_bw_lsc; + is40mhz = rtlpriv->mac80211.bw_40; + sec_ch_offset = rtlpriv->mac80211.cur_40_prime_sc; + /* NIC: 2: sec is below, 1: sec is above */ + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) { + cur_mf_state = MF_USC_LSC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + return; + } + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) + return; + + if (is40mhz) + return; + + if (primarycca->pricca_flag == 0) { + /* Primary channel is above + * NOTE: duplicate CTS can remove this condition + */ + if (sec_ch_offset == 2) { + if ((ofdm_cca > OFDMCCA_TH) && + (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) && + (ofdm_fa > (ofdm_cca >> 1))) { + primarycca->intf_type = 1; + primarycca->intf_flag = 1; + cur_mf_state = MF_USC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->pricca_flag = 1; + } else if ((ofdm_cca > OFDMCCA_TH) && + (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) && + (ofdm_fa < (ofdm_cca >> 1))) { + primarycca->intf_type = 2; + primarycca->intf_flag = 1; + cur_mf_state = MF_USC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->pricca_flag = 1; + primarycca->dup_rts_flag = 1; + } else { + primarycca->intf_type = 0; + primarycca->intf_flag = 0; + cur_mf_state = MF_USC_LSC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->dup_rts_flag = 0; + } + } else if (sec_ch_offset == 1) { + if ((ofdm_cca > OFDMCCA_TH) && + (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) && + (ofdm_fa > (ofdm_cca >> 1))) { + primarycca->intf_type = 1; + primarycca->intf_flag = 1; + cur_mf_state = MF_LSC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->pricca_flag = 1; + } else if ((ofdm_cca > OFDMCCA_TH) && + (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) && + (ofdm_fa < (ofdm_cca >> 1))) { + primarycca->intf_type = 2; + primarycca->intf_flag = 1; + cur_mf_state = MF_LSC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->pricca_flag = 1; + primarycca->dup_rts_flag = 1; + } else { + primarycca->intf_type = 0; + primarycca->intf_flag = 0; + cur_mf_state = MF_USC_LSC; + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->dup_rts_flag = 0; + } + } + } else {/* PrimaryCCA->PriCCA_flag==1 */ + count_down--; + if (count_down == 0) { + count_down = MONITOR_TIME; + primarycca->pricca_flag = 0; + cur_mf_state = MF_USC_LSC; + /* default */ + rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); + primarycca->dup_rts_flag = 0; + primarycca->intf_type = 0; + primarycca->intf_flag = 0; + } + } +} + +static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 crystal_cap; + u32 packet_count; + int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0; + int cfo_ave_diff; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { + if (rtldm->atc_status == ATC_STATUS_OFF) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_ON); + rtldm->atc_status = ATC_STATUS_ON; + } + /* Disable CFO tracking for BT */ + if (rtlpriv->cfg->ops->get_btc_status()) { + if (!rtlpriv->btcoexist.btc_ops-> + btc_is_bt_disabled(rtlpriv)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n"); + return; + } + } + /* Reset Crystal Cap */ + if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { + rtldm->crystal_cap = rtlpriv->efuse.crystalcap; + crystal_cap = rtldm->crystal_cap & 0x3f; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + } + } else { + cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; + cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; + packet_count = rtldm->packet_count; + + if (packet_count == rtldm->packet_count_pre) + return; + + rtldm->packet_count_pre = packet_count; + + if (rtlpriv->phy.rf_type == RF_1T1R) + cfo_ave = cfo_khz_a; + else + cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1; + + cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? + (rtldm->cfo_ave_pre - cfo_ave) : + (cfo_ave - rtldm->cfo_ave_pre); + + if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { + rtldm->large_cfo_hit = true; + return; + } + rtldm->large_cfo_hit = false; + + rtldm->cfo_ave_pre = cfo_ave; + + if (cfo_ave >= -rtldm->cfo_threshold && + cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) { + if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; + rtldm->is_freeze = 1; + } else { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; + } + } + + if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) + adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; + else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && + rtlpriv->dm.crystal_cap > 0) + adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; + + if (adjust_xtal != 0) { + rtldm->is_freeze = 0; + rtldm->crystal_cap += adjust_xtal; + + if (rtldm->crystal_cap > 0x3f) + rtldm->crystal_cap = 0x3f; + else if (rtldm->crystal_cap < 0) + rtldm->crystal_cap = 0; + + crystal_cap = rtldm->crystal_cap & 0x3f; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + } + + if (cfo_ave < CFO_THRESHOLD_ATC && + cfo_ave > -CFO_THRESHOLD_ATC) { + if (rtldm->atc_status == ATC_STATUS_ON) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_OFF); + rtldm->atc_status = ATC_STATUS_OFF; + } + } else { + if (rtldm->atc_status == ATC_STATUS_OFF) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_ON); + rtldm->atc_status = ATC_STATUS_ON; + } + } + } +} + +static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *dm = rtl_dm(rtlpriv); + u8 path; + + dm->txpower_tracking = true; + dm->default_ofdm_index = 30; + dm->default_cck_index = 20; + + dm->swing_idx_cck_base = dm->default_cck_index; + dm->cck_index = dm->default_cck_index; + + for (path = RF90_PATH_A; path < MAX_RF_PATH; path++) { + dm->swing_idx_ofdm_base[path] = dm->default_ofdm_index; + dm->ofdm_index[path] = dm->default_ofdm_index; + dm->delta_power_index[path] = 0; + dm->delta_power_index_last[path] = 0; + dm->power_index_offset[path] = 0; + } +} + +void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + + p_ra->ldpc_thres = 35; + p_ra->use_ldpc = false; + p_ra->high_rssi_thresh_for_ra = 50; + p_ra->low_rssi_thresh_for_ra40m = 20; +} + +static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw, + s32 rssi, u8 *ratr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + const u8 go_up_gap = 5; + u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; + u32 low_rssithresh_for_ra = p_ra->low_rssi_thresh_for_ra40m; + u8 state; + + /* Threshold Adjustment: + * when RSSI state trends to go up one or two levels, + * make sure RSSI is high enough. + * Here GoUpGap is added to solve + * the boundary's level alternation issue. + */ + switch (*ratr_state) { + case DM_RATR_STA_INIT: + case DM_RATR_STA_HIGH: + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra += go_up_gap; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra += go_up_gap; + low_rssithresh_for_ra += go_up_gap; + break; + default: + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "wrong rssi level setting %d !\n", *ratr_state); + break; + } + + /* Decide RATRState by RSSI. */ + if (rssi > high_rssithresh_for_ra) + state = DM_RATR_STA_HIGH; + else if (rssi > low_rssithresh_for_ra) + state = DM_RATR_STA_MIDDLE; + else + state = DM_RATR_STA_LOW; + + if (*ratr_state != state) { + *ratr_state = state; + return true; + } + + return false; +} + +static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &rtlpriv->ra; + struct ieee80211_sta *sta = NULL; + + if (is_hal_stop(rtlhal)) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver is going to unload\n"); + return; + } + + if (!rtlpriv->dm.useramask) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver does not control rate adaptive mask\n"); + return; + } + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + if (rtlpriv->dm.undec_sm_pwdb < p_ra->ldpc_thres) { + p_ra->use_ldpc = true; + p_ra->lower_rts_rate = true; + } else if (rtlpriv->dm.undec_sm_pwdb > + (p_ra->ldpc_thres - 5)) { + p_ra->use_ldpc = false; + p_ra->lower_rts_rate = false; + } + if (_rtl92ee_dm_ra_state_check(hw, rtlpriv->dm.undec_sm_pwdb, + &p_ra->ratr_state)) { + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, + p_ra->ratr_state, + true); + rcu_read_unlock(); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; + + rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11)); + rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; +} + +void rtl92ee_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N, DM_BIT_IGI_11N); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + + rtl_dm_diginit(hw, cur_igvalue); + rtl92ee_dm_init_rate_adaptive_mask(hw); + rtl92ee_dm_init_primary_cca_check(hw); + rtl92ee_dm_init_edca_turbo(hw); + rtl92ee_dm_init_txpower_tracking(hw); + rtl92ee_dm_init_dynamic_atc_switch(hw); +} + +static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 cnt; + + rtlpriv->dm.one_entry_only = false; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && + rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + rtlpriv->dm.one_entry_only = true; + return; + } + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + cnt = list_count_nodes(&rtlpriv->entry_list); + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + if (cnt == 1) + rtlpriv->dm.one_entry_only = true; + } +} + +void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw, + u8 rate, bool collision_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS12) { + if (collision_state == 1) { + if (rate == DESC92C_RATEMCS12) { + rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x07060501); + } else if (rate == DESC92C_RATEMCS11) { + rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x07070605); + } else if (rate == DESC92C_RATEMCS10) { + rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x08080706); + } else if (rate == DESC92C_RATEMCS9) { + rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x08080707); + } else { + rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x09090808); + } + } else { /* collision_state == 0 */ + if (rate == DESC92C_RATEMCS12) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x05010000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x09080706); + } else if (rate == DESC92C_RATEMCS11) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x06050000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x09080807); + } else if (rate == DESC92C_RATEMCS10) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x07060000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x0a090908); + } else if (rate == DESC92C_RATEMCS9) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x07070000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x0a090808); + } else { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x08080000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x0b0a0909); + } + } + } else { /* MCS13~MCS15, 1SS, G-mode */ + if (collision_state == 1) { + if (rate == DESC92C_RATEMCS15) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x05040302); + } else if (rate == DESC92C_RATEMCS14) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x06050302); + } else if (rate == DESC92C_RATEMCS13) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x07060502); + } else { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x06050402); + } + } else{ /* collision_state == 0 */ + if (rate == DESC92C_RATEMCS15) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x03020000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x07060504); + } else if (rate == DESC92C_RATEMCS14) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x03020000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x08070605); + } else if (rate == DESC92C_RATEMCS13) { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x05020000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x09080706); + } else { + rtl_write_dword(rtlpriv, REG_DARFRC, + 0x04020000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, + 0x08070605); + } + } + } +} + +void rtl92ee_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) { + rtl92ee_dm_common_info_self_update(hw); + rtl92ee_dm_false_alarm_counter_statistics(hw); + rtl92ee_dm_check_rssi_monitor(hw); + rtl92ee_dm_dig(hw); + rtl92ee_dm_adaptivity(hw); + rtl92ee_dm_cck_packet_detection_thresh(hw); + rtl92ee_dm_refresh_rate_adaptive_mask(hw); + rtl92ee_dm_check_edca_turbo(hw); + rtl92ee_dm_dynamic_atc_switch(hw); + rtl92ee_dm_dynamic_primary_cca_check(hw); + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h new file mode 100644 index 000000000..ec48e5671 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h @@ -0,0 +1,229 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_DM_H__ +#define __RTL92E_DM_H__ + +#define OFDMCCA_TH 500 +#define BW_IND_BIAS 500 +#define MF_USC 2 +#define MF_LSC 1 +#define MF_USC_LSC 0 +#define MONITOR_TIME 30 + +#define MAIN_ANT 0 +#define AUX_ANT 1 +#define MAIN_ANT_CG_TRX 1 +#define AUX_ANT_CG_TRX 0 +#define MAIN_ANT_CGCS_RX 0 +#define AUX_ANT_CGCS_RX 1 + +/*RF REG LIST*/ +#define DM_REG_RF_MODE_11N 0x00 +#define DM_REG_RF_0B_11N 0x0B +#define DM_REG_CHNBW_11N 0x18 +#define DM_REG_T_METER_11N 0x24 +#define DM_REG_RF_25_11N 0x25 +#define DM_REG_RF_26_11N 0x26 +#define DM_REG_RF_27_11N 0x27 +#define DM_REG_RF_2B_11N 0x2B +#define DM_REG_RF_2C_11N 0x2C +#define DM_REG_RXRF_A3_11N 0x3C +#define DM_REG_T_METER_92D_11N 0x42 +#define DM_REG_T_METER_92E_11N 0x42 + +/*BB REG LIST*/ +/*PAGE 8 */ +#define DM_REG_BB_CTRL_11N 0x800 +#define DM_REG_RF_PIN_11N 0x804 +#define DM_REG_PSD_CTRL_11N 0x808 +#define DM_REG_TX_ANT_CTRL_11N 0x80C +#define DM_REG_BB_PWR_SAV5_11N 0x818 +#define DM_REG_CCK_RPT_FORMAT_11N 0x824 +#define DM_REG_RX_DEFUALT_A_11N 0x858 +#define DM_REG_RX_DEFUALT_B_11N 0x85A +#define DM_REG_BB_PWR_SAV3_11N 0x85C +#define DM_REG_ANTSEL_CTRL_11N 0x860 +#define DM_REG_RX_ANT_CTRL_11N 0x864 +#define DM_REG_PIN_CTRL_11N 0x870 +#define DM_REG_BB_PWR_SAV1_11N 0x874 +#define DM_REG_ANTSEL_PATH_11N 0x878 +#define DM_REG_BB_3WIRE_11N 0x88C +#define DM_REG_SC_CNT_11N 0x8C4 +#define DM_REG_PSD_DATA_11N 0x8B4 +/*PAGE 9*/ +#define DM_REG_ANT_MAPPING1_11N 0x914 +#define DM_REG_ANT_MAPPING2_11N 0x918 +/*PAGE A*/ +#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define DM_REG_CCK_CCA_11N 0xA0A +#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define DM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define DM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define DM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define DM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define DM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define DM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define DM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define DM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define DM_REG_CCK_FA_RST_11N 0xA2C +#define DM_REG_CCK_FA_MSB_11N 0xA58 +#define DM_REG_CCK_FA_LSB_11N 0xA5C +#define DM_REG_CCK_CCA_CNT_11N 0xA60 +#define DM_REG_BB_PWR_SAV4_11N 0xA74 +/*PAGE B */ +#define DM_REG_LNA_SWITCH_11N 0xB2C +#define DM_REG_PATH_SWITCH_11N 0xB30 +#define DM_REG_RSSI_CTRL_11N 0xB38 +#define DM_REG_CONFIG_ANTA_11N 0xB68 +#define DM_REG_RSSI_BT_11N 0xB9C +/*PAGE C */ +#define DM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define DM_REG_RX_PATH_11N 0xC04 +#define DM_REG_TRMUX_11N 0xC08 +#define DM_REG_OFDM_FA_RSTC_11N 0xC0C +#define DM_REG_RXIQI_MATRIX_11N 0xC14 +#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define DM_REG_IGI_A_11N 0xC50 +#define DM_REG_ANTDIV_PARA2_11N 0xC54 +#define DM_REG_IGI_B_11N 0xC58 +#define DM_REG_ANTDIV_PARA3_11N 0xC5C +#define DM_REG_L1SBD_PD_CH_11N 0XC6C +#define DM_REG_BB_PWR_SAV2_11N 0xC70 +#define DM_REG_RX_OFF_11N 0xC7C +#define DM_REG_TXIQK_MATRIXA_11N 0xC80 +#define DM_REG_TXIQK_MATRIXB_11N 0xC88 +#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define DM_REG_ANTDIV_PARA1_11N 0xCA4 +#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/*PAGE D */ +#define DM_REG_OFDM_FA_RSTD_11N 0xD00 +#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8 +/*PAGE E */ +#define DM_REG_TXAGC_A_6_18_11N 0xE00 +#define DM_REG_TXAGC_A_24_54_11N 0xE04 +#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define DM_REG_FPGA0_IQK_11N 0xE28 +#define DM_REG_TXIQK_TONE_A_11N 0xE30 +#define DM_REG_RXIQK_TONE_A_11N 0xE34 +#define DM_REG_TXIQK_PI_A_11N 0xE38 +#define DM_REG_RXIQK_PI_A_11N 0xE3C +#define DM_REG_TXIQK_11N 0xE40 +#define DM_REG_RXIQK_11N 0xE44 +#define DM_REG_IQK_AGC_PTS_11N 0xE48 +#define DM_REG_IQK_AGC_RSP_11N 0xE4C +#define DM_REG_BLUETOOTH_11N 0xE6C +#define DM_REG_RX_WAIT_CCA_11N 0xE70 +#define DM_REG_TX_CCK_RFON_11N 0xE74 +#define DM_REG_TX_CCK_BBON_11N 0xE78 +#define DM_REG_OFDM_RFON_11N 0xE7C +#define DM_REG_OFDM_BBON_11N 0xE80 +#define DM_REG_TX2RX_11N 0xE84 +#define DM_REG_TX2TX_11N 0xE88 +#define DM_REG_RX_CCK_11N 0xE8C +#define DM_REG_RX_OFDM_11N 0xED0 +#define DM_REG_RX_WAIT_RIFS_11N 0xED4 +#define DM_REG_RX2RX_11N 0xED8 +#define DM_REG_STANDBY_11N 0xEDC +#define DM_REG_SLEEP_11N 0xEE0 +#define DM_REG_PMPD_ANAEN_11N 0xEEC + +/*MAC REG LIST*/ +#define DM_REG_BB_RST_11N 0x02 +#define DM_REG_ANTSEL_PIN_11N 0x4C +#define DM_REG_EARLY_MODE_11N 0x4D0 +#define DM_REG_RSSI_MONITOR_11N 0x4FE +#define DM_REG_EDCA_VO_11N 0x500 +#define DM_REG_EDCA_VI_11N 0x504 +#define DM_REG_EDCA_BE_11N 0x508 +#define DM_REG_EDCA_BK_11N 0x50C +#define DM_REG_TXPAUSE_11N 0x522 +#define DM_REG_RESP_TX_11N 0x6D8 +#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + +/*DIG Related*/ +#define DM_BIT_IGI_11N 0x0000007F + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 43 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x3e +#define DM_DIG_FA_LOWER 0x1e +#define DM_DIG_FA_TH0 0x200 +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TXPWRTRACK_MAX_IDX 6 + +/* Dynamic ATC switch */ +#define ATC_STATUS_OFF 0x0 /* enable */ +#define ATC_STATUS_ON 0x1 /* disable */ +#define CFO_THRESHOLD_XTAL 10 /* kHz */ +#define CFO_THRESHOLD_ATC 80 /* kHz */ + +/* RSSI Dump Message */ +#define RA_RSSIDUMP 0xcb0 +#define RB_RSSIDUMP 0xcb1 +#define RS1_RXEVMDUMP 0xcb2 +#define RS2_RXEVMDUMP 0xcb3 +#define RA_RXSNRDUMP 0xcb4 +#define RB_RXSNRDUMP 0xcb5 +#define RA_CFOSHORTDUMP 0xcb6 +#define RB_CFOSHORTDUMP 0xcb8 +#define RA_CFOLONGDUMP 0xcba +#define RB_CFOLONGDUMP 0xcbc + +void rtl92ee_dm_init(struct ieee80211_hw *hw); +void rtl92ee_dm_watchdog(struct ieee80211_hw *hw); +void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, + u8 cur_thres); +void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi); +void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw, + u8 rate, bool collision_state); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c new file mode 100644 index 000000000..88b7a715f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c @@ -0,0 +1,863 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "../efuse.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "dm.h" + +static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + } +} + +static void _rtl92ee_write_fw(struct ieee80211_hw *hw, + enum version_8192e version, + u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *bufferptr = (u8 *)buffer; + u32 pagenums, remainsize; + u32 page, offset; + + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); + + rtl_fill_dummy(bufferptr, &size); + + pagenums = size / FW_8192C_PAGE_SIZE; + remainsize = size % FW_8192C_PAGE_SIZE; + + if (pagenums > 8) + pr_err("Page numbers should not greater then 8\n"); + + for (page = 0; page < pagenums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); + udelay(2); + } + + if (remainsize) { + offset = pagenums * FW_8192C_PAGE_SIZE; + page = pagenums; + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); + } +} + +static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n", + value32); + goto exit; + } + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + rtl92ee_firmware_selfreset(hw); + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) + return 0; + + udelay(FW_8192C_POLLING_DELAY*10); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n", + value32, counter); + +exit: + return err; +} + +int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtlwifi_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + enum version_8192e version = rtlhal->version; + + if (!rtlhal->pfirmware) + return 1; + + pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware; + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = (u8 *)rtlhal->pfirmware; + fwsize = rtlhal->fwsize; + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "normal Firmware SIZE %d\n", fwsize); + + if (IS_FW_HEADER_EXIST(pfwheader)) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Firmware Version(%d), Signature(%#x),Size(%d)\n", + pfwheader->version, pfwheader->signature, + (int)sizeof(struct rtlwifi_firmware_header)); + + pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); + fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); + } else { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Firmware no Header, Signature(%#x)\n", + pfwheader->signature); + } + + if (rtlhal->mac_func_enable) { + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + rtl92ee_firmware_selfreset(hw); + } + } + _rtl92ee_enable_fw_download(hw, true); + _rtl92ee_write_fw(hw, version, pfwdata, fwsize); + _rtl92ee_enable_fw_download(hw, false); + + return _rtl92ee_fw_free_to_go(hw); +} + +static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + if (ppsc->dot11_psmode != EACTIVE || + ppsc->inactive_pwrstate == ERFOFF) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "FillH2CCommand8192E(): Return because RF is off!!!\n"); + return; + } + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + /* 1. Prevent race condition in setting H2C cmd. + * (copy from MgntActSet_RF_State().) + */ + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + /* 2. Find the last BOX number which has been writen. */ + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", boxnum); + break; + } + + /* 3. Check if the box content is empty. */ + isfw_read = false; + u1b_tmp = rtl_read_byte(rtlpriv, REG_CR); + + if (u1b_tmp != 0xea) { + isfw_read = true; + } else { + if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea || + rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea) + rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff); + } + + if (isfw_read) { + wait_h2c_limmit = 100; + isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!!!\n", + boxnum); + break; + } + udelay(10); + isfw_read = + _rtl92ee_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + } + + /* If Fw has not read the last + * H2C cmd, break and give up this H2C. + */ + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C reg BOX[%d] fail,Fw don't read.\n", + boxnum); + break; + } + /* 4. Fill the H2C cmd into box */ + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index+3, cmd_len-3); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", cmd_len); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8192ee: error H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); +} + +void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + + udelay(50); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2))); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + " _8051Reset92E(): 8051 reset success .\n"); +} + +void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0, byte5 = 0; + u8 awake_intvl; /* DTIM = (awake_intvl - 1) */ + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false); + bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_lps_on(rtlpriv) : false); + + if (bt_ctrl_lps) + mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n", + mode, bt_ctrl_lps); + + switch (mode) { + case FW_PS_MIN_MODE: + rlbm = 0; + awake_intvl = 2; + break; + case FW_PS_MAX_MODE: + rlbm = 1; + awake_intvl = 2; + break; + case FW_PS_DTIM_MODE: + rlbm = 2; + awake_intvl = ppsc->reg_max_lps_awakeintvl; + /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period + * is only used in swlps. + */ + break; + default: + rlbm = 2; + awake_intvl = 4; + break; + } + + if (rtlpriv->mac80211.p2p) { + awake_intvl = 2; + rlbm = 1; + } + + if (mode == FW_PS_ACTIVE_MODE) { + byte5 = 0x40; + power_state = FW_PWR_STATE_ACTIVE; + } else { + if (bt_ctrl_lps) { + byte5 = btc_ops->btc_get_lps_val(rtlpriv); + power_state = btc_ops->btc_get_rpwm_val(rtlpriv); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from + * decreasing coex performance + */ + awake_intvl = 2; + rlbm = 2; + } + } else { + byte5 = 0x40; + power_state = FW_PWR_STATE_RF_OFF; + } + } + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, + bt_ctrl_lps ? 0 : + ((rtlpriv->mac80211.p2p) ? + ppsc->smart_ps : 1)); + SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, + awake_intvl); + SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode, + H2C_92E_PWEMODE_LENGTH); + rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH, + u1_h2c_set_pwrmode); +} + +void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 parm[3] = { 0 , 0 , 0 }; + /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect + * bit1=0-->update Media Status to MACID + * bit1=1-->update Media Status from MACID to MACID_End + * parm[1]: MACID, if this is INFRA_STA, MacID = 0 + * parm[2]: MACID_End + */ + + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + + rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm); +} + +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ +#define QOS_NULL_PG 6 +#define BT_QOS_NULL_PG 7 + +#define TOTAL_RESERVED_PKT_LEN 1024 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, + 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, + 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, + 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, + 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, + 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, + 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, + 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, + 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, + + /* page 1 beacon */ + 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 6 qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 7 BT-qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + bool rtstatus; + u32 totalpacketlen; + u8 u1rsvdpageloc[5] = { 0 }; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + u8 *qosnull; + u8 *btqosnull; + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *---------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + + /*--------------------------------------------------------- + * (5) QoS null data + *---------------------------------------------------------- + */ + qosnull = &reserved_page_packet[QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG); + + /*--------------------------------------------------------- + * (6) BT QoS null data + *---------------------------------------------------------- + */ + btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , + "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , + "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1rsvdpageloc, 3); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , + "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3); + rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); + } +} + +/*Shoud check FW support p2p or not.*/ +static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = {ctwindow}; + + rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); +} + +void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info; + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow); + } + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num ; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low + (50 * 1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1, + (u8 *)p2p_ps_offload); +} + +void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw, + u8 *cmd_buf, u8 cmd_len) +{ + u8 rate = cmd_buf[0] & 0x3F; + bool collision_state = cmd_buf[3] & BIT(0); + + rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h new file mode 100644 index 000000000..27ac4f8b9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E__FW__H__ +#define __RTL92E__FW__H__ + +#define FW_8192C_SIZE 0x8000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x5FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 3000 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((le16_to_cpu(_pfwhdr->signature) & 0xFFF0) == 0x92E0) +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_92E_RSVDPAGE_LOC_LEN 5 +#define H2C_92E_PWEMODE_LENGTH 7 +#define H2C_92E_JOINBSSRPT_LENGTH 1 +#define H2C_92E_AP_OFFLOAD_LENGTH 3 +#define H2C_92E_WOWLAN_LENGTH 3 +#define H2C_92E_KEEP_ALIVE_CTRL_LENGTH 3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_92E_REMOTE_WAKE_CTRL_LEN 1 +#else +#define H2C_92E_REMOTE_WAKE_CTRL_LEN 3 +#endif +#define H2C_92E_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_92E_AOAC_RSVDPAGE_LOC_LEN 7 + +/* Fw PS state for RPWM. +*BIT[2:0] = HW state +*BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state +*BIT[4] = sub-state +*/ +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + + /* 92E RPWM value*/ + /* BIT[0] = 1: 32k, 0: 40M*/ +#define FW_PS_CLOCK_OFF BIT(0) /* 32k */ +#define FW_PS_CLOCK_ON 0 /* 40M */ + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) + +#define FW_PS_STATE_ALL_ON_92E (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_ON_92E (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_92E (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF) + +/* For 92E H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) + +#define IS_IN_LOW_POWER_STATE_92E(__state) \ + (FW_PS_STATE(__state) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8192e_h2c_cmd { + H2C_92E_RSVDPAGE = 0, + H2C_92E_MSRRPT = 1, + H2C_92E_SCAN = 2, + H2C_92E_KEEP_ALIVE_CTRL = 3, + H2C_92E_DISCONNECT_DECISION = 4, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_92E_WO_WLAN = 5, +#endif + H2C_92E_INIT_OFFLOAD = 6, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_92E_REMOTE_WAKE_CTRL = 7, +#endif + H2C_92E_AP_OFFLOAD = 8, + H2C_92E_BCN_RSVDPAGE = 9, + H2C_92E_PROBERSP_RSVDPAGE = 10, + + H2C_92E_SETPWRMODE = 0x20, + H2C_92E_PS_TUNING_PARA = 0x21, + H2C_92E_PS_TUNING_PARA2 = 0x22, + H2C_92E_PS_LPS_PARA = 0x23, + H2C_92E_P2P_PS_OFFLOAD = 024, + +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) + H2C_92E_WO_WLAN = 0x80, + H2C_92E_REMOTE_WAKE_CTRL = 0x81, + H2C_92E_AOAC_GLOBAL_INFO = 0x82, + H2C_92E_AOAC_RSVDPAGE = 0x83, +#endif + H2C_92E_RA_MASK = 0x40, + H2C_92E_RSSI_REPORT = 0x42, + H2C_92E_SELECTIVE_SUSPEND_ROF_CMD, + H2C_92E_P2P_PS_MODE, + H2C_92E_PSD_RESULT, + /*Not defined CTW CMD for P2P yet*/ + H2C_92E_P2P_PS_CTW_CMD, + MAX_92E_H2CCMD +}; + +#define pagenum_128(_len) \ + (u32)(((_len) >> 7) + ((_len) & 0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val; +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__cmd, __val) \ + u8p_replace_bits(__cmd + 1, __val, GENMASK(3, 0)) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__cmd, __val) \ + u8p_replace_bits(__cmd + 1, __val, GENMASK(7, 4)) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__cmd, __val) \ + *(u8 *)(__cmd + 2) = __val; +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__cmd, __val) \ + *(u8 *)(__cmd + 3) = __val; +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__cmd, __val) \ + *(u8 *)(__cmd + 4) = __val; +#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__cmd, __val) \ + *(u8 *)(__cmd + 5) = __val; + +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 3) = __val; +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 4) = __val; + +/* _MEDIA_STATUS_RPT_PARM_CMD1 */ +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __val) \ + u8p_replace_bits(__cmd, __val, BIT(0)) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__cmd, __val) \ + u8p_replace_bits(__cmd, __val, BIT(1)) +#define SET_H2CCMD_MSRRPT_PARM_MACID(__cmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val; +#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__cmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val; + +int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw); +void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer); +void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw, + u8 *cmd_buf, u8 cmd_len); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c new file mode 100644 index 000000000..48a3c9460 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c @@ -0,0 +1,2609 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "hw.h" +#include "../pwrseqcmd.h" +#include "pwrseq.h" + +#define LLT_CONFIG 5 + +static void _rtl92ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92ee_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp); +} + +static void _rtl92ee_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp); +} + +static void _rtl92ee_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92ee_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl92ee_set_fw_clock_on(struct ieee80211_hw *hw, + u8 rpwm_val, bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_support_remote_wake_up; + u32 count = 0, isr_regaddr, content; + bool b_schedule_timer = b_need_turn_off_ckk; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&b_support_remote_wake_up)); + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + return; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + break; + } + } + + if (IS_IN_LOW_POWER_STATE_92E(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_92E; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! PSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl92ee_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool b_schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + b_schedule_timer = true; + break; + } + } + + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } +} + +static void _rtl92ee_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= (FW_PS_STATE_RF_OFF_92E | FW_PS_ACK); + _rtl92ee_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl92ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR; + _rtl92ee_set_fw_clock_off(hw, rpwm_val); +} + +void rtl92ee_fw_clk_off_timer_callback(unsigned long data) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; + + _rtl92ee_set_fw_ps_rf_off_low_power(hw); +} + +static void _rtl92ee_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON_92E | FW_PS_ACK);/* RF on */ + _rtl92ee_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON_92E; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } +} + +static void _rtl92ee_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl92ee_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF_92E; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } +} + +void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + } + break; + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *)(val)) = tsf; + } + break; + case HAL_DEF_WOWLAN: + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case %#x not processed\n", variable); + break; + } +} + +static void _rtl92ee_download_rsvd_page(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_regcr, tmp_reg422; + u8 bcnvalid_reg, txbc_reg; + u8 count = 0, dlbcn_count = 0; + bool b_recover = false; + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr | BIT(0)); + + /* Disable Hw protection for a time which revserd for Hw sending beacon. + * Fix download reserved page packet fail + * that access collision with the protection time. + * 2010.05.11. Added by tynli. + */ + _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0); + + /* Set FWHW_TXQ_CTRL 0x422[6]=0 to + * tell Hw the packet is not a real beacon frame. + */ + tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); + + if (tmp_reg422 & BIT(6)) + b_recover = true; + + do { + /* Clear beacon valid check bit */ + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2); + rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, + bcnvalid_reg | BIT(0)); + + /* download rsvd page */ + rtl92ee_set_fw_rsvdpagepkt(hw, false); + + txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3); + count = 0; + while ((txbc_reg & BIT(4)) && count < 20) { + count++; + udelay(10); + txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3); + } + rtl_write_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3, + txbc_reg | BIT(4)); + + /* check rsvd page download OK. */ + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2); + count = 0; + while (!(bcnvalid_reg & BIT(0)) && count < 20) { + count++; + udelay(50); + bcnvalid_reg = rtl_read_byte(rtlpriv, + REG_DWBCN0_CTRL + 2); + } + + if (bcnvalid_reg & BIT(0)) + rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, BIT(0)); + + dlbcn_count++; + } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + + if (!(bcnvalid_reg & BIT(0))) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Download RSVD page failed!\n"); + + /* Enable Bcn */ + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr & (~BIT(0))); +} + +void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR: + for (idx = 0; idx < ETH_ALEN; idx++) + rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]); + break; + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *)val)[0]; + + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1)); + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff); + break; } + case HW_VAR_BSSID: + for (idx = 0; idx < ETH_ALEN; idx++) + rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]); + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_TRACE, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + break; } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + + reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + rtlpriv->mac80211.short_preamble = short_preamble; + } + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); + break; + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + u8 fac; + u8 *reg = NULL; + u8 i = 0; + + reg = regtoset_normal; + + fac = *((u8 *)val); + if (fac <= 3) { + fac = (1 << (fac + 2)); + if (fac > 0xf) + fac = 0xf; + for (i = 0; i < 4; i++) { + if ((reg[i] & 0xf0) > (fac << 4)) + reg[i] = (reg[i] & 0x0f) | + (fac << 4); + if ((reg[i] & 0x0f) > fac) + reg[i] = (reg[i] & 0xf0) | fac; + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + i), + reg[i]); + } + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR:%#x\n", fac); + } + } + break; + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *)val); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + } + break; + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *)val); + union aci_aifsn *aifs = (union aci_aifsn *)(&mac->ac[0].aifs); + + u8 acm = aifs->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + } + break; + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + } + break; + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RETRY_LIMIT, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + } + break; + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + efuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + efuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl92ee_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *)val) | BIT(7))); + } + } + break; + case HW_VAR_H2C_FW_PWRMODE: + rtl92ee_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_RESUME_CLK_ON: + _rtl92ee_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION:{ + bool b_enter_fwlps = *((bool *)val); + + if (b_enter_fwlps) + _rtl92ee_fwlps_enter(hw); + else + _rtl92ee_fwlps_leave(hw); + } + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *)val); + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + _rtl92ee_download_rsvd_page(hw); + } + rtl92ee_set_fw_media_status_rpt_cmd(hw, mstatus); + } + break; + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl92ee_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, + (u2btmp | mac->assoc_id)); + } + break; + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl92ee_stop_tx_beacon(hw); + + _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl92ee_resume_tx_beacon(hw); + } + break; + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl92ee_fill_h2c_cmd(hw, H2C_92E_KEEP_ALIVE_CTRL, 2, array); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case %#x not processed\n", variable); + break; + } +} + +static bool _rtl92ee_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 txpktbuf_bndy; + u8 u8tmp, testcnt = 0; + + txpktbuf_bndy = 0xF7; + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80E60808); + + rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x3d00 - 1); + + rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 1, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_DWBCN1_CTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_BCNQ1_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_MGQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_PBP, 0x31); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2); + rtl_write_byte(rtlpriv, REG_AUTO_LLT + 2, u8tmp | BIT(0)); + + while (u8tmp & BIT(0)) { + u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2); + udelay(10); + testcnt++; + if (testcnt > 10) + break; + } + + return true; +} + +static void _rtl92ee_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92ee_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92ee_sw_led_on(hw, pin0); + else + rtl92ee_sw_led_off(hw, pin0); +} + +static bool _rtl92ee_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 bytetmp; + u16 wordtmp; + u32 dwordtmp; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); + + dwordtmp = rtl_read_dword(rtlpriv, REG_SYS_CFG1); + if (dwordtmp & BIT(24)) { + rtl_write_byte(rtlpriv, 0x7c, 0xc3); + } else { + bytetmp = rtl_read_byte(rtlpriv, 0x16); + rtl_write_byte(rtlpriv, 0x16, bytetmp | BIT(4) | BIT(6)); + rtl_write_byte(rtlpriv, 0x7c, 0x83); + } + /* 1. 40Mhz crystal source*/ + bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2); + bytetmp &= 0xfb; + rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp); + + dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4); + dwordtmp &= 0xfffffc7f; + rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp); + + /* 2. 92E AFE parameter + * MP chip then check version + */ + bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2); + bytetmp &= 0xbf; + rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp); + + dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4); + dwordtmp &= 0xffdfffff; + rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp); + + /* HW Power on sequence */ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, + RTL8192E_NIC_ENABLE_FLOW)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "init MAC Fail as rtl_hal_pwrseqcmdparsing\n"); + return false; + } + + /* Release MAC IO register reset */ + bytetmp = rtl_read_byte(rtlpriv, REG_CR); + bytetmp = 0xff; + rtl_write_byte(rtlpriv, REG_CR, bytetmp); + mdelay(2); + bytetmp = 0x7f; + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp); + mdelay(2); + + /* Add for wakeup online */ + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); + rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3)); + bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1); + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4))); + /* Release MAC IO register reset */ + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (!rtlhal->mac_func_enable) { + if (!_rtl92ee_llt_table_init(hw)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "LLT table init fail\n"); + return false; + } + } + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF5B1; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + /* Reported Tx status from HW for rate adaptive.*/ + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + + /* Set RCR register */ + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff); + + /* Set TCR register */ + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + /* Set TX/RX descriptor physical address -- HI part */ + if (!rtlpriv->cfg->mod_params->dma64) + goto dma64_end; + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA + 4, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >> + 32); + rtl_write_dword(rtlpriv, REG_MGQ_DESA + 4, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VOQ_DESA + 4, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VIQ_DESA + 4, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BEQ_DESA + 4, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BKQ_DESA + 4, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_HQ0_DESA + 4, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32); + + rtl_write_dword(rtlpriv, REG_RX_DESA + 4, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32); + +dma64_end: + + /* Set TX/RX descriptor physical address(from OS API). */ + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + + dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_DESA); + + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ0_DESA, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + /* if we want to support 64 bit DMA, we should set it here, + * but now we do not support 64 bit DMA + */ + + rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0x3fffffff); + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0xF7); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM, + TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); + /*Rx*/ + rtl_write_word(rtlpriv, REG_RX_RXBD_NUM, + RX_DESC_NUM_92E | + ((RTL8192EE_SEG_NUM << 13) & 0x6000) | 0x8000); + + rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0XFFFFFFFF); + + _rtl92ee_gen_refresh_led_state(hw); + return true; +} + +static void _rtl92ee_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rrsr; + + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + /* Init value for RRSR. */ + rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); + + /* ARFB table 9 for 11ac 5G 2SS */ + rtl_write_dword(rtlpriv, REG_ARFR0, 0x00000010); + rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0x3e0ff000); + + /* ARFB table 10 for 11ac 5G 1SS */ + rtl_write_dword(rtlpriv, REG_ARFR1, 0x00000010); + rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x000ff000); + + /* Set SLOT time */ + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + + /* CF-End setting. */ + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + + /* Set retry limit */ + rtl_write_word(rtlpriv, REG_RETRY_LIMIT, 0x0707); + + /* BAR settings */ + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x0201ffff); + + /* Set Data / Response auto rate fallack retry count */ + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + /* Beacon related, for rate adaptive */ + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + rtlpci->reg_bcn_ctrl_val = 0x1d; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + /* Marked out by Bruce, 2010-09-09. + * This register is configured for the 2nd Beacon (multiple BSSID). + * We shall disable this register if we only support 1 BSSID. + * vivi guess 92d also need this, also 92d now doesnot set this reg + */ + rtl_write_byte(rtlpriv, REG_BCN_CTRL_1, 0); + + /* TBTT prohibit hold time. Suggested by designer TimChen. */ + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */ + + rtl_write_byte(rtlpriv, REG_PIFS, 0); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x08ff); + + /* For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/ + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); + + /* ACKTO for IOT issue. */ + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + + /* Set Spec SIFS (used in NAV) */ + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x100a); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x100a); + + /* Set SIFS for CCK */ + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x100a); + + /* Set SIFS for OFDM */ + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a); + + /* Note Data sheet don't define */ + rtl_write_byte(rtlpriv, 0x4C7, 0x80); + + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20); + + rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, 0x1717); + + /* Set Multicast Address. 2009.01.07. by tynli. */ + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); +} + +static void _rtl92ee_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u32 tmp32 = 0, count = 0; + u8 tmp8 = 0; + + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x78); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count++; + } + + if (0 == tmp8) { + tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); + if ((tmp32 & 0xff00) != 0x2000) { + tmp32 &= 0xffff00ff; + rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, + tmp32 | BIT(13)); + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf078); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); + + tmp8 = rtl_read_byte(rtlpriv, + REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, + REG_BACKDOOR_DBI_DATA + 2); + count++; + } + } + } + + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x70c); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count++; + } + if (0 == tmp8) { + tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); + rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, + tmp32 | BIT(31)); + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf70c); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); + } + + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count++; + } + + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x718); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count++; + } + if (ppsc->support_backdoor || (0 == tmp8)) { + tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); + rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, + tmp32 | BIT(11) | BIT(12)); + rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf718); + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); + } + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count = 0; + while (tmp8 && count < 20) { + udelay(10); + tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); + count++; + } +} + +void rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + u8 tmp; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + tmp = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1)); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static bool _rtl8192ee_check_pcie_dma_hang(struct rtl_priv *rtlpriv) +{ + u8 tmp; + + /* write reg 0x350 Bit[26]=1. Enable debug port. */ + tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3); + if (!(tmp & BIT(2))) { + rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3, + tmp | BIT(2)); + mdelay(100); /* Suggested by DD Justin_tsai. */ + } + + /* read reg 0x350 Bit[25] if 1 : RX hang + * read reg 0x350 Bit[24] if 1 : TX hang + */ + tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3); + if ((tmp & BIT(0)) || (tmp & BIT(1))) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "CheckPcieDMAHang8192EE(): true!!\n"); + return true; + } + return false; +} + +static void _rtl8192ee_reset_pcie_interface_dma(struct rtl_priv *rtlpriv, + bool mac_power_on) +{ + u8 tmp; + bool release_mac_rx_pause; + u8 backup_pcie_dma_pause; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "ResetPcieInterfaceDMA8192EE()\n"); + + /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03" + * released by SD1 Alan. + */ + + /* 1. disable register write lock + * write 0x1C bit[1:0] = 2'h0 + * write 0xCC bit[2] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL); + tmp &= ~(BIT(1) | BIT(0)); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp); + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp |= BIT(2); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); + + /* 2. Check and pause TRX DMA + * write 0x284 bit[18] = 1'b1 + * write 0x301 = 0xFF + */ + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + if (tmp & BIT(2)) { + /* Already pause before the function for another reason. */ + release_mac_rx_pause = false; + } else { + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2))); + release_mac_rx_pause = true; + } + + backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1); + if (backup_pcie_dma_pause != 0xFF) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF); + + if (mac_power_on) { + /* 3. reset TRX function + * write 0x100 = 0x00 + */ + rtl_write_byte(rtlpriv, REG_CR, 0); + } + + /* 4. Reset PCIe DMA + * write 0x003 bit[0] = 0 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + /* 5. Enable PCIe DMA + * write 0x003 bit[0] = 1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + if (mac_power_on) { + /* 6. enable TRX function + * write 0x100 = 0xFF + */ + rtl_write_byte(rtlpriv, REG_CR, 0xFF); + + /* We should init LLT & RQPN and + * prepare Tx/Rx descrptor address later + * because MAC function is reset. + */ + } + + /* 7. Restore PCIe autoload down bit + * write 0xF8 bit[17] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2); + tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp); + + /* In MAC power on state, BB and RF maybe in ON state, + * if we release TRx DMA here + * it will cause packets to be started to Tx/Rx, + * so we release Tx/Rx DMA later. + */ + if (!mac_power_on) { + /* 8. release TRX DMA + * write 0x284 bit[18] = 1'b0 + * write 0x301 = 0x00 + */ + if (release_mac_rx_pause) { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, + (tmp & (~BIT(2)))); + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, + backup_pcie_dma_pause); + } + + /* 9. lock system register + * write 0xCC bit[2] = 1'b0 + */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp &= ~(BIT(2)); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); +} + +int rtl92ee_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool rtstatus = true; + int err = 0; + u8 tmp_u1b, u1byte; + u32 tmp_u4b; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8192EE hw init\n"); + rtlpriv->rtlhal.being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1); + u1byte = rtl_read_byte(rtlpriv, REG_CR); + if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) { + rtlhal->mac_func_enable = true; + } else { + rtlhal->mac_func_enable = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E; + } + + if (_rtl8192ee_check_pcie_dma_hang(rtlpriv)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "92ee dma hang!\n"); + _rtl8192ee_reset_pcie_interface_dma(rtlpriv, + rtlhal->mac_func_enable); + rtlhal->mac_func_enable = false; + } + + rtstatus = _rtl92ee_init_mac(hw); + + rtl_write_byte(rtlpriv, 0x577, 0x03); + + /*for Crystal 40 Mhz setting */ + rtl_write_byte(rtlpriv, REG_AFE_CTRL4, 0x2A); + rtl_write_byte(rtlpriv, REG_AFE_CTRL4 + 1, 0x00); + rtl_write_byte(rtlpriv, REG_AFE_CTRL2, 0x83); + + /*Forced the antenna b to wifi */ + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) { + rtl_write_byte(rtlpriv, 0x64, 0); + rtl_write_byte(rtlpriv, 0x65, 1); + } + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + return err; + } + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, 0x8000); + err = rtl92ee_download_fw(hw, false); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + rtlhal->fw_ready = false; + return err; + } + rtlhal->fw_ready = true; + /*fw related variable initialize */ + ppsc->fw_current_inpsmode = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + rtlhal->last_hmeboxnum = 0; + + rtl92ee_phy_mac_config(hw); + + rtl92ee_phy_bb_config(hw); + + rtl92ee_phy_rf_config(hw); + + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, RF90_PATH_A, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, RF90_PATH_B, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, + RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[0] = (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) | + BIT(10) | BIT(11); + + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + + /*---- Set CCK and OFDM Block "ON"----*/ + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + /* Must set this, + * otherwise the rx sensitivity will be very pool. Maddest + */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xB1, RFREG_OFFSET_MASK, 0x54418); + + /*Set Hardware(MAC default setting.)*/ + _rtl92ee_hw_configure(hw); + + rtlhal->mac_func_enable = true; + + rtl_cam_reset_all_entry(hw); + rtl92ee_enable_hw_security_config(hw); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl92ee_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + rtl92ee_bt_hw_init(hw); + + rtlpriv->rtlhal.being_init_adapter = false; + + if (ppsc->rfpwr_state == ERFON) { + if (rtlphy->iqk_initialized) { + rtl92ee_phy_iq_calibrate(hw, true); + } else { + rtl92ee_phy_iq_calibrate(hw, false); + rtlphy->iqk_initialized = true; + } + } + + rtlphy->rfpath_rx_enable[0] = true; + if (rtlphy->rf_type == RF_2T2R) + rtlphy->rfpath_rx_enable[1] = true; + + efuse_one_byte_read(hw, 0x1FA, &tmp_u1b); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n"); + } + + if ((!(tmp_u1b & BIT(1))) && (rtlphy->rf_type == RF_2T2R)) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path B\n"); + } + + rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128)); + + /*Fixed LDPC rx hang issue. */ + tmp_u4b = rtl_read_dword(rtlpriv, REG_SYS_SWR_CTRL1); + rtl_write_byte(rtlpriv, REG_SYS_SWR_CTRL2, 0x75); + tmp_u4b = (tmp_u4b & 0xfff00fff) | (0x7E << 12); + rtl_write_dword(rtlpriv, REG_SYS_SWR_CTRL1, tmp_u4b); + + rtl92ee_dm_init(hw); + + rtl_write_dword(rtlpriv, 0x4fc, 0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "end of Rtl8192EE hw init %x\n", err); + return 0; +} + +static enum version_8192e _rtl92ee_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + enum version_8192e version; + u32 value32; + + rtlphy->rf_type = RF_2T2R; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1); + if (value32 & TRP_VAUX_EN) + version = (enum version_8192e)VERSION_TEST_CHIP_2T2R_8192E; + else + version = (enum version_8192e)VERSION_NORMAL_CHIP_2T2R_8192E; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl92ee_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl92ee_stop_tx_beacon(hw); + _rtl92ee_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl92ee_resume_tx_beacon(hw); + _rtl92ee_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, MSR, bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl92ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + } +} + +int rtl92ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92ee_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP && + type != NL80211_IFTYPE_MESH_POINT) + rtl92ee_set_check_bssid(hw, true); + } else { + rtl92ee_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ +void rtl92ee_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl92ee_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */ + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8192ee: invalid aci: %d !\n", aci); + break; + } +} + +void rtl92ee_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92ee_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +static void _rtl92ee_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + rtlhal->mac_func_enable = false; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n"); + + /* Run LPS WL RFOFF flow */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8192E_NIC_LPS_ENTER_FLOW); + /* turn off RF */ + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + + /* ==== Reset digital sequence ====== */ + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) + rtl92ee_firmware_selfreset(hw); + + /* Reset MCU */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* HW card disable configuration. */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8192E_NIC_DISABLE_FLOW); + + /* Reset MCU IO Wrapper */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); + + /* lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); +} + +void rtl92ee_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8192ee card disable\n"); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + + _rtl92ee_set_media_status(hw, opmode); + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + _rtl92ee_poweroff_adapter(hw); + + /* after power off we should do iqk again */ + if (!rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->phy.iqk_initialized = false; +} + +void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); + + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); +} + +void rtl92ee_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl92ee_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtlpci->reg_bcn_ctrl_val |= BIT(3); + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); +} + +void rtl92ee_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); +} + +void rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92ee_disable_interrupt(hw); + rtl92ee_enable_interrupt(hw); +} + +static __always_inline u8 _rtl92ee_get_chnl_group(u8 chnl) +{ + u8 group = 0; + + if (chnl <= 14) { + if (1 <= chnl && chnl <= 2) + group = 0; + else if (3 <= chnl && chnl <= 5) + group = 1; + else if (6 <= chnl && chnl <= 8) + group = 2; + else if (9 <= chnl && chnl <= 11) + group = 3; + else if (12 <= chnl && chnl <= 14) + group = 4; + } else { + if (36 <= chnl && chnl <= 42) + group = 0; + else if (44 <= chnl && chnl <= 48) + group = 1; + else if (50 <= chnl && chnl <= 58) + group = 2; + else if (60 <= chnl && chnl <= 64) + group = 3; + else if (100 <= chnl && chnl <= 106) + group = 4; + else if (108 <= chnl && chnl <= 114) + group = 5; + else if (116 <= chnl && chnl <= 122) + group = 6; + else if (124 <= chnl && chnl <= 130) + group = 7; + else if (132 <= chnl && chnl <= 138) + group = 8; + else if (140 <= chnl && chnl <= 144) + group = 9; + else if (149 <= chnl && chnl <= 155) + group = 10; + else if (157 <= chnl && chnl <= 161) + group = 11; + else if (165 <= chnl && chnl <= 171) + group = 12; + else if (173 <= chnl && chnl <= 177) + group = 13; + } + return group; +} + +static void _rtl8192ee_read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pwr2g, + struct txpower_info_5g *pwr5g, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 rf, addr = EEPROM_TX_PWR_INX, group, i = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM92E(): PROMContent[0x%x]=0x%x\n", + (addr + 1), hwinfo[addr + 1]); + if (0xFF == hwinfo[addr+1]) /*YJ,add,120316*/ + autoload_fail = true; + + if (autoload_fail) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (rf = 0 ; rf < MAX_RF_PATH ; rf++) { + /* 2.4G default value */ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwr2g->index_cck_base[rf][group] = 0x2D; + pwr2g->index_bw40_base[rf][group] = 0x2D; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw20_diff[rf][0] = 0x02; + pwr2g->ofdm_diff[rf][0] = 0x04; + } else { + pwr2g->bw20_diff[rf][i] = 0xFE; + pwr2g->bw40_diff[rf][i] = 0xFE; + pwr2g->cck_diff[rf][i] = 0xFE; + pwr2g->ofdm_diff[rf][i] = 0xFE; + } + } + + /*5G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) + pwr5g->index_bw40_base[rf][group] = 0x2A; + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->ofdm_diff[rf][0] = 0x04; + pwr5g->bw20_diff[rf][0] = 0x00; + pwr5g->bw80_diff[rf][0] = 0xFE; + pwr5g->bw160_diff[rf][0] = 0xFE; + } else { + pwr5g->ofdm_diff[rf][0] = 0xFE; + pwr5g->bw20_diff[rf][0] = 0xFE; + pwr5g->bw40_diff[rf][0] = 0xFE; + pwr5g->bw80_diff[rf][0] = 0xFE; + pwr5g->bw160_diff[rf][0] = 0xFE; + } + } + } + return; + } + + rtl_priv(hw)->efuse.txpwr_fromeprom = true; + + for (rf = 0 ; rf < MAX_RF_PATH ; rf++) { + /*2.4G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwr2g->index_cck_base[rf][group] = hwinfo[addr++]; + if (pwr2g->index_cck_base[rf][group] == 0xFF) + pwr2g->index_cck_base[rf][group] = 0x2D; + } + for (group = 0 ; group < MAX_CHNL_GROUP_24G - 1; group++) { + pwr2g->index_bw40_base[rf][group] = hwinfo[addr++]; + if (pwr2g->index_bw40_base[rf][group] == 0xFF) + pwr2g->index_bw40_base[rf][group] = 0x2D; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw40_diff[rf][i] = 0; + if (hwinfo[addr] == 0xFF) { + pwr2g->bw20_diff[rf][i] = 0x02; + } else { + pwr2g->bw20_diff[rf][i] = (hwinfo[addr] + & 0xf0) >> 4; + if (pwr2g->bw20_diff[rf][i] & BIT(3)) + pwr2g->bw20_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr2g->ofdm_diff[rf][i] = 0x04; + } else { + pwr2g->ofdm_diff[rf][i] = (hwinfo[addr] + & 0x0f); + if (pwr2g->ofdm_diff[rf][i] & BIT(3)) + pwr2g->ofdm_diff[rf][i] |= 0xF0; + } + pwr2g->cck_diff[rf][i] = 0; + addr++; + } else { + if (hwinfo[addr] == 0xFF) { + pwr2g->bw40_diff[rf][i] = 0xFE; + } else { + pwr2g->bw40_diff[rf][i] = (hwinfo[addr] + & 0xf0) >> 4; + if (pwr2g->bw40_diff[rf][i] & BIT(3)) + pwr2g->bw40_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr2g->bw20_diff[rf][i] = 0xFE; + } else { + pwr2g->bw20_diff[rf][i] = (hwinfo[addr] + & 0x0f); + if (pwr2g->bw20_diff[rf][i] & BIT(3)) + pwr2g->bw20_diff[rf][i] |= 0xF0; + } + addr++; + + if (hwinfo[addr] == 0xFF) { + pwr2g->ofdm_diff[rf][i] = 0xFE; + } else { + pwr2g->ofdm_diff[rf][i] = (hwinfo[addr] + & 0xf0) >> 4; + if (pwr2g->ofdm_diff[rf][i] & BIT(3)) + pwr2g->ofdm_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr2g->cck_diff[rf][i] = 0xFE; + } else { + pwr2g->cck_diff[rf][i] = (hwinfo[addr] + & 0x0f); + if (pwr2g->cck_diff[rf][i] & BIT(3)) + pwr2g->cck_diff[rf][i] |= 0xF0; + } + addr++; + } + } + + /*5G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) { + pwr5g->index_bw40_base[rf][group] = hwinfo[addr++]; + if (pwr5g->index_bw40_base[rf][group] == 0xFF) + pwr5g->index_bw40_base[rf][group] = 0xFE; + } + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->bw40_diff[rf][i] = 0; + + if (hwinfo[addr] == 0xFF) { + pwr5g->bw20_diff[rf][i] = 0; + } else { + pwr5g->bw20_diff[rf][0] = (hwinfo[addr] + & 0xf0) >> 4; + if (pwr5g->bw20_diff[rf][i] & BIT(3)) + pwr5g->bw20_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr5g->ofdm_diff[rf][i] = 0x04; + } else { + pwr5g->ofdm_diff[rf][0] = (hwinfo[addr] + & 0x0f); + if (pwr5g->ofdm_diff[rf][i] & BIT(3)) + pwr5g->ofdm_diff[rf][i] |= 0xF0; + } + addr++; + } else { + if (hwinfo[addr] == 0xFF) { + pwr5g->bw40_diff[rf][i] = 0xFE; + } else { + pwr5g->bw40_diff[rf][i] = (hwinfo[addr] + & 0xf0) >> 4; + if (pwr5g->bw40_diff[rf][i] & BIT(3)) + pwr5g->bw40_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr5g->bw20_diff[rf][i] = 0xFE; + } else { + pwr5g->bw20_diff[rf][i] = (hwinfo[addr] + & 0x0f); + if (pwr5g->bw20_diff[rf][i] & BIT(3)) + pwr5g->bw20_diff[rf][i] |= 0xF0; + } + addr++; + } + } + + if (hwinfo[addr] == 0xFF) { + pwr5g->ofdm_diff[rf][1] = 0xFE; + pwr5g->ofdm_diff[rf][2] = 0xFE; + } else { + pwr5g->ofdm_diff[rf][1] = (hwinfo[addr] & 0xf0) >> 4; + pwr5g->ofdm_diff[rf][2] = (hwinfo[addr] & 0x0f); + } + addr++; + + if (hwinfo[addr] == 0xFF) + pwr5g->ofdm_diff[rf][3] = 0xFE; + else + pwr5g->ofdm_diff[rf][3] = (hwinfo[addr] & 0x0f); + addr++; + + for (i = 1; i < MAX_TX_COUNT; i++) { + if (pwr5g->ofdm_diff[rf][i] == 0xFF) + pwr5g->ofdm_diff[rf][i] = 0xFE; + else if (pwr5g->ofdm_diff[rf][i] & BIT(3)) + pwr5g->ofdm_diff[rf][i] |= 0xF0; + } + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (hwinfo[addr] == 0xFF) { + pwr5g->bw80_diff[rf][i] = 0xFE; + } else { + pwr5g->bw80_diff[rf][i] = (hwinfo[addr] & 0xf0) + >> 4; + if (pwr5g->bw80_diff[rf][i] & BIT(3)) + pwr5g->bw80_diff[rf][i] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pwr5g->bw160_diff[rf][i] = 0xFE; + } else { + pwr5g->bw160_diff[rf][i] = + (hwinfo[addr] & 0x0f); + if (pwr5g->bw160_diff[rf][i] & BIT(3)) + pwr5g->bw160_diff[rf][i] |= 0xF0; + } + addr++; + } + } +} + +static noinline_for_stack void +_rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwr2g; + struct txpower_info_5g pwr5g; + u8 rf, idx; + u8 i; + + _rtl8192ee_read_power_value_fromprom(hw, &pwr2g, &pwr5g, + autoload_fail, hwinfo); + + for (rf = 0; rf < MAX_RF_PATH; rf++) { + for (i = 0; i < 14; i++) { + idx = _rtl92ee_get_chnl_group(i + 1); + + if (i == CHANNEL_MAX_NUMBER_2G - 1) { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][5]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][idx]; + } else { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][idx]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][idx]; + } + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { + idx = _rtl92ee_get_chnl_group(channel5g[i]); + efu->txpwr_5g_bw40base[rf][i] = + pwr5g.index_bw40_base[rf][idx]; + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { + u8 upper, lower; + + idx = _rtl92ee_get_chnl_group(channel5g_80m[i]); + upper = pwr5g.index_bw40_base[rf][idx]; + lower = pwr5g.index_bw40_base[rf][idx + 1]; + + efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i]; + efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i]; + efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i]; + efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i]; + + efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i]; + efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i]; + efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i]; + efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i]; + } + } + + if (!autoload_fail) + efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_92E]; + else + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + + if (efu->eeprom_thermalmeter == 0xff || autoload_fail) { + efu->apk_thermalmeterignore = true; + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + } + + efu->thermalmeter[0] = efu->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", efu->eeprom_thermalmeter); + + if (!autoload_fail) { + efu->eeprom_regulatory = hwinfo[EEPROM_RF_BOARD_OPTION_92E] + & 0x07; + if (hwinfo[EEPROM_RF_BOARD_OPTION_92E] == 0xFF) + efu->eeprom_regulatory = 0; + } else { + efu->eeprom_regulatory = 0; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", efu->eeprom_regulatory); +} + +static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int params[] = {RTL8192E_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13}; + u8 *hwinfo; + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + if (rtlefuse->eeprom_oemid == 0xFF) + rtlefuse->eeprom_oemid = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + /*tx power*/ + _rtl92ee_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + rtl92ee_read_bt_coexist_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + /*board type*/ + rtlefuse->board_type = (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E]) + & 0xE0) >> 5); + if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E]) == 0xFF) + rtlefuse->board_type = 0; + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) + rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */ + + rtlhal->board_type = rtlefuse->board_type; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "board_type = 0x%x\n", rtlefuse->board_type); + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_92E]; + if (hwinfo[EEPROM_XTAL_92E] == 0xFF) + rtlefuse->crystalcap = 0x20; + + /*antenna diversity*/ + rtlefuse->antenna_div_type = NO_ANTDIV; + rtlefuse->antenna_div_cfg = 0; + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x818B) { + if ((rtlefuse->eeprom_svid == 0x10EC) && + (rtlefuse->eeprom_smid == 0x001B)) + rtlhal->oem_id = RT_CID_819X_LENOVO; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } + } +exit: + kfree(hwinfo); +} + +static void _rtl92ee_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpriv->ledctl.led_opendrain = true; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92ee_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) { + rtlpriv->dm.rfpath_rxenable[0] = true; + } else { + rtlpriv->dm.rfpath_rxenable[0] = true; + rtlpriv->dm.rfpath_rxenable[1] = true; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl92ee_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl92ee_hal_customized_behavior(hw); + + rtlphy->rfpath_rx_enable[0] = true; + if (rtlphy->rf_type == RF_2T2R) + rtlphy->rfpath_rx_enable[1] = true; +} + +static u8 _rtl92ee_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index) +{ + u8 ret = 0; + + switch (rate_index) { + case RATR_INX_WIRELESS_NGB: + ret = 0; + break; + case RATR_INX_WIRELESS_N: + case RATR_INX_WIRELESS_NG: + ret = 4; + break; + case RATR_INX_WIRELESS_NB: + ret = 2; + break; + case RATR_INX_WIRELESS_GB: + ret = 6; + break; + case RATR_INX_WIRELESS_G: + ret = 7; + break; + case RATR_INX_WIRELESS_B: + ret = 8; + break; + default: + ret = 0; + break; + } + return ret; +} + +static void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ? 1 : 0; + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool b_shortgi = false; + u8 rate_mask[7] = {0}; + u8 macid = 0; + /*u8 mimo_ps = IEEE80211_SMPS_OFF;*/ + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_N_24G: + if (curtxbw_40mhz) + ratr_index = RATR_INX_WIRELESS_NGB; + else + ratr_index = RATR_INX_WIRELESS_NB; + + if (rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0ffff000; + else + ratr_bitmap &= 0x0ffff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0ffff000; + else + ratr_bitmap &= 0x0ffff005; + } + } + + if ((curtxbw_40mhz && b_curshortgi_40mhz) || + (!curtxbw_40mhz && b_curshortgi_20mhz)) { + if (macid == 0) + b_shortgi = true; + else if (macid == 1) + b_shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T1R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f8ff0ff; + break; + } + ratr_index = _rtl92ee_mrate_idx_to_arfr_id(hw, ratr_index); + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[0] = macid; + rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00); + rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3); + rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); + rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); + rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); + rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], rate_mask[4], + rate_mask[5], rate_mask[6]); + rtl92ee_fill_h2c_cmd(hw, H2C_92E_RA_MASK, 7, rate_mask); + _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl92ee_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw); +} + +void rtl92ee_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + *valid = 1; + return true; +} + +void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } + } +} + +void rtl92ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + + if (!auto_load_fail) { + value = hwinfo[EEPROM_RF_BOARD_OPTION_92E]; + if (((value & 0xe0) >> 5) == 0x1) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E; + rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; + } else { + rtlpriv->btcoexist.btc_info.btcoexist = 1; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E; + rtlpriv->btcoexist.btc_info.ant_num = ANT_X1; + } +} + +void rtl92ee_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl92ee_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); +} + +void rtl92ee_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl92ee_resume(struct ieee80211_hw *hw) +{ +} + +/* Turn on AAP (RCR:bit 0) for promicuous mode. */ +void rtl92ee_allow_all_destaddr(struct ieee80211_hw *hw, + bool allow_all_da, bool write_into_reg) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + if (allow_all_da) /* Set BIT0 */ + rtlpci->receive_config |= RCR_AAP; + else /* Clear BIT0 */ + rtlpci->receive_config &= ~RCR_AAP; + + if (write_into_reg) + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + + rtl_dbg(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, + "receive_config=0x%08X, write_into_reg=%d\n", + rtlpci->receive_config, write_into_reg); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h new file mode 100644 index 000000000..fc2243926 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_HW_H__ +#define __RTL92E_HW_H__ + +void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl92ee_hw_init(struct ieee80211_hw *hw); +void rtl92ee_card_disable(struct ieee80211_hw *hw); +void rtl92ee_enable_interrupt(struct ieee80211_hw *hw); +void rtl92ee_disable_interrupt(struct ieee80211_hw *hw); +int rtl92ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92ee_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92ee_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92ee_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92ee_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl92ee_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); +void rtl92ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl92ee_bt_reg_init(struct ieee80211_hw *hw); +void rtl92ee_bt_hw_init(struct ieee80211_hw *hw); +void rtl92ee_suspend(struct ieee80211_hw *hw); +void rtl92ee_resume(struct ieee80211_hw *hw); +void rtl92ee_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da, + bool write_into_reg); +void rtl92ee_fw_clk_off_timer_callback(unsigned long data); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c new file mode 100644 index 000000000..a9b5e3c88 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl92ee_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u32 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_dword(rtlpriv , REG_GPIO_PIN_CTRL); + ledcfg &= ~BIT(13); + ledcfg |= BIT(21); + ledcfg &= ~BIT(29); + + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, ledcfg); + + break; + case LED_PIN_LED1: + + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +void rtl92ee_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + + ledcfg = rtl_read_dword(rtlpriv , REG_GPIO_PIN_CTRL); + ledcfg |= ~BIT(21); + ledcfg &= ~BIT(29); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, ledcfg); + + break; + case LED_PIN_LED1: + + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl92ee_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92ee_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl92ee_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl92ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", ledaction); + _rtl92ee_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h new file mode 100644 index 000000000..08b8ff328 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_LED_H__ +#define __RTL92E_LED_H__ + +void rtl92ee_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92ee_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c new file mode 100644 index 000000000..1e7f0cd1c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c @@ -0,0 +1,3164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" + +static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); +static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, + u8 configtype); +static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw, + u8 configtype); +static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw); +static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, + u32 msdelay); +static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, + u8 *step, u32 *delay); +static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl92ee_phy_set_io(struct ieee80211_hw *hw); + +u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + + return returnvalue; +} + +void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} + +u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 addr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + addr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); + bitshift = calculate_bit_shift(bitmask); + data = (original_value & (~bitmask)) | (data << bitshift); + } + + _rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data); + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + addr, bitmask, data, rfpath); +} + +static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0xff; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + pr_err("return all one\n"); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + udelay(20); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSIREADBACKDATA); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); + return retvalue; +} + +static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + pr_err("stop\n"); + return; + } + offset &= 0xff; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFW-%d Addr[0x%x]=0x%x\n", rfpath, + pphyreg->rf3wire_offset, data_and_addr); +} + +bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) +{ + return _rtl92ee_phy_config_mac_with_headerfile(hw); +} + +bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = true; + u16 regval; + u32 tmp; + u8 crystal_cap; + + phy_init_bb_rf_register_def(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTN | FEN_BBRSTB); + + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + + tmp = rtl_read_dword(rtlpriv, 0x4c); + rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); + + rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw); + + crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + return rtstatus; +} + +bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92ee_phy_rf6052_config(hw); +} + +static bool _check_condition(struct ieee80211_hw *hw, + const u32 condition) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 _board = rtlefuse->board_type; /*need efuse define*/ + u32 _interface = rtlhal->interface; + u32 _platform = 0x08;/*SupportPlatform */ + u32 cond = condition; + + if (condition == 0xCDCDCDCD) + return true; + + cond = condition & 0xFF; + if ((_board != cond) && (cond != 0xFF)) + return false; + + cond = condition & 0xFF00; + cond = cond >> 8; + if ((_interface & cond) == 0 && cond != 0x07) + return false; + + cond = condition & 0xFF0000; + cond = cond >> 16; + if ((_platform & cond) == 0 && cond != 0x0F) + return false; + + return true; +} + +static void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data, + enum radio_path rfpath, u32 regaddr) +{ + if (addr == 0xfe || addr == 0xffe) { + mdelay(50); + } else { + rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); + udelay(1); + + if (addr == 0xb6) { + u32 getvalue; + u8 count = 0; + + getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD); + udelay(1); + + while ((getvalue >> 8) != (data >> 8)) { + count++; + rtl_set_rfreg(hw, rfpath, regaddr, + RFREG_OFFSET_MASK, data); + udelay(1); + getvalue = rtl_get_rfreg(hw, rfpath, addr, + MASKDWORD); + if (count > 5) + break; + } + } + + if (addr == 0xb2) { + u32 getvalue; + u8 count = 0; + + getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD); + udelay(1); + + while (getvalue != data) { + count++; + rtl_set_rfreg(hw, rfpath, regaddr, + RFREG_OFFSET_MASK, data); + udelay(1); + rtl_set_rfreg(hw, rfpath, 0x18, + RFREG_OFFSET_MASK, 0x0fc07); + udelay(1); + getvalue = rtl_get_rfreg(hw, rfpath, addr, + MASKDWORD); + if (count > 5) + break; + } + } + } +} + +static void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1000; /*RF Content: radio_a_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A, + addr | maskforphyset); +} + +static void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1001; /*RF Content: radio_b_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B, + addr | maskforphyset); +} + +static void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + if (addr == 0xfe) + mdelay(50); + else if (addr == 0xfd) + mdelay(5); + else if (addr == 0xfc) + mdelay(1); + else if (addr == 0xfb) + udelay(50); + else if (addr == 0xfa) + udelay(5); + else if (addr == 0xf9) + udelay(1); + else + rtl_set_bbreg(hw, addr, MASKDWORD , data); + + udelay(1); +} + +static void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0; + + for (; band <= BAND_ON_5G; ++band) + for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf) + for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) + for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec) + rtlphy->tx_power_by_rate_offset + [band][rf][txnum][sec] = 0; +} + +static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, + u8 rate_section, u8 txnum, + u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d\n", path); + return; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; + break; + case OFDM: + rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; + break; + case HT_MCS0_MCS7: + rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; + break; + case HT_MCS8_MCS15: + rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d\n", band); + } +} + +static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, u8 txnum, + u8 rate_section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 value = 0; + + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d\n", path); + return 0; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; + break; + case OFDM: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; + break; + case HT_MCS0_MCS7: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; + break; + case HT_MCS8_MCS15: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d()\n", band); + } + return value; +} + +static void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u16 raw = 0; + u8 base = 0, path = 0; + + for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { + if (path == RF90_PATH_A) { + raw = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & + 0xFF; + base = (raw >> 4) * 10 + (raw & 0xF); + _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, CCK, RF_1TX, + base); + } else if (path == RF90_PATH_B) { + raw = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & + 0xFF; + base = (raw >> 4) * 10 + (raw & 0xF); + _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, CCK, RF_1TX, + base); + } + raw = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF; + base = (raw >> 4) * 10 + (raw & 0xF); + _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, + OFDM, RF_1TX, base); + + raw = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF; + base = (raw >> 4) * 10 + (raw & 0xF); + _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, + HT_MCS0_MCS7, RF_1TX, + base); + + raw = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF; + base = (raw >> 4) * 10 + (raw & 0xF); + _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, + HT_MCS8_MCS15, RF_2TX, + base); + } +} + +static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, + u8 end, u8 base) +{ + s8 i = 0; + u8 tmp = 0; + u32 temp_data = 0; + + for (i = 3; i >= 0; --i) { + if (i >= start && i <= end) { + /* Get the exact value */ + tmp = (u8)(*data >> (i * 8)) & 0xF; + tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10; + + /* Change the value to a relative value */ + tmp = (tmp > base) ? tmp - base : base - tmp; + } else { + tmp = (u8)(*data >> (i * 8)) & 0xFF; + } + temp_data <<= 8; + temp_data |= tmp; + } + *data = temp_data; +} + +static void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 base = 0, rf = 0, band = BAND_ON_2_4G; + + for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) { + if (rf == RF90_PATH_A) { + base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, + rf, RF_1TX, + CCK); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset + [band][rf][RF_1TX][2], + 1, 1, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset + [band][rf][RF_1TX][3], + 1, 3, base); + } else if (rf == RF90_PATH_B) { + base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, + rf, RF_1TX, + CCK); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset + [band][rf][RF_1TX][3], + 0, 0, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset + [band][rf][RF_1TX][2], + 1, 3, base); + } + base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, + RF_1TX, OFDM); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1], + 0, 3, base); + + base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, + RF_1TX, + HT_MCS0_MCS7); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5], + 0, 3, base); + + base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, + RF_2TX, + HT_MCS8_MCS15); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6], + 0, 3, base); + + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7], + 0, 3, base); + } + + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "<==%s\n", __func__); +} + +static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) +{ + _rtl92ee_phy_store_txpower_by_rate_base(hw); + phy_convert_txpwr_dbm_to_rel_val(hw); +} + +static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + + _rtl92ee_phy_init_tx_power_by_rate(hw); + if (!rtlefuse->autoload_failflag) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = + phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG); + } + _rtl92ee_phy_txpower_by_rate_configuration(hw); + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + + return true; +} + +static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n"); + arraylength = RTL8192EE_MAC_ARRAY_LEN; + ptrarray = RTL8192EE_MAC_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Img:RTL8192EE_MAC_ARRAY LEN %d\n", arraylength); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); + return true; +} + +#define READ_NEXT_PAIR(v1, v2, i) \ + do { \ + i += 2; \ + v1 = array[i]; \ + v2 = array[i+1]; \ + } while (0) + +static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *array; + u16 len; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 v1 = 0, v2 = 0; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + len = RTL8192EE_PHY_REG_ARRAY_LEN; + array = RTL8192EE_PHY_REG_ARRAY; + + for (i = 0; i < len; i = i + 2) { + v1 = array[i]; + v2 = array[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl92ee_config_bb_reg(hw, v1, v2); + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= len - 2) + break; + + if (!_check_condition(hw , array[i])) { + /*Discard the following pairs*/ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + READ_NEXT_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + } else { + /* Configure matched pairs and + * skip to end of if-else. + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + _rtl92ee_config_bb_reg(hw, v1, + v2); + READ_NEXT_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < len - 2) + READ_NEXT_PAIR(v1, v2, i); + } + } + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + len = RTL8192EE_AGC_TAB_ARRAY_LEN; + array = RTL8192EE_AGC_TAB_ARRAY; + + for (i = 0; i < len; i = i + 2) { + v1 = array[i]; + v2 = array[i+1]; + if (v1 < 0xCDCDCDCD) { + rtl_set_bbreg(hw, array[i], MASKDWORD, + array[i + 1]); + udelay(1); + continue; + } else{/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= len - 2) + break; + + if (!_check_condition(hw , array[i])) { + /*Discard the following pairs*/ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < len - 2) { + READ_NEXT_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + } else { + /* Configure matched pairs and + * skip to end of if-else. + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < len - 2) { + rtl_set_bbreg(hw, + array[i], + MASKDWORD, + array[i + 1]); + udelay(1); + READ_NEXT_PAIR(v1 , v2 , i); + } + + while (v2 != 0xDEAD && + i < len - 2) { + READ_NEXT_PAIR(v1 , v2 , i); + } + } + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", + array[i], + array[i + 1]); + } + } + return true; +} + +static u8 _rtl92ee_get_rate_section_index(u32 regaddr) +{ + u8 index = 0; + + switch (regaddr) { + case RTXAGC_A_RATE18_06: + case RTXAGC_B_RATE18_06: + index = 0; + break; + case RTXAGC_A_RATE54_24: + case RTXAGC_B_RATE54_24: + index = 1; + break; + case RTXAGC_A_CCK1_MCS32: + case RTXAGC_B_CCK1_55_MCS32: + index = 2; + break; + case RTXAGC_B_CCK11_A_CCK2_11: + index = 3; + break; + case RTXAGC_A_MCS03_MCS00: + case RTXAGC_B_MCS03_MCS00: + index = 4; + break; + case RTXAGC_A_MCS07_MCS04: + case RTXAGC_B_MCS07_MCS04: + index = 5; + break; + case RTXAGC_A_MCS11_MCS08: + case RTXAGC_B_MCS11_MCS08: + index = 6; + break; + case RTXAGC_A_MCS15_MCS12: + case RTXAGC_B_MCS15_MCS12: + index = 7; + break; + default: + regaddr &= 0xFFF; + if (regaddr >= 0xC20 && regaddr <= 0xC4C) + index = (u8)((regaddr - 0xC20) / 4); + else if (regaddr >= 0xE20 && regaddr <= 0xE4C) + index = (u8)((regaddr - 0xE20) / 4); + break; + } + return index; +} + +static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw, + enum band_type band, + enum radio_path rfpath, + u32 txnum, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 section = _rtl92ee_get_rate_section_index(regaddr); + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band); + return; + } + + if (rfpath > MAX_RF_PATH - 1) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, + "Invalid RfPath %d\n", rfpath); + return; + } + if (txnum > MAX_RF_PATH - 1) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); + return; + } + + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data; +} + +static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0; + + phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN; + phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 6) { + v1 = phy_regarray_table_pg[i]; + v2 = phy_regarray_table_pg[i+1]; + v3 = phy_regarray_table_pg[i+2]; + v4 = phy_regarray_table_pg[i+3]; + v5 = phy_regarray_table_pg[i+4]; + v6 = phy_regarray_table_pg[i+5]; + + if (v1 < 0xcdcdcdcd) { + _rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3, + v4, v5, v6); + continue; + } + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +#define READ_NEXT_RF_PAIR(v1, v2, i) \ + do { \ + i += 2; \ + v1 = array[i]; \ + v2 = array[i+1]; \ + } while (0) + +bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *array; + u16 len; + u32 v1 = 0, v2 = 0; + + switch (rfpath) { + case RF90_PATH_A: + len = RTL8192EE_RADIOA_ARRAY_LEN; + array = RTL8192EE_RADIOA_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n", len); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + for (i = 0; i < len; i = i + 2) { + v1 = array[i]; + v2 = array[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl92ee_config_rf_radio_a(hw, v1, v2); + continue; + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= len - 2) + break; + + if (!_check_condition(hw , array[i])) { + /*Discard the following pairs*/ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + READ_NEXT_RF_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + } else { + /* Configure matched pairs and + * skip to end of if-else. + */ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + _rtl92ee_config_rf_radio_a(hw, + v1, + v2); + READ_NEXT_RF_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < len - 2) + READ_NEXT_RF_PAIR(v1, v2, i); + } + } + } + break; + + case RF90_PATH_B: + len = RTL8192EE_RADIOB_ARRAY_LEN; + array = RTL8192EE_RADIOB_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n", len); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + for (i = 0; i < len; i = i + 2) { + v1 = array[i]; + v2 = array[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl92ee_config_rf_radio_b(hw, v1, v2); + continue; + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= len - 2) + break; + + if (!_check_condition(hw , array[i])) { + /*Discard the following pairs*/ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + READ_NEXT_RF_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + } else { + /* Configure matched pairs and + * skip to end of if-else. + */ + READ_NEXT_RF_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && i < len - 2) { + _rtl92ee_config_rf_radio_b(hw, + v1, + v2); + READ_NEXT_RF_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < len - 2) + READ_NEXT_RF_PAIR(v1, v2, i); + } + } + } + break; + case RF90_PATH_C: + case RF90_PATH_D: + break; + } + return true; +} + +void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; +} + +void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > + txpwr_dbm) + txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path, + u8 rate) +{ + u8 rate_section = 0; + + switch (rate) { + case DESC92C_RATE1M: + rate_section = 2; + break; + case DESC92C_RATE2M: + case DESC92C_RATE5_5M: + if (path == RF90_PATH_A) + rate_section = 3; + else if (path == RF90_PATH_B) + rate_section = 2; + break; + case DESC92C_RATE11M: + rate_section = 3; + break; + case DESC92C_RATE6M: + case DESC92C_RATE9M: + case DESC92C_RATE12M: + case DESC92C_RATE18M: + rate_section = 0; + break; + case DESC92C_RATE24M: + case DESC92C_RATE36M: + case DESC92C_RATE48M: + case DESC92C_RATE54M: + rate_section = 1; + break; + case DESC92C_RATEMCS0: + case DESC92C_RATEMCS1: + case DESC92C_RATEMCS2: + case DESC92C_RATEMCS3: + rate_section = 4; + break; + case DESC92C_RATEMCS4: + case DESC92C_RATEMCS5: + case DESC92C_RATEMCS6: + case DESC92C_RATEMCS7: + rate_section = 5; + break; + case DESC92C_RATEMCS8: + case DESC92C_RATEMCS9: + case DESC92C_RATEMCS10: + case DESC92C_RATEMCS11: + rate_section = 6; + break; + case DESC92C_RATEMCS12: + case DESC92C_RATEMCS13: + case DESC92C_RATEMCS14: + case DESC92C_RATEMCS15: + rate_section = 7; + break; + default: + WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n"); + break; + } + return rate_section; +} + +static u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw, + enum band_type band, + enum radio_path rf, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 shift = 0, sec, tx_num; + s8 diff = 0; + + sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate); + tx_num = RF_TX_NUM_NONIMPLEMENT; + + if (tx_num == RF_TX_NUM_NONIMPLEMENT) { + if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)) + tx_num = RF_2TX; + else + tx_num = RF_1TX; + } + + switch (rate) { + case DESC92C_RATE1M: + case DESC92C_RATE6M: + case DESC92C_RATE24M: + case DESC92C_RATEMCS0: + case DESC92C_RATEMCS4: + case DESC92C_RATEMCS8: + case DESC92C_RATEMCS12: + shift = 0; + break; + case DESC92C_RATE2M: + case DESC92C_RATE9M: + case DESC92C_RATE36M: + case DESC92C_RATEMCS1: + case DESC92C_RATEMCS5: + case DESC92C_RATEMCS9: + case DESC92C_RATEMCS13: + shift = 8; + break; + case DESC92C_RATE5_5M: + case DESC92C_RATE12M: + case DESC92C_RATE48M: + case DESC92C_RATEMCS2: + case DESC92C_RATEMCS6: + case DESC92C_RATEMCS10: + case DESC92C_RATEMCS14: + shift = 16; + break; + case DESC92C_RATE11M: + case DESC92C_RATE18M: + case DESC92C_RATE54M: + case DESC92C_RATEMCS3: + case DESC92C_RATEMCS7: + case DESC92C_RATEMCS11: + case DESC92C_RATEMCS15: + shift = 24; + break; + default: + WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n"); + break; + } + + diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >> + shift) & 0xff; + + return diff; +} + +static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw, + enum radio_path rfpath, u8 rate, + u8 bw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + u8 index = (channel - 1); + u8 tx_power = 0; + u8 diff = 0; + + if (channel < 1 || channel > 14) { + index = 0; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG, + "Illegal channel!!\n"); + } + + if (IS_CCK_RATE((s8)rate)) + tx_power = rtlefuse->txpwrlevel_cck[rfpath][index]; + else if (DESC92C_RATE6M <= rate) + tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index]; + + /* OFDM-1T*/ + if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && + !IS_CCK_RATE((s8)rate)) + tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S]; + + /* BW20-1S, BW20-2S */ + if (bw == HT_CHANNEL_WIDTH_20) { + if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) + tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S]; + if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) + tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S]; + } else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */ + if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) + tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S]; + if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) + tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S]; + } + + if (rtlefuse->eeprom_regulatory != 2) + diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G, + rfpath, rate); + + tx_power += diff; + + if (tx_power > MAX_POWER_INDEX) + tx_power = MAX_POWER_INDEX; + + return tx_power; +} + +static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx, + enum radio_path rfpath, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rfpath == RF90_PATH_A) { + switch (rate) { + case DESC92C_RATE1M: + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE2M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE5_5M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE11M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATE6M: + rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATE9M: + rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE12M: + rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE18M: + rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATE24M: + rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATE36M: + rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE48M: + rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE54M: + rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS0: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS1: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS2: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS3: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS4: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS5: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS6: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS7: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS8: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS9: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS10: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS11: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS12: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS13: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS14: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS15: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3, + pwr_idx); + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Rate!!\n"); + break; + } + } else if (rfpath == RF90_PATH_B) { + switch (rate) { + case DESC92C_RATE1M: + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE2M: + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE5_5M: + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATE11M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATE6M: + rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATE9M: + rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE12M: + rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE18M: + rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATE24M: + rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATE36M: + rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATE48M: + rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATE54M: + rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS0: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS1: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS2: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS3: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS4: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS5: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS6: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS7: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS8: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS9: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS10: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS11: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3, + pwr_idx); + break; + case DESC92C_RATEMCS12: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0, + pwr_idx); + break; + case DESC92C_RATEMCS13: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1, + pwr_idx); + break; + case DESC92C_RATEMCS14: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2, + pwr_idx); + break; + case DESC92C_RATEMCS15: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3, + pwr_idx); + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Rate!!\n"); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); + } +} + +static void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw, + enum radio_path rfpath, u8 bw, + u8 channel, u8 *rates, u8 size) +{ + u8 i; + u8 power_index; + + for (i = 0; i < size; i++) { + power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i], + bw, channel); + _rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]); + } +} + +static void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw, + enum radio_path rfpath, + u8 channel, + enum rate_section section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (section == CCK) { + u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M, + DESC92C_RATE5_5M, DESC92C_RATE11M}; + if (rtlhal->current_bandtype == BAND_ON_2_4G) + phy_set_txpower_index_by_rate_array(hw, rfpath, + rtlphy->current_chan_bw, + channel, cck_rates, 4); + } else if (section == OFDM) { + u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M, + DESC92C_RATE12M, DESC92C_RATE18M, + DESC92C_RATE24M, DESC92C_RATE36M, + DESC92C_RATE48M, DESC92C_RATE54M}; + phy_set_txpower_index_by_rate_array(hw, rfpath, + rtlphy->current_chan_bw, + channel, ofdm_rates, 8); + } else if (section == HT_MCS0_MCS7) { + u8 ht_rates1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1, + DESC92C_RATEMCS2, DESC92C_RATEMCS3, + DESC92C_RATEMCS4, DESC92C_RATEMCS5, + DESC92C_RATEMCS6, DESC92C_RATEMCS7}; + phy_set_txpower_index_by_rate_array(hw, rfpath, + rtlphy->current_chan_bw, + channel, ht_rates1t, 8); + } else if (section == HT_MCS8_MCS15) { + u8 ht_rates2t[] = {DESC92C_RATEMCS8, DESC92C_RATEMCS9, + DESC92C_RATEMCS10, DESC92C_RATEMCS11, + DESC92C_RATEMCS12, DESC92C_RATEMCS13, + DESC92C_RATEMCS14, DESC92C_RATEMCS15}; + phy_set_txpower_index_by_rate_array(hw, rfpath, + rtlphy->current_chan_bw, + channel, ht_rates2t, 8); + } else + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, + "Invalid RateSection %d\n", section); +} + +void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtl_priv(hw)->phy; + enum radio_path rfpath; + + if (!rtlefuse->txpwr_fromeprom) + return; + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + phy_set_txpower_index_by_rate_section(hw, rfpath, + channel, CCK); + phy_set_txpower_index_by_rate_section(hw, rfpath, + channel, OFDM); + phy_set_txpower_index_by_rate_section(hw, rfpath, + channel, + HT_MCS0_MCS7); + + if (rtlphy->num_total_rfpath >= 2) + phy_set_txpower_index_by_rate_section(hw, + rfpath, channel, + HT_MCS8_MCS15); + } +} + +static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = (reg_prsr_rsc & 0x90) | + (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT, + (BIT(31) | BIT(30)), 0); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, + mac->cur_40_prime_sc); + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); +} + +void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92ee_phy_set_bw_mode_callback(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "false driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 delay; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92ee_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + WARN_ONCE((rtlphy->current_channel > 14), + "rtl8192ee: WIRELESS_MODE_G but channel>14"); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92ee_phy_sw_chnl_callback(hw); + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false schedule workitem current channel %d\n", + rtlphy->current_channel); + rtlphy->sw_chnl_inprogress = false; + } else { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8192ee: illegal channel for Zebra: %d\n", channel); + + _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, + CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, + 0, 0, 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + pr_err("Invalid 'stage' = %d, Check it!\n", + *stage); + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) + return true; + (*stage)++; + (*step) = 0; + continue; + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92ee_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffff00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + 0x3ff, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8192ee: cmdtable cannot be NULL.\n"); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +static u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c; + u8 result = 0x00; + /* path-A IQK setting */ + /* PA/PAD controlled by 0x0 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000); + + /*LO calibration setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /*One shot, path A LOK & IQK*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + return result; +} + +static u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc; + u8 result = 0x00; + + /* PA/PAD controlled by 0x0 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /*One shot, path B LOK & IQK*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + return result; +} + +static u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp; + u8 result = 0x00; + + /*Get TXIMR Setting*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); + + /*PA/PAD control by 0x56, and set = 0x0*/ + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980); + rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000); + + /*enter IQK mode*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /*path a IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) { + result |= 0x01; + } else { + /* PA/PAD controlled by 0x0 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); + return result; + } + + u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000) | + ((reg_e9c & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); + /*RX IQK*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); + + /*PA/PAD control by 0x56, and set = 0x0*/ + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980); + rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000); + + /*enter IQK mode*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /*path a IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891); + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + /*Check failed*/ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + /*PA/PAD controlled by 0x0*/ + /*leave IQK mode*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); + /*if Tx is OK, check whether Rx is OK*/ + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + + return result; +} + +static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp; + u8 result = 0x00; + + /*Get TXIMR Setting*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); + + /*PA/PAD all off*/ + rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980); + rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000); + + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /*path a IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD); + + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) { + result |= 0x01; + } else { + /* PA/PAD controlled by 0x0 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); + return result; + } + + u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) | + ((reg_ebc & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); + /*RX IQK*/ + /*Modify RX IQK mode table*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + + rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); + rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); + + /*PA/PAD all off*/ + rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980); + rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000); + + /*enter IQK mode*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /*IQK Setting*/ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /*path b IQK setting*/ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f); + + /*LO calibration Setting*/ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891); + /*one shot,path A LOK & iqk*/ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + /*Check failed*/ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD); + /*PA/PAD controlled by 0x0*/ + /*leave IQK mode*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); + /*if Tx is OK, check whether Rx is OK*/ + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n"); + + return result; +} + +static void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, + bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + + if (btxonly) + return; + + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg); + } +} + +static void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, long result[][8], + u8 final_candidate, + bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + + if (btxonly) + return; + + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg); + } +} + +static void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, + bool is_patha_on, bool is2t) +{ + u32 i; + + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, 0x0fc01616); +} + +static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff); +} + +static void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true/*, is2t = true*/; + s32 tmp1, tmp2; + + bound = 8; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { + if ((result[c1][i] & 0x00000200) != 0) + tmp1 = result[c1][i] | 0xFFFFFC00; + else + tmp1 = result[c1][i]; + + if ((result[c2][i] & 0x00000200) != 0) + tmp2 = result[c2][i] | 0xFFFFFC00; + else + tmp2 = result[c2][i]; + } else { + tmp1 = result[c1][i]; + tmp2 = result[c2][i]; + } + + diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap |= (1 << i); + } else { + simularity_bitmap |= (1 << i); + } + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } + if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/ + for (i = 2; i < 4; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/ + for (i = 6; i < 8; i++) + result[3][i] = result[c1][i]; + } + return false; +} + +static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 i; + u8 patha_ok, pathb_ok; + u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0); + u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0); + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, + 0x870, 0x860, + 0x864, 0x800 + }; + const u32 retrycount = 2; + + if (t == 0) { + _rtl92ee_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + _rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + } + + _rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t); + + /*BB setting*/ + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200); + + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01); + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01); + + _rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /* Page B init*/ + /* IQ calibration setting*/ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + for (i = 0 ; i < retrycount ; i++) { + patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t); + + if (patha_ok == 0x01) { + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path A Tx IQK Success!!\n"); + result[t][0] = (rtl_get_bbreg(hw, + RTX_POWER_BEFORE_IQK_A, + MASKDWORD) & 0x3FF0000) + >> 16; + result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, + MASKDWORD) & 0x3FF0000) + >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path A Tx IQK Fail!!, ret = 0x%x\n", + patha_ok); + } + + for (i = 0 ; i < retrycount ; i++) { + patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t); + + if (patha_ok == 0x03) { + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path A Rx IQK Success!!\n"); + result[t][2] = (rtl_get_bbreg(hw, + RRX_POWER_BEFORE_IQK_A_2, + MASKDWORD) & 0x3FF0000) + >> 16; + result[t][3] = (rtl_get_bbreg(hw, + RRX_POWER_AFTER_IQK_A_2, + MASKDWORD) & 0x3FF0000) + >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path A Rx IQK Fail!!, ret = 0x%x\n", + patha_ok); + } + + if (0x00 == patha_ok) + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path A IQK failed!!, ret = 0\n"); + if (is2t) { + _rtl92ee_phy_path_a_standby(hw); + /* Turn Path B ADDA on */ + _rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t); + + /* IQ calibration setting */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + for (i = 0 ; i < retrycount ; i++) { + pathb_ok = _rtl92ee_phy_path_b_iqk(hw); + if (pathb_ok == 0x01) { + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path B Tx IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, + RTX_POWER_BEFORE_IQK_B, + MASKDWORD) & 0x3FF0000) + >> 16; + result[t][5] = (rtl_get_bbreg(hw, + RTX_POWER_AFTER_IQK_B, + MASKDWORD) & 0x3FF0000) + >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path B Tx IQK Fail!!, ret = 0x%x\n", + pathb_ok); + } + + for (i = 0 ; i < retrycount ; i++) { + pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t); + if (pathb_ok == 0x03) { + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path B Rx IQK Success!!\n"); + result[t][6] = (rtl_get_bbreg(hw, + RRX_POWER_BEFORE_IQK_B_2, + MASKDWORD) & 0x3FF0000) + >> 16; + result[t][7] = (rtl_get_bbreg(hw, + RRX_POWER_AFTER_IQK_B_2, + MASKDWORD) & 0x3FF0000) + >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path B Rx IQK Fail!!, ret = 0x%x\n", + pathb_ok); + } + + if (0x00 == pathb_ok) + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "Path B IQK failed!!, ret = 0\n"); + } + /* Back to BB mode, load original value */ + rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, + "IQK:Back to BB mode, load original value!\n"); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); + + if (t != 0) { + /* Reload ADDA power saving parameters */ + _rtl92ee_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + + /* Reload MAC parameters */ + _rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + + _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + + /* Restore RX initial gain */ + rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); + rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50); + if (is2t) { + rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); + rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58); + } + + /* load 0xe30 IQC default value */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00); + } +} + +static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + + if (is_hal_stop(rtlhal)) { + u8 u1btmp; + + u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); + rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); + rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); + + /* We use the RF definition of MAIN and AUX, + * left antenna and right antenna repectively. + * Default output at AUX. + */ + if (bmain) { + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(14) | BIT(13) | BIT(12), 0); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(4) | BIT(3), 0); + if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0); + } else { + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(14) | BIT(13) | BIT(12), 1); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(4) | BIT(3), 1); + if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) + rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1); + } + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +static u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl) +{ + u8 channel_all[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, + 132, 134, 136, 138, 140, 149, 151, 153, 155, + 157, 159, 161, 163, 165 + }; + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } + } + + return 0; +} + +void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4; + long reg_eb4, reg_ebc, reg_ec4; + bool is12simular, is13simular, is23simular; + u8 idx; + u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); + return; + } + + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + + if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) + result[3][i] = 0x100; + else + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + b_pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + _rtl92ee_phy_iq_calibrate(hw, result, i, true); + if (i == 1) { + is12simular = _rtl92ee_phy_simularity_compare(hw, + result, + 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + + if (i == 2) { + is13simular = _rtl92ee_phy_simularity_compare(hw, + result, + 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92ee_phy_simularity_compare(hw, + result, + 1, 2); + if (is23simular) + final_candidate = 1; + else + final_candidate = 3; + } + } + + reg_e94 = result[3][0]; + reg_e9c = result[3][1]; + reg_ea4 = result[3][2]; + reg_eb4 = result[3][4]; + reg_ebc = result[3][5]; + reg_ec4 = result[3][6]; + + if (final_candidate != 0xff) { + reg_e94 = result[final_candidate][0]; + rtlphy->reg_e94 = reg_e94; + reg_e9c = result[final_candidate][1]; + rtlphy->reg_e9c = reg_e9c; + reg_ea4 = result[final_candidate][2]; + reg_eb4 = result[final_candidate][4]; + rtlphy->reg_eb4 = reg_eb4; + reg_ebc = result[final_candidate][5]; + rtlphy->reg_ebc = reg_ebc; + reg_ec4 = result[final_candidate][6]; + b_patha_ok = true; + b_pathb_ok = true; + } else { + rtlphy->reg_e94 = 0x100; + rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = 0x0; + rtlphy->reg_ebc = 0x0; + } + + if (reg_e94 != 0) + _rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + + _rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result, + final_candidate, + (reg_ec4 == 0)); + + idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel); + + /* To Fix BSOD when final_candidate is 0xff */ + if (final_candidate < 4) { + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix[idx].value[0][i] = + result[final_candidate][i]; + + rtlphy->iqk_matrix[idx].iqk_done = true; + } + _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); +} + +void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); + + _rtl92ee_phy_lc_calibrate(hw, false); + + rtlphy->lck_inprogress = false; +} + +void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + _rtl92ee_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", iotype); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92ee_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl92ee_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1); + rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "no set txpower\n"); + rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + /* 8192eebt */ + rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue; + rtl92ee_dm_write_dig(hw, 0x17); + rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres; + rtl92ee_dm_write_cck_cca_thres(hw, 0x40); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + +static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON sleeping:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl92ee_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl92ee_phy_set_rf_sleep(hw); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h new file mode 100644 index 000000000..ec4c26b81 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_PHY_H__ +#define __RTL92E_PHY_H__ + +/* MAX_TX_COUNT must always set to 4, otherwise read efuse table sequence + * will be wrong. + */ +#define MAX_TX_COUNT 4 +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define MAX_POWER_INDEX 0x3f + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define index_mapping_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ant_div_type { + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, +}; + +u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw); +void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c new file mode 100644 index 000000000..515c1c3d6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "pwrseq.h" + +/* drivers should parse below arrays and do the corresponding actions */ + +/*3 Power on Array*/ +struct wlan_pwr_cfg rtl8192E_power_on_flow + [RTL8192E_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_CARDEMU_TO_ACT + RTL8192E_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8192E_radio_off_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_ACT_TO_CARDEMU + RTL8192E_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8192E_card_disable_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_ACT_TO_CARDEMU + RTL8192E_TRANS_CARDEMU_TO_CARDDIS + RTL8192E_TRANS_END +}; + +/*3 Card Enable Array*/ +struct wlan_pwr_cfg rtl8192E_card_enable_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_CARDDIS_TO_CARDEMU + RTL8192E_TRANS_CARDEMU_TO_ACT + RTL8192E_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8192E_suspend_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_ACT_TO_CARDEMU + RTL8192E_TRANS_CARDEMU_TO_SUS + RTL8192E_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8192E_resume_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_SUS_TO_CARDEMU + RTL8192E_TRANS_CARDEMU_TO_ACT + RTL8192E_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8192E_hwpdn_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS] = { + RTL8192E_TRANS_ACT_TO_CARDEMU + RTL8192E_TRANS_CARDEMU_TO_PDN + RTL8192E_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8192E_enter_lps_flow + [RTL8192E_TRANS_ACT_TO_LPS_STEPS + + RTL8192E_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8192E_TRANS_ACT_TO_LPS + RTL8192E_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8192E_leave_lps_flow + [RTL8192E_TRANS_LPS_TO_ACT_STEPS + + RTL8192E_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8192E_TRANS_LPS_TO_ACT + RTL8192E_TRANS_END +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h new file mode 100644 index 000000000..2ae8347f7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h @@ -0,0 +1,318 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_PWRSEQ_H__ +#define __RTL92E_PWRSEQ_H__ + +#include "../pwrseqcmd.h" +/** + * Check document WM-20110607-Paul-RTL8192E_Power_Architecture-R02.vsd + * There are 6 HW Power States: + * 0: POFF--Power Off + * 1: PDN--Power Down + * 2: CARDEMU--Card Emulation + * 3: ACT--Active Mode + * 4: LPS--Low Power State + * 5: SUS--Suspend + * + * The transision from different states are defined below + * TRANS_CARDEMU_TO_ACT + * TRANS_ACT_TO_CARDEMU + * TRANS_CARDEMU_TO_SUS + * TRANS_SUS_TO_CARDEMU + * TRANS_CARDEMU_TO_PDN + * TRANS_ACT_TO_LPS + * TRANS_LPS_TO_ACT + * + * TRANS_END + * PWR SEQ Version: rtl8192E_PwrSeq_V09.h + */ + +#define RTL8192E_TRANS_CARDEMU_TO_ACT_STEPS 18 +#define RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS 18 +#define RTL8192E_TRANS_SUS_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS 18 +#define RTL8192E_TRANS_PDN_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_ACT_TO_LPS_STEPS 23 +#define RTL8192E_TRANS_LPS_TO_ACT_STEPS 23 +#define RTL8192E_TRANS_END_STEPS 1 + +#define RTL8192E_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(7), 0}, \ + /* disable SW LPS 0x04[10]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), 0}, \ + /* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \ + /* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /* release WLON reset 0x04[16]=1*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /**/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, BIT(0), 0}, + +#define RTL8192E_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*0x1F[7:0] = 0 turn off RF*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0}, \ + /*0x4C[23]=0x4E[7]=0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(7), 0}, \ + /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8192E_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(4) | BIT(3), (BIT(4) | BIT(3))},\ + /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},\ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8192E_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_WRITE, BIT(0), 0}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, + +#define RTL8192E_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0x20}, \ + /*Unlock small LDO Register*/ \ + {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), BIT(2)}, \ + /*Disable small LDO*/ \ + {0x0011, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), 0}, \ + /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \ + /*0x04[10] = 1, enable SW LPS*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), BIT(2)}, \ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8192E_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_WRITE, BIT(0), 0}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /*Enable small LDO*/ \ + {0x0011, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*Lock small LDO Register*/ \ + {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), 0}, \ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, + +#define RTL8192E_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /* 0x04[16] = 0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), 0}, \ + /* 0x04[15] = 1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(7), BIT(7)}, + +#define RTL8192E_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /* 0x04[15] = 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(7), 0}, + +#define RTL8192E_TRANS_ACT_TO_LPS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*PCIe DMA stop*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /*Tx Pause*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, 0xFF, 0}, \ + /*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(0), 0}, \ + /*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \ + /*Whole BB is reset*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(1), 0}, \ + /*Reset MAC TRX*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0x03}, \ + /*check if removed later*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(1), 0}, \ + /*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0x00}, \ + /*Respond TxOK to scheduler*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(5), BIT(5)}, + +#define RTL8192E_TRANS_LPS_TO_ACT \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*SDIO RPWM, For Repeatly In and out, Taggle bit should be changed*/\ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO , PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*USB RPWM*/ \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*PCIe RPWM*/ \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*Delay*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \ + /*0x08[4] = 0 switch TSF to 40M*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(4), 0}, \ + /*Polling 0x109[7]=0 TSF in 40M*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_POLLING, BIT(7), 0}, \ + /*0x101[1] = 1*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*0x100[7:0] = 0xFF enable WMAC TRX*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /* 0x02[1:0] = 2b'11 enable BB macro*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(1) | BIT(0), BIT(1) | BIT(0)},\ + /*0x522 = 0*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0}, \ + /*Clear ISR*/ \ + {0x013D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC , PWR_CMD_WRITE, 0xFF, 0xFF}, + +#define RTL8192E_TRANS_END \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + 0, PWR_CMD_END, 0, 0}, + +extern struct wlan_pwr_cfg rtl8192E_power_on_flow + [RTL8192E_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_radio_off_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_card_disable_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_card_enable_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_suspend_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_resume_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_hwpdn_flow + [RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_enter_lps_flow + [RTL8192E_TRANS_ACT_TO_LPS_STEPS + + RTL8192E_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8192E_leave_lps_flow + [RTL8192E_TRANS_LPS_TO_ACT_STEPS + + RTL8192E_TRANS_END_STEPS]; + +/* RTL8192EE Power Configuration CMDs for PCIe interface */ +#define RTL8192E_NIC_PWR_ON_FLOW rtl8192E_power_on_flow +#define RTL8192E_NIC_RF_OFF_FLOW rtl8192E_radio_off_flow +#define RTL8192E_NIC_DISABLE_FLOW rtl8192E_card_disable_flow +#define RTL8192E_NIC_ENABLE_FLOW rtl8192E_card_enable_flow +#define RTL8192E_NIC_SUSPEND_FLOW rtl8192E_suspend_flow +#define RTL8192E_NIC_RESUME_FLOW rtl8192E_resume_flow +#define RTL8192E_NIC_PDN_FLOW rtl8192E_hwpdn_flow +#define RTL8192E_NIC_LPS_ENTER_FLOW rtl8192E_enter_lps_flow +#define RTL8192E_NIC_LPS_LEAVE_FLOW rtl8192E_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h new file mode 100644 index 000000000..0164e006f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h @@ -0,0 +1,2211 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_REG_H__ +#define __RTL92E_REG_H__ + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_SYS_SWR_CTRL1 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SYS_SWR_CTRL2 0x0014 +#define REG_SYS_SWR_CTRL3 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_CTRL1 0x0024 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_CTRL2 0x0028 +#define REG_MAC_PHY_CTRL 0x002c +#define REG_AFE_CTRL3 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_SDIO_CTRL 0x0070 +#define REG_OPT_CTRL 0x0074 +#define REG_GPIO_OUTPUT 0x006c +#define REG_AFE_CTRL4 0x0078 +#define REG_MCUFWDL 0x0080 + +#define REG_HIMR 0x00B0 +#define REG_HISR 0x00B4 +#define REG_HIMRE 0x00B8 +#define REG_HISRE 0x00BC + +#define REG_PMC_DBG_CTRL2 0x00CC +#define REG_EFUSE_ACCESS 0x00CF +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG1 0x00F0 +#define REG_MAC_PHY_CTRL_NORMAL 0x00F8 +#define REG_SYS_CFG2 0x00FC + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C + +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_RXPKTBUF_CTRL 0x0142 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_RSVD3 0x0168 +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_MCUTST_1 0x01c0 +#define REG_MCUTST_WOWLAN 0x01C7 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 + +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC + +/*----------------------------------------------------- + * + * 0x0200h ~ 0x027Fh TXDMA Configuration + * + *----------------------------------------------------- + */ +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_DWBCN0_CTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 +#define REG_AUTO_LLT 0x0224 +#define REG_DWBCN1_CTRL 0x0228 + +/*----------------------------------------------------- + * + * 0x0280h ~ 0x02FFh RXDMA Configuration + * + *----------------------------------------------------- + */ +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_FW_UPD_RDPTR 0x0284 +#define REG_RXDMA_CONTROL 0x0286 +#define REG_RXPKT_NUM 0x0287 +#define REG_RXDMA_STATUS 0x0288 +#define REG_RXDMA_PRO 0x0290 +#define REG_EARLY_MODE_CONTROL 0x02BC +#define REG_RSVD5 0x02F0 +#define REG_RSVD6 0x02F4 + +/*----------------------------------------------------- + * + * 0x0300h ~ 0x03FFh PCIe + * + *----------------------------------------------------- + */ +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_MGQ_DESA 0x0310 +#define REG_VOQ_DESA 0x0318 +#define REG_VIQ_DESA 0x0320 +#define REG_BEQ_DESA 0x0328 +#define REG_BKQ_DESA 0x0330 +#define REG_RX_DESA 0x0338 +#define REG_HQ0_DESA 0x0340 +#define REG_HQ1_DESA 0x0348 +#define REG_HQ2_DESA 0x0350 +#define REG_HQ3_DESA 0x0358 +#define REG_HQ4_DESA 0x0360 +#define REG_HQ5_DESA 0x0368 +#define REG_HQ6_DESA 0x0370 +#define REG_HQ7_DESA 0x0378 +#define REG_MGQ_TXBD_NUM 0x0380 +#define REG_RX_RXBD_NUM 0x0382 +#define REG_VOQ_TXBD_NUM 0x0384 +#define REG_VIQ_TXBD_NUM 0x0386 +#define REG_BEQ_TXBD_NUM 0x0388 +#define REG_BKQ_TXBD_NUM 0x038A +#define REG_HI0Q_TXBD_NUM 0x038C +#define REG_HI1Q_TXBD_NUM 0x038E +#define REG_HI2Q_TXBD_NUM 0x0390 +#define REG_HI3Q_TXBD_NUM 0x0392 +#define REG_HI4Q_TXBD_NUM 0x0394 +#define REG_HI5Q_TXBD_NUM 0x0396 +#define REG_HI6Q_TXBD_NUM 0x0398 +#define REG_HI7Q_TXBD_NUM 0x039A +#define REG_TSFTIMER_HCI 0x039C +/*Read Write Point*/ +#define REG_VOQ_TXBD_IDX 0x03A0 +#define REG_VIQ_TXBD_IDX 0x03A4 +#define REG_BEQ_TXBD_IDX 0x03A8 +#define REG_BKQ_TXBD_IDX 0x03AC +#define REG_MGQ_TXBD_IDX 0x03B0 +#define REG_RXQ_TXBD_IDX 0x03B4 + +#define REG_HI0Q_TXBD_IDX 0x03B8 +#define REG_HI1Q_TXBD_IDX 0x03BC +#define REG_HI2Q_TXBD_IDX 0x03C0 +#define REG_HI3Q_TXBD_IDX 0x03C4 + +#define REG_HI4Q_TXBD_IDX 0x03C8 +#define REG_HI5Q_TXBD_IDX 0x03CC +#define REG_HI6Q_TXBD_IDX 0x03D0 +#define REG_HI7Q_TXBD_IDX 0x03D4 +#define REG_PCIE_HCPWM 0x03D8 +#define REG_PCIE_CTRL2 0x03DB +#define REG_PCIE_HRPWM 0x03DC +#define REG_H2C_MSG_DRV2FW_INFO 0x03E0 +#define REG_PCIE_C2H_MSG_REQUEST 0x03E4 +#define REG_BACKDOOR_DBI_WDATA 0x03E8 +#define REG_BACKDOOR_DBI_RDATA 0x03EC +#define REG_BACKDOOR_DBI_DATA 0x03F0 +#define REG_MDIO 0x03F4 +#define REG_MDIO_DATA 0x03F8 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 +/* spec version 11 + *----------------------------------------------------- + * + * 0x0400h ~ 0x047Fh Protocol Configuration + * + *----------------------------------------------------- + */ +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 +#define REG_TXPKT_EMPTY 0x041A + +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_BCNQ_BDNY 0x0424 +#define REG_MGQ_BDNY 0x0425 +#define REG_LIFECTRL_CTRL 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RETRY_LIMIT 0x042A +#define REG_TXBF_CTRL 0x042C +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x044C +#define REG_AMPDU_MAX_TIME 0x0456 +#define REG_BCNQ1_BDNY 0x0457 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_NDPA_OPT_CTRL 0x045F +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_AMPDU_BURST_MODE 0x04BC +#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_MACID_PKT_DROP0 0x04D0 + +/*----------------------------------------------------- + * + * 0x0500h ~ 0x05FFh EDCA Configuration + * + *----------------------------------------------------- + */ +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 + +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_CTWND 0x0572 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_BCN_PREDL_ITV 0x058F +#define REG_ACMHWCTRL 0x05C0 + +/*----------------------------------------------------- + * + * 0x0600h ~ 0x07FFh WMAC Configuration + * + *----------------------------------------------------- + */ +#define REG_MAC_CR 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_UPPER 0x0652 + +/* Security*/ +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +/* Power*/ +#define REG_WOW_CTRL 0x0690 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_WKFMCAM_NUM 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_BFMER0_INFO 0x06E4 +#define REG_BFMER1_INFO 0x06EC +#define REG_CSI_RPT_PARAM_BW20 0x06F4 +#define REG_CSI_RPT_PARAM_BW40 0x06F8 +#define REG_CSI_RPT_PARAM_BW80 0x06FC +/* Hardware Port 2*/ +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 +#define REG_BFMEE_SEL 0x0714 +#define REG_SND_PTCL_CTRL 0x0718 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN | CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL + 1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL + 2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL + 3) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +/********************************************* +* 8192EE IMR/ISR bits +**********************************************/ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +#define IMR_TIMER2 BIT(31) +#define IMR_TIMER1 BIT(30) +#define IMR_PSTIMEOUT BIT(29) +#define IMR_GTINT4 BIT(28) +#define IMR_GTINT3 BIT(27) +#define IMR_TBDER BIT(26) +#define IMR_TBDOK BIT(25) +#define IMR_TSF_BIT32_TOGGLE BIT(24) +#define IMR_BCNDMAINT0 BIT(20) +#define IMR_BCNDOK0 BIT(16) +#define IMR_BCNDMAINT_E BIT(14) +#define IMR_ATIMEND BIT(12) +#define IMR_HISR1_IND_INT BIT(11) +#define IMR_C2HCMD BIT(10) +#define IMR_CPWM2 BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_HIGHDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_BKDOK BIT(5) +#define IMR_BEDOK BIT(4) +#define IMR_VIDOK BIT(3) +#define IMR_VODOK BIT(2) +#define IMR_RDU BIT(1) +#define IMR_ROK BIT(0) + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +#define IMR_MCUERR BIT(28) +#define IMR_BCNDMAINT7 BIT(27) +#define IMR_BCNDMAINT6 BIT(26) +#define IMR_BCNDMAINT5 BIT(25) +#define IMR_BCNDMAINT4 BIT(24) +#define IMR_BCNDMAINT3 BIT(23) +#define IMR_BCNDMAINT2 BIT(22) +#define IMR_BCNDMAINT1 BIT(21) +#define IMR_BCNDOK7 BIT(20) +#define IMR_BCNDOK6 BIT(19) +#define IMR_BCNDOK5 BIT(18) +#define IMR_BCNDOK4 BIT(17) +#define IMR_BCNDOK3 BIT(16) +#define IMR_BCNDOK2 BIT(15) +#define IMR_BCNDOK1 BIT(14) +#define IMR_ATIMEND_E BIT(13) +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_TXFOVW BIT(9) +#define IMR_RXFOVW BIT(8) + +#define HWSET_MAX_SIZE 512 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 256 +#define EFUSE_OOB_PROTECT_BYTES 18 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x1A +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8192E_EEPROM_ID 0x8129 + +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_TXPOWERCCK 0x10 +#define EEPROM_TXPOWERHT40_1S 0x16 +#define EEPROM_TXPOWERHT20DIFF 0x1B +#define EEPROM_TXPOWER_OFDMDIFF 0x1B + +#define EEPROM_TX_PWR_INX 0x10 + +#define EEPROM_CHANNELPLAN 0xB8 +#define EEPROM_XTAL_92E 0xB9 +#define EEPROM_THERMAL_METER_92E 0xBA +#define EEPROM_IQK_LCK_92E 0xBB + +#define EEPROM_RF_BOARD_OPTION_92E 0xC1 +#define EEPROM_RF_FEATURE_OPTION_92E 0xC2 +#define EEPROM_RF_BT_SETTING_92E 0xC3 +#define EEPROM_VERSION 0xC4 +#define EEPROM_CUSTOMER_ID 0xC5 +#define EEPROM_RF_ANTENNA_OPT_92E 0xC9 + +#define EEPROM_MAC_ADDR 0xD0 +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 175 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1 << 7) | (1 << 6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define REG_SC_CNT 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 +#define RCCK0_CCA_CNT 0xa60 + +/* PageB(0xB00) */ +#define RPDP_ANTA 0xb00 +#define RPDP_ANTA_4 0xb04 +#define RPDP_ANTA_8 0xb08 +#define RPDP_ANTA_C 0xb0c +#define RPDP_ANTA_10 0xb10 +#define RPDP_ANTA_14 0xb14 +#define RPDP_ANTA_18 0xb18 +#define RPDP_ANTA_1C 0xb1c +#define RPDP_ANTA_20 0xb20 +#define RPDP_ANTA_24 0xb24 + +#define RCONFIG_PMPD_ANTA 0xb28 +#define RCONFIG_RAM64x16 0xb2c + +#define RBNDA 0xb30 +#define RHSSIPAR 0xb34 + +#define RCONFIG_ANTA 0xb68 +#define RCONFIG_ANTB 0xb6c + +#define RPDP_ANTB 0xb70 +#define RPDP_ANTB_4 0xb74 +#define RPDP_ANTB_8 0xb78 +#define RPDP_ANTB_C 0xb7c +#define RPDP_ANTB_10 0xb80 +#define RPDP_ANTB_14 0xb84 +#define RPDP_ANTB_18 0xb88 +#define RPDP_ANTB_1C 0xb8c +#define RPDP_ANTB_20 0xb90 +#define RPDP_ANTB_24 0xb94 + +#define RCONFIG_PMPD_ANTB 0xb98 + +#define RBNDB 0xba0 + +#define RAPK 0xbd8 +#define RPM_RX0_ANTA 0xbdc +#define RPM_RX1_ANTA 0xbe0 +#define RPM_RX2_ANTA 0xbe4 +#define RPM_RX3_ANTA 0xbe8 +#define RPM_RX0_ANTB 0xbec +#define RPM_RX1_ANTB 0xbf0 +#define RPM_RX2_ANTB 0xbf4 +#define RPM_RX3_ANTB 0xbf8 + +/*Page C*/ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RFPGA0_IQK 0xe28 +#define RTX_IQK_TONE_A 0xe30 +#define RRX_IQK_TONE_A 0xe34 +#define RTX_IQK_PI_A 0xe38 +#define RRX_IQK_PI_A 0xe3c + +#define RTX_IQK 0xe40 +#define RRX_IQK 0xe44 +#define RIQK_AGC_PTS 0xe48 +#define RIQK_AGC_RSP 0xe4c +#define RTX_IQK_TONE_B 0xe50 +#define RRX_IQK_TONE_B 0xe54 +#define RTX_IQK_PI_B 0xe58 +#define RRX_IQK_PI_B 0xe5c +#define RIQK_AGC_CONT 0xe60 + +#define RBLUE_TOOTH 0xe6c +#define RRX_WAIT_CCA 0xe70 +#define RTX_CCK_RFON 0xe74 +#define RTX_CCK_BBON 0xe78 +#define RTX_OFDM_RFON 0xe7c +#define RTX_OFDM_BBON 0xe80 +#define RTX_TO_RX 0xe84 +#define RTX_TO_TX 0xe88 +#define RRX_CCK 0xe8c + +#define RTX_POWER_BEFORE_IQK_A 0xe94 +#define RTX_POWER_AFTER_IQK_A 0xe9c + +#define RRX_POWER_BEFORE_IQK_A 0xea0 +#define RRX_POWER_BEFORE_IQK_A_2 0xea4 +#define RRX_POWER_AFTER_IQK_A 0xea8 +#define RRX_POWER_AFTER_IQK_A_2 0xeac + +#define RTX_POWER_BEFORE_IQK_B 0xeb4 +#define RTX_POWER_AFTER_IQK_B 0xebc + +#define RRX_POWER_BEFORE_IQK_B 0xec0 +#define RRX_POWER_BEFORE_IQK_B_2 0xec4 +#define RRX_POWER_AFTER_IQK_B 0xec8 +#define RRX_POWER_AFTER_IQK_B_2 0xecc + +#define RRX_OFDM 0xed0 +#define RRX_WAIT_RIFS 0xed4 +#define RRX_TO_RX 0xed8 +#define RSTANDBY 0xedc +#define RSLEEP 0xee0 +#define RPMPD_ANAEN 0xeec + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) \ + ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCKRXRFSETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#define REG_UN_used_register 0x01bf + +/* WOL bit information */ +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0) +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1) +#define HAL92C_WOL_DISASSOC_EVENT BIT(2) +#define HAL92C_WOL_DEAUTH_EVENT BIT(3) +#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_FW_DISCONNECT BIT(4) +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c new file mode 100644 index 000000000..bbe632d56 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl92ee_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10) | BIT(11)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +bool rtl92ee_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl92ee_phy_rf6052_config_parafile(hw); +} + +static bool _rtl92ee_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92ee_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92ee_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h new file mode 100644 index 000000000..d7b391599 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_RF_H__ +#define __RTL92E_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +bool rtl92ee_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c new file mode 100644 index 000000000..181dd7823 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "fw.h" +#include "trx.h" +#include "led.h" +#include "table.h" + +#include "../btcoexist/rtl_btc.h" + +#include +#include + +static void rtl92ee_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /** + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /** + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /** + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; + char *fw_name; + + rtl92ee_bt_reg_init(hw); + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpci->transmit_config = CFENDFORM | BIT(15); + + /*just 2.4G band*/ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = (u32)(IMR_PSTIMEOUT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl92ee_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + + /*low power */ + rtlpriv->psc.low_power_enable = false; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw\n"); + return 1; + } + + /* request fw */ + fw_name = "rtlwifi/rtl8192eefw.bin"; + + rtlpriv->max_fw_size = 0x8000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + return 0; +} + +static void rtl92ee_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +static bool rtl92ee_get_btc_status(void) +{ + return true; +} + +static const struct rtl_hal_ops rtl8192ee_hal_ops = { + .init_sw_vars = rtl92ee_init_sw_vars, + .deinit_sw_vars = rtl92ee_deinit_sw_vars, + .read_eeprom_info = rtl92ee_read_eeprom_info, + .interrupt_recognized = rtl92ee_interrupt_recognized,/*need check*/ + .hw_init = rtl92ee_hw_init, + .hw_disable = rtl92ee_card_disable, + .hw_suspend = rtl92ee_suspend, + .hw_resume = rtl92ee_resume, + .enable_interrupt = rtl92ee_enable_interrupt, + .disable_interrupt = rtl92ee_disable_interrupt, + .set_network_type = rtl92ee_set_network_type, + .set_chk_bssid = rtl92ee_set_check_bssid, + .set_qos = rtl92ee_set_qos, + .set_bcn_reg = rtl92ee_set_beacon_related_registers, + .set_bcn_intv = rtl92ee_set_beacon_interval, + .update_interrupt_mask = rtl92ee_update_interrupt_mask, + .get_hw_reg = rtl92ee_get_hw_reg, + .set_hw_reg = rtl92ee_set_hw_reg, + .update_rate_tbl = rtl92ee_update_hal_rate_tbl, + .rx_desc_buff_remained_cnt = rtl92ee_rx_desc_buff_remained_cnt, + .rx_check_dma_ok = rtl92ee_rx_check_dma_ok, + .fill_tx_desc = rtl92ee_tx_fill_desc, + .fill_tx_cmddesc = rtl92ee_tx_fill_cmddesc, + .query_rx_desc = rtl92ee_rx_query_desc, + .set_channel_access = rtl92ee_update_channel_access_setting, + .radio_onoff_checking = rtl92ee_gpio_radio_on_off_checking, + .set_bw_mode = rtl92ee_phy_set_bw_mode, + .switch_channel = rtl92ee_phy_sw_chnl, + .dm_watchdog = rtl92ee_dm_watchdog, + .scan_operation_backup = rtl92ee_phy_scan_operation_backup, + .set_rf_power_state = rtl92ee_phy_set_rf_power_state, + .led_control = rtl92ee_led_control, + .set_desc = rtl92ee_set_desc, + .get_desc = rtl92ee_get_desc, + .is_tx_desc_closed = rtl92ee_is_tx_desc_closed, + .get_available_desc = rtl92ee_get_available_desc, + .tx_polling = rtl92ee_tx_polling, + .enable_hw_sec = rtl92ee_enable_hw_security_config, + .set_key = rtl92ee_set_key, + .get_bbreg = rtl92ee_phy_query_bb_reg, + .set_bbreg = rtl92ee_phy_set_bb_reg, + .get_rfreg = rtl92ee_phy_query_rf_reg, + .set_rfreg = rtl92ee_phy_set_rf_reg, + .fill_h2c_cmd = rtl92ee_fill_h2c_cmd, + .get_btc_status = rtl92ee_get_btc_status, + .c2h_ra_report_handler = rtl92ee_c2h_ra_report_handler, +}; + +static struct rtl_mod_params rtl92ee_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .msi_support = true, + .dma64 = false, + .aspm_support = 1, + .debug_level = 0, + .debug_mask = 0, +}; + +static const struct rtl_hal_cfg rtl92ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92ee_pci", + .ops = &rtl8192ee_hal_ops, + .mod_params = &rtl92ee_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static const struct pci_device_id rtl92ee_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x818B, rtl92ee_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92ee_pci_ids); + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192EE 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192eefw.bin"); + +module_param_named(swenc, rtl92ee_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92ee_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92ee_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl92ee_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92ee_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92ee_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl92ee_mod_params.msi_support, bool, 0444); +module_param_named(dma64, rtl92ee_mod_params.dma64, bool, 0444); +module_param_named(aspm, rtl92ee_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl92ee_mod_params.disable_watchdog, + bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); +MODULE_PARM_DESC(dma64, "Set to 1 to use DMA 64 (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl92ee_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92ee_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl92ee_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c new file mode 100644 index 000000000..fb66f610b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c @@ -0,0 +1,858 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "table.h" +u32 RTL8192EE_PHY_REG_ARRAY[] = { + 0x800, 0x80040000, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x02220385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x01000100, + 0x82C, 0x00390204, + 0x830, 0x32323232, + 0x834, 0x30303030, + 0x838, 0x30303030, + 0x83C, 0x30303030, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x28282828, + 0x84C, 0x28282828, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x009A009A, + 0x85C, 0x01000014, + 0x860, 0x66F60000, + 0x864, 0x061F0000, + 0x868, 0x30303030, + 0x86C, 0x30303030, + 0x870, 0x00000000, + 0x874, 0x55004200, + 0x878, 0x08080808, + 0x87C, 0x00000000, + 0x880, 0xB0000C1C, + 0x884, 0x00000001, + 0x888, 0x00000000, + 0x88C, 0xCC0000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121313, + 0x910, 0x806C0001, + 0x914, 0x00000001, + 0x918, 0x00000000, + 0x91C, 0x00010000, + 0x924, 0x00000001, + 0x928, 0x00000000, + 0x92C, 0x00000000, + 0x930, 0x00000000, + 0x934, 0x00000000, + 0x938, 0x00000000, + 0x93C, 0x00000000, + 0x940, 0x00000000, + 0x944, 0x00000000, + 0x94C, 0x00000008, + 0xA00, 0x00D0C7C8, + 0xA04, 0x81FF000C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E68120F, + 0xA10, 0x95009B78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B1, + 0xB38, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05633, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x08800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC47, + 0xC34, 0x469652AF, + 0xC38, 0x49795994, + 0xC3C, 0x0A97971C, + 0xC40, 0x1F7C403F, + 0xC44, 0x000100B7, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xFF010718, 0xABCD, + 0xC50, 0x00340220, + 0xCDCDCDCD, 0xCDCD, + 0xC50, 0x00340020, + 0xFF010718, 0xDEAD, + 0xC54, 0x0080801F, + 0xFF010718, 0xABCD, + 0xC58, 0x00000220, + 0xCDCDCDCD, 0xCDCD, + 0xC58, 0x00000020, + 0xFF010718, 0xDEAD, + 0xC5C, 0x00248492, + 0xC60, 0x00000000, + 0xC64, 0x7112848B, + 0xC68, 0x47C00BFF, + 0xC6C, 0x00000036, + 0xC70, 0x00000600, + 0xC74, 0x02013169, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xFF010718, 0xABCD, + 0xC80, 0x2D4000B5, + 0xCDCDCDCD, 0xCDCD, + 0xC80, 0x40000100, + 0xFF010718, 0xDEAD, + 0xC84, 0x21F60000, + 0xFF010718, 0xABCD, + 0xC88, 0x2D4000B5, + 0xCDCDCDCD, 0xCDCD, + 0xC88, 0x40000100, + 0xFF010718, 0xDEAD, + 0xC8C, 0xA0E40000, + 0xC90, 0x00121820, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00000000, + 0xCA4, 0x000300A0, + 0xCA8, 0x00000000, + 0xCAC, 0x00000000, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x64B22427, + 0xCDC, 0x00766932, + 0xCE0, 0x00222222, + 0xCE4, 0x00040000, + 0xCE8, 0x77644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00080740, + 0xD04, 0x00020403, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC43, + 0xD18, 0x7A8F5B6B, + 0xD1C, 0x0000007F, + 0xD2C, 0xCC979975, + 0xD30, 0x00000000, + 0xD34, 0x80608000, + 0xD38, 0x00000000, + 0xD3C, 0x00127353, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x6437140A, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xD6C, 0x2A201C16, + 0xD70, 0x1812362E, + 0xD74, 0x322C2220, + 0xD78, 0x000E3C24, + 0xD80, 0x01081008, + 0xD84, 0x00000800, + 0xD88, 0xF0B50000, + 0xE00, 0x30303030, + 0xE04, 0x30303030, + 0xE08, 0x03903030, + 0xE10, 0x30303030, + 0xE14, 0x30303030, + 0xE18, 0x30303030, + 0xE1C, 0x30303030, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE68, 0x0FC05656, + 0xE6C, 0x03C09696, + 0xE70, 0x03C09696, + 0xE74, 0x0C005656, + 0xE78, 0x0C005656, + 0xE7C, 0x0C005656, + 0xE80, 0x0C005656, + 0xE84, 0x03C09696, + 0xE88, 0x0C005656, + 0xE8C, 0x03C09696, + 0xED0, 0x03C09696, + 0xED4, 0x03C09696, + 0xED8, 0x03C09696, + 0xEDC, 0x0000D6D6, + 0xEE0, 0x0000D6D6, + 0xEEC, 0x0FC01616, + 0xEE4, 0xB0000C1C, + 0xEE8, 0x00000001, + 0xF14, 0x00000003, + 0xF4C, 0x00000000, + 0xF00, 0x00000300, +}; + +u32 RTL8192EE_PHY_REG_ARRAY_PG[] = { + 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, + 0, 0, 1, 0x00000e08, 0x0000ff00, 0x00003200, + 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, + 0, 0, 1, 0x0000086c, 0xffffff00, 0x32323200, + 0, 0, 0, 0x00000e00, 0xffffffff, 0x34343636, + 0, 0, 1, 0x00000e00, 0xffffffff, 0x34343636, + 0, 0, 0, 0x00000e04, 0xffffffff, 0x28283032, + 0, 0, 1, 0x00000e04, 0xffffffff, 0x28283032, + 0, 0, 0, 0x00000e10, 0xffffffff, 0x34363840, + 0, 0, 1, 0x00000e10, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000e14, 0xffffffff, 0x26283032, + 0, 0, 1, 0x00000e14, 0xffffffff, 0x26283032, + 0, 0, 1, 0x00000e18, 0xffffffff, 0x36384040, + 0, 0, 1, 0x00000e1c, 0xffffffff, 0x24262832, + 0, 1, 0, 0x00000838, 0xffffff00, 0x32323200, + 0, 1, 1, 0x00000838, 0xffffff00, 0x32323200, + 0, 1, 0, 0x0000086c, 0x000000ff, 0x00000032, + 0, 1, 1, 0x0000086c, 0x000000ff, 0x00000032, + 0, 1, 0, 0x00000830, 0xffffffff, 0x34343636, + 0, 1, 1, 0x00000830, 0xffffffff, 0x34343636, + 0, 1, 0, 0x00000834, 0xffffffff, 0x28283032, + 0, 1, 1, 0x00000834, 0xffffffff, 0x28283032, + 0, 1, 0, 0x0000083c, 0xffffffff, 0x34363840, + 0, 1, 1, 0x0000083c, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000848, 0xffffffff, 0x26283032, + 0, 1, 1, 0x00000848, 0xffffffff, 0x26283032, + 0, 1, 1, 0x0000084c, 0xffffffff, 0x36384040, + 0, 1, 1, 0x00000868, 0xffffffff, 0x24262832 +}; + +u32 RTL8192EE_RADIOA_ARRAY[] = { + 0x07F, 0x00000082, + 0x081, 0x0003FC00, + 0x000, 0x00030000, + 0x008, 0x00008400, + 0x018, 0x00000407, + 0x019, 0x00000012, + 0x01B, 0x00000064, + 0x01E, 0x00080009, + 0x01F, 0x00000880, + 0x02F, 0x0001A060, + 0x03F, 0x00000000, + 0x042, 0x000060C0, + 0x057, 0x000D0000, + 0x058, 0x000BE180, + 0x067, 0x00001552, + 0x083, 0x00000000, + 0x0B0, 0x000FF9F1, + 0x0B1, 0x00055418, + 0x0B2, 0x0008CC00, + 0x0B4, 0x00043083, + 0x0B5, 0x00008166, + 0x0B6, 0x0000803E, + 0x0B7, 0x0001C69F, + 0x0B8, 0x0000407F, + 0x0B9, 0x00080001, + 0x0BA, 0x00040001, + 0x0BB, 0x00000400, + 0x0BF, 0x000C0000, + 0x0C2, 0x00002400, + 0x0C3, 0x00000009, + 0x0C4, 0x00040C91, + 0x0C5, 0x00099999, + 0x0C6, 0x000000A3, + 0x0C7, 0x00088820, + 0x0C8, 0x00076C06, + 0x0C9, 0x00000000, + 0x0CA, 0x00080000, + 0x0DF, 0x00000180, + 0x0EF, 0x000001A0, + 0x051, 0x00069545, + 0x052, 0x0007E45E, + 0x053, 0x00000071, + 0x056, 0x00051FF3, + 0x035, 0x000000A8, + 0x035, 0x000001E2, + 0x035, 0x000002A8, + 0x036, 0x00001C24, + 0x036, 0x00009C24, + 0x036, 0x00011C24, + 0x036, 0x00019C24, + 0x018, 0x00000C07, + 0x05A, 0x00048000, + 0x019, 0x000739D0, + 0xFF010718, 0xABCD, + 0x034, 0x0000A093, + 0x034, 0x0000908F, + 0x034, 0x0000808C, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000000, + 0xCDCDCDCD, 0xCDCD, + 0x034, 0x0000ADD7, + 0x034, 0x00009DD4, + 0x034, 0x00008DD1, + 0x034, 0x00007DCE, + 0x034, 0x00006DCB, + 0x034, 0x00005DC8, + 0x034, 0x00004DC5, + 0x034, 0x000034CC, + 0x034, 0x0000244F, + 0x034, 0x0000144C, + 0x034, 0x00000014, + 0xFF010718, 0xDEAD, + 0x000, 0x00030159, + 0x084, 0x00068180, + 0x086, 0x0000014E, + 0x087, 0x00048E00, + 0x08E, 0x00065540, + 0x08F, 0x00088000, + 0x0EF, 0x000020A0, + 0xFF010718, 0xABCD, + 0x03B, 0x000F07B0, + 0xCDCDCDCD, 0xCDCD, + 0x03B, 0x000F02B0, + 0xFF010718, 0xDEAD, + 0x03B, 0x000EF7B0, + 0x03B, 0x000D4FB0, + 0x03B, 0x000CF060, + 0x03B, 0x000B0090, + 0x03B, 0x000A0080, + 0x03B, 0x00090080, + 0x03B, 0x0008F780, + 0xFF010718, 0xABCD, + 0x03B, 0x000787B0, + 0xCDCDCDCD, 0xCDCD, + 0x03B, 0x00078730, + 0xFF010718, 0xDEAD, + 0x03B, 0x00060FB0, + 0x03B, 0x0005FFA0, + 0x03B, 0x00040620, + 0x03B, 0x00037090, + 0x03B, 0x00020080, + 0x03B, 0x0001F060, + 0x03B, 0x0000FFB0, + 0x0EF, 0x000000A0, + 0x0FE, 0x00000000, + 0x018, 0x0000FC07, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x01E, 0x00000001, + 0x01F, 0x00080000, + 0x000, 0x00033E70, +}; + +u32 RTL8192EE_RADIOB_ARRAY[] = { + 0x07F, 0x00000082, + 0x081, 0x0003FC00, + 0x000, 0x00030000, + 0x008, 0x00008400, + 0x018, 0x00000407, + 0x019, 0x00000012, + 0x01B, 0x00000064, + 0x01E, 0x00080009, + 0x01F, 0x00000880, + 0x02F, 0x0001A060, + 0x03F, 0x00000000, + 0x042, 0x000060C0, + 0x057, 0x000D0000, + 0x058, 0x000BE180, + 0x067, 0x00001552, + 0x07F, 0x00000082, + 0x081, 0x0003F000, + 0x083, 0x00000000, + 0x0DF, 0x00000180, + 0x0EF, 0x000001A0, + 0x051, 0x00069545, + 0x052, 0x0007E42E, + 0x053, 0x00000071, + 0x056, 0x00051FF3, + 0x035, 0x000000A8, + 0x035, 0x000001E0, + 0x035, 0x000002A8, + 0x036, 0x00001CA8, + 0x036, 0x00009C24, + 0x036, 0x00011C24, + 0x036, 0x00019C24, + 0x018, 0x00000C07, + 0x05A, 0x00048000, + 0x019, 0x000739D0, + 0xFF010718, 0xABCD, + 0x034, 0x0000A093, + 0x034, 0x0000908F, + 0x034, 0x0000808C, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000000, + 0xCDCDCDCD, 0xCDCD, + 0x034, 0x0000ADD7, + 0x034, 0x00009DD4, + 0x034, 0x00008DD1, + 0x034, 0x00007DCE, + 0x034, 0x00006DCB, + 0x034, 0x00005DC8, + 0x034, 0x00004DC5, + 0x034, 0x000034CC, + 0x034, 0x0000244F, + 0x034, 0x0000144C, + 0x034, 0x00000014, + 0xFF010718, 0xDEAD, + 0x000, 0x00030159, + 0x084, 0x00068180, + 0x086, 0x000000CE, + 0x087, 0x00048A00, + 0x08E, 0x00065540, + 0x08F, 0x00088000, + 0x0EF, 0x000020A0, + 0xFF010718, 0xABCD, + 0x03B, 0x000F07B0, + 0xCDCDCDCD, 0xCDCD, + 0x03B, 0x000F02B0, + 0xFF010718, 0xDEAD, + 0x03B, 0x000EF7B0, + 0x03B, 0x000D4FB0, + 0x03B, 0x000CF060, + 0x03B, 0x000B0090, + 0x03B, 0x000A0080, + 0x03B, 0x00090080, + 0x03B, 0x0008F780, + 0xFF010718, 0xABCD, + 0x03B, 0x000787B0, + 0xCDCDCDCD, 0xCDCD, + 0x03B, 0x00078730, + 0xFF010718, 0xDEAD, + 0x03B, 0x00060FB0, + 0x03B, 0x0005FFA0, + 0x03B, 0x00040620, + 0x03B, 0x00037090, + 0x03B, 0x00020080, + 0x03B, 0x0001F060, + 0x03B, 0x0000FFB0, + 0x0EF, 0x000000A0, + 0x000, 0x00010159, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x01E, 0x00000001, + 0x01F, 0x00080000, + 0x000, 0x00033E70, +}; + +u32 RTL8192EE_MAC_ARRAY[] = { + 0x011, 0x000000EB, + 0x012, 0x00000007, + 0x014, 0x00000075, + 0x303, 0x000000A7, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x540, 0x00000012, + 0x541, 0x00000064, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, +}; + +u32 RTL8192EE_AGC_TAB_ARRAY[] = { + 0xFF010718, 0xABCD, + 0xC78, 0xFA000001, + 0xC78, 0xF9010001, + 0xC78, 0xF8020001, + 0xC78, 0xF7030001, + 0xC78, 0xF6040001, + 0xC78, 0xF5050001, + 0xC78, 0xF4060001, + 0xC78, 0xF3070001, + 0xC78, 0xF2080001, + 0xC78, 0xF1090001, + 0xC78, 0xF00A0001, + 0xC78, 0xEF0B0001, + 0xC78, 0xEE0C0001, + 0xC78, 0xED0D0001, + 0xC78, 0xEC0E0001, + 0xC78, 0xEB0F0001, + 0xC78, 0xEA100001, + 0xC78, 0xE9110001, + 0xC78, 0xE8120001, + 0xC78, 0xE7130001, + 0xC78, 0xE6140001, + 0xC78, 0xE5150001, + 0xC78, 0xE4160001, + 0xC78, 0xE3170001, + 0xC78, 0xE2180001, + 0xC78, 0xE1190001, + 0xC78, 0x8A1A0001, + 0xC78, 0x891B0001, + 0xC78, 0x881C0001, + 0xC78, 0x871D0001, + 0xC78, 0x861E0001, + 0xC78, 0x851F0001, + 0xC78, 0x84200001, + 0xC78, 0x83210001, + 0xC78, 0x82220001, + 0xC78, 0x6A230001, + 0xC78, 0x69240001, + 0xC78, 0x68250001, + 0xC78, 0x67260001, + 0xC78, 0x66270001, + 0xC78, 0x65280001, + 0xC78, 0x64290001, + 0xC78, 0x632A0001, + 0xC78, 0x622B0001, + 0xC78, 0x612C0001, + 0xC78, 0x602D0001, + 0xC78, 0x472E0001, + 0xC78, 0x462F0001, + 0xC78, 0x45300001, + 0xC78, 0x44310001, + 0xC78, 0x43320001, + 0xC78, 0x42330001, + 0xC78, 0x41340001, + 0xC78, 0x40350001, + 0xC78, 0x40360001, + 0xC78, 0x40370001, + 0xC78, 0x40380001, + 0xC78, 0x40390001, + 0xC78, 0x403A0001, + 0xC78, 0x403B0001, + 0xC78, 0x403C0001, + 0xC78, 0x403D0001, + 0xC78, 0x403E0001, + 0xC78, 0x403F0001, + 0xCDCDCDCD, 0xCDCD, + 0xC78, 0xFB000001, + 0xC78, 0xFB010001, + 0xC78, 0xFB020001, + 0xC78, 0xFB030001, + 0xC78, 0xFB040001, + 0xC78, 0xFB050001, + 0xC78, 0xFA060001, + 0xC78, 0xF9070001, + 0xC78, 0xF8080001, + 0xC78, 0xF7090001, + 0xC78, 0xF60A0001, + 0xC78, 0xF50B0001, + 0xC78, 0xF40C0001, + 0xC78, 0xF30D0001, + 0xC78, 0xF20E0001, + 0xC78, 0xF10F0001, + 0xC78, 0xF0100001, + 0xC78, 0xEF110001, + 0xC78, 0xEE120001, + 0xC78, 0xED130001, + 0xC78, 0xEC140001, + 0xC78, 0xEB150001, + 0xC78, 0xEA160001, + 0xC78, 0xE9170001, + 0xC78, 0xE8180001, + 0xC78, 0xE7190001, + 0xC78, 0xC81A0001, + 0xC78, 0xC71B0001, + 0xC78, 0xC61C0001, + 0xC78, 0x071D0001, + 0xC78, 0x061E0001, + 0xC78, 0x051F0001, + 0xC78, 0x04200001, + 0xC78, 0x03210001, + 0xC78, 0xAA220001, + 0xC78, 0xA9230001, + 0xC78, 0xA8240001, + 0xC78, 0xA7250001, + 0xC78, 0xA6260001, + 0xC78, 0x85270001, + 0xC78, 0x84280001, + 0xC78, 0x83290001, + 0xC78, 0x252A0001, + 0xC78, 0x242B0001, + 0xC78, 0x232C0001, + 0xC78, 0x222D0001, + 0xC78, 0x672E0001, + 0xC78, 0x662F0001, + 0xC78, 0x65300001, + 0xC78, 0x64310001, + 0xC78, 0x63320001, + 0xC78, 0x62330001, + 0xC78, 0x61340001, + 0xC78, 0x45350001, + 0xC78, 0x44360001, + 0xC78, 0x43370001, + 0xC78, 0x42380001, + 0xC78, 0x41390001, + 0xC78, 0x403A0001, + 0xC78, 0x403B0001, + 0xC78, 0x403C0001, + 0xC78, 0x403D0001, + 0xC78, 0x403E0001, + 0xC78, 0x403F0001, + 0xFF010718, 0xDEAD, + 0xFF010718, 0xABCD, + 0xC78, 0xFA400001, + 0xC78, 0xF9410001, + 0xC78, 0xF8420001, + 0xC78, 0xF7430001, + 0xC78, 0xF6440001, + 0xC78, 0xF5450001, + 0xC78, 0xF4460001, + 0xC78, 0xF3470001, + 0xC78, 0xF2480001, + 0xC78, 0xF1490001, + 0xC78, 0xF04A0001, + 0xC78, 0xEF4B0001, + 0xC78, 0xEE4C0001, + 0xC78, 0xED4D0001, + 0xC78, 0xEC4E0001, + 0xC78, 0xEB4F0001, + 0xC78, 0xEA500001, + 0xC78, 0xE9510001, + 0xC78, 0xE8520001, + 0xC78, 0xE7530001, + 0xC78, 0xE6540001, + 0xC78, 0xE5550001, + 0xC78, 0xE4560001, + 0xC78, 0xE3570001, + 0xC78, 0xE2580001, + 0xC78, 0xE1590001, + 0xC78, 0x8A5A0001, + 0xC78, 0x895B0001, + 0xC78, 0x885C0001, + 0xC78, 0x875D0001, + 0xC78, 0x865E0001, + 0xC78, 0x855F0001, + 0xC78, 0x84600001, + 0xC78, 0x83610001, + 0xC78, 0x82620001, + 0xC78, 0x6A630001, + 0xC78, 0x69640001, + 0xC78, 0x68650001, + 0xC78, 0x67660001, + 0xC78, 0x66670001, + 0xC78, 0x65680001, + 0xC78, 0x64690001, + 0xC78, 0x636A0001, + 0xC78, 0x626B0001, + 0xC78, 0x616C0001, + 0xC78, 0x606D0001, + 0xC78, 0x476E0001, + 0xC78, 0x466F0001, + 0xC78, 0x45700001, + 0xC78, 0x44710001, + 0xC78, 0x43720001, + 0xC78, 0x42730001, + 0xC78, 0x41740001, + 0xC78, 0x40750001, + 0xC78, 0x40760001, + 0xC78, 0x40770001, + 0xC78, 0x40780001, + 0xC78, 0x40790001, + 0xC78, 0x407A0001, + 0xC78, 0x407B0001, + 0xC78, 0x407C0001, + 0xC78, 0x407D0001, + 0xC78, 0x407E0001, + 0xC78, 0x407F0001, + 0xC50, 0x00040222, + 0xC50, 0x00040220, + 0xCDCDCDCD, 0xCDCD, + 0xC78, 0xFB400001, + 0xC78, 0xFB410001, + 0xC78, 0xFB420001, + 0xC78, 0xFB430001, + 0xC78, 0xFB440001, + 0xC78, 0xFB450001, + 0xC78, 0xFA460001, + 0xC78, 0xF9470001, + 0xC78, 0xF8480001, + 0xC78, 0xF7490001, + 0xC78, 0xF64A0001, + 0xC78, 0xF54B0001, + 0xC78, 0xF44C0001, + 0xC78, 0xF34D0001, + 0xC78, 0xF24E0001, + 0xC78, 0xF14F0001, + 0xC78, 0xF0500001, + 0xC78, 0xEF510001, + 0xC78, 0xEE520001, + 0xC78, 0xED530001, + 0xC78, 0xEC540001, + 0xC78, 0xEB550001, + 0xC78, 0xEA560001, + 0xC78, 0xE9570001, + 0xC78, 0xE8580001, + 0xC78, 0xE7590001, + 0xC78, 0xE65A0001, + 0xC78, 0xE55B0001, + 0xC78, 0xE45C0001, + 0xC78, 0xE35D0001, + 0xC78, 0xE25E0001, + 0xC78, 0xE15F0001, + 0xC78, 0x8A600001, + 0xC78, 0x89610001, + 0xC78, 0x88620001, + 0xC78, 0x87630001, + 0xC78, 0x86640001, + 0xC78, 0x85650001, + 0xC78, 0x84660001, + 0xC78, 0x83670001, + 0xC78, 0x82680001, + 0xC78, 0x6B690001, + 0xC78, 0x6A6A0001, + 0xC78, 0x696B0001, + 0xC78, 0x686C0001, + 0xC78, 0x676D0001, + 0xC78, 0x666E0001, + 0xC78, 0x656F0001, + 0xC78, 0x64700001, + 0xC78, 0x63710001, + 0xC78, 0x62720001, + 0xC78, 0x61730001, + 0xC78, 0x49740001, + 0xC78, 0x48750001, + 0xC78, 0x47760001, + 0xC78, 0x46770001, + 0xC78, 0x45780001, + 0xC78, 0x44790001, + 0xC78, 0x437A0001, + 0xC78, 0x427B0001, + 0xC78, 0x417C0001, + 0xC78, 0x407D0001, + 0xC78, 0x407E0001, + 0xC78, 0x407F0001, + 0xC50, 0x00040022, + 0xC50, 0x00040020, + 0xFF010718, 0xDEAD, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h new file mode 100644 index 000000000..0bc7ef58c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_TABLE__H_ +#define __RTL92E_TABLE__H_ + +#include +#define RTL8192EE_PHY_REG_ARRAY_LEN 448 +extern u32 RTL8192EE_PHY_REG_ARRAY[]; +#define RTL8192EE_PHY_REG_ARRAY_PG_LEN 168 +extern u32 RTL8192EE_PHY_REG_ARRAY_PG[]; +#define RTL8192EE_RADIOA_ARRAY_LEN 238 +extern u32 RTL8192EE_RADIOA_ARRAY[]; +#define RTL8192EE_RADIOB_ARRAY_LEN 198 +extern u32 RTL8192EE_RADIOB_ARRAY[]; +#define RTL8192EE_MAC_ARRAY_LEN 202 +extern u32 RTL8192EE_MAC_ARRAY[]; +#define RTL8192EE_AGC_TAB_ARRAY_LEN 532 +extern u32 RTL8192EE_AGC_TAB_ARRAY[]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c new file mode 100644 index 000000000..16589e184 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c @@ -0,0 +1,1045 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" +#include "dm.h" +#include "fw.h" + +static u8 _rtl92ee_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstatus, u8 *pdesc, + struct rx_fwinfo *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo; + s8 rx_pwr_all, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstatus->is_cck; + u8 lan_idx, vga_idx; + + /* Record it for next packet processing */ + pstatus->packet_matchbssid = bpacket_match_bssid; + pstatus->packet_toself = bpacket_toself; + pstatus->packet_beacon = packet_beacon; + pstatus->rx_mimo_signalquality[0] = -1; + pstatus->rx_mimo_signalquality[1] = -1; + + if (is_cck) { + u8 cck_highpwr; + u8 cck_agc_rpt; + /* CCK Driver info Structure is not the same as OFDM packet. */ + cck_agc_rpt = p_phystrpt->cck_agc_rpt_ofdm_cfosho_a; + + /* (1)Hardware does not provide RSSI for CCK + * (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + cck_highpwr = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + + lan_idx = ((cck_agc_rpt & 0xE0) >> 5); + vga_idx = (cck_agc_rpt & 0x1f); + switch (lan_idx) { + case 7: /*VGA_idx = 27~2*/ + if (vga_idx <= 27) + rx_pwr_all = -100 + 2 * (27 - vga_idx); + else + rx_pwr_all = -100; + break; + case 6: /*VGA_idx = 2~0*/ + rx_pwr_all = -48 + 2 * (2 - vga_idx); + break; + case 5: /*VGA_idx = 7~5*/ + rx_pwr_all = -42 + 2 * (7 - vga_idx); + break; + case 4: /*VGA_idx = 7~4*/ + rx_pwr_all = -36 + 2 * (7 - vga_idx); + break; + case 3: /*VGA_idx = 7~0*/ + rx_pwr_all = -24 + 2 * (7 - vga_idx); + break; + case 2: /*VGA_idx = 5~0*/ + if (cck_highpwr) + rx_pwr_all = -12 + 2 * (5 - vga_idx); + else + rx_pwr_all = -6 + 2 * (5 - vga_idx); + break; + case 1: + rx_pwr_all = 8 - 2 * vga_idx; + break; + case 0: + rx_pwr_all = 14 - 2 * vga_idx; + break; + default: + rx_pwr_all = 0; + break; + } + rx_pwr_all += 16; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + + if (!cck_highpwr) { + if (pwdb_all >= 80) + pwdb_all = ((pwdb_all - 80) << 1) + + ((pwdb_all - 80) >> 1) + 80; + else if ((pwdb_all <= 78) && (pwdb_all >= 20)) + pwdb_all += 3; + if (pwdb_all > 100) + pwdb_all = 100; + } + + pstatus->rx_pwdb_all = pwdb_all; + pstatus->bt_rx_rssi_percentage = pwdb_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (bpacket_match_bssid) { + u8 sq, sq_rpt; + + if (pstatus->rx_pwdb_all > 40) { + sq = 100; + } else { + sq_rpt = p_phystrpt->cck_sig_qual_ofdm_pwdb_all; + if (sq_rpt > 64) + sq = 0; + else if (sq_rpt < 20) + sq = 100; + else + sq = ((64 - sq_rpt) * 100) / 44; + } + + pstatus->signalquality = sq; + pstatus->rx_mimo_signalquality[0] = sq; + pstatus->rx_mimo_signalquality[1] = -1; + } + } else { + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((p_phystrpt->path_agc[i].gain & 0x3f) * 2) + - 110; + + pstatus->rx_pwr[i] = rx_pwr[i]; + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + + pstatus->rx_mimo_signalstrength[i] = (u8)rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_phystrpt->cck_sig_qual_ofdm_pwdb_all >> 1) + & 0x7f) - 110; + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstatus->rx_pwdb_all = pwdb_all; + pstatus->bt_rx_rssi_percentage = pwdb_all; + pstatus->rxpower = rx_pwr_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if (pstatus->rate >= DESC_RATEMCS8 && + pstatus->rate <= DESC_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage( + p_phystrpt->stream_rxevm[i]); + + if (bpacket_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream only + */ + if (i == 0) + pstatus->signalquality = (u8)(evm & + 0xff); + pstatus->rx_mimo_signalquality[i] = (u8)(evm & + 0xff); + } + } + + if (bpacket_match_bssid) { + for (i = RF90_PATH_A; i <= RF90_PATH_B; i++) + rtl_priv(hw)->dm.cfo_tail[i] = + (int)p_phystrpt->path_cfotail[i]; + + if (rtl_priv(hw)->dm.packet_count == 0xffffffff) + rtl_priv(hw)->dm.packet_count = 0; + else + rtl_priv(hw)->dm.packet_count++; + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void _rtl92ee_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, + u8 *pdesc, + struct rx_fwinfo *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + __le16 fc; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + + pstatus->rx_bufshift + 24; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + praddr = hdr->addr1; + psaddr = ieee80211_get_SA(hdr); + ether_addr_copy(pstatus->psaddr, psaddr); + + packet_matchbssid = (!ieee80211_is_ctl(fc) && + (ether_addr_equal(mac->bssid, + ieee80211_has_tods(fc) ? + hdr->addr1 : + ieee80211_has_fromds(fc) ? + hdr->addr2 : hdr->addr3)) && + (!pstatus->hwerror) && (!pstatus->crc) && + (!pstatus->icv)); + + packet_toself = packet_matchbssid && + (ether_addr_equal(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + else + packet_beacon = false; + + if (packet_beacon && packet_matchbssid) + rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + + if (packet_matchbssid && ieee80211_is_data_qos(hdr->frame_control) && + !is_multicast_ether_addr(ieee80211_get_DA(hdr))) { + struct ieee80211_qos_hdr *hdr_qos = + (struct ieee80211_qos_hdr *)tmp_buf; + u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf; + + if (tid != 0 && tid != 3) + rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++; + } + + _rtl92ee_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void _rtl92ee_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + u8 *virtualaddress8) +{ + u32 dwtmp; + __le32 *virtualaddress = (__le32 *)virtualaddress8; + + memset(virtualaddress, 0, 8); + + set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[1]; + } + set_earlymode_len0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[3]; + } + set_earlymode_len1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[5]; + } + set_earlymode_len2_1(virtualaddress, dwtmp & 0xF); + set_earlymode_len2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[7]; + } + set_earlymode_len3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[9]; + } + set_earlymode_len4(virtualaddress, dwtmp); +} + +bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rx_fwinfo *p_drvinfo; + struct ieee80211_hdr *hdr; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_physt(pdesc); + u8 wake_match; + + if (get_rx_status_desc_rpt_sel(pdesc) == 0) + status->packet_report_type = NORMAL_RX; + else + status->packet_report_type = C2H_PACKET; + status->length = (u16)get_rx_desc_pkt_len(pdesc); + status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + status->icv = (u16)get_rx_desc_icv(pdesc); + status->crc = (u16)get_rx_desc_crc32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !get_rx_desc_swdec(pdesc); + status->rate = (u8)get_rx_desc_rxmcs(pdesc); + status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->timestamp_low = get_rx_desc_tsfl(pdesc); + status->is_cck = RTL92EE_RX_HAL_IS_CCK_RATE(status->rate); + + status->macid = get_rx_desc_macid(pdesc); + if (get_rx_status_desc_pattern_match(pdesc)) + wake_match = BIT(2); + else if (get_rx_status_desc_magic_match(pdesc)) + wake_match = BIT(1); + else if (get_rx_status_desc_unicast_match(pdesc)) + wake_match = BIT(0); + else + wake_match = 0; + if (wake_match) + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift + 24); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + * Notice: this is diff with windows define + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, + false, status->rate); + + rx_status->mactime = status->timestamp_low; + if (phystatus) { + p_drvinfo = (struct rx_fwinfo *)(skb->data + + status->rx_bufshift + 24); + + _rtl92ee_translate_rx_signal_stuff(hw, skb, status, pdesc8, + p_drvinfo); + } + rx_status->signal = status->recvsignalpower + 10; + if (status->packet_report_type == TX_REPORT2) { + status->macid_valid_entry[0] = + get_rx_rpt2_desc_macid_valid_1(pdesc); + status->macid_valid_entry[1] = + get_rx_rpt2_desc_macid_valid_2(pdesc); + } + return true; +} + +/*in Windows, this == Rx_92EE_Interrupt*/ +void rtl92ee_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc8, + u8 queue_index) +{ + u8 first_seg = 0; + u8 last_seg = 0; + u16 total_len = 0; + u16 read_cnt = 0; + __le32 *header_desc = (__le32 *)header_desc8; + + if (header_desc == NULL) + return; + + total_len = (u16)get_rx_buffer_desc_total_length(header_desc); + + first_seg = (u8)get_rx_buffer_desc_fs(header_desc); + + last_seg = (u8)get_rx_buffer_desc_ls(header_desc); + + while (total_len == 0 && first_seg == 0 && last_seg == 0) { + read_cnt++; + total_len = (u16)get_rx_buffer_desc_total_length(header_desc); + first_seg = (u8)get_rx_buffer_desc_fs(header_desc); + last_seg = (u8)get_rx_buffer_desc_ls(header_desc); + + if (read_cnt > 20) + break; + } +} + +u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 read_point, write_point, remind_cnt; + u32 tmp_4byte; + static bool start_rx; + + tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_TXBD_IDX); + read_point = (u16)((tmp_4byte>>16) & 0x7ff); + write_point = (u16)(tmp_4byte & 0x7ff); + + if (write_point != rtlpci->rx_ring[queue_index].next_rx_rp) { + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_DMESG, + "!!!write point is 0x%x, reg 0x3B4 value is 0x%x\n", + write_point, tmp_4byte); + tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_TXBD_IDX); + read_point = (u16)((tmp_4byte>>16) & 0x7ff); + write_point = (u16)(tmp_4byte & 0x7ff); + } + + if (read_point > 0) + start_rx = true; + if (!start_rx) + return 0; + + remind_cnt = calc_fifo_space(read_point, write_point, + RTL_PCI_MAX_RX_COUNT); + + if (remind_cnt == 0) + return 0; + + rtlpci->rx_ring[queue_index].next_rx_rp = write_point; + + return remind_cnt; +} + +static u16 get_desc_addr_fr_q_idx(u16 queue_index) +{ + u16 desc_address; + + switch (queue_index) { + case BK_QUEUE: + desc_address = REG_BKQ_TXBD_IDX; + break; + case BE_QUEUE: + desc_address = REG_BEQ_TXBD_IDX; + break; + case VI_QUEUE: + desc_address = REG_VIQ_TXBD_IDX; + break; + case VO_QUEUE: + desc_address = REG_VOQ_TXBD_IDX; + break; + case BEACON_QUEUE: + desc_address = REG_BEQ_TXBD_IDX; + break; + case TXCMD_QUEUE: + desc_address = REG_BEQ_TXBD_IDX; + break; + case MGNT_QUEUE: + desc_address = REG_MGQ_TXBD_IDX; + break; + case HIGH_QUEUE: + desc_address = REG_HI0Q_TXBD_IDX; + break; + case HCCA_QUEUE: + desc_address = REG_BEQ_TXBD_IDX; + break; + default: + desc_address = REG_BEQ_TXBD_IDX; + break; + } + return desc_address; +} + +u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 point_diff = 0; + u16 current_tx_read_point, current_tx_write_point; + u32 tmp_4byte; + + tmp_4byte = rtl_read_dword(rtlpriv, + get_desc_addr_fr_q_idx(q_idx)); + current_tx_read_point = (u16)((tmp_4byte >> 16) & 0x0fff); + current_tx_write_point = (u16)((tmp_4byte) & 0x0fff); + + point_diff = calc_fifo_space(current_tx_read_point, + current_tx_write_point, + TX_DESC_NUM_92E); + + return point_diff; +} + +static void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, + u8 *tx_bd_desc8, u8 *desc8, + u8 queue_index, + struct sk_buff *skb, + dma_addr_t addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 pkt_len = skb->len; + u16 desc_size = 40; /*tx desc size*/ + u32 psblen = 0; + u16 tx_page_size; + u32 total_packet_size; + u16 current_bd_desc; + u8 i; + u16 real_desc_size = 0x28; + u16 append_early_mode_size = 0; + u8 segmentnum = 1 << (RTL8192EE_SEG_NUM + 1); + dma_addr_t desc_dma_addr; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + __le32 *desc = (__le32 *)desc8; + __le32 *tx_bd_desc = (__le32 *)tx_bd_desc8; + + tx_page_size = 2; + current_bd_desc = rtlpci->tx_ring[queue_index].cur_tx_wp; + + total_packet_size = desc_size+pkt_len; + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) { + append_early_mode_size = 8; + total_packet_size += append_early_mode_size; + } + } + + if (tx_page_size > 0) { + psblen = (pkt_len + real_desc_size + append_early_mode_size) / + (tx_page_size * 128); + + if (psblen * (tx_page_size * 128) < total_packet_size) + psblen += 1; + } + + /* tx desc addr */ + desc_dma_addr = rtlpci->tx_ring[queue_index].dma + + (current_bd_desc * TX_DESC_SIZE); + + /* Reset */ + set_tx_buff_desc_len_0(tx_bd_desc, 0); + set_tx_buff_desc_psb(tx_bd_desc, 0); + set_tx_buff_desc_own(tx_bd_desc, 0); + + for (i = 1; i < segmentnum; i++) { + set_txbuffer_desc_len_with_offset(tx_bd_desc, i, 0); + set_txbuffer_desc_amsdu_with_offset(tx_bd_desc, i, 0); + set_txbuffer_desc_add_low_with_offset(tx_bd_desc, i, 0); + set_txbuffer_desc_add_high_with_offset(tx_bd_desc, i, 0, dma64); + } + + /* Clear all status */ + clear_pci_tx_desc_content(desc, TX_DESC_SIZE); + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) { + /* This if needs braces */ + set_tx_buff_desc_len_0(tx_bd_desc, desc_size + 8); + } else { + set_tx_buff_desc_len_0(tx_bd_desc, desc_size); + } + } else { + set_tx_buff_desc_len_0(tx_bd_desc, desc_size); + } + set_tx_buff_desc_psb(tx_bd_desc, psblen); + set_tx_buff_desc_addr_low_0(tx_bd_desc, desc_dma_addr); + set_tx_buff_desc_addr_high_0(tx_bd_desc, ((u64)desc_dma_addr >> 32), + dma64); + + set_txbuffer_desc_len_with_offset(tx_bd_desc, 1, pkt_len); + /* don't using extendsion mode. */ + set_txbuffer_desc_amsdu_with_offset(tx_bd_desc, 1, 0); + set_txbuffer_desc_add_low_with_offset(tx_bd_desc, 1, addr); + set_txbuffer_desc_add_high_with_offset(tx_bd_desc, 1, + ((u64)addr >> 32), dma64); + + set_tx_desc_pkt_size(desc, (u16)(pkt_len)); + set_tx_desc_tx_buffer_size(desc, (u16)(pkt_len)); +} + +void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtlwifi_tx_info *tx_info = rtl_tx_skb_cb_info(skb); + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 fw_qsel = _rtl92ee_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 bw_40 = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + + if (pbd_desc_tx != NULL) + rtl92ee_pre_fill_tx_bd_desc(hw, pbd_desc_tx, pdesc8, hw_queue, + skb, mapping); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + set_tx_desc_pkt_offset(pdesc, 1); + set_tx_desc_offset(pdesc, + USB_HWDESC_HEADER_LEN + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + _rtl92ee_insert_emcontent(ptcb_desc, + (u8 *)(skb->data)); + } + } else { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + } + + + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + + if (ieee80211_is_mgmt(fc)) { + ptcb_desc->use_driver_rate = true; + } else { + if (rtlpriv->ra.is_special_data) { + ptcb_desc->use_driver_rate = true; + set_tx_desc_tx_rate(pdesc, DESC_RATE11M); + } else { + ptcb_desc->use_driver_rate = false; + } + } + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + set_tx_desc_rts_enable(pdesc, + ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, 0); + set_tx_desc_cts2self(pdesc, + ((ptcb_desc->cts_enable) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, + ((ptcb_desc->rts_rate <= DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (ptcb_desc->tx_enable_sw_calc_duration) + set_tx_desc_nav_use_hdr(pdesc, 1); + + if (bw_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + set_tx_desc_linip(pdesc, 0); + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *key = info->control.hw_key; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + } + } + + set_tx_desc_queue_sel(pdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, + ptcb_desc->disable_ratefallback ? 1 : 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /*set_tx_desc_pwr_status(pdesc, pwr_status);*/ + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + /*set_tx_desc_rts_rate(pdesc, 0x08); */ + /* set_tx_desc_tx_rate(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + /* tx report */ + rtl_set_tx_report(ptcb_desc, pdesc8, hw, tx_info); + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + set_tx_desc_tx_buffer_address(pdesc, mapping); + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->ratr_index); + } + + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + u8 txdesc_len = 40; + __le32 *pdesc = (__le32 *)pdesc8; + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, txdesc_len); + + set_tx_desc_offset(pdesc, txdesc_len); + + set_tx_desc_tx_rate(pdesc, DESC_RATE1M); + + set_tx_desc_seq(pdesc, 0); + + set_tx_desc_linip(pdesc, 0); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_offset(pdesc, 40); + + set_tx_desc_use_rate(pdesc, 1); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", pdesc, txdesc_len); +} + +void rtl92ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx, + u8 desc_name, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 q_idx = *val; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + case HW_DESC_OWN:{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx]; + u16 max_tx_desc = ring->entries; + + if (q_idx == BEACON_QUEUE) { + ring->cur_tx_wp = 0; + ring->cur_tx_rp = 0; + set_tx_buff_desc_own(pdesc, 1); + return; + } + + /* make sure tx desc is available by caller */ + ring->cur_tx_wp = ((ring->cur_tx_wp + 1) % max_tx_desc); + + rtl_write_word(rtlpriv, + get_desc_addr_fr_q_idx(q_idx), + ring->cur_tx_wp); + } + break; + } + } else { + switch (desc_name) { + case HW_DESC_RX_PREPARE: + set_rx_buffer_desc_ls(pdesc, 0); + set_rx_buffer_desc_fs(pdesc, 0); + set_rx_buffer_desc_total_length(pdesc, 0); + + set_rx_buffer_desc_data_length(pdesc, + MAX_RECEIVE_BUFFER_SIZE + + RX_DESC_SIZE); + + set_rx_buffer_physical_low(pdesc, (*(dma_addr_t *)val) & + DMA_BIT_MASK(32)); + set_rx_buffer_physical_high(pdesc, + ((u64)(*(dma_addr_t *)val) + >> 32), + dma64); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, + "rtl8192ee: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl92ee_get_desc(struct ieee80211_hw *hw, + u8 *pdesc8, bool istx, u8 desc_name) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u64 ret = 0; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(pdesc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_txbuffer_desc_addr_low(pdesc, 1); + ret |= (u64)get_txbuffer_desc_addr_high(pdesc, 1, + dma64) << 32; + break; + default: + WARN_ONCE(true, + "rtl8192ee: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(pdesc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(pdesc); + break; + default: + WARN_ONCE(true, + "rtl8192ee: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 read_point, write_point; + bool ret = false; + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + + { + u16 cur_tx_rp; + u32 tmpu32; + + tmpu32 = + rtl_read_dword(rtlpriv, + get_desc_addr_fr_q_idx(hw_queue)); + cur_tx_rp = (u16)((tmpu32 >> 16) & 0x0fff); + + /* don't need to update ring->cur_tx_wp */ + ring->cur_tx_rp = cur_tx_rp; + } + + read_point = ring->cur_tx_rp; + write_point = ring->cur_tx_wp; + + if (write_point > read_point) { + if (index < write_point && index >= read_point) + ret = false; + else + ret = true; + } else if (write_point < read_point) { + if (index > write_point && index < read_point) + ret = true; + else + ret = false; + } else { + if (index != read_point) + ret = true; + } + + if (hw_queue == BEACON_QUEUE) + ret = true; + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) + ret = true; + + return ret; +} + +void rtl92ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h new file mode 100644 index 000000000..4c6cf4f16 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h @@ -0,0 +1,744 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL92E_TRX_H__ +#define __RTL92E_TRX_H__ + +#define TX_DESC_SIZE 64 + +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 40 + +#define RX_DESC_SIZE 24 +#define MAX_RECEIVE_BUFFER_SIZE 8192 + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(20, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(12)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(13)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(13)); +} + +static inline void set_tx_desc_nav_use_hdr(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(15)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(21, 17)); +} + +/* Dword 4 */ +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(28, 24)); +} + +/* Dword 5 */ +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(3, 0)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(6, 5)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(12)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13)); +} + +/* Dword 7 */ +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +/* Dword 9 */ +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 9), __val, GENMASK(23, 12)); +} + +/* Dword 10 */ +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +/* Dword 11*/ +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 12) = cpu_to_le32(__val); +} + +static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits(__paddr, __val, GENMASK(3, 0)); +} + +static inline void set_earlymode_len0(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits(__paddr, __val, GENMASK(18, 4)); +} + +static inline void set_earlymode_len1(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits(__paddr, __val, GENMASK(17, 16)); +} + +static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits(__paddr, __val, GENMASK(5, 2)); +} + +static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits((__paddr + 1), __val, GENMASK(7, 0)); +} + +static inline void set_earlymode_len3(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits((__paddr + 1), __val, GENMASK(31, 17)); +} + +static inline void set_earlymode_len4(__le32 *__paddr, u32 __val) +{ + le32p_replace_bits((__paddr + 1), __val, GENMASK(31, 20)); +} + +/* TX/RX buffer descriptor */ + +/* for Txfilldescroptor92ee, fill the desc content. */ +static inline void set_txbuffer_desc_len_with_offset(__le32 *__pdesc, + u8 __offset, u32 __val) +{ + le32p_replace_bits((__pdesc + 4 * __offset), __val, + GENMASK(15, 0)); +} + +static inline void set_txbuffer_desc_amsdu_with_offset(__le32 *__pdesc, + u8 __offset, u32 __val) +{ + le32p_replace_bits((__pdesc + 4 * __offset), __val, BIT(31)); +} + +static inline void set_txbuffer_desc_add_low_with_offset(__le32 *__pdesc, + u8 __offset, + u32 __val) +{ + *(__pdesc + 4 * __offset + 1) = cpu_to_le32(__val); +} + +static inline void set_txbuffer_desc_add_high_with_offset(__le32 *pbd, u8 off, + u32 val, bool dma64) +{ + if (dma64) + *(pbd + 4 * off + 2) = cpu_to_le32(val); + else + *(pbd + 4 * off + 2) = 0; +} + +static inline u32 get_txbuffer_desc_addr_low(__le32 *__pdesc, u8 __offset) +{ + return le32_to_cpu(*((__pdesc + 4 * __offset + 1))); +} + +static inline u32 get_txbuffer_desc_addr_high(__le32 *pbd, u32 off, bool dma64) +{ + if (dma64) + return le32_to_cpu(*((pbd + 4 * off + 2))); + return 0; +} + +/* Dword 0 */ +static inline void set_tx_buff_desc_len_0(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_tx_buff_desc_psb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(30, 16)); +} + +static inline void set_tx_buff_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +/* Dword 1 */ +static inline void set_tx_buff_desc_addr_low_0(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 1) = cpu_to_le32(__val); +} + +/* Dword 2 */ +static inline void set_tx_buff_desc_addr_high_0(__le32 *pdesc, u32 val, + bool dma64) +{ + if (dma64) + *(pdesc + 2) = cpu_to_le32(val); + else + *(pdesc + 2) = 0; +} + +/* RX buffer */ + +/* DWORD 0 */ +static inline void set_rx_buffer_desc_data_length(__le32 *__status, u32 __val) +{ + le32p_replace_bits(__status, __val, GENMASK(13, 0)); +} + +static inline void set_rx_buffer_desc_ls(__le32 *__status, u32 __val) +{ + le32p_replace_bits(__status, __val, BIT(15)); +} + +static inline void set_rx_buffer_desc_fs(__le32 *__status, u32 __val) +{ + le32p_replace_bits(__status, __val, BIT(16)); +} + +static inline void set_rx_buffer_desc_total_length(__le32 *__status, u32 __val) +{ + le32p_replace_bits(__status, __val, GENMASK(30, 16)); +} + +static inline int get_rx_buffer_desc_ls(__le32 *__status) +{ + return le32_get_bits(*(__status), BIT(15)); +} + +static inline int get_rx_buffer_desc_fs(__le32 *__status) +{ + return le32_get_bits(*(__status), BIT(16)); +} + +static inline int get_rx_buffer_desc_total_length(__le32 *__status) +{ + return le32_get_bits(*(__status), GENMASK(30, 16)); +} + +/* DWORD 1 */ +static inline void set_rx_buffer_physical_low(__le32 *__status, u32 __val) +{ + *(__status + 1) = cpu_to_le32(__val); +} + +/* DWORD 2 */ +static inline void set_rx_buffer_physical_high(__le32 *__rx_status_desc, + u32 __val, bool dma64) +{ + if (dma64) + *(__rx_status_desc + 2) = cpu_to_le32(__val); + else + *(__rx_status_desc + 2) = 0; +} + +static inline int get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(13, 0)); +} + +static inline int get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(14)); +} + +static inline int get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(15)); +} + +static inline int get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(19, 16)); +} + +static inline int get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(25, 24)); +} + +static inline int get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(26)); +} + +static inline int get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(27)); +} + +static inline int get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline int get_rx_desc_macid(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(6, 0)); +} + +static inline int get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline int get_rx_status_desc_rpt_sel(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 2), BIT(28)); +} + +static inline int get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(6, 0)); +} + +static inline int get_rx_status_desc_pattern_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(29)); +} + +static inline int get_rx_status_desc_unicast_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(30)); +} + +static inline int get_rx_status_desc_magic_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(31)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 5))); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 6))); +} + +/* TX report 2 format in Rx desc*/ + +static inline u32 get_rx_rpt2_desc_macid_valid_1(__le32 *__status) +{ + return le32_to_cpu(*((__status + 4))); +} + +static inline u32 get_rx_rpt2_desc_macid_valid_2(__le32 *__status) +{ + return le32_to_cpu(*((__status + 5))); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, int _size) +{ + if (_size > TX_DESC_NEXT_DESC_OFFSET) + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); + else + memset(__pdesc, 0, _size); +} + +#define RTL92EE_RX_HAL_IS_CCK_RATE(rxmcs)\ + (rxmcs == DESC_RATE1M ||\ + rxmcs == DESC_RATE2M ||\ + rxmcs == DESC_RATE5_5M ||\ + rxmcs == DESC_RATE11M) + +#define IS_LITTLE_ENDIAN 1 + +struct phy_rx_agc_info_t { + #if IS_LITTLE_ENDIAN + u8 gain:7, trsw:1; + #else + u8 trsw:1, gain:7; + #endif +}; + +struct phy_status_rpt { + struct phy_rx_agc_info_t path_agc[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 rsvd_1; + u8 noise_power_db_msb; + u8 path_cfotail[2]; + u8 pcts_mask[2]; + u8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 rsvd_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + u8 sig_evm; + u8 rsvd_3; +#if IS_LITTLE_ENDIAN + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ + u8 sgi_en:1; + u8 rxsc:2; + u8 idle_long:1; + u8 r_ant_train_en:1; + u8 ant_sel_b:1; + u8 ant_sel:1; +#else /* _BIG_ENDIAN_ */ + u8 ant_sel:1; + u8 ant_sel_b:1; + u8 r_ant_train_en:1; + u8 idle_long:1; + u8 rxsc:2; + u8 sgi_en:1; + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ +#endif +} __packed; + +struct rx_fwinfo { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:6; + u32 rsvd0:2; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rdg_en:1; + u32 bar_retryht:2; + u32 agg_break:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 bt_int:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_ssn:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 pwr_status:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 sw_offset30:8; + u32 sw_offset31:4; + u32 rsvd1:1; + u32 antsel_c:1; + u32 null_0:1; + u32 null_1:1; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:6; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl92ee_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); +u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, + u8 queue_index); +u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); + +void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); + +u64 rtl92ee_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index); +void rtl92ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile new file mode 100644 index 000000000..e577235f5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8192se-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192SE) += rtl8192se.o + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h new file mode 100644 index 000000000..f43331224 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h @@ -0,0 +1,431 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_92S_DEF_H__ +#define __REALTEK_92S_DEF_H__ + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + +/* Queue Select Value in TxDesc */ +#define QSLT_BK 0x2 +#define QSLT_BE 0x0 +#define QSLT_VI 0x5 +#define QSLT_VO 0x6 +#define QSLT_BEACON 0x10 +#define QSLT_HIGH 0x11 +#define QSLT_MGNT 0x12 +#define QSLT_CMD 0x13 + +/* Tx Desc */ +#define TX_DESC_SIZE_RTL8192S (16 * 4) +#define TX_CMDDESC_SIZE_RTL8192S (16 * 4) + +/* macros to read/write various fields in RX or TX descriptors */ + +/* Dword 0 */ +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +/* Dword 1 */ +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_non_qos(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +/* Dword 2 */ +static inline void set_tx_desc_rsvd_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(29)); +} + +/* Dword 3 */ +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16)); +} + +/* Dword 4 */ +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_cts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(12)); +} + +static inline void set_tx_desc_ra_brsr_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(15, 13)); +} + +static inline void set_tx_desc_txht(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(16)); +} + +static inline void set_tx_desc_tx_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(17)); +} + +static inline void set_tx_desc_tx_bandwidth(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(18)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(20, 19)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(25)); +} + +static inline void set_tx_desc_rts_bandwidth(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(26)); +} + +static inline void set_tx_desc_rts_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(28, 27)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(30, 29)); +} + +static inline void set_tx_desc_user_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(31)); +} + +/* Dword 5 */ +static inline void set_tx_desc_packet_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(8, 0)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(14, 9)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(20, 16)); +} + +/* Dword 7 */ +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +/* Dword 8 */ +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 8) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 8))); +} + +/* Dword 9 */ +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 9) = cpu_to_le32(__val); +} + +/* Because the PCI Tx descriptors are chaied at the + * initialization and all the NextDescAddresses in + * these descriptors cannot not be cleared (,or + * driver/HW cannot find the next descriptor), the + * offset 36 (NextDescAddresses) is reserved when + * the desc is cleared. */ +#define TX_DESC_NEXT_DESC_OFFSET 36 +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ + memset(__pdesc, 0, min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET)) + +/* Rx Desc */ +#define RX_STATUS_DESC_SIZE 24 +#define RX_DRV_INFO_SIZE_UNIT 8 + +/* DWORD 0 */ +static inline void set_rx_status_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_status_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_status_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_rx_status_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(13, 0)); +} + +static inline u32 get_rx_status_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(14)); +} + +static inline u32 get_rx_status_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(15)); +} + +static inline u32 get_rx_status_desc_drvinfo_size(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(19, 16)); +} + +static inline u32 get_rx_status_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(25, 24)); +} + +static inline u32 get_rx_status_desc_phy_status(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(26)); +} + +static inline u32 get_rx_status_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(27)); +} + +static inline u32 get_rx_status_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +/* DWORD 1 */ +static inline u32 get_rx_status_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(14)); +} + +static inline u32 get_rx_status_desc_faggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +/* DWORD 3 */ +static inline u32 get_rx_status_desc_rx_mcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0)); +} + +static inline u32 get_rx_status_desc_rx_ht(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(6)); +} + +static inline u32 get_rx_status_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(8)); +} + +static inline u32 get_rx_status_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(9)); +} + +/* DWORD 5 */ +static inline u32 get_rx_status_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 5))); +} + +/* DWORD 6 */ +static inline void set_rx_status__desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +static inline u32 get_rx_status_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 6)); +} + +#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\ + (get_rx_status_desc_rx_mcs(_pdesc) == DESC_RATE1M || \ + get_rx_status_desc_rx_mcs(_pdesc) == DESC_RATE2M || \ + get_rx_status_desc_rx_mcs(_pdesc) == DESC_RATE5_5M ||\ + get_rx_status_desc_rx_mcs(_pdesc) == DESC_RATE11M) + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum ic_inferiority { + IC_INFERIORITY_A = 0, + IC_INFERIORITY_B = 1, +}; + +enum fwcmd_iotype { + /* For DIG DM */ + FW_CMD_DIG_ENABLE = 0, + FW_CMD_DIG_DISABLE = 1, + FW_CMD_DIG_HALT = 2, + FW_CMD_DIG_RESUME = 3, + /* For High Power DM */ + FW_CMD_HIGH_PWR_ENABLE = 4, + FW_CMD_HIGH_PWR_DISABLE = 5, + /* For Rate adaptive DM */ + FW_CMD_RA_RESET = 6, + FW_CMD_RA_ACTIVE = 7, + FW_CMD_RA_REFRESH_N = 8, + FW_CMD_RA_REFRESH_BG = 9, + FW_CMD_RA_INIT = 10, + /* For FW supported IQK */ + FW_CMD_IQK_INIT = 11, + /* Tx power tracking switch, + * MP driver only */ + FW_CMD_TXPWR_TRACK_ENABLE = 12, + /* Tx power tracking switch, + * MP driver only */ + FW_CMD_TXPWR_TRACK_DISABLE = 13, + /* Tx power tracking with thermal + * indication, for Normal driver */ + FW_CMD_TXPWR_TRACK_THERMAL = 14, + FW_CMD_PAUSE_DM_BY_SCAN = 15, + FW_CMD_RESUME_DM_BY_SCAN = 16, + FW_CMD_RA_REFRESH_N_COMB = 17, + FW_CMD_RA_REFRESH_BG_COMB = 18, + FW_CMD_ANTENNA_SW_ENABLE = 19, + FW_CMD_ANTENNA_SW_DISABLE = 20, + /* Tx Status report for CCX from FW */ + FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21, + /* Indifate firmware that driver + * enters LPS, For PS-Poll issue */ + FW_CMD_LPS_ENTER = 22, + /* Indicate firmware that driver + * leave LPS*/ + FW_CMD_LPS_LEAVE = 23, + /* Set DIG mode to signal strength */ + FW_CMD_DIG_MODE_SS = 24, + /* Set DIG mode to false alarm. */ + FW_CMD_DIG_MODE_FA = 25, + FW_CMD_ADD_A2_ENTRY = 26, + FW_CMD_CTRL_DM_BY_DRIVER = 27, + FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28, + FW_CMD_PAPE_CONTROL = 29, + FW_CMD_IQK_ENABLE = 30, +}; + +/* Driver info contain PHY status + * and other variabel size info + * PHY Status content as below + */ +struct rx_fwinfo { + /* DWORD 0 */ + u8 gain_trsw[4]; + /* DWORD 1 */ + u8 pwdb_all; + u8 cfosho[4]; + /* DWORD 2 */ + u8 cfotail[4]; + /* DWORD 3 */ + s8 rxevm[2]; + s8 rxsnr[4]; + /* DWORD 4 */ + u8 pdsnr[2]; + /* DWORD 5 */ + u8 csi_current[2]; + u8 csi_target[2]; + /* DWORD 6 */ + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +}; + +struct phy_sts_cck_8192s_t { + u8 adc_pwdb_x[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +#endif + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c new file mode 100644 index 000000000..5fce3db52 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c @@ -0,0 +1,717 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" + +static const u32 edca_setting_dl[PEER_MAX] = { + 0xa44f, /* 0 UNKNOWN */ + 0x5ea44f, /* 1 REALTEK_90 */ + 0x5ea44f, /* 2 REALTEK_92SE */ + 0xa630, /* 3 BROAD */ + 0xa44f, /* 4 RAL */ + 0xa630, /* 5 ATH */ + 0xa630, /* 6 CISCO */ + 0xa42b, /* 7 MARV */ +}; + +static const u32 edca_setting_dl_gmode[PEER_MAX] = { + 0x4322, /* 0 UNKNOWN */ + 0xa44f, /* 1 REALTEK_90 */ + 0x5ea44f, /* 2 REALTEK_92SE */ + 0xa42b, /* 3 BROAD */ + 0x5e4322, /* 4 RAL */ + 0x4322, /* 5 ATH */ + 0xa430, /* 6 CISCO */ + 0x5ea44f, /* 7 MARV */ +}; + +static const u32 edca_setting_ul[PEER_MAX] = { + 0x5e4322, /* 0 UNKNOWN */ + 0xa44f, /* 1 REALTEK_90 */ + 0x5ea44f, /* 2 REALTEK_92SE */ + 0x5ea322, /* 3 BROAD */ + 0x5ea422, /* 4 RAL */ + 0x5ea322, /* 5 ATH */ + 0x3ea44f, /* 6 CISCO */ + 0x5ea44f, /* 7 MARV */ +}; + +static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + + u32 edca_be_ul = edca_setting_ul[mac->vendor]; + u32 edca_be_dl = edca_setting_dl[mac->vendor]; + u32 edca_gmode = edca_setting_dl_gmode[mac->vendor]; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + goto dm_checkedcaturbo_exit; + } + + if ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + if (rtlpriv->phy.rf_type == RF_1T2R) { + if (cur_txok_cnt > 4 * cur_rxok_cnt) { + /* Uplink TP is present. */ + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, EDCAPARA_BE, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } else {/* Balance TP is present. */ + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + if (mac->mode == WIRELESS_MODE_G || + mac->mode == WIRELESS_MODE_B) + rtl_write_dword(rtlpriv, + EDCAPARA_BE, + edca_gmode); + else + rtl_write_dword(rtlpriv, + EDCAPARA_BE, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + if (mac->mode == WIRELESS_MODE_G || + mac->mode == WIRELESS_MODE_B) + rtl_write_dword(rtlpriv, + EDCAPARA_BE, + edca_gmode); + else + rtl_write_dword(rtlpriv, + EDCAPARA_BE, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, EDCAPARA_BE, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + &tmp); + rtlpriv->dm.current_turbo_edca = false; + } + } + +dm_checkedcaturbo_exit: + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void _rtl92s_dm_txpowertracking_callback_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue = 0; + u32 fw_cmd = 0; + + rtlpriv->dm.txpower_trackinginit = true; + + thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); + + if (thermalvalue) { + rtlpriv->dm.thermalvalue = thermalvalue; + if (hal_get_firmwareversion(rtlpriv) >= 0x35) { + rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL); + } else { + fw_cmd = (FW_TXPWR_TRACK_THERMAL | + (rtlpriv->efuse.thermalmeter[0] << 8) | + (thermalvalue << 16)); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Write to FW Thermal Val = 0x%x\n", fw_cmd); + + rtl_write_dword(rtlpriv, WFM5, fw_cmd); + rtl92s_phy_chk_fwcmd_iodone(hw); + } + } + + rtlpriv->dm.txpowercount = 0; +} + +static void _rtl92s_dm_check_txpowertracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 tx_power_checkcnt = 5; + + /* 2T2R TP issue */ + if (rtlphy->rf_type == RF_2T2R) + return; + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) { + rtlpriv->dm.txpowercount++; + return; + } + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, + RFREG_OFFSET_MASK, 0x60); + rtlpriv->dm.tm_trigger = 1; + } else { + _rtl92s_dm_txpowertracking_callback_thermalmeter(hw); + rtlpriv->dm.tm_trigger = 0; + } +} + +static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *ra = &(rtlpriv->ra); + struct ieee80211_sta *sta = NULL; + u32 low_rssi_thresh = 0; + u32 middle_rssi_thresh = 0; + u32 high_rssi_thresh = 0; + + if (is_hal_stop(rtlhal)) + return; + + if (!rtlpriv->dm.useramask) + return; + + if (hal_get_firmwareversion(rtlpriv) >= 61 && + !rtlpriv->dm.inform_fw_driverctrldm) { + rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER); + rtlpriv->dm.inform_fw_driverctrldm = true; + } + + if ((mac->link_state == MAC80211_LINKED) && + (mac->opmode == NL80211_IFTYPE_STATION)) { + switch (ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssi_thresh = 40; + middle_rssi_thresh = 30; + low_rssi_thresh = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssi_thresh = 44; + middle_rssi_thresh = 30; + low_rssi_thresh = 20; + break; + case DM_RATR_STA_LOW: + high_rssi_thresh = 44; + middle_rssi_thresh = 34; + low_rssi_thresh = 20; + break; + case DM_RATR_STA_ULTRALOW: + high_rssi_thresh = 44; + middle_rssi_thresh = 34; + low_rssi_thresh = 24; + break; + default: + high_rssi_thresh = 44; + middle_rssi_thresh = 34; + low_rssi_thresh = 24; + break; + } + + if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) { + ra->ratr_state = DM_RATR_STA_HIGH; + } else if (rtlpriv->dm.undec_sm_pwdb > + (long)middle_rssi_thresh) { + ra->ratr_state = DM_RATR_STA_LOW; + } else if (rtlpriv->dm.undec_sm_pwdb > + (long)low_rssi_thresh) { + ra->ratr_state = DM_RATR_STA_LOW; + } else { + ra->ratr_state = DM_RATR_STA_ULTRALOW; + } + + if (ra->pre_ratr_state != ra->ratr_state) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", + rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, + ra->pre_ratr_state, ra->ratr_state); + + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, + ra->ratr_state, + true); + rcu_read_unlock(); + + ra->pre_ratr_state = ra->ratr_state; + } + } +} + +static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + bool current_mrc; + bool enable_mrc = true; + long tmpentry_maxpwdb = 0; + u8 rssi_a = 0; + u8 rssi_b = 0; + + if (is_hal_stop(rtlhal)) + return; + + if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R)) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); + + if (mac->link_state >= MAC80211_LINKED) { + if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) { + rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; + rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; + } + } + + /* MRC settings would NOT affect TP on Wireless B mode. */ + if (mac->mode != WIRELESS_MODE_B) { + if ((rssi_a == 0) && (rssi_b == 0)) { + enable_mrc = true; + } else if (rssi_b > 30) { + /* Turn on B-Path */ + enable_mrc = true; + } else if (rssi_b < 5) { + /* Turn off B-path */ + enable_mrc = false; + /* Take care of RSSI differentiation. */ + } else if (rssi_a > 15 && (rssi_a >= rssi_b)) { + if ((rssi_a - rssi_b) > 15) + /* Turn off B-path */ + enable_mrc = false; + else if ((rssi_a - rssi_b) < 10) + /* Turn on B-Path */ + enable_mrc = true; + else + enable_mrc = current_mrc; + } else { + /* Turn on B-Path */ + enable_mrc = true; + } + } + + /* Update MRC settings if needed. */ + if (enable_mrc != current_mrc) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, + (u8 *)&enable_mrc); + +} + +void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} + +static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *ra = &(rtlpriv->ra); + + ra->ratr_state = DM_RATR_STA_MAX; + ra->pre_ratr_state = DM_RATR_STA_MAX; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER && + hal_get_firmwareversion(rtlpriv) >= 60) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + + rtlpriv->dm.useramask = false; + rtlpriv->dm.inform_fw_driverctrldm = false; +} + +static void _rtl92s_dm_init_txpowertracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpowercount = 0; + rtlpriv->dm.txpower_trackinginit = false; +} + +static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + u32 ret_value; + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail; + + /* read CCK false alarm */ + ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD); + falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + + falsealm_cnt->cnt_cck_fail; +} + +static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *digtable = &rtlpriv->dm_digtable; + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + if (falsealm_cnt->cnt_all > digtable->fa_highthresh) { + if ((digtable->back_val - 6) < + digtable->backoffval_range_min) + digtable->back_val = digtable->backoffval_range_min; + else + digtable->back_val -= 6; + } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) { + if ((digtable->back_val + 6) > + digtable->backoffval_range_max) + digtable->back_val = + digtable->backoffval_range_max; + else + digtable->back_val += 6; + } +} + +static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *digtable = &rtlpriv->dm_digtable; + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + static u8 initialized, force_write; + u8 initial_gain = 0; + + if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) || + (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) { + if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) { + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (digtable->backoff_enable_flag) + rtl92s_backoff_enable_flag(hw); + else + digtable->back_val = DM_DIG_BACKOFF_MAX; + + if ((digtable->rssi_val + 10 - digtable->back_val) > + digtable->rx_gain_max) + digtable->cur_igvalue = + digtable->rx_gain_max; + else if ((digtable->rssi_val + 10 - digtable->back_val) + < digtable->rx_gain_min) + digtable->cur_igvalue = + digtable->rx_gain_min; + else + digtable->cur_igvalue = digtable->rssi_val + 10 + - digtable->back_val; + + if (falsealm_cnt->cnt_all > 10000) + digtable->cur_igvalue = + (digtable->cur_igvalue > 0x33) ? + digtable->cur_igvalue : 0x33; + + if (falsealm_cnt->cnt_all > 16000) + digtable->cur_igvalue = + digtable->rx_gain_max; + /* connected -> connected or disconnected -> disconnected */ + } else { + /* Firmware control DIG, do nothing in driver dm */ + return; + } + /* disconnected -> connected or connected -> + * disconnected or beforeconnect->(dis)connected */ + } else { + /* Enable FW DIG */ + digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); + + digtable->back_val = DM_DIG_BACKOFF_MAX; + digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; + digtable->pre_igvalue = 0; + return; + } + + /* Forced writing to prevent from fw-dig overwriting. */ + if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, + MASKBYTE0)) + force_write = 1; + + if ((digtable->pre_igvalue != digtable->cur_igvalue) || + !initialized || force_write) { + /* Disable FW DIG */ + rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE); + + initial_gain = (u8)digtable->cur_igvalue; + + /* Set initial gain. */ + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain); + digtable->pre_igvalue = digtable->cur_igvalue; + initialized = 1; + force_write = 0; + } +} + +static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dig = &rtlpriv->dm_digtable; + + if (rtlpriv->mac80211.act_scanning) + return; + + /* Decide the current status and if modify initial gain or not */ + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) + dig->cur_sta_cstate = DIG_STA_CONNECT; + else + dig->cur_sta_cstate = DIG_STA_DISCONNECT; + + dig->rssi_val = rtlpriv->dm.undec_sm_pwdb; + + /* Change dig mode to rssi */ + if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) { + if (dig->dig_twoport_algorithm == + DIG_TWO_PORT_ALGO_FALSE_ALARM) { + dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; + rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS); + } + } + + _rtl92s_dm_false_alarm_counter_statistics(hw); + _rtl92s_dm_initial_gain_sta_beforeconnect(hw); + + dig->pre_sta_cstate = dig->cur_sta_cstate; +} + +static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct dig_t *digtable = &rtlpriv->dm_digtable; + + /* 2T2R TP issue */ + if (rtlphy->rf_type == RF_2T2R) + return; + + if (!rtlpriv->dm.dm_initialgain_enable) + return; + + if (digtable->dig_enable_flag == false) + return; + + _rtl92s_dm_ctrl_initgain_bytwoport(hw); +} + +static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + long txpwr_threshold_lv1, txpwr_threshold_lv2; + + /* 2T2R TP issue */ + if (rtlphy->rf_type == RF_2T2R) + return; + + if (!rtlpriv->dm.dynamic_txpower_enable || + rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; + txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1; + + if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; + else if (undec_sm_pwdb >= txpwr_threshold_lv2) + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; + else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) && + (undec_sm_pwdb >= txpwr_threshold_lv1)) + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; + else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3)) + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) + rtl92s_phy_set_txpower(hw, rtlphy->current_channel); + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *digtable = &rtlpriv->dm_digtable; + + /* Disable DIG scheme now.*/ + digtable->dig_enable_flag = true; + digtable->backoff_enable_flag = true; + + if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) && + (hal_get_firmwareversion(rtlpriv) >= 0x3c)) + digtable->dig_algorithm = DIG_ALGO_BY_TOW_PORT; + else + digtable->dig_algorithm = + DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM; + + digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; + digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + /* off=by real rssi value, on=by digtable->rssi_val for new dig */ + digtable->dig_dbgmode = DM_DBG_OFF; + digtable->dig_slgorithm_switch = 0; + + /* 2007/10/04 MH Define init gain threshol. */ + digtable->dig_state = DM_STA_DIG_MAX; + digtable->dig_highpwrstate = DM_STA_DIG_MAX; + + digtable->cur_sta_cstate = DIG_STA_DISCONNECT; + digtable->pre_sta_cstate = DIG_STA_DISCONNECT; + digtable->cur_ap_cstate = DIG_AP_DISCONNECT; + digtable->pre_ap_cstate = DIG_AP_DISCONNECT; + + digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; + digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; + + digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + + digtable->rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; + digtable->rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; + + /* for dig debug rssi value */ + digtable->rssi_val = 50; + digtable->back_val = DM_DIG_BACKOFF_MAX; + digtable->rx_gain_max = DM_DIG_MAX; + + digtable->rx_gain_min = DM_DIG_MIN; + + digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX; + digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN; +} + +static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if ((hal_get_firmwareversion(rtlpriv) >= 60) && + (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)) + rtlpriv->dm.dynamic_txpower_enable = true; + else + rtlpriv->dm.dynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; +} + +void rtl92s_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtlpriv->dm.undec_sm_pwdb = -1; + + _rtl92s_dm_init_dynamic_txpower(hw); + rtl92s_dm_init_edca_turbo(hw); + _rtl92s_dm_init_rate_adaptive_mask(hw); + _rtl92s_dm_init_txpowertracking_thermalmeter(hw); + _rtl92s_dm_init_dig(hw); + + rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE); +} + +void rtl92s_dm_watchdog(struct ieee80211_hw *hw) +{ + _rtl92s_dm_check_edca_turbo(hw); + _rtl92s_dm_check_txpowertracking_thermalmeter(hw); + _rtl92s_dm_ctrl_initgain_byrssi(hw); + _rtl92s_dm_dynamic_txpower(hw); + _rtl92s_dm_refresh_rateadaptive_mask(hw); + _rtl92s_dm_switch_baseband_mrc(hw); +} + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h new file mode 100644 index 000000000..b9c5a92c2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_92S_DM_H__ +#define __RTL_92S_DM_H__ + +enum dm_dig_alg { + DIG_ALGO_BY_FALSE_ALARM = 0, + DIG_ALGO_BY_RSSI = 1, + DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2, + DIG_ALGO_BY_TOW_PORT = 3, + DIG_ALGO_MAX +}; + +enum dm_dig_two_port_alg { + DIG_TWO_PORT_ALGO_RSSI = 0, + DIG_TWO_PORT_ALGO_FALSE_ALARM = 1, +}; + +enum dm_dig_dbg { + DM_DBG_OFF = 0, + DM_DBG_ON = 1, + DM_DBG_MAX +}; + +enum dm_dig_sta { + DM_STA_DIG_OFF = 0, + DM_STA_DIG_ON, + DM_STA_DIG_MAX +}; + +enum dm_ratr_sta { + DM_RATR_STA_HIGH = 0, + DM_RATR_STA_MIDDLEHIGH = 1, + DM_RATR_STA_MIDDLE = 2, + DM_RATR_STA_MIDDLELOW = 3, + DM_RATR_STA_LOW = 4, + DM_RATR_STA_ULTRALOW = 5, + DM_RATR_STA_MAX +}; + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_HIGH_PWR_LEVEL_NORMAL 0 +#define TX_HIGH_PWR_LEVEL_LEVEL1 1 +#define TX_HIGH_PWR_LEVEL_LEVEL2 2 + +#define HAL_DM_DIG_DISABLE BIT(0) /* Disable Dig */ +#define HAL_DM_HIPWR_DISABLE BIT(1) /* Disable High Power */ + +#define TX_HIGHPWR_LEVEL_NORMAL 0 +#define TX_HIGHPWR_LEVEL_NORMAL1 1 +#define TX_HIGHPWR_LEVEL_NORMAL2 2 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 +#define DM_DIG_HIGH_PWR_THRESH_LOW 70 +#define DM_DIG_MIN_NETCORE 0x12 + +void rtl92s_dm_watchdog(struct ieee80211_hw *hw); +void rtl92s_dm_init(struct ieee80211_hw *hw); +void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c new file mode 100644 index 000000000..579b1789d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c @@ -0,0 +1,616 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "fw.h" + +static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_dword(rtlpriv, RQPN, 0xffffffff); + rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff); + rtl_write_byte(rtlpriv, RQPN + 8, 0xff); + rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80); +} + +static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 ichecktime = 200; + u16 tmpu2b; + u8 tmpu1b, cpustatus = 0; + + _rtl92s_fw_set_rqpn(hw); + + /* Enable CPU. */ + tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR); + /* AFE source */ + rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL)); + + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN)); + + /* Polling IMEM Ready after CPU has refilled. */ + do { + cpustatus = rtl_read_byte(rtlpriv, TCR); + if (cpustatus & IMEM_RDY) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "IMEM Ready after CPU has refilled\n"); + break; + } + + udelay(100); + } while (ichecktime--); + + if (!(cpustatus & IMEM_RDY)) + return false; + + return true; +} + +static enum fw_status _rtl92s_firmware_get_nextstatus( + enum fw_status fw_currentstatus) +{ + enum fw_status next_fwstatus = 0; + + switch (fw_currentstatus) { + case FW_STATUS_INIT: + next_fwstatus = FW_STATUS_LOAD_IMEM; + break; + case FW_STATUS_LOAD_IMEM: + next_fwstatus = FW_STATUS_LOAD_EMEM; + break; + case FW_STATUS_LOAD_EMEM: + next_fwstatus = FW_STATUS_LOAD_DMEM; + break; + case FW_STATUS_LOAD_DMEM: + next_fwstatus = FW_STATUS_READY; + break; + default: + break; + } + + return next_fwstatus; +} + +static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (rtlphy->rf_type) { + case RF_1T1R: + return 0x11; + case RF_1T2R: + return 0x12; + case RF_2T2R: + return 0x22; + default: + pr_err("Unknown RF type(%x)\n", rtlphy->rf_type); + break; + } + return 0x22; +} + +static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw, + struct fw_priv *pfw_priv) +{ + /* Update RF types for RATR settings. */ + pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw); +} + + + +static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb, u8 last) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + unsigned long flags; + u8 idx = 0; + + ring = &rtlpci->tx_ring[TXCMD_QUEUE]; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + pdesc = &ring->desc[idx]; + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb); + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + return true; +} + +static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, + u8 *code_virtual_address, u32 buffer_len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct sk_buff *skb; + struct rtl_tcb_desc *tcb_desc; + u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; + u16 frag_length, frag_offset = 0; + u16 extra_descoffset = 0; + u8 last_inipkt = 0; + + _rtl92s_fw_set_rqpn(hw); + + if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { + pr_err("Size over FIRMWARE_CODE_SIZE!\n"); + return false; + } + + extra_descoffset = 0; + + do { + if ((buffer_len - frag_offset) > frag_threshold) { + frag_length = frag_threshold + extra_descoffset; + } else { + frag_length = (u16)(buffer_len - frag_offset + + extra_descoffset); + last_inipkt = 1; + } + + /* Allocate skb buffer to contain firmware */ + /* info and tx descriptor info. */ + skb = dev_alloc_skb(frag_length); + if (!skb) + return false; + skb_reserve(skb, extra_descoffset); + skb_put_data(skb, code_virtual_address + frag_offset, + (u32)(frag_length - extra_descoffset)); + + tcb_desc = (struct rtl_tcb_desc *)(skb->cb); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT; + tcb_desc->last_inipkt = last_inipkt; + + _rtl92s_cmd_send_packet(hw, skb, last_inipkt); + + frag_offset += (frag_length - extra_descoffset); + + } while (frag_offset < buffer_len); + + rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ); + + return true ; +} + +static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, + u8 loadfw_status) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware; + u32 tmpu4b; + u8 cpustatus = 0; + short pollingcnt = 1000; + bool rtstatus = true; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "LoadStaus(%d)\n", loadfw_status); + + firmware->fwstatus = (enum fw_status)loadfw_status; + + switch (loadfw_status) { + case FW_STATUS_LOAD_IMEM: + /* Polling IMEM code done. */ + do { + cpustatus = rtl_read_byte(rtlpriv, TCR); + if (cpustatus & IMEM_CODE_DONE) + break; + udelay(5); + } while (pollingcnt--); + + if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { + pr_err("FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n", + cpustatus); + goto status_check_fail; + } + break; + + case FW_STATUS_LOAD_EMEM: + /* Check Put Code OK and Turn On CPU */ + /* Polling EMEM code done. */ + do { + cpustatus = rtl_read_byte(rtlpriv, TCR); + if (cpustatus & EMEM_CODE_DONE) + break; + udelay(5); + } while (pollingcnt--); + + if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { + pr_err("FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n", + cpustatus); + goto status_check_fail; + } + + /* Turn On CPU */ + rtstatus = _rtl92s_firmware_enable_cpu(hw); + if (!rtstatus) { + pr_err("Enable CPU fail!\n"); + goto status_check_fail; + } + break; + + case FW_STATUS_LOAD_DMEM: + /* Polling DMEM code done */ + do { + cpustatus = rtl_read_byte(rtlpriv, TCR); + if (cpustatus & DMEM_CODE_DONE) + break; + udelay(5); + } while (pollingcnt--); + + if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { + pr_err("Polling DMEM code done fail ! cpustatus(%#x)\n", + cpustatus); + goto status_check_fail; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "DMEM code download success, cpustatus(%#x)\n", + cpustatus); + + /* Prevent Delay too much and being scheduled out */ + /* Polling Load Firmware ready */ + pollingcnt = 2000; + do { + cpustatus = rtl_read_byte(rtlpriv, TCR); + if (cpustatus & FWRDY) + break; + udelay(40); + } while (pollingcnt--); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Polling Load Firmware ready, cpustatus(%x)\n", + cpustatus); + + if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || + (pollingcnt <= 0)) { + pr_err("Polling Load Firmware ready fail ! cpustatus(%x)\n", + cpustatus); + goto status_check_fail; + } + + /* If right here, we can set TCR/RCR to desired value */ + /* and config MAC lookback mode to normal mode */ + tmpu4b = rtl_read_dword(rtlpriv, TCR); + rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV))); + + tmpu4b = rtl_read_dword(rtlpriv, RCR); + rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS | + RCR_APP_ICV | RCR_APP_MIC)); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Current RCR settings(%#x)\n", tmpu4b); + + /* Set to normal mode. */ + rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); + break; + + default: + pr_err("Unknown status check!\n"); + rtstatus = false; + break; + } + +status_check_fail: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "loadfw_status(%d), rtstatus(%x)\n", + loadfw_status, rtstatus); + return rtstatus; +} + +int rtl92s_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rt_firmware *firmware = NULL; + struct fw_hdr *pfwheader; + struct fw_priv *pfw_priv = NULL; + u8 *puc_mappedfile = NULL; + u32 ul_filelength = 0; + u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; + u8 fwstatus = FW_STATUS_INIT; + bool rtstatus = true; + + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) + return 1; + + firmware = (struct rt_firmware *)rtlhal->pfirmware; + firmware->fwstatus = FW_STATUS_INIT; + + puc_mappedfile = firmware->sz_fw_tmpbuffer; + + /* 1. Retrieve FW header. */ + firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; + pfwheader = firmware->pfwheader; + firmware->firmwareversion = byte(pfwheader->version, 0); + firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", + pfwheader->signature, + pfwheader->version, pfwheader->dmem_size, + pfwheader->img_imem_size, pfwheader->img_sram_size); + + /* 2. Retrieve IMEM image. */ + if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > + sizeof(firmware->fw_imem))) { + pr_err("memory for data image is less than IMEM required\n"); + goto fail; + } else { + puc_mappedfile += fwhdr_size; + + memcpy(firmware->fw_imem, puc_mappedfile, + pfwheader->img_imem_size); + firmware->fw_imem_len = pfwheader->img_imem_size; + } + + /* 3. Retriecve EMEM image. */ + if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { + pr_err("memory for data image is less than EMEM required\n"); + goto fail; + } else { + puc_mappedfile += firmware->fw_imem_len; + + memcpy(firmware->fw_emem, puc_mappedfile, + pfwheader->img_sram_size); + firmware->fw_emem_len = pfwheader->img_sram_size; + } + + /* 4. download fw now */ + fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); + while (fwstatus != FW_STATUS_READY) { + /* Image buffer redirection. */ + switch (fwstatus) { + case FW_STATUS_LOAD_IMEM: + puc_mappedfile = firmware->fw_imem; + ul_filelength = firmware->fw_imem_len; + break; + case FW_STATUS_LOAD_EMEM: + puc_mappedfile = firmware->fw_emem; + ul_filelength = firmware->fw_emem_len; + break; + case FW_STATUS_LOAD_DMEM: + /* Partial update the content of header private. */ + pfwheader = firmware->pfwheader; + pfw_priv = &pfwheader->fwpriv; + _rtl92s_firmwareheader_priveupdate(hw, pfw_priv); + puc_mappedfile = (u8 *)(firmware->pfwheader) + + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; + ul_filelength = fwhdr_size - + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; + break; + default: + pr_err("Unexpected Download step!!\n"); + goto fail; + } + + /* <2> Download image file */ + rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile, + ul_filelength); + + if (!rtstatus) { + pr_err("fail!\n"); + goto fail; + } + + /* <3> Check whether load FW process is ready */ + rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); + if (!rtstatus) { + pr_err("rtl8192se: firmware fail!\n"); + goto fail; + } + + fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); + } + + return rtstatus; +fail: + return 0; +} + +static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen, + u32 cmd_num, u32 *pelement_id, u32 *pcmd_len, + u8 **pcmb_buffer, u8 *cmd_start_seq) +{ + u32 totallen = 0, len = 0, tx_desclen = 0; + u32 pre_continueoffset = 0; + u8 *ph2c_buffer; + u8 i = 0; + + do { + /* 8 - Byte alignment */ + len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); + + /* Buffer length is not enough */ + if (h2cbufferlen < totallen + len + tx_desclen) + break; + + /* Clear content */ + ph2c_buffer = skb_put(skb, (u32)len); + memset((ph2c_buffer + totallen + tx_desclen), 0, len); + + /* CMD len */ + le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + + tx_desclen), pcmd_len[i], + GENMASK(15, 0)); + + /* CMD ID */ + le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + + tx_desclen), pelement_id[i], + GENMASK(23, 16)); + + /* CMD Sequence */ + *cmd_start_seq = *cmd_start_seq % 0x80; + le32p_replace_bits((__le32 *)(ph2c_buffer + totallen + + tx_desclen), *cmd_start_seq, + GENMASK(30, 24)); + ++*cmd_start_seq; + + /* Copy memory */ + memcpy((ph2c_buffer + totallen + tx_desclen + + H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]); + + /* CMD continue */ + /* set the continue in prevoius cmd. */ + if (i < cmd_num - 1) + le32p_replace_bits((__le32 *)(ph2c_buffer + + pre_continueoffset), + 1, BIT(31)); + + pre_continueoffset = totallen; + + totallen += len; + } while (++i < cmd_num); + + return totallen; +} + +static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len) +{ + u32 totallen = 0, len = 0, tx_desclen = 0; + u8 i = 0; + + do { + /* 8 - Byte alignment */ + len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); + + /* Buffer length is not enough */ + if (h2cbufferlen < totallen + len + tx_desclen) + break; + + totallen += len; + } while (++i < cmd_num); + + return totallen + tx_desclen; +} + +static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd, + u8 *pcmd_buffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_tcb_desc *cb_desc; + struct sk_buff *skb; + u32 element_id = 0; + u32 cmd_len = 0; + u32 len; + + switch (h2c_cmd) { + case FW_H2C_SETPWRMODE: + element_id = H2C_SETPWRMODE_CMD ; + cmd_len = sizeof(struct h2c_set_pwrmode_parm); + break; + case FW_H2C_JOINBSSRPT: + element_id = H2C_JOINBSSRPT_CMD; + cmd_len = sizeof(struct h2c_joinbss_rpt_parm); + break; + case FW_H2C_WOWLAN_UPDATE_GTK: + element_id = H2C_WOWLAN_UPDATE_GTK_CMD; + cmd_len = sizeof(struct h2c_wpa_two_way_parm); + break; + case FW_H2C_WOWLAN_UPDATE_IV: + element_id = H2C_WOWLAN_UPDATE_IV_CMD; + cmd_len = sizeof(unsigned long long); + break; + case FW_H2C_WOWLAN_OFFLOAD: + element_id = H2C_WOWLAN_FW_OFFLOAD; + cmd_len = sizeof(u8); + break; + default: + break; + } + + len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); + skb = dev_alloc_skb(len); + if (!skb) + return false; + cb_desc = (struct rtl_tcb_desc *)(skb->cb); + cb_desc->queue_index = TXCMD_QUEUE; + cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; + cb_desc->last_inipkt = false; + + _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id, + &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq); + _rtl92s_cmd_send_packet(hw, skb, false); + rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE); + + return true; +} + +void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct h2c_set_pwrmode_parm pwrmode; + u16 max_wakeup_period = 0; + + pwrmode.mode = mode; + pwrmode.flag_low_traffic_en = 0; + pwrmode.flag_lpnav_en = 0; + pwrmode.flag_rf_low_snr_en = 0; + pwrmode.flag_dps_en = 0; + pwrmode.bcn_rx_en = 0; + pwrmode.bcn_to = 0; + le16p_replace_bits((__le16 *)(((u8 *)(&pwrmode) + 8)), + mac->vif->bss_conf.beacon_int, GENMASK(15, 0)); + pwrmode.app_itv = 0; + pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl; + pwrmode.smart_ps = 1; + pwrmode.bcn_pass_period = 10; + + /* Set beacon pass count */ + if (pwrmode.mode == FW_PS_MIN_MODE) + max_wakeup_period = mac->vif->bss_conf.beacon_int; + else if (pwrmode.mode == FW_PS_MAX_MODE) + max_wakeup_period = mac->vif->bss_conf.beacon_int * + mac->vif->bss_conf.dtim_period; + + if (max_wakeup_period >= 500) + pwrmode.bcn_pass_cnt = 1; + else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500)) + pwrmode.bcn_pass_cnt = 2; + else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300)) + pwrmode.bcn_pass_cnt = 3; + else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200)) + pwrmode.bcn_pass_cnt = 5; + else + pwrmode.bcn_pass_cnt = 1; + + _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode); + +} + +void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, + u8 mstatus, u8 ps_qosinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct h2c_joinbss_rpt_parm joinbss_rpt; + + joinbss_rpt.opmode = mstatus; + joinbss_rpt.ps_qos_info = ps_qosinfo; + joinbss_rpt.bssid[0] = mac->bssid[0]; + joinbss_rpt.bssid[1] = mac->bssid[1]; + joinbss_rpt.bssid[2] = mac->bssid[2]; + joinbss_rpt.bssid[3] = mac->bssid[3]; + joinbss_rpt.bssid[4] = mac->bssid[4]; + joinbss_rpt.bssid[5] = mac->bssid[5]; + le16p_replace_bits((__le16 *)(((u8 *)(&joinbss_rpt) + 8)), + mac->vif->bss_conf.beacon_int, GENMASK(15, 0)); + le16p_replace_bits((__le16 *)(((u8 *)(&joinbss_rpt) + 10)), + mac->assoc_id, GENMASK(15, 0)); + + _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt); +} + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h new file mode 100644 index 000000000..99c6f7eef --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h @@ -0,0 +1,350 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_FIRMWARE92S_H__ +#define __REALTEK_FIRMWARE92S_H__ + +#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 +#define RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE 90000 +#define RTL8190_CPU_START_OFFSET 0x80 +/* Firmware Local buffer size. 64k */ +#define MAX_FIRMWARE_CODE_SIZE 0xFF00 + +#define RT_8192S_FIRMWARE_HDR_SIZE 80 +#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32 + +/* support till 64 bit bus width OS */ +#define MAX_DEV_ADDR_SIZE 8 +#define MAX_FIRMWARE_INFORMATION_SIZE 32 +#define MAX_802_11_HEADER_LENGTH (40 + \ + MAX_FIRMWARE_INFORMATION_SIZE) +#define ENCRYPTION_MAX_OVERHEAD 128 +#define MAX_FRAGMENT_COUNT 8 +#define MAX_TRANSMIT_BUFFER_SIZE (1600 + \ + (MAX_802_11_HEADER_LENGTH + \ + ENCRYPTION_MAX_OVERHEAD) *\ + MAX_FRAGMENT_COUNT) + +#define H2C_TX_CMD_HDR_LEN 8 + +/* The following DM control code are for Reg0x364, */ +#define FW_DIG_ENABLE_CTL BIT(0) +#define FW_HIGH_PWR_ENABLE_CTL BIT(1) +#define FW_SS_CTL BIT(2) +#define FW_RA_INIT_CTL BIT(3) +#define FW_RA_BG_CTL BIT(4) +#define FW_RA_N_CTL BIT(5) +#define FW_PWR_TRK_CTL BIT(6) +#define FW_IQK_CTL BIT(7) +#define FW_FA_CTL BIT(8) +#define FW_DRIVER_CTRL_DM_CTL BIT(9) +#define FW_PAPE_CTL_BY_SW_HW BIT(10) +#define FW_DISABLE_ALL_DM 0 +#define FW_PWR_TRK_PARAM_CLR 0x0000ffff +#define FW_RA_PARAM_CLR 0xffff0000 + +enum desc_packet_type { + DESC_PACKET_TYPE_INIT = 0, + DESC_PACKET_TYPE_NORMAL = 1, +}; + +/* 8-bytes alignment required */ +struct fw_priv { + /* --- long word 0 ---- */ + /* 0x12: CE product, 0x92: IT product */ + u8 signature_0; + /* 0x87: CE product, 0x81: IT product */ + u8 signature_1; + /* 0x81: PCI-AP, 01:PCIe, 02: 92S-U, + * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */ + u8 hci_sel; + /* the same value as reigster value */ + u8 chip_version; + /* customer ID low byte */ + u8 customer_id_0; + /* customer ID high byte */ + u8 customer_id_1; + /* 0x11: 1T1R, 0x12: 1T2R, + * 0x92: 1T2R turbo, 0x22: 2T2R */ + u8 rf_config; + /* 4: 4EP, 6: 6EP, 11: 11EP */ + u8 usb_ep_num; + + /* --- long word 1 ---- */ + /* regulatory class bit map 0 */ + u8 regulatory_class_0; + /* regulatory class bit map 1 */ + u8 regulatory_class_1; + /* regulatory class bit map 2 */ + u8 regulatory_class_2; + /* regulatory class bit map 3 */ + u8 regulatory_class_3; + /* 0:SWSI, 1:HWSI, 2:HWPI */ + u8 rfintfs; + u8 def_nettype; + u8 rsvd010; + u8 rsvd011; + + /* --- long word 2 ---- */ + /* 0x00: normal, 0x03: MACLBK, 0x01: PHYLBK */ + u8 lbk_mode; + /* 1: for MP use, 0: for normal + * driver (to be discussed) */ + u8 mp_mode; + u8 rsvd020; + u8 rsvd021; + u8 rsvd022; + u8 rsvd023; + u8 rsvd024; + u8 rsvd025; + + /* --- long word 3 ---- */ + /* QoS enable */ + u8 qos_en; + /* 40MHz BW enable */ + /* 4181 convert AMSDU to AMPDU, 0: disable */ + u8 bw_40mhz_en; + u8 amsdu2ampdu_en; + /* 11n AMPDU enable */ + u8 ampdu_en; + /* FW offloads, 0: driver handles */ + u8 rate_control_offload; + /* FW offloads, 0: driver handles */ + u8 aggregation_offload; + u8 rsvd030; + u8 rsvd031; + + /* --- long word 4 ---- */ + /* 1. FW offloads, 0: driver handles */ + u8 beacon_offload; + /* 2. FW offloads, 0: driver handles */ + u8 mlme_offload; + /* 3. FW offloads, 0: driver handles */ + u8 hwpc_offload; + /* 4. FW offloads, 0: driver handles */ + u8 tcp_checksum_offload; + /* 5. FW offloads, 0: driver handles */ + u8 tcp_offload; + /* 6. FW offloads, 0: driver handles */ + u8 ps_control_offload; + /* 7. FW offloads, 0: driver handles */ + u8 wwlan_offload; + u8 rsvd040; + + /* --- long word 5 ---- */ + /* tcp tx packet length low byte */ + u8 tcp_tx_frame_len_L; + /* tcp tx packet length high byte */ + u8 tcp_tx_frame_len_H; + /* tcp rx packet length low byte */ + u8 tcp_rx_frame_len_L; + /* tcp rx packet length high byte */ + u8 tcp_rx_frame_len_H; + u8 rsvd050; + u8 rsvd051; + u8 rsvd052; + u8 rsvd053; +}; + +/* 8-byte alinment required */ +struct fw_hdr { + + /* --- LONG WORD 0 ---- */ + u16 signature; + /* 0x8000 ~ 0x8FFF for FPGA version, + * 0x0000 ~ 0x7FFF for ASIC version, */ + u16 version; + /* define the size of boot loader */ + u32 dmem_size; + + + /* --- LONG WORD 1 ---- */ + /* define the size of FW in IMEM */ + u32 img_imem_size; + /* define the size of FW in SRAM */ + u32 img_sram_size; + + /* --- LONG WORD 2 ---- */ + /* define the size of DMEM variable */ + u32 fw_priv_size; + u32 rsvd0; + + /* --- LONG WORD 3 ---- */ + u32 rsvd1; + u32 rsvd2; + + struct fw_priv fwpriv; + +} ; + +enum fw_status { + FW_STATUS_INIT = 0, + FW_STATUS_LOAD_IMEM = 1, + FW_STATUS_LOAD_EMEM = 2, + FW_STATUS_LOAD_DMEM = 3, + FW_STATUS_READY = 4, +}; + +struct rt_firmware { + struct fw_hdr *pfwheader; + enum fw_status fwstatus; + u16 firmwareversion; + u8 fw_imem[RTL8190_MAX_FIRMWARE_CODE_SIZE]; + u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE]; + u32 fw_imem_len; + u32 fw_emem_len; + u8 sz_fw_tmpbuffer[RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE]; + u32 sz_fw_tmpbufferlen; + u16 cmdpacket_fragthresold; +}; + +struct h2c_set_pwrmode_parm { + u8 mode; + u8 flag_low_traffic_en; + u8 flag_lpnav_en; + u8 flag_rf_low_snr_en; + /* 1: dps, 0: 32k */ + u8 flag_dps_en; + u8 bcn_rx_en; + u8 bcn_pass_cnt; + /* beacon TO (ms). ¡§=0¡¨ no limit. */ + u8 bcn_to; + u16 bcn_itv; + /* only for VOIP mode. */ + u8 app_itv; + u8 awake_bcn_itvl; + u8 smart_ps; + /* unit: 100 ms */ + u8 bcn_pass_period; +}; + +struct h2c_joinbss_rpt_parm { + u8 opmode; + u8 ps_qos_info; + u8 bssid[6]; + u16 bcnitv; + u16 aid; +} ; + +struct h2c_wpa_ptk { + /* EAPOL-Key Key Confirmation Key (KCK) */ + u8 kck[16]; + /* EAPOL-Key Key Encryption Key (KEK) */ + u8 kek[16]; + /* Temporal Key 1 (TK1) */ + u8 tk1[16]; + union { + /* Temporal Key 2 (TK2) */ + u8 tk2[16]; + struct { + u8 tx_mic_key[8]; + u8 rx_mic_key[8]; + } athu; + } u; +}; + +struct h2c_wpa_two_way_parm { + /* algorithm TKIP or AES */ + u8 pairwise_en_alg; + u8 group_en_alg; + struct h2c_wpa_ptk wpa_ptk_value; +} ; + +enum h2c_cmd { + FW_H2C_SETPWRMODE = 0, + FW_H2C_JOINBSSRPT = 1, + FW_H2C_WOWLAN_UPDATE_GTK = 2, + FW_H2C_WOWLAN_UPDATE_IV = 3, + FW_H2C_WOWLAN_OFFLOAD = 4, +}; + +enum fw_h2c_cmd { + H2C_READ_MACREG_CMD, /*0*/ + H2C_WRITE_MACREG_CMD, + H2C_READBB_CMD, + H2C_WRITEBB_CMD, + H2C_READRF_CMD, + H2C_WRITERF_CMD, /*5*/ + H2C_READ_EEPROM_CMD, + H2C_WRITE_EEPROM_CMD, + H2C_READ_EFUSE_CMD, + H2C_WRITE_EFUSE_CMD, + H2C_READ_CAM_CMD, /*10*/ + H2C_WRITE_CAM_CMD, + H2C_SETBCNITV_CMD, + H2C_SETMBIDCFG_CMD, + H2C_JOINBSS_CMD, + H2C_DISCONNECT_CMD, /*15*/ + H2C_CREATEBSS_CMD, + H2C_SETOPMODE_CMD, + H2C_SITESURVEY_CMD, + H2C_SETAUTH_CMD, + H2C_SETKEY_CMD, /*20*/ + H2C_SETSTAKEY_CMD, + H2C_SETASSOCSTA_CMD, + H2C_DELASSOCSTA_CMD, + H2C_SETSTAPWRSTATE_CMD, + H2C_SETBASICRATE_CMD, /*25*/ + H2C_GETBASICRATE_CMD, + H2C_SETDATARATE_CMD, + H2C_GETDATARATE_CMD, + H2C_SETPHYINFO_CMD, + H2C_GETPHYINFO_CMD, /*30*/ + H2C_SETPHY_CMD, + H2C_GETPHY_CMD, + H2C_READRSSI_CMD, + H2C_READGAIN_CMD, + H2C_SETATIM_CMD, /*35*/ + H2C_SETPWRMODE_CMD, + H2C_JOINBSSRPT_CMD, + H2C_SETRATABLE_CMD, + H2C_GETRATABLE_CMD, + H2C_GETCCXREPORT_CMD, /*40*/ + H2C_GETDTMREPORT_CMD, + H2C_GETTXRATESTATICS_CMD, + H2C_SETUSBSUSPEND_CMD, + H2C_SETH2CLBK_CMD, + H2C_TMP1, /*45*/ + H2C_WOWLAN_UPDATE_GTK_CMD, + H2C_WOWLAN_FW_OFFLOAD, + H2C_TMP2, + H2C_TMP3, + H2C_WOWLAN_UPDATE_IV_CMD, /*50*/ + H2C_TMP4, +}; + +/* The following macros are used for FW + * CMD map and parameter updated. */ +#define FW_CMD_IO_CLR(rtlpriv, _bit) \ + do { \ + udelay(1000); \ + rtlpriv->rtlhal.fwcmd_iomap &= (~_bit); \ + } while (0) + +#define FW_CMD_IO_UPDATE(rtlpriv, _val) \ + rtlpriv->rtlhal.fwcmd_iomap = _val; + +#define FW_CMD_IO_SET(rtlpriv, _val) \ + do { \ + rtl_write_word(rtlpriv, LBUS_MON_ADDR, (u16)_val); \ + FW_CMD_IO_UPDATE(rtlpriv, _val); \ + } while (0) + +#define FW_CMD_PARA_SET(rtlpriv, _val) \ + do { \ + rtl_write_dword(rtlpriv, LBUS_ADDR_MASK, _val); \ + rtlpriv->rtlhal.fwcmd_ioparam = _val; \ + } while (0) + +#define FW_CMD_IO_QUERY(rtlpriv) \ + (u16)(rtlpriv->rtlhal.fwcmd_iomap) +#define FW_CMD_IO_PARA_QUERY(rtlpriv) \ + ((u32)(rtlpriv->rtlhal.fwcmd_ioparam)) + +int rtl92s_download_fw(struct ieee80211_hw *hw); +void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, + u8 mstatus, u8 ps_qosinfo); + +#endif + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c new file mode 100644 index 000000000..e5775b94f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -0,0 +1,2512 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "hw.h" + +void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: { + *((u32 *) (val)) = rtlpci->receive_config; + break; + } + case HW_VAR_RF_STATE: { + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + } + case HW_VAR_FW_PSMODE_STATUS: { + *((bool *) (val)) = ppsc->fw_current_inpsmode; + break; + } + case HW_VAR_CORRECT_TSF: { + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, TSFR); + + *((u64 *) (val)) = tsf; + + break; + } + case HW_VAR_MRC: { + *((bool *)(val)) = rtlpriv->dm.current_mrc_switch; + break; + } + case HAL_DEF_WOWLAN: + break; + default: + pr_err("switch case %#x not processed\n", variable); + break; + } +} + +void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]); + rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]); + break; + } + case HW_VAR_BASIC_RATE:{ + u16 rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + + if (rtlhal->version == VERSION_8192S_ACUT) + rate_cfg = rate_cfg & 0x150; + else + rate_cfg = rate_cfg & 0x15f; + + rate_cfg |= 0x01; + + rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, RRSR + 1, + (rate_cfg >> 8) & 0xff); + + while (rate_cfg > 0x1) { + rate_cfg = (rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index); + + break; + } + case HW_VAR_BSSID:{ + rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]); + rtl_write_word(rtlpriv, BSSIDR + 4, + ((u16 *)(val + 4))[0]); + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]); + rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (&e_aci)); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool) (*val); + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + + rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *val; + if (min_spacing_to_set <= 7) { + if (rtlpriv->sec.pairwise_enc_algorithm == + NO_ENCRYPTION) + sec_min_space = 0; + else + sec_min_space = 1; + + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + if (min_spacing_to_set > 5) + min_spacing_to_set = 5; + + mac->min_space_cfg = + ((mac->min_space_cfg & 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *val; + mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 factor_toset; + u8 regtoset; + u8 factorlevel[18] = { + 2, 4, 4, 7, 7, 13, 13, + 13, 2, 7, 7, 13, 13, + 15, 15, 15, 15, 0}; + u8 index = 0; + + factor_toset = *val; + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 17; index++) { + if (factorlevel[index] > factor_toset) + factorlevel[index] = + factor_toset; + } + + for (index = 0; index < 8; index++) { + regtoset = ((factorlevel[index * 2]) | + (factorlevel[index * + 2 + 1] << 4)); + rtl_write_byte(rtlpriv, + AGGLEN_LMT_L + index, + regtoset); + } + + regtoset = ((factorlevel[16]) | + (factorlevel[17] << 4)); + rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *val; + rtl92s_dm_init_edca_turbo(hw); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + &e_aci); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *val; + union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( + mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, ACMHWCTRL); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? + 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + pr_err("switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); + rtl_write_byte(rtlpriv, ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = val[0]; + + rtl_write_word(rtlpriv, RETRY_LIMIT, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: { + break; + } + case HW_VAR_EFUSE_BYTES: { + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + } + case HW_VAR_EFUSE_USAGE: { + rtlefuse->efuse_usedpercentage = *val; + break; + } + case HW_VAR_IO_CMD: { + break; + } + case HW_VAR_WPA_CONFIG: { + rtl_write_byte(rtlpriv, REG_SECR, *val); + break; + } + case HW_VAR_SET_RPWM:{ + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + break; + } + case HW_VAR_FW_PSMODE_STATUS: { + ppsc->fw_current_inpsmode = *((bool *) val); + break; + } + case HW_VAR_H2C_FW_JOINBSSRPT:{ + break; + } + case HW_VAR_AID:{ + break; + } + case HW_VAR_CORRECT_TSF:{ + break; + } + case HW_VAR_MRC: { + bool bmrc_toset = *((bool *)val); + u8 u1bdata = 0; + + if (bmrc_toset) { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x33); + u1bdata = (u8)rtl_get_bbreg(hw, + ROFDM1_TRXPATHENABLE, + MASKBYTE0); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, + MASKBYTE0, + ((u1bdata & 0xf0) | 0x03)); + u1bdata = (u8)rtl_get_bbreg(hw, + ROFDM0_TRXPATHENABLE, + MASKBYTE1); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE1, + (u1bdata | 0x04)); + + /* Update current settings. */ + rtlpriv->dm.current_mrc_switch = bmrc_toset; + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x13); + u1bdata = (u8)rtl_get_bbreg(hw, + ROFDM1_TRXPATHENABLE, + MASKBYTE0); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, + MASKBYTE0, + ((u1bdata & 0xf0) | 0x01)); + u1bdata = (u8)rtl_get_bbreg(hw, + ROFDM0_TRXPATHENABLE, + MASKBYTE1); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE1, (u1bdata & 0xfb)); + + /* Update current settings. */ + rtlpriv->dm.current_mrc_switch = bmrc_toset; + } + + break; + } + case HW_VAR_FW_LPS_ACTION: { + bool enter_fwlps = *((bool *)val); + u8 rpwm_val, fw_pwrmode; + bool fw_current_inps; + + if (enter_fwlps) { + rpwm_val = 0x02; /* RF off */ + fw_current_inps = true; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &ppsc->fwctrl_psmode); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + &rpwm_val); + } else { + rpwm_val = 0x0C; /* RF on */ + fw_pwrmode = FW_PS_ACTIVE_MODE; + fw_current_inps = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + &rpwm_val); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + &fw_pwrmode); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } + break; } + default: + pr_err("switch case %#x not processed\n", variable); + break; + } + +} + +void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value = 0x0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); + +} + +static u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 waitcount = 100; + bool bresult = false; + u8 tmpvalue; + + rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); + + /* Wait the MAC synchronized. */ + udelay(400); + + /* Check if it is set ready. */ + tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); + bresult = ((tmpvalue & BIT(7)) == (data & BIT(7))); + + if (!(data & (BIT(6) | BIT(7)))) { + waitcount = 100; + tmpvalue = 0; + + while (1) { + waitcount--; + + tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); + if ((tmpvalue & BIT(6))) + break; + + pr_err("wait for BIT(6) return value %x\n", tmpvalue); + if (waitcount == 0) + break; + + udelay(10); + } + + if (waitcount == 0) + bresult = false; + else + bresult = true; + } + + return bresult; +} + +void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1tmp; + + /* The following config GPIO function */ + rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); + u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); + + /* config GPIO3 to input */ + u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; + rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); + +} + +static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1tmp; + u8 retval = ERFON; + + /* The following config GPIO function */ + rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); + u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); + + /* config GPIO3 to input */ + u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; + rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); + + /* On some of the platform, driver cannot read correct + * value without delay between Write_GPIO_SEL and Read_GPIO_IN */ + mdelay(10); + + /* check GPIO3 */ + u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE); + retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; + + return retval; +} + +static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + u8 i; + u8 tmpu1b; + u16 tmpu2b; + u8 pollingcnt = 20; + + if (rtlpci->first_init) { + /* Reset PCIE Digital */ + tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmpu1b &= 0xFE; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); + udelay(1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0)); + } + + /* Switch to SW IO control */ + tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); + if (tmpu1b & BIT(7)) { + tmpu1b &= ~(BIT(6) | BIT(7)); + + /* Set failed, return to prevent hang. */ + if (!_rtl92se_halset_sysclk(hw, tmpu1b)) + return; + } + + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); + udelay(50); + rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); + udelay(50); + + /* Clear FW RPWM for FW control LPS.*/ + rtl_write_byte(rtlpriv, RPWM, 0x0); + + /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */ + tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmpu1b &= 0x73; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); + /* wait for BIT 10/11/15 to pull high automatically!! */ + mdelay(1); + + rtl_write_byte(rtlpriv, CMDR, 0); + rtl_write_byte(rtlpriv, TCR, 0); + + /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ + tmpu1b = rtl_read_byte(rtlpriv, 0x562); + tmpu1b |= 0x08; + rtl_write_byte(rtlpriv, 0x562, tmpu1b); + tmpu1b &= ~(BIT(3)); + rtl_write_byte(rtlpriv, 0x562, tmpu1b); + + /* Enable AFE clock source */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); + /* Delay 1.5ms */ + mdelay(2); + tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); + + /* Enable AFE Macro Block's Bandgap */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); + rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); + mdelay(1); + + /* Enable AFE Mbias */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); + rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); + mdelay(1); + + /* Enable LDOA15 block */ + tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); + rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); + + /* Set Digital Vdd to Retention isolation Path. */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); + rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11))); + + /* For warm reboot NIC disappera bug. */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13))); + + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68); + + /* Enable AFE PLL Macro Block */ + /* We need to delay 100u before enabling PLL. */ + udelay(200); + tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); + + /* for divider reset */ + udelay(100); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | + BIT(4) | BIT(6))); + udelay(10); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); + udelay(10); + + /* Enable MAC 80MHZ clock */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); + mdelay(1); + + /* Release isolation AFE PLL & MD */ + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6); + + /* Enable MAC clock */ + tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); + rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); + + /* Enable Core digital and enable IOREG R/W */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11))); + + tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7))); + + /* enable REG_EN */ + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); + + /* Switch the control path. */ + tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); + rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); + + tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); + tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); + if (!_rtl92se_halset_sysclk(hw, tmpu1b)) + return; /* Set failed, return to prevent hang. */ + + rtl_write_word(rtlpriv, CMDR, 0x07FC); + + /* MH We must enable the section of code to prevent load IMEM fail. */ + /* Load MAC register from WMAc temporarily We simulate macreg. */ + /* txt HW will provide MAC txt later */ + rtl_write_byte(rtlpriv, 0x6, 0x30); + rtl_write_byte(rtlpriv, 0x49, 0xf0); + + rtl_write_byte(rtlpriv, 0x4b, 0x81); + + rtl_write_byte(rtlpriv, 0xb5, 0x21); + + rtl_write_byte(rtlpriv, 0xdc, 0xff); + rtl_write_byte(rtlpriv, 0xdd, 0xff); + rtl_write_byte(rtlpriv, 0xde, 0xff); + rtl_write_byte(rtlpriv, 0xdf, 0xff); + + rtl_write_byte(rtlpriv, 0x11a, 0x00); + rtl_write_byte(rtlpriv, 0x11b, 0x00); + + for (i = 0; i < 32; i++) + rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b); + + rtl_write_byte(rtlpriv, 0x236, 0xff); + + rtl_write_byte(rtlpriv, 0x503, 0x22); + + if (ppsc->support_aspm && !ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x560, 0x40); + else + rtl_write_byte(rtlpriv, 0x560, 0x00); + + rtl_write_byte(rtlpriv, DBG_PORT, 0x91); + + /* Set RX Desc Address */ + rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma); + rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma); + + /* Set TX Desc Address */ + rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma); + rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma); + rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma); + rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma); + rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma); + rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma); + rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma); + rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma); + rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma); + + rtl_write_word(rtlpriv, CMDR, 0x37FC); + + /* To make sure that TxDMA can ready to download FW. */ + /* We should reset TxDMA if IMEM RPT was not ready. */ + do { + tmpu1b = rtl_read_byte(rtlpriv, TCR); + if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE) + break; + + udelay(5); + } while (pollingcnt--); + + if (pollingcnt <= 0) { + pr_err("Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", + tmpu1b); + tmpu1b = rtl_read_byte(rtlpriv, CMDR); + rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); + udelay(2); + /* Reset TxDMA */ + rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN); + } + + /* After MACIO reset,we must refresh LED state. */ + if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) || + (ppsc->rfoff_reason == 0)) { + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + enum rf_pwrstate rfpwr_state_toset; + rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw); + + if (rfpwr_state_toset == ERFON) + rtl92se_sw_led_on(hw, pin0); + } +} + +static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 i; + u16 tmpu2b; + + /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */ + + /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */ + /* Turn on 0x40 Command register */ + rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN | + SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN | + RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN)); + + /* Set TCR TX DMA pre 2 FULL enable bit */ + rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) | + TXDMAPRE2FULL); + + /* Set RCR */ + rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); + + /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */ + + /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */ + /* Set CCK/OFDM SIFS */ + /* CCK SIFS shall always be 10us. */ + rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a); + rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010); + + /* Set AckTimeout */ + rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40); + + /* Beacon related */ + rtl_write_word(rtlpriv, BCN_INTERVAL, 100); + rtl_write_word(rtlpriv, ATIMWND, 2); + + /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */ + /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */ + /* Firmware allocate now, associate with FW internal setting.!!! */ + + /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */ + /* 5.3 Set driver info, we only accept PHY status now. */ + /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */ + rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6)); + + /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */ + /* Set RRSR to all legacy rate and HT rate + * CCK rate is supported by default. + * CCK rate will be filtered out only when associated + * AP does not support it. + * Only enable ACK rate to OFDM 24M + * Disable RRSR for CCK rate in A-Cut */ + + if (rtlhal->version == VERSION_8192S_ACUT) + rtl_write_byte(rtlpriv, RRSR, 0xf0); + else if (rtlhal->version == VERSION_8192S_BCUT) + rtl_write_byte(rtlpriv, RRSR, 0xff); + rtl_write_byte(rtlpriv, RRSR + 1, 0x01); + rtl_write_byte(rtlpriv, RRSR + 2, 0x00); + + /* A-Cut IC do not support CCK rate. We forbid ARFR to */ + /* fallback to CCK rate */ + for (i = 0; i < 8; i++) { + /*Disable RRSR for CCK rate in A-Cut */ + if (rtlhal->version == VERSION_8192S_ACUT) + rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0); + } + + /* Different rate use different AMPDU size */ + /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */ + rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f); + /* MCS0/1/2/3 use max AMPDU size 4*2=8K */ + rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442); + /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */ + rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7); + /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */ + rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772); + /* MCS12/13/14/15 use max AMPDU size 15*2=30K */ + rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd); + + /* Set Data / Response auto rate fallack retry count */ + rtl_write_dword(rtlpriv, DARFRC, 0x04010000); + rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605); + rtl_write_dword(rtlpriv, RARFRC, 0x04010000); + rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605); + + /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */ + /* Set all rate to support SG */ + rtl_write_word(rtlpriv, SG_RATE, 0xFFFF); + + /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */ + /* Set NAV protection length */ + rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080); + /* CF-END Threshold */ + rtl_write_byte(rtlpriv, CFEND_TH, 0xFF); + /* Set AMPDU minimum space */ + rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07); + /* Set TXOP stall control for several queue/HI/BCN/MGT/ */ + rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00); + + /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */ + /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */ + /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */ + /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */ + /* 13. Test mode and Debug Control Register (Offset: 0x0310 - 0x034F) */ + + /* 14. Set driver info, we only accept PHY status now. */ + rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4); + + /* 15. For EEPROM R/W Workaround */ + /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */ + tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13)); + tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8))); + + /* 17. For EFUSE */ + /* We may R/W EFUSE in EEPROM mode */ + if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { + u8 tempval; + + tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1); + tempval &= 0xFE; + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval); + + /* Change Program timing */ + rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); + +} + +static void _rtl92se_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 reg_bw_opmode = 0; + u32 reg_rrsr = 0; + u8 regtmp = 0; + + reg_bw_opmode = BW_OPMODE_20MHZ; + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); + reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp; + rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr); + rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); + + /* Set Retry Limit here */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + (u8 *)(&rtlpci->shortretry_limit)); + + rtl_write_byte(rtlpriv, MLT, 0x8f); + + /* For Min Spacing configuration. */ + switch (rtlphy->rf_type) { + case RF_1T2R: + case RF_1T1R: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); + break; + case RF_2T2R: + case RF_2T2R_GREEN: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); + break; + } + rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg); +} + +int rtl92se_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 tmp_byte = 0; + unsigned long flags; + bool rtstatus = true; + u8 tmp_u1b; + int err = false; + u8 i; + int wdcapra_add[] = { + EDCAPARA_BE, EDCAPARA_BK, + EDCAPARA_VI, EDCAPARA_VO}; + u8 secr_value = 0x0; + + rtlpci->being_init_adapter = true; + + /* As this function can take a very long time (up to 350 ms) + * and can be called with irqs disabled, reenable the irqs + * to let the other devices continue being serviced. + * + * It is safe doing so since our own interrupts will only be enabled + * in a subsequent step. + */ + local_save_flags(flags); + local_irq_enable(); + + rtlpriv->intf_ops->disable_aspm(hw); + + /* 1. MAC Initialize */ + /* Before FW download, we have to set some MAC register */ + _rtl92se_macconfig_before_fwdownload(hw); + + rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv, + PMC_FSM) >> 16) & 0xF); + + rtl8192se_gpiobit3_cfg_inputmode(hw); + + /* 2. download firmware */ + rtstatus = rtl92s_download_fw(hw); + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); + err = 1; + goto exit; + } + + /* After FW download, we have to reset MAC register */ + _rtl92se_macconfig_after_fwdownload(hw); + + /*Retrieve default FW Cmd IO map. */ + rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR); + rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK); + + /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ + if (!rtl92s_phy_mac_config(hw)) { + pr_err("MAC Config failed\n"); + err = rtstatus; + goto exit; + } + + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 + */ + rtlpci->receive_config = rtl_read_dword(rtlpriv, RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); + + /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */ + /* We must set flag avoid BB/RF config period later!! */ + rtl_write_dword(rtlpriv, CMDR, 0x37FC); + + /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ + if (!rtl92s_phy_bb_config(hw)) { + pr_err("BB Config failed\n"); + err = rtstatus; + goto exit; + } + + /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */ + /* Before initalizing RF. We can not use FW to do RF-R/W. */ + + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + + /* Before RF-R/W we must execute the IO from Scott's suggestion. */ + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB); + if (rtlhal->version == VERSION_8192S_ACUT) + rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07); + else + rtl_write_byte(rtlpriv, RF_CTRL, 0x07); + + if (!rtl92s_phy_rf_config(hw)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); + err = rtstatus; + goto exit; + } + + /* After read predefined TXT, we must set BB/MAC/RF + * register as our requirement */ + + rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw, + (enum radio_path)0, + RF_CHNLBW, + RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw, + (enum radio_path)1, + RF_CHNLBW, + RFREG_OFFSET_MASK); + + /*---- Set CCK and OFDM Block "ON"----*/ + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + /*3 Set Hardware(Do nothing now) */ + _rtl92se_hw_configure(hw); + + /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ + /* TX power index for different rate set. */ + /* Get original hw reg values */ + rtl92s_phy_get_hw_reg_originalvalue(hw); + /* Write correct tx power index */ + rtl92s_phy_set_txpower(hw, rtlphy->current_channel); + + /* We must set MAC address after firmware download. */ + for (i = 0; i < 6; i++) + rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); + + /* EEPROM R/W workaround */ + tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG); + rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3))); + + rtl_write_byte(rtlpriv, 0x4d, 0x0); + + if (hal_get_firmwareversion(rtlpriv) >= 0x49) { + tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4)); + tmp_byte = tmp_byte | BIT(5); + rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte); + rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF); + } + + /* We enable high power and RA related mechanism after NIC + * initialized. */ + if (hal_get_firmwareversion(rtlpriv) >= 0x35) { + /* Fw v.53 and later. */ + rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT); + } else if (hal_get_firmwareversion(rtlpriv) == 0x34) { + /* Fw v.52. */ + rtl_write_dword(rtlpriv, WFM5, FW_RA_INIT); + rtl92s_phy_chk_fwcmd_iodone(hw); + } else { + /* Compatible earlier FW version. */ + rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); + rtl92s_phy_chk_fwcmd_iodone(hw); + rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); + rtl92s_phy_chk_fwcmd_iodone(hw); + rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); + rtl92s_phy_chk_fwcmd_iodone(hw); + } + + /* Add to prevent ASPM bug. */ + /* Always enable hst and NIC clock request. */ + rtl92s_phy_switch_ephy_parameter(hw); + + /* Security related + * 1. Clear all H/W keys. + * 2. Enable H/W encryption/decryption. */ + rtl_cam_reset_all_entry(hw); + secr_value |= SCR_TXENCENABLE; + secr_value |= SCR_RXENCENABLE; + secr_value |= SCR_NOSKMC; + rtl_write_byte(rtlpriv, REG_SECR, secr_value); + + for (i = 0; i < 4; i++) + rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322); + + if (rtlphy->rf_type == RF_1T2R) { + bool mrc2set = true; + /* Turn on B-Path */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set); + } + + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); + rtl92s_dm_init(hw); +exit: + local_irq_restore(flags); + rtlpci->being_init_adapter = false; + return err; +} + +void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr) +{ + /* This is a stub. */ +} + +void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } else if (!check_bssid) { + reg_rcr &= (~RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } + +} + +static int _rtl92se_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + u32 temp; + bt_msr &= ~MSR_LINK_MASK; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not supported!\n", type); + return 1; + + } + + if (type != NL80211_IFTYPE_AP && + rtlpriv->mac80211.link_state < MAC80211_LINKED) + bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK; + rtl_write_byte(rtlpriv, MSR, bt_msr); + + temp = rtl_read_dword(rtlpriv, TCR); + rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8))); + rtl_write_dword(rtlpriv, TCR, temp | BIT(8)); + + + return 0; +} + +/* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */ +int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92se_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92se_set_check_bssid(hw, true); + } else { + rtl92se_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ +void rtl92se_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl92s_dm_init_edca_turbo(hw); + + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f); + break; + case AC0_BE: + /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */ + break; + case AC2_VI: + rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8192se: invalid aci: %d !\n", aci); + break; + } +} + +void rtl92se_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); + /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ + rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); + rtlpci->irq_enabled = true; +} + +void rtl92se_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv; + struct rtl_pci *rtlpci; + + rtlpriv = rtl_priv(hw); + /* if firmware not available, no interrupts */ + if (!rtlpriv || !rtlpriv->max_fw_size) + return; + rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + rtl_write_dword(rtlpriv, INTA_MASK, 0); + rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); + rtlpci->irq_enabled = false; +} + +static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 waitcnt = 100; + bool result = false; + u8 tmp; + + rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); + + /* Wait the MAC synchronized. */ + udelay(400); + + /* Check if it is set ready. */ + tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); + result = ((tmp & BIT(7)) == (data & BIT(7))); + + if (!(data & (BIT(6) | BIT(7)))) { + waitcnt = 100; + tmp = 0; + + while (1) { + waitcnt--; + tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); + + if ((tmp & BIT(6))) + break; + + pr_err("wait for BIT(6) return value %x\n", tmp); + + if (waitcnt == 0) + break; + udelay(10); + } + + if (waitcnt == 0) + result = false; + else + result = true; + } + + return result; +} + +static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 u1btmp; + + if (rtlhal->driver_is_goingto_unload) + rtl_write_byte(rtlpriv, 0x560, 0x0); + + /* Power save for BB/RF */ + u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); + u1btmp |= BIT(0); + rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); + rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); + rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); + rtl_write_word(rtlpriv, CMDR, 0x57FC); + udelay(100); + rtl_write_word(rtlpriv, CMDR, 0x77FC); + rtl_write_byte(rtlpriv, PHY_CCA, 0x0); + udelay(10); + rtl_write_word(rtlpriv, CMDR, 0x37FC); + udelay(10); + rtl_write_word(rtlpriv, CMDR, 0x77FC); + udelay(10); + rtl_write_word(rtlpriv, CMDR, 0x57FC); + rtl_write_word(rtlpriv, CMDR, 0x0000); + + if (rtlhal->driver_is_goingto_unload) { + u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1)); + u1btmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp); + } + + u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); + + /* Add description. After switch control path. register + * after page1 will be invisible. We can not do any IO + * for register>0x40. After resume&MACIO reset, we need + * to remember previous reg content. */ + if (u1btmp & BIT(7)) { + u1btmp &= ~(BIT(6) | BIT(7)); + if (!_rtl92s_set_sysclk(hw, u1btmp)) { + pr_err("Switch ctrl path fail\n"); + return; + } + } + + /* Power save for MAC */ + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS && + !rtlhal->driver_is_goingto_unload) { + /* enable LED function */ + rtl_write_byte(rtlpriv, 0x03, 0xF9); + /* SW/HW radio off or halt adapter!! For example S3/S4 */ + } else { + /* LED function disable. Power range is about 8mA now. */ + /* if write 0xF1 disconnect_pci power + * ifconfig wlan0 down power are both high 35:70 */ + /* if write oxF9 disconnect_pci power + * ifconfig wlan0 down power are both low 12:45*/ + rtl_write_byte(rtlpriv, 0x03, 0xF9); + } + + rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00); + rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + +} + +static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpci->up_first_time) + return; + + if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS) + rtl92se_sw_led_on(hw, pin0); + else + rtl92se_sw_led_off(hw, pin0); +} + + +static void _rtl92se_power_domain_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 tmpu2b; + u8 tmpu1b; + + rtlpriv->psc.pwrdomain_protect = true; + + tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); + if (tmpu1b & BIT(7)) { + tmpu1b &= ~(BIT(6) | BIT(7)); + if (!_rtl92s_set_sysclk(hw, tmpu1b)) { + rtlpriv->psc.pwrdomain_protect = false; + return; + } + } + + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); + rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); + + /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */ + tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + /* If IPS we need to turn LED on. So we not + * disable BIT 3/7 of reg3. */ + if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW)) + tmpu1b &= 0xFB; + else + tmpu1b &= 0x73; + + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); + /* wait for BIT 10/11/15 to pull high automatically!! */ + mdelay(1); + + rtl_write_byte(rtlpriv, CMDR, 0); + rtl_write_byte(rtlpriv, TCR, 0); + + /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ + tmpu1b = rtl_read_byte(rtlpriv, 0x562); + tmpu1b |= 0x08; + rtl_write_byte(rtlpriv, 0x562, tmpu1b); + tmpu1b &= ~(BIT(3)); + rtl_write_byte(rtlpriv, 0x562, tmpu1b); + + /* Enable AFE clock source */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); + /* Delay 1.5ms */ + udelay(1500); + tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); + rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); + + /* Enable AFE Macro Block's Bandgap */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); + rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); + mdelay(1); + + /* Enable AFE Mbias */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); + rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); + mdelay(1); + + /* Enable LDOA15 block */ + tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); + rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); + + /* Set Digital Vdd to Retention isolation Path. */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); + rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11))); + + + /* For warm reboot NIC disappera bug. */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13))); + + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68); + + /* Enable AFE PLL Macro Block */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); + /* Enable MAC 80MHZ clock */ + tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); + rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); + mdelay(1); + + /* Release isolation AFE PLL & MD */ + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6); + + /* Enable MAC clock */ + tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); + rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); + + /* Enable Core digital and enable IOREG R/W */ + tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11))); + /* enable REG_EN */ + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); + + /* Switch the control path. */ + tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); + rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); + + tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); + tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); + if (!_rtl92s_set_sysclk(hw, tmpu1b)) { + rtlpriv->psc.pwrdomain_protect = false; + return; + } + + rtl_write_word(rtlpriv, CMDR, 0x37FC); + + /* After MACIO reset,we must refresh LED state. */ + _rtl92se_gen_refreshledstate(hw); + + rtlpriv->psc.pwrdomain_protect = false; +} + +void rtl92se_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum nl80211_iftype opmode; + u8 wait = 30; + + rtlpriv->intf_ops->enable_aspm(hw); + + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + /* we should chnge GPIO to input mode + * this will drop away current about 25mA*/ + rtl8192se_gpiobit3_cfg_inputmode(hw); + + /* this is very important for ips power save */ + while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) { + if (rtlpriv->psc.pwrdomain_protect) + mdelay(20); + else + break; + } + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92se_set_media_status(hw, opmode); + + _rtl92s_phy_set_rfhalt(hw); + udelay(100); +} + +void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); + + intvec->intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, ISR + 4, intvec->intb); +} + +void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 atim_window = 2; + + /* ATIM Window (in unit of TU). */ + rtl_write_word(rtlpriv, ATIMWND, atim_window); + + /* Beacon interval (in unit of TU). */ + rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval); + + /* DrvErlyInt (in unit of TU). (Time to send + * interrupt to notify driver to change + * beacon content) */ + rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4); + + /* BcnDMATIM(in unit of us). Indicates the + * time before TBTT to perform beacon queue DMA */ + rtl_write_word(rtlpriv, BCN_DMATIME, 256); + + /* Force beacon frame transmission even + * after receiving beacon frame from + * other ad hoc STA */ + rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100); + + /*for beacon changed */ + rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval); +} + +void rtl92se_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + /* Beacon interval (in unit of TU). */ + rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval); + /* 2008.10.24 added by tynli for beacon changed. */ + rtl92s_phy_set_beacon_hwreg(hw, bcn_interval); +} + +void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + + rtl92se_disable_interrupt(hw); + rtl92se_enable_interrupt(hw); +} + +static void _rtl8192se_get_ic_inferiority(struct ieee80211_hw *hw) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 efuse_id; + + rtlhal->ic_class = IC_INFERIORITY_A; + + /* Only retrieving while using EFUSE. */ + if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) && + !rtlefuse->autoload_failflag) { + efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET); + + if (efuse_id == 0xfe) + rtlhal->ic_class = IC_INFERIORITY_B; + } +} + +static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev; + u16 i, usvalue; + u16 eeprom_id; + u8 tempval; + u8 hwinfo[HWSET_MAX_SIZE_92S]; + u8 rf_path, index; + + switch (rtlefuse->epromtype) { + case EEPROM_BOOT_EFUSE: + rtl_efuse_shadow_map_update(hw); + break; + + case EEPROM_93C46: + pr_err("RTL819X Not boot from eeprom, check it !!\n"); + return; + + default: + dev_warn(dev, "no efuse data\n"); + return; + } + + memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + HWSET_MAX_SIZE_92S); + + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", + hwinfo, HWSET_MAX_SIZE_92S); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8190_EEPROM_ID) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtlefuse->autoload_failflag = true; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag) + return; + + _rtl8192se_get_ic_inferiority(hw); + + /* Read IC Version && Channel Plan */ + /* VID, DID SE 0xA-D */ + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; + rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; + rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROMId = 0x%4x\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + + for (i = 0; i < 6; i++) + rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + + /* Get Tx Power Level by Channel */ + /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ + /* 92S suupport RF A & B */ + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + /* Read CCK RF A & B Tx power */ + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i]; + + /* Read OFDM RF A & B Tx power for 1T */ + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; + + /* Read OFDM RF A & B Tx power for 2T */ + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] + = hwinfo[EEPROM_TXPOWERBASE + 12 + + rf_path * 3 + i]; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eprom_chnl_txpwr_ht40_2sdf + [rf_path][i]); + + for (rf_path = 0; rf_path < 2; rf_path++) { + + /* Assign dedicated channel tx power */ + for (i = 0; i < 14; i++) { + /* channel 1~3 use the same Tx Power Level. */ + if (i < 3) + index = 0; + /* Channel 4-8 */ + else if (i < 8) + index = 1; + /* Channel 9-14 */ + else + index = 2; + + /* Record A & B CCK /OFDM - 1T/2T Channel area + * tx power */ + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][index]; + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + rtlefuse->eprom_chnl_txpwr_ht40_2sdf + [rf_path][index]; + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + /* Read Power diff limit. */ + rtlefuse->eeprom_pwrgroup[rf_path][i] = + hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i]; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + /* Fill Pwr group */ + for (i = 0; i < 14; i++) { + /* Chanel 1-3 */ + if (i < 3) + index = 0; + /* Channel 4-8 */ + else if (i < 8) + index = 1; + /* Channel 9-13 */ + else + index = 2; + + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrgroup[rf_path][index] & + 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrgroup[rf_path][index] & + 0xf0) >> 4); + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); + } + } + + for (i = 0; i < 14; i++) { + /* Read tx power difference between HT OFDM 20/40 MHZ */ + /* channel 1-3 */ + if (i < 3) + index = 0; + /* Channel 4-8 */ + else if (i < 8) + index = 1; + /* Channel 9-14 */ + else + index = 2; + + tempval = hwinfo[EEPROM_TX_PWR_HT20_DIFF + index] & 0xff; + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + /* Read OFDM<->HT tx power diff */ + /* Channel 1-3 */ + if (i < 3) + index = 0; + /* Channel 4-8 */ + else if (i < 8) + index = 0x11; + /* Channel 9-14 */ + else + index = 1; + + tempval = hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index] & 0xff; + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = + (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + tempval = hwinfo[TX_PWR_SAFETY_CHK]; + rtlefuse->txpwr_safetyflag = (tempval & 0x01); + } + + rtlefuse->eeprom_regulatory = 0; + if (rtlefuse->eeprom_version >= 2) { + /* BIT(0)~2 */ + if (rtlefuse->eeprom_version >= 4) + rtlefuse->eeprom_regulatory = + (hwinfo[EEPROM_REGULATORY] & 0x7); + else /* BIT(0) */ + rtlefuse->eeprom_regulatory = + (hwinfo[EEPROM_REGULATORY] & 0x1); + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); + + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); + + /* Read RF-indication and Tx Power gain + * index diff of legacy to HT OFDM rate. */ + tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff; + rtlefuse->eeprom_txpowerdiff = tempval; + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); + + /* Get TSSI value for each path. */ + usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); + usvalue = hwinfo[EEPROM_TSSI_B]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); + + /* Read antenna tx power offset of B/C/D to A from EEPROM */ + /* and read ThermalMeter from EEPROM */ + tempval = hwinfo[EEPROM_THERMALMETER]; + rtlefuse->eeprom_thermalmeter = tempval; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + + /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ + rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); + rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; + + /* Read CrystalCap from EEPROM */ + tempval = hwinfo[EEPROM_CRYSTALCAP] >> 4; + rtlefuse->eeprom_crystalcap = tempval; + /* CrystalCap, BIT(12)~15 */ + rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; + + /* Read IC Version && Channel Plan */ + /* Version ID, Channel plan */ + rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->txpwr_fromeprom = true; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); + + /* Read Customer ID or Board Type!!! */ + tempval = hwinfo[EEPROM_BOARDTYPE]; + /* Change RF type definition */ + if (tempval == 0) + rtlphy->rf_type = RF_2T2R; + else if (tempval == 1) + rtlphy->rf_type = RF_1T2R; + else if (tempval == 2) + rtlphy->rf_type = RF_1T2R; + else if (tempval == 3) + rtlphy->rf_type = RF_1T1R; + + /* 1T2R but 1SS (1x1 receive combining) */ + rtlefuse->b1x1_recvcombine = false; + if (rtlphy->rf_type == RF_1T2R) { + tempval = rtl_read_byte(rtlpriv, 0x07); + if (!(tempval & BIT(0))) { + rtlefuse->b1x1_recvcombine = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "RF_TYPE=1T2R but only 1SS\n"); + } + } + rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; + rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID]; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); + + /* set channel paln to world wide 13 */ + rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; +} + +void rtl92se_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 tmp_u1b = 0; + + tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); + + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl92se_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + rtlefuse->autoload_failflag = true; + } +} + +static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 nmode = mac->ht_enable; + u8 mimo_ps = IEEE80211_SMPS_OFF; + u16 shortgi_rate = 0; + u32 tmp_ratr_value = 0; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_value &= 0x0000000D; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + if (mimo_ps == IEEE80211_SMPS_STATIC) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) { + if (curtxbw_40mhz) + ratr_mask = 0x000ff015; + else + ratr_mask = 0x000ff005; + } else { + if (curtxbw_40mhz) + ratr_mask = 0x0f0ff015; + else + ratr_mask = 0x0f0ff005; + } + + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) + ratr_value &= 0x0FFFFFFF; + else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) + ratr_value &= 0x0FFFFFF0; + + if (nmode && ((curtxbw_40mhz && + curshortgi_40mhz) || (!curtxbw_40mhz && + curshortgi_20mhz))) { + + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + + rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); + } + + rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value); + if (ratr_value & 0xfffff000) + rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N); + else + rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, ARFR0)); +} + +static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index = 0; + u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u32 ratr_value = 0; + u8 shortgi_rate = 0; + u32 mask = 0; + u32 band = 0; + bool bmulticast = false; + u8 macid = 0; + u8 mimo_ps = IEEE80211_SMPS_OFF; + + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + band |= WIRELESS_11B; + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + band |= (WIRELESS_11G | WIRELESS_11B); + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + band |= WIRELESS_11A; + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); + ratr_index = RATR_INX_WIRELESS_NGB; + + if (mimo_ps == IEEE80211_SMPS_STATIC) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (rssi_level == 1) { + ratr_bitmap &= 0x000f0000; + } else if (rssi_level == 3) { + ratr_bitmap &= 0x000fc000; + } else if (rssi_level == 5) { + ratr_bitmap &= 0x000ff000; + } else { + if (curtxbw_40mhz) + ratr_bitmap &= 0x000ff015; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (rssi_level == 1) { + ratr_bitmap &= 0x0f8f0000; + } else if (rssi_level == 3) { + ratr_bitmap &= 0x0f8fc000; + } else if (rssi_level == 5) { + ratr_bitmap &= 0x0f8ff000; + } else { + if (curtxbw_40mhz) + ratr_bitmap &= 0x0f8ff015; + else + ratr_bitmap &= 0x0f8ff005; + } + } + } + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f8ff0ff; + break; + } + sta_entry->ratr_index = ratr_index; + + if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) + ratr_bitmap &= 0x0FFFFFFF; + else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) + ratr_bitmap &= 0x0FFFFFF0; + + if (shortgi) { + ratr_bitmap |= 0x10000000; + /* Get MAX MCS available. */ + ratr_value = (ratr_bitmap >> 12); + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); + } + + mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", + mask, ratr_bitmap); + rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); + rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); + + if (macid != 0) + sta_entry->ratr_index = ratr_index; +} + +void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92se_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl92se_update_hal_rate_table(hw, sta); +} + +void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + &mac->slot_time); + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); + +} + +/* this ifunction is for RFKILL, it's different with windows, + * because UI will disable wireless when GPIO Radio Off. + * And here we not check or Disable/Enable ASPM like windows*/ +bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate rfpwr_toset /*, cur_rfstate */; + unsigned long flag = 0; + bool actuallyset = false; + bool turnonbypowerdomain = false; + + /* just 8191se can check gpio before firstup, 92c/92d have fixed it */ + if (rtlpci->up_first_time || rtlpci->being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + /* cur_rfstate = ppsc->rfpwr_state;*/ + + /* because after _rtl92s_phy_set_rfhalt, all power + * closed, so we must open some power for GPIO check, + * or we will always check GPIO RFOFF here, + * And we should close power after GPIO check */ + if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + _rtl92se_power_domain_init(hw); + turnonbypowerdomain = true; + } + + rfpwr_toset = _rtl92se_rf_onoff_detect(hw); + + if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "RFKILL-HW Radio ON, RF ON\n"); + + rfpwr_toset = ERFON; + ppsc->hwradiooff = false; + actuallyset = true; + } else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, + DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); + + rfpwr_toset = ERFOFF; + ppsc->hwradiooff = true; + actuallyset = true; + } + + if (actuallyset) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + + /* this not include ifconfig wlan0 down case */ + /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */ + } else { + /* because power_domain_init may be happen when + * _rtl92s_phy_set_rfhalt, this will open some powers + * and cause current increasing about 40 mA for ips, + * rfoff and ifconfig down, so we set + * _rtl92s_phy_set_rfhalt again here */ + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC && + turnonbypowerdomain) { + _rtl92s_phy_set_rfhalt(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } + + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + + *valid = 1; + return !ppsc->hwradiooff; + +} + +/* Is_wepkey just used for WEP used as group & pairwise key + * if pairwise is AES ang group is WEP Is_wepkey == false.*/ +void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, + bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + pr_err("switch case %#x not processed\n", + enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} + +void rtl92se_suspend(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtlpci->up_first_time = true; +} + +void rtl92se_resume(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 val; + + pci_read_config_dword(rtlpci->pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(rtlpci->pdev, 0x40, + val & 0xffff00ff); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h new file mode 100644 index 000000000..5edbc1ecd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_PCI92SE_HW_H__ +#define __REALTEK_PCI92SE_HW_H__ + +#define MSR_LINK_MANAGED 2 +#define MSR_LINK_NONE 0 +#define MSR_LINK_SHIFT 0 +#define MSR_LINK_ADHOC 1 +#define MSR_LINK_MASTER 3 + +enum WIRELESS_NETWORK_TYPE { + WIRELESS_11B = 1, + WIRELESS_11G = 2, + WIRELESS_11A = 4, + WIRELESS_11N = 8 +}; + +void rtl92se_get_hw_reg(struct ieee80211_hw *hw, + u8 variable, u8 *val); +void rtl92se_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl92se_hw_init(struct ieee80211_hw *hw); +void rtl92se_card_disable(struct ieee80211_hw *hw); +void rtl92se_enable_interrupt(struct ieee80211_hw *hw); +void rtl92se_disable_interrupt(struct ieee80211_hw *hw); +int rtl92se_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr); +void rtl92se_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92se_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, + u8 *val); +void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw); +void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, + u8 *valid); +void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw); +void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92se_set_key(struct ieee80211_hw *hw, + u32 key_index, u8 *macaddr, bool is_group, + u8 enc_algo, bool is_wepkey, bool clear_all); +void rtl92se_suspend(struct ieee80211_hw *hw); +void rtl92se_resume(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c new file mode 100644 index 000000000..db16a325c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl92se_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pin); + + ledcfg = rtl_read_byte(rtlpriv, LEDCFG); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0xf0); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0x0f); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl92se_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv; + u8 ledcfg; + + rtlpriv = rtl_priv(hw); + if (!rtlpriv || rtlpriv->max_fw_size) + return; + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pin); + + ledcfg = rtl_read_byte(rtlpriv, LEDCFG); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) + rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); + else + rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl92se_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92se_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl92se_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); + + _rtl92se_sw_led_control(hw, ledaction); +} + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h new file mode 100644 index 000000000..43fcc3c77 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_PCI92SE_LED_H__ +#define __REALTEK_PCI92SE_LED_H__ + +void rtl92se_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92se_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c new file mode 100644 index 000000000..d9ef7e1da --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c @@ -0,0 +1,1610 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "fw.h" +#include "hw.h" +#include "table.h" + +u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue = 0, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + + return returnvalue; + +} + +void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + +} + +static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue = 0; + + offset &= 0x3f; + newoffset = offset; + + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + + tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) | + BLSSI_READEDGE; + + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSI_READEDGE)); + + mdelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + mdelay(1); + + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong | + BLSSI_READEDGE); + mdelay(1); + + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSI_READBACK_DATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSI_READBACK_DATA); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); + + return retvalue; + +} + +static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 data_and_addr = 0; + u32 newoffset; + + offset &= 0x3f; + newoffset = offset; + + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); +} + + +u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); + + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + + if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) + return; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | (data << bitshift)); + } + + _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + +} + +void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN); + break; + case SCAN_OPT_RESTORE: + rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN); + break; + default: + pr_err("Unknown operation\n"); + break; + } + } +} + +void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (rtlphy->set_bwmode_inprogress) + return; + if (is_hal_stop(rtlhal)) + return; + + rtlphy->set_bwmode_inprogress = true; + + reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); + /* dummy read */ + rtl_read_byte(rtlpriv, RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + + if (rtlhal->version >= VERSION_8192S_BCUT) + rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + + if (rtlhal->version >= VERSION_8192S_BCUT) + rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); +} + +static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8192se: cmdtable cannot be NULL\n"); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + + return true; +} + +static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8192se: invalid channel for Zebra: %d\n", channel); + + _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92s_phy_set_txpower(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + pr_err("switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 delay; + bool ret; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); + + if (rtlphy->sw_chnl_inprogress) + return 0; + + if (rtlphy->set_bwmode_inprogress) + return 0; + + if (is_hal_stop(rtlhal)) + return 0; + + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + + do { + if (!rtlphy->sw_chnl_inprogress) + break; + + ret = _rtl92s_phy_sw_chnl_step_by_step(hw, + rtlphy->current_channel, + &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay); + if (!ret) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + + rtlphy->sw_chnl_inprogress = false; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); + + return 1; +} + +static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1btmp; + + u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); + u1btmp |= BIT(0); + + rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); + rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); + rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); + rtl_write_word(rtlpriv, CMDR, 0x57FC); + udelay(100); + + rtl_write_word(rtlpriv, CMDR, 0x77FC); + rtl_write_byte(rtlpriv, PHY_CCA, 0x0); + udelay(10); + + rtl_write_word(rtlpriv, CMDR, 0x37FC); + udelay(10); + + rtl_write_word(rtlpriv, CMDR, 0x77FC); + udelay(10); + + rtl_write_word(rtlpriv, CMDR, 0x57FC); + + /* we should chnge GPIO to input mode + * this will drop away current about 25mA*/ + rtl8192se_gpiobit3_cfg_inputmode(hw); +} + +bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + if (rfpwr_state == ppsc->rfpwr_state) + return false; + + switch (rfpwr_state) { + case ERFON:{ + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + + bool rtstatus; + u32 initializecount = 0; + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "awake, slept:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_awake_jiffies = jiffies; + rtl_write_word(rtlpriv, CMDR, 0x37FC); + rtl_write_byte(rtlpriv, TXPAUSE, 0x00); + rtl_write_byte(rtlpriv, PHY_CCA, 0x3); + } + + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + break; + } + case ERFOFF:{ + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + break; + } + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + return false; + + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); + ppsc->last_sleep_jiffies = jiffies; + _rtl92se_phy_set_rf_sleep(hw); + break; + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + bresult = false; + break; + } + + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + + return bresult; +} + +static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool rtstatus = true; + u32 tmpval = 0; + + /* If inferiority IC, we have to increase the PA bias current */ + if (rtlhal->ic_class != IC_INFERIORITY_A) { + tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf); + rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1); + } + + return rtstatus; +} + +static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 reg_addr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + int index; + + if (reg_addr == RTXAGC_RATE18_06) + index = 0; + else if (reg_addr == RTXAGC_RATE54_24) + index = 1; + else if (reg_addr == RTXAGC_CCK_MCS32) + index = 6; + else if (reg_addr == RTXAGC_MCS03_MCS00) + index = 2; + else if (reg_addr == RTXAGC_MCS07_MCS04) + index = 3; + else if (reg_addr == RTXAGC_MCS11_MCS08) + index = 4; + else if (reg_addr == RTXAGC_MCS15_MCS12) + index = 5; + else + return; + + rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + if (index == 5) + rtlphy->pwrgroup_cnt++; +} + +static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + /*RF Interface Sowrtware Control */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + /* RF Interface Readback Value */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + /* RF Interface Output (and Enable) */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE; + + /* RF Interface (Output and) Enable */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE; + + /* Addr of LSSI. Wirte RF register by driver */ + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset = + RFPGA0_XC_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset = + RFPGA0_XD_LSSIPARAMETER; + + /* RF parameter */ + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + /* Tranceiver A~D HSSI Parameter-1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1; + + /* Tranceiver A~D HSSI Parameter-2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; + + /* RF switch Control */ + rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + + /* AGC control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + /* AGC control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + /* RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + + /* RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + /* Tx AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + + /* Tx AFE control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + /* Tranceiver LSSI Readback */ + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + + /* Tranceiver LSSI Readback PI mode */ + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; +} + + +static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype) +{ + int i; + u32 *phy_reg_table; + u32 *agc_table; + u16 phy_reg_len, agc_len; + + agc_len = AGCTAB_ARRAYLENGTH; + agc_table = rtl8192seagctab_array; + /* Default RF_type: 2T2R */ + phy_reg_len = PHY_REG_2T2RARRAYLENGTH; + phy_reg_table = rtl8192sephy_reg_2t2rarray; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_len; i = i + 2) { + rtl_addr_delay(phy_reg_table[i]); + + /* Add delay for ECS T20 & LG malow platform, */ + udelay(1); + + rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD, + phy_reg_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agc_len; i = i + 2) { + rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD, + agc_table[i + 1]); + + /* Add delay for ECS T20 & LG malow platform */ + udelay(1); + } + } + + return true; +} + +static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 *phy_regarray2xtxr_table; + u16 phy_regarray2xtxr_len; + int i; + + if (rtlphy->rf_type == RF_1T1R) { + phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray; + phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH; + } else if (rtlphy->rf_type == RF_1T2R) { + phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray; + phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH; + } else { + return false; + } + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { + rtl_addr_delay(phy_regarray2xtxr_table[i]); + + rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i], + phy_regarray2xtxr_table[i + 1], + phy_regarray2xtxr_table[i + 2]); + } + } + + return true; +} + +static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_table_pg; + u16 phy_pg_len; + + phy_pg_len = PHY_REG_ARRAY_PGLENGTH; + phy_table_pg = rtl8192sephy_reg_array_pg; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_pg_len; i = i + 3) { + rtl_addr_delay(phy_table_pg[i]); + + _rtl92s_store_pwrindex_diffrate_offset(hw, + phy_table_pg[i], + phy_table_pg[i + 1], + phy_table_pg[i + 2]); + rtl92s_phy_set_bb_reg(hw, phy_table_pg[i], + phy_table_pg[i + 1], + phy_table_pg[i + 2]); + } + } + + return true; +} + +static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus = true; + + /* 1. Read PHY_REG.TXT BB INIT!! */ + /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */ + if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R || + rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) { + rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG); + + if (rtlphy->rf_type != RF_2T2R && + rtlphy->rf_type != RF_2T2R_GREEN) + /* so we should reconfig BB reg with the right + * PHY parameters. */ + rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw, + BASEBAND_CONFIG_PHY_REG); + } else { + rtstatus = false; + } + + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + goto phy_bb8190_config_parafile_fail; + } + + /* 2. If EEPROM or EFUSE autoload OK, We must config by + * PHY_REG_PG.txt */ + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + + rtstatus = _rtl92s_phy_config_bb_with_pg(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); + goto phy_bb8190_config_parafile_fail; + } + + /* 3. BB AGC table Initialization */ + rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); + + if (!rtstatus) { + pr_err("%s(): AGC Table Fail\n", __func__); + goto phy_bb8190_config_parafile_fail; + } + + /* Check if the CCK HighPower is turned ON. */ + /* This is used to calculate PWDB. */ + rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw, + RFPGA0_XA_HSSIPARAMETER2, 0x200)); + +phy_bb8190_config_parafile_fail: + return rtstatus; +} + +u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + int i; + bool rtstatus = true; + u32 *radio_a_table; + u32 *radio_b_table; + u16 radio_a_tblen, radio_b_tblen; + + radio_a_tblen = RADIOA_1T_ARRAYLENGTH; + radio_a_table = rtl8192seradioa_1t_array; + + /* Using Green mode array table for RF_2T2R_GREEN */ + if (rtlphy->rf_type == RF_2T2R_GREEN) { + radio_b_table = rtl8192seradiob_gm_array; + radio_b_tblen = RADIOB_GM_ARRAYLENGTH; + } else { + radio_b_table = rtl8192seradiob_array; + radio_b_tblen = RADIOB_ARRAYLENGTH; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + rtstatus = true; + + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radio_a_tblen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radio_a_table[i], + MASK20BITS, radio_a_table[i + 1]); + + } + + /* PA Bias current for inferiority IC */ + _rtl92s_phy_config_rfpa_bias_current(hw, rfpath); + break; + case RF90_PATH_B: + for (i = 0; i < radio_b_tblen; i = i + 2) { + rtl_rfreg_delay(hw, rfpath, radio_b_table[i], + MASK20BITS, radio_b_table[i + 1]); + } + break; + case RF90_PATH_C: + ; + break; + case RF90_PATH_D: + ; + break; + default: + break; + } + + return rtstatus; +} + + +bool rtl92s_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = rtl8192semac_2t_array; + + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); + + return true; +} + + +bool rtl92s_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool rtstatus; + u8 pathmap, index, rf_num = 0; + u8 path1, path2; + + _rtl92s_phy_init_register_definition(hw); + + /* Config BB and AGC */ + rtstatus = _rtl92s_phy_bb_config_parafile(hw); + + + /* Check BB/RF confiuration setting. */ + /* We only need to configure RF which is turned on. */ + path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf)); + mdelay(10); + path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf)); + pathmap = path1 | path2; + + rtlphy->rf_pathmap = pathmap; + for (index = 0; index < 4; index++) { + if ((pathmap >> index) & 0x1) + rf_num++; + } + + if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) || + (rtlphy->rf_type == RF_1T2R && rf_num != 2) || + (rtlphy->rf_type == RF_2T2R && rf_num != 2) || + (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { + pr_err("RF_Type(%x) does not match RF_Num(%x)!!\n", + rtlphy->rf_type, rf_num); + pr_err("path1 0x%x, path2 0x%x, pathmap 0x%x\n", + path1, path2, pathmap); + } + + return rtstatus; +} + +bool rtl92s_phy_rf_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + /* Initialize general global value */ + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + /* Config BB and RF */ + return rtl92s_phy_rf6052_config(hw); +} + +void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + /* read rx initial gain */ + rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, + ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, + ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, + ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, + ROFDM0_XDAGCCORE1, MASKBYTE0); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + /* read framesync */ + rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, + MASKDWORD); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); + +} + +static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + /* 1. CCK */ + /* RF-A */ + cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index]; + /* RF-B */ + cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index]; + + /* 2. OFDM for 1T or 2T */ + if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index]; + ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index]; + } else if (rtlphy->rf_type == RF_2T2R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; + ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; + } else { + ofdmpowerlevel[0] = 0; + ofdmpowerlevel[1] = 0; + } +} + +static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + /* [0]:RF-A, [1]:RF-B */ + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (!rtlefuse->txpwr_fromeprom) + return; + + /* Mainly we use RF-A Tx Power to write the Tx Power registers, + * but the RF-B Tx Power must be calculated by the antenna diff. + * So we have to rewrite Antenna gain offset register here. + * Please refer to BB register 0x80c + * 1. For CCK. + * 2. For OFDM 1T or 2T */ + _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + channel, cckpowerlevel[0], cckpowerlevel[1], + ofdmpowerlevel[0], ofdmpowerlevel[1]); + + _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + + rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]); + rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerlevel[0], channel); + +} + +void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 pollingcnt = 10000; + u32 tmpvalue; + + /* Make sure that CMD IO has be accepted by FW. */ + do { + udelay(10); + + tmpvalue = rtl_read_dword(rtlpriv, WFM5); + if (tmpvalue == 0) + break; + } while (--pollingcnt); + + if (pollingcnt == 0) + pr_err("Set FW Cmd fail!!\n"); +} + + +static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 input, current_aid = 0; + + if (is_hal_stop(rtlhal)) + return; + + if (hal_get_firmwareversion(rtlpriv) < 0x34) + goto skip; + /* We re-map RA related CMD IO to combinational ones */ + /* if FW version is v.52 or later. */ + switch (rtlhal->current_fwcmd_io) { + case FW_CMD_RA_REFRESH_N: + rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB; + break; + case FW_CMD_RA_REFRESH_BG: + rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB; + break; + default: + break; + } + +skip: + switch (rtlhal->current_fwcmd_io) { + case FW_CMD_RA_RESET: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); + rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_RA_ACTIVE: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); + rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_RA_REFRESH_N: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); + input = FW_RA_REFRESH; + rtl_write_dword(rtlpriv, WFM5, input); + rtl92s_phy_chk_fwcmd_iodone(hw); + rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_RA_REFRESH_BG: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_BG\n"); + rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); + rtl92s_phy_chk_fwcmd_iodone(hw); + rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_RA_REFRESH_N_COMB: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_N_COMB\n"); + input = FW_RA_IOT_N_COMB; + rtl_write_dword(rtlpriv, WFM5, input); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_RA_REFRESH_BG_COMB: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_BG_COMB\n"); + input = FW_RA_IOT_BG_COMB; + rtl_write_dword(rtlpriv, WFM5, input); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_IQK_ENABLE: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); + rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_PAUSE_DM_BY_SCAN: + /* Lower initial gain */ + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); + /* CCA threshold */ + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); + break; + case FW_CMD_RESUME_DM_BY_SCAN: + /* CCA threshold */ + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl92s_phy_set_txpower(hw, rtlphy->current_channel); + break; + case FW_CMD_HIGH_PWR_DISABLE: + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) + break; + + /* Lower initial gain */ + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); + /* CCA threshold */ + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); + break; + case FW_CMD_HIGH_PWR_ENABLE: + if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || + rtlpriv->dm.dynamic_txpower_enable) + break; + + /* CCA threshold */ + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + break; + case FW_CMD_LPS_ENTER: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); + current_aid = rtlpriv->mac80211.assoc_id; + rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | + ((current_aid | 0xc000) << 8))); + rtl92s_phy_chk_fwcmd_iodone(hw); + /* FW set TXOP disable here, so disable EDCA + * turbo mode until driver leave LPS */ + break; + case FW_CMD_LPS_LEAVE: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); + rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_ADD_A2_ENTRY: + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); + rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + case FW_CMD_CTRL_DM_BY_DRIVER: + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "FW_CMD_CTRL_DM_BY_DRIVER\n"); + rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); + rtl92s_phy_chk_fwcmd_iodone(hw); + break; + + default: + break; + } + + rtl92s_phy_chk_fwcmd_iodone(hw); + + /* Clear FW CMD operation flag. */ + rtlhal->set_fwcmd_inprogress = false; +} + +bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *digtable = &rtlpriv->dm_digtable; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv); + u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", + fw_cmdio, rtlhal->set_fwcmd_inprogress); + + do { + /* We re-map to combined FW CMD ones if firmware version */ + /* is v.53 or later. */ + if (hal_get_firmwareversion(rtlpriv) >= 0x35) { + switch (fw_cmdio) { + case FW_CMD_RA_REFRESH_N: + fw_cmdio = FW_CMD_RA_REFRESH_N_COMB; + break; + case FW_CMD_RA_REFRESH_BG: + fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB; + break; + default: + break; + } + } else { + if ((fw_cmdio == FW_CMD_IQK_ENABLE) || + (fw_cmdio == FW_CMD_RA_REFRESH_N) || + (fw_cmdio == FW_CMD_RA_REFRESH_BG)) { + postprocessing = true; + break; + } + } + + /* If firmware version is v.62 or later, + * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */ + if (hal_get_firmwareversion(rtlpriv) >= 0x3E) { + if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER) + fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW; + } + + + /* We shall revise all FW Cmd IO into Reg0x364 + * DM map table in the future. */ + switch (fw_cmdio) { + case FW_CMD_RA_INIT: + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); + fw_cmdmap |= FW_RA_INIT_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + /* Clear control flag to sync with FW. */ + FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL); + break; + case FW_CMD_DIG_DISABLE: + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG disable!!\n"); + fw_cmdmap &= ~FW_DIG_ENABLE_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + case FW_CMD_DIG_ENABLE: + case FW_CMD_DIG_RESUME: + if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG enable or resume!!\n"); + fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + } + break; + case FW_CMD_DIG_HALT: + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG halt!!\n"); + fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + case FW_CMD_TXPWR_TRACK_THERMAL: { + u8 thermalval = 0; + fw_cmdmap |= FW_PWR_TRK_CTL; + + /* Clear FW parameter in terms of thermal parts. */ + fw_param &= FW_PWR_TRK_PARAM_CLR; + + thermalval = rtlpriv->dm.thermalvalue; + fw_param |= ((thermalval << 24) | + (rtlefuse->thermalmeter[0] << 16)); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); + + FW_CMD_PARA_SET(rtlpriv, fw_param); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + + /* Clear control flag to sync with FW. */ + FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL); + } + break; + /* The following FW CMDs are only compatible to + * v.53 or later. */ + case FW_CMD_RA_REFRESH_N_COMB: + fw_cmdmap |= FW_RA_N_CTL; + + /* Clear RA BG mode control. */ + fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL); + + /* Clear FW parameter in terms of RA parts. */ + fw_param &= FW_RA_PARAM_CLR; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); + + FW_CMD_PARA_SET(rtlpriv, fw_param); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + + /* Clear control flag to sync with FW. */ + FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL); + break; + case FW_CMD_RA_REFRESH_BG_COMB: + fw_cmdmap |= FW_RA_BG_CTL; + + /* Clear RA n-mode control. */ + fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL); + /* Clear FW parameter in terms of RA parts. */ + fw_param &= FW_RA_PARAM_CLR; + + FW_CMD_PARA_SET(rtlpriv, fw_param); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + + /* Clear control flag to sync with FW. */ + FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL); + break; + case FW_CMD_IQK_ENABLE: + fw_cmdmap |= FW_IQK_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + /* Clear control flag to sync with FW. */ + FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL); + break; + /* The following FW CMD is compatible to v.62 or later. */ + case FW_CMD_CTRL_DM_BY_DRIVER_NEW: + fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + /* The followed FW Cmds needs post-processing later. */ + case FW_CMD_RESUME_DM_BY_SCAN: + fw_cmdmap |= (FW_DIG_ENABLE_CTL | + FW_HIGH_PWR_ENABLE_CTL | + FW_SS_CTL); + + if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE || + !digtable->dig_enable_flag) + fw_cmdmap &= ~FW_DIG_ENABLE_CTL; + + if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || + rtlpriv->dm.dynamic_txpower_enable) + fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; + + if ((digtable->dig_ext_port_stage == + DIG_EXT_PORT_STAGE_0) || + (digtable->dig_ext_port_stage == + DIG_EXT_PORT_STAGE_1)) + fw_cmdmap &= ~FW_DIG_ENABLE_CTL; + + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + postprocessing = true; + break; + case FW_CMD_PAUSE_DM_BY_SCAN: + fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | + FW_HIGH_PWR_ENABLE_CTL | + FW_SS_CTL); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + postprocessing = true; + break; + case FW_CMD_HIGH_PWR_DISABLE: + fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + postprocessing = true; + break; + case FW_CMD_HIGH_PWR_ENABLE: + if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && + !rtlpriv->dm.dynamic_txpower_enable) { + fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | + FW_SS_CTL); + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + postprocessing = true; + } + break; + case FW_CMD_DIG_MODE_FA: + fw_cmdmap |= FW_FA_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + case FW_CMD_DIG_MODE_SS: + fw_cmdmap &= ~FW_FA_CTL; + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + case FW_CMD_PAPE_CONTROL: + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "[FW CMD] Set PAPE Control\n"); + fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; + + FW_CMD_IO_SET(rtlpriv, fw_cmdmap); + break; + default: + /* Pass to original FW CMD processing callback + * routine. */ + postprocessing = true; + break; + } + } while (false); + + /* We shall post processing these FW CMD if + * variable postprocessing is set. + */ + if (postprocessing && !rtlhal->set_fwcmd_inprogress) { + rtlhal->set_fwcmd_inprogress = true; + /* Update current FW Cmd for callback use. */ + rtlhal->current_fwcmd_io = fw_cmdio; + } else { + return false; + } + + _rtl92s_phy_set_fwcmd_io(hw); + return true; +} + +static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 delay = 100; + u8 regu1; + + regu1 = rtl_read_byte(rtlpriv, 0x554); + while ((regu1 & BIT(5)) && (delay > 0)) { + regu1 = rtl_read_byte(rtlpriv, 0x554); + delay--; + /* We delay only 50us to prevent + * being scheduled out. */ + udelay(50); + } +} + +void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + /* The way to be capable to switch clock request + * when the PG setting does not support clock request. + * This is the backdoor solution to switch clock + * request before ASPM or D3. */ + rtl_write_dword(rtlpriv, 0x540, 0x73c11); + rtl_write_dword(rtlpriv, 0x548, 0x2407c); + + /* Switch EPHY parameter!!!! */ + rtl_write_word(rtlpriv, 0x550, 0x1000); + rtl_write_byte(rtlpriv, 0x554, 0x20); + _rtl92s_phy_check_ephy_switchready(hw); + + rtl_write_word(rtlpriv, 0x550, 0xa0eb); + rtl_write_byte(rtlpriv, 0x554, 0x3e); + _rtl92s_phy_check_ephy_switchready(hw); + + rtl_write_word(rtlpriv, 0x550, 0xff80); + rtl_write_byte(rtlpriv, 0x554, 0x39); + _rtl92s_phy_check_ephy_switchready(hw); + + /* Delay L1 enter time */ + if (ppsc->support_aspm && !ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x560, 0x40); + else + rtl_write_byte(rtlpriv, 0x560, 0x00); + +} + +void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 new_bcn_num = 0; + + if (hal_get_firmwareversion(rtlpriv) >= 0x33) { + /* Fw v.51 and later. */ + rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | + (beaconinterval << 8)); + } else { + new_bcn_num = beaconinterval * 32 - 64; + rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num); + rtl_write_dword(rtlpriv, WFM3, 0xB026007C); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h new file mode 100644 index 000000000..b8b5f097b --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92S_PHY_H__ +#define __RTL92S_PHY_H__ + +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define MAX_DOZE_WAITING_TIMES_9x 64 + +/* Channel switch:The size of + * command tables for switch channel */ +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define RF90_PATH_MAX 4 +#define RF6052_MAX_PATH 2 + +enum version_8192s { + VERSION_8192S_ACUT, + VERSION_8192S_BCUT, + VERSION_8192S_CCUT +}; + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum baseband_config_type { + /* Radio Path A */ + BASEBAND_CONFIG_PHY_REG = 0, + /* Radio Path B */ + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +#define hal_get_firmwareversion(rtlpriv) \ + (((struct rt_firmware *)(rtlpriv->rtlhal.pfirmware))->firmwareversion) + +u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); +void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); +void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); +u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw); +bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpower_state); +bool rtl92s_phy_mac_config(struct ieee80211_hw *hw); +void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw); +bool rtl92s_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92s_phy_rf_config(struct ieee80211_hw *hw); +void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel); +bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fwcmd_io); +void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw); +void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval); +u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) ; + +#endif + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h new file mode 100644 index 000000000..45f968e0e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h @@ -0,0 +1,1143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_92S_REG_H__ +#define __REALTEK_92S_REG_H__ + +/* 1. System Configuration Registers */ +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define PMC_FSM 0x0004 +#define SYS_CLKR 0x0008 +#define EPROM_CMD 0x000A +#define EE_VPD 0x000C +#define AFE_MISC 0x0010 +#define SPS0_CTRL 0x0011 +#define SPS1_CTRL 0x0018 +#define RF_CTRL 0x001F +#define LDOA15_CTRL 0x0020 +#define LDOV12D_CTRL 0x0021 +#define LDOHCI12_CTRL 0x0022 +#define LDO_USB_SDIO 0x0023 +#define LPLDO_CTRL 0x0024 +#define AFE_XTAL_CTRL 0x0026 +#define AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define PWR_DATA 0x0038 +#define DBG_PORT 0x003A +#define DPS_TIMER 0x003C +#define RCLK_MON 0x003E + +/* 2. Command Control Registers */ +#define CMDR 0x0040 +#define TXPAUSE 0x0042 +#define LBKMD_SEL 0x0043 +#define TCR 0x0044 +#define RCR 0x0048 +#define MSR 0x004C +#define SYSF_CFG 0x004D +#define RX_PKY_LIMIT 0x004E +#define MBIDCTRL 0x004F + +/* 3. MACID Setting Registers */ +#define MACIDR 0x0050 +#define MACIDR0 0x0050 +#define MACIDR4 0x0054 +#define BSSIDR 0x0058 +#define HWVID 0x005E +#define MAR 0x0060 +#define MBIDCAMCONTENT 0x0068 +#define MBIDCAMCFG 0x0070 +#define BUILDTIME 0x0074 +#define BUILDUSER 0x0078 + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +/* 4. Timing Control Registers */ +#define TSFR 0x0080 +#define SLOT_TIME 0x0089 +#define USTIME 0x008A +#define SIFS_CCK 0x008C +#define SIFS_OFDM 0x008E +#define PIFS_TIME 0x0090 +#define ACK_TIMEOUT 0x0091 +#define EIFSTR 0x0092 +#define BCN_INTERVAL 0x0094 +#define ATIMWND 0x0096 +#define BCN_DRV_EARLY_INT 0x0098 +#define BCN_DMATIME 0x009A +#define BCN_ERR_THRESH 0x009C +#define MLT 0x009D +#define RSVD_MAC_TUNE_US 0x009E + +/* 5. FIFO Control Registers */ +#define RQPN 0x00A0 +#define RQPN1 0x00A0 +#define RQPN2 0x00A1 +#define RQPN3 0x00A2 +#define RQPN4 0x00A3 +#define RQPN5 0x00A4 +#define RQPN6 0x00A5 +#define RQPN7 0x00A6 +#define RQPN8 0x00A7 +#define RQPN9 0x00A8 +#define RQPN10 0x00A9 +#define LD_RQPN 0x00AB +#define RXFF_BNDY 0x00AC +#define RXRPT_BNDY 0x00B0 +#define TXPKTBUF_PGBNDY 0x00B4 +#define PBP 0x00B5 +#define RXDRVINFO_SZ 0x00B6 +#define TXFF_STATUS 0x00B7 +#define RXFF_STATUS 0x00B8 +#define TXFF_EMPTY_TH 0x00B9 +#define SDIO_RX_BLKSZ 0x00BC +#define RXDMA 0x00BD +#define RXPKT_NUM 0x00BE +#define C2HCMD_UDT_SIZE 0x00C0 +#define C2HCMD_UDT_ADDR 0x00C2 +#define FIFOPAGE1 0x00C4 +#define FIFOPAGE2 0x00C8 +#define FIFOPAGE3 0x00CC +#define FIFOPAGE4 0x00D0 +#define FIFOPAGE5 0x00D4 +#define FW_RSVD_PG_CRTL 0x00D8 +#define RXDMA_AGG_PG_TH 0x00D9 +#define TXDESC_MSK 0x00DC +#define TXRPTFF_RDPTR 0x00E0 +#define TXRPTFF_WTPTR 0x00E4 +#define C2HFF_RDPTR 0x00E8 +#define C2HFF_WTPTR 0x00EC +#define RXFF0_RDPTR 0x00F0 +#define RXFF0_WTPTR 0x00F4 +#define RXFF1_RDPTR 0x00F8 +#define RXFF1_WTPTR 0x00FC +#define RXRPT0_RDPTR 0x0100 +#define RXRPT0_WTPTR 0x0104 +#define RXRPT1_RDPTR 0x0108 +#define RXRPT1_WTPTR 0x010C +#define RX0_UDT_SIZE 0x0110 +#define RX1PKTNUM 0x0114 +#define RXFILTERMAP 0x0116 +#define RXFILTERMAP_GP1 0x0118 +#define RXFILTERMAP_GP2 0x011A +#define RXFILTERMAP_GP3 0x011C +#define BCNQ_CTRL 0x0120 +#define MGTQ_CTRL 0x0124 +#define HIQ_CTRL 0x0128 +#define VOTID7_CTRL 0x012c +#define VOTID6_CTRL 0x0130 +#define VITID5_CTRL 0x0134 +#define VITID4_CTRL 0x0138 +#define BETID3_CTRL 0x013c +#define BETID0_CTRL 0x0140 +#define BKTID2_CTRL 0x0144 +#define BKTID1_CTRL 0x0148 +#define CMDQ_CTRL 0x014c +#define TXPKT_NUM_CTRL 0x0150 +#define TXQ_PGADD 0x0152 +#define TXFF_PG_NUM 0x0154 +#define TRXDMA_STATUS 0x0156 + +/* 6. Adaptive Control Registers */ +#define INIMCS_SEL 0x0160 +#define TX_RATE_REG INIMCS_SEL +#define INIRTSMCS_SEL 0x0180 +#define RRSR 0x0181 +#define ARFR0 0x0184 +#define ARFR1 0x0188 +#define ARFR2 0x018C +#define ARFR3 0x0190 +#define ARFR4 0x0194 +#define ARFR5 0x0198 +#define ARFR6 0x019C +#define ARFR7 0x01A0 +#define AGGLEN_LMT_H 0x01A7 +#define AGGLEN_LMT_L 0x01A8 +#define DARFRC 0x01B0 +#define RARFRC 0x01B8 +#define MCS_TXAGC 0x01C0 +#define CCK_TXAGC 0x01C8 + +/* 7. EDCA Setting Registers */ +#define EDCAPARA_VO 0x01D0 +#define EDCAPARA_VI 0x01D4 +#define EDCAPARA_BE 0x01D8 +#define EDCAPARA_BK 0x01DC +#define BCNTCFG 0x01E0 +#define CWRR 0x01E2 +#define ACMAVG 0x01E4 +#define ACMHWCTRL 0x01E7 +#define VO_ADMTM 0x01E8 +#define VI_ADMTM 0x01EC +#define BE_ADMTM 0x01F0 +#define RETRY_LIMIT 0x01F4 +#define SG_RATE 0x01F6 + +/* 8. WMAC, BA and CCX related Register. */ +#define NAV_CTRL 0x0200 +#define BW_OPMODE 0x0203 +#define BACAMCMD 0x0204 +#define BACAMCONTENT 0x0208 + +/* the 0x2xx register WMAC definition */ +#define LBDLY 0x0210 +#define FWDLY 0x0211 +#define HWPC_RX_CTRL 0x0218 +#define MQIR 0x0220 +#define MAIR 0x0222 +#define MSIR 0x0224 +#define CLM_RESULT 0x0227 +#define NHM_RPI_CNT 0x0228 +#define RXERR_RPT 0x0230 +#define NAV_PROT_LEN 0x0234 +#define CFEND_TH 0x0236 +#define AMPDU_MIN_SPACE 0x0237 +#define TXOP_STALL_CTRL 0x0238 + +/* 9. Security Control Registers */ +#define REG_RWCAM 0x0240 +#define REG_WCAMI 0x0244 +#define REG_RCAMO 0x0248 +#define REG_CAMDBG 0x024C +#define REG_SECR 0x0250 + +/* 10. Power Save Control Registers */ +#define WOW_CTRL 0x0260 +#define PSSTATUS 0x0261 +#define PSSWITCH 0x0262 +#define MIMOPS_WAIT_PERIOD 0x0263 +#define LPNAV_CTRL 0x0264 +#define WFM0 0x0270 +#define WFM1 0x0280 +#define WFM2 0x0290 +#define WFM3 0x02A0 +#define WFM4 0x02B0 +#define WFM5 0x02C0 +#define WFCRC 0x02D0 +#define FW_RPT_REG 0x02c4 + +/* 11. General Purpose Registers */ +#define PSTIME 0x02E0 +#define TIMER0 0x02E4 +#define TIMER1 0x02E8 +#define GPIO_IN_SE 0x02EC +#define GPIO_IO_SEL 0x02EE +#define MAC_PINMUX_CFG 0x02F1 +#define LEDCFG 0x02F2 +#define PHY_REG 0x02F3 +#define PHY_REG_DATA 0x02F4 +#define REG_EFUSE_CLK 0x02F8 + +/* 12. Host Interrupt Status Registers */ +#define INTA_MASK 0x0300 +#define ISR 0x0308 + +/* 13. Test mode and Debug Control Registers */ +#define DBG_PORT_SWITCH 0x003A +#define BIST 0x0310 +#define DBS 0x0314 +#define CPUINST 0x0318 +#define CPUCAUSE 0x031C +#define LBUS_ERR_ADDR 0x0320 +#define LBUS_ERR_CMD 0x0324 +#define LBUS_ERR_DATA_L 0x0328 +#define LBUS_ERR_DATA_H 0x032C +#define LX_EXCEPTION_ADDR 0x0330 +#define WDG_CTRL 0x0334 +#define INTMTU 0x0338 +#define INTM 0x033A +#define FDLOCKTURN0 0x033C +#define FDLOCKTURN1 0x033D +#define TRXPKTBUF_DBG_DATA 0x0340 +#define TRXPKTBUF_DBG_CTRL 0x0348 +#define DPLL 0x034A +#define CBUS_ERR_ADDR 0x0350 +#define CBUS_ERR_CMD 0x0354 +#define CBUS_ERR_DATA_L 0x0358 +#define CBUS_ERR_DATA_H 0x035C +#define USB_SIE_INTF_ADDR 0x0360 +#define USB_SIE_INTF_WD 0x0361 +#define USB_SIE_INTF_RD 0x0362 +#define USB_SIE_INTF_CTRL 0x0363 +#define LBUS_MON_ADDR 0x0364 +#define LBUS_ADDR_MASK 0x0368 + +/* Boundary is 0x37F */ + +/* 14. PCIE config register */ +#define TP_POLL 0x0500 +#define PM_CTRL 0x0502 +#define PCIF 0x0503 + +#define THPDA 0x0514 +#define TMDA 0x0518 +#define TCDA 0x051C +#define HDA 0x0520 +#define TVODA 0x0524 +#define TVIDA 0x0528 +#define TBEDA 0x052C +#define TBKDA 0x0530 +#define TBDA 0x0534 +#define RCDA 0x0538 +#define RDQDA 0x053C +#define DBI_WDATA 0x0540 +#define DBI_RDATA 0x0544 +#define DBI_CTRL 0x0548 +#define MDIO_DATA 0x0550 +#define MDIO_CTRL 0x0554 +#define PCI_RPWM 0x0561 +#define PCI_CPWM 0x0563 + +/* Config register (Offset 0x800-) */ +#define PHY_CCA 0x803 + +/* Min Spacing related settings. */ +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +/* Rx DMA Control related settings */ +#define RXDMA_AGG_EN BIT(7) + +#define RPWM PCI_RPWM + +/* Regsiter Bit and Content definition */ + +#define ISO_MD2PP BIT(0) +#define ISO_PA2PCIE BIT(3) +#define ISO_PLL2MD BIT(4) +#define ISO_PWC_DV2RP BIT(11) +#define ISO_PWC_RV2RP BIT(12) + + +#define FEN_MREGEN BIT(15) +#define FEN_DCORE BIT(11) +#define FEN_CPUEN BIT(10) + +#define PAD_HWPD_IDN BIT(22) + +#define SYS_CLKSEL_80M BIT(0) +#define SYS_PS_CLKSEL BIT(1) +#define SYS_CPU_CLKSEL BIT(2) +#define SYS_MAC_CLK_EN BIT(11) +#define SYS_SWHW_SEL BIT(14) +#define SYS_FWHW_SEL BIT(15) + +#define CMDEEPROM_EN BIT(5) +#define CMDEERPOMSEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) + +#define AFE_MBEN BIT(1) +#define AFE_BGEN BIT(0) + +#define SPS1_SWEN BIT(1) +#define SPS1_LDEN BIT(0) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) + +#define XTAL_GATE_AFE BIT(10) + +#define APLL_EN BIT(0) + +#define AFR_CARDBEN BIT(0) +#define AFR_CLKRUN_SEL BIT(1) +#define AFR_FUNCREGEN BIT(2) + +#define APSDOFF_STATUS BIT(15) +#define APSDOFF BIT(14) +#define BBRSTN BIT(13) +#define BB_GLB_RSTN BIT(12) +#define SCHEDULE_EN BIT(10) +#define MACRXEN BIT(9) +#define MACTXEN BIT(8) +#define DDMA_EN BIT(7) +#define FW2HW_EN BIT(6) +#define RXDMA_EN BIT(5) +#define TXDMA_EN BIT(4) +#define HCI_RXDMA_EN BIT(3) +#define HCI_TXDMA_EN BIT(2) + +#define STOPHCCA BIT(6) +#define STOPHIGH BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define LBK_NORMAL 0x00 +#define LBK_MAC_LB (BIT(0) | BIT(1) | BIT(3)) +#define LBK_MAC_DLB (BIT(0) | BIT(1)) +#define LBK_DMA_LB (BIT(0) | BIT(1) | BIT(2)) + +#define TCP_OFDL_EN BIT(25) +#define HWPC_TX_EN BIT(24) +#define TXDMAPRE2FULL BIT(23) +#define DISCW BIT(20) +#define TCRICV BIT(19) +#define cfendform BIT(17) +#define TCRCRC BIT(16) +#define FAKE_IMEM_EN BIT(15) +#define TSFRST BIT(9) +#define TSFEN BIT(8) +#define FWALLRDY (BIT(0) | BIT(1) | BIT(2) | \ + BIT(3) | BIT(4) | BIT(5) | \ + BIT(6) | BIT(7)) +#define FWRDY BIT(7) +#define BASECHG BIT(6) +#define IMEM BIT(5) +#define DMEM_CODE_DONE BIT(4) +#define EXT_IMEM_CHK_RPT BIT(3) +#define EXT_IMEM_CODE_DONE BIT(2) +#define IMEM_CHK_RPT BIT(1) +#define IMEM_CODE_DONE BIT(0) +#define EMEM_CODE_DONE BIT(2) +#define EMEM_CHK_RPT BIT(3) +#define IMEM_RDY BIT(5) +#define LOAD_FW_READY (IMEM_CODE_DONE | \ + IMEM_CHK_RPT | \ + EMEM_CODE_DONE | \ + EMEM_CHK_RPT | \ + DMEM_CODE_DONE | \ + IMEM_RDY | \ + BASECHG | \ + FWRDY) +#define TCR_TSFEN BIT(8) +#define TCR_TSFRST BIT(9) +#define TCR_FAKE_IMEM_EN BIT(15) +#define TCR_CRC BIT(16) +#define TCR_ICV BIT(19) +#define TCR_DISCW BIT(20) +#define TCR_HWPC_TX_EN BIT(24) +#define TCR_TCP_OFDL_EN BIT(25) +#define TXDMA_INIT_VALUE (IMEM_CHK_RPT | \ + EXT_IMEM_CHK_RPT) + +#define RCR_APPFCS BIT(31) +#define RCR_DIS_ENC_2BYTE BIT(30) +#define RCR_DIS_AES_2BYTE BIT(29) +#define RCR_HTC_LOC_CTRL BIT(28) +#define RCR_ENMBID BIT(27) +#define RCR_RX_TCPOFDL_EN BIT(26) +#define RCR_APP_PHYST_RXFF BIT(25) +#define RCR_APP_PHYST_STAFF BIT(24) +#define RCR_CBSSID BIT(23) +#define RCR_APWRMGT BIT(22) +#define RCR_ADD3 BIT(21) +#define RCR_AMF BIT(20) +#define RCR_ACF BIT(19) +#define RCR_ADF BIT(18) +#define RCR_APP_MIC BIT(17) +#define RCR_APP_ICV BIT(16) +#define RCR_RXFTH BIT(13) +#define RCR_AICV BIT(12) +#define RCR_RXDESC_LK_EN BIT(11) +#define RCR_APP_BA_SSN BIT(6) +#define RCR_ACRC32 BIT(5) +#define RCR_RXSHFT_EN BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + + +#define MSR_LINK_MASK ((1 << 0) | (1 << 1)) +#define MSR_LINK_MANAGED 2 +#define MSR_LINK_NONE 0 +#define MSR_LINK_SHIFT 0 +#define MSR_LINK_ADHOC 1 +#define MSR_LINK_MASTER 3 +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define ENUART BIT(7) +#define ENJTAG BIT(3) +#define BTMODE (BIT(2) | BIT(1)) +#define ENBT BIT(0) + +#define ENMBID BIT(7) +#define BCNUM (BIT(6) | BIT(5) | BIT(4)) + +#define USTIME_EDCA 0xFF00 +#define USTIME_TSF 0x00FF + +#define SIFS_TRX 0xFF00 +#define SIFS_CTX 0x00FF + +#define ENSWBCN BIT(15) +#define DRVERLY_TU 0x0FF0 +#define DRVERLY_US 0x000F +#define BCN_TCFG_CW_SHIFT 8 +#define BCN_TCFG_IFS 0 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | \ + RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | \ + RATR_12M | RATR_18M | \ + RATR_24M | RATR_36M | \ + RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | \ + RATR_MCS2 | RATR_MCS3 | \ + RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | \ + RATR_MCS10 | RATR_MCS11 | \ + RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define NAV_UPPER_EN BIT(16) +#define NAV_UPPER 0xFF00 +#define NAV_RTSRST 0xFF + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define RXERR_RPT_RST BIT(27) +#define RXERR_OFDM_PPDU 0 +#define RXERR_OFDM_FALSE_ALARM 1 +#define RXERR_OFDM_MPDU_OK 2 +#define RXERR_OFDM_MPDU_FAIL 3 +#define RXERR_CCK_PPDU 4 +#define RXERR_CCK_FALSE_ALARM 5 +#define RXERR_CCK_MPDU_OK 6 +#define RXERR_CCK_MPDU_FAIL 7 +#define RXERR_HT_PPDU 8 +#define RXERR_HT_FALSE_ALARM 9 +#define RXERR_HT_MPDU_TOTAL 10 +#define RXERR_HT_MPDU_OK 11 +#define RXERR_HT_MPDU_FAIL 12 +#define RXERR_RX_FULL_DROP 15 + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXENCENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +#define GPIOMUX_EN BIT(3) +#define GPIOSEL_GPIO 0 +#define GPIOSEL_PHYDBG 1 +#define GPIOSEL_BT 2 +#define GPIOSEL_WLANDBG 3 +#define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1))) + +#define HST_RDBUSY BIT(0) +#define CPU_WTBUSY BIT(1) + +#define IMR8190_DISABLED 0x0 +#define IMR_CPUERR BIT(5) +#define IMR_ATIMEND BIT(4) +#define IMR_TBDOK BIT(3) +#define IMR_TBDER BIT(2) +#define IMR_BCNDMAINT8 BIT(1) +#define IMR_BCNDMAINT7 BIT(0) +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_RXCMDOK BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_COMDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_HCCADOK BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define TPPOLL_BKQ BIT(0) +#define TPPOLL_BEQ BIT(1) +#define TPPOLL_VIQ BIT(2) +#define TPPOLL_VOQ BIT(3) +#define TPPOLL_BQ BIT(4) +#define TPPOLL_CQ BIT(5) +#define TPPOLL_MQ BIT(6) +#define TPPOLL_HQ BIT(7) +#define TPPOLL_HCCAQ BIT(8) +#define TPPOLL_STOPBK BIT(9) +#define TPPOLL_STOPBE BIT(10) +#define TPPOLL_STOPVI BIT(11) +#define TPPOLL_STOPVO BIT(12) +#define TPPOLL_STOPMGT BIT(13) +#define TPPOLL_STOPHIGH BIT(14) +#define TPPOLL_STOPHCCA BIT(15) +#define TPPOLL_SHIFT 8 + +#define CCX_CMD_CLM_ENABLE BIT(0) +#define CCX_CMD_NHM_ENABLE BIT(1) +#define CCX_CMD_FUNCTION_ENABLE BIT(8) +#define CCX_CMD_IGNORE_CCA BIT(9) +#define CCX_CMD_IGNORE_TXON BIT(10) +#define CCX_CLM_RESULT_READY BIT(16) +#define CCX_NHM_RESULT_READY BIT(16) +#define CCX_CMD_RESET 0x0 + + +#define HWSET_MAX_SIZE_92S 128 +#define EFUSE_MAX_SECTION 16 +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_VID 0x0A +#define EEPROM_DID 0x0C +#define EEPROM_SVID 0x0E +#define EEPROM_SMID 0x10 + +#define EEPROM_MAC_ADDR 0x12 +#define EEPROM_NODE_ADDRESS_BYTE_0 0x12 + +#define EEPROM_PWDIFF 0x54 + +#define EEPROM_TXPOWERBASE 0x50 +#define EEPROM_TX_PWR_INDEX_RANGE 28 + +#define EEPROM_TX_PWR_HT20_DIFF 0x62 +#define DEFAULT_HT20_TXPWR_DIFF 2 +#define EEPROM_TX_PWR_OFDM_DIFF 0x65 + +#define EEPROM_TXPWRGROUP 0x67 +#define EEPROM_REGULATORY 0x6D + +#define TX_PWR_SAFETY_CHK 0x6D +#define EEPROM_TXPWINDEX_CCK_24G 0x5D +#define EEPROM_TXPWINDEX_OFDM_24G 0x6B +#define EEPROM_HT2T_CH1_A 0x6c +#define EEPROM_HT2T_CH7_A 0x6d +#define EEPROM_HT2T_CH13_A 0x6e +#define EEPROM_HT2T_CH1_B 0x6f +#define EEPROM_HT2T_CH7_B 0x70 +#define EEPROM_HT2T_CH13_B 0x71 + +#define EEPROM_TSSI_A 0x74 +#define EEPROM_TSSI_B 0x75 + +#define EEPROM_RFIND_POWERDIFF 0x76 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 + +#define EEPROM_THERMALMETER 0x77 +#define EEPROM_BLUETOOTH_COEXIST 0x78 +#define EEPROM_BLUETOOTH_TYPE 0x4f + +#define EEPROM_OPTIONAL 0x78 +#define EEPROM_WOWLAN 0x78 + +#define EEPROM_CRYSTALCAP 0x79 +#define EEPROM_CHANNELPLAN 0x7B +#define EEPROM_VERSION 0x7C +#define EEPROM_CUSTOMID 0x7A +#define EEPROM_BOARDTYPE 0x7E + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define FW_DIG_DISABLE 0xfd00cc00 +#define FW_DIG_ENABLE 0xfd000000 +#define FW_DIG_HALT 0xfd000001 +#define FW_DIG_RESUME 0xfd000002 +#define FW_HIGH_PWR_DISABLE 0xfd000008 +#define FW_HIGH_PWR_ENABLE 0xfd000009 +#define FW_ADD_A2_ENTRY 0xfd000016 +#define FW_TXPWR_TRACK_ENABLE 0xfd000017 +#define FW_TXPWR_TRACK_DISABLE 0xfd000018 +#define FW_TXPWR_TRACK_THERMAL 0xfd000019 +#define FW_TXANT_SWITCH_ENABLE 0xfd000023 +#define FW_TXANT_SWITCH_DISABLE 0xfd000024 +#define FW_RA_INIT 0xfd000026 +#define FW_CTRL_DM_BY_DRIVER 0Xfd00002a +#define FW_RA_IOT_BG_COMB 0xfd000030 +#define FW_RA_IOT_N_COMB 0xfd000031 +#define FW_RA_REFRESH 0xfd0000a0 +#define FW_RA_UPDATE_MASK 0xfd0000a2 +#define FW_RA_DISABLE 0xfd0000a4 +#define FW_RA_ACTIVE 0xfd0000a6 +#define FW_RA_DISABLE_RSSI_MASK 0xfd0000ac +#define FW_RA_ENABLE_RSSI_MASK 0xfd0000ad +#define FW_RA_RESET 0xfd0000af +#define FW_DM_DISABLE 0xfd00aa00 +#define FW_IQK_ENABLE 0xf0000020 +#define FW_IQK_SUCCESS 0x0000dddd +#define FW_IQK_FAIL 0x0000ffff +#define FW_OP_FAILURE 0xffffffff +#define FW_TX_FEEDBACK_NONE 0xfb000000 +#define FW_TX_FEEDBACK_DTM_ENABLE (FW_TX_FEEDBACK_NONE | 0x1) +#define FW_TX_FEEDBACK_CCX_ENABL (FW_TX_FEEDBACK_NONE | 0x2) +#define FW_BB_RESET_ENABLE 0xff00000d +#define FW_BB_RESET_DISABLE 0xff00000e +#define FW_CCA_CHK_ENABLE 0xff000011 +#define FW_CCK_RESET_CNT 0xff000013 +#define FW_LPS_ENTER 0xfe000010 +#define FW_LPS_LEAVE 0xfe000011 +#define FW_INDIRECT_READ 0xf2000000 +#define FW_INDIRECT_WRITE 0xf2000001 +#define FW_CHAN_SET 0xf3000001 + +#define RFPC 0x5F +#define RCR_9356SEL BIT(6) +#define TCR_LRL_OFFSET 0 +#define TCR_SRL_OFFSET 8 +#define TCR_MXDMA_OFFSET 21 +#define TCR_SAT BIT(24) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 +#define RCR_ONLYERLPKT BIT(31) +#define CWR 0xDC +#define RETRYCTR 0xDE + +#define CPU_GEN_SYSTEM_RESET 0x00000001 + +#define CCX_COMMAND_REG 0x890 +#define CLM_PERIOD_REG 0x894 +#define NHM_PERIOD_REG 0x896 + +#define NHM_THRESHOLD0 0x898 +#define NHM_THRESHOLD1 0x899 +#define NHM_THRESHOLD2 0x89A +#define NHM_THRESHOLD3 0x89B +#define NHM_THRESHOLD4 0x89C +#define NHM_THRESHOLD5 0x89D +#define NHM_THRESHOLD6 0x89E +#define CLM_RESULT_REG 0x8D0 +#define NHM_RESULT_REG 0x8D4 +#define NHM_RPI_COUNTER0 0x8D8 +#define NHM_RPI_COUNTER1 0x8D9 +#define NHM_RPI_COUNTER2 0x8DA +#define NHM_RPI_COUNTER3 0x8DB +#define NHM_RPI_COUNTER4 0x8DC +#define NHM_RPI_COUNTER5 0x8DD +#define NHM_RPI_COUNTER6 0x8DE +#define NHM_RPI_COUNTER7 0x8DF + +#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) +#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 +#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNNM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDATATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RF_BB_CMD_ADDR 0x02c0 +#define RF_BB_CMD_DATA 0x02c4 + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c +#define RFPGA0_XC_HSSIPARAMETER1 0x830 +#define RFPGA0_XC_HSSIPARAMETER2 0x834 +#define RFPGA0_XD_HSSIPARAMETER1 0x838 +#define RFPGA0_XD_HSSIPARAMETER2 0x83c +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 +#define RFPGA0_XC_LSSIPARAMETER 0x848 +#define RFPGA0_XD_LSSIPARAMETER 0x84c + +#define RFPGA0_RFWAKEUP_PARAMETER 0x850 +#define RFPGA0_RFSLEEPUP_PARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 +#define RFPGA0_XC_RFINTERFACEOE 0x868 +#define RFPGA0_XD_RFINTERFACEOE 0x86c + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVERA_HSPI_READBACK 0x8b8 +#define TRANSCEIVERB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBALANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFO_AND_DAGC 0xc44 +#define ROFDM0_CCADROP_THRESHOLD 0xc48 +#define ROFDM0_ECCA_THRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXHP_PARAMETER 0xce0 +#define ROFDM0_TXPSEUDO_NOISE_WGT 0xce4 +#define ROFDM0_FRAME_SYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CFO 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTF_DET 0xd3c +#define ROFDM1_PSEUDO_NOISESTATEAB 0xd50 +#define ROFDM1_PSEUDO_NOISESTATECD 0xd54 +#define ROFDM1_RX_PSEUDO_NOISE_WGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORT_CFOAB 0xdac +#define ROFDM_SHORT_CFOCD 0xdb0 +#define ROFDM_LONG_CFOAB 0xdb4 +#define ROFDM_LONG_CFOCD 0xdb8 +#define ROFDM_TAIL_CFOAB 0xdbc +#define ROFDM_TAIL_CFOCD 0xdc0 +#define ROFDM_PW_MEASURE1 0xdc4 +#define ROFDM_PW_MEASURE2 0xdc8 +#define ROFDM_BW_REPORT 0xdcc +#define ROFDM_AGC_REPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIG_REPORT 0xddc + + +#define RTXAGC_RATE18_06 0xe00 +#define RTXAGC_RATE54_24 0xe04 +#define RTXAGC_CCK_MCS32 0xe08 +#define RTXAGC_MCS03_MCS00 0xe10 +#define RTXAGC_MCS07_MCS04 0xe14 +#define RTXAGC_MCS11_MCS08 0xe18 +#define RTXAGC_MCS15_MCS12 0xe1c + + +#define RF_AC 0x00 +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RF_CHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define BRFMOD 0x1 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define B3WIRE_DATALENGTH 0x800 +#define B3WIRE_ADDRESSLENGTH 0x400 + +#define BRFSI_RFENV 0x10 + +#define BLSSI_READADDRESS 0x7f800000 +#define BLSSI_READEDGE 0x80000000 +#define BLSSI_READBACK_DATA 0xfffff + +#define BADCLKPHASE 0x4000000 + +#define BCCK_SIDEBAND 0x10 + +#define BTX_AGCRATECCK 0x7f00 + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c new file mode 100644 index 000000000..17d29249a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + + +static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, + u8 chnl, u32 *ofdmbase, u32 *mcsbase, + u8 *p_final_pwridx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 pwrbase0, pwrbase1; + u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; + u8 i, pwrlevel[4]; + + for (i = 0; i < 2; i++) + pwrlevel[i] = p_pwrlevel[i]; + + /* We only care about the path A for legacy. */ + if (rtlefuse->eeprom_version < 2) { + pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_ht_txpowerdiff & 0xf); + } else { + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff + [RF90_PATH_A][chnl - 1]; + + /* For legacy OFDM, tx pwr always > HT OFDM pwr. + * We do not care Path B + * legacy OFDM pwr diff. NO BB register + * to notify HW. */ + pwrbase0 = pwrlevel[0] + legacy_pwrdiff; + } + + pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) | + pwrbase0; + *ofdmbase = pwrbase0; + + /* MCS rates */ + if (rtlefuse->eeprom_version >= 2) { + /* Check HT20 to HT40 diff */ + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + for (i = 0; i < 2; i++) { + /* rf-A, rf-B */ + /* HT 20<->40 pwr diff */ + ht20_pwrdiff = rtlefuse->txpwr_ht20diff + [i][chnl - 1]; + + if (ht20_pwrdiff < 8) /* 0~+7 */ + pwrlevel[i] += ht20_pwrdiff; + else /* index8-15=-8~-1 */ + pwrlevel[i] -= (16 - ht20_pwrdiff); + } + } + } + + /* use index of rf-A */ + pwrbase1 = pwrlevel[0]; + pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) | + pwrbase1; + *mcsbase = pwrbase1; + + /* The following is for Antenna + * diff from Ant-B to Ant-A */ + p_final_pwridx[0] = pwrlevel[0]; + p_final_pwridx[1] = pwrlevel[1]; + + switch (rtlefuse->eeprom_regulatory) { + case 3: + /* The following is for calculation + * of the power diff for Ant-B to Ant-A. */ + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + p_final_pwridx[0] += rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][ + chnl - 1]; + p_final_pwridx[1] += rtlefuse->pwrgroup_ht40 + [RF90_PATH_B][ + chnl - 1]; + } else { + p_final_pwridx[0] += rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][ + chnl - 1]; + p_final_pwridx[1] += rtlefuse->pwrgroup_ht20 + [RF90_PATH_B][ + chnl - 1]; + } + break; + default: + break; + } + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); + } +} + +static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, + u8 *p_final_pwridx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + s8 ant_pwr_diff = 0; + u32 u4reg_val = 0; + + if (rtlphy->rf_type == RF_2T2R) { + ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0]; + + /* range is from 7~-8, + * index = 0x0~0xf */ + if (ant_pwr_diff > 7) + ant_pwr_diff = 7; + if (ant_pwr_diff < -8) + ant_pwr_diff = -8; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", + ant_pwr_diff, ant_pwr_diff & 0xf); + + ant_pwr_diff &= 0xf; + } + + /* Antenna TX power difference */ + rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */ + rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */ + rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff); /* RF-B */ + + u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 | + rtlefuse->antenna_txpwdiff[1] << 4 | + rtlefuse->antenna_txpwdiff[0]; + + rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), + u4reg_val); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", + RFPGA0_TXGAINSTAGE, u4reg_val); +} + +static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, + u8 chnl, u8 index, + u32 pwrbase0, + u32 pwrbase1, + u32 *p_outwrite_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup, pwrdiff_limit[4]; + u32 writeval, customer_limit; + + /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */ + switch (rtlefuse->eeprom_regulatory) { + case 0: + /* Realtek better performance increase power diff + * defined by Realtek for large power */ + chnlgroup = 0; + + writeval = rtlphy->mcs_offset[chnlgroup][index] + + ((index < 2) ? pwrbase0 : pwrbase1); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "RTK better performance, writeval = 0x%x\n", writeval); + break; + case 1: + /* Realtek regulatory increase power diff defined + * by Realtek for regulatory */ + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + writeval = ((index < 2) ? pwrbase0 : pwrbase1); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Realtek regulatory, 40MHz, writeval = 0x%x\n", + writeval); + } else { + chnlgroup = 0; + + if (rtlphy->pwrgroup_cnt >= 3) { + if (chnl <= 3) + chnlgroup = 0; + else if (chnl >= 4 && chnl <= 8) + chnlgroup = 1; + else if (chnl > 8) + chnlgroup = 2; + if (rtlphy->pwrgroup_cnt == 4) + chnlgroup++; + } + + writeval = rtlphy->mcs_offset[chnlgroup][index] + + ((index < 2) ? + pwrbase0 : pwrbase1); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Realtek regulatory, 20MHz, writeval = 0x%x\n", + writeval); + } + break; + case 2: + /* Better regulatory don't increase any power diff */ + writeval = ((index < 2) ? pwrbase0 : pwrbase1); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Better regulatory, writeval = 0x%x\n", writeval); + break; + case 3: + /* Customer defined power diff. increase power diff + defined by customer. */ + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "customer's limit, 40MHz = 0x%x\n", + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]); + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "customer's limit, 20MHz = 0x%x\n", + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]); + } + + for (i = 0; i < 4; i++) { + pwrdiff_limit[i] = (u8)((rtlphy->mcs_offset + [chnlgroup][index] & (0x7f << (i * 8))) + >> (i * 8)); + + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwrdiff_limit[i] > + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]) { + pwrdiff_limit[i] = + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]; + } + } else { + if (pwrdiff_limit[i] > + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]) { + pwrdiff_limit[i] = + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]; + } + } + } + + customer_limit = (pwrdiff_limit[3] << 24) | + (pwrdiff_limit[2] << 16) | + (pwrdiff_limit[1] << 8) | + (pwrdiff_limit[0]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Customer's limit = 0x%x\n", customer_limit); + + writeval = customer_limit + ((index < 2) ? + pwrbase0 : pwrbase1); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Customer, writeval = 0x%x\n", writeval); + break; + default: + chnlgroup = 0; + writeval = rtlphy->mcs_offset[chnlgroup][index] + + ((index < 2) ? pwrbase0 : pwrbase1); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "RTK better performance, writeval = 0x%x\n", writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1) + writeval = 0x10101010; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TX_HIGH_PWR_LEVEL_LEVEL2) + writeval = 0x0; + + *p_outwrite_val = writeval; + +} + +static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw, + u8 index, u32 val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; + u8 i, rfa_pwr[4]; + u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0; + u32 writeval = val; + + /* If path A and Path B coexist, we must limit Path A tx power. + * Protect Path B pwr over or under flow. We need to calculate + * upper and lower bound of path A tx power. */ + if (rtlphy->rf_type == RF_2T2R) { + rf_pwr_diff = rtlefuse->antenna_txpwdiff[0]; + + /* Diff=-8~-1 */ + if (rf_pwr_diff >= 8) { + /* Prevent underflow!! */ + rfa_lower_bound = 0x10 - rf_pwr_diff; + /* if (rf_pwr_diff >= 0) Diff = 0-7 */ + } else { + rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff; + } + } + + for (i = 0; i < 4; i++) { + rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8)); + if (rfa_pwr[i] > RF6052_MAX_TX_PWR) + rfa_pwr[i] = RF6052_MAX_TX_PWR; + + /* If path A and Path B coexist, we must limit Path A tx power. + * Protect Path B pwr over or under flow. We need to calculate + * upper and lower bound of path A tx power. */ + if (rtlphy->rf_type == RF_2T2R) { + /* Diff=-8~-1 */ + if (rf_pwr_diff >= 8) { + /* Prevent underflow!! */ + if (rfa_pwr[i] < rfa_lower_bound) + rfa_pwr[i] = rfa_lower_bound; + /* Diff = 0-7 */ + } else if (rf_pwr_diff >= 1) { + /* Prevent overflow */ + if (rfa_pwr[i] > rfa_upper_bound) + rfa_pwr[i] = rfa_upper_bound; + } + } + + } + + writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) | + rfa_pwr[0]; + + rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval); +} + +void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw, + u8 *p_pwrlevel, u8 chnl) +{ + u32 writeval, pwrbase0, pwrbase1; + u8 index = 0; + u8 finalpwr_idx[4]; + + _rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1, + &finalpwr_idx[0]); + _rtl92s_set_antennadiff(hw, &finalpwr_idx[0]); + + for (index = 0; index < 6; index++) { + _rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index, + pwrbase0, pwrbase1, &writeval); + + _rtl92s_write_ofdm_powerreg(hw, index, writeval); + } +} + +void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 txagc = 0; + bool dont_inc_cck_or_turboscanoff = false; + + if (((rtlefuse->eeprom_version >= 2) && + (rtlefuse->txpwr_safetyflag == 1)) || + ((rtlefuse->eeprom_version >= 2) && + (rtlefuse->eeprom_regulatory != 0))) + dont_inc_cck_or_turboscanoff = true; + + if (mac->act_scanning) { + txagc = 0x3f; + if (dont_inc_cck_or_turboscanoff) + txagc = pwrlevel; + } else { + txagc = pwrlevel; + + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TX_HIGH_PWR_LEVEL_LEVEL1) + txagc = 0x10; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TX_HIGH_PWR_LEVEL_LEVEL2) + txagc = 0x0; + } + + if (txagc > RF6052_MAX_TX_PWR) + txagc = RF6052_MAX_TX_PWR; + + rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc); + +} + +bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4reg_val = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + /* Initialize RF */ + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + /* Store original RFENV control type */ + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4reg_val = rtl92s_phy_query_bb_reg(hw, + pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4reg_val = rtl92s_phy_query_bb_reg(hw, + pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + /* Set RF_ENV enable */ + rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe, + BRFSI_RFENV << 16, 0x1); + + /* Set RF_ENV output high */ + rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + + /* Set bit number of Address and Data for RF register */ + rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, + B3WIRE_ADDRESSLENGTH, 0x0); + rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, + B3WIRE_DATALENGTH, 0x0); + + /* Initialize RF from configuration file */ + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92s_phy_config_rf(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92s_phy_config_rf(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + /* Restore RFENV control type */ + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV, + u4reg_val); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, + u4reg_val); + break; + } + + if (!rtstatus) { + pr_err("Radio[%d] Fail!!\n", rfpath); + goto fail; + } + + } + + return rtstatus; + +fail: + return rtstatus; +} + +void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h new file mode 100644 index 000000000..a5959a228 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __INC_RTL92S_RF_H +#define __INC_RTL92S_RF_H + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) ; +void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, + u8 powerlevel); +void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw, + u8 *p_pwrlevel, u8 chnl); + +#endif + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c new file mode 100644 index 000000000..1cf801feb --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../base.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "hw.h" +#include "trx.h" +#include "led.h" + +#include + +static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /* ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + * */ + rtlpci->const_pci_aspm = 2; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 2; + + /* This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static void rtl92se_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_firmware *pfirmware = NULL; + char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + if (!firmware) { + pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; + goto exit; + } + if (firmware->size > rtlpriv->max_fw_size) { + pr_err("Firmware is too big!\n"); + rtlpriv->max_fw_size = 0; + release_firmware(firmware); + goto exit; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); +exit: + complete(&rtlpriv->firmware_loading_complete); +} + +static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; + u16 earlyrxthreshold = 7; + char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpriv->dm.useramask = true; + + /* compatible 5G band 91se just 2.4G band & smsp */ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->transmit_config = 0; + + rtlpci->receive_config = + RCR_APPFCS | + RCR_APWRMGT | + /*RCR_ADD3 |*/ + RCR_AMF | + RCR_ADF | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_AICV | + /* Accept ICV error, CRC32 Error */ + RCR_ACRC32 | + RCR_AB | + /* Accept Broadcast, Multicast */ + RCR_AM | + /* Accept Physical match */ + RCR_APM | + /* Accept Destination Address packets */ + /*RCR_AAP |*/ + RCR_APP_PHYST_STAFF | + /* Accept PHY status */ + RCR_APP_PHYST_RXFF | + (earlyrxthreshold << RCR_FIFO_OFFSET); + + rtlpci->irq_mask[0] = (u32) + (IMR_ROK | + IMR_VODOK | + IMR_VIDOK | + IMR_BEDOK | + IMR_BKDOK | + IMR_HCCADOK | + IMR_MGNTDOK | + IMR_COMDOK | + IMR_HIGHDOK | + IMR_BDOK | + IMR_RXCMDOK | + /*IMR_TIMEOUT0 |*/ + IMR_RDU | + IMR_RXFOVW | + IMR_BCNINT + /*| IMR_TXFOVW*/ + /*| IMR_TBDOK | + IMR_TBDER*/); + + rtlpci->irq_mask[1] = (u32) 0; + + rtlpci->shortretry_limit = 0x30; + rtlpci->longretry_limit = 0x30; + + rtlpci->first_init = true; + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("FW Power Save off (module option)\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 */ + rtl92s_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); + if (!rtlpriv->rtlhal.pfirmware) + return 1; + + rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 + + sizeof(struct fw_hdr); + pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" + "Loading firmware %s\n", fw_name); + /* request fw */ + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + return err; +} + +static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +static bool rtl92se_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, + u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl92se_get_desc(hw, entry, true, HW_DESC_OWN); + + if (own) + return false; + return true; +} + +static const struct rtl_hal_ops rtl8192se_hal_ops = { + .init_sw_vars = rtl92s_init_sw_vars, + .deinit_sw_vars = rtl92s_deinit_sw_vars, + .read_eeprom_info = rtl92se_read_eeprom_info, + .interrupt_recognized = rtl92se_interrupt_recognized, + .hw_init = rtl92se_hw_init, + .hw_disable = rtl92se_card_disable, + .hw_suspend = rtl92se_suspend, + .hw_resume = rtl92se_resume, + .enable_interrupt = rtl92se_enable_interrupt, + .disable_interrupt = rtl92se_disable_interrupt, + .set_network_type = rtl92se_set_network_type, + .set_chk_bssid = rtl92se_set_check_bssid, + .set_qos = rtl92se_set_qos, + .set_bcn_reg = rtl92se_set_beacon_related_registers, + .set_bcn_intv = rtl92se_set_beacon_interval, + .update_interrupt_mask = rtl92se_update_interrupt_mask, + .get_hw_reg = rtl92se_get_hw_reg, + .set_hw_reg = rtl92se_set_hw_reg, + .update_rate_tbl = rtl92se_update_hal_rate_tbl, + .fill_tx_desc = rtl92se_tx_fill_desc, + .fill_tx_cmddesc = rtl92se_tx_fill_cmddesc, + .query_rx_desc = rtl92se_rx_query_desc, + .set_channel_access = rtl92se_update_channel_access_setting, + .radio_onoff_checking = rtl92se_gpio_radio_on_off_checking, + .set_bw_mode = rtl92s_phy_set_bw_mode, + .switch_channel = rtl92s_phy_sw_chnl, + .dm_watchdog = rtl92s_dm_watchdog, + .scan_operation_backup = rtl92s_phy_scan_operation_backup, + .set_rf_power_state = rtl92s_phy_set_rf_power_state, + .led_control = rtl92se_led_control, + .set_desc = rtl92se_set_desc, + .get_desc = rtl92se_get_desc, + .is_tx_desc_closed = rtl92se_is_tx_desc_closed, + .tx_polling = rtl92se_tx_polling, + .enable_hw_sec = rtl92se_enable_hw_security_config, + .set_key = rtl92se_set_key, + .get_bbreg = rtl92s_phy_query_bb_reg, + .set_bbreg = rtl92s_phy_set_bb_reg, + .get_rfreg = rtl92s_phy_query_rf_reg, + .set_rfreg = rtl92s_phy_set_rf_reg, + .get_btc_status = rtl_btc_status_false, +}; + +static struct rtl_mod_params rtl92se_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = true, + .fwctrl_lps = false, + .aspm_support = 2, + .debug_level = 0, + .debug_mask = 0, +}; + +/* Because memory R/W bursting will cause system hang/crash + * for 92se, so we don't read back after every write action */ +static const struct rtl_hal_cfg rtl92se_hal_cfg = { + .bar_id = 1, + .write_readback = false, + .name = "rtl92s_pci", + .ops = &rtl8192se_hal_ops, + .mod_params = &rtl92se_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = SYS_CLKR, + .maps[MAC_RCR_AM] = RCR_AM, + .maps[MAC_RCR_AB] = RCR_AB, + .maps[MAC_RCR_ACRC32] = RCR_ACRC32, + .maps[MAC_RCR_ACF] = RCR_ACF, + .maps[MAC_RCR_AAP] = RCR_AAP, + .maps[MAC_HIMR] = INTA_MASK, + .maps[MAC_HIMRE] = INTA_MASK + 4, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = REG_EFUSE_CLK, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = 0, /* nouse for 8192se */ + .maps[EFUSE_FEN_ELDR] = 0, /* nouse for 8192se */ + .maps[EFUSE_LOADER_CLK_EN] = 0,/* nouse for 8192se */ + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_RWCAM, + .maps[WCAMI] = REG_WCAMI, + .maps[RCAMO] = REG_RCAMO, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECR, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_COMDOK] = IMR_COMDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, +}; + +static const struct pci_device_id rtl92se_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8173, rtl92se_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8174, rtl92se_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin"); + +module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl92se_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92se_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444); +module_param_named(aspm, rtl92se_mod_params.aspm_support, int, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl92se_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92se_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl92se_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c new file mode 100644 index 000000000..776e28e99 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c @@ -0,0 +1,607 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "table.h" + +u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH] = { + 0x01c, 0x07000000, + 0x800, 0x00040000, + 0x804, 0x00008003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005088, + 0x814, 0x020c3d10, + 0x818, 0x00200185, + 0x81c, 0x00000000, + 0x820, 0x01000000, + 0x824, 0x00390004, + 0x828, 0x01000000, + 0x82c, 0x00390004, + 0x830, 0x00000004, + 0x834, 0x00690200, + 0x838, 0x00000004, + 0x83c, 0x00690200, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x48484848, + 0x85c, 0x65a965a9, + 0x860, 0x0f7f0130, + 0x864, 0x0f7f0130, + 0x868, 0x0f7f0130, + 0x86c, 0x0f7f0130, + 0x870, 0x03000700, + 0x874, 0x03000300, + 0x878, 0x00020002, + 0x87c, 0x004f0201, + 0x880, 0xa8300ac1, + 0x884, 0x00000058, + 0x888, 0x00000008, + 0x88c, 0x00000004, + 0x890, 0x00000000, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x8b0, 0x00000000, + 0x8e0, 0x00000000, + 0x8e4, 0x00000000, + 0xe00, 0x30333333, + 0xe04, 0x2a2d2e2f, + 0xe08, 0x00003232, + 0xe10, 0x30333333, + 0xe14, 0x2a2d2e2f, + 0xe18, 0x30333333, + 0xe1c, 0x2a2d2e2f, + 0xe30, 0x01007c00, + 0xe34, 0x01004800, + 0xe38, 0x1000dc1f, + 0xe3c, 0x10008c1f, + 0xe40, 0x021400a0, + 0xe44, 0x281600a0, + 0xe48, 0xf8000001, + 0xe4c, 0x00002910, + 0xe50, 0x01007c00, + 0xe54, 0x01004800, + 0xe58, 0x1000dc1f, + 0xe5c, 0x10008c1f, + 0xe60, 0x021400a0, + 0xe64, 0x281600a0, + 0xe6c, 0x00002910, + 0xe70, 0x31ed92fb, + 0xe74, 0x361536fb, + 0xe78, 0x361536fb, + 0xe7c, 0x361536fb, + 0xe80, 0x361536fb, + 0xe84, 0x000d92fb, + 0xe88, 0x000d92fb, + 0xe8c, 0x31ed92fb, + 0xed0, 0x31ed92fb, + 0xed4, 0x31ed92fb, + 0xed8, 0x000d92fb, + 0xedc, 0x000d92fb, + 0xee0, 0x000d92fb, + 0xee4, 0x015e5448, + 0xee8, 0x21555448, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x01121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff0008, + 0xa08, 0x8ccd8300, + 0xa0c, 0x2e62120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x10d30000, + 0xc00, 0x40071d40, + 0xc04, 0x00a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08000000, + 0xc1c, 0x40000100, + 0xc20, 0x08000000, + 0xc24, 0x40000100, + 0xc28, 0x08000000, + 0xc2c, 0x40000100, + 0xc30, 0x6de9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a979764, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020000, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x433c0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x69543420, + 0xc64, 0x433c0094, + 0xc68, 0x69543420, + 0xc6c, 0x433c0094, + 0xc70, 0x2c7f000d, + 0xc74, 0x0186155b, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x20000080, + 0xc8c, 0x20200000, + 0xc90, 0x40000100, + 0xc94, 0x00000000, + 0xc98, 0x40000100, + 0xc9c, 0x00000000, + 0xca0, 0x00492492, + 0xca4, 0x00000000, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00000750, + 0xd04, 0x00000403, + 0xd08, 0x0000907f, + 0xd0c, 0x00000001, + 0xd10, 0xa0633333, + 0xd14, 0x33333c63, + 0xd18, 0x6a8f5b6b, + 0xd1c, 0x00000000, + 0xd20, 0x00000000, + 0xd24, 0x00000000, + 0xd28, 0x00000000, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x00000000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x024dbd02, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x00518a3c, + 0xd68, 0x00002101, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH] = { + 0x844, 0xffffffff, 0x00010000, + 0x804, 0x0000000f, 0x00000001, + 0x824, 0x00f0000f, 0x00300004, + 0x82c, 0x00f0000f, 0x00100002, + 0x870, 0x04000000, 0x00000001, + 0x864, 0x00000400, 0x00000000, + 0x878, 0x000f000f, 0x00000002, + 0xe74, 0x0f000000, 0x00000002, + 0xe78, 0x0f000000, 0x00000002, + 0xe7c, 0x0f000000, 0x00000002, + 0xe80, 0x0f000000, 0x00000002, + 0x90c, 0x000000ff, 0x00000011, + 0xc04, 0x000000ff, 0x00000011, + 0xd04, 0x0000000f, 0x00000001, + 0x1f4, 0xffff0000, 0x00007777, + 0x234, 0xf8000000, 0x0000000a, +}; + +u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH] = { + 0x804, 0x0000000f, 0x00000003, + 0x824, 0x00f0000f, 0x00300004, + 0x82c, 0x00f0000f, 0x00300002, + 0x870, 0x04000000, 0x00000001, + 0x864, 0x00000400, 0x00000000, + 0x878, 0x000f000f, 0x00000002, + 0xe74, 0x0f000000, 0x00000002, + 0xe78, 0x0f000000, 0x00000002, + 0xe7c, 0x0f000000, 0x00000002, + 0xe80, 0x0f000000, 0x00000002, + 0x90c, 0x000000ff, 0x00000011, + 0xc04, 0x000000ff, 0x00000033, + 0xd04, 0x0000000f, 0x00000003, + 0x1f4, 0xffff0000, 0x00007777, + 0x234, 0xf8000000, 0x0000000a, +}; + +u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x06090909, + 0xe04, 0xffffffff, 0x00030406, + 0xe08, 0x0000ff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0e, + 0xe14, 0xffffffff, 0x04070809, + 0xe18, 0xffffffff, 0x0a0c0d0e, + 0xe1c, 0xffffffff, 0x04070809, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0xe10, 0xffffffff, 0x02040404, + 0xe14, 0xffffffff, 0x00000002, + 0xe18, 0xffffffff, 0x02040404, + 0xe1c, 0xffffffff, 0x00000002, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0xe10, 0xffffffff, 0x02040404, + 0xe14, 0xffffffff, 0x00000002, + 0xe18, 0xffffffff, 0x02040404, + 0xe1c, 0xffffffff, 0x00000002, + 0xe00, 0xffffffff, 0x02020202, + 0xe04, 0xffffffff, 0x00020202, + 0xe08, 0x0000ff00, 0x00000000, + 0xe10, 0xffffffff, 0x02020202, + 0xe14, 0xffffffff, 0x00000002, + 0xe18, 0xffffffff, 0x02020202, + 0xe1c, 0xffffffff, 0x00000002, +}; + +u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00030250, + 0x002, 0x00010000, + 0x010, 0x0008000f, + 0x011, 0x000231fc, + 0x010, 0x000c000f, + 0x011, 0x0003f9f8, + 0x010, 0x0002000f, + 0x011, 0x00020101, + 0x014, 0x0001093e, + 0x014, 0x0009093e, + 0x015, 0x0000f8f4, + 0x017, 0x000f6500, + 0x01a, 0x00013056, + 0x01b, 0x00060000, + 0x01c, 0x00000300, + 0x01e, 0x00031059, + 0x021, 0x00054000, + 0x022, 0x0000083c, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00022583, + 0x026, 0x0000f200, + 0x027, 0x000eacf1, + 0x028, 0x0009bd54, + 0x029, 0x00004582, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x0000000a, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000709, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x00000709, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000050b, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066623, + 0x02c, 0x0000001a, + 0x02a, 0x000e4000, + 0x030, 0x00020000, + 0x031, 0x000b9631, + 0x032, 0x0000130d, + 0x033, 0x00000187, + 0x013, 0x00019e6c, + 0x013, 0x00015e94, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x01e, 0x0003105b, + 0x0fe, 0x00000000, + 0x000, 0x00030159, + 0x010, 0x0004000f, + 0x011, 0x000203f9, +}; + +u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00001041, + 0x002, 0x00011000, + 0x005, 0x00080fc0, + 0x007, 0x000fc803, + 0x013, 0x00017cb0, + 0x013, 0x00011cc0, + 0x013, 0x0000dc60, + 0x013, 0x00008c60, + 0x013, 0x00004450, + 0x013, 0x00000020, +}; + +u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00001041, + 0x002, 0x00011000, + 0x005, 0x00080fc0, + 0x007, 0x000fc803, +}; + +u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH] = { + 0x020, 0x00000035, + 0x048, 0x0000000e, + 0x049, 0x000000f0, + 0x04a, 0x00000077, + 0x04b, 0x00000083, + 0x0b5, 0x00000021, + 0x0dc, 0x000000ff, + 0x0dd, 0x000000ff, + 0x0de, 0x000000ff, + 0x0df, 0x000000ff, + 0x116, 0x00000000, + 0x117, 0x00000000, + 0x118, 0x00000000, + 0x119, 0x00000000, + 0x11a, 0x00000000, + 0x11b, 0x00000000, + 0x11c, 0x00000000, + 0x11d, 0x00000000, + 0x160, 0x0000000b, + 0x161, 0x0000000b, + 0x162, 0x0000000b, + 0x163, 0x0000000b, + 0x164, 0x0000000b, + 0x165, 0x0000000b, + 0x166, 0x0000000b, + 0x167, 0x0000000b, + 0x168, 0x0000000b, + 0x169, 0x0000000b, + 0x16a, 0x0000000b, + 0x16b, 0x0000000b, + 0x16c, 0x0000000b, + 0x16d, 0x0000000b, + 0x16e, 0x0000000b, + 0x16f, 0x0000000b, + 0x170, 0x0000000b, + 0x171, 0x0000000b, + 0x172, 0x0000000b, + 0x173, 0x0000000b, + 0x174, 0x0000000b, + 0x175, 0x0000000b, + 0x176, 0x0000000b, + 0x177, 0x0000000b, + 0x178, 0x0000000b, + 0x179, 0x0000000b, + 0x17a, 0x0000000b, + 0x17b, 0x0000000b, + 0x17c, 0x0000000b, + 0x17d, 0x0000000b, + 0x17e, 0x0000000b, + 0x17f, 0x0000000b, + 0x236, 0x0000000c, + 0x503, 0x00000022, + 0x560, 0x00000000, +}; + +u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH] = { + 0xc78, 0x7f000001, + 0xc78, 0x7f010001, + 0xc78, 0x7e020001, + 0xc78, 0x7d030001, + 0xc78, 0x7c040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6d150001, + 0xc78, 0x6c160001, + 0xc78, 0x6b170001, + 0xc78, 0x6a180001, + 0xc78, 0x6a190001, + 0xc78, 0x691a0001, + 0xc78, 0x681b0001, + 0xc78, 0x671c0001, + 0xc78, 0x661d0001, + 0xc78, 0x651e0001, + 0xc78, 0x641f0001, + 0xc78, 0x63200001, + 0xc78, 0x4c210001, + 0xc78, 0x4b220001, + 0xc78, 0x4a230001, + 0xc78, 0x49240001, + 0xc78, 0x48250001, + 0xc78, 0x47260001, + 0xc78, 0x46270001, + 0xc78, 0x45280001, + 0xc78, 0x44290001, + 0xc78, 0x2c2a0001, + 0xc78, 0x2b2b0001, + 0xc78, 0x2a2c0001, + 0xc78, 0x292d0001, + 0xc78, 0x282e0001, + 0xc78, 0x272f0001, + 0xc78, 0x26300001, + 0xc78, 0x25310001, + 0xc78, 0x24320001, + 0xc78, 0x23330001, + 0xc78, 0x22340001, + 0xc78, 0x09350001, + 0xc78, 0x08360001, + 0xc78, 0x07370001, + 0xc78, 0x06380001, + 0xc78, 0x05390001, + 0xc78, 0x043a0001, + 0xc78, 0x033b0001, + 0xc78, 0x023c0001, + 0xc78, 0x013d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7f400001, + 0xc78, 0x7f410001, + 0xc78, 0x7e420001, + 0xc78, 0x7d430001, + 0xc78, 0x7c440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6f520001, + 0xc78, 0x6e530001, + 0xc78, 0x6d540001, + 0xc78, 0x6d550001, + 0xc78, 0x6c560001, + 0xc78, 0x6b570001, + 0xc78, 0x6a580001, + 0xc78, 0x6a590001, + 0xc78, 0x695a0001, + 0xc78, 0x685b0001, + 0xc78, 0x675c0001, + 0xc78, 0x665d0001, + 0xc78, 0x655e0001, + 0xc78, 0x645f0001, + 0xc78, 0x63600001, + 0xc78, 0x4c610001, + 0xc78, 0x4b620001, + 0xc78, 0x4a630001, + 0xc78, 0x49640001, + 0xc78, 0x48650001, + 0xc78, 0x47660001, + 0xc78, 0x46670001, + 0xc78, 0x45680001, + 0xc78, 0x44690001, + 0xc78, 0x2c6a0001, + 0xc78, 0x2b6b0001, + 0xc78, 0x2a6c0001, + 0xc78, 0x296d0001, + 0xc78, 0x286e0001, + 0xc78, 0x276f0001, + 0xc78, 0x26700001, + 0xc78, 0x25710001, + 0xc78, 0x24720001, + 0xc78, 0x23730001, + 0xc78, 0x22740001, + 0xc78, 0x09750001, + 0xc78, 0x08760001, + 0xc78, 0x07770001, + 0xc78, 0x06780001, + 0xc78, 0x05790001, + 0xc78, 0x047a0001, + 0xc78, 0x037b0001, + 0xc78, 0x027c0001, + 0xc78, 0x017d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3000001e, + 0xc78, 0x3001001e, + 0xc78, 0x3002001e, + 0xc78, 0x3003001e, + 0xc78, 0x3004001e, + 0xc78, 0x3405001e, + 0xc78, 0x3806001e, + 0xc78, 0x3e07001e, + 0xc78, 0x3e08001e, + 0xc78, 0x4409001e, + 0xc78, 0x460a001e, + 0xc78, 0x480b001e, + 0xc78, 0x480c001e, + 0xc78, 0x4e0d001e, + 0xc78, 0x560e001e, + 0xc78, 0x5a0f001e, + 0xc78, 0x5e10001e, + 0xc78, 0x6211001e, + 0xc78, 0x6c12001e, + 0xc78, 0x7213001e, + 0xc78, 0x7214001e, + 0xc78, 0x7215001e, + 0xc78, 0x7216001e, + 0xc78, 0x7217001e, + 0xc78, 0x7218001e, + 0xc78, 0x7219001e, + 0xc78, 0x721a001e, + 0xc78, 0x721b001e, + 0xc78, 0x721c001e, + 0xc78, 0x721d001e, + 0xc78, 0x721e001e, + 0xc78, 0x721f001e, +}; + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h new file mode 100644 index 000000000..4fd09f11f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __INC_HAL8192SE_FW_IMG_H +#define __INC_HAL8192SE_FW_IMG_H + +#include + +/*Created on 2010/ 4/12, 5:56*/ + +#define PHY_REG_2T2RARRAYLENGTH 372 +extern u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH]; +#define PHY_CHANGETO_1T1RARRAYLENGTH 48 +extern u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH]; +#define PHY_CHANGETO_1T2RARRAYLENGTH 45 +extern u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH]; +#define PHY_REG_ARRAY_PGLENGTH 84 +extern u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH]; +#define RADIOA_1T_ARRAYLENGTH 202 +extern u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH]; +#define RADIOB_ARRAYLENGTH 22 +extern u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH]; +#define RADIOB_GM_ARRAYLENGTH 10 +extern u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 106 +extern u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_ARRAYLENGTH 320 +extern u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH]; + +#endif + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c new file mode 100644 index 000000000..f104cdb64 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "fw.h" +#include "trx.h" +#include "led.h" + +static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + if (ieee80211_is_nullfunc(fc)) + return QSLT_HIGH; + + /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use + * queue V0 at priority 7; however, the RTL8192SE appears to have + * that queue at priority 6 + */ + if (skb->priority == 7) + return QSLT_VO; + return skb->priority; +} + +static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, __le32 *pdesc, + struct rx_fwinfo *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_sts_cck_8192s_t *cck_buf; + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstats->is_cck; + + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->packet_beacon = packet_beacon; + pstats->rx_mimo_sig_qual[0] = -1; + pstats->rx_mimo_sig_qual[1] = -1; + + if (is_cck) { + u8 report, cck_highpwr; + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200); + else + cck_highpwr = false; + + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -40 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -20 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -2 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 14 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + + /* CCK gain is smaller than OFDM/MCS gain, */ + /* so we add gain diff by experiences, the val is 6 */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same gain index with OFDM. */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + + if (packet_match_bssid) { + u8 sq; + if (pstats->rx_pwdb_all > 40) { + sq = 100; + } else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstats->signalquality = sq; + pstats->rx_mimo_sig_qual[0] = sq; + pstats->rx_mimo_sig_qual[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & + 0x3f) * 2) - 110; + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + + if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 && + pstats->rate <= DESC_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (packet_match_bssid) { + if (i == 0) + pstats->signalquality = (u8)(evm & + 0xff); + pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); + } + } + } + + if (is_cck) + pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = (u8) (rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, struct rtl_stats *pstats, + __le32 *pdesc, struct rx_fwinfo *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + __le16 fc; + u16 type, cfc; + bool packet_matchbssid, packet_toself, packet_beacon = false; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + cfc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + + packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && + ether_addr_equal(mac->bssid, + (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + + packet_toself = packet_matchbssid && + ether_addr_equal(praddr, rtlefuse->dev_addr); + + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + + _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, packet_beacon); + rtl_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rx_fwinfo *p_drvinfo; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = (u32)get_rx_status_desc_phy_status(pdesc); + struct ieee80211_hdr *hdr; + + stats->length = (u16)get_rx_status_desc_pkt_len(pdesc); + stats->rx_drvinfo_size = (u8)get_rx_status_desc_drvinfo_size(pdesc) * 8; + stats->rx_bufshift = (u8)(get_rx_status_desc_shift(pdesc) & 0x03); + stats->icv = (u16)get_rx_status_desc_icv(pdesc); + stats->crc = (u16)get_rx_status_desc_crc32(pdesc); + stats->hwerror = (u16)(stats->crc | stats->icv); + stats->decrypted = !get_rx_status_desc_swdec(pdesc); + + stats->rate = (u8)get_rx_status_desc_rx_mcs(pdesc); + stats->shortpreamble = (u16)get_rx_status_desc_splcp(pdesc); + stats->isampdu = (bool)(get_rx_status_desc_paggr(pdesc) == 1); + stats->isfirst_ampdu = (bool)((get_rx_status_desc_paggr(pdesc) == 1) && + (get_rx_status_desc_faggr(pdesc) == 1)); + stats->timestamp_low = get_rx_status_desc_tsfl(pdesc); + stats->rx_is40mhzpacket = (bool)get_rx_status_desc_bw(pdesc); + stats->is_ht = (bool)get_rx_status_desc_rx_ht(pdesc); + stats->is_cck = SE_RX_HAL_IS_CCK_RATE(pdesc); + + if (stats->hwerror) + return false; + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + if (stats->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (stats->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (stats->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set stats->decrypted true, if it finds the + * frame is open data frame or mgmt frame, + * hw will not decrypt robust managment frame + * for IEEE80211w but still set stats->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it */ + if (stats->decrypted) { + hdr = (struct ieee80211_hdr *)(skb->data + + stats->rx_drvinfo_size + stats->rx_bufshift); + + if ((_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag &= ~RX_FLAG_DECRYPTED; + else + rx_status->flag |= RX_FLAG_DECRYPTED; + } + + rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht, + false, stats->rate); + + rx_status->mactime = stats->timestamp_low; + if (phystatus) { + p_drvinfo = (struct rx_fwinfo *)(skb->data + + stats->rx_bufshift); + _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, + p_drvinfo); + } + + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->recvsignalpower + 10; + + return true; +} + +void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + __le32 *pdesc = (__le32 *)pdesc8; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 reserved_macid = 0; + u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG))); + bool lastseg = (!(hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS))); + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + u8 bw_40 = 0; + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; + } + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + + if (firstseg) { + if (rtlpriv->dm.useramask) { + /* set txdesc macId */ + if (ptcb_desc->mac_id < 32) { + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + reserved_macid |= ptcb_desc->mac_id; + } + } + set_tx_desc_rsvd_macid(pdesc, reserved_macid); + + set_tx_desc_txht(pdesc, ((ptcb_desc->hw_rate >= + DESC_RATEMCS0) ? 1 : 0)); + + if (rtlhal->version == VERSION_8192S_ACUT) { + if (ptcb_desc->hw_rate == DESC_RATE1M || + ptcb_desc->hw_rate == DESC_RATE2M || + ptcb_desc->hw_rate == DESC_RATE5_5M || + ptcb_desc->hw_rate == DESC_RATE11M) { + ptcb_desc->hw_rate = DESC_RATE12M; + } + } + + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + + if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) + set_tx_desc_tx_short(pdesc, 0); + + /* Aggregation related */ + if (info->flags & IEEE80211_TX_CTL_AMPDU) + set_tx_desc_agg_enable(pdesc, 1); + + /* For AMPDU, we must insert SSN into TX_DESC */ + set_tx_desc_seq(pdesc, seq_number); + + /* Protection mode related */ + /* For 92S, if RTS/CTS are set, HW will execute RTS. */ + /* We choose only one protection mode to execute */ + set_tx_desc_rts_enable(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? + 1 : 0)); + set_tx_desc_cts_enable(pdesc, ((ptcb_desc->cts_enable) ? + 1 : 0)); + set_tx_desc_rts_stbc(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_bandwidth(pdesc, 0); + set_tx_desc_rts_sub_carrier(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, ((ptcb_desc->rts_rate <= + DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) + : (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + + /* Set Bandwidth and sub-channel settings. */ + if (bw_40) { + if (ptcb_desc->packet_bw) { + set_tx_desc_tx_bandwidth(pdesc, 1); + /* use duplicated mode */ + set_tx_desc_tx_sub_carrier(pdesc, 0); + } else { + set_tx_desc_tx_bandwidth(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_tx_bandwidth(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + /* 3 Fill necessary field in First Descriptor */ + /*DWORD 0*/ + set_tx_desc_linip(pdesc, 0); + set_tx_desc_offset(pdesc, 32); + set_tx_desc_pkt_size(pdesc, (u16)skb->len); + + /*DWORD 1*/ + set_tx_desc_ra_brsr_id(pdesc, ptcb_desc->ratr_index); + + /* Fill security related */ + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf; + + keyconf = info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x2); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + + } + } + + /* Set Packet ID */ + set_tx_desc_packet_id(pdesc, 0); + + /* We will assign magement queue to BK. */ + set_tx_desc_queue_sel(pdesc, fw_qsel); + + /* Alwasy enable all rate fallback range */ + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + + /* Fix: I don't kown why hw use 6.5M to tx when set it */ + set_tx_desc_user_rate(pdesc, + ptcb_desc->use_driver_rate ? 1 : 0); + + /* Set NON_QOS bit. */ + if (!ieee80211_is_data_qos(fc)) + set_tx_desc_non_qos(pdesc, 1); + + } + + /* Fill fields that are required to be initialized + * in all of the descriptors */ + /*DWORD 0 */ + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + + /* DWORD 7 */ + set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len); + + /* DOWRD 8 */ + set_tx_desc_tx_buffer_address(pdesc, mapping); + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb); + __le32 *pdesc = (__le32 *)pdesc8; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + /* Clear all status */ + CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S); + + /* This bit indicate this packet is used for FW download. */ + if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) { + /* For firmware download we only need to set LINIP */ + set_tx_desc_linip(pdesc, tcb_desc->last_inipkt); + + /* 92SE must set as 1 for firmware download HW DMA error */ + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + /* 92SE need not to set TX packet size when firmware download */ + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + set_tx_desc_tx_buffer_address(pdesc, mapping); + + wmb(); + set_tx_desc_own(pdesc, 1); + } else { /* H2C Command Desc format (Host TXCMD) */ + /* 92SE must set as 1 for firmware download HW DMA error */ + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_offset(pdesc, 0x20); + + /* Buffer size + command header */ + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + /* Fixed queue of H2C command */ + set_tx_desc_queue_sel(pdesc, 0x13); + + le32p_replace_bits((__le32 *)skb->data, rtlhal->h2c_txcmd_seq, + GENMASK(30, 24)); + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + set_tx_desc_tx_buffer_address(pdesc, mapping); + + wmb(); + set_tx_desc_own(pdesc, 1); + + } +} + +void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx, + u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + wmb(); + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8192se: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + wmb(); + set_rx_status_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_status__desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_status_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_status_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8192se: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl92se_get_desc(struct ieee80211_hw *hw, + u8 *desc8, bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *desc = (__le32 *)desc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(desc); + break; + default: + WARN_ONCE(true, "rtl8192se: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_status_desc_own(desc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_status_desc_pkt_len(desc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_status_desc_buff_addr(desc); + break; + default: + WARN_ONCE(true, "rtl8192se: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue)); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h new file mode 100644 index 000000000..40291a6a1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __REALTEK_PCI92SE_TRX_H__ +#define __REALTEK_PCI92SE_TRX_H__ + +void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc, + u8 *pbd_desc_tx, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, u8 *pdesc, + struct sk_buff *skb); +void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); +u64 rtl92se_get_desc(struct ieee80211_hw *hw, + u8 *desc, bool istx, u8 desc_name); +void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile new file mode 100644 index 000000000..d12387072 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8723ae-objs := \ + dm.o \ + fw.o \ + hal_btc.o \ + hal_bt_coexist.o\ + hw.o \ + led.o \ + phy.o \ + pwrseq.o \ + rf.o \ + sw.o \ + table.o \ + trx.o \ + + +obj-$(CONFIG_RTL8723AE) += rtl8723ae.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h new file mode 100644 index 000000000..20a67dcc5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_BTC_H__ +#define __RTL8723E_BTC_H__ + +#include "../wifi.h" +#include "hal_bt_coexist.h" + +struct bt_coexist_c2h_info { + u8 no_parse_c2h; + u8 has_c2h; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h new file mode 100644 index 000000000..84505a850 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_DEF_H__ +#define __RTL8723E_DEF_H__ + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) +#define CHIP_BONDING_92C_1T2R 0x1 + +#define CHIP_8723 BIT(0) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(12)|BIT(13))) +#define E_CUT_VERSION BIT(14) +#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) + +/* MASK */ +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + +/* Get element */ +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\ + true : false) +#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? \ + true : false) +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? false : true) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\ + ? true : false) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\ + ? true : false) +#define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version)) ? \ + true : false) + +#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version))\ + ? ((GET_CVID_CUT_VERSION(version)) ? \ + false : true) : false) +#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version))\ + ? ((GET_CVID_CUT_VERSION(version)) ? \ + false : true) : false) +#define IS_VENDOR_8723A_B_CUT(version) ((IS_8723_SERIES(version))\ + ? ((GET_CVID_CUT_VERSION(version) == \ + B_CUT_VERSION) ? true : false) : false) +#define IS_81XXC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version))\ + ? ((GET_CVID_CUT_VERSION(version) == \ + B_CUT_VERSION) ? true : false) : false) + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_policy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc8723e_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, + DESC92C_RATEMCS15_SG = 0x1c, + DESC92C_RATEMCS32 = 0x20, +}; + +struct phy_sts_cck_8723e_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8723e { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c new file mode 100644 index 000000000..0ff8e355c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c @@ -0,0 +1,840 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "hal_btc.h" + +static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + long rssi_val_min = 0; + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION && + rtlpriv->link_info.bcn_rx_inperiod == 0) + return 0; + + if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && + (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undec_sm_pwdb > + rtlpriv->dm.undec_sm_pwdb) ? + rtlpriv->dm.undec_sm_pwdb : + rtlpriv->dm.entry_min_undec_sm_pwdb; + else + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || + dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_digtable->curmultista_cstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + + return (u8) rssi_val_min; +} + +static void rtl8723e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + u8 value_igi = dm_digtable->cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = 0x32; + + dm_digtable->cur_igvalue = value_igi; + rtl8723e_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) { + if ((dm_digtable->back_val - 2) < + dm_digtable->back_range_min) + dm_digtable->back_val = + dm_digtable->back_range_min; + else + dm_digtable->back_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) { + if ((dm_digtable->back_val + 2) > + dm_digtable->back_range_max) + dm_digtable->back_val = + dm_digtable->back_range_max; + else + dm_digtable->back_val += 2; + } + + if ((dm_digtable->rssi_val_min + 10 - dm_digtable->back_val) > + dm_digtable->rx_gain_max) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_max; + else if ((dm_digtable->rssi_val_min + 10 - + dm_digtable->back_val) < dm_digtable->rx_gain_min) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_min; + else + dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 - + dm_digtable->back_val; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "rssi_val_min = %x back_val %x\n", + dm_digtable->rssi_val_min, dm_digtable->back_val); + + rtl8723e_dm_write_dig(hw); +} + +static void rtl8723e_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 binitialized; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; + bool multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + multi_sta = true; + + if (!multi_sta || (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { + binitialized = false; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (!binitialized) { + binitialized = true; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable->cur_igvalue = 0x20; + rtl8723e_dm_write_dig(hw); + } + + if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable->rssi_lowthresh) && + (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable->dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable->cur_igvalue = 0x20; + rtl8723e_dm_write_dig(hw); + } + + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable->rssi_highthresh) { + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable->cur_igvalue = 0x20; + rtl8723e_dm_write_dig(hw); + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "curmultista_cstate = %x dig_ext_port_stage %x\n", + dm_digtable->curmultista_cstate, + dm_digtable->dig_ext_port_stage); +} + +static void rtl8723e_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "presta_cstate = %x, cursta_cstate = %x\n", + dm_digtable->presta_cstate, + dm_digtable->cursta_cstate); + + if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || + dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || + dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + dm_digtable->rssi_val_min = + rtl8723e_dm_initial_gain_min_pwdb(hw); + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable->rssi_val_min = 0; + dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->cur_igvalue = 0x20; + dm_digtable->pre_igvalue = 0; + rtl8723e_dm_write_dig(hw); + } +} + +static void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw); + + if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (dm_digtable->rssi_val_min <= 25) + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } else { + if (dm_digtable->rssi_val_min <= 20) + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable->cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } + } else { + dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { + if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) + dm_digtable->cur_cck_fa_state = + CCK_FA_STAGE_HIGH; + else + dm_digtable->cur_cck_fa_state = + CCK_FA_STAGE_LOW; + if (dm_digtable->pre_cck_fa_state != + dm_digtable->cur_cck_fa_state) { + if (dm_digtable->cur_cck_fa_state == + CCK_FA_STAGE_LOW) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0xcd); + + dm_digtable->pre_cck_fa_state = + dm_digtable->cur_cck_fa_state; + } + + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); + + } else { + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); + dm_digtable->pre_cck_fa_state = 0; + dm_digtable->cur_cck_fa_state = 0; + + } + dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); + +} + +static void rtl8723e_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (mac->act_scanning) + return; + + if (mac->link_state >= MAC80211_LINKED) + dm_digtable->cursta_cstate = DIG_STA_CONNECT; + else + dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; + + rtl8723e_dm_initial_gain_sta(hw); + rtl8723e_dm_initial_gain_multi_sta(hw); + rtl8723e_dm_cck_packet_detection_thresh(hw); + + dm_digtable->presta_cstate = dm_digtable->cursta_cstate; + +} + +static void rtl8723e_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (!rtlpriv->dm.dm_initialgain_enable) + return; + if (!dm_digtable->dig_enable_flag) + return; + + rtl8723e_dm_ctrl_initgain_by_twoport(hw); + +} + +static void rtl8723e_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undec_sm_pwdb = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); + } else { + undec_sm_pwdb = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + } else { + undec_sm_pwdb = + rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); + } + + if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); + } else if ((undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undec_sm_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); + } else if (undec_sm_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "TXHIGHPWRLEVEL_NORMAL\n"); + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); + rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +void rtl8723e_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, + dm_digtable->back_val); + + if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable->cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable->cur_igvalue); + + dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; + } +} + +static void rtl8723e_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ +} + +static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + static u32 last_bt_edca_ul; + static u32 last_bt_edca_dl; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + bool bt_change_edca = false; + + if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) || + (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) { + rtlpriv->dm.current_turbo_edca = false; + last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul; + last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl; + } + + if (rtlpriv->btcoexist.bt_edca_ul != 0) { + edca_be_ul = rtlpriv->btcoexist.bt_edca_ul; + bt_change_edca = true; + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + return; + } + if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting))) { + + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + rtlpriv->dm.current_turbo_edca = false; + } + } + + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl8723e_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackinginit = false; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); +} + +static void rtl8723e_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl8723e_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +void rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + return; +} + +void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + +} + +static void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &rtlpriv->ra; + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + struct ieee80211_sta *sta = NULL; + + if (is_hal_stop(rtlhal)) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + " driver is going to unload\n"); + return; + } + + if (!rtlpriv->dm.useramask) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + " driver does not control rate adaptive mask\n"); + return; + } + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 60; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->link_info.bcn_rx_inperiod == 0) + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + default: + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + break; + case DM_RATR_STA_MIDDLE: + case DM_RATR_STA_LOW: + p_ra->ratr_state = DM_RATR_STA_LOW; + break; + } + else if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld\n", + rtlpriv->dm.undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI_LEVEL = %d\n", p_ra->ratr_state); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); + + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, + p_ra->ratr_state, + true); + rcu_read_unlock(); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +void rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + static u8 initialize; + static u32 reg_874, reg_c70, reg_85c, reg_a74; + + if (initialize == 0) { + reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; + + initialize = 1; + } + + if (!bforce_in_normal) { + if (dm_pstable->rssi_val_min != 0) { + if (dm_pstable->pre_rfstate == RF_NORMAL) { + if (dm_pstable->rssi_val_min >= 30) + dm_pstable->cur_rfstate = RF_SAVE; + else + dm_pstable->cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable->rssi_val_min <= 25) + dm_pstable->cur_rfstate = RF_NORMAL; + else + dm_pstable->cur_rfstate = RF_SAVE; + } + } else { + dm_pstable->cur_rfstate = RF_MAX; + } + } else { + dm_pstable->cur_rfstate = RF_NORMAL; + } + + if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { + if (dm_pstable->cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + BIT(5), 0x1); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + BIT(5), 0x0); + } + + dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; + } +} + +static void rtl8723e_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + dm_pstable->rssi_val_min = 0; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "Not connected to any\n"); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable->rssi_val_min = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } else { + dm_pstable->rssi_val_min = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } + } else { + dm_pstable->rssi_val_min = + rtlpriv->dm.entry_min_undec_sm_pwdb; + + rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + dm_pstable->rssi_val_min); + } + + rtl8723e_dm_rf_saving(hw, false); +} + +void rtl8723e_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl_dm_diginit(hw, 0x20); + rtl8723_dm_init_dynamic_txpower(hw); + rtl8723_dm_init_edca_turbo(hw); + rtl8723e_dm_init_rate_adaptive_mask(hw); + rtl8723e_dm_initialize_txpower_tracking(hw); + rtl8723_dm_init_dynamic_bb_powersaving(hw); +} + +void rtl8723e_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) { + rtl8723e_dm_pwdb_monitor(hw); + rtl8723e_dm_dig(hw); + rtl8723e_dm_false_alarm_counter_statistics(hw); + rtl8723e_dm_dynamic_bb_powersaving(hw); + rtl8723e_dm_dynamic_txpower(hw); + rtl8723e_dm_check_txpower_tracking(hw); + rtl8723e_dm_refresh_rate_adaptive_mask(hw); + rtl8723e_dm_bt_coexist(hw); + rtl8723e_dm_check_edca_turbo(hw); + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + if (rtlpriv->btcoexist.init_set) + rtl_write_byte(rtlpriv, 0x76e, 0xc); +} + +static void rtl8723e_dm_init_bt_coexist(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->btcoexist.bt_rfreg_origin_1e + = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); + rtlpriv->btcoexist.bt_rfreg_origin_1f + = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); + + rtlpriv->btcoexist.cstate = 0; + rtlpriv->btcoexist.previous_state = 0; + rtlpriv->btcoexist.cstate_h = 0; + rtlpriv->btcoexist.previous_state_h = 0; + rtlpriv->btcoexist.lps_counter = 0; + + /* Enable counter statistics */ + rtl_write_byte(rtlpriv, 0x76e, 0x4); + rtl_write_byte(rtlpriv, 0x778, 0x3); + rtl_write_byte(rtlpriv, 0x40, 0x20); + + rtlpriv->btcoexist.init_set = true; +} + +void rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_byte = 0; + if (!rtlpriv->btcoexist.bt_coexistence) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[DM]{BT], BT not exist!!\n"); + return; + } + + if (!rtlpriv->btcoexist.init_set) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[DM][BT], %s\n", __func__); + rtl8723e_dm_init_bt_coexist(hw); + } + + tmp_byte = rtl_read_byte(rtlpriv, 0x40); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "[DM][BT], 0x40 is 0x%x\n", tmp_byte); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[DM][BT], bt_dm_coexist start\n"); + rtl8723e_dm_bt_coexist_8723(hw); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h new file mode 100644 index 000000000..bcad516f0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_DM_H__ +#define __RTL8723E_DM_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; + +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) +#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) +#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) +#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1) +#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1) +#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ + ( \ + (((struct rtl_priv *)(_priv))->mac80211.opmode == \ + NL80211_IFTYPE_ADHOC) ? \ + (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) : \ + (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb) \ + ) + +void rtl8723e_dm_init(struct ieee80211_hw *hw); +void rtl8723e_dm_watchdog(struct ieee80211_hw *hw); +void rtl8723e_dm_write_dig(struct ieee80211_hw *hw); +void rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c new file mode 100644 index 000000000..d1b50a80c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" + +static bool _rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw *hw, + u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr, val_mcutst_1; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); + + if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) + result = true; + return result; +} + +static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + pr_err("Write H2C fail because no trigger for FW INT!\n"); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + pr_err("switch case %#x not processed\n", + boxnum); + break; + } + + isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, + boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 1); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 2); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index, 2); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index + 2, 2); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index, 2); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index + 2, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + pr_err("switch case %#x not processed\n", + cmd_len); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8723ae: error H2C cmd because of Fw download fail!!!\n"); + return; + } + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl8723e_fill_h2c_command(hw, element_id, cmd_len, + (u8 *)&tmp_cmdbuf); +} + +void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, + (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); +} + +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[3] = { 0 }; + bool b_dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *---------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1rsvdpageloc, 3); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", + u1rsvdpageloc, 3); + rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = { 0 }; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} + +static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, + u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = { ctwindow}; + + rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); + +} + +void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow); + } + + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num ; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= + (tsf_low+(50*1024))) { + start_time += + p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + + } + + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); + +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h new file mode 100644 index 000000000..3f9ed9b44 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_SIZE 0x3000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x3FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((_pfwhdr->signature&0xFFFF) == 0x2300 ||\ + (_pfwhdr->signature&0xFFFF) == 0x2301 ||\ + (_pfwhdr->signature&0xFFFF) == 0x2302) + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val + +void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c new file mode 100644 index 000000000..6c4fedc3e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c @@ -0,0 +1,515 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "hal_bt_coexist.h" +#include "../pci.h" +#include "dm.h" +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "hal_btc.h" + +static bool bt_operation_on; + +void rtl8723e_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, + bool b_reject) +{ +} + +void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlpriv->link_info.busytraffic) { + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_IDLE; + + if (rtlpriv->link_info.tx_busy_traffic) + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_UPLINK; + else + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_UPLINK; + + if (rtlpriv->link_info.rx_busy_traffic) + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_DOWNLINK; + else + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_DOWNLINK; + } else { + rtlpriv->btcoexist.cstate |= BT_COEX_STATE_WIFI_IDLE; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_UPLINK; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_DOWNLINK; + } + + if (rtlpriv->mac80211.mode == WIRELESS_MODE_G || + rtlpriv->mac80211.mode == WIRELESS_MODE_B) { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_LEGACY; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_HT20; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_HT40; + } else { + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_LEGACY; + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_HT40; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_HT20; + } else { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_HT20; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_HT40; + } + } + + if (bt_operation_on) + rtlpriv->btcoexist.cstate |= BT_COEX_STATE_BT30; + else + rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_BT30; +} + +u8 rtl8723e_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1) + +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long undecoratedsmoothed_pwdb; + u8 bt_rssi_state = 0; + + undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw); + + if (level_num == 2) { + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; + + if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_LOW) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_LOW)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_HIGH; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to High\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state stay at Low\n"); + } + } else { + if (undecoratedsmoothed_pwdb < rssi_thresh) { + bt_rssi_state = BT_RSSI_STATE_LOW; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to Low\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 thresh error!!\n"); + return rtlpriv->btcoexist.bt_pre_rssi_state; + } + + if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_LOW) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_LOW)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh+BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_MEDIUM; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to Medium\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state stay at Low\n"); + } + } else if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_MEDIUM) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_MEDIUM)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_HIGH; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to High\n"); + } else if (undecoratedsmoothed_pwdb < rssi_thresh) { + bt_rssi_state = BT_RSSI_STATE_LOW; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to Low\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state stay at Medium\n"); + } + } else { + if (undecoratedsmoothed_pwdb < rssi_thresh1) { + bt_rssi_state = BT_RSSI_STATE_MEDIUM; + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_1_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state switch to Medium\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI_1 state stay at High\n"); + } + } + } + rtlpriv->btcoexist.bt_pre_rssi_state1 = bt_rssi_state; + + return bt_rssi_state; +} + +u8 rtl8723e_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, + u8 level_num, + u8 rssi_thresh, + u8 rssi_thresh1) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long undecoratedsmoothed_pwdb = 0; + u8 bt_rssi_state = 0; + + undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw); + + if (level_num == 2) { + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; + + if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_LOW) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_LOW)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_HIGH; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_HIGH; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to High\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state stay at Low\n"); + } + } else { + if (undecoratedsmoothed_pwdb < rssi_thresh) { + bt_rssi_state = BT_RSSI_STATE_LOW; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_LOW; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to Low\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state stay at High\n"); + } + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI thresh error!!\n"); + return rtlpriv->btcoexist.bt_pre_rssi_state; + } + if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_LOW) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_LOW)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_MEDIUM; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_LOW; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to Medium\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state stay at Low\n"); + } + } else if ((rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_MEDIUM) || + (rtlpriv->btcoexist.bt_pre_rssi_state == + BT_RSSI_STATE_STAY_MEDIUM)) { + if (undecoratedsmoothed_pwdb >= + (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) { + bt_rssi_state = BT_RSSI_STATE_HIGH; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_HIGH; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_LOW; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to High\n"); + } else if (undecoratedsmoothed_pwdb < rssi_thresh) { + bt_rssi_state = BT_RSSI_STATE_LOW; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_LOW; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to Low\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state stay at Medium\n"); + } + } else { + if (undecoratedsmoothed_pwdb < rssi_thresh1) { + bt_rssi_state = BT_RSSI_STATE_MEDIUM; + rtlpriv->btcoexist.cstate + |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; + rtlpriv->btcoexist.cstate + &= ~BT_COEX_STATE_WIFI_RSSI_LOW; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state switch to Medium\n"); + } else { + bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], RSSI state stay at High\n"); + } + } + } + rtlpriv->btcoexist.bt_pre_rssi_state = bt_rssi_state; + return bt_rssi_state; +} + +long rtl8723e_dm_bt_get_rx_ss(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long undecoratedsmoothed_pwdb = 0; + + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + undecoratedsmoothed_pwdb = + GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); + } else { + undecoratedsmoothed_pwdb + = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "%s = %ld\n", __func__, + undecoratedsmoothed_pwdb); + + return undecoratedsmoothed_pwdb; +} + +void rtl8723e_dm_bt_balance(struct ieee80211_hw *hw, + bool balance_on, u8 ms0, u8 ms1) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[3] = {0}; + + if (balance_on) { + h2c_parameter[2] = 1; + h2c_parameter[1] = ms1; + h2c_parameter[0] = ms0; + rtlpriv->btcoexist.fw_coexist_all_off = false; + } else { + h2c_parameter[2] = 0; + h2c_parameter[1] = 0; + h2c_parameter[0] = 0; + } + rtlpriv->btcoexist.balance_on = balance_on; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", + balance_on ? "ON" : "OFF", ms0, ms1, h2c_parameter[0] << 16 | + h2c_parameter[1] << 8 | h2c_parameter[2]); + + rtl8723e_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter); +} + + +void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (type == BT_AGCTABLE_OFF) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BT]AGCTable Off!\n"); + rtl_write_dword(rtlpriv, 0xc78, 0x641c0001); + rtl_write_dword(rtlpriv, 0xc78, 0x631d0001); + rtl_write_dword(rtlpriv, 0xc78, 0x621e0001); + rtl_write_dword(rtlpriv, 0xc78, 0x611f0001); + rtl_write_dword(rtlpriv, 0xc78, 0x60200001); + + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0x32000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0x71000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0xb0000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0xfc000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_G1, 0xfffff, 0x30355); + } else if (type == BT_AGCTABLE_ON) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BT]AGCTable On!\n"); + rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001); + rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001); + rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001); + rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001); + rtl_write_dword(rtlpriv, 0xc78, 0x4a200001); + + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0xdc000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0x90000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0x51000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_AGC_HP, 0xfffff, 0x12000); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, + RF_RX_G1, 0xfffff, 0x00355); + + rtlpriv->btcoexist.sw_coexist_all_off = false; + } +} + +void rtl8723e_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (type == BT_BB_BACKOFF_OFF) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BT]BBBackOffLevel Off!\n"); + rtl_write_dword(rtlpriv, 0xc04, 0x3a05611); + } else if (type == BT_BB_BACKOFF_ON) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BT]BBBackOffLevel On!\n"); + rtl_write_dword(rtlpriv, 0xc04, 0x3a07611); + rtlpriv->btcoexist.sw_coexist_all_off = false; + } +} + +void rtl8723e_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "rtl8723e_dm_bt_fw_coex_all_off()\n"); + + if (rtlpriv->btcoexist.fw_coexist_all_off) + return; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "rtl8723e_dm_bt_fw_coex_all_off(), real Do\n"); + rtl8723e_dm_bt_fw_coex_all_off_8723a(hw); + rtlpriv->btcoexist.fw_coexist_all_off = true; +} + +void rtl8723e_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "%s\n", __func__); + + if (rtlpriv->btcoexist.sw_coexist_all_off) + return; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "%s, real Do\n", __func__); + rtl8723e_dm_bt_sw_coex_all_off_8723a(hw); + rtlpriv->btcoexist.sw_coexist_all_off = true; +} + +void rtl8723e_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "%s\n", __func__); + + if (rtlpriv->btcoexist.hw_coexist_all_off) + return; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "%s, real Do\n", __func__); + + rtl8723e_dm_bt_hw_coex_all_off_8723a(hw); + + rtlpriv->btcoexist.hw_coexist_all_off = true; +} + +void rtl8723e_btdm_coex_all_off(struct ieee80211_hw *hw) +{ + rtl8723e_dm_bt_fw_coex_all_off(hw); + rtl8723e_dm_bt_sw_coex_all_off(hw); + rtl8723e_dm_bt_hw_coex_all_off(hw); +} + +bool rtl8723e_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if ((rtlpriv->btcoexist.previous_state == rtlpriv->btcoexist.cstate) && + (rtlpriv->btcoexist.previous_state_h == + rtlpriv->btcoexist.cstate_h)) + return false; + return true; +} + +bool rtl8723e_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->link_info.tx_busy_traffic) + return true; + return false; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h new file mode 100644 index 000000000..12cdecdaf --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_HAL_BT_COEXIST_H__ +#define __RTL8723E_HAL_BT_COEXIST_H__ + +#include "../wifi.h" + +/* The reg define is for 8723 */ +#define REG_HIGH_PRIORITY_TXRX 0x770 +#define REG_LOW_PRIORITY_TXRX 0x774 + +#define BT_FW_COEX_THRESH_TOL 6 +#define BT_FW_COEX_THRESH_20 20 +#define BT_FW_COEX_THRESH_23 23 +#define BT_FW_COEX_THRESH_25 25 +#define BT_FW_COEX_THRESH_30 30 +#define BT_FW_COEX_THRESH_35 35 +#define BT_FW_COEX_THRESH_40 40 +#define BT_FW_COEX_THRESH_45 45 +#define BT_FW_COEX_THRESH_47 47 +#define BT_FW_COEX_THRESH_50 50 +#define BT_FW_COEX_THRESH_55 55 + +#define BT_COEX_STATE_BT30 BIT(0) +#define BT_COEX_STATE_WIFI_HT20 BIT(1) +#define BT_COEX_STATE_WIFI_HT40 BIT(2) +#define BT_COEX_STATE_WIFI_LEGACY BIT(3) + +#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4) +#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5) +#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6) +#define BT_COEX_STATE_DEC_BT_POWER BIT(7) + +#define BT_COEX_STATE_WIFI_IDLE BIT(8) +#define BT_COEX_STATE_WIFI_UPLINK BIT(9) +#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10) + +#define BT_COEX_STATE_BT_INQ_PAGE BIT(11) +#define BT_COEX_STATE_BT_IDLE BIT(12) +#define BT_COEX_STATE_BT_UPLINK BIT(13) +#define BT_COEX_STATE_BT_DOWNLINK BIT(14) + +#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15) +#define BT_COEX_STATE_BT_RSSI_LOW BIT(19) + +#define BT_COEX_STATE_PROFILE_HID BIT(20) +#define BT_COEX_STATE_PROFILE_A2DP BIT(21) +#define BT_COEX_STATE_PROFILE_PAN BIT(22) +#define BT_COEX_STATE_PROFILE_SCO BIT(23) + +#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24) +#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25) +#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26) + +#define BT_COEX_STATE_BTINFO_COMMON BIT(30) +#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31) +#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29) + +#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0) +#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1) +#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2) +#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3) + +#define BT_RSSI_STATE_HIGH 0 +#define BT_RSSI_STATE_MEDIUM 1 +#define BT_RSSI_STATE_LOW 2 +#define BT_RSSI_STATE_STAY_HIGH 3 +#define BT_RSSI_STATE_STAY_MEDIUM 4 +#define BT_RSSI_STATE_STAY_LOW 5 + +#define BT_AGCTABLE_OFF 0 +#define BT_AGCTABLE_ON 1 +#define BT_BB_BACKOFF_OFF 0 +#define BT_BB_BACKOFF_ON 1 +#define BT_FW_NAV_OFF 0 +#define BT_FW_NAV_ON 1 + +#define BT_COEX_MECH_NONE 0 +#define BT_COEX_MECH_SCO 1 +#define BT_COEX_MECH_HID 2 +#define BT_COEX_MECH_A2DP 3 +#define BT_COEX_MECH_PAN 4 +#define BT_COEX_MECH_HID_A2DP 5 +#define BT_COEX_MECH_HID_PAN 6 +#define BT_COEX_MECH_PAN_A2DP 7 +#define BT_COEX_MECH_HID_SCO_ESCO 8 +#define BT_COEX_MECH_FTP_A2DP 9 +#define BT_COEX_MECH_COMMON 10 +#define BT_COEX_MECH_MAX 11 + +#define BT_DBG_PROFILE_NONE 0 +#define BT_DBG_PROFILE_SCO 1 +#define BT_DBG_PROFILE_HID 2 +#define BT_DBG_PROFILE_A2DP 3 +#define BT_DBG_PROFILE_PAN 4 +#define BT_DBG_PROFILE_HID_A2DP 5 +#define BT_DBG_PROFILE_HID_PAN 6 +#define BT_DBG_PROFILE_PAN_A2DP 7 +#define BT_DBG_PROFILE_MAX 9 + +#define BTINFO_B_FTP BIT(7) +#define BTINFO_B_A2DP BIT(6) +#define BTINFO_B_HID BIT(5) +#define BTINFO_B_SCO_BUSY BIT(4) +#define BTINFO_B_ACL_BUSY BIT(3) +#define BTINFO_B_INQ_PAGE BIT(2) +#define BTINFO_B_SCO_ESCO BIT(1) +#define BTINFO_B_CONNECTION BIT(0) + +void rtl8723e_btdm_coex_all_off(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw); + +void rtl8723e_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw); +long rtl8723e_dm_bt_get_rx_ss(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_balance(struct ieee80211_hw *hw, + bool balance_on, u8 ms0, u8 ms1); +void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type); +void rtl8723e_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type); +u8 rtl8723e_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1); +u8 rtl8723e_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, + u8 level_num, u8 rssi_thresh, + u8 rssi_thresh1); +void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, + bool b_reject); +bool rtl8723e_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw); +bool rtl8723e_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c new file mode 100644 index 000000000..b34dffc6a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c @@ -0,0 +1,1756 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "hal_btc.h" +#include "../pci.h" +#include "phy.h" +#include "fw.h" +#include "reg.h" +#include "def.h" +#include "../rtl8723com/phy_common.h" + +static struct bt_coexist_8723 hal_coex_8723; + +void rtl8723e_dm_bt_turn_off_bt_coexist_before_enter_lps(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if (!rtlpriv->btcoexist.bt_coexistence) + return; + + if (ppsc->inactiveps) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BT][DM], Before enter IPS, turn off all Coexist DM\n"); + rtlpriv->btcoexist.cstate = 0; + rtlpriv->btcoexist.previous_state = 0; + rtlpriv->btcoexist.cstate_h = 0; + rtlpriv->btcoexist.previous_state_h = 0; + rtl8723e_btdm_coex_all_off(hw); + } +} + +static enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum rt_media_status m_status = RT_MEDIA_DISCONNECT; + u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; + if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) + m_status = RT_MEDIA_CONNECT; + + return m_status; +} + +void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, + bool mstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 h2c_parameter[3] = {0}; + u8 chnl; + + if (!rtlpriv->btcoexist.bt_coexistence) + return; + + if (RT_MEDIA_CONNECT == mstatus) + h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */ + else + h2c_parameter[0] = 0x0; + + if (mgnt_link_status_query(hw)) { + chnl = rtlphy->current_channel; + h2c_parameter[1] = chnl; + } + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) + h2c_parameter[2] = 0x30; + else + h2c_parameter[2] = 0x20; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], FW write 0x19=0x%x\n", + h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | + h2c_parameter[2]); + + rtl8723e_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter); +} + +static bool rtl8723e_dm_bt_is_wifi_busy(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (rtlpriv->link_info.busytraffic || + rtlpriv->link_info.rx_busy_traffic || + rtlpriv->link_info.tx_busy_traffic) + return true; + else + return false; +} + +static void rtl8723e_dm_bt_set_fw_3a(struct ieee80211_hw *hw, + u8 byte1, u8 byte2, u8 byte3, u8 byte4, + u8 byte5) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[5]; + + h2c_parameter[0] = byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = byte5; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], FW write 0x3a(4bytes)=0x%x%8x\n", + h2c_parameter[0], h2c_parameter[1]<<24 | + h2c_parameter[2]<<16 | h2c_parameter[3]<<8 | + h2c_parameter[4]); + rtl8723e_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter); +} + +static bool rtl8723e_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Need to decrease bt power\n"); + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_DEC_BT_POWER; + return true; + } + + rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER; + return false; +} + +static bool rtl8723e_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if ((rtlpriv->btcoexist.previous_state == + rtlpriv->btcoexist.cstate) && + (rtlpriv->btcoexist.previous_state_h == + rtlpriv->btcoexist.cstate_h)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[DM][BT], Coexist state do not change!!\n"); + return true; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[DM][BT], Coexist state changed!!\n"); + return false; + } +} + +static void rtl8723e_dm_bt_set_coex_table(struct ieee80211_hw *hw, + u32 val_0x6c0, u32 val_0x6c8, + u32 val_0x6cc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "set coex table, set 0x6c0=0x%x\n", val_0x6c0); + rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "set coex table, set 0x6c8=0x%x\n", val_0x6c8); + rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "set coex table, set 0x6cc=0x%x\n", val_0x6cc); + rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc); +} + +static void rtl8723e_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool b_mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (BT_PTA_MODE_ON == b_mode) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on\n"); + /* Enable GPIO 0/1/2/3/8 pins for bt */ + rtl_write_byte(rtlpriv, 0x40, 0x20); + rtlpriv->btcoexist.hw_coexist_all_off = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n"); + rtl_write_byte(rtlpriv, 0x40, 0x0); + } +} + +static void rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw, + u8 type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (BT_RF_RX_LPF_CORNER_SHRINK == type) { + /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "Shrink RF Rx LPF corner!!\n"); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, + 0xfffff, 0xf0ff7); + rtlpriv->btcoexist.sw_coexist_all_off = false; + } else if (BT_RF_RX_LPF_CORNER_RESUME == type) { + /*Resume RF Rx LPF corner*/ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "Resume RF Rx LPF corner!!\n"); + rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, + rtlpriv->btcoexist.bt_rfreg_origin_1e); + } +} + +static void dm_bt_set_sw_penalty_tx_rate_adapt(struct ieee80211_hw *hw, + u8 ra_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_u1; + + tmp_u1 = rtl_read_byte(rtlpriv, 0x4fd); + tmp_u1 |= BIT(0); + if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "Tx rate adaptive, set low penalty!!\n"); + tmp_u1 &= ~BIT(2); + rtlpriv->btcoexist.sw_coexist_all_off = false; + } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "Tx rate adaptive, set normal!!\n"); + tmp_u1 |= BIT(2); + } + + rtl_write_byte(rtlpriv, 0x4fd, tmp_u1); +} + +static void rtl8723e_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw, + struct btdm_8723 *btdm) +{ + btdm->all_off = false; + btdm->agc_table_en = false; + btdm->adc_back_off_on = false; + btdm->b2_ant_hid_en = false; + btdm->low_penalty_rate_adaptive = false; + btdm->rf_rx_lpf_shrink = false; + btdm->reject_aggre_pkt = false; + + btdm->tdma_on = false; + btdm->tdma_ant = TDMA_2ANT; + btdm->tdma_nav = TDMA_NAV_OFF; + btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF; + btdm->fw_dac_swing_lvl = 0x20; + + btdm->tra_tdma_on = false; + btdm->tra_tdma_ant = TDMA_2ANT; + btdm->tra_tdma_nav = TDMA_NAV_OFF; + btdm->ignore_wlan_act = false; + + btdm->ps_tdma_on = false; + btdm->ps_tdma_byte[0] = 0x0; + btdm->ps_tdma_byte[1] = 0x0; + btdm->ps_tdma_byte[2] = 0x0; + btdm->ps_tdma_byte[3] = 0x8; + btdm->ps_tdma_byte[4] = 0x0; + + btdm->pta_on = true; + btdm->val_0x6c0 = 0x5a5aaaaa; + btdm->val_0x6c8 = 0xcc; + btdm->val_0x6cc = 0x3; + + btdm->sw_dac_swing_on = false; + btdm->sw_dac_swing_lvl = 0xc0; + btdm->wlan_act_hi = 0x20; + btdm->wlan_act_lo = 0x10; + btdm->bt_retry_index = 2; + + btdm->dec_bt_pwr = false; +} + +static void rtl8723e_dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw, + struct btdm_8723 *btdm) +{ + rtl8723e_dm_bt_btdm_structure_reload(hw, btdm); + btdm->all_off = true; + btdm->pta_on = false; + btdm->wlan_act_hi = 0x10; +} + +static bool rtl8723e_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct btdm_8723 btdm8723; + bool b_common = false; + + rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723); + + if (!rtl8723e_dm_bt_is_wifi_busy(hw) && + !rtlpriv->btcoexist.bt_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi idle + Bt idle, bt coex mechanism always off!!\n"); + rtl8723e_dm_bt_btdm_structure_reload_all_off(hw, &btdm8723); + b_common = true; + } else if (rtl8723e_dm_bt_is_wifi_busy(hw) && + !rtlpriv->btcoexist.bt_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi non-idle + Bt disabled/idle!!\n"); + btdm8723.low_penalty_rate_adaptive = true; + btdm8723.rf_rx_lpf_shrink = false; + btdm8723.reject_aggre_pkt = false; + + /* sw mechanism */ + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = false; + btdm8723.sw_dac_swing_on = false; + + btdm8723.pta_on = true; + btdm8723.val_0x6c0 = 0x5a5aaaaa; + btdm8723.val_0x6c8 = 0xcccc; + btdm8723.val_0x6cc = 0x3; + + btdm8723.tdma_on = false; + btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; + btdm8723.b2_ant_hid_en = false; + + b_common = true; + } else if (rtlpriv->btcoexist.bt_busy) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Bt non-idle!\n"); + if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi connection exist\n"); + b_common = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "No Wifi connection!\n"); + btdm8723.rf_rx_lpf_shrink = true; + btdm8723.low_penalty_rate_adaptive = false; + btdm8723.reject_aggre_pkt = false; + + /* sw mechanism */ + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = false; + btdm8723.sw_dac_swing_on = false; + + btdm8723.pta_on = true; + btdm8723.val_0x6c0 = 0x55555555; + btdm8723.val_0x6c8 = 0x0000ffff; + btdm8723.val_0x6cc = 0x3; + + btdm8723.tdma_on = false; + btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; + btdm8723.b2_ant_hid_en = false; + + b_common = true; + } + } + + if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw)) + btdm8723.dec_bt_pwr = true; + + if (b_common) + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_BTINFO_COMMON; + + if (b_common && rtl8723e_dm_bt_is_coexist_state_changed(hw)) + rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723); + + return b_common; +} + +static void rtl8723e_dm_bt_set_sw_full_time_dac_swing( + struct ieee80211_hw *hw, + bool sw_dac_swing_on, + u32 sw_dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (sw_dac_swing_on) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); + rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, + sw_dac_swing_lvl); + rtlpriv->btcoexist.sw_coexist_all_off = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], SwDacSwing Off!\n"); + rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); + } +} + +static void rtl8723e_dm_bt_set_fw_dec_bt_pwr( + struct ieee80211_hw *hw, bool dec_bt_pwr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + + h2c_parameter[0] = 0; + + if (dec_bt_pwr) { + h2c_parameter[0] |= BIT(1); + rtlpriv->btcoexist.fw_coexist_all_off = false; + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], decrease Bt Power : %s, write 0x21=0x%x\n", + (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw, + bool b_enable, bool b_dac_swing_on) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + + if (b_enable) { + h2c_parameter[0] |= BIT(0); + rtlpriv->btcoexist.fw_coexist_all_off = false; + } + if (b_dac_swing_on) + h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15=0x%x\n", + (b_enable ? "ON!!" : "OFF!!"), (b_dac_swing_on ? "ON" : "OFF"), + h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw, + bool b_enable, u8 ant_num, + u8 nav_en, u8 dac_swing_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + u8 h2c_parameter1[1] = {0}; + + h2c_parameter[0] = 0; + h2c_parameter1[0] = 0; + + if (b_enable) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], set BT PTA update manager to trigger update!!\n"); + h2c_parameter1[0] |= BIT(0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], turn TDMA mode ON!!\n"); + h2c_parameter[0] |= BIT(0); /* function enable */ + if (TDMA_1ANT == ant_num) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_1ANT\n"); + h2c_parameter[0] |= BIT(1); + } else if (TDMA_2ANT == ant_num) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_2ANT\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Unknown Ant\n"); + } + + if (TDMA_NAV_OFF == nav_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_NAV_OFF\n"); + } else if (TDMA_NAV_ON == nav_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_NAV_ON\n"); + h2c_parameter[0] |= BIT(2); + } + + if (TDMA_DAC_SWING_OFF == dac_swing_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_DAC_SWING_OFF\n"); + } else if (TDMA_DAC_SWING_ON == dac_swing_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TDMA_DAC_SWING_ON\n"); + h2c_parameter[0] |= BIT(4); + } + rtlpriv->btcoexist.fw_coexist_all_off = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], set BT PTA update manager to no update!!\n"); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], turn TDMA mode OFF!!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], FW2AntTDMA, write 0x26=0x%x\n", + h2c_parameter1[0]); + rtl8723e_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], FW2AntTDMA, write 0x14=0x%x\n", + h2c_parameter[0]); + rtl8723e_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw, + bool b_enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + + if (b_enable) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], BT Ignore Wlan_Act !!\n"); + h2c_parameter[0] |= BIT(0); /* function enable */ + rtlpriv->btcoexist.fw_coexist_all_off = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], BT don't ignore Wlan_Act !!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25=0x%x\n", + h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw, + bool b_enable, u8 ant_num, + u8 nav_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 h2c_parameter[2] = {0}; + + /* Only 8723 B cut should do this */ + if (IS_VENDOR_8723_A_CUT(rtlhal->version)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n"); + return; + } + + if (b_enable) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], turn TTDMA mode ON!!\n"); + h2c_parameter[0] |= BIT(0); /* function enable */ + if (TDMA_1ANT == ant_num) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TTDMA_1ANT\n"); + h2c_parameter[0] |= BIT(1); + } else if (TDMA_2ANT == ant_num) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TTDMA_2ANT\n"); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Unknown Ant\n"); + } + + if (TDMA_NAV_OFF == nav_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TTDMA_NAV_OFF\n"); + } else if (TDMA_NAV_ON == nav_en) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], TTDMA_NAV_ON\n"); + h2c_parameter[1] |= BIT(0); + } + + rtlpriv->btcoexist.fw_coexist_all_off = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], turn TTDMA mode OFF!!\n"); + } + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], FW Traditional TDMA, write 0x33=0x%x\n", + h2c_parameter[0] << 8 | h2c_parameter[1]); + + rtl8723e_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw, + u8 dac_swing_lvl) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + h2c_parameter[0] = dac_swing_lvl; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], write 0x29=0x%x\n", h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw, + bool b_enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + h2c_parameter[0] = 0; + + if (b_enable) { + h2c_parameter[0] |= BIT(0); + rtlpriv->btcoexist.fw_coexist_all_off = false; + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Set BT HID information=0x%x\n", b_enable); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], write 0x24=0x%x\n", h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw, + u8 retry_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + h2c_parameter[0] = retry_index; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Set BT Retry Index=%d\n", retry_index); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], write 0x23=0x%x\n", h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw, + u8 wlan_act_hi, u8 wlan_act_lo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter_hi[1] = {0}; + u8 h2c_parameter_lo[1] = {0}; + h2c_parameter_hi[0] = wlan_act_hi; + h2c_parameter_lo[0] = wlan_act_lo; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], Set WLAN_ACT Hi:Lo=0x%x/0x%x\n", + wlan_act_hi, wlan_act_lo); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], write 0x22=0x%x\n", h2c_parameter_hi[0]); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], write 0x11=0x%x\n", h2c_parameter_lo[0]); + + /* WLAN_ACT = High duration, unit:ms */ + rtl8723e_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi); + /* WLAN_ACT = Low duration, unit:3*625us */ + rtl8723e_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo); +} + +void rtl8723e_dm_bt_set_bt_dm(struct ieee80211_hw *hw, + struct btdm_8723 *btdm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct btdm_8723 *btdm_8723 = &hal_coex_8723.btdm; + u8 i; + + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + + /* check new setting is different with the old one, */ + /* if all the same, don't do the setting again. */ + if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], the same coexist setting, return!!\n"); + return; + } else { /* save the new coexist setting */ + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], UPDATE TO NEW COEX SETTING!!\n"); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bAllOff=0x%x/ 0x%x\n", + btdm_8723->all_off, btdm->all_off); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new agc_table_en=0x%x/ 0x%x\n", + btdm_8723->agc_table_en, btdm->agc_table_en); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new adc_back_off_on=0x%x/ 0x%x\n", + btdm_8723->adc_back_off_on, + btdm->adc_back_off_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new b2_ant_hid_en=0x%x/ 0x%x\n", + btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bLowPenaltyRateAdaptive=0x%x/ 0x%x\n", + btdm_8723->low_penalty_rate_adaptive, + btdm->low_penalty_rate_adaptive); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bRfRxLpfShrink=0x%x/ 0x%x\n", + btdm_8723->rf_rx_lpf_shrink, + btdm->rf_rx_lpf_shrink); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bRejectAggrePkt=0x%x/ 0x%x\n", + btdm_8723->reject_aggre_pkt, + btdm->reject_aggre_pkt); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new tdma_on=0x%x/ 0x%x\n", + btdm_8723->tdma_on, btdm->tdma_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new tdmaAnt=0x%x/ 0x%x\n", + btdm_8723->tdma_ant, btdm->tdma_ant); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new tdmaNav=0x%x/ 0x%x\n", + btdm_8723->tdma_nav, btdm->tdma_nav); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new tdma_dac_swing=0x%x/ 0x%x\n", + btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new fw_dac_swing_lvl=0x%x/ 0x%x\n", + btdm_8723->fw_dac_swing_lvl, + btdm->fw_dac_swing_lvl); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bTraTdmaOn=0x%x/ 0x%x\n", + btdm_8723->tra_tdma_on, btdm->tra_tdma_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new traTdmaAnt=0x%x/ 0x%x\n", + btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new traTdmaNav=0x%x/ 0x%x\n", + btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bPsTdmaOn=0x%x/ 0x%x\n", + btdm_8723->ps_tdma_on, btdm->ps_tdma_on); + for (i = 0; i < 5; i++) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new psTdmaByte[i]=0x%x/ 0x%x\n", + btdm_8723->ps_tdma_byte[i], + btdm->ps_tdma_byte[i]); + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bIgnoreWlanAct=0x%x/ 0x%x\n", + btdm_8723->ignore_wlan_act, + btdm->ignore_wlan_act); + + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new bPtaOn=0x%x/ 0x%x\n", + btdm_8723->pta_on, btdm->pta_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new val_0x6c0=0x%x/ 0x%x\n", + btdm_8723->val_0x6c0, btdm->val_0x6c0); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new val_0x6c8=0x%x/ 0x%x\n", + btdm_8723->val_0x6c8, btdm->val_0x6c8); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new val_0x6cc=0x%x/ 0x%x\n", + btdm_8723->val_0x6cc, btdm->val_0x6cc); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new sw_dac_swing_on=0x%x/ 0x%x\n", + btdm_8723->sw_dac_swing_on, + btdm->sw_dac_swing_on); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new sw_dac_swing_lvl=0x%x/ 0x%x\n", + btdm_8723->sw_dac_swing_lvl, + btdm->sw_dac_swing_lvl); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new wlanActHi=0x%x/ 0x%x\n", + btdm_8723->wlan_act_hi, btdm->wlan_act_hi); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new wlanActLo=0x%x/ 0x%x\n", + btdm_8723->wlan_act_lo, btdm->wlan_act_lo); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], original/new btRetryIndex=0x%x/ 0x%x\n", + btdm_8723->bt_retry_index, btdm->bt_retry_index); + + memcpy(btdm_8723, btdm, sizeof(struct btdm_8723)); + } + /* Here we only consider when Bt Operation + * inquiry/paging/pairing is ON + * we only need to turn off TDMA + */ + + if (rtlpriv->btcoexist.hold_for_bt_operation) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], set to ignore wlanAct for BT OP!!\n"); + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, true); + return; + } + + if (btdm->all_off) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], disable all coexist mechanism !!\n"); + rtl8723e_btdm_coex_all_off(hw); + return; + } + + rtl8723e_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt); + + if (btdm->low_penalty_rate_adaptive) + dm_bt_set_sw_penalty_tx_rate_adapt(hw, BT_TX_RATE_ADAPTIVE_LOW_PENALTY); + else + dm_bt_set_sw_penalty_tx_rate_adapt(hw, + BT_TX_RATE_ADAPTIVE_NORMAL); + + if (btdm->rf_rx_lpf_shrink) + rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw, + BT_RF_RX_LPF_CORNER_SHRINK); + else + rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw, + BT_RF_RX_LPF_CORNER_RESUME); + + if (btdm->agc_table_en) + rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_ON); + else + rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); + + if (btdm->adc_back_off_on) + rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_ON); + else + rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF); + + rtl8723e_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index); + + rtl8723e_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl); + rtl8723e_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi, + btdm->wlan_act_lo); + + rtl8723e_dm_bt_set_coex_table(hw, btdm->val_0x6c0, + btdm->val_0x6c8, btdm->val_0x6cc); + rtl8723e_dm_bt_set_hw_pta_mode(hw, btdm->pta_on); + + /* Note: There is a constraint between TDMA and 2AntHID + * Only one of 2AntHid and tdma can be turn on + * We should turn off those mechanisms should be turned off first + * and then turn on those mechanisms should be turned on. + */ + if (btdm->b2_ant_hid_en) { + /* turn off tdma */ + rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, + btdm->tra_tdma_ant, + btdm->tra_tdma_nav); + rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, + btdm->tdma_nav, + btdm->tdma_dac_swing); + + /* turn off Pstdma */ + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, + btdm->ignore_wlan_act); + /* Antenna control by PTA, 0x870 = 0x300. */ + rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); + + /* turn on 2AntHid */ + rtl8723e_dm_bt_set_fw_bt_hid_info(hw, true); + rtl8723e_dm_bt_set_fw_2_ant_hid(hw, true, true); + } else if (btdm->tdma_on) { + /* turn off 2AntHid */ + rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false); + rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false); + + /* turn off pstdma */ + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, + btdm->ignore_wlan_act); + /* Antenna control by PTA, 0x870 = 0x300. */ + rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); + + /* turn on tdma */ + rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, + btdm->tra_tdma_ant, + btdm->tra_tdma_nav); + rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant, + btdm->tdma_nav, + btdm->tdma_dac_swing); + } else if (btdm->ps_tdma_on) { + /* turn off 2AntHid */ + rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false); + rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false); + + /* turn off tdma */ + rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, + btdm->tra_tdma_ant, + btdm->tra_tdma_nav); + rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, + btdm->tdma_nav, + btdm->tdma_dac_swing); + + /* turn on pstdma */ + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, + btdm->ignore_wlan_act); + rtl8723e_dm_bt_set_fw_3a(hw, btdm->ps_tdma_byte[0], + btdm->ps_tdma_byte[1], + btdm->ps_tdma_byte[2], + btdm->ps_tdma_byte[3], + btdm->ps_tdma_byte[4]); + } else { + /* turn off 2AntHid */ + rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false); + rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false); + + /* turn off tdma */ + rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, + btdm->tra_tdma_ant, + btdm->tra_tdma_nav); + rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, + btdm->tdma_nav, + btdm->tdma_dac_swing); + + /* turn off pstdma */ + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, + btdm->ignore_wlan_act); + /* Antenna control by PTA, 0x870 = 0x300. */ + rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); + } + + /* Note: + * We should add delay for making sure + * sw DacSwing can be set sucessfully. + * because of that rtl8723e_dm_bt_set_fw_2_ant_hid() + * and rtl8723e_dm_bt_set_fw_tdma_ctrl() + * will overwrite the reg 0x880. + */ + mdelay(30); + rtl8723e_dm_bt_set_sw_full_time_dac_swing(hw, btdm->sw_dac_swing_on, + btdm->sw_dac_swing_lvl); + rtl8723e_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr); +} + +/* ============================================================ */ +/* extern function start with BTDM_ */ +/* ============================================================i + */ +static u32 rtl8723e_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw) +{ + u32 counters = 0; + + counters = hal_coex_8723.high_priority_tx + + hal_coex_8723.high_priority_rx; + return counters; +} + +static u32 rtl8723e_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw) +{ + u32 counters = 0; + + counters = hal_coex_8723.low_priority_tx + + hal_coex_8723.low_priority_rx; + return counters; +} + +static u8 rtl8723e_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 bt_tx_rx_cnt = 0; + u8 bt_tx_rx_cnt_lvl = 0; + + bt_tx_rx_cnt = rtl8723e_dm_bt_tx_rx_couter_h(hw) + + rtl8723e_dm_bt_tx_rx_couter_l(hw); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt); + + rtlpriv->btcoexist.cstate_h &= ~ + (BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1| + BT_COEX_STATE_BT_CNT_LEVEL_2); + + if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters at level 3\n"); + bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3; + rtlpriv->btcoexist.cstate_h |= + BT_COEX_STATE_BT_CNT_LEVEL_3; + } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters at level 2\n"); + bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2; + rtlpriv->btcoexist.cstate_h |= + BT_COEX_STATE_BT_CNT_LEVEL_2; + } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters at level 1\n"); + bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1; + rtlpriv->btcoexist.cstate_h |= + BT_COEX_STATE_BT_CNT_LEVEL_1; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters at level 0\n"); + bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0; + rtlpriv->btcoexist.cstate_h |= + BT_COEX_STATE_BT_CNT_LEVEL_0; + } + return bt_tx_rx_cnt_lvl; +} + +static void rtl8723e_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct btdm_8723 btdm8723; + u8 bt_rssi_state, bt_rssi_state1; + u8 bt_tx_rx_cnt_lvl = 0; + + rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723); + + btdm8723.rf_rx_lpf_shrink = true; + btdm8723.low_penalty_rate_adaptive = true; + btdm8723.reject_aggre_pkt = false; + + bt_tx_rx_cnt_lvl = rtl8723e_dm_bt_bt_tx_rx_counter_level(hw); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); + /* coex table */ + btdm8723.val_0x6c0 = 0x55555555; + btdm8723.val_0x6c8 = 0xffff; + btdm8723.val_0x6cc = 0x3; + + /* sw mechanism */ + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = false; + btdm8723.sw_dac_swing_on = false; + + /* fw mechanism */ + btdm8723.ps_tdma_on = true; + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "HT20 or Legacy\n"); + bt_rssi_state = + rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 47, 0); + bt_rssi_state1 = + rtl8723e_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0); + + /* coex table */ + btdm8723.val_0x6c0 = 0x55555555; + btdm8723.val_0x6c8 = 0xffff; + btdm8723.val_0x6cc = 0x3; + + /* sw mechanism */ + if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || + (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi high\n"); + btdm8723.agc_table_en = true; + btdm8723.adc_back_off_on = true; + btdm8723.sw_dac_swing_on = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi low\n"); + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = false; + btdm8723.sw_dac_swing_on = false; + } + + /* fw mechanism */ + btdm8723.ps_tdma_on = true; + if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || + (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi-1 high\n"); + /* only rssi high we need to do this, */ + /* when rssi low, the value will modified by fw */ + rtl_write_byte(rtlpriv, 0x883, 0x40); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x83; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters>= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x83; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x83; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi-1 low\n"); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } + } + + if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw)) + btdm8723.dec_bt_pwr = true; + + /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */ + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT btInqPageStartTime = 0x%lx, btTxRxCntLvl = %d\n", + hal_coex_8723.bt_inq_page_start_time, bt_tx_rx_cnt_lvl); + if ((hal_coex_8723.bt_inq_page_start_time) || + (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); + btdm8723.ps_tdma_on = true; + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x2; + btdm8723.ps_tdma_byte[4] = 0x80; + } + + if (rtl8723e_dm_bt_is_coexist_state_changed(hw)) + rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723); + +} + +static void rtl8723e_dm_bt_2_ant_ftp_a2dp(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct btdm_8723 btdm8723; + + u8 bt_rssi_state, bt_rssi_state1; + u32 bt_tx_rx_cnt_lvl = 0; + + rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723); + + btdm8723.rf_rx_lpf_shrink = true; + btdm8723.low_penalty_rate_adaptive = true; + btdm8723.reject_aggre_pkt = false; + + bt_tx_rx_cnt_lvl = rtl8723e_dm_bt_bt_tx_rx_counter_level(hw); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); + bt_rssi_state = + rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 37, 0); + + /* coex table */ + btdm8723.val_0x6c0 = 0x55555555; + btdm8723.val_0x6c8 = 0xffff; + btdm8723.val_0x6cc = 0x3; + + /* sw mechanism */ + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = true; + btdm8723.sw_dac_swing_on = false; + + /* fw mechanism */ + btdm8723.ps_tdma_on = true; + if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || + (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi high\n"); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi low\n"); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == + BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "HT20 or Legacy\n"); + bt_rssi_state = + rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 47, 0); + bt_rssi_state1 = + rtl8723e_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0); + + /* coex table */ + btdm8723.val_0x6c0 = 0x55555555; + btdm8723.val_0x6c8 = 0xffff; + btdm8723.val_0x6cc = 0x3; + + /* sw mechanism */ + if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || + (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi high\n"); + btdm8723.agc_table_en = true; + btdm8723.adc_back_off_on = true; + btdm8723.sw_dac_swing_on = false; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi low\n"); + btdm8723.agc_table_en = false; + btdm8723.adc_back_off_on = false; + btdm8723.sw_dac_swing_on = false; + } + + /* fw mechanism */ + btdm8723.ps_tdma_on = true; + if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || + (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi-1 high\n"); + /* only rssi high we need to do this, */ + /* when rssi low, the value will modified by fw */ + rtl_write_byte(rtlpriv, 0x883, 0x40); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x81; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Wifi rssi-1 low\n"); + if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xa; + btdm8723.ps_tdma_byte[2] = 0xa; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT TxRx Counters < 1200\n"); + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0xf; + btdm8723.ps_tdma_byte[2] = 0xf; + btdm8723.ps_tdma_byte[3] = 0x0; + btdm8723.ps_tdma_byte[4] = 0x80; + } + } + } + + if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw)) + btdm8723.dec_bt_pwr = true; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT btInqPageStartTime = 0x%lx, btTxRxCntLvl = %d\n", + hal_coex_8723.bt_inq_page_start_time, bt_tx_rx_cnt_lvl); + + if ((hal_coex_8723.bt_inq_page_start_time) || + (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); + btdm8723.ps_tdma_on = true; + btdm8723.ps_tdma_byte[0] = 0xa3; + btdm8723.ps_tdma_byte[1] = 0x5; + btdm8723.ps_tdma_byte[2] = 0x5; + btdm8723.ps_tdma_byte[3] = 0x83; + btdm8723.ps_tdma_byte[4] = 0x80; + } + + if (rtl8723e_dm_bt_is_coexist_state_changed(hw)) + rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723); + +} + +static void rtl8723e_dm_bt_inq_page_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long cur_time = jiffies; + + if (hal_coex_8723.c2h_bt_inquiry_page) { + /* bt inquiry or page is started. */ + if (hal_coex_8723.bt_inq_page_start_time == 0) { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_BT_INQ_PAGE; + hal_coex_8723.bt_inq_page_start_time = cur_time; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT Inquiry/page is started at time : 0x%lx\n", + hal_coex_8723.bt_inq_page_start_time); + } + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT Inquiry/page started time : 0x%lx, cur_time : 0x%lx\n", + hal_coex_8723.bt_inq_page_start_time, cur_time); + + if (hal_coex_8723.bt_inq_page_start_time) { + if (jiffies_to_msecs(cur_time - + hal_coex_8723.bt_inq_page_start_time) >= 10000) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BT Inquiry/page >= 10sec!!!\n"); + hal_coex_8723.bt_inq_page_start_time = 0; + rtlpriv->btcoexist.cstate &= + ~BT_COEX_STATE_BT_INQ_PAGE; + } + } +} + +static void rtl8723e_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->btcoexist.cstate &= ~ + (BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP| + BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO); + + rtlpriv->btcoexist.cstate &= ~ + (BT_COEX_STATE_BTINFO_COMMON | + BT_COEX_STATE_BTINFO_B_HID_SCOESCO| + BT_COEX_STATE_BTINFO_B_FTP_A2DP); +} + +static void _rtl8723e_dm_bt_coexist_2_ant(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_info_original; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex] Get bt info by fw!!\n"); + + _rtl8723_dm_bt_check_wifi_state(hw); + + if (hal_coex_8723.c2h_bt_info_req_sent) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex] c2h for bt_info not rcvd yet!!\n"); + } + + bt_info_original = hal_coex_8723.c2h_bt_info_original; + + /* when bt inquiry or page scan, we have to set h2c 0x25 */ + /* ignore wlanact for continuous 4x2secs */ + rtl8723e_dm_bt_inq_page_monitor(hw); + rtl8723e_dm_bt_reset_action_profile_state(hw); + + if (rtl8723e_dm_bt_is_2_ant_common_action(hw)) { + rtlpriv->btcoexist.bt_profile_case = BT_COEX_MECH_COMMON; + rtlpriv->btcoexist.bt_profile_action = BT_COEX_MECH_COMMON; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Action 2-Ant common.\n"); + } else { + if ((bt_info_original & BTINFO_B_HID) || + (bt_info_original & BTINFO_B_SCO_BUSY) || + (bt_info_original & BTINFO_B_SCO_ESCO)) { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_BTINFO_B_HID_SCOESCO; + rtlpriv->btcoexist.bt_profile_case = + BT_COEX_MECH_HID_SCO_ESCO; + rtlpriv->btcoexist.bt_profile_action = + BT_COEX_MECH_HID_SCO_ESCO; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n"); + rtl8723e_dm_bt_2_ant_hid_sco_esco(hw); + } else if ((bt_info_original & BTINFO_B_FTP) || + (bt_info_original & BTINFO_B_A2DP)) { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_BTINFO_B_FTP_A2DP; + rtlpriv->btcoexist.bt_profile_case = + BT_COEX_MECH_FTP_A2DP; + rtlpriv->btcoexist.bt_profile_action = + BT_COEX_MECH_FTP_A2DP; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "BTInfo: bFTP|bA2DP\n"); + rtl8723e_dm_bt_2_ant_ftp_a2dp(hw); + } else { + rtlpriv->btcoexist.cstate |= + BT_COEX_STATE_BTINFO_B_HID_SCOESCO; + rtlpriv->btcoexist.bt_profile_case = + BT_COEX_MECH_NONE; + rtlpriv->btcoexist.bt_profile_action = + BT_COEX_MECH_NONE; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], BTInfo: undefined case!!!!\n"); + rtl8723e_dm_bt_2_ant_hid_sco_esco(hw); + } + } +} + +static void _rtl8723e_dm_bt_coexist_1_ant(struct ieee80211_hw *hw) +{ + return; +} + +void rtl8723e_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw) +{ + rtl8723e_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3); + rtl8723e_dm_bt_set_hw_pta_mode(hw, true); +} + +void rtl8723e_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw) +{ + rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, false); + rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); + rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false); + rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, false, TDMA_2ANT, + TDMA_NAV_OFF); + rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT, TDMA_NAV_OFF, + TDMA_DAC_SWING_OFF); + rtl8723e_dm_bt_set_fw_dac_swing_level(hw, 0); + rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false); + rtl8723e_dm_bt_set_fw_bt_retry_index(hw, 2); + rtl8723e_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10); + rtl8723e_dm_bt_set_fw_dec_bt_pwr(hw, false); +} + +void rtl8723e_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw) +{ + rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); + rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF); + rtl8723e_dm_bt_reject_ap_aggregated_packet(hw, false); + + dm_bt_set_sw_penalty_tx_rate_adapt(hw, BT_TX_RATE_ADAPTIVE_NORMAL); + rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME); + rtl8723e_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0); +} + +static void rtl8723e_dm_bt_query_bt_information(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 h2c_parameter[1] = {0}; + + hal_coex_8723.c2h_bt_info_req_sent = true; + + h2c_parameter[0] |= BIT(0); + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "Query Bt information, write 0x38=0x%x\n", h2c_parameter[0]); + + rtl8723e_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter); +} + +static void rtl8723e_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_hp_tx_rx, reg_lp_tx_rx, u32_tmp; + u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; + + reg_hp_tx_rx = REG_HIGH_PRIORITY_TXRX; + reg_lp_tx_rx = REG_LOW_PRIORITY_TXRX; + + u32_tmp = rtl_read_dword(rtlpriv, reg_hp_tx_rx); + reg_hp_tx = u32_tmp & MASKLWORD; + reg_hp_rx = (u32_tmp & MASKHWORD)>>16; + + u32_tmp = rtl_read_dword(rtlpriv, reg_lp_tx_rx); + reg_lp_tx = u32_tmp & MASKLWORD; + reg_lp_rx = (u32_tmp & MASKHWORD)>>16; + + if (rtlpriv->btcoexist.lps_counter > 1) { + reg_hp_tx %= rtlpriv->btcoexist.lps_counter; + reg_hp_rx %= rtlpriv->btcoexist.lps_counter; + reg_lp_tx %= rtlpriv->btcoexist.lps_counter; + reg_lp_rx %= rtlpriv->btcoexist.lps_counter; + } + + hal_coex_8723.high_priority_tx = reg_hp_tx; + hal_coex_8723.high_priority_rx = reg_hp_rx; + hal_coex_8723.low_priority_tx = reg_lp_tx; + hal_coex_8723.low_priority_rx = reg_lp_rx; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", + reg_hp_tx_rx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", + reg_lp_tx_rx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + rtlpriv->btcoexist.lps_counter = 0; + /* rtl_write_byte(rtlpriv, 0x76e, 0xc); */ +} + +static void rtl8723e_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool bt_alife = true; + + if (hal_coex_8723.high_priority_tx == 0 && + hal_coex_8723.high_priority_rx == 0 && + hal_coex_8723.low_priority_tx == 0 && + hal_coex_8723.low_priority_rx == 0) { + bt_alife = false; + } + if (hal_coex_8723.high_priority_tx == 0xeaea && + hal_coex_8723.high_priority_rx == 0xeaea && + hal_coex_8723.low_priority_tx == 0xeaea && + hal_coex_8723.low_priority_rx == 0xeaea) { + bt_alife = false; + } + if (hal_coex_8723.high_priority_tx == 0xffff && + hal_coex_8723.high_priority_rx == 0xffff && + hal_coex_8723.low_priority_tx == 0xffff && + hal_coex_8723.low_priority_rx == 0xffff) { + bt_alife = false; + } + if (bt_alife) { + rtlpriv->btcoexist.bt_active_zero_cnt = 0; + rtlpriv->btcoexist.cur_bt_disabled = false; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "8723A BT is enabled !!\n"); + } else { + rtlpriv->btcoexist.bt_active_zero_cnt++; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "8723A bt all counters=0, %d times!!\n", + rtlpriv->btcoexist.bt_active_zero_cnt); + if (rtlpriv->btcoexist.bt_active_zero_cnt >= 2) { + rtlpriv->btcoexist.cur_bt_disabled = true; + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "8723A BT is disabled !!\n"); + } + } + if (rtlpriv->btcoexist.pre_bt_disabled != + rtlpriv->btcoexist.cur_bt_disabled) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, + DBG_TRACE, "8723A BT is from %s to %s!!\n", + (rtlpriv->btcoexist.pre_bt_disabled ? + "disabled" : "enabled"), + (rtlpriv->btcoexist.cur_bt_disabled ? + "disabled" : "enabled")); + rtlpriv->btcoexist.pre_bt_disabled + = rtlpriv->btcoexist.cur_bt_disabled; + } +} + + +void rtl8723e_dm_bt_coexist_8723(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl8723e_dm_bt_query_bt_information(hw); + rtl8723e_dm_bt_bt_hw_counters_monitor(hw); + rtl8723e_dm_bt_bt_enable_disable_check(hw); + + if (rtlpriv->btcoexist.bt_ant_num == ANT_X2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], 2 Ant mechanism\n"); + _rtl8723e_dm_bt_coexist_2_ant(hw); + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "[BTCoex], 1 Ant mechanism\n"); + _rtl8723e_dm_bt_coexist_1_ant(hw); + } + + if (!rtl8723e_dm_bt_is_same_coexist_state(hw)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n", + rtlpriv->btcoexist.previous_state_h, + rtlpriv->btcoexist.previous_state, + rtlpriv->btcoexist.cstate_h, + rtlpriv->btcoexist.cstate); + rtlpriv->btcoexist.previous_state + = rtlpriv->btcoexist.cstate; + rtlpriv->btcoexist.previous_state_h + = rtlpriv->btcoexist.cstate_h; + } +} + +static void rtl8723e_dm_bt_parse_bt_info(struct ieee80211_hw *hw, + u8 *tmp_buf, u8 len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_info; + u8 i; + + hal_coex_8723.c2h_bt_info_req_sent = false; + hal_coex_8723.bt_retry_cnt = 0; + for (i = 0; i < len; i++) { + if (i == 0) + hal_coex_8723.c2h_bt_info_original = tmp_buf[i]; + else if (i == 1) + hal_coex_8723.bt_retry_cnt = tmp_buf[i]; + if (i == len-1) + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "0x%2x]", tmp_buf[i]); + else + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "0x%2x, ", tmp_buf[i]); + + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "BT info bt_info (Data)= 0x%x\n", + hal_coex_8723.c2h_bt_info_original); + bt_info = hal_coex_8723.c2h_bt_info_original; + + if (bt_info & BIT(2)) + hal_coex_8723.c2h_bt_inquiry_page = true; + else + hal_coex_8723.c2h_bt_inquiry_page = false; + + + if (bt_info & BTINFO_B_CONNECTION) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTC2H], BTInfo: bConnect=true\n"); + rtlpriv->btcoexist.bt_busy = true; + rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_BT_IDLE; + } else { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "[BTC2H], BTInfo: bConnect=false\n"); + rtlpriv->btcoexist.bt_busy = false; + rtlpriv->btcoexist.cstate |= BT_COEX_STATE_BT_IDLE; + } +} +void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct c2h_evt_hdr c2h_event; + u8 *ptmp_buf = NULL; + u8 index = 0; + u8 u1b_tmp = 0; + memset(&c2h_event, 0, sizeof(c2h_event)); + u1b_tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL); + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1b_tmp); + c2h_event.cmd_id = u1b_tmp & 0xF; + c2h_event.cmd_len = (u1b_tmp & 0xF0) >> 4; + c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1); + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n", + c2h_event.cmd_id, c2h_event.cmd_len, c2h_event.cmd_seq); + u1b_tmp = rtl_read_byte(rtlpriv, 0x01AF); + if (u1b_tmp == C2H_EVT_HOST_CLOSE) { + return; + } else if (u1b_tmp != C2H_EVT_FW_CLOSE) { + rtl_write_byte(rtlpriv, 0x1AF, 0x00); + return; + } + ptmp_buf = kzalloc(c2h_event.cmd_len, GFP_KERNEL); + if (ptmp_buf == NULL) { + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "malloc cmd buf failed\n"); + return; + } + + /* Read the content */ + for (index = 0; index < c2h_event.cmd_len; index++) + ptmp_buf[index] = rtl_read_byte(rtlpriv, + REG_C2HEVT_MSG_NORMAL + 2 + index); + + + switch (c2h_event.cmd_id) { + case C2H_V0_BT_RSSI: + break; + + case C2H_V0_BT_OP_MODE: + break; + + case C2H_V0_BT_INFO: + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "BT info Byte[0] (ID) is 0x%x\n", + c2h_event.cmd_id); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "BT info Byte[1] (Seq) is 0x%x\n", + c2h_event.cmd_seq); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "BT info Byte[2] (Data)= 0x%x\n", ptmp_buf[0]); + + rtl8723e_dm_bt_parse_bt_info(hw, ptmp_buf, c2h_event.cmd_len); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv); + + break; + default: + break; + } + kfree(ptmp_buf); + + rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h new file mode 100644 index 000000000..620677128 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_HAL_BTC_H__ +#define __RTL8723E_HAL_BTC_H__ + +#include "../wifi.h" +#include "btc.h" +#include "hal_bt_coexist.h" + +#define BT_TXRX_CNT_THRES_1 1200 +#define BT_TXRX_CNT_THRES_2 1400 +#define BT_TXRX_CNT_THRES_3 3000 +/* < 1200 */ +#define BT_TXRX_CNT_LEVEL_0 0 +/* >= 1200 && < 1400 */ +#define BT_TXRX_CNT_LEVEL_1 1 +/* >= 1400 */ +#define BT_TXRX_CNT_LEVEL_2 2 +#define BT_TXRX_CNT_LEVEL_3 3 + +#define BT_COEX_DISABLE 0 +#define BT_Q_PKT_OFF 0 +#define BT_Q_PKT_ON 1 + +#define BT_TX_PWR_OFF 0 +#define BT_TX_PWR_ON 1 + +/* TDMA mode definition */ +#define TDMA_2ANT 0 +#define TDMA_1ANT 1 +#define TDMA_NAV_OFF 0 +#define TDMA_NAV_ON 1 +#define TDMA_DAC_SWING_OFF 0 +#define TDMA_DAC_SWING_ON 1 + +/* PTA mode related definition */ +#define BT_PTA_MODE_OFF 0 +#define BT_PTA_MODE_ON 1 + +/* Penalty Tx Rate Adaptive */ +#define BT_TX_RATE_ADAPTIVE_NORMAL 0 +#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1 + +/* RF Corner */ +#define BT_RF_RX_LPF_CORNER_RESUME 0 +#define BT_RF_RX_LPF_CORNER_SHRINK 1 + +#define C2H_EVT_HOST_CLOSE 0x00 +#define C2H_EVT_FW_CLOSE 0xFF + +enum bt_traffic_mode { + BT_MOTOR_EXT_BE = 0x00, + BT_MOTOR_EXT_GUL = 0x01, + BT_MOTOR_EXT_GUB = 0x02, + BT_MOTOR_EXT_GULB = 0x03 +}; + +enum bt_traffic_mode_profile { + BT_PROFILE_NONE, + BT_PROFILE_A2DP, + BT_PROFILE_PAN, + BT_PROFILE_HID, + BT_PROFILE_SCO +}; + +/* +enum hci_ext_bt_operation { + HCI_BT_OP_NONE = 0x0, + HCI_BT_OP_INQUIRE_START = 0x1, + HCI_BT_OP_INQUIRE_FINISH = 0x2, + HCI_BT_OP_PAGING_START = 0x3, + HCI_BT_OP_PAGING_SUCCESS = 0x4, + HCI_BT_OP_PAGING_UNSUCCESS = 0x5, + HCI_BT_OP_PAIRING_START = 0x6, + HCI_BT_OP_PAIRING_FINISH = 0x7, + HCI_BT_OP_BT_DEV_ENABLE = 0x8, + HCI_BT_OP_BT_DEV_DISABLE = 0x9, + HCI_BT_OP_MAX, +}; +*/ + +enum bt_spec { + BT_SPEC_1_0_b = 0x00, + BT_SPEC_1_1 = 0x01, + BT_SPEC_1_2 = 0x02, + BT_SPEC_2_0_EDR = 0x03, + BT_SPEC_2_1_EDR = 0x04, + BT_SPEC_3_0_HS = 0x05, + BT_SPEC_4_0 = 0x06 +}; + +struct c2h_evt_hdr { + u8 cmd_id; + u8 cmd_len; + u8 cmd_seq; +}; + +enum bt_state { + BT_INFO_STATE_DISABLED = 0, + BT_INFO_STATE_NO_CONNECTION = 1, + BT_INFO_STATE_CONNECT_IDLE = 2, + BT_INFO_STATE_INQ_OR_PAG = 3, + BT_INFO_STATE_ACL_ONLY_BUSY = 4, + BT_INFO_STATE_SCO_ONLY_BUSY = 5, + BT_INFO_STATE_ACL_SCO_BUSY = 6, + BT_INFO_STATE_HID_BUSY = 7, + BT_INFO_STATE_HID_SCO_BUSY = 8, + BT_INFO_STATE_MAX = 7 +}; + +enum rtl8723e_c2h_evt_v0 { + C2H_V0_DBG = 0, + C2H_V0_TSF = 1, + C2H_V0_AP_RPT_RSP = 2, + /* The FW notify the report of the specific tx packet. */ + C2H_V0_CCX_TX_RPT = 3, + C2H_V0_BT_RSSI = 4, + C2H_V0_BT_OP_MODE = 5, + C2H_V0_HW_INFO_EXCH = 10, + C2H_V0_C2H_H2C_TEST = 11, + C2H_V0_BT_INFO = 12, + MAX_C2HEVENT +}; + +void rtl8723e_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_coexist_8723(struct ieee80211_hw *hw); +void rtl8723e_dm_bt_set_bt_dm(struct ieee80211_hw *hw, + struct btdm_8723 *p_btdm); +void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw); +void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, + bool mstatus); +void rtl8723e_dm_bt_turn_off_bt_coexist_before_enter_lps( + struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c new file mode 100644 index 000000000..bd45d9bd4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c @@ -0,0 +1,2393 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "led.h" +#include "hw.h" +#include "../pwrseqcmd.h" +#include "pwrseq.h" +#include "btc.h" + +#define LLT_CONFIG 5 + +static void _rtl8723e_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl8723e_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723e_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(1); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723e_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8723e_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8723e_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8723e_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl8723e_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *)(val)) = tsf; + + break; + } + case HAL_DEF_WOWLAN: + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +void rtl8723e_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *)val)[0]; + u8 rate_index = 0; + + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (b_rate_cfg >> 8) & 0xff); + while (b_rate_cfg > 0x1) { + b_rate_cfg = (b_rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *)val)); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + + min_spacing_to_set = *((u8 *)val); + if (min_spacing_to_set <= 7) { + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *)val); + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; + u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == + BT_CSR_BC4)) + p_regtoset = regtoset_bt; + else + p_regtoset = regtoset_normal; + + factor_toset = *((u8 *)val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + } + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *)val); + + rtl8723_dm_init_edca_turbo(hw); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *)val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&mac->ac[0].aifs); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl8723e_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + (*(u8 *)val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *)val) | BIT(7))); + } + + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = (*(u8 *)val); + + if (psmode != FW_PS_ACTIVE_MODE) + rtl8723e_dm_rf_saving(hw, true); + + rtl8723e_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *)val); + u8 tmp_regcr, tmp_reg422; + bool b_recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl8723e_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl8723e_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = + rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + b_recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + + rtl8723e_set_fw_rsvdpagepkt(hw, 0); + + _rtl8723e_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl8723e_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) { + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + } + + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl8723e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); + + break; + } + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:{ + rtl8723e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + } + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, + (u2btmp | mac->assoc_id)); + + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl8723e_stop_tx_beacon(hw); + + _rtl8723e_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl8723e_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl8723e_resume_tx_beacon(hw); + + break; + } + case HW_VAR_FW_LPS_ACTION:{ + bool b_enter_fwlps = *((bool *)val); + u8 rpwm_val, fw_pwrmode; + bool fw_current_inps; + + if (b_enter_fwlps) { + rpwm_val = 0x02; /* RF off */ + fw_current_inps = true; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } else { + rpwm_val = 0x0C; /* RF on */ + fw_pwrmode = FW_PS_ACTIVE_MODE; + fw_current_inps = false; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } + break; + } + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +static bool _rtl8723e_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl8723e_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxpage; + bool status; + u8 ubyte; + +#if LLT_CONFIG == 1 + maxpage = 255; + txpktbuf_bndy = 252; +#elif LLT_CONFIG == 2 + maxpage = 127; + txpktbuf_bndy = 124; +#elif LLT_CONFIG == 3 + maxpage = 255; + txpktbuf_bndy = 174; +#elif LLT_CONFIG == 4 + maxpage = 255; + txpktbuf_bndy = 246; +#elif LLT_CONFIG == 5 + maxpage = 255; + txpktbuf_bndy = 246; +#endif + + rtl_write_byte(rtlpriv, REG_CR, 0x8B); + +#if LLT_CONFIG == 1 + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c); + rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c); +#elif LLT_CONFIG == 2 + rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010); +#elif LLT_CONFIG == 3 + rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484); +#elif LLT_CONFIG == 4 + rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c); +#elif LLT_CONFIG == 5 + rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29); + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03); +#endif + + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl8723e_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + status = _rtl8723e_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = _rtl8723e_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + status = _rtl8723e_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + rtl_write_byte(rtlpriv, REG_CR, 0xff); + ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3); + rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7)); + + return true; +} + +static void _rtl8723e_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl8723e_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl8723e_sw_led_on(hw, pin0); + else + rtl8723e_sw_led_off(hw, pin0); +} + +static bool _rtl8712e_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry = 0; + u16 tmpu2b; + bool mac_func_enable; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + bytetmp = rtl_read_byte(rtlpriv, REG_CR); + if (bytetmp == 0xFF) + mac_func_enable = true; + else + mac_func_enable = false; + + /* HW Power on sequence */ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8723_NIC_ENABLE_FLOW)) + return false; + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4)); + + /* eMAC time out function enable, 0x369[7]=1 */ + bytetmp = rtl_read_byte(rtlpriv, 0x369); + rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7)); + + /* ePHY reg 0x1e bit[4]=1 using MDIO interface, + * we should do this before Enabling ASPM backdoor. + */ + do { + rtl_write_word(rtlpriv, 0x358, 0x5e); + udelay(100); + rtl_write_word(rtlpriv, 0x356, 0xc280); + rtl_write_word(rtlpriv, 0x354, 0xc290); + rtl_write_word(rtlpriv, 0x358, 0x3e); + udelay(100); + rtl_write_word(rtlpriv, 0x358, 0x5e); + udelay(100); + tmpu2b = rtl_read_word(rtlpriv, 0x356); + retry++; + } while (tmpu2b != 0xc290 && retry < 100); + + if (retry >= 100) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "InitMAC(): ePHY configure fail!!!\n"); + return false; + } + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + rtl_write_word(rtlpriv, REG_CR + 1, 0x06); + + if (!mac_func_enable) { + if (!_rtl8723e_llt_table_init(hw)) + return false; + } + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && (bytetmp & BIT(7))); + + _rtl8723e_gen_refresh_led_state(hw); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true; +} + +static void _rtl8723e_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_bw_opmode; + u32 reg_prsr; + + reg_bw_opmode = BW_OPMODE_20MHZ; + reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); + + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); + else + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) { + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); + } else { + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); + else + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); + + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + + rtl_write_dword(rtlpriv, 0x394, 0x1); +} + +static void _rtl8723e_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + + if (ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl8723e_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); + +} + +int rtl8723e_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + bool rtstatus; + int err; + u8 tmp_u1b; + unsigned long flags; + + rtlpriv->rtlhal.being_init_adapter = true; + /* As this function can take a very long time (up to 350 ms) + * and can be called with irqs disabled, reenable the irqs + * to let the other devices continue being serviced. + * + * It is safe doing so since our own interrupts will only be enabled + * in a subsequent step. + */ + local_save_flags(flags); + local_irq_enable(); + rtlhal->fw_ready = false; + + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl8712e_init_mac(hw); + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + goto exit; + } + + err = rtl8723_download_fw(hw, false, FW_8723A_POLLING_TIMEOUT_COUNT); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + goto exit; + } + rtlhal->fw_ready = true; + + rtlhal->last_hmeboxnum = 0; + rtl8723e_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 + */ + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + + rtl8723e_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl8723e_phy_rf_config(hw); + if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); + } else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); + rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); + rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); + } + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + _rtl8723e_hw_configure(hw); + rtl_cam_reset_all_entry(hw); + rtl8723e_enable_hw_security_config(hw); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl8723e_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + rtl8723e_bt_hw_init(hw); + + if (ppsc->rfpwr_state == ERFON) { + rtl8723e_phy_set_rfpath_switch(hw, 1); + if (rtlphy->iqk_initialized) { + rtl8723e_phy_iq_calibrate(hw, true); + } else { + rtl8723e_phy_iq_calibrate(hw, false); + rtlphy->iqk_initialized = true; + } + + rtl8723e_dm_check_txpower_tracking(hw); + rtl8723e_phy_lc_calibrate(hw); + } + + tmp_u1b = efuse_read_1byte(hw, 0x1FA); + if (!(tmp_u1b & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); + } + + if (!(tmp_u1b & BIT(4))) { + tmp_u1b = rtl_read_byte(rtlpriv, 0x16); + tmp_u1b &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); + udelay(10); + rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); + } + rtl8723e_dm_init(hw); +exit: + local_irq_restore(flags); + rtlpriv->rtlhal.being_init_adapter = false; + return err; +} + +static enum version_8723e _rtl8723e_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8723e version = 0x0000; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + version = (enum version_8723e)(version | + ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); + /* RTL8723 with BT function. */ + version = (enum version_8723e)(version | + ((value32 & BT_FUNC) ? CHIP_8723 : 0)); + + } else { + /* Normal mass production chip. */ + version = (enum version_8723e) NORMAL_CHIP; + version = (enum version_8723e)(version | + ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); + /* RTL8723 with BT function. */ + version = (enum version_8723e)(version | + ((value32 & BT_FUNC) ? CHIP_8723 : 0)); + if (IS_CHIP_VENDOR_UMC(version)) + version = (enum version_8723e)(version | + ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */ + if (IS_8723_SERIES(version)) { + value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); + /* ROM code version. */ + version = (enum version_8723e)(version | + ((value32 & RF_RL_ID)>>20)); + } + } + + if (IS_8723_SERIES(version)) { + value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); + rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ? + RT_POLARITY_HIGH_ACT : + RT_POLARITY_LOW_ACT); + } + switch (version) { + case VERSION_TEST_UMC_CHIP_8723: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT: + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n"); + break; + default: + pr_err("Chip Version ID: Unknown. Bug?\n"); + break; + } + + if (IS_8723_SERIES(version)) + rtlphy->rf_type = RF_1T1R; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl8723e_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); + rtl_dbg(rtlpriv, COMP_BEACON, DBG_LOUD, + "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && + rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl8723e_stop_tx_beacon(hw); + _rtl8723e_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl8723e_resume_tx_beacon(hw); + _rtl8723e_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, MSR, bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl8723e_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl8723e_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl8723e_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl8723e_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl8723e_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl8723e_set_check_bssid(hw, true); + } else { + rtl8723e_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here + * because mac80211 will send pkt when scan + */ +void rtl8723e_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl8723_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8723ae: invalid aci: %d !\n", aci); + break; + } +} + +void rtl8723e_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl8723e_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +static void _rtl8723e_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + /* Combo (PCIe + USB) Card and PCIe-MF Card */ + /* 1. Run LPS WL RFOFF flow */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW); + + /* 2. 0x1F[7:0] = 0 */ + /* turn off RF */ + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && + rtlhal->fw_ready) { + rtl8723ae_firmware_selfreset(hw); + } + + /* Reset MCU. Suggested by Filen. */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2)))); + + /* g. MCUFWDL 0x80[1:0]=0 */ + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* HW card disable configuration. */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW); + + /* Reset MCU IO Wrapper */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0)); + + /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ + /* lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); +} + +void rtl8723e_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl8723e_set_media_status(hw, opmode); + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl8723e_poweroff_adapter(hw); + + /* after power off we should do iqk again */ + rtlpriv->phy.iqk_initialized = false; +} + +void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, 0x3a0, intvec->inta); +} + +void rtl8723e_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl8723e_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtl8723e_enable_interrupt(hw); +} + +void rtl8723e_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl8723e_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl8723e_enable_interrupt(hw); +} + +void rtl8723e_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl8723e_disable_interrupt(hw); + rtl8723e_enable_interrupt(hw); +} + +static u8 _rtl8723e_get_chnl_group(u8 chnl) +{ + u8 group; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + return group; +} + +static noinline_for_stack void +_rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 1; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + i]; + } else { + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, + i, rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][i]); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eprom_chnl_txpwr_ht40_2sdf + [rf_path][i]); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl8723e_get_chnl_group((u8)i); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][index]; + + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0); + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); + } + } + + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl8723e_get_chnl_group((u8)i); + + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] & + 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] & + 0xf0) >> 4); + } + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); + } + } + + for (i = 0; i < 14; i++) { + index = _rtl8723e_get_chnl_group((u8)i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + + index = _rtl8723e_get_chnl_group((u8)i); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); + + if (!autoload_fail) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); + + if (!autoload_fail) + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + else + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); + + if (!autoload_fail) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->apk_thermalmeterignore = true; + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); +} + +static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw, + bool b_pseudo_test) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13}; + u8 *hwinfo; + + if (b_pseudo_test) { + /* need add */ + return; + } + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + _rtl8723e_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + rtl8723e_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, hwinfo); + + if (rtlhal->oem_id != RT_CID_DEFAULT) + goto exit; + + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + switch (rtlefuse->eeprom_did) { + case 0x8176: + switch (rtlefuse->eeprom_svid) { + case 0x10EC: + switch (rtlefuse->eeprom_smid) { + case 0x6151 ... 0x6152: + case 0x6154 ... 0x6155: + case 0x6177 ... 0x6180: + case 0x7151 ... 0x7152: + case 0x7154 ... 0x7155: + case 0x7177 ... 0x7180: + case 0x8151 ... 0x8152: + case 0x8154 ... 0x8155: + case 0x8181 ... 0x8182: + case 0x8184 ... 0x8185: + case 0x9151 ... 0x9152: + case 0x9154 ... 0x9155: + case 0x9181 ... 0x9182: + case 0x9184 ... 0x9185: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case 0x6191 ... 0x6193: + case 0x7191 ... 0x7193: + case 0x8191 ... 0x8193: + case 0x9191 ... 0x9193: + rtlhal->oem_id = RT_CID_819X_SAMSUNG; + break; + case 0x8197: + case 0x9196: + rtlhal->oem_id = RT_CID_819X_CLEVO; + break; + case 0x8203: + rtlhal->oem_id = RT_CID_819X_PRONETS; + break; + case 0x8195: + case 0x9195: + case 0x7194: + case 0x8200 ... 0x8202: + case 0x9200: + rtlhal->oem_id = RT_CID_819X_LENOVO; + break; + } + break; + case 0x1025: + rtlhal->oem_id = RT_CID_819X_ACER; + break; + case 0x1028: + switch (rtlefuse->eeprom_smid) { + case 0x8194: + case 0x8198: + case 0x9197 ... 0x9198: + rtlhal->oem_id = RT_CID_819X_DELL; + break; + } + break; + case 0x103C: + switch (rtlefuse->eeprom_smid) { + case 0x1629: + rtlhal->oem_id = RT_CID_819X_HP; + } + break; + case 0x1A32: + switch (rtlefuse->eeprom_smid) { + case 0x2315: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + } + break; + case 0x1043: + switch (rtlefuse->eeprom_smid) { + case 0x84B5: + rtlhal->oem_id = + RT_CID_819X_EDIMAX_ASUS; + } + break; + } + break; + case 0x8178: + switch (rtlefuse->eeprom_svid) { + case 0x10ec: + switch (rtlefuse->eeprom_smid) { + case 0x6181 ... 0x6182: + case 0x6184 ... 0x6185: + case 0x7181 ... 0x7182: + case 0x7184 ... 0x7185: + case 0x8181 ... 0x8182: + case 0x8184 ... 0x8185: + case 0x9181 ... 0x9182: + case 0x9184 ... 0x9185: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case 0x8186: + rtlhal->oem_id = + RT_CID_819X_PRONETS; + break; + } + break; + case 0x1025: + rtlhal->oem_id = RT_CID_819X_ACER; + break; + case 0x1043: + switch (rtlefuse->eeprom_smid) { + case 0x8486: + rtlhal->oem_id = + RT_CID_819X_EDIMAX_ASUS; + } + break; + } + break; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_CCX: + rtlhal->oem_id = RT_CID_CCX; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + break; + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } +exit: + kfree(hwinfo); +} + +static void _rtl8723e_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpriv->ledctl.led_opendrain = true; + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl8723e_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]); + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32); + + rtlhal->version = _rtl8723e_read_chip_version(hw); + + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl8723e_read_adapter_info(hw, false); + } else { + rtlefuse->autoload_failflag = true; + _rtl8723e_read_adapter_info(hw, false); + pr_err("Autoload ERR!!\n"); + } + _rtl8723e_hal_customized_behavior(hw); +} + +static void rtl8723e_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 b_nmode = mac->ht_enable; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + u32 ratr_mask; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + b_nmode = 1; + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) && + (rtlpriv->btcoexist.bt_cur_state) && + (rtlpriv->btcoexist.bt_ant_isolation) && + ((rtlpriv->btcoexist.bt_service == BT_SCO) || + (rtlpriv->btcoexist.bt_service == BT_BUSY))) + ratr_value &= 0x0fffcfc0; + else + ratr_value &= 0x0FFFFFFF; + + if (b_nmode && + ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static void rtl8723e_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + /*u8 mimo_ps = IEEE80211_SMPS_OFF;*/ + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->deflink.supp_rates[1] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_G; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4]); + rtl8723e_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); +} + +void rtl8723e_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl8723e_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + rtl8723e_update_hal_rate_table(hw, sta); +} + +void rtl8723e_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl8723e_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp; + bool b_actuallyset = false; + + if (rtlpriv->rtlhal.being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, + rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); + + if (rtlphy->polarity_ctl) + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; + else + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; + + if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + b_actuallyset = true; + } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + *valid = 1; + return !ppsc->hwradiooff; + +} + +void rtl8723e_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = + rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + } + } +} + +static void rtl8723e_bt_var_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->btcoexist.bt_coexistence = + rtlpriv->btcoexist.eeprom_bt_coexist; + rtlpriv->btcoexist.bt_ant_num = + rtlpriv->btcoexist.eeprom_bt_ant_num; + rtlpriv->btcoexist.bt_coexist_type = + rtlpriv->btcoexist.eeprom_bt_type; + + rtlpriv->btcoexist.bt_ant_isolation = + rtlpriv->btcoexist.eeprom_bt_ant_isol; + + rtlpriv->btcoexist.bt_radio_shared_type = + rtlpriv->btcoexist.eeprom_bt_radio_shared; + + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BT Coexistence = 0x%x\n", + rtlpriv->btcoexist.bt_coexistence); + + if (rtlpriv->btcoexist.bt_coexistence) { + rtlpriv->btcoexist.bt_busy_traffic = false; + rtlpriv->btcoexist.bt_traffic_mode_set = false; + rtlpriv->btcoexist.bt_non_traffic_mode_set = false; + + rtlpriv->btcoexist.cstate = 0; + rtlpriv->btcoexist.previous_state = 0; + + if (rtlpriv->btcoexist.bt_ant_num == ANT_X2) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_Ant_Num = Antx2\n"); + } else if (rtlpriv->btcoexist.bt_ant_num == ANT_X1) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_Ant_Num = Antx1\n"); + } + switch (rtlpriv->btcoexist.bt_coexist_type) { + case BT_2WIRE: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_2Wire\n"); + break; + case BT_ISSC_3WIRE: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); + break; + case BT_ACCEL: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_ACCEL\n"); + break; + case BT_CSR_BC4: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_CSR_BC4\n"); + break; + case BT_CSR_BC8: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_CSR_BC8\n"); + break; + case BT_RTL8756: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = BT_RTL8756\n"); + break; + default: + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_CoexistType = Unknown\n"); + break; + } + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BlueTooth BT_Ant_isolation = %d\n", + rtlpriv->btcoexist.bt_ant_isolation); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, + "BT_RadioSharedType = 0x%x\n", + rtlpriv->btcoexist.bt_radio_shared_type); + rtlpriv->btcoexist.bt_active_zero_cnt = 0; + rtlpriv->btcoexist.cur_bt_disabled = false; + rtlpriv->btcoexist.pre_bt_disabled = false; + } +} + +void rtl8723e_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + u32 tmpu_32; + + if (!auto_load_fail) { + tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); + if (tmpu_32 & BIT(18)) + rtlpriv->btcoexist.eeprom_bt_coexist = 1; + else + rtlpriv->btcoexist.eeprom_bt_coexist = 0; + value = hwinfo[RF_OPTION4]; + rtlpriv->btcoexist.eeprom_bt_type = BT_RTL8723A; + rtlpriv->btcoexist.eeprom_bt_ant_num = (value & 0x1); + rtlpriv->btcoexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4); + rtlpriv->btcoexist.eeprom_bt_radio_shared = + ((value & 0x20) >> 5); + } else { + rtlpriv->btcoexist.eeprom_bt_coexist = 0; + rtlpriv->btcoexist.eeprom_bt_type = BT_RTL8723A; + rtlpriv->btcoexist.eeprom_bt_ant_num = ANT_X2; + rtlpriv->btcoexist.eeprom_bt_ant_isol = 0; + rtlpriv->btcoexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; + } + + rtl8723e_bt_var_init(hw); +} + +void rtl8723e_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8723e_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); +} + +void rtl8723e_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl8723e_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h new file mode 100644 index 000000000..cf55f45d0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_HW_H__ +#define __RTL8723E_HW_H__ + +#define CHK_SVID_SMID(_val1, _val2) \ + ((rtlefuse->eeprom_svid == (_val1)) && \ + (rtlefuse->eeprom_smid == (_val2))) + +void rtl8723e_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723e_read_eeprom_info(struct ieee80211_hw *hw); + +void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl8723e_hw_init(struct ieee80211_hw *hw); +void rtl8723e_card_disable(struct ieee80211_hw *hw); +void rtl8723e_enable_interrupt(struct ieee80211_hw *hw); +void rtl8723e_disable_interrupt(struct ieee80211_hw *hw); +int rtl8723e_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl8723e_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8723e_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8723e_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8723e_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8723e_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl8723e_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723e_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl8723e_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8723e_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8723e_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8723e_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +void rtl8723e_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8723e_bt_reg_init(struct ieee80211_hw *hw); +void rtl8723e_bt_hw_init(struct ieee80211_hw *hw); +void rtl8723e_suspend(struct ieee80211_hw *hw); +void rtl8723e_resume(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c new file mode 100644 index 000000000..90d3f6ae8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl8723e_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl8723e_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) { + ledcfg &= 0x90; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); + ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); + ledcfg &= 0xFE; + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); + } else { + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5))); + } + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + ledcfg &= 0x10; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); + + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl8723e_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl8723e_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl8723e_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl8723e_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", + ledaction); + _rtl8723e_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h new file mode 100644 index 000000000..6db5290da --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl8723e_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8723e_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8723e_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c new file mode 100644 index 000000000..71e29b103 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c @@ -0,0 +1,1665 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" +#include "../rtl8723com/phy_common.h" + +static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); +static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8723e_phy_set_io(struct ieee80211_hw *hw); + +u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value = 0, readback_value, bitshift; + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = rtl8723_phy_rf_serial_read(hw, + rfpath, regaddr); + } + + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 original_value = 0, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = rtl8723_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + + rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl8723e_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + +} + +static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + WARN_ONCE(true, "rtl8723ae: _rtl8723e_phy_fw_rf_serial_write deprecated!\n"); +} + +static void _rtl8723e_phy_bb_config_1t(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); + rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); + rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); + rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); +} + +bool rtl8723e_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = _rtl8723e_phy_config_mac_with_headerfile(hw); + rtl_write_byte(rtlpriv, 0x04CA, 0x0A); + return rtstatus; +} + +bool rtl8723e_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmpu1b; + u8 b_reg_hwparafile = 1; + + rtl8723_phy_init_bb_rf_reg_def(hw); + + /* 1. 0x28[1] = 1 */ + tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); + udelay(2); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1))); + udelay(2); + /* 2. 0x29[7:0] = 0xFF */ + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff); + udelay(2); + + /* 3. 0x02[1:0] = 2b'11 */ + tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + (tmpu1b | FEN_BB_GLB_RSTN | FEN_BBRSTB)); + + /* 4. 0x25[6] = 0 */ + tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b & (~BIT(6)))); + + /* 5. 0x24[20] = 0 //Advised by SD3 Alex Wang. 2011.02.09. */ + tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b & (~BIT(4)))); + + /* 6. 0x1f[7:0] = 0x07 */ + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07); + + if (b_reg_hwparafile == 1) + rtstatus = _rtl8723e_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +bool rtl8723e_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl8723e_phy_rf6052_config(hw); +} + +static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + rtstatus = _rtl8723e_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + + if (rtlphy->rf_type == RF_1T2R) { + _rtl8723e_phy_bb_config_1t(hw); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); + } + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl8723e_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = + _rtl8723e_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + + return true; +} + +static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n"); + arraylength = RTL8723E_MACARRAYLENGTH; + ptrarray = RTL8723EMAC_ARRAY; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Img:RTL8192CEMAC_2T_ARRAY\n"); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH; + agctab_array_table = RTL8723EAGCTAB_1TARRAY; + phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH; + phy_regarray_table = RTL8723EPHY_REG_1TARRAY; + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + if (phy_regarray_table[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table[i] == 0xfb) + udelay(50); + else if (phy_regarray_table[i] == 0xfa) + udelay(5); + else if (phy_regarray_table[i] == 0xf9) + udelay(1); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); + } + } + return true; +} + +static void store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][0]); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][1]); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][6]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][7]); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][2]); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][3]); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][4]); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][5]); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][8]); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][9]); + } + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][14]); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][15]); + } + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][10]); + } + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][11]); + } + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][12]); + } + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][13]); + + rtlphy->pwrgroup_cnt++; + } +} + +static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH; + phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + if (phy_regarray_table_pg[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table_pg[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table_pg[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table_pg[i] == 0xfb) + udelay(50); + else if (phy_regarray_table_pg[i] == 0xfa) + udelay(5); + else if (phy_regarray_table_pg[i] == 0xf9) + udelay(1); + + store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +bool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + int i; + u32 *radioa_array_table; + u16 radioa_arraylen; + + radioa_arraylen = RTL8723ERADIOA_1TARRAYLENGTH; + radioa_array_table = RTL8723E_RADIOA_1TARRAY; + + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + if (radioa_array_table[i] == 0xfe) { + mdelay(50); + } else if (radioa_array_table[i] == 0xfd) { + mdelay(5); + } else if (radioa_array_table[i] == 0xfc) { + mdelay(1); + } else if (radioa_array_table[i] == 0xfb) { + udelay(50); + } else if (radioa_array_table[i] == 0xfa) { + udelay(5); + } else if (radioa_array_table[i] == 0xf9) { + udelay(1); + } else { + rtl_set_rfreg(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + udelay(1); + } + } + break; + case RF90_PATH_B: + case RF90_PATH_C: + case RF90_PATH_D: + break; + } + return true; +} + +void rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8) rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +void rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx + + rtlefuse->legacy_ht_txpowerdiff; + if (rtl8723_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (rtl8723_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void _rtl8723e_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (get_rf_type(rtlphy) == RF_2T2R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl8723e_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; + +} + +void rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (!rtlefuse->txpwr_fromeprom) + return; + _rtl8723e_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0]); + _rtl8723e_ccxpower_index_check(hw, + channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + rtl8723e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl8723e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} + +bool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 idx; + u8 rf_path; + u8 ccktxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw, + WIRELESS_MODE_B, + power_indbm); + u8 ofdmtxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw, + WIRELESS_MODE_N_24G, + power_indbm); + if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) + ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; + else + ofdmtxpwridx = 0; + rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE, + "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx); + for (idx = 0; idx < 14; idx++) { + for (rf_path = 0; rf_path < 2; rf_path++) { + rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; + rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = + ofdmtxpwridx; + rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = + ofdmtxpwridx; + } + } + rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); + return true; +} + +static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) +{ + u8 txpwridx; + long offset; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + + if ((power_indbm - offset) > 0) + txpwridx = (u8)((power_indbm - offset) * 2); + else + txpwridx = 0; + + if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) + txpwridx = MAX_TXPWR_IDX_NMODE_92S; + + return txpwridx; +} + +void rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +void rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl8723e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +void rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl8723e_phy_set_bw_mode_callback(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "false driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 delay; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl8723e_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + WARN_ONCE((rtlphy->current_channel > 14), + "rtl8723ae: WIRELESS_MODE_G but channel>14"); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl8723e_phy_sw_chnl_callback(hw); + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false schedule workitem\n"); + rtlphy->sw_chnl_inprogress = false; + } else { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static void _rtl8723e_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { + if (channel == 6 && rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, + MASKDWORD, 0x00255); + else{ + u32 backuprf0x1a = (u32)rtl_get_rfreg(hw, + RF90_PATH_A, RF_RX_G1, + RFREG_OFFSET_MASK); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, + MASKDWORD, backuprf0x1a); + } + } +} + +static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8723ae: illegal channel for Zebra: %d\n", channel); + + rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + pr_err("Invalid 'stage' = %d, Check it!\n", + *stage); + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl8723e_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16) currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8) currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + _rtl8723e_phy_sw_rf_seting(hw, channel); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static u8 _rtl8723e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, + config_pathb ? 0x28160202 : 0x28160502); + + if (config_pathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); + } + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl8723e_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static bool _rtl8723e_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true; + + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } + +} + +static void _rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + const u32 retrycount = 2; + + if (t == 0) { + rtl_get_bbreg(hw, 0x800, MASKDWORD); + + rtl8723_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } + rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + + if (!rtlphy->rfpi_enable) + rtl8723_phy_pi_mode_switch(hw, true); + if (t == 0) { + rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); + rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); + rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl8723e_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x03) { + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & 0x3FF0000) >> + 16; + result[t][1] = + (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; + + } + + if (is2t) { + rtl8723_phy_path_a_standby(hw); + rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl8723e_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); + rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + if (t != 0) { + if (!rtlphy->rfpi_enable) + rtl8723_phy_pi_mode_switch(hw, false); + rtl8723_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } +} + +static void _rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + + mdelay(100); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static void _rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) { + rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); + else + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); + + } + +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + long result[4][8]; + u8 i, final_candidate; + bool b_patha_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, + reg_tmp = 0; + bool is12simular, is13simular, is23simular; + u32 iqk_bb_reg[10] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (b_recovery) { + rtl8723_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); + return; + } + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + _rtl8723e_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = + _rtl8723e_phy_simularity_compare(hw, result, 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = + _rtl8723e_phy_simularity_compare(hw, result, 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = + _rtl8723e_phy_simularity_compare(hw, result, 1, 2); + if (is23simular) + final_candidate = 1; + else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; + rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; + rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; + b_patha_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) + rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + rtl8723_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); +} + +void rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + _rtl8723e_phy_lc_calibrate(hw, false); +} + +void rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + _rtl8723e_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", iotype); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl8723e_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl8723e_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl8723e_dm_write_dig(hw); + rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = 0x17; + rtl8723e_dm_write_dig(hw); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + +static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl8723e_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + u32 u4b_tmp; + u8 delay = 5; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4b_tmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Switch RF timeout !!!.\n"); + return; + } + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl8723e_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + case ERFOFF: + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl8723e_phy_set_rf_sleep(hw); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl8723e_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h new file mode 100644 index 000000000..98bfe02f6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define reset_cnt_limit 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define IQK_DELAY_TIME 1 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl8723e_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8723e_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8723e_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +bool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +void rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +void rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c new file mode 100644 index 000000000..041e3113a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../pwrseqcmd.h" +#include "pwrseq.h" + +/* drivers should parse below arrays and do the corresponding actions */ +/*3 Power on Array*/ +struct wlan_pwr_cfg rtl8723A_power_on_flow + [RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_CARDEMU_TO_ACT + RTL8723A_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8723A_radio_off_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_ACT_TO_CARDEMU + RTL8723A_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8723A_card_disable_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_ACT_TO_CARDEMU + RTL8723A_TRANS_CARDEMU_TO_CARDDIS + RTL8723A_TRANS_END +}; + +/*3 Card Enable Array*/ +struct wlan_pwr_cfg rtl8723A_card_enable_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_CARDDIS_TO_CARDEMU + RTL8723A_TRANS_CARDEMU_TO_ACT + RTL8723A_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8723A_suspend_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_ACT_TO_CARDEMU + RTL8723A_TRANS_CARDEMU_TO_SUS + RTL8723A_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8723A_resume_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_SUS_TO_CARDEMU + RTL8723A_TRANS_CARDEMU_TO_ACT + RTL8723A_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8723A_hwpdn_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS] = { + RTL8723A_TRANS_ACT_TO_CARDEMU + RTL8723A_TRANS_CARDEMU_TO_PDN + RTL8723A_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8723A_enter_lps_flow + [RTL8723A_TRANS_ACT_TO_LPS_STEPS + + RTL8723A_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8723A_TRANS_ACT_TO_LPS + RTL8723A_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8723A_leave_lps_flow + [RTL8723A_TRANS_LPS_TO_ACT_STEPS + + RTL8723A_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8723A_TRANS_LPS_TO_ACT + RTL8723A_TRANS_END +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h new file mode 100644 index 000000000..d9247a8f3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h @@ -0,0 +1,318 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_PWRSEQ_H__ +#define __RTL8723E_PWRSEQ_H__ + +#include "../pwrseqcmd.h" +/* + * Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd + * There are 6 HW Power States: + * 0: POFF--Power Off + * 1: PDN--Power Down + * 2: CARDEMU--Card Emulation + * 3: ACT--Active Mode + * 4: LPS--Low Power State + * 5: SUS--Suspend + * + * The transision from different states are defined below + * TRANS_CARDEMU_TO_ACT + * TRANS_ACT_TO_CARDEMU + * TRANS_CARDEMU_TO_SUS + * TRANS_SUS_TO_CARDEMU + * TRANS_CARDEMU_TO_PDN + * TRANS_ACT_TO_LPS + * TRANS_LPS_TO_ACT + * + * TRANS_END + */ + +#define RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS 10 +#define RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS 10 +#define RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS 10 +#define RTL8723A_TRANS_SUS_TO_CARDEMU_STEPS 10 +#define RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS 10 +#define RTL8723A_TRANS_PDN_TO_CARDEMU_STEPS 10 +#define RTL8723A_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8723A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8723A_TRANS_END_STEPS 1 + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }*/ + +#define RTL8723A_TRANS_CARDEMU_TO_ACT \ + /* disable SW LPS 0x04[10]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0},\ + /* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},\ + /* release WLON reset 0x04[16]=1*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},\ + /* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},\ + /* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0},\ + /* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_ACT_TO_CARDEMU \ + /*0x1F[7:0] = 0 turn off RF*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/ +#define RTL8723A_TRANS_CARDEMU_TO_SUS \ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, \ + BIT(4)|BIT(3), (BIT(4)|BIT(3))},\ +/*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK| \ + PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, \ + BIT(3)|BIT(4), BIT(3)}, \ +/*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(3)|BIT(4), \ + BIT(3)|BIT(4)}, \ +/*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_WRITE, BIT(0), BIT(0)}, \ +/*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_POLLING, BIT(1), 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_SUS_TO_CARDEMU \ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0},\ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)},\ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ + /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \ +/*0x04[10] = 1, enable SW LPS*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(2), BIT(2)}, \ +/*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_POLLING, BIT(1), 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU\ +/*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_WRITE, BIT(0), 0}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_POLLING, BIT(1), BIT(1)},\ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(3)|BIT(4), 0},\ +/*PCIe DMA start*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0}, + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ +#define RTL8723A_TRANS_CARDEMU_TO_PDN \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/ + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ +#define RTL8723A_TRANS_PDN_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/ + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_ACT_TO_LPS \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ + /*Should be zero if no packet is transmitting*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_POLLING, 0xFF, 0},\ + /*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_POLLING, 0xFF, 0},\ + /*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_POLLING, 0xFF, 0},\ + /*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_POLLING, 0xFF, 0},\ + /*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(0), 0},\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(1), 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \ + /*Respond TxOK to scheduler*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(5), BIT(5)},\ + +#define RTL8723A_TRANS_LPS_TO_ACT\ +/* format */ \ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ + PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(4), 0}, \ + /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_POLLING, BIT(7), 0}, \ + /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(6)|BIT(7), 0},\ + /*. 0x101[1] = 1*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(1), BIT(1)},\ + /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0xFF},\ + /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0)},\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ + PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +/* format */ +/* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */ + +#define RTL8723A_TRANS_END \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + 0, PWR_CMD_END, 0, 0} + +extern struct wlan_pwr_cfg rtl8723A_power_on_flow + [RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_radio_off_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_card_disable_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_card_enable_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_suspend_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_resume_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_hwpdn_flow + [RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_enter_lps_flow + [RTL8723A_TRANS_ACT_TO_LPS_STEPS + RTL8723A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723A_leave_lps_flow + [RTL8723A_TRANS_LPS_TO_ACT_STEPS + RTL8723A_TRANS_END_STEPS]; + +/* RTL8723 Power Configuration CMDs for PCIe interface */ +#define RTL8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow +#define RTL8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow +#define RTL8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow +#define RTL8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow +#define RTL8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow +#define RTL8723_NIC_RESUME_FLOW rtl8723A_resume_flow +#define RTL8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow +#define RTL8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow +#define RTL8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h new file mode 100644 index 000000000..8696614c7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h @@ -0,0 +1,2098 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_REG_H__ +#define __RTL8723E_REG_H__ + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_GPIO_PIN_CTRL_2 0x0060 +#define REG_GPIO_IO_SEL_2 0x0062 +#define REG_MULTI_FUNC_CTRL 0x0068 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BCNINT BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +/* 8723E series PCIE Host IMR/ISR bit */ +/* IMR DW0 Bit 0-31 */ +#define PHIMR_TIMEOUT2 BIT(31) +#define PHIMR_TIMEOUT1 BIT(30) +#define PHIMR_PSTIMEOUT BIT(29) +#define PHIMR_GTINT4 BIT(28) +#define PHIMR_GTINT3 BIT(27) +#define PHIMR_TXBCNERR BIT(26) +#define PHIMR_TXBCNOK BIT(25) +#define PHIMR_TSF_BIT32_TOGGLE BIT(24) +#define PHIMR_BCNDMAINT3 BIT(23) +#define PHIMR_BCNDMAINT2 BIT(22) +#define PHIMR_BCNDMAINT1 BIT(21) +#define PHIMR_BCNDMAINT0 BIT(20) +#define PHIMR_BCNDOK3 BIT(19) +#define PHIMR_BCNDOK2 BIT(18) +#define PHIMR_BCNDOK1 BIT(17) +#define PHIMR_BCNDOK0 BIT(16) +#define PHIMR_HSISR_IND_ON BIT(15) +#define PHIMR_BCNDMAINT_E BIT(14) +#define PHIMR_ATIMEND_E BIT(13) +#define PHIMR_ATIM_CTW_END BIT(12) +#define PHIMR_HISRE_IND BIT(11) +#define PHIMR_C2HCMD BIT(10) +#define PHIMR_CPWM2 BIT(9) +#define PHIMR_CPWM BIT(8) +#define PHIMR_HIGHDOK BIT(7) +#define PHIMR_MGNTDOK BIT(6) +#define PHIMR_BKDOK BIT(5) +#define PHIMR_BEDOK BIT(4) +#define PHIMR_VIDOK BIT(3) +#define PHIMR_VODOK BIT(2) +#define PHIMR_RDU BIT(1) +#define PHIMR_ROK BIT(0) + +/* PCIE Host Interrupt Status Extension bit */ +#define PHIMR_BCNDMAINT7 BIT(23) +#define PHIMR_BCNDMAINT6 BIT(22) +#define PHIMR_BCNDMAINT5 BIT(21) +#define PHIMR_BCNDMAINT4 BIT(20) +#define PHIMR_BCNDOK7 BIT(19) +#define PHIMR_BCNDOK6 BIT(18) +#define PHIMR_BCNDOK5 BIT(17) +#define PHIMR_BCNDOK4 BIT(16) +/* bit12-15: RSVD */ +#define PHIMR_TXERR BIT(11) +#define PHIMR_RXERR BIT(10) +#define PHIMR_TXFOVW BIT(9) +#define PHIMR_RXFOVW BIT(8) +/* bit2-7: RSVD */ +#define PHIMR_OCPINT BIT(1) + +#define HWSET_MAX_SIZE 256 +#define EFUSE_MAX_SECTION 32 +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x12 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8192_EEPROM_ID 0x8129 + +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_VID 0x49 +#define EEPROM_DID 0x4B +#define EEPROM_SVID 0x4D +#define EEPROM_SMID 0x4F + +#define EEPROM_MAC_ADDR 0x67 + +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x25 +#define EEPROM_HT20_MAX_PWR_OFFSET 0x22 + +#define EEPROM_THERMAL_METER 0x2a +#define EEPROM_XTAL_K 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_CHANNEL_PLAN 0x28 +#define EEPROM_VERSION 0x30 +#define EEPROM_CUSTOMER_ID 0x31 + +#define EEPROM_PWRDIFF 0x54 + +#define EEPROM_TXPOWERCCK 0x10 +#define EEPROM_TXPOWERHT40_1S 0x16 +#define EEPROM_TXPOWERHT40_2SDIFF 0x66 +#define EEPROM_TXPOWERHT20DIFF 0x1C +#define EEPROM_TXPOWER_OFDMDIFF 0x1F + +#define EEPROM_TXPWR_GROUP 0x22 + +#define EEPROM_TSSI_A 0x29 +#define EEPROM_TSSI_B 0x77 + +#define EEPROM_CHANNELPLAN 0x28 + +#define RF_OPTION1 0x2B +#define RF_OPTION2 0x2C +#define RF_OPTION3 0x2D +#define RF_OPTION4 0x2E + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) \ + ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCKRXRFSETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +/* 2 EFUSE_TEST (For RTL8723 partially) */ +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +/* Enable GPIO[9] as WiFi HW PDn source*/ +#define WL_HWPDN_EN BIT(0) +/* WiFi HW PDn polarity control*/ +#define WL_HWPDN_SL BIT(1) + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c new file mode 100644 index 000000000..b8ed80c84 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl8723e_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl8723e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; + idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *)&tx_agc[idx1]; + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + tmpval = tmpval & 0xff00ffff; + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl8723e_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerbase0, powerbase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerbase0 = powerlevel[i] + legacy_pwrdiff; + + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = + rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | + (powerbase1 << 16) | (powerbase1 << 8) | powerbase1; + + *(mcsbase + i) = powerbase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); + } +} + +static void get_txpower_writeval_by_reg(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4]; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 1: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + writeval = ((index < 2) ? powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 40MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + } else { + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + chnlgroup++; + else + chnlgroup += 4; + } + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + } + break; + case 2: + writeval = + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] & (0x7f << + (i * 8))) >> (i * 8)); + + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht40[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse-> + pwrgroup_ht20[rf][channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit); + + writeval = customer_limit + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + default: + chnlgroup = 0; + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeval = writeval - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl8723e_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = pvalue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + + writeval = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + + for (i = 0; i < 3; i++) { + writeval = (writeval > 6) ? (writeval - 6) : 0; + rtl_write_byte(rtlpriv, (u32) (regoffset + i), + (u8)writeval); + } + } + } +} + +void rtl8723e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + + rtl8723e_phy_get_power_base(hw, ppowerlevel, + channel, &powerbase0[0], &powerbase1[0]); + + for (index = 0; index < 6; index++) { + get_txpower_writeval_by_reg(hw, channel, index, &powerbase0[0], + &powerbase1[0], + &writeval[0]); + + _rtl8723e_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl8723e_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl8723e_phy_rf6052_config_parafile(hw); +} + +static bool _rtl8723e_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl8723e_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = + rtl8723e_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h new file mode 100644 index 000000000..b445cfe65 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_RF_H__ +#define __RTL8723E_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +void rtl8723e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl8723e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl8723e_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c new file mode 100644 index 000000000..dcd7cdb96 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "hw.h" +#include "trx.h" +#include "led.h" +#include "table.h" +#include "hal_btc.h" +#include "../btcoexist/rtl_btc.h" +#include "../rtl8723com/phy_common.h" + +#include +#include + +static void rtl8723e_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /** + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /** + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /** + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int err = 0; + char *fw_name = "rtlwifi/rtl8723fw.bin"; + + rtl8723e_bt_reg_init(hw); + + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + /* compatible 5G band 88ce just 2.4G band & smsp */ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | + RCR_ADF | + RCR_AICV | + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = + (u32) (PHIMR_ROK | + PHIMR_RDU | + PHIMR_VODOK | + PHIMR_VIDOK | + PHIMR_BEDOK | + PHIMR_BKDOK | + PHIMR_MGNTDOK | + PHIMR_HIGHDOK | + PHIMR_C2HCMD | + PHIMR_HISRE_IND | + PHIMR_TSF_BIT32_TOGGLE | + PHIMR_TXBCNOK | + PHIMR_PSTIMEOUT | + 0); + + rtlpci->irq_mask[1] = + (u32)(PHIMR_RXFOVW | + 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + rtl8723e_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x6000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw.\n"); + return 1; + } + + if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) + fw_name = "rtlwifi/rtl8723fw_B.bin"; + + rtlpriv->max_fw_size = 0x6000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + return 0; +} + +static void rtl8723e_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +static bool rtl8723e_get_btc_status(void) +{ + return true; +} + +static bool is_fw_header(struct rtlwifi_firmware_header *hdr) +{ + return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x2300; +} + +static const struct rtl_hal_ops rtl8723e_hal_ops = { + .init_sw_vars = rtl8723e_init_sw_vars, + .deinit_sw_vars = rtl8723e_deinit_sw_vars, + .read_eeprom_info = rtl8723e_read_eeprom_info, + .interrupt_recognized = rtl8723e_interrupt_recognized, + .hw_init = rtl8723e_hw_init, + .hw_disable = rtl8723e_card_disable, + .hw_suspend = rtl8723e_suspend, + .hw_resume = rtl8723e_resume, + .enable_interrupt = rtl8723e_enable_interrupt, + .disable_interrupt = rtl8723e_disable_interrupt, + .set_network_type = rtl8723e_set_network_type, + .set_chk_bssid = rtl8723e_set_check_bssid, + .set_qos = rtl8723e_set_qos, + .set_bcn_reg = rtl8723e_set_beacon_related_registers, + .set_bcn_intv = rtl8723e_set_beacon_interval, + .update_interrupt_mask = rtl8723e_update_interrupt_mask, + .get_hw_reg = rtl8723e_get_hw_reg, + .set_hw_reg = rtl8723e_set_hw_reg, + .update_rate_tbl = rtl8723e_update_hal_rate_tbl, + .fill_tx_desc = rtl8723e_tx_fill_desc, + .fill_tx_cmddesc = rtl8723e_tx_fill_cmddesc, + .query_rx_desc = rtl8723e_rx_query_desc, + .set_channel_access = rtl8723e_update_channel_access_setting, + .radio_onoff_checking = rtl8723e_gpio_radio_on_off_checking, + .set_bw_mode = rtl8723e_phy_set_bw_mode, + .switch_channel = rtl8723e_phy_sw_chnl, + .dm_watchdog = rtl8723e_dm_watchdog, + .scan_operation_backup = rtl8723e_phy_scan_operation_backup, + .set_rf_power_state = rtl8723e_phy_set_rf_power_state, + .led_control = rtl8723e_led_control, + .set_desc = rtl8723e_set_desc, + .get_desc = rtl8723e_get_desc, + .is_tx_desc_closed = rtl8723e_is_tx_desc_closed, + .tx_polling = rtl8723e_tx_polling, + .enable_hw_sec = rtl8723e_enable_hw_security_config, + .set_key = rtl8723e_set_key, + .get_bbreg = rtl8723_phy_query_bb_reg, + .set_bbreg = rtl8723_phy_set_bb_reg, + .get_rfreg = rtl8723e_phy_query_rf_reg, + .set_rfreg = rtl8723e_phy_set_rf_reg, + .c2h_command_handle = rtl_8723e_c2h_command_handle, + .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, + .bt_coex_off_before_lps = + rtl8723e_dm_bt_turn_off_bt_coexist_before_enter_lps, + .get_btc_status = rtl8723e_get_btc_status, + .is_fw_header = is_fw_header, +}; + +static struct rtl_mod_params rtl8723e_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = true, + .fwctrl_lps = false, + .aspm_support = 1, + .debug_level = 0, + .debug_mask = 0, + .msi_support = false, + .disable_watchdog = false, +}; + +static const struct rtl_hal_cfg rtl8723e_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723e_pci", + .ops = &rtl8723e_hal_ops, + .mod_params = &rtl8723e_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = PHIMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW, + .maps[RTL_IMR_RDU] = PHIMR_RDU, + .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E, + .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR, + .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK, + .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK, + .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK, + .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK, + .maps[RTL_IMR_VODOK] = PHIMR_VODOK, + .maps[RTL_IMR_ROK] = PHIMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = + (PHIMR_BCNDMAINT0 | PHIMR_TXBCNOK | PHIMR_TXBCNERR), + .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD, + + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static const struct pci_device_id rtl8723e_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723e_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8723e_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin"); + +module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8723e_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl8723e_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8723e_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8723e_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8723e_mod_params.msi_support, bool, 0444); +module_param_named(aspm, rtl8723e_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl8723e_mod_params.disable_watchdog, + bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8723e_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8723e_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8723e_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c new file mode 100644 index 000000000..d895694be --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c @@ -0,0 +1,704 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "table.h" + +u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = { + 0x800, 0x80040000, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66f60110, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000760, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xa78, 0x00000900, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x7116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000008, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x0a0c0c0c, + 0xe04, 0xffffffff, 0x02040608, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0e, + 0xe14, 0xffffffff, 0x02040608, + 0xe18, 0xffffffff, 0x0a0c0d0e, + 0xe1c, 0xffffffff, 0x02040608, + 0x830, 0xffffffff, 0x0a0c0c0c, + 0x834, 0xffffffff, 0x02040608, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0a0c0d0e, + 0x848, 0xffffffff, 0x02040608, + 0x84c, 0xffffffff, 0x0a0c0d0e, + 0x868, 0xffffffff, 0x02040608, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8723E_RADIOA_1TARRAY[RTL8723ERADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001a3f1, + 0x00b, 0x00014787, + 0x00c, 0x000896fe, + 0x00d, 0x0000e02c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00030355, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x00057730, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287b3, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x0001429b, + 0x013, 0x00010299, + 0x013, 0x0000c29c, + 0x013, 0x000081a0, + 0x013, 0x000040ac, + 0x013, 0x00000020, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f407, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x00000339, + 0x016, 0x00040339, + 0x016, 0x00080339, + 0x016, 0x000c0336, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000e, + 0x63e, 0x0000000a, + 0x63f, 0x0000000e, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h new file mode 100644 index 000000000..4897dbc73 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_TABLE__H_ +#define __RTL8723E_TABLE__H_ + +#include + +#define RTL8723E_PHY_REG_1TARRAY_LENGTH 372 +extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH]; +#define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336 +extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH]; +#define RTL8723ERADIOA_1TARRAYLENGTH 282 +extern u32 RTL8723E_RADIOA_1TARRAY[RTL8723ERADIOA_1TARRAYLENGTH]; +#define RTL8723E_MACARRAYLENGTH 172 +extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH]; +#define RTL8723E_AGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c new file mode 100644 index 000000000..65bfc1470 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c @@ -0,0 +1,687 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" + +static u8 _rtl8723e_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl8723e_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstatus, u8 *pdesc, + struct rx_fwinfo_8723e *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct phy_sts_cck_8723e_t *cck_buf; + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstatus->is_cck; + + /* Record it for next packet processing */ + pstatus->packet_matchbssid = bpacket_match_bssid; + pstatus->packet_toself = bpacket_toself; + pstatus->packet_beacon = packet_beacon; + pstatus->rx_mimo_signalquality[0] = -1; + pstatus->rx_mimo_signalquality[1] = -1; + + if (is_cck) { + u8 report, cck_highpwr; + + /* CCK Driver info Structure is not the same as OFDM packet. */ + cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; + + /* (1)Hardware does not provide RSSI for CCK */ + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = (u8)rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + else + cck_highpwr = false; + + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + /* CCK gain is smaller than OFDM/MCS gain, */ + /* so we add gain diff by experiences, + * the val is 6 + */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same + * gain index with OFDM. + */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + + pstatus->rx_pwdb_all = pwdb_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (bpacket_match_bssid) { + u8 sq; + + if (pstatus->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstatus->signalquality = sq; + pstatus->rx_mimo_signalquality[0] = sq; + pstatus->rx_mimo_signalquality[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & + 0x3f) * 2) - 110; + + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + + /* Get Rx snr value in DB */ + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + /* Record Signal Strength for next packet */ + if (bpacket_match_bssid) + pstatus->rx_mimo_signalstrength[i] = (u8)rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstatus->rx_pwdb_all = pwdb_all; + pstatus->rxpower = rx_pwr_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 && + pstatus->rate <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + + if (bpacket_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream only + */ + if (i == 0) + pstatus->signalquality = + (u8)(evm & 0xff); + pstatus->rx_mimo_signalquality[i] = + (u8)(evm & 0xff); + } + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, u8 *pdesc, + struct rx_fwinfo_8723e *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + /*u8 *psaddr;*/ + u16 fc, type; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_control); + type = WLAN_FC_GET_TYPE(hdr->frame_control); + praddr = hdr->addr1; + + packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && + (ether_addr_equal(mac->bssid, (fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && + (!pstatus->hwerror) && + (!pstatus->crc) && (!pstatus->icv)); + + packet_toself = packet_matchbssid && + (ether_addr_equal(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(hdr->frame_control)) + packet_beacon = true; + else + packet_beacon = false; + + _rtl8723e_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rx_fwinfo_8723e *p_drvinfo; + struct ieee80211_hdr *hdr; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_physt(pdesc); + + status->length = (u16)get_rx_desc_pkt_len(pdesc); + status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + status->icv = (u16)get_rx_desc_icv(pdesc); + status->crc = (u16)get_rx_desc_crc32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !get_rx_desc_swdec(pdesc); + status->rate = (u8)get_rx_desc_rxmcs(pdesc); + status->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) && + (get_rx_desc_faggr(pdesc) == 1)); + status->timestamp_low = get_rx_desc_tsfl(pdesc); + status->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc); + status->is_ht = (bool)get_rx_desc_rxht(pdesc); + + status->is_cck = RX_HAL_IS_CCK_RATE(status->rate); + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + * Notice: this is diff with windows define + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, + false, status->rate); + + rx_status->mactime = status->timestamp_low; + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data + + status->rx_bufshift); + + translate_rx_signal_stuff(hw, skb, status, pdesc8, p_drvinfo); + } + rx_status->signal = status->recvsignalpower + 10; + return true; +} + +void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *txbd, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + /* bool b_trigger_ac = false; */ + u8 *pdesc8 = (u8 *)pdesc_tx; + __le32 *pdesc = (__le32 *)pdesc8; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 fw_qsel = _rtl8723e_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + u8 bw_40 = 0; + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_8723e)); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + + if (firstseg) { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + + if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) + set_tx_desc_data_shortgi(pdesc, 1); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_break(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + + set_tx_desc_rts_enable(pdesc, + ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, + ((ptcb_desc->rts_enable || + ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_cts2self(pdesc, + ((ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_rts_stbc(pdesc, + ((ptcb_desc->rts_stbc) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_bw(pdesc, 0); + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, + ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) + : (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (bw_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, + mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb->len); + + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + + } + } + + set_tx_desc_pkt_id(pdesc, 0); + set_tx_desc_queue_sel(pdesc, fw_qsel); + + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + + set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + if (rtlpriv->dm.useramask) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->ratr_index); + } + + if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { + set_tx_desc_hwseq_en_8723(pdesc, 1); + /* set_tx_desc_hwseq_en(pdesc, 1); */ + /* set_tx_desc_pkt_id(pdesc, 8); */ + /* set_tx_desc_qos(pdesc, 1); */ + } + + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + __le32 *pdesc = (__le32 *)pdesc8; + + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_tx_rate(pdesc, DESC92C_RATE1M); + + set_tx_desc_seq(pdesc, 0); + + set_tx_desc_linip(pdesc, 0); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_rate_id(pdesc, 7); + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_offset(pdesc, 0x20); + + set_tx_desc_use_rate(pdesc, 1); + + if (!ieee80211_is_data_qos(fc)) { + set_tx_desc_hwseq_en_8723(pdesc, 1); + /* set_tx_desc_hwseq_en(pdesc, 1); */ + /* set_tx_desc_pkt_id(pdesc, 8); */ + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", + pdesc, TX_DESC_SIZE); +} + +void rtl8723e_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, + bool istx, u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl8723e_get_desc(struct ieee80211_hw *hw, + u8 *pdesc8, bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(pdesc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(pdesc); + break; + default: + WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(pdesc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(pdesc); + break; + default: + WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl8723e_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl8723e_get_desc(hw, entry, true, HW_DESC_OWN); + + /** + *beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl8723e_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h new file mode 100644 index 000000000..f352fddff --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h @@ -0,0 +1,534 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL8723E_TRX_H__ +#define __RTL8723E_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_agg_break(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(5)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, BIT(7)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16)); +} + +static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28)); +} + +/* For RTL8723 */ +static inline void set_tx_desc_hwseq_en_8723(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(31)); +} + +static inline void set_tx_desc_hwseq_sel_8723(__le32 *__txdesc, u32 __value) +{ + le32p_replace_bits((__txdesc + 4), __value, GENMASK(7, 6)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(13)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(25)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(26)); +} + +static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, BIT(27)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28)); +} + +static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(6)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 8) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 8)); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(13, 0)); +} + +static inline u32 get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(14)); +} + +static inline u32 get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(15)); +} + +static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(19, 16)); +} + +static inline u32 get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(25, 24)); +} + +static inline u32 get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(26)); +} + +static inline u32 get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(27)); +} + +static inline u32 get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(14)); +} + +static inline u32 get_rx_desc_faggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0)); +} + +static inline u32 get_rx_desc_rxht(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(6)); +} + +static inline u32 get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(8)); +} + +static inline u32 get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(9)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 5)); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 6)); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size) +{ + if (_size > TX_DESC_NEXT_DESC_OFFSET) + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); + else + memset(__pdesc, 0, _size); +} + +struct rx_fwinfo_8723e { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_8723e { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_8723e { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + u8 *pdesc, u8 *txbd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl8723e_set_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name, u8 *val); +u64 rtl8723e_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl8723e_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl8723e_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile new file mode 100644 index 000000000..d3ed44d80 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8723be-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + pwrseq.o \ + rf.o \ + sw.o \ + table.o \ + trx.o \ + + +obj-$(CONFIG_RTL8723BE) += rtl8723be.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h new file mode 100644 index 000000000..f4886c868 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_DEF_H__ +#define __RTL8723BE_DEF_H__ + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + + +#define RX_MPDU_QUEUE 0 +#define CHIP_8723B (BIT(1) | BIT(2)) +#define NORMAL_CHIP BIT(3) +#define CHIP_VENDOR_SMIC BIT(8) +/* Currently only for RTL8723B */ +#define EXT_VENDOR_ID (BIT(18) | BIT(19)) + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc8723e_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, +}; +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c new file mode 100644 index 000000000..c65d14fb9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c @@ -0,0 +1,1266 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "trx.h" +#include "../btcoexist/rtl_btc.h" + +static const u32 ofdmswing_table[] = { + 0x0b40002d, /* 0, -15.0dB */ + 0x0c000030, /* 1, -14.5dB */ + 0x0cc00033, /* 2, -14.0dB */ + 0x0d800036, /* 3, -13.5dB */ + 0x0e400039, /* 4, -13.0dB */ + 0x0f00003c, /* 5, -12.5dB */ + 0x10000040, /* 6, -12.0dB */ + 0x11000044, /* 7, -11.5dB */ + 0x12000048, /* 8, -11.0dB */ + 0x1300004c, /* 9, -10.5dB */ + 0x14400051, /* 10, -10.0dB */ + 0x15800056, /* 11, -9.5dB */ + 0x16c0005b, /* 12, -9.0dB */ + 0x18000060, /* 13, -8.5dB */ + 0x19800066, /* 14, -8.0dB */ + 0x1b00006c, /* 15, -7.5dB */ + 0x1c800072, /* 16, -7.0dB */ + 0x1e400079, /* 17, -6.5dB */ + 0x20000080, /* 18, -6.0dB */ + 0x22000088, /* 19, -5.5dB */ + 0x24000090, /* 20, -5.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x288000a2, /* 22, -4.0dB */ + 0x2ac000ab, /* 23, -3.5dB */ + 0x2d4000b5, /* 24, -3.0dB */ + 0x300000c0, /* 25, -2.5dB */ + 0x32c000cb, /* 26, -2.0dB */ + 0x35c000d7, /* 27, -1.5dB */ + 0x390000e4, /* 28, -1.0dB */ + 0x3c8000f2, /* 29, -0.5dB */ + 0x40000100, /* 30, +0dB */ + 0x43c0010f, /* 31, +0.5dB */ + 0x47c0011f, /* 32, +1.0dB */ + 0x4c000130, /* 33, +1.5dB */ + 0x50800142, /* 34, +2.0dB */ + 0x55400155, /* 35, +2.5dB */ + 0x5a400169, /* 36, +3.0dB */ + 0x5fc0017f, /* 37, +3.5dB */ + 0x65400195, /* 38, +4.0dB */ + 0x6b8001ae, /* 39, +4.5dB */ + 0x71c001c7, /* 40, +5.0dB */ + 0x788001e2, /* 41, +5.5dB */ + 0x7f8001fe /* 42, +6.0dB */ +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */ + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */ +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */ + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */ +}; + +static const u32 edca_setting_dl[PEER_MAX] = { + 0xa44f, /* 0 UNKNOWN */ + 0x5ea44f, /* 1 REALTEK_90 */ + 0x5e4322, /* 2 REALTEK_92SE */ + 0x5ea42b, /* 3 BROAD */ + 0xa44f, /* 4 RAL */ + 0xa630, /* 5 ATH */ + 0x5ea630, /* 6 CISCO */ + 0x5ea42b, /* 7 MARVELL */ +}; + +static const u32 edca_setting_ul[PEER_MAX] = { + 0x5e4322, /* 0 UNKNOWN */ + 0xa44f, /* 1 REALTEK_90 */ + 0x5ea44f, /* 2 REALTEK_92SE */ + 0x5ea32b, /* 3 BROAD */ + 0x5ea422, /* 4 RAL */ + 0x5ea322, /* 5 ATH */ + 0x3ea430, /* 6 CISCO */ + 0x5ea44f, /* 7 MARV */ +}; + +void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type, + u8 *pdirection, u32 *poutwrite_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 pwr_val = 0; + u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]; + u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A]; + u8 cck_base = rtldm->swing_idx_cck_base; + u8 cck_val = rtldm->swing_idx_cck; + + if (type == 0) { + if (ofdm_val <= ofdm_base) { + *pdirection = 1; + pwr_val = ofdm_base - ofdm_val; + } else { + *pdirection = 2; + pwr_val = ofdm_val - ofdm_base; + } + } else if (type == 1) { + if (cck_val <= cck_base) { + *pdirection = 1; + pwr_val = cck_base - cck_val; + } else { + *pdirection = 2; + pwr_val = cck_val - cck_base; + } + } + + if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) + pwr_val = TXPWRTRACK_MAX_IDX; + + *poutwrite_val = pwr_val | (pwr_val << 8) | + (pwr_val << 16) | (pwr_val << 24); +} + +void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + + p_ra->high_rssi_thresh_for_ra = 50; + p_ra->low_rssi_thresh_for_ra40m = 20; +} + +static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_track_control = true; + rtlpriv->dm.thermalvalue = 0; + + rtlpriv->dm.ofdm_index[0] = 30; + rtlpriv->dm.cck_index = 20; + + rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index; + + rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0]; + rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0; + rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0; + rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "rtlpriv->dm.txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); +} + +static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; + + rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800); + rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; +} + +void rtl8723be_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl_dm_diginit(hw, cur_igvalue); + rtl8723be_dm_init_rate_adaptive_mask(hw); + rtl8723_dm_init_edca_turbo(hw); + rtl8723_dm_init_dynamic_bb_powersaving(hw); + rtl8723_dm_init_dynamic_txpower(hw); + rtl8723be_dm_init_txpower_tracking(hw); + rtl8723be_dm_init_dynamic_atc_switch(hw); +} + +static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + + /* Determine the minimum RSSI */ + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dm_dig->min_undec_pwdb_for_dm = 0; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "Not connected to any\n"); + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.entry_min_undec_sm_pwdb); + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "STA Default Port PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Ext Port or disconnect PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + rtl_dm_dig->min_undec_pwdb_for_dm); +} + +static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_sta_info *drv_priv; + u8 h2c_parameter[3] = { 0 }; + long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; + + /* AP & ADHOC & MESH */ + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { + if (drv_priv->rssi_stat.undec_sm_pwdb < + tmp_entry_min_pwdb) + tmp_entry_min_pwdb = + drv_priv->rssi_stat.undec_sm_pwdb; + if (drv_priv->rssi_stat.undec_sm_pwdb > + tmp_entry_max_pwdb) + tmp_entry_max_pwdb = + drv_priv->rssi_stat.undec_sm_pwdb; + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + /* If associated entry is found */ + if (tmp_entry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undec_sm_pwdb = + tmp_entry_max_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMaxPWDB = 0x%lx(%ld)\n", + tmp_entry_max_pwdb, tmp_entry_max_pwdb); + } else { + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + } + /* If associated entry is found */ + if (tmp_entry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undec_sm_pwdb = + tmp_entry_min_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMinPWDB = 0x%lx(%ld)\n", + tmp_entry_min_pwdb, tmp_entry_min_pwdb); + } else { + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + } + /* Indicate Rx signal strength to FW. */ + if (rtlpriv->dm.useramask) { + h2c_parameter[2] = + (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF); + h2c_parameter[1] = 0x20; + h2c_parameter[0] = 0; + rtl8723be_fill_h2c_cmd(hw, H2C_RSSIBE_REPORT, 3, h2c_parameter); + } else { + rtl_write_byte(rtlpriv, 0x4fe, + rtlpriv->dm.undec_sm_pwdb); + } + rtl8723be_dm_find_minimum_rssi(hw); + dm_digtable->rssi_val_min = + rtlpriv->dm_digtable.min_undec_pwdb_for_dm; +} + +void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (dm_digtable->stop_dig) + return; + + if (dm_digtable->cur_igvalue != current_igi) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi); + if (rtlpriv->phy.rf_type != RF_1T1R) + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, + 0x7f, current_igi); + } + dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = current_igi; +} + +static void rtl8723be_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 dig_min_0, dig_maxofmin; + bool bfirstconnect, bfirstdisconnect; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dm_digtable->cur_igvalue; + u8 offset; + + /* AP,BT */ + if (mac->act_scanning) + return; + + dig_min_0 = dm_digtable->dig_min_0; + bfirstconnect = (mac->link_state >= MAC80211_LINKED) && + !dm_digtable->media_connect_0; + bfirstdisconnect = (mac->link_state < MAC80211_LINKED) && + (dm_digtable->media_connect_0); + + dm_dig_max = 0x5a; + dm_dig_min = DM_DIG_MIN; + dig_maxofmin = DM_DIG_MAX_AP; + + if (mac->link_state >= MAC80211_LINKED) { + if ((dm_digtable->rssi_val_min + 10) > dm_dig_max) + dm_digtable->rx_gain_max = dm_dig_max; + else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min) + dm_digtable->rx_gain_max = dm_dig_min; + else + dm_digtable->rx_gain_max = + dm_digtable->rssi_val_min + 10; + + if (rtlpriv->dm.one_entry_only) { + offset = 12; + if (dm_digtable->rssi_val_min - offset < dm_dig_min) + dig_min_0 = dm_dig_min; + else if (dm_digtable->rssi_val_min - offset > + dig_maxofmin) + dig_min_0 = dig_maxofmin; + else + dig_min_0 = + dm_digtable->rssi_val_min - offset; + } else { + dig_min_0 = dm_dig_min; + } + + } else { + dm_digtable->rx_gain_max = dm_dig_max; + dig_min_0 = dm_dig_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); + } + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { + if (dm_digtable->large_fa_hit != 3) + dm_digtable->large_fa_hit++; + if (dm_digtable->forbidden_igi < current_igi) { + dm_digtable->forbidden_igi = current_igi; + dm_digtable->large_fa_hit = 1; + } + + if (dm_digtable->large_fa_hit >= 3) { + if ((dm_digtable->forbidden_igi + 1) > + dm_digtable->rx_gain_max) + dm_digtable->rx_gain_min = + dm_digtable->rx_gain_max; + else + dm_digtable->rx_gain_min = + dm_digtable->forbidden_igi + 1; + dm_digtable->recover_cnt = 3600; + } + } else { + if (dm_digtable->recover_cnt != 0) { + dm_digtable->recover_cnt--; + } else { + if (dm_digtable->large_fa_hit < 3) { + if ((dm_digtable->forbidden_igi - 1) < + dig_min_0) { + dm_digtable->forbidden_igi = + dig_min_0; + dm_digtable->rx_gain_min = + dig_min_0; + } else { + dm_digtable->forbidden_igi--; + dm_digtable->rx_gain_min = + dm_digtable->forbidden_igi + 1; + } + } else { + dm_digtable->large_fa_hit = 0; + } + } + } + if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) + dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; + + if (mac->link_state >= MAC80211_LINKED) { + if (bfirstconnect) { + current_igi = min(dm_digtable->rssi_val_min, dig_maxofmin); + + dm_digtable->large_fa_hit = 0; + } else { + if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) + current_igi += 4; + else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + current_igi -= 2; + } + } else { + if (bfirstdisconnect) { + current_igi = dm_digtable->rx_gain_min; + } else { + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + current_igi += 4; + else if (rtlpriv->falsealm_cnt.cnt_all > 8000) + current_igi += 2; + else if (rtlpriv->falsealm_cnt.cnt_all < 500) + current_igi -= 2; + } + } + + if (current_igi > dm_digtable->rx_gain_max) + current_igi = dm_digtable->rx_gain_max; + else if (current_igi < dm_digtable->rx_gain_min) + current_igi = dm_digtable->rx_gain_min; + + rtl8723be_dm_write_dig(hw, current_igi); + dm_digtable->media_connect_0 = + ((mac->link_state >= MAC80211_LINKED) ? true : false); + dm_digtable->dig_min_0 = dig_min_0; +} + +static void rtl8723be_dm_false_alarm_counter_statistics( + struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + + rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff; + falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD); + falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff; + falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff; + falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16; + + ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff; + + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1); + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD); + falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | + ((ret_value & 0xff00) >> 8); + + falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail + + falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail; + + falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca + + falsealm_cnt->cnt_cck_cca; + + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); + + rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); + rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); + + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); + + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); + rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, + falsealm_cnt->cnt_mcs_fail); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, + falsealm_cnt->cnt_all); +} + +static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/ + return; +} + +static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index, + u8 rfpath, long iqk_result_x, + long iqk_result_y) +{ + long ele_a = 0, ele_d, ele_c = 0, value32; + + if (ofdm_index >= 43) + ofdm_index = 43 - 1; + + ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22; + + if (iqk_result_x != 0) { + if ((iqk_result_x & 0x00000200) != 0) + iqk_result_x = iqk_result_x | 0xFFFFFC00; + ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF; + + if ((iqk_result_y & 0x00000200) != 0) + iqk_result_y = iqk_result_y | 0xFFFFFC00; + ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF; + + switch (rfpath) { + case RF90_PATH_A: + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32); + value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + value32); + break; + default: + break; + } + } else { + switch (rfpath) { + case RF90_PATH_A: + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, + ofdmswing_table[ofdm_index]); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00); + break; + default: + break; + } + } +} + +static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rfpath, u8 idx) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 swing_idx_ofdm_limit = 36; + + if (method == TXAGC) { + rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); + } else if (method == BBSWING) { + if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE) + rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1; + + if (!rtldm->cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[rtldm->swing_idx_cck][0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[rtldm->swing_idx_cck][1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[rtldm->swing_idx_cck][2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[rtldm->swing_idx_cck][3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[rtldm->swing_idx_cck][4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[rtldm->swing_idx_cck][5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[rtldm->swing_idx_cck][6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[rtldm->swing_idx_cck][7]); + } + + if (rfpath == RF90_PATH_A) { + if (rtldm->swing_idx_ofdm[RF90_PATH_A] < + swing_idx_ofdm_limit) + swing_idx_ofdm_limit = + rtldm->swing_idx_ofdm[RF90_PATH_A]; + + rtl8723be_set_iqk_matrix(hw, + rtldm->swing_idx_ofdm[rfpath], rfpath, + rtlphy->iqk_matrix[idx].value[0][0], + rtlphy->iqk_matrix[idx].value[0][1]); + } else if (rfpath == RF90_PATH_B) { + if (rtldm->swing_idx_ofdm[RF90_PATH_B] < + swing_idx_ofdm_limit) + swing_idx_ofdm_limit = + rtldm->swing_idx_ofdm[RF90_PATH_B]; + + rtl8723be_set_iqk_matrix(hw, + rtldm->swing_idx_ofdm[rfpath], rfpath, + rtlphy->iqk_matrix[idx].value[0][4], + rtlphy->iqk_matrix[idx].value[0][5]); + } + } else { + return; + } +} + +static void rtl8723be_dm_txpower_tracking_callback_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 thermalvalue = 0, delta, delta_lck, delta_iqk; + u8 thermalvalue_avg_count = 0; + u32 thermalvalue_avg = 0; + int i = 0; + + u8 ofdm_min_index = 6; + u8 index_for_channel = 0; + + static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = { + 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5, + 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 14, 15}; + static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = { + 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 12, 13, 14, 15}; + + /*Initilization ( 7 steps in total )*/ + rtlpriv->dm.txpower_trackinginit = true; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "%s\n", __func__); + + thermalvalue = (u8)rtl_get_rfreg(hw, + RF90_PATH_A, RF_T_METER, 0xfc00); + if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 || + rtlefuse->eeprom_thermalmeter == 0xFF) + return; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtldm->thermalvalue, + rtlefuse->eeprom_thermalmeter); + /*3 Initialize ThermalValues of RFCalibrateInfo*/ + if (!rtldm->thermalvalue) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + } + + /*4 Calculate average thermal meter*/ + rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue; + rtldm->thermalvalue_avg_index++; + if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE) + rtldm->thermalvalue_avg_index = 0; + + for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) { + if (rtldm->thermalvalue_avg[i]) { + thermalvalue_avg += rtldm->thermalvalue_avg[i]; + thermalvalue_avg_count++; + } + } + + if (thermalvalue_avg_count) + thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count); + + /* 5 Calculate delta, delta_LCK, delta_IQK.*/ + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk); + /* 6 If necessary, do LCK.*/ + if (delta_lck >= IQK_THRESHOLD) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl8723be_phy_lc_calibrate(hw); + } + + /* 7 If necessary, move the index of + * swing table to adjust Tx power. + */ + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + + if (delta >= TXSCALE_TABLE_SIZE) + delta = TXSCALE_TABLE_SIZE - 1; + /* 7.1 Get the final CCK_index and + * OFDM_index for each swing table. + */ + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + delta_swing_table_idx_tup_a[delta]; + } else { + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + -1 * delta_swing_table_idx_tdown_a[delta]; + } + + /* 7.2 Handle boundary conditions of index.*/ + if (rtldm->delta_power_index[RF90_PATH_A] == + rtldm->delta_power_index_last[RF90_PATH_A]) + rtldm->power_index_offset[RF90_PATH_A] = 0; + else + rtldm->power_index_offset[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A] - + rtldm->delta_power_index_last[RF90_PATH_A]; + + rtldm->ofdm_index[0] = + rtldm->swing_idx_ofdm_base[RF90_PATH_A] + + rtldm->power_index_offset[RF90_PATH_A]; + rtldm->cck_index = rtldm->swing_idx_cck_base + + rtldm->power_index_offset[RF90_PATH_A]; + + rtldm->swing_idx_cck = rtldm->cck_index; + rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0]; + + if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1) + rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1; + else if (rtldm->ofdm_index[0] < ofdm_min_index) + rtldm->ofdm_index[0] = ofdm_min_index; + + if (rtldm->cck_index > CCK_TABLE_SIZE - 1) + rtldm->cck_index = CCK_TABLE_SIZE - 1; + else if (rtldm->cck_index < 0) + rtldm->cck_index = 0; + } else { + rtldm->power_index_offset[RF90_PATH_A] = 0; + } + + if ((rtldm->power_index_offset[RF90_PATH_A] != 0) && + (rtldm->txpower_track_control)) { + rtldm->done_txpower = true; + rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0, + index_for_channel); + + rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; + rtldm->swing_idx_ofdm_base[RF90_PATH_A] = + rtldm->swing_idx_ofdm[0]; + rtldm->thermalvalue = thermalvalue; + } + + if (delta_iqk >= IQK_THRESHOLD) { + rtldm->thermalvalue_iqk = thermalvalue; + rtl8723be_phy_iq_calibrate(hw, false); + } + + rtldm->txpowercount = 0; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n"); + +} + +void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), + 0x03); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 8723be Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + return; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking !!\n"); + rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw); + rtlpriv->dm.tm_trigger = 0; + } +} + +static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &rtlpriv->ra; + u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m; + u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; + u8 go_up_gap = 5; + struct ieee80211_sta *sta = NULL; + + if (is_hal_stop(rtlhal)) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver is going to unload\n"); + return; + } + + if (!rtlpriv->dm.useramask) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver does not control rate adaptive mask\n"); + return; + } + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra += go_up_gap; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra += go_up_gap; + low_rssithresh_for_ra += go_up_gap; + break; + default: + break; + } + + if (rtlpriv->dm.undec_sm_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undec_sm_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld\n", + rtlpriv->dm.undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI_LEVEL = %d\n", p_ra->ratr_state); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); + + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, sta, + p_ra->ratr_state, + true); + rcu_read_unlock(); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) + return true; + + return false; +} + +static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x6ea42b; + u32 edca_be_dl = 0x6ea42b;/*not sure*/ + u32 edca_be = 0x5ea42b; + u32 iot_peer = 0; + bool b_is_cur_rdlstate; + bool b_bias_on_rx = false; + bool b_edca_turbo_on = false; + + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + + iot_peer = rtlpriv->mac80211.vendor; + b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ? + true : false; + b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) ? + true : false; + + if ((iot_peer == PEER_CISCO) && + (mac->mode == WIRELESS_MODE_N_24G)) { + edca_be_dl = edca_setting_dl[iot_peer]; + edca_be_ul = edca_setting_ul[iot_peer]; + } + if (rtl8723be_dm_is_edca_turbo_disable(hw)) + goto exit; + + if (b_edca_turbo_on) { + if (b_bias_on_rx) + b_is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ? + false : true; + else + b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ? + true : false; + + edca_be = (b_is_cur_rdlstate) ? edca_be_dl : edca_be_ul; + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be); + rtlpriv->dm.is_cur_rdlstate = b_is_cur_rdlstate; + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + } + rtlpriv->dm.current_turbo_edca = false; + } + +exit: + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + u8 cur_cck_cca_thresh; + + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + if (dm_digtable->rssi_val_min > 25) { + cur_cck_cca_thresh = 0xcd; + } else if ((dm_digtable->rssi_val_min <= 25) && + (dm_digtable->rssi_val_min > 10)) { + cur_cck_cca_thresh = 0x83; + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh); + + dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; + dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh; + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres); +} + +static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 reg_c50, reg_c58; + bool fw_current_in_ps_mode = false; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_in_ps_mode)); + if (fw_current_in_ps_mode) + return; + + reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + + if (reg_c50 > 0x28 && reg_c58 > 0x28) { + if (!rtlpriv->rtlhal.pre_edcca_enable) { + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03); + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00); + } + } else if (reg_c50 < 0x25 && reg_c58 < 0x25) { + if (rtlpriv->rtlhal.pre_edcca_enable) { + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f); + rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f); + } + } +} + +static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 crystal_cap; + u32 packet_count; + int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; + int cfo_ave_diff; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { + if (rtldm->atc_status == ATC_STATUS_OFF) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_ON); + rtldm->atc_status = ATC_STATUS_ON; + } + if (rtlpriv->cfg->ops->get_btc_status()) { + if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) { + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, + "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n"); + return; + } + } + + if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { + rtldm->crystal_cap = rtlpriv->efuse.crystalcap; + crystal_cap = rtldm->crystal_cap & 0x3f; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + } + } else { + cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; + cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; + packet_count = rtldm->packet_count; + + if (packet_count == rtldm->packet_count_pre) + return; + + rtldm->packet_count_pre = packet_count; + + if (rtlpriv->phy.rf_type == RF_1T1R) + cfo_ave = cfo_khz_a; + else + cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1; + + cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? + (rtldm->cfo_ave_pre - cfo_ave) : + (cfo_ave - rtldm->cfo_ave_pre); + + if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { + rtldm->large_cfo_hit = true; + return; + } else + rtldm->large_cfo_hit = false; + + rtldm->cfo_ave_pre = cfo_ave; + + if (cfo_ave >= -rtldm->cfo_threshold && + cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) { + if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; + rtldm->is_freeze = 1; + } else { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; + } + } + + if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) + adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1; + else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && + rtlpriv->dm.crystal_cap > 0) + adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1; + + if (adjust_xtal != 0) { + rtldm->is_freeze = 0; + rtldm->crystal_cap += adjust_xtal; + + if (rtldm->crystal_cap > 0x3f) + rtldm->crystal_cap = 0x3f; + else if (rtldm->crystal_cap < 0) + rtldm->crystal_cap = 0; + + crystal_cap = rtldm->crystal_cap & 0x3f; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + } + + if (cfo_ave < CFO_THRESHOLD_ATC && + cfo_ave > -CFO_THRESHOLD_ATC) { + if (rtldm->atc_status == ATC_STATUS_ON) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_OFF); + rtldm->atc_status = ATC_STATUS_OFF; + } + } else { + if (rtldm->atc_status == ATC_STATUS_OFF) { + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), + ATC_STATUS_ON); + rtldm->atc_status = ATC_STATUS_ON; + } + } + } +} + +static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 cnt; + + rtlpriv->dm.one_entry_only = false; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && + rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + rtlpriv->dm.one_entry_only = true; + return; + } + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + cnt = list_count_nodes(&rtlpriv->entry_list); + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + if (cnt == 1) + rtlpriv->dm.one_entry_only = true; + } +} + +void rtl8723be_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) { + rtl8723be_dm_common_info_self_update(hw); + rtl8723be_dm_false_alarm_counter_statistics(hw); + rtl8723be_dm_check_rssi_monitor(hw); + rtl8723be_dm_dig(hw); + rtl8723be_dm_dynamic_edcca(hw); + rtl8723be_dm_cck_packet_detection_thresh(hw); + rtl8723be_dm_refresh_rate_adaptive_mask(hw); + rtl8723be_dm_check_edca_turbo(hw); + rtl8723be_dm_dynamic_atc_switch(hw); + rtl8723be_dm_check_txpower_tracking(hw); + rtl8723be_dm_dynamic_txpower(hw); + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h new file mode 100644 index 000000000..c4f36e951 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h @@ -0,0 +1,248 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_DM_H__ +#define __RTL8723BE_DM_H__ + +#define MAIN_ANT 0 +#define AUX_ANT 1 +#define MAIN_ANT_CG_TRX 1 +#define AUX_ANT_CG_TRX 0 +#define MAIN_ANT_CGCS_RX 0 +#define AUX_ANT_CGCS_RX 1 + +#define TXSCALE_TABLE_SIZE 30 + +/*RF REG LIST*/ +#define DM_REG_RF_MODE_11N 0x00 +#define DM_REG_RF_0B_11N 0x0B +#define DM_REG_CHNBW_11N 0x18 +#define DM_REG_T_METER_11N 0x24 +#define DM_REG_RF_25_11N 0x25 +#define DM_REG_RF_26_11N 0x26 +#define DM_REG_RF_27_11N 0x27 +#define DM_REG_RF_2B_11N 0x2B +#define DM_REG_RF_2C_11N 0x2C +#define DM_REG_RXRF_A3_11N 0x3C +#define DM_REG_T_METER_92D_11N 0x42 +#define DM_REG_T_METER_88E_11N 0x42 + +/*BB REG LIST*/ +/*PAGE 8 */ +#define DM_REG_BB_CTRL_11N 0x800 +#define DM_REG_RF_PIN_11N 0x804 +#define DM_REG_PSD_CTRL_11N 0x808 +#define DM_REG_TX_ANT_CTRL_11N 0x80C +#define DM_REG_BB_PWR_SAV5_11N 0x818 +#define DM_REG_CCK_RPT_FORMAT_11N 0x824 +#define DM_REG_RX_DEFUALT_A_11N 0x858 +#define DM_REG_RX_DEFUALT_B_11N 0x85A +#define DM_REG_BB_PWR_SAV3_11N 0x85C +#define DM_REG_ANTSEL_CTRL_11N 0x860 +#define DM_REG_RX_ANT_CTRL_11N 0x864 +#define DM_REG_PIN_CTRL_11N 0x870 +#define DM_REG_BB_PWR_SAV1_11N 0x874 +#define DM_REG_ANTSEL_PATH_11N 0x878 +#define DM_REG_BB_3WIRE_11N 0x88C +#define DM_REG_SC_CNT_11N 0x8C4 +#define DM_REG_PSD_DATA_11N 0x8B4 +/*PAGE 9*/ +#define DM_REG_ANT_MAPPING1_11N 0x914 +#define DM_REG_ANT_MAPPING2_11N 0x918 +/*PAGE A*/ +#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define DM_REG_CCK_CCA_11N 0xA0A +#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define DM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define DM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define DM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define DM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define DM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define DM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define DM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define DM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define DM_REG_CCK_FA_RST_11N 0xA2C +#define DM_REG_CCK_FA_MSB_11N 0xA58 +#define DM_REG_CCK_FA_LSB_11N 0xA5C +#define DM_REG_CCK_CCA_CNT_11N 0xA60 +#define DM_REG_BB_PWR_SAV4_11N 0xA74 +/*PAGE B */ +#define DM_REG_LNA_SWITCH_11N 0xB2C +#define DM_REG_PATH_SWITCH_11N 0xB30 +#define DM_REG_RSSI_CTRL_11N 0xB38 +#define DM_REG_CONFIG_ANTA_11N 0xB68 +#define DM_REG_RSSI_BT_11N 0xB9C +/*PAGE C */ +#define DM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define DM_REG_RX_PATH_11N 0xC04 +#define DM_REG_TRMUX_11N 0xC08 +#define DM_REG_OFDM_FA_RSTC_11N 0xC0C +#define DM_REG_RXIQI_MATRIX_11N 0xC14 +#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define DM_REG_IGI_A_11N 0xC50 +#define DM_REG_ANTDIV_PARA2_11N 0xC54 +#define DM_REG_IGI_B_11N 0xC58 +#define DM_REG_ANTDIV_PARA3_11N 0xC5C +#define DM_REG_BB_PWR_SAV2_11N 0xC70 +#define DM_REG_RX_OFF_11N 0xC7C +#define DM_REG_TXIQK_MATRIXA_11N 0xC80 +#define DM_REG_TXIQK_MATRIXB_11N 0xC88 +#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define DM_REG_ANTDIV_PARA1_11N 0xCA4 +#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/*PAGE D */ +#define DM_REG_OFDM_FA_RSTD_11N 0xD00 +#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8 +/*PAGE E */ +#define DM_REG_TXAGC_A_6_18_11N 0xE00 +#define DM_REG_TXAGC_A_24_54_11N 0xE04 +#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define DM_REG_FPGA0_IQK_11N 0xE28 +#define DM_REG_TXIQK_TONE_A_11N 0xE30 +#define DM_REG_RXIQK_TONE_A_11N 0xE34 +#define DM_REG_TXIQK_PI_A_11N 0xE38 +#define DM_REG_RXIQK_PI_A_11N 0xE3C +#define DM_REG_TXIQK_11N 0xE40 +#define DM_REG_RXIQK_11N 0xE44 +#define DM_REG_IQK_AGC_PTS_11N 0xE48 +#define DM_REG_IQK_AGC_RSP_11N 0xE4C +#define DM_REG_BLUETOOTH_11N 0xE6C +#define DM_REG_RX_WAIT_CCA_11N 0xE70 +#define DM_REG_TX_CCK_RFON_11N 0xE74 +#define DM_REG_TX_CCK_BBON_11N 0xE78 +#define DM_REG_OFDM_RFON_11N 0xE7C +#define DM_REG_OFDM_BBON_11N 0xE80 +#define DM_REG_TX2RX_11N 0xE84 +#define DM_REG_TX2TX_11N 0xE88 +#define DM_REG_RX_CCK_11N 0xE8C +#define DM_REG_RX_OFDM_11N 0xED0 +#define DM_REG_RX_WAIT_RIFS_11N 0xED4 +#define DM_REG_RX2RX_11N 0xED8 +#define DM_REG_STANDBY_11N 0xEDC +#define DM_REG_SLEEP_11N 0xEE0 +#define DM_REG_PMPD_ANAEN_11N 0xEEC + +/*MAC REG LIST*/ +#define DM_REG_BB_RST_11N 0x02 +#define DM_REG_ANTSEL_PIN_11N 0x4C +#define DM_REG_EARLY_MODE_11N 0x4D0 +#define DM_REG_RSSI_MONITOR_11N 0x4FE +#define DM_REG_EDCA_VO_11N 0x500 +#define DM_REG_EDCA_VI_11N 0x504 +#define DM_REG_EDCA_BE_11N 0x508 +#define DM_REG_EDCA_BK_11N 0x50C +#define DM_REG_TXPAUSE_11N 0x522 +#define DM_REG_RESP_TX_11N 0x6D8 +#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + +/*DIG Related*/ +#define DM_BIT_IGI_11N 0x0000007F + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 43 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x3e +#define DM_DIG_FA_LOWER 0x1e +#define DM_DIG_FA_TH0 0x200 +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TXPWRTRACK_MAX_IDX 6 + +/* Dynamic ATC switch */ +#define ATC_STATUS_OFF 0x0 /* enable */ +#define ATC_STATUS_ON 0x1 /* disable */ +#define CFO_THRESHOLD_XTAL 10 /* kHz */ +#define CFO_THRESHOLD_ATC 80 /* kHz */ + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum pwr_track_control_method { + BBSWING, + TXAGC +}; + +#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) +#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) +#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) +#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1) +#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1) +#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ + ((((struct rtl_priv *)(_priv))->mac80211.opmode == \ + NL80211_IFTYPE_ADHOC) ? \ + (((struct rtl_priv *)(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) :\ + (((struct rtl_priv *)(_priv))->dm.undecorated_smoothed_pwdb)) + +void rtl8723be_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, u8 *pdesc, + u32 mac_id); +void rtl8723be_dm_ant_sel_statistics(struct ieee80211_hw *hw, u8 antsel_tr_mux, + u32 mac_id, u32 rx_pwdb_all); +void rtl8723be_dm_fast_antenna_training_callback(unsigned long data); +void rtl8723be_dm_init(struct ieee80211_hw *hw); +void rtl8723be_dm_watchdog(struct ieee80211_hw *hw); +void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi); +void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type, + u8 *pdirection, u32 *poutwrite_val); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c new file mode 100644 index 000000000..b3e6c91e2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c @@ -0,0 +1,685 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" + +static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw, + u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + pr_err("Write H2C fail because no trigger for FW INT!\n"); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + pr_err("switch case %#x not processed\n", + boxnum); + break; + } + + isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, + boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, + p_cmdbuffer + buf_index, cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), + p_cmdbuffer + buf_index+3, cmd_len-3); + memcpy((u8 *)(boxcontent) + 1, + p_cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + pr_err("switch case %#x not processed\n", + cmd_len); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8723be: error H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); + _rtl8723be_fill_h2c_command(hw, element_id, cmd_len, + (u8 *)&tmp_cmdbuf); + return; +} + +void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0, byte5 = 0; + u8 awake_intvl; /* DTIM = (awake_intvl - 1) */ + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false); + bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_lps_on(rtlpriv) : false); + + if (bt_ctrl_lps) + mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n", + mode, bt_ctrl_lps); + + switch (mode) { + case FW_PS_MIN_MODE: + rlbm = 0; + awake_intvl = 2; + break; + case FW_PS_MAX_MODE: + rlbm = 1; + awake_intvl = 2; + break; + case FW_PS_DTIM_MODE: + rlbm = 2; + awake_intvl = ppsc->reg_max_lps_awakeintvl; + /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period + * is only used in swlps. + */ + break; + default: + rlbm = 2; + awake_intvl = 4; + break; + } + + if (rtlpriv->mac80211.p2p) { + awake_intvl = 2; + rlbm = 1; + } + + if (mode == FW_PS_ACTIVE_MODE) { + byte5 = 0x40; + power_state = FW_PWR_STATE_ACTIVE; + } else { + if (bt_ctrl_lps) { + byte5 = btc_ops->btc_get_lps_val(rtlpriv); + power_state = btc_ops->btc_get_rpwm_val(rtlpriv); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from + * decreasing coex performance + */ + awake_intvl = 2; + rlbm = 2; + } + } else { + byte5 = 0x40; + power_state = FW_PWR_STATE_RF_OFF; + } + } + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, + bt_ctrl_lps ? 0 : ppsc->smart_ps); + SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, + awake_intvl); + SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode, + H2C_PWEMODE_LENGTH); + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH, + u1_h2c_set_pwrmode); +} + +void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 parm[3] = { 0, 0, 0 }; + /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect + * bit1=0-->update Media Status to MACID + * bit1=1-->update Media Status from MACID to MACID_End + * parm[1]: MACID, if this is INFRA_STA, MacID = 0 + * parm[2]: MACID_End + */ + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm); +} + +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ +#define QOS_NULL_PG 6 +#define BT_QOS_NULL_PG 7 + +#define TOTAL_RESERVED_PKT_LEN 1024 /* can be up to 1280 (tx_bndy=245) */ + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, + 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, + 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, + 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, + 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, + 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, + 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, + 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, + 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, + + /* page 1 beacon */ + 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 6 qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 7 BT-qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +}; + +void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[5] = { 0 }; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + u8 *qosnull; + u8 *btqosnull; + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *-------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *--------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + + /*--------------------------------------------------------- + * (5) QoS Null + *--------------------------------------------------------- + */ + qosnull = &reserved_page_packet[QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG); + + /*--------------------------------------------------------- + * (5) QoS Null + *--------------------------------------------------------- + */ + btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1rsvdpageloc, sizeof(u1rsvdpageloc)); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n", + u1rsvdpageloc, sizeof(u1rsvdpageloc)); + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + } else + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +/*Should check FW support p2p or not.*/ +static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, + u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = { ctwindow}; + + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1, + u1_ctwindow_period); +} + +void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, + u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow); + } + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num ; i++) { + /* To control the register setting + * for which NOA + */ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low + (50 * 1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + + if ((p2pinfo->opp_ps == 1) || + (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1, + (u8 *)p2p_ps_offload); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h new file mode 100644 index 000000000..7c5e5e916 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE__FW__H__ +#define __RTL8723BE__FW__H__ + +#define FW_8192C_SIZE 0x8000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x5FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 + +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_PWEMODE_LENGTH 7 + +/* Fw PS state for RPWM. +*BIT[2:0] = HW state +*BIT[3] = Protocol PS state, 1: register active state , 0: register sleep state +*BIT[4] = sub-state +*/ +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + + /* 8723BE RPWM value*/ + /* BIT[0] = 1: 32k, 0: 40M*/ +#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/ +#define FW_PS_CLOCK_ON 0 /*40M*/ + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/ +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) + +/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/ +#define FW_PS_STATE_ALL_ON (FW_PS_CLOCK_ON) +/* (FW_PS_RF_ON)*/ +#define FW_PS_STATE_RF_ON (FW_PS_CLOCK_ON) +/* 0x0*/ +#define FW_PS_STATE_RF_OFF (FW_PS_CLOCK_ON) +/* (FW_PS_STATE_RF_OFF)*/ +#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF) + + +/* For 8723BE H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) + +#define IS_IN_LOW_POWER_STATE(__fwpsstate) \ + (FW_PS_STATE(__fwpsstate) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8723b_h2c_cmd { + H2C_8723B_RSVDPAGE = 0, + H2C_8723B_MSRRPT = 1, + H2C_8723B_SCAN = 2, + H2C_8723B_KEEP_ALIVE_CTRL = 3, + H2C_8723B_DISCONNECT_DECISION = 4, + H2C_8723B_BCN_RSVDPAGE = 9, + H2C_8723B_PROBERSP_RSVDPAGE = 10, + + H2C_8723B_SETPWRMODE = 0x20, + H2C_8723B_PS_LPS_PARA = 0x23, + H2C_8723B_P2P_PS_OFFLOAD = 0x24, + + H2C_8723B_RA_MASK = 0x40, + H2C_RSSIBE_REPORT = 0x42, + /*Not defined CTW CMD for P2P yet*/ + H2C_8723B_P2P_PS_CTW_CMD, + MAX_8723B_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \ + u8p_replace_bits(__ph2ccmd + 1, __val, GENMASK(3, 0)) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + u8p_replace_bits(__ph2ccmd + 1, __val, GENMASK(7, 4)) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 3) = __val +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 4) = __val +#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 5) = __val + +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__ph2ccmd, __val) \ + u8p_replace_bits(__ph2ccmd, __val, BIT(0)) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__ph2ccmd, __val) \ + u8p_replace_bits(__ph2ccmd, __val, BIT(1)) + +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 3) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 4) = __val + + +void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c new file mode 100644 index 000000000..bf7b5a32a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -0,0 +1,2718 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "led.h" +#include "hw.h" +#include "../pwrseqcmd.h" +#include "pwrseq.h" +#include "../btcoexist/rtl_btc.h" +#include + +#define LLT_CONFIG 5 + +static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; + unsigned long flags; + + skb_queue_head_init(&free_list); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + __skb_queue_tail(&free_list, skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); +} + +static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(1); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val, + bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_support_remote_wake_up; + u32 count = 0, isr_regaddr, content; + bool b_schedule_timer = b_need_turn_off_ckk; + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&b_support_remote_wake_up)); + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + return; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + break; + } + } + + if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (b_schedule_timer) + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool b_schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + b_schedule_timer = true; + break; + } + } + + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } + +} + +static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK); + _rtl8723be_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */ + _rtl8723be_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } + +} + +static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl8723be_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } + +} + +void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + } + break; + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *)(val)) = tsf; + } + break; + case HAL_DEF_WOWLAN: + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_regcr, tmp_reg422, bcnvalid_reg; + u8 count = 0, dlbcn_count = 0; + bool b_recover = false; + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + + _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); + if (tmp_reg422 & BIT(6)) + b_recover = true; + + do { + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2); + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, + (bcnvalid_reg | BIT(0))); + _rtl8723be_return_beacon_queue_skb(hw); + + rtl8723be_set_fw_rsvdpagepkt(hw, 0); + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2); + count = 0; + while (!(bcnvalid_reg & BIT(0)) && count < 20) { + count++; + udelay(10); + bcnvalid_reg = rtl_read_byte(rtlpriv, + REG_TDECTRL + 2); + } + dlbcn_count++; + } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + + if (bcnvalid_reg & BIT(0)) + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0)); + + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422); + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0)))); +} + +void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR: + for (idx = 0; idx < ETH_ALEN; idx++) + rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]); + break; + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *)val)[0]; + u8 rate_index = 0; + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff); + while (b_rate_cfg > 0x1) { + b_rate_cfg = (b_rate_cfg >> 1); + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index); + } + break; + case HW_VAR_BSSID: + for (idx = 0; idx < ETH_ALEN; idx++) + rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]); + + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + } + break; + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2); + if (short_preamble) { + reg_tmp |= 0x02; + rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp); + } else { + reg_tmp &= 0xFD; + rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp); + } + } + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); + break; + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + + min_spacing_to_set = *((u8 *)val); + if (min_spacing_to_set <= 7) { + mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + } + break; + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *)val); + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + + factor_toset = *((u8 *)val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) | + (factor_toset << 4); + + if ((p_regtoset[index] & 0x0f) > factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) | + (factor_toset); + + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + + } + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); + } + } + break; + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *)val); + rtl8723_dm_init_edca_turbo(hw); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + } + break; + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *)val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + } + break; + case HW_VAR_RCR: + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + break; + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + } + break; + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *)val) | BIT(7))); + } + } + break; + case HW_VAR_H2C_FW_PWRMODE: + rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_RESUME_CLK_ON: + _rtl8723be_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION:{ + bool b_enter_fwlps = *((bool *)val); + + if (b_enter_fwlps) + _rtl8723be_fwlps_enter(hw); + else + _rtl8723be_fwlps_leave(hw); + } + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *)val); + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + _rtl8723be_download_rsvd_page(hw); + } + rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus); + } + break; + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_AID:{ + u16 u2btmp; + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, + (u2btmp | mac->assoc_id)); + } + break; + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl8723be_stop_tx_beacon(hw); + + _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32) & 0xffffffff)); + + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl8723be_resume_tx_beacon(hw); + } + break; + case HW_VAR_KEEP_ALIVE:{ + u8 array[2]; + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | + _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxpage; + bool status; + + maxpage = 255; + txpktbuf_bndy = 245; + + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, + (0x27FF0000 | txpktbuf_bndy)); + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_PBP, 0x31); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl8723be_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + + if (!status) + return status; + + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = _rtl8723be_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808); + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00); + + return true; +} + +static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl8723be_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl8723be_sw_led_on(hw, pin0); + else + rtl8723be_sw_led_off(hw, pin0); +} + +static bool _rtl8723be_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + unsigned char bytetmp; + unsigned short wordtmp; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + + /*Auto Power Down to CHIP-off State*/ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7)); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + + /* HW Power on sequence */ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, + PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, + RTL8723_NIC_ENABLE_FLOW)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "init MAC Fail as power on failure\n"); + return false; + } + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv); + + bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL); + rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3)); + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4); + rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp); + + bytetmp = rtl_read_byte(rtlpriv, REG_CR); + bytetmp = 0xff; + rtl_write_byte(rtlpriv, REG_CR, bytetmp); + mdelay(2); + + bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL); + bytetmp |= 0x7f; + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp); + mdelay(2); + + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3); + if (bytetmp & BIT(0)) { + bytetmp = rtl_read_byte(rtlpriv, 0x7c); + rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6)); + } + + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); + rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3)); + bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1); + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4))); + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (!rtlhal->mac_func_enable) { + if (!_rtl8723be_llt_table_init(hw)) + return false; + } + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); + + /* Enable FW Beamformer Interrupt */ + bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3); + rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6)); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF5B1; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3); + + /* <20130114, Kordan> The following setting is + * only for DPDT and Fixed board type. + * TODO: A better solution is configure it + * according EFUSE during the run-time. + */ + rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */ + rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */ + rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */; + rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */; + rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */; + rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */; + rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */; + rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */; + + bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2))); + + _rtl8723be_gen_refresh_led_state(hw); + return true; +} + +static void _rtl8723be_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rrsr; + + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + /* Init value for RRSR. */ + rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); + + /* ARFB table 9 for 11ac 5G 2SS */ + rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000); + + /* ARFB table 10 for 11ac 5G 1SS */ + rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000); + + /* CF-End setting. */ + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00); + + /* 0x456 = 0x70, sugguested by Zhilin */ + rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70); + + /* Set retry limit */ + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + /* Set Data / Response auto rate fallack retry count */ + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + rtlpci->reg_bcn_ctrl_val = 0x1d; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + /* TBTT prohibit hold time. Suggested by designer TimChen. */ + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */ + + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + + /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/ + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); + + rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80); + + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20); + + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F); +} + +static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr) +{ + u16 read_addr = addr & 0xfffc; + u8 ret = 0, tmp = 0, count = 0; + + rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count++; + } + if (0 == tmp) { + read_addr = REG_DBI_RDATA + addr % 4; + ret = rtl_read_byte(rtlpriv, read_addr); + } + + return ret; +} + +static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data) +{ + u8 tmp = 0, count = 0; + u16 write_addr = 0, remainder = addr % 4; + + /* Write DBI 1Byte Data */ + write_addr = REG_DBI_WDATA + remainder; + rtl_write_byte(rtlpriv, write_addr, data); + + /* Write DBI 2Byte Address & Write Enable */ + write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12)); + rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr); + + /* Write DBI Write Flag */ + rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1); + + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count++; + } +} + +static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr) +{ + u16 ret = 0; + u8 tmp = 0, count = 0; + + rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6)); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6); + count++; + } + + if (0 == tmp) + ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA); + + return ret; +} + +static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data) +{ + u8 tmp = 0, count = 0; + + rtl_write_word(rtlpriv, REG_MDIO_WDATA, data); + rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5)); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5); + count++; + } +} + +static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp8 = 0; + u16 tmp16 = 0; + + /* Overwrite following ePHY parameter for + * some platform compatibility issue, + * especially when CLKReq is enabled, 2012.11.09. + */ + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01); + if (tmp16 != 0x0663) + _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04); + if (tmp16 != 0x7544) + _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06); + if (tmp16 != 0xB880) + _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07); + if (tmp16 != 0x4000) + _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08); + if (tmp16 != 0x9003) + _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09); + if (tmp16 != 0x0D03) + _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A); + if (tmp16 != 0x4037) + _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037); + + tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B); + if (tmp16 != 0x0070) + _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070); + + /* Configuration Space offset 0x70f BIT7 is used to control L0S */ + tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f); + _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) | + ASPM_L1_LATENCY << 3); + + /* Configuration Space offset 0x719 Bit3 is for L1 + * BIT4 is for clock request + */ + tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719); + _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4)); +} + +void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + rtlhal->mac_func_enable = false; + /* Combo (PCIe + USB) Card and PCIe-MF Card */ + /* 1. Run LPS WL RFOFF flow */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW); + + /* 2. 0x1F[7:0] = 0 */ + /* turn off RF */ + /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */ + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && + rtlhal->fw_ready) { + rtl8723be_firmware_selfreset(hw); + } + + /* Reset MCU. Suggested by Filen. */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + + /* g. MCUFWDL 0x80[1:0]=0 */ + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* HW card disable configuration. */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW); + + /* Reset MCU IO Wrapper */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0)); + + /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ + /* lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); +} + +static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv) +{ + u8 tmp; + + /* write reg 0x350 Bit[26]=1. Enable debug port. */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3); + if (!(tmp & BIT(2))) { + rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2))); + mdelay(100); /* Suggested by DD Justin_tsai. */ + } + + /* read reg 0x350 Bit[25] if 1 : RX hang + * read reg 0x350 Bit[24] if 1 : TX hang + */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3); + if ((tmp & BIT(0)) || (tmp & BIT(1))) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "CheckPcieDMAHang8723BE(): true!!\n"); + return true; + } + return false; +} + +static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv, + bool mac_power_on) +{ + u8 tmp; + bool release_mac_rx_pause; + u8 backup_pcie_dma_pause; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "ResetPcieInterfaceDMA8723BE()\n"); + + /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03" + * released by SD1 Alan. + * 2013.05.07, by tynli. + */ + + /* 1. disable register write lock + * write 0x1C bit[1:0] = 2'h0 + * write 0xCC bit[2] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL); + tmp &= ~(BIT(1) | BIT(0)); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp); + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp |= BIT(2); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); + + /* 2. Check and pause TRX DMA + * write 0x284 bit[18] = 1'b1 + * write 0x301 = 0xFF + */ + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + if (tmp & BIT(2)) { + /* Already pause before the function for another purpose. */ + release_mac_rx_pause = false; + } else { + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2))); + release_mac_rx_pause = true; + } + + backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1); + if (backup_pcie_dma_pause != 0xFF) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF); + + if (mac_power_on) { + /* 3. reset TRX function + * write 0x100 = 0x00 + */ + rtl_write_byte(rtlpriv, REG_CR, 0); + } + + /* 4. Reset PCIe DMA + * write 0x003 bit[0] = 0 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + /* 5. Enable PCIe DMA + * write 0x003 bit[0] = 1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + if (mac_power_on) { + /* 6. enable TRX function + * write 0x100 = 0xFF + */ + rtl_write_byte(rtlpriv, REG_CR, 0xFF); + + /* We should init LLT & RQPN and + * prepare Tx/Rx descrptor address later + * because MAC function is reset. + */ + } + + /* 7. Restore PCIe autoload down bit + * write 0xF8 bit[17] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2); + tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp); + + /* In MAC power on state, BB and RF maybe in ON state, + * if we release TRx DMA here + * it will cause packets to be started to Tx/Rx, + * so we release Tx/Rx DMA later. + */ + if (!mac_power_on) { + /* 8. release TRX DMA + * write 0x284 bit[18] = 1'b0 + * write 0x301 = 0x00 + */ + if (release_mac_rx_pause) { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, + (tmp & (~BIT(2)))); + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, + backup_pcie_dma_pause); + } + + /* 9. lock system register + * write 0xCC bit[2] = 1'b0 + */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp &= ~(BIT(2)); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); +} + +int rtl8723be_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + bool rtstatus = true; + int err; + u8 tmp_u1b; + + rtlhal->fw_ready = false; + rtlpriv->rtlhal.being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + + tmp_u1b = rtl_read_byte(rtlpriv, REG_CR); + if (tmp_u1b != 0 && tmp_u1b != 0xea) { + rtlhal->mac_func_enable = true; + } else { + rtlhal->mac_func_enable = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON; + } + + if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) { + _rtl8723be_reset_pcie_interface_dma(rtlpriv, + rtlhal->mac_func_enable); + rtlhal->mac_func_enable = false; + } + if (rtlhal->mac_func_enable) { + _rtl8723be_poweroff_adapter(hw); + rtlhal->mac_func_enable = false; + } + rtstatus = _rtl8723be_init_mac(hw); + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + goto exit; + } + + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG); + rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F); + + err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; + goto exit; + } + rtlhal->fw_ready = true; + + rtlhal->last_hmeboxnum = 0; + rtl8723be_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 + */ + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + + rtl8723be_phy_bb_config(hw); + rtl8723be_phy_rf_config(hw); + + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[0] &= 0xFFF03FF; + rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11)); + + _rtl8723be_hw_configure(hw); + rtlhal->mac_func_enable = true; + rtl_cam_reset_all_entry(hw); + rtl8723be_enable_hw_security_config(hw); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl8723be_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + rtl8723be_bt_hw_init(hw); + + if (ppsc->rfpwr_state == ERFON) { + rtl8723be_phy_set_rfpath_switch(hw, 1); + /* when use 1ant NIC, iqk will disturb BT music + * root cause is not clear now, is something + * related with 'mdelay' and Reg[0x948] + */ + if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 || + !rtlpriv->cfg->ops->get_btc_status()) { + rtl8723be_phy_iq_calibrate(hw, + (rtlphy->iqk_initialized ? + true : false)); + rtlphy->iqk_initialized = true; + } + rtl8723be_dm_check_txpower_tracking(hw); + rtl8723be_phy_lc_calibrate(hw); + } + rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128)); + + /* Release Rx DMA. */ + tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + if (tmp_u1b & BIT(2)) { + /* Release Rx DMA if needed */ + tmp_u1b &= (~BIT(2)); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b); + } + /* Release Tx/Rx PCIE DMA. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0); + + rtl8723be_dm_init(hw); +exit: + rtlpriv->rtlhal.being_init_adapter = false; + return err; +} + +static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum version_8723e version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1); + if ((value32 & (CHIP_8723B)) != CHIP_8723B) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n"); + else + version = (enum version_8723e)CHIP_8723B; + + rtlphy->rf_type = RF_1T1R; + + /* treat rtl8723be chip as MP version in default */ + version = (enum version_8723e)(version | NORMAL_CHIP); + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + /* cut version */ + version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK); + /* Manufacture */ + if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01) + version = (enum version_8723e)(version | CHIP_VENDOR_SMIC); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl8723be_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl8723be_stop_tx_beacon(hw); + _rtl8723be_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl8723be_resume_tx_beacon(hw); + _rtl8723be_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, MSR, bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + } + +} + +int rtl8723be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl8723be_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl8723be_set_check_bssid(hw, true); + } else { + rtl8723be_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here + * because mac80211 will send pkt when scan + */ +void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl8723_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci); + break; + } +} + +void rtl8723be_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; + + /*enable system interrupt*/ + rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF); +} + +void rtl8723be_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +void rtl8723be_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl8723be_set_media_status(hw, opmode); + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + _rtl8723be_poweroff_adapter(hw); + + /* after power off we should do iqk again */ + if (!rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->phy.iqk_initialized = false; +} + +void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); + + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & + rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); +} + +void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl8723be_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtl8723be_enable_interrupt(hw); +} + +void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl8723be_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl8723be_enable_interrupt(hw); +} + +void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl8723be_disable_interrupt(hw); + rtl8723be_enable_interrupt(hw); +} + +static u8 _rtl8723be_get_chnl_group(u8 chnl) +{ + u8 group; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + return group; +} + +static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pw2g, + struct txpower_info_5g *pw5g, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n", + (addr + 1), hwinfo[addr + 1]); + if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/ + autoload_fail = true; + + if (autoload_fail) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (path = 0; path < MAX_RF_PATH; path++) { + /* 2.4G default value */ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pw2g->index_cck_base[path][group] = 0x2D; + pw2g->index_bw40_base[path][group] = 0x2D; + } + for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { + if (cnt == 0) { + pw2g->bw20_diff[path][0] = 0x02; + pw2g->ofdm_diff[path][0] = 0x04; + } else { + pw2g->bw20_diff[path][cnt] = 0xFE; + pw2g->bw40_diff[path][cnt] = 0xFE; + pw2g->cck_diff[path][cnt] = 0xFE; + pw2g->ofdm_diff[path][cnt] = 0xFE; + } + } + } + return; + } + + for (path = 0; path < MAX_RF_PATH; path++) { + /*2.4G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + pw2g->index_cck_base[path][group] = hwinfo[addr++]; + if (pw2g->index_cck_base[path][group] == 0xFF) + pw2g->index_cck_base[path][group] = 0x2D; + + } + for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { + pw2g->index_bw40_base[path][group] = hwinfo[addr++]; + if (pw2g->index_bw40_base[path][group] == 0xFF) + pw2g->index_bw40_base[path][group] = 0x2D; + } + for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { + if (cnt == 0) { + pw2g->bw40_diff[path][cnt] = 0; + if (hwinfo[addr] == 0xFF) { + pw2g->bw20_diff[path][cnt] = 0x02; + } else { + pw2g->bw20_diff[path][cnt] = + (hwinfo[addr] & 0xf0) >> 4; + /*bit sign number to 8 bit sign number*/ + if (pw2g->bw20_diff[path][cnt] & BIT(3)) + pw2g->bw20_diff[path][cnt] |= + 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pw2g->ofdm_diff[path][cnt] = 0x04; + } else { + pw2g->ofdm_diff[path][cnt] = + (hwinfo[addr] & 0x0f); + /*bit sign number to 8 bit sign number*/ + if (pw2g->ofdm_diff[path][cnt] & BIT(3)) + pw2g->ofdm_diff[path][cnt] |= + 0xF0; + } + pw2g->cck_diff[path][cnt] = 0; + addr++; + } else { + if (hwinfo[addr] == 0xFF) { + pw2g->bw40_diff[path][cnt] = 0xFE; + } else { + pw2g->bw40_diff[path][cnt] = + (hwinfo[addr] & 0xf0) >> 4; + if (pw2g->bw40_diff[path][cnt] & BIT(3)) + pw2g->bw40_diff[path][cnt] |= + 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pw2g->bw20_diff[path][cnt] = 0xFE; + } else { + pw2g->bw20_diff[path][cnt] = + (hwinfo[addr] & 0x0f); + if (pw2g->bw20_diff[path][cnt] & BIT(3)) + pw2g->bw20_diff[path][cnt] |= + 0xF0; + } + addr++; + + if (hwinfo[addr] == 0xFF) { + pw2g->ofdm_diff[path][cnt] = 0xFE; + } else { + pw2g->ofdm_diff[path][cnt] = + (hwinfo[addr] & 0xf0) >> 4; + if (pw2g->ofdm_diff[path][cnt] & BIT(3)) + pw2g->ofdm_diff[path][cnt] |= + 0xF0; + } + + if (hwinfo[addr] == 0xFF) + pw2g->cck_diff[path][cnt] = 0xFE; + else { + pw2g->cck_diff[path][cnt] = + (hwinfo[addr] & 0x0f); + if (pw2g->cck_diff[path][cnt] & BIT(3)) + pw2g->cck_diff[path][cnt] |= + 0xF0; + } + addr++; + } + } + + /*5G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_5G; group++) { + pw5g->index_bw40_base[path][group] = hwinfo[addr++]; + if (pw5g->index_bw40_base[path][group] == 0xFF) + pw5g->index_bw40_base[path][group] = 0xFE; + } + + for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { + if (cnt == 0) { + pw5g->bw40_diff[path][cnt] = 0; + + if (hwinfo[addr] == 0xFF) { + pw5g->bw20_diff[path][cnt] = 0; + } else { + pw5g->bw20_diff[path][0] = + (hwinfo[addr] & 0xf0) >> 4; + if (pw5g->bw20_diff[path][cnt] & BIT(3)) + pw5g->bw20_diff[path][cnt] |= + 0xF0; + } + + if (hwinfo[addr] == 0xFF) + pw5g->ofdm_diff[path][cnt] = 0x04; + else { + pw5g->ofdm_diff[path][0] = + (hwinfo[addr] & 0x0f); + if (pw5g->ofdm_diff[path][cnt] & BIT(3)) + pw5g->ofdm_diff[path][cnt] |= + 0xF0; + } + addr++; + } else { + if (hwinfo[addr] == 0xFF) { + pw5g->bw40_diff[path][cnt] = 0xFE; + } else { + pw5g->bw40_diff[path][cnt] = + (hwinfo[addr] & 0xf0) >> 4; + if (pw5g->bw40_diff[path][cnt] & BIT(3)) + pw5g->bw40_diff[path][cnt] |= 0xF0; + } + + if (hwinfo[addr] == 0xFF) { + pw5g->bw20_diff[path][cnt] = 0xFE; + } else { + pw5g->bw20_diff[path][cnt] = + (hwinfo[addr] & 0x0f); + if (pw5g->bw20_diff[path][cnt] & BIT(3)) + pw5g->bw20_diff[path][cnt] |= 0xF0; + } + addr++; + } + } + + if (hwinfo[addr] == 0xFF) { + pw5g->ofdm_diff[path][1] = 0xFE; + pw5g->ofdm_diff[path][2] = 0xFE; + } else { + pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4; + pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f); + } + addr++; + + if (hwinfo[addr] == 0xFF) + pw5g->ofdm_diff[path][3] = 0xFE; + else + pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f); + addr++; + + for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) { + if (pw5g->ofdm_diff[path][cnt] == 0xFF) + pw5g->ofdm_diff[path][cnt] = 0xFE; + else if (pw5g->ofdm_diff[path][cnt] & BIT(3)) + pw5g->ofdm_diff[path][cnt] |= 0xF0; + } + } +} + +static noinline_for_stack void +_rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pw2g; + struct txpower_info_5g pw5g; + u8 rf_path, index; + u8 i; + + _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail, + hwinfo); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl8723be_get_chnl_group(i+1); + + rtlefuse->txpwrlevel_cck[rf_path][i] = + pw2g.index_cck_base[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pw2g.index_bw40_base[rf_path][index]; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + rtlefuse->txpwr_ht20diff[rf_path][i] = + pw2g.bw20_diff[rf_path][i]; + rtlefuse->txpwr_ht40diff[rf_path][i] = + pw2g.bw40_diff[rf_path][i]; + rtlefuse->txpwr_legacyhtdiff[rf_path][i] = + pw2g.ofdm_diff[rf_path][i]; + } + + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i]); + } + } + + if (!autoload_fail) + rtlefuse->eeprom_thermalmeter = + hwinfo[EEPROM_THERMAL_METER_88E]; + else + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + + if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) { + rtlefuse->apk_thermalmeterignore = true; + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + } + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + + if (!autoload_fail) { + rtlefuse->eeprom_regulatory = + hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/ + if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) + rtlefuse->eeprom_regulatory = 0; + } else { + rtlefuse->eeprom_regulatory = 0; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); +} + +static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw) +{ + u8 package_type; + u8 value; + + efuse_power_switch(hw, false, true); + if (!efuse_one_byte_read(hw, 0x1FB, &value)) + value = 0; + efuse_power_switch(hw, false, false); + + switch (value & 0x7) { + case 0x4: + package_type = PACKAGE_TFBGA79; + break; + case 0x5: + package_type = PACKAGE_TFBGA90; + break; + case 0x6: + package_type = PACKAGE_QFN68; + break; + case 0x7: + package_type = PACKAGE_TFBGA80; + break; + default: + package_type = PACKAGE_DEFAULT; + break; + } + + return package_type; +} + +static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw, + bool pseudo_test) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + static const int params[] = { + RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13 + }; + u8 *hwinfo; + int i; + bool is_toshiba_smid1 = false; + bool is_toshiba_smid2 = false; + bool is_samsung_smid = false; + bool is_lenovo_smid = false; + static const u16 toshiba_smid1[] = { + 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180, + 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180, + 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185, + 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185 + }; + static const u16 toshiba_smid2[] = { + 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181, + 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185 + }; + static const u16 samsung_smid[] = { + 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192, + 0x8193, 0x9191, 0x9192, 0x9193 + }; + static const u16 lenovo_smid[] = { + 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200 + }; + + if (pseudo_test) { + /* needs to be added */ + return; + } + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE]; + if (rtlefuse->crystalcap == 0xFF) + rtlefuse->crystalcap = 0x20; + + _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + rtl8723be_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, + hwinfo); + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) + rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */ + + rtlhal->board_type = rtlefuse->board_type; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "board_type = 0x%x\n", rtlefuse->board_type); + + rtlhal->package_type = _rtl8723be_read_package_type(hw); + + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + /* Does this one have a Toshiba SMID from group 1? */ + for (i = 0; i < ARRAY_SIZE(toshiba_smid1); i++) { + if (rtlefuse->eeprom_smid == toshiba_smid1[i]) { + is_toshiba_smid1 = true; + break; + } + } + /* Does this one have a Toshiba SMID from group 2? */ + for (i = 0; i < ARRAY_SIZE(toshiba_smid2); i++) { + if (rtlefuse->eeprom_smid == toshiba_smid2[i]) { + is_toshiba_smid2 = true; + break; + } + } + /* Does this one have a Samsung SMID? */ + for (i = 0; i < ARRAY_SIZE(samsung_smid); i++) { + if (rtlefuse->eeprom_smid == samsung_smid[i]) { + is_samsung_smid = true; + break; + } + } + /* Does this one have a Lenovo SMID? */ + for (i = 0; i < ARRAY_SIZE(lenovo_smid); i++) { + if (rtlefuse->eeprom_smid == lenovo_smid[i]) { + is_lenovo_smid = true; + break; + } + } + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if (rtlefuse->eeprom_svid == 0x10EC && + is_toshiba_smid1) { + rtlhal->oem_id = RT_CID_TOSHIBA; + } else if (rtlefuse->eeprom_svid == 0x1025) { + rtlhal->oem_id = RT_CID_819X_ACER; + } else if (rtlefuse->eeprom_svid == 0x10EC && + is_samsung_smid) { + rtlhal->oem_id = RT_CID_819X_SAMSUNG; + } else if (rtlefuse->eeprom_svid == 0x10EC && + is_lenovo_smid) { + rtlhal->oem_id = RT_CID_819X_LENOVO; + } else if ((rtlefuse->eeprom_svid == 0x10EC && + rtlefuse->eeprom_smid == 0x8197) || + (rtlefuse->eeprom_svid == 0x10EC && + rtlefuse->eeprom_smid == 0x9196)) { + rtlhal->oem_id = RT_CID_819X_CLEVO; + } else if ((rtlefuse->eeprom_svid == 0x1028 && + rtlefuse->eeprom_smid == 0x8194) || + (rtlefuse->eeprom_svid == 0x1028 && + rtlefuse->eeprom_smid == 0x8198) || + (rtlefuse->eeprom_svid == 0x1028 && + rtlefuse->eeprom_smid == 0x9197) || + (rtlefuse->eeprom_svid == 0x1028 && + rtlefuse->eeprom_smid == 0x9198)) { + rtlhal->oem_id = RT_CID_819X_DELL; + } else if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) { + rtlhal->oem_id = RT_CID_819X_HP; + } else if ((rtlefuse->eeprom_svid == 0x1A32 && + rtlefuse->eeprom_smid == 0x2315)) { + rtlhal->oem_id = RT_CID_819X_QMI; + } else if ((rtlefuse->eeprom_svid == 0x10EC && + rtlefuse->eeprom_smid == 0x8203)) { + rtlhal->oem_id = RT_CID_819X_PRONETS; + } else if ((rtlefuse->eeprom_svid == 0x1043 && + rtlefuse->eeprom_smid == 0x84B5)) { + rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + } else if (rtlefuse->eeprom_did == 0x8178) { + if (rtlefuse->eeprom_svid == 0x10EC && + is_toshiba_smid2) + rtlhal->oem_id = RT_CID_TOSHIBA; + else if (rtlefuse->eeprom_svid == 0x1025) + rtlhal->oem_id = RT_CID_819X_ACER; + else if ((rtlefuse->eeprom_svid == 0x10EC && + rtlefuse->eeprom_smid == 0x8186)) + rtlhal->oem_id = RT_CID_819X_PRONETS; + else if ((rtlefuse->eeprom_svid == 0x1043 && + rtlefuse->eeprom_smid == 0x84B6)) + rtlhal->oem_id = + RT_CID_819X_EDIMAX_ASUS; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_CCX: + rtlhal->oem_id = RT_CID_CCX; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + break; + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } + } +exit: + kfree(hwinfo); +} + +static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpriv->ledctl.led_opendrain = true; + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl8723be_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl8723be_read_adapter_info(hw, false); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl8723be_hal_customized_behavior(hw); +} + +static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, + u8 rate_index) +{ + u8 ret = 0; + switch (rate_index) { + case RATR_INX_WIRELESS_NGB: + ret = 1; + break; + case RATR_INX_WIRELESS_N: + case RATR_INX_WIRELESS_NG: + ret = 5; + break; + case RATR_INX_WIRELESS_NB: + ret = 3; + break; + case RATR_INX_WIRELESS_GB: + ret = 6; + break; + case RATR_INX_WIRELESS_G: + ret = 7; + break; + case RATR_INX_WIRELESS_B: + ret = 8; + break; + default: + ret = 0; + break; + } + return ret; +} + +static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u8 rate_mask[7]; + u8 macid = 0; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + ratr_bitmap = sta->deflink.supp_rates[0]; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + if (rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f8ff000; + else + ratr_bitmap &= 0x0f8ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f8f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f8ff000; + else + ratr_bitmap &= 0x0f8ff005; + } + } + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + + sta_entry->ratr_index = ratr_index; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); + rate_mask[0] = macid; + rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) | + (shortgi ? 0x80 : 0x00); + rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3); + + rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); + rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); + rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); + rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4], rate_mask[5], + rate_mask[6]); + rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask); + _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (rtlpriv->dm.useramask) + rtl8723be_update_hal_rate_mask(hw, sta, rssi_level, update_bw); +} + +void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp; + bool b_actuallyset = false; + + if (rtlpriv->rtlhal.being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, + rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); + + if (rtlphy->polarity_ctl) + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; + else + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; + + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + b_actuallyset = true; + } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + *valid = 1; + return !ppsc->hwradiooff; + +} + +void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } + } +} + +void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; + u8 value; + u32 tmpu_32; + + if (!auto_load_fail) { + tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); + if (tmpu_32 & BIT(18)) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + value = hwinfo[EEPROM_RF_BT_SETTING_8723B]; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; + rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); + rtlpriv->btcoexist.btc_info.single_ant_path = + (value & 0x40 ? ANT_AUX : ANT_MAIN); /*0xc3[6]*/ + } else { + rtlpriv->btcoexist.btc_info.btcoexist = 0; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; + rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; + rtlpriv->btcoexist.btc_info.single_ant_path = ANT_MAIN; + } + + /* override ant_num / ant_path */ + if (mod_params->ant_sel) { + rtlpriv->btcoexist.btc_info.ant_num = + (mod_params->ant_sel == 1 ? ANT_X1 : ANT_X2); + + rtlpriv->btcoexist.btc_info.single_ant_path = + (mod_params->ant_sel == 1 ? ANT_AUX : ANT_MAIN); + } +} + +void rtl8723be_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8723be_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); + +} + +void rtl8723be_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl8723be_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h new file mode 100644 index 000000000..eb797e9bb --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_HW_H__ +#define __RTL8723BE_HW_H__ + +void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw); + +void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl8723be_hw_init(struct ieee80211_hw *hw); +void rtl8723be_card_disable(struct ieee80211_hw *hw); +void rtl8723be_enable_interrupt(struct ieee80211_hw *hw); +void rtl8723be_disable_interrupt(struct ieee80211_hw *hw); +int rtl8723be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw); +void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); +void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8723be_bt_reg_init(struct ieee80211_hw *hw); +void rtl8723be_bt_hw_init(struct ieee80211_hw *hw); +void rtl8723be_suspend(struct ieee80211_hw *hw); +void rtl8723be_resume(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c new file mode 100644 index 000000000..462fe1d02 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl8723be_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +void rtl8723be_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) { + ledcfg &= 0x90; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); + ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); + ledcfg &= 0xFE; + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); + } else { + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5))); + } + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + ledcfg &= 0x10; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); + + break; + default: + pr_err("switch case %#x not processed\n", pin); + break; + } +} + +static void _rtl8723be_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl8723be_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + rtl8723be_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl8723be_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); + _rtl8723be_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h new file mode 100644 index 000000000..3ca927715 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_LED_H__ +#define __RTL8723BE_LED_H__ + +void rtl8723be_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8723be_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8723be_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c new file mode 100644 index 000000000..13e689037 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c @@ -0,0 +1,2656 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "rf.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "table.h" +#include "trx.h" +#include + +static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw); +static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, + u8 *step, u32 *delay); + +static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8723be_phy_set_io(struct ieee80211_hw *hw); + +u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, path); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = rtl8723_phy_rf_serial_read(hw, path, + regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } + + rtl8723_phy_rf_serial_write(hw, path, regaddr, data); + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, path); + +} + +bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw); + + rtl_write_byte(rtlpriv, 0x04CA, 0x0B); + return rtstatus; +} + +bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u8 b_reg_hwparafile = 1; + u32 tmp; + u8 crystalcap = rtlpriv->efuse.crystalcap; + rtl8723_phy_init_bb_rf_reg_def(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | + FEN_BB_GLB_RSTN | FEN_BBRSTB); + tmp = rtl_read_dword(rtlpriv, 0x4c); + rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); + + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + + if (b_reg_hwparafile == 1) + rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw); + + crystalcap = crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystalcap | crystalcap << 6)); + + return rtstatus; +} + +bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl8723be_phy_rf6052_config(hw); +} + +static bool _rtl8723be_check_positive(struct ieee80211_hw *hw, + const u32 condition1, + const u32 condition2) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK) + >> CHIP_VER_RTL_SHIFT); + u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0)); + + u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */ + ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */ + ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */ + ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */ + + u32 cond1 = condition1, cond2 = condition2; + u32 driver1 = cut_ver << 24 | /* CUT ver */ + 0 << 20 | /* interface 2/2 */ + 0x04 << 16 | /* platform */ + rtlhal->package_type << 12 | + intf << 8 | /* interface 1/2 */ + board_type; + + u32 driver2 = rtlhal->type_glna << 0 | + rtlhal->type_gpa << 8 | + rtlhal->type_alna << 16 | + rtlhal->type_apa << 24; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n", + cond1, cond2); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n", + driver1, driver2); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "(Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "(Board, Package) = (0x%X, 0x%X)\n", + rtlhal->board_type, rtlhal->package_type); + + /*============== Value Defined Check ===============*/ + /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != + (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != + (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 mask = 0; + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + mask |= 0xFF000000; + + /* BoardType of each RF path is matched*/ + if ((cond2 & mask) == (driver2 & mask)) + return true; + else + return false; + } + return false; +} + +static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr, + u32 data, enum radio_path rfpath, + u32 regaddr) +{ + if (addr == 0xfe || addr == 0xffe) { + /* In order not to disturb BT music + * when wifi init.(1ant NIC only) + */ + mdelay(50); + } else { + rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); + udelay(1); + } +} +static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1000; /*RF Content: radio_a_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A, + addr | maskforphyset); + +} + +static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 band, path, txnum, section; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) + for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path) + for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) + for (section = 0; + section < TX_PWR_BY_RATE_NUM_SECTION; + ++section) + rtlphy->tx_power_by_rate_offset + [band][path][txnum][section] = 0; +} + +static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + if (addr == 0xfe) { + mdelay(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + rtl_set_bbreg(hw, addr, MASKDWORD, data); + udelay(1); + } +} + +static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, + u8 path, u8 rate_section, + u8 txnum, u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", + path); + return; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; + break; + case OFDM: + rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; + break; + case HT_MCS0_MCS7: + rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; + break; + case HT_MCS8_MCS15: + rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", + band); + } + +} + +static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, u8 txnum, + u8 rate_section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 value = 0; + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", + path); + return 0; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; + break; + case OFDM: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; + break; + case HT_MCS0_MCS7: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; + break; + case HT_MCS8_MCS15: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", + band); + } + + return value; +} + +static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u16 rawvalue = 0; + u8 base = 0, path = 0; + + for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { + if (path == RF90_PATH_A) { + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, + BAND_ON_2_4G, path, CCK, RF_1TX, base); + } else if (path == RF90_PATH_B) { + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, + BAND_ON_2_4G, + path, CCK, + RF_1TX, base); + } + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, OFDM, RF_1TX, + base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, HT_MCS0_MCS7, + RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, HT_MCS8_MCS15, + RF_2TX, base); + } +} + +static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, + u8 end, u8 base_val) +{ + s8 i = 0; + u8 temp_value = 0; + u32 temp_data = 0; + + for (i = 3; i >= 0; --i) { + if (i >= start && i <= end) { + /* Get the exact value */ + temp_value = (u8)(*data >> (i * 8)) & 0xF; + temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10; + + /* Change the value to a relative value */ + temp_value = (temp_value > base_val) ? + temp_value - base_val : + base_val - temp_value; + } else { + temp_value = (u8)(*data >> (i * 8)) & 0xFF; + } + temp_data <<= 8; + temp_data |= temp_value; + } + *data = temp_data; +} + +static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 base = 0, rfpath = RF90_PATH_A; + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, + BAND_ON_2_4G, rfpath, RF_1TX, CCK); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2], + 1, 1, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3], + 1, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, + RF_1TX, OFDM); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1], + 0, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, + rfpath, RF_1TX, HT_MCS0_MCS7); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5], + 0, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, + rfpath, RF_2TX, + HT_MCS8_MCS15); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6], + 0, 3, base); + + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7], + 0, 3, base); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "<===%s\n", __func__); +} + +static void phy_txpower_by_rate_config(struct ieee80211_hw *hw) +{ + _rtl8723be_phy_store_txpower_by_rate_base(hw); + _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw); +} + +static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + /* switch ant to BT */ + if (rtlpriv->rtlhal.interface == INTF_USB) { + rtl_write_dword(rtlpriv, 0x948, 0x0); + } else { + if (rtlpriv->btcoexist.btc_info.single_ant_path == 0) + rtl_write_dword(rtlpriv, 0x948, 0x280); + else + rtl_write_dword(rtlpriv, 0x948, 0x0); + } + + rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + _rtl8723be_phy_init_tx_power_by_rate(hw); + if (!rtlefuse->autoload_failflag) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + phy_txpower_by_rate_config(hw); + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + return true; +} + +static bool rtl8723be_phy_config_with_headerfile(struct ieee80211_hw *hw, + u32 *array_table, + u16 arraylen, + void (*set_reg)(struct ieee80211_hw *hw, u32 regaddr, u32 data)) +{ + #define COND_ELSE 2 + #define COND_ENDIF 3 + + int i = 0; + u8 cond; + bool matched = true, skipped = false; + + while ((i + 1) < arraylen) { + u32 v1 = array_table[i]; + u32 v2 = array_table[i + 1]; + + if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/ + if (v1 & BIT(31)) {/* positive condition*/ + cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (cond == COND_ENDIF) { /*end*/ + matched = true; + skipped = false; + } else if (cond == COND_ELSE) { /*else*/ + matched = skipped ? false : true; + } else {/*if , else if*/ + if (skipped) { + matched = false; + } else { + if (_rtl8723be_check_positive( + hw, v1, v2)) { + matched = true; + skipped = true; + } else { + matched = false; + skipped = false; + } + } + } + } else if (v1 & BIT(30)) { /*negative condition*/ + /*do nothing*/ + } + } else { + if (matched) + set_reg(hw, v1, v2); + } + i = i + 2; + } + + return true; +} + +static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n"); + + return rtl8723be_phy_config_with_headerfile(hw, + RTL8723BEMAC_1T_ARRAY, RTL8723BEMAC_1T_ARRAYLEN, + rtl_write_byte_with_val32); +} + +static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + + if (configtype == BASEBAND_CONFIG_PHY_REG) + return rtl8723be_phy_config_with_headerfile(hw, + RTL8723BEPHY_REG_1TARRAY, + RTL8723BEPHY_REG_1TARRAYLEN, + _rtl8723be_config_bb_reg); + else if (configtype == BASEBAND_CONFIG_AGC_TAB) + return rtl8723be_phy_config_with_headerfile(hw, + RTL8723BEAGCTAB_1TARRAY, + RTL8723BEAGCTAB_1TARRAYLEN, + rtl_set_bbreg_with_dwmask); + + return false; +} + +static u8 _rtl8723be_get_rate_section_index(u32 regaddr) +{ + u8 index = 0; + + switch (regaddr) { + case RTXAGC_A_RATE18_06: + index = 0; + break; + case RTXAGC_A_RATE54_24: + index = 1; + break; + case RTXAGC_A_CCK1_MCS32: + index = 2; + break; + case RTXAGC_B_CCK11_A_CCK2_11: + index = 3; + break; + case RTXAGC_A_MCS03_MCS00: + index = 4; + break; + case RTXAGC_A_MCS07_MCS04: + index = 5; + break; + case RTXAGC_A_MCS11_MCS08: + index = 6; + break; + case RTXAGC_A_MCS15_MCS12: + index = 7; + break; + case RTXAGC_B_RATE18_06: + index = 0; + break; + case RTXAGC_B_RATE54_24: + index = 1; + break; + case RTXAGC_B_CCK1_55_MCS32: + index = 2; + break; + case RTXAGC_B_MCS03_MCS00: + index = 4; + break; + case RTXAGC_B_MCS07_MCS04: + index = 5; + break; + case RTXAGC_B_MCS11_MCS08: + index = 6; + break; + case RTXAGC_B_MCS15_MCS12: + index = 7; + break; + default: + regaddr &= 0xFFF; + if (regaddr >= 0xC20 && regaddr <= 0xC4C) + index = (u8)((regaddr - 0xC20) / 4); + else if (regaddr >= 0xE20 && regaddr <= 0xE4C) + index = (u8)((regaddr - 0xE20) / 4); + break; + } + return index; +} + +static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw, + u32 band, u32 rfpath, + u32 txnum, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rate_section = _rtl8723be_get_rate_section_index(regaddr); + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band); + return; + } + if (rfpath > MAX_RF_PATH - 1) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, + "Invalid RfPath %d\n", rfpath); + return; + } + if (txnum > MAX_RF_PATH - 1) { + rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); + return; + } + + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = + data; + +} + +static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0; + + phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN; + phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 6) { + v1 = phy_regarray_table_pg[i]; + v2 = phy_regarray_table_pg[i+1]; + v3 = phy_regarray_table_pg[i+2]; + v4 = phy_regarray_table_pg[i+3]; + v5 = phy_regarray_table_pg[i+4]; + v6 = phy_regarray_table_pg[i+5]; + + if (v1 < 0xcdcdcdcd) { + if (phy_regarray_table_pg[i] == 0xfe || + phy_regarray_table_pg[i] == 0xffe) + mdelay(50); + else + _rtl8723be_store_tx_power_by_rate(hw, + v1, v2, v3, v4, v5, v6); + continue; + } + } + } else { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + } + return true; +} + +bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool ret = true; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + ret = rtl8723be_phy_config_with_headerfile(hw, + RTL8723BE_RADIOA_1TARRAY, + RTL8723BE_RADIOA_1TARRAYLEN, + _rtl8723be_config_rf_radio_a); + + if (rtlhal->oem_id == RT_CID_819X_HP) + _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD); + break; + case RF90_PATH_B: + case RF90_PATH_C: + break; + case RF90_PATH_D: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", rfpath); + break; + } + return ret; +} + +void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, + MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, + MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, + u8 rate) +{ + u8 rate_section = 0; + + switch (rate) { + case DESC92C_RATE1M: + rate_section = 2; + break; + + case DESC92C_RATE2M: + case DESC92C_RATE5_5M: + if (path == RF90_PATH_A) + rate_section = 3; + else if (path == RF90_PATH_B) + rate_section = 2; + break; + + case DESC92C_RATE11M: + rate_section = 3; + break; + + case DESC92C_RATE6M: + case DESC92C_RATE9M: + case DESC92C_RATE12M: + case DESC92C_RATE18M: + rate_section = 0; + break; + + case DESC92C_RATE24M: + case DESC92C_RATE36M: + case DESC92C_RATE48M: + case DESC92C_RATE54M: + rate_section = 1; + break; + + case DESC92C_RATEMCS0: + case DESC92C_RATEMCS1: + case DESC92C_RATEMCS2: + case DESC92C_RATEMCS3: + rate_section = 4; + break; + + case DESC92C_RATEMCS4: + case DESC92C_RATEMCS5: + case DESC92C_RATEMCS6: + case DESC92C_RATEMCS7: + rate_section = 5; + break; + + case DESC92C_RATEMCS8: + case DESC92C_RATEMCS9: + case DESC92C_RATEMCS10: + case DESC92C_RATEMCS11: + rate_section = 6; + break; + + case DESC92C_RATEMCS12: + case DESC92C_RATEMCS13: + case DESC92C_RATEMCS14: + case DESC92C_RATEMCS15: + rate_section = 7; + break; + + default: + WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n"); + break; + } + + return rate_section; +} + +static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw, + enum band_type band, + enum radio_path rfpath, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 shift = 0, rate_section, tx_num; + s8 tx_pwr_diff = 0; + + rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath, + rate); + tx_num = RF_TX_NUM_NONIMPLEMENT; + + if (tx_num == RF_TX_NUM_NONIMPLEMENT) { + if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15) + tx_num = RF_2TX; + else + tx_num = RF_1TX; + } + + switch (rate) { + case DESC92C_RATE6M: + case DESC92C_RATE24M: + case DESC92C_RATEMCS0: + case DESC92C_RATEMCS4: + case DESC92C_RATEMCS8: + case DESC92C_RATEMCS12: + shift = 0; + break; + case DESC92C_RATE1M: + case DESC92C_RATE2M: + case DESC92C_RATE9M: + case DESC92C_RATE36M: + case DESC92C_RATEMCS1: + case DESC92C_RATEMCS5: + case DESC92C_RATEMCS9: + case DESC92C_RATEMCS13: + shift = 8; + break; + case DESC92C_RATE5_5M: + case DESC92C_RATE12M: + case DESC92C_RATE48M: + case DESC92C_RATEMCS2: + case DESC92C_RATEMCS6: + case DESC92C_RATEMCS10: + case DESC92C_RATEMCS14: + shift = 16; + break; + case DESC92C_RATE11M: + case DESC92C_RATE18M: + case DESC92C_RATE54M: + case DESC92C_RATEMCS3: + case DESC92C_RATEMCS7: + case DESC92C_RATEMCS11: + case DESC92C_RATEMCS15: + shift = 24; + break; + default: + WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n"); + break; + } + tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num] + [rate_section] >> shift) & 0xff; + + return tx_pwr_diff; +} + +static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, + u8 rate, u8 bandwidth, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + u8 txpower = 0; + u8 power_diff_byrate = 0; + + if (channel > 14 || channel < 1) { + index = 0; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Illegal channel!\n"); + } + if (RX_HAL_IS_CCK_RATE(rate)) + txpower = rtlefuse->txpwrlevel_cck[path][index]; + else if (DESC92C_RATE6M <= rate) + txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; + else + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "invalid rate\n"); + + if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && + !RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) + txpower += rtlefuse->txpwr_ht20diff[0][TX_1S]; + if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) + txpower += rtlefuse->txpwr_ht20diff[0][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) + txpower += rtlefuse->txpwr_ht40diff[0][TX_1S]; + if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) + txpower += rtlefuse->txpwr_ht40diff[0][TX_2S]; + } + + if (rtlefuse->eeprom_regulatory != 2) + power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw, + BAND_ON_2_4G, + path, rate); + + txpower += power_diff_byrate; + + if (txpower > MAX_POWER_INDEX) + txpower = MAX_POWER_INDEX; + + return txpower; +} + +static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, + u8 power_index, u8 path, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (path == RF90_PATH_A) { + switch (rate) { + case DESC92C_RATE1M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32, + MASKBYTE1, power_index); + break; + case DESC92C_RATE2M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, + MASKBYTE1, power_index); + break; + case DESC92C_RATE5_5M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, + MASKBYTE2, power_index); + break; + case DESC92C_RATE11M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, + MASKBYTE3, power_index); + break; + + case DESC92C_RATE6M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, + MASKBYTE0, power_index); + break; + case DESC92C_RATE9M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, + MASKBYTE1, power_index); + break; + case DESC92C_RATE12M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, + MASKBYTE2, power_index); + break; + case DESC92C_RATE18M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, + MASKBYTE3, power_index); + break; + + case DESC92C_RATE24M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, + MASKBYTE0, power_index); + break; + case DESC92C_RATE36M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, + MASKBYTE1, power_index); + break; + case DESC92C_RATE48M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, + MASKBYTE2, power_index); + break; + case DESC92C_RATE54M: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, + MASKBYTE3, power_index); + break; + + case DESC92C_RATEMCS0: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE0, power_index); + break; + case DESC92C_RATEMCS1: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE1, power_index); + break; + case DESC92C_RATEMCS2: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE2, power_index); + break; + case DESC92C_RATEMCS3: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE3, power_index); + break; + + case DESC92C_RATEMCS4: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE0, power_index); + break; + case DESC92C_RATEMCS5: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE1, power_index); + break; + case DESC92C_RATEMCS6: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE2, power_index); + break; + case DESC92C_RATEMCS7: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE3, power_index); + break; + + case DESC92C_RATEMCS8: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE0, power_index); + break; + case DESC92C_RATEMCS9: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE1, power_index); + break; + case DESC92C_RATEMCS10: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE2, power_index); + break; + case DESC92C_RATEMCS11: + rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE3, power_index); + break; + + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n"); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); + } +} + +void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + static const u8 cck_rates[] = { + DESC92C_RATE1M, DESC92C_RATE2M, + DESC92C_RATE5_5M, DESC92C_RATE11M + }; + static const u8 ofdm_rates[] = { + DESC92C_RATE6M, DESC92C_RATE9M, + DESC92C_RATE12M, DESC92C_RATE18M, + DESC92C_RATE24M, DESC92C_RATE36M, + DESC92C_RATE48M, DESC92C_RATE54M + }; + static const u8 ht_rates_1t[] = { + DESC92C_RATEMCS0, DESC92C_RATEMCS1, + DESC92C_RATEMCS2, DESC92C_RATEMCS3, + DESC92C_RATEMCS4, DESC92C_RATEMCS5, + DESC92C_RATEMCS6, DESC92C_RATEMCS7 + }; + u8 i; + u8 power_index; + + if (!rtlefuse->txpwr_fromeprom) + return; + + for (i = 0; i < ARRAY_SIZE(cck_rates); i++) { + power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, + cck_rates[i], + rtl_priv(hw)->phy.current_chan_bw, + channel); + _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, + cck_rates[i]); + } + for (i = 0; i < ARRAY_SIZE(ofdm_rates); i++) { + power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, + ofdm_rates[i], + rtl_priv(hw)->phy.current_chan_bw, + channel); + _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, + ofdm_rates[i]); + } + for (i = 0; i < ARRAY_SIZE(ht_rates_1t); i++) { + power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, + ht_rates_1t[i], + rtl_priv(hw)->phy.current_chan_bw, + channel); + _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, + ht_rates_1t[i]); + } +} + +void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = (reg_prsr_rsc & 0x90) | + (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/ + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/ + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); +} + +void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl8723be_phy_set_bw_mode_callback(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "false driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 delay = 0; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl8723be_phy_sw_chnl_step_by_step(hw, + rtlphy->current_channel, + &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, + &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + WARN_ONCE((rtlphy->current_channel > 14), + "rtl8723be: WIRELESS_MODE_G but channel>14"); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl8723be_phy_sw_chnl_callback(hw); + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false schedule workitem current channel %d\n", + rtlphy->current_channel); + rtlphy->sw_chnl_inprogress = false; + } else { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, + u8 *step, u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, + 0, 0, 0); + rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, + 0, 0, 0); + + rfdependcmdcnt = 0; + + WARN_ONCE((channel < 1 || channel > 14), + "rtl8723be: illegal channel for Zebra: %d\n", channel); + + rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, + CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, + CMDID_END, 0, 0, 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + default: + pr_err("Invalid 'stage' = %d, Check it!\n", + *stage); + return true; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl8723be_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + currentcmd->cmdid); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_e94, reg_e9c, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path A */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); + /* enable path A PA in TXIQK mode */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87); + + /* 1. TX IQK */ + /* path-A IQK setting */ + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* switch to path A */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); + + /* 1 Get TXIMR setting */ + /* modify RXIQK mode table */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + /* LNA2 off, PA on for Dcut */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | + ((reg_e9c & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); + + /* 1 RX IQK */ + /* modify RXIQK mode table */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + /* LAN2 on, PA off for Dcut */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); + + /* PA, PAD setting */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80); + rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f); + + /* IQK setting */ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780); + + /* Allen 20131125 */ + tmp = (reg_eac & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + /* if Tx is OK, check whether Rx is OK */ + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && + (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x02; + + return result; +} + +static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_e94, reg_e9c, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path B */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); + + /* enable path B PA in TXIQK mode */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1); + + /* 1 Tx IQK */ + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else + return result; + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw) +{ + u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path B */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); + + /* 1 Get TXIMR setting */ + /* modify RXIQK mode table */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7); + + /* open PA S1 & SMIXER */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed); + + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B TXIQK @ RXIQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else + return result; + + u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | + ((reg_e9c & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); + + /* 1 RX IQK */ + + /* <20121009, Kordan> RF Mode = 3 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0); + + /* open PA S1 & close SMIXER */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd); + + /* IQK setting */ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + /* Allen 20131125 */ + tmp = (reg_eac & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + /* if Tx is OK, check whether Rx is OK */ + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && + (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x02; + else + return result; + + return result; +} + +static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, + long result[][8], + u8 final_candidate, + bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */ + } +} + +static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound = 0; + + u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ + bool bresult = true; /* is2t = true*/ + s32 tmp1 = 0, tmp2 = 0; + + bound = 8; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { + if ((result[c1][i] & 0x00000200) != 0) + tmp1 = result[c1][i] | 0xFFFFFC00; + else + tmp1 = result[c1][i]; + + if ((result[c2][i] & 0x00000200) != 0) + tmp2 = result[c2][i] | 0xFFFFFC00; + else + tmp2 = result[c2][i]; + } else { + tmp1 = result[c1][i]; + tmp2 = result[c2][i]; + } + + diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap |= (1 << i); + } else + simularity_bitmap |= (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else { + if (!(simularity_bitmap & 0x03)) { /* path A TX OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */ + for (i = 2; i < 4; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x30)) { /* path B TX OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */ + for (i = 6; i < 8; i++) + result[3][i] = result[c1][i]; + } + return false; + } +} + +static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, + 0x870, 0x860, + 0x864, 0xa04 + }; + const u32 retrycount = 2; + + u32 path_sel_bb;/* path_sel_rf */ + + u8 tmp_reg_c50, tmp_reg_c58; + + tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0); + tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0); + + if (t == 0) { + rtl8723_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl8723_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + } + rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + + path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); + + rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /*BB Setting*/ + rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf); + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + + /* path A TX IQK */ + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl8723be_phy_path_a_iqk(hw); + if (patha_ok == 0x01) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Tx IQK Success!!\n"); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Tx IQK Fail!!\n"); + } + } + /* path A RX IQK */ + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw); + if (patha_ok == 0x03) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Rx IQK Success!!\n"); + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Rx IQK Fail!!\n"); + } + + if (0x00 == patha_ok) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n"); + + if (is2t) { + /* path B TX IQK */ + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl8723be_phy_path_b_iqk(hw); + if (pathb_ok == 0x01) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Tx IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xe9c, + MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Tx IQK Fail!!\n"); + } + /* path B RX IQK */ + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw); + if (pathb_ok == 0x03) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Rx IQK Success!!\n"); + result[t][6] = (rtl_get_bbreg(hw, 0xea4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xeac, + MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Rx IQK Fail!!\n"); + } + } + + /* Back to BB mode, load original value */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); + + if (t != 0) { + rtl8723_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + + rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); + /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/ + + rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); + rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50); + if (is2t) { + rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50); + rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58); + } + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n"); +} + +static u8 _get_right_chnl_place_for_iqk(u8 chnl) +{ + static const u8 channel_all[TARGET_CHNL_NUM_2G_5G] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 36, 38, 40, 42, 44, 46, + 48, 50, 52, 54, 56, 58, 60, 62, 64, + 100, 102, 104, 106, 108, 110, + 112, 114, 116, 118, 120, 122, + 124, 126, 128, 130, 132, 134, 136, + 138, 140, 149, 151, 153, 155, 157, + 159, 161, 163, 165 + }; + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } + } + return 0; +} + +static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + + rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a); + + /* In order not to disturb BT music when wifi init.(1ant NIC only) */ + /*mdelay(100);*/ + /* In order not to disturb BT music when wifi init.(1ant NIC only) */ + mdelay(50); + + rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0); + + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS, rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); +} + +static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + + if (bmain) /* left antenna */ + rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1); + else + rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2); +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME +/* IQK is merge from Merge Temp */ +void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + long result[4][8]; + u8 i, final_candidate, idx; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4; + long reg_tmp = 0; + bool is12simular, is13simular, is23simular; + u32 iqk_bb_reg[9] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + u32 path_sel_bb = 0; /* path_sel_rf = 0 */ + + if (rtlphy->lck_inprogress) + return; + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = true; + spin_unlock(&rtlpriv->locks.iqk_lock); + + if (b_recovery) { + rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); + goto label_done; + } + /* Save RF Path */ + path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); + /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */ + + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + b_patha_ok = false; + b_pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + _rtl8723be_phy_iq_calibrate(hw, result, i, true); + if (i == 1) { + is12simular = _rtl8723be_phy_simularity_compare(hw, + result, + 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl8723be_phy_simularity_compare(hw, + result, + 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl8723be_phy_simularity_compare(hw, + result, + 1, 2); + if (is23simular) { + final_candidate = 1; + } else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + } + if (final_candidate != 0xff) { + reg_e94 = result[final_candidate][0]; + rtlphy->reg_e94 = reg_e94; + reg_e9c = result[final_candidate][1]; + rtlphy->reg_e9c = reg_e9c; + reg_ea4 = result[final_candidate][2]; + reg_eb4 = result[final_candidate][4]; + rtlphy->reg_eb4 = reg_eb4; + reg_ebc = result[final_candidate][5]; + rtlphy->reg_ebc = reg_ebc; + reg_ec4 = result[final_candidate][6]; + b_patha_ok = true; + b_pathb_ok = true; + } else { + rtlphy->reg_e94 = 0x100; + rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = 0x0; + rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) + rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (reg_eb4 != 0) + _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result, + final_candidate, + (reg_ec4 == 0)); + + idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel); + + if (final_candidate < 4) { + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix[idx].value[0][i] = + result[final_candidate][i]; + rtlphy->iqk_matrix[idx].iqk_done = true; + + } + rtl8723_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); + + rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); + /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */ + +label_done: + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = false; + spin_unlock(&rtlpriv->locks.iqk_lock); +} + +void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); + + _rtl8723be_phy_lc_calibrate(hw, false); + + rtlphy->lck_inprogress = false; +} + +void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + _rtl8723be_phy_set_rfpath_switch(hw, bmain, true); +} + +bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool b_postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + b_postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + b_postprocessing = true; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", iotype); + break; + } + } while (false); + if (b_postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl8723be_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl8723be_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + /*rtl92c_dm_write_dig(hw);*/ + rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = 0x17; + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + +static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 initializecount = 0; + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl8723be_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + + break; + + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + /* Don't check BEACON Q. + * BEACON Q is always not empty, + * because '_rtl8723be_cmd_send_packet' + */ + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + ppsc->last_sleep_jiffies = jiffies; + _rtl8723be_phy_set_rf_sleep(hw); + break; + + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h new file mode 100644 index 000000000..a59813ea7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_PHY_H__ +#define __RTL8723BE_PHY_H__ + +/* MAX_TX_COUNT must always set to 4, otherwise read efuse table sequence + * will be wrong. + */ +#define MAX_TX_COUNT 4 +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define MAX_POWER_INDEX 0x3F + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define TARGET_CHNL_NUM_2G_5G 59 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define index_mapping_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 1 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ant_div_type { + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, + +}; + +u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw); +void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, + u8 channel); +void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, + bool b_recovery); +void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c new file mode 100644 index 000000000..95adac666 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../pwrseqcmd.h" +#include "pwrseq.h" + + +/* drivers should parse below arrays and do the corresponding actions */ +/*3 Power on Array*/ +struct wlan_pwr_cfg rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_CARDEMU_TO_ACT + RTL8723B_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8723B_radio_off_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_ACT_TO_CARDEMU + RTL8723B_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8723B_card_disable_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_ACT_TO_CARDEMU + RTL8723B_TRANS_CARDEMU_TO_CARDDIS + RTL8723B_TRANS_END +}; + +/*3 Card Enable Array*/ +struct wlan_pwr_cfg rtl8723B_card_enable_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_CARDDIS_TO_CARDEMU + RTL8723B_TRANS_CARDEMU_TO_ACT + RTL8723B_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8723B_suspend_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_ACT_TO_CARDEMU + RTL8723B_TRANS_CARDEMU_TO_SUS + RTL8723B_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8723B_resume_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_SUS_TO_CARDEMU + RTL8723B_TRANS_CARDEMU_TO_ACT + RTL8723B_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8723B_hwpdn_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS] = { + RTL8723B_TRANS_ACT_TO_CARDEMU + RTL8723B_TRANS_CARDEMU_TO_PDN + RTL8723B_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8723B_enter_lps_flow[RTL8723B_TRANS_ACT_TO_LPS_STEPS + + RTL8723B_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8723B_TRANS_ACT_TO_LPS + RTL8723B_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8723B_leave_lps_flow[RTL8723B_TRANS_LPS_TO_ACT_STEPS + + RTL8723B_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8723B_TRANS_LPS_TO_ACT + RTL8723B_TRANS_END +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h new file mode 100644 index 000000000..57eac4864 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_PWRSEQ_H__ +#define __RTL8723BE_PWRSEQ_H__ + +#include "../pwrseqcmd.h" +/** + * Check document WM-20130425-JackieLau-RTL8723B_Power_Architecture v05.vsd + * There are 6 HW Power States: + * 0: POFF--Power Off + * 1: PDN--Power Down + * 2: CARDEMU--Card Emulation + * 3: ACT--Active Mode + * 4: LPS--Low Power State + * 5: SUS--Suspend + * + * The transision from different states are defined below + * TRANS_CARDEMU_TO_ACT + * TRANS_ACT_TO_CARDEMU + * TRANS_CARDEMU_TO_SUS + * TRANS_SUS_TO_CARDEMU + * TRANS_CARDEMU_TO_PDN + * TRANS_ACT_TO_LPS + * TRANS_LPS_TO_ACT + * + * TRANS_END + */ +#define RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS 23 +#define RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8723B_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8723B_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8723B_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8723B_TRANS_END_STEPS 1 + +#define RTL8723B_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* comments here */ \ + /* {offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value}, */\ + /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ + /*Delay 1ms*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS}, \ + /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, \ + /* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[11]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)|BIT(2)), 0}, \ + /* Disable USB suspend */ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , BIT(0)}, \ + /* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /* Enable USB suspend */ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , 0}, \ + /* release WLON reset 0x04[16]=1*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ + /* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \ + /* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, \ + /* Enable WL control XTAL setting*/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)}, \ + /*Enable falling edge triggering interrupt*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*Enable GPIO9 interrupt mode*/ \ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*Enable GPIO9 input mode*/ \ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ + /*Enable HSISR GPIO[C:0] interrupt*/ \ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*Enable HSISR GPIO9 interrupt*/ \ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*For GPIO9 internal pull high setting by test chip*/ \ + {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3), BIT(3)}, \ + /*For GPIO9 internal pull high setting*/ \ + {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)}, + +#define RTL8723B_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*0x1F[7:0] = 0 turn off RF*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \ + /*0x4C[24] = 0x4F[0] = 0, */ \ + /*switch DPDT_SEL_P output from register 0x65[2] */ \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ + /*Enable rising edge triggering interrupt*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ + /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, \ + /* Enable BT control XTAL setting*/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), 0}, \ + /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(5), BIT(5)}, \ + /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(0), 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4) | BIT(3), (BIT(4) | BIT(3))}, \ + /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, \ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \ + /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},\ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8723B_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*clear suspend enable and power down enable*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \ + /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \ + /*0x04[10] = 1, enable SW LPS*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \ + /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1}, \ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*clear suspend enable and power down enable*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \ + /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ + /*wait power state to suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ + /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ + /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ + /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ + /*PCIe DMA start*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \ + /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK | PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, \ + PWR_CMD_WRITE, 0xFF, 0x20}, \ + /* 0x04[16] = 0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ + /* 0x04[15] = 1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, + +#define RTL8723B_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /* 0x04[15] = 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, + +#define RTL8723B_TRANS_ACT_TO_LPS \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*PCIe DMA stop*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /*Tx Pause*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ + /*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ + /*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ + /*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \ + /*Whole BB is reset*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ + /*Reset MAC TRX*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03}, \ + /*check if removed later*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ + /*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00}, \ + /*Respond TxOK to scheduler*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, + +#define RTL8723B_TRANS_LPS_TO_ACT \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + /*SDIO RPWM*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*USB RPWM*/ \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*PCIe RPWM*/ \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ + /*Delay*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \ + /*. 0x08[4] = 0 switch TSF to 40M*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ + /*Polling 0x109[7]=0 TSF in 40M*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \ + /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \ + /*. 0x101[1] = 1*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ + /*. 0x100[7:0] = 0xFF enable WMAC TRX*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ + /*. 0x02[1:0] = 2b'11 enable BB macro*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1) | BIT(0), BIT(1) | BIT(0)}, \ + /*. 0x522 = 0*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, + +#define RTL8723B_TRANS_END \ + /* format */ \ + /* comments here */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, \ + PWR_CMD_END, 0, 0}, + +extern struct wlan_pwr_cfg rtl8723B_power_on_flow + [RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_radio_off_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_card_disable_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_card_enable_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_suspend_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_resume_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_hwpdn_flow + [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_enter_lps_flow + [RTL8723B_TRANS_ACT_TO_LPS_STEPS + + RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_leave_lps_flow + [RTL8723B_TRANS_LPS_TO_ACT_STEPS + + RTL8723B_TRANS_END_STEPS]; + +/* RTL8723 Power Configuration CMDs for PCIe interface */ +#define RTL8723_NIC_PWR_ON_FLOW rtl8723B_power_on_flow +#define RTL8723_NIC_RF_OFF_FLOW rtl8723B_radio_off_flow +#define RTL8723_NIC_DISABLE_FLOW rtl8723B_card_disable_flow +#define RTL8723_NIC_ENABLE_FLOW rtl8723B_card_enable_flow +#define RTL8723_NIC_SUSPEND_FLOW rtl8723B_suspend_flow +#define RTL8723_NIC_RESUME_FLOW rtl8723B_resume_flow +#define RTL8723_NIC_PDN_FLOW rtl8723B_hwpdn_flow +#define RTL8723_NIC_LPS_ENTER_FLOW rtl8723B_enter_lps_flow +#define RTL8723_NIC_LPS_LEAVE_FLOW rtl8723B_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h new file mode 100644 index 000000000..28fd22b2a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h @@ -0,0 +1,2273 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_REG_H__ +#define __RTL8723BE_REG_H__ + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +/* 1.5v for 8188EE test chip, 1.4v for MP chip */ +#define REG_AFE_LDO_CTRL 0x0027 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 +#define REG_GPIO_IO_SEL_2 0x0062 +#define REG_MULTI_FUNC_CTRL 0x0068 +#define REG_GPIO_OUTPUT 0x006c +#define REG_AFE_XTAL_CTRL_EXT 0x0078 +#define REG_XCK_OUT_CTRL 0x007c +#define REG_MCUFWDL 0x0080 +#define REG_WOL_EVENT 0x0081 +#define REG_MCUTSTCFG 0x0084 + +#define REG_HIMR 0x00B0 +#define REG_HISR 0x00B4 +#define REG_HIMRE 0x00B8 +#define REG_HISRE 0x00BC +#define REG_PMC_DBG_CTRL2 0x00CC + +#define REG_EFUSE_ACCESS 0x00CF + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 +#define REG_MAC_PHY_CTRL_NORMAL 0x00F8 +#define REG_SYS_CFG1 0x00FC +#define REG_ROM_VERSION 0x00FD + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C + +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 +#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL + 2) + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_32K_CTRL 0x0194 +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 +/* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */ +#define REG_FW_UPD_RDPTR 0x0284 +/* Control the RX DMA.*/ +#define REG_RXDMA_CONTROL 0x0286 +/* The number of packets in RXPKTBUF. */ +#define REG_RXPKT_NUM 0x0287 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 + +#define REG_DBI_WDATA 0x0348 +#define REG_DBI_RDATA 0x034C +#define REG_DBI_CTRL 0x0350 +#define REG_DBI_ADDR 0x0350 +#define REG_DBI_FLAG 0x0352 +#define REG_MDIO_WDATA 0x0354 +#define REG_MDIO_RDATA 0x0356 +#define REG_MDIO_CTL 0x0358 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_WATCH_DOG 0x0368 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 +#define REG_TXPKT_EMPTY 0x041A + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x044C +#define REG_AMPDU_MAX_TIME 0x0456 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_HT_SINGLE_AMPDU 0x04C7 + +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_EARLY_MODE_CONTROL 0x04D0 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_SECONDARY_CCA_CTRL 0x0577 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_NAV_UPPER 0x0652 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_NUM 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN | CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL + 1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL + 2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL + 3) + +/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */ +#define HSIMR_GPIO12_0_INT_EN BIT(0) +#define HSIMR_SPS_OCP_INT_EN BIT(5) +#define HSIMR_RON_INT_EN BIT(6) +#define HSIMR_PDN_INT_EN BIT(7) +#define HSIMR_GPIO9_INT_EN BIT(25) + +/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */ +#define HSISR_GPIO12_0_INT BIT(0) +#define HSISR_SPS_OCP_INT BIT(5) +#define HSISR_RON_INT_EN BIT(6) +#define HSISR_PDNINT BIT(7) +#define HSISR_GPIO9_INT BIT(25) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +/********************************************* +* 8723BE IMR/ISR bits +********************************************* +*/ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +#define IMR_TXCCK BIT(30) /* TXRPT interrupt when + * CCX bit of the packet is set + */ +#define IMR_PSTIMEOUT BIT(29) /* Power Save Time Out Interrupt */ +#define IMR_GTINT4 BIT(28) /* When GTIMER4 expires, + * this bit is set to 1 + */ +#define IMR_GTINT3 BIT(27) /* When GTIMER3 expires, + * this bit is set to 1 + */ +#define IMR_TBDER BIT(26) /* Transmit Beacon0 Error */ +#define IMR_TBDOK BIT(25) /* Transmit Beacon0 OK */ +#define IMR_TSF_BIT32_TOGGLE BIT(24) /* TSF Timer BIT32 toggle + * indication interrupt + */ +#define IMR_BCNDMAINT0 BIT(20) /* Beacon DMA Interrupt 0 */ +#define IMR_BCNDOK0 BIT(16) /* Beacon Queue DMA OK0 */ +#define IMR_HSISR_IND_ON_INT BIT(15) /* HSISR Indicator (HSIMR & HSISR is + * true, this bit is set to 1) + */ +#define IMR_BCNDMAINT_E BIT(14) /* Beacon DMA Interrupt + * Extension for Win7 + */ +#define IMR_ATIMEND BIT(12) /* CTWidnow End or ATIM Window End */ +#define IMR_HISR1_IND_INT BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is + * true, this bit is set to 1) + */ +#define IMR_C2HCMD BIT(10) /* CPU to Host Command INT Status, + * Write 1 clear + */ +#define IMR_CPWM2 BIT(9) /* CPU power Mode exchange INT Status, + * Write 1 clear + */ +#define IMR_CPWM BIT(8) /* CPU power Mode exchange INT Status, + * Write 1 clear + */ +#define IMR_HIGHDOK BIT(7) /* High Queue DMA OK */ +#define IMR_MGNTDOK BIT(6) /* Management Queue DMA OK */ +#define IMR_BKDOK BIT(5) /* AC_BK DMA OK */ +#define IMR_BEDOK BIT(4) /* AC_BE DMA OK */ +#define IMR_VIDOK BIT(3) /* AC_VI DMA OK */ +#define IMR_VODOK BIT(2) /* AC_VO DMA OK */ +#define IMR_RDU BIT(1) /* Rx Descriptor Unavailable */ +#define IMR_ROK BIT(0) /* Receive DMA OK */ + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +#define IMR_BCNDMAINT7 BIT(27) /* Beacon DMA Interrupt 7 */ +#define IMR_BCNDMAINT6 BIT(26) /* Beacon DMA Interrupt 6 */ +#define IMR_BCNDMAINT5 BIT(25) /* Beacon DMA Interrupt 5 */ +#define IMR_BCNDMAINT4 BIT(24) /* Beacon DMA Interrupt 4 */ +#define IMR_BCNDMAINT3 BIT(23) /* Beacon DMA Interrupt 3 */ +#define IMR_BCNDMAINT2 BIT(22) /* Beacon DMA Interrupt 2 */ +#define IMR_BCNDMAINT1 BIT(21) /* Beacon DMA Interrupt 1 */ +#define IMR_BCNDOK7 BIT(20) /* Beacon Queue DMA OK Interrup 7 */ +#define IMR_BCNDOK6 BIT(19) /* Beacon Queue DMA OK Interrup 6 */ +#define IMR_BCNDOK5 BIT(18) /* Beacon Queue DMA OK Interrup 5 */ +#define IMR_BCNDOK4 BIT(17) /* Beacon Queue DMA OK Interrup 4 */ +#define IMR_BCNDOK3 BIT(16) /* Beacon Queue DMA OK Interrup 3 */ +#define IMR_BCNDOK2 BIT(15) /* Beacon Queue DMA OK Interrup 2 */ +#define IMR_BCNDOK1 BIT(14) /* Beacon Queue DMA OK Interrup 1 */ +#define IMR_ATIMEND_E BIT(13) /* ATIM Window End Extension for Win7 */ +#define IMR_TXERR BIT(11) /* Tx Error Flag Interrupt Status, + * write 1 clear. + */ +#define IMR_RXERR BIT(10) /* Rx Error Flag INT Status, + * Write 1 clear + */ +#define IMR_TXFOVW BIT(9) /* Transmit FIFO Overflow */ +#define IMR_RXFOVW BIT(8) /* Receive FIFO Overflow */ + +#define HWSET_MAX_SIZE 512 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 256 +#define EFUSE_OOB_PROTECT_BYTES 18 /* PG data exclude header, + * dummy 7 bytes frome CP test + * and reserved 1byte. + */ + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x18 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define EEPROM_RF_BT_SETTING_8723B 0xC3 + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL8723BE_EEPROM_ID 0x8129 + +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_TXPOWERCCK 0x10 +#define EEPROM_TXPOWERHT40_1S 0x16 +#define EEPROM_TXPOWERHT20DIFF 0x1B +#define EEPROM_TXPOWER_OFDMDIFF 0x1B + +#define EEPROM_TX_PWR_INX 0x10 + +#define EEPROM_CHANNELPLAN 0xB8 +#define EEPROM_XTAL_8723BE 0xB9 +#define EEPROM_THERMAL_METER_88E 0xBA +#define EEPROM_IQK_LCK_88E 0xBB + +#define EEPROM_RF_BOARD_OPTION_88E 0xC1 +#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 +#define EEPROM_RF_BT_SETTING_88E 0xC3 +#define EEPROM_VERSION 0xC4 +#define EEPROM_CUSTOMER_ID 0xC5 +#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 + +#define EEPROM_MAC_ADDR 0xD0 +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 175/*255 88e*/ + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define REG_SC_CNT 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 +#define RCCK0_CCA_CNT 0xa60 + +/* PageB(0xB00) */ +#define RPDP_ANTA 0xb00 +#define RPDP_ANTA_4 0xb04 +#define RPDP_ANTA_8 0xb08 +#define RPDP_ANTA_C 0xb0c +#define RPDP_ANTA_10 0xb10 +#define RPDP_ANTA_14 0xb14 +#define RPDP_ANTA_18 0xb18 +#define RPDP_ANTA_1C 0xb1c +#define RPDP_ANTA_20 0xb20 +#define RPDP_ANTA_24 0xb24 + +#define RCONFIG_PMPD_ANTA 0xb28 +#define RCONFIG_ram64x16 0xb2c + +#define RBNDA 0xb30 +#define RHSSIPAR 0xb34 + +#define RCONFIG_ANTA 0xb68 +#define RCONFIG_ANTB 0xb6c + +#define RPDP_ANTB 0xb70 +#define RPDP_ANTB_4 0xb74 +#define RPDP_ANTB_8 0xb78 +#define RPDP_ANTB_C 0xb7c +#define RPDP_ANTB_10 0xb80 +#define RPDP_ANTB_14 0xb84 +#define RPDP_ANTB_18 0xb88 +#define RPDP_ANTB_1C 0xb8c +#define RPDP_ANTB_20 0xb90 +#define RPDP_ANTB_24 0xb94 + +#define RCONFIG_PMPD_ANTB 0xb98 + +#define RBNDB 0xba0 + +#define RAPK 0xbd8 +#define RPM_RX0_ANTA 0xbdc +#define RPM_RX1_ANTA 0xbe0 +#define RPM_RX2_ANTA 0xbe4 +#define RPM_RX3_ANTA 0xbe8 +#define RPM_RX0_ANTB 0xbec +#define RPM_RX1_ANTB 0xbf0 +#define RPM_RX2_ANTB 0xbf4 +#define RPM_RX3_ANTB 0xbf8 + +/*Page C*/ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +#define RFPGA0_IQK 0xe28 +#define RTX_IQK_TONE_A 0xe30 +#define RRX_IQK_TONE_A 0xe34 +#define RTX_IQK_PI_A 0xe38 +#define RRX_IQK_PI_A 0xe3c + +#define RTX_IQK 0xe40 +#define RRX_IQK 0xe44 +#define RIQK_AGC_PTS 0xe48 +#define RIQK_AGC_RSP 0xe4c +#define RTX_IQK_TONE_B 0xe50 +#define RRX_IQK_TONE_B 0xe54 +#define RTX_IQK_PI_B 0xe58 +#define RRX_IQK_PI_B 0xe5c +#define RIQK_AGC_CONT 0xe60 + +#define RBLUE_TOOTH 0xe6c +#define RRX_WAIT_CCA 0xe70 +#define RTX_CCK_RFON 0xe74 +#define RTX_CCK_BBON 0xe78 +#define RTX_OFDM_RFON 0xe7c +#define RTX_OFDM_BBON 0xe80 +#define RTX_TO_RX 0xe84 +#define RTX_TO_TX 0xe88 +#define RRX_CCK 0xe8c + +#define RTX_POWER_BEFORE_IQK_A 0xe94 +#define RTX_POWER_AFTER_IQK_A 0xe9c + +#define RRX_POWER_BEFORE_IQK_A 0xea0 +#define RRX_POWER_BEFORE_IQK_A_2 0xea4 +#define RRX_POWER_AFTER_IQK_A 0xea8 +#define RRX_POWER_AFTER_IQK_A_2 0xeac + +#define RTX_POWER_BEFORE_IQK_B 0xeb4 +#define RTX_POWER_AFTER_IQK_B 0xebc + +#define RRX_POWER_BEFORE_IQK_B 0xec0 +#define RRX_POWER_BEFORE_IQK_B_2 0xec4 +#define RRX_POWER_AFTER_IQK_B 0xec8 +#define RRX_POWER_AFTER_IQK_B_2 0xecc + +#define RRX_OFDM 0xed0 +#define RRX_WAIT_RIFS 0xed4 +#define RRX_TO_RX 0xed8 +#define RSTANDBY 0xedc +#define RSLEEP 0xee0 +#define RPMPD_ANAEN 0xeec + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) \ + ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCKRXRFSETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#define REG_UN_used_register 0x01bf + +/* WOL bit information */ +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0) +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1) +#define HAL92C_WOL_DISASSOC_EVENT BIT(2) +#define HAL92C_WOL_DEAUTH_EVENT BIT(3) +#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_FW_DISCONNECT BIT(4) + +/* 2 EFUSE_TEST (For RTL8723 partially) */ +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 + +#define WL_HWPDN_EN BIT(0) /* Enable GPIO[9] as WiFi HW PDn source*/ +#define WL_HWPDN_SL BIT(1) /* WiFi HW PDn polarity control*/ + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c new file mode 100644 index 000000000..8a856fb42 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c @@ -0,0 +1,489 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10) | BIT(11)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | BIT(10)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + u8 direction; + u32 pwrtrac_value; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *)(&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + if (direction == 1) { + tx_agc[0] += pwrtrac_value; + tx_agc[1] += pwrtrac_value; + } else if (direction == 2) { + tx_agc[0] -= pwrtrac_value; + tx_agc[1] -= pwrtrac_value; + } + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + + /*tmpval = tmpval & 0xff00ffff;*/ + + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11); + + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl8723be_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, + u8 channel, u32 *ofdmbase, + u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 powerbase0, powerbase1; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerbase0 = ppowerlevel_ofdm[i]; + + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + powerlevel[i] = ppowerlevel_bw20[i]; + else + powerlevel[i] = ppowerlevel_bw40[i]; + + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) | + (powerbase1 << 8) | powerbase1; + + *(mcsbase + i) = powerbase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); + } +} + +static void _rtl8723be_get_txpower_writeval_by_regulatory( + struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4], pwr_diff = 0, customer_pwr_diff; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) { + chnlgroup = 0; + } else { + if (channel < 3) + chnlgroup = 0; + else if (channel < 6) + chnlgroup = 1; + else if (channel < 9) + chnlgroup = 2; + else if (channel < 12) + chnlgroup = 3; + else if (channel < 14) + chnlgroup = 4; + else if (channel == 14) + chnlgroup = 5; + } + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + + break; + case 2: + writeval = + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40 + [rf][channel - 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20 + [rf][channel - 1]); + } + + if (index < 2) + pwr_diff = + rtlefuse->txpwr_legacyhtdiff[rf][channel-1]; + else if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + pwr_diff = + rtlefuse->txpwr_ht20diff[rf][channel-1]; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) + customer_pwr_diff = + rtlefuse->pwrgroup_ht40[rf][channel-1]; + else + customer_pwr_diff = + rtlefuse->pwrgroup_ht20[rf][channel-1]; + + if (pwr_diff > customer_pwr_diff) + pwr_diff = 0; + else + pwr_diff = customer_pwr_diff - pwr_diff; + + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] & + (0x7f << (i * 8))) >> (i * 8)); + + if (pwr_diff_limit[i] > pwr_diff) + pwr_diff_limit[i] = pwr_diff; + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | + (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit); + + writeval = customer_limit + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + default: + chnlgroup = 0; + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeval = writeval - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl8723be_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = pvalue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + } +} + +void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + u8 direction; + u32 pwrtrac_value; + + rtl8723be_phy_get_power_base(hw, ppowerlevel_ofdm, ppowerlevel_bw20, + ppowerlevel_bw40, channel, + &powerbase0[0], &powerbase1[0]); + + rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + + for (index = 0; index < 6; index++) { + _rtl8723be_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + if (direction == 1) { + writeval[0] += pwrtrac_value; + writeval[1] += pwrtrac_value; + } else if (direction == 2) { + writeval[0] -= pwrtrac_value; + writeval[1] -= pwrtrac_value; + } + _rtl8723be_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl8723be_phy_rf6052_config_parafile(hw); + +} + +static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + pphyreg = &rtlphy->phyreg_def[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h new file mode 100644 index 000000000..81537a1a4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_RF_H__ +#define __RTL8723BE_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, + u8 channel); +bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c new file mode 100644 index 000000000..5967df08e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "hw.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "trx.h" +#include "led.h" +#include "table.h" +#include "../btcoexist/rtl_btc.h" + +#include +#include + +static void rtl8723be_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /* ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +static int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + char *fw_name = "rtlwifi/rtl8723befw_36.bin"; + + rtl8723be_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25); + + rtlpriv->phy.lck_inprogress = false; + + mac->ht_enable = true; + + /* compatible 5G band 88ce just 2.4G band & smsp */ + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + rtlpriv->rtlhal.bandset = BAND_ON_2_4G; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | + RCR_ADF | + RCR_AICV | + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = (u32) (IMR_PSTIMEOUT | + IMR_HSISR_IND_ON_INT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + + rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0); + + rtlpci->sys_irq_mask = (u32)(HSIMR_PDN_INT_EN | + HSIMR_RON_INT_EN | + 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 2; + rtlpriv->psc.reg_max_lps_awakeintvl = 2; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl8723be_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /*low power: Disable 32k */ + rtlpriv->psc.low_power_enable = false; + + rtlpriv->rtlhal.earlymode_enable = false; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw.\n"); + return 1; + } + + rtlpriv->max_fw_size = 0x8000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + return 0; +} + +static void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +static bool rtl8723be_get_btc_status(void) +{ + return true; +} + +static bool is_fw_header(struct rtlwifi_firmware_header *hdr) +{ + return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x5300; +} + +static const struct rtl_hal_ops rtl8723be_hal_ops = { + .init_sw_vars = rtl8723be_init_sw_vars, + .deinit_sw_vars = rtl8723be_deinit_sw_vars, + .read_eeprom_info = rtl8723be_read_eeprom_info, + .interrupt_recognized = rtl8723be_interrupt_recognized, + .hw_init = rtl8723be_hw_init, + .hw_disable = rtl8723be_card_disable, + .hw_suspend = rtl8723be_suspend, + .hw_resume = rtl8723be_resume, + .enable_interrupt = rtl8723be_enable_interrupt, + .disable_interrupt = rtl8723be_disable_interrupt, + .set_network_type = rtl8723be_set_network_type, + .set_chk_bssid = rtl8723be_set_check_bssid, + .set_qos = rtl8723be_set_qos, + .set_bcn_reg = rtl8723be_set_beacon_related_registers, + .set_bcn_intv = rtl8723be_set_beacon_interval, + .update_interrupt_mask = rtl8723be_update_interrupt_mask, + .get_hw_reg = rtl8723be_get_hw_reg, + .set_hw_reg = rtl8723be_set_hw_reg, + .update_rate_tbl = rtl8723be_update_hal_rate_tbl, + .fill_tx_desc = rtl8723be_tx_fill_desc, + .fill_tx_cmddesc = rtl8723be_tx_fill_cmddesc, + .query_rx_desc = rtl8723be_rx_query_desc, + .set_channel_access = rtl8723be_update_channel_access_setting, + .radio_onoff_checking = rtl8723be_gpio_radio_on_off_checking, + .set_bw_mode = rtl8723be_phy_set_bw_mode, + .switch_channel = rtl8723be_phy_sw_chnl, + .dm_watchdog = rtl8723be_dm_watchdog, + .scan_operation_backup = rtl8723be_phy_scan_operation_backup, + .set_rf_power_state = rtl8723be_phy_set_rf_power_state, + .led_control = rtl8723be_led_control, + .set_desc = rtl8723be_set_desc, + .get_desc = rtl8723be_get_desc, + .is_tx_desc_closed = rtl8723be_is_tx_desc_closed, + .tx_polling = rtl8723be_tx_polling, + .enable_hw_sec = rtl8723be_enable_hw_security_config, + .set_key = rtl8723be_set_key, + .get_bbreg = rtl8723_phy_query_bb_reg, + .set_bbreg = rtl8723_phy_set_bb_reg, + .get_rfreg = rtl8723be_phy_query_rf_reg, + .set_rfreg = rtl8723be_phy_set_rf_reg, + .fill_h2c_cmd = rtl8723be_fill_h2c_cmd, + .get_btc_status = rtl8723be_get_btc_status, + .is_fw_header = is_fw_header, +}; + +static struct rtl_mod_params rtl8723be_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .msi_support = false, + .aspm_support = 1, + .disable_watchdog = false, + .debug_level = 0, + .debug_mask = 0, + .ant_sel = 0, +}; + +static const struct rtl_hal_cfg rtl8723be_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723be_pci", + .alt_fw_name = "rtlwifi/rtl8723befw.bin", + .ops = &rtl8723be_hal_ops, + .mod_params = &rtl8723be_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + .maps[MAC_HSISR] = REG_HSISR, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, +/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/ + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, +/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/ +/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/ + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IMR_HSISR_IND] = IMR_HSISR_IND_ON_INT, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static const struct pci_device_id rtl8723be_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB723, rtl8723be_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8723be_pci_ids); + +MODULE_AUTHOR("PageHe "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8723befw_36.bin"); + +module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl8723be_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8723be_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444); +module_param_named(aspm, rtl8723be_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog, + bool, 0444); +module_param_named(ant_sel, rtl8723be_mod_params.ant_sel, int, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, + "Set to 1 to disable the watchdog (default 0)\n"); +MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8723be_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8723be_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8723be_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c new file mode 100644 index 000000000..5864be89d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c @@ -0,0 +1,597 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include +#include "table.h" + +u32 RTL8723BEPHY_REG_1TARRAY[] = { + 0x800, 0x80040000, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x02200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00190204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569A11A9, + 0x85C, 0x01000014, + 0x860, 0x66F60110, + 0x864, 0x061F0649, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x07000760, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x00000000, + 0x880, 0xB0000C1C, + 0x884, 0x00000001, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000002, + 0x914, 0x00000201, + 0xA00, 0x00D047C8, + 0xA04, 0x80FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7F120F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x21806490, + 0xB2C, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x08800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC44, + 0xC34, 0x469652AF, + 0xC38, 0x49795994, + 0xC3C, 0x0A97971C, + 0xC40, 0x1F7C403F, + 0xC44, 0x000100B7, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00013147, + 0xC5C, 0x00250492, + 0xC60, 0x00000000, + 0xC64, 0x7112848B, + 0xC68, 0x47C00BFF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020610DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0xC84, 0x21F60000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00020E1A, + 0xC94, 0x00000000, + 0xC98, 0x00020E1A, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00000000, + 0xCA4, 0x000300A0, + 0xCA8, 0x00000000, + 0xCAC, 0x00000000, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x64B22427, + 0xCDC, 0x00766932, + 0xCE0, 0x00222222, + 0xCE4, 0x00000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00000740, + 0xD04, 0x40020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC53, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCC979975, + 0xD30, 0x00000000, + 0xD34, 0x80608000, + 0xD38, 0x00000000, + 0xD3C, 0x00127353, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x6437140A, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xD6C, 0x2A201C16, + 0xD70, 0x1812362E, + 0xD74, 0x322C2220, + 0xD78, 0x000E3C24, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE68, 0x001B2556, + 0xE6C, 0x00C00096, + 0xE70, 0x00C00096, + 0xE74, 0x01000056, + 0xE78, 0x01000014, + 0xE7C, 0x01000056, + 0xE80, 0x01000014, + 0xE84, 0x00C00096, + 0xE88, 0x01000056, + 0xE8C, 0x00C00096, + 0xED0, 0x00C00096, + 0xED4, 0x00C00096, + 0xED8, 0x00C00096, + 0xEDC, 0x000000D6, + 0xEE0, 0x000000D6, + 0xEEC, 0x01C00016, + 0xF14, 0x00000003, + 0xF4C, 0x00000000, + 0xF00, 0x00000300, + 0x820, 0x01000100, + 0x800, 0x83040000, + +}; + +u32 RTL8723BEPHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8723BEPHY_REG_1TARRAY); + +u32 RTL8723BEPHY_REG_ARRAY_PG[] = { + 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003800, + 0, 0, 0, 0x0000086c, 0xffffff00, 0x32343600, + 0, 0, 0, 0x00000e00, 0xffffffff, 0x40424444, + 0, 0, 0, 0x00000e04, 0xffffffff, 0x28323638, + 0, 0, 0, 0x00000e10, 0xffffffff, 0x38404244, + 0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436 +}; + +u32 RTL8723BEPHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8723BEPHY_REG_ARRAY_PG); + +u32 RTL8723BE_RADIOA_1TARRAY[] = { + 0x000, 0x00010000, + 0x0B0, 0x000DFFE0, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0B1, 0x00000018, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0B2, 0x00084C00, + 0x0B5, 0x0000D2CC, + 0x0B6, 0x000925AA, + 0x0B7, 0x00000010, + 0x0B8, 0x0000907F, + 0x05C, 0x00000002, + 0x07C, 0x00000002, + 0x07E, 0x00000005, + 0x08B, 0x0006FC00, + 0x0B0, 0x000FF9F0, + 0x01C, 0x000739D2, + 0x01E, 0x00000000, + 0x0DF, 0x00000780, + 0x050, 0x00067435, + 0x80002000, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x0006F10E, + 0x052, 0x000007D3, + 0x90003000, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x0006F10E, + 0x052, 0x000007D3, + 0x90004000, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x0006F10E, + 0x052, 0x000007D3, + 0xA0000000, 0x00000000, + 0x051, 0x0006B04E, + 0x052, 0x000007D2, + 0xB0000000, 0x00000000, + 0x053, 0x00000000, + 0x054, 0x00050400, + 0x055, 0x0004026E, + 0x0DD, 0x0000004C, + 0x070, 0x00067435, + 0x80002000, 0x00000000, 0x40000000, 0x00000000, + 0x071, 0x0006F10E, + 0x072, 0x000007D3, + 0x90003000, 0x00000000, 0x40000000, 0x00000000, + 0x071, 0x0006F10E, + 0x072, 0x000007D3, + 0x90004000, 0x00000000, 0x40000000, 0x00000000, + 0x071, 0x0006F10E, + 0x072, 0x000007D3, + 0xA0000000, 0x00000000, + 0x071, 0x0006B04E, + 0x072, 0x000007D2, + 0xB0000000, 0x00000000, + 0x073, 0x00000000, + 0x074, 0x00050400, + 0x075, 0x0004026E, + 0x0EF, 0x00000100, + 0x034, 0x0000ADD7, + 0x035, 0x00005C00, + 0x034, 0x00009DD4, + 0x035, 0x00005000, + 0x034, 0x00008DD1, + 0x035, 0x00004400, + 0x034, 0x00007DCE, + 0x035, 0x00003800, + 0x034, 0x00006CD1, + 0x035, 0x00004400, + 0x034, 0x00005CCE, + 0x035, 0x00003800, + 0x034, 0x000048CE, + 0x035, 0x00004400, + 0x034, 0x000034CE, + 0x035, 0x00003800, + 0x034, 0x00002451, + 0x035, 0x00004400, + 0x034, 0x0000144E, + 0x035, 0x00003800, + 0x034, 0x00000051, + 0x035, 0x00004400, + 0x0EF, 0x00000000, + 0x0EF, 0x00000100, + 0x0ED, 0x00000010, + 0x044, 0x0000ADD7, + 0x044, 0x00009DD4, + 0x044, 0x00008DD1, + 0x044, 0x00007DCE, + 0x044, 0x00006CC1, + 0x044, 0x00005CCE, + 0x044, 0x000044D1, + 0x044, 0x000034CE, + 0x044, 0x00002451, + 0x044, 0x0000144E, + 0x044, 0x00000051, + 0x0EF, 0x00000000, + 0x0ED, 0x00000000, + 0x07F, 0x00020080, + 0x0EF, 0x00002000, + 0x03B, 0x000380EF, + 0x03B, 0x000302FE, + 0x03B, 0x00028CE6, + 0x03B, 0x000200BC, + 0x03B, 0x000188A5, + 0x03B, 0x00010FBC, + 0x03B, 0x00008F71, + 0x03B, 0x00000900, + 0x0EF, 0x00000000, + 0x0ED, 0x00000001, + 0x040, 0x000380EF, + 0x040, 0x000302FE, + 0x040, 0x00028CE6, + 0x040, 0x000200BC, + 0x040, 0x000188A5, + 0x040, 0x00010FBC, + 0x040, 0x00008F71, + 0x040, 0x00000900, + 0x0ED, 0x00000000, + 0x082, 0x00080000, + 0x083, 0x00008000, + 0x084, 0x00048D80, + 0x085, 0x00068000, + 0x0A2, 0x00080000, + 0x0A3, 0x00008000, + 0x0A4, 0x00048D80, + 0x0A5, 0x00068000, + 0x0ED, 0x00000002, + 0x0EF, 0x00000002, + 0x056, 0x00000032, + 0x076, 0x00000032, + 0x001, 0x00000780, + +}; + +u32 RTL8723BE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8723BE_RADIOA_1TARRAY); + +u32 RTL8723BEMAC_1T_ARRAY[] = { + 0x02F, 0x00000030, + 0x035, 0x00000000, + 0x039, 0x00000008, + 0x064, 0x00000000, + 0x067, 0x00000020, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x765, 0x00000018, + 0x76E, 0x00000004, + +}; + +u32 RTL8723BEMAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8723BEMAC_1T_ARRAY); + +u32 RTL8723BEAGCTAB_1TARRAY[] = { + 0xC78, 0xFD000001, + 0xC78, 0xFC010001, + 0xC78, 0xFB020001, + 0xC78, 0xFA030001, + 0xC78, 0xF9040001, + 0xC78, 0xF8050001, + 0xC78, 0xF7060001, + 0xC78, 0xF6070001, + 0xC78, 0xF5080001, + 0xC78, 0xF4090001, + 0xC78, 0xF30A0001, + 0xC78, 0xF20B0001, + 0xC78, 0xF10C0001, + 0xC78, 0xF00D0001, + 0xC78, 0xEF0E0001, + 0xC78, 0xEE0F0001, + 0xC78, 0xED100001, + 0xC78, 0xEC110001, + 0xC78, 0xEB120001, + 0xC78, 0xEA130001, + 0xC78, 0xE9140001, + 0xC78, 0xE8150001, + 0xC78, 0xE7160001, + 0xC78, 0xE6170001, + 0xC78, 0xE5180001, + 0xC78, 0xE4190001, + 0xC78, 0xE31A0001, + 0xC78, 0xA51B0001, + 0xC78, 0xA41C0001, + 0xC78, 0xA31D0001, + 0xC78, 0x671E0001, + 0xC78, 0x661F0001, + 0xC78, 0x65200001, + 0xC78, 0x64210001, + 0xC78, 0x63220001, + 0xC78, 0x4A230001, + 0xC78, 0x49240001, + 0xC78, 0x48250001, + 0xC78, 0x47260001, + 0xC78, 0x46270001, + 0xC78, 0x45280001, + 0xC78, 0x44290001, + 0xC78, 0x432A0001, + 0xC78, 0x422B0001, + 0xC78, 0x292C0001, + 0xC78, 0x282D0001, + 0xC78, 0x272E0001, + 0xC78, 0x262F0001, + 0xC78, 0x0A300001, + 0xC78, 0x09310001, + 0xC78, 0x08320001, + 0xC78, 0x07330001, + 0xC78, 0x06340001, + 0xC78, 0x05350001, + 0xC78, 0x04360001, + 0xC78, 0x03370001, + 0xC78, 0x02380001, + 0xC78, 0x01390001, + 0xC78, 0x013A0001, + 0xC78, 0x013B0001, + 0xC78, 0x013C0001, + 0xC78, 0x013D0001, + 0xC78, 0x013E0001, + 0xC78, 0x013F0001, + 0xC78, 0xFC400001, + 0xC78, 0xFB410001, + 0xC78, 0xFA420001, + 0xC78, 0xF9430001, + 0xC78, 0xF8440001, + 0xC78, 0xF7450001, + 0xC78, 0xF6460001, + 0xC78, 0xF5470001, + 0xC78, 0xF4480001, + 0xC78, 0xF3490001, + 0xC78, 0xF24A0001, + 0xC78, 0xF14B0001, + 0xC78, 0xF04C0001, + 0xC78, 0xEF4D0001, + 0xC78, 0xEE4E0001, + 0xC78, 0xED4F0001, + 0xC78, 0xEC500001, + 0xC78, 0xEB510001, + 0xC78, 0xEA520001, + 0xC78, 0xE9530001, + 0xC78, 0xE8540001, + 0xC78, 0xE7550001, + 0xC78, 0xE6560001, + 0xC78, 0xE5570001, + 0xC78, 0xE4580001, + 0xC78, 0xE3590001, + 0xC78, 0xA65A0001, + 0xC78, 0xA55B0001, + 0xC78, 0xA45C0001, + 0xC78, 0xA35D0001, + 0xC78, 0x675E0001, + 0xC78, 0x665F0001, + 0xC78, 0x65600001, + 0xC78, 0x64610001, + 0xC78, 0x63620001, + 0xC78, 0x62630001, + 0xC78, 0x61640001, + 0xC78, 0x48650001, + 0xC78, 0x47660001, + 0xC78, 0x46670001, + 0xC78, 0x45680001, + 0xC78, 0x44690001, + 0xC78, 0x436A0001, + 0xC78, 0x426B0001, + 0xC78, 0x286C0001, + 0xC78, 0x276D0001, + 0xC78, 0x266E0001, + 0xC78, 0x256F0001, + 0xC78, 0x24700001, + 0xC78, 0x09710001, + 0xC78, 0x08720001, + 0xC78, 0x07730001, + 0xC78, 0x06740001, + 0xC78, 0x05750001, + 0xC78, 0x04760001, + 0xC78, 0x03770001, + 0xC78, 0x02780001, + 0xC78, 0x01790001, + 0xC78, 0x017A0001, + 0xC78, 0x017B0001, + 0xC78, 0x017C0001, + 0xC78, 0x017D0001, + 0xC78, 0x017E0001, + 0xC78, 0x017F0001, + 0xC50, 0x69553422, + 0xC50, 0x69553420, + 0x824, 0x00390204, + +}; + +u32 RTL8723BEAGCTAB_1TARRAYLEN = ARRAY_SIZE(RTL8723BEAGCTAB_1TARRAY); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h new file mode 100644 index 000000000..cf0c8d58c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_TABLE__H_ +#define __RTL8723BE_TABLE__H_ + +#include +extern u32 RTL8723BEPHY_REG_1TARRAYLEN; +extern u32 RTL8723BEPHY_REG_1TARRAY[]; +extern u32 RTL8723BEPHY_REG_ARRAY_PGLEN; +extern u32 RTL8723BEPHY_REG_ARRAY_PG[]; +extern u32 RTL8723BE_RADIOA_1TARRAYLEN; +extern u32 RTL8723BE_RADIOA_1TARRAY[]; +extern u32 RTL8723BEMAC_1T_ARRAYLEN; +extern u32 RTL8723BEMAC_1T_ARRAY[]; +extern u32 RTL8723BEAGCTAB_1TARRAYLEN; +extern u32 RTL8723BEAGCTAB_1TARRAY[]; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c new file mode 100644 index 000000000..8b6352f7f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c @@ -0,0 +1,743 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" +#include "dm.h" +#include "fw.h" + +static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstatus, + __le32 *pdesc, + struct rx_fwinfo_8723be *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo; + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all, pwdb_all_bt = 0; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstatus->is_cck; + u8 lan_idx, vga_idx; + + /* Record it for next packet processing */ + pstatus->packet_matchbssid = bpacket_match_bssid; + pstatus->packet_toself = bpacket_toself; + pstatus->packet_beacon = packet_beacon; + pstatus->rx_mimo_signalquality[0] = -1; + pstatus->rx_mimo_signalquality[1] = -1; + + if (is_cck) { + u8 cck_agc_rpt; + + cck_agc_rpt = p_phystrpt->cck_agc_rpt_ofdm_cfosho_a; + + /* (1)Hardware does not provide RSSI for CCK */ + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BIT(9)); + + lan_idx = ((cck_agc_rpt & 0xE0) >> 5); + vga_idx = (cck_agc_rpt & 0x1f); + + switch (lan_idx) { + /* 46 53 73 95 201301231630 */ + /* 46 53 77 99 201301241630 */ + case 6: + rx_pwr_all = -34 - (2 * vga_idx); + break; + case 4: + rx_pwr_all = -14 - (2 * vga_idx); + break; + case 1: + rx_pwr_all = 6 - (2 * vga_idx); + break; + case 0: + rx_pwr_all = 16 - (2 * vga_idx); + break; + default: + break; + } + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + if (pwdb_all > 100) + pwdb_all = 100; + + pstatus->rx_pwdb_all = pwdb_all; + pstatus->bt_rx_rssi_percentage = pwdb_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (bpacket_match_bssid) { + u8 sq, sq_rpt; + if (pstatus->rx_pwdb_all > 40) { + sq = 100; + } else { + sq_rpt = p_phystrpt->cck_sig_qual_ofdm_pwdb_all; + if (sq_rpt > 64) + sq = 0; + else if (sq_rpt < 20) + sq = 100; + else + sq = ((64 - sq_rpt) * 100) / 44; + } + pstatus->signalquality = sq; + pstatus->rx_mimo_signalquality[0] = sq; + pstatus->rx_mimo_signalquality[1] = -1; + } + } else { + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((p_phystrpt->path_agc[i].gain & 0x3f) * 2) + - 110; + + pstatus->rx_pwr[i] = rx_pwr[i]; + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + + pstatus->rx_mimo_signalstrength[i] = (u8)rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_phystrpt->cck_sig_qual_ofdm_pwdb_all >> 1) & + 0x7f) - 110; + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pwdb_all_bt = pwdb_all; + pstatus->rx_pwdb_all = pwdb_all; + pstatus->bt_rx_rssi_percentage = pwdb_all_bt; + pstatus->rxpower = rx_pwr_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if (pstatus->rate >= DESC92C_RATEMCS8 && + pstatus->rate <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage( + p_phystrpt->stream_rxevm[i]); + + if (bpacket_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream only + */ + if (i == 0) + pstatus->signalquality = + (u8)(evm & 0xff); + pstatus->rx_mimo_signalquality[i] = + (u8)(evm & 0xff); + } + } + + if (bpacket_match_bssid) { + for (i = RF90_PATH_A; i <= RF90_PATH_B; i++) + rtl_priv(hw)->dm.cfo_tail[i] = + (int)p_phystrpt->path_cfotail[i]; + + if (rtl_priv(hw)->dm.packet_count == 0xffffffff) + rtl_priv(hw)->dm.packet_count = 0; + else + rtl_priv(hw)->dm.packet_count++; + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, + __le32 *pdesc, + struct rx_fwinfo_8723be *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + u16 fc, type; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_control); + type = WLAN_FC_GET_TYPE(hdr->frame_control); + praddr = hdr->addr1; + psaddr = ieee80211_get_SA(hdr); + memcpy(pstatus->psaddr, psaddr, ETH_ALEN); + + packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && + (ether_addr_equal(mac->bssid, (fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && + (!pstatus->hwerror) && + (!pstatus->crc) && (!pstatus->icv)); + + packet_toself = packet_matchbssid && + (ether_addr_equal(praddr, rtlefuse->dev_addr)); + + /* YP: packet_beacon is not initialized, + * this assignment is neccesary, + * otherwise it counld be true in this case + * the situation is much worse in Kernel 3.10 + */ + if (ieee80211_is_beacon(hdr->frame_control)) + packet_beacon = true; + else + packet_beacon = false; + + if (packet_beacon && packet_matchbssid) + rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + + _rtl8723be_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, + packet_matchbssid, + packet_toself, + packet_beacon); + + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + __le32 *virtualaddress) +{ + u32 dwtmp = 0; + memset(virtualaddress, 0, 8); + + set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[1]; + } + set_earlymode_len0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[3]; + } + set_earlymode_len1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[5]; + } + set_earlymode_len2_1(virtualaddress, dwtmp & 0xF); + set_earlymode_len2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[7]; + } + set_earlymode_len3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[9]; + } + set_earlymode_len4(virtualaddress, dwtmp); +} + +bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rx_fwinfo_8723be *p_drvinfo; + struct ieee80211_hdr *hdr; + u8 wake_match; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_physt(pdesc); + + status->length = (u16)get_rx_desc_pkt_len(pdesc); + status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + status->icv = (u16)get_rx_desc_icv(pdesc); + status->crc = (u16)get_rx_desc_crc32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !get_rx_desc_swdec(pdesc); + status->rate = (u8)get_rx_desc_rxmcs(pdesc); + status->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->isfirst_ampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->timestamp_low = get_rx_desc_tsfl(pdesc); + status->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc); + status->bandwidth = (u8)get_rx_desc_bw(pdesc); + status->macid = get_rx_desc_macid(pdesc); + status->is_ht = (bool)get_rx_desc_rxht(pdesc); + + status->is_cck = RX_HAL_IS_CCK_RATE(status->rate); + + if (get_rx_status_desc_rpt_sel(pdesc)) + status->packet_report_type = C2H_PACKET; + else + status->packet_report_type = NORMAL_RX; + + + if (get_rx_status_desc_pattern_match(pdesc)) + wake_match = BIT(2); + else if (get_rx_status_desc_magic_match(pdesc)) + wake_match = BIT(1); + else if (get_rx_status_desc_unicast_match(pdesc)) + wake_match = BIT(0); + else + wake_match = 0; + if (wake_match) + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->rx_is40mhzpacket) + rx_status->bw = RATE_INFO_BW_40; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, + false, status->rate); + + rx_status->mactime = status->timestamp_low; + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_8723be *)(skb->data + + status->rx_bufshift); + + _rtl8723be_translate_rx_signal_stuff(hw, skb, status, + pdesc, p_drvinfo); + } + rx_status->signal = status->recvsignalpower + 10; + if (status->packet_report_type == TX_REPORT2) { + status->macid_valid_entry[0] = + get_rx_rpt2_desc_macid_valid_1(pdesc); + status->macid_valid_entry[1] = + get_rx_rpt2_desc_macid_valid_2(pdesc); + } + return true; +} + +void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, + u8 *txbd, struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtlwifi_tx_info *tx_info = rtl_tx_skb_cb_info(skb); + __le32 *pdesc = (__le32 *)pdesc8; + u16 seq_number; + __le16 fc = hdr->frame_control; + unsigned int buf_len = 0; + unsigned int skb_len = skb->len; + u8 fw_qsel = _rtl8723be_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 bw_40 = 0; + u8 short_gi = 0; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->deflink.ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + buf_len = skb->len; + mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_8723be)); + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + set_tx_desc_pkt_offset(pdesc, 1); + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN + + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + _rtl8723be_insert_emcontent(ptcb_desc, + (__le32 *)(skb->data)); + } + } else { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + } + + + /* ptcb_desc->use_driver_rate = true; */ + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + if (ptcb_desc->hw_rate > DESC92C_RATEMCS0) + short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; + else + short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + + set_tx_desc_data_shortgi(pdesc, short_gi); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x14); + } + set_tx_desc_seq(pdesc, seq_number); + set_tx_desc_rts_enable(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? + 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, 0); + set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ? + 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + set_tx_desc_rts_short(pdesc, + ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (ptcb_desc->tx_enable_sw_calc_duration) + set_tx_desc_nav_use_hdr(pdesc, 1); + + if (bw_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + set_tx_desc_data_bw(pdesc, 1); + set_tx_desc_tx_sub_carrier(pdesc, 3); + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, mac->cur_40_prime_sc); + } + } else { + set_tx_desc_data_bw(pdesc, 0); + set_tx_desc_tx_sub_carrier(pdesc, 0); + } + + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb_len); + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + } + } + + set_tx_desc_queue_sel(pdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ? + 1 : 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + /* tx report */ + rtl_set_tx_report(ptcb_desc, pdesc8, hw, tx_info); + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + set_tx_desc_tx_buffer_size(pdesc, (u16)buf_len); + set_tx_desc_tx_buffer_address(pdesc, mapping); + /* if (rtlpriv->dm.useramask) { */ + if (1) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } + if (!ieee80211_is_data_qos(fc)) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_hwseq_sel(pdesc, 0); + } + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + __le32 *pdesc = (__le32 *)pdesc8; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_tx_rate(pdesc, DESC92C_RATE1M); + + set_tx_desc_seq(pdesc, 0); + + set_tx_desc_linip(pdesc, 0); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len)); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_rate_id(pdesc, 0); + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_use_rate(pdesc, 1); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); +} + +void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, + bool istx, u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, "rtl8723be: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, "rtl8723be: ERR rxdesc :%d not process\n", + desc_name); + break; + } + } +} + +u64 rtl8723be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc8, bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(pdesc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(pdesc); + break; + default: + WARN_ONCE(true, "rtl8723be: ERR txdesc :%d not process\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(pdesc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(pdesc); + break; + default: + WARN_ONCE(true, "rtl8723be: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl8723be_get_desc(hw, entry, true, HW_DESC_OWN); + + /*beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h new file mode 100644 index 000000000..da027f915 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h @@ -0,0 +1,646 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __RTL8723BE_TRX_H__ +#define __RTL8723BE_TRX_H__ + +#define TX_DESC_SIZE 40 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 40 +#define CRCLENGTH 4 + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(20, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 1), __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(12)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(13)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_hwseq_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(7, 6)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(13)); +} + +static inline void set_tx_desc_nav_use_hdr(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, BIT(15)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 3), __val, GENMASK(21, 17)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 4), __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(3, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(4)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(6, 5)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, BIT(12)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 8), __val, BIT(15)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits((__pdesc + 9), __val, GENMASK(23, 12)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 10))); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 12) = cpu_to_le32(__val); +} + +static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(13, 0)); +} + +static inline u32 get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(14)); +} + +static inline u32 get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(15)); +} + +static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(19, 16)); +} + +static inline u32 get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, GENMASK(25, 24)); +} + +static inline u32 get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(26)); +} + +static inline u32 get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(27)); +} + +static inline u32 get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*__pdesc, BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline u32 get_rx_desc_macid(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(6, 0)); +} + +static inline u32 get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline u32 get_rx_status_desc_rpt_sel(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 2), BIT(28)); +} + +static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(6, 0)); +} + +static inline u32 get_rx_desc_rxht(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(6)); +} + +static inline u32 get_rx_status_desc_pattern_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(29)); +} + +static inline u32 get_rx_status_desc_unicast_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(30)); +} + +static inline u32 get_rx_status_desc_magic_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(31)); +} + +static inline u32 get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 4), BIT(0)); +} + +static inline u32 get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 4), GENMASK(5, 4)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 5))); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*((__pdesc + 6))); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +/* TX report 2 format in Rx desc*/ + +static inline u32 get_rx_rpt2_desc_macid_valid_1(__le32 *__rxstatusdesc) +{ + return le32_to_cpu(*((__rxstatusdesc + 4))); +} + +static inline u32 get_rx_rpt2_desc_macid_valid_2(__le32 *__rxstatusdesc) +{ + return le32_to_cpu(*((__rxstatusdesc + 5))); +} + +static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(3, 0)); +} + +static inline void set_earlymode_len0(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(15, 4)); +} + +static inline void set_earlymode_len1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(27, 16)); +} + +static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(31, 28)); +} + +static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(7, 0)); +} + +static inline void set_earlymode_len3(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8)); +} + +static inline void set_earlymode_len4(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20)); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size) +{ + if (_size > TX_DESC_NEXT_DESC_OFFSET) + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); + else + memset(__pdesc, 0, _size); +} + +struct phy_rx_agc_info_t { + #ifdef __LITTLE_ENDIAN + u8 gain:7, trsw:1; + #else + u8 trsw:1, gain:7; + #endif +}; +struct phy_status_rpt { + struct phy_rx_agc_info_t path_agc[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 rsvd_1;/* ch_corr_msb; */ + u8 noise_power_db_msb; + s8 path_cfotail[2]; + u8 pcts_mask[2]; + s8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 rsvd_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + u8 sig_evm; + u8 rsvd_3; +#ifdef __LITTLE_ENDIAN + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ + u8 sgi_en:1; + u8 rxsc:2; + u8 idle_long:1; + u8 r_ant_train_en:1; + u8 ant_sel_b:1; + u8 ant_sel:1; +#else /* _BIG_ENDIAN_ */ + u8 ant_sel:1; + u8 ant_sel_b:1; + u8 r_ant_train_en:1; + u8 idle_long:1; + u8 rxsc:2; + u8 sgi_en:1; + u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ +#endif +} __packed; + +struct rx_fwinfo_8723be { + u8 gain_trsw[2]; + u16 chl_num:10; + u16 sub_chnl:4; + u16 r_rfmod:2; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[2]; + u8 pcts_msk_rpt[2]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 rx_gain_c; + u8 rx_gain_d; + u8 sigevm; + u8 resvd_0; + u8 antidx_anta:3; + u8 antidx_antb:3; + u8 resvd_1:2; +} __packed; + +struct tx_desc_8723be { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:6; + u32 rsvd0:2; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rdg_en:1; + u32 bar_retryht:2; + u32 agg_break:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 bt_int:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_ssn:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 pwr_status:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 sw_offset30:8; + u32 sw_offset31:4; + u32 rsvd1:1; + u32 antsel_c:1; + u32 null_0:1; + u32 null_1:1; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_8723be { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:6; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + u8 *pdesc_tx, u8 *txbd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, + bool istx, u8 desc_name, u8 *val); +u64 rtl8723be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile new file mode 100644 index 000000000..3451198b6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8723-common-objs := \ + main.o \ + dm_common.o \ + fw_common.o \ + phy_common.o + +obj-$(CONFIG_RTL8723_COMMON) += rtl8723-common.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c new file mode 100644 index 000000000..46ab90332 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "dm_common.h" +#include "../rtl8723ae/dm.h" +#include + +/* These routines are common to RTL8723AE and RTL8723bE */ + +void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_txpower); + +void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_edca_turbo); + +void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ps_t *dm_pstable = &rtlpriv->dm_pstable; + + dm_pstable->pre_ccastate = CCA_MAX; + dm_pstable->cur_ccasate = CCA_MAX; + dm_pstable->pre_rfstate = RF_MAX; + dm_pstable->cur_rfstate = RF_MAX; + dm_pstable->rssi_val_min = 0; + dm_pstable->initialize = 0; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_bb_powersaving); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h new file mode 100644 index 000000000..6300be65a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __DM_COMMON_H__ +#define __DM_COMMON_H__ + +void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw); +void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c new file mode 100644 index 000000000..50b79cf8f --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../efuse.h" +#include "fw_common.h" +#include + +void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } +} +EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download); + +void rtl8723_write_fw(struct ieee80211_hw *hw, + enum version_8723e version, + u8 *buffer, u32 size, u8 max_page) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *bufferptr = buffer; + u32 page_nums, remain_size; + u32 page, offset; + + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); + + rtl_fill_dummy(bufferptr, &size); + + page_nums = size / FW_8192C_PAGE_SIZE; + remain_size = size % FW_8192C_PAGE_SIZE; + + if (page_nums > max_page) { + pr_err("Page numbers should not greater than %d\n", + max_page); + } + for (page = 0; page < page_nums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remain_size) { + offset = page_nums * FW_8192C_PAGE_SIZE; + page = page_nums; + rtl_fw_page_write(hw, page, (bufferptr + offset), remain_size); + } + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); +} +EXPORT_SYMBOL_GPL(rtl8723_write_fw); + +void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + u8 delay = 100; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) + break; + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } + if (delay == 0) { + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + u1b_tmp&(~BIT(2))); + } +} +EXPORT_SYMBOL_GPL(rtl8723ae_firmware_selfreset); + +void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + udelay(50); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2))); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "_8051Reset8723be(): 8051 reset success .\n"); +} +EXPORT_SYMBOL_GPL(rtl8723be_firmware_selfreset); + +int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be, + int max_count) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < max_count) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= max_count) { + pr_err("chksum report fail ! REG_MCUFWDL:0x%08x .\n", + value32); + goto exit; + } + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + if (is_8723be) + rtl8723be_firmware_selfreset(hw); + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) { + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n", + value32); + err = 0; + goto exit; + } + + mdelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < max_count); + + pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", + value32); + +exit: + return err; +} +EXPORT_SYMBOL_GPL(rtl8723_fw_free_to_go); + +int rtl8723_download_fw(struct ieee80211_hw *hw, + bool is_8723be, int max_count) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtlwifi_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8723e version = rtlhal->version; + int max_page; + + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) + return 1; + + pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware; + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = rtlhal->pfirmware; + fwsize = rtlhal->fwsize; + + if (!is_8723be) + max_page = 6; + else + max_page = 8; + if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) { + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "Firmware Version(%d), Signature(%#x), Size(%d)\n", + pfwheader->version, pfwheader->signature, + (int)sizeof(struct rtlwifi_firmware_header)); + + pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); + fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); + } + + if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) { + if (is_8723be) + rtl8723be_firmware_selfreset(hw); + else + rtl8723ae_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + } + rtl8723_enable_fw_download(hw, true); + rtl8723_write_fw(hw, version, pfwdata, fwsize, max_page); + rtl8723_enable_fw_download(hw, false); + + err = rtl8723_fw_free_to_go(hw, is_8723be, max_count); + if (err) + pr_err("Firmware is not ready to run!\n"); + return 0; +} +EXPORT_SYMBOL_GPL(rtl8723_download_fw); + diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h new file mode 100644 index 000000000..c8e04f972 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __FW_COMMON_H__ +#define __FW_COMMON_H__ + +#define REG_SYS_FUNC_EN 0x0002 +#define REG_MCUFWDL 0x0080 +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8723A_POLLING_TIMEOUT_COUNT 1000 +#define FW_8723B_POLLING_TIMEOUT_COUNT 6000 +#define FW_8192C_POLLING_DELAY 5 + +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define WINTINI_RDY BIT(6) + +#define REG_RSV_CTRL 0x001C +#define REG_HMETFR 0x01CC + +enum version_8723e { + VERSION_TEST_UMC_CHIP_8723 = 0x0081, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, + VERSION_TEST_CHIP_1T1R_8723B = 0x0106, + VERSION_NORMAL_SMIC_CHIP_1T1R_8723B = 0x010E, + VERSION_UNKNOWN = 0xFF, +}; + +enum rtl8723be_cmd { + H2C_8723BE_RSVDPAGE = 0, + H2C_8723BE_JOINBSSRPT = 1, + H2C_8723BE_SCAN = 2, + H2C_8723BE_KEEP_ALIVE_CTRL = 3, + H2C_8723BE_DISCONNECT_DECISION = 4, + H2C_8723BE_INIT_OFFLOAD = 6, + H2C_8723BE_AP_OFFLOAD = 8, + H2C_8723BE_BCN_RSVDPAGE = 9, + H2C_8723BE_PROBERSP_RSVDPAGE = 10, + + H2C_8723BE_SETPWRMODE = 0x20, + H2C_8723BE_PS_TUNING_PARA = 0x21, + H2C_8723BE_PS_TUNING_PARA2 = 0x22, + H2C_8723BE_PS_LPS_PARA = 0x23, + H2C_8723BE_P2P_PS_OFFLOAD = 0x24, + + H2C_8723BE_WO_WLAN = 0x80, + H2C_8723BE_REMOTE_WAKE_CTRL = 0x81, + H2C_8723BE_AOAC_GLOBAL_INFO = 0x82, + H2C_8723BE_AOAC_RSVDPAGE = 0x83, + H2C_8723BE_RSSI_REPORT = 0x42, + H2C_8723BE_RA_MASK = 0x40, + H2C_8723BE_SELECTIVE_SUSPEND_ROF_CMD, + H2C_8723BE_P2P_PS_MODE, + H2C_8723BE_PSD_RESULT, + /*Not defined CTW CMD for P2P yet*/ + H2C_8723BE_P2P_PS_CTW_CMD, + MAX_8723BE_H2CCMD +}; + +void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable); +void rtl8723_write_fw(struct ieee80211_hw *hw, + enum version_8723e version, + u8 *buffer, u32 size, u8 max_page); +int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be, int count); +int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be, int count); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c new file mode 100644 index 000000000..f5a9ecbf7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include + + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek RTL8723AE/RTL8723BE 802.11n PCI wireless common routines"); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c new file mode 100644 index 000000000..d97c88ebc --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#include "../wifi.h" +#include "phy_common.h" +#include "../rtl8723ae/reg.h" +#include + +/* These routines are common to RTL8723AE and RTL8723bE */ + +u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, + regaddr, originalvalue); + return returnvalue; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg); + +void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask, + data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg); + +u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0xff; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + pr_err("return all one\n"); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + udelay(120); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + BLSSIREADBACKDATA); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); + return retvalue; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read); + +void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 offset, u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + pr_err("stop\n"); + return; + } + offset &= 0xff; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, + data_and_addr); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write); + +long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm); + +void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; + +} +EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def); + +bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, + u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, + u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + WARN_ONCE(true, "rtl8723-common: cmdtable cannot be NULL.\n"); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray); + +void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, + long result[][8], + u8 final_candidate, + bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix); + +void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg, + u32 *addabackup, u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} +EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers); + +void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers); + +void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers); + +void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers); + +void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, + bool is_patha_on, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 pathon; + u32 i; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { + pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (!is2t) { + pathon = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); + } + } else { + /* rtl8723be */ + pathon = 0x01c00014; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on); + +void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i = 0; + + rtl_write_byte(rtlpriv, macreg[i], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8) (macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration); + +void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby); + +void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h new file mode 100644 index 000000000..af85c3287 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2014 Realtek Corporation.*/ + +#ifndef __PHY_COMMON__ +#define __PHY_COMMON__ + +#define RT_CANNOT_IO(hw) false + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data); +u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 offset, u32 data); +long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); +bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, + u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, + u32 msdelay); +void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, + long result[][8], + u8 final_candidate, + bool btxonly); +void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg, + u32 *addabackup, u32 registernum); +void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup); +void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum); +void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup); +void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, + bool is_patha_on, bool is2t); +void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup); +void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw); +void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile new file mode 100644 index 000000000..81dbf4ca6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +rtl8821ae-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + pwrseq.o \ + rf.o \ + sw.o \ + table.o \ + trx.o \ + + +obj-$(CONFIG_RTL8821AE) += rtl8821ae.o diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h new file mode 100644 index 000000000..235a79656 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_DEF_H__ +#define __RTL8821AE_DEF_H__ + +/*--------------------------Define -------------------------------------------*/ +#define USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN 1 + +/* BIT 7 HT Rate*/ +/*TxHT = 0*/ +#define MGN_1M 0x02 +#define MGN_2M 0x04 +#define MGN_5_5M 0x0b +#define MGN_11M 0x16 + +#define MGN_6M 0x0c +#define MGN_9M 0x12 +#define MGN_12M 0x18 +#define MGN_18M 0x24 +#define MGN_24M 0x30 +#define MGN_36M 0x48 +#define MGN_48M 0x60 +#define MGN_54M 0x6c + +/* TxHT = 1 */ +#define MGN_MCS0 0x80 +#define MGN_MCS1 0x81 +#define MGN_MCS2 0x82 +#define MGN_MCS3 0x83 +#define MGN_MCS4 0x84 +#define MGN_MCS5 0x85 +#define MGN_MCS6 0x86 +#define MGN_MCS7 0x87 +#define MGN_MCS8 0x88 +#define MGN_MCS9 0x89 +#define MGN_MCS10 0x8a +#define MGN_MCS11 0x8b +#define MGN_MCS12 0x8c +#define MGN_MCS13 0x8d +#define MGN_MCS14 0x8e +#define MGN_MCS15 0x8f +/* VHT rate */ +#define MGN_VHT1SS_MCS0 0x90 +#define MGN_VHT1SS_MCS1 0x91 +#define MGN_VHT1SS_MCS2 0x92 +#define MGN_VHT1SS_MCS3 0x93 +#define MGN_VHT1SS_MCS4 0x94 +#define MGN_VHT1SS_MCS5 0x95 +#define MGN_VHT1SS_MCS6 0x96 +#define MGN_VHT1SS_MCS7 0x97 +#define MGN_VHT1SS_MCS8 0x98 +#define MGN_VHT1SS_MCS9 0x99 +#define MGN_VHT2SS_MCS0 0x9a +#define MGN_VHT2SS_MCS1 0x9b +#define MGN_VHT2SS_MCS2 0x9c +#define MGN_VHT2SS_MCS3 0x9d +#define MGN_VHT2SS_MCS4 0x9e +#define MGN_VHT2SS_MCS5 0x9f +#define MGN_VHT2SS_MCS6 0xa0 +#define MGN_VHT2SS_MCS7 0xa1 +#define MGN_VHT2SS_MCS8 0xa2 +#define MGN_VHT2SS_MCS9 0xa3 + +#define MGN_VHT3SS_MCS0 0xa4 +#define MGN_VHT3SS_MCS1 0xa5 +#define MGN_VHT3SS_MCS2 0xa6 +#define MGN_VHT3SS_MCS3 0xa7 +#define MGN_VHT3SS_MCS4 0xa8 +#define MGN_VHT3SS_MCS5 0xa9 +#define MGN_VHT3SS_MCS6 0xaa +#define MGN_VHT3SS_MCS7 0xab +#define MGN_VHT3SS_MCS8 0xac +#define MGN_VHT3SS_MCS9 0xad + +#define MGN_MCS0_SG 0xc0 +#define MGN_MCS1_SG 0xc1 +#define MGN_MCS2_SG 0xc2 +#define MGN_MCS3_SG 0xc3 +#define MGN_MCS4_SG 0xc4 +#define MGN_MCS5_SG 0xc5 +#define MGN_MCS6_SG 0xc6 +#define MGN_MCS7_SG 0xc7 +#define MGN_MCS8_SG 0xc8 +#define MGN_MCS9_SG 0xc9 +#define MGN_MCS10_SG 0xca +#define MGN_MCS11_SG 0xcb +#define MGN_MCS12_SG 0xcc +#define MGN_MCS13_SG 0xcd +#define MGN_MCS14_SG 0xce +#define MGN_MCS15_SG 0xcf + +#define MGN_UNKNOWN 0xff + +/* 30 ms */ +#define WIFI_NAV_UPPER_US 30000 +#define HAL_92C_NAV_UPPER_UNIT 128 + +#define MAX_RX_DMA_BUFFER_SIZE 0x3E80 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + +#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80 + +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) + +#define CHIP_8812 BIT(2) +#define CHIP_8821 (BIT(0)|BIT(2)) + +#define CHIP_8821A (BIT(0)|BIT(2)) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(12)|BIT(13))) +#define E_CUT_VERSION BIT(14) +#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) + +enum version_8821ae { + VERSION_TEST_CHIP_1T1R_8812 = 0x0004, + VERSION_TEST_CHIP_2T2R_8812 = 0x0024, + VERSION_NORMAL_TSMC_CHIP_1T1R_8812 = 0x100c, + VERSION_NORMAL_TSMC_CHIP_2T2R_8812 = 0x102c, + VERSION_NORMAL_TSMC_CHIP_1T1R_8812_C_CUT = 0x200c, + VERSION_NORMAL_TSMC_CHIP_2T2R_8812_C_CUT = 0x202c, + VERSION_TEST_CHIP_8821 = 0x0005, + VERSION_NORMAL_TSMC_CHIP_8821 = 0x000d, + VERSION_NORMAL_TSMC_CHIP_8821_B_CUT = 0x100d, + VERSION_UNKNOWN = 0xFF, +}; + +enum vht_data_sc { + VHT_DATA_SC_DONOT_CARE = 0, + VHT_DATA_SC_20_UPPER_OF_80MHZ = 1, + VHT_DATA_SC_20_LOWER_OF_80MHZ = 2, + VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3, + VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4, + VHT_DATA_SC_20_RECV1 = 5, + VHT_DATA_SC_20_RECV2 = 6, + VHT_DATA_SC_20_RECV3 = 7, + VHT_DATA_SC_20_RECV4 = 8, + VHT_DATA_SC_40_UPPER_OF_80MHZ = 9, + VHT_DATA_SC_40_LOWER_OF_80MHZ = 10, +}; + +/* MASK */ +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + +/* Get element */ +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? false : true) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\ + ? true : false) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\ + ? true : false) + +#define IS_8812_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8812) ? \ + true : false) +#define IS_8821_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8821) ? \ + true : false) + +#define IS_VENDOR_8812A_TEST_CHIP(version) ((IS_8812_SERIES(version)) ? \ + ((IS_NORMAL_CHIP(version)) ? \ + false : true) : false) +#define IS_VENDOR_8812A_MP_CHIP(version) ((IS_8812_SERIES(version)) ? \ + ((IS_NORMAL_CHIP(version)) ? \ + true : false) : false) +#define IS_VENDOR_8812A_C_CUT(version) ((IS_8812_SERIES(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + C_CUT_VERSION) ? \ + true : false) : false) + +#define IS_VENDOR_8821A_TEST_CHIP(version) ((IS_8821_SERIES(version)) ? \ + ((IS_NORMAL_CHIP(version)) ? \ + false : true) : false) +#define IS_VENDOR_8821A_MP_CHIP(version) ((IS_8821_SERIES(version)) ? \ + ((IS_NORMAL_CHIP(version)) ? \ + true : false) : false) +#define IS_VENDOR_8821A_B_CUT(version) ((IS_8821_SERIES(version)) ? \ + ((GET_CVID_CUT_VERSION(version) == \ + B_CUT_VERSION) ? \ + true : false) : false) +enum board_type { + ODM_BOARD_DEFAULT = 0, /* The DEFAULT case. */ + ODM_BOARD_MINICARD = BIT(0), /* 0 = non-mini card, 1 = mini card. */ + ODM_BOARD_SLIM = BIT(1), /* 0 = non-slim card, 1 = slim card */ + ODM_BOARD_BT = BIT(2), /* 0 = without BT card, 1 = with BT */ + ODM_BOARD_EXT_PA = BIT(3), /* 1 = existing 2G ext-PA */ + ODM_BOARD_EXT_LNA = BIT(4), /* 1 = existing 2G ext-LNA */ + ODM_BOARD_EXT_TRSW = BIT(5), /* 1 = existing ext-TRSW */ + ODM_BOARD_EXT_PA_5G = BIT(6), /* 1 = existing 5G ext-PA */ + ODM_BOARD_EXT_LNA_5G = BIT(7), /* 1 = existing 5G ext-LNA */ +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +struct phy_sts_cck_8821ae_t { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8821ae { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c new file mode 100644 index 000000000..f8b159c74 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c @@ -0,0 +1,2795 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../base.h" +#include "../pci.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "trx.h" +#include "../btcoexist/rtl_btc.h" + +static const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = { + 0x081, /* 0, -12.0dB */ + 0x088, /* 1, -11.5dB */ + 0x090, /* 2, -11.0dB */ + 0x099, /* 3, -10.5dB */ + 0x0A2, /* 4, -10.0dB */ + 0x0AC, /* 5, -9.5dB */ + 0x0B6, /* 6, -9.0dB */ + 0x0C0, /* 7, -8.5dB */ + 0x0CC, /* 8, -8.0dB */ + 0x0D8, /* 9, -7.5dB */ + 0x0E5, /* 10, -7.0dB */ + 0x0F2, /* 11, -6.5dB */ + 0x101, /* 12, -6.0dB */ + 0x110, /* 13, -5.5dB */ + 0x120, /* 14, -5.0dB */ + 0x131, /* 15, -4.5dB */ + 0x143, /* 16, -4.0dB */ + 0x156, /* 17, -3.5dB */ + 0x16A, /* 18, -3.0dB */ + 0x180, /* 19, -2.5dB */ + 0x197, /* 20, -2.0dB */ + 0x1AF, /* 21, -1.5dB */ + 0x1C8, /* 22, -1.0dB */ + 0x1E3, /* 23, -0.5dB */ + 0x200, /* 24, +0 dB */ + 0x21E, /* 25, +0.5dB */ + 0x23E, /* 26, +1.0dB */ + 0x261, /* 27, +1.5dB */ + 0x285, /* 28, +2.0dB */ + 0x2AB, /* 29, +2.5dB */ + 0x2D3, /* 30, +3.0dB */ + 0x2FE, /* 31, +3.5dB */ + 0x32B, /* 32, +4.0dB */ + 0x35C, /* 33, +4.5dB */ + 0x38E, /* 34, +5.0dB */ + 0x3C4, /* 35, +5.5dB */ + 0x3FE /* 36, +6.0dB */ +}; + +static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = { + 0x081, /* 0, -12.0dB */ + 0x088, /* 1, -11.5dB */ + 0x090, /* 2, -11.0dB */ + 0x099, /* 3, -10.5dB */ + 0x0A2, /* 4, -10.0dB */ + 0x0AC, /* 5, -9.5dB */ + 0x0B6, /* 6, -9.0dB */ + 0x0C0, /* 7, -8.5dB */ + 0x0CC, /* 8, -8.0dB */ + 0x0D8, /* 9, -7.5dB */ + 0x0E5, /* 10, -7.0dB */ + 0x0F2, /* 11, -6.5dB */ + 0x101, /* 12, -6.0dB */ + 0x110, /* 13, -5.5dB */ + 0x120, /* 14, -5.0dB */ + 0x131, /* 15, -4.5dB */ + 0x143, /* 16, -4.0dB */ + 0x156, /* 17, -3.5dB */ + 0x16A, /* 18, -3.0dB */ + 0x180, /* 19, -2.5dB */ + 0x197, /* 20, -2.0dB */ + 0x1AF, /* 21, -1.5dB */ + 0x1C8, /* 22, -1.0dB */ + 0x1E3, /* 23, -0.5dB */ + 0x200, /* 24, +0 dB */ + 0x21E, /* 25, +0.5dB */ + 0x23E, /* 26, +1.0dB */ + 0x261, /* 27, +1.5dB */ + 0x285, /* 28, +2.0dB */ + 0x2AB, /* 29, +2.5dB */ + 0x2D3, /* 30, +3.0dB */ + 0x2FE, /* 31, +3.5dB */ + 0x32B, /* 32, +4.0dB */ + 0x35C, /* 33, +4.5dB */ + 0x38E, /* 34, +5.0dB */ + 0x3C4, /* 35, +5.5dB */ + 0x3FE /* 36, +6.0dB */ +}; + +static const u32 edca_setting_dl[PEER_MAX] = { + 0xa44f, /* 0 UNKNOWN */ + 0x5ea44f, /* 1 REALTEK_90 */ + 0x5e4322, /* 2 REALTEK_92SE */ + 0x5ea42b, /* 3 BROAD */ + 0xa44f, /* 4 RAL */ + 0xa630, /* 5 ATH */ + 0x5ea630, /* 6 CISCO */ + 0x5ea42b, /* 7 MARVELL */ +}; + +static const u32 edca_setting_ul[PEER_MAX] = { + 0x5e4322, /* 0 UNKNOWN */ + 0xa44f, /* 1 REALTEK_90 */ + 0x5ea44f, /* 2 REALTEK_92SE */ + 0x5ea32b, /* 3 BROAD */ + 0x5ea422, /* 4 RAL */ + 0x5ea322, /* 5 ATH */ + 0x3ea430, /* 6 CISCO */ + 0x5ea44f, /* 7 MARV */ +}; + +static const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; + +static const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = { + 0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; + +static const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; + +static const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; + +static const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; + +static const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13}, + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18}, +}; + +static const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13}, + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, + 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, + 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18}, +}; + +static const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, + 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; + +static const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; + +static const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; + +static const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; + +static const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw, + u8 type, u8 *pdirection, + u32 *poutwrite_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 pwr_val = 0; + + if (type == 0) { + if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <= + rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) { + *pdirection = 1; + pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] - + rtldm->swing_idx_ofdm[RF90_PATH_A]; + } else { + *pdirection = 2; + pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] - + rtldm->swing_idx_ofdm_base[RF90_PATH_A]; + } + } else if (type == 1) { + if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) { + *pdirection = 1; + pwr_val = rtldm->swing_idx_cck_base - + rtldm->swing_idx_cck; + } else { + *pdirection = 2; + pwr_val = rtldm->swing_idx_cck - + rtldm->swing_idx_cck_base; + } + } + + if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) + pwr_val = TXPWRTRACK_MAX_IDX; + + *poutwrite_val = pwr_val | (pwr_val << 8)| + (pwr_val << 16)| + (pwr_val << 24); +} + +void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + u8 p = 0; + + rtldm->swing_idx_cck_base = rtldm->default_cck_index; + rtldm->swing_idx_cck = rtldm->default_cck_index; + rtldm->cck_index = 0; + + for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) { + rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index; + rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index; + rtldm->ofdm_index[p] = rtldm->default_ofdm_index; + + rtldm->power_index_offset[p] = 0; + rtldm->delta_power_index[p] = 0; + rtldm->delta_power_index_last[p] = 0; + /*Initial Mix mode power tracking*/ + rtldm->absolute_ofdm_swing_idx[p] = 0; + rtldm->remnant_ofdm_swing_idx[p] = 0; + } + /*Initial at Modify Tx Scaling Mode*/ + rtldm->modify_txagc_flag_path_a = false; + /*Initial at Modify Tx Scaling Mode*/ + rtldm->modify_txagc_flag_path_b = false; + rtldm->remnant_cck_idx = 0; + rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; + rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; + rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; +} + +static u8 rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 i = 0; + u32 bb_swing; + + bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype, + RF90_PATH_A); + + for (i = 0; i < TXSCALE_TABLE_SIZE; ++i) + if (bb_swing == rtl8821ae_txscaling_table[i]) + break; + + return i; +} + +void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + u8 default_swing_index = 0; + u8 p = 0; + + rtlpriv->dm.txpower_track_control = true; + rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; + rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; + rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; + default_swing_index = rtl8821ae_dm_get_swing_index(hw); + + rtldm->default_ofdm_index = + (default_swing_index == TXSCALE_TABLE_SIZE) ? + 24 : default_swing_index; + rtldm->default_cck_index = 24; + + rtldm->swing_idx_cck_base = rtldm->default_cck_index; + rtldm->cck_index = rtldm->default_cck_index; + + for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) { + rtldm->swing_idx_ofdm_base[p] = + rtldm->default_ofdm_index; + rtldm->ofdm_index[p] = rtldm->default_ofdm_index; + rtldm->delta_power_index[p] = 0; + rtldm->power_index_offset[p] = 0; + rtldm->delta_power_index_last[p] = 0; + } +} + +void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} + +void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &rtlpriv->ra; + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; + + p_ra->high_rssi_thresh_for_ra = 50; + p_ra->low_rssi_thresh_for_ra40m = 20; +} + +static void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; + + rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11)); + rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; +} + +static void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 tmp; + + rtlphy->cck_high_power = + (bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC, + ODM_BIT_CCK_RPT_FORMAT_11AC); + + tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, + ODM_BIT_BB_RX_PATH_11AC); + if (tmp & BIT(0)) + rtlpriv->dm.rfpath_rxenable[0] = true; + if (tmp & BIT(1)) + rtlpriv->dm.rfpath_rxenable[1] = true; +} + +void rtl8821ae_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = false; + spin_unlock(&rtlpriv->locks.iqk_lock); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl8821ae_dm_common_info_self_init(hw); + rtl_dm_diginit(hw, cur_igvalue); + rtl8821ae_dm_init_rate_adaptive_mask(hw); + rtl8821ae_dm_init_edca_turbo(hw); + rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw); + rtl8821ae_dm_init_dynamic_atc_switch(hw); +} + +static void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtlpriv); + + /* Determine the minimum RSSI */ + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + rtl_dm_dig->min_undec_pwdb_for_dm = 0; + pr_debug("rtl8821ae: Not connected to any AP\n"); + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.entry_min_undec_sm_pwdb); + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "STA Default Port PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + } else { + rtl_dm_dig->min_undec_pwdb_for_dm = + rtlpriv->dm.entry_min_undec_sm_pwdb; + rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + "AP Ext Port or disconnect PWDB = 0x%x\n", + rtl_dm_dig->min_undec_pwdb_for_dm); + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "MinUndecoratedPWDBForDM =%d\n", + rtl_dm_dig->min_undec_pwdb_for_dm); +} + +static void rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, RA_RSSI_DUMP, + rtlpriv->stats.rx_rssi_percentage[0]); + rtl_write_byte(rtlpriv, RB_RSSI_DUMP, + rtlpriv->stats.rx_rssi_percentage[1]); + + /* Rx EVM*/ + rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP, + rtlpriv->stats.rx_evm_dbm[0]); + rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP, + rtlpriv->stats.rx_evm_dbm[1]); + + /*Rx SNR*/ + rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP, + (u8)(rtlpriv->stats.rx_snr_db[0])); + rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP, + (u8)(rtlpriv->stats.rx_snr_db[1])); + + /*Rx Cfo_Short*/ + rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP, + rtlpriv->stats.rx_cfo_short[0]); + rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP, + rtlpriv->stats.rx_cfo_short[1]); + + /*Rx Cfo_Tail*/ + rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP, + rtlpriv->stats.rx_cfo_tail[0]); + rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP, + rtlpriv->stats.rx_cfo_tail[1]); +} + +static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *drv_priv; + u8 h2c_parameter[4] = { 0 }; + long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; + u8 stbc_tx = 0; + u64 cur_rxokcnt = 0; + static u64 last_txokcnt = 0, last_rxokcnt; + + cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt; + last_txokcnt = rtlpriv->stats.txbytesunicast; + last_rxokcnt = rtlpriv->stats.rxbytesunicast; + if (cur_rxokcnt > (last_txokcnt * 6)) + h2c_parameter[3] = 0x01; + else + h2c_parameter[3] = 0x00; + + /* AP & ADHOC & MESH */ + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { + if (drv_priv->rssi_stat.undec_sm_pwdb < + tmp_entry_min_pwdb) + tmp_entry_min_pwdb = + drv_priv->rssi_stat.undec_sm_pwdb; + if (drv_priv->rssi_stat.undec_sm_pwdb > + tmp_entry_max_pwdb) + tmp_entry_max_pwdb = + drv_priv->rssi_stat.undec_sm_pwdb; + } + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + /* If associated entry is found */ + if (tmp_entry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undec_sm_pwdb = + tmp_entry_max_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMaxPWDB = 0x%lx(%ld)\n", + tmp_entry_max_pwdb, tmp_entry_max_pwdb); + } else { + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + } + /* If associated entry is found */ + if (tmp_entry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undec_sm_pwdb = + tmp_entry_min_pwdb; + RTPRINT(rtlpriv, FDM, DM_PWDB, + "EntryMinPWDB = 0x%lx(%ld)\n", + tmp_entry_min_pwdb, tmp_entry_min_pwdb); + } else { + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + } + } + /* Indicate Rx signal strength to FW. */ + if (rtlpriv->dm.useramask) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + if (mac->mode == WIRELESS_MODE_AC_24G || + mac->mode == WIRELESS_MODE_AC_5G || + mac->mode == WIRELESS_MODE_AC_ONLY) + stbc_tx = (mac->vht_cur_stbc & + STBC_VHT_ENABLE_TX) ? 1 : 0; + else + stbc_tx = (mac->ht_cur_stbc & + STBC_HT_ENABLE_TX) ? 1 : 0; + h2c_parameter[3] |= stbc_tx << 1; + } + h2c_parameter[2] = + (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF); + h2c_parameter[1] = 0x20; + h2c_parameter[0] = 0; + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4, + h2c_parameter); + else + rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3, + h2c_parameter); + } else { + rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb); + } + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_dm_rssi_dump_to_register(hw); + rtl8821ae_dm_find_minimum_rssi(hw); + dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; +} + +void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (dm_digtable->cur_cck_cca_thres != current_cca) + rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca); + + dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; + dm_digtable->cur_cck_cca_thres = current_cca; +} + +void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + + if (dm_digtable->stop_dig) + return; + + if (dm_digtable->cur_igvalue != current_igi) { + rtl_set_bbreg(hw, DM_REG_IGI_A_11AC, + DM_BIT_IGI_11AC, current_igi); + if (rtlpriv->phy.rf_type != RF_1T1R) + rtl_set_bbreg(hw, DM_REG_IGI_B_11AC, + DM_BIT_IGI_11AC, current_igi); + } + dm_digtable->cur_igvalue = current_igi; +} + +static void rtl8821ae_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 dig_min_0; + u8 dig_max_of_min; + bool first_connect, first_disconnect; + u8 dm_dig_max, dm_dig_min, offset; + u8 current_igi = dm_digtable->cur_igvalue; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n"); + + if (mac->act_scanning) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Return: In Scan Progress\n"); + return; + } + + /*add by Neil Chen to avoid PSD is processing*/ + dig_min_0 = dm_digtable->dig_min_0; + first_connect = (mac->link_state >= MAC80211_LINKED) && + (!dm_digtable->media_connect_0); + first_disconnect = (mac->link_state < MAC80211_LINKED) && + (dm_digtable->media_connect_0); + + /*1 Boundary Decision*/ + + dm_dig_max = 0x5A; + + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) + dm_dig_min = DM_DIG_MIN; + else + dm_dig_min = 0x1C; + + dig_max_of_min = DM_DIG_MAX_AP; + + if (mac->link_state >= MAC80211_LINKED) { + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) + offset = 20; + else + offset = 10; + + if ((dm_digtable->rssi_val_min + offset) > dm_dig_max) + dm_digtable->rx_gain_max = dm_dig_max; + else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min) + dm_digtable->rx_gain_max = dm_dig_min; + else + dm_digtable->rx_gain_max = + dm_digtable->rssi_val_min + offset; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n", + dm_digtable->rssi_val_min, + dm_digtable->rx_gain_max); + if (rtlpriv->dm.one_entry_only) { + offset = 0; + + if (dm_digtable->rssi_val_min - offset < dm_dig_min) + dig_min_0 = dm_dig_min; + else if (dm_digtable->rssi_val_min - + offset > dig_max_of_min) + dig_min_0 = dig_max_of_min; + else + dig_min_0 = + dm_digtable->rssi_val_min - offset; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "bOneEntryOnly=TRUE, dig_min_0=0x%x\n", + dig_min_0); + } else { + dig_min_0 = dm_dig_min; + } + } else { + dm_digtable->rx_gain_max = dm_dig_max; + dig_min_0 = dm_dig_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n"); + } + + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Abnormally false alarm case.\n"); + + if (dm_digtable->large_fa_hit != 3) + dm_digtable->large_fa_hit++; + if (dm_digtable->forbidden_igi < current_igi) { + dm_digtable->forbidden_igi = current_igi; + dm_digtable->large_fa_hit = 1; + } + + if (dm_digtable->large_fa_hit >= 3) { + if ((dm_digtable->forbidden_igi + 1) > + dm_digtable->rx_gain_max) + dm_digtable->rx_gain_min = + dm_digtable->rx_gain_max; + else + dm_digtable->rx_gain_min = + (dm_digtable->forbidden_igi + 1); + dm_digtable->recover_cnt = 3600; + } + } else { + /*Recovery mechanism for IGI lower bound*/ + if (dm_digtable->recover_cnt != 0) { + dm_digtable->recover_cnt--; + } else { + if (dm_digtable->large_fa_hit < 3) { + if ((dm_digtable->forbidden_igi - 1) < + dig_min_0) { + dm_digtable->forbidden_igi = + dig_min_0; + dm_digtable->rx_gain_min = + dig_min_0; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Normal Case: At Lower Bound\n"); + } else { + dm_digtable->forbidden_igi--; + dm_digtable->rx_gain_min = + (dm_digtable->forbidden_igi + 1); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Normal Case: Approach Lower Bound\n"); + } + } else { + dm_digtable->large_fa_hit = 0; + } + } + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "pDM_DigTable->LargeFAHit=%d\n", + dm_digtable->large_fa_hit); + + if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) + dm_digtable->rx_gain_min = dm_dig_min; + + if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) + dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; + + /*Adjust initial gain by false alarm*/ + if (mac->link_state >= MAC80211_LINKED) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "DIG AfterLink\n"); + if (first_connect) { + current_igi = min(dm_digtable->rssi_val_min, dig_max_of_min); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "First Connect\n"); + } else { + if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) + current_igi = current_igi + 4; + else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) + current_igi = current_igi + 2; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + current_igi = current_igi - 2; + + if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) && + (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) { + current_igi = dm_digtable->rx_gain_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"); + } + } + } else { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "DIG BeforeLink\n"); + if (first_disconnect) { + current_igi = dm_digtable->rx_gain_min; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "First DisConnect\n"); + } else { + /* 2012.03.30 LukeLee: enable DIG before + * link but with very high thresholds + */ + if (rtlpriv->falsealm_cnt.cnt_all > 2000) + current_igi = current_igi + 4; + else if (rtlpriv->falsealm_cnt.cnt_all > 600) + current_igi = current_igi + 2; + else if (rtlpriv->falsealm_cnt.cnt_all < 300) + current_igi = current_igi - 2; + + if (current_igi >= 0x3e) + current_igi = 0x3e; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n"); + } + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "DIG End Adjust IGI\n"); + /* Check initial gain by upper/lower bound*/ + + if (current_igi > dm_digtable->rx_gain_max) + current_igi = dm_digtable->rx_gain_max; + if (current_igi < dm_digtable->rx_gain_min) + current_igi = dm_digtable->rx_gain_min; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "rx_gain_max=0x%x, rx_gain_min=0x%x\n", + dm_digtable->rx_gain_max, dm_digtable->rx_gain_min); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "CurIGValue=0x%x\n", current_igi); + + rtl8821ae_dm_write_dig(hw, current_igi); + dm_digtable->media_connect_0 = + ((mac->link_state >= MAC80211_LINKED) ? true : false); + dm_digtable->dig_min_0 = dig_min_0; +} + +static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 cnt; + + rtlpriv->dm.tx_rate = 0xff; + + rtlpriv->dm.one_entry_only = false; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && + rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + rtlpriv->dm.one_entry_only = true; + return; + } + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { + spin_lock_bh(&rtlpriv->locks.entry_list_lock); + cnt = list_count_nodes(&rtlpriv->entry_list); + spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + + if (cnt == 1) + rtlpriv->dm.one_entry_only = true; + } +} + +static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; + u32 cck_enable = 0; + + /*read OFDM FA counter*/ + falsealm_cnt->cnt_ofdm_fail = + rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD); + falsealm_cnt->cnt_cck_fail = + rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD); + + cck_enable = rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28)); + if (cck_enable) /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/ + falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + + falsealm_cnt->cnt_cck_fail; + else + falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail; + + /*reset OFDM FA counter*/ + rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); + rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); + /* reset CCK FA counter*/ + rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); + rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n", + falsealm_cnt->cnt_cck_fail); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n", + falsealm_cnt->cnt_ofdm_fail); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n", + falsealm_cnt->cnt_all); +} + +static void rtl8812ae_dm_check_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, + BIT(17) | BIT(16), 0x03); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 8812 Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + return; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking direct call!!\n"); + rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (mac->link_state >= MAC80211_LINKED) { + if (rtldm->linked_interval < 3) + rtldm->linked_interval++; + + if (rtldm->linked_interval == 2) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_phy_iq_calibrate(hw, false); + else + rtl8821ae_phy_iq_calibrate(hw, false); + } + } else { + rtldm->linked_interval = 0; + } +} + +static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, + const u8 **up_a, + const u8 **down_a, + const u8 **up_b, + const u8 **down_b) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 channel = rtlphy->current_channel; + u8 rate = rtldm->tx_rate; + + if (1 <= channel && channel <= 14) { + if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { + *up_a = rtl8812ae_delta_swing_table_idx_24gccka_p; + *down_a = rtl8812ae_delta_swing_table_idx_24gccka_n; + *up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p; + *down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n; + } else { + *up_a = rtl8812ae_delta_swing_table_idx_24ga_p; + *down_a = rtl8812ae_delta_swing_table_idx_24ga_n; + *up_b = rtl8812ae_delta_swing_table_idx_24gb_p; + *down_b = rtl8812ae_delta_swing_table_idx_24gb_n; + } + } else if (36 <= channel && channel <= 64) { + *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0]; + *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0]; + *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0]; + *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0]; + } else if (100 <= channel && channel <= 140) { + *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1]; + *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1]; + *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1]; + *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1]; + } else if (149 <= channel && channel <= 173) { + *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2]; + *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2]; + *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2]; + *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2]; + } else { + *up_a = rtl8818e_delta_swing_table_idx_24gb_p; + *down_a = rtl8818e_delta_swing_table_idx_24gb_n; + *up_b = rtl8818e_delta_swing_table_idx_24gb_p; + *down_b = rtl8818e_delta_swing_table_idx_24gb_n; + } +} + +void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 p = 0; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Get C2H Command! Rate=0x%x\n", rate); + + rtldm->tx_rate = rate; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0); + } else { + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) + rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0); + } +} + +u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ret_rate = MGN_1M; + + switch (rate) { + case DESC_RATE1M: + ret_rate = MGN_1M; + break; + case DESC_RATE2M: + ret_rate = MGN_2M; + break; + case DESC_RATE5_5M: + ret_rate = MGN_5_5M; + break; + case DESC_RATE11M: + ret_rate = MGN_11M; + break; + case DESC_RATE6M: + ret_rate = MGN_6M; + break; + case DESC_RATE9M: + ret_rate = MGN_9M; + break; + case DESC_RATE12M: + ret_rate = MGN_12M; + break; + case DESC_RATE18M: + ret_rate = MGN_18M; + break; + case DESC_RATE24M: + ret_rate = MGN_24M; + break; + case DESC_RATE36M: + ret_rate = MGN_36M; + break; + case DESC_RATE48M: + ret_rate = MGN_48M; + break; + case DESC_RATE54M: + ret_rate = MGN_54M; + break; + case DESC_RATEMCS0: + ret_rate = MGN_MCS0; + break; + case DESC_RATEMCS1: + ret_rate = MGN_MCS1; + break; + case DESC_RATEMCS2: + ret_rate = MGN_MCS2; + break; + case DESC_RATEMCS3: + ret_rate = MGN_MCS3; + break; + case DESC_RATEMCS4: + ret_rate = MGN_MCS4; + break; + case DESC_RATEMCS5: + ret_rate = MGN_MCS5; + break; + case DESC_RATEMCS6: + ret_rate = MGN_MCS6; + break; + case DESC_RATEMCS7: + ret_rate = MGN_MCS7; + break; + case DESC_RATEMCS8: + ret_rate = MGN_MCS8; + break; + case DESC_RATEMCS9: + ret_rate = MGN_MCS9; + break; + case DESC_RATEMCS10: + ret_rate = MGN_MCS10; + break; + case DESC_RATEMCS11: + ret_rate = MGN_MCS11; + break; + case DESC_RATEMCS12: + ret_rate = MGN_MCS12; + break; + case DESC_RATEMCS13: + ret_rate = MGN_MCS13; + break; + case DESC_RATEMCS14: + ret_rate = MGN_MCS14; + break; + case DESC_RATEMCS15: + ret_rate = MGN_MCS15; + break; + case DESC_RATEVHT1SS_MCS0: + ret_rate = MGN_VHT1SS_MCS0; + break; + case DESC_RATEVHT1SS_MCS1: + ret_rate = MGN_VHT1SS_MCS1; + break; + case DESC_RATEVHT1SS_MCS2: + ret_rate = MGN_VHT1SS_MCS2; + break; + case DESC_RATEVHT1SS_MCS3: + ret_rate = MGN_VHT1SS_MCS3; + break; + case DESC_RATEVHT1SS_MCS4: + ret_rate = MGN_VHT1SS_MCS4; + break; + case DESC_RATEVHT1SS_MCS5: + ret_rate = MGN_VHT1SS_MCS5; + break; + case DESC_RATEVHT1SS_MCS6: + ret_rate = MGN_VHT1SS_MCS6; + break; + case DESC_RATEVHT1SS_MCS7: + ret_rate = MGN_VHT1SS_MCS7; + break; + case DESC_RATEVHT1SS_MCS8: + ret_rate = MGN_VHT1SS_MCS8; + break; + case DESC_RATEVHT1SS_MCS9: + ret_rate = MGN_VHT1SS_MCS9; + break; + case DESC_RATEVHT2SS_MCS0: + ret_rate = MGN_VHT2SS_MCS0; + break; + case DESC_RATEVHT2SS_MCS1: + ret_rate = MGN_VHT2SS_MCS1; + break; + case DESC_RATEVHT2SS_MCS2: + ret_rate = MGN_VHT2SS_MCS2; + break; + case DESC_RATEVHT2SS_MCS3: + ret_rate = MGN_VHT2SS_MCS3; + break; + case DESC_RATEVHT2SS_MCS4: + ret_rate = MGN_VHT2SS_MCS4; + break; + case DESC_RATEVHT2SS_MCS5: + ret_rate = MGN_VHT2SS_MCS5; + break; + case DESC_RATEVHT2SS_MCS6: + ret_rate = MGN_VHT2SS_MCS6; + break; + case DESC_RATEVHT2SS_MCS7: + ret_rate = MGN_VHT2SS_MCS7; + break; + case DESC_RATEVHT2SS_MCS8: + ret_rate = MGN_VHT2SS_MCS8; + break; + case DESC_RATEVHT2SS_MCS9: + ret_rate = MGN_VHT2SS_MCS9; + break; + default: + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "HwRateToMRate8812(): Non supported Rate [%x]!!!\n", + rate); + break; + } + return ret_rate; +} + +/*----------------------------------------------------------------------------- + * Function: odm_TxPwrTrackSetPwr88E() + * + * Overview: 88E change all channel tx power accordign to flag. + * OFDM & CCK are all different. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 04/23/2012 MHC Create Version 0. + * + *--------------------------------------------------------------------------- + */ +void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rf_path, u8 channel_mapped_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 final_swing_idx[2]; + u8 pwr_tracking_limit = 26; /*+1.0dB*/ + u8 tx_rate = 0xFF; + s8 final_ofdm_swing_index = 0; + + if (rtldm->tx_rate != 0xFF) + tx_rate = + rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "===>%s\n", __func__); + /*20130429 Mimic Modify High Rate BBSwing Limit.*/ + if (tx_rate != 0xFF) { + /*CCK*/ + if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) + pwr_tracking_limit = 32; /*+4dB*/ + /*OFDM*/ + else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) + pwr_tracking_limit = 30; /*+3dB*/ + else if (tx_rate == MGN_54M) + pwr_tracking_limit = 28; /*+2dB*/ + /*HT*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) + pwr_tracking_limit = 28; /*+2dB*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) + pwr_tracking_limit = 28; /*+2dB*/ + + /*2 VHT*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_VHT1SS_MCS0) && + (tx_rate <= MGN_VHT1SS_MCS2)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_VHT1SS_MCS3) && + (tx_rate <= MGN_VHT1SS_MCS4)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_VHT1SS_MCS5) && + (tx_rate <= MGN_VHT1SS_MCS6)) + pwr_tracking_limit = 28; /*+2dB*/ + else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ + pwr_tracking_limit = 26; /*+1dB*/ + else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ + pwr_tracking_limit = 24; /*+0dB*/ + else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ + pwr_tracking_limit = 22; /*-1dB*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_VHT2SS_MCS0) && + (tx_rate <= MGN_VHT2SS_MCS2)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_VHT2SS_MCS3) && + (tx_rate <= MGN_VHT2SS_MCS4)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_VHT2SS_MCS5) && + (tx_rate <= MGN_VHT2SS_MCS6)) + pwr_tracking_limit = 28; /*+2dB*/ + else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/ + pwr_tracking_limit = 26; /*+1dB*/ + else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/ + pwr_tracking_limit = 24; /*+0dB*/ + else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/ + pwr_tracking_limit = 22; /*-1dB*/ + else + pwr_tracking_limit = 24; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxRate=0x%x, PwrTrackingLimit=%d\n", + tx_rate, pwr_tracking_limit); + + if (method == BBSWING) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "===>%s\n", __func__); + + if (rf_path == RF90_PATH_A) { + u32 tmp; + + final_swing_idx[RF90_PATH_A] = + (rtldm->ofdm_index[RF90_PATH_A] > + pwr_tracking_limit) ? + pwr_tracking_limit : + rtldm->ofdm_index[RF90_PATH_A]; + tmp = final_swing_idx[RF90_PATH_A]; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", + rtldm->ofdm_index[RF90_PATH_A], + final_swing_idx[RF90_PATH_A]); + + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[tmp]); + } else { + u32 tmp; + + final_swing_idx[RF90_PATH_B] = + rtldm->ofdm_index[RF90_PATH_B] > + pwr_tracking_limit ? + pwr_tracking_limit : + rtldm->ofdm_index[RF90_PATH_B]; + tmp = final_swing_idx[RF90_PATH_B]; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n", + rtldm->ofdm_index[RF90_PATH_B], + final_swing_idx[RF90_PATH_B]); + + rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, + txscaling_tbl[tmp]); + } + } else if (method == MIX_MODE) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", + rtldm->default_ofdm_index, + rtldm->absolute_ofdm_swing_idx[rf_path], + rf_path); + + final_ofdm_swing_index = rtldm->default_ofdm_index + + rtldm->absolute_ofdm_swing_idx[rf_path]; + + if (rf_path == RF90_PATH_A) { + /*BBSwing higher then Limit*/ + if (final_ofdm_swing_index > pwr_tracking_limit) { + rtldm->remnant_cck_idx = + final_ofdm_swing_index - + pwr_tracking_limit; + /* CCK Follow the same compensation value + * as Path A + */ + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index - + pwr_tracking_limit; + + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[pwr_tracking_limit]); + + rtldm->modify_txagc_flag_path_a = true; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, + RF90_PATH_A); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n", + pwr_tracking_limit, + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else if (final_ofdm_swing_index < 0) { + rtldm->remnant_cck_idx = final_ofdm_swing_index; + /* CCK Follow the same compensate value as Path A*/ + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index; + + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[0]); + + rtldm->modify_txagc_flag_path_a = true; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_A); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else { + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[(u8)final_ofdm_swing_index]); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n", + final_ofdm_swing_index); + /*If TxAGC has changed, reset TxAGC again*/ + if (rtldm->modify_txagc_flag_path_a) { + rtldm->remnant_cck_idx = 0; + rtldm->remnant_ofdm_swing_idx[rf_path] = 0; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_A); + rtldm->modify_txagc_flag_path_a = false; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); + } + } + } + /*BBSwing higher then Limit*/ + if (rf_path == RF90_PATH_B) { + if (final_ofdm_swing_index > pwr_tracking_limit) { + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index - + pwr_tracking_limit; + + rtl_set_bbreg(hw, RB_TXSCALE, + 0xFFE00000, + txscaling_tbl[pwr_tracking_limit]); + + rtldm->modify_txagc_flag_path_b = true; + + /*Set TxAGC Page E{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_B); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", + pwr_tracking_limit, + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else if (final_ofdm_swing_index < 0) { + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index; + + rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, + txscaling_tbl[0]); + + rtldm->modify_txagc_flag_path_b = true; + + /*Set TxAGC Page E{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_B); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else { + rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, + txscaling_tbl[(u8)final_ofdm_swing_index]); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", + final_ofdm_swing_index); + /*If TxAGC has changed, reset TxAGC again*/ + if (rtldm->modify_txagc_flag_path_b) { + rtldm->remnant_ofdm_swing_idx[rf_path] = 0; + + /*Set TxAGC Page E{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_B); + + rtldm->modify_txagc_flag_path_b = + false; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); + } + } + } + } else { + return; + } +} + +void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; + u8 thermal_value_avg_count = 0; + u32 thermal_value_avg = 0; + /* OFDM BB Swing should be less than +3.0dB, */ + u8 ofdm_min_index = 6; + /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ + u8 index_for_channel = 0; + /* 1. The following TWO tables decide + * the final index of OFDM/CCK swing table. + */ + const u8 *delta_swing_table_idx_tup_a; + const u8 *delta_swing_table_idx_tdown_a; + const u8 *delta_swing_table_idx_tup_b; + const u8 *delta_swing_table_idx_tdown_b; + + /*2. Initialization ( 7 steps in total )*/ + rtl8812ae_get_delta_swing_table(hw, + &delta_swing_table_idx_tup_a, + &delta_swing_table_idx_tdown_a, + &delta_swing_table_idx_tup_b, + &delta_swing_table_idx_tdown_b); + + rtldm->txpower_trackinginit = true; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", + rtldm->swing_idx_cck_base, + rtldm->swing_idx_ofdm_base[RF90_PATH_A], + rtldm->default_ofdm_index); + + thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, + /*0x42: RF Reg[15:10] 88E*/ + RF_T_METER_8812A, 0xfc00); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + if (!rtldm->txpower_track_control || + rtlefuse->eeprom_thermalmeter == 0 || + rtlefuse->eeprom_thermalmeter == 0xFF) + return; + + /* 3. Initialize ThermalValues of RFCalibrateInfo*/ + + if (rtlhal->reloadtxpowerindex) + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "reload ofdm index for band switch\n"); + + /*4. Calculate average thermal meter*/ + rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; + rtldm->thermalvalue_avg_index++; + if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) + /*Average times = c.AverageThermalNum*/ + rtldm->thermalvalue_avg_index = 0; + + for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { + if (rtldm->thermalvalue_avg[i]) { + thermal_value_avg += rtldm->thermalvalue_avg[i]; + thermal_value_avg_count++; + } + } + /*Calculate Average ThermalValue after average enough times*/ + if (thermal_value_avg_count) { + thermal_value = (u8)(thermal_value_avg / + thermal_value_avg_count); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + } + + /*5. Calculate delta, delta_LCK, delta_IQK. + *"delta" here is used to determine whether + *thermal value changes or not. + */ + delta = (thermal_value > rtldm->thermalvalue) ? + (thermal_value - rtldm->thermalvalue) : + (rtldm->thermalvalue - thermal_value); + delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? + (thermal_value - rtldm->thermalvalue_lck) : + (rtldm->thermalvalue_lck - thermal_value); + delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? + (thermal_value - rtldm->thermalvalue_iqk) : + (rtldm->thermalvalue_iqk - thermal_value); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", + delta, delta_lck, delta_iqk); + + /* 6. If necessary, do LCK. + * Delta temperature is equal to or larger than 20 centigrade. + */ + if (delta_lck >= IQK_THRESHOLD) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_LCK(%d) >= Threshold_IQK(%d)\n", + delta_lck, IQK_THRESHOLD); + rtldm->thermalvalue_lck = thermal_value; + rtl8821ae_phy_lc_calibrate(hw); + } + + /*7. If necessary, move the index of swing table to adjust Tx power.*/ + + if (delta > 0 && rtldm->txpower_track_control) { + /* "delta" here is used to record the + * absolute value of differrence. + */ + delta = thermal_value > rtlefuse->eeprom_thermalmeter ? + (thermal_value - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermal_value); + + if (delta >= TXPWR_TRACK_TABLE_SIZE) + delta = TXPWR_TRACK_TABLE_SIZE - 1; + + /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ + + if (thermal_value > rtlefuse->eeprom_thermalmeter) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_swing_table_idx_tup_a[%d] = %d\n", + delta, delta_swing_table_idx_tup_a[delta]); + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + delta_swing_table_idx_tup_a[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = + delta_swing_table_idx_tup_a[delta]; + /*Record delta swing for mix mode power tracking*/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_swing_table_idx_tup_b[%d] = %d\n", + delta, delta_swing_table_idx_tup_b[delta]); + rtldm->delta_power_index_last[RF90_PATH_B] = + rtldm->delta_power_index[RF90_PATH_B]; + rtldm->delta_power_index[RF90_PATH_B] = + delta_swing_table_idx_tup_b[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = + delta_swing_table_idx_tup_b[delta]; + /*Record delta swing for mix mode power tracking*/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_swing_table_idx_tdown_a[%d] = %d\n", + delta, delta_swing_table_idx_tdown_a[delta]); + + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + -1 * delta_swing_table_idx_tdown_a[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = + -1 * delta_swing_table_idx_tdown_a[delta]; + /* Record delta swing for mix mode power tracking*/ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "deltaSwingTableIdx_TDOWN_B[%d] = %d\n", + delta, delta_swing_table_idx_tdown_b[delta]); + + rtldm->delta_power_index_last[RF90_PATH_B] = + rtldm->delta_power_index[RF90_PATH_B]; + rtldm->delta_power_index[RF90_PATH_B] = + -1 * delta_swing_table_idx_tdown_b[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = + -1 * delta_swing_table_idx_tdown_b[delta]; + /*Record delta swing for mix mode power tracking*/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); + } + + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "============================= [Path-%c]Calculating PowerIndexOffset =============================\n", + (p == RF90_PATH_A ? 'A' : 'B')); + + if (rtldm->delta_power_index[p] == + rtldm->delta_power_index_last[p]) + /*If Thermal value changes but lookup + table value still the same*/ + rtldm->power_index_offset[p] = 0; + else + rtldm->power_index_offset[p] = + rtldm->delta_power_index[p] - + rtldm->delta_power_index_last[p]; + /* Power Index Diff between 2 + * times Power Tracking + */ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n", + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->power_index_offset[p], + rtldm->delta_power_index[p], + rtldm->delta_power_index_last[p]); + + rtldm->ofdm_index[p] = + rtldm->swing_idx_ofdm_base[p] + + rtldm->power_index_offset[p]; + rtldm->cck_index = + rtldm->swing_idx_cck_base + + rtldm->power_index_offset[p]; + + rtldm->swing_idx_cck = rtldm->cck_index; + rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; + + /****Print BB Swing Base and Index Offset */ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", + rtldm->swing_idx_cck, + rtldm->swing_idx_cck_base, + rtldm->power_index_offset[p]); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", + rtldm->swing_idx_ofdm[p], + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->swing_idx_ofdm_base[p], + rtldm->power_index_offset[p]); + + /*7.1 Handle boundary conditions of index.*/ + + if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) + rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; + else if (rtldm->ofdm_index[p] < ofdm_min_index) + rtldm->ofdm_index[p] = ofdm_min_index; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "\n\n====================================================================================\n"); + if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) + rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; + else if (rtldm->cck_index < 0) + rtldm->cck_index = 0; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", + rtldm->txpower_track_control, + thermal_value, + rtldm->thermalvalue); + + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) + rtldm->power_index_offset[p] = 0; + } + /*Print Swing base & current*/ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n", + rtldm->cck_index, rtldm->swing_idx_cck_base); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n", + rtldm->ofdm_index[p], + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->swing_idx_ofdm_base[p]); + } + + if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || + rtldm->power_index_offset[RF90_PATH_B] != 0) && + rtldm->txpower_track_control) { + /*7.2 Configure the Swing Table to adjust Tx Power. + *Always TRUE after Tx Power is adjusted by power tracking. + * + *2012/04/23 MH According to Luke's suggestion, + *we can not write BB digital + *to increase TX power. Otherwise, EVM will be bad. + * + *2012/04/25 MH Add for tx power tracking to set + *tx power in tx agc for 88E. + */ + if (thermal_value > rtldm->thermalvalue) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_A], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_B], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_A], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_B], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + } + + if (thermal_value > rtlefuse->eeprom_thermalmeter) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature(%d) higher than PG value(%d)\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "**********Enter POWER Tracking MIX_MODE**********\n"); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) + rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, + p, 0); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature(%d) lower than PG value(%d)\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "**********Enter POWER Tracking MIX_MODE**********\n"); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) + rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, + p, index_for_channel); + } + /*Record last time Power Tracking result as base.*/ + rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) + rtldm->swing_idx_ofdm_base[p] = + rtldm->swing_idx_ofdm[p]; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n", + rtldm->thermalvalue, thermal_value); + /*Record last Power Tracking Thermal Value*/ + rtldm->thermalvalue = thermal_value; + } + /*Delta temperature is equal to or larger than + 20 centigrade (When threshold is 8).*/ + if (delta_iqk >= IQK_THRESHOLD) + rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "<===%s\n", __func__); +} + +static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, + const u8 **up_a, + const u8 **down_a) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 channel = rtlphy->current_channel; + u8 rate = rtldm->tx_rate; + + if (1 <= channel && channel <= 14) { + if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { + *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p; + *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n; + } else { + *up_a = rtl8821ae_delta_swing_table_idx_24ga_p; + *down_a = rtl8821ae_delta_swing_table_idx_24ga_n; + } + } else if (36 <= channel && channel <= 64) { + *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0]; + *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0]; + } else if (100 <= channel && channel <= 140) { + *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1]; + *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1]; + } else if (149 <= channel && channel <= 173) { + *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2]; + *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2]; + } else { + *up_a = rtl8818e_delta_swing_table_idx_24gb_p; + *down_a = rtl8818e_delta_swing_table_idx_24gb_n; + } + return; +} + +/*----------------------------------------------------------------------------- + * Function: odm_TxPwrTrackSetPwr88E() + * + * Overview: 88E change all channel tx power accordign to flag. + * OFDM & CCK are all different. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 04/23/2012 MHC Create Version 0. + * + *--------------------------------------------------------------------------- + */ +void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rf_path, u8 channel_mapped_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 final_swing_idx[1]; + u8 pwr_tracking_limit = 26; /*+1.0dB*/ + u8 tx_rate = 0xFF; + s8 final_ofdm_swing_index = 0; + + if (rtldm->tx_rate != 0xFF) + tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__); + + if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/ + /*CCK*/ + if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) + pwr_tracking_limit = 32; /*+4dB*/ + /*OFDM*/ + else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) + pwr_tracking_limit = 30; /*+3dB*/ + else if (tx_rate == MGN_54M) + pwr_tracking_limit = 28; /*+2dB*/ + /*HT*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) + pwr_tracking_limit = 28; /*+2dB*/ + /*2 VHT*/ + /*QPSK/BPSK*/ + else if ((tx_rate >= MGN_VHT1SS_MCS0) && + (tx_rate <= MGN_VHT1SS_MCS2)) + pwr_tracking_limit = 34; /*+5dB*/ + /*16QAM*/ + else if ((tx_rate >= MGN_VHT1SS_MCS3) && + (tx_rate <= MGN_VHT1SS_MCS4)) + pwr_tracking_limit = 30; /*+3dB*/ + /*64QAM*/ + else if ((tx_rate >= MGN_VHT1SS_MCS5) && + (tx_rate <= MGN_VHT1SS_MCS6)) + pwr_tracking_limit = 28; /*+2dB*/ + else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ + pwr_tracking_limit = 26; /*+1dB*/ + else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ + pwr_tracking_limit = 24; /*+0dB*/ + else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ + pwr_tracking_limit = 22; /*-1dB*/ + else + pwr_tracking_limit = 24; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxRate=0x%x, PwrTrackingLimit=%d\n", + tx_rate, pwr_tracking_limit); + + if (method == BBSWING) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "===>%s\n", __func__); + if (rf_path == RF90_PATH_A) { + final_swing_idx[RF90_PATH_A] = + (rtldm->ofdm_index[RF90_PATH_A] > + pwr_tracking_limit) ? + pwr_tracking_limit : + rtldm->ofdm_index[RF90_PATH_A]; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", + rtldm->ofdm_index[RF90_PATH_A], + final_swing_idx[RF90_PATH_A]); + + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[final_swing_idx[RF90_PATH_A]]); + } + } else if (method == MIX_MODE) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", + rtldm->default_ofdm_index, + rtldm->absolute_ofdm_swing_idx[rf_path], + rf_path); + + final_ofdm_swing_index = + rtldm->default_ofdm_index + + rtldm->absolute_ofdm_swing_idx[rf_path]; + /*BBSwing higher then Limit*/ + if (rf_path == RF90_PATH_A) { + if (final_ofdm_swing_index > pwr_tracking_limit) { + rtldm->remnant_cck_idx = + final_ofdm_swing_index - + pwr_tracking_limit; + /* CCK Follow the same compensate value as Path A*/ + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index - + pwr_tracking_limit; + + rtl_set_bbreg(hw, RA_TXSCALE, + 0xFFE00000, + txscaling_tbl[pwr_tracking_limit]); + + rtldm->modify_txagc_flag_path_a = true; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, + RF90_PATH_A); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", + pwr_tracking_limit, + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else if (final_ofdm_swing_index < 0) { + rtldm->remnant_cck_idx = final_ofdm_swing_index; + /* CCK Follow the same compensate value as Path A*/ + rtldm->remnant_ofdm_swing_idx[rf_path] = + final_ofdm_swing_index; + + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[0]); + + rtldm->modify_txagc_flag_path_a = true; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_A); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", + rtldm->remnant_ofdm_swing_idx[rf_path]); + } else { + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + txscaling_tbl[(u8)final_ofdm_swing_index]); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", + final_ofdm_swing_index); + /*If TxAGC has changed, reset TxAGC again*/ + if (rtldm->modify_txagc_flag_path_a) { + rtldm->remnant_cck_idx = 0; + rtldm->remnant_ofdm_swing_idx[rf_path] = 0; + + /*Set TxAGC Page C{};*/ + rtl8821ae_phy_set_txpower_level_by_path(hw, + rtlphy->current_channel, RF90_PATH_A); + + rtldm->modify_txagc_flag_path_a = false; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n"); + } + } + } + } else { + return; + } +} + +void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; + u8 thermal_value_avg_count = 0; + u32 thermal_value_avg = 0; + + u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB */ + /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ + u8 index_for_channel = 0; + + /* 1. The following TWO tables decide the final + * index of OFDM/CCK swing table. + */ + const u8 *delta_swing_table_idx_tup_a; + const u8 *delta_swing_table_idx_tdown_a; + + /*2. Initilization ( 7 steps in total )*/ + rtl8821ae_get_delta_swing_table(hw, + &delta_swing_table_idx_tup_a, + &delta_swing_table_idx_tdown_a); + + rtldm->txpower_trackinginit = true; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", + __func__, + rtldm->swing_idx_cck_base, + rtldm->swing_idx_ofdm_base[RF90_PATH_A], + rtldm->default_ofdm_index); + /*0x42: RF Reg[15:10] 88E*/ + thermal_value = (u8)rtl_get_rfreg(hw, + RF90_PATH_A, RF_T_METER_8812A, 0xfc00); + if (!rtldm->txpower_track_control || + rtlefuse->eeprom_thermalmeter == 0 || + rtlefuse->eeprom_thermalmeter == 0xFF) + return; + + /* 3. Initialize ThermalValues of RFCalibrateInfo*/ + + if (rtlhal->reloadtxpowerindex) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "reload ofdm index for band switch\n"); + } + + /*4. Calculate average thermal meter*/ + rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; + rtldm->thermalvalue_avg_index++; + if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) + /*Average times = c.AverageThermalNum*/ + rtldm->thermalvalue_avg_index = 0; + + for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { + if (rtldm->thermalvalue_avg[i]) { + thermal_value_avg += rtldm->thermalvalue_avg[i]; + thermal_value_avg_count++; + } + } + /*Calculate Average ThermalValue after average enough times*/ + if (thermal_value_avg_count) { + thermal_value = (u8)(thermal_value_avg / + thermal_value_avg_count); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + } + + /*5. Calculate delta, delta_LCK, delta_IQK. + *"delta" here is used to determine whether + * thermal value changes or not. + */ + delta = (thermal_value > rtldm->thermalvalue) ? + (thermal_value - rtldm->thermalvalue) : + (rtldm->thermalvalue - thermal_value); + delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? + (thermal_value - rtldm->thermalvalue_lck) : + (rtldm->thermalvalue_lck - thermal_value); + delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? + (thermal_value - rtldm->thermalvalue_iqk) : + (rtldm->thermalvalue_iqk - thermal_value); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", + delta, delta_lck, delta_iqk); + + /* 6. If necessary, do LCK. */ + /*Delta temperature is equal to or larger than 20 centigrade.*/ + if (delta_lck >= IQK_THRESHOLD) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_LCK(%d) >= Threshold_IQK(%d)\n", + delta_lck, IQK_THRESHOLD); + rtldm->thermalvalue_lck = thermal_value; + rtl8821ae_phy_lc_calibrate(hw); + } + + /*7. If necessary, move the index of swing table to adjust Tx power.*/ + + if (delta > 0 && rtldm->txpower_track_control) { + /*"delta" here is used to record the + * absolute value of differrence. + */ + delta = thermal_value > rtlefuse->eeprom_thermalmeter ? + (thermal_value - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermal_value); + + if (delta >= TXSCALE_TABLE_SIZE) + delta = TXSCALE_TABLE_SIZE - 1; + + /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ + + if (thermal_value > rtlefuse->eeprom_thermalmeter) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_swing_table_idx_tup_a[%d] = %d\n", + delta, delta_swing_table_idx_tup_a[delta]); + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + delta_swing_table_idx_tup_a[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = + delta_swing_table_idx_tup_a[delta]; + /*Record delta swing for mix mode power tracking*/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "delta_swing_table_idx_tdown_a[%d] = %d\n", + delta, delta_swing_table_idx_tdown_a[delta]); + + rtldm->delta_power_index_last[RF90_PATH_A] = + rtldm->delta_power_index[RF90_PATH_A]; + rtldm->delta_power_index[RF90_PATH_A] = + -1 * delta_swing_table_idx_tdown_a[delta]; + + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = + -1 * delta_swing_table_idx_tdown_a[delta]; + /* Record delta swing for mix mode power tracking*/ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", + rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); + } + + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n", + (p == RF90_PATH_A ? 'A' : 'B')); + /*If Thermal value changes but lookup table value + * still the same + */ + if (rtldm->delta_power_index[p] == + rtldm->delta_power_index_last[p]) + + rtldm->power_index_offset[p] = 0; + else + rtldm->power_index_offset[p] = + rtldm->delta_power_index[p] - + rtldm->delta_power_index_last[p]; + /*Power Index Diff between 2 times Power Tracking*/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->power_index_offset[p], + rtldm->delta_power_index[p] , + rtldm->delta_power_index_last[p]); + + rtldm->ofdm_index[p] = + rtldm->swing_idx_ofdm_base[p] + + rtldm->power_index_offset[p]; + rtldm->cck_index = + rtldm->swing_idx_cck_base + + rtldm->power_index_offset[p]; + + rtldm->swing_idx_cck = rtldm->cck_index; + rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; + + /*********Print BB Swing Base and Index Offset********/ + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", + rtldm->swing_idx_cck, + rtldm->swing_idx_cck_base, + rtldm->power_index_offset[p]); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", + rtldm->swing_idx_ofdm[p], + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->swing_idx_ofdm_base[p], + rtldm->power_index_offset[p]); + + /*7.1 Handle boundary conditions of index.*/ + + if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) + rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; + else if (rtldm->ofdm_index[p] < ofdm_min_index) + rtldm->ofdm_index[p] = ofdm_min_index; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "\n\n========================================================================================================\n"); + if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) + rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; + else if (rtldm->cck_index < 0) + rtldm->cck_index = 0; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", + rtldm->txpower_track_control, + thermal_value, + rtldm->thermalvalue); + + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) + rtldm->power_index_offset[p] = 0; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", + /*Print Swing base & current*/ + rtldm->cck_index, rtldm->swing_idx_cck_base); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n", + rtldm->ofdm_index[p], + (p == RF90_PATH_A ? 'A' : 'B'), + rtldm->swing_idx_ofdm_base[p]); + } + + if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || + rtldm->power_index_offset[RF90_PATH_B] != 0) && + rtldm->txpower_track_control) { + /*7.2 Configure the Swing Table to adjust Tx Power.*/ + /*Always TRUE after Tx Power is adjusted by power tracking.*/ + /* + * 2012/04/23 MH According to Luke's suggestion, + * we can not write BB digital + * to increase TX power. Otherwise, EVM will be bad. + * + * 2012/04/25 MH Add for tx power tracking to + * set tx power in tx agc for 88E. + */ + if (thermal_value > rtldm->thermalvalue) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_A], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + rtldm->power_index_offset[RF90_PATH_A], + delta, thermal_value, + rtlefuse->eeprom_thermalmeter, + rtldm->thermalvalue); + } + + if (thermal_value > rtlefuse->eeprom_thermalmeter) { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature(%d) higher than PG value(%d)\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "****Enter POWER Tracking MIX_MODE****\n"); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) + rtl8821ae_dm_txpwr_track_set_pwr(hw, + MIX_MODE, p, index_for_channel); + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Temperature(%d) lower than PG value(%d)\n", + thermal_value, rtlefuse->eeprom_thermalmeter); + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "*****Enter POWER Tracking MIX_MODE*****\n"); + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) + rtl8812ae_dm_txpwr_track_set_pwr(hw, + MIX_MODE, p, index_for_channel); + } + /*Record last time Power Tracking result as base.*/ + rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; + for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) + rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p]; + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", + rtldm->thermalvalue, thermal_value); + /*Record last Power Tracking Thermal Value*/ + rtldm->thermalvalue = thermal_value; + } + /* Delta temperature is equal to or larger than + * 20 centigrade (When threshold is 8). + */ + if (delta_iqk >= IQK_THRESHOLD) { + if (!rtlphy->lck_inprogress) { + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = true; + spin_unlock(&rtlpriv->locks.iqk_lock); + + rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8); + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = false; + spin_unlock(&rtlpriv->locks.iqk_lock); + } + } + + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__); +} + +void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (!rtlpriv->dm.tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), + 0x03); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Trigger 8821ae Thermal Meter!!\n"); + rtlpriv->dm.tm_trigger = 1; + return; + } else { + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Schedule TxPowerTracking !!\n"); + + rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw); + rtlpriv->dm.tm_trigger = 0; + } +} + +static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &rtlpriv->ra; + u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m; + u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; + u8 go_up_gap = 5; + struct ieee80211_sta *sta = NULL; + + if (is_hal_stop(rtlhal)) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver is going to unload\n"); + return; + } + + if (!rtlpriv->dm.useramask) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "driver does not control rate adaptive mask\n"); + return; + } + + if (mac->link_state == MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra += go_up_gap; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra += go_up_gap; + low_rssithresh_for_ra += go_up_gap; + break; + default: + break; + } + + if (rtlpriv->dm.undec_sm_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undec_sm_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld\n", + rtlpriv->dm.undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI_LEVEL = %d\n", p_ra->ratr_state); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); + + rcu_read_lock(); + sta = rtl_find_sta(hw, mac->bssid); + if (sta) + rtlpriv->cfg->ops->update_rate_tbl(hw, + sta, p_ra->ratr_state, true); + rcu_read_unlock(); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_mac *mac = &rtlpriv->mac80211; + static u8 stage; + u8 cur_stage = 0; + u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M; + + if (mac->link_state < MAC80211_LINKED) + cur_stage = 0; + else if (dm_digtable->rssi_val_min < 25) + cur_stage = 1; + else if (dm_digtable->rssi_val_min > 30) + cur_stage = 3; + else + cur_stage = 2; + + if (cur_stage != stage) { + if (cur_stage == 1) { + basic_rate &= (!(basic_rate ^ mac->basic_rates)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_BASIC_RATE, (u8 *)&basic_rate); + } else if (cur_stage == 3 && (stage == 1 || stage == 2)) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates); + } + } + stage = cur_stage; +} + +static void rtl8821ae_dm_edca_choose_traffic_idx( + struct ieee80211_hw *hw, u64 cur_tx_bytes, + u64 cur_rx_bytes, bool b_bias_on_rx, + bool *pb_is_cur_rdl_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (b_bias_on_rx) { + if (cur_tx_bytes > (cur_rx_bytes*4)) { + *pb_is_cur_rdl_state = false; + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "Uplink Traffic\n"); + } else { + *pb_is_cur_rdl_state = true; + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "Balance Traffic\n"); + } + } else { + if (cur_rx_bytes > (cur_tx_bytes*4)) { + *pb_is_cur_rdl_state = true; + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "Downlink Traffic\n"); + } else { + *pb_is_cur_rdl_state = false; + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "Balance Traffic\n"); + } + } + return; +} + +static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + + /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/ + u64 cur_tx_ok_cnt = 0; + u64 cur_rx_ok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + u32 edca_be = 0x5ea42b; + u8 iot_peer = 0; + bool *pb_is_cur_rdl_state = NULL; + bool b_bias_on_rx = false; + bool b_edca_turbo_on = false; + + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "%s=====>\n", __func__); + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "Original BE PARAM: 0x%x\n", + rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)); + + if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) + rtlpriv->dm.is_any_nonbepkts = true; + rtlpriv->dm.dbginfo.num_non_be_pkt = 0; + + /*=============================== + * list parameter for different platform + *=============================== + */ + pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate; + + cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt; + cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt; + + rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; + rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; + + iot_peer = rtlpriv->mac80211.vendor; + b_bias_on_rx = false; + b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) ? + true : false; + + if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) { + if ((iot_peer == PEER_CISCO) && + (mac->mode == WIRELESS_MODE_N_24G)) { + edca_be_dl = edca_setting_dl[iot_peer]; + edca_be_ul = edca_setting_ul[iot_peer]; + } + } + + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x\n", + rtlpriv->dm.is_any_nonbepkts, + rtlpriv->dm.disable_framebursting); + + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n", + b_edca_turbo_on, b_bias_on_rx); + + if (b_edca_turbo_on) { + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt); + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt); + if (b_bias_on_rx) + rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, + cur_rx_ok_cnt, true, pb_is_cur_rdl_state); + else + rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, + cur_rx_ok_cnt, false, pb_is_cur_rdl_state); + + edca_be = (*pb_is_cur_rdl_state) ? edca_be_dl : edca_be_ul; + + rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be); + + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be); + + rtlpriv->dm.current_turbo_edca = true; + + rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, + "EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x\n", + edca_be_dl, edca_be_ul, edca_be); + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + } + rtlpriv->dm.current_turbo_edca = false; + } + + rtlpriv->dm.is_any_nonbepkts = false; + rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; + rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + u8 cur_cck_cca_thresh; + + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { + if (dm_digtable->rssi_val_min > 25) { + cur_cck_cca_thresh = 0xcd; + } else if ((dm_digtable->rssi_val_min <= 25) && + (dm_digtable->rssi_val_min > 10)) { + cur_cck_cca_thresh = 0x83; + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh) + rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC, + cur_cck_cca_thresh); + + dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; + dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh; + rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, + "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres); +} + +static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 crystal_cap; + u32 packet_count; + int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; + int cfo_ave_diff; + + if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { + /*1.Enable ATC*/ + if (rtldm->atc_status == ATC_STATUS_OFF) { + rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON); + rtldm->atc_status = ATC_STATUS_ON; + } + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n"); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "atc_status = %d\n", rtldm->atc_status); + + if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { + rtldm->crystal_cap = rtlpriv->efuse.crystalcap; + crystal_cap = rtldm->crystal_cap & 0x3f; + crystal_cap = crystal_cap & 0x3f; + if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, + 0x7ff80000, (crystal_cap | + (crystal_cap << 6))); + else + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, + 0xfff000, (crystal_cap | + (crystal_cap << 6))); + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n", + rtldm->crystal_cap); + } else{ + /*1. Calculate CFO for path-A & path-B*/ + cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; + cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; + packet_count = rtldm->packet_count; + + /*2.No new packet*/ + if (packet_count == rtldm->packet_count_pre) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "packet counter doesn't change\n"); + return; + } + + rtldm->packet_count_pre = packet_count; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "packet counter = %d\n", + rtldm->packet_count); + + /*3.Average CFO*/ + if (rtlpriv->phy.rf_type == RF_1T1R) + cfo_ave = cfo_khz_a; + else + cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1; + + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n", + cfo_khz_a, cfo_khz_b, cfo_ave); + + /*4.Avoid abnormal large CFO*/ + cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? + (rtldm->cfo_ave_pre - cfo_ave) : + (cfo_ave - rtldm->cfo_ave_pre); + + if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "first large CFO hit\n"); + rtldm->large_cfo_hit = true; + return; + } else + rtldm->large_cfo_hit = false; + + rtldm->cfo_ave_pre = cfo_ave; + + /*CFO tracking by adjusting Xtal cap.*/ + + /*1.Dynamic Xtal threshold*/ + if (cfo_ave >= -rtldm->cfo_threshold && + cfo_ave <= rtldm->cfo_threshold && + rtldm->is_freeze == 0) { + if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; + rtldm->is_freeze = 1; + } else { + rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; + } + } + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Dynamic threshold = %d\n", + rtldm->cfo_threshold); + + /* 2.Calculate Xtal offset*/ + if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) + adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; + else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && + rtlpriv->dm.crystal_cap > 0) + adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "Crystal cap = 0x%x, Crystal cap offset = %d\n", + rtldm->crystal_cap, adjust_xtal); + + /*3.Adjudt Crystal Cap.*/ + if (adjust_xtal != 0) { + rtldm->is_freeze = 0; + rtldm->crystal_cap += adjust_xtal; + + if (rtldm->crystal_cap > 0x3f) + rtldm->crystal_cap = 0x3f; + else if (rtldm->crystal_cap < 0) + rtldm->crystal_cap = 0; + + crystal_cap = rtldm->crystal_cap & 0x3f; + crystal_cap = crystal_cap & 0x3f; + if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, + 0x7ff80000, (crystal_cap | + (crystal_cap << 6))); + else + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, + 0xfff000, (crystal_cap | + (crystal_cap << 6))); + rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, + "New crystal cap = 0x%x\n", + rtldm->crystal_cap); + } + } +} + +void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) { + rtl8821ae_dm_common_info_self_update(hw); + rtl8821ae_dm_false_alarm_counter_statistics(hw); + rtl8821ae_dm_check_rssi_monitor(hw); + rtl8821ae_dm_dig(hw); + rtl8821ae_dm_cck_packet_detection_thresh(hw); + rtl8821ae_dm_refresh_rate_adaptive_mask(hw); + rtl8821ae_dm_refresh_basic_rate_mask(hw); + rtl8821ae_dm_check_edca_turbo(hw); + rtl8821ae_dm_dynamic_atc_switch(hw); + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw); + else + rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw); + rtl8821ae_dm_iq_calibrate(hw); + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; + rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n"); +} + +void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, + u8 *pdesc, u32 mac_id) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct fast_ant_training *pfat_table = &rtldm->fat_table; + __le32 *pdesc32 = (__le32 *)pdesc; + + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE) + return; + + if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) + set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h new file mode 100644 index 000000000..137ed735d --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_DM_H__ +#define __RTL8821AE_DM_H__ + +#define MAIN_ANT 0 +#define AUX_ANT 1 +#define MAIN_ANT_CG_TRX 1 +#define AUX_ANT_CG_TRX 0 +#define MAIN_ANT_CGCS_RX 0 +#define AUX_ANT_CGCS_RX 1 + +#define TXSCALE_TABLE_SIZE 37 + +/*RF REG LIST*/ +#define DM_REG_RF_MODE_11N 0x00 +#define DM_REG_RF_0B_11N 0x0B +#define DM_REG_CHNBW_11N 0x18 +#define DM_REG_T_METER_11N 0x24 +#define DM_REG_RF_25_11N 0x25 +#define DM_REG_RF_26_11N 0x26 +#define DM_REG_RF_27_11N 0x27 +#define DM_REG_RF_2B_11N 0x2B +#define DM_REG_RF_2C_11N 0x2C +#define DM_REG_RXRF_A3_11N 0x3C +#define DM_REG_T_METER_92D_11N 0x42 +#define DM_REG_T_METER_88E_11N 0x42 + +/*BB REG LIST*/ +/*PAGE 8 */ +#define DM_REG_BB_CTRL_11N 0x800 +#define DM_REG_RF_PIN_11N 0x804 +#define DM_REG_PSD_CTRL_11N 0x808 +#define DM_REG_TX_ANT_CTRL_11N 0x80C +#define DM_REG_BB_PWR_SAV5_11N 0x818 +#define DM_REG_CCK_RPT_FORMAT_11N 0x824 +#define DM_REG_RX_DEFUALT_A_11N 0x858 +#define DM_REG_RX_DEFUALT_B_11N 0x85A +#define DM_REG_BB_PWR_SAV3_11N 0x85C +#define DM_REG_ANTSEL_CTRL_11N 0x860 +#define DM_REG_RX_ANT_CTRL_11N 0x864 +#define DM_REG_PIN_CTRL_11N 0x870 +#define DM_REG_BB_PWR_SAV1_11N 0x874 +#define DM_REG_ANTSEL_PATH_11N 0x878 +#define DM_REG_BB_3WIRE_11N 0x88C +#define DM_REG_SC_CNT_11N 0x8C4 +#define DM_REG_PSD_DATA_11N 0x8B4 +/*PAGE 9*/ +#define DM_REG_ANT_MAPPING1_11N 0x914 +#define DM_REG_ANT_MAPPING2_11N 0x918 +/*PAGE A*/ +#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define DM_REG_CCK_CCA_11N 0xA0A +#define DM_REG_CCK_CCA_11AC 0xA0A +#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define DM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define DM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define DM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define DM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define DM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define DM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define DM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define DM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define DM_REG_CCK_FA_RST_11N 0xA2C +#define DM_REG_CCK_FA_MSB_11N 0xA58 +#define DM_REG_CCK_FA_LSB_11N 0xA5C +#define DM_REG_CCK_CCA_CNT_11N 0xA60 +#define DM_REG_BB_PWR_SAV4_11N 0xA74 +/*PAGE B */ +#define DM_REG_LNA_SWITCH_11N 0XB2C +#define DM_REG_PATH_SWITCH_11N 0XB30 +#define DM_REG_RSSI_CTRL_11N 0XB38 +#define DM_REG_CONFIG_ANTA_11N 0XB68 +#define DM_REG_RSSI_BT_11N 0XB9C +/*PAGE C */ +#define DM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define DM_REG_RX_PATH_11N 0xC04 +#define DM_REG_TRMUX_11N 0xC08 +#define DM_REG_OFDM_FA_RSTC_11N 0xC0C +#define DM_REG_RXIQI_MATRIX_11N 0xC14 +#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define DM_REG_IGI_A_11N 0xC50 +#define DM_REG_IGI_A_11AC 0xC50 +#define DM_REG_ANTDIV_PARA2_11N 0xC54 +#define DM_REG_IGI_B_11N 0xC58 +#define DM_REG_IGI_B_11AC 0xE50 +#define DM_REG_ANTDIV_PARA3_11N 0xC5C +#define DM_REG_BB_PWR_SAV2_11N 0xC70 +#define DM_REG_RX_OFF_11N 0xC7C +#define DM_REG_TXIQK_MATRIXA_11N 0xC80 +#define DM_REG_TXIQK_MATRIXB_11N 0xC88 +#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define DM_REG_ANTDIV_PARA1_11N 0xCA4 +#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/*PAGE D */ +#define DM_REG_OFDM_FA_RSTD_11N 0xD00 +#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8 +/*PAGE E */ +#define DM_REG_TXAGC_A_6_18_11N 0xE00 +#define DM_REG_TXAGC_A_24_54_11N 0xE04 +#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define DM_REG_FPGA0_IQK_11N 0xE28 +#define DM_REG_TXIQK_TONE_A_11N 0xE30 +#define DM_REG_RXIQK_TONE_A_11N 0xE34 +#define DM_REG_TXIQK_PI_A_11N 0xE38 +#define DM_REG_RXIQK_PI_A_11N 0xE3C +#define DM_REG_TXIQK_11N 0xE40 +#define DM_REG_RXIQK_11N 0xE44 +#define DM_REG_IQK_AGC_PTS_11N 0xE48 +#define DM_REG_IQK_AGC_RSP_11N 0xE4C +#define DM_REG_BLUETOOTH_11N 0xE6C +#define DM_REG_RX_WAIT_CCA_11N 0xE70 +#define DM_REG_TX_CCK_RFON_11N 0xE74 +#define DM_REG_TX_CCK_BBON_11N 0xE78 +#define DM_REG_OFDM_RFON_11N 0xE7C +#define DM_REG_OFDM_BBON_11N 0xE80 +#define DM_REG_TX2RX_11N 0xE84 +#define DM_REG_TX2TX_11N 0xE88 +#define DM_REG_RX_CCK_11N 0xE8C +#define DM_REG_RX_OFDM_11N 0xED0 +#define DM_REG_RX_WAIT_RIFS_11N 0xED4 +#define DM_REG_RX2RX_11N 0xED8 +#define DM_REG_STANDBY_11N 0xEDC +#define DM_REG_SLEEP_11N 0xEE0 +#define DM_REG_PMPD_ANAEN_11N 0xEEC + +/*MAC REG LIST*/ +#define DM_REG_BB_RST_11N 0x02 +#define DM_REG_ANTSEL_PIN_11N 0x4C +#define DM_REG_EARLY_MODE_11N 0x4D0 +#define DM_REG_RSSI_MONITOR_11N 0x4FE +#define DM_REG_EDCA_VO_11N 0x500 +#define DM_REG_EDCA_VI_11N 0x504 +#define DM_REG_EDCA_BE_11N 0x508 +#define DM_REG_EDCA_BK_11N 0x50C +#define DM_REG_TXPAUSE_11N 0x522 +#define DM_REG_RESP_TX_11N 0x6D8 +#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + +/*DIG Related*/ +#define DM_BIT_IGI_11N 0x0000007F +#define DM_BIT_IGI_11AC 0xFFFFFFFF + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 43 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_FA_UPPER 0x3e +#define DM_DIG_FA_LOWER 0x1e +#define DM_DIG_FA_TH0 200 +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 + +#define RXPATHSELECTION_SS_TH_LOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TXPWRTRACK_MAX_IDX 6 + +/* Dynamic ATC switch */ +#define ATC_STATUS_OFF 0x0 /* enable */ +#define ATC_STATUS_ON 0x1 /* disable */ +#define CFO_THRESHOLD_XTAL 10 /* kHz */ +#define CFO_THRESHOLD_ATC 80 /* kHz */ + +#define AVG_THERMAL_NUM_8812A 4 +#define TXPWR_TRACK_TABLE_SIZE 30 +#define MAX_PATH_NUM_8812A 2 +#define MAX_PATH_NUM_8821A 1 + +enum FAT_STATE { + FAT_NORMAL_STATE = 0, + FAT_TRAINING_STATE = 1, +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum pwr_track_control_method { + BBSWING, + TXAGC, + MIX_MODE +}; + +#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) +#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) +#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) +#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1) +#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1) +#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ + ((((struct rtl_priv *)(_priv))->mac80211.opmode == \ + NL80211_IFTYPE_ADHOC) ? \ + (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) : \ + (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb)) + +void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, + u8 *pdesc, u32 mac_id); +void rtl8821ae_dm_ant_sel_statistics(struct ieee80211_hw *hw, + u8 antsel_tr_mux, u32 mac_id, + u32 rx_pwdb_all); +void rtl8821ae_dm_fast_antenna_training_callback(unsigned long data); +void rtl8821ae_dm_init(struct ieee80211_hw *hw); +void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw); +void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi); +void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw); +void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw, + u8 type, u8 *pdirection, + u32 *poutwrite_val); +void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw); +void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca); +void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(struct ieee80211_hw *hw); +void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rf_path, + u8 channel_mapped_index); +void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rf_path, u8 channel_mapped_index); + +void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate); +u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate); +void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw); +void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c new file mode 100644 index 000000000..1ae56e15c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c @@ -0,0 +1,1901 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../core.h" +#include "../efuse.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "dm.h" + +static void _rtl8821ae_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + } +} + +static void _rtl8821ae_write_fw(struct ieee80211_hw *hw, + enum version_8821ae version, + u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *bufferptr = (u8 *)buffer; + u32 pagenums, remainsize; + u32 page, offset; + + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); + + rtl_fill_dummy(bufferptr, &size); + + pagenums = size / FW_8821AE_PAGE_SIZE; + remainsize = size % FW_8821AE_PAGE_SIZE; + + if (pagenums > 8) + pr_err("Page numbers should not greater then 8\n"); + + for (page = 0; page < pagenums; page++) { + offset = page * FW_8821AE_PAGE_SIZE; + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8821AE_PAGE_SIZE); + } + + if (remainsize) { + offset = pagenums * FW_8821AE_PAGE_SIZE; + page = pagenums; + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); + } +} + +static int _rtl8821ae_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8821AE_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_CHKSUM_RPT))); + + if (counter >= FW_8821AE_POLLING_TIMEOUT_COUNT) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "chksum report fail! REG_MCUFWDL:0x%08x .\n", + value32); + goto exit; + } + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + rtl8821ae_firmware_selfreset(hw); + + counter = 0; + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) + return 0; + + udelay(FW_8821AE_POLLING_DELAY); + } while (counter++ < FW_8821AE_POLLING_TIMEOUT_COUNT); + + pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", + value32); + +exit: + return err; +} + +static void _rtl8821ae_wait_for_h2c_cmd_finish(struct rtl_priv *rtlpriv) +{ + u8 val; + u16 count = 0; + + do { + val = rtl_read_byte(rtlpriv, REG_HMETFR); + mdelay(1); + count++; + } while ((val & 0x0F) && (count < 1000)); +} + +int rtl8821ae_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtlwifi_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + bool support_remote_wakeup; + enum version_8821ae version = rtlhal->version; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&support_remote_wakeup)); + + if (support_remote_wakeup) + _rtl8821ae_wait_for_h2c_cmd_finish(rtlpriv); + + if (buse_wake_on_wlan_fw) { + if (!rtlhal->wowlan_firmware) + return 1; + + pfwheader = + (struct rtlwifi_firmware_header *)rtlhal->wowlan_firmware; + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = (u8 *)rtlhal->wowlan_firmware; + fwsize = rtlhal->wowlan_fwsize; + } else { + if (!rtlhal->pfirmware) + return 1; + + pfwheader = + (struct rtlwifi_firmware_header *)rtlhal->pfirmware; + rtlhal->fw_version = le16_to_cpu(pfwheader->version); + rtlhal->fw_subversion = pfwheader->subversion; + pfwdata = (u8 *)rtlhal->pfirmware; + fwsize = rtlhal->fwsize; + } + + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "%s Firmware SIZE %d\n", + buse_wake_on_wlan_fw ? "Wowlan" : "Normal", fwsize); + + if (IS_FW_HEADER_EXIST_8812(pfwheader) || + IS_FW_HEADER_EXIST_8821(pfwheader)) { + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, + "Firmware Version(%d), Signature(%#x)\n", + pfwheader->version, pfwheader->signature); + + pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); + fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); + } + + if (rtlhal->mac_func_enable) { + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + rtl8821ae_firmware_selfreset(hw); + } + } + _rtl8821ae_enable_fw_download(hw, true); + _rtl8821ae_write_fw(hw, version, pfwdata, fwsize); + _rtl8821ae_enable_fw_download(hw, false); + + err = _rtl8821ae_fw_free_to_go(hw); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "Firmware is not ready to run!\n"); + } else { + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "Firmware is ready to run!\n"); + } + + return 0; +} + +#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1) +void rtl8821ae_set_fw_related_for_wowlan(struct ieee80211_hw *hw, + bool used_wowlan_fw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + /* 1. Before WoWLAN or After WOWLAN we need to re-download Fw. */ + if (rtl8821ae_download_fw(hw, used_wowlan_fw)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Re-Download Firmware failed!!\n"); + rtlhal->fw_ready = false; + return; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Re-Download Firmware Success !!\n"); + rtlhal->fw_ready = true; + + /* 2. Re-Init the variables about Fw related setting. */ + ppsc->fw_current_inpsmode = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + rtlhal->last_hmeboxnum = 0; +} +#endif + +static bool _rtl8821ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, + u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl8821ae_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, + u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum = 0; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp = 0; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + /*u8 wait_writeh2c_limmit = 100;*/ + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag = 0; + u8 idx = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! Wait to set..element_id(%d).\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", boxnum); + break; + } + + isfw_read = false; + u1b_tmp = rtl_read_byte(rtlpriv, REG_CR); + + if (u1b_tmp != 0xEA) { + isfw_read = true; + } else { + if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xEA || + rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xEA) + rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xFF); + } + + if (isfw_read) { + wait_h2c_limmit = 100; + isfw_read = + _rtl8821ae_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + /*wait until Fw read*/ + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); + break; + } + + udelay(10); + + isfw_read = + _rtl8821ae_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + } + + if (!isfw_read) { + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), + cmdbuffer + buf_index+3, cmd_len-3); + memcpy((u8 *)(boxcontent) + 1, + cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", cmd_len); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8821ae_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "rtl8821ae: error H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl8821ae_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); +} + +void rtl8821ae_firmware_selfreset(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3)))); + } else { + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(0)))); + } + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2)))); + udelay(50); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(3))); + } else { + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(0))); + } + + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2))); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "_8051Reset8812ae(): 8051 reset success .\n"); +} + +void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_8821AE_PWEMODE_LENGTH] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0, byte5 = 0; + u8 awake_intvl; /* DTIM = (awake_intvl - 1) */ + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false); + bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_lps_on(rtlpriv) : false); + + if (bt_ctrl_lps) + mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n", + mode, bt_ctrl_lps); + + switch (mode) { + case FW_PS_MIN_MODE: + rlbm = 0; + awake_intvl = 2; + break; + case FW_PS_MAX_MODE: + rlbm = 1; + awake_intvl = 2; + break; + case FW_PS_DTIM_MODE: + rlbm = 2; + awake_intvl = ppsc->reg_max_lps_awakeintvl; + /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period + * is only used in swlps. + */ + break; + default: + rlbm = 2; + awake_intvl = 4; + break; + } + + if (rtlpriv->mac80211.p2p) { + awake_intvl = 2; + rlbm = 1; + } + + if (mode == FW_PS_ACTIVE_MODE) { + byte5 = 0x40; + power_state = FW_PWR_STATE_ACTIVE; + } else { + if (bt_ctrl_lps) { + byte5 = btc_ops->btc_get_lps_val(rtlpriv); + power_state = btc_ops->btc_get_rpwm_val(rtlpriv); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from + * decreasing coex performance + */ + awake_intvl = 2; + rlbm = 2; + } + } else { + byte5 = 0x40; + power_state = FW_PWR_STATE_RF_OFF; + } + } + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, + bt_ctrl_lps ? 0 : + ((rtlpriv->mac80211.p2p) ? + ppsc->smart_ps : 1)); + SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, + awake_intvl); + SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_8821AE_PWEMODE_LENGTH); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode, + H2C_8821AE_PWEMODE_LENGTH); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_SETPWRMODE, + H2C_8821AE_PWEMODE_LENGTH, + u1_h2c_set_pwrmode); +} + +void rtl8821ae_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, + u8 mstatus) +{ + u8 parm[3] = { 0, 0, 0 }; + /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect + * bit1=0-->update Media Status to MACID + * bit1=1-->update Media Status from MACID to MACID_End + * parm[1]: MACID, if this is INFRA_STA, MacID = 0 + * parm[2]: MACID_End + */ + + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_MSRRPT, 3, parm); +} + +void rtl8821ae_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, + u8 ap_offload_enable) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 u1_apoffload_parm[H2C_8821AE_AP_OFFLOAD_LENGTH] = { 0 }; + + SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable); + SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid); + SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0); + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_AP_OFFLOAD, + H2C_8821AE_AP_OFFLOAD_LENGTH, + u1_apoffload_parm); +} + +void rtl8821ae_set_fw_wowlan_mode(struct ieee80211_hw *hw, bool func_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 fw_wowlan_info[H2C_8821AE_WOWLAN_LENGTH] = {0}; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "enable(%d)\n", func_en); + + SET_8812_H2CCMD_WOWLAN_FUNC_ENABLE(fw_wowlan_info, + (func_en ? true : false)); + + SET_8812_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(fw_wowlan_info, + ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) ? 1 : 0)); + SET_8812_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(fw_wowlan_info, + ((ppsc->wo_wlan_mode & WAKE_ON_MAGIC_PACKET) ? 1 : 0)); + + SET_8812_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(fw_wowlan_info, 0); + SET_8812_H2CCMD_WOWLAN_ALL_PKT_DROP(fw_wowlan_info, false); + SET_8812_H2CCMD_WOWLAN_GPIO_ACTIVE(fw_wowlan_info, 0); + SET_8812_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(fw_wowlan_info, 1); + SET_8812_H2CCMD_WOWLAN_GPIONUM(fw_wowlan_info, 0); + SET_8812_H2CCMD_WOWLAN_GPIO_DURATION(fw_wowlan_info, 0); + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_DMESG, + "wowlan mode: cmd 0x80: Content:\n", + fw_wowlan_info, H2C_8821AE_WOWLAN_LENGTH); + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_WO_WLAN, + H2C_8821AE_WOWLAN_LENGTH, + fw_wowlan_info); +} + +void rtl8821ae_set_fw_remote_wake_ctrl_cmd(struct ieee80211_hw *hw, + u8 enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 remote_wake_ctrl_parm[H2C_8821AE_REMOTE_WAKE_CTRL_LEN] = {0}; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "enable=%d, ARP offload=%d, GTK offload=%d\n", + enable, ppsc->arp_offload_enable, ppsc->gtk_offload_enable); + + SET_8812_H2CCMD_REMOTE_WAKECTRL_ENABLE(remote_wake_ctrl_parm, enable); + SET_8812_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(remote_wake_ctrl_parm, + (ppsc->arp_offload_enable ? 1 : 0)); + SET_8812_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(remote_wake_ctrl_parm, + (ppsc->gtk_offload_enable ? 1 : 0)); + SET_8812_H2CCMD_REMOTE_WAKE_CTRL_REALWOWV2_EN(remote_wake_ctrl_parm, + (rtlhal->real_wow_v2_enable ? 1 : 0)); + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "remote_wake_ctrl: cmd 0x4: Content:\n", + remote_wake_ctrl_parm, H2C_8821AE_REMOTE_WAKE_CTRL_LEN); + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_REMOTE_WAKE_CTRL, + H2C_8821AE_REMOTE_WAKE_CTRL_LEN, + remote_wake_ctrl_parm); +} + +void rtl8821ae_set_fw_keep_alive_cmd(struct ieee80211_hw *hw, + bool func_en) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 keep_alive_info[H2C_8821AE_KEEP_ALIVE_CTRL_LENGTH] = {0}; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Enable(%d)\n", func_en); + + SET_8812_H2CCMD_KEEP_ALIVE_ENABLE(keep_alive_info, func_en); + /* 1: the period is controled by driver, 0: by Fw default */ + SET_8812_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(keep_alive_info, 1); + SET_8812_H2CCMD_KEEP_ALIVE_PERIOD(keep_alive_info, 10); /* 10 sec */ + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "keep alive: cmd 0x3: Content:\n", + keep_alive_info, H2C_8821AE_KEEP_ALIVE_CTRL); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_KEEP_ALIVE_CTRL, + H2C_8821AE_KEEP_ALIVE_CTRL_LENGTH, + keep_alive_info); +} + +void rtl8821ae_set_fw_disconnect_decision_ctrl_cmd(struct ieee80211_hw *hw, + bool enabled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 parm[H2C_8821AE_DISCONNECT_DECISION_CTRL_LEN] = {0}; + + SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_ENABLE(parm, enabled); + SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_USER_SETTING(parm, 1); + SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_CHECK_PERIOD(parm, 30); + SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_TRYPKT_NUM(parm, 3); + + RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE, + "disconnect_decision_ctrl: cmd 0x4: Content:\n", + parm, H2C_8821AE_DISCONNECT_DECISION_CTRL_LEN); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_DISCONNECT_DECISION, + H2C_8821AE_DISCONNECT_DECISION_CTRL_LEN, parm); +} + +void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_security *sec = &rtlpriv->sec; + u8 remote_wakeup_sec_info[H2C_8821AE_AOAC_GLOBAL_INFO_LEN] = {0}; + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "PairwiseEncAlgorithm=%d, GroupEncAlgorithm=%d\n", + sec->pairwise_enc_algorithm, sec->group_enc_algorithm); + + SET_8812_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG( + remote_wakeup_sec_info, + sec->pairwise_enc_algorithm); + SET_8812_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(remote_wakeup_sec_info, + sec->group_enc_algorithm); + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_AOAC_GLOBAL_INFO, + H2C_8821AE_AOAC_GLOBAL_INFO_LEN, + remote_wakeup_sec_info); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_TRACE, + "rtl8821ae_set_global_info: cmd 0x82:\n", + remote_wakeup_sec_info, H2C_8821AE_AOAC_GLOBAL_INFO_LEN); +} + +#define BEACON_PG 0 +#define PSPOLL_PG 1 +#define NULL_PG 2 +#define QOSNULL_PG 3 +#define BT_QOSNULL_PG 4 +#define ARPRESP_PG 5 +#define REMOTE_PG 6 +#define GTKEXT_PG 7 + +#define TOTAL_RESERVED_PKT_LEN_8812 4096 +#define TOTAL_RESERVED_PKT_LEN_8821 2048 + +static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = { + /* page 0: beacon */ + 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xe0, 0x4c, 0x02, 0xe2, 0x64, + 0x40, 0x16, 0x9f, 0x23, 0xd4, 0x46, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x20, 0x04, 0x00, 0x06, 0x64, 0x6c, + 0x69, 0x6e, 0x6b, 0x31, 0x01, 0x08, 0x82, 0x84, + 0x8b, 0x96, 0x0c, 0x18, 0x30, 0x48, 0x03, 0x01, + 0x0b, 0x06, 0x02, 0x00, 0x00, 0x2a, 0x01, 0x8b, + 0x32, 0x04, 0x12, 0x24, 0x60, 0x6c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x28, 0x8c, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 1: ps-poll */ + 0xa4, 0x10, 0x01, 0xc0, 0x40, 0x16, 0x9f, 0x23, + 0xd4, 0x46, 0x00, 0xe0, 0x4c, 0x02, 0xe2, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x28, 0x8c, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 2: null data */ + 0x48, 0x01, 0x00, 0x00, 0x40, 0x16, 0x9f, 0x23, + 0xd4, 0x46, 0x00, 0xe0, 0x4c, 0x02, 0xe2, 0x64, + 0x40, 0x16, 0x9f, 0x23, 0xd4, 0x46, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 3: qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 4: BT qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 5~7 is for wowlan */ + /* page 5: ARP resp */ + 0x08, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06, + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, + 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 6: H2C_REMOTE_WAKE_CTRL_INFO */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 7: Rsvd GTK extend memory (zero memory) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u8 reserved_page_packet_8812[TOTAL_RESERVED_PKT_LEN_8812] = { + /* page 0: beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x20, 0x04, 0x00, 0x03, 0x32, 0x31, + 0x35, 0x01, 0x08, 0x82, 0x84, 0x8B, 0x96, 0x0C, + 0x12, 0x18, 0x24, 0x03, 0x01, 0x01, 0x06, 0x02, + 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, 0x04, 0x30, + 0x48, 0x60, 0x6C, 0x2D, 0x1A, 0xED, 0x09, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, + 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, 0x02, 0x02, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 1: ps-poll */ + 0xA4, 0x10, 0x09, 0xC0, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 2: null data */ + 0x48, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 3: Qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 4: BT Qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 5~7 is for wowlan */ + /* page 5: ARP resp */ + 0x08, 0x01, 0x00, 0x00, 0x84, 0xC9, 0XB2, 0xA7, + 0XB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0XB2, 0xA7, 0XB3, 0x6E, 0x00, 0x00, + 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06, + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, + 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 6: H2C_REMOTE_WAKE_CTRL_INFO */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* page 7: Rsvd GTK extend memory (zero memory) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool b_dl_finished, bool dl_whole_packets) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[5] = { 0 }; + u8 u1rsvdpageloc2[7] = { 0 }; + bool b_dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *qosnull; + u8 *btqosnull; + u8 *arpresp; + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet_8812[BEACON_PG * 512]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + if (b_dl_finished) { + totalpacketlen = 512 - 40; + goto out; + } + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet_8812[PSPOLL_PG * 512]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet_8812[NULL_PG * 512]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) Qos null data + *---------------------------------------------------------- + */ + qosnull = &reserved_page_packet_8812[QOSNULL_PG * 512]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOSNULL_PG); + + /*--------------------------------------------------------- + * (5) BT Qos null data + *---------------------------------------------------------- + */ + btqosnull = &reserved_page_packet_8812[BT_QOSNULL_PG * 512]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOSNULL_PG); + + if (!dl_whole_packets) { + totalpacketlen = 512 * (BT_QOSNULL_PG + 1) - 40; + goto out; + } + /*--------------------------------------------------------- + * (6) ARP Resp + *---------------------------------------------------------- + */ + arpresp = &reserved_page_packet_8812[ARPRESP_PG * 512]; + SET_80211_HDR_ADDRESS1(arpresp, mac->bssid); + SET_80211_HDR_ADDRESS2(arpresp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(arpresp, mac->bssid); + + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1rsvdpageloc2, ARPRESP_PG); + + /*--------------------------------------------------------- + * (7) Remote Wake Ctrl + *---------------------------------------------------------- + */ + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1rsvdpageloc2, + REMOTE_PG); + + /*--------------------------------------------------------- + * (8) GTK Ext Memory + *---------------------------------------------------------- + */ + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1rsvdpageloc2, GTKEXT_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN_8812 - 40; + +out: + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8812ae_set_fw_rsvdpagepkt(): packet data\n", + &reserved_page_packet_8812[0], totalpacketlen); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet_8812, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (!b_dl_finished && b_dlok) { + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", u1rsvdpageloc, 5); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + if (dl_whole_packets) { + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "wowlan H2C_RSVDPAGE:\n", u1rsvdpageloc2, 7); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_AOAC_RSVDPAGE, + sizeof(u1rsvdpageloc2), u1rsvdpageloc2); + } + } + + if (!b_dlok) + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool b_dl_finished, bool dl_whole_packets) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1rsvdpageloc[5] = { 0 }; + u8 u1rsvdpageloc2[7] = { 0 }; + bool b_dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *qosnull; + u8 *btqosnull; + u8 *arpresp; + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet_8821[BEACON_PG * 256]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + if (b_dl_finished) { + totalpacketlen = 256 - 40; + goto out; + } + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet_8821[PSPOLL_PG * 256]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *---------------------------------------------------------i + */ + nullfunc = &reserved_page_packet_8821[NULL_PG * 256]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + + /*--------------------------------------------------------- + * (4) Qos null data + *---------------------------------------------------------- + */ + qosnull = &reserved_page_packet_8821[QOSNULL_PG * 256]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOSNULL_PG); + + /*--------------------------------------------------------- + * (5) Qos null data + *---------------------------------------------------------- + */ + btqosnull = &reserved_page_packet_8821[BT_QOSNULL_PG * 256]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOSNULL_PG); + + if (!dl_whole_packets) { + totalpacketlen = 256 * (BT_QOSNULL_PG + 1) - 40; + goto out; + } + /*--------------------------------------------------------- + * (6) ARP Resp + *---------------------------------------------------------- + */ + arpresp = &reserved_page_packet_8821[ARPRESP_PG * 256]; + SET_80211_HDR_ADDRESS1(arpresp, mac->bssid); + SET_80211_HDR_ADDRESS2(arpresp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(arpresp, mac->bssid); + + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1rsvdpageloc2, ARPRESP_PG); + + /*--------------------------------------------------------- + * (7) Remote Wake Ctrl + *---------------------------------------------------------- + */ + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1rsvdpageloc2, + REMOTE_PG); + + /*--------------------------------------------------------- + * (8) GTK Ext Memory + *---------------------------------------------------------- + */ + SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1rsvdpageloc2, GTKEXT_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN_8821 - 40; + +out: + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8821ae_set_fw_rsvdpagepkt(): packet data\n", + &reserved_page_packet_8821[0], totalpacketlen); + + skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; + skb_put_data(skb, &reserved_page_packet_8821, totalpacketlen); + + rtstatus = rtl_cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (!b_dl_finished && b_dlok) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", u1rsvdpageloc, 5); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RSVDPAGE, + sizeof(u1rsvdpageloc), u1rsvdpageloc); + if (dl_whole_packets) { + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "wowlan H2C_RSVDPAGE:\n", + u1rsvdpageloc2, 7); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_AOAC_RSVDPAGE, + sizeof(u1rsvdpageloc2), + u1rsvdpageloc2); + } + } + + if (!b_dlok) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); + } +} + +/*Should check FW support p2p or not.*/ +static void rtl8821ae_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = { ctwindow}; + + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_P2P_PS_CTW_CMD, 1, + u1_ctwindow_period); +} + +void rtl8821ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info; + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl8821ae_set_p2p_ctw_period_cmd(hw, ctwindow); + } + + /* hw only support 2 set of NoA */ + for (i = 0 ; i < p2pinfo->noa_num ; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low+(50*1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->offload_en = 1; + + if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8821ae_fill_h2c_cmd(hw, + H2C_8821AE_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); +} + +void rtl8821ae_c2h_ra_report_handler(struct ieee80211_hw *hw, + u8 *cmd_buf, u8 cmd_len) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 rate = cmd_buf[0] & 0x3F; + + rtlhal->current_ra_rate = rtl8821ae_hw_rate_to_mrate(hw, rate); + + rtl8821ae_dm_update_init_rate(hw, rate); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h new file mode 100644 index 000000000..af8d17b9e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE__FW__H__ +#define __RTL8821AE__FW__H__ +#include "def.h" + +#define FW_8821AE_SIZE 0x8000 +#define FW_8821AE_START_ADDRESS 0x1000 +#define FW_8821AE_END_ADDRESS 0x5FFF +#define FW_8821AE_PAGE_SIZE 4096 +#define FW_8821AE_POLLING_DELAY 5 +#define FW_8821AE_POLLING_TIMEOUT_COUNT 6000 + +#define IS_FW_HEADER_EXIST_8812(_pfwhdr) \ + ((le16_to_cpu(_pfwhdr->signature) & 0xFFF0) == 0x9500) + +#define IS_FW_HEADER_EXIST_8821(_pfwhdr) \ + ((le16_to_cpu(_pfwhdr->signature) & 0xFFF0) == 0x2100) + +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_8821AE_RSVDPAGE_LOC_LEN 5 +#define H2C_8821AE_PWEMODE_LENGTH 7 +#define H2C_8821AE_JOINBSSRPT_LENGTH 1 +#define H2C_8821AE_AP_OFFLOAD_LENGTH 3 +#define H2C_8821AE_WOWLAN_LENGTH 3 +#define H2C_8821AE_KEEP_ALIVE_CTRL_LENGTH 3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_8821AE_REMOTE_WAKE_CTRL_LEN 1 +#else +#define H2C_8821AE_REMOTE_WAKE_CTRL_LEN 3 +#endif +#define H2C_8821AE_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_8821AE_AOAC_RSVDPAGE_LOC_LEN 7 +#define H2C_8821AE_DISCONNECT_DECISION_CTRL_LEN 3 + +/* Fw PS state for RPWM. +*BIT[2:0] = HW state + +*BIT[3] = Protocol PS state, +1: register active state , +0: register sleep state + +*BIT[4] = sub-state +*/ +#define FW_PS_GO_ON BIT(0) +#define FW_PS_TX_NULL BIT(1) +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_DPS BIT(0) +#define FW_PS_LCLK (FW_PS_DPS) +#define FW_PS_RF_OFF BIT(1) +#define FW_PS_ALL_ON BIT(2) +#define FW_PS_ST_ACTIVE BIT(3) +#define FW_PS_ISR_ENABLE BIT(4) +#define FW_PS_IMR_ENABLE BIT(5) + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + + /* 8821AE RPWM value*/ + /* BIT[0] = 1: 32k, 0: 40M*/ + /* 32k*/ +#define FW_PS_CLOCK_OFF BIT(0) +/*40M*/ +#define FW_PS_CLOCK_ON 0 + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/ +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) +#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x)) +#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x)) +#define FW_PS_ISR_VAL(x) ((x) & 0x70) +#define FW_PS_IMR_MASK(x) ((x) & 0xDF) +#define FW_PS_KEEP_IMR(x) ((x) & 0x20) + +#define FW_PS_STATE_S0 (FW_PS_DPS) +#define FW_PS_STATE_S1 (FW_PS_LCLK) +#define FW_PS_STATE_S2 (FW_PS_RF_OFF) +#define FW_PS_STATE_S3 (FW_PS_ALL_ON) +#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON)) + /* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/ +#define FW_PS_STATE_ALL_ON_8821AE (FW_PS_CLOCK_ON) + /* (FW_PS_RF_ON)*/ +#define FW_PS_STATE_RF_ON_8821AE (FW_PS_CLOCK_ON) + /* 0x0*/ +#define FW_PS_STATE_RF_OFF_8821AE (FW_PS_CLOCK_ON) + /* (FW_PS_STATE_RF_OFF)*/ +#define FW_PS_STATE_RF_OFF_LOW_PWR_8821AE (FW_PS_CLOCK_OFF) + +#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4) +#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3) +#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2) +#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1) + +/* For 8821AE H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) +#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON)) +#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON)) +#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE)) +#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40) + +#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) + +#define IS_IN_LOW_POWER_STATE_8821AE(__state) \ + (FW_PS_STATE(__state) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8821a_h2c_cmd { + H2C_8821AE_RSVDPAGE = 0, + H2C_8821AE_MSRRPT = 1, + H2C_8821AE_SCAN = 2, + H2C_8821AE_KEEP_ALIVE_CTRL = 3, + H2C_8821AE_DISCONNECT_DECISION = 4, + H2C_8821AE_INIT_OFFLOAD = 6, + H2C_8821AE_AP_OFFLOAD = 8, + H2C_8821AE_BCN_RSVDPAGE = 9, + H2C_8821AE_PROBERSP_RSVDPAGE = 10, + + H2C_8821AE_SETPWRMODE = 0x20, + H2C_8821AE_PS_TUNING_PARA = 0x21, + H2C_8821AE_PS_TUNING_PARA2 = 0x22, + H2C_8821AE_PS_LPS_PARA = 0x23, + H2C_8821AE_P2P_PS_OFFLOAD = 024, + + H2C_8821AE_WO_WLAN = 0x80, + H2C_8821AE_REMOTE_WAKE_CTRL = 0x81, + H2C_8821AE_AOAC_GLOBAL_INFO = 0x82, + H2C_8821AE_AOAC_RSVDPAGE = 0x83, + + H2C_RSSI_21AE_REPORT = 0x42, + H2C_8821AE_RA_MASK = 0x40, + H2C_8821AE_SELECTIVE_SUSPEND_ROF_CMD, + H2C_8821AE_P2P_PS_MODE, + H2C_8821AE_PSD_RESULT, + /*Not defined CTW CMD for P2P yet*/ + H2C_8821AE_P2P_PS_CTW_CMD, + MAX_8821AE_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_8812_H2CCMD_WOWLAN_FUNC_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(0)) +#define SET_8812_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(1)) +#define SET_8812_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(2)) +#define SET_8812_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(3)) +#define SET_8812_H2CCMD_WOWLAN_ALL_PKT_DROP(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(4)) +#define SET_8812_H2CCMD_WOWLAN_GPIO_ACTIVE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(5)) +#define SET_8812_H2CCMD_WOWLAN_REKEY_WAKE_UP(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(6)) +#define SET_8812_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(7)) +#define SET_8812_H2CCMD_WOWLAN_GPIONUM(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value +#define SET_8812_H2CCMD_WOWLAN_GPIO_DURATION(__cmd, __value) \ + *(u8 *)(__cmd + 2) = __value + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + *(u8 *)__ph2ccmd = __val +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__cmd, __value) \ + u8p_replace_bits(__cmd + 1, __value, GENMASK(3, 0)) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__cmd, __value) \ + u8p_replace_bits(__cmd + 1, __value, GENMASK(7, 4)) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__cmd, __value) \ + *(u8 *)(__cmd + 2) = __value +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__cmd, __value) \ + *(u8 *)(__cmd + 3) = __value +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__cmd, __value) \ + *(u8 *)(__cmd + 4) = __value +#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__cmd, __value) \ + *(u8 *)(__cmd + 5) = __value + +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 1) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 2) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 3) = __val +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \ + *(u8 *)(__ph2ccmd + 4) = __val + +/* _MEDIA_STATUS_RPT_PARM_CMD1 */ +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(0)) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(1)) + +/* AP_OFFLOAD */ +#define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \ + *(u8 *)__cmd = __value +#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value +#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__cmd, __value) \ + *(u8 *)(__cmd + 2) = __value +#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__cmd, __value) \ + *(u8 *)(__cmd + 3) = __value + +/* Keep Alive Control*/ +#define SET_8812_H2CCMD_KEEP_ALIVE_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(0)) +#define SET_8812_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(1)) +#define SET_8812_H2CCMD_KEEP_ALIVE_PERIOD(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value + +/*REMOTE_WAKE_CTRL */ +#define SET_8812_H2CCMD_REMOTE_WAKECTRL_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(0)) +#define SET_8812_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__cmd, __value)\ + u8p_replace_bits(__cmd, __value, BIT(1)) +#define SET_8812_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__cmd, __value)\ + u8p_replace_bits(__cmd, __value, BIT(2)) +#define SET_8812_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__cmd, __value)\ + u8p_replace_bits(__cmd, __value, BIT(3)) +#define SET_8812_H2CCMD_REMOTE_WAKE_CTRL_REALWOWV2_EN(__cmd, __value)\ + u8p_replace_bits(__cmd, __value, BIT(6)) + +/* GTK_OFFLOAD */ +#define SET_8812_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__cmd, __value)\ + *(u8 *)__cmd = __value +#define SET_8812_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value + +/* AOAC_RSVDPAGE_LOC */ +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(__cmd, __value) \ + *(u8 *)__cmd = __value +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__cmd, __value) \ + *(u8 *)(__cmd + 1) = __value +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__cmd, __value)\ + *(u8 *)(__cmd + 2) = __value +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__cmd, __value) \ + *(u8 *)(__cmd + 3) = __value +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__cmd, __value) \ + *(u8 *)(__cmd + 4) = __value +#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(__cmd, __value) \ + *(u8 *)(__cmd + 5) = __value + +/* Disconnect_Decision_Control */ +#define SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_ENABLE(__cmd, __value) \ + u8p_replace_bits(__cmd, __value, BIT(0)) +#define SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_USER_SETTING(__cmd, __value)\ + u8p_replace_bits(__cmd, __value, BIT(1)) +#define SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_CHECK_PERIOD(__cmd, __value)\ + *(u8 *)(__cmd + 1) = __value +#define SET_8812_H2CCMD_DISCONNECT_DECISION_CTRL_TRYPKT_NUM(__cmd, __value)\ + *(u8 *)(__cmd + 2) = __value + +int rtl8821ae_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw); +#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1) +void rtl8821ae_set_fw_related_for_wowlan(struct ieee80211_hw *hw, + bool used_wowlan_fw); + +#endif +void rtl8821ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer); +void rtl8821ae_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8821ae_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, + u8 mstatus); +void rtl8821ae_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, + u8 ap_offload_enable); +void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool b_dl_finished, bool dl_whole_packet); +void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool b_dl_finished, bool dl_whole_packet); +void rtl8821ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, + u8 p2p_ps_state); +void rtl8821ae_set_fw_wowlan_mode(struct ieee80211_hw *hw, bool func_en); +void rtl8821ae_set_fw_remote_wake_ctrl_cmd(struct ieee80211_hw *hw, + u8 enable); +void rtl8821ae_set_fw_keep_alive_cmd(struct ieee80211_hw *hw, bool func_en); +void rtl8821ae_set_fw_disconnect_decision_ctrl_cmd(struct ieee80211_hw *hw, + bool enabled); +void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw); +void rtl8821ae_c2h_ra_report_handler(struct ieee80211_hw *hw, + u8 *cmd_buf, u8 cmd_len); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c new file mode 100644 index 000000000..1ba53e671 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -0,0 +1,4028 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "hw.h" +#include "../pwrseqcmd.h" +#include "pwrseq.h" +#include "../btcoexist/rtl_btc.h" + +#define LLT_CONFIG 5 + +static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; + unsigned long flags; + + skb_queue_head_init(&free_list); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + dma_unmap_single(&rtlpci->pdev->dev, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, + true, HW_DESC_TXBUFF_ADDR), + skb->len, DMA_TO_DEVICE); + __skb_queue_tail(&free_list, skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); +} + +static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); +} + +void _rtl8821ae_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +void _rtl8821ae_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8821ae_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8821ae_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl8821ae_set_fw_clock_on(struct ieee80211_hw *hw, + u8 rpwm_val, bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool b_support_remote_wake_up; + u32 count = 0, isr_regaddr, content; + bool b_schedule_timer = b_need_turn_off_ckk; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&b_support_remote_wake_up)); + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + goto change_done; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + goto change_done; + } + } +change_done: + if (IS_IN_LOW_POWER_STATE_8821AE(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_8821AE; + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! Set rtlhal->FwPSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (b_schedule_timer) + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl8821ae_set_fw_clock_off(struct ieee80211_hw *hw, + u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool b_schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + b_schedule_timer = true; + break; + } + } + + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != + FW_PS_STATE_RF_OFF_LOW_PWR_8821AE) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } +} + +static void _rtl8821ae_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= (FW_PS_STATE_RF_OFF_8821AE | FW_PS_ACK); + _rtl8821ae_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl8821ae_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON_8821AE|FW_PS_ACK);/* RF on */ + _rtl8821ae_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON_8821AE; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } +} + +static void _rtl8821ae_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_8821AE; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl8821ae_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF_8821AE; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } +} + +static void _rtl8821ae_download_rsvd_page(struct ieee80211_hw *hw, + bool dl_whole_packets) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 tmp_regcr, tmp_reg422, bcnvalid_reg; + u8 count = 0, dlbcn_count = 0; + bool send_beacon = false; + + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr | BIT(0))); + + _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(4), 0); + + tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + if (tmp_reg422 & BIT(6)) + send_beacon = true; + + do { + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2); + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, + (bcnvalid_reg | BIT(0))); + _rtl8821ae_return_beacon_queue_skb(hw); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_set_fw_rsvdpagepkt(hw, false, + dl_whole_packets); + else + rtl8821ae_set_fw_rsvdpagepkt(hw, false, + dl_whole_packets); + + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2); + count = 0; + while (!(bcnvalid_reg & BIT(0)) && count < 20) { + count++; + udelay(10); + bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2); + } + dlbcn_count++; + } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + + if (!(bcnvalid_reg & BIT(0))) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Download RSVD page failed!\n"); + if (bcnvalid_reg & BIT(0) && rtlhal->enter_pnp_sleep) { + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, bcnvalid_reg | BIT(0)); + _rtl8821ae_return_beacon_queue_skb(hw); + if (send_beacon) { + dlbcn_count = 0; + do { + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, + bcnvalid_reg | BIT(0)); + + _rtl8821ae_return_beacon_queue_skb(hw); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_set_fw_rsvdpagepkt(hw, true, + false); + else + rtl8821ae_set_fw_rsvdpagepkt(hw, true, + false); + + /* check rsvd page download OK. */ + bcnvalid_reg = rtl_read_byte(rtlpriv, + REG_TDECTRL + 2); + count = 0; + while (!(bcnvalid_reg & BIT(0)) && count < 20) { + count++; + udelay(10); + bcnvalid_reg = + rtl_read_byte(rtlpriv, + REG_TDECTRL + 2); + } + dlbcn_count++; + } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + + if (!(bcnvalid_reg & BIT(0))) + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "2 Download RSVD page failed!\n"); + } + } + + if (bcnvalid_reg & BIT(0)) + rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0)); + + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (send_beacon) + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422); + + if (!rtlhal->enter_pnp_sleep) { + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0)))); + } +} + +void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_ETHER_ADDR: + *((u32 *)(val)) = rtl_read_dword(rtlpriv, REG_MACID); + *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_MACID + 4); + break; + case HW_VAR_BSSID: + *((u32 *)(val)) = rtl_read_dword(rtlpriv, REG_BSSID); + *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_BSSID+4); + break; + case HW_VAR_MEDIA_STATUS: + val[0] = rtl_read_byte(rtlpriv, MSR) & 0x3; + break; + case HW_VAR_SLOT_TIME: + *((u8 *)(val)) = mac->slot_time; + break; + case HW_VAR_BEACON_INTERVAL: + *((u16 *)(val)) = rtl_read_word(rtlpriv, REG_BCN_INTERVAL); + break; + case HW_VAR_ATIM_WINDOW: + *((u16 *)(val)) = rtl_read_word(rtlpriv, REG_ATIMWND); + break; + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfstate; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, + HW_VAR_RF_STATE, + (u8 *)(&rfstate)); + if (rfstate == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + break; } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + + *((u64 *)(val)) = tsf; + + break; } + case HAL_DEF_WOWLAN: + if (ppsc->wo_wlan_mode) + *((bool *)(val)) = true; + else + *((bool *)(val)) = false; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 b_rate_cfg = ((u16 *)val)[0]; + b_rate_cfg = b_rate_cfg & 0x15f; + rtl_write_word(rtlpriv, REG_RRSR, b_rate_cfg); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[0]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + + rtl_write_byte(rtlpriv, REG_RESP_SIFS_OFDM + 1, val[0]); + rtl_write_byte(rtlpriv, REG_RESP_SIFS_OFDM, val[0]); + break; + case HW_VAR_R2T_SIFS: + rtl_write_byte(rtlpriv, REG_RESP_SIFS_OFDM + 1, val[0]); + break; + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + break; } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + + reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2); + if (short_preamble) { + reg_tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, + reg_tmp); + } else { + reg_tmp &= (~BIT(1)); + rtl_write_byte(rtlpriv, + REG_TRXPTCL_CTL + 2, + reg_tmp); + } + break; } + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); + break; + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + + min_spacing_to_set = *((u8 *)val); + if (min_spacing_to_set <= 7) { + + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + + *val = min_spacing_to_set; + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *)val); + mac->min_space_cfg |= (density_to_set << 3); + + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + + break; } + case HW_VAR_AMPDU_FACTOR:{ + u32 ampdu_len = (*((u8 *)val)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + if (ampdu_len < VHT_AGG_SIZE_128K) + ampdu_len = + (0x2000 << (*((u8 *)val))) - 1; + else + ampdu_len = 0x1ffff; + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + if (ampdu_len < HT_AGG_SIZE_64K) + ampdu_len = + (0x2000 << (*((u8 *)val))) - 1; + else + ampdu_len = 0xffff; + } + ampdu_len |= BIT(31); + + rtl_write_dword(rtlpriv, + REG_AMPDU_MAX_LENGTH_8812, ampdu_len); + break; } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *)val); + + rtl8821ae_dm_init_edca_turbo(hw); + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + break; } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *)val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&mac->ac[0].aifs); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", + e_aci); + break; + } + } + + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; } + case HW_VAR_RCR: + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + break; + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl8821ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val; + + rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); + udelay(1); + + if (rpwm_val & BIT(7)) { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + (*(u8 *)val)); + } else { + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, + ((*(u8 *)val) | BIT(7))); + } + + break; } + case HW_VAR_H2C_FW_PWRMODE: + rtl8821ae_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_INIT_RTS_RATE: + break; + case HW_VAR_RESUME_CLK_ON: + _rtl8821ae_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION:{ + bool b_enter_fwlps = *((bool *)val); + + if (b_enter_fwlps) + _rtl8821ae_fwlps_enter(hw); + else + _rtl8821ae_fwlps_leave(hw); + break; } + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *)val); + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, + NULL); + _rtl8821ae_download_rsvd_page(hw, false); + } + rtl8821ae_set_fw_media_status_rpt_cmd(hw, mstatus); + + break; } + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl8821ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_AID:{ + u16 u2btmp; + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + break; } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl8821ae_stop_tx_beacon(hw); + + _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl8821ae_resume_tx_beacon(hw); + break; } + case HW_VAR_NAV_UPPER: { + u32 us_nav_upper = *(u32 *)val; + + if (us_nav_upper > HAL_92C_NAV_UPPER_UNIT * 0xFF) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, + "The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", + us_nav_upper, HAL_92C_NAV_UPPER_UNIT); + break; + } + rtl_write_byte(rtlpriv, REG_NAV_UPPER, + ((u8)((us_nav_upper + + HAL_92C_NAV_UPPER_UNIT - 1) / + HAL_92C_NAV_UPPER_UNIT))); + break; } + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_KEEP_ALIVE_CTRL, 2, + array); + break; } + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", variable); + break; + } +} + +static bool _rtl8821ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | + _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + + if (count > POLLING_LLT_THRESHOLD) { + pr_err("Failed to polling write LLT done at address %d!\n", + address); + status = false; + break; + } + } while (++count); + + return status; +} + +static bool _rtl8821ae_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u32 rqpn; + u8 maxpage; + bool status; + + maxpage = 255; + txpktbuf_bndy = 0xF7; + rqpn = 0x80e60808; + + rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, MAX_RX_DMA_BUFFER_SIZE - 1); + + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + rtl_write_byte(rtlpriv, REG_PBP, 0x31); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl8821ae_llt_write(hw, i, i + 1); + if (!status) + return status; + } + + status = _rtl8821ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + for (i = txpktbuf_bndy; i < maxpage; i++) { + status = _rtl8821ae_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + status = _rtl8821ae_llt_write(hw, maxpage, txpktbuf_bndy); + if (!status) + return status; + + rtl_write_dword(rtlpriv, REG_RQPN, rqpn); + + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00); + + return true; +} + +static void _rtl8821ae_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_sw_led_on(hw, pin0); + else + rtl8821ae_sw_led_on(hw, pin0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_sw_led_on(hw, pin0); + else + rtl8821ae_sw_led_on(hw, pin0); + else + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_sw_led_off(hw, pin0); + else + rtl8821ae_sw_led_off(hw, pin0); +} + +static bool _rtl8821ae_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 bytetmp = 0; + u16 wordtmp = 0; + bool mac_func_enable = rtlhal->mac_func_enable; + + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + + /*Auto Power Down to CHIP-off State*/ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7)); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + /* HW Power on sequence*/ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, + PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, + RTL8812_NIC_ENABLE_FLOW)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "init 8812 MAC Fail as power on failure\n"); + return false; + } + } else { + /* HW Power on sequence */ + if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_A_MSK, + PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, + RTL8821A_NIC_ENABLE_FLOW)){ + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "init 8821 MAC Fail as power on failure\n"); + return false; + } + } + + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4); + rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp); + + bytetmp = rtl_read_byte(rtlpriv, REG_CR); + bytetmp = 0xff; + rtl_write_byte(rtlpriv, REG_CR, bytetmp); + mdelay(2); + + bytetmp = 0xff; + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp); + mdelay(2); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3); + if (bytetmp & BIT(0)) { + bytetmp = rtl_read_byte(rtlpriv, 0x7c); + bytetmp |= BIT(6); + rtl_write_byte(rtlpriv, 0x7c, bytetmp); + } + } + + bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1); + bytetmp &= ~BIT(4); + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp); + + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + if (!mac_func_enable) { + if (!_rtl8821ae_llt_table_init(hw)) + return false; + } + + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); + + /* Enable FW Beamformer Interrupt */ + bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3); + rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6)); + + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF5B1; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); + /*low address*/ + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + rtlpci->tx_ring[BEACON_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + rtlpci->tx_ring[MGNT_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + rtlpci->tx_ring[HIGH_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + rtlpci->rx_ring[RX_MPDU_QUEUE].dma & DMA_BIT_MASK(32)); + + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77); + + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0); + + rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3); + _rtl8821ae_gen_refresh_led_state(hw); + + return true; +} + +static void _rtl8821ae_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rrsr; + + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + + rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); + /* ARFB table 9 for 11ac 5G 2SS */ + rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000); + /* ARFB table 10 for 11ac 5G 1SS */ + rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000); + /* ARFB table 11 for 11ac 24G 1SS */ + rtl_write_dword(rtlpriv, REG_ARFR2, 0x00000015); + rtl_write_dword(rtlpriv, REG_ARFR2 + 4, 0x003ff000); + /* ARFB table 12 for 11ac 24G 1SS */ + rtl_write_dword(rtlpriv, REG_ARFR3, 0x00000015); + rtl_write_dword(rtlpriv, REG_ARFR3 + 4, 0xffcff000); + /* 0x420[7] = 0 , enable retry AMPDU in new AMPD not singal MPDU. */ + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00); + rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70); + + /*Set retry limit*/ + rtl_write_word(rtlpriv, REG_RL, 0x0707); + + /* Set Data / Response auto rate fallback retry count*/ + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + + rtlpci->reg_bcn_ctrl_val = 0x1d; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + + /* TBTT prohibit hold time. Suggested by designer TimChen. */ + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + + /* AGGR_BK_TIME Reg51A 0x16 */ + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + + /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/ + rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); + + rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20); + rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, 0x1F1F); +} + +static u16 _rtl8821ae_mdio_read(struct rtl_priv *rtlpriv, u8 addr) +{ + u16 ret = 0; + u8 tmp = 0, count = 0; + + rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6)); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6); + count++; + } + if (0 == tmp) + ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA); + + return ret; +} + +static void _rtl8821ae_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data) +{ + u8 tmp = 0, count = 0; + + rtl_write_word(rtlpriv, REG_MDIO_WDATA, data); + rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5)); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5); + count++; + } +} + +static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr) +{ + u16 read_addr = addr & 0xfffc; + u8 tmp = 0, count = 0, ret = 0; + + rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count++; + } + if (0 == tmp) { + read_addr = REG_DBI_RDATA + addr % 4; + ret = rtl_read_byte(rtlpriv, read_addr); + } + return ret; +} + +static void _rtl8821ae_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data) +{ + u8 tmp = 0, count = 0; + u16 write_addr, remainder = addr % 4; + + write_addr = REG_DBI_WDATA + remainder; + rtl_write_byte(rtlpriv, write_addr, data); + + write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12)); + rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr); + + rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1); + + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count = 0; + while (tmp && count < 20) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG); + count++; + } +} + +static void _rtl8821ae_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + if (_rtl8821ae_mdio_read(rtlpriv, 0x04) != 0x8544) + _rtl8821ae_mdio_write(rtlpriv, 0x04, 0x8544); + + if (_rtl8821ae_mdio_read(rtlpriv, 0x0b) != 0x0070) + _rtl8821ae_mdio_write(rtlpriv, 0x0b, 0x0070); + } + + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f); + _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7) | + ASPM_L1_LATENCY << 3); + + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719); + _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x718); + _rtl8821ae_dbi_write(rtlpriv, 0x718, tmp|BIT(4)); + } +} + +void rtl8821ae_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + u8 tmp; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + tmp = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1)); + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "The SECR-value %x\n", sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +/* Static MacID Mapping (cf. Used in MacIdDoStaticMapping) ---------- */ +#define MAC_ID_STATIC_FOR_DEFAULT_PORT 0 +#define MAC_ID_STATIC_FOR_BROADCAST_MULTICAST 1 +#define MAC_ID_STATIC_FOR_BT_CLIENT_START 2 +#define MAC_ID_STATIC_FOR_BT_CLIENT_END 3 +/* ----------------------------------------------------------- */ + +static void rtl8821ae_macid_initialize_mediastatus(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 media_rpt[4] = {RT_MEDIA_CONNECT, 1, + MAC_ID_STATIC_FOR_BROADCAST_MULTICAST, + MAC_ID_STATIC_FOR_BT_CLIENT_END}; + + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_MEDIASTATUSRPT, media_rpt); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Initialize MacId media status: from %d to %d\n", + MAC_ID_STATIC_FOR_BROADCAST_MULTICAST, + MAC_ID_STATIC_FOR_BT_CLIENT_END); +} + +static bool _rtl8821ae_check_pcie_dma_hang(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + /* write reg 0x350 Bit[26]=1. Enable debug port. */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3); + if (!(tmp & BIT(2))) { + rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2))); + mdelay(100); + } + + /* read reg 0x350 Bit[25] if 1 : RX hang */ + /* read reg 0x350 Bit[24] if 1 : TX hang */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3); + if ((tmp & BIT(0)) || (tmp & BIT(1))) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "CheckPcieDMAHang8821AE(): true! Reset PCIE DMA!\n"); + return true; + } else { + return false; + } +} + +static bool _rtl8821ae_reset_pcie_interface_dma(struct ieee80211_hw *hw, + bool mac_power_on, + bool in_watchdog) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp; + bool release_mac_rx_pause; + u8 backup_pcie_dma_pause; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + + /* 1. Disable register write lock. 0x1c[1] = 0 */ + tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL); + tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp); + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* write 0xCC bit[2] = 1'b1 */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp |= BIT(2); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); + } + + /* 2. Check and pause TRX DMA */ + /* write 0x284 bit[18] = 1'b1 */ + /* write 0x301 = 0xFF */ + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + if (tmp & BIT(2)) { + /* Already pause before the function for another purpose. */ + release_mac_rx_pause = false; + } else { + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2))); + release_mac_rx_pause = true; + } + backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1); + if (backup_pcie_dma_pause != 0xFF) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF); + + if (mac_power_on) { + /* 3. reset TRX function */ + /* write 0x100 = 0x00 */ + rtl_write_byte(rtlpriv, REG_CR, 0); + } + + /* 4. Reset PCIe DMA. 0x3[0] = 0 */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + /* 5. Enable PCIe DMA. 0x3[0] = 1 */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); + + if (mac_power_on) { + /* 6. enable TRX function */ + /* write 0x100 = 0xFF */ + rtl_write_byte(rtlpriv, REG_CR, 0xFF); + + /* We should init LLT & RQPN and + * prepare Tx/Rx descriptor address later + * because MAC function is reset.*/ + } + + /* 7. Restore PCIe autoload down bit */ + /* 8812AE does not have the definition. */ + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* write 0xF8 bit[17] = 1'b1 */ + tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2); + tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp); + } + + /* In MAC power on state, BB and RF may be in ON state, + * if we release TRx DMA here. + * it will cause packets to be started to Tx/Rx, + * so we release Tx/Rx DMA later.*/ + if (!mac_power_on/* || in_watchdog*/) { + /* 8. release TRX DMA */ + /* write 0x284 bit[18] = 1'b0 */ + /* write 0x301 = 0x00 */ + if (release_mac_rx_pause) { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, + tmp & (~BIT(2))); + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, + backup_pcie_dma_pause); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* 9. lock system register */ + /* write 0xCC bit[2] = 1'b0 */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); + tmp &= ~(BIT(2)); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); + } + return true; +} + +static void _rtl8821ae_get_wakeup_reason(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + u8 fw_reason = 0; + + fw_reason = rtl_read_byte(rtlpriv, REG_MCUTST_WOWLAN); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "WOL Read 0x1c7 = %02X\n", + fw_reason); + + ppsc->wakeup_reason = 0; + + rtlhal->last_suspend_sec = ktime_get_real_seconds(); + + switch (fw_reason) { + case FW_WOW_V2_PTK_UPDATE_EVENT: + ppsc->wakeup_reason = WOL_REASON_PTK_UPDATE; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a WOL PTK Key update event!\n"); + break; + case FW_WOW_V2_GTK_UPDATE_EVENT: + ppsc->wakeup_reason = WOL_REASON_GTK_UPDATE; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a WOL GTK Key update event!\n"); + break; + case FW_WOW_V2_DISASSOC_EVENT: + ppsc->wakeup_reason = WOL_REASON_DISASSOC; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a disassociation event!\n"); + break; + case FW_WOW_V2_DEAUTH_EVENT: + ppsc->wakeup_reason = WOL_REASON_DEAUTH; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a deauth event!\n"); + break; + case FW_WOW_V2_FW_DISCONNECT_EVENT: + ppsc->wakeup_reason = WOL_REASON_AP_LOST; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a Fw disconnect decision (AP lost) event!\n"); + break; + case FW_WOW_V2_MAGIC_PKT_EVENT: + ppsc->wakeup_reason = WOL_REASON_MAGIC_PKT; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a magic packet event!\n"); + break; + case FW_WOW_V2_UNICAST_PKT_EVENT: + ppsc->wakeup_reason = WOL_REASON_UNICAST_PKT; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's an unicast packet event!\n"); + break; + case FW_WOW_V2_PATTERN_PKT_EVENT: + ppsc->wakeup_reason = WOL_REASON_PATTERN_PKT; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's a pattern match event!\n"); + break; + case FW_WOW_V2_RTD3_SSID_MATCH_EVENT: + ppsc->wakeup_reason = WOL_REASON_RTD3_SSID_MATCH; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's an RTD3 Ssid match event!\n"); + break; + case FW_WOW_V2_REALWOW_V2_WAKEUPPKT: + ppsc->wakeup_reason = WOL_REASON_REALWOW_V2_WAKEUPPKT; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's an RealWoW wake packet event!\n"); + break; + case FW_WOW_V2_REALWOW_V2_ACKLOST: + ppsc->wakeup_reason = WOL_REASON_REALWOW_V2_ACKLOST; + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "It's an RealWoW ack lost event!\n"); + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "WOL Read 0x1c7 = %02X, Unknown reason!\n", + fw_reason); + break; + } +} + +static void _rtl8821ae_init_trx_desc_hw_address(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /*low address*/ + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + rtlpci->tx_ring[BEACON_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, + rtlpci->tx_ring[MGNT_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, + rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, + rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, + rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, + rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HQ_DESA, + rtlpci->tx_ring[HIGH_QUEUE].dma & DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_RX_DESA, + rtlpci->rx_ring[RX_MPDU_QUEUE].dma & DMA_BIT_MASK(32)); +} + +static bool _rtl8821ae_init_llt_table(struct ieee80211_hw *hw, u32 boundary) +{ + bool status = true; + u32 i; + u32 txpktbuf_bndy = boundary; + u32 last_entry_of_txpktbuf = LAST_ENTRY_OF_TX_PKT_BUFFER; + + for (i = 0 ; i < (txpktbuf_bndy - 1) ; i++) { + status = _rtl8821ae_llt_write(hw, i , i + 1); + if (!status) + return status; + } + + status = _rtl8821ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (!status) + return status; + + for (i = txpktbuf_bndy ; i < last_entry_of_txpktbuf ; i++) { + status = _rtl8821ae_llt_write(hw, i, (i + 1)); + if (!status) + return status; + } + + return _rtl8821ae_llt_write(hw, last_entry_of_txpktbuf, txpktbuf_bndy); +} + +static bool _rtl8821ae_dynamic_rqpn(struct ieee80211_hw *hw, u32 boundary, + u16 npq_rqpn_value, u32 rqpn_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + bool ret = true; + u16 count = 0, tmp16; + bool support_remote_wakeup; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&support_remote_wakeup)); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "boundary=%#X, NPQ_RQPNValue=%#X, RQPNValue=%#X\n", + boundary, npq_rqpn_value, rqpn_val); + + /* stop PCIe DMA + * 1. 0x301[7:0] = 0xFE */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE); + + /* wait TXFF empty + * 2. polling till 0x41A[15:0]=0x07FF */ + tmp16 = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); + while ((tmp16 & 0x07FF) != 0x07FF) { + udelay(100); + tmp16 = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); + count++; + if ((count % 200) == 0) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Tx queue is not empty for 20ms!\n"); + } + if (count >= 1000) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wait for Tx FIFO empty timeout!\n"); + break; + } + } + + /* TX pause + * 3. reg 0x522=0xFF */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + /* Wait TX State Machine OK + * 4. polling till reg 0x5FB~0x5F8 = 0x00000000 for 50ms */ + count = 0; + while (rtl_read_byte(rtlpriv, REG_SCH_TXCMD) != 0) { + udelay(100); + count++; + if (count >= 500) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wait for TX State Machine ready timeout !!\n"); + break; + } + } + + /* stop RX DMA path + * 5. 0x284[18] = 1 + * 6. wait till 0x284[17] == 1 + * wait RX DMA idle */ + count = 0; + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2))); + do { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + udelay(10); + count++; + } while (!(tmp & BIT(1)) && count < 100); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wait until Rx DMA Idle. count=%d REG[0x286]=0x%x\n", + count, tmp); + + /* reset BB + * 7. 0x02 [0] = 0 */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmp); + + /* Reset TRX MAC + * 8. 0x100 = 0x00 + * Delay (1ms) */ + rtl_write_byte(rtlpriv, REG_CR, 0x00); + udelay(1000); + + /* Disable MAC Security Engine + * 9. 0x100 bit[9]=0 */ + tmp = rtl_read_byte(rtlpriv, REG_CR + 1); + tmp &= ~(BIT(1)); + rtl_write_byte(rtlpriv, REG_CR + 1, tmp); + + /* To avoid DD-Tim Circuit hang + * 10. 0x553 bit[5]=1 */ + tmp = rtl_read_byte(rtlpriv, REG_DUAL_TSF_RST); + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (tmp | BIT(5))); + + /* Enable MAC Security Engine + * 11. 0x100 bit[9]=1 */ + tmp = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, (tmp | BIT(1))); + + /* Enable TRX MAC + * 12. 0x100 = 0xFF + * Delay (1ms) */ + rtl_write_byte(rtlpriv, REG_CR, 0xFF); + udelay(1000); + + /* Enable BB + * 13. 0x02 [0] = 1 */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmp | BIT(0))); + + /* beacon setting + * 14,15. set beacon head page (reg 0x209 and 0x424) */ + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, (u8)boundary); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, (u8)boundary); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, (u8)boundary); + + /* 16. WMAC_LBK_BF_HD 0x45D[7:0] + * WMAC_LBK_BF_HD */ + rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, + (u8)boundary); + + rtl_write_word(rtlpriv, REG_TRXFF_BNDY, boundary); + + /* init LLT + * 17. init LLT */ + if (!_rtl8821ae_init_llt_table(hw, boundary)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, + "Failed to init LLT table!\n"); + return false; + } + + /* reallocate RQPN + * 18. reallocate RQPN and init LLT */ + rtl_write_word(rtlpriv, REG_RQPN_NPQ, npq_rqpn_value); + rtl_write_dword(rtlpriv, REG_RQPN, rqpn_val); + + /* release Tx pause + * 19. 0x522=0x00 */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + + /* enable PCIE DMA + * 20. 0x301[7:0] = 0x00 + * 21. 0x284[18] = 0 */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x00); + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp&~BIT(2))); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "End.\n"); + return ret; +} + +static void _rtl8821ae_simple_initialize_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + +#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1) + /* Re-download normal Fw. */ + rtl8821ae_set_fw_related_for_wowlan(hw, false); +#endif + + /* Re-Initialize LLT table. */ + if (rtlhal->re_init_llt_table) { + u32 rqpn = 0x80e70808; + u8 rqpn_npq = 0, boundary = 0xF8; + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + rqpn = 0x80e90808; + boundary = 0xFA; + } + if (_rtl8821ae_dynamic_rqpn(hw, boundary, rqpn_npq, rqpn)) + rtlhal->re_init_llt_table = false; + } + + ppsc->rfpwr_state = ERFON; +} + +static void _rtl8821ae_enable_l1off(struct ieee80211_hw *hw) +{ + u8 tmp = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "--->\n"); + + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x160); + if (!(tmp & (BIT(2) | BIT(3)))) { + rtl_dbg(rtlpriv, COMP_POWER | COMP_INIT, DBG_LOUD, + "0x160(%#x)return!!\n", tmp); + return; + } + + tmp = _rtl8821ae_mdio_read(rtlpriv, 0x1b); + _rtl8821ae_mdio_write(rtlpriv, 0x1b, (tmp | BIT(4))); + + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x718); + _rtl8821ae_dbi_write(rtlpriv, 0x718, tmp | BIT(5)); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<---\n"); +} + +static void _rtl8821ae_enable_ltr(struct ieee80211_hw *hw) +{ + u8 tmp = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "--->\n"); + + /* Check 0x98[10] */ + tmp = _rtl8821ae_dbi_read(rtlpriv, 0x99); + if (!(tmp & BIT(2))) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "<---0x99(%#x) return!!\n", tmp); + return; + } + + /* LTR idle latency, 0x90 for 144us */ + rtl_write_dword(rtlpriv, 0x798, 0x88908890); + + /* LTR active latency, 0x3c for 60us */ + rtl_write_dword(rtlpriv, 0x79c, 0x883c883c); + + tmp = rtl_read_byte(rtlpriv, 0x7a4); + rtl_write_byte(rtlpriv, 0x7a4, (tmp | BIT(4))); + + tmp = rtl_read_byte(rtlpriv, 0x7a4); + rtl_write_byte(rtlpriv, 0x7a4, (tmp & (~BIT(0)))); + rtl_write_byte(rtlpriv, 0x7a4, (tmp | BIT(0))); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<---\n"); +} + +static bool _rtl8821ae_wowlan_initialize_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + bool init_finished = true; + u8 tmp = 0; + + /* Get Fw wake up reason. */ + _rtl8821ae_get_wakeup_reason(hw); + + /* Patch Pcie Rx DMA hang after S3/S4 several times. + * The root cause has not been found. */ + if (_rtl8821ae_check_pcie_dma_hang(hw)) + _rtl8821ae_reset_pcie_interface_dma(hw, true, false); + + /* Prepare Tx/Rx Desc Hw address. */ + _rtl8821ae_init_trx_desc_hw_address(hw); + + /* Release Pcie Interface Rx DMA to allow wake packet DMA. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Enable PCIE Rx DMA.\n"); + + /* Check wake up event. + * We should check wake packet bit before disable wowlan by H2C or + * Fw will clear the bit. */ + tmp = rtl_read_byte(rtlpriv, REG_FTISR + 3); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Read REG_FTISR 0x13f = %#X\n", tmp); + + /* Set the WoWLAN related function control disable. */ + rtl8821ae_set_fw_wowlan_mode(hw, false); + rtl8821ae_set_fw_remote_wake_ctrl_cmd(hw, 0); + + if (rtlhal->hw_rof_enable) { + tmp = rtl_read_byte(rtlpriv, REG_HSISR + 3); + if (tmp & BIT(1)) { + /* Clear GPIO9 ISR */ + rtl_write_byte(rtlpriv, REG_HSISR + 3, tmp | BIT(1)); + init_finished = false; + } else { + init_finished = true; + } + } + + if (init_finished) { + _rtl8821ae_simple_initialize_adapter(hw); + + /* Release Pcie Interface Tx DMA. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x00); + /* Release Pcie RX DMA */ + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, 0x02); + + tmp = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & (~BIT(0)))); + + _rtl8821ae_enable_l1off(hw); + _rtl8821ae_enable_ltr(hw); + } + + return init_finished; +} + +static void _rtl8812ae_bb8812_config_1t(struct ieee80211_hw *hw) +{ + /* BB OFDM RX Path_A */ + rtl_set_bbreg(hw, 0x808, 0xff, 0x11); + /* BB OFDM TX Path_A */ + rtl_set_bbreg(hw, 0x80c, MASKLWORD, 0x1111); + /* BB CCK R/Rx Path_A */ + rtl_set_bbreg(hw, 0xa04, 0x0c000000, 0x0); + /* MCS support */ + rtl_set_bbreg(hw, 0x8bc, 0xc0000060, 0x4); + /* RF Path_B HSSI OFF */ + rtl_set_bbreg(hw, 0xe00, 0xf, 0x4); + /* RF Path_B Power Down */ + rtl_set_bbreg(hw, 0xe90, MASKDWORD, 0); + /* ADDA Path_B OFF */ + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0); + rtl_set_bbreg(hw, 0xe64, MASKDWORD, 0); +} + +static void _rtl8821ae_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1b_tmp; + + rtlhal->mac_func_enable = false; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* Combo (PCIe + USB) Card and PCIe-MF Card */ + /* 1. Run LPS WL RFOFF flow */ + /* rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "=====>CardDisableRTL8812E,RTL8821A_NIC_LPS_ENTER_FLOW\n"); + */ + rtl_hal_pwrseqcmdparsing(rtlpriv, + PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8821A_NIC_LPS_ENTER_FLOW); + } + /* 2. 0x1F[7:0] = 0 */ + /* turn off RF */ + /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */ + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && + rtlhal->fw_ready) { + rtl8821ae_firmware_selfreset(hw); + } + + /* Reset MCU. Suggested by Filen. */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2)))); + + /* g. MCUFWDL 0x80[1:0]=0 */ + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* HW card disable configuration. */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8821A_NIC_DISABLE_FLOW); + } else { + /* HW card disable configuration. */ + rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, + PWR_INTF_PCI_MSK, RTL8812_NIC_DISABLE_FLOW); + } + + /* Reset MCU IO Wrapper */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); + rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0)); + + /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ + /* lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); +} + +int rtl8821ae_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool rtstatus = true; + int err; + u8 tmp_u1b; + bool support_remote_wakeup; + u32 nav_upper = WIFI_NAV_UPPER_US; + + rtlhal->being_init_adapter = true; + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&support_remote_wakeup)); + rtlpriv->intf_ops->disable_aspm(hw); + + /*YP wowlan not considered*/ + + tmp_u1b = rtl_read_byte(rtlpriv, REG_CR); + if (tmp_u1b != 0 && tmp_u1b != 0xEA) { + rtlhal->mac_func_enable = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "MAC has already power on.\n"); + } else { + rtlhal->mac_func_enable = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE; + } + + if (support_remote_wakeup && + rtlhal->wake_from_pnp_sleep && + rtlhal->mac_func_enable) { + if (_rtl8821ae_wowlan_initialize_adapter(hw)) { + rtlhal->being_init_adapter = false; + return 0; + } + } + + if (_rtl8821ae_check_pcie_dma_hang(hw)) { + _rtl8821ae_reset_pcie_interface_dma(hw, + rtlhal->mac_func_enable, + false); + rtlhal->mac_func_enable = false; + } + + /* Reset MAC/BB/RF status if it is not powered off + * before calling initialize Hw flow to prevent + * from interface and MAC status mismatch. + * 2013.06.21, by tynli. Suggested by SD1 JackieLau. */ + if (rtlhal->mac_func_enable) { + _rtl8821ae_poweroff_adapter(hw); + rtlhal->mac_func_enable = false; + } + + rtstatus = _rtl8821ae_init_mac(hw); + if (!rtstatus) { + pr_err("Init MAC failed\n"); + err = 1; + return err; + } + + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG); + tmp_u1b &= 0x7F; + rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b); + + err = rtl8821ae_download_fw(hw, false); + if (err) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now\n"); + err = 1; + rtlhal->fw_ready = false; + return err; + } else { + rtlhal->fw_ready = true; + } + ppsc->fw_current_inpsmode = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + rtlhal->last_hmeboxnum = 0; + + /*SIC_Init(Adapter); + if(rtlhal->AMPDUBurstMode) + rtl_write_byte(rtlpriv,REG_AMPDU_BURST_MODE_8812, 0x7F);*/ + + rtl8821ae_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);*/ + rtl8821ae_phy_bb_config(hw); + + rtl8821ae_phy_rf_config(hw); + + if (rtlpriv->phy.rf_type == RF_1T1R && + rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + _rtl8812ae_bb8812_config_1t(hw); + + _rtl8821ae_hw_configure(hw); + + rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G); + + /*set wireless mode*/ + + rtlhal->mac_func_enable = true; + + rtl_cam_reset_all_entry(hw); + + rtl8821ae_enable_hw_security_config(hw); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl8821ae_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE && + (rtlhal->rfe_type == 1 || rtlhal->rfe_type == 5)) + rtl_set_bbreg(hw, 0x900, 0x00000303, 0x0302); + + rtl8821ae_bt_hw_init(hw); + rtlpriv->rtlhal.being_init_adapter = false; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_NAV_UPPER, (u8 *)&nav_upper); + + /* rtl8821ae_dm_check_txpower_tracking(hw); */ + /* rtl8821ae_phy_lc_calibrate(hw); */ + if (support_remote_wakeup) + rtl_write_byte(rtlpriv, REG_WOW_CTRL, 0); + + /* Release Rx DMA*/ + tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + if (tmp_u1b & BIT(2)) { + /* Release Rx DMA if needed*/ + tmp_u1b &= ~BIT(2); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b); + } + + /* Release Tx/Rx PCIE DMA if*/ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0); + + rtl8821ae_dm_init(hw); + rtl8821ae_macid_initialize_mediastatus(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "%s() <====\n", __func__); + return err; +} + +static enum version_8821ae _rtl8821ae_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum version_8821ae version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "ReadChipVersion8812A 0xF0 = 0x%x\n", value32); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtlphy->rf_type = RF_2T2R; + else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) + rtlphy->rf_type = RF_1T1R; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "RF_Type is %x!!\n", rtlphy->rf_type); + + if (value32 & TRP_VAUX_EN) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + if (rtlphy->rf_type == RF_2T2R) + version = VERSION_TEST_CHIP_2T2R_8812; + else + version = VERSION_TEST_CHIP_1T1R_8812; + } else + version = VERSION_TEST_CHIP_8821; + } else { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + u32 rtl_id = ((value32 & CHIP_VER_RTL_MASK) >> 12) + 1; + + if (rtlphy->rf_type == RF_2T2R) + version = + (enum version_8821ae)(CHIP_8812 + | NORMAL_CHIP | + RF_TYPE_2T2R); + else + version = (enum version_8821ae)(CHIP_8812 + | NORMAL_CHIP); + + version = (enum version_8821ae)(version | (rtl_id << 12)); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + u32 rtl_id = value32 & CHIP_VER_RTL_MASK; + + version = (enum version_8821ae)(CHIP_8821 + | NORMAL_CHIP | rtl_id); + } + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /*WL_HWROF_EN.*/ + value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); + rtlhal->hw_rof_enable = ((value32 & WL_HWROF_EN) ? 1 : 0); + } + + switch (version) { + case VERSION_TEST_CHIP_1T1R_8812: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_TEST_CHIP_1T1R_8812\n"); + break; + case VERSION_TEST_CHIP_2T2R_8812: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_TEST_CHIP_2T2R_8812\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_1T1R_8812: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID:VERSION_NORMAL_TSMC_CHIP_1T1R_8812\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_2T2R_8812: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_2T2R_8812\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_1T1R_8812_C_CUT: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_1T1R_8812 C CUT\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_2T2R_8812_C_CUT: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_2T2R_8812 C CUT\n"); + break; + case VERSION_TEST_CHIP_8821: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_TEST_CHIP_8821\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_8821: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_8821 A CUT\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_8821_B_CUT: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_8821 B CUT\n"); + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Chip Version ID: Unknown (0x%X)\n", version); + break; + } + + return version; +} + +static int _rtl8821ae_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + bt_msr &= 0xfc; + + rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); + rtl_dbg(rtlpriv, COMP_BEACON, DBG_LOUD, + "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + _rtl8821ae_stop_tx_beacon(hw); + _rtl8821ae_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || + type == NL80211_IFTYPE_AP) { + _rtl8821ae_resume_tx_beacon(hw); + _rtl8821ae_disable_bcn_sub_func(hw); + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + type); + } + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + rtl_write_byte(rtlpriv, MSR, bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & MSR_MASK) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + + return 0; +} + +void rtl8821ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl8821ae_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "%s!\n", __func__); + + if (_rtl8821ae_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl8821ae_set_check_bssid(hw, true); + } else { + rtl8821ae_set_check_bssid(hw, false); + } + + return 0; +} + +/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ +void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl8821ae_dm_init_edca_turbo(hw); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */ + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + WARN_ONCE(true, "rtl8821ae: invalid aci: %d !\n", aci); + break; + } +} + +static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 tmp = rtl_read_dword(rtlpriv, REG_HISR); + + rtl_write_dword(rtlpriv, REG_HISR, tmp); + + tmp = rtl_read_dword(rtlpriv, REG_HISRE); + rtl_write_dword(rtlpriv, REG_HISRE, tmp); + + tmp = rtl_read_dword(rtlpriv, REG_HSISR); + rtl_write_dword(rtlpriv, REG_HSISR, tmp); +} + +void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + if (rtlpci->int_clear) + rtl8821ae_clear_interrupt(hw);/*clear it here first*/ + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; + /* there are some C2H CMDs have been sent before + system interrupt is enabled, e.g., C2H, CPWM. + *So we need to clear all C2H events that FW has + notified, otherwise FW won't schedule any commands anymore. + */ + /* rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0); */ + /*enable system interrupt*/ + rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF); +} + +void rtl8821ae_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +static void _rtl8821ae_clear_pci_pme_status(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct pci_dev *pdev = rtlpci->pdev; + u16 pmcs_reg; + u8 pm_cap; + + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (!pm_cap) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, + "Cannot find PME Capability\n"); + return; + } + + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcs_reg); + if (pmcs_reg & PCI_PM_CTRL_PME_STATUS) { + /* Clear PME_Status with write */ + pci_write_config_word(pdev, pm_cap + PCI_PM_CTRL, pmcs_reg); + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcs_reg); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Cleared PME status, PMCS reg = 0x%4x\n", pmcs_reg); + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "PMCS reg = 0x%4x\n", pmcs_reg); + } +} + +void rtl8821ae_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + enum nl80211_iftype opmode; + bool support_remote_wakeup; + u8 tmp; + u32 count = 0; + + rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, + (u8 *)(&support_remote_wakeup)); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + if (!(support_remote_wakeup && mac->opmode == NL80211_IFTYPE_STATION) + || !rtlhal->enter_pnp_sleep) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Normal Power off\n"); + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl8821ae_set_media_status(hw, opmode); + _rtl8821ae_poweroff_adapter(hw); + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Wowlan Supported.\n"); + /* 3 <1> Prepare for configuring wowlan related infomations */ + /* Clear Fw WoWLAN event. */ + rtl_write_byte(rtlpriv, REG_MCUTST_WOWLAN, 0x0); + +#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1) + rtl8821ae_set_fw_related_for_wowlan(hw, true); +#endif + /* Dynamically adjust Tx packet boundary + * for download reserved page packet. + * reserve 30 pages for rsvd page */ + if (_rtl8821ae_dynamic_rqpn(hw, 0xE0, 0x3, 0x80c20d0d)) + rtlhal->re_init_llt_table = true; + + /* 3 <2> Set Fw related H2C cmd. */ + + /* Set WoWLAN related security information. */ + rtl8821ae_set_fw_global_info_cmd(hw); + + _rtl8821ae_download_rsvd_page(hw, true); + + /* Just enable AOAC related functions when we connect to AP. */ + printk("mac->link_state = %d\n", mac->link_state); + if (mac->link_state >= MAC80211_LINKED && + mac->opmode == NL80211_IFTYPE_STATION) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + rtl8821ae_set_fw_media_status_rpt_cmd(hw, + RT_MEDIA_CONNECT); + + rtl8821ae_set_fw_wowlan_mode(hw, true); + /* Enable Fw Keep alive mechanism. */ + rtl8821ae_set_fw_keep_alive_cmd(hw, true); + + /* Enable disconnect decision control. */ + rtl8821ae_set_fw_disconnect_decision_ctrl_cmd(hw, true); + } + + /* 3 <3> Hw Configurations */ + + /* Wait until Rx DMA Finished before host sleep. + * FW Pause Rx DMA may happen when received packet doing DMA. + */ + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, BIT(2)); + + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + count = 0; + while (!(tmp & BIT(1)) && (count++ < 100)) { + udelay(10); + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wait Rx DMA Finished before host sleep. count=%d\n", + count); + + /* reset trx ring */ + rtlpriv->intf_ops->reset_trx_ring(hw); + + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x0); + + _rtl8821ae_clear_pci_pme_status(hw); + tmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); + rtl_write_byte(rtlpriv, REG_SYS_CLKR, tmp | BIT(3)); + /* prevent 8051 to be reset by PERST */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x20); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x60); + } + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + /* For wowlan+LPS+32k. */ + if (support_remote_wakeup && rtlhal->enter_pnp_sleep) { + /* Set the WoWLAN related function control enable. + * It should be the last H2C cmd in the WoWLAN flow. */ + rtl8821ae_set_fw_remote_wake_ctrl_cmd(hw, 1); + + /* Stop Pcie Interface Tx DMA. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Stop PCIE Tx DMA.\n"); + + /* Wait for TxDMA idle. */ + count = 0; + do { + tmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG); + udelay(10); + count++; + } while ((tmp != 0) && (count < 100)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wait Tx DMA Finished before host sleep. count=%d\n", + count); + + if (rtlhal->hw_rof_enable) { + printk("hw_rof_enable\n"); + tmp = rtl_read_byte(rtlpriv, REG_HSISR + 3); + rtl_write_byte(rtlpriv, REG_HSISR + 3, tmp | BIT(1)); + } + } + /* after power off we should do iqk again */ + rtlpriv->phy.iqk_initialized = false; +} + +void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *intvec) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, intvec->inta); + + intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); +} + +void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl8821ae_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtlpci->reg_bcn_ctrl_val |= BIT(3); + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); + rtl8821ae_enable_interrupt(hw); +} + +void rtl8821ae_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, + "beacon_interval:%d\n", bcn_interval); + rtl8821ae_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl8821ae_enable_interrupt(hw); +} + +void rtl8821ae_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, + "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl8821ae_disable_interrupt(hw); + rtl8821ae_enable_interrupt(hw); +} + +static u8 _rtl8821ae_get_chnl_group(u8 chnl) +{ + u8 group = 0; + + if (chnl <= 14) { + if (1 <= chnl && chnl <= 2) + group = 0; + else if (3 <= chnl && chnl <= 5) + group = 1; + else if (6 <= chnl && chnl <= 8) + group = 2; + else if (9 <= chnl && chnl <= 11) + group = 3; + else /*if (12 <= chnl && chnl <= 14)*/ + group = 4; + } else { + if (36 <= chnl && chnl <= 42) + group = 0; + else if (44 <= chnl && chnl <= 48) + group = 1; + else if (50 <= chnl && chnl <= 58) + group = 2; + else if (60 <= chnl && chnl <= 64) + group = 3; + else if (100 <= chnl && chnl <= 106) + group = 4; + else if (108 <= chnl && chnl <= 114) + group = 5; + else if (116 <= chnl && chnl <= 122) + group = 6; + else if (124 <= chnl && chnl <= 130) + group = 7; + else if (132 <= chnl && chnl <= 138) + group = 8; + else if (140 <= chnl && chnl <= 144) + group = 9; + else if (149 <= chnl && chnl <= 155) + group = 10; + else if (157 <= chnl && chnl <= 161) + group = 11; + else if (165 <= chnl && chnl <= 171) + group = 12; + else if (173 <= chnl && chnl <= 177) + group = 13; + else + WARN_ONCE(true, + "rtl8821ae: 5G, Channel %d in Group not found\n", + chnl); + } + return group; +} + +static void _rtl8821ae_read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pwrinfo24g, + struct txpower_info_5g *pwrinfo5g, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 rfpath, eeaddr = EEPROM_TX_PWR_INX, group, txcount = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM8821ae(): hwinfo[0x%x]=0x%x\n", + (eeaddr + 1), hwinfo[eeaddr + 1]); + if (hwinfo[eeaddr + 1] == 0xFF) /*YJ,add,120316*/ + autoload_fail = true; + + if (autoload_fail) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) { + /*2.4G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwrinfo24g->index_cck_base[rfpath][group] = 0x2D; + pwrinfo24g->index_bw40_base[rfpath][group] = 0x2D; + } + for (txcount = 0; txcount < MAX_TX_COUNT; txcount++) { + if (txcount == 0) { + pwrinfo24g->bw20_diff[rfpath][0] = 0x02; + pwrinfo24g->ofdm_diff[rfpath][0] = 0x04; + } else { + pwrinfo24g->bw20_diff[rfpath][txcount] = 0xFE; + pwrinfo24g->bw40_diff[rfpath][txcount] = 0xFE; + pwrinfo24g->cck_diff[rfpath][txcount] = 0xFE; + pwrinfo24g->ofdm_diff[rfpath][txcount] = 0xFE; + } + } + /*5G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) + pwrinfo5g->index_bw40_base[rfpath][group] = 0x2A; + + for (txcount = 0; txcount < MAX_TX_COUNT; txcount++) { + if (txcount == 0) { + pwrinfo5g->ofdm_diff[rfpath][0] = 0x04; + pwrinfo5g->bw20_diff[rfpath][0] = 0x00; + pwrinfo5g->bw80_diff[rfpath][0] = 0xFE; + pwrinfo5g->bw160_diff[rfpath][0] = 0xFE; + } else { + pwrinfo5g->ofdm_diff[rfpath][0] = 0xFE; + pwrinfo5g->bw20_diff[rfpath][0] = 0xFE; + pwrinfo5g->bw40_diff[rfpath][0] = 0xFE; + pwrinfo5g->bw80_diff[rfpath][0] = 0xFE; + pwrinfo5g->bw160_diff[rfpath][0] = 0xFE; + } + } + } + return; + } + + rtl_priv(hw)->efuse.txpwr_fromeprom = true; + + for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) { + /*2.4G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { + pwrinfo24g->index_cck_base[rfpath][group] = hwinfo[eeaddr++]; + if (pwrinfo24g->index_cck_base[rfpath][group] == 0xFF) + pwrinfo24g->index_cck_base[rfpath][group] = 0x2D; + } + for (group = 0 ; group < MAX_CHNL_GROUP_24G - 1; group++) { + pwrinfo24g->index_bw40_base[rfpath][group] = hwinfo[eeaddr++]; + if (pwrinfo24g->index_bw40_base[rfpath][group] == 0xFF) + pwrinfo24g->index_bw40_base[rfpath][group] = 0x2D; + } + for (txcount = 0; txcount < MAX_TX_COUNT; txcount++) { + if (txcount == 0) { + pwrinfo24g->bw40_diff[rfpath][txcount] = 0; + /*bit sign number to 8 bit sign number*/ + pwrinfo24g->bw20_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0xf0) >> 4; + if (pwrinfo24g->bw20_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->bw20_diff[rfpath][txcount] |= 0xF0; + /*bit sign number to 8 bit sign number*/ + pwrinfo24g->ofdm_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo24g->ofdm_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->ofdm_diff[rfpath][txcount] |= 0xF0; + + pwrinfo24g->cck_diff[rfpath][txcount] = 0; + eeaddr++; + } else { + pwrinfo24g->bw40_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0xf0) >> 4; + if (pwrinfo24g->bw40_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->bw40_diff[rfpath][txcount] |= 0xF0; + + pwrinfo24g->bw20_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo24g->bw20_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->bw20_diff[rfpath][txcount] |= 0xF0; + + eeaddr++; + + pwrinfo24g->ofdm_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0xf0) >> 4; + if (pwrinfo24g->ofdm_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->ofdm_diff[rfpath][txcount] |= 0xF0; + + pwrinfo24g->cck_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo24g->cck_diff[rfpath][txcount] & BIT(3)) + pwrinfo24g->cck_diff[rfpath][txcount] |= 0xF0; + + eeaddr++; + } + } + + /*5G default value*/ + for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) { + pwrinfo5g->index_bw40_base[rfpath][group] = hwinfo[eeaddr++]; + if (pwrinfo5g->index_bw40_base[rfpath][group] == 0xFF) + pwrinfo5g->index_bw40_base[rfpath][group] = 0xFE; + } + + for (txcount = 0; txcount < MAX_TX_COUNT; txcount++) { + if (txcount == 0) { + pwrinfo5g->bw40_diff[rfpath][txcount] = 0; + + pwrinfo5g->bw20_diff[rfpath][0] = (hwinfo[eeaddr] & 0xf0) >> 4; + if (pwrinfo5g->bw20_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->bw20_diff[rfpath][txcount] |= 0xF0; + + pwrinfo5g->ofdm_diff[rfpath][0] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo5g->ofdm_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->ofdm_diff[rfpath][txcount] |= 0xF0; + + eeaddr++; + } else { + pwrinfo5g->bw40_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0xf0) >> 4; + if (pwrinfo5g->bw40_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->bw40_diff[rfpath][txcount] |= 0xF0; + + pwrinfo5g->bw20_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo5g->bw20_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->bw20_diff[rfpath][txcount] |= 0xF0; + + eeaddr++; + } + } + + pwrinfo5g->ofdm_diff[rfpath][1] = (hwinfo[eeaddr] & 0xf0) >> 4; + pwrinfo5g->ofdm_diff[rfpath][2] = (hwinfo[eeaddr] & 0x0f); + + eeaddr++; + + pwrinfo5g->ofdm_diff[rfpath][3] = (hwinfo[eeaddr] & 0x0f); + + eeaddr++; + + for (txcount = 1; txcount < MAX_TX_COUNT; txcount++) { + if (pwrinfo5g->ofdm_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->ofdm_diff[rfpath][txcount] |= 0xF0; + } + for (txcount = 0; txcount < MAX_TX_COUNT; txcount++) { + pwrinfo5g->bw80_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0xf0) >> 4; + /* 4bit sign number to 8 bit sign number */ + if (pwrinfo5g->bw80_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->bw80_diff[rfpath][txcount] |= 0xF0; + /* 4bit sign number to 8 bit sign number */ + pwrinfo5g->bw160_diff[rfpath][txcount] = (hwinfo[eeaddr] & 0x0f); + if (pwrinfo5g->bw160_diff[rfpath][txcount] & BIT(3)) + pwrinfo5g->bw160_diff[rfpath][txcount] |= 0xF0; + + eeaddr++; + } + } +} +#if 0 +static void _rtl8812ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwrinfo24g; + struct txpower_info_5g pwrinfo5g; + u8 rf_path, index; + u8 i; + + _rtl8821ae_read_power_value_fromprom(hw, &pwrinfo24g, + &pwrinfo5g, autoload_fail, hwinfo); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) { + index = _rtl8821ae_get_chnl_group(i + 1); + + if (i == CHANNEL_MAX_NUMBER_2G - 1) { + rtlefuse->txpwrlevel_cck[rf_path][i] = + pwrinfo24g.index_cck_base[rf_path][5]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pwrinfo24g.index_bw40_base[rf_path][index]; + } else { + rtlefuse->txpwrlevel_cck[rf_path][i] = + pwrinfo24g.index_cck_base[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pwrinfo24g.index_bw40_base[rf_path][index]; + } + } + + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { + index = _rtl8821ae_get_chnl_group(channel5g[i]); + rtlefuse->txpwr_5g_bw40base[rf_path][i] = + pwrinfo5g.index_bw40_base[rf_path][index]; + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { + u8 upper, lower; + index = _rtl8821ae_get_chnl_group(channel5g_80m[i]); + upper = pwrinfo5g.index_bw40_base[rf_path][index]; + lower = pwrinfo5g.index_bw40_base[rf_path][index + 1]; + + rtlefuse->txpwr_5g_bw80base[rf_path][i] = (upper + lower) / 2; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + rtlefuse->txpwr_cckdiff[rf_path][i] = + pwrinfo24g.cck_diff[rf_path][i]; + rtlefuse->txpwr_legacyhtdiff[rf_path][i] = + pwrinfo24g.ofdm_diff[rf_path][i]; + rtlefuse->txpwr_ht20diff[rf_path][i] = + pwrinfo24g.bw20_diff[rf_path][i]; + rtlefuse->txpwr_ht40diff[rf_path][i] = + pwrinfo24g.bw40_diff[rf_path][i]; + + rtlefuse->txpwr_5g_ofdmdiff[rf_path][i] = + pwrinfo5g.ofdm_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw20diff[rf_path][i] = + pwrinfo5g.bw20_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw40diff[rf_path][i] = + pwrinfo5g.bw40_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw80diff[rf_path][i] = + pwrinfo5g.bw80_diff[rf_path][i]; + } + } + + if (!autoload_fail) { + rtlefuse->eeprom_regulatory = + hwinfo[EEPROM_RF_BOARD_OPTION] & 0x07;/*bit0~2*/ + if (hwinfo[EEPROM_RF_BOARD_OPTION] == 0xFF) + rtlefuse->eeprom_regulatory = 0; + } else { + rtlefuse->eeprom_regulatory = 0; + } + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); +} +#endif +static noinline_for_stack void +_rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwrinfo24g; + struct txpower_info_5g pwrinfo5g; + u8 rf_path, index; + u8 i; + + _rtl8821ae_read_power_value_fromprom(hw, &pwrinfo24g, + &pwrinfo5g, autoload_fail, hwinfo); + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) { + index = _rtl8821ae_get_chnl_group(i + 1); + + if (i == CHANNEL_MAX_NUMBER_2G - 1) { + rtlefuse->txpwrlevel_cck[rf_path][i] = + pwrinfo24g.index_cck_base[rf_path][5]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pwrinfo24g.index_bw40_base[rf_path][index]; + } else { + rtlefuse->txpwrlevel_cck[rf_path][i] = + pwrinfo24g.index_cck_base[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + pwrinfo24g.index_bw40_base[rf_path][index]; + } + } + + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { + index = _rtl8821ae_get_chnl_group(channel5g[i]); + rtlefuse->txpwr_5g_bw40base[rf_path][i] = + pwrinfo5g.index_bw40_base[rf_path][index]; + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { + u8 upper, lower; + index = _rtl8821ae_get_chnl_group(channel5g_80m[i]); + upper = pwrinfo5g.index_bw40_base[rf_path][index]; + lower = pwrinfo5g.index_bw40_base[rf_path][index + 1]; + + rtlefuse->txpwr_5g_bw80base[rf_path][i] = (upper + lower) / 2; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + rtlefuse->txpwr_cckdiff[rf_path][i] = + pwrinfo24g.cck_diff[rf_path][i]; + rtlefuse->txpwr_legacyhtdiff[rf_path][i] = + pwrinfo24g.ofdm_diff[rf_path][i]; + rtlefuse->txpwr_ht20diff[rf_path][i] = + pwrinfo24g.bw20_diff[rf_path][i]; + rtlefuse->txpwr_ht40diff[rf_path][i] = + pwrinfo24g.bw40_diff[rf_path][i]; + + rtlefuse->txpwr_5g_ofdmdiff[rf_path][i] = + pwrinfo5g.ofdm_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw20diff[rf_path][i] = + pwrinfo5g.bw20_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw40diff[rf_path][i] = + pwrinfo5g.bw40_diff[rf_path][i]; + rtlefuse->txpwr_5g_bw80diff[rf_path][i] = + pwrinfo5g.bw80_diff[rf_path][i]; + } + } + /*bit0~2*/ + if (!autoload_fail) { + rtlefuse->eeprom_regulatory = hwinfo[EEPROM_RF_BOARD_OPTION] & 0x07; + if (hwinfo[EEPROM_RF_BOARD_OPTION] == 0xFF) + rtlefuse->eeprom_regulatory = 0; + } else { + rtlefuse->eeprom_regulatory = 0; + } + + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); +} + +static void _rtl8812ae_read_pa_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) { + rtlhal->pa_type_2g = hwinfo[0XBC]; + rtlhal->lna_type_2g = hwinfo[0XBD]; + if (rtlhal->pa_type_2g == 0xFF && rtlhal->lna_type_2g == 0xFF) { + rtlhal->pa_type_2g = 0; + rtlhal->lna_type_2g = 0; + } + rtlhal->external_pa_2g = ((rtlhal->pa_type_2g & BIT(5)) && + (rtlhal->pa_type_2g & BIT(4))) ? + 1 : 0; + rtlhal->external_lna_2g = ((rtlhal->lna_type_2g & BIT(7)) && + (rtlhal->lna_type_2g & BIT(3))) ? + 1 : 0; + + rtlhal->pa_type_5g = hwinfo[0XBC]; + rtlhal->lna_type_5g = hwinfo[0XBF]; + if (rtlhal->pa_type_5g == 0xFF && rtlhal->lna_type_5g == 0xFF) { + rtlhal->pa_type_5g = 0; + rtlhal->lna_type_5g = 0; + } + rtlhal->external_pa_5g = ((rtlhal->pa_type_5g & BIT(1)) && + (rtlhal->pa_type_5g & BIT(0))) ? + 1 : 0; + rtlhal->external_lna_5g = ((rtlhal->lna_type_5g & BIT(7)) && + (rtlhal->lna_type_5g & BIT(3))) ? + 1 : 0; + } else { + rtlhal->external_pa_2g = 0; + rtlhal->external_lna_2g = 0; + rtlhal->external_pa_5g = 0; + rtlhal->external_lna_5g = 0; + } +} + +static void _rtl8812ae_read_amplifier_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + u8 ext_type_pa_2g_a = (hwinfo[0XBD] & BIT(2)) >> 2; /* 0XBD[2] */ + u8 ext_type_pa_2g_b = (hwinfo[0XBD] & BIT(6)) >> 6; /* 0XBD[6] */ + u8 ext_type_pa_5g_a = (hwinfo[0XBF] & BIT(2)) >> 2; /* 0XBF[2] */ + u8 ext_type_pa_5g_b = (hwinfo[0XBF] & BIT(6)) >> 6; /* 0XBF[6] */ + /* 0XBD[1:0] */ + u8 ext_type_lna_2g_a = (hwinfo[0XBD] & (BIT(1) | BIT(0))) >> 0; + /* 0XBD[5:4] */ + u8 ext_type_lna_2g_b = (hwinfo[0XBD] & (BIT(5) | BIT(4))) >> 4; + /* 0XBF[1:0] */ + u8 ext_type_lna_5g_a = (hwinfo[0XBF] & (BIT(1) | BIT(0))) >> 0; + /* 0XBF[5:4] */ + u8 ext_type_lna_5g_b = (hwinfo[0XBF] & (BIT(5) | BIT(4))) >> 4; + + _rtl8812ae_read_pa_type(hw, hwinfo, autoload_fail); + + /* [2.4G] Path A and B are both extPA */ + if ((rtlhal->pa_type_2g & (BIT(5) | BIT(4))) == (BIT(5) | BIT(4))) + rtlhal->type_gpa = ext_type_pa_2g_b << 2 | ext_type_pa_2g_a; + + /* [5G] Path A and B are both extPA */ + if ((rtlhal->pa_type_5g & (BIT(1) | BIT(0))) == (BIT(1) | BIT(0))) + rtlhal->type_apa = ext_type_pa_5g_b << 2 | ext_type_pa_5g_a; + + /* [2.4G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_2g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_glna = ext_type_lna_2g_b << 2 | ext_type_lna_2g_a; + + /* [5G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_5g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_alna = ext_type_lna_5g_b << 2 | ext_type_lna_5g_a; +} + +static void _rtl8821ae_read_pa_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) { + rtlhal->pa_type_2g = hwinfo[0XBC]; + rtlhal->lna_type_2g = hwinfo[0XBD]; + if (rtlhal->pa_type_2g == 0xFF && rtlhal->lna_type_2g == 0xFF) { + rtlhal->pa_type_2g = 0; + rtlhal->lna_type_2g = 0; + } + rtlhal->external_pa_2g = (rtlhal->pa_type_2g & BIT(5)) ? 1 : 0; + rtlhal->external_lna_2g = (rtlhal->lna_type_2g & BIT(7)) ? 1 : 0; + + rtlhal->pa_type_5g = hwinfo[0XBC]; + rtlhal->lna_type_5g = hwinfo[0XBF]; + if (rtlhal->pa_type_5g == 0xFF && rtlhal->lna_type_5g == 0xFF) { + rtlhal->pa_type_5g = 0; + rtlhal->lna_type_5g = 0; + } + rtlhal->external_pa_5g = (rtlhal->pa_type_5g & BIT(1)) ? 1 : 0; + rtlhal->external_lna_5g = (rtlhal->lna_type_5g & BIT(7)) ? 1 : 0; + } else { + rtlhal->external_pa_2g = 0; + rtlhal->external_lna_2g = 0; + rtlhal->external_pa_5g = 0; + rtlhal->external_lna_5g = 0; + } +} + +static void _rtl8821ae_read_rfe_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) { + if (hwinfo[EEPROM_RFE_OPTION] & BIT(7)) { + if (rtlhal->external_lna_5g) { + if (rtlhal->external_pa_5g) { + if (rtlhal->external_lna_2g && + rtlhal->external_pa_2g) + rtlhal->rfe_type = 3; + else + rtlhal->rfe_type = 0; + } else { + rtlhal->rfe_type = 2; + } + } else { + rtlhal->rfe_type = 4; + } + } else { + rtlhal->rfe_type = hwinfo[EEPROM_RFE_OPTION] & 0x3F; + + if (rtlhal->rfe_type == 4 && + (rtlhal->external_pa_5g || + rtlhal->external_pa_2g || + rtlhal->external_lna_5g || + rtlhal->external_lna_2g)) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtlhal->rfe_type = 2; + } + } + } else { + rtlhal->rfe_type = 0x04; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "RFE Type: 0x%2x\n", rtlhal->rfe_type); +} + +static void _rtl8812ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + + if (!auto_load_fail) { + value = *(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION]; + if (((value & 0xe0) >> 5) == 0x1) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8812A; + + value = hwinfo[EEPROM_RF_BT_SETTING]; + rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); + } else { + rtlpriv->btcoexist.btc_info.btcoexist = 0; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8812A; + rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; + } + /*move BT_InitHalVars() to init_sw_vars*/ +} + +static void _rtl8821ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + u32 tmpu_32; + + if (!auto_load_fail) { + tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); + if (tmpu_32 & BIT(18)) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8821A; + + value = hwinfo[EEPROM_RF_BT_SETTING]; + rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); + } else { + rtlpriv->btcoexist.btc_info.btcoexist = 0; + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8821A; + rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; + } + /*move BT_InitHalVars() to init_sw_vars*/ +} + +static void _rtl8821ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_test) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + static const int params[] = { + RTL_EEPROM_ID, EEPROM_VID, EEPROM_DID, + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, + COUNTRY_CODE_WORLD_WIDE_13 + }; + u8 *hwinfo; + + if (b_pseudo_test) { + ;/* need add */ + } + + hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); + if (!hwinfo) + return; + + if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) + goto exit; + + _rtl8821ae_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + _rtl8812ae_read_amplifier_type(hw, hwinfo, + rtlefuse->autoload_failflag); + _rtl8812ae_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, hwinfo); + } else { + _rtl8821ae_read_pa_type(hw, hwinfo, rtlefuse->autoload_failflag); + _rtl8821ae_read_bt_coexist_info_from_hwpg(hw, + rtlefuse->autoload_failflag, hwinfo); + } + + _rtl8821ae_read_rfe_type(hw, hwinfo, rtlefuse->autoload_failflag); + /*board type*/ + rtlefuse->board_type = ODM_BOARD_DEFAULT; + if (rtlhal->external_lna_2g != 0) + rtlefuse->board_type |= ODM_BOARD_EXT_LNA; + if (rtlhal->external_lna_5g != 0) + rtlefuse->board_type |= ODM_BOARD_EXT_LNA_5G; + if (rtlhal->external_pa_2g != 0) + rtlefuse->board_type |= ODM_BOARD_EXT_PA; + if (rtlhal->external_pa_5g != 0) + rtlefuse->board_type |= ODM_BOARD_EXT_PA_5G; + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) + rtlefuse->board_type |= ODM_BOARD_BT; + + rtlhal->board_type = rtlefuse->board_type; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "board_type = 0x%x\n", rtlefuse->board_type); + + rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + if (rtlefuse->eeprom_channelplan == 0xff) + rtlefuse->eeprom_channelplan = 0x7F; + + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8821AE]; + if (rtlefuse->crystalcap == 0xFF) + rtlefuse->crystalcap = 0x20; + + rtlefuse->eeprom_thermalmeter = *(u8 *)&hwinfo[EEPROM_THERMAL_METER]; + if ((rtlefuse->eeprom_thermalmeter == 0xff) || + rtlefuse->autoload_failflag) { + rtlefuse->apk_thermalmeterignore = true; + rtlefuse->eeprom_thermalmeter = 0xff; + } + + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + + if (!rtlefuse->autoload_failflag) { + rtlefuse->antenna_div_cfg = + (hwinfo[EEPROM_RF_BOARD_OPTION] & 0x18) >> 3; + if (hwinfo[EEPROM_RF_BOARD_OPTION] == 0xff) + rtlefuse->antenna_div_cfg = 0; + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1 && + rtlpriv->btcoexist.btc_info.ant_num == ANT_X1) + rtlefuse->antenna_div_cfg = 0; + + rtlefuse->antenna_div_type = hwinfo[EEPROM_RF_ANTENNA_OPT_88E]; + if (rtlefuse->antenna_div_type == 0xff) + rtlefuse->antenna_div_type = FIXED_HW_ANTDIV; + } else { + rtlefuse->antenna_div_cfg = 0; + rtlefuse->antenna_div_type = 0; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "SWAS: bHwAntDiv = %x, TRxAntDivType = %x\n", + rtlefuse->antenna_div_cfg, rtlefuse->antenna_div_type); + + rtlpriv->ledctl.led_opendrain = true; + + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case RT_CID_DEFAULT: + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_CCX: + rtlhal->oem_id = RT_CID_CCX; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819X_QMI; + break; + case EEPROM_CID_WHQL: + break; + default: + break; + } + } +exit: + kfree(hwinfo); +} + +/*static void _rtl8821ae_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtlpriv->ledctl.led_opendrain = true; + switch (rtlhal->oem_id) { + case RT_CID_819X_HP: + rtlpriv->ledctl.led_opendrain = true; + break; + case RT_CID_819X_LENOVO: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819X_ACER: + case RT_CID_WHQL: + default: + break; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +}*/ + +void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl8821ae_read_chip_version(hw); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + if (tmp_u1b & BIT(4)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + + if (tmp_u1b & BIT(5)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl8821ae_read_adapter_info(hw, false); + } else { + pr_err("Autoload ERR!!\n"); + } + /*hal_ReadRFType_8812A()*/ + /* _rtl8821ae_hal_customized_behavior(hw); */ +} + +static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 b_nmode = mac->ht_enable; + u16 shortgi_rate; + u32 tmp_ratr_value; + u32 ratr_mask; + u8 curtxbw_40mhz = mac->bw_40; + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->deflink.supp_rates[1] << 4; + else + ratr_value = sta->deflink.supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + b_nmode = 1; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + + ratr_value &= ratr_mask; + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + + if ((rtlpriv->btcoexist.bt_coexistence) && + (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) && + (rtlpriv->btcoexist.bt_cur_state) && + (rtlpriv->btcoexist.bt_ant_isolation) && + ((rtlpriv->btcoexist.bt_service == BT_SCO) || + (rtlpriv->btcoexist.bt_service == BT_BUSY))) + ratr_value &= 0x0fffcfc0; + else + ratr_value &= 0x0FFFFFFF; + + if (b_nmode && ((curtxbw_40mhz && + b_curshortgi_40mhz) || (!curtxbw_40mhz && + b_curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static u32 _rtl8821ae_rate_to_bitmap_2ssvht(__le16 vht_rate) +{ + u8 i, j, tmp_rate; + u32 rate_bitmap = 0; + + for (i = j = 0; i < 4; i += 2, j += 10) { + tmp_rate = (le16_to_cpu(vht_rate) >> i) & 3; + + switch (tmp_rate) { + case 2: + rate_bitmap = rate_bitmap | (0x03ff << j); + break; + case 1: + rate_bitmap = rate_bitmap | (0x01ff << j); + break; + case 0: + rate_bitmap = rate_bitmap | (0x00ff << j); + break; + default: + break; + } + } + + return rate_bitmap; +} + +static u32 _rtl8821ae_set_ra_vht_ratr_bitmap(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 ret_bitmap = ratr_bitmap; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 + || rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) + ret_bitmap = ratr_bitmap; + else if (wirelessmode == WIRELESS_MODE_AC_5G + || wirelessmode == WIRELESS_MODE_AC_24G) { + if (rtlphy->rf_type == RF_1T1R) + ret_bitmap = ratr_bitmap & (~BIT21); + else + ret_bitmap = ratr_bitmap & (~(BIT31|BIT21)); + } + + return ret_bitmap; +} + +static u8 _rtl8821ae_get_vht_eni(enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + u8 ret = 0; + if (wirelessmode < WIRELESS_MODE_N_24G) + ret = 0; + else if (wirelessmode == WIRELESS_MODE_AC_24G) { + if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */ + ret = 3; + else /* Mix, 1SS */ + ret = 2; + } else if (wirelessmode == WIRELESS_MODE_AC_5G) { + ret = 1; + } /* VHT */ + + return ret << 4; +} + +static u8 _rtl8821ae_get_ra_ldpc(struct ieee80211_hw *hw, + u8 mac_id, struct rtl_sta_info *sta_entry, + enum wireless_mode wirelessmode) +{ + u8 b_ldpc = 0; + /*not support ldpc, do not open*/ + return b_ldpc << 2; +} + +static u8 _rtl8821ae_get_ra_rftype(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rf_type = RF_1T1R; + + if (rtlphy->rf_type == RF_1T1R) + rf_type = RF_1T1R; + else if (wirelessmode == WIRELESS_MODE_AC_5G + || wirelessmode == WIRELESS_MODE_AC_24G + || wirelessmode == WIRELESS_MODE_AC_ONLY) { + if (ratr_bitmap & 0xffc00000) + rf_type = RF_2T2R; + } else if (wirelessmode == WIRELESS_MODE_N_5G + || wirelessmode == WIRELESS_MODE_N_24G) { + if (ratr_bitmap & 0xfff00000) + rf_type = RF_2T2R; + } + + return rf_type; +} + +static bool _rtl8821ae_get_ra_shortgi(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + u8 mac_id) +{ + bool b_short_gi = false; + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + u8 b_curshortgi_80mhz = 0; + b_curshortgi_80mhz = (sta->deflink.vht_cap.cap & + IEEE80211_VHT_CAP_SHORT_GI_80) ? 1 : 0; + + if (mac_id == MAC_ID_STATIC_FOR_BROADCAST_MULTICAST) + b_short_gi = false; + + if (b_curshortgi_40mhz || b_curshortgi_80mhz + || b_curshortgi_20mhz) + b_short_gi = true; + + return b_short_gi; +} + +static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + enum wireless_mode wirelessmode = 0; + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ? 1 : 0; + bool b_shortgi = false; + u8 rate_mask[7]; + u8 macid = 0; + u8 mimo_ps = IEEE80211_SMPS_OFF; + u8 rf_type; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + + rtl_dbg(rtlpriv, COMP_RATR, DBG_LOUD, + "wireless mode = 0x%x\n", wirelessmode); + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + curtxbw_40mhz = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + if (wirelessmode == WIRELESS_MODE_N_5G || + wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_A) + ratr_bitmap = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; + else + ratr_bitmap = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + + if (wirelessmode == WIRELESS_MODE_N_24G + || wirelessmode == WIRELESS_MODE_N_5G) + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + else if (wirelessmode == WIRELESS_MODE_AC_24G + || wirelessmode == WIRELESS_MODE_AC_5G + || wirelessmode == WIRELESS_MODE_AC_ONLY) + ratr_bitmap |= _rtl8821ae_rate_to_bitmap_2ssvht( + sta->deflink.vht_cap.vht_mcs.rx_mcs_map) << 12; + + b_shortgi = _rtl8821ae_get_ra_shortgi(hw, sta, macid); + rf_type = _rtl8821ae_get_ra_rftype(hw, wirelessmode, ratr_bitmap); + +/*mac id owner*/ + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_G; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + if (wirelessmode == WIRELESS_MODE_N_24G) + ratr_index = RATR_INX_WIRELESS_NGB; + else + ratr_index = RATR_INX_WIRELESS_NG; + + if (mimo_ps == IEEE80211_SMPS_STATIC + || mimo_ps == IEEE80211_SMPS_DYNAMIC) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } else { + if (rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0fff0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0ffff000; + else + ratr_bitmap &= 0x0ffff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0fff0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0ffff000; + else + ratr_bitmap &= 0x0ffff005; + } + } + } + break; + + case WIRELESS_MODE_AC_24G: + ratr_index = RATR_INX_WIRELESS_AC_24N; + if (rssi_level == 1) + ratr_bitmap &= 0xfc3f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0xfffff000; + else + ratr_bitmap &= 0xffffffff; + break; + + case WIRELESS_MODE_AC_5G: + ratr_index = RATR_INX_WIRELESS_AC_5N; + + if (rf_type == RF_1T1R) { + if (rssi_level == 1) /*add by Gary for ac-series*/ + ratr_bitmap &= 0x003f8000; + else if (rssi_level == 2) + ratr_bitmap &= 0x003ff000; + else + ratr_bitmap &= 0x003ff010; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0xfe3f8000; + else if (rssi_level == 2) + ratr_bitmap &= 0xfffff000; + else + ratr_bitmap &= 0xfffff010; + } + break; + + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f8ff0ff; + break; + } + + ratr_index = rtl_mrate_idx_to_arfr_id(hw, ratr_index, wirelessmode); + sta_entry->ratr_index = ratr_index; + ratr_bitmap = _rtl8821ae_set_ra_vht_ratr_bitmap(hw, wirelessmode, + ratr_bitmap); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_LOUD, + "ratr_bitmap :%x\n", ratr_bitmap); + + /* *(u32 *)& rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | + (ratr_index << 28)); */ + + rate_mask[0] = macid; + rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00); + rate_mask[2] = rtlphy->current_chan_bw | ((!update_bw) << 3) + | _rtl8821ae_get_vht_eni(wirelessmode, ratr_bitmap) + | _rtl8821ae_get_ra_ldpc(hw, macid, sta_entry, wirelessmode); + + rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); + rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); + rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); + rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4], rate_mask[5], + rate_mask[6]); + rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RA_MASK, 7, rate_mask); + _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl8821ae_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (rtlpriv->dm.useramask) + rtl8821ae_update_hal_rate_mask(hw, sta, rssi_level, update_bw); + else + /*rtl_dbg(rtlpriv, COMP_RATR,DBG_LOUD, + "rtl8821ae_update_hal_rate_tbl() Error! 8821ae FW RA Only\n");*/ + rtl8821ae_update_hal_rate_table(hw, sta); +} + +void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 wireless_mode = mac->mode; + u8 sifs_timer, r2t_sifs; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (wireless_mode == WIRELESS_MODE_G) + sifs_timer = 0x0a; + else + sifs_timer = 0x0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); + + r2t_sifs = 0xa; + + if (wireless_mode == WIRELESS_MODE_AC_5G && + (mac->vht_ldpc_cap & LDPC_VHT_ENABLE_RX) && + (mac->vht_stbc_cap & STBC_VHT_ENABLE_RX)) { + if (mac->vendor == PEER_ATH) + r2t_sifs = 0x8; + else + r2t_sifs = 0xa; + } else if (wireless_mode == WIRELESS_MODE_AC_5G) { + r2t_sifs = 0xa; + } + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_R2T_SIFS, (u8 *)&r2t_sifs); +} + +bool rtl8821ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp = 0; + bool b_actuallyset = false; + + if (rtlpriv->rtlhal.being_init_adapter) + return false; + + if (ppsc->swrf_processing) + return false; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, + rtl_read_byte(rtlpriv, + REG_GPIO_IO_SEL_2) & ~(BIT(1))); + + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); + + if (rtlphy->polarity_ctl) + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; + else + e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; + + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio ON, RF ON\n"); + + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + b_actuallyset = true; + } else if ((!ppsc->hwradiooff) + && (e_rfpowerstate_toset == ERFOFF)) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); + + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + b_actuallyset = true; + } + + if (b_actuallyset) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + + *valid = 1; + return !ppsc->hwradiooff; +} + +void rtl8821ae_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("an not find free hwsecurity cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); + if (is_pairwise) { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } + } +} + +void rtl8821ae_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8821ae_bt_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); +} + +void rtl8821ae_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl8821ae_resume(struct ieee80211_hw *hw) +{ +} + +/* Turn on AAP (RCR:bit 0) for promiscuous mode. */ +void rtl8821ae_allow_all_destaddr(struct ieee80211_hw *hw, + bool allow_all_da, bool write_into_reg) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + if (allow_all_da) /* Set BIT0 */ + rtlpci->receive_config |= RCR_AAP; + else /* Clear BIT0 */ + rtlpci->receive_config &= ~RCR_AAP; + + if (write_into_reg) + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + + rtl_dbg(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, + "receive_config=0x%08X, write_into_reg=%d\n", + rtlpci->receive_config, write_into_reg); +} + +/* WKFMCAMAddAllEntry8812 */ +void rtl8821ae_add_wowlan_pattern(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 cam = 0; + u8 addr = 0; + u16 rxbuf_addr; + u8 tmp, count = 0; + u16 cam_start; + u16 offset; + + /* Count the WFCAM entry start offset. */ + + /* RX page size = 128 byte */ + offset = MAX_RX_DMA_BUFFER_SIZE_8812 / 128; + /* We should start from the boundary */ + cam_start = offset * 128; + + /* Enable Rx packet buffer access. */ + rtl_write_byte(rtlpriv, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT); + for (addr = 0; addr < WKFMCAM_ADDR_NUM; addr++) { + /* Set Rx packet buffer offset. + * RXBufer pointer increases 1, + * we can access 8 bytes in Rx packet buffer. + * CAM start offset (unit: 1 byte) = index*WKFMCAM_SIZE + * RXBufer addr = (CAM start offset + + * per entry offset of a WKFM CAM)/8 + * * index: The index of the wake up frame mask + * * WKFMCAM_SIZE: the total size of one WKFM CAM + * * per entry offset of a WKFM CAM: Addr*4 bytes + */ + rxbuf_addr = (cam_start + index * WKFMCAM_SIZE + addr * 4) >> 3; + /* Set R/W start offset */ + rtl_write_word(rtlpriv, REG_PKTBUF_DBG_CTRL, rxbuf_addr); + + if (addr == 0) { + cam = BIT(31) | rtl_pattern->crc; + + if (rtl_pattern->type == UNICAST_PATTERN) + cam |= BIT(24); + else if (rtl_pattern->type == MULTICAST_PATTERN) + cam |= BIT(25); + else if (rtl_pattern->type == BROADCAST_PATTERN) + cam |= BIT(26); + + rtl_write_dword(rtlpriv, REG_PKTBUF_DBG_DATA_L, cam); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "WRITE entry[%d] 0x%x: %x\n", addr, + REG_PKTBUF_DBG_DATA_L, cam); + + /* Write to Rx packet buffer. */ + rtl_write_word(rtlpriv, REG_RXPKTBUF_CTRL, 0x0f01); + } else if (addr == 2 || addr == 4) {/* WKFM[127:0] */ + cam = rtl_pattern->mask[addr - 2]; + + rtl_write_dword(rtlpriv, REG_PKTBUF_DBG_DATA_L, cam); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "WRITE entry[%d] 0x%x: %x\n", addr, + REG_PKTBUF_DBG_DATA_L, cam); + + rtl_write_word(rtlpriv, REG_RXPKTBUF_CTRL, 0x0f01); + } else if (addr == 3 || addr == 5) {/* WKFM[127:0] */ + cam = rtl_pattern->mask[addr - 2]; + + rtl_write_dword(rtlpriv, REG_PKTBUF_DBG_DATA_H, cam); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "WRITE entry[%d] 0x%x: %x\n", addr, + REG_PKTBUF_DBG_DATA_H, cam); + + rtl_write_word(rtlpriv, REG_RXPKTBUF_CTRL, 0xf001); + } + + count = 0; + do { + tmp = rtl_read_byte(rtlpriv, REG_RXPKTBUF_CTRL); + udelay(2); + count++; + } while (tmp && count < 100); + + WARN_ONCE((count >= 100), + "rtl8821ae: Write wake up frame mask FAIL %d value!\n", + tmp); + } + /* Disable Rx packet buffer access. */ + rtl_write_byte(rtlpriv, REG_PKT_BUFF_ACCESS_CTRL, + DISABLE_TRXPKT_BUF_ACCESS); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h new file mode 100644 index 000000000..fb0fb3a50 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_HW_H__ +#define __RTL8821AE_HW_H__ + +void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw); + +void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, + struct rtl_int *int_vec); +int rtl8821ae_hw_init(struct ieee80211_hw *hw); +void rtl8821ae_card_disable(struct ieee80211_hw *hw); +void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw); +void rtl8821ae_disable_interrupt(struct ieee80211_hw *hw); +int rtl8821ae_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl8821ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8821ae_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8821ae_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8821ae_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw); +void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8821ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8821ae_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8821ae_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +void rtl8821ae_bt_reg_init(struct ieee80211_hw *hw); +void rtl8821ae_bt_hw_init(struct ieee80211_hw *hw); +void rtl8821ae_suspend(struct ieee80211_hw *hw); +void rtl8821ae_resume(struct ieee80211_hw *hw); +void rtl8821ae_allow_all_destaddr(struct ieee80211_hw *hw, + bool allow_all_da, + bool write_into_reg); +void _rtl8821ae_stop_tx_beacon(struct ieee80211_hw *hw); +void _rtl8821ae_resume_tx_beacon(struct ieee80211_hw *hw); +void rtl8821ae_add_wowlan_pattern(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c new file mode 100644 index 000000000..fb003f9ce --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u16 ledreg = REG_LEDCFG1; + u8 ledcfg = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (pin) { + case LED_PIN_LED0: + ledreg = REG_LEDCFG1; + break; + + case LED_PIN_LED1: + ledreg = REG_LEDCFG2; + break; + + case LED_PIN_GPIO0: + default: + break; + } + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "In SwLedOn, LedAddr:%X LEDPIN=%d\n", + ledreg, pin); + + ledcfg = rtl_read_byte(rtlpriv, ledreg); + ledcfg |= BIT(5); /*Set 0x4c[21]*/ + ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); + /*Clear 0x4c[23:22] and 0x4c[19:16]*/ + rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/ +} + +void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 ledcfg; + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (rtlpriv->ledctl.led_opendrain) { + ledcfg &= 0x90; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); + ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); + ledcfg &= 0xFE; + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); + } else { + ledcfg &= ~BIT(6); + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5))); + } + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + ledcfg &= 0x10; /* Set to software control. */ + rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", pin); + break; + } +} + +void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) +{ + u16 ledreg = REG_LEDCFG1; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (pin) { + case LED_PIN_LED0: + ledreg = REG_LEDCFG1; + break; + + case LED_PIN_LED1: + ledreg = REG_LEDCFG2; + break; + + case LED_PIN_GPIO0: + default: + break; + } + + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, + "In SwLedOff,LedAddr:%X LEDPIN=%d\n", + ledreg, pin); + /*Open-drain arrangement for controlling the LED*/ + if (rtlpriv->ledctl.led_opendrain) { + u8 ledcfg = rtl_read_byte(rtlpriv, ledreg); + + ledreg &= 0xd0; /* Set to software control.*/ + rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3))); + + /*Open-drain arrangement*/ + ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); + ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/ + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); + } else { + rtl_write_byte(rtlpriv, ledreg, 0x28); + } +} + +static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_sw_led_on(hw, pin0); + else + rtl8821ae_sw_led_on(hw, pin0); + break; + case LED_CTL_POWER_OFF: + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtl8812ae_sw_led_off(hw, pin0); + else + rtl8821ae_sw_led_off(hw, pin0); + break; + default: + break; + } +} + +void rtl8821ae_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", + ledaction); + _rtl8821ae_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h new file mode 100644 index 000000000..76d5c0b0e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_LED_H__ +#define __RTL8821AE_LED_H__ + +void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin); +void rtl8821ae_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c new file mode 100644 index 000000000..13a05066e --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -0,0 +1,4787 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" +#include "trx.h" +#include "../btcoexist/halbt_precomp.h" +#include "hw.h" +#include "../efuse.h" + +#define READ_NEXT_PAIR(array_table, v1, v2, i) \ + do { \ + i += 2; \ + v1 = array_table[i]; \ + v2 = array_table[i+1]; \ + } while (0) + +static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); +/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ +static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); + +static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw); + +static void rtl8812ae_fixspur(struct ieee80211_hw *hw, + enum ht_channel_width band_width, u8 channel) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /*C cut Item12 ADC FIFO CLOCK*/ + if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) { + if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11) + rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3); + /* 0x8AC[11:10] = 2'b11*/ + else + rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2); + /* 0x8AC[11:10] = 2'b10*/ + + /* <20120914, Kordan> A workaround to resolve + * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson) + */ + if (band_width == HT_CHANNEL_WIDTH_20 && + (channel == 13 || channel == 14)) { + rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3); + /*0x8AC[9:8] = 2'b11*/ + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); + /* 0x8C4[30] = 1*/ + } else if (band_width == HT_CHANNEL_WIDTH_20_40 && + channel == 11) { + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); + /*0x8C4[30] = 1*/ + } else if (band_width != HT_CHANNEL_WIDTH_80) { + rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2); + /*0x8AC[9:8] = 2'b10*/ + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); + /*0x8C4[30] = 0*/ + } + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + /* <20120914, Kordan> A workaround to resolve + * 2480Mhz spur by setting ADC clock as 160M. + */ + if (band_width == HT_CHANNEL_WIDTH_20 && + (channel == 13 || channel == 14)) + rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3); + /*0x8AC[9:8] = 11*/ + else if (channel <= 14) /*2.4G only*/ + rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2); + /*0x8AC[9:8] = 10*/ + } +} + +u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + return returnvalue; +} + +void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | + ((data << bitshift) & bitmask)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); +} + +u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); + + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); + + return readback_value; +} + +void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock(&rtlpriv->locks.rf_lock); + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = + _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | (data << bitshift)); + } + + _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data); + + spin_unlock(&rtlpriv->locks.rf_lock); + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_pi_mode = false; + u32 retvalue = 0; + + /* 2009/06/17 MH We can not execute IO for power + save or other accident mode.*/ + if (RT_CANNOT_IO(hw)) { + pr_err("return all one\n"); + return 0xFFFFFFFF; + } + /* <20120809, Kordan> CCA OFF(when entering), + asked by James to avoid reading the wrong value. + <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/ + if (offset != 0x0 && + !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || + (IS_VENDOR_8812A_C_CUT(rtlhal->version)))) + rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1); + offset &= 0xff; + + if (rfpath == RF90_PATH_A) + is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4); + else if (rfpath == RF90_PATH_B) + is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4); + + rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset); + + if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || + (IS_VENDOR_8812A_C_CUT(rtlhal->version))) + udelay(20); + + if (is_pi_mode) { + if (rfpath == RF90_PATH_A) + retvalue = + rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA); + else if (rfpath == RF90_PATH_B) + retvalue = + rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA); + } else { + if (rfpath == RF90_PATH_A) + retvalue = + rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA); + else if (rfpath == RF90_PATH_B) + retvalue = + rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA); + } + + /*<20120809, Kordan> CCA ON(when exiting), + * asked by James to avoid reading the wrong value. + * <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it! + */ + if (offset != 0x0 && + !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || + (IS_VENDOR_8812A_C_CUT(rtlhal->version)))) + rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0); + return retvalue; +} + +static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 data_and_addr; + u32 newoffset; + + if (RT_CANNOT_IO(hw)) { + pr_err("stop\n"); + return; + } + offset &= 0xff; + newoffset = offset; + data_and_addr = ((newoffset << 20) | + (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); +} + +bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw) +{ + bool rtstatus = 0; + + rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw); + + return rtstatus; +} + +bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 regval; + u8 crystal_cap; + + phy_init_bb_rf_register_definition(hw); + + regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); + regval |= FEN_PCIEA; + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, + regval | FEN_BB_GLB_RSTN | FEN_BBRSTB); + + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7); + rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7); + + rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + crystal_cap = rtlefuse->crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000, + (crystal_cap | (crystal_cap << 6))); + } else { + crystal_cap = rtlefuse->crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, + (crystal_cap | (crystal_cap << 6))); + } + rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837); + + return rtstatus; +} + +bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl8821ae_phy_rf6052_config(hw); +} + +static void _rtl8812ae_phy_set_rfe_reg_24g(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp; + + switch (rtlhal->rfe_type) { + case 3: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337770); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337770); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1); + break; + case 4: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x001); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x001); + break; + case 5: + rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x77); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777); + tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3); + rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp & ~0x1); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000); + break; + case 1: + if (rtlpriv->btcoexist.bt_coexistence) { + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x777777); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, + 0x77777777); + rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000); + break; + } + fallthrough; + case 0: + case 2: + default: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000); + break; + } +} + +static void _rtl8812ae_phy_set_rfe_reg_5g(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp; + + switch (rtlhal->rfe_type) { + case 0: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337717); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337717); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010); + break; + case 1: + if (rtlpriv->btcoexist.bt_coexistence) { + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x337717); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, + 0x77337717); + rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000); + } else { + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, + 0x77337717); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, + 0x77337717); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000); + } + break; + case 3: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337717); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337717); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1); + break; + case 5: + rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x33); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777); + tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3); + rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp | 0x1); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010); + break; + case 2: + case 4: + default: + rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777); + rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777); + rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010); + rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010); + break; + } +} + +u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band, + u8 rf_path) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + s8 reg_swing_2g = -1;/* 0xff; */ + s8 reg_swing_5g = -1;/* 0xff; */ + s8 swing_2g = -1 * reg_swing_2g; + s8 swing_5g = -1 * reg_swing_5g; + u32 out = 0x200; + const s8 auto_temp = -1; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "===> PHY_GetTXBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n", + (int)swing_2g, (int)swing_5g, + (int)rtlefuse->autoload_failflag); + + if (rtlefuse->autoload_failflag) { + if (band == BAND_ON_2_4G) { + rtldm->swing_diff_2g = swing_2g; + if (swing_2g == 0) { + out = 0x200; /* 0 dB */ + } else if (swing_2g == -3) { + out = 0x16A; /* -3 dB */ + } else if (swing_2g == -6) { + out = 0x101; /* -6 dB */ + } else if (swing_2g == -9) { + out = 0x0B6; /* -9 dB */ + } else { + rtldm->swing_diff_2g = 0; + out = 0x200; + } + } else if (band == BAND_ON_5G) { + rtldm->swing_diff_5g = swing_5g; + if (swing_5g == 0) { + out = 0x200; /* 0 dB */ + } else if (swing_5g == -3) { + out = 0x16A; /* -3 dB */ + } else if (swing_5g == -6) { + out = 0x101; /* -6 dB */ + } else if (swing_5g == -9) { + out = 0x0B6; /* -9 dB */ + } else { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + rtldm->swing_diff_5g = -3; + out = 0x16A; + } else { + rtldm->swing_diff_5g = 0; + out = 0x200; + } + } + } else { + rtldm->swing_diff_2g = -3; + rtldm->swing_diff_5g = -3; + out = 0x16A; /* -3 dB */ + } + } else { + u32 swing = 0, swing_a = 0, swing_b = 0; + + if (band == BAND_ON_2_4G) { + if (reg_swing_2g == auto_temp) { + efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing); + swing = (swing == 0xFF) ? 0x00 : swing; + } else if (swing_2g == 0) { + swing = 0x00; /* 0 dB */ + } else if (swing_2g == -3) { + swing = 0x05; /* -3 dB */ + } else if (swing_2g == -6) { + swing = 0x0A; /* -6 dB */ + } else if (swing_2g == -9) { + swing = 0xFF; /* -9 dB */ + } else { + swing = 0x00; + } + } else { + if (reg_swing_5g == auto_temp) { + efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing); + swing = (swing == 0xFF) ? 0x00 : swing; + } else if (swing_5g == 0) { + swing = 0x00; /* 0 dB */ + } else if (swing_5g == -3) { + swing = 0x05; /* -3 dB */ + } else if (swing_5g == -6) { + swing = 0x0A; /* -6 dB */ + } else if (swing_5g == -9) { + swing = 0xFF; /* -9 dB */ + } else { + swing = 0x00; + } + } + + swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */ + swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */ + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "===> PHY_GetTXBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n", + swing_a, swing_b); + + /* 3 Path-A */ + if (swing_a == 0x0) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = 0; + else + rtldm->swing_diff_5g = 0; + out = 0x200; /* 0 dB */ + } else if (swing_a == 0x1) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -3; + else + rtldm->swing_diff_5g = -3; + out = 0x16A; /* -3 dB */ + } else if (swing_a == 0x2) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -6; + else + rtldm->swing_diff_5g = -6; + out = 0x101; /* -6 dB */ + } else if (swing_a == 0x3) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -9; + else + rtldm->swing_diff_5g = -9; + out = 0x0B6; /* -9 dB */ + } + /* 3 Path-B */ + if (swing_b == 0x0) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = 0; + else + rtldm->swing_diff_5g = 0; + out = 0x200; /* 0 dB */ + } else if (swing_b == 0x1) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -3; + else + rtldm->swing_diff_5g = -3; + out = 0x16A; /* -3 dB */ + } else if (swing_b == 0x2) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -6; + else + rtldm->swing_diff_5g = -6; + out = 0x101; /* -6 dB */ + } else if (swing_b == 0x3) { + if (band == BAND_ON_2_4G) + rtldm->swing_diff_2g = -9; + else + rtldm->swing_diff_5g = -9; + out = 0x0B6; /* -9 dB */ + } + } + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "<=== PHY_GetTXBBSwing_8812A, out = 0x%X\n", out); + return out; +} + +void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_dm *rtldm = rtl_dm(rtlpriv); + u8 current_band = rtlhal->current_bandtype; + s8 bb_diff_between_band; + + rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0); + rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000); + rtlhal->current_bandtype = (enum band_type) band; + /* reconfig BB/RF according to wireless mode */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* BB & RF Config */ + rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* 0xCB0[15:12] = 0x7 (LNA_On)*/ + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7); + /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + /*0x834[1:0] = 0x1*/ + rtl_set_bbreg(hw, 0x834, 0x3, 0x1); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* 0xC1C[11:8] = 0 */ + rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0); + } else { + /* 0x82C[1:0] = 2b'00 */ + rtl_set_bbreg(hw, 0x82c, 0x3, 0); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + _rtl8812ae_phy_set_rfe_reg_24g(hw); + + rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1); + rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1); + + rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0); + } else {/* 5G band */ + u16 count, reg_41a; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /*0xCB0[15:12] = 0x5 (LNA_On)*/ + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5); + /*0xCB0[7:4] = 0x4 (PAPE_A)*/ + rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4); + } + /*CCK_CHECK_en*/ + rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80); + + count = 0; + reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Reg41A value %d\n", reg_41a); + reg_41a &= 0x30; + while ((reg_41a != 0x30) && (count < 50)) { + udelay(50); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n"); + + reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); + reg_41a &= 0x30; + count++; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Reg41A value %d\n", reg_41a); + } + if (count != 0) + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n", + count, reg_41a); + + /* 2012/02/01, Sinda add registry to switch workaround + without long-run verification for scan issue. */ + rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + /*0x834[1:0] = 0x2*/ + rtl_set_bbreg(hw, 0x834, 0x3, 0x2); + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + /* AGC table select */ + /* 0xC1C[11:8] = 1*/ + rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1); + } else + /* 0x82C[1:0] = 2'b00 */ + rtl_set_bbreg(hw, 0x82c, 0x3, 1); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + _rtl8812ae_phy_set_rfe_reg_5g(hw); + + rtl_set_bbreg(hw, RTXPATH, 0xf0, 0); + rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf); + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n", + rtlpriv->dm.ofdm_index[RF90_PATH_A]); + } + + if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || + (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) { + /* 0xC1C[31:21] */ + rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, + phy_get_tx_swing_8812A(hw, band, RF90_PATH_A)); + /* 0xE1C[31:21] */ + rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, + phy_get_tx_swing_8812A(hw, band, RF90_PATH_B)); + + /* <20121005, Kordan> When TxPowerTrack is ON, + * we should take care of the change of BB swing. + * That is, reset all info to trigger Tx power tracking. + */ + if (band != current_band) { + bb_diff_between_band = + (rtldm->swing_diff_2g - rtldm->swing_diff_5g); + bb_diff_between_band = (band == BAND_ON_2_4G) ? + bb_diff_between_band : + (-1 * bb_diff_between_band); + rtldm->default_ofdm_index += bb_diff_between_band * 2; + } + rtl8821ae_dm_clear_txpower_tracking_state(hw); + } + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "<==%s():Switch Band OK.\n", __func__); + return; +} + +static bool _rtl8821ae_check_positive(struct ieee80211_hw *hw, + const u32 condition1, + const u32 condition2) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK) + >> CHIP_VER_RTL_SHIFT); + u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0)); + + u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */ + ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */ + ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */ + ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */ + + u32 cond1 = condition1, cond2 = condition2; + u32 driver1 = cut_ver << 24 | /* CUT ver */ + 0 << 20 | /* interface 2/2 */ + 0x04 << 16 | /* platform */ + rtlhal->package_type << 12 | + intf << 8 | /* interface 1/2 */ + board_type; + + u32 driver2 = rtlhal->type_glna << 0 | + rtlhal->type_gpa << 8 | + rtlhal->type_alna << 16 | + rtlhal->type_apa << 24; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n", + cond1, cond2); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n", + driver1, driver2); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + " (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + " (Board, Package) = (0x%X, 0x%X)\n", + rtlhal->board_type, rtlhal->package_type); + + /*============== Value Defined Check ===============*/ + /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != + (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != + (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 mask = 0; + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + mask |= 0xFF000000; + + /* BoardType of each RF path is matched*/ + if ((cond2 & mask) == (driver2 & mask)) + return true; + else + return false; + } else + return false; +} + +static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw, + const u32 condition) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 _board = rtlefuse->board_type; /*need efuse define*/ + u32 _interface = 0x01; /* ODM_ITRF_PCIE */ + u32 _platform = 0x08;/* ODM_WIN */ + u32 cond = condition; + + if (condition == 0xCDCDCDCD) + return true; + + cond = condition & 0xFF; + if ((_board != cond) && cond != 0xFF) + return false; + + cond = condition & 0xFF00; + cond = cond >> 8; + if ((_interface & cond) == 0 && cond != 0x07) + return false; + + cond = condition & 0xFF0000; + cond = cond >> 16; + if ((_platform & cond) == 0 && cond != 0x0F) + return false; + return true; +} + +static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw, + u32 addr, u32 data, + enum radio_path rfpath, u32 regaddr) +{ + if (addr == 0xfe || addr == 0xffe) { + /* In order not to disturb BT music when + * wifi init.(1ant NIC only) + */ + mdelay(50); + } else { + rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); + udelay(1); + } +} + +static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1000; /*RF Content: radio_a_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl8821ae_config_rf_reg(hw, addr, data, + RF90_PATH_A, addr | maskforphyset); +} + +static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + u32 content = 0x1001; /*RF Content: radio_b_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + _rtl8821ae_config_rf_reg(hw, addr, data, + RF90_PATH_B, addr | maskforphyset); +} + +static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + if (addr == 0xfe) + mdelay(50); + else if (addr == 0xfd) + mdelay(5); + else if (addr == 0xfc) + mdelay(1); + else if (addr == 0xfb) + udelay(50); + else if (addr == 0xfa) + udelay(5); + else if (addr == 0xf9) + udelay(1); + else + rtl_set_bbreg(hw, addr, MASKDWORD, data); + + udelay(1); +} + +static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 band, rfpath, txnum, rate_section; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) + for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath) + for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) + for (rate_section = 0; + rate_section < TX_PWR_BY_RATE_NUM_SECTION; + ++rate_section) + rtlphy->tx_power_by_rate_offset[band] + [rfpath][txnum][rate_section] = 0; +} + +static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, + u8 rate_section, + u8 txnum, u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path); + return; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; + break; + case OFDM: + rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; + break; + case HT_MCS0_MCS7: + rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; + break; + case HT_MCS8_MCS15: + rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; + break; + case VHT_1SSMCS0_1SSMCS9: + rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value; + break; + case VHT_2SSMCS0_2SSMCS9: + rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else if (band == BAND_ON_5G) { + switch (rate_section) { + case OFDM: + rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value; + break; + case HT_MCS0_MCS7: + rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value; + break; + case HT_MCS8_MCS15: + rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value; + break; + case VHT_1SSMCS0_1SSMCS9: + rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value; + break; + case VHT_2SSMCS0_2SSMCS9: + rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band); + } +} + +static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, + u8 txnum, u8 rate_section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 value = 0; + + if (path > RF90_PATH_D) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", + path); + return 0; + } + + if (band == BAND_ON_2_4G) { + switch (rate_section) { + case CCK: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; + break; + case OFDM: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; + break; + case HT_MCS0_MCS7: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; + break; + case HT_MCS8_MCS15: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; + break; + case VHT_1SSMCS0_1SSMCS9: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4]; + break; + case VHT_2SSMCS0_2SSMCS9: + value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5]; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else if (band == BAND_ON_5G) { + switch (rate_section) { + case OFDM: + value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0]; + break; + case HT_MCS0_MCS7: + value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1]; + break; + case HT_MCS8_MCS15: + value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2]; + break; + case VHT_1SSMCS0_1SSMCS9: + value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3]; + break; + case VHT_2SSMCS0_2SSMCS9: + value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4]; + break; + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", + rate_section, path, txnum); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band); + } + + return value; +} + +static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u16 rawvalue = 0; + u8 base = 0, path = 0; + + for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base); + } +} + +static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, + u8 end, u8 base_val) +{ + int i; + u8 temp_value = 0; + u32 temp_data = 0; + + for (i = 3; i >= 0; --i) { + if (i >= start && i <= end) { + /* Get the exact value */ + temp_value = (u8)(*data >> (i * 8)) & 0xF; + temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10; + + /* Change the value to a relative value */ + temp_value = (temp_value > base_val) ? temp_value - + base_val : base_val - temp_value; + } else { + temp_value = (u8)(*data >> (i * 8)) & 0xFF; + } + temp_data <<= 8; + temp_data |= temp_value; + } + *data = temp_data; +} + +static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 regulation, bw, channel, rate_section; + s8 temp_pwrlmt = 0; + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) { + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { + temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation] + [bw][rate_section][channel][RF90_PATH_A]; + if (temp_pwrlmt == MAX_POWER_INDEX) { + if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/ + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n", + 1, bw, rate_section, channel, RF90_PATH_A); + if (rate_section == 2) { + rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] = + rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A]; + } else if (rate_section == 4) { + rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] = + rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A]; + } else if (rate_section == 3) { + rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] = + rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A]; + } else if (rate_section == 5) { + rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] = + rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A]; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "use other value %d\n", + temp_pwrlmt); + } + } + } + } + } + } +} + +static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw, + enum band_type band, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 index = 0; + if (band == BAND_ON_2_4G) { + switch (rate) { + case MGN_1M: + case MGN_2M: + case MGN_5_5M: + case MGN_11M: + index = 0; + break; + + case MGN_6M: + case MGN_9M: + case MGN_12M: + case MGN_18M: + case MGN_24M: + case MGN_36M: + case MGN_48M: + case MGN_54M: + index = 1; + break; + + case MGN_MCS0: + case MGN_MCS1: + case MGN_MCS2: + case MGN_MCS3: + case MGN_MCS4: + case MGN_MCS5: + case MGN_MCS6: + case MGN_MCS7: + index = 2; + break; + + case MGN_MCS8: + case MGN_MCS9: + case MGN_MCS10: + case MGN_MCS11: + case MGN_MCS12: + case MGN_MCS13: + case MGN_MCS14: + case MGN_MCS15: + index = 3; + break; + + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n", + rate); + break; + } + } else if (band == BAND_ON_5G) { + switch (rate) { + case MGN_6M: + case MGN_9M: + case MGN_12M: + case MGN_18M: + case MGN_24M: + case MGN_36M: + case MGN_48M: + case MGN_54M: + index = 0; + break; + + case MGN_MCS0: + case MGN_MCS1: + case MGN_MCS2: + case MGN_MCS3: + case MGN_MCS4: + case MGN_MCS5: + case MGN_MCS6: + case MGN_MCS7: + index = 1; + break; + + case MGN_MCS8: + case MGN_MCS9: + case MGN_MCS10: + case MGN_MCS11: + case MGN_MCS12: + case MGN_MCS13: + case MGN_MCS14: + case MGN_MCS15: + index = 2; + break; + + case MGN_VHT1SS_MCS0: + case MGN_VHT1SS_MCS1: + case MGN_VHT1SS_MCS2: + case MGN_VHT1SS_MCS3: + case MGN_VHT1SS_MCS4: + case MGN_VHT1SS_MCS5: + case MGN_VHT1SS_MCS6: + case MGN_VHT1SS_MCS7: + case MGN_VHT1SS_MCS8: + case MGN_VHT1SS_MCS9: + index = 3; + break; + + case MGN_VHT2SS_MCS0: + case MGN_VHT2SS_MCS1: + case MGN_VHT2SS_MCS2: + case MGN_VHT2SS_MCS3: + case MGN_VHT2SS_MCS4: + case MGN_VHT2SS_MCS5: + case MGN_VHT2SS_MCS6: + case MGN_VHT2SS_MCS7: + case MGN_VHT2SS_MCS8: + case MGN_VHT2SS_MCS9: + index = 4; + break; + + default: + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n", + rate); + break; + } + } + + return index; +} + +static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G; + u8 regulation, bw, channel, rate_section; + u8 base_index2_4G = 0; + u8 base_index5G = 0; + s8 temp_value = 0, temp_pwrlmt = 0; + u8 rf_path = 0; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n"); + + _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw); + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) { + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { + /* obtain the base dBm values in 2.4G band + CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/ + if (rate_section == 0) { /*CCK*/ + base_index2_4G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_2_4G, MGN_11M); + } else if (rate_section == 1) { /*OFDM*/ + base_index2_4G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_2_4G, MGN_54M); + } else if (rate_section == 2) { /*HT IT*/ + base_index2_4G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_2_4G, MGN_MCS7); + } else if (rate_section == 3) { /*HT 2T*/ + base_index2_4G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_2_4G, MGN_MCS15); + } + + temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation] + [bw][rate_section][channel][RF90_PATH_A]; + + for (rf_path = RF90_PATH_A; + rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + if (rate_section == 3) + bw40_pwr_base_dbm2_4G = + rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G]; + else + bw40_pwr_base_dbm2_4G = + rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G]; + + if (temp_pwrlmt != MAX_POWER_INDEX) { + temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G; + rtlphy->txpwr_limit_2_4g[regulation] + [bw][rate_section][channel][rf_path] = + temp_value; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfpath %d] %d)\n", + regulation, bw, rate_section, channel, + rtlphy->txpwr_limit_2_4g[regulation][bw] + [rate_section][channel][rf_path], (temp_pwrlmt == 63) + ? 0 : temp_pwrlmt/2, channel, rf_path, + bw40_pwr_base_dbm2_4G); + } + } + } + } + } + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) { + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { + /* obtain the base dBm values in 5G band + OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15, + VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/ + if (rate_section == 1) { /*OFDM*/ + base_index5G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_5G, MGN_54M); + } else if (rate_section == 2) { /*HT 1T*/ + base_index5G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_5G, MGN_MCS7); + } else if (rate_section == 3) { /*HT 2T*/ + base_index5G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_5G, MGN_MCS15); + } else if (rate_section == 4) { /*VHT 1T*/ + base_index5G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_5G, MGN_VHT1SS_MCS7); + } else if (rate_section == 5) { /*VHT 2T*/ + base_index5G = + _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, + BAND_ON_5G, MGN_VHT2SS_MCS7); + } + + temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation] + [bw][rate_section][channel] + [RF90_PATH_A]; + + for (rf_path = RF90_PATH_A; + rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + if (rate_section == 3 || rate_section == 5) + bw40_pwr_base_dbm5G = + rtlphy->txpwr_by_rate_base_5g[rf_path] + [RF_2TX][base_index5G]; + else + bw40_pwr_base_dbm5G = + rtlphy->txpwr_by_rate_base_5g[rf_path] + [RF_1TX][base_index5G]; + + if (temp_pwrlmt != MAX_POWER_INDEX) { + temp_value = + temp_pwrlmt - bw40_pwr_base_dbm5G; + rtlphy->txpwr_limit_5g[regulation] + [bw][rate_section][channel] + [rf_path] = temp_value; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfpath %d] %d)\n", + regulation, bw, rate_section, + channel, rtlphy->txpwr_limit_5g[regulation] + [bw][rate_section][channel][rf_path], + temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G); + } + } + } + } + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "<===== %s()\n", __func__); +} + +static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i, j, k, l, m; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "=====>`%s()!\n", __func__); + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_2_4g + [i][j][k][m][l] + = MAX_POWER_INDEX; + } + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_5g + [i][j][k][m][l] + = MAX_POWER_INDEX; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "<===== %s()!\n", __func__); +} + +static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 base = 0, rfpath = 0; + + for (rfpath = RF90_PATH_A; rfpath <= RF90_PATH_B; ++rfpath) { + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, CCK); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, OFDM); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, HT_MCS0_MCS7); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_2TX, HT_MCS8_MCS15); + + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][5], + 0, 3, base); + + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, VHT_1SSMCS0_1SSMCS9); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][7], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][8], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][9], + 0, 1, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_2TX, VHT_2SSMCS0_2SSMCS9); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][9], + 2, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][10], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][11], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, OFDM); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][1], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][2], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, HT_MCS0_MCS7); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][3], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][4], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_2TX, HT_MCS8_MCS15); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][5], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][6], + 0, 3, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, VHT_1SSMCS0_1SSMCS9); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][7], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][8], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][9], + 0, 1, base); + + base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_2TX, VHT_2SSMCS0_2SSMCS9); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][9], + 2, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][10], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][11], + 0, 3, base); + } + + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n"); +} + +static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) +{ + _rtl8821ae_phy_store_txpower_by_rate_base(hw); + _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw); +} + +/* string is in decimal */ +static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint) +{ + u16 i = 0; + *pint = 0; + + while (str[i] != '\0') { + if (str[i] >= '0' && str[i] <= '9') { + *pint *= 10; + *pint += (str[i] - '0'); + } else { + return false; + } + ++i; + } + + return true; +} + +static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, + u8 band, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + s8 channel_index = -1; + u8 i = 0; + + if (band == BAND_ON_2_4G) + channel_index = channel - 1; + else if (band == BAND_ON_5G) { + for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) { + if (channel5g[i] == channel) + channel_index = i; + } + } else + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n", + band, __func__); + + if (channel_index == -1) + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Channel %d of Band %d in %s\n", channel, + band, __func__); + + return channel_index; +} + +static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, + const char *pregulation, + const char *pband, const char *pbandwidth, + const char *prate_section, const char *prf_path, + const char *pchannel, const char *ppower_limit) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 regulation = 0, bandwidth = 0, rate_section = 0, channel; + u8 channel_index; + s8 power_limit = 0, prev_power_limit, ret; + + if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) || + !_rtl8812ae_get_integer_from_string(ppower_limit, + &power_limit)) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Illegal index of pwr_lmt table [chnl %d][val %d]\n", + channel, power_limit); + } + + power_limit = power_limit > MAX_POWER_INDEX ? + MAX_POWER_INDEX : power_limit; + + if (strcmp(pregulation, "FCC") == 0) + regulation = 0; + else if (strcmp(pregulation, "MKK") == 0) + regulation = 1; + else if (strcmp(pregulation, "ETSI") == 0) + regulation = 2; + else if (strcmp(pregulation, "WW13") == 0) + regulation = 3; + + if (strcmp(prate_section, "CCK") == 0) + rate_section = 0; + else if (strcmp(prate_section, "OFDM") == 0) + rate_section = 1; + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "1T") == 0) + rate_section = 2; + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "2T") == 0) + rate_section = 3; + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "1T") == 0) + rate_section = 4; + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "2T") == 0) + rate_section = 5; + + if (strcmp(pbandwidth, "20M") == 0) + bandwidth = 0; + else if (strcmp(pbandwidth, "40M") == 0) + bandwidth = 1; + else if (strcmp(pbandwidth, "80M") == 0) + bandwidth = 2; + else if (strcmp(pbandwidth, "160M") == 0) + bandwidth = 3; + + if (strcmp(pband, "2.4G") == 0) { + ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, + BAND_ON_2_4G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation] + [bandwidth][rate_section] + [channel_index][RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index][RF90_PATH_A] = + power_limit; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel_index, + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index][RF90_PATH_A]); + } else if (strcmp(pband, "5G") == 0) { + ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, + BAND_ON_5G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index][RF90_PATH_A] = power_limit; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel, + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index][RF90_PATH_A]); + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Cannot recognize the band info in %s\n", pband); + return; + } +} + +static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw, + const char *regulation, const char *band, + const char *bandwidth, const char *rate_section, + const char *rf_path, const char *channel, + const char *power_limit) +{ + _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth, + rate_section, rf_path, channel, + power_limit); +} + +static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 i = 0; + u32 array_len; + const char **array; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN; + array = RTL8812AE_TXPWR_LMT; + } else { + array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN; + array = RTL8821AE_TXPWR_LMT; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + + for (i = 0; i < array_len; i += 7) { + const char *regulation = array[i]; + const char *band = array[i+1]; + const char *bandwidth = array[i+2]; + const char *rate = array[i+3]; + const char *rf_path = array[i+4]; + const char *chnl = array[i+5]; + const char *val = array[i+6]; + + _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band, + bandwidth, rate, rf_path, + chnl, val); + } +} + +static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + _rtl8821ae_phy_init_txpower_limit(hw); + + /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ + if (rtlefuse->eeprom_regulatory != 2) + _rtl8821ae_phy_read_and_config_txpwr_lmt(hw); + + rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (!rtstatus) { + pr_err("Write BB Reg Fail!!\n"); + return false; + } + _rtl8821ae_phy_init_tx_power_by_rate(hw); + if (!rtlefuse->autoload_failflag) { + rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!\n"); + return false; + } + + _rtl8821ae_phy_txpower_by_rate_configuration(hw); + + /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ + if (rtlefuse->eeprom_regulatory != 2) + _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw); + + rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + + if (!rtstatus) { + pr_err("AGC Table Fail\n"); + return false; + } + rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, 0x200)); + return true; +} + +static bool +__rtl8821ae_phy_config_with_headerfile(struct ieee80211_hw *hw, + u32 *array_table, u16 arraylen, + void (*set_reg)(struct ieee80211_hw *hw, + u32 regaddr, u32 data)) +{ + #define COND_ELSE 2 + #define COND_ENDIF 3 + + int i = 0; + u8 cond; + bool matched = true, skipped = false; + + while ((i + 1) < arraylen) { + u32 v1 = array_table[i]; + u32 v2 = array_table[i + 1]; + + if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/ + if (v1 & BIT(31)) {/* positive condition*/ + cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (cond == COND_ENDIF) {/*end*/ + matched = true; + skipped = false; + } else if (cond == COND_ELSE) /*else*/ + matched = skipped ? false : true; + else {/*if , else if*/ + if (skipped) { + matched = false; + } else { + if (_rtl8821ae_check_positive( + hw, v1, v2)) { + matched = true; + skipped = true; + } else { + matched = false; + skipped = false; + } + } + } + } else if (v1 & BIT(30)) { /*negative condition*/ + /*do nothing*/ + } + } else { + if (matched) + set_reg(hw, v1, v2); + } + i = i + 2; + } + + return true; +} + +static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 arraylength; + u32 *ptrarray; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n"); + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + arraylength = RTL8821AE_MAC_1T_ARRAYLEN; + ptrarray = RTL8821AE_MAC_REG_ARRAY; + } else { + arraylength = RTL8812AE_MAC_1T_ARRAYLEN; + ptrarray = RTL8812AE_MAC_REG_ARRAY; + } + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Img: MAC_REG_ARRAY LEN %d\n", arraylength); + + return __rtl8821ae_phy_config_with_headerfile(hw, + ptrarray, arraylength, rtl_write_byte_with_val32); +} + +static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 *array_table; + u16 arraylen; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + arraylen = RTL8812AE_PHY_REG_1TARRAYLEN; + array_table = RTL8812AE_PHY_REG_ARRAY; + } else { + arraylen = RTL8821AE_PHY_REG_1TARRAYLEN; + array_table = RTL8821AE_PHY_REG_ARRAY; + } + + return __rtl8821ae_phy_config_with_headerfile(hw, + array_table, arraylen, + _rtl8821ae_config_bb_reg); + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + arraylen = RTL8812AE_AGC_TAB_1TARRAYLEN; + array_table = RTL8812AE_AGC_TAB_ARRAY; + } else { + arraylen = RTL8821AE_AGC_TAB_1TARRAYLEN; + array_table = RTL8821AE_AGC_TAB_ARRAY; + } + + return __rtl8821ae_phy_config_with_headerfile(hw, + array_table, arraylen, + rtl_set_bbreg_with_dwmask); + } + return true; +} + +static u8 _rtl8821ae_get_rate_section_index(u32 regaddr) +{ + u8 index = 0; + regaddr &= 0xFFF; + if (regaddr >= 0xC20 && regaddr <= 0xC4C) + index = (u8)((regaddr - 0xC20) / 4); + else if (regaddr >= 0xE20 && regaddr <= 0xE4C) + index = (u8)((regaddr - 0xE20) / 4); + else + WARN_ONCE(true, + "rtl8821ae: Invalid RegAddr 0x%x\n", regaddr); + return index; +} + +static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw, + u32 band, u32 rfpath, + u32 txnum, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr); + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band); + band = BAND_ON_2_4G; + } + if (rfpath >= MAX_RF_PATH) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath); + rfpath = MAX_RF_PATH - 1; + } + if (txnum >= MAX_RF_PATH) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum); + txnum = MAX_RF_PATH - 1; + } + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n", + band, rfpath, txnum, rate_section, + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]); +} + +static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + int i; + u32 *array; + u16 arraylen; + u32 v1, v2, v3, v4, v5, v6; + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + arraylen = RTL8812AE_PHY_REG_ARRAY_PGLEN; + array = RTL8812AE_PHY_REG_ARRAY_PG; + } else { + arraylen = RTL8821AE_PHY_REG_ARRAY_PGLEN; + array = RTL8821AE_PHY_REG_ARRAY_PG; + } + + if (configtype != BASEBAND_CONFIG_PHY_REG) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "configtype != BaseBand_Config_PHY_REG\n"); + return true; + } + for (i = 0; i < arraylen; i += 6) { + v1 = array[i]; + v2 = array[i+1]; + v3 = array[i+2]; + v4 = array[i+3]; + v5 = array[i+4]; + v6 = array[i+5]; + + if (v1 < 0xCDCDCDCD) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE && + (v4 == 0xfe || v4 == 0xffe)) { + msleep(50); + continue; + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + if (v4 == 0xfe) + msleep(50); + else if (v4 == 0xfd) + mdelay(5); + else if (v4 == 0xfc) + mdelay(1); + else if (v4 == 0xfb) + udelay(50); + else if (v4 == 0xfa) + udelay(5); + else if (v4 == 0xf9) + udelay(1); + } + _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3, + v4, v5, v6); + continue; + } else { + /*don't need the hw_body*/ + if (!_rtl8821ae_check_condition(hw, v1)) { + i += 2; /* skip the pair of expression*/ + v2 = array[i+1]; + while (v2 != 0xDEAD) { + i += 3; + v2 = array[i + 1]; + } + } + } + } + + return true; +} + +bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + u32 *radioa_array_table_a, *radioa_array_table_b; + u16 radioa_arraylen_a, radioa_arraylen_b; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN; + radioa_array_table_a = RTL8812AE_RADIOA_ARRAY; + radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN; + radioa_array_table_b = RTL8812AE_RADIOB_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + return __rtl8821ae_phy_config_with_headerfile(hw, + radioa_array_table_a, radioa_arraylen_a, + _rtl8821ae_config_rf_radio_a); + case RF90_PATH_B: + return __rtl8821ae_phy_config_with_headerfile(hw, + radioa_array_table_b, radioa_arraylen_b, + _rtl8821ae_config_rf_radio_b); + case RF90_PATH_C: + case RF90_PATH_D: + pr_err("switch case %#x not processed\n", rfpath); + break; + } + return true; +} + +bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + u32 *radioa_array_table; + u16 radioa_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN; + radioa_array_table = RTL8821AE_RADIOA_ARRAY; + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + switch (rfpath) { + case RF90_PATH_A: + return __rtl8821ae_phy_config_with_headerfile(hw, + radioa_array_table, radioa_arraylen, + _rtl8821ae_config_rf_radio_a); + + case RF90_PATH_B: + case RF90_PATH_C: + case RF90_PATH_D: + pr_err("switch case %#x not processed\n", rfpath); + break; + } + return true; +} + +void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->default_initialgain[0] = + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A; +} + +void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index) +{ + u8 i = 0; + bool in_24g = true; + + if (channel <= 14) { + in_24g = true; + *chnl_index = channel - 1; + } else { + in_24g = false; + + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) { + if (channel5g[i] == channel) { + *chnl_index = i; + return in_24g; + } + } + } + return in_24g; +} + +static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate) +{ + s8 rate_section = 0; + switch (rate) { + case DESC_RATE1M: + case DESC_RATE2M: + case DESC_RATE5_5M: + case DESC_RATE11M: + rate_section = 0; + break; + case DESC_RATE6M: + case DESC_RATE9M: + case DESC_RATE12M: + case DESC_RATE18M: + rate_section = 1; + break; + case DESC_RATE24M: + case DESC_RATE36M: + case DESC_RATE48M: + case DESC_RATE54M: + rate_section = 2; + break; + case DESC_RATEMCS0: + case DESC_RATEMCS1: + case DESC_RATEMCS2: + case DESC_RATEMCS3: + rate_section = 3; + break; + case DESC_RATEMCS4: + case DESC_RATEMCS5: + case DESC_RATEMCS6: + case DESC_RATEMCS7: + rate_section = 4; + break; + case DESC_RATEMCS8: + case DESC_RATEMCS9: + case DESC_RATEMCS10: + case DESC_RATEMCS11: + rate_section = 5; + break; + case DESC_RATEMCS12: + case DESC_RATEMCS13: + case DESC_RATEMCS14: + case DESC_RATEMCS15: + rate_section = 6; + break; + case DESC_RATEVHT1SS_MCS0: + case DESC_RATEVHT1SS_MCS1: + case DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT1SS_MCS3: + rate_section = 7; + break; + case DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT1SS_MCS5: + case DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT1SS_MCS7: + rate_section = 8; + break; + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT1SS_MCS9: + case DESC_RATEVHT2SS_MCS0: + case DESC_RATEVHT2SS_MCS1: + rate_section = 9; + break; + case DESC_RATEVHT2SS_MCS2: + case DESC_RATEVHT2SS_MCS3: + case DESC_RATEVHT2SS_MCS4: + case DESC_RATEVHT2SS_MCS5: + rate_section = 10; + break; + case DESC_RATEVHT2SS_MCS6: + case DESC_RATEVHT2SS_MCS7: + case DESC_RATEVHT2SS_MCS8: + case DESC_RATEVHT2SS_MCS9: + rate_section = 11; + break; + default: + WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n"); + break; + } + + return rate_section; +} + +static s8 _rtl8812ae_phy_get_world_wide_limit(s8 *limit_table) +{ + s8 min = limit_table[0]; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + if (limit_table[i] < min) + min = limit_table[i]; + } + return min; +} + +static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw, + u8 band, + enum ht_channel_width bandwidth, + enum radio_path rf_path, + u8 rate, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + short band_temp = -1, regulation = -1, bandwidth_temp = -1, + rate_section = -1, channel_temp = -1; + u16 regu, bdwidth, sec, chnl; + s8 power_limit = MAX_POWER_INDEX; + + if (rtlefuse->eeprom_regulatory == 2) + return MAX_POWER_INDEX; + + regulation = TXPWR_LMT_WW; + + if (band == BAND_ON_2_4G) + band_temp = 0; + else if (band == BAND_ON_5G) + band_temp = 1; + + if (bandwidth == HT_CHANNEL_WIDTH_20) + bandwidth_temp = 0; + else if (bandwidth == HT_CHANNEL_WIDTH_20_40) + bandwidth_temp = 1; + else if (bandwidth == HT_CHANNEL_WIDTH_80) + bandwidth_temp = 2; + + switch (rate) { + case DESC_RATE1M: + case DESC_RATE2M: + case DESC_RATE5_5M: + case DESC_RATE11M: + rate_section = 0; + break; + case DESC_RATE6M: + case DESC_RATE9M: + case DESC_RATE12M: + case DESC_RATE18M: + case DESC_RATE24M: + case DESC_RATE36M: + case DESC_RATE48M: + case DESC_RATE54M: + rate_section = 1; + break; + case DESC_RATEMCS0: + case DESC_RATEMCS1: + case DESC_RATEMCS2: + case DESC_RATEMCS3: + case DESC_RATEMCS4: + case DESC_RATEMCS5: + case DESC_RATEMCS6: + case DESC_RATEMCS7: + rate_section = 2; + break; + case DESC_RATEMCS8: + case DESC_RATEMCS9: + case DESC_RATEMCS10: + case DESC_RATEMCS11: + case DESC_RATEMCS12: + case DESC_RATEMCS13: + case DESC_RATEMCS14: + case DESC_RATEMCS15: + rate_section = 3; + break; + case DESC_RATEVHT1SS_MCS0: + case DESC_RATEVHT1SS_MCS1: + case DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT1SS_MCS3: + case DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT1SS_MCS5: + case DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT1SS_MCS9: + rate_section = 4; + break; + case DESC_RATEVHT2SS_MCS0: + case DESC_RATEVHT2SS_MCS1: + case DESC_RATEVHT2SS_MCS2: + case DESC_RATEVHT2SS_MCS3: + case DESC_RATEVHT2SS_MCS4: + case DESC_RATEVHT2SS_MCS5: + case DESC_RATEVHT2SS_MCS6: + case DESC_RATEVHT2SS_MCS7: + case DESC_RATEVHT2SS_MCS8: + case DESC_RATEVHT2SS_MCS9: + rate_section = 5; + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong rate 0x%x\n", rate); + break; + } + + if (band_temp == BAND_ON_5G && rate_section == 0) + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong rate 0x%x: No CCK in 5G Band\n", rate); + + /*workaround for wrong index combination to obtain tx power limit, + OFDM only exists in BW 20M*/ + if (rate_section == 1) + bandwidth_temp = 0; + + /*workaround for wrong index combination to obtain tx power limit, + *HT on 80M will reference to HT on 40M + */ + if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G && + bandwidth_temp == 2) + bandwidth_temp = 1; + + if (band == BAND_ON_2_4G) + channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, + BAND_ON_2_4G, channel); + else if (band == BAND_ON_5G) + channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, + BAND_ON_5G, channel); + else if (band == BAND_ON_BOTH) { + ;/* BAND_ON_BOTH don't care temporarily */ + } + + if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 || + rate_section == -1 || channel_temp == -1) { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n", + band_temp, regulation, bandwidth_temp, rf_path, + rate_section, channel_temp); + return MAX_POWER_INDEX; + } + + regu = regulation; + bdwidth = bandwidth_temp; + sec = rate_section; + chnl = channel_temp; + + if (band == BAND_ON_2_4G) { + s8 limits[10] = {0}; + u8 i; + + for (i = 0; i < 4; ++i) + limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth] + [sec][chnl][rf_path]; + + power_limit = (regulation == TXPWR_LMT_WW) ? + _rtl8812ae_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_2_4g[regu][bdwidth] + [sec][chnl][rf_path]; + } else if (band == BAND_ON_5G) { + s8 limits[10] = {0}; + u8 i; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) + limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth] + [sec][chnl][rf_path]; + + power_limit = (regulation == TXPWR_LMT_WW) ? + _rtl8812ae_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_5g[regu][chnl] + [sec][chnl][rf_path]; + } else { + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "No power limit table of the specified band\n"); + } + return power_limit; +} + +static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw, + u8 band, u8 path, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 shift = 0, rate_section, tx_num; + s8 tx_pwr_diff = 0; + s8 limit = 0; + + rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate); + tx_num = RF_TX_NUM_NONIMPLEMENT; + + if (tx_num == RF_TX_NUM_NONIMPLEMENT) { + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9)) + tx_num = RF_2TX; + else + tx_num = RF_1TX; + } + + switch (rate) { + case DESC_RATE1M: + case DESC_RATE6M: + case DESC_RATE24M: + case DESC_RATEMCS0: + case DESC_RATEMCS4: + case DESC_RATEMCS8: + case DESC_RATEMCS12: + case DESC_RATEVHT1SS_MCS0: + case DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT2SS_MCS2: + case DESC_RATEVHT2SS_MCS6: + shift = 0; + break; + case DESC_RATE2M: + case DESC_RATE9M: + case DESC_RATE36M: + case DESC_RATEMCS1: + case DESC_RATEMCS5: + case DESC_RATEMCS9: + case DESC_RATEMCS13: + case DESC_RATEVHT1SS_MCS1: + case DESC_RATEVHT1SS_MCS5: + case DESC_RATEVHT1SS_MCS9: + case DESC_RATEVHT2SS_MCS3: + case DESC_RATEVHT2SS_MCS7: + shift = 8; + break; + case DESC_RATE5_5M: + case DESC_RATE12M: + case DESC_RATE48M: + case DESC_RATEMCS2: + case DESC_RATEMCS6: + case DESC_RATEMCS10: + case DESC_RATEMCS14: + case DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT2SS_MCS0: + case DESC_RATEVHT2SS_MCS4: + case DESC_RATEVHT2SS_MCS8: + shift = 16; + break; + case DESC_RATE11M: + case DESC_RATE18M: + case DESC_RATE54M: + case DESC_RATEMCS3: + case DESC_RATEMCS7: + case DESC_RATEMCS11: + case DESC_RATEMCS15: + case DESC_RATEVHT1SS_MCS3: + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT2SS_MCS1: + case DESC_RATEVHT2SS_MCS5: + case DESC_RATEVHT2SS_MCS9: + shift = 24; + break; + default: + WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n"); + break; + } + + tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path] + [tx_num][rate_section] >> shift) & 0xff; + + /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ + if (rtlpriv->efuse.eeprom_regulatory != 2) { + limit = _rtl8812ae_phy_get_txpower_limit(hw, band, + rtlphy->current_chan_bw, path, rate, + rtlphy->current_channel); + + if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 || + rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) { + if (limit < 0) { + if (tx_pwr_diff < (-limit)) + tx_pwr_diff = -limit; + } + } else { + if (limit < 0) + tx_pwr_diff = limit; + else + tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff; + } + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Maximum power by rate %d, final power by rate %d\n", + limit, tx_pwr_diff); + } + + return tx_pwr_diff; +} + +static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path, + u8 rate, u8 bandwidth, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + u8 txpower = 0; + bool in_24g = false; + s8 powerdiff_byrate = 0; + + if (((rtlhal->current_bandtype == BAND_ON_2_4G) && + (channel > 14 || channel < 1)) || + ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) { + index = 0; + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Illegal channel!!\n"); + } + + in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index); + if (in_24g) { + if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) + txpower = rtlefuse->txpwrlevel_cck[path][index]; + else if (DESC_RATE6M <= rate) + txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; + else + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n"); + + if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && + !RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht20diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht20diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht40diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_ht40diff[path][TX_2S]; + } + } else { + if (DESC_RATE6M <= rate) + txpower = rtlefuse->txpwr_5g_bw40base[path][index]; + else + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING, + "INVALID Rate.\n"); + + if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && + !RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + u8 i; + + for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i) + if (channel5g_80m[i] == channel) + index = i; + + if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT1SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower = rtlefuse->txpwr_5g_bw80base[path][index] + + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]; + if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || + (DESC_RATEVHT2SS_MCS0 <= rate && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower = rtlefuse->txpwr_5g_bw80base[path][index] + + rtlefuse->txpwr_5g_bw80diff[path][TX_1S] + + rtlefuse->txpwr_5g_bw80diff[path][TX_2S]; + } + } + if (rtlefuse->eeprom_regulatory != 2) + powerdiff_byrate = + _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g), + path, rate); + + if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 || + rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) + txpower -= powerdiff_byrate; + else + txpower += powerdiff_byrate; + + if (rate > DESC_RATE11M) + txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path]; + else + txpower += rtlpriv->dm.remnant_cck_idx; + + if (txpower > MAX_POWER_INDEX) + txpower = MAX_POWER_INDEX; + + return txpower; +} + +static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw, + u8 power_index, u8 path, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (path == RF90_PATH_A) { + switch (rate) { + case DESC_RATE1M: + rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, + MASKBYTE0, power_index); + break; + case DESC_RATE2M: + rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, + MASKBYTE1, power_index); + break; + case DESC_RATE5_5M: + rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, + MASKBYTE2, power_index); + break; + case DESC_RATE11M: + rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, + MASKBYTE3, power_index); + break; + case DESC_RATE6M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, + MASKBYTE0, power_index); + break; + case DESC_RATE9M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, + MASKBYTE1, power_index); + break; + case DESC_RATE12M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, + MASKBYTE2, power_index); + break; + case DESC_RATE18M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, + MASKBYTE3, power_index); + break; + case DESC_RATE24M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, + MASKBYTE0, power_index); + break; + case DESC_RATE36M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, + MASKBYTE1, power_index); + break; + case DESC_RATE48M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, + MASKBYTE2, power_index); + break; + case DESC_RATE54M: + rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS0: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS1: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS2: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS3: + rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS4: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS5: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS6: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS7: + rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS8: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS9: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS10: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS11: + rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS12: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS13: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS14: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS15: + rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS0: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS1: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT1SS_MCS2: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT1SS_MCS3: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS4: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS5: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT1SS_MCS6: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT1SS_MCS7: + rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS8: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS9: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS0: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS1: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT2SS_MCS2: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT2SS_MCS3: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS4: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS5: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT2SS_MCS6: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT2SS_MCS7: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS8: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS9: + rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, + MASKBYTE3, power_index); + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Rate!!\n"); + break; + } + } else if (path == RF90_PATH_B) { + switch (rate) { + case DESC_RATE1M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, + MASKBYTE0, power_index); + break; + case DESC_RATE2M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, + MASKBYTE1, power_index); + break; + case DESC_RATE5_5M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, + MASKBYTE2, power_index); + break; + case DESC_RATE11M: + rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, + MASKBYTE3, power_index); + break; + case DESC_RATE6M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, + MASKBYTE0, power_index); + break; + case DESC_RATE9M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, + MASKBYTE1, power_index); + break; + case DESC_RATE12M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, + MASKBYTE2, power_index); + break; + case DESC_RATE18M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, + MASKBYTE3, power_index); + break; + case DESC_RATE24M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, + MASKBYTE0, power_index); + break; + case DESC_RATE36M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, + MASKBYTE1, power_index); + break; + case DESC_RATE48M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, + MASKBYTE2, power_index); + break; + case DESC_RATE54M: + rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS0: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS1: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS2: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS3: + rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS4: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS5: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS6: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS7: + rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS8: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS9: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS10: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS11: + rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, + MASKBYTE3, power_index); + break; + case DESC_RATEMCS12: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, + MASKBYTE0, power_index); + break; + case DESC_RATEMCS13: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, + MASKBYTE1, power_index); + break; + case DESC_RATEMCS14: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, + MASKBYTE2, power_index); + break; + case DESC_RATEMCS15: + rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS0: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS1: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT1SS_MCS2: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT1SS_MCS3: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS4: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS5: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT1SS_MCS6: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT1SS_MCS7: + rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT1SS_MCS8: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT1SS_MCS9: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS0: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS1: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT2SS_MCS2: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT2SS_MCS3: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS4: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS5: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, + MASKBYTE3, power_index); + break; + case DESC_RATEVHT2SS_MCS6: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, + MASKBYTE0, power_index); + break; + case DESC_RATEVHT2SS_MCS7: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, + MASKBYTE1, power_index); + break; + case DESC_RATEVHT2SS_MCS8: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, + MASKBYTE2, power_index); + break; + case DESC_RATEVHT2SS_MCS9: + rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, + MASKBYTE3, power_index); + break; + default: + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Rate!!\n"); + break; + } + } else { + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid RFPath!!\n"); + } +} + +static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 *array, u8 path, + u8 channel, u8 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i; + u8 power_index; + + for (i = 0; i < size; i++) { + power_index = + _rtl8821ae_get_txpower_index(hw, path, array[i], + rtlphy->current_chan_bw, + channel); + _rtl8821ae_phy_set_txpower_index(hw, power_index, path, + array[i]); + } +} + +static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw, + u8 bw, u8 channel, u8 path) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 i; + u32 power_level, data, offset; + + if (path >= rtlphy->num_total_rfpath) + return; + + data = 0; + if (path == RF90_PATH_A) { + power_level = + _rtl8821ae_get_txpower_index(hw, RF90_PATH_A, + DESC_RATEMCS7, bw, channel); + offset = RA_TXPWRTRAING; + } else { + power_level = + _rtl8821ae_get_txpower_index(hw, RF90_PATH_B, + DESC_RATEMCS7, bw, channel); + offset = RB_TXPWRTRAING; + } + + for (i = 0; i < 3; i++) { + if (i == 0) + power_level = power_level - 10; + else if (i == 1) + power_level = power_level - 8; + else + power_level = power_level - 6; + + data |= (((power_level > 2) ? (power_level) : 2) << (i * 8)); + } + rtl_set_bbreg(hw, offset, 0xffffff, data); +} + +void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path) +{ + /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, + DESC_RATE11M}; + u8 sizes_of_cck_retes = 4; + u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, + DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, + DESC_RATE48M, DESC_RATE54M}; + u8 sizes_of_ofdm_retes = 8; + u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, + DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, + DESC_RATEMCS6, DESC_RATEMCS7}; + u8 sizes_of_ht_retes_1t = 8; + u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, + DESC_RATEMCS10, DESC_RATEMCS11, + DESC_RATEMCS12, DESC_RATEMCS13, + DESC_RATEMCS14, DESC_RATEMCS15}; + u8 sizes_of_ht_retes_2t = 8; + u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, + DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, + DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, + DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, + DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9}; + u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, + DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, + DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, + DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, + DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9}; + u8 sizes_of_vht_retes = 10; + + if (rtlhal->current_bandtype == BAND_ON_2_4G) + _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel, + sizes_of_cck_retes); + + _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel, + sizes_of_ofdm_retes); + _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel, + sizes_of_ht_retes_1t); + _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel, + sizes_of_vht_retes); + + if (rtlphy->num_total_rfpath >= 2) { + _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, + channel, + sizes_of_ht_retes_2t); + _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path, + channel, + sizes_of_vht_retes); + } + + _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw, + channel, path); +} + +/*just in case, write txpower in DW, to reduce time*/ +void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 path = 0; + + for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path) + rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path); +} + +static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_BACKUP_BAND1: + iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw) +{ + u16 reg_rf_mode_bw, tmp = 0; + + reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL); + switch (bw) { + case HT_CHANNEL_WIDTH_20: + rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F); + break; + case HT_CHANNEL_WIDTH_20_40: + tmp = reg_rf_mode_bw | BIT(7); + rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF); + break; + case HT_CHANNEL_WIDTH_80: + tmp = reg_rf_mode_bw | BIT(8); + rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F); + break; + default: + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw); + break; + } +} + +static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv) +{ + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 sc_set_40 = 0, sc_set_20 = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER) + sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER) + sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + pr_err("SCMapping: Not Correct Primary40MHz Setting\n"); + + if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + pr_err("SCMapping: Not Correct Primary40MHz Setting\n"); + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) + sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) + sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else + pr_err("SCMapping: Not Correct Primary40MHz Setting\n"); + } + return (sc_set_40 << 4) | sc_set_20; +} + +void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 sub_chnl = 0; + u8 l1pk_val = 0; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "Switch to %s bandwidth\n", + (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : + (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ? + "40MHz" : "80MHz"))); + + _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw); + sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv); + rtl_write_byte(rtlpriv, 0x0483, sub_chnl); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200); + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); + + if (rtlphy->rf_type == RF_2T2R) + rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7); + else + rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201); + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); + rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl); + rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl); + + if (rtlphy->reg_837 & BIT(2)) + l1pk_val = 6; + else { + if (rtlphy->rf_type == RF_2T2R) + l1pk_val = 7; + else + l1pk_val = 8; + } + /* 0x848[25:22] = 0x6 */ + rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val); + + if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ) + rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1); + else + rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0); + break; + + case HT_CHANNEL_WIDTH_80: + /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */ + rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202); + /* 0x8c4[30] = 1 */ + rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); + rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl); + rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl); + + if (rtlphy->reg_837 & BIT(2)) + l1pk_val = 5; + else { + if (rtlphy->rf_type == RF_2T2R) + l1pk_val = 6; + else + l1pk_val = 7; + } + rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val); + + break; + default: + pr_err("unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); + break; + } + + rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel); + + rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); +} + +void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) + rtl8821ae_phy_set_bw_mode_callback(hw); + else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "FALSE driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + u8 path; + u32 data; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d\n", rtlphy->current_channel); + if (is_hal_stop(rtlhal)) + return; + + if (36 <= channel && channel <= 48) + data = 0x494; + else if (50 <= channel && channel <= 64) + data = 0x453; + else if (100 <= channel && channel <= 116) + data = 0x452; + else if (118 <= channel) + data = 0x412; + else + data = 0x96a; + rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data); + + for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) { + if (36 <= channel && channel <= 64) + data = 0x101; + else if (100 <= channel && channel <= 140) + data = 0x301; + else if (140 < channel) + data = 0x501; + else + data = 0x000; + rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW, + BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data); + + rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW, + BMASKBYTE0, channel); + + if (channel > 14) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { + if (36 <= channel && channel <= 64) + data = 0x114E9; + else + data = 0x110E9; + rtl8821ae_phy_set_rf_reg(hw, path, RF_APK, + BRFREGOFFSETMASK, data); + } + } + } + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 timeout = 1000, timecount = 0; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + return 0; + } + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + + if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G) + rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G); + else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G) + rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G); + + rtlphy->sw_chnl_inprogress = true; + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d, band type is %d\n", + rtlphy->current_channel, rtlhal->current_bandtype); + + rtl8821ae_phy_sw_chnl_callback(hw); + + rtl8821ae_dm_clear_txpower_tracking_state(hw); + rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel); + + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl) +{ + static const u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, + 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, + 110, 112, 114, 116, 118, 120, 122, 124, 126, + 128, 130, 132, 134, 136, 138, 140, 149, 151, + 153, 155, 157, 159, 161, 163, 165}; + u8 place; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) + if (channel_all[place] == chnl) + return place-13; + } + + return 0; +} + +#define MACBB_REG_NUM 10 +#define AFE_REG_NUM 14 +#define RF_REG_NUM 3 + +static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw, + u32 *macbb_backup, + u32 *backup_macbb_reg, u32 mac_bb_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ + /*save MACBB default value*/ + for (i = 0; i < mac_bb_num; i++) + macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]); + + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n"); +} + +static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup, + u32 *backup_afe_REG, u32 afe_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ + /*Save AFE Parameters */ + for (i = 0; i < afe_num; i++) + afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n"); +} + +static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup, + u32 *rfb_backup, u32 *backup_rf_reg, + u32 rf_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ + /*Save RF Parameters*/ + for (i = 0; i < rf_num; i++) { + rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i], + BMASKDWORD); + rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i], + BMASKDWORD); + } + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n"); +} + +static void _rtl8821ae_iqk_configure_mac( + struct ieee80211_hw *hw + ) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + /* ========MAC register setting========*/ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ + rtl_write_byte(rtlpriv, 0x522, 0x3f); + rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0); + rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/ + rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/ +} + +static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw, + enum radio_path path, u32 tx_x, u32 tx_y) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + switch (path) { + case RF90_PATH_A: + /* [31] = 1 --> Page C1 */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); + rtl_write_dword(rtlpriv, 0xc90, 0x00000080); + rtl_write_dword(rtlpriv, 0xcc4, 0x20040000); + rtl_write_dword(rtlpriv, 0xcc8, 0x20000000); + rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y); + rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "TX_X = %x;;TX_Y = %x =====> fill to IQC\n", + tx_x, tx_y); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", + rtl_get_bbreg(hw, 0xcd4, 0x000007ff), + rtl_get_bbreg(hw, 0xccc, 0x000007ff)); + break; + default: + break; + } +} + +static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw, + enum radio_path path, u32 rx_x, u32 rx_y) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + switch (path) { + case RF90_PATH_A: + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1); + rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "rx_x = %x;;rx_y = %x ====>fill to IQC\n", + rx_x >> 1, rx_y >> 1); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "0xc10 = %x ====>fill to IQC\n", + rtl_read_dword(rtlpriv, 0xc10)); + break; + default: + break; + } +} + +#define cal_num 10 + +static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65; + int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0; + int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num], + tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num], + tx_dt[cal_num], rx_dt[cal_num]; + bool tx0iqkok = false, rx0iqkok = false; + bool vdf_enable = false; + int i, k, vdf_y[3], vdf_x[3], + ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0; + + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "BandWidth = %d.\n", + rtlphy->current_chan_bw); + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) + vdf_enable = true; + + while (cal < cal_num) { + switch (path) { + case RF90_PATH_A: + temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff); + /* Path-A LOK */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ + /*========Path-A AFE all on========*/ + /*Port 0 DAC/ADC on*/ + rtl_write_dword(rtlpriv, 0xc60, 0x77777777); + rtl_write_dword(rtlpriv, 0xc64, 0x77777777); + rtl_write_dword(rtlpriv, 0xc68, 0x19791979); + rtl_write_dword(rtlpriv, 0xc6c, 0x19791979); + rtl_write_dword(rtlpriv, 0xc70, 0x19791979); + rtl_write_dword(rtlpriv, 0xc74, 0x19791979); + rtl_write_dword(rtlpriv, 0xc78, 0x19791979); + rtl_write_dword(rtlpriv, 0xc7c, 0x19791979); + rtl_write_dword(rtlpriv, 0xc80, 0x19791979); + rtl_write_dword(rtlpriv, 0xc84, 0x19791979); + + rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/ + + /* LOK Setting */ + /* ====== LOK ====== */ + /*DAC/ADC sampling rate (160 MHz)*/ + rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7); + + /* 2. LoK RF Setting (at BW = 20M) */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002); + rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */ + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); + rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd); + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0xb00, 0x03000100); + rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1); + rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ + rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ + rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */ + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_write_dword(rtlpriv, 0xc88, 0x821403f4); + + if (rtlhal->current_bandtype) + rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96); + else + rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96); + + rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */ + + switch (rtlphy->current_chan_bw) { + case 1: + rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1); + break; + case 2: + rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0); + break; + default: + break; + } + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + + /* 3. TX RF Setting */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); + /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */ + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0xb00, 0x03000100); + rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1); + rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ + rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ + rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_write_dword(rtlpriv, 0xc88, 0x821403f1); + if (rtlhal->current_bandtype) + rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96); + else + rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96); + + if (vdf_enable) { + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n"); + for (k = 0; k <= 2; k++) { + switch (k) { + case 0: + rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); + break; + case 1: + rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0); + rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0); + rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); + break; + case 2: + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff); + tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20); + tx_dt[cal] = ((16*tx_dt[cal])*10000/15708); + tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0)); + rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); + rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff); + break; + default: + break; + } + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); + + if (~tx_fail) { + rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); + vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); + vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + tx0iqkok = true; + break; + } else { + rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0); + rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200); + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } else { + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + } + if (k == 3) { + tx_x0[cal] = vdf_x[k-1]; + tx_y0[cal] = vdf_y[k-1]; + } + } else { + rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); + + if (~tx_fail) { + rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); + tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); + tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + tx0iqkok = true; + break; + } else { + rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0); + rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200); + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } else { + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + } + + if (!tx0iqkok) + break; /* TXK fail, Don't do RXK */ + + if (vdf_enable == 1) { + rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */ + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n"); + for (k = 0; k <= 2; k++) { + /* ====== RX mode TXK (RXK Step 1) ====== */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* 1. TX RF Setting */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); + + rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd); + rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ + rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ + rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0xb00, 0x03000100); + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + switch (k) { + case 0: + { + rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0); + } + break; + case 1: + { + rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0); + } + break; + case 2: + { + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n", + vdf_y[1] >> 21 & 0x00007ff, + vdf_y[0] >> 21 & 0x00007ff); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "VDF_X[1] = %x;;;VDF_X[0] = %x\n", + vdf_x[1] >> 21 & 0x00007ff, + vdf_x[0] >> 21 & 0x00007ff); + rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", + rx_dt[cal]); + rx_dt[cal] = ((16*rx_dt[cal])*10000/13823); + rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0)); + rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff); + } + break; + default: + break; + } + rtl_write_dword(rtlpriv, 0xc88, 0x821603e0); + rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96); + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); + + if (~tx_fail) { + rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); + tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); + tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + tx0iqkok = true; + break; + } else{ + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } else { + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + + if (!tx0iqkok) { /* If RX mode TXK fail, then take TXK Result */ + tx_x0_rxk[cal] = tx_x0[cal]; + tx_y0_rxk[cal] = tx_y0[cal]; + tx0iqkok = true; + rtl_dbg(rtlpriv, + COMP_IQK, + DBG_LOUD, + "RXK Step 1 fail\n"); + } + + /* ====== RX IQK ====== */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* 1. RX RF Setting */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8); + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); + + rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff); + rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff); + rtl_set_bbreg(hw, 0x978, BIT(31), 0x1); + rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0); + rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe); + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0x984, 0x0046a911); + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1); + rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0); + rtl_write_dword(rtlpriv, 0xc88, 0x02140119); + + rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */ + + if (k == 2) + rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============RXIQK Check============== */ + rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11)); + if (rx_fail == 0) { + rtl_write_dword(rtlpriv, 0xcb8, 0x06000000); + vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x08000000); + vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rx0iqkok = true; + break; + } else { + rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1); + rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1); + rx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + + } + } else{ + rx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + + } + if (k == 3) { + rx_x0[cal] = vdf_x[k-1]; + rx_y0[cal] = vdf_y[k-1]; + } + rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */ + } + + else{ + /* ====== RX mode TXK (RXK Step 1) ====== */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* 1. TX RF Setting */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0xb00, 0x03000100); + rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_write_dword(rtlpriv, 0xc88, 0x821603e0); + /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); + + if (~tx_fail) { + rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); + tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); + tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + tx0iqkok = true; + break; + } else { + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } else{ + tx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + + if (!tx0iqkok) { /* If RX mode TXK fail, then take TXK Result */ + tx_x0_rxk[cal] = tx_x0[cal]; + tx_y0_rxk[cal] = tx_y0[cal]; + tx0iqkok = true; + rtl_dbg(rtlpriv, COMP_IQK, + DBG_LOUD, "1"); + } + + /* ====== RX IQK ====== */ + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* 1. RX RF Setting */ + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); + rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f); + rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb); + rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001); + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8); + rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); + + rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff); + rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff); + rtl_set_bbreg(hw, 0x978, BIT(31), 0x1); + rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0); + /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */ + rtl_write_dword(rtlpriv, 0x90c, 0x00008000); + rtl_write_dword(rtlpriv, 0x984, 0x0046a911); + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ + rtl_write_dword(rtlpriv, 0xc88, 0x02140119); + + rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/ + + rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ + + cal_retry = 0; + while (1) { + /* one shot */ + rtl_write_dword(rtlpriv, 0x980, 0xfa000000); + rtl_write_dword(rtlpriv, 0x980, 0xf8000000); + + mdelay(10); /* Delay 10ms */ + rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); + delay_count = 0; + while (1) { + iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); + if ((~iqk_ready) || (delay_count > 20)) + break; + else{ + mdelay(1); + delay_count++; + } + } + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============RXIQK Check============== */ + rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11)); + if (rx_fail == 0) { + rtl_write_dword(rtlpriv, 0xcb8, 0x06000000); + rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rtl_write_dword(rtlpriv, 0xcb8, 0x08000000); + rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; + rx0iqkok = true; + break; + } else{ + rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1); + rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1); + rx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + + } + } else{ + rx0iqkok = false; + cal_retry++; + if (cal_retry == 10) + break; + } + } + } + + if (tx0iqkok) + tx_average++; + if (rx0iqkok) + rx_average++; + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); + break; + default: + break; + } + cal++; + } + + /* FillIQK Result */ + switch (path) { + case RF90_PATH_A: + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "========Path_A =======\n"); + if (tx_average == 0) + break; + + for (i = 0; i < tx_average; i++) { + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i, + (tx_x0_rxk[i]) >> 21 & 0x000007ff, i, + (tx_y0_rxk[i]) >> 21 & 0x000007ff); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i, + (tx_x0[i]) >> 21 & 0x000007ff, i, + (tx_y0[i]) >> 21 & 0x000007ff); + } + for (i = 0; i < tx_average; i++) { + for (ii = i+1; ii < tx_average; ii++) { + dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21); + if (dx < 3 && dx > -3) { + dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21); + if (dy < 3 && dy > -3) { + tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2; + tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2; + tx_finish = 1; + break; + } + } + } + if (tx_finish == 1) + break; + } + + if (tx_finish == 1) + _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */ + else + _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0); + + if (rx_average == 0) + break; + + for (i = 0; i < rx_average; i++) + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i, + (rx_x0[i])>>21&0x000007ff, i, + (rx_y0[i])>>21&0x000007ff); + for (i = 0; i < rx_average; i++) { + for (ii = i+1; ii < rx_average; ii++) { + dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21); + if (dx < 4 && dx > -4) { + dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21); + if (dy < 4 && dy > -4) { + rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2; + rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2; + rx_finish = 1; + break; + } + } + } + if (rx_finish == 1) + break; + } + + if (rx_finish == 1) + _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y); + else + _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0); + break; + default: + break; + } +} + +static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw, + enum radio_path path, + u32 *backup_rf_reg, + u32 *rf_backup, u32 rf_reg_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + for (i = 0; i < RF_REG_NUM; i++) + rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK, + rf_backup[i]); + + switch (path) { + case RF90_PATH_A: + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "RestoreRF Path A Success!!!!\n"); + break; + default: + break; + } +} + +static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw, + u32 *afe_backup, u32 *backup_afe_reg, + u32 afe_num) +{ + u32 i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* Reload AFE Parameters */ + for (i = 0; i < afe_num; i++) + rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]); + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ + rtl_write_dword(rtlpriv, 0xc80, 0x0); + rtl_write_dword(rtlpriv, 0xc84, 0x0); + rtl_write_dword(rtlpriv, 0xc88, 0x0); + rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000); + rtl_write_dword(rtlpriv, 0xc90, 0x00000080); + rtl_write_dword(rtlpriv, 0xc94, 0x00000000); + rtl_write_dword(rtlpriv, 0xcc4, 0x20040000); + rtl_write_dword(rtlpriv, 0xcc8, 0x20000000); + rtl_write_dword(rtlpriv, 0xcb8, 0x0); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n"); +} + +static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw, + u32 *macbb_backup, + u32 *backup_macbb_reg, + u32 macbb_num) +{ + u32 i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ + /* Reload MacBB Parameters */ + for (i = 0; i < macbb_num; i++) + rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]); + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n"); +} + +#undef MACBB_REG_NUM +#undef AFE_REG_NUM +#undef RF_REG_NUM + +#define MACBB_REG_NUM 11 +#define AFE_REG_NUM 12 +#define RF_REG_NUM 3 + +static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw) +{ + u32 macbb_backup[MACBB_REG_NUM]; + u32 afe_backup[AFE_REG_NUM]; + u32 rfa_backup[RF_REG_NUM]; + u32 rfb_backup[RF_REG_NUM]; + u32 backup_macbb_reg[MACBB_REG_NUM] = { + 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50, + 0xe00, 0xe50, 0x838, 0x82c + }; + u32 backup_afe_reg[AFE_REG_NUM] = { + 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, + 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8 + }; + u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0}; + + _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg, + MACBB_REG_NUM); + _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM); + _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg, + RF_REG_NUM); + + _rtl8821ae_iqk_configure_mac(hw); + _rtl8821ae_iqk_tx(hw, RF90_PATH_A); + _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup, + RF_REG_NUM); + + _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM); + _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg, + MACBB_REG_NUM); +} + +static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */ + /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */ + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + + if (main) + rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1); + else + rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2); +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ +} + +void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold) +{ + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + + rtldm->thermalvalue_iqk = thermal_value; + rtl8812ae_phy_iq_calibrate(hw, false); +} + +void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (!rtlphy->lck_inprogress) { + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = true; + spin_unlock(&rtlpriv->locks.iqk_lock); + + _rtl8821ae_phy_iq_calibrate(hw); + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = false; + spin_unlock(&rtlpriv->locks.iqk_lock); + } +} + +void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i; + + rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, + "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n", + (int)(sizeof(rtlphy->iqk_matrix) / + sizeof(struct iqk_matrix_regs)), + IQK_MATRIX_SETTINGS_NUM); + + for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { + rtlphy->iqk_matrix[i].value[0][0] = 0x100; + rtlphy->iqk_matrix[i].value[0][2] = 0x100; + rtlphy->iqk_matrix[i].value[0][4] = 0x100; + rtlphy->iqk_matrix[i].value[0][6] = 0x100; + + rtlphy->iqk_matrix[i].value[0][1] = 0x0; + rtlphy->iqk_matrix[i].value[0][3] = 0x0; + rtlphy->iqk_matrix[i].value[0][5] = 0x0; + rtlphy->iqk_matrix[i].value[0][7] = 0x0; + + rtlphy->iqk_matrix[i].iqk_done = false; + } +} + +void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold) +{ + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + + rtl8821ae_reset_iqk_result(hw); + + rtldm->thermalvalue_iqk = thermal_value; + rtl8821ae_phy_iq_calibrate(hw, false); +} + +void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw) +{ +} + +void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + _rtl8821ae_phy_set_rfpath_switch(hw, bmain); +} + +bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + pr_err("switch case %#x not processed\n", + iotype); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl8821ae_phy_set_io(hw); + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) + _rtl8821ae_resume_tx_beacon(hw); + rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1); + rtl8821ae_dm_write_cck_cca_thres(hw, + rtlphy->initgain_backup.cca); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) + _rtl8821ae_stop_tx_beacon(hw); + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + rtl8821ae_dm_write_dig(hw, 0x17); + rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres; + rtl8821ae_dm_write_cck_cca_thres(hw, 0x40); + break; + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + break; + default: + pr_err("switch case %#x not processed\n", + rtlphy->current_io_type); + break; + } + rtlphy->set_io_inprogress = false; + rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + +static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus = false; + u32 initializecount = 0; + + do { + initializecount++; + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while (!rtstatus && (initializecount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl8821ae_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + default: + pr_err("switch case %#x not processed\n", + rfpwr_state); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h new file mode 100644 index 000000000..90bf5462a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_PHY_H__ +#define __RTL8821AE_PHY_H__ + +/* MAX_TX_COUNT must always be set to 4, otherwise read + * efuse table sequence will be wrong. + */ +#define MAX_TX_COUNT 4 +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define MAX_POWER_INDEX 0x3F + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define index_mapping_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNADIVERSITYVALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL8821AE_MAX_PATH_NUM 2 + +#define TARGET_CHNL_NUM_2G_5G_8812 59 + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; +enum _ANT_DIV_TYPE { + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, + +}; + +u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw); +void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, + u8 band); +void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, + u8 channel); +void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, + bool b_recovery); +void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, + bool b_recovery); +void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl); +void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path); +void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw); +u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band, u8 rf_path); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c new file mode 100644 index 000000000..1e7b3c770 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../pwrseqcmd.h" +#include "pwrseq.h" + +/* drivers should parse below arrays and do the corresponding actions */ +/* 3 Power on Array */ +struct wlan_pwr_cfg rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_CARDEMU_TO_ACT + RTL8812_TRANS_END +}; + +/* 3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_ACT_TO_CARDEMU + RTL8812_TRANS_END +}; + +/* 3Card Disable Array */ +struct wlan_pwr_cfg rtl8812_card_disable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_ACT_TO_CARDEMU + RTL8812_TRANS_CARDEMU_TO_CARDDIS + RTL8812_TRANS_END +}; + +/* 3 Card Enable Array */ +struct wlan_pwr_cfg rtl8812_card_enable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_CARDDIS_TO_CARDEMU + RTL8812_TRANS_CARDEMU_TO_ACT + RTL8812_TRANS_END +}; + +/* 3Suspend Array */ +struct wlan_pwr_cfg rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_ACT_TO_CARDEMU + RTL8812_TRANS_CARDEMU_TO_SUS + RTL8812_TRANS_END +}; + +/* 3 Resume Array */ +struct wlan_pwr_cfg rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_SUS_TO_CARDEMU + RTL8812_TRANS_CARDEMU_TO_ACT + RTL8812_TRANS_END +}; + +/* 3HWPDN Array */ +struct wlan_pwr_cfg rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS] = { + RTL8812_TRANS_ACT_TO_CARDEMU + RTL8812_TRANS_CARDEMU_TO_PDN + RTL8812_TRANS_END +}; + +/* 3 Enter LPS */ +struct wlan_pwr_cfg rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS + + RTL8812_TRANS_END_STEPS] = { + /* FW behavior */ + RTL8812_TRANS_ACT_TO_LPS + RTL8812_TRANS_END +}; + +/* 3 Leave LPS */ +struct wlan_pwr_cfg rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS + + RTL8812_TRANS_END_STEPS] = { + /* FW behavior */ + RTL8812_TRANS_LPS_TO_ACT + RTL8812_TRANS_END +}; + +/* drivers should parse below arrays and do the corresponding actions */ +/*3 Power on Array*/ +struct wlan_pwr_cfg rtl8821A_power_on_flow[RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_CARDEMU_TO_ACT + RTL8821A_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8821A_radio_off_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_ACT_TO_CARDEMU + RTL8821A_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8821A_card_disable_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_ACT_TO_CARDEMU + RTL8821A_TRANS_CARDEMU_TO_CARDDIS + RTL8821A_TRANS_END +}; + +/*3 Card Enable Array*/ +/*RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS*/ +struct wlan_pwr_cfg rtl8821A_card_enable_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_CARDDIS_TO_CARDEMU + RTL8821A_TRANS_CARDEMU_TO_ACT + RTL8821A_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8821A_suspend_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_ACT_TO_CARDEMU + RTL8821A_TRANS_CARDEMU_TO_SUS + RTL8821A_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8821A_resume_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_SUS_TO_CARDEMU + RTL8821A_TRANS_CARDEMU_TO_ACT + RTL8821A_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8821A_hwpdn_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8821A_TRANS_END_STEPS] = { + RTL8821A_TRANS_ACT_TO_CARDEMU + RTL8821A_TRANS_CARDEMU_TO_PDN + RTL8821A_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8821A_enter_lps_flow[RTL8821A_TRANS_ACT_TO_LPS_STEPS + + RTL8821A_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8821A_TRANS_ACT_TO_LPS + RTL8821A_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8821A_leave_lps_flow[RTL8821A_TRANS_LPS_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS] = { + /*FW behavior*/ + RTL8821A_TRANS_LPS_TO_ACT + RTL8821A_TRANS_END +}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h new file mode 100644 index 000000000..d6f3cbab4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h @@ -0,0 +1,716 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_PWRSEQ_H__ +#define __RTL8821AE_PWRSEQ_H__ + +#include "../pwrseqcmd.h" +#include "../btcoexist/halbt_precomp.h" + +#define RTL8812_TRANS_CARDEMU_TO_ACT_STEPS 15 +#define RTL8812_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8812_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_CARDEMU_TO_PDN_STEPS 25 +#define RTL8812_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8812_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8812_TRANS_END_STEPS 1 + +/* The following macros have the following format: + * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value + * comments }, + */ +#define RTL8812_TRANS_CARDEMU_TO_ACT \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0 \ + /* disable SW LPS 0x04[10]=0*/}, \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, BIT1 \ + /* wait till 0x04[17] = 1 power ready*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0 \ + /* disable HWPDN 0x04[15]=0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0 \ + /* disable WL suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /* polling until return 0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT0, 0}, + +#define RTL8812_TRANS_ACT_TO_CARDEMU \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04 \ + /* 0xc00[7:0] = 4 turn off 3-wire */}, \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04 \ + /* 0xe00[7:0] = 4 turn off 3-wire */}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /* 0x2[0] = 0 RESET BB, CLOSE RF */}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US \ + /*Delay 1us*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /* Whole BB is reset*/}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x2A \ + /* 0x07[7:0] = 0x28 sps pwm mode 0x2a for BT coex*/}, \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0 \ + /*0x8[1] = 0 ANA clk =500k */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*0x04[9] = 1 turn off MAC by HW state machine*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, 0 \ + /*wait till 0x04[9] = 0 polling until return 0 to disable*/}, + +#define RTL8812_TRANS_CARDEMU_TO_SUS \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xc0}, \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xE0}, \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07 \ + /* gpio11 input mode, gpio10~8 output mode */}, \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio 0~7 output same value as input ?? */}, \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xff \ + /* gpio0~7 output mode */}, \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /* 0x47[7:0] = 00 gpio mode */}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /* suspend option all off */}, \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, BIT7 \ + /*0x14[7] = 1 turn on ZCD */}, \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, BIT0 \ + /* 0x15[0] =1 trun on ZCD */}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, BIT4 \ + /*0x23[4] = 1 hpon LDO sleep mode */}, \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0 \ + /*0x8[1] = 0 ANA clk =500k */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, BIT3 \ + /*0x04[11] = 2b'11 enable WL suspend for PCIe*/}, + +#define RTL8812_TRANS_SUS_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0 \ + /*0x04[11] = 2b'01enable WL suspend*/}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, 0 \ + /*0x23[4] = 0 hpon LDO sleep mode leave */}, \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0 \ + /* 0x15[0] =0 trun off ZCD */}, \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, 0 \ + /*0x14[7] = 0 turn off ZCD */}, \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio0~7 input mode */}, \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio11 input mode, gpio10~8 input mode */}, + +#define RTL8812_TRANS_CARDEMU_TO_CARDDIS \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0 \ + /*0x03[2] = 0, reset 8051*/}, \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x05 \ + /*0x80=05h if reload fw, fill the default value of host_CPU handshake field*/}, \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xcc}, \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xEC}, \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07 \ + /* gpio11 input mode, gpio10~8 output mode */}, \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio 0~7 output same value as input ?? */}, \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xff \ + /* gpio0~7 output mode */}, \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /* 0x47[7:0] = 00 gpio mode */}, \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, BIT7 \ + /*0x14[7] = 1 turn on ZCD */}, \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, BIT0 \ + /* 0x15[0] =1 trun on ZCD */}, \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0 \ + /*0x12[0] = 0 force PFM mode */}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, BIT4 \ + /*0x23[4] = 1 hpon LDO sleep mode */}, \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x02, 0 \ + /*0x8[1] = 0 ANA clk =500k */}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20 \ + /*0x07=0x20 , SOP option to disable BG/MB*/}, \ + {0x001f, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*0x01f[1]=0 , disable RFC_0 control REG_RF_CTRL_8812 */}, \ + {0x0076, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*0x076[1]=0 , disable RFC_1 control REG_OPT_CTRL_8812 +2 */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, BIT3 \ + /*0x04[11] = 2b'01 enable WL suspend*/}, + +#define RTL8812_TRANS_CARDDIS_TO_CARDEMU \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /*0x12[0] = 1 force PWM mode */}, \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x80, 0 \ + /*0x14[7] = 0 turn off ZCD */}, \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x01, 0 \ + /* 0x15[0] =0 trun off ZCD */}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x10, 0 \ + /*0x23[4] = 0 hpon LDO leave sleep mode */}, \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio0~7 input mode */}, \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /* gpio11 input mode, gpio10~8 input mode */}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, 0 \ + /*0x04[10] = 0, enable SW LPS PCIE only*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3, 0 \ + /*0x04[11] = 2b'01enable WL suspend*/}, \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, BIT2 \ + /*0x03[2] = 1, enable 8051*/}, \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*PCIe DMA start*/}, + +#define RTL8812_TRANS_CARDEMU_TO_PDN \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, BIT7 \ + /* 0x04[15] = 1*/}, + +#define RTL8812_TRANS_PDN_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0 \ + /* 0x04[15] = 0*/}, + +#define RTL8812_TRANS_ACT_TO_LPS \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*PCIe DMA stop*/}, \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F \ + /*Tx Pause*/}, \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04 \ + /* 0xc00[7:0] = 4 turn off 3-wire */}, \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x04 \ + /* 0xe00[7:0] = 4 turn off 3-wire */}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /*CCK and OFDM are disabled,and clock are gated,and RF closed*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US \ + /*Delay 1us*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /* Whole BB is reset*/}, \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03 \ + /*Reset MAC TRX*/}, \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*check if removed later*/}, \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5 \ + /*Respond TxOK to scheduler*/}, + +#define RTL8812_TRANS_LPS_TO_ACT \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*SDIO RPWM*/}, \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*USB RPWM*/}, \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*PCIe RPWM*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS \ + /*Delay*/}, \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ + /*. 0x08[4] = 0 switch TSF to 40M*/}, \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT7, 0 \ + /*Polling 0x109[7]=0 TSF in 40M*/}, \ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT6|BIT7, 0 \ + /*. 0x29[7:6] = 2b'00 enable BB clock*/}, \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*. 0x101[1] = 1*/}, \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*. 0x100[7:0] = 0xFF enable WMAC TRX*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0 \ + /*. 0x02[1:0] = 2b'11 enable BB macro*/}, \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*. 0x522 = 0*/}, + +#define RTL8812_TRANS_END \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ + 0, PWR_CMD_END, 0, 0}, + +extern struct wlan_pwr_cfg rtl8812_power_on_flow + [RTL8812_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_radio_off_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_card_disable_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_card_enable_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_suspend_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_resume_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_hwpdn_flow + [RTL8812_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_enter_lps_flow + [RTL8812_TRANS_ACT_TO_LPS_STEPS + + RTL8812_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8812_leave_lps_flow + [RTL8812_TRANS_LPS_TO_ACT_STEPS + + RTL8812_TRANS_END_STEPS]; + +/* Check document WM-20130516-JackieLau-RTL8821A_Power_Architecture-R10.vsd + * There are 6 HW Power States: + * 0: POFF--Power Off + * 1: PDN--Power Down + * 2: CARDEMU--Card Emulation + * 3: ACT--Active Mode + * 4: LPS--Low Power State + * 5: SUS--Suspend + * + * The transision from different states are defined below + * TRANS_CARDEMU_TO_ACT + * TRANS_ACT_TO_CARDEMU + * TRANS_CARDEMU_TO_SUS + * TRANS_SUS_TO_CARDEMU + * TRANS_CARDEMU_TO_PDN + * TRANS_ACT_TO_LPS + * TRANS_LPS_TO_ACT + * + * TRANS_END + */ +#define RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS 25 +#define RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8821A_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8821A_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8821A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8821A_TRANS_END_STEPS 1 + +#define RTL8821A_TRANS_CARDEMU_TO_ACT \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/}, \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ + /*0x67[0] = 0 to disable BT_GPS_SEL pins*/}, \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS \ + /*Delay 1ms*/}, \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, 0 \ + /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT4|BIT3|BIT2), 0 \ + /* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[12:11]=0*/}, \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0 , BIT0 \ + /* Disable USB suspend */}, \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, BIT1 \ + /* wait till 0x04[17] = 1 power ready*/}, \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0 , 0 \ + /* Enable USB suspend */}, \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /* release WLON reset 0x04[16]=1*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0 \ + /* disable HWPDN 0x04[15]=0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT4|BIT3), 0 \ + /* disable WL suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /* polling until return 0*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT0, 0 \ + /**/}, \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /*0x4C[24] = 0x4F[0] = 1, switch DPDT_SEL_P output from WL BB */},\ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT5|BIT4), (BIT5|BIT4) \ + /*0x66[13] = 0x67[5] = 1, switch for PAPE_G/PAPE_A \ + from WL BB ; 0x66[12] = 0x67[4] = 1, switch LNAON from WL BB */},\ + {0x0025, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT6, 0 \ + /*anapar_mac<118> , 0x25[6]=0 by wlan single function*/},\ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*Enable falling edge triggering interrupt*/},\ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*Enable GPIO9 interrupt mode*/},\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*Enable GPIO9 input mode*/},\ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0 \ + /*Enable HSISR GPIO[C:0] interrupt*/},\ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*Enable HSISR GPIO9 interrupt*/},\ + {0x007A, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3A \ + /*0x7A = 0x3A start BT*/},\ + {0x002E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF , 0x82 \ + /* 0x2C[23:12]=0x820 ; XTAL trim */}, \ + {0x0010, PWR_CUT_A_MSK , PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT6 , BIT6 \ + /* 0x10[6]=1 */}, + +#define RTL8821A_TRANS_ACT_TO_CARDEMU \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*0x1F[7:0] = 0 turn off RF*/}, \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /*0x4C[24] = 0x4F[0] = 0, switch DPDT_SEL_P output from \ + register 0x65[2] */},\ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*Enable rising edge triggering interrupt*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*0x04[9] = 1 turn off MAC by HW state machine*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT1, 0 \ + /*wait till 0x04[9] = 0 polling until return 0 to disable*/}, \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5 \ + /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/}, \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/}, + +#define RTL8821A_TRANS_CARDEMU_TO_SUS \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3) \ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, BIT3 \ + /*0x04[12:11] = 2b'01 enable WL suspend*/}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, BIT4 \ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20 \ + /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4 \ + /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT0, BIT0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT1, 0 \ + /*wait power state to suspend*/}, + +#define RTL8821A_TRANS_SUS_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3 | BIT7, 0 \ + /*clear suspend enable and power down enable*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT0, 0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT1, BIT1 \ + /*wait power state to suspend*/},\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ + /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ + /*0x04[12:11] = 2b'00 disable WL suspend*/}, + +#define RTL8821A_TRANS_CARDEMU_TO_CARDDIS \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20 \ + /*0x07=0x20 , SOP option to disable BG/MB*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, BIT3 \ + /*0x04[12:11] = 2b'01 enable WL suspend*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT2, BIT2 \ + /*0x04[10] = 1, enable SW LPS*/}, \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 1 \ + /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/}, \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, BIT4 \ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT0, BIT0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT1, 0 \ + /*wait power state to suspend*/}, + +#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3 | BIT7, 0 \ + /*clear suspend enable and power down enable*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT0, 0 \ + /*Set SDIO suspend local register*/}, \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT1, BIT1 \ + /*wait power state to suspend*/},\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/}, \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ + /*0x04[12:11] = 2b'00 disable WL suspend*/},\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ + /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*PCIe DMA start*/}, + +#define RTL8821A_TRANS_CARDEMU_TO_PDN \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, BIT4 \ + /*0x23[4] = 1b'1 12H LDO enter sleep mode*/}, \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ + PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20 \ + /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/}, \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /* 0x04[16] = 0*/},\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, BIT7 \ + /* 0x04[15] = 1*/}, + +#define RTL8821A_TRANS_PDN_TO_CARDEMU \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, 0 \ + /* 0x04[15] = 0*/}, + +#define RTL8821A_TRANS_ACT_TO_LPS \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*PCIe DMA stop*/}, \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*Tx Pause*/}, \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \ + /*Should be zero if no packet is transmitting*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0 \ + /*CCK and OFDM are disabled,and clock are gated*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US \ + /*Delay 1us*/}, \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*Whole BB is reset*/}, \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03 \ + /*Reset MAC TRX*/}, \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0 \ + /*check if removed later*/}, \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00 \ + /*When driver enter Sus/ Disable, enable LOP for BT*/}, \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5 \ + /*Respond TxOK to scheduler*/}, + +#define RTL8821A_TRANS_LPS_TO_ACT \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ + PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*SDIO RPWM*/},\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*USB RPWM*/},\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \ + /*PCIe RPWM*/},\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS \ + /*Delay*/},\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ + /*. 0x08[4] = 0 switch TSF to 40M*/},\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT7, 0 \ + /*Polling 0x109[7]=0 TSF in 40M*/},\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT6|BIT7, 0 \ + /*. 0x29[7:6] = 2b'00 enable BB clock*/},\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1 \ + /*. 0x101[1] = 1*/},\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \ + /*. 0x100[7:0] = 0xFF enable WMAC TRX*/},\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0 \ + /*. 0x02[1:0] = 2b'11 enable BB macro*/},\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \ + /*. 0x522 = 0*/}, + +#define RTL8821A_TRANS_END \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ + 0, PWR_CMD_END, 0, 0}, + +extern struct wlan_pwr_cfg rtl8821A_power_on_flow + [RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_radio_off_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_card_disable_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_card_enable_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_suspend_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_resume_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_hwpdn_flow + [RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS + + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_enter_lps_flow + [RTL8821A_TRANS_ACT_TO_LPS_STEPS + + RTL8821A_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8821A_leave_lps_flow + [RTL8821A_TRANS_LPS_TO_ACT_STEPS + + RTL8821A_TRANS_END_STEPS]; + +/*RTL8812 Power Configuration CMDs for PCIe interface*/ +#define RTL8812_NIC_PWR_ON_FLOW rtl8812_power_on_flow +#define RTL8812_NIC_RF_OFF_FLOW rtl8812_radio_off_flow +#define RTL8812_NIC_DISABLE_FLOW rtl8812_card_disable_flow +#define RTL8812_NIC_ENABLE_FLOW rtl8812_card_enable_flow +#define RTL8812_NIC_SUSPEND_FLOW rtl8812_suspend_flow +#define RTL8812_NIC_RESUME_FLOW rtl8812_resume_flow +#define RTL8812_NIC_PDN_FLOW rtl8812_hwpdn_flow +#define RTL8812_NIC_LPS_ENTER_FLOW rtl8812_enter_lps_flow +#define RTL8812_NIC_LPS_LEAVE_FLOW rtl8812_leave_lps_flow + +/* RTL8821 Power Configuration CMDs for PCIe interface */ +#define RTL8821A_NIC_PWR_ON_FLOW rtl8821A_power_on_flow +#define RTL8821A_NIC_RF_OFF_FLOW rtl8821A_radio_off_flow +#define RTL8821A_NIC_DISABLE_FLOW rtl8821A_card_disable_flow +#define RTL8821A_NIC_ENABLE_FLOW rtl8821A_card_enable_flow +#define RTL8821A_NIC_SUSPEND_FLOW rtl8821A_suspend_flow +#define RTL8821A_NIC_RESUME_FLOW rtl8821A_resume_flow +#define RTL8821A_NIC_PDN_FLOW rtl8821A_hwpdn_flow +#define RTL8821A_NIC_LPS_ENTER_FLOW rtl8821A_enter_lps_flow +#define RTL8821A_NIC_LPS_LEAVE_FLOW rtl8821A_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h new file mode 100644 index 000000000..7d833b72c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h @@ -0,0 +1,2444 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_REG_H__ +#define __RTL8821AE_REG_H__ + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 + /* 1.5v for 8188EE test chip, 1.4v for MP chip */ +#define REG_AFE_LDO_CTRL 0x0027 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 +#define REG_GPIO_IO_SEL_2 0x0062 +#define REG_MULTI_FUNC_CTRL 0x0068 +#define REG_GPIO_OUTPUT 0x006c +#define REG_OPT_CTRL 0x0074 +#define REG_AFE_XTAL_CTRL_EXT 0x0078 +#define REG_XCK_OUT_CTRL 0x007c +#define REG_MCUFWDL 0x0080 +#define REG_WOL_EVENT 0x0081 +#define REG_MCUTSTCFG 0x0084 + +#define REG_HIMR 0x00B0 +#define REG_HISR 0x00B4 +#define REG_HIMRE 0x00B8 +#define REG_HISRE 0x00BC + +#define REG_PMC_DBG_CTRL2 0x00CC + +#define REG_EFUSE_ACCESS 0x00CF + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 +#define REG_MAC_PHY_CTRL_NORMAL 0x00F8 +#define REG_SYS_CFG1 0x00FC +#define REG_ROM_VERSION 0x00FD + +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C + +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTISR 0x013C +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 +#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_32K_CTRL 0x0194 +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_MCUTST_WOWLAN 0x01C7 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC + +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +#define REG_RXDMA_AGG_PG_TH 0x0280 + /* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */ +#define REG_FW_UPD_RDPTR 0x0284 + /* Control the RX DMA.*/ +#define REG_RXDMA_CONTROL 0x0286 +/* The number of packets in RXPKTBUF. */ +#define REG_RXPKT_NUM 0x0287 + +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 + +#define REG_DBI_WDATA 0x0348 +#define REG_DBI_RDATA 0x034C +#define REG_DBI_CTRL 0x0350 +#define REG_DBI_ADDR 0x0350 +#define REG_DBI_FLAG 0x0352 +#define REG_MDIO_WDATA 0x0354 +#define REG_MDIO_RDATA 0x0356 +#define REG_MDIO_CTL 0x0358 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_WATCH_DOG 0x0368 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +#define REG_HDAQ_DESA_NODEF 0x0000 +#define REG_CMDQ_DESA_NODEF 0x0000 + +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 +#define REG_TXPKT_EMPTY 0x041A + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x044C +#define REG_CCK_CHECK 0x0454 +#define REG_AMPDU_MAX_TIME 0x0456 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_ARFR2 0x048C +#define REG_ARFR3 0x0494 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_HT_SINGLE_AMPDU 0x04C7 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_EARLY_MODE_CONTROL 0x04D0 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 +#define REG_DUMMY 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_SECONDARY_CCA_CTRL 0x0577 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_NOA_DESC_SEL 0x05CF +#define REG_NOA_DESC_DURATION 0x05E0 +#define REG_NOA_DESC_INTERVAL 0x05E4 +#define REG_NOA_DESC_START 0x05E8 +#define REG_NOA_DESC_COUNT 0x05EC +#define REG_SCH_TXCMD 0x05F8 + +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_NAV_CTRL 0x0650 +#define REG_NAV_UPPER 0x0652 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_TRXPTCL_CTL 0x0668 + +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_NUM 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 +#define REG_TEST_SIE_PID 0xFE62 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 +#define REG_TEST_SIE_MAC_ADDR 0xFE70 +#define REG_TEST_SIE_STRING 0xFE80 + +#define REG_NORMAL_SIE_VID 0xFE60 +#define REG_NORMAL_SIE_PID 0xFE62 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 +#define REG_NORMAL_SIE_PHY 0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 +#define REG_NORMAL_SIE_STRING 0xFE80 + +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +#define UNUSED_REGISTER 0x1BF +#define DCAM UNUSED_REGISTER +#define PSR UNUSED_REGISTER +#define BBADDR UNUSED_REGISTER +#define PHYDATAR UNUSED_REGISTER + +#define INVALID_BBRF_VALUE 0x12345678 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define CMDEEPROM_EN BIT(5) +#define CMDEEPROM_SEL BIT(4) +#define CMD9346CR_9356SEL BIT(4) +#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) +#define AUTOLOAD_EFUSE CMDEEPROM_EN + +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT(5) + +#define GPIO_IN REG_GPIO_PIN_CTRL +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */ +#define HSIMR_GPIO12_0_INT_EN BIT(0) +#define HSIMR_SPS_OCP_INT_EN BIT(5) +#define HSIMR_RON_INT_EN BIT(6) +#define HSIMR_PDN_INT_EN BIT(7) +#define HSIMR_GPIO9_INT_EN BIT(25) + +/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */ +#define HSISR_GPIO12_0_INT BIT(0) +#define HSISR_SPS_OCP_INT BIT(5) +#define HSISR_RON_INT_EN BIT(6) +#define HSISR_PDNINT BIT(7) +#define HSISR_GPIO9_INT BIT(25) + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 +#define MSR_MASK 0x03 + +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) +#define BRSR_ACKSHORTPMB BIT(23) + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ + RATR_MCS14 | RATR_MCS15) + +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +#define SCR_USEDK 0x01 +#define SCR_TXSEC_ENABLE 0x02 +#define SCR_RXSEC_ENABLE 0x04 + +#define WOW_PMEN BIT(0) +#define WOW_WOMEN BIT(1) +#define WOW_MAGIC BIT(2) +#define WOW_UWF BIT(3) + +/********************************************* +* 8188 IMR/ISR bits +**********************************************/ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +/* TXRPT interrupt when CCX bit of the packet is set */ +#define IMR_TXCCK BIT(30) +/* Power Save Time Out Interrupt */ +#define IMR_PSTIMEOUT BIT(29) +/* When GTIMER4 expires, this bit is set to 1 */ +#define IMR_GTINT4 BIT(28) +/* When GTIMER3 expires, this bit is set to 1 */ +#define IMR_GTINT3 BIT(27) +/* Transmit Beacon0 Error */ +#define IMR_TBDER BIT(26) +/* Transmit Beacon0 OK */ +#define IMR_TBDOK BIT(25) +/* TSF Timer BIT32 toggle indication interrupt */ +#define IMR_TSF_BIT32_TOGGLE BIT(24) +/* Beacon DMA Interrupt 0 */ +#define IMR_BCNDMAINT0 BIT(20) +/* Beacon Queue DMA OK0 */ +#define IMR_BCNDOK0 BIT(16) +/* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */ +#define IMR_HSISR_IND_ON_INT BIT(15) +/* Beacon DMA Interrupt Extension for Win7 */ +#define IMR_BCNDMAINT_E BIT(14) +/* CTWidnow End or ATIM Window End */ +#define IMR_ATIMEND BIT(12) +/* HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1)*/ +#define IMR_HISR1_IND_INT BIT(11) +/* CPU to Host Command INT Status, Write 1 clear */ +#define IMR_C2HCMD BIT(10) +/* CPU power Mode exchange INT Status, Write 1 clear */ +#define IMR_CPWM2 BIT(9) +/* CPU power Mode exchange INT Status, Write 1 clear */ +#define IMR_CPWM BIT(8) +/* High Queue DMA OK */ +#define IMR_HIGHDOK BIT(7) +/* Management Queue DMA OK */ +#define IMR_MGNTDOK BIT(6) +/* AC_BK DMA OK */ +#define IMR_BKDOK BIT(5) +/* AC_BE DMA OK */ +#define IMR_BEDOK BIT(4) +/* AC_VI DMA OK */ +#define IMR_VIDOK BIT(3) +/* AC_VO DMA OK */ +#define IMR_VODOK BIT(2) +/* Rx Descriptor Unavailable */ +#define IMR_RDU BIT(1) +#define IMR_ROK BIT(0) /* Receive DMA OK */ + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +/* Beacon DMA Interrupt 7 */ +#define IMR_BCNDMAINT7 BIT(27) +/* Beacon DMA Interrupt 6 */ +#define IMR_BCNDMAINT6 BIT(26) +/* Beacon DMA Interrupt 5 */ +#define IMR_BCNDMAINT5 BIT(25) +/* Beacon DMA Interrupt 4 */ +#define IMR_BCNDMAINT4 BIT(24) +/* Beacon DMA Interrupt 3 */ +#define IMR_BCNDMAINT3 BIT(23) +/* Beacon DMA Interrupt 2 */ +#define IMR_BCNDMAINT2 BIT(22) +/* Beacon DMA Interrupt 1 */ +#define IMR_BCNDMAINT1 BIT(21) +/* Beacon Queue DMA OK Interrup 7 */ +#define IMR_BCNDOK7 BIT(20) +/* Beacon Queue DMA OK Interrup 6 */ +#define IMR_BCNDOK6 BIT(19) +/* Beacon Queue DMA OK Interrup 5 */ +#define IMR_BCNDOK5 BIT(18) +/* Beacon Queue DMA OK Interrup 4 */ +#define IMR_BCNDOK4 BIT(17) +/* Beacon Queue DMA OK Interrup 3 */ +#define IMR_BCNDOK3 BIT(16) +/* Beacon Queue DMA OK Interrup 2 */ +#define IMR_BCNDOK2 BIT(15) +/* Beacon Queue DMA OK Interrup 1 */ +#define IMR_BCNDOK1 BIT(14) +/* ATIM Window End Extension for Win7 */ +#define IMR_ATIMEND_E BIT(13) +/* Tx Error Flag Interrupt Status, write 1 clear. */ +#define IMR_TXERR BIT(11) +/* Rx Error Flag INT Status, Write 1 clear */ +#define IMR_RXERR BIT(10) +/* Transmit FIFO Overflow */ +#define IMR_TXFOVW BIT(9) +/* Receive FIFO Overflow */ +#define IMR_RXFOVW BIT(8) + +#define HWSET_MAX_SIZE 512 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 256 +/* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte.*/ +#define EFUSE_OOB_PROTECT_BYTES 18 + +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_BOARDTYPE 0x02 +#define EEPROM_DEFAULT_TXPOWER 0x1010 +#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 + +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_THERMALMETER 0x18 +#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 +#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 +#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +#define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0xC3 + +#define EEPROM_DEFAULT_PID 0x1234 +#define EEPROM_DEFAULT_VID 0x5678 +#define EEPROM_DEFAULT_CUSTOMERID 0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD +#define EEPROM_DEFAULT_VERSION 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0XB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define RTL_EEPROM_ID 0x8129 + +#define EEPROM_HPON 0x02 +#define EEPROM_CLK 0x06 +#define EEPROM_TESTR 0x08 + +#define EEPROM_TXPOWERCCK 0x10 +#define EEPROM_TXPOWERHT40_1S 0x16 +#define EEPROM_TXPOWERHT20DIFF 0x1B +#define EEPROM_TXPOWER_OFDMDIFF 0x1B + +#define EEPROM_TX_PWR_INX 0x10 + +#define EEPROM_CHANNELPLAN 0XB8 +#define EEPROM_XTAL_8821AE 0XB9 +#define EEPROM_THERMAL_METER 0XBA +#define EEPROM_IQK_LCK_88E 0XBB + +#define EEPROM_RF_BOARD_OPTION 0xC1 +#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 +#define EEPROM_RF_BT_SETTING 0xC3 +#define EEPROM_VERSION 0xC4 +#define EEPROM_CUSTOMER_ID 0xC5 +#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 +#define EEPROM_RFE_OPTION 0xCA + +#define EEPROM_MAC_ADDR 0xD0 +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_NONQOS_VHT BIT(26) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define ENPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define ENBT BIT(5) +#define ENUART BIT(8) +#define UART_910 BIT(9) +#define ENPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define ENSIC BIT(12) +#define SIC_23 BIT(13) +#define ENHDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE (REG_CR + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0XB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) +#define ACMHW_BEQSTATUS BIT(4) +#define ACMHW_VIQSTATUS BIT(5) +#define ACMHW_VOQSTATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define ENMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXDECENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE + +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +#define RA_LSSIWRITE_8821A 0xc90 +#define RB_LSSIWRITE_8821A 0xe90 + +#define RA_PIREAD_8821A 0xd04 +#define RB_PIREAD_8821A 0xd44 +#define RA_SIREAD_8821A 0xd08 +#define RB_SIREAD_8821A 0xd48 + +#define RPMAC_RESET 0x100 +#define RPMAC_TXSTART 0x104 +#define RPMAC_TXLEGACYSIG 0x108 +#define RPMAC_TXHTSIG1 0x10c +#define RPMAC_TXHTSIG2 0x110 +#define RPMAC_PHYDEBUG 0x114 +#define RPMAC_TXPACKETNUM 0x118 +#define RPMAC_TXIDLE 0x11c +#define RPMAC_TXMACHEADER0 0x120 +#define RPMAC_TXMACHEADER1 0x124 +#define RPMAC_TXMACHEADER2 0x128 +#define RPMAC_TXMACHEADER3 0x12c +#define RPMAC_TXMACHEADER4 0x130 +#define RPMAC_TXMACHEADER5 0x134 +#define RPMAC_TXDADATYPE 0x138 +#define RPMAC_TXRANDOMSEED 0x13c +#define RPMAC_CCKPLCPPREAMBLE 0x140 +#define RPMAC_CCKPLCPHEADER 0x144 +#define RPMAC_CCKCRC16 0x148 +#define RPMAC_OFDMRXCRC32OK 0x170 +#define RPMAC_OFDMRXCRC32ER 0x174 +#define RPMAC_OFDMRXPARITYER 0x178 +#define RPMAC_OFDMRXCRC8ER 0x17c +#define RPMAC_CCKCRXRC16ER 0x180 +#define RPMAC_CCKCRXRC32ER 0x184 +#define RPMAC_CCKCRXRC32OK 0x188 +#define RPMAC_TXSTATUS 0x18c + +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c +#define RCCAONSEC 0x838 + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 +#define RL1PEAKTH 0x848 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFC_AREA 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RRFMOD 0x8ac +#define RHSSIREAD_8821AE 0x8b0 + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +#define RADC_BUF_CLK 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +#define RCCK_SYSTEM 0xa00 +#define BCCK_SYSTEM 0x10 + +#define RCCK0_AFESETTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 +#define RCCK0_CCA_CNT 0xa60 + +/* PageB(0XB00) */ +#define RPDP_ANTA 0xb00 +#define RPDP_ANTA_4 0xb04 +#define RPDP_ANTA_8 0xb08 +#define RPDP_ANTA_C 0xb0c +#define RPDP_ANTA_10 0xb10 +#define RPDP_ANTA_14 0xb14 +#define RPDP_ANTA_18 0xb18 +#define RPDP_ANTA_1C 0xb1c +#define RPDP_ANTA_20 0xb20 +#define RPDP_ANTA_24 0xb24 + +#define RCONFIG_PMPD_ANTA 0xb28 +#define RCONFIG_RAM64x16 0xb2c + +#define RBNDA 0xb30 +#define RHSSIPAR 0xb34 + +#define RCONFIG_ANTA 0xb68 +#define RCONFIG_ANTB 0xb6c + +#define RPDP_ANTB 0xb70 +#define RPDP_ANTB_4 0xb74 +#define RPDP_ANTB_8 0xb78 +#define RPDP_ANTB_C 0xb7c +#define RPDP_ANTB_10 0xb80 +#define RPDP_ANTB_14 0xb84 +#define RPDP_ANTB_18 0xb88 +#define RPDP_ANTB_1C 0xb8c +#define RPDP_ANTB_20 0xb90 +#define RPDP_ANTB_24 0xb94 + +#define RCONFIG_PMPD_ANTB 0xb98 + +#define RBNDB 0xba0 + +#define RAPK 0xbd8 +#define RPM_RX0_ANTA 0xbdc +#define RPM_RX1_ANTA 0xbe0 +#define RPM_RX2_ANTA 0xbe4 +#define RPM_RX3_ANTA 0xbe8 +#define RPM_RX0_ANTB 0xbec +#define RPM_RX1_ANTB 0xbf0 +#define RPM_RX2_ANTB 0xbf4 +#define RPM_RX3_ANTB 0xbf8 + +/*RSSI Dump*/ +#define RA_RSSI_DUMP 0XBF0 +#define RB_RSSI_DUMP 0XBF1 +#define RS1_RX_EVM_DUMP 0XBF4 +#define RS2_RX_EVM_DUMP 0XBF5 +#define RA_RX_SNR_DUMP 0XBF6 +#define RB_RX_SNR_DUMP 0XBF7 +#define RA_CFO_SHORT_DUMP 0XBF8 +#define RB_CFO_SHORT_DUMP 0XBFA +#define RA_CFO_LONG_DUMP 0XBEC +#define RB_CFO_LONG_DUMP 0XBEE + +/*Page C*/ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBANLANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATXIQIMBALANCE 0xc80 +#define ROFDM0_XATXAFE 0xc84 +#define ROFDM0_XBTXIQIMBALANCE 0xc88 +#define ROFDM0_XBTXAFE 0xc8c +#define ROFDM0_XCTXIQIMBALANCE 0xc90 +#define ROFDM0_XCTXAFE 0xc94 +#define ROFDM0_XDTXIQIMBALANCE 0xc98 +#define ROFDM0_XDTXAFE 0xc9c + +#define ROFDM0_RXIQEXTANTA 0xca0 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +/*Path_A RFE cotrol */ +#define RA_RFE_CTRL_8812 0xcb8 +/*Path_B RFE control*/ +#define RB_RFE_CTRL_8812 0xeb8 + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 + +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CF0 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCF0AB 0xdbc +#define ROFDM_TAILCF0CD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGREPORT 0xddc + +#define RTXAGC_A_CCK11_CCK1 0xc20 +#define RTXAGC_A_OFDM18_OFDM6 0xc24 +#define RTXAGC_A_OFDM54_OFDM24 0xc28 +#define RTXAGC_A_MCS03_MCS00 0xc2c +#define RTXAGC_A_MCS07_MCS04 0xc30 +#define RTXAGC_A_MCS11_MCS08 0xc34 +#define RTXAGC_A_MCS15_MCS12 0xc38 +#define RTXAGC_A_NSS1INDEX3_NSS1INDEX0 0xc3c +#define RTXAGC_A_NSS1INDEX7_NSS1INDEX4 0xc40 +#define RTXAGC_A_NSS2INDEX1_NSS1INDEX8 0xc44 +#define RTXAGC_A_NSS2INDEX5_NSS2INDEX2 0xc48 +#define RTXAGC_A_NSS2INDEX9_NSS2INDEX6 0xc4c +#define RTXAGC_B_CCK11_CCK1 0xe20 +#define RTXAGC_B_OFDM18_OFDM6 0xe24 +#define RTXAGC_B_OFDM54_OFDM24 0xe28 +#define RTXAGC_B_MCS03_MCS00 0xe2c +#define RTXAGC_B_MCS07_MCS04 0xe30 +#define RTXAGC_B_MCS11_MCS08 0xe34 +#define RTXAGC_B_MCS15_MCS12 0xe38 +#define RTXAGC_B_NSS1INDEX3_NSS1INDEX0 0xe3c +#define RTXAGC_B_NSS1INDEX7_NSS1INDEX4 0xe40 +#define RTXAGC_B_NSS2INDEX1_NSS1INDEX8 0xe44 +#define RTXAGC_B_NSS2INDEX5_NSS2INDEX2 0xe48 +#define RTXAGC_B_NSS2INDEX9_NSS2INDEX6 0xe4c + +#define RA_TXPWRTRAING 0xc54 +#define RB_TXPWRTRAING 0xe54 + +#define RFPGA0_IQK 0xe28 +#define RTX_IQK_TONE_A 0xe30 +#define RRX_IQK_TONE_A 0xe34 +#define RTX_IQK_PI_A 0xe38 +#define RRX_IQK_PI_A 0xe3c + +#define RTX_IQK 0xe40 +#define RRX_IQK 0xe44 +#define RIQK_AGC_PTS 0xe48 +#define RIQK_AGC_RSP 0xe4c +#define RTX_IQK_TONE_B 0xe50 +#define RRX_IQK_TONE_B 0xe54 +#define RTX_IQK_PI_B 0xe58 +#define RRX_IQK_PI_B 0xe5c +#define RIQK_AGC_CONT 0xe60 + +#define RBLUE_TOOTH 0xe6c +#define RRX_WAIT_CCA 0xe70 +#define RTX_CCK_RFON 0xe74 +#define RTX_CCK_BBON 0xe78 +#define RTX_OFDM_RFON 0xe7c +#define RTX_OFDM_BBON 0xe80 +#define RTX_TO_RX 0xe84 +#define RTX_TO_TX 0xe88 +#define RRX_CCK 0xe8c + +#define RTX_POWER_BEFORE_IQK_A 0xe94 +#define RTX_POWER_AFTER_IQK_A 0xe9c + +#define RRX_POWER_BEFORE_IQK_A 0xea0 +#define RRX_POWER_BEFORE_IQK_A_2 0xea4 +#define RRX_POWER_AFTER_IQK_A 0xea8 +#define RRX_POWER_AFTER_IQK_A_2 0xeac + +#define RTX_POWER_BEFORE_IQK_B 0xeb4 +#define RTX_POWER_AFTER_IQK_B 0xebc + +#define RRX_POER_BEFORE_IQK_B 0xec0 +#define RRX_POER_BEFORE_IQK_B_2 0xec4 +#define RRX_POWER_AFTER_IQK_B 0xec8 +#define RRX_POWER_AFTER_IQK_B_2 0xecc + +#define RRX_OFDM 0xed0 +#define RRX_WAIT_RIFS 0xed4 +#define RRX_TO_RX 0xed8 +#define RSTANDBY 0xedc +#define RSLEEP 0xee0 +#define RPMPD_ANAEN 0xeec + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x24 +#define RF_T_METER_88E 0x42 +#define RF_T_METER_8812A 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_APK 0x63 + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(__offset) \ + ((__offset >= 0x800) && (__offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +/* Block & Path enable*/ +#define ROFDMCCKEN 0x808 +#define BCCKEN 0x10000000 +#define BOFDMEN 0x20000000 +/* Rx antenna*/ +#define RRXPATH 0x808 +#define BRXPATH 0xff +/* Tx antenna*/ +#define RTXPATH 0x80c +#define BTXPATH 0x0fffffff +/* for cck rx path selection*/ +#define RCCK_RX 0xa04 +#define BCCK_RX 0x0c000000 +/* Use LSIG for VHT length*/ +#define RVHTLEN_USE_LSIG 0x8c3 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCKRXRFSETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BENABLE 0x1 +#define BDISABLE 0x0 + +#define LEFT_ANTENNA 0x0 +#define RIGHT_ANTENNA 0x1 + +#define TCHECK_TXSTATUS 500 +#define TUPDATE_RXCOUNTER 100 + +#define REG_UN_used_register 0x01bf + +/* Path_A RFE cotrol pinmux*/ +#define RA_RFE_PINMUX 0xcb0 +/* Path_B RFE control pinmux*/ +#define RB_RFE_PINMUX 0xeb0 + +#define RA_RFE_INV 0xcb4 +#define RB_RFE_INV 0xeb4 + +/* RXIQC */ +/*RxIQ imblance matrix coeff. A & B*/ +#define RA_RXIQC_AB 0xc10 +/*RxIQ imblance matrix coeff. C & D*/ +#define RA_RXIQC_CD 0xc14 +/* Pah_A TX scaling factor*/ +#define RA_TXSCALE 0xc1c +/* Path_B TX scaling factor*/ +#define RB_TXSCALE 0xe1c +/*RxIQ imblance matrix coeff. A & B*/ +#define RB_RXIQC_AB 0xe10 +/*RxIQ imblance matrix coeff. C & D*/ +#define RB_RXIQC_CD 0xe14 +/*bit mask for IQC matrix element A & C*/ +#define RXIQC_AC 0x02ff + /*bit mask for IQC matrix element A & C*/ +#define RXIQC_BD 0x02ff0000 + +/* 2 EFUSE_TEST (For RTL8723 partially) */ +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 + +/*REG_MULTI_FUNC_CTRL(For RTL8723 Only)*/ +/* Enable GPIO[9] as WiFi HW PDn source*/ +#define WL_HWPDN_EN BIT(0) +/* WiFi HW PDn polarity control*/ +#define WL_HWPDN_SL BIT(1) +/* WiFi function enable */ +#define WL_FUNC_EN BIT(2) +/* Enable GPIO[9] as WiFi RF HW PDn source */ +#define WL_HWROF_EN BIT(3) +/* Enable GPIO[11] as BT HW PDn source */ +#define BT_HWPDN_EN BIT(16) +/* BT HW PDn polarity control */ +#define BT_HWPDN_SL BIT(17) +/* BT function enable */ +#define BT_FUNC_EN BIT(18) +/* Enable GPIO[11] as BT/GPS RF HW PDn source */ +#define BT_HWROF_EN BIT(19) +/* Enable GPIO[10] as GPS HW PDn source */ +#define GPS_HWPDN_EN BIT(20) +/* GPS HW PDn polarity control */ +#define GPS_HWPDN_SL BIT(21) +/* GPS function enable */ +#define GPS_FUNC_EN BIT(22) + +#define BMASKBYTE0 0xff +#define BMASKBYTE1 0xff00 +#define BMASKBYTE2 0xff0000 +#define BMASKBYTE3 0xff000000 +#define BMASKHWORD 0xffff0000 +#define BMASKLWORD 0x0000ffff +#define BMASKDWORD 0xffffffff +#define BMASK12BITS 0xfff +#define BMASKH4BITS 0xf0000000 +#define BMASKOFDM_D 0xffc00000 +#define BMASKCCK 0x3f3f3f3f +#define BMASKRFEINV 0x3ff00000 + +#define BRFREGOFFSETMASK 0xfffff + +#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804 +#define ODM_REG_BB_RX_PATH_11AC 0x808 +/*PAGE 9*/ +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +/*PAGE A*/ +#define ODM_REG_CCK_CCA_11AC 0xA0A +#define ODM_REG_CCK_FA_RST_11AC 0xA2C +#define ODM_REG_CCK_FA_11AC 0xA5C +/*PAGE C*/ +#define ODM_REG_IGI_A_11AC 0xC50 +/*PAGE E*/ +#define ODM_REG_IGI_B_11AC 0xE50 +/*PAGE F*/ +#define ODM_REG_OFDM_FA_11AC 0xF48 + +/* 2 MAC REG LIST */ + +/* DIG Related */ +#define ODM_BIT_IGI_11AC 0xFFFFFFFF +#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT16 +#define ODM_BIT_BB_RX_PATH_11AC 0xF + +enum AGGRE_SIZE { + HT_AGG_SIZE_8K = 0, + HT_AGG_SIZE_16K = 1, + HT_AGG_SIZE_32K = 2, + HT_AGG_SIZE_64K = 3, + VHT_AGG_SIZE_128K = 4, + VHT_AGG_SIZE_256K = 5, + VHT_AGG_SIZE_512K = 6, + VHT_AGG_SIZE_1024K = 7, +}; + +#define REG_AMPDU_MAX_LENGTH_8812 0x0458 + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c new file mode 100644 index 000000000..e339f2383 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c @@ -0,0 +1,440 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl8821ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 3); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 3); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 1); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_80: + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 0); + rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 0); + break; + default: + pr_err("unknown bandwidth: %#X\n", bandwidth); + break; + } +} + +void rtl8821ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + u8 direction; + u32 pwrtrac_value; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; + idx1 <= RF90_PATH_B; + idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); + tx_agc[RF90_PATH_A] += tmpval; + + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *)(&tx_agc[idx1]); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + rtl8821ae_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + if (direction == 1) { + tx_agc[0] += pwrtrac_value; + tx_agc[1] += pwrtrac_value; + } else if (direction == 2) { + tx_agc[0] -= pwrtrac_value; + tx_agc[1] -= pwrtrac_value; + } + tmpval = tx_agc[RF90_PATH_A]; + rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKDWORD, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 1~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK11_CCK1); + + tmpval = tx_agc[RF90_PATH_B]; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKDWORD, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_CCK1); +} + +static void rtl8821ae_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u32 powerbase0, powerbase1; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerbase0 = ppowerlevel_ofdm[i]; + + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + powerlevel[i] = ppowerlevel_bw20[i]; + else + powerlevel[i] = ppowerlevel_bw40[i]; + + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | + (powerbase1 << 16) | (powerbase1 << 8) | powerbase1; + + *(mcsbase + i) = powerbase1; + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + " [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); + } +} + +static void get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4], pwr_diff = 0, customer_pwr_diff; + u32 writeval, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) { + chnlgroup = 0; + } else { + if (channel < 3) + chnlgroup = 0; + else if (channel < 6) + chnlgroup = 1; + else if (channel < 9) + chnlgroup = 2; + else if (channel < 12) + chnlgroup = 3; + else if (channel < 14) + chnlgroup = 4; + else if (channel == 14) + chnlgroup = 5; + } + + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + + break; + case 2: + writeval = + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + case 3: + chnlgroup = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 40MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "customer's limit, 20MHz rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); + } + + if (index < 2) + pwr_diff = rtlefuse->txpwr_legacyhtdiff[rf][channel-1]; + else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) + pwr_diff = + rtlefuse->txpwr_ht20diff[rf][channel-1]; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) + customer_pwr_diff = + rtlefuse->pwrgroup_ht40[rf][channel-1]; + else + customer_pwr_diff = + rtlefuse->pwrgroup_ht20[rf][channel-1]; + + if (pwr_diff > customer_pwr_diff) + pwr_diff = 0; + else + pwr_diff = customer_pwr_diff - pwr_diff; + + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] & + (0x7f << (i * 8))) >> (i * 8)); + + if (pwr_diff_limit[i] > pwr_diff) + pwr_diff_limit[i] = pwr_diff; + } + + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit); + + writeval = customer_limit + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Customer, writeval rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + default: + chnlgroup = 0; + writeval = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval); + break; + } + + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeval = writeval - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeval = writeval - 0x0c0c0c0c; + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl8821ae_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regoffset_a[6] = { + RTXAGC_A_OFDM18_OFDM6, RTXAGC_A_OFDM54_OFDM24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_OFDM18_OFDM6, RTXAGC_B_OFDM54_OFDM24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = pvalue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeval & (0x7f << + (i * 8))) >> (i * 8)); + + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Set 0x%x = %08x\n", regoffset, writeval); + } +} + +void rtl8821ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, + u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + u8 direction; + u32 pwrtrac_value; + + rtl8821ae_phy_get_power_base(hw, ppowerlevel_ofdm, + ppowerlevel_bw20, + ppowerlevel_bw40, + channel, + &powerbase0[0], + &powerbase1[0]); + + rtl8821ae_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + + for (index = 0; index < 6; index++) { + get_txpower_writeval_by_regulatory(hw, channel, index, + &powerbase0[0], + &powerbase1[0], + &writeval[0]); + if (direction == 1) { + writeval[0] += pwrtrac_value; + writeval[1] += pwrtrac_value; + } else if (direction == 2) { + writeval[0] -= pwrtrac_value; + writeval[1] -= pwrtrac_value; + } + _rtl8821ae_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl8821ae_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return _rtl8821ae_phy_rf6052_config_parafile(hw); +} + +static bool _rtl8821ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 rfpath; + bool rtstatus = true; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + switch (rfpath) { + case RF90_PATH_A: { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtstatus = + rtl8812ae_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + else + rtstatus = + rtl8821ae_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + } + case RF90_PATH_B: + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) + rtstatus = + rtl8812ae_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + else + rtstatus = + rtl8821ae_phy_config_rf_with_headerfile(hw, + (enum radio_path)rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + if (!rtstatus) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Radio[%d] Fail!!\n", rfpath); + return false; + } + } + + /*put arrays in dm.c*/ + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); + return rtstatus; +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h new file mode 100644 index 000000000..6e3c8bfb2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_RF_H__ +#define __RTL8821AE_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F + +void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +void rtl8821ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl8821ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel_ofdm, + u8 *ppowerlevel_bw20, + u8 *ppowerlevel_bw40, + u8 channel); +bool rtl8821ae_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c new file mode 100644 index 000000000..1557d32ef --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "fw.h" +#include "trx.h" +#include "led.h" +#include "table.h" +#include "../btcoexist/rtl_btc.h" + +#include +#include + +static void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /** + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8192CE:3 RTL8192E:2 + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /** + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /** + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +/*InitializeVariables8812E*/ +static int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + char *fw_name, *wowlan_fw_name; + + rtl8821ae_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = false; + rtlpriv->dm.thermalvalue = 0; + rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25); + + mac->ht_enable = true; + mac->ht_cur_stbc = 0; + mac->ht_stbc_cap = 0; + mac->vht_cur_ldpc = 0; + mac->vht_ldpc_cap = 0; + mac->vht_cur_stbc = 0; + mac->vht_stbc_cap = 0; + + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + /*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/ + rtlpriv->rtlhal.bandset = BAND_ON_BOTH; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_NONQOS_VHT | + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | + /*This bit controls the PS-Poll packet filter.*/ + RCR_ADF | + RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = + (u32)(IMR_PSTIMEOUT | + IMR_GTINT3 | + IMR_HSISR_IND_ON_INT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + + rtlpci->irq_mask[1] = + (u32)(IMR_RXFOVW | + IMR_TXFOVW | + 0); + rtlpci->sys_irq_mask = (u32)(HSIMR_PDN_INT_EN | + HSIMR_RON_INT_EN | + 0); + /* for WOWLAN */ + rtlpriv->psc.wo_wlan_mode = WAKE_ON_MAGIC_PACKET | + WAKE_ON_PATTERN_MATCH; + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 2; + rtlpriv->psc.reg_max_lps_awakeintvl = 2; + + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl8821ae_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + pr_err("Can't alloc buffer for fw.\n"); + return 1; + } + rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.wowlan_firmware) { + pr_err("Can't alloc buffer for wowlan fw.\n"); + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + return 1; + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + fw_name = "rtlwifi/rtl8812aefw.bin"; + wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin"; + } else { + fw_name = "rtlwifi/rtl8821aefw_29.bin"; + wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin"; + } + + rtlpriv->max_fw_size = 0x8000; + /*load normal firmware*/ + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { + pr_err("Failed to request normal firmware!\n"); + vfree(rtlpriv->rtlhal.wowlan_firmware); + vfree(rtlpriv->rtlhal.pfirmware); + return 1; + } + /*load wowlan firmware*/ + pr_info("Using firmware %s\n", wowlan_fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, + wowlan_fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_wowlan_fw_cb); + if (err) { + pr_err("Failed to request wowlan firmware!\n"); + vfree(rtlpriv->rtlhal.wowlan_firmware); + vfree(rtlpriv->rtlhal.pfirmware); + return 1; + } + return 0; +} + +static void rtl8821ae_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1) + if (rtlpriv->rtlhal.wowlan_firmware) { + vfree(rtlpriv->rtlhal.wowlan_firmware); + rtlpriv->rtlhal.wowlan_firmware = NULL; + } +#endif +} + +/* get bt coexist status */ +static bool rtl8821ae_get_btc_status(void) +{ + return true; +} + +static const struct rtl_hal_ops rtl8821ae_hal_ops = { + .init_sw_vars = rtl8821ae_init_sw_vars, + .deinit_sw_vars = rtl8821ae_deinit_sw_vars, + .read_eeprom_info = rtl8821ae_read_eeprom_info, + .interrupt_recognized = rtl8821ae_interrupt_recognized, + .hw_init = rtl8821ae_hw_init, + .hw_disable = rtl8821ae_card_disable, + .hw_suspend = rtl8821ae_suspend, + .hw_resume = rtl8821ae_resume, + .enable_interrupt = rtl8821ae_enable_interrupt, + .disable_interrupt = rtl8821ae_disable_interrupt, + .set_network_type = rtl8821ae_set_network_type, + .set_chk_bssid = rtl8821ae_set_check_bssid, + .set_qos = rtl8821ae_set_qos, + .set_bcn_reg = rtl8821ae_set_beacon_related_registers, + .set_bcn_intv = rtl8821ae_set_beacon_interval, + .update_interrupt_mask = rtl8821ae_update_interrupt_mask, + .get_hw_reg = rtl8821ae_get_hw_reg, + .set_hw_reg = rtl8821ae_set_hw_reg, + .update_rate_tbl = rtl8821ae_update_hal_rate_tbl, + .fill_tx_desc = rtl8821ae_tx_fill_desc, + .fill_tx_cmddesc = rtl8821ae_tx_fill_cmddesc, + .query_rx_desc = rtl8821ae_rx_query_desc, + .set_channel_access = rtl8821ae_update_channel_access_setting, + .radio_onoff_checking = rtl8821ae_gpio_radio_on_off_checking, + .set_bw_mode = rtl8821ae_phy_set_bw_mode, + .switch_channel = rtl8821ae_phy_sw_chnl, + .dm_watchdog = rtl8821ae_dm_watchdog, + .scan_operation_backup = rtl8821ae_phy_scan_operation_backup, + .set_rf_power_state = rtl8821ae_phy_set_rf_power_state, + .led_control = rtl8821ae_led_control, + .set_desc = rtl8821ae_set_desc, + .get_desc = rtl8821ae_get_desc, + .is_tx_desc_closed = rtl8821ae_is_tx_desc_closed, + .tx_polling = rtl8821ae_tx_polling, + .enable_hw_sec = rtl8821ae_enable_hw_security_config, + .set_key = rtl8821ae_set_key, + .get_bbreg = rtl8821ae_phy_query_bb_reg, + .set_bbreg = rtl8821ae_phy_set_bb_reg, + .get_rfreg = rtl8821ae_phy_query_rf_reg, + .set_rfreg = rtl8821ae_phy_set_rf_reg, + .fill_h2c_cmd = rtl8821ae_fill_h2c_cmd, + .get_btc_status = rtl8821ae_get_btc_status, + .c2h_ra_report_handler = rtl8821ae_c2h_ra_report_handler, + .add_wowlan_pattern = rtl8821ae_add_wowlan_pattern, +}; + +static struct rtl_mod_params rtl8821ae_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .msi_support = true, + .aspm_support = 1, + .int_clear = true, + .debug_level = 0, + .debug_mask = 0, + .disable_watchdog = 0, +}; + +static const struct rtl_hal_cfg rtl8821ae_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8821ae_pci", + .alt_fw_name = "rtlwifi/rtl8821aefw.bin", + .ops = &rtl8821ae_hal_ops, + .mod_params = &rtl8821ae_mod_params, + .spec_ver = RTL_SPEC_SUPPORT_VHT, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR, + .maps[MAC_HIMRE] = REG_HIMRE, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, +/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/ + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, +/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/ +/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/ + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, + + /*VHT hightest rate*/ + .maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7, + .maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8, + .maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9, + .maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7, + .maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8, + .maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9, +}; + +static const struct pci_device_id rtl8821ae_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8812, rtl8821ae_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8821, rtl8821ae_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8821ae_pci_ids); + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8821aefw_29.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8821aefw_wowlan.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8812aefw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8812aefw_wowlan.bin"); + +module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8821ae_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl8821ae_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8821ae_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444); +module_param_named(aspm, rtl8821ae_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog, + bool, 0444); +module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); +MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8821ae_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8821ae_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8821ae_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c new file mode 100644 index 000000000..fcaaf664c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c @@ -0,0 +1,4033 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include +#include "table.h" +u32 RTL8812AE_PHY_REG_ARRAY[] = { + 0x800, 0x8020D010, + 0x804, 0x080112E0, + 0x808, 0x0E028233, + 0x80C, 0x12131113, + 0x810, 0x20101263, + 0x814, 0x020C3D10, + 0x818, 0x03A00385, + 0x820, 0x00000000, + 0x824, 0x00030FE0, + 0x828, 0x00000000, + 0x82C, 0x002083DD, + 0x830, 0x2EAAEEB8, + 0x834, 0x0037A706, + 0x838, 0x06C89B44, + 0x83C, 0x0000095B, + 0x840, 0xC0000001, + 0x844, 0x40003CDE, + 0x848, 0x6210FF8B, + 0x84C, 0x6CFDFFB8, + 0x850, 0x28874706, + 0x854, 0x0001520C, + 0x858, 0x8060E000, + 0x85C, 0x74210168, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x338C2878, + 0x870, 0x03333333, + 0x874, 0x31602C2E, + 0x878, 0x00003152, + 0x87C, 0x000FC000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA202033E, + 0x8AC, 0x0FF0FA0A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0x6C0057FF, + 0x8BC, 0x4CA520A3, + 0x8C0, 0x27F00020, + 0x8C4, 0x00000000, + 0x8C8, 0x00012D69, + 0x8CC, 0x08248492, + 0x8D0, 0x0000B800, + 0x8DC, 0x00000000, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8F8, 0x400002C0, + 0x8FC, 0x00000000, + 0x900, 0x00000701, + 0x90C, 0x00000000, + 0x910, 0x0000FC00, + 0x914, 0x00000404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x00000004, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00080080, + 0x9A8, 0x00000000, + 0x9AC, 0x00000000, + 0x9B0, 0x81081008, + 0x9B4, 0x00000000, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E4, 0x00000003, + 0x9E8, 0x000002D5, + 0xA00, 0x00D047C8, + 0xA04, 0x01FF000C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7F000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000008, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B2, + 0xA84, 0x001F8C80, + 0XB00, 0x03100000, + 0XB04, 0x0000B000, + 0XB08, 0xAE0201EB, + 0XB0C, 0x01003207, + 0XB10, 0x00009807, + 0XB14, 0x01000000, + 0XB18, 0x00000002, + 0XB1C, 0x00000002, + 0XB20, 0x0000001F, + 0XB24, 0x03020100, + 0XB28, 0x07060504, + 0XB2C, 0x0B0A0908, + 0XB30, 0x0F0E0D0C, + 0XB34, 0x13121110, + 0XB38, 0x17161514, + 0XB3C, 0x0000003A, + 0XB40, 0x00000000, + 0XB44, 0x00000000, + 0XB48, 0x13000032, + 0XB4C, 0x48080000, + 0XB50, 0x00000000, + 0XB54, 0x00000000, + 0XB58, 0x00000000, + 0XB5C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000003, + 0xC20, 0x12121212, + 0xC24, 0x12121212, + 0xC28, 0x12121212, + 0xC2C, 0x12121212, + 0xC30, 0x12121212, + 0xC34, 0x12121212, + 0xC38, 0x12121212, + 0xC3C, 0x12121212, + 0xC40, 0x12121212, + 0xC44, 0x12121212, + 0xC48, 0x12121212, + 0xC4C, 0x12121212, + 0xC50, 0x00000020, + 0xC54, 0x0008121C, + 0xC58, 0x30000C1C, + 0xC5C, 0x00000058, + 0xC60, 0x34344443, + 0xC64, 0x07003333, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0xA0000000, 0x00000000, + 0xC68, 0x59799979, + 0XB0000000, 0x00000000, + 0xC6C, 0x59795979, + 0xC70, 0x19795979, + 0xC74, 0x19795979, + 0xC78, 0x19791979, + 0xC7C, 0x19791979, + 0xC80, 0x19791979, + 0xC84, 0x19791979, + 0xC94, 0x0100005C, + 0xC98, 0x00000000, + 0xC9C, 0x00000000, + 0xCA0, 0x00000029, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCB0, 0x77547777, + 0xCB4, 0x00000077, + 0xCB8, 0x00508242, + 0xE00, 0x00000007, + 0xE04, 0x00042020, + 0xE08, 0x80410231, + 0xE0C, 0x00000000, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE1C, 0x40000003, + 0xE20, 0x12121212, + 0xE24, 0x12121212, + 0xE28, 0x12121212, + 0xE2C, 0x12121212, + 0xE30, 0x12121212, + 0xE34, 0x12121212, + 0xE38, 0x12121212, + 0xE3C, 0x12121212, + 0xE40, 0x12121212, + 0xE44, 0x12121212, + 0xE48, 0x12121212, + 0xE4C, 0x12121212, + 0xE50, 0x00000020, + 0xE54, 0x0008121C, + 0xE58, 0x30000C1C, + 0xE5C, 0x00000058, + 0xE60, 0x34344443, + 0xE64, 0x07003333, + 0xE68, 0x59791979, + 0xE6C, 0x59795979, + 0xE70, 0x19795979, + 0xE74, 0x19795979, + 0xE78, 0x19791979, + 0xE7C, 0x19791979, + 0xE80, 0x19791979, + 0xE84, 0x19791979, + 0xE94, 0x0100005C, + 0xE98, 0x00000000, + 0xE9C, 0x00000000, + 0xEA0, 0x00000029, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEB0, 0x77547777, + 0xEB4, 0x00000077, + 0xEB8, 0x00508242, +}; + +u32 RTL8812AE_PHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_PHY_REG_ARRAY); + +u32 RTL8821AE_PHY_REG_ARRAY[] = { + 0x800, 0x0020D090, + 0x804, 0x080112E0, + 0x808, 0x0E028211, + 0x80C, 0x92131111, + 0x810, 0x20101261, + 0x814, 0x020C3D10, + 0x818, 0x03A00385, + 0x820, 0x00000000, + 0x824, 0x00030FE0, + 0x828, 0x00000000, + 0x82C, 0x002081DD, + 0x830, 0x2AAAEEC8, + 0x834, 0x0037A706, + 0x838, 0x06489B44, + 0x83C, 0x0000095B, + 0x840, 0xC0000001, + 0x844, 0x40003CDE, + 0x848, 0x62103F8B, + 0x84C, 0x6CFDFFB8, + 0x850, 0x28874706, + 0x854, 0x0001520C, + 0x858, 0x8060E000, + 0x85C, 0x74210168, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x888C2878, + 0x870, 0x08888888, + 0x874, 0x31612C2E, + 0x878, 0x00000152, + 0x87C, 0x000FD000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA2000338, + 0x8AC, 0x0FF0FA0A, + 0x8B4, 0x000FC080, + 0x8B8, 0x6C10D7FF, + 0x8BC, 0x0CA52090, + 0x8C0, 0x1BF00020, + 0x8C4, 0x00000000, + 0x8C8, 0x00013169, + 0x8CC, 0x08248492, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8F8, 0x400002C0, + 0x8FC, 0x00000000, + 0x900, 0x00000700, + 0x90C, 0x00000000, + 0x910, 0x0000FC00, + 0x914, 0x00000404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x00000004, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x974, 0x000003FF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00480080, + 0x9A8, 0x00000000, + 0x9AC, 0x00000000, + 0x9B0, 0x81081008, + 0x9B4, 0x01081008, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00005D00, + 0x9E4, 0x00000003, + 0x9E8, 0x00000001, + 0xA00, 0x00D047C8, + 0xA04, 0x01FF800C, + 0xA08, 0x8C8A8300, + 0xA0C, 0x2E68000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000008, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x21805490, + 0xA84, 0x001F0000, + 0XB00, 0x03100040, + 0XB04, 0x0000B000, + 0XB08, 0xAE0201EB, + 0XB0C, 0x01003207, + 0XB10, 0x00009807, + 0XB14, 0x01000000, + 0XB18, 0x00000002, + 0XB1C, 0x00000002, + 0XB20, 0x0000001F, + 0XB24, 0x03020100, + 0XB28, 0x07060504, + 0XB2C, 0x0B0A0908, + 0XB30, 0x0F0E0D0C, + 0XB34, 0x13121110, + 0XB38, 0x17161514, + 0XB3C, 0x0000003A, + 0XB40, 0x00000000, + 0XB44, 0x00000000, + 0XB48, 0x13000032, + 0XB4C, 0x48080000, + 0XB50, 0x00000000, + 0XB54, 0x00000000, + 0XB58, 0x00000000, + 0XB5C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000003, + 0xC20, 0x2C2C2C2C, + 0xC24, 0x30303030, + 0xC28, 0x30303030, + 0xC2C, 0x2C2C2C2C, + 0xC30, 0x2C2C2C2C, + 0xC34, 0x2C2C2C2C, + 0xC38, 0x2C2C2C2C, + 0xC3C, 0x2A2A2A2A, + 0xC40, 0x2A2A2A2A, + 0xC44, 0x2A2A2A2A, + 0xC48, 0x2A2A2A2A, + 0xC4C, 0x2A2A2A2A, + 0xC50, 0x00000020, + 0xC54, 0x001C1208, + 0xC58, 0x30000C1C, + 0xC5C, 0x00000058, + 0xC60, 0x34344443, + 0xC64, 0x07003333, + 0xC68, 0x19791979, + 0xC6C, 0x19791979, + 0xC70, 0x19791979, + 0xC74, 0x19791979, + 0xC78, 0x19791979, + 0xC7C, 0x19791979, + 0xC80, 0x19791979, + 0xC84, 0x19791979, + 0xC94, 0x0100005C, + 0xC98, 0x00000000, + 0xC9C, 0x00000000, + 0xCA0, 0x00000029, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCB0, 0x77775747, + 0xCB4, 0x10000077, + 0xCB8, 0x00508240, +}; + +u32 RTL8821AE_PHY_REG_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_PHY_REG_ARRAY); + +u32 RTL8812AE_PHY_REG_ARRAY_PG[] = { + 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, + 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, + 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, + 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, + 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, + 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, + 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, + 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, + 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, + 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, + 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, + 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, + 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, + 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, + 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, + 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, + 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, + 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, + 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, + 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, + 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, + 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, + 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, + 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, + 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, + 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, + 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, + 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, + 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, + 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, + 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, + 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, + 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, + 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, + 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, + 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, + 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, + 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, + 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, + 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, + 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, + 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, + 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, + 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628 +}; + +u32 RTL8812AE_PHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8812AE_PHY_REG_ARRAY_PG); + +u32 RTL8821AE_PHY_REG_ARRAY_PG[] = { + 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, + 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, + 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, + 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, + 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, + 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, + 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, + 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, + 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, + 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, + 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, + 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, + 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022 +}; + +u32 RTL8821AE_PHY_REG_ARRAY_PGLEN = ARRAY_SIZE(RTL8821AE_PHY_REG_ARRAY_PG); + +u32 RTL8812AE_RADIOA_ARRAY[] = { + 0x000, 0x00010000, + 0x018, 0x0001712A, + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x01E, 0x00080000, + 0x089, 0x00000080, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0xA0000000, 0x00000000, + 0x086, 0x00014B38, + 0XB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x08B, 0x00080180, + 0xA0000000, 0x00000000, + 0x08B, 0x00087180, + 0XB0000000, 0x00000000, + 0x0B1, 0x0001FC1A, + 0x0B3, 0x000F0810, + 0x0B4, 0x0001A78D, + 0x0BA, 0x00086180, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xA0000000, 0x00000000, + 0x03B, 0x00038A58, + 0x03B, 0x00037A58, + 0x03B, 0x0002A590, + 0x03B, 0x00027A50, + 0x03B, 0x00018248, + 0x03B, 0x00010240, + 0x03B, 0x00008240, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A4EE, + 0x034, 0x00009076, + 0x034, 0x00008073, + 0x034, 0x00007070, + 0x034, 0x0000606D, + 0x034, 0x0000506A, + 0x034, 0x00004049, + 0x034, 0x00003046, + 0x034, 0x00002028, + 0x034, 0x00001025, + 0x034, 0x00000022, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF4, + 0x034, 0x00009DF1, + 0x034, 0x00008DEE, + 0x034, 0x00007DEB, + 0x034, 0x00006DE8, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146B, + 0x034, 0x0000006D, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x0EF, 0x00000002, + 0x008, 0x00008400, + 0x018, 0x0001712A, + 0x0EF, 0x00001000, + 0x03A, 0x00000080, + 0x03B, 0x0003A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0003202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0002B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00023070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0001B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00012085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0000A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00002080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x0007A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0007202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0006B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00063070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0005B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00052085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0004A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00042080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x000BA02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x000B202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x000AB064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x000A3070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0009B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00092085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0008A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00082080, + 0x03C, 0x00010000, + 0x0EF, 0x00001100, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x00046050, + 0x034, 0x0004504D, + 0x034, 0x0004404A, + 0x034, 0x00043047, + 0x034, 0x0004200A, + 0x034, 0x00041007, + 0x034, 0x00040004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x0004604D, + 0x034, 0x0004504A, + 0x034, 0x00044047, + 0x034, 0x00043044, + 0x034, 0x00042007, + 0x034, 0x00041004, + 0x034, 0x00040001, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045DE6, + 0x034, 0x00044DE3, + 0x034, 0x000438C8, + 0x034, 0x000428C5, + 0x034, 0x000418C2, + 0x034, 0x000408C0, + 0XB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B2, + 0x034, 0x000290AF, + 0x034, 0x00028070, + 0x034, 0x0002706D, + 0x034, 0x00026050, + 0x034, 0x0002504D, + 0x034, 0x0002404A, + 0x034, 0x00023047, + 0x034, 0x0002200A, + 0x034, 0x00021007, + 0x034, 0x00020004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B4, + 0x034, 0x000290B1, + 0x034, 0x00028072, + 0x034, 0x0002706F, + 0x034, 0x0002604F, + 0x034, 0x0002504C, + 0x034, 0x00024049, + 0x034, 0x00023046, + 0x034, 0x00022009, + 0x034, 0x00021006, + 0x034, 0x00020003, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF5, + 0x034, 0x00029DF2, + 0x034, 0x00028DEF, + 0x034, 0x00027DEC, + 0x034, 0x00026DE9, + 0x034, 0x00025DE6, + 0x034, 0x00024DE3, + 0x034, 0x000238C8, + 0x034, 0x000228C5, + 0x034, 0x000218C2, + 0x034, 0x000208C0, + 0XB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x00006050, + 0x034, 0x0000504D, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x0000200A, + 0x034, 0x00001007, + 0x034, 0x00000004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x0000604D, + 0x034, 0x0000504A, + 0x034, 0x00004047, + 0x034, 0x00003044, + 0x034, 0x00002007, + 0x034, 0x00001004, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009DF7, + 0x034, 0x00008DF4, + 0x034, 0x00007DF1, + 0x034, 0x00006DEE, + 0x034, 0x00005DEB, + 0x034, 0x00004DE8, + 0x034, 0x000038CC, + 0x034, 0x000028C9, + 0x034, 0x000018C6, + 0x034, 0x000008C3, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001D4, + 0x035, 0x000081D4, + 0x035, 0x000101D4, + 0x035, 0x000201B4, + 0x035, 0x000281B4, + 0x035, 0x000301B4, + 0x035, 0x000401B4, + 0x035, 0x000481B4, + 0x035, 0x000501B4, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001D4, + 0x035, 0x000081D4, + 0x035, 0x000101D4, + 0x035, 0x000201B4, + 0x035, 0x000281B4, + 0x035, 0x000301B4, + 0x035, 0x000401B4, + 0x035, 0x000481B4, + 0x035, 0x000501B4, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x00000188, + 0x035, 0x00008147, + 0x035, 0x00010147, + 0x035, 0x000201D7, + 0x035, 0x000281D7, + 0x035, 0x000301D7, + 0x035, 0x000401D8, + 0x035, 0x000481D8, + 0x035, 0x000501D8, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00004BFB, + 0x036, 0x0000CBFB, + 0x036, 0x00014BFB, + 0x036, 0x0001CBFB, + 0x036, 0x00024F4B, + 0x036, 0x0002CF4B, + 0x036, 0x00034F4B, + 0x036, 0x0003CF4B, + 0x036, 0x00044F4B, + 0x036, 0x0004CF4B, + 0x036, 0x00054F4B, + 0x036, 0x0005CF4B, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00004BFB, + 0x036, 0x0000CBFB, + 0x036, 0x00014BFB, + 0x036, 0x0001CBFB, + 0x036, 0x00024F4B, + 0x036, 0x0002CF4B, + 0x036, 0x00034F4B, + 0x036, 0x0003CF4B, + 0x036, 0x00044F4B, + 0x036, 0x0004CF4B, + 0x036, 0x00054F4B, + 0x036, 0x0005CF4B, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00084EB4, + 0x036, 0x0008CC35, + 0x036, 0x00094C35, + 0x036, 0x0009CC35, + 0x036, 0x000A4C35, + 0x036, 0x000ACC35, + 0x036, 0x000B4C35, + 0x036, 0x000BCC35, + 0x036, 0x000C4C34, + 0x036, 0x000CCC35, + 0x036, 0x000D4C35, + 0x036, 0x000DCC35, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000002CC, + 0x03C, 0x00000522, + 0x03C, 0x00000902, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x03C, 0x000002CC, + 0x03C, 0x00000522, + 0x03C, 0x00000902, + 0xA0000000, 0x00000000, + 0x03C, 0x000002A8, + 0x03C, 0x000005A2, + 0x03C, 0x00000880, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x0DF, 0x00000080, + 0x01F, 0x00000064, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000FDD43, + 0x062, 0x00038F4B, + 0x063, 0x00032117, + 0x064, 0x000194AC, + 0x065, 0x000931D1, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x061, 0x000FDD43, + 0x062, 0x00038F4B, + 0x063, 0x00032117, + 0x064, 0x000194AC, + 0x065, 0x000931D2, + 0xA0000000, 0x00000000, + 0x061, 0x000E5D53, + 0x062, 0x00038FCD, + 0x063, 0x000114EB, + 0x064, 0x000196AC, + 0x065, 0x000911D7, + 0XB0000000, 0x00000000, + 0x008, 0x00008400, + 0x01C, 0x000739D2, + 0x0B4, 0x0001E78D, + 0x018, 0x0001F12A, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0B4, 0x0001A78D, + 0x018, 0x0001712A, +}; + +u32 RTL8812AE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_RADIOA_ARRAY); + +u32 RTL8812AE_RADIOB_ARRAY[] = { + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x089, 0x00000080, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0xA0000000, 0x00000000, + 0x086, 0x00014B38, + 0XB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x08B, 0x00080180, + 0xA0000000, 0x00000000, + 0x08B, 0x00087180, + 0XB0000000, 0x00000000, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xA0000000, 0x00000000, + 0x03B, 0x00038A58, + 0x03B, 0x00037A58, + 0x03B, 0x0002A590, + 0x03B, 0x00027A50, + 0x03B, 0x00018248, + 0x03B, 0x00010240, + 0x03B, 0x00008240, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A4EE, + 0x034, 0x00009076, + 0x034, 0x00008073, + 0x034, 0x00007070, + 0x034, 0x0000606D, + 0x034, 0x0000506A, + 0x034, 0x00004049, + 0x034, 0x00003046, + 0x034, 0x00002028, + 0x034, 0x00001025, + 0x034, 0x00000022, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF4, + 0x034, 0x00009DF1, + 0x034, 0x00008DEE, + 0x034, 0x00007DEB, + 0x034, 0x00006DE8, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146B, + 0x034, 0x0000006D, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x0EF, 0x00000002, + 0x008, 0x00008400, + 0x018, 0x0001712A, + 0x0EF, 0x00001000, + 0x03A, 0x00000080, + 0x03B, 0x0003A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0003202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0002B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00023070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0001B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00012085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0000A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00002080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x0007A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0007202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0006B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00063070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0005B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00052085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0004A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00042080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x000BA02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x000B202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x000AB064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x000A3070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0009B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00092085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0008A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00082080, + 0x03C, 0x00010000, + 0x0EF, 0x00001100, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x00046050, + 0x034, 0x0004504D, + 0x034, 0x0004404A, + 0x034, 0x00043047, + 0x034, 0x0004200A, + 0x034, 0x00041007, + 0x034, 0x00040004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B1, + 0x034, 0x000490AE, + 0x034, 0x0004806F, + 0x034, 0x0004706C, + 0x034, 0x0004604C, + 0x034, 0x00045049, + 0x034, 0x00044046, + 0x034, 0x00043043, + 0x034, 0x00042006, + 0x034, 0x00041003, + 0x034, 0x00040000, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045DE6, + 0x034, 0x00044DE3, + 0x034, 0x000438C8, + 0x034, 0x000428C5, + 0x034, 0x000418C2, + 0x034, 0x000408C0, + 0XB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B2, + 0x034, 0x000290AF, + 0x034, 0x00028070, + 0x034, 0x0002706D, + 0x034, 0x00026050, + 0x034, 0x0002504D, + 0x034, 0x0002404A, + 0x034, 0x00023047, + 0x034, 0x0002200A, + 0x034, 0x00021007, + 0x034, 0x00020004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B3, + 0x034, 0x000290B0, + 0x034, 0x00028071, + 0x034, 0x0002706E, + 0x034, 0x0002604E, + 0x034, 0x0002504B, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022008, + 0x034, 0x00021005, + 0x034, 0x00020002, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF5, + 0x034, 0x00029DF2, + 0x034, 0x00028DEF, + 0x034, 0x00027DEC, + 0x034, 0x00026DE9, + 0x034, 0x00025DE6, + 0x034, 0x00024DE3, + 0x034, 0x000238C8, + 0x034, 0x000228C5, + 0x034, 0x000218C2, + 0x034, 0x000208C0, + 0XB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x00006050, + 0x034, 0x0000504D, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x0000200A, + 0x034, 0x00001007, + 0x034, 0x00000004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B3, + 0x034, 0x000090B0, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x0000604D, + 0x034, 0x0000504A, + 0x034, 0x00004047, + 0x034, 0x00003044, + 0x034, 0x00002007, + 0x034, 0x00001004, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009DF7, + 0x034, 0x00008DF4, + 0x034, 0x00007DF1, + 0x034, 0x00006DEE, + 0x034, 0x00005DEB, + 0x034, 0x00004DE8, + 0x034, 0x000038CC, + 0x034, 0x000028C9, + 0x034, 0x000018C6, + 0x034, 0x000008C3, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001C5, + 0x035, 0x000081C5, + 0x035, 0x000101C5, + 0x035, 0x00020174, + 0x035, 0x00028174, + 0x035, 0x00030174, + 0x035, 0x00040185, + 0x035, 0x00048185, + 0x035, 0x00050185, + 0x0EF, 0x00000000, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001C5, + 0x035, 0x000081C5, + 0x035, 0x000101C5, + 0x035, 0x00020174, + 0x035, 0x00028174, + 0x035, 0x00030174, + 0x035, 0x00040185, + 0x035, 0x00048185, + 0x035, 0x00050185, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x00000188, + 0x035, 0x00008147, + 0x035, 0x00010147, + 0x035, 0x000201D7, + 0x035, 0x000281D7, + 0x035, 0x000301D7, + 0x035, 0x000401D8, + 0x035, 0x000481D8, + 0x035, 0x000501D8, + 0x0EF, 0x00000000, + 0XB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00005B8B, + 0x036, 0x0000DB8B, + 0x036, 0x00015B8B, + 0x036, 0x0001DB8B, + 0x036, 0x000262DB, + 0x036, 0x0002E2DB, + 0x036, 0x000362DB, + 0x036, 0x0003E2DB, + 0x036, 0x0004553B, + 0x036, 0x0004D53B, + 0x036, 0x0005553B, + 0x036, 0x0005D53B, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00005B8B, + 0x036, 0x0000DB8B, + 0x036, 0x00015B8B, + 0x036, 0x0001DB8B, + 0x036, 0x000262DB, + 0x036, 0x0002E2DB, + 0x036, 0x000362DB, + 0x036, 0x0003E2DB, + 0x036, 0x0004553B, + 0x036, 0x0004D53B, + 0x036, 0x0005553B, + 0x036, 0x0005D53B, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00084EB4, + 0x036, 0x0008CC35, + 0x036, 0x00094C35, + 0x036, 0x0009CC35, + 0x036, 0x000A4C35, + 0x036, 0x000ACC35, + 0x036, 0x000B4C35, + 0x036, 0x000BCC35, + 0x036, 0x000C4C34, + 0x036, 0x000CCC35, + 0x036, 0x000D4C35, + 0x036, 0x000DCC35, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000002DC, + 0x03C, 0x00000524, + 0x03C, 0x00000902, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x03C, 0x000002DC, + 0x03C, 0x00000524, + 0x03C, 0x00000902, + 0xA0000000, 0x00000000, + 0x03C, 0x000002A8, + 0x03C, 0x000005A2, + 0x03C, 0x00000880, + 0XB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x0DF, 0x00000080, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D1, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D2, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D1, + 0xA0000000, 0x00000000, + 0x061, 0x000E5D53, + 0x062, 0x00038FCD, + 0x063, 0x000114EB, + 0x064, 0x000196AC, + 0x065, 0x000911D7, + 0XB0000000, 0x00000000, + 0x008, 0x00008400, +}; + +u32 RTL8812AE_RADIOB_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_RADIOB_ARRAY); + +u32 RTL8821AE_RADIOA_ARRAY[] = { + 0x018, 0x0001712A, + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x000, 0x00010000, + 0x01E, 0x00080000, + 0x082, 0x00000830, + 0x083, 0x00021800, + 0x084, 0x00028000, + 0x085, 0x00048000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x0009483A, + 0xA0000000, 0x00000000, + 0x086, 0x00094838, + 0xB0000000, 0x00000000, + 0x087, 0x00044980, + 0x088, 0x00048000, + 0x089, 0x0000D480, + 0x08A, 0x00042240, + 0x08B, 0x000F0380, + 0x08C, 0x00090000, + 0x08D, 0x00022852, + 0x08E, 0x00065540, + 0x08F, 0x00088001, + 0x0EF, 0x00020000, + 0x03E, 0x00000380, + 0x03F, 0x00090018, + 0x03E, 0x00020380, + 0x03F, 0x000A0018, + 0x03E, 0x00040308, + 0x03F, 0x000A0018, + 0x03E, 0x00060018, + 0x03F, 0x000A0018, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x089, 0x00000080, + 0x08B, 0x00080180, + 0x0EF, 0x00001000, + 0x03A, 0x00000244, + 0x03B, 0x00038027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x00030113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x00028027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x00027027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0001F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00017F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00008027, + 0x03C, 0x000CA000, + 0x03A, 0x00000244, + 0x03B, 0x00078027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x00070113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x00068027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x00067027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0005F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00057F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00048027, + 0x03C, 0x000CA000, + 0x03A, 0x00000244, + 0x03B, 0x000B8027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x000B0113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x000A8027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x000A7027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0009F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00097F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00088027, + 0x03C, 0x000CA000, + 0x0EF, 0x00000000, + 0x0EF, 0x00001100, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0F3, + 0x034, 0x000490B1, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0F3, + 0x034, 0x000490B1, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF7, + 0x034, 0x00049DF3, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000480AE, + 0x034, 0x000470AB, + 0x034, 0x0004608B, + 0x034, 0x00045069, + 0x034, 0x00044048, + 0x034, 0x00043045, + 0x034, 0x00042026, + 0x034, 0x00041023, + 0x034, 0x00040002, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000480AE, + 0x034, 0x000470AB, + 0x034, 0x0004608B, + 0x034, 0x00045069, + 0x034, 0x00044048, + 0x034, 0x00043045, + 0x034, 0x00042026, + 0x034, 0x00041023, + 0x034, 0x00040002, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0xA0000000, 0x00000000, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045CCB, + 0x034, 0x0004488D, + 0x034, 0x0004348D, + 0x034, 0x0004248A, + 0x034, 0x0004108D, + 0x034, 0x0004008A, + 0xB0000000, 0x00000000, + 0x80000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002ADF4, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0F3, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0F3, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002ADF4, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF7, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF1, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000290F0, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000290F0, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF1, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0xA0000000, 0x00000000, + 0x034, 0x00029DF2, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000280AF, + 0x034, 0x000270AC, + 0x034, 0x0002608B, + 0x034, 0x00025069, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020002, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000280AF, + 0x034, 0x000270AC, + 0x034, 0x0002608B, + 0x034, 0x00025069, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020002, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0xA0000000, 0x00000000, + 0x034, 0x00028DEE, + 0x034, 0x00027DEB, + 0x034, 0x00026CCD, + 0x034, 0x00025CCA, + 0x034, 0x0002488C, + 0x034, 0x0002384C, + 0x034, 0x00022849, + 0x034, 0x00021449, + 0x034, 0x0002004D, + 0xB0000000, 0x00000000, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D7, + 0x034, 0x000090D3, + 0x034, 0x000080B1, + 0x034, 0x000070AE, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D7, + 0x034, 0x000090D3, + 0x034, 0x000080B1, + 0x034, 0x000070AE, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF7, + 0x034, 0x00009DF4, + 0x034, 0x00008DF1, + 0x034, 0x00007DEE, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000608D, + 0x034, 0x0000506B, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x00002044, + 0x034, 0x00001025, + 0x034, 0x00000004, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000608D, + 0x034, 0x0000506B, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x00002044, + 0x034, 0x00001025, + 0x034, 0x00000004, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0xA0000000, 0x00000000, + 0x034, 0x00006DCD, + 0x034, 0x00005CCD, + 0x034, 0x00004CCA, + 0x034, 0x0000388C, + 0x034, 0x00002888, + 0x034, 0x00001488, + 0x034, 0x00000486, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000145, + 0x035, 0x00008145, + 0x035, 0x00010145, + 0x035, 0x00020196, + 0x035, 0x00028196, + 0x035, 0x00030196, + 0x035, 0x000401C7, + 0x035, 0x000481C7, + 0x035, 0x000501C7, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0xA0000000, 0x00000000, + 0x035, 0x00000145, + 0x035, 0x00008145, + 0x035, 0x00010145, + 0x035, 0x00020196, + 0x035, 0x00028196, + 0x035, 0x00030196, + 0x035, 0x000401C7, + 0x035, 0x000481C7, + 0x035, 0x000501C7, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000056B3, + 0x036, 0x0000D6B3, + 0x036, 0x000156B3, + 0x036, 0x0001D6B3, + 0x036, 0x00026634, + 0x036, 0x0002E634, + 0x036, 0x00036634, + 0x036, 0x0003E634, + 0x036, 0x000467B4, + 0x036, 0x0004E7B4, + 0x036, 0x000567B4, + 0x036, 0x0005E7B4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0xA0000000, 0x00000000, + 0x036, 0x000056B3, + 0x036, 0x0000D6B3, + 0x036, 0x000156B3, + 0x036, 0x0001D6B3, + 0x036, 0x00026634, + 0x036, 0x0002E634, + 0x036, 0x00036634, + 0x036, 0x0003E634, + 0x036, 0x000467B4, + 0x036, 0x0004E7B4, + 0x036, 0x000567B4, + 0x036, 0x0005E7B4, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000022A, + 0x03C, 0x00000594, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0xA0000000, 0x00000000, + 0x03C, 0x0000022A, + 0x03C, 0x00000594, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000820, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000820, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0xA0000000, 0x00000000, + 0x03C, 0x00000900, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0xA0000000, 0x00000000, + 0x008, 0x00002000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x000000C0, + 0x01F, 0x00000064, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0xA0000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAD53, + 0x062, 0x00093BC4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0xA0000000, 0x00000000, + 0x061, 0x000EAD53, + 0x062, 0x00093BC4, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0xA0000000, 0x00000000, + 0x063, 0x000714E9, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C67C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0xA0000000, 0x00000000, + 0x064, 0x0001C67C, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093016, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093015, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093015, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093016, + 0xA0000000, 0x00000000, + 0x065, 0x00091016, + 0xB0000000, 0x00000000, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x03B, 0x0003824B, + 0x03B, 0x0003024B, + 0x03B, 0x0002844B, + 0x03B, 0x00020F4B, + 0x03B, 0x00018F4B, + 0x03B, 0x000104B2, + 0x03B, 0x00008049, + 0x03B, 0x00000148, + 0x03B, 0x0007824B, + 0x03B, 0x0007024B, + 0x03B, 0x0006824B, + 0x03B, 0x00060F4B, + 0x03B, 0x00058F4B, + 0x03B, 0x000504B2, + 0x03B, 0x00048049, + 0x03B, 0x00040148, + 0x0EF, 0x00000000, + 0x0EF, 0x00000100, + 0x034, 0x0000ADF3, + 0x034, 0x00009DF0, + 0x034, 0x00008D70, + 0x034, 0x00007D6D, + 0x034, 0x00006CEE, + 0x034, 0x00005CCC, + 0x034, 0x000044EC, + 0x034, 0x000034AC, + 0x034, 0x0000246D, + 0x034, 0x0000106F, + 0x034, 0x0000006C, + 0x0EF, 0x00000000, + 0x0ED, 0x00000010, + 0x044, 0x0000ADF2, + 0x044, 0x00009DEF, + 0x044, 0x00008DEC, + 0x044, 0x00007DE9, + 0x044, 0x00006CEC, + 0x044, 0x00005CE9, + 0x044, 0x000044EC, + 0x044, 0x000034E9, + 0x044, 0x0000246C, + 0x044, 0x00001469, + 0x044, 0x0000006C, + 0x0ED, 0x00000000, + 0x0ED, 0x00000001, + 0x040, 0x00038DA7, + 0x040, 0x000300C2, + 0x040, 0x000288E2, + 0x040, 0x000200B8, + 0x040, 0x000188A5, + 0x040, 0x00010FBC, + 0x040, 0x00008F71, + 0x040, 0x00000240, + 0x0ED, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000120, + 0x035, 0x00008120, + 0x035, 0x00010120, + 0x036, 0x00000085, + 0x036, 0x00008085, + 0x036, 0x00010085, + 0x036, 0x00018085, + 0x0EF, 0x00000000, + 0x051, 0x00000C31, + 0x052, 0x00000622, + 0x053, 0x000FC70B, + 0x054, 0x0000017E, + 0x056, 0x00051DF3, + 0x051, 0x00000C01, + 0x052, 0x000006D6, + 0x053, 0x000FC649, + 0x070, 0x00049661, + 0x071, 0x0007843E, + 0x072, 0x00000382, + 0x074, 0x00051400, + 0x035, 0x00000160, + 0x035, 0x00008160, + 0x035, 0x00010160, + 0x036, 0x00000124, + 0x036, 0x00008124, + 0x036, 0x00010124, + 0x036, 0x00018124, + 0x0ED, 0x0000000C, + 0x045, 0x00000140, + 0x045, 0x00008140, + 0x045, 0x00010140, + 0x046, 0x00000124, + 0x046, 0x00008124, + 0x046, 0x00010124, + 0x046, 0x00018124, + 0x0DF, 0x00000088, + 0x0B3, 0x000F0E18, + 0x0B4, 0x0001214C, + 0x0B7, 0x0003000C, + 0x01C, 0x000539D2, + 0x0C4, 0x000AFE00, + 0x018, 0x0001F12A, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x0001712A, + +}; + +u32 RTL8821AE_RADIOA_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_RADIOA_ARRAY); + +u32 RTL8812AE_MAC_REG_ARRAY[] = { + 0x010, 0x0000000C, + 0x80000200, 0x00000000, 0x40000000, 0x00000000, + 0x011, 0x00000066, + 0xA0000000, 0x00000000, + 0x011, 0x0000005A, + 0XB0000000, 0x00000000, + 0x025, 0x0000000F, + 0x072, 0x00000000, + 0x420, 0x00000080, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x45B, 0x00000080, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x604, 0x00000009, + 0x605, 0x00000030, + 0x607, 0x00000003, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000080, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, +}; + +u32 RTL8812AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8812AE_MAC_REG_ARRAY); + +u32 RTL8821AE_MAC_REG_ARRAY[] = { + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x0000003F, + 0x4C9, 0x000000FF, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x607, 0x00000007, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, +}; + +u32 RTL8821AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8821AE_MAC_REG_ARRAY); + +u32 RTL8812AE_AGC_TAB_ARRAY[] = { + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000001, + 0x81C, 0xFB020001, + 0x81C, 0xFA040001, + 0x81C, 0xF9060001, + 0x81C, 0xF8080001, + 0x81C, 0xF70A0001, + 0x81C, 0xF60C0001, + 0x81C, 0xF50E0001, + 0x81C, 0xF4100001, + 0x81C, 0xF3120001, + 0x81C, 0xF2140001, + 0x81C, 0xF1160001, + 0x81C, 0xF0180001, + 0x81C, 0xEF1A0001, + 0x81C, 0xEE1C0001, + 0x81C, 0xED1E0001, + 0x81C, 0xEC200001, + 0x81C, 0xEB220001, + 0x81C, 0xEA240001, + 0x81C, 0xCD260001, + 0x81C, 0xCC280001, + 0x81C, 0xCB2A0001, + 0x81C, 0xCA2C0001, + 0x81C, 0xC92E0001, + 0x81C, 0xC8300001, + 0x81C, 0xA6320001, + 0x81C, 0xA5340001, + 0x81C, 0xA4360001, + 0x81C, 0xA3380001, + 0x81C, 0xA23A0001, + 0x81C, 0x883C0001, + 0x81C, 0x873E0001, + 0x81C, 0x86400001, + 0x81C, 0x85420001, + 0x81C, 0x84440001, + 0x81C, 0x83460001, + 0x81C, 0x82480001, + 0x81C, 0x814A0001, + 0x81C, 0x484C0001, + 0x81C, 0x474E0001, + 0x81C, 0x46500001, + 0x81C, 0x45520001, + 0x81C, 0x44540001, + 0x81C, 0x43560001, + 0x81C, 0x42580001, + 0x81C, 0x415A0001, + 0x81C, 0x255C0001, + 0x81C, 0x245E0001, + 0x81C, 0x23600001, + 0x81C, 0x22620001, + 0x81C, 0x21640001, + 0x81C, 0x21660001, + 0x81C, 0x21680001, + 0x81C, 0x216A0001, + 0x81C, 0x216C0001, + 0x81C, 0x216E0001, + 0x81C, 0x21700001, + 0x81C, 0x21720001, + 0x81C, 0x21740001, + 0x81C, 0x21760001, + 0x81C, 0x21780001, + 0x81C, 0x217A0001, + 0x81C, 0x217C0001, + 0x81C, 0x217E0001, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x81C, 0xF9000001, + 0x81C, 0xF8020001, + 0x81C, 0xF7040001, + 0x81C, 0xF6060001, + 0x81C, 0xF5080001, + 0x81C, 0xF40A0001, + 0x81C, 0xF30C0001, + 0x81C, 0xF20E0001, + 0x81C, 0xF1100001, + 0x81C, 0xF0120001, + 0x81C, 0xEF140001, + 0x81C, 0xEE160001, + 0x81C, 0xED180001, + 0x81C, 0xEC1A0001, + 0x81C, 0xEB1C0001, + 0x81C, 0xEA1E0001, + 0x81C, 0xCD200001, + 0x81C, 0xCC220001, + 0x81C, 0xCB240001, + 0x81C, 0xCA260001, + 0x81C, 0xC9280001, + 0x81C, 0xC82A0001, + 0x81C, 0xC72C0001, + 0x81C, 0xC62E0001, + 0x81C, 0xA5300001, + 0x81C, 0xA4320001, + 0x81C, 0xA3340001, + 0x81C, 0xA2360001, + 0x81C, 0x88380001, + 0x81C, 0x873A0001, + 0x81C, 0x863C0001, + 0x81C, 0x853E0001, + 0x81C, 0x84400001, + 0x81C, 0x83420001, + 0x81C, 0x82440001, + 0x81C, 0x81460001, + 0x81C, 0x48480001, + 0x81C, 0x474A0001, + 0x81C, 0x464C0001, + 0x81C, 0x454E0001, + 0x81C, 0x44500001, + 0x81C, 0x43520001, + 0x81C, 0x42540001, + 0x81C, 0x41560001, + 0x81C, 0x25580001, + 0x81C, 0x245A0001, + 0x81C, 0x235C0001, + 0x81C, 0x225E0001, + 0x81C, 0x21600001, + 0x81C, 0x21620001, + 0x81C, 0x21640001, + 0x81C, 0x21660001, + 0x81C, 0x21680001, + 0x81C, 0x216A0001, + 0x81C, 0x236C0001, + 0x81C, 0x226E0001, + 0x81C, 0x21700001, + 0x81C, 0x21720001, + 0x81C, 0x21740001, + 0x81C, 0x21760001, + 0x81C, 0x21780001, + 0x81C, 0x217A0001, + 0x81C, 0x217C0001, + 0x81C, 0x217E0001, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000001, + 0x81C, 0xFF020001, + 0x81C, 0xFF040001, + 0x81C, 0xFF060001, + 0x81C, 0xFF080001, + 0x81C, 0xFE0A0001, + 0x81C, 0xFD0C0001, + 0x81C, 0xFC0E0001, + 0x81C, 0xFB100001, + 0x81C, 0xFA120001, + 0x81C, 0xF9140001, + 0x81C, 0xF8160001, + 0x81C, 0xF7180001, + 0x81C, 0xF61A0001, + 0x81C, 0xF51C0001, + 0x81C, 0xF41E0001, + 0x81C, 0xF3200001, + 0x81C, 0xF2220001, + 0x81C, 0xF1240001, + 0x81C, 0xF0260001, + 0x81C, 0xEF280001, + 0x81C, 0xEE2A0001, + 0x81C, 0xED2C0001, + 0x81C, 0xEC2E0001, + 0x81C, 0xEB300001, + 0x81C, 0xEA320001, + 0x81C, 0xE9340001, + 0x81C, 0xE8360001, + 0x81C, 0xE7380001, + 0x81C, 0xE63A0001, + 0x81C, 0xE53C0001, + 0x81C, 0xC73E0001, + 0x81C, 0xC6400001, + 0x81C, 0xC5420001, + 0x81C, 0xC4440001, + 0x81C, 0xC3460001, + 0x81C, 0xC2480001, + 0x81C, 0xC14A0001, + 0x81C, 0xA74C0001, + 0x81C, 0xA64E0001, + 0x81C, 0xA5500001, + 0x81C, 0xA4520001, + 0x81C, 0xA3540001, + 0x81C, 0xA2560001, + 0x81C, 0xA1580001, + 0x81C, 0x675A0001, + 0x81C, 0x665C0001, + 0x81C, 0x655E0001, + 0x81C, 0x64600001, + 0x81C, 0x63620001, + 0x81C, 0x48640001, + 0x81C, 0x47660001, + 0x81C, 0x46680001, + 0x81C, 0x456A0001, + 0x81C, 0x446C0001, + 0x81C, 0x436E0001, + 0x81C, 0x42700001, + 0x81C, 0x41720001, + 0x81C, 0x41740001, + 0x81C, 0x41760001, + 0x81C, 0x41780001, + 0x81C, 0x417A0001, + 0x81C, 0x417C0001, + 0x81C, 0x417E0001, + 0XB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC800001, + 0x81C, 0xFB820001, + 0x81C, 0xFA840001, + 0x81C, 0xF9860001, + 0x81C, 0xF8880001, + 0x81C, 0xF78A0001, + 0x81C, 0xF68C0001, + 0x81C, 0xF58E0001, + 0x81C, 0xF4900001, + 0x81C, 0xF3920001, + 0x81C, 0xF2940001, + 0x81C, 0xF1960001, + 0x81C, 0xF0980001, + 0x81C, 0xEF9A0001, + 0x81C, 0xEE9C0001, + 0x81C, 0xED9E0001, + 0x81C, 0xECA00001, + 0x81C, 0xEBA20001, + 0x81C, 0xEAA40001, + 0x81C, 0xE9A60001, + 0x81C, 0xE8A80001, + 0x81C, 0xE7AA0001, + 0x81C, 0xE6AC0001, + 0x81C, 0xE5AE0001, + 0x81C, 0xE4B00001, + 0x81C, 0xE3B20001, + 0x81C, 0xA8B40001, + 0x81C, 0xA7B60001, + 0x81C, 0xA6B80001, + 0x81C, 0xA5BA0001, + 0x81C, 0xA4BC0001, + 0x81C, 0xA3BE0001, + 0x81C, 0xA2C00001, + 0x81C, 0xA1C20001, + 0x81C, 0x68C40001, + 0x81C, 0x67C60001, + 0x81C, 0x66C80001, + 0x81C, 0x65CA0001, + 0x81C, 0x64CC0001, + 0x81C, 0x47CE0001, + 0x81C, 0x46D00001, + 0x81C, 0x45D20001, + 0x81C, 0x44D40001, + 0x81C, 0x43D60001, + 0x81C, 0x42D80001, + 0x81C, 0x08DA0001, + 0x81C, 0x07DC0001, + 0x81C, 0x06DE0001, + 0x81C, 0x05E00001, + 0x81C, 0x04E20001, + 0x81C, 0x03E40001, + 0x81C, 0x02E60001, + 0x81C, 0x01E80001, + 0x81C, 0x01EA0001, + 0x81C, 0x01EC0001, + 0x81C, 0x01EE0001, + 0x81C, 0x01F00001, + 0x81C, 0x01F20001, + 0x81C, 0x01F40001, + 0x81C, 0x01F60001, + 0x81C, 0x01F80001, + 0x81C, 0x01FA0001, + 0x81C, 0x01FC0001, + 0x81C, 0x01FE0001, + 0xA0000000, 0x00000000, + 0x81C, 0xFF800001, + 0x81C, 0xFF820001, + 0x81C, 0xFF840001, + 0x81C, 0xFE860001, + 0x81C, 0xFD880001, + 0x81C, 0xFC8A0001, + 0x81C, 0xFB8C0001, + 0x81C, 0xFA8E0001, + 0x81C, 0xF9900001, + 0x81C, 0xF8920001, + 0x81C, 0xF7940001, + 0x81C, 0xF6960001, + 0x81C, 0xF5980001, + 0x81C, 0xF49A0001, + 0x81C, 0xF39C0001, + 0x81C, 0xF29E0001, + 0x81C, 0xF1A00001, + 0x81C, 0xF0A20001, + 0x81C, 0xEFA40001, + 0x81C, 0xEEA60001, + 0x81C, 0xEDA80001, + 0x81C, 0xECAA0001, + 0x81C, 0xEBAC0001, + 0x81C, 0xEAAE0001, + 0x81C, 0xE9B00001, + 0x81C, 0xE8B20001, + 0x81C, 0xE7B40001, + 0x81C, 0xE6B60001, + 0x81C, 0xE5B80001, + 0x81C, 0xE4BA0001, + 0x81C, 0xE3BC0001, + 0x81C, 0xA8BE0001, + 0x81C, 0xA7C00001, + 0x81C, 0xA6C20001, + 0x81C, 0xA5C40001, + 0x81C, 0xA4C60001, + 0x81C, 0xA3C80001, + 0x81C, 0xA2CA0001, + 0x81C, 0xA1CC0001, + 0x81C, 0x68CE0001, + 0x81C, 0x67D00001, + 0x81C, 0x66D20001, + 0x81C, 0x65D40001, + 0x81C, 0x64D60001, + 0x81C, 0x47D80001, + 0x81C, 0x46DA0001, + 0x81C, 0x45DC0001, + 0x81C, 0x44DE0001, + 0x81C, 0x43E00001, + 0x81C, 0x42E20001, + 0x81C, 0x08E40001, + 0x81C, 0x07E60001, + 0x81C, 0x06E80001, + 0x81C, 0x05EA0001, + 0x81C, 0x04EC0001, + 0x81C, 0x03EE0001, + 0x81C, 0x02F00001, + 0x81C, 0x01F20001, + 0x81C, 0x01F40001, + 0x81C, 0x01F60001, + 0x81C, 0x01F80001, + 0x81C, 0x01FA0001, + 0x81C, 0x01FC0001, + 0x81C, 0x01FE0001, + 0XB0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, +}; + +u32 RTL8812AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8812AE_AGC_TAB_ARRAY); + +u32 RTL8821AE_AGC_TAB_ARRAY[] = { + 0x81C, 0XBF000001, + 0x81C, 0XBF020001, + 0x81C, 0XBF040001, + 0x81C, 0XBF060001, + 0x81C, 0XBE080001, + 0x81C, 0XBD0A0001, + 0x81C, 0XBC0C0001, + 0x81C, 0XBA0E0001, + 0x81C, 0XB9100001, + 0x81C, 0XB8120001, + 0x81C, 0XB7140001, + 0x81C, 0XB6160001, + 0x81C, 0XB5180001, + 0x81C, 0XB41A0001, + 0x81C, 0XB31C0001, + 0x81C, 0XB21E0001, + 0x81C, 0XB1200001, + 0x81C, 0XB0220001, + 0x81C, 0xAF240001, + 0x81C, 0xAE260001, + 0x81C, 0xAD280001, + 0x81C, 0xAC2A0001, + 0x81C, 0xAB2C0001, + 0x81C, 0xAA2E0001, + 0x81C, 0xA9300001, + 0x81C, 0xA8320001, + 0x81C, 0xA7340001, + 0x81C, 0xA6360001, + 0x81C, 0xA5380001, + 0x81C, 0xA43A0001, + 0x81C, 0x683C0001, + 0x81C, 0x673E0001, + 0x81C, 0x66400001, + 0x81C, 0x65420001, + 0x81C, 0x64440001, + 0x81C, 0x63460001, + 0x81C, 0x62480001, + 0x81C, 0x614A0001, + 0x81C, 0x474C0001, + 0x81C, 0x464E0001, + 0x81C, 0x45500001, + 0x81C, 0x44520001, + 0x81C, 0x43540001, + 0x81C, 0x42560001, + 0x81C, 0x41580001, + 0x81C, 0x285A0001, + 0x81C, 0x275C0001, + 0x81C, 0x265E0001, + 0x81C, 0x25600001, + 0x81C, 0x24620001, + 0x81C, 0x0A640001, + 0x81C, 0x09660001, + 0x81C, 0x08680001, + 0x81C, 0x076A0001, + 0x81C, 0x066C0001, + 0x81C, 0x056E0001, + 0x81C, 0x04700001, + 0x81C, 0x03720001, + 0x81C, 0x02740001, + 0x81C, 0x01760001, + 0x81C, 0x01780001, + 0x81C, 0x017A0001, + 0x81C, 0x017C0001, + 0x81C, 0x017E0001, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000101, + 0x81C, 0xFA020101, + 0x81C, 0xF9040101, + 0x81C, 0xF8060101, + 0x81C, 0xF7080101, + 0x81C, 0xF60A0101, + 0x81C, 0xF50C0101, + 0x81C, 0xF40E0101, + 0x81C, 0xF3100101, + 0x81C, 0xF2120101, + 0x81C, 0xF1140101, + 0x81C, 0xF0160101, + 0x81C, 0xEF180101, + 0x81C, 0xEE1A0101, + 0x81C, 0xED1C0101, + 0x81C, 0xEC1E0101, + 0x81C, 0xEB200101, + 0x81C, 0xEA220101, + 0x81C, 0xE9240101, + 0x81C, 0xE8260101, + 0x81C, 0xE7280101, + 0x81C, 0xE62A0101, + 0x81C, 0xE52C0101, + 0x81C, 0xE42E0101, + 0x81C, 0xE3300101, + 0x81C, 0xA5320101, + 0x81C, 0xA4340101, + 0x81C, 0xA3360101, + 0x81C, 0x87380101, + 0x81C, 0x863A0101, + 0x81C, 0x853C0101, + 0x81C, 0x843E0101, + 0x81C, 0x69400101, + 0x81C, 0x68420101, + 0x81C, 0x67440101, + 0x81C, 0x66460101, + 0x81C, 0x49480101, + 0x81C, 0x484A0101, + 0x81C, 0x474C0101, + 0x81C, 0x2A4E0101, + 0x81C, 0x29500101, + 0x81C, 0x28520101, + 0x81C, 0x27540101, + 0x81C, 0x26560101, + 0x81C, 0x25580101, + 0x81C, 0x245A0101, + 0x81C, 0x235C0101, + 0x81C, 0x055E0101, + 0x81C, 0x04600101, + 0x81C, 0x03620101, + 0x81C, 0x02640101, + 0x81C, 0x01660101, + 0x81C, 0x01680101, + 0x81C, 0x016A0101, + 0x81C, 0x016C0101, + 0x81C, 0x016E0101, + 0x81C, 0x01700101, + 0x81C, 0x01720101, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000101, + 0x81C, 0xFA020101, + 0x81C, 0xF9040101, + 0x81C, 0xF8060101, + 0x81C, 0xF7080101, + 0x81C, 0xF60A0101, + 0x81C, 0xF50C0101, + 0x81C, 0xF40E0101, + 0x81C, 0xF3100101, + 0x81C, 0xF2120101, + 0x81C, 0xF1140101, + 0x81C, 0xF0160101, + 0x81C, 0xEF180101, + 0x81C, 0xEE1A0101, + 0x81C, 0xED1C0101, + 0x81C, 0xEC1E0101, + 0x81C, 0xEB200101, + 0x81C, 0xEA220101, + 0x81C, 0xE9240101, + 0x81C, 0xE8260101, + 0x81C, 0xE7280101, + 0x81C, 0xE62A0101, + 0x81C, 0xE52C0101, + 0x81C, 0xE42E0101, + 0x81C, 0xE3300101, + 0x81C, 0xA5320101, + 0x81C, 0xA4340101, + 0x81C, 0xA3360101, + 0x81C, 0x87380101, + 0x81C, 0x863A0101, + 0x81C, 0x853C0101, + 0x81C, 0x843E0101, + 0x81C, 0x69400101, + 0x81C, 0x68420101, + 0x81C, 0x67440101, + 0x81C, 0x66460101, + 0x81C, 0x49480101, + 0x81C, 0x484A0101, + 0x81C, 0x474C0101, + 0x81C, 0x2A4E0101, + 0x81C, 0x29500101, + 0x81C, 0x28520101, + 0x81C, 0x27540101, + 0x81C, 0x26560101, + 0x81C, 0x25580101, + 0x81C, 0x245A0101, + 0x81C, 0x235C0101, + 0x81C, 0x055E0101, + 0x81C, 0x04600101, + 0x81C, 0x03620101, + 0x81C, 0x02640101, + 0x81C, 0x01660101, + 0x81C, 0x01680101, + 0x81C, 0x016A0101, + 0x81C, 0x016C0101, + 0x81C, 0x016E0101, + 0x81C, 0x01700101, + 0x81C, 0x01720101, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000101, + 0x81C, 0xFF020101, + 0x81C, 0xFE040101, + 0x81C, 0xFD060101, + 0x81C, 0xFC080101, + 0x81C, 0xFD0A0101, + 0x81C, 0xFC0C0101, + 0x81C, 0xFB0E0101, + 0x81C, 0xFA100101, + 0x81C, 0xF9120101, + 0x81C, 0xF8140101, + 0x81C, 0xF7160101, + 0x81C, 0xF6180101, + 0x81C, 0xF51A0101, + 0x81C, 0xF41C0101, + 0x81C, 0xF31E0101, + 0x81C, 0xF2200101, + 0x81C, 0xF1220101, + 0x81C, 0xF0240101, + 0x81C, 0xEF260101, + 0x81C, 0xEE280101, + 0x81C, 0xED2A0101, + 0x81C, 0xEC2C0101, + 0x81C, 0xEB2E0101, + 0x81C, 0xEA300101, + 0x81C, 0xE9320101, + 0x81C, 0xE8340101, + 0x81C, 0xE7360101, + 0x81C, 0xE6380101, + 0x81C, 0xE53A0101, + 0x81C, 0xE43C0101, + 0x81C, 0xE33E0101, + 0x81C, 0xA5400101, + 0x81C, 0xA4420101, + 0x81C, 0xA3440101, + 0x81C, 0x87460101, + 0x81C, 0x86480101, + 0x81C, 0x854A0101, + 0x81C, 0x844C0101, + 0x81C, 0x694E0101, + 0x81C, 0x68500101, + 0x81C, 0x67520101, + 0x81C, 0x66540101, + 0x81C, 0x49560101, + 0x81C, 0x48580101, + 0x81C, 0x475A0101, + 0x81C, 0x2A5C0101, + 0x81C, 0x295E0101, + 0x81C, 0x28600101, + 0x81C, 0x27620101, + 0x81C, 0x26640101, + 0x81C, 0x25660101, + 0x81C, 0x24680101, + 0x81C, 0x236A0101, + 0x81C, 0x056C0101, + 0x81C, 0x046E0101, + 0x81C, 0x03700101, + 0x81C, 0x02720101, + 0xB0000000, 0x00000000, + 0x81C, 0x01740101, + 0x81C, 0x01760101, + 0x81C, 0x01780101, + 0x81C, 0x017A0101, + 0x81C, 0x017C0101, + 0x81C, 0x017E0101, + 0xC50, 0x00000022, + 0xC50, 0x00000020, +}; + +u32 RTL8821AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_AGC_TAB_ARRAY); + +/****************************************************************************** +* TXPWR_LMT.TXT +******************************************************************************/ + +const char *RTL8812AE_TXPWR_LMT[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "02", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "02", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "02", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "03", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "03", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "03", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "04", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "04", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "05", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "05", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "05", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "06", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "06", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "06", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "07", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "07", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "08", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "08", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "08", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "09", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "09", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "09", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "10", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "10", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "11", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "11", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "11", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "12", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "12", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "12", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "13", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "13", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", + "MKK", "2.4G", "20M", "CCK", "1T", "14", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "01", "34", + "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "01", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "02", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "03", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "03", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "04", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "04", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "05", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "06", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "06", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "07", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "07", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "08", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "09", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "09", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "10", "36", + "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "10", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "11", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "12", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "13", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", + "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "1T", "01", "34", + "ETSI", "2.4G", "20M", "HT", "1T", "01", "32", + "MKK", "2.4G", "20M", "HT", "1T", "01", "32", + "FCC", "2.4G", "20M", "HT", "1T", "02", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "02", "32", + "MKK", "2.4G", "20M", "HT", "1T", "02", "32", + "FCC", "2.4G", "20M", "HT", "1T", "03", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "03", "32", + "MKK", "2.4G", "20M", "HT", "1T", "03", "32", + "FCC", "2.4G", "20M", "HT", "1T", "04", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "04", "32", + "MKK", "2.4G", "20M", "HT", "1T", "04", "32", + "FCC", "2.4G", "20M", "HT", "1T", "05", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "05", "32", + "MKK", "2.4G", "20M", "HT", "1T", "05", "32", + "FCC", "2.4G", "20M", "HT", "1T", "06", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "06", "32", + "MKK", "2.4G", "20M", "HT", "1T", "06", "32", + "FCC", "2.4G", "20M", "HT", "1T", "07", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "07", "32", + "MKK", "2.4G", "20M", "HT", "1T", "07", "32", + "FCC", "2.4G", "20M", "HT", "1T", "08", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "08", "32", + "MKK", "2.4G", "20M", "HT", "1T", "08", "32", + "FCC", "2.4G", "20M", "HT", "1T", "09", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "09", "32", + "MKK", "2.4G", "20M", "HT", "1T", "09", "32", + "FCC", "2.4G", "20M", "HT", "1T", "10", "36", + "ETSI", "2.4G", "20M", "HT", "1T", "10", "32", + "MKK", "2.4G", "20M", "HT", "1T", "10", "32", + "FCC", "2.4G", "20M", "HT", "1T", "11", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "11", "32", + "MKK", "2.4G", "20M", "HT", "1T", "11", "32", + "FCC", "2.4G", "20M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "12", "32", + "MKK", "2.4G", "20M", "HT", "1T", "12", "32", + "FCC", "2.4G", "20M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "13", "32", + "MKK", "2.4G", "20M", "HT", "1T", "13", "32", + "FCC", "2.4G", "20M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", + "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "01", "32", + "MKK", "2.4G", "20M", "HT", "2T", "01", "32", + "FCC", "2.4G", "20M", "HT", "2T", "02", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "02", "32", + "MKK", "2.4G", "20M", "HT", "2T", "02", "32", + "FCC", "2.4G", "20M", "HT", "2T", "03", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "03", "32", + "MKK", "2.4G", "20M", "HT", "2T", "03", "32", + "FCC", "2.4G", "20M", "HT", "2T", "04", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "04", "32", + "MKK", "2.4G", "20M", "HT", "2T", "04", "32", + "FCC", "2.4G", "20M", "HT", "2T", "05", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "05", "32", + "MKK", "2.4G", "20M", "HT", "2T", "05", "32", + "FCC", "2.4G", "20M", "HT", "2T", "06", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "06", "32", + "MKK", "2.4G", "20M", "HT", "2T", "06", "32", + "FCC", "2.4G", "20M", "HT", "2T", "07", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "07", "32", + "MKK", "2.4G", "20M", "HT", "2T", "07", "32", + "FCC", "2.4G", "20M", "HT", "2T", "08", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "08", "32", + "MKK", "2.4G", "20M", "HT", "2T", "08", "32", + "FCC", "2.4G", "20M", "HT", "2T", "09", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "09", "32", + "MKK", "2.4G", "20M", "HT", "2T", "09", "32", + "FCC", "2.4G", "20M", "HT", "2T", "10", "34", + "ETSI", "2.4G", "20M", "HT", "2T", "10", "32", + "MKK", "2.4G", "20M", "HT", "2T", "10", "32", + "FCC", "2.4G", "20M", "HT", "2T", "11", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "11", "32", + "MKK", "2.4G", "20M", "HT", "2T", "11", "32", + "FCC", "2.4G", "20M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "12", "32", + "MKK", "2.4G", "20M", "HT", "2T", "12", "32", + "FCC", "2.4G", "20M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "13", "32", + "MKK", "2.4G", "20M", "HT", "2T", "13", "32", + "FCC", "2.4G", "20M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", + "MKK", "2.4G", "20M", "HT", "2T", "14", "63", + "FCC", "2.4G", "40M", "HT", "1T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", + "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", + "MKK", "2.4G", "40M", "HT", "1T", "02", "63", + "FCC", "2.4G", "40M", "HT", "1T", "03", "32", + "ETSI", "2.4G", "40M", "HT", "1T", "03", "32", + "MKK", "2.4G", "40M", "HT", "1T", "03", "32", + "FCC", "2.4G", "40M", "HT", "1T", "04", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "04", "32", + "MKK", "2.4G", "40M", "HT", "1T", "04", "32", + "FCC", "2.4G", "40M", "HT", "1T", "05", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "05", "32", + "MKK", "2.4G", "40M", "HT", "1T", "05", "32", + "FCC", "2.4G", "40M", "HT", "1T", "06", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "06", "32", + "MKK", "2.4G", "40M", "HT", "1T", "06", "32", + "FCC", "2.4G", "40M", "HT", "1T", "07", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "07", "32", + "MKK", "2.4G", "40M", "HT", "1T", "07", "32", + "FCC", "2.4G", "40M", "HT", "1T", "08", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "08", "32", + "MKK", "2.4G", "40M", "HT", "1T", "08", "32", + "FCC", "2.4G", "40M", "HT", "1T", "09", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "09", "32", + "MKK", "2.4G", "40M", "HT", "1T", "09", "32", + "FCC", "2.4G", "40M", "HT", "1T", "10", "36", + "ETSI", "2.4G", "40M", "HT", "1T", "10", "32", + "MKK", "2.4G", "40M", "HT", "1T", "10", "32", + "FCC", "2.4G", "40M", "HT", "1T", "11", "32", + "ETSI", "2.4G", "40M", "HT", "1T", "11", "32", + "MKK", "2.4G", "40M", "HT", "1T", "11", "32", + "FCC", "2.4G", "40M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "12", "32", + "MKK", "2.4G", "40M", "HT", "1T", "12", "32", + "FCC", "2.4G", "40M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "13", "32", + "MKK", "2.4G", "40M", "HT", "1T", "13", "32", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", + "MKK", "2.4G", "40M", "HT", "1T", "14", "63", + "FCC", "2.4G", "40M", "HT", "2T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", + "MKK", "2.4G", "40M", "HT", "2T", "01", "63", + "FCC", "2.4G", "40M", "HT", "2T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "02", "63", + "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "30", + "ETSI", "2.4G", "40M", "HT", "2T", "03", "30", + "MKK", "2.4G", "40M", "HT", "2T", "03", "30", + "FCC", "2.4G", "40M", "HT", "2T", "04", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "04", "30", + "MKK", "2.4G", "40M", "HT", "2T", "04", "30", + "FCC", "2.4G", "40M", "HT", "2T", "05", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "05", "30", + "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "06", "30", + "MKK", "2.4G", "40M", "HT", "2T", "06", "30", + "FCC", "2.4G", "40M", "HT", "2T", "07", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "07", "30", + "MKK", "2.4G", "40M", "HT", "2T", "07", "30", + "FCC", "2.4G", "40M", "HT", "2T", "08", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "08", "30", + "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "09", "30", + "MKK", "2.4G", "40M", "HT", "2T", "09", "30", + "FCC", "2.4G", "40M", "HT", "2T", "10", "34", + "ETSI", "2.4G", "40M", "HT", "2T", "10", "30", + "MKK", "2.4G", "40M", "HT", "2T", "10", "30", + "FCC", "2.4G", "40M", "HT", "2T", "11", "30", + "ETSI", "2.4G", "40M", "HT", "2T", "11", "30", + "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "12", "32", + "MKK", "2.4G", "40M", "HT", "2T", "12", "32", + "FCC", "2.4G", "40M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "13", "32", + "MKK", "2.4G", "40M", "HT", "2T", "13", "32", + "FCC", "2.4G", "40M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "14", "63", + "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "36", "32", + "MKK", "5G", "20M", "OFDM", "1T", "36", "32", + "FCC", "5G", "20M", "OFDM", "1T", "40", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", + "MKK", "5G", "20M", "OFDM", "1T", "40", "32", + "FCC", "5G", "20M", "OFDM", "1T", "44", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "44", "32", + "MKK", "5G", "20M", "OFDM", "1T", "44", "32", + "FCC", "5G", "20M", "OFDM", "1T", "48", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "48", "32", + "MKK", "5G", "20M", "OFDM", "1T", "48", "32", + "FCC", "5G", "20M", "OFDM", "1T", "52", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", + "MKK", "5G", "20M", "OFDM", "1T", "52", "32", + "FCC", "5G", "20M", "OFDM", "1T", "56", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "56", "32", + "MKK", "5G", "20M", "OFDM", "1T", "56", "32", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "60", "32", + "MKK", "5G", "20M", "OFDM", "1T", "60", "32", + "FCC", "5G", "20M", "OFDM", "1T", "64", "28", + "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", + "MKK", "5G", "20M", "OFDM", "1T", "64", "32", + "FCC", "5G", "20M", "OFDM", "1T", "100", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "100", "32", + "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "104", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "104", "32", + "MKK", "5G", "20M", "OFDM", "1T", "104", "32", + "FCC", "5G", "20M", "OFDM", "1T", "108", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", + "MKK", "5G", "20M", "OFDM", "1T", "108", "32", + "FCC", "5G", "20M", "OFDM", "1T", "112", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "112", "32", + "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "116", "32", + "MKK", "5G", "20M", "OFDM", "1T", "116", "32", + "FCC", "5G", "20M", "OFDM", "1T", "120", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", + "MKK", "5G", "20M", "OFDM", "1T", "120", "32", + "FCC", "5G", "20M", "OFDM", "1T", "124", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "124", "32", + "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "128", "32", + "MKK", "5G", "20M", "OFDM", "1T", "128", "32", + "FCC", "5G", "20M", "OFDM", "1T", "132", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", + "MKK", "5G", "20M", "OFDM", "1T", "132", "32", + "FCC", "5G", "20M", "OFDM", "1T", "136", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "136", "32", + "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", + "ETSI", "5G", "20M", "OFDM", "1T", "140", "32", + "MKK", "5G", "20M", "OFDM", "1T", "140", "32", + "FCC", "5G", "20M", "OFDM", "1T", "149", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "149", "32", + "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "153", "32", + "MKK", "5G", "20M", "OFDM", "1T", "153", "63", + "FCC", "5G", "20M", "OFDM", "1T", "157", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "157", "32", + "MKK", "5G", "20M", "OFDM", "1T", "157", "63", + "FCC", "5G", "20M", "OFDM", "1T", "161", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "161", "32", + "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "36", + "ETSI", "5G", "20M", "OFDM", "1T", "165", "32", + "MKK", "5G", "20M", "OFDM", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "1T", "36", "30", + "ETSI", "5G", "20M", "HT", "1T", "36", "32", + "MKK", "5G", "20M", "HT", "1T", "36", "32", + "FCC", "5G", "20M", "HT", "1T", "40", "30", + "ETSI", "5G", "20M", "HT", "1T", "40", "32", + "MKK", "5G", "20M", "HT", "1T", "40", "32", + "FCC", "5G", "20M", "HT", "1T", "44", "30", + "ETSI", "5G", "20M", "HT", "1T", "44", "32", + "MKK", "5G", "20M", "HT", "1T", "44", "32", + "FCC", "5G", "20M", "HT", "1T", "48", "30", + "ETSI", "5G", "20M", "HT", "1T", "48", "32", + "MKK", "5G", "20M", "HT", "1T", "48", "32", + "FCC", "5G", "20M", "HT", "1T", "52", "36", + "ETSI", "5G", "20M", "HT", "1T", "52", "32", + "MKK", "5G", "20M", "HT", "1T", "52", "32", + "FCC", "5G", "20M", "HT", "1T", "56", "34", + "ETSI", "5G", "20M", "HT", "1T", "56", "32", + "MKK", "5G", "20M", "HT", "1T", "56", "32", + "FCC", "5G", "20M", "HT", "1T", "60", "32", + "ETSI", "5G", "20M", "HT", "1T", "60", "32", + "MKK", "5G", "20M", "HT", "1T", "60", "32", + "FCC", "5G", "20M", "HT", "1T", "64", "28", + "ETSI", "5G", "20M", "HT", "1T", "64", "32", + "MKK", "5G", "20M", "HT", "1T", "64", "32", + "FCC", "5G", "20M", "HT", "1T", "100", "30", + "ETSI", "5G", "20M", "HT", "1T", "100", "32", + "MKK", "5G", "20M", "HT", "1T", "100", "32", + "FCC", "5G", "20M", "HT", "1T", "104", "30", + "ETSI", "5G", "20M", "HT", "1T", "104", "32", + "MKK", "5G", "20M", "HT", "1T", "104", "32", + "FCC", "5G", "20M", "HT", "1T", "108", "32", + "ETSI", "5G", "20M", "HT", "1T", "108", "32", + "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "34", + "ETSI", "5G", "20M", "HT", "1T", "112", "32", + "MKK", "5G", "20M", "HT", "1T", "112", "32", + "FCC", "5G", "20M", "HT", "1T", "116", "34", + "ETSI", "5G", "20M", "HT", "1T", "116", "32", + "MKK", "5G", "20M", "HT", "1T", "116", "32", + "FCC", "5G", "20M", "HT", "1T", "120", "36", + "ETSI", "5G", "20M", "HT", "1T", "120", "32", + "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "34", + "ETSI", "5G", "20M", "HT", "1T", "124", "32", + "MKK", "5G", "20M", "HT", "1T", "124", "32", + "FCC", "5G", "20M", "HT", "1T", "128", "32", + "ETSI", "5G", "20M", "HT", "1T", "128", "32", + "MKK", "5G", "20M", "HT", "1T", "128", "32", + "FCC", "5G", "20M", "HT", "1T", "132", "30", + "ETSI", "5G", "20M", "HT", "1T", "132", "32", + "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "30", + "ETSI", "5G", "20M", "HT", "1T", "136", "32", + "MKK", "5G", "20M", "HT", "1T", "136", "32", + "FCC", "5G", "20M", "HT", "1T", "140", "28", + "ETSI", "5G", "20M", "HT", "1T", "140", "32", + "MKK", "5G", "20M", "HT", "1T", "140", "32", + "FCC", "5G", "20M", "HT", "1T", "149", "36", + "ETSI", "5G", "20M", "HT", "1T", "149", "32", + "MKK", "5G", "20M", "HT", "1T", "149", "63", + "FCC", "5G", "20M", "HT", "1T", "153", "36", + "ETSI", "5G", "20M", "HT", "1T", "153", "32", + "MKK", "5G", "20M", "HT", "1T", "153", "63", + "FCC", "5G", "20M", "HT", "1T", "157", "36", + "ETSI", "5G", "20M", "HT", "1T", "157", "32", + "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "36", + "ETSI", "5G", "20M", "HT", "1T", "161", "32", + "MKK", "5G", "20M", "HT", "1T", "161", "63", + "FCC", "5G", "20M", "HT", "1T", "165", "36", + "ETSI", "5G", "20M", "HT", "1T", "165", "32", + "MKK", "5G", "20M", "HT", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "2T", "36", "28", + "ETSI", "5G", "20M", "HT", "2T", "36", "30", + "MKK", "5G", "20M", "HT", "2T", "36", "30", + "FCC", "5G", "20M", "HT", "2T", "40", "28", + "ETSI", "5G", "20M", "HT", "2T", "40", "30", + "MKK", "5G", "20M", "HT", "2T", "40", "30", + "FCC", "5G", "20M", "HT", "2T", "44", "28", + "ETSI", "5G", "20M", "HT", "2T", "44", "30", + "MKK", "5G", "20M", "HT", "2T", "44", "30", + "FCC", "5G", "20M", "HT", "2T", "48", "28", + "ETSI", "5G", "20M", "HT", "2T", "48", "30", + "MKK", "5G", "20M", "HT", "2T", "48", "30", + "FCC", "5G", "20M", "HT", "2T", "52", "34", + "ETSI", "5G", "20M", "HT", "2T", "52", "30", + "MKK", "5G", "20M", "HT", "2T", "52", "30", + "FCC", "5G", "20M", "HT", "2T", "56", "32", + "ETSI", "5G", "20M", "HT", "2T", "56", "30", + "MKK", "5G", "20M", "HT", "2T", "56", "30", + "FCC", "5G", "20M", "HT", "2T", "60", "30", + "ETSI", "5G", "20M", "HT", "2T", "60", "30", + "MKK", "5G", "20M", "HT", "2T", "60", "30", + "FCC", "5G", "20M", "HT", "2T", "64", "26", + "ETSI", "5G", "20M", "HT", "2T", "64", "30", + "MKK", "5G", "20M", "HT", "2T", "64", "30", + "FCC", "5G", "20M", "HT", "2T", "100", "28", + "ETSI", "5G", "20M", "HT", "2T", "100", "30", + "MKK", "5G", "20M", "HT", "2T", "100", "30", + "FCC", "5G", "20M", "HT", "2T", "104", "28", + "ETSI", "5G", "20M", "HT", "2T", "104", "30", + "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "30", + "ETSI", "5G", "20M", "HT", "2T", "108", "30", + "MKK", "5G", "20M", "HT", "2T", "108", "30", + "FCC", "5G", "20M", "HT", "2T", "112", "32", + "ETSI", "5G", "20M", "HT", "2T", "112", "30", + "MKK", "5G", "20M", "HT", "2T", "112", "30", + "FCC", "5G", "20M", "HT", "2T", "116", "32", + "ETSI", "5G", "20M", "HT", "2T", "116", "30", + "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "34", + "ETSI", "5G", "20M", "HT", "2T", "120", "30", + "MKK", "5G", "20M", "HT", "2T", "120", "30", + "FCC", "5G", "20M", "HT", "2T", "124", "32", + "ETSI", "5G", "20M", "HT", "2T", "124", "30", + "MKK", "5G", "20M", "HT", "2T", "124", "30", + "FCC", "5G", "20M", "HT", "2T", "128", "30", + "ETSI", "5G", "20M", "HT", "2T", "128", "30", + "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "28", + "ETSI", "5G", "20M", "HT", "2T", "132", "30", + "MKK", "5G", "20M", "HT", "2T", "132", "30", + "FCC", "5G", "20M", "HT", "2T", "136", "28", + "ETSI", "5G", "20M", "HT", "2T", "136", "30", + "MKK", "5G", "20M", "HT", "2T", "136", "30", + "FCC", "5G", "20M", "HT", "2T", "140", "26", + "ETSI", "5G", "20M", "HT", "2T", "140", "30", + "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "149", "34", + "ETSI", "5G", "20M", "HT", "2T", "149", "30", + "MKK", "5G", "20M", "HT", "2T", "149", "63", + "FCC", "5G", "20M", "HT", "2T", "153", "34", + "ETSI", "5G", "20M", "HT", "2T", "153", "30", + "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "34", + "ETSI", "5G", "20M", "HT", "2T", "157", "30", + "MKK", "5G", "20M", "HT", "2T", "157", "63", + "FCC", "5G", "20M", "HT", "2T", "161", "34", + "ETSI", "5G", "20M", "HT", "2T", "161", "30", + "MKK", "5G", "20M", "HT", "2T", "161", "63", + "FCC", "5G", "20M", "HT", "2T", "165", "34", + "ETSI", "5G", "20M", "HT", "2T", "165", "30", + "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "30", + "ETSI", "5G", "40M", "HT", "1T", "38", "32", + "MKK", "5G", "40M", "HT", "1T", "38", "32", + "FCC", "5G", "40M", "HT", "1T", "46", "30", + "ETSI", "5G", "40M", "HT", "1T", "46", "32", + "MKK", "5G", "40M", "HT", "1T", "46", "32", + "FCC", "5G", "40M", "HT", "1T", "54", "32", + "ETSI", "5G", "40M", "HT", "1T", "54", "32", + "MKK", "5G", "40M", "HT", "1T", "54", "32", + "FCC", "5G", "40M", "HT", "1T", "62", "32", + "ETSI", "5G", "40M", "HT", "1T", "62", "32", + "MKK", "5G", "40M", "HT", "1T", "62", "32", + "FCC", "5G", "40M", "HT", "1T", "102", "28", + "ETSI", "5G", "40M", "HT", "1T", "102", "32", + "MKK", "5G", "40M", "HT", "1T", "102", "32", + "FCC", "5G", "40M", "HT", "1T", "110", "32", + "ETSI", "5G", "40M", "HT", "1T", "110", "32", + "MKK", "5G", "40M", "HT", "1T", "110", "32", + "FCC", "5G", "40M", "HT", "1T", "118", "36", + "ETSI", "5G", "40M", "HT", "1T", "118", "32", + "MKK", "5G", "40M", "HT", "1T", "118", "32", + "FCC", "5G", "40M", "HT", "1T", "126", "34", + "ETSI", "5G", "40M", "HT", "1T", "126", "32", + "MKK", "5G", "40M", "HT", "1T", "126", "32", + "FCC", "5G", "40M", "HT", "1T", "134", "32", + "ETSI", "5G", "40M", "HT", "1T", "134", "32", + "MKK", "5G", "40M", "HT", "1T", "134", "32", + "FCC", "5G", "40M", "HT", "1T", "151", "36", + "ETSI", "5G", "40M", "HT", "1T", "151", "32", + "MKK", "5G", "40M", "HT", "1T", "151", "63", + "FCC", "5G", "40M", "HT", "1T", "159", "36", + "ETSI", "5G", "40M", "HT", "1T", "159", "32", + "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "28", + "ETSI", "5G", "40M", "HT", "2T", "38", "30", + "MKK", "5G", "40M", "HT", "2T", "38", "30", + "FCC", "5G", "40M", "HT", "2T", "46", "28", + "ETSI", "5G", "40M", "HT", "2T", "46", "30", + "MKK", "5G", "40M", "HT", "2T", "46", "30", + "FCC", "5G", "40M", "HT", "2T", "54", "30", + "ETSI", "5G", "40M", "HT", "2T", "54", "30", + "MKK", "5G", "40M", "HT", "2T", "54", "30", + "FCC", "5G", "40M", "HT", "2T", "62", "30", + "ETSI", "5G", "40M", "HT", "2T", "62", "30", + "MKK", "5G", "40M", "HT", "2T", "62", "30", + "FCC", "5G", "40M", "HT", "2T", "102", "26", + "ETSI", "5G", "40M", "HT", "2T", "102", "30", + "MKK", "5G", "40M", "HT", "2T", "102", "30", + "FCC", "5G", "40M", "HT", "2T", "110", "30", + "ETSI", "5G", "40M", "HT", "2T", "110", "30", + "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "34", + "ETSI", "5G", "40M", "HT", "2T", "118", "30", + "MKK", "5G", "40M", "HT", "2T", "118", "30", + "FCC", "5G", "40M", "HT", "2T", "126", "32", + "ETSI", "5G", "40M", "HT", "2T", "126", "30", + "MKK", "5G", "40M", "HT", "2T", "126", "30", + "FCC", "5G", "40M", "HT", "2T", "134", "30", + "ETSI", "5G", "40M", "HT", "2T", "134", "30", + "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "151", "34", + "ETSI", "5G", "40M", "HT", "2T", "151", "30", + "MKK", "5G", "40M", "HT", "2T", "151", "63", + "FCC", "5G", "40M", "HT", "2T", "159", "34", + "ETSI", "5G", "40M", "HT", "2T", "159", "30", + "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "30", + "ETSI", "5G", "80M", "VHT", "1T", "42", "32", + "MKK", "5G", "80M", "VHT", "1T", "42", "32", + "FCC", "5G", "80M", "VHT", "1T", "58", "28", + "ETSI", "5G", "80M", "VHT", "1T", "58", "32", + "MKK", "5G", "80M", "VHT", "1T", "58", "32", + "FCC", "5G", "80M", "VHT", "1T", "106", "30", + "ETSI", "5G", "80M", "VHT", "1T", "106", "32", + "MKK", "5G", "80M", "VHT", "1T", "106", "32", + "FCC", "5G", "80M", "VHT", "1T", "122", "34", + "ETSI", "5G", "80M", "VHT", "1T", "122", "32", + "MKK", "5G", "80M", "VHT", "1T", "122", "32", + "FCC", "5G", "80M", "VHT", "1T", "155", "36", + "ETSI", "5G", "80M", "VHT", "1T", "155", "32", + "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "28", + "ETSI", "5G", "80M", "VHT", "2T", "42", "30", + "MKK", "5G", "80M", "VHT", "2T", "42", "30", + "FCC", "5G", "80M", "VHT", "2T", "58", "26", + "ETSI", "5G", "80M", "VHT", "2T", "58", "30", + "MKK", "5G", "80M", "VHT", "2T", "58", "30", + "FCC", "5G", "80M", "VHT", "2T", "106", "28", + "ETSI", "5G", "80M", "VHT", "2T", "106", "30", + "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "32", + "ETSI", "5G", "80M", "VHT", "2T", "122", "30", + "MKK", "5G", "80M", "VHT", "2T", "122", "30", + "FCC", "5G", "80M", "VHT", "2T", "155", "34", + "ETSI", "5G", "80M", "VHT", "2T", "155", "30", + "MKK", "5G", "80M", "VHT", "2T", "155", "63" +}; + +u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT); + +const char *RTL8821AE_TXPWR_LMT[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "02", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "02", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "02", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "03", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "03", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "03", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "04", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "04", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "05", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "05", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "05", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "06", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "06", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "06", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "07", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "07", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "08", "36", + "ETSI", "2.4G", "20M", "CCK", "1T", "08", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "08", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "09", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "09", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "09", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "10", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "10", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "11", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "11", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "11", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "12", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "12", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "12", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "13", "32", + "MKK", "2.4G", "20M", "CCK", "1T", "13", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", + "MKK", "2.4G", "20M", "CCK", "1T", "14", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "01", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "01", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "02", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "03", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "03", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "04", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "04", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "05", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "06", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "06", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "07", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "07", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "32", + "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "08", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "09", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "09", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "10", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "10", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "11", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "12", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "32", + "MKK", "2.4G", "20M", "OFDM", "1T", "13", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", + "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "1T", "01", "26", + "ETSI", "2.4G", "20M", "HT", "1T", "01", "32", + "MKK", "2.4G", "20M", "HT", "1T", "01", "32", + "FCC", "2.4G", "20M", "HT", "1T", "02", "26", + "ETSI", "2.4G", "20M", "HT", "1T", "02", "32", + "MKK", "2.4G", "20M", "HT", "1T", "02", "32", + "FCC", "2.4G", "20M", "HT", "1T", "03", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "03", "32", + "MKK", "2.4G", "20M", "HT", "1T", "03", "32", + "FCC", "2.4G", "20M", "HT", "1T", "04", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "04", "32", + "MKK", "2.4G", "20M", "HT", "1T", "04", "32", + "FCC", "2.4G", "20M", "HT", "1T", "05", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "05", "32", + "MKK", "2.4G", "20M", "HT", "1T", "05", "32", + "FCC", "2.4G", "20M", "HT", "1T", "06", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "06", "32", + "MKK", "2.4G", "20M", "HT", "1T", "06", "32", + "FCC", "2.4G", "20M", "HT", "1T", "07", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "07", "32", + "MKK", "2.4G", "20M", "HT", "1T", "07", "32", + "FCC", "2.4G", "20M", "HT", "1T", "08", "32", + "ETSI", "2.4G", "20M", "HT", "1T", "08", "32", + "MKK", "2.4G", "20M", "HT", "1T", "08", "32", + "FCC", "2.4G", "20M", "HT", "1T", "09", "26", + "ETSI", "2.4G", "20M", "HT", "1T", "09", "32", + "MKK", "2.4G", "20M", "HT", "1T", "09", "32", + "FCC", "2.4G", "20M", "HT", "1T", "10", "26", + "ETSI", "2.4G", "20M", "HT", "1T", "10", "32", + "MKK", "2.4G", "20M", "HT", "1T", "10", "32", + "FCC", "2.4G", "20M", "HT", "1T", "11", "26", + "ETSI", "2.4G", "20M", "HT", "1T", "11", "32", + "MKK", "2.4G", "20M", "HT", "1T", "11", "32", + "FCC", "2.4G", "20M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "12", "32", + "MKK", "2.4G", "20M", "HT", "1T", "12", "32", + "FCC", "2.4G", "20M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "13", "32", + "MKK", "2.4G", "20M", "HT", "1T", "13", "32", + "FCC", "2.4G", "20M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", + "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "01", "32", + "MKK", "2.4G", "20M", "HT", "2T", "01", "32", + "FCC", "2.4G", "20M", "HT", "2T", "02", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "02", "32", + "MKK", "2.4G", "20M", "HT", "2T", "02", "32", + "FCC", "2.4G", "20M", "HT", "2T", "03", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "03", "32", + "MKK", "2.4G", "20M", "HT", "2T", "03", "32", + "FCC", "2.4G", "20M", "HT", "2T", "04", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "04", "32", + "MKK", "2.4G", "20M", "HT", "2T", "04", "32", + "FCC", "2.4G", "20M", "HT", "2T", "05", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "05", "32", + "MKK", "2.4G", "20M", "HT", "2T", "05", "32", + "FCC", "2.4G", "20M", "HT", "2T", "06", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "06", "32", + "MKK", "2.4G", "20M", "HT", "2T", "06", "32", + "FCC", "2.4G", "20M", "HT", "2T", "07", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "07", "32", + "MKK", "2.4G", "20M", "HT", "2T", "07", "32", + "FCC", "2.4G", "20M", "HT", "2T", "08", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "08", "32", + "MKK", "2.4G", "20M", "HT", "2T", "08", "32", + "FCC", "2.4G", "20M", "HT", "2T", "09", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "09", "32", + "MKK", "2.4G", "20M", "HT", "2T", "09", "32", + "FCC", "2.4G", "20M", "HT", "2T", "10", "32", + "ETSI", "2.4G", "20M", "HT", "2T", "10", "32", + "MKK", "2.4G", "20M", "HT", "2T", "10", "32", + "FCC", "2.4G", "20M", "HT", "2T", "11", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "11", "32", + "MKK", "2.4G", "20M", "HT", "2T", "11", "32", + "FCC", "2.4G", "20M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "12", "32", + "MKK", "2.4G", "20M", "HT", "2T", "12", "32", + "FCC", "2.4G", "20M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "13", "32", + "MKK", "2.4G", "20M", "HT", "2T", "13", "32", + "FCC", "2.4G", "20M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", + "MKK", "2.4G", "20M", "HT", "2T", "14", "63", + "FCC", "2.4G", "40M", "HT", "1T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", + "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", + "MKK", "2.4G", "40M", "HT", "1T", "02", "63", + "FCC", "2.4G", "40M", "HT", "1T", "03", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "03", "32", + "MKK", "2.4G", "40M", "HT", "1T", "03", "32", + "FCC", "2.4G", "40M", "HT", "1T", "04", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "04", "32", + "MKK", "2.4G", "40M", "HT", "1T", "04", "32", + "FCC", "2.4G", "40M", "HT", "1T", "05", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "05", "32", + "MKK", "2.4G", "40M", "HT", "1T", "05", "32", + "FCC", "2.4G", "40M", "HT", "1T", "06", "32", + "ETSI", "2.4G", "40M", "HT", "1T", "06", "32", + "MKK", "2.4G", "40M", "HT", "1T", "06", "32", + "FCC", "2.4G", "40M", "HT", "1T", "07", "32", + "ETSI", "2.4G", "40M", "HT", "1T", "07", "32", + "MKK", "2.4G", "40M", "HT", "1T", "07", "32", + "FCC", "2.4G", "40M", "HT", "1T", "08", "32", + "ETSI", "2.4G", "40M", "HT", "1T", "08", "32", + "MKK", "2.4G", "40M", "HT", "1T", "08", "32", + "FCC", "2.4G", "40M", "HT", "1T", "09", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "09", "32", + "MKK", "2.4G", "40M", "HT", "1T", "09", "32", + "FCC", "2.4G", "40M", "HT", "1T", "10", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "10", "32", + "MKK", "2.4G", "40M", "HT", "1T", "10", "32", + "FCC", "2.4G", "40M", "HT", "1T", "11", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "11", "32", + "MKK", "2.4G", "40M", "HT", "1T", "11", "32", + "FCC", "2.4G", "40M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "12", "32", + "MKK", "2.4G", "40M", "HT", "1T", "12", "32", + "FCC", "2.4G", "40M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "13", "32", + "MKK", "2.4G", "40M", "HT", "1T", "13", "32", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", + "MKK", "2.4G", "40M", "HT", "1T", "14", "63", + "FCC", "2.4G", "40M", "HT", "2T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", + "MKK", "2.4G", "40M", "HT", "2T", "01", "63", + "FCC", "2.4G", "40M", "HT", "2T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "02", "63", + "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "30", + "ETSI", "2.4G", "40M", "HT", "2T", "03", "30", + "MKK", "2.4G", "40M", "HT", "2T", "03", "30", + "FCC", "2.4G", "40M", "HT", "2T", "04", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "04", "30", + "MKK", "2.4G", "40M", "HT", "2T", "04", "30", + "FCC", "2.4G", "40M", "HT", "2T", "05", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "05", "30", + "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "06", "30", + "MKK", "2.4G", "40M", "HT", "2T", "06", "30", + "FCC", "2.4G", "40M", "HT", "2T", "07", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "07", "30", + "MKK", "2.4G", "40M", "HT", "2T", "07", "30", + "FCC", "2.4G", "40M", "HT", "2T", "08", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "08", "30", + "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "09", "30", + "MKK", "2.4G", "40M", "HT", "2T", "09", "30", + "FCC", "2.4G", "40M", "HT", "2T", "10", "32", + "ETSI", "2.4G", "40M", "HT", "2T", "10", "30", + "MKK", "2.4G", "40M", "HT", "2T", "10", "30", + "FCC", "2.4G", "40M", "HT", "2T", "11", "30", + "ETSI", "2.4G", "40M", "HT", "2T", "11", "30", + "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "12", "32", + "MKK", "2.4G", "40M", "HT", "2T", "12", "32", + "FCC", "2.4G", "40M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "13", "32", + "MKK", "2.4G", "40M", "HT", "2T", "13", "32", + "FCC", "2.4G", "40M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "14", "63", + "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "36", "30", + "MKK", "5G", "20M", "OFDM", "1T", "36", "30", + "FCC", "5G", "20M", "OFDM", "1T", "40", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "40", "30", + "MKK", "5G", "20M", "OFDM", "1T", "40", "30", + "FCC", "5G", "20M", "OFDM", "1T", "44", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "44", "30", + "MKK", "5G", "20M", "OFDM", "1T", "44", "30", + "FCC", "5G", "20M", "OFDM", "1T", "48", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "48", "30", + "MKK", "5G", "20M", "OFDM", "1T", "48", "30", + "FCC", "5G", "20M", "OFDM", "1T", "52", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "52", "30", + "MKK", "5G", "20M", "OFDM", "1T", "52", "30", + "FCC", "5G", "20M", "OFDM", "1T", "56", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "56", "30", + "MKK", "5G", "20M", "OFDM", "1T", "56", "30", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "60", "30", + "MKK", "5G", "20M", "OFDM", "1T", "60", "30", + "FCC", "5G", "20M", "OFDM", "1T", "64", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "64", "30", + "MKK", "5G", "20M", "OFDM", "1T", "64", "30", + "FCC", "5G", "20M", "OFDM", "1T", "100", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "100", "30", + "MKK", "5G", "20M", "OFDM", "1T", "100", "30", + "FCC", "5G", "20M", "OFDM", "1T", "104", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "104", "30", + "MKK", "5G", "20M", "OFDM", "1T", "104", "30", + "FCC", "5G", "20M", "OFDM", "1T", "108", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "108", "30", + "MKK", "5G", "20M", "OFDM", "1T", "108", "30", + "FCC", "5G", "20M", "OFDM", "1T", "112", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "112", "30", + "MKK", "5G", "20M", "OFDM", "1T", "112", "30", + "FCC", "5G", "20M", "OFDM", "1T", "116", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "116", "30", + "MKK", "5G", "20M", "OFDM", "1T", "116", "30", + "FCC", "5G", "20M", "OFDM", "1T", "120", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "120", "30", + "MKK", "5G", "20M", "OFDM", "1T", "120", "30", + "FCC", "5G", "20M", "OFDM", "1T", "124", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "124", "30", + "MKK", "5G", "20M", "OFDM", "1T", "124", "30", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "128", "30", + "MKK", "5G", "20M", "OFDM", "1T", "128", "30", + "FCC", "5G", "20M", "OFDM", "1T", "132", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "132", "30", + "MKK", "5G", "20M", "OFDM", "1T", "132", "30", + "FCC", "5G", "20M", "OFDM", "1T", "136", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "136", "30", + "MKK", "5G", "20M", "OFDM", "1T", "136", "30", + "FCC", "5G", "20M", "OFDM", "1T", "140", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "140", "30", + "MKK", "5G", "20M", "OFDM", "1T", "140", "30", + "FCC", "5G", "20M", "OFDM", "1T", "149", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "149", "30", + "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "153", "30", + "MKK", "5G", "20M", "OFDM", "1T", "153", "63", + "FCC", "5G", "20M", "OFDM", "1T", "157", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "157", "30", + "MKK", "5G", "20M", "OFDM", "1T", "157", "63", + "FCC", "5G", "20M", "OFDM", "1T", "161", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "161", "30", + "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "165", "30", + "MKK", "5G", "20M", "OFDM", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "1T", "36", "32", + "ETSI", "5G", "20M", "HT", "1T", "36", "30", + "MKK", "5G", "20M", "HT", "1T", "36", "30", + "FCC", "5G", "20M", "HT", "1T", "40", "32", + "ETSI", "5G", "20M", "HT", "1T", "40", "30", + "MKK", "5G", "20M", "HT", "1T", "40", "30", + "FCC", "5G", "20M", "HT", "1T", "44", "32", + "ETSI", "5G", "20M", "HT", "1T", "44", "30", + "MKK", "5G", "20M", "HT", "1T", "44", "30", + "FCC", "5G", "20M", "HT", "1T", "48", "32", + "ETSI", "5G", "20M", "HT", "1T", "48", "30", + "MKK", "5G", "20M", "HT", "1T", "48", "30", + "FCC", "5G", "20M", "HT", "1T", "52", "32", + "ETSI", "5G", "20M", "HT", "1T", "52", "30", + "MKK", "5G", "20M", "HT", "1T", "52", "30", + "FCC", "5G", "20M", "HT", "1T", "56", "32", + "ETSI", "5G", "20M", "HT", "1T", "56", "30", + "MKK", "5G", "20M", "HT", "1T", "56", "30", + "FCC", "5G", "20M", "HT", "1T", "60", "32", + "ETSI", "5G", "20M", "HT", "1T", "60", "30", + "MKK", "5G", "20M", "HT", "1T", "60", "30", + "FCC", "5G", "20M", "HT", "1T", "64", "32", + "ETSI", "5G", "20M", "HT", "1T", "64", "30", + "MKK", "5G", "20M", "HT", "1T", "64", "30", + "FCC", "5G", "20M", "HT", "1T", "100", "32", + "ETSI", "5G", "20M", "HT", "1T", "100", "30", + "MKK", "5G", "20M", "HT", "1T", "100", "30", + "FCC", "5G", "20M", "HT", "1T", "104", "32", + "ETSI", "5G", "20M", "HT", "1T", "104", "30", + "MKK", "5G", "20M", "HT", "1T", "104", "30", + "FCC", "5G", "20M", "HT", "1T", "108", "32", + "ETSI", "5G", "20M", "HT", "1T", "108", "30", + "MKK", "5G", "20M", "HT", "1T", "108", "30", + "FCC", "5G", "20M", "HT", "1T", "112", "32", + "ETSI", "5G", "20M", "HT", "1T", "112", "30", + "MKK", "5G", "20M", "HT", "1T", "112", "30", + "FCC", "5G", "20M", "HT", "1T", "116", "32", + "ETSI", "5G", "20M", "HT", "1T", "116", "30", + "MKK", "5G", "20M", "HT", "1T", "116", "30", + "FCC", "5G", "20M", "HT", "1T", "120", "32", + "ETSI", "5G", "20M", "HT", "1T", "120", "30", + "MKK", "5G", "20M", "HT", "1T", "120", "30", + "FCC", "5G", "20M", "HT", "1T", "124", "32", + "ETSI", "5G", "20M", "HT", "1T", "124", "30", + "MKK", "5G", "20M", "HT", "1T", "124", "30", + "FCC", "5G", "20M", "HT", "1T", "128", "32", + "ETSI", "5G", "20M", "HT", "1T", "128", "30", + "MKK", "5G", "20M", "HT", "1T", "128", "30", + "FCC", "5G", "20M", "HT", "1T", "132", "32", + "ETSI", "5G", "20M", "HT", "1T", "132", "30", + "MKK", "5G", "20M", "HT", "1T", "132", "30", + "FCC", "5G", "20M", "HT", "1T", "136", "32", + "ETSI", "5G", "20M", "HT", "1T", "136", "30", + "MKK", "5G", "20M", "HT", "1T", "136", "30", + "FCC", "5G", "20M", "HT", "1T", "140", "32", + "ETSI", "5G", "20M", "HT", "1T", "140", "30", + "MKK", "5G", "20M", "HT", "1T", "140", "30", + "FCC", "5G", "20M", "HT", "1T", "149", "32", + "ETSI", "5G", "20M", "HT", "1T", "149", "30", + "MKK", "5G", "20M", "HT", "1T", "149", "63", + "FCC", "5G", "20M", "HT", "1T", "153", "32", + "ETSI", "5G", "20M", "HT", "1T", "153", "30", + "MKK", "5G", "20M", "HT", "1T", "153", "63", + "FCC", "5G", "20M", "HT", "1T", "157", "32", + "ETSI", "5G", "20M", "HT", "1T", "157", "30", + "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "32", + "ETSI", "5G", "20M", "HT", "1T", "161", "30", + "MKK", "5G", "20M", "HT", "1T", "161", "63", + "FCC", "5G", "20M", "HT", "1T", "165", "32", + "ETSI", "5G", "20M", "HT", "1T", "165", "30", + "MKK", "5G", "20M", "HT", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "2T", "36", "28", + "ETSI", "5G", "20M", "HT", "2T", "36", "30", + "MKK", "5G", "20M", "HT", "2T", "36", "30", + "FCC", "5G", "20M", "HT", "2T", "40", "28", + "ETSI", "5G", "20M", "HT", "2T", "40", "30", + "MKK", "5G", "20M", "HT", "2T", "40", "30", + "FCC", "5G", "20M", "HT", "2T", "44", "28", + "ETSI", "5G", "20M", "HT", "2T", "44", "30", + "MKK", "5G", "20M", "HT", "2T", "44", "30", + "FCC", "5G", "20M", "HT", "2T", "48", "28", + "ETSI", "5G", "20M", "HT", "2T", "48", "30", + "MKK", "5G", "20M", "HT", "2T", "48", "30", + "FCC", "5G", "20M", "HT", "2T", "52", "34", + "ETSI", "5G", "20M", "HT", "2T", "52", "30", + "MKK", "5G", "20M", "HT", "2T", "52", "30", + "FCC", "5G", "20M", "HT", "2T", "56", "32", + "ETSI", "5G", "20M", "HT", "2T", "56", "30", + "MKK", "5G", "20M", "HT", "2T", "56", "30", + "FCC", "5G", "20M", "HT", "2T", "60", "30", + "ETSI", "5G", "20M", "HT", "2T", "60", "30", + "MKK", "5G", "20M", "HT", "2T", "60", "30", + "FCC", "5G", "20M", "HT", "2T", "64", "26", + "ETSI", "5G", "20M", "HT", "2T", "64", "30", + "MKK", "5G", "20M", "HT", "2T", "64", "30", + "FCC", "5G", "20M", "HT", "2T", "100", "28", + "ETSI", "5G", "20M", "HT", "2T", "100", "30", + "MKK", "5G", "20M", "HT", "2T", "100", "30", + "FCC", "5G", "20M", "HT", "2T", "104", "28", + "ETSI", "5G", "20M", "HT", "2T", "104", "30", + "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "30", + "ETSI", "5G", "20M", "HT", "2T", "108", "30", + "MKK", "5G", "20M", "HT", "2T", "108", "30", + "FCC", "5G", "20M", "HT", "2T", "112", "32", + "ETSI", "5G", "20M", "HT", "2T", "112", "30", + "MKK", "5G", "20M", "HT", "2T", "112", "30", + "FCC", "5G", "20M", "HT", "2T", "116", "32", + "ETSI", "5G", "20M", "HT", "2T", "116", "30", + "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "34", + "ETSI", "5G", "20M", "HT", "2T", "120", "30", + "MKK", "5G", "20M", "HT", "2T", "120", "30", + "FCC", "5G", "20M", "HT", "2T", "124", "32", + "ETSI", "5G", "20M", "HT", "2T", "124", "30", + "MKK", "5G", "20M", "HT", "2T", "124", "30", + "FCC", "5G", "20M", "HT", "2T", "128", "30", + "ETSI", "5G", "20M", "HT", "2T", "128", "30", + "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "28", + "ETSI", "5G", "20M", "HT", "2T", "132", "30", + "MKK", "5G", "20M", "HT", "2T", "132", "30", + "FCC", "5G", "20M", "HT", "2T", "136", "28", + "ETSI", "5G", "20M", "HT", "2T", "136", "30", + "MKK", "5G", "20M", "HT", "2T", "136", "30", + "FCC", "5G", "20M", "HT", "2T", "140", "26", + "ETSI", "5G", "20M", "HT", "2T", "140", "30", + "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "149", "34", + "ETSI", "5G", "20M", "HT", "2T", "149", "30", + "MKK", "5G", "20M", "HT", "2T", "149", "63", + "FCC", "5G", "20M", "HT", "2T", "153", "34", + "ETSI", "5G", "20M", "HT", "2T", "153", "30", + "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "34", + "ETSI", "5G", "20M", "HT", "2T", "157", "30", + "MKK", "5G", "20M", "HT", "2T", "157", "63", + "FCC", "5G", "20M", "HT", "2T", "161", "34", + "ETSI", "5G", "20M", "HT", "2T", "161", "30", + "MKK", "5G", "20M", "HT", "2T", "161", "63", + "FCC", "5G", "20M", "HT", "2T", "165", "34", + "ETSI", "5G", "20M", "HT", "2T", "165", "30", + "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "26", + "ETSI", "5G", "40M", "HT", "1T", "38", "30", + "MKK", "5G", "40M", "HT", "1T", "38", "30", + "FCC", "5G", "40M", "HT", "1T", "46", "32", + "ETSI", "5G", "40M", "HT", "1T", "46", "30", + "MKK", "5G", "40M", "HT", "1T", "46", "30", + "FCC", "5G", "40M", "HT", "1T", "54", "32", + "ETSI", "5G", "40M", "HT", "1T", "54", "30", + "MKK", "5G", "40M", "HT", "1T", "54", "30", + "FCC", "5G", "40M", "HT", "1T", "62", "24", + "ETSI", "5G", "40M", "HT", "1T", "62", "30", + "MKK", "5G", "40M", "HT", "1T", "62", "30", + "FCC", "5G", "40M", "HT", "1T", "102", "24", + "ETSI", "5G", "40M", "HT", "1T", "102", "30", + "MKK", "5G", "40M", "HT", "1T", "102", "30", + "FCC", "5G", "40M", "HT", "1T", "110", "32", + "ETSI", "5G", "40M", "HT", "1T", "110", "30", + "MKK", "5G", "40M", "HT", "1T", "110", "30", + "FCC", "5G", "40M", "HT", "1T", "118", "32", + "ETSI", "5G", "40M", "HT", "1T", "118", "30", + "MKK", "5G", "40M", "HT", "1T", "118", "30", + "FCC", "5G", "40M", "HT", "1T", "126", "32", + "ETSI", "5G", "40M", "HT", "1T", "126", "30", + "MKK", "5G", "40M", "HT", "1T", "126", "30", + "FCC", "5G", "40M", "HT", "1T", "134", "32", + "ETSI", "5G", "40M", "HT", "1T", "134", "30", + "MKK", "5G", "40M", "HT", "1T", "134", "30", + "FCC", "5G", "40M", "HT", "1T", "151", "30", + "ETSI", "5G", "40M", "HT", "1T", "151", "30", + "MKK", "5G", "40M", "HT", "1T", "151", "63", + "FCC", "5G", "40M", "HT", "1T", "159", "32", + "ETSI", "5G", "40M", "HT", "1T", "159", "30", + "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "28", + "ETSI", "5G", "40M", "HT", "2T", "38", "30", + "MKK", "5G", "40M", "HT", "2T", "38", "30", + "FCC", "5G", "40M", "HT", "2T", "46", "28", + "ETSI", "5G", "40M", "HT", "2T", "46", "30", + "MKK", "5G", "40M", "HT", "2T", "46", "30", + "FCC", "5G", "40M", "HT", "2T", "54", "30", + "ETSI", "5G", "40M", "HT", "2T", "54", "30", + "MKK", "5G", "40M", "HT", "2T", "54", "30", + "FCC", "5G", "40M", "HT", "2T", "62", "30", + "ETSI", "5G", "40M", "HT", "2T", "62", "30", + "MKK", "5G", "40M", "HT", "2T", "62", "30", + "FCC", "5G", "40M", "HT", "2T", "102", "26", + "ETSI", "5G", "40M", "HT", "2T", "102", "30", + "MKK", "5G", "40M", "HT", "2T", "102", "30", + "FCC", "5G", "40M", "HT", "2T", "110", "30", + "ETSI", "5G", "40M", "HT", "2T", "110", "30", + "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "34", + "ETSI", "5G", "40M", "HT", "2T", "118", "30", + "MKK", "5G", "40M", "HT", "2T", "118", "30", + "FCC", "5G", "40M", "HT", "2T", "126", "32", + "ETSI", "5G", "40M", "HT", "2T", "126", "30", + "MKK", "5G", "40M", "HT", "2T", "126", "30", + "FCC", "5G", "40M", "HT", "2T", "134", "30", + "ETSI", "5G", "40M", "HT", "2T", "134", "30", + "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "151", "34", + "ETSI", "5G", "40M", "HT", "2T", "151", "30", + "MKK", "5G", "40M", "HT", "2T", "151", "63", + "FCC", "5G", "40M", "HT", "2T", "159", "34", + "ETSI", "5G", "40M", "HT", "2T", "159", "30", + "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "22", + "ETSI", "5G", "80M", "VHT", "1T", "42", "30", + "MKK", "5G", "80M", "VHT", "1T", "42", "30", + "FCC", "5G", "80M", "VHT", "1T", "58", "20", + "ETSI", "5G", "80M", "VHT", "1T", "58", "30", + "MKK", "5G", "80M", "VHT", "1T", "58", "30", + "FCC", "5G", "80M", "VHT", "1T", "106", "20", + "ETSI", "5G", "80M", "VHT", "1T", "106", "30", + "MKK", "5G", "80M", "VHT", "1T", "106", "30", + "FCC", "5G", "80M", "VHT", "1T", "122", "20", + "ETSI", "5G", "80M", "VHT", "1T", "122", "30", + "MKK", "5G", "80M", "VHT", "1T", "122", "30", + "FCC", "5G", "80M", "VHT", "1T", "155", "28", + "ETSI", "5G", "80M", "VHT", "1T", "155", "30", + "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "28", + "ETSI", "5G", "80M", "VHT", "2T", "42", "30", + "MKK", "5G", "80M", "VHT", "2T", "42", "30", + "FCC", "5G", "80M", "VHT", "2T", "58", "26", + "ETSI", "5G", "80M", "VHT", "2T", "58", "30", + "MKK", "5G", "80M", "VHT", "2T", "58", "30", + "FCC", "5G", "80M", "VHT", "2T", "106", "28", + "ETSI", "5G", "80M", "VHT", "2T", "106", "30", + "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "32", + "ETSI", "5G", "80M", "VHT", "2T", "122", "30", + "MKK", "5G", "80M", "VHT", "2T", "122", "30", + "FCC", "5G", "80M", "VHT", "2T", "155", "34", + "ETSI", "5G", "80M", "VHT", "2T", "155", "30", + "MKK", "5G", "80M", "VHT", "2T", "155", "63" +}; + +u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8821AE_TXPWR_LMT); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h new file mode 100644 index 000000000..76c62b7c0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_TABLE__H_ +#define __RTL8821AE_TABLE__H_ + +#include +extern u32 RTL8821AE_PHY_REG_1TARRAYLEN; +extern u32 RTL8821AE_PHY_REG_ARRAY[]; +extern u32 RTL8812AE_PHY_REG_1TARRAYLEN; +extern u32 RTL8812AE_PHY_REG_ARRAY[]; +extern u32 RTL8821AE_PHY_REG_ARRAY_PGLEN; +extern u32 RTL8821AE_PHY_REG_ARRAY_PG[]; +extern u32 RTL8812AE_PHY_REG_ARRAY_PGLEN; +extern u32 RTL8812AE_PHY_REG_ARRAY_PG[]; +extern u32 RTL8812AE_RADIOA_1TARRAYLEN; +extern u32 RTL8812AE_RADIOA_ARRAY[]; +extern u32 RTL8812AE_RADIOB_1TARRAYLEN; +extern u32 RTL8812AE_RADIOB_ARRAY[]; +extern u32 RTL8821AE_RADIOA_1TARRAYLEN; +extern u32 RTL8821AE_RADIOA_ARRAY[]; +extern u32 RTL8821AE_MAC_1T_ARRAYLEN; +extern u32 RTL8821AE_MAC_REG_ARRAY[]; +extern u32 RTL8812AE_MAC_1T_ARRAYLEN; +extern u32 RTL8812AE_MAC_REG_ARRAY[]; +extern u32 RTL8821AE_AGC_TAB_1TARRAYLEN; +extern u32 RTL8821AE_AGC_TAB_ARRAY[]; +extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN; +extern u32 RTL8812AE_AGC_TAB_ARRAY[]; +extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN; +extern const char *RTL8812AE_TXPWR_LMT[]; +extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN; +extern const char *RTL8821AE_TXPWR_LMT[]; +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c new file mode 100644 index 000000000..bd71592fe --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c @@ -0,0 +1,990 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "trx.h" +#include "led.h" +#include "dm.h" +#include "phy.h" +#include "fw.h" + +static u8 _rtl8821ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static u16 odm_cfo(s8 value) +{ + int ret_val; + + if (value < 0) { + ret_val = 0 - value; + ret_val = (ret_val << 1) + (ret_val >> 1); + /* set bit12 as 1 for negative cfo */ + ret_val = ret_val | BIT(12); + } else { + ret_val = value; + ret_val = (ret_val << 1) + (ret_val >> 1); + } + return ret_val; +} + +static u8 _rtl8821ae_evm_dbm_jaguar(s8 value) +{ + s8 ret_val = value; + + /* -33dB~0dB to 33dB ~ 0dB*/ + if (ret_val == -128) + ret_val = 127; + else if (ret_val < 0) + ret_val = 0 - ret_val; + + ret_val = ret_val >> 1; + return ret_val; +} + +static void query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstatus, __le32 *pdesc, + struct rx_fwinfo_8821ae *p_drvinfo, + bool bpacket_match_bssid, + bool bpacket_toself, bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo; + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, evmdbm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck = pstatus->is_cck; + u8 lan_idx, vga_idx; + + /* Record it for next packet processing */ + pstatus->packet_matchbssid = bpacket_match_bssid; + pstatus->packet_toself = bpacket_toself; + pstatus->packet_beacon = packet_beacon; + pstatus->rx_mimo_signalquality[0] = -1; + pstatus->rx_mimo_signalquality[1] = -1; + + if (is_cck) { + u8 cck_highpwr; + u8 cck_agc_rpt; + + cck_agc_rpt = p_phystrpt->cfosho[0]; + + /* (1)Hardware does not provide RSSI for CCK + * (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + cck_highpwr = (u8)rtlphy->cck_high_power; + + lan_idx = ((cck_agc_rpt & 0xE0) >> 5); + vga_idx = (cck_agc_rpt & 0x1f); + if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) { + switch (lan_idx) { + case 7: + if (vga_idx <= 27) + /*VGA_idx = 27~2*/ + rx_pwr_all = -100 + 2*(27-vga_idx); + else + rx_pwr_all = -100; + break; + case 6: + /*VGA_idx = 2~0*/ + rx_pwr_all = -48 + 2*(2-vga_idx); + break; + case 5: + /*VGA_idx = 7~5*/ + rx_pwr_all = -42 + 2*(7-vga_idx); + break; + case 4: + /*VGA_idx = 7~4*/ + rx_pwr_all = -36 + 2*(7-vga_idx); + break; + case 3: + /*VGA_idx = 7~0*/ + rx_pwr_all = -24 + 2*(7-vga_idx); + break; + case 2: + if (cck_highpwr) + /*VGA_idx = 5~0*/ + rx_pwr_all = -12 + 2*(5-vga_idx); + else + rx_pwr_all = -6 + 2*(5-vga_idx); + break; + case 1: + rx_pwr_all = 8-2*vga_idx; + break; + case 0: + rx_pwr_all = 14-2*vga_idx; + break; + default: + break; + } + rx_pwr_all += 6; + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + if (!cck_highpwr) { + if (pwdb_all >= 80) + pwdb_all = + ((pwdb_all - 80)<<1) + + ((pwdb_all - 80)>>1) + 80; + else if ((pwdb_all <= 78) && (pwdb_all >= 20)) + pwdb_all += 3; + if (pwdb_all > 100) + pwdb_all = 100; + } + } else { /* 8821 */ + s8 pout = -6; + + switch (lan_idx) { + case 5: + rx_pwr_all = pout - 32 - (2*vga_idx); + break; + case 4: + rx_pwr_all = pout - 24 - (2*vga_idx); + break; + case 2: + rx_pwr_all = pout - 11 - (2*vga_idx); + break; + case 1: + rx_pwr_all = pout + 5 - (2*vga_idx); + break; + case 0: + rx_pwr_all = pout + 21 - (2*vga_idx); + break; + } + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + } + + pstatus->rx_pwdb_all = pwdb_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3) Get Signal Quality (EVM) */ + if (bpacket_match_bssid) { + u8 sq; + + if (pstatus->rx_pwdb_all > 40) { + sq = 100; + } else { + sq = p_phystrpt->pwdb_all; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + + pstatus->signalquality = sq; + pstatus->rx_mimo_signalquality[0] = sq; + pstatus->rx_mimo_signalquality[1] = -1; + } + } else { + /* (1)Get RSSI for HT rate */ + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + /* we will judge RF RX path now. */ + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = (p_phystrpt->gain_trsw[i] & 0x7f) - 110; + + /* Translate DBM to percentage. */ + rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + + /* Get Rx snr value in DB */ + pstatus->rx_snr[i] = p_phystrpt->rxsnr[i] / 2; + rtlpriv->stats.rx_snr_db[i] = p_phystrpt->rxsnr[i] / 2; + + pstatus->cfo_short[i] = odm_cfo(p_phystrpt->cfosho[i]); + pstatus->cfo_tail[i] = odm_cfo(p_phystrpt->cfotail[i]); + /* Record Signal Strength for next packet */ + pstatus->rx_mimo_signalstrength[i] = (u8)rssi; + } + + /* (2)PWDB, Average PWDB calculated by + * hardware (for rate adaptive) + */ + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + + pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); + pstatus->rx_pwdb_all = pwdb_all; + pstatus->rxpower = rx_pwr_all; + pstatus->recvsignalpower = rx_pwr_all; + + /* (3)EVM of HT rate */ + if ((pstatus->is_ht && pstatus->rate >= DESC_RATEMCS8 && + pstatus->rate <= DESC_RATEMCS15) || + (pstatus->is_vht && + pstatus->rate >= DESC_RATEVHT2SS_MCS0 && + pstatus->rate <= DESC_RATEVHT2SS_MCS9)) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + evm = rtl_evm_db_to_percentage(p_phystrpt->rxevm[i]); + evmdbm = _rtl8821ae_evm_dbm_jaguar(p_phystrpt->rxevm[i]); + + if (bpacket_match_bssid) { + /* Fill value in RFD, Get the first + * spatial stream only + */ + if (i == 0) + pstatus->signalquality = evm; + pstatus->rx_mimo_signalquality[i] = evm; + pstatus->rx_mimo_evm_dbm[i] = evmdbm; + } + } + if (bpacket_match_bssid) { + for (i = RF90_PATH_A; i <= RF90_PATH_B; i++) + rtl_priv(hw)->dm.cfo_tail[i] = + (s8)p_phystrpt->cfotail[i]; + + rtl_priv(hw)->dm.packet_count++; + } + } + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + if (is_cck) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); + /*HW antenna diversity*/ + rtldm->fat_table.antsel_rx_keep_0 = p_phystrpt->antidx_anta; + rtldm->fat_table.antsel_rx_keep_1 = p_phystrpt->antidx_antb; +} + +static void translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, __le32 *pdesc, + struct rx_fwinfo_8821ae *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + __le16 fc; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; + + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + praddr = hdr->addr1; + psaddr = ieee80211_get_SA(hdr); + ether_addr_copy(pstatus->psaddr, psaddr); + + packet_matchbssid = (!ieee80211_is_ctl(fc) && + (ether_addr_equal(mac->bssid, + ieee80211_has_tods(fc) ? + hdr->addr1 : + ieee80211_has_fromds(fc) ? + hdr->addr2 : hdr->addr3)) && + (!pstatus->hwerror) && + (!pstatus->crc) && (!pstatus->icv)); + + packet_toself = packet_matchbssid && + (ether_addr_equal(praddr, rtlefuse->dev_addr)); + + if (ieee80211_is_beacon(hdr->frame_control)) + packet_beacon = true; + else + packet_beacon = false; + + if (packet_beacon && packet_matchbssid) + rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + + if (packet_matchbssid && + ieee80211_is_data_qos(hdr->frame_control) && + !is_multicast_ether_addr(ieee80211_get_DA(hdr))) { + struct ieee80211_qos_hdr *hdr_qos = + (struct ieee80211_qos_hdr *)tmp_buf; + u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf; + + if (tid != 0 && tid != 3) + rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++; + } + + query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + /*_rtl8821ae_smart_antenna(hw, pstatus); */ + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void rtl8821ae_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + __le32 *virtualaddress) +{ + u32 dwtmp = 0; + + memset(virtualaddress, 0, 8); + + set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[1]; + } + set_earlymode_len0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[3]; + } + set_earlymode_len1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[5]; + } + set_earlymode_len2_1(virtualaddress, dwtmp & 0xF); + set_earlymode_len2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[7]; + } + set_earlymode_len3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4; + dwtmp += ptcb_desc->empkt_len[9]; + } + set_earlymode_len4(virtualaddress, dwtmp); +} + +static bool rtl8821ae_get_rxdesc_is_ht(struct ieee80211_hw *hw, __le32 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = get_rx_desc_rxmcs(pdesc); + + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if ((rx_rate >= DESC_RATEMCS0) && (rx_rate <= DESC_RATEMCS15)) + return true; + return false; +} + +static bool rtl8821ae_get_rxdesc_is_vht(struct ieee80211_hw *hw, __le32 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = get_rx_desc_rxmcs(pdesc); + + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if (rx_rate >= DESC_RATEVHT1SS_MCS0) + return true; + return false; +} + +static u8 rtl8821ae_get_rx_vht_nss(struct ieee80211_hw *hw, __le32 *pdesc) +{ + u8 rx_rate = 0; + u8 vht_nss = 0; + + rx_rate = get_rx_desc_rxmcs(pdesc); + if ((rx_rate >= DESC_RATEVHT1SS_MCS0) && + (rx_rate <= DESC_RATEVHT1SS_MCS9)) + vht_nss = 1; + else if ((rx_rate >= DESC_RATEVHT2SS_MCS0) && + (rx_rate <= DESC_RATEVHT2SS_MCS9)) + vht_nss = 2; + + return vht_nss; +} + +bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc8, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rx_fwinfo_8821ae *p_drvinfo; + struct ieee80211_hdr *hdr; + u8 wake_match; + __le32 *pdesc = (__le32 *)pdesc8; + u32 phystatus = get_rx_desc_physt(pdesc); + + status->length = (u16)get_rx_desc_pkt_len(pdesc); + status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03); + status->icv = (u16)get_rx_desc_icv(pdesc); + status->crc = (u16)get_rx_desc_crc32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !get_rx_desc_swdec(pdesc); + status->rate = (u8)get_rx_desc_rxmcs(pdesc); + status->shortpreamble = (u16)get_rx_desc_splcp(pdesc); + status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->isfirst_ampdu = (bool)(get_rx_desc_paggr(pdesc) == 1); + status->timestamp_low = get_rx_desc_tsfl(pdesc); + status->rx_packet_bw = get_rx_desc_bw(pdesc); + status->macid = get_rx_desc_macid(pdesc); + status->is_short_gi = !(bool)get_rx_desc_splcp(pdesc); + status->is_ht = rtl8821ae_get_rxdesc_is_ht(hw, pdesc); + status->is_vht = rtl8821ae_get_rxdesc_is_vht(hw, pdesc); + status->vht_nss = rtl8821ae_get_rx_vht_nss(hw, pdesc); + status->is_cck = RTL8821AE_RX_HAL_IS_CCK_RATE(status->rate); + + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, + "rx_packet_bw=%s,is_ht %d, is_vht %d, vht_nss=%d,is_short_gi %d.\n", + (status->rx_packet_bw == 2) ? "80M" : + (status->rx_packet_bw == 1) ? "40M" : "20M", + status->is_ht, status->is_vht, status->vht_nss, + status->is_short_gi); + + if (get_rx_status_desc_rpt_sel(pdesc)) + status->packet_report_type = C2H_PACKET; + else + status->packet_report_type = NORMAL_RX; + + if (get_rx_status_desc_pattern_match(pdesc)) + wake_match = BIT(2); + else if (get_rx_status_desc_magic_match(pdesc)) + wake_match = BIT(1); + else if (get_rx_status_desc_unicast_match(pdesc)) + wake_match = BIT(0); + else + wake_match = 0; + + if (wake_match) + rtl_dbg(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + hdr = (struct ieee80211_hdr *)(skb->data + + status->rx_drvinfo_size + status->rx_bufshift); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40) + rx_status->bw = RATE_INFO_BW_40; + else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80) + rx_status->bw = RATE_INFO_BW_80; + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + if (status->is_vht) + rx_status->encoding = RX_ENC_VHT; + + if (status->is_short_gi) + rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + rx_status->nss = status->vht_nss; + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + * So hw will not decryption robust managment frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + */ + rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, + status->is_vht, + status->rate); + + rx_status->mactime = status->timestamp_low; + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_8821ae *)(skb->data + + status->rx_bufshift); + + translate_rx_signal_stuff(hw, skb, status, pdesc, p_drvinfo); + } + rx_status->signal = status->recvsignalpower + 10; + if (status->packet_report_type == TX_REPORT2) { + status->macid_valid_entry[0] = + get_rx_rpt2_desc_macid_valid_1(pdesc); + status->macid_valid_entry[1] = + get_rx_rpt2_desc_macid_valid_2(pdesc); + } + return true; +} + +static u8 rtl8821ae_bw_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw_setting_of_desc = 0; + + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "%s, current_chan_bw %d, packet_bw %d\n", + __func__, + rtlphy->current_chan_bw, ptcb_desc->packet_bw); + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) + bw_setting_of_desc = 2; + else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if ((ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) || + (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80)) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else { + bw_setting_of_desc = 0; + } + return bw_setting_of_desc; +} + +static u8 rtl8821ae_sc_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 sc_setting_of_desc = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) + sc_setting_of_desc = + VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) + sc_setting_of_desc = + VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + rtl_dbg(rtlpriv, COMP_SEND, DBG_LOUD, + "%s: Not Correct Primary40MHz Setting\n", + __func__); + } else { + if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + rtl_dbg(rtlpriv, COMP_SEND, DBG_LOUD, + "%s: Not Correct Primary40MHz Setting\n", + __func__); + } + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20) { + if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) { + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + } else if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER){ + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + } + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + + return sc_setting_of_desc; +} + +void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc8, u8 *txbd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtlwifi_tx_info *tx_info = rtl_tx_skb_cb_info(skb); + u16 seq_number; + __le16 fc = hdr->frame_control; + unsigned int buf_len = 0; + unsigned int skb_len = skb->len; + u8 fw_qsel = _rtl8821ae_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 short_gi = 0; + bool tmp_bool; + __le32 *pdesc = (__le32 *)pdesc8; + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + buf_len = skb->len; + mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_8821ae)); + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + set_tx_desc_pkt_offset(pdesc, 1); + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN + + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + rtl8821ae_insert_emcontent(ptcb_desc, + (__le32 *)skb->data); + } + } else { + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + } + + + /* ptcb_desc->use_driver_rate = true; */ + set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate); + if (ptcb_desc->hw_rate > DESC_RATEMCS0) + short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; + else + short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + + set_tx_desc_data_shortgi(pdesc, short_gi); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + set_tx_desc_agg_enable(pdesc, 1); + set_tx_desc_max_agg_num(pdesc, 0x1f); + } + set_tx_desc_seq(pdesc, seq_number); + set_tx_desc_rts_enable(pdesc, + ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + set_tx_desc_hw_rts_enable(pdesc, 0); + set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + + set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate); + set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc); + tmp_bool = ((ptcb_desc->rts_rate <= DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0)); + set_tx_desc_rts_short(pdesc, tmp_bool); + + if (ptcb_desc->tx_enable_sw_calc_duration) + set_tx_desc_nav_use_hdr(pdesc, 1); + + set_tx_desc_data_bw(pdesc, + rtl8821ae_bw_mapping(hw, ptcb_desc)); + + set_tx_desc_tx_sub_carrier(pdesc, + rtl8821ae_sc_mapping(hw, ptcb_desc)); + + set_tx_desc_linip(pdesc, 0); + set_tx_desc_pkt_size(pdesc, (u16)skb_len); + if (sta) { + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; + + set_tx_desc_ampdu_density(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = + info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + set_tx_desc_sec_type(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + set_tx_desc_sec_type(pdesc, 0x3); + break; + default: + set_tx_desc_sec_type(pdesc, 0x0); + break; + } + } + + set_tx_desc_queue_sel(pdesc, fw_qsel); + set_tx_desc_data_rate_fb_limit(pdesc, 0x1F); + set_tx_desc_rts_rate_fb_limit(pdesc, 0xF); + set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ? + 1 : 0); + set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + set_tx_desc_rdg_enable(pdesc, 1); + set_tx_desc_htc(pdesc, 1); + } + } + /* tx report */ + rtl_set_tx_report(ptcb_desc, pdesc8, hw, tx_info); + } + + set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0)); + set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0)); + set_tx_desc_tx_buffer_size(pdesc, buf_len); + set_tx_desc_tx_buffer_address(pdesc, mapping); + /* if (rtlpriv->dm.useramask) { */ + if (1) { + set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } else { + set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index); + set_tx_desc_macid(pdesc, ptcb_desc->mac_id); + } + if (!ieee80211_is_data_qos(fc)) { + set_tx_desc_hwseq_en(pdesc, 1); + set_tx_desc_hwseq_sel(pdesc, 0); + } + set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1)); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + set_tx_desc_bmc(pdesc, 1); + } + + rtl8821ae_dm_set_tx_ant_by_tx_info(hw, pdesc8, ptcb_desc->mac_id); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue = QSLT_BEACON; + __le32 *pdesc = (__le32 *)pdesc8; + + dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + + if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); + return; + } + clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE); + + set_tx_desc_first_seg(pdesc, 1); + set_tx_desc_last_seg(pdesc, 1); + + set_tx_desc_pkt_size(pdesc, (u16)(skb->len)); + + set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN); + + set_tx_desc_use_rate(pdesc, 1); + set_tx_desc_tx_rate(pdesc, DESC_RATE1M); + set_tx_desc_disable_fb(pdesc, 1); + + set_tx_desc_data_bw(pdesc, 0); + + set_tx_desc_hwseq_en(pdesc, 1); + + set_tx_desc_queue_sel(pdesc, fw_queue); + + set_tx_desc_tx_buffer_size(pdesc, skb->len); + + set_tx_desc_tx_buffer_address(pdesc, mapping); + + set_tx_desc_macid(pdesc, 0); + + set_tx_desc_own(pdesc, 1); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", + pdesc8, TX_DESC_SIZE); +} + +void rtl8821ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, + bool istx, u8 desc_name, u8 *val) +{ + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + set_tx_desc_own(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + set_tx_desc_next_desc_address(pdesc, *(u32 *)val); + break; + default: + WARN_ONCE(true, + "rtl8821ae: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + set_rx_desc_own(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + set_rx_desc_buff_addr(pdesc, *(u32 *)val); + break; + case HW_DESC_RXPKT_LEN: + set_rx_desc_pkt_len(pdesc, *(u32 *)val); + break; + case HW_DESC_RXERO: + set_rx_desc_eor(pdesc, 1); + break; + default: + WARN_ONCE(true, + "rtl8821ae: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } +} + +u64 rtl8821ae_get_desc(struct ieee80211_hw *hw, + u8 *pdesc8, bool istx, u8 desc_name) +{ + u32 ret = 0; + __le32 *pdesc = (__le32 *)pdesc8; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_tx_desc_own(pdesc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = get_tx_desc_tx_buffer_address(pdesc); + break; + default: + WARN_ONCE(true, + "rtl8821ae: ERR txdesc :%d not processed\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_OWN: + ret = get_rx_desc_own(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = get_rx_desc_pkt_len(pdesc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = get_rx_desc_buff_addr(pdesc); + break; + default: + WARN_ONCE(true, + "rtl8821ae: ERR rxdesc :%d not processed\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl8821ae_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl8821ae_get_desc(hw, entry, true, HW_DESC_OWN); + + /** + *beacon packet will only use the first + *descriptor defautly,and the own may not + *be cleared by the hardware + */ + if (own) + return false; + return true; +} + +void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (hw_queue == BEACON_QUEUE) { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + } else { + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); + } +} diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h new file mode 100644 index 000000000..d5de09d75 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h @@ -0,0 +1,652 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2010 Realtek Corporation.*/ + +#ifndef __RTL8821AE_TRX_H__ +#define __RTL8821AE_TRX_H__ + +#define TX_DESC_SIZE 40 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 40 +#define CRCLENGTH 4 + +static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(23, 16)); +} + +static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(24)); +} + +static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(25)); +} + +static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(26)); +} + +static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(27)); +} + +static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(28)); +} + +static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_tx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(20, 16)); +} + +static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(23, 22)); +} + +static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 1, __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(12)); +} + +static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(13)); +} + +static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, BIT(17)); +} + +static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 2, __val, GENMASK(22, 20)); +} + +static inline void set_tx_desc_hwseq_sel(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, GENMASK(7, 6)); +} + +static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(8)); +} + +static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(10)); +} + +static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(11)); +} + +static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(12)); +} + +static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(13)); +} + +static inline void set_tx_desc_nav_use_hdr(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, BIT(15)); +} + +static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 3, __val, GENMASK(21, 17)); +} + +static inline void set_tx_desc_tx_ant(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(27, 24)); +} + +static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(6, 0)); +} + +static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(12, 8)); +} + +static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 4, __val, GENMASK(28, 24)); +} + +static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(3, 0)); +} + +static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, BIT(4)); +} + +static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(6, 5)); +} + +static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, BIT(12)); +} + +static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 5, __val, GENMASK(16, 13)); +} + +static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 7, __val, GENMASK(15, 0)); +} + +static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 8, __val, BIT(15)); +} + +static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc + 9, __val, GENMASK(23, 12)); +} + +static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 10) = cpu_to_le32(__val); +} + +static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 10)); +} + +static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 12) = cpu_to_le32(__val); +} + +static inline int get_rx_desc_pkt_len(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(13, 0)); +} + +static inline int get_rx_desc_crc32(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(14)); +} + +static inline int get_rx_desc_icv(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(15)); +} + +static inline int get_rx_desc_drv_info_size(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(19, 16)); +} + +static inline int get_rx_desc_shift(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), GENMASK(25, 24)); +} + +static inline int get_rx_desc_physt(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(26)); +} + +static inline int get_rx_desc_swdec(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(27)); +} + +static inline int get_rx_desc_own(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc), BIT(31)); +} + +static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, GENMASK(13, 0)); +} + +static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(30)); +} + +static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val) +{ + le32p_replace_bits(__pdesc, __val, BIT(31)); +} + +static inline int get_rx_desc_macid(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), GENMASK(6, 0)); +} + +static inline int get_rx_desc_paggr(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 1), BIT(15)); +} + +static inline int get_rx_status_desc_rpt_sel(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 2), BIT(28)); +} + +static inline int get_rx_desc_rxmcs(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), GENMASK(6, 0)); +} + +static inline int get_rx_status_desc_pattern_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(29)); +} + +static inline int get_rx_status_desc_unicast_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(30)); +} + +static inline int get_rx_status_desc_magic_match(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 3), BIT(31)); +} + +static inline int get_rx_desc_splcp(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 4), BIT(0)); +} + +static inline int get_rx_desc_bw(__le32 *__pdesc) +{ + return le32_get_bits(*(__pdesc + 4), GENMASK(5, 4)); +} + +static inline u32 get_rx_desc_tsfl(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 5)); +} + +static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc) +{ + return le32_to_cpu(*(__pdesc + 6)); +} + +static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val) +{ + *(__pdesc + 6) = cpu_to_le32(__val); +} + +/* TX report 2 format in Rx desc*/ + +static inline u32 get_rx_rpt2_desc_macid_valid_1(__le32 *__status) +{ + return le32_to_cpu(*(__status + 4)); +} + +static inline u32 get_rx_rpt2_desc_macid_valid_2(__le32 *__status) +{ + return le32_to_cpu(*(__status + 5)); +} + +static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(3, 0)); +} + +static inline void set_earlymode_len0(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(15, 4)); +} + +static inline void set_earlymode_len1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(27, 16)); +} + +static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(31, 28)); +} + +static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits(__paddr, __value, GENMASK(7, 0)); +} + +static inline void set_earlymode_len3(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8)); +} + +static inline void set_earlymode_len4(__le32 *__paddr, u32 __value) +{ + le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20)); +} + +static inline void clear_pci_tx_desc_content(__le32 *__pdesc, int _size) +{ + if (_size > TX_DESC_NEXT_DESC_OFFSET) + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); + else + memset(__pdesc, 0, _size); +} + +#define RTL8821AE_RX_HAL_IS_CCK_RATE(rxmcs)\ + (rxmcs == DESC_RATE1M ||\ + rxmcs == DESC_RATE2M ||\ + rxmcs == DESC_RATE5_5M ||\ + rxmcs == DESC_RATE11M) + +struct phy_rx_agc_info_t { + #ifdef __LITTLE_ENDIAN + u8 gain:7, trsw:1; + #else + u8 trsw:1, gain:7; + #endif +}; + +struct phy_status_rpt { + /* DWORD 0 */ + u8 gain_trsw[2]; +#ifdef __LITTLE_ENDIAN + u16 chl_num:10; + u16 sub_chnl:4; + u16 r_rfmod:2; +#else /* _BIG_ENDIAN_ */ + u16 r_rfmod:2; + u16 sub_chnl:4; + u16 chl_num:10; +#endif + /* DWORD 1 */ + u8 pwdb_all; + u8 cfosho[4]; /* DW 1 byte 1 DW 2 byte 0 */ + + /* DWORD 2 */ + s8 cfotail[4]; /* DW 2 byte 1 DW 3 byte 0 */ + + /* DWORD 3 */ + s8 rxevm[2]; /* DW 3 byte 1 DW 3 byte 2 */ + s8 rxsnr[2]; /* DW 3 byte 3 DW 4 byte 0 */ + + /* DWORD 4 */ + u8 pcts_msk_rpt[2]; + u8 pdsnr[2]; /* DW 4 byte 3 DW 5 Byte 0 */ + + /* DWORD 5 */ + u8 csi_current[2]; + u8 rx_gain_c; + + /* DWORD 6 */ + u8 rx_gain_d; + u8 sigevm; + u8 resvd_0; + u8 antidx_anta:3; + u8 antidx_antb:3; + u8 resvd_1:2; +} __packed; + +struct rx_fwinfo_8821ae { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + s8 rxevm[2]; + s8 rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_8821ae { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:6; + u32 rsvd0:2; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rdg_en:1; + u32 bar_retryht:2; + u32 agg_break:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 bt_int:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_ssn:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 pwr_status:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 sw_offset30:8; + u32 sw_offset31:4; + u32 rsvd1:1; + u32 antsel_c:1; + u32 null_0:1; + u32 null_1:1; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_8821ae { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:6; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl8821ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc, + bool istx, u8 desc_name, u8 *val); +u64 rtl8821ae_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl8821ae_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); +void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/stats.c b/drivers/net/wireless/realtek/rtlwifi/stats.c new file mode 100644 index 000000000..504ca587a --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/stats.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "stats.h" +#include + +u8 rtl_query_rxpwrpercentage(s8 antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} +EXPORT_SYMBOL(rtl_query_rxpwrpercentage); + +u8 rtl_evm_db_to_percentage(s8 value) +{ + s8 ret_val = clamp(-value, 0, 33) * 3; + + if (ret_val == 99) + ret_val = 100; + + return ret_val; +} +EXPORT_SYMBOL(rtl_evm_db_to_percentage); + +static long rtl_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} +EXPORT_SYMBOL(rtl_signal_scale_mapping); + +static void rtl_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + u32 last_rssi, tmpval; + + if (!pstatus->packet_toself && !pstatus->packet_beacon) + return; + + rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all; + rtlpriv->stats.rssi_calculate_cnt++; + + if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = rtlpriv->stats.ui_rssi.elements[ + rtlpriv->stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = + pstatus->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, + (u8) tmpval); + pstatus->rssi = rtlpriv->stats.signal_strength; + + if (pstatus->is_cck) + return; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstatus->rx_mimo_signalstrength[rfpath]; + + } + if (pstatus->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath]; + rtlpriv->stats.rx_evm_dbm[rfpath] = + pstatus->rx_mimo_evm_dbm[rfpath]; + rtlpriv->stats.rx_cfo_short[rfpath] = + pstatus->cfo_short[rfpath]; + rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath]; + } +} + +static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; + if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * + 5 + pstatus->recvsignalpower + weighting) / 6; +} + +static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *drv_priv = NULL; + struct ieee80211_sta *sta = NULL; + long undec_sm_pwdb; + + rcu_read_lock(); + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + sta = rtl_find_sta(hw, pstatus->psaddr); + + /* adhoc or ap mode */ + if (sta) { + drv_priv = (struct rtl_sta_info *) sta->drv_priv; + undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + } + + if (undec_sm_pwdb < 0) + undec_sm_pwdb = pstatus->rx_pwdb_all; + if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undec_sm_pwdb = undec_sm_pwdb + 1; + } else { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + + if (sta) { + drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; + } else { + rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + } + rcu_read_unlock(); + + rtl_update_rxsignalstatistics(hw, pstatus); +} + +static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, n_stream, tmpval; + + if (pstatus->signalquality == 0) + return; + + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index]; + rtlpriv->stats.ui_link_quality.total_val -= last_evm; + } + rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; + rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index++] = + pstatus->signalquality; + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + for (n_stream = 0; n_stream < 2; n_stream++) { + if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { + if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { + rtlpriv->stats.rx_evm_percentage[n_stream] = + pstatus->rx_mimo_sig_qual[n_stream]; + } + rtlpriv->stats.rx_evm_percentage[n_stream] = + ((rtlpriv->stats.rx_evm_percentage[n_stream] + * (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } +} + +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus) +{ + + if (!pstatus->packet_matchbssid) + return; + + rtl_process_ui_rssi(hw, pstatus); + rtl_process_pwdb(hw, pstatus); + rtl_process_ui_link_quality(hw, pstatus); +} +EXPORT_SYMBOL(rtl_process_phyinfo); diff --git a/drivers/net/wireless/realtek/rtlwifi/stats.h b/drivers/net/wireless/realtek/rtlwifi/stats.h new file mode 100644 index 000000000..581590729 --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/stats.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_STATS_H__ +#define __RTL_STATS_H__ + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +/* Rx smooth factor */ +#define RX_SMOOTH_FACTOR 20 + +u8 rtl_query_rxpwrpercentage(s8 antpower); +u8 rtl_evm_db_to_percentage(s8 value); +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c new file mode 100644 index 000000000..9a64df9ee --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -0,0 +1,1075 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#include "wifi.h" +#include "core.h" +#include "usb.h" +#include "base.h" +#include "ps.h" +#include "rtl8192c/fw_common.h" +#include +#include + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("USB basic driver for rtlwifi"); + +#define REALTEK_USB_VENQT_READ 0xC0 +#define REALTEK_USB_VENQT_WRITE 0x40 +#define REALTEK_USB_VENQT_CMD_REQ 0x05 +#define REALTEK_USB_VENQT_CMD_IDX 0x00 + +#define MAX_USBCTRL_VENDORREQ_TIMES 10 + +static void _rtl_usb_cleanup_tx(struct ieee80211_hw *hw); + +static void _usbctrl_vendorreq_sync(struct usb_device *udev, u8 reqtype, + u16 value, void *pdata, u16 len) +{ + unsigned int pipe; + int status; + int vendorreq_times = 0; + static int count; + + if (reqtype == REALTEK_USB_VENQT_READ) + pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ + else + pipe = usb_sndctrlpipe(udev, 0); /* write_out */ + + do { + status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ, + reqtype, value, REALTEK_USB_VENQT_CMD_IDX, + pdata, len, 1000); + if (status < 0) { + /* firmware download is checksumed, don't retry */ + if ((value >= FW_8192C_START_ADDRESS && + value <= FW_8192C_END_ADDRESS)) + break; + } else { + break; + } + } while (++vendorreq_times < MAX_USBCTRL_VENDORREQ_TIMES); + + if (status < 0 && count++ < 4) + dev_err(&udev->dev, "reg 0x%x, usbctrl_vendorreq TimeOut! status:0x%x value=0x%x reqtype=0x%x\n", + value, status, *(u32 *)pdata, reqtype); +} + +static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len) +{ + struct device *dev = rtlpriv->io.dev; + struct usb_device *udev = to_usb_device(dev); + u16 wvalue; + __le32 *data; + unsigned long flags; + + spin_lock_irqsave(&rtlpriv->locks.usb_lock, flags); + if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) + rtlpriv->usb_data_index = 0; + data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + spin_unlock_irqrestore(&rtlpriv->locks.usb_lock, flags); + + wvalue = (u16)addr; + _usbctrl_vendorreq_sync(udev, REALTEK_USB_VENQT_READ, wvalue, data, len); + return le32_to_cpu(*data); +} + + +static void _usb_write_sync(struct rtl_priv *rtlpriv, u32 addr, u32 val, u16 len) +{ + struct device *dev = rtlpriv->io.dev; + struct usb_device *udev = to_usb_device(dev); + unsigned long flags; + __le32 *data; + u16 wvalue; + + spin_lock_irqsave(&rtlpriv->locks.usb_lock, flags); + if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) + rtlpriv->usb_data_index = 0; + data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + spin_unlock_irqrestore(&rtlpriv->locks.usb_lock, flags); + + wvalue = (u16)(addr & 0x0000ffff); + *data = cpu_to_le32(val); + + _usbctrl_vendorreq_sync(udev, REALTEK_USB_VENQT_WRITE, wvalue, data, len); +} + +static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return (u8)_usb_read_sync(rtlpriv, addr, 1); +} + +static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return (u16)_usb_read_sync(rtlpriv, addr, 2); +} + +static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + return _usb_read_sync(rtlpriv, addr, 4); +} + +static void _usb_write8_sync(struct rtl_priv *rtlpriv, u32 addr, u8 val) +{ + _usb_write_sync(rtlpriv, addr, val, 1); +} + +static void _usb_write16_sync(struct rtl_priv *rtlpriv, u32 addr, u16 val) +{ + _usb_write_sync(rtlpriv, addr, val, 2); +} + +static void _usb_write32_sync(struct rtl_priv *rtlpriv, u32 addr, u32 val) +{ + _usb_write_sync(rtlpriv, addr, val, 4); +} + +static void _usb_write_chunk_sync(struct rtl_priv *rtlpriv, u32 addr, + u32 length, u8 *data) +{ + struct usb_device *udev = to_usb_device(rtlpriv->io.dev); + + _usbctrl_vendorreq_sync(udev, REALTEK_USB_VENQT_WRITE, addr, data, length); +} + +static void _rtl_usb_io_handler_init(struct device *dev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->io.dev = dev; + mutex_init(&rtlpriv->io.bb_mutex); + rtlpriv->io.write8 = _usb_write8_sync; + rtlpriv->io.write16 = _usb_write16_sync; + rtlpriv->io.write32 = _usb_write32_sync; + rtlpriv->io.write_chunk = _usb_write_chunk_sync; + rtlpriv->io.read8 = _usb_read8_sync; + rtlpriv->io.read16 = _usb_read16_sync; + rtlpriv->io.read32 = _usb_read32_sync; +} + +static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw) +{ + struct rtl_priv __maybe_unused *rtlpriv = rtl_priv(hw); + + mutex_destroy(&rtlpriv->io.bb_mutex); +} + +/* Default aggregation handler. Do nothing and just return the oldest skb. */ +static struct sk_buff *_none_usb_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list) +{ + return skb_dequeue(list); +} + +#define IS_HIGH_SPEED_USB(udev) \ + ((USB_SPEED_HIGH == (udev)->speed) ? true : false) + +static int _rtl_usb_init_tx(struct ieee80211_hw *hw) +{ + u32 i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlusb->max_bulk_out_size = IS_HIGH_SPEED_USB(rtlusb->udev) + ? USB_HIGH_SPEED_BULK_SIZE + : USB_FULL_SPEED_BULK_SIZE; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); + + for (i = 0; i < __RTL_TXQ_NUM; i++) { + u32 ep_num = rtlusb->ep_map.ep_mapping[i]; + + if (!ep_num) { + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Invalid endpoint map setting!\n"); + return -EINVAL; + } + } + + rtlusb->usb_tx_post_hdl = + rtlpriv->cfg->usb_interface_cfg->usb_tx_post_hdl; + rtlusb->usb_tx_cleanup = + rtlpriv->cfg->usb_interface_cfg->usb_tx_cleanup; + rtlusb->usb_tx_aggregate_hdl = + (rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl) + ? rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl + : &_none_usb_tx_aggregate_hdl; + + init_usb_anchor(&rtlusb->tx_submitted); + for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { + skb_queue_head_init(&rtlusb->tx_skb_queue[i]); + init_usb_anchor(&rtlusb->tx_pending[i]); + } + return 0; +} + +static void _rtl_rx_work(struct tasklet_struct *t); + +static int _rtl_usb_init_rx(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->rx_max_size = rtlpriv->cfg->usb_interface_cfg->rx_max_size; + rtlusb->rx_urb_num = rtlpriv->cfg->usb_interface_cfg->rx_urb_num; + rtlusb->usb_rx_hdl = rtlpriv->cfg->usb_interface_cfg->usb_rx_hdl; + rtlusb->usb_rx_segregate_hdl = + rtlpriv->cfg->usb_interface_cfg->usb_rx_segregate_hdl; + + pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n", + rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); + init_usb_anchor(&rtlusb->rx_submitted); + init_usb_anchor(&rtlusb->rx_cleanup_urbs); + + skb_queue_head_init(&rtlusb->rx_queue); + tasklet_setup(&rtlusb->rx_work_tasklet, _rtl_rx_work); + + return 0; +} + +static int _rtl_usb_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + int err; + u8 epidx; + struct usb_interface *usb_intf = rtlusb->intf; + u8 epnums = usb_intf->cur_altsetting->desc.bNumEndpoints; + + rtlusb->out_ep_nums = rtlusb->in_ep_nums = 0; + for (epidx = 0; epidx < epnums; epidx++) { + struct usb_endpoint_descriptor *pep_desc; + + pep_desc = &usb_intf->cur_altsetting->endpoint[epidx].desc; + + if (usb_endpoint_dir_in(pep_desc)) { + if (usb_endpoint_xfer_bulk(pep_desc)) { + /* The vendor drivers assume there is only one + * bulk in ep and that it's the first in ep. + */ + if (rtlusb->in_ep_nums == 0) + rtlusb->in_ep = usb_endpoint_num(pep_desc); + else + pr_warn("%s: bulk in endpoint is not the first in endpoint\n", + __func__); + } + + rtlusb->in_ep_nums++; + } else if (usb_endpoint_dir_out(pep_desc)) { + if (rtlusb->out_ep_nums < RTL_USB_MAX_BULKOUT_NUM) { + if (usb_endpoint_xfer_bulk(pep_desc)) + rtlusb->out_eps[rtlusb->out_ep_nums] = + usb_endpoint_num(pep_desc); + } else { + pr_warn("%s: found more bulk out endpoints than the expected %d\n", + __func__, RTL_USB_MAX_BULKOUT_NUM); + } + + rtlusb->out_ep_nums++; + } + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", + pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, + pep_desc->bInterval); + } + + if (rtlusb->out_ep_nums == 0) { + pr_err("No output end points found\n"); + return -EINVAL; + } + /* usb endpoint mapping */ + err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); + if (err) + return err; + + rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; + + err = _rtl_usb_init_tx(hw); + if (err) + return err; + + err = _rtl_usb_init_rx(hw); + if (err) + goto err_out; + + return 0; + +err_out: + _rtl_usb_cleanup_tx(hw); + return err; +} + +static void rtl_usb_init_sw(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlhal->hw = hw; + ppsc->inactiveps = false; + ppsc->leisure_ps = false; + ppsc->fwctrl_lps = false; + ppsc->reg_fwctrl_lps = 3; + ppsc->reg_max_lps_awakeintvl = 5; + ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; + + /* IBSS */ + mac->beacon_interval = 100; + + /* AMPDU */ + mac->min_space_cfg = 0; + mac->max_mss_density = 0; + + /* set sane AMPDU defaults */ + mac->current_ampdu_density = 7; + mac->current_ampdu_factor = 3; + + /* QOS */ + rtlusb->acm_method = EACMWAY2_SW; + + /* IRQ */ + /* HIMR - turn all on */ + rtlusb->irq_mask[0] = 0xFFFFFFFF; + /* HIMR_EX - turn all on */ + rtlusb->irq_mask[1] = 0xFFFFFFFF; + rtlusb->disablehwsm = true; +} + +static void _rtl_rx_completed(struct urb *urb); + +static int _rtl_prep_rx_urb(struct ieee80211_hw *hw, struct rtl_usb *rtlusb, + struct urb *urb, gfp_t gfp_mask) +{ + void *buf; + + buf = usb_alloc_coherent(rtlusb->udev, rtlusb->rx_max_size, gfp_mask, + &urb->transfer_dma); + if (!buf) { + pr_err("Failed to usb_alloc_coherent!!\n"); + return -ENOMEM; + } + + usb_fill_bulk_urb(urb, rtlusb->udev, + usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), + buf, rtlusb->rx_max_size, _rtl_rx_completed, rtlusb); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + return 0; +} + +static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *rxdesc = skb->data; + struct ieee80211_hdr *hdr; + bool unicast = false; + __le16 fc; + struct ieee80211_rx_status rx_status = {0}; + struct rtl_stats stats = { + .signal = 0, + .rate = 0, + }; + + skb_pull(skb, RTL_RX_DESC_SIZE); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); + skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); + hdr = rtl_get_hdr(skb); + fc = hdr->frame_control; + if (!stats.crc) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + /*TODO*/; + } else if (is_multicast_ether_addr(hdr->addr1)) { + /*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + /* static bcn for roaming */ + rtl_beacon_statistic(hw, skb); + } +} + +static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *rxdesc = skb->data; + struct ieee80211_hdr *hdr; + bool unicast = false; + __le16 fc; + struct ieee80211_rx_status rx_status = {0}; + struct rtl_stats stats = { + .signal = 0, + .rate = 0, + }; + + skb_pull(skb, RTL_RX_DESC_SIZE); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); + skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); + hdr = rtl_get_hdr(skb); + fc = hdr->frame_control; + if (!stats.crc) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + /*TODO*/; + } else if (is_multicast_ether_addr(hdr->addr1)) { + /*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + + /* static bcn for roaming */ + rtl_beacon_statistic(hw, skb); + + if (likely(rtl_action_proc(hw, skb, false))) + ieee80211_rx(hw, skb); + else + dev_kfree_skb_any(skb); + } else { + dev_kfree_skb_any(skb); + } +} + +static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct sk_buff *_skb; + struct sk_buff_head rx_queue; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + skb_queue_head_init(&rx_queue); + if (rtlusb->usb_rx_segregate_hdl) + rtlusb->usb_rx_segregate_hdl(hw, skb, &rx_queue); + WARN_ON(skb_queue_empty(&rx_queue)); + while (!skb_queue_empty(&rx_queue)) { + _skb = skb_dequeue(&rx_queue); + _rtl_usb_rx_process_agg(hw, _skb); + ieee80211_rx(hw, _skb); + } +} + +#define __RX_SKB_MAX_QUEUED 64 + +static void _rtl_rx_work(struct tasklet_struct *t) +{ + struct rtl_usb *rtlusb = from_tasklet(rtlusb, t, rx_work_tasklet); + struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&rtlusb->rx_queue))) { + if (unlikely(IS_USB_STOP(rtlusb))) { + dev_kfree_skb_any(skb); + continue; + } + + if (likely(!rtlusb->usb_rx_segregate_hdl)) { + _rtl_usb_rx_process_noagg(hw, skb); + } else { + /* TO DO */ + _rtl_rx_pre_process(hw, skb); + pr_err("rx agg not supported\n"); + } + } +} + +static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr, + unsigned int len) +{ +#if NET_IP_ALIGN != 0 + unsigned int padding = 0; +#endif + + /* make function no-op when possible */ + if (NET_IP_ALIGN == 0 || len < sizeof(*hdr)) + return 0; + +#if NET_IP_ALIGN != 0 + /* alignment calculation as in lbtf_rx() / carl9170_rx_copy_data() */ + /* TODO: deduplicate common code, define helper function instead? */ + + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + + padding ^= NET_IP_ALIGN; + + /* Input might be invalid, avoid accessing memory outside + * the buffer. + */ + if ((unsigned long)qc - (unsigned long)hdr < len && + *qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) + padding ^= NET_IP_ALIGN; + } + + if (ieee80211_has_a4(hdr->frame_control)) + padding ^= NET_IP_ALIGN; + + return padding; +#endif +} + +#define __RADIO_TAP_SIZE_RSV 32 + +static void _rtl_rx_completed(struct urb *_urb) +{ + struct rtl_usb *rtlusb = (struct rtl_usb *)_urb->context; + int err = 0; + + if (unlikely(IS_USB_STOP(rtlusb))) + goto free; + + if (likely(0 == _urb->status)) { + unsigned int padding; + struct sk_buff *skb; + unsigned int qlen; + unsigned int size = _urb->actual_length; + struct ieee80211_hdr *hdr; + + if (size < RTL_RX_DESC_SIZE + sizeof(struct ieee80211_hdr)) { + pr_err("Too short packet from bulk IN! (len: %d)\n", + size); + goto resubmit; + } + + qlen = skb_queue_len(&rtlusb->rx_queue); + if (qlen >= __RX_SKB_MAX_QUEUED) { + pr_err("Pending RX skbuff queue full! (qlen: %d)\n", + qlen); + goto resubmit; + } + + hdr = (void *)(_urb->transfer_buffer + RTL_RX_DESC_SIZE); + padding = _rtl_rx_get_padding(hdr, size - RTL_RX_DESC_SIZE); + + skb = dev_alloc_skb(size + __RADIO_TAP_SIZE_RSV + padding); + if (!skb) { + pr_err("Can't allocate skb for bulk IN!\n"); + goto resubmit; + } + + _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); + + /* Make sure the payload data is 4 byte aligned. */ + skb_reserve(skb, padding); + + /* reserve some space for mac80211's radiotap */ + skb_reserve(skb, __RADIO_TAP_SIZE_RSV); + + skb_put_data(skb, _urb->transfer_buffer, size); + + skb_queue_tail(&rtlusb->rx_queue, skb); + tasklet_schedule(&rtlusb->rx_work_tasklet); + + goto resubmit; + } + + switch (_urb->status) { + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + goto free; + default: + break; + } + +resubmit: + usb_anchor_urb(_urb, &rtlusb->rx_submitted); + err = usb_submit_urb(_urb, GFP_ATOMIC); + if (unlikely(err)) { + usb_unanchor_urb(_urb); + goto free; + } + return; + +free: + /* On some architectures, usb_free_coherent must not be called from + * hardirq context. Queue urb to cleanup list. + */ + usb_anchor_urb(_urb, &rtlusb->rx_cleanup_urbs); +} + +#undef __RADIO_TAP_SIZE_RSV + +static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct urb *urb; + + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); + + skb_queue_purge(&rtlusb->rx_queue); + + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + usb_free_urb(urb); + } +} + +static int _rtl_usb_receive(struct ieee80211_hw *hw) +{ + struct urb *urb; + int err; + int i; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + WARN_ON(0 == rtlusb->rx_urb_num); + /* 1600 == 1514 + max WLAN header + rtk info */ + WARN_ON(rtlusb->rx_max_size < 1600); + + for (i = 0; i < rtlusb->rx_urb_num; i++) { + err = -ENOMEM; + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + goto err_out; + + err = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); + if (err < 0) { + pr_err("Failed to prep_rx_urb!!\n"); + usb_free_urb(urb); + goto err_out; + } + + usb_anchor_urb(urb, &rtlusb->rx_submitted); + err = usb_submit_urb(urb, GFP_KERNEL); + if (err) { + usb_unanchor_urb(urb); + usb_free_urb(urb); + goto err_out; + } + usb_free_urb(urb); + } + return 0; + +err_out: + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + return err; +} + +static int rtl_usb_start(struct ieee80211_hw *hw) +{ + int err; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + err = rtlpriv->cfg->ops->hw_init(hw); + if (!err) { + rtl_init_rx_config(hw); + + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); + + /* Start bulk IN */ + err = _rtl_usb_receive(hw); + } + + return err; +} + +/*======================= tx =========================================*/ +static void _rtl_usb_cleanup_tx(struct ieee80211_hw *hw) +{ + u32 i; + struct sk_buff *_skb; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct ieee80211_tx_info *txinfo; + + for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { + while ((_skb = skb_dequeue(&rtlusb->tx_skb_queue[i]))) { + rtlusb->usb_tx_cleanup(hw, _skb); + txinfo = IEEE80211_SKB_CB(_skb); + ieee80211_tx_info_clear_status(txinfo); + txinfo->flags |= IEEE80211_TX_STAT_ACK; + ieee80211_tx_status_irqsafe(hw, _skb); + } + usb_kill_anchored_urbs(&rtlusb->tx_pending[i]); + } + usb_kill_anchored_urbs(&rtlusb->tx_submitted); +} + +static void rtl_usb_cleanup(struct ieee80211_hw *hw) +{ + _rtl_usb_cleanup_rx(hw); + _rtl_usb_cleanup_tx(hw); +} + +/* We may add some struct into struct rtl_usb later. Do deinit here. */ +static void rtl_usb_deinit(struct ieee80211_hw *hw) +{ + rtl_usb_cleanup(hw); +} + +static void rtl_usb_stop(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct urb *urb; + + /* should after adapter start and interrupt enable. */ + set_hal_stop(rtlhal); + cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); + /* Enable software */ + SET_USB_STOP(rtlusb); + + /* free pre-allocated URBs from rtl_usb_start() */ + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); + cancel_work_sync(&rtlpriv->works.update_beacon_work); + + flush_workqueue(rtlpriv->works.rtl_wq); + + skb_queue_purge(&rtlusb->rx_queue); + + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + usb_free_urb(urb); + } + + rtlpriv->cfg->ops->hw_disable(hw); +} + +static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) +{ + int err; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + usb_anchor_urb(_urb, &rtlusb->tx_submitted); + err = usb_submit_urb(_urb, GFP_ATOMIC); + if (err < 0) { + struct sk_buff *skb; + + pr_err("Failed to submit urb\n"); + usb_unanchor_urb(_urb); + skb = (struct sk_buff *)_urb->context; + kfree_skb(skb); + } + usb_free_urb(_urb); +} + +static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct ieee80211_tx_info *txinfo; + + rtlusb->usb_tx_post_hdl(hw, urb, skb); + skb_pull(skb, RTL_TX_HEADER_SIZE); + txinfo = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(txinfo); + txinfo->flags |= IEEE80211_TX_STAT_ACK; + + if (urb->status) { + pr_err("Urb has error status 0x%X\n", urb->status); + goto out; + } + /* TODO: statistics */ +out: + ieee80211_tx_status_irqsafe(hw, skb); + return urb->status; +} + +static void _rtl_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; + struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); + int err; + + if (unlikely(IS_USB_STOP(rtlusb))) + return; + err = _usb_tx_post(hw, urb, skb); + if (err) { + /* Ignore error and keep issuiing other urbs */ + return; + } +} + +static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, + struct sk_buff *skb, u32 ep_num) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct urb *_urb; + + WARN_ON(NULL == skb); + _urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!_urb) + return NULL; + _rtl_install_trx_info(rtlusb, skb, ep_num); + usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, + ep_num), skb->data, skb->len, _rtl_tx_complete, skb); + _urb->transfer_flags |= URB_ZERO_PACKET; + return _urb; +} + +static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, + enum rtl_txq qnum) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + u32 ep_num; + struct urb *_urb = NULL; + + WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); + if (unlikely(IS_USB_STOP(rtlusb))) { + pr_err("USB device is stopping...\n"); + kfree_skb(skb); + return; + } + ep_num = rtlusb->ep_map.ep_mapping[qnum]; + _urb = _rtl_usb_tx_urb_setup(hw, skb, ep_num); + if (unlikely(!_urb)) { + pr_err("Can't allocate urb. Drop skb!\n"); + kfree_skb(skb); + return; + } + _rtl_submit_tx_urb(hw, _urb); +} + +static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + u16 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_tx_desc *pdesc = NULL; + struct rtl_tcb_desc tcb_desc; + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + u8 *pda_addr = hdr->addr1; + + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + if (ieee80211_is_auth(fc)) { + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + } + + if (rtlpriv->psc.sw_ps_enabled) { + if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && + !ieee80211_has_pm(fc)) + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); + } + + rtl_action_proc(hw, skb, true); + if (is_multicast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesmulticast += skb->len; + else if (is_broadcast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesbroadcast += skb->len; + else + rtlpriv->stats.txbytesunicast += skb->len; + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, NULL, info, sta, skb, + hw_queue, &tcb_desc); + if (ieee80211_is_data(fc)) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); +} + +static int rtl_usb_tx(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + struct rtl_tcb_desc *dummy) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = hdr->frame_control; + u16 hw_queue; + + if (unlikely(is_hal_stop(rtlhal))) + goto err_free; + hw_queue = rtlusb->usb_mq_to_hwq(fc, skb_get_queue_mapping(skb)); + _rtl_usb_tx_preprocess(hw, sta, skb, hw_queue); + _rtl_usb_transmit(hw, skb, hw_queue); + return NETDEV_TX_OK; + +err_free: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + return false; +} + +static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, fill_h2c_cmd); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask); +} + +static const struct rtl_intf_ops rtl_usb_ops = { + .adapter_start = rtl_usb_start, + .adapter_stop = rtl_usb_stop, + .adapter_tx = rtl_usb_tx, + .waitq_insert = rtl_usb_tx_chk_waitq_insert, +}; + +int rtl_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id, + const struct rtl_hal_cfg *rtl_hal_cfg) +{ + int err; + struct ieee80211_hw *hw = NULL; + struct rtl_priv *rtlpriv = NULL; + struct usb_device *udev; + struct rtl_usb_priv *usb_priv; + + hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + + sizeof(struct rtl_usb_priv), &rtl_ops); + if (!hw) { + pr_warn("rtl_usb: ieee80211 alloc failed\n"); + return -ENOMEM; + } + rtlpriv = hw->priv; + rtlpriv->hw = hw; + rtlpriv->usb_data = kcalloc(RTL_USB_MAX_RX_COUNT, sizeof(u32), + GFP_KERNEL); + if (!rtlpriv->usb_data) { + ieee80211_free_hw(hw); + return -ENOMEM; + } + + /* this spin lock must be initialized early */ + spin_lock_init(&rtlpriv->locks.usb_lock); + INIT_WORK(&rtlpriv->works.fill_h2c_cmd, + rtl_fill_h2c_cmd_work_callback); + INIT_WORK(&rtlpriv->works.lps_change_work, + rtl_lps_change_work_callback); + INIT_WORK(&rtlpriv->works.update_beacon_work, + rtl_update_beacon_work_callback); + + rtlpriv->usb_data_index = 0; + init_completion(&rtlpriv->firmware_loading_complete); + SET_IEEE80211_DEV(hw, &intf->dev); + udev = interface_to_usbdev(intf); + usb_priv = rtl_usbpriv(hw); + memset(usb_priv, 0, sizeof(*usb_priv)); + usb_priv->dev.intf = intf; + usb_priv->dev.udev = udev; + usb_set_intfdata(intf, hw); + /* For dual MAC RTL8192DU, which has two interfaces. */ + rtlpriv->rtlhal.interfaceindex = + intf->altsetting[0].desc.bInterfaceNumber; + /* init cfg & intf_ops */ + rtlpriv->rtlhal.interface = INTF_USB; + rtlpriv->cfg = rtl_hal_cfg; + rtlpriv->intf_ops = &rtl_usb_ops; + /* Init IO handler */ + _rtl_usb_io_handler_init(&udev->dev, hw); + rtlpriv->cfg->ops->read_chip_version(hw); + /*like read eeprom and so on */ + rtlpriv->cfg->ops->read_eeprom_info(hw); + err = _rtl_usb_init(hw); + if (err) + goto error_out2; + rtl_usb_init_sw(hw); + /* Init mac80211 sw */ + err = rtl_init_core(hw); + if (err) { + pr_err("Can't allocate sw for mac80211\n"); + goto error_out2; + } + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + pr_err("Can't init_sw_vars\n"); + goto error_out; + } + rtl_init_sw_leds(hw); + + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); + goto error_init_vars; + } + rtlpriv->mac80211.mac80211_registered = 1; + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + +error_init_vars: + wait_for_completion(&rtlpriv->firmware_loading_complete); + rtlpriv->cfg->ops->deinit_sw_vars(hw); +error_out: + rtl_usb_deinit(hw); + rtl_deinit_core(hw); +error_out2: + _rtl_usb_io_handler_release(hw); + kfree(rtlpriv->usb_data); + ieee80211_free_hw(hw); + return -ENODEV; +} +EXPORT_SYMBOL(rtl_usb_probe); + +void rtl_usb_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + if (unlikely(!rtlpriv)) + return; + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); + clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + /*ieee80211_unregister_hw will call ops_stop */ + if (rtlmac->mac80211_registered == 1) { + ieee80211_unregister_hw(hw); + rtlmac->mac80211_registered = 0; + } else { + rtl_deinit_deferred_work(hw, false); + rtlpriv->intf_ops->adapter_stop(hw); + } + /*deinit rfkill */ + /* rtl_deinit_rfkill(hw); */ + rtl_usb_deinit(hw); + rtl_deinit_core(hw); + kfree(rtlpriv->usb_data); + rtlpriv->cfg->ops->deinit_sw_vars(hw); + _rtl_usb_io_handler_release(hw); + usb_set_intfdata(intf, NULL); + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtl_usb_disconnect); diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.h b/drivers/net/wireless/realtek/rtlwifi/usb.h new file mode 100644 index 000000000..b873bbc9c --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/usb.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_USB_H__ +#define __RTL_USB_H__ + +#include + +#define RTL_RX_DESC_SIZE 24 + +#define RTL_USB_DEVICE(vend, prod, cfg) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .driver_info = (kernel_ulong_t)&(cfg) + +#define USB_HIGH_SPEED_BULK_SIZE 512 +#define USB_FULL_SPEED_BULK_SIZE 64 + +#define RTL_USB_MAX_TXQ_NUM 4 /* max tx queue */ +#define RTL_USB_MAX_EP_NUM 6 /* max ep number */ +#define RTL_USB_MAX_BULKOUT_NUM 4 +#define RTL_USB_MAX_TX_URBS_NUM 8 + +enum rtl_txq { + /* These definitions shall be consistent with value + * returned by skb_get_queue_mapping + *------------------------------------*/ + RTL_TXQ_BK, + RTL_TXQ_BE, + RTL_TXQ_VI, + RTL_TXQ_VO, + /*------------------------------------*/ + RTL_TXQ_BCN, + RTL_TXQ_MGT, + RTL_TXQ_HI, + + /* Must be last */ + __RTL_TXQ_NUM, +}; + +struct rtl_ep_map { + u32 ep_mapping[__RTL_TXQ_NUM]; +}; + +struct _trx_info { + struct rtl_usb *rtlusb; + u32 ep_num; +}; + +static inline void _rtl_install_trx_info(struct rtl_usb *rtlusb, + struct sk_buff *skb, + u32 ep_num) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + info->rate_driver_data[0] = rtlusb; + info->rate_driver_data[1] = (void *)(__kernel_size_t)ep_num; +} + +/* Add suspend/resume later */ +enum rtl_usb_state { + USB_STATE_STOP = 0, + USB_STATE_START = 1, +}; + +#define IS_USB_STOP(rtlusb_ptr) (USB_STATE_STOP == (rtlusb_ptr)->state) +#define IS_USB_START(rtlusb_ptr) (USB_STATE_START == (rtlusb_ptr)->state) +#define SET_USB_STOP(rtlusb_ptr) \ + do { \ + (rtlusb_ptr)->state = USB_STATE_STOP; \ + } while (0) + +#define SET_USB_START(rtlusb_ptr) \ + do { \ + (rtlusb_ptr)->state = USB_STATE_START; \ + } while (0) + +struct rtl_usb { + struct usb_device *udev; + struct usb_interface *intf; + enum rtl_usb_state state; + + /* Bcn control register setting */ + u32 reg_bcn_ctrl_val; + /* for 88/92cu card disable */ + u8 disablehwsm; + /*QOS & EDCA */ + enum acm_method acm_method; + /* irq . HIMR,HIMR_EX */ + u32 irq_mask[2]; + bool irq_enabled; + + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); + + /* Tx */ + u8 out_ep_nums ; + u8 out_eps[RTL_USB_MAX_BULKOUT_NUM]; + u8 out_queue_sel; + struct rtl_ep_map ep_map; + + u32 max_bulk_out_size; + u32 tx_submitted_urbs; + struct sk_buff_head tx_skb_queue[RTL_USB_MAX_EP_NUM]; + + struct usb_anchor tx_pending[RTL_USB_MAX_EP_NUM]; + struct usb_anchor tx_submitted; + + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, + struct urb *, struct sk_buff *); + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + + /* Rx */ + u8 in_ep_nums; + u32 in_ep; /* Bulk IN endpoint number */ + u32 rx_max_size; /* Bulk IN max buffer size */ + u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ + struct usb_anchor rx_submitted; + struct usb_anchor rx_cleanup_urbs; + struct tasklet_struct rx_work_tasklet; + struct sk_buff_head rx_queue; + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); +}; + +struct rtl_usb_priv { + struct bt_coexist_info bt_coexist; + struct rtl_usb dev; +}; + +#define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv)) +#define rtl_usbdev(usbpriv) (&((usbpriv)->dev)) + +int rtl_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id, + const struct rtl_hal_cfg *rtl92cu_hal_cfg); +void rtl_usb_disconnect(struct usb_interface *intf); + +#endif diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h new file mode 100644 index 000000000..f1830ddcd --- /dev/null +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -0,0 +1,3038 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2009-2012 Realtek Corporation.*/ + +#ifndef __RTL_WIFI_H__ +#define __RTL_WIFI_H__ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKH3BYTES 0xffffff00 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +/* For dual MAC RTL8192DU */ +#define MAC0_ACCESS_PHY1 0x4000 +#define MAC1_ACCESS_PHY0 0x2000 + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT(28) +#define RF_CHANGE_BY_PS BIT(29) +#define RF_CHANGE_BY_HW BIT(30) +#define RF_CHANGE_BY_SW BIT(31) + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 +#define IQK_THRESHOLD 8 + +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +/* QoS related. */ +/*aci: 0x00 Best Effort*/ +/*aci: 0x01 Background*/ +/*aci: 0x10 Video*/ +/*aci: 0x11 Voice*/ +/*Max: define total number.*/ +#define AC0_BE 0 +#define AC1_BK 1 +#define AC2_VI 2 +#define AC3_VO 3 +#define AC_MAX 4 +#define QOS_QUEUE_NUM 4 +#define RTL_MAC80211_NUM_QUEUE 5 +#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 +#define RTL_USB_MAX_RX_COUNT 100 +#define QBSS_LOAD_SIZE 5 +#define MAX_WMMELE_LENGTH 64 +#define ASPM_L1_LATENCY 7 + +#define TOTAL_CAM_ENTRY 32 + +/*slot time for 11g. */ +#define RTL_SLOT_TIME_9 9 +#define RTL_SLOT_TIME_20 20 + +/*related to tcp/ip. */ +#define SNAP_SIZE 6 +#define PROTOC_TYPE_SIZE 2 + +/*related with 802.11 frame*/ +#define MAC80211_3ADDR_LEN 24 +#define MAC80211_4ADDR_LEN 30 + +#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ +#define CHANNEL_MAX_NUMBER_2G 14 +#define CHANNEL_MAX_NUMBER_5G 49 /* Please refer to + *"phy_GetChnlGroup8812A" and + * "Hal_ReadTxPowerInfo8812A" + */ +#define CHANNEL_MAX_NUMBER_5G_80M 7 +#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ +#define MAX_PG_GROUP 13 +#define CHANNEL_GROUP_MAX_2G 3 +#define CHANNEL_GROUP_IDX_5GL 3 +#define CHANNEL_GROUP_IDX_5GM 6 +#define CHANNEL_GROUP_IDX_5GH 9 +#define CHANNEL_GROUP_MAX_5G 9 +#define AVG_THERMAL_NUM 8 +#define AVG_THERMAL_NUM_88E 4 +#define AVG_THERMAL_NUM_8723BE 4 +#define MAX_TID_COUNT 9 + +/* for early mode */ +#define FCS_LEN 4 +#define EM_HDR_LEN 8 + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + H2C_MACID_PS_MODE = 7, + H2C_P2P_PS_OFFLOAD = 8, + H2C_MAC_MODE_SEL = 9, + H2C_PWRM = 15, + H2C_P2P_PS_CTW_CMD = 24, + MAX_H2CCMD +}; + +enum { + H2C_BT_PORT_ID = 0x71, +}; + +enum rtl_c2h_evt_v1 { + C2H_DBG = 0, + C2H_LB = 1, + C2H_TXBF = 2, + C2H_TX_REPORT = 3, + C2H_BT_INFO = 9, + C2H_BT_MP = 11, + C2H_RA_RPT = 12, + + C2H_FW_SWCHNL = 0x10, + C2H_IQK_FINISH = 0x11, + + C2H_EXT_V2 = 0xFF, +}; + +enum rtl_c2h_evt_v2 { + C2H_V2_CCX_RPT = 0x0F, +}; + +#define GET_C2H_CMD_ID(c2h) ({u8 *__c2h = c2h; __c2h[0]; }) +#define GET_C2H_SEQ(c2h) ({u8 *__c2h = c2h; __c2h[1]; }) +#define C2H_DATA_OFFSET 2 +#define GET_C2H_DATA_PTR(c2h) ({u8 *__c2h = c2h; &__c2h[C2H_DATA_OFFSET]; }) + +#define GET_TX_REPORT_SN_V1(c2h) (c2h[6]) +#define GET_TX_REPORT_ST_V1(c2h) (c2h[0] & 0xC0) +#define GET_TX_REPORT_RETRY_V1(c2h) (c2h[2] & 0x3F) +#define GET_TX_REPORT_SN_V2(c2h) (c2h[6]) +#define GET_TX_REPORT_ST_V2(c2h) (c2h[7] & 0xC0) +#define GET_TX_REPORT_RETRY_V2(c2h) (c2h[8] & 0x3F) + +#define MAX_TX_COUNT 4 +#define MAX_REGULATION_NUM 4 +#define MAX_RF_PATH_NUM 4 +#define MAX_RATE_SECTION_NUM 6 /* = MAX_RATE_SECTION */ +#define MAX_2_4G_BANDWIDTH_NUM 4 +#define MAX_5G_BANDWIDTH_NUM 4 +#define MAX_RF_PATH 4 +#define MAX_CHNL_GROUP_24G 6 +#define MAX_CHNL_GROUP_5G 14 + +#define TX_PWR_BY_RATE_NUM_BAND 2 +#define TX_PWR_BY_RATE_NUM_RF 4 +#define TX_PWR_BY_RATE_NUM_SECTION 12 +#define TX_PWR_BY_RATE_NUM_RATE 84 /* >= TX_PWR_BY_RATE_NUM_SECTION */ +#define MAX_BASE_NUM_IN_PHY_REG_PG_24G 6 /* MAX_RATE_SECTION */ +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 5 /* MAX_RATE_SECTION -1 */ + +#define BUFDESC_SEG_NUM 1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */ + +#define DEL_SW_IDX_SZ 30 + +/* For now, it's just for 8192ee + * but not OK yet, keep it 0 + */ +#define RTL8192EE_SEG_NUM BUFDESC_SEG_NUM + +enum rf_tx_num { + RF_1TX = 0, + RF_2TX, + RF_MAX_TX_NUM, + RF_TX_NUM_NONIMPLEMENT, +}; + +#define PACKET_NORMAL 0 +#define PACKET_DHCP 1 +#define PACKET_ARP 2 +#define PACKET_EAPOL 3 + +#define MAX_SUPPORT_WOL_PATTERN_NUM 16 +#define RSVD_WOL_PATTERN_NUM 1 +#define WKFMCAM_ADDR_NUM 6 +#define WKFMCAM_SIZE 24 + +#define MAX_WOL_BIT_MASK_SIZE 16 +/* MIN LEN keeps 13 here */ +#define MIN_WOL_PATTERN_SIZE 13 +#define MAX_WOL_PATTERN_SIZE 128 + +#define WAKE_ON_MAGIC_PACKET BIT(0) +#define WAKE_ON_PATTERN_MATCH BIT(1) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_AP_LOST BIT(4) +#define WOL_REASON_MAGIC_PKT BIT(5) +#define WOL_REASON_UNICAST_PKT BIT(6) +#define WOL_REASON_PATTERN_PKT BIT(7) +#define WOL_REASON_RTD3_SSID_MATCH BIT(8) +#define WOL_REASON_REALWOW_V2_WAKEUPPKT BIT(9) +#define WOL_REASON_REALWOW_V2_ACKLOST BIT(10) + +struct rtlwifi_firmware_header { + __le16 signature; + u8 category; + u8 function; + __le16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + __le16 ramcodesize; + __le16 rsvd2; + __le32 svnindex; + __le32 rsvd3; + __le32 rsvd4; + __le32 rsvd5; +}; + +struct txpower_info_2g { + u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + /*If only one tx, only BW20 and OFDM are used.*/ + u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +struct txpower_info_5g { + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G]; + /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/ + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +enum rate_section { + CCK = 0, + OFDM, + HT_MCS0_MCS7, + HT_MCS8_MCS15, + VHT_1SSMCS0_1SSMCS9, + VHT_2SSMCS0_2SSMCS9, + MAX_RATE_SECTION, +}; + +enum intf_type { + INTF_PCI = 0, + INTF_USB = 1, +}; + +enum radio_path { + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, +}; + +enum radio_mask { + RF_MASK_A = BIT(0), + RF_MASK_B = BIT(1), + RF_MASK_C = BIT(2), + RF_MASK_D = BIT(3), +}; + +enum regulation_txpwr_lmt { + TXPWR_LMT_FCC = 0, + TXPWR_LMT_MKK = 1, + TXPWR_LMT_ETSI = 2, + TXPWR_LMT_WW = 3, + + TXPWR_LMT_MAX_REGULATION_NUM = 4 +}; + +enum rt_eeprom_type { + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}; + +enum ttl_status { + RTL_STATUS_INTERFACE_START = 0, +}; + +enum hardware_type { + HARDWARE_TYPE_RTL8192E, + HARDWARE_TYPE_RTL8192U, + HARDWARE_TYPE_RTL8192SE, + HARDWARE_TYPE_RTL8192SU, + HARDWARE_TYPE_RTL8192CE, + HARDWARE_TYPE_RTL8192CU, + HARDWARE_TYPE_RTL8192DE, + HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723AE, + HARDWARE_TYPE_RTL8723U, + HARDWARE_TYPE_RTL8188EE, + HARDWARE_TYPE_RTL8723BE, + HARDWARE_TYPE_RTL8192EE, + HARDWARE_TYPE_RTL8821AE, + HARDWARE_TYPE_RTL8812AE, + HARDWARE_TYPE_RTL8822BE, + + /* keep it last */ + HARDWARE_TYPE_NUM +}; + +#define RTL_HW_TYPE(rtlpriv) (rtl_hal((struct rtl_priv *)rtlpriv)->hw_type) +#define IS_NEW_GENERATION_IC(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) >= HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8192CE(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8812(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8812AE) +#define IS_HARDWARE_TYPE_8821(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8821AE) +#define IS_HARDWARE_TYPE_8723A(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723AE) +#define IS_HARDWARE_TYPE_8723B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723BE) +#define IS_HARDWARE_TYPE_8192E(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8822B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8822BE) + +#define RX_HAL_IS_CCK_RATE(rxmcs) \ + ((rxmcs) == DESC_RATE1M || \ + (rxmcs) == DESC_RATE2M || \ + (rxmcs) == DESC_RATE5_5M || \ + (rxmcs) == DESC_RATE11M) + +enum scan_operation_backup_opt { + SCAN_OPT_BACKUP = 0, + SCAN_OPT_BACKUP_BAND0 = 0, + SCAN_OPT_BACKUP_BAND1, + SCAN_OPT_RESTORE, + SCAN_OPT_MAX +}; + +/*RF state.*/ +enum rf_pwrstate { + ERFON, + ERFSLEEP, + ERFOFF +}; + +struct bb_reg_def { + u32 rfintfs; + u32 rfintfi; + u32 rfintfo; + u32 rfintfe; + u32 rf3wire_offset; + u32 rflssi_select; + u32 rftxgain_stage; + u32 rfhssi_para1; + u32 rfhssi_para2; + u32 rfsw_ctrl; + u32 rfagc_control1; + u32 rfagc_control2; + u32 rfrxiq_imbal; + u32 rfrx_afe; + u32 rftxiq_imbal; + u32 rftx_afe; + u32 rf_rb; /* rflssi_readback */ + u32 rf_rbpi; /* rflssi_readbackpi */ +}; + +enum io_type { + IO_CMD_PAUSE_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1, + IO_CMD_RESUME_DM_BY_SCAN = 2, +}; + +enum hw_variables { + HW_VAR_ETHER_ADDR = 0x0, + HW_VAR_MULTICAST_REG = 0x1, + HW_VAR_BASIC_RATE = 0x2, + HW_VAR_BSSID = 0x3, + HW_VAR_MEDIA_STATUS = 0x4, + HW_VAR_SECURITY_CONF = 0x5, + HW_VAR_BEACON_INTERVAL = 0x6, + HW_VAR_ATIM_WINDOW = 0x7, + HW_VAR_LISTEN_INTERVAL = 0x8, + HW_VAR_CS_COUNTER = 0x9, + HW_VAR_DEFAULTKEY0 = 0xa, + HW_VAR_DEFAULTKEY1 = 0xb, + HW_VAR_DEFAULTKEY2 = 0xc, + HW_VAR_DEFAULTKEY3 = 0xd, + HW_VAR_SIFS = 0xe, + HW_VAR_R2T_SIFS = 0xf, + HW_VAR_DIFS = 0x10, + HW_VAR_EIFS = 0x11, + HW_VAR_SLOT_TIME = 0x12, + HW_VAR_ACK_PREAMBLE = 0x13, + HW_VAR_CW_CONFIG = 0x14, + HW_VAR_CW_VALUES = 0x15, + HW_VAR_RATE_FALLBACK_CONTROL = 0x16, + HW_VAR_CONTENTION_WINDOW = 0x17, + HW_VAR_RETRY_COUNT = 0x18, + HW_VAR_TR_SWITCH = 0x19, + HW_VAR_COMMAND = 0x1a, + HW_VAR_WPA_CONFIG = 0x1b, + HW_VAR_AMPDU_MIN_SPACE = 0x1c, + HW_VAR_SHORTGI_DENSITY = 0x1d, + HW_VAR_AMPDU_FACTOR = 0x1e, + HW_VAR_MCS_RATE_AVAILABLE = 0x1f, + HW_VAR_AC_PARAM = 0x20, + HW_VAR_ACM_CTRL = 0x21, + HW_VAR_DIS_REQ_QSIZE = 0x22, + HW_VAR_CCX_CHNL_LOAD = 0x23, + HW_VAR_CCX_NOISE_HISTOGRAM = 0x24, + HW_VAR_CCX_CLM_NHM = 0x25, + HW_VAR_TXOPLIMIT = 0x26, + HW_VAR_TURBO_MODE = 0x27, + HW_VAR_RF_STATE = 0x28, + HW_VAR_RF_OFF_BY_HW = 0x29, + HW_VAR_BUS_SPEED = 0x2a, + HW_VAR_SET_DEV_POWER = 0x2b, + + HW_VAR_RCR = 0x2c, + HW_VAR_RATR_0 = 0x2d, + HW_VAR_RRSR = 0x2e, + HW_VAR_CPU_RST = 0x2f, + HW_VAR_CHECK_BSSID = 0x30, + HW_VAR_LBK_MODE = 0x31, + HW_VAR_AES_11N_FIX = 0x32, + HW_VAR_USB_RX_AGGR = 0x33, + HW_VAR_USER_CONTROL_TURBO_MODE = 0x34, + HW_VAR_RETRY_LIMIT = 0x35, + HW_VAR_INIT_TX_RATE = 0x36, + HW_VAR_TX_RATE_REG = 0x37, + HW_VAR_EFUSE_USAGE = 0x38, + HW_VAR_EFUSE_BYTES = 0x39, + HW_VAR_AUTOLOAD_STATUS = 0x3a, + HW_VAR_RF_2R_DISABLE = 0x3b, + HW_VAR_SET_RPWM = 0x3c, + HW_VAR_H2C_FW_PWRMODE = 0x3d, + HW_VAR_H2C_FW_JOINBSSRPT = 0x3e, + HW_VAR_H2C_FW_MEDIASTATUSRPT = 0x3f, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD = 0x40, + HW_VAR_FW_PSMODE_STATUS = 0x41, + HW_VAR_INIT_RTS_RATE = 0x42, + HW_VAR_RESUME_CLK_ON = 0x43, + HW_VAR_FW_LPS_ACTION = 0x44, + HW_VAR_1X1_RECV_COMBINE = 0x45, + HW_VAR_STOP_SEND_BEACON = 0x46, + HW_VAR_TSF_TIMER = 0x47, + HW_VAR_IO_CMD = 0x48, + + HW_VAR_RF_RECOVERY = 0x49, + HW_VAR_H2C_FW_UPDATE_GTK = 0x4a, + HW_VAR_WF_MASK = 0x4b, + HW_VAR_WF_CRC = 0x4c, + HW_VAR_WF_IS_MAC_ADDR = 0x4d, + HW_VAR_H2C_FW_OFFLOAD = 0x4e, + HW_VAR_RESET_WFCRC = 0x4f, + + HW_VAR_HANDLE_FW_C2H = 0x50, + HW_VAR_DL_FW_RSVD_PAGE = 0x51, + HW_VAR_AID = 0x52, + HW_VAR_HW_SEQ_ENABLE = 0x53, + HW_VAR_CORRECT_TSF = 0x54, + HW_VAR_BCN_VALID = 0x55, + HW_VAR_FWLPS_RF_ON = 0x56, + HW_VAR_DUAL_TSF_RST = 0x57, + HW_VAR_SWITCH_EPHY_WOWLAN = 0x58, + HW_VAR_INT_MIGRATION = 0x59, + HW_VAR_INT_AC = 0x5a, + HW_VAR_RF_TIMING = 0x5b, + + HAL_DEF_WOWLAN = 0x5c, + HW_VAR_MRC = 0x5d, + HW_VAR_KEEP_ALIVE = 0x5e, + HW_VAR_NAV_UPPER = 0x5f, + + HW_VAR_MGT_FILTER = 0x60, + HW_VAR_CTRL_FILTER = 0x61, + HW_VAR_DATA_FILTER = 0x62, +}; + +enum rt_media_status { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +}; + +enum rt_oem_id { + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819X_CAMEO = 6, + RT_CID_819X_RUNTOP = 7, + RT_CID_819X_SENAO = 8, + RT_CID_TOSHIBA = 9, + RT_CID_819X_NETCORE = 10, + RT_CID_NETTRONIX = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_819X_ALPHA = 15, + RT_CID_819X_SITECOM = 16, + RT_CID_CCX = 17, + RT_CID_819X_LENOVO = 18, + RT_CID_819X_QMI = 19, + RT_CID_819X_EDIMAX_BELKIN = 20, + RT_CID_819X_SERCOMM_BELKIN = 21, + RT_CID_819X_CAMEO1 = 22, + RT_CID_819X_MSI = 23, + RT_CID_819X_ACER = 24, + RT_CID_819X_HP = 27, + RT_CID_819X_CLEVO = 28, + RT_CID_819X_ARCADYAN_BELKIN = 29, + RT_CID_819X_SAMSUNG = 30, + RT_CID_819X_WNC_COREGA = 31, + RT_CID_819X_FOXCOON = 32, + RT_CID_819X_DELL = 33, + RT_CID_819X_PRONETS = 34, + RT_CID_819X_EDIMAX_ASUS = 35, + RT_CID_NETGEAR = 36, + RT_CID_PLANEX = 37, + RT_CID_CC_C = 38, + RT_CID_LENOVO_CHINA = 40, +}; + +enum hw_descs { + HW_DESC_OWN, + HW_DESC_RXOWN, + HW_DESC_TX_NEXTDESC_ADDR, + HW_DESC_TXBUFF_ADDR, + HW_DESC_RXBUFF_ADDR, + HW_DESC_RXPKT_LEN, + HW_DESC_RXERO, + HW_DESC_RX_PREPARE, +}; + +enum prime_sc { + PRIME_CHNL_OFFSET_DONT_CARE = 0, + PRIME_CHNL_OFFSET_LOWER = 1, + PRIME_CHNL_OFFSET_UPPER = 2, +}; + +enum rf_type { + RF_1T1R = 0, + RF_1T2R = 1, + RF_2T2R = 2, + RF_2T2R_GREEN = 3, + RF_2T3R = 4, + RF_2T4R = 5, + RF_3T3R = 6, + RF_3T4R = 7, + RF_4T4R = 8, +}; + +enum ht_channel_width { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, + HT_CHANNEL_WIDTH_80 = 2, + HT_CHANNEL_WIDTH_MAX, +}; + +/* Ref: 802.11i spec D10.0 7.3.2.25.1 + * Cipher Suites Encryption Algorithms + */ +enum rt_enc_alg { + NO_ENCRYPTION = 0, + WEP40_ENCRYPTION = 1, + TKIP_ENCRYPTION = 2, + RSERVED_ENCRYPTION = 3, + AESCCMP_ENCRYPTION = 4, + WEP104_ENCRYPTION = 5, + AESCMAC_ENCRYPTION = 6, /*IEEE802.11w */ +}; + +enum rtl_hal_state { + _HAL_STATE_STOP = 0, + _HAL_STATE_START = 1, +}; + +enum rtl_desc_rate { + DESC_RATE1M = 0x00, + DESC_RATE2M = 0x01, + DESC_RATE5_5M = 0x02, + DESC_RATE11M = 0x03, + + DESC_RATE6M = 0x04, + DESC_RATE9M = 0x05, + DESC_RATE12M = 0x06, + DESC_RATE18M = 0x07, + DESC_RATE24M = 0x08, + DESC_RATE36M = 0x09, + DESC_RATE48M = 0x0a, + DESC_RATE54M = 0x0b, + + DESC_RATEMCS0 = 0x0c, + DESC_RATEMCS1 = 0x0d, + DESC_RATEMCS2 = 0x0e, + DESC_RATEMCS3 = 0x0f, + DESC_RATEMCS4 = 0x10, + DESC_RATEMCS5 = 0x11, + DESC_RATEMCS6 = 0x12, + DESC_RATEMCS7 = 0x13, + DESC_RATEMCS8 = 0x14, + DESC_RATEMCS9 = 0x15, + DESC_RATEMCS10 = 0x16, + DESC_RATEMCS11 = 0x17, + DESC_RATEMCS12 = 0x18, + DESC_RATEMCS13 = 0x19, + DESC_RATEMCS14 = 0x1a, + DESC_RATEMCS15 = 0x1b, + DESC_RATEMCS15_SG = 0x1c, + DESC_RATEMCS32 = 0x20, + + DESC_RATEVHT1SS_MCS0 = 0x2c, + DESC_RATEVHT1SS_MCS1 = 0x2d, + DESC_RATEVHT1SS_MCS2 = 0x2e, + DESC_RATEVHT1SS_MCS3 = 0x2f, + DESC_RATEVHT1SS_MCS4 = 0x30, + DESC_RATEVHT1SS_MCS5 = 0x31, + DESC_RATEVHT1SS_MCS6 = 0x32, + DESC_RATEVHT1SS_MCS7 = 0x33, + DESC_RATEVHT1SS_MCS8 = 0x34, + DESC_RATEVHT1SS_MCS9 = 0x35, + DESC_RATEVHT2SS_MCS0 = 0x36, + DESC_RATEVHT2SS_MCS1 = 0x37, + DESC_RATEVHT2SS_MCS2 = 0x38, + DESC_RATEVHT2SS_MCS3 = 0x39, + DESC_RATEVHT2SS_MCS4 = 0x3a, + DESC_RATEVHT2SS_MCS5 = 0x3b, + DESC_RATEVHT2SS_MCS6 = 0x3c, + DESC_RATEVHT2SS_MCS7 = 0x3d, + DESC_RATEVHT2SS_MCS8 = 0x3e, + DESC_RATEVHT2SS_MCS9 = 0x3f, +}; + +enum rtl_var_map { + /*reg map */ + SYS_ISO_CTRL = 0, + SYS_FUNC_EN, + SYS_CLK, + MAC_RCR_AM, + MAC_RCR_AB, + MAC_RCR_ACRC32, + MAC_RCR_ACF, + MAC_RCR_AAP, + MAC_HIMR, + MAC_HIMRE, + MAC_HSISR, + + /*efuse map */ + EFUSE_TEST, + EFUSE_CTRL, + EFUSE_CLK, + EFUSE_CLK_CTRL, + EFUSE_PWC_EV12V, + EFUSE_FEN_ELDR, + EFUSE_LOADER_CLK_EN, + EFUSE_ANA8M, + EFUSE_HWSET_MAX_SIZE, + EFUSE_MAX_SECTION_MAP, + EFUSE_REAL_CONTENT_SIZE, + EFUSE_OOB_PROTECT_BYTES_LEN, + EFUSE_ACCESS, + + /*CAM map */ + RWCAM, + WCAMI, + RCAMO, + CAMDBG, + SECR, + SEC_CAM_NONE, + SEC_CAM_WEP40, + SEC_CAM_TKIP, + SEC_CAM_AES, + SEC_CAM_WEP104, + + /*IMR map */ + RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */ + RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */ + RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */ + RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */ + RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */ + RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */ + RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrup 8 */ + RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrup 7 */ + RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrup 6 */ + RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrup 5 */ + RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrup 4 */ + RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrup 3 */ + RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrup 2 */ + RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrup 1 */ + RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */ + RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */ + RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */ + RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */ + RTL_IMR_BCNINT, /*Beacon DMA Interrupt 0 */ + RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ + RTL_IMR_RDU, /*Receive Descriptor Unavailable */ + RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ + RTL_IMR_H2CDOK, /*H2C Queue DMA OK Interrupt */ + RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ + RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ + RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ + RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */ + RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ + RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ + RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */ + RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */ + RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ + RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ + RTL_IMR_ROK, /*Receive DMA OK Interrupt */ + RTL_IMR_HSISR_IND, /*HSISR Interrupt*/ + RTL_IBSS_INT_MASKS, /*(RTL_IMR_BCNINT | RTL_IMR_TBDOK | + * RTL_IMR_TBDER) + */ + RTL_IMR_C2HCMD, /*fw interrupt*/ + + /*CCK Rates, TxHT = 0 */ + RTL_RC_CCK_RATE1M, + RTL_RC_CCK_RATE2M, + RTL_RC_CCK_RATE5_5M, + RTL_RC_CCK_RATE11M, + + /*OFDM Rates, TxHT = 0 */ + RTL_RC_OFDM_RATE6M, + RTL_RC_OFDM_RATE9M, + RTL_RC_OFDM_RATE12M, + RTL_RC_OFDM_RATE18M, + RTL_RC_OFDM_RATE24M, + RTL_RC_OFDM_RATE36M, + RTL_RC_OFDM_RATE48M, + RTL_RC_OFDM_RATE54M, + + RTL_RC_HT_RATEMCS7, + RTL_RC_HT_RATEMCS15, + + RTL_RC_VHT_RATE_1SS_MCS7, + RTL_RC_VHT_RATE_1SS_MCS8, + RTL_RC_VHT_RATE_1SS_MCS9, + RTL_RC_VHT_RATE_2SS_MCS7, + RTL_RC_VHT_RATE_2SS_MCS8, + RTL_RC_VHT_RATE_2SS_MCS9, + + /*keep it last */ + RTL_VAR_MAP_MAX, +}; + +/*Firmware PS mode for control LPS.*/ +enum _fw_ps_mode { + FW_PS_ACTIVE_MODE = 0, + FW_PS_MIN_MODE = 1, + FW_PS_MAX_MODE = 2, + FW_PS_DTIM_MODE = 3, + FW_PS_VOIP_MODE = 4, + FW_PS_UAPSD_WMM_MODE = 5, + FW_PS_UAPSD_MODE = 6, + FW_PS_IBSS_MODE = 7, + FW_PS_WWLAN_MODE = 8, + FW_PS_PM_RADIO_OFF = 9, + FW_PS_PM_CARD_DISABLE = 10, +}; + +enum rt_psmode { + EACTIVE, /*Active/Continuous access. */ + EMAXPS, /*Max power save mode. */ + EFASTPS, /*Fast power save mode. */ + EAUTOPS, /*Auto power save mode. */ +}; + +/*LED related.*/ +enum led_ctl_mode { + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, +}; + +enum rtl_led_pin { + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}; + +/*QoS related.*/ +/*acm implementation method.*/ +enum acm_method { + EACMWAY0_SWANDHW = 0, + EACMWAY1_HW = 1, + EACMWAY2_SW = 2, +}; + +enum macphy_mode { + SINGLEMAC_SINGLEPHY = 0, + DUALMAC_DUALPHY, + DUALMAC_SINGLEPHY, +}; + +enum band_type { + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}; + +/* aci/aifsn Field. + * Ref: WMM spec 2.2.2: WME Parameter Element, p.12. + */ +union aci_aifsn { + u8 char_data; + + struct { + u8 aifsn:4; + u8 acm:1; + u8 aci:2; + u8 reserved:1; + } f; /* Field */ +}; + +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20, + WIRELESS_MODE_AC_5G = 0x40, + WIRELESS_MODE_AC_24G = 0x80, + WIRELESS_MODE_AC_ONLY = 0x100, + WIRELESS_MODE_MAX = 0x800 +}; + +#define IS_WIRELESS_MODE_A(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_A) +#define IS_WIRELESS_MODE_B(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_B) +#define IS_WIRELESS_MODE_G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_G) +#define IS_WIRELESS_MODE_N_24G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_24G) +#define IS_WIRELESS_MODE_N_5G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_5G) + +enum ratr_table_mode { + RATR_INX_WIRELESS_NGB = 0, + RATR_INX_WIRELESS_NG = 1, + RATR_INX_WIRELESS_NB = 2, + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_A = 8, + RATR_INX_WIRELESS_AC_5N = 8, + RATR_INX_WIRELESS_AC_24N = 9, +}; + +enum ratr_table_mode_new { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +}; + +enum rtl_link_state { + MAC80211_NOLINK = 0, + MAC80211_LINKING = 1, + MAC80211_LINKED = 2, + MAC80211_LINKED_SCANNING = 3, +}; + +enum act_category { + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +}; + +enum ba_action { + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +}; + +enum rt_polarity_ctl { + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +}; + +/* After 8188E, we use V2 reason define. 88C/8723A use V1 reason. */ +enum fw_wow_reason_v2 { + FW_WOW_V2_PTK_UPDATE_EVENT = 0x01, + FW_WOW_V2_GTK_UPDATE_EVENT = 0x02, + FW_WOW_V2_DISASSOC_EVENT = 0x04, + FW_WOW_V2_DEAUTH_EVENT = 0x08, + FW_WOW_V2_FW_DISCONNECT_EVENT = 0x10, + FW_WOW_V2_MAGIC_PKT_EVENT = 0x21, + FW_WOW_V2_UNICAST_PKT_EVENT = 0x22, + FW_WOW_V2_PATTERN_PKT_EVENT = 0x23, + FW_WOW_V2_RTD3_SSID_MATCH_EVENT = 0x24, + FW_WOW_V2_REALWOW_V2_WAKEUPPKT = 0x30, + FW_WOW_V2_REALWOW_V2_ACKLOST = 0x31, + FW_WOW_V2_REASON_MAX = 0xff, +}; + +enum wolpattern_type { + UNICAST_PATTERN = 0, + MULTICAST_PATTERN = 1, + BROADCAST_PATTERN = 2, + DONT_CARE_DA = 3, + UNKNOWN_TYPE = 4, +}; + +enum package_type { + PACKAGE_DEFAULT, + PACKAGE_QFN68, + PACKAGE_TFBGA90, + PACKAGE_TFBGA80, + PACKAGE_TFBGA79 +}; + +enum rtl_spec_ver { + RTL_SPEC_NEW_RATEID = BIT(0), /* use ratr_table_mode_new */ + RTL_SPEC_SUPPORT_VHT = BIT(1), /* support VHT */ + RTL_SPEC_EXT_C2H = BIT(2), /* extend FW C2H (e.g. TX REPORT) */ +}; + +enum dm_info_query { + DM_INFO_FA_OFDM, + DM_INFO_FA_CCK, + DM_INFO_FA_TOTAL, + DM_INFO_CCA_OFDM, + DM_INFO_CCA_CCK, + DM_INFO_CCA_ALL, + DM_INFO_CRC32_OK_VHT, + DM_INFO_CRC32_OK_HT, + DM_INFO_CRC32_OK_LEGACY, + DM_INFO_CRC32_OK_CCK, + DM_INFO_CRC32_ERROR_VHT, + DM_INFO_CRC32_ERROR_HT, + DM_INFO_CRC32_ERROR_LEGACY, + DM_INFO_CRC32_ERROR_CCK, + DM_INFO_EDCCA_FLAG, + DM_INFO_OFDM_ENABLE, + DM_INFO_CCK_ENABLE, + DM_INFO_CRC32_OK_HT_AGG, + DM_INFO_CRC32_ERROR_HT_AGG, + DM_INFO_DBG_PORT_0, + DM_INFO_CURR_IGI, + DM_INFO_RSSI_MIN, + DM_INFO_RSSI_MAX, + DM_INFO_CLM_RATIO, + DM_INFO_NHM_RATIO, + DM_INFO_IQK_ALL, + DM_INFO_IQK_OK, + DM_INFO_IQK_NG, + DM_INFO_SIZE, +}; + +enum rx_packet_type { + NORMAL_RX, + TX_REPORT1, + TX_REPORT2, + HIS_REPORT, + C2H_PACKET, +}; + +struct rtlwifi_tx_info { + int sn; + unsigned long send_time; +}; + +static inline struct rtlwifi_tx_info *rtl_tx_skb_cb_info(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct rtlwifi_tx_info) > + sizeof(info->status.status_driver_data)); + + return (struct rtlwifi_tx_info *)(info->status.status_driver_data); +} + +struct octet_string { + u8 *octet; + u16 length; +}; + +struct rtl_led_ctl { + bool led_opendrain; + enum rtl_led_pin sw_led0; + enum rtl_led_pin sw_led1; +}; + +struct rtl_qos_parameters { + __le16 cw_min; + __le16 cw_max; + u8 aifs; + u8 flag; + __le16 tx_op; +} __packed; + +struct rt_smooth_data { + u32 elements[100]; /*array to store values */ + u32 index; /*index to current array to store */ + u32 total_num; /*num of valid elements */ + u32 total_val; /*sum of valid elements */ +}; + +struct false_alarm_statistics { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_fast_fsync_fail; + u32 cnt_sb_search_fail; + u32 cnt_ofdm_fail; + u32 cnt_cck_fail; + u32 cnt_all; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_bw_usc; + u32 cnt_bw_lsc; +}; + +struct init_gain { + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +}; + +struct wireless_stats { + u64 txbytesunicast; + u64 txbytesmulticast; + u64 txbytesbroadcast; + u64 rxbytesunicast; + + u64 txbytesunicast_inperiod; + u64 rxbytesunicast_inperiod; + u32 txbytesunicast_inperiod_tp; + u32 rxbytesunicast_inperiod_tp; + u64 txbytesunicast_last; + u64 rxbytesunicast_last; + + long rx_snr_db[4]; + /*Correct smoothed ss in Dbm, only used + * in driver to report real power now. + */ + long recv_signal_power; + long signal_quality; + long last_sigstrength_inpercent; + + u32 rssi_calculate_cnt; + u32 pwdb_all_cnt; + + /* Transformed, in dbm. Beautified signal + * strength for UI, not correct. + */ + long signal_strength; + + u8 rx_rssi_percentage[4]; + u8 rx_evm_dbm[4]; + u8 rx_evm_percentage[2]; + + u16 rx_cfo_short[4]; + u16 rx_cfo_tail[4]; + + struct rt_smooth_data ui_rssi; + struct rt_smooth_data ui_link_quality; +}; + +struct rate_adaptive { + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40m; + u32 low_rssi_thresh_for_ra40m; + u8 low2high_rssi_thresh_for_ra20m; + u32 low_rssi_thresh_for_ra20m; + u32 upper_rssi_threshold_ratr; + u32 middleupper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 middlelow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 ultralow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40m; + u32 low_rssi_threshold_ratr_20m; + u8 ping_rssi_enable; + u32 ping_rssi_ratr; + u32 ping_rssi_thresh_for_ra; + u32 last_ratr; + u8 pre_ratr_state; + u8 ldpc_thres; + bool use_ldpc; + bool lower_rts_rate; + bool is_special_data; +}; + +struct regd_pair_mapping { + u16 reg_dmnenum; + u16 reg_5ghz_ctl; + u16 reg_2ghz_ctl; +}; + +struct dynamic_primary_cca { + u8 pricca_flag; + u8 intf_flag; + u8 intf_type; + u8 dup_rts_flag; + u8 monitor_flag; + u8 ch_offset; + u8 mf_state; +}; + +struct rtl_regulatory { + s8 alpha2[2]; + u16 country_code; + u16 max_power_level; + u32 tp_scale; + u16 current_rd; + u16 current_rd_ext; + int16_t power_limit; + struct regd_pair_mapping *regpair; +}; + +struct rtl_rfkill { + bool rfkill_state; /*0 is off, 1 is on */ +}; + +/*for P2P PS**/ +#define P2P_MAX_NOA_NUM 2 + +enum p2p_role { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum p2p_ps_state { + P2P_PS_DISABLE = 0, + P2P_PS_ENABLE = 1, + P2P_PS_SCAN = 2, + P2P_PS_SCAN_DONE = 3, + P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ +}; + +enum p2p_ps_mode { + P2P_PS_NONE = 0, + P2P_PS_CTWINDOW = 1, + P2P_PS_NOA = 2, + P2P_PS_MIX = 3, /* CTWindow and NoA */ +}; + +struct rtl_p2p_ps_info { + enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */ + enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */ + u8 noa_index; /* Identifies instance of Notice of Absence timing. */ + /* Client traffic window. A period of time in TU after TBTT. */ + u8 ctwindow; + u8 opp_ps; /* opportunistic power save. */ + u8 noa_num; /* number of NoA descriptor in P2P IE. */ + /* Count for owner, Type of client. */ + u8 noa_count_type[P2P_MAX_NOA_NUM]; + /* Max duration for owner, preferred or min acceptable duration + * for client. + */ + u32 noa_duration[P2P_MAX_NOA_NUM]; + /* Length of interval for owner, preferred or max acceptable intervali + * of client. + */ + u32 noa_interval[P2P_MAX_NOA_NUM]; + /* schedule in terms of the lower 4 bytes of the TSF timer. */ + u32 noa_start_time[P2P_MAX_NOA_NUM]; +}; + +struct p2p_ps_offload_t { + u8 offload_en:1; + u8 role:1; /* 1: Owner, 0: Client */ + u8 ctwindow_en:1; + u8 noa0_en:1; + u8 noa1_en:1; + u8 allstasleep:1; + u8 discovery:1; + u8 reserved:1; +}; + +#define IQK_MATRIX_REG_NUM 8 +#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) + +struct iqk_matrix_regs { + bool iqk_done; + long value[1][IQK_MATRIX_REG_NUM]; +}; + +struct phy_parameters { + u16 length; + u32 *pdata; +}; + +enum hw_param_tab_index { + PHY_REG_2T, + PHY_REG_1T, + PHY_REG_PG, + RADIOA_2T, + RADIOB_2T, + RADIOA_1T, + RADIOB_1T, + MAC_REG, + AGCTAB_2T, + AGCTAB_1T, + MAX_TAB +}; + +struct rtl_phy { + struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ + struct init_gain initgain_backup; + enum io_type current_io_type; + + u8 rf_mode; + u8 rf_type; + u8 current_chan_bw; + u8 set_bwmode_inprogress; + u8 sw_chnl_inprogress; + u8 sw_chnl_stage; + u8 sw_chnl_step; + u8 current_channel; + u8 set_io_inprogress; + u8 lck_inprogress; + + /* record for power tracking */ + s32 reg_e94; + s32 reg_e9c; + s32 reg_ea4; + s32 reg_eac; + s32 reg_eb4; + s32 reg_ebc; + s32 reg_ec4; + s32 reg_ecc; + u32 reg_c04, reg_c08, reg_874; + u32 adda_backup[16]; + u32 iqk_mac_backup[IQK_MAC_REG_NUM]; + u32 iqk_bb_backup[10]; + bool iqk_initialized; + + bool rfpath_rx_enable[MAX_RF_PATH]; + u8 reg_837; + /* Dual mac */ + bool need_iqk; + struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM]; + + bool rfpi_enable; + + u8 pwrgroup_cnt; + u8 cck_high_power; + /* this is for 88E & 8723A */ + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; + /* MAX_PG_GROUP groups of pwr diff by rates */ + u32 mcs_offset[MAX_PG_GROUP][16]; + u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RATE]; + u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_24G]; + u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_5G]; + u8 default_initialgain[4]; + + /* the current Tx power level */ + u8 cur_cck_txpwridx; + u8 cur_ofdm24g_txpwridx; + u8 cur_bw20_txpwridx; + u8 cur_bw40_txpwridx; + + s8 txpwr_limit_2_4g[MAX_REGULATION_NUM] + [MAX_2_4G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_2G] + [MAX_RF_PATH_NUM]; + s8 txpwr_limit_5g[MAX_REGULATION_NUM] + [MAX_5G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_5G] + [MAX_RF_PATH_NUM]; + + u32 rfreg_chnlval[2]; + u32 reg_rf3c[2]; /* pathA / pathB */ + + u32 backup_rf_0x1a;/*92ee*/ + /* bfsync */ + u8 framesync; + u32 framesync_c34; + + u8 num_total_rfpath; + struct phy_parameters hwparam_tables[MAX_TAB]; + u16 rf_pathmap; + + enum rt_polarity_ctl polarity_ctl; +}; + +#define MAX_TID_COUNT 9 +#define RTL_AGG_STOP 0 +#define RTL_AGG_PROGRESS 1 +#define RTL_AGG_START 2 +#define RTL_AGG_OPERATIONAL 3 +#define RTL_RX_AGG_START 1 +#define RTL_RX_AGG_STOP 0 +#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 +#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3 + +struct rtl_ht_agg { + u16 txq_id; + u16 wait_for_ba; + u16 start_idx; + u64 bitmap; + u32 rate_n_flags; + u8 agg_state; + u8 rx_agg_state; +}; + +struct rssi_sta { + long undec_sm_pwdb; + long undec_sm_cck; +}; + +struct rtl_tid_data { + struct rtl_ht_agg agg; +}; + +struct rtl_sta_info { + struct list_head list; + struct rtl_tid_data tids[MAX_TID_COUNT]; + /* just used for ap adhoc or mesh*/ + struct rssi_sta rssi_stat; + u8 rssi_level; + u16 wireless_mode; + u8 ratr_index; + u8 mimo_ps; + u8 mac_addr[ETH_ALEN]; +} __packed; + +struct rtl_priv; +struct rtl_io { + struct device *dev; + struct mutex bb_mutex; + + /*PCI MEM map */ + unsigned long pci_mem_end; /*shared mem end */ + unsigned long pci_mem_start; /*shared mem start */ + + /*PCI IO map */ + unsigned long pci_base_addr; /*device I/O address */ + + void (*write8)(struct rtl_priv *rtlpriv, u32 addr, u8 val); + void (*write16)(struct rtl_priv *rtlpriv, u32 addr, u16 val); + void (*write32)(struct rtl_priv *rtlpriv, u32 addr, u32 val); + void (*write_chunk)(struct rtl_priv *rtlpriv, u32 addr, u32 length, + u8 *data); + + u8 (*read8)(struct rtl_priv *rtlpriv, u32 addr); + u16 (*read16)(struct rtl_priv *rtlpriv, u32 addr); + u32 (*read32)(struct rtl_priv *rtlpriv, u32 addr); + +}; + +struct rtl_mac { + u8 mac_addr[ETH_ALEN]; + u8 mac80211_registered; + u8 beacon_enabled; + + u32 tx_ss_num; + u32 rx_ss_num; + + struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + enum nl80211_iftype opmode; + + /*Probe Beacon management */ + enum rtl_link_state link_state; + + int n_channels; + int n_bitrates; + + bool offchan_delay; + u8 p2p; /*using p2p role*/ + bool p2p_in_use; + + /*filters */ + u32 rx_conf; + u16 rx_mgt_filter; + u16 rx_ctrl_filter; + u16 rx_data_filter; + + bool act_scanning; + u8 cnt_after_linked; + bool skip_scan; + + /* early mode */ + /* skb wait queue */ + struct sk_buff_head skb_waitq[MAX_TID_COUNT]; + + u8 ht_stbc_cap; + u8 ht_cur_stbc; + + /*vht support*/ + u8 vht_enable; + u8 bw_80; + u8 vht_cur_ldpc; + u8 vht_cur_stbc; + u8 vht_stbc_cap; + u8 vht_ldpc_cap; + + /*RDG*/ + bool rdg_en; + + /*AP*/ + u8 bssid[ETH_ALEN] __aligned(2); + u32 vendor; + u8 mcs[16]; /* 16 bytes mcs for HT rates. */ + u32 basic_rates; /* b/g rates */ + u8 ht_enable; + u8 sgi_40; + u8 sgi_20; + u8 bw_40; + u16 mode; /* wireless mode */ + u8 slot_time; + u8 short_preamble; + u8 use_cts_protect; + u8 cur_40_prime_sc; + u8 cur_40_prime_sc_bk; + u8 cur_80_prime_sc; + u64 tsf; + u8 retry_short; + u8 retry_long; + u16 assoc_id; + bool hiddenssid; + + /*IBSS*/ + int beacon_interval; + + /*AMPDU*/ + u8 min_space_cfg; /*For Min spacing configurations */ + u8 max_mss_density; + u8 current_ampdu_factor; + u8 current_ampdu_density; + + /*QOS & EDCA */ + struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; + struct rtl_qos_parameters ac[AC_MAX]; + + /* counters */ + u64 last_txok_cnt; + u64 last_rxok_cnt; + u32 last_bt_edca_ul; + u32 last_bt_edca_dl; +}; + +struct btdm_8723 { + bool all_off; + bool agc_table_en; + bool adc_back_off_on; + bool b2_ant_hid_en; + bool low_penalty_rate_adaptive; + bool rf_rx_lpf_shrink; + bool reject_aggre_pkt; + bool tra_tdma_on; + u8 tra_tdma_nav; + u8 tra_tdma_ant; + bool tdma_on; + u8 tdma_ant; + u8 tdma_nav; + u8 tdma_dac_swing; + u8 fw_dac_swing_lvl; + bool ps_tdma_on; + u8 ps_tdma_byte[5]; + bool pta_on; + u32 val_0x6c0; + u32 val_0x6c8; + u32 val_0x6cc; + bool sw_dac_swing_on; + u32 sw_dac_swing_lvl; + u32 wlan_act_hi; + u32 wlan_act_lo; + u32 bt_retry_index; + bool dec_bt_pwr; + bool ignore_wlan_act; +}; + +struct bt_coexist_8723 { + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 c2h_bt_info; + bool c2h_bt_info_req_sent; + bool c2h_bt_inquiry_page; + unsigned long bt_inq_page_start_time; + u8 bt_retry_cnt; + u8 c2h_bt_info_original; + u8 bt_inquiry_page_cnt; + struct btdm_8723 btdm; +}; + +struct rtl_hal { + struct ieee80211_hw *hw; + bool driver_is_goingto_unload; + bool up_first_time; + bool first_init; + bool being_init_adapter; + bool mac_func_enable; + bool pre_edcca_enable; + struct bt_coexist_8723 hal_coex_8723; + + enum intf_type interface; + u16 hw_type; /*92c or 92d or 92s and so on */ + u8 ic_class; + u8 oem_id; + u32 version; /*version of chip */ + u8 state; /*stop 0, start 1 */ + u8 board_type; + u8 package_type; + + u8 pa_type_2g; + u8 pa_type_5g; + u8 lna_type_2g; + u8 lna_type_5g; + u8 external_pa_2g; + u8 external_lna_2g; + u8 external_pa_5g; + u8 external_lna_5g; + u8 type_glna; + u8 type_gpa; + u8 type_alna; + u8 type_apa; + u8 rfe_type; + + /*firmware */ + u32 fwsize; + u8 *pfirmware; + u16 fw_version; + u16 fw_subversion; + bool h2c_setinprogress; + u8 last_hmeboxnum; + bool fw_ready; + /*Reserve page start offset except beacon in TxQ. */ + u8 fw_rsvdpage_startoffset; + u8 h2c_txcmd_seq; + u8 current_ra_rate; + + /* FW Cmd IO related */ + u16 fwcmd_iomap; + u32 fwcmd_ioparam; + bool set_fwcmd_inprogress; + u8 current_fwcmd_io; + + struct p2p_ps_offload_t p2p_ps_offload; + bool fw_clk_change_in_progress; + bool allow_sw_to_change_hwclc; + u8 fw_ps_state; + + /*AMPDU init min space*/ + u8 minspace_cfg; /*For Min spacing configurations */ + + /* Dual mac */ + enum macphy_mode macphymode; + enum band_type current_bandtype; /* 0:2.4G, 1:5G */ + enum band_type current_bandtypebackup; + enum band_type bandset; + /* dual MAC 0--Mac0 1--Mac1 */ + u32 interfaceindex; + /* just for DualMac S3S4 */ + u8 macphyctl_reg; + bool earlymode_enable; + u8 max_earlymode_num; + /* Dual mac*/ + bool during_mac0init_radiob; + bool during_mac1init_radioa; + bool reloadtxpowerindex; + /* True if IMR or IQK have done + * for 2.4G in scan progress + */ + bool load_imrandiqk_setting_for2g; + + bool disable_amsdu_8k; + bool master_of_dmsp; + bool slave_of_dmsp; + + /*for wowlan*/ + bool enter_pnp_sleep; + bool wake_from_pnp_sleep; + time64_t last_suspend_sec; + u32 wowlan_fwsize; + u8 *wowlan_firmware; + + u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/ + + bool real_wow_v2_enable; + bool re_init_llt_table; +}; + +struct rtl_security { + /*default 0 */ + bool use_sw_sec; + + bool being_setkey; + bool use_defaultkey; + /*Encryption Algorithm for Unicast Packet */ + enum rt_enc_alg pairwise_enc_algorithm; + /*Encryption Algorithm for Brocast/Multicast */ + enum rt_enc_alg group_enc_algorithm; + /*Cam Entry Bitmap */ + u32 hwsec_cam_bitmap; + u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN]; + /*local Key buffer, indx 0 is for + * pairwise key 1-4 is for agoup key. + */ + u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; + u8 key_len[KEY_BUF_SIZE]; + + /*The pointer of Pairwise Key, + * it always points to KeyBuf[4] + */ + u8 *pairwise_key; +}; + +#define ASSOCIATE_ENTRY_NUM 33 + +struct fast_ant_training { + u8 bssid[6]; + u8 antsel_rx_keep_0; + u8 antsel_rx_keep_1; + u8 antsel_rx_keep_2; + u32 ant_sum[7]; + u32 ant_cnt[7]; + u32 ant_ave[7]; + u8 fat_state; + u32 train_idx; + u8 antsel_a[ASSOCIATE_ENTRY_NUM]; + u8 antsel_b[ASSOCIATE_ENTRY_NUM]; + u8 antsel_c[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u8 rx_idle_ant; + bool becomelinked; +}; + +struct dm_phy_dbg_info { + s8 rx_snrdb[4]; + u64 num_qry_phy_status; + u64 num_qry_phy_status_cck; + u64 num_qry_phy_status_ofdm; + u16 num_qry_beacon_pkt; + u16 num_non_be_pkt; + s32 rx_evm[4]; +}; + +struct rtl_dm { + /*PHY status for Dynamic Management */ + long entry_min_undec_sm_pwdb; + long undec_sm_cck; + long undec_sm_pwdb; /*out dm */ + long entry_max_undec_sm_pwdb; + s32 ofdm_pkt_cnt; + bool dm_initialgain_enable; + bool dynamic_txpower_enable; + bool current_turbo_edca; + bool is_any_nonbepkts; /*out dm */ + bool is_cur_rdlstate; + bool txpower_trackinginit; + bool disable_framebursting; + bool cck_inch14; + bool txpower_tracking; + bool useramask; + bool rfpath_rxenable[4]; + bool inform_fw_driverctrldm; + bool current_mrc_switch; + u8 txpowercount; + u8 powerindex_backup[6]; + + u8 thermalvalue_rxgain; + u8 thermalvalue_iqk; + u8 thermalvalue_lck; + u8 thermalvalue; + u8 last_dtp_lvl; + u8 thermalvalue_avg[AVG_THERMAL_NUM]; + u8 thermalvalue_avg_index; + u8 tm_trigger; + bool done_txpower; + u8 dynamic_txhighpower_lvl; /*Tx high power level */ + u8 dm_flag; /*Indicate each dynamic mechanism's status. */ + u8 dm_flag_tmp; + u8 dm_type; + u8 dm_rssi_sel; + u8 txpower_track_control; + bool interrupt_migration; + bool disable_tx_int; + s8 ofdm_index[MAX_RF_PATH]; + u8 default_ofdm_index; + u8 default_cck_index; + s8 cck_index; + s8 delta_power_index[MAX_RF_PATH]; + s8 delta_power_index_last[MAX_RF_PATH]; + s8 power_index_offset[MAX_RF_PATH]; + s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_cck_idx; + bool modify_txagc_flag_path_a; + bool modify_txagc_flag_path_b; + + bool one_entry_only; + struct dm_phy_dbg_info dbginfo; + + /* Dynamic ATC switch */ + bool atc_status; + bool large_cfo_hit; + bool is_freeze; + int cfo_tail[2]; + int cfo_ave_pre; + int crystal_cap; + u8 cfo_threshold; + u32 packet_count; + u32 packet_count_pre; + u8 tx_rate; + + /*88e tx power tracking*/ + u8 swing_idx_ofdm[MAX_RF_PATH]; + u8 swing_idx_ofdm_cur; + u8 swing_idx_ofdm_base[MAX_RF_PATH]; + bool swing_flag_ofdm; + u8 swing_idx_cck; + u8 swing_idx_cck_cur; + u8 swing_idx_cck_base; + bool swing_flag_cck; + + s8 swing_diff_2g; + s8 swing_diff_5g; + + /* DMSP */ + bool supp_phymode_switch; + + /* DulMac */ + struct fast_ant_training fat_table; + + u8 resp_tx_path; + u8 path_sel; + u32 patha_sum; + u32 pathb_sum; + u32 patha_cnt; + u32 pathb_cnt; + + u8 pre_channel; + u8 *p_channel; + u8 linked_interval; + + u64 last_tx_ok_cnt; + u64 last_rx_ok_cnt; +}; + +#define EFUSE_MAX_LOGICAL_SIZE 512 + +struct rtl_efuse { + const struct rtl_efuse_ops *efuse_ops; + bool autoload_ok; + bool bootfromefuse; + u16 max_physical_size; + + u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; + u16 efuse_usedbytes; + u8 efuse_usedpercentage; + + u8 autoload_failflag; + u8 autoload_status; + + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u16 eeprom_svid; + u16 eeprom_smid; + u8 eeprom_oemid; + u16 eeprom_channelplan; + u8 eeprom_version; + u8 board_type; + u8 external_pa; + + u8 dev_addr[6]; + u8 wowlan_enable; + u8 antenna_div_cfg; + u8 antenna_div_type; + + bool txpwr_fromeprom; + u8 eeprom_crystalcap; + u8 eeprom_tssi[2]; + u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ + u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; + u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G]; + u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + + u8 internal_pa_5g[2]; /* pathA / pathB */ + u8 eeprom_c9; + u8 eeprom_cc; + + /*For power group */ + u8 eeprom_pwrgroup[2][3]; + u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; + + u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + /*--------------------------------------------------------* + * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays, + * other ICs (8188EE\8723BE\8192EE\8812AE...) + * define new arrays in Windows code. + * BUT, in linux code, we use the same array for all ICs. + * + * The Correspondance relation between two arrays is: + * txpwr_cckdiff[][] == CCK_24G_Diff[][] + * txpwr_ht20diff[][] == BW20_24G_Diff[][] + * txpwr_ht40diff[][] == BW40_24G_Diff[][] + * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][] + * + * Sizes of these arrays are decided by the larger ones. + */ + s8 txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M]; + s8 txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT]; + + u8 txpwr_safetyflag; /* Band edge enable flag */ + u16 eeprom_txpowerdiff; + u8 antenna_txpwdiff[3]; + + u8 eeprom_regulatory; + u8 eeprom_thermalmeter; + u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */ + u16 tssi_13dbm; + u8 crystalcap; /* CrystalCap. */ + u8 delta_iqk; + u8 delta_lck; + + u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ + bool apk_thermalmeterignore; + + bool b1x1_recvcombine; + bool b1ss_support; + + /*channel plan */ + u8 channel_plan; +}; + +struct rtl_efuse_ops { + int (*efuse_onebyte_read)(struct ieee80211_hw *hw, u16 addr, u8 *data); + void (*efuse_logical_map_read)(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value); +}; + +struct rtl_tx_report { + atomic_t sn; + u16 last_sent_sn; + unsigned long last_sent_time; + u16 last_recv_sn; + struct sk_buff_head queue; +}; + +struct rtl_ps_ctl { + bool pwrdomain_protect; + bool in_powersavemode; + bool rfchange_inprogress; + bool swrf_processing; + bool hwradiooff; + /* just for PCIE ASPM + * If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + */ + bool support_aspm; + bool support_backdoor; + + /*for LPS */ + enum rt_psmode dot11_psmode; /*Power save mode configured. */ + bool swctrl_lps; + bool leisure_ps; + bool fwctrl_lps; + u8 fwctrl_psmode; + /*For Fw control LPS mode */ + u8 reg_fwctrl_lps; + /*Record Fw PS mode status. */ + bool fw_current_inpsmode; + u8 reg_max_lps_awakeintvl; + bool report_linked; + bool low_power_enable;/*for 32k*/ + + /*for IPS */ + bool inactiveps; + + u32 rfoff_reason; + + /*RF OFF Level */ + u32 cur_ps_level; + u32 reg_rfps_level; + + bool pwrdown_mode; + + enum rf_pwrstate inactive_pwrstate; + enum rf_pwrstate rfpwr_state; /*cur power state */ + + /* for SW LPS*/ + bool sw_ps_enabled; + bool state_inap; + bool multi_buffered; + u16 nullfunc_seq; + unsigned int dtim_counter; + unsigned long last_sleep_jiffies; + unsigned long last_awake_jiffies; + unsigned long last_delaylps_stamp_jiffies; + unsigned long last_dtim; + unsigned long last_beacon; + + /*For P2P PS */ + struct rtl_p2p_ps_info p2p_ps_info; + u8 pwr_mode; + u8 smart_ps; + + /* wake up on line */ + u8 wo_wlan_mode; + u8 arp_offload_enable; + u8 gtk_offload_enable; + /* Used for WOL, indicates the reason for waking event.*/ + u32 wakeup_reason; +}; + +struct rtl_stats { + u8 psaddr[ETH_ALEN]; + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 rate; /* hw desc rate */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 length; + u8 signalquality; /*in 0-100 index. */ + /* Real power in dBm for this packet, + * no beautification and aggregation. + */ + s32 recvsignalpower; + s8 rxpower; /*in dBm Translate from PWdB */ + u8 signalstrength; /*in 0-100 index. */ + u16 hwerror:1; + u16 crc:1; + u16 icv:1; + u16 shortpreamble:1; + u16 antenna:1; + u16 decrypted:1; + u16 wakeup:1; + u32 timestamp_low; + u32 timestamp_high; + bool shift; + + u8 rx_drvinfo_size; + u8 rx_bufshift; + bool isampdu; + bool isfirst_ampdu; + bool rx_is40mhzpacket; + u8 rx_packet_bw; + u32 rx_pwdb_all; + u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ + s8 rx_mimo_signalquality[4]; + u8 rx_mimo_evm_dbm[4]; + u16 cfo_short[4]; /* per-path's Cfo_short */ + u16 cfo_tail[4]; + + s8 rx_mimo_sig_qual[4]; + u8 rx_pwr[4]; /* per-path's pwdb */ + u8 rx_snr[4]; /* per-path's SNR */ + u8 bandwidth; + u8 bt_coex_pwr_adjust; + bool packet_matchbssid; + bool is_cck; + bool is_ht; + bool packet_toself; + bool packet_beacon; /*for rssi */ + s8 cck_adc_pwdb[4]; /*for rx path selection */ + + bool is_vht; + bool is_short_gi; + u8 vht_nss; + + u8 packet_report_type; + + u32 macid; + u32 bt_rx_rssi_percentage; + u32 macid_valid_entry[2]; +}; + +struct rt_link_detect { + /* count for roaming */ + u32 bcn_rx_inperiod; + u32 roam_times; + + u32 num_tx_in4period[4]; + u32 num_rx_in4period[4]; + + u32 num_tx_inperiod; + u32 num_rx_inperiod; + + bool busytraffic; + bool tx_busy_traffic; + bool rx_busy_traffic; + bool higher_busytraffic; + bool higher_busyrxtraffic; + + u32 tidtx_in4period[MAX_TID_COUNT][4]; + u32 tidtx_inperiod[MAX_TID_COUNT]; + bool higher_busytxtraffic[MAX_TID_COUNT]; +}; + +struct rtl_tcb_desc { + u8 packet_bw:2; + u8 multicast:1; + u8 broadcast:1; + + u8 rts_stbc:1; + u8 rts_enable:1; + u8 cts_enable:1; + u8 rts_use_shortpreamble:1; + u8 rts_use_shortgi:1; + u8 rts_sc:1; + u8 rts_bw:1; + u8 rts_rate; + + u8 use_shortgi:1; + u8 use_shortpreamble:1; + u8 use_driver_rate:1; + u8 disable_ratefallback:1; + + u8 use_spe_rpt:1; + + u8 ratr_index; + u8 mac_id; + u8 hw_rate; + + u8 last_inipkt:1; + u8 cmd_or_init:1; + u8 queue_index; + + /* early mode */ + u8 empkt_num; + /* The max value by HW */ + u32 empkt_len[10]; + bool tx_enable_sw_calc_duration; +}; + +struct rtl_wow_pattern { + u8 type; + u16 crc; + u32 mask[4]; +}; + +/* struct to store contents of interrupt vectors */ +struct rtl_int { + u32 inta; + u32 intb; + u32 intc; + u32 intd; +}; + +struct rtl_hal_ops { + int (*init_sw_vars)(struct ieee80211_hw *hw); + void (*deinit_sw_vars)(struct ieee80211_hw *hw); + void (*read_chip_version)(struct ieee80211_hw *hw); + void (*read_eeprom_info)(struct ieee80211_hw *hw); + void (*interrupt_recognized)(struct ieee80211_hw *hw, + struct rtl_int *intvec); + int (*hw_init)(struct ieee80211_hw *hw); + void (*hw_disable)(struct ieee80211_hw *hw); + void (*hw_suspend)(struct ieee80211_hw *hw); + void (*hw_resume)(struct ieee80211_hw *hw); + void (*enable_interrupt)(struct ieee80211_hw *hw); + void (*disable_interrupt)(struct ieee80211_hw *hw); + int (*set_network_type)(struct ieee80211_hw *hw, + enum nl80211_iftype type); + void (*set_chk_bssid)(struct ieee80211_hw *hw, + bool check_bssid); + void (*set_bw_mode)(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); + u8 (*switch_channel)(struct ieee80211_hw *hw); + void (*set_qos)(struct ieee80211_hw *hw, int aci); + void (*set_bcn_reg)(struct ieee80211_hw *hw); + void (*set_bcn_intv)(struct ieee80211_hw *hw); + void (*update_interrupt_mask)(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); + void (*get_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*set_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*update_rate_tbl)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_leve, + bool update_bw); + void (*update_rate_mask)(struct ieee80211_hw *hw, u8 rssi_level); + u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw, + u8 queue_index); + void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); + void (*fill_tx_desc)(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); + void (*fill_tx_cmddesc)(struct ieee80211_hw *hw, u8 *pdesc, + struct sk_buff *skb); + void (*fill_tx_special_desc)(struct ieee80211_hw *hw, + u8 *pdesc, u8 *pbd_desc, + struct sk_buff *skb, u8 hw_queue); + bool (*query_rx_desc)(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); + void (*set_channel_access)(struct ieee80211_hw *hw); + bool (*radio_onoff_checking)(struct ieee80211_hw *hw, u8 *valid); + void (*dm_watchdog)(struct ieee80211_hw *hw); + void (*scan_operation_backup)(struct ieee80211_hw *hw, u8 operation); + bool (*set_rf_power_state)(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + void (*led_control)(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); + u64 (*get_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name); + bool (*is_tx_desc_closed)(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); + void (*tx_polling)(struct ieee80211_hw *hw, u8 hw_queue); + void (*enable_hw_sec)(struct ieee80211_hw *hw); + void (*set_key)(struct ieee80211_hw *hw, u32 key_index, + u8 *macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + u32 (*get_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); + void (*set_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); + u32 (*get_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); + void (*set_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); + void (*linked_set_reg)(struct ieee80211_hw *hw); + void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw); + bool (*phy_rf6052_config)(struct ieee80211_hw *hw); + void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw, + u8 *powerlevel); + void (*phy_rf6052_set_ofdm_txpower)(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + bool (*config_bb_with_headerfile)(struct ieee80211_hw *hw, + u8 configtype); + bool (*config_bb_with_pgheaderfile)(struct ieee80211_hw *hw, + u8 configtype); + void (*phy_lc_calibrate)(struct ieee80211_hw *hw, bool is2t); + void (*phy_iq_calibrate)(struct ieee80211_hw *hw); + void (*phy_set_bw_mode_callback)(struct ieee80211_hw *hw); + void (*dm_dynamic_txpower)(struct ieee80211_hw *hw); + void (*c2h_command_handle)(struct ieee80211_hw *hw); + void (*bt_wifi_media_status_notify)(struct ieee80211_hw *hw, + bool mstate); + void (*bt_coex_off_before_lps)(struct ieee80211_hw *hw); + void (*fill_h2c_cmd)(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); + void (*set_default_port_id_cmd)(struct ieee80211_hw *hw); + bool (*get_btc_status)(void); + bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr); + void (*add_wowlan_pattern)(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index); + u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx); + void (*c2h_ra_report_handler)(struct ieee80211_hw *hw, + u8 *cmd_buf, u8 cmd_len); +}; + +struct rtl_intf_ops { + /*com */ + int (*adapter_start)(struct ieee80211_hw *hw); + void (*adapter_stop)(struct ieee80211_hw *hw); + + int (*adapter_tx)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc); + void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); + int (*reset_trx_ring)(struct ieee80211_hw *hw); + bool (*waitq_insert)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb); + + /*pci */ + void (*disable_aspm)(struct ieee80211_hw *hw); + void (*enable_aspm)(struct ieee80211_hw *hw); + + /*usb */ +}; + +struct rtl_mod_params { + /* default: 0,0 */ + u64 debug_mask; + /* default: 0 = using hardware encryption */ + bool sw_crypto; + + /* default: 0 = DBG_EMERG (0)*/ + int debug_level; + + /* default: 1 = using no linked power save */ + bool inactiveps; + + /* default: 1 = using linked sw power save */ + bool swctrl_lps; + + /* default: 1 = using linked fw power save */ + bool fwctrl_lps; + + /* default: 0 = not using MSI interrupts mode + * submodules should set their own default value + */ + bool msi_support; + + /* default: 0 = dma 32 */ + bool dma64; + + /* default: 1 = enable aspm */ + int aspm_support; + + /* default 0: 1 means disable */ + bool disable_watchdog; + + /* default 0: 1 means do not disable interrupts */ + bool int_clear; + + /* select antenna */ + int ant_sel; +}; + +struct rtl_hal_usbint_cfg { + /* data - rx */ + u32 rx_urb_num; + u32 rx_max_size; + + /* op - rx */ + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + + /* tx */ + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, + struct sk_buff *); + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + + /* endpoint mapping */ + int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); +}; + +struct rtl_hal_cfg { + u8 bar_id; + bool write_readback; + char *name; + char *alt_fw_name; + const struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + const struct rtl_hal_usbint_cfg *usb_interface_cfg; + enum rtl_spec_ver spec_ver; + + /*this map used for some registers or vars + * defined int HAL but used in MAIN + */ + u32 maps[RTL_VAR_MAP_MAX]; + +}; + +struct rtl_locks { + /* mutex */ + struct mutex conf_mutex; + struct mutex ips_mutex; /* mutex for enter/leave IPS */ + struct mutex lps_mutex; /* mutex for enter/leave LPS */ + + /*spin lock */ + spinlock_t irq_th_lock; + spinlock_t h2c_lock; + spinlock_t rf_ps_lock; + spinlock_t rf_lock; + spinlock_t waitq_lock; + spinlock_t entry_list_lock; + spinlock_t usb_lock; + spinlock_t scan_list_lock; /* lock for the scan list */ + + /*FW clock change */ + spinlock_t fw_ps_lock; + + /*Dual mac*/ + spinlock_t cck_and_rw_pagea_lock; + + spinlock_t iqk_lock; +}; + +struct rtl_works { + struct ieee80211_hw *hw; + + /*timer */ + struct timer_list watchdog_timer; + struct timer_list fw_clockoff_timer; + struct timer_list fast_antenna_training_timer; + /*task */ + struct tasklet_struct irq_tasklet; + struct tasklet_struct irq_prepare_bcn_tasklet; + + /*work queue */ + struct workqueue_struct *rtl_wq; + struct delayed_work watchdog_wq; + struct delayed_work ips_nic_off_wq; + struct delayed_work c2hcmd_wq; + + /* For SW LPS */ + struct delayed_work ps_work; + struct delayed_work ps_rfon_wq; + struct delayed_work fwevt_wq; + + struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; + struct work_struct update_beacon_work; +}; + +struct rtl_debug { + /* add for debug */ + struct dentry *debugfs_dir; + char debugfs_name[20]; +}; + +#define MIMO_PS_STATIC 0 +#define MIMO_PS_DYNAMIC 1 +#define MIMO_PS_NOLIMIT 3 + +struct rtl_dmsp_ctl { + bool activescan_for_slaveofdmsp; + bool scan_for_anothermac_fordmsp; + bool scan_for_itself_fordmsp; + bool writedig_for_anothermacofdmsp; + u32 curdigvalue_for_anothermacofdmsp; + bool changecckpdstate_for_anothermacofdmsp; + u8 curcckpdstate_for_anothermacofdmsp; + bool changetxhighpowerlvl_for_anothermacofdmsp; + u8 curtxhighlvl_for_anothermacofdmsp; + long rssivalmin_for_anothermacofdmsp; +}; + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + u8 initialize; + long rssi_val_min; +}; + +struct dig_t { + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + long last_min_undec_pwdb_for_dm; + long rssi_highpower_lowthresh; + long rssi_highpower_highthresh; + u32 recover_cnt; + u32 pre_igvalue; + u32 cur_igvalue; + long rssi_val; + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u8 dig_algorithm; + u8 dig_twoport_algorithm; + u8 dig_dbgmode; + u8 dig_slgorithm_switch; + u8 cursta_cstate; + u8 presta_cstate; + u8 curmultista_cstate; + u8 stop_dig; + s8 back_val; + s8 back_range_max; + s8 back_range_min; + u8 rx_gain_max; + u8 rx_gain_min; + u8 min_undec_pwdb_for_dm; + u8 rssi_val_min; + u8 pre_cck_cca_thres; + u8 cur_cck_cca_thres; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; + u8 large_fa_hit; + u8 forbidden_igi; + u8 dig_state; + u8 dig_highpwrstate; + u8 cur_sta_cstate; + u8 pre_sta_cstate; + u8 cur_ap_cstate; + u8 pre_ap_cstate; + u8 cur_pd_thstate; + u8 pre_pd_thstate; + u8 cur_cs_ratiostate; + u8 pre_cs_ratiostate; + u8 backoff_enable_flag; + s8 backoffval_range_max; + s8 backoffval_range_min; + u8 dig_min_0; + u8 dig_min_1; + u8 bt30_cur_igi; + bool media_connect_0; + bool media_connect_1; + + u32 antdiv_rssi_max; + u32 rssi_max; +}; + +#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ + +struct rtl_btc_info { + u8 bt_type; + u8 btcoexist; + u8 ant_num; + u8 single_ant_path; + + u8 ap_num; + bool in_4way; + unsigned long in_4way_ts; +}; + +struct bt_coexist_info { + struct rtl_btc_ops *btc_ops; + struct rtl_btc_info btc_info; + /* btc context */ + void *btc_context; + void *wifi_only_context; + /* EEPROM BT info. */ + u8 eeprom_bt_coexist; + u8 eeprom_bt_type; + u8 eeprom_bt_ant_num; + u8 eeprom_bt_ant_isol; + u8 eeprom_bt_radio_shared; + + u8 bt_coexistence; + u8 bt_ant_num; + u8 bt_coexist_type; + u8 bt_state; + u8 bt_cur_state; /* 0:on, 1:off */ + u8 bt_ant_isolation; /* 0:good, 1:bad */ + u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */ + u8 bt_service; + u8 bt_radio_shared_type; + u8 bt_rfreg_origin_1e; + u8 bt_rfreg_origin_1f; + u8 bt_rssi_state; + u32 ratio_tx; + u32 ratio_pri; + u32 bt_edca_ul; + u32 bt_edca_dl; + + bool init_set; + bool bt_busy_traffic; + bool bt_traffic_mode_set; + bool bt_non_traffic_mode_set; + + bool fw_coexist_all_off; + bool sw_coexist_all_off; + bool hw_coexist_all_off; + u32 cstate; + u32 previous_state; + u32 cstate_h; + u32 previous_state_h; + + u8 bt_pre_rssi_state; + u8 bt_pre_rssi_state1; + + u8 reg_bt_iso; + u8 reg_bt_sco; + bool balance_on; + u8 bt_active_zero_cnt; + bool cur_bt_disabled; + bool pre_bt_disabled; + + u8 bt_profile_case; + u8 bt_profile_action; + bool bt_busy; + bool hold_for_bt_operation; + u8 lps_counter; +}; + +struct rtl_btc_ops { + void (*btc_init_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_variables_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_deinit_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_hal_vars)(struct rtl_priv *rtlpriv); + void (*btc_power_on_setting)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_ips_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_scan_notify)(struct rtl_priv *rtlpriv, u8 scantype); + void (*btc_scan_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 scantype); + void (*btc_connect_notify)(struct rtl_priv *rtlpriv, u8 action); + void (*btc_mediastatus_notify)(struct rtl_priv *rtlpriv, + enum rt_media_status mstatus); + void (*btc_periodical)(struct rtl_priv *rtlpriv); + void (*btc_halt_notify)(struct rtl_priv *rtlpriv); + void (*btc_btinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + void (*btc_btmpinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + bool (*btc_is_limited_dig)(struct rtl_priv *rtlpriv); + bool (*btc_is_disable_edca_turbo)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_disabled)(struct rtl_priv *rtlpriv); + void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv, + u8 pkt_type); + void (*btc_switch_band_notify)(struct rtl_priv *rtlpriv, u8 type, + bool scanning); + void (*btc_switch_band_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 type, bool scanning); + void (*btc_display_bt_coex_info)(struct rtl_priv *rtlpriv, + struct seq_file *m); + void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len); + u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv); + u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_ctrl_lps)(struct rtl_priv *rtlpriv); + void (*btc_get_ampdu_cfg)(struct rtl_priv *rtlpriv, u8 *reject_agg, + u8 *ctrl_agg_size, u8 *agg_size); + bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv); +}; + +struct proxim { + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status, + struct sk_buff *skb); + u8 (*proxim_get_var)(struct ieee80211_hw *hw, u8 type); +}; + +struct rtl_c2hcmd { + struct list_head list; + u8 tag; + u8 len; + u8 *val; +}; + +struct rtl_bssid_entry { + struct list_head list; + u8 bssid[ETH_ALEN]; + unsigned long age; +}; + +struct rtl_scan_list { + int num; + struct list_head list; /* sort by age */ +}; + +struct rtl_priv { + struct ieee80211_hw *hw; + struct completion firmware_loading_complete; + struct rtl_priv *buddy_priv; + struct rtl_dmsp_ctl dmsp_ctl; + struct rtl_locks locks; + struct rtl_works works; + struct rtl_mac mac80211; + struct rtl_hal rtlhal; + struct rtl_regulatory regd; + struct rtl_rfkill rfkill; + struct rtl_io io; + struct rtl_phy phy; + struct rtl_dm dm; + struct rtl_security sec; + struct rtl_efuse efuse; + struct rtl_led_ctl ledctl; + struct rtl_tx_report tx_report; + struct rtl_scan_list scan_list; + + struct rtl_ps_ctl psc; + struct rate_adaptive ra; + struct dynamic_primary_cca primarycca; + struct wireless_stats stats; + struct rt_link_detect link_info; + struct false_alarm_statistics falsealm_cnt; + + struct rtl_rate_priv *rate_priv; + + /* sta entry list for ap adhoc or mesh */ + struct list_head entry_list; + + /* c2hcmd list for kthread level access */ + struct sk_buff_head c2hcmd_queue; + + struct rtl_debug dbg; + int max_fw_size; + + /* hal_cfg : for diff cards + * intf_ops : for diff interrface usb/pcie + */ + const struct rtl_hal_cfg *cfg; + const struct rtl_intf_ops *intf_ops; + + /* this var will be set by set_bit, + * and was used to indicate status of + * interface or hardware + */ + unsigned long status; + + /* tables for dm */ + struct dig_t dm_digtable; + struct ps_t dm_pstable; + + u32 reg_874; + u32 reg_c70; + u32 reg_85c; + u32 reg_a74; + bool reg_init; /* true if regs saved */ + bool bt_operation_on; + __le32 *usb_data; + int usb_data_index; + bool initialized; + bool enter_ps; /* true when entering PS */ + u8 rate_mask[5]; + + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode + */ + struct proxim proximity; + + /*for bt coexist use*/ + struct bt_coexist_info btcoexist; + + /* separate 92ee from other ICs, + * 92ee use new trx flow. + */ + bool use_new_trx_flow; + + /* For dual MAC RTL8192DU, things shared by the 2 USB interfaces */ + u32 *curveindex_2g; + u32 *curveindex_5g; + struct mutex *mutex_for_power_on_off; /* for power on/off */ + struct mutex *mutex_for_hw_init; /* for hardware init */ + +#ifdef CONFIG_PM + struct wiphy_wowlan_support wowlan; +#endif + /* This must be the last item so + * that it points to the data allocated + * beyond this structure like: + * rtl_pci_priv or rtl_usb_priv + */ + u8 priv[] __aligned(sizeof(void *)); +}; + +#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211)) +#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal)) +#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) +#define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) + +/* Bluetooth Co-existence Related */ + +enum bt_ant_num { + ANT_X2 = 0, + ANT_X1 = 1, +}; + +enum bt_ant_path { + ANT_MAIN = 0, + ANT_AUX = 1, +}; + +enum bt_co_type { + BT_2WIRE = 0, + BT_ISSC_3WIRE = 1, + BT_ACCEL = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, + BT_RTL8723A = 6, + BT_RTL8821A = 7, + BT_RTL8723B = 8, + BT_RTL8192E = 9, + BT_RTL8812A = 11, +}; + +enum bt_cur_state { + BT_OFF = 0, + BT_ON = 1, +}; + +enum bt_service_type { + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_IDLE = 3, + BT_SCAN = 4, + BT_IDLE = 5, + BT_OTHER_ACTION = 6, + BT_BUSY = 7, + BT_OTHERBUSY = 8, + BT_PAN = 9, +}; + +enum bt_radio_shared { + BT_RADIO_SHARED = 0, + BT_RADIO_INDIVIDUAL = 1, +}; + +/**************************************** + * mem access macro define start + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. + ****************************************/ + +#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ + (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) + +/* mem access macro define end */ + +#define byte(x, n) ((x >> (8 * n)) & 0xff) + +#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) +#define RTL_WATCH_DOG_TIME 2000 +#define MSECS(t) msecs_to_jiffies(t) +#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) +#define rtl_dm(rtlpriv) (&((rtlpriv)->dm)) + +#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */ +/*NIC halt, re-initialize hw parameters*/ +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */ +#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ +/*Always enable ASPM and Clock Req in initialization.*/ +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) +/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/ +#define RT_PS_LEVEL_ASPM BIT(7) +/*When LPS is on, disable 2R if no packet is received or transmittd.*/ +#define RT_RF_LPS_DISALBE_2R BIT(30) +#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ +#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \ + ((ppsc->cur_ps_level & _ps_flg) ? true : false) +#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level &= (~(_ps_flg))) +#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level |= _ps_flg) + +#define FILL_OCTET_STRING(_os, _octet, _len) \ + (_os).octet = (u8 *)(_octet); \ + (_os).length = (_len); + +#define CP_MACADDR(des, src) \ + ((des)[0] = (src)[0], (des)[1] = (src)[1],\ + (des)[2] = (src)[2], (des)[3] = (src)[3],\ + (des)[4] = (src)[4], (des)[5] = (src)[5]) + +#define LDPC_HT_ENABLE_RX BIT(0) +#define LDPC_HT_ENABLE_TX BIT(1) +#define LDPC_HT_TEST_TX_ENABLE BIT(2) +#define LDPC_HT_CAP_TX BIT(3) + +#define STBC_HT_ENABLE_RX BIT(0) +#define STBC_HT_ENABLE_TX BIT(1) +#define STBC_HT_TEST_TX_ENABLE BIT(2) +#define STBC_HT_CAP_TX BIT(3) + +#define LDPC_VHT_ENABLE_RX BIT(0) +#define LDPC_VHT_ENABLE_TX BIT(1) +#define LDPC_VHT_TEST_TX_ENABLE BIT(2) +#define LDPC_VHT_CAP_TX BIT(3) + +#define STBC_VHT_ENABLE_RX BIT(0) +#define STBC_VHT_ENABLE_TX BIT(1) +#define STBC_VHT_TEST_TX_ENABLE BIT(2) +#define STBC_VHT_CAP_TX BIT(3) + +extern u8 channel5g[CHANNEL_MAX_NUMBER_5G]; + +extern u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M]; + +static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read8(rtlpriv, addr); +} + +static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read16(rtlpriv, addr); +} + +static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read32(rtlpriv, addr); +} + +static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) +{ + rtlpriv->io.write8(rtlpriv, addr, val8); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read8(rtlpriv, addr); +} + +static inline void rtl_write_byte_with_val32(struct ieee80211_hw *hw, + u32 addr, u32 val8) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, addr, (u8)val8); +} + +static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) +{ + rtlpriv->io.write16(rtlpriv, addr, val16); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read16(rtlpriv, addr); +} + +static inline void rtl_write_dword(struct rtl_priv *rtlpriv, + u32 addr, u32 val32) +{ + rtlpriv->io.write32(rtlpriv, addr, val32); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read32(rtlpriv, addr); +} + +static inline void rtl_write_chunk(struct rtl_priv *rtlpriv, + u32 addr, u32 length, u8 *data) +{ + rtlpriv->io.write_chunk(rtlpriv, addr, length, data); +} + +static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_bbreg(hw, regaddr, bitmask); +} + +static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_bbreg(hw, regaddr, bitmask, data); +} + +static inline void rtl_set_bbreg_with_dwmask(struct ieee80211_hw *hw, + u32 regaddr, u32 data) +{ + rtl_set_bbreg(hw, regaddr, 0xffffffff, data); +} + +static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_rfreg(hw, rfpath, regaddr, bitmask); +} + +static inline void rtl_set_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_rfreg(hw, rfpath, regaddr, bitmask, data); +} + +static inline bool is_hal_stop(struct rtl_hal *rtlhal) +{ + return (_HAL_STATE_STOP == rtlhal->state); +} + +static inline void set_hal_start(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_START; +} + +static inline void set_hal_stop(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_STOP; +} + +static inline u8 get_rf_type(struct rtl_phy *rtlphy) +{ + return rtlphy->rf_type; +} + +static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb) +{ + return (struct ieee80211_hdr *)(skb->data); +} + +static inline __le16 rtl_get_fc(struct sk_buff *skb) +{ + return rtl_get_hdr(skb)->frame_control; +} + +static inline u16 rtl_get_tid(struct sk_buff *skb) +{ + return ieee80211_get_tid(rtl_get_hdr(skb)); +} + +static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *bssid) +{ + return ieee80211_find_sta(vif, bssid); +} + +static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, + u8 *mac_addr) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + return ieee80211_find_sta(mac->vif, mac_addr); +} + +static inline u32 calculate_bit_shift(u32 bitmask) +{ + if (WARN_ON_ONCE(!bitmask)) + return 0; + + return __ffs(bitmask); +} +#endif diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig new file mode 100644 index 000000000..3736f290b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/Kconfig @@ -0,0 +1,271 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig RTW88 + tristate "Realtek 802.11ac wireless chips support" + depends on MAC80211 + help + This module adds support for mac80211-based wireless drivers that + enables Realtek IEEE 802.11ac wireless chipsets. + + If you choose to build a module, it'll be called rtw88. + +if RTW88 + +config RTW88_CORE + tristate + select WANT_DEV_COREDUMP + +config RTW88_PCI + tristate + +config RTW88_SDIO + tristate + +config RTW88_USB + tristate + +config RTW88_8822B + tristate + +config RTW88_8822C + tristate + +config RTW88_8723X + tristate + +config RTW88_8703B + tristate + select RTW88_8723X + +config RTW88_8723D + tristate + select RTW88_8723X + +config RTW88_8821C + tristate + +config RTW88_88XXA + tristate + +config RTW88_8821A + tristate + select RTW88_88XXA + +config RTW88_8812A + tristate + select RTW88_88XXA + +config RTW88_8814A + tristate + +config RTW88_8822BE + tristate "Realtek 8822BE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8822B + help + Select this option will enable support for 8822BE chipset + + 802.11ac PCIe wireless network adapter + +config RTW88_8822BS + tristate "Realtek 8822BS SDIO wireless network adapter" + depends on MMC + select RTW88_CORE + select RTW88_SDIO + select RTW88_8822B + help + Select this option will enable support for 8822BS chipset + + 802.11ac SDIO wireless network adapter + +config RTW88_8822BU + tristate "Realtek 8822BU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8822B + help + Select this option will enable support for 8822BU chipset + + 802.11ac USB wireless network adapter + +config RTW88_8822CE + tristate "Realtek 8822CE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8822C + help + Select this option will enable support for 8822CE chipset + + 802.11ac PCIe wireless network adapter + +config RTW88_8822CS + tristate "Realtek 8822CS SDIO wireless network adapter" + depends on MMC + select RTW88_CORE + select RTW88_SDIO + select RTW88_8822C + help + Select this option will enable support for 8822CS chipset + + 802.11ac SDIO wireless network adapter + +config RTW88_8822CU + tristate "Realtek 8822CU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8822C + help + Select this option will enable support for 8822CU chipset + + 802.11ac USB wireless network adapter + +config RTW88_8723DE + tristate "Realtek 8723DE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8723D + help + Select this option will enable support for 8723DE chipset + + 802.11n PCIe wireless network adapter + +config RTW88_8723DS + tristate "Realtek 8723DS SDIO wireless network adapter" + depends on MMC + select RTW88_CORE + select RTW88_SDIO + select RTW88_8723D + help + Select this option will enable support for 8723DS chipset + + 802.11n SDIO wireless network adapter + +config RTW88_8723CS + tristate "Realtek 8723CS SDIO wireless network adapter" + depends on MMC + select RTW88_CORE + select RTW88_SDIO + select RTW88_8703B + help + Select this option to enable support for 8723CS chipset (EXPERIMENTAL) + + This module adds support for the 8723CS 802.11n SDIO + wireless network adapter. + + If you choose to build a module, it'll be called rtw88_8723cs. + +config RTW88_8723DU + tristate "Realtek 8723DU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8723D + help + Select this option will enable support for 8723DU chipset + + 802.11n USB wireless network adapter + +config RTW88_8821CE + tristate "Realtek 8821CE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8821C + help + Select this option will enable support for 8821CE chipset + + 802.11ac PCIe wireless network adapter + +config RTW88_8821CS + tristate "Realtek 8821CS SDIO wireless network adapter" + depends on MMC + select RTW88_CORE + select RTW88_SDIO + select RTW88_8821C + help + Select this option will enable support for 8821CS chipset + + 802.11ac SDIO wireless network adapter + +config RTW88_8821CU + tristate "Realtek 8821CU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8821C + help + Select this option will enable support for 8821CU chipset + + 802.11ac USB wireless network adapter + +config RTW88_8821AU + tristate "Realtek 8821AU/8811AU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8821A + help + Select this option will enable support for 8821AU and 8811AU chipset + + 802.11ac USB wireless network adapter + +config RTW88_8812AU + tristate "Realtek 8812AU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8812A + help + Select this option will enable support for 8812AU chipset + + 802.11ac USB wireless network adapter + +config RTW88_8814AE + tristate "Realtek 8814AE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8814A + help + Select this option will enable support for 8814AE chipset + + 802.11ac PCIe wireless network adapter + +config RTW88_8814AU + tristate "Realtek 8814AU USB wireless network adapter" + depends on USB + select RTW88_CORE + select RTW88_USB + select RTW88_8814A + help + Select this option will enable support for 8814AU chipset + + 802.11ac USB wireless network adapter + +config RTW88_DEBUG + bool "Realtek rtw88 debug support" + depends on RTW88_CORE + help + Enable debug support + + If unsure, say Y to simplify debug problems + +config RTW88_DEBUGFS + bool "Realtek rtw88 debugfs support" + depends on RTW88_CORE + help + Enable debug support + + If unsure, say Y to simplify debug problems + +config RTW88_LEDS + bool + depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211 + default y + +endif diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile new file mode 100644 index 000000000..0b3da05a2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/Makefile @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +obj-$(CONFIG_RTW88_CORE) += rtw88_core.o +rtw88_core-y += main.o \ + mac80211.o \ + util.o \ + debug.o \ + tx.o \ + rx.o \ + mac.o \ + phy.o \ + coex.o \ + efuse.o \ + fw.o \ + ps.o \ + sec.o \ + bf.o \ + sar.o \ + regd.o + +rtw88_core-$(CONFIG_PM) += wow.o + +rtw88_core-$(CONFIG_RTW88_LEDS) += led.o + +obj-$(CONFIG_RTW88_8822B) += rtw88_8822b.o +rtw88_8822b-objs := rtw8822b.o rtw8822b_table.o + +obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o +rtw88_8822be-objs := rtw8822be.o + +obj-$(CONFIG_RTW88_8822BS) += rtw88_8822bs.o +rtw88_8822bs-objs := rtw8822bs.o + +obj-$(CONFIG_RTW88_8822BU) += rtw88_8822bu.o +rtw88_8822bu-objs := rtw8822bu.o + +obj-$(CONFIG_RTW88_8822C) += rtw88_8822c.o +rtw88_8822c-objs := rtw8822c.o rtw8822c_table.o + +obj-$(CONFIG_RTW88_8822CE) += rtw88_8822ce.o +rtw88_8822ce-objs := rtw8822ce.o + +obj-$(CONFIG_RTW88_8822CS) += rtw88_8822cs.o +rtw88_8822cs-objs := rtw8822cs.o + +obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o +rtw88_8822cu-objs := rtw8822cu.o + +obj-$(CONFIG_RTW88_8723X) += rtw88_8723x.o +rtw88_8723x-objs := rtw8723x.o + +obj-$(CONFIG_RTW88_8703B) += rtw88_8703b.o +rtw88_8703b-objs := rtw8703b.o rtw8703b_tables.o + +obj-$(CONFIG_RTW88_8723CS) += rtw88_8723cs.o +rtw88_8723cs-objs := rtw8723cs.o + +obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o +rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o + +obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o +rtw88_8723de-objs := rtw8723de.o + +obj-$(CONFIG_RTW88_8723DS) += rtw88_8723ds.o +rtw88_8723ds-objs := rtw8723ds.o + +obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o +rtw88_8723du-objs := rtw8723du.o + +obj-$(CONFIG_RTW88_8821C) += rtw88_8821c.o +rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o + +obj-$(CONFIG_RTW88_8821CE) += rtw88_8821ce.o +rtw88_8821ce-objs := rtw8821ce.o + +obj-$(CONFIG_RTW88_8821CS) += rtw88_8821cs.o +rtw88_8821cs-objs := rtw8821cs.o + +obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o +rtw88_8821cu-objs := rtw8821cu.o + +obj-$(CONFIG_RTW88_88XXA) += rtw88_88xxa.o +rtw88_88xxa-objs := rtw88xxa.o + +obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o +rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o + +obj-$(CONFIG_RTW88_8812A) += rtw88_8812a.o +rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o + +obj-$(CONFIG_RTW88_8821AU) += rtw88_8821au.o +rtw88_8821au-objs := rtw8821au.o + +obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o +rtw88_8812au-objs := rtw8812au.o + +obj-$(CONFIG_RTW88_8814A) += rtw88_8814a.o +rtw88_8814a-objs := rtw8814a.o rtw8814a_table.o + +obj-$(CONFIG_RTW88_8814AE) += rtw88_8814ae.o +rtw88_8814ae-objs := rtw8814ae.o + +obj-$(CONFIG_RTW88_8814AU) += rtw88_8814au.o +rtw88_8814au-objs := rtw8814au.o + +obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o +rtw88_pci-objs := pci.o + +obj-$(CONFIG_RTW88_SDIO) += rtw88_sdio.o +rtw88_sdio-objs := sdio.o + +obj-$(CONFIG_RTW88_USB) += rtw88_usb.o +rtw88_usb-objs := usb.o diff --git a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c new file mode 100644 index 000000000..7313ecc5c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/bf.c @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation. + */ + +#include "main.h" +#include "reg.h" +#include "bf.h" +#include "debug.h" + +void rtw_bf_disassoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + if (bfee->role == RTW_BFEE_NONE) + return; + + if (bfee->role == RTW_BFEE_MU) + bfinfo->bfer_mu_cnt--; + else if (bfee->role == RTW_BFEE_SU) + bfinfo->bfer_su_cnt--; + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, false); + + bfee->role = RTW_BFEE_NONE; +} + +void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + struct ieee80211_sta *sta; + struct ieee80211_sta_vht_cap *vht_cap; + struct ieee80211_sta_vht_cap *ic_vht_cap; + const u8 *bssid = bss_conf->bssid; + u32 sound_dim; + u8 i; + + if (!(chip->band & RTW_BAND_5G)) + return; + + rcu_read_lock(); + + sta = ieee80211_find_sta(vif, bssid); + if (!sta) { + rcu_read_unlock(); + + rtw_warn(rtwdev, "failed to find station entry for bss %pM\n", + bssid); + return; + } + + ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; + vht_cap = &sta->deflink.vht_cap; + + rcu_read_unlock(); + + if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && + (vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { + if (bfinfo->bfer_mu_cnt >= chip->bfer_mu_max_num) { + rtw_dbg(rtwdev, RTW_DBG_BF, "mu bfer number over limit\n"); + return; + } + + ether_addr_copy(bfee->mac_addr, bssid); + bfee->role = RTW_BFEE_MU; + bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7); + bfee->aid = vif->cfg.aid; + bfinfo->bfer_mu_cnt++; + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true); + } else if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) && + (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + if (bfinfo->bfer_su_cnt >= chip->bfer_su_max_num) { + rtw_dbg(rtwdev, RTW_DBG_BF, "su bfer number over limit\n"); + return; + } + + sound_dim = vht_cap->cap & + IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; + sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + + ether_addr_copy(bfee->mac_addr, bssid); + bfee->role = RTW_BFEE_SU; + bfee->sound_dim = (u8)sound_dim; + bfee->g_id = 0; + bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7); + bfinfo->bfer_su_cnt++; + for (i = 0; i < chip->bfer_su_max_num; i++) { + if (!test_bit(i, bfinfo->bfer_su_reg_maping)) { + set_bit(i, bfinfo->bfer_su_reg_maping); + bfee->su_reg_index = i; + break; + } + } + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true); + } +} + +void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, + struct mu_bfer_init_para *param) +{ + u16 mu_bf_ctl = 0; + u8 *addr = param->bfer_address; + int i; + + for (i = 0; i < ETH_ALEN; i++) + rtw_write8(rtwdev, REG_ASSOCIATED_BFMER0_INFO + i, addr[i]); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 6, param->paid); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, param->csi_para); + + mu_bf_ctl = rtw_read16(rtwdev, REG_WMAC_MU_BF_CTL) & 0xC000; + mu_bf_ctl |= param->my_aid | (param->csi_length_sel << 12); + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, mu_bf_ctl); +} + +void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, + enum rtw_trx_desc_rate rate) +{ + u8 csi_rsc = CSI_RSC_FOLLOW_RX_PACKET_BW; + u32 psf_ctl = 0; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) + csi_rsc = CSI_RSC_PRIMARY_20M_BW; + + psf_ctl = rtw_read32(rtwdev, REG_BBPSF_CTRL) | + BIT_WMAC_USE_NDPARATE | + (csi_rsc << 13); + + rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, + RTW_SND_CTRL_SOUNDING); + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, 0x26); + rtwdev->hal.rxfltmap1 &= ~BIT_RXFLTMAP1_BF_REPORT_POLL; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write8_clr(rtwdev, REG_RXFLTMAP4, BIT_RXFLTMAP4_BF_REPORT_POLL); + + if (vif->net_type == RTW_NET_AP_MODE) + rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl | BIT(12)); + else + rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl & ~BIT(12)); +} + +void rtw_bf_cfg_mu_bfee(struct rtw_dev *rtwdev, struct cfg_mumimo_para *param) +{ + u8 mu_tbl_sel; + u8 mu_valid; + + mu_valid = rtw_read8(rtwdev, REG_MU_TX_CTL) & + ~BIT_MASK_R_MU_TABLE_VALID; + + rtw_write8(rtwdev, REG_MU_TX_CTL, + (mu_valid | BIT(0) | BIT(1)) & ~(BIT(7))); + + mu_tbl_sel = rtw_read8(rtwdev, REG_MU_TX_CTL + 1) & 0xF8; + + rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel); + rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[0]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[0]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4, + param->given_user_pos[1]); + + rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel | 1); + rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[1]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[2]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4, + param->given_user_pos[3]); +} + +void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0); + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0); + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0); + rtw_write8(rtwdev, REG_MU_TX_CTL, 0); +} + +void rtw_bf_del_sounding(struct rtw_dev *rtwdev) +{ + rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, 0); +} + +void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; + u8 nr_index = bfee->sound_dim; + u8 grouping = 0, codebookinfo = 1, coefficientsize = 3; + u32 addr_bfer_info, addr_csi_rpt, csi_param; + u8 i; + + rtw_dbg(rtwdev, RTW_DBG_BF, "config as an su bfee\n"); + + switch (bfee->su_reg_index) { + case 1: + addr_bfer_info = REG_ASSOCIATED_BFMER1_INFO; + addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20 + 2; + break; + case 0: + default: + addr_bfer_info = REG_ASSOCIATED_BFMER0_INFO; + addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20; + break; + } + + /* Sounding protocol control */ + rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, + RTW_SND_CTRL_SOUNDING); + + /* MAC address/Partial AID of Beamformer */ + for (i = 0; i < ETH_ALEN; i++) + rtw_write8(rtwdev, addr_bfer_info + i, bfee->mac_addr[i]); + + csi_param = (u16)((coefficientsize << 10) | + (codebookinfo << 8) | + (grouping << 6) | + (nr_index << 3) | + nc_index); + rtw_write16(rtwdev, addr_csi_rpt, csi_param); + + /* ndp rx standby timer */ + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, RTW_NDP_RX_STANDBY_TIME); +} +EXPORT_SYMBOL(rtw_bf_enable_bfee_su); + +/* nc index: 1 2T2R 0 1T1R + * nr index: 1 use Nsts 0 use reg setting + * codebookinfo: 1 802.11ac 3 802.11n + */ +void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bf_info = &rtwdev->bf_info; + struct mu_bfer_init_para param; + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; + u8 nr_index = 1; + u8 grouping = 0, codebookinfo = 1, coefficientsize = 0; + u32 csi_param; + + rtw_dbg(rtwdev, RTW_DBG_BF, "config as an mu bfee\n"); + + csi_param = (u16)((coefficientsize << 10) | + (codebookinfo << 8) | + (grouping << 6) | + (nr_index << 3) | + nc_index); + + rtw_dbg(rtwdev, RTW_DBG_BF, "nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n", + nc_index, nr_index, grouping, codebookinfo, + coefficientsize); + + param.paid = bfee->p_aid; + param.csi_para = csi_param; + param.my_aid = bfee->aid & 0xfff; + param.csi_length_sel = HAL_CSI_SEG_4K; + ether_addr_copy(param.bfer_address, bfee->mac_addr); + + rtw_bf_init_bfer_entry_mu(rtwdev, ¶m); + + bf_info->cur_csi_rpt_rate = DESC_RATE6M; + rtw_bf_cfg_sounding(rtwdev, vif, DESC_RATE6M); + + /* accept action_no_ack */ + rtw_write16_set(rtwdev, REG_RXFLTMAP0, BIT_RXFLTMAP0_ACTIONNOACK); + + /* accept NDPA and BF report poll */ + rtwdev->hal.rxfltmap1 |= BIT_RXFLTMAP1_BF; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); +} +EXPORT_SYMBOL(rtw_bf_enable_bfee_mu); + +void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + rtw_dbg(rtwdev, RTW_DBG_BF, "remove as a su bfee\n"); + rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, + RTW_SND_CTRL_REMOVE); + + switch (bfee->su_reg_index) { + case 0: + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, 0); + break; + case 1: + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER1_INFO, 0); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER1_INFO + 4, 0); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20 + 2, 0); + break; + } + + clear_bit(bfee->su_reg_index, bfinfo->bfer_su_reg_maping); + bfee->su_reg_index = 0xFF; +} +EXPORT_SYMBOL(rtw_bf_remove_bfee_su); + +void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, + RTW_SND_CTRL_REMOVE); + + rtw_bf_del_bfer_entry_mu(rtwdev); + + if (bfinfo->bfer_su_cnt == 0 && bfinfo->bfer_mu_cnt == 0) + rtw_bf_del_sounding(rtwdev); +} +EXPORT_SYMBOL(rtw_bf_remove_bfee_mu); + +void rtw_bf_set_gid_table(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct cfg_mumimo_para param; + + if (bfee->role != RTW_BFEE_MU) { + rtw_dbg(rtwdev, RTW_DBG_BF, "this vif is not mu bfee\n"); + return; + } + + param.grouping_bitmap = 0; + param.mu_tx_en = 0; + memset(param.sounding_sts, 0, 6); + memcpy(param.given_gid_tab, conf->mu_group.membership, 8); + memcpy(param.given_user_pos, conf->mu_group.position, 16); + rtw_dbg(rtwdev, RTW_DBG_BF, "STA0: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n", + param.given_gid_tab[0], param.given_user_pos[0], + param.given_user_pos[1]); + + rtw_dbg(rtwdev, RTW_DBG_BF, "STA1: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n", + param.given_gid_tab[1], param.given_user_pos[2], + param.given_user_pos[3]); + + rtw_bf_cfg_mu_bfee(rtwdev, ¶m); +} +EXPORT_SYMBOL(rtw_bf_set_gid_table); + +void rtw_bf_phy_init(struct rtw_dev *rtwdev) +{ + u8 tmp8; + u32 tmp32; + u8 retry_limit = 0xA; + u8 ndpa_rate = 0x10; + u8 ack_policy = 3; + + tmp32 = rtw_read32(rtwdev, REG_MU_TX_CTL); + /* Enable P1 aggr new packet according to P0 transfer time */ + tmp32 |= BIT_MU_P1_WAIT_STATE_EN; + /* MU Retry Limit */ + tmp32 &= ~BIT_MASK_R_MU_RL; + tmp32 |= (retry_limit << BIT_SHIFT_R_MU_RL) & BIT_MASK_R_MU_RL; + /* Disable Tx MU-MIMO until sounding done */ + tmp32 &= ~BIT_EN_MU_MIMO; + /* Clear validity of MU STAs */ + tmp32 &= ~BIT_MASK_R_MU_TABLE_VALID; + rtw_write32(rtwdev, REG_MU_TX_CTL, tmp32); + + /* MU-MIMO Option as default value */ + tmp8 = ack_policy << BIT_SHIFT_WMAC_TXMU_ACKPOLICY; + tmp8 |= BIT_WMAC_TXMU_ACKPOLICY_EN; + rtw_write8(rtwdev, REG_WMAC_MU_BF_OPTION, tmp8); + + /* MU-MIMO Control as default value */ + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0); + /* Set MU NDPA rate & BW source */ + rtw_write32_set(rtwdev, REG_TXBF_CTRL, BIT_USE_NDPA_PARAMETER); + /* Set NDPA Rate */ + rtw_write8(rtwdev, REG_NDPA_OPT_CTRL, ndpa_rate); + + rtw_write32_mask(rtwdev, REG_BBPSF_CTRL, BIT_MASK_CSI_RATE, + DESC_RATE6M); +} +EXPORT_SYMBOL(rtw_bf_phy_init); + +void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate) +{ + u32 csi_cfg; + u16 cur_rrsr; + + csi_cfg = rtw_read32(rtwdev, REG_BBPSF_CTRL) & ~BIT_MASK_CSI_RATE; + cur_rrsr = rtw_read16(rtwdev, REG_RRSR); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) + csi_cfg |= BIT_CSI_FORCE_RATE; + + if (rssi >= 40) { + if (cur_rate != DESC_RATE54M) { + cur_rrsr |= BIT(DESC_RATE54M); + csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) << + BIT_SHIFT_CSI_RATE; + rtw_write16(rtwdev, REG_RRSR, cur_rrsr); + rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg); + } + *new_rate = DESC_RATE54M; + } else { + if (cur_rate != DESC_RATE24M) { + cur_rrsr &= ~BIT(DESC_RATE54M); + csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) << + BIT_SHIFT_CSI_RATE; + rtw_write16(rtwdev, REG_RRSR, cur_rrsr); + rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg); + } + *new_rate = DESC_RATE24M; + } +} +EXPORT_SYMBOL(rtw_bf_cfg_csi_rate); diff --git a/drivers/net/wireless/realtek/rtw88/bf.h b/drivers/net/wireless/realtek/rtw88/bf.h new file mode 100644 index 000000000..a5d3010e6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/bf.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation. + */ + +#ifndef __RTW_BF_H_ +#define __RTW_BF_H_ + +#define REG_TXBF_CTRL 0x042C +#define REG_RRSR 0x0440 +#define REG_NDPA_OPT_CTRL 0x045F + +#define REG_ASSOCIATED_BFMER0_INFO 0x06E4 +#define REG_ASSOCIATED_BFMER1_INFO 0x06EC +#define REG_TX_CSI_RPT_PARAM_BW20 0x06F4 +#define REG_SND_PTCL_CTRL 0x0718 +#define BIT_DIS_CHK_VHTSIGB_CRC BIT(6) +#define BIT_DIS_CHK_VHTSIGA_CRC BIT(5) +#define BIT_MASK_BEAMFORM (GENMASK(4, 0) | BIT(7)) +#define REG_MU_TX_CTL 0x14C0 +#define REG_MU_STA_GID_VLD 0x14C4 +#define REG_MU_STA_USER_POS_INFO 0x14C8 +#define REG_CSI_RRSR 0x1678 +#define REG_WMAC_MU_BF_OPTION 0x167C +#define REG_WMAC_MU_BF_CTL 0x1680 + +#define BIT_WMAC_USE_NDPARATE BIT(30) +#define BIT_WMAC_TXMU_ACKPOLICY_EN BIT(6) +#define BIT_USE_NDPA_PARAMETER BIT(30) +#define BIT_MU_P1_WAIT_STATE_EN BIT(16) +#define BIT_EN_MU_MIMO BIT(7) + +#define R_MU_RL 0xf +#define BIT_SHIFT_R_MU_RL 12 +#define BIT_SHIFT_WMAC_TXMU_ACKPOLICY 4 +#define BIT_SHIFT_CSI_RATE 24 +#define BIT_CSI_FORCE_RATE BIT(15) + +#define BIT_MASK_R_MU_RL (R_MU_RL << BIT_SHIFT_R_MU_RL) +#define BIT_MASK_R_MU_TABLE_VALID 0x3f +#define BIT_MASK_CSI_RATE_VAL 0x3F +#define BIT_MASK_CSI_RATE (BIT_MASK_CSI_RATE_VAL << BIT_SHIFT_CSI_RATE) + +#define BIT_RXFLTMAP0_ACTIONNOACK BIT(14) +#define BIT_RXFLTMAP1_BF (BIT(4) | BIT(5)) +#define BIT_RXFLTMAP1_BF_REPORT_POLL BIT(4) +#define BIT_RXFLTMAP4_BF_REPORT_POLL BIT(4) + +#define RTW_NDP_RX_STANDBY_TIME 0x70 +#define RTW_SND_CTRL_REMOVE 0x98 +#define RTW_SND_CTRL_SOUNDING 0x9B + +enum csi_rsc { + CSI_RSC_PRIMARY_20M_BW = 0, + CSI_RSC_FOLLOW_RX_PACKET_BW = 1, + CSI_RSC_DUPLICATE_MODE = 2, +}; + +enum csi_seg_len { + HAL_CSI_SEG_4K = 0, + HAL_CSI_SEG_8K = 1, + HAL_CSI_SEG_11K = 2, +}; + +struct cfg_mumimo_para { + u8 sounding_sts[6]; + u16 grouping_bitmap; + u8 mu_tx_en; + u32 given_gid_tab[2]; + u32 given_user_pos[4]; +}; + +struct mu_bfer_init_para { + u16 paid; + u16 csi_para; + u16 my_aid; + enum csi_seg_len csi_length_sel; + u8 bfer_address[ETH_ALEN]; +}; + +void rtw_bf_disassoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); +void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); +void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, + struct mu_bfer_init_para *param); +void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, + enum rtw_trx_desc_rate rate); +void rtw_bf_cfg_mu_bfee(struct rtw_dev *rtwdev, struct cfg_mumimo_para *param); +void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev); +void rtw_bf_del_sounding(struct rtw_dev *rtwdev); +void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee); +void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee); +void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev, struct rtw_bfee *bfee); +void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev, struct rtw_bfee *bfee); +void rtw_bf_set_gid_table(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); +void rtw_bf_phy_init(struct rtw_dev *rtwdev); +void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate); +static inline void rtw_chip_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (rtwdev->chip->ops->config_bfee) + rtwdev->chip->ops->config_bfee(rtwdev, vif, bfee, enable); +} + +static inline void rtw_chip_set_gid_table(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + if (rtwdev->chip->ops->set_gid_table) + rtwdev->chip->ops->set_gid_table(rtwdev, vif, conf); +} + +static inline void rtw_chip_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate) +{ + if (rtwdev->chip->ops->cfg_csi_rate) + rtwdev->chip->ops->cfg_csi_rate(rtwdev, rssi, cur_rate, + fixrate_en, new_rate); +} +#endif diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c new file mode 100644 index 000000000..37c336def --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -0,0 +1,4205 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "ps.h" +#include "debug.h" +#include "reg.h" +#include "phy.h" + +static u8 rtw_coex_next_rssi_state(struct rtw_dev *rtwdev, u8 pre_state, + u8 rssi, u8 rssi_thresh) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 tol = chip->rssi_tolerance; + u8 next_state; + + if (pre_state == COEX_RSSI_STATE_LOW || + pre_state == COEX_RSSI_STATE_STAY_LOW) { + if (rssi >= (rssi_thresh + tol)) + next_state = COEX_RSSI_STATE_HIGH; + else + next_state = COEX_RSSI_STATE_STAY_LOW; + } else { + if (rssi < rssi_thresh) + next_state = COEX_RSSI_STATE_LOW; + else + next_state = COEX_RSSI_STATE_STAY_HIGH; + } + + return next_state; +} + +static void rtw_coex_limited_tx(struct rtw_dev *rtwdev, + bool tx_limit_en, bool ampdu_limit_en) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 num_of_active_port = 1; + + if (!chip->scbd_support) + return; + + /* force max tx retry limit = 8 */ + if (coex_stat->wl_tx_limit_en == tx_limit_en && + coex_stat->wl_ampdu_limit_en == ampdu_limit_en) + return; + + if (!coex_stat->wl_tx_limit_en) { + coex_stat->darfrc = rtw_read32(rtwdev, REG_DARFRC); + coex_stat->darfrch = rtw_read32(rtwdev, REG_DARFRCH); + coex_stat->retry_limit = rtw_read16(rtwdev, REG_RETRY_LIMIT); + } + + if (!coex_stat->wl_ampdu_limit_en) + coex_stat->ampdu_max_time = + rtw_read8(rtwdev, REG_AMPDU_MAX_TIME_V1); + + coex_stat->wl_tx_limit_en = tx_limit_en; + coex_stat->wl_ampdu_limit_en = ampdu_limit_en; + + if (tx_limit_en) { + /* set BT polluted packet on for tx rate adaptive, + * not including tx retry broken by PTA + */ + rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE); + + /* set queue life time to avoid can't reach tx retry limit + * if tx is always broken by GNT_BT + */ + if (num_of_active_port <= 1) + rtw_write8_set(rtwdev, REG_LIFETIME_EN, 0xf); + rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x0808); + + /* auto rate fallback step within 8 retries */ + rtw_write32(rtwdev, REG_DARFRC, 0x1000000); + rtw_write32(rtwdev, REG_DARFRCH, 0x4030201); + } else { + rtw_write8_clr(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE); + rtw_write8_clr(rtwdev, REG_LIFETIME_EN, 0xf); + + rtw_write16(rtwdev, REG_RETRY_LIMIT, coex_stat->retry_limit); + rtw_write32(rtwdev, REG_DARFRC, coex_stat->darfrc); + rtw_write32(rtwdev, REG_DARFRCH, coex_stat->darfrch); + } + + if (ampdu_limit_en) + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, 0x20); + else + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, + coex_stat->ampdu_max_time); +} + +static void rtw_coex_limited_wl(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + bool tx_limit = false; + bool tx_agg_ctrl = false; + + if (!coex->under_5g && coex_dm->bt_status != COEX_BTSTATUS_NCON_IDLE) { + tx_limit = true; + tx_agg_ctrl = true; + } + + rtw_coex_limited_tx(rtwdev, tx_limit, tx_agg_ctrl); +} + +static bool rtw_coex_freerun_check(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 bt_rssi; + u8 ant_distance = 10; + + if (coex_stat->bt_disabled) + return false; + + if (efuse->share_ant || ant_distance <= 5 || !coex_stat->wl_gl_busy) + return false; + + if (ant_distance >= 40 || coex_stat->bt_hid_pair_num >= 2) + return true; + + /* ant_distance = 5 ~ 40 */ + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]) && + COEX_RSSI_HIGH(coex_dm->bt_rssi_state[0])) + return true; + + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + bt_rssi = coex_dm->bt_rssi_state[0]; + else + bt_rssi = coex_dm->bt_rssi_state[1]; + + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) && + COEX_RSSI_HIGH(bt_rssi) && + coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] <= 5) + return true; + + return false; +} + +static void rtw_coex_wl_slot_extend(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 para[6] = {0}; + + para[0] = COEX_H2C69_WL_LEAKAP; + para[1] = PARA1_H2C69_DIS_5MS; + + if (enable) + para[1] = PARA1_H2C69_EN_5MS; + else + coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0; + + coex_stat->wl_slot_extend = enable; + rtw_fw_bt_wifi_control(rtwdev, para[0], ¶[1]); +} + +static void rtw_coex_wl_ccklock_action(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + + if (coex_stat->tdma_timer_base == 3 && coex_stat->wl_slot_extend) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); + rtw_coex_wl_slot_extend(rtwdev, false); + return; + } + + if (coex_stat->wl_slot_extend && coex_stat->wl_force_lps_ctrl && + !coex_stat->wl_cck_lock_ever) { + if (coex_stat->wl_fw_dbg_info[7] <= 5) + coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND]++; + else + coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], 5ms WL slot extend cnt = %d!!\n", + coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND]); + + if (coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] == 7) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); + rtw_coex_wl_slot_extend(rtwdev, false); + } + } else if (!coex_stat->wl_slot_extend && coex_stat->wl_cck_lock) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], set h2c 0x69 opcode 12 to turn on 5ms WL slot extend!!\n"); + + rtw_coex_wl_slot_extend(rtwdev, true); + } +} + +static void rtw_coex_wl_ccklock_detect(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + + bool is_cck_lock_rate = false; + + if (coex_stat->wl_coex_mode != COEX_WLINK_2G1PORT && + coex_stat->wl_coex_mode != COEX_WLINK_2GFREE) + return; + + if (coex_dm->bt_status == COEX_BTSTATUS_INQ_PAGE || + coex_stat->bt_setup_link) { + coex_stat->wl_cck_lock = false; + coex_stat->wl_cck_lock_pre = false; + return; + } + + if (coex_stat->wl_rx_rate <= COEX_CCK_2 || + coex_stat->wl_rts_rx_rate <= COEX_CCK_2) + is_cck_lock_rate = true; + + if (coex_stat->wl_connected && coex_stat->wl_gl_busy && + COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) && + (coex_dm->bt_status == COEX_BTSTATUS_ACL_BUSY || + coex_dm->bt_status == COEX_BTSTATUS_ACL_SCO_BUSY || + coex_dm->bt_status == COEX_BTSTATUS_SCO_BUSY)) { + if (is_cck_lock_rate) { + coex_stat->wl_cck_lock = true; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], cck locking...\n"); + + } else { + coex_stat->wl_cck_lock = false; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], cck unlock...\n"); + } + } else { + coex_stat->wl_cck_lock = false; + } + + /* CCK lock identification */ + if (coex_stat->wl_cck_lock && !coex_stat->wl_cck_lock_pre) + ieee80211_queue_delayed_work(rtwdev->hw, &coex->wl_ccklock_work, + 3 * HZ); + + coex_stat->wl_cck_lock_pre = coex_stat->wl_cck_lock; +} + +static void rtw_coex_wl_noisy_detect(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cnt_cck; + bool wl_cck_lock = false; + + /* wifi noisy environment identification */ + cnt_cck = dm_info->cck_ok_cnt + dm_info->cck_err_cnt; + + if (!coex_stat->wl_gl_busy && !wl_cck_lock) { + if (cnt_cck > 250) { + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] < 5) + coex_stat->cnt_wl[COEX_CNT_WL_NOISY2]++; + + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5) { + coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0; + coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0; + } + } else if (cnt_cck < 100) { + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] < 5) + coex_stat->cnt_wl[COEX_CNT_WL_NOISY0]++; + + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] == 5) { + coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0; + coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0; + } + } else { + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] < 5) + coex_stat->cnt_wl[COEX_CNT_WL_NOISY1]++; + + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5) { + coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0; + coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0; + } + } + + if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5) + coex_stat->wl_noisy_level = 2; + else if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5) + coex_stat->wl_noisy_level = 1; + else + coex_stat->wl_noisy_level = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], wl_noisy_level = %d\n", + coex_stat->wl_noisy_level); + } +} + +static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 para[6] = {}; + u8 times; + u16 tbtt_interval = coex_stat->wl_beacon_interval; + + if (coex_stat->tdma_timer_base == type) + return; + + coex_stat->tdma_timer_base = type; + + para[0] = COEX_H2C69_TDMA_SLOT; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], tbtt_interval = %d\n", + tbtt_interval); + + if (type == TDMA_TIMER_TYPE_4SLOT && tbtt_interval < 120) { + para[1] = PARA1_H2C69_TDMA_4SLOT; /* 4-slot */ + } else if (tbtt_interval < 80 && tbtt_interval > 0) { + times = 100 / tbtt_interval; + if (100 % tbtt_interval != 0) + times++; + + para[1] = FIELD_PREP(PARA1_H2C69_TBTT_TIMES, times); + } else if (tbtt_interval >= 180) { + times = tbtt_interval / 100; + if (tbtt_interval % 100 <= 80) + times--; + + para[1] = FIELD_PREP(PARA1_H2C69_TBTT_TIMES, times) | + FIELD_PREP(PARA1_H2C69_TBTT_DIV100, 1); + } else { + para[1] = PARA1_H2C69_TDMA_2SLOT; + } + + rtw_fw_bt_wifi_control(rtwdev, para[0], ¶[1]); + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): h2c_0x69 = 0x%x\n", + __func__, para[1]); + + /* no 5ms_wl_slot_extend for 4-slot mode */ + if (coex_stat->tdma_timer_base == 3) + rtw_coex_wl_ccklock_action(rtwdev); +} + +static void rtw_coex_set_wl_pri_mask(struct rtw_dev *rtwdev, u8 bitmap, + u8 data) +{ + u32 addr; + + addr = REG_BT_COEX_TABLE_H + (bitmap / 8); + bitmap = bitmap % 8; + + rtw_write8_mask(rtwdev, addr, BIT(bitmap), data); +} + +void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u16 val = 0x2; + + if (!chip->scbd_support) + return; + + val |= coex_stat->score_board; + + /* for 8822b, scbd[10] is CQDDR on + * for 8822c, scbd[10] is no fix 2M + */ + if (!chip->new_scbd10_def && (bitpos & COEX_SCBD_FIX2M)) { + if (set) + val &= ~COEX_SCBD_FIX2M; + else + val |= COEX_SCBD_FIX2M; + } else { + if (set) + val |= bitpos; + else + val &= ~bitpos; + } + + if (val != coex_stat->score_board) { + coex_stat->score_board = val; + val |= BIT_BT_INT_EN; + rtw_write16(rtwdev, REG_WIFI_BT_INFO, val); + } +} +EXPORT_SYMBOL(rtw_coex_write_scbd); + +static u16 rtw_coex_read_scbd(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (!chip->scbd_support) + return 0; + + return (rtw_read16(rtwdev, REG_WIFI_BT_INFO)) & ~(BIT_BT_INT_EN); +} + +static void rtw_coex_check_rfk(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + u8 cnt = 0; + u32 wait_cnt; + bool btk, wlk; + + if (coex_rfe->wlg_at_btg && chip->scbd_support && + coex_stat->bt_iqk_state != 0xff) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], (Before Ant Setup) Delay by IQK\n"); + + wait_cnt = COEX_RFK_TIMEOUT / COEX_MIN_DELAY; + do { + /* BT RFK */ + btk = !!(rtw_coex_read_scbd(rtwdev) & COEX_SCBD_BT_RFK); + + /* WL RFK */ + wlk = !!(rtw_read8(rtwdev, REG_ARFR4) & BIT_WL_RFK); + + if (!btk && !wlk) + break; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], (Before Ant Setup) wlk = %d, btk = %d\n", + wlk, btk); + + mdelay(COEX_MIN_DELAY); + } while (++cnt < wait_cnt); + + if (cnt >= wait_cnt) + coex_stat->bt_iqk_state = 0xff; + } +} + +void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex_stat->bt_disabled) + return; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_fw_query_bt_info(rtwdev); +} + +static void rtw_coex_gnt_workaround(struct rtw_dev *rtwdev, bool force, u8 mode) +{ + rtw_coex_set_gnt_fix(rtwdev); +} + +static void rtw_coex_monitor_bt_ctr(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u32 tmp; + + tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS); + coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, tmp); + coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, tmp); + + tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1); + coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, tmp); + coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, tmp); + + rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, + BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + coex_stat->hi_pri_rx, coex_stat->hi_pri_tx, + coex_stat->lo_pri_rx, coex_stat->lo_pri_tx); + + if (coex_stat->wl_under_lps || coex_stat->wl_under_ips || + (coex_stat->hi_pri_rx > 60000 && coex_stat->hi_pri_tx == 60000 && + coex_stat->lo_pri_rx > 60000 && coex_stat->lo_pri_tx == 60000)) + coex_stat->bt_ctr_ok = false; + else + coex_stat->bt_ctr_ok = true; +} + +static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + bool bt_disabled = false; + bool bt_active = true; + u16 score_board; + + if (chip->scbd_support) { + score_board = rtw_coex_read_scbd(rtwdev); + bt_disabled = !(score_board & COEX_SCBD_ONOFF); + } else { + if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 && + coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0) + bt_active = false; + + if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff && + coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff) + bt_active = false; + + if (bt_active) { + coex_stat->bt_disable_cnt = 0; + bt_disabled = false; + } else { + coex_stat->bt_disable_cnt++; + if (coex_stat->bt_disable_cnt >= 10) + bt_disabled = true; + } + } + + if (coex_stat->bt_disabled != bt_disabled) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT state changed (%d) -> (%d)\n", + coex_stat->bt_disabled, bt_disabled); + + coex_stat->bt_disabled = bt_disabled; + coex_stat->bt_ble_scan_type = 0; + coex_dm->cur_bt_lna_lvl = 0; + + if (!coex_stat->bt_disabled) { + coex_stat->bt_reenable = true; + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_reenable_work, + 15 * HZ); + } else { + coex_stat->bt_mailbox_reply = false; + coex_stat->bt_reenable = false; + } + } +} + +static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_traffic_stats *stats = &rtwdev->stats; + bool is_5G = false; + bool wl_busy = false; + bool scan = false, link = false; + int i; + u8 rssi_state; + u8 rssi_step; + u8 rssi; + + scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags); + coex_stat->wl_connected = !!rtwdev->sta_cnt; + + wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + if (wl_busy != coex_stat->wl_gl_busy) { + if (wl_busy) + coex_stat->wl_gl_busy = true; + else + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->wl_remain_work, + 12 * HZ); + } + + if (stats->tx_throughput > stats->rx_throughput) + coex_stat->wl_tput_dir = COEX_WL_TPUT_TX; + else + coex_stat->wl_tput_dir = COEX_WL_TPUT_RX; + + if (scan || link || reason == COEX_RSN_2GCONSTART || + reason == COEX_RSN_2GSCANSTART || reason == COEX_RSN_2GSWITCHBAND) + coex_stat->wl_linkscan_proc = true; + else + coex_stat->wl_linkscan_proc = false; + + rtw_coex_wl_noisy_detect(rtwdev); + + for (i = 0; i < 4; i++) { + rssi_state = coex_dm->wl_rssi_state[i]; + rssi_step = chip->wl_rssi_step[i]; + rssi = rtwdev->dm_info.min_rssi; + rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state, + rssi, rssi_step); + coex_dm->wl_rssi_state[i] = rssi_state; + } + + if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 || + coex_stat->wl_hi_pri_task2 || coex_stat->wl_gl_busy) + rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, true); + else + rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, false); + + switch (reason) { + case COEX_RSN_5GSCANSTART: + case COEX_RSN_5GSWITCHBAND: + case COEX_RSN_5GCONSTART: + + is_5G = true; + break; + case COEX_RSN_2GSCANSTART: + case COEX_RSN_2GSWITCHBAND: + case COEX_RSN_2GCONSTART: + + is_5G = false; + break; + default: + if (rtwdev->hal.current_band_type == RTW_BAND_5G) + is_5G = true; + else + is_5G = false; + break; + } + + coex->under_5g = is_5G; +} + +static inline u8 *get_payload_from_coex_resp(struct sk_buff *resp) +{ + struct rtw_c2h_cmd *c2h; + u32 pkt_offset; + + pkt_offset = *((u32 *)resp->cb); + c2h = (struct rtw_c2h_cmd *)(resp->data + pkt_offset); + + return c2h->payload; +} + +void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw_coex *coex = &rtwdev->coex; + u8 *payload = get_payload_from_coex_resp(skb); + + if (payload[0] != COEX_RESP_ACK_BY_WL_FW) { + dev_kfree_skb_any(skb); + return; + } + + skb_queue_tail(&coex->queue, skb); + wake_up(&coex->wait); +} + +static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev, + struct rtw_coex_info_req *req) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct sk_buff *skb_resp = NULL; + + lockdep_assert_held(&rtwdev->mutex); + + rtw_fw_query_bt_mp_info(rtwdev, req); + + if (!wait_event_timeout(coex->wait, !skb_queue_empty(&coex->queue), + COEX_REQUEST_TIMEOUT)) { + rtw_err(rtwdev, "coex request time out\n"); + goto out; + } + + skb_resp = skb_dequeue(&coex->queue); + if (!skb_resp) { + rtw_err(rtwdev, "failed to get coex info response\n"); + goto out; + } + +out: + return skb_resp; +} + +static bool rtw_coex_get_bt_scan_type(struct rtw_dev *rtwdev, u8 *scan_type) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + + req.op_code = BT_MP_INFO_OP_SCAN_TYPE; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + return false; + + payload = get_payload_from_coex_resp(skb); + *scan_type = GET_COEX_RESP_BT_SCAN_TYPE(payload); + dev_kfree_skb_any(skb); + return true; +} + +static bool rtw_coex_set_lna_constrain_level(struct rtw_dev *rtwdev, + u8 lna_constrain_level) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + + req.op_code = BT_MP_INFO_OP_LNA_CONSTRAINT; + req.para1 = lna_constrain_level; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + return false; + + dev_kfree_skb_any(skb); + return true; +} + +#define case_BTSTATUS(src) \ + case COEX_BTSTATUS_##src: return #src + +static const char *rtw_coex_get_bt_status_string(u8 bt_status) +{ + switch (bt_status) { + case_BTSTATUS(NCON_IDLE); + case_BTSTATUS(CON_IDLE); + case_BTSTATUS(INQ_PAGE); + case_BTSTATUS(ACL_BUSY); + case_BTSTATUS(SCO_BUSY); + case_BTSTATUS(ACL_SCO_BUSY); + default: + return "Unknown"; + } +} + +static void rtw_coex_update_bt_link_info(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + u8 i; + u8 rssi_state; + u8 rssi_step; + u8 rssi; + + /* update wl/bt rssi by btinfo */ + for (i = 0; i < COEX_RSSI_STEP; i++) { + rssi_state = coex_dm->bt_rssi_state[i]; + rssi_step = chip->bt_rssi_step[i]; + rssi = coex_stat->bt_rssi; + rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state, rssi, + rssi_step); + coex_dm->bt_rssi_state[i] = rssi_state; + } + + if (coex_stat->bt_ble_scan_en && + coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE] % 3 == 0) { + u8 scan_type; + + if (rtw_coex_get_bt_scan_type(rtwdev, &scan_type)) { + coex_stat->bt_ble_scan_type = scan_type; + if ((coex_stat->bt_ble_scan_type & 0x1) == 0x1) + coex_stat->bt_init_scan = true; + else + coex_stat->bt_init_scan = false; + } + } + + coex_stat->bt_profile_num = 0; + + /* set link exist status */ + if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) { + coex_stat->bt_link_exist = false; + coex_stat->bt_pan_exist = false; + coex_stat->bt_a2dp_exist = false; + coex_stat->bt_hid_exist = false; + coex_stat->bt_hfp_exist = false; + } else { + /* connection exists */ + coex_stat->bt_link_exist = true; + if (coex_stat->bt_info_lb2 & COEX_INFO_FTP) { + coex_stat->bt_pan_exist = true; + coex_stat->bt_profile_num++; + } else { + coex_stat->bt_pan_exist = false; + } + + if (coex_stat->bt_info_lb2 & COEX_INFO_A2DP) { + coex_stat->bt_a2dp_exist = true; + coex_stat->bt_profile_num++; + } else { + coex_stat->bt_a2dp_exist = false; + } + + if (coex_stat->bt_info_lb2 & COEX_INFO_HID) { + coex_stat->bt_hid_exist = true; + coex_stat->bt_profile_num++; + } else { + coex_stat->bt_hid_exist = false; + } + + if (coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) { + coex_stat->bt_hfp_exist = true; + coex_stat->bt_profile_num++; + } else { + coex_stat->bt_hfp_exist = false; + } + } + + if (coex_stat->bt_info_lb2 & COEX_INFO_INQ_PAGE) { + coex_dm->bt_status = COEX_BTSTATUS_INQ_PAGE; + } else if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) { + coex_dm->bt_status = COEX_BTSTATUS_NCON_IDLE; + coex_stat->bt_multi_link_remain = false; + } else if (coex_stat->bt_info_lb2 == COEX_INFO_CONNECTION) { + coex_dm->bt_status = COEX_BTSTATUS_CON_IDLE; + } else if ((coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) || + (coex_stat->bt_info_lb2 & COEX_INFO_SCO_BUSY)) { + if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY) + coex_dm->bt_status = COEX_BTSTATUS_ACL_SCO_BUSY; + else + coex_dm->bt_status = COEX_BTSTATUS_SCO_BUSY; + } else if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY) { + coex_dm->bt_status = COEX_BTSTATUS_ACL_BUSY; + } else { + coex_dm->bt_status = COEX_BTSTATUS_MAX; + } + + coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE]++; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(), %s!!!\n", __func__, + rtw_coex_get_bt_status_string(coex_dm->bt_status)); +} + +static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm; + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + u8 link = 0; + u8 center_chan = 0; + u8 bw; + int i; + + bw = rtwdev->hal.current_band_width; + + if (type != COEX_MEDIA_DISCONNECT) + center_chan = rtwdev->hal.current_channel; + + if (center_chan == 0 || + (efuse->share_ant && center_chan <= 14 && + coex_stat->wl_coex_mode != COEX_WLINK_2GFREE)) { + link = 0; + center_chan = 0; + bw = 0; + } else if (center_chan <= 14) { + link = 0x1; + + if (bw == RTW_CHANNEL_WIDTH_40) + bw = chip->bt_afh_span_bw40; + else + bw = chip->bt_afh_span_bw20; + } else if (chip->afh_5g_num > 1) { + for (i = 0; i < chip->afh_5g_num; i++) { + if (center_chan == chip->afh_5g[i].wl_5g_ch) { + link = 0x3; + center_chan = chip->afh_5g[i].bt_skip_ch; + bw = chip->afh_5g[i].bt_skip_span; + break; + } + } + } + + coex_dm->wl_ch_info[0] = link; + coex_dm->wl_ch_info[1] = center_chan; + coex_dm->wl_ch_info[2] = bw; + + rtw_fw_wl_ch_info(rtwdev, link, center_chan, bw); + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s: para[0:2] = 0x%x 0x%x 0x%x\n", __func__, link, + center_chan, bw); +} + +static void rtw_coex_set_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + + if (bt_pwr_dec_lvl == coex_dm->cur_bt_pwr_lvl) + return; + + coex_dm->cur_bt_pwr_lvl = bt_pwr_dec_lvl; + + rtw_fw_force_bt_tx_power(rtwdev, bt_pwr_dec_lvl); +} + +static void rtw_coex_set_bt_rx_gain(struct rtw_dev *rtwdev, u8 bt_lna_lvl) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + + if (bt_lna_lvl == coex_dm->cur_bt_lna_lvl) + return; + + coex_dm->cur_bt_lna_lvl = bt_lna_lvl; + + /* notify BT rx gain table changed */ + if (bt_lna_lvl < 7) { + rtw_coex_set_lna_constrain_level(rtwdev, bt_lna_lvl); + rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, true); + } else { + rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, false); + } + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): bt_rx_LNA_level = %d\n", + __func__, bt_lna_lvl); +} + +static void rtw_coex_set_rf_para(struct rtw_dev *rtwdev, + struct coex_rf_para para) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 offset = 0; + + if (coex->freerun && coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] <= 5) + offset = 3; + + rtw_coex_set_wl_tx_power(rtwdev, para.wl_pwr_dec_lvl); + rtw_coex_set_bt_tx_power(rtwdev, para.bt_pwr_dec_lvl + offset); + rtw_coex_set_wl_rx_gain(rtwdev, para.wl_low_gain_en); + rtw_coex_set_bt_rx_gain(rtwdev, para.bt_lna_lvl); +} + +u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr) +{ + u32 val; + + if (!ltecoex_read_reg(rtwdev, addr, &val)) { + rtw_err(rtwdev, "failed to read indirect register\n"); + return 0; + } + + return val; +} +EXPORT_SYMBOL(rtw_coex_read_indirect_reg); + +void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr, + u32 mask, u32 val) +{ + u32 shift = __ffs(mask); + u32 tmp; + + tmp = rtw_coex_read_indirect_reg(rtwdev, addr); + tmp = (tmp & (~mask)) | ((val << shift) & mask); + + if (!ltecoex_reg_write(rtwdev, addr, tmp)) + rtw_err(rtwdev, "failed to write indirect register\n"); +} +EXPORT_SYMBOL(rtw_coex_write_indirect_reg); + +static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_hw_reg *btg_reg = chip->btg_reg; + + if (wifi_control) { + rtw_write8_set(rtwdev, REG_SYS_SDIO_CTRL + 3, + BIT_LTE_MUX_CTRL_PATH >> 24); + if (btg_reg) + rtw_write8_set(rtwdev, btg_reg->addr, btg_reg->mask); + } else { + rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL + 3, + BIT_LTE_MUX_CTRL_PATH >> 24); + if (btg_reg) + rtw_write8_clr(rtwdev, btg_reg->addr, btg_reg->mask); + } +} + +static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state) +{ + if (!rtwdev->chip->ltecoex_addr) + return; + + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state); +} + +static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state) +{ + if (!rtwdev->chip->ltecoex_addr) + return; + + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state); +} + +static void rtw_coex_mimo_ps(struct rtw_dev *rtwdev, bool force, bool state) +{ + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + if (!force && state == coex_stat->wl_mimo_ps) + return; + + coex_stat->wl_mimo_ps = state; + + rtw_set_txrx_1ss(rtwdev, state); + + rtw_coex_update_wl_ch_info(rtwdev, (u8)coex_stat->wl_connected); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): state = %d\n", __func__, state); +} + +static void rtw_btc_wltoggle_table_a(struct rtw_dev *rtwdev, bool force, + u8 table_case) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 h2c_para[6] = {0}; + u32 table_wl = 0x5a5a5a5a; + + h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_A; + /* no definition */ + h2c_para[1] = 0x1; + + if (efuse->share_ant) { + if (table_case < chip->table_sant_num) + table_wl = chip->table_sant[table_case].wl; + } else { + if (table_case < chip->table_nsant_num) + table_wl = chip->table_nsant[table_case].wl; + } + + /* tell WL FW WL slot toggle table-A*/ + h2c_para[2] = (u8)u32_get_bits(table_wl, GENMASK(7, 0)); + h2c_para[3] = (u8)u32_get_bits(table_wl, GENMASK(15, 8)); + h2c_para[4] = (u8)u32_get_bits(table_wl, GENMASK(23, 16)); + h2c_para[5] = (u8)u32_get_bits(table_wl, GENMASK(31, 24)); + + rtw_fw_bt_wifi_control(rtwdev, h2c_para[0], &h2c_para[1]); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n", + __func__, h2c_para[0], h2c_para[1], h2c_para[2], + h2c_para[3], h2c_para[4], h2c_para[5]); +} + +#define COEX_WL_SLOT_TOGLLE 0x5a5a5aaa +static void rtw_btc_wltoggle_table_b(struct rtw_dev *rtwdev, bool force, + u8 interval, u32 table) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 cur_h2c_para[6] = {0}; + u8 i; + + cur_h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_B; + cur_h2c_para[1] = interval; + cur_h2c_para[2] = (u8)u32_get_bits(table, GENMASK(7, 0)); + cur_h2c_para[3] = (u8)u32_get_bits(table, GENMASK(15, 8)); + cur_h2c_para[4] = (u8)u32_get_bits(table, GENMASK(23, 16)); + cur_h2c_para[5] = (u8)u32_get_bits(table, GENMASK(31, 24)); + + coex_stat->wl_toggle_interval = interval; + + for (i = 0; i <= 5; i++) + coex_stat->wl_toggle_para[i] = cur_h2c_para[i]; + + rtw_fw_bt_wifi_control(rtwdev, cur_h2c_para[0], &cur_h2c_para[1]); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n", + __func__, cur_h2c_para[0], cur_h2c_para[1], cur_h2c_para[2], + cur_h2c_para[3], cur_h2c_para[4], cur_h2c_para[5]); +} + +static void rtw_coex_set_table(struct rtw_dev *rtwdev, bool force, u32 table0, + u32 table1) +{ +#define DEF_BRK_TABLE_VAL 0xf0ffffff + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + + /* If last tdma is wl slot toggle, force write table*/ + if (!force && coex_dm->reason != COEX_RSN_LPS) { + if (table0 == rtw_read32(rtwdev, REG_BT_COEX_TABLE0) && + table1 == rtw_read32(rtwdev, REG_BT_COEX_TABLE1)) + return; + } + rtw_write32(rtwdev, REG_BT_COEX_TABLE0, table0); + rtw_write32(rtwdev, REG_BT_COEX_TABLE1, table1); + rtw_write32(rtwdev, REG_BT_COEX_BRK_TABLE, DEF_BRK_TABLE_VAL); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): 0x6c0 = %x, 0x6c4 = %x\n", __func__, table0, + table1); +} + +static void rtw_coex_table(struct rtw_dev *rtwdev, bool force, u8 type) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_stat *coex_stat = &coex->stat; + + coex_dm->cur_table = type; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Coex_Table - %d\n", type); + + if (efuse->share_ant) { + if (type < chip->table_sant_num) + rtw_coex_set_table(rtwdev, force, + chip->table_sant[type].bt, + chip->table_sant[type].wl); + } else { + type = type - 100; + if (type < chip->table_nsant_num) + rtw_coex_set_table(rtwdev, force, + chip->table_nsant[type].bt, + chip->table_nsant[type].wl); + } + if (coex_stat->wl_slot_toggle_change) + rtw_btc_wltoggle_table_a(rtwdev, true, type); +} + +static void rtw_coex_ignore_wlan_act(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_coex *coex = &rtwdev->coex; + + if (coex->manual_control || coex->stop_dm) + return; + + rtw_fw_bt_ignore_wlan_action(rtwdev, enable); +} + +static void rtw_coex_power_save_state(struct rtw_dev *rtwdev, u8 ps_type, + u8 lps_val, u8 rpwm_val) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 lps_mode = 0x0; + + lps_mode = rtwdev->lps_conf.mode; + + switch (ps_type) { + case COEX_PS_WIFI_NATIVE: + /* recover to original 32k low power setting */ + coex_stat->wl_force_lps_ctrl = false; + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): COEX_PS_WIFI_NATIVE\n", __func__); + rtw_leave_lps(rtwdev); + break; + case COEX_PS_LPS_OFF: + coex_stat->wl_force_lps_ctrl = true; + if (lps_mode) + rtw_fw_coex_tdma_type(rtwdev, 0, 0, 0, 0, 0); + + rtw_leave_lps(rtwdev); + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): COEX_PS_LPS_OFF\n", __func__); + break; + default: + break; + } +} + +static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2, + u8 byte3, u8 byte4, u8 byte5) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 ps_type = COEX_PS_WIFI_NATIVE; + bool ap_enable = false; + + if (ap_enable && (byte1 & BIT(4) && !(byte1 & BIT(5)))) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): AP mode\n", + __func__); + + byte1 &= ~BIT(4); + byte1 |= BIT(5); + + byte5 |= BIT(5); + byte5 &= ~BIT(6); + + ps_type = COEX_PS_WIFI_NATIVE; + rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0); + } else if ((byte1 & BIT(4) && !(byte1 & BIT(5))) || + coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): Force LPS (byte1 = 0x%x)\n", __func__, + byte1); + + if (chip->pstdma_type == COEX_PSTDMA_FORCE_LPSOFF) + ps_type = COEX_PS_LPS_OFF; + else + ps_type = COEX_PS_LPS_ON; + rtw_coex_power_save_state(rtwdev, ps_type, 0x50, 0x4); + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): native power save (byte1 = 0x%x)\n", + __func__, byte1); + + ps_type = COEX_PS_WIFI_NATIVE; + rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0); + } + + coex_dm->ps_tdma_para[0] = byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = byte5; + + rtw_fw_coex_tdma_type(rtwdev, byte1, byte2, byte3, byte4, byte5); + + if (byte1 & BIT(2)) { + coex_stat->wl_slot_toggle = true; + coex_stat->wl_slot_toggle_change = false; + } else { + coex_stat->wl_slot_toggle_change = coex_stat->wl_slot_toggle; + coex_stat->wl_slot_toggle = false; + } +} + +static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 n, type; + bool turn_on; + bool wl_busy = false; + + if (tcase & TDMA_4SLOT) /* 4-slot (50ms) mode */ + rtw_coex_tdma_timer_base(rtwdev, TDMA_TIMER_TYPE_4SLOT); + else + rtw_coex_tdma_timer_base(rtwdev, TDMA_TIMER_TYPE_2SLOT); + + type = (u8)(tcase & 0xff); + + turn_on = (type == 0 || type == 100) ? false : true; + + if (!force && turn_on == coex_dm->cur_ps_tdma_on && + type == coex_dm->cur_ps_tdma) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n", + (coex_dm->cur_ps_tdma_on ? "on" : "off"), + coex_dm->cur_ps_tdma); + + return; + } + wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + + if ((coex_stat->bt_a2dp_exist && + (coex_stat->bt_inq_remain || coex_stat->bt_multi_link)) || + !wl_busy) + rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, false); + else + rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true); + + /* update pre state */ + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + if (efuse->share_ant) { + if (type < chip->tdma_sant_num) + rtw_coex_set_tdma(rtwdev, + chip->tdma_sant[type].para[0], + chip->tdma_sant[type].para[1], + chip->tdma_sant[type].para[2], + chip->tdma_sant[type].para[3], + chip->tdma_sant[type].para[4]); + } else { + n = type - 100; + if (n < chip->tdma_nsant_num) + rtw_coex_set_tdma(rtwdev, + chip->tdma_nsant[n].para[0], + chip->tdma_nsant[n].para[1], + chip->tdma_nsant[n].para[2], + chip->tdma_nsant[n].para[3], + chip->tdma_nsant[n].para[4]); + } + + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], coex tdma type(%s, %d)\n", + turn_on ? "on" : "off", type); +} + +static void rtw_coex_set_ant_path(struct rtw_dev *rtwdev, bool force, u8 phase) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + struct rtw_coex_dm *coex_dm = &coex->dm; + u8 ctrl_type = COEX_SWITCH_CTRL_MAX; + u8 pos_type = COEX_SWITCH_TO_MAX; + + if (!force && coex_dm->cur_ant_pos_type == phase) + return; + + coex_dm->cur_ant_pos_type = phase; + + /* avoid switch coex_ctrl_owner during BT IQK */ + rtw_coex_check_rfk(rtwdev); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], coex_stat->bt_disabled = 0x%x\n", + coex_stat->bt_disabled); + + switch (phase) { + case COEX_SET_ANT_POWERON: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_COEX_POWERON\n", __func__); + /* set path control owner to BT at power-on */ + if (coex_stat->bt_disabled) + rtw_coex_coex_ctrl_owner(rtwdev, true); + else + rtw_coex_coex_ctrl_owner(rtwdev, false); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_BT; + break; + case COEX_SET_ANT_INIT: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_COEX_INIT\n", __func__); + if (coex_stat->bt_disabled) { + /* set GNT_BT to SW low */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW); + + /* set GNT_WL to SW high */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH); + } else { + /* set GNT_BT to SW high */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_HIGH); + + /* set GNT_WL to SW low */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_LOW); + } + + /* set path control owner to wl at initial step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_BT; + break; + case COEX_SET_ANT_WONLY: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_WLANONLY_INIT\n", __func__); + /* set GNT_BT to SW Low */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW); + + /* set GNT_WL to SW high */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH); + + /* set path control owner to wl at initial step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_WLG; + break; + case COEX_SET_ANT_WOFF: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_WLAN_OFF\n", __func__); + /* set path control owner to BT */ + rtw_coex_coex_ctrl_owner(rtwdev, false); + + ctrl_type = COEX_SWITCH_CTRL_BY_BT; + pos_type = COEX_SWITCH_TO_NOCARE; + break; + case COEX_SET_ANT_2G: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_2G_RUNTIME\n", __func__); + /* set GNT_BT to PTA */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA); + + /* set GNT_WL to PTA */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA); + + /* set path control owner to wl at runtime step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_PTA; + pos_type = COEX_SWITCH_TO_NOCARE; + break; + case COEX_SET_ANT_5G: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_5G_RUNTIME\n", __func__); + + /* set GNT_BT to HW PTA */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA); + + /* set GNT_WL to SW high */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH); + + /* set path control owner to wl at runtime step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_WLA; + break; + case COEX_SET_ANT_2G_FREERUN: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_2G_FREERUN\n", __func__); + + /* set GNT_BT to HW PTA */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA); + + /* Set GNT_WL to SW high */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH); + + /* set path control owner to wl at runtime step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_WLG_BT; + break; + case COEX_SET_ANT_2G_WLBT: + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s() - PHASE_2G_WLBT\n", __func__); + /* set GNT_BT to HW PTA */ + rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA); + + /* Set GNT_WL to HW PTA */ + rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA); + + /* set path control owner to wl at runtime step */ + rtw_coex_coex_ctrl_owner(rtwdev, true); + + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + pos_type = COEX_SWITCH_TO_WLG_BT; + break; + default: + WARN(1, "unknown phase when setting antenna path\n"); + return; + } + + if (ctrl_type < COEX_SWITCH_CTRL_MAX && pos_type < COEX_SWITCH_TO_MAX && + coex_rfe->ant_switch_exist) + rtw_coex_set_ant_switch(rtwdev, ctrl_type, pos_type); +} + +#define case_ALGO(src) \ + case COEX_ALGO_##src: return #src + +static const char *rtw_coex_get_algo_string(u8 algo) +{ + switch (algo) { + case_ALGO(NOPROFILE); + case_ALGO(HFP); + case_ALGO(HID); + case_ALGO(A2DP); + case_ALGO(PAN); + case_ALGO(A2DP_HID); + case_ALGO(A2DP_PAN); + case_ALGO(PAN_HID); + case_ALGO(A2DP_PAN_HID); + default: + return "Unknown"; + } +} + +#define case_BT_PROFILE(src) \ + case BPM_##src: return #src + +static const char *rtw_coex_get_bt_profile_string(u8 bt_profile) +{ + switch (bt_profile) { + case_BT_PROFILE(NOPROFILE); + case_BT_PROFILE(HFP); + case_BT_PROFILE(HID); + case_BT_PROFILE(A2DP); + case_BT_PROFILE(PAN); + case_BT_PROFILE(HID_HFP); + case_BT_PROFILE(A2DP_HFP); + case_BT_PROFILE(A2DP_HID); + case_BT_PROFILE(A2DP_HID_HFP); + case_BT_PROFILE(PAN_HFP); + case_BT_PROFILE(PAN_HID); + case_BT_PROFILE(PAN_HID_HFP); + case_BT_PROFILE(PAN_A2DP); + case_BT_PROFILE(PAN_A2DP_HFP); + case_BT_PROFILE(PAN_A2DP_HID); + case_BT_PROFILE(PAN_A2DP_HID_HFP); + default: + return "Unknown"; + } +} + +static u8 rtw_coex_algorithm(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 algorithm = COEX_ALGO_NOPROFILE; + u8 profile_map = 0; + + if (coex_stat->bt_hfp_exist) + profile_map |= BPM_HFP; + if (coex_stat->bt_hid_exist) + profile_map |= BPM_HID; + if (coex_stat->bt_a2dp_exist) + profile_map |= BPM_A2DP; + if (coex_stat->bt_pan_exist) + profile_map |= BPM_PAN; + + switch (profile_map) { + case BPM_HFP: + algorithm = COEX_ALGO_HFP; + break; + case BPM_HID: + case BPM_HFP | BPM_HID: + algorithm = COEX_ALGO_HID; + break; + case BPM_HFP | BPM_A2DP: + case BPM_HID | BPM_A2DP: + case BPM_HFP | BPM_HID | BPM_A2DP: + algorithm = COEX_ALGO_A2DP_HID; + break; + case BPM_HFP | BPM_PAN: + case BPM_HID | BPM_PAN: + case BPM_HFP | BPM_HID | BPM_PAN: + algorithm = COEX_ALGO_PAN_HID; + break; + case BPM_HFP | BPM_A2DP | BPM_PAN: + case BPM_HID | BPM_A2DP | BPM_PAN: + case BPM_HFP | BPM_HID | BPM_A2DP | BPM_PAN: + algorithm = COEX_ALGO_A2DP_PAN_HID; + break; + case BPM_PAN: + algorithm = COEX_ALGO_PAN; + break; + case BPM_A2DP | BPM_PAN: + algorithm = COEX_ALGO_A2DP_PAN; + break; + case BPM_A2DP: + if (coex_stat->bt_multi_link) { + if (coex_stat->bt_hid_pair_num > 0) + algorithm = COEX_ALGO_A2DP_HID; + else + algorithm = COEX_ALGO_A2DP_PAN; + } else { + algorithm = COEX_ALGO_A2DP; + } + break; + default: + algorithm = COEX_ALGO_NOPROFILE; + break; + } + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT Profile = %s => Algorithm = %s\n", + rtw_coex_get_bt_profile_string(profile_map), + rtw_coex_get_algo_string(algorithm)); + return algorithm; +} + +static void rtw_coex_action_coex_all_off(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 2; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_freerun(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 level = 0; + bool bt_afh_loss = true; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + if (efuse->share_ant) + return; + + coex->freerun = true; + + if (bt_afh_loss) + rtw_coex_update_wl_ch_info(rtwdev, COEX_MEDIA_CONNECT); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN); + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false); + + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[0])) + level = 2; + else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) + level = 3; + else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[2])) + level = 4; + else + level = 5; + + if (level > chip->wl_rf_para_num - 1) + level = chip->wl_rf_para_num - 1; + + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[level]); + else + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[level]); + + rtw_coex_table(rtwdev, false, 100); + rtw_coex_tdma(rtwdev, false, 100); +} + +static void rtw_coex_action_rf4ce(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 9; + tdma_case = 16; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_whql_test(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 2; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + u32 slot_type = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { /* Shared-Ant */ + if (coex_stat->wl_gl_busy) { + table_case = 26; + if (coex_stat->bt_hid_exist && + coex_stat->bt_profile_num == 1) { + slot_type = TDMA_4SLOT; + tdma_case = 20; + } else { + tdma_case = 20; + } + } else { + table_case = 1; + tdma_case = 0; + } + } else { /* Non-Shared-Ant */ + if (coex_stat->wl_gl_busy) + table_case = 115; + else + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_bt_idle(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + u8 table_case = 0xff, tdma_case = 0xff; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (coex_rfe->ant_switch_with_bt && + coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) { + if (efuse->share_ant && + COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) && + coex_stat->wl_gl_busy) { + table_case = 0; + tdma_case = 0; + } else if (!efuse->share_ant) { + table_case = 100; + tdma_case = 100; + } + } + + if (table_case != 0xff && tdma_case != 0xff) { + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN); + goto exit; + } + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + + if (efuse->share_ant) { + /* Shared-Ant */ + if (!coex_stat->wl_gl_busy) { + table_case = 10; + tdma_case = 3; + } else if (coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) { + table_case = 11; + + if (coex_stat->lo_pri_rx + coex_stat->lo_pri_tx > 250) + tdma_case = 17; + else + tdma_case = 7; + } else { + table_case = 12; + tdma_case = 7; + } + } else { + /* Non-Shared-Ant */ + if (!coex_stat->wl_gl_busy) { + table_case = 112; + tdma_case = 104; + } else if ((coex_stat->bt_ble_scan_type & 0x2) && + coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) { + table_case = 114; + tdma_case = 103; + } else { + table_case = 112; + tdma_case = 103; + } + } + +exit: + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool wl_hi_pri = false; + u8 table_case, tdma_case; + u32 slot_type = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 || + coex_stat->wl_hi_pri_task2) + wl_hi_pri = true; + + if (efuse->share_ant) { + /* Shared-Ant */ + if (wl_hi_pri) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi hi-pri task\n"); + table_case = 15; + + if (coex_stat->bt_profile_num > 0) + tdma_case = 10; + else if (coex_stat->wl_hi_pri_task1) + tdma_case = 6; + else if (!coex_stat->bt_page) + tdma_case = 8; + else + tdma_case = 9; + } else if (coex_stat->wl_gl_busy) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi busy\n"); + if (coex_stat->bt_profile_num == 0) { + table_case = 12; + tdma_case = 18; + } else if (coex_stat->bt_profile_num == 1 && + !coex_stat->bt_a2dp_exist) { + slot_type = TDMA_4SLOT; + table_case = 12; + tdma_case = 20; + } else { + slot_type = TDMA_4SLOT; + table_case = 12; + tdma_case = 26; + } + } else if (coex_stat->wl_connected) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi connected\n"); + table_case = 9; + tdma_case = 27; + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi not-connected\n"); + table_case = 1; + tdma_case = 0; + } + } else { + /* Non_Shared-Ant */ + if (wl_hi_pri) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi hi-pri task\n"); + table_case = 114; + + if (coex_stat->bt_profile_num > 0) + tdma_case = 110; + else if (coex_stat->wl_hi_pri_task1) + tdma_case = 106; + else if (!coex_stat->bt_page) + tdma_case = 108; + else + tdma_case = 109; + } else if (coex_stat->wl_gl_busy) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi busy\n"); + table_case = 114; + tdma_case = 121; + } else if (coex_stat->wl_connected) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi connected\n"); + table_case = 101; + tdma_case = 100; + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt inq/page + wifi not-connected\n"); + table_case = 101; + tdma_case = 100; + } + } + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], wifi hi(%d), bt page(%d)\n", + wl_hi_pri, coex_stat->bt_page); + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_bt_game_hid(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_dm *coex_dm = &coex->dm; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + + if (efuse->share_ant) { + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + if (coex_stat->bt_whck_test) + table_case = 2; + else if (coex_stat->wl_linkscan_proc || coex_stat->bt_hid_exist) + table_case = 33; + else if (coex_stat->bt_setup_link || coex_stat->bt_inq_page) + table_case = 0; + else if (coex_stat->bt_a2dp_exist) + table_case = 34; + else + table_case = 33; + + tdma_case = 0; + } else { + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) + tdma_case = 112; + else + tdma_case = 113; + + table_case = 121; + } + + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]); + else + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]); + } else { + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 10; + tdma_case = 5; + } else { + /* Non-Shared-Ant */ + if (coex_stat->bt_multi_link) { + table_case = 112; + tdma_case = 117; + } else { + table_case = 105; + tdma_case = 100; + } + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool is_bt_ctr_hi = false, is_toggle_table = false; + u8 table_case, tdma_case; + u32 slot_type = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (coex_stat->bt_ctr_ok && + coex_stat->lo_pri_rx + coex_stat->lo_pri_tx > 360) + is_bt_ctr_hi = true; + + if (efuse->share_ant) { + /* Shared-Ant */ + if (coex_stat->bt_ble_exist) { + /* RCU */ + if (coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] > 5) { + table_case = 26; + tdma_case = 2; + } else { + table_case = 27; + tdma_case = 9; + } + } else { + /* Legacy HID */ + if (coex_stat->bt_a2dp_active) { + table_case = 9; + tdma_case = 18; + } else if (coex_stat->bt_profile_num == 1 && + (coex_stat->bt_multi_link && + (is_bt_ctr_hi || coex_stat->bt_slave || + coex_stat->bt_multi_link_remain))) { + if (coex_stat->wl_gl_busy && + (coex_stat->wl_rx_rate <= 3 || + coex_stat->wl_rts_rx_rate <= 3)) + table_case = 13; + else + table_case = 12; + + tdma_case = 26; + } else if (coex_stat->bt_418_hid_exist && + coex_stat->wl_gl_busy) { + is_toggle_table = true; + slot_type = TDMA_4SLOT; + table_case = 32; + tdma_case = 27; + } else if (coex_stat->bt_ble_hid_exist && + coex_stat->wl_gl_busy) { + table_case = 36; + tdma_case = 0; + } else { + table_case = 9; + tdma_case = 9; + } + } + } else { + /* Non-Shared-Ant */ + if (coex_stat->bt_ble_exist) { + /* BLE */ + if (coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] > 5) { + table_case = 121; + tdma_case = 102; + } else { + table_case = 122; + tdma_case = 109; + } + } else if (coex_stat->bt_a2dp_active) { + table_case = 113; + tdma_case = 118; + } else { + table_case = 113; + tdma_case = 104; + } + } + + rtw_coex_table(rtwdev, false, table_case); + if (is_toggle_table) { + rtw_btc_wltoggle_table_a(rtwdev, true, table_case); + rtw_btc_wltoggle_table_b(rtwdev, false, 1, COEX_WL_SLOT_TOGLLE); + } + + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_bt_a2dp(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + u32 slot_type = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + slot_type = TDMA_4SLOT; + + if (efuse->share_ant) { + /* Shared-Ant */ + if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0) + table_case = 12; + else + table_case = 9; + + if (coex_stat->wl_connecting || !coex_stat->wl_gl_busy) + tdma_case = 14; + else + tdma_case = 13; + } else { + /* Non-Shared-Ant */ + table_case = 112; + + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) + tdma_case = 112; + else + tdma_case = 113; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_bt_a2dpsink(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + bool ap_enable = false; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { /* Shared-Ant */ + if (ap_enable) { + table_case = 2; + tdma_case = 0; + } else if (coex_stat->wl_gl_busy) { + table_case = 28; + tdma_case = 20; + } else { + table_case = 28; + tdma_case = 26; + } + } else { /* Non-Shared-Ant */ + if (ap_enable) { + table_case = 100; + tdma_case = 100; + } else { + table_case = 119; + tdma_case = 120; + } + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_pan(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0) + table_case = 14; + else + table_case = 10; + + if (coex_stat->wl_gl_busy) + tdma_case = 17; + else + tdma_case = 20; + } else { + /* Non-Shared-Ant */ + table_case = 112; + + if (coex_stat->wl_gl_busy) + tdma_case = 117; + else + tdma_case = 119; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case, interval = 0; + u32 slot_type = 0; + bool is_toggle_table = false; + + slot_type = TDMA_4SLOT; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + if (coex_stat->bt_ble_exist) { + table_case = 26; /* for RCU */ + } else if (coex_stat->bt_418_hid_exist) { + table_case = 9; + interval = 1; + } else { + table_case = 9; + } + + if (coex_stat->wl_connecting || !coex_stat->wl_gl_busy) { + tdma_case = 14; + } else if (coex_stat->bt_418_hid_exist) { + is_toggle_table = true; + tdma_case = 23; + } else { + tdma_case = 13; + } + } else { + /* Non-Shared-Ant */ + if (coex_stat->bt_ble_exist) + table_case = 121; + else + table_case = 113; + + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) + tdma_case = 112; + else + tdma_case = 113; + } + + rtw_coex_table(rtwdev, false, table_case); + if (is_toggle_table) { + rtw_btc_wltoggle_table_a(rtwdev, true, table_case); + rtw_btc_wltoggle_table_b(rtwdev, false, interval, COEX_WL_SLOT_TOGLLE); + } + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + if (efuse->share_ant) { + /* Shared-Ant */ + if (coex_stat->wl_gl_busy && + coex_stat->wl_noisy_level == 0) + table_case = 14; + else + table_case = 10; + + if (coex_stat->wl_gl_busy) + tdma_case = 15; + else + tdma_case = 20; + } else { + /* Non-Shared-Ant */ + table_case = 112; + + if (coex_stat->wl_gl_busy) + tdma_case = 115; + else + tdma_case = 120; + } + + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_pan_hid(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 9; + + if (coex_stat->wl_gl_busy) + tdma_case = 18; + else + tdma_case = 19; + } else { + /* Non-Shared-Ant */ + table_case = 113; + + if (coex_stat->wl_gl_busy) + tdma_case = 117; + else + tdma_case = 119; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_bt_a2dp_pan_hid(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 10; + + if (coex_stat->wl_gl_busy) + tdma_case = 15; + else + tdma_case = 20; + } else { + /* Non-Shared-Ant */ + table_case = 113; + + if (coex_stat->wl_gl_busy) + tdma_case = 115; + else + tdma_case = 120; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false); + + if (coex_stat->bt_game_hid_exist && coex_stat->wl_linkscan_proc) + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 0; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_wl_only(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 2; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 table_case, tdma_case; + + if (coex->under_5g) + return; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 28; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + if (coex_stat->bt_game_hid_exist) { + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]); + else + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]); + } else { + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_wl_linkscan(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + u32 slot_type = 0; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { /* Shared-Ant */ + if (coex_stat->bt_a2dp_exist) { + slot_type = TDMA_4SLOT; + tdma_case = 11; + if (coex_stat->wl_gl_busy) + table_case = 26; + else + table_case = 9; + } else { + table_case = 9; + tdma_case = 7; + } + } else { /* Non-Shared-Ant */ + if (coex_stat->bt_a2dp_exist) { + slot_type = TDMA_4SLOT; + table_case = 112; + tdma_case = 111; + } else { + table_case = 112; + tdma_case = 107; + } + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); +} + +static void rtw_coex_action_wl_not_connected(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + + if (efuse->share_ant) { + /* Shared-Ant */ + table_case = 1; + tdma_case = 0; + } else { + /* Non-Shared-Ant */ + table_case = 100; + tdma_case = 100; + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + +static void rtw_coex_action_wl_connected(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 algorithm; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + algorithm = rtw_coex_algorithm(rtwdev); + + switch (algorithm) { + case COEX_ALGO_HFP: + rtw_coex_action_bt_hfp(rtwdev); + break; + case COEX_ALGO_HID: + if (rtw_coex_freerun_check(rtwdev)) + rtw_coex_action_freerun(rtwdev); + else + rtw_coex_action_bt_hid(rtwdev); + break; + case COEX_ALGO_A2DP: + if (rtw_coex_freerun_check(rtwdev)) + rtw_coex_action_freerun(rtwdev); + else if (coex_stat->bt_a2dp_sink) + rtw_coex_action_bt_a2dpsink(rtwdev); + else + rtw_coex_action_bt_a2dp(rtwdev); + break; + case COEX_ALGO_PAN: + rtw_coex_action_bt_pan(rtwdev); + break; + case COEX_ALGO_A2DP_HID: + if (rtw_coex_freerun_check(rtwdev)) + rtw_coex_action_freerun(rtwdev); + else + rtw_coex_action_bt_a2dp_hid(rtwdev); + break; + case COEX_ALGO_A2DP_PAN: + rtw_coex_action_bt_a2dp_pan(rtwdev); + break; + case COEX_ALGO_PAN_HID: + rtw_coex_action_bt_pan_hid(rtwdev); + break; + case COEX_ALGO_A2DP_PAN_HID: + rtw_coex_action_bt_a2dp_pan_hid(rtwdev); + break; + default: + case COEX_ALGO_NOPROFILE: + rtw_coex_action_bt_idle(rtwdev); + break; + } +} + +static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_stat *coex_stat = &coex->stat; + bool rf4ce_en = false; + + lockdep_assert_held(&rtwdev->mutex); + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + return; + + coex_dm->reason = reason; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): reason = %d\n", __func__, + reason); + + /* update wifi_link_info_ext variable */ + rtw_coex_update_wl_link_info(rtwdev, reason); + + rtw_coex_monitor_bt_enable(rtwdev); + + if (coex->manual_control) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], return for Manual CTRL!!\n"); + return; + } + + if (coex->stop_dm) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], return for Stop Coex DM!!\n"); + return; + } + + if (coex_stat->wl_under_ips) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], return for wifi is under IPS!!\n"); + return; + } + + if (coex->freeze && coex_dm->reason == COEX_RSN_BTINFO && + !coex_stat->bt_setup_link) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], return for coex_freeze!!\n"); + return; + } + + coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN]++; + coex->freerun = false; + + /* Pure-5G Coex Process */ + if (coex->under_5g) { + coex_stat->wl_coex_mode = COEX_WLINK_5G; + rtw_coex_action_wl_under5g(rtwdev); + goto exit; + } + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WiFi is single-port 2G!!\n"); + coex_stat->wl_coex_mode = COEX_WLINK_2G1PORT; + + if (coex_stat->bt_disabled) { + if (coex_stat->wl_connected && rf4ce_en) + rtw_coex_action_rf4ce(rtwdev); + else if (!coex_stat->wl_connected) + rtw_coex_action_wl_not_connected(rtwdev); + else + rtw_coex_action_wl_only(rtwdev); + goto exit; + } + + if (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) { + rtw_coex_action_wl_native_lps(rtwdev); + goto exit; + } + + if (coex_stat->bt_game_hid_exist && coex_stat->wl_connected) { + rtw_coex_action_bt_game_hid(rtwdev); + goto exit; + } + + if (coex_stat->bt_whck_test) { + rtw_coex_action_bt_whql_test(rtwdev); + goto exit; + } + + if (coex_stat->bt_setup_link) { + rtw_coex_action_bt_relink(rtwdev); + goto exit; + } + + if (coex_stat->bt_inq_page) { + rtw_coex_action_bt_inquiry(rtwdev); + goto exit; + } + + if ((coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE || + coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE) && + coex_stat->wl_connected) { + rtw_coex_action_bt_idle(rtwdev); + goto exit; + } + + if (coex_stat->wl_linkscan_proc && !coex->freerun) { + rtw_coex_action_wl_linkscan(rtwdev); + goto exit; + } + + if (coex_stat->wl_connected) { + rtw_coex_action_wl_connected(rtwdev); + goto exit; + } else { + rtw_coex_action_wl_not_connected(rtwdev); + goto exit; + } + +exit: + + if (chip->wl_mimo_ps_support) { + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + if (coex_dm->reason == COEX_RSN_2GMEDIA) + rtw_coex_mimo_ps(rtwdev, true, true); + else + rtw_coex_mimo_ps(rtwdev, false, true); + } else { + rtw_coex_mimo_ps(rtwdev, false, false); + } + } + + rtw_coex_gnt_workaround(rtwdev, false, coex_stat->wl_coex_mode); + rtw_coex_limited_wl(rtwdev); +} + +static void rtw_coex_init_coex_var(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + u8 i; + + memset(coex_dm, 0, sizeof(*coex_dm)); + memset(coex_stat, 0, sizeof(*coex_stat)); + + for (i = 0; i < COEX_CNT_WL_MAX; i++) + coex_stat->cnt_wl[i] = 0; + + for (i = 0; i < COEX_CNT_BT_MAX; i++) + coex_stat->cnt_bt[i] = 0; + + for (i = 0; i < ARRAY_SIZE(coex_dm->bt_rssi_state); i++) + coex_dm->bt_rssi_state[i] = COEX_RSSI_STATE_LOW; + + for (i = 0; i < ARRAY_SIZE(coex_dm->wl_rssi_state); i++) + coex_dm->wl_rssi_state[i] = COEX_RSSI_STATE_LOW; + + coex_stat->wl_coex_mode = COEX_WLINK_MAX; + coex_stat->wl_rx_rate = DESC_RATE5_5M; + coex_stat->wl_rts_rx_rate = DESC_RATE5_5M; +} + +static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + rtw_coex_init_coex_var(rtwdev); + + coex_stat->kt_ver = u8_get_bits(rtw_read8(rtwdev, 0xf1), GENMASK(7, 4)); + + rtw_coex_monitor_bt_enable(rtwdev); + rtw_coex_wl_slot_extend(rtwdev, coex_stat->wl_slot_extend); + + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + rtw_coex_set_rfe_type(rtwdev); + rtw_coex_set_init(rtwdev); + + /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */ + rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_RSP, 1); + + /* set Tx beacon = Hi-Pri */ + rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACON, 1); + + /* set Tx beacon queue = Hi-Pri */ + rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACONQ, 1); + + /* antenna config */ + if (coex->wl_rf_off) { + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF); + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false); + coex->stop_dm = true; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): RF Off\n", + __func__); + } else if (wifi_only) { + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WONLY); + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, + true); + coex->stop_dm = true; + } else { + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_INIT); + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, + true); + coex->stop_dm = false; + coex->freeze = true; + } + + /* PTA parameter */ + rtw_coex_table(rtwdev, true, 1); + rtw_coex_tdma(rtwdev, true, 0); + rtw_coex_query_bt_info(rtwdev); +} + +void rtw_coex_power_on_setting(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + u8 table_case = 1; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + + coex->stop_dm = true; + coex->wl_rf_off = false; + + /* enable BB, we can write 0x948 */ + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + + rtw_coex_monitor_bt_enable(rtwdev); + rtw_coex_set_rfe_type(rtwdev); + + /* set antenna path to BT */ + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_POWERON); + + rtw_coex_table(rtwdev, true, table_case); + /* red x issue */ + rtw_write8(rtwdev, 0xff1a, 0x0); + rtw_coex_set_gnt_debug(rtwdev); +} +EXPORT_SYMBOL(rtw_coex_power_on_setting); + +void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) +{ + rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); +} +EXPORT_SYMBOL(rtw_coex_power_off_setting); + +void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) +{ + __rtw_coex_init_hw_config(rtwdev, wifi_only); +} +EXPORT_SYMBOL(rtw_coex_init_hw_config); + +void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + if (type == COEX_IPS_ENTER) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], IPS ENTER notify\n"); + + coex_stat->wl_under_ips = true; + + /* for lps off */ + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF); + rtw_coex_action_coex_all_off(rtwdev); + } else if (type == COEX_IPS_LEAVE) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], IPS LEAVE notify\n"); + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true); + /* run init hw config (exclude wifi only) */ + __rtw_coex_init_hw_config(rtwdev, false); + + coex_stat->wl_under_ips = false; + } +} + +void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + if (type == COEX_LPS_ENABLE) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], LPS ENABLE notify\n"); + + coex_stat->wl_under_lps = true; + + if (coex_stat->wl_force_lps_ctrl) { + /* for ps-tdma */ + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true); + } else { + /* for native ps */ + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, false); + rtw_coex_write_scbd(rtwdev, COEX_SCBD_WLBUSY, false); + + rtw_coex_run_coex(rtwdev, COEX_RSN_LPS); + } + } else if (type == COEX_LPS_DISABLE) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], LPS DISABLE notify\n"); + + coex_stat->wl_under_lps = false; + + /* for lps off */ + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true); + + if (!coex_stat->wl_force_lps_ctrl) + rtw_coex_query_bt_info(rtwdev); + + rtw_coex_run_coex(rtwdev, COEX_RSN_LPS); + } +} + +void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + coex->freeze = false; + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true); + + if (type == COEX_SCAN_START_5G) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], SCAN START notify (5G)\n"); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G); + rtw_coex_run_coex(rtwdev, COEX_RSN_5GSCANSTART); + } else if ((type == COEX_SCAN_START_2G) || (type == COEX_SCAN_START)) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], SCAN START notify (2G)\n"); + + coex_stat->wl_hi_pri_task2 = true; + + /* Force antenna setup for no scan result issue */ + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G); + rtw_coex_run_coex(rtwdev, COEX_RSN_2GSCANSTART); + } else { + coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] = 30; /* To do */ + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n", + coex_stat->cnt_wl[COEX_CNT_WL_SCANAP]); + + coex_stat->wl_hi_pri_task2 = false; + rtw_coex_run_coex(rtwdev, COEX_RSN_SCANFINISH); + } +} + +void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + + if (coex->manual_control || coex->stop_dm) + return; + + if (type == COEX_SWITCH_TO_5G) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): TO_5G\n", + __func__); + } else if (type == COEX_SWITCH_TO_24G_NOFORSCAN) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): TO_24G_NOFORSCAN\n", __func__); + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): TO_2G\n", + __func__); + } + + if (type == COEX_SWITCH_TO_5G) + rtw_coex_run_coex(rtwdev, COEX_RSN_5GSWITCHBAND); + else if (type == COEX_SWITCH_TO_24G_NOFORSCAN) + rtw_coex_run_coex(rtwdev, COEX_RSN_2GSWITCHBAND); + else + rtw_coex_scan_notify(rtwdev, COEX_SCAN_START_2G); +} + +void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true); + + if (type == COEX_ASSOCIATE_5G_START) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G start\n", + __func__); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G); + rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONSTART); + } else if (type == COEX_ASSOCIATE_5G_FINISH) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G finish\n", + __func__); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G); + rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONFINISH); + } else if (type == COEX_ASSOCIATE_START) { + coex_stat->wl_hi_pri_task1 = true; + coex_stat->wl_connecting = true; + coex_stat->cnt_wl[COEX_CNT_WL_CONNPKT] = 2; + coex_stat->wl_connecting = true; + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->wl_connecting_work, 2 * HZ); + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G start\n", + __func__); + /* Force antenna setup for no scan result issue */ + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G); + + rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONSTART); + + /* To keep TDMA case during connect process, + * to avoid changed by Btinfo and runcoexmechanism + */ + coex->freeze = true; + ieee80211_queue_delayed_work(rtwdev->hw, &coex->defreeze_work, + 5 * HZ); + } else { + coex_stat->wl_hi_pri_task1 = false; + coex->freeze = false; + coex_stat->wl_connecting = false; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G finish\n", + __func__); + rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONFINISH); + } +} + +void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + if (coex->manual_control || coex->stop_dm) + return; + + if (type == COEX_MEDIA_CONNECT_5G) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G\n", __func__); + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true); + + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G); + rtw_coex_run_coex(rtwdev, COEX_RSN_5GMEDIA); + } else if (type == COEX_MEDIA_CONNECT) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G\n", __func__); + + coex_stat->wl_connecting = false; + + rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true); + + /* Force antenna setup for no scan result issue */ + rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G); + + /* Set CCK Rx high Pri */ + rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 1); + rtw_coex_run_coex(rtwdev, COEX_RSN_2GMEDIA); + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): disconnect!!\n", + __func__); + rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 0); + rtw_coex_run_coex(rtwdev, COEX_RSN_MEDIADISCON); + } + + rtw_coex_update_wl_ch_info(rtwdev, type); +} + +void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + u32 bt_relink_time; + u8 i, rsp_source = 0, type; + bool inq_page = false; + + rsp_source = buf[0] & 0xf; + if (rsp_source >= COEX_BTINFO_SRC_MAX) + return; + coex_stat->cnt_bt_info_c2h[rsp_source]++; + + if (rsp_source == COEX_BTINFO_SRC_BT_IQK) { + coex_stat->bt_iqk_state = buf[1]; + if (coex_stat->bt_iqk_state == 0) + coex_stat->cnt_bt[COEX_CNT_BT_IQK]++; + else if (coex_stat->bt_iqk_state == 2) + coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]++; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT IQK by bt_info, data0 = 0x%02x\n", + buf[1]); + + return; + } + + if (rsp_source == COEX_BTINFO_SRC_BT_SCBD) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT Scoreboard change notify by WL FW c2h, 0xaa = 0x%02x, 0xab = 0x%02x\n", + buf[1], buf[2]); + + rtw_coex_monitor_bt_enable(rtwdev); + if (coex_stat->bt_disabled != coex_stat->bt_disabled_pre) { + coex_stat->bt_disabled_pre = coex_stat->bt_disabled; + rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO); + } + return; + } + + if (rsp_source == COEX_BTINFO_SRC_H2C60) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], H2C 0x60 content replied by WL FW: H2C_0x60 = [%02x %02x %02x %02x %02x]\n", + buf[1], buf[2], buf[3], buf[4], buf[5]); + + for (i = 1; i <= COEX_WL_TDMA_PARA_LENGTH; i++) + coex_dm->fw_tdma_para[i - 1] = buf[i]; + return; + } + + if (rsp_source == COEX_BTINFO_SRC_WL_FW) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], bt_info reply by WL FW\n"); + + rtw_coex_update_bt_link_info(rtwdev); + return; + } + + if (rsp_source == COEX_BTINFO_SRC_BT_RSP || + rsp_source == COEX_BTINFO_SRC_BT_ACT) { + if (coex_stat->bt_disabled) { + coex_stat->bt_disabled = false; + coex_stat->bt_reenable = true; + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_reenable_work, + 15 * HZ); + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT enable detected by bt_info\n"); + } + } + + if (length != COEX_BTINFO_LENGTH) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Bt_info length = %d invalid!!\n", length); + + return; + } + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n", + buf[0], length, buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + for (i = 0; i < COEX_BTINFO_LENGTH; i++) + coex_stat->bt_info_c2h[rsp_source][i] = buf[i]; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + coex_stat->bt_info_c2h[rsp_source][5] = 0; + + /* get the same info from bt, skip it */ + if (coex_stat->bt_info_c2h[rsp_source][1] == coex_stat->bt_info_lb2 && + coex_stat->bt_info_c2h[rsp_source][2] == coex_stat->bt_info_lb3 && + coex_stat->bt_info_c2h[rsp_source][3] == coex_stat->bt_info_hb0 && + coex_stat->bt_info_c2h[rsp_source][4] == coex_stat->bt_info_hb1 && + coex_stat->bt_info_c2h[rsp_source][5] == coex_stat->bt_info_hb2 && + coex_stat->bt_info_c2h[rsp_source][6] == coex_stat->bt_info_hb3) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Return because Btinfo duplicate!!\n"); + return; + } + + coex_stat->bt_info_lb2 = coex_stat->bt_info_c2h[rsp_source][1]; + coex_stat->bt_info_lb3 = coex_stat->bt_info_c2h[rsp_source][2]; + coex_stat->bt_info_hb0 = coex_stat->bt_info_c2h[rsp_source][3]; + coex_stat->bt_info_hb1 = coex_stat->bt_info_c2h[rsp_source][4]; + coex_stat->bt_info_hb2 = coex_stat->bt_info_c2h[rsp_source][5]; + coex_stat->bt_info_hb3 = coex_stat->bt_info_c2h[rsp_source][6]; + + /* 0xff means BT is under WHCK test */ + coex_stat->bt_whck_test = (coex_stat->bt_info_lb2 == 0xff); + + inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2)); + + if (inq_page != coex_stat->bt_inq_page) { + cancel_delayed_work_sync(&coex->bt_remain_work); + coex_stat->bt_inq_page = inq_page; + + if (inq_page) + coex_stat->bt_inq_remain = true; + else + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_remain_work, + 4 * HZ); + } + coex_stat->bt_acl_busy = ((coex_stat->bt_info_lb2 & BIT(3)) == BIT(3)); + if (chip->ble_hid_profile_support) { + if (coex_stat->bt_info_lb2 & BIT(5)) { + if (coex_stat->bt_info_hb1 & BIT(0)) { + /*BLE HID*/ + coex_stat->bt_ble_hid_exist = true; + } else { + coex_stat->bt_ble_hid_exist = false; + } + coex_stat->bt_ble_exist = false; + } else if (coex_stat->bt_info_hb1 & BIT(0)) { + /*RCU*/ + coex_stat->bt_ble_hid_exist = false; + coex_stat->bt_ble_exist = true; + } else { + coex_stat->bt_ble_hid_exist = false; + coex_stat->bt_ble_exist = false; + } + } else { + if (coex_stat->bt_info_hb1 & BIT(0)) { + if (coex_stat->bt_hid_slot == 1 && + coex_stat->hi_pri_rx + 100 < coex_stat->hi_pri_tx && + coex_stat->hi_pri_rx < 100) { + coex_stat->bt_ble_hid_exist = true; + coex_stat->bt_ble_exist = false; + } else { + coex_stat->bt_ble_hid_exist = false; + coex_stat->bt_ble_exist = true; + } + } else { + coex_stat->bt_ble_hid_exist = false; + coex_stat->bt_ble_exist = false; + } + } + + coex_stat->cnt_bt[COEX_CNT_BT_RETRY] = coex_stat->bt_info_lb3 & 0xf; + if (coex_stat->cnt_bt[COEX_CNT_BT_RETRY] >= 1) + coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]++; + + coex_stat->bt_fix_2M = ((coex_stat->bt_info_lb3 & BIT(4)) == BIT(4)); + coex_stat->bt_inq = ((coex_stat->bt_info_lb3 & BIT(5)) == BIT(5)); + if (coex_stat->bt_inq) + coex_stat->cnt_bt[COEX_CNT_BT_INQ]++; + + coex_stat->bt_page = ((coex_stat->bt_info_lb3 & BIT(7)) == BIT(7)); + if (coex_stat->bt_page) + coex_stat->cnt_bt[COEX_CNT_BT_PAGE]++; + + /* unit: % (value-100 to translate to unit: dBm in coex info) */ + if (chip->bt_rssi_type == COEX_BTRSSI_RATIO) { + coex_stat->bt_rssi = coex_stat->bt_info_hb0 * 2 + 10; + } else { + if (coex_stat->bt_info_hb0 <= 127) + coex_stat->bt_rssi = 100; + else if (256 - coex_stat->bt_info_hb0 <= 100) + coex_stat->bt_rssi = 100 - (256 - coex_stat->bt_info_hb0); + else + coex_stat->bt_rssi = 0; + } + + if (coex_stat->bt_info_hb1 & BIT(1)) + coex_stat->cnt_bt[COEX_CNT_BT_REINIT]++; + + if (coex_stat->bt_info_hb1 & BIT(2)) { + coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK]++; + coex_stat->bt_setup_link = true; + if (coex_stat->bt_reenable) + bt_relink_time = 6 * HZ; + else + bt_relink_time = 1 * HZ; + + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_relink_work, + bt_relink_time); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Re-Link start in BT info!!\n"); + } + + if (coex_stat->bt_info_hb1 & BIT(3)) + coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT]++; + + coex_stat->bt_ble_voice = ((coex_stat->bt_info_hb1 & BIT(4)) == BIT(4)); + coex_stat->bt_ble_scan_en = ((coex_stat->bt_info_hb1 & BIT(5)) == BIT(5)); + if (coex_stat->bt_info_hb1 & BIT(6)) + coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH]++; + + coex_stat->bt_multi_link = ((coex_stat->bt_info_hb1 & BIT(7)) == BIT(7)); + /* for multi_link = 0 but bt pkt remain exist */ + /* Use PS-TDMA to protect WL RX */ + if (!coex_stat->bt_multi_link && coex_stat->bt_multi_link_pre) { + coex_stat->bt_multi_link_remain = true; + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_multi_link_remain_work, + 3 * HZ); + } + coex_stat->bt_multi_link_pre = coex_stat->bt_multi_link; + + /* resend wifi info to bt, it is reset and lost the info */ + if (coex_stat->bt_info_hb1 & BIT(1)) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT Re-init, send wifi BW & Chnl to BT!!\n"); + + if (coex_stat->wl_connected) + type = COEX_MEDIA_CONNECT; + else + type = COEX_MEDIA_DISCONNECT; + rtw_coex_update_wl_ch_info(rtwdev, type); + } + + /* if ignore_wlan_act && not set_up_link */ + if ((coex_stat->bt_info_hb1 & BIT(3)) && + (!(coex_stat->bt_info_hb1 & BIT(2)))) { + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); + rtw_coex_ignore_wlan_act(rtwdev, false); + } + + coex_stat->bt_opp_exist = ((coex_stat->bt_info_hb2 & BIT(0)) == BIT(0)); + if (coex_stat->bt_info_hb2 & BIT(1)) + coex_stat->cnt_bt[COEX_CNT_BT_AFHUPDATE]++; + + coex_stat->bt_a2dp_active = (coex_stat->bt_info_hb2 & BIT(2)) == BIT(2); + coex_stat->bt_slave = ((coex_stat->bt_info_hb2 & BIT(3)) == BIT(3)); + coex_stat->bt_hid_slot = (coex_stat->bt_info_hb2 & 0x30) >> 4; + coex_stat->bt_hid_pair_num = (coex_stat->bt_info_hb2 & 0xc0) >> 6; + if (coex_stat->bt_hid_pair_num > 0 && coex_stat->bt_hid_slot >= 2) + coex_stat->bt_418_hid_exist = true; + else if (coex_stat->bt_hid_pair_num == 0 || coex_stat->bt_hid_slot == 1) + coex_stat->bt_418_hid_exist = false; + + if ((coex_stat->bt_info_lb2 & 0x49) == 0x49) + coex_stat->bt_a2dp_bitpool = (coex_stat->bt_info_hb3 & 0x7f); + else + coex_stat->bt_a2dp_bitpool = 0; + + coex_stat->bt_a2dp_sink = ((coex_stat->bt_info_hb3 & BIT(7)) == BIT(7)); + + rtw_coex_update_bt_link_info(rtwdev); + rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO); +} + +#define COEX_BT_HIDINFO_MTK 0x46 +static const u8 coex_bt_hidinfo_ps[] = {0x57, 0x69, 0x72}; +static const u8 coex_bt_hidinfo_xb[] = {0x58, 0x62, 0x6f}; + +void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_hid *hidinfo; + struct rtw_coex_hid_info_a *hida; + struct rtw_coex_hid_handle_list *hl, *bhl; + u8 sub_id = buf[2], gamehid_cnt = 0, handle, i; + bool cur_game_hid_exist, complete; + + if (!chip->wl_mimo_ps_support && + (sub_id == COEX_BT_HIDINFO_LIST || sub_id == COEX_BT_HIDINFO_A)) + return; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], HID info notify, sub_id = 0x%x\n", sub_id); + + switch (sub_id) { + case COEX_BT_HIDINFO_LIST: + hl = &coex_stat->hid_handle_list; + bhl = (struct rtw_coex_hid_handle_list *)buf; + if (!memcmp(hl, bhl, sizeof(*hl))) + return; + coex_stat->hid_handle_list = *bhl; + memset(&coex_stat->hid_info, 0, sizeof(coex_stat->hid_info)); + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + if (hl->handle[i] != COEX_BT_HIDINFO_NOTCON && + hl->handle[i] != 0) + hidinfo->hid_handle = hl->handle[i]; + } + break; + case COEX_BT_HIDINFO_A: + hida = (struct rtw_coex_hid_info_a *)buf; + handle = hida->handle; + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + if (hidinfo->hid_handle == handle) { + hidinfo->hid_vendor = hida->vendor; + memcpy(hidinfo->hid_name, hida->name, + sizeof(hidinfo->hid_name)); + hidinfo->hid_info_completed = true; + break; + } + } + break; + } + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + complete = hidinfo->hid_info_completed; + handle = hidinfo->hid_handle; + if (!complete || handle == COEX_BT_HIDINFO_NOTCON || + handle == 0 || handle >= COEX_BT_BLE_HANDLE_THRS) { + hidinfo->is_game_hid = false; + continue; + } + + if (hidinfo->hid_vendor == COEX_BT_HIDINFO_MTK) { + if ((memcmp(hidinfo->hid_name, + coex_bt_hidinfo_ps, + COEX_BT_HIDINFO_NAME)) == 0) + hidinfo->is_game_hid = true; + else if ((memcmp(hidinfo->hid_name, + coex_bt_hidinfo_xb, + COEX_BT_HIDINFO_NAME)) == 0) + hidinfo->is_game_hid = true; + else + hidinfo->is_game_hid = false; + } else { + hidinfo->is_game_hid = false; + } + if (hidinfo->is_game_hid) + gamehid_cnt++; + } + + if (gamehid_cnt > 0) + cur_game_hid_exist = true; + else + cur_game_hid_exist = false; + + if (cur_game_hid_exist != coex_stat->bt_game_hid_exist) { + coex_stat->bt_game_hid_exist = cur_game_hid_exist; + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], HID info changed!bt_game_hid_exist = %d!\n", + coex_stat->bt_game_hid_exist); + rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); + } +} + +void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_hid *hidinfo; + u8 i, handle; + bool complete; + + if (!chip->wl_mimo_ps_support || coex_stat->wl_under_ips || + (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl)) + return; + + if (!coex_stat->bt_hid_exist && + !((coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION) && + (coex_stat->hi_pri_tx + coex_stat->hi_pri_rx > + COEX_BT_GAMEHID_CNT))) + return; + + rtw_fw_coex_query_hid_info(rtwdev, COEX_BT_HIDINFO_LIST, 0); + + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + complete = hidinfo->hid_info_completed; + handle = hidinfo->hid_handle; + if (handle == 0 || handle == COEX_BT_HIDINFO_NOTCON || + handle >= COEX_BT_BLE_HANDLE_THRS || complete) + continue; + + rtw_fw_coex_query_hid_info(rtwdev, + COEX_BT_HIDINFO_A, + handle); + } +} + +void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u8 val; + int i; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], WiFi Fw Dbg info = %8ph (len = %d)\n", + buf, length); + if (WARN(length < 8, "invalid wl info c2h length\n")) + return; + + if (buf[0] != 0x08) + return; + + for (i = 1; i < 8; i++) { + val = coex_stat->wl_fw_dbg_info_pre[i]; + if (buf[i] >= val) + coex_stat->wl_fw_dbg_info[i] = buf[i] - val; + else + coex_stat->wl_fw_dbg_info[i] = 255 - val + buf[i]; + + coex_stat->wl_fw_dbg_info_pre[i] = buf[i]; + } + + coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]++; + rtw_coex_wl_ccklock_action(rtwdev); + rtw_coex_wl_ccklock_detect(rtwdev); +} + +void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type) +{ + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); +} + +void rtw_coex_wl_status_check(struct rtw_dev *rtwdev) +{ + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + if ((coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) || + coex_stat->wl_under_ips) + return; + + rtw_coex_monitor_bt_ctr(rtwdev); +} + +void rtw_coex_bt_relink_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.bt_relink_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->bt_setup_link = false; + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_bt_reenable_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.bt_reenable_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->bt_reenable = false; + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_defreeze_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.defreeze_work.work); + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex->freeze = false; + coex_stat->wl_hi_pri_task1 = false; + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_wl_remain_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.wl_remain_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_bt_remain_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.bt_remain_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->bt_inq_remain = coex_stat->bt_inq_page; + rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_wl_connecting_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.wl_connecting_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->wl_connecting = false; + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WL connecting stop!!\n"); + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_bt_multi_link_remain_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.bt_multi_link_remain_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->bt_multi_link_remain = false; + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_wl_ccklock_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.wl_ccklock_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->wl_cck_lock = false; + mutex_unlock(&rtwdev->mutex); +} + +#ifdef CONFIG_RTW88_DEBUGFS +#define INFO_SIZE 80 + +#define case_BTINFO(src) \ + case COEX_BTINFO_SRC_##src: return #src + +static const char *rtw_coex_get_bt_info_src_string(u8 bt_info_src) +{ + switch (bt_info_src) { + case_BTINFO(WL_FW); + case_BTINFO(BT_RSP); + case_BTINFO(BT_ACT); + default: + return "Unknown"; + } +} + +#define case_RSN(src) \ + case COEX_RSN_##src: return #src + +static const char *rtw_coex_get_reason_string(u8 reason) +{ + switch (reason) { + case_RSN(2GSCANSTART); + case_RSN(5GSCANSTART); + case_RSN(SCANFINISH); + case_RSN(2GSWITCHBAND); + case_RSN(5GSWITCHBAND); + case_RSN(2GCONSTART); + case_RSN(5GCONSTART); + case_RSN(2GCONFINISH); + case_RSN(5GCONFINISH); + case_RSN(2GMEDIA); + case_RSN(5GMEDIA); + case_RSN(MEDIADISCON); + case_RSN(BTINFO); + case_RSN(LPS); + case_RSN(WLSTATUS); + default: + return "Unknown"; + } +} + +static u8 rtw_coex_get_table_index(struct rtw_dev *rtwdev, u32 wl_reg_6c0, + u32 wl_reg_6c4) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 ans = 0xFF; + u8 n, i; + u32 load_bt_val; + u32 load_wl_val; + bool share_ant = efuse->share_ant; + + if (share_ant) + n = chip->table_sant_num; + else + n = chip->table_nsant_num; + + for (i = 0; i < n; i++) { + if (share_ant) { + load_bt_val = chip->table_sant[i].bt; + load_wl_val = chip->table_sant[i].wl; + } else { + load_bt_val = chip->table_nsant[i].bt; + load_wl_val = chip->table_nsant[i].wl; + } + + if (wl_reg_6c0 == load_bt_val && + wl_reg_6c4 == load_wl_val) { + ans = i; + if (!share_ant) + ans += 100; + break; + } + } + + return ans; +} + +static u8 rtw_coex_get_tdma_index(struct rtw_dev *rtwdev, u8 *tdma_para) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 ans = 0xFF; + u8 n, i, j; + u8 load_cur_tab_val; + bool valid = false; + bool share_ant = efuse->share_ant; + + if (share_ant) + n = chip->tdma_sant_num; + else + n = chip->tdma_nsant_num; + + for (i = 0; i < n; i++) { + valid = false; + for (j = 0; j < 5; j++) { + if (share_ant) + load_cur_tab_val = chip->tdma_sant[i].para[j]; + else + load_cur_tab_val = chip->tdma_nsant[i].para[j]; + + if (*(tdma_para + j) != load_cur_tab_val) + break; + + if (j == 4) + valid = true; + } + if (valid) { + ans = i; + break; + } + } + + return ans; +} + +static int rtw_coex_addr_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char addr_info[], int n) +{ + const char *rf_prefix = ""; + const char *sep = n == 0 ? "" : "/ "; + int ffs, fls; + int max_fls; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + max_fls = 31; + break; + case RTW_REG_DOMAIN_MAC16: + max_fls = 15; + break; + case RTW_REG_DOMAIN_MAC8: + max_fls = 7; + break; + case RTW_REG_DOMAIN_RF_A: + case RTW_REG_DOMAIN_RF_B: + rf_prefix = "RF_"; + max_fls = 19; + break; + default: + return 0; + } + + ffs = __ffs(reg->mask); + fls = __fls(reg->mask); + + if (ffs == 0 && fls == max_fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x", + sep, rf_prefix, reg->addr); + else if (ffs == fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d]", + sep, rf_prefix, reg->addr, ffs); + else + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d:%d]", + sep, rf_prefix, reg->addr, fls, ffs); +} + +static int rtw_coex_val_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char val_info[], int n) +{ + const char *sep = n == 0 ? "" : "/ "; + u8 rf_path; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read32_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC16: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read16_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC8: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read8_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_RF_A: + rf_path = RF_PATH_A; + break; + case RTW_REG_DOMAIN_RF_B: + rf_path = RF_PATH_B; + break; + default: + return 0; + } + + /* only RF go through here */ + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read_rf(rtwdev, rf_path, reg->addr, reg->mask)); +} + +static void rtw_coex_set_coexinfo_hw(struct rtw_dev *rtwdev, struct seq_file *m) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_reg_domain *reg; + char addr_info[INFO_SIZE]; + int n_addr = 0; + char val_info[INFO_SIZE]; + int n_val = 0; + int i; + + for (i = 0; i < chip->coex_info_hw_regs_num; i++) { + reg = &chip->coex_info_hw_regs[i]; + + n_addr += rtw_coex_addr_info(rtwdev, reg, addr_info, n_addr); + n_val += rtw_coex_val_info(rtwdev, reg, val_info, n_val); + + if (reg->domain == RTW_REG_DOMAIN_NL) { + seq_printf(m, "%-40s = %s\n", addr_info, val_info); + n_addr = 0; + n_val = 0; + } + } + + if (n_addr != 0 && n_val != 0) + seq_printf(m, "%-40s = %s\n", addr_info, val_info); +} + +static bool rtw_coex_get_bt_reg(struct rtw_dev *rtwdev, + u8 type, u16 addr, u16 *val) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + __le16 le_addr; + u8 *payload; + + le_addr = cpu_to_le16(addr); + req.op_code = BT_MP_INFO_OP_READ_REG; + req.para1 = type; + req.para2 = le16_get_bits(le_addr, GENMASK(7, 0)); + req.para3 = le16_get_bits(le_addr, GENMASK(15, 8)); + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) { + *val = 0xeaea; + return false; + } + + payload = get_payload_from_coex_resp(skb); + *val = GET_COEX_RESP_BT_REG_VAL(payload); + dev_kfree_skb_any(skb); + + return true; +} + +static bool rtw_coex_get_bt_patch_version(struct rtw_dev *rtwdev, + u32 *patch_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + + req.op_code = BT_MP_INFO_OP_PATCH_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + return false; + + payload = get_payload_from_coex_resp(skb); + *patch_version = GET_COEX_RESP_BT_PATCH_VER(payload); + dev_kfree_skb_any(skb); + + return true; +} + +static bool rtw_coex_get_bt_supported_version(struct rtw_dev *rtwdev, + u32 *supported_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + + req.op_code = BT_MP_INFO_OP_SUPP_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + return false; + + payload = get_payload_from_coex_resp(skb); + *supported_version = GET_COEX_RESP_BT_SUPP_VER(payload); + dev_kfree_skb_any(skb); + + return true; +} + +static bool rtw_coex_get_bt_supported_feature(struct rtw_dev *rtwdev, + u32 *supported_feature) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + + req.op_code = BT_MP_INFO_OP_SUPP_FEAT; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + return false; + + payload = get_payload_from_coex_resp(skb); + *supported_feature = GET_COEX_RESP_BT_SUPP_FEAT(payload); + dev_kfree_skb_any(skb); + + return true; +} + +struct rtw_coex_sta_stat_iter_data { + struct rtw_vif *rtwvif; + struct seq_file *file; +}; + +static void rtw_coex_sta_stat_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_coex_sta_stat_iter_data *sta_iter_data = data; + struct rtw_vif *rtwvif = sta_iter_data->rtwvif; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct seq_file *m = sta_iter_data->file; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 rssi; + + if (si->vif != vif) + return; + + rssi = ewma_rssi_read(&si->avg_rssi); + seq_printf(m, "\tPeer %3d\n", si->mac_id); + seq_printf(m, "\t\t%-24s = %d\n", "RSSI", rssi); + seq_printf(m, "\t\t%-24s = %d\n", "BW mode", si->bw_mode); +} + +struct rtw_coex_vif_stat_iter_data { + struct rtw_dev *rtwdev; + struct seq_file *file; +}; + +static void rtw_coex_vif_stat_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_coex_vif_stat_iter_data *vif_iter_data = data; + struct rtw_coex_sta_stat_iter_data sta_iter_data; + struct rtw_dev *rtwdev = vif_iter_data->rtwdev; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct seq_file *m = vif_iter_data->file; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + seq_printf(m, "Iface on Port (%d)\n", rtwvif->port); + seq_printf(m, "\t%-32s = %d\n", + "Beacon interval", bss_conf->beacon_int); + seq_printf(m, "\t%-32s = %d\n", + "Network Type", rtwvif->net_type); + + sta_iter_data.rtwvif = rtwvif; + sta_iter_data.file = m; + rtw_iterate_stas_atomic(rtwdev, rtw_coex_sta_stat_iter, + &sta_iter_data); +} + +#define case_WLINK(src) \ + case COEX_WLINK_##src: return #src + +static const char *rtw_coex_get_wl_coex_mode(u8 coex_wl_link_mode) +{ + switch (coex_wl_link_mode) { + case_WLINK(2G1PORT); + case_WLINK(5G); + case_WLINK(2GFREE); + default: + return "Unknown"; + } +} + +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_coex_vif_stat_iter_data vif_iter_data; + u8 reason = coex_dm->reason; + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; + u32 lte_coex = 0, bt_coex = 0; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); + score_board_WB = coex_stat->score_board; + wl_reg_6c0 = rtw_read32(rtwdev, REG_BT_COEX_TABLE0); + wl_reg_6c4 = rtw_read32(rtwdev, REG_BT_COEX_TABLE1); + wl_reg_6c8 = rtw_read32(rtwdev, REG_BT_COEX_BRK_TABLE); + wl_reg_6cc = rtw_read32(rtwdev, REG_BT_COEX_TABLE_H); + wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL); + + sys_lte = rtw_read8(rtwdev, 0x73); + if (rtwdev->chip->ltecoex_addr) { + lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); + bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); + } + + if (!coex_stat->wl_under_ips && + (!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) && + !coex_stat->bt_disabled && !coex_stat->bt_mailbox_reply) { + rtw_coex_get_bt_supported_version(rtwdev, + &coex_stat->bt_supported_version); + rtw_coex_get_bt_patch_version(rtwdev, &coex_stat->patch_ver); + rtw_coex_get_bt_supported_feature(rtwdev, + &coex_stat->bt_supported_feature); + rtw_coex_get_bt_reg(rtwdev, 3, 0xae, &coex_stat->bt_reg_vendor_ae); + rtw_coex_get_bt_reg(rtwdev, 3, 0xac, &coex_stat->bt_reg_vendor_ac); + + if (coex_stat->patch_ver != 0) + coex_stat->bt_mailbox_reply = true; + } + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Coexist info %x\n", chip->id); + seq_printf(m, "**********************************************\n"); + + if (coex->manual_control) { + seq_puts(m, "============[Under Manual Control]============\n"); + seq_puts(m, "==========================================\n"); + + } else if (coex->stop_dm) { + seq_puts(m, "============[Coex is STOPPED]============\n"); + seq_puts(m, "==========================================\n"); + + } else if (coex->freeze) { + seq_puts(m, "============[coex_freeze]============\n"); + seq_puts(m, "==========================================\n"); + } + + seq_printf(m, "%-40s = %s/ %d\n", + "Mech/ RFE", + efuse->share_ant ? "Shared" : "Non-Shared", + efuse->rfe_option); + seq_printf(m, "%-40s = %08x/ 0x%02x/ 0x%08x %s\n", + "Coex Ver/ BT Dez/ BT Rpt", + chip->coex_para_ver, chip->bt_desired_ver, + coex_stat->bt_supported_version, + coex_stat->bt_disabled ? "(BT disabled)" : + coex_stat->bt_supported_version >= chip->bt_desired_ver ? + "(Match)" : "(Mismatch)"); + seq_printf(m, "%-40s = %s/ %u/ %d\n", + "Role/ RoleSwCnt/ IgnWL/ Feature", + coex_stat->bt_slave ? "Slave" : "Master", + coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH], + coex_dm->ignore_wl_act); + seq_printf(m, "%-40s = %u.%u/ 0x%x/ 0x%x/ %c\n", + "WL FW/ BT FW/ BT FW Desired/ KT", + fw->version, fw->sub_version, + coex_stat->patch_ver, + chip->wl_fw_desired_ver, coex_stat->kt_ver + 65); + seq_printf(m, "%-40s = %u/ %u/ %u/ ch-(%u)\n", + "AFH Map", + coex_dm->wl_ch_info[0], coex_dm->wl_ch_info[1], + coex_dm->wl_ch_info[2], hal->current_channel); + + rtw_debugfs_get_simple_phy_info(m); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %ddBm/ %u/ %u\n", + "BT status/ rssi/ retry/ pop", + coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ? "non-conn" : + coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE ? "conn-idle" : "busy", + coex_stat->bt_rssi - 100, + coex_stat->cnt_bt[COEX_CNT_BT_RETRY], + coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]); + seq_printf(m, "%-40s = %s%s%s%s%s (multi-link %d)\n", + "Profiles", + coex_stat->bt_a2dp_exist ? (coex_stat->bt_a2dp_sink ? + "A2DP sink," : "A2DP,") : "", + coex_stat->bt_hfp_exist ? "HFP," : "", + coex_stat->bt_hid_exist ? + (coex_stat->bt_ble_exist ? "HID(RCU)," : + coex_stat->bt_hid_slot >= 2 ? "HID(4/18)" : + coex_stat->bt_ble_hid_exist ? "HID(BLE)" : + "HID(2/18),") : "", + coex_stat->bt_pan_exist ? coex_stat->bt_opp_exist ? + "OPP," : "PAN," : "", + coex_stat->bt_ble_voice ? "Voice," : "", + coex_stat->bt_multi_link); + seq_printf(m, "%-40s = %u/ %u/ %u/ 0x%08x\n", + "Reinit/ Relink/ IgnWl/ Feature", + coex_stat->cnt_bt[COEX_CNT_BT_REINIT], + coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK], + coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT], + coex_stat->bt_supported_feature); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "Page/ Inq/ iqk/ iqk fail", + coex_stat->cnt_bt[COEX_CNT_BT_PAGE], + coex_stat->cnt_bt[COEX_CNT_BT_INQ], + coex_stat->cnt_bt[COEX_CNT_BT_IQK], + coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]); + seq_printf(m, "%-40s = 0x%04x/ 0x%04x/ 0x%04x/ 0x%04x\n", + "0xae/ 0xac/ score board (W->B)/ (B->W)", + coex_stat->bt_reg_vendor_ae, + coex_stat->bt_reg_vendor_ac, + score_board_WB, score_board_BW); + seq_printf(m, "%-40s = %u/%u, %u/%u\n", + "Hi-Pri TX/RX, Lo-Pri TX/RX", + coex_stat->hi_pri_tx, coex_stat->hi_pri_rx, + coex_stat->lo_pri_tx, coex_stat->lo_pri_rx); + for (i = 0; i < COEX_BTINFO_SRC_BT_IQK; i++) + seq_printf(m, "%-40s = %7ph\n", + rtw_coex_get_bt_info_src_string(i), + coex_stat->bt_info_c2h[i]); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tWiFi Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %d\n", + "Scanning", test_bit(RTW_FLAG_SCANNING, rtwdev->flags)); + seq_printf(m, "%-40s = %u/ TX %d Mbps/ RX %d Mbps\n", + "G_busy/ TX/ RX", + coex_stat->wl_gl_busy, + rtwdev->stats.tx_throughput, rtwdev->stats.rx_throughput); + seq_printf(m, "%-40s = %u/ %u/ %u\n", + "IPS/ Low Power/ PS mode", + !test_bit(RTW_FLAG_POWERON, rtwdev->flags), + test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags), + rtwdev->lps_conf.mode); + + vif_iter_data.rtwdev = rtwdev; + vif_iter_data.file = m; + rtw_iterate_vifs_atomic(rtwdev, rtw_coex_vif_stat_iter, &vif_iter_data); + + if (coex->manual_control) { + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tMechanism (Under Manual)\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %5ph (%d)\n", + "TDMA Now", + coex_dm->fw_tdma_para, + rtw_coex_get_tdma_index(rtwdev, + &coex_dm->fw_tdma_para[0])); + } else { + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tMechanism\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %5ph (case-%d)\n", + "TDMA", + coex_dm->ps_tdma_para, coex_dm->cur_ps_tdma); + } + seq_printf(m, "%-40s = %s/ %s/ %d\n", + "Coex Mode/Free Run/Timer base", + rtw_coex_get_wl_coex_mode(coex_stat->wl_coex_mode), + coex->freerun ? "Yes" : "No", + coex_stat->tdma_timer_base); + seq_printf(m, "%-40s = %d(%d)/ 0x%08x/ 0x%08x/ 0x%08x\n", + "Table/ 0x6c0/ 0x6c4/ 0x6c8", + coex_dm->cur_table, + rtw_coex_get_table_index(rtwdev, wl_reg_6c0, wl_reg_6c4), + wl_reg_6c0, wl_reg_6c4, wl_reg_6c8); + seq_printf(m, "%-40s = 0x%08x/ 0x%08x/ %d/ reason (%s)\n", + "0x778/ 0x6cc/ Run Count/ Reason", + wl_reg_778, wl_reg_6cc, + coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN], + rtw_coex_get_reason_string(reason)); + seq_printf(m, "%-40s = %3ph\n", + "AFH Map to BT", + coex_dm->wl_ch_info); + seq_printf(m, "%-40s = %s/ %d\n", + "AntDiv/ BtCtrlLPS/ g_busy", + coex_stat->wl_force_lps_ctrl ? "On" : "Off", + coex_stat->wl_gl_busy); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u/ %u\n", + "Null All/ Retry/ Ack/ BT Empty/ BT Late", + coex_stat->wl_fw_dbg_info[1], coex_stat->wl_fw_dbg_info[2], + coex_stat->wl_fw_dbg_info[3], coex_stat->wl_fw_dbg_info[4], + coex_stat->wl_fw_dbg_info[5]); + seq_printf(m, "%-40s = %u/ %u/ %s/ %u\n", + "Cnt TDMA Toggle/ Lk 5ms/ Lk 5ms on/ FW", + coex_stat->wl_fw_dbg_info[6], + coex_stat->wl_fw_dbg_info[7], + coex_stat->wl_slot_extend ? "Yes" : "No", + coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]); + seq_printf(m, "%-40s = %d/ %d/ %s/ %d\n", + "WL_TxPw/ BT_TxPw/ WL_Rx/ BT_LNA_Lvl", + coex_dm->cur_wl_pwr_lvl, + coex_dm->cur_bt_pwr_lvl, + coex_dm->cur_wl_rx_low_gain_en ? "On" : "Off", + coex_dm->cur_bt_lna_lvl); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tHW setting\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %s\n", + "LTE Coex/ Path Owner", + lte_coex & BIT(7) ? "ON" : "OFF", + sys_lte & BIT(2) ? "WL" : "BT"); + seq_printf(m, "%-40s = RF:%s_BB:%s/ RF:%s_BB:%s/ %s\n", + "GNT_WL_CTRL/ GNT_BT_CTRL/ Dbg", + lte_coex & BIT(12) ? "SW" : "HW", + lte_coex & BIT(8) ? "SW" : "HW", + lte_coex & BIT(14) ? "SW" : "HW", + lte_coex & BIT(10) ? "SW" : "HW", + sys_lte & BIT(3) ? "On" : "Off"); + seq_printf(m, "%-40s = %lu/ %lu\n", + "GNT_WL/ GNT_BT", + (bt_coex & BIT(2)) >> 2, (bt_coex & BIT(3)) >> 3); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC OK CCK/ OFDM/ HT/ VHT", + dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt, + dm_info->ht_ok_cnt, dm_info->vht_ok_cnt); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC ERR CCK/ OFDM/ HT/ VHT", + dm_info->cck_err_cnt, dm_info->ofdm_err_cnt, + dm_info->ht_err_cnt, dm_info->vht_err_cnt); + seq_printf(m, "%-40s = %s/ %s/ %s/ %u\n", + "HiPr/ Locking/ Locked/ Noisy", + coex_stat->wl_hi_pri_task1 ? "Y" : "N", + coex_stat->wl_cck_lock ? "Y" : "N", + coex_stat->wl_cck_lock_ever ? "Y" : "N", + coex_stat->wl_noisy_level); + + rtw_coex_set_coexinfo_hw(rtwdev, m); + seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", + "EVM A/ EVM B/ SNR A/ SNR B", + -dm_info->rx_evm_dbm[RF_PATH_A], + -dm_info->rx_evm_dbm[RF_PATH_B], + -dm_info->rx_snr[RF_PATH_A], + -dm_info->rx_snr[RF_PATH_B]); + seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", + "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", + dm_info->cck_cca_cnt, dm_info->cck_fa_cnt, + dm_info->ofdm_cca_cnt, dm_info->ofdm_fa_cnt); + seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", "CRC OK CCK/11g/11n/11ac", + dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt, + dm_info->ht_ok_cnt, dm_info->vht_ok_cnt); + seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", "CRC Err CCK/11g/11n/11ac", + dm_info->cck_err_cnt, dm_info->ofdm_err_cnt, + dm_info->ht_err_cnt, dm_info->vht_err_cnt); + +} +#endif /* CONFIG_RTW88_DEBUGFS */ diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h new file mode 100644 index 000000000..c398be839 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/coex.h @@ -0,0 +1,433 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_COEX_H__ +#define __RTW_COEX_H__ + +#define COEX_CCK_2 0x1 +#define COEX_RESP_ACK_BY_WL_FW 0x1 +#define COEX_REQUEST_TIMEOUT msecs_to_jiffies(10) + +#define COEX_MIN_DELAY 10 /* delay unit in ms */ +#define COEX_RFK_TIMEOUT 600 /* RFK timeout in ms */ +#define COEX_BT_GAMEHID_CNT 800 + +#define COEX_RF_OFF 0x0 +#define COEX_RF_ON 0x1 + +#define COEX_H2C69_WL_LEAKAP 0xc +#define PARA1_H2C69_DIS_5MS 0x1 +#define PARA1_H2C69_EN_5MS 0x0 + +#define COEX_H2C69_TDMA_SLOT 0xb +#define PARA1_H2C69_TDMA_4SLOT 0xc1 +#define PARA1_H2C69_TDMA_2SLOT 0x1 +#define PARA1_H2C69_TBTT_TIMES GENMASK(5, 0) +#define PARA1_H2C69_TBTT_DIV100 BIT(7) + +#define COEX_H2C69_TOGGLE_TABLE_A 0xd +#define COEX_H2C69_TOGGLE_TABLE_B 0x7 + +#define TDMA_4SLOT BIT(8) + +#define TDMA_TIMER_TYPE_2SLOT 0 +#define TDMA_TIMER_TYPE_4SLOT 3 + +#define COEX_RSSI_STEP 4 + +#define COEX_RSSI_HIGH(rssi) \ + ({ typeof(rssi) __rssi__ = rssi; \ + (__rssi__ == COEX_RSSI_STATE_HIGH || \ + __rssi__ == COEX_RSSI_STATE_STAY_HIGH ? true : false); }) + +#define COEX_RSSI_MEDIUM(rssi) \ + ({ typeof(rssi) __rssi__ = rssi; \ + (__rssi__ == COEX_RSSI_STATE_MEDIUM || \ + __rssi__ == COEX_RSSI_STATE_STAY_MEDIUM ? true : false); }) + +#define COEX_RSSI_LOW(rssi) \ + ({ typeof(rssi) __rssi__ = rssi; \ + (__rssi__ == COEX_RSSI_STATE_LOW || \ + __rssi__ == COEX_RSSI_STATE_STAY_LOW ? true : false); }) + +#define GET_COEX_RESP_BT_SUPP_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 32)) +#define GET_COEX_RESP_BT_SUPP_FEAT(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) +#define GET_COEX_RESP_BT_PATCH_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(55, 24)) +#define GET_COEX_RESP_BT_REG_VAL(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) +#define GET_COEX_RESP_BT_SCAN_TYPE(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK(31, 24)) + +enum coex_mp_info_op { + BT_MP_INFO_OP_PATCH_VER = 0x00, + BT_MP_INFO_OP_READ_REG = 0x11, + BT_MP_INFO_OP_SUPP_FEAT = 0x2a, + BT_MP_INFO_OP_SUPP_VER = 0x2b, + BT_MP_INFO_OP_SCAN_TYPE = 0x2d, + BT_MP_INFO_OP_LNA_CONSTRAINT = 0x32, +}; + +enum coex_set_ant_phase { + COEX_SET_ANT_INIT, + COEX_SET_ANT_WONLY, + COEX_SET_ANT_WOFF, + COEX_SET_ANT_2G, + COEX_SET_ANT_5G, + COEX_SET_ANT_POWERON, + COEX_SET_ANT_2G_WLBT, + COEX_SET_ANT_2G_FREERUN, + + COEX_SET_ANT_MAX +}; + +enum coex_runreason { + COEX_RSN_2GSCANSTART = 0, + COEX_RSN_5GSCANSTART = 1, + COEX_RSN_SCANFINISH = 2, + COEX_RSN_2GSWITCHBAND = 3, + COEX_RSN_5GSWITCHBAND = 4, + COEX_RSN_2GCONSTART = 5, + COEX_RSN_5GCONSTART = 6, + COEX_RSN_2GCONFINISH = 7, + COEX_RSN_5GCONFINISH = 8, + COEX_RSN_2GMEDIA = 9, + COEX_RSN_5GMEDIA = 10, + COEX_RSN_MEDIADISCON = 11, + COEX_RSN_BTINFO = 12, + COEX_RSN_LPS = 13, + COEX_RSN_WLSTATUS = 14, + COEX_RSN_BTSTATUS = 15, + + COEX_RSN_MAX +}; + +enum coex_lte_coex_table_type { + COEX_CTT_WL_VS_LTE, + COEX_CTT_BT_VS_LTE, +}; + +enum coex_gnt_setup_state { + COEX_GNT_SET_HW_PTA = 0x0, + COEX_GNT_SET_SW_LOW = 0x1, + COEX_GNT_SET_SW_HIGH = 0x3, +}; + +enum coex_ext_ant_switch_pos_type { + COEX_SWITCH_TO_BT, + COEX_SWITCH_TO_WLG, + COEX_SWITCH_TO_WLA, + COEX_SWITCH_TO_NOCARE, + COEX_SWITCH_TO_WLG_BT, + + COEX_SWITCH_TO_MAX +}; + +enum coex_ext_ant_switch_ctrl_type { + COEX_SWITCH_CTRL_BY_BBSW, + COEX_SWITCH_CTRL_BY_PTA, + COEX_SWITCH_CTRL_BY_ANTDIV, + COEX_SWITCH_CTRL_BY_MAC, + COEX_SWITCH_CTRL_BY_BT, + COEX_SWITCH_CTRL_BY_FW, + + COEX_SWITCH_CTRL_MAX +}; + +enum coex_algorithm { + COEX_ALGO_NOPROFILE = 0, + COEX_ALGO_HFP = 1, + COEX_ALGO_HID = 2, + COEX_ALGO_A2DP = 3, + COEX_ALGO_PAN = 4, + COEX_ALGO_A2DP_HID = 5, + COEX_ALGO_A2DP_PAN = 6, + COEX_ALGO_PAN_HID = 7, + COEX_ALGO_A2DP_PAN_HID = 8, + + COEX_ALGO_MAX +}; + +enum coex_bt_profile { + BPM_NOPROFILE = 0, + BPM_HFP = BIT(0), + BPM_HID = BIT(1), + BPM_A2DP = BIT(2), + BPM_PAN = BIT(3), + BPM_HID_HFP = BPM_HID | BPM_HFP, + BPM_A2DP_HFP = BPM_A2DP | BPM_HFP, + BPM_A2DP_HID = BPM_A2DP | BPM_HID, + BPM_A2DP_HID_HFP = BPM_A2DP | BPM_HID | BPM_HFP, + BPM_PAN_HFP = BPM_PAN | BPM_HFP, + BPM_PAN_HID = BPM_PAN | BPM_HID, + BPM_PAN_HID_HFP = BPM_PAN | BPM_HID | BPM_HFP, + BPM_PAN_A2DP = BPM_PAN | BPM_A2DP, + BPM_PAN_A2DP_HFP = BPM_PAN | BPM_A2DP | BPM_HFP, + BPM_PAN_A2DP_HID = BPM_PAN | BPM_A2DP | BPM_HID, + BPM_PAN_A2DP_HID_HFP = BPM_PAN | BPM_A2DP | BPM_HID | BPM_HFP, +}; + +enum coex_wl_link_mode { + COEX_WLINK_2G1PORT = 0x0, + COEX_WLINK_5G = 0x3, + COEX_WLINK_2GFREE = 0x7, + COEX_WLINK_MAX +}; + +enum coex_wl2bt_scoreboard { + COEX_SCBD_ACTIVE = BIT(0), + COEX_SCBD_ONOFF = BIT(1), + COEX_SCBD_SCAN = BIT(2), + COEX_SCBD_UNDERTEST = BIT(3), + COEX_SCBD_RXGAIN = BIT(4), + COEX_SCBD_BT_RFK = BIT(5), + COEX_SCBD_WLBUSY = BIT(6), + COEX_SCBD_EXTFEM = BIT(8), + COEX_SCBD_TDMA = BIT(9), + COEX_SCBD_FIX2M = BIT(10), + COEX_SCBD_ALL = GENMASK(15, 0), +}; + +enum coex_power_save_type { + COEX_PS_WIFI_NATIVE = 0, + COEX_PS_LPS_ON = 1, + COEX_PS_LPS_OFF = 2, +}; + +enum coex_rssi_state { + COEX_RSSI_STATE_HIGH, + COEX_RSSI_STATE_MEDIUM, + COEX_RSSI_STATE_LOW, + COEX_RSSI_STATE_STAY_HIGH, + COEX_RSSI_STATE_STAY_MEDIUM, + COEX_RSSI_STATE_STAY_LOW, +}; + +enum coex_notify_type_ips { + COEX_IPS_LEAVE = 0x0, + COEX_IPS_ENTER = 0x1, +}; + +enum coex_notify_type_lps { + COEX_LPS_DISABLE = 0x0, + COEX_LPS_ENABLE = 0x1, +}; + +enum coex_notify_type_scan { + COEX_SCAN_FINISH, + COEX_SCAN_START, + COEX_SCAN_START_2G, + COEX_SCAN_START_5G, +}; + +enum coex_notify_type_switchband { + COEX_NOT_SWITCH, + COEX_SWITCH_TO_24G, + COEX_SWITCH_TO_5G, + COEX_SWITCH_TO_24G_NOFORSCAN, +}; + +enum coex_notify_type_associate { + COEX_ASSOCIATE_FINISH, + COEX_ASSOCIATE_START, + COEX_ASSOCIATE_5G_FINISH, + COEX_ASSOCIATE_5G_START, +}; + +enum coex_notify_type_media_status { + COEX_MEDIA_DISCONNECT, + COEX_MEDIA_CONNECT, + COEX_MEDIA_CONNECT_5G, +}; + +enum coex_bt_status { + COEX_BTSTATUS_NCON_IDLE = 0, + COEX_BTSTATUS_CON_IDLE = 1, + COEX_BTSTATUS_INQ_PAGE = 2, + COEX_BTSTATUS_ACL_BUSY = 3, + COEX_BTSTATUS_SCO_BUSY = 4, + COEX_BTSTATUS_ACL_SCO_BUSY = 5, + + COEX_BTSTATUS_MAX +}; + +enum coex_wl_tput_dir { + COEX_WL_TPUT_TX = 0x0, + COEX_WL_TPUT_RX = 0x1, + COEX_WL_TPUT_MAX +}; + +enum coex_wl_priority_mask { + COEX_WLPRI_RX_RSP = 2, + COEX_WLPRI_TX_RSP = 3, + COEX_WLPRI_TX_BEACON = 4, + COEX_WLPRI_TX_OFDM = 11, + COEX_WLPRI_TX_CCK = 12, + COEX_WLPRI_TX_BEACONQ = 27, + COEX_WLPRI_RX_CCK = 28, + COEX_WLPRI_RX_OFDM = 29, + COEX_WLPRI_MAX +}; + +enum coex_commom_chip_setup { + COEX_CSETUP_INIT_HW = 0x0, + COEX_CSETUP_ANT_SWITCH = 0x1, + COEX_CSETUP_GNT_FIX = 0x2, + COEX_CSETUP_GNT_DEBUG = 0x3, + COEX_CSETUP_RFE_TYPE = 0x4, + COEX_CSETUP_COEXINFO_HW = 0x5, + COEX_CSETUP_WL_TX_POWER = 0x6, + COEX_CSETUP_WL_RX_GAIN = 0x7, + COEX_CSETUP_WLAN_ACT_IPS = 0x8, + COEX_CSETUP_MAX +}; + +enum coex_indirect_reg_type { + COEX_INDIRECT_1700 = 0x0, + COEX_INDIRECT_7C0 = 0x1, + COEX_INDIRECT_MAX +}; + +enum coex_pstdma_type { + COEX_PSTDMA_FORCE_LPSOFF = 0x0, + COEX_PSTDMA_FORCE_LPSON = 0x1, + COEX_PSTDMA_MAX +}; + +enum coex_btrssi_type { + COEX_BTRSSI_RATIO = 0x0, + COEX_BTRSSI_DBM = 0x1, + COEX_BTRSSI_MAX +}; + +struct coex_table_para { + u32 bt; + u32 wl; +}; + +struct coex_tdma_para { + u8 para[5]; +}; + +struct coex_5g_afh_map { + u32 wl_5g_ch; + u8 bt_skip_ch; + u8 bt_skip_span; +}; + +struct coex_rf_para { + u8 wl_pwr_dec_lvl; + u8 bt_pwr_dec_lvl; + bool wl_low_gain_en; + u8 bt_lna_lvl; +}; + +static inline void rtw_coex_set_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_init(rtwdev); +} + +static inline +void rtw_coex_set_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, u8 pos_type) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (!chip->ops->coex_set_ant_switch) + return; + + chip->ops->coex_set_ant_switch(rtwdev, ctrl_type, pos_type); +} + +static inline void rtw_coex_set_gnt_fix(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_gnt_fix(rtwdev); +} + +static inline void rtw_coex_set_gnt_debug(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_gnt_debug(rtwdev); +} + +static inline void rtw_coex_set_rfe_type(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_rfe_type(rtwdev); +} + +static inline void rtw_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_wl_tx_power(rtwdev, wl_pwr); +} + +static inline +void rtw_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->coex_set_wl_rx_gain(rtwdev, low_gain); +} + +void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb); +u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr); +void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr, + u32 mask, u32 val); +void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set); +void rtw_coex_query_bt_info(struct rtw_dev *rtwdev); + +void rtw_coex_bt_relink_work(struct work_struct *work); +void rtw_coex_bt_reenable_work(struct work_struct *work); +void rtw_coex_defreeze_work(struct work_struct *work); +void rtw_coex_wl_remain_work(struct work_struct *work); +void rtw_coex_bt_remain_work(struct work_struct *work); +void rtw_coex_wl_connecting_work(struct work_struct *work); +void rtw_coex_bt_multi_link_remain_work(struct work_struct *work); +void rtw_coex_wl_ccklock_work(struct work_struct *work); + +void rtw_coex_power_on_setting(struct rtw_dev *rtwdev); +void rtw_coex_power_off_setting(struct rtw_dev *rtwdev); +void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only); +void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); +void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); +void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); +void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type); +void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type); +void rtw_coex_wl_status_check(struct rtw_dev *rtwdev); +void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev); +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m); + +static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + + return coex_stat->bt_disabled; +} + +static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev) +{ + /* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself + * when bluetooth headphones are disconnected, so we have to + * ask for it regularly. + */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex) + rtw_coex_query_bt_info(rtwdev); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c new file mode 100644 index 000000000..b67d69b01 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -0,0 +1,1375 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "coex.h" +#include "sec.h" +#include "fw.h" +#include "debug.h" +#include "phy.h" +#include "reg.h" +#include "ps.h" +#include "regd.h" + +#ifdef CONFIG_RTW88_DEBUGFS + +struct rtw_debugfs_priv { + struct rtw_dev *rtwdev; + int (*cb_read)(struct seq_file *m, void *v); + ssize_t (*cb_write)(struct file *filp, const char __user *buffer, + size_t count, loff_t *loff); + union { + u32 cb_data; + u8 *buf; + struct { + u32 page_offset; + u32 page_num; + } rsvd_page; + struct { + u8 rf_path; + u32 rf_addr; + u32 rf_mask; + }; + struct { + u32 addr; + u32 len; + } read_reg; + struct { + u8 bit; + } dm_cap; + }; +}; + +struct rtw_debugfs { + struct rtw_debugfs_priv mac_0; + struct rtw_debugfs_priv mac_1; + struct rtw_debugfs_priv mac_2; + struct rtw_debugfs_priv mac_3; + struct rtw_debugfs_priv mac_4; + struct rtw_debugfs_priv mac_5; + struct rtw_debugfs_priv mac_6; + struct rtw_debugfs_priv mac_7; + struct rtw_debugfs_priv mac_10; + struct rtw_debugfs_priv mac_11; + struct rtw_debugfs_priv mac_12; + struct rtw_debugfs_priv mac_13; + struct rtw_debugfs_priv mac_14; + struct rtw_debugfs_priv mac_15; + struct rtw_debugfs_priv mac_16; + struct rtw_debugfs_priv mac_17; + struct rtw_debugfs_priv bb_8; + struct rtw_debugfs_priv bb_9; + struct rtw_debugfs_priv bb_a; + struct rtw_debugfs_priv bb_b; + struct rtw_debugfs_priv bb_c; + struct rtw_debugfs_priv bb_d; + struct rtw_debugfs_priv bb_e; + struct rtw_debugfs_priv bb_f; + struct rtw_debugfs_priv bb_18; + struct rtw_debugfs_priv bb_19; + struct rtw_debugfs_priv bb_1a; + struct rtw_debugfs_priv bb_1b; + struct rtw_debugfs_priv bb_1c; + struct rtw_debugfs_priv bb_1d; + struct rtw_debugfs_priv bb_1e; + struct rtw_debugfs_priv bb_1f; + struct rtw_debugfs_priv bb_2c; + struct rtw_debugfs_priv bb_2d; + struct rtw_debugfs_priv bb_40; + struct rtw_debugfs_priv bb_41; + struct rtw_debugfs_priv rf_dump; + struct rtw_debugfs_priv tx_pwr_tbl; + struct rtw_debugfs_priv write_reg; + struct rtw_debugfs_priv h2c; + struct rtw_debugfs_priv rf_write; + struct rtw_debugfs_priv rf_read; + struct rtw_debugfs_priv read_reg; + struct rtw_debugfs_priv fix_rate; + struct rtw_debugfs_priv dump_cam; + struct rtw_debugfs_priv rsvd_page; + struct rtw_debugfs_priv phy_info; + struct rtw_debugfs_priv coex_enable; + struct rtw_debugfs_priv coex_info; + struct rtw_debugfs_priv edcca_enable; + struct rtw_debugfs_priv fw_crash; + struct rtw_debugfs_priv force_lowest_basic_rate; + struct rtw_debugfs_priv dm_cap; +}; + +static const char * const rtw_dm_cap_strs[] = { + [RTW_DM_CAP_NA] = "NA", + [RTW_DM_CAP_TXGAPK] = "TXGAPK", +}; + +static int rtw_debugfs_single_show(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + + return debugfs_priv->cb_read(m, v); +} + +static ssize_t rtw_debugfs_common_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtw_debugfs_priv *debugfs_priv = filp->private_data; + + return debugfs_priv->cb_write(filp, buffer, count, loff); +} + +static ssize_t rtw_debugfs_single_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + + return debugfs_priv->cb_write(filp, buffer, count, loff); +} + +static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp) +{ + return single_open(filp, rtw_debugfs_single_show, inode->i_private); +} + +static int rtw_debugfs_close(struct inode *inode, struct file *filp) +{ + return 0; +} + +static const struct file_operations file_ops_single_r = { + .owner = THIS_MODULE, + .open = rtw_debugfs_single_open_rw, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations file_ops_single_rw = { + .owner = THIS_MODULE, + .open = rtw_debugfs_single_open_rw, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek, + .write = rtw_debugfs_single_write, +}; + +static const struct file_operations file_ops_common_write = { + .owner = THIS_MODULE, + .write = rtw_debugfs_common_write, + .open = simple_open, + .release = rtw_debugfs_close, +}; + +static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 val, len, addr; + + len = debugfs_priv->read_reg.len; + addr = debugfs_priv->read_reg.addr; + switch (len) { + case 1: + val = rtw_read8(rtwdev, addr); + seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val); + break; + case 2: + val = rtw_read16(rtwdev, addr); + seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val); + break; + case 4: + val = rtw_read32(rtwdev, addr); + seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val); + break; + } + return 0; +} + +static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 val, addr, mask; + u8 path; + + path = debugfs_priv->rf_path; + addr = debugfs_priv->rf_addr; + mask = debugfs_priv->rf_mask; + + mutex_lock(&rtwdev->mutex); + val = rtw_read_rf(rtwdev, path, addr, mask); + mutex_unlock(&rtwdev->mutex); + + seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", + path, addr, mask, val); + + return 0; +} + +static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 fix_rate = dm_info->fix_rate; + + if (fix_rate >= DESC_RATE_MAX) { + seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate); + return 0; + } + + seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate); + return 0; +} + +static int rtw_debugfs_copy_from_user(char tmp[], int size, + const char __user *buffer, size_t count, + int num) +{ + int tmp_len; + + memset(tmp, 0, size); + + if (count < num) + return -EFAULT; + + tmp_len = (count > size - 1 ? size - 1 : count); + + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; + + tmp[tmp_len] = '\0'; + + return 0; +} + +static ssize_t rtw_debugfs_set_read_reg(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u32 addr, len; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); + if (ret) + return ret; + + num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) + return -EINVAL; + + if (len != 1 && len != 2 && len != 4) { + rtw_warn(rtwdev, "read reg setting wrong len\n"); + return -EINVAL; + } + debugfs_priv->read_reg.addr = addr; + debugfs_priv->read_reg.len = len; + + return count; +} + +static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 val, command; + u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; + u32 read_cmd = RTW_SEC_CMD_POLLING; + int i; + + seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); + seq_puts(m, "0x0 0x1 0x2 0x3 "); + seq_puts(m, "0x4 0x5\n"); + mutex_lock(&rtwdev->mutex); + for (i = 0; i <= 5; i++) { + command = read_cmd | (hw_key_idx + i); + rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); + val = rtw_read32(rtwdev, RTW_SEC_READ_REG); + seq_printf(m, "%8.8x", val); + if (i < 2) + seq_puts(m, " "); + } + seq_puts(m, "\n"); + mutex_unlock(&rtwdev->mutex); + return 0; +} + +static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u16 page_size = rtwdev->chip->page_size; + u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; + u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; + u8 *buf; + int i; + int ret; + + buf = vzalloc(buf_size); + if (!buf) + return -ENOMEM; + + ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, + buf_size, (u32 *)buf); + if (ret) { + rtw_err(rtwdev, "failed to dump rsvd page\n"); + vfree(buf); + return ret; + } + + for (i = 0 ; i < buf_size ; i += 8) { + if (i % page_size == 0) + seq_printf(m, "PAGE %d\n", (i + offset) / page_size); + seq_printf(m, "%8ph\n", buf + i); + } + vfree(buf); + + return 0; +} + +static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u32 offset, page_num; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); + if (ret) + return ret; + + num = sscanf(tmp, "%d %d", &offset, &page_num); + + if (num != 2) { + rtw_warn(rtwdev, "invalid arguments\n"); + return -EINVAL; + } + + debugfs_priv->rsvd_page.page_offset = offset; + debugfs_priv->rsvd_page.page_num = page_num; + + return count; +} + +static ssize_t rtw_debugfs_set_single_input(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + u32 input; + int ret; + + ret = kstrtou32_from_user(buffer, count, 0, &input); + if (ret) + return ret; + + debugfs_priv->cb_data = input; + + return count; +} + +static ssize_t rtw_debugfs_set_write_reg(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtw_debugfs_priv *debugfs_priv = filp->private_data; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u32 addr, val, len; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); + if (ret) + return ret; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) + return -EINVAL; + + switch (len) { + case 1: + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "reg write8 0x%03x: 0x%08x\n", addr, val); + rtw_write8(rtwdev, addr, (u8)val); + break; + case 2: + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "reg write16 0x%03x: 0x%08x\n", addr, val); + rtw_write16(rtwdev, addr, (u16)val); + break; + case 4: + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "reg write32 0x%03x: 0x%08x\n", addr, val); + rtw_write32(rtwdev, addr, (u32)val); + break; + default: + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "error write length = %d\n", len); + break; + } + + return count; +} + +static ssize_t rtw_debugfs_set_h2c(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtw_debugfs_priv *debugfs_priv = filp->private_data; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u8 param[8]; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); + if (ret) + return ret; + + num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], + ¶m[4], ¶m[5], ¶m[6], ¶m[7]); + if (num != 8) { + rtw_warn(rtwdev, "invalid H2C command format for debug\n"); + return -EINVAL; + } + + mutex_lock(&rtwdev->mutex); + rtw_fw_h2c_cmd_dbg(rtwdev, param); + mutex_unlock(&rtwdev->mutex); + + return count; +} + +static ssize_t rtw_debugfs_set_rf_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtw_debugfs_priv *debugfs_priv = filp->private_data; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u32 path, addr, mask, val; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); + if (ret) + return ret; + + num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); + + if (num != 4) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); + return -EINVAL; + } + + mutex_lock(&rtwdev->mutex); + rtw_write_rf(rtwdev, path, addr, mask, val); + mutex_unlock(&rtwdev->mutex); + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", + path, addr, mask, val); + + return count; +} + +static ssize_t rtw_debugfs_set_rf_read(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + u32 path, addr, mask; + int num; + int ret; + + ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); + if (ret) + return ret; + + num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); + + if (num != 3) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); + return -EINVAL; + } + + debugfs_priv->rf_path = path; + debugfs_priv->rf_addr = addr; + debugfs_priv->rf_mask = mask; + + return count; +} + +static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 fix_rate; + int ret; + + ret = kstrtou8_from_user(buffer, count, 0, &fix_rate); + if (ret) + return ret; + + dm_info->fix_rate = fix_rate; + + return count; +} + +static int rtw_debug_get_mac_page(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 page = debugfs_priv->cb_data; + int i, n; + int max = 0xff; + + rtw_read32(rtwdev, debugfs_priv->cb_data); + for (n = 0; n <= max; ) { + seq_printf(m, "\n%8.8x ", n + page); + for (i = 0; i < 4 && n <= max; i++, n += 4) + seq_printf(m, "%8.8x ", + rtw_read32(rtwdev, (page | n))); + } + seq_puts(m, "\n"); + return 0; +} + +static int rtw_debug_get_bb_page(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 page = debugfs_priv->cb_data; + int i, n; + int max = 0xff; + + rtw_read32(rtwdev, debugfs_priv->cb_data); + for (n = 0; n <= max; ) { + seq_printf(m, "\n%8.8x ", n + page); + for (i = 0; i < 4 && n <= max; i++, n += 4) + seq_printf(m, "%8.8x ", + rtw_read32(rtwdev, (page | n))); + } + seq_puts(m, "\n"); + return 0; +} + +static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + u32 addr, offset, data; + u8 path; + + mutex_lock(&rtwdev->mutex); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + seq_printf(m, "RF path:%d\n", path); + for (addr = 0; addr < 0x100; addr += 4) { + seq_printf(m, "%8.8x ", addr); + for (offset = 0; offset < 4; offset++) { + data = rtw_read_rf(rtwdev, path, addr + offset, + 0xffffffff); + seq_printf(m, "%8.8x ", data); + } + seq_puts(m, "\n"); + } + seq_puts(m, "\n"); + } + + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) +{ + static const char * const + cck_rate[] = {"1M", "2M", "5.5M", "11M"}; + u8 idx = rate - DESC_RATE1M; + + seq_printf(m, " CCK_%-5s", cck_rate[idx]); +} + +static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) +{ + static const char * const + ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; + u8 idx = rate - DESC_RATE6M; + + seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); +} + +static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) +{ + u8 mcs_n = rate - DESC_RATEMCS0; + + seq_printf(m, " MCS%-6u", mcs_n); +} + +static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) +{ + u8 idx = rate - DESC_RATEVHT1SS_MCS0; + u8 n_ss, mcs_n; + + /* n spatial stream */ + n_ss = 1 + idx / 10; + /* MCS n */ + mcs_n = idx % 10; + seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); +} + +static void rtw_print_rate(struct seq_file *m, u8 rate) +{ + switch (rate) { + case DESC_RATE1M...DESC_RATE11M: + rtw_print_cck_rate_txt(m, rate); + break; + case DESC_RATE6M...DESC_RATE54M: + rtw_print_ofdm_rate_txt(m, rate); + break; + case DESC_RATEMCS0...DESC_RATEMCS31: + rtw_print_ht_rate_txt(m, rate); + break; + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT4SS_MCS9: + rtw_print_vht_rate_txt(m, rate); + break; + default: + seq_printf(m, " Unknown rate=0x%x\n", rate); + break; + } +} + +#define case_REGD(src) \ + case RTW_REGD_##src: return #src + +static const char *rtw_get_regd_string(u8 regd) +{ + switch (regd) { + case_REGD(FCC); + case_REGD(MKK); + case_REGD(ETSI); + case_REGD(IC); + case_REGD(KCC); + case_REGD(ACMA); + case_REGD(CHILE); + case_REGD(UKRAINE); + case_REGD(MEXICO); + case_REGD(CN); + case_REGD(WW); + default: + return "Unknown"; + } +} + +static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_power_params pwr_param = {0}; + struct rtw_hal *hal = &rtwdev->hal; + u8 nss = rtwdev->efuse.hw_cap.nss; + u8 path, rate, bw, ch, regd; + u8 max_ht_rate, max_rate; + + mutex_lock(&rtwdev->mutex); + bw = hal->current_band_width; + ch = hal->current_channel; + regd = rtw_regd_get(rtwdev); + + seq_printf(m, "channel: %u\n", ch); + seq_printf(m, "bandwidth: %u\n", bw); + seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); + seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", + "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); + + max_ht_rate = DESC_RATEMCS0 + nss * 8 - 1; + + if (rtwdev->chip->vht_supported) + max_rate = DESC_RATEVHT1SS_MCS0 + nss * 10 - 1; + else + max_rate = max_ht_rate; + + mutex_lock(&hal->tx_power_mutex); + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { + /* there is no CCK rates used in 5G */ + if (hal->current_band_type == RTW_BAND_5G) + rate = DESC_RATE6M; + else + rate = DESC_RATE1M; + + for (; rate <= max_rate; rate++) { + if (rate > max_ht_rate && rate <= DESC_RATEMCS31) + continue; + + rtw_get_tx_power_params(rtwdev, path, rate, bw, + ch, regd, &pwr_param); + + seq_printf(m, "%4c ", path + 'A'); + rtw_print_rate(m, rate); + seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", + hal->tx_pwr_tbl[path][rate], + hal->tx_pwr_tbl[path][rate], + pwr_param.pwr_base, + min3(pwr_param.pwr_offset, + pwr_param.pwr_limit, + pwr_param.pwr_sar), + pwr_param.pwr_offset, pwr_param.pwr_limit, + pwr_param.pwr_sar, + pwr_param.pwr_remnant); + } + } + + mutex_unlock(&hal->tx_power_mutex); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +void rtw_debugfs_get_simple_phy_info(struct seq_file *m) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_traffic_stats *stats = &rtwdev->stats; + + seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", + dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); + + seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", + stats->tx_throughput, stats->rx_throughput); + + seq_puts(m, "[Tx Rate] = "); + rtw_print_rate(m, dm_info->tx_rate); + seq_printf(m, "(0x%x)\n", dm_info->tx_rate); + + seq_puts(m, "[Rx Rate] = "); + rtw_print_rate(m, dm_info->curr_rx_rate); + seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); +} + +static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct ewma_evm *ewma_evm = dm_info->ewma_evm; + struct ewma_snr *ewma_snr = dm_info->ewma_snr; + u8 ss, rate_id; + + seq_puts(m, "==========[Common Info]========\n"); + seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); + seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); + seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); + seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); + seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", + stats->tx_throughput, stats->rx_throughput); + seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? + 'Y' : 'N'); + + seq_puts(m, "==========[Tx Phy Info]========\n"); + seq_puts(m, "[Tx Rate] = "); + rtw_print_rate(m, dm_info->tx_rate); + seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); + + seq_puts(m, "==========[Rx Phy Info]========\n"); + seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); + seq_puts(m, "[Rx Rate] = "); + rtw_print_rate(m, dm_info->curr_rx_rate); + seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); + + seq_puts(m, "[Rx Rate Count]:\n"); + seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", + last_cnt->num_qry_pkt[DESC_RATE1M], + last_cnt->num_qry_pkt[DESC_RATE2M], + last_cnt->num_qry_pkt[DESC_RATE5_5M], + last_cnt->num_qry_pkt[DESC_RATE11M]); + + seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", + last_cnt->num_qry_pkt[DESC_RATE6M], + last_cnt->num_qry_pkt[DESC_RATE9M], + last_cnt->num_qry_pkt[DESC_RATE12M], + last_cnt->num_qry_pkt[DESC_RATE18M], + last_cnt->num_qry_pkt[DESC_RATE24M], + last_cnt->num_qry_pkt[DESC_RATE36M], + last_cnt->num_qry_pkt[DESC_RATE48M], + last_cnt->num_qry_pkt[DESC_RATE54M]); + + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { + rate_id = DESC_RATEMCS0 + ss * 8; + seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", + ss * 8, ss * 8 + 7, + last_cnt->num_qry_pkt[rate_id], + last_cnt->num_qry_pkt[rate_id + 1], + last_cnt->num_qry_pkt[rate_id + 2], + last_cnt->num_qry_pkt[rate_id + 3], + last_cnt->num_qry_pkt[rate_id + 4], + last_cnt->num_qry_pkt[rate_id + 5], + last_cnt->num_qry_pkt[rate_id + 6], + last_cnt->num_qry_pkt[rate_id + 7]); + } + + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { + rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; + seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", + ss + 1, + last_cnt->num_qry_pkt[rate_id], + last_cnt->num_qry_pkt[rate_id + 1], + last_cnt->num_qry_pkt[rate_id + 2], + last_cnt->num_qry_pkt[rate_id + 3], + last_cnt->num_qry_pkt[rate_id + 4], + last_cnt->num_qry_pkt[rate_id + 5], + last_cnt->num_qry_pkt[rate_id + 6], + last_cnt->num_qry_pkt[rate_id + 7], + last_cnt->num_qry_pkt[rate_id + 8], + last_cnt->num_qry_pkt[rate_id + 9]); + } + + seq_printf(m, "[RSSI(dBm)] = {%d, %d, %d, %d}\n", + dm_info->rssi[RF_PATH_A] - 100, + dm_info->rssi[RF_PATH_B] - 100, + dm_info->rssi[RF_PATH_C] - 100, + dm_info->rssi[RF_PATH_D] - 100); + seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d, -%d, -%d}\n", + dm_info->rx_evm_dbm[RF_PATH_A], + dm_info->rx_evm_dbm[RF_PATH_B], + dm_info->rx_evm_dbm[RF_PATH_C], + dm_info->rx_evm_dbm[RF_PATH_D]); + seq_printf(m, "[Rx SNR] = {%d, %d, %d, %d}\n", + dm_info->rx_snr[RF_PATH_A], + dm_info->rx_snr[RF_PATH_B], + dm_info->rx_snr[RF_PATH_C], + dm_info->rx_snr[RF_PATH_D]); + seq_printf(m, "[CFO_tail(KHz)] = {%d, %d, %d, %d}\n", + dm_info->cfo_tail[RF_PATH_A], + dm_info->cfo_tail[RF_PATH_B], + dm_info->cfo_tail[RF_PATH_C], + dm_info->cfo_tail[RF_PATH_D]); + + if (dm_info->curr_rx_rate >= DESC_RATE6M) { + seq_puts(m, "[Rx Average Status]:\n"); + seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); + seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); + seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); + seq_printf(m, " * 3SS, EVM: {-%d, -%d, -%d}, SNR: {%d, %d, %d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_A]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_B]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_C]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_A]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_B]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_C])); + } + + seq_puts(m, "[Rx Counter]:\n"); + seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", + dm_info->cck_cca_cnt, + dm_info->ofdm_cca_cnt, + dm_info->total_cca_cnt); + seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", + dm_info->cck_fa_cnt, + dm_info->ofdm_fa_cnt, + dm_info->total_fa_cnt); + seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", + dm_info->cck_ok_cnt, dm_info->cck_err_cnt); + seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", + dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); + seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", + dm_info->ht_ok_cnt, dm_info->ht_err_cnt); + seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", + dm_info->vht_ok_cnt, dm_info->vht_err_cnt); + + return 0; +} + +static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + mutex_lock(&rtwdev->mutex); + rtw_coex_display_coex_info(rtwdev, m); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + bool enable; + int ret; + + ret = kstrtobool_from_user(buffer, count, &enable); + if (ret) + return ret; + + mutex_lock(&rtwdev->mutex); + coex->manual_control = !enable; + mutex_unlock(&rtwdev->mutex); + + return count; +} + +static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + + seq_printf(m, "coex mechanism %s\n", + coex->manual_control ? "disabled" : "enabled"); + + return 0; +} + +static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + bool input; + int err; + + err = kstrtobool_from_user(buffer, count, &input); + if (err) + return err; + + rtw_edcca_enabled = input; + rtw_phy_adaptivity_set_mode(rtwdev); + + return count; +} + +static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + seq_printf(m, "EDCCA %s: EDCCA mode %d\n", + rtw_edcca_enabled ? "enabled" : "disabled", + dm_info->edcca_mode); + return 0; +} + +static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + bool input; + int ret; + + ret = kstrtobool_from_user(buffer, count, &input); + if (ret) + return ret; + + if (!input) + return -EINVAL; + + if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) + return -EINPROGRESS; + + mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); + rtw_write8(rtwdev, REG_HRCV_MSG, 1); + mutex_unlock(&rtwdev->mutex); + + return count; +} + +static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + seq_printf(m, "%d\n", + test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || + test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); + return 0; +} + +static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + bool input; + int err; + + err = kstrtobool_from_user(buffer, count, &input); + if (err) + return err; + + if (input) + set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); + else + clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); + + return count; +} + +static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + seq_printf(m, "force lowest basic rate: %d\n", + test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); + + return 0; +} + +static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + int ret, bit; + bool en; + + ret = kstrtoint_from_user(buffer, count, 10, &bit); + if (ret) + return ret; + + en = bit > 0; + bit = abs(bit); + + if (bit >= RTW_DM_CAP_NUM) { + rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); + return -EINVAL; + } + + if (en) + dm_info->dm_flags &= ~BIT(bit); + else + dm_info->dm_flags |= BIT(bit); + + debugfs_priv->dm_cap.bit = bit; + + return count; +} + +static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + int i, path; + u32 val; + + seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, + dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', + rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); + + mutex_lock(&rtwdev->mutex); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); + seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); + + for (i = 0; i < RF_HW_OFFSET_NUM; i++) + seq_printf(m, "[TXGAPK] offset %d %d\n", + txgapk->rf3f_fs[path][i], i); + seq_puts(m, "\n"); + } + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + int i; + + switch (debugfs_priv->dm_cap.bit) { + case RTW_DM_CAP_TXGAPK: + dump_gapk_status(rtwdev, m); + break; + default: + for (i = 1; i < RTW_DM_CAP_NUM; i++) { + seq_printf(m, "(%2d) %c%s\n", i, + dm_info->dm_flags & BIT(i) ? '-' : '+', + rtw_dm_cap_strs[i]); + } + break; + } + debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; + return 0; +} + +#define rtw_debug_priv_mac(addr) \ +{ \ + .cb_read = rtw_debug_get_mac_page, \ + .cb_data = addr, \ +} + +#define rtw_debug_priv_bb(addr) \ +{ \ + .cb_read = rtw_debug_get_bb_page, \ + .cb_data = addr, \ +} + +#define rtw_debug_priv_get(name) \ +{ \ + .cb_read = rtw_debugfs_get_ ##name, \ +} + +#define rtw_debug_priv_set(name) \ +{ \ + .cb_write = rtw_debugfs_set_ ##name, \ +} + +#define rtw_debug_priv_set_and_get(name) \ +{ \ + .cb_write = rtw_debugfs_set_ ##name, \ + .cb_read = rtw_debugfs_get_ ##name, \ +} + +#define rtw_debug_priv_set_single_and_get(name) \ +{ \ + .cb_write = rtw_debugfs_set_single_input, \ + .cb_read = rtw_debugfs_get_ ##name, \ +} + +static const struct rtw_debugfs rtw_debugfs_templ = { + .mac_0 = rtw_debug_priv_mac(0x0000), + .mac_1 = rtw_debug_priv_mac(0x0100), + .mac_2 = rtw_debug_priv_mac(0x0200), + .mac_3 = rtw_debug_priv_mac(0x0300), + .mac_4 = rtw_debug_priv_mac(0x0400), + .mac_5 = rtw_debug_priv_mac(0x0500), + .mac_6 = rtw_debug_priv_mac(0x0600), + .mac_7 = rtw_debug_priv_mac(0x0700), + .mac_10 = rtw_debug_priv_mac(0x1000), + .mac_11 = rtw_debug_priv_mac(0x1100), + .mac_12 = rtw_debug_priv_mac(0x1200), + .mac_13 = rtw_debug_priv_mac(0x1300), + .mac_14 = rtw_debug_priv_mac(0x1400), + .mac_15 = rtw_debug_priv_mac(0x1500), + .mac_16 = rtw_debug_priv_mac(0x1600), + .mac_17 = rtw_debug_priv_mac(0x1700), + .bb_8 = rtw_debug_priv_bb(0x0800), + .bb_9 = rtw_debug_priv_bb(0x0900), + .bb_a = rtw_debug_priv_bb(0x0a00), + .bb_b = rtw_debug_priv_bb(0x0b00), + .bb_c = rtw_debug_priv_bb(0x0c00), + .bb_d = rtw_debug_priv_bb(0x0d00), + .bb_e = rtw_debug_priv_bb(0x0e00), + .bb_f = rtw_debug_priv_bb(0x0f00), + .bb_18 = rtw_debug_priv_bb(0x1800), + .bb_19 = rtw_debug_priv_bb(0x1900), + .bb_1a = rtw_debug_priv_bb(0x1a00), + .bb_1b = rtw_debug_priv_bb(0x1b00), + .bb_1c = rtw_debug_priv_bb(0x1c00), + .bb_1d = rtw_debug_priv_bb(0x1d00), + .bb_1e = rtw_debug_priv_bb(0x1e00), + .bb_1f = rtw_debug_priv_bb(0x1f00), + .bb_2c = rtw_debug_priv_bb(0x2c00), + .bb_2d = rtw_debug_priv_bb(0x2d00), + .bb_40 = rtw_debug_priv_bb(0x4000), + .bb_41 = rtw_debug_priv_bb(0x4100), + .rf_dump = rtw_debug_priv_get(rf_dump), + .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl), + .write_reg = rtw_debug_priv_set(write_reg), + .h2c = rtw_debug_priv_set(h2c), + .rf_write = rtw_debug_priv_set(rf_write), + .rf_read = rtw_debug_priv_set_and_get(rf_read), + .read_reg = rtw_debug_priv_set_and_get(read_reg), + .fix_rate = rtw_debug_priv_set_and_get(fix_rate), + .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam), + .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page), + .phy_info = rtw_debug_priv_get(phy_info), + .coex_enable = rtw_debug_priv_set_and_get(coex_enable), + .coex_info = rtw_debug_priv_get(coex_info), + .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable), + .fw_crash = rtw_debug_priv_set_and_get(fw_crash), + .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate), + .dm_cap = rtw_debug_priv_set_and_get(dm_cap), +}; + +#define rtw_debugfs_add_core(name, mode, fopname, parent) \ + do { \ + struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \ + priv->rtwdev = rtwdev; \ + if (IS_ERR(debugfs_create_file(#name, mode, \ + parent, priv, \ + &file_ops_ ##fopname))) \ + pr_debug("Unable to initialize debugfs:%s\n", \ + #name); \ + } while (0) + +#define rtw_debugfs_add_w(name) \ + rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) +#define rtw_debugfs_add_rw(name) \ + rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) +#define rtw_debugfs_add_r(name) \ + rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) + +static +void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw_debugfs_add_w(write_reg); + rtw_debugfs_add_rw(read_reg); + rtw_debugfs_add_w(rf_write); + rtw_debugfs_add_rw(rf_read); + rtw_debugfs_add_rw(fix_rate); + rtw_debugfs_add_rw(dump_cam); + rtw_debugfs_add_rw(rsvd_page); + rtw_debugfs_add_r(phy_info); + rtw_debugfs_add_r(coex_info); + rtw_debugfs_add_rw(coex_enable); + rtw_debugfs_add_w(h2c); + rtw_debugfs_add_r(rf_dump); + rtw_debugfs_add_r(tx_pwr_tbl); + rtw_debugfs_add_rw(edcca_enable); + rtw_debugfs_add_rw(fw_crash); + rtw_debugfs_add_rw(force_lowest_basic_rate); + rtw_debugfs_add_rw(dm_cap); +} + +static +void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw_debugfs_add_r(mac_0); + rtw_debugfs_add_r(mac_1); + rtw_debugfs_add_r(mac_2); + rtw_debugfs_add_r(mac_3); + rtw_debugfs_add_r(mac_4); + rtw_debugfs_add_r(mac_5); + rtw_debugfs_add_r(mac_6); + rtw_debugfs_add_r(mac_7); + rtw_debugfs_add_r(bb_8); + rtw_debugfs_add_r(bb_9); + rtw_debugfs_add_r(bb_a); + rtw_debugfs_add_r(bb_b); + rtw_debugfs_add_r(bb_c); + rtw_debugfs_add_r(bb_d); + rtw_debugfs_add_r(bb_e); + rtw_debugfs_add_r(bb_f); +} + +static +void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw_debugfs_add_r(mac_10); + rtw_debugfs_add_r(mac_11); + rtw_debugfs_add_r(mac_12); + rtw_debugfs_add_r(mac_13); + rtw_debugfs_add_r(mac_14); + rtw_debugfs_add_r(mac_15); + rtw_debugfs_add_r(mac_16); + rtw_debugfs_add_r(mac_17); + rtw_debugfs_add_r(bb_18); + rtw_debugfs_add_r(bb_19); + rtw_debugfs_add_r(bb_1a); + rtw_debugfs_add_r(bb_1b); + rtw_debugfs_add_r(bb_1c); + rtw_debugfs_add_r(bb_1d); + rtw_debugfs_add_r(bb_1e); + rtw_debugfs_add_r(bb_1f); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { + rtw_debugfs_add_r(bb_2c); + rtw_debugfs_add_r(bb_2d); + rtw_debugfs_add_r(bb_40); + rtw_debugfs_add_r(bb_41); + } +} + +void rtw_debugfs_init(struct rtw_dev *rtwdev) +{ + struct dentry *debugfs_topdir; + + rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ), + GFP_KERNEL); + if (!rtwdev->debugfs) + return; + + debugfs_topdir = debugfs_create_dir("rtw88", + rtwdev->hw->wiphy->debugfsdir); + + rtw_debugfs_add_basic(rtwdev, debugfs_topdir); + rtw_debugfs_add_sec0(rtwdev, debugfs_topdir); + rtw_debugfs_add_sec1(rtwdev, debugfs_topdir); +} + +void rtw_debugfs_deinit(struct rtw_dev *rtwdev) +{ + kfree(rtwdev->debugfs); +} +#endif /* CONFIG_RTW88_DEBUGFS */ + +#ifdef CONFIG_RTW88_DEBUG + +void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, + const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + if (rtw_debug_mask & mask) + dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); + + va_end(args); +} +EXPORT_SYMBOL(rtw_dbg); + +#endif /* CONFIG_RTW88_DEBUG */ diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h new file mode 100644 index 000000000..6570e84d8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/debug.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_DEBUG_H +#define __RTW_DEBUG_H + +enum rtw_debug_mask { + RTW_DBG_PCI = 0x00000001, + RTW_DBG_TX = 0x00000002, + RTW_DBG_RX = 0x00000004, + RTW_DBG_PHY = 0x00000008, + RTW_DBG_FW = 0x00000010, + RTW_DBG_EFUSE = 0x00000020, + RTW_DBG_COEX = 0x00000040, + RTW_DBG_RFK = 0x00000080, + RTW_DBG_REGD = 0x00000100, + RTW_DBG_DEBUGFS = 0x00000200, + RTW_DBG_PS = 0x00000400, + RTW_DBG_BF = 0x00000800, + RTW_DBG_WOW = 0x00001000, + RTW_DBG_CFO = 0x00002000, + RTW_DBG_PATH_DIV = 0x00004000, + RTW_DBG_ADAPTIVITY = 0x00008000, + RTW_DBG_HW_SCAN = 0x00010000, + RTW_DBG_STATE = 0x00020000, + RTW_DBG_SDIO = 0x00040000, + RTW_DBG_USB = 0x00080000, + + RTW_DBG_UNEXP = 0x80000000, + RTW_DBG_ALL = 0xffffffff +}; + +#ifdef CONFIG_RTW88_DEBUGFS + +void rtw_debugfs_init(struct rtw_dev *rtwdev); +void rtw_debugfs_deinit(struct rtw_dev *rtwdev); +void rtw_debugfs_get_simple_phy_info(struct seq_file *m); + +#else + +static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {} +static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {} + +#endif /* CONFIG_RTW88_DEBUGFS */ + +#ifdef CONFIG_RTW88_DEBUG + +__printf(3, 4) +void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, + const char *fmt, ...); + +static inline bool rtw_dbg_is_enabled(struct rtw_dev *rtwdev, + enum rtw_debug_mask mask) +{ + return !!(rtw_debug_mask & mask); +} + +#else + +static inline void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, + const char *fmt, ...) {} + +static inline bool rtw_dbg_is_enabled(struct rtw_dev *rtwdev, + enum rtw_debug_mask mask) +{ + return false; +} + +#endif /* CONFIG_RTW88_DEBUG */ + +#define rtw_info(rtwdev, a...) dev_info(rtwdev->dev, ##a) +#define rtw_warn(rtwdev, a...) dev_warn(rtwdev->dev, ##a) +#define rtw_err(rtwdev, a...) dev_err(rtwdev->dev, ##a) + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/efuse.c b/drivers/net/wireless/realtek/rtw88/efuse.c new file mode 100644 index 000000000..b85075cd6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/efuse.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include + +#include "main.h" +#include "efuse.h" +#include "reg.h" +#include "debug.h" + +#define RTW_EFUSE_BANK_WIFI 0x0 + +static void switch_efuse_bank(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, REG_LDO_EFUSE_CTRL, BIT_MASK_EFUSE_BANK_SEL, + RTW_EFUSE_BANK_WIFI); +} + +#define invalid_efuse_header(hdr1, hdr2) \ + ((hdr1) == 0xff || (((hdr1) & 0x1f) == 0xf && (hdr2) == 0xff)) +#define invalid_efuse_content(word_en, i) \ + (((word_en) & BIT(i)) != 0x0) +#define get_efuse_blk_idx_2_byte(hdr1, hdr2) \ + ((((hdr2) & 0xf0) >> 1) | (((hdr1) >> 5) & 0x07)) +#define get_efuse_blk_idx_1_byte(hdr1) \ + (((hdr1) & 0xf0) >> 4) +#define block_idx_to_logical_idx(blk_idx, i) \ + (((blk_idx) << 3) + ((i) << 1)) + +/* efuse header format + * + * | 7 5 4 0 | 7 4 3 0 | 15 8 7 0 | + * block[2:0] 0 1111 block[6:3] word_en[3:0] byte0 byte1 + * | header 1 (optional) | header 2 | word N | + * + * word_en: 4 bits each word. 0 -> write; 1 -> not write + * N: 1~4, depends on word_en + */ +static int rtw_dump_logical_efuse_map(struct rtw_dev *rtwdev, u8 *phy_map, + u8 *log_map) +{ + u32 physical_size = rtwdev->efuse.physical_size; + u32 protect_size = rtwdev->efuse.protect_size; + u32 logical_size = rtwdev->efuse.logical_size; + u32 phy_idx, log_idx; + u8 hdr1, hdr2; + u8 blk_idx; + u8 word_en; + int i; + + for (phy_idx = 0; phy_idx < physical_size - protect_size;) { + hdr1 = phy_map[phy_idx]; + hdr2 = phy_map[phy_idx + 1]; + if (invalid_efuse_header(hdr1, hdr2)) + break; + + if ((hdr1 & 0x1f) == 0xf) { + /* 2-byte header format */ + blk_idx = get_efuse_blk_idx_2_byte(hdr1, hdr2); + word_en = hdr2 & 0xf; + phy_idx += 2; + } else { + /* 1-byte header format */ + blk_idx = get_efuse_blk_idx_1_byte(hdr1); + word_en = hdr1 & 0xf; + phy_idx += 1; + } + + for (i = 0; i < 4; i++) { + if (invalid_efuse_content(word_en, i)) + continue; + + log_idx = block_idx_to_logical_idx(blk_idx, i); + if (phy_idx + 1 > physical_size - protect_size || + log_idx + 1 > logical_size) + return -EINVAL; + + log_map[log_idx] = phy_map[phy_idx]; + log_map[log_idx + 1] = phy_map[phy_idx + 1]; + phy_idx += 2; + } + } + return 0; +} + +static int rtw_dump_physical_efuse_map(struct rtw_dev *rtwdev, u8 *map) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u32 size = rtwdev->efuse.physical_size; + u32 efuse_ctl; + u32 addr; + u32 cnt; + + rtw_chip_efuse_grant_on(rtwdev); + + switch_efuse_bank(rtwdev); + + /* disable 2.5V LDO */ + chip->ops->cfg_ldo25(rtwdev, false); + + efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL); + + for (addr = 0; addr < size; addr++) { + efuse_ctl &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR); + efuse_ctl |= (addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR; + rtw_write32(rtwdev, REG_EFUSE_CTRL, efuse_ctl & (~BIT_EF_FLAG)); + + cnt = 1000000; + do { + udelay(1); + efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL); + if (--cnt == 0) + return -EBUSY; + } while (!(efuse_ctl & BIT_EF_FLAG)); + + *(map + addr) = (u8)(efuse_ctl & BIT_MASK_EF_DATA); + } + + rtw_chip_efuse_grant_off(rtwdev); + + return 0; +} + +int rtw_read8_physical_efuse(struct rtw_dev *rtwdev, u16 addr, u8 *data) +{ + u32 efuse_ctl; + int ret; + + rtw_write32_mask(rtwdev, REG_EFUSE_CTRL, 0x3ff00, addr); + rtw_write32_clr(rtwdev, REG_EFUSE_CTRL, BIT_EF_FLAG); + + ret = read_poll_timeout(rtw_read32, efuse_ctl, efuse_ctl & BIT_EF_FLAG, + 1000, 100000, false, rtwdev, REG_EFUSE_CTRL); + if (ret) { + *data = EFUSE_READ_FAIL; + return ret; + } + + *data = rtw_read8(rtwdev, REG_EFUSE_CTRL); + + return 0; +} +EXPORT_SYMBOL(rtw_read8_physical_efuse); + +int rtw_parse_efuse_map(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u32 phy_size = efuse->physical_size; + u32 log_size = efuse->logical_size; + u8 *phy_map = NULL; + u8 *log_map = NULL; + int ret = 0; + + phy_map = kmalloc(phy_size, GFP_KERNEL); + log_map = kmalloc(log_size, GFP_KERNEL); + if (!phy_map || !log_map) { + ret = -ENOMEM; + goto out_free; + } + + ret = rtw_dump_physical_efuse_map(rtwdev, phy_map); + if (ret) { + rtw_err(rtwdev, "failed to dump efuse physical map\n"); + goto out_free; + } + + memset(log_map, 0xff, log_size); + ret = rtw_dump_logical_efuse_map(rtwdev, phy_map, log_map); + if (ret) { + rtw_err(rtwdev, "failed to dump efuse logical map\n"); + goto out_free; + } + + ret = chip->ops->read_efuse(rtwdev, log_map); + if (ret) { + rtw_err(rtwdev, "failed to read efuse map\n"); + goto out_free; + } + +out_free: + kfree(log_map); + kfree(phy_map); + + return ret; +} diff --git a/drivers/net/wireless/realtek/rtw88/efuse.h b/drivers/net/wireless/realtek/rtw88/efuse.h new file mode 100644 index 000000000..97a51f0b0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/efuse.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_EFUSE_H__ +#define __RTW_EFUSE_H__ + +#define EFUSE_HW_CAP_IGNORE 0 +#define EFUSE_HW_CAP_PTCL_VHT 3 +#define EFUSE_HW_CAP_SUPP_BW80 7 +#define EFUSE_HW_CAP_SUPP_BW40 6 + +#define EFUSE_READ_FAIL 0xff + +#define GET_EFUSE_HW_CAP_HCI(hw_cap) \ + le32_get_bits(*((__le32 *)(hw_cap) + 0x01), GENMASK(3, 0)) +#define GET_EFUSE_HW_CAP_BW(hw_cap) \ + le32_get_bits(*((__le32 *)(hw_cap) + 0x01), GENMASK(18, 16)) +#define GET_EFUSE_HW_CAP_NSS(hw_cap) \ + le32_get_bits(*((__le32 *)(hw_cap) + 0x01), GENMASK(20, 19)) +#define GET_EFUSE_HW_CAP_ANT_NUM(hw_cap) \ + le32_get_bits(*((__le32 *)(hw_cap) + 0x01), GENMASK(23, 21)) +#define GET_EFUSE_HW_CAP_PTCL(hw_cap) \ + le32_get_bits(*((__le32 *)(hw_cap) + 0x01), GENMASK(27, 26)) + +int rtw_parse_efuse_map(struct rtw_dev *rtwdev); +int rtw_read8_physical_efuse(struct rtw_dev *rtwdev, u16 addr, u8 *data); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c new file mode 100644 index 000000000..945fedcd3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -0,0 +1,2471 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include + +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "reg.h" +#include "sec.h" +#include "debug.h" +#include "util.h" +#include "wow.h" +#include "ps.h" +#include "phy.h" +#include "mac.h" + +static const struct rtw_hw_reg_desc fw_h2c_regs[] = { + {REG_FWIMR, MASKDWORD, "FWIMR"}, + {REG_FWIMR, BIT_FS_H2CCMD_INT_EN, "FWIMR enable"}, + {REG_FWISR, MASKDWORD, "FWISR"}, + {REG_FWISR, BIT_FS_H2CCMD_INT, "FWISR enable"}, + {REG_HMETFR, BIT_INT_BOX_ALL, "BoxBitMap"}, + {REG_HMEBOX0, MASKDWORD, "MSG 0"}, + {REG_HMEBOX0_EX, MASKDWORD, "MSG_EX 0"}, + {REG_HMEBOX1, MASKDWORD, "MSG 1"}, + {REG_HMEBOX1_EX, MASKDWORD, "MSG_EX 1"}, + {REG_HMEBOX2, MASKDWORD, "MSG 2"}, + {REG_HMEBOX2_EX, MASKDWORD, "MSG_EX 2"}, + {REG_HMEBOX3, MASKDWORD, "MSG 3"}, + {REG_HMEBOX3_EX, MASKDWORD, "MSG_EX 3"}, + {REG_FT1IMR, MASKDWORD, "FT1IMR"}, + {REG_FT1IMR, BIT_FS_H2C_CMD_OK_INT_EN, "FT1IMR enable"}, + {REG_FT1ISR, MASKDWORD, "FT1ISR"}, + {REG_FT1ISR, BIT_FS_H2C_CMD_OK_INT, "FT1ISR enable "}, +}; + +static const struct rtw_hw_reg_desc fw_c2h_regs[] = { + {REG_FWIMR, MASKDWORD, "FWIMR"}, + {REG_FWIMR, BIT_FS_H2CCMD_INT_EN, "CPWM"}, + {REG_FWIMR, BIT_FS_HRCV_INT_EN, "HRECV"}, + {REG_FWISR, MASKDWORD, "FWISR"}, + {REG_FWISR, BIT_FS_H2CCMD_INT, "CPWM"}, + {REG_FWISR, BIT_FS_HRCV_INT, "HRECV"}, + {REG_CPWM, MASKDWORD, "REG_CPWM"}, +}; + +static const struct rtw_hw_reg_desc fw_core_regs[] = { + {REG_ARFR2_V1, MASKDWORD, "EPC"}, + {REG_ARFRH2_V1, MASKDWORD, "BADADDR"}, + {REG_ARFR3_V1, MASKDWORD, "CAUSE"}, + {REG_ARFR3_V1, BIT_EXC_CODE, "ExcCode"}, + {REG_ARFRH3_V1, MASKDWORD, "Status"}, + {REG_ARFR4, MASKDWORD, "SP"}, + {REG_ARFRH4, MASKDWORD, "RA"}, + {REG_FW_DBG6, MASKDWORD, "DBG 6"}, + {REG_FW_DBG7, MASKDWORD, "DBG 7"}, +}; + +static void _rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev, + const struct rtw_hw_reg_desc regs[], u32 size) +{ + const struct rtw_hw_reg_desc *reg; + u32 val; + int i; + + for (i = 0; i < size; i++) { + reg = ®s[i]; + val = rtw_read32_mask(rtwdev, reg->addr, reg->mask); + + rtw_dbg(rtwdev, RTW_DBG_FW, "[%s]addr:0x%x mask:0x%x value:0x%x\n", + reg->desc, reg->addr, reg->mask, val); + } +} + +void rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev) +{ + int i; + + if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_FW)) + return; + + _rtw_fw_dump_dbg_info(rtwdev, fw_h2c_regs, ARRAY_SIZE(fw_h2c_regs)); + _rtw_fw_dump_dbg_info(rtwdev, fw_c2h_regs, ARRAY_SIZE(fw_c2h_regs)); + for (i = 0 ; i < RTW_DEBUG_DUMP_TIMES; i++) { + rtw_dbg(rtwdev, RTW_DBG_FW, "Firmware Coredump %dth\n", i + 1); + _rtw_fw_dump_dbg_info(rtwdev, fw_core_regs, ARRAY_SIZE(fw_core_regs)); + } +} + +static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw_c2h_cmd *c2h; + u8 sub_cmd_id; + + c2h = get_c2h_from_skb(skb); + sub_cmd_id = c2h->payload[0]; + + switch (sub_cmd_id) { + case C2H_CCX_RPT: + rtw_tx_report_handle(rtwdev, skb, C2H_CCX_RPT); + break; + case C2H_SCAN_STATUS_RPT: + rtw_hw_scan_status_report(rtwdev, skb); + break; + case C2H_CHAN_SWITCH: + rtw_hw_scan_chan_switch(rtwdev, skb); + break; + default: + break; + } +} + +static u16 get_max_amsdu_len(u32 bit_rate) +{ + /* lower than ofdm, do not aggregate */ + if (bit_rate < 550) + return 1; + + /* lower than 20M 2ss mcs8, make it small */ + if (bit_rate < 1800) + return 1200; + + /* lower than 40M 2ss mcs9, make it medium */ + if (bit_rate < 4000) + return 2600; + + /* not yet 80M 2ss mcs8/9, make it twice regular packet size */ + if (bit_rate < 7000) + return 3500; + + /* unlimited */ + return 0; +} + +struct rtw_fw_iter_ra_data { + struct rtw_dev *rtwdev; + u8 *payload; + u8 length; +}; + +static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_fw_iter_ra_data *ra_data = data; + struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + u8 mac_id, rate, sgi, bw; + u8 mcs, nss; + u32 bit_rate; + + mac_id = ra_rpt->mac_id; + if (si->mac_id != mac_id) + return; + + si->ra_report.txrate.flags = 0; + + rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE); + sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI); + if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw)) + bw = ra_rpt->bw; + else + bw = si->bw_mode; + + if (rate < DESC_RATEMCS0) { + si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); + goto legacy; + } + + rtw_desc_to_mcsrate(rate, &mcs, &nss); + if (rate >= DESC_RATEVHT1SS_MCS0) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + else if (rate >= DESC_RATEMCS0) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_MCS; + + if (rate >= DESC_RATEMCS0) { + si->ra_report.txrate.mcs = mcs; + si->ra_report.txrate.nss = nss; + } + + if (sgi) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (bw == RTW_CHANNEL_WIDTH_80) + si->ra_report.txrate.bw = RATE_INFO_BW_80; + else if (bw == RTW_CHANNEL_WIDTH_40) + si->ra_report.txrate.bw = RATE_INFO_BW_40; + else + si->ra_report.txrate.bw = RATE_INFO_BW_20; + +legacy: + bit_rate = cfg80211_calculate_bitrate(&si->ra_report.txrate); + + si->ra_report.desc_rate = rate; + si->ra_report.bit_rate = bit_rate; + + sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(bit_rate); +} + +static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload, + u8 length) +{ + struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload; + struct rtw_fw_iter_ra_data ra_data; + + if (WARN(length < rtwdev->chip->c2h_ra_report_size, + "invalid ra report c2h length %d\n", length)) + return; + + rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi, + RTW_C2H_RA_RPT_RATE); + ra_data.rtwdev = rtwdev; + ra_data.payload = payload; + ra_data.length = length; + rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data); +} + +struct rtw_beacon_filter_iter_data { + struct rtw_dev *rtwdev; + u8 *payload; +}; + +static void rtw_fw_bcn_filter_notify_vif_iter(void *data, + struct ieee80211_vif *vif) +{ + struct rtw_beacon_filter_iter_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + u8 *payload = iter_data->payload; + u8 type = GET_BCN_FILTER_NOTIFY_TYPE(payload); + u8 event = GET_BCN_FILTER_NOTIFY_EVENT(payload); + s8 sig = (s8)GET_BCN_FILTER_NOTIFY_RSSI(payload); + + switch (type) { + case BCN_FILTER_NOTIFY_SIGNAL_CHANGE: + event = event ? NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH : + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + ieee80211_cqm_rssi_notify(vif, event, sig, GFP_KERNEL); + break; + case BCN_FILTER_CONNECTION_LOSS: + ieee80211_connection_loss(vif); + break; + case BCN_FILTER_CONNECTED: + rtwdev->beacon_loss = false; + break; + case BCN_FILTER_NOTIFY_BEACON_LOSS: + rtwdev->beacon_loss = true; + rtw_leave_lps(rtwdev); + break; + } +} + +static void rtw_fw_bcn_filter_notify(struct rtw_dev *rtwdev, u8 *payload, + u8 length) +{ + struct rtw_beacon_filter_iter_data dev_iter_data; + + dev_iter_data.rtwdev = rtwdev; + dev_iter_data.payload = payload; + rtw_iterate_vifs(rtwdev, rtw_fw_bcn_filter_notify_vif_iter, + &dev_iter_data); +} + +static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload, + u8 length) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->scan_density = payload[0]; + + rtw_dbg(rtwdev, RTW_DBG_FW, "scan.density = %x\n", + dm_info->scan_density); +} + +static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload, + u8 length) +{ + const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload; + + if (!edcca_th) + return; + + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, + "Adaptivity: density %x igi %x l2h_th_init %x l2h %x h2l %x option %x\n", + result->density, result->igi, result->l2h_th_init, result->l2h, + result->h2l, result->option); + + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "Reg Setting: L2H %x H2L %x\n", + rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask), + rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask)); + + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "EDCCA Flag %s\n", + rtw_read32_mask(rtwdev, REG_EDCCA_REPORT, BIT_EDCCA_FLAG) ? + "Set" : "Unset"); +} + +void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw_c2h_cmd *c2h; + u32 pkt_offset; + u8 len; + + pkt_offset = *((u32 *)skb->cb); + c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset); + len = skb->len - pkt_offset - 2; + + mutex_lock(&rtwdev->mutex); + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + goto unlock; + + switch (c2h->id) { + case C2H_CCX_TX_RPT: + rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT); + break; + case C2H_BT_INFO: + rtw_coex_bt_info_notify(rtwdev, c2h->payload, len); + break; + case C2H_BT_HID_INFO: + rtw_coex_bt_hid_info_notify(rtwdev, c2h->payload, len); + break; + case C2H_WLAN_INFO: + rtw_coex_wl_fwdbginfo_notify(rtwdev, c2h->payload, len); + break; + case C2H_BCN_FILTER_NOTIFY: + rtw_fw_bcn_filter_notify(rtwdev, c2h->payload, len); + break; + case C2H_HALMAC: + rtw_fw_c2h_cmd_handle_ext(rtwdev, skb); + break; + case C2H_RA_RPT: + rtw_fw_ra_report_handle(rtwdev, c2h->payload, len); + break; + case C2H_ADAPTIVITY: + rtw_fw_adaptivity_result(rtwdev, c2h->payload, len); + break; + default: + rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id); + break; + } + +unlock: + mutex_unlock(&rtwdev->mutex); +} + +void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset, + struct sk_buff *skb) +{ + struct rtw_c2h_cmd *c2h; + u8 len; + + c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset); + len = skb->len - pkt_offset - 2; + *((u32 *)skb->cb) = pkt_offset; + + rtw_dbg(rtwdev, RTW_DBG_FW, "recv C2H, id=0x%02x, seq=0x%02x, len=%d\n", + c2h->id, c2h->seq, len); + + switch (c2h->id) { + case C2H_BT_MP_INFO: + rtw_coex_info_response(rtwdev, skb); + break; + case C2H_WLAN_RFON: + complete(&rtwdev->lps_leave_check); + dev_kfree_skb_any(skb); + break; + case C2H_SCAN_RESULT: + complete(&rtwdev->fw_scan_density); + rtw_fw_scan_result(rtwdev, c2h->payload, len); + dev_kfree_skb_any(skb); + break; + default: + /* pass offset for further operation */ + *((u32 *)skb->cb) = pkt_offset; + skb_queue_tail(&rtwdev->c2h_queue, skb); + ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); + break; + } +} +EXPORT_SYMBOL(rtw_fw_c2h_cmd_rx_irqsafe); + +void rtw_fw_c2h_cmd_isr(struct rtw_dev *rtwdev) +{ + if (rtw_read8(rtwdev, REG_MCU_TST_CFG) == VAL_FW_TRIGGER) + rtw_fw_recovery(rtwdev); + else + rtw_warn(rtwdev, "unhandled firmware c2h interrupt\n"); +} +EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); + +static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, + struct rtw_h2c_register *h2c) +{ + u32 box_reg, box_ex_reg; + u8 box_state, box; + int ret; + + rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, + h2c->w1); + + lockdep_assert_held(&rtwdev->mutex); + + box = rtwdev->h2c.last_box_num; + switch (box) { + case 0: + box_reg = REG_HMEBOX0; + box_ex_reg = REG_HMEBOX0_EX; + break; + case 1: + box_reg = REG_HMEBOX1; + box_ex_reg = REG_HMEBOX1_EX; + break; + case 2: + box_reg = REG_HMEBOX2; + box_ex_reg = REG_HMEBOX2_EX; + break; + case 3: + box_reg = REG_HMEBOX3; + box_ex_reg = REG_HMEBOX3_EX; + break; + default: + WARN(1, "invalid h2c mail box number\n"); + return; + } + + ret = read_poll_timeout_atomic(rtw_read8, box_state, + !((box_state >> box) & 0x1), 100, 3000, + false, rtwdev, REG_HMETFR); + + if (ret) { + rtw_err(rtwdev, "failed to send h2c command\n"); + rtw_fw_dump_dbg_info(rtwdev); + return; + } + + rtw_write32(rtwdev, box_ex_reg, h2c->w1); + rtw_write32(rtwdev, box_reg, h2c->w0); + + if (++rtwdev->h2c.last_box_num >= 4) + rtwdev->h2c.last_box_num = 0; +} + +static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + u8 *h2c) +{ + struct rtw_h2c_cmd *h2c_cmd = (struct rtw_h2c_cmd *)h2c; + u8 box; + u8 box_state; + u32 box_reg, box_ex_reg; + int ret; + + rtw_dbg(rtwdev, RTW_DBG_FW, + "send H2C content %02x%02x%02x%02x %02x%02x%02x%02x\n", + h2c[3], h2c[2], h2c[1], h2c[0], + h2c[7], h2c[6], h2c[5], h2c[4]); + + lockdep_assert_held(&rtwdev->mutex); + + box = rtwdev->h2c.last_box_num; + switch (box) { + case 0: + box_reg = REG_HMEBOX0; + box_ex_reg = REG_HMEBOX0_EX; + break; + case 1: + box_reg = REG_HMEBOX1; + box_ex_reg = REG_HMEBOX1_EX; + break; + case 2: + box_reg = REG_HMEBOX2; + box_ex_reg = REG_HMEBOX2_EX; + break; + case 3: + box_reg = REG_HMEBOX3; + box_ex_reg = REG_HMEBOX3_EX; + break; + default: + WARN(1, "invalid h2c mail box number\n"); + return; + } + + ret = read_poll_timeout_atomic(rtw_read8, box_state, + !((box_state >> box) & 0x1), 100, 3000, + false, rtwdev, REG_HMETFR); + + if (ret) { + rtw_err(rtwdev, "failed to send h2c command\n"); + return; + } + + rtw_write32(rtwdev, box_ex_reg, le32_to_cpu(h2c_cmd->msg_ext)); + rtw_write32(rtwdev, box_reg, le32_to_cpu(h2c_cmd->msg)); + + if (++rtwdev->h2c.last_box_num >= 4) + rtwdev->h2c.last_box_num = 0; +} + +void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c) +{ + rtw_fw_send_h2c_command(rtwdev, h2c); +} + +static void rtw_fw_send_h2c_packet(struct rtw_dev *rtwdev, u8 *h2c_pkt) +{ + int ret; + + lockdep_assert_held(&rtwdev->mutex); + + FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq); + ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE); + if (ret) + rtw_err(rtwdev, "failed to send h2c packet\n"); + rtwdev->h2c.seq++; +} + +void +rtw_fw_send_general_info(struct rtw_dev *rtwdev) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + 4; + + if (rtw_chip_wcpu_8051(rtwdev)) + return; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO); + + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + + GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_pkt, + fifo->rsvd_fw_txbuf_addr - + fifo->rsvd_boundary); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void +rtw_fw_send_phydm_info(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + 8; + u8 fw_rf_type = 0; + + if (rtw_chip_wcpu_8051(rtwdev)) + return; + + if (hal->rf_type == RF_1T1R) + fw_rf_type = FW_RF_1T1R; + else if (hal->rf_type == RF_2T2R) + fw_rf_type = FW_RF_2T2R; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_PHYDM_INFO); + + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + PHYDM_INFO_SET_REF_TYPE(h2c_pkt, efuse->rfe_option); + PHYDM_INFO_SET_RF_TYPE(h2c_pkt, fw_rf_type); + PHYDM_INFO_SET_CUT_VER(h2c_pkt, hal->cut_version); + PHYDM_INFO_SET_RX_ANT_STATUS(h2c_pkt, hal->antenna_tx); + PHYDM_INFO_SET_TX_ANT_STATUS(h2c_pkt, hal->antenna_rx); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + 1; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_IQK); + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + IQK_SET_CLEAR(h2c_pkt, para->clear); + IQK_SET_SEGMENT_IQK(h2c_pkt, para->segment_iqk); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} +EXPORT_SYMBOL(rtw_fw_do_iqk); + +void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WIFI_CALIBRATION); + + RFK_SET_INFORM_START(h2c_pkt, start); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} +EXPORT_SYMBOL(rtw_fw_inform_rfk_status); + +void rtw_fw_query_bt_info(struct rtw_dev *rtwdev) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_INFO); + + SET_QUERY_BT_INFO(h2c_pkt, true); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +{ + struct rtw_h2c_register h2c = {}; + + if (rtwvif->net_type != RTW_NET_MGD_LINKED) + return; + + /* Leave LPS before default port H2C so FW timer is correct */ + rtw_leave_lps(rtwdev); + + h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | + u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | + u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); + + rtw_fw_send_h2c_command_register(rtwdev, &h2c); +} + +void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_CH_INFO); + + SET_WL_CH_INFO_LINK(h2c_pkt, link); + SET_WL_CH_INFO_CHNL(h2c_pkt, ch); + SET_WL_CH_INFO_BW(h2c_pkt, bw); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev, + struct rtw_coex_info_req *req) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_MP_INFO); + + SET_BT_MP_INFO_SEQ(h2c_pkt, req->seq); + SET_BT_MP_INFO_OP_CODE(h2c_pkt, req->op_code); + SET_BT_MP_INFO_PARA1(h2c_pkt, req->para1); + SET_BT_MP_INFO_PARA2(h2c_pkt, req->para2); + SET_BT_MP_INFO_PARA3(h2c_pkt, req->para3); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 index = 0 - bt_pwr_dec_lvl; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_FORCE_BT_TX_POWER); + + SET_BT_TX_POWER_INDEX(h2c_pkt, index); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_IGNORE_WLAN_ACTION); + + SET_IGNORE_WLAN_ACTION_EN(h2c_pkt, enable); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev, + u8 para1, u8 para2, u8 para3, u8 para4, u8 para5) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_COEX_TDMA_TYPE); + + SET_COEX_TDMA_TYPE_PARA1(h2c_pkt, para1); + SET_COEX_TDMA_TYPE_PARA2(h2c_pkt, para2); + SET_COEX_TDMA_TYPE_PARA3(h2c_pkt, para3); + SET_COEX_TDMA_TYPE_PARA4(h2c_pkt, para4); + SET_COEX_TDMA_TYPE_PARA5(h2c_pkt, para5); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_HID_INFO); + + SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, sub_id); + SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, data); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BT_WIFI_CONTROL); + + SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt, op_code); + + SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data); + SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1)); + SET_BT_WIFI_CONTROL_DATA3(h2c_pkt, *(data + 2)); + SET_BT_WIFI_CONTROL_DATA4(h2c_pkt, *(data + 3)); + SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4)); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 rssi = ewma_rssi_read(&si->avg_rssi); + bool stbc_en = si->stbc_en ? true : false; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSSI_MONITOR); + + SET_RSSI_INFO_MACID(h2c_pkt, si->mac_id); + SET_RSSI_INFO_RSSI(h2c_pkt, rssi); + SET_RSSI_INFO_STBC(h2c_pkt, stbc_en); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + bool disable_pt = true; + u32 mask_hi; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO); + + SET_RA_INFO_MACID(h2c_pkt, si->mac_id); + SET_RA_INFO_RATE_ID(h2c_pkt, si->rate_id); + SET_RA_INFO_INIT_RA_LVL(h2c_pkt, si->init_ra_lv); + SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable); + SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode); + SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en); + SET_RA_INFO_NO_UPDATE(h2c_pkt, !reset_ra_mask); + SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable); + SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt); + SET_RA_INFO_RA_MASK0(h2c_pkt, (si->ra_mask & 0xff)); + SET_RA_INFO_RA_MASK1(h2c_pkt, (si->ra_mask & 0xff00) >> 8); + SET_RA_INFO_RA_MASK2(h2c_pkt, (si->ra_mask & 0xff0000) >> 16); + SET_RA_INFO_RA_MASK3(h2c_pkt, (si->ra_mask & 0xff000000) >> 24); + + si->init_ra_lv = 0; + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + + if (rtwdev->chip->id != RTW_CHIP_TYPE_8814A) + return; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI); + + mask_hi = si->ra_mask >> 32; + + SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff)); + SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8); + SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16); + SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_MEDIA_STATUS_RPT); + MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect); + MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev) +{ + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_PHY_INFO); + SET_WL_PHY_INFO_TX_TP(h2c_pkt, stats->tx_throughput); + SET_WL_PHY_INFO_RX_TP(h2c_pkt, stats->rx_throughput); + SET_WL_PHY_INFO_TX_RATE_DESC(h2c_pkt, dm_info->tx_rate); + SET_WL_PHY_INFO_RX_RATE_DESC(h2c_pkt, dm_info->curr_rx_rate); + SET_WL_PHY_INFO_RX_EVM(h2c_pkt, dm_info->rx_evm_dbm[RF_PATH_A]); + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect, + struct ieee80211_vif *vif) +{ + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); + static const u8 rssi_min = 0, rssi_max = 100, rssi_offset = 100; + struct rtw_sta_info *si = + sta ? (struct rtw_sta_info *)sta->drv_priv : NULL; + s32 thold = RTW_DEFAULT_CQM_THOLD; + u32 hyst = RTW_DEFAULT_CQM_HYST; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER)) + return; + + if (bss_conf->cqm_rssi_thold) + thold = bss_conf->cqm_rssi_thold; + if (bss_conf->cqm_rssi_hyst) + hyst = bss_conf->cqm_rssi_hyst; + + if (!connect) { + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P1); + SET_BCN_FILTER_OFFLOAD_P1_ENABLE(h2c_pkt, connect); + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + + return; + } + + if (!si) + return; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P0); + ether_addr_copy(&h2c_pkt[1], bss_conf->bssid); + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + + memset(h2c_pkt, 0, sizeof(h2c_pkt)); + thold = clamp_t(s32, thold + rssi_offset, rssi_min, rssi_max); + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P1); + SET_BCN_FILTER_OFFLOAD_P1_ENABLE(h2c_pkt, connect); + SET_BCN_FILTER_OFFLOAD_P1_OFFLOAD_MODE(h2c_pkt, + BCN_FILTER_OFFLOAD_MODE_DEFAULT); + SET_BCN_FILTER_OFFLOAD_P1_THRESHOLD(h2c_pkt, thold); + SET_BCN_FILTER_OFFLOAD_P1_BCN_LOSS_CNT(h2c_pkt, BCN_LOSS_CNT); + SET_BCN_FILTER_OFFLOAD_P1_MACID(h2c_pkt, si->mac_id); + SET_BCN_FILTER_OFFLOAD_P1_HYST(h2c_pkt, hyst); + SET_BCN_FILTER_OFFLOAD_P1_BCN_INTERVAL(h2c_pkt, bss_conf->beacon_int); + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_pwr_mode(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_SET_PWR_MODE); + + SET_PWR_MODE_SET_MODE(h2c_pkt, conf->mode); + SET_PWR_MODE_SET_RLBM(h2c_pkt, conf->rlbm); + SET_PWR_MODE_SET_SMART_PS(h2c_pkt, conf->smart_ps); + SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_pkt, conf->awake_interval); + SET_PWR_MODE_SET_PORT_ID(h2c_pkt, conf->port_id); + SET_PWR_MODE_SET_PWR_STATE(h2c_pkt, conf->state); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_keep_alive_cmd(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + struct rtw_fw_wow_keep_alive_para mode = { + .adopt = true, + .pkt_type = KEEP_ALIVE_NULL_PKT, + .period = 5, + }; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_KEEP_ALIVE); + SET_KEEP_ALIVE_ENABLE(h2c_pkt, enable); + SET_KEEP_ALIVE_ADOPT(h2c_pkt, mode.adopt); + SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt, mode.pkt_type); + SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, mode.period); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + struct rtw_fw_wow_disconnect_para mode = { + .adopt = true, + .period = 30, + .retry_count = 5, + }; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_DISCONNECT_DECISION); + + if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { + SET_DISCONNECT_DECISION_ENABLE(h2c_pkt, enable); + SET_DISCONNECT_DECISION_ADOPT(h2c_pkt, mode.adopt); + SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt, mode.period); + SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt, mode.retry_count); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WOWLAN); + + SET_WOWLAN_FUNC_ENABLE(h2c_pkt, enable); + if (rtw_wow_mgd_linked(rtwdev)) { + if (test_bit(RTW_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) + SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt, enable); + if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) + SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt, enable); + if (test_bit(RTW_WOW_FLAG_EN_REKEY_PKT, rtw_wow->flags)) + SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt, enable); + if (rtw_wow->pattern_cnt) + SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt, enable); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev *rtwdev, + u8 pairwise_key_enc, + u8 group_key_enc) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_AOAC_GLOBAL_INFO); + + SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt, pairwise_key_enc); + SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt, group_key_enc); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_REMOTE_WAKE_CTRL); + + SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt, enable); + + if (rtw_wow_no_link(rtwdev)) + SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt, enable); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +static u8 rtw_get_rsvd_page_location(struct rtw_dev *rtwdev, + enum rtw_rsvd_packet_type type) +{ + struct rtw_rsvd_page *rsvd_pkt; + u8 location = 0; + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + if (type == rsvd_pkt->type) + location = rsvd_pkt->page; + } + + return location; +} + +void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 loc_nlo; + + loc_nlo = rtw_get_rsvd_page_location(rtwdev, RSVD_NLO_INFO); + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_NLO_INFO); + + SET_NLO_FUN_EN(h2c_pkt, enable); + if (enable) { + if (rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE) + SET_NLO_PS_32K(h2c_pkt, enable); + SET_NLO_IGNORE_SECURITY(h2c_pkt, enable); + SET_NLO_LOC_NLO_INFO(h2c_pkt, loc_nlo); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RECOVER_BT_DEV); + SET_RECOVER_BT_DEV_EN(h2c_pkt, 1); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_pg_info(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 loc_pg, loc_dpk; + + loc_pg = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_INFO); + loc_dpk = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_DPK); + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_LPS_PG_INFO); + + LPS_PG_INFO_LOC(h2c_pkt, loc_pg); + LPS_PG_DPK_LOC(h2c_pkt, loc_dpk); + LPS_PG_SEC_CAM_EN(h2c_pkt, conf->sec_cam_backup); + LPS_PG_PATTERN_CAM_EN(h2c_pkt, conf->pattern_cam_backup); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +static u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + u8 location = 0; + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + if (rsvd_pkt->type != RSVD_PROBE_REQ) + continue; + if ((!ssid && !rsvd_pkt->ssid) || + cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) + location = rsvd_pkt->page; + } + + return location; +} + +static u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + u16 size = 0; + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + if (rsvd_pkt->type != RSVD_PROBE_REQ) + continue; + if ((!ssid && !rsvd_pkt->ssid) || + cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) + size = rsvd_pkt->probe_req_size; + } + + return size; +} + +void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 location = 0; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSVD_PAGE); + + location = rtw_get_rsvd_page_location(rtwdev, RSVD_PROBE_RESP); + *(h2c_pkt + 1) = location; + rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_PROBE_RESP loc: %d\n", location); + + location = rtw_get_rsvd_page_location(rtwdev, RSVD_PS_POLL); + *(h2c_pkt + 2) = location; + rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_PS_POLL loc: %d\n", location); + + location = rtw_get_rsvd_page_location(rtwdev, RSVD_NULL); + *(h2c_pkt + 3) = location; + rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_NULL loc: %d\n", location); + + location = rtw_get_rsvd_page_location(rtwdev, RSVD_QOS_NULL); + *(h2c_pkt + 4) = location; + rtw_dbg(rtwdev, RTW_DBG_FW, "RSVD_QOS_NULL loc: %d\n", location); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +static struct sk_buff *rtw_nlo_info_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req; + struct rtw_nlo_info_hdr *nlo_hdr; + struct cfg80211_ssid *ssid; + struct sk_buff *skb; + u8 *pos, loc; + u32 size; + int i; + + if (!pno_req->inited || !pno_req->match_set_cnt) + return NULL; + + size = sizeof(struct rtw_nlo_info_hdr) + pno_req->match_set_cnt * + IEEE80211_MAX_SSID_LEN + chip->tx_pkt_desc_sz; + + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + + nlo_hdr = skb_put_zero(skb, sizeof(struct rtw_nlo_info_hdr)); + + nlo_hdr->nlo_count = pno_req->match_set_cnt; + nlo_hdr->hidden_ap_count = pno_req->match_set_cnt; + + /* pattern check for firmware */ + memset(nlo_hdr->pattern_check, 0xA5, FW_NLO_INFO_CHECK_SIZE); + + for (i = 0; i < pno_req->match_set_cnt; i++) + nlo_hdr->ssid_len[i] = pno_req->match_sets[i].ssid.ssid_len; + + for (i = 0; i < pno_req->match_set_cnt; i++) { + ssid = &pno_req->match_sets[i].ssid; + loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid); + if (!loc) { + rtw_err(rtwdev, "failed to get probe req rsvd loc\n"); + kfree_skb(skb); + return NULL; + } + nlo_hdr->location[i] = loc; + } + + for (i = 0; i < pno_req->match_set_cnt; i++) { + pos = skb_put_zero(skb, IEEE80211_MAX_SSID_LEN); + memcpy(pos, pno_req->match_sets[i].ssid.ssid, + pno_req->match_sets[i].ssid.ssid_len); + } + + return skb; +} + +static struct sk_buff *rtw_cs_channel_info_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req; + struct ieee80211_channel *channels = pno_req->channels; + struct sk_buff *skb; + int count = pno_req->channel_cnt; + u8 *pos; + int i = 0; + + skb = alloc_skb(4 * count + chip->tx_pkt_desc_sz, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + + for (i = 0; i < count; i++) { + pos = skb_put_zero(skb, 4); + + CHSW_INFO_SET_CH(pos, channels[i].hw_value); + + if (channels[i].flags & IEEE80211_CHAN_RADAR) + CHSW_INFO_SET_ACTION_ID(pos, 0); + else + CHSW_INFO_SET_ACTION_ID(pos, 1); + CHSW_INFO_SET_TIMEOUT(pos, 1); + CHSW_INFO_SET_PRI_CH_IDX(pos, 1); + CHSW_INFO_SET_BW(pos, 0); + } + + return skb; +} + +static struct sk_buff *rtw_lps_pg_dpk_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + struct rtw_lps_pg_dpk_hdr *dpk_hdr; + struct sk_buff *skb; + u32 size; + + size = chip->tx_pkt_desc_sz + sizeof(*dpk_hdr); + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + dpk_hdr = skb_put_zero(skb, sizeof(*dpk_hdr)); + dpk_hdr->dpk_ch = dpk_info->dpk_ch; + dpk_hdr->dpk_path_ok = dpk_info->dpk_path_ok[0]; + memcpy(dpk_hdr->dpk_txagc, dpk_info->dpk_txagc, 2); + memcpy(dpk_hdr->dpk_gs, dpk_info->dpk_gs, 4); + memcpy(dpk_hdr->coef, dpk_info->coef, 160); + + return skb; +} + +static struct sk_buff *rtw_lps_pg_info_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + struct rtw_lps_pg_info_hdr *pg_info_hdr; + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct sk_buff *skb; + u32 size; + + size = chip->tx_pkt_desc_sz + sizeof(*pg_info_hdr); + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + pg_info_hdr = skb_put_zero(skb, sizeof(*pg_info_hdr)); + pg_info_hdr->tx_bu_page_count = rtwdev->fifo.rsvd_drv_pg_num; + pg_info_hdr->macid = find_first_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); + pg_info_hdr->sec_cam_count = + rtw_sec_cam_pg_backup(rtwdev, pg_info_hdr->sec_cam); + pg_info_hdr->pattern_count = rtw_wow->pattern_cnt; + + conf->sec_cam_backup = pg_info_hdr->sec_cam_count != 0; + conf->pattern_cam_backup = rtw_wow->pattern_cnt != 0; + + return skb; +} + +static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, + struct rtw_rsvd_page *rsvd_pkt) +{ + struct ieee80211_vif *vif; + struct rtw_vif *rtwvif; + struct sk_buff *skb_new; + struct cfg80211_ssid *ssid; + u16 tim_offset = 0; + + if (rsvd_pkt->type == RSVD_DUMMY) { + skb_new = alloc_skb(1, GFP_KERNEL); + if (!skb_new) + return NULL; + + skb_put(skb_new, 1); + return skb_new; + } + + rtwvif = rsvd_pkt->rtwvif; + if (!rtwvif) + return NULL; + + vif = rtwvif_to_vif(rtwvif); + + switch (rsvd_pkt->type) { + case RSVD_BEACON: + skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL, 0); + rsvd_pkt->tim_offset = tim_offset; + break; + case RSVD_PS_POLL: + skb_new = ieee80211_pspoll_get(hw, vif); + break; + case RSVD_PROBE_RESP: + skb_new = ieee80211_proberesp_get(hw, vif); + break; + case RSVD_NULL: + skb_new = ieee80211_nullfunc_get(hw, vif, -1, false); + break; + case RSVD_QOS_NULL: + skb_new = ieee80211_nullfunc_get(hw, vif, -1, true); + break; + case RSVD_LPS_PG_DPK: + skb_new = rtw_lps_pg_dpk_get(hw); + break; + case RSVD_LPS_PG_INFO: + skb_new = rtw_lps_pg_info_get(hw); + break; + case RSVD_PROBE_REQ: + ssid = (struct cfg80211_ssid *)rsvd_pkt->ssid; + if (ssid) + skb_new = ieee80211_probereq_get(hw, vif->addr, + ssid->ssid, + ssid->ssid_len, 0); + else + skb_new = ieee80211_probereq_get(hw, vif->addr, NULL, 0, 0); + if (skb_new) + rsvd_pkt->probe_req_size = (u16)skb_new->len; + break; + case RSVD_NLO_INFO: + skb_new = rtw_nlo_info_get(hw); + break; + case RSVD_CH_INFO: + skb_new = rtw_cs_channel_info_get(hw); + break; + default: + return NULL; + } + + if (!skb_new) + return NULL; + + return skb_new; +} + +static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb, + enum rtw_rsvd_packet_type type) +{ + struct rtw_tx_pkt_info pkt_info = {0}; + const struct rtw_chip_info *chip = rtwdev->chip; + u8 *pkt_desc; + + rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type); + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); +} + +static inline u8 rtw_len_to_page(unsigned int len, u16 page_size) +{ + return DIV_ROUND_UP(len, page_size); +} + +static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size, + u16 page_margin, u32 page, u8 *buf, + struct rtw_rsvd_page *rsvd_pkt) +{ + struct sk_buff *skb = rsvd_pkt->skb; + + if (page >= 1) + memcpy(buf + page_margin + page_size * (page - 1), + skb->data, skb->len); + else + memcpy(buf, skb->data, skb->len); +} + +static struct rtw_rsvd_page *rtw_alloc_rsvd_page(struct rtw_dev *rtwdev, + enum rtw_rsvd_packet_type type, + bool txdesc) +{ + struct rtw_rsvd_page *rsvd_pkt = NULL; + + rsvd_pkt = kzalloc_obj(*rsvd_pkt); + + if (!rsvd_pkt) + return NULL; + + INIT_LIST_HEAD(&rsvd_pkt->vif_list); + INIT_LIST_HEAD(&rsvd_pkt->build_list); + rsvd_pkt->type = type; + rsvd_pkt->add_txdesc = txdesc; + + return rsvd_pkt; +} + +static void rtw_insert_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + struct rtw_rsvd_page *rsvd_pkt) +{ + lockdep_assert_held(&rtwdev->mutex); + + list_add_tail(&rsvd_pkt->vif_list, &rtwvif->rsvd_page_list); +} + +static void rtw_add_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + enum rtw_rsvd_packet_type type, + bool txdesc) +{ + struct rtw_rsvd_page *rsvd_pkt; + + rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, type, txdesc); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to alloc rsvd page %d\n", type); + return; + } + + rsvd_pkt->rtwvif = rtwvif; + rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt); +} + +static void rtw_add_rsvd_page_probe_req(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + + rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_PROBE_REQ, true); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to alloc probe req rsvd page\n"); + return; + } + + rsvd_pkt->rtwvif = rtwvif; + rsvd_pkt->ssid = ssid; + rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt); +} + +void rtw_remove_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct rtw_rsvd_page *rsvd_pkt, *tmp; + + lockdep_assert_held(&rtwdev->mutex); + + /* remove all of the rsvd pages for vif */ + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwvif->rsvd_page_list, + vif_list) { + list_del(&rsvd_pkt->vif_list); + if (!list_empty(&rsvd_pkt->build_list)) + list_del(&rsvd_pkt->build_list); + kfree(rsvd_pkt); + } +} + +void rtw_add_rsvd_page_bcn(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_ADHOC && + vif->type != NL80211_IFTYPE_MESH_POINT) { + rtw_warn(rtwdev, "Cannot add beacon rsvd page for %d\n", + vif->type); + return; + } + + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_BEACON, false); +} + +void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *rtw_pno_req = &rtw_wow->pno_req; + struct cfg80211_ssid *ssid; + int i; + + if (vif->type != NL80211_IFTYPE_STATION) { + rtw_warn(rtwdev, "Cannot add PNO rsvd page for %d\n", + vif->type); + return; + } + + for (i = 0 ; i < rtw_pno_req->match_set_cnt; i++) { + ssid = &rtw_pno_req->match_sets[i].ssid; + rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, ssid); + } + + rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, NULL); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NLO_INFO, false); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_CH_INFO, true); +} + +void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + + if (vif->type != NL80211_IFTYPE_STATION) { + rtw_warn(rtwdev, "Cannot add sta rsvd page for %d\n", + vif->type); + return; + } + + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_PS_POLL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_QOS_NULL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NULL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_DPK, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_INFO, true); +} + +int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, + u8 *buf, u32 size) +{ + u8 bckp[3]; + u8 val; + u16 rsvd_pg_head; + u32 bcn_valid_addr; + u32 bcn_valid_mask; + int ret; + + lockdep_assert_held(&rtwdev->mutex); + + if (!size) + return -EINVAL; + + bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL); + + if (rtw_chip_wcpu_8051(rtwdev)) { + rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); + } else { + pg_addr &= BIT_MASK_BCN_HEAD_1_V1; + pg_addr |= BIT_BCN_VALID_V1; + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr); + } + + val = rtw_read8(rtwdev, REG_CR + 1); + bckp[0] = val; + val |= BIT_ENSWBCN >> 8; + rtw_write8(rtwdev, REG_CR + 1, val); + + rtw_write8(rtwdev, REG_BCN_CTRL, + (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { + val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2); + bckp[1] = val; + val &= ~(BIT_EN_BCNQ_DL >> 16); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val); + } + + ret = rtw_hci_write_data_rsvd_page(rtwdev, buf, size); + if (ret) { + rtw_err(rtwdev, "failed to write data to rsvd page\n"); + goto restore; + } + + if (rtw_chip_wcpu_8051(rtwdev)) { + bcn_valid_addr = REG_DWBCN0_CTRL; + bcn_valid_mask = BIT_BCN_VALID; + } else { + bcn_valid_addr = REG_FIFOPAGE_CTRL_2; + bcn_valid_mask = BIT_BCN_VALID_V1; + } + + if (!check_hw_ready(rtwdev, bcn_valid_addr, bcn_valid_mask, 1)) { + rtw_err(rtwdev, "error beacon valid\n"); + ret = -EBUSY; + } + +restore: + rsvd_pg_head = rtwdev->fifo.rsvd_boundary; + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, + rsvd_pg_head | BIT_BCN_VALID_V1); + rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]); + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]); + rtw_write8(rtwdev, REG_CR + 1, bckp[0]); + + return ret; +} + +static int rtw_download_drv_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + u32 pg_size; + u32 pg_num = 0; + u16 pg_addr = 0; + + pg_size = rtwdev->chip->page_size; + pg_num = size / pg_size + ((size & (pg_size - 1)) ? 1 : 0); + if (pg_num > rtwdev->fifo.rsvd_drv_pg_num) + return -ENOMEM; + + pg_addr = rtwdev->fifo.rsvd_drv_addr; + + return rtw_fw_write_data_rsvd_page(rtwdev, pg_addr, buf, size); +} + +static void __rtw_build_rsvd_page_reset(struct rtw_dev *rtwdev) +{ + struct rtw_rsvd_page *rsvd_pkt, *tmp; + + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, + build_list) { + list_del_init(&rsvd_pkt->build_list); + + /* Don't free except for the dummy rsvd page, + * others will be freed when removing vif + */ + if (rsvd_pkt->type == RSVD_DUMMY) + kfree(rsvd_pkt); + } +} + +static void rtw_build_rsvd_page_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_rsvd_page *rsvd_pkt; + + /* AP not yet started, don't gather its rsvd pages */ + if (vif->type == NL80211_IFTYPE_AP && !rtwdev->ap_active) + return; + + list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { + if (rsvd_pkt->type == RSVD_BEACON) + list_add(&rsvd_pkt->build_list, + &rtwdev->rsvd_page_list); + else + list_add_tail(&rsvd_pkt->build_list, + &rtwdev->rsvd_page_list); + } +} + +static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev) +{ + struct rtw_rsvd_page *rsvd_pkt; + + __rtw_build_rsvd_page_reset(rtwdev); + + /* gather rsvd page from vifs */ + rtw_iterate_vifs_atomic(rtwdev, rtw_build_rsvd_page_iter, rtwdev); + + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, build_list); + if (!rsvd_pkt) { + WARN(1, "Should not have an empty reserved page\n"); + return -EINVAL; + } + + /* the first rsvd should be beacon, otherwise add a dummy one */ + if (rsvd_pkt->type != RSVD_BEACON) { + struct rtw_rsvd_page *dummy_pkt; + + dummy_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_DUMMY, false); + if (!dummy_pkt) { + rtw_err(rtwdev, "failed to alloc dummy rsvd page\n"); + return -ENOMEM; + } + + list_add(&dummy_pkt->build_list, &rtwdev->rsvd_page_list); + } + + return 0; +} + +static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_rsvd_page *rsvd_pkt; + struct sk_buff *iter; + u16 page_size, page_margin, tx_desc_sz; + u8 total_page = 0; + u32 page = 0; + u8 *buf; + int ret; + + page_size = chip->page_size; + tx_desc_sz = chip->tx_pkt_desc_sz; + page_margin = page_size - tx_desc_sz; + + ret = __rtw_build_rsvd_page_from_vifs(rtwdev); + if (ret) { + rtw_err(rtwdev, + "failed to build rsvd page from vifs, ret %d\n", ret); + return NULL; + } + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + iter = rtw_get_rsvd_page_skb(hw, rsvd_pkt); + if (!iter) { + rtw_err(rtwdev, "failed to build rsvd packet\n"); + goto release_skb; + } + + /* Fill the tx_desc for the rsvd pkt that requires one. + * And iter->len will be added with size of tx_desc_sz. + */ + if (rsvd_pkt->add_txdesc) + rtw_fill_rsvd_page_desc(rtwdev, iter, rsvd_pkt->type); + + rsvd_pkt->skb = iter; + rsvd_pkt->page = total_page; + + /* Reserved page is downloaded via TX path, and TX path will + * generate a tx_desc at the header to describe length of + * the buffer. If we are not counting page numbers with the + * size of tx_desc added at the first rsvd_pkt (usually a + * beacon, firmware default refer to the first page as the + * content of beacon), we could generate a buffer which size + * is smaller than the actual size of the whole rsvd_page + */ + if (total_page == 0) { + if (rsvd_pkt->type != RSVD_BEACON && + rsvd_pkt->type != RSVD_DUMMY) { + rtw_err(rtwdev, "first page should be a beacon\n"); + goto release_skb; + } + total_page += rtw_len_to_page(iter->len + tx_desc_sz, + page_size); + } else { + total_page += rtw_len_to_page(iter->len, page_size); + } + } + + if (total_page > rtwdev->fifo.rsvd_drv_pg_num) { + rtw_err(rtwdev, "rsvd page over size: %d\n", total_page); + goto release_skb; + } + + *size = (total_page - 1) * page_size + page_margin; + buf = kzalloc(*size, GFP_KERNEL); + if (!buf) + goto release_skb; + + /* Copy the content of each rsvd_pkt to the buf, and they should + * be aligned to the pages. + * + * Note that the first rsvd_pkt is a beacon no matter what vif->type. + * And that rsvd_pkt does not require tx_desc because when it goes + * through TX path, the TX path will generate one for it. + */ + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + rtw_rsvd_page_list_to_buf(rtwdev, page_size, page_margin, + page, buf, rsvd_pkt); + if (page == 0) + page += rtw_len_to_page(rsvd_pkt->skb->len + + tx_desc_sz, page_size); + else + page += rtw_len_to_page(rsvd_pkt->skb->len, page_size); + + kfree_skb(rsvd_pkt->skb); + rsvd_pkt->skb = NULL; + } + + return buf; + +release_skb: + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + kfree_skb(rsvd_pkt->skb); + rsvd_pkt->skb = NULL; + } + + return NULL; +} + +static int rtw_download_beacon(struct rtw_dev *rtwdev) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_rsvd_page *rsvd_pkt; + struct sk_buff *skb; + int ret = 0; + + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, build_list); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to get rsvd page from build list\n"); + return -ENOENT; + } + + if (rsvd_pkt->type != RSVD_BEACON && + rsvd_pkt->type != RSVD_DUMMY) { + rtw_err(rtwdev, "invalid rsvd page type %d, should be beacon or dummy\n", + rsvd_pkt->type); + return -EINVAL; + } + + skb = rtw_get_rsvd_page_skb(hw, rsvd_pkt); + if (!skb) { + rtw_err(rtwdev, "failed to get beacon skb\n"); + return -ENOMEM; + } + + ret = rtw_download_drv_rsvd_page(rtwdev, skb->data, skb->len); + if (ret) + rtw_err(rtwdev, "failed to download drv rsvd page\n"); + + dev_kfree_skb(skb); + + return ret; +} + +int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev) +{ + u8 *buf; + u32 size; + int ret; + + buf = rtw_build_rsvd_page(rtwdev, &size); + if (!buf) { + rtw_err(rtwdev, "failed to build rsvd page pkt\n"); + return -ENOMEM; + } + + ret = rtw_download_drv_rsvd_page(rtwdev, buf, size); + if (ret) { + rtw_err(rtwdev, "failed to download drv rsvd page\n"); + goto free; + } + + /* The last thing is to download the *ONLY* beacon again, because + * the previous tx_desc is to describe the total rsvd page. Download + * the beacon again to replace the TX desc header, and we will get + * a correct tx_desc for the beacon in the rsvd page. + */ + ret = rtw_download_beacon(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to download beacon\n"); + goto free; + } + +free: + kfree(buf); + + return ret; +} + +void rtw_fw_update_beacon_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + update_beacon_work); + + mutex_lock(&rtwdev->mutex); + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size, + u32 *buf, u32 residue, u16 start_pg) +{ + u32 i; + u16 idx = 0; + u16 ctl; + + ctl = rtw_read16(rtwdev, REG_PKTBUF_DBG_CTRL) & 0xf000; + /* disable rx clock gate */ + rtw_write32_set(rtwdev, REG_RCR, BIT_DISGCLK); + + do { + rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, start_pg | ctl); + + for (i = FIFO_DUMP_ADDR + residue; + i < FIFO_DUMP_ADDR + FIFO_PAGE_SIZE; i += 4) { + buf[idx++] = rtw_read32(rtwdev, i); + size -= 4; + if (size == 0) + goto out; + } + + residue = 0; + start_pg++; + } while (size); + +out: + rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, ctl); + /* restore rx clock gate */ + rtw_write32_clr(rtwdev, REG_RCR, BIT_DISGCLK); +} + +static void rtw_fw_read_fifo(struct rtw_dev *rtwdev, enum rtw_fw_fifo_sel sel, + u32 offset, u32 size, u32 *buf) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u32 start_pg, residue; + + if (sel >= RTW_FW_FIFO_MAX) { + rtw_dbg(rtwdev, RTW_DBG_FW, "wrong fw fifo sel\n"); + return; + } + if (sel == RTW_FW_FIFO_SEL_RSVD_PAGE) + offset += rtwdev->fifo.rsvd_boundary << TX_PAGE_SIZE_SHIFT; + residue = offset & (FIFO_PAGE_SIZE - 1); + start_pg = (offset >> FIFO_PAGE_SIZE_SHIFT) + chip->fw_fifo_addr[sel]; + + rtw_fw_read_fifo_page(rtwdev, offset, size, buf, residue, start_pg); +} + +static bool rtw_fw_dump_check_size(struct rtw_dev *rtwdev, + enum rtw_fw_fifo_sel sel, + u32 start_addr, u32 size) +{ + switch (sel) { + case RTW_FW_FIFO_SEL_TX: + case RTW_FW_FIFO_SEL_RX: + if ((start_addr + size) > rtwdev->chip->fw_fifo_addr[sel]) + return false; + fallthrough; + default: + return true; + } +} + +int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, + u32 *buffer) +{ + if (!rtwdev->chip->fw_fifo_addr[0]) { + rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n"); + return -ENOTSUPP; + } + + if (size == 0 || !buffer) + return -EINVAL; + + if (size & 0x3) { + rtw_dbg(rtwdev, RTW_DBG_FW, "not 4byte alignment\n"); + return -EINVAL; + } + + if (!rtw_fw_dump_check_size(rtwdev, fifo_sel, addr, size)) { + rtw_dbg(rtwdev, RTW_DBG_FW, "fw fifo dump size overflow\n"); + return -EINVAL; + } + + rtw_fw_read_fifo(rtwdev, fifo_sel, addr, size, buffer); + + return 0; +} + +static void __rtw_fw_update_pkt(struct rtw_dev *rtwdev, u8 pkt_id, u16 size, + u8 location) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_UPDATE_PKT_LEN; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_UPDATE_PKT); + + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + UPDATE_PKT_SET_PKT_ID(h2c_pkt, pkt_id); + UPDATE_PKT_SET_LOCATION(h2c_pkt, location); + + /* include txdesc size */ + size += chip->tx_pkt_desc_sz; + UPDATE_PKT_SET_SIZE(h2c_pkt, size); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + u8 loc; + u16 size; + + loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid); + if (!loc) { + rtw_err(rtwdev, "failed to get probe_req rsvd loc\n"); + return; + } + + size = rtw_get_rsvd_page_probe_req_size(rtwdev, ssid); + if (!size) { + rtw_err(rtwdev, "failed to get probe_req rsvd size\n"); + return; + } + + __rtw_fw_update_pkt(rtwdev, RTW_PACKET_PROBE_REQ, size, loc); +} + +void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_pno_request *rtw_pno_req = &rtwdev->wow.pno_req; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_CH_SWITCH_LEN; + u8 loc_ch_info; + const struct rtw_ch_switch_option cs_option = { + .dest_ch_en = 1, + .dest_ch = 1, + .periodic_option = 2, + .normal_period = 5, + .normal_period_sel = 0, + .normal_cycle = 10, + .slow_period = 1, + .slow_period_sel = 1, + }; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_CH_SWITCH); + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + + CH_SWITCH_SET_START(h2c_pkt, enable); + CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, cs_option.dest_ch_en); + CH_SWITCH_SET_DEST_CH(h2c_pkt, cs_option.dest_ch); + CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, cs_option.normal_period); + CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, cs_option.normal_period_sel); + CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, cs_option.slow_period); + CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, cs_option.slow_period_sel); + CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, cs_option.normal_cycle); + CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, cs_option.periodic_option); + + CH_SWITCH_SET_CH_NUM(h2c_pkt, rtw_pno_req->channel_cnt); + CH_SWITCH_SET_INFO_SIZE(h2c_pkt, rtw_pno_req->channel_cnt * 4); + + loc_ch_info = rtw_get_rsvd_page_location(rtwdev, RSVD_CH_INFO); + CH_SWITCH_SET_INFO_LOC(h2c_pkt, loc_ch_info); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void rtw_fw_adaptivity(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + if (!rtw_edcca_enabled) { + dm_info->edcca_mode = RTW_EDCCA_NORMAL; + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, + "EDCCA disabled by debugfs\n"); + } + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_ADAPTIVITY); + SET_ADAPTIVITY_MODE(h2c_pkt, dm_info->edcca_mode); + SET_ADAPTIVITY_OPTION(h2c_pkt, 1); + SET_ADAPTIVITY_IGI(h2c_pkt, dm_info->igi_history[0]); + SET_ADAPTIVITY_L2H(h2c_pkt, dm_info->l2h_th_ini); + SET_ADAPTIVITY_DENSITY(h2c_pkt, dm_info->scan_density); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_SCAN); + SET_SCAN_START(h2c_pkt, start); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +static int rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct sk_buff_head *list, u8 *bands, + struct rtw_vif *rtwvif) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct sk_buff *new; + u8 idx; + + for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { + if (!(BIT(idx) & chip->band)) + continue; + new = skb_copy(skb, GFP_KERNEL); + if (!new) + return -ENOMEM; + skb_put_data(new, ies->ies[idx], ies->len[idx]); + skb_put_data(new, ies->common_ies, ies->common_ie_len); + skb_queue_tail(list, new); + (*bands)++; + } + + return 0; +} + +static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes, + struct sk_buff_head *probe_req_list) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb, *tmp; + u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc; + u8 tx_desc_sz = chip->tx_pkt_desc_sz; + u16 page_size = chip->page_size; + u8 page_offset = 1, *buf; + u16 buf_offset = page_size * page_offset; + unsigned int pkt_len; + u8 page_cnt, pages; + int ret; + + if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM)) + page_cnt = RTW_OLD_PROBE_PG_CNT; + else + page_cnt = RTW_PROBE_PG_CNT; + + pages = page_offset + num_probes * page_cnt; + + buf = kzalloc(page_size * pages, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf_offset -= tx_desc_sz; + skb_queue_walk_safe(probe_req_list, skb, tmp) { + skb_unlink(skb, probe_req_list); + rtw_fill_rsvd_page_desc(rtwdev, skb, RSVD_PROBE_REQ); + if (skb->len > page_size * page_cnt) { + ret = -EINVAL; + goto out; + } + + memcpy(buf + buf_offset, skb->data, skb->len); + pkt_len = skb->len - tx_desc_sz; + loc = pg_addr - rtwdev->fifo.rsvd_boundary + page_offset; + __rtw_fw_update_pkt(rtwdev, RTW_PACKET_PROBE_REQ, pkt_len, loc); + + buf_offset += page_cnt * page_size; + page_offset += page_cnt; + kfree_skb(skb); + } + + ret = rtw_fw_write_data_rsvd_page(rtwdev, pg_addr, buf, buf_offset); + if (ret) { + rtw_err(rtwdev, "Download probe request to firmware failed\n"); + goto out; + } + + rtwdev->scan_info.probe_pg_size = page_offset; +out: + kfree(buf); + skb_queue_walk_safe(probe_req_list, skb, tmp) + kfree_skb(skb); + + return ret; +} + +static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct sk_buff_head list; + struct sk_buff *skb, *tmp; + u8 num = req->n_ssids, i, bands = 0; + int ret; + + skb_queue_head_init(&list); + for (i = 0; i < num; i++) { + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, + req->ssids[i].ssid, + req->ssids[i].ssid_len, + req->ie_len); + if (!skb) { + ret = -ENOMEM; + goto out; + } + ret = rtw_append_probe_req_ie(rtwdev, skb, &list, &bands, + rtwvif); + if (ret) + goto out; + + kfree_skb(skb); + } + + return _rtw_hw_scan_update_probe_req(rtwdev, num * bands, &list); + +out: + skb_queue_walk_safe(&list, skb, tmp) + kfree_skb(skb); + + return ret; +} + +static int rtw_add_chan_info(struct rtw_dev *rtwdev, struct rtw_chan_info *info, + struct rtw_chan_list *list, u8 *buf) +{ + u8 *chan = &buf[list->size]; + u8 info_size = RTW_CH_INFO_SIZE; + + if (list->size > list->buf_size) + return -ENOMEM; + + CH_INFO_SET_CH(chan, info->channel); + CH_INFO_SET_PRI_CH_IDX(chan, info->pri_ch_idx); + CH_INFO_SET_BW(chan, info->bw); + CH_INFO_SET_TIMEOUT(chan, info->timeout); + CH_INFO_SET_ACTION_ID(chan, info->action_id); + CH_INFO_SET_EXTRA_INFO(chan, info->extra_info); + if (info->extra_info) { + EXTRA_CH_INFO_SET_ID(chan, RTW_SCAN_EXTRA_ID_DFS); + EXTRA_CH_INFO_SET_INFO(chan, RTW_SCAN_EXTRA_ACTION_SCAN); + EXTRA_CH_INFO_SET_SIZE(chan, RTW_EX_CH_INFO_SIZE - + RTW_EX_CH_INFO_HDR_SIZE); + EXTRA_CH_INFO_SET_DFS_EXT_TIME(chan, RTW_DFS_CHAN_TIME); + info_size += RTW_EX_CH_INFO_SIZE; + } + list->size += info_size; + list->ch_num++; + + return 0; +} + +static int rtw_add_chan_list(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + struct rtw_chan_list *list, u8 *buf) +{ + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + struct ieee80211_channel *channel; + int i, ret = 0; + + for (i = 0; i < req->n_channels; i++) { + struct rtw_chan_info ch_info = {0}; + + channel = req->channels[i]; + ch_info.channel = channel->hw_value; + ch_info.bw = RTW_SCAN_WIDTH; + ch_info.pri_ch_idx = RTW_PRI_CH_IDX; + ch_info.timeout = req->duration_mandatory ? + req->duration : RTW_CHANNEL_TIME; + + if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) { + ch_info.action_id = RTW_CHANNEL_RADAR; + ch_info.extra_info = 1; + /* Overwrite duration for passive scans if necessary */ + ch_info.timeout = ch_info.timeout > RTW_PASS_CHAN_TIME ? + ch_info.timeout : RTW_PASS_CHAN_TIME; + } else { + ch_info.action_id = RTW_CHANNEL_ACTIVE; + } + + ret = rtw_add_chan_info(rtwdev, &ch_info, list, buf); + if (ret) + return ret; + } + + if (list->size > fifo->rsvd_pg_num << TX_PAGE_SIZE_SHIFT) { + rtw_err(rtwdev, "List exceeds rsvd page total size\n"); + return -EINVAL; + } + + list->addr = fifo->rsvd_h2c_info_addr + rtwdev->scan_info.probe_pg_size; + ret = rtw_fw_write_data_rsvd_page(rtwdev, list->addr, buf, list->size); + if (ret) + rtw_err(rtwdev, "Download channel list failed\n"); + + return ret; +} + +static void rtw_fw_set_scan_offload(struct rtw_dev *rtwdev, + struct rtw_ch_switch_option *opt, + struct rtw_vif *rtwvif, + struct rtw_chan_list *list) +{ + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + /* reserve one dummy page at the beginning for tx descriptor */ + u8 pkt_loc = fifo->rsvd_h2c_info_addr - fifo->rsvd_boundary + 1; + bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_SCAN_OFFLOAD); + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, H2C_PKT_CH_SWITCH_LEN); + + SCAN_OFFLOAD_SET_START(h2c_pkt, opt->switch_en); + SCAN_OFFLOAD_SET_BACK_OP_EN(h2c_pkt, opt->back_op_en); + SCAN_OFFLOAD_SET_RANDOM_SEQ_EN(h2c_pkt, random_seq); + SCAN_OFFLOAD_SET_NO_CCK_EN(h2c_pkt, req->no_cck); + SCAN_OFFLOAD_SET_CH_NUM(h2c_pkt, list->ch_num); + SCAN_OFFLOAD_SET_CH_INFO_SIZE(h2c_pkt, list->size); + SCAN_OFFLOAD_SET_CH_INFO_LOC(h2c_pkt, list->addr - fifo->rsvd_boundary); + SCAN_OFFLOAD_SET_OP_CH(h2c_pkt, scan_info->op_chan); + SCAN_OFFLOAD_SET_OP_PRI_CH_IDX(h2c_pkt, scan_info->op_pri_ch_idx); + SCAN_OFFLOAD_SET_OP_BW(h2c_pkt, scan_info->op_bw); + SCAN_OFFLOAD_SET_OP_PORT_ID(h2c_pkt, rtwvif->port); + SCAN_OFFLOAD_SET_OP_DWELL_TIME(h2c_pkt, req->duration_mandatory ? + req->duration : RTW_CHANNEL_TIME); + SCAN_OFFLOAD_SET_OP_GAP_TIME(h2c_pkt, RTW_OFF_CHAN_TIME); + SCAN_OFFLOAD_SET_SSID_NUM(h2c_pkt, req->n_ssids); + SCAN_OFFLOAD_SET_PKT_LOC(h2c_pkt, pkt_loc); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void rtw_hw_scan_start(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_scan_request *scan_req) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct cfg80211_scan_request *req = &scan_req->req; + u8 mac_addr[ETH_ALEN]; + + rtwdev->scan_info.scanning_vif = vif; + rtwvif->scan_ies = &scan_req->ies; + rtwvif->scan_req = req; + + ieee80211_stop_queues(rtwdev->hw); + rtw_leave_lps_deep(rtwdev); + rtw_hci_flush_all_queues(rtwdev, false); + rtw_mac_flush_all_queues(rtwdev, false); + if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) + get_random_mask_addr(mac_addr, req->mac_addr, + req->mac_addr_mask); + else + ether_addr_copy(mac_addr, vif->addr); + + rtw_core_scan_start(rtwdev, rtwvif, mac_addr, true); + + rtwdev->hal.rcr &= ~BIT_CBSSID_BCN; + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); +} + +void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool aborted) +{ + struct cfg80211_scan_info info = { + .aborted = aborted, + }; + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_vif *rtwvif; + u8 chan = scan_info->op_chan; + + if (!vif) + return; + + rtwdev->hal.rcr |= BIT_CBSSID_BCN; + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); + + rtw_core_scan_complete(rtwdev, vif, true); + + rtwvif = (struct rtw_vif *)vif->drv_priv; + if (chan) + rtw_store_op_chan(rtwdev, false); + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); + ieee80211_wake_queues(rtwdev->hw); + ieee80211_scan_completed(rtwdev->hw, &info); + + rtwvif->scan_req = NULL; + rtwvif->scan_ies = NULL; + rtwdev->scan_info.scanning_vif = NULL; +} + +static int rtw_hw_scan_prehandle(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + struct rtw_chan_list *list) +{ + struct cfg80211_scan_request *req = rtwvif->scan_req; + int size = req->n_channels * (RTW_CH_INFO_SIZE + RTW_EX_CH_INFO_SIZE); + u8 *buf; + int ret; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = rtw_hw_scan_update_probe_req(rtwdev, rtwvif); + if (ret) { + rtw_err(rtwdev, "Update probe request failed\n"); + goto out; + } + + list->buf_size = size; + list->size = 0; + list->ch_num = 0; + ret = rtw_add_chan_list(rtwdev, rtwvif, list, buf); +out: + kfree(buf); + + return ret; +} + +int rtw_hw_scan_offload(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool enable) +{ + struct rtw_vif *rtwvif = vif ? (struct rtw_vif *)vif->drv_priv : NULL; + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw_ch_switch_option cs_option = {0}; + struct rtw_chan_list chan_list = {0}; + int ret = 0; + + if (!rtwvif) + return -EINVAL; + + cs_option.switch_en = enable; + cs_option.back_op_en = scan_info->op_chan != 0; + if (enable) { + ret = rtw_hw_scan_prehandle(rtwdev, rtwvif, &chan_list); + if (ret) + goto out; + } + rtw_fw_set_scan_offload(rtwdev, &cs_option, rtwvif, &chan_list); +out: + if (rtwdev->ap_active) { + ret = rtw_download_beacon(rtwdev); + if (ret) + rtw_err(rtwdev, "HW scan download beacon failed\n"); + } + + return ret; +} + +void rtw_hw_scan_abort(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) + return; + + rtw_hw_scan_offload(rtwdev, vif, false); + rtw_hw_scan_complete(rtwdev, vif, true); +} + +void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb) +{ + struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; + struct rtw_c2h_cmd *c2h; + bool aborted; + u8 rc; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + return; + + c2h = get_c2h_from_skb(skb); + rc = GET_SCAN_REPORT_RETURN_CODE(c2h->payload); + aborted = rc != RTW_SCAN_REPORT_SUCCESS; + rtw_hw_scan_complete(rtwdev, vif, aborted); + + if (aborted) + rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, "HW scan aborted with code: %d\n", rc); +} + +void rtw_store_op_chan(struct rtw_dev *rtwdev, bool backup) +{ + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw_hal *hal = &rtwdev->hal; + u8 band; + + if (backup) { + scan_info->op_chan = hal->current_channel; + scan_info->op_bw = hal->current_band_width; + scan_info->op_pri_ch_idx = hal->current_primary_channel_index; + scan_info->op_pri_ch = hal->primary_channel; + } else { + band = scan_info->op_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; + rtw_update_channel(rtwdev, scan_info->op_chan, + scan_info->op_pri_ch, + band, scan_info->op_bw); + } +} + +void rtw_clear_op_chan(struct rtw_dev *rtwdev) +{ + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + + scan_info->op_chan = 0; + scan_info->op_bw = 0; + scan_info->op_pri_ch_idx = 0; + scan_info->op_pri_ch = 0; +} + +static bool rtw_is_op_chan(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + + return channel == scan_info->op_chan; +} + +void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_c2h_cmd *c2h; + enum rtw_scan_notify_id id; + u8 chan, band, status; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + return; + + c2h = get_c2h_from_skb(skb); + chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload); + id = GET_CHAN_SWITCH_ID(c2h->payload); + status = GET_CHAN_SWITCH_STATUS(c2h->payload); + + if (id == RTW_SCAN_NOTIFY_ID_POSTSWITCH) { + band = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; + rtw_update_channel(rtwdev, chan, chan, band, + RTW_CHANNEL_WIDTH_20); + if (rtw_is_op_chan(rtwdev, chan)) { + rtw_store_op_chan(rtwdev, false); + ieee80211_wake_queues(rtwdev->hw); + rtw_core_enable_beacon(rtwdev, true); + } + } else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) { + if (IS_CH_5G_BAND(chan)) { + rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G); + } else if (IS_CH_2G_BAND(chan)) { + u8 chan_type; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + chan_type = COEX_SWITCH_TO_24G; + else + chan_type = COEX_SWITCH_TO_24G_NOFORSCAN; + rtw_coex_switchband_notify(rtwdev, chan_type); + } + /* The channel of C2H RTW_SCAN_NOTIFY_ID_PRESWITCH is next + * channel that hardware will switch. We need to stop queue + * if next channel is non-op channel. + */ + if (!rtw_is_op_chan(rtwdev, chan) && + rtw_is_op_chan(rtwdev, hal->current_channel)) { + rtw_core_enable_beacon(rtwdev, false); + ieee80211_stop_queues(rtwdev->hw); + } + } + + rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, + "Chan switch: %x, id: %x, status: %x\n", chan, id, status); +} diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h new file mode 100644 index 000000000..48ad9ceab --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -0,0 +1,900 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_FW_H_ +#define __RTW_FW_H_ + +#define H2C_PKT_SIZE 32 +#define H2C_PKT_HDR_SIZE 8 + +/* FW bin information */ +#define FW_HDR_SIZE 64 +#define FW_HDR_CHKSUM_SIZE 8 + +#define FW_NLO_INFO_CHECK_SIZE 4 + +#define FIFO_PAGE_SIZE_SHIFT 12 +#define FIFO_PAGE_SIZE 4096 +#define FIFO_DUMP_ADDR 0x8000 + +#define DLFW_PAGE_SIZE_SHIFT_LEGACY 12 +#define DLFW_PAGE_SIZE_LEGACY 0x1000 +#define DLFW_BLK_SIZE_SHIFT_LEGACY 2 +#define DLFW_BLK_SIZE_LEGACY 4 +#define FW_START_ADDR_LEGACY 0x1000 + +#define BCN_LOSS_CNT 10 +#define BCN_FILTER_NOTIFY_SIGNAL_CHANGE 0 +#define BCN_FILTER_CONNECTION_LOSS 1 +#define BCN_FILTER_CONNECTED 2 +#define BCN_FILTER_NOTIFY_BEACON_LOSS 3 +#define RTW_DEFAULT_CQM_THOLD -70 +#define RTW_DEFAULT_CQM_HYST 4 + +#define SCAN_NOTIFY_TIMEOUT msecs_to_jiffies(10) + +#define RTW_CHANNEL_TIME 45 +#define RTW_OFF_CHAN_TIME 100 +#define RTW_PASS_CHAN_TIME 105 +#define RTW_DFS_CHAN_TIME 20 +#define RTW_CH_INFO_SIZE 4 +#define RTW_EX_CH_INFO_SIZE 3 +#define RTW_EX_CH_INFO_HDR_SIZE 2 +#define RTW_SCAN_WIDTH 0 +#define RTW_PRI_CH_IDX 1 +#define RTW_OLD_PROBE_PG_CNT 2 +#define RTW_PROBE_PG_CNT 4 + +#define RTW_DEBUG_DUMP_TIMES 10 + +enum rtw_c2h_cmd_id { + C2H_CCX_TX_RPT = 0x03, + C2H_BT_INFO = 0x09, + C2H_BT_MP_INFO = 0x0b, + C2H_BT_HID_INFO = 0x45, + C2H_RA_RPT = 0x0c, + C2H_HW_FEATURE_REPORT = 0x19, + C2H_WLAN_INFO = 0x27, + C2H_WLAN_RFON = 0x32, + C2H_BCN_FILTER_NOTIFY = 0x36, + C2H_ADAPTIVITY = 0x37, + C2H_SCAN_RESULT = 0x38, + C2H_HW_FEATURE_DUMP = 0xfd, + C2H_HALMAC = 0xff, +}; + +enum rtw_c2h_cmd_id_ext { + C2H_SCAN_STATUS_RPT = 0x3, + C2H_CCX_RPT = 0x0f, + C2H_CHAN_SWITCH = 0x22, +}; + +struct rtw_c2h_cmd { + u8 id; + u8 seq; + u8 payload[]; +} __packed; + +struct rtw_c2h_adaptivity { + u8 density; + u8 igi; + u8 l2h_th_init; + u8 l2h; + u8 h2l; + u8 option; +} __packed; + +struct rtw_c2h_ra_rpt { + u8 rate_sgi; + u8 mac_id; + u8 byte2; + u8 status; + u8 byte4; + u8 ra_ratio; + u8 bw; +} __packed; + +#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0) +#define RTW_C2H_RA_RPT_SGI BIT(7) + +struct rtw_h2c_register { + u32 w0; + u32 w1; +} __packed; + +#define RTW_H2C_W0_CMDID GENMASK(7, 0) + +/* H2C_CMD_DEFAULT_PORT command */ +#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) +#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) + +struct rtw_h2c_cmd { + __le32 msg; + __le32 msg_ext; +} __packed; + +enum rtw_rsvd_packet_type { + RSVD_BEACON, + RSVD_DUMMY, + RSVD_PS_POLL, + RSVD_PROBE_RESP, + RSVD_NULL, + RSVD_QOS_NULL, + RSVD_LPS_PG_DPK, + RSVD_LPS_PG_INFO, + RSVD_PROBE_REQ, + RSVD_NLO_INFO, + RSVD_CH_INFO, +}; + +enum rtw_fw_rf_type { + FW_RF_1T2R = 0, + FW_RF_2T4R = 1, + FW_RF_2T2R = 2, + FW_RF_2T3R = 3, + FW_RF_1T1R = 4, + FW_RF_2T2R_GREEN = 5, + FW_RF_3T3R = 6, + FW_RF_3T4R = 7, + FW_RF_4T4R = 8, + FW_RF_MAX_TYPE = 0xF, +}; + +enum rtw_fw_feature { + FW_FEATURE_SIG = BIT(0), + FW_FEATURE_LPS_C2H = BIT(1), + FW_FEATURE_LCLK = BIT(2), + FW_FEATURE_PG = BIT(3), + FW_FEATURE_TX_WAKE = BIT(4), + FW_FEATURE_BCN_FILTER = BIT(5), + FW_FEATURE_NOTIFY_SCAN = BIT(6), + FW_FEATURE_ADAPTIVITY = BIT(7), + FW_FEATURE_SCAN_OFFLOAD = BIT(8), + FW_FEATURE_MAX = BIT(31), +}; + +enum rtw_fw_feature_ext { + FW_FEATURE_EXT_OLD_PAGE_NUM = BIT(0), +}; + +enum rtw_beacon_filter_offload_mode { + BCN_FILTER_OFFLOAD_MODE_0 = 0, + BCN_FILTER_OFFLOAD_MODE_1, + BCN_FILTER_OFFLOAD_MODE_2, + BCN_FILTER_OFFLOAD_MODE_3, + + BCN_FILTER_OFFLOAD_MODE_DEFAULT = BCN_FILTER_OFFLOAD_MODE_0, +}; + +struct rtw_coex_info_req { + u8 seq; + u8 op_code; + u8 para1; + u8 para2; + u8 para3; +}; + +struct rtw_iqk_para { + u8 clear; + u8 segment_iqk; +}; + +struct rtw_lps_pg_dpk_hdr { + u16 dpk_path_ok; + u8 dpk_txagc[2]; + u16 dpk_gs[2]; + u32 coef[2][20]; + u8 dpk_ch; +} __packed; + +struct rtw_lps_pg_info_hdr { + u8 macid; + u8 mbssid; + u8 pattern_count; + u8 mu_tab_group_id; + u8 sec_cam_count; + u8 tx_bu_page_count; + u16 rsvd; + u8 sec_cam[MAX_PG_CAM_BACKUP_NUM]; +} __packed; + +struct rtw_rsvd_page { + /* associated with each vif */ + struct list_head vif_list; + struct rtw_vif *rtwvif; + + /* associated when build rsvd page */ + struct list_head build_list; + + struct sk_buff *skb; + enum rtw_rsvd_packet_type type; + u8 page; + u16 tim_offset; + bool add_txdesc; + struct cfg80211_ssid *ssid; + u16 probe_req_size; +}; + +enum rtw_keep_alive_pkt_type { + KEEP_ALIVE_NULL_PKT = 0, + KEEP_ALIVE_ARP_RSP = 1, +}; + +struct rtw_nlo_info_hdr { + u8 nlo_count; + u8 hidden_ap_count; + u8 rsvd1[2]; + u8 pattern_check[FW_NLO_INFO_CHECK_SIZE]; + u8 rsvd2[8]; + u8 ssid_len[16]; + u8 chiper[16]; + u8 rsvd3[16]; + u8 location[8]; +} __packed; + +enum rtw_packet_type { + RTW_PACKET_PROBE_REQ = 0x00, + + RTW_PACKET_UNDEFINE = 0x7FFFFFFF, +}; + +struct rtw_fw_wow_keep_alive_para { + bool adopt; + u8 pkt_type; + u8 period; /* unit: sec */ +}; + +struct rtw_fw_wow_disconnect_para { + bool adopt; + u8 period; /* unit: sec */ + u8 retry_count; +}; + +enum rtw_channel_type { + RTW_CHANNEL_PASSIVE, + RTW_CHANNEL_ACTIVE, + RTW_CHANNEL_RADAR, +}; + +enum rtw_scan_extra_id { + RTW_SCAN_EXTRA_ID_DFS, +}; + +enum rtw_scan_extra_info { + RTW_SCAN_EXTRA_ACTION_SCAN, +}; + +enum rtw_scan_report_code { + RTW_SCAN_REPORT_SUCCESS = 0x00, + RTW_SCAN_REPORT_ERR_PHYDM = 0x01, + RTW_SCAN_REPORT_ERR_ID = 0x02, + RTW_SCAN_REPORT_ERR_TX = 0x03, + RTW_SCAN_REPORT_CANCELED = 0x10, + RTW_SCAN_REPORT_CANCELED_EXT = 0x11, + RTW_SCAN_REPORT_FW_DISABLED = 0xF0, +}; + +enum rtw_scan_notify_id { + RTW_SCAN_NOTIFY_ID_PRESWITCH = 0x00, + RTW_SCAN_NOTIFY_ID_POSTSWITCH = 0x01, + RTW_SCAN_NOTIFY_ID_PROBE_PRETX = 0x02, + RTW_SCAN_NOTIFY_ID_PROBE_ISSUETX = 0x03, + RTW_SCAN_NOTIFY_ID_NULL0_PRETX = 0x04, + RTW_SCAN_NOTIFY_ID_NULL0_ISSUETX = 0x05, + RTW_SCAN_NOTIFY_ID_NULL0_POSTTX = 0x06, + RTW_SCAN_NOTIFY_ID_NULL1_PRETX = 0x07, + RTW_SCAN_NOTIFY_ID_NULL1_ISSUETX = 0x08, + RTW_SCAN_NOTIFY_ID_NULL1_POSTTX = 0x09, + RTW_SCAN_NOTIFY_ID_DWELLEXT = 0x0A, +}; + +enum rtw_scan_notify_status { + RTW_SCAN_NOTIFY_STATUS_SUCCESS = 0x00, + RTW_SCAN_NOTIFY_STATUS_FAILURE = 0x01, + RTW_SCAN_NOTIFY_STATUS_RESOURCE = 0x02, + RTW_SCAN_NOTIFY_STATUS_TIMEOUT = 0x03, +}; + +struct rtw_ch_switch_option { + u8 periodic_option; + u32 tsf_high; + u32 tsf_low; + u8 dest_ch_en; + u8 absolute_time_en; + u8 dest_ch; + u8 normal_period; + u8 normal_period_sel; + u8 normal_cycle; + u8 slow_period; + u8 slow_period_sel; + u8 nlo_en; + bool switch_en; + bool back_op_en; +}; + +struct rtw_fw_hdr { + __le16 signature; + u8 category; + u8 function; + __le16 version; /* 0x04 */ + u8 subversion; + u8 subindex; + __le32 rsvd; /* 0x08 */ + __le32 feature; /* 0x0C */ + u8 month; /* 0x10 */ + u8 day; + u8 hour; + u8 min; + __le16 year; /* 0x14 */ + __le16 rsvd3; + u8 mem_usage; /* 0x18 */ + u8 rsvd4[3]; + __le16 h2c_fmt_ver; /* 0x1C */ + __le16 rsvd5; + __le32 dmem_addr; /* 0x20 */ + __le32 dmem_size; + __le32 rsvd6; + __le32 rsvd7; + __le32 imem_size; /* 0x30 */ + __le32 emem_size; + __le32 emem_addr; + __le32 imem_addr; +} __packed; + +struct rtw_fw_hdr_legacy { + __le16 signature; + u8 category; + u8 function; + __le16 version; /* 0x04 */ + u8 subversion1; + u8 subversion2; + u8 month; /* 0x08 */ + u8 day; + u8 hour; + u8 minute; + __le16 size; + __le16 rsvd2; + __le32 idx; /* 0x10 */ + __le32 rsvd3; + __le32 rsvd4; /* 0x18 */ + __le32 rsvd5; +} __packed; + +#define RTW_FW_VER_CODE(ver, sub_ver, idx) \ + (((ver) << 16) | ((sub_ver) << 8) | (idx)) +#define RTW_FW_SUIT_VER_CODE(s) \ + RTW_FW_VER_CODE((s).version, (s).sub_version, (s).sub_index) + +/* C2H */ +#define GET_CCX_REPORT_SEQNUM_V0(c2h_payload) (c2h_payload[6] & 0xfc) +#define GET_CCX_REPORT_STATUS_V0(c2h_payload) (c2h_payload[0] & 0xc0) +#define GET_CCX_REPORT_SEQNUM_V1(c2h_payload) (c2h_payload[8] & 0xfc) +#define GET_CCX_REPORT_STATUS_V1(c2h_payload) (c2h_payload[9] & 0xc0) + +#define GET_SCAN_REPORT_RETURN_CODE(c2h_payload) (c2h_payload[2] & 0xff) + +#define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2]) +#define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3]) +#define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4]) + +#define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf) +#define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10) +#define GET_BCN_FILTER_NOTIFY_RSSI(c2h_payload) (c2h_payload[2] - 100) + +/* PKT H2C */ +#define H2C_PKT_CMD_ID 0xFF +#define H2C_PKT_CATEGORY 0x01 + +#define H2C_PKT_GENERAL_INFO 0x0D +#define H2C_PKT_PHYDM_INFO 0x11 +#define H2C_PKT_IQK 0x0E + +#define H2C_PKT_CH_SWITCH 0x02 +#define H2C_PKT_UPDATE_PKT 0x0C +#define H2C_PKT_SCAN_OFFLOAD 0x19 + +#define H2C_PKT_CH_SWITCH_LEN 0x20 +#define H2C_PKT_UPDATE_PKT_LEN 0x4 + +#define SET_PKT_H2C_CATEGORY(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(6, 0)) +#define SET_PKT_H2C_CMD_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_PKT_H2C_SUB_CMD_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 16)) +#define SET_PKT_H2C_TOTAL_LEN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 0)) + +static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id) +{ + SET_PKT_H2C_CATEGORY(h2c_pkt, H2C_PKT_CATEGORY); + SET_PKT_H2C_CMD_ID(h2c_pkt, H2C_PKT_CMD_ID); + SET_PKT_H2C_SUB_CMD_ID(h2c_pkt, sub_id); +} + +#define FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(31, 16)) +#define GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) + +#define PHYDM_INFO_SET_REF_TYPE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(7, 0)) +#define PHYDM_INFO_SET_RF_TYPE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 8)) +#define PHYDM_INFO_SET_CUT_VER(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) +#define PHYDM_INFO_SET_RX_ANT_STATUS(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(27, 24)) +#define PHYDM_INFO_SET_TX_ANT_STATUS(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(31, 28)) +#define IQK_SET_CLEAR(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(0)) +#define IQK_SET_SEGMENT_IQK(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(1)) + +#define CHSW_INFO_SET_CH(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(7, 0)) +#define CHSW_INFO_SET_PRI_CH_IDX(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(11, 8)) +#define CHSW_INFO_SET_BW(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(15, 12)) +#define CHSW_INFO_SET_TIMEOUT(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(23, 16)) +#define CHSW_INFO_SET_ACTION_ID(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(30, 24)) +#define CHSW_INFO_SET_EXTRA_INFO(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, BIT(31)) + +#define CH_INFO_SET_CH(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x00, value, GENMASK(7, 0)) +#define CH_INFO_SET_PRI_CH_IDX(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x01, value, GENMASK(3, 0)) +#define CH_INFO_SET_BW(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x01, value, GENMASK(7, 4)) +#define CH_INFO_SET_TIMEOUT(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x02, value, GENMASK(7, 0)) +#define CH_INFO_SET_ACTION_ID(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x03, value, GENMASK(6, 0)) +#define CH_INFO_SET_EXTRA_INFO(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x03, value, BIT(7)) + +#define EXTRA_CH_INFO_SET_ID(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x04, value, GENMASK(6, 0)) +#define EXTRA_CH_INFO_SET_INFO(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x04, value, BIT(7)) +#define EXTRA_CH_INFO_SET_SIZE(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x05, value, GENMASK(7, 0)) +#define EXTRA_CH_INFO_SET_DFS_EXT_TIME(pkt, value) \ + u8p_replace_bits((u8 *)(pkt) + 0x06, value, GENMASK(7, 0)) + +#define UPDATE_PKT_SET_SIZE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 0)) +#define UPDATE_PKT_SET_PKT_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) +#define UPDATE_PKT_SET_LOCATION(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(31, 24)) + +#define CH_SWITCH_SET_START(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(0)) +#define CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(1)) +#define CH_SWITCH_SET_ABSOLUTE_TIME(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(2)) +#define CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(4, 3)) +#define CH_SWITCH_SET_SCAN_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(5)) +#define CH_SWITCH_SET_BACK_OP_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(6)) +#define CH_SWITCH_SET_INFO_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 8)) +#define CH_SWITCH_SET_CH_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) +#define CH_SWITCH_SET_PRI_CH_IDX(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(27, 24)) +#define CH_SWITCH_SET_DEST_BW(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(31, 28)) +#define CH_SWITCH_SET_DEST_CH(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(7, 0)) +#define CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(13, 8)) +#define CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(15, 14)) +#define CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(21, 16)) +#define CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(23, 22)) +#define CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(31, 24)) +#define CH_SWITCH_SET_TSF_HIGH(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x04, value, GENMASK(31, 0)) +#define CH_SWITCH_SET_TSF_LOW(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x05, value, GENMASK(31, 0)) +#define CH_SWITCH_SET_INFO_SIZE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x06, value, GENMASK(15, 0)) + +#define SCAN_OFFLOAD_SET_START(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(0)) +#define SCAN_OFFLOAD_SET_BACK_OP_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(1)) +#define SCAN_OFFLOAD_SET_RANDOM_SEQ_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(2)) +#define SCAN_OFFLOAD_SET_NO_CCK_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(3)) +#define SCAN_OFFLOAD_SET_VERBOSE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(4)) +#define SCAN_OFFLOAD_SET_CH_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 8)) +#define SCAN_OFFLOAD_SET_CH_INFO_SIZE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(31, 16)) +#define SCAN_OFFLOAD_SET_CH_INFO_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(7, 0)) +#define SCAN_OFFLOAD_SET_OP_CH(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(15, 8)) +#define SCAN_OFFLOAD_SET_OP_PRI_CH_IDX(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(19, 16)) +#define SCAN_OFFLOAD_SET_OP_BW(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(23, 20)) +#define SCAN_OFFLOAD_SET_OP_PORT_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(26, 24)) +#define SCAN_OFFLOAD_SET_OP_DWELL_TIME(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x04, value, GENMASK(15, 0)) +#define SCAN_OFFLOAD_SET_OP_GAP_TIME(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x04, value, GENMASK(31, 16)) +#define SCAN_OFFLOAD_SET_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x05, value, GENMASK(3, 0)) +#define SCAN_OFFLOAD_SET_SSID_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x05, value, GENMASK(7, 4)) +#define SCAN_OFFLOAD_SET_PKT_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x05, value, GENMASK(15, 8)) + +/* Command H2C */ +#define H2C_CMD_RSVD_PAGE 0x0 +#define H2C_CMD_MEDIA_STATUS_RPT 0x01 +#define H2C_CMD_SET_PWR_MODE 0x20 +#define H2C_CMD_LPS_PG_INFO 0x2b +#define H2C_CMD_DEFAULT_PORT 0x2c +#define H2C_CMD_RA_INFO 0x40 +#define H2C_CMD_RSSI_MONITOR 0x42 +#define H2C_CMD_RA_INFO_HI 0x46 +#define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 +#define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57 +#define H2C_CMD_WL_PHY_INFO 0x58 +#define H2C_CMD_SCAN 0x59 +#define H2C_CMD_ADAPTIVITY 0x5A + +#define H2C_CMD_COEX_TDMA_TYPE 0x60 +#define H2C_CMD_QUERY_BT_INFO 0x61 +#define H2C_CMD_FORCE_BT_TX_POWER 0x62 +#define H2C_CMD_IGNORE_WLAN_ACTION 0x63 +#define H2C_CMD_WL_CH_INFO 0x66 +#define H2C_CMD_QUERY_BT_MP_INFO 0x67 +#define H2C_CMD_BT_WIFI_CONTROL 0x69 +#define H2C_CMD_WIFI_CALIBRATION 0x6d +#define H2C_CMD_QUERY_BT_HID_INFO 0x73 + +#define H2C_CMD_KEEP_ALIVE 0x03 +#define H2C_CMD_DISCONNECT_DECISION 0x04 +#define H2C_CMD_WOWLAN 0x80 +#define H2C_CMD_REMOTE_WAKE_CTRL 0x81 +#define H2C_CMD_AOAC_GLOBAL_INFO 0x82 +#define H2C_CMD_NLO_INFO 0x8C + +#define H2C_CMD_RECOVER_BT_DEV 0xD1 + +#define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0)) + +#define MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_WL_PHY_INFO_TX_TP(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(17, 8)) +#define SET_WL_PHY_INFO_RX_TP(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(27, 18)) +#define SET_WL_PHY_INFO_TX_RATE_DESC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) +#define SET_WL_PHY_INFO_RX_RATE_DESC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define SET_WL_PHY_INFO_RX_EVM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16)) +#define SET_BCN_FILTER_OFFLOAD_P1_MACID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_BCN_FILTER_OFFLOAD_P1_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(16)) +#define SET_BCN_FILTER_OFFLOAD_P1_HYST(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(20, 17)) +#define SET_BCN_FILTER_OFFLOAD_P1_OFFLOAD_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 21)) +#define SET_BCN_FILTER_OFFLOAD_P1_THRESHOLD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_BCN_FILTER_OFFLOAD_P1_BCN_LOSS_CNT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(3, 0)) +#define SET_BCN_FILTER_OFFLOAD_P1_BCN_INTERVAL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(13, 4)) + +#define SET_SCAN_START(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) + +#define SET_ADAPTIVITY_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(11, 8)) +#define SET_ADAPTIVITY_OPTION(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 12)) +#define SET_ADAPTIVITY_IGI(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_ADAPTIVITY_L2H(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_ADAPTIVITY_DENSITY(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) + +#define SET_PWR_MODE_SET_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(14, 8)) +#define SET_PWR_MODE_SET_RLBM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(19, 16)) +#define SET_PWR_MODE_SET_SMART_PS(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 20)) +#define SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_PWR_MODE_SET_PORT_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 5)) +#define SET_PWR_MODE_SET_PWR_STATE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define LPS_PG_INFO_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define LPS_PG_DPK_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define LPS_PG_SEC_CAM_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define LPS_PG_PATTERN_CAM_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_RSSI_INFO_MACID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_RSSI_INFO_RSSI(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_RSSI_INFO_STBC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, BIT(1)) +#define SET_RA_INFO_MACID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_RA_INFO_RATE_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(20, 16)) +#define SET_RA_INFO_INIT_RA_LVL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(22, 21)) +#define SET_RA_INFO_SGI_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(23)) +#define SET_RA_INFO_BW_MODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(25, 24)) +#define SET_RA_INFO_LDPC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(26)) +#define SET_RA_INFO_NO_UPDATE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(27)) +#define SET_RA_INFO_VHT_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(29, 28)) +#define SET_RA_INFO_DIS_PT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(30)) +#define SET_RA_INFO_RA_MASK0(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) +#define SET_RA_INFO_RA_MASK1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define SET_RA_INFO_RA_MASK2(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16)) +#define SET_RA_INFO_RA_MASK3(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(31, 24)) +#define SET_QUERY_BT_INFO(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_WL_CH_INFO_LINK(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_WL_CH_INFO_CHNL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_WL_CH_INFO_BW(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_BT_MP_INFO_SEQ(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 12)) +#define SET_BT_MP_INFO_OP_CODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_BT_MP_INFO_PARA1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_BT_MP_INFO_PARA2(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) +#define SET_BT_MP_INFO_PARA3(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define SET_BT_TX_POWER_INDEX(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_IGNORE_WLAN_ACTION_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_COEX_TDMA_TYPE_PARA1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_COEX_TDMA_TYPE_PARA2(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_COEX_TDMA_TYPE_PARA3(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_COEX_TDMA_TYPE_PARA4(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) +#define SET_COEX_TDMA_TYPE_PARA5(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define SET_BT_WIFI_CONTROL_DATA3(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0)) +#define SET_BT_WIFI_CONTROL_DATA4(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16)) + +#define SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_KEEP_ALIVE_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_KEEP_ALIVE_ADOPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_DISCONNECT_DECISION_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_DISCONNECT_DECISION_ADOPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) + +#define SET_WOWLAN_FUNC_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_WOWLAN_UNICAST_PKT_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(11)) +#define SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(14)) +#define SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(15)) + +#define SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(12)) + +#define SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_NLO_FUN_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_NLO_PS_32K(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_NLO_IGNORE_SECURITY(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_RECOVER_BT_DEV_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) + +#define GET_FW_DUMP_LEN(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(15, 0)) +#define GET_FW_DUMP_SEQ(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(22, 16)) +#define GET_FW_DUMP_MORE(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x00), BIT(23)) +#define GET_FW_DUMP_VERSION(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(31, 24)) +#define GET_FW_DUMP_TLV_TYPE(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x01), GENMASK(15, 0)) +#define GET_FW_DUMP_TLV_LEN(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x01), GENMASK(31, 16)) +#define GET_FW_DUMP_TLV_VAL(_header) \ + le32_get_bits(*((__le32 *)(_header) + 0x02), GENMASK(31, 0)) + +#define RFK_SET_INFORM_START(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +static inline struct rtw_c2h_cmd *get_c2h_from_skb(struct sk_buff *skb) +{ + u32 pkt_offset; + + pkt_offset = *((u32 *)skb->cb); + return (struct rtw_c2h_cmd *)(skb->data + pkt_offset); +} + +static inline bool rtw_fw_feature_check(struct rtw_fw_state *fw, + enum rtw_fw_feature feature) +{ + return !!(fw->feature & feature); +} + +static inline bool rtw_fw_feature_ext_check(struct rtw_fw_state *fw, + enum rtw_fw_feature_ext feature) +{ + return !!(fw->feature_ext & feature); +} + +void rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev); +void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset, + struct sk_buff *skb); +void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); +void rtw_fw_send_general_info(struct rtw_dev *rtwdev); +void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); +void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); + +void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); +void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); +void rtw_fw_set_pwr_mode(struct rtw_dev *rtwdev); +void rtw_fw_set_pg_info(struct rtw_dev *rtwdev); +void rtw_fw_query_bt_info(struct rtw_dev *rtwdev); +void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw); +void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev, + struct rtw_coex_info_req *req); +void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl); +void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev, + u8 para1, u8 para2, u8 para3, u8 para4, u8 para5); +void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data); + +void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data); +void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); +void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask); +void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn); +void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev); +void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect, + struct ieee80211_vif *vif); +int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, + u8 *buf, u32 size); +void rtw_remove_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_bcn(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev); +void rtw_fw_update_beacon_work(struct work_struct *work); +void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev); +int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev, + u32 offset, u32 size, u32 *buf); +void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_keep_alive_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev *rtwdev, + u8 pairwise_key_enc, + u8 group_key_enc); + +void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev); +void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid); +void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c); +void rtw_fw_c2h_cmd_isr(struct rtw_dev *rtwdev); +int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, + u32 *buffer); +void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start); +void rtw_fw_adaptivity(struct rtw_dev *rtwdev); +void rtw_store_op_chan(struct rtw_dev *rtwdev, bool backup); +void rtw_clear_op_chan(struct rtw_dev *rtwdev); +void rtw_hw_scan_start(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_scan_request *req); +void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool aborted); +int rtw_hw_scan_offload(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool enable); +void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb); +void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb); +void rtw_hw_scan_abort(struct rtw_dev *rtwdev); +#endif diff --git a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/realtek/rtw88/hci.h new file mode 100644 index 000000000..d4bee9c3e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/hci.h @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_HCI_H__ +#define __RTW_HCI_H__ + +/* ops for PCI, USB and SDIO */ +struct rtw_hci_ops { + int (*tx_write)(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb); + void (*tx_kick_off)(struct rtw_dev *rtwdev); + void (*flush_queues)(struct rtw_dev *rtwdev, u32 queues, bool drop); + int (*setup)(struct rtw_dev *rtwdev); + int (*start)(struct rtw_dev *rtwdev); + void (*stop)(struct rtw_dev *rtwdev); + void (*deep_ps)(struct rtw_dev *rtwdev, bool enter); + void (*link_ps)(struct rtw_dev *rtwdev, bool enter); + void (*interface_cfg)(struct rtw_dev *rtwdev); + void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable); + void (*write_firmware_page)(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size); + + int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size); + int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size); + + u8 (*read8)(struct rtw_dev *rtwdev, u32 addr); + u16 (*read16)(struct rtw_dev *rtwdev, u32 addr); + u32 (*read32)(struct rtw_dev *rtwdev, u32 addr); + void (*write8)(struct rtw_dev *rtwdev, u32 addr, u8 val); + void (*write16)(struct rtw_dev *rtwdev, u32 addr, u16 val); + void (*write32)(struct rtw_dev *rtwdev, u32 addr, u32 val); +}; + +static inline int rtw_hci_tx_write(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + return rtwdev->hci.ops->tx_write(rtwdev, pkt_info, skb); +} + +static inline void rtw_hci_tx_kick_off(struct rtw_dev *rtwdev) +{ + return rtwdev->hci.ops->tx_kick_off(rtwdev); +} + +static inline int rtw_hci_setup(struct rtw_dev *rtwdev) +{ + return rtwdev->hci.ops->setup(rtwdev); +} + +static inline int rtw_hci_start(struct rtw_dev *rtwdev) +{ + return rtwdev->hci.ops->start(rtwdev); +} + +static inline void rtw_hci_stop(struct rtw_dev *rtwdev) +{ + rtwdev->hci.ops->stop(rtwdev); +} + +static inline void rtw_hci_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + rtwdev->hci.ops->deep_ps(rtwdev, enter); +} + +static inline void rtw_hci_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + rtwdev->hci.ops->link_ps(rtwdev, enter); +} + +static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev) +{ + rtwdev->hci.ops->interface_cfg(rtwdev); +} + +static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) +{ + if (rtwdev->hci.ops->dynamic_rx_agg) + rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable); +} + +static inline void rtw_hci_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) +{ + rtwdev->hci.ops->write_firmware_page(rtwdev, page, data, size); +} + +static inline int +rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + return rtwdev->hci.ops->write_data_rsvd_page(rtwdev, buf, size); +} + +static inline int +rtw_hci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + return rtwdev->hci.ops->write_data_h2c(rtwdev, buf, size); +} + +static inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read8(rtwdev, addr); +} + +static inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read16(rtwdev, addr); +} + +static inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read32(rtwdev, addr); +} + +static inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) +{ + rtwdev->hci.ops->write8(rtwdev, addr, val); +} + +static inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) +{ + rtwdev->hci.ops->write16(rtwdev, addr, val); +} + +static inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) +{ + rtwdev->hci.ops->write32(rtwdev, addr, val); +} + +static inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit) +{ + u8 val; + + val = rtw_read8(rtwdev, addr); + rtw_write8(rtwdev, addr, val | bit); +} + +static inline void rtw_write16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit) +{ + u16 val; + + val = rtw_read16(rtwdev, addr); + rtw_write16(rtwdev, addr, val | bit); +} + +static inline void rtw_write32_set(struct rtw_dev *rtwdev, u32 addr, u32 bit) +{ + u32 val; + + val = rtw_read32(rtwdev, addr); + rtw_write32(rtwdev, addr, val | bit); +} + +static inline void rtw_write8_clr(struct rtw_dev *rtwdev, u32 addr, u8 bit) +{ + u8 val; + + val = rtw_read8(rtwdev, addr); + rtw_write8(rtwdev, addr, val & ~bit); +} + +static inline void rtw_write16_clr(struct rtw_dev *rtwdev, u32 addr, u16 bit) +{ + u16 val; + + val = rtw_read16(rtwdev, addr); + rtw_write16(rtwdev, addr, val & ~bit); +} + +static inline void rtw_write32_clr(struct rtw_dev *rtwdev, u32 addr, u32 bit) +{ + u32 val; + + val = rtw_read32(rtwdev, addr); + rtw_write32(rtwdev, addr, val & ~bit); +} + +static inline u32 +rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask) +{ + u32 val; + + lockdep_assert_held(&rtwdev->mutex); + + val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); + + return val; +} + +static inline void +rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + lockdep_assert_held(&rtwdev->mutex); + + rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); +} + +static inline u32 +rtw_read32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw_read32(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline u16 +rtw_read16_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw_read16(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline u8 +rtw_read8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw_read8(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline void +rtw_write32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 set; + + WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr); + + orig = rtw_read32(rtwdev, addr); + set = (orig & ~mask) | ((data << shift) & mask); + rtw_write32(rtwdev, addr, set); +} + +static inline void +rtw_write8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u8 data) +{ + u32 shift; + u8 orig, set; + + mask &= 0xff; + shift = __ffs(mask); + + orig = rtw_read8(rtwdev, addr); + set = (orig & ~mask) | ((data << shift) & mask); + rtw_write8(rtwdev, addr, set); +} + +static inline enum rtw_hci_type rtw_hci_type(struct rtw_dev *rtwdev) +{ + return rtwdev->hci.type; +} + +static inline void rtw_hci_flush_queues(struct rtw_dev *rtwdev, u32 queues, + bool drop) +{ + if (rtwdev->hci.ops->flush_queues) + rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); +} + +static inline void rtw_hci_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +{ + if (rtwdev->hci.ops->flush_queues) + rtwdev->hci.ops->flush_queues(rtwdev, + BIT(rtwdev->hw->queues) - 1, + drop); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/led.c b/drivers/net/wireless/realtek/rtw88/led.c new file mode 100644 index 000000000..4cc62e49d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/led.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include "main.h" +#include "debug.h" +#include "led.h" + +static int rtw_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + + mutex_lock(&rtwdev->mutex); + + rtwdev->chip->ops->led_set(led, brightness); + + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +void rtw_led_init(struct rtw_dev *rtwdev) +{ + static const struct ieee80211_tpt_blink rtw_tpt_blink[] = { + { .throughput = 0 * 1024, .blink_time = 334 }, + { .throughput = 1 * 1024, .blink_time = 260 }, + { .throughput = 5 * 1024, .blink_time = 220 }, + { .throughput = 10 * 1024, .blink_time = 190 }, + { .throughput = 20 * 1024, .blink_time = 170 }, + { .throughput = 50 * 1024, .blink_time = 150 }, + { .throughput = 70 * 1024, .blink_time = 130 }, + { .throughput = 100 * 1024, .blink_time = 110 }, + { .throughput = 200 * 1024, .blink_time = 80 }, + { .throughput = 300 * 1024, .blink_time = 50 }, + }; + struct led_classdev *led = &rtwdev->led_cdev; + int err; + + if (!rtwdev->chip->ops->led_set) + return; + + led->brightness_set_blocking = rtw_led_set; + + snprintf(rtwdev->led_name, sizeof(rtwdev->led_name), + "rtw88-%s", dev_name(rtwdev->dev)); + + led->name = rtwdev->led_name; + led->max_brightness = LED_ON; + led->default_trigger = + ieee80211_create_tpt_led_trigger(rtwdev->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, + rtw_tpt_blink, + ARRAY_SIZE(rtw_tpt_blink)); + + err = led_classdev_register(rtwdev->dev, led); + if (err) { + rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err); + return; + } + + rtwdev->led_registered = true; +} + +void rtw_led_deinit(struct rtw_dev *rtwdev) +{ + struct led_classdev *led = &rtwdev->led_cdev; + + if (!rtwdev->led_registered) + return; + + rtwdev->chip->ops->led_set(led, LED_OFF); + led_classdev_unregister(led); +} diff --git a/drivers/net/wireless/realtek/rtw88/led.h b/drivers/net/wireless/realtek/rtw88/led.h new file mode 100644 index 000000000..fa64002b0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/led.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW_LED_H +#define __RTW_LED_H + +#ifdef CONFIG_RTW88_LEDS + +void rtw_led_init(struct rtw_dev *rtwdev); +void rtw_led_deinit(struct rtw_dev *rtwdev); + +#else + +static inline void rtw_led_init(struct rtw_dev *rtwdev) +{ +} + +static inline void rtw_led_deinit(struct rtw_dev *rtwdev) +{ +} + +#endif + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c new file mode 100644 index 000000000..eaa928bab --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -0,0 +1,1421 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "mac.h" +#include "reg.h" +#include "fw.h" +#include "debug.h" +#include "sdio.h" + +void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + u8 txsc40 = 0, txsc20 = 0; + u32 value32; + u8 value8; + + txsc20 = primary_ch_idx; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } + rtw_write8(rtwdev, REG_DATA_SC, + BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40)); + + value32 = rtw_read32(rtwdev, REG_WMAC_TRXPTCL_CTL); + value32 &= ~BIT_RFMOD; + switch (bw) { + case RTW_CHANNEL_WIDTH_80: + value32 |= BIT_RFMOD_80M; + break; + case RTW_CHANNEL_WIDTH_40: + value32 |= BIT_RFMOD_40M; + break; + case RTW_CHANNEL_WIDTH_20: + default: + break; + } + rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32); + + if (rtw_chip_wcpu_8051(rtwdev)) + return; + + value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL); + value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL); + rtw_write32(rtwdev, REG_AFE_CTRL1, value32); + + rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED); + rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED); + + value8 = rtw_read8(rtwdev, REG_CCK_CHECK); + value8 = value8 & ~BIT_CHECK_CCK_EN; + if (IS_CH_5G_BAND(channel)) + value8 |= BIT_CHECK_CCK_EN; + rtw_write8(rtwdev, REG_CCK_CHECK, value8); +} +EXPORT_SYMBOL(rtw_set_channel_mac); + +static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) +{ + unsigned int retry; + u32 value32; + u8 value8; + + rtw_write8(rtwdev, REG_RSV_CTRL, 0); + + if (rtw_chip_wcpu_8051(rtwdev)) { + if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO) + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL); + else + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, SPS_SEL); + return 0; + } + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); + break; + case RTW_HCI_TYPE_SDIO: + rtw_write8_clr(rtwdev, REG_SDIO_HSUS_CTRL, BIT_HCI_SUS_REQ); + + for (retry = 0; retry < RTW_PWR_POLLING_CNT; retry++) { + if (rtw_read8(rtwdev, REG_SDIO_HSUS_CTRL) & BIT_HCI_RESUME_RDY) + break; + + usleep_range(10, 50); + } + + if (retry == RTW_PWR_POLLING_CNT) { + rtw_err(rtwdev, "failed to poll REG_SDIO_HSUS_CTRL[1]"); + return -ETIMEDOUT; + } + + if (rtw_sdio_is_sdio30_supported(rtwdev)) + rtw_write8_set(rtwdev, REG_HCI_OPT_CTRL + 2, + BIT_SDIO_PAD_E5 >> 16); + else + rtw_write8_clr(rtwdev, REG_HCI_OPT_CTRL + 2, + BIT_SDIO_PAD_E5 >> 16); + break; + case RTW_HCI_TYPE_USB: + break; + default: + return -EINVAL; + } + + /* config PIN Mux */ + value32 = rtw_read32(rtwdev, REG_PAD_CTRL1); + value32 |= BIT_PAPE_WLBT_SEL | BIT_LNAON_WLBT_SEL; + rtw_write32(rtwdev, REG_PAD_CTRL1, value32); + + value32 = rtw_read32(rtwdev, REG_LED_CFG); + value32 &= ~(BIT_PAPE_SEL_EN | BIT_LNAON_SEL_EN); + rtw_write32(rtwdev, REG_LED_CFG, value32); + + value32 = rtw_read32(rtwdev, REG_GPIO_MUXCFG); + value32 |= BIT_WLRFE_4_5_EN; + rtw_write32(rtwdev, REG_GPIO_MUXCFG, value32); + + /* disable BB/RF */ + value8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); + value8 &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST); + rtw_write8(rtwdev, REG_SYS_FUNC_EN, value8); + + value8 = rtw_read8(rtwdev, REG_RF_CTRL); + value8 &= ~(BIT_RF_SDM_RSTB | BIT_RF_RSTB | BIT_RF_EN); + rtw_write8(rtwdev, REG_RF_CTRL, value8); + + value32 = rtw_read32(rtwdev, REG_WLRF1); + value32 &= ~BIT_WLRF1_BBRF_EN; + rtw_write32(rtwdev, REG_WLRF1, value32); + + return 0; +} + +static bool do_pwr_poll_cmd(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target) +{ + u32 val; + + target &= mask; + + return read_poll_timeout_atomic(rtw_read8, val, (val & mask) == target, + 50, 50 * RTW_PWR_POLLING_CNT, false, + rtwdev, addr) == 0; +} + +static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd *cmd) +{ + u8 value; + u32 offset; + + if (cmd->base == RTW_PWR_ADDR_SDIO) + offset = cmd->offset | SDIO_LOCAL_OFFSET; + else + offset = cmd->offset; + + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + + if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_PCIE) + goto err; + + /* if PCIE, toggle BIT_PFM_WOWL and try again */ + value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + +err: + rtw_err(rtwdev, "failed to poll offset=0x%x mask=0x%x value=0x%x\n", + offset, cmd->mask, cmd->value); + return -EBUSY; +} + +static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, + u8 cut_mask, + const struct rtw_pwr_seq_cmd *cmd) +{ + const struct rtw_pwr_seq_cmd *cur_cmd; + u32 offset; + u8 value; + + for (cur_cmd = cmd; cur_cmd->cmd != RTW_PWR_CMD_END; cur_cmd++) { + if (!(cur_cmd->intf_mask & intf_mask) || + !(cur_cmd->cut_mask & cut_mask)) + continue; + + switch (cur_cmd->cmd) { + case RTW_PWR_CMD_WRITE: + offset = cur_cmd->offset; + + if (cur_cmd->base == RTW_PWR_ADDR_SDIO) + offset |= SDIO_LOCAL_OFFSET; + + value = rtw_read8(rtwdev, offset); + value &= ~cur_cmd->mask; + value |= (cur_cmd->value & cur_cmd->mask); + rtw_write8(rtwdev, offset, value); + break; + case RTW_PWR_CMD_POLLING: + if (rtw_pwr_cmd_polling(rtwdev, cur_cmd)) + return -EBUSY; + break; + case RTW_PWR_CMD_DELAY: + if (cur_cmd->value == RTW_PWR_DELAY_US) + udelay(cur_cmd->offset); + else + mdelay(cur_cmd->offset); + break; + case RTW_PWR_CMD_READ: + break; + default: + return -EINVAL; + } + } + + return 0; +} + +int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd * const *cmd_seq) +{ + u8 cut_mask; + u8 intf_mask; + u8 cut; + u32 idx = 0; + const struct rtw_pwr_seq_cmd *cmd; + int ret; + + cut = rtwdev->hal.cut_version; + cut_mask = cut_version_to_mask(cut); + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + intf_mask = RTW_PWR_INTF_PCI_MSK; + break; + case RTW_HCI_TYPE_USB: + intf_mask = RTW_PWR_INTF_USB_MSK; + break; + case RTW_HCI_TYPE_SDIO: + intf_mask = RTW_PWR_INTF_SDIO_MSK; + break; + default: + return -EINVAL; + } + + do { + cmd = cmd_seq[idx]; + if (!cmd) + break; + + ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd); + if (ret) + return ret; + + idx++; + } while (1); + + return 0; +} +EXPORT_SYMBOL(rtw_pwr_seq_parser); + +static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_pwr_seq_cmd * const *pwr_seq; + u32 imr = 0; + u8 rpwm; + bool cur_pwr; + int ret; + + if (rtw_chip_wcpu_3081(rtwdev)) { + rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + + /* Check FW still exist or not */ + if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) { + rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE; + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm); + } + } + + if (rtw_read8(rtwdev, REG_CR) == 0xea) + cur_pwr = false; + else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + chip->id != RTW_CHIP_TYPE_8814A && + (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0))) + cur_pwr = false; + else + cur_pwr = true; + + if (pwr_on == cur_pwr) + return -EALREADY; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { + imr = rtw_read32(rtwdev, REG_SDIO_HIMR); + rtw_write32(rtwdev, REG_SDIO_HIMR, 0); + } + + if (!pwr_on) + clear_bit(RTW_FLAG_POWERON, rtwdev->flags); + + pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; + ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); + + if (pwr_on && rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { + if (chip->id == RTW_CHIP_TYPE_8822C || + chip->id == RTW_CHIP_TYPE_8822B || + chip->id == RTW_CHIP_TYPE_8821C) + rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0)); + } + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) + rtw_write32(rtwdev, REG_SDIO_HIMR, imr); + + if (!ret && pwr_on) + set_bit(RTW_FLAG_POWERON, rtwdev->flags); + + return ret; +} + +static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +{ + u8 sys_func_en = rtwdev->chip->sys_func_en; + u8 value8; + u32 value, tmp; + + value = rtw_read32(rtwdev, REG_CPU_DMEM_CON); + value |= BIT_WL_PLATFORM_RST | BIT_DDMA_EN; + rtw_write32(rtwdev, REG_CPU_DMEM_CON, value); + + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, sys_func_en); + value8 = (rtw_read8(rtwdev, REG_CR_EXT + 3) & 0xF0) | 0x0C; + rtw_write8(rtwdev, REG_CR_EXT + 3, value8); + + /* disable boot-from-flash for driver's DL FW */ + tmp = rtw_read32(rtwdev, REG_MCUFW_CTRL); + if (tmp & BIT_BOOT_FSPI_EN) { + rtw_write32(rtwdev, REG_MCUFW_CTRL, tmp & (~BIT_BOOT_FSPI_EN)); + value = rtw_read32(rtwdev, REG_GPIO_MUXCFG) & (~BIT_FSPI_EN); + rtw_write32(rtwdev, REG_GPIO_MUXCFG, value); + } + + return 0; +} + +static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_CR, 0xff); + mdelay(2); + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0x7f); + mdelay(2); + + rtw_write8_set(rtwdev, REG_SYS_CLKR, BIT_WAKEPAD_EN); + rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); + + rtw_write16(rtwdev, REG_CR, 0x2ff); + + return 0; +} + +static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +{ + if (rtw_chip_wcpu_8051(rtwdev)) + return __rtw_mac_init_system_cfg_legacy(rtwdev); + + return __rtw_mac_init_system_cfg(rtwdev); +} + +int rtw_mac_power_on(struct rtw_dev *rtwdev) +{ + int ret = 0; + + ret = rtw_mac_pre_system_cfg(rtwdev); + if (ret) + goto err; + + ret = rtw_mac_power_switch(rtwdev, true); + if (ret == -EALREADY) { + rtw_mac_power_switch(rtwdev, false); + + ret = rtw_mac_pre_system_cfg(rtwdev); + if (ret) + goto err; + + ret = rtw_mac_power_switch(rtwdev, true); + if (ret) + goto err; + } else if (ret) { + goto err; + } + + ret = rtw_mac_init_system_cfg(rtwdev); + if (ret) + goto err; + + return 0; + +err: + rtw_err(rtwdev, "mac power on failed"); + return ret; +} + +void rtw_mac_power_off(struct rtw_dev *rtwdev) +{ + rtw_mac_power_switch(rtwdev, false); +} + +static bool check_firmware_size(const u8 *data, u32 size) +{ + const struct rtw_fw_hdr *fw_hdr = (const struct rtw_fw_hdr *)data; + u32 dmem_size; + u32 imem_size; + u32 emem_size; + u32 real_size; + + dmem_size = le32_to_cpu(fw_hdr->dmem_size); + imem_size = le32_to_cpu(fw_hdr->imem_size); + emem_size = (fw_hdr->mem_usage & BIT(4)) ? + le32_to_cpu(fw_hdr->emem_size) : 0; + + dmem_size += FW_HDR_CHKSUM_SIZE; + imem_size += FW_HDR_CHKSUM_SIZE; + emem_size += emem_size ? FW_HDR_CHKSUM_SIZE : 0; + real_size = FW_HDR_SIZE + dmem_size + imem_size + emem_size; + if (real_size != size) + return false; + + return true; +} + +static void wlan_cpu_enable(struct rtw_dev *rtwdev, bool enable) +{ + if (enable) { + /* cpu io interface enable */ + rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT_WLMCU_IOIF); + + /* cpu enable */ + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT_FEN_CPUEN); + } else { + /* cpu io interface disable */ + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT_FEN_CPUEN); + + /* cpu disable */ + rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT_WLMCU_IOIF); + } +} + +#define DLFW_RESTORE_REG_NUM 6 + +static void download_firmware_reg_backup(struct rtw_dev *rtwdev, + struct rtw_backup_info *bckp) +{ + u8 tmp; + u8 bckp_idx = 0; + + /* set HIQ to hi priority */ + bckp[bckp_idx].len = 1; + bckp[bckp_idx].reg = REG_TXDMA_PQ_MAP + 1; + bckp[bckp_idx].val = rtw_read8(rtwdev, REG_TXDMA_PQ_MAP + 1); + bckp_idx++; + tmp = RTW_DMA_MAPPING_HIGH << 6; + rtw_write8(rtwdev, REG_TXDMA_PQ_MAP + 1, tmp); + + /* DLFW only use HIQ, map HIQ to hi priority */ + bckp[bckp_idx].len = 1; + bckp[bckp_idx].reg = REG_CR; + bckp[bckp_idx].val = rtw_read8(rtwdev, REG_CR); + bckp_idx++; + bckp[bckp_idx].len = 4; + bckp[bckp_idx].reg = REG_H2CQ_CSR; + bckp[bckp_idx].val = BIT_H2CQ_FULL; + bckp_idx++; + tmp = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN; + rtw_write8(rtwdev, REG_CR, tmp); + rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); + + /* Config hi priority queue and public priority queue page number */ + bckp[bckp_idx].len = 2; + bckp[bckp_idx].reg = REG_FIFOPAGE_INFO_1; + bckp[bckp_idx].val = rtw_read16(rtwdev, REG_FIFOPAGE_INFO_1); + bckp_idx++; + bckp[bckp_idx].len = 4; + bckp[bckp_idx].reg = REG_RQPN_CTRL_2; + bckp[bckp_idx].val = rtw_read32(rtwdev, REG_RQPN_CTRL_2) | BIT_LD_RQPN; + bckp_idx++; + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, 0x200); + rtw_write32(rtwdev, REG_RQPN_CTRL_2, bckp[bckp_idx - 1].val); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) + rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); + + /* Disable beacon related functions */ + tmp = rtw_read8(rtwdev, REG_BCN_CTRL); + bckp[bckp_idx].len = 1; + bckp[bckp_idx].reg = REG_BCN_CTRL; + bckp[bckp_idx].val = tmp; + bckp_idx++; + tmp = (u8)((tmp & (~BIT_EN_BCN_FUNCTION)) | BIT_DIS_TSF_UDT); + rtw_write8(rtwdev, REG_BCN_CTRL, tmp); + + WARN(bckp_idx != DLFW_RESTORE_REG_NUM, "wrong backup number\n"); +} + +static void download_firmware_reset_platform(struct rtw_dev *rtwdev) +{ + rtw_write8_clr(rtwdev, REG_CPU_DMEM_CON + 2, BIT_WL_PLATFORM_RST >> 16); + rtw_write8_clr(rtwdev, REG_SYS_CLK_CTRL + 1, BIT_CPU_CLK_EN >> 8); + rtw_write8_set(rtwdev, REG_CPU_DMEM_CON + 2, BIT_WL_PLATFORM_RST >> 16); + rtw_write8_set(rtwdev, REG_SYS_CLK_CTRL + 1, BIT_CPU_CLK_EN >> 8); +} + +static void download_firmware_reg_restore(struct rtw_dev *rtwdev, + struct rtw_backup_info *bckp, + u8 bckp_num) +{ + rtw_restore_reg(rtwdev, bckp, bckp_num); +} + +#define TX_DESC_SIZE 48 + +static int send_firmware_pkt_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, + const u8 *data, u32 size) +{ + u8 *buf; + int ret; + + buf = kmemdup(data, size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = rtw_fw_write_data_rsvd_page(rtwdev, pg_addr, buf, size); + kfree(buf); + return ret; +} + +static int +send_firmware_pkt(struct rtw_dev *rtwdev, u16 pg_addr, const u8 *data, u32 size) +{ + int ret; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + !((size + TX_DESC_SIZE) & (512 - 1))) + size += 1; + + ret = send_firmware_pkt_rsvd_page(rtwdev, pg_addr, data, size); + if (ret) + rtw_err(rtwdev, "failed to download rsvd page\n"); + + return ret; +} + +static int +iddma_enable(struct rtw_dev *rtwdev, u32 src, u32 dst, u32 ctrl) +{ + rtw_write32(rtwdev, REG_DDMA_CH0SA, src); + rtw_write32(rtwdev, REG_DDMA_CH0DA, dst); + rtw_write32(rtwdev, REG_DDMA_CH0CTRL, ctrl); + + if (!check_hw_ready(rtwdev, REG_DDMA_CH0CTRL, BIT_DDMACH0_OWN, 0)) + return -EBUSY; + + return 0; +} + +static int iddma_download_firmware(struct rtw_dev *rtwdev, u32 src, u32 dst, + u32 len, u8 first) +{ + u32 ch0_ctrl = BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN; + + if (!check_hw_ready(rtwdev, REG_DDMA_CH0CTRL, BIT_DDMACH0_OWN, 0)) + return -EBUSY; + + ch0_ctrl |= len & BIT_MASK_DDMACH0_DLEN; + if (!first) + ch0_ctrl |= BIT_DDMACH0_CHKSUM_CONT; + + if (iddma_enable(rtwdev, src, dst, ch0_ctrl)) + return -EBUSY; + + return 0; +} + +int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size) +{ + u32 ch0_ctrl = BIT_DDMACH0_OWN | BIT_DDMACH0_DDMA_MODE; + + if (!check_hw_ready(rtwdev, REG_DDMA_CH0CTRL, BIT_DDMACH0_OWN, 0)) { + rtw_dbg(rtwdev, RTW_DBG_FW, "busy to start ddma\n"); + return -EBUSY; + } + + ch0_ctrl |= size & BIT_MASK_DDMACH0_DLEN; + + if (iddma_enable(rtwdev, ocp_src, OCPBASE_RXBUF_FW_88XX, ch0_ctrl)) { + rtw_dbg(rtwdev, RTW_DBG_FW, "busy to complete ddma\n"); + return -EBUSY; + } + + return 0; +} + +static bool +check_fw_checksum(struct rtw_dev *rtwdev, u32 addr) +{ + u8 fw_ctrl; + + fw_ctrl = rtw_read8(rtwdev, REG_MCUFW_CTRL); + + if (rtw_read32(rtwdev, REG_DDMA_CH0CTRL) & BIT_DDMACH0_CHKSUM_STS) { + if (addr < OCPBASE_DMEM_88XX) { + fw_ctrl |= BIT_IMEM_DW_OK; + fw_ctrl &= ~BIT_IMEM_CHKSUM_OK; + rtw_write8(rtwdev, REG_MCUFW_CTRL, fw_ctrl); + } else { + fw_ctrl |= BIT_DMEM_DW_OK; + fw_ctrl &= ~BIT_DMEM_CHKSUM_OK; + rtw_write8(rtwdev, REG_MCUFW_CTRL, fw_ctrl); + } + + rtw_err(rtwdev, "invalid fw checksum\n"); + + return false; + } + + if (addr < OCPBASE_DMEM_88XX) { + fw_ctrl |= (BIT_IMEM_DW_OK | BIT_IMEM_CHKSUM_OK); + rtw_write8(rtwdev, REG_MCUFW_CTRL, fw_ctrl); + } else { + fw_ctrl |= (BIT_DMEM_DW_OK | BIT_DMEM_CHKSUM_OK); + rtw_write8(rtwdev, REG_MCUFW_CTRL, fw_ctrl); + } + + return true; +} + +static int +download_firmware_to_mem(struct rtw_dev *rtwdev, const u8 *data, + u32 src, u32 dst, u32 size) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u32 desc_size = chip->tx_pkt_desc_sz; + u8 first_part; + u32 mem_offset; + u32 residue_size; + u32 pkt_size; + u32 max_size = 0x1000; + u32 val; + int ret; + + mem_offset = 0; + first_part = 1; + residue_size = size; + + val = rtw_read32(rtwdev, REG_DDMA_CH0CTRL); + val |= BIT_DDMACH0_RESET_CHKSUM_STS; + rtw_write32(rtwdev, REG_DDMA_CH0CTRL, val); + + while (residue_size) { + if (residue_size >= max_size) + pkt_size = max_size; + else + pkt_size = residue_size; + + ret = send_firmware_pkt(rtwdev, (u16)(src >> 7), + data + mem_offset, pkt_size); + if (ret) + return ret; + + ret = iddma_download_firmware(rtwdev, OCPBASE_TXBUF_88XX + + src + desc_size, + dst + mem_offset, pkt_size, + first_part); + if (ret) + return ret; + + first_part = 0; + mem_offset += pkt_size; + residue_size -= pkt_size; + } + + if (!check_fw_checksum(rtwdev, dst)) + return -EINVAL; + + return 0; +} + +static int +start_download_firmware(struct rtw_dev *rtwdev, const u8 *data, u32 size) +{ + const struct rtw_fw_hdr *fw_hdr = (const struct rtw_fw_hdr *)data; + const u8 *cur_fw; + u16 val; + u32 imem_size; + u32 dmem_size; + u32 emem_size; + u32 addr; + int ret; + + dmem_size = le32_to_cpu(fw_hdr->dmem_size); + imem_size = le32_to_cpu(fw_hdr->imem_size); + emem_size = (fw_hdr->mem_usage & BIT(4)) ? + le32_to_cpu(fw_hdr->emem_size) : 0; + dmem_size += FW_HDR_CHKSUM_SIZE; + imem_size += FW_HDR_CHKSUM_SIZE; + emem_size += emem_size ? FW_HDR_CHKSUM_SIZE : 0; + + val = (u16)(rtw_read16(rtwdev, REG_MCUFW_CTRL) & 0x3800); + val |= BIT_MCUFWDL_EN; + rtw_write16(rtwdev, REG_MCUFW_CTRL, val); + + cur_fw = data + FW_HDR_SIZE; + addr = le32_to_cpu(fw_hdr->dmem_addr); + addr &= ~BIT(31); + ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, dmem_size); + if (ret) + return ret; + + cur_fw = data + FW_HDR_SIZE + dmem_size; + addr = le32_to_cpu(fw_hdr->imem_addr); + addr &= ~BIT(31); + ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, imem_size); + if (ret) + return ret; + + if (emem_size) { + cur_fw = data + FW_HDR_SIZE + dmem_size + imem_size; + addr = le32_to_cpu(fw_hdr->emem_addr); + addr &= ~BIT(31); + ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, + emem_size); + if (ret) + return ret; + } + + return 0; +} + +static int download_firmware_validate(struct rtw_dev *rtwdev) +{ + u32 fw_key; + + if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, FW_READY_MASK, FW_READY)) { + fw_key = rtw_read32(rtwdev, REG_FW_DBG7) & FW_KEY_MASK; + if (fw_key == ILLEGAL_KEY_GROUP) + rtw_err(rtwdev, "invalid fw key\n"); + return -EINVAL; + } + + return 0; +} + +static void download_firmware_end_flow(struct rtw_dev *rtwdev) +{ + u16 fw_ctrl; + + rtw_write32(rtwdev, REG_TXDMA_STATUS, BTI_PAGE_OVF); + + /* Check IMEM & DMEM checksum is OK or not */ + fw_ctrl = rtw_read16(rtwdev, REG_MCUFW_CTRL); + if ((fw_ctrl & BIT_CHECK_SUM_OK) != BIT_CHECK_SUM_OK) + return; + + fw_ctrl = (fw_ctrl | BIT_FW_DW_RDY) & ~BIT_MCUFWDL_EN; + rtw_write16(rtwdev, REG_MCUFW_CTRL, fw_ctrl); +} + +static int __rtw_download_firmware(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + struct rtw_backup_info bckp[DLFW_RESTORE_REG_NUM]; + const u8 *data = fw->firmware->data; + u32 size = fw->firmware->size; + u32 ltecoex_bckp; + int ret; + + if (!check_firmware_size(data, size)) + return -EINVAL; + + if (rtwdev->chip->ltecoex_addr && + !ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) + return -EBUSY; + + wlan_cpu_enable(rtwdev, false); + + download_firmware_reg_backup(rtwdev, bckp); + download_firmware_reset_platform(rtwdev); + + ret = start_download_firmware(rtwdev, data, size); + if (ret) + goto dlfw_fail; + + download_firmware_reg_restore(rtwdev, bckp, DLFW_RESTORE_REG_NUM); + + download_firmware_end_flow(rtwdev); + + wlan_cpu_enable(rtwdev, true); + + if (rtwdev->chip->ltecoex_addr && + !ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { + ret = -EBUSY; + goto dlfw_fail; + } + + ret = download_firmware_validate(rtwdev); + if (ret) + goto dlfw_fail; + + /* reset desc and index */ + rtw_hci_setup(rtwdev); + + rtwdev->h2c.last_box_num = 0; + rtwdev->h2c.seq = 0; + + set_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + + return 0; + +dlfw_fail: + /* Disable FWDL_EN */ + rtw_write8_clr(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT_FEN_CPUEN); + + return ret; +} + +static void en_download_firmware_legacy(struct rtw_dev *rtwdev, bool en) +{ + int try; + + if (en) { + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + + for (try = 0; try < 10; try++) { + if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_MCUFWDL_EN) + goto fwdl_ready; + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + msleep(20); + } + rtw_err(rtwdev, "failed to check fw download ready\n"); +fwdl_ready: + rtw_write32_clr(rtwdev, REG_MCUFW_CTRL, BIT_ROM_DLEN); + } else { + rtw_write8_clr(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + } +} + +void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) +{ + u32 val32; + u32 block_nr; + u32 remain_size; + u32 write_addr = FW_START_ADDR_LEGACY; + const __le32 *ptr = (const __le32 *)data; + u32 block; + __le32 remain_data = 0; + + block_nr = size >> DLFW_BLK_SIZE_SHIFT_LEGACY; + remain_size = size & (DLFW_BLK_SIZE_LEGACY - 1); + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 &= ~BIT_ROM_PGE; + val32 |= (page << BIT_SHIFT_ROM_PGE) & BIT_ROM_PGE; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + for (block = 0; block < block_nr; block++) { + rtw_write32(rtwdev, write_addr, le32_to_cpu(*ptr)); + + write_addr += DLFW_BLK_SIZE_LEGACY; + ptr++; + } + + if (remain_size) { + memcpy(&remain_data, ptr, remain_size); + rtw_write32(rtwdev, write_addr, le32_to_cpu(remain_data)); + } +} +EXPORT_SYMBOL(rtw_write_firmware_page); + +static int +download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size) +{ + u32 page; + u32 total_page; + u32 last_page_size; + + data += sizeof(struct rtw_fw_hdr_legacy); + size -= sizeof(struct rtw_fw_hdr_legacy); + + total_page = size >> DLFW_PAGE_SIZE_SHIFT_LEGACY; + last_page_size = size & (DLFW_PAGE_SIZE_LEGACY - 1); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT); + + for (page = 0; page < total_page; page++) { + rtw_hci_write_firmware_page(rtwdev, page, data, + DLFW_PAGE_SIZE_LEGACY); + data += DLFW_PAGE_SIZE_LEGACY; + } + if (last_page_size) + rtw_hci_write_firmware_page(rtwdev, page, data, + last_page_size); + + if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT, 1)) { + rtw_err(rtwdev, "failed to check download firmware report\n"); + return -EINVAL; + } + + return 0; +} + +static int download_firmware_validate_legacy(struct rtw_dev *rtwdev) +{ + u32 val32; + int try; + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 |= BIT_MCUFWDL_RDY; + val32 &= ~BIT_WINTINI_RDY; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + for (try = 0; try < 10; try++) { + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + if ((val32 & FW_READY_LEGACY) == FW_READY_LEGACY) + return 0; + msleep(20); + } + + rtw_err(rtwdev, "failed to validate firmware\n"); + return -EINVAL; +} + +static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + int ret = 0; + + /* reset firmware if still present */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && + rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) { + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); + } + + en_download_firmware_legacy(rtwdev, true); + ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size); + en_download_firmware_legacy(rtwdev, false); + if (ret) + goto out; + + ret = download_firmware_validate_legacy(rtwdev); + if (ret) + goto out; + + /* reset desc and index */ + rtw_hci_setup(rtwdev); + + rtwdev->h2c.last_box_num = 0; + rtwdev->h2c.seq = 0; + + set_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + +out: + return ret; +} + +static +int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_8051(rtwdev)) + return __rtw_download_firmware_legacy(rtwdev, fw); + + return __rtw_download_firmware(rtwdev, fw); +} + +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + int ret; + + ret = _rtw_download_firmware(rtwdev, fw); + if (ret) + return ret; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_fw_set_recover_bt_device(rtwdev); + + return 0; +} +EXPORT_SYMBOL(rtw_download_firmware); + +static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) +{ + const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn; + u32 prio_queues = 0; + + if (queues & BIT(IEEE80211_AC_VO)) + prio_queues |= BIT(rqpn->dma_map_vo); + if (queues & BIT(IEEE80211_AC_VI)) + prio_queues |= BIT(rqpn->dma_map_vi); + if (queues & BIT(IEEE80211_AC_BE)) + prio_queues |= BIT(rqpn->dma_map_be); + if (queues & BIT(IEEE80211_AC_BK)) + prio_queues |= BIT(rqpn->dma_map_bk); + + return prio_queues; +} + +static void __rtw_mac_flush_prio_queue(struct rtw_dev *rtwdev, + u32 prio_queue, bool drop) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_prioq_addr *addr; + bool wsize; + u16 avail_page, rsvd_page; + int i; + + if (prio_queue >= RTW_DMA_MAPPING_MAX) + return; + + addr = &chip->prioq_addrs->prio[prio_queue]; + wsize = chip->prioq_addrs->wsize; + + /* check if all of the reserved pages are available for 100 msecs */ + for (i = 0; i < 5; i++) { + rsvd_page = wsize ? rtw_read16(rtwdev, addr->rsvd) : + rtw_read8(rtwdev, addr->rsvd); + avail_page = wsize ? rtw_read16(rtwdev, addr->avail) : + rtw_read8(rtwdev, addr->avail); + if (rsvd_page == avail_page) + return; + + msleep(20); + } + + /* priority queue is still not empty, throw a debug message + * + * Note that if we want to flush the tx queue when having a lot of + * traffic (ex, 100Mbps up), some of the packets could be dropped. + * And it requires like ~2secs to flush the full priority queue. + */ + if (!drop) + rtw_dbg(rtwdev, RTW_DBG_UNEXP, + "timed out to flush queue %d\n", prio_queue); +} + +static void rtw_mac_flush_prio_queues(struct rtw_dev *rtwdev, + u32 prio_queues, bool drop) +{ + u32 q; + + for (q = 0; q < RTW_DMA_MAPPING_MAX; q++) + if (prio_queues & BIT(q)) + __rtw_mac_flush_prio_queue(rtwdev, q, drop); +} + +void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop) +{ + u32 prio_queues = 0; + + /* If all of the hardware queues are requested to flush, + * or the priority queues are not mapped yet, + * flush all of the priority queues + */ + if (queues == BIT(rtwdev->hw->queues) - 1 || !rtwdev->fifo.rqpn) + prio_queues = BIT(RTW_DMA_MAPPING_MAX) - 1; + else + prio_queues = get_priority_queues(rtwdev, queues); + + rtw_mac_flush_prio_queues(rtwdev, prio_queues, drop); +} + +static int txdma_queue_mapping(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_rqpn *rqpn = NULL; + u16 txdma_pq_map = 0; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rqpn = &chip->rqpn_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (rtwdev->hci.bulkout_num == 2) + rqpn = &chip->rqpn_table[2]; + else if (rtwdev->hci.bulkout_num == 3) + rqpn = &chip->rqpn_table[3]; + else if (rtwdev->hci.bulkout_num == 4) + rqpn = &chip->rqpn_table[4]; + else + return -EINVAL; + break; + case RTW_HCI_TYPE_SDIO: + rqpn = &chip->rqpn_table[0]; + break; + default: + return -EINVAL; + } + + rtwdev->fifo.rqpn = rqpn; + txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); + txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); + txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); + txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); + txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); + txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); + rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); + + rtw_write8(rtwdev, REG_CR, 0); + rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE); + if (rtw_chip_wcpu_3081(rtwdev)) + rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { + rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); + rtw_write32(rtwdev, REG_SDIO_TX_CTRL, 0); + } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN); + } + + return 0; +} + +int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + u16 cur_pg_addr; + u8 csi_buf_pg_num = chip->csi_buf_pg_num; + + /* config rsvd page num */ + fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; + fifo->txff_pg_num = chip->txff_size / chip->page_size; + if (rtw_chip_wcpu_8051(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + + RSVD_PG_H2C_EXTRAINFO_NUM + + RSVD_PG_H2C_STATICINFO_NUM + + RSVD_PG_H2CQ_NUM + + RSVD_PG_CPU_INSTRUCTION_NUM + + RSVD_PG_FW_TXBUF_NUM + + csi_buf_pg_num; + + if (fifo->rsvd_pg_num > fifo->txff_pg_num) + return -ENOMEM; + + fifo->acq_pg_num = fifo->txff_pg_num - fifo->rsvd_pg_num; + fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num; + + cur_pg_addr = fifo->txff_pg_num; + if (rtw_chip_wcpu_3081(rtwdev)) { + cur_pg_addr -= csi_buf_pg_num; + fifo->rsvd_csibuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; + fifo->rsvd_fw_txbuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM; + fifo->rsvd_cpu_instr_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2CQ_NUM; + fifo->rsvd_h2cq_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM; + fifo->rsvd_h2c_sta_info_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM; + fifo->rsvd_h2c_info_addr = cur_pg_addr; + } + cur_pg_addr -= fifo->rsvd_drv_pg_num; + fifo->rsvd_drv_addr = cur_pg_addr; + + if (fifo->rsvd_boundary != fifo->rsvd_drv_addr) { + rtw_err(rtwdev, "wrong rsvd driver address\n"); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(rtw_set_trx_fifo_info); + +static int __priority_queue_cfg(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, + u16 pubq_num) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, pg_tbl->hq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_2, pg_tbl->lq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_3, pg_tbl->nq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_4, pg_tbl->exq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_5, pubq_num); + rtw_write32_set(rtwdev, REG_RQPN_CTRL_2, BIT_LD_RQPN); + + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, fifo->rsvd_boundary); + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL + 2, BIT_EN_WR_FREE_TAIL >> 16); + + rtw_write16(rtwdev, REG_BCNQ_BDNY_V1, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); + rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); + + if (rtwdev->hci.type == RTW_HCI_TYPE_USB) { + rtw_write8_mask(rtwdev, REG_AUTO_LLT_V1, BIT_MASK_BLK_DESC_NUM, + chip->usb_tx_agg_desc_num); + + rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, chip->usb_tx_agg_desc_num); + rtw_write8_set(rtwdev, REG_TXDMA_OFFSET_CHK + 1, BIT(1)); + } + + rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) + return -EBUSY; + + rtw_write8(rtwdev, REG_CR + 3, 0); + + return 0; +} + +static int __priority_queue_cfg_legacy(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, + u16 pubq_num) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + u32 val32; + + val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); + rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); + rtw_write32(rtwdev, REG_RQPN, val32); + + rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, chip->rxff_size - REPORT_BUF - 1); + rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); + + rtw_write32_set(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT, 0)) + return -EBUSY; + + return 0; +} + +static int priority_queue_cfg(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + const struct rtw_page_table *pg_tbl = NULL; + u16 pubq_num; + int ret; + + ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) + return ret; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + pg_tbl = &chip->page_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (rtwdev->hci.bulkout_num == 2) + pg_tbl = &chip->page_table[2]; + else if (rtwdev->hci.bulkout_num == 3) + pg_tbl = &chip->page_table[3]; + else if (rtwdev->hci.bulkout_num == 4) + pg_tbl = &chip->page_table[4]; + else + return -EINVAL; + break; + case RTW_HCI_TYPE_SDIO: + pg_tbl = &chip->page_table[0]; + break; + default: + return -EINVAL; + } + + pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - + pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; + if (rtw_chip_wcpu_8051(rtwdev)) + return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num); + else + return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num); +} + +static int init_h2c(struct rtw_dev *rtwdev) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + u8 value8; + u32 value32; + u32 h2cq_addr; + u32 h2cq_size; + u32 h2cq_free; + u32 wp, rp; + + if (rtw_chip_wcpu_8051(rtwdev)) + return 0; + + h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT; + h2cq_size = RSVD_PG_H2CQ_NUM << TX_PAGE_SIZE_SHIFT; + + value32 = rtw_read32(rtwdev, REG_H2C_HEAD); + value32 = (value32 & 0xFFFC0000) | h2cq_addr; + rtw_write32(rtwdev, REG_H2C_HEAD, value32); + + value32 = rtw_read32(rtwdev, REG_H2C_READ_ADDR); + value32 = (value32 & 0xFFFC0000) | h2cq_addr; + rtw_write32(rtwdev, REG_H2C_READ_ADDR, value32); + + value32 = rtw_read32(rtwdev, REG_H2C_TAIL); + value32 &= 0xFFFC0000; + value32 |= (h2cq_addr + h2cq_size); + rtw_write32(rtwdev, REG_H2C_TAIL, value32); + + value8 = rtw_read8(rtwdev, REG_H2C_INFO); + value8 = (u8)((value8 & 0xFC) | 0x01); + rtw_write8(rtwdev, REG_H2C_INFO, value8); + + value8 = rtw_read8(rtwdev, REG_H2C_INFO); + value8 = (u8)((value8 & 0xFB) | 0x04); + rtw_write8(rtwdev, REG_H2C_INFO, value8); + + value8 = rtw_read8(rtwdev, REG_TXDMA_OFFSET_CHK + 1); + value8 = (u8)((value8 & 0x7f) | 0x80); + rtw_write8(rtwdev, REG_TXDMA_OFFSET_CHK + 1, value8); + + wp = rtw_read32(rtwdev, REG_H2C_PKT_WRITEADDR) & 0x3FFFF; + rp = rtw_read32(rtwdev, REG_H2C_PKT_READADDR) & 0x3FFFF; + h2cq_free = wp >= rp ? h2cq_size - (wp - rp) : rp - wp; + + if (h2cq_size != h2cq_free) { + rtw_err(rtwdev, "H2C queue mismatch\n"); + return -EINVAL; + } + + return 0; +} + +static int rtw_init_trx_cfg(struct rtw_dev *rtwdev) +{ + int ret; + + ret = txdma_queue_mapping(rtwdev); + if (ret) + return ret; + + ret = priority_queue_cfg(rtwdev); + if (ret) + return ret; + + ret = init_h2c(rtwdev); + if (ret) + return ret; + + return 0; +} + +static int rtw_drv_info_cfg(struct rtw_dev *rtwdev) +{ + u8 value8; + + rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); + if (rtw_chip_wcpu_3081(rtwdev)) { + value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); + value8 &= 0xF0; + /* For rxdesc len = 0 issue */ + value8 |= 0xF; + rtw_write8(rtwdev, REG_TRXFF_BNDY + 1, value8); + } + rtw_write32_set(rtwdev, REG_RCR, BIT_APP_PHYSTS); + rtw_write32_clr(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, BIT(8) | BIT(9)); + + return 0; +} + +int rtw_mac_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + int ret; + + ret = rtw_init_trx_cfg(rtwdev); + if (ret) + return ret; + + ret = chip->ops->mac_init(rtwdev); + if (ret) + return ret; + + ret = rtw_drv_info_cfg(rtwdev); + if (ret) + return ret; + + rtw_hci_interface_cfg(rtwdev); + + return 0; +} + +int rtw_mac_postinit(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (!chip->ops->mac_postinit) + return 0; + + return chip->ops->mac_postinit(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h new file mode 100644 index 000000000..b73af90ee --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/mac.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_MAC_H__ +#define __RTW_MAC_H__ + +#define RTW_HW_PORT_NUM 5 +#define cut_version_to_mask(cut) (0x1 << ((cut) + 1)) +#define DDMA_POLLING_COUNT 1000 +#define C2H_PKT_BUF 256 +#define REPORT_BUF 128 +#define PHY_STATUS_SIZE 4 +#define ILLEGAL_KEY_GROUP 0xFAAAAA00 + +/* HW memory address */ +#define OCPBASE_RXBUF_FW_88XX 0x18680000 +#define OCPBASE_TXBUF_88XX 0x18780000 +#define OCPBASE_ROM_88XX 0x00000000 +#define OCPBASE_IMEM_88XX 0x00030000 +#define OCPBASE_DMEM_88XX 0x00200000 +#define OCPBASE_EMEM_88XX 0x00100000 + +#define RSVD_PG_DRV_NUM 16 +#define RSVD_PG_H2C_EXTRAINFO_NUM 24 +#define RSVD_PG_H2C_STATICINFO_NUM 8 +#define RSVD_PG_H2CQ_NUM 8 +#define RSVD_PG_CPU_INSTRUCTION_NUM 0 +#define RSVD_PG_FW_TXBUF_NUM 4 + +void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx); +int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd * const *cmd_seq); +int rtw_mac_power_on(struct rtw_dev *rtwdev); +void rtw_mac_power_off(struct rtw_dev *rtwdev); +void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size); +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); +int rtw_mac_init(struct rtw_dev *rtwdev); +int rtw_mac_postinit(struct rtw_dev *rtwdev); +void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); +int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev); +int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size); + +static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +{ + rtw_mac_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, drop); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c new file mode 100644 index 000000000..b01b98d24 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -0,0 +1,997 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "sec.h" +#include "tx.h" +#include "fw.h" +#include "mac.h" +#include "coex.h" +#include "ps.h" +#include "reg.h" +#include "bf.h" +#include "debug.h" +#include "wow.h" +#include "sar.h" + +static void rtw_ops_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtw_dev *rtwdev = hw->priv; + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) { + ieee80211_free_txskb(hw, skb); + return; + } + + rtw_tx(rtwdev, control, skb); +} + +static void rtw_ops_wake_tx_queue(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv; + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + return; + + spin_lock_bh(&rtwdev->txq_lock); + if (list_empty(&rtwtxq->list)) + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + + /* ensure to dequeue EAPOL (4/4) at the right time */ + if (txq->ac == IEEE80211_AC_VO) + __rtw_tx_work(rtwdev); + else + queue_work(rtwdev->tx_wq, &rtwdev->tx_work); +} + +static int rtw_ops_start(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + mutex_lock(&rtwdev->mutex); + ret = rtw_core_start(rtwdev); + mutex_unlock(&rtwdev->mutex); + + return ret; +} + +static void rtw_ops_stop(struct ieee80211_hw *hw, bool suspend) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_core_stop(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret = 0; + + /* let previous ips work finish to ensure we don't leave ips twice */ + cancel_work_sync(&rtwdev->ips_work); + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + !(hw->conf.flags & IEEE80211_CONF_IDLE)) { + ret = rtw_leave_ips(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave idle state\n"); + goto out; + } + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) + rtw_set_channel(rtwdev); + + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (hw->conf.flags & IEEE80211_CONF_IDLE) && + !test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtw_enter_ips(rtwdev); + +out: + mutex_unlock(&rtwdev->mutex); + return ret; +} + +static const struct rtw_vif_port rtw_vif_port[] = { + [0] = { + .mac_addr = {.addr = 0x0610}, + .bssid = {.addr = 0x0618}, + .net_type = {.addr = 0x0100, .mask = 0x30000}, + .aid = {.addr = 0x06a8, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0550, .mask = 0xff}, + }, + [1] = { + .mac_addr = {.addr = 0x0700}, + .bssid = {.addr = 0x0708}, + .net_type = {.addr = 0x0100, .mask = 0xc0000}, + .aid = {.addr = 0x0710, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0551, .mask = 0xff}, + }, + [2] = { + .mac_addr = {.addr = 0x1620}, + .bssid = {.addr = 0x1628}, + .net_type = {.addr = 0x1100, .mask = 0x3}, + .aid = {.addr = 0x1600, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0578, .mask = 0xff}, + }, + [3] = { + .mac_addr = {.addr = 0x1630}, + .bssid = {.addr = 0x1638}, + .net_type = {.addr = 0x1100, .mask = 0xc}, + .aid = {.addr = 0x1604, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0579, .mask = 0xff}, + }, + [4] = { + .mac_addr = {.addr = 0x1640}, + .bssid = {.addr = 0x1648}, + .net_type = {.addr = 0x1100, .mask = 0x30}, + .aid = {.addr = 0x1608, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x057a, .mask = 0xff}, + }, +}; + +static int rtw_ops_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + enum rtw_net_type net_type; + u32 config = 0; + u8 port; + u8 bcn_ctrl = 0; + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER)) + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + rtwvif->stats.tx_unicast = 0; + rtwvif->stats.rx_unicast = 0; + rtwvif->stats.tx_cnt = 0; + rtwvif->stats.rx_cnt = 0; + rtwvif->scan_req = NULL; + memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee)); + rtw_txq_init(rtwdev, vif->txq); + INIT_LIST_HEAD(&rtwvif->rsvd_page_list); + + mutex_lock(&rtwdev->mutex); + + rtwvif->mac_id = rtw_acquire_macid(rtwdev); + if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) { + mutex_unlock(&rtwdev->mutex); + return -ENOSPC; + } + + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); + if (port >= RTW_PORT_NUM) { + mutex_unlock(&rtwdev->mutex); + return -EINVAL; + } + set_bit(port, rtwdev->hw_port); + + rtwvif->port = port; + rtwvif->conf = &rtw_vif_port[port]; + rtw_leave_lps_deep(rtwdev); + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: + rtw_add_rsvd_page_bcn(rtwdev, rtwvif); + net_type = RTW_NET_AP_MODE; + bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; + break; + case NL80211_IFTYPE_ADHOC: + rtw_add_rsvd_page_bcn(rtwdev, rtwvif); + net_type = RTW_NET_AD_HOC; + bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; + break; + case NL80211_IFTYPE_STATION: + rtw_add_rsvd_page_sta(rtwdev, rtwvif); + net_type = RTW_NET_NO_LINK; + bcn_ctrl = BIT_EN_BCN_FUNCTION; + break; + default: + WARN_ON(1); + clear_bit(rtwvif->port, rtwdev->hw_port); + mutex_unlock(&rtwdev->mutex); + return -EINVAL; + } + + ether_addr_copy(rtwvif->mac_addr, vif->addr); + config |= PORT_SET_MAC_ADDR; + rtwvif->net_type = net_type; + config |= PORT_SET_NET_TYPE; + rtwvif->bcn_ctrl = bcn_ctrl; + config |= PORT_SET_BCN_CTRL; + rtw_vif_port_config(rtwdev, rtwvif, config); + rtw_core_port_switch(rtwdev, vif); + rtw_recalc_lps(rtwdev, vif); + + mutex_unlock(&rtwdev->mutex); + + rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n", + vif->addr, rtwvif->mac_id, rtwvif->port); + return 0; +} + +static void rtw_ops_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + u32 config = 0; + + rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n", + vif->addr, rtwvif->mac_id, rtwvif->port); + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + rtw_txq_cleanup(rtwdev, vif->txq); + rtw_remove_rsvd_page(rtwdev, rtwvif); + + eth_zero_addr(rtwvif->mac_addr); + config |= PORT_SET_MAC_ADDR; + rtwvif->net_type = RTW_NET_NO_LINK; + config |= PORT_SET_NET_TYPE; + rtwvif->bcn_ctrl = 0; + config |= PORT_SET_BCN_CTRL; + rtw_vif_port_config(rtwdev, rtwvif, config); + clear_bit(rtwvif->port, rtwdev->hw_port); + rtw_release_macid(rtwdev, rtwvif->mac_id); + rtw_recalc_lps(rtwdev, NULL); + + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype type, bool p2p) +{ + struct rtw_dev *rtwdev = hw->priv; + + rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", + vif->addr, vif->type, type, vif->p2p, p2p); + + rtw_ops_remove_interface(hw, vif); + + vif->type = type; + vif->p2p = p2p; + + return rtw_ops_add_interface(hw, vif); +} + +static void rtw_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct rtw_dev *rtwdev = hw->priv; + + *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | + FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + if (changed_flags & FIF_CONTROL) { + if (*new_flags & FIF_CONTROL) + rtw_write16(rtwdev, REG_RXFLTMAP1, 0xffff); + else + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + } + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) + rtwdev->hal.rcr |= BIT_AM; + else + rtwdev->hal.rcr &= ~(BIT_AM); + } + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) + rtwdev->hal.rcr |= BIT_ACRC32; + else + rtwdev->hal.rcr &= ~(BIT_ACRC32); + } + if (changed_flags & FIF_OTHER_BSS) { + if (*new_flags & FIF_OTHER_BSS) + rtwdev->hal.rcr |= BIT_AAP; + else + rtwdev->hal.rcr &= ~(BIT_AAP); + } + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) + rtwdev->hal.rcr &= ~(BIT_CBSSID_BCN | BIT_CBSSID_DATA); + else + rtwdev->hal.rcr |= BIT_CBSSID_BCN; + } + + rtw_dbg(rtwdev, RTW_DBG_RX, + "config rx filter, changed=0x%08x, new=0x%08x, rcr=0x%08x\n", + changed_flags, *new_flags, rtwdev->hal.rcr); + + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); + + mutex_unlock(&rtwdev->mutex); +} + +/* Only have one group of EDCA parameters now */ +static const u32 ac_to_edca_param[IEEE80211_NUM_ACS] = { + [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM, + [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM, + [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM, + [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM, +}; + +static u8 rtw_aifsn_to_aifs(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, u8 aifsn) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 slot_time; + u8 sifs; + + slot_time = vif->bss_conf.use_short_slot ? 9 : 20; + sifs = rtwdev->hal.current_band_type == RTW_BAND_5G ? 16 : 10; + + return aifsn * slot_time + sifs; +} + +static void __rtw_conf_tx(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, u16 ac) +{ + struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; + u32 edca_param = ac_to_edca_param[ac]; + u8 ecw_max, ecw_min; + u8 aifs; + + /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ + ecw_max = ilog2(params->cw_max + 1); + ecw_min = ilog2(params->cw_min + 1); + aifs = rtw_aifsn_to_aifs(rtwdev, rtwvif, params->aifs); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_TXOP_LMT, params->txop); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMAX, ecw_max); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMIN, ecw_min); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_AIFS, aifs); +} + +static void rtw_conf_tx(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + u16 ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + __rtw_conf_tx(rtwdev, rtwvif, ac); +} + +static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf, + u64 changed) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u32 config = 0; + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + if (changed & BSS_CHANGED_ASSOC) { + rtw_vif_assoc_changed(rtwvif, conf); + if (vif->cfg.assoc) { + rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH); + + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); + rtw_fw_default_port(rtwdev, rtwvif); + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); + + rtw_set_ampdu_factor(rtwdev, vif, conf); + + rtw_fw_beacon_filter_config(rtwdev, true, vif); + } else { + rtw_leave_lps(rtwdev); + rtw_bf_disassoc(rtwdev, vif, conf); + /* Abort ongoing scan if cancel_scan isn't issued + * when disconnected by peer + */ + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtw_hw_scan_abort(rtwdev); + + } + + config |= PORT_SET_NET_TYPE; + config |= PORT_SET_AID; + } + + if (changed & BSS_CHANGED_BSSID) { + ether_addr_copy(rtwvif->bssid, conf->bssid); + config |= PORT_SET_BSSID; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); + else + rtw_store_op_chan(rtwdev, true); + } + + if (changed & BSS_CHANGED_BEACON_INT) { + if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION) + coex_stat->wl_beacon_interval = conf->beacon_int; + } + + if (changed & BSS_CHANGED_BEACON) { + rtw_set_dtim_period(rtwdev, conf->dtim_period); + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); + } + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + if (conf->enable_beacon) + rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, + BIT_EN_BCNQ_DL); + else + rtw_write32_clr(rtwdev, REG_FWHW_TXQ_CTRL, + BIT_EN_BCNQ_DL); + } + if (changed & BSS_CHANGED_CQM) + rtw_fw_beacon_filter_config(rtwdev, true, vif); + + if (changed & BSS_CHANGED_MU_GROUPS) + rtw_chip_set_gid_table(rtwdev, vif, conf); + + if (changed & BSS_CHANGED_ERP_SLOT) + rtw_conf_tx(rtwdev, rtwvif); + + if (changed & BSS_CHANGED_PS) + rtw_recalc_lps(rtwdev, NULL); + + rtw_vif_port_config(rtwdev, rtwvif, config); + + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_start_ap(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + + mutex_lock(&rtwdev->mutex); + rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = true; + rtw_store_op_chan(rtwdev, true); + chip->ops->phy_calibration(rtwdev); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static void rtw_ops_stop_ap(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = false; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + rtwvif->tx_params[ac] = *params; + __rtw_conf_tx(rtwdev, rtwvif, ac); + + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static int rtw_ops_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret = 0; + + mutex_lock(&rtwdev->mutex); + ret = rtw_sta_add(rtwdev, sta, vif); + mutex_unlock(&rtwdev->mutex); + + return ret; +} + +static int rtw_ops_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_fw_beacon_filter_config(rtwdev, false, vif); + rtw_sta_remove(rtwdev, sta, true); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static int rtw_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtw_dev *rtwdev = hw->priv; + + ieee80211_queue_work(hw, &rtwdev->update_beacon_work); + + return 0; +} + +static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_sec_desc *sec = &rtwdev->sec; + u8 hw_key_type; + u8 hw_key_idx; + int ret = 0; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + hw_key_type = RTW_CAM_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + hw_key_type = RTW_CAM_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + hw_key_type = RTW_CAM_TKIP; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + case WLAN_CIPHER_SUITE_CCMP: + hw_key_type = RTW_CAM_AES; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + case WLAN_CIPHER_SUITE_BIP_CMAC_256: + case WLAN_CIPHER_SUITE_BIP_GMAC_128: + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + /* suppress error messages */ + return -EOPNOTSUPP; + default: + return -ENOTSUPP; + } + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + hw_key_idx = rtw_sec_get_free_cam(sec); + } else { + /* multiple interfaces? */ + hw_key_idx = key->keyidx; + } + + if (hw_key_idx > sec->total_cam_num) { + ret = -ENOSPC; + goto out; + } + + switch (cmd) { + case SET_KEY: + /* need sw generated IV */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + key->hw_key_idx = hw_key_idx; + rtw_sec_write_cam(rtwdev, sec, sta, key, + hw_key_type, hw_key_idx); + break; + case DISABLE_KEY: + rtw_hci_flush_all_queues(rtwdev, false); + rtw_mac_flush_all_queues(rtwdev, false); + rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx); + break; + } + + /* download new cam settings for PG to backup */ + if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG) + rtw_fw_download_rsvd_page(rtwdev); + +out: + mutex_unlock(&rtwdev->mutex); + + return ret; +} + +static int rtw_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + struct ieee80211_sta *sta = params->sta; + u16 tid = params->tid; + struct ieee80211_txq *txq = sta->txq[tid]; + struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv; + + switch (params->action) { + case IEEE80211_AMPDU_TX_START: + return IEEE80211_AMPDU_TX_START_IMMEDIATE; + case IEEE80211_AMPDU_TX_STOP_CONT: + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + clear_bit(RTW_TXQ_AMPDU, &rtwtxq->flags); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + set_bit(RTW_TXQ_AMPDU, &rtwtxq->flags); + break; + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + break; + default: + WARN_ON(1); + return -ENOTSUPP; + } + + return 0; +} + +static bool rtw_ops_can_aggregate_in_amsdu(struct ieee80211_hw *hw, + struct sk_buff *head, + struct sk_buff *skb) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_hal *hal = &rtwdev->hal; + + /* we don't want to enable TX AMSDU on 2.4G */ + if (hal->current_band_type == RTW_BAND_2G) + return false; + + return true; +} + +static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + mutex_lock(&rtwdev->mutex); + rtw_core_scan_start(rtwdev, rtwvif, mac_addr, false); + mutex_unlock(&rtwdev->mutex); +} + +static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_core_scan_complete(rtwdev, vif, false); + mutex_unlock(&rtwdev->mutex); +} + +static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_prep_tx_info *info) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START); + rtw_chip_prepare_tx(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, + u32 value) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtwdev->rts_threshold = value; + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static void rtw_ops_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + sinfo->txrate = si->ra_report.txrate; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +} + +static void rtw_ops_flush(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 queues, bool drop) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + + rtw_hci_flush_queues(rtwdev, queues, drop); + rtw_mac_flush_queues(rtwdev, queues, drop); + mutex_unlock(&rtwdev->mutex); +} + +struct rtw_iter_bitrate_mask_data { + struct rtw_dev *rtwdev; + struct ieee80211_vif *vif; + const struct cfg80211_bitrate_mask *mask; +}; + +static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_iter_bitrate_mask_data *br_data = data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + if (si->vif != br_data->vif) + return; + + /* free previous mask setting */ + kfree(si->mask); + si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask), + GFP_ATOMIC); + if (!si->mask) { + si->use_cfg_mask = false; + return; + } + + si->use_cfg_mask = true; + rtw_update_sta_info(br_data->rtwdev, si, true); +} + +static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_iter_bitrate_mask_data br_data; + + br_data.rtwdev = rtwdev; + br_data.vif = vif; + br_data.mask = mask; + rtw_iterate_stas(rtwdev, rtw_ra_mask_info_update_iter, &br_data); +} + +static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_ra_mask_info_update(rtwdev, vif, mask); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static int rtw_ops_set_antenna(struct ieee80211_hw *hw, + int radio_idx, + u32 tx_antenna, + u32 rx_antenna) +{ + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + int ret; + + if (!chip->ops->set_antenna) + return -EOPNOTSUPP; + + mutex_lock(&rtwdev->mutex); + ret = chip->ops->set_antenna(rtwdev, -1, tx_antenna, rx_antenna); + mutex_unlock(&rtwdev->mutex); + + return ret; +} + +static int rtw_ops_get_antenna(struct ieee80211_hw *hw, + int radio_idx, + u32 *tx_antenna, + u32 *rx_antenna) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_hal *hal = &rtwdev->hal; + + *tx_antenna = hal->antenna_tx; + *rx_antenna = hal->antenna_rx; + + return 0; +} + +#ifdef CONFIG_PM +static int rtw_ops_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + mutex_lock(&rtwdev->mutex); + ret = rtw_wow_suspend(rtwdev, wowlan); + if (ret) + rtw_err(rtwdev, "failed to suspend for wow %d\n", ret); + mutex_unlock(&rtwdev->mutex); + + return ret ? 1 : 0; +} + +static int rtw_ops_resume(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + mutex_lock(&rtwdev->mutex); + ret = rtw_wow_resume(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to resume for wow %d\n", ret); + mutex_unlock(&rtwdev->mutex); + + return ret ? 1 : 0; +} + +static void rtw_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct rtw_dev *rtwdev = hw->priv; + + device_set_wakeup_enable(rtwdev->dev, enabled); +} +#endif + +static void rtw_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART) + clear_bit(RTW_FLAG_RESTARTING, rtwdev->flags); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *req) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) + return 1; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + return -EBUSY; + + mutex_lock(&rtwdev->mutex); + rtw_hw_scan_start(rtwdev, vif, req); + ret = rtw_hw_scan_offload(rtwdev, vif, true); + if (ret) { + rtw_hw_scan_abort(rtwdev); + rtw_err(rtwdev, "HW scan failed with status: %d\n", ret); + } + mutex_unlock(&rtwdev->mutex); + + return ret; +} + +static void rtw_ops_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = hw->priv; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) + return; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + return; + + mutex_lock(&rtwdev->mutex); + rtw_hw_scan_abort(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_set_sar_specs(rtwdev, sar); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed) +{ + struct ieee80211_sta *sta = link_sta->sta; + struct rtw_dev *rtwdev = hw->priv; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + if (changed & IEEE80211_RC_BW_CHANGED) + ieee80211_queue_work(rtwdev->hw, &si->rc_work); +} + +const struct ieee80211_ops rtw_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .tx = rtw_ops_tx, + .wake_tx_queue = rtw_ops_wake_tx_queue, + .start = rtw_ops_start, + .stop = rtw_ops_stop, + .config = rtw_ops_config, + .add_interface = rtw_ops_add_interface, + .remove_interface = rtw_ops_remove_interface, + .change_interface = rtw_ops_change_interface, + .configure_filter = rtw_ops_configure_filter, + .bss_info_changed = rtw_ops_bss_info_changed, + .start_ap = rtw_ops_start_ap, + .stop_ap = rtw_ops_stop_ap, + .conf_tx = rtw_ops_conf_tx, + .sta_add = rtw_ops_sta_add, + .sta_remove = rtw_ops_sta_remove, + .set_tim = rtw_ops_set_tim, + .set_key = rtw_ops_set_key, + .ampdu_action = rtw_ops_ampdu_action, + .can_aggregate_in_amsdu = rtw_ops_can_aggregate_in_amsdu, + .sw_scan_start = rtw_ops_sw_scan_start, + .sw_scan_complete = rtw_ops_sw_scan_complete, + .mgd_prepare_tx = rtw_ops_mgd_prepare_tx, + .set_rts_threshold = rtw_ops_set_rts_threshold, + .sta_statistics = rtw_ops_sta_statistics, + .flush = rtw_ops_flush, + .set_bitrate_mask = rtw_ops_set_bitrate_mask, + .set_antenna = rtw_ops_set_antenna, + .get_antenna = rtw_ops_get_antenna, + .reconfig_complete = rtw_reconfig_complete, + .hw_scan = rtw_ops_hw_scan, + .cancel_hw_scan = rtw_ops_cancel_hw_scan, + .link_sta_rc_update = rtw_ops_sta_rc_update, + .set_sar_specs = rtw_ops_set_sar_specs, +#ifdef CONFIG_PM + .suspend = rtw_ops_suspend, + .resume = rtw_ops_resume, + .set_wakeup = rtw_ops_set_wakeup, +#endif +}; +EXPORT_SYMBOL(rtw_ops); diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c new file mode 100644 index 000000000..cd9254370 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -0,0 +1,2514 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include + +#include "main.h" +#include "regd.h" +#include "fw.h" +#include "ps.h" +#include "sec.h" +#include "mac.h" +#include "coex.h" +#include "phy.h" +#include "reg.h" +#include "efuse.h" +#include "tx.h" +#include "debug.h" +#include "bf.h" +#include "sar.h" +#include "sdio.h" +#include "led.h" + +bool rtw_disable_lps_deep_mode; +EXPORT_SYMBOL(rtw_disable_lps_deep_mode); +bool rtw_bf_support = true; +unsigned int rtw_debug_mask; +EXPORT_SYMBOL(rtw_debug_mask); +/* EDCCA is enabled during normal behavior. For debugging purpose in + * a noisy environment, it can be disabled via edcca debugfs. Because + * all rtw88 devices will probably be affected if environment is noisy, + * rtw_edcca_enabled is just declared by driver instead of by device. + * So, turning it off will take effect for all rtw88 devices before + * there is a tough reason to maintain rtw_edcca_enabled by device. + */ +bool rtw_edcca_enabled = true; + +module_param_named(disable_lps_deep, rtw_disable_lps_deep_mode, bool, 0644); +module_param_named(support_bf, rtw_bf_support, bool, 0644); +module_param_named(debug_mask, rtw_debug_mask, uint, 0644); + +MODULE_PARM_DESC(disable_lps_deep, "Set Y to disable Deep PS"); +MODULE_PARM_DESC(support_bf, "Set Y to enable beamformee support"); +MODULE_PARM_DESC(debug_mask, "Debugging mask"); + +static struct ieee80211_channel rtw_channeltable_2g[] = { + {.center_freq = 2412, .hw_value = 1,}, + {.center_freq = 2417, .hw_value = 2,}, + {.center_freq = 2422, .hw_value = 3,}, + {.center_freq = 2427, .hw_value = 4,}, + {.center_freq = 2432, .hw_value = 5,}, + {.center_freq = 2437, .hw_value = 6,}, + {.center_freq = 2442, .hw_value = 7,}, + {.center_freq = 2447, .hw_value = 8,}, + {.center_freq = 2452, .hw_value = 9,}, + {.center_freq = 2457, .hw_value = 10,}, + {.center_freq = 2462, .hw_value = 11,}, + {.center_freq = 2467, .hw_value = 12,}, + {.center_freq = 2472, .hw_value = 13,}, + {.center_freq = 2484, .hw_value = 14,}, +}; + +static struct ieee80211_channel rtw_channeltable_5g[] = { + {.center_freq = 5180, .hw_value = 36,}, + {.center_freq = 5200, .hw_value = 40,}, + {.center_freq = 5220, .hw_value = 44,}, + {.center_freq = 5240, .hw_value = 48,}, + {.center_freq = 5260, .hw_value = 52,}, + {.center_freq = 5280, .hw_value = 56,}, + {.center_freq = 5300, .hw_value = 60,}, + {.center_freq = 5320, .hw_value = 64,}, + {.center_freq = 5500, .hw_value = 100,}, + {.center_freq = 5520, .hw_value = 104,}, + {.center_freq = 5540, .hw_value = 108,}, + {.center_freq = 5560, .hw_value = 112,}, + {.center_freq = 5580, .hw_value = 116,}, + {.center_freq = 5600, .hw_value = 120,}, + {.center_freq = 5620, .hw_value = 124,}, + {.center_freq = 5640, .hw_value = 128,}, + {.center_freq = 5660, .hw_value = 132,}, + {.center_freq = 5680, .hw_value = 136,}, + {.center_freq = 5700, .hw_value = 140,}, + {.center_freq = 5720, .hw_value = 144,}, + {.center_freq = 5745, .hw_value = 149,}, + {.center_freq = 5765, .hw_value = 153,}, + {.center_freq = 5785, .hw_value = 157,}, + {.center_freq = 5805, .hw_value = 161,}, + {.center_freq = 5825, .hw_value = 165, + .flags = IEEE80211_CHAN_NO_HT40MINUS}, +}; + +static struct ieee80211_rate rtw_ratetable[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static const struct ieee80211_iface_limit rtw_iface_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + } +}; + +static const struct ieee80211_iface_combination rtw_iface_combs[] = { + { + .limits = rtw_iface_limits, + .n_limits = ARRAY_SIZE(rtw_iface_limits), + .max_interfaces = 2, + .num_different_channels = 1, + } +}; + +u16 rtw_desc_to_bitrate(u8 desc_rate) +{ + struct ieee80211_rate rate; + + if (WARN(desc_rate >= ARRAY_SIZE(rtw_ratetable), "invalid desc rate\n")) + return 0; + + rate = rtw_ratetable[desc_rate]; + + return rate.bitrate; +} + +static const struct ieee80211_supported_band rtw_band_2ghz = { + .band = NL80211_BAND_2GHZ, + + .channels = rtw_channeltable_2g, + .n_channels = ARRAY_SIZE(rtw_channeltable_2g), + + .bitrates = rtw_ratetable, + .n_bitrates = ARRAY_SIZE(rtw_ratetable), + + .ht_cap = {0}, + .vht_cap = {0}, +}; + +static const struct ieee80211_supported_band rtw_band_5ghz = { + .band = NL80211_BAND_5GHZ, + + .channels = rtw_channeltable_5g, + .n_channels = ARRAY_SIZE(rtw_channeltable_5g), + + /* 5G has no CCK rates */ + .bitrates = rtw_ratetable + 4, + .n_bitrates = ARRAY_SIZE(rtw_ratetable) - 4, + + .ht_cap = {0}, + .vht_cap = {0}, +}; + +struct rtw_watch_dog_iter_data { + struct rtw_dev *rtwdev; + struct rtw_vif *rtwvif; +}; + +static void rtw_dynamic_csi_rate(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +{ + struct rtw_bf_info *bf_info = &rtwdev->bf_info; + u8 fix_rate_enable = 0; + u8 new_csi_rate_idx; + + if (rtwvif->bfee.role != RTW_BFEE_SU && + rtwvif->bfee.role != RTW_BFEE_MU) + return; + + rtw_chip_cfg_csi_rate(rtwdev, rtwdev->dm_info.min_rssi, + bf_info->cur_csi_rpt_rate, + fix_rate_enable, &new_csi_rate_idx); + + if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate) + bf_info->cur_csi_rpt_rate = new_csi_rate_idx; +} + +static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif) +{ + struct rtw_watch_dog_iter_data *iter_data = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + if (vif->type == NL80211_IFTYPE_STATION) + if (vif->cfg.assoc) + iter_data->rtwvif = rtwvif; + + rtw_dynamic_csi_rate(iter_data->rtwdev, rtwvif); + + rtwvif->stats.tx_unicast = 0; + rtwvif->stats.rx_unicast = 0; + rtwvif->stats.tx_cnt = 0; + rtwvif->stats.rx_cnt = 0; +} + +static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, int received_beacons) +{ + int watchdog_delay = 2000000 / 1024; /* TU */ + int beacon_int, expected_beacons; + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif) + return; + + beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int; + expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int); + + rtwdev->beacon_loss = received_beacons < expected_beacons / 2; +} + +/* process TX/RX statistics periodically for hardware, + * the information helps hardware to enhance performance + */ +static void rtw_watch_dog_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + watch_dog_work.work); + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_watch_dog_iter_data data = {}; + bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt; + u32 tx_unicast_mbps, rx_unicast_mbps; + bool ps_active; + + mutex_lock(&rtwdev->mutex); + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + goto unlock; + + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, + RTW_WATCH_DOG_DELAY_TIME); + + if (rtwdev->stats.tx_cnt > 100 || rtwdev->stats.rx_cnt > 100) + set_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + else + clear_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + + if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags)) + rtw_coex_wl_status_change_notify(rtwdev, 0); + + if (stats->tx_cnt > RTW_LPS_THRESHOLD || + stats->rx_cnt > RTW_LPS_THRESHOLD) + ps_active = true; + else + ps_active = false; + + tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT; + rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT; + + ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps); + ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps); + stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); + stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); + + /* reset tx/rx statictics */ + stats->tx_unicast = 0; + stats->rx_unicast = 0; + stats->tx_cnt = 0; + stats->rx_cnt = 0; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + goto unlock; + + /* make sure BB/RF is working for dynamic mech */ + rtw_leave_lps(rtwdev); + rtw_coex_wl_status_check(rtwdev); + rtw_coex_query_bt_hid_list(rtwdev); + rtw_coex_active_query_bt_info(rtwdev); + + rtw_phy_dynamic_mechanism(rtwdev); + + rtw_hci_dynamic_rx_agg(rtwdev, + tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1); + + data.rtwdev = rtwdev; + /* rtw_iterate_vifs internally uses an atomic iterator which is needed + * to avoid taking local->iflist_mtx mutex + */ + rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); + + rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons); + + /* fw supports only one station associated to enter lps, if there are + * more than two stations associated to the AP, then we can not enter + * lps, because fw does not handle the overlapped beacon interval + * + * rtw_recalc_lps() iterate vifs and determine if driver can enter + * ps by vif->type and vif->cfg.ps, all we need to do here is to + * get that vif and check if device is having traffic more than the + * threshold. + */ + if (rtwdev->ps_enabled && data.rtwvif && !ps_active && + !rtwdev->beacon_loss && !rtwdev->ap_active) + rtw_enter_lps(rtwdev, data.rtwvif->port); + + rtwdev->watch_dog_cnt++; + +unlock: + mutex_unlock(&rtwdev->mutex); +} + +static void rtw_c2h_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, c2h_work); + struct sk_buff *skb, *tmp; + + skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { + skb_unlink(skb, &rtwdev->c2h_queue); + rtw_fw_c2h_cmd_handle(rtwdev, skb); + dev_kfree_skb_any(skb); + } +} + +static void rtw_ips_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work); + + mutex_lock(&rtwdev->mutex); + if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE) + rtw_enter_ips(rtwdev); + mutex_unlock(&rtwdev->mutex); +} + +static void rtw_sta_rc_work(struct work_struct *work) +{ + struct rtw_sta_info *si = container_of(work, struct rtw_sta_info, + rc_work); + struct rtw_dev *rtwdev = si->rtwdev; + + mutex_lock(&rtwdev->mutex); + rtw_update_sta_info(rtwdev, si, true); + mutex_unlock(&rtwdev->mutex); +} + +int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + struct ieee80211_vif *vif) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + si->mac_id = rtwvif->mac_id; + } else { + si->mac_id = rtw_acquire_macid(rtwdev); + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + } + + si->rtwdev = rtwdev; + si->sta = sta; + si->vif = vif; + si->init_ra_lv = 1; + ewma_rssi_init(&si->avg_rssi); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw_txq_init(rtwdev, sta->txq[i]); + INIT_WORK(&si->rc_work, rtw_sta_rc_work); + + rtw_update_sta_info(rtwdev, si, true); + rtw_fw_media_status_report(rtwdev, si->mac_id, true); + + rtwdev->sta_cnt++; + rtwdev->beacon_loss = false; + rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM joined with macid %d\n", + sta->addr, si->mac_id); + + return 0; +} + +void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + bool fw_exist) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct ieee80211_vif *vif = si->vif; + int i; + + cancel_work_sync(&si->rc_work); + + if (vif->type != NL80211_IFTYPE_STATION || sta->tdls) + rtw_release_macid(rtwdev, si->mac_id); + if (fw_exist) + rtw_fw_media_status_report(rtwdev, si->mac_id, false); + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw_txq_cleanup(rtwdev, sta->txq[i]); + + kfree(si->mask); + + rtwdev->sta_cnt--; + rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM with macid %d left\n", + sta->addr, si->mac_id); +} + +struct rtw_fwcd_hdr { + u32 item; + u32 size; + u32 padding1; + u32 padding2; +} __packed; + +static int rtw_fwcd_prep(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; + const struct rtw_fwcd_segs *segs = chip->fwcd_segs; + u32 prep_size = chip->fw_rxff_size + sizeof(struct rtw_fwcd_hdr); + u8 i; + + if (segs) { + prep_size += segs->num * sizeof(struct rtw_fwcd_hdr); + + for (i = 0; i < segs->num; i++) + prep_size += segs->segs[i]; + } + + desc->data = vmalloc(prep_size); + if (!desc->data) + return -ENOMEM; + + desc->size = prep_size; + desc->next = desc->data; + + return 0; +} + +static u8 *rtw_fwcd_next(struct rtw_dev *rtwdev, u32 item, u32 size) +{ + struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; + struct rtw_fwcd_hdr *hdr; + u8 *next; + + if (!desc->data) { + rtw_dbg(rtwdev, RTW_DBG_FW, "fwcd isn't prepared successfully\n"); + return NULL; + } + + next = desc->next + sizeof(struct rtw_fwcd_hdr); + if (next - desc->data + size > desc->size) { + rtw_dbg(rtwdev, RTW_DBG_FW, "fwcd isn't prepared enough\n"); + return NULL; + } + + hdr = (struct rtw_fwcd_hdr *)(desc->next); + hdr->item = item; + hdr->size = size; + hdr->padding1 = 0x01234567; + hdr->padding2 = 0x89abcdef; + desc->next = next + size; + + return next; +} + +static void rtw_fwcd_dump(struct rtw_dev *rtwdev) +{ + struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; + + rtw_dbg(rtwdev, RTW_DBG_FW, "dump fwcd\n"); + + /* Data will be freed after lifetime of device coredump. After calling + * dev_coredump, data is supposed to be handled by the device coredump + * framework. Note that a new dump will be discarded if a previous one + * hasn't been released yet. + */ + dev_coredumpv(rtwdev->dev, desc->data, desc->size, GFP_KERNEL); +} + +static void rtw_fwcd_free(struct rtw_dev *rtwdev, bool free_self) +{ + struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; + + if (free_self) { + rtw_dbg(rtwdev, RTW_DBG_FW, "free fwcd by self\n"); + vfree(desc->data); + } + + desc->data = NULL; + desc->next = NULL; +} + +static int rtw_fw_dump_crash_log(struct rtw_dev *rtwdev) +{ + u32 size = rtwdev->chip->fw_rxff_size; + u32 *buf; + u8 seq; + + buf = (u32 *)rtw_fwcd_next(rtwdev, RTW_FWCD_TLV, size); + if (!buf) + return -ENOMEM; + + if (rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RXBUF_FW, 0, size, buf)) { + rtw_dbg(rtwdev, RTW_DBG_FW, "dump fw fifo fail\n"); + return -EINVAL; + } + + if (GET_FW_DUMP_LEN(buf) == 0) { + rtw_dbg(rtwdev, RTW_DBG_FW, "fw crash dump's length is 0\n"); + return -EINVAL; + } + + seq = GET_FW_DUMP_SEQ(buf); + if (seq > 0) { + rtw_dbg(rtwdev, RTW_DBG_FW, + "fw crash dump's seq is wrong: %d\n", seq); + return -EINVAL; + } + + return 0; +} + +int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, + u32 fwcd_item) +{ + u32 rxff = rtwdev->chip->fw_rxff_size; + u32 dump_size, done_size = 0; + u8 *buf; + int ret; + + buf = rtw_fwcd_next(rtwdev, fwcd_item, size); + if (!buf) + return -ENOMEM; + + while (size) { + dump_size = size > rxff ? rxff : size; + + ret = rtw_ddma_to_fw_fifo(rtwdev, ocp_src + done_size, + dump_size); + if (ret) { + rtw_err(rtwdev, + "ddma fw 0x%x [+0x%x] to fw fifo fail\n", + ocp_src, done_size); + return ret; + } + + ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RXBUF_FW, 0, + dump_size, (u32 *)(buf + done_size)); + if (ret) { + rtw_err(rtwdev, + "dump fw 0x%x [+0x%x] from fw fifo fail\n", + ocp_src, done_size); + return ret; + } + + size -= dump_size; + done_size += dump_size; + } + + return 0; +} +EXPORT_SYMBOL(rtw_dump_fw); + +int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size) +{ + u8 *buf; + u32 i; + + if (addr & 0x3) { + WARN(1, "should be 4-byte aligned, addr = 0x%08x\n", addr); + return -EINVAL; + } + + buf = rtw_fwcd_next(rtwdev, RTW_FWCD_REG, size); + if (!buf) + return -ENOMEM; + + for (i = 0; i < size; i += 4) + *(u32 *)(buf + i) = rtw_read32(rtwdev, addr + i); + + return 0; +} +EXPORT_SYMBOL(rtw_dump_reg); + +void rtw_vif_assoc_changed(struct rtw_vif *rtwvif, + struct ieee80211_bss_conf *conf) +{ + struct ieee80211_vif *vif = NULL; + + if (conf) + vif = container_of(conf, struct ieee80211_vif, bss_conf); + + if (conf && vif->cfg.assoc) { + rtwvif->aid = vif->cfg.aid; + rtwvif->net_type = RTW_NET_MGD_LINKED; + } else { + rtwvif->aid = 0; + rtwvif->net_type = RTW_NET_NO_LINK; + } +} + +static void rtw_reset_key_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + struct rtw_sec_desc *sec = &rtwdev->sec; + + rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx); +} + +static void rtw_reset_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + + if (rtwdev->sta_cnt == 0) { + rtw_warn(rtwdev, "sta count before reset should not be 0\n"); + return; + } + rtw_sta_remove(rtwdev, sta, false); +} + +static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + rtw_bf_disassoc(rtwdev, vif, NULL); + rtw_vif_assoc_changed(rtwvif, NULL); + rtw_txq_cleanup(rtwdev, vif->txq); + + rtw_release_macid(rtwdev, rtwvif->mac_id); +} + +void rtw_fw_recovery(struct rtw_dev *rtwdev) +{ + if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) + ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work); +} +EXPORT_SYMBOL(rtw_fw_recovery); + +static void __fw_recovery_work(struct rtw_dev *rtwdev) +{ + int ret = 0; + + set_bit(RTW_FLAG_RESTARTING, rtwdev->flags); + clear_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); + + ret = rtw_fwcd_prep(rtwdev); + if (ret) + goto free; + ret = rtw_fw_dump_crash_log(rtwdev); + if (ret) + goto free; + ret = rtw_chip_dump_fw_crash(rtwdev); + if (ret) + goto free; + + rtw_fwcd_dump(rtwdev); +free: + rtw_fwcd_free(rtwdev, !!ret); + rtw_write8(rtwdev, REG_MCU_TST_CFG, 0); + + WARN(1, "firmware crash, start reset and recover\n"); + + rcu_read_lock(); + rtw_iterate_keys_rcu(rtwdev, NULL, rtw_reset_key_iter, rtwdev); + rcu_read_unlock(); + rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); + rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); + bitmap_zero(rtwdev->hw_port, RTW_PORT_NUM); + rtw_enter_ips(rtwdev); +} + +static void rtw_fw_recovery_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + fw_recovery_work); + + mutex_lock(&rtwdev->mutex); + __fw_recovery_work(rtwdev); + mutex_unlock(&rtwdev->mutex); + + ieee80211_restart_hw(rtwdev->hw); +} + +struct rtw_txq_ba_iter_data { +}; + +static void rtw_txq_ba_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + int ret; + u8 tid; + + tid = find_first_bit(si->tid_ba, IEEE80211_NUM_TIDS); + while (tid != IEEE80211_NUM_TIDS) { + clear_bit(tid, si->tid_ba); + ret = ieee80211_start_tx_ba_session(sta, tid, 0); + if (ret == -EINVAL) { + struct ieee80211_txq *txq; + struct rtw_txq *rtwtxq; + + txq = sta->txq[tid]; + rtwtxq = (struct rtw_txq *)txq->drv_priv; + set_bit(RTW_TXQ_BLOCK_BA, &rtwtxq->flags); + } + + tid = find_first_bit(si->tid_ba, IEEE80211_NUM_TIDS); + } +} + +static void rtw_txq_ba_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ba_work); + struct rtw_txq_ba_iter_data data; + + rtw_iterate_stas_atomic(rtwdev, rtw_txq_ba_iter, &data); +} + +void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel) +{ + if (IS_CH_2G_BAND(channel)) + pkt_stat->band = NL80211_BAND_2GHZ; + else if (IS_CH_5G_BAND(channel)) + pkt_stat->band = NL80211_BAND_5GHZ; + else + return; + + pkt_stat->freq = ieee80211_channel_to_frequency(channel, pkt_stat->band); +} +EXPORT_SYMBOL(rtw_set_rx_freq_band); + +void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period) +{ + rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE); + rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period ? dtim_period - 1 : 0); +} + +void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, + u8 primary_channel, enum rtw_supported_band band, + enum rtw_bandwidth bandwidth) +{ + enum nl80211_band nl_band = rtw_hw_to_nl80211_band(band); + struct rtw_hal *hal = &rtwdev->hal; + u8 *cch_by_bw = hal->cch_by_bw; + u32 center_freq, primary_freq; + enum rtw_sar_bands sar_band; + u8 primary_channel_idx; + + center_freq = ieee80211_channel_to_frequency(center_channel, nl_band); + primary_freq = ieee80211_channel_to_frequency(primary_channel, nl_band); + + /* assign the center channel used while 20M bw is selected */ + cch_by_bw[RTW_CHANNEL_WIDTH_20] = primary_channel; + + /* assign the center channel used while current bw is selected */ + cch_by_bw[bandwidth] = center_channel; + + switch (bandwidth) { + case RTW_CHANNEL_WIDTH_20: + default: + primary_channel_idx = RTW_SC_DONT_CARE; + break; + case RTW_CHANNEL_WIDTH_40: + if (primary_freq > center_freq) + primary_channel_idx = RTW_SC_20_UPPER; + else + primary_channel_idx = RTW_SC_20_LOWER; + break; + case RTW_CHANNEL_WIDTH_80: + if (primary_freq > center_freq) { + if (primary_freq - center_freq == 10) + primary_channel_idx = RTW_SC_20_UPPER; + else + primary_channel_idx = RTW_SC_20_UPMOST; + + /* assign the center channel used + * while 40M bw is selected + */ + cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel + 4; + } else { + if (center_freq - primary_freq == 10) + primary_channel_idx = RTW_SC_20_LOWER; + else + primary_channel_idx = RTW_SC_20_LOWEST; + + /* assign the center channel used + * while 40M bw is selected + */ + cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel - 4; + } + break; + } + + switch (center_channel) { + case 1 ... 14: + sar_band = RTW_SAR_BAND_0; + break; + case 36 ... 64: + sar_band = RTW_SAR_BAND_1; + break; + case 100 ... 144: + sar_band = RTW_SAR_BAND_3; + break; + case 149 ... 177: + sar_band = RTW_SAR_BAND_4; + break; + default: + WARN(1, "unknown ch(%u) to SAR band\n", center_channel); + sar_band = RTW_SAR_BAND_0; + break; + } + + hal->current_primary_channel_index = primary_channel_idx; + hal->current_band_width = bandwidth; + hal->primary_channel = primary_channel; + hal->current_channel = center_channel; + hal->current_band_type = band; + hal->sar_band = sar_band; +} + +void rtw_get_channel_params(struct cfg80211_chan_def *chandef, + struct rtw_channel_params *chan_params) +{ + struct ieee80211_channel *channel = chandef->chan; + enum nl80211_chan_width width = chandef->width; + u32 primary_freq, center_freq; + u8 center_chan; + u8 bandwidth = RTW_CHANNEL_WIDTH_20; + + center_chan = channel->hw_value; + primary_freq = channel->center_freq; + center_freq = chandef->center_freq1; + + switch (width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + bandwidth = RTW_CHANNEL_WIDTH_20; + break; + case NL80211_CHAN_WIDTH_40: + bandwidth = RTW_CHANNEL_WIDTH_40; + if (primary_freq > center_freq) + center_chan -= 2; + else + center_chan += 2; + break; + case NL80211_CHAN_WIDTH_80: + bandwidth = RTW_CHANNEL_WIDTH_80; + if (primary_freq > center_freq) { + if (primary_freq - center_freq == 10) + center_chan -= 2; + else + center_chan -= 6; + } else { + if (center_freq - primary_freq == 10) + center_chan += 2; + else + center_chan += 6; + } + break; + default: + center_chan = 0; + break; + } + + chan_params->center_chan = center_chan; + chan_params->bandwidth = bandwidth; + chan_params->primary_chan = channel->hw_value; +} + +void rtw_set_channel(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_channel_params ch_param; + u8 center_chan, primary_chan, bandwidth, band; + + rtw_get_channel_params(&hw->conf.chandef, &ch_param); + if (WARN(ch_param.center_chan == 0, "Invalid channel\n")) + return; + + center_chan = ch_param.center_chan; + primary_chan = ch_param.primary_chan; + bandwidth = ch_param.bandwidth; + band = ch_param.center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; + + rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth); + + if (rtwdev->scan_info.op_chan) + rtw_store_op_chan(rtwdev, true); + + chip->ops->set_channel(rtwdev, center_chan, bandwidth, + hal->current_primary_channel_index); + + if (hal->current_band_type == RTW_BAND_5G) { + rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G); + } else { + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_24G); + else + rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_24G_NOFORSCAN); + } + + rtw_phy_set_tx_power_level(rtwdev, center_chan); + + /* if the channel isn't set for scanning, we will do RF calibration + * in ieee80211_ops::mgd_prepare_tx(). Performing the calibration + * during scanning on each channel takes too long. + */ + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtwdev->need_rfk = true; +} + +void rtw_chip_prepare_tx(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (rtwdev->need_rfk) { + rtwdev->need_rfk = false; + chip->ops->phy_calibration(rtwdev); + } +} + +static void rtw_vif_write_addr(struct rtw_dev *rtwdev, u32 start, u8 *addr) +{ + int i; + + for (i = 0; i < ETH_ALEN; i++) + rtw_write8(rtwdev, start + i, addr[i]); +} + +void rtw_vif_port_config(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + u32 config) +{ + u32 addr, mask; + + if (config & PORT_SET_MAC_ADDR) { + addr = rtwvif->conf->mac_addr.addr; + rtw_vif_write_addr(rtwdev, addr, rtwvif->mac_addr); + } + if (config & PORT_SET_BSSID) { + addr = rtwvif->conf->bssid.addr; + rtw_vif_write_addr(rtwdev, addr, rtwvif->bssid); + } + if (config & PORT_SET_NET_TYPE) { + addr = rtwvif->conf->net_type.addr; + mask = rtwvif->conf->net_type.mask; + rtw_write32_mask(rtwdev, addr, mask, rtwvif->net_type); + } + if (config & PORT_SET_AID) { + addr = rtwvif->conf->aid.addr; + mask = rtwvif->conf->aid.mask; + rtw_write32_mask(rtwdev, addr, mask, rtwvif->aid); + } + if (config & PORT_SET_BCN_CTRL) { + addr = rtwvif->conf->bcn_ctrl.addr; + mask = rtwvif->conf->bcn_ctrl.mask; + rtw_write8_mask(rtwdev, addr, mask, rtwvif->bcn_ctrl); + } +} + +static u8 hw_bw_cap_to_bitamp(u8 bw_cap) +{ + u8 bw = 0; + + switch (bw_cap) { + case EFUSE_HW_CAP_IGNORE: + case EFUSE_HW_CAP_SUPP_BW80: + bw |= BIT(RTW_CHANNEL_WIDTH_80); + fallthrough; + case EFUSE_HW_CAP_SUPP_BW40: + bw |= BIT(RTW_CHANNEL_WIDTH_40); + fallthrough; + default: + bw |= BIT(RTW_CHANNEL_WIDTH_20); + break; + } + + return bw; +} + +static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + + if (hw_ant_num == EFUSE_HW_CAP_IGNORE || + hw_ant_num >= hal->rf_path_num) + return; + + switch (hw_ant_num) { + case 1: + hal->rf_type = RF_1T1R; + hal->rf_path_num = 1; + if (!chip->fix_rf_phy_num) + hal->rf_phy_num = hal->rf_path_num; + hal->antenna_tx = BB_PATH_A; + hal->antenna_rx = BB_PATH_A; + break; + default: + WARN(1, "invalid hw configuration from efuse\n"); + break; + } +} + +static u64 get_vht_ra_mask(struct ieee80211_sta *sta) +{ + u64 ra_mask = 0; + u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); + u8 vht_mcs_cap; + int i, nss; + + /* 4SS, every two bits for MCS7/8/9 */ + for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 10) { + vht_mcs_cap = mcs_map & 0x3; + switch (vht_mcs_cap) { + case 2: /* MCS9 */ + ra_mask |= 0x3ffULL << nss; + break; + case 1: /* MCS8 */ + ra_mask |= 0x1ffULL << nss; + break; + case 0: /* MCS7 */ + ra_mask |= 0x0ffULL << nss; + break; + default: + break; + } + } + + return ra_mask; +} + +static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 tx_num) +{ + u8 rate_id = 0; + + switch (wireless_set) { + case WIRELESS_CCK: + rate_id = RTW_RATEID_B_20M; + break; + case WIRELESS_OFDM: + rate_id = RTW_RATEID_G; + break; + case WIRELESS_CCK | WIRELESS_OFDM: + rate_id = RTW_RATEID_BG; + break; + case WIRELESS_OFDM | WIRELESS_HT: + if (tx_num == 1) + rate_id = RTW_RATEID_GN_N1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_GN_N2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR5_N_3SS; + break; + case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT: + if (bw_mode == RTW_CHANNEL_WIDTH_40) { + if (tx_num == 1) + rate_id = RTW_RATEID_BGN_40M_1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_BGN_40M_2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR5_N_3SS; + else if (tx_num == 4) + rate_id = RTW_RATEID_ARFR7_N_4SS; + } else { + if (tx_num == 1) + rate_id = RTW_RATEID_BGN_20M_1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_BGN_20M_2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR5_N_3SS; + else if (tx_num == 4) + rate_id = RTW_RATEID_ARFR7_N_4SS; + } + break; + case WIRELESS_OFDM | WIRELESS_VHT: + if (tx_num == 1) + rate_id = RTW_RATEID_ARFR1_AC_1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_ARFR0_AC_2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR4_AC_3SS; + else if (tx_num == 4) + rate_id = RTW_RATEID_ARFR6_AC_4SS; + break; + case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_VHT: + if (bw_mode >= RTW_CHANNEL_WIDTH_80) { + if (tx_num == 1) + rate_id = RTW_RATEID_ARFR1_AC_1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_ARFR0_AC_2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR4_AC_3SS; + else if (tx_num == 4) + rate_id = RTW_RATEID_ARFR6_AC_4SS; + } else { + if (tx_num == 1) + rate_id = RTW_RATEID_ARFR2_AC_2G_1SS; + else if (tx_num == 2) + rate_id = RTW_RATEID_ARFR3_AC_2G_2SS; + else if (tx_num == 3) + rate_id = RTW_RATEID_ARFR4_AC_3SS; + else if (tx_num == 4) + rate_id = RTW_RATEID_ARFR6_AC_4SS; + } + break; + default: + break; + } + + return rate_id; +} + +#define RA_MASK_CCK_RATES 0x0000f +#define RA_MASK_OFDM_RATES 0x00ff0 +#define RA_MASK_HT_RATES_1SS (0xff000ULL << 0) +#define RA_MASK_HT_RATES_2SS (0xff000ULL << 8) +#define RA_MASK_HT_RATES_3SS (0xff000ULL << 16) +#define RA_MASK_HT_RATES (RA_MASK_HT_RATES_1SS | \ + RA_MASK_HT_RATES_2SS | \ + RA_MASK_HT_RATES_3SS) +#define RA_MASK_VHT_RATES_1SS (0x3ff000ULL << 0) +#define RA_MASK_VHT_RATES_2SS (0x3ff000ULL << 10) +#define RA_MASK_VHT_RATES_3SS (0x3ff000ULL << 20) +#define RA_MASK_VHT_RATES (RA_MASK_VHT_RATES_1SS | \ + RA_MASK_VHT_RATES_2SS | \ + RA_MASK_VHT_RATES_3SS) +#define RA_MASK_CCK_IN_BG 0x00005 +#define RA_MASK_CCK_IN_HT 0x00005 +#define RA_MASK_CCK_IN_VHT 0x00005 +#define RA_MASK_OFDM_IN_VHT 0x00010 +#define RA_MASK_OFDM_IN_HT_2G 0x00010 +#define RA_MASK_OFDM_IN_HT_5G 0x00030 + +static u64 rtw_rate_mask_rssi(struct rtw_sta_info *si, u8 wireless_set) +{ + u8 rssi_level = si->rssi_level; + + if (wireless_set == WIRELESS_CCK) + return 0xffffffffffffffffULL; + + if (rssi_level == 0) + return 0xffffffffffffffffULL; + else if (rssi_level == 1) + return 0xfffffffffffffff0ULL; + else if (rssi_level == 2) + return 0xffffffffffffefe0ULL; + else if (rssi_level == 3) + return 0xffffffffffffcfc0ULL; + else if (rssi_level == 4) + return 0xffffffffffff8f80ULL; + else + return 0xffffffffffff0f00ULL; +} + +static u64 rtw_rate_mask_recover(u64 ra_mask, u64 ra_mask_bak) +{ + if ((ra_mask & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)) == 0) + ra_mask |= (ra_mask_bak & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); + + if (ra_mask == 0) + ra_mask |= (ra_mask_bak & (RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); + + return ra_mask; +} + +static u64 rtw_rate_mask_cfg(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + u64 ra_mask, bool is_vht_enable) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct cfg80211_bitrate_mask *mask = si->mask; + u64 cfg_mask = GENMASK_ULL(63, 0); + u8 band; + + if (!si->use_cfg_mask) + return ra_mask; + + band = hal->current_band_type; + if (band == RTW_BAND_2G) { + band = NL80211_BAND_2GHZ; + cfg_mask = mask->control[band].legacy; + } else if (band == RTW_BAND_5G) { + band = NL80211_BAND_5GHZ; + cfg_mask = u64_encode_bits(mask->control[band].legacy, + RA_MASK_OFDM_RATES); + } + + if (!is_vht_enable) { + if (ra_mask & RA_MASK_HT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], + RA_MASK_HT_RATES_1SS); + if (ra_mask & RA_MASK_HT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], + RA_MASK_HT_RATES_2SS); + } else { + if (ra_mask & RA_MASK_VHT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], + RA_MASK_VHT_RATES_1SS); + if (ra_mask & RA_MASK_VHT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], + RA_MASK_VHT_RATES_2SS); + } + + ra_mask &= cfg_mask; + + return ra_mask; +} + +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct ieee80211_sta *sta = si->sta; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + u8 wireless_set; + u8 bw_mode; + u8 rate_id; + u8 stbc_en = 0; + u8 ldpc_en = 0; + u8 tx_num = 1; + u64 ra_mask = 0; + u64 ra_mask_bak = 0; + bool is_vht_enable = false; + bool is_support_sgi = false; + + if (sta->deflink.vht_cap.vht_supported) { + is_vht_enable = true; + ra_mask |= get_vht_ra_mask(sta); + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + stbc_en = VHT_STBC_EN; + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + ldpc_en = VHT_LDPC_EN; + } else if (sta->deflink.ht_cap.ht_supported) { + ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 36) | + ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 28) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + stbc_en = HT_STBC_EN; + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) + ldpc_en = HT_LDPC_EN; + } + + if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss) + ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + else if (efuse->hw_cap.nss == 2) + ra_mask &= RA_MASK_VHT_RATES_2SS | RA_MASK_HT_RATES_2SS | + RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + + if (hal->current_band_type == RTW_BAND_5G) { + ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; + ra_mask_bak = ra_mask; + if (sta->deflink.vht_cap.vht_supported) { + ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT; + wireless_set = WIRELESS_OFDM | WIRELESS_VHT; + } else if (sta->deflink.ht_cap.ht_supported) { + ra_mask &= RA_MASK_HT_RATES | RA_MASK_OFDM_IN_HT_5G; + wireless_set = WIRELESS_OFDM | WIRELESS_HT; + } else { + wireless_set = WIRELESS_OFDM; + } + dm_info->rrsr_val_init = RRSR_INIT_5G; + } else if (hal->current_band_type == RTW_BAND_2G) { + ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; + ra_mask_bak = ra_mask; + if (sta->deflink.vht_cap.vht_supported) { + ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT | + RA_MASK_OFDM_IN_VHT; + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | + WIRELESS_HT | WIRELESS_VHT; + } else if (sta->deflink.ht_cap.ht_supported) { + ra_mask &= RA_MASK_HT_RATES | RA_MASK_CCK_IN_HT | + RA_MASK_OFDM_IN_HT_2G; + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | + WIRELESS_HT; + } else if (sta->deflink.supp_rates[0] <= 0xf) { + wireless_set = WIRELESS_CCK; + } else { + ra_mask &= RA_MASK_OFDM_RATES | RA_MASK_CCK_IN_BG; + wireless_set = WIRELESS_CCK | WIRELESS_OFDM; + } + dm_info->rrsr_val_init = RRSR_INIT_2G; + } else { + rtw_err(rtwdev, "Unknown band type\n"); + ra_mask_bak = ra_mask; + wireless_set = 0; + } + + switch (sta->deflink.bandwidth) { + case IEEE80211_STA_RX_BW_80: + bw_mode = RTW_CHANNEL_WIDTH_80; + is_support_sgi = sta->deflink.vht_cap.vht_supported && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + break; + case IEEE80211_STA_RX_BW_40: + bw_mode = RTW_CHANNEL_WIDTH_40; + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + break; + default: + bw_mode = RTW_CHANNEL_WIDTH_20; + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + break; + } + + if (sta->deflink.vht_cap.vht_supported || + sta->deflink.ht_cap.ht_supported) + tx_num = efuse->hw_cap.nss; + + rate_id = get_rate_id(wireless_set, bw_mode, tx_num); + + ra_mask &= rtw_rate_mask_rssi(si, wireless_set); + ra_mask = rtw_rate_mask_recover(ra_mask, ra_mask_bak); + ra_mask = rtw_rate_mask_cfg(rtwdev, si, ra_mask, is_vht_enable); + + si->bw_mode = bw_mode; + si->stbc_en = stbc_en; + si->ldpc_en = ldpc_en; + si->sgi_enable = is_support_sgi; + si->vht_enable = is_vht_enable; + si->ra_mask = ra_mask; + si->rate_id = rate_id; + + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); +} + +int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; + int ret = 0; + + fw = &rtwdev->fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + ret = -EINVAL; + + if (chip->wow_fw_name) { + fw = &rtwdev->wow_fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(rtw_wait_firmware_completion); + +static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (rtw_disable_lps_deep_mode || !chip->lps_deep_mode_supported || + !fw->feature) + return LPS_DEEP_MODE_NONE; + + if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_PG)) && + rtw_fw_feature_check(fw, FW_FEATURE_PG)) + return LPS_DEEP_MODE_PG; + + if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_LCLK)) && + rtw_fw_feature_check(fw, FW_FEATURE_LCLK)) + return LPS_DEEP_MODE_LCLK; + + return LPS_DEEP_MODE_NONE; +} + +int rtw_power_on(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw = &rtwdev->fw; + bool wifi_only; + int ret; + + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + goto err; + } + + /* power on MAC before firmware downloaded */ + ret = rtw_mac_power_on(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to power on mac\n"); + goto err; + } + + ret = rtw_wait_firmware_completion(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to wait firmware completion\n"); + goto err_off; + } + + ret = rtw_download_firmware(rtwdev, fw); + if (ret) { + rtw_err(rtwdev, "failed to download firmware\n"); + goto err_off; + } + + /* config mac after firmware downloaded */ + ret = rtw_mac_init(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to configure mac\n"); + goto err_off; + } + + chip->ops->phy_set_param(rtwdev); + + ret = rtw_mac_postinit(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to configure mac in postinit\n"); + goto err_off; + } + + ret = rtw_hci_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start hci\n"); + goto err_off; + } + + /* send H2C after HCI has started */ + rtw_fw_send_general_info(rtwdev); + rtw_fw_send_phydm_info(rtwdev); + + wifi_only = !rtwdev->efuse.btcoex; + rtw_coex_power_on_setting(rtwdev); + rtw_coex_init_hw_config(rtwdev, wifi_only); + + return 0; + +err_off: + rtw_mac_power_off(rtwdev); + +err: + return ret; +} +EXPORT_SYMBOL(rtw_power_on); + +void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start) +{ + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_NOTIFY_SCAN)) + return; + + if (start) { + rtw_fw_scan_notify(rtwdev, true); + } else { + reinit_completion(&rtwdev->fw_scan_density); + rtw_fw_scan_notify(rtwdev, false); + if (!wait_for_completion_timeout(&rtwdev->fw_scan_density, + SCAN_NOTIFY_TIMEOUT)) + rtw_warn(rtwdev, "firmware failed to report density after scan\n"); + } +} + +void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + const u8 *mac_addr, bool hw_scan) +{ + u32 config = 0; + int ret = 0; + + rtw_leave_lps(rtwdev); + + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) { + ret = rtw_leave_ips(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave idle state\n"); + return; + } + } + + ether_addr_copy(rtwvif->mac_addr, mac_addr); + config |= PORT_SET_MAC_ADDR; + rtw_vif_port_config(rtwdev, rtwvif, config); + + rtw_coex_scan_notify(rtwdev, COEX_SCAN_START); + rtw_core_fw_scan_notify(rtwdev, true); + + set_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); + set_bit(RTW_FLAG_SCANNING, rtwdev->flags); + + rtw_phy_dig_set_max_coverage(rtwdev); +} + +void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool hw_scan) +{ + struct rtw_vif *rtwvif = vif ? (struct rtw_vif *)vif->drv_priv : NULL; + u32 config = 0; + + if (!rtwvif) + return; + + rtw_phy_dig_reset(rtwdev); + clear_bit(RTW_FLAG_SCANNING, rtwdev->flags); + clear_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); + + rtw_core_fw_scan_notify(rtwdev, false); + + ether_addr_copy(rtwvif->mac_addr, vif->addr); + config |= PORT_SET_MAC_ADDR; + rtw_vif_port_config(rtwdev, rtwvif, config); + + rtw_coex_scan_notify(rtwdev, COEX_SCAN_FINISH); + + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) + ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work); +} + +int rtw_core_start(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtwdev->chip->ops->power_on(rtwdev); + if (ret) + return ret; + + rtw_sec_enable_sec_engine(rtwdev); + + rtwdev->lps_conf.deep_mode = rtw_update_lps_deep_mode(rtwdev, &rtwdev->fw); + rtwdev->lps_conf.wow_deep_mode = rtw_update_lps_deep_mode(rtwdev, &rtwdev->wow_fw); + + /* rcr reset after powered on */ + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); + + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, + RTW_WATCH_DOG_DELAY_TIME); + + set_bit(RTW_FLAG_RUNNING, rtwdev->flags); + + return 0; +} + +void rtw_power_off(struct rtw_dev *rtwdev) +{ + rtw_hci_stop(rtwdev); + rtw_coex_power_off_setting(rtwdev); + rtw_mac_power_off(rtwdev); +} +EXPORT_SYMBOL(rtw_power_off); + +void rtw_core_stop(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + + clear_bit(RTW_FLAG_RUNNING, rtwdev->flags); + clear_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + + mutex_unlock(&rtwdev->mutex); + + cancel_work_sync(&rtwdev->c2h_work); + cancel_work_sync(&rtwdev->update_beacon_work); + cancel_delayed_work_sync(&rtwdev->watch_dog_work); + cancel_delayed_work_sync(&coex->bt_relink_work); + cancel_delayed_work_sync(&coex->bt_reenable_work); + cancel_delayed_work_sync(&coex->defreeze_work); + cancel_delayed_work_sync(&coex->wl_remain_work); + cancel_delayed_work_sync(&coex->bt_remain_work); + cancel_delayed_work_sync(&coex->wl_connecting_work); + cancel_delayed_work_sync(&coex->bt_multi_link_remain_work); + cancel_delayed_work_sync(&coex->wl_ccklock_work); + + mutex_lock(&rtwdev->mutex); + + rtwdev->chip->ops->power_off(rtwdev); +} + +static void rtw_init_ht_cap(struct rtw_dev *rtwdev, + struct ieee80211_sta_ht_cap *ht_cap) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + int i; + + ht_cap->ht_supported = true; + ht_cap->cap = 0; + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_MAX_AMSDU | + (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + + if (rtw_chip_has_rx_ldpc(rtwdev)) + ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; + if (rtw_chip_has_tx_stbc(rtwdev)) + ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC; + + if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40)) + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_DSSSCCK40 | + IEEE80211_HT_CAP_SGI_40; + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap->ampdu_density = chip->ampdu_density; + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + for (i = 0; i < efuse->hw_cap.nss; i++) + ht_cap->mcs.rx_mask[i] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + ht_cap->mcs.rx_highest = cpu_to_le16(150 * efuse->hw_cap.nss); +} + +static void rtw_init_vht_cap(struct rtw_dev *rtwdev, + struct ieee80211_sta_vht_cap *vht_cap) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + u16 mcs_map = 0; + __le16 highest; + int i; + + if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE && + efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT) + return; + + vht_cap->vht_supported = true; + vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | + IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_HTC_VHT | + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | + 0; + if (rtwdev->hal.rf_path_num > 1) + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + vht_cap->cap |= (rtwdev->hal.bfee_sts_cap << + IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); + + if (rtw_chip_has_rx_ldpc(rtwdev)) + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + + for (i = 0; i < 8; i++) { + if (i < efuse->hw_cap.nss) + mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); + else + mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); + } + + highest = cpu_to_le16(390 * efuse->hw_cap.nss); + + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.rx_highest = highest; + vht_cap->vht_mcs.tx_highest = highest; +} + +static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev) +{ + u16 len; + + len = rtwdev->chip->max_scan_ie_len; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && + rtwdev->chip->id == RTW_CHIP_TYPE_8822C) + len = IEEE80211_MAX_DATA_LEN; + else if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM)) + len -= RTW_OLD_PROBE_PG_CNT * TX_PAGE_SIZE; + + return len; +} + +static struct ieee80211_supported_band * +rtw_sband_dup(struct rtw_dev *rtwdev, + const struct ieee80211_supported_band *sband) +{ + struct ieee80211_supported_band *dup; + + dup = devm_kmemdup(rtwdev->dev, sband, sizeof(*sband), GFP_KERNEL); + if (!dup) + return NULL; + + dup->channels = devm_kmemdup_array(rtwdev->dev, sband->channels, + sband->n_channels, + sizeof(*sband->channels), + GFP_KERNEL); + if (!dup->channels) + return NULL; + + dup->bitrates = devm_kmemdup_array(rtwdev->dev, sband->bitrates, + sband->n_bitrates, + sizeof(*sband->bitrates), + GFP_KERNEL); + if (!dup->bitrates) + return NULL; + + return dup; +} + +static void rtw_set_supported_band(struct ieee80211_hw *hw, + const struct rtw_chip_info *chip) +{ + struct ieee80211_supported_band *sband; + struct rtw_dev *rtwdev = hw->priv; + + if (chip->band & RTW_BAND_2G) { + sband = rtw_sband_dup(rtwdev, &rtw_band_2ghz); + if (!sband) + goto err_out; + if (chip->ht_supported) + rtw_init_ht_cap(rtwdev, &sband->ht_cap); + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; + } + + if (chip->band & RTW_BAND_5G) { + sband = rtw_sband_dup(rtwdev, &rtw_band_5ghz); + if (!sband) + goto err_out; + if (chip->ht_supported) + rtw_init_ht_cap(rtwdev, &sband->ht_cap); + if (chip->vht_supported) + rtw_init_vht_cap(rtwdev, &sband->vht_cap); + hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; + } + + return; + +err_out: + rtw_err(rtwdev, "failed to set supported band\n"); +} + +static void rtw_vif_smps_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + + if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) + return; + + if (rtwdev->hal.txrx_1ss) + ieee80211_request_smps(vif, 0, IEEE80211_SMPS_STATIC); + else + ieee80211_request_smps(vif, 0, IEEE80211_SMPS_OFF); +} + +void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + + if (!chip->ops->config_txrx_mode || rtwdev->hal.txrx_1ss == txrx_1ss) + return; + + rtwdev->hal.txrx_1ss = txrx_1ss; + if (txrx_1ss) + chip->ops->config_txrx_mode(rtwdev, BB_PATH_A, BB_PATH_A, false); + else + chip->ops->config_txrx_mode(rtwdev, hal->antenna_tx, + hal->antenna_rx, false); + rtw_iterate_vifs_atomic(rtwdev, rtw_vif_smps_iter, rtwdev); +} + +static void __update_firmware_feature(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + u32 feature; + const struct rtw_fw_hdr *fw_hdr = + (const struct rtw_fw_hdr *)fw->firmware->data; + + feature = le32_to_cpu(fw_hdr->feature); + fw->feature = feature & FW_FEATURE_SIG ? feature : 0; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C && + RTW_FW_SUIT_VER_CODE(rtwdev->fw) < RTW_FW_VER_CODE(9, 9, 13)) + fw->feature_ext |= FW_FEATURE_EXT_OLD_PAGE_NUM; +} + +static void __update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + const struct rtw_fw_hdr *fw_hdr = + (const struct rtw_fw_hdr *)fw->firmware->data; + + fw->h2c_version = le16_to_cpu(fw_hdr->h2c_fmt_ver); + fw->version = le16_to_cpu(fw_hdr->version); + fw->sub_version = fw_hdr->subversion; + fw->sub_index = fw_hdr->subindex; + + __update_firmware_feature(rtwdev, fw); +} + +static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + struct rtw_fw_hdr_legacy *legacy = + (struct rtw_fw_hdr_legacy *)fw->firmware->data; + + fw->h2c_version = 0; + fw->version = le16_to_cpu(legacy->version); + fw->sub_version = legacy->subversion1; + fw->sub_index = legacy->subversion2; +} + +static void update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_8051(rtwdev)) + __update_firmware_info_legacy(rtwdev, fw); + else + __update_firmware_info(rtwdev, fw); +} + +static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) +{ + struct rtw_fw_state *fw = context; + struct rtw_dev *rtwdev = fw->rtwdev; + struct wiphy *wiphy = rtwdev->hw->wiphy; + + if (!firmware || !firmware->data) { + rtw_err(rtwdev, "failed to request firmware\n"); + complete_all(&fw->completion); + return; + } + + fw->firmware = firmware; + update_firmware_info(rtwdev, fw); + complete_all(&fw->completion); + + rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n", + fw->type == RTW_WOWLAN_FW ? "WOW " : "", + fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); + + if (fw->type == RTW_NORMAL_FW) + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), + "%u.%u.%u", + fw->version, fw->sub_version, fw->sub_index); +} + +static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type) +{ + const char *fw_name; + struct rtw_fw_state *fw; + int ret; + + switch (type) { + case RTW_WOWLAN_FW: + fw = &rtwdev->wow_fw; + fw_name = rtwdev->chip->wow_fw_name; + break; + + case RTW_NORMAL_FW: + fw = &rtwdev->fw; + fw_name = rtwdev->chip->fw_name; + break; + + default: + rtw_warn(rtwdev, "unsupported firmware type\n"); + return -ENOENT; + } + + fw->type = type; + fw->rtwdev = rtwdev; + init_completion(&fw->completion); + + ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, + GFP_KERNEL, fw, rtw_load_firmware_cb); + if (ret) { + rtw_err(rtwdev, "failed to async firmware request\n"); + return ret; + } + + return 0; +} + +static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtwdev->hci.rpwm_addr = 0x03d9; + rtwdev->hci.cpwm_addr = 0x03da; + break; + case RTW_HCI_TYPE_SDIO: + rtwdev->hci.rpwm_addr = REG_SDIO_HRPWM1; + rtwdev->hci.cpwm_addr = REG_SDIO_HCPWM1_V2; + break; + case RTW_HCI_TYPE_USB: + rtwdev->hci.rpwm_addr = 0xfe58; + rtwdev->hci.cpwm_addr = 0xfe57; + break; + default: + rtw_err(rtwdev, "unsupported hci type\n"); + return -EINVAL; + } + + hal->chip_version = rtw_read32(rtwdev, REG_SYS_CFG1); + hal->cut_version = BIT_GET_CHIP_VER(hal->chip_version); + hal->mp_chip = (hal->chip_version & BIT_RTL_ID) ? 0 : 1; + if (hal->chip_version & BIT_RF_TYPE_ID) { + hal->rf_type = RF_2T2R; + hal->rf_path_num = 2; + hal->antenna_tx = BB_PATH_AB; + hal->antenna_rx = BB_PATH_AB; + } else { + hal->rf_type = RF_1T1R; + hal->rf_path_num = 1; + hal->antenna_tx = BB_PATH_A; + hal->antenna_rx = BB_PATH_A; + } + hal->rf_phy_num = chip->fix_rf_phy_num ? chip->fix_rf_phy_num : + hal->rf_path_num; + + efuse->physical_size = chip->phy_efuse_size; + efuse->logical_size = chip->log_efuse_size; + efuse->protect_size = chip->ptct_efuse_size; + + /* default use ack */ + rtwdev->hal.rcr |= BIT_VHT_DACK; + + hal->bfee_sts_cap = 3; + + return 0; +} + +static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev) +{ + struct rtw_fw_state *fw = &rtwdev->fw; + int ret; + + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + goto err; + } + + ret = rtw_mac_power_on(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to power on mac\n"); + goto err; + } + + rtw_write8(rtwdev, REG_C2HEVT, C2H_HW_FEATURE_DUMP); + + wait_for_completion(&fw->completion); + if (!fw->firmware) { + ret = -EINVAL; + rtw_err(rtwdev, "failed to load firmware\n"); + goto err; + } + + ret = rtw_download_firmware(rtwdev, fw); + if (ret) { + rtw_err(rtwdev, "failed to download firmware\n"); + goto err_off; + } + + return 0; + +err_off: + rtw_mac_power_off(rtwdev); + +err: + return ret; +} + +static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 hw_feature[HW_FEATURE_LEN]; + u8 id; + u8 bw; + int i; + + if (!rtwdev->chip->hw_feature_report) + return 0; + + id = rtw_read8(rtwdev, REG_C2HEVT); + if (id != C2H_HW_FEATURE_REPORT) { + rtw_err(rtwdev, "failed to read hw feature report\n"); + return -EBUSY; + } + + for (i = 0; i < HW_FEATURE_LEN; i++) + hw_feature[i] = rtw_read8(rtwdev, REG_C2HEVT + 2 + i); + + rtw_write8(rtwdev, REG_C2HEVT, 0); + + bw = GET_EFUSE_HW_CAP_BW(hw_feature); + efuse->hw_cap.bw = hw_bw_cap_to_bitamp(bw); + efuse->hw_cap.hci = GET_EFUSE_HW_CAP_HCI(hw_feature); + efuse->hw_cap.nss = GET_EFUSE_HW_CAP_NSS(hw_feature); + efuse->hw_cap.ptcl = GET_EFUSE_HW_CAP_PTCL(hw_feature); + efuse->hw_cap.ant_num = GET_EFUSE_HW_CAP_ANT_NUM(hw_feature); + + rtw_hw_config_rf_ant_num(rtwdev, efuse->hw_cap.ant_num); + + if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE || + efuse->hw_cap.nss > rtwdev->hal.rf_path_num) + efuse->hw_cap.nss = rtwdev->hal.rf_path_num; + + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, + efuse->hw_cap.ant_num, efuse->hw_cap.nss); + + return 0; +} + +static void rtw_chip_efuse_disable(struct rtw_dev *rtwdev) +{ + rtw_hci_stop(rtwdev); + rtw_mac_power_off(rtwdev); +} + +static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + int ret; + + mutex_lock(&rtwdev->mutex); + + /* power on mac to read efuse */ + ret = rtw_chip_efuse_enable(rtwdev); + if (ret) + goto out_unlock; + + ret = rtw_parse_efuse_map(rtwdev); + if (ret) + goto out_disable; + + ret = rtw_dump_hw_feature(rtwdev); + if (ret) + goto out_disable; + + ret = rtw_check_supported_rfe(rtwdev); + if (ret) + goto out_disable; + + if (efuse->crystal_cap == 0xff) + efuse->crystal_cap = 0; + if (efuse->pa_type_2g == 0xff) + efuse->pa_type_2g = 0; + if (efuse->pa_type_5g == 0xff) + efuse->pa_type_5g = 0; + if (efuse->lna_type_2g == 0xff) + efuse->lna_type_2g = 0; + if (efuse->lna_type_5g == 0xff) + efuse->lna_type_5g = 0; + if (efuse->channel_plan == 0xff) + efuse->channel_plan = 0x7f; + if (efuse->rf_board_option == 0xff) + efuse->rf_board_option = 0; + if (efuse->bt_setting & BIT(0)) + efuse->share_ant = true; + if (efuse->regd == 0xff) + efuse->regd = 0; + if (efuse->tx_bb_swing_setting_2g == 0xff) + efuse->tx_bb_swing_setting_2g = 0; + if (efuse->tx_bb_swing_setting_5g == 0xff) + efuse->tx_bb_swing_setting_5g = 0; + + efuse->btcoex = (efuse->rf_board_option & 0xe0) == 0x20; + efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0; + efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0; + efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0; + efuse->ext_lna_5g = efuse->lna_type_5g & BIT(3) ? 1 : 0; + + if (!is_valid_ether_addr(efuse->addr)) { + eth_random_addr(efuse->addr); + dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n"); + } + +out_disable: + rtw_chip_efuse_disable(rtwdev); + +out_unlock: + mutex_unlock(&rtwdev->mutex); + return ret; +} + +static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); + + if (!rfe_def) + return -ENODEV; + + rtw_phy_setup_phy_cond(rtwdev, hal->pkg_type); + + rtw_phy_init_tx_power(rtwdev); + rtw_load_table(rtwdev, rfe_def->phy_pg_tbl); + rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl); + rtw_phy_tx_power_by_rate_config(hal); + rtw_phy_tx_power_limit_config(hal); + + return 0; +} + +int rtw_chip_info_setup(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtw_chip_parameter_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip parameters\n"); + goto err_out; + } + + ret = rtw_chip_efuse_info_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip efuse info\n"); + goto err_out; + } + + ret = rtw_chip_board_info_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip board info\n"); + goto err_out; + } + + return 0; + +err_out: + return ret; +} +EXPORT_SYMBOL(rtw_chip_info_setup); + +static void rtw_stats_init(struct rtw_dev *rtwdev) +{ + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + int i; + + ewma_tp_init(&stats->tx_ewma_tp); + ewma_tp_init(&stats->rx_ewma_tp); + + for (i = 0; i < RTW_EVM_NUM; i++) + ewma_evm_init(&dm_info->ewma_evm[i]); + for (i = 0; i < RTW_SNR_NUM; i++) + ewma_snr_init(&dm_info->ewma_snr[i]); +} + +int rtw_core_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex *coex = &rtwdev->coex; + int ret; + + INIT_LIST_HEAD(&rtwdev->rsvd_page_list); + INIT_LIST_HEAD(&rtwdev->txqs); + + timer_setup(&rtwdev->tx_report.purge_timer, + rtw_tx_report_purge_timer, 0); + rtwdev->tx_wq = alloc_workqueue("rtw_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); + if (!rtwdev->tx_wq) { + rtw_warn(rtwdev, "alloc_workqueue rtw_tx_wq failed\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work); + INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work); + INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work); + INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work); + INIT_DELAYED_WORK(&coex->wl_remain_work, rtw_coex_wl_remain_work); + INIT_DELAYED_WORK(&coex->bt_remain_work, rtw_coex_bt_remain_work); + INIT_DELAYED_WORK(&coex->wl_connecting_work, rtw_coex_wl_connecting_work); + INIT_DELAYED_WORK(&coex->bt_multi_link_remain_work, + rtw_coex_bt_multi_link_remain_work); + INIT_DELAYED_WORK(&coex->wl_ccklock_work, rtw_coex_wl_ccklock_work); + INIT_WORK(&rtwdev->tx_work, rtw_tx_work); + INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work); + INIT_WORK(&rtwdev->ips_work, rtw_ips_work); + INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work); + INIT_WORK(&rtwdev->update_beacon_work, rtw_fw_update_beacon_work); + INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work); + skb_queue_head_init(&rtwdev->c2h_queue); + skb_queue_head_init(&rtwdev->coex.queue); + skb_queue_head_init(&rtwdev->tx_report.queue); + + spin_lock_init(&rtwdev->txq_lock); + spin_lock_init(&rtwdev->tx_report.q_lock); + + mutex_init(&rtwdev->mutex); + mutex_init(&rtwdev->hal.tx_power_mutex); + + init_waitqueue_head(&rtwdev->coex.wait); + init_completion(&rtwdev->lps_leave_check); + init_completion(&rtwdev->fw_scan_density); + + rtwdev->sec.total_cam_num = 32; + rtwdev->hal.current_channel = 1; + rtwdev->dm_info.fix_rate = U8_MAX; + + rtw_stats_init(rtwdev); + + /* default rx filter setting */ + rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | + BIT_PKTCTL_DLEN | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | + BIT_AB | BIT_AM | BIT_APM; + + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); + if (ret) { + rtw_warn(rtwdev, "no firmware loaded\n"); + goto out; + } + + if (chip->wow_fw_name) { + ret = rtw_load_firmware(rtwdev, RTW_WOWLAN_FW); + if (ret) { + rtw_warn(rtwdev, "no wow firmware loaded\n"); + wait_for_completion(&rtwdev->fw.completion); + if (rtwdev->fw.firmware) + release_firmware(rtwdev->fw.firmware); + goto out; + } + } + + return 0; + +out: + destroy_workqueue(rtwdev->tx_wq); + return ret; +} +EXPORT_SYMBOL(rtw_core_init); + +void rtw_core_deinit(struct rtw_dev *rtwdev) +{ + struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_fw_state *wow_fw = &rtwdev->wow_fw; + struct rtw_rsvd_page *rsvd_pkt, *tmp; + unsigned long flags; + + rtw_wait_firmware_completion(rtwdev); + + if (fw->firmware) + release_firmware(fw->firmware); + + if (wow_fw->firmware) + release_firmware(wow_fw->firmware); + + destroy_workqueue(rtwdev->tx_wq); + timer_delete_sync(&rtwdev->tx_report.purge_timer); + spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags); + skb_queue_purge(&rtwdev->tx_report.queue); + spin_unlock_irqrestore(&rtwdev->tx_report.q_lock, flags); + skb_queue_purge(&rtwdev->coex.queue); + skb_queue_purge(&rtwdev->c2h_queue); + + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, + build_list) { + list_del(&rsvd_pkt->build_list); + kfree(rsvd_pkt); + } + + mutex_destroy(&rtwdev->mutex); + mutex_destroy(&rtwdev->hal.tx_power_mutex); +} +EXPORT_SYMBOL(rtw_core_deinit); + +int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) +{ + struct rtw_hal *hal = &rtwdev->hal; + int max_tx_headroom = 0; + int ret; + + max_tx_headroom = rtwdev->chip->tx_pkt_desc_sz; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) + max_tx_headroom += RTW_SDIO_DATA_PTR_ALIGN; + + hw->extra_tx_headroom = max_tx_headroom; + hw->queues = IEEE80211_NUM_ACS; + hw->txq_data_size = sizeof(struct rtw_txq); + hw->sta_data_size = sizeof(struct rtw_sta_info); + hw->vif_data_size = sizeof(struct rtw_vif); + + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, RX_INCLUDES_FCS); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, MFP_CAPABLE); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + if (rtwdev->chip->amsdu_in_ampdu) + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, TX_AMSDU); + ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); + + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_ADHOC); + hw->wiphy->available_antennas_tx = hal->antenna_tx; + hw->wiphy->available_antennas_rx = hal->antenna_rx; + + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | + WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + + hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; + hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { + hw->wiphy->iface_combinations = rtw_iface_combs; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); + } + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); + +#ifdef CONFIG_PM + hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; + hw->wiphy->max_sched_scan_ssids = rtwdev->chip->max_sched_scan_ssids; +#endif + rtw_set_supported_band(hw, rtwdev->chip); + SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr); + + hw->wiphy->sar_capa = &rtw_sar_capa; + + ret = rtw_regd_init(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to init regd\n"); + return ret; + } + + rtw_led_init(rtwdev); + + ret = ieee80211_register_hw(hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw\n"); + goto led_deinit; + } + + ret = rtw_regd_hint(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to hint regd\n"); + goto led_deinit; + } + + rtw_debugfs_init(rtwdev); + + rtwdev->bf_info.bfer_mu_cnt = 0; + rtwdev->bf_info.bfer_su_cnt = 0; + + return 0; + +led_deinit: + rtw_led_deinit(rtwdev); + return ret; +} +EXPORT_SYMBOL(rtw_register_hw); + +void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) +{ + ieee80211_unregister_hw(hw); + rtw_debugfs_deinit(rtwdev); + rtw_led_deinit(rtwdev); +} +EXPORT_SYMBOL(rtw_unregister_hw); + +static +void rtw_swap_reg_nbytes(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, + const struct rtw_hw_reg *reg2, u8 nbytes) +{ + u8 i; + + for (i = 0; i < nbytes; i++) { + u8 v1 = rtw_read8(rtwdev, reg1->addr + i); + u8 v2 = rtw_read8(rtwdev, reg2->addr + i); + + rtw_write8(rtwdev, reg1->addr + i, v2); + rtw_write8(rtwdev, reg2->addr + i, v1); + } +} + +static +void rtw_swap_reg_mask(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, + const struct rtw_hw_reg *reg2) +{ + u32 v1, v2; + + v1 = rtw_read32_mask(rtwdev, reg1->addr, reg1->mask); + v2 = rtw_read32_mask(rtwdev, reg2->addr, reg2->mask); + rtw_write32_mask(rtwdev, reg2->addr, reg2->mask, v1); + rtw_write32_mask(rtwdev, reg1->addr, reg1->mask, v2); +} + +struct rtw_iter_port_switch_data { + struct rtw_dev *rtwdev; + struct rtw_vif *rtwvif_ap; +}; + +static void rtw_port_switch_iter(void *data, struct ieee80211_vif *vif) +{ + struct rtw_iter_port_switch_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + struct rtw_vif *rtwvif_target = (struct rtw_vif *)vif->drv_priv; + struct rtw_vif *rtwvif_ap = iter_data->rtwvif_ap; + const struct rtw_hw_reg *reg1, *reg2; + + if (rtwvif_target->port != RTW_PORT_0) + return; + + rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", + rtwvif_ap->port, rtwvif_target->port); + + /* Leave LPS so the value swapped are not in PS mode */ + rtw_leave_lps(rtwdev); + + reg1 = &rtwvif_ap->conf->net_type; + reg2 = &rtwvif_target->conf->net_type; + rtw_swap_reg_mask(rtwdev, reg1, reg2); + + reg1 = &rtwvif_ap->conf->mac_addr; + reg2 = &rtwvif_target->conf->mac_addr; + rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); + + reg1 = &rtwvif_ap->conf->bssid; + reg2 = &rtwvif_target->conf->bssid; + rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); + + reg1 = &rtwvif_ap->conf->bcn_ctrl; + reg2 = &rtwvif_target->conf->bcn_ctrl; + rtw_swap_reg_nbytes(rtwdev, reg1, reg2, 1); + + swap(rtwvif_target->port, rtwvif_ap->port); + swap(rtwvif_target->conf, rtwvif_ap->conf); + + rtw_fw_default_port(rtwdev, rtwvif_target); +} + +void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_iter_port_switch_data iter_data; + + if (vif->type != NL80211_IFTYPE_AP || rtwvif->port == RTW_PORT_0) + return; + + iter_data.rtwdev = rtwdev; + iter_data.rtwvif_ap = rtwvif; + rtw_iterate_vifs(rtwdev, rtw_port_switch_iter, &iter_data); +} + +static void rtw_check_sta_active_iter(void *data, struct ieee80211_vif *vif) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + bool *active = data; + + if (*active) + return; + + if (vif->type != NL80211_IFTYPE_STATION) + return; + + if (vif->cfg.assoc || !is_zero_ether_addr(rtwvif->bssid)) + *active = true; +} + +bool rtw_core_check_sta_active(struct rtw_dev *rtwdev) +{ + bool sta_active = false; + + rtw_iterate_vifs(rtwdev, rtw_check_sta_active_iter, &sta_active); + + return rtwdev->ap_active || sta_active; +} + +void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) +{ + if (!rtwdev->ap_active) + return; + + if (enable) { + rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + rtw_write8_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + } else { + rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + rtw_write8_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + } +} + +void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + const struct rtw_chip_ops *ops = rtwdev->chip->ops; + struct ieee80211_sta *sta; + u8 factor = 0xff; + + if (!ops->set_ampdu_factor) + return; + + rcu_read_lock(); + + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (!sta) { + rcu_read_unlock(); + rtw_warn(rtwdev, "%s: failed to find station %pM\n", + __func__, bss_conf->bssid); + return; + } + + if (sta->deflink.vht_cap.vht_supported) + factor = u32_get_bits(sta->deflink.vht_cap.cap, + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + else if (sta->deflink.ht_cap.ht_supported) + factor = sta->deflink.ht_cap.ampdu_factor; + + rcu_read_unlock(); + + if (factor != 0xff) + ops->set_ampdu_factor(rtwdev, factor); +} + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h new file mode 100644 index 000000000..c6e981ba7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -0,0 +1,2287 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTK_MAIN_H_ +#define __RTK_MAIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + +#define RTW_MAX_MAC_ID_NUM 32 +#define RTW_MAX_SEC_CAM_NUM 32 +#define MAX_PG_CAM_BACKUP_NUM 8 + +#define RTW_SCAN_MAX_SSIDS 4 + +#define RTW_MAX_PATTERN_NUM 12 +#define RTW_MAX_PATTERN_MASK_SIZE 16 +#define RTW_MAX_PATTERN_SIZE 128 + +#define RTW_WATCH_DOG_DELAY_TIME round_jiffies_relative(HZ * 2) + +#define RFREG_MASK 0xfffff +#define INV_RF_DATA 0xffffffff +#define TX_PAGE_SIZE_SHIFT 7 +#define TX_PAGE_SIZE (1 << TX_PAGE_SIZE_SHIFT) + +#define RTW_CHANNEL_WIDTH_MAX 3 +#define RTW_RF_PATH_MAX 4 +#define HW_FEATURE_LEN 13 + +#define RTW_TP_SHIFT 18 /* bytes/2s --> Mbps */ + +extern bool rtw_bf_support; +extern bool rtw_disable_lps_deep_mode; +extern unsigned int rtw_debug_mask; +extern bool rtw_edcca_enabled; +extern const struct ieee80211_ops rtw_ops; + +#define RTW_MAX_CHANNEL_NUM_2G 14 +#define RTW_MAX_CHANNEL_NUM_5G 49 + +struct rtw_dev; +struct rtw_debugfs; + +enum rtw_hci_type { + RTW_HCI_TYPE_PCIE, + RTW_HCI_TYPE_USB, + RTW_HCI_TYPE_SDIO, + + RTW_HCI_TYPE_UNDEFINE, +}; + +struct rtw_hci { + const struct rtw_hci_ops *ops; + enum rtw_hci_type type; + + u32 rpwm_addr; + u32 cpwm_addr; + + u8 bulkout_num; +}; + +#define IS_CH_5G_BAND_1(channel) ((channel) >= 36 && (channel <= 48)) +#define IS_CH_5G_BAND_2(channel) ((channel) >= 52 && (channel <= 64)) +#define IS_CH_5G_BAND_3(channel) ((channel) >= 100 && (channel <= 144)) +#define IS_CH_5G_BAND_4(channel) ((channel) >= 149 && (channel <= 177)) + +#define IS_CH_5G_BAND_MID(channel) \ + (IS_CH_5G_BAND_2(channel) || IS_CH_5G_BAND_3(channel)) + +#define IS_CH_2G_BAND(channel) ((channel) <= 14) +#define IS_CH_5G_BAND(channel) \ + (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel) || \ + IS_CH_5G_BAND_3(channel) || IS_CH_5G_BAND_4(channel)) + +enum rtw_supported_band { + RTW_BAND_2G = BIT(NL80211_BAND_2GHZ), + RTW_BAND_5G = BIT(NL80211_BAND_5GHZ), + RTW_BAND_60G = BIT(NL80211_BAND_60GHZ), +}; + +/* now, support up to 80M bw */ +#define RTW_MAX_CHANNEL_WIDTH RTW_CHANNEL_WIDTH_80 + +enum rtw_bandwidth { + RTW_CHANNEL_WIDTH_20 = 0, + RTW_CHANNEL_WIDTH_40 = 1, + RTW_CHANNEL_WIDTH_80 = 2, + RTW_CHANNEL_WIDTH_160 = 3, + RTW_CHANNEL_WIDTH_80_80 = 4, + RTW_CHANNEL_WIDTH_5 = 5, + RTW_CHANNEL_WIDTH_10 = 6, +}; + +enum rtw_sc_offset { + RTW_SC_DONT_CARE = 0, + RTW_SC_20_UPPER = 1, + RTW_SC_20_LOWER = 2, + RTW_SC_20_UPMOST = 3, + RTW_SC_20_LOWEST = 4, + RTW_SC_40_UPPER = 9, + RTW_SC_40_LOWER = 10, +}; + +enum rtw_net_type { + RTW_NET_NO_LINK = 0, + RTW_NET_AD_HOC = 1, + RTW_NET_MGD_LINKED = 2, + RTW_NET_AP_MODE = 3, +}; + +enum rtw_rf_type { + RF_1T1R = 0, + RF_1T2R = 1, + RF_2T2R = 2, + RF_2T3R = 3, + RF_2T4R = 4, + RF_3T3R = 5, + RF_3T4R = 6, + RF_4T4R = 7, + RF_TYPE_MAX, +}; + +enum rtw_rf_path { + RF_PATH_A = 0, + RF_PATH_B = 1, + RF_PATH_C = 2, + RF_PATH_D = 3, +}; + +enum rtw_bb_path { + BB_PATH_A = BIT(0), + BB_PATH_B = BIT(1), + BB_PATH_C = BIT(2), + BB_PATH_D = BIT(3), + + BB_PATH_AB = (BB_PATH_A | BB_PATH_B), + BB_PATH_AC = (BB_PATH_A | BB_PATH_C), + BB_PATH_AD = (BB_PATH_A | BB_PATH_D), + BB_PATH_BC = (BB_PATH_B | BB_PATH_C), + BB_PATH_BD = (BB_PATH_B | BB_PATH_D), + BB_PATH_CD = (BB_PATH_C | BB_PATH_D), + + BB_PATH_ABC = (BB_PATH_A | BB_PATH_B | BB_PATH_C), + BB_PATH_ABD = (BB_PATH_A | BB_PATH_B | BB_PATH_D), + BB_PATH_ACD = (BB_PATH_A | BB_PATH_C | BB_PATH_D), + BB_PATH_BCD = (BB_PATH_B | BB_PATH_C | BB_PATH_D), + + BB_PATH_ABCD = (BB_PATH_A | BB_PATH_B | BB_PATH_C | BB_PATH_D), +}; + +enum rtw_rate_section { + RTW_RATE_SECTION_CCK = 0, + RTW_RATE_SECTION_OFDM, + RTW_RATE_SECTION_HT_1S, + RTW_RATE_SECTION_HT_2S, + RTW_RATE_SECTION_VHT_1S, + RTW_RATE_SECTION_VHT_2S, + __RTW_RATE_SECTION_2SS_MAX = RTW_RATE_SECTION_VHT_2S, + RTW_RATE_SECTION_HT_3S, + RTW_RATE_SECTION_HT_4S, + RTW_RATE_SECTION_VHT_3S, + RTW_RATE_SECTION_VHT_4S, + + /* keep last */ + RTW_RATE_SECTION_NUM, +}; + +enum rtw_wireless_set { + WIRELESS_CCK = 0x00000001, + WIRELESS_OFDM = 0x00000002, + WIRELESS_HT = 0x00000004, + WIRELESS_VHT = 0x00000008, +}; + +#define HT_STBC_EN BIT(0) +#define VHT_STBC_EN BIT(1) +#define HT_LDPC_EN BIT(0) +#define VHT_LDPC_EN BIT(1) + +enum rtw_chip_type { + RTW_CHIP_TYPE_8822B, + RTW_CHIP_TYPE_8822C, + RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, + RTW_CHIP_TYPE_8703B, + RTW_CHIP_TYPE_8821A, + RTW_CHIP_TYPE_8812A, + RTW_CHIP_TYPE_8814A, +}; + +enum rtw_tx_queue_type { + /* the order of AC queues matters */ + RTW_TX_QUEUE_BK = 0x0, + RTW_TX_QUEUE_BE = 0x1, + RTW_TX_QUEUE_VI = 0x2, + RTW_TX_QUEUE_VO = 0x3, + + RTW_TX_QUEUE_BCN = 0x4, + RTW_TX_QUEUE_MGMT = 0x5, + RTW_TX_QUEUE_HI0 = 0x6, + RTW_TX_QUEUE_H2C = 0x7, + /* keep it last */ + RTK_MAX_TX_QUEUE_NUM +}; + +enum rtw_rx_queue_type { + RTW_RX_QUEUE_MPDU = 0x0, + RTW_RX_QUEUE_C2H = 0x1, + /* keep it last */ + RTK_MAX_RX_QUEUE_NUM +}; + +enum rtw_fw_type { + RTW_NORMAL_FW = 0x0, + RTW_WOWLAN_FW = 0x1, +}; + +enum rtw_rate_index { + RTW_RATEID_BGN_40M_2SS = 0, + RTW_RATEID_BGN_40M_1SS = 1, + RTW_RATEID_BGN_20M_2SS = 2, + RTW_RATEID_BGN_20M_1SS = 3, + RTW_RATEID_GN_N2SS = 4, + RTW_RATEID_GN_N1SS = 5, + RTW_RATEID_BG = 6, + RTW_RATEID_G = 7, + RTW_RATEID_B_20M = 8, + RTW_RATEID_ARFR0_AC_2SS = 9, + RTW_RATEID_ARFR1_AC_1SS = 10, + RTW_RATEID_ARFR2_AC_2G_1SS = 11, + RTW_RATEID_ARFR3_AC_2G_2SS = 12, + RTW_RATEID_ARFR4_AC_3SS = 13, + RTW_RATEID_ARFR5_N_3SS = 14, + RTW_RATEID_ARFR7_N_4SS = 15, + RTW_RATEID_ARFR6_AC_4SS = 16 +}; + +enum rtw_trx_desc_rate { + DESC_RATE1M = 0x00, + DESC_RATE2M = 0x01, + DESC_RATE5_5M = 0x02, + DESC_RATE11M = 0x03, + + DESC_RATE6M = 0x04, + DESC_RATE9M = 0x05, + DESC_RATE12M = 0x06, + DESC_RATE18M = 0x07, + DESC_RATE24M = 0x08, + DESC_RATE36M = 0x09, + DESC_RATE48M = 0x0a, + DESC_RATE54M = 0x0b, + + DESC_RATEMCS0 = 0x0c, + DESC_RATEMCS1 = 0x0d, + DESC_RATEMCS2 = 0x0e, + DESC_RATEMCS3 = 0x0f, + DESC_RATEMCS4 = 0x10, + DESC_RATEMCS5 = 0x11, + DESC_RATEMCS6 = 0x12, + DESC_RATEMCS7 = 0x13, + DESC_RATEMCS8 = 0x14, + DESC_RATEMCS9 = 0x15, + DESC_RATEMCS10 = 0x16, + DESC_RATEMCS11 = 0x17, + DESC_RATEMCS12 = 0x18, + DESC_RATEMCS13 = 0x19, + DESC_RATEMCS14 = 0x1a, + DESC_RATEMCS15 = 0x1b, + DESC_RATEMCS16 = 0x1c, + DESC_RATEMCS17 = 0x1d, + DESC_RATEMCS18 = 0x1e, + DESC_RATEMCS19 = 0x1f, + DESC_RATEMCS20 = 0x20, + DESC_RATEMCS21 = 0x21, + DESC_RATEMCS22 = 0x22, + DESC_RATEMCS23 = 0x23, + DESC_RATEMCS24 = 0x24, + DESC_RATEMCS25 = 0x25, + DESC_RATEMCS26 = 0x26, + DESC_RATEMCS27 = 0x27, + DESC_RATEMCS28 = 0x28, + DESC_RATEMCS29 = 0x29, + DESC_RATEMCS30 = 0x2a, + DESC_RATEMCS31 = 0x2b, + + DESC_RATEVHT1SS_MCS0 = 0x2c, + DESC_RATEVHT1SS_MCS1 = 0x2d, + DESC_RATEVHT1SS_MCS2 = 0x2e, + DESC_RATEVHT1SS_MCS3 = 0x2f, + DESC_RATEVHT1SS_MCS4 = 0x30, + DESC_RATEVHT1SS_MCS5 = 0x31, + DESC_RATEVHT1SS_MCS6 = 0x32, + DESC_RATEVHT1SS_MCS7 = 0x33, + DESC_RATEVHT1SS_MCS8 = 0x34, + DESC_RATEVHT1SS_MCS9 = 0x35, + + DESC_RATEVHT2SS_MCS0 = 0x36, + DESC_RATEVHT2SS_MCS1 = 0x37, + DESC_RATEVHT2SS_MCS2 = 0x38, + DESC_RATEVHT2SS_MCS3 = 0x39, + DESC_RATEVHT2SS_MCS4 = 0x3a, + DESC_RATEVHT2SS_MCS5 = 0x3b, + DESC_RATEVHT2SS_MCS6 = 0x3c, + DESC_RATEVHT2SS_MCS7 = 0x3d, + DESC_RATEVHT2SS_MCS8 = 0x3e, + DESC_RATEVHT2SS_MCS9 = 0x3f, + + DESC_RATEVHT3SS_MCS0 = 0x40, + DESC_RATEVHT3SS_MCS1 = 0x41, + DESC_RATEVHT3SS_MCS2 = 0x42, + DESC_RATEVHT3SS_MCS3 = 0x43, + DESC_RATEVHT3SS_MCS4 = 0x44, + DESC_RATEVHT3SS_MCS5 = 0x45, + DESC_RATEVHT3SS_MCS6 = 0x46, + DESC_RATEVHT3SS_MCS7 = 0x47, + DESC_RATEVHT3SS_MCS8 = 0x48, + DESC_RATEVHT3SS_MCS9 = 0x49, + + DESC_RATEVHT4SS_MCS0 = 0x4a, + DESC_RATEVHT4SS_MCS1 = 0x4b, + DESC_RATEVHT4SS_MCS2 = 0x4c, + DESC_RATEVHT4SS_MCS3 = 0x4d, + DESC_RATEVHT4SS_MCS4 = 0x4e, + DESC_RATEVHT4SS_MCS5 = 0x4f, + DESC_RATEVHT4SS_MCS6 = 0x50, + DESC_RATEVHT4SS_MCS7 = 0x51, + DESC_RATEVHT4SS_MCS8 = 0x52, + DESC_RATEVHT4SS_MCS9 = 0x53, + + DESC_RATE_MAX, +}; + +enum rtw_regulatory_domains { + RTW_REGD_FCC = 0, + RTW_REGD_MKK = 1, + RTW_REGD_ETSI = 2, + RTW_REGD_IC = 3, + RTW_REGD_KCC = 4, + RTW_REGD_ACMA = 5, + RTW_REGD_CHILE = 6, + RTW_REGD_UKRAINE = 7, + RTW_REGD_MEXICO = 8, + RTW_REGD_CN = 9, + RTW_REGD_QATAR = 10, + RTW_REGD_UK = 11, + + RTW_REGD_WW, + RTW_REGD_MAX +}; + +enum rtw_txq_flags { + RTW_TXQ_AMPDU, + RTW_TXQ_BLOCK_BA, +}; + +enum rtw_flags { + RTW_FLAG_RUNNING, + RTW_FLAG_FW_RUNNING, + RTW_FLAG_SCANNING, + RTW_FLAG_POWERON, + RTW_FLAG_LEISURE_PS, + RTW_FLAG_LEISURE_PS_DEEP, + RTW_FLAG_DIG_DISABLE, + RTW_FLAG_BUSY_TRAFFIC, + RTW_FLAG_WOWLAN, + RTW_FLAG_RESTARTING, + RTW_FLAG_RESTART_TRIGGERING, + RTW_FLAG_FORCE_LOWEST_RATE, + + NUM_OF_RTW_FLAGS, +}; + +enum rtw_evm { + RTW_EVM_OFDM = 0, + RTW_EVM_1SS, + RTW_EVM_2SS_A, + RTW_EVM_2SS_B, + RTW_EVM_3SS_A, + RTW_EVM_3SS_B, + RTW_EVM_3SS_C, + /* keep it last */ + RTW_EVM_NUM +}; + +enum rtw_snr { + RTW_SNR_OFDM_A = 0, + RTW_SNR_OFDM_B, + RTW_SNR_OFDM_C, + RTW_SNR_OFDM_D, + RTW_SNR_1SS_A, + RTW_SNR_1SS_B, + RTW_SNR_1SS_C, + RTW_SNR_1SS_D, + RTW_SNR_2SS_A, + RTW_SNR_2SS_B, + RTW_SNR_2SS_C, + RTW_SNR_2SS_D, + RTW_SNR_3SS_A, + RTW_SNR_3SS_B, + RTW_SNR_3SS_C, + RTW_SNR_3SS_D, + /* keep it last */ + RTW_SNR_NUM +}; + +enum rtw_port { + RTW_PORT_0 = 0, + RTW_PORT_1 = 1, + RTW_PORT_2 = 2, + RTW_PORT_3 = 3, + RTW_PORT_4 = 4, + RTW_PORT_NUM +}; + +enum rtw_wow_flags { + RTW_WOW_FLAG_EN_MAGIC_PKT, + RTW_WOW_FLAG_EN_REKEY_PKT, + RTW_WOW_FLAG_EN_DISCONNECT, + + /* keep it last */ + RTW_WOW_FLAG_MAX, +}; + +enum rtw_quirk_dis_caps { + QUIRK_DIS_CAP_PCI_ASPM, + QUIRK_DIS_CAP_LPS_DEEP, +}; + +/* the power index is represented by differences, which cck-1s & ht40-1s are + * the base values, so for 1s's differences, there are only ht20 & ofdm + */ +struct rtw_2g_1s_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 ofdm:4; + s8 bw20:4; +#else + s8 bw20:4; + s8 ofdm:4; +#endif +} __packed; + +struct rtw_2g_ns_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 bw20:4; + s8 bw40:4; + s8 cck:4; + s8 ofdm:4; +#else + s8 ofdm:4; + s8 cck:4; + s8 bw40:4; + s8 bw20:4; +#endif +} __packed; + +struct rtw_2g_txpwr_idx { + u8 cck_base[6]; + u8 bw40_base[5]; + struct rtw_2g_1s_pwr_idx_diff ht_1s_diff; + struct rtw_2g_ns_pwr_idx_diff ht_2s_diff; + struct rtw_2g_ns_pwr_idx_diff ht_3s_diff; + struct rtw_2g_ns_pwr_idx_diff ht_4s_diff; +}; + +struct rtw_5g_ht_1s_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 ofdm:4; + s8 bw20:4; +#else + s8 bw20:4; + s8 ofdm:4; +#endif +} __packed; + +struct rtw_5g_ht_ns_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 bw20:4; + s8 bw40:4; +#else + s8 bw40:4; + s8 bw20:4; +#endif +} __packed; + +struct rtw_5g_ofdm_ns_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 ofdm_3s:4; + s8 ofdm_2s:4; + s8 ofdm_4s:4; + s8 res:4; +#else + s8 res:4; + s8 ofdm_4s:4; + s8 ofdm_2s:4; + s8 ofdm_3s:4; +#endif +} __packed; + +struct rtw_5g_vht_ns_pwr_idx_diff { +#ifdef __LITTLE_ENDIAN + s8 bw160:4; + s8 bw80:4; +#else + s8 bw80:4; + s8 bw160:4; +#endif +} __packed; + +struct rtw_5g_txpwr_idx { + u8 bw40_base[14]; + struct rtw_5g_ht_1s_pwr_idx_diff ht_1s_diff; + struct rtw_5g_ht_ns_pwr_idx_diff ht_2s_diff; + struct rtw_5g_ht_ns_pwr_idx_diff ht_3s_diff; + struct rtw_5g_ht_ns_pwr_idx_diff ht_4s_diff; + struct rtw_5g_ofdm_ns_pwr_idx_diff ofdm_diff; + struct rtw_5g_vht_ns_pwr_idx_diff vht_1s_diff; + struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff; + struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff; + struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff; +} __packed; + +struct rtw_txpwr_idx { + struct rtw_2g_txpwr_idx pwr_idx_2g; + struct rtw_5g_txpwr_idx pwr_idx_5g; +} __packed; + +struct rtw_channel_params { + u8 center_chan; + u8 primary_chan; + u8 bandwidth; +}; + +struct rtw_hw_reg { + u32 addr; + u32 mask; +}; + +struct rtw_hw_reg_desc { + u32 addr; + u32 mask; + const char *desc; +}; + +struct rtw_ltecoex_addr { + u32 ctrl; + u32 wdata; + u32 rdata; +}; + +struct rtw_reg_domain { + u32 addr; + u32 mask; +#define RTW_REG_DOMAIN_MAC32 0 +#define RTW_REG_DOMAIN_MAC16 1 +#define RTW_REG_DOMAIN_MAC8 2 +#define RTW_REG_DOMAIN_RF_A 3 +#define RTW_REG_DOMAIN_RF_B 4 +#define RTW_REG_DOMAIN_NL 0xFF + u8 domain; +}; + +struct rtw_rf_sipi_addr { + u32 hssi_1; + u32 hssi_2; + u32 lssi_read; + u32 lssi_read_pi; +}; + +struct rtw_hw_reg_offset { + struct rtw_hw_reg hw_reg; + u8 offset; +}; + +struct rtw_backup_info { + u8 len; + u32 reg; + u32 val; +}; + +enum rtw_vif_port_set { + PORT_SET_MAC_ADDR = BIT(0), + PORT_SET_BSSID = BIT(1), + PORT_SET_NET_TYPE = BIT(2), + PORT_SET_AID = BIT(3), + PORT_SET_BCN_CTRL = BIT(4), +}; + +struct rtw_vif_port { + struct rtw_hw_reg mac_addr; + struct rtw_hw_reg bssid; + struct rtw_hw_reg net_type; + struct rtw_hw_reg aid; + struct rtw_hw_reg bcn_ctrl; +}; + +struct rtw_tx_pkt_info { + u32 tx_pkt_size; + u8 offset; + u8 pkt_offset; + u8 tim_offset; + u8 mac_id; + u8 rate_id; + u8 rate; + u8 qsel; + u8 bw; + u8 sec_type; + u8 sn; + bool ampdu_en; + u8 ampdu_factor; + u8 ampdu_density; + u16 seq; + bool stbc; + bool ldpc; + bool dis_rate_fallback; + bool bmc; + bool use_rate; + bool ls; + bool fs; + bool short_gi; + bool report; + bool rts; + bool dis_qselseq; + bool en_hwseq; + u8 hw_ssn_sel; + bool nav_use_hdr; + bool bt_null; +}; + +struct rtw_rx_pkt_stat { + bool phy_status; + bool icv_err; + bool crc_err; + bool decrypted; + bool is_c2h; + bool channel_invalid; + + s32 signal_power; + u16 pkt_len; + u8 bw; + u8 drv_info_sz; + u8 shift; + u8 rate; + u8 mac_id; + u8 cam_id; + u8 ppdu_cnt; + u32 tsf_low; + s8 rx_power[RTW_RF_PATH_MAX]; + u8 rssi; + u8 rxsc; + s8 rx_snr[RTW_RF_PATH_MAX]; + u8 rx_evm[RTW_RF_PATH_MAX]; + s8 cfo_tail[RTW_RF_PATH_MAX]; + u16 freq; + u8 band; + + struct rtw_sta_info *si; + struct ieee80211_vif *vif; + struct ieee80211_hdr *hdr; +}; + +DECLARE_EWMA(tp, 10, 2); + +struct rtw_traffic_stats { + /* units in bytes */ + u64 tx_unicast; + u64 rx_unicast; + + /* count for packets */ + u64 tx_cnt; + u64 rx_cnt; + + /* units in Mbps */ + u32 tx_throughput; + u32 rx_throughput; + struct ewma_tp tx_ewma_tp; + struct ewma_tp rx_ewma_tp; +}; + +enum rtw_lps_mode { + RTW_MODE_ACTIVE = 0, + RTW_MODE_LPS = 1, + RTW_MODE_WMM_PS = 2, +}; + +enum rtw_lps_deep_mode { + LPS_DEEP_MODE_NONE = 0, + LPS_DEEP_MODE_LCLK = 1, + LPS_DEEP_MODE_PG = 2, +}; + +enum rtw_pwr_state { + RTW_RF_OFF = 0x0, + RTW_RF_ON = 0x4, + RTW_ALL_ON = 0xc, +}; + +struct rtw_lps_conf { + enum rtw_lps_mode mode; + enum rtw_lps_deep_mode deep_mode; + enum rtw_lps_deep_mode wow_deep_mode; + enum rtw_pwr_state state; + u8 awake_interval; + u8 rlbm; + u8 smart_ps; + u8 port_id; + bool sec_cam_backup; + bool pattern_cam_backup; +}; + +enum rtw_hw_key_type { + RTW_CAM_NONE = 0, + RTW_CAM_WEP40 = 1, + RTW_CAM_TKIP = 2, + RTW_CAM_AES = 4, + RTW_CAM_WEP104 = 5, +}; + +struct rtw_cam_entry { + bool valid; + bool group; + u8 addr[ETH_ALEN]; + u8 hw_key_type; + struct ieee80211_key_conf *key; +}; + +struct rtw_sec_desc { + /* search strategy */ + bool default_key_search; + + u32 total_cam_num; + struct rtw_cam_entry cam_table[RTW_MAX_SEC_CAM_NUM]; + DECLARE_BITMAP(cam_map, RTW_MAX_SEC_CAM_NUM); +}; + +struct rtw_tx_report { + /* protect the tx report queue */ + spinlock_t q_lock; + struct sk_buff_head queue; + atomic_t sn; + struct timer_list purge_timer; +}; + +struct rtw_ra_report { + struct rate_info txrate; + u32 bit_rate; + u8 desc_rate; +}; + +struct rtw_txq { + struct list_head list; + unsigned long flags; +}; + +DECLARE_EWMA(rssi, 10, 16); + +struct rtw_sta_info { + struct rtw_dev *rtwdev; + struct ieee80211_sta *sta; + struct ieee80211_vif *vif; + + struct ewma_rssi avg_rssi; + u8 rssi_level; + + u8 mac_id; + u8 rate_id; + enum rtw_bandwidth bw_mode; + u8 stbc_en:2; + u8 ldpc_en:2; + bool sgi_enable; + bool vht_enable; + u8 init_ra_lv; + u64 ra_mask; + + DECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS); + + struct rtw_ra_report ra_report; + + bool use_cfg_mask; + struct cfg80211_bitrate_mask *mask; + + struct work_struct rc_work; +}; + +enum rtw_bfee_role { + RTW_BFEE_NONE, + RTW_BFEE_SU, + RTW_BFEE_MU +}; + +struct rtw_bfee { + enum rtw_bfee_role role; + + u16 p_aid; + u8 g_id; + u8 mac_addr[ETH_ALEN]; + u8 sound_dim; + + /* SU-MIMO */ + u8 su_reg_index; + + /* MU-MIMO */ + u16 aid; +}; + +struct rtw_bf_info { + u8 bfer_mu_cnt; + u8 bfer_su_cnt; + DECLARE_BITMAP(bfer_su_reg_maping, 2); + u8 cur_csi_rpt_rate; +}; + +struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; + u8 mac_id; + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; + u8 bcn_ctrl; + struct list_head rsvd_page_list; + struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; + const struct rtw_vif_port *conf; + struct cfg80211_scan_request *scan_req; + struct ieee80211_scan_ies *scan_ies; + + struct rtw_traffic_stats stats; + + struct rtw_bfee bfee; +}; + +struct rtw_regulatory { + char alpha2[2] __nonstring; + u8 txpwr_regd_2g; + u8 txpwr_regd_5g; +}; + +enum rtw_regd_state { + RTW_REGD_STATE_WORLDWIDE, + RTW_REGD_STATE_PROGRAMMED, + RTW_REGD_STATE_SETTING, + + RTW_REGD_STATE_NR, +}; + +struct rtw_regd { + enum rtw_regd_state state; + const struct rtw_regulatory *regulatory; + enum nl80211_dfs_regions dfs_region; +}; + +struct rtw_chip_ops { + int (*power_on)(struct rtw_dev *rtwdev); + void (*power_off)(struct rtw_dev *rtwdev); + int (*mac_init)(struct rtw_dev *rtwdev); + int (*mac_postinit)(struct rtw_dev *rtwdev); + int (*dump_fw_crash)(struct rtw_dev *rtwdev); + void (*shutdown)(struct rtw_dev *rtwdev); + int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map); + void (*phy_set_param)(struct rtw_dev *rtwdev); + void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, + u8 bandwidth, u8 primary_chan_idx); + void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat); + u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); + bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data); + void (*set_tx_power_index)(struct rtw_dev *rtwdev); + int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset, + u32 size); + int (*set_antenna)(struct rtw_dev *rtwdev, int radio_idx, + u32 antenna_tx, + u32 antenna_rx); + void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); + void (*efuse_grant)(struct rtw_dev *rtwdev, bool enable); + void (*set_ampdu_factor)(struct rtw_dev *rtwdev, u8 factor); + void (*false_alarm_statistics)(struct rtw_dev *rtwdev); + void (*phy_calibration)(struct rtw_dev *rtwdev); + void (*dpk_track)(struct rtw_dev *rtwdev); + void (*cck_pd_set)(struct rtw_dev *rtwdev, u8 level); + void (*pwr_track)(struct rtw_dev *rtwdev); + void (*config_bfee)(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable); + void (*set_gid_table)(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); + void (*cfg_csi_rate)(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate); + void (*adaptivity_init)(struct rtw_dev *rtwdev); + void (*adaptivity)(struct rtw_dev *rtwdev); + void (*cfo_init)(struct rtw_dev *rtwdev); + void (*cfo_track)(struct rtw_dev *rtwdev); + void (*config_tx_path)(struct rtw_dev *rtwdev, u8 tx_path, + enum rtw_bb_path tx_path_1ss, + enum rtw_bb_path tx_path_cck, + bool is_tx2_path); + void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path); + void (*led_set)(struct led_classdev *led, enum led_brightness brightness); + /* for USB/SDIO only */ + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc); + + /* for coex */ + void (*coex_set_init)(struct rtw_dev *rtwdev); + void (*coex_set_ant_switch)(struct rtw_dev *rtwdev, + u8 ctrl_type, u8 pos_type); + void (*coex_set_gnt_fix)(struct rtw_dev *rtwdev); + void (*coex_set_gnt_debug)(struct rtw_dev *rtwdev); + void (*coex_set_rfe_type)(struct rtw_dev *rtwdev); + void (*coex_set_wl_tx_power)(struct rtw_dev *rtwdev, u8 wl_pwr); + void (*coex_set_wl_rx_gain)(struct rtw_dev *rtwdev, bool low_gain); +}; + +#define RTW_PWR_POLLING_CNT 20000 + +#define RTW_PWR_CMD_READ 0x00 +#define RTW_PWR_CMD_WRITE 0x01 +#define RTW_PWR_CMD_POLLING 0x02 +#define RTW_PWR_CMD_DELAY 0x03 +#define RTW_PWR_CMD_END 0x04 + +/* define the base address of each block */ +#define RTW_PWR_ADDR_MAC 0x00 +#define RTW_PWR_ADDR_USB 0x01 +#define RTW_PWR_ADDR_PCIE 0x02 +#define RTW_PWR_ADDR_SDIO 0x03 + +#define RTW_PWR_INTF_SDIO_MSK BIT(0) +#define RTW_PWR_INTF_USB_MSK BIT(1) +#define RTW_PWR_INTF_PCI_MSK BIT(2) +#define RTW_PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define RTW_PWR_CUT_TEST_MSK BIT(0) +#define RTW_PWR_CUT_A_MSK BIT(1) +#define RTW_PWR_CUT_B_MSK BIT(2) +#define RTW_PWR_CUT_C_MSK BIT(3) +#define RTW_PWR_CUT_D_MSK BIT(4) +#define RTW_PWR_CUT_E_MSK BIT(5) +#define RTW_PWR_CUT_F_MSK BIT(6) +#define RTW_PWR_CUT_G_MSK BIT(7) +#define RTW_PWR_CUT_ALL_MSK 0xFF + +enum rtw_pwr_seq_cmd_delay_unit { + RTW_PWR_DELAY_US, + RTW_PWR_DELAY_MS, +}; + +struct rtw_pwr_seq_cmd { + u16 offset; + u8 cut_mask; + u8 intf_mask; + u8 base:4; + u8 cmd:4; + u8 mask; + u8 value; +}; + +enum rtw_chip_ver { + RTW_CHIP_VER_CUT_A = 0x00, + RTW_CHIP_VER_CUT_B = 0x01, + RTW_CHIP_VER_CUT_C = 0x02, + RTW_CHIP_VER_CUT_D = 0x03, + RTW_CHIP_VER_CUT_E = 0x04, + RTW_CHIP_VER_CUT_F = 0x05, + RTW_CHIP_VER_CUT_G = 0x06, +}; + +#define RTW_INTF_PHY_PLATFORM_ALL 0 + +enum rtw_intf_phy_cut { + RTW_INTF_PHY_CUT_A = BIT(0), + RTW_INTF_PHY_CUT_B = BIT(1), + RTW_INTF_PHY_CUT_C = BIT(2), + RTW_INTF_PHY_CUT_D = BIT(3), + RTW_INTF_PHY_CUT_E = BIT(4), + RTW_INTF_PHY_CUT_F = BIT(5), + RTW_INTF_PHY_CUT_G = BIT(6), + RTW_INTF_PHY_CUT_ALL = 0xFFFF, +}; + +enum rtw_ip_sel { + RTW_IP_SEL_PHY = 0, + RTW_IP_SEL_MAC = 1, + RTW_IP_SEL_DBI = 2, + + RTW_IP_SEL_UNDEF = 0xFFFF +}; + +enum rtw_pq_map_id { + RTW_PQ_MAP_VO = 0x0, + RTW_PQ_MAP_VI = 0x1, + RTW_PQ_MAP_BE = 0x2, + RTW_PQ_MAP_BK = 0x3, + RTW_PQ_MAP_MG = 0x4, + RTW_PQ_MAP_HI = 0x5, + RTW_PQ_MAP_NUM = 0x6, + + RTW_PQ_MAP_UNDEF, +}; + +enum rtw_dma_mapping { + RTW_DMA_MAPPING_EXTRA = 0, + RTW_DMA_MAPPING_LOW = 1, + RTW_DMA_MAPPING_NORMAL = 2, + RTW_DMA_MAPPING_HIGH = 3, + + RTW_DMA_MAPPING_MAX, + RTW_DMA_MAPPING_UNDEF, +}; + +struct rtw_rqpn { + enum rtw_dma_mapping dma_map_vo; + enum rtw_dma_mapping dma_map_vi; + enum rtw_dma_mapping dma_map_be; + enum rtw_dma_mapping dma_map_bk; + enum rtw_dma_mapping dma_map_mg; + enum rtw_dma_mapping dma_map_hi; +}; + +struct rtw_prioq_addr { + u32 rsvd; + u32 avail; +}; + +struct rtw_prioq_addrs { + struct rtw_prioq_addr prio[RTW_DMA_MAPPING_MAX]; + bool wsize; +}; + +struct rtw_page_table { + u16 hq_num; + u16 nq_num; + u16 lq_num; + u16 exq_num; + u16 gapq_num; +}; + +struct rtw_intf_phy_para { + u16 offset; + u16 value; + u16 ip_sel; + u16 cut_mask; + u16 platform; +}; + +struct rtw_wow_pattern { + u16 crc; + u8 type; + u8 valid; + u8 mask[RTW_MAX_PATTERN_MASK_SIZE]; +}; + +struct rtw_pno_request { + bool inited; + u32 match_set_cnt; + struct cfg80211_match_set *match_sets; + u8 channel_cnt; + struct ieee80211_channel *channels; + struct cfg80211_sched_scan_plan scan_plan; +}; + +struct rtw_wow_param { + struct ieee80211_vif *wow_vif; + DECLARE_BITMAP(flags, RTW_WOW_FLAG_MAX); + u8 txpause; + u8 pattern_cnt; + struct rtw_wow_pattern patterns[RTW_MAX_PATTERN_NUM]; + + bool ips_enabled; + struct rtw_pno_request pno_req; +}; + +struct rtw_intf_phy_para_table { + const struct rtw_intf_phy_para *usb2_para; + const struct rtw_intf_phy_para *usb3_para; + const struct rtw_intf_phy_para *gen1_para; + const struct rtw_intf_phy_para *gen2_para; + u8 n_usb2_para; + u8 n_usb3_para; + u8 n_gen1_para; + u8 n_gen2_para; +}; + +struct rtw_table { + const void *data; + const u32 size; + void (*parse)(struct rtw_dev *rtwdev, const struct rtw_table *tbl); + void (*do_cfg)(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data); + enum rtw_rf_path rf_path; +}; + +static inline void rtw_load_table(struct rtw_dev *rtwdev, + const struct rtw_table *tbl) +{ + (*tbl->parse)(rtwdev, tbl); +} + +enum rtw_rfe_fem { + RTW_RFE_IFEM, + RTW_RFE_EFEM, + RTW_RFE_IFEM2G_EFEM5G, + RTW_RFE_NUM, +}; + +struct rtw_rfe_def { + const struct rtw_table *phy_pg_tbl; + const struct rtw_table *txpwr_lmt_tbl; + const struct rtw_pwr_track_tbl *pwr_track_tbl; + const struct rtw_table *agc_btg_tbl; +}; + +#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ + .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + } + +#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ + .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + .agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \ + } + +#define RTW_PWR_TRK_5G_1 0 +#define RTW_PWR_TRK_5G_2 1 +#define RTW_PWR_TRK_5G_3 2 +#define RTW_PWR_TRK_5G_NUM 3 + +#define RTW_PWR_TRK_TBL_SZ 30 + +/* This table stores the values of TX power that will be adjusted by power + * tracking. + * + * For 5G bands, there are 3 different settings. + * For 2G there are cck rate and ofdm rate with different settings. + */ +struct rtw_pwr_track_tbl { + const u8 *pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_2gd_n; + const u8 *pwrtrk_2gd_p; + const u8 *pwrtrk_2gc_n; + const u8 *pwrtrk_2gc_p; + const u8 *pwrtrk_2gb_n; + const u8 *pwrtrk_2gb_p; + const u8 *pwrtrk_2ga_n; + const u8 *pwrtrk_2ga_p; + const u8 *pwrtrk_2g_cckd_n; + const u8 *pwrtrk_2g_cckd_p; + const u8 *pwrtrk_2g_cckc_n; + const u8 *pwrtrk_2g_cckc_p; + const u8 *pwrtrk_2g_cckb_n; + const u8 *pwrtrk_2g_cckb_p; + const u8 *pwrtrk_2g_ccka_n; + const u8 *pwrtrk_2g_ccka_p; + const s8 *pwrtrk_xtal_n; + const s8 *pwrtrk_xtal_p; +}; + +enum rtw_wlan_cpu { + RTW_WCPU_3081, + RTW_WCPU_8051, +}; + +enum rtw_fw_fifo_sel { + RTW_FW_FIFO_SEL_TX, + RTW_FW_FIFO_SEL_RX, + RTW_FW_FIFO_SEL_RSVD_PAGE, + RTW_FW_FIFO_SEL_REPORT, + RTW_FW_FIFO_SEL_LLT, + RTW_FW_FIFO_SEL_RXBUF_FW, + + RTW_FW_FIFO_MAX, +}; + +enum rtw_fwcd_item { + RTW_FWCD_TLV, + RTW_FWCD_REG, + RTW_FWCD_ROM, + RTW_FWCD_IMEM, + RTW_FWCD_DMEM, + RTW_FWCD_EMEM, +}; + +/* hardware configuration for each IC */ +struct rtw_chip_info { + const struct rtw_chip_ops *ops; + u8 id; + + const char *fw_name; + enum rtw_wlan_cpu wlan_cpu; + u8 tx_pkt_desc_sz; + u8 tx_buf_desc_sz; + u8 rx_pkt_desc_sz; + u8 rx_buf_desc_sz; + u32 phy_efuse_size; + u32 log_efuse_size; + u32 ptct_efuse_size; + u32 txff_size; + u32 rxff_size; + u32 fw_rxff_size; + u16 rsvd_drv_pg_num; + u8 band; + u16 page_size; + u8 csi_buf_pg_num; + u8 dig_max; + u8 dig_min; + u8 txgi_factor; + bool is_pwr_by_rate_dec; + bool rx_ldpc; + bool tx_stbc; + u8 max_power_index; + u8 ampdu_density; + + u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; + const struct rtw_fwcd_segs *fwcd_segs; + + bool amsdu_in_ampdu; + u8 usb_tx_agg_desc_num; + bool hw_feature_report; + u8 c2h_ra_report_size; + bool old_datarate_fb_limit; + + u8 default_1ss_tx_path; + + bool path_div_supported; + bool ht_supported; + bool vht_supported; + u8 lps_deep_mode_supported; + + /* init values */ + u8 sys_func_en; + const struct rtw_pwr_seq_cmd * const *pwr_on_seq; + const struct rtw_pwr_seq_cmd * const *pwr_off_seq; + const struct rtw_rqpn *rqpn_table; + const struct rtw_prioq_addrs *prioq_addrs; + const struct rtw_page_table *page_table; + const struct rtw_intf_phy_para_table *intf_table; + + const struct rtw_hw_reg *dig; + const struct rtw_hw_reg *dig_cck; + u32 rf_base_addr[RTW_RF_PATH_MAX]; + u32 rf_sipi_addr[RTW_RF_PATH_MAX]; + const struct rtw_rf_sipi_addr *rf_sipi_read_addr; + u8 fix_rf_phy_num; + const struct rtw_ltecoex_addr *ltecoex_addr; + + const struct rtw_table *mac_tbl; + const struct rtw_table *agc_tbl; + const struct rtw_table *bb_tbl; + const struct rtw_table *rf_tbl[RTW_RF_PATH_MAX]; + const struct rtw_table *rfk_init_tbl; + + const struct rtw_rfe_def *rfe_defs; + u32 rfe_defs_size; + + bool en_dis_dpd; + u16 dpd_ratemask; + u8 iqk_threshold; + u8 lck_threshold; + + u8 bfer_su_max_num; + u8 bfer_mu_max_num; + + const struct rtw_hw_reg_offset *edcca_th; + s8 l2h_th_ini_cs; + s8 l2h_th_ini_ad; + + const char *wow_fw_name; + const struct wiphy_wowlan_support *wowlan_stub; + const u8 max_sched_scan_ssids; + const u16 max_scan_ie_len; + + /* coex paras */ + u32 coex_para_ver; + u8 bt_desired_ver; + bool scbd_support; + bool new_scbd10_def; /* true: fix 2M(8822c) */ + bool ble_hid_profile_support; + bool wl_mimo_ps_support; + u8 pstdma_type; /* 0: LPSoff, 1:LPSon */ + u8 bt_rssi_type; + u8 ant_isolation; + u8 rssi_tolerance; + u8 table_sant_num; + u8 table_nsant_num; + u8 tdma_sant_num; + u8 tdma_nsant_num; + u8 bt_afh_span_bw20; + u8 bt_afh_span_bw40; + u8 afh_5g_num; + u8 wl_rf_para_num; + u8 coex_info_hw_regs_num; + const u8 *bt_rssi_step; + const u8 *wl_rssi_step; + const struct coex_table_para *table_nsant; + const struct coex_table_para *table_sant; + const struct coex_tdma_para *tdma_sant; + const struct coex_tdma_para *tdma_nsant; + const struct coex_rf_para *wl_rf_para_tx; + const struct coex_rf_para *wl_rf_para_rx; + const struct coex_5g_afh_map *afh_5g; + const struct rtw_hw_reg *btg_reg; + const struct rtw_reg_domain *coex_info_hw_regs; + u32 wl_fw_desired_ver; +}; + +enum rtw_coex_bt_state_cnt { + COEX_CNT_BT_RETRY, + COEX_CNT_BT_REINIT, + COEX_CNT_BT_REENABLE, + COEX_CNT_BT_POPEVENT, + COEX_CNT_BT_SETUPLINK, + COEX_CNT_BT_IGNWLANACT, + COEX_CNT_BT_INQ, + COEX_CNT_BT_PAGE, + COEX_CNT_BT_ROLESWITCH, + COEX_CNT_BT_AFHUPDATE, + COEX_CNT_BT_INFOUPDATE, + COEX_CNT_BT_IQK, + COEX_CNT_BT_IQKFAIL, + + COEX_CNT_BT_MAX +}; + +enum rtw_coex_wl_state_cnt { + COEX_CNT_WL_SCANAP, + COEX_CNT_WL_CONNPKT, + COEX_CNT_WL_COEXRUN, + COEX_CNT_WL_NOISY0, + COEX_CNT_WL_NOISY1, + COEX_CNT_WL_NOISY2, + COEX_CNT_WL_5MS_NOEXTEND, + COEX_CNT_WL_FW_NOTIFY, + + COEX_CNT_WL_MAX +}; + +struct rtw_coex_rfe { + bool ant_switch_exist; + bool ant_switch_diversity; + bool ant_switch_with_bt; + u8 rfe_module_type; + u8 ant_switch_polarity; + + /* true if WLG at BTG, else at WLAG */ + bool wlg_at_btg; +}; + +#define COEX_WL_TDMA_PARA_LENGTH 5 + +struct rtw_coex_dm { + bool cur_ps_tdma_on; + bool cur_wl_rx_low_gain_en; + bool ignore_wl_act; + + u8 reason; + u8 bt_rssi_state[4]; + u8 wl_rssi_state[4]; + u8 wl_ch_info[3]; + u8 cur_ps_tdma; + u8 cur_table; + u8 ps_tdma_para[5]; + u8 cur_bt_pwr_lvl; + u8 cur_bt_lna_lvl; + u8 cur_wl_pwr_lvl; + u8 bt_status; + u32 cur_ant_pos_type; + u32 cur_switch_status; + u32 setting_tdma; + u8 fw_tdma_para[COEX_WL_TDMA_PARA_LENGTH]; +}; + +#define COEX_BTINFO_SRC_WL_FW 0x0 +#define COEX_BTINFO_SRC_BT_RSP 0x1 +#define COEX_BTINFO_SRC_BT_ACT 0x2 +#define COEX_BTINFO_SRC_BT_IQK 0x3 +#define COEX_BTINFO_SRC_BT_SCBD 0x4 +#define COEX_BTINFO_SRC_H2C60 0x5 +#define COEX_BTINFO_SRC_MAX 0x6 + +#define COEX_INFO_FTP BIT(7) +#define COEX_INFO_A2DP BIT(6) +#define COEX_INFO_HID BIT(5) +#define COEX_INFO_SCO_BUSY BIT(4) +#define COEX_INFO_ACL_BUSY BIT(3) +#define COEX_INFO_INQ_PAGE BIT(2) +#define COEX_INFO_SCO_ESCO BIT(1) +#define COEX_INFO_CONNECTION BIT(0) +#define COEX_BTINFO_LENGTH_MAX 10 +#define COEX_BTINFO_LENGTH 7 + +#define COEX_BT_HIDINFO_LIST 0x0 +#define COEX_BT_HIDINFO_A 0x1 +#define COEX_BT_HIDINFO_NAME 3 + +#define COEX_BT_HIDINFO_LENGTH 6 +#define COEX_BT_HIDINFO_HANDLE_NUM 4 +#define COEX_BT_HIDINFO_C2H_HANDLE 0 +#define COEX_BT_HIDINFO_C2H_VENDOR 1 +#define COEX_BT_BLE_HANDLE_THRS 0x10 +#define COEX_BT_HIDINFO_NOTCON 0xff + +struct rtw_coex_hid { + u8 hid_handle; + u8 hid_vendor; + u8 hid_name[COEX_BT_HIDINFO_NAME]; + bool hid_info_completed; + bool is_game_hid; +}; + +struct rtw_coex_hid_handle_list { + u8 cmd_id; + u8 len; + u8 subid; + u8 handle_cnt; + u8 handle[COEX_BT_HIDINFO_HANDLE_NUM]; +} __packed; + +struct rtw_coex_hid_info_a { + u8 cmd_id; + u8 len; + u8 subid; + u8 handle; + u8 vendor; + u8 name[COEX_BT_HIDINFO_NAME]; +} __packed; + +struct rtw_coex_stat { + bool bt_disabled; + bool bt_disabled_pre; + bool bt_link_exist; + bool bt_whck_test; + bool bt_inq_page; + bool bt_inq_remain; + bool bt_inq; + bool bt_page; + bool bt_ble_voice; + bool bt_ble_exist; + bool bt_hfp_exist; + bool bt_a2dp_exist; + bool bt_hid_exist; + bool bt_pan_exist; /* PAN or OPP */ + bool bt_opp_exist; /* OPP only */ + bool bt_acl_busy; + bool bt_fix_2M; + bool bt_setup_link; + bool bt_multi_link; + bool bt_multi_link_pre; + bool bt_multi_link_remain; + bool bt_a2dp_sink; + bool bt_a2dp_active; + bool bt_reenable; + bool bt_ble_scan_en; + bool bt_init_scan; + bool bt_slave; + bool bt_418_hid_exist; + bool bt_ble_hid_exist; + bool bt_game_hid_exist; + bool bt_hid_handle_cnt; + bool bt_mailbox_reply; + bool bt_ctr_ok; + + bool wl_under_lps; + bool wl_under_ips; + bool wl_hi_pri_task1; + bool wl_hi_pri_task2; + bool wl_force_lps_ctrl; + bool wl_gl_busy; + bool wl_linkscan_proc; + bool wl_ps_state_fail; + bool wl_tx_limit_en; + bool wl_ampdu_limit_en; + bool wl_connected; + bool wl_slot_extend; + bool wl_cck_lock; + bool wl_cck_lock_pre; + bool wl_cck_lock_ever; + bool wl_connecting; + bool wl_slot_toggle; + bool wl_slot_toggle_change; /* if toggle to no-toggle */ + bool wl_mimo_ps; + + u32 bt_supported_version; + u32 bt_supported_feature; + u32 hi_pri_tx; + u32 hi_pri_rx; + u32 lo_pri_tx; + u32 lo_pri_rx; + u32 patch_ver; + u16 bt_reg_vendor_ae; + u16 bt_reg_vendor_ac; + s8 bt_rssi; + u8 kt_ver; + u8 gnt_workaround_state; + u8 tdma_timer_base; + u8 bt_profile_num; + u8 bt_info_c2h[COEX_BTINFO_SRC_MAX][COEX_BTINFO_LENGTH_MAX]; + u8 bt_info_lb2; + u8 bt_info_lb3; + u8 bt_info_hb0; + u8 bt_info_hb1; + u8 bt_info_hb2; + u8 bt_info_hb3; + u8 bt_ble_scan_type; + u8 bt_hid_pair_num; + u8 bt_hid_slot; + u8 bt_a2dp_bitpool; + u8 bt_iqk_state; + u8 bt_disable_cnt; + + u16 wl_beacon_interval; + u8 wl_noisy_level; + u8 wl_fw_dbg_info[10]; + u8 wl_fw_dbg_info_pre[10]; + u8 wl_rx_rate; + u8 wl_tx_rate; + u8 wl_rts_rx_rate; + u8 wl_coex_mode; + u8 wl_iot_peer; + u8 ampdu_max_time; + u8 wl_tput_dir; + + u8 wl_toggle_para[6]; + u8 wl_toggle_interval; + + u16 score_board; + u16 retry_limit; + + /* counters to record bt states */ + u32 cnt_bt[COEX_CNT_BT_MAX]; + + /* counters to record wifi states */ + u32 cnt_wl[COEX_CNT_WL_MAX]; + + /* counters to record bt c2h data */ + u32 cnt_bt_info_c2h[COEX_BTINFO_SRC_MAX]; + + u32 darfrc; + u32 darfrch; + + struct rtw_coex_hid hid_info[COEX_BT_HIDINFO_HANDLE_NUM]; + struct rtw_coex_hid_handle_list hid_handle_list; +}; + +struct rtw_coex { + struct sk_buff_head queue; + wait_queue_head_t wait; + + bool under_5g; + bool stop_dm; + bool freeze; + bool freerun; + bool wl_rf_off; + bool manual_control; + + struct rtw_coex_stat stat; + struct rtw_coex_dm dm; + struct rtw_coex_rfe rfe; + + struct delayed_work bt_relink_work; + struct delayed_work bt_reenable_work; + struct delayed_work defreeze_work; + struct delayed_work wl_remain_work; + struct delayed_work bt_remain_work; + struct delayed_work wl_connecting_work; + struct delayed_work bt_multi_link_remain_work; + struct delayed_work wl_ccklock_work; + +}; + +#define DPK_RF_REG_NUM 7 +#define DPK_RF_PATH_NUM 2 +#define DPK_BB_REG_NUM 18 +#define DPK_CHANNEL_WIDTH_80 1 + +DECLARE_EWMA(thermal, 10, 4); + +struct rtw_dpk_info { + bool is_dpk_pwr_on; + bool is_reload; + + DECLARE_BITMAP(dpk_path_ok, DPK_RF_PATH_NUM); + + u8 thermal_dpk[DPK_RF_PATH_NUM]; + struct ewma_thermal avg_thermal[DPK_RF_PATH_NUM]; + + u32 gnt_control; + u32 gnt_value; + + u8 result[RTW_RF_PATH_MAX]; + u8 dpk_txagc[RTW_RF_PATH_MAX]; + u32 coef[RTW_RF_PATH_MAX][20]; + u16 dpk_gs[RTW_RF_PATH_MAX]; + u8 thermal_dpk_delta[RTW_RF_PATH_MAX]; + u8 pre_pwsf[RTW_RF_PATH_MAX]; + + u8 dpk_band; + u8 dpk_ch; + u8 dpk_bw; +}; + +struct rtw_phy_cck_pd_reg { + u32 reg_pd; + u32 mask_pd; + u32 reg_cs; + u32 mask_cs; +}; + +#define DACK_MSBK_BACKUP_NUM 0xf +#define DACK_DCK_BACKUP_NUM 0x2 + +struct rtw_swing_table { + const u8 *p[RTW_RF_PATH_MAX]; + const u8 *n[RTW_RF_PATH_MAX]; +}; + +struct rtw_pkt_count { + u16 num_bcn_pkt; + u16 num_qry_pkt[DESC_RATE_MAX]; +}; + +DECLARE_EWMA(evm, 10, 4); +DECLARE_EWMA(snr, 10, 4); + +struct rtw_iqk_info { + bool done; + struct { + u32 s1_x; + u32 s1_y; + u32 s0_x; + u32 s0_y; + } result; +}; + +enum rtw_rf_band { + RF_BAND_2G_CCK, + RF_BAND_2G_OFDM, + RF_BAND_5G_L, + RF_BAND_5G_M, + RF_BAND_5G_H, + RF_BAND_MAX +}; + +#define RF_GAIN_NUM 11 +#define RF_HW_OFFSET_NUM 10 + +struct rtw_gapk_info { + u32 rf3f_bp[RF_BAND_MAX][RF_GAIN_NUM][RTW_RF_PATH_MAX]; + u32 rf3f_fs[RTW_RF_PATH_MAX][RF_GAIN_NUM]; + bool txgapk_bp_done; + s8 offset[RF_GAIN_NUM][RTW_RF_PATH_MAX]; + s8 fianl_offset[RF_GAIN_NUM][RTW_RF_PATH_MAX]; + u8 read_txgain; + u8 channel; +}; + +#define EDCCA_TH_L2H_IDX 0 +#define EDCCA_TH_H2L_IDX 1 +#define EDCCA_TH_L2H_LB 48 +#define EDCCA_ADC_BACKOFF 12 +#define EDCCA_IGI_BASE 50 +#define EDCCA_IGI_L2H_DIFF 8 +#define EDCCA_L2H_H2L_DIFF 7 +#define EDCCA_L2H_H2L_DIFF_NORMAL 8 + +enum rtw_edcca_mode { + RTW_EDCCA_NORMAL = 0, + RTW_EDCCA_ADAPTIVITY = 1, +}; + +struct rtw_cfo_track { + bool is_adjust; + u8 crystal_cap; + s32 cfo_tail[RTW_RF_PATH_MAX]; + s32 cfo_cnt[RTW_RF_PATH_MAX]; + u32 packet_count; + u32 packet_count_pre; +}; + +#define RRSR_INIT_2G 0x15f +#define RRSR_INIT_5G 0x150 + +enum rtw_dm_cap { + RTW_DM_CAP_NA, + RTW_DM_CAP_TXGAPK, + RTW_DM_CAP_NUM +}; + +struct rtw_dm_info { + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 total_fa_cnt; + u32 cck_cca_cnt; + u32 ofdm_cca_cnt; + u32 total_cca_cnt; + + u32 cck_ok_cnt; + u32 cck_err_cnt; + u32 ofdm_ok_cnt; + u32 ofdm_err_cnt; + u32 ht_ok_cnt; + u32 ht_err_cnt; + u32 vht_ok_cnt; + u32 vht_err_cnt; + + u8 min_rssi; + u8 pre_min_rssi; + u16 fa_history[4]; + u8 igi_history[4]; + u8 igi_bitmap; + bool damping; + u8 damping_cnt; + u8 damping_rssi; + + u8 cck_gi_u_bnd; + u8 cck_gi_l_bnd; + + u8 fix_rate; + u8 tx_rate; + u32 rrsr_val_init; + u32 rrsr_mask_min; + u8 thermal_avg[RTW_RF_PATH_MAX]; + u8 thermal_meter_k; + u8 thermal_meter_lck; + s8 delta_power_index[RTW_RF_PATH_MAX]; + s8 delta_power_index_last[RTW_RF_PATH_MAX]; + u8 default_ofdm_index; + u8 default_cck_index; + bool pwr_trk_triggered; + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; + s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX]; + u8 rx_cck_agc_report_type; + + /* backup dack results for each path and I/Q */ + u32 dack_adck[RTW_RF_PATH_MAX]; + u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM]; + u8 dack_dck[RTW_RF_PATH_MAX][2][DACK_DCK_BACKUP_NUM]; + + struct rtw_dpk_info dpk_info; + struct rtw_cfo_track cfo_track; + + /* [bandwidth 0:20M/1:40M][number of path] */ + u8 cck_pd_lv[2][RTW_RF_PATH_MAX]; + u32 cck_fa_avg; + u8 cck_pd_default; + + /* save the last rx phy status for debug */ + s8 rx_snr[RTW_RF_PATH_MAX]; + u8 rx_evm_dbm[RTW_RF_PATH_MAX]; + s16 cfo_tail[RTW_RF_PATH_MAX]; + u8 rssi[RTW_RF_PATH_MAX]; + u8 curr_rx_rate; + struct rtw_pkt_count cur_pkt_count; + struct rtw_pkt_count last_pkt_count; + struct ewma_evm ewma_evm[RTW_EVM_NUM]; + struct ewma_snr ewma_snr[RTW_SNR_NUM]; + + u32 dm_flags; /* enum rtw_dm_cap */ + struct rtw_iqk_info iqk; + struct rtw_gapk_info gapk; + bool is_bt_iqk_timeout; + + s8 l2h_th_ini; + enum rtw_edcca_mode edcca_mode; + u8 scan_density; +}; + +struct rtw_efuse { + u32 size; + u32 physical_size; + u32 logical_size; + u32 protect_size; + + u8 addr[ETH_ALEN]; + u8 channel_plan; + u8 country_code[2]; + u8 rf_board_option; + u8 rfe_option; + u8 power_track_type; + u8 thermal_meter[RTW_RF_PATH_MAX]; + u8 thermal_meter_k; + u8 crystal_cap; + u8 ant_div_cfg; + u8 ant_div_type; + u8 regd; + u8 afe; + + u8 lna_type_2g; + u8 lna_type_5g; + u8 glna_type; + u8 alna_type; + bool ext_lna_2g; + bool ext_lna_5g; + u8 pa_type_2g; + u8 pa_type_5g; + u8 gpa_type; + u8 apa_type; + bool ext_pa_2g; + bool ext_pa_5g; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + + bool btcoex; + /* bt share antenna with wifi */ + bool share_ant; + u8 bt_setting; + + u8 usb_mode_switch; + + struct { + u8 hci; + u8 bw; + u8 ptcl; + u8 nss; + u8 ant_num; + } hw_cap; + + struct rtw_txpwr_idx txpwr_idx_table[4]; +}; + +struct rtw_phy_cond { +#ifdef __LITTLE_ENDIAN + u32 rfe:8; + u32 intf:4; + u32 pkg:4; + u32 plat:4; + u32 intf_rsvd:4; + u32 cut:4; + u32 branch:2; + u32 neg:1; + u32 pos:1; +#else + u32 pos:1; + u32 neg:1; + u32 branch:2; + u32 cut:4; + u32 intf_rsvd:4; + u32 plat:4; + u32 pkg:4; + u32 intf:4; + u32 rfe:8; +#endif + /* for intf:4 */ + #define INTF_PCIE BIT(0) + #define INTF_USB BIT(1) + #define INTF_SDIO BIT(2) + /* for branch:2 */ + #define BRANCH_IF 0 + #define BRANCH_ELIF 1 + #define BRANCH_ELSE 2 + #define BRANCH_ENDIF 3 +}; + +struct rtw_phy_cond2 { +#ifdef __LITTLE_ENDIAN + u8 type_glna; + u8 type_gpa; + u8 type_alna; + u8 type_apa; +#else + u8 type_apa; + u8 type_alna; + u8 type_gpa; + u8 type_glna; +#endif +}; + +struct rtw_fifo_conf { + /* tx fifo information */ + u16 rsvd_boundary; + u16 rsvd_pg_num; + u16 rsvd_drv_pg_num; + u16 txff_pg_num; + u16 acq_pg_num; + u16 rsvd_drv_addr; + u16 rsvd_h2c_info_addr; + u16 rsvd_h2c_sta_info_addr; + u16 rsvd_h2cq_addr; + u16 rsvd_cpu_instr_addr; + u16 rsvd_fw_txbuf_addr; + u16 rsvd_csibuf_addr; + const struct rtw_rqpn *rqpn; +}; + +struct rtw_fwcd_desc { + u32 size; + u8 *next; + u8 *data; +}; + +struct rtw_fwcd_segs { + const u32 *segs; + u8 num; +}; + +#define FW_CD_TYPE 0xffff +#define FW_CD_LEN 4 +#define FW_CD_VAL 0xaabbccdd +struct rtw_fw_state { + const struct firmware *firmware; + struct rtw_dev *rtwdev; + struct completion completion; + struct rtw_fwcd_desc fwcd_desc; + u16 version; + u8 sub_version; + u8 sub_index; + u16 h2c_version; + u32 feature; + u32 feature_ext; + enum rtw_fw_type type; +}; + +enum rtw_sar_sources { + RTW_SAR_SOURCE_NONE, + RTW_SAR_SOURCE_COMMON, +}; + +enum rtw_sar_bands { + RTW_SAR_BAND_0, + RTW_SAR_BAND_1, + /* RTW_SAR_BAND_2, not used now */ + RTW_SAR_BAND_3, + RTW_SAR_BAND_4, + + RTW_SAR_BAND_NR, +}; + +/* the union is reserved for other kinds of SAR sources + * which might not re-use same format with array common. + */ +union rtw_sar_cfg { + s8 common[RTW_SAR_BAND_NR]; +}; + +struct rtw_sar { + enum rtw_sar_sources src; + union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_NUM]; +}; + +struct rtw_hal { + u32 rcr; + u16 rxfltmap1; + + u32 chip_version; + u8 cut_version; + u8 mp_chip; + u8 oem_id; + u8 pkg_type; + struct rtw_phy_cond phy_cond; + struct rtw_phy_cond2 phy_cond2; + bool rfe_btg; + + u8 ps_mode; + u8 current_channel; + u8 current_primary_channel_index; + u8 current_band_width; + u8 current_band_type; + u8 primary_channel; + + /* center channel for different available bandwidth, + * val of (bw > current_band_width) is invalid + */ + u8 cch_by_bw[RTW_MAX_CHANNEL_WIDTH + 1]; + + u8 sec_ch_offset; + u8 rf_type; + u8 rf_path_num; + u8 rf_phy_num; + u32 antenna_tx; + u32 antenna_rx; + u8 bfee_sts_cap; + bool txrx_1ss; + bool cck_high_power; + + /* protect tx power section */ + struct mutex tx_power_mutex; + s8 tx_pwr_by_rate_offset_2g[RTW_RF_PATH_MAX] + [DESC_RATE_MAX]; + s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX] + [DESC_RATE_MAX]; + s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX] + [RTW_RATE_SECTION_NUM]; + s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX] + [RTW_RATE_SECTION_NUM]; + s8 tx_pwr_limit_2g[RTW_REGD_MAX] + [RTW_CHANNEL_WIDTH_MAX] + [RTW_RATE_SECTION_NUM] + [RTW_MAX_CHANNEL_NUM_2G]; + s8 tx_pwr_limit_5g[RTW_REGD_MAX] + [RTW_CHANNEL_WIDTH_MAX] + [RTW_RATE_SECTION_NUM] + [RTW_MAX_CHANNEL_NUM_5G]; + s8 tx_pwr_tbl[RTW_RF_PATH_MAX] + [DESC_RATE_MAX]; + + enum rtw_sar_bands sar_band; + struct rtw_sar sar; + + /* for 8821c set channel */ + u32 ch_param[3]; +}; + +struct rtw_path_div { + enum rtw_bb_path current_tx_path; + u32 path_a_sum; + u32 path_b_sum; + u16 path_a_cnt; + u16 path_b_cnt; +}; + +struct rtw_chan_info { + int pri_ch_idx; + int action_id; + int bw; + u8 extra_info; + u8 channel; + u16 timeout; +}; + +struct rtw_chan_list { + u32 buf_size; + u32 ch_num; + u32 size; + u16 addr; +}; + +struct rtw_hw_scan_info { + struct ieee80211_vif *scanning_vif; + u8 probe_pg_size; + u8 op_pri_ch_idx; + u8 op_pri_ch; + u8 op_chan; + u8 op_bw; +}; + +struct rtw_dev { + struct ieee80211_hw *hw; + struct device *dev; + + struct rtw_hci hci; + + struct rtw_hw_scan_info scan_info; + const struct rtw_chip_info *chip; + struct rtw_hal hal; + struct rtw_fifo_conf fifo; + struct rtw_fw_state fw; + struct rtw_efuse efuse; + struct rtw_sec_desc sec; + struct rtw_traffic_stats stats; + struct rtw_regd regd; + struct rtw_bf_info bf_info; + + struct rtw_dm_info dm_info; + struct rtw_coex coex; + + /* ensures exclusive access from mac80211 callbacks */ + struct mutex mutex; + + /* watch dog every 2 sec */ + struct delayed_work watch_dog_work; + u32 watch_dog_cnt; + + struct list_head rsvd_page_list; + + /* c2h cmd queue & handler work */ + struct sk_buff_head c2h_queue; + struct work_struct c2h_work; + struct work_struct ips_work; + struct work_struct fw_recovery_work; + struct work_struct update_beacon_work; + + /* used to protect txqs list */ + spinlock_t txq_lock; + struct list_head txqs; + struct workqueue_struct *tx_wq; + struct work_struct tx_work; + struct work_struct ba_work; + + struct rtw_tx_report tx_report; + + struct { + /* indicate the mail box to use with fw */ + u8 last_box_num; + u32 seq; + } h2c; + + /* lps power state & handler work */ + struct rtw_lps_conf lps_conf; + bool ps_enabled; + bool beacon_loss; + struct completion lps_leave_check; + + struct rtw_debugfs *debugfs; + + u8 sta_cnt; + u32 rts_threshold; + + DECLARE_BITMAP(hw_port, RTW_PORT_NUM); + DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); + DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); + + u8 mp_mode; + struct rtw_path_div dm_path_div; + + struct rtw_fw_state wow_fw; + struct rtw_wow_param wow; + + bool need_rfk; + struct completion fw_scan_density; + bool ap_active; + + bool led_registered; + char led_name[32]; + struct led_classdev led_cdev; + + /* hci related data, must be last */ + u8 priv[] __aligned(sizeof(void *)); +}; + +#include "hci.h" + +static inline bool rtw_is_assoc(struct rtw_dev *rtwdev) +{ + return !!rtwdev->sta_cnt; +} + +static inline struct ieee80211_txq *rtwtxq_to_txq(struct rtw_txq *rtwtxq) +{ + void *p = rtwtxq; + + return container_of(p, struct ieee80211_txq, drv_priv); +} + +static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw_vif *rtwvif) +{ + void *p = rtwvif; + + return container_of(p, struct ieee80211_vif, drv_priv); +} + +static inline void rtw_chip_efuse_grant_on(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->efuse_grant) + rtwdev->chip->ops->efuse_grant(rtwdev, true); +} + +static inline void rtw_chip_efuse_grant_off(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->efuse_grant) + rtwdev->chip->ops->efuse_grant(rtwdev, false); +} + +static inline bool rtw_chip_wcpu_8051(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_8051; +} + +static inline bool rtw_chip_wcpu_3081(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_3081; +} + +static inline bool rtw_chip_has_rx_ldpc(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->rx_ldpc; +} + +static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->tx_stbc; +} + +static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev) +{ + unsigned long mac_id; + + mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); + if (mac_id < RTW_MAX_MAC_ID_NUM) + set_bit(mac_id, rtwdev->mac_id_map); + + return mac_id; +} + +static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id) +{ + clear_bit(mac_id, rtwdev->mac_id_map); +} + +static inline int rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->dump_fw_crash) + return rtwdev->chip->ops->dump_fw_crash(rtwdev); + + return 0; +} + +static inline +enum nl80211_band rtw_hw_to_nl80211_band(enum rtw_supported_band hw_band) +{ + switch (hw_band) { + default: + case RTW_BAND_2G: + return NL80211_BAND_2GHZ; + case RTW_BAND_5G: + return NL80211_BAND_5GHZ; + case RTW_BAND_60G: + return NL80211_BAND_60GHZ; + } +} + +void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel); +void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period); +void rtw_get_channel_params(struct cfg80211_chan_def *chandef, + struct rtw_channel_params *ch_param); +bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target); +bool ltecoex_read_reg(struct rtw_dev *rtwdev, u16 offset, u32 *val); +bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value); +void rtw_restore_reg(struct rtw_dev *rtwdev, + struct rtw_backup_info *bckp, u32 num); +void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss); +void rtw_set_channel(struct rtw_dev *rtwdev); +void rtw_chip_prepare_tx(struct rtw_dev *rtwdev); +void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + u32 config); +void rtw_tx_report_purge_timer(struct timer_list *t); +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask); +void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + const u8 *mac_addr, bool hw_scan); +void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool hw_scan); +int rtw_core_start(struct rtw_dev *rtwdev); +void rtw_power_off(struct rtw_dev *rtwdev); +void rtw_core_stop(struct rtw_dev *rtwdev); +int rtw_chip_info_setup(struct rtw_dev *rtwdev); +int rtw_core_init(struct rtw_dev *rtwdev); +void rtw_core_deinit(struct rtw_dev *rtwdev); +int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); +void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); +u16 rtw_desc_to_bitrate(u8 desc_rate); +void rtw_vif_assoc_changed(struct rtw_vif *rtwvif, + struct ieee80211_bss_conf *conf); +int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + struct ieee80211_vif *vif); +void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + bool fw_exist); +void rtw_fw_recovery(struct rtw_dev *rtwdev); +int rtw_wait_firmware_completion(struct rtw_dev *rtwdev); +int rtw_power_on(struct rtw_dev *rtwdev); +void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start); +int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, + u32 fwcd_item); +int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size); +void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool config_1ss); +void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, + u8 primary_channel, enum rtw_supported_band band, + enum rtw_bandwidth bandwidth); +void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif); +bool rtw_core_check_sta_active(struct rtw_dev *rtwdev); +void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable); +void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); +#endif diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c new file mode 100644 index 000000000..5b00c1e1e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -0,0 +1,1940 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include +#include "main.h" +#include "pci.h" +#include "reg.h" +#include "tx.h" +#include "rx.h" +#include "fw.h" +#include "ps.h" +#include "debug.h" +#include "mac.h" + +static bool rtw_disable_msi; +static bool rtw_pci_disable_aspm; +module_param_named(disable_msi, rtw_disable_msi, bool, 0644); +module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644); +MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support"); +MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support"); + +static const u32 rtw_pci_tx_queue_idx_addr[] = { + [RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ, + [RTW_TX_QUEUE_BE] = RTK_PCI_TXBD_IDX_BEQ, + [RTW_TX_QUEUE_VI] = RTK_PCI_TXBD_IDX_VIQ, + [RTW_TX_QUEUE_VO] = RTK_PCI_TXBD_IDX_VOQ, + [RTW_TX_QUEUE_MGMT] = RTK_PCI_TXBD_IDX_MGMTQ, + [RTW_TX_QUEUE_HI0] = RTK_PCI_TXBD_IDX_HI0Q, + [RTW_TX_QUEUE_H2C] = RTK_PCI_TXBD_IDX_H2CQ, +}; + +static u8 rtw_pci_get_tx_qsel(struct sk_buff *skb, + enum rtw_tx_queue_type queue) +{ + switch (queue) { + case RTW_TX_QUEUE_BCN: + return TX_DESC_QSEL_BEACON; + case RTW_TX_QUEUE_H2C: + return TX_DESC_QSEL_H2C; + case RTW_TX_QUEUE_MGMT: + return TX_DESC_QSEL_MGMT; + case RTW_TX_QUEUE_HI0: + return TX_DESC_QSEL_HIGH; + default: + return skb->priority; + } +}; + +static u8 rtw_pci_read8(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + return readb(rtwpci->mmap + addr); +} + +static u16 rtw_pci_read16(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + return readw(rtwpci->mmap + addr); +} + +static u32 rtw_pci_read32(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + return readl(rtwpci->mmap + addr); +} + +static void rtw_pci_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + writeb(val, rtwpci->mmap + addr); +} + +static void rtw_pci_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + writew(val, rtwpci->mmap + addr); +} + +static void rtw_pci_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + writel(val, rtwpci->mmap + addr); +} + +static void rtw_pci_free_tx_ring_skbs(struct rtw_dev *rtwdev, + struct rtw_pci_tx_ring *tx_ring) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + struct rtw_pci_tx_data *tx_data; + struct sk_buff *skb, *tmp; + dma_addr_t dma; + + /* free every skb remained in tx list */ + skb_queue_walk_safe(&tx_ring->queue, skb, tmp) { + __skb_unlink(skb, &tx_ring->queue); + tx_data = rtw_pci_get_tx_data(skb); + dma = tx_data->dma; + + dma_unmap_single(&pdev->dev, dma, skb->len, DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + } +} + +static void rtw_pci_free_tx_ring(struct rtw_dev *rtwdev, + struct rtw_pci_tx_ring *tx_ring) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + u8 *head = tx_ring->r.head; + u32 len = tx_ring->r.len; + int ring_sz = len * tx_ring->r.desc_size; + + rtw_pci_free_tx_ring_skbs(rtwdev, tx_ring); + + /* free the ring itself */ + dma_free_coherent(&pdev->dev, ring_sz, head, tx_ring->r.dma); + tx_ring->r.head = NULL; +} + +static void rtw_pci_free_rx_ring_skbs(struct rtw_dev *rtwdev, + struct rtw_pci_rx_ring *rx_ring) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + struct sk_buff *skb; + int buf_sz = RTK_PCI_RX_BUF_SIZE; + dma_addr_t dma; + int i; + + for (i = 0; i < rx_ring->r.len; i++) { + skb = rx_ring->buf[i]; + if (!skb) + continue; + + dma = *((dma_addr_t *)skb->cb); + dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb(skb); + rx_ring->buf[i] = NULL; + } +} + +static void rtw_pci_free_rx_ring(struct rtw_dev *rtwdev, + struct rtw_pci_rx_ring *rx_ring) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + u8 *head = rx_ring->r.head; + int ring_sz = rx_ring->r.desc_size * rx_ring->r.len; + + rtw_pci_free_rx_ring_skbs(rtwdev, rx_ring); + + dma_free_coherent(&pdev->dev, ring_sz, head, rx_ring->r.dma); +} + +static void rtw_pci_free_trx_ring(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *tx_ring; + struct rtw_pci_rx_ring *rx_ring; + int i; + + for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) { + tx_ring = &rtwpci->tx_rings[i]; + rtw_pci_free_tx_ring(rtwdev, tx_ring); + } + + for (i = 0; i < RTK_MAX_RX_QUEUE_NUM; i++) { + rx_ring = &rtwpci->rx_rings[i]; + rtw_pci_free_rx_ring(rtwdev, rx_ring); + } +} + +static int rtw_pci_init_tx_ring(struct rtw_dev *rtwdev, + struct rtw_pci_tx_ring *tx_ring, + u8 desc_size, u32 len) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + int ring_sz = desc_size * len; + dma_addr_t dma; + u8 *head; + + if (len > TRX_BD_IDX_MASK) { + rtw_err(rtwdev, "len %d exceeds maximum TX entries\n", len); + return -EINVAL; + } + + head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); + if (!head) { + rtw_err(rtwdev, "failed to allocate tx ring\n"); + return -ENOMEM; + } + + skb_queue_head_init(&tx_ring->queue); + tx_ring->r.head = head; + tx_ring->r.dma = dma; + tx_ring->r.len = len; + tx_ring->r.desc_size = desc_size; + tx_ring->r.wp = 0; + tx_ring->r.rp = 0; + + return 0; +} + +static int rtw_pci_reset_rx_desc(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct rtw_pci_rx_ring *rx_ring, + u32 idx, u32 desc_sz) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + struct rtw_pci_rx_buffer_desc *buf_desc; + int buf_sz = RTK_PCI_RX_BUF_SIZE; + dma_addr_t dma; + + if (!skb) + return -EINVAL; + + dma = dma_map_single(&pdev->dev, skb->data, buf_sz, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, dma)) + return -EBUSY; + + *((dma_addr_t *)skb->cb) = dma; + buf_desc = (struct rtw_pci_rx_buffer_desc *)(rx_ring->r.head + + idx * desc_sz); + memset(buf_desc, 0, sizeof(*buf_desc)); + buf_desc->buf_size = cpu_to_le16(RTK_PCI_RX_BUF_SIZE); + buf_desc->dma = cpu_to_le32(dma); + + return 0; +} + +static void rtw_pci_sync_rx_desc_device(struct rtw_dev *rtwdev, dma_addr_t dma, + struct rtw_pci_rx_ring *rx_ring, + u32 idx, u32 desc_sz) +{ + struct device *dev = rtwdev->dev; + struct rtw_pci_rx_buffer_desc *buf_desc; + int buf_sz = RTK_PCI_RX_BUF_SIZE; + + dma_sync_single_for_device(dev, dma, buf_sz, DMA_FROM_DEVICE); + + buf_desc = (struct rtw_pci_rx_buffer_desc *)(rx_ring->r.head + + idx * desc_sz); + memset(buf_desc, 0, sizeof(*buf_desc)); + buf_desc->buf_size = cpu_to_le16(RTK_PCI_RX_BUF_SIZE); + buf_desc->dma = cpu_to_le32(dma); +} + +static int rtw_pci_init_rx_ring(struct rtw_dev *rtwdev, + struct rtw_pci_rx_ring *rx_ring, + u8 desc_size, u32 len) +{ + struct pci_dev *pdev = to_pci_dev(rtwdev->dev); + struct sk_buff *skb = NULL; + dma_addr_t dma; + u8 *head; + int ring_sz = desc_size * len; + int buf_sz = RTK_PCI_RX_BUF_SIZE; + int i, allocated; + int ret = 0; + + head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); + if (!head) { + rtw_err(rtwdev, "failed to allocate rx ring\n"); + return -ENOMEM; + } + rx_ring->r.head = head; + + for (i = 0; i < len; i++) { + skb = dev_alloc_skb(buf_sz); + if (!skb) { + allocated = i; + ret = -ENOMEM; + goto err_out; + } + + memset(skb->data, 0, buf_sz); + rx_ring->buf[i] = skb; + ret = rtw_pci_reset_rx_desc(rtwdev, skb, rx_ring, i, desc_size); + if (ret) { + allocated = i; + dev_kfree_skb_any(skb); + goto err_out; + } + } + + rx_ring->r.dma = dma; + rx_ring->r.len = len; + rx_ring->r.desc_size = desc_size; + rx_ring->r.wp = 0; + rx_ring->r.rp = 0; + + return 0; + +err_out: + for (i = 0; i < allocated; i++) { + skb = rx_ring->buf[i]; + if (!skb) + continue; + dma = *((dma_addr_t *)skb->cb); + dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb_any(skb); + rx_ring->buf[i] = NULL; + } + dma_free_coherent(&pdev->dev, ring_sz, head, dma); + + rtw_err(rtwdev, "failed to init rx buffer\n"); + + return ret; +} + +static int rtw_pci_init_trx_ring(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *tx_ring; + struct rtw_pci_rx_ring *rx_ring; + const struct rtw_chip_info *chip = rtwdev->chip; + int i = 0, j = 0, tx_alloced = 0, rx_alloced = 0; + int tx_desc_size, rx_desc_size; + u32 len; + int ret; + + tx_desc_size = chip->tx_buf_desc_sz; + + for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) { + tx_ring = &rtwpci->tx_rings[i]; + len = max_num_of_tx_queue(i); + ret = rtw_pci_init_tx_ring(rtwdev, tx_ring, tx_desc_size, len); + if (ret) + goto out; + } + + rx_desc_size = chip->rx_buf_desc_sz; + + for (j = 0; j < RTK_MAX_RX_QUEUE_NUM; j++) { + rx_ring = &rtwpci->rx_rings[j]; + ret = rtw_pci_init_rx_ring(rtwdev, rx_ring, rx_desc_size, + RTK_MAX_RX_DESC_NUM); + if (ret) + goto out; + } + + return 0; + +out: + tx_alloced = i; + for (i = 0; i < tx_alloced; i++) { + tx_ring = &rtwpci->tx_rings[i]; + rtw_pci_free_tx_ring(rtwdev, tx_ring); + } + + rx_alloced = j; + for (j = 0; j < rx_alloced; j++) { + rx_ring = &rtwpci->rx_rings[j]; + rtw_pci_free_rx_ring(rtwdev, rx_ring); + } + + return ret; +} + +static void rtw_pci_deinit(struct rtw_dev *rtwdev) +{ + rtw_pci_free_trx_ring(rtwdev); +} + +static int rtw_pci_init(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + int ret = 0; + + rtwpci->irq_mask[0] = IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_ROK | + IMR_BCNDMAINT_E | + IMR_C2HCMD | + 0; + rtwpci->irq_mask[1] = IMR_TXFOVW | + 0; + rtwpci->irq_mask[3] = IMR_H2CDOK | + 0; + spin_lock_init(&rtwpci->irq_lock); + spin_lock_init(&rtwpci->hwirq_lock); + ret = rtw_pci_init_trx_ring(rtwdev); + + return ret; +} + +static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + u32 len; + u8 tmp; + dma_addr_t dma; + + tmp = rtw_read8(rtwdev, RTK_PCI_CTRL + 3); + rtw_write8(rtwdev, RTK_PCI_CTRL + 3, tmp | 0xf7); + + dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma; + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma); + + if (!rtw_chip_wcpu_8051(rtwdev)) { + len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_H2CQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_H2CQ, dma); + } + + len = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_BKQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BKQ, dma); + + len = rtwpci->tx_rings[RTW_TX_QUEUE_BE].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_BE].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_BE].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_BE].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_BEQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BEQ, dma); + + len = rtwpci->tx_rings[RTW_TX_QUEUE_VO].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_VO].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_VO].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_VO].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_VOQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_VOQ, dma); + + len = rtwpci->tx_rings[RTW_TX_QUEUE_VI].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_VI].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_VI].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_VI].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_VIQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_VIQ, dma); + + len = rtwpci->tx_rings[RTW_TX_QUEUE_MGMT].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_MGMT].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_MGMT].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_MGMT].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_MGMTQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_MGMTQ, dma); + + len = rtwpci->tx_rings[RTW_TX_QUEUE_HI0].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_HI0].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_HI0].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_HI0].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_HI0Q, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_HI0Q, dma); + + len = rtwpci->rx_rings[RTW_RX_QUEUE_MPDU].r.len; + dma = rtwpci->rx_rings[RTW_RX_QUEUE_MPDU].r.dma; + rtwpci->rx_rings[RTW_RX_QUEUE_MPDU].r.rp = 0; + rtwpci->rx_rings[RTW_RX_QUEUE_MPDU].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_RXBD_NUM_MPDUQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_RXBD_DESA_MPDUQ, dma); + + /* reset read/write point */ + rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff); + + /* reset H2C Queue index in a single write */ + if (rtw_chip_wcpu_3081(rtwdev)) + rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, + BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); +} + +static void rtw_pci_reset_trx_ring(struct rtw_dev *rtwdev) +{ + rtw_pci_reset_buf_desc(rtwdev); +} + +static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev, + struct rtw_pci *rtwpci, bool exclude_rx) +{ + unsigned long flags; + u32 imr0_unmask = exclude_rx ? IMR_ROK : 0; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + + rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0] & ~imr0_unmask); + rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]); + if (rtw_chip_wcpu_3081(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); + + rtwpci->irq_enabled = true; + + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); +} + +static void rtw_pci_disable_interrupt(struct rtw_dev *rtwdev, + struct rtw_pci *rtwpci) +{ + unsigned long flags; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + + if (!rtwpci->irq_enabled) + goto out; + + rtw_write32(rtwdev, RTK_PCI_HIMR0, 0); + rtw_write32(rtwdev, RTK_PCI_HIMR1, 0); + if (rtw_chip_wcpu_3081(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); + + rtwpci->irq_enabled = false; + +out: + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); +} + +static void rtw_pci_dma_reset(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) +{ + /* reset dma and rx tag */ + rtw_write32_set(rtwdev, RTK_PCI_CTRL, + BIT_RST_TRXDMA_INTF | BIT_RX_TAG_EN); + rtwpci->rx_tag = 0; +} + +static int rtw_pci_setup(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtw_pci_reset_trx_ring(rtwdev); + rtw_pci_dma_reset(rtwdev, rtwpci); + + return 0; +} + +static void rtw_pci_dma_release(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) +{ + struct rtw_pci_tx_ring *tx_ring; + enum rtw_tx_queue_type queue; + + rtw_pci_reset_trx_ring(rtwdev); + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { + tx_ring = &rtwpci->tx_rings[queue]; + rtw_pci_free_tx_ring_skbs(rtwdev, tx_ring); + } +} + +static void rtw_pci_napi_start(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + if (test_and_set_bit(RTW_PCI_FLAG_NAPI_RUNNING, rtwpci->flags)) + return; + + napi_enable(&rtwpci->napi); +} + +static void rtw_pci_napi_stop(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + if (!test_and_clear_bit(RTW_PCI_FLAG_NAPI_RUNNING, rtwpci->flags)) + return; + + napi_synchronize(&rtwpci->napi); + napi_disable(&rtwpci->napi); +} + +static int rtw_pci_start(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtw_pci_napi_start(rtwdev); + + spin_lock_bh(&rtwpci->irq_lock); + rtwpci->running = true; + rtw_pci_enable_interrupt(rtwdev, rtwpci, false); + spin_unlock_bh(&rtwpci->irq_lock); + + return 0; +} + +static void rtw_pci_stop(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + spin_lock_bh(&rtwpci->irq_lock); + rtwpci->running = false; + rtw_pci_disable_interrupt(rtwdev, rtwpci); + spin_unlock_bh(&rtwpci->irq_lock); + + synchronize_irq(pdev->irq); + rtw_pci_napi_stop(rtwdev); + + spin_lock_bh(&rtwpci->irq_lock); + rtw_pci_dma_release(rtwdev, rtwpci); + spin_unlock_bh(&rtwpci->irq_lock); +} + +static void rtw_pci_deep_ps_enter(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *tx_ring; + enum rtw_tx_queue_type queue; + bool tx_empty = true; + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + goto enter_deep_ps; + + lockdep_assert_held(&rtwpci->irq_lock); + + /* Deep PS state is not allowed to TX-DMA */ + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { + /* BCN queue is rsvd page, does not have DMA interrupt + * H2C queue is managed by firmware + */ + if (queue == RTW_TX_QUEUE_BCN || + queue == RTW_TX_QUEUE_H2C) + continue; + + tx_ring = &rtwpci->tx_rings[queue]; + + /* check if there is any skb DMAing */ + if (skb_queue_len(&tx_ring->queue)) { + tx_empty = false; + break; + } + } + + if (!tx_empty) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "TX path not empty, cannot enter deep power save state\n"); + return; + } +enter_deep_ps: + set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); + rtw_power_mode_change(rtwdev, true); +} + +static void rtw_pci_deep_ps_leave(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + lockdep_assert_held(&rtwpci->irq_lock); + + if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_power_mode_change(rtwdev, false); +} + +static void rtw_pci_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + spin_lock_bh(&rtwpci->irq_lock); + + if (enter && !test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_pci_deep_ps_enter(rtwdev); + + if (!enter && test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_pci_deep_ps_leave(rtwdev); + + spin_unlock_bh(&rtwpci->irq_lock); +} + +static void rtw_pci_release_rsvd_page(struct rtw_pci *rtwpci, + struct rtw_pci_tx_ring *ring) +{ + struct sk_buff *prev = skb_dequeue(&ring->queue); + struct rtw_pci_tx_data *tx_data; + dma_addr_t dma; + + if (!prev) + return; + + tx_data = rtw_pci_get_tx_data(prev); + dma = tx_data->dma; + dma_unmap_single(&rtwpci->pdev->dev, dma, prev->len, DMA_TO_DEVICE); + dev_kfree_skb_any(prev); +} + +static void rtw_pci_dma_check(struct rtw_dev *rtwdev, + struct rtw_pci_rx_ring *rx_ring, + u32 idx) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pci_rx_buffer_desc *buf_desc; + u32 desc_sz = chip->rx_buf_desc_sz; + u16 total_pkt_size; + + buf_desc = (struct rtw_pci_rx_buffer_desc *)(rx_ring->r.head + + idx * desc_sz); + total_pkt_size = le16_to_cpu(buf_desc->total_pkt_size); + + /* rx tag mismatch, throw a warning */ + if (total_pkt_size != rtwpci->rx_tag) + rtw_warn(rtwdev, "pci bus timeout, check dma status\n"); + + rtwpci->rx_tag = (rtwpci->rx_tag + 1) % RX_TAG_MAX; +} + +static u32 __pci_get_hw_tx_ring_rp(struct rtw_dev *rtwdev, u8 pci_q) +{ + u32 bd_idx_addr = rtw_pci_tx_queue_idx_addr[pci_q]; + u32 bd_idx = rtw_read16(rtwdev, bd_idx_addr + 2); + + return FIELD_GET(TRX_BD_IDX_MASK, bd_idx); +} + +static void __pci_flush_queue(struct rtw_dev *rtwdev, u8 pci_q, bool drop) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *ring = &rtwpci->tx_rings[pci_q]; + u32 cur_rp; + u8 i; + + /* Because the time taked by the I/O in __pci_get_hw_tx_ring_rp is a + * bit dynamic, it's hard to define a reasonable fixed total timeout to + * use read_poll_timeout* helper. Instead, we can ensure a reasonable + * polling times, so we just use for loop with udelay here. + */ + for (i = 0; i < 30; i++) { + cur_rp = __pci_get_hw_tx_ring_rp(rtwdev, pci_q); + if (cur_rp == ring->r.wp) + return; + + udelay(1); + } + + if (!drop) + rtw_dbg(rtwdev, RTW_DBG_UNEXP, + "timed out to flush pci tx ring[%d]\n", pci_q); +} + +static void __rtw_pci_flush_queues(struct rtw_dev *rtwdev, u32 pci_queues, + bool drop) +{ + u8 q; + + for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { + /* Unnecessary to flush BCN, H2C and HI tx queues. */ + if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || + q == RTW_TX_QUEUE_HI0) + continue; + + if (pci_queues & BIT(q)) + __pci_flush_queue(rtwdev, q, drop); + } +} + +static void rtw_pci_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop) +{ + u32 pci_queues = 0; + u8 i; + + /* If all of the hardware queues are requested to flush, + * flush all of the pci queues. + */ + if (queues == BIT(rtwdev->hw->queues) - 1) { + pci_queues = BIT(RTK_MAX_TX_QUEUE_NUM) - 1; + } else { + for (i = 0; i < rtwdev->hw->queues; i++) + if (queues & BIT(i)) + pci_queues |= BIT(rtw_tx_ac_to_hwq(i)); + } + + __rtw_pci_flush_queues(rtwdev, pci_queues, drop); +} + +static void rtw_pci_tx_kick_off_queue(struct rtw_dev *rtwdev, + enum rtw_tx_queue_type queue) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *ring; + u32 bd_idx; + + ring = &rtwpci->tx_rings[queue]; + bd_idx = rtw_pci_tx_queue_idx_addr[queue]; + + spin_lock_bh(&rtwpci->irq_lock); + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + rtw_pci_deep_ps_leave(rtwdev); + rtw_write16(rtwdev, bd_idx, ring->r.wp & TRX_BD_IDX_MASK); + spin_unlock_bh(&rtwpci->irq_lock); +} + +static void rtw_pci_tx_kick_off(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + enum rtw_tx_queue_type queue; + + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) + if (test_and_clear_bit(queue, rtwpci->tx_queued)) + rtw_pci_tx_kick_off_queue(rtwdev, queue); +} + +static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_tx_queue_type queue) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pci_tx_ring *ring; + struct rtw_pci_tx_data *tx_data; + dma_addr_t dma; + u32 tx_pkt_desc_sz = chip->tx_pkt_desc_sz; + u32 tx_buf_desc_sz = chip->tx_buf_desc_sz; + u32 size; + u32 psb_len; + u8 *pkt_desc; + struct rtw_pci_tx_buffer_desc *buf_desc; + + ring = &rtwpci->tx_rings[queue]; + + size = skb->len; + + if (queue == RTW_TX_QUEUE_BCN) + rtw_pci_release_rsvd_page(rtwpci, ring); + else if (!avail_desc(ring->r.wp, ring->r.rp, ring->r.len)) + return -ENOSPC; + + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, tx_pkt_desc_sz); + pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue); + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtwpci->pdev->dev, dma)) + return -EBUSY; + + /* after this we got dma mapped, there is no way back */ + buf_desc = get_tx_buffer_desc(ring, tx_buf_desc_sz); + memset(buf_desc, 0, tx_buf_desc_sz); + psb_len = (skb->len - 1) / 128 + 1; + if (queue == RTW_TX_QUEUE_BCN) + psb_len |= 1 << RTK_PCI_TXBD_OWN_OFFSET; + + buf_desc[0].psb_len = cpu_to_le16(psb_len); + buf_desc[0].buf_size = cpu_to_le16(tx_pkt_desc_sz); + buf_desc[0].dma = cpu_to_le32(dma); + buf_desc[1].buf_size = cpu_to_le16(size); + buf_desc[1].dma = cpu_to_le32(dma + tx_pkt_desc_sz); + + tx_data = rtw_pci_get_tx_data(skb); + tx_data->dma = dma; + tx_data->sn = pkt_info->sn; + + spin_lock_bh(&rtwpci->irq_lock); + + skb_queue_tail(&ring->queue, skb); + + if (queue == RTW_TX_QUEUE_BCN) + goto out_unlock; + + /* update write-index, and kick it off later */ + set_bit(queue, rtwpci->tx_queued); + if (++ring->r.wp >= ring->r.len) + ring->r.wp = 0; + +out_unlock: + spin_unlock_bh(&rtwpci->irq_lock); + + return 0; +} + +static int rtw_pci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, + u32 size) +{ + struct sk_buff *skb; + struct rtw_tx_pkt_info pkt_info = {0}; + u8 reg_bcn_work; + int ret; + + skb = rtw_tx_write_data_rsvd_page_get(rtwdev, &pkt_info, buf, size); + if (!skb) + return -ENOMEM; + + ret = rtw_pci_tx_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_BCN); + if (ret) { + rtw_err(rtwdev, "failed to write rsvd page data\n"); + return ret; + } + + /* reserved pages go through beacon queue */ + reg_bcn_work = rtw_read8(rtwdev, RTK_PCI_TXBD_BCN_WORK); + reg_bcn_work |= BIT_PCI_BCNQ_FLAG; + rtw_write8(rtwdev, RTK_PCI_TXBD_BCN_WORK, reg_bcn_work); + + return 0; +} + +static int rtw_pci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + struct sk_buff *skb; + struct rtw_tx_pkt_info pkt_info = {0}; + int ret; + + skb = rtw_tx_write_data_h2c_get(rtwdev, &pkt_info, buf, size); + if (!skb) + return -ENOMEM; + + ret = rtw_pci_tx_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_H2C); + if (ret) { + rtw_err(rtwdev, "failed to write h2c data\n"); + return ret; + } + + rtw_pci_tx_kick_off_queue(rtwdev, RTW_TX_QUEUE_H2C); + + return 0; +} + +static int rtw_pci_tx_write(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + enum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb); + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *ring; + int ret; + + ret = rtw_pci_tx_write_data(rtwdev, pkt_info, skb, queue); + if (ret) + return ret; + + ring = &rtwpci->tx_rings[queue]; + spin_lock_bh(&rtwpci->irq_lock); + if (avail_desc(ring->r.wp, ring->r.rp, ring->r.len) < 2) { + ieee80211_stop_queue(rtwdev->hw, skb_get_queue_mapping(skb)); + ring->queue_stopped = true; + } + spin_unlock_bh(&rtwpci->irq_lock); + + return 0; +} + +static void rtw_pci_tx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, + u8 hw_queue) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_tx_info *info; + struct rtw_pci_tx_ring *ring; + struct rtw_pci_tx_data *tx_data; + struct sk_buff *skb; + u32 count; + u32 bd_idx_addr; + u32 bd_idx, cur_rp, rp_idx; + u16 q_map; + + ring = &rtwpci->tx_rings[hw_queue]; + + bd_idx_addr = rtw_pci_tx_queue_idx_addr[hw_queue]; + bd_idx = rtw_read32(rtwdev, bd_idx_addr); + cur_rp = bd_idx >> 16; + cur_rp &= TRX_BD_IDX_MASK; + rp_idx = ring->r.rp; + if (cur_rp >= ring->r.rp) + count = cur_rp - ring->r.rp; + else + count = ring->r.len - (ring->r.rp - cur_rp); + + while (count--) { + skb = skb_dequeue(&ring->queue); + if (!skb) { + rtw_err(rtwdev, "failed to dequeue %d skb TX queue %d, BD=0x%08x, rp %d -> %d\n", + count, hw_queue, bd_idx, ring->r.rp, cur_rp); + break; + } + tx_data = rtw_pci_get_tx_data(skb); + dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, + DMA_TO_DEVICE); + + /* just free command packets from host to card */ + if (hw_queue == RTW_TX_QUEUE_H2C) { + dev_kfree_skb_irq(skb); + continue; + } + + if (ring->queue_stopped && + avail_desc(ring->r.wp, rp_idx, ring->r.len) > 4) { + q_map = skb_get_queue_mapping(skb); + ieee80211_wake_queue(hw, q_map); + ring->queue_stopped = false; + } + + if (++rp_idx >= ring->r.len) + rp_idx = 0; + + skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + + info = IEEE80211_SKB_CB(skb); + + /* enqueue to wait for tx report */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); + continue; + } + + /* always ACK for others, then they won't be marked as drop */ + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + else + info->flags |= IEEE80211_TX_STAT_ACK; + + ieee80211_tx_info_clear_status(info); + ieee80211_tx_status_irqsafe(hw, skb); + } + + ring->r.rp = cur_rp; +} + +static void rtw_pci_rx_isr(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct napi_struct *napi = &rtwpci->napi; + + napi_schedule(napi); +} + +static int rtw_pci_get_hw_rx_ring_nr(struct rtw_dev *rtwdev, + struct rtw_pci *rtwpci) +{ + struct rtw_pci_rx_ring *ring; + int count = 0; + u32 tmp, cur_wp; + + ring = &rtwpci->rx_rings[RTW_RX_QUEUE_MPDU]; + tmp = rtw_read32(rtwdev, RTK_PCI_RXBD_IDX_MPDUQ); + cur_wp = u32_get_bits(tmp, TRX_BD_HW_IDX_MASK); + if (cur_wp >= ring->r.wp) + count = cur_wp - ring->r.wp; + else + count = ring->r.len - (ring->r.wp - cur_wp); + + return count; +} + +static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, + u8 hw_queue, u32 limit) +{ + struct rtw_pci_rx_ring *ring = &rtwpci->rx_rings[RTW_RX_QUEUE_MPDU]; + const struct rtw_chip_info *chip = rtwdev->chip; + struct napi_struct *napi = &rtwpci->napi; + u32 pkt_desc_sz = chip->rx_pkt_desc_sz; + u32 buf_desc_sz = chip->rx_buf_desc_sz; + struct ieee80211_rx_status rx_status; + struct rtw_rx_pkt_stat pkt_stat; + struct sk_buff *skb, *new; + u32 cur_rp = ring->r.rp; + u32 count, rx_done = 0; + u32 pkt_offset; + dma_addr_t dma; + u32 new_len; + u8 *rx_desc; + int ret; + + count = rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci); + count = min(count, limit); + + while (count--) { + rtw_pci_dma_check(rtwdev, ring, cur_rp); + skb = ring->buf[cur_rp]; + dma = *((dma_addr_t *)skb->cb); + dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE, + DMA_FROM_DEVICE); + rx_desc = skb->data; + ret = rtw_rx_query_rx_desc(rtwdev, rx_desc, + &pkt_stat, &rx_status); + if (ret) + goto next_rp; + + /* offset from rx_desc to payload */ + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + + /* allocate a new skb for this frame, + * discard the frame if none available + */ + new_len = pkt_stat.pkt_len + pkt_offset; + if (unlikely(new_len > RTK_PCI_RX_BUF_SIZE)) { + rtw_dbg(rtwdev, RTW_DBG_RX, + "oversized RX packet: %u\n", new_len); + goto next_rp; + } + new = dev_alloc_skb(new_len); + if (WARN_ONCE(!new, "rx routine starvation\n")) + goto next_rp; + + /* put the DMA data including rx_desc from phy to new skb */ + skb_put_data(new, skb->data, new_len); + + if (pkt_stat.is_c2h) { + rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, new); + } else { + /* remove rx_desc */ + skb_pull(new, pkt_offset); + + rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat); + rtw_rx_stats(rtwdev, pkt_stat.vif, new); + memcpy(new->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_napi(rtwdev->hw, NULL, new, napi); + rx_done++; + } + +next_rp: + /* new skb delivered to mac80211, re-enable original skb DMA */ + rtw_pci_sync_rx_desc_device(rtwdev, dma, ring, cur_rp, + buf_desc_sz); + + /* host read next element in ring */ + if (++cur_rp >= ring->r.len) + cur_rp = 0; + } + + ring->r.rp = cur_rp; + /* 'rp', the last position we have read, is seen as previous posistion + * of 'wp' that is used to calculate 'count' next time. + */ + ring->r.wp = cur_rp; + rtw_write16(rtwdev, RTK_PCI_RXBD_IDX_MPDUQ, ring->r.rp); + + return rx_done; +} + +static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev, + struct rtw_pci *rtwpci, u32 *irq_status) +{ + unsigned long flags; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + + irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0); + irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1); + if (rtw_chip_wcpu_3081(rtwdev)) + irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); + else + irq_status[3] = 0; + irq_status[0] &= rtwpci->irq_mask[0]; + irq_status[1] &= rtwpci->irq_mask[1]; + irq_status[3] &= rtwpci->irq_mask[3]; + rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]); + rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]); + if (rtw_chip_wcpu_3081(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); + + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); +} + +static irqreturn_t rtw_pci_interrupt_handler(int irq, void *dev) +{ + struct rtw_dev *rtwdev = dev; + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + /* disable RTW PCI interrupt to avoid more interrupts before the end of + * thread function + * + * disable HIMR here to also avoid new HISR flag being raised before + * the HISRs have been Write-1-cleared for MSI. If not all of the HISRs + * are cleared, the edge-triggered interrupt will not be generated when + * a new HISR flag is set. + */ + rtw_pci_disable_interrupt(rtwdev, rtwpci); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t rtw_pci_interrupt_threadfn(int irq, void *dev) +{ + struct rtw_dev *rtwdev = dev; + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + u32 irq_status[4]; + bool rx = false; + + spin_lock_bh(&rtwpci->irq_lock); + rtw_pci_irq_recognized(rtwdev, rtwpci, irq_status); + + if (irq_status[0] & IMR_MGNTDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_MGMT); + if (irq_status[0] & IMR_HIGHDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_HI0); + if (irq_status[0] & IMR_BEDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_BE); + if (irq_status[0] & IMR_BKDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_BK); + if (irq_status[0] & IMR_VODOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_VO); + if (irq_status[0] & IMR_VIDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_VI); + if (irq_status[3] & IMR_H2CDOK) + rtw_pci_tx_isr(rtwdev, rtwpci, RTW_TX_QUEUE_H2C); + if (irq_status[0] & IMR_ROK) { + rtw_pci_rx_isr(rtwdev); + rx = true; + } + if (unlikely(irq_status[0] & IMR_C2HCMD)) + rtw_fw_c2h_cmd_isr(rtwdev); + + /* all of the jobs for this interrupt have been done */ + if (rtwpci->running) + rtw_pci_enable_interrupt(rtwdev, rtwpci, rx); + spin_unlock_bh(&rtwpci->irq_lock); + + return IRQ_HANDLED; +} + +static int rtw_pci_io_mapping(struct rtw_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + unsigned long len; + u8 bar_id = 2; + int ret; + + ret = pci_request_regions(pdev, KBUILD_MODNAME); + if (ret) { + rtw_err(rtwdev, "failed to request pci regions\n"); + return ret; + } + + len = pci_resource_len(pdev, bar_id); + rtwpci->mmap = pci_iomap(pdev, bar_id, len); + if (!rtwpci->mmap) { + pci_release_regions(pdev); + rtw_err(rtwdev, "failed to map pci memory\n"); + return -ENOMEM; + } + + return 0; +} + +static void rtw_pci_io_unmapping(struct rtw_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + if (rtwpci->mmap) { + pci_iounmap(pdev, rtwpci->mmap); + pci_release_regions(pdev); + } +} + +static void rtw_dbi_write8(struct rtw_dev *rtwdev, u16 addr, u8 data) +{ + u16 write_addr; + u16 remainder = addr & ~(BITS_DBI_WREN | BITS_DBI_ADDR_MASK); + u8 flag; + u8 cnt; + + write_addr = addr & BITS_DBI_ADDR_MASK; + write_addr |= u16_encode_bits(BIT(remainder), BITS_DBI_WREN); + rtw_write8(rtwdev, REG_DBI_WDATA_V1 + remainder, data); + rtw_write16(rtwdev, REG_DBI_FLAG_V1, write_addr); + rtw_write8(rtwdev, REG_DBI_FLAG_V1 + 2, BIT_DBI_WFLAG >> 16); + + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { + flag = rtw_read8(rtwdev, REG_DBI_FLAG_V1 + 2); + if (flag == 0) + return; + + udelay(10); + } + + WARN(flag, "failed to write to DBI register, addr=0x%04x\n", addr); +} + +static int rtw_dbi_read8(struct rtw_dev *rtwdev, u16 addr, u8 *value) +{ + u16 read_addr = addr & BITS_DBI_ADDR_MASK; + u8 flag; + u8 cnt; + + rtw_write16(rtwdev, REG_DBI_FLAG_V1, read_addr); + rtw_write8(rtwdev, REG_DBI_FLAG_V1 + 2, BIT_DBI_RFLAG >> 16); + + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { + flag = rtw_read8(rtwdev, REG_DBI_FLAG_V1 + 2); + if (flag == 0) { + read_addr = REG_DBI_RDATA_V1 + (addr & 3); + *value = rtw_read8(rtwdev, read_addr); + return 0; + } + + udelay(10); + } + + WARN(1, "failed to read DBI register, addr=0x%04x\n", addr); + return -EIO; +} + +static void rtw_mdio_write(struct rtw_dev *rtwdev, u8 addr, u16 data, bool g1) +{ + u8 page; + u8 wflag; + u8 cnt; + + rtw_write16(rtwdev, REG_MDIO_V1, data); + + page = addr < RTW_PCI_MDIO_PG_SZ ? 0 : 1; + page += g1 ? RTW_PCI_MDIO_PG_OFFS_G1 : RTW_PCI_MDIO_PG_OFFS_G2; + rtw_write8(rtwdev, REG_PCIE_MIX_CFG, addr & BITS_MDIO_ADDR_MASK); + rtw_write8(rtwdev, REG_PCIE_MIX_CFG + 3, page); + rtw_write32_mask(rtwdev, REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1, 1); + + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { + wflag = rtw_read32_mask(rtwdev, REG_PCIE_MIX_CFG, + BIT_MDIO_WFLAG_V1); + if (wflag == 0) + return; + + udelay(10); + } + + WARN(wflag, "failed to write to MDIO register, addr=0x%02x\n", addr); +} + +static void rtw_pci_clkreq_set(struct rtw_dev *rtwdev, bool enable) +{ + u8 value; + int ret; + + if (rtw_pci_disable_aspm) + return; + + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); + if (ret) { + rtw_err(rtwdev, "failed to read CLKREQ_L1, ret=%d", ret); + return; + } + + if (enable) + value |= BIT_CLKREQ_SW_EN; + else + value &= ~BIT_CLKREQ_SW_EN; + + rtw_dbi_write8(rtwdev, RTK_PCIE_LINK_CFG, value); +} + +static void rtw_pci_clkreq_pad_low(struct rtw_dev *rtwdev, bool enable) +{ + u8 value; + int ret; + + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); + if (ret) { + rtw_err(rtwdev, "failed to read CLKREQ_L1, ret=%d", ret); + return; + } + + if (enable) + value &= ~BIT_CLKREQ_N_PAD; + else + value |= BIT_CLKREQ_N_PAD; + + rtw_dbi_write8(rtwdev, RTK_PCIE_LINK_CFG, value); +} + +static void rtw_pci_aspm_set(struct rtw_dev *rtwdev, bool enable) +{ + u8 value; + int ret; + + if (rtw_pci_disable_aspm) + return; + + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); + if (ret) { + rtw_err(rtwdev, "failed to read ASPM, ret=%d", ret); + return; + } + + if (enable) + value |= BIT_L1_SW_EN; + else + value &= ~BIT_L1_SW_EN; + + rtw_dbi_write8(rtwdev, RTK_PCIE_LINK_CFG, value); +} + +static void rtw_pci_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + /* Like CLKREQ, ASPM is also implemented by two HW modules, and can + * only be enabled when host supports it. + * + * And ASPM mechanism should be enabled when driver/firmware enters + * power save mode, without having heavy traffic. Because we've + * experienced some inter-operability issues that the link tends + * to enter L1 state on the fly even when driver is having high + * throughput. This is probably because the ASPM behavior slightly + * varies from different SOC. + */ + if (!(rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1)) + return; + + if ((enter && atomic_dec_if_positive(&rtwpci->link_usage) == 0) || + (!enter && atomic_inc_return(&rtwpci->link_usage) == 1)) + rtw_pci_aspm_set(rtwdev, enter); +} + +static void rtw_pci_link_cfg(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u16 link_ctrl; + int ret; + + /* RTL8822CE has enabled REFCLK auto calibration, it does not need + * to add clock delay to cover the REFCLK timing gap. + */ + if (chip->id == RTW_CHIP_TYPE_8822C) + rtw_dbi_write8(rtwdev, RTK_PCIE_CLKDLY_CTRL, 0); + + /* Though there is standard PCIE configuration space to set the + * link control register, but by Realtek's design, driver should + * check if host supports CLKREQ/ASPM to enable the HW module. + * + * These functions are implemented by two HW modules associated, + * one is responsible to access PCIE configuration space to + * follow the host settings, and another is in charge of doing + * CLKREQ/ASPM mechanisms, it is default disabled. Because sometimes + * the host does not support it, and due to some reasons or wrong + * settings (ex. CLKREQ# not Bi-Direction), it could lead to device + * loss if HW misbehaves on the link. + * + * Hence it's designed that driver should first check the PCIE + * configuration space is sync'ed and enabled, then driver can turn + * on the other module that is actually working on the mechanism. + */ + ret = pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &link_ctrl); + if (ret) { + rtw_err(rtwdev, "failed to read PCI cap, ret=%d\n", ret); + return; + } + + if (link_ctrl & PCI_EXP_LNKCTL_CLKREQ_EN) + rtw_pci_clkreq_set(rtwdev, true); + + rtwpci->link_ctrl = link_ctrl; +} + +static void rtw_pci_interface_cfg(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + switch (chip->id) { + case RTW_CHIP_TYPE_8822C: + if (rtwdev->hal.cut_version >= RTW_CHIP_VER_CUT_D) + rtw_write32_mask(rtwdev, REG_HCI_MIX_CFG, + BIT_PCIE_EMAC_PDN_AUX_TO_FAST_CLK, 1); + break; + default: + break; + } +} + +static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct pci_dev *pdev = rtwpci->pdev; + const struct rtw_intf_phy_para *para; + u16 cut; + u16 value; + u16 offset; + int i; + int ret; + + cut = BIT(0) << rtwdev->hal.cut_version; + + for (i = 0; i < chip->intf_table->n_gen1_para; i++) { + para = &chip->intf_table->gen1_para[i]; + if (!(para->cut_mask & cut)) + continue; + if (para->offset == 0xffff) + break; + offset = para->offset; + value = para->value; + if (para->ip_sel == RTW_IP_SEL_PHY) + rtw_mdio_write(rtwdev, offset, value, true); + else + rtw_dbi_write8(rtwdev, offset, value); + } + + for (i = 0; i < chip->intf_table->n_gen2_para; i++) { + para = &chip->intf_table->gen2_para[i]; + if (!(para->cut_mask & cut)) + continue; + if (para->offset == 0xffff) + break; + offset = para->offset; + value = para->value; + if (para->ip_sel == RTW_IP_SEL_PHY) + rtw_mdio_write(rtwdev, offset, value, false); + else + rtw_dbi_write8(rtwdev, offset, value); + } + + rtw_pci_link_cfg(rtwdev); + + /* Disable 8821ce completion timeout by default */ + if (chip->id == RTW_CHIP_TYPE_8821C) { + ret = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); + if (ret) + rtw_err(rtwdev, "failed to set PCI cap, ret = %d\n", + ret); + } + + if (chip->id == RTW_CHIP_TYPE_8822C && efuse->rfe_option == 5) + rtw_write32_mask(rtwdev, REG_ANAPARSW_MAC_0, BIT_CF_L_V2, 0x1); +} + +static int __maybe_unused rtw_pci_suspend(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (chip->id == RTW_CHIP_TYPE_8822C && efuse->rfe_option == 6) + rtw_pci_clkreq_pad_low(rtwdev, true); + return 0; +} + +static int __maybe_unused rtw_pci_resume(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw_dev *rtwdev = hw->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (chip->id == RTW_CHIP_TYPE_8822C && efuse->rfe_option == 6) + rtw_pci_clkreq_pad_low(rtwdev, false); + return 0; +} + +SIMPLE_DEV_PM_OPS(rtw_pm_ops, rtw_pci_suspend, rtw_pci_resume); +EXPORT_SYMBOL(rtw_pm_ops); + +static int rtw_pci_claim(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + int ret; + + ret = pci_enable_device(pdev); + if (ret) { + rtw_err(rtwdev, "failed to enable pci device\n"); + return ret; + } + + pci_set_master(pdev); + pci_set_drvdata(pdev, rtwdev->hw); + SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); + + return 0; +} + +static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + pci_disable_device(pdev); +} + +static int rtw_pci_setup_resource(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + struct rtw_pci *rtwpci; + int ret; + + rtwpci = (struct rtw_pci *)rtwdev->priv; + rtwpci->pdev = pdev; + + /* after this driver can access to hw registers */ + ret = rtw_pci_io_mapping(rtwdev, pdev); + if (ret) { + rtw_err(rtwdev, "failed to request pci io region\n"); + goto err_out; + } + + ret = rtw_pci_init(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to allocate pci resources\n"); + goto err_io_unmap; + } + + return 0; + +err_io_unmap: + rtw_pci_io_unmapping(rtwdev, pdev); + +err_out: + return ret; +} + +static void rtw_pci_destroy(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + rtw_pci_deinit(rtwdev); + rtw_pci_io_unmapping(rtwdev, pdev); +} + +static const struct rtw_hci_ops rtw_pci_ops = { + .tx_write = rtw_pci_tx_write, + .tx_kick_off = rtw_pci_tx_kick_off, + .flush_queues = rtw_pci_flush_queues, + .setup = rtw_pci_setup, + .start = rtw_pci_start, + .stop = rtw_pci_stop, + .deep_ps = rtw_pci_deep_ps, + .link_ps = rtw_pci_link_ps, + .interface_cfg = rtw_pci_interface_cfg, + .dynamic_rx_agg = NULL, + .write_firmware_page = rtw_write_firmware_page, + + .read8 = rtw_pci_read8, + .read16 = rtw_pci_read16, + .read32 = rtw_pci_read32, + .write8 = rtw_pci_write8, + .write16 = rtw_pci_write16, + .write32 = rtw_pci_write32, + .write_data_rsvd_page = rtw_pci_write_data_rsvd_page, + .write_data_h2c = rtw_pci_write_data_h2c, +}; + +static int rtw_pci_request_irq(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + unsigned int flags = PCI_IRQ_INTX; + int ret; + + if (!rtw_disable_msi) + flags |= PCI_IRQ_MSI; + + ret = pci_alloc_irq_vectors(pdev, 1, 1, flags); + if (ret < 0) { + rtw_err(rtwdev, "failed to alloc PCI irq vectors\n"); + return ret; + } + + ret = devm_request_threaded_irq(rtwdev->dev, pdev->irq, + rtw_pci_interrupt_handler, + rtw_pci_interrupt_threadfn, + IRQF_SHARED, KBUILD_MODNAME, rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to request irq %d\n", ret); + pci_free_irq_vectors(pdev); + } + + return ret; +} + +static void rtw_pci_free_irq(struct rtw_dev *rtwdev, struct pci_dev *pdev) +{ + devm_free_irq(rtwdev->dev, pdev->irq, rtwdev); + pci_free_irq_vectors(pdev); +} + +static int rtw_pci_napi_poll(struct napi_struct *napi, int budget) +{ + struct rtw_pci *rtwpci = container_of(napi, struct rtw_pci, napi); + struct rtw_dev *rtwdev = container_of((void *)rtwpci, struct rtw_dev, + priv); + int work_done = 0; + + if (rtwpci->rx_no_aspm) + rtw_pci_link_ps(rtwdev, false); + + while (work_done < budget) { + u32 work_done_once; + + work_done_once = rtw_pci_rx_napi(rtwdev, rtwpci, RTW_RX_QUEUE_MPDU, + budget - work_done); + if (work_done_once == 0) + break; + work_done += work_done_once; + } + if (work_done < budget) { + napi_complete_done(napi, work_done); + spin_lock_bh(&rtwpci->irq_lock); + if (rtwpci->running) + rtw_pci_enable_interrupt(rtwdev, rtwpci, false); + spin_unlock_bh(&rtwpci->irq_lock); + /* When ISR happens during polling and before napi_complete + * while no further data is received. Data on the dma_ring will + * not be processed immediately. Check whether dma ring is + * empty and perform napi_schedule accordingly. + */ + if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci)) + napi_schedule(napi); + } + if (rtwpci->rx_no_aspm) + rtw_pci_link_ps(rtwdev, true); + + return work_done; +} + +static int rtw_pci_napi_init(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtwpci->netdev = alloc_netdev_dummy(0); + if (!rtwpci->netdev) + return -ENOMEM; + + netif_napi_add(rtwpci->netdev, &rtwpci->napi, rtw_pci_napi_poll); + return 0; +} + +static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtw_pci_napi_stop(rtwdev); + netif_napi_del(&rtwpci->napi); + free_netdev(rtwpci->netdev); +} + +static pci_ers_result_t rtw_pci_io_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + + ieee80211_stop_queues(hw); + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t rtw_pci_io_slot_reset(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw_dev *rtwdev = hw->priv; + + rtw_fw_recovery(rtwdev); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void rtw_pci_io_resume(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, PCI_D0, 0); + + ieee80211_wake_queues(hw); +} + +const struct pci_error_handlers rtw_pci_err_handler = { + .error_detected = rtw_pci_io_err_detected, + .slot_reset = rtw_pci_io_slot_reset, + .resume = rtw_pci_io_resume, +}; +EXPORT_SYMBOL(rtw_pci_err_handler); + +static int rtw_pci_disable_caps(const struct dmi_system_id *dmi) +{ + uintptr_t dis_caps = (uintptr_t)dmi->driver_data; + + if (dis_caps & BIT(QUIRK_DIS_CAP_PCI_ASPM)) + rtw_pci_disable_aspm = true; + + if (dis_caps & BIT(QUIRK_DIS_CAP_LPS_DEEP)) + rtw_disable_lps_deep_mode = true; + + return 1; +} + +static const struct dmi_system_id rtw_pci_quirks[] = { + { + .callback = rtw_pci_disable_caps, + .ident = "HP Notebook - P3S95EA#ACB", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Notebook"), + DMI_MATCH(DMI_PRODUCT_SKU, "P3S95EA#ACB"), + }, + .driver_data = (void *)(BIT(QUIRK_DIS_CAP_PCI_ASPM) | + BIT(QUIRK_DIS_CAP_LPS_DEEP)), + }, + { + .callback = rtw_pci_disable_caps, + .ident = "ASUS TUF Gaming A15 FA506II", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "FA506II"), + }, + .driver_data = (void *)(BIT(QUIRK_DIS_CAP_PCI_ASPM) | + BIT(QUIRK_DIS_CAP_LPS_DEEP)), + }, + {} +}; + +int rtw_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct pci_dev *bridge = pci_upstream_bridge(pdev); + struct ieee80211_hw *hw; + struct rtw_dev *rtwdev; + struct rtw_pci *rtwpci; + int drv_data_size; + int ret; + + drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_pci); + hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops); + if (!hw) { + dev_err(&pdev->dev, "failed to allocate hw\n"); + return -ENOMEM; + } + + rtwdev = hw->priv; + rtwdev->hw = hw; + rtwdev->dev = &pdev->dev; + rtwdev->chip = (struct rtw_chip_info *)id->driver_data; + rtwdev->hci.ops = &rtw_pci_ops; + rtwdev->hci.type = RTW_HCI_TYPE_PCIE; + + rtwpci = (struct rtw_pci *)rtwdev->priv; + atomic_set(&rtwpci->link_usage, 1); + + dmi_check_system(rtw_pci_quirks); + + ret = rtw_core_init(rtwdev); + if (ret) + goto err_release_hw; + + rtw_dbg(rtwdev, RTW_DBG_PCI, + "rtw88 pci probe: vendor=0x%4.04X device=0x%4.04X rev=%d\n", + pdev->vendor, pdev->device, pdev->revision); + + ret = rtw_pci_claim(rtwdev, pdev); + if (ret) { + rtw_err(rtwdev, "failed to claim pci device\n"); + goto err_deinit_core; + } + + ret = rtw_pci_setup_resource(rtwdev, pdev); + if (ret) { + rtw_err(rtwdev, "failed to setup pci resources\n"); + goto err_pci_declaim; + } + + ret = rtw_pci_napi_init(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup NAPI\n"); + goto err_destroy_rsrc; + } + + ret = rtw_chip_info_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip information\n"); + goto err_destroy_pci; + } + + /* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821C && + bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) + rtwpci->rx_no_aspm = true; + + rtw_pci_phy_cfg(rtwdev); + + ret = rtw_register_hw(rtwdev, hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw\n"); + goto err_destroy_pci; + } + + ret = rtw_pci_request_irq(rtwdev, pdev); + if (ret) { + ieee80211_unregister_hw(hw); + goto err_destroy_pci; + } + + return 0; + +err_destroy_pci: + rtw_pci_napi_deinit(rtwdev); + +err_destroy_rsrc: + rtw_pci_destroy(rtwdev, pdev); + +err_pci_declaim: + rtw_pci_declaim(rtwdev, pdev); + +err_deinit_core: + rtw_core_deinit(rtwdev); + +err_release_hw: + ieee80211_free_hw(hw); + + return ret; +} +EXPORT_SYMBOL(rtw_pci_probe); + +void rtw_pci_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw_dev *rtwdev; + struct rtw_pci *rtwpci; + + if (!hw) + return; + + rtwdev = hw->priv; + rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtw_unregister_hw(rtwdev, hw); + rtw_pci_disable_interrupt(rtwdev, rtwpci); + rtw_pci_napi_deinit(rtwdev); + rtw_pci_destroy(rtwdev, pdev); + rtw_pci_declaim(rtwdev, pdev); + rtw_pci_free_irq(rtwdev, pdev); + rtw_core_deinit(rtwdev); + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtw_pci_remove); + +void rtw_pci_shutdown(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw_dev *rtwdev; + const struct rtw_chip_info *chip; + + if (!hw) + return; + + rtwdev = hw->priv; + chip = rtwdev->chip; + + if (chip->ops->shutdown) + chip->ops->shutdown(rtwdev); + + pci_set_power_state(pdev, PCI_D3hot); +} +EXPORT_SYMBOL(rtw_pci_shutdown); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek PCI 802.11ac wireless driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/pci.h b/drivers/net/wireless/realtek/rtw88/pci.h new file mode 100644 index 000000000..8ffdea113 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/pci.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTK_PCI_H_ +#define __RTK_PCI_H_ + +#include "main.h" + +#define RTK_DEFAULT_TX_DESC_NUM 128 +#define RTK_BEQ_TX_DESC_NUM 256 + +#define RTK_MAX_RX_DESC_NUM 512 +/* 11K + rx desc size */ +#define RTK_PCI_RX_BUF_SIZE (11454 + 24) + +#define RTK_PCI_CTRL 0x300 +#define BIT_RST_TRXDMA_INTF BIT(20) +#define BIT_RX_TAG_EN BIT(15) +#define REG_DBI_WDATA_V1 0x03E8 +#define REG_DBI_RDATA_V1 0x03EC +#define REG_DBI_FLAG_V1 0x03F0 +#define BIT_DBI_RFLAG BIT(17) +#define BIT_DBI_WFLAG BIT(16) +#define BITS_DBI_WREN GENMASK(15, 12) +#define BITS_DBI_ADDR_MASK GENMASK(11, 2) + +#define REG_MDIO_V1 0x03F4 +#define REG_PCIE_MIX_CFG 0x03F8 +#define BITS_MDIO_ADDR_MASK GENMASK(4, 0) +#define BIT_MDIO_WFLAG_V1 BIT(5) +#define RTW_PCI_MDIO_PG_SZ BIT(5) +#define RTW_PCI_MDIO_PG_OFFS_G1 0 +#define RTW_PCI_MDIO_PG_OFFS_G2 2 +#define RTW_PCI_WR_RETRY_CNT 20 + +#define RTK_PCIE_LINK_CFG 0x0719 +#define BIT_CLKREQ_SW_EN BIT(4) +#define BIT_L1_SW_EN BIT(3) +#define BIT_CLKREQ_N_PAD BIT(0) +#define RTK_PCIE_CLKDLY_CTRL 0x0725 + +#define BIT_PCI_BCNQ_FLAG BIT(4) +#define RTK_PCI_TXBD_DESA_BCNQ 0x308 +#define RTK_PCI_TXBD_DESA_H2CQ 0x1320 +#define RTK_PCI_TXBD_DESA_MGMTQ 0x310 +#define RTK_PCI_TXBD_DESA_BKQ 0x330 +#define RTK_PCI_TXBD_DESA_BEQ 0x328 +#define RTK_PCI_TXBD_DESA_VIQ 0x320 +#define RTK_PCI_TXBD_DESA_VOQ 0x318 +#define RTK_PCI_TXBD_DESA_HI0Q 0x340 +#define RTK_PCI_RXBD_DESA_MPDUQ 0x338 + +#define TRX_BD_IDX_MASK GENMASK(11, 0) +#define TRX_BD_HW_IDX_MASK GENMASK(27, 16) + +/* BCNQ is specialized for rsvd page, does not need to specify a number */ +#define RTK_PCI_TXBD_NUM_H2CQ 0x1328 +#define RTK_PCI_TXBD_NUM_MGMTQ 0x380 +#define RTK_PCI_TXBD_NUM_BKQ 0x38A +#define RTK_PCI_TXBD_NUM_BEQ 0x388 +#define RTK_PCI_TXBD_NUM_VIQ 0x386 +#define RTK_PCI_TXBD_NUM_VOQ 0x384 +#define RTK_PCI_TXBD_NUM_HI0Q 0x38C +#define RTK_PCI_RXBD_NUM_MPDUQ 0x382 +#define RTK_PCI_TXBD_IDX_H2CQ 0x132C +#define RTK_PCI_TXBD_IDX_MGMTQ 0x3B0 +#define RTK_PCI_TXBD_IDX_BKQ 0x3AC +#define RTK_PCI_TXBD_IDX_BEQ 0x3A8 +#define RTK_PCI_TXBD_IDX_VIQ 0x3A4 +#define RTK_PCI_TXBD_IDX_VOQ 0x3A0 +#define RTK_PCI_TXBD_IDX_HI0Q 0x3B8 +#define RTK_PCI_RXBD_IDX_MPDUQ 0x3B4 + +#define RTK_PCI_TXBD_RWPTR_CLR 0x39C +#define RTK_PCI_TXBD_H2CQ_CSR 0x1330 + +#define BIT_CLR_H2CQ_HOST_IDX BIT(16) +#define BIT_CLR_H2CQ_HW_IDX BIT(8) + +#define RTK_PCI_HIMR0 0x0B0 +#define RTK_PCI_HISR0 0x0B4 +#define RTK_PCI_HIMR1 0x0B8 +#define RTK_PCI_HISR1 0x0BC +#define RTK_PCI_HIMR2 0x10B0 +#define RTK_PCI_HISR2 0x10B4 +#define RTK_PCI_HIMR3 0x10B8 +#define RTK_PCI_HISR3 0x10BC +/* IMR 0 */ +#define IMR_TIMER2 BIT(31) +#define IMR_TIMER1 BIT(30) +#define IMR_PSTIMEOUT BIT(29) +#define IMR_GTINT4 BIT(28) +#define IMR_GTINT3 BIT(27) +#define IMR_TBDER BIT(26) +#define IMR_TBDOK BIT(25) +#define IMR_TSF_BIT32_TOGGLE BIT(24) +#define IMR_BCNDMAINT0 BIT(20) +#define IMR_BCNDOK0 BIT(16) +#define IMR_HSISR_IND_ON_INT BIT(15) +#define IMR_BCNDMAINT_E BIT(14) +#define IMR_ATIMEND BIT(12) +#define IMR_HISR1_IND_INT BIT(11) +#define IMR_C2HCMD BIT(10) +#define IMR_CPWM2 BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_HIGHDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_BKDOK BIT(5) +#define IMR_BEDOK BIT(4) +#define IMR_VIDOK BIT(3) +#define IMR_VODOK BIT(2) +#define IMR_RDU BIT(1) +#define IMR_ROK BIT(0) +/* IMR 1 */ +#define IMR_TXFIFO_TH_INT BIT(30) +#define IMR_BTON_STS_UPDATE BIT(29) +#define IMR_MCUERR BIT(28) +#define IMR_BCNDMAINT7 BIT(27) +#define IMR_BCNDMAINT6 BIT(26) +#define IMR_BCNDMAINT5 BIT(25) +#define IMR_BCNDMAINT4 BIT(24) +#define IMR_BCNDMAINT3 BIT(23) +#define IMR_BCNDMAINT2 BIT(22) +#define IMR_BCNDMAINT1 BIT(21) +#define IMR_BCNDOK7 BIT(20) +#define IMR_BCNDOK6 BIT(19) +#define IMR_BCNDOK5 BIT(18) +#define IMR_BCNDOK4 BIT(17) +#define IMR_BCNDOK3 BIT(16) +#define IMR_BCNDOK2 BIT(15) +#define IMR_BCNDOK1 BIT(14) +#define IMR_ATIMEND_E BIT(13) +#define IMR_ATIMEND BIT(12) +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_TXFOVW BIT(9) +#define IMR_RXFOVW BIT(8) +#define IMR_CPU_MGQ_TXDONE BIT(5) +#define IMR_PS_TIMER_C BIT(4) +#define IMR_PS_TIMER_B BIT(3) +#define IMR_PS_TIMER_A BIT(2) +#define IMR_CPUMGQ_TX_TIMER BIT(1) +/* IMR 3 */ +#define IMR_H2CDOK BIT(16) + +enum rtw_pci_flags { + RTW_PCI_FLAG_NAPI_RUNNING, + + NUM_OF_RTW_PCI_FLAGS, +}; + +/* one element is reserved to know if the ring is closed */ +static inline int avail_desc(u32 wp, u32 rp, u32 len) +{ + if (rp > wp) + return rp - wp - 1; + else + return len - wp + rp - 1; +} + +#define RTK_PCI_TXBD_OWN_OFFSET 15 +#define RTK_PCI_TXBD_BCN_WORK 0x383 + +struct rtw_pci_tx_buffer_desc { + __le16 buf_size; + __le16 psb_len; + __le32 dma; +}; + +struct rtw_pci_tx_data { + dma_addr_t dma; + u8 sn; +}; + +struct rtw_pci_ring { + u8 *head; + dma_addr_t dma; + + u8 desc_size; + + u32 len; + u32 wp; + u32 rp; +}; + +struct rtw_pci_tx_ring { + struct rtw_pci_ring r; + struct sk_buff_head queue; + bool queue_stopped; +}; + +struct rtw_pci_rx_buffer_desc { + __le16 buf_size; + __le16 total_pkt_size; + __le32 dma; +}; + +struct rtw_pci_rx_ring { + struct rtw_pci_ring r; + struct sk_buff *buf[RTK_MAX_RX_DESC_NUM]; +}; + +#define RX_TAG_MAX 8192 + +struct rtw_pci { + struct pci_dev *pdev; + + /* Used for PCI interrupt. */ + spinlock_t hwirq_lock; + /* Used for PCI TX ring/queueing, and enable INT. */ + spinlock_t irq_lock; + u32 irq_mask[4]; + bool irq_enabled; + bool running; + + /* napi structure */ + struct net_device *netdev; + struct napi_struct napi; + + u16 rx_tag; + DECLARE_BITMAP(tx_queued, RTK_MAX_TX_QUEUE_NUM); + struct rtw_pci_tx_ring tx_rings[RTK_MAX_TX_QUEUE_NUM]; + struct rtw_pci_rx_ring rx_rings[RTK_MAX_RX_QUEUE_NUM]; + u16 link_ctrl; + atomic_t link_usage; + bool rx_no_aspm; + DECLARE_BITMAP(flags, NUM_OF_RTW_PCI_FLAGS); + + void __iomem *mmap; +}; + +extern const struct dev_pm_ops rtw_pm_ops; +extern const struct pci_error_handlers rtw_pci_err_handler; + +int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); +void rtw_pci_remove(struct pci_dev *pdev); +void rtw_pci_shutdown(struct pci_dev *pdev); + +static inline u32 max_num_of_tx_queue(u8 queue) +{ + u32 max_num; + + switch (queue) { + case RTW_TX_QUEUE_BE: + max_num = RTK_BEQ_TX_DESC_NUM; + break; + case RTW_TX_QUEUE_BCN: + max_num = 1; + break; + default: + max_num = RTK_DEFAULT_TX_DESC_NUM; + break; + } + + return max_num; +} + +static inline struct +rtw_pci_tx_data *rtw_pci_get_tx_data(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct rtw_pci_tx_data) > + sizeof(info->status.status_driver_data)); + + return (struct rtw_pci_tx_data *)info->status.status_driver_data; +} + +static inline +struct rtw_pci_tx_buffer_desc *get_tx_buffer_desc(struct rtw_pci_tx_ring *ring, + u32 size) +{ + u8 *buf_desc; + + buf_desc = ring->r.head + ring->r.wp * size; + return (struct rtw_pci_tx_buffer_desc *)buf_desc; +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c new file mode 100644 index 000000000..e2ac5c6fd --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -0,0 +1,2699 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include + +#include "main.h" +#include "reg.h" +#include "fw.h" +#include "phy.h" +#include "debug.h" +#include "regd.h" +#include "sar.h" + +struct phy_cfg_pair { + u32 addr; + u32 data; +}; + +union phy_table_tile { + struct { + struct rtw_phy_cond cond; + struct rtw_phy_cond2 cond2; + } __packed; + struct phy_cfg_pair cfg; +}; + +static const u32 db_invert_table[12][8] = { + {10, 13, 16, 20, + 25, 32, 40, 50}, + {64, 80, 101, 128, + 160, 201, 256, 318}, + {401, 505, 635, 800, + 1007, 1268, 1596, 2010}, + {316, 398, 501, 631, + 794, 1000, 1259, 1585}, + {1995, 2512, 3162, 3981, + 5012, 6310, 7943, 10000}, + {12589, 15849, 19953, 25119, + 31623, 39811, 50119, 63098}, + {79433, 100000, 125893, 158489, + 199526, 251189, 316228, 398107}, + {501187, 630957, 794328, 1000000, + 1258925, 1584893, 1995262, 2511886}, + {3162278, 3981072, 5011872, 6309573, + 7943282, 1000000, 12589254, 15848932}, + {19952623, 25118864, 31622777, 39810717, + 50118723, 63095734, 79432823, 100000000}, + {125892541, 158489319, 199526232, 251188643, + 316227766, 398107171, 501187234, 630957345}, + {794328235, 1000000000, 1258925412, 1584893192, + 1995262315, 2511886432U, 3162277660U, 3981071706U} +}; + +const u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; + +const u8 rtw_ofdm_rates[] = { + DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, + DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, + DESC_RATE48M, DESC_RATE54M +}; + +const u8 rtw_ht_1s_rates[] = { + DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, + DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, + DESC_RATEMCS6, DESC_RATEMCS7 +}; + +const u8 rtw_ht_2s_rates[] = { + DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, + DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, + DESC_RATEMCS14, DESC_RATEMCS15 +}; + +const u8 rtw_vht_1s_rates[] = { + DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, + DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, + DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, + DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, + DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9 +}; + +const u8 rtw_vht_2s_rates[] = { + DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, + DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, + DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, + DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, + DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 +}; + +const u8 rtw_ht_3s_rates[] = { + DESC_RATEMCS16, DESC_RATEMCS17, DESC_RATEMCS18, + DESC_RATEMCS19, DESC_RATEMCS20, DESC_RATEMCS21, + DESC_RATEMCS22, DESC_RATEMCS23 +}; + +const u8 rtw_ht_4s_rates[] = { + DESC_RATEMCS24, DESC_RATEMCS25, DESC_RATEMCS26, + DESC_RATEMCS27, DESC_RATEMCS28, DESC_RATEMCS29, + DESC_RATEMCS30, DESC_RATEMCS31 +}; + +const u8 rtw_vht_3s_rates[] = { + DESC_RATEVHT3SS_MCS0, DESC_RATEVHT3SS_MCS1, + DESC_RATEVHT3SS_MCS2, DESC_RATEVHT3SS_MCS3, + DESC_RATEVHT3SS_MCS4, DESC_RATEVHT3SS_MCS5, + DESC_RATEVHT3SS_MCS6, DESC_RATEVHT3SS_MCS7, + DESC_RATEVHT3SS_MCS8, DESC_RATEVHT3SS_MCS9 +}; + +const u8 rtw_vht_4s_rates[] = { + DESC_RATEVHT4SS_MCS0, DESC_RATEVHT4SS_MCS1, + DESC_RATEVHT4SS_MCS2, DESC_RATEVHT4SS_MCS3, + DESC_RATEVHT4SS_MCS4, DESC_RATEVHT4SS_MCS5, + DESC_RATEVHT4SS_MCS6, DESC_RATEVHT4SS_MCS7, + DESC_RATEVHT4SS_MCS8, DESC_RATEVHT4SS_MCS9 +}; + +const u8 * const rtw_rate_section[RTW_RATE_SECTION_NUM] = { + rtw_cck_rates, rtw_ofdm_rates, + rtw_ht_1s_rates, rtw_ht_2s_rates, + rtw_vht_1s_rates, rtw_vht_2s_rates, + rtw_ht_3s_rates, rtw_ht_4s_rates, + rtw_vht_3s_rates, rtw_vht_4s_rates +}; +EXPORT_SYMBOL(rtw_rate_section); + +const u8 rtw_rate_size[RTW_RATE_SECTION_NUM] = { + ARRAY_SIZE(rtw_cck_rates), + ARRAY_SIZE(rtw_ofdm_rates), + ARRAY_SIZE(rtw_ht_1s_rates), + ARRAY_SIZE(rtw_ht_2s_rates), + ARRAY_SIZE(rtw_vht_1s_rates), + ARRAY_SIZE(rtw_vht_2s_rates), + ARRAY_SIZE(rtw_ht_3s_rates), + ARRAY_SIZE(rtw_ht_4s_rates), + ARRAY_SIZE(rtw_vht_3s_rates), + ARRAY_SIZE(rtw_vht_4s_rates) +}; +EXPORT_SYMBOL(rtw_rate_size); + +enum rtw_phy_band_type { + PHY_BAND_2G = 0, + PHY_BAND_5G = 1, +}; + +static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 i, j; + + for (i = 0; i <= RTW_CHANNEL_WIDTH_40; i++) { + for (j = 0; j < RTW_RF_PATH_MAX; j++) + dm_info->cck_pd_lv[i][j] = CCK_PD_LV0; + } + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; +} + +void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) +{ + const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask, + l2h + edcca_th[EDCCA_TH_L2H_IDX].offset); + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask, + h2l + edcca_th[EDCCA_TH_H2L_IDX].offset); +} +EXPORT_SYMBOL(rtw_phy_set_edcca_th); + +void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* turn off in debugfs for debug usage */ + if (!rtw_edcca_enabled) { + dm_info->edcca_mode = RTW_EDCCA_NORMAL; + rtw_dbg(rtwdev, RTW_DBG_PHY, "EDCCA disabled, cannot be set\n"); + return; + } + + switch (rtwdev->regd.dfs_region) { + case NL80211_DFS_ETSI: + dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; + dm_info->l2h_th_ini = chip->l2h_th_ini_ad; + break; + case NL80211_DFS_JP: + dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; + dm_info->l2h_th_ini = chip->l2h_th_ini_cs; + break; + default: + dm_info->edcca_mode = RTW_EDCCA_NORMAL; + break; + } +} + +static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + rtw_phy_adaptivity_set_mode(rtwdev); + if (chip->ops->adaptivity_init) + chip->ops->adaptivity_init(rtwdev); +} + +static void rtw_phy_adaptivity(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->adaptivity) + rtwdev->chip->ops->adaptivity(rtwdev); +} + +static void rtw_phy_cfo_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (chip->ops->cfo_init) + chip->ops->cfo_init(rtwdev); +} + +static void rtw_phy_tx_path_div_init(struct rtw_dev *rtwdev) +{ + struct rtw_path_div *path_div = &rtwdev->dm_path_div; + + path_div->current_tx_path = rtwdev->chip->default_1ss_tx_path; + path_div->path_a_cnt = 0; + path_div->path_a_sum = 0; + path_div->path_b_cnt = 0; + path_div->path_b_sum = 0; +} + +void rtw_phy_init(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 addr, mask; + + dm_info->fa_history[3] = 0; + dm_info->fa_history[2] = 0; + dm_info->fa_history[1] = 0; + dm_info->fa_history[0] = 0; + dm_info->igi_bitmap = 0; + dm_info->igi_history[3] = 0; + dm_info->igi_history[2] = 0; + dm_info->igi_history[1] = 0; + + addr = chip->dig[0].addr; + mask = chip->dig[0].mask; + dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask); + rtw_phy_cck_pd_init(rtwdev); + + dm_info->iqk.done = false; + rtw_phy_adaptivity_init(rtwdev); + rtw_phy_cfo_init(rtwdev); + rtw_phy_tx_path_div_init(rtwdev); +} +EXPORT_SYMBOL(rtw_phy_init); + +void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + u32 addr, mask; + u8 path; + + if (chip->dig_cck) { + const struct rtw_hw_reg *dig_cck = &chip->dig_cck[0]; + rtw_write32_mask(rtwdev, dig_cck->addr, dig_cck->mask, igi >> 1); + } + + for (path = 0; path < hal->rf_path_num; path++) { + addr = chip->dig[path].addr; + mask = chip->dig[path].mask; + rtw_write32_mask(rtwdev, addr, mask, igi); + } +} + +static void rtw_phy_stat_false_alarm(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->false_alarm_statistics(rtwdev); +} + +#define RA_FLOOR_TABLE_SIZE 7 +#define RA_FLOOR_UP_GAP 3 + +static u8 rtw_phy_get_rssi_level(u8 old_level, u8 rssi) +{ + u8 table[RA_FLOOR_TABLE_SIZE] = {20, 34, 38, 42, 46, 50, 100}; + u8 new_level = 0; + int i; + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) + if (i >= old_level) + table[i] += RA_FLOOR_UP_GAP; + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (rssi < table[i]) { + new_level = i; + break; + } + } + + return new_level; +} + +struct rtw_phy_stat_iter_data { + struct rtw_dev *rtwdev; + u8 min_rssi; +}; + +static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_phy_stat_iter_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + u8 rssi; + + rssi = ewma_rssi_read(&si->avg_rssi); + si->rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi); + + rtw_fw_send_rssi_info(rtwdev, si); + + iter_data->min_rssi = min_t(u8, rssi, iter_data->min_rssi); +} + +static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_phy_stat_iter_data data = {}; + + data.rtwdev = rtwdev; + data.min_rssi = U8_MAX; + rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data); + + dm_info->pre_min_rssi = dm_info->min_rssi; + dm_info->min_rssi = data.min_rssi; +} + +static void rtw_phy_stat_rate_cnt(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->last_pkt_count = dm_info->cur_pkt_count; + memset(&dm_info->cur_pkt_count, 0, sizeof(dm_info->cur_pkt_count)); +} + +static void rtw_phy_statistics(struct rtw_dev *rtwdev) +{ + rtw_phy_stat_rssi(rtwdev); + rtw_phy_stat_false_alarm(rtwdev); + rtw_phy_stat_rate_cnt(rtwdev); +} + +#define DIG_PERF_FA_TH_LOW 250 +#define DIG_PERF_FA_TH_HIGH 500 +#define DIG_PERF_FA_TH_EXTRA_HIGH 750 +#define DIG_PERF_MAX 0x5a +#define DIG_PERF_MID 0x40 +#define DIG_CVRG_FA_TH_LOW 2000 +#define DIG_CVRG_FA_TH_HIGH 4000 +#define DIG_CVRG_FA_TH_EXTRA_HIGH 5000 +#define DIG_CVRG_MAX 0x2a +#define DIG_CVRG_MID 0x26 +#define DIG_CVRG_MIN 0x1c +#define DIG_RSSI_GAIN_OFFSET 15 + +void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev) +{ + /* Lower values result in greater coverage. */ + rtw_dbg(rtwdev, RTW_DBG_PHY, "Setting IGI=%#x for max coverage\n", + DIG_CVRG_MIN); + + rtw_phy_dig_write(rtwdev, DIG_CVRG_MIN); +} + +void rtw_phy_dig_reset(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 last_igi; + + last_igi = dm_info->igi_history[0]; + rtw_dbg(rtwdev, RTW_DBG_PHY, "Resetting IGI=%#x\n", last_igi); + + rtw_phy_dig_write(rtwdev, last_igi); +} + +static bool +rtw_phy_dig_check_damping(struct rtw_dm_info *dm_info) +{ + u16 fa_lo = DIG_PERF_FA_TH_LOW; + u16 fa_hi = DIG_PERF_FA_TH_HIGH; + u16 *fa_history; + u8 *igi_history; + u8 damping_rssi; + u8 min_rssi; + u8 diff; + u8 igi_bitmap; + bool damping = false; + + min_rssi = dm_info->min_rssi; + if (dm_info->damping) { + damping_rssi = dm_info->damping_rssi; + diff = min_rssi > damping_rssi ? min_rssi - damping_rssi : + damping_rssi - min_rssi; + if (diff > 3 || dm_info->damping_cnt++ > 20) { + dm_info->damping = false; + return false; + } + + return true; + } + + igi_history = dm_info->igi_history; + fa_history = dm_info->fa_history; + igi_bitmap = dm_info->igi_bitmap & 0xf; + switch (igi_bitmap) { + case 5: + /* down -> up -> down -> up */ + if (igi_history[0] > igi_history[1] && + igi_history[2] > igi_history[3] && + igi_history[0] - igi_history[1] >= 2 && + igi_history[2] - igi_history[3] >= 2 && + fa_history[0] > fa_hi && fa_history[1] < fa_lo && + fa_history[2] > fa_hi && fa_history[3] < fa_lo) + damping = true; + break; + case 9: + /* up -> down -> down -> up */ + if (igi_history[0] > igi_history[1] && + igi_history[3] > igi_history[2] && + igi_history[0] - igi_history[1] >= 4 && + igi_history[3] - igi_history[2] >= 2 && + fa_history[0] > fa_hi && fa_history[1] < fa_lo && + fa_history[2] < fa_lo && fa_history[3] > fa_hi) + damping = true; + break; + default: + return false; + } + + if (damping) { + dm_info->damping = true; + dm_info->damping_cnt = 0; + dm_info->damping_rssi = min_rssi; + } + + return damping; +} + +static void rtw_phy_dig_get_boundary(struct rtw_dev *rtwdev, + struct rtw_dm_info *dm_info, + u8 *upper, u8 *lower, bool linked) +{ + u8 dig_max, dig_min, dig_mid; + u8 min_rssi; + + if (linked) { + dig_max = DIG_PERF_MAX; + dig_mid = DIG_PERF_MID; + dig_min = rtwdev->chip->dig_min; + min_rssi = max_t(u8, dm_info->min_rssi, dig_min); + } else { + dig_max = DIG_CVRG_MAX; + dig_mid = DIG_CVRG_MID; + dig_min = DIG_CVRG_MIN; + min_rssi = dig_min; + } + + /* DIG MAX should be bounded by minimum RSSI with offset +15 */ + dig_max = min_t(u8, dig_max, min_rssi + DIG_RSSI_GAIN_OFFSET); + + *lower = clamp_t(u8, min_rssi, dig_min, dig_mid); + *upper = clamp_t(u8, *lower + DIG_RSSI_GAIN_OFFSET, dig_min, dig_max); +} + +static void rtw_phy_dig_get_threshold(struct rtw_dm_info *dm_info, + u16 *fa_th, u8 *step, bool linked) +{ + u8 min_rssi, pre_min_rssi; + + min_rssi = dm_info->min_rssi; + pre_min_rssi = dm_info->pre_min_rssi; + step[0] = 4; + step[1] = 3; + step[2] = 2; + + if (linked) { + fa_th[0] = DIG_PERF_FA_TH_EXTRA_HIGH; + fa_th[1] = DIG_PERF_FA_TH_HIGH; + fa_th[2] = DIG_PERF_FA_TH_LOW; + if (pre_min_rssi > min_rssi) { + step[0] = 6; + step[1] = 4; + step[2] = 2; + } + } else { + fa_th[0] = DIG_CVRG_FA_TH_EXTRA_HIGH; + fa_th[1] = DIG_CVRG_FA_TH_HIGH; + fa_th[2] = DIG_CVRG_FA_TH_LOW; + } +} + +static void rtw_phy_dig_recorder(struct rtw_dm_info *dm_info, u8 igi, u16 fa) +{ + u8 *igi_history; + u16 *fa_history; + u8 igi_bitmap; + bool up; + + igi_bitmap = dm_info->igi_bitmap << 1 & 0xfe; + igi_history = dm_info->igi_history; + fa_history = dm_info->fa_history; + + up = igi > igi_history[0]; + igi_bitmap |= up; + + igi_history[3] = igi_history[2]; + igi_history[2] = igi_history[1]; + igi_history[1] = igi_history[0]; + igi_history[0] = igi; + + fa_history[3] = fa_history[2]; + fa_history[2] = fa_history[1]; + fa_history[1] = fa_history[0]; + fa_history[0] = fa; + + dm_info->igi_bitmap = igi_bitmap; +} + +static void rtw_phy_dig(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 upper_bound, lower_bound; + u8 pre_igi, cur_igi; + u16 fa_th[3], fa_cnt; + u8 level; + u8 step[3]; + bool linked; + + if (test_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags)) + return; + + if (rtw_phy_dig_check_damping(dm_info)) + return; + + linked = !!rtwdev->sta_cnt; + + fa_cnt = dm_info->total_fa_cnt; + pre_igi = dm_info->igi_history[0]; + + rtw_phy_dig_get_threshold(dm_info, fa_th, step, linked); + + /* test the false alarm count from the highest threshold level first, + * and increase it by corresponding step size + * + * note that the step size is offset by -2, compensate it afterall + */ + cur_igi = pre_igi; + for (level = 0; level < 3; level++) { + if (fa_cnt > fa_th[level]) { + cur_igi += step[level]; + break; + } + } + cur_igi -= 2; + + /* calculate the upper/lower bound by the minimum rssi we have among + * the peers connected with us, meanwhile make sure the igi value does + * not beyond the hardware limitation + */ + rtw_phy_dig_get_boundary(rtwdev, dm_info, &upper_bound, &lower_bound, + linked); + cur_igi = clamp_t(u8, cur_igi, lower_bound, upper_bound); + + /* record current igi value and false alarm statistics for further + * damping checks, and record the trend of igi values + */ + rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt); + + /* Mitigate beacon loss and connectivity issues, mainly (only?) + * in the 5 GHz band + */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss && + linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH) + cur_igi = DIG_CVRG_MIN; + + if (cur_igi != pre_igi) + rtw_phy_dig_write(rtwdev, cur_igi); +} + +static void rtw_phy_ra_info_update_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_dev *rtwdev = data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + rtw_update_sta_info(rtwdev, si, false); +} + +static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev) +{ + if (rtwdev->watch_dog_cnt & 0x3) + return; + + rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev); +} + +static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx) +{ + u8 rate_order; + + rate_order = rate_idx; + + if (rate_idx >= DESC_RATEVHT4SS_MCS0) + rate_order -= DESC_RATEVHT4SS_MCS0; + else if (rate_idx >= DESC_RATEVHT3SS_MCS0) + rate_order -= DESC_RATEVHT3SS_MCS0; + else if (rate_idx >= DESC_RATEVHT2SS_MCS0) + rate_order -= DESC_RATEVHT2SS_MCS0; + else if (rate_idx >= DESC_RATEVHT1SS_MCS0) + rate_order -= DESC_RATEVHT1SS_MCS0; + else if (rate_idx >= DESC_RATEMCS24) + rate_order -= DESC_RATEMCS24; + else if (rate_idx >= DESC_RATEMCS16) + rate_order -= DESC_RATEMCS16; + else if (rate_idx >= DESC_RATEMCS8) + rate_order -= DESC_RATEMCS8; + else if (rate_idx >= DESC_RATEMCS0) + rate_order -= DESC_RATEMCS0; + else if (rate_idx >= DESC_RATE6M) + rate_order -= DESC_RATE6M; + else + rate_order -= DESC_RATE1M; + + if (rate_idx >= DESC_RATEMCS0 || rate_order == 0) + rate_order++; + + return GENMASK(rate_order + RRSR_RATE_ORDER_CCK_LEN - 1, 0); +} + +static void rtw_phy_rrsr_mask_min_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 mask = 0; + + mask = rtw_phy_get_rrsr_mask(rtwdev, si->ra_report.desc_rate); + if (mask < dm_info->rrsr_mask_min) + dm_info->rrsr_mask_min = mask; +} + +static void rtw_phy_rrsr_update(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX; + rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev); + rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min); +} + +static void rtw_phy_dpk_track(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (chip->ops->dpk_track) + chip->ops->dpk_track(rtwdev); +} + +struct rtw_rx_addr_match_data { + struct rtw_dev *rtwdev; + struct ieee80211_hdr *hdr; + struct rtw_rx_pkt_stat *pkt_stat; + u8 *bssid; +}; + +static void rtw_phy_parsing_cfo_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_rx_addr_match_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + u8 *bssid = iter_data->bssid; + u8 i; + + if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) + return; + + for (i = 0; i < rtwdev->hal.rf_path_num; i++) { + cfo->cfo_tail[i] += pkt_stat->cfo_tail[i]; + cfo->cfo_cnt[i]++; + } + + cfo->packet_count++; +} + +void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct ieee80211_hdr *hdr = pkt_stat->hdr; + struct rtw_rx_addr_match_data data = {}; + + if (pkt_stat->crc_err || pkt_stat->icv_err || !pkt_stat->phy_status || + ieee80211_is_ctl(hdr->frame_control)) + return; + + data.rtwdev = rtwdev; + data.hdr = hdr; + data.pkt_stat = pkt_stat; + data.bssid = get_hdr_bssid(hdr); + + rtw_iterate_vifs_atomic(rtwdev, rtw_phy_parsing_cfo_iter, &data); +} +EXPORT_SYMBOL(rtw_phy_parsing_cfo); + +static void rtw_phy_cfo_track(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (chip->ops->cfo_track) + chip->ops->cfo_track(rtwdev); +} + +#define CCK_PD_FA_LV1_MIN 1000 +#define CCK_PD_FA_LV0_MAX 500 + +static u8 rtw_phy_cck_pd_lv_unlink(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_avg = dm_info->cck_fa_avg; + + if (cck_fa_avg > CCK_PD_FA_LV1_MIN) + return CCK_PD_LV1; + + if (cck_fa_avg < CCK_PD_FA_LV0_MAX) + return CCK_PD_LV0; + + return CCK_PD_LV_MAX; +} + +#define CCK_PD_IGI_LV4_VAL 0x38 +#define CCK_PD_IGI_LV3_VAL 0x2a +#define CCK_PD_IGI_LV2_VAL 0x24 +#define CCK_PD_RSSI_LV4_VAL 32 +#define CCK_PD_RSSI_LV3_VAL 32 +#define CCK_PD_RSSI_LV2_VAL 24 + +static u8 rtw_phy_cck_pd_lv_link(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 igi = dm_info->igi_history[0]; + u8 rssi = dm_info->min_rssi; + u32 cck_fa_avg = dm_info->cck_fa_avg; + + if (igi > CCK_PD_IGI_LV4_VAL && rssi > CCK_PD_RSSI_LV4_VAL) + return CCK_PD_LV4; + if (igi > CCK_PD_IGI_LV3_VAL && rssi > CCK_PD_RSSI_LV3_VAL) + return CCK_PD_LV3; + if (igi > CCK_PD_IGI_LV2_VAL || rssi > CCK_PD_RSSI_LV2_VAL) + return CCK_PD_LV2; + if (cck_fa_avg > CCK_PD_FA_LV1_MIN) + return CCK_PD_LV1; + if (cck_fa_avg < CCK_PD_FA_LV0_MAX) + return CCK_PD_LV0; + + return CCK_PD_LV_MAX; +} + +static u8 rtw_phy_cck_pd_lv(struct rtw_dev *rtwdev) +{ + if (!rtw_is_assoc(rtwdev)) + return rtw_phy_cck_pd_lv_unlink(rtwdev); + else + return rtw_phy_cck_pd_lv_link(rtwdev); +} + +static void rtw_phy_cck_pd(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa = dm_info->cck_fa_cnt; + u8 level; + + if (rtwdev->hal.current_band_type != RTW_BAND_2G) + return; + + if (dm_info->cck_fa_avg == CCK_FA_AVG_RESET) + dm_info->cck_fa_avg = cck_fa; + else + dm_info->cck_fa_avg = (dm_info->cck_fa_avg * 3 + cck_fa) >> 2; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "IGI=0x%x, rssi_min=%d, cck_fa=%d\n", + dm_info->igi_history[0], dm_info->min_rssi, + dm_info->fa_history[0]); + rtw_dbg(rtwdev, RTW_DBG_PHY, "cck_fa_avg=%d, cck_pd_default=%d\n", + dm_info->cck_fa_avg, dm_info->cck_pd_default); + + level = rtw_phy_cck_pd_lv(rtwdev); + + if (level >= CCK_PD_LV_MAX) + return; + + if (chip->ops->cck_pd_set) + chip->ops->cck_pd_set(rtwdev, level); +} + +static void rtw_phy_pwr_track(struct rtw_dev *rtwdev) +{ + rtwdev->chip->ops->pwr_track(rtwdev); +} + +static void rtw_phy_ra_track(struct rtw_dev *rtwdev) +{ + rtw_fw_update_wl_phy_info(rtwdev); + rtw_phy_ra_info_update(rtwdev); + rtw_phy_rrsr_update(rtwdev); +} + +void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev) +{ + /* for further calculation */ + rtw_phy_statistics(rtwdev); + rtw_phy_dig(rtwdev); + rtw_phy_cck_pd(rtwdev); + rtw_phy_ra_track(rtwdev); + rtw_phy_tx_path_diversity(rtwdev); + rtw_phy_cfo_track(rtwdev); + rtw_phy_dpk_track(rtwdev); + rtw_phy_pwr_track(rtwdev); + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_ADAPTIVITY)) + rtw_fw_adaptivity(rtwdev); + else + rtw_phy_adaptivity(rtwdev); +} + +#define FRAC_BITS 3 + +static u8 rtw_phy_power_2_db(s8 power) +{ + if (power <= -100 || power >= 20) + return 0; + else if (power >= 0) + return 100; + else + return 100 + power; +} + +static u64 rtw_phy_db_2_linear(u8 power_db) +{ + u8 i, j; + u64 linear; + + if (power_db > 96) + power_db = 96; + else if (power_db < 1) + return 1; + + /* 1dB ~ 96dB */ + i = (power_db - 1) >> 3; + j = (power_db - 1) - (i << 3); + + linear = db_invert_table[i][j]; + linear = i > 2 ? linear << FRAC_BITS : linear; + + return linear; +} + +static u8 rtw_phy_linear_2_db(u64 linear) +{ + u8 i; + u8 j; + u32 dB; + + for (i = 0; i < 12; i++) { + for (j = 0; j < 8; j++) { + if (i <= 2 && (linear << FRAC_BITS) <= db_invert_table[i][j]) + goto cnt; + else if (i > 2 && linear <= db_invert_table[i][j]) + goto cnt; + } + } + + return 96; /* maximum 96 dB */ + +cnt: + if (j == 0 && i == 0) + goto end; + + if (j == 0) { + if (i != 3) { + if (db_invert_table[i][0] - linear > + linear - db_invert_table[i - 1][7]) { + i = i - 1; + j = 7; + } + } else { + if (db_invert_table[3][0] - linear > + linear - db_invert_table[2][7]) { + i = 2; + j = 7; + } + } + } else { + if (db_invert_table[i][j] - linear > + linear - db_invert_table[i][j - 1]) { + j = j - 1; + } + } +end: + dB = (i << 3) + j + 1; + + return dB; +} + +u8 rtw_phy_rf_power_2_rssi(s8 *rf_power, u8 path_num) +{ + s8 power; + u8 power_db; + u64 linear; + u64 sum = 0; + u8 path; + + for (path = 0; path < path_num; path++) { + power = rf_power[path]; + power_db = rtw_phy_power_2_db(power); + linear = rtw_phy_db_2_linear(power_db); + sum += linear; + } + + sum = (sum + (1 << (FRAC_BITS - 1))) >> FRAC_BITS; + switch (path_num) { + case 2: + sum >>= 1; + break; + case 3: + sum = ((sum) + ((sum) << 1) + ((sum) << 3)) >> 5; + break; + case 4: + sum >>= 2; + break; + default: + break; + } + + return rtw_phy_linear_2_db(sum); +} +EXPORT_SYMBOL(rtw_phy_rf_power_2_rssi); + +u32 rtw_phy_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_chip_info *chip = rtwdev->chip; + const u32 *base_addr = chip->rf_base_addr; + u32 val, direct_addr; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + addr &= 0xff; + direct_addr = base_addr[rf_path] + (addr << 2); + mask &= RFREG_MASK; + + val = rtw_read32_mask(rtwdev, direct_addr, mask); + + return val; +} +EXPORT_SYMBOL(rtw_phy_read_rf); + +u32 rtw_phy_read_rf_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_rf_sipi_addr *rf_sipi_addr; + const struct rtw_rf_sipi_addr *rf_sipi_addr_a; + u32 val32; + u32 en_pi; + u32 r_addr; + u32 shift; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (!chip->rf_sipi_read_addr) { + rtw_err(rtwdev, "rf_sipi_read_addr isn't defined\n"); + return INV_RF_DATA; + } + + rf_sipi_addr = &chip->rf_sipi_read_addr[rf_path]; + rf_sipi_addr_a = &chip->rf_sipi_read_addr[RF_PATH_A]; + + addr &= 0xff; + + val32 = rtw_read32(rtwdev, rf_sipi_addr->hssi_2); + val32 = (val32 & ~LSSI_READ_ADDR_MASK) | (addr << 23); + rtw_write32(rtwdev, rf_sipi_addr->hssi_2, val32); + + /* toggle read edge of path A */ + val32 = rtw_read32(rtwdev, rf_sipi_addr_a->hssi_2); + rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 & ~LSSI_READ_EDGE_MASK); + rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 | LSSI_READ_EDGE_MASK); + + udelay(120); + + en_pi = rtw_read32_mask(rtwdev, rf_sipi_addr->hssi_1, BIT(8)); + r_addr = en_pi ? rf_sipi_addr->lssi_read_pi : rf_sipi_addr->lssi_read; + + val32 = rtw_read32_mask(rtwdev, r_addr, LSSI_READ_DATA_MASK); + + shift = __ffs(mask); + + return (val32 & mask) >> shift; +} +EXPORT_SYMBOL(rtw_phy_read_rf_sipi); + +bool rtw_phy_write_rf_reg_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_chip_info *chip = rtwdev->chip; + const u32 *sipi_addr = chip->rf_sipi_addr; + u32 data_and_addr; + u32 old_data = 0; + u32 shift; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return false; + } + + addr &= 0xff; + mask &= RFREG_MASK; + + if (mask != RFREG_MASK) { + old_data = chip->ops->read_rf(rtwdev, rf_path, addr, RFREG_MASK); + + if (old_data == INV_RF_DATA) { + rtw_err(rtwdev, "Write fail, rf is disabled\n"); + return false; + } + + shift = __ffs(mask); + data = ((old_data) & (~mask)) | (data << shift); + } + + data_and_addr = ((addr << 20) | (data & 0x000fffff)) & 0x0fffffff; + + rtw_write32(rtwdev, sipi_addr[rf_path], data_and_addr); + + udelay(13); + + return true; +} +EXPORT_SYMBOL(rtw_phy_write_rf_reg_sipi); + +bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_chip_info *chip = rtwdev->chip; + const u32 *base_addr = chip->rf_base_addr; + u32 direct_addr; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return false; + } + + addr &= 0xff; + direct_addr = base_addr[rf_path] + (addr << 2); + mask &= RFREG_MASK; + + rtw_write32_mask(rtwdev, direct_addr, mask, data); + + udelay(1); + + return true; +} + +bool rtw_phy_write_rf_reg_mix(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + if (addr != 0x00) + return rtw_phy_write_rf_reg(rtwdev, rf_path, addr, mask, data); + + return rtw_phy_write_rf_reg_sipi(rtwdev, rf_path, addr, mask, data); +} +EXPORT_SYMBOL(rtw_phy_write_rf_reg_mix); + +void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_phy_cond cond = {}; + struct rtw_phy_cond2 cond2 = {}; + + cond.cut = hal->cut_version ? hal->cut_version : 15; + cond.pkg = pkg ? pkg : 15; + cond.plat = 0x04; + cond.rfe = efuse->rfe_option; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_USB: + cond.intf = INTF_USB; + break; + case RTW_HCI_TYPE_SDIO: + cond.intf = INTF_SDIO; + break; + case RTW_HCI_TYPE_PCIE: + default: + cond.intf = INTF_PCIE; + break; + } + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || + rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { + cond.rfe = 0; + cond.rfe |= efuse->ext_lna_2g; + cond.rfe |= efuse->ext_pa_2g << 1; + cond.rfe |= efuse->ext_lna_5g << 2; + cond.rfe |= efuse->ext_pa_5g << 3; + cond.rfe |= efuse->btcoex << 4; + + cond2.type_alna = efuse->alna_type; + cond2.type_glna = efuse->glna_type; + cond2.type_apa = efuse->apa_type; + cond2.type_gpa = efuse->gpa_type; + } + + hal->phy_cond = cond; + hal->phy_cond2 = cond2; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n", + *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2)); +} + +static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, + struct rtw_phy_cond2 cond2) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_phy_cond drv_cond = hal->phy_cond; + struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2; + + if (cond.cut && cond.cut != drv_cond.cut) + return false; + + if (cond.pkg && cond.pkg != drv_cond.pkg) + return false; + + if (cond.intf && cond.intf != drv_cond.intf) + return false; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || + rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { + if (!(cond.rfe & 0x0f)) + return true; + + if ((cond.rfe & drv_cond.rfe) != cond.rfe) + return false; + + if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) + return false; + + if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) + return false; + + if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna) + return false; + + if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa) + return false; + } else { + if (cond.rfe != drv_cond.rfe) + return false; + } + + return true; +} + +void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl) +{ + const union phy_table_tile *p = tbl->data; + const union phy_table_tile *end = p + tbl->size / 2; + struct rtw_phy_cond pos_cond = {}; + struct rtw_phy_cond2 pos_cond2 = {}; + bool is_matched = true, is_skipped = false; + + BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair)); + + for (; p < end; p++) { + if (p->cond.pos) { + switch (p->cond.branch) { + case BRANCH_ENDIF: + is_matched = true; + is_skipped = false; + break; + case BRANCH_ELSE: + is_matched = is_skipped ? false : true; + break; + case BRANCH_IF: + case BRANCH_ELIF: + default: + pos_cond = p->cond; + pos_cond2 = p->cond2; + break; + } + } else if (p->cond.neg) { + if (!is_skipped) { + if (check_positive(rtwdev, pos_cond, pos_cond2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else { + is_matched = false; + } + } else if (is_matched) { + (*tbl->do_cfg)(rtwdev, tbl, p->cfg.addr, p->cfg.data); + } + } +} +EXPORT_SYMBOL(rtw_parse_tbl_phy_cond); + +#define bcd_to_dec_pwr_by_rate(val, i) bcd2bin(val >> (i * 8)) + +static u8 tbl_to_dec_pwr_by_rate(struct rtw_dev *rtwdev, u32 hex, u8 i) +{ + if (rtwdev->chip->is_pwr_by_rate_dec) + return bcd_to_dec_pwr_by_rate(hex, i); + + return (hex >> (i * 8)) & 0xFF; +} + +static void +rtw_phy_get_rate_values_of_txpwr_by_rate(struct rtw_dev *rtwdev, + u32 addr, u32 mask, u32 val, u8 *rate, + u8 *pwr_by_rate, u8 *rate_num) +{ + int i; + + switch (addr) { + case 0xE00: + case 0x830: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE04: + case 0x834: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE08: + rate[0] = DESC_RATE1M; + pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 1); + *rate_num = 1; + break; + case 0x86C: + if (mask == 0xffffff00) { + rate[0] = DESC_RATE2M; + rate[1] = DESC_RATE5_5M; + rate[2] = DESC_RATE11M; + for (i = 1; i < 4; ++i) + pwr_by_rate[i - 1] = + tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 3; + } else if (mask == 0x000000ff) { + rate[0] = DESC_RATE11M; + pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 0); + *rate_num = 1; + } + break; + case 0xE10: + case 0x83C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE14: + case 0x848: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE18: + case 0x84C: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE1C: + case 0x868: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0x838: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + for (i = 1; i < 4; ++i) + pwr_by_rate[i - 1] = tbl_to_dec_pwr_by_rate(rtwdev, + val, i); + *rate_num = 3; + break; + case 0xC20: + case 0xE20: + case 0x1820: + case 0x1A20: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + rate[3] = DESC_RATE11M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC24: + case 0xE24: + case 0x1824: + case 0x1A24: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC28: + case 0xE28: + case 0x1828: + case 0x1A28: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC2C: + case 0xE2C: + case 0x182C: + case 0x1A2C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC30: + case 0xE30: + case 0x1830: + case 0x1A30: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC34: + case 0xE34: + case 0x1834: + case 0x1A34: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC38: + case 0xE38: + case 0x1838: + case 0x1A38: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC3C: + case 0xE3C: + case 0x183C: + case 0x1A3C: + rate[0] = DESC_RATEVHT1SS_MCS0; + rate[1] = DESC_RATEVHT1SS_MCS1; + rate[2] = DESC_RATEVHT1SS_MCS2; + rate[3] = DESC_RATEVHT1SS_MCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC40: + case 0xE40: + case 0x1840: + case 0x1A40: + rate[0] = DESC_RATEVHT1SS_MCS4; + rate[1] = DESC_RATEVHT1SS_MCS5; + rate[2] = DESC_RATEVHT1SS_MCS6; + rate[3] = DESC_RATEVHT1SS_MCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC44: + case 0xE44: + case 0x1844: + case 0x1A44: + rate[0] = DESC_RATEVHT1SS_MCS8; + rate[1] = DESC_RATEVHT1SS_MCS9; + rate[2] = DESC_RATEVHT2SS_MCS0; + rate[3] = DESC_RATEVHT2SS_MCS1; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC48: + case 0xE48: + case 0x1848: + case 0x1A48: + rate[0] = DESC_RATEVHT2SS_MCS2; + rate[1] = DESC_RATEVHT2SS_MCS3; + rate[2] = DESC_RATEVHT2SS_MCS4; + rate[3] = DESC_RATEVHT2SS_MCS5; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC4C: + case 0xE4C: + case 0x184C: + case 0x1A4C: + rate[0] = DESC_RATEVHT2SS_MCS6; + rate[1] = DESC_RATEVHT2SS_MCS7; + rate[2] = DESC_RATEVHT2SS_MCS8; + rate[3] = DESC_RATEVHT2SS_MCS9; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCD8: + case 0xED8: + case 0x18D8: + case 0x1AD8: + rate[0] = DESC_RATEMCS16; + rate[1] = DESC_RATEMCS17; + rate[2] = DESC_RATEMCS18; + rate[3] = DESC_RATEMCS19; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCDC: + case 0xEDC: + case 0x18DC: + case 0x1ADC: + rate[0] = DESC_RATEMCS20; + rate[1] = DESC_RATEMCS21; + rate[2] = DESC_RATEMCS22; + rate[3] = DESC_RATEMCS23; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE0: + case 0xEE0: + case 0x18E0: + case 0x1AE0: + rate[0] = DESC_RATEVHT3SS_MCS0; + rate[1] = DESC_RATEVHT3SS_MCS1; + rate[2] = DESC_RATEVHT3SS_MCS2; + rate[3] = DESC_RATEVHT3SS_MCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE4: + case 0xEE4: + case 0x18E4: + case 0x1AE4: + rate[0] = DESC_RATEVHT3SS_MCS4; + rate[1] = DESC_RATEVHT3SS_MCS5; + rate[2] = DESC_RATEVHT3SS_MCS6; + rate[3] = DESC_RATEVHT3SS_MCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE8: + case 0xEE8: + case 0x18E8: + case 0x1AE8: + rate[0] = DESC_RATEVHT3SS_MCS8; + rate[1] = DESC_RATEVHT3SS_MCS9; + for (i = 0; i < 2; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 2; + break; + default: + rtw_warn(rtwdev, "invalid tx power index addr 0x%08x\n", addr); + break; + } +} + +static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev, + u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 rate_num = 0; + u8 rate; + u8 rates[RTW_RF_PATH_MAX] = {0}; + s8 offset; + s8 pwr_by_rate[RTW_RF_PATH_MAX] = {0}; + int i; + + rtw_phy_get_rate_values_of_txpwr_by_rate(rtwdev, regaddr, bitmask, data, + rates, pwr_by_rate, &rate_num); + + if (WARN_ON(rfpath >= RTW_RF_PATH_MAX || + (band != PHY_BAND_2G && band != PHY_BAND_5G) || + rate_num > RTW_RF_PATH_MAX)) + return; + + for (i = 0; i < rate_num; i++) { + offset = pwr_by_rate[i]; + rate = rates[i]; + if (band == PHY_BAND_2G) + hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; + else + hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + } +} + +void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl) +{ + const struct rtw_phy_pg_cfg_pair *p = tbl->data; + const struct rtw_phy_pg_cfg_pair *end = p + tbl->size; + + for (; p < end; p++) { + if (p->addr == 0xfe || p->addr == 0xffe) { + msleep(50); + continue; + } + rtw_phy_store_tx_power_by_rate(rtwdev, p->band, p->rf_path, + p->tx_num, p->addr, p->bitmask, + p->data); + } +} +EXPORT_SYMBOL(rtw_parse_tbl_bb_pg); + +static const u8 rtw_channel_idx_5g[RTW_MAX_CHANNEL_NUM_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + +static int rtw_channel_to_idx(u8 band, u8 channel) +{ + int ch_idx; + u8 n_channel; + + if (band == PHY_BAND_2G) { + ch_idx = channel - 1; + n_channel = RTW_MAX_CHANNEL_NUM_2G; + } else if (band == PHY_BAND_5G) { + n_channel = RTW_MAX_CHANNEL_NUM_5G; + for (ch_idx = 0; ch_idx < n_channel; ch_idx++) + if (rtw_channel_idx_5g[ch_idx] == channel) + break; + } else { + return -1; + } + + if (ch_idx >= n_channel) + return -1; + + return ch_idx; +} + +static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, + u8 bw, u8 rs, u8 ch, s8 pwr_limit) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 max_power_index = rtwdev->chip->max_power_index; + s8 ww; + int ch_idx; + + pwr_limit = clamp_t(s8, pwr_limit, + -max_power_index, max_power_index); + ch_idx = rtw_channel_to_idx(band, ch); + + if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX || + rs >= RTW_RATE_SECTION_NUM || ch_idx < 0) { + WARN(1, + "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n", + regd, band, bw, rs, ch_idx, pwr_limit); + return; + } + + if (band == PHY_BAND_2G) { + hal->tx_pwr_limit_2g[regd][bw][rs][ch_idx] = pwr_limit; + ww = hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx]; + ww = min_t(s8, ww, pwr_limit); + hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx] = ww; + } else if (band == PHY_BAND_5G) { + hal->tx_pwr_limit_5g[regd][bw][rs][ch_idx] = pwr_limit; + ww = hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx]; + ww = min_t(s8, ww, pwr_limit); + hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx] = ww; + } +} + +/* cross-reference 5G power limits if values are not assigned */ +static void +rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd, + u8 bw, u8 ch_idx, u8 rs_ht, u8 rs_vht) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 max_power_index = rtwdev->chip->max_power_index; + s8 lmt_ht = hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx]; + s8 lmt_vht = hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx]; + + if (lmt_ht == lmt_vht) + return; + + if (lmt_ht == max_power_index) + hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx] = lmt_vht; + + else if (lmt_vht == max_power_index) + hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx] = lmt_ht; +} + +/* cross-reference power limits for ht and vht */ +static void +rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx) +{ + static const u8 rs_cmp[4][2] = { + {RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, + {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S}, + {RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S}, + {RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S} + }; + u8 rs_idx, rs_ht, rs_vht; + + for (rs_idx = 0; rs_idx < 4; rs_idx++) { + rs_ht = rs_cmp[rs_idx][0]; + rs_vht = rs_cmp[rs_idx][1]; + + rtw_xref_5g_txpwr_lmt(rtwdev, regd, bw, ch_idx, rs_ht, rs_vht); + } +} + +/* cross-reference power limits for 5G channels */ +static void +rtw_xref_5g_txpwr_lmt_by_ch(struct rtw_dev *rtwdev, u8 regd, u8 bw) +{ + u8 ch_idx; + + for (ch_idx = 0; ch_idx < RTW_MAX_CHANNEL_NUM_5G; ch_idx++) + rtw_xref_txpwr_lmt_by_rs(rtwdev, regd, bw, ch_idx); +} + +/* cross-reference power limits for 20/40M bandwidth */ +static void +rtw_xref_txpwr_lmt_by_bw(struct rtw_dev *rtwdev, u8 regd) +{ + u8 bw; + + for (bw = RTW_CHANNEL_WIDTH_20; bw <= RTW_CHANNEL_WIDTH_40; bw++) + rtw_xref_5g_txpwr_lmt_by_ch(rtwdev, regd, bw); +} + +/* cross-reference power limits */ +static void rtw_xref_txpwr_lmt(struct rtw_dev *rtwdev) +{ + u8 regd; + + for (regd = 0; regd < RTW_REGD_MAX; regd++) + rtw_xref_txpwr_lmt_by_bw(rtwdev, regd); +} + +static void +__cfg_txpwr_lmt_by_alt(struct rtw_hal *hal, u8 regd, u8 regd_alt, u8 bw, u8 rs) +{ + u8 ch; + + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) + hal->tx_pwr_limit_2g[regd][bw][rs][ch] = + hal->tx_pwr_limit_2g[regd_alt][bw][rs][ch]; + + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++) + hal->tx_pwr_limit_5g[regd][bw][rs][ch] = + hal->tx_pwr_limit_5g[regd_alt][bw][rs][ch]; +} + +static void +rtw_cfg_txpwr_lmt_by_alt(struct rtw_dev *rtwdev, u8 regd, u8 regd_alt) +{ + u8 bw, rs; + + for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) + __cfg_txpwr_lmt_by_alt(&rtwdev->hal, regd, regd_alt, + bw, rs); +} + +void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev, + const struct rtw_table *tbl) +{ + const struct rtw_txpwr_lmt_cfg_pair *p = tbl->data; + const struct rtw_txpwr_lmt_cfg_pair *end = p + tbl->size; + u32 regd_cfg_flag = 0; + u8 regd_alt; + u8 i; + + for (; p < end; p++) { + regd_cfg_flag |= BIT(p->regd); + rtw_phy_set_tx_power_limit(rtwdev, p->regd, p->band, + p->bw, p->rs, p->ch, p->txpwr_lmt); + } + + for (i = 0; i < RTW_REGD_MAX; i++) { + if (i == RTW_REGD_WW) + continue; + + if (regd_cfg_flag & BIT(i)) + continue; + + rtw_dbg(rtwdev, RTW_DBG_REGD, + "txpwr regd %d does not be configured\n", i); + + if (rtw_regd_has_alt(i, ®d_alt) && + regd_cfg_flag & BIT(regd_alt)) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "cfg txpwr regd %d by regd %d as alternative\n", + i, regd_alt); + + rtw_cfg_txpwr_lmt_by_alt(rtwdev, i, regd_alt); + continue; + } + + rtw_dbg(rtwdev, RTW_DBG_REGD, "cfg txpwr regd %d by WW\n", i); + rtw_cfg_txpwr_lmt_by_alt(rtwdev, i, RTW_REGD_WW); + } + + rtw_xref_txpwr_lmt(rtwdev); +} +EXPORT_SYMBOL(rtw_parse_tbl_txpwr_lmt); + +void rtw_phy_cfg_mac(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data) +{ + rtw_write8(rtwdev, addr, data); +} +EXPORT_SYMBOL(rtw_phy_cfg_mac); + +void rtw_phy_cfg_agc(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data) +{ + rtw_write32(rtwdev, addr, data); +} +EXPORT_SYMBOL(rtw_phy_cfg_agc); + +void rtw_phy_cfg_bb(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data) +{ + if (addr == 0xfe) + msleep(50); + else if (addr == 0xfd) + mdelay(5); + else if (addr == 0xfc) + mdelay(1); + else if (addr == 0xfb) + usleep_range(50, 60); + else if (addr == 0xfa) + udelay(5); + else if (addr == 0xf9) + udelay(1); + else + rtw_write32(rtwdev, addr, data); +} +EXPORT_SYMBOL(rtw_phy_cfg_bb); + +void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data) +{ + if (addr == 0xffe) { + msleep(50); + } else if (addr == 0xfe) { + usleep_range(100, 110); + } else { + rtw_write_rf(rtwdev, tbl->rf_path, addr, RFREG_MASK, data); + udelay(1); + } +} +EXPORT_SYMBOL(rtw_phy_cfg_rf); + +static void rtw_load_rfk_table(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + + if (!chip->rfk_init_tbl) + return; + + rtw_write32_mask(rtwdev, 0x1e24, BIT(17), 0x1); + rtw_write32_mask(rtwdev, 0x1cd0, BIT(28), 0x1); + rtw_write32_mask(rtwdev, 0x1cd0, BIT(29), 0x1); + rtw_write32_mask(rtwdev, 0x1cd0, BIT(30), 0x1); + rtw_write32_mask(rtwdev, 0x1cd0, BIT(31), 0x0); + + rtw_load_table(rtwdev, chip->rfk_init_tbl); + + dpk_info->is_dpk_pwr_on = true; +} + +void rtw_phy_load_tables(struct rtw_dev *rtwdev) +{ + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); + const struct rtw_chip_info *chip = rtwdev->chip; + u8 rf_path; + + rtw_load_table(rtwdev, chip->mac_tbl); + rtw_load_table(rtwdev, chip->bb_tbl); + rtw_load_table(rtwdev, chip->agc_tbl); + if (rfe_def->agc_btg_tbl) + rtw_load_table(rtwdev, rfe_def->agc_btg_tbl); + rtw_load_rfk_table(rtwdev); + + for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) { + const struct rtw_table *tbl; + + tbl = chip->rf_tbl[rf_path]; + rtw_load_table(rtwdev, tbl); + } +} +EXPORT_SYMBOL(rtw_phy_load_tables); + +static u8 rtw_get_channel_group(u8 channel, u8 rate) +{ + switch (channel) { + default: + WARN_ON(1); + fallthrough; + case 1: + case 2: + case 36: + case 38: + case 40: + case 42: + return 0; + case 3: + case 4: + case 5: + case 44: + case 46: + case 48: + case 50: + return 1; + case 6: + case 7: + case 8: + case 52: + case 54: + case 56: + case 58: + return 2; + case 9: + case 10: + case 11: + case 60: + case 62: + case 64: + return 3; + case 12: + case 13: + case 100: + case 102: + case 104: + case 106: + return 4; + case 14: + return rate <= DESC_RATE11M ? 5 : 4; + case 108: + case 110: + case 112: + case 114: + return 5; + case 116: + case 118: + case 120: + case 122: + return 6; + case 124: + case 126: + case 128: + case 130: + return 7; + case 132: + case 134: + case 136: + case 138: + return 8; + case 140: + case 142: + case 144: + return 9; + case 149: + case 151: + case 153: + case 155: + return 10; + case 157: + case 159: + case 161: + return 11; + case 165: + case 167: + case 169: + case 171: + return 12; + case 173: + case 175: + case 177: + return 13; + } +} + +static s8 rtw_phy_get_dis_dpd_by_rate_diff(struct rtw_dev *rtwdev, u16 rate) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + s8 dpd_diff = 0; + + if (!chip->en_dis_dpd) + return 0; + +#define RTW_DPD_RATE_CHECK(_rate) \ + case DESC_RATE ## _rate: \ + if (DIS_DPD_RATE ## _rate & chip->dpd_ratemask) \ + dpd_diff = -6 * chip->txgi_factor; \ + break + + switch (rate) { + RTW_DPD_RATE_CHECK(6M); + RTW_DPD_RATE_CHECK(9M); + RTW_DPD_RATE_CHECK(MCS0); + RTW_DPD_RATE_CHECK(MCS1); + RTW_DPD_RATE_CHECK(MCS8); + RTW_DPD_RATE_CHECK(MCS9); + RTW_DPD_RATE_CHECK(VHT1SS_MCS0); + RTW_DPD_RATE_CHECK(VHT1SS_MCS1); + RTW_DPD_RATE_CHECK(VHT2SS_MCS0); + RTW_DPD_RATE_CHECK(VHT2SS_MCS1); + } +#undef RTW_DPD_RATE_CHECK + + return dpd_diff; +} + +static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, + struct rtw_2g_txpwr_idx *pwr_idx_2g, + enum rtw_bandwidth bandwidth, + u8 rate, u8 group) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + bool above_2ss, above_3ss, above_4ss; + u8 factor = chip->txgi_factor; + bool mcs_rate; + u8 tx_power; + + if (rate <= DESC_RATE11M) + tx_power = pwr_idx_2g->cck_base[group]; + else + tx_power = pwr_idx_2g->bw40_base[group]; + + if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) + tx_power += pwr_idx_2g->ht_1s_diff.ofdm * factor; + + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); + + if (!mcs_rate) + return tx_power; + + switch (bandwidth) { + default: + WARN_ON(1); + fallthrough; + case RTW_CHANNEL_WIDTH_20: + tx_power += pwr_idx_2g->ht_1s_diff.bw20 * factor; + if (above_2ss) + tx_power += pwr_idx_2g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw20 * factor; + break; + case RTW_CHANNEL_WIDTH_40: + /* bw40 is the base power */ + if (above_2ss) + tx_power += pwr_idx_2g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw40 * factor; + break; + } + + return tx_power; +} + +static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, + struct rtw_5g_txpwr_idx *pwr_idx_5g, + enum rtw_bandwidth bandwidth, + u8 rate, u8 group) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + bool above_2ss, above_3ss, above_4ss; + u8 factor = chip->txgi_factor; + u8 upper, lower; + bool mcs_rate; + u8 tx_power; + + tx_power = pwr_idx_5g->bw40_base[group]; + + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); + + if (!mcs_rate) { + tx_power += pwr_idx_5g->ht_1s_diff.ofdm * factor; + return tx_power; + } + + switch (bandwidth) { + default: + WARN_ON(1); + fallthrough; + case RTW_CHANNEL_WIDTH_20: + tx_power += pwr_idx_5g->ht_1s_diff.bw20 * factor; + if (above_2ss) + tx_power += pwr_idx_5g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw20 * factor; + break; + case RTW_CHANNEL_WIDTH_40: + /* bw40 is the base power */ + if (above_2ss) + tx_power += pwr_idx_5g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw40 * factor; + break; + case RTW_CHANNEL_WIDTH_80: + /* the base idx of bw80 is the average of bw40+/bw40- */ + lower = pwr_idx_5g->bw40_base[group]; + upper = pwr_idx_5g->bw40_base[group + 1]; + + tx_power = (lower + upper) / 2; + tx_power += pwr_idx_5g->vht_1s_diff.bw80 * factor; + if (above_2ss) + tx_power += pwr_idx_5g->vht_2s_diff.bw80 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->vht_3s_diff.bw80 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->vht_4s_diff.bw80 * factor; + break; + } + + return tx_power; +} + +/* return RTW_RATE_SECTION_NUM to indicate rate is invalid */ +static u8 rtw_phy_rate_to_rate_section(u8 rate) +{ + if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) + return RTW_RATE_SECTION_CCK; + else if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) + return RTW_RATE_SECTION_OFDM; + else if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS7) + return RTW_RATE_SECTION_HT_1S; + else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) + return RTW_RATE_SECTION_HT_2S; + else if (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS23) + return RTW_RATE_SECTION_HT_3S; + else if (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) + return RTW_RATE_SECTION_HT_4S; + else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9) + return RTW_RATE_SECTION_VHT_1S; + else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9) + return RTW_RATE_SECTION_VHT_2S; + else if (rate >= DESC_RATEVHT3SS_MCS0 && rate <= DESC_RATEVHT3SS_MCS9) + return RTW_RATE_SECTION_VHT_3S; + else if (rate >= DESC_RATEVHT4SS_MCS0 && rate <= DESC_RATEVHT4SS_MCS9) + return RTW_RATE_SECTION_VHT_4S; + else + return RTW_RATE_SECTION_NUM; +} + +static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, + enum rtw_bandwidth bw, u8 rf_path, + u8 rate, u8 channel, u8 regd) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 *cch_by_bw = hal->cch_by_bw; + s8 power_limit = (s8)rtwdev->chip->max_power_index; + u8 rs = rtw_phy_rate_to_rate_section(rate); + int ch_idx; + u8 cur_bw, cur_ch; + s8 cur_lmt; + + if (regd > RTW_REGD_WW) + return power_limit; + + if (rs == RTW_RATE_SECTION_NUM) + goto err; + + /* only 20M BW with cck and ofdm */ + if (rs == RTW_RATE_SECTION_CCK || rs == RTW_RATE_SECTION_OFDM) + bw = RTW_CHANNEL_WIDTH_20; + + /* only 20/40M BW with ht */ + if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) + bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40); + + /* select min power limit among [20M BW ~ current BW] */ + for (cur_bw = RTW_CHANNEL_WIDTH_20; cur_bw <= bw; cur_bw++) { + cur_ch = cch_by_bw[cur_bw]; + + ch_idx = rtw_channel_to_idx(band, cur_ch); + if (ch_idx < 0) + goto err; + + cur_lmt = cur_ch <= RTW_MAX_CHANNEL_NUM_2G ? + hal->tx_pwr_limit_2g[regd][cur_bw][rs][ch_idx] : + hal->tx_pwr_limit_5g[regd][cur_bw][rs][ch_idx]; + + power_limit = min_t(s8, cur_lmt, power_limit); + } + + return power_limit; + +err: + WARN(1, "invalid arguments, band=%d, bw=%d, path=%d, rate=%d, ch=%d\n", + band, bw, rf_path, rate, channel); + return (s8)rtwdev->chip->max_power_index; +} + +static s8 rtw_phy_get_tx_power_sar(struct rtw_dev *rtwdev, u8 sar_band, + u8 rf_path, u8 rate) +{ + u8 rs = rtw_phy_rate_to_rate_section(rate); + struct rtw_sar_arg arg = { + .sar_band = sar_band, + .path = rf_path, + .rs = rs, + }; + + if (rs == RTW_RATE_SECTION_NUM) + goto err; + + return rtw_query_sar(rtwdev, &arg); + +err: + WARN(1, "invalid arguments, sar_band=%d, path=%d, rate=%d\n", + sar_band, rf_path, rate); + return (s8)rtwdev->chip->max_power_index; +} + +void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, + u8 ch, u8 regd, struct rtw_power_params *pwr_param) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_txpwr_idx *pwr_idx; + u8 group, band; + u8 *base = &pwr_param->pwr_base; + s8 *offset = &pwr_param->pwr_offset; + s8 *limit = &pwr_param->pwr_limit; + s8 *remnant = &pwr_param->pwr_remnant; + s8 *sar = &pwr_param->pwr_sar; + + pwr_idx = &rtwdev->efuse.txpwr_idx_table[path]; + group = rtw_get_channel_group(ch, rate); + + /* base power index for 2.4G/5G */ + if (IS_CH_2G_BAND(ch)) { + band = PHY_BAND_2G; + *base = rtw_phy_get_2g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_2g, + bw, rate, group); + *offset = hal->tx_pwr_by_rate_offset_2g[path][rate]; + } else { + band = PHY_BAND_5G; + *base = rtw_phy_get_5g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_5g, + bw, rate, group); + *offset = hal->tx_pwr_by_rate_offset_5g[path][rate]; + } + + *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, + rate, ch, regd); + *remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : + dm_info->txagc_remnant_ofdm[path]; + *sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate); +} + +u8 +rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, + enum rtw_bandwidth bandwidth, u8 channel, u8 regd) +{ + struct rtw_power_params pwr_param = {0}; + u8 tx_power; + s8 offset; + + rtw_get_tx_power_params(rtwdev, rf_path, rate, bandwidth, + channel, regd, &pwr_param); + + tx_power = pwr_param.pwr_base; + offset = min3(pwr_param.pwr_offset, + pwr_param.pwr_limit, + pwr_param.pwr_sar); + + if (rtwdev->chip->en_dis_dpd) + offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate); + + tx_power += offset + pwr_param.pwr_remnant; + + if (tx_power > rtwdev->chip->max_power_index) + tx_power = rtwdev->chip->max_power_index; + + return tx_power; +} +EXPORT_SYMBOL(rtw_phy_get_tx_power_index); + +static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev, + u8 ch, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 regd = rtw_regd_get(rtwdev); + const u8 *rates; + u8 size; + u8 rate; + u8 pwr_idx; + u8 bw; + int i; + + if (rs >= RTW_RATE_SECTION_NUM) + return; + + rates = rtw_rate_section[rs]; + size = rtw_rate_size[rs]; + bw = hal->current_band_width; + for (i = 0; i < size; i++) { + rate = rates[i]; + pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, rate, + bw, ch, regd); + hal->tx_pwr_tbl[path][rate] = pwr_idx; + } +} + +/* set tx power level by path for each rates, note that the order of the rates + * are *very* important, bacause 8822B/8821C combines every four bytes of tx + * power index into a four-byte power index register, and calls set_tx_agc to + * write these values into hardware + */ +static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev, + u8 ch, u8 path) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 rs; + + /* do not need cck rates if we are not in 2.4G */ + if (hal->current_band_type == RTW_BAND_2G) + rs = RTW_RATE_SECTION_CCK; + else + rs = RTW_RATE_SECTION_OFDM; + + for (; rs < RTW_RATE_SECTION_NUM; rs++) + rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs); +} + +void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + u8 path; + + mutex_lock(&hal->tx_power_mutex); + + for (path = 0; path < hal->rf_path_num; path++) + rtw_phy_set_tx_power_level_by_path(rtwdev, channel, path); + + chip->ops->set_tx_power_index(rtwdev); + mutex_unlock(&hal->tx_power_mutex); +} +EXPORT_SYMBOL(rtw_phy_set_tx_power_level); + +static void +rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, + u8 rs, u8 size, const u8 *rates) +{ + u8 rate; + u8 base_idx, rate_idx; + s8 base_2g, base_5g; + + if (size == 10) /* VHT rates */ + base_idx = rates[size - 3]; + else + base_idx = rates[size - 1]; + base_2g = hal->tx_pwr_by_rate_offset_2g[path][base_idx]; + base_5g = hal->tx_pwr_by_rate_offset_5g[path][base_idx]; + hal->tx_pwr_by_rate_base_2g[path][rs] = base_2g; + hal->tx_pwr_by_rate_base_5g[path][rs] = base_5g; + for (rate = 0; rate < size; rate++) { + rate_idx = rates[rate]; + hal->tx_pwr_by_rate_offset_2g[path][rate_idx] -= base_2g; + hal->tx_pwr_by_rate_offset_5g[path][rate_idx] -= base_5g; + } +} + +void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal) +{ + u8 path, rs; + + for (path = 0; path < RTW_RF_PATH_MAX; path++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) + rtw_phy_tx_power_by_rate_config_by_path(hal, path, rs, + rtw_rate_size[rs], rtw_rate_section[rs]); +} + +static void +__rtw_phy_tx_power_limit_config(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs) +{ + s8 base; + u8 ch; + + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) { + base = hal->tx_pwr_by_rate_base_2g[0][rs]; + hal->tx_pwr_limit_2g[regd][bw][rs][ch] -= base; + } + + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++) { + base = hal->tx_pwr_by_rate_base_5g[0][rs]; + hal->tx_pwr_limit_5g[regd][bw][rs][ch] -= base; + } +} + +void rtw_phy_tx_power_limit_config(struct rtw_hal *hal) +{ + u8 regd, bw, rs; + + /* default at channel 1 */ + hal->cch_by_bw[RTW_CHANNEL_WIDTH_20] = 1; + + for (regd = 0; regd < RTW_REGD_MAX; regd++) + for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) + __rtw_phy_tx_power_limit_config(hal, regd, bw, rs); +} + +static void rtw_phy_init_tx_power_limit(struct rtw_dev *rtwdev, + u8 regd, u8 bw, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + s8 max_power_index = (s8)rtwdev->chip->max_power_index; + u8 ch; + + /* 2.4G channels */ + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) + hal->tx_pwr_limit_2g[regd][bw][rs][ch] = max_power_index; + + /* 5G channels */ + for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++) + hal->tx_pwr_limit_5g[regd][bw][rs][ch] = max_power_index; +} + +void rtw_phy_init_tx_power(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 regd, path, rate, rs, bw; + + /* init tx power by rate offset */ + for (path = 0; path < RTW_RF_PATH_MAX; path++) { + for (rate = 0; rate < DESC_RATE_MAX; rate++) { + hal->tx_pwr_by_rate_offset_2g[path][rate] = 0; + hal->tx_pwr_by_rate_offset_5g[path][rate] = 0; + } + } + + /* init tx power limit */ + for (regd = 0; regd < RTW_REGD_MAX; regd++) + for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) + rtw_phy_init_tx_power_limit(rtwdev, regd, bw, + rs); +} + +void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table) +{ + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); + const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + u8 channel = rtwdev->hal.current_channel; + + if (IS_CH_2G_BAND(channel)) { + if (rtwdev->dm_info.tx_rate <= DESC_RATE11M) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2g_ccka_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2g_cckc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2g_cckc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2g_cckd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2g_cckd_n; + } else { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n; + } + } else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_1]; + } else if (IS_CH_5G_BAND_3(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_2]; + } else if (IS_CH_5G_BAND_4(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_3]; + } else { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n; + } +} +EXPORT_SYMBOL(rtw_phy_config_swing_table); + +void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + ewma_thermal_add(&dm_info->avg_thermal[path], thermal); + dm_info->thermal_avg[path] = + ewma_thermal_read(&dm_info->avg_thermal[path]); +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_avg); + +bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 avg = ewma_thermal_read(&dm_info->avg_thermal[path]); + + if (avg == thermal) + return false; + + return true; +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_thermal_changed); + +u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 therm_avg, therm_efuse, therm_delta; + + therm_avg = dm_info->thermal_avg[path]; + therm_efuse = rtwdev->efuse.thermal_meter[path]; + therm_delta = abs(therm_avg - therm_efuse); + + return min_t(u8, therm_delta, RTW_PWR_TRK_TBL_SZ - 1); +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_get_delta); + +s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 tbl_path, u8 therm_path, u8 delta) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + const u8 *delta_swing_table_idx_pos; + const u8 *delta_swing_table_idx_neg; + + if (delta >= RTW_PWR_TRK_TBL_SZ) { + rtw_warn(rtwdev, "power track table overflow\n"); + return 0; + } + + if (!swing_table) { + rtw_warn(rtwdev, "swing table not configured\n"); + return 0; + } + + delta_swing_table_idx_pos = swing_table->p[tbl_path]; + delta_swing_table_idx_neg = swing_table->n[tbl_path]; + + if (!delta_swing_table_idx_pos || !delta_swing_table_idx_neg) { + rtw_warn(rtwdev, "invalid swing table index\n"); + return 0; + } + + if (dm_info->thermal_avg[therm_path] > + rtwdev->efuse.thermal_meter[therm_path]) + return delta_swing_table_idx_pos[delta]; + else + return -delta_swing_table_idx_neg[delta]; +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_get_pwridx); + +bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 delta_lck; + + delta_lck = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_lck); + if (delta_lck >= rtwdev->chip->lck_threshold) { + dm_info->thermal_meter_lck = dm_info->thermal_avg[0]; + return true; + } + return false; +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_need_lck); + +bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 delta_iqk; + + delta_iqk = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_k); + if (delta_iqk >= rtwdev->chip->iqk_threshold) { + dm_info->thermal_meter_k = dm_info->thermal_avg[0]; + return true; + } + return false; +} +EXPORT_SYMBOL(rtw_phy_pwrtrack_need_iqk); + +static void rtw_phy_set_tx_path_by_reg(struct rtw_dev *rtwdev, + enum rtw_bb_path tx_path_sel_1ss) +{ + struct rtw_path_div *path_div = &rtwdev->dm_path_div; + enum rtw_bb_path tx_path_sel_cck = tx_path_sel_1ss; + const struct rtw_chip_info *chip = rtwdev->chip; + + if (tx_path_sel_1ss == path_div->current_tx_path) + return; + + path_div->current_tx_path = tx_path_sel_1ss; + rtw_dbg(rtwdev, RTW_DBG_PATH_DIV, "Switch TX path=%s\n", + tx_path_sel_1ss == BB_PATH_A ? "A" : "B"); + chip->ops->config_tx_path(rtwdev, rtwdev->hal.antenna_tx, + tx_path_sel_1ss, tx_path_sel_cck, false); +} + +static void rtw_phy_tx_path_div_select(struct rtw_dev *rtwdev) +{ + struct rtw_path_div *path_div = &rtwdev->dm_path_div; + enum rtw_bb_path path = path_div->current_tx_path; + s32 rssi_a = 0, rssi_b = 0; + + if (path_div->path_a_cnt) + rssi_a = path_div->path_a_sum / path_div->path_a_cnt; + else + rssi_a = 0; + if (path_div->path_b_cnt) + rssi_b = path_div->path_b_sum / path_div->path_b_cnt; + else + rssi_b = 0; + + if (rssi_a != rssi_b) + path = (rssi_a > rssi_b) ? BB_PATH_A : BB_PATH_B; + + path_div->path_a_cnt = 0; + path_div->path_a_sum = 0; + path_div->path_b_cnt = 0; + path_div->path_b_sum = 0; + rtw_phy_set_tx_path_by_reg(rtwdev, path); +} + +static void rtw_phy_tx_path_diversity_2ss(struct rtw_dev *rtwdev) +{ + if (rtwdev->hal.antenna_rx != BB_PATH_AB) { + rtw_dbg(rtwdev, RTW_DBG_PATH_DIV, + "[Return] tx_Path_en=%d, rx_Path_en=%d\n", + rtwdev->hal.antenna_tx, rtwdev->hal.antenna_rx); + return; + } + if (rtwdev->sta_cnt == 0) { + rtw_dbg(rtwdev, RTW_DBG_PATH_DIV, "No Link\n"); + return; + } + + rtw_phy_tx_path_div_select(rtwdev); +} + +void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + if (!chip->path_div_supported) + return; + + rtw_phy_tx_path_diversity_2ss(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h new file mode 100644 index 000000000..844993649 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/phy.h @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_PHY_H_ +#define __RTW_PHY_H_ + +#include "debug.h" + +extern const u8 rtw_cck_rates[]; +extern const u8 rtw_ofdm_rates[]; +extern const u8 rtw_ht_1s_rates[]; +extern const u8 rtw_ht_2s_rates[]; +extern const u8 rtw_vht_1s_rates[]; +extern const u8 rtw_vht_2s_rates[]; +extern const u8 rtw_ht_3s_rates[]; +extern const u8 rtw_ht_4s_rates[]; +extern const u8 rtw_vht_3s_rates[]; +extern const u8 rtw_vht_4s_rates[]; +extern const u8 * const rtw_rate_section[]; +extern const u8 rtw_rate_size[]; + +void rtw_phy_init(struct rtw_dev *rtwdev); +void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev); +u8 rtw_phy_rf_power_2_rssi(s8 *rf_power, u8 path_num); +u32 rtw_phy_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); +u32 rtw_phy_read_rf_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); +bool rtw_phy_write_rf_reg_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data); +bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data); +bool rtw_phy_write_rf_reg_mix(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data); +void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg); +void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl); +void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl); +void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev, const struct rtw_table *tbl); +void rtw_phy_cfg_mac(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data); +void rtw_phy_cfg_agc(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data); +void rtw_phy_cfg_bb(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data); +void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl, + u32 addr, u32 data); +void rtw_phy_init_tx_power(struct rtw_dev *rtwdev); +void rtw_phy_load_tables(struct rtw_dev *rtwdev); +u8 rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, + enum rtw_bandwidth bw, u8 channel, u8 regd); +void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel); +void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal); +void rtw_phy_tx_power_limit_config(struct rtw_hal *hal); +void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path); +bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, + u8 path); +u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path); +s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 tbl_path, u8 therm_path, u8 delta); +bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev); +bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev); +void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table); +void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l); +void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev); +void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat); +void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev); + +struct rtw_txpwr_lmt_cfg_pair { + u8 regd; + u8 band; + u8 bw; + u8 rs; + u8 ch; + s8 txpwr_lmt; +}; + +struct rtw_phy_pg_cfg_pair { + u32 band; + u32 rf_path; + u32 tx_num; + u32 addr; + u32 bitmask; + u32 data; +}; + +#define RTW_DECL_TABLE_PHY_COND_CORE(name, cfg, path) \ +const struct rtw_table name ## _tbl = { \ + .data = name, \ + .size = ARRAY_SIZE(name), \ + .parse = rtw_parse_tbl_phy_cond, \ + .do_cfg = cfg, \ + .rf_path = path, \ +} + +#define RTW_DECL_TABLE_PHY_COND(name, cfg) \ + RTW_DECL_TABLE_PHY_COND_CORE(name, cfg, 0) + +#define RTW_DECL_TABLE_RF_RADIO(name, path) \ + RTW_DECL_TABLE_PHY_COND_CORE(name, rtw_phy_cfg_rf, RF_PATH_ ## path) + +#define RTW_DECL_TABLE_BB_PG(name) \ +const struct rtw_table name ## _tbl = { \ + .data = name, \ + .size = ARRAY_SIZE(name), \ + .parse = rtw_parse_tbl_bb_pg, \ +} + +#define RTW_DECL_TABLE_TXPWR_LMT(name) \ +const struct rtw_table name ## _tbl = { \ + .data = name, \ + .size = ARRAY_SIZE(name), \ + .parse = rtw_parse_tbl_txpwr_lmt, \ +} + +static inline const struct rtw_rfe_def *rtw_get_rfe_def(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + const struct rtw_rfe_def *rfe_def = NULL; + + if (chip->rfe_defs_size == 0) + return NULL; + + if (efuse->rfe_option < chip->rfe_defs_size) + rfe_def = &chip->rfe_defs[efuse->rfe_option]; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "use rfe_def[%d]\n", efuse->rfe_option); + return rfe_def; +} + +static inline int rtw_check_supported_rfe(struct rtw_dev *rtwdev) +{ + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); + + if (!rfe_def || !rfe_def->phy_pg_tbl || !rfe_def->txpwr_lmt_tbl) { + rtw_err(rtwdev, "rfe %d isn't supported\n", + rtwdev->efuse.rfe_option); + return -ENODEV; + } + + return 0; +} + +void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi); +void rtw_phy_dig_reset(struct rtw_dev *rtwdev); +void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev); + +struct rtw_power_params { + u8 pwr_base; + s8 pwr_offset; + s8 pwr_limit; + s8 pwr_remnant; + s8 pwr_sar; +}; + +void +rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, + u8 rate, u8 bw, u8 ch, u8 regd, + struct rtw_power_params *pwr_param); + +enum rtw_phy_cck_pd_lv { + CCK_PD_LV0, + CCK_PD_LV1, + CCK_PD_LV2, + CCK_PD_LV3, + CCK_PD_LV4, + CCK_PD_LV_MAX, +}; + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define RFREG_MASK 0xfffff + +#define MASK7BITS 0x7f +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASK20BITS 0xfffff +#define MASK24BITS 0xffffff + +#define MASKH3BYTES 0xffffff00 +#define MASKL3BYTES 0x00ffffff +#define MASKBYTE2HIGHNIBBLE 0x00f00000 +#define MASKBYTE3LOWNIBBLE 0x0f000000 +#define MASKL3BYTES 0x00ffffff + +#define CCK_FA_AVG_RESET 0xffffffff + +#define LSSI_READ_ADDR_MASK 0x7f800000 +#define LSSI_READ_EDGE_MASK 0x80000000 +#define LSSI_READ_DATA_MASK 0xfffff + +#define RRSR_RATE_ORDER_MAX 0xfffff +#define RRSR_RATE_ORDER_CCK_LEN 4 + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c new file mode 100644 index 000000000..add5a20b8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/ps.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "reg.h" +#include "fw.h" +#include "ps.h" +#include "mac.h" +#include "coex.h" +#include "debug.h" + +static int rtw_ips_pwr_up(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtw_core_start(rtwdev); + if (ret) + rtw_err(rtwdev, "leave idle state failed\n"); + + rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_set_channel(rtwdev); + + return ret; +} + +int rtw_enter_ips(struct rtw_dev *rtwdev) +{ + if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + return 0; + + rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER); + + rtw_core_stop(rtwdev); + rtw_hci_link_ps(rtwdev, true); + + return 0; +} + +static void rtw_restore_port_cfg_iter(void *data, struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + u32 config = ~0; + + rtw_vif_port_config(rtwdev, rtwvif, config); +} + +int rtw_leave_ips(struct rtw_dev *rtwdev) +{ + int ret; + + if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + return 0; + + rtw_hci_link_ps(rtwdev, false); + + ret = rtw_ips_pwr_up(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave ips state\n"); + return ret; + } + + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); + + return 0; +} + +void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) +{ + u8 request, confirm, polling; + int ret; + + request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); + + /* toggle to request power mode, others remain 0 */ + request ^= request | BIT_RPWM_TOGGLE; + if (enter) { + request |= POWER_MODE_LCLK; + if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG) + request |= POWER_MODE_PG; + } + /* Each request require an ack from firmware */ + request |= POWER_MODE_ACK; + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + request |= POWER_TX_WAKE; + + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request); + + /* Check firmware get the power requset and ack via cpwm register */ + ret = read_poll_timeout_atomic(rtw_read8, polling, + (polling ^ confirm) & BIT_RPWM_TOGGLE, + 100, 15000, true, rtwdev, + rtwdev->hci.cpwm_addr); + if (ret) { + /* Hit here means that driver failed to get an ack from firmware. + * The reason could be that hardware is locked at Deep sleep, + * so most of the hardware circuits are not working, even + * register read/write; or firmware is locked in some state and + * cannot get the request. It should be treated as fatal error + * and requires an entire analysis about the firmware/hardware. + */ + WARN(1, "firmware failed to ack driver for %s Deep Power mode\n", + enter ? "entering" : "leaving"); + rtw_fw_dump_dbg_info(rtwdev); + } +} +EXPORT_SYMBOL(rtw_power_mode_change); + +static void __rtw_leave_lps_deep(struct rtw_dev *rtwdev) +{ + rtw_hci_deep_ps(rtwdev, false); +} + +static int __rtw_fw_leave_lps_check_reg(struct rtw_dev *rtwdev) +{ + int i; + + /* Driver needs to wait for firmware to leave LPS state + * successfully. Firmware will send null packet to inform AP, + * and see if AP sends an ACK back, then firmware will restore + * the REG_TCR register. + * + * If driver does not wait for firmware, null packet with + * PS bit could be sent due to incorrect REG_TCR setting. + * + * In our test, 100ms should be enough for firmware to finish + * the flow. If REG_TCR Register is still incorrect after 100ms, + * just modify it directly, and throw a warn message. + */ + for (i = 0 ; i < LEAVE_LPS_TRY_CNT; i++) { + if (rtw_read32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN) == 0) + return 0; + msleep(20); + } + + return -EBUSY; +} + +static int __rtw_fw_leave_lps_check_c2h(struct rtw_dev *rtwdev) +{ + if (wait_for_completion_timeout(&rtwdev->lps_leave_check, + LEAVE_LPS_TIMEOUT)) + return 0; + return -EBUSY; +} + +static void rtw_fw_leave_lps_check(struct rtw_dev *rtwdev) +{ + bool ret = false; + struct rtw_fw_state *fw; + + if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) + fw = &rtwdev->wow_fw; + else + fw = &rtwdev->fw; + + if (rtw_fw_feature_check(fw, FW_FEATURE_LPS_C2H)) + ret = __rtw_fw_leave_lps_check_c2h(rtwdev); + else + ret = __rtw_fw_leave_lps_check_reg(rtwdev); + + if (ret) { + rtw_write32_clr(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN); + rtw_warn(rtwdev, "firmware failed to leave lps state\n"); + rtw_fw_dump_dbg_info(rtwdev); + } +} + +static void rtw_fw_leave_lps_check_prepare(struct rtw_dev *rtwdev) +{ + struct rtw_fw_state *fw; + + if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) + fw = &rtwdev->wow_fw; + else + fw = &rtwdev->fw; + + if (rtw_fw_feature_check(fw, FW_FEATURE_LPS_C2H)) + reinit_completion(&rtwdev->lps_leave_check); +} + +static void rtw_leave_lps_core(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + + conf->state = RTW_ALL_ON; + conf->awake_interval = 1; + conf->rlbm = 0; + conf->smart_ps = 0; + + rtw_hci_link_ps(rtwdev, false); + rtw_fw_leave_lps_check_prepare(rtwdev); + rtw_fw_set_pwr_mode(rtwdev); + rtw_fw_leave_lps_check(rtwdev); + + clear_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags); + + rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE); +} + +enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev) +{ + if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) + return rtwdev->lps_conf.wow_deep_mode; + else + return rtwdev->lps_conf.deep_mode; +} + +static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev) +{ + if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_NONE) + return; + + if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "Should enter LPS before entering deep PS\n"); + return; + } + + if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG) + rtw_fw_set_pg_info(rtwdev); + + rtw_hci_deep_ps(rtwdev, true); +} + +static void rtw_enter_lps_core(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + + conf->state = RTW_RF_OFF; + conf->awake_interval = 1; + conf->rlbm = 1; + conf->smart_ps = 2; + + rtw_coex_lps_notify(rtwdev, COEX_LPS_ENABLE); + + rtw_fw_set_pwr_mode(rtwdev); + rtw_hci_link_ps(rtwdev, true); + + set_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags); +} + +static void __rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + + if (test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) + return; + + conf->mode = RTW_MODE_LPS; + conf->port_id = port_id; + + rtw_enter_lps_core(rtwdev); +} + +static void __rtw_leave_lps(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + + if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "Should leave deep PS before leaving LPS\n"); + __rtw_leave_lps_deep(rtwdev); + } + + if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) + return; + + conf->mode = RTW_MODE_ACTIVE; + + rtw_leave_lps_core(rtwdev); +} + +void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id) +{ + lockdep_assert_held(&rtwdev->mutex); + + if (rtwdev->coex.stat.wl_force_lps_ctrl) + return; + + __rtw_enter_lps(rtwdev, port_id); + __rtw_enter_lps_deep(rtwdev); +} + +void rtw_leave_lps(struct rtw_dev *rtwdev) +{ + lockdep_assert_held(&rtwdev->mutex); + + __rtw_leave_lps_deep(rtwdev); + __rtw_leave_lps(rtwdev); +} + +void rtw_leave_lps_deep(struct rtw_dev *rtwdev) +{ + lockdep_assert_held(&rtwdev->mutex); + + __rtw_leave_lps_deep(rtwdev); +} + +struct rtw_vif_recalc_lps_iter_data { + struct rtw_dev *rtwdev; + struct ieee80211_vif *found_vif; + int count; +}; + +static void __rtw_vif_recalc_lps(struct rtw_vif_recalc_lps_iter_data *data, + struct ieee80211_vif *vif) +{ + if (data->count < 0) + return; + + if (vif->type != NL80211_IFTYPE_STATION) { + data->count = -1; + return; + } + + data->count++; + data->found_vif = vif; +} + +static void rtw_vif_recalc_lps_iter(void *data, struct ieee80211_vif *vif) +{ + __rtw_vif_recalc_lps(data, vif); +} + +void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif) +{ + struct rtw_vif_recalc_lps_iter_data data = { .rtwdev = rtwdev }; + + if (new_vif) + __rtw_vif_recalc_lps(&data, new_vif); + rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data); + + if (data.count == 1 && data.found_vif->cfg.ps) { + rtwdev->ps_enabled = true; + } else { + rtwdev->ps_enabled = false; + rtw_leave_lps(rtwdev); + } +} diff --git a/drivers/net/wireless/realtek/rtw88/ps.h b/drivers/net/wireless/realtek/rtw88/ps.h new file mode 100644 index 000000000..5ae83d252 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/ps.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_PS_H_ +#define __RTW_PS_H_ + +#define RTW_LPS_THRESHOLD 50 + +#define POWER_MODE_ACK BIT(6) +#define POWER_MODE_PG BIT(4) +#define POWER_TX_WAKE BIT(1) +#define POWER_MODE_LCLK BIT(0) + +#define LEAVE_LPS_TRY_CNT 5 +#define LEAVE_LPS_TIMEOUT msecs_to_jiffies(100) + +int rtw_enter_ips(struct rtw_dev *rtwdev); +int rtw_leave_ips(struct rtw_dev *rtwdev); + +void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter); +void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id); +void rtw_leave_lps(struct rtw_dev *rtwdev); +void rtw_leave_lps_deep(struct rtw_dev *rtwdev); +enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev); +void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h new file mode 100644 index 000000000..08e949497 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -0,0 +1,1004 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_REG_DEF_H__ +#define __RTW_REG_DEF_H__ + +#define REG_SYS_FUNC_EN 0x0002 +#define BIT_FEN_EN_25_1 BIT(13) +#define BIT_FEN_ELDR BIT(12) +#define BIT_FEN_PCIEA BIT(6) +#define BIT_FEN_CPUEN BIT(2) +#define BIT_FEN_USBA BIT(2) +#define BIT_FEN_BB_GLB_RST BIT(1) +#define BIT_FEN_BB_RSTB BIT(0) +#define BIT_R_DIS_PRST BIT(6) +#define BIT_WLOCK_1C_B6 BIT(5) +#define REG_SYS_PW_CTRL 0x0004 +#define BIT_PFM_WOWL BIT(3) +#define BIT_APFM_OFFMAC BIT(9) +#define REG_APS_FSMCO 0x0004 +#define APS_FSMCO_MAC_ENABLE BIT(8) +#define APS_FSMCO_MAC_OFF BIT(9) +#define APS_FSMCO_HW_POWERDOWN BIT(15) +#define REG_SYS_CLK_CTRL 0x0008 +#define BIT_CPU_CLK_EN BIT(14) + +#define REG_SYS_CLKR 0x0008 +#define BIT_ANA8M BIT(1) +#define BIT_WAKEPAD_EN BIT(3) +#define BIT_LOADER_CLK_EN BIT(5) + +#define REG_RSV_CTRL 0x001C +#define DISABLE_PI 0x3 +#define ENABLE_PI 0x2 +#define BITS_RFC_DIRECT (BIT(31) | BIT(30)) +#define BIT_WLMCU_IOIF BIT(0) +#define REG_RF_CTRL 0x001F +#define BIT_RF_SDM_RSTB BIT(2) +#define BIT_RF_RSTB BIT(1) +#define BIT_RF_EN BIT(0) + +#define REG_RF_CTRL1 0x0020 +#define REG_RF_CTRL2 0x0021 + +#define REG_AFE_CTRL1 0x0024 +#define BIT_MAC_CLK_SEL (BIT(20) | BIT(21)) +#define REG_EFUSE_CTRL 0x0030 +#define BIT_EF_FLAG BIT(31) +#define BIT_SHIFT_EF_ADDR 8 +#define BIT_MASK_EF_ADDR 0x3ff +#define BIT_MASK_EF_DATA 0xff +#define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR) +#define BITS_PLL 0xf0 + +#define REG_AFE_XTAL_CTRL 0x24 +#define REG_AFE_PLL_CTRL 0x28 +#define REG_AFE_CTRL3 0x2c +#define BIT_MASK_XTAL 0x00FFF000 +#define BIT_XTAL_GMP_BIT4 BIT(28) + +#define REG_LDO_EFUSE_CTRL 0x0034 +#define BIT_MASK_EFUSE_BANK_SEL (BIT(8) | BIT(9)) + +#define BIT_LDO25_VOLTAGE_V25 0x03 +#define BIT_MASK_LDO25_VOLTAGE GENMASK(6, 4) +#define BIT_SHIFT_LDO25_VOLTAGE 4 +#define BIT_LDO25_EN BIT(7) + +#define REG_ACLK_MON 0x3e + +#define REG_GPIO_MUXCFG 0x0040 +#define BIT_FSPI_EN BIT(19) +#define BIT_EN_SIC BIT(12) + +#define BIT_PO_BT_PTA_PINS BIT(9) +#define BIT_BT_PTA_EN BIT(5) +#define BIT_WLRFE_4_5_EN BIT(2) + +#define REG_GPIO_PIN_CTRL 0x0044 + +#define REG_LED_CFG 0x004C +#define BIT_LNAON_SEL_EN BIT(26) +#define BIT_PAPE_SEL_EN BIT(25) +#define BIT_DPDT_WL_SEL BIT(24) +#define BIT_DPDT_SEL_EN BIT(23) +#define BIT_GPIO13_14_WL_CTRL_EN BIT(22) +#define BIT_LED2_SV BIT(19) +#define BIT_LED2_CM GENMASK(18, 16) +#define BIT_LED1_SV BIT(11) +#define BIT_LED1_CM GENMASK(10, 8) +#define BIT_LED0_SV BIT(3) +#define BIT_LED0_CM GENMASK(2, 0) +#define BIT_LED_MODE_SW_CTRL 0 +#define BIT_LED_MODE_RX 6 +#define BIT_LED_MODE_TX 4 +#define BIT_LED_MODE_TRX 2 +#define REG_LEDCFG2 0x004E +#define REG_GPIO_PIN_CTRL_2 0x0060 +#define REG_PAD_CTRL1 0x0064 +#define BIT_BT_BTG_SEL BIT(31) +#define BIT_PAPE_WLBT_SEL BIT(29) +#define BIT_LNAON_WLBT_SEL BIT(28) +#define BIT_BTGP_JTAG_EN BIT(24) +#define BIT_BTGP_SPI_EN BIT(20) +#define BIT_LED1DIS BIT(15) +#define BIT_SW_DPDT_SEL_DATA BIT(0) +#define REG_WL_BT_PWR_CTRL 0x0068 +#define BIT_BT_FUNC_EN BIT(18) +#define BIT_BT_DIG_CLK_EN BIT(8) +#define REG_SYS_SDIO_CTRL 0x0070 +#define BIT_DBG_GNT_WL_BT BIT(27) +#define BIT_LTE_MUX_CTRL_PATH BIT(26) +#define REG_HCI_OPT_CTRL 0x0074 +#define BIT_USB_SUS_DIS BIT(8) +#define BIT_SDIO_PAD_E5 BIT(18) + +#define REG_RF_B_CTRL 0x76 +#define REG_RF_CTRL3 0x0076 + +#define REG_AFE_CTRL_4 0x0078 +#define BIT_CK320M_AFE_EN BIT(4) +#define BIT_EN_SYN BIT(15) + +#define REG_LDO_SWR_CTRL 0x007C +#define LDO_SEL 0xC3 +#define SPS_SEL 0x83 +#define BIT_XTA1 BIT(29) +#define BIT_XTA0 BIT(28) + +#define REG_MCUFW_CTRL 0x0080 +#define BIT_ANA_PORT_EN BIT(22) +#define BIT_MAC_PORT_EN BIT(21) +#define BIT_BOOT_FSPI_EN BIT(20) +#define BIT_ROM_DLEN BIT(19) +#define BIT_ROM_PGE GENMASK(18, 16) /* legacy only */ +#define BIT_SHIFT_ROM_PGE 16 +#define BIT_FW_INIT_RDY BIT(15) +#define BIT_FW_DW_RDY BIT(14) +#define BIT_CPU_CLK_SEL (BIT(12) | BIT(13)) +#define BIT_RPWM_TOGGLE BIT(7) +#define BIT_RAM_DL_SEL BIT(7) /* legacy only */ +#define BIT_DMEM_CHKSUM_OK BIT(6) +#define BIT_WINTINI_RDY BIT(6) /* legacy only */ +#define BIT_DMEM_DW_OK BIT(5) +#define BIT_IMEM_CHKSUM_OK BIT(4) +#define BIT_IMEM_DW_OK BIT(3) +#define BIT_IMEM_BOOT_LOAD_CHECKSUM_OK BIT(2) +#define BIT_FWDL_CHK_RPT BIT(2) /* legacy only */ +#define BIT_MCUFWDL_RDY BIT(1) /* legacy only */ +#define BIT_MCUFWDL_EN BIT(0) +#define BIT_CHECK_SUM_OK (BIT(4) | BIT(6)) +#define FW_READY (BIT_FW_INIT_RDY | BIT_FW_DW_RDY | \ + BIT_IMEM_DW_OK | BIT_DMEM_DW_OK | \ + BIT_CHECK_SUM_OK) +#define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ + BIT_WINTINI_RDY | BIT_RAM_DL_SEL) +#define FW_READY_MASK (0xffff & ~BIT_CPU_CLK_SEL) + +#define REG_MCU_TST_CFG 0x84 +#define VAL_FW_TRIGGER 0x1 + +#define REG_PMC_DBG_CTRL1 0xa8 +#define BITS_PMC_BT_IQK_STS GENMASK(22, 21) + +#define REG_HIMR0 0xb0 +#define REG_HISR0 0xb4 +#define REG_HIMR1 0xb8 +#define REG_HISR1 0xbc + +#define REG_PAD_CTRL2 0x00C4 +#define BIT_RSM_EN_V1 BIT(16) +#define BIT_NO_PDN_CHIPOFF_V1 BIT(17) +#define BIT_MASK_USB23_SW_MODE_V1 GENMASK(19, 18) +#define BIT_USB3_USB2_TRANSITION BIT(20) +#define BIT_USB_MODE_U2 1 +#define BIT_USB_MODE_U3 2 + +#define REG_EFUSE_ACCESS 0x00CF +#define EFUSE_ACCESS_ON 0x69 +#define EFUSE_ACCESS_OFF 0x00 + +#define REG_WLRF1 0x00EC +#define REG_WIFI_BT_INFO 0x00AA +#define BIT_BT_INT_EN BIT(15) +#define REG_SYS_CFG1 0x00F0 +#define BIT_RTL_ID BIT(23) +#define BIT_LDO BIT(24) +#define BIT_RF_TYPE_ID BIT(27) +#define BIT_SHIFT_VENDOR_ID 16 +#define BIT_MASK_VENDOR_ID 0xf +#define BIT_VENDOR_ID(x) (((x) & BIT_MASK_VENDOR_ID) << BIT_SHIFT_VENDOR_ID) +#define BITS_VENDOR_ID (BIT_MASK_VENDOR_ID << BIT_SHIFT_VENDOR_ID) +#define BIT_CLEAR_VENDOR_ID(x) ((x) & (~BITS_VENDOR_ID)) +#define BIT_GET_VENDOR_ID(x) (((x) >> BIT_SHIFT_VENDOR_ID) & BIT_MASK_VENDOR_ID) +#define BIT_SHIFT_CHIP_VER 12 +#define BIT_MASK_CHIP_VER 0xf +#define BIT_CHIP_VER(x) (((x) & BIT_MASK_CHIP_VER) << BIT_SHIFT_CHIP_VER) +#define BITS_CHIP_VER (BIT_MASK_CHIP_VER << BIT_SHIFT_CHIP_VER) +#define BIT_CLEAR_CHIP_VER(x) ((x) & (~BITS_CHIP_VER)) +#define BIT_GET_CHIP_VER(x) (((x) >> BIT_SHIFT_CHIP_VER) & BIT_MASK_CHIP_VER) +#define REG_SYS_STATUS1 0x00F4 +#define REG_SYS_STATUS2 0x00F8 +#define REG_SYS_CFG2 0x00FC +#define REG_WLRF1 0x00EC +#define BIT_WLRF1_BBRF_EN (BIT(24) | BIT(25) | BIT(26)) +#define REG_CR 0x0100 +#define BIT_32K_CAL_TMR_EN BIT(10) +#define BIT_MAC_SEC_EN BIT(9) +#define BIT_ENSWBCN BIT(8) +#define BIT_MACRXEN BIT(7) +#define BIT_MACTXEN BIT(6) +#define BIT_SCHEDULE_EN BIT(5) +#define BIT_PROTOCOL_EN BIT(4) +#define BIT_RXDMA_EN BIT(3) +#define BIT_TXDMA_EN BIT(2) +#define BIT_HCI_RXDMA_EN BIT(1) +#define BIT_HCI_TXDMA_EN BIT(0) +#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \ + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \ + BIT_MACTXEN | BIT_MACRXEN) +#define REG_PBP 0x104 +#define PBP_RX_MASK 0x0f +#define PBP_TX_MASK 0xf0 +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define BIT_SHIFT_TXDMA_VOQ_MAP 4 +#define BIT_MASK_TXDMA_VOQ_MAP 0x3 +#define BIT_TXDMA_VOQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_VOQ_MAP) << BIT_SHIFT_TXDMA_VOQ_MAP) +#define BIT_SHIFT_TXDMA_VIQ_MAP 6 +#define BIT_MASK_TXDMA_VIQ_MAP 0x3 +#define BIT_TXDMA_VIQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP) +#define REG_TXDMA_PQ_MAP 0x010C +#define BIT_RXDMA_ARBBW_EN BIT(0) +#define BIT_RXSHFT_EN BIT(1) +#define BIT_RXDMA_AGG_EN BIT(2) +#define BIT_TXDMA_BW_EN BIT(3) +#define BIT_SHIFT_TXDMA_BEQ_MAP 8 +#define BIT_MASK_TXDMA_BEQ_MAP 0x3 +#define BIT_TXDMA_BEQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_BEQ_MAP) << BIT_SHIFT_TXDMA_BEQ_MAP) +#define BIT_SHIFT_TXDMA_BKQ_MAP 10 +#define BIT_MASK_TXDMA_BKQ_MAP 0x3 +#define BIT_TXDMA_BKQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_BKQ_MAP) << BIT_SHIFT_TXDMA_BKQ_MAP) +#define BIT_SHIFT_TXDMA_MGQ_MAP 12 +#define BIT_MASK_TXDMA_MGQ_MAP 0x3 +#define BIT_TXDMA_MGQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_MGQ_MAP) << BIT_SHIFT_TXDMA_MGQ_MAP) +#define BIT_SHIFT_TXDMA_HIQ_MAP 14 +#define BIT_MASK_TXDMA_HIQ_MAP 0x3 +#define BIT_TXDMA_HIQ_MAP(x) \ + (((x) & BIT_MASK_TXDMA_HIQ_MAP) << BIT_SHIFT_TXDMA_HIQ_MAP) +#define BIT_SHIFT_TXSC_40M 4 +#define BIT_MASK_TXSC_40M 0xf +#define BIT_TXSC_40M(x) \ + (((x) & BIT_MASK_TXSC_40M) << BIT_SHIFT_TXSC_40M) +#define BIT_SHIFT_TXSC_20M 0 +#define BIT_MASK_TXSC_20M 0xf +#define BIT_TXSC_20M(x) \ + (((x) & BIT_MASK_TXSC_20M) << BIT_SHIFT_TXSC_20M) +#define BIT_SHIFT_MAC_CLK_SEL 20 +#define MAC_CLK_HW_DEF_80M 0 +#define MAC_CLK_HW_DEF_40M 1 +#define MAC_CLK_HW_DEF_20M 2 +#define MAC_CLK_SPEED 80 + +#define REG_CR 0x0100 +#define REG_TRXFF_BNDY 0x0114 +#define REG_RXFF_BNDY 0x011C +#define REG_FE1IMR 0x0120 +#define BIT_FS_RXDONE BIT(16) +#define REG_CPWM 0x012C +#define REG_FWIMR 0x0130 +#define BIT_FS_H2CCMD_INT_EN BIT(4) +#define BIT_FS_HRCV_INT_EN BIT(5) +#define REG_FWISR 0x0134 +#define BIT_FS_H2CCMD_INT BIT(4) +#define BIT_FS_HRCV_INT BIT(5) +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_C2HEVT 0x01A0 +#define REG_MCUTST_1 0x01C0 +#define REG_MCUTST_II 0x01C4 +#define REG_WOWLAN_WAKE_REASON 0x01C7 +#define REG_HMETFR 0x01CC +#define BIT_INT_BOX0 BIT(0) +#define BIT_INT_BOX1 BIT(1) +#define BIT_INT_BOX2 BIT(2) +#define BIT_INT_BOX3 BIT(3) +#define BIT_INT_BOX_ALL (BIT_INT_BOX0 | BIT_INT_BOX1 | BIT_INT_BOX2 | \ + BIT_INT_BOX3) +#define REG_HMEBOX0 0x01D0 +#define REG_HMEBOX1 0x01D4 +#define REG_HMEBOX2 0x01D8 +#define REG_HMEBOX3 0x01DC +#define REG_LLT_INIT 0x01E0 +#define BIT_LLT_WRITE_ACCESS BIT(30) +#define REG_HMEBOX0_EX 0x01F0 +#define REG_HMEBOX1_EX 0x01F4 +#define REG_HMEBOX2_EX 0x01F8 +#define REG_HMEBOX3_EX 0x01FC + +#define REG_RQPN 0x0200 +#define BIT_MASK_HPQ 0xff +#define BIT_SHIFT_HPQ 0 +#define BIT_RQPN_HPQ(x) (((x) & BIT_MASK_HPQ) << BIT_SHIFT_HPQ) +#define BIT_MASK_LPQ 0xff +#define BIT_SHIFT_LPQ 8 +#define BIT_RQPN_LPQ(x) (((x) & BIT_MASK_LPQ) << BIT_SHIFT_LPQ) +#define BIT_MASK_PUBQ 0xff +#define BIT_SHIFT_PUBQ 16 +#define BIT_RQPN_PUBQ(x) (((x) & BIT_MASK_PUBQ) << BIT_SHIFT_PUBQ) +#define BIT_RQPN_HLP(h, l, p) (BIT_LD_RQPN | BIT_RQPN_HPQ(h) | \ + BIT_RQPN_LPQ(l) | BIT_RQPN_PUBQ(p)) + +#define REG_FIFOPAGE_CTRL_2 0x0204 +#define BIT_BCN_VALID_V1 BIT(15) +#define BIT_MASK_BCN_HEAD_1_V1 0xfff +#define REG_AUTO_LLT_V1 0x0208 +#define BIT_AUTO_INIT_LLT_V1 BIT(0) +#define BIT_MASK_BLK_DESC_NUM GENMASK(7, 4) +#define REG_DWBCN0_CTRL 0x0208 +#define BIT_BCN_VALID BIT(16) +#define REG_TXDMA_OFFSET_CHK 0x020C +#define BIT_DROP_DATA_EN BIT(9) +#define REG_TXDMA_STATUS 0x0210 +#define BTI_PAGE_OVF BIT(2) + +#define REG_RQPN_NPQ 0x0214 +#define BIT_MASK_NPQ 0xff +#define BIT_SHIFT_NPQ 0 +#define BIT_MASK_EPQ 0xff +#define BIT_SHIFT_EPQ 16 +#define BIT_RQPN_NPQ(x) (((x) & BIT_MASK_NPQ) << BIT_SHIFT_NPQ) +#define BIT_RQPN_EPQ(x) (((x) & BIT_MASK_EPQ) << BIT_SHIFT_EPQ) +#define BIT_RQPN_NE(n, e) (BIT_RQPN_NPQ(n) | BIT_RQPN_EPQ(e)) + +#define REG_AUTO_LLT 0x0224 +#define BIT_AUTO_INIT_LLT BIT(16) +#define REG_DWBCN1_CTRL 0x0228 +#define REG_RQPN_CTRL_1 0x0228 +#define REG_RQPN_CTRL_2 0x022C +#define BIT_LD_RQPN BIT(31) +#define REG_FIFOPAGE_INFO_1 0x0230 +#define REG_FIFOPAGE_INFO_2 0x0234 +#define REG_FIFOPAGE_INFO_3 0x0238 +#define REG_FIFOPAGE_INFO_4 0x023C +#define REG_FIFOPAGE_INFO_5 0x0240 +#define REG_H2C_HEAD 0x0244 +#define REG_H2C_TAIL 0x0248 +#define REG_H2C_READ_ADDR 0x024C +#define REG_H2C_INFO 0x0254 +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define BIT_RXDMA_AGG_PG_TH GENMASK(7, 0) +#define BIT_DMA_AGG_TO_V1 GENMASK(15, 8) +#define BIT_EN_PRE_CALC BIT(29) +#define REG_RXPKT_NUM 0x0284 +#define BIT_RXDMA_REQ BIT(19) +#define BIT_RW_RELEASE BIT(18) +#define BIT_RXDMA_IDLE BIT(17) +#define REG_RXDMA_STATUS 0x0288 +#define REG_RXDMA_DPR 0x028C +#define REG_RXDMA_MODE 0x0290 +#define BIT_DMA_MODE BIT(1) +#define BIT_DMA_BURST_CNT GENMASK(3, 2) +#define BIT_DMA_BURST_SIZE GENMASK(5, 4) +#define BIT_DMA_BURST_SIZE_64 2 +#define BIT_DMA_BURST_SIZE_512 1 +#define BIT_DMA_BURST_SIZE_1024 0 + +#define REG_RXPKTNUM 0x02B0 +#define REG_EARLY_MODE_CONTROL 0x02BC + +#define REG_INT_MIG 0x0304 +#define REG_HCI_MIX_CFG 0x03FC +#define BIT_PCIE_EMAC_PDN_AUX_TO_FAST_CLK BIT(26) + +#define REG_BCNQ_INFO 0x0418 +#define BIT_MGQ_CPU_EMPTY BIT(24) +#define REG_TXPKT_EMPTY 0x041A +#define REG_FWHW_TXQ_CTRL 0x0420 +#define BIT_EN_BCNQ_DL BIT(22) +#define BIT_EN_WR_FREE_TAIL BIT(20) +#define REG_HWSEQ_CTRL 0x0423 + +#define REG_BCNQ_BDNY_V1 0x0424 +#define REG_BCNQ_BDNY 0x0424 +#define REG_MGQ_BDNY 0x0425 +#define REG_LIFETIME_EN 0x0426 +#define BIT_BA_PARSER_EN BIT(5) +#define REG_SPEC_SIFS 0x0428 +#define REG_RETRY_LIMIT 0x042a +#define REG_DARFRC 0x0430 +#define REG_DARFRCH 0x0434 +#define REG_RARFRCH 0x043C +#define REG_RRSR 0x0440 +#define BITS_RRSR_RSC GENMASK(22, 21) +#define REG_ARFR0 0x0444 +#define REG_ARFRH0 0x0448 +#define REG_ARFR1_V1 0x044C +#define REG_ARFRH1_V1 0x0450 +#define REG_CCK_CHECK 0x0454 +#define BIT_CHECK_CCK_EN BIT(7) +#define REG_AMPDU_MAX_TIME_V1 0x0455 +#define REG_BCNQ1_BDNY_V1 0x0456 +#define REG_AMPDU_MAX_TIME 0x0456 +#define REG_AMPDU_MAX_LENGTH 0x0458 +#define REG_WMAC_LBK_BF_HD 0x045D +#define REG_TX_HANG_CTRL 0x045E +#define BIT_EN_GNT_BT_AWAKE BIT(3) +#define BIT_EN_EOF_V1 BIT(2) +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_DATA_SC 0x0483 +#define REG_ARFR2_V1 0x048C +#define REG_ARFRH2_V1 0x0490 +#define REG_ARFR3_V1 0x0494 +#define BIT_EXC_CODE GENMASK(6, 2) +#define REG_ARFRH3_V1 0x0498 +#define REG_ARFR4 0x049C +#define BIT_WL_RFK BIT(0) +#define REG_ARFRH4 0x04A0 +#define REG_ARFR5 0x04A4 +#define REG_ARFRH5 0x04A8 +#define REG_SW_AMPDU_BURST_MODE_CTRL 0x04BC +#define BIT_PRE_TX_CMD BIT(6) +#define REG_QUEUE_CTRL 0x04C6 +#define BIT_PTA_WL_TX_EN BIT(4) +#define BIT_PTA_EDCCA_EN BIT(5) +#define REG_SINGLE_AMPDU_CTRL 0x04C7 +#define BIT_EN_SINGLE_APMDU BIT(7) +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_PRECNT_CTRL 0x04E5 +#define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) +#define BIT_EN_PRECNT BIT(11) +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 +#define REG_DUMMY_PAGE4_V1 0x04FC + +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define BIT_MASK_TXOP_LMT GENMASK(26, 16) +#define BIT_MASK_CWMAX GENMASK(15, 12) +#define BIT_MASK_CWMIN GENMASK(11, 8) +#define BIT_MASK_AIFS GENMASK(7, 0) +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_SIFS 0x0514 +#define BIT_SHIFT_SIFS_OFDM_CTX 8 +#define BIT_SHIFT_SIFS_CCK_TRX 16 +#define BIT_SHIFT_SIFS_OFDM_TRX 24 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define BIT_DIS_EDCCA BIT(15) +#define BIT_SIFS_BK_EN BIT(12) +#define REG_TXPAUSE 0x0522 +#define BIT_AC_QUEUE GENMASK(7, 0) +#define BIT_HIGH_QUEUE BIT(5) +#define REG_RD_CTRL 0x0524 +#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) +#define BIT_DIS_TXOP_CFE BIT(10) +#define BIT_DIS_LSIG_CFE BIT(9) +#define BIT_DIS_STBC_CFE BIT(8) +#define REG_TBTT_PROHIBIT 0x0540 +#define BIT_SHIFT_TBTT_HOLD_TIME_AP 8 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define BIT_DIS_TSF_UDT BIT(4) +#define BIT_EN_BCN_FUNCTION BIT(3) +#define BIT_EN_TXBCN_RPT BIT(2) +#define REG_BCN_CTRL_CLINT0 0x0551 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_MISC_CTRL 0x0577 +#define BIT_EN_FREE_CNT BIT(3) +#define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1)) +#define REG_HIQ_NO_LMT_EN 0x5A7 +#define REG_DTIM_COUNTER_ROOT 0x5A8 +#define BIT_HIQ_NO_LMT_EN_ROOT BIT(0) +#define REG_TIMER0_SRC_SEL 0x05B4 +#define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) + +#define REG_TCR 0x0604 +#define BIT_PWRMGT_HWDATA_EN BIT(7) +#define BIT_TCR_UPDATE_TIMIE BIT(5) +#define BIT_TCR_UPDATE_HGQMD BIT(4) +#define REG_RCR 0x0608 +#define BIT_APP_FCS BIT(31) +#define BIT_APP_MIC BIT(30) +#define BIT_APP_ICV BIT(29) +#define BIT_APP_PHYSTS BIT(28) +#define BIT_APP_BASSN BIT(27) +#define BIT_VHT_DACK BIT(26) +#define BIT_TCPOFLD_EN BIT(25) +#define BIT_ENMBID BIT(24) +#define BIT_LSIGEN BIT(23) +#define BIT_MFBEN BIT(22) +#define BIT_DISCHKPPDLLEN BIT(21) +#define BIT_PKTCTL_DLEN BIT(20) +#define BIT_DISGCLK BIT(19) +#define BIT_TIM_PARSER_EN BIT(18) +#define BIT_BC_MD_EN BIT(17) +#define BIT_UC_MD_EN BIT(16) +#define BIT_RXSK_PERPKT BIT(15) +#define BIT_HTC_LOC_CTRL BIT(14) +#define BIT_RPFM_CAM_ENABLE BIT(12) +#define BIT_TA_BCN BIT(11) +#define BIT_RCR_ADF BIT(11) +#define BIT_DISDECMYPKT BIT(10) +#define BIT_AICV BIT(9) +#define BIT_ACRC32 BIT(8) +#define BIT_CBSSID_BCN BIT(7) +#define BIT_CBSSID_DATA BIT(6) +#define BIT_APWRMGT BIT(5) +#define BIT_ADD3 BIT(4) +#define BIT_AB BIT(3) +#define BIT_AM BIT(2) +#define BIT_APM BIT(1) +#define BIT_AAP BIT(0) +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DRVINFO_SZ 0x060F +#define BIT_APP_PHYSTS BIT(28) +#define REG_MAR 0x0620 +#define REG_USTIME_EDCA 0x0638 +#define REG_ACKTO_CCK 0x0639 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_EIFS 0x0642 +#define REG_NAV_CTRL 0x0650 +#define REG_WMAC_TRXPTCL_CTL 0x0668 +#define BIT_RFMOD (BIT(7) | BIT(8)) +#define BIT_RFMOD_80M BIT(8) +#define BIT_RFMOD_40M BIT(7) +#define REG_WMAC_TRXPTCL_CTL_H 0x066C +#define REG_WKFMCAM_CMD 0x0698 +#define BIT_WKFCAM_POLLING_V1 BIT(31) +#define BIT_WKFCAM_CLR_V1 BIT(30) +#define BIT_WKFCAM_WE BIT(16) +#define BIT_SHIFT_WKFCAM_ADDR_V2 8 +#define BIT_MASK_WKFCAM_ADDR_V2 0xff +#define BIT_WKFCAM_ADDR_V2(x) \ + (((x) & BIT_MASK_WKFCAM_ADDR_V2) << BIT_SHIFT_WKFCAM_ADDR_V2) +#define REG_WKFMCAM_RWD 0x069C +#define BIT_WKFMCAM_VALID BIT(31) +#define BIT_WKFMCAM_BC BIT(26) +#define BIT_WKFMCAM_MC BIT(25) +#define BIT_WKFMCAM_UC BIT(24) + +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_RXFLTMAP4 0x068A +#define REG_BT_COEX_TABLE0 0x06C0 +#define REG_BT_COEX_TABLE1 0x06C4 +#define REG_BT_COEX_BRK_TABLE 0x06C8 +#define REG_BT_COEX_TABLE_H 0x06CC +#define REG_BT_COEX_TABLE_H1 0x06CD +#define REG_BT_COEX_TABLE_H2 0x06CE +#define REG_BT_COEX_TABLE_H3 0x06CF +#define REG_BBPSF_CTRL 0x06DC + +#define REG_BT_COEX_V2 0x0762 +#define BIT_GNT_BT_POLARITY BIT(12) +#define BIT_LTE_COEX_EN BIT(7) +#define REG_GNT_BT 0x0765 +#define BIT_PTA_SW_CTL GENMASK(4, 3) +#define REG_BT_COEX_ENH_INTR_CTRL 0x76E +#define BIT_R_GRANTALL_WLMASK BIT(3) +#define BIT_STATIS_BT_EN BIT(2) +#define REG_BT_ACT_STATISTICS 0x0770 +#define REG_BT_ACT_STATISTICS_1 0x0774 +#define REG_BT_STAT_CTRL 0x0778 +#define REG_BT_TDMA_TIME 0x0790 +#define BIT_MASK_SAMPLE_RATE GENMASK(5, 0) +#define REG_LTR_IDLE_LATENCY 0x0798 +#define REG_LTR_ACTIVE_LATENCY 0x079C +#define REG_LTR_CTRL_BASIC 0x07A4 +#define REG_WMAC_OPTION_FUNCTION 0x07D0 +#define REG_WMAC_OPTION_FUNCTION_1 0x07D4 + +#define REG_FPGA0_RFMOD 0x0800 +#define BIT_CCKEN BIT(24) +#define BIT_OFDMEN BIT(25) +#define REG_CCK_RPT_FORMAT 0x0804 +#define BIT_CCK_RPT_FORMAT BIT(16) +#define REG_RXPSEL 0x0808 +#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +#define REG_TXPSEL 0x080C +#define REG_RX_GAIN_EN 0x081c +#define REG_CCASEL 0x082C +#define REG_PDMFTH 0x0830 +#define REG_BWINDICATION 0x0834 +#define REG_CCA2ND 0x0838 +#define REG_L1PKTH 0x0848 +#define REG_CLKTRK 0x0860 +#define REG_CSI_MASK_SETTING1 0x0874 +#define REG_NBI_SETTING 0x087c +#define BIT_NBI_ENABLE BIT(13) +#define REG_CSI_FIX_MASK0 0x0880 +#define REG_CSI_FIX_MASK1 0x0884 +#define REG_CSI_FIX_MASK6 0x0898 +#define REG_CSI_FIX_MASK7 0x089c +#define REG_ADCCLK 0x08AC +#define REG_HSSI_READ 0x08B0 +#define REG_FPGA0_XCD_RF_PARA 0x08B4 +#define REG_RX_MCS_LIMIT 0x08BC +#define REG_ADC160 0x08C4 +#define REG_DBGSEL 0x08fc +#define REG_ANTSEL_SW 0x0900 +#define REG_DAC_RSTB 0x090c +#define REG_PSD 0x0910 +#define BIT_PSD_INI GENMASK(23, 22) +#define REG_SINGLE_TONE_CONT_TX 0x0914 +#define REG_AGC_TABLE 0x0958 +#define REG_RFE_CTRL_E 0x0974 +#define REG_2ND_CCA_CTRL 0x0976 +#define REG_IQK_COM00 0x0978 +#define REG_IQK_COM32 0x097c +#define REG_IQK_COM64 0x0980 +#define REG_IQK_COM96 0x0984 + +#define REG_FAS 0x09a4 +#define REG_RXSB 0x0a00 +#define BIT_RXSB_ANA_DIV BIT(15) +#define REG_CCK_RX 0x0a04 +#define REG_CCK_PD_TH 0x0a0a +#define REG_PRECTRL 0x0a14 +#define BIT_DIS_CO_PATHSEL BIT(7) +#define BIT_IQ_WGT GENMASK(9, 8) +#define REG_CCA_MF 0x0a20 +#define BIT_MBC_WIN GENMASK(5, 4) +#define REG_CCK0_TX_FILTER1 0x0a20 +#define REG_CCK0_TX_FILTER2 0x0a24 +#define REG_CCK0_DEBUG_PORT 0x0a28 +#define REG_CCK0_FAREPORT 0x0a2c +#define BIT_CCK0_2RX BIT(18) +#define BIT_CCK0_MRC BIT(22) +#define REG_FA_CCK 0x0a5c + +#define REG_DIS_DPD 0x0a70 +#define DIS_DPD_MASK GENMASK(9, 0) +#define DIS_DPD_RATE6M BIT(0) +#define DIS_DPD_RATE9M BIT(1) +#define DIS_DPD_RATEMCS0 BIT(2) +#define DIS_DPD_RATEMCS1 BIT(3) +#define DIS_DPD_RATEMCS8 BIT(4) +#define DIS_DPD_RATEMCS9 BIT(5) +#define DIS_DPD_RATEVHT1SS_MCS0 BIT(6) +#define DIS_DPD_RATEVHT1SS_MCS1 BIT(7) +#define DIS_DPD_RATEVHT2SS_MCS0 BIT(8) +#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9) +#define DIS_DPD_RATEALL GENMASK(9, 0) + +#define REG_CCA 0x0a70 +#define BIT_CCA_CO BIT(7) +#define REG_ANTSEL 0x0a74 +#define BIT_ANT_BYCO BIT(8) +#define REG_CCKTX 0x0a84 +#define BIT_CMB_CCA_2R BIT(28) + +#define REG_CNTRST 0x0b58 + +#define REG_3WIRE_SWA 0x0c00 +#define REG_RX_IQC_AB_A 0x0c10 +#define REG_RX_IQC_CD_A 0x0c14 +#define REG_TXSCALE_A 0x0c1c +#define BB_SWING_MASK GENMASK(31, 21) +#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20 +#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24 +#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28 +#define REG_TX_AGC_A_MCS3_MCS0 0xc2c +#define REG_TX_AGC_A_MCS7_MCS4 0xc30 +#define REG_TX_AGC_A_MCS11_MCS8 0xc34 +#define REG_TX_AGC_A_MCS15_MCS12 0xc38 +#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c +#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40 +#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44 +#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48 +#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c +#define REG_RXIGI_A 0x0c50 +#define REG_TX_PWR_TRAINING_A 0x0c54 +#define REG_CK_MONHA 0x0c5c +#define REG_AFE_PWR1_A 0x0c60 +#define REG_AFE_PWR2_A 0x0c64 +#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68 +#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80 +#define REG_OFDM0_A_TX_AFE 0x0c84 +#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88 +#define REG_TSSI_TRK_SW 0x0c8c +#define REG_LSSI_WRITE_A 0x0c90 +#define REG_PREDISTA 0x0c90 +#define REG_TXAGCIDX 0x0c94 +#define REG_TX_AGC_A 0x0c94 +#define REG_RFE_PINMUX_A 0x0cb0 +#define REG_RFE_INV_A 0x0cb4 +#define REG_RFE_CTRL8 0x0cb4 +#define BIT_MASK_RFE_SEL89 GENMASK(7, 0) +#define PTA_CTRL_PIN 0x66 +#define DPDT_CTRL_PIN 0x77 +#define RFE_INV_MASK 0x3ff00000 +#define REG_RFECTL_A 0x0cb8 +#define REG_RFE_INV0 0x0cbc +#define REG_RFE_INV8 0x0cbd +#define BIT_MASK_RFE_INV89 GENMASK(1, 0) +#define REG_RFE_INV16 0x0cbe +#define BIT_RFE_BUF_EN BIT(3) + +#define REG_IQK_DPD_CFG 0x0cc4 +#define REG_CFG_PMPD 0x0cc8 +#define REG_IQC_Y 0x0ccc +#define REG_IQC_X 0x0cd4 +#define REG_INTPO_SETA 0x0ce8 + +#define REG_IQKA_END 0x0d00 +#define REG_PI_READ_A 0x0d04 +#define REG_SI_READ_A 0x0d08 +#define REG_IQKB_END 0x0d40 +#define REG_PI_READ_B 0x0d44 +#define REG_SI_READ_B 0x0d48 + +#define REG_3WIRE_SWB 0x0e00 +#define REG_RX_IQC_AB_B 0x0e10 +#define REG_RX_IQC_CD_B 0x0e14 +#define REG_TXSCALE_B 0x0e1c +#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20 +#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24 +#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28 +#define REG_TX_AGC_B_MCS3_MCS0 0xe2c +#define REG_TX_AGC_B_MCS7_MCS4 0xe30 +#define REG_TX_AGC_B_MCS11_MCS8 0xe34 +#define REG_TX_AGC_B_MCS15_MCS12 0xe38 +#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c +#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40 +#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44 +#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48 +#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c +#define REG_RXIGI_B 0x0e50 +#define REG_TX_PWR_TRAINING_B 0x0e54 +#define REG_CK_MONHB 0x0e5c +#define REG_AFE_PWR1_B 0x0e60 +#define REG_AFE_PWR2_B 0x0e64 +#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68 +#define REG_TXTONEB 0x0e80 +#define REG_RXTONEB 0x0e84 +#define REG_TXPITMB 0x0e88 +#define REG_RXPITMB 0x0e8c +#define REG_LSSI_WRITE_B 0x0e90 +#define REG_PREDISTB 0x0e90 +#define REG_INIDLYB 0x0e94 +#define REG_TX_AGC_B 0x0e94 +#define REG_RFE_PINMUX_B 0x0eb0 +#define REG_RFE_INV_B 0x0eb4 +#define REG_RFECTL_B 0x0eb8 +#define REG_BPBDB 0x0ec4 +#define REG_PHYTXONB 0x0ec8 +#define REG_IQKYB 0x0ecc +#define REG_IQKXB 0x0ed4 +#define REG_INTPO_SETB 0x0ee8 + +#define REG_CRC_CCK 0x0f04 +#define REG_CCA_OFDM 0x0f08 +#define REG_CRC_VHT 0x0f0c +#define REG_CRC_HT 0x0f10 +#define REG_CRC_OFDM 0x0f14 +#define REG_FA_OFDM 0x0f48 +#define REG_DBGRPT 0x0fa0 +#define REG_CCA_CCK 0x0fcc + +#define REG_SYS_CFG3_8814A 0x1000 + +#define REG_ANAPARSW_MAC_0 0x1010 +#define BIT_CF_L_V2 GENMASK(29, 28) + +#define REG_ANAPAR_XTAL_0 0x1040 +#define BIT_XCAP_0 GENMASK(23, 10) +#define REG_CPU_DMEM_CON 0x1080 +#define BIT_WL_PLATFORM_RST BIT(16) +#define BIT_WL_SECURITY_CLK BIT(15) +#define BIT_DDMA_EN BIT(8) + +#define REG_SW_MDIO 0x10C0 + +#define REG_H2C_PKT_READADDR 0x10D0 +#define REG_H2C_PKT_WRITEADDR 0x10D4 +#define REG_FW_DBG6 0x10F8 +#define REG_FW_DBG7 0x10FC +#define FW_KEY_MASK 0xffffff00 + +#define REG_CR_EXT 0x1100 + +#define REG_FT1IMR 0x1138 +#define BIT_FS_H2C_CMD_OK_INT_EN BIT(25) +#define REG_FT1ISR 0x113c +#define BIT_FS_H2C_CMD_OK_INT BIT(25) +#define REG_DDMA_CH0SA 0x1200 +#define REG_DDMA_CH0DA 0x1204 +#define REG_DDMA_CH0CTRL 0x1208 +#define BIT_DDMACH0_OWN BIT(31) +#define BIT_DDMACH0_CHKSUM_EN BIT(29) +#define BIT_DDMACH0_CHKSUM_STS BIT(27) +#define BIT_DDMACH0_DDMA_MODE BIT(26) +#define BIT_DDMACH0_RESET_CHKSUM_STS BIT(25) +#define BIT_DDMACH0_CHKSUM_CONT BIT(24) +#define BIT_MASK_DDMACH0_DLEN 0x3ffff + +#define REG_H2CQ_CSR 0x1330 +#define BIT_H2CQ_FULL BIT(31) +#define REG_FAST_EDCA_VOVI_SETTING 0x1448 +#define REG_FAST_EDCA_BEBK_SETTING 0x144C + +#define REG_RXPSF_CTRL 0x1610 +#define BIT_RXGCK_FIFOTHR_EN BIT(28) + +#define BIT_SHIFT_RXGCK_VHT_FIFOTHR 26 +#define BIT_MASK_RXGCK_VHT_FIFOTHR 0x3 +#define BIT_RXGCK_VHT_FIFOTHR(x) \ + (((x) & BIT_MASK_RXGCK_VHT_FIFOTHR) << BIT_SHIFT_RXGCK_VHT_FIFOTHR) +#define BITS_RXGCK_VHT_FIFOTHR \ + (BIT_MASK_RXGCK_VHT_FIFOTHR << BIT_SHIFT_RXGCK_VHT_FIFOTHR) + +#define BIT_SHIFT_RXGCK_HT_FIFOTHR 24 +#define BIT_MASK_RXGCK_HT_FIFOTHR 0x3 +#define BIT_RXGCK_HT_FIFOTHR(x) \ + (((x) & BIT_MASK_RXGCK_HT_FIFOTHR) << BIT_SHIFT_RXGCK_HT_FIFOTHR) +#define BITS_RXGCK_HT_FIFOTHR \ + (BIT_MASK_RXGCK_HT_FIFOTHR << BIT_SHIFT_RXGCK_HT_FIFOTHR) + +#define BIT_SHIFT_RXGCK_OFDM_FIFOTHR 22 +#define BIT_MASK_RXGCK_OFDM_FIFOTHR 0x3 +#define BIT_RXGCK_OFDM_FIFOTHR(x) \ + (((x) & BIT_MASK_RXGCK_OFDM_FIFOTHR) << BIT_SHIFT_RXGCK_OFDM_FIFOTHR) +#define BITS_RXGCK_OFDM_FIFOTHR \ + (BIT_MASK_RXGCK_OFDM_FIFOTHR << BIT_SHIFT_RXGCK_OFDM_FIFOTHR) + +#define BIT_SHIFT_RXGCK_CCK_FIFOTHR 20 +#define BIT_MASK_RXGCK_CCK_FIFOTHR 0x3 +#define BIT_RXGCK_CCK_FIFOTHR(x) \ + (((x) & BIT_MASK_RXGCK_CCK_FIFOTHR) << BIT_SHIFT_RXGCK_CCK_FIFOTHR) +#define BITS_RXGCK_CCK_FIFOTHR \ + (BIT_MASK_RXGCK_CCK_FIFOTHR << BIT_SHIFT_RXGCK_CCK_FIFOTHR) + +#define BIT_RXGCK_OFDMCCA_EN BIT(16) + +#define BIT_SHIFT_RXPSF_PKTLENTHR 13 +#define BIT_MASK_RXPSF_PKTLENTHR 0x7 +#define BIT_RXPSF_PKTLENTHR(x) \ + (((x) & BIT_MASK_RXPSF_PKTLENTHR) << BIT_SHIFT_RXPSF_PKTLENTHR) +#define BITS_RXPSF_PKTLENTHR \ + (BIT_MASK_RXPSF_PKTLENTHR << BIT_SHIFT_RXPSF_PKTLENTHR) +#define BIT_CLEAR_RXPSF_PKTLENTHR(x) ((x) & (~BITS_RXPSF_PKTLENTHR)) +#define BIT_SET_RXPSF_PKTLENTHR(x, v) \ + (BIT_CLEAR_RXPSF_PKTLENTHR(x) | BIT_RXPSF_PKTLENTHR(v)) + +#define BIT_RXPSF_CTRLEN BIT(12) +#define BIT_RXPSF_VHTCHKEN BIT(11) +#define BIT_RXPSF_HTCHKEN BIT(10) +#define BIT_RXPSF_OFDMCHKEN BIT(9) +#define BIT_RXPSF_CCKCHKEN BIT(8) +#define BIT_RXPSF_OFDMRST BIT(7) +#define BIT_RXPSF_CCKRST BIT(6) +#define BIT_RXPSF_MHCHKEN BIT(5) +#define BIT_RXPSF_CONT_ERRCHKEN BIT(4) +#define BIT_RXPSF_ALL_ERRCHKEN BIT(3) + +#define BIT_SHIFT_RXPSF_ERRTHR 0 +#define BIT_MASK_RXPSF_ERRTHR 0x7 +#define BIT_RXPSF_ERRTHR(x) \ + (((x) & BIT_MASK_RXPSF_ERRTHR) << BIT_SHIFT_RXPSF_ERRTHR) +#define BITS_RXPSF_ERRTHR (BIT_MASK_RXPSF_ERRTHR << BIT_SHIFT_RXPSF_ERRTHR) +#define BIT_CLEAR_RXPSF_ERRTHR(x) ((x) & (~BITS_RXPSF_ERRTHR)) +#define BIT_GET_RXPSF_ERRTHR(x) \ + (((x) >> BIT_SHIFT_RXPSF_ERRTHR) & BIT_MASK_RXPSF_ERRTHR) +#define BIT_SET_RXPSF_ERRTHR(x, v) \ + (BIT_CLEAR_RXPSF_ERRTHR(x) | BIT_RXPSF_ERRTHR(v)) + +#define REG_RXPSF_TYPE_CTRL 0x1614 +#define REG_GENERAL_OPTION 0x1664 +#define BIT_DUMMY_FCS_READY_MASK_EN BIT(9) + +#define REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 0x1700 +#define REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 0x1704 +#define REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 0x1708 +#define LTECOEX_READY BIT(29) +#define LTECOEX_ACCESS_CTRL REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 +#define LTECOEX_WRITE_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 +#define LTECOEX_READ_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 + +#define REG_RX_IQC_AB_C 0x1810 +#define REG_RX_IQC_CD_C 0x1814 +#define REG_TXSCALE_C 0x181c +#define REG_CK_MONHC 0x185c +#define REG_AFE_PWR1_C 0x1860 +#define REG_IGN_GNT_BT1 0x1860 +#define REG_TX_AGC_C 0x1894 +#define REG_RFE_PINMUX_C 0x18b4 + +#define REG_RFESEL_CTRL 0x1990 +#define REG_AGC_TBL 0x1998 + +#define REG_RX_IQC_AB_D 0x1a10 +#define REG_RX_IQC_CD_D 0x1a14 +#define REG_TXSCALE_D 0x1a1c +#define REG_CK_MONHD 0x1a5c +#define REG_AFE_PWR1_D 0x1a60 +#define REG_TX_AGC_D 0x1a94 +#define REG_RFE_PINMUX_D 0x1ab4 +#define REG_RFE_INVSEL_D 0x1abc +#define BIT_RFE_SELSW0_D GENMASK(27, 20) + +#define REG_NOMASK_TXBT 0x1ca7 +#define REG_ANAPAR 0x1c30 +#define BIT_ANAPAR_BTPS BIT(22) +#define REG_RSTB_SEL 0x1c38 +#define BIT_DAC_OFF_ENABLE BIT(4) +#define BIT_PI_IGNORE_GNT_BT BIT(3) +#define BIT_NOMASK_TXBT_ENABLE BIT(3) + +#define REG_HRCV_MSG 0x1cf + +#define REG_EDCCA_REPORT 0x2d38 +#define BIT_EDCCA_FLAG BIT(24) + +#define REG_IGN_GNTBT4 0x4160 + +#define REG_USB_MOD 0xf008 +#define REG_USB3_RXITV 0xf050 +#define REG_USB2_PHY_ADR 0xfe40 +#define REG_USB2_PHY_DAT 0xfe41 +#define REG_USB2_PHY_CMD 0xfe42 +#define BIT_USB2_PHY_CMD_TRG 0x81 +#define REG_USB_HRPWM 0xfe58 +#define REG_USB3_PHY_ADR 0xff0c +#define REG_USB3_PHY_DAT_L 0xff0d +#define REG_USB3_PHY_DAT_H 0xff0e +#define BIT_USB3_PHY_ADR_WR BIT(7) +#define BIT_USB3_PHY_ADR_RD BIT(6) +#define BIT_USB3_PHY_ADR_MASK GENMASK(5, 0) + +#define RF_MODE 0x00 +#define RF_MODOPT 0x01 +#define RF_WLINT 0x01 +#define RF_WLSEL 0x02 +#define RF_DTXLOK 0x08 +#define RF_CFGCH 0x18 +#define BIT_BAND GENMASK(18, 16) +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF_RCK1_V1 0x1c +#define RF_RCK 0x1d +#define RF_MODE_TABLE_ADDR 0x30 +#define RF_MODE_TABLE_DATA0 0x31 +#define RF_MODE_TABLE_DATA1 0x32 +#define RF_LUTWA 0x33 +#define RF_LUTWD1 0x3e +#define RF_LUTWD0 0x3f +#define BIT_GAIN_EXT BIT(12) +#define BIT_DATA_L GENMASK(11, 0) +#define RF_T_METER 0x42 +#define RF_BSPAD 0x54 +#define RF_GAINTX 0x56 +#define RF_TXMOD 0x58 +#define RF_TXATANK 0x64 +#define RF_TXA_PREPAD 0x65 +#define RF_TRXIQ 0x66 +#define RF_RXIQGEN 0x8d +#define RF_RXBB2 0x8f +#define RF_SYN_PFD 0xb0 +#define RF_LCK 0xb4 +#define RF_XTALX2 0xb8 +#define RF_SYN_CTRL 0xbb +#define RF_MALSEL 0xbe +#define RF_SYN_AAC 0xc9 +#define RF_AAC_CTRL 0xca +#define RF_FAST_LCK 0xcc +#define RF_RCKD 0xde +#define RF_TXADBG 0xde +#define RF_LUTDBG 0xdf +#define BIT_TXA_TANK BIT(4) +#define RF_LUTWE2 0xee +#define RF_LUTWE 0xef + +#define LTE_COEX_CTRL 0x38 +#define LTE_WL_TRX_CTRL 0xa0 +#define LTE_BT_TRX_CTRL 0xa4 + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c new file mode 100644 index 000000000..7f3b2ea3f --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/regd.c @@ -0,0 +1,541 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "regd.h" +#include "debug.h" +#include "phy.h" + +#define COUNTRY_REGD_ENT(_alpha2, _regd_2g, _regd_5g) \ + {.alpha2 = (_alpha2), \ + .txpwr_regd_2g = (_regd_2g), \ + .txpwr_regd_5g = (_regd_5g), \ + } + +#define rtw_dbg_regd_dump(_dev, _msg, _args...) \ +do { \ + struct rtw_dev *__d = (_dev); \ + const struct rtw_regd *__r = &__d->regd; \ + rtw_dbg(__d, RTW_DBG_REGD, _msg \ + "apply alpha2 %c%c, regd {%d, %d}, dfs_region %d\n",\ + ##_args, \ + __r->regulatory->alpha2[0], \ + __r->regulatory->alpha2[1], \ + __r->regulatory->txpwr_regd_2g, \ + __r->regulatory->txpwr_regd_5g, \ + __r->dfs_region); \ +} while (0) + +/* If country code is not correctly defined in efuse, + * use worldwide country code and txpwr regd. + */ +static const struct rtw_regulatory rtw_reg_ww = + COUNTRY_REGD_ENT("00", RTW_REGD_WW, RTW_REGD_WW); + +static const struct rtw_regulatory rtw_reg_map[] = { + COUNTRY_REGD_ENT("AD", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AG", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("AI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AN", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("AO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AQ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AR", RTW_REGD_MEXICO, RTW_REGD_MEXICO), + COUNTRY_REGD_ENT("AS", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("AT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("AU", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("AW", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("AZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BB", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("BD", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BJ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BM", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("BN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BO", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("BR", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("BS", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("BT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BV", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BW", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BY", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("BZ", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("CA", RTW_REGD_IC, RTW_REGD_IC), + COUNTRY_REGD_ENT("CC", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("CD", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CL", RTW_REGD_CHILE, RTW_REGD_CHILE), + COUNTRY_REGD_ENT("CM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CN", RTW_REGD_CN, RTW_REGD_CN), + COUNTRY_REGD_ENT("CO", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("CR", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("CV", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CX", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("CY", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("CZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("DE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("DJ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("DK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("DM", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("DO", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("DZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("EC", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("EE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("EG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("EH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ER", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ES", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ET", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("FI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("FJ", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("FK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("FM", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("FO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("FR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GB", RTW_REGD_UK, RTW_REGD_UK), + COUNTRY_REGD_ENT("GD", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("GE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GP", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GQ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GT", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("GU", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("GW", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("GY", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("HK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("HM", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("HN", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("HR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("HT", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("HU", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ID", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IQ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("IT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("JE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("JM", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("JO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("JP", RTW_REGD_MKK, RTW_REGD_MKK), + COUNTRY_REGD_ENT("KE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KN", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("KR", RTW_REGD_KCC, RTW_REGD_KCC), + COUNTRY_REGD_ENT("KW", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("KY", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("KZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LB", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LC", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("LI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LU", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LV", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("LY", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MC", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MD", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ME", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MF", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("MG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MH", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("MK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ML", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MP", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("MQ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MU", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MV", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MW", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MX", RTW_REGD_MEXICO, RTW_REGD_MEXICO), + COUNTRY_REGD_ENT("MY", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("MZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NC", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NF", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("NG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NI", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("NL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NP", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("NU", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("NZ", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("OM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PA", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("PE", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("PF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PR", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("PS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("PW", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("PY", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("QA", RTW_REGD_QATAR, RTW_REGD_QATAR), + COUNTRY_REGD_ENT("RE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("RO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("RS", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("RU", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("RW", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SB", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SC", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("SE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SI", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SJ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SL", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SR", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("ST", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("SV", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("SX", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("SZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TC", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TD", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TH", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TJ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TK", RTW_REGD_ACMA, RTW_REGD_ACMA), + COUNTRY_REGD_ENT("TM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TO", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TR", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("TT", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("TV", RTW_REGD_ETSI, RTW_REGD_WW), + COUNTRY_REGD_ENT("TW", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("TZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("UA", RTW_REGD_UKRAINE, RTW_REGD_UKRAINE), + COUNTRY_REGD_ENT("UG", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("US", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("UY", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("UZ", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("VA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("VC", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("VE", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("VG", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("VI", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("VN", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("VU", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("WF", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("WS", RTW_REGD_FCC, RTW_REGD_FCC), + COUNTRY_REGD_ENT("XK", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("YE", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("YT", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ZA", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ZM", RTW_REGD_ETSI, RTW_REGD_ETSI), + COUNTRY_REGD_ENT("ZW", RTW_REGD_ETSI, RTW_REGD_ETSI), +}; + +static void rtw_regd_apply_hw_cap_flags(struct wiphy *wiphy) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + struct rtw_dev *rtwdev = hw->priv; + struct rtw_efuse *efuse = &rtwdev->efuse; + int i; + + if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_80)) + return; + + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + goto out_5g; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + ch->flags |= IEEE80211_CHAN_NO_80MHZ; + } + +out_5g: + sband = wiphy->bands[NL80211_BAND_5GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + ch->flags |= IEEE80211_CHAN_NO_80MHZ; + } +} + +static bool rtw_reg_is_ww(const struct rtw_regulatory *reg) +{ + return reg == &rtw_reg_ww; +} + +static bool rtw_reg_match(const struct rtw_regulatory *reg, const char *alpha2) +{ + return memcmp(reg->alpha2, alpha2, 2) == 0; +} + +static const struct rtw_regulatory *rtw_reg_find_by_name(const char *alpha2) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rtw_reg_map); i++) { + if (rtw_reg_match(&rtw_reg_map[i], alpha2)) + return &rtw_reg_map[i]; + } + + return &rtw_reg_ww; +} + +static +void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +/* call this before ieee80211_register_hw() */ +int rtw_regd_init(struct rtw_dev *rtwdev) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + const struct rtw_regulatory *chip_reg; + + if (!wiphy) + return -EINVAL; + + wiphy->reg_notifier = rtw_regd_notifier; + + chip_reg = rtw_reg_find_by_name(rtwdev->efuse.country_code); + if (!rtw_reg_is_ww(chip_reg)) { + rtwdev->regd.state = RTW_REGD_STATE_PROGRAMMED; + + /* Set REGULATORY_STRICT_REG before ieee80211_register_hw(), + * stack will wait for regulatory_hint() and consider it + * as the superset for our regulatory rule. + */ + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; + } else { + rtwdev->regd.state = RTW_REGD_STATE_WORLDWIDE; + } + + rtwdev->regd.regulatory = &rtw_reg_ww; + rtwdev->regd.dfs_region = NL80211_DFS_UNSET; + rtw_dbg_regd_dump(rtwdev, "regd init state %d: ", rtwdev->regd.state); + + rtw_regd_apply_hw_cap_flags(wiphy); + return 0; +} + +/* call this after ieee80211_register_hw() */ +int rtw_regd_hint(struct rtw_dev *rtwdev) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + int ret; + + if (!wiphy) + return -EINVAL; + + if (rtwdev->regd.state == RTW_REGD_STATE_PROGRAMMED) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "country domain %c%c is PGed on efuse", + rtwdev->efuse.country_code[0], + rtwdev->efuse.country_code[1]); + + ret = regulatory_hint(wiphy, rtwdev->efuse.country_code); + if (ret) { + rtw_warn(rtwdev, + "failed to hint regulatory: %d\n", ret); + return ret; + } + } + + return 0; +} + +static bool rtw_regd_mgmt_worldwide(struct rtw_dev *rtwdev, + struct rtw_regd *next_regd, + struct regulatory_request *request) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + + next_regd->state = RTW_REGD_STATE_WORLDWIDE; + + if (request->initiator == NL80211_REGDOM_SET_BY_USER && + !rtw_reg_is_ww(next_regd->regulatory)) { + next_regd->state = RTW_REGD_STATE_SETTING; + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; + } + + return true; +} + +static bool rtw_regd_mgmt_programmed(struct rtw_dev *rtwdev, + struct rtw_regd *next_regd, + struct regulatory_request *request) +{ + if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER && + rtw_reg_match(next_regd->regulatory, rtwdev->efuse.country_code)) { + next_regd->state = RTW_REGD_STATE_PROGRAMMED; + return true; + } + + return false; +} + +static bool rtw_regd_mgmt_setting(struct rtw_dev *rtwdev, + struct rtw_regd *next_regd, + struct regulatory_request *request) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + + if (request->initiator != NL80211_REGDOM_SET_BY_USER) + return false; + + next_regd->state = RTW_REGD_STATE_SETTING; + + if (rtw_reg_is_ww(next_regd->regulatory)) { + next_regd->state = RTW_REGD_STATE_WORLDWIDE; + wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; + } + + return true; +} + +static bool (*const rtw_regd_handler[RTW_REGD_STATE_NR]) + (struct rtw_dev *, struct rtw_regd *, struct regulatory_request *) = { + [RTW_REGD_STATE_WORLDWIDE] = rtw_regd_mgmt_worldwide, + [RTW_REGD_STATE_PROGRAMMED] = rtw_regd_mgmt_programmed, + [RTW_REGD_STATE_SETTING] = rtw_regd_mgmt_setting, +}; + +static bool rtw_regd_state_hdl(struct rtw_dev *rtwdev, + struct rtw_regd *next_regd, + struct regulatory_request *request) +{ + next_regd->regulatory = rtw_reg_find_by_name(request->alpha2); + next_regd->dfs_region = request->dfs_region; + return rtw_regd_handler[rtwdev->regd.state](rtwdev, next_regd, request); +} + +static +void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw_dev *rtwdev = hw->priv; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_regd next_regd = {0}; + bool hdl; + + hdl = rtw_regd_state_hdl(rtwdev, &next_regd, request); + if (!hdl) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "regd state %d: ignore request %c%c of initiator %d\n", + rtwdev->regd.state, + request->alpha2[0], + request->alpha2[1], + request->initiator); + return; + } + + rtw_dbg(rtwdev, RTW_DBG_REGD, "regd state: %d -> %d\n", + rtwdev->regd.state, next_regd.state); + + mutex_lock(&rtwdev->mutex); + rtwdev->regd = next_regd; + rtw_dbg_regd_dump(rtwdev, "get alpha2 %c%c from initiator %d: ", + request->alpha2[0], + request->alpha2[1], + request->initiator); + + rtw_phy_adaptivity_set_mode(rtwdev); + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); + mutex_unlock(&rtwdev->mutex); +} + +u8 rtw_regd_get(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 band = hal->current_band_type; + + return band == RTW_BAND_2G ? + rtwdev->regd.regulatory->txpwr_regd_2g : + rtwdev->regd.regulatory->txpwr_regd_5g; +} +EXPORT_SYMBOL(rtw_regd_get); + +bool rtw_regd_srrc(struct rtw_dev *rtwdev) +{ + struct rtw_regd *regd = &rtwdev->regd; + + return rtw_reg_match(regd->regulatory, "CN"); +} +EXPORT_SYMBOL(rtw_regd_srrc); + +struct rtw_regd_alternative_t { + bool set; + u8 alt; +}; + +#define DECL_REGD_ALT(_regd, _regd_alt) \ + [(_regd)] = {.set = true, .alt = (_regd_alt)} + +static const struct rtw_regd_alternative_t +rtw_regd_alt[RTW_REGD_MAX] = { + DECL_REGD_ALT(RTW_REGD_IC, RTW_REGD_FCC), + DECL_REGD_ALT(RTW_REGD_KCC, RTW_REGD_ETSI), + DECL_REGD_ALT(RTW_REGD_ACMA, RTW_REGD_ETSI), + DECL_REGD_ALT(RTW_REGD_CHILE, RTW_REGD_FCC), + DECL_REGD_ALT(RTW_REGD_UKRAINE, RTW_REGD_ETSI), + DECL_REGD_ALT(RTW_REGD_MEXICO, RTW_REGD_FCC), + DECL_REGD_ALT(RTW_REGD_CN, RTW_REGD_ETSI), + DECL_REGD_ALT(RTW_REGD_QATAR, RTW_REGD_ETSI), + DECL_REGD_ALT(RTW_REGD_UK, RTW_REGD_ETSI), +}; + +bool rtw_regd_has_alt(u8 regd, u8 *regd_alt) +{ + if (!rtw_regd_alt[regd].set) + return false; + + *regd_alt = rtw_regd_alt[regd].alt; + return true; +} diff --git a/drivers/net/wireless/realtek/rtw88/regd.h b/drivers/net/wireless/realtek/rtw88/regd.h new file mode 100644 index 000000000..3c5a6fd8e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/regd.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_REGD_H_ +#define __RTW_REGD_H_ + +#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR +enum rtw_chplan_id { + RTW_CHPLAN_ETSI1_NULL = 0x21, + RTW_CHPLAN_WORLD_ETSI1 = 0x26, + RTW_CHPLAN_MKK1_MKK1 = 0x27, + RTW_CHPLAN_IC1_IC2 = 0x2B, + RTW_CHPLAN_WORLD_CHILE1 = 0x2D, + RTW_CHPLAN_WORLD_FCC3 = 0x30, + RTW_CHPLAN_WORLD_FCC5 = 0x32, + RTW_CHPLAN_FCC1_FCC7 = 0x34, + RTW_CHPLAN_WORLD_ETSI2 = 0x35, + RTW_CHPLAN_WORLD_ETSI3 = 0x36, + RTW_CHPLAN_ETSI1_ETSI12 = 0x3D, + RTW_CHPLAN_KCC1_KCC2 = 0x3E, + RTW_CHPLAN_ETSI1_ETSI4 = 0x42, + RTW_CHPLAN_FCC1_NCC3 = 0x44, + RTW_CHPLAN_WORLD_ACMA1 = 0x45, + RTW_CHPLAN_WORLD_ETSI6 = 0x47, + RTW_CHPLAN_WORLD_ETSI7 = 0x48, + RTW_CHPLAN_WORLD_ETSI8 = 0x49, + RTW_CHPLAN_KCC1_KCC3 = 0x4B, + RTW_CHPLAN_WORLD_ETSI10 = 0x51, + RTW_CHPLAN_WORLD_ETSI14 = 0x59, + RTW_CHPLAN_FCC2_FCC7 = 0x61, + RTW_CHPLAN_FCC2_FCC1 = 0x62, + RTW_CHPLAN_WORLD_ETSI15 = 0x63, + RTW_CHPLAN_WORLD_FCC7 = 0x73, + RTW_CHPLAN_FCC2_FCC17 = 0x74, + RTW_CHPLAN_WORLD_ETSI20 = 0x75, + RTW_CHPLAN_FCC2_FCC11 = 0x76, + RTW_CHPLAN_REALTEK_DEFINE = 0x7f, +}; + +struct country_code_to_enum_rd { + u16 countrycode; + const char *iso_name; +}; + +enum country_code_type { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + COUNTRY_CODE_WORLD_WIDE_13_5G_ALL = 13, + + /* new channel plan above this */ + COUNTRY_CODE_MAX +}; + +int rtw_regd_init(struct rtw_dev *rtwdev); +int rtw_regd_hint(struct rtw_dev *rtwdev); +u8 rtw_regd_get(struct rtw_dev *rtwdev); +bool rtw_regd_has_alt(u8 regd, u8 *regd_alt); +bool rtw_regd_srrc(struct rtw_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c new file mode 100644 index 000000000..b5e7ae7eb --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c @@ -0,0 +1,2008 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright Fiona Klute */ + +#include +#include "main.h" +#include "coex.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rx.h" +#include "rtw8703b.h" +#include "rtw8703b_tables.h" +#include "rtw8723x.h" + +#define BIT_MASK_TXQ_INIT (BIT(7)) +#define WLAN_RL_VAL 0x3030 +/* disable BAR */ +#define WLAN_BAR_VAL 0x0201ffff +#define WLAN_PIFS_VAL 0 +#define WLAN_RX_PKT_LIMIT 0x18 +#define WLAN_SLOT_TIME 0x09 +#define WLAN_SPEC_SIFS 0x100a +#define WLAN_MAX_AGG_NR 0x1f +#define WLAN_AMPDU_MAX_TIME 0x70 + +/* unit is 32us */ +#define TBTT_PROHIBIT_SETUP_TIME 0x04 +#define TBTT_PROHIBIT_HOLD_TIME 0x80 +#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64 + +#define TRANS_SEQ_END \ + 0xFFFF, \ + RTW_PWR_CUT_ALL_MSK, \ + RTW_PWR_INTF_ALL_MSK, \ + 0, \ + RTW_PWR_CMD_END, 0, 0 + +/* rssi in percentage % (dbm = % - 100) */ +/* These are used to select simple signal quality levels, might need + * tweaking. Same for rf_para tables below. + */ +static const u8 wl_rssi_step_8703b[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8703b[] = {30, 30, 30, 30}; +static const struct coex_5g_afh_map afh_5g_8703b[] = { {0, 0, 0} }; + +/* Actually decreasing wifi TX power/RX gain isn't implemented in + * rtw8703b, but hopefully adjusting the BT side helps. + */ +static const struct coex_rf_para rf_para_tx_8703b[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 4}, + {1, 2, true, 4}, + {1, 10, true, 4}, + {1, 15, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8703b[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 5}, + {1, 2, true, 5}, + {1, 10, true, 5}, + {1, 15, true, 5} +}; + +static const u32 rtw8703b_ofdm_swing_table[] = { + 0x0b40002d, /* 0, -15.0dB */ + 0x0c000030, /* 1, -14.5dB */ + 0x0cc00033, /* 2, -14.0dB */ + 0x0d800036, /* 3, -13.5dB */ + 0x0e400039, /* 4, -13.0dB */ + 0x0f00003c, /* 5, -12.5dB */ + 0x10000040, /* 6, -12.0dB */ + 0x11000044, /* 7, -11.5dB */ + 0x12000048, /* 8, -11.0dB */ + 0x1300004c, /* 9, -10.5dB */ + 0x14400051, /* 10, -10.0dB */ + 0x15800056, /* 11, -9.5dB */ + 0x16c0005b, /* 12, -9.0dB */ + 0x18000060, /* 13, -8.5dB */ + 0x19800066, /* 14, -8.0dB */ + 0x1b00006c, /* 15, -7.5dB */ + 0x1c800072, /* 16, -7.0dB */ + 0x1e400079, /* 17, -6.5dB */ + 0x20000080, /* 18, -6.0dB */ + 0x22000088, /* 19, -5.5dB */ + 0x24000090, /* 20, -5.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x288000a2, /* 22, -4.0dB */ + 0x2ac000ab, /* 23, -3.5dB */ + 0x2d4000b5, /* 24, -3.0dB */ + 0x300000c0, /* 25, -2.5dB */ + 0x32c000cb, /* 26, -2.0dB */ + 0x35c000d7, /* 27, -1.5dB */ + 0x390000e4, /* 28, -1.0dB */ + 0x3c8000f2, /* 29, -0.5dB */ + 0x40000100, /* 30, +0dB */ + 0x43c0010f, /* 31, +0.5dB */ + 0x47c0011f, /* 32, +1.0dB */ + 0x4c000130, /* 33, +1.5dB */ + 0x50800142, /* 34, +2.0dB */ + 0x55400155, /* 35, +2.5dB */ + 0x5a400169, /* 36, +3.0dB */ + 0x5fc0017f, /* 37, +3.5dB */ + 0x65400195, /* 38, +4.0dB */ + 0x6b8001ae, /* 39, +4.5dB */ + 0x71c001c7, /* 40, +5.0dB */ + 0x788001e2, /* 41, +5.5dB */ + 0x7f8001fe /* 42, +6.0dB */ +}; + +static const u32 rtw8703b_cck_pwr_regs[] = { + 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29, + 0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3, +}; + +static const u8 rtw8703b_cck_swing_table[][16] = { + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +#define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_ofdm_swing_table) +#define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_cck_swing_table) + +static const struct rtw_pwr_seq_cmd trans_pre_enable_8703b[] = { + /* set up external crystal (XTAL) */ + {REG_PAD_CTRL1 + 2, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + /* set CLK_REQ to high active */ + {0x0069, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + /* unlock ISO/CLK/power control register */ + {REG_RSV_CTRL, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8703b[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8703b[] = { + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK | RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8703b[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0004, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0004, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + /* wait for power ready */ + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0063, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0058, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x005A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0068, + RTW_PWR_CUT_TEST_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0069, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8703b[] = { + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_reset_mcu_8703b[] = { + {REG_SYS_FUNC_EN + 1, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT_FEN_CPUEN, 0}, + /* reset MCU ready */ + {REG_MCUFW_CTRL, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0}, + /* reset MCU IO wrapper */ + {REG_RSV_CTRL + 1, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {REG_RSV_CTRL + 1, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 1}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = { + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0xff}, + {0x0522, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0xff}, + {0x05f8, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xff, 0}, + {0x05f9, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xff, 0}, + {0x05fa, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xff, 0}, + {0x05fb, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xff, 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0100, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0x03}, + {0x0101, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xff, 0}, + {0x0553, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {TRANS_SEQ_END}, +}; + +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = { + trans_pre_enable_8703b, + trans_carddis_to_cardemu_8703b, + trans_cardemu_to_act_8703b, + NULL +}; + +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = { + trans_act_to_lps_8703b, + trans_act_to_reset_mcu_8703b, + trans_act_to_cardemu_8703b, + trans_cardemu_to_carddis_8703b, + NULL +}; + +static const struct rtw_page_table page_table_8703b[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +}; + +static const struct rtw_rqpn rqpn_table_8703b[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static void try_mac_from_devicetree(struct rtw_dev *rtwdev) +{ + struct device_node *node = rtwdev->dev->of_node; + struct rtw_efuse *efuse = &rtwdev->efuse; + int ret; + + if (node) { + ret = of_get_mac_address(node, efuse->addr); + if (ret == 0) { + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "got wifi mac address from DT: %pM\n", + efuse->addr); + } + } +} + +static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + int ret; + + ret = rtw8723x_read_efuse(rtwdev, log_map); + if (ret != 0) + return ret; + + if (!is_valid_ether_addr(efuse->addr)) + try_mac_from_devicetree(rtwdev); + + return 0; +} + +static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + /* TODO: The vendor driver selects these using tables in + * halrf_powertracking_ce.c, functions are called + * get_swing_index and get_cck_swing_index. There the current + * fixed values are only the defaults in case no match is + * found. + */ + dm_info->default_ofdm_index = 30; + dm_info->default_cck_index = 20; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; + dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; +} + +static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) +{ + u8 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + + /* power on BB/RF domain */ + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780); + rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); + + rtw_phy_load_tables(rtwdev); + + rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); + /* 0xff is from vendor driver, rtw8723d uses + * BIT_HIQ_NO_LMT_EN_ROOT. Comment in vendor driver: "Packet + * in Hi Queue Tx immediately". I wonder if setting all bits + * is really necessary. + */ + rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); + rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); + + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); + + /* Init EDCA */ + rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); /* CCK */ + rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); /* OFDM */ + /* TXOP */ + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); + + /* Init retry */ + rtw_write8(rtwdev, REG_ACKTO, 0x40); + + /* Set up RX aggregation. sdio.c also sets DMA mode, but not + * the burst parameters. + */ + rtw_write8(rtwdev, REG_RXDMA_MODE, + BIT_DMA_MODE | + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) | + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE)); + + /* Init beacon parameters */ + rtw_write8(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); + rtw_write8(rtwdev, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME); + rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1, + TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF); + rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2, + (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xF0) + | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8)); + + /* configure packet burst */ + rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); + rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT_MASK_TXQ_INIT); + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); + + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); + rtw_write16(rtwdev, REG_ATIMWND, 0x2); + + rtw_phy_init(rtwdev); + + if (rtw_read32_mask(rtwdev, REG_BB_AMP, BIT_MASK_RX_LNA) != 0) { + rtwdev->dm_info.rx_cck_agc_report_type = 1; + } else { + rtwdev->dm_info.rx_cck_agc_report_type = 0; + rtw_warn(rtwdev, "unexpected cck agc report type"); + } + + rtw8723x_lck(rtwdev); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); + + rtw8703b_pwrtrack_init(rtwdev); +} + +static bool rtw8703b_check_spur_ov_thres(struct rtw_dev *rtwdev, + u32 freq, u32 thres) +{ + bool ret = false; + + rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); + + msleep(30); + if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) + ret = true; + + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); + + return ret; +} + +static void rtw8703b_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) +{ + if (!notch) { + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); + return; + } + + switch (channel) { + case 5: + fallthrough; + case 13: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x06000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 6: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x4); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000600); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 7: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x3); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x06000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 8: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xa); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000380); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 14: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00180000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + default: + rtw_warn(rtwdev, + "Bug: Notch filter enable called for channel %u!", + channel); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); + break; + } +} + +static void rtw8703b_spur_cal(struct rtw_dev *rtwdev, u8 channel) +{ + bool notch; + u32 freq; + + if (channel == 5) { + freq = FREQ_CH5; + } else if (channel == 6) { + freq = FREQ_CH6; + } else if (channel == 7) { + freq = FREQ_CH7; + } else if (channel == 8) { + freq = FREQ_CH8; + } else if (channel == 13) { + freq = FREQ_CH13; + } else if (channel == 14) { + freq = FREQ_CH14; + } else { + rtw8703b_cfg_notch(rtwdev, channel, false); + return; + } + + notch = rtw8703b_check_spur_ov_thres(rtwdev, freq, SPUR_THRES); + rtw8703b_cfg_notch(rtwdev, channel, notch); +} + +static void rtw8703b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u32 rf_cfgch_a; + u32 rf_cfgch_b; + /* default value for 20M */ + u32 rf_rck = 0x00000C08; + + rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); + + rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); + rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); + + rf_cfgch_a &= ~RFCFGCH_BW_MASK; + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rf_cfgch_a |= RFCFGCH_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_cfgch_a |= RFCFGCH_BW_40M; + rf_rck = 0x00000C4C; + break; + default: + break; + } + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a); + rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK, rf_rck); + rtw8703b_spur_cal(rtwdev, channel); +} + +#define CCK_DFIR_NR_8703B 2 +static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR_8703B] = { + [0] = { + { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x5A7DA0BD }, + { .len = 4, .reg = REG_CCK_DBG, .val = 0x0000223B }, + }, + [1] = { + { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x00000000 }, + { .len = 4, .reg = REG_CCK_DBG, .val = 0x00000000 }, + }, +}; + +static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + const struct rtw_backup_info *cck_dfir; + int i; + + cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; + + for (i = 0; i < CCK_DFIR_NR_8703B; i++, cck_dfir++) + rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE, + GENMASK(31, 30), 0x0); + rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32(rtwdev, REG_BBRX_DFIR, 0x40100000); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x51F60000); + rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, + primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, 0xC00, + primary_ch_idx == RTW_SC_20_UPPER ? 2 : 1); + + rtw_write32_mask(rtwdev, REG_BB_PWR_SAV5_11N, GENMASK(27, 26), + primary_ch_idx == RTW_SC_20_UPPER ? 1 : 2); + break; + default: + break; + } +} + +static void rtw8703b_set_channel(struct rtw_dev *rtwdev, u8 channel, + u8 bw, u8 primary_chan_idx) +{ + rtw8703b_set_channel_rf(rtwdev, channel, bw); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8703b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); +} + +/* Not all indices are valid, based on available data. None of the + * known valid values are positive, so use 0x7f as "invalid". + */ +#define LNA_IDX_INVALID 0x7f +static const s8 lna_gain_table[16] = { + -2, LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, + -6, LNA_IDX_INVALID, LNA_IDX_INVALID, -19, + -32, LNA_IDX_INVALID, -36, -42, + LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, -48, +}; + +static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) +{ + s8 lna_gain = 0; + + if (lna_idx < ARRAY_SIZE(lna_gain_table)) + lna_gain = lna_gain_table[lna_idx]; + + if (lna_gain >= 0) { + rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); + return -120; + } + + return lna_gain - 2 * vga_idx; +} + +static void query_phy_status_cck(struct rtw_dev *rtwdev, u8 *phy_raw, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; + u8 vga_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & VGA_BITS; + u8 lna_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & LNA_L_BITS; + s8 rx_power; + + if (rtwdev->dm_info.rx_cck_agc_report_type == 1) + lna_idx = FIELD_PREP(BIT_LNA_H_MASK, + phy_status->cck_rpt_b_ofdm_cfosho_b & LNA_H_BIT) + | FIELD_PREP(BIT_LNA_L_MASK, lna_idx); + else + lna_idx = FIELD_PREP(BIT_LNA_L_MASK, lna_idx); + rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx); + + pkt_stat->rx_power[RF_PATH_A] = rx_power; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->signal_power = rx_power; +} + +static void query_phy_status_ofdm(struct rtw_dev *rtwdev, u8 *phy_raw, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 val_s8; + + val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F; + pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2); + + /* signal power reported by HW */ + val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1; + pkt_stat->signal_power = (val_s8 & 0x7f) - 110; + + pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A]; + pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A]; + + dm_info->curr_rx_rate = pkt_stat->rate; + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; + /* convert to KHz (used only for debugfs) */ + dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; + + /* (EVM value as s8 / 2) is dbm, should usually be in -33 to 0 + * range. rx_evm_dbm needs the absolute (positive) value. + */ + val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A]; + val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64); + val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ + dm_info->rx_evm_dbm[RF_PATH_A] = val_s8; +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + if (pkt_stat->rate <= DESC_RATE11M) + query_phy_status_cck(rtwdev, phy_status, pkt_stat); + else + query_phy_status_ofdm(rtwdev, phy_status, pkt_stat); +} + +#define ADDA_ON_VAL_8703B 0x03c00014 + +static +void rtw8703b_iqk_config_mac(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[0], 0x3F); + for (int i = 1; i < RTW8723X_IQK_MAC8_REG_NUM; i++) + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], + backup->mac8[i] & (~BIT(3))); +} + +#define IQK_LTE_WRITE_VAL_8703B 0x00007700 +#define IQK_DELAY_TIME_8703B 4 + +static void rtw8703b_iqk_one_shot(struct rtw_dev *rtwdev, bool tx) +{ + u32 regval; + ktime_t t; + s64 dur; + int ret; + + /* enter IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); + + /* One shot, LOK & IQK */ + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); + + t = ktime_get(); + msleep(IQK_DELAY_TIME_8703B); + ret = read_poll_timeout(rtw_read32, regval, regval != 0, 1000, + 100000, false, rtwdev, + REG_IQK_RDY); + dur = ktime_us_delta(ktime_get(), t); + + if (ret) + rtw_warn(rtwdev, "[IQK] %s timed out after %lldus!\n", + tx ? "TX" : "RX", dur); + else + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] %s done after %lldus\n", + tx ? "TX" : "RX", dur); +} + +static void rtw8703b_iqk_txrx_path_post(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); + + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x0); +} + +static u8 rtw8703b_iqk_check_tx_failed(struct rtw_dev *rtwdev) +{ + s32 tx_x, tx_y; + u32 tx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_TX), + rtw_read32(rtwdev, REG_IQK_RES_TY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xe90(before IQK) = 0x%x, 0xe98(after IQK) = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RDY), + rtw_read32(rtwdev, 0xe98)); + + tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) + return IQK_TX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A TX IQK failed\n"); + + return 0; +} + +static u8 rtw8703b_iqk_check_rx_failed(struct rtw_dev *rtwdev) +{ + s32 rx_x, rx_y; + u32 rx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RX), + rtw_read32(rtwdev, REG_IQK_RES_RY)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xea0(before IQK) = 0x%x, 0xea8(after IQK) = 0x%x\n", + rtw_read32(rtwdev, 0xea0), + rtw_read32(rtwdev, 0xea8)); + + rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); + rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + rx_y = abs(iqkxy_to_s32(rx_y)); + + if (!rx_fail && rx_x != IQK_RX_X_ERR && rx_y != IQK_RX_Y_ERR && + rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && + rx_y < IQK_RX_Y_LMT) + return IQK_RX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A RX IQK failed\n"); + + return 0; +} + +static u8 rtw8703b_iqk_tx_path(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u8 status; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n"); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); + + /* LO calibration setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); + + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); + + /* PA, PAD setting */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x7); + rtw_write_rf(rtwdev, RF_PATH_A, 0x7f, RFREG_MASK, 0xd400); + + rtw8703b_iqk_one_shot(rtwdev, true); + status = rtw8703b_iqk_check_tx_failed(rtwdev); + + rtw8703b_iqk_txrx_path_post(rtwdev, backup); + + return status; +} + +static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u8 status; + u32 tx_x, tx_y; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 1!\n"); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK1 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x99000000); + + /* disable IQC mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + /* path IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); + + /* RX IQK mode */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); + rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0x57db7); + + rtw8703b_iqk_one_shot(rtwdev, true); + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); + status = rtw8703b_iqk_check_tx_failed(rtwdev); + + if (!status) + goto restore; + + /* second round */ + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQK_11N), + BIT_SET_TXIQK_11N(tx_x, tx_y)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 2!\n"); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK 2 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + + /* IQK setting */ + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82110000); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160c1f); + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); + + /* LO calibration setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); + + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); + /* modify RX IQK mode table */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); + /* RF_RCK_OS, RF_TXPA_G1, RF_TXPA_G2 */ + rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); + rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0xf7d77); + + /* PA, PAD setting */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x5); + + rtw8703b_iqk_one_shot(rtwdev, false); + status |= rtw8703b_iqk_check_rx_failed(rtwdev); + +restore: + rtw8703b_iqk_txrx_path_post(rtwdev, backup); + + return status; +} + +static +void rtw8703b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u32 i; + u8 a_ok; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); + + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8703B); + rtw8703b_iqk_config_mac(rtwdev, backup); + rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); + rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05600); + rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); + rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204000); + + for (i = 0; i < PATH_IQK_RETRY; i++) { + a_ok = rtw8703b_iqk_tx_path(rtwdev, backup); + if (a_ok == IQK_TX_OK) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path A TX IQK success!\n"); + result[t][IQK_S1_TX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, + BIT_MASK_RES_TX); + result[t][IQK_S1_TX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, + BIT_MASK_RES_TY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n"); + result[t][IQK_S1_TX_X] = 0x100; + result[t][IQK_S1_TX_Y] = 0x0; + } + + for (i = 0; i < PATH_IQK_RETRY; i++) { + a_ok = rtw8703b_iqk_rx_path(rtwdev, backup); + if (a_ok == (IQK_TX_OK | IQK_RX_OK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path A RX IQK success!\n"); + result[t][IQK_S1_RX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, + BIT_MASK_RES_RX); + result[t][IQK_S1_RX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, + BIT_MASK_RES_RY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n"); + result[t][IQK_S1_RX_X] = 0x100; + result[t][IQK_S1_RX_Y] = 0x0; + } + + if (a_ok == 0x0) + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n"); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); +} + +static +void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[]) +{ + u32 tmp_rx_iqi = 0x40000100 & GENMASK(31, 16); + s32 tx1_a, tx1_a_ext; + s32 tx1_c, tx1_c_ext; + s32 oldval_1; + s32 x, y; + + if (result[IQK_S1_TX_X] == 0) + return; + + oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_D); + + x = iqkxy_to_s32(result[IQK_S1_TX_X]); + tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_A, tx1_a); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_A, tx1_a_ext); + + y = iqkxy_to_s32(result[IQK_S1_TX_Y]); + tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + BIT_SET_TXIQ_ELM_C1(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_C, tx1_c_ext); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", + x, tx1_a, oldval_1); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); + + if (result[IQK_S1_RX_X] == 0) + return; + + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]); + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_Y]); + rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi); + rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, + BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); +} + +static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev) +{ + /* For some reason path A is called S1 and B S0 in shared + * rtw88 calibration data. + */ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw8723x_iqk_backup_regs backup; + u8 final_candidate = IQK_ROUND_INVALID; + s32 result[IQK_ROUND_SIZE][IQK_NR]; + bool good; + u8 i, j; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n"); + + memset(result, 0, sizeof(result)); + + rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); + rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); + rtw8723x_iqk_backup_regs(rtwdev, &backup); + + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { + rtw8723x_iqk_config_path_ctrl(rtwdev); + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); + + rtw8703b_iqk_one_round(rtwdev, result, i, &backup); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] back to BB mode, load original values!\n"); + if (i > IQK_ROUND_0) + rtw8723x_iqk_restore_regs(rtwdev, &backup); + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); + rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); + + for (j = IQK_ROUND_0; j < i; j++) { + good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); + + if (good) { + final_candidate = j; + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] cmp %d:%d final_candidate is %x\n", + j, i, final_candidate); + goto iqk_done; + } + } + } + + if (final_candidate == IQK_ROUND_INVALID) { + s32 reg_tmp = 0; + + for (i = 0; i < IQK_NR; i++) + reg_tmp += result[IQK_ROUND_HYBRID][i]; + + if (reg_tmp != 0) { + final_candidate = IQK_ROUND_HYBRID; + } else { + WARN(1, "IQK failed\n"); + goto out; + } + } + +iqk_done: + /* only path A is calibrated in rtl8703b */ + rtw8703b_iqk_fill_a_matrix(rtwdev, result[final_candidate]); + + dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; + dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; + dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; + dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; + dm_info->iqk.done = true; + +out: + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", + final_candidate); + + for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", + i, + result[i][0], result[i][1], result[i][2], result[i][3], + result[i][4], result[i][5], result[i][6], result[i][7], + final_candidate == i ? "(final candidate)" : ""); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", + rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), + rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), + rtw_read32(rtwdev, REG_A_RXIQI), + rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQ_AB_S0), + rtw_read32(rtwdev, REG_TXIQ_CD_S0), + rtw_read32(rtwdev, REG_RXIQ_AB_S0)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Finished.\n"); +} + +static void rtw8703b_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, + u32 ofdm_swing, u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 ele_A, ele_D, ele_C; + s32 ele_A_ext, ele_C_ext, ele_D_ext; + s32 iqk_result_x; + s32 iqk_result_y; + s32 value32; + + switch (rf_path) { + default: + case RF_PATH_A: + iqk_result_x = dm_info->iqk.result.s1_x; + iqk_result_y = dm_info->iqk.result.s1_y; + break; + case RF_PATH_B: + iqk_result_x = dm_info->iqk.result.s0_x; + iqk_result_y = dm_info->iqk.result.s0_y; + break; + } + + /* new element D */ + ele_D = OFDM_SWING_D(ofdm_swing); + iqk_mult(iqk_result_x, ele_D, &ele_D_ext); + /* new element A */ + iqk_result_x = iqkxy_to_s32(iqk_result_x); + ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); + /* new element C */ + iqk_result_y = iqkxy_to_s32(iqk_result_y); + ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); + + switch (rf_path) { + case RF_PATH_A: + default: + /* write new elements A, C, D, and element B is always 0 */ + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + value32); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + /* write new elements A, C, D, and element B is always 0 */ + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); + rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, value32); + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, + value32); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS_B; + value32 |= BIT_SET_OFDM0_EXTS_B(ele_A_ext, ele_C_ext, ele_D_ext); + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + } +} + +static void rtw8703b_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, + u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 value32; + u32 ofdm_swing; + + ofdm_index = clamp_t(s8, ofdm_index, 0, RTW_OFDM_SWING_TABLE_SIZE - 1); + + ofdm_swing = rtw8703b_ofdm_swing_table[ofdm_index]; + + if (dm_info->iqk.done) { + rtw8703b_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); + return; + } + + switch (rf_path) { + case RF_PATH_A: + default: + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + 0x00); + + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, ofdm_swing); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, + 0x00); + + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS_B; + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + } +} + +static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + /* Only path A is calibrated for rtl8703b */ + rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); +} + +static void rtw8703b_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_cck = txagc_idx; + + swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1); + + BUILD_BUG_ON(ARRAY_SIZE(rtw8703b_cck_pwr_regs) + != ARRAY_SIZE(rtw8703b_cck_swing_table[0])); + + for (int i = 0; i < ARRAY_SIZE(rtw8703b_cck_pwr_regs); i++) + rtw_write8(rtwdev, rtw8703b_cck_pwr_regs[i], + rtw8703b_cck_swing_table[swing_idx][i]); +} + +static void rtw8703b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + u8 limit_ofdm; + u8 limit_cck = 21; + s8 final_ofdm_swing_index; + s8 final_cck_swing_index; + + limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); + + final_ofdm_swing_index = dm_info->default_ofdm_index + + dm_info->delta_power_index[path]; + final_cck_swing_index = dm_info->default_cck_index + + dm_info->delta_power_index[path]; + + if (final_ofdm_swing_index > limit_ofdm) + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, + final_ofdm_swing_index - limit_ofdm); + else if (final_ofdm_swing_index < 0) + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, 0, + final_ofdm_swing_index); + else + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); + + if (final_cck_swing_index > limit_cck) + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, limit_cck, + final_cck_swing_index - limit_cck); + else if (final_cck_swing_index < 0) + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, 0, + final_cck_swing_index); + else + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); + + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); +} + +static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, delta, path; + bool do_iqk = false; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (do_iqk) + rtw8723x_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + s8 delta_cur, delta_last; + + delta_last = dm_info->delta_power_index[path]; + delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, + path, RF_PATH_A, delta); + if (delta_last == delta_cur) + continue; + + dm_info->delta_power_index[path] = delta_cur; + rtw8703b_pwrtrack_set(rtwdev, path); + } + + rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); + +iqk: + if (do_iqk) + rtw8703b_phy_calibration(rtwdev); +} + +static void rtw8703b_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) { + rtw_warn(rtwdev, "unsupported power track type"); + return; + } + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8703b_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8703b_coex_set_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8703b_coex_set_gnt_debug(struct rtw_dev *rtwdev) +{ +} + +static void rtw8703b_coex_set_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_exist = false; + coex_rfe->ant_switch_with_bt = false; + coex_rfe->ant_switch_diversity = false; + coex_rfe->wlg_at_btg = true; + + /* disable LTE coex on wifi side */ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); +} + +static void rtw8703b_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ +} + +static void rtw8703b_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static const u8 rtw8703b_pwrtrk_2gb_n[] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8703b_pwrtrk_2gb_p[] = { + 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 +}; + +static const u8 rtw8703b_pwrtrk_2ga_n[] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8703b_pwrtrk_2ga_p[] = { + 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 +}; + +static const u8 rtw8703b_pwrtrk_2g_cck_b_n[] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8703b_pwrtrk_2g_cck_b_p[] = { + 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, + 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8703b_pwrtrk_2g_cck_a_n[] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8703b_pwrtrk_2g_cck_a_p[] = { + 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, + 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const s8 rtw8703b_pwrtrk_xtal_n[] = { + 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -3, -3, -3, -3, -3, + -4, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 +}; + +static const s8 rtw8703b_pwrtrk_xtal_p[] = { + 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, -1, -1, -1, + -2, -3, -7, -9, -10, -11, -14, -16, -18, -20, -22, -24, -26, -28, -30 +}; + +static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = { + .pwrtrk_2gb_n = rtw8703b_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8703b_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8703b_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8703b_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8703b_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8703b_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8703b_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8703b_pwrtrk_2g_cck_a_p, + .pwrtrk_xtal_n = rtw8703b_pwrtrk_xtal_n, + .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, +}; + +static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, }, +}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8703b[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, + {0x66555555, 0x6aaa5aaa}, + {0x66555555, 0xaaaa5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x55555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8703b[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} }, +}; + +static const struct rtw_chip_ops rtw8703b_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .mac_init = rtw8723x_mac_init, + .mac_postinit = rtw8723x_mac_postinit, + .dump_fw_crash = NULL, + .shutdown = NULL, + .read_efuse = rtw8703b_read_efuse, + .phy_set_param = rtw8703b_phy_set_param, + .set_channel = rtw8703b_set_channel, + .query_phy_status = query_phy_status, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8723x_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8723x_cfg_ldo25, + .efuse_grant = rtw8723x_efuse_grant, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw8723x_false_alarm_statistics, + .phy_calibration = rtw8703b_phy_calibration, + .dpk_track = NULL, + /* 8723d uses REG_CSRATIO to set dm_info.cck_pd_default, which + * is used in its cck_pd_set function. According to comments + * in the vendor driver code it doesn't exist in this chip + * generation, only 0xa0a ("ODM_CCK_PD_THRESH", which is only + * *written* to). + */ + .cck_pd_set = NULL, + .pwr_track = rtw8703b_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .adaptivity_init = NULL, + .adaptivity = NULL, + .cfo_init = NULL, + .cfo_track = NULL, + .config_tx_path = NULL, + .config_txrx_mode = NULL, + .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, + + /* for coex */ + .coex_set_init = rtw8723x_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8703b_coex_set_gnt_fix, + .coex_set_gnt_debug = rtw8703b_coex_set_gnt_debug, + .coex_set_rfe_type = rtw8703b_coex_set_rfe_type, + .coex_set_wl_tx_power = rtw8703b_coex_set_wl_tx_power, + .coex_set_wl_rx_gain = rtw8703b_coex_set_wl_rx_gain, +}; + +const struct rtw_chip_info rtw8703b_hw_spec = { + .ops = &rtw8703b_ops, + .id = RTW_CHIP_TYPE_8703B, + + .fw_name = "rtw88/rtw8703b_fw.bin", + .wlan_cpu = RTW_WCPU_8051, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 256, + .log_efuse_size = 512, + .ptct_efuse_size = 15, + .txff_size = 32768, + .rxff_size = 16384, + .rsvd_drv_pg_num = 8, + .band = RTW_BAND_2G, + .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, + .dig_min = 0x20, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = false, + .tx_stbc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, + .c2h_ra_report_size = 7, + .old_datarate_fb_limit = true, + + .path_div_supported = false, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, + + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8703b, + .pwr_off_seq = card_disable_flow_8703b, + .rqpn_table = rqpn_table_8703b, + .prioq_addrs = &rtw8723x_common.prioq_addrs, + .page_table = page_table_8703b, + /* used only in pci.c, not needed for SDIO devices */ + .intf_table = NULL, + + .dig = rtw8723x_common.dig, + .dig_cck = rtw8723x_common.dig_cck, + + .rf_sipi_addr = {0x840, 0x844}, + .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, + .fix_rf_phy_num = 2, + .ltecoex_addr = &rtw8723x_common.ltecoex_addr, + + .mac_tbl = &rtw8703b_mac_tbl, + .agc_tbl = &rtw8703b_agc_tbl, + .bb_tbl = &rtw8703b_bb_tbl, + .rf_tbl = {&rtw8703b_rf_a_tbl}, + + .rfe_defs = rtw8703b_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), + + .iqk_threshold = 8, + + /* WOWLAN firmware exists, but not implemented yet */ + .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", + .wowlan_stub = NULL, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + /* Vendor driver has a time-based format, converted from + * 20180330 + */ + .coex_para_ver = 0x0133ed6a, + .bt_desired_ver = 0x1c, + .scbd_support = true, + .new_scbd10_def = true, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .bt_rssi_step = bt_rssi_step_8703b, + .wl_rssi_step = wl_rssi_step_8703b, + /* sant -> shared antenna, nsant -> non-shared antenna + * Not sure if 8703b versions with non-shard antenna even exist. + */ + .table_sant_num = ARRAY_SIZE(table_sant_8703b), + .table_sant = table_sant_8703b, + .table_nsant_num = 0, + .table_nsant = NULL, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8703b), + .tdma_sant = tdma_sant_8703b, + .tdma_nsant_num = 0, + .tdma_nsant = NULL, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8703b), + .wl_rf_para_tx = rf_para_tx_8703b, + .wl_rf_para_rx = rf_para_rx_8703b, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = ARRAY_SIZE(afh_5g_8703b), + .afh_5g = afh_5g_8703b, + /* REG_BTG_SEL doesn't seem to have a counterpart in the + * vendor driver. Mathematically it's REG_PAD_CTRL1 + 3. + * + * It is used in the cardemu_to_act power sequence by though + * (by address, 0x0067), comment: "0x67[0] = 0 to disable + * BT_GPS_SEL pins" That seems to fit. + */ + .btg_reg = NULL, + /* These registers are used to read (and print) from if + * CONFIG_RTW88_DEBUGFS is enabled. + */ + .coex_info_hw_regs_num = 0, + .coex_info_hw_regs = NULL, +}; +EXPORT_SYMBOL(rtw8703b_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8703b_fw.bin"); +MODULE_FIRMWARE("rtw88/rtw8703b_wow_fw.bin"); + +MODULE_AUTHOR("Fiona Klute "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8703b driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.h b/drivers/net/wireless/realtek/rtw88/rtw8703b.h new file mode 100644 index 000000000..3e2da2e67 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright Fiona Klute */ + +#ifndef __RTW8703B_H__ +#define __RTW8703B_H__ + +#include "rtw8723x.h" + +extern const struct rtw_chip_info rtw8703b_hw_spec; + +/* phy status parsing */ +#define VGA_BITS GENMASK(4, 0) +#define LNA_L_BITS GENMASK(7, 5) +#define LNA_H_BIT BIT(7) +/* masks for assembling LNA index from high and low bits */ +#define BIT_LNA_H_MASK BIT(3) +#define BIT_LNA_L_MASK GENMASK(2, 0) + +struct phy_rx_agc_info { +#ifdef __LITTLE_ENDIAN + u8 gain: 7; + u8 trsw: 1; +#else + u8 trsw: 1; + u8 gain: 7; +#endif +} __packed; + +/* This struct is called phy_status_rpt_8192cd in the vendor driver, + * there might be potential to share it with drivers for other chips + * of the same generation. + */ +struct phy_status_8703b { + struct phy_rx_agc_info path_agc[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + /* for CCK: bits 0:4: VGA index, bits 5:7: LNA index (low) */ + u8 cck_agc_rpt_ofdm_cfosho_a; + /* for CCK: bit 7 is high bit of LNA index if long report type */ + u8 cck_rpt_b_ofdm_cfosho_b; + u8 reserved_1; + u8 noise_power_db_msb; + s8 path_cfotail[2]; + u8 pcts_mask[2]; + s8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 reserved_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + s8 sig_evm; + u8 reserved_3; + +#ifdef __LITTLE_ENDIAN + u8 antsel_rx_keep_2: 1; + u8 sgi_en: 1; + u8 rxsc: 2; + u8 idle_long: 1; + u8 r_ant_train_en: 1; + u8 ant_sel_b: 1; + u8 ant_sel: 1; +#else /* __BIG_ENDIAN */ + u8 ant_sel: 1; + u8 ant_sel_b: 1; + u8 r_ant_train_en: 1; + u8 idle_long: 1; + u8 rxsc: 2; + u8 sgi_en: 1; + u8 antsel_rx_keep_2: 1; +#endif +} __packed; + +/* Baseband registers */ +#define REG_BB_PWR_SAV5_11N 0x0818 +/* BIT(11) should be 1 for 8703B *and* 8723D, which means LNA uses 4 + * bit for CCK rates in report, not 3. Vendor driver logs a warning if + * it's 0, but handles the case. + * + * Purpose of other parts of this register is unknown, 8723cs driver + * code indicates some other chips use certain bits for antenna + * diversity. + */ +#define REG_BB_AMP 0x0950 +#define BIT_MASK_RX_LNA (BIT(11)) + +/* 0xaXX: 40MHz channel settings */ +#define REG_CCK_TXSF2 0x0a24 /* CCK TX filter 2 */ +#define REG_CCK_DBG 0x0a28 /* debug port */ +#define REG_OFDM0_A_TX_AFE 0x0c84 +#define REG_TXIQK_MATRIXB_LSB2_11N 0x0c9c +#define REG_OFDM0_TX_PSD_NOISE 0x0ce4 /* TX pseudo noise weighting */ +#define REG_IQK_RDY 0x0e90 /* is != 0 when IQK is done */ + +/* RF registers */ +#define RF_RCK1 0x1E + +#define AGG_BURST_NUM 3 +#define AGG_BURST_SIZE 0 /* 1K */ +#define BIT_MASK_AGG_BURST_NUM (GENMASK(3, 2)) +#define BIT_MASK_AGG_BURST_SIZE (GENMASK(5, 4)) + +#endif /* __RTW8703B_H__ */ diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c new file mode 100644 index 000000000..81020fd90 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c @@ -0,0 +1,902 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright Fiona Klute */ + +#include "main.h" +#include "phy.h" +#include "rtw8703b_tables.h" + +static const struct rtw_phy_pg_cfg_pair rtw8703b_bb_pg[] = { + { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, }, + { 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, }, + { 0, 0, 0, 0x00000e00, 0xffffffff, 0x34363636, }, + { 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000e10, 0xffffffff, 0x30343434, }, + { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26262830, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8703b_bb_pg); + +/* Regd: FCC -> 0, ETSI -> 2, MKK -> 1 + * Band: 2.4G -> 0, 5G -> 1 + * Bandwidth (bw): 20M -> 0, 40M -> 1, 80M -> 2, 160M -> 3 + * Rate Section (rs): CCK -> 0, OFDM -> 1, HT -> 2, VHT -> 3 + */ +static const struct rtw_txpwr_lmt_cfg_pair rtw8703b_txpwr_lmt[] = { + {0, 0, 0, 0, 1, 30}, + {2, 0, 0, 0, 1, 26}, + {1, 0, 0, 0, 1, 32}, + {0, 0, 0, 0, 2, 30}, + {2, 0, 0, 0, 2, 26}, + {1, 0, 0, 0, 2, 32}, + {0, 0, 0, 0, 3, 30}, + {2, 0, 0, 0, 3, 26}, + {1, 0, 0, 0, 3, 32}, + {0, 0, 0, 0, 4, 30}, + {2, 0, 0, 0, 4, 26}, + {1, 0, 0, 0, 4, 32}, + {0, 0, 0, 0, 5, 30}, + {2, 0, 0, 0, 5, 26}, + {1, 0, 0, 0, 5, 32}, + {0, 0, 0, 0, 6, 30}, + {2, 0, 0, 0, 6, 26}, + {1, 0, 0, 0, 6, 32}, + {0, 0, 0, 0, 7, 30}, + {2, 0, 0, 0, 7, 26}, + {1, 0, 0, 0, 7, 32}, + {0, 0, 0, 0, 8, 30}, + {2, 0, 0, 0, 8, 26}, + {1, 0, 0, 0, 8, 32}, + {0, 0, 0, 0, 9, 30}, + {2, 0, 0, 0, 9, 26}, + {1, 0, 0, 0, 9, 32}, + {0, 0, 0, 0, 10, 30}, + {2, 0, 0, 0, 10, 26}, + {1, 0, 0, 0, 10, 32}, + {0, 0, 0, 0, 11, 30}, + {2, 0, 0, 0, 11, 26}, + {1, 0, 0, 0, 11, 32}, + {0, 0, 0, 0, 12, 63}, + {2, 0, 0, 0, 12, 26}, + {1, 0, 0, 0, 12, 32}, + {0, 0, 0, 0, 13, 63}, + {2, 0, 0, 0, 13, 26}, + {1, 0, 0, 0, 13, 32}, + {0, 0, 0, 0, 14, 63}, + {2, 0, 0, 0, 14, 63}, + {1, 0, 0, 0, 14, 32}, + {0, 0, 0, 1, 1, 28}, + {2, 0, 0, 1, 1, 28}, + {1, 0, 0, 1, 1, 28}, + {0, 0, 0, 1, 2, 28}, + {2, 0, 0, 1, 2, 32}, + {1, 0, 0, 1, 2, 32}, + {0, 0, 0, 1, 3, 32}, + {2, 0, 0, 1, 3, 32}, + {1, 0, 0, 1, 3, 32}, + {0, 0, 0, 1, 4, 32}, + {2, 0, 0, 1, 4, 32}, + {1, 0, 0, 1, 4, 32}, + {0, 0, 0, 1, 5, 32}, + {2, 0, 0, 1, 5, 32}, + {1, 0, 0, 1, 5, 32}, + {0, 0, 0, 1, 6, 32}, + {2, 0, 0, 1, 6, 32}, + {1, 0, 0, 1, 6, 32}, + {0, 0, 0, 1, 7, 32}, + {2, 0, 0, 1, 7, 32}, + {1, 0, 0, 1, 7, 32}, + {0, 0, 0, 1, 8, 32}, + {2, 0, 0, 1, 8, 32}, + {1, 0, 0, 1, 8, 32}, + {0, 0, 0, 1, 9, 32}, + {2, 0, 0, 1, 9, 32}, + {1, 0, 0, 1, 9, 32}, + {0, 0, 0, 1, 10, 28}, + {2, 0, 0, 1, 10, 32}, + {1, 0, 0, 1, 10, 32}, + {0, 0, 0, 1, 11, 28}, + {2, 0, 0, 1, 11, 32}, + {1, 0, 0, 1, 11, 32}, + {0, 0, 0, 1, 12, 63}, + {2, 0, 0, 1, 12, 32}, + {1, 0, 0, 1, 12, 32}, + {0, 0, 0, 1, 13, 63}, + {2, 0, 0, 1, 13, 28}, + {1, 0, 0, 1, 13, 28}, + {0, 0, 0, 1, 14, 63}, + {2, 0, 0, 1, 14, 63}, + {1, 0, 0, 1, 14, 63}, + {0, 0, 0, 2, 1, 26}, + {2, 0, 0, 2, 1, 26}, + {1, 0, 0, 2, 1, 28}, + {0, 0, 0, 2, 2, 26}, + {2, 0, 0, 2, 2, 32}, + {1, 0, 0, 2, 2, 32}, + {0, 0, 0, 2, 3, 32}, + {2, 0, 0, 2, 3, 32}, + {1, 0, 0, 2, 3, 32}, + {0, 0, 0, 2, 4, 32}, + {2, 0, 0, 2, 4, 32}, + {1, 0, 0, 2, 4, 32}, + {0, 0, 0, 2, 5, 32}, + {2, 0, 0, 2, 5, 32}, + {1, 0, 0, 2, 5, 32}, + {0, 0, 0, 2, 6, 32}, + {2, 0, 0, 2, 6, 32}, + {1, 0, 0, 2, 6, 32}, + {0, 0, 0, 2, 7, 32}, + {2, 0, 0, 2, 7, 32}, + {1, 0, 0, 2, 7, 32}, + {0, 0, 0, 2, 8, 32}, + {2, 0, 0, 2, 8, 32}, + {1, 0, 0, 2, 8, 32}, + {0, 0, 0, 2, 9, 32}, + {2, 0, 0, 2, 9, 32}, + {1, 0, 0, 2, 9, 32}, + {0, 0, 0, 2, 10, 26}, + {2, 0, 0, 2, 10, 32}, + {1, 0, 0, 2, 10, 32}, + {0, 0, 0, 2, 11, 26}, + {2, 0, 0, 2, 11, 32}, + {1, 0, 0, 2, 11, 32}, + {0, 0, 0, 2, 12, 63}, + {2, 0, 0, 2, 12, 32}, + {1, 0, 0, 2, 12, 32}, + {0, 0, 0, 2, 13, 63}, + {2, 0, 0, 2, 13, 26}, + {1, 0, 0, 2, 13, 28}, + {0, 0, 0, 2, 14, 63}, + {2, 0, 0, 2, 14, 63}, + {1, 0, 0, 2, 14, 63}, + {0, 0, 1, 2, 1, 63}, + {2, 0, 1, 2, 1, 63}, + {1, 0, 1, 2, 1, 63}, + {0, 0, 1, 2, 2, 63}, + {2, 0, 1, 2, 2, 63}, + {1, 0, 1, 2, 2, 63}, + {0, 0, 1, 2, 3, 26}, + {2, 0, 1, 2, 3, 26}, + {1, 0, 1, 2, 3, 26}, + {0, 0, 1, 2, 4, 26}, + {2, 0, 1, 2, 4, 28}, + {1, 0, 1, 2, 4, 26}, + {0, 0, 1, 2, 5, 28}, + {2, 0, 1, 2, 5, 28}, + {1, 0, 1, 2, 5, 26}, + {0, 0, 1, 2, 6, 28}, + {2, 0, 1, 2, 6, 28}, + {1, 0, 1, 2, 6, 26}, + {0, 0, 1, 2, 7, 28}, + {2, 0, 1, 2, 7, 28}, + {1, 0, 1, 2, 7, 26}, + {0, 0, 1, 2, 8, 26}, + {2, 0, 1, 2, 8, 28}, + {1, 0, 1, 2, 8, 26}, + {0, 0, 1, 2, 9, 26}, + {2, 0, 1, 2, 9, 28}, + {1, 0, 1, 2, 9, 26}, + {0, 0, 1, 2, 10, 26}, + {2, 0, 1, 2, 10, 28}, + {1, 0, 1, 2, 10, 26}, + {0, 0, 1, 2, 11, 26}, + {2, 0, 1, 2, 11, 26}, + {1, 0, 1, 2, 11, 26}, + {0, 0, 1, 2, 12, 63}, + {2, 0, 1, 2, 12, 26}, + {1, 0, 1, 2, 12, 26}, + {0, 0, 1, 2, 13, 63}, + {2, 0, 1, 2, 13, 26}, + {1, 0, 1, 2, 13, 26}, + {0, 0, 1, 2, 14, 63}, + {2, 0, 1, 2, 14, 63}, + {1, 0, 1, 2, 14, 63}, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8703b_txpwr_lmt); + +static const u32 rtw8703b_mac[] = { + 0x02F, 0x00000030, + 0x035, 0x00000000, + 0x067, 0x00000002, + 0x092, 0x00000080, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000002, + 0x435, 0x00000003, + 0x436, 0x00000005, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43A, 0x00000000, + 0x43B, 0x00000001, + 0x43C, 0x00000002, + 0x43D, 0x00000003, + 0x43E, 0x00000005, + 0x43F, 0x00000007, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000028, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000028, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000C, + 0x63F, 0x0000000C, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66A, 0x000000B0, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x765, 0x00000018, + 0x76E, 0x00000004, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8703b_mac, rtw_phy_cfg_mac); + +static const u32 rtw8703b_agc[] = { + 0xC78, 0xFC000101, + 0xC78, 0xFB010101, + 0xC78, 0xFA020101, + 0xC78, 0xF9030101, + 0xC78, 0xF8040101, + 0xC78, 0xF7050101, + 0xC78, 0xF6060101, + 0xC78, 0xF5070101, + 0xC78, 0xF4080101, + 0xC78, 0xF3090101, + 0xC78, 0xF20A0101, + 0xC78, 0xF10B0101, + 0xC78, 0xF00C0101, + 0xC78, 0xEF0D0101, + 0xC78, 0xEE0E0101, + 0xC78, 0xED0F0101, + 0xC78, 0xEC100101, + 0xC78, 0xEB110101, + 0xC78, 0xEA120101, + 0xC78, 0xE9130101, + 0xC78, 0xE8140101, + 0xC78, 0xE7150101, + 0xC78, 0xE6160101, + 0xC78, 0xE5170101, + 0xC78, 0xE4180101, + 0xC78, 0xE3190101, + 0xC78, 0x661A0101, + 0xC78, 0x651B0101, + 0xC78, 0x641C0101, + 0xC78, 0x631D0101, + 0xC78, 0x071E0101, + 0xC78, 0x061F0101, + 0xC78, 0x05200101, + 0xC78, 0x04210101, + 0xC78, 0x03220101, + 0xC78, 0xE8230001, + 0xC78, 0xE7240001, + 0xC78, 0xE6250001, + 0xC78, 0xE5260001, + 0xC78, 0xE4270001, + 0xC78, 0x89280001, + 0xC78, 0x88290001, + 0xC78, 0x872A0001, + 0xC78, 0x862B0001, + 0xC78, 0x852C0001, + 0xC78, 0x482D0001, + 0xC78, 0x472E0001, + 0xC78, 0x462F0001, + 0xC78, 0x45300001, + 0xC78, 0x44310001, + 0xC78, 0x07320001, + 0xC78, 0x06330001, + 0xC78, 0x05340001, + 0xC78, 0x04350001, + 0xC78, 0x03360001, + 0xC78, 0x02370001, + 0xC78, 0x01380001, + 0xC78, 0x00390001, + 0xC78, 0x003A0001, + 0xC78, 0x003B0001, + 0xC78, 0x003C0001, + 0xC78, 0x003D0001, + 0xC78, 0x003E0001, + 0xC78, 0x003F0001, + 0xC78, 0x7F002001, + 0xC78, 0x7F012001, + 0xC78, 0x7F022001, + 0xC78, 0x7F032001, + 0xC78, 0x7F042001, + 0xC78, 0x7F052001, + 0xC78, 0x7F062001, + 0xC78, 0x7F072001, + 0xC78, 0x7F082001, + 0xC78, 0x7F092001, + 0xC78, 0x7F0A2001, + 0xC78, 0x7F0B2001, + 0xC78, 0x7F0C2001, + 0xC78, 0x7F0D2001, + 0xC78, 0x7F0E2001, + 0xC78, 0x7F0F2001, + 0xC78, 0x7F102001, + 0xC78, 0x7F112001, + 0xC78, 0x7E122001, + 0xC78, 0x7D132001, + 0xC78, 0x7C142001, + 0xC78, 0x7B152001, + 0xC78, 0x7A162001, + 0xC78, 0x79172001, + 0xC78, 0x78182001, + 0xC78, 0x77192001, + 0xC78, 0x761A2001, + 0xC78, 0x751B2001, + 0xC78, 0x741C2001, + 0xC78, 0x731D2001, + 0xC78, 0x721E2001, + 0xC78, 0x711F2001, + 0xC78, 0x70202001, + 0xC78, 0x6F212001, + 0xC78, 0x6E222001, + 0xC78, 0x6D232001, + 0xC78, 0x6C242001, + 0xC78, 0x6B252001, + 0xC78, 0x6A262001, + 0xC78, 0x69272001, + 0xC78, 0x68282001, + 0xC78, 0x67292001, + 0xC78, 0x662A2001, + 0xC78, 0x652B2001, + 0xC78, 0x642C2001, + 0xC78, 0x632D2001, + 0xC78, 0x622E2001, + 0xC78, 0x612F2001, + 0xC78, 0x60302001, + 0xC78, 0x42312001, + 0xC78, 0x41322001, + 0xC78, 0x40332001, + 0xC78, 0x23342001, + 0xC78, 0x22352001, + 0xC78, 0x21362001, + 0xC78, 0x20372001, + 0xC78, 0x00382001, + 0xC78, 0x02392001, + 0xC78, 0x013A2001, + 0xC78, 0x003B2001, + 0xC78, 0x003C2001, + 0xC78, 0x003D2001, + 0xC78, 0x003E2001, + 0xC78, 0x003F2001, + 0xC78, 0x7F003101, + 0xC78, 0x7F013101, + 0xC78, 0x7F023101, + 0xC78, 0x7F033101, + 0xC78, 0x7F043101, + 0xC78, 0x7F053101, + 0xC78, 0x7F063101, + 0xC78, 0x7E073101, + 0xC78, 0x7D083101, + 0xC78, 0x7C093101, + 0xC78, 0x7B0A3101, + 0xC78, 0x7A0B3101, + 0xC78, 0x790C3101, + 0xC78, 0x780D3101, + 0xC78, 0x770E3101, + 0xC78, 0x760F3101, + 0xC78, 0x75103101, + 0xC78, 0x74113101, + 0xC78, 0x73123101, + 0xC78, 0x72133101, + 0xC78, 0x71143101, + 0xC78, 0x70153101, + 0xC78, 0x6F163101, + 0xC78, 0x69173101, + 0xC78, 0x68183101, + 0xC78, 0x67193101, + 0xC78, 0x661A3101, + 0xC78, 0x651B3101, + 0xC78, 0x641C3101, + 0xC78, 0x631D3101, + 0xC78, 0x621E3101, + 0xC78, 0x611F3101, + 0xC78, 0x60203101, + 0xC78, 0x42213101, + 0xC78, 0x41223101, + 0xC78, 0x40233101, + 0xC78, 0x22243101, + 0xC78, 0x21253101, + 0xC78, 0x20263101, + 0xC78, 0x00273101, + 0xC78, 0x00283101, + 0xC78, 0x00293101, + 0xC78, 0x002A3101, + 0xC78, 0x002B3101, + 0xC78, 0x002C3101, + 0xC78, 0x002D3101, + 0xC78, 0x002E3101, + 0xC78, 0x002F3101, + 0xC78, 0x00303101, + 0xC78, 0x00313101, + 0xC78, 0x00323101, + 0xC78, 0x00333101, + 0xC78, 0x00343101, + 0xC78, 0x00353101, + 0xC78, 0x00363101, + 0xC78, 0x00373101, + 0xC78, 0x00383101, + 0xC78, 0x00393101, + 0xC78, 0x003A3101, + 0xC78, 0x003B3101, + 0xC78, 0x003C3101, + 0xC78, 0x003D3101, + 0xC78, 0x003E3101, + 0xC78, 0x003F3101, + 0xC78, 0xFA403101, + 0xC78, 0xF9413101, + 0xC78, 0xF8423101, + 0xC78, 0xF7433101, + 0xC78, 0xF6443101, + 0xC78, 0xF5453101, + 0xC78, 0xF4463101, + 0xC78, 0xF3473101, + 0xC78, 0xF2483101, + 0xC78, 0xE1493101, + 0xC78, 0xE04A3101, + 0xC78, 0xEF4B3101, + 0xC78, 0xEE4C3101, + 0xC78, 0xED4D3101, + 0xC78, 0xEC4E3101, + 0xC78, 0xEB4F3101, + 0xC78, 0xEA503101, + 0xC78, 0xE9513101, + 0xC78, 0xE8523101, + 0xC78, 0xE7533101, + 0xC78, 0xE6543101, + 0xC78, 0xE5553101, + 0xC78, 0xE4563101, + 0xC78, 0xE3573101, + 0xC78, 0xE2583101, + 0xC78, 0xE1593101, + 0xC78, 0xE05A3101, + 0xC78, 0xC25B3101, + 0xC78, 0xC15C3101, + 0xC78, 0xC05D3101, + 0xC78, 0x825E3101, + 0xC78, 0x815F3101, + 0xC78, 0x80603101, + 0xC78, 0x80613101, + 0xC78, 0x80623101, + 0xC78, 0x80633101, + 0xC78, 0x80643101, + 0xC78, 0x80653101, + 0xC78, 0x80663101, + 0xC78, 0x80673101, + 0xC78, 0x80683101, + 0xC78, 0x80693101, + 0xC78, 0x806A3101, + 0xC78, 0x806B3101, + 0xC78, 0x806C3101, + 0xC78, 0x806D3101, + 0xC78, 0x806E3101, + 0xC78, 0x806F3101, + 0xC78, 0x80703101, + 0xC78, 0x80713101, + 0xC78, 0x80723101, + 0xC78, 0x80733101, + 0xC78, 0x80743101, + 0xC78, 0x80753101, + 0xC78, 0x80763101, + 0xC78, 0x80773101, + 0xC78, 0x80783101, + 0xC78, 0x80793101, + 0xC78, 0x807A3101, + 0xC78, 0x807B3101, + 0xC78, 0x807C3101, + 0xC78, 0x807D3101, + 0xC78, 0x807E3101, + 0xC78, 0x807F3101, + 0xC78, 0xFF402001, + 0xC78, 0xFF412001, + 0xC78, 0xFF422001, + 0xC78, 0xFF432001, + 0xC78, 0xFF442001, + 0xC78, 0xFF452001, + 0xC78, 0xFF462001, + 0xC78, 0xFF472001, + 0xC78, 0xFF482001, + 0xC78, 0xFF492001, + 0xC78, 0xFF4A2001, + 0xC78, 0xFF4B2001, + 0xC78, 0xFF4C2001, + 0xC78, 0xFE4D2001, + 0xC78, 0xFD4E2001, + 0xC78, 0xFC4F2001, + 0xC78, 0xFB502001, + 0xC78, 0xFA512001, + 0xC78, 0xF9522001, + 0xC78, 0xF8532001, + 0xC78, 0xF7542001, + 0xC78, 0xF6552001, + 0xC78, 0xF5562001, + 0xC78, 0xF4572001, + 0xC78, 0xF3582001, + 0xC78, 0xF2592001, + 0xC78, 0xF15A2001, + 0xC78, 0xF05B2001, + 0xC78, 0xEF5C2001, + 0xC78, 0xEE5D2001, + 0xC78, 0xED5E2001, + 0xC78, 0xEC5F2001, + 0xC78, 0xEB602001, + 0xC78, 0xEA612001, + 0xC78, 0xE9622001, + 0xC78, 0xE8632001, + 0xC78, 0xE7642001, + 0xC78, 0xE6652001, + 0xC78, 0xE5662001, + 0xC78, 0xE4672001, + 0xC78, 0xE3682001, + 0xC78, 0xC5692001, + 0xC78, 0xC46A2001, + 0xC78, 0xC36B2001, + 0xC78, 0xA46C2001, + 0xC78, 0x846D2001, + 0xC78, 0x836E2001, + 0xC78, 0x826F2001, + 0xC78, 0x81702001, + 0xC78, 0x80712001, + 0xC78, 0x80722001, + 0xC78, 0x80732001, + 0xC78, 0x80742001, + 0xC78, 0x80752001, + 0xC78, 0x80762001, + 0xC78, 0x80772001, + 0xC78, 0x80782001, + 0xC78, 0x80792001, + 0xC78, 0x807A2001, + 0xC78, 0x807B2001, + 0xC78, 0x807C2001, + 0xC78, 0x807D2001, + 0xC78, 0x807E2001, + 0xC78, 0x807F2001, + 0xC50, 0x69553422, + 0xC50, 0x69553420, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8703b_agc, rtw_phy_cfg_agc); + +/* init values for BB registers */ +static const u32 rtw8703b_bb[] = { + 0x800, 0x83045700, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x02200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569A11A9, + 0x85C, 0x01000014, + 0x860, 0x66F60110, + 0x864, 0x061F0649, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x07000760, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x004F0201, + 0x880, 0xB0000B1E, + 0x884, 0x00000001, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000002, + 0x914, 0x00000201, + 0x948, 0x99000000, + 0x94C, 0x00000010, + 0x950, 0x20003800, + 0x954, 0x4A880000, + 0x958, 0x4BC5D87A, + 0x95C, 0x04EB9B79, + 0xA00, 0x00D047C8, + 0xA04, 0x80FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7F120F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xD1D80000, + 0xA24, 0x5A7DA0BD, + 0xA28, 0x0000223B, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x2180FA74, + 0xA84, 0x00120000, + 0xA88, 0x040C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x05100000, + 0xA9C, 0x3F000000, + 0xAA0, 0x00000000, + 0xB2C, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x18800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC4B, + 0xC34, 0x31000040, + 0xC38, 0x21688080, + 0xC3C, 0x000016CC, + 0xC40, 0x1F78403F, + 0xC44, 0x00010036, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00015967, + 0xC5C, 0x18250492, + 0xC60, 0x00000000, + 0xC64, 0x7112848B, + 0xC68, 0x47C07BFF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020600DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0xC84, 0x19F60000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00091521, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00000000, + 0xCA4, 0x000300A0, + 0xCA8, 0x00000000, + 0xCAC, 0x00000000, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x64B22427, + 0xCDC, 0x00766932, + 0xCE0, 0x00222222, + 0xCE4, 0x10000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00030740, + 0xD04, 0x40020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC53, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCB979975, + 0xD30, 0x00000000, + 0xD34, 0x80608000, + 0xD38, 0x98000000, + 0xD3C, 0x40127353, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x6437140A, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000048, + 0xE68, 0x001B25A4, + 0xE6C, 0x01C00014, + 0xE70, 0x01C00014, + 0xE74, 0x02000014, + 0xE78, 0x02000014, + 0xE7C, 0x02000014, + 0xE80, 0x02000014, + 0xE84, 0x01C00014, + 0xE88, 0x02000014, + 0xE8C, 0x01C00014, + 0xED0, 0x01C00014, + 0xED4, 0x01C00014, + 0xED8, 0x01C00014, + 0xEDC, 0x00000014, + 0xEE0, 0x00000014, + 0xEE8, 0x21555448, + 0xEEC, 0x03C00014, + 0xF14, 0x00000003, + 0xF4C, 0x00000000, + 0xF00, 0x00000300, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8703b_bb, rtw_phy_cfg_bb); + +static const u32 rtw8703b_rf_a[] = { + 0x018, 0x00008C01, + 0x0B5, 0x0008C050, + 0x0B1, 0x00054258, + 0x0B2, 0x00054C00, + 0x030, 0x00018000, + 0x031, 0x00000027, + 0x032, 0x000A7F07, + 0x030, 0x00020000, + 0x031, 0x00000027, + 0x032, 0x000E7D87, + 0x01C, 0x000F8635, + 0x0EF, 0x00080000, + 0x030, 0x00008000, + 0x031, 0x00000004, + 0x032, 0x00006105, + 0x0EF, 0x00000000, + 0x0EF, 0x00000400, + 0x041, 0x0000BD54, + 0x041, 0x00003DD4, + 0x041, 0x0000FDD4, + 0x0EF, 0x00000000, + 0x0DF, 0x00000600, + 0x050, 0x0000C6DB, + 0x051, 0x00004505, + 0x052, 0x0000E31D, + 0x053, 0x00040579, + 0x054, 0x00000000, + 0x055, 0x0008206E, + 0x056, 0x00040000, + 0x0EF, 0x00000100, + 0x034, 0x0000ADD7, + 0x034, 0x00009DD4, + 0x034, 0x00008DD1, + 0x034, 0x00007DCE, + 0x034, 0x00006DCB, + 0x034, 0x00005CCE, + 0x034, 0x000048CD, + 0x034, 0x000034CC, + 0x034, 0x0000244F, + 0x034, 0x0000144C, + 0x034, 0x0000004E, + 0x0EF, 0x00000000, + 0x0EF, 0x00002000, + 0x03B, 0x0003801F, + 0x03B, 0x00030002, + 0x03B, 0x00028001, + 0x03B, 0x00020000, + 0x03B, 0x00018003, + 0x03B, 0x00010002, + 0x03B, 0x00008001, + 0x03B, 0x00000000, + 0x0EF, 0x00000000, + 0x082, 0x000C0000, + 0x083, 0x000AF025, + 0x01E, 0x00000C08, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8703b_rf_a, A); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h new file mode 100644 index 000000000..98bd399bd --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright Fiona Klute */ + +#ifndef __RTW8703B_TABLES_H__ +#define __RTW8703B_TABLES_H__ + +extern const struct rtw_table rtw8703b_bb_pg_tbl; +extern const struct rtw_table rtw8703b_txpwr_lmt_tbl; +extern const struct rtw_table rtw8703b_mac_tbl; +extern const struct rtw_table rtw8703b_agc_tbl; +extern const struct rtw_table rtw8703b_bb_tbl; +extern const struct rtw_table rtw8703b_rf_a_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723cs.c b/drivers/net/wireless/realtek/rtw88/rtw8723cs.c new file mode 100644 index 000000000..2018c9d76 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723cs.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright Fiona Klute */ + +#include +#include +#include +#include "main.h" +#include "rtw8703b.h" +#include "sdio.h" + +static const struct sdio_device_id rtw_8723cs_id_table[] = { + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8723CS), + .driver_data = (kernel_ulong_t)&rtw8703b_hw_spec, + }, + {} +}; +MODULE_DEVICE_TABLE(sdio, rtw_8723cs_id_table); + +static struct sdio_driver rtw_8723cs_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8723cs_id_table, + .probe = rtw_sdio_probe, + .remove = rtw_sdio_remove, + .shutdown = rtw_sdio_shutdown, + .drv = { + .pm = &rtw_sdio_pm_ops, + }}; +module_sdio_driver(rtw_8723cs_driver); + +MODULE_AUTHOR("Fiona Klute "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c new file mode 100644 index 000000000..a2b3e7a2a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -0,0 +1,2212 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8723x.h" +#include "rtw8723d.h" +#include "rtw8723d_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" + +#define WLAN_SLOT_TIME 0x09 +#define WLAN_RL_VAL 0x3030 +#define WLAN_BAR_VAL 0x0201ffff +#define BIT_MASK_TBTT_HOLD 0x00000fff +#define BIT_SHIFT_TBTT_HOLD 8 +#define BIT_MASK_TBTT_SETUP 0x000000ff +#define BIT_SHIFT_TBTT_SETUP 0 +#define BIT_MASK_TBTT_MASK ((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \ + (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP)) +#define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\ + (((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD)) +#define WLAN_TBTT_TIME_NORMAL TBTT_TIME(0x04, 0x80) +#define WLAN_TBTT_TIME_STOP_BCN TBTT_TIME(0x04, 0x64) +#define WLAN_PIFS_VAL 0 +#define WLAN_AGG_BRK_TIME 0x16 +#define WLAN_NAV_PROT_LEN 0x0040 +#define WLAN_SPEC_SIFS 0x100a +#define WLAN_RX_PKT_LIMIT 0x17 +#define WLAN_MAX_AGG_NR 0x0A +#define WLAN_AMPDU_MAX_TIME 0x1C +#define WLAN_ANT_SEL 0x82 +#define WLAN_LTR_IDLE_LAT 0x90039003 +#define WLAN_LTR_ACT_LAT 0x883c883c +#define WLAN_LTR_CTRL1 0xCB004010 +#define WLAN_LTR_CTRL2 0x01233425 + +static const u32 rtw8723d_ofdm_swing_table[] = { + 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, + 0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056, + 0x16c0005b, 0x18000060, 0x19800066, 0x1b00006c, 0x1c800072, 0x1e400079, + 0x20000080, 0x22000088, 0x24000090, 0x26000098, 0x288000a2, 0x2ac000ab, + 0x2d4000b5, 0x300000c0, 0x32c000cb, 0x35c000d7, 0x390000e4, 0x3c8000f2, + 0x40000100, 0x43c0010f, 0x47c0011f, 0x4c000130, 0x50800142, 0x55400155, + 0x5a400169, 0x5fc0017f, 0x65400195, 0x6b8001ae, 0x71c001c7, 0x788001e2, + 0x7f8001fe, +}; + +static const u32 rtw8723d_cck_swing_table[] = { + 0x0CD, 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, + 0x16C, 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, + 0x287, 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, + 0x47F, 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, + 0x7FF, +}; + +#define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_ofdm_swing_table) +#define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_cck_swing_table) + +static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = RTW_DEF_OFDM_SWING_INDEX; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; + dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; +} + +static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +{ + u8 xtal_cap; + u32 val32; + + /* power on BB/RF domain */ + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); + + rtw_phy_load_tables(rtwdev); + + /* post init after header files config */ + rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); + rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT); + rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); + + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); + if ((rtwdev->efuse.afe >> 4) == 14) { + rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4); + rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL); + rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1); + rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0); + } + + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); + rtw_write8(rtwdev, REG_ATIMWND, 0x2); + rtw_write8(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); + val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT); + val32 &= ~BIT_MASK_TBTT_MASK; + val32 |= WLAN_TBTT_TIME_STOP_BCN; + rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val32); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); + rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME); + rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); + rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); + rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL); + + rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT); + rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2); + + rtw_phy_init(rtwdev); + rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; + + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + + rtw8723x_lck(rtwdev); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); + + rtw8723d_pwrtrack_init(rtwdev); +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 min_rx_power = -120; + u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); + + pkt_stat->rx_power[RF_PATH_A] = pwdb - 97; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 rxsc, bw; + s8 min_rx_power = -120; + s8 rx_evm; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0) + bw = RTW_CHANNEL_WIDTH_20; + else if ((rxsc == 1) || (rxsc == 2)) + bw = RTW_CHANNEL_WIDTH_20; + else + bw = RTW_CHANNEL_WIDTH_40; + + pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = bw; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + + dm_info->curr_rx_rate = pkt_stat->rate; + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; + dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; + + rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64); + rx_evm &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ + dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm; +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, + u8 channel, u32 thres) +{ + u32 freq; + bool ret = false; + + if (channel == 13) + freq = FREQ_CH13; + else if (channel == 14) + freq = FREQ_CH14; + else + return false; + + rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); + + msleep(30); + if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) + ret = true; + + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); + + return ret; +} + +static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) +{ + if (!notch) { + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); + return; + } + + switch (channel) { + case 13: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 14: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + default: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); + break; + } +} + +static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel) +{ + bool notch; + + if (channel < 13) { + rtw8723d_cfg_notch(rtwdev, channel, false); + return; + } + + notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES); + rtw8723d_cfg_notch(rtwdev, channel, notch); +} + +static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u32 rf_cfgch_a, rf_cfgch_b; + + rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); + + rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); + rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); + + rf_cfgch_a &= ~RFCFGCH_BW_MASK; + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rf_cfgch_a |= RFCFGCH_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_cfgch_a |= RFCFGCH_BW_40M; + break; + default: + break; + } + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a); + rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b); + + rtw8723d_spur_cal(rtwdev, channel); +} + +static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = { + [0] = { + { .len = 4, .reg = 0xA24, .val = 0x64B80C1C }, + { .len = 4, .reg = 0xA28, .val = 0x00008810 }, + { .len = 4, .reg = 0xAAC, .val = 0x01235667 }, + }, + [1] = { + { .len = 4, .reg = 0xA24, .val = 0x0000B81C }, + { .len = 4, .reg = 0xA28, .val = 0x00000000 }, + { .len = 4, .reg = 0xAAC, .val = 0x00003667 }, + }, +}; + +static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + const struct rtw_backup_info *cck_dfir; + int i; + + cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; + + for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++) + rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0); + rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, + (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); + break; + default: + break; + } +} + +static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + rtw8723d_set_channel_rf(rtwdev, channel, bw); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); +} + +static void rtw8723d_shutdown(struct rtw_dev *rtwdev) +{ + rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); +} + +struct rtw_8723d_iqk_cfg { + const char *name; + u32 val_bb_sel_btg; + u32 reg_lutwe; + u32 val_txiqk_pi; + u32 reg_padlut; + u32 reg_gaintx; + u32 reg_bspad; + u32 val_wlint; + u32 val_wlsel; + u32 val_iqkpts; +}; + +static const struct rtw_8723d_iqk_cfg iqk_tx_cfg[PATH_NR] = { + [PATH_S1] = { + .name = "S1", + .val_bb_sel_btg = 0x99000000, + .reg_lutwe = RF_LUTWE, + .val_txiqk_pi = 0x8214019f, + .reg_padlut = RF_LUTDBG, + .reg_gaintx = RF_GAINTX, + .reg_bspad = RF_BSPAD, + .val_wlint = 0xe0d, + .val_wlsel = 0x60d, + .val_iqkpts = 0xfa000000, + }, + [PATH_S0] = { + .name = "S0", + .val_bb_sel_btg = 0x99000280, + .reg_lutwe = RF_LUTWE2, + .val_txiqk_pi = 0x8214018a, + .reg_padlut = RF_TXADBG, + .reg_gaintx = RF_TRXIQ, + .reg_bspad = RF_TXATANK, + .val_wlint = 0xe6d, + .val_wlsel = 0x66d, + .val_iqkpts = 0xf9000000, + }, +}; + +static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + s32 tx_x, tx_y; + u32 tx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_TX), + rtw_read32(rtwdev, REG_IQK_RES_TY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(after IQK) = 0x%x\n", + rtw_read32(rtwdev, 0xe90), + rtw_read32(rtwdev, 0xe98)); + + tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) + return IQK_TX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s TXIQK is failed\n", + iqk_cfg->name); + + return 0; +} + +static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + s32 rx_x, rx_y; + u32 rx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RX), + rtw_read32(rtwdev, REG_IQK_RES_RY)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(after IQK) = 0x%x\n", + rtw_read32(rtwdev, 0xea0), + rtw_read32(rtwdev, 0xea8)); + + rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); + rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + rx_y = abs(iqkxy_to_s32(rx_y)); + + if (!rx_fail && rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && + rx_y < IQK_RX_Y_LMT) + return IQK_RX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s RXIQK STEP2 is failed\n", + iqk_cfg->name); + + return 0; +} + +#define IQK_LTE_WRITE_VAL_8723D 0x0000ff00 + +static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + u32 pts = (tx ? iqk_cfg->val_iqkpts : 0xf9000000); + + /* enter IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); + + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054); + mdelay(1); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] GNT_BT @%s %sIQK1 = 0x%x\n", + iqk_cfg->name, tx ? "TX" : "RX", + rtw_read32(rtwdev, REG_LTECOEX_READ_DATA)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x948 @%s %sIQK1 = 0x%x\n", + iqk_cfg->name, tx ? "TX" : "RX", + rtw_read32(rtwdev, REG_BB_SEL_BTG)); + + /* One shot, LOK & IQK */ + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, pts); + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); + + if (!check_hw_ready(rtwdev, REG_IQK_RES_RY, BIT_IQK_DONE, 1)) + rtw_warn(rtwdev, "%s %s IQK isn't done\n", iqk_cfg->name, + tx ? "TX" : "RX"); +} + +static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct rtw8723x_iqk_backup_regs *backup) +{ + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); + + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, BIT(0), 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, BIT(0), 0x0); +} + +static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u8 status; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s TXIQK!!\n", iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + + rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00004); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005d); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xBFFE0); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x08008c0c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, iqk_cfg->val_txiqk_pi); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160200); + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); + + /* PA, PAD setting */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x1E0, 0x3); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXIQGEN, 0x1F, 0xf); + + /* LOK setting for 8723D */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x10, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_bspad, 0x1, 0x1); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, true, iqk_cfg); + status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); + + rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); + + return status; +} + +static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u32 tx_x, tx_y; + u8 status; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK Step1!!\n", + iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + /* path IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82160000); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160000); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); + + /* RXIQK mode */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00006); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xa7ffb); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + /* PA/PAD=0 */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1@ path %s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2@ path %s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); + status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); + + if (!status) + goto restore; + + /* second round */ + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQK_11N), + BIT_SET_TXIQK_11N(tx_x, tx_y)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK STEP2!!\n", + iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82170000); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28171400); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); + + /* RXIQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x80000, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00007); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xb3fdb); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); + status |= rtw8723d_iqk_check_rx_failed(rtwdev, iqk_cfg); + +restore: + rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); + + return status; +} + +static +void rtw8723d_iqk_fill_s1_matrix(struct rtw_dev *rtwdev, const s32 result[]) +{ + s32 oldval_1; + s32 x, y; + s32 tx1_a, tx1_a_ext; + s32 tx1_c, tx1_c_ext; + + if (result[IQK_S1_TX_X] == 0) + return; + + oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_D); + + x = iqkxy_to_s32(result[IQK_S1_TX_X]); + tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_A, tx1_a); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_A, tx1_a_ext); + + y = iqkxy_to_s32(result[IQK_S1_TX_Y]); + tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + BIT_SET_TXIQ_ELM_C1(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_C, tx1_c_ext); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", + x, tx1_a, oldval_1); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); + + if (result[IQK_S1_RX_X] == 0) + return; + + rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_X, + result[IQK_S1_RX_X]); + rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_Y1, + BIT_SET_RXIQ_S1_Y1(result[IQK_S1_RX_Y])); + rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, + BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); +} + +static +void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[]) +{ + s32 oldval_0; + s32 x, y; + s32 tx0_a, tx0_a_ext; + s32 tx0_c, tx0_c_ext; + + if (result[IQK_S0_TX_X] == 0) + return; + + oldval_0 = rtw_read32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0); + + x = iqkxy_to_s32(result[IQK_S0_TX_X]); + tx0_a = iqk_mult(x, oldval_0, &tx0_a_ext); + + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, tx0_a); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, tx0_a_ext); + + y = iqkxy_to_s32(result[IQK_S0_TX_Y]); + tx0_c = iqk_mult(y, oldval_0, &tx0_c_ext); + + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, tx0_c); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, tx0_c_ext); + + if (result[IQK_S0_RX_X] == 0) + return; + + rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_X_S0, + result[IQK_S0_RX_X]); + rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_Y_S0, + result[IQK_S0_RX_Y]); +} + +static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); +} + +static +void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path) +{ + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path-%s standby mode!\n", + path == RF_PATH_A ? "S1" : "S0"); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, path, RF_MODE, RFREG_MASK, 0x10000); + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); +} + +#define ADDA_ON_VAL_8723D 0x03c00016 + +static +void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723x_path path) +{ + if (path == PATH_S0) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A); + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + } + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + if (path == PATH_S1) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B); + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + } +} + +static +void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, + const struct rtw8723x_iqk_backup_regs *backup) +{ + u32 i; + u8 s1_ok, s0_ok; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); + + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + rtw8723d_iqk_config_mac(rtwdev); + rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); + rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611); + rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); + rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204200); + rtw8723d_iqk_precfg_path(rtwdev, PATH_S1); + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s1_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); + if (s1_ok == IQK_TX_OK) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S1 Tx IQK Success!!\n"); + result[t][IQK_S1_TX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + result[t][IQK_S1_TX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Tx IQK Fail!!\n"); + result[t][IQK_S1_TX_X] = 0x100; + result[t][IQK_S1_TX_Y] = 0x0; + } + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s1_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); + if (s1_ok == (IQK_TX_OK | IQK_RX_OK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S1 Rx IQK Success!!\n"); + result[t][IQK_S1_RX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + result[t][IQK_S1_RX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Rx IQK Fail!!\n"); + result[t][IQK_S1_RX_X] = 0x100; + result[t][IQK_S1_RX_Y] = 0x0; + } + + if (s1_ok == 0x0) + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 IQK is failed!!\n"); + + rtw8723d_iqk_precfg_path(rtwdev, PATH_S0); + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s0_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); + if (s0_ok == IQK_TX_OK) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S0 Tx IQK Success!!\n"); + result[t][IQK_S0_TX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + result[t][IQK_S0_TX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Tx IQK Fail!!\n"); + result[t][IQK_S0_TX_X] = 0x100; + result[t][IQK_S0_TX_Y] = 0x0; + } + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s0_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); + if (s0_ok == (IQK_TX_OK | IQK_RX_OK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S0 Rx IQK Success!!\n"); + + result[t][IQK_S0_RX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + result[t][IQK_S0_RX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Rx IQK Fail!!\n"); + result[t][IQK_S0_RX_X] = 0x100; + result[t][IQK_S0_RX_Y] = 0x0; + } + + if (s0_ok == 0x0) + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 IQK is failed!!\n"); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] back to BB mode, load original value!\n"); +} + +static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 result[IQK_ROUND_SIZE][IQK_NR]; + struct rtw8723x_iqk_backup_regs backup; + u8 i, j; + u8 final_candidate = IQK_ROUND_INVALID; + bool good; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!!!\n"); + + memset(result, 0, sizeof(result)); + + rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); + rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); + rtw8723x_iqk_backup_regs(rtwdev, &backup); + + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { + rtw8723x_iqk_config_path_ctrl(rtwdev); + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); + + rtw8723d_iqk_one_round(rtwdev, result, i, &backup); + + if (i > IQK_ROUND_0) + rtw8723x_iqk_restore_regs(rtwdev, &backup); + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); + rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); + + for (j = IQK_ROUND_0; j < i; j++) { + good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); + + if (good) { + final_candidate = j; + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] cmp %d:%d final_candidate is %x\n", + j, i, final_candidate); + goto iqk_done; + } + } + } + + if (final_candidate == IQK_ROUND_INVALID) { + s32 reg_tmp = 0; + + for (i = 0; i < IQK_NR; i++) + reg_tmp += result[IQK_ROUND_HYBRID][i]; + + if (reg_tmp != 0) { + final_candidate = IQK_ROUND_HYBRID; + } else { + WARN(1, "IQK is failed\n"); + goto out; + } + } + +iqk_done: + rtw8723d_iqk_fill_s1_matrix(rtwdev, result[final_candidate]); + rtw8723d_iqk_fill_s0_matrix(rtwdev, result[final_candidate]); + + dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; + dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; + dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; + dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; + dm_info->iqk.done = true; + +out: + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", + final_candidate); + + for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", + i, + result[i][0], result[i][1], result[i][2], result[i][3], + result[i][4], result[i][5], result[i][6], result[i][7], + final_candidate == i ? "(final candidate)" : ""); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", + rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), + rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), + rtw_read32(rtwdev, REG_A_RXIQI), + rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK]0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQ_AB_S0), + rtw_read32(rtwdev, REG_TXIQ_CD_S0), + rtw_read32(rtwdev, REG_RXIQ_AB_S0)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] finished\n"); +} + +static void rtw8723d_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; + u8 cck_n_rx; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + cck_n_rx = (rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_2RX) && + rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_MRC)) ? 2 : 1; + rtw_dbg(rtwdev, RTW_DBG_PHY, + "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x, cck_fa_avg=%d\n", + rtw_is_assoc(rtwdev), new_lvl, cck_n_rx, + dm_info->cck_pd_default + new_lvl * 2, + pd[new_lvl], dm_info->cck_fa_avg); + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]); + rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000, + dm_info->cck_pd_default + new_lvl * 2); +} + +/* for coex */ +static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8723d_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ + rtw_write8_mask(rtwdev, REG_LEDCFG2, BIT(6), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(0), 0); + rtw_write8_mask(rtwdev, REG_GPIO_INTM + 2, BIT(4), 0); + rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT(7), 0); + rtw_write8_mask(rtwdev, REG_SYS_CLKR + 1, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT(3), 0); +} + +static void rtw8723d_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + bool aux = efuse->bt_setting & BIT(6); + + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_exist = false; + coex_rfe->ant_switch_with_bt = false; + coex_rfe->ant_switch_diversity = false; + coex_rfe->wlg_at_btg = true; + + /* decide antenna at main or aux */ + if (efuse->share_ant) { + if (aux) + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x80); + else + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x200); + } else { + if (aux) + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x280); + else + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x0); + } + + /* disable LTE coex in wifi side */ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); +} + +static void rtw8723d_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + static const u8 wl_tx_power[] = {0xb2, 0x90}; + u8 pwr; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; + + if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power)) + coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1; + + pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl]; + + rtw_write8(rtwdev, REG_ANA_PARAM1 + 3, pwr); +} + +static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + /* WL Rx Low gain on */ + static const u32 wl_rx_low_gain_on[] = { + 0xec120101, 0xeb130101, 0xce140101, 0xcd150101, 0xcc160101, + 0xcb170101, 0xca180101, 0x8d190101, 0x8c1a0101, 0x8b1b0101, + 0x4f1c0101, 0x4e1d0101, 0x4d1e0101, 0x4c1f0101, 0x0e200101, + 0x0d210101, 0x0c220101, 0x0b230101, 0xcf240001, 0xce250001, + 0xcd260001, 0xcc270001, 0x8f280001 + }; + /* WL Rx Low gain off */ + static const u32 wl_rx_low_gain_off[] = { + 0xec120101, 0xeb130101, 0xea140101, 0xe9150101, 0xe8160101, + 0xe7170101, 0xe6180101, 0xe5190101, 0xe41a0101, 0xe31b0101, + 0xe21c0101, 0xe11d0101, 0xe01e0101, 0x861f0101, 0x85200101, + 0x84210101, 0x83220101, 0x82230101, 0x81240101, 0x80250101, + 0x44260101, 0x43270101, 0x42280101 + }; + u8 i; + + if (low_gain == coex_dm->cur_wl_rx_low_gain_en) + return; + + coex_dm->cur_wl_rx_low_gain_en = low_gain; + + if (coex_dm->cur_wl_rx_low_gain_en) { + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++) + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_on[i]); + } else { + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_off[i]); + } +} + +static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, + u32 ofdm_swing, u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 ele_A, ele_D, ele_C; + s32 ele_A_ext, ele_C_ext, ele_D_ext; + s32 iqk_result_x; + s32 iqk_result_y; + s32 value32; + + switch (rf_path) { + default: + case RF_PATH_A: + iqk_result_x = dm_info->iqk.result.s1_x; + iqk_result_y = dm_info->iqk.result.s1_y; + break; + case RF_PATH_B: + iqk_result_x = dm_info->iqk.result.s0_x; + iqk_result_y = dm_info->iqk.result.s0_y; + break; + } + + /* new element D */ + ele_D = OFDM_SWING_D(ofdm_swing); + iqk_mult(iqk_result_x, ele_D, &ele_D_ext); + /* new element A */ + iqk_result_x = iqkxy_to_s32(iqk_result_x); + ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); + /* new element C */ + iqk_result_y = iqkxy_to_s32(iqk_result_y); + ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); + + switch (rf_path) { + case RF_PATH_A: + default: + /* write new elements A, C, D, and element B is always 0 */ + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + value32); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + /* write new elements A, C, D, and element B is always 0 */ + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, ele_D); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, ele_C); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, ele_A); + + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, + ele_D_ext); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, + ele_A_ext); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, + ele_C_ext); + break; + } +} + +static void rtw8723d_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, + u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 value32; + u32 ofdm_swing; + + if (ofdm_index >= RTW_OFDM_SWING_TABLE_SIZE) + ofdm_index = RTW_OFDM_SWING_TABLE_SIZE - 1; + else if (ofdm_index < 0) + ofdm_index = 0; + + ofdm_swing = rtw8723d_ofdm_swing_table[ofdm_index]; + + if (dm_info->iqk.done) { + rtw8723d_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); + return; + } + + switch (rf_path) { + case RF_PATH_A: + default: + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + 0x00); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + /* image S1:c80 to S0:Cd0 and Cd4 */ + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, + OFDM_SWING_A(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_B_S0, + OFDM_SWING_B(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, + OFDM_SWING_C(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, + OFDM_SWING_D(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, 0x0); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, 0x0); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, 0x0); + break; + } +} + +static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); +} + +static void rtw8723d_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_cck = txagc_idx; + + rtw_write32_mask(rtwdev, 0xab4, 0x000007FF, + rtw8723d_cck_swing_table[swing_idx]); +} + +static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + u8 limit_ofdm; + u8 limit_cck = 40; + s8 final_ofdm_swing_index; + s8 final_cck_swing_index; + + limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); + + final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + + dm_info->delta_power_index[path]; + final_cck_swing_index = RTW_DEF_CCK_SWING_INDEX + + dm_info->delta_power_index[path]; + + if (final_ofdm_swing_index > limit_ofdm) + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, + final_ofdm_swing_index - limit_ofdm); + else if (final_ofdm_swing_index < 0) + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, 0, + final_ofdm_swing_index); + else + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); + + if (final_cck_swing_index > limit_cck) + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, limit_cck, + final_cck_swing_index - limit_cck); + else if (final_cck_swing_index < 0) + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, 0, + final_cck_swing_index); + else + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); + + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); +} + +static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, delta, path; + bool do_iqk = false; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (do_iqk) + rtw8723x_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + s8 delta_cur, delta_last; + + delta_last = dm_info->delta_power_index[path]; + delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, + path, RF_PATH_A, delta); + if (delta_last == delta_cur) + continue; + + dm_info->delta_power_index[path] = delta_cur; + rtw8723d_pwrtrack_set(rtwdev, path); + } + + rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); + +iqk: + if (do_iqk) + rtw8723d_phy_calibration(rtwdev); +} + +static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8723d_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static const struct rtw_chip_ops rtw8723d_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_phy_status = query_phy_status, + .set_channel = rtw8723d_set_channel, + .mac_init = rtw8723x_mac_init, + .mac_postinit = rtw8723x_mac_postinit, + .shutdown = rtw8723d_shutdown, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8723x_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8723x_cfg_ldo25, + .efuse_grant = rtw8723x_efuse_grant, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw8723x_false_alarm_statistics, + .phy_calibration = rtw8723d_phy_calibration, + .cck_pd_set = rtw8723d_phy_cck_pd_set, + .pwr_track = rtw8723d_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, + + .coex_set_init = rtw8723x_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8723d_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8723d_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8723d_coex_cfg_wl_rx_gain, +}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8723d[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, + {0x66555555, 0x6aaa5aaa}, + {0x66555555, 0xaaaa5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x55555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8723d[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-110 */ + {0x66555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xffff55ff, 0xffff55ff}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffffffff, 0x5afa5afa}, + {0xffffffff, 0xaaaaaaaa}, /* case-120 */ + {0x55ff55ff, 0x5afa5afa}, + {0x55ff55ff, 0xaaaaaaaa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8723d[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8723d[] = { + { {0x00, 0x00, 0x00, 0x00, 0x01} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} } +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8723d[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8723d[] = {30, 30, 30, 30}; +static const struct coex_5g_afh_map afh_5g_8723d[] = { {0, 0, 0} }; + +static const struct rtw_hw_reg btg_reg_8723d = { + .addr = REG_BTG_SEL, .mask = BIT_MASK_BTG_WL, +}; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8723d[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 4}, + {1, 2, true, 4}, + {1, 10, true, 4}, + {1, 15, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8723d[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 5}, + {1, 2, true, 5}, + {1, 10, true, 5}, + {1, 15, true, 5} +}; + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, (BIT(1) | BIT(0)), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0063, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0058, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x005A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0068, + RTW_PWR_CUT_TEST_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0069, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0077, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x07}, + {0x0077, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x07}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = { + trans_carddis_to_cardemu_8723d, + trans_cardemu_to_act_8723d, + NULL +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_lps_8723d[] = { + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x0522, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x05F8, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05F9, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FA, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FB, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0100, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x03}, + {0x0101, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0553, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_pre_carddis_8723d[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0080, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8723d[] = { + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8723d[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 1}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = { + {0x001D, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x001D, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x001C, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x0E}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = { + trans_act_to_lps_8723d, + trans_act_to_pre_carddis_8723d, + trans_act_to_cardemu_8723d, + trans_cardemu_to_carddis_8723d, + trans_act_to_post_carddis_8723d, + NULL +}; + +static const struct rtw_page_table page_table_8723d[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +}; + +static const struct rtw_rqpn rqpn_table_8723d[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = { + {0x0008, 0x4a22, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0009, 0x1000, + RTW_IP_SEL_PHY, + ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B), + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8723d = { + .gen1_para = pcie_gen1_param_8723d, + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), +}; + +static const u8 rtw8723d_pwrtrk_2gb_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2gb_p[] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2ga_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2ga_p[] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_b_n[] = { + 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_b_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_a_n[] = { + 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_a_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const s8 rtw8723d_pwrtrk_xtal_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const s8 rtw8723d_pwrtrk_xtal_p[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -10, -12, -14, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 +}; + +static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = { + .pwrtrk_2gb_n = rtw8723d_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8723d_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8723d_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8723d_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8723d_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8723d_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8723d_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8723d_pwrtrk_2g_cck_a_p, + .pwrtrk_xtal_p = rtw8723d_pwrtrk_xtal_p, + .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, +}; + +static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, }, +}; + +static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x964, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0x864, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0xab7, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0xa01, BIT(7), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, +}; + +const struct rtw_chip_info rtw8723d_hw_spec = { + .ops = &rtw8723d_ops, + .id = RTW_CHIP_TYPE_8723D, + .fw_name = "rtw88/rtw8723d_fw.bin", + .wlan_cpu = RTW_WCPU_8051, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 96 + 1, + .txff_size = 32768, + .rxff_size = 16384, + .rsvd_drv_pg_num = 8, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, + .c2h_ra_report_size = 7, + .old_datarate_fb_limit = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8723d, + .pwr_off_seq = card_disable_flow_8723d, + .page_table = page_table_8723d, + .rqpn_table = rqpn_table_8723d, + .prioq_addrs = &rtw8723x_common.prioq_addrs, + .intf_table = &phy_para_table_8723d, + .dig = rtw8723x_common.dig, + .dig_cck = rtw8723x_common.dig_cck, + .rf_sipi_addr = {0x840, 0x844}, + .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, + .fix_rf_phy_num = 2, + .ltecoex_addr = &rtw8723x_common.ltecoex_addr, + .mac_tbl = &rtw8723d_mac_tbl, + .agc_tbl = &rtw8723d_agc_tbl, + .bb_tbl = &rtw8723d_bb_tbl, + .rf_tbl = {&rtw8723d_rf_a_tbl}, + .rfe_defs = rtw8723d_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .rx_ldpc = false, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0x2007022f, + .bt_desired_ver = 0x2f, + .scbd_support = true, + .new_scbd10_def = true, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8723d, + .bt_rssi_step = bt_rssi_step_8723d, + .table_sant_num = ARRAY_SIZE(table_sant_8723d), + .table_sant = table_sant_8723d, + .table_nsant_num = ARRAY_SIZE(table_nsant_8723d), + .table_nsant = table_nsant_8723d, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8723d), + .tdma_sant = tdma_sant_8723d, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8723d), + .tdma_nsant = tdma_nsant_8723d, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8723d), + .wl_rf_para_tx = rf_para_tx_8723d, + .wl_rf_para_rx = rf_para_rx_8723d, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = ARRAY_SIZE(afh_5g_8723d), + .afh_5g = afh_5g_8723d, + .btg_reg = &btg_reg_8723d, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8723d), + .coex_info_hw_regs = coex_info_hw_regs_8723d, +}; +EXPORT_SYMBOL(rtw8723d_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8723d_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723d driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h new file mode 100644 index 000000000..fba06c9f4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8723D_H__ +#define __RTW8723D_H__ + +#include "rtw8723x.h" + +extern const struct rtw_chip_info rtw8723d_hw_spec; + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) + +#define RTW_DEF_OFDM_SWING_INDEX 28 +#define RTW_DEF_CCK_SWING_INDEX 28 + +#define CCK_DFIR_NR 3 + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d_table.c b/drivers/net/wireless/realtek/rtw88/rtw8723d_table.c new file mode 100644 index 000000000..27a22b392 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d_table.c @@ -0,0 +1,1196 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8723d_table.h" + +static const u32 rtw8723d_mac[] = { + 0x020, 0x00000013, + 0x02F, 0x00000010, + 0x077, 0x00000007, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000002, + 0x435, 0x00000003, + 0x436, 0x00000005, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43A, 0x00000000, + 0x43B, 0x00000001, + 0x43C, 0x00000002, + 0x43D, 0x00000003, + 0x43E, 0x00000005, + 0x43F, 0x00000007, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000028, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000028, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000C, + 0x63F, 0x0000000C, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66A, 0x000000B0, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x765, 0x00000018, + 0x76E, 0x00000004, + 0x7C0, 0x00000038, + 0x7C2, 0x0000000F, + 0x7C3, 0x000000C0, + 0x073, 0x00000004, + 0x7C4, 0x00000077, + 0x07C, 0x00000003, + 0x016, 0x000000B3, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_mac, rtw_phy_cfg_mac); + +static const u32 rtw8723d_agc[] = { + 0xC78, 0xFE000101, + 0xC78, 0xFD010101, + 0xC78, 0xFC020101, + 0xC78, 0xFB030101, + 0xC78, 0xFA040101, + 0xC78, 0xF9050101, + 0xC78, 0xF8060101, + 0xC78, 0xF7070101, + 0xC78, 0xF6080101, + 0xC78, 0xF5090101, + 0xC78, 0xF40A0101, + 0xC78, 0xF30B0101, + 0xC78, 0xF20C0101, + 0xC78, 0xF10D0101, + 0xC78, 0xF00E0101, + 0xC78, 0xEF0F0101, + 0xC78, 0xEE100101, + 0xC78, 0xED110101, + 0xC78, 0xEC120101, + 0xC78, 0xEB130101, + 0xC78, 0xEA140101, + 0xC78, 0xE9150101, + 0xC78, 0xE8160101, + 0xC78, 0xE7170101, + 0xC78, 0xE6180101, + 0xC78, 0xE5190101, + 0xC78, 0xE41A0101, + 0xC78, 0xE31B0101, + 0xC78, 0xE21C0101, + 0xC78, 0xE11D0101, + 0xC78, 0xE01E0101, + 0xC78, 0x861F0101, + 0xC78, 0x85200101, + 0xC78, 0x84210101, + 0xC78, 0x83220101, + 0xC78, 0x82230101, + 0xC78, 0x81240101, + 0xC78, 0x80250101, + 0xC78, 0x44260101, + 0xC78, 0x43270101, + 0xC78, 0x42280101, + 0xC78, 0x41290101, + 0xC78, 0x402A0101, + 0xC78, 0x022B0101, + 0xC78, 0x012C0101, + 0xC78, 0x002D0101, + 0xC78, 0xC52E0001, + 0xC78, 0xC42F0001, + 0xC78, 0xC3300001, + 0xC78, 0xC2310001, + 0xC78, 0xC1320001, + 0xC78, 0xC0330001, + 0xC78, 0x04340001, + 0xC78, 0x03350001, + 0xC78, 0x02360001, + 0xC78, 0x01370001, + 0xC78, 0x00380001, + 0xC78, 0x00390001, + 0xC78, 0x003A0001, + 0xC78, 0x003B0001, + 0xC78, 0x003C0001, + 0xC78, 0x003D0001, + 0xC78, 0x003E0001, + 0xC78, 0x003F0001, + 0xC78, 0x6F002001, + 0xC78, 0x6F012001, + 0xC78, 0x6F022001, + 0xC78, 0x6F032001, + 0xC78, 0x6F042001, + 0xC78, 0x6F052001, + 0xC78, 0x6F062001, + 0xC78, 0x6F072001, + 0xC78, 0x6F082001, + 0xC78, 0x6F092001, + 0xC78, 0x6F0A2001, + 0xC78, 0x6F0B2001, + 0xC78, 0x6F0C2001, + 0xC78, 0x6F0D2001, + 0xC78, 0x6F0E2001, + 0xC78, 0x6F0F2001, + 0xC78, 0x6F102001, + 0xC78, 0x6F112001, + 0xC78, 0x6F122001, + 0xC78, 0x6F132001, + 0xC78, 0x6F142001, + 0xC78, 0x6F152001, + 0xC78, 0x6F162001, + 0xC78, 0x6F172001, + 0xC78, 0x6F182001, + 0xC78, 0x6F192001, + 0xC78, 0x6F1A2001, + 0xC78, 0x6F1B2001, + 0xC78, 0x6F1C2001, + 0xC78, 0x6F1D2001, + 0xC78, 0x6F1E2001, + 0xC78, 0x6F1F2001, + 0xC78, 0x6F202001, + 0xC78, 0x6F212001, + 0xC78, 0x6F222001, + 0xC78, 0x6F232001, + 0xC78, 0x6E242001, + 0xC78, 0x6D252001, + 0xC78, 0x6C262001, + 0xC78, 0x6B272001, + 0xC78, 0x6A282001, + 0xC78, 0x69292001, + 0xC78, 0x4B2A2001, + 0xC78, 0x4A2B2001, + 0xC78, 0x492C2001, + 0xC78, 0x482D2001, + 0xC78, 0x472E2001, + 0xC78, 0x462F2001, + 0xC78, 0x45302001, + 0xC78, 0x44312001, + 0xC78, 0x43322001, + 0xC78, 0x42332001, + 0xC78, 0x41342001, + 0xC78, 0x40352001, + 0xC78, 0x02362001, + 0xC78, 0x01372001, + 0xC78, 0x00382001, + 0xC78, 0x00392001, + 0xC78, 0x003A2001, + 0xC78, 0x003B2001, + 0xC78, 0x003C2001, + 0xC78, 0x003D2001, + 0xC78, 0x003E2001, + 0xC78, 0x003F2001, + 0xC78, 0x7F003101, + 0xC78, 0x7F013101, + 0xC78, 0x7F023101, + 0xC78, 0x7F033101, + 0xC78, 0x7F043101, + 0xC78, 0x7F053101, + 0xC78, 0x7F063101, + 0xC78, 0x7F073101, + 0xC78, 0x7E083101, + 0xC78, 0x7D093101, + 0xC78, 0x7C0A3101, + 0xC78, 0x7B0B3101, + 0xC78, 0x7A0C3101, + 0xC78, 0x790D3101, + 0xC78, 0x780E3101, + 0xC78, 0x770F3101, + 0xC78, 0x76103101, + 0xC78, 0x75113101, + 0xC78, 0x74123101, + 0xC78, 0x73133101, + 0xC78, 0x72143101, + 0xC78, 0x71153101, + 0xC78, 0x70163101, + 0xC78, 0x6F173101, + 0xC78, 0x6E183101, + 0xC78, 0x6D193101, + 0xC78, 0x6C1A3101, + 0xC78, 0x6B1B3101, + 0xC78, 0x6A1C3101, + 0xC78, 0x691D3101, + 0xC78, 0x681E3101, + 0xC78, 0x4B1F3101, + 0xC78, 0x4A203101, + 0xC78, 0x49213101, + 0xC78, 0x48223101, + 0xC78, 0x47233101, + 0xC78, 0x46243101, + 0xC78, 0x45253101, + 0xC78, 0x44263101, + 0xC78, 0x43273101, + 0xC78, 0x42283101, + 0xC78, 0x41293101, + 0xC78, 0x402A3101, + 0xC78, 0x022B3101, + 0xC78, 0x012C3101, + 0xC78, 0x002D3101, + 0xC78, 0x002E3101, + 0xC78, 0x002F3101, + 0xC78, 0x00303101, + 0xC78, 0x00313101, + 0xC78, 0x00323101, + 0xC78, 0x00333101, + 0xC78, 0x00343101, + 0xC78, 0x00353101, + 0xC78, 0x00363101, + 0xC78, 0x00373101, + 0xC78, 0x00383101, + 0xC78, 0x00393101, + 0xC78, 0x003A3101, + 0xC78, 0x003B3101, + 0xC78, 0x003C3101, + 0xC78, 0x003D3101, + 0xC78, 0x003E3101, + 0xC78, 0x003F3101, + 0xC78, 0xFE403101, + 0xC78, 0xFD413101, + 0xC78, 0xFC423101, + 0xC78, 0xFB433101, + 0xC78, 0xFA443101, + 0xC78, 0xF9453101, + 0xC78, 0xF8463101, + 0xC78, 0xF7473101, + 0xC78, 0xF6483101, + 0xC78, 0xF5493101, + 0xC78, 0xF44A3101, + 0xC78, 0xF34B3101, + 0xC78, 0xF24C3101, + 0xC78, 0xF14D3101, + 0xC78, 0xF04E3101, + 0xC78, 0xEF4F3101, + 0xC78, 0xEE503101, + 0xC78, 0xED513101, + 0xC78, 0xEC523101, + 0xC78, 0xEB533101, + 0xC78, 0xEA543101, + 0xC78, 0xE9553101, + 0xC78, 0xE8563101, + 0xC78, 0xE7573101, + 0xC78, 0xE6583101, + 0xC78, 0xE5593101, + 0xC78, 0xE45A3101, + 0xC78, 0xE35B3101, + 0xC78, 0xE25C3101, + 0xC78, 0xE15D3101, + 0xC78, 0xE05E3101, + 0xC78, 0x865F3101, + 0xC78, 0x85603101, + 0xC78, 0x84613101, + 0xC78, 0x83623101, + 0xC78, 0x82633101, + 0xC78, 0x81643101, + 0xC78, 0x80653101, + 0xC78, 0x80663101, + 0xC78, 0x80673101, + 0xC78, 0x80683101, + 0xC78, 0x80693101, + 0xC78, 0x806A3101, + 0xC78, 0x806B3101, + 0xC78, 0x806C3101, + 0xC78, 0x806D3101, + 0xC78, 0x806E3101, + 0xC78, 0x806F3101, + 0xC78, 0x80703101, + 0xC78, 0x80713101, + 0xC78, 0x80723101, + 0xC78, 0x80733101, + 0xC78, 0x80743101, + 0xC78, 0x80753101, + 0xC78, 0x80763101, + 0xC78, 0x80773101, + 0xC78, 0x80783101, + 0xC78, 0x80793101, + 0xC78, 0x807A3101, + 0xC78, 0x807B3101, + 0xC78, 0x807C3101, + 0xC78, 0x807D3101, + 0xC78, 0x807E3101, + 0xC78, 0x807F3101, + 0xC78, 0xEF402001, + 0xC78, 0xEF412001, + 0xC78, 0xEF422001, + 0xC78, 0xEF432001, + 0xC78, 0xEF442001, + 0xC78, 0xEF452001, + 0xC78, 0xEF462001, + 0xC78, 0xEF472001, + 0xC78, 0xEF482001, + 0xC78, 0xEF492001, + 0xC78, 0xEF4A2001, + 0xC78, 0xEF4B2001, + 0xC78, 0xEF4C2001, + 0xC78, 0xEF4D2001, + 0xC78, 0xEF4E2001, + 0xC78, 0xEF4F2001, + 0xC78, 0xEF502001, + 0xC78, 0xEF512001, + 0xC78, 0xEF522001, + 0xC78, 0xEF532001, + 0xC78, 0xEF542001, + 0xC78, 0xEF552001, + 0xC78, 0xEF562001, + 0xC78, 0xEF572001, + 0xC78, 0xEF582001, + 0xC78, 0xEF592001, + 0xC78, 0xEF5A2001, + 0xC78, 0xEF5B2001, + 0xC78, 0xEF5C2001, + 0xC78, 0xEF5D2001, + 0xC78, 0xEF5E2001, + 0xC78, 0xEF5F2001, + 0xC78, 0xEF602001, + 0xC78, 0xEE612001, + 0xC78, 0xED622001, + 0xC78, 0xEC632001, + 0xC78, 0xEB642001, + 0xC78, 0xEA652001, + 0xC78, 0xE9662001, + 0xC78, 0xE8672001, + 0xC78, 0xCB682001, + 0xC78, 0xCA692001, + 0xC78, 0xC96A2001, + 0xC78, 0xC86B2001, + 0xC78, 0xC76C2001, + 0xC78, 0xC66D2001, + 0xC78, 0xC56E2001, + 0xC78, 0xC46F2001, + 0xC78, 0xC3702001, + 0xC78, 0xC2712001, + 0xC78, 0xC1722001, + 0xC78, 0xC0732001, + 0xC78, 0x82742001, + 0xC78, 0x81752001, + 0xC78, 0x80762001, + 0xC78, 0x80772001, + 0xC78, 0x80782001, + 0xC78, 0x80792001, + 0xC78, 0x807A2001, + 0xC78, 0x807B2001, + 0xC78, 0x807C2001, + 0xC78, 0x807D2001, + 0xC78, 0x807E2001, + 0xC78, 0x807F2001, + 0xC78, 0xFA001101, + 0xC78, 0xF9011101, + 0xC78, 0xF8021101, + 0xC78, 0xF7031101, + 0xC78, 0xF6041101, + 0xC78, 0xF5051101, + 0xC78, 0xF4061101, + 0xC78, 0xD7071101, + 0xC78, 0xD6081101, + 0xC78, 0xD5091101, + 0xC78, 0xD40A1101, + 0xC78, 0x970B1101, + 0xC78, 0x960C1101, + 0xC78, 0x950D1101, + 0xC78, 0x940E1101, + 0xC78, 0x930F1101, + 0xC78, 0x92101101, + 0xC78, 0x91111101, + 0xC78, 0x90121101, + 0xC78, 0x8F131101, + 0xC78, 0x8E141101, + 0xC78, 0x8D151101, + 0xC78, 0x8C161101, + 0xC78, 0x8B171101, + 0xC78, 0x8A181101, + 0xC78, 0x89191101, + 0xC78, 0x881A1101, + 0xC78, 0x871B1101, + 0xC78, 0x861C1101, + 0xC78, 0x851D1101, + 0xC78, 0x841E1101, + 0xC78, 0x831F1101, + 0xC78, 0x82201101, + 0xC78, 0x81211101, + 0xC78, 0x80221101, + 0xC78, 0x43231101, + 0xC78, 0x42241101, + 0xC78, 0x41251101, + 0xC78, 0x04261101, + 0xC78, 0x03271101, + 0xC78, 0x02281101, + 0xC78, 0x01291101, + 0xC78, 0x002A1101, + 0xC78, 0xC42B1001, + 0xC78, 0xC32C1001, + 0xC78, 0xC22D1001, + 0xC78, 0xC12E1001, + 0xC78, 0xC02F1001, + 0xC78, 0x85301001, + 0xC78, 0x84311001, + 0xC78, 0x83321001, + 0xC78, 0x82331001, + 0xC78, 0x81341001, + 0xC78, 0x80351001, + 0xC78, 0x05361001, + 0xC78, 0x04371001, + 0xC78, 0x03381001, + 0xC78, 0x02391001, + 0xC78, 0x013A1001, + 0xC78, 0x003B1001, + 0xC78, 0x003C1001, + 0xC78, 0x003D1001, + 0xC78, 0x003E1001, + 0xC78, 0x003F1001, + 0xC50, 0x69553422, + 0xC50, 0x69553420, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_agc, rtw_phy_cfg_agc); + +static const u32 rtw8723d_bb[] = { + 0x800, 0x80046C00, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x00200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569A11A9, + 0x85C, 0x01000014, + 0x860, 0x66F60110, + 0x864, 0x461F0641, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x07000460, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x004F0201, + 0x880, 0xB2002E12, + 0x884, 0x00000007, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000402, + 0x914, 0x00000300, + 0x920, 0x18C6318C, + 0x924, 0x0000018C, + 0x948, 0x99000000, + 0x94C, 0x00000010, + 0x950, 0x00003800, + 0x954, 0x5A380000, + 0x958, 0x4BC6D87A, + 0x95C, 0x04EB9B79, + 0x96C, 0x00000003, + 0x970, 0x00000000, + 0x974, 0x00000000, + 0x978, 0x00000000, + 0x97C, 0x13000000, + 0x980, 0x00000000, + 0xA00, 0x00D046C8, + 0xA04, 0x80FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E20100F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xE82C0001, + 0xA24, 0x64B80C1C, + 0xA28, 0x00008810, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x2180FA74, + 0xA84, 0x00200000, + 0xA88, 0x040C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x00000000, + 0xA9C, 0x00020000, + 0xAA0, 0x00000000, + 0xAA4, 0x0000000C, + 0xAA8, 0xCA100008, + 0xAAC, 0x01235667, + 0xAB0, 0x00000000, + 0xAB4, 0x20201402, + 0xB2C, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x28800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC48, + 0xC34, 0x31000040, + 0xC38, 0x21688080, + 0xC3C, 0x000016D4, + 0xC40, 0x1F78403F, + 0xC44, 0x00010036, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00015969, + 0xC5C, 0x00310492, + 0xC60, 0x00280A00, + 0xC64, 0x7112848B, + 0xC68, 0x47C074FF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020600DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0xC84, 0x21F60000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00091521, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00012000, + 0xCA4, 0x800000A0, + 0xCA8, 0x84E6C606, + 0xCAC, 0x00000060, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x0010A3D0, + 0xCC4, 0x00000F7D, + 0xCC8, 0x000442D6, + 0xCCC, 0x00000000, + 0xCD0, 0x000001C8, + 0xCD4, 0x001C8000, + 0xCD8, 0x00000100, + 0xCDC, 0x40100000, + 0xCE0, 0x00222220, + 0xCE4, 0x20000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00030740, + 0xD04, 0x40020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC53, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCC979975, + 0xD30, 0x00000000, + 0xD34, 0x40608000, + 0xD38, 0x88000000, + 0xD3C, 0xC0127343, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x00000038, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE68, 0x001B25A4, + 0xE6C, 0x01C00014, + 0xE70, 0x01C00016, + 0xE74, 0x02000014, + 0xE78, 0x02000014, + 0xE7C, 0x02000014, + 0xE80, 0x02000014, + 0xE84, 0x01C00014, + 0xE88, 0x02000014, + 0xE8C, 0x01C00014, + 0xED0, 0x01C00014, + 0xED4, 0x01C00014, + 0xED8, 0x01C00014, + 0xEDC, 0x00000014, + 0xEE0, 0x00000014, + 0xEE8, 0x21555448, + 0xEEC, 0x03C00014, + 0xF14, 0x00000003, + 0xF00, 0x00100300, + 0xF08, 0x0000800B, + 0xF0C, 0x0000F007, + 0xF10, 0x0000A487, + 0xF1C, 0x80000064, + 0xF38, 0x00030155, + 0xF3C, 0x0000003A, + 0xF4C, 0x13000000, + 0xF50, 0x00000000, + 0xF18, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8723d_bb_pg[] = { + { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, }, + { 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, }, + { 0, 0, 0, 0x00000e00, 0xffffffff, 0x32343434, }, + { 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303032, }, + { 0, 0, 0, 0x00000e10, 0xffffffff, 0x30323234, }, + { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26282830, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8723d_bb_pg); + +static const u32 rtw8723d_rf_a[] = { + 0x050, 0x0001C000, + 0x049, 0x0004AA00, + 0x000, 0x00010000, + 0x0B1, 0x00054573, + 0x0B4, 0x000508AB, + 0x0B7, 0x00014787, + 0x0B8, 0x000064CB, + 0x01B, 0x00073A40, + 0x051, 0x00038CAF, + 0x052, 0x000FCCA3, + 0x053, 0x00090F38, + 0x054, 0x00011083, + 0x057, 0x000D0000, + 0x08D, 0x00000A1A, + 0x082, 0x00082AAC, + 0x08E, 0x00076940, + 0x08F, 0x00088400, + 0x061, 0x00038CAF, + 0x062, 0x000FCCA3, + 0x063, 0x00090F38, + 0x064, 0x00011083, + 0x067, 0x000D0000, + 0x092, 0x00082AAC, + 0x0EF, 0x00000400, + 0x030, 0x000008CA, + 0x030, 0x000018CA, + 0x030, 0x000028CA, + 0x030, 0x000038CA, + 0x0EF, 0x00000000, + 0x0EE, 0x00000400, + 0x030, 0x000008CA, + 0x030, 0x000018CA, + 0x030, 0x000028CA, + 0x030, 0x000038CA, + 0x0EE, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x0000CCA3, + 0x033, 0x00000001, + 0x03F, 0x0000CCA3, + 0x033, 0x00000002, + 0x03F, 0x0000CCA3, + 0x033, 0x00000003, + 0x03F, 0x0000CCA3, + 0x033, 0x00000004, + 0x03F, 0x0000CCA3, + 0x033, 0x00000005, + 0x03F, 0x0000CCA3, + 0x033, 0x00000006, + 0x03F, 0x0000CCA3, + 0x033, 0x00000007, + 0x03F, 0x0000CCA3, + 0x0EF, 0x00000000, + 0x0EE, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x0000CCA3, + 0x033, 0x00000001, + 0x03F, 0x0000CCA3, + 0x033, 0x00000002, + 0x03F, 0x0000CCA3, + 0x033, 0x00000003, + 0x03F, 0x0000CCA3, + 0x033, 0x00000004, + 0x03F, 0x0000CCA3, + 0x033, 0x00000005, + 0x03F, 0x0000CCA3, + 0x033, 0x00000006, + 0x03F, 0x0000CCA3, + 0x033, 0x00000007, + 0x03F, 0x0000CCA3, + 0x0EE, 0x00000000, + 0x0EF, 0x00000800, + 0x030, 0x0000002D, + 0x030, 0x0000122C, + 0x030, 0x0000222F, + 0x030, 0x0000326C, + 0x030, 0x0000466B, + 0x030, 0x0000566E, + 0x030, 0x000066EB, + 0x030, 0x000077EC, + 0x030, 0x000087EF, + 0x030, 0x000097F2, + 0x030, 0x0000A7F5, + 0x0EF, 0x00000000, + 0x0EE, 0x00000800, + 0x030, 0x00000001, + 0x030, 0x00001011, + 0x030, 0x00002011, + 0x030, 0x00003013, + 0x030, 0x00004033, + 0x030, 0x00005033, + 0x030, 0x00006037, + 0x030, 0x0000703F, + 0x030, 0x0000803F, + 0x030, 0x0000903F, + 0x030, 0x0000A03F, + 0x0EE, 0x00000000, + 0x082, 0x00083B8C, + 0x0ED, 0x00000008, + 0x030, 0x000030F6, + 0x030, 0x00002004, + 0x030, 0x000010F6, + 0x030, 0x000000F6, + 0x0ED, 0x00000000, + 0x092, 0x00083B8C, + 0x0EC, 0x00000008, + 0x030, 0x000030F6, + 0x030, 0x00002004, + 0x030, 0x000010F6, + 0x030, 0x000000F6, + 0x0EC, 0x00000000, + 0x0EF, 0x00010000, + 0x030, 0x0001C11C, + 0x030, 0x000181F4, + 0x030, 0x00014108, + 0x030, 0x000101E4, + 0x030, 0x0000C11C, + 0x030, 0x000081F4, + 0x030, 0x00004108, + 0x030, 0x000001E4, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x030, 0x0001C11C, + 0x030, 0x000181F4, + 0x030, 0x00014108, + 0x030, 0x000101E4, + 0x030, 0x0000C11C, + 0x030, 0x000081F4, + 0x030, 0x00004108, + 0x030, 0x000001E4, + 0x0EE, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000007, + 0x03E, 0x0000005F, + 0x03F, 0x000B3FDB, + 0x033, 0x00000004, + 0x03E, 0x0000005D, + 0x03F, 0x000BFFE0, + 0x033, 0x00000005, + 0x03E, 0x0000005D, + 0x03F, 0x000FBFCE, + 0x033, 0x00000006, + 0x03E, 0x0000005F, + 0x03F, 0x000A7FFB, + 0x0EF, 0x00000000, + 0x0EE, 0x00000002, + 0x030, 0x00000001, + 0x030, 0x00002001, + 0x030, 0x00004001, + 0x030, 0x00007001, + 0x030, 0x00006001, + 0x030, 0x00020001, + 0x030, 0x00022001, + 0x030, 0x00024001, + 0x030, 0x00027001, + 0x030, 0x00026001, + 0x030, 0x00034001, + 0x030, 0x00037001, + 0x030, 0x00036001, + 0x030, 0x00008000, + 0x030, 0x0000A000, + 0x030, 0x0000C000, + 0x83000100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x0000E024, + 0xA0000000, 0x00000000, + 0x030, 0x0000E000, + 0xB0000000, 0x00000000, + 0x030, 0x0001C000, + 0x030, 0x0001E000, + 0x0EE, 0x00000000, + 0x0EE, 0x00020000, + 0x0EF, 0x00020000, + 0x030, 0x00000F75, + 0x030, 0x00002F55, + 0x030, 0x00003F75, + 0x0EE, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x00008401, + 0xFFE, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8723d_rf_a, A); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8723d_txpwr_lmt[] = { + {0, 0, 0, 0, 1, 30, }, + {2, 0, 0, 0, 1, 30, }, + {1, 0, 0, 0, 1, 30, }, + {0, 0, 0, 0, 2, 30, }, + {2, 0, 0, 0, 2, 30, }, + {1, 0, 0, 0, 2, 30, }, + {0, 0, 0, 0, 3, 30, }, + {2, 0, 0, 0, 3, 30, }, + {1, 0, 0, 0, 3, 30, }, + {0, 0, 0, 0, 4, 30, }, + {2, 0, 0, 0, 4, 30, }, + {1, 0, 0, 0, 4, 30, }, + {0, 0, 0, 0, 5, 30, }, + {2, 0, 0, 0, 5, 30, }, + {1, 0, 0, 0, 5, 30, }, + {0, 0, 0, 0, 6, 30, }, + {2, 0, 0, 0, 6, 30, }, + {1, 0, 0, 0, 6, 30, }, + {0, 0, 0, 0, 7, 30, }, + {2, 0, 0, 0, 7, 30, }, + {1, 0, 0, 0, 7, 30, }, + {0, 0, 0, 0, 8, 30, }, + {2, 0, 0, 0, 8, 30, }, + {1, 0, 0, 0, 8, 30, }, + {0, 0, 0, 0, 9, 30, }, + {2, 0, 0, 0, 9, 30, }, + {1, 0, 0, 0, 9, 30, }, + {0, 0, 0, 0, 10, 30, }, + {2, 0, 0, 0, 10, 30, }, + {1, 0, 0, 0, 10, 30, }, + {0, 0, 0, 0, 11, 30, }, + {2, 0, 0, 0, 11, 30, }, + {1, 0, 0, 0, 11, 30, }, + {0, 0, 0, 0, 12, 30, }, + {2, 0, 0, 0, 12, 30, }, + {1, 0, 0, 0, 12, 30, }, + {0, 0, 0, 0, 13, 17, }, + {2, 0, 0, 0, 13, 30, }, + {1, 0, 0, 0, 13, 30, }, + {0, 0, 0, 0, 14, 63, }, + {2, 0, 0, 0, 14, 63, }, + {1, 0, 0, 0, 14, 30, }, + {0, 0, 0, 1, 1, 26, }, + {2, 0, 0, 1, 1, 31, }, + {1, 0, 0, 1, 1, 31, }, + {0, 0, 0, 1, 2, 28, }, + {2, 0, 0, 1, 2, 31, }, + {1, 0, 0, 1, 2, 31, }, + {0, 0, 0, 1, 3, 30, }, + {2, 0, 0, 1, 3, 31, }, + {1, 0, 0, 1, 3, 31, }, + {0, 0, 0, 1, 4, 30, }, + {2, 0, 0, 1, 4, 31, }, + {1, 0, 0, 1, 4, 31, }, + {0, 0, 0, 1, 5, 30, }, + {2, 0, 0, 1, 5, 31, }, + {1, 0, 0, 1, 5, 31, }, + {0, 0, 0, 1, 6, 30, }, + {2, 0, 0, 1, 6, 31, }, + {1, 0, 0, 1, 6, 31, }, + {0, 0, 0, 1, 7, 30, }, + {2, 0, 0, 1, 7, 31, }, + {1, 0, 0, 1, 7, 31, }, + {0, 0, 0, 1, 8, 30, }, + {2, 0, 0, 1, 8, 31, }, + {1, 0, 0, 1, 8, 31, }, + {0, 0, 0, 1, 9, 30, }, + {2, 0, 0, 1, 9, 31, }, + {1, 0, 0, 1, 9, 31, }, + {0, 0, 0, 1, 10, 28, }, + {2, 0, 0, 1, 10, 31, }, + {1, 0, 0, 1, 10, 31, }, + {0, 0, 0, 1, 11, 26, }, + {2, 0, 0, 1, 11, 31, }, + {1, 0, 0, 1, 11, 31, }, + {0, 0, 0, 1, 12, 24, }, + {2, 0, 0, 1, 12, 31, }, + {1, 0, 0, 1, 12, 31, }, + {0, 0, 0, 1, 13, 14, }, + {2, 0, 0, 1, 13, 31, }, + {1, 0, 0, 1, 13, 31, }, + {0, 0, 0, 1, 14, 63, }, + {2, 0, 0, 1, 14, 63, }, + {1, 0, 0, 1, 14, 63, }, + {0, 0, 0, 2, 1, 24, }, + {2, 0, 0, 2, 1, 31, }, + {1, 0, 0, 2, 1, 31, }, + {0, 0, 0, 2, 2, 26, }, + {2, 0, 0, 2, 2, 31, }, + {1, 0, 0, 2, 2, 31, }, + {0, 0, 0, 2, 3, 30, }, + {2, 0, 0, 2, 3, 31, }, + {1, 0, 0, 2, 3, 31, }, + {0, 0, 0, 2, 4, 30, }, + {2, 0, 0, 2, 4, 31, }, + {1, 0, 0, 2, 4, 31, }, + {0, 0, 0, 2, 5, 30, }, + {2, 0, 0, 2, 5, 31, }, + {1, 0, 0, 2, 5, 31, }, + {0, 0, 0, 2, 6, 30, }, + {2, 0, 0, 2, 6, 31, }, + {1, 0, 0, 2, 6, 31, }, + {0, 0, 0, 2, 7, 30, }, + {2, 0, 0, 2, 7, 31, }, + {1, 0, 0, 2, 7, 31, }, + {0, 0, 0, 2, 8, 30, }, + {2, 0, 0, 2, 8, 31, }, + {1, 0, 0, 2, 8, 31, }, + {0, 0, 0, 2, 9, 30, }, + {2, 0, 0, 2, 9, 31, }, + {1, 0, 0, 2, 9, 31, }, + {0, 0, 0, 2, 10, 26, }, + {2, 0, 0, 2, 10, 31, }, + {1, 0, 0, 2, 10, 31, }, + {0, 0, 0, 2, 11, 24, }, + {2, 0, 0, 2, 11, 31, }, + {1, 0, 0, 2, 11, 31, }, + {0, 0, 0, 2, 12, 23, }, + {2, 0, 0, 2, 12, 31, }, + {1, 0, 0, 2, 12, 31, }, + {0, 0, 0, 2, 13, 13, }, + {2, 0, 0, 2, 13, 31, }, + {1, 0, 0, 2, 13, 31, }, + {0, 0, 0, 2, 14, 63, }, + {2, 0, 0, 2, 14, 63, }, + {1, 0, 0, 2, 14, 63, }, + {0, 0, 0, 3, 1, 28, }, + {2, 0, 0, 3, 1, 30, }, + {1, 0, 0, 3, 1, 30, }, + {0, 0, 0, 3, 2, 28, }, + {2, 0, 0, 3, 2, 30, }, + {1, 0, 0, 3, 2, 30, }, + {0, 0, 0, 3, 3, 30, }, + {2, 0, 0, 3, 3, 30, }, + {1, 0, 0, 3, 3, 30, }, + {0, 0, 0, 3, 4, 30, }, + {2, 0, 0, 3, 4, 30, }, + {1, 0, 0, 3, 4, 30, }, + {0, 0, 0, 3, 5, 30, }, + {2, 0, 0, 3, 5, 30, }, + {1, 0, 0, 3, 5, 30, }, + {0, 0, 0, 3, 6, 30, }, + {2, 0, 0, 3, 6, 30, }, + {1, 0, 0, 3, 6, 30, }, + {0, 0, 0, 3, 7, 30, }, + {2, 0, 0, 3, 7, 30, }, + {1, 0, 0, 3, 7, 30, }, + {0, 0, 0, 3, 8, 30, }, + {2, 0, 0, 3, 8, 30, }, + {1, 0, 0, 3, 8, 30, }, + {0, 0, 0, 3, 9, 28, }, + {2, 0, 0, 3, 9, 30, }, + {1, 0, 0, 3, 9, 30, }, + {0, 0, 0, 3, 10, 28, }, + {2, 0, 0, 3, 10, 30, }, + {1, 0, 0, 3, 10, 30, }, + {0, 0, 0, 3, 11, 28, }, + {2, 0, 0, 3, 11, 30, }, + {1, 0, 0, 3, 11, 30, }, + {0, 0, 0, 3, 12, 63, }, + {2, 0, 0, 3, 12, 30, }, + {1, 0, 0, 3, 12, 30, }, + {0, 0, 0, 3, 13, 63, }, + {2, 0, 0, 3, 13, 30, }, + {1, 0, 0, 3, 13, 30, }, + {0, 0, 0, 3, 14, 63, }, + {2, 0, 0, 3, 14, 63, }, + {1, 0, 0, 3, 14, 63, }, + {0, 0, 1, 2, 1, 63, }, + {2, 0, 1, 2, 1, 63, }, + {1, 0, 1, 2, 1, 63, }, + {0, 0, 1, 2, 2, 63, }, + {2, 0, 1, 2, 2, 63, }, + {1, 0, 1, 2, 2, 63, }, + {0, 0, 1, 2, 3, 24, }, + {2, 0, 1, 2, 3, 30, }, + {1, 0, 1, 2, 3, 30, }, + {0, 0, 1, 2, 4, 24, }, + {2, 0, 1, 2, 4, 30, }, + {1, 0, 1, 2, 4, 30, }, + {0, 0, 1, 2, 5, 24, }, + {2, 0, 1, 2, 5, 30, }, + {1, 0, 1, 2, 5, 30, }, + {0, 0, 1, 2, 6, 24, }, + {2, 0, 1, 2, 6, 30, }, + {1, 0, 1, 2, 6, 30, }, + {0, 0, 1, 2, 7, 24, }, + {2, 0, 1, 2, 7, 30, }, + {1, 0, 1, 2, 7, 30, }, + {0, 0, 1, 2, 8, 24, }, + {2, 0, 1, 2, 8, 30, }, + {1, 0, 1, 2, 8, 30, }, + {0, 0, 1, 2, 9, 24, }, + {2, 0, 1, 2, 9, 30, }, + {1, 0, 1, 2, 9, 30, }, + {0, 0, 1, 2, 10, 22, }, + {2, 0, 1, 2, 10, 30, }, + {1, 0, 1, 2, 10, 30, }, + {0, 0, 1, 2, 11, 20, }, + {2, 0, 1, 2, 11, 30, }, + {1, 0, 1, 2, 11, 30, }, + {0, 0, 1, 2, 12, 63, }, + {2, 0, 1, 2, 12, 30, }, + {1, 0, 1, 2, 12, 30, }, + {0, 0, 1, 2, 13, 63, }, + {2, 0, 1, 2, 13, 30, }, + {1, 0, 1, 2, 13, 30, }, + {0, 0, 1, 2, 14, 63, }, + {2, 0, 1, 2, 14, 63, }, + {1, 0, 1, 2, 14, 63, }, + {0, 0, 1, 3, 1, 63, }, + {2, 0, 1, 3, 1, 63, }, + {1, 0, 1, 3, 1, 63, }, + {0, 0, 1, 3, 2, 63, }, + {2, 0, 1, 3, 2, 63, }, + {1, 0, 1, 3, 2, 63, }, + {0, 0, 1, 3, 3, 26, }, + {2, 0, 1, 3, 3, 26, }, + {1, 0, 1, 3, 3, 26, }, + {0, 0, 1, 3, 4, 26, }, + {2, 0, 1, 3, 4, 26, }, + {1, 0, 1, 3, 4, 26, }, + {0, 0, 1, 3, 5, 26, }, + {2, 0, 1, 3, 5, 26, }, + {1, 0, 1, 3, 5, 26, }, + {0, 0, 1, 3, 6, 26, }, + {2, 0, 1, 3, 6, 26, }, + {1, 0, 1, 3, 6, 26, }, + {0, 0, 1, 3, 7, 26, }, + {2, 0, 1, 3, 7, 26, }, + {1, 0, 1, 3, 7, 26, }, + {0, 0, 1, 3, 8, 26, }, + {2, 0, 1, 3, 8, 26, }, + {1, 0, 1, 3, 8, 26, }, + {0, 0, 1, 3, 9, 26, }, + {2, 0, 1, 3, 9, 26, }, + {1, 0, 1, 3, 9, 26, }, + {0, 0, 1, 3, 10, 26, }, + {2, 0, 1, 3, 10, 26, }, + {1, 0, 1, 3, 10, 26, }, + {0, 0, 1, 3, 11, 26, }, + {2, 0, 1, 3, 11, 26, }, + {1, 0, 1, 3, 11, 26, }, + {0, 0, 1, 3, 12, 63, }, + {2, 0, 1, 3, 12, 26, }, + {1, 0, 1, 3, 12, 26, }, + {0, 0, 1, 3, 13, 63, }, + {2, 0, 1, 3, 13, 26, }, + {1, 0, 1, 3, 13, 26, }, + {0, 0, 1, 3, 14, 63, }, + {2, 0, 1, 3, 14, 63, }, + {1, 0, 1, 3, 14, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8723d_txpwr_lmt); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d_table.h b/drivers/net/wireless/realtek/rtw88/rtw8723d_table.h new file mode 100644 index 000000000..4db996a1d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d_table.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8723D_TABLE_H__ +#define __RTW8723D_TABLE_H__ + +extern const struct rtw_table rtw8723d_mac_tbl; +extern const struct rtw_table rtw8723d_agc_tbl; +extern const struct rtw_table rtw8723d_bb_tbl; +extern const struct rtw_table rtw8723d_bb_pg_tbl; +extern const struct rtw_table rtw8723d_rf_a_tbl; +extern const struct rtw_table rtw8723d_txpwr_lmt_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723de.c b/drivers/net/wireless/realtek/rtw88/rtw8723de.c new file mode 100644 index 000000000..c6d0c88e5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723de.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8723d.h" + +static const struct pci_device_id rtw_8723de_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xD723), + .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8723de_id_table); + +static struct pci_driver rtw_8723de_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8723de_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, +}; +module_pci_driver(rtw_8723de_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723de driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723ds.c b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c new file mode 100644 index 000000000..e38c90b76 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl + */ + +#include +#include +#include +#include "main.h" +#include "rtw8723d.h" +#include "sdio.h" + +static const struct sdio_device_id rtw_8723ds_id_table[] = { + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT), + .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, + }, + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT), + .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, + }, + {} +}; +MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); + +static struct sdio_driver rtw_8723ds_driver = { + .name = KBUILD_MODNAME, + .probe = rtw_sdio_probe, + .remove = rtw_sdio_remove, + .shutdown = rtw_sdio_shutdown, + .id_table = rtw_8723ds_id_table, + .drv = { + .pm = &rtw_sdio_pm_ops, + } +}; +module_sdio_driver(rtw_8723ds_driver); + +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.c b/drivers/net/wireless/realtek/rtw88/rtw8723du.c new file mode 100644 index 000000000..b661a26e0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8723d.h" +#include "usb.h" + +static const struct usb_device_id rtw_8723du_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd723, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* 8723DU 1*1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd611, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* Edimax EW-7611ULB V2 */ + { }, +}; +MODULE_DEVICE_TABLE(usb, rtw_8723du_id_table); + +static int rtw8723du_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtw_usb_probe(intf, id); +} + +static struct usb_driver rtw_8723du_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8723du_id_table, + .probe = rtw8723du_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8723du_driver); + +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c new file mode 100644 index 000000000..97e6f6a62 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c @@ -0,0 +1,789 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright 2024 Fiona Klute + * + * Based on code originally in rtw8723d.[ch], + * Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "debug.h" +#include "phy.h" +#include "reg.h" +#include "tx.h" +#include "rtw8723x.h" + +static const struct rtw_hw_reg rtw8723x_txagc[] = { + [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, + [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, + [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, + [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, + [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, + [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, + [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, + [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, + [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, + [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, + [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, + [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, + [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, + [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, + [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, + [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, + [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, + [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, + [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, + [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, +}; + +static void __rtw8723x_lck(struct rtw_dev *rtwdev) +{ + u32 lc_cal; + u8 val_ctx, rf_val; + int ret; + + val_ctx = rtw_read8(rtwdev, REG_CTX); + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) + rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); + else + rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); + lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); + + ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, + 10000, 1000000, false, + rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); + if (ret) + rtw_warn(rtwdev, "failed to poll LCK status bit\n"); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) + rtw_write8(rtwdev, REG_CTX, val_ctx); + else + rtw_write8(rtwdev, REG_TXPAUSE, 0x00); +} + +#define DBG_EFUSE_VAL(rtwdev, map, name) \ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \ + (map)->name) +#define DBG_EFUSE_2BYTE(rtwdev, map, name) \ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \ + (map)->name[0], (map)->name[1]) +#define DBG_EFUSE_FIX(rtwdev, name) \ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \ + # name "=0x%x\n", rtwdev->efuse.name) + +static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev, + struct rtw8723x_efuse *map) +{ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr); + DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id); + DBG_EFUSE_2BYTE(rtwdev, map, e.device_id); + DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id); + DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id); +} + +static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev, + struct rtw8723x_efuse *map) +{ + DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id); + DBG_EFUSE_2BYTE(rtwdev, map, u.product_id); + DBG_EFUSE_VAL(rtwdev, map, u.usb_option); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr); +} + +static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev, + struct rtw8723x_efuse *map) +{ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr); +} + +static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, + struct rtw_txpwr_idx *table, + int tx_path_count) +{ + if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + return; + + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "Power index table (2.4G):\n"); + /* CCK base */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %3u %3u %3u %3u %3u %3u\n", + 'A' + i, + table[i].pwr_idx_2g.cck_base[0], + table[i].pwr_idx_2g.cck_base[1], + table[i].pwr_idx_2g.cck_base[2], + table[i].pwr_idx_2g.cck_base[3], + table[i].pwr_idx_2g.cck_base[4], + table[i].pwr_idx_2g.cck_base[5]); + /* CCK diff */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %2d %2d %2d %2d\n", + 'A' + i, 0 /* no diff for 1S */, + table[i].pwr_idx_2g.ht_2s_diff.cck, + table[i].pwr_idx_2g.ht_3s_diff.cck, + table[i].pwr_idx_2g.ht_4s_diff.cck); + /* BW40-1S base */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %3u %3u %3u %3u %3u\n", + 'A' + i, + table[i].pwr_idx_2g.bw40_base[0], + table[i].pwr_idx_2g.bw40_base[1], + table[i].pwr_idx_2g.bw40_base[2], + table[i].pwr_idx_2g.bw40_base[3], + table[i].pwr_idx_2g.bw40_base[4]); + /* OFDM diff */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %2d %2d %2d %2d\n", + 'A' + i, + table[i].pwr_idx_2g.ht_1s_diff.ofdm, + table[i].pwr_idx_2g.ht_2s_diff.ofdm, + table[i].pwr_idx_2g.ht_3s_diff.ofdm, + table[i].pwr_idx_2g.ht_4s_diff.ofdm); + /* BW20 diff */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %2d %2d %2d %2d\n", + 'A' + i, + table[i].pwr_idx_2g.ht_1s_diff.bw20, + table[i].pwr_idx_2g.ht_2s_diff.bw20, + table[i].pwr_idx_2g.ht_3s_diff.bw20, + table[i].pwr_idx_2g.ht_4s_diff.bw20); + /* BW40 diff */ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n"); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); + for (int i = 0; i < tx_path_count; i++) + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "[%c]: %2d %2d %2d %2d\n", + 'A' + i, 0 /* no diff for 1S */, + table[i].pwr_idx_2g.ht_2s_diff.bw40, + table[i].pwr_idx_2g.ht_3s_diff.bw40, + table[i].pwr_idx_2g.ht_4s_diff.bw40); +} + +static void efuse_debug_dump(struct rtw_dev *rtwdev, + struct rtw8723x_efuse *map) +{ + if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + return; + + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n"); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, + (u8 *)map, sizeof(struct rtw8723x_efuse), false); + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n"); + DBG_EFUSE_VAL(rtwdev, map, rtl_id); + DBG_EFUSE_VAL(rtwdev, map, afe); + rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4); + DBG_EFUSE_VAL(rtwdev, map, channel_plan); + DBG_EFUSE_VAL(rtwdev, map, xtal_k); + DBG_EFUSE_VAL(rtwdev, map, thermal_meter); + DBG_EFUSE_VAL(rtwdev, map, iqk_lck); + DBG_EFUSE_VAL(rtwdev, map, pa_type); + DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g); + DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g); + DBG_EFUSE_VAL(rtwdev, map, rf_board_option); + DBG_EFUSE_VAL(rtwdev, map, rf_feature_option); + DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting); + DBG_EFUSE_VAL(rtwdev, map, eeprom_version); + DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id); + DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g); + DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate); + DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option); + DBG_EFUSE_VAL(rtwdev, map, rfe_option); + DBG_EFUSE_2BYTE(rtwdev, map, country_code); + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8723xe_efuse_debug(rtwdev, map); + break; + case RTW_HCI_TYPE_USB: + rtw8723xu_efuse_debug(rtwdev, map); + break; + case RTW_HCI_TYPE_SDIO: + rtw8723xs_efuse_debug(rtwdev, map); + break; + default: + /* unsupported now */ + break; + } +} + +static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8723x_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8723x_efuse *map) +{ + ether_addr_copy(efuse->addr, map->u.mac_addr); +} + +static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8723x_efuse *map) +{ + ether_addr_copy(efuse->addr, map->s.mac_addr); +} + +/* Default power index table for RTL8703B/RTL8723D, used if EFUSE does + * not contain valid data. Replaces EFUSE data from offset 0x10 (start + * of txpwr_idx_table). + */ +static const u8 rtw8723x_txpwr_idx_table[] = { + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02 +}; + +static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 *pwr = (u8 *)efuse->txpwr_idx_table; + struct rtw8723x_efuse *map; + bool valid = false; + int i; + + map = (struct rtw8723x_efuse *)log_map; + efuse_debug_dump(rtwdev, map); + + efuse->rfe_option = 0; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->pa_type_2g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g[0]; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->afe = map->afe; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8723xe_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_USB: + rtw8723xu_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_SDIO: + rtw8723xs_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -EOPNOTSUPP; + } + + /* If TX power index table in EFUSE is invalid, fall back to + * built-in table. + */ + for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++) + if (pwr[i] != 0xff) { + valid = true; + break; + } + if (!valid) { + for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++) + pwr[i] = rtw8723x_txpwr_idx_table[i]; + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "Replaced invalid EFUSE TX power index table."); + rtw8723x_debug_txpwr_limit(rtwdev, + efuse->txpwr_idx_table, 2); + } + + /* Override invalid antenna settings. */ + if (efuse->bt_setting == 0xff) { + /* shared antenna */ + efuse->bt_setting |= BIT(0); + /* RF path A */ + efuse->bt_setting &= ~BIT(6); + DBG_EFUSE_FIX(rtwdev, bt_setting); + } + + /* Override invalid board options: The coex code incorrectly + * assumes that if bits 6 & 7 are set the board doesn't + * support coex. Regd is also derived from rf_board_option and + * should be 0 if there's no valid data. + */ + if (efuse->rf_board_option == 0xff) { + efuse->regd = 0; + efuse->rf_board_option &= GENMASK(5, 0); + DBG_EFUSE_FIX(rtwdev, rf_board_option); + } + + /* Override invalid crystal cap setting, default comes from + * vendor driver. Chip specific. + */ + if (efuse->crystal_cap == 0xff) { + efuse->crystal_cap = 0x20; + DBG_EFUSE_FIX(rtwdev, crystal_cap); + } + + return 0; +} + +#define BIT_CFENDFORM BIT(9) +#define BIT_WMAC_TCR_ERR0 BIT(12) +#define BIT_WMAC_TCR_ERR1 BIT(13) +#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ + BIT_WMAC_TCR_ERR1) +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0x400 +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0x700060CE + +static int __rtw8723x_mac_init(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); + + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + + rtw_write32(rtwdev, REG_INT_MIG, 0); + rtw_write32(rtwdev, REG_MCUTST_1, 0x0); + + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); + rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); + + return 0; +} + +static int __rtw8723x_mac_postinit(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + + return 0; +} + +static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); + if (enable) { + ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; + ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; + } else { + ldo_pwr &= ~BIT_LDO25_EN; + } + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +} + +static void +rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_hw_reg *txagc; + u8 rate, pwr_index; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + + if (rate >= ARRAY_SIZE(rtw8723x_txagc)) { + rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); + continue; + } + txagc = &rtw8723x_txagc[rate]; + if (!txagc->addr) { + rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); + continue; + } + + rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); + } +} + +static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) + rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs); + } +} + +static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} + +static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 crc32_cnt; + u32 val32; + + /* hold counter */ + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); + + cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); + cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; + + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); + ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); + dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; + + dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); + dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); + crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); + crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); + dm_info->vht_err_cnt = 0; + dm_info->vht_ok_cnt = 0; + + val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); + dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | + u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); + dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; + + /* reset counter */ + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); +} + +/* IQK (IQ calibration) */ + +static +void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, + struct rtw8723x_iqk_backup_regs *backup) +{ + int i; + + for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) + backup->adda[i] = rtw_read32(rtwdev, + rtw8723x_common.iqk_adda_regs[i]); + + for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) + backup->mac8[i] = rtw_read8(rtwdev, + rtw8723x_common.iqk_mac8_regs[i]); + for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) + backup->mac32[i] = rtw_read32(rtwdev, + rtw8723x_common.iqk_mac32_regs[i]); + + for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) + backup->bb[i] = rtw_read32(rtwdev, + rtw8723x_common.iqk_bb_regs[i]); + + backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); + backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); + + backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); +} + +static +void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + int i; + + for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) + rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], + backup->adda[i]); + + for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], + backup->mac8[i]); + for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) + rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i], + backup->mac32[i]); + + for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) + rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i], + backup->bb[i]); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); + + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); + + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); +} + +static +bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, + s32 result[][IQK_NR], + u8 c1, u8 c2) +{ + u32 i, j, diff; + u32 bitmap = 0; + u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; + bool ret = true; + + s32 tmp1, tmp2; + + for (i = 0; i < IQK_NR; i++) { + tmp1 = iqkxy_to_s32(result[c1][i]); + tmp2 = iqkxy_to_s32(result[c2][i]); + + diff = abs(tmp1 - tmp2); + + if (diff <= MAX_TOLERANCE) + continue; + + if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + candidate[i / IQK_SX_NR] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + candidate[i / IQK_SX_NR] = c1; + else + bitmap |= BIT(i); + } else { + bitmap |= BIT(i); + } + } + + if (bitmap != 0) + goto check_sim; + + for (i = 0; i < PATH_NR; i++) { + if (candidate[i] == IQK_ROUND_INVALID) + continue; + + for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) + result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; + ret = false; + } + + return ret; + +check_sim: + for (i = 0; i < IQK_NR; i++) { + j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ + if (bitmap & GENMASK(j + 1, j)) + continue; + + result[IQK_ROUND_HYBRID][i] = result[c1][i]; + } + + return false; +} + +static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 tx_rate = dm_info->tx_rate; + u8 limit_ofdm = 30; + + switch (tx_rate) { + case DESC_RATE1M...DESC_RATE5_5M: + case DESC_RATE11M: + break; + case DESC_RATE6M...DESC_RATE48M: + limit_ofdm = 36; + break; + case DESC_RATE54M: + limit_ofdm = 34; + break; + case DESC_RATEMCS0...DESC_RATEMCS2: + limit_ofdm = 38; + break; + case DESC_RATEMCS3...DESC_RATEMCS4: + limit_ofdm = 36; + break; + case DESC_RATEMCS5...DESC_RATEMCS7: + limit_ofdm = 34; + break; + default: + rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); + break; + } + + return limit_ofdm; +} + +static +void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, + u8 delta) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); + const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + const s8 *pwrtrk_xtal; + s8 xtal_cap; + + if (dm_info->thermal_avg[therm_path] > + rtwdev->efuse.thermal_meter[therm_path]) + pwrtrk_xtal = tbl->pwrtrk_xtal_p; + else + pwrtrk_xtal = tbl->pwrtrk_xtal_n; + + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); +} + +static +void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + + le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + chksum = ~chksum; + + le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), + RTW_TX_DESC_W7_TXDESC_CHECKSUM); +} + +static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) +{ + /* enable TBTT nterrupt */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* BT report packet sample rate */ + /* 0x790[5:0]=0x5 */ + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); + + /* enable PTA (3-wire function form BT side) */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); + + /* enable PTA (tx/rx signal form WiFi side) */ + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); +} + +const struct rtw8723x_common rtw8723x_common = { + .iqk_adda_regs = { + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec + }, + .iqk_mac8_regs = {0x522, 0x550, 0x551}, + .iqk_mac32_regs = {0x40}, + .iqk_bb_regs = { + 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 + }, + + .ltecoex_addr = { + .ctrl = REG_LTECOEX_CTRL, + .wdata = REG_LTECOEX_WRITE_DATA, + .rdata = REG_LTECOEX_READ_DATA, + }, + .rf_sipi_addr = { + [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, + .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, + [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, + .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, + }, + .dig = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xc50, .mask = 0x7f }, + }, + .dig_cck = { + [0] = { .addr = 0xa0c, .mask = 0x3f00 }, + }, + .prioq_addrs = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, + }, + .wsize = false, + }, + + .lck = __rtw8723x_lck, + .read_efuse = __rtw8723x_read_efuse, + .mac_init = __rtw8723x_mac_init, + .mac_postinit = __rtw8723x_mac_postinit, + .cfg_ldo25 = __rtw8723x_cfg_ldo25, + .set_tx_power_index = __rtw8723x_set_tx_power_index, + .efuse_grant = __rtw8723x_efuse_grant, + .false_alarm_statistics = __rtw8723x_false_alarm_statistics, + .iqk_backup_regs = __rtw8723x_iqk_backup_regs, + .iqk_restore_regs = __rtw8723x_iqk_restore_regs, + .iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp, + .pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm, + .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal, + .coex_cfg_init = __rtw8723x_coex_cfg_init, + .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum, + .debug_txpwr_limit = __rtw8723x_debug_txpwr_limit, +}; +EXPORT_SYMBOL(rtw8723x_common); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_AUTHOR("Fiona Klute "); +MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h new file mode 100644 index 000000000..0fc70dfdf --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h @@ -0,0 +1,524 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright 2024 Fiona Klute + * + * Based on code originally in rtw8723d.[ch], + * Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8723X_H__ +#define __RTW8723X_H__ + +#include "main.h" +#include "debug.h" +#include "phy.h" +#include "reg.h" + +enum rtw8723x_path { + PATH_S1, + PATH_S0, + PATH_NR, +}; + +enum rtw8723x_iqk_round { + IQK_ROUND_0, + IQK_ROUND_1, + IQK_ROUND_2, + IQK_ROUND_HYBRID, + IQK_ROUND_SIZE, + IQK_ROUND_INVALID = 0xff, +}; + +enum rtw8723x_iqk_result { + IQK_S1_TX_X, + IQK_S1_TX_Y, + IQK_S1_RX_X, + IQK_S1_RX_Y, + IQK_S0_TX_X, + IQK_S0_TX_Y, + IQK_S0_RX_X, + IQK_S0_RX_Y, + IQK_NR, + IQK_SX_NR = IQK_NR / PATH_NR, +}; + +struct rtw8723xe_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vendor_id[2]; + u8 device_id[2]; + u8 sub_vendor_id[2]; + u8 sub_device_id[2]; +} __packed; + +struct rtw8723xu_efuse { + u8 res4[48]; /* 0xd0 */ + u8 vendor_id[2]; /* 0x100 */ + u8 product_id[2]; /* 0x102 */ + u8 usb_option; /* 0x104 */ + u8 res5[2]; /* 0x105 */ + u8 mac_addr[ETH_ALEN]; /* 0x107 */ +} __packed; + +struct rtw8723xs_efuse { + u8 res4[0x4a]; /* 0xd0 */ + u8 mac_addr[ETH_ALEN]; /* 0x11a */ +} __packed; + +struct rtw8723x_efuse { + __le16 rtl_id; + u8 rsvd[2]; + u8 afe; + u8 rsvd1[11]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 res_c7; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res[3]; + union { + struct rtw8723xe_efuse e; + struct rtw8723xu_efuse u; + struct rtw8723xs_efuse s; + }; +} __packed; + +#define RTW8723X_IQK_ADDA_REG_NUM 16 +#define RTW8723X_IQK_MAC8_REG_NUM 3 +#define RTW8723X_IQK_MAC32_REG_NUM 1 +#define RTW8723X_IQK_BB_REG_NUM 9 + +struct rtw8723x_iqk_backup_regs { + u32 adda[RTW8723X_IQK_ADDA_REG_NUM]; + u8 mac8[RTW8723X_IQK_MAC8_REG_NUM]; + u32 mac32[RTW8723X_IQK_MAC32_REG_NUM]; + u32 bb[RTW8723X_IQK_BB_REG_NUM]; + + u32 lte_path; + u32 lte_gnt; + + u32 bb_sel_btg; + u8 btg_sel; + + u8 igia; + u8 igib; +}; + +struct rtw8723x_common { + /* registers that must be backed up before IQK and restored after */ + u32 iqk_adda_regs[RTW8723X_IQK_ADDA_REG_NUM]; + u32 iqk_mac8_regs[RTW8723X_IQK_MAC8_REG_NUM]; + u32 iqk_mac32_regs[RTW8723X_IQK_MAC32_REG_NUM]; + u32 iqk_bb_regs[RTW8723X_IQK_BB_REG_NUM]; + + /* chip register definitions */ + struct rtw_ltecoex_addr ltecoex_addr; + struct rtw_rf_sipi_addr rf_sipi_addr[2]; + struct rtw_hw_reg dig[2]; + struct rtw_hw_reg dig_cck[1]; + struct rtw_prioq_addrs prioq_addrs; + + /* common functions */ + void (*lck)(struct rtw_dev *rtwdev); + int (*read_efuse)(struct rtw_dev *rtwdev, u8 *log_map); + int (*mac_init)(struct rtw_dev *rtwdev); + int (*mac_postinit)(struct rtw_dev *rtwdev); + void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); + void (*set_tx_power_index)(struct rtw_dev *rtwdev); + void (*efuse_grant)(struct rtw_dev *rtwdev, bool on); + void (*false_alarm_statistics)(struct rtw_dev *rtwdev); + void (*iqk_backup_regs)(struct rtw_dev *rtwdev, + struct rtw8723x_iqk_backup_regs *backup); + void (*iqk_restore_regs)(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup); + bool (*iqk_similarity_cmp)(struct rtw_dev *rtwdev, s32 result[][IQK_NR], + u8 c1, u8 c2); + u8 (*pwrtrack_get_limit_ofdm)(struct rtw_dev *rtwdev); + void (*pwrtrack_set_xtal)(struct rtw_dev *rtwdev, u8 therm_path, + u8 delta); + void (*coex_cfg_init)(struct rtw_dev *rtwdev); + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc); + void (*debug_txpwr_limit)(struct rtw_dev *rtwdev, + struct rtw_txpwr_idx *table, + int tx_path_count); +}; + +extern const struct rtw8723x_common rtw8723x_common; + +#define PATH_IQK_RETRY 2 +#define MAX_TOLERANCE 5 +#define IQK_TX_X_ERR 0x142 +#define IQK_TX_Y_ERR 0x42 +#define IQK_RX_X_ERR 0x132 +#define IQK_RX_Y_ERR 0x36 +#define IQK_RX_X_UPPER 0x11a +#define IQK_RX_X_LOWER 0xe6 +#define IQK_RX_Y_LMT 0x1a +#define IQK_TX_OK BIT(0) +#define IQK_RX_OK BIT(1) + +#define WLAN_TXQ_RPT_EN 0x1F + +#define SPUR_THRES 0x16 +#define DIS_3WIRE 0xccf000c0 +#define EN_3WIRE 0xccc000c0 +#define START_PSD 0x400000 +#define FREQ_CH5 0xfccd +#define FREQ_CH6 0xfc4d +#define FREQ_CH7 0xffcd +#define FREQ_CH8 0xff4d +#define FREQ_CH13 0xfccd +#define FREQ_CH14 0xff9a +#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) +#define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) +#define RFCFGCH_BW_20M (BIT(11) | BIT(10)) +#define RFCFGCH_BW_40M BIT(10) +#define BIT_MASK_RFMOD BIT(0) +#define BIT_LCK BIT(15) + +#define REG_GPIO_INTM 0x0048 +#define REG_BTG_SEL 0x0067 +#define BIT_MASK_BTG_WL BIT(7) +#define REG_LTECOEX_PATH_CONTROL 0x0070 +#define REG_LTECOEX_CTRL 0x07c0 +#define REG_LTECOEX_WRITE_DATA 0x07c4 +#define REG_LTECOEX_READ_DATA 0x07c8 +#define REG_PSDFN 0x0808 +#define REG_BB_PWR_SAV1_11N 0x0874 +#define REG_ANA_PARAM1 0x0880 +#define REG_ANALOG_P4 0x088c +#define REG_PSDRPT 0x08b4 +#define REG_FPGA1_RFMOD 0x0900 +#define REG_BB_SEL_BTG 0x0948 +#define REG_BBRX_DFIR 0x0954 +#define BIT_MASK_RXBB_DFIR GENMASK(27, 24) +#define BIT_RXBB_DFIR_EN BIT(19) +#define REG_CCK0_SYS 0x0a00 +#define BIT_CCK_SIDE_BAND BIT(4) +#define REG_CCK_ANT_SEL_11N 0x0a04 +#define REG_PWRTH 0x0a08 +#define REG_CCK_FA_RST_11N 0x0a2c +#define BIT_MASK_CCK_CNT_KEEP BIT(12) +#define BIT_MASK_CCK_CNT_EN BIT(13) +#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) +#define BIT_MASK_CCK_FA_KEEP BIT(14) +#define BIT_MASK_CCK_FA_EN BIT(15) +#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) +#define REG_CCK_FA_LSB_11N 0x0a5c +#define REG_CCK_FA_MSB_11N 0x0a58 +#define REG_CCK_CCA_CNT_11N 0x0a60 +#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) +#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) +#define REG_PWRTH2 0x0aa8 +#define REG_CSRATIO 0x0aaa +#define REG_OFDM_FA_HOLDC_11N 0x0c00 +#define BIT_MASK_OFDM_FA_KEEP BIT(31) +#define REG_BB_RX_PATH_11N 0x0c04 +#define REG_TRMUX_11N 0x0c08 +#define REG_OFDM_FA_RSTC_11N 0x0c0c +#define BIT_MASK_OFDM_FA_RST BIT(31) +#define REG_A_RXIQI 0x0c14 +#define BIT_MASK_RXIQ_S1_X 0x000003FF +#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 +#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) +#define REG_OFDM0_RXDSP 0x0c40 +#define BIT_MASK_RXDSP GENMASK(28, 24) +#define BIT_EN_RXDSP BIT(9) +#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c +#define BIT_MASK_OFDM0_EXT_A BIT(31) +#define BIT_MASK_OFDM0_EXT_C BIT(29) +#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) +#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) +#define BIT_MASK_OFDM0_EXTS_B (BIT(27) | BIT(25) | BIT(24)) +#define BIT_SET_OFDM0_EXTS_B(a, c, d) (((a) << 27) | ((c) << 25) | ((d) << 24)) +#define REG_OFDM0_XAAGC1 0x0c50 +#define REG_OFDM0_XBAGC1 0x0c58 +#define REG_AGCRSSI 0x0c78 +#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 +#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88 +#define BIT_MASK_TXIQ_ELM_A 0x03ff +#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ + ((a) & 0x03ff)) +#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) +#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) +#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) +#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 +#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) +#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 +#define BIT_MASK_RXIQ_S1_Y2 0xF0000000 +#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) +#define REG_TXIQ_AB_S0 0x0cd0 +#define BIT_MASK_TXIQ_A_S0 0x000007FE +#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) +#define BIT_MASK_TXIQ_B_S0 0x0007E000 +#define REG_TXIQ_CD_S0 0x0cd4 +#define BIT_MASK_TXIQ_C_S0 0x000007FE +#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) +#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) +#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) +#define REG_RXIQ_AB_S0 0x0cd8 +#define BIT_MASK_RXIQ_X_S0 0x000003FF +#define BIT_MASK_RXIQ_Y_S0 0x003FF000 +#define REG_OFDM_FA_TYPE1_11N 0x0cf0 +#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) +#define REG_OFDM_FA_RSTD_11N 0x0d00 +#define BIT_MASK_OFDM_FA_RST1 BIT(27) +#define BIT_MASK_OFDM_FA_KEEP1 BIT(31) +#define REG_CTX 0x0d03 +#define BIT_MASK_CTX_TYPE GENMASK(6, 4) +#define REG_OFDM1_CFOTRK 0x0d2c +#define BIT_EN_CFOTRK BIT(28) +#define REG_OFDM1_CSI1 0x0d40 +#define REG_OFDM1_CSI2 0x0d44 +#define REG_OFDM1_CSI3 0x0d48 +#define REG_OFDM1_CSI4 0x0d4c +#define REG_OFDM_FA_TYPE2_11N 0x0da0 +#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) +#define REG_OFDM_FA_TYPE3_11N 0x0da4 +#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) +#define REG_OFDM_FA_TYPE4_11N 0x0da8 +#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) +#define REG_FPGA0_IQK_11N 0x0e28 +#define BIT_MASK_IQK_MOD 0xffffff00 +#define EN_IQK 0x808000 +#define RST_IQK 0x000000 +#define REG_TXIQK_TONE_A_11N 0x0e30 +#define REG_RXIQK_TONE_A_11N 0x0e34 +#define REG_TXIQK_PI_A_11N 0x0e38 +#define REG_RXIQK_PI_A_11N 0x0e3c +#define REG_TXIQK_11N 0x0e40 +#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) +#define REG_RXIQK_11N 0x0e44 +#define REG_IQK_AGC_PTS_11N 0x0e48 +#define REG_IQK_AGC_RSP_11N 0x0e4c +#define REG_TX_IQK_TONE_B 0x0e50 +#define REG_RX_IQK_TONE_B 0x0e54 +#define REG_TXIQK_PI_B 0x0e58 +#define REG_RXIQK_PI_B 0x0e5c +#define REG_IQK_RES_TX 0x0e94 +#define BIT_MASK_RES_TX GENMASK(25, 16) +#define REG_IQK_RES_TY 0x0e9c +#define BIT_MASK_RES_TY GENMASK(25, 16) +#define REG_IQK_RES_RX 0x0ea4 +#define BIT_MASK_RES_RX GENMASK(25, 16) +#define REG_IQK_RES_RY 0x0eac +#define BIT_IQK_TX_FAIL BIT(28) +#define BIT_IQK_RX_FAIL BIT(27) +#define BIT_IQK_DONE BIT(26) +#define BIT_MASK_RES_RY GENMASK(25, 16) +#define REG_PAGE_F_RST_11N 0x0f14 +#define BIT_MASK_F_RST_ALL BIT(16) +#define REG_IGI_C_11N 0x0f84 +#define REG_IGI_D_11N 0x0f88 +#define REG_HT_CRC32_CNT_11N 0x0f90 +#define BIT_MASK_HT_CRC_OK GENMASK(15, 0) +#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) +#define REG_OFDM_CRC32_CNT_11N 0x0f94 +#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) +#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) +#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 + +#define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing) +#define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing) +#define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing) +#define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing) + +static inline s32 iqkxy_to_s32(s32 val) +{ + /* val is Q10.8 */ + return sign_extend32(val, 9); +} + +static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) +{ + /* x, y and return value are Q10.8 */ + s32 t; + + t = x * y; + if (ext) + *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ + + return (t >> 8); /* Q.16 --> Q.8 */ +} + +static inline +void rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, + struct rtw_txpwr_idx *table, + int tx_path_count) +{ + rtw8723x_common.debug_txpwr_limit(rtwdev, table, tx_path_count); +} + +static inline void rtw8723x_lck(struct rtw_dev *rtwdev) +{ + rtw8723x_common.lck(rtwdev); +} + +static inline int rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + return rtw8723x_common.read_efuse(rtwdev, log_map); +} + +static inline int rtw8723x_mac_init(struct rtw_dev *rtwdev) +{ + return rtw8723x_common.mac_init(rtwdev); +} + +static inline int rtw8723x_mac_postinit(struct rtw_dev *rtwdev) +{ + return rtw8723x_common.mac_postinit(rtwdev); +} + +static inline void rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + rtw8723x_common.cfg_ldo25(rtwdev, enable); +} + +static inline void rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) +{ + rtw8723x_common.set_tx_power_index(rtwdev); +} + +static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + rtw8723x_common.efuse_grant(rtwdev, on); +} + +static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + rtw8723x_common.false_alarm_statistics(rtwdev); +} + +static inline +void rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, + struct rtw8723x_iqk_backup_regs *backup) +{ + rtw8723x_common.iqk_backup_regs(rtwdev, backup); +} + +static inline +void rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + rtw8723x_common.iqk_restore_regs(rtwdev, backup); +} + +static inline +bool rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], + u8 c1, u8 c2) +{ + return rtw8723x_common.iqk_similarity_cmp(rtwdev, result, c1, c2); +} + +static inline u8 rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) +{ + return rtw8723x_common.pwrtrack_get_limit_ofdm(rtwdev); +} + +static inline +void rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, + u8 delta) +{ + rtw8723x_common.pwrtrack_set_xtal(rtwdev, therm_path, delta); +} + +static inline void rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) +{ + rtw8723x_common.coex_cfg_init(rtwdev); +} + +static inline +void rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + rtw8723x_common.fill_txdesc_checksum(rtwdev, pkt_info, txdesc); +} + +/* IQK helper functions, defined as inline so they can be shared + * without needing an EXPORT_SYMBOL each. + */ +static inline void +rtw8723x_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, + struct rtw8723x_iqk_backup_regs *backup) +{ + backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", + backup->btg_sel); +} + +static inline void rtw8723x_iqk_config_path_ctrl(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +} + +static inline void +rtw8723x_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *backup) +{ + rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +} + +static inline void +rtw8723x_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, + struct rtw8723x_iqk_backup_regs *backup) +{ + backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); + mdelay(1); + backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", + backup->lte_gnt); +} + +static inline void +rtw8723x_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev, + u32 write_data) +{ + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, write_data); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); + rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, + BIT_LTE_MUX_CTRL_PATH, 0x1); +} + +static inline void +rtw8723x_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, + const struct rtw8723x_iqk_backup_regs *bak) +{ + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); + rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); +} + +/* set all ADDA registers to the given value */ +static inline void rtw8723x_iqk_path_adda_on(struct rtw_dev *rtwdev, u32 value) +{ + for (int i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) + rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], value); +} + +#endif /* __RTW8723X_H__ */ diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c new file mode 100644 index 000000000..2078eb6e3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c @@ -0,0 +1,1125 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "phy.h" +#include "reg.h" +#include "rtw88xxa.h" +#include "rtw8812a.h" +#include "rtw8812a_table.h" +#include "tx.h" + +static void rtw8812a_power_off(struct rtw_dev *rtwdev) +{ + rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a); +} + +static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) +{ + s8 rx_pwr_all = 0; + + switch (lna_idx) { + case 7: + if (vga_idx <= 27) + rx_pwr_all = -94 + 2 * (27 - vga_idx); + else + rx_pwr_all = -94; + break; + case 6: + rx_pwr_all = -42 + 2 * (2 - vga_idx); + break; + case 5: + rx_pwr_all = -36 + 2 * (7 - vga_idx); + break; + case 4: + rx_pwr_all = -30 + 2 * (7 - vga_idx); + break; + case 3: + rx_pwr_all = -18 + 2 * (7 - vga_idx); + break; + case 2: + rx_pwr_all = 2 * (5 - vga_idx); + break; + case 1: + rx_pwr_all = 14 - 2 * vga_idx; + break; + case 0: + rx_pwr_all = 20 - 2 * vga_idx; + break; + default: + break; + } + + return rx_pwr_all; +} + +static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, + rtw8812a_cck_rx_pwr); + + if (pkt_stat->rate >= DESC_RATE6M) + return; + + if (rtwdev->hal.cck_high_power) + return; + + if (pkt_stat->rssi >= 80) + pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + + ((pkt_stat->rssi - 80) >> 1) + 80; + else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) + pkt_stat->rssi += 3; +} + +static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ +} + +static void rtw8812a_do_lck(struct rtw_dev *rtwdev) +{ + u32 cont_tx, lc_cal, i; + + cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); + + lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + + if (!cont_tx) + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); + + mdelay(150); + + for (i = 0; i < 5; i++) { + if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) + break; + + mdelay(10); + } + + if (i == 5) + rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); + + if (!cont_tx) + rtw_write8(rtwdev, REG_TXPAUSE, 0); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); +} + +static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, + u32 *rfb_backup, const u32 *backup_rf_reg, + u32 rf_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Save RF Parameters */ + for (i = 0; i < rf_num; i++) { + rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, + backup_rf_reg[i], MASKDWORD); + rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, + backup_rf_reg[i], MASKDWORD); + } +} + +static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path path, + const u32 *backup_rf_reg, + u32 *RF_backup, u32 rf_reg_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + for (i = 0; i < rf_reg_num; i++) + rtw_write_rf(rtwdev, path, backup_rf_reg[i], + RFREG_MASK, RF_backup[i]); + + rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); +} + +static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Reload AFE Parameters */ + for (i = 0; i < afe_num; i++) + rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1); + rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1); + + rtw_write32(rtwdev, REG_TXTONEB, 0x0); + rtw_write32(rtwdev, REG_RXTONEB, 0x0); + rtw_write32(rtwdev, REG_TXPITMB, 0x0); + rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1); + rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1); +} + +static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, + unsigned int rx_x, unsigned int rx_y) +{ + switch (path) { + case RF_PATH_A: + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (rx_x >> 1 >= 0x112 || + (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, 0x100); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, 0); + } else { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, rx_y >> 1); + } + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x = %x;;rx_y = %x ====>fill to IQC\n", + rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", + rtw_read32(rtwdev, REG_RX_IQC_AB_A)); + break; + case RF_PATH_B: + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (rx_x >> 1 >= 0x112 || + (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x000003ff, 0x100); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x03ff0000, 0); + } else { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x03ff0000, rx_y >> 1); + } + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x = %x;;rx_y = %x ====>fill to IQC\n", + rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", + rtw_read32(rtwdev, REG_RX_IQC_AB_B)); + break; + default: + break; + } +} + +static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, + unsigned int tx_x, unsigned int tx_y) +{ + switch (path) { + case RF_PATH_A: + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x = %x;;tx_y = %x =====> fill to IQC\n", + tx_x & 0x000007ff, tx_y & 0x000007ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", + rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff), + rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff)); + break; + case RF_PATH_B: + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x = %x;;tx_y = %x =====> fill to IQC\n", + tx_x & 0x000007ff, tx_y & 0x000007ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", + rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff), + rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff)); + break; + default: + break; + } +} + +static void rtw8812a_iqk(struct rtw_dev *rtwdev) +{ + int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10]; + int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10]; + bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; + bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; + u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; + int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0; + int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool tx0_fail = true, rx0_fail = true; + bool tx1_fail = true, rx1_fail = true; + u8 cal0_retry, cal1_retry; + u8 delay_count; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* ========path-A AFE all on======== */ + /* Port 0 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); + + /* Port 1 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); + + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); + + /* hardware 3-wire off */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); + rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); + + /* DAC/ADC sampling rate (160 MHz) */ + rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); + rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* ====== path A TX IQK RF setting ====== */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + + /* ====== path B TX IQK RF setting ====== */ + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001); + + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1); + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (efuse->ext_pa_5g) { + if (efuse->rfe_option == 1) { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3); + } else { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7); + } + } else { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1); + } + + if (rtwdev->hal.current_band_type == RTW_BAND_5G) { + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); + rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96); + } else { + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); + rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96); + + if (efuse->rfe_option == 3) { + if (efuse->ext_pa_2g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403e3); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + } + } + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000); + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10); + rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000); + + cal0_retry = 0; + cal1_retry = 0; + while (1) { + /* one shot */ + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); + + for (delay_count = 0; delay_count < 20; delay_count++) { + if (!tx0_finish) + iqk0_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); + if (!tx1_finish) + iqk1_ready = rtw_read32_mask(rtwdev, + REG_IQKB_END, + BIT(10)); + if (iqk0_ready && iqk1_ready) + break; + + mdelay(1); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", + delay_count); + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); + tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12)); + + if (!(tx0_fail || tx0_finish)) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); + tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); + tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", + tx0_avg, tx_x0_temp[tx0_avg], + tx0_avg, tx_y0_temp[tx0_avg]); + + tx_x0_temp[tx0_avg] <<= 21; + tx_y0_temp[tx0_avg] <<= 21; + + tx0_avg++; + } else { + cal0_retry++; + if (cal0_retry == 10) + break; + } + + if (!(tx1_fail || tx1_finish)) { + rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); + tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); + tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", + tx1_avg, tx_x1_temp[tx1_avg], + tx1_avg, tx_y1_temp[tx1_avg]); + + tx_x1_temp[tx1_avg] <<= 21; + tx_y1_temp[tx1_avg] <<= 21; + + tx1_avg++; + } else { + cal1_retry++; + if (cal1_retry == 10) + break; + } + } else { + cal0_retry++; + cal1_retry++; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "delay 20ms TX IQK Not Ready!!!!!\n"); + + if (cal0_retry == 10) + break; + } + + if (tx0_avg >= 2) + tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4, + tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0, + false, false); + + if (tx1_avg >= 2) + tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4, + tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1, + false, false); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx0_average = %d, tx1_average = %d\n", + tx0_avg, tx1_avg); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx0_finish = %d, tx1_finish = %d\n", + tx0_finish, tx1_finish); + + if (tx0_finish && tx1_finish) + break; + + if ((cal0_retry + tx0_avg) >= 10 || + (cal1_retry + tx1_avg) >= 10) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* Load LOK */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00)); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (tx0_finish) { + /* ====== path A RX IQK RF setting====== */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x3f7ff); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfe7bf); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + } + if (tx1_finish) { + /* ====== path B RX IQK RF setting====== */ + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x3f7ff); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfe7bf); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); + } + + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + + if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); + else + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890); + + if (efuse->rfe_option == 1) { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); + } + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (tx0_finish) { + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119); + } + if (tx1_finish) { + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10); + rtw_write32(rtwdev, REG_TXPITMB, 0x82140119); + } + + cal0_retry = 0; + cal1_retry = 0; + while (1) { + /* one shot */ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + if (tx0_finish) { + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + tx_x0 & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + tx_y0 & 0x000007ff); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (efuse->rfe_option == 1) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + mdelay(5); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + } + + if (tx1_finish) { + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + tx_x1 & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + tx_y1 & 0x000007ff); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (efuse->rfe_option == 1) + rtw_write32(rtwdev, REG_RXPITMB, 0x28161500); + else + rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); + mdelay(5); + rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); + } + + for (delay_count = 0; delay_count < 20; delay_count++) { + if (!rx0_finish && tx0_finish) + iqk0_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); + if (!rx1_finish && tx1_finish) + iqk1_ready = rtw_read32_mask(rtwdev, + REG_IQKB_END, + BIT(10)); + if (iqk0_ready && iqk1_ready) + break; + + mdelay(1); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", + delay_count); + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============RXIQK Check============== */ + rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); + rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11)); + + if (!(rx0_fail || rx0_finish) && tx0_finish) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); + rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); + rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", + rx0_avg, rx_x0_temp[rx0_avg], + rx0_avg, rx_y0_temp[rx0_avg]); + + rx_x0_temp[rx0_avg] <<= 21; + rx_y0_temp[rx0_avg] <<= 21; + + rx0_avg++; + } else { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "1. RXA_cal_retry = %d\n", cal0_retry); + + cal0_retry++; + if (cal0_retry == 10) + break; + } + + if (!(rx1_fail || rx1_finish) && tx1_finish) { + rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); + rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); + rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", + rx1_avg, rx_x1_temp[rx1_avg], + rx1_avg, rx_y1_temp[rx1_avg]); + + rx_x1_temp[rx1_avg] <<= 21; + rx_y1_temp[rx1_avg] <<= 21; + + rx1_avg++; + } else { + cal1_retry++; + if (cal1_retry == 10) + break; + } + } else { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "2. RXA_cal_retry = %d\n", cal0_retry); + + cal0_retry++; + cal1_retry++; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "delay 20ms RX IQK Not Ready!!!!!\n"); + + if (cal0_retry == 10) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", + cal0_retry); + + if (rx0_avg >= 2) + rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4, + rx_x0_temp, rx_y0_temp, + &rx_x0, &rx_y0, + true, false); + + if (rx1_avg >= 2) + rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4, + rx_x1_temp, rx_y1_temp, + &rx_x1, &rx_y1, + true, false); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx0_average = %d, rx1_average = %d\n", + rx0_avg, rx1_avg); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx0_finish = %d, rx1_finish = %d\n", + rx0_finish, rx1_finish); + + if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) + break; + + if ((cal0_retry + rx0_avg) >= 10 || + (cal1_retry + rx1_avg) >= 10 || + rx0_avg == 3 || rx1_avg == 3) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); + + /* FillIQK Result */ + rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); + + if (tx0_finish) + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0); + else + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + + if (rx0_finish) + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0); + else + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); + + if (tx1_finish) + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1); + else + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); + + if (rx1_finish) + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1); + else + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); +} + +#define MACBB_REG_NUM_8812A 9 +#define AFE_REG_NUM_8812A 12 +#define RF_REG_NUM_8812A 3 + +static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) +{ + static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { + 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c + }; + static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { + 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, + 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 + }; + static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { + 0x65, 0x8f, 0x0 + }; + u32 macbb_backup[MACBB_REG_NUM_8812A] = {}; + u32 afe_backup[AFE_REG_NUM_8812A] = {}; + u32 rfa_backup[RF_REG_NUM_8812A] = {}; + u32 rfb_backup[RF_REG_NUM_8812A] = {}; + u32 reg_cb8, reg_eb8; + + rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8812A); + + rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); + reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); + reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); + rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); + + rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8812A); + rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, + backup_rf_reg, RF_REG_NUM_8812A); + + rtw88xxa_iqk_configure_mac(rtwdev); + + rtw8812a_iqk(rtwdev); + + rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, + rfa_backup, RF_REG_NUM_8812A); + rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, + rfb_backup, RF_REG_NUM_8812A); + + rtw8812a_iqk_restore_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8812A); + + rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); + rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); + rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); + rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); + + rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8812A); +} + +static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev) +{ + u8 channel = rtwdev->hal.current_channel; + + rtw8812a_do_iqk(rtwdev); + + /* The official driver wants to do this after connecting + * but before first writing a new igi (phydm_get_new_igi). + * Here seems close enough. + */ + if (channel >= 36 && channel <= 64) + rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); + else if (channel >= 100) + rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); +} + +static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8812a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u8 ledcfg; + + ledcfg = rtw_read8(rtwdev, REG_LED_CFG); + ledcfg &= BIT(6) | BIT(4); + ledcfg |= BIT(5); + + if (brightness == LED_OFF) + ledcfg |= BIT(3); + + rtw_write8(rtwdev, REG_LED_CFG, ledcfg); +} + +static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + fill_txdesc_checksum_common(txdesc, 16); +} + +static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev) +{ +} + +static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ +} + +static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static const struct rtw_chip_ops rtw8812a_ops = { + .power_on = rtw88xxa_power_on, + .power_off = rtw8812a_power_off, + .phy_set_param = NULL, + .read_efuse = rtw88xxa_read_efuse, + .query_phy_status = rtw8812a_query_phy_status, + .set_channel = rtw88xxa_set_channel, + .mac_init = NULL, + .mac_postinit = NULL, + .read_rf = rtw88xxa_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw88xxa_set_tx_power_index, + .cfg_ldo25 = rtw8812a_cfg_ldo25, + .efuse_grant = rtw88xxa_efuse_grant, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw88xxa_false_alarm_statistics, + .phy_calibration = rtw8812a_phy_calibration, + .cck_pd_set = rtw88xxa_phy_cck_pd_set, + .pwr_track = rtw8812a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .led_set = rtw8812a_led_set, + .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, + .coex_set_init = rtw8812a_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = NULL, + .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, +}; + +static const struct rtw_page_table page_table_8812a[] = { + /* hq_num, nq_num, lq_num, exq_num, gapq_num */ + {0, 0, 0, 0, 0}, /* SDIO */ + {0, 0, 0, 0, 0}, /* PCI */ + {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ + {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ + {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ +}; + +static const struct rtw_rqpn rqpn_table_8812a[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8812a = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, + }, + .wsize = false, +}; + +static const struct rtw_hw_reg rtw8812a_dig[] = { + [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, + [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [2] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, +}; + +static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40}; +static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101}; + +static const struct coex_rf_para rf_para_tx_8812a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {8, 17, true, 4}, + {7, 18, true, 4}, + {6, 19, true, 4}, + {5, 20, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8812a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {3, 24, true, 5}, + {2, 26, true, 5}, + {1, 27, true, 5}, + {0, 28, true, 5} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a)); + +const struct rtw_chip_info rtw8812a_hw_spec = { + .ops = &rtw8812a_ops, + .id = RTW_CHIP_TYPE_8812A, + .fw_name = "rtw88/rtw8812a_fw.bin", + .wlan_cpu = RTW_WCPU_8051, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 0, + .txff_size = 131072, + .rxff_size = 16128, + .rsvd_drv_pg_num = 9, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 512, + .dig_min = 0x20, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8812a, + .pwr_off_seq = card_disable_flow_8812a, + .page_table = page_table_8812a, + .rqpn_table = rqpn_table_8812a, + .prioq_addrs = &prioq_addrs_8812a, + .intf_table = NULL, + .dig = rtw8812a_dig, + .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, + .ltecoex_addr = NULL, + .mac_tbl = &rtw8812a_mac_tbl, + .agc_tbl = &rtw8812a_agc_tbl, + .bb_tbl = &rtw8812a_bb_tbl, + .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, + .rfe_defs = rtw8812a_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), + .rx_ldpc = false, + .amsdu_in_ampdu = true, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .usb_tx_agg_desc_num = 1, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0, /* no coex code in 8812au driver */ + .bt_desired_ver = 0, + .scbd_support = false, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8812a, + .bt_rssi_step = bt_rssi_step_8812a, + .table_sant_num = 0, + .table_sant = NULL, + .table_nsant_num = 0, + .table_nsant = NULL, + .tdma_sant_num = 0, + .tdma_sant = NULL, + .tdma_nsant_num = 0, + .tdma_nsant = NULL, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a), + .wl_rf_para_tx = rf_para_tx_8812a, + .wl_rf_para_rx = rf_para_rx_8812a, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = 0, + .afh_5g = NULL, + .coex_info_hw_regs_num = 0, + .coex_info_hw_regs = NULL, +}; +EXPORT_SYMBOL(rtw8812a_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.h b/drivers/net/wireless/realtek/rtw88/rtw8812a.h new file mode 100644 index 000000000..82dab59e3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW8812A_H__ +#define __RTW8812A_H__ + +extern const struct rtw_chip_info rtw8812a_hw_spec; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c new file mode 100644 index 000000000..048efbbd4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c @@ -0,0 +1,2812 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8812a_table.h" + +static const u32 rtw8812a_mac[] = { + 0x010, 0x0000000C, + 0x80000200, 0x00000000, 0x40000000, 0x00000000, + 0x011, 0x00000066, + 0xA0000000, 0x00000000, + 0x011, 0x0000005A, + 0xB0000000, 0x00000000, + 0x025, 0x0000000F, + 0x072, 0x00000000, + 0x420, 0x00000080, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000002, + 0x435, 0x00000003, + 0x436, 0x00000005, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43A, 0x00000000, + 0x43B, 0x00000001, + 0x43C, 0x00000002, + 0x43D, 0x00000003, + 0x43E, 0x00000005, + 0x43F, 0x00000007, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x45B, 0x00000080, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x604, 0x00000009, + 0x605, 0x00000030, + 0x607, 0x00000003, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000080, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8812a_mac, rtw_phy_cfg_mac); + +static const u32 rtw8812a_agc[] = { + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000001, + 0x81C, 0xFB020001, + 0x81C, 0xFA040001, + 0x81C, 0xF9060001, + 0x81C, 0xF8080001, + 0x81C, 0xF70A0001, + 0x81C, 0xF60C0001, + 0x81C, 0xF50E0001, + 0x81C, 0xF4100001, + 0x81C, 0xF3120001, + 0x81C, 0xF2140001, + 0x81C, 0xF1160001, + 0x81C, 0xF0180001, + 0x81C, 0xEF1A0001, + 0x81C, 0xEE1C0001, + 0x81C, 0xED1E0001, + 0x81C, 0xEC200001, + 0x81C, 0xEB220001, + 0x81C, 0xEA240001, + 0x81C, 0xCD260001, + 0x81C, 0xCC280001, + 0x81C, 0xCB2A0001, + 0x81C, 0xCA2C0001, + 0x81C, 0xC92E0001, + 0x81C, 0xC8300001, + 0x81C, 0xA6320001, + 0x81C, 0xA5340001, + 0x81C, 0xA4360001, + 0x81C, 0xA3380001, + 0x81C, 0xA23A0001, + 0x81C, 0x883C0001, + 0x81C, 0x873E0001, + 0x81C, 0x86400001, + 0x81C, 0x85420001, + 0x81C, 0x84440001, + 0x81C, 0x83460001, + 0x81C, 0x82480001, + 0x81C, 0x814A0001, + 0x81C, 0x484C0001, + 0x81C, 0x474E0001, + 0x81C, 0x46500001, + 0x81C, 0x45520001, + 0x81C, 0x44540001, + 0x81C, 0x43560001, + 0x81C, 0x42580001, + 0x81C, 0x415A0001, + 0x81C, 0x255C0001, + 0x81C, 0x245E0001, + 0x81C, 0x23600001, + 0x81C, 0x22620001, + 0x81C, 0x21640001, + 0x81C, 0x21660001, + 0x81C, 0x21680001, + 0x81C, 0x216A0001, + 0x81C, 0x216C0001, + 0x81C, 0x216E0001, + 0x81C, 0x21700001, + 0x81C, 0x21720001, + 0x81C, 0x21740001, + 0x81C, 0x21760001, + 0x81C, 0x21780001, + 0x81C, 0x217A0001, + 0x81C, 0x217C0001, + 0x81C, 0x217E0001, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x81C, 0xF9000001, + 0x81C, 0xF8020001, + 0x81C, 0xF7040001, + 0x81C, 0xF6060001, + 0x81C, 0xF5080001, + 0x81C, 0xF40A0001, + 0x81C, 0xF30C0001, + 0x81C, 0xF20E0001, + 0x81C, 0xF1100001, + 0x81C, 0xF0120001, + 0x81C, 0xEF140001, + 0x81C, 0xEE160001, + 0x81C, 0xED180001, + 0x81C, 0xEC1A0001, + 0x81C, 0xEB1C0001, + 0x81C, 0xEA1E0001, + 0x81C, 0xCD200001, + 0x81C, 0xCC220001, + 0x81C, 0xCB240001, + 0x81C, 0xCA260001, + 0x81C, 0xC9280001, + 0x81C, 0xC82A0001, + 0x81C, 0xC72C0001, + 0x81C, 0xC62E0001, + 0x81C, 0xA5300001, + 0x81C, 0xA4320001, + 0x81C, 0xA3340001, + 0x81C, 0xA2360001, + 0x81C, 0x88380001, + 0x81C, 0x873A0001, + 0x81C, 0x863C0001, + 0x81C, 0x853E0001, + 0x81C, 0x84400001, + 0x81C, 0x83420001, + 0x81C, 0x82440001, + 0x81C, 0x81460001, + 0x81C, 0x48480001, + 0x81C, 0x474A0001, + 0x81C, 0x464C0001, + 0x81C, 0x454E0001, + 0x81C, 0x44500001, + 0x81C, 0x43520001, + 0x81C, 0x42540001, + 0x81C, 0x41560001, + 0x81C, 0x25580001, + 0x81C, 0x245A0001, + 0x81C, 0x235C0001, + 0x81C, 0x225E0001, + 0x81C, 0x21600001, + 0x81C, 0x21620001, + 0x81C, 0x21640001, + 0x81C, 0x21660001, + 0x81C, 0x21680001, + 0x81C, 0x216A0001, + 0x81C, 0x236C0001, + 0x81C, 0x226E0001, + 0x81C, 0x21700001, + 0x81C, 0x21720001, + 0x81C, 0x21740001, + 0x81C, 0x21760001, + 0x81C, 0x21780001, + 0x81C, 0x217A0001, + 0x81C, 0x217C0001, + 0x81C, 0x217E0001, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000001, + 0x81C, 0xFF020001, + 0x81C, 0xFF040001, + 0x81C, 0xFF060001, + 0x81C, 0xFF080001, + 0x81C, 0xFE0A0001, + 0x81C, 0xFD0C0001, + 0x81C, 0xFC0E0001, + 0x81C, 0xFB100001, + 0x81C, 0xFA120001, + 0x81C, 0xF9140001, + 0x81C, 0xF8160001, + 0x81C, 0xF7180001, + 0x81C, 0xF61A0001, + 0x81C, 0xF51C0001, + 0x81C, 0xF41E0001, + 0x81C, 0xF3200001, + 0x81C, 0xF2220001, + 0x81C, 0xF1240001, + 0x81C, 0xF0260001, + 0x81C, 0xEF280001, + 0x81C, 0xEE2A0001, + 0x81C, 0xED2C0001, + 0x81C, 0xEC2E0001, + 0x81C, 0xEB300001, + 0x81C, 0xEA320001, + 0x81C, 0xE9340001, + 0x81C, 0xE8360001, + 0x81C, 0xE7380001, + 0x81C, 0xE63A0001, + 0x81C, 0xE53C0001, + 0x81C, 0xC73E0001, + 0x81C, 0xC6400001, + 0x81C, 0xC5420001, + 0x81C, 0xC4440001, + 0x81C, 0xC3460001, + 0x81C, 0xC2480001, + 0x81C, 0xC14A0001, + 0x81C, 0xA74C0001, + 0x81C, 0xA64E0001, + 0x81C, 0xA5500001, + 0x81C, 0xA4520001, + 0x81C, 0xA3540001, + 0x81C, 0xA2560001, + 0x81C, 0xA1580001, + 0x81C, 0x675A0001, + 0x81C, 0x665C0001, + 0x81C, 0x655E0001, + 0x81C, 0x64600001, + 0x81C, 0x63620001, + 0x81C, 0x48640001, + 0x81C, 0x47660001, + 0x81C, 0x46680001, + 0x81C, 0x456A0001, + 0x81C, 0x446C0001, + 0x81C, 0x436E0001, + 0x81C, 0x42700001, + 0x81C, 0x41720001, + 0x81C, 0x41740001, + 0x81C, 0x41760001, + 0x81C, 0x41780001, + 0x81C, 0x417A0001, + 0x81C, 0x417C0001, + 0x81C, 0x417E0001, + 0xB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC800001, + 0x81C, 0xFB820001, + 0x81C, 0xFA840001, + 0x81C, 0xF9860001, + 0x81C, 0xF8880001, + 0x81C, 0xF78A0001, + 0x81C, 0xF68C0001, + 0x81C, 0xF58E0001, + 0x81C, 0xF4900001, + 0x81C, 0xF3920001, + 0x81C, 0xF2940001, + 0x81C, 0xF1960001, + 0x81C, 0xF0980001, + 0x81C, 0xEF9A0001, + 0x81C, 0xEE9C0001, + 0x81C, 0xED9E0001, + 0x81C, 0xECA00001, + 0x81C, 0xEBA20001, + 0x81C, 0xEAA40001, + 0x81C, 0xE9A60001, + 0x81C, 0xE8A80001, + 0x81C, 0xE7AA0001, + 0x81C, 0xE6AC0001, + 0x81C, 0xE5AE0001, + 0x81C, 0xE4B00001, + 0x81C, 0xE3B20001, + 0x81C, 0xA8B40001, + 0x81C, 0xA7B60001, + 0x81C, 0xA6B80001, + 0x81C, 0xA5BA0001, + 0x81C, 0xA4BC0001, + 0x81C, 0xA3BE0001, + 0x81C, 0xA2C00001, + 0x81C, 0xA1C20001, + 0x81C, 0x68C40001, + 0x81C, 0x67C60001, + 0x81C, 0x66C80001, + 0x81C, 0x65CA0001, + 0x81C, 0x64CC0001, + 0x81C, 0x47CE0001, + 0x81C, 0x46D00001, + 0x81C, 0x45D20001, + 0x81C, 0x44D40001, + 0x81C, 0x43D60001, + 0x81C, 0x42D80001, + 0x81C, 0x08DA0001, + 0x81C, 0x07DC0001, + 0x81C, 0x06DE0001, + 0x81C, 0x05E00001, + 0x81C, 0x04E20001, + 0x81C, 0x03E40001, + 0x81C, 0x02E60001, + 0x81C, 0x01E80001, + 0x81C, 0x01EA0001, + 0x81C, 0x01EC0001, + 0x81C, 0x01EE0001, + 0x81C, 0x01F00001, + 0x81C, 0x01F20001, + 0x81C, 0x01F40001, + 0x81C, 0x01F60001, + 0x81C, 0x01F80001, + 0x81C, 0x01FA0001, + 0x81C, 0x01FC0001, + 0x81C, 0x01FE0001, + 0xA0000000, 0x00000000, + 0x81C, 0xFF800001, + 0x81C, 0xFF820001, + 0x81C, 0xFF840001, + 0x81C, 0xFE860001, + 0x81C, 0xFD880001, + 0x81C, 0xFC8A0001, + 0x81C, 0xFB8C0001, + 0x81C, 0xFA8E0001, + 0x81C, 0xF9900001, + 0x81C, 0xF8920001, + 0x81C, 0xF7940001, + 0x81C, 0xF6960001, + 0x81C, 0xF5980001, + 0x81C, 0xF49A0001, + 0x81C, 0xF39C0001, + 0x81C, 0xF29E0001, + 0x81C, 0xF1A00001, + 0x81C, 0xF0A20001, + 0x81C, 0xEFA40001, + 0x81C, 0xEEA60001, + 0x81C, 0xEDA80001, + 0x81C, 0xECAA0001, + 0x81C, 0xEBAC0001, + 0x81C, 0xEAAE0001, + 0x81C, 0xE9B00001, + 0x81C, 0xE8B20001, + 0x81C, 0xE7B40001, + 0x81C, 0xE6B60001, + 0x81C, 0xE5B80001, + 0x81C, 0xE4BA0001, + 0x81C, 0xE3BC0001, + 0x81C, 0xA8BE0001, + 0x81C, 0xA7C00001, + 0x81C, 0xA6C20001, + 0x81C, 0xA5C40001, + 0x81C, 0xA4C60001, + 0x81C, 0xA3C80001, + 0x81C, 0xA2CA0001, + 0x81C, 0xA1CC0001, + 0x81C, 0x68CE0001, + 0x81C, 0x67D00001, + 0x81C, 0x66D20001, + 0x81C, 0x65D40001, + 0x81C, 0x64D60001, + 0x81C, 0x47D80001, + 0x81C, 0x46DA0001, + 0x81C, 0x45DC0001, + 0x81C, 0x44DE0001, + 0x81C, 0x43E00001, + 0x81C, 0x42E20001, + 0x81C, 0x08E40001, + 0x81C, 0x07E60001, + 0x81C, 0x06E80001, + 0x81C, 0x05EA0001, + 0x81C, 0x04EC0001, + 0x81C, 0x03EE0001, + 0x81C, 0x02F00001, + 0x81C, 0x01F20001, + 0x81C, 0x01F40001, + 0x81C, 0x01F60001, + 0x81C, 0x01F80001, + 0x81C, 0x01FA0001, + 0x81C, 0x01FC0001, + 0x81C, 0x01FE0001, + 0xB0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8812a_agc, rtw_phy_cfg_agc); + +static const u32 rtw8812a_agc_diff_lb[] = { + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0x47CE0001, + 0x81C, 0x46D00001, + 0x81C, 0x45D20001, + 0x81C, 0x44D40001, + 0x81C, 0x43D60001, + 0x81C, 0x42D80001, + 0x81C, 0x08DA0001, + 0x81C, 0x07DC0001, + 0x81C, 0x06DE0001, + 0x81C, 0x05E00001, + 0x81C, 0x04E20001, + 0x81C, 0x03E40001, + 0x81C, 0x02E60001, + 0xA0000000, 0x00000000, + 0x81C, 0x47D80001, + 0x81C, 0x46DA0001, + 0x81C, 0x45DC0001, + 0x81C, 0x44DE0001, + 0x81C, 0x43E00001, + 0x81C, 0x42E20001, + 0x81C, 0x08E40001, + 0x81C, 0x07E60001, + 0x81C, 0x06E80001, + 0x81C, 0x05EA0001, + 0x81C, 0x04EC0001, + 0x81C, 0x03EE0001, + 0x81C, 0x02F00001, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_lb, rtw_phy_cfg_agc); + +static const u32 rtw8812a_agc_diff_hb[] = { + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0x45CE0001, + 0x81C, 0x44D00001, + 0x81C, 0x43D20001, + 0x81C, 0x42D40001, + 0x81C, 0x08D60001, + 0x81C, 0x07D80001, + 0x81C, 0x06DA0001, + 0x81C, 0x05DC0001, + 0x81C, 0x04DE0001, + 0x81C, 0x03E00001, + 0x81C, 0x02E20001, + 0x81C, 0x01E40001, + 0x81C, 0x01E60001, + 0xA0000000, 0x00000000, + 0x81C, 0x45D80001, + 0x81C, 0x44DA0001, + 0x81C, 0x43DC0001, + 0x81C, 0x42DE0001, + 0x81C, 0x08E00001, + 0x81C, 0x07E20001, + 0x81C, 0x06E40001, + 0x81C, 0x05E60001, + 0x81C, 0x04E80001, + 0x81C, 0x03EA0001, + 0x81C, 0x02EC0001, + 0x81C, 0x01EE0001, + 0x81C, 0x01F00001, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_hb, rtw_phy_cfg_agc); + +static const u32 rtw8812a_bb[] = { + 0x800, 0x8020D010, + 0x804, 0x080112E0, + 0x808, 0x0E028233, + 0x80C, 0x12131113, + 0x810, 0x20101263, + 0x814, 0x020C3D10, + 0x818, 0x03A00385, + 0x820, 0x00000000, + 0x824, 0x00030FE0, + 0x828, 0x00000000, + 0x82C, 0x002083DD, + 0x830, 0x2EAAEEB8, + 0x834, 0x0037A706, + 0x838, 0x06C89B44, + 0x83C, 0x0000095B, + 0x840, 0xC0000001, + 0x844, 0x40003CDE, + 0x848, 0x6210FF8B, + 0x84C, 0x6CFDFFB8, + 0x850, 0x28874706, + 0x854, 0x0001520C, + 0x858, 0x8060E000, + 0x85C, 0x74210168, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x338C2878, + 0x870, 0x03333333, + 0x874, 0x31602C2E, + 0x878, 0x00003152, + 0x87C, 0x000FC000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA202033E, + 0x8AC, 0x0FF0FA0A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0x6C10D7FF, + 0x8BC, 0x4CA520A3, + 0x8C0, 0x27F00020, + 0x8C4, 0x00000000, + 0x8C8, 0x00012D69, + 0x8CC, 0x08248492, + 0x8D0, 0x0000B800, + 0x8DC, 0x00000000, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8F8, 0x400002C0, + 0x8FC, 0x00000000, + 0x900, 0x00000701, + 0x90C, 0x00000000, + 0x910, 0x0000FC00, + 0x914, 0x00000404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x00000004, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00080080, + 0x9A8, 0x00000000, + 0x9AC, 0x00000000, + 0x9B0, 0x81081008, + 0x9B4, 0x00000000, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E4, 0x00000003, + 0x9E8, 0x000002D5, + 0xA00, 0x00D047C8, + 0xA04, 0x01FF000C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7F000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1217, + 0xA28, 0x00000305, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000008, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B2, + 0xA84, 0x001F8C80, + 0xB00, 0x03100000, + 0xB04, 0x0000B000, + 0xB08, 0xAE0201EB, + 0xB0C, 0x01003207, + 0xB10, 0x00009807, + 0xB14, 0x01000000, + 0xB18, 0x00000002, + 0xB1C, 0x00000002, + 0xB20, 0x0000001F, + 0xB24, 0x03020100, + 0xB28, 0x07060504, + 0xB2C, 0x0B0A0908, + 0xB30, 0x0F0E0D0C, + 0xB34, 0x13121110, + 0xB38, 0x17161514, + 0xB3C, 0x0000003A, + 0xB40, 0x00000000, + 0xB44, 0x00000000, + 0xB48, 0x13000032, + 0xB4C, 0x48080000, + 0xB50, 0x00000000, + 0xB54, 0x00000000, + 0xB58, 0x00000000, + 0xB5C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000003, + 0xC20, 0x12121212, + 0xC24, 0x12121212, + 0xC28, 0x12121212, + 0xC2C, 0x12121212, + 0xC30, 0x12121212, + 0xC34, 0x12121212, + 0xC38, 0x12121212, + 0xC3C, 0x12121212, + 0xC40, 0x12121212, + 0xC44, 0x12121212, + 0xC48, 0x12121212, + 0xC4C, 0x12121212, + 0xC50, 0x00000020, + 0xC54, 0x0008121C, + 0xC58, 0x30000C1C, + 0xC5C, 0x00000058, + 0xC60, 0x34344443, + 0xC64, 0x07003333, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0xC68, 0x59791979, + 0xA0000000, 0x00000000, + 0xC68, 0x59799979, + 0xB0000000, 0x00000000, + 0xC6C, 0x59795979, + 0xC70, 0x19795979, + 0xC74, 0x19795979, + 0xC78, 0x19791979, + 0xC7C, 0x19791979, + 0xC80, 0x19791979, + 0xC84, 0x19791979, + 0xC94, 0x0100005C, + 0xC98, 0x00000000, + 0xC9C, 0x00000000, + 0xCA0, 0x00000029, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCB0, 0x77547777, + 0xCB4, 0x00000077, + 0xCB8, 0x00508242, + 0xE00, 0x00000007, + 0xE04, 0x00042020, + 0xE08, 0x80410231, + 0xE0C, 0x00000000, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE1C, 0x40000003, + 0xE20, 0x12121212, + 0xE24, 0x12121212, + 0xE28, 0x12121212, + 0xE2C, 0x12121212, + 0xE30, 0x12121212, + 0xE34, 0x12121212, + 0xE38, 0x12121212, + 0xE3C, 0x12121212, + 0xE40, 0x12121212, + 0xE44, 0x12121212, + 0xE48, 0x12121212, + 0xE4C, 0x12121212, + 0xE50, 0x00000020, + 0xE54, 0x0008121C, + 0xE58, 0x30000C1C, + 0xE5C, 0x00000058, + 0xE60, 0x34344443, + 0xE64, 0x07003333, + 0xE68, 0x59791979, + 0xE6C, 0x59795979, + 0xE70, 0x19795979, + 0xE74, 0x19795979, + 0xE78, 0x19791979, + 0xE7C, 0x19791979, + 0xE80, 0x19791979, + 0xE84, 0x19791979, + 0xE94, 0x0100005C, + 0xE98, 0x00000000, + 0xE9C, 0x00000000, + 0xEA0, 0x00000029, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEB0, 0x77547777, + 0xEB4, 0x00000077, + 0xEB8, 0x00508242, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8812a_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg); + +static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg_rfe3[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303232, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303232, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303232, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303232, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322222, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303232, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22222426, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322222, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303232, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22222426, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg_rfe3); + +static const u32 rtw8812a_rf_a[] = { + 0x000, 0x00010000, + 0x018, 0x0001712A, + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x01E, 0x00080000, + 0x089, 0x00000080, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0xA0000000, 0x00000000, + 0x086, 0x00014B38, + 0xB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x08B, 0x00080180, + 0xA0000000, 0x00000000, + 0x08B, 0x00087180, + 0xB0000000, 0x00000000, + 0x0B1, 0x0001FC1A, + 0x0B3, 0x000F0810, + 0x0B4, 0x0001A78D, + 0x0BA, 0x00086180, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xA0000000, 0x00000000, + 0x03B, 0x00038A58, + 0x03B, 0x00037A58, + 0x03B, 0x0002A590, + 0x03B, 0x00027A50, + 0x03B, 0x00018248, + 0x03B, 0x00010240, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A4EE, + 0x034, 0x00009076, + 0x034, 0x00008073, + 0x034, 0x00007070, + 0x034, 0x0000606D, + 0x034, 0x0000506A, + 0x034, 0x00004049, + 0x034, 0x00003046, + 0x034, 0x00002028, + 0x034, 0x00001025, + 0x034, 0x00000022, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF4, + 0x034, 0x00009DF1, + 0x034, 0x00008DEE, + 0x034, 0x00007DEB, + 0x034, 0x00006DE8, + 0x034, 0x00005DE5, + 0x034, 0x00004DE2, + 0x034, 0x00003CE6, + 0x034, 0x000024E7, + 0x034, 0x000014E4, + 0x034, 0x000004E1, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x0EF, 0x00000002, + 0x008, 0x00008400, + 0x018, 0x0001712A, + 0x0EF, 0x00001000, + 0x03A, 0x00000080, + 0x03B, 0x0003A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0003202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0002B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00023070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0001B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00012085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0000A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00002080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x0007A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0007202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0006B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00063070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0005B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00052085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0004A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00042080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x000BA02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x000B202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x000AB064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x000A3070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0009B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00092085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0008A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00082080, + 0x03C, 0x00010000, + 0x0EF, 0x00001100, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x00046050, + 0x034, 0x0004504D, + 0x034, 0x0004404A, + 0x034, 0x00043047, + 0x034, 0x0004200A, + 0x034, 0x00041007, + 0x034, 0x00040004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x0004604D, + 0x034, 0x0004504A, + 0x034, 0x00044047, + 0x034, 0x00043044, + 0x034, 0x00042007, + 0x034, 0x00041004, + 0x034, 0x00040001, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045DE6, + 0x034, 0x00044DE3, + 0x034, 0x000438C8, + 0x034, 0x000428C5, + 0x034, 0x000418C2, + 0x034, 0x000408C0, + 0xB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B2, + 0x034, 0x000290AF, + 0x034, 0x00028070, + 0x034, 0x0002706D, + 0x034, 0x00026050, + 0x034, 0x0002504D, + 0x034, 0x0002404A, + 0x034, 0x00023047, + 0x034, 0x0002200A, + 0x034, 0x00021007, + 0x034, 0x00020004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B4, + 0x034, 0x000290B1, + 0x034, 0x00028072, + 0x034, 0x0002706F, + 0x034, 0x0002604F, + 0x034, 0x0002504C, + 0x034, 0x00024049, + 0x034, 0x00023046, + 0x034, 0x00022009, + 0x034, 0x00021006, + 0x034, 0x00020003, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF5, + 0x034, 0x00029DF2, + 0x034, 0x00028DEF, + 0x034, 0x00027DEC, + 0x034, 0x00026DE9, + 0x034, 0x00025DE6, + 0x034, 0x00024DE3, + 0x034, 0x000238C8, + 0x034, 0x000228C5, + 0x034, 0x000218C2, + 0x034, 0x000208C0, + 0xB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x00006050, + 0x034, 0x0000504D, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x0000200A, + 0x034, 0x00001007, + 0x034, 0x00000004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x0000604D, + 0x034, 0x0000504A, + 0x034, 0x00004047, + 0x034, 0x00003044, + 0x034, 0x00002007, + 0x034, 0x00001004, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009DF7, + 0x034, 0x00008DF4, + 0x034, 0x00007DF1, + 0x034, 0x00006DEE, + 0x034, 0x00005DEB, + 0x034, 0x00004DE8, + 0x034, 0x000038CC, + 0x034, 0x000028C9, + 0x034, 0x000018C6, + 0x034, 0x000008C3, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001D4, + 0x035, 0x000081D4, + 0x035, 0x000101D4, + 0x035, 0x000201B4, + 0x035, 0x000281B4, + 0x035, 0x000301B4, + 0x035, 0x000401B4, + 0x035, 0x000481B4, + 0x035, 0x000501B4, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001D4, + 0x035, 0x000081D4, + 0x035, 0x000101D4, + 0x035, 0x000201B4, + 0x035, 0x000281B4, + 0x035, 0x000301B4, + 0x035, 0x000401B4, + 0x035, 0x000481B4, + 0x035, 0x000501B4, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x00000188, + 0x035, 0x00008147, + 0x035, 0x00010147, + 0x035, 0x000201D7, + 0x035, 0x000281D7, + 0x035, 0x000301D7, + 0x035, 0x000401D8, + 0x035, 0x000481D8, + 0x035, 0x000501D8, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00004BFB, + 0x036, 0x0000CBFB, + 0x036, 0x00014BFB, + 0x036, 0x0001CBFB, + 0x036, 0x00024F4B, + 0x036, 0x0002CF4B, + 0x036, 0x00034F4B, + 0x036, 0x0003CF4B, + 0x036, 0x00044F4B, + 0x036, 0x0004CF4B, + 0x036, 0x00054F4B, + 0x036, 0x0005CF4B, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00004BFB, + 0x036, 0x0000CBFB, + 0x036, 0x00014BFB, + 0x036, 0x0001CBFB, + 0x036, 0x00024F4B, + 0x036, 0x0002CF4B, + 0x036, 0x00034F4B, + 0x036, 0x0003CF4B, + 0x036, 0x00044F4B, + 0x036, 0x0004CF4B, + 0x036, 0x00054F4B, + 0x036, 0x0005CF4B, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00084EB4, + 0x036, 0x0008CC35, + 0x036, 0x00094C35, + 0x036, 0x0009CC35, + 0x036, 0x000A4C35, + 0x036, 0x000ACC35, + 0x036, 0x000B4C35, + 0x036, 0x000BCC35, + 0x036, 0x000C4C34, + 0x036, 0x000CCC35, + 0x036, 0x000D4C35, + 0x036, 0x000DCC35, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000002CC, + 0x03C, 0x00000522, + 0x03C, 0x00000902, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x03C, 0x000002CC, + 0x03C, 0x00000522, + 0x03C, 0x00000902, + 0xA0000000, 0x00000000, + 0x03C, 0x000002A8, + 0x03C, 0x000005A2, + 0x03C, 0x00000880, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x0DF, 0x00000080, + 0x01F, 0x00000064, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000FDD43, + 0x062, 0x00038F4B, + 0x063, 0x00032117, + 0x064, 0x000194AC, + 0x065, 0x000931D1, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x061, 0x000FDD43, + 0x062, 0x00038F4B, + 0x063, 0x00032117, + 0x064, 0x000194AC, + 0x065, 0x000931D2, + 0xA0000000, 0x00000000, + 0x061, 0x000E5D53, + 0x062, 0x00038FCD, + 0x063, 0x000114EB, + 0x064, 0x000196AC, + 0x065, 0x000911D7, + 0xB0000000, 0x00000000, + 0x008, 0x00008400, + 0x01C, 0x000739D2, + 0x0B4, 0x0001E78D, + 0x018, 0x0001F12A, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x0B4, 0x0001A78D, + 0x018, 0x0001712A, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_a, A); + +static const u32 rtw8812a_rf_b[] = { + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x089, 0x00000080, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x086, 0x00014B3A, + 0xA0000000, 0x00000000, + 0x086, 0x00014B38, + 0xB0000000, 0x00000000, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x08B, 0x00080180, + 0xA0000000, 0x00000000, + 0x08B, 0x00087180, + 0xB0000000, 0x00000000, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0x90000001, 0x00000005, 0x40000000, 0x00000000, + 0x03B, 0x0003F218, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xA0000000, 0x00000000, + 0x03B, 0x00038A58, + 0x03B, 0x00037A58, + 0x03B, 0x0002A590, + 0x03B, 0x00027A50, + 0x03B, 0x00018248, + 0x03B, 0x00010240, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A4EE, + 0x034, 0x00009076, + 0x034, 0x00008073, + 0x034, 0x00007070, + 0x034, 0x0000606D, + 0x034, 0x0000506A, + 0x034, 0x00004049, + 0x034, 0x00003046, + 0x034, 0x00002028, + 0x034, 0x00001025, + 0x034, 0x00000022, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF4, + 0x034, 0x00009DF1, + 0x034, 0x00008DEE, + 0x034, 0x00007DEB, + 0x034, 0x00006DE8, + 0x034, 0x00005DE5, + 0x034, 0x00004DE2, + 0x034, 0x00003CE6, + 0x034, 0x000024E7, + 0x034, 0x000014E4, + 0x034, 0x000004E1, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x0EF, 0x00000002, + 0x008, 0x00008400, + 0x018, 0x0001712A, + 0x0EF, 0x00001000, + 0x03A, 0x00000080, + 0x03B, 0x0003A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0003202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0002B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00023070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0001B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00012085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0000A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00002080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x0007A02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x0007202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x0006B064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x00063070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0005B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00052085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0004A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00042080, + 0x03C, 0x00010000, + 0x03A, 0x00000080, + 0x03B, 0x000BA02C, + 0x03C, 0x00004000, + 0x03A, 0x00000400, + 0x03B, 0x000B202C, + 0x03C, 0x00010000, + 0x03A, 0x000000A0, + 0x03B, 0x000AB064, + 0x03C, 0x00004000, + 0x03A, 0x000000D8, + 0x03B, 0x000A3070, + 0x03C, 0x00004000, + 0x03A, 0x00000468, + 0x03B, 0x0009B870, + 0x03C, 0x00010000, + 0x03A, 0x00000098, + 0x03B, 0x00092085, + 0x03C, 0x000E4000, + 0x03A, 0x00000418, + 0x03B, 0x0008A080, + 0x03C, 0x000F0000, + 0x03A, 0x00000418, + 0x03B, 0x00082080, + 0x03C, 0x00010000, + 0x0EF, 0x00001100, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B2, + 0x034, 0x000490AF, + 0x034, 0x00048070, + 0x034, 0x0004706D, + 0x034, 0x00046050, + 0x034, 0x0004504D, + 0x034, 0x0004404A, + 0x034, 0x00043047, + 0x034, 0x0004200A, + 0x034, 0x00041007, + 0x034, 0x00040004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0B1, + 0x034, 0x000490AE, + 0x034, 0x0004806F, + 0x034, 0x0004706C, + 0x034, 0x0004604C, + 0x034, 0x00045049, + 0x034, 0x00044046, + 0x034, 0x00043043, + 0x034, 0x00042006, + 0x034, 0x00041003, + 0x034, 0x00040000, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045DE6, + 0x034, 0x00044DE3, + 0x034, 0x000438C8, + 0x034, 0x000428C5, + 0x034, 0x000418C2, + 0x034, 0x000408C0, + 0xB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B2, + 0x034, 0x000290AF, + 0x034, 0x00028070, + 0x034, 0x0002706D, + 0x034, 0x00026050, + 0x034, 0x0002504D, + 0x034, 0x0002404A, + 0x034, 0x00023047, + 0x034, 0x0002200A, + 0x034, 0x00021007, + 0x034, 0x00020004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0B3, + 0x034, 0x000290B0, + 0x034, 0x00028071, + 0x034, 0x0002706E, + 0x034, 0x0002604E, + 0x034, 0x0002504B, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022008, + 0x034, 0x00021005, + 0x034, 0x00020002, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF5, + 0x034, 0x00029DF2, + 0x034, 0x00028DEF, + 0x034, 0x00027DEC, + 0x034, 0x00026DE9, + 0x034, 0x00025DE6, + 0x034, 0x00024DE3, + 0x034, 0x000238C8, + 0x034, 0x000228C5, + 0x034, 0x000218C2, + 0x034, 0x000208C0, + 0xB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B2, + 0x034, 0x000090AF, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x00006050, + 0x034, 0x0000504D, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x0000200A, + 0x034, 0x00001007, + 0x034, 0x00000004, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0B3, + 0x034, 0x000090B0, + 0x034, 0x00008070, + 0x034, 0x0000706D, + 0x034, 0x0000604D, + 0x034, 0x0000504A, + 0x034, 0x00004047, + 0x034, 0x00003044, + 0x034, 0x00002007, + 0x034, 0x00001004, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009DF7, + 0x034, 0x00008DF4, + 0x034, 0x00007DF1, + 0x034, 0x00006DEE, + 0x034, 0x00005DEB, + 0x034, 0x00004DE8, + 0x034, 0x000038CC, + 0x034, 0x000028C9, + 0x034, 0x000018C6, + 0x034, 0x000008C3, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001C5, + 0x035, 0x000081C5, + 0x035, 0x000101C5, + 0x035, 0x00020174, + 0x035, 0x00028174, + 0x035, 0x00030174, + 0x035, 0x00040185, + 0x035, 0x00048185, + 0x035, 0x00050185, + 0x0EF, 0x00000000, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x000001C5, + 0x035, 0x000081C5, + 0x035, 0x000101C5, + 0x035, 0x00020174, + 0x035, 0x00028174, + 0x035, 0x00030174, + 0x035, 0x00040185, + 0x035, 0x00048185, + 0x035, 0x00050185, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x035, 0x00000188, + 0x035, 0x00008147, + 0x035, 0x00010147, + 0x035, 0x000201D7, + 0x035, 0x000281D7, + 0x035, 0x000301D7, + 0x035, 0x000401D8, + 0x035, 0x000481D8, + 0x035, 0x000501D8, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00005B8B, + 0x036, 0x0000DB8B, + 0x036, 0x00015B8B, + 0x036, 0x0001DB8B, + 0x036, 0x000262DB, + 0x036, 0x0002E2DB, + 0x036, 0x000362DB, + 0x036, 0x0003E2DB, + 0x036, 0x0004553B, + 0x036, 0x0004D53B, + 0x036, 0x0005553B, + 0x036, 0x0005D53B, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00005B8B, + 0x036, 0x0000DB8B, + 0x036, 0x00015B8B, + 0x036, 0x0001DB8B, + 0x036, 0x000262DB, + 0x036, 0x0002E2DB, + 0x036, 0x000362DB, + 0x036, 0x0003E2DB, + 0x036, 0x0004553B, + 0x036, 0x0004D53B, + 0x036, 0x0005553B, + 0x036, 0x0005D53B, + 0xA0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x036, 0x00084EB4, + 0x036, 0x0008CC35, + 0x036, 0x00094C35, + 0x036, 0x0009CC35, + 0x036, 0x000A4C35, + 0x036, 0x000ACC35, + 0x036, 0x000B4C35, + 0x036, 0x000BCC35, + 0x036, 0x000C4C34, + 0x036, 0x000CCC35, + 0x036, 0x000D4C35, + 0x036, 0x000DCC35, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000002DC, + 0x03C, 0x00000524, + 0x03C, 0x00000902, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x03C, 0x000002DC, + 0x03C, 0x00000524, + 0x03C, 0x00000902, + 0xA0000000, 0x00000000, + 0x03C, 0x000002A8, + 0x03C, 0x000005A2, + 0x03C, 0x00000880, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x0DF, 0x00000080, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D1, + 0x90000008, 0x05000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D2, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAC43, + 0x062, 0x00038F47, + 0x063, 0x00031157, + 0x064, 0x0001C4AC, + 0x065, 0x000931D1, + 0xA0000000, 0x00000000, + 0x061, 0x000E5D53, + 0x062, 0x00038FCD, + 0x063, 0x000114EB, + 0x064, 0x000196AC, + 0x065, 0x000911D7, + 0xB0000000, 0x00000000, + 0x008, 0x00008400, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_b, B); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8812a_txpwr_lmt[] = { + { 0, 0, 0, 0, 1, 36, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 36, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 36, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 36, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 36, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 36, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 36, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 36, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 36, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 36, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 36, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 34, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 36, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 36, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 36, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 36, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 36, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 36, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 36, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 36, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 36, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 32, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 34, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 36, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 36, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 36, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 36, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 36, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 36, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 36, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 36, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 36, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 32, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 32, }, + { 1, 0, 0, 3, 1, 32, }, + { 0, 0, 0, 3, 2, 34, }, + { 2, 0, 0, 3, 2, 32, }, + { 1, 0, 0, 3, 2, 32, }, + { 0, 0, 0, 3, 3, 34, }, + { 2, 0, 0, 3, 3, 32, }, + { 1, 0, 0, 3, 3, 32, }, + { 0, 0, 0, 3, 4, 34, }, + { 2, 0, 0, 3, 4, 32, }, + { 1, 0, 0, 3, 4, 32, }, + { 0, 0, 0, 3, 5, 34, }, + { 2, 0, 0, 3, 5, 32, }, + { 1, 0, 0, 3, 5, 32, }, + { 0, 0, 0, 3, 6, 34, }, + { 2, 0, 0, 3, 6, 32, }, + { 1, 0, 0, 3, 6, 32, }, + { 0, 0, 0, 3, 7, 34, }, + { 2, 0, 0, 3, 7, 32, }, + { 1, 0, 0, 3, 7, 32, }, + { 0, 0, 0, 3, 8, 34, }, + { 2, 0, 0, 3, 8, 32, }, + { 1, 0, 0, 3, 8, 32, }, + { 0, 0, 0, 3, 9, 34, }, + { 2, 0, 0, 3, 9, 32, }, + { 1, 0, 0, 3, 9, 32, }, + { 0, 0, 0, 3, 10, 34, }, + { 2, 0, 0, 3, 10, 32, }, + { 1, 0, 0, 3, 10, 32, }, + { 0, 0, 0, 3, 11, 30, }, + { 2, 0, 0, 3, 11, 32, }, + { 1, 0, 0, 3, 11, 32, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 32, }, + { 1, 0, 0, 3, 12, 32, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 32, }, + { 1, 0, 0, 3, 13, 32, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 32, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 36, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 36, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 36, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 36, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 36, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 36, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 36, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 32, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 30, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 32, }, + { 1, 0, 1, 3, 12, 32, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 32, }, + { 1, 0, 1, 3, 13, 32, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 30, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 30, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 30, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 36, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 34, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 30, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 30, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 34, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 34, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 36, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 34, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 30, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 30, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 36, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 36, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 36, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 36, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 36, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 30, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 30, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 30, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 34, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 30, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 30, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 34, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 34, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 36, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 34, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 30, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 30, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 28, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 36, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 36, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 36, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 36, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 36, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 26, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 34, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 34, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 34, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 34, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 34, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 30, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 32, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 28, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 36, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 34, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 36, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 28, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 30, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 34, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 34, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 34, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 30, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 28, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 30, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 34, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 36, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 28, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 26, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 28, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 32, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8812a_txpwr_lmt); + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8812a[] = { + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0014, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x80, 0}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x01, 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x10, 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0043, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0024, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0028, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8812a[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0024, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0028, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_lps_8812a[] = { + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x0522, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x7F}, + {0x05F8, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05F9, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FA, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FB, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x0c00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0e00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0100, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x03}, + {0x0101, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0553, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8812a[] = { + {0x0c00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0e00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x2A}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x02, 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8812a[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0080, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x05}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xF0, 0xcc}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xF0, 0xEC}, + {0x0043, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x07}, + {0x0045, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xff}, + {0x0047, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0014, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x80, BIT(7)}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x01, BIT(0)}, + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x01, 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x10, BIT(4)}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x02, 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0076, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[] = { + trans_carddis_to_cardemu_8812a, + trans_cardemu_to_act_8812a, + NULL +}; + +const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = { + trans_act_to_lps_8812a, + NULL +}; + +const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = { + trans_act_to_cardemu_8812a, + trans_cardemu_to_carddis_8812a, + NULL +}; + +static const u8 rtw8812a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 14, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 14, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, + 13, 14, 14, 15, 16, 16, 16, 16, 16}, +}; + +static const u8 rtw8812a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtw8812a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 15, 15, 15, 15, 15}, +}; + +static const u8 rtw8812a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtw8812a_pwrtrk_2gb_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8812a_pwrtrk_2gb_p[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +static const u8 rtw8812a_pwrtrk_2ga_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8812a_pwrtrk_2ga_p[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +static const u8 rtw8812a_pwrtrk_2g_cck_b_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8812a_pwrtrk_2g_cck_b_p[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +static const u8 rtw8812a_pwrtrk_2g_cck_a_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8812a_pwrtrk_2g_cck_a_p[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl = { + .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_5gb_n[2], + .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_5gb_p[0], + .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_5gb_p[1], + .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_5gb_p[2], + .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_5ga_n[0], + .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_5ga_n[1], + .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_5ga_n[2], + .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_5ga_p[0], + .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_5ga_p[1], + .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_5ga_p[2], + .pwrtrk_2gb_n = rtw8812a_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8812a_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8812a_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8812a_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_2g_cck_a_p, +}; + +static const u8 rtw8812a_pwrtrk_rfe3_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, + 13, 14, 15, 16, 16, 17, 17, 18, 18}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, + 12, 14, 13, 13, 14, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 14, 15, 15, 16, 16}, +}; + +static const u8 rtw8812a_pwrtrk_rfe3_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtw8812a_pwrtrk_rfe3_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, + 13, 14, 15, 16, 16, 17, 17, 18, 18}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 13, 13, 14, 15, 16, 16, 17, 17}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, + 13, 14, 14, 15, 15, 16, 17, 18, 18}, +}; + +static const u8 rtw8812a_pwrtrk_rfe3_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2gb_n[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2gb_p[] = { + 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2ga_n[] = { + 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2ga_p[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_n[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_p[] = { + 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_n[] = { + 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 +}; + +static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_p[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl = { + .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_rfe3_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_rfe3_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_rfe3_5gb_n[2], + .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_rfe3_5gb_p[0], + .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_rfe3_5gb_p[1], + .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_rfe3_5gb_p[2], + .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_rfe3_5ga_n[0], + .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_rfe3_5ga_n[1], + .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_rfe3_5ga_n[2], + .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_rfe3_5ga_p[0], + .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_rfe3_5ga_p[1], + .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_rfe3_5ga_p[2], + .pwrtrk_2gb_n = rtw8812a_pwrtrk_rfe3_2gb_n, + .pwrtrk_2gb_p = rtw8812a_pwrtrk_rfe3_2gb_p, + .pwrtrk_2ga_n = rtw8812a_pwrtrk_rfe3_2ga_n, + .pwrtrk_2ga_p = rtw8812a_pwrtrk_rfe3_2ga_p, + .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_rfe3_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_rfe3_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_rfe3_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_rfe3_2g_cck_a_p, +}; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h new file mode 100644 index 000000000..f7ab5e4cf --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW8812A_TABLE_H__ +#define __RTW8812A_TABLE_H__ + +extern const struct rtw_table rtw8812a_mac_tbl; +extern const struct rtw_table rtw8812a_agc_tbl; +extern const struct rtw_table rtw8812a_agc_diff_lb_tbl; +extern const struct rtw_table rtw8812a_agc_diff_hb_tbl; +extern const struct rtw_table rtw8812a_bb_tbl; +extern const struct rtw_table rtw8812a_bb_pg_tbl; +extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl; +extern const struct rtw_table rtw8812a_rf_a_tbl; +extern const struct rtw_table rtw8812a_rf_b_tbl; +extern const struct rtw_table rtw8812a_txpwr_lmt_tbl; + +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[]; +extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[]; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[]; + +extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl; +extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812au.c b/drivers/net/wireless/realtek/rtw88/rtw8812au.c new file mode 100644 index 000000000..dfea89670 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8812a.h" +#include "usb.h" + +static const struct usb_device_id rtw_8812au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */ + { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */ + { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1106, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ + { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1109, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3426, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ZyXEL */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Logitec */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Abocom */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9051, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Netgear */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17d2, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ASUS */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0074, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Sitecom */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0022, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Hawking */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0632, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* WD */ + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x003f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Linksys */ + { USB_DEVICE_AND_INTERFACE_INFO(0x148f, 0x9097, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Amped Wireless */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1740, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* EnGenius */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3313, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3315, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3316, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab30, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Planex */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TRENDnet */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0101, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0103, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0122, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); + +static struct usb_driver rtw_8812au_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8812au_id_table, + .probe = rtw_usb_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8812au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c new file mode 100644 index 000000000..fa02aa299 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c @@ -0,0 +1,2271 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "tx.h" +#include "phy.h" +#include "rtw8814a.h" +#include "rtw8814a_table.h" +#include "rtw88xxa.h" +#include "reg.h" +#include "debug.h" +#include "efuse.h" +#include "regd.h" +#include "usb.h" + +static void rtw8814a_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, + BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} + +static void rtw8814a_read_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (!(efuse->rfe_option & BIT(7))) + return; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 0; + else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + efuse->rfe_option = 1; +} + +static void rtw8814a_read_amplifier_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + switch (efuse->rfe_option) { + case 1: + /* Internal 2G */ + efuse->pa_type_2g = 0; + efuse->lna_type_2g = 0; + /* External 5G */ + efuse->pa_type_5g = BIT(0); + efuse->lna_type_5g = BIT(3); + break; + case 2 ... 5: + /* External everything */ + efuse->pa_type_2g = BIT(4); + efuse->lna_type_2g = BIT(3); + efuse->pa_type_5g = BIT(0); + efuse->lna_type_5g = BIT(3); + break; + case 6: + efuse->lna_type_5g = BIT(3); + break; + default: + break; + } +} + +static void rtw8814a_read_rf_type(struct rtw_dev *rtwdev, + struct rtw8814a_efuse *map) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct rtw_hal *hal = &rtwdev->hal; + + switch (map->trx_antenna_option) { + case 0xff: /* 4T4R */ + case 0xee: /* 3T3R */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + rtwusb->udev->speed != USB_SPEED_SUPER) + hal->rf_type = RF_2T2R; + else + hal->rf_type = RF_3T3R; + + break; + case 0x66: /* 2T2R */ + case 0x6f: /* 2T4R */ + default: + hal->rf_type = RF_2T2R; + break; + } + + hal->rf_path_num = 4; + hal->rf_phy_num = 4; + + if (hal->rf_type == RF_3T3R) { + hal->antenna_rx = BB_PATH_ABC; + hal->antenna_tx = BB_PATH_ABC; + } else { + hal->antenna_rx = BB_PATH_AB; + hal->antenna_tx = BB_PATH_AB; + } +} + +static void rtw8814a_init_hwcap(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + + efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | + BIT(RTW_CHANNEL_WIDTH_40) | + BIT(RTW_CHANNEL_WIDTH_80); + efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; + + if (hal->rf_type == RF_3T3R) + efuse->hw_cap.nss = 3; + else + efuse->hw_cap.nss = 2; + + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, + efuse->hw_cap.ant_num, efuse->hw_cap.nss); +} + +static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8814a_efuse *map; + int i; + + if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, + log_map, rtwdev->chip->log_efuse_size, true); + + map = (struct rtw8814a_efuse *)log_map; + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(4)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + rtw8814a_read_rfe_type(rtwdev); + rtw8814a_read_amplifier_type(rtwdev); + + /* Override rtw_chip_parameter_setup() */ + rtw8814a_read_rf_type(rtwdev, map); + + rtw8814a_init_hwcap(rtwdev); + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + break; + case RTW_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; + case RTW_HCI_TYPE_SDIO: + default: + /* unsupported now */ + return -EOPNOTSUPP; + } + + return 0; +} + +static void rtw8814a_init_rfe_reg(struct rtw_dev *rtwdev) +{ + u8 rfe_option = rtwdev->efuse.rfe_option; + + if (rfe_option == 2 || rfe_option == 1) { + rtw_write32_mask(rtwdev, 0x1994, 0xf, 0xf); + rtw_write8_set(rtwdev, REG_GPIO_MUXCFG + 2, 0xf0); + } else if (rfe_option == 0) { + rtw_write32_mask(rtwdev, 0x1994, 0xf, 0xf); + rtw_write8_set(rtwdev, REG_GPIO_MUXCFG + 2, 0xc0); + } +} + +#define RTW_TXSCALE_SIZE 37 +static const u32 rtw8814a_txscale_tbl[RTW_TXSCALE_SIZE] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u32 rtw8814a_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 rf_path) +{ + static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 tx_bb_swing; + + if (band == RTW_BAND_2G) + tx_bb_swing = efuse->tx_bb_swing_setting_2g; + else + tx_bb_swing = efuse->tx_bb_swing_setting_5g; + + tx_bb_swing >>= 2 * rf_path; + tx_bb_swing &= 0x3; + + return swing2setting[tx_bb_swing]; +} + +static u8 rtw8814a_get_swing_index(struct rtw_dev *rtwdev) +{ + u32 swing, table_value; + u8 i; + + swing = rtw8814a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, + RF_PATH_A); + + for (i = 0; i < ARRAY_SIZE(rtw8814a_txscale_tbl); i++) { + table_value = rtw8814a_txscale_tbl[i]; + if (swing == table_value) + return i; + } + + return 24; +} + +static void rtw8814a_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = rtw8814a_get_swing_index(rtwdev); + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + dm_info->delta_power_index_last[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8814a_config_trx_path(struct rtw_dev *rtwdev) +{ + /* RX CCK disable 2R CCA */ + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, + BIT_CCK0_2RX | BIT_CCK0_MRC); + /* pathB tx on, path A/C/D tx off */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0xf0000000, 0x4); + /* pathB rx */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x5); +} + +static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev) +{ + /* CCK 2R CCA parameters */ + + /* Disable Ant diversity */ + rtw_write32_mask(rtwdev, REG_RXSB, BIT_RXSB_ANA_DIV, 0x0); + /* Concurrent CCA at LSB & USB */ + rtw_write32_mask(rtwdev, REG_CCA, BIT_CCA_CO, 0); + /* RX path diversity enable */ + rtw_write32_mask(rtwdev, REG_ANTSEL, BIT_ANT_BYCO, 0); + /* r_en_mrc_antsel */ + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_DIS_CO_PATHSEL, 0); + /* MBC weighting */ + rtw_write32_mask(rtwdev, REG_CCA_MF, BIT_MBC_WIN, 1); + /* 2R CCA only */ + rtw_write32_mask(rtwdev, REG_CCKTX, BIT_CMB_CCA_2R, 1); +} + +static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) +{ + u32 crystal_cap, val32; + u8 val8, rf_path; + + /* power on BB/RF domain */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_USBA); + else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_PCIEA); + + rtw_write8_set(rtwdev, REG_SYS_CFG3_8814A + 2, + BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + + /* Power on RF paths A..D */ + val8 = BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB; + rtw_write8(rtwdev, REG_RF_CTRL, val8); + rtw_write8(rtwdev, REG_RF_CTRL1, val8); + rtw_write8(rtwdev, REG_RF_CTRL2, val8); + rtw_write8(rtwdev, REG_RF_CTRL3, val8); + + rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); + rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + crystal_cap |= crystal_cap << 6; + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000, crystal_cap); + + rtw8814a_config_trx_path(rtwdev); + + for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) + rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); + + val32 = rtw_read_rf(rtwdev, RF_PATH_A, RF_RCK1_V1, RFREG_MASK); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK1_V1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_C, RF_RCK1_V1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_D, RF_RCK1_V1, RFREG_MASK, val32); + + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xFF); + + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); + + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); + + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); + + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); + + rtw8814a_config_cck_rx_antenna_init(rtwdev); + + rtw_phy_init(rtwdev); + rtw8814a_pwrtrack_init(rtwdev); + + rtw8814a_init_rfe_reg(rtwdev); + + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); + + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 235); + + /* enable Tx report. */ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x1F); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { + /* Reset USB mode switch setting */ + rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); + rtw_write8(rtwdev, REG_ACLK_MON, 0x0); + } +} + +static void rtw8814ae_enable_rf_1_2v(struct rtw_dev *rtwdev) +{ + /* This is for fullsize card, because GPIO7 there is floating. + * We should pull GPIO7 high to enable RF 1.2V Switch Power Supply + */ + + /* 1. set 0x40[1:0] to 0, BIT_GPIOSEL=0, select pin as GPIO */ + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(1) | BIT(0)); + + /* 2. set 0x44[31] to 0 + * mode=0: data port; + * mode=1 and BIT_GPIO_IO_SEL=0: interrupt mode; + */ + rtw_write8_clr(rtwdev, REG_GPIO_PIN_CTRL + 3, BIT(7)); + + /* 3. data mode + * 3.1 set 0x44[23] to 1 + * sel=0: input; + * sel=1: output; + */ + rtw_write8_set(rtwdev, REG_GPIO_PIN_CTRL + 2, BIT(7)); + + /* 3.2 set 0x44[15] to 1 + * output high value; + */ + rtw_write8_set(rtwdev, REG_GPIO_PIN_CTRL + 1, BIT(7)); +} + +static int rtw8814a_mac_init(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + rtw_write16(rtwdev, REG_CR, + MAC_TRX_ENABLE | BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN); + + rtw_load_table(rtwdev, rtwdev->chip->mac_tbl); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, + rtwdev->chip->usb_tx_agg_desc_num << 1); + + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xfffff); + + rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); + + rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); + rtwdev->hal.rxfltmap1 = 0x0400; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); + + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, 0x36); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM + 1, 0x36); + + /* Set Spec SIFS (used in NAV) */ + rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); + + /* Set SIFS for CCK */ + rtw_write16(rtwdev, REG_SIFS, 0x100a); + + /* Set SIFS for OFDM */ + rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); + + /* TXOP */ + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + + rtw_write8(rtwdev, REG_ACKTO, 0x80); + + rtw_write16(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | (BIT_DIS_TSF_UDT << 8)); + rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); + rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xFF); + + rtw_write32(rtwdev, REG_FAST_EDCA_VOVI_SETTING, 0x08070807); + rtw_write32(rtwdev, REG_FAST_EDCA_BEBK_SETTING, 0x08070807); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + rtwusb->udev->speed == USB_SPEED_SUPER) { + /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ + rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); + /* To avoid usb 3.0 H2C fail. */ + rtw_write16(rtwdev, 0xf002, 0); + + rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, + BIT_PRE_TX_CMD); + } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { + rtw8814ae_enable_rf_1_2v(rtwdev); + + /* Force the antenna b to wifi. */ + rtw_write8_set(rtwdev, REG_PAD_CTRL1, BIT(2)); + rtw_write8_set(rtwdev, REG_PAD_CTRL1 + 1, BIT(0)); + rtw_write8_set(rtwdev, REG_LED_CFG + 3, + (BIT(27) | BIT_DPDT_WL_SEL) >> 24); + } + + return 0; +} + +static void rtw8814a_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77707770); + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x72); + + break; + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x77); + + break; + case 0: + default: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + /* Is it not necessary to set REG_RFE_PINMUX_D ? */ + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x77); + + break; + } +} + +static void rtw8814a_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x37); + + break; + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x33); + + break; + case 0: + default: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x54775477); + + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x54); + + break; + } +} + +static void rtw8814a_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_A)); + rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_B)); + rtw_write32_mask(rtwdev, REG_TXSCALE_C, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_C)); + rtw_write32_mask(rtwdev, REG_TXSCALE_D, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_D)); + rtw8814a_pwrtrack_init(rtwdev); +} + +static void rtw8814a_set_bw_reg_adc(struct rtw_dev *rtwdev, u8 bw) +{ + u32 adc = 0; + + if (bw == RTW_CHANNEL_WIDTH_20) + adc = 0; + else if (bw == RTW_CHANNEL_WIDTH_40) + adc = 1; + else if (bw == RTW_CHANNEL_WIDTH_80) + adc = 2; + + rtw_write32_mask(rtwdev, REG_ADCCLK, BIT(1) | BIT(0), adc); +} + +static void rtw8814a_set_bw_reg_agc(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + u32 agc = 7; + + if (bw == RTW_CHANNEL_WIDTH_20) { + agc = 6; + } else if (bw == RTW_CHANNEL_WIDTH_40) { + if (new_band == RTW_BAND_5G) + agc = 8; + else + agc = 7; + } else if (bw == RTW_CHANNEL_WIDTH_80) { + agc = 3; + } + + rtw_write32_mask(rtwdev, REG_CCASEL, 0xf000, agc); +} + +static void rtw8814a_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + /* Clear 0x1000[16], When this bit is set to 0, CCK and OFDM + * are disabled, and clock are gated. Otherwise, CCK and OFDM + * are enabled. + */ + rtw_write8_clr(rtwdev, REG_SYS_CFG3_8814A + 2, BIT_FEN_BB_RSTB); + + if (new_band == RTW_BAND_2G) { + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 0); + + rtw8814a_set_rfe_reg_24g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x2); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x5); + + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST, 0x3); + + rtw_write8(rtwdev, REG_CCK_CHECK, 0); + + rtw_write32_mask(rtwdev, 0xa80, BIT(18), 0); + } else { + rtw_write8(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + + /* Enable CCK Tx function, even when CCK is off */ + rtw_write32_mask(rtwdev, 0xa80, BIT(18), 1); + + rtw8814a_set_rfe_reg_5g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); + + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST, 0x2); + } + + rtw8814a_set_channel_bb_swing(rtwdev, new_band); + + rtw8814a_set_bw_reg_adc(rtwdev, bw); + rtw8814a_set_bw_reg_agc(rtwdev, new_band, bw); + + rtw_write8_set(rtwdev, REG_SYS_CFG3_8814A + 2, BIT_FEN_BB_RSTB); +} + +static void rtw8814a_switch_channel(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 fc_area, rf_mod_ag, cfgch; + u8 path; + + switch (channel) { + case 36 ... 48: + fc_area = 0x494; + break; + case 50 ... 64: + fc_area = 0x453; + break; + case 100 ... 116: + fc_area = 0x452; + break; + default: + if (channel >= 118) + fc_area = 0x412; + else + fc_area = 0x96a; + break; + } + + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); + + for (path = 0; path < hal->rf_path_num; path++) { + switch (channel) { + case 36 ... 64: + rf_mod_ag = 0x101; + break; + case 100 ... 140: + rf_mod_ag = 0x301; + break; + default: + if (channel > 140) + rf_mod_ag = 0x501; + else + rf_mod_ag = 0x000; + break; + } + + cfgch = (rf_mod_ag << 8) | channel; + + rtw_write_rf(rtwdev, path, RF_CFGCH, + RF18_RFSI_MASK | RF18_BAND_MASK | RF18_CHANNEL_MASK, cfgch); + } + + switch (channel) { + case 36 ... 64: + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 1); + break; + case 100 ... 144: + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 2); + break; + default: + if (channel >= 149) + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 3); + + break; + } +} + +static void rtw8814a_24g_cck_tx_dfir(struct rtw_dev *rtwdev, u8 channel) +{ + if (channel >= 1 && channel <= 11) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x090e1317); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000204); + } else if (channel >= 12 && channel <= 13) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x090e1217); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000305); + } else if (channel == 14) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x00000E17); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000000); + } +} + +static void rtw8814a_set_bw_reg_mac(struct rtw_dev *rtwdev, u8 bw) +{ + u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); + + val16 &= ~BIT_RFMOD; + if (bw == RTW_CHANNEL_WIDTH_80) + val16 |= BIT_RFMOD_80M; + else if (bw == RTW_CHANNEL_WIDTH_40) + val16 |= BIT_RFMOD_40M; + + rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); +} + +static void rtw8814a_set_bw_rf(struct rtw_dev *rtwdev, u8 bw) +{ + u8 path; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); + break; + } + } +} + +static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) +{ + static const u32 rxiqc_reg[2][4] = { + { REG_RX_IQC_AB_A, REG_RX_IQC_AB_B, + REG_RX_IQC_AB_C, REG_RX_IQC_AB_D }, + { REG_RX_IQC_CD_A, REG_RX_IQC_CD_B, + REG_RX_IQC_CD_C, REG_RX_IQC_CD_D } + }; + u32 bb_reg_8fc, bb_reg_808, rxiqc[4]; + u32 i = 0, mac_active = 1; + u8 mac_reg_522; + + if (rtwdev->hal.cut_version != RTW_CHIP_VER_CUT_A) + return; + + /* 1 Step1. MAC TX pause */ + mac_reg_522 = rtw_read8(rtwdev, REG_TXPAUSE); + bb_reg_8fc = rtw_read32(rtwdev, REG_DBGSEL); + bb_reg_808 = rtw_read32(rtwdev, REG_RXPSEL); + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + + /* 1 Step 2. Backup rxiqc & rxiqc = 0 */ + for (i = 0; i < 4; i++) { + rxiqc[i] = rtw_read32(rtwdev, rxiqc_reg[0][i]); + rtw_write32(rtwdev, rxiqc_reg[0][i], 0x0); + rtw_write32(rtwdev, rxiqc_reg[1][i], 0x0); + } + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_IQ_WGT, 0x3); + i = 0; + + /* 1 Step 3. Monitor MAC IDLE */ + rtw_write32(rtwdev, REG_DBGSEL, 0x0); + while (mac_active) { + mac_active = rtw_read32(rtwdev, REG_DBGRPT) & 0x803e0008; + i++; + if (i > 1000) + break; + } + + /* 1 Step 4. ADC clk flow */ + rtw_write8(rtwdev, REG_RXPSEL, 0x11); + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x1); + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2) | BIT(1), 0x3); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x1); + + /* 0xc1c/0xe1c/0x181c/0x1a1c[4] must=1 to ensure table can be + * written when bbrstb=0 + * 0xc60/0xe60/0x1860/0x1a60[15] always = 1 after this line + * 0xc60/0xe60/0x1860/0x1a60[14] always = 0 bcz its error in A-cut + */ + + /* power_off/clk_off @ anapar_state=idle mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x01808003); + + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2), 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x0); + /* [19] = 1 to turn off ADC */ + rtw_write32(rtwdev, REG_CK_MONHA, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHB, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHC, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHD, 0x0D080058); + + /* power_on/clk_off */ + /* [19] = 0 to turn on ADC */ + rtw_write32(rtwdev, REG_CK_MONHA, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHB, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHC, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHD, 0x0D000058); + + /* power_on/clk_on @ anapar_state=BT mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05808032); + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x1); + + /* recover original setting @ anapar_state=BT mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05808032); + + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x07808003); + + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2) | BIT(1), 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x0); + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x0); + + /* 1 Step 5. Recover MAC TX & IQC */ + rtw_write8(rtwdev, REG_TXPAUSE, mac_reg_522); + rtw_write32(rtwdev, REG_DBGSEL, bb_reg_8fc); + rtw_write32(rtwdev, REG_RXPSEL, bb_reg_808); + for (i = 0; i < 4; i++) { + rtw_write32(rtwdev, rxiqc_reg[0][i], rxiqc[i]); + rtw_write32(rtwdev, rxiqc_reg[1][i], 0x01000000); + } + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_IQ_WGT, 0x0); +} + +static void rtw8814a_spur_calibration_ch140(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + + /* Add for 8814AE module ch140 MP Rx */ + if (channel == 140) { + if (hal->ch_param[0] == 0) + hal->ch_param[0] = rtw_read32(rtwdev, REG_CCASEL); + if (hal->ch_param[1] == 0) + hal->ch_param[1] = rtw_read32(rtwdev, REG_PDMFTH); + + rtw_write32(rtwdev, REG_CCASEL, 0x75438170); + rtw_write32(rtwdev, REG_PDMFTH, 0x79a18a0a); + } else { + if (rtw_read32(rtwdev, REG_CCASEL) == 0x75438170 && + hal->ch_param[0] != 0) + rtw_write32(rtwdev, REG_CCASEL, hal->ch_param[0]); + + if (rtw_read32(rtwdev, REG_PDMFTH) == 0x79a18a0a && + hal->ch_param[1] != 0) + rtw_write32(rtwdev, REG_PDMFTH, hal->ch_param[1]); + + hal->ch_param[0] = rtw_read32(rtwdev, REG_CCASEL); + hal->ch_param[1] = rtw_read32(rtwdev, REG_PDMFTH); + } +} + +static void rtw8814a_set_nbi_reg(struct rtw_dev *rtwdev, u32 tone_idx) +{ + /* tone_idx X 10 */ + static const u32 nbi_128[] = { + 25, 55, 85, 115, 135, + 155, 185, 205, 225, 245, + 265, 285, 305, 335, 355, + 375, 395, 415, 435, 455, + 485, 505, 525, 555, 585, 615, 635 + }; + u32 reg_idx = 0; + u32 i; + + for (i = 0; i < ARRAY_SIZE(nbi_128); i++) { + if (tone_idx < nbi_128[i]) { + reg_idx = i + 1; + break; + } + } + + rtw_write32_mask(rtwdev, REG_NBI_SETTING, 0xfc000, reg_idx); +} + +static void rtw8814a_nbi_setting(struct rtw_dev *rtwdev, u32 ch, u32 f_intf) +{ + u32 fc, int_distance, tone_idx; + + fc = 2412 + (ch - 1) * 5; + int_distance = abs_diff(fc, f_intf); + + /* 10 * (int_distance / 0.3125) */ + tone_idx = int_distance << 5; + + rtw8814a_set_nbi_reg(rtwdev, tone_idx); + + rtw_write32_mask(rtwdev, REG_NBI_SETTING, BIT_NBI_ENABLE, 1); +} + +static void rtw8814a_spur_nbi_setting(struct rtw_dev *rtwdev) +{ + u8 primary_channel = rtwdev->hal.primary_channel; + u8 rfe_type = rtwdev->efuse.rfe_option; + + if (rfe_type != 0 && rfe_type != 1 && rfe_type != 6 && rfe_type != 7) + return; + + if (primary_channel == 14) + rtw8814a_nbi_setting(rtwdev, primary_channel, 2480); + else if (primary_channel >= 4 && primary_channel <= 8) + rtw8814a_nbi_setting(rtwdev, primary_channel, 2440); + else + rtw_write32_mask(rtwdev, REG_NBI_SETTING, BIT_NBI_ENABLE, 0); +} + +/* A workaround to eliminate the 5280 MHz & 5600 MHz & 5760 MHz spur of 8814A */ +static void rtw8814a_spur_calibration(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u8 rfe_type = rtwdev->efuse.rfe_option; + bool reset_nbi_csi = true; + + if (rfe_type == 0) { + switch (bw) { + case RTW_CHANNEL_WIDTH_40: + if (channel == 54 || channel == 118) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x3e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } else if (channel == 151) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK0, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_80: + if (channel == 58 || channel == 122) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x3a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(0), 1); + + reset_nbi_csi = false; + } else if (channel == 155) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x5a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK6, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_20: + if (channel == 153) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(16), 1); + + reset_nbi_csi = false; + } + + rtw8814a_spur_calibration_ch140(rtwdev, channel); + break; + default: + break; + } + } else if (rfe_type == 1 || rfe_type == 2) { + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + if (channel == 153) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1E >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(16), 1); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_40: + if (channel == 151) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK0, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_80: + if (channel == 155) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x5a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK6, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + default: + break; + } + } + + if (reset_nbi_csi) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0xfc >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, BIT(0), 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + } + + rtw8814a_spur_nbi_setting(rtwdev); +} + +static void rtw8814a_set_bw_mode(struct rtw_dev *rtwdev, u8 new_band, + u8 channel, u8 bw, u8 primary_chan_idx) +{ + u8 txsc40 = 0, txsc20, txsc; + + rtw8814a_set_bw_reg_mac(rtwdev, bw); + + txsc20 = primary_chan_idx; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } + + txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); + rtw_write8(rtwdev, REG_DATA_SC, txsc); + + rtw8814a_set_bw_reg_adc(rtwdev, bw); + rtw8814a_set_bw_reg_agc(rtwdev, new_band, bw); + + if (bw == RTW_CHANNEL_WIDTH_80) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3c, txsc); + } else if (bw == RTW_CHANNEL_WIDTH_40) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3c, txsc); + + if (txsc == RTW_SC_20_UPPER) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + } + + rtw8814a_set_bw_rf(rtwdev, bw); + + rtw8814a_adc_clk(rtwdev); + + rtw8814a_spur_calibration(rtwdev, channel, bw); +} + +static void rtw8814a_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + u8 old_band, new_band; + + if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) + old_band = RTW_BAND_5G; + else + old_band = RTW_BAND_2G; + + if (channel > 14) + new_band = RTW_BAND_5G; + else + new_band = RTW_BAND_2G; + + if (new_band != old_band) + rtw8814a_switch_band(rtwdev, new_band, bw); + + rtw8814a_switch_channel(rtwdev, channel); + + rtw8814a_24g_cck_tx_dfir(rtwdev, channel); + + rtw8814a_set_bw_mode(rtwdev, new_band, channel, bw, primary_chan_idx); +} + +static s8 rtw8814a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) +{ + s8 rx_pwr_all = 0; + + switch (lna_idx) { + case 7: + rx_pwr_all = -38 - 2 * vga_idx; + break; + case 5: + rx_pwr_all = -28 - 2 * vga_idx; + break; + case 3: + rx_pwr_all = -8 - 2 * vga_idx; + break; + case 2: + rx_pwr_all = -1 - 2 * vga_idx; + break; + default: + break; + } + + return rx_pwr_all; +} + +static void rtw8814a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_jaguar_phy_status_rpt *rpt; + u8 gain[RTW_RF_PATH_MAX], rssi, i; + s8 rx_pwr_db, middle1, middle2; + s8 snr[RTW_RF_PATH_MAX]; + s8 evm[RTW_RF_PATH_MAX]; + u8 rfmode, subchannel; + u8 lna, vga; + s8 cfo[2]; + + rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; + + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + + if (pkt_stat->rate <= DESC_RATE11M) { + lna = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); + vga = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); + + rx_pwr_db = rtw8814a_cck_rx_pwr(lna, vga); + + pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->signal_power = rx_pwr_db; + } else { /* OFDM rate */ + gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); + gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); + gain[RF_PATH_C] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_GAIN_C); + gain[RF_PATH_D] = le32_get_bits(rpt->w6, RTW_JGRPHY_W6_GAIN_D); + + snr[RF_PATH_A] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXSNR_A); + snr[RF_PATH_B] = le32_get_bits(rpt->w4, RTW_JGRPHY_W4_RXSNR_B); + snr[RF_PATH_C] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXSNR_C); + snr[RF_PATH_D] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXSNR_D); + + evm[RF_PATH_A] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXEVM_1); + evm[RF_PATH_B] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXEVM_2); + evm[RF_PATH_C] = le32_get_bits(rpt->w4, RTW_JGRPHY_W4_RXEVM_3); + evm[RF_PATH_D] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXEVM_4); + + if (pkt_stat->rate <= DESC_RATE54M) + evm[RF_PATH_A] = le32_get_bits(rpt->w6, + RTW_JGRPHY_W6_SIGEVM); + + for (i = RF_PATH_A; i < RTW_RF_PATH_MAX; i++) { + pkt_stat->rx_power[i] = gain[i] - 110; + + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); + dm_info->rssi[i] = rssi; + + pkt_stat->rx_snr[i] = snr[i]; + dm_info->rx_snr[i] = snr[i] >> 1; + + pkt_stat->rx_evm[i] = evm[i]; + evm[i] = max_t(s8, -127, evm[i]); + dm_info->rx_evm_dbm[i] = abs(evm[i]) >> 1; + } + + rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, + RTW_RF_PATH_MAX); + pkt_stat->rssi = rssi; + + /* When power saving is enabled the hardware sometimes + * reports unbelievably high gain for paths A and C + * (e.g. one frame 64 68 68 72, the next frame 106 66 88 72, + * the next 66 66 68 72), so use the second lowest gain + * instead of the highest. + */ + middle1 = max(min(gain[RF_PATH_A], gain[RF_PATH_B]), + min(gain[RF_PATH_C], gain[RF_PATH_D])); + middle2 = min(max(gain[RF_PATH_A], gain[RF_PATH_B]), + max(gain[RF_PATH_C], gain[RF_PATH_D])); + rx_pwr_db = min(middle1, middle2); + rx_pwr_db -= 110; + pkt_stat->signal_power = rx_pwr_db; + + rfmode = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_R_RFMOD); + subchannel = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_SUB_CHNL); + + if (rfmode == 1 && subchannel == 0) { + pkt_stat->bw = RTW_CHANNEL_WIDTH_40; + } else if (rfmode == 2) { + if (subchannel == 0) + pkt_stat->bw = RTW_CHANNEL_WIDTH_80; + else if (subchannel == 9 || subchannel == 10) + pkt_stat->bw = RTW_CHANNEL_WIDTH_40; + } + + cfo[RF_PATH_A] = le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_A); + cfo[RF_PATH_B] = le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_B); + + for (i = RF_PATH_A; i < 2; i++) { + pkt_stat->cfo_tail[i] = cfo[i]; + dm_info->cfo_tail[i] = (cfo[i] * 5) >> 1; + } + } +} + +static void +rtw8814a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 txagc_table_wd; + u8 rate, pwr_index; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + + pwr_index = hal->tx_pwr_tbl[path][rate] + 2; + if (pwr_index > rtwdev->chip->max_power_index) + pwr_index = rtwdev->chip->max_power_index; + + txagc_table_wd = 0x00801000; + txagc_table_wd |= (pwr_index << 24) | (path << 8) | rate; + + rtw_write32(rtwdev, REG_AGC_TBL, txagc_table_wd); + + /* first time to turn on the txagc table + * second to write the addr0 + */ + if (rate == DESC_RATE1M) + rtw_write32(rtwdev, REG_AGC_TBL, txagc_table_wd); + } +} + +static void rtw8814a_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + int path; + + for (path = 0; path < hal->rf_path_num; path++) { + if (hal->current_band_type == RTW_BAND_2G) + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_CCK); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_OFDM); + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + continue; + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_1S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_1S); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_2S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_2S); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_3S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_3S); + } +} + +static void rtw8814a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ +} + +/* Without this RTL8814A sends too many frames and (some?) 11n AP + * can't handle it, resulting in low TX speed. Other chips seem fine. + */ +static void rtw8814a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_256K); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + +static void rtw8814a_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt, ofdm_fa_cnt; + u32 crc32_cnt, cca32_cnt; + u32 cck_enable; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} + +#define MAC_REG_NUM_8814 2 +#define BB_REG_NUM_8814 14 +#define RF_REG_NUM_8814 1 + +static void rtw8814a_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *mac_backup, u32 *bb_backup, + const u32 *mac_regs, + const u32 *bb_regs) +{ + u32 i; + + /* save MACBB default value */ + for (i = 0; i < MAC_REG_NUM_8814; i++) + mac_backup[i] = rtw_read32(rtwdev, mac_regs[i]); + + for (i = 0; i < BB_REG_NUM_8814; i++) + bb_backup[i] = rtw_read32(rtwdev, bb_regs[i]); +} + +static void rtw8814a_iqk_backup_rf(struct rtw_dev *rtwdev, + u32 rf_backup[][4], const u32 *rf_regs) +{ + u32 i; + + /* Save RF Parameters */ + for (i = 0; i < RF_REG_NUM_8814; i++) { + rf_backup[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_C] = rtw_read_rf(rtwdev, RF_PATH_C, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_D] = rtw_read_rf(rtwdev, RF_PATH_D, + rf_regs[i], RFREG_MASK); + } +} + +static void rtw8814a_iqk_afe_setting(struct rtw_dev *rtwdev, bool do_iqk) +{ + if (do_iqk) { + /* IQK AFE setting RX_WAIT_CCA mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x0e808003); + } else { + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x07808003); + } + + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x1); + + rtw_write8_set(rtwdev, REG_GNT_BT, BIT(2) | BIT(1)); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT(2) | BIT(1)); + + rtw_write32_set(rtwdev, REG_CCK_RPT_FORMAT, BIT(2)); + rtw_write32_clr(rtwdev, REG_CCK_RPT_FORMAT, BIT(2)); +} + +static void rtw8814a_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *mac_backup, u32 *bb_backup, + const u32 *mac_regs, + const u32 *bb_regs) +{ + u32 i; + + /* Reload MacBB Parameters */ + for (i = 0; i < MAC_REG_NUM_8814; i++) + rtw_write32(rtwdev, mac_regs[i], mac_backup[i]); + + for (i = 0; i < BB_REG_NUM_8814; i++) + rtw_write32(rtwdev, bb_regs[i], bb_backup[i]); +} + +static void rtw8814a_iqk_restore_rf(struct rtw_dev *rtwdev, + const u32 rf_backup[][4], + const u32 *rf_regs) +{ + u32 i; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_C, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_D, RF_LUTWE, RFREG_MASK, 0x0); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_C, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_D, RF_RXBB2, RFREG_MASK, 0x88001); + + for (i = 0; i < RF_REG_NUM_8814; i++) { + rtw_write_rf(rtwdev, RF_PATH_A, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_A]); + rtw_write_rf(rtwdev, RF_PATH_B, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_B]); + rtw_write_rf(rtwdev, RF_PATH_C, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_C]); + rtw_write_rf(rtwdev, RF_PATH_D, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_D]); + } +} + +static void rtw8814a_iqk_reset_nctl(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, 0x1b00, 0xf8000000); + rtw_write32(rtwdev, 0x1b80, 0x00000006); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000); + rtw_write32(rtwdev, 0x1b80, 0x00000002); +} + +static void rtw8814a_iqk_configure_mac(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + rtw_write32_clr(rtwdev, REG_BCN_CTRL, + (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION); + + /* RX ante off */ + rtw_write8(rtwdev, REG_RXPSEL, 0x00); + /* CCA off */ + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xe); + /* CCK RX path off */ + rtw_write32_set(rtwdev, REG_PRECTRL, BIT_IQ_WGT); + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, BIT_RFE_SELSW0_D, 0x77); + rtw_write32_mask(rtwdev, REG_PSD, BIT_PSD_INI, 0x0); + + rtw_write32_mask(rtwdev, REG_RFE_INV0, 0xf, 0x0); +} + +static void rtw8814a_lok_one_shot(struct rtw_dev *rtwdev, u8 path) +{ + u32 lok_temp1, lok_temp2; + bool lok_ready; + u8 ii; + + /* ADC Clock source */ + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + /* LOK: CMD ID = 0 + * {0xf8000011, 0xf8000021, 0xf8000041, 0xf8000081} + */ + rtw_write32(rtwdev, 0x1b00, 0xf8000001 | (BIT(path) << 4)); + + usleep_range(1000, 1100); + + if (read_poll_timeout(!rtw_read32_mask, lok_ready, lok_ready, + 1000, 10000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, "==>S%d LOK timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + + rtw_write_rf(rtwdev, path, RF_DTXLOK, RFREG_MASK, 0x08400); + + return; + } + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + rtw_write32(rtwdev, 0x1bd4, 0x003f0001); + + lok_temp2 = rtw_read32_mask(rtwdev, 0x1bfc, 0x003e0000); + lok_temp2 = (lok_temp2 + 0x10) & 0x1f; + + lok_temp1 = rtw_read32_mask(rtwdev, 0x1bfc, 0x0000003e); + lok_temp1 = (lok_temp1 + 0x10) & 0x1f; + + for (ii = 1; ii < 5; ii++) { + lok_temp1 += (lok_temp1 & BIT(4 - ii)) << (ii * 2); + lok_temp2 += (lok_temp2 & BIT(4 - ii)) << (ii * 2); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "path %d lok_temp1 = %#x, lok_temp2 = %#x\n", + path, lok_temp1 >> 4, lok_temp2 >> 4); + + rtw_write_rf(rtwdev, path, RF_DTXLOK, 0x07c00, lok_temp1 >> 4); + rtw_write_rf(rtwdev, path, RF_DTXLOK, 0xf8000, lok_temp2 >> 4); +} + +static void rtw8814a_iqk_tx_one_shot(struct rtw_dev *rtwdev, u8 path, + u32 *tx_matrix, bool *tx_ok) +{ + u8 bw = rtwdev->hal.current_band_width; + u8 cal_retry; + u32 iqk_cmd; + + for (cal_retry = 0; cal_retry < 4; cal_retry++) { + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + + iqk_cmd = 0xf8000001 | ((bw + 3) << 8) | (BIT(path) << 4); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXK_Trigger = %#x\n", iqk_cmd); + + rtw_write32(rtwdev, 0x1b00, iqk_cmd); + + usleep_range(10000, 11000); + + if (read_poll_timeout(!rtw_read32_mask, *tx_ok, *tx_ok, + 1000, 20000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx iqk S%d timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + } else { + *tx_ok = !rtw_read32_mask(rtwdev, 0x1b08, BIT(26)); + + if (*tx_ok) + break; + } + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> 0x1b00 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b00)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> 0x1b08 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b08)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> cal_retry = %x\n", + path, cal_retry); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + + if (*tx_ok) { + *tx_matrix = rtw_read32(rtwdev, 0x1b38); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d_IQC = 0x%x\n", + path, *tx_matrix); + } +} + +static void rtw8814a_iqk_rx_one_shot(struct rtw_dev *rtwdev, u8 path, + u32 *tx_matrix, bool *tx_ok) +{ + static const u16 iqk_apply[RTW_RF_PATH_MAX] = { + REG_TXAGCIDX, REG_TX_AGC_B, REG_TX_AGC_C, REG_TX_AGC_D + }; + u8 band = rtwdev->hal.current_band_type; + u8 bw = rtwdev->hal.current_band_width; + u32 rx_matrix; + u8 cal_retry; + u32 iqk_cmd; + bool rx_ok; + + for (cal_retry = 0; cal_retry < 4; cal_retry++) { + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + + if (band == RTW_BAND_2G) { + rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT(11), 0x1); + rtw_write_rf(rtwdev, path, RF_GAINTX, 0xfffff, 0x51ce1); + + switch (path) { + case 0: + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_B, + 0x54775477); + break; + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_C, + 0x54775477); + break; + case 3: + rtw_write32(rtwdev, REG_RFE_INVSEL_D, 0x75400000); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, + 0x77777777); + break; + } + } + + iqk_cmd = 0xf8000001 | ((9 - bw) << 8) | (BIT(path) << 4); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXK_Trigger = 0x%x\n", iqk_cmd); + + rtw_write32(rtwdev, 0x1b00, iqk_cmd); + + usleep_range(10000, 11000); + + if (read_poll_timeout(!rtw_read32_mask, rx_ok, rx_ok, + 1000, 20000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx iqk S%d timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + } else { + rx_ok = !rtw_read32_mask(rtwdev, 0x1b08, BIT(26)); + + if (rx_ok) + break; + } + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> 0x1b00 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b00)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> 0x1b08 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b08)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> cal_retry = %x\n", + path, cal_retry); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + + if (rx_ok) { + rtw_write32(rtwdev, 0x1b3c, 0x20000000); + rx_matrix = rtw_read32(rtwdev, 0x1b3c); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d_IQC = 0x%x\n", + path, rx_matrix); + } + + if (*tx_ok) + rtw_write32(rtwdev, 0x1b38, *tx_matrix); + else + rtw_write32_mask(rtwdev, iqk_apply[path], BIT(0), 0x0); + + if (!rx_ok) + rtw_write32_mask(rtwdev, iqk_apply[path], + BIT(11) | BIT(10), 0x0); + + if (band == RTW_BAND_2G) + rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT(11), 0x0); +} + +static void rtw8814a_iqk(struct rtw_dev *rtwdev) +{ + u8 band = rtwdev->hal.current_band_type; + u8 bw = rtwdev->hal.current_band_width; + u32 tx_matrix[RTW_RF_PATH_MAX]; + bool tx_ok[RTW_RF_PATH_MAX]; + u8 path; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "IQK band = %d GHz bw = %d MHz\n", + band == RTW_BAND_2G ? 2 : 5, (1 << (bw + 1)) * 10); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_C, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_D, RF_TXMOD, BIT(19), 0x1); + + rtw_write32_mask(rtwdev, REG_TXAGCIDX, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_B, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_C, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_D, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + + if (band == RTW_BAND_5G) + rtw_write32(rtwdev, 0x1b00, 0xf8000ff1); + else + rtw_write32(rtwdev, 0x1b00, 0xf8000ef1); + + usleep_range(1000, 1100); + + rtw_write32(rtwdev, 0x810, 0x20101063); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x0B00C000); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_lok_one_shot(rtwdev, path); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_iqk_tx_one_shot(rtwdev, path, + &tx_matrix[path], &tx_ok[path]); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_iqk_rx_one_shot(rtwdev, path, + &tx_matrix[path], &tx_ok[path]); +} + +static void rtw8814a_do_iqk(struct rtw_dev *rtwdev) +{ + static const u32 backup_mac_reg[MAC_REG_NUM_8814] = {0x520, 0x550}; + static const u32 backup_bb_reg[BB_REG_NUM_8814] = { + 0xa14, 0x808, 0x838, 0x90c, 0x810, 0xcb0, 0xeb0, + 0x18b4, 0x1ab4, 0x1abc, 0x9a4, 0x764, 0xcbc, 0x910 + }; + static const u32 backup_rf_reg[RF_REG_NUM_8814] = {0x0}; + u32 rf_backup[RF_REG_NUM_8814][RTW_RF_PATH_MAX]; + u32 mac_backup[MAC_REG_NUM_8814]; + u32 bb_backup[BB_REG_NUM_8814]; + + rtw8814a_iqk_backup_mac_bb(rtwdev, mac_backup, bb_backup, + backup_mac_reg, backup_bb_reg); + rtw8814a_iqk_afe_setting(rtwdev, true); + rtw8814a_iqk_backup_rf(rtwdev, rf_backup, backup_rf_reg); + rtw8814a_iqk_configure_mac(rtwdev); + rtw8814a_iqk(rtwdev); + rtw8814a_iqk_reset_nctl(rtwdev); /* for 3-wire to BB use */ + rtw8814a_iqk_afe_setting(rtwdev, false); + rtw8814a_iqk_restore_mac_bb(rtwdev, mac_backup, bb_backup, + backup_mac_reg, backup_bb_reg); + rtw8814a_iqk_restore_rf(rtwdev, rf_backup, backup_rf_reg); +} + +static void rtw8814a_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8814a_do_iqk(rtwdev); +} + +static void rtw8814a_coex_cfg_init(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + u8 pos_type) +{ + /* Override rtw_coex_coex_ctrl_owner(). RF path C does not + * function when BIT_LTE_MUX_CTRL_PATH is set. + */ + rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL + 3, + BIT_LTE_MUX_CTRL_PATH >> 24); +} + +static void rtw8814a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + + /* Only needed to make rtw8814a_coex_cfg_ant_switch() run. */ + coex_rfe->ant_switch_exist = true; +} + +static void rtw8814a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ +} + +static void rtw8814a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static void rtw8814a_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path, + u8 tx_pwr_idx_offset, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + s8 delta_pwr_idx = dm_info->delta_power_index[path]; + u8 swing_index = dm_info->default_ofdm_index; + u8 max_tx_pwr_idx_offset = 0xf; + u8 swing_lower_bound = 0; + s8 agc_index = 0; + + tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= tx_pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > tx_pwr_idx_offset) { + agc_index = tx_pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - tx_pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else { + if (dm_info->default_ofdm_index > abs(delta_pwr_idx)) + swing_index = + dm_info->default_ofdm_index + delta_pwr_idx; + else + swing_index = swing_lower_bound; + swing_index = max_t(u8, swing_index, swing_lower_bound); + + agc_index = 0; + } + + if (swing_index >= RTW_TXSCALE_SIZE) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = RTW_TXSCALE_SIZE - 1; + } + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8814a_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path, + u8 pwr_idx_offset) +{ + static const u32 txagc_reg[RTW_RF_PATH_MAX] = { + REG_TX_AGC_A, REG_TX_AGC_B, REG_TX_AGC_C, REG_TX_AGC_D + }; + static const u32 txscale_reg[RTW_RF_PATH_MAX] = { + REG_TXSCALE_A, REG_TXSCALE_B, REG_TXSCALE_C, REG_TXSCALE_D + }; + s8 txagc_idx; + u8 swing_idx; + + rtw8814a_txagc_swing_offset(rtwdev, path, pwr_idx_offset, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, txagc_reg[path], GENMASK(29, 25), + txagc_idx); + rtw_write32_mask(rtwdev, txscale_reg[path], BB_SWING_MASK, + rtw8814a_txscale_tbl[swing_idx]); +} + +static void rtw8814a_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + u8 max_pwr_idx = rtwdev->chip->max_power_index; + u8 band_width = rtwdev->hal.current_band_width; + u8 channel = rtwdev->hal.current_channel; + u8 tx_rate = rtwdev->dm_info.tx_rate; + u8 regd = rtw_regd_get(rtwdev); + u8 pwr_idx_offset, tx_pwr_idx; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + + rtw8814a_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset); +} + +static void rtw8814a_phy_pwrtrack_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 power_idx_cur, power_idx_last; + u8 delta; + + /* 8814A only has one thermal meter at PATH A */ + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + power_idx_last = dm_info->delta_power_index[path]; + power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, + path, RF_PATH_A, delta); + + /* if delta of power indexes are the same, just skip */ + if (power_idx_cur == power_idx_last) + return; + + dm_info->delta_power_index[path] = power_idx_cur; + rtw8814a_pwrtrack_set(rtwdev, path); +} + +static void rtw8814a_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, path; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) + rtw8814a_phy_pwrtrack_path(rtwdev, &swing_table, path); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8814a_do_iqk(rtwdev); +} + +static void rtw8814a_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8814a_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8814a_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* Override rtw_phy_cck_pd_lv_link(). It implements something + * like type 2/3/4. We need type 1 here. + */ + if (rtw_is_assoc(rtwdev)) { + if (dm_info->min_rssi > 60) { + new_lvl = CCK_PD_LV3; + } else if (dm_info->min_rssi > 35) { + new_lvl = CCK_PD_LV2; + } else if (dm_info->min_rssi > 20) { + if (dm_info->cck_fa_avg > 500) + new_lvl = CCK_PD_LV2; + else if (dm_info->cck_fa_avg < 250) + new_lvl = CCK_PD_LV1; + else + return; + } else { + new_lvl = CCK_PD_LV1; + } + } + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + + rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); +} + +static void rtw8814a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 led_gpio_cfg; + + led_gpio_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + led_gpio_cfg |= BIT(16) | BIT(17) | BIT(21) | BIT(22); + + if (brightness == LED_OFF) { + led_gpio_cfg |= BIT(8) | BIT(9) | BIT(13) | BIT(14); + } else { + led_gpio_cfg &= ~(BIT(8) | BIT(9) | BIT(13) | BIT(14)); + led_gpio_cfg &= ~(BIT(0) | BIT(1) | BIT(5) | BIT(6)); + } + + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, led_gpio_cfg); +} + +static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + + fill_txdesc_checksum_common(txdesc, words); +} + +static const struct rtw_chip_ops rtw8814a_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8814a_phy_set_param, + .read_efuse = rtw8814a_read_efuse, + .query_phy_status = rtw8814a_query_phy_status, + .set_channel = rtw8814a_set_channel, + .mac_init = rtw8814a_mac_init, + .mac_postinit = NULL, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8814a_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8814a_cfg_ldo25, + .efuse_grant = rtw8814a_efuse_grant, + .set_ampdu_factor = rtw8814a_set_ampdu_factor, + .false_alarm_statistics = rtw8814a_false_alarm_statistics, + .phy_calibration = rtw8814a_phy_calibration, + .cck_pd_set = rtw8814a_phy_cck_pd_set, + .pwr_track = rtw8814a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .led_set = rtw8814a_led_set, + .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, + + .coex_set_init = rtw8814a_coex_cfg_init, + .coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8814a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8814a_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8814a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8814a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8814a_coex_cfg_wl_rx_gain, +}; + +static const struct rtw_rqpn rqpn_table_8814a[] = { + /* SDIO */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, /* vo vi */ + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, /* be bk */ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, /* mg hi */ + /* PCIE */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + /* USB, 2 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + /* USB, 3 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + /* USB, 4 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8814a = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static const struct rtw_page_table page_table_8814a[] = { + /* SDIO */ + {0, 0, 0, 0, 0}, /* hq nq lq exq gapq */ + /* PCIE */ + {32, 32, 32, 32, 0}, + /* USB, 2 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 3 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 4 bulk out */ + {32, 32, 32, 32, 0}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8814a = {}; + +static const struct rtw_hw_reg rtw8814a_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, + [2] = { .addr = 0x1850, .mask = 0x7f }, + [3] = { .addr = 0x1a50, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8814a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8814a_bb_pg_type0_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type0_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_type0_tbl }, + [1] = { .phy_pg_tbl = &rtw8814a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type1_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_tbl }, +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8814a[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8814a[] = {30, 30, 30, 30}; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8814a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static const struct coex_rf_para rf_para_rx_8814a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8814a) == ARRAY_SIZE(rf_para_rx_8814a)); + +const struct rtw_chip_info rtw8814a_hw_spec = { + .ops = &rtw8814a_ops, + .id = RTW_CHIP_TYPE_8814A, + .fw_name = "rtw88/rtw8814a_fw.bin", + .wlan_cpu = RTW_WCPU_3081, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 1024, + .log_efuse_size = 512, + .ptct_efuse_size = 0, + .txff_size = (2048 - 10) * TX_PAGE_SIZE, + .rxff_size = 23552, + .rsvd_drv_pg_num = 8, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, + .dig_min = 0x1c, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = true, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .amsdu_in_ampdu = false, /* RX speed is better without AMSDU */ + .usb_tx_agg_desc_num = 3, + .hw_feature_report = false, + .c2h_ra_report_size = 6, + .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), + .sys_func_en = 0xDC, + .pwr_on_seq = card_enable_flow_8814a, + .pwr_off_seq = card_disable_flow_8814a, + .rqpn_table = rqpn_table_8814a, + .prioq_addrs = &prioq_addrs_8814a, + .page_table = page_table_8814a, + .intf_table = &phy_para_table_8814a, + .dig = rtw8814a_dig, + .dig_cck = NULL, + .rf_base_addr = {0x2800, 0x2c00, 0x3800, 0x3c00}, + .rf_sipi_addr = {0xc90, 0xe90, 0x1890, 0x1a90}, + .ltecoex_addr = NULL, + .mac_tbl = &rtw8814a_mac_tbl, + .agc_tbl = &rtw8814a_agc_tbl, + .bb_tbl = &rtw8814a_bb_tbl, + .rf_tbl = {&rtw8814a_rf_a_tbl, &rtw8814a_rf_b_tbl, + &rtw8814a_rf_c_tbl, &rtw8814a_rf_d_tbl}, + .rfe_defs = rtw8814a_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8814a_rfe_defs), + .iqk_threshold = 8, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0, + .bt_desired_ver = 0, + .scbd_support = false, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8814a, + .bt_rssi_step = bt_rssi_step_8814a, + .table_sant_num = 0, + .table_sant = NULL, + .table_nsant_num = 0, + .table_nsant = NULL, + .tdma_sant_num = 0, + .tdma_sant = NULL, + .tdma_nsant_num = 0, + .tdma_nsant = NULL, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8814a), + .wl_rf_para_tx = rf_para_tx_8814a, + .wl_rf_para_rx = rf_para_rx_8814a, + .bt_afh_span_bw20 = 0x24, + .bt_afh_span_bw40 = 0x36, + .afh_5g_num = 0, + .afh_5g = NULL, + .coex_info_hw_regs_num = 0, + .coex_info_hw_regs = NULL, +}; +EXPORT_SYMBOL(rtw8814a_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8814a_fw.bin"); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814a driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.h b/drivers/net/wireless/realtek/rtw88/rtw8814a.h new file mode 100644 index 000000000..c57c7c8f9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW8814A_H__ +#define __RTW8814A_H__ + +struct rtw8814au_efuse { + u8 vid[2]; /* 0xd0 */ + u8 pid[2]; /* 0xd2 */ + u8 res[4]; /* 0xd4 */ + u8 mac_addr[ETH_ALEN]; /* 0xd8 */ +} __packed; + +struct rtw8814ae_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vid[2]; /* 0xd6 */ + u8 did[2]; /* 0xd8 */ + u8 svid[2]; /* 0xda */ + u8 smid[2]; /* 0xdc */ +} __packed; + +struct rtw8814a_efuse { + __le16 rtl_id; + u8 res0[0x0c]; + u8 usb_mode; /* 0x0e */ + u8 res1; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; /* 0xb9 */ + u8 thermal_meter; /* 0xba */ + u8 iqk_lck; /* 0xbb */ + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; /* 0xbf */ + u8 rf_board_option; /* 0xc1 */ + u8 res2; + u8 rf_bt_setting; /* 0xc3 */ + u8 eeprom_version; /* 0xc4 */ + u8 eeprom_customer_id; /* 0xc5 */ + u8 tx_bb_swing_setting_2g; /* 0xc6 */ + u8 tx_bb_swing_setting_5g; /* 0xc7 */ + u8 res3; + u8 trx_antenna_option; /* 0xc9 */ + u8 rfe_option; /* 0xca */ + u8 country_code[2]; /* 0xcb */ + u8 res4[3]; + union { + struct rtw8814au_efuse u; + struct rtw8814ae_efuse e; + }; + u8 res5[0x122]; /* 0xde */ +} __packed; + +static_assert(sizeof(struct rtw8814a_efuse) == 512); + +extern const struct rtw_chip_info rtw8814a_hw_spec; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8814a_table.c new file mode 100644 index 000000000..b9ce51a09 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814a_table.c @@ -0,0 +1,23930 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8814a_table.h" + +static const u32 rtw8814a_mac[] = { + 0x010, 0x0000007C, + 0x014, 0x000000DB, + 0x016, 0x00000002, + 0x073, 0x00000010, + 0x420, 0x00000080, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x000000F0, + 0x446, 0x00000001, + 0x447, 0x000000FE, + 0x448, 0x00000000, + 0x449, 0x00000000, + 0x44A, 0x00000000, + 0x44B, 0x00000040, + 0x44C, 0x00000010, + 0x44D, 0x000000F0, + 0x44E, 0x0000003F, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x00000000, + 0x452, 0x00000000, + 0x453, 0x00000040, + 0x45E, 0x00000004, + 0x49C, 0x00000010, + 0x49D, 0x000000F0, + 0x49E, 0x00000000, + 0x49F, 0x00000006, + 0x4A0, 0x000000E0, + 0x4A1, 0x00000003, + 0x4A2, 0x00000000, + 0x4A3, 0x00000040, + 0x4A4, 0x00000015, + 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, + 0x4A7, 0x00000006, + 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, + 0x4AA, 0x00000000, + 0x4AB, 0x00000000, + 0x7DA, 0x00000008, + 0x1448, 0x00000006, + 0x144A, 0x00000006, + 0x144C, 0x00000006, + 0x144E, 0x00000006, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CA, 0x0000003C, + 0x4CB, 0x0000003C, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4CF, 0x00000008, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x521, 0x0000002F, + 0x525, 0x00000047, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000064, + 0x55D, 0x000000FF, + 0x577, 0x00000003, + 0x5BE, 0x00000064, + 0x604, 0x00000001, + 0x605, 0x00000030, + 0x607, 0x00000001, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x60A, 0x00000000, + 0x60C, 0x00000018, + 0x60D, 0x00000050, + 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, + 0x6A2, 0x000000FF, + 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, + 0x6A5, 0x000000FF, + 0x6DE, 0x00000084, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000064, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, + 0x7D5, 0x000000BC, + 0x7D8, 0x00000028, + 0x7D9, 0x00000000, + 0x7DA, 0x0000000B, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_mac, rtw_phy_cfg_mac); + +static const u32 rtw8814a_agc[] = { + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000003, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0xA1460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x27620003, + 0x81C, 0x26640003, + 0x81C, 0x25660003, + 0x81C, 0x24680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x216E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xE4340003, + 0x81C, 0xE3360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x49580003, + 0x81C, 0x485A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xE4340003, + 0x81C, 0xE3360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x49580003, + 0x81C, 0x485A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xDF000003, + 0x81C, 0xDF020003, + 0x81C, 0xDF040003, + 0x81C, 0xDE060003, + 0x81C, 0xDD080003, + 0x81C, 0xDC0A0003, + 0x81C, 0xDB0C0003, + 0x81C, 0xDA0E0003, + 0x81C, 0xD9100003, + 0x81C, 0xD8120003, + 0x81C, 0xD7140003, + 0x81C, 0xD6160003, + 0x81C, 0xD5180003, + 0x81C, 0xD41A0003, + 0x81C, 0xD31C0003, + 0x81C, 0xD21E0003, + 0x81C, 0xD1200003, + 0x81C, 0xD0220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xA73A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0x87460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x27640003, + 0x81C, 0x26660003, + 0x81C, 0x25680003, + 0x81C, 0x246A0003, + 0x81C, 0x236C0003, + 0x81C, 0x226E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xDF000003, + 0x81C, 0xDF020003, + 0x81C, 0xDF040003, + 0x81C, 0xDE060003, + 0x81C, 0xDD080003, + 0x81C, 0xDC0A0003, + 0x81C, 0xDB0C0003, + 0x81C, 0xDA0E0003, + 0x81C, 0xD9100003, + 0x81C, 0xD8120003, + 0x81C, 0xD7140003, + 0x81C, 0xD6160003, + 0x81C, 0xD5180003, + 0x81C, 0xD41A0003, + 0x81C, 0xD31C0003, + 0x81C, 0xD21E0003, + 0x81C, 0xD1200003, + 0x81C, 0xD0220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xA73A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0x87460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x27640003, + 0x81C, 0x26660003, + 0x81C, 0x25680003, + 0x81C, 0x246A0003, + 0x81C, 0x236C0003, + 0x81C, 0x226E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0x0F260003, + 0x81C, 0x0E280003, + 0x81C, 0x0D2A0003, + 0x81C, 0x0C2C0003, + 0x81C, 0x0B2E0003, + 0x81C, 0x0A300003, + 0x81C, 0x09320003, + 0x81C, 0x08340003, + 0x81C, 0x07360003, + 0x81C, 0x06380003, + 0x81C, 0x053A0003, + 0x81C, 0x043C0003, + 0x81C, 0x033E0003, + 0x81C, 0x23400003, + 0x81C, 0x22420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0x684E0003, + 0x81C, 0x67500003, + 0x81C, 0x66520003, + 0x81C, 0x65540003, + 0x81C, 0x64560003, + 0x81C, 0x63580003, + 0x81C, 0x625A0003, + 0x81C, 0x615C0003, + 0x81C, 0x475E0003, + 0x81C, 0x46600003, + 0x81C, 0x45620003, + 0x81C, 0x44640003, + 0x81C, 0x43660003, + 0x81C, 0x42680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0x08340003, + 0x81C, 0x07360003, + 0x81C, 0x06380003, + 0x81C, 0x053A0003, + 0x81C, 0x043C0003, + 0x81C, 0x033E0003, + 0x81C, 0x02400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0x684C0003, + 0x81C, 0x674E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0xA0000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0xA1460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x27620003, + 0x81C, 0x26640003, + 0x81C, 0x25660003, + 0x81C, 0x24680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x216E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x444E0103, + 0x81C, 0x43500103, + 0x81C, 0x42520103, + 0x81C, 0x41540103, + 0x81C, 0x25560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x065C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xE12E0103, + 0x81C, 0xA5300103, + 0x81C, 0xA4320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0x843A0103, + 0x81C, 0x833C0103, + 0x81C, 0x823E0103, + 0x81C, 0x81400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x61480103, + 0x81C, 0x454A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x25520103, + 0x81C, 0x24540103, + 0x81C, 0x23560103, + 0x81C, 0x06580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000103, + 0x81C, 0xFB020103, + 0x81C, 0xFA040103, + 0x81C, 0xF9060103, + 0x81C, 0xF8080103, + 0x81C, 0xF70A0103, + 0x81C, 0xF60C0103, + 0x81C, 0xF50E0103, + 0x81C, 0xF4100103, + 0x81C, 0xF3120103, + 0x81C, 0xF2140103, + 0x81C, 0xF1160103, + 0x81C, 0xF0180103, + 0x81C, 0xEF1A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xE1360103, + 0x81C, 0x87380103, + 0x81C, 0x863A0103, + 0x81C, 0x853C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x464C0103, + 0x81C, 0x454E0103, + 0x81C, 0x44500103, + 0x81C, 0x43520103, + 0x81C, 0x26540103, + 0x81C, 0x25560103, + 0x81C, 0x24580103, + 0x81C, 0x075A0103, + 0x81C, 0x065C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA6300103, + 0x81C, 0xA5320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0x843C0103, + 0x81C, 0x833E0103, + 0x81C, 0x82400103, + 0x81C, 0x81420103, + 0x81C, 0x64440103, + 0x81C, 0x63460103, + 0x81C, 0x62480103, + 0x81C, 0x614A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x41520103, + 0x81C, 0x25540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x225A0103, + 0x81C, 0x055C0103, + 0x81C, 0x045E0103, + 0x81C, 0x03600103, + 0x81C, 0x02620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xA33A0103, + 0x81C, 0xA23C0103, + 0x81C, 0xA13E0103, + 0x81C, 0x84400103, + 0x81C, 0x83420103, + 0x81C, 0x82440103, + 0x81C, 0x81460103, + 0x81C, 0x64480103, + 0x81C, 0x634A0103, + 0x81C, 0x624C0103, + 0x81C, 0x614E0103, + 0x81C, 0x45500103, + 0x81C, 0x44520103, + 0x81C, 0x43540103, + 0x81C, 0x42560103, + 0x81C, 0x25580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x065E0103, + 0x81C, 0x05600103, + 0x81C, 0x04620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000103, + 0x81C, 0xF9020103, + 0x81C, 0xF8040103, + 0x81C, 0xF7060103, + 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, + 0x81C, 0xF40C0103, + 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, + 0x81C, 0xF1120103, + 0x81C, 0xF0140103, + 0x81C, 0xEF160103, + 0x81C, 0xEE180103, + 0x81C, 0xED1A0103, + 0x81C, 0xEC1C0103, + 0x81C, 0xEB1E0103, + 0x81C, 0xEA200103, + 0x81C, 0xE9220103, + 0x81C, 0xE8240103, + 0x81C, 0xE7260103, + 0x81C, 0xE6280103, + 0x81C, 0xE52A0103, + 0x81C, 0xE42C0103, + 0x81C, 0xE32E0103, + 0x81C, 0xE2300103, + 0x81C, 0xE1320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x454E0103, + 0x81C, 0x44500103, + 0x81C, 0x43520103, + 0x81C, 0x42540103, + 0x81C, 0x41560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x225C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFF020103, + 0x81C, 0xFE040103, + 0x81C, 0xFD060103, + 0x81C, 0xFC080103, + 0x81C, 0xFB0A0103, + 0x81C, 0xFA0C0103, + 0x81C, 0xF90E0103, + 0x81C, 0xF8100103, + 0x81C, 0xF7120103, + 0x81C, 0xF6140103, + 0x81C, 0xF5160103, + 0x81C, 0xF4180103, + 0x81C, 0xF31A0103, + 0x81C, 0xF21C0103, + 0x81C, 0xF11E0103, + 0x81C, 0xF0200103, + 0x81C, 0xEF220103, + 0x81C, 0xEE240103, + 0x81C, 0xED260103, + 0x81C, 0xEC280103, + 0x81C, 0xEB2A0103, + 0x81C, 0xEA2C0103, + 0x81C, 0xE92E0103, + 0x81C, 0xE8300103, + 0x81C, 0xE7320103, + 0x81C, 0xE6340103, + 0x81C, 0xE5360103, + 0x81C, 0xE4380103, + 0x81C, 0xE33A0103, + 0x81C, 0xA53C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x85460103, + 0x81C, 0x84480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x64500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x44560103, + 0x81C, 0x43580103, + 0x81C, 0x425A0103, + 0x81C, 0x265C0103, + 0x81C, 0x255E0103, + 0x81C, 0x24600103, + 0x81C, 0x07620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xE12E0103, + 0x81C, 0xA4300103, + 0x81C, 0xA3320103, + 0x81C, 0xA2340103, + 0x81C, 0xA1360103, + 0x81C, 0x85380103, + 0x81C, 0x843A0103, + 0x81C, 0x833C0103, + 0x81C, 0x823E0103, + 0x81C, 0x65400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x45480103, + 0x81C, 0x444A0103, + 0x81C, 0x434C0103, + 0x81C, 0x264E0103, + 0x81C, 0x25500103, + 0x81C, 0x24520103, + 0x81C, 0x08540103, + 0x81C, 0x07560103, + 0x81C, 0x06580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFF020103, + 0x81C, 0xFE040103, + 0x81C, 0xFD060103, + 0x81C, 0xFC080103, + 0x81C, 0xFB0A0103, + 0x81C, 0xFA0C0103, + 0x81C, 0xF90E0103, + 0x81C, 0xF8100103, + 0x81C, 0xF7120103, + 0x81C, 0xF6140103, + 0x81C, 0xF5160103, + 0x81C, 0xF4180103, + 0x81C, 0xF31A0103, + 0x81C, 0xF21C0103, + 0x81C, 0xF11E0103, + 0x81C, 0xF0200103, + 0x81C, 0xEF220103, + 0x81C, 0xEE240103, + 0x81C, 0xED260103, + 0x81C, 0xEC280103, + 0x81C, 0xEB2A0103, + 0x81C, 0xEA2C0103, + 0x81C, 0xE92E0103, + 0x81C, 0xE8300103, + 0x81C, 0xE7320103, + 0x81C, 0xE6340103, + 0x81C, 0xE5360103, + 0x81C, 0xE4380103, + 0x81C, 0xE33A0103, + 0x81C, 0xA53C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x85460103, + 0x81C, 0x84480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x64500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x44560103, + 0x81C, 0x43580103, + 0x81C, 0x425A0103, + 0x81C, 0x265C0103, + 0x81C, 0x255E0103, + 0x81C, 0x24600103, + 0x81C, 0x07620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA6300103, + 0x81C, 0xA5320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0x843C0103, + 0x81C, 0x833E0103, + 0x81C, 0x82400103, + 0x81C, 0x81420103, + 0x81C, 0x64440103, + 0x81C, 0x63460103, + 0x81C, 0x62480103, + 0x81C, 0x614A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x41520103, + 0x81C, 0x25540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x225A0103, + 0x81C, 0x055C0103, + 0x81C, 0x045E0103, + 0x81C, 0x03600103, + 0x81C, 0x02620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000103, + 0x81C, 0xF9020103, + 0x81C, 0xF8040103, + 0x81C, 0xF7060103, + 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, + 0x81C, 0xF40C0103, + 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, + 0x81C, 0xF1120103, + 0x81C, 0xF0140103, + 0x81C, 0xEF160103, + 0x81C, 0xEE180103, + 0x81C, 0xED1A0103, + 0x81C, 0xCC1C0103, + 0x81C, 0xCB1E0103, + 0x81C, 0xCA200103, + 0x81C, 0xE9220103, + 0x81C, 0xE8240103, + 0x81C, 0xE7260103, + 0x81C, 0xE6280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA7300103, + 0x81C, 0xA6320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x65440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x444E0103, + 0x81C, 0x43500103, + 0x81C, 0x42520103, + 0x81C, 0x41540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFE020103, + 0x81C, 0xFD040103, + 0x81C, 0xFC060103, + 0x81C, 0xFB080103, + 0x81C, 0xFA0A0103, + 0x81C, 0xF90C0103, + 0x81C, 0xF80E0103, + 0x81C, 0xF7100103, + 0x81C, 0xF6120103, + 0x81C, 0xF5140103, + 0x81C, 0xF4160103, + 0x81C, 0xF3180103, + 0x81C, 0xF21A0103, + 0x81C, 0xF11C0103, + 0x81C, 0xF01E0103, + 0x81C, 0xEF200103, + 0x81C, 0xEE220103, + 0x81C, 0xED240103, + 0x81C, 0xEC260103, + 0x81C, 0xEB280103, + 0x81C, 0xEA2A0103, + 0x81C, 0xE92C0103, + 0x81C, 0xE82E0103, + 0x81C, 0xE7300103, + 0x81C, 0xE6320103, + 0x81C, 0xE5340103, + 0x81C, 0xE4360103, + 0x81C, 0xE3380103, + 0x81C, 0xE23A0103, + 0x81C, 0xE13C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x86460103, + 0x81C, 0x85480103, + 0x81C, 0x844A0103, + 0x81C, 0x834C0103, + 0x81C, 0x824E0103, + 0x81C, 0x81500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x435A0103, + 0x81C, 0x425C0103, + 0x81C, 0x415E0103, + 0x81C, 0x25600103, + 0x81C, 0x24620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000203, + 0x81C, 0xF9020203, + 0x81C, 0xF8040203, + 0x81C, 0xF7060203, + 0x81C, 0xF6080203, + 0x81C, 0xF50A0203, + 0x81C, 0xF40C0203, + 0x81C, 0xF30E0203, + 0x81C, 0xF2100203, + 0x81C, 0xF1120203, + 0x81C, 0xF0140203, + 0x81C, 0xEF160203, + 0x81C, 0xEE180203, + 0x81C, 0xED1A0203, + 0x81C, 0xEC1C0203, + 0x81C, 0xEB1E0203, + 0x81C, 0xEA200203, + 0x81C, 0xE9220203, + 0x81C, 0xE8240203, + 0x81C, 0xE7260203, + 0x81C, 0xE6280203, + 0x81C, 0xE52A0203, + 0x81C, 0xE42C0203, + 0x81C, 0xE32E0203, + 0x81C, 0xE2300203, + 0x81C, 0xE1320203, + 0x81C, 0xA5340203, + 0x81C, 0xA4360203, + 0x81C, 0xA3380203, + 0x81C, 0xA23A0203, + 0x81C, 0xA13C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x464C0203, + 0x81C, 0x454E0203, + 0x81C, 0x44500203, + 0x81C, 0x43520203, + 0x81C, 0x42540203, + 0x81C, 0x41560203, + 0x81C, 0x24580203, + 0x81C, 0x235A0203, + 0x81C, 0x065C0203, + 0x81C, 0x055E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0x853A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x25520203, + 0x81C, 0x24540203, + 0x81C, 0x23560203, + 0x81C, 0x06580203, + 0x81C, 0x055A0203, + 0x81C, 0x045C0203, + 0x81C, 0x035E0203, + 0x81C, 0x02600203, + 0x81C, 0x01620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0x87380203, + 0x81C, 0x863A0203, + 0x81C, 0x853C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x474C0203, + 0x81C, 0x464E0203, + 0x81C, 0x45500203, + 0x81C, 0x44520203, + 0x81C, 0x43540203, + 0x81C, 0x42560203, + 0x81C, 0x24580203, + 0x81C, 0x235A0203, + 0x81C, 0x075C0203, + 0x81C, 0x065E0203, + 0x81C, 0x05600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x41520203, + 0x81C, 0x25540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x065A0203, + 0x81C, 0x055C0203, + 0x81C, 0x045E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000203, + 0x81C, 0xFA020203, + 0x81C, 0xF9040203, + 0x81C, 0xF8060203, + 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, + 0x81C, 0xF50C0203, + 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, + 0x81C, 0xF2120203, + 0x81C, 0xF1140203, + 0x81C, 0xF0160203, + 0x81C, 0xEF180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xE1340203, + 0x81C, 0xA5360203, + 0x81C, 0xA4380203, + 0x81C, 0xA33A0203, + 0x81C, 0xA23C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x614C0203, + 0x81C, 0x474E0203, + 0x81C, 0x46500203, + 0x81C, 0x45520203, + 0x81C, 0x44540203, + 0x81C, 0x43560203, + 0x81C, 0x25580203, + 0x81C, 0x245A0203, + 0x81C, 0x235C0203, + 0x81C, 0x075E0203, + 0x81C, 0x06600203, + 0x81C, 0x05620203, + 0x81C, 0x04640203, + 0x81C, 0x03660203, + 0x81C, 0x02680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xA5380203, + 0x81C, 0xA43A0203, + 0x81C, 0xA33C0203, + 0x81C, 0x853E0203, + 0x81C, 0x84400203, + 0x81C, 0x83420203, + 0x81C, 0x82440203, + 0x81C, 0x81460203, + 0x81C, 0x64480203, + 0x81C, 0x634A0203, + 0x81C, 0x624C0203, + 0x81C, 0x614E0203, + 0x81C, 0x46500203, + 0x81C, 0x45520203, + 0x81C, 0x44540203, + 0x81C, 0x43560203, + 0x81C, 0x25580203, + 0x81C, 0x245A0203, + 0x81C, 0x235C0203, + 0x81C, 0x075E0203, + 0x81C, 0x06600203, + 0x81C, 0x05620203, + 0x81C, 0x04640203, + 0x81C, 0x03660203, + 0x81C, 0x02680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x84480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x45580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x24600203, + 0x81C, 0x23620203, + 0x81C, 0x07640203, + 0x81C, 0x06660203, + 0x81C, 0x05680203, + 0x81C, 0x046A0203, + 0x81C, 0x036C0203, + 0x81C, 0x026E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xE22A0203, + 0x81C, 0xA62C0203, + 0x81C, 0xA52E0203, + 0x81C, 0xA4300203, + 0x81C, 0xA3320203, + 0x81C, 0xA2340203, + 0x81C, 0xA1360203, + 0x81C, 0x86380203, + 0x81C, 0x853A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x65400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x46460203, + 0x81C, 0x45480203, + 0x81C, 0x444A0203, + 0x81C, 0x434C0203, + 0x81C, 0x264E0203, + 0x81C, 0x25500203, + 0x81C, 0x24520203, + 0x81C, 0x08540203, + 0x81C, 0x07560203, + 0x81C, 0x06580203, + 0x81C, 0x055A0203, + 0x81C, 0x045C0203, + 0x81C, 0x035E0203, + 0x81C, 0x02600203, + 0x81C, 0x01620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x84480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x45580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x24600203, + 0x81C, 0x23620203, + 0x81C, 0x07640203, + 0x81C, 0x06660203, + 0x81C, 0x05680203, + 0x81C, 0x046A0203, + 0x81C, 0x036C0203, + 0x81C, 0x026E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x41520203, + 0x81C, 0x25540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x065A0203, + 0x81C, 0x055C0203, + 0x81C, 0x045E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000203, + 0x81C, 0xF8020203, + 0x81C, 0xF7040203, + 0x81C, 0xF6060203, + 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, + 0x81C, 0xF30C0203, + 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, + 0x81C, 0xF0120203, + 0x81C, 0xEF140203, + 0x81C, 0xCE160203, + 0x81C, 0xCD180203, + 0x81C, 0xCC1A0203, + 0x81C, 0xCB1C0203, + 0x81C, 0xCA1E0203, + 0x81C, 0xC9200203, + 0x81C, 0xC8220203, + 0x81C, 0xC7240203, + 0x81C, 0xC6260203, + 0x81C, 0xC5280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x853C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x614C0203, + 0x81C, 0x444E0203, + 0x81C, 0x43500203, + 0x81C, 0x42520203, + 0x81C, 0x41540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x075A0203, + 0x81C, 0x065C0203, + 0x81C, 0x055E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x85480203, + 0x81C, 0x844A0203, + 0x81C, 0x834C0203, + 0x81C, 0x824E0203, + 0x81C, 0x81500203, + 0x81C, 0x64520203, + 0x81C, 0x63540203, + 0x81C, 0x62560203, + 0x81C, 0x61580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x25600203, + 0x81C, 0x24620203, + 0x81C, 0x06640203, + 0x81C, 0x05660203, + 0x81C, 0x04680203, + 0x81C, 0x036A0203, + 0x81C, 0x026C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000303, + 0x81C, 0xF7020303, + 0x81C, 0xF6040303, + 0x81C, 0xF5060303, + 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, + 0x81C, 0xF20C0303, + 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, + 0x81C, 0xEF120303, + 0x81C, 0xEE140303, + 0x81C, 0xED160303, + 0x81C, 0xEC180303, + 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, + 0x81C, 0xE91E0303, + 0x81C, 0xE8200303, + 0x81C, 0xE7220303, + 0x81C, 0xE6240303, + 0x81C, 0xE5260303, + 0x81C, 0xE4280303, + 0x81C, 0xE32A0303, + 0x81C, 0xE22C0303, + 0x81C, 0xE12E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xC32A0303, + 0x81C, 0xC22C0303, + 0x81C, 0xC12E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x25520303, + 0x81C, 0x24540303, + 0x81C, 0x23560303, + 0x81C, 0x06580303, + 0x81C, 0x055A0303, + 0x81C, 0x045C0303, + 0x81C, 0x035E0303, + 0x81C, 0x02600303, + 0x81C, 0x01620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000303, + 0x81C, 0xF8020303, + 0x81C, 0xF7040303, + 0x81C, 0xF6060303, + 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, + 0x81C, 0xF30C0303, + 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, + 0x81C, 0xF0120303, + 0x81C, 0xEF140303, + 0x81C, 0xEE160303, + 0x81C, 0xED180303, + 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, + 0x81C, 0xEA1E0303, + 0x81C, 0xE9200303, + 0x81C, 0xE8220303, + 0x81C, 0xE7240303, + 0x81C, 0xE6260303, + 0x81C, 0xE5280303, + 0x81C, 0xE42A0303, + 0x81C, 0xE32C0303, + 0x81C, 0xE22E0303, + 0x81C, 0xE1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x444C0303, + 0x81C, 0x434E0303, + 0x81C, 0x42500303, + 0x81C, 0x25520303, + 0x81C, 0x24540303, + 0x81C, 0x23560303, + 0x81C, 0x07580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xE12C0303, + 0x81C, 0xA72E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xC2360303, + 0x81C, 0xC1380303, + 0x81C, 0xA33A0303, + 0x81C, 0xA23C0303, + 0x81C, 0x853E0303, + 0x81C, 0x84400303, + 0x81C, 0x83420303, + 0x81C, 0x66440303, + 0x81C, 0x65460303, + 0x81C, 0x64480303, + 0x81C, 0x634A0303, + 0x81C, 0x624C0303, + 0x81C, 0x614E0303, + 0x81C, 0x45500303, + 0x81C, 0x44520303, + 0x81C, 0x43540303, + 0x81C, 0x42560303, + 0x81C, 0x25580303, + 0x81C, 0x245A0303, + 0x81C, 0x235C0303, + 0x81C, 0x065E0303, + 0x81C, 0x05600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000303, + 0x81C, 0xF8020303, + 0x81C, 0xF7040303, + 0x81C, 0xF6060303, + 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, + 0x81C, 0xF30C0303, + 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, + 0x81C, 0xF0120303, + 0x81C, 0xEF140303, + 0x81C, 0xEE160303, + 0x81C, 0xED180303, + 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, + 0x81C, 0xEA1E0303, + 0x81C, 0xE9200303, + 0x81C, 0xE8220303, + 0x81C, 0xE7240303, + 0x81C, 0xE6260303, + 0x81C, 0xE5280303, + 0x81C, 0xE42A0303, + 0x81C, 0xE32C0303, + 0x81C, 0xE22E0303, + 0x81C, 0xE1300303, + 0x81C, 0xA6320303, + 0x81C, 0xA5340303, + 0x81C, 0xA4360303, + 0x81C, 0xA3380303, + 0x81C, 0xA23A0303, + 0x81C, 0xA13C0303, + 0x81C, 0x853E0303, + 0x81C, 0x84400303, + 0x81C, 0x83420303, + 0x81C, 0x82440303, + 0x81C, 0x81460303, + 0x81C, 0x64480303, + 0x81C, 0x634A0303, + 0x81C, 0x624C0303, + 0x81C, 0x614E0303, + 0x81C, 0x44500303, + 0x81C, 0x43520303, + 0x81C, 0x42540303, + 0x81C, 0x41560303, + 0x81C, 0x25580303, + 0x81C, 0x245A0303, + 0x81C, 0x235C0303, + 0x81C, 0x055E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000303, + 0x81C, 0xFD020303, + 0x81C, 0xFC040303, + 0x81C, 0xFB060303, + 0x81C, 0xFA080303, + 0x81C, 0xF90A0303, + 0x81C, 0xF80C0303, + 0x81C, 0xF70E0303, + 0x81C, 0xF6100303, + 0x81C, 0xF5120303, + 0x81C, 0xF4140303, + 0x81C, 0xF3160303, + 0x81C, 0xF2180303, + 0x81C, 0xF11A0303, + 0x81C, 0xF01C0303, + 0x81C, 0xEF1E0303, + 0x81C, 0xEE200303, + 0x81C, 0xED220303, + 0x81C, 0xEC240303, + 0x81C, 0xEB260303, + 0x81C, 0xEA280303, + 0x81C, 0xE92A0303, + 0x81C, 0xE82C0303, + 0x81C, 0xE72E0303, + 0x81C, 0xE6300303, + 0x81C, 0xE5320303, + 0x81C, 0xE4340303, + 0x81C, 0xE3360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA43E0303, + 0x81C, 0xA3400303, + 0x81C, 0xA2420303, + 0x81C, 0xA1440303, + 0x81C, 0x85460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x44580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x265E0303, + 0x81C, 0x25600303, + 0x81C, 0x24620303, + 0x81C, 0x06640303, + 0x81C, 0x05660303, + 0x81C, 0x04680303, + 0x81C, 0x036A0303, + 0x81C, 0x026C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xA62C0303, + 0x81C, 0xA52E0303, + 0x81C, 0xA4300303, + 0x81C, 0xA3320303, + 0x81C, 0xA2340303, + 0x81C, 0x87360303, + 0x81C, 0x86380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x66400303, + 0x81C, 0x65420303, + 0x81C, 0x64440303, + 0x81C, 0x45460303, + 0x81C, 0x44480303, + 0x81C, 0x434A0303, + 0x81C, 0x274C0303, + 0x81C, 0x264E0303, + 0x81C, 0x25500303, + 0x81C, 0x24520303, + 0x81C, 0x23540303, + 0x81C, 0x08560303, + 0x81C, 0x07580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000303, + 0x81C, 0xFD020303, + 0x81C, 0xFC040303, + 0x81C, 0xFB060303, + 0x81C, 0xFA080303, + 0x81C, 0xF90A0303, + 0x81C, 0xF80C0303, + 0x81C, 0xF70E0303, + 0x81C, 0xF6100303, + 0x81C, 0xF5120303, + 0x81C, 0xF4140303, + 0x81C, 0xF3160303, + 0x81C, 0xF2180303, + 0x81C, 0xF11A0303, + 0x81C, 0xF01C0303, + 0x81C, 0xEF1E0303, + 0x81C, 0xEE200303, + 0x81C, 0xED220303, + 0x81C, 0xEC240303, + 0x81C, 0xEB260303, + 0x81C, 0xEA280303, + 0x81C, 0xE92A0303, + 0x81C, 0xE82C0303, + 0x81C, 0xE72E0303, + 0x81C, 0xE6300303, + 0x81C, 0xE5320303, + 0x81C, 0xE4340303, + 0x81C, 0xE3360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA43E0303, + 0x81C, 0xA3400303, + 0x81C, 0xA2420303, + 0x81C, 0xA1440303, + 0x81C, 0x85460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x44580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x265E0303, + 0x81C, 0x25600303, + 0x81C, 0x24620303, + 0x81C, 0x06640303, + 0x81C, 0x05660303, + 0x81C, 0x04680303, + 0x81C, 0x036A0303, + 0x81C, 0x026C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xE12C0303, + 0x81C, 0xA72E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xAF1C0303, + 0x81C, 0xAE1E0303, + 0x81C, 0xAD200303, + 0x81C, 0xAC220303, + 0x81C, 0xAB240303, + 0x81C, 0xAA260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x444C0303, + 0x81C, 0x434E0303, + 0x81C, 0x42500303, + 0x81C, 0x41520303, + 0x81C, 0x25540303, + 0x81C, 0x24560303, + 0x81C, 0x06580303, + 0x81C, 0x055A0303, + 0x81C, 0x045C0303, + 0x81C, 0x035E0303, + 0x81C, 0x02600303, + 0x81C, 0x01620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000303, + 0x81C, 0xFC020303, + 0x81C, 0xFB040303, + 0x81C, 0xFA060303, + 0x81C, 0xF9080303, + 0x81C, 0xF80A0303, + 0x81C, 0xF70C0303, + 0x81C, 0xF60E0303, + 0x81C, 0xF5100303, + 0x81C, 0xF4120303, + 0x81C, 0xF3140303, + 0x81C, 0xF2160303, + 0x81C, 0xF1180303, + 0x81C, 0xF01A0303, + 0x81C, 0xEF1C0303, + 0x81C, 0xEE1E0303, + 0x81C, 0xED200303, + 0x81C, 0xEC220303, + 0x81C, 0xEB240303, + 0x81C, 0xEA260303, + 0x81C, 0xE9280303, + 0x81C, 0xE82A0303, + 0x81C, 0xE72C0303, + 0x81C, 0xE62E0303, + 0x81C, 0xE5300303, + 0x81C, 0xE4320303, + 0x81C, 0xE3340303, + 0x81C, 0xE2360303, + 0x81C, 0xE1380303, + 0x81C, 0xA53A0303, + 0x81C, 0xA43C0303, + 0x81C, 0xA33E0303, + 0x81C, 0xA2400303, + 0x81C, 0xA1420303, + 0x81C, 0x87440303, + 0x81C, 0x86460303, + 0x81C, 0x85480303, + 0x81C, 0x844A0303, + 0x81C, 0x834C0303, + 0x81C, 0x824E0303, + 0x81C, 0x81500303, + 0x81C, 0x64520303, + 0x81C, 0x63540303, + 0x81C, 0x62560303, + 0x81C, 0x61580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x415E0303, + 0x81C, 0x07600303, + 0x81C, 0x06620303, + 0x81C, 0x05640303, + 0x81C, 0x04660303, + 0x81C, 0x03680303, + 0x81C, 0x026A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xB0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0x1850, 0x00000022, + 0x1850, 0x00000020, + 0x1A50, 0x00000022, + 0x1A50, 0x00000020, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_agc, rtw_phy_cfg_agc); + +static const u32 rtw8814a_bb[] = { + 0x800, 0x9020D010, + 0x804, 0x08011280, + 0x808, 0x0E0282FF, + 0x80C, 0x1000002F, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x810, 0x33303265, + 0xA0000000, 0x00000000, + 0x810, 0x33303265, + 0xB0000000, 0x00000000, + 0x814, 0x020C3D10, + 0x818, 0x04A10385, + 0x820, 0x00000000, + 0x824, 0x00033E40, + 0x828, 0x00000000, + 0x82C, 0x73985170, + 0x830, 0x79A0EA08, + 0x834, 0x042E708A, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667640, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0xA0000000, 0x00000000, + 0x838, 0x86667640, + 0xB0000000, 0x00000000, + 0x83C, 0x9798B9B9, + 0x840, 0x17578F60, + 0x844, 0x4BBDFCDE, + 0x848, 0x5CD07F8B, + 0x84C, 0x6CFBF7B5, + 0x850, 0x28834706, + 0x854, 0x0001520C, + 0x858, 0x4060C000, + 0x85C, 0x74210368, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x438C2878, + 0x870, 0x44444444, + 0x874, 0x21612C2E, + 0x878, 0x00003152, + 0x87C, 0x000FC000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA202033E, + 0x8AC, 0xF40F550A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0xEC0057FF, + 0x8BC, 0x8CA520C3, + 0x8C0, 0x3FF00020, + 0x8C4, 0x44C00000, + 0x80000009, 0x00000000, 0x40000000, 0x00000000, + 0x8C8, 0x80025969, + 0xA0000000, 0x00000000, + 0x8C8, 0x80025167, + 0xB0000000, 0x00000000, + 0x8CC, 0x08250492, + 0x8D0, 0x0000B800, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8DC, 0x00000000, + 0x8E0, 0x32316407, + 0x8E4, 0x4A092925, + 0x8E8, 0xFFFFC42C, + 0x8EC, 0x99999999, + 0x8F0, 0x00009999, + 0x8F4, 0x00F80FA1, + 0x8F8, 0x400082C0, + 0x8FC, 0x00000000, + 0x900, 0x00400700, + 0x90C, 0x09004000, + 0x910, 0x0000FC00, + 0x914, 0xD6400404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x938, 0x00008400, + 0x93C, 0x932C0642, + 0x940, 0x093E9360, + 0x944, 0x08000000, + 0x948, 0x04000000, + 0x950, 0x02010080, + 0x954, 0x86510080, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x98C, 0x03440000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00080080, + 0x9A8, 0x0C2F0000, + 0x9AC, 0x00560000, + 0x9B0, 0x81081008, + 0x9B4, 0x00000000, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E4, 0x00000002, + 0x9E8, 0x000022D5, + 0x9FC, 0xEFFFF7FF, + 0xB00, 0xE3100000, + 0xB04, 0x0000B000, + 0xB0C, 0x31EAA006, + 0xB5C, 0x41CFFFFF, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000053, + 0xC50, 0x00000020, + 0xC54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0xC58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0xC5C, 0x0D000058, + 0xC60, 0x1B800000, + 0xC60, 0x0B800001, + 0xC60, 0x05800002, + 0xC60, 0x07800003, + 0xC60, 0x1A800004, + 0xC60, 0x0B800005, + 0xC60, 0x05800006, + 0xC60, 0x0E800007, + 0xC60, 0x1A800008, + 0xC60, 0x0B800009, + 0xC60, 0x1580000A, + 0xC60, 0x0880000B, + 0xC60, 0x1A80000C, + 0xC60, 0x0B80000D, + 0xC60, 0x0580000E, + 0xC60, 0x0E80000F, + 0xC60, 0x1A800010, + 0xC60, 0x0B800011, + 0xC60, 0x15800012, + 0xC60, 0x08800013, + 0xC60, 0x1A800014, + 0xC60, 0x0B800015, + 0xC60, 0x05800016, + 0xC60, 0x07800017, + 0xC60, 0x1A800018, + 0xC60, 0x0B800019, + 0xC60, 0x1580001A, + 0xC60, 0x0880001B, + 0xC60, 0x1B80001C, + 0xC60, 0x0B80001D, + 0xC60, 0x0580001E, + 0xC60, 0x0780001F, + 0xC60, 0x1B800020, + 0xC60, 0x0B800021, + 0xC60, 0x05800022, + 0xC60, 0x07800023, + 0xC60, 0x1B800024, + 0xC60, 0x0B800025, + 0xC60, 0x05800026, + 0xC60, 0x07800027, + 0xC60, 0x1B800028, + 0xC60, 0x0B800029, + 0xC60, 0x0580002A, + 0xC60, 0x0780002B, + 0xC60, 0x1B800030, + 0xC60, 0x0B800031, + 0xC60, 0x05800032, + 0xC60, 0x00800033, + 0xC60, 0x1B800034, + 0xC60, 0x0B800035, + 0xC60, 0x05800036, + 0xC60, 0x00800037, + 0xC60, 0x1B800038, + 0xC60, 0x0B800039, + 0xC60, 0x0580003A, + 0xC60, 0x0E80803B, + 0xC94, 0x01000401, + 0xC98, 0x00188000, + 0xCA0, 0x00002929, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCAC, 0x77777000, + 0xCB0, 0x54775477, + 0xCB4, 0x54775477, + 0xCB8, 0x00500000, + 0xCBC, 0x77700000, + 0xCC0, 0x00000010, + 0xCC8, 0x00000010, + 0xE00, 0x00000007, + 0xE04, 0x00042020, + 0xE08, 0x80410231, + 0xE0C, 0x00000000, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE1C, 0x40000053, + 0xE50, 0x00000020, + 0xE54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0xE58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0xE5C, 0x0D000058, + 0xE60, 0x1B800000, + 0xE60, 0x0B800001, + 0xE60, 0x05800002, + 0xE60, 0x07800003, + 0xE60, 0x1A800004, + 0xE60, 0x0B800005, + 0xE60, 0x05800006, + 0xE60, 0x0E800007, + 0xE60, 0x1A800008, + 0xE60, 0x0B800009, + 0xE60, 0x1580000A, + 0xE60, 0x0880000B, + 0xE60, 0x1A80000C, + 0xE60, 0x0B80000D, + 0xE60, 0x0580000E, + 0xE60, 0x0E80000F, + 0xE60, 0x1A800010, + 0xE60, 0x0B800011, + 0xE60, 0x15800012, + 0xE60, 0x08800013, + 0xE60, 0x1A800014, + 0xE60, 0x0B800015, + 0xE60, 0x05800016, + 0xE60, 0x07800017, + 0xE60, 0x1A800018, + 0xE60, 0x0B800019, + 0xE60, 0x1580001A, + 0xE60, 0x0880001B, + 0xE60, 0x1B80001C, + 0xE60, 0x0B80001D, + 0xE60, 0x0580001E, + 0xE60, 0x0780001F, + 0xE60, 0x1B800020, + 0xE60, 0x0B800021, + 0xE60, 0x05800022, + 0xE60, 0x07800023, + 0xE60, 0x1B800024, + 0xE60, 0x0B800025, + 0xE60, 0x05800026, + 0xE60, 0x07800027, + 0xE60, 0x1B800028, + 0xE60, 0x0B800029, + 0xE60, 0x0580002A, + 0xE60, 0x0780002B, + 0xE60, 0x1B800030, + 0xE60, 0x0B800031, + 0xE60, 0x05800032, + 0xE60, 0x00800033, + 0xE60, 0x1B800034, + 0xE60, 0x0B800035, + 0xE60, 0x05800036, + 0xE60, 0x00800037, + 0xE60, 0x1B800038, + 0xE60, 0x0B800039, + 0xE60, 0x0580003A, + 0xE60, 0x0E80803B, + 0xE94, 0x01000401, + 0xE98, 0x00188000, + 0xEA0, 0x00002929, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEAC, 0x77777000, + 0xEB0, 0x54775477, + 0xEB4, 0x54775477, + 0xEB8, 0x00500000, + 0xEBC, 0x77700000, + 0x1800, 0x00000007, + 0x1804, 0x00042020, + 0x1808, 0x80410231, + 0x180C, 0x00000000, + 0x1810, 0x00000100, + 0x1814, 0x01000000, + 0x181C, 0x40000053, + 0x1850, 0x00000020, + 0x1854, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0x1858, 0x3C020C14, + 0xB0000000, 0x00000000, + 0x185C, 0x0D000058, + 0x1860, 0x1B800000, + 0x1860, 0x0B800001, + 0x1860, 0x05800002, + 0x1860, 0x07800003, + 0x1860, 0x1A800004, + 0x1860, 0x0B800005, + 0x1860, 0x05800006, + 0x1860, 0x0E800007, + 0x1860, 0x1A800008, + 0x1860, 0x0B800009, + 0x1860, 0x1580000A, + 0x1860, 0x0880000B, + 0x1860, 0x1A80000C, + 0x1860, 0x0B80000D, + 0x1860, 0x0580000E, + 0x1860, 0x0E80000F, + 0x1860, 0x1A800010, + 0x1860, 0x0B800011, + 0x1860, 0x15800012, + 0x1860, 0x08800013, + 0x1860, 0x1A800014, + 0x1860, 0x0B800015, + 0x1860, 0x05800016, + 0x1860, 0x07800017, + 0x1860, 0x1A800018, + 0x1860, 0x0B800019, + 0x1860, 0x1580001A, + 0x1860, 0x0880001B, + 0x1860, 0x1B80001C, + 0x1860, 0x0B80001D, + 0x1860, 0x0580001E, + 0x1860, 0x0780001F, + 0x1860, 0x1B800020, + 0x1860, 0x0B800021, + 0x1860, 0x05800022, + 0x1860, 0x07800023, + 0x1860, 0x1B800024, + 0x1860, 0x0B800025, + 0x1860, 0x05800026, + 0x1860, 0x07800027, + 0x1860, 0x1B800028, + 0x1860, 0x0B800029, + 0x1860, 0x0580002A, + 0x1860, 0x0780002B, + 0x1860, 0x1B800030, + 0x1860, 0x0B800031, + 0x1860, 0x05800032, + 0x1860, 0x00800033, + 0x1860, 0x1B800034, + 0x1860, 0x0B800035, + 0x1860, 0x05800036, + 0x1860, 0x00800037, + 0x1860, 0x1B800038, + 0x1860, 0x0B800039, + 0x1860, 0x0580003A, + 0x1860, 0x0E80803B, + 0x1894, 0x01000401, + 0x1898, 0x00188000, + 0x18A0, 0x00002929, + 0x18A4, 0x08040201, + 0x18A8, 0x80402010, + 0x18AC, 0x77777000, + 0x18B0, 0x54775477, + 0x18B4, 0x54775477, + 0x18B8, 0x00500000, + 0x18BC, 0x77700000, + 0x1A00, 0x00000007, + 0x1A04, 0x00042020, + 0x1A08, 0x80410231, + 0x1A0C, 0x00000000, + 0x1A10, 0x00000100, + 0x1A14, 0x01000000, + 0x1A1C, 0x40000053, + 0x1A50, 0x00000020, + 0x1A54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0x1A58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0x1A5C, 0x0D000058, + 0x1A60, 0x1B800000, + 0x1A60, 0x0B800001, + 0x1A60, 0x05800002, + 0x1A60, 0x07800003, + 0x1A60, 0x1A800004, + 0x1A60, 0x0B800005, + 0x1A60, 0x05800006, + 0x1A60, 0x0E800007, + 0x1A60, 0x1A800008, + 0x1A60, 0x0B800009, + 0x1A60, 0x1580000A, + 0x1A60, 0x0880000B, + 0x1A60, 0x1A80000C, + 0x1A60, 0x0B80000D, + 0x1A60, 0x0580000E, + 0x1A60, 0x0E80000F, + 0x1A60, 0x1A800010, + 0x1A60, 0x0B800011, + 0x1A60, 0x15800012, + 0x1A60, 0x08800013, + 0x1A60, 0x1A800014, + 0x1A60, 0x0B800015, + 0x1A60, 0x05800016, + 0x1A60, 0x07800017, + 0x1A60, 0x1A800018, + 0x1A60, 0x0B800019, + 0x1A60, 0x1580001A, + 0x1A60, 0x0880001B, + 0x1A60, 0x1B80001C, + 0x1A60, 0x0B80001D, + 0x1A60, 0x0580001E, + 0x1A60, 0x0780001F, + 0x1A60, 0x1B800020, + 0x1A60, 0x0B800021, + 0x1A60, 0x05800022, + 0x1A60, 0x07800023, + 0x1A60, 0x1B800024, + 0x1A60, 0x0B800025, + 0x1A60, 0x05800026, + 0x1A60, 0x07800027, + 0x1A60, 0x1B800028, + 0x1A60, 0x0B800029, + 0x1A60, 0x0580002A, + 0x1A60, 0x0780002B, + 0x1A60, 0x1B800030, + 0x1A60, 0x0B800031, + 0x1A60, 0x05800032, + 0x1A60, 0x00800033, + 0x1A60, 0x1B800034, + 0x1A60, 0x0B800035, + 0x1A60, 0x05800036, + 0x1A60, 0x00800037, + 0x1A60, 0x1B800038, + 0x1A60, 0x0B800039, + 0x1A60, 0x0580003A, + 0x1A60, 0x0E80803B, + 0x1A94, 0x01000401, + 0x1A98, 0x00188000, + 0x1AA0, 0x00002929, + 0x1AA4, 0x08040201, + 0x1AA8, 0x80402010, + 0x1AAC, 0x77777000, + 0x1AB0, 0x54775477, + 0x1AB4, 0x54775477, + 0x1AB8, 0x00500000, + 0x1ABC, 0x77700000, + 0x1904, 0x00030000, + 0x1914, 0x00030000, + 0x1984, 0x03000000, + 0x1988, 0x00000087, + 0x198C, 0x00000007, + 0x1990, 0xFFAA5500, + 0x1994, 0x00000077, + 0x1998, 0x12801000, + 0x1998, 0x12801000, + 0x1998, 0x12801001, + 0x1998, 0x12801002, + 0x1998, 0x12801003, + 0x1998, 0x12801004, + 0x1998, 0x12801005, + 0x1998, 0x12801006, + 0x1998, 0x12801007, + 0x1998, 0x12801008, + 0x1998, 0x12801009, + 0x1998, 0x1280100A, + 0x1998, 0x1280100B, + 0x1998, 0x1280100C, + 0x1998, 0x1280100D, + 0x1998, 0x1280100E, + 0x1998, 0x1280100F, + 0x1998, 0x12801010, + 0x1998, 0x12801011, + 0x1998, 0x12801012, + 0x1998, 0x12801013, + 0x1998, 0x12801014, + 0x1998, 0x12801015, + 0x1998, 0x12801016, + 0x1998, 0x12801017, + 0x1998, 0x12801018, + 0x1998, 0x12801019, + 0x1998, 0x1280101A, + 0x1998, 0x1280101B, + 0x1998, 0x1280101C, + 0x1998, 0x1280101D, + 0x1998, 0x1280101E, + 0x1998, 0x1280101F, + 0x1998, 0x12801020, + 0x1998, 0x12801021, + 0x1998, 0x12801022, + 0x1998, 0x12801023, + 0x1998, 0x1280102C, + 0x1998, 0x1280102D, + 0x1998, 0x1280102E, + 0x1998, 0x1280102F, + 0x1998, 0x12801030, + 0x1998, 0x12801031, + 0x1998, 0x12801032, + 0x1998, 0x12801033, + 0x1998, 0x12801034, + 0x1998, 0x12801035, + 0x1998, 0x12801036, + 0x1998, 0x12801037, + 0x1998, 0x12801038, + 0x1998, 0x12801039, + 0x1998, 0x1280103A, + 0x1998, 0x1280103B, + 0x1998, 0x1280103C, + 0x1998, 0x1280103D, + 0x1998, 0x1280103E, + 0x1998, 0x1280103F, + 0x1998, 0x12801040, + 0x1998, 0x12801041, + 0x1998, 0x12801042, + 0x1998, 0x12801043, + 0x1998, 0x12801044, + 0x1998, 0x12801045, + 0x1998, 0x12801046, + 0x1998, 0x12801047, + 0x1998, 0x12801048, + 0x1998, 0x12801049, + 0x1998, 0x12801100, + 0x1998, 0x12801101, + 0x1998, 0x12801102, + 0x1998, 0x12801103, + 0x1998, 0x12801104, + 0x1998, 0x12801105, + 0x1998, 0x12801106, + 0x1998, 0x12801107, + 0x1998, 0x12801108, + 0x1998, 0x12801109, + 0x1998, 0x1280110A, + 0x1998, 0x1280110B, + 0x1998, 0x1280110C, + 0x1998, 0x1280110D, + 0x1998, 0x1280110E, + 0x1998, 0x1280110F, + 0x1998, 0x12801110, + 0x1998, 0x12801111, + 0x1998, 0x12801112, + 0x1998, 0x12801113, + 0x1998, 0x12801114, + 0x1998, 0x12801115, + 0x1998, 0x12801116, + 0x1998, 0x12801117, + 0x1998, 0x12801118, + 0x1998, 0x12801119, + 0x1998, 0x1280111A, + 0x1998, 0x1280111B, + 0x1998, 0x1280111C, + 0x1998, 0x1280111D, + 0x1998, 0x1280111E, + 0x1998, 0x1280111F, + 0x1998, 0x12801120, + 0x1998, 0x12801121, + 0x1998, 0x12801122, + 0x1998, 0x12801123, + 0x1998, 0x1280112C, + 0x1998, 0x1280112D, + 0x1998, 0x1280112E, + 0x1998, 0x1280112F, + 0x1998, 0x12801130, + 0x1998, 0x12801131, + 0x1998, 0x12801132, + 0x1998, 0x12801133, + 0x1998, 0x12801134, + 0x1998, 0x12801135, + 0x1998, 0x12801136, + 0x1998, 0x12801137, + 0x1998, 0x12801138, + 0x1998, 0x12801139, + 0x1998, 0x1280113A, + 0x1998, 0x1280113B, + 0x1998, 0x1280113C, + 0x1998, 0x1280113D, + 0x1998, 0x1280113E, + 0x1998, 0x1280113F, + 0x1998, 0x12801140, + 0x1998, 0x12801141, + 0x1998, 0x12801142, + 0x1998, 0x12801143, + 0x1998, 0x12801144, + 0x1998, 0x12801145, + 0x1998, 0x12801146, + 0x1998, 0x12801147, + 0x1998, 0x12801148, + 0x1998, 0x12801149, + 0x1998, 0x12801200, + 0x1998, 0x12801201, + 0x1998, 0x12801202, + 0x1998, 0x12801203, + 0x1998, 0x12801204, + 0x1998, 0x12801205, + 0x1998, 0x12801206, + 0x1998, 0x12801207, + 0x1998, 0x12801208, + 0x1998, 0x12801209, + 0x1998, 0x1280120A, + 0x1998, 0x1280120B, + 0x1998, 0x1280120C, + 0x1998, 0x1280120D, + 0x1998, 0x1280120E, + 0x1998, 0x1280120F, + 0x1998, 0x12801210, + 0x1998, 0x12801211, + 0x1998, 0x12801212, + 0x1998, 0x12801213, + 0x1998, 0x12801214, + 0x1998, 0x12801215, + 0x1998, 0x12801216, + 0x1998, 0x12801217, + 0x1998, 0x12801218, + 0x1998, 0x12801219, + 0x1998, 0x1280121A, + 0x1998, 0x1280121B, + 0x1998, 0x1280121C, + 0x1998, 0x1280121D, + 0x1998, 0x1280121E, + 0x1998, 0x1280121F, + 0x1998, 0x12801220, + 0x1998, 0x12801221, + 0x1998, 0x12801222, + 0x1998, 0x12801223, + 0x1998, 0x1280122C, + 0x1998, 0x1280122D, + 0x1998, 0x1280122E, + 0x1998, 0x1280122F, + 0x1998, 0x12801230, + 0x1998, 0x12801231, + 0x1998, 0x12801232, + 0x1998, 0x12801233, + 0x1998, 0x12801234, + 0x1998, 0x12801235, + 0x1998, 0x12801236, + 0x1998, 0x12801237, + 0x1998, 0x12801238, + 0x1998, 0x12801239, + 0x1998, 0x1280123A, + 0x1998, 0x1280123B, + 0x1998, 0x1280123C, + 0x1998, 0x1280123D, + 0x1998, 0x1280123E, + 0x1998, 0x1280123F, + 0x1998, 0x12801240, + 0x1998, 0x12801241, + 0x1998, 0x12801242, + 0x1998, 0x12801243, + 0x1998, 0x12801244, + 0x1998, 0x12801245, + 0x1998, 0x12801246, + 0x1998, 0x12801247, + 0x1998, 0x12801248, + 0x1998, 0x12801249, + 0x1998, 0x12801300, + 0x1998, 0x12801301, + 0x1998, 0x12801302, + 0x1998, 0x12801303, + 0x1998, 0x12801304, + 0x1998, 0x12801305, + 0x1998, 0x12801306, + 0x1998, 0x12801307, + 0x1998, 0x12801308, + 0x1998, 0x12801309, + 0x1998, 0x1280130A, + 0x1998, 0x1280130B, + 0x1998, 0x1280130C, + 0x1998, 0x1280130D, + 0x1998, 0x1280130E, + 0x1998, 0x1280130F, + 0x1998, 0x12801310, + 0x1998, 0x12801311, + 0x1998, 0x12801312, + 0x1998, 0x12801313, + 0x1998, 0x12801314, + 0x1998, 0x12801315, + 0x1998, 0x12801316, + 0x1998, 0x12801317, + 0x1998, 0x12801318, + 0x1998, 0x12801319, + 0x1998, 0x1280131A, + 0x1998, 0x1280131B, + 0x1998, 0x1280131C, + 0x1998, 0x1280131D, + 0x1998, 0x1280131E, + 0x1998, 0x1280131F, + 0x1998, 0x12801320, + 0x1998, 0x12801321, + 0x1998, 0x12801322, + 0x1998, 0x12801323, + 0x1998, 0x1280132C, + 0x1998, 0x1280132D, + 0x1998, 0x1280132E, + 0x1998, 0x1280132F, + 0x1998, 0x12801330, + 0x1998, 0x12801331, + 0x1998, 0x12801332, + 0x1998, 0x12801333, + 0x1998, 0x12801334, + 0x1998, 0x12801335, + 0x1998, 0x12801336, + 0x1998, 0x12801337, + 0x1998, 0x12801338, + 0x1998, 0x12801339, + 0x1998, 0x1280133A, + 0x1998, 0x1280133B, + 0x1998, 0x1280133C, + 0x1998, 0x1280133D, + 0x1998, 0x1280133E, + 0x1998, 0x1280133F, + 0x1998, 0x12801340, + 0x1998, 0x12801341, + 0x1998, 0x12801342, + 0x1998, 0x12801343, + 0x1998, 0x12801344, + 0x1998, 0x12801345, + 0x1998, 0x12801346, + 0x1998, 0x12801347, + 0x1998, 0x12801348, + 0x1998, 0x12801349, + 0x19D4, 0x88888888, + 0x19D8, 0x00000888, + 0xB00, 0xE3100100, + 0xB00, 0xE7100100, + 0xC60, 0x15808002, + 0xC60, 0x01808003, + 0xE60, 0x15808002, + 0xE60, 0x01808003, + 0x1860, 0x15808002, + 0x1860, 0x01808003, + 0x1A60, 0x15808002, + 0x1A60, 0x01808003, + 0xB00, 0xE3100100, + 0xC5C, 0x0D080058, + 0xE5C, 0x0D080058, + 0x185C, 0x0D080058, + 0x1A5C, 0x0D080058, + 0xC5C, 0x0D000058, + 0xE5C, 0x0D000058, + 0x185C, 0x0D000058, + 0x1A5C, 0x0D000058, + 0xC60, 0x05808002, + 0xC60, 0x0E808003, + 0xE60, 0x05808002, + 0xE60, 0x0E808003, + 0x1860, 0x05808002, + 0x1860, 0x0E808003, + 0x1A60, 0x05808002, + 0x1A60, 0x0E808003, + 0xB00, 0xE7100100, + 0xB00, 0xE3100100, + 0xB00, 0xE3100000, + 0x1C38, 0x00000002, + 0xA00, 0x00D047C8, + 0xA04, 0x46FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7E000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0030, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000128, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B2, + 0xA84, 0x9C1F8C00, + 0x1B04, 0xE24628D2, + 0x1B10, 0x88010D46, + 0x1B14, 0x00000000, + 0x1B18, 0x00292903, + 0x1B00, 0xF8000000, + 0x1B00, 0xF800D000, + 0x1B00, 0xF801F000, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000002, + 0x1B00, 0xF800D002, + 0x1B00, 0xF801F002, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000004, + 0x1B00, 0xF800D004, + 0x1B00, 0xF801F004, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000006, + 0x1B00, 0xF800D006, + 0x1B00, 0xF801F006, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000000, + 0x1B80, 0x00000007, + 0x1B80, 0x09060005, + 0x1B80, 0x09060007, + 0x1B80, 0x0FFE0015, + 0x1B80, 0x0FFE0017, + 0x1B80, 0x00240025, + 0x1B80, 0x00240027, + 0x1B80, 0x00040035, + 0x1B80, 0x00040037, + 0x1B80, 0x05C00045, + 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, + 0x1B80, 0x00070057, + 0x1B80, 0x64000065, + 0x1B80, 0x64000067, + 0x1B80, 0x00020075, + 0x1B80, 0x00020077, + 0x1B80, 0x00080085, + 0x1B80, 0x00080087, + 0x1B80, 0x80000095, + 0x1B80, 0x80000097, + 0x1B80, 0x090100A5, + 0x1B80, 0x090100A7, + 0x1B80, 0x0F0200B5, + 0x1B80, 0x0F0200B7, + 0x1B80, 0x002400C5, + 0x1B80, 0x002400C7, + 0x1B80, 0x000400D5, + 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, + 0x1B80, 0x05C000E7, + 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, + 0x1B80, 0x64020105, + 0x1B80, 0x64020107, + 0x1B80, 0x00020115, + 0x1B80, 0x00020117, + 0x1B80, 0x00040125, + 0x1B80, 0x00040127, + 0x1B80, 0x4A000135, + 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, + 0x1B80, 0x4B040147, + 0x1B80, 0x85030155, + 0x1B80, 0x85030157, + 0x1B80, 0x40010165, + 0x1B80, 0x40010167, + 0x1B80, 0xE0290175, + 0x1B80, 0xE0290177, + 0x1B80, 0x00040185, + 0x1B80, 0x00040187, + 0x1B80, 0x4B050195, + 0x1B80, 0x4B050197, + 0x1B80, 0x860301A5, + 0x1B80, 0x860301A7, + 0x1B80, 0x400301B5, + 0x1B80, 0x400301B7, + 0x1B80, 0xE02901C5, + 0x1B80, 0xE02901C7, + 0x1B80, 0x000401D5, + 0x1B80, 0x000401D7, + 0x1B80, 0x4B0601E5, + 0x1B80, 0x4B0601E7, + 0x1B80, 0x870301F5, + 0x1B80, 0x870301F7, + 0x1B80, 0x40050205, + 0x1B80, 0x40050207, + 0x1B80, 0xE0290215, + 0x1B80, 0xE0290217, + 0x1B80, 0x00040225, + 0x1B80, 0x00040227, + 0x1B80, 0x4B070235, + 0x1B80, 0x4B070237, + 0x1B80, 0x88030245, + 0x1B80, 0x88030247, + 0x1B80, 0x40070255, + 0x1B80, 0x40070257, + 0x1B80, 0xE0290265, + 0x1B80, 0xE0290267, + 0x1B80, 0x4B000275, + 0x1B80, 0x4B000277, + 0x1B80, 0x30000285, + 0x1B80, 0x30000287, + 0x1B80, 0xFE100295, + 0x1B80, 0xFE100297, + 0x1B80, 0xFF1002A5, + 0x1B80, 0xFF1002A7, + 0x1B80, 0xE18602B5, + 0x1B80, 0xE18602B7, + 0x1B80, 0xF00A02C5, + 0x1B80, 0xF00A02C7, + 0x1B80, 0xF10A02D5, + 0x1B80, 0xF10A02D7, + 0x1B80, 0xF20A02E5, + 0x1B80, 0xF20A02E7, + 0x1B80, 0xF30802F5, + 0x1B80, 0xF30802F7, + 0x1B80, 0xF4070305, + 0x1B80, 0xF4070307, + 0x1B80, 0xF5060315, + 0x1B80, 0xF5060317, + 0x1B80, 0xF7060325, + 0x1B80, 0xF7060327, + 0x1B80, 0xF8050335, + 0x1B80, 0xF8050337, + 0x1B80, 0xF9040345, + 0x1B80, 0xF9040347, + 0x1B80, 0x00010355, + 0x1B80, 0x00010357, + 0x1B80, 0x303B0365, + 0x1B80, 0x303B0367, + 0x1B80, 0x30500375, + 0x1B80, 0x30500377, + 0x1B80, 0x305C0385, + 0x1B80, 0x305C0387, + 0x1B80, 0x31D50395, + 0x1B80, 0x31D50397, + 0x1B80, 0x31C503A5, + 0x1B80, 0x31C503A7, + 0x1B80, 0x4D0403B5, + 0x1B80, 0x4D0403B7, + 0x1B80, 0x2EF003C5, + 0x1B80, 0x2EF003C7, + 0x1B80, 0x000203D5, + 0x1B80, 0x000203D7, + 0x1B80, 0x208003E5, + 0x1B80, 0x208003E7, + 0x1B80, 0x000003F5, + 0x1B80, 0x000003F7, + 0x1B80, 0x4D000405, + 0x1B80, 0x4D000407, + 0x1B80, 0x55070415, + 0x1B80, 0x55070417, + 0x1B80, 0xE1230425, + 0x1B80, 0xE1230427, + 0x1B80, 0xE1230435, + 0x1B80, 0xE1230437, + 0x1B80, 0x4D040445, + 0x1B80, 0x4D040447, + 0x1B80, 0x20800455, + 0x1B80, 0x20800457, + 0x1B80, 0x84000465, + 0x1B80, 0x84000467, + 0x1B80, 0x4D000475, + 0x1B80, 0x4D000477, + 0x1B80, 0x550F0485, + 0x1B80, 0x550F0487, + 0x1B80, 0xE1230495, + 0x1B80, 0xE1230497, + 0x1B80, 0x4F0204A5, + 0x1B80, 0x4F0204A7, + 0x1B80, 0x4E0004B5, + 0x1B80, 0x4E0004B7, + 0x1B80, 0x530204C5, + 0x1B80, 0x530204C7, + 0x1B80, 0x520104D5, + 0x1B80, 0x520104D7, + 0x1B80, 0xE12704E5, + 0x1B80, 0xE12704E7, + 0x1B80, 0x000104F5, + 0x1B80, 0x000104F7, + 0x1B80, 0x5C720505, + 0x1B80, 0x5C720507, + 0x1B80, 0xE1320515, + 0x1B80, 0xE1320517, + 0x1B80, 0x54E50525, + 0x1B80, 0x54E50527, + 0x1B80, 0x54BF0535, + 0x1B80, 0x54BF0537, + 0x1B80, 0x54C50545, + 0x1B80, 0x54C50547, + 0x1B80, 0x54BE0555, + 0x1B80, 0x54BE0557, + 0x1B80, 0x54DF0565, + 0x1B80, 0x54DF0567, + 0x1B80, 0x0BA60575, + 0x1B80, 0x0BA60577, + 0x1B80, 0xF3130585, + 0x1B80, 0xF3130587, + 0x1B80, 0xF41E0595, + 0x1B80, 0xF41E0597, + 0x1B80, 0xF53C05A5, + 0x1B80, 0xF53C05A7, + 0x1B80, 0x000105B5, + 0x1B80, 0x000105B7, + 0x1B80, 0x620605C5, + 0x1B80, 0x620605C7, + 0x1B80, 0x600605D5, + 0x1B80, 0x600605D7, + 0x1B80, 0xE1A905E5, + 0x1B80, 0xE1A905E7, + 0x1B80, 0x0C0005F5, + 0x1B80, 0x0C0005F7, + 0x1B80, 0x5C720605, + 0x1B80, 0x5C720607, + 0x1B80, 0xE1320615, + 0x1B80, 0xE1320617, + 0x1B80, 0x5CF10625, + 0x1B80, 0x5CF10627, + 0x1B80, 0x0C010635, + 0x1B80, 0x0C010637, + 0x1B80, 0xF2020645, + 0x1B80, 0xF2020647, + 0x1B80, 0x30D60655, + 0x1B80, 0x30D60657, + 0x1B80, 0x0AC60665, + 0x1B80, 0x0AC60667, + 0x1B80, 0xE1B60675, + 0x1B80, 0xE1B60677, + 0x1B80, 0xE1580685, + 0x1B80, 0xE1580687, + 0x1B80, 0x54E50695, + 0x1B80, 0x54E50697, + 0x1B80, 0x000106A5, + 0x1B80, 0x000106A7, + 0x1B80, 0x560106B5, + 0x1B80, 0x560106B7, + 0x1B80, 0x5CE206C5, + 0x1B80, 0x5CE206C7, + 0x1B80, 0x0AE106D5, + 0x1B80, 0x0AE106D7, + 0x1B80, 0x630C06E5, + 0x1B80, 0x630C06E7, + 0x1B80, 0xE13F06F5, + 0x1B80, 0xE13F06F7, + 0x1B80, 0x00270705, + 0x1B80, 0x00270707, + 0x1B80, 0xE16C0715, + 0x1B80, 0xE16C0717, + 0x1B80, 0x00020725, + 0x1B80, 0x00020727, + 0x1B80, 0x002A0735, + 0x1B80, 0x002A0737, + 0x1B80, 0x07140745, + 0x1B80, 0x07140747, + 0x1B80, 0x00020755, + 0x1B80, 0x00020757, + 0x1B80, 0x30C30765, + 0x1B80, 0x30C30767, + 0x1B80, 0x56010775, + 0x1B80, 0x56010777, + 0x1B80, 0x5CE20785, + 0x1B80, 0x5CE20787, + 0x1B80, 0x0AE10795, + 0x1B80, 0x0AE10797, + 0x1B80, 0x631707A5, + 0x1B80, 0x631707A7, + 0x1B80, 0xE13F07B5, + 0x1B80, 0xE13F07B7, + 0x1B80, 0x002507C5, + 0x1B80, 0x002507C7, + 0x1B80, 0xE16C07D5, + 0x1B80, 0xE16C07D7, + 0x1B80, 0x000207E5, + 0x1B80, 0x000207E7, + 0x1B80, 0x630F07F5, + 0x1B80, 0x630F07F7, + 0x1B80, 0xE13F0805, + 0x1B80, 0xE13F0807, + 0x1B80, 0x63070815, + 0x1B80, 0x63070817, + 0x1B80, 0xE13F0825, + 0x1B80, 0xE13F0827, + 0x1B80, 0x07140835, + 0x1B80, 0x07140837, + 0x1B80, 0x56000845, + 0x1B80, 0x56000847, + 0x1B80, 0x5CF20855, + 0x1B80, 0x5CF20857, + 0x1B80, 0x0AF10865, + 0x1B80, 0x0AF10867, + 0x1B80, 0x07140875, + 0x1B80, 0x07140877, + 0x1B80, 0x07140885, + 0x1B80, 0x07140887, + 0x1B80, 0x630F0895, + 0x1B80, 0x630F0897, + 0x1B80, 0xE13F08A5, + 0x1B80, 0xE13F08A7, + 0x1B80, 0x631708B5, + 0x1B80, 0x631708B7, + 0x1B80, 0xE13F08C5, + 0x1B80, 0xE13F08C7, + 0x1B80, 0x002508D5, + 0x1B80, 0x002508D7, + 0x1B80, 0xE16C08E5, + 0x1B80, 0xE16C08E7, + 0x1B80, 0x000208F5, + 0x1B80, 0x000208F7, + 0x1B80, 0x30C30905, + 0x1B80, 0x30C30907, + 0x1B80, 0xE1A90915, + 0x1B80, 0xE1A90917, + 0x1B80, 0x62060925, + 0x1B80, 0x62060927, + 0x1B80, 0x60060935, + 0x1B80, 0x60060937, + 0x1B80, 0xE1160945, + 0x1B80, 0xE1160947, + 0x1B80, 0x54BE0955, + 0x1B80, 0x54BE0957, + 0x1B80, 0x56010965, + 0x1B80, 0x56010967, + 0x1B80, 0x5CE20975, + 0x1B80, 0x5CE20977, + 0x1B80, 0x0AE10985, + 0x1B80, 0x0AE10987, + 0x1B80, 0x633A0995, + 0x1B80, 0x633A0997, + 0x1B80, 0xE13F09A5, + 0x1B80, 0xE13F09A7, + 0x1B80, 0x633709B5, + 0x1B80, 0x633709B7, + 0x1B80, 0xE13F09C5, + 0x1B80, 0xE13F09C7, + 0x1B80, 0x632F09D5, + 0x1B80, 0x632F09D7, + 0x1B80, 0xE13F09E5, + 0x1B80, 0xE13F09E7, + 0x1B80, 0x632709F5, + 0x1B80, 0x632709F7, + 0x1B80, 0xE13F0A05, + 0x1B80, 0xE13F0A07, + 0x1B80, 0x631F0A15, + 0x1B80, 0x631F0A17, + 0x1B80, 0xE13F0A25, + 0x1B80, 0xE13F0A27, + 0x1B80, 0x63170A35, + 0x1B80, 0x63170A37, + 0x1B80, 0xE13F0A45, + 0x1B80, 0xE13F0A47, + 0x1B80, 0x630F0A55, + 0x1B80, 0x630F0A57, + 0x1B80, 0xE13F0A65, + 0x1B80, 0xE13F0A67, + 0x1B80, 0x63070A75, + 0x1B80, 0x63070A77, + 0x1B80, 0xE13F0A85, + 0x1B80, 0xE13F0A87, + 0x1B80, 0xE16C0A95, + 0x1B80, 0xE16C0A97, + 0x1B80, 0x56000AA5, + 0x1B80, 0x56000AA7, + 0x1B80, 0x5CF20AB5, + 0x1B80, 0x5CF20AB7, + 0x1B80, 0x0AF10AC5, + 0x1B80, 0x0AF10AC7, + 0x1B80, 0xF5040AD5, + 0x1B80, 0xF5040AD7, + 0x1B80, 0xE13F0AE5, + 0x1B80, 0xE13F0AE7, + 0x1B80, 0xE16C0AF5, + 0x1B80, 0xE16C0AF7, + 0x1B80, 0x30B30B05, + 0x1B80, 0x30B30B07, + 0x1B80, 0x07140B15, + 0x1B80, 0x07140B17, + 0x1B80, 0x07140B25, + 0x1B80, 0x07140B27, + 0x1B80, 0x630F0B35, + 0x1B80, 0x630F0B37, + 0x1B80, 0xE13F0B45, + 0x1B80, 0xE13F0B47, + 0x1B80, 0x63170B55, + 0x1B80, 0x63170B57, + 0x1B80, 0xE13F0B65, + 0x1B80, 0xE13F0B67, + 0x1B80, 0x631F0B75, + 0x1B80, 0x631F0B77, + 0x1B80, 0xE13F0B85, + 0x1B80, 0xE13F0B87, + 0x1B80, 0x63270B95, + 0x1B80, 0x63270B97, + 0x1B80, 0xE13F0BA5, + 0x1B80, 0xE13F0BA7, + 0x1B80, 0x632F0BB5, + 0x1B80, 0x632F0BB7, + 0x1B80, 0xE13F0BC5, + 0x1B80, 0xE13F0BC7, + 0x1B80, 0x63370BD5, + 0x1B80, 0x63370BD7, + 0x1B80, 0xE13F0BE5, + 0x1B80, 0xE13F0BE7, + 0x1B80, 0x633A0BF5, + 0x1B80, 0x633A0BF7, + 0x1B80, 0xE13F0C05, + 0x1B80, 0xE13F0C07, + 0x1B80, 0xF60B0C15, + 0x1B80, 0xF60B0C17, + 0x1B80, 0xF7170C25, + 0x1B80, 0xF7170C27, + 0x1B80, 0x4D300C35, + 0x1B80, 0x4D300C37, + 0x1B80, 0x57040C45, + 0x1B80, 0x57040C47, + 0x1B80, 0x57000C55, + 0x1B80, 0x57000C57, + 0x1B80, 0x96000C65, + 0x1B80, 0x96000C67, + 0x1B80, 0x57080C75, + 0x1B80, 0x57080C77, + 0x1B80, 0x57000C85, + 0x1B80, 0x57000C87, + 0x1B80, 0x95000C95, + 0x1B80, 0x95000C97, + 0x1B80, 0x4D000CA5, + 0x1B80, 0x4D000CA7, + 0x1B80, 0x6C070CB5, + 0x1B80, 0x6C070CB7, + 0x1B80, 0x00010CC5, + 0x1B80, 0x00010CC7, + 0x1B80, 0x00220CD5, + 0x1B80, 0x00220CD7, + 0x1B80, 0x06140CE5, + 0x1B80, 0x06140CE7, + 0x1B80, 0xE16C0CF5, + 0x1B80, 0xE16C0CF7, + 0x1B80, 0x00020D05, + 0x1B80, 0x00020D07, + 0x1B80, 0x00250D15, + 0x1B80, 0x00250D17, + 0x1B80, 0x06140D25, + 0x1B80, 0x06140D27, + 0x1B80, 0xE16C0D35, + 0x1B80, 0xE16C0D37, + 0x1B80, 0x00020D45, + 0x1B80, 0x00020D47, + 0x1B80, 0x00010D55, + 0x1B80, 0x00010D57, + 0x1B80, 0x00320D65, + 0x1B80, 0x00320D67, + 0x1B80, 0xE16C0D75, + 0x1B80, 0xE16C0D77, + 0x1B80, 0x00020D85, + 0x1B80, 0x00020D87, + 0x1B80, 0xE1860D95, + 0x1B80, 0xE1860D97, + 0x1B80, 0xE1B60DA5, + 0x1B80, 0xE1B60DA7, + 0x1B80, 0x5CD10DB5, + 0x1B80, 0x5CD10DB7, + 0x1B80, 0x673A0DC5, + 0x1B80, 0x673A0DC7, + 0x1B80, 0xE1230DD5, + 0x1B80, 0xE1230DD7, + 0x1B80, 0xF80B0DE5, + 0x1B80, 0xF80B0DE7, + 0x1B80, 0xF9110DF5, + 0x1B80, 0xF9110DF7, + 0x1B80, 0xE1580E05, + 0x1B80, 0xE1580E07, + 0x1B80, 0x67370E15, + 0x1B80, 0x67370E17, + 0x1B80, 0xE1580E25, + 0x1B80, 0xE1580E27, + 0x1B80, 0x672F0E35, + 0x1B80, 0x672F0E37, + 0x1B80, 0xE1580E45, + 0x1B80, 0xE1580E47, + 0x1B80, 0x67270E55, + 0x1B80, 0x67270E57, + 0x1B80, 0xE1580E65, + 0x1B80, 0xE1580E67, + 0x1B80, 0x671F0E75, + 0x1B80, 0x671F0E77, + 0x1B80, 0xE1580E85, + 0x1B80, 0xE1580E87, + 0x1B80, 0x67170E95, + 0x1B80, 0x67170E97, + 0x1B80, 0xE1580EA5, + 0x1B80, 0xE1580EA7, + 0x1B80, 0xF8020EB5, + 0x1B80, 0xF8020EB7, + 0x1B80, 0x30EE0EC5, + 0x1B80, 0x30EE0EC7, + 0x1B80, 0xE0D10ED5, + 0x1B80, 0xE0D10ED7, + 0x1B80, 0x670F0EE5, + 0x1B80, 0x670F0EE7, + 0x1B80, 0xE1580EF5, + 0x1B80, 0xE1580EF7, + 0x1B80, 0x67070F05, + 0x1B80, 0x67070F07, + 0x1B80, 0xE1580F15, + 0x1B80, 0xE1580F17, + 0x1B80, 0xF9020F25, + 0x1B80, 0xF9020F27, + 0x1B80, 0x30F50F35, + 0x1B80, 0x30F50F37, + 0x1B80, 0xE0CD0F45, + 0x1B80, 0xE0CD0F47, + 0x1B80, 0x06140F55, + 0x1B80, 0x06140F57, + 0x1B80, 0xE16C0F65, + 0x1B80, 0xE16C0F67, + 0x1B80, 0x5CF10F75, + 0x1B80, 0x5CF10F77, + 0x1B80, 0xE1580F85, + 0x1B80, 0xE1580F87, + 0x1B80, 0x06140F95, + 0x1B80, 0x06140F97, + 0x1B80, 0xE16C0FA5, + 0x1B80, 0xE16C0FA7, + 0x1B80, 0xF9020FB5, + 0x1B80, 0xF9020FB7, + 0x1B80, 0x30FF0FC5, + 0x1B80, 0x30FF0FC7, + 0x1B80, 0xE0CD0FD5, + 0x1B80, 0xE0CD0FD7, + 0x1B80, 0x31130FE5, + 0x1B80, 0x31130FE7, + 0x1B80, 0x670F0FF5, + 0x1B80, 0x670F0FF7, + 0x1B80, 0xE1581005, + 0x1B80, 0xE1581007, + 0x1B80, 0x67171015, + 0x1B80, 0x67171017, + 0x1B80, 0xE1581025, + 0x1B80, 0xE1581027, + 0x1B80, 0xF8021035, + 0x1B80, 0xF8021037, + 0x1B80, 0x31071045, + 0x1B80, 0x31071047, + 0x1B80, 0xE0D11055, + 0x1B80, 0xE0D11057, + 0x1B80, 0x31131065, + 0x1B80, 0x31131067, + 0x1B80, 0x670F1075, + 0x1B80, 0x670F1077, + 0x1B80, 0xE1581085, + 0x1B80, 0xE1581087, + 0x1B80, 0x671F1095, + 0x1B80, 0x671F1097, + 0x1B80, 0xE15810A5, + 0x1B80, 0xE15810A7, + 0x1B80, 0x672710B5, + 0x1B80, 0x672710B7, + 0x1B80, 0xE15810C5, + 0x1B80, 0xE15810C7, + 0x1B80, 0x672F10D5, + 0x1B80, 0x672F10D7, + 0x1B80, 0xE15810E5, + 0x1B80, 0xE15810E7, + 0x1B80, 0x673710F5, + 0x1B80, 0x673710F7, + 0x1B80, 0xE1581105, + 0x1B80, 0xE1581107, + 0x1B80, 0x673A1115, + 0x1B80, 0x673A1117, + 0x1B80, 0xE1581125, + 0x1B80, 0xE1581127, + 0x1B80, 0x4D101135, + 0x1B80, 0x4D101137, + 0x1B80, 0x30C41145, + 0x1B80, 0x30C41147, + 0x1B80, 0x00011155, + 0x1B80, 0x00011157, + 0x1B80, 0x6F241165, + 0x1B80, 0x6F241167, + 0x1B80, 0x6E401175, + 0x1B80, 0x6E401177, + 0x1B80, 0x6D001185, + 0x1B80, 0x6D001187, + 0x1B80, 0x55031195, + 0x1B80, 0x55031197, + 0x1B80, 0x312311A5, + 0x1B80, 0x312311A7, + 0x1B80, 0x6F1C11B5, + 0x1B80, 0x6F1C11B7, + 0x1B80, 0x6E4011C5, + 0x1B80, 0x6E4011C7, + 0x1B80, 0x550B11D5, + 0x1B80, 0x550B11D7, + 0x1B80, 0x312311E5, + 0x1B80, 0x312311E7, + 0x1B80, 0x061C11F5, + 0x1B80, 0x061C11F7, + 0x1B80, 0x54DE1205, + 0x1B80, 0x54DE1207, + 0x1B80, 0x06DC1215, + 0x1B80, 0x06DC1217, + 0x1B80, 0x55131225, + 0x1B80, 0x55131227, + 0x1B80, 0x74011235, + 0x1B80, 0x74011237, + 0x1B80, 0x74001245, + 0x1B80, 0x74001247, + 0x1B80, 0x8E001255, + 0x1B80, 0x8E001257, + 0x1B80, 0x00011265, + 0x1B80, 0x00011267, + 0x1B80, 0x57021275, + 0x1B80, 0x57021277, + 0x1B80, 0x57001285, + 0x1B80, 0x57001287, + 0x1B80, 0x97001295, + 0x1B80, 0x97001297, + 0x1B80, 0x000112A5, + 0x1B80, 0x000112A7, + 0x1B80, 0x54BF12B5, + 0x1B80, 0x54BF12B7, + 0x1B80, 0x54C112C5, + 0x1B80, 0x54C112C7, + 0x1B80, 0x54A212D5, + 0x1B80, 0x54A212D7, + 0x1B80, 0x54C012E5, + 0x1B80, 0x54C012E7, + 0x1B80, 0x54A112F5, + 0x1B80, 0x54A112F7, + 0x1B80, 0x54DF1305, + 0x1B80, 0x54DF1307, + 0x1B80, 0x00011315, + 0x1B80, 0x00011317, + 0x1B80, 0x55001325, + 0x1B80, 0x55001327, + 0x1B80, 0xE1231335, + 0x1B80, 0xE1231337, + 0x1B80, 0x54811345, + 0x1B80, 0x54811347, + 0x1B80, 0xE1231355, + 0x1B80, 0xE1231357, + 0x1B80, 0x54801365, + 0x1B80, 0x54801367, + 0x1B80, 0x002A1375, + 0x1B80, 0x002A1377, + 0x1B80, 0xE12B1385, + 0x1B80, 0xE12B1387, + 0x1B80, 0xE1231395, + 0x1B80, 0xE1231397, + 0x1B80, 0x548013A5, + 0x1B80, 0x548013A7, + 0x1B80, 0xE17213B5, + 0x1B80, 0xE17213B7, + 0x1B80, 0xBF3013C5, + 0x1B80, 0xBF3013C7, + 0x1B80, 0x000213D5, + 0x1B80, 0x000213D7, + 0x1B80, 0x302813E5, + 0x1B80, 0x302813E7, + 0x1B80, 0x4F7813F5, + 0x1B80, 0x4F7813F7, + 0x1B80, 0x4E001405, + 0x1B80, 0x4E001407, + 0x1B80, 0x53871415, + 0x1B80, 0x53871417, + 0x1B80, 0x52F11425, + 0x1B80, 0x52F11427, + 0x1B80, 0xE1161435, + 0x1B80, 0xE1161437, + 0x1B80, 0xE11B1445, + 0x1B80, 0xE11B1447, + 0x1B80, 0xE11F1455, + 0x1B80, 0xE11F1457, + 0x1B80, 0xE1271465, + 0x1B80, 0xE1271467, + 0x1B80, 0x54811475, + 0x1B80, 0x54811477, + 0x1B80, 0xE1161485, + 0x1B80, 0xE1161487, + 0x1B80, 0xE11B1495, + 0x1B80, 0xE11B1497, + 0x1B80, 0xE11F14A5, + 0x1B80, 0xE11F14A7, + 0x1B80, 0xE12714B5, + 0x1B80, 0xE12714B7, + 0x1B80, 0x548014C5, + 0x1B80, 0x548014C7, + 0x1B80, 0x002A14D5, + 0x1B80, 0x002A14D7, + 0x1B80, 0xE12B14E5, + 0x1B80, 0xE12B14E7, + 0x1B80, 0xE11614F5, + 0x1B80, 0xE11614F7, + 0x1B80, 0xE11B1505, + 0x1B80, 0xE11B1507, + 0x1B80, 0xE11F1515, + 0x1B80, 0xE11F1517, + 0x1B80, 0xE1271525, + 0x1B80, 0xE1271527, + 0x1B80, 0x54801535, + 0x1B80, 0x54801537, + 0x1B80, 0xE1721545, + 0x1B80, 0xE1721547, + 0x1B80, 0xBF171555, + 0x1B80, 0xBF171557, + 0x1B80, 0x00021565, + 0x1B80, 0x00021567, + 0x1B80, 0x30281575, + 0x1B80, 0x30281577, + 0x1B80, 0x06141585, + 0x1B80, 0x06141587, + 0x1B80, 0x73201595, + 0x1B80, 0x73201597, + 0x1B80, 0x720015A5, + 0x1B80, 0x720015A7, + 0x1B80, 0x710015B5, + 0x1B80, 0x710015B7, + 0x1B80, 0x550115C5, + 0x1B80, 0x550115C7, + 0x1B80, 0xE12315D5, + 0x1B80, 0xE12315D7, + 0x1B80, 0xE12715E5, + 0x1B80, 0xE12715E7, + 0x1B80, 0x548115F5, + 0x1B80, 0x548115F7, + 0x1B80, 0xE1231605, + 0x1B80, 0xE1231607, + 0x1B80, 0xE1271615, + 0x1B80, 0xE1271617, + 0x1B80, 0x54801625, + 0x1B80, 0x54801627, + 0x1B80, 0x002A1635, + 0x1B80, 0x002A1637, + 0x1B80, 0xE12B1645, + 0x1B80, 0xE12B1647, + 0x1B80, 0xE1231655, + 0x1B80, 0xE1231657, + 0x1B80, 0xE1271665, + 0x1B80, 0xE1271667, + 0x1B80, 0x54801675, + 0x1B80, 0x54801677, + 0x1B80, 0xE1721685, + 0x1B80, 0xE1721687, + 0x1B80, 0xBF031695, + 0x1B80, 0xBF031697, + 0x1B80, 0x000216A5, + 0x1B80, 0x000216A7, + 0x1B80, 0x302816B5, + 0x1B80, 0x302816B7, + 0x1B80, 0x54BF16C5, + 0x1B80, 0x54BF16C7, + 0x1B80, 0x54C516D5, + 0x1B80, 0x54C516D7, + 0x1B80, 0x050A16E5, + 0x1B80, 0x050A16E7, + 0x1B80, 0x071416F5, + 0x1B80, 0x071416F7, + 0x1B80, 0x54DF1705, + 0x1B80, 0x54DF1707, + 0x1B80, 0x00011715, + 0x1B80, 0x00011717, + 0x1B80, 0x54BF1725, + 0x1B80, 0x54BF1727, + 0x1B80, 0x54C01735, + 0x1B80, 0x54C01737, + 0x1B80, 0x54A31745, + 0x1B80, 0x54A31747, + 0x1B80, 0x54C11755, + 0x1B80, 0x54C11757, + 0x1B80, 0x54A41765, + 0x1B80, 0x54A41767, + 0x1B80, 0x4C831775, + 0x1B80, 0x4C831777, + 0x1B80, 0x4C031785, + 0x1B80, 0x4C031787, + 0x1B80, 0xBF0B1795, + 0x1B80, 0xBF0B1797, + 0x1B80, 0x54C217A5, + 0x1B80, 0x54C217A7, + 0x1B80, 0x54A417B5, + 0x1B80, 0x54A417B7, + 0x1B80, 0x4C8517C5, + 0x1B80, 0x4C8517C7, + 0x1B80, 0x4C0517D5, + 0x1B80, 0x4C0517D7, + 0x1B80, 0xBF0617E5, + 0x1B80, 0xBF0617E7, + 0x1B80, 0x54C117F5, + 0x1B80, 0x54C117F7, + 0x1B80, 0x54A31805, + 0x1B80, 0x54A31807, + 0x1B80, 0x4C861815, + 0x1B80, 0x4C861817, + 0x1B80, 0x4C061825, + 0x1B80, 0x4C061827, + 0x1B80, 0xBF011835, + 0x1B80, 0xBF011837, + 0x1B80, 0x54DF1845, + 0x1B80, 0x54DF1847, + 0x1B80, 0x00011855, + 0x1B80, 0x00011857, + 0x1B80, 0x00071865, + 0x1B80, 0x00071867, + 0x1B80, 0x54011875, + 0x1B80, 0x54011877, + 0x1B80, 0x00041885, + 0x1B80, 0x00041887, + 0x1B80, 0x56001895, + 0x1B80, 0x56001897, + 0x1B80, 0x5CF218A5, + 0x1B80, 0x5CF218A7, + 0x1B80, 0x630718B5, + 0x1B80, 0x630718B7, + 0x1B80, 0x620418C5, + 0x1B80, 0x620418C7, + 0x1B80, 0x610018D5, + 0x1B80, 0x610018D7, + 0x1B80, 0x670718E5, + 0x1B80, 0x670718E7, + 0x1B80, 0x660618F5, + 0x1B80, 0x660618F7, + 0x1B80, 0x6F201905, + 0x1B80, 0x6F201907, + 0x1B80, 0x6E001915, + 0x1B80, 0x6E001917, + 0x1B80, 0x6D001925, + 0x1B80, 0x6D001927, + 0x1B80, 0x6C031935, + 0x1B80, 0x6C031937, + 0x1B80, 0x73201945, + 0x1B80, 0x73201947, + 0x1B80, 0x72001955, + 0x1B80, 0x72001957, + 0x1B80, 0x71001965, + 0x1B80, 0x71001967, + 0x1B80, 0x7B201975, + 0x1B80, 0x7B201977, + 0x1B80, 0x7A001985, + 0x1B80, 0x7A001987, + 0x1B80, 0x79001995, + 0x1B80, 0x79001997, + 0x1B80, 0x7F2019A5, + 0x1B80, 0x7F2019A7, + 0x1B80, 0x7E0019B5, + 0x1B80, 0x7E0019B7, + 0x1B80, 0x7D0019C5, + 0x1B80, 0x7D0019C7, + 0x1B80, 0x090119D5, + 0x1B80, 0x090119D7, + 0x1B80, 0x0AC619E5, + 0x1B80, 0x0AC619E7, + 0x1B80, 0x0BA619F5, + 0x1B80, 0x0BA619F7, + 0x1B80, 0x0C011A05, + 0x1B80, 0x0C011A07, + 0x1B80, 0x0D021A15, + 0x1B80, 0x0D021A17, + 0x1B80, 0x0E041A25, + 0x1B80, 0x0E041A27, + 0x1B80, 0x0FFF1A35, + 0x1B80, 0x0FFF1A37, + 0x1B80, 0x4D041A45, + 0x1B80, 0x4D041A47, + 0x1B80, 0x28F81A55, + 0x1B80, 0x28F81A57, + 0x1B80, 0xE0001A65, + 0x1B80, 0xE0001A67, + 0x1B80, 0x4D001A75, + 0x1B80, 0x4D001A77, + 0x1B80, 0x00011A85, + 0x1B80, 0x00011A87, + 0x1B80, 0x4D041A95, + 0x1B80, 0x4D041A97, + 0x1B80, 0x2EF81AA5, + 0x1B80, 0x2EF81AA7, + 0x1B80, 0x00021AB5, + 0x1B80, 0x00021AB7, + 0x1B80, 0x23031AC5, + 0x1B80, 0x23031AC7, + 0x1B80, 0x00001AD5, + 0x1B80, 0x00001AD7, + 0x1B80, 0x23131AE5, + 0x1B80, 0x23131AE7, + 0x1B80, 0xE77F1AF5, + 0x1B80, 0xE77F1AF7, + 0x1B80, 0x232F1B05, + 0x1B80, 0x232F1B07, + 0x1B80, 0xEFBF1B15, + 0x1B80, 0xEFBF1B17, + 0x1B80, 0x2EF01B25, + 0x1B80, 0x2EF01B27, + 0x1B80, 0x00021B35, + 0x1B80, 0x00021B37, + 0x1B80, 0x4D001B45, + 0x1B80, 0x4D001B47, + 0x1B80, 0x00011B55, + 0x1B80, 0x00011B57, + 0x1B80, 0x4D041B65, + 0x1B80, 0x4D041B67, + 0x1B80, 0x2EF81B75, + 0x1B80, 0x2EF81B77, + 0x1B80, 0x00021B85, + 0x1B80, 0x00021B87, + 0x1B80, 0x23031B95, + 0x1B80, 0x23031B97, + 0x1B80, 0x00001BA5, + 0x1B80, 0x00001BA7, + 0x1B80, 0x23131BB5, + 0x1B80, 0x23131BB7, + 0x1B80, 0xE77F1BC5, + 0x1B80, 0xE77F1BC7, + 0x1B80, 0x232F1BD5, + 0x1B80, 0x232F1BD7, + 0x1B80, 0xE79F1BE5, + 0x1B80, 0xE79F1BE7, + 0x1B80, 0x2EF01BF5, + 0x1B80, 0x2EF01BF7, + 0x1B80, 0x00021C05, + 0x1B80, 0x00021C07, + 0x1B80, 0x28F81C15, + 0x1B80, 0x28F81C17, + 0x1B80, 0x80001C25, + 0x1B80, 0x80001C27, + 0x1B80, 0x4D001C35, + 0x1B80, 0x4D001C37, + 0x1B80, 0x00011C45, + 0x1B80, 0x00011C47, + 0x1B80, 0x00041C55, + 0x1B80, 0x00041C57, + 0x1B80, 0x6BC01C65, + 0x1B80, 0x6BC01C67, + 0x1B80, 0x4D041C75, + 0x1B80, 0x4D041C77, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0xA0000000, 0x00000000, + 0x1B80, 0x68481C85, + 0x1B80, 0x68481C87, + 0xB0000000, 0x00000000, + 0x1B80, 0x66061C95, + 0x1B80, 0x66061C97, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0xA0000000, 0x00000000, + 0x1B80, 0x65041CA5, + 0x1B80, 0x65041CA7, + 0xB0000000, 0x00000000, + 0x1B80, 0x64471CB5, + 0x1B80, 0x64471CB7, + 0x1B80, 0x23411CC5, + 0x1B80, 0x23411CC7, + 0x1B80, 0x100E1CD5, + 0x1B80, 0x100E1CD7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0xA0000000, 0x00000000, + 0x1B80, 0x60011CE5, + 0x1B80, 0x60011CE7, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411CF5, + 0x1B80, 0x23411CF7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0xA0000000, 0x00000000, + 0x1B80, 0x60611D05, + 0x1B80, 0x60611D07, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411D15, + 0x1B80, 0x23411D17, + 0x1B80, 0x70E11D25, + 0x1B80, 0x70E11D27, + 0x1B80, 0x4D001D35, + 0x1B80, 0x4D001D37, + 0x1B80, 0x00011D45, + 0x1B80, 0x00011D47, + 0x1B80, 0x00041D55, + 0x1B80, 0x00041D57, + 0x1B80, 0x6B401D65, + 0x1B80, 0x6B401D67, + 0x1B80, 0x4D041D75, + 0x1B80, 0x4D041D77, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0xA0000000, 0x00000000, + 0x1B80, 0x68481D85, + 0x1B80, 0x68481D87, + 0xB0000000, 0x00000000, + 0x1B80, 0x66061D95, + 0x1B80, 0x66061D97, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0xA0000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0xA0000000, 0x00000000, + 0x1B80, 0x64471DB5, + 0x1B80, 0x64471DB7, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411DC5, + 0x1B80, 0x23411DC7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0xA0000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0xB0000000, 0x00000000, + 0x1B80, 0x60011DE5, + 0x1B80, 0x60011DE7, + 0x1B80, 0x23411DF5, + 0x1B80, 0x23411DF7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0xA0000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411E15, + 0x1B80, 0x23411E17, + 0x1B80, 0x70611E25, + 0x1B80, 0x70611E27, + 0x1B80, 0x4D001E35, + 0x1B80, 0x4D001E37, + 0x1B80, 0x00011E45, + 0x1B80, 0x00011E47, + 0x1B80, 0x00001E55, + 0x1B80, 0x00001E57, + 0x1B80, 0x00001E65, + 0x1B80, 0x00001E67, + 0x1B80, 0x00001E75, + 0x1B80, 0x00001E77, + 0x1B80, 0x00001E85, + 0x1B80, 0x00001E87, + 0x1B80, 0x00001E95, + 0x1B80, 0x00001E97, + 0x1B80, 0x00001EA5, + 0x1B80, 0x00001EA7, + 0x1B80, 0x00001EB5, + 0x1B80, 0x00001EB7, + 0x1B80, 0x00001EC5, + 0x1B80, 0x00001EC7, + 0x1B80, 0x00001ED5, + 0x1B80, 0x00001ED7, + 0x1B80, 0x00001EE5, + 0x1B80, 0x00001EE7, + 0x1B80, 0x00001EF5, + 0x1B80, 0x00001EF7, + 0x1B80, 0x00001F05, + 0x1B80, 0x00001F07, + 0x1B80, 0x00001F15, + 0x1B80, 0x00001F17, + 0x1B80, 0x00001F25, + 0x1B80, 0x00001F27, + 0x1B80, 0x00001F35, + 0x1B80, 0x00001F37, + 0x1B80, 0x00001F45, + 0x1B80, 0x00001F47, + 0x1B80, 0x00001F55, + 0x1B80, 0x00001F57, + 0x1B80, 0x00001F65, + 0x1B80, 0x00001F67, + 0x1B80, 0x00001F75, + 0x1B80, 0x00001F77, + 0x1B80, 0x00001F85, + 0x1B80, 0x00001F87, + 0x1B80, 0x00001F95, + 0x1B80, 0x00001F97, + 0x1B80, 0x00001FA5, + 0x1B80, 0x00001FA7, + 0x1B80, 0x00001FB5, + 0x1B80, 0x00001FB7, + 0x1B80, 0x00001FC5, + 0x1B80, 0x00001FC7, + 0x1B80, 0x00001FD5, + 0x1B80, 0x00001FD7, + 0x1B80, 0x00001FE5, + 0x1B80, 0x00001FE7, + 0x1B80, 0x00001FF5, + 0x1B80, 0x00001FF7, + 0x1B80, 0x00000006, + 0x1B80, 0x00000002, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x30303030, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x28282828, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x22242628, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x30302224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x28303030, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x28282828, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x18202020, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x30303030, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x28282828, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x30302224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x28303030, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x28282828, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x18202020, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x28303232, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x26283032, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x30303030, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x28282828, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x22242628, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x26283032, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x30302224, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x28303030, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x20222426, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x28282828, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x18202020, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x28303232, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x26283032, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x30303030, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x28282828, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x22242628, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x26283032, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x30302224, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x28303030, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x20222426, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x28282828, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x18202020, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x30303030, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x28282828, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x30302224, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303030, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x28282828, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x18202020, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x30303030, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x28282828, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x22242628, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x30302224, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303030, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x28282828, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x18202020, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x28303232, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x26283032, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x30303030, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x28282828, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x22242628, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x26283032, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x30302224, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x28303030, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x20222426, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x28282828, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x18202020, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x28303232, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x26283032, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x30303030, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x28282828, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x22242628, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x26283032, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x30302224, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x28303030, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x20222426, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x28282828, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x18202020, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type0); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type2[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type2); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type3[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x48484848, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x42444646, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x46463840, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x46464646, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x38404244, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x42444646, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x38383840, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x48484848, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x42444646, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x46463840, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x46464646, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x38404244, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x42444646, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x38383840, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x48484848, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x42444646, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x46463840, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x46464646, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x38404244, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x42444646, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x38383840, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x48484848, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x42444646, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x46463840, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x46464646, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x38404244, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x42444646, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x38383840, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x42444646, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x46463840, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x38404244, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x42444646, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x38383840, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x42444646, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x46463840, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x38404244, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x42444646, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x38383840, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x42444646, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x46463840, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x38404244, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x42444646, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x38383840, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x42444646, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x46463840, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x38404244, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x42444646, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x38383840, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type3); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type4[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x42424242, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x34363840, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42423032, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x38404242, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x30323436, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x34363840, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x30303032, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x42424242, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x34363840, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42423032, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x38404242, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x30323436, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x34363840, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x30303032, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x36384042, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x34363840, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x42424242, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x34363840, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x34363840, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x42423032, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x38404242, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x30323436, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x34363840, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x30303032, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x36384042, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x34363840, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x42424242, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x34363840, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x34363840, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x42423032, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x38404242, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x30323436, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x34363840, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x30303032, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x36384042, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x34363840, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x42424242, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x34363840, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42423032, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x38404242, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x30323436, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x34363840, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x30303032, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x36384042, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x34363840, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x42424242, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x34363840, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42423032, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x38404242, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x30323436, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x34363840, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x30303032, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x36384042, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x34363840, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x42424242, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x34363840, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x42423032, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x38404242, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x30323436, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x34363840, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x30303032, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x36384042, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x34363840, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x42424242, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x34363840, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x42423032, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x38404242, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x30323436, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x34363840, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x30303032, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type4); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type5[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x48484848, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x44444444, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x40424444, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x38404242, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x44444040, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x44444444, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x38384042, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x38404242, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20203636, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x48484848, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x44444444, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x40424444, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x38404242, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x44444040, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x44444444, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x38384042, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x38404242, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20203636, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x48484848, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x44444444, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x40424444, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x38404242, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x44444040, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x44444444, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x38384042, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x38404242, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20203636, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x48484848, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x44444444, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x40424444, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x38404242, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x44444040, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x44444444, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x38384042, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x38404242, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20203636, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x44444444, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x40424444, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x38404242, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x44443840, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x44444444, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x36384042, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x38404242, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20203436, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x44444444, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x40424444, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x38404242, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x44443840, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x44444444, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x36384042, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x38404242, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20203436, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x44444444, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x40424444, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x38404242, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x44443840, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x44444444, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x36384042, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x38404242, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20203436, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x44444444, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x40424444, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x38404242, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x44443840, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x44444444, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x36384042, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x38404242, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20203436, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type5); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type7[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34343434, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x28303234, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x34343434, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x34342426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32343434, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x34343434, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x28303234, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x24263434, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34343434, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x28303234, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x34343434, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x34342426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32343434, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x34343434, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x28303234, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x24263434, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x34343434, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x28303234, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x34343434, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x34342426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x32343434, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x34343434, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x28303234, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x24263434, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x34343434, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x28303234, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x34343434, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x34342426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x32343434, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x34343434, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x28303234, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x24263434, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x34343434, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x28303234, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x34343434, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x34342426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x32343434, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x34343434, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x28303234, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x24263434, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x34343434, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x28303234, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x34343434, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x34342426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x32343434, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x34343434, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x28303234, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x24263434, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x34343434, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x28303234, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x34343434, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x34342426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x32343434, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x34343434, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x28303234, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x24263434, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x34343434, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x28303234, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x34343434, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x34342426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x32343434, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x34343434, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x28303234, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x24263434, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type7); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type8[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x35373941, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x33353739, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x43434343, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x31333537, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x43434343, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x29313335, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x43434343, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x43434343, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x35373941, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x41434343, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x33353739, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x39414141, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x31333537, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x37393939, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x29313335, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x43434343, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x43434343, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x35373941, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x41434343, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x33353739, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x39414141, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x31333537, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x37393939, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x29313335, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x43434343, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x43434343, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x35373941, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x41434343, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x33353739, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x39414141, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x31333537, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x37393939, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x29313335, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x39414345, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x38404244, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x36384042, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x46463738, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x35373840, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x37394143, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x33333335, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x39414345, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x38404244, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x36384042, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x46463738, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x35373840, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x37394143, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x33333335, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x39414345, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x38404244, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x36384042, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x38404244, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x46463738, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x35373840, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x37394143, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x33333335, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x39414345, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x38404244, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x36384042, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x38404244, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x46463738, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x35373840, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x37394143, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x33333335, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type8); + +static const u32 rtw8814a_rf_a[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x0B0, 0x000FFFFE, + 0x0B1, 0x0003FF48, + 0x0B2, 0x0006AA3F, + 0x0B3, 0x000FFC9A, + 0x0B4, 0x0000A78F, + 0x0B5, 0x00000A3F, + 0x0B6, 0x0000C09C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0xA0000000, 0x00000000, + 0x0B7, 0x0003000C, + 0xB0000000, 0x00000000, + 0x0B8, 0x0007400E, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0xA0000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0xB0000000, 0x00000000, + 0x0BA, 0x00050780, + 0x0BB, 0x00000000, + 0x0BC, 0x00040009, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0EF, 0x00020000, + 0x03E, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x03E, 0x00020000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00040000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00040000, + 0xA0000000, 0x00000000, + 0x03F, 0x00040000, + 0xB0000000, 0x00000000, + 0x03E, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x03E, 0x00060000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00010000, + 0x03E, 0x00000000, + 0x03F, 0x00006800, + 0x03E, 0x00000080, + 0x03F, 0x00006000, + 0x03E, 0x00000100, + 0x03F, 0x00004800, + 0x03E, 0x00000180, + 0x03F, 0x00004000, + 0x03E, 0x00000200, + 0x03F, 0x00004000, + 0x03E, 0x00000280, + 0x03F, 0x00002800, + 0x03E, 0x00000300, + 0x03F, 0x00002800, + 0x03E, 0x00000380, + 0x03F, 0x00002000, + 0x0EF, 0x00000000, + 0x0EF, 0x00040000, + 0x03E, 0x00000000, + 0x03F, 0x000000BC, + 0x03E, 0x00000040, + 0x03F, 0x00000053, + 0x03E, 0x00000050, + 0x03F, 0x00000050, + 0x03E, 0x00000060, + 0x03F, 0x00000050, + 0x0EF, 0x00000000, + 0x0EF, 0x00000400, + 0x03E, 0x00000006, + 0x041, 0x000EE080, + 0x03E, 0x00000008, + 0x041, 0x000EE0C0, + 0x03E, 0x0000000A, + 0x041, 0x000EE100, + 0x03E, 0x0000000C, + 0x041, 0x000EE100, + 0x0EF, 0x00000000, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00028000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0000118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000AC000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00040000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x0004C000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0004138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0004078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0008C000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0xA0000000, 0x00000000, + 0x03C, 0x00004000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000801, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001801, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000003, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001001, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A1AD, + 0x034, 0x000491AA, + 0x034, 0x000481A7, + 0x034, 0x000470AA, + 0x034, 0x000460A7, + 0x034, 0x00045049, + 0x034, 0x00044046, + 0x034, 0x00043026, + 0x034, 0x00042009, + 0x034, 0x00041006, + 0x034, 0x00040003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F2, + 0x034, 0x000483B0, + 0x034, 0x00047370, + 0x034, 0x0004636D, + 0x034, 0x0004536A, + 0x034, 0x00044349, + 0x034, 0x0004316A, + 0x034, 0x00042167, + 0x034, 0x00041129, + 0x034, 0x00040049, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF1, + 0x034, 0x00049FEE, + 0x034, 0x00048FEB, + 0x034, 0x00047FE8, + 0x034, 0x00046DEA, + 0x034, 0x00045DE7, + 0x034, 0x00044CEA, + 0x034, 0x00043CE7, + 0x034, 0x00042C69, + 0x034, 0x00041C66, + 0x034, 0x00040C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A1AD, + 0x034, 0x000291AA, + 0x034, 0x000281A7, + 0x034, 0x000270AA, + 0x034, 0x000260A7, + 0x034, 0x00025049, + 0x034, 0x00024046, + 0x034, 0x00023026, + 0x034, 0x00022009, + 0x034, 0x00021006, + 0x034, 0x00020003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F2, + 0x034, 0x000282F1, + 0x034, 0x000272B0, + 0x034, 0x000262AD, + 0x034, 0x000252AA, + 0x034, 0x000242A7, + 0x034, 0x000230EC, + 0x034, 0x000220E9, + 0x034, 0x0002106A, + 0x034, 0x00020067, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF1, + 0x034, 0x00029FEE, + 0x034, 0x00028FEB, + 0x034, 0x00027FE8, + 0x034, 0x00026DEA, + 0x034, 0x00025DE7, + 0x034, 0x00024CEA, + 0x034, 0x00023CE7, + 0x034, 0x00022C69, + 0x034, 0x00021C66, + 0x034, 0x00020C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x0000938C, + 0x034, 0x000081AD, + 0x034, 0x000071AA, + 0x034, 0x000061A7, + 0x034, 0x000050AA, + 0x034, 0x000040A7, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x0000100C, + 0x034, 0x00000009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F4, + 0x034, 0x000093F1, + 0x034, 0x000082B1, + 0x034, 0x000071D1, + 0x034, 0x000061CE, + 0x034, 0x000051CB, + 0x034, 0x000041C8, + 0x034, 0x000030CB, + 0x034, 0x000020C8, + 0x034, 0x00001087, + 0x034, 0x00000084, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF1, + 0x034, 0x00009FEE, + 0x034, 0x00008FEB, + 0x034, 0x00007FE8, + 0x034, 0x00006DEA, + 0x034, 0x00005DE7, + 0x034, 0x00004CEA, + 0x034, 0x00003CE7, + 0x034, 0x00002C69, + 0x034, 0x00001C66, + 0x034, 0x00000C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA1AD, + 0x034, 0x000C91AA, + 0x034, 0x000C81A7, + 0x034, 0x000C70AA, + 0x034, 0x000C60A7, + 0x034, 0x000C5049, + 0x034, 0x000C4046, + 0x034, 0x000C3026, + 0x034, 0x000C2009, + 0x034, 0x000C1006, + 0x034, 0x000C0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F2, + 0x034, 0x000C83B0, + 0x034, 0x000C7370, + 0x034, 0x000C636D, + 0x034, 0x000C536A, + 0x034, 0x000C4349, + 0x034, 0x000C316A, + 0x034, 0x000C2167, + 0x034, 0x000C1129, + 0x034, 0x000C0049, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA1AD, + 0x034, 0x000A91AA, + 0x034, 0x000A81A7, + 0x034, 0x000A70AA, + 0x034, 0x000A60A7, + 0x034, 0x000A5049, + 0x034, 0x000A4046, + 0x034, 0x000A3026, + 0x034, 0x000A2009, + 0x034, 0x000A1006, + 0x034, 0x000A0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F2, + 0x034, 0x000A82F1, + 0x034, 0x000A72B0, + 0x034, 0x000A62AD, + 0x034, 0x000A52AA, + 0x034, 0x000A42A7, + 0x034, 0x000A30EC, + 0x034, 0x000A20E9, + 0x034, 0x000A106A, + 0x034, 0x000A0067, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x0008938C, + 0x034, 0x000881AD, + 0x034, 0x000871AA, + 0x034, 0x000861A7, + 0x034, 0x000850AA, + 0x034, 0x000840A7, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x0008100C, + 0x034, 0x00080009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F4, + 0x034, 0x000893F1, + 0x034, 0x000882B1, + 0x034, 0x000871D1, + 0x034, 0x000861CE, + 0x034, 0x000851CB, + 0x034, 0x000841C8, + 0x034, 0x000830CB, + 0x034, 0x000820C8, + 0x034, 0x00081087, + 0x034, 0x00080084, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x00000001, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000747, + 0x035, 0x00008747, + 0x035, 0x00010747, + 0x035, 0x00020747, + 0x035, 0x00028747, + 0x035, 0x00030747, + 0x035, 0x00040747, + 0x035, 0x00048747, + 0x035, 0x00050747, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x00000001, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x00005146, + 0x037, 0x00004000, + 0x038, 0x00005146, + 0x037, 0x00008000, + 0x038, 0x00005146, + 0x037, 0x00010000, + 0x038, 0x00005146, + 0x037, 0x00014000, + 0x038, 0x00005146, + 0x037, 0x00018000, + 0x038, 0x00004D4E, + 0x037, 0x0001C000, + 0x038, 0x00004D4E, + 0x037, 0x00020000, + 0x038, 0x00004D4E, + 0x037, 0x00024000, + 0x038, 0x000071C6, + 0x037, 0x00028000, + 0x038, 0x000071C6, + 0x037, 0x0002C000, + 0x038, 0x000071C6, + 0x037, 0x00030000, + 0x038, 0x000071CE, + 0x037, 0x00034000, + 0x038, 0x000071CE, + 0x037, 0x00038000, + 0x038, 0x00005126, + 0x037, 0x0003C000, + 0x038, 0x00005126, + 0x037, 0x00040000, + 0x038, 0x00005126, + 0x037, 0x00044000, + 0x038, 0x00005126, + 0x037, 0x00048000, + 0x038, 0x00005126, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000933FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, + 0x01C, 0x000739D2, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0xA0000000, 0x00000000, + 0x01F, 0x0002255C, + 0xB0000000, 0x00000000, + 0x0B1, 0x0007FF48, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0xA0000000, 0x00000000, + 0x0C4, 0x00083F00, + 0xB0000000, 0x00000000, + 0x018, 0x0001B126, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x00013126, + 0x018, 0x00013124, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_a, A); + +static const u32 rtw8814a_rf_b[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F39B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F39B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00040000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00000F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x03B, 0x0004078B, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x000491AD, + 0x034, 0x000481AA, + 0x034, 0x000471A7, + 0x034, 0x000460AA, + 0x034, 0x000450A7, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x0004200C, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38B, + 0x034, 0x00049388, + 0x034, 0x0004818B, + 0x034, 0x00047188, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38B, + 0x034, 0x00049388, + 0x034, 0x0004818B, + 0x034, 0x00047188, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F3, + 0x034, 0x000483B2, + 0x034, 0x00047390, + 0x034, 0x0004638D, + 0x034, 0x0004538A, + 0x034, 0x00044387, + 0x034, 0x0004324A, + 0x034, 0x00042247, + 0x034, 0x0004104D, + 0x034, 0x0004004A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043DEA, + 0x034, 0x00042DE7, + 0x034, 0x00041DE4, + 0x034, 0x00040CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A38C, + 0x034, 0x000291AD, + 0x034, 0x000281AA, + 0x034, 0x000271A7, + 0x034, 0x000260AA, + 0x034, 0x000250A7, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x0002200C, + 0x034, 0x00021009, + 0x034, 0x00020006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AD, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AD, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F3, + 0x034, 0x000283D0, + 0x034, 0x00027371, + 0x034, 0x0002636E, + 0x034, 0x0002536B, + 0x034, 0x00024368, + 0x034, 0x0002332A, + 0x034, 0x00022327, + 0x034, 0x0002104C, + 0x034, 0x00020049, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020F25, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A38C, + 0x034, 0x000091AD, + 0x034, 0x000081AA, + 0x034, 0x000071A7, + 0x034, 0x000060AA, + 0x034, 0x000050A7, + 0x034, 0x0000402C, + 0x034, 0x00003029, + 0x034, 0x00002026, + 0x034, 0x00001009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093AD, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093AD, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F4, + 0x034, 0x000093F0, + 0x034, 0x000083AE, + 0x034, 0x00007350, + 0x034, 0x0000634D, + 0x034, 0x0000534A, + 0x034, 0x00004347, + 0x034, 0x0000312D, + 0x034, 0x0000212A, + 0x034, 0x00001127, + 0x034, 0x0000002A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF4, + 0x034, 0x00008FF1, + 0x034, 0x00007FEE, + 0x034, 0x00006FEB, + 0x034, 0x00005FE8, + 0x034, 0x00004DEB, + 0x034, 0x00003DE8, + 0x034, 0x00002DE5, + 0x034, 0x00001C8B, + 0x034, 0x00000C88, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C91AD, + 0x034, 0x000C81AA, + 0x034, 0x000C71A7, + 0x034, 0x000C60AA, + 0x034, 0x000C50A7, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C200C, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38B, + 0x034, 0x000C9388, + 0x034, 0x000C818B, + 0x034, 0x000C7188, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38B, + 0x034, 0x000C9388, + 0x034, 0x000C818B, + 0x034, 0x000C7188, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F3, + 0x034, 0x000C83B2, + 0x034, 0x000C7390, + 0x034, 0x000C638D, + 0x034, 0x000C538A, + 0x034, 0x000C4387, + 0x034, 0x000C324A, + 0x034, 0x000C2247, + 0x034, 0x000C104D, + 0x034, 0x000C004A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3DEA, + 0x034, 0x000C2DE7, + 0x034, 0x000C1DE4, + 0x034, 0x000C0CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA38C, + 0x034, 0x000A91AD, + 0x034, 0x000A81AA, + 0x034, 0x000A71A7, + 0x034, 0x000A60AA, + 0x034, 0x000A50A7, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A200C, + 0x034, 0x000A1009, + 0x034, 0x000A0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AD, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AD, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F3, + 0x034, 0x000A83D0, + 0x034, 0x000A7371, + 0x034, 0x000A636E, + 0x034, 0x000A536B, + 0x034, 0x000A4368, + 0x034, 0x000A332A, + 0x034, 0x000A2327, + 0x034, 0x000A104C, + 0x034, 0x000A0049, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0F25, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A38C, + 0x034, 0x000891AD, + 0x034, 0x000881AA, + 0x034, 0x000871A7, + 0x034, 0x000860AA, + 0x034, 0x000850A7, + 0x034, 0x0008402C, + 0x034, 0x00083029, + 0x034, 0x00082026, + 0x034, 0x00081009, + 0x034, 0x00080006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893AD, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893AD, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F4, + 0x034, 0x000893F0, + 0x034, 0x000883AE, + 0x034, 0x00087350, + 0x034, 0x0008634D, + 0x034, 0x0008534A, + 0x034, 0x00084347, + 0x034, 0x0008312D, + 0x034, 0x0008212A, + 0x034, 0x00081127, + 0x034, 0x0008002A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF4, + 0x034, 0x00088FF1, + 0x034, 0x00087FEE, + 0x034, 0x00086FEB, + 0x034, 0x00085FE8, + 0x034, 0x00084DEB, + 0x034, 0x00083DE8, + 0x034, 0x00082DE5, + 0x034, 0x00081C8B, + 0x034, 0x00080C88, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_b, B); + +static const u32 rtw8814a_rf_c[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0006C000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000D4000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0006C000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0008C000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x000A0000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0000118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000D0000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0xA0000000, 0x00000000, + 0x03C, 0x00028000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x03B, 0x0004078B, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008128B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0xA0000000, 0x00000000, + 0x018, 0x00013124, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x000491AD, + 0x034, 0x000481AA, + 0x034, 0x000471A7, + 0x034, 0x000460AA, + 0x034, 0x000450A7, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x0004200C, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F3, + 0x034, 0x00048393, + 0x034, 0x00047390, + 0x034, 0x0004638D, + 0x034, 0x0004538A, + 0x034, 0x00044387, + 0x034, 0x000430ED, + 0x034, 0x000420EA, + 0x034, 0x000410E7, + 0x034, 0x0004002D, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043CD0, + 0x034, 0x00042CCD, + 0x034, 0x00041CCA, + 0x034, 0x00040CC7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002938C, + 0x034, 0x000281AD, + 0x034, 0x000271AA, + 0x034, 0x000261A7, + 0x034, 0x000250AA, + 0x034, 0x000240A7, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x0002100C, + 0x034, 0x00020009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F3, + 0x034, 0x000282F2, + 0x034, 0x000272D0, + 0x034, 0x000262CD, + 0x034, 0x000252CA, + 0x034, 0x000242C7, + 0x034, 0x000230CD, + 0x034, 0x000220CA, + 0x034, 0x000210C7, + 0x034, 0x00020086, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020E44, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A38C, + 0x034, 0x000091AD, + 0x034, 0x000081AA, + 0x034, 0x000071A7, + 0x034, 0x000060AA, + 0x034, 0x000050A7, + 0x034, 0x0000402C, + 0x034, 0x00003029, + 0x034, 0x0000200C, + 0x034, 0x00001009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F5, + 0x034, 0x000093F1, + 0x034, 0x000083B0, + 0x034, 0x00007370, + 0x034, 0x0000636D, + 0x034, 0x0000536A, + 0x034, 0x00004367, + 0x034, 0x0000308E, + 0x034, 0x0000208B, + 0x034, 0x00001088, + 0x034, 0x00000085, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF5, + 0x034, 0x00008FF2, + 0x034, 0x00007FEF, + 0x034, 0x00006FEC, + 0x034, 0x00005FE9, + 0x034, 0x00004EAA, + 0x034, 0x00003EA7, + 0x034, 0x00002C70, + 0x034, 0x00001C6D, + 0x034, 0x00000C6A, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C91AD, + 0x034, 0x000C81AA, + 0x034, 0x000C71A7, + 0x034, 0x000C60AA, + 0x034, 0x000C50A7, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C200C, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F3, + 0x034, 0x000C8393, + 0x034, 0x000C7390, + 0x034, 0x000C638D, + 0x034, 0x000C538A, + 0x034, 0x000C4387, + 0x034, 0x000C30ED, + 0x034, 0x000C20EA, + 0x034, 0x000C10E7, + 0x034, 0x000C002D, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3CD0, + 0x034, 0x000C2CCD, + 0x034, 0x000C1CCA, + 0x034, 0x000C0CC7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A938C, + 0x034, 0x000A81AD, + 0x034, 0x000A71AA, + 0x034, 0x000A61A7, + 0x034, 0x000A50AA, + 0x034, 0x000A40A7, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A100C, + 0x034, 0x000A0009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F3, + 0x034, 0x000A82F2, + 0x034, 0x000A72D0, + 0x034, 0x000A62CD, + 0x034, 0x000A52CA, + 0x034, 0x000A42C7, + 0x034, 0x000A30CD, + 0x034, 0x000A20CA, + 0x034, 0x000A10C7, + 0x034, 0x000A0086, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0E44, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A38C, + 0x034, 0x000891AD, + 0x034, 0x000881AA, + 0x034, 0x000871A7, + 0x034, 0x000860AA, + 0x034, 0x000850A7, + 0x034, 0x0008402C, + 0x034, 0x00083029, + 0x034, 0x0008200C, + 0x034, 0x00081009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F5, + 0x034, 0x000893F1, + 0x034, 0x000883B0, + 0x034, 0x00087370, + 0x034, 0x0008636D, + 0x034, 0x0008536A, + 0x034, 0x00084367, + 0x034, 0x0008308E, + 0x034, 0x0008208B, + 0x034, 0x00081088, + 0x034, 0x00080085, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF5, + 0x034, 0x00088FF2, + 0x034, 0x00087FEF, + 0x034, 0x00086FEC, + 0x034, 0x00085FE9, + 0x034, 0x00084EAA, + 0x034, 0x00083EA7, + 0x034, 0x00082C70, + 0x034, 0x00081C6D, + 0x034, 0x00080C6A, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000541, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001541, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002541, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_c, C); + +static const u32 rtw8814a_rf_d[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F09B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F09B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00040000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00048000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00000F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0xA0000000, 0x00000000, + 0x03C, 0x00024000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00040F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0004078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0xA0000000, 0x00000000, + 0x03C, 0x00004000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001002, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000001, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EB, + 0x034, 0x0004938B, + 0x034, 0x000481AC, + 0x034, 0x000471A9, + 0x034, 0x000460AC, + 0x034, 0x000450A9, + 0x034, 0x0004402E, + 0x034, 0x0004302B, + 0x034, 0x00042028, + 0x034, 0x0004100B, + 0x034, 0x00040008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F4, + 0x034, 0x000493D2, + 0x034, 0x000482D1, + 0x034, 0x000471F1, + 0x034, 0x000461EE, + 0x034, 0x000451EB, + 0x034, 0x000441E8, + 0x034, 0x0004314B, + 0x034, 0x00042148, + 0x034, 0x0004104B, + 0x034, 0x00040048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043CB1, + 0x034, 0x00042CAE, + 0x034, 0x00041CAB, + 0x034, 0x00040CA8, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293EB, + 0x034, 0x0002838B, + 0x034, 0x000271AC, + 0x034, 0x000261A9, + 0x034, 0x000250AC, + 0x034, 0x000240A9, + 0x034, 0x000230A6, + 0x034, 0x0002202C, + 0x034, 0x00021029, + 0x034, 0x00020026, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293D2, + 0x034, 0x000283CE, + 0x034, 0x00027290, + 0x034, 0x0002628D, + 0x034, 0x0002528A, + 0x034, 0x00024287, + 0x034, 0x0002308D, + 0x034, 0x0002208A, + 0x034, 0x00021087, + 0x034, 0x00020048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093EC, + 0x034, 0x0000838C, + 0x034, 0x000071AD, + 0x034, 0x000061AA, + 0x034, 0x000050AD, + 0x034, 0x000040AA, + 0x034, 0x0000306A, + 0x034, 0x0000202D, + 0x034, 0x0000102A, + 0x034, 0x00000027, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F1, + 0x034, 0x000092B1, + 0x034, 0x000081CF, + 0x034, 0x00007170, + 0x034, 0x0000616D, + 0x034, 0x0000516A, + 0x034, 0x00004167, + 0x034, 0x0000302F, + 0x034, 0x0000202C, + 0x034, 0x00001029, + 0x034, 0x00000026, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF6, + 0x034, 0x00008FF3, + 0x034, 0x00007FF0, + 0x034, 0x00006FED, + 0x034, 0x00005FEA, + 0x034, 0x00004FE7, + 0x034, 0x00003EC7, + 0x034, 0x00002EC4, + 0x034, 0x00001D4B, + 0x034, 0x00000D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EB, + 0x034, 0x000C938B, + 0x034, 0x000C81AC, + 0x034, 0x000C71A9, + 0x034, 0x000C60AC, + 0x034, 0x000C50A9, + 0x034, 0x000C402E, + 0x034, 0x000C302B, + 0x034, 0x000C2028, + 0x034, 0x000C100B, + 0x034, 0x000C0008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F4, + 0x034, 0x000C93D2, + 0x034, 0x000C82D1, + 0x034, 0x000C71F1, + 0x034, 0x000C61EE, + 0x034, 0x000C51EB, + 0x034, 0x000C41E8, + 0x034, 0x000C314B, + 0x034, 0x000C2148, + 0x034, 0x000C104B, + 0x034, 0x000C0048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3CB1, + 0x034, 0x000C2CAE, + 0x034, 0x000C1CAB, + 0x034, 0x000C0CA8, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93EB, + 0x034, 0x000A838B, + 0x034, 0x000A71AC, + 0x034, 0x000A61A9, + 0x034, 0x000A50AC, + 0x034, 0x000A40A9, + 0x034, 0x000A30A6, + 0x034, 0x000A202C, + 0x034, 0x000A1029, + 0x034, 0x000A0026, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93D2, + 0x034, 0x000A83CE, + 0x034, 0x000A7290, + 0x034, 0x000A628D, + 0x034, 0x000A528A, + 0x034, 0x000A4287, + 0x034, 0x000A308D, + 0x034, 0x000A208A, + 0x034, 0x000A1087, + 0x034, 0x000A0048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893EC, + 0x034, 0x0008838C, + 0x034, 0x000871AD, + 0x034, 0x000861AA, + 0x034, 0x000850AD, + 0x034, 0x000840AA, + 0x034, 0x0008306A, + 0x034, 0x0008202D, + 0x034, 0x0008102A, + 0x034, 0x00080027, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F1, + 0x034, 0x000892B1, + 0x034, 0x000881CF, + 0x034, 0x00087170, + 0x034, 0x0008616D, + 0x034, 0x0008516A, + 0x034, 0x00084167, + 0x034, 0x0008302F, + 0x034, 0x0008202C, + 0x034, 0x00081029, + 0x034, 0x00080026, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF6, + 0x034, 0x00088FF3, + 0x034, 0x00087FF0, + 0x034, 0x00086FED, + 0x034, 0x00085FEA, + 0x034, 0x00084FE7, + 0x034, 0x00083EC7, + 0x034, 0x00082EC4, + 0x034, 0x00081D4B, + 0x034, 0x00080D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000275, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x00001275, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x00002275, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_d, D); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt[] = { + { 0, 0, 0, 0, 1, 36, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 36, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 36, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 36, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 36, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 36, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 36, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 36, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 36, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 36, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 36, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 34, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 36, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 36, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 36, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 36, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 36, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 36, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 36, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 36, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 36, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 32, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 34, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 36, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 36, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 36, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 36, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 36, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 36, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 36, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 36, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 36, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 32, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 34, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 34, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 34, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 34, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 34, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 34, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 34, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 34, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 34, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 30, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 30, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 32, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 32, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 32, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 32, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 32, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 32, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 32, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 32, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 32, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 28, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 28, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 30, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 30, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 30, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 30, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 30, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 30, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 30, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 30, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 30, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 26, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 32, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 36, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 36, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 36, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 36, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 36, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 36, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 36, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 32, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 30, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 28, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 32, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 32, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 32, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 32, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 32, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 32, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 32, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 26, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 30, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 30, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 30, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 30, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 30, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 30, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 30, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 26, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 30, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 30, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 30, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 36, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 34, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 30, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 30, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 34, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 34, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 36, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 34, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 30, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 30, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 36, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 36, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 36, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 36, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 36, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 30, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 30, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 30, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 34, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 30, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 30, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 34, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 34, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 36, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 34, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 30, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 30, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 28, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 36, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 36, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 36, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 36, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 36, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 26, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 34, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 34, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 34, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 34, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 34, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 26, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 26, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 26, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 26, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 32, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 30, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 28, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 24, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 26, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 26, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 28, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 30, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 30, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 30, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 28, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 26, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 26, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 24, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 32, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 32, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 32, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 32, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 32, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 24, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 24, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 24, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 24, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 30, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 28, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 26, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 22, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 24, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 24, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 26, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 28, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 28, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 30, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 28, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 26, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 24, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 24, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 22, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 30, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 30, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 30, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 30, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 30, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 30, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 32, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 28, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 36, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 34, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 36, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 28, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 30, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 34, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 34, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 34, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 26, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 26, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 28, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 24, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 28, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 32, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 30, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 28, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 32, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 32, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 24, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 24, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 26, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 22, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 26, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 30, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 28, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 26, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 30, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 30, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 30, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 28, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 30, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 34, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 36, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 28, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 26, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 28, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 32, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 26, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 24, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 26, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 30, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 32, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 24, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 22, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 24, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 28, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 30, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 28, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 32, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 32, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 32, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 32, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 32, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 18, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 8, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 32, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 32, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 32, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 32, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 32, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 32, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 32, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 16, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 6, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 24, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 30, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 30, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 30, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 30, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 30, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 24, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 14, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 4, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 22, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 28, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 28, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 28, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 28, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 28, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 28, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 28, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 28, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 28, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 22, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 14, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 4, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 20, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 26, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 26, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 26, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 26, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 26, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 26, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 26, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 26, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 26, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 20, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 14, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 4, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 32, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 32, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 32, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 32, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 32, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 32, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 26, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 16, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 10, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 30, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 30, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 30, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 30, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 30, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 30, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 30, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 24, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 14, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 8, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 22, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 28, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 28, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 28, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 28, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 28, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 28, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 28, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 22, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 14, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 8, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 20, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 26, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 26, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 26, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 26, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 26, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 26, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 26, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 20, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 14, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 8, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 28, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 28, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 28, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 26, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 26, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 26, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 26, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 26, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 24, }, + { 2, 1, 0, 3, 36, 28, }, + { 1, 1, 0, 3, 36, 28, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 28, }, + { 1, 1, 0, 3, 40, 28, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 28, }, + { 1, 1, 0, 3, 44, 28, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 28, }, + { 1, 1, 0, 3, 48, 28, }, + { 0, 1, 0, 3, 52, 28, }, + { 2, 1, 0, 3, 52, 28, }, + { 1, 1, 0, 3, 52, 28, }, + { 0, 1, 0, 3, 56, 28, }, + { 2, 1, 0, 3, 56, 28, }, + { 1, 1, 0, 3, 56, 28, }, + { 0, 1, 0, 3, 60, 28, }, + { 2, 1, 0, 3, 60, 28, }, + { 1, 1, 0, 3, 60, 28, }, + { 0, 1, 0, 3, 64, 24, }, + { 2, 1, 0, 3, 64, 28, }, + { 1, 1, 0, 3, 64, 28, }, + { 0, 1, 0, 3, 100, 24, }, + { 2, 1, 0, 3, 100, 28, }, + { 1, 1, 0, 3, 100, 28, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 28, }, + { 1, 1, 0, 3, 104, 28, }, + { 0, 1, 0, 3, 108, 28, }, + { 2, 1, 0, 3, 108, 28, }, + { 1, 1, 0, 3, 108, 28, }, + { 0, 1, 0, 3, 112, 28, }, + { 2, 1, 0, 3, 112, 28, }, + { 1, 1, 0, 3, 112, 28, }, + { 0, 1, 0, 3, 116, 28, }, + { 2, 1, 0, 3, 116, 28, }, + { 1, 1, 0, 3, 116, 28, }, + { 0, 1, 0, 3, 120, 28, }, + { 2, 1, 0, 3, 120, 28, }, + { 1, 1, 0, 3, 120, 28, }, + { 0, 1, 0, 3, 124, 28, }, + { 2, 1, 0, 3, 124, 28, }, + { 1, 1, 0, 3, 124, 28, }, + { 0, 1, 0, 3, 128, 28, }, + { 2, 1, 0, 3, 128, 28, }, + { 1, 1, 0, 3, 128, 28, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 28, }, + { 1, 1, 0, 3, 132, 28, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 28, }, + { 1, 1, 0, 3, 136, 28, }, + { 0, 1, 0, 3, 140, 24, }, + { 2, 1, 0, 3, 140, 28, }, + { 1, 1, 0, 3, 140, 28, }, + { 0, 1, 0, 3, 149, 24, }, + { 2, 1, 0, 3, 149, 28, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 28, }, + { 2, 1, 0, 3, 153, 28, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 28, }, + { 2, 1, 0, 3, 157, 28, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 28, }, + { 2, 1, 0, 3, 161, 28, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 28, }, + { 2, 1, 0, 3, 165, 28, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 22, }, + { 2, 1, 0, 6, 36, 26, }, + { 1, 1, 0, 6, 36, 26, }, + { 0, 1, 0, 6, 40, 26, }, + { 2, 1, 0, 6, 40, 26, }, + { 1, 1, 0, 6, 40, 26, }, + { 0, 1, 0, 6, 44, 26, }, + { 2, 1, 0, 6, 44, 26, }, + { 1, 1, 0, 6, 44, 26, }, + { 0, 1, 0, 6, 48, 26, }, + { 2, 1, 0, 6, 48, 26, }, + { 1, 1, 0, 6, 48, 26, }, + { 0, 1, 0, 6, 52, 26, }, + { 2, 1, 0, 6, 52, 26, }, + { 1, 1, 0, 6, 52, 26, }, + { 0, 1, 0, 6, 56, 26, }, + { 2, 1, 0, 6, 56, 26, }, + { 1, 1, 0, 6, 56, 26, }, + { 0, 1, 0, 6, 60, 26, }, + { 2, 1, 0, 6, 60, 26, }, + { 1, 1, 0, 6, 60, 26, }, + { 0, 1, 0, 6, 64, 22, }, + { 2, 1, 0, 6, 64, 26, }, + { 1, 1, 0, 6, 64, 26, }, + { 0, 1, 0, 6, 100, 22, }, + { 2, 1, 0, 6, 100, 26, }, + { 1, 1, 0, 6, 100, 26, }, + { 0, 1, 0, 6, 104, 26, }, + { 2, 1, 0, 6, 104, 26, }, + { 1, 1, 0, 6, 104, 26, }, + { 0, 1, 0, 6, 108, 26, }, + { 2, 1, 0, 6, 108, 26, }, + { 1, 1, 0, 6, 108, 26, }, + { 0, 1, 0, 6, 112, 26, }, + { 2, 1, 0, 6, 112, 26, }, + { 1, 1, 0, 6, 112, 26, }, + { 0, 1, 0, 6, 116, 26, }, + { 2, 1, 0, 6, 116, 26, }, + { 1, 1, 0, 6, 116, 26, }, + { 0, 1, 0, 6, 120, 26, }, + { 2, 1, 0, 6, 120, 26, }, + { 1, 1, 0, 6, 120, 26, }, + { 0, 1, 0, 6, 124, 26, }, + { 2, 1, 0, 6, 124, 26, }, + { 1, 1, 0, 6, 124, 26, }, + { 0, 1, 0, 6, 128, 26, }, + { 2, 1, 0, 6, 128, 26, }, + { 1, 1, 0, 6, 128, 26, }, + { 0, 1, 0, 6, 132, 26, }, + { 2, 1, 0, 6, 132, 26, }, + { 1, 1, 0, 6, 132, 26, }, + { 0, 1, 0, 6, 136, 26, }, + { 2, 1, 0, 6, 136, 26, }, + { 1, 1, 0, 6, 136, 26, }, + { 0, 1, 0, 6, 140, 22, }, + { 2, 1, 0, 6, 140, 26, }, + { 1, 1, 0, 6, 140, 26, }, + { 0, 1, 0, 6, 149, 22, }, + { 2, 1, 0, 6, 149, 26, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 26, }, + { 2, 1, 0, 6, 153, 26, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 26, }, + { 2, 1, 0, 6, 157, 26, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 26, }, + { 2, 1, 0, 6, 161, 26, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 26, }, + { 2, 1, 0, 6, 165, 26, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 20, }, + { 2, 1, 0, 7, 36, 24, }, + { 1, 1, 0, 7, 36, 24, }, + { 0, 1, 0, 7, 40, 24, }, + { 2, 1, 0, 7, 40, 24, }, + { 1, 1, 0, 7, 40, 24, }, + { 0, 1, 0, 7, 44, 24, }, + { 2, 1, 0, 7, 44, 24, }, + { 1, 1, 0, 7, 44, 24, }, + { 0, 1, 0, 7, 48, 24, }, + { 2, 1, 0, 7, 48, 24, }, + { 1, 1, 0, 7, 48, 24, }, + { 0, 1, 0, 7, 52, 24, }, + { 2, 1, 0, 7, 52, 24, }, + { 1, 1, 0, 7, 52, 24, }, + { 0, 1, 0, 7, 56, 24, }, + { 2, 1, 0, 7, 56, 24, }, + { 1, 1, 0, 7, 56, 24, }, + { 0, 1, 0, 7, 60, 24, }, + { 2, 1, 0, 7, 60, 24, }, + { 1, 1, 0, 7, 60, 24, }, + { 0, 1, 0, 7, 64, 20, }, + { 2, 1, 0, 7, 64, 24, }, + { 1, 1, 0, 7, 64, 24, }, + { 0, 1, 0, 7, 100, 20, }, + { 2, 1, 0, 7, 100, 24, }, + { 1, 1, 0, 7, 100, 24, }, + { 0, 1, 0, 7, 104, 24, }, + { 2, 1, 0, 7, 104, 24, }, + { 1, 1, 0, 7, 104, 24, }, + { 0, 1, 0, 7, 108, 24, }, + { 2, 1, 0, 7, 108, 24, }, + { 1, 1, 0, 7, 108, 24, }, + { 0, 1, 0, 7, 112, 24, }, + { 2, 1, 0, 7, 112, 24, }, + { 1, 1, 0, 7, 112, 24, }, + { 0, 1, 0, 7, 116, 24, }, + { 2, 1, 0, 7, 116, 24, }, + { 1, 1, 0, 7, 116, 24, }, + { 0, 1, 0, 7, 120, 24, }, + { 2, 1, 0, 7, 120, 24, }, + { 1, 1, 0, 7, 120, 24, }, + { 0, 1, 0, 7, 124, 24, }, + { 2, 1, 0, 7, 124, 24, }, + { 1, 1, 0, 7, 124, 24, }, + { 0, 1, 0, 7, 128, 24, }, + { 2, 1, 0, 7, 128, 24, }, + { 1, 1, 0, 7, 128, 24, }, + { 0, 1, 0, 7, 132, 24, }, + { 2, 1, 0, 7, 132, 24, }, + { 1, 1, 0, 7, 132, 24, }, + { 0, 1, 0, 7, 136, 24, }, + { 2, 1, 0, 7, 136, 24, }, + { 1, 1, 0, 7, 136, 24, }, + { 0, 1, 0, 7, 140, 20, }, + { 2, 1, 0, 7, 140, 24, }, + { 1, 1, 0, 7, 140, 24, }, + { 0, 1, 0, 7, 149, 20, }, + { 2, 1, 0, 7, 149, 24, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 24, }, + { 2, 1, 0, 7, 153, 24, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 24, }, + { 2, 1, 0, 7, 157, 24, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 24, }, + { 2, 1, 0, 7, 161, 24, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 24, }, + { 2, 1, 0, 7, 165, 24, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 26, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 26, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 26, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 26, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 24, }, + { 2, 1, 1, 3, 38, 28, }, + { 1, 1, 1, 3, 38, 28, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 28, }, + { 1, 1, 1, 3, 46, 28, }, + { 0, 1, 1, 3, 54, 28, }, + { 2, 1, 1, 3, 54, 28, }, + { 1, 1, 1, 3, 54, 28, }, + { 0, 1, 1, 3, 62, 24, }, + { 2, 1, 1, 3, 62, 28, }, + { 1, 1, 1, 3, 62, 28, }, + { 0, 1, 1, 3, 102, 24, }, + { 2, 1, 1, 3, 102, 28, }, + { 1, 1, 1, 3, 102, 28, }, + { 0, 1, 1, 3, 110, 28, }, + { 2, 1, 1, 3, 110, 28, }, + { 1, 1, 1, 3, 110, 28, }, + { 0, 1, 1, 3, 118, 28, }, + { 2, 1, 1, 3, 118, 28, }, + { 1, 1, 1, 3, 118, 28, }, + { 0, 1, 1, 3, 126, 28, }, + { 2, 1, 1, 3, 126, 28, }, + { 1, 1, 1, 3, 126, 28, }, + { 0, 1, 1, 3, 134, 28, }, + { 2, 1, 1, 3, 134, 28, }, + { 1, 1, 1, 3, 134, 28, }, + { 0, 1, 1, 3, 151, 24, }, + { 2, 1, 1, 3, 151, 28, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 28, }, + { 2, 1, 1, 3, 159, 28, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 20, }, + { 2, 1, 1, 6, 38, 26, }, + { 1, 1, 1, 6, 38, 26, }, + { 0, 1, 1, 6, 46, 26, }, + { 2, 1, 1, 6, 46, 26, }, + { 1, 1, 1, 6, 46, 26, }, + { 0, 1, 1, 6, 54, 26, }, + { 2, 1, 1, 6, 54, 26, }, + { 1, 1, 1, 6, 54, 26, }, + { 0, 1, 1, 6, 62, 20, }, + { 2, 1, 1, 6, 62, 26, }, + { 1, 1, 1, 6, 62, 26, }, + { 0, 1, 1, 6, 102, 20, }, + { 2, 1, 1, 6, 102, 26, }, + { 1, 1, 1, 6, 102, 26, }, + { 0, 1, 1, 6, 110, 26, }, + { 2, 1, 1, 6, 110, 26, }, + { 1, 1, 1, 6, 110, 26, }, + { 0, 1, 1, 6, 118, 26, }, + { 2, 1, 1, 6, 118, 26, }, + { 1, 1, 1, 6, 118, 26, }, + { 0, 1, 1, 6, 126, 26, }, + { 2, 1, 1, 6, 126, 26, }, + { 1, 1, 1, 6, 126, 26, }, + { 0, 1, 1, 6, 134, 26, }, + { 2, 1, 1, 6, 134, 26, }, + { 1, 1, 1, 6, 134, 26, }, + { 0, 1, 1, 6, 151, 20, }, + { 2, 1, 1, 6, 151, 26, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 26, }, + { 2, 1, 1, 6, 159, 26, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 18, }, + { 2, 1, 1, 7, 38, 24, }, + { 1, 1, 1, 7, 38, 24, }, + { 0, 1, 1, 7, 46, 24, }, + { 2, 1, 1, 7, 46, 24, }, + { 1, 1, 1, 7, 46, 24, }, + { 0, 1, 1, 7, 54, 24, }, + { 2, 1, 1, 7, 54, 24, }, + { 1, 1, 1, 7, 54, 24, }, + { 0, 1, 1, 7, 62, 18, }, + { 2, 1, 1, 7, 62, 24, }, + { 1, 1, 1, 7, 62, 24, }, + { 0, 1, 1, 7, 102, 18, }, + { 2, 1, 1, 7, 102, 24, }, + { 1, 1, 1, 7, 102, 24, }, + { 0, 1, 1, 7, 110, 24, }, + { 2, 1, 1, 7, 110, 24, }, + { 1, 1, 1, 7, 110, 24, }, + { 0, 1, 1, 7, 118, 24, }, + { 2, 1, 1, 7, 118, 24, }, + { 1, 1, 1, 7, 118, 24, }, + { 0, 1, 1, 7, 126, 24, }, + { 2, 1, 1, 7, 126, 24, }, + { 1, 1, 1, 7, 126, 24, }, + { 0, 1, 1, 7, 134, 24, }, + { 2, 1, 1, 7, 134, 24, }, + { 1, 1, 1, 7, 134, 24, }, + { 0, 1, 1, 7, 151, 18, }, + { 2, 1, 1, 7, 151, 24, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 24, }, + { 2, 1, 1, 7, 159, 24, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 22, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 30, }, + { 0, 1, 2, 4, 58, 22, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 30, }, + { 0, 1, 2, 4, 106, 22, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 30, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 155, 22, }, + { 2, 1, 2, 4, 155, 30, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 20, }, + { 2, 1, 2, 5, 42, 28, }, + { 1, 1, 2, 5, 42, 28, }, + { 0, 1, 2, 5, 58, 20, }, + { 2, 1, 2, 5, 58, 28, }, + { 1, 1, 2, 5, 58, 28, }, + { 0, 1, 2, 5, 106, 20, }, + { 2, 1, 2, 5, 106, 28, }, + { 1, 1, 2, 5, 106, 28, }, + { 0, 1, 2, 5, 122, 28, }, + { 2, 1, 2, 5, 122, 28, }, + { 1, 1, 2, 5, 122, 28, }, + { 0, 1, 2, 5, 155, 20, }, + { 2, 1, 2, 5, 155, 28, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 18, }, + { 2, 1, 2, 8, 42, 26, }, + { 1, 1, 2, 8, 42, 26, }, + { 0, 1, 2, 8, 58, 18, }, + { 2, 1, 2, 8, 58, 26, }, + { 1, 1, 2, 8, 58, 26, }, + { 0, 1, 2, 8, 106, 18, }, + { 2, 1, 2, 8, 106, 26, }, + { 1, 1, 2, 8, 106, 26, }, + { 0, 1, 2, 8, 122, 26, }, + { 2, 1, 2, 8, 122, 26, }, + { 1, 1, 2, 8, 122, 26, }, + { 0, 1, 2, 8, 155, 18, }, + { 2, 1, 2, 8, 155, 26, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 16, }, + { 2, 1, 2, 9, 42, 24, }, + { 1, 1, 2, 9, 42, 24, }, + { 0, 1, 2, 9, 58, 16, }, + { 2, 1, 2, 9, 58, 24, }, + { 1, 1, 2, 9, 58, 24, }, + { 0, 1, 2, 9, 106, 16, }, + { 2, 1, 2, 9, 106, 24, }, + { 1, 1, 2, 9, 106, 24, }, + { 0, 1, 2, 9, 122, 24, }, + { 2, 1, 2, 9, 122, 24, }, + { 1, 1, 2, 9, 122, 24, }, + { 0, 1, 2, 9, 155, 16, }, + { 2, 1, 2, 9, 155, 24, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type0); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type1[] = { + { 0, 0, 0, 0, 1, 34, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 34, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 34, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 34, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 34, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 34, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 34, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 34, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 34, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 34, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 34, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 30, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 32, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 32, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 32, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 32, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 32, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 30, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 18, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 8, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 28, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 32, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 32, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 32, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 32, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 32, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 32, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 32, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 16, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 6, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 30, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 30, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 30, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 30, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 30, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 14, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 4, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 24, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 28, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 28, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 28, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 28, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 28, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 28, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 28, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 28, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 28, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 24, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 14, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 4, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 22, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 26, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 26, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 26, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 26, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 26, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 26, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 26, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 26, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 26, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 22, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 14, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 4, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 28, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 32, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 32, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 32, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 32, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 32, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 32, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 16, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 10, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 26, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 30, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 30, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 30, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 30, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 30, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 30, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 30, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 26, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 14, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 8, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 24, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 28, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 28, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 28, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 28, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 28, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 28, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 28, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 24, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 14, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 8, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 22, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 26, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 26, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 26, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 26, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 26, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 26, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 26, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 22, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 14, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 8, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 28, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 30, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 28, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 28, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 28, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 30, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 28, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 28, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 28, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 26, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 30, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 30, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 30, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 30, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 30, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 28, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 30, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 30, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 30, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 30, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 30, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 30, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 30, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 26, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 30, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 30, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 30, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 30, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 24, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 28, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 28, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 28, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 28, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 28, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 28, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 26, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 24, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 28, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 28, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 28, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 28, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 28, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 28, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 28, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 28, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 28, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 24, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 24, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 28, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 28, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 28, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 28, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 22, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 26, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 26, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 26, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 26, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 26, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 26, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 24, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 22, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 26, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 26, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 26, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 26, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 26, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 26, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 26, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 26, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 26, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 22, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 22, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 26, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 26, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 26, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 26, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 28, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 28, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 28, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 30, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 28, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 26, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 26, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 30, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 30, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 28, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 26, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 20, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 28, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 20, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 22, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 28, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 28, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 28, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 26, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 22, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 28, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 18, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 26, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 18, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 20, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 26, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 26, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 26, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 24, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 20, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 26, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 24, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 24, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 24, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 32, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 26, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 22, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 22, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 22, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 30, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 24, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 20, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 20, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 20, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 28, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 20, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 18, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 18, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 18, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 26, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 18, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type1); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type2[] = { + { 0, 0, 0, 0, 1, 42, }, + { 2, 0, 0, 0, 1, 42, }, + { 1, 0, 0, 0, 1, 42, }, + { 0, 0, 0, 0, 2, 50, }, + { 2, 0, 0, 0, 2, 42, }, + { 1, 0, 0, 0, 2, 42, }, + { 0, 0, 0, 0, 3, 50, }, + { 2, 0, 0, 0, 3, 42, }, + { 1, 0, 0, 0, 3, 42, }, + { 0, 0, 0, 0, 4, 50, }, + { 2, 0, 0, 0, 4, 42, }, + { 1, 0, 0, 0, 4, 42, }, + { 0, 0, 0, 0, 5, 50, }, + { 2, 0, 0, 0, 5, 42, }, + { 1, 0, 0, 0, 5, 42, }, + { 0, 0, 0, 0, 6, 50, }, + { 2, 0, 0, 0, 6, 42, }, + { 1, 0, 0, 0, 6, 42, }, + { 0, 0, 0, 0, 7, 50, }, + { 2, 0, 0, 0, 7, 42, }, + { 1, 0, 0, 0, 7, 42, }, + { 0, 0, 0, 0, 8, 50, }, + { 2, 0, 0, 0, 8, 42, }, + { 1, 0, 0, 0, 8, 42, }, + { 0, 0, 0, 0, 9, 50, }, + { 2, 0, 0, 0, 9, 42, }, + { 1, 0, 0, 0, 9, 42, }, + { 0, 0, 0, 0, 10, 50, }, + { 2, 0, 0, 0, 10, 42, }, + { 1, 0, 0, 0, 10, 42, }, + { 0, 0, 0, 0, 11, 44, }, + { 2, 0, 0, 0, 11, 42, }, + { 1, 0, 0, 0, 11, 42, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 42, }, + { 1, 0, 0, 0, 12, 42, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 42, }, + { 1, 0, 0, 0, 13, 42, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 42, }, + { 0, 0, 0, 1, 1, 32, }, + { 2, 0, 0, 1, 1, 42, }, + { 1, 0, 0, 1, 1, 42, }, + { 0, 0, 0, 1, 2, 42, }, + { 2, 0, 0, 1, 2, 42, }, + { 1, 0, 0, 1, 2, 42, }, + { 0, 0, 0, 1, 3, 42, }, + { 2, 0, 0, 1, 3, 42, }, + { 1, 0, 0, 1, 3, 42, }, + { 0, 0, 0, 1, 4, 42, }, + { 2, 0, 0, 1, 4, 42, }, + { 1, 0, 0, 1, 4, 42, }, + { 0, 0, 0, 1, 5, 42, }, + { 2, 0, 0, 1, 5, 42, }, + { 1, 0, 0, 1, 5, 42, }, + { 0, 0, 0, 1, 6, 42, }, + { 2, 0, 0, 1, 6, 42, }, + { 1, 0, 0, 1, 6, 42, }, + { 0, 0, 0, 1, 7, 42, }, + { 2, 0, 0, 1, 7, 42, }, + { 1, 0, 0, 1, 7, 42, }, + { 0, 0, 0, 1, 8, 42, }, + { 2, 0, 0, 1, 8, 42, }, + { 1, 0, 0, 1, 8, 42, }, + { 0, 0, 0, 1, 9, 42, }, + { 2, 0, 0, 1, 9, 42, }, + { 1, 0, 0, 1, 9, 42, }, + { 0, 0, 0, 1, 10, 42, }, + { 2, 0, 0, 1, 10, 42, }, + { 1, 0, 0, 1, 10, 42, }, + { 0, 0, 0, 1, 11, 32, }, + { 2, 0, 0, 1, 11, 42, }, + { 1, 0, 0, 1, 11, 42, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 42, }, + { 1, 0, 0, 1, 12, 42, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 42, }, + { 1, 0, 0, 1, 13, 42, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 32, }, + { 2, 0, 0, 2, 1, 42, }, + { 1, 0, 0, 2, 1, 42, }, + { 0, 0, 0, 2, 2, 40, }, + { 2, 0, 0, 2, 2, 42, }, + { 1, 0, 0, 2, 2, 42, }, + { 0, 0, 0, 2, 3, 40, }, + { 2, 0, 0, 2, 3, 42, }, + { 1, 0, 0, 2, 3, 42, }, + { 0, 0, 0, 2, 4, 40, }, + { 2, 0, 0, 2, 4, 42, }, + { 1, 0, 0, 2, 4, 42, }, + { 0, 0, 0, 2, 5, 40, }, + { 2, 0, 0, 2, 5, 42, }, + { 1, 0, 0, 2, 5, 42, }, + { 0, 0, 0, 2, 6, 40, }, + { 2, 0, 0, 2, 6, 42, }, + { 1, 0, 0, 2, 6, 42, }, + { 0, 0, 0, 2, 7, 40, }, + { 2, 0, 0, 2, 7, 42, }, + { 1, 0, 0, 2, 7, 42, }, + { 0, 0, 0, 2, 8, 40, }, + { 2, 0, 0, 2, 8, 42, }, + { 1, 0, 0, 2, 8, 42, }, + { 0, 0, 0, 2, 9, 40, }, + { 2, 0, 0, 2, 9, 42, }, + { 1, 0, 0, 2, 9, 42, }, + { 0, 0, 0, 2, 10, 40, }, + { 2, 0, 0, 2, 10, 42, }, + { 1, 0, 0, 2, 10, 42, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 42, }, + { 1, 0, 0, 2, 11, 42, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 42, }, + { 1, 0, 0, 2, 12, 42, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 42, }, + { 1, 0, 0, 2, 13, 42, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 40, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 40, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 40, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 40, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 40, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 40, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 40, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 40, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 40, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 28, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 32, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 40, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 40, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 40, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 40, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 40, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 40, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 40, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 40, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 40, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 28, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 32, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 40, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 40, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 40, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 40, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 40, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 40, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 40, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 40, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 40, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 28, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 30, }, + { 2, 0, 1, 2, 3, 34, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 34, }, + { 2, 0, 1, 2, 4, 34, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 34, }, + { 2, 0, 1, 2, 5, 34, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 34, }, + { 2, 0, 1, 2, 6, 34, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 34, }, + { 2, 0, 1, 2, 7, 34, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 34, }, + { 2, 0, 1, 2, 8, 34, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 34, }, + { 2, 0, 1, 2, 9, 34, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 34, }, + { 2, 0, 1, 2, 10, 34, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 34, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 34, }, + { 1, 0, 1, 2, 12, 34, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 34, }, + { 1, 0, 1, 2, 13, 34, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 34, }, + { 1, 0, 1, 3, 3, 34, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 34, }, + { 1, 0, 1, 3, 4, 34, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 34, }, + { 1, 0, 1, 3, 5, 34, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 34, }, + { 1, 0, 1, 3, 6, 34, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 34, }, + { 1, 0, 1, 3, 7, 34, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 34, }, + { 1, 0, 1, 3, 8, 34, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 34, }, + { 1, 0, 1, 3, 9, 34, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 34, }, + { 1, 0, 1, 3, 10, 34, }, + { 0, 0, 1, 3, 11, 28, }, + { 2, 0, 1, 3, 11, 34, }, + { 1, 0, 1, 3, 11, 34, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 34, }, + { 1, 0, 1, 3, 12, 34, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 34, }, + { 1, 0, 1, 3, 13, 34, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 30, }, + { 2, 0, 1, 6, 3, 34, }, + { 1, 0, 1, 6, 3, 34, }, + { 0, 0, 1, 6, 4, 34, }, + { 2, 0, 1, 6, 4, 34, }, + { 1, 0, 1, 6, 4, 34, }, + { 0, 0, 1, 6, 5, 34, }, + { 2, 0, 1, 6, 5, 34, }, + { 1, 0, 1, 6, 5, 34, }, + { 0, 0, 1, 6, 6, 34, }, + { 2, 0, 1, 6, 6, 34, }, + { 1, 0, 1, 6, 6, 34, }, + { 0, 0, 1, 6, 7, 34, }, + { 2, 0, 1, 6, 7, 34, }, + { 1, 0, 1, 6, 7, 34, }, + { 0, 0, 1, 6, 8, 34, }, + { 2, 0, 1, 6, 8, 34, }, + { 1, 0, 1, 6, 8, 34, }, + { 0, 0, 1, 6, 9, 34, }, + { 2, 0, 1, 6, 9, 34, }, + { 1, 0, 1, 6, 9, 34, }, + { 0, 0, 1, 6, 10, 34, }, + { 2, 0, 1, 6, 10, 34, }, + { 1, 0, 1, 6, 10, 34, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 34, }, + { 1, 0, 1, 6, 11, 34, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 34, }, + { 1, 0, 1, 6, 12, 34, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 34, }, + { 1, 0, 1, 6, 13, 34, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 30, }, + { 2, 0, 1, 7, 3, 34, }, + { 1, 0, 1, 7, 3, 34, }, + { 0, 0, 1, 7, 4, 34, }, + { 2, 0, 1, 7, 4, 34, }, + { 1, 0, 1, 7, 4, 34, }, + { 0, 0, 1, 7, 5, 34, }, + { 2, 0, 1, 7, 5, 34, }, + { 1, 0, 1, 7, 5, 34, }, + { 0, 0, 1, 7, 6, 34, }, + { 2, 0, 1, 7, 6, 34, }, + { 1, 0, 1, 7, 6, 34, }, + { 0, 0, 1, 7, 7, 34, }, + { 2, 0, 1, 7, 7, 34, }, + { 1, 0, 1, 7, 7, 34, }, + { 0, 0, 1, 7, 8, 34, }, + { 2, 0, 1, 7, 8, 34, }, + { 1, 0, 1, 7, 8, 34, }, + { 0, 0, 1, 7, 9, 34, }, + { 2, 0, 1, 7, 9, 34, }, + { 1, 0, 1, 7, 9, 34, }, + { 0, 0, 1, 7, 10, 34, }, + { 2, 0, 1, 7, 10, 34, }, + { 1, 0, 1, 7, 10, 34, }, + { 0, 0, 1, 7, 11, 28, }, + { 2, 0, 1, 7, 11, 34, }, + { 1, 0, 1, 7, 11, 34, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 34, }, + { 1, 0, 1, 7, 12, 34, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 34, }, + { 1, 0, 1, 7, 13, 34, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 42, }, + { 2, 1, 0, 1, 36, 42, }, + { 1, 1, 0, 1, 36, 42, }, + { 0, 1, 0, 1, 40, 42, }, + { 2, 1, 0, 1, 40, 42, }, + { 1, 1, 0, 1, 40, 42, }, + { 0, 1, 0, 1, 44, 42, }, + { 2, 1, 0, 1, 44, 42, }, + { 1, 1, 0, 1, 44, 42, }, + { 0, 1, 0, 1, 48, 42, }, + { 2, 1, 0, 1, 48, 42, }, + { 1, 1, 0, 1, 48, 42, }, + { 0, 1, 0, 1, 52, 42, }, + { 2, 1, 0, 1, 52, 42, }, + { 1, 1, 0, 1, 52, 42, }, + { 0, 1, 0, 1, 56, 42, }, + { 2, 1, 0, 1, 56, 42, }, + { 1, 1, 0, 1, 56, 42, }, + { 0, 1, 0, 1, 60, 42, }, + { 2, 1, 0, 1, 60, 42, }, + { 1, 1, 0, 1, 60, 42, }, + { 0, 1, 0, 1, 64, 42, }, + { 2, 1, 0, 1, 64, 42, }, + { 1, 1, 0, 1, 64, 42, }, + { 0, 1, 0, 1, 100, 42, }, + { 2, 1, 0, 1, 100, 42, }, + { 1, 1, 0, 1, 100, 42, }, + { 0, 1, 0, 1, 104, 42, }, + { 2, 1, 0, 1, 104, 42, }, + { 1, 1, 0, 1, 104, 42, }, + { 0, 1, 0, 1, 108, 42, }, + { 2, 1, 0, 1, 108, 42, }, + { 1, 1, 0, 1, 108, 42, }, + { 0, 1, 0, 1, 112, 42, }, + { 2, 1, 0, 1, 112, 42, }, + { 1, 1, 0, 1, 112, 42, }, + { 0, 1, 0, 1, 116, 42, }, + { 2, 1, 0, 1, 116, 42, }, + { 1, 1, 0, 1, 116, 42, }, + { 0, 1, 0, 1, 120, 42, }, + { 2, 1, 0, 1, 120, 42, }, + { 1, 1, 0, 1, 120, 42, }, + { 0, 1, 0, 1, 124, 42, }, + { 2, 1, 0, 1, 124, 42, }, + { 1, 1, 0, 1, 124, 42, }, + { 0, 1, 0, 1, 128, 42, }, + { 2, 1, 0, 1, 128, 42, }, + { 1, 1, 0, 1, 128, 42, }, + { 0, 1, 0, 1, 132, 42, }, + { 2, 1, 0, 1, 132, 42, }, + { 1, 1, 0, 1, 132, 42, }, + { 0, 1, 0, 1, 136, 42, }, + { 2, 1, 0, 1, 136, 42, }, + { 1, 1, 0, 1, 136, 42, }, + { 0, 1, 0, 1, 140, 40, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 44, }, + { 2, 1, 0, 1, 149, 44, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 44, }, + { 2, 1, 0, 1, 153, 44, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 44, }, + { 2, 1, 0, 1, 157, 44, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 44, }, + { 2, 1, 0, 1, 161, 44, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 44, }, + { 2, 1, 0, 1, 165, 44, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 32, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 36, }, + { 2, 1, 0, 2, 48, 36, }, + { 1, 1, 0, 2, 48, 36, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 36, }, + { 1, 1, 0, 2, 52, 36, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 32, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 32, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 30, }, + { 2, 1, 0, 2, 140, 30, }, + { 1, 1, 0, 2, 140, 30, }, + { 0, 1, 0, 2, 149, 40, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 40, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 40, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 40, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 42, }, + { 2, 1, 0, 2, 165, 42, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 32, }, + { 2, 1, 0, 3, 36, 32, }, + { 1, 1, 0, 3, 36, 32, }, + { 0, 1, 0, 3, 40, 32, }, + { 2, 1, 0, 3, 40, 32, }, + { 1, 1, 0, 3, 40, 32, }, + { 0, 1, 0, 3, 44, 32, }, + { 2, 1, 0, 3, 44, 32, }, + { 1, 1, 0, 3, 44, 32, }, + { 0, 1, 0, 3, 48, 36, }, + { 2, 1, 0, 3, 48, 36, }, + { 1, 1, 0, 3, 48, 36, }, + { 0, 1, 0, 3, 52, 36, }, + { 2, 1, 0, 3, 52, 36, }, + { 1, 1, 0, 3, 52, 36, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 32, }, + { 1, 1, 0, 3, 56, 32, }, + { 0, 1, 0, 3, 60, 32, }, + { 2, 1, 0, 3, 60, 32, }, + { 1, 1, 0, 3, 60, 32, }, + { 0, 1, 0, 3, 64, 32, }, + { 2, 1, 0, 3, 64, 32, }, + { 1, 1, 0, 3, 64, 32, }, + { 0, 1, 0, 3, 100, 32, }, + { 2, 1, 0, 3, 100, 32, }, + { 1, 1, 0, 3, 100, 32, }, + { 0, 1, 0, 3, 104, 32, }, + { 2, 1, 0, 3, 104, 32, }, + { 1, 1, 0, 3, 104, 32, }, + { 0, 1, 0, 3, 108, 32, }, + { 2, 1, 0, 3, 108, 32, }, + { 1, 1, 0, 3, 108, 32, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 32, }, + { 1, 1, 0, 3, 112, 32, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 32, }, + { 1, 1, 0, 3, 116, 32, }, + { 0, 1, 0, 3, 120, 32, }, + { 2, 1, 0, 3, 120, 32, }, + { 1, 1, 0, 3, 120, 32, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 32, }, + { 1, 1, 0, 3, 124, 32, }, + { 0, 1, 0, 3, 128, 32, }, + { 2, 1, 0, 3, 128, 32, }, + { 1, 1, 0, 3, 128, 32, }, + { 0, 1, 0, 3, 132, 32, }, + { 2, 1, 0, 3, 132, 32, }, + { 1, 1, 0, 3, 132, 32, }, + { 0, 1, 0, 3, 136, 32, }, + { 2, 1, 0, 3, 136, 32, }, + { 1, 1, 0, 3, 136, 32, }, + { 0, 1, 0, 3, 140, 30, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 40, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 40, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 40, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 40, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 42, }, + { 2, 1, 0, 3, 165, 42, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 32, }, + { 2, 1, 0, 6, 36, 32, }, + { 1, 1, 0, 6, 36, 32, }, + { 0, 1, 0, 6, 40, 32, }, + { 2, 1, 0, 6, 40, 32, }, + { 1, 1, 0, 6, 40, 32, }, + { 0, 1, 0, 6, 44, 32, }, + { 2, 1, 0, 6, 44, 32, }, + { 1, 1, 0, 6, 44, 32, }, + { 0, 1, 0, 6, 48, 36, }, + { 2, 1, 0, 6, 48, 36, }, + { 1, 1, 0, 6, 48, 36, }, + { 0, 1, 0, 6, 52, 36, }, + { 2, 1, 0, 6, 52, 36, }, + { 1, 1, 0, 6, 52, 36, }, + { 0, 1, 0, 6, 56, 32, }, + { 2, 1, 0, 6, 56, 32, }, + { 1, 1, 0, 6, 56, 32, }, + { 0, 1, 0, 6, 60, 32, }, + { 2, 1, 0, 6, 60, 32, }, + { 1, 1, 0, 6, 60, 32, }, + { 0, 1, 0, 6, 64, 32, }, + { 2, 1, 0, 6, 64, 32, }, + { 1, 1, 0, 6, 64, 32, }, + { 0, 1, 0, 6, 100, 32, }, + { 2, 1, 0, 6, 100, 32, }, + { 1, 1, 0, 6, 100, 32, }, + { 0, 1, 0, 6, 104, 32, }, + { 2, 1, 0, 6, 104, 32, }, + { 1, 1, 0, 6, 104, 32, }, + { 0, 1, 0, 6, 108, 32, }, + { 2, 1, 0, 6, 108, 32, }, + { 1, 1, 0, 6, 108, 32, }, + { 0, 1, 0, 6, 112, 32, }, + { 2, 1, 0, 6, 112, 32, }, + { 1, 1, 0, 6, 112, 32, }, + { 0, 1, 0, 6, 116, 32, }, + { 2, 1, 0, 6, 116, 32, }, + { 1, 1, 0, 6, 116, 32, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 32, }, + { 1, 1, 0, 6, 120, 32, }, + { 0, 1, 0, 6, 124, 32, }, + { 2, 1, 0, 6, 124, 32, }, + { 1, 1, 0, 6, 124, 32, }, + { 0, 1, 0, 6, 128, 32, }, + { 2, 1, 0, 6, 128, 32, }, + { 1, 1, 0, 6, 128, 32, }, + { 0, 1, 0, 6, 132, 32, }, + { 2, 1, 0, 6, 132, 32, }, + { 1, 1, 0, 6, 132, 32, }, + { 0, 1, 0, 6, 136, 32, }, + { 2, 1, 0, 6, 136, 32, }, + { 1, 1, 0, 6, 136, 32, }, + { 0, 1, 0, 6, 140, 30, }, + { 2, 1, 0, 6, 140, 30, }, + { 1, 1, 0, 6, 140, 30, }, + { 0, 1, 0, 6, 149, 40, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 40, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 40, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 40, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 42, }, + { 2, 1, 0, 6, 165, 42, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 32, }, + { 2, 1, 0, 7, 36, 32, }, + { 1, 1, 0, 7, 36, 32, }, + { 0, 1, 0, 7, 40, 32, }, + { 2, 1, 0, 7, 40, 32, }, + { 1, 1, 0, 7, 40, 32, }, + { 0, 1, 0, 7, 44, 32, }, + { 2, 1, 0, 7, 44, 32, }, + { 1, 1, 0, 7, 44, 32, }, + { 0, 1, 0, 7, 48, 36, }, + { 2, 1, 0, 7, 48, 36, }, + { 1, 1, 0, 7, 48, 36, }, + { 0, 1, 0, 7, 52, 36, }, + { 2, 1, 0, 7, 52, 36, }, + { 1, 1, 0, 7, 52, 36, }, + { 0, 1, 0, 7, 56, 32, }, + { 2, 1, 0, 7, 56, 32, }, + { 1, 1, 0, 7, 56, 32, }, + { 0, 1, 0, 7, 60, 32, }, + { 2, 1, 0, 7, 60, 32, }, + { 1, 1, 0, 7, 60, 32, }, + { 0, 1, 0, 7, 64, 32, }, + { 2, 1, 0, 7, 64, 32, }, + { 1, 1, 0, 7, 64, 32, }, + { 0, 1, 0, 7, 100, 32, }, + { 2, 1, 0, 7, 100, 32, }, + { 1, 1, 0, 7, 100, 32, }, + { 0, 1, 0, 7, 104, 32, }, + { 2, 1, 0, 7, 104, 32, }, + { 1, 1, 0, 7, 104, 32, }, + { 0, 1, 0, 7, 108, 32, }, + { 2, 1, 0, 7, 108, 32, }, + { 1, 1, 0, 7, 108, 32, }, + { 0, 1, 0, 7, 112, 32, }, + { 2, 1, 0, 7, 112, 32, }, + { 1, 1, 0, 7, 112, 32, }, + { 0, 1, 0, 7, 116, 32, }, + { 2, 1, 0, 7, 116, 32, }, + { 1, 1, 0, 7, 116, 32, }, + { 0, 1, 0, 7, 120, 32, }, + { 2, 1, 0, 7, 120, 32, }, + { 1, 1, 0, 7, 120, 32, }, + { 0, 1, 0, 7, 124, 32, }, + { 2, 1, 0, 7, 124, 32, }, + { 1, 1, 0, 7, 124, 32, }, + { 0, 1, 0, 7, 128, 32, }, + { 2, 1, 0, 7, 128, 32, }, + { 1, 1, 0, 7, 128, 32, }, + { 0, 1, 0, 7, 132, 32, }, + { 2, 1, 0, 7, 132, 32, }, + { 1, 1, 0, 7, 132, 32, }, + { 0, 1, 0, 7, 136, 32, }, + { 2, 1, 0, 7, 136, 32, }, + { 1, 1, 0, 7, 136, 32, }, + { 0, 1, 0, 7, 140, 30, }, + { 2, 1, 0, 7, 140, 30, }, + { 1, 1, 0, 7, 140, 30, }, + { 0, 1, 0, 7, 149, 40, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 40, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 40, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 40, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 42, }, + { 2, 1, 0, 7, 165, 42, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 32, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 36, }, + { 2, 1, 1, 2, 46, 36, }, + { 1, 1, 1, 2, 46, 36, }, + { 0, 1, 1, 2, 54, 36, }, + { 2, 1, 1, 2, 54, 36, }, + { 1, 1, 1, 2, 54, 36, }, + { 0, 1, 1, 2, 62, 32, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 30, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 36, }, + { 2, 1, 1, 2, 134, 36, }, + { 1, 1, 1, 2, 134, 36, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 36, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 40, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 32, }, + { 2, 1, 1, 3, 38, 32, }, + { 1, 1, 1, 3, 38, 32, }, + { 0, 1, 1, 3, 46, 36, }, + { 2, 1, 1, 3, 46, 36, }, + { 1, 1, 1, 3, 46, 36, }, + { 0, 1, 1, 3, 54, 36, }, + { 2, 1, 1, 3, 54, 36, }, + { 1, 1, 1, 3, 54, 36, }, + { 0, 1, 1, 3, 62, 32, }, + { 2, 1, 1, 3, 62, 32, }, + { 1, 1, 1, 3, 62, 32, }, + { 0, 1, 1, 3, 102, 30, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 32, }, + { 2, 1, 1, 3, 110, 32, }, + { 1, 1, 1, 3, 110, 32, }, + { 0, 1, 1, 3, 118, 32, }, + { 2, 1, 1, 3, 118, 32, }, + { 1, 1, 1, 3, 118, 32, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 32, }, + { 1, 1, 1, 3, 126, 32, }, + { 0, 1, 1, 3, 134, 36, }, + { 2, 1, 1, 3, 134, 36, }, + { 1, 1, 1, 3, 134, 36, }, + { 0, 1, 1, 3, 151, 36, }, + { 2, 1, 1, 3, 151, 36, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 40, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 32, }, + { 2, 1, 1, 6, 38, 32, }, + { 1, 1, 1, 6, 38, 32, }, + { 0, 1, 1, 6, 46, 36, }, + { 2, 1, 1, 6, 46, 36, }, + { 1, 1, 1, 6, 46, 36, }, + { 0, 1, 1, 6, 54, 36, }, + { 2, 1, 1, 6, 54, 36, }, + { 1, 1, 1, 6, 54, 36, }, + { 0, 1, 1, 6, 62, 32, }, + { 2, 1, 1, 6, 62, 32, }, + { 1, 1, 1, 6, 62, 32, }, + { 0, 1, 1, 6, 102, 30, }, + { 2, 1, 1, 6, 102, 30, }, + { 1, 1, 1, 6, 102, 30, }, + { 0, 1, 1, 6, 110, 32, }, + { 2, 1, 1, 6, 110, 32, }, + { 1, 1, 1, 6, 110, 32, }, + { 0, 1, 1, 6, 118, 32, }, + { 2, 1, 1, 6, 118, 32, }, + { 1, 1, 1, 6, 118, 32, }, + { 0, 1, 1, 6, 126, 32, }, + { 2, 1, 1, 6, 126, 32, }, + { 1, 1, 1, 6, 126, 32, }, + { 0, 1, 1, 6, 134, 36, }, + { 2, 1, 1, 6, 134, 36, }, + { 1, 1, 1, 6, 134, 36, }, + { 0, 1, 1, 6, 151, 36, }, + { 2, 1, 1, 6, 151, 36, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 40, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 32, }, + { 2, 1, 1, 7, 38, 32, }, + { 1, 1, 1, 7, 38, 32, }, + { 0, 1, 1, 7, 46, 36, }, + { 2, 1, 1, 7, 46, 36, }, + { 1, 1, 1, 7, 46, 36, }, + { 0, 1, 1, 7, 54, 36, }, + { 2, 1, 1, 7, 54, 36, }, + { 1, 1, 1, 7, 54, 36, }, + { 0, 1, 1, 7, 62, 32, }, + { 2, 1, 1, 7, 62, 32, }, + { 1, 1, 1, 7, 62, 32, }, + { 0, 1, 1, 7, 102, 30, }, + { 2, 1, 1, 7, 102, 30, }, + { 1, 1, 1, 7, 102, 30, }, + { 0, 1, 1, 7, 110, 32, }, + { 2, 1, 1, 7, 110, 32, }, + { 1, 1, 1, 7, 110, 32, }, + { 0, 1, 1, 7, 118, 32, }, + { 2, 1, 1, 7, 118, 32, }, + { 1, 1, 1, 7, 118, 32, }, + { 0, 1, 1, 7, 126, 32, }, + { 2, 1, 1, 7, 126, 32, }, + { 1, 1, 1, 7, 126, 32, }, + { 0, 1, 1, 7, 134, 36, }, + { 2, 1, 1, 7, 134, 36, }, + { 1, 1, 1, 7, 134, 36, }, + { 0, 1, 1, 7, 151, 36, }, + { 2, 1, 1, 7, 151, 36, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 40, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 34, }, + { 2, 1, 2, 4, 42, 34, }, + { 1, 1, 2, 4, 42, 34, }, + { 0, 1, 2, 4, 58, 34, }, + { 2, 1, 2, 4, 58, 34, }, + { 1, 1, 2, 4, 58, 34, }, + { 0, 1, 2, 4, 106, 32, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 34, }, + { 2, 1, 2, 4, 122, 34, }, + { 1, 1, 2, 4, 122, 34, }, + { 0, 1, 2, 4, 155, 34, }, + { 2, 1, 2, 4, 155, 34, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 34, }, + { 2, 1, 2, 5, 42, 34, }, + { 1, 1, 2, 5, 42, 34, }, + { 0, 1, 2, 5, 58, 34, }, + { 2, 1, 2, 5, 58, 34, }, + { 1, 1, 2, 5, 58, 34, }, + { 0, 1, 2, 5, 106, 32, }, + { 2, 1, 2, 5, 106, 32, }, + { 1, 1, 2, 5, 106, 32, }, + { 0, 1, 2, 5, 122, 34, }, + { 2, 1, 2, 5, 122, 34, }, + { 1, 1, 2, 5, 122, 34, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 34, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 34, }, + { 2, 1, 2, 8, 42, 34, }, + { 1, 1, 2, 8, 42, 34, }, + { 0, 1, 2, 8, 58, 34, }, + { 2, 1, 2, 8, 58, 34, }, + { 1, 1, 2, 8, 58, 34, }, + { 0, 1, 2, 8, 106, 32, }, + { 2, 1, 2, 8, 106, 32, }, + { 1, 1, 2, 8, 106, 32, }, + { 0, 1, 2, 8, 122, 34, }, + { 2, 1, 2, 8, 122, 34, }, + { 1, 1, 2, 8, 122, 34, }, + { 0, 1, 2, 8, 155, 34, }, + { 2, 1, 2, 8, 155, 34, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 34, }, + { 2, 1, 2, 9, 42, 34, }, + { 1, 1, 2, 9, 42, 34, }, + { 0, 1, 2, 9, 58, 34, }, + { 2, 1, 2, 9, 58, 34, }, + { 1, 1, 2, 9, 58, 34, }, + { 0, 1, 2, 9, 106, 32, }, + { 2, 1, 2, 9, 106, 32, }, + { 1, 1, 2, 9, 106, 32, }, + { 0, 1, 2, 9, 122, 34, }, + { 2, 1, 2, 9, 122, 34, }, + { 1, 1, 2, 9, 122, 34, }, + { 0, 1, 2, 9, 155, 34, }, + { 2, 1, 2, 9, 155, 34, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type2); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type3[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 40, }, + { 1, 0, 0, 0, 1, 40, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 40, }, + { 1, 0, 0, 0, 2, 40, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 40, }, + { 1, 0, 0, 0, 3, 40, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 40, }, + { 1, 0, 0, 0, 4, 40, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 40, }, + { 1, 0, 0, 0, 5, 40, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 40, }, + { 1, 0, 0, 0, 6, 40, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 40, }, + { 1, 0, 0, 0, 7, 40, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 40, }, + { 1, 0, 0, 0, 8, 40, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 40, }, + { 1, 0, 0, 0, 9, 40, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 40, }, + { 1, 0, 0, 0, 10, 40, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 40, }, + { 1, 0, 0, 0, 11, 40, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 40, }, + { 1, 0, 0, 0, 12, 40, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 40, }, + { 1, 0, 0, 0, 13, 40, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 40, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 40, }, + { 1, 0, 0, 1, 1, 40, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 40, }, + { 1, 0, 0, 1, 2, 40, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 40, }, + { 1, 0, 0, 1, 3, 40, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 40, }, + { 1, 0, 0, 1, 4, 40, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 40, }, + { 1, 0, 0, 1, 5, 40, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 40, }, + { 1, 0, 0, 1, 6, 40, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 40, }, + { 1, 0, 0, 1, 7, 40, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 40, }, + { 1, 0, 0, 1, 8, 40, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 40, }, + { 1, 0, 0, 1, 9, 40, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 40, }, + { 1, 0, 0, 1, 10, 40, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 40, }, + { 1, 0, 0, 1, 11, 40, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 40, }, + { 1, 0, 0, 1, 12, 40, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 40, }, + { 1, 0, 0, 1, 13, 40, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 40, }, + { 1, 0, 0, 2, 1, 40, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 40, }, + { 1, 0, 0, 2, 2, 40, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 40, }, + { 1, 0, 0, 2, 3, 40, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 40, }, + { 1, 0, 0, 2, 4, 40, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 40, }, + { 1, 0, 0, 2, 5, 40, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 40, }, + { 1, 0, 0, 2, 6, 40, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 40, }, + { 1, 0, 0, 2, 7, 40, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 40, }, + { 1, 0, 0, 2, 8, 40, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 40, }, + { 1, 0, 0, 2, 9, 40, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 40, }, + { 1, 0, 0, 2, 10, 40, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 40, }, + { 1, 0, 0, 2, 11, 40, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 40, }, + { 1, 0, 0, 2, 12, 40, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 40, }, + { 1, 0, 0, 2, 13, 40, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 46, }, + { 2, 0, 1, 2, 3, 40, }, + { 1, 0, 1, 2, 3, 40, }, + { 0, 0, 1, 2, 4, 46, }, + { 2, 0, 1, 2, 4, 40, }, + { 1, 0, 1, 2, 4, 40, }, + { 0, 0, 1, 2, 5, 46, }, + { 2, 0, 1, 2, 5, 40, }, + { 1, 0, 1, 2, 5, 40, }, + { 0, 0, 1, 2, 6, 46, }, + { 2, 0, 1, 2, 6, 40, }, + { 1, 0, 1, 2, 6, 40, }, + { 0, 0, 1, 2, 7, 46, }, + { 2, 0, 1, 2, 7, 40, }, + { 1, 0, 1, 2, 7, 40, }, + { 0, 0, 1, 2, 8, 46, }, + { 2, 0, 1, 2, 8, 40, }, + { 1, 0, 1, 2, 8, 40, }, + { 0, 0, 1, 2, 9, 46, }, + { 2, 0, 1, 2, 9, 40, }, + { 1, 0, 1, 2, 9, 40, }, + { 0, 0, 1, 2, 10, 46, }, + { 2, 0, 1, 2, 10, 40, }, + { 1, 0, 1, 2, 10, 40, }, + { 0, 0, 1, 2, 11, 46, }, + { 2, 0, 1, 2, 11, 40, }, + { 1, 0, 1, 2, 11, 40, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 40, }, + { 1, 0, 1, 2, 12, 40, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 40, }, + { 1, 0, 1, 2, 13, 40, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 46, }, + { 2, 0, 1, 3, 3, 40, }, + { 1, 0, 1, 3, 3, 40, }, + { 0, 0, 1, 3, 4, 46, }, + { 2, 0, 1, 3, 4, 40, }, + { 1, 0, 1, 3, 4, 40, }, + { 0, 0, 1, 3, 5, 46, }, + { 2, 0, 1, 3, 5, 40, }, + { 1, 0, 1, 3, 5, 40, }, + { 0, 0, 1, 3, 6, 46, }, + { 2, 0, 1, 3, 6, 40, }, + { 1, 0, 1, 3, 6, 40, }, + { 0, 0, 1, 3, 7, 46, }, + { 2, 0, 1, 3, 7, 40, }, + { 1, 0, 1, 3, 7, 40, }, + { 0, 0, 1, 3, 8, 46, }, + { 2, 0, 1, 3, 8, 40, }, + { 1, 0, 1, 3, 8, 40, }, + { 0, 0, 1, 3, 9, 46, }, + { 2, 0, 1, 3, 9, 40, }, + { 1, 0, 1, 3, 9, 40, }, + { 0, 0, 1, 3, 10, 46, }, + { 2, 0, 1, 3, 10, 40, }, + { 1, 0, 1, 3, 10, 40, }, + { 0, 0, 1, 3, 11, 46, }, + { 2, 0, 1, 3, 11, 40, }, + { 1, 0, 1, 3, 11, 40, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 40, }, + { 1, 0, 1, 3, 12, 40, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 40, }, + { 1, 0, 1, 3, 13, 40, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 46, }, + { 2, 0, 1, 6, 3, 40, }, + { 1, 0, 1, 6, 3, 40, }, + { 0, 0, 1, 6, 4, 46, }, + { 2, 0, 1, 6, 4, 40, }, + { 1, 0, 1, 6, 4, 40, }, + { 0, 0, 1, 6, 5, 46, }, + { 2, 0, 1, 6, 5, 40, }, + { 1, 0, 1, 6, 5, 40, }, + { 0, 0, 1, 6, 6, 46, }, + { 2, 0, 1, 6, 6, 40, }, + { 1, 0, 1, 6, 6, 40, }, + { 0, 0, 1, 6, 7, 46, }, + { 2, 0, 1, 6, 7, 40, }, + { 1, 0, 1, 6, 7, 40, }, + { 0, 0, 1, 6, 8, 46, }, + { 2, 0, 1, 6, 8, 40, }, + { 1, 0, 1, 6, 8, 40, }, + { 0, 0, 1, 6, 9, 46, }, + { 2, 0, 1, 6, 9, 40, }, + { 1, 0, 1, 6, 9, 40, }, + { 0, 0, 1, 6, 10, 46, }, + { 2, 0, 1, 6, 10, 40, }, + { 1, 0, 1, 6, 10, 40, }, + { 0, 0, 1, 6, 11, 46, }, + { 2, 0, 1, 6, 11, 40, }, + { 1, 0, 1, 6, 11, 40, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 40, }, + { 1, 0, 1, 6, 12, 40, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 40, }, + { 1, 0, 1, 6, 13, 40, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 46, }, + { 2, 0, 1, 7, 3, 40, }, + { 1, 0, 1, 7, 3, 40, }, + { 0, 0, 1, 7, 4, 46, }, + { 2, 0, 1, 7, 4, 40, }, + { 1, 0, 1, 7, 4, 40, }, + { 0, 0, 1, 7, 5, 46, }, + { 2, 0, 1, 7, 5, 40, }, + { 1, 0, 1, 7, 5, 40, }, + { 0, 0, 1, 7, 6, 46, }, + { 2, 0, 1, 7, 6, 40, }, + { 1, 0, 1, 7, 6, 40, }, + { 0, 0, 1, 7, 7, 46, }, + { 2, 0, 1, 7, 7, 40, }, + { 1, 0, 1, 7, 7, 40, }, + { 0, 0, 1, 7, 8, 46, }, + { 2, 0, 1, 7, 8, 40, }, + { 1, 0, 1, 7, 8, 40, }, + { 0, 0, 1, 7, 9, 46, }, + { 2, 0, 1, 7, 9, 40, }, + { 1, 0, 1, 7, 9, 40, }, + { 0, 0, 1, 7, 10, 46, }, + { 2, 0, 1, 7, 10, 40, }, + { 1, 0, 1, 7, 10, 40, }, + { 0, 0, 1, 7, 11, 46, }, + { 2, 0, 1, 7, 11, 40, }, + { 1, 0, 1, 7, 11, 40, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 40, }, + { 1, 0, 1, 7, 12, 40, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 40, }, + { 1, 0, 1, 7, 13, 40, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 40, }, + { 1, 1, 0, 1, 36, 40, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 40, }, + { 1, 1, 0, 1, 40, 40, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 40, }, + { 1, 1, 0, 1, 44, 40, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 40, }, + { 1, 1, 0, 1, 48, 40, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 40, }, + { 1, 1, 0, 1, 52, 40, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 40, }, + { 1, 1, 0, 1, 56, 40, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 40, }, + { 1, 1, 0, 1, 60, 40, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 40, }, + { 1, 1, 0, 1, 64, 40, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 40, }, + { 1, 1, 0, 1, 100, 40, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 40, }, + { 1, 1, 0, 1, 104, 40, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 40, }, + { 1, 1, 0, 1, 108, 40, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 40, }, + { 1, 1, 0, 1, 112, 40, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 40, }, + { 1, 1, 0, 1, 116, 40, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 40, }, + { 1, 1, 0, 1, 120, 40, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 40, }, + { 1, 1, 0, 1, 124, 40, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 40, }, + { 1, 1, 0, 1, 128, 40, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 40, }, + { 1, 1, 0, 1, 132, 40, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 40, }, + { 1, 1, 0, 1, 136, 40, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 40, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 40, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 40, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 40, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 40, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 40, }, + { 1, 1, 0, 2, 36, 40, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 40, }, + { 1, 1, 0, 2, 40, 40, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 40, }, + { 1, 1, 0, 2, 44, 40, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 40, }, + { 1, 1, 0, 2, 48, 40, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 40, }, + { 1, 1, 0, 2, 52, 40, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 40, }, + { 1, 1, 0, 2, 56, 40, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 40, }, + { 1, 1, 0, 2, 60, 40, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 40, }, + { 1, 1, 0, 2, 64, 40, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 40, }, + { 1, 1, 0, 2, 100, 40, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 40, }, + { 1, 1, 0, 2, 104, 40, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 40, }, + { 1, 1, 0, 2, 108, 40, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 40, }, + { 1, 1, 0, 2, 112, 40, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 40, }, + { 1, 1, 0, 2, 116, 40, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 40, }, + { 1, 1, 0, 2, 120, 40, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 40, }, + { 1, 1, 0, 2, 124, 40, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 40, }, + { 1, 1, 0, 2, 128, 40, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 40, }, + { 1, 1, 0, 2, 132, 40, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 40, }, + { 1, 1, 0, 2, 136, 40, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 40, }, + { 1, 1, 0, 2, 140, 40, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 40, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 40, }, + { 1, 1, 0, 3, 36, 40, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 40, }, + { 1, 1, 0, 3, 40, 40, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 40, }, + { 1, 1, 0, 3, 44, 40, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 40, }, + { 1, 1, 0, 3, 48, 40, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 40, }, + { 1, 1, 0, 3, 52, 40, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 40, }, + { 1, 1, 0, 3, 56, 40, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 40, }, + { 1, 1, 0, 3, 60, 40, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 40, }, + { 1, 1, 0, 3, 64, 40, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 40, }, + { 1, 1, 0, 3, 100, 40, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 40, }, + { 1, 1, 0, 3, 104, 40, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 40, }, + { 1, 1, 0, 3, 108, 40, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 40, }, + { 1, 1, 0, 3, 112, 40, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 40, }, + { 1, 1, 0, 3, 116, 40, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 40, }, + { 1, 1, 0, 3, 120, 40, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 40, }, + { 1, 1, 0, 3, 124, 40, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 40, }, + { 1, 1, 0, 3, 128, 40, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 40, }, + { 1, 1, 0, 3, 132, 40, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 40, }, + { 1, 1, 0, 3, 136, 40, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 40, }, + { 1, 1, 0, 3, 140, 40, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 40, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 40, }, + { 1, 1, 0, 6, 36, 40, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 40, }, + { 1, 1, 0, 6, 40, 40, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 40, }, + { 1, 1, 0, 6, 44, 40, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 40, }, + { 1, 1, 0, 6, 48, 40, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 40, }, + { 1, 1, 0, 6, 52, 40, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 40, }, + { 1, 1, 0, 6, 56, 40, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 40, }, + { 1, 1, 0, 6, 60, 40, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 40, }, + { 1, 1, 0, 6, 64, 40, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 40, }, + { 1, 1, 0, 6, 100, 40, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 40, }, + { 1, 1, 0, 6, 104, 40, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 40, }, + { 1, 1, 0, 6, 108, 40, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 40, }, + { 1, 1, 0, 6, 112, 40, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 40, }, + { 1, 1, 0, 6, 116, 40, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 40, }, + { 1, 1, 0, 6, 120, 40, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 40, }, + { 1, 1, 0, 6, 124, 40, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 40, }, + { 1, 1, 0, 6, 128, 40, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 40, }, + { 1, 1, 0, 6, 132, 40, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 40, }, + { 1, 1, 0, 6, 136, 40, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 40, }, + { 1, 1, 0, 6, 140, 40, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 40, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 40, }, + { 1, 1, 0, 7, 36, 40, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 40, }, + { 1, 1, 0, 7, 40, 40, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 40, }, + { 1, 1, 0, 7, 44, 40, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 40, }, + { 1, 1, 0, 7, 48, 40, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 40, }, + { 1, 1, 0, 7, 52, 40, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 40, }, + { 1, 1, 0, 7, 56, 40, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 40, }, + { 1, 1, 0, 7, 60, 40, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 40, }, + { 1, 1, 0, 7, 64, 40, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 40, }, + { 1, 1, 0, 7, 100, 40, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 40, }, + { 1, 1, 0, 7, 104, 40, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 40, }, + { 1, 1, 0, 7, 108, 40, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 40, }, + { 1, 1, 0, 7, 112, 40, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 40, }, + { 1, 1, 0, 7, 116, 40, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 40, }, + { 1, 1, 0, 7, 120, 40, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 40, }, + { 1, 1, 0, 7, 124, 40, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 40, }, + { 1, 1, 0, 7, 128, 40, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 40, }, + { 1, 1, 0, 7, 132, 40, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 40, }, + { 1, 1, 0, 7, 136, 40, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 40, }, + { 1, 1, 0, 7, 140, 40, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 40, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 40, }, + { 1, 1, 1, 2, 38, 40, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 40, }, + { 1, 1, 1, 2, 46, 40, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 40, }, + { 1, 1, 1, 2, 54, 40, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 40, }, + { 1, 1, 1, 2, 62, 40, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 40, }, + { 1, 1, 1, 2, 102, 40, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 40, }, + { 1, 1, 1, 2, 110, 40, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 40, }, + { 1, 1, 1, 2, 118, 40, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 40, }, + { 1, 1, 1, 2, 126, 40, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 40, }, + { 1, 1, 1, 2, 134, 40, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 40, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 40, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 40, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 40, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 40, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 40, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 40, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 40, }, + { 1, 1, 1, 6, 38, 40, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 40, }, + { 1, 1, 1, 6, 46, 40, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 40, }, + { 1, 1, 1, 6, 54, 40, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 40, }, + { 1, 1, 1, 6, 62, 40, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 40, }, + { 1, 1, 1, 6, 102, 40, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 40, }, + { 1, 1, 1, 6, 110, 40, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 40, }, + { 1, 1, 1, 6, 118, 40, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 40, }, + { 1, 1, 1, 6, 126, 40, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 40, }, + { 1, 1, 1, 6, 134, 40, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 40, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 40, }, + { 1, 1, 1, 7, 38, 40, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 40, }, + { 1, 1, 1, 7, 46, 40, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 40, }, + { 1, 1, 1, 7, 54, 40, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 40, }, + { 1, 1, 1, 7, 62, 40, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 40, }, + { 1, 1, 1, 7, 102, 40, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 40, }, + { 1, 1, 1, 7, 110, 40, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 40, }, + { 1, 1, 1, 7, 118, 40, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 40, }, + { 1, 1, 1, 7, 126, 40, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 40, }, + { 1, 1, 1, 7, 134, 40, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 40, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 40, }, + { 1, 1, 2, 4, 42, 40, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 40, }, + { 1, 1, 2, 4, 58, 40, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 40, }, + { 1, 1, 2, 4, 106, 40, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 40, }, + { 1, 1, 2, 4, 122, 40, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 40, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 40, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 40, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 40, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 40, }, + { 1, 1, 2, 8, 42, 40, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 40, }, + { 1, 1, 2, 8, 58, 40, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 40, }, + { 1, 1, 2, 8, 106, 40, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 40, }, + { 1, 1, 2, 8, 122, 40, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 40, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 40, }, + { 1, 1, 2, 9, 42, 40, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 40, }, + { 1, 1, 2, 9, 58, 40, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 40, }, + { 1, 1, 2, 9, 106, 40, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 40, }, + { 1, 1, 2, 9, 122, 40, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 40, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type3); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type5[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 40, }, + { 1, 0, 0, 0, 1, 40, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 40, }, + { 1, 0, 0, 0, 2, 40, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 40, }, + { 1, 0, 0, 0, 3, 40, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 40, }, + { 1, 0, 0, 0, 4, 40, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 40, }, + { 1, 0, 0, 0, 5, 40, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 40, }, + { 1, 0, 0, 0, 6, 40, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 40, }, + { 1, 0, 0, 0, 7, 40, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 40, }, + { 1, 0, 0, 0, 8, 40, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 40, }, + { 1, 0, 0, 0, 9, 40, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 40, }, + { 1, 0, 0, 0, 10, 40, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 40, }, + { 1, 0, 0, 0, 11, 40, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 40, }, + { 1, 0, 0, 0, 12, 40, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 40, }, + { 1, 0, 0, 0, 13, 40, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 40, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 40, }, + { 1, 0, 0, 1, 1, 40, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 40, }, + { 1, 0, 0, 1, 2, 40, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 40, }, + { 1, 0, 0, 1, 3, 40, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 40, }, + { 1, 0, 0, 1, 4, 40, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 40, }, + { 1, 0, 0, 1, 5, 40, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 40, }, + { 1, 0, 0, 1, 6, 40, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 40, }, + { 1, 0, 0, 1, 7, 40, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 40, }, + { 1, 0, 0, 1, 8, 40, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 40, }, + { 1, 0, 0, 1, 9, 40, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 40, }, + { 1, 0, 0, 1, 10, 40, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 40, }, + { 1, 0, 0, 1, 11, 40, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 40, }, + { 1, 0, 0, 1, 12, 40, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 40, }, + { 1, 0, 0, 1, 13, 40, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 40, }, + { 1, 0, 0, 2, 1, 40, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 40, }, + { 1, 0, 0, 2, 2, 40, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 40, }, + { 1, 0, 0, 2, 3, 40, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 40, }, + { 1, 0, 0, 2, 4, 40, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 40, }, + { 1, 0, 0, 2, 5, 40, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 40, }, + { 1, 0, 0, 2, 6, 40, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 40, }, + { 1, 0, 0, 2, 7, 40, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 40, }, + { 1, 0, 0, 2, 8, 40, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 40, }, + { 1, 0, 0, 2, 9, 40, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 40, }, + { 1, 0, 0, 2, 10, 40, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 40, }, + { 1, 0, 0, 2, 11, 40, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 40, }, + { 1, 0, 0, 2, 12, 40, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 40, }, + { 1, 0, 0, 2, 13, 40, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 46, }, + { 2, 0, 1, 2, 3, 40, }, + { 1, 0, 1, 2, 3, 40, }, + { 0, 0, 1, 2, 4, 46, }, + { 2, 0, 1, 2, 4, 40, }, + { 1, 0, 1, 2, 4, 40, }, + { 0, 0, 1, 2, 5, 46, }, + { 2, 0, 1, 2, 5, 40, }, + { 1, 0, 1, 2, 5, 40, }, + { 0, 0, 1, 2, 6, 46, }, + { 2, 0, 1, 2, 6, 40, }, + { 1, 0, 1, 2, 6, 40, }, + { 0, 0, 1, 2, 7, 46, }, + { 2, 0, 1, 2, 7, 40, }, + { 1, 0, 1, 2, 7, 40, }, + { 0, 0, 1, 2, 8, 46, }, + { 2, 0, 1, 2, 8, 40, }, + { 1, 0, 1, 2, 8, 40, }, + { 0, 0, 1, 2, 9, 46, }, + { 2, 0, 1, 2, 9, 40, }, + { 1, 0, 1, 2, 9, 40, }, + { 0, 0, 1, 2, 10, 46, }, + { 2, 0, 1, 2, 10, 40, }, + { 1, 0, 1, 2, 10, 40, }, + { 0, 0, 1, 2, 11, 46, }, + { 2, 0, 1, 2, 11, 40, }, + { 1, 0, 1, 2, 11, 40, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 40, }, + { 1, 0, 1, 2, 12, 40, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 40, }, + { 1, 0, 1, 2, 13, 40, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 46, }, + { 2, 0, 1, 3, 3, 40, }, + { 1, 0, 1, 3, 3, 40, }, + { 0, 0, 1, 3, 4, 46, }, + { 2, 0, 1, 3, 4, 40, }, + { 1, 0, 1, 3, 4, 40, }, + { 0, 0, 1, 3, 5, 46, }, + { 2, 0, 1, 3, 5, 40, }, + { 1, 0, 1, 3, 5, 40, }, + { 0, 0, 1, 3, 6, 46, }, + { 2, 0, 1, 3, 6, 40, }, + { 1, 0, 1, 3, 6, 40, }, + { 0, 0, 1, 3, 7, 46, }, + { 2, 0, 1, 3, 7, 40, }, + { 1, 0, 1, 3, 7, 40, }, + { 0, 0, 1, 3, 8, 46, }, + { 2, 0, 1, 3, 8, 40, }, + { 1, 0, 1, 3, 8, 40, }, + { 0, 0, 1, 3, 9, 46, }, + { 2, 0, 1, 3, 9, 40, }, + { 1, 0, 1, 3, 9, 40, }, + { 0, 0, 1, 3, 10, 46, }, + { 2, 0, 1, 3, 10, 40, }, + { 1, 0, 1, 3, 10, 40, }, + { 0, 0, 1, 3, 11, 46, }, + { 2, 0, 1, 3, 11, 40, }, + { 1, 0, 1, 3, 11, 40, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 40, }, + { 1, 0, 1, 3, 12, 40, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 40, }, + { 1, 0, 1, 3, 13, 40, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 46, }, + { 2, 0, 1, 6, 3, 40, }, + { 1, 0, 1, 6, 3, 40, }, + { 0, 0, 1, 6, 4, 46, }, + { 2, 0, 1, 6, 4, 40, }, + { 1, 0, 1, 6, 4, 40, }, + { 0, 0, 1, 6, 5, 46, }, + { 2, 0, 1, 6, 5, 40, }, + { 1, 0, 1, 6, 5, 40, }, + { 0, 0, 1, 6, 6, 46, }, + { 2, 0, 1, 6, 6, 40, }, + { 1, 0, 1, 6, 6, 40, }, + { 0, 0, 1, 6, 7, 46, }, + { 2, 0, 1, 6, 7, 40, }, + { 1, 0, 1, 6, 7, 40, }, + { 0, 0, 1, 6, 8, 46, }, + { 2, 0, 1, 6, 8, 40, }, + { 1, 0, 1, 6, 8, 40, }, + { 0, 0, 1, 6, 9, 46, }, + { 2, 0, 1, 6, 9, 40, }, + { 1, 0, 1, 6, 9, 40, }, + { 0, 0, 1, 6, 10, 46, }, + { 2, 0, 1, 6, 10, 40, }, + { 1, 0, 1, 6, 10, 40, }, + { 0, 0, 1, 6, 11, 46, }, + { 2, 0, 1, 6, 11, 40, }, + { 1, 0, 1, 6, 11, 40, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 40, }, + { 1, 0, 1, 6, 12, 40, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 40, }, + { 1, 0, 1, 6, 13, 40, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 46, }, + { 2, 0, 1, 7, 3, 40, }, + { 1, 0, 1, 7, 3, 40, }, + { 0, 0, 1, 7, 4, 46, }, + { 2, 0, 1, 7, 4, 40, }, + { 1, 0, 1, 7, 4, 40, }, + { 0, 0, 1, 7, 5, 46, }, + { 2, 0, 1, 7, 5, 40, }, + { 1, 0, 1, 7, 5, 40, }, + { 0, 0, 1, 7, 6, 46, }, + { 2, 0, 1, 7, 6, 40, }, + { 1, 0, 1, 7, 6, 40, }, + { 0, 0, 1, 7, 7, 46, }, + { 2, 0, 1, 7, 7, 40, }, + { 1, 0, 1, 7, 7, 40, }, + { 0, 0, 1, 7, 8, 46, }, + { 2, 0, 1, 7, 8, 40, }, + { 1, 0, 1, 7, 8, 40, }, + { 0, 0, 1, 7, 9, 46, }, + { 2, 0, 1, 7, 9, 40, }, + { 1, 0, 1, 7, 9, 40, }, + { 0, 0, 1, 7, 10, 46, }, + { 2, 0, 1, 7, 10, 40, }, + { 1, 0, 1, 7, 10, 40, }, + { 0, 0, 1, 7, 11, 46, }, + { 2, 0, 1, 7, 11, 40, }, + { 1, 0, 1, 7, 11, 40, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 40, }, + { 1, 0, 1, 7, 12, 40, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 40, }, + { 1, 0, 1, 7, 13, 40, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 40, }, + { 1, 1, 0, 1, 36, 40, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 40, }, + { 1, 1, 0, 1, 40, 40, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 40, }, + { 1, 1, 0, 1, 44, 40, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 40, }, + { 1, 1, 0, 1, 48, 40, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 40, }, + { 1, 1, 0, 1, 52, 40, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 40, }, + { 1, 1, 0, 1, 56, 40, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 40, }, + { 1, 1, 0, 1, 60, 40, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 40, }, + { 1, 1, 0, 1, 64, 40, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 40, }, + { 1, 1, 0, 1, 100, 40, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 40, }, + { 1, 1, 0, 1, 104, 40, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 40, }, + { 1, 1, 0, 1, 108, 40, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 40, }, + { 1, 1, 0, 1, 112, 40, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 40, }, + { 1, 1, 0, 1, 116, 40, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 40, }, + { 1, 1, 0, 1, 120, 40, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 40, }, + { 1, 1, 0, 1, 124, 40, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 40, }, + { 1, 1, 0, 1, 128, 40, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 40, }, + { 1, 1, 0, 1, 132, 40, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 40, }, + { 1, 1, 0, 1, 136, 40, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 40, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 40, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 40, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 40, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 40, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 40, }, + { 1, 1, 0, 2, 36, 40, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 40, }, + { 1, 1, 0, 2, 40, 40, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 40, }, + { 1, 1, 0, 2, 44, 40, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 40, }, + { 1, 1, 0, 2, 48, 40, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 40, }, + { 1, 1, 0, 2, 52, 40, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 40, }, + { 1, 1, 0, 2, 56, 40, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 40, }, + { 1, 1, 0, 2, 60, 40, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 40, }, + { 1, 1, 0, 2, 64, 40, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 40, }, + { 1, 1, 0, 2, 100, 40, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 40, }, + { 1, 1, 0, 2, 104, 40, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 40, }, + { 1, 1, 0, 2, 108, 40, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 40, }, + { 1, 1, 0, 2, 112, 40, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 40, }, + { 1, 1, 0, 2, 116, 40, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 40, }, + { 1, 1, 0, 2, 120, 40, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 40, }, + { 1, 1, 0, 2, 124, 40, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 40, }, + { 1, 1, 0, 2, 128, 40, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 40, }, + { 1, 1, 0, 2, 132, 40, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 40, }, + { 1, 1, 0, 2, 136, 40, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 40, }, + { 1, 1, 0, 2, 140, 40, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 40, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 40, }, + { 1, 1, 0, 3, 36, 40, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 40, }, + { 1, 1, 0, 3, 40, 40, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 40, }, + { 1, 1, 0, 3, 44, 40, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 40, }, + { 1, 1, 0, 3, 48, 40, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 40, }, + { 1, 1, 0, 3, 52, 40, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 40, }, + { 1, 1, 0, 3, 56, 40, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 40, }, + { 1, 1, 0, 3, 60, 40, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 40, }, + { 1, 1, 0, 3, 64, 40, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 40, }, + { 1, 1, 0, 3, 100, 40, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 40, }, + { 1, 1, 0, 3, 104, 40, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 40, }, + { 1, 1, 0, 3, 108, 40, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 40, }, + { 1, 1, 0, 3, 112, 40, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 40, }, + { 1, 1, 0, 3, 116, 40, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 40, }, + { 1, 1, 0, 3, 120, 40, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 40, }, + { 1, 1, 0, 3, 124, 40, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 40, }, + { 1, 1, 0, 3, 128, 40, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 40, }, + { 1, 1, 0, 3, 132, 40, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 40, }, + { 1, 1, 0, 3, 136, 40, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 40, }, + { 1, 1, 0, 3, 140, 40, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 40, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 40, }, + { 1, 1, 0, 6, 36, 40, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 40, }, + { 1, 1, 0, 6, 40, 40, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 40, }, + { 1, 1, 0, 6, 44, 40, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 40, }, + { 1, 1, 0, 6, 48, 40, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 40, }, + { 1, 1, 0, 6, 52, 40, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 40, }, + { 1, 1, 0, 6, 56, 40, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 40, }, + { 1, 1, 0, 6, 60, 40, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 40, }, + { 1, 1, 0, 6, 64, 40, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 40, }, + { 1, 1, 0, 6, 100, 40, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 40, }, + { 1, 1, 0, 6, 104, 40, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 40, }, + { 1, 1, 0, 6, 108, 40, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 40, }, + { 1, 1, 0, 6, 112, 40, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 40, }, + { 1, 1, 0, 6, 116, 40, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 40, }, + { 1, 1, 0, 6, 120, 40, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 40, }, + { 1, 1, 0, 6, 124, 40, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 40, }, + { 1, 1, 0, 6, 128, 40, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 40, }, + { 1, 1, 0, 6, 132, 40, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 40, }, + { 1, 1, 0, 6, 136, 40, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 40, }, + { 1, 1, 0, 6, 140, 40, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 40, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 40, }, + { 1, 1, 0, 7, 36, 40, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 40, }, + { 1, 1, 0, 7, 40, 40, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 40, }, + { 1, 1, 0, 7, 44, 40, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 40, }, + { 1, 1, 0, 7, 48, 40, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 40, }, + { 1, 1, 0, 7, 52, 40, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 40, }, + { 1, 1, 0, 7, 56, 40, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 40, }, + { 1, 1, 0, 7, 60, 40, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 40, }, + { 1, 1, 0, 7, 64, 40, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 40, }, + { 1, 1, 0, 7, 100, 40, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 40, }, + { 1, 1, 0, 7, 104, 40, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 40, }, + { 1, 1, 0, 7, 108, 40, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 40, }, + { 1, 1, 0, 7, 112, 40, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 40, }, + { 1, 1, 0, 7, 116, 40, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 40, }, + { 1, 1, 0, 7, 120, 40, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 40, }, + { 1, 1, 0, 7, 124, 40, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 40, }, + { 1, 1, 0, 7, 128, 40, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 40, }, + { 1, 1, 0, 7, 132, 40, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 40, }, + { 1, 1, 0, 7, 136, 40, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 40, }, + { 1, 1, 0, 7, 140, 40, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 40, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 40, }, + { 1, 1, 1, 2, 38, 40, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 40, }, + { 1, 1, 1, 2, 46, 40, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 40, }, + { 1, 1, 1, 2, 54, 40, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 40, }, + { 1, 1, 1, 2, 62, 40, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 40, }, + { 1, 1, 1, 2, 102, 40, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 40, }, + { 1, 1, 1, 2, 110, 40, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 40, }, + { 1, 1, 1, 2, 118, 40, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 40, }, + { 1, 1, 1, 2, 126, 40, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 40, }, + { 1, 1, 1, 2, 134, 40, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 40, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 40, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 40, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 40, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 40, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 40, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 40, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 40, }, + { 1, 1, 1, 6, 38, 40, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 40, }, + { 1, 1, 1, 6, 46, 40, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 40, }, + { 1, 1, 1, 6, 54, 40, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 40, }, + { 1, 1, 1, 6, 62, 40, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 40, }, + { 1, 1, 1, 6, 102, 40, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 40, }, + { 1, 1, 1, 6, 110, 40, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 40, }, + { 1, 1, 1, 6, 118, 40, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 40, }, + { 1, 1, 1, 6, 126, 40, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 40, }, + { 1, 1, 1, 6, 134, 40, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 40, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 40, }, + { 1, 1, 1, 7, 38, 40, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 40, }, + { 1, 1, 1, 7, 46, 40, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 40, }, + { 1, 1, 1, 7, 54, 40, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 40, }, + { 1, 1, 1, 7, 62, 40, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 40, }, + { 1, 1, 1, 7, 102, 40, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 40, }, + { 1, 1, 1, 7, 110, 40, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 40, }, + { 1, 1, 1, 7, 118, 40, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 40, }, + { 1, 1, 1, 7, 126, 40, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 40, }, + { 1, 1, 1, 7, 134, 40, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 40, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 40, }, + { 1, 1, 2, 4, 42, 40, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 40, }, + { 1, 1, 2, 4, 58, 40, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 40, }, + { 1, 1, 2, 4, 106, 40, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 40, }, + { 1, 1, 2, 4, 122, 40, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 40, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 40, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 40, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 40, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 40, }, + { 1, 1, 2, 8, 42, 40, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 40, }, + { 1, 1, 2, 8, 58, 40, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 40, }, + { 1, 1, 2, 8, 106, 40, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 40, }, + { 1, 1, 2, 8, 122, 40, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 40, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 40, }, + { 1, 1, 2, 9, 42, 40, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 40, }, + { 1, 1, 2, 9, 58, 40, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 40, }, + { 1, 1, 2, 9, 106, 40, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 40, }, + { 1, 1, 2, 9, 122, 40, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 40, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type5); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type7[] = { + { 0, 0, 0, 0, 1, 44, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 52, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 52, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 52, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 52, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 52, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 52, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 52, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 52, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 52, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 44, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 38, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 38, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 34, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 34, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 44, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 44, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 44, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 44, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 44, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 44, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 44, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 44, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 44, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 32, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 30, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 42, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 42, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 42, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 42, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 42, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 42, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 42, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 42, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 42, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 30, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 28, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 40, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 40, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 40, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 40, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 40, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 40, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 40, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 40, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 40, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 28, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 36, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 40, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 40, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 40, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 40, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 40, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 40, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 40, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 34, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 34, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 38, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 38, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 38, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 38, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 38, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 38, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 38, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 32, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 32, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 36, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 36, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 36, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 36, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 36, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 36, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 36, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 30, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 32, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 36, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 36, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 36, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 36, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 36, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 36, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 36, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 30, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 38, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 38, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 38, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 38, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 38, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 38, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 38, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 38, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 36, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 36, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 36, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 36, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 36, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 36, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 36, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 36, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 36, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 36, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 36, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 36, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 36, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 36, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 36, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 36, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 36, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 36, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 36, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 36, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 36, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 36, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 36, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 36, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 36, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 36, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 36, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 36, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 36, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 36, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 36, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 36, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 36, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 34, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 38, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 38, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 38, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 38, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 34, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 34, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 34, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 34, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 34, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 34, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 34, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 34, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 34, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 34, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 34, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 34, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 34, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 34, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 34, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 34, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 32, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 30, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 36, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 36, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 36, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 36, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 32, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 32, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 32, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 32, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 32, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 32, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 32, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 32, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 32, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 32, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 32, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 32, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 32, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 32, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 32, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 32, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 32, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 30, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 28, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 34, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 34, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 34, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 34, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 30, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 30, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 30, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 30, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 30, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 30, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 30, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 30, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 30, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 30, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 30, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 30, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 30, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 30, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 30, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 30, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 30, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 30, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 28, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 26, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 32, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 32, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 32, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 32, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 32, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 30, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 30, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 38, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 38, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 38, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 38, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 32, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 30, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 28, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 28, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 36, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 36, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 36, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 36, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 30, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 28, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 28, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 26, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 26, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 34, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 34, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 34, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 34, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 28, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 28, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 26, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 26, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 24, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 24, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 32, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 32, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 32, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 32, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 26, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 26, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 26, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 26, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 28, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 28, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 28, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 24, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 24, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 26, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 26, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 26, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 22, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 22, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 24, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 24, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 24, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 20, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 20, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 22, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 22, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 22, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type7); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type8[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 46, }, + { 1, 0, 0, 0, 1, 46, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 46, }, + { 1, 0, 0, 0, 2, 46, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 46, }, + { 1, 0, 0, 0, 3, 46, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 46, }, + { 1, 0, 0, 0, 4, 46, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 46, }, + { 1, 0, 0, 0, 5, 46, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 46, }, + { 1, 0, 0, 0, 6, 46, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 46, }, + { 1, 0, 0, 0, 7, 46, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 46, }, + { 1, 0, 0, 0, 8, 46, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 46, }, + { 1, 0, 0, 0, 9, 46, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 46, }, + { 1, 0, 0, 0, 10, 46, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 46, }, + { 1, 0, 0, 0, 11, 46, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 46, }, + { 1, 0, 0, 0, 12, 46, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 46, }, + { 1, 0, 0, 0, 13, 46, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 46, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 46, }, + { 1, 0, 0, 1, 1, 46, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 46, }, + { 1, 0, 0, 1, 2, 46, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 46, }, + { 1, 0, 0, 1, 3, 46, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 46, }, + { 1, 0, 0, 1, 4, 46, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 46, }, + { 1, 0, 0, 1, 5, 46, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 46, }, + { 1, 0, 0, 1, 6, 46, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 46, }, + { 1, 0, 0, 1, 7, 46, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 46, }, + { 1, 0, 0, 1, 8, 46, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 46, }, + { 1, 0, 0, 1, 9, 46, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 46, }, + { 1, 0, 0, 1, 10, 46, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 46, }, + { 1, 0, 0, 1, 11, 46, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 46, }, + { 1, 0, 0, 1, 12, 46, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 46, }, + { 1, 0, 0, 1, 13, 46, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 46, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 46, }, + { 1, 0, 0, 2, 1, 46, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 46, }, + { 1, 0, 0, 2, 2, 46, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 46, }, + { 1, 0, 0, 2, 3, 46, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 46, }, + { 1, 0, 0, 2, 4, 46, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 46, }, + { 1, 0, 0, 2, 5, 46, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 46, }, + { 1, 0, 0, 2, 6, 46, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 46, }, + { 1, 0, 0, 2, 7, 46, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 46, }, + { 1, 0, 0, 2, 8, 46, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 46, }, + { 1, 0, 0, 2, 9, 46, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 46, }, + { 1, 0, 0, 2, 10, 46, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 46, }, + { 1, 0, 0, 2, 11, 46, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 46, }, + { 1, 0, 0, 2, 12, 46, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 46, }, + { 1, 0, 0, 2, 13, 46, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 46, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 46, }, + { 1, 0, 0, 3, 1, 46, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 46, }, + { 1, 0, 0, 3, 2, 46, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 46, }, + { 1, 0, 0, 3, 3, 46, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 46, }, + { 1, 0, 0, 3, 4, 46, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 46, }, + { 1, 0, 0, 3, 5, 46, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 46, }, + { 1, 0, 0, 3, 6, 46, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 46, }, + { 1, 0, 0, 3, 7, 46, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 46, }, + { 1, 0, 0, 3, 8, 46, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 46, }, + { 1, 0, 0, 3, 9, 46, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 46, }, + { 1, 0, 0, 3, 10, 46, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 46, }, + { 1, 0, 0, 3, 11, 46, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 46, }, + { 1, 0, 0, 3, 12, 46, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 46, }, + { 1, 0, 0, 3, 13, 46, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 46, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 46, }, + { 1, 0, 0, 6, 1, 46, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 46, }, + { 1, 0, 0, 6, 2, 46, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 46, }, + { 1, 0, 0, 6, 3, 46, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 46, }, + { 1, 0, 0, 6, 4, 46, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 46, }, + { 1, 0, 0, 6, 5, 46, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 46, }, + { 1, 0, 0, 6, 6, 46, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 46, }, + { 1, 0, 0, 6, 7, 46, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 46, }, + { 1, 0, 0, 6, 8, 46, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 46, }, + { 1, 0, 0, 6, 9, 46, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 46, }, + { 1, 0, 0, 6, 10, 46, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 46, }, + { 1, 0, 0, 6, 11, 46, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 46, }, + { 1, 0, 0, 6, 12, 46, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 46, }, + { 1, 0, 0, 6, 13, 46, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 46, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 46, }, + { 1, 0, 0, 7, 1, 46, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 46, }, + { 1, 0, 0, 7, 2, 46, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 46, }, + { 1, 0, 0, 7, 3, 46, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 46, }, + { 1, 0, 0, 7, 4, 46, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 46, }, + { 1, 0, 0, 7, 5, 46, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 46, }, + { 1, 0, 0, 7, 6, 46, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 46, }, + { 1, 0, 0, 7, 7, 46, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 46, }, + { 1, 0, 0, 7, 8, 46, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 46, }, + { 1, 0, 0, 7, 9, 46, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 46, }, + { 1, 0, 0, 7, 10, 46, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 46, }, + { 1, 0, 0, 7, 11, 46, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 46, }, + { 1, 0, 0, 7, 12, 46, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 46, }, + { 1, 0, 0, 7, 13, 46, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 46, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 30, }, + { 2, 0, 1, 2, 3, 34, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 34, }, + { 2, 0, 1, 2, 4, 34, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 34, }, + { 2, 0, 1, 2, 5, 34, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 34, }, + { 2, 0, 1, 2, 6, 34, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 34, }, + { 2, 0, 1, 2, 7, 34, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 34, }, + { 2, 0, 1, 2, 8, 34, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 34, }, + { 2, 0, 1, 2, 9, 34, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 34, }, + { 2, 0, 1, 2, 10, 34, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 34, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 34, }, + { 1, 0, 1, 2, 12, 34, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 34, }, + { 1, 0, 1, 2, 13, 34, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 34, }, + { 1, 0, 1, 3, 3, 34, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 34, }, + { 1, 0, 1, 3, 4, 34, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 34, }, + { 1, 0, 1, 3, 5, 34, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 34, }, + { 1, 0, 1, 3, 6, 34, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 34, }, + { 1, 0, 1, 3, 7, 34, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 34, }, + { 1, 0, 1, 3, 8, 34, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 34, }, + { 1, 0, 1, 3, 9, 34, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 34, }, + { 1, 0, 1, 3, 10, 34, }, + { 0, 0, 1, 3, 11, 28, }, + { 2, 0, 1, 3, 11, 34, }, + { 1, 0, 1, 3, 11, 34, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 34, }, + { 1, 0, 1, 3, 12, 34, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 34, }, + { 1, 0, 1, 3, 13, 34, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 30, }, + { 2, 0, 1, 6, 3, 34, }, + { 1, 0, 1, 6, 3, 34, }, + { 0, 0, 1, 6, 4, 34, }, + { 2, 0, 1, 6, 4, 34, }, + { 1, 0, 1, 6, 4, 34, }, + { 0, 0, 1, 6, 5, 34, }, + { 2, 0, 1, 6, 5, 34, }, + { 1, 0, 1, 6, 5, 34, }, + { 0, 0, 1, 6, 6, 34, }, + { 2, 0, 1, 6, 6, 34, }, + { 1, 0, 1, 6, 6, 34, }, + { 0, 0, 1, 6, 7, 34, }, + { 2, 0, 1, 6, 7, 34, }, + { 1, 0, 1, 6, 7, 34, }, + { 0, 0, 1, 6, 8, 34, }, + { 2, 0, 1, 6, 8, 34, }, + { 1, 0, 1, 6, 8, 34, }, + { 0, 0, 1, 6, 9, 34, }, + { 2, 0, 1, 6, 9, 34, }, + { 1, 0, 1, 6, 9, 34, }, + { 0, 0, 1, 6, 10, 34, }, + { 2, 0, 1, 6, 10, 34, }, + { 1, 0, 1, 6, 10, 34, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 34, }, + { 1, 0, 1, 6, 11, 34, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 34, }, + { 1, 0, 1, 6, 12, 34, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 34, }, + { 1, 0, 1, 6, 13, 34, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 30, }, + { 2, 0, 1, 7, 3, 34, }, + { 1, 0, 1, 7, 3, 34, }, + { 0, 0, 1, 7, 4, 34, }, + { 2, 0, 1, 7, 4, 34, }, + { 1, 0, 1, 7, 4, 34, }, + { 0, 0, 1, 7, 5, 34, }, + { 2, 0, 1, 7, 5, 34, }, + { 1, 0, 1, 7, 5, 34, }, + { 0, 0, 1, 7, 6, 34, }, + { 2, 0, 1, 7, 6, 34, }, + { 1, 0, 1, 7, 6, 34, }, + { 0, 0, 1, 7, 7, 34, }, + { 2, 0, 1, 7, 7, 34, }, + { 1, 0, 1, 7, 7, 34, }, + { 0, 0, 1, 7, 8, 34, }, + { 2, 0, 1, 7, 8, 34, }, + { 1, 0, 1, 7, 8, 34, }, + { 0, 0, 1, 7, 9, 34, }, + { 2, 0, 1, 7, 9, 34, }, + { 1, 0, 1, 7, 9, 34, }, + { 0, 0, 1, 7, 10, 34, }, + { 2, 0, 1, 7, 10, 34, }, + { 1, 0, 1, 7, 10, 34, }, + { 0, 0, 1, 7, 11, 28, }, + { 2, 0, 1, 7, 11, 34, }, + { 1, 0, 1, 7, 11, 34, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 34, }, + { 1, 0, 1, 7, 12, 34, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 34, }, + { 1, 0, 1, 7, 13, 34, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 46, }, + { 1, 1, 0, 1, 36, 46, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 46, }, + { 1, 1, 0, 1, 40, 46, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 46, }, + { 1, 1, 0, 1, 44, 46, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 46, }, + { 1, 1, 0, 1, 48, 46, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 46, }, + { 1, 1, 0, 1, 52, 46, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 46, }, + { 1, 1, 0, 1, 56, 46, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 46, }, + { 1, 1, 0, 1, 60, 46, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 46, }, + { 1, 1, 0, 1, 64, 46, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 46, }, + { 1, 1, 0, 1, 100, 46, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 46, }, + { 1, 1, 0, 1, 104, 46, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 46, }, + { 1, 1, 0, 1, 108, 46, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 46, }, + { 1, 1, 0, 1, 112, 46, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 46, }, + { 1, 1, 0, 1, 116, 46, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 46, }, + { 1, 1, 0, 1, 120, 46, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 46, }, + { 1, 1, 0, 1, 124, 46, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 46, }, + { 1, 1, 0, 1, 128, 46, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 46, }, + { 1, 1, 0, 1, 132, 46, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 46, }, + { 1, 1, 0, 1, 136, 46, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 46, }, + { 1, 1, 0, 1, 140, 46, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 46, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 46, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 46, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 46, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 46, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 46, }, + { 1, 1, 0, 2, 36, 46, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 46, }, + { 1, 1, 0, 2, 40, 46, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 46, }, + { 1, 1, 0, 2, 44, 46, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 46, }, + { 1, 1, 0, 2, 48, 46, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 46, }, + { 1, 1, 0, 2, 52, 46, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 46, }, + { 1, 1, 0, 2, 56, 46, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 46, }, + { 1, 1, 0, 2, 60, 46, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 46, }, + { 1, 1, 0, 2, 64, 46, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 46, }, + { 1, 1, 0, 2, 100, 46, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 46, }, + { 1, 1, 0, 2, 104, 46, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 46, }, + { 1, 1, 0, 2, 108, 46, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 46, }, + { 1, 1, 0, 2, 112, 46, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 46, }, + { 1, 1, 0, 2, 116, 46, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 46, }, + { 1, 1, 0, 2, 120, 46, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 46, }, + { 1, 1, 0, 2, 124, 46, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 46, }, + { 1, 1, 0, 2, 128, 46, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 46, }, + { 1, 1, 0, 2, 132, 46, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 46, }, + { 1, 1, 0, 2, 136, 46, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 46, }, + { 1, 1, 0, 2, 140, 46, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 46, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 46, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 46, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 46, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 46, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 46, }, + { 1, 1, 0, 3, 36, 46, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 46, }, + { 1, 1, 0, 3, 40, 46, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 46, }, + { 1, 1, 0, 3, 44, 46, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 46, }, + { 1, 1, 0, 3, 48, 46, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 46, }, + { 1, 1, 0, 3, 52, 46, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 46, }, + { 1, 1, 0, 3, 56, 46, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 46, }, + { 1, 1, 0, 3, 60, 46, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 46, }, + { 1, 1, 0, 3, 64, 46, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 46, }, + { 1, 1, 0, 3, 100, 46, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 46, }, + { 1, 1, 0, 3, 104, 46, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 46, }, + { 1, 1, 0, 3, 108, 46, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 46, }, + { 1, 1, 0, 3, 112, 46, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 46, }, + { 1, 1, 0, 3, 116, 46, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 46, }, + { 1, 1, 0, 3, 120, 46, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 46, }, + { 1, 1, 0, 3, 124, 46, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 46, }, + { 1, 1, 0, 3, 128, 46, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 46, }, + { 1, 1, 0, 3, 132, 46, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 46, }, + { 1, 1, 0, 3, 136, 46, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 46, }, + { 1, 1, 0, 3, 140, 46, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 46, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 46, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 46, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 46, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 46, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 46, }, + { 1, 1, 0, 6, 36, 46, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 46, }, + { 1, 1, 0, 6, 40, 46, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 46, }, + { 1, 1, 0, 6, 44, 46, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 46, }, + { 1, 1, 0, 6, 48, 46, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 46, }, + { 1, 1, 0, 6, 52, 46, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 46, }, + { 1, 1, 0, 6, 56, 46, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 46, }, + { 1, 1, 0, 6, 60, 46, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 46, }, + { 1, 1, 0, 6, 64, 46, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 46, }, + { 1, 1, 0, 6, 100, 46, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 46, }, + { 1, 1, 0, 6, 104, 46, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 46, }, + { 1, 1, 0, 6, 108, 46, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 46, }, + { 1, 1, 0, 6, 112, 46, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 46, }, + { 1, 1, 0, 6, 116, 46, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 46, }, + { 1, 1, 0, 6, 120, 46, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 46, }, + { 1, 1, 0, 6, 124, 46, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 46, }, + { 1, 1, 0, 6, 128, 46, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 46, }, + { 1, 1, 0, 6, 132, 46, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 46, }, + { 1, 1, 0, 6, 136, 46, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 46, }, + { 1, 1, 0, 6, 140, 46, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 46, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 46, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 46, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 46, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 46, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 46, }, + { 1, 1, 0, 7, 36, 46, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 46, }, + { 1, 1, 0, 7, 40, 46, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 46, }, + { 1, 1, 0, 7, 44, 46, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 46, }, + { 1, 1, 0, 7, 48, 46, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 46, }, + { 1, 1, 0, 7, 52, 46, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 46, }, + { 1, 1, 0, 7, 56, 46, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 46, }, + { 1, 1, 0, 7, 60, 46, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 46, }, + { 1, 1, 0, 7, 64, 46, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 46, }, + { 1, 1, 0, 7, 100, 46, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 46, }, + { 1, 1, 0, 7, 104, 46, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 46, }, + { 1, 1, 0, 7, 108, 46, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 46, }, + { 1, 1, 0, 7, 112, 46, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 46, }, + { 1, 1, 0, 7, 116, 46, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 46, }, + { 1, 1, 0, 7, 120, 46, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 46, }, + { 1, 1, 0, 7, 124, 46, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 46, }, + { 1, 1, 0, 7, 128, 46, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 46, }, + { 1, 1, 0, 7, 132, 46, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 46, }, + { 1, 1, 0, 7, 136, 46, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 46, }, + { 1, 1, 0, 7, 140, 46, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 46, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 46, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 46, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 46, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 46, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 46, }, + { 1, 1, 1, 2, 38, 46, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 46, }, + { 1, 1, 1, 2, 46, 46, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 46, }, + { 1, 1, 1, 2, 54, 46, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 46, }, + { 1, 1, 1, 2, 62, 46, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 46, }, + { 1, 1, 1, 2, 102, 46, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 46, }, + { 1, 1, 1, 2, 110, 46, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 46, }, + { 1, 1, 1, 2, 118, 46, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 46, }, + { 1, 1, 1, 2, 126, 46, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 46, }, + { 1, 1, 1, 2, 134, 46, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 46, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 46, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 46, }, + { 1, 1, 1, 3, 38, 46, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 46, }, + { 1, 1, 1, 3, 46, 46, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 46, }, + { 1, 1, 1, 3, 54, 46, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 46, }, + { 1, 1, 1, 3, 62, 46, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 46, }, + { 1, 1, 1, 3, 102, 46, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 46, }, + { 1, 1, 1, 3, 110, 46, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 46, }, + { 1, 1, 1, 3, 118, 46, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 46, }, + { 1, 1, 1, 3, 126, 46, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 46, }, + { 1, 1, 1, 3, 134, 46, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 46, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 46, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 46, }, + { 1, 1, 1, 6, 38, 46, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 46, }, + { 1, 1, 1, 6, 46, 46, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 46, }, + { 1, 1, 1, 6, 54, 46, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 46, }, + { 1, 1, 1, 6, 62, 46, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 46, }, + { 1, 1, 1, 6, 102, 46, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 46, }, + { 1, 1, 1, 6, 110, 46, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 46, }, + { 1, 1, 1, 6, 118, 46, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 46, }, + { 1, 1, 1, 6, 126, 46, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 46, }, + { 1, 1, 1, 6, 134, 46, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 46, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 46, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 46, }, + { 1, 1, 1, 7, 38, 46, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 46, }, + { 1, 1, 1, 7, 46, 46, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 46, }, + { 1, 1, 1, 7, 54, 46, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 46, }, + { 1, 1, 1, 7, 62, 46, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 46, }, + { 1, 1, 1, 7, 102, 46, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 46, }, + { 1, 1, 1, 7, 110, 46, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 46, }, + { 1, 1, 1, 7, 118, 46, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 46, }, + { 1, 1, 1, 7, 126, 46, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 46, }, + { 1, 1, 1, 7, 134, 46, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 46, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 46, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 46, }, + { 1, 1, 2, 4, 42, 46, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 46, }, + { 1, 1, 2, 4, 58, 46, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 46, }, + { 1, 1, 2, 4, 106, 46, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 46, }, + { 1, 1, 2, 4, 122, 46, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 46, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 46, }, + { 1, 1, 2, 5, 42, 46, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 46, }, + { 1, 1, 2, 5, 58, 46, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 46, }, + { 1, 1, 2, 5, 106, 46, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 46, }, + { 1, 1, 2, 5, 122, 46, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 46, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 46, }, + { 1, 1, 2, 8, 42, 46, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 46, }, + { 1, 1, 2, 8, 58, 46, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 46, }, + { 1, 1, 2, 8, 106, 46, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 46, }, + { 1, 1, 2, 8, 122, 46, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 46, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 46, }, + { 1, 1, 2, 9, 42, 46, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 46, }, + { 1, 1, 2, 9, 58, 46, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 46, }, + { 1, 1, 2, 9, 106, 46, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 46, }, + { 1, 1, 2, 9, 122, 46, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 46, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type8); + +static const u8 +rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, + 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19}, + {0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 19}, +}; + +static const u8 +rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 14, 15, 15, 15, 15, 16, 16, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 14, 15, 16, 17, 18, 18, 19, 20, 20}, +}; + +static const u8 +rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17, 17}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 14, 15, 16, 17, 18, 18, 19, 20, 20}, +}; + +static const u8 +rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 23, 24}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 11, 11, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, + 12, 13, 14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21}, + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 19}, +}; + +static const u8 +rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 12, 13, + 14, 15, 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, +}; + +static const u8 rtw8814a_pwrtrk_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, + 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8814a_pwrtrk_type0_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type0_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type0_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type0_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type0_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type0_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type0_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type0_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type0_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type0_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type0_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type0_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type0_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type0_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type0_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type0_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type0_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type0_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 12, 12, + 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 10, 10, 10, + 11, 11, 12, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 22, 22, 22, 22, 22}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 22, 22, 22, 22, 22}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 12, + 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 11, 12, 13, + 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21, 21}, + {0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 20}, + {0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, + 12, 13, 13, 13, 13, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, + 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 11, 11, 12, + 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, + 15, 15, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, + 15, 16, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 20}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, + 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20, 20, 20}, +}; + +static const u8 rtw8814a_pwrtrk_type2_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, + 10, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, + 9, 9, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 9, 9, + 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type2_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type2_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type2_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type2_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type2_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type2_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type2_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type2_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type2_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type2_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type2_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type2_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type2_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type2_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type2_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type2_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 3, 3, 3, 4, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 13, 14, + 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 4, 5, 6, 7, 7, 8, 7, 8, 10, 11, 12, 12, 13, 13, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 5, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 10, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 11, 12, + 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 0, 1, 1, 2, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 6, 7, 7, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 3, 7, 7, 8, 8, 9, 11, 12, 12, 13, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 4, 5, 7, 8, 8, 10, 11, 12, 12, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13}, + {0, 0, 1, 2, 3, 3, 5, 5, 6, 8, 8, 9, 10, 11, 13, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 4, 5, 7, 8, 9, 9, 10, 11, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 9, 10, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 3, 7, 7, 8, 8, 9, 11, 12, 12, 13, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 4, 5, 7, 8, 8, 10, 11, 12, 12, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 1, 2, 2, 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 0, 2, 3, 4, 5, 6, 8, 8, 9, 9, 11, 12, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 0, 1, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12}, + {0, 2, 3, 4, 5, 7, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 17, + 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 6, 7, 8, 8, 10, 11, 11, 12, 13, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 3, 3, 3, 5, 5, 6, 6, 8, 8, 9, 10, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 11, 12, 13, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 rtw8814a_pwrtrk_type5_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 111, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 11, 11, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 2, 3, 4, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type5_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type5_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type5_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type5_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type5_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type5_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type5_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type5_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type5_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type5_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type5_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type5_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type5_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type5_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type5_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type5_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8814a_pwrtrk_type7_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type7_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type7_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type7_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type7_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type7_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type7_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type7_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type7_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type7_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type7_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type7_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type7_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type7_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type7_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type7_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type7_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 3, 4, 4, 5, 6, 7, 7, 8, 10, 11, 12, 13, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 4, 5, 5, 6, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 10, 11, 11, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 10, 10, 11, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 10, 11, 12, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 3, 4, 4, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 rtw8814a_pwrtrk_type8_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, + 10, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, + 9, 9, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 9, 9, + 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type8_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type8_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type8_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type8_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type8_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type8_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type8_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type8_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type8_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type8_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type8_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type8_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type8_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type8_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type8_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type8_2g_cck_a_p, +}; + +static const struct rtw_pwr_seq_cmd init_power_on_8814a[] = { + {0x10c2, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8814a[] = { + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0071, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8814a[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x00F0, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x30, 0x20}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8814a[] = { + {0x0c00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0e00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x1002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_US}, + {0x1002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x28}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x02, 0}, + {0x0066, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x004e, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8814a[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0080, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x01}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x30}, + {0x0045, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xff}, + {0x0047, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0021, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0076, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0091, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xA0, 0xA0}, + {0x0070, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[] = { + init_power_on_8814a, + trans_carddis_to_cardemu_8814a, + trans_cardemu_to_act_8814a, + NULL +}; + +const struct rtw_pwr_seq_cmd * const card_disable_flow_8814a[] = { + trans_act_to_cardemu_8814a, + trans_cardemu_to_carddis_8814a, + NULL +}; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8814a_table.h new file mode 100644 index 000000000..69fb87e36 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814a_table.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW8814A_TABLE_H__ +#define __RTW8814A_TABLE_H__ + +extern const struct rtw_table rtw8814a_mac_tbl; +extern const struct rtw_table rtw8814a_agc_tbl; +extern const struct rtw_table rtw8814a_bb_tbl; +extern const struct rtw_table rtw8814a_bb_pg_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type0_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type2_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type3_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type4_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type5_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type7_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type8_tbl; +extern const struct rtw_table rtw8814a_rf_a_tbl; +extern const struct rtw_table rtw8814a_rf_b_tbl; +extern const struct rtw_table rtw8814a_rf_c_tbl; +extern const struct rtw_table rtw8814a_rf_d_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type0_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type1_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type2_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type3_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type5_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type7_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type8_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type0_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8814a[]; +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[]; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814ae.c b/drivers/net/wireless/realtek/rtw88/rtw8814ae.c new file mode 100644 index 000000000..c7436f1c8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814ae.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8814a.h" + +static const struct pci_device_id rtw_8814ae_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8813), + .driver_data = (kernel_ulong_t)&rtw8814a_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8814ae_id_table); + +static struct pci_driver rtw_8814ae_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8814ae_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, +}; +module_pci_driver(rtw_8814ae_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814ae driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814au.c b/drivers/net/wireless/realtek/rtw88/rtw8814au.c new file mode 100644 index 000000000..1a0886ec1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8814au.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8814a.h" +#include "usb.h" + +static const struct usb_device_id rtw_8814au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8813, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9054, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1817, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1852, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1853, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0026, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0106, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa834, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa833, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8814au_id_table); + +static struct usb_driver rtw_8814au_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8814au_id_table, + .probe = rtw_usb_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8814au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814au driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c new file mode 100644 index 000000000..cab85203b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c @@ -0,0 +1,1231 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "phy.h" +#include "reg.h" +#include "rtw88xxa.h" +#include "rtw8821a.h" +#include "rtw8821a_table.h" +#include "tx.h" + +static void rtw8821a_power_off(struct rtw_dev *rtwdev) +{ + rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); +} + +static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) +{ + static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; + s8 rx_pwr_all = 0; + s8 lna_gain; + + switch (lna_idx) { + case 5: + case 4: + case 2: + case 1: + case 0: + lna_gain = lna_gain_table[lna_idx]; + rx_pwr_all = lna_gain - 2 * vga_idx; + break; + default: + break; + } + + return rx_pwr_all; +} + +static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, + rtw8821a_cck_rx_pwr); +} + +static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ +} + +#define CAL_NUM_8821A 3 +#define MACBB_REG_NUM_8821A 8 +#define AFE_REG_NUM_8821A 4 +#define RF_REG_NUM_8821A 3 + +static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, + const u32 *backup_rf_reg, u32 rf_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Save RF Parameters */ + for (i = 0; i < rf_num; i++) + rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, + backup_rf_reg[i], MASKDWORD); +} + +static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, + const u32 *backup_rf_reg, + u32 *RF_backup, u32 rf_reg_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + for (i = 0; i < rf_reg_num; i++) + rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], + RFREG_MASK, RF_backup[i]); +} + +static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Reload AFE Parameters */ + for (i = 0; i < afe_num; i++) + rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); + rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000); + rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); + rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x0); +} + +static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, + unsigned int rx_x, unsigned int rx_y) +{ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, (rx_y >> 1) & 0x3ff); +} + +static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, + unsigned int tx_x, unsigned int tx_y) +{ + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); + rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); + rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); +} + +static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal, + bool *tx0iqkok, + int tx_x0[CAL_NUM_8821A], + int tx_y0[CAL_NUM_8821A]) +{ + u32 cal_retry, delay_count, iqk_ready, tx_fail; + int tx_dt[3], vdf_y[3], vdf_x[3]; + int k; + + for (k = 0; k < 3; k++) { + switch (k) { + case 0: + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + 0x18008c38); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); + break; + case 1: + rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE, + BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); + break; + case 2: + rtw_dbg(rtwdev, RTW_DBG_RFK, + "vdf_y[1] = %x vdf_y[0] = %x\n", + vdf_y[1] >> 21 & 0x00007ff, + vdf_y[0] >> 21 & 0x00007ff); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "vdf_x[1] = %x vdf_x[0] = %x\n", + vdf_x[1] >> 21 & 0x00007ff, + vdf_x[0] >> 21 & 0x00007ff); + + tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20); + tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; + tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + 0x18008c20); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000, + tx_dt[cal] & 0x00003fff); + break; + } + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); + + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; + + if (iqk_ready) + break; + + mdelay(1); + } + + if (delay_count < 20) { + /* ============TXIQK Check============== */ + tx_fail = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(12)); + + /* Originally: if (~tx_fail) { + * It looks like a typo, so make it more explicit. + */ + tx_fail = false; + + if (!tx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, + 0x02000000); + vdf_x[k] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + vdf_x[k] <<= 21; + + rtw_write32(rtwdev, REG_RFECTL_A, + 0x04000000); + vdf_y[k] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + vdf_y[k] <<= 21; + + *tx0iqkok = true; + break; + } + + rtw_write32_mask(rtwdev, REG_IQC_Y, + 0x000007ff, 0x0); + rtw_write32_mask(rtwdev, REG_IQC_X, + 0x000007ff, 0x200); + } + + *tx0iqkok = false; + } + } + + if (k == 3) { + tx_x0[cal] = vdf_x[k - 1]; + tx_y0[cal] = vdf_y[k - 1]; + } +} + +static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal, + bool *tx0iqkok, + int tx_x0[CAL_NUM_8821A], + int tx_y0[CAL_NUM_8821A]) +{ + u32 cal_retry, delay_count, iqk_ready, tx_fail; + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); + + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; + + if (iqk_ready) + break; + + mdelay(1); + } + + if (delay_count < 20) { + /* ============TXIQK Check============== */ + tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); + + /* Originally: if (~tx_fail) { + * It looks like a typo, so make it more explicit. + */ + tx_fail = false; + + if (!tx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); + tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + tx_x0[cal] <<= 21; + + rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); + tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + tx_y0[cal] <<= 21; + + *tx0iqkok = true; + break; + } + + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); + } + + *tx0iqkok = false; + } +} + +static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok, + int rx_x0[CAL_NUM_8821A], + int rx_y0[CAL_NUM_8821A]) +{ + u32 cal_retry, delay_count, iqk_ready, rx_fail; + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); + + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; + + if (iqk_ready) + break; + + mdelay(1); + } + + if (delay_count < 20) { + /* ============RXIQK Check============== */ + rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); + if (!rx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); + rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + rx_x0[cal] <<= 21; + + rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); + rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + rx_y0[cal] <<= 21; + + *rx0iqkok = true; + break; + } + + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, 0x200 >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, 0x0 >> 1); + } + + *rx0iqkok = false; + } +} + +static void rtw8821a_iqk(struct rtw_dev *rtwdev) +{ + int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; + const struct rtw_efuse *efuse = &rtwdev->efuse; + int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; + const struct rtw_hal *hal = &rtwdev->hal; + bool tx0iqkok = false, rx0iqkok = false; + int rx_x_temp = 0, rx_y_temp = 0; + int rx_x0[2][CAL_NUM_8821A]; + int rx_y0[2][CAL_NUM_8821A]; + int tx_x0[CAL_NUM_8821A]; + int tx_y0[CAL_NUM_8821A]; + bool rx_finish1 = false; + bool rx_finish2 = false; + bool vdf_enable; + u32 cal; + int i; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", + hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); + + vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; + + for (cal = 0; cal < CAL_NUM_8821A; cal++) { + /* path-A LOK */ + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* ========path-A AFE all on======== */ + /* Port 0 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); + + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); + + /* hardware 3-wire off */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); + + /* LOK setting */ + + /* 1. DAC/ADC sampling rate (160 MHz) */ + rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); + + /* 2. LoK RF setting (at BW = 20M) */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0003f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xf3fc3); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, + 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); + /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); + /* [0]:AGC_en, [15]:idac_K_Mask */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (efuse->ext_pa_5g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f4); + + if (hal->current_band_type == RTW_BAND_5G) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); + + if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, + RF18_BW_MASK, 0x1); + else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, + RF18_BW_MASK, 0x0); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + /* 3. TX RF setting */ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0003f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xf3fc3); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); + /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); + /* [0]:AGC_en, [15]:idac_K_Mask */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (efuse->ext_pa_5g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403e3); + + if (hal->current_band_type == RTW_BAND_5G) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); + + if (vdf_enable) + rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok, + tx_x0, tx_y0); + else + rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok, + tx_x0, tx_y0); + + if (!tx0iqkok) + break; /* TXK fail, Don't do RXK */ + + /* ====== RX IQK ====== */ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* 1. RX RF setting */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0002f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfffbb); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + (tx_x0[cal] >> 21) & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + (tx_y0[cal] >> 21) & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + rx_iqk_loop = 2; /* for 2% fail; */ + else + rx_iqk_loop = 1; + + for (i = 0; i < rx_iqk_loop; i++) { + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); + + rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, + rx_x0[i], rx_y0[i]); + } + + if (tx0iqkok) + tx_average++; + if (rx0iqkok) + rx_average++; + } + + /* FillIQK Result */ + + if (tx_average == 0) + return; + + for (i = 0; i < tx_average; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", + i, (tx_x0[i] >> 21) & 0x000007ff, + i, (tx_y0[i] >> 21) & 0x000007ff); + + if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0, + &tx_x, &tx_y, true, true)) + rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y); + else + rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0); + + if (rx_average == 0) + return; + + for (i = 0; i < rx_average; i++) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", + i, (rx_x0[0][i] >> 21) & 0x000007ff, + i, (rx_y0[0][i] >> 21) & 0x000007ff); + + if (rx_iqk_loop == 2) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", + i, (rx_x0[1][i] >> 21) & 0x000007ff, + i, (rx_y0[1][i] >> 21) & 0x000007ff); + } + + rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], + &rx_x_temp, &rx_y_temp, true, true); + + if (rx_finish1) { + rx_x = rx_x_temp; + rx_y = rx_y_temp; + } + + if (rx_iqk_loop == 2) { + rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4, + rx_x0[1], rx_y0[1], + &rx_x, &rx_y, true, true); + + if (rx_finish1 && rx_finish2) { + rx_x = (rx_x + rx_x_temp) / 2; + rx_y = (rx_y + rx_y_temp) / 2; + } + } + + if (rx_finish1 || rx_finish2) + rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y); + else + rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0); +} + +static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) +{ + static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { + 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c + }; + static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { + 0xc5c, 0xc60, 0xc64, 0xc68 + }; + static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { + 0x65, 0x8f, 0x0 + }; + u32 macbb_backup[MACBB_REG_NUM_8821A]; + u32 afe_backup[AFE_REG_NUM_8821A]; + u32 rfa_backup[RF_REG_NUM_8821A]; + + rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8821A); + rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8821A); + rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, + backup_rf_reg, RF_REG_NUM_8821A); + + rtw88xxa_iqk_configure_mac(rtwdev); + + rtw8821a_iqk(rtwdev); + + rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, + rfa_backup, RF_REG_NUM_8821A); + rtw8821a_iqk_restore_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8821A); + rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8821A); +} + +static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8821a_do_iqk(rtwdev); +} + +static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8821a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 gpio8_cfg; + u8 ledcfg; + + if (brightness == LED_OFF) { + gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + gpio8_cfg &= ~BIT(24); + gpio8_cfg |= BIT(16) | BIT(8); + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); + } else { + ledcfg = rtw_read8(rtwdev, REG_LED_CFG + 2); + gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + + ledcfg &= BIT(7) | BIT(6); + rtw_write8(rtwdev, REG_LED_CFG + 2, ledcfg); + + gpio8_cfg &= ~(BIT(24) | BIT(8)); + gpio8_cfg |= BIT(16); + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); + } +} + +static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + fill_txdesc_checksum_common(txdesc, 16); +} + +static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev) +{ + u8 val8; + + /* BT report packet sample rate */ + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); + + val8 = BIT_STATIS_BT_EN; + if (rtwdev->efuse.share_ant) + val8 |= BIT_R_GRANTALL_WLMASK; + rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3); + + /* enable PTA */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); +} + +static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + u8 pos_type) +{ + bool share_ant = rtwdev->efuse.share_ant; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + u32 phase = coex_dm->cur_ant_pos_type; + + if (!rtwdev->efuse.btcoex) + return; + + switch (phase) { + case COEX_SET_ANT_POWERON: + case COEX_SET_ANT_INIT: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); + + rtw_write8(rtwdev, REG_RFE_CTRL8, + share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); + break; + case COEX_SET_ANT_WONLY: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); + + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); + break; + case COEX_SET_ANT_2G: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); + + rtw_write8(rtwdev, REG_RFE_CTRL8, + share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); + break; + case COEX_SET_ANT_5G: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); + + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, + share_ant ? 0x2 : 0x1); + break; + case COEX_SET_ANT_WOFF: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); + + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, + share_ant ? 0x2 : 0x1); + break; + default: + rtw_warn(rtwdev, "%s: not handling phase %d\n", + __func__, phase); + break; + } +} + +static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + + coex_rfe->ant_switch_exist = true; +} + +static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool share_ant = efuse->share_ant; + + if (share_ant) + return; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; +} + +static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static const struct rtw_chip_ops rtw8821a_ops = { + .power_on = rtw88xxa_power_on, + .power_off = rtw8821a_power_off, + .phy_set_param = NULL, + .read_efuse = rtw88xxa_read_efuse, + .query_phy_status = rtw8821a_query_phy_status, + .set_channel = rtw88xxa_set_channel, + .mac_init = NULL, + .mac_postinit = NULL, + .read_rf = rtw88xxa_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw88xxa_set_tx_power_index, + .cfg_ldo25 = rtw8821a_cfg_ldo25, + .efuse_grant = rtw88xxa_efuse_grant, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw88xxa_false_alarm_statistics, + .phy_calibration = rtw8821a_phy_calibration, + .cck_pd_set = rtw88xxa_phy_cck_pd_set, + .pwr_track = rtw8821a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .led_set = rtw8821a_led_set, + .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, + .coex_set_init = rtw8821a_coex_cfg_init, + .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, +}; + +static const struct rtw_page_table page_table_8821a[] = { + /* hq_num, nq_num, lq_num, exq_num, gapq_num */ + {0, 0, 0, 0, 0}, /* SDIO */ + {0, 0, 0, 0, 0}, /* PCI */ + {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */ + {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */ + {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */ +}; + +static const struct rtw_rqpn rqpn_table_8821a[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8821a = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, + }, + .wsize = false, +}; + +static const struct rtw_hw_reg rtw8821a_dig[] = { + [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, +}; + +/* TODO */ +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40}; +static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101}; + +/* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a + * are copied from rtw8821c.c because the 8821au driver's tables are not + * compatible with the coex code in rtw88. + * + * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51, + * otherwise the firmware gets confused after pausing the music: + * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00] + * - 81 means PAN (personal area network) when it should be 4x (A2DP) + * The music is not smooth with the PAN algorithm. + */ + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8821a[] = { + {0x55555555, 0x55555555}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0xaaaaaaaa}, + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x6aaa6aaa}, + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x66555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8821a[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0xffff55ff, 0xfafafafa}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xffffffff, 0xffffffff}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-110 */ + {0x66555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xffff55ff, 0xffff55ff}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffff55ff, 0xfafafafa}, + {0xffffffff, 0xaaaaaaaa}, /* case-120 */ + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0x5afa5afa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8821a[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x35, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x35, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x15} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x11, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x08, 0x03, 0x30, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8821a[] = { + { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, + { {0x61, 0x25, 0x03, 0x11, 0x11} }, + { {0x61, 0x35, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x10, 0x03, 0x11, 0x11} }, + { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */ + { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */ + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x10, 0x03, 0x10, 0x50} } +}; + +/* TODO */ +static const struct coex_rf_para rf_para_tx_8821a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {8, 17, true, 4}, + {7, 18, true, 4}, + {6, 19, true, 4}, + {5, 20, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8821a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {3, 24, true, 5}, + {2, 26, true, 5}, + {1, 27, true, 5}, + {0, 28, true, 5} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); + +static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; + +static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = { + {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + +const struct rtw_chip_info rtw8821a_hw_spec = { + .ops = &rtw8821a_ops, + .id = RTW_CHIP_TYPE_8821A, + .fw_name = "rtw88/rtw8821a_fw.bin", + .wlan_cpu = RTW_WCPU_8051, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 0, + .txff_size = 65536, + .rxff_size = 16128, + .rsvd_drv_pg_num = 8, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 256, + .dig_min = 0x20, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8821a, + .pwr_off_seq = card_disable_flow_8821a, + .page_table = page_table_8821a, + .rqpn_table = rqpn_table_8821a, + .prioq_addrs = &prioq_addrs_8821a, + .intf_table = NULL, + .dig = rtw8821a_dig, + .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, + .ltecoex_addr = NULL, + .mac_tbl = &rtw8821a_mac_tbl, + .agc_tbl = &rtw8821a_agc_tbl, + .bb_tbl = &rtw8821a_bb_tbl, + .rf_tbl = {&rtw8821a_rf_a_tbl}, + .rfe_defs = rtw8821a_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), + .rx_ldpc = false, + .amsdu_in_ampdu = true, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .usb_tx_agg_desc_num = 6, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ + .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */ + .scbd_support = false, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 10, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8821a, + .bt_rssi_step = bt_rssi_step_8821a, + .table_sant_num = ARRAY_SIZE(table_sant_8821a), + .table_sant = table_sant_8821a, + .table_nsant_num = ARRAY_SIZE(table_nsant_8821a), + .table_nsant = table_nsant_8821a, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a), + .tdma_sant = tdma_sant_8821a, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a), + .tdma_nsant = tdma_nsant_8821a, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a), + .wl_rf_para_tx = rf_para_tx_8821a, + .wl_rf_para_rx = rf_para_rx_8821a, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = ARRAY_SIZE(afh_5g_8821a), + .afh_5g = afh_5g_8821a, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a), + .coex_info_hw_regs = coex_info_hw_regs_8821a, +}; +EXPORT_SYMBOL(rtw8821a_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.h b/drivers/net/wireless/realtek/rtw88/rtw8821a.h new file mode 100644 index 000000000..1b2e548f7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW8821A_H__ +#define __RTW8821A_H__ + +extern const struct rtw_chip_info rtw8821a_hw_spec; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c new file mode 100644 index 000000000..c8fd8e331 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c @@ -0,0 +1,2350 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8821a_table.h" + +static const u32 rtw8821a_mac[] = { + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x0000003F, + 0x4C9, 0x000000FF, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x607, 0x00000007, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821a_mac, rtw_phy_cfg_mac); + +static const u32 rtw8821a_agc[] = { + 0x81C, 0xBF000001, + 0x81C, 0xBF020001, + 0x81C, 0xBF040001, + 0x81C, 0xBF060001, + 0x81C, 0xBE080001, + 0x81C, 0xBD0A0001, + 0x81C, 0xBC0C0001, + 0x81C, 0xBA0E0001, + 0x81C, 0xB9100001, + 0x81C, 0xB8120001, + 0x81C, 0xB7140001, + 0x81C, 0xB6160001, + 0x81C, 0xB5180001, + 0x81C, 0xB41A0001, + 0x81C, 0xB31C0001, + 0x81C, 0xB21E0001, + 0x81C, 0xB1200001, + 0x81C, 0xB0220001, + 0x81C, 0xAF240001, + 0x81C, 0xAE260001, + 0x81C, 0xAD280001, + 0x81C, 0xAC2A0001, + 0x81C, 0xAB2C0001, + 0x81C, 0xAA2E0001, + 0x81C, 0xA9300001, + 0x81C, 0xA8320001, + 0x81C, 0xA7340001, + 0x81C, 0xA6360001, + 0x81C, 0xA5380001, + 0x81C, 0xA43A0001, + 0x81C, 0x683C0001, + 0x81C, 0x673E0001, + 0x81C, 0x66400001, + 0x81C, 0x65420001, + 0x81C, 0x64440001, + 0x81C, 0x63460001, + 0x81C, 0x62480001, + 0x81C, 0x614A0001, + 0x81C, 0x474C0001, + 0x81C, 0x464E0001, + 0x81C, 0x45500001, + 0x81C, 0x44520001, + 0x81C, 0x43540001, + 0x81C, 0x42560001, + 0x81C, 0x41580001, + 0x81C, 0x285A0001, + 0x81C, 0x275C0001, + 0x81C, 0x265E0001, + 0x81C, 0x25600001, + 0x81C, 0x24620001, + 0x81C, 0x0A640001, + 0x81C, 0x09660001, + 0x81C, 0x08680001, + 0x81C, 0x076A0001, + 0x81C, 0x066C0001, + 0x81C, 0x056E0001, + 0x81C, 0x04700001, + 0x81C, 0x03720001, + 0x81C, 0x02740001, + 0x81C, 0x01760001, + 0x81C, 0x01780001, + 0x81C, 0x017A0001, + 0x81C, 0x017C0001, + 0x81C, 0x017E0001, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000101, + 0x81C, 0xFA020101, + 0x81C, 0xF9040101, + 0x81C, 0xF8060101, + 0x81C, 0xF7080101, + 0x81C, 0xF60A0101, + 0x81C, 0xF50C0101, + 0x81C, 0xF40E0101, + 0x81C, 0xF3100101, + 0x81C, 0xF2120101, + 0x81C, 0xF1140101, + 0x81C, 0xF0160101, + 0x81C, 0xEF180101, + 0x81C, 0xEE1A0101, + 0x81C, 0xED1C0101, + 0x81C, 0xEC1E0101, + 0x81C, 0xEB200101, + 0x81C, 0xEA220101, + 0x81C, 0xE9240101, + 0x81C, 0xE8260101, + 0x81C, 0xE7280101, + 0x81C, 0xE62A0101, + 0x81C, 0xE52C0101, + 0x81C, 0xE42E0101, + 0x81C, 0xE3300101, + 0x81C, 0xA5320101, + 0x81C, 0xA4340101, + 0x81C, 0xA3360101, + 0x81C, 0x87380101, + 0x81C, 0x863A0101, + 0x81C, 0x853C0101, + 0x81C, 0x843E0101, + 0x81C, 0x69400101, + 0x81C, 0x68420101, + 0x81C, 0x67440101, + 0x81C, 0x66460101, + 0x81C, 0x49480101, + 0x81C, 0x484A0101, + 0x81C, 0x474C0101, + 0x81C, 0x2A4E0101, + 0x81C, 0x29500101, + 0x81C, 0x28520101, + 0x81C, 0x27540101, + 0x81C, 0x26560101, + 0x81C, 0x25580101, + 0x81C, 0x245A0101, + 0x81C, 0x235C0101, + 0x81C, 0x055E0101, + 0x81C, 0x04600101, + 0x81C, 0x03620101, + 0x81C, 0x02640101, + 0x81C, 0x01660101, + 0x81C, 0x01680101, + 0x81C, 0x016A0101, + 0x81C, 0x016C0101, + 0x81C, 0x016E0101, + 0x81C, 0x01700101, + 0x81C, 0x01720101, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000101, + 0x81C, 0xFA020101, + 0x81C, 0xF9040101, + 0x81C, 0xF8060101, + 0x81C, 0xF7080101, + 0x81C, 0xF60A0101, + 0x81C, 0xF50C0101, + 0x81C, 0xF40E0101, + 0x81C, 0xF3100101, + 0x81C, 0xF2120101, + 0x81C, 0xF1140101, + 0x81C, 0xF0160101, + 0x81C, 0xEF180101, + 0x81C, 0xEE1A0101, + 0x81C, 0xED1C0101, + 0x81C, 0xEC1E0101, + 0x81C, 0xEB200101, + 0x81C, 0xEA220101, + 0x81C, 0xE9240101, + 0x81C, 0xE8260101, + 0x81C, 0xE7280101, + 0x81C, 0xE62A0101, + 0x81C, 0xE52C0101, + 0x81C, 0xE42E0101, + 0x81C, 0xE3300101, + 0x81C, 0xA5320101, + 0x81C, 0xA4340101, + 0x81C, 0xA3360101, + 0x81C, 0x87380101, + 0x81C, 0x863A0101, + 0x81C, 0x853C0101, + 0x81C, 0x843E0101, + 0x81C, 0x69400101, + 0x81C, 0x68420101, + 0x81C, 0x67440101, + 0x81C, 0x66460101, + 0x81C, 0x49480101, + 0x81C, 0x484A0101, + 0x81C, 0x474C0101, + 0x81C, 0x2A4E0101, + 0x81C, 0x29500101, + 0x81C, 0x28520101, + 0x81C, 0x27540101, + 0x81C, 0x26560101, + 0x81C, 0x25580101, + 0x81C, 0x245A0101, + 0x81C, 0x235C0101, + 0x81C, 0x055E0101, + 0x81C, 0x04600101, + 0x81C, 0x03620101, + 0x81C, 0x02640101, + 0x81C, 0x01660101, + 0x81C, 0x01680101, + 0x81C, 0x016A0101, + 0x81C, 0x016C0101, + 0x81C, 0x016E0101, + 0x81C, 0x01700101, + 0x81C, 0x01720101, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000101, + 0x81C, 0xFF020101, + 0x81C, 0xFE040101, + 0x81C, 0xFD060101, + 0x81C, 0xFC080101, + 0x81C, 0xFD0A0101, + 0x81C, 0xFC0C0101, + 0x81C, 0xFB0E0101, + 0x81C, 0xFA100101, + 0x81C, 0xF9120101, + 0x81C, 0xF8140101, + 0x81C, 0xF7160101, + 0x81C, 0xF6180101, + 0x81C, 0xF51A0101, + 0x81C, 0xF41C0101, + 0x81C, 0xF31E0101, + 0x81C, 0xF2200101, + 0x81C, 0xF1220101, + 0x81C, 0xF0240101, + 0x81C, 0xEF260101, + 0x81C, 0xEE280101, + 0x81C, 0xED2A0101, + 0x81C, 0xEC2C0101, + 0x81C, 0xEB2E0101, + 0x81C, 0xEA300101, + 0x81C, 0xE9320101, + 0x81C, 0xE8340101, + 0x81C, 0xE7360101, + 0x81C, 0xE6380101, + 0x81C, 0xE53A0101, + 0x81C, 0xE43C0101, + 0x81C, 0xE33E0101, + 0x81C, 0xA5400101, + 0x81C, 0xA4420101, + 0x81C, 0xA3440101, + 0x81C, 0x87460101, + 0x81C, 0x86480101, + 0x81C, 0x854A0101, + 0x81C, 0x844C0101, + 0x81C, 0x694E0101, + 0x81C, 0x68500101, + 0x81C, 0x67520101, + 0x81C, 0x66540101, + 0x81C, 0x49560101, + 0x81C, 0x48580101, + 0x81C, 0x475A0101, + 0x81C, 0x2A5C0101, + 0x81C, 0x295E0101, + 0x81C, 0x28600101, + 0x81C, 0x27620101, + 0x81C, 0x26640101, + 0x81C, 0x25660101, + 0x81C, 0x24680101, + 0x81C, 0x236A0101, + 0x81C, 0x056C0101, + 0x81C, 0x046E0101, + 0x81C, 0x03700101, + 0x81C, 0x02720101, + 0xB0000000, 0x00000000, + 0x81C, 0x01740101, + 0x81C, 0x01760101, + 0x81C, 0x01780101, + 0x81C, 0x017A0101, + 0x81C, 0x017C0101, + 0x81C, 0x017E0101, + 0xC50, 0x00000022, + 0xC50, 0x00000020, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821a_agc, rtw_phy_cfg_agc); + +static const u32 rtw8821a_bb[] = { + 0x800, 0x0020D090, + 0x804, 0x080112E0, + 0x808, 0x0E028211, + 0x80C, 0x92131111, + 0x810, 0x20101261, + 0x814, 0x020C3D10, + 0x818, 0x03A00385, + 0x820, 0x00000000, + 0x824, 0x00030FE0, + 0x828, 0x00000000, + 0x82C, 0x002081DD, + 0x830, 0x2AAAEEC8, + 0x834, 0x0037A706, + 0x838, 0x06489B44, + 0x83C, 0x0000095B, + 0x840, 0xC0000001, + 0x844, 0x40003CDE, + 0x848, 0x62103F8B, + 0x84C, 0x6CFDFFB8, + 0x850, 0x28874706, + 0x854, 0x0001520C, + 0x858, 0x8060E000, + 0x85C, 0x74210168, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x888C2878, + 0x870, 0x08888888, + 0x874, 0x31612C2E, + 0x878, 0x00000152, + 0x87C, 0x000FD000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA2000338, + 0x8AC, 0x0FF0FA0A, + 0x8B4, 0x000FC080, + 0x8B8, 0x6C10D7FF, + 0x8BC, 0x0CA52090, + 0x8C0, 0x1BF00020, + 0x8C4, 0x00000000, + 0x8C8, 0x00013169, + 0x8CC, 0x08248492, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8F8, 0x400002C0, + 0x8FC, 0x00000000, + 0x900, 0x00000700, + 0x90C, 0x00000000, + 0x910, 0x0000FC00, + 0x914, 0x00000404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x00000004, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x974, 0x000003FF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00480080, + 0x9A8, 0x00000000, + 0x9AC, 0x00000000, + 0x9B0, 0x81081008, + 0x9B4, 0x01081008, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00005D00, + 0x9E4, 0x00000003, + 0x9E8, 0x00000001, + 0xA00, 0x00D047C8, + 0xA04, 0x01FF800C, + 0xA08, 0x8C8A8300, + 0xA0C, 0x2E68000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0000, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000008, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x21805490, + 0xA84, 0x001F0000, + 0XB00, 0x03100040, + 0XB04, 0x0000B000, + 0XB08, 0xAE0201EB, + 0XB0C, 0x01003207, + 0XB10, 0x00009807, + 0XB14, 0x01000000, + 0XB18, 0x00000002, + 0XB1C, 0x00000002, + 0XB20, 0x0000001F, + 0XB24, 0x03020100, + 0XB28, 0x07060504, + 0XB2C, 0x0B0A0908, + 0XB30, 0x0F0E0D0C, + 0XB34, 0x13121110, + 0XB38, 0x17161514, + 0XB3C, 0x0000003A, + 0XB40, 0x00000000, + 0XB44, 0x00000000, + 0XB48, 0x13000032, + 0XB4C, 0x48080000, + 0XB50, 0x00000000, + 0XB54, 0x00000000, + 0XB58, 0x00000000, + 0XB5C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000003, + 0xC20, 0x2C2C2C2C, + 0xC24, 0x30303030, + 0xC28, 0x30303030, + 0xC2C, 0x2C2C2C2C, + 0xC30, 0x2C2C2C2C, + 0xC34, 0x2C2C2C2C, + 0xC38, 0x2C2C2C2C, + 0xC3C, 0x2A2A2A2A, + 0xC40, 0x2A2A2A2A, + 0xC44, 0x2A2A2A2A, + 0xC48, 0x2A2A2A2A, + 0xC4C, 0x2A2A2A2A, + 0xC50, 0x00000020, + 0xC54, 0x001C1208, + 0xC58, 0x30000C1C, + 0xC5C, 0x00000058, + 0xC60, 0x34344443, + 0xC64, 0x07003333, + 0xC68, 0x19791979, + 0xC6C, 0x19791979, + 0xC70, 0x19791979, + 0xC74, 0x19791979, + 0xC78, 0x19791979, + 0xC7C, 0x19791979, + 0xC80, 0x19791979, + 0xC84, 0x19791979, + 0xC94, 0x0100005C, + 0xC98, 0x00000000, + 0xC9C, 0x00000000, + 0xCA0, 0x00000029, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCB0, 0x77775747, + 0xCB4, 0x10000077, + 0xCB8, 0x00508240, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821a_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8821a_bb_pg[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8821a_bb_pg); + +static const u32 rtw8821a_rf_a[] = { + 0x018, 0x0001712A, + 0x056, 0x00051CF2, + 0x066, 0x00040000, + 0x000, 0x00010000, + 0x01E, 0x00080000, + 0x082, 0x00000830, + 0x083, 0x00021800, + 0x084, 0x00028000, + 0x085, 0x00048000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x0009483A, + 0xA0000000, 0x00000000, + 0x086, 0x00094838, + 0xB0000000, 0x00000000, + 0x087, 0x00044980, + 0x088, 0x00048000, + 0x089, 0x0000D480, + 0x08A, 0x00042240, + 0x08B, 0x000F0380, + 0x08C, 0x00090000, + 0x08D, 0x00022852, + 0x08E, 0x00065540, + 0x08F, 0x00088001, + 0x0EF, 0x00020000, + 0x03E, 0x00000380, + 0x03F, 0x00090018, + 0x03E, 0x00020380, + 0x03F, 0x000A0018, + 0x03E, 0x00040308, + 0x03F, 0x000A0018, + 0x03E, 0x00060018, + 0x03F, 0x000A0018, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x089, 0x00000080, + 0x08B, 0x00080180, + 0x0EF, 0x00001000, + 0x03A, 0x00000244, + 0x03B, 0x00038027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x00030113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x00028027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x00027027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0001F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00017F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00008027, + 0x03C, 0x000CA000, + 0x03A, 0x00000244, + 0x03B, 0x00078027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x00070113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x00068027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x00067027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0005F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00057F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00048027, + 0x03C, 0x000CA000, + 0x03A, 0x00000244, + 0x03B, 0x000B8027, + 0x03C, 0x00082000, + 0x03A, 0x00000244, + 0x03B, 0x000B0113, + 0x03C, 0x00082000, + 0x03A, 0x0000014C, + 0x03B, 0x000A8027, + 0x03C, 0x00082000, + 0x03A, 0x000000CC, + 0x03B, 0x000A7027, + 0x03C, 0x00042000, + 0x03A, 0x0000014C, + 0x03B, 0x0009F913, + 0x03C, 0x00042000, + 0x03A, 0x0000010C, + 0x03B, 0x00097F10, + 0x03C, 0x00012000, + 0x03A, 0x000000D0, + 0x03B, 0x00088027, + 0x03C, 0x000CA000, + 0x0EF, 0x00000000, + 0x0EF, 0x00001100, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0F3, + 0x034, 0x000490B1, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0F3, + 0x034, 0x000490B1, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0xA0000000, 0x00000000, + 0x034, 0x0004ADF7, + 0x034, 0x00049DF3, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000480AE, + 0x034, 0x000470AB, + 0x034, 0x0004608B, + 0x034, 0x00045069, + 0x034, 0x00044048, + 0x034, 0x00043045, + 0x034, 0x00042026, + 0x034, 0x00041023, + 0x034, 0x00040002, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000480AE, + 0x034, 0x000470AB, + 0x034, 0x0004608B, + 0x034, 0x00045069, + 0x034, 0x00044048, + 0x034, 0x00043045, + 0x034, 0x00042026, + 0x034, 0x00041023, + 0x034, 0x00040002, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0xA0000000, 0x00000000, + 0x034, 0x00048DEF, + 0x034, 0x00047DEC, + 0x034, 0x00046DE9, + 0x034, 0x00045CCB, + 0x034, 0x0004488D, + 0x034, 0x0004348D, + 0x034, 0x0004248A, + 0x034, 0x0004108D, + 0x034, 0x0004008A, + 0xB0000000, 0x00000000, + 0x80000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002ADF4, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0F3, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0F3, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002ADF4, + 0xA0000000, 0x00000000, + 0x034, 0x0002ADF7, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF1, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000290F0, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000290F0, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF1, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0xA0000000, 0x00000000, + 0x034, 0x00029DF2, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000280AF, + 0x034, 0x000270AC, + 0x034, 0x0002608B, + 0x034, 0x00025069, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020002, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000280AF, + 0x034, 0x000270AC, + 0x034, 0x0002608B, + 0x034, 0x00025069, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020002, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0xA0000000, 0x00000000, + 0x034, 0x00028DEE, + 0x034, 0x00027DEB, + 0x034, 0x00026CCD, + 0x034, 0x00025CCA, + 0x034, 0x0002488C, + 0x034, 0x0002384C, + 0x034, 0x00022849, + 0x034, 0x00021449, + 0x034, 0x0002004D, + 0xB0000000, 0x00000000, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D7, + 0x034, 0x000090D3, + 0x034, 0x000080B1, + 0x034, 0x000070AE, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D7, + 0x034, 0x000090D3, + 0x034, 0x000080B1, + 0x034, 0x000070AE, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF7, + 0x034, 0x00009DF4, + 0x034, 0x00008DF1, + 0x034, 0x00007DEE, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000608D, + 0x034, 0x0000506B, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x00002044, + 0x034, 0x00001025, + 0x034, 0x00000004, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000608D, + 0x034, 0x0000506B, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x00002044, + 0x034, 0x00001025, + 0x034, 0x00000004, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0xA0000000, 0x00000000, + 0x034, 0x00006DCD, + 0x034, 0x00005CCD, + 0x034, 0x00004CCA, + 0x034, 0x0000388C, + 0x034, 0x00002888, + 0x034, 0x00001488, + 0x034, 0x00000486, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000145, + 0x035, 0x00008145, + 0x035, 0x00010145, + 0x035, 0x00020196, + 0x035, 0x00028196, + 0x035, 0x00030196, + 0x035, 0x000401C7, + 0x035, 0x000481C7, + 0x035, 0x000501C7, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000187, + 0x035, 0x00008187, + 0x035, 0x00010187, + 0x035, 0x00020188, + 0x035, 0x00028188, + 0x035, 0x00030188, + 0x035, 0x00040188, + 0x035, 0x00048188, + 0x035, 0x00050188, + 0xA0000000, 0x00000000, + 0x035, 0x00000145, + 0x035, 0x00008145, + 0x035, 0x00010145, + 0x035, 0x00020196, + 0x035, 0x00028196, + 0x035, 0x00030196, + 0x035, 0x000401C7, + 0x035, 0x000481C7, + 0x035, 0x000501C7, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000056B3, + 0x036, 0x0000D6B3, + 0x036, 0x000156B3, + 0x036, 0x0001D6B3, + 0x036, 0x00026634, + 0x036, 0x0002E634, + 0x036, 0x00036634, + 0x036, 0x0003E634, + 0x036, 0x000467B4, + 0x036, 0x0004E7B4, + 0x036, 0x000567B4, + 0x036, 0x0005E7B4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00085733, + 0x036, 0x0008D733, + 0x036, 0x00095733, + 0x036, 0x0009D733, + 0x036, 0x000A64B4, + 0x036, 0x000AE4B4, + 0x036, 0x000B64B4, + 0x036, 0x000BE4B4, + 0x036, 0x000C64B4, + 0x036, 0x000CE4B4, + 0x036, 0x000D64B4, + 0x036, 0x000DE4B4, + 0xA0000000, 0x00000000, + 0x036, 0x000056B3, + 0x036, 0x0000D6B3, + 0x036, 0x000156B3, + 0x036, 0x0001D6B3, + 0x036, 0x00026634, + 0x036, 0x0002E634, + 0x036, 0x00036634, + 0x036, 0x0003E634, + 0x036, 0x000467B4, + 0x036, 0x0004E7B4, + 0x036, 0x000567B4, + 0x036, 0x0005E7B4, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000008, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000022A, + 0x03C, 0x00000594, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001C8, + 0x03C, 0x00000492, + 0xA0000000, 0x00000000, + 0x03C, 0x0000022A, + 0x03C, 0x00000594, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000820, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000820, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0xA0000000, 0x00000000, + 0x03C, 0x00000900, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000002, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x0004E400, + 0xA0000000, 0x00000000, + 0x008, 0x00002000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x000000C0, + 0x01F, 0x00000064, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x000A7284, + 0x059, 0x000600EC, + 0xA0000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAD53, + 0x062, 0x00093BC4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000E8D73, + 0x062, 0x00093FC5, + 0xA0000000, 0x00000000, + 0x061, 0x000EAD53, + 0x062, 0x00093BC4, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0xA0000000, 0x00000000, + 0x063, 0x000714E9, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C67C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0xA0000000, 0x00000000, + 0x064, 0x0001C67C, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093016, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093015, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093015, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093016, + 0xA0000000, 0x00000000, + 0x065, 0x00091016, + 0xB0000000, 0x00000000, + 0x018, 0x00000006, + 0x0EF, 0x00002000, + 0x03B, 0x0003824B, + 0x03B, 0x0003024B, + 0x03B, 0x0002844B, + 0x03B, 0x00020F4B, + 0x03B, 0x00018F4B, + 0x03B, 0x000104B2, + 0x03B, 0x00008049, + 0x03B, 0x00000148, + 0x03B, 0x0007824B, + 0x03B, 0x0007024B, + 0x03B, 0x0006824B, + 0x03B, 0x00060F4B, + 0x03B, 0x00058F4B, + 0x03B, 0x000504B2, + 0x03B, 0x00048049, + 0x03B, 0x00040148, + 0x0EF, 0x00000000, + 0x0EF, 0x00000100, + 0x034, 0x0000ADF3, + 0x034, 0x00009DF0, + 0x034, 0x00008D70, + 0x034, 0x00007D6D, + 0x034, 0x00006CEE, + 0x034, 0x00005CCC, + 0x034, 0x000044EC, + 0x034, 0x000034AC, + 0x034, 0x0000246D, + 0x034, 0x0000106F, + 0x034, 0x0000006C, + 0x0EF, 0x00000000, + 0x0ED, 0x00000010, + 0x044, 0x0000ADF2, + 0x044, 0x00009DEF, + 0x044, 0x00008DEC, + 0x044, 0x00007DE9, + 0x044, 0x00006CEC, + 0x044, 0x00005CE9, + 0x044, 0x000044EC, + 0x044, 0x000034E9, + 0x044, 0x0000246C, + 0x044, 0x00001469, + 0x044, 0x0000006C, + 0x0ED, 0x00000000, + 0x0ED, 0x00000001, + 0x040, 0x00038DA7, + 0x040, 0x000300C2, + 0x040, 0x000288E2, + 0x040, 0x000200B8, + 0x040, 0x000188A5, + 0x040, 0x00010FBC, + 0x040, 0x00008F71, + 0x040, 0x00000240, + 0x0ED, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000120, + 0x035, 0x00008120, + 0x035, 0x00010120, + 0x036, 0x00000085, + 0x036, 0x00008085, + 0x036, 0x00010085, + 0x036, 0x00018085, + 0x0EF, 0x00000000, + 0x051, 0x00000C31, + 0x052, 0x00000622, + 0x053, 0x000FC70B, + 0x054, 0x0000017E, + 0x056, 0x00051DF3, + 0x051, 0x00000C01, + 0x052, 0x000006D6, + 0x053, 0x000FC649, + 0x070, 0x00049661, + 0x071, 0x0007843E, + 0x072, 0x00000382, + 0x074, 0x00051400, + 0x035, 0x00000160, + 0x035, 0x00008160, + 0x035, 0x00010160, + 0x036, 0x00000124, + 0x036, 0x00008124, + 0x036, 0x00010124, + 0x036, 0x00018124, + 0x0ED, 0x0000000C, + 0x045, 0x00000140, + 0x045, 0x00008140, + 0x045, 0x00010140, + 0x046, 0x00000124, + 0x046, 0x00008124, + 0x046, 0x00010124, + 0x046, 0x00018124, + 0x0DF, 0x00000088, + 0x0B3, 0x000F0E18, + 0x0B4, 0x0001214C, + 0x0B7, 0x0003000C, + 0x01C, 0x000539D2, + 0x0C4, 0x000AFE00, + 0x018, 0x0001F12A, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x0001712A, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8821a_rf_a, A); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8821a_txpwr_lmt[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 28, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 28, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 36, }, + { 2, 0, 0, 0, 3, 28, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 36, }, + { 2, 0, 0, 0, 4, 28, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 36, }, + { 2, 0, 0, 0, 5, 28, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 36, }, + { 2, 0, 0, 0, 6, 28, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 36, }, + { 2, 0, 0, 0, 7, 28, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 36, }, + { 2, 0, 0, 0, 8, 28, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 28, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 28, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 28, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 28, }, + { 2, 0, 0, 0, 12, 28, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 26, }, + { 2, 0, 0, 0, 13, 28, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 30, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 30, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 32, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 32, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 32, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 32, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 32, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 30, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 30, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 30, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 26, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 24, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 26, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 26, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 32, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 32, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 32, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 32, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 32, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 26, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 26, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 26, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 24, }, + { 2, 0, 0, 2, 13, 26, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 30, }, + { 2, 0, 0, 3, 1, 32, }, + { 1, 0, 0, 3, 1, 32, }, + { 0, 0, 0, 3, 2, 32, }, + { 2, 0, 0, 3, 2, 32, }, + { 1, 0, 0, 3, 2, 32, }, + { 0, 0, 0, 3, 3, 32, }, + { 2, 0, 0, 3, 3, 32, }, + { 1, 0, 0, 3, 3, 32, }, + { 0, 0, 0, 3, 4, 32, }, + { 2, 0, 0, 3, 4, 32, }, + { 1, 0, 0, 3, 4, 32, }, + { 0, 0, 0, 3, 5, 32, }, + { 2, 0, 0, 3, 5, 32, }, + { 1, 0, 0, 3, 5, 32, }, + { 0, 0, 0, 3, 6, 32, }, + { 2, 0, 0, 3, 6, 32, }, + { 1, 0, 0, 3, 6, 32, }, + { 0, 0, 0, 3, 7, 32, }, + { 2, 0, 0, 3, 7, 32, }, + { 1, 0, 0, 3, 7, 32, }, + { 0, 0, 0, 3, 8, 32, }, + { 2, 0, 0, 3, 8, 32, }, + { 1, 0, 0, 3, 8, 32, }, + { 0, 0, 0, 3, 9, 32, }, + { 2, 0, 0, 3, 9, 32, }, + { 1, 0, 0, 3, 9, 32, }, + { 0, 0, 0, 3, 10, 32, }, + { 2, 0, 0, 3, 10, 32, }, + { 1, 0, 0, 3, 10, 32, }, + { 0, 0, 0, 3, 11, 30, }, + { 2, 0, 0, 3, 11, 32, }, + { 1, 0, 0, 3, 11, 32, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 32, }, + { 1, 0, 0, 3, 12, 32, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 32, }, + { 1, 0, 0, 3, 13, 32, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 26, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 26, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 32, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 32, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 24, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 22, }, + { 2, 0, 1, 2, 11, 26, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 32, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 32, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 32, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 32, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 32, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 32, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 32, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 30, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 32, }, + { 1, 0, 1, 3, 12, 32, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 32, }, + { 1, 0, 1, 3, 13, 32, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 32, }, + { 2, 1, 0, 1, 36, 30, }, + { 1, 1, 0, 1, 36, 30, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 30, }, + { 1, 1, 0, 1, 40, 30, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 30, }, + { 1, 1, 0, 1, 44, 30, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 30, }, + { 1, 1, 0, 1, 48, 30, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 30, }, + { 1, 1, 0, 1, 52, 30, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 30, }, + { 1, 1, 0, 1, 56, 30, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 30, }, + { 1, 1, 0, 1, 60, 30, }, + { 0, 1, 0, 1, 64, 32, }, + { 2, 1, 0, 1, 64, 30, }, + { 1, 1, 0, 1, 64, 30, }, + { 0, 1, 0, 1, 100, 32, }, + { 2, 1, 0, 1, 100, 30, }, + { 1, 1, 0, 1, 100, 30, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 30, }, + { 1, 1, 0, 1, 104, 30, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 30, }, + { 1, 1, 0, 1, 108, 30, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 30, }, + { 1, 1, 0, 1, 112, 30, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 30, }, + { 1, 1, 0, 1, 116, 30, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 30, }, + { 1, 1, 0, 1, 120, 30, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 30, }, + { 1, 1, 0, 1, 124, 30, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 30, }, + { 1, 1, 0, 1, 128, 30, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 30, }, + { 1, 1, 0, 1, 132, 30, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 30, }, + { 1, 1, 0, 1, 136, 30, }, + { 0, 1, 0, 1, 140, 32, }, + { 2, 1, 0, 1, 140, 30, }, + { 1, 1, 0, 1, 140, 30, }, + { 0, 1, 0, 1, 149, 32, }, + { 2, 1, 0, 1, 149, 30, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 30, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 30, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 30, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 30, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 32, }, + { 2, 1, 0, 2, 36, 30, }, + { 1, 1, 0, 2, 36, 30, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 30, }, + { 1, 1, 0, 2, 40, 30, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 30, }, + { 1, 1, 0, 2, 44, 30, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 30, }, + { 1, 1, 0, 2, 48, 30, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 30, }, + { 1, 1, 0, 2, 52, 30, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 30, }, + { 1, 1, 0, 2, 56, 30, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 30, }, + { 1, 1, 0, 2, 60, 30, }, + { 0, 1, 0, 2, 64, 32, }, + { 2, 1, 0, 2, 64, 30, }, + { 1, 1, 0, 2, 64, 30, }, + { 0, 1, 0, 2, 100, 32, }, + { 2, 1, 0, 2, 100, 30, }, + { 1, 1, 0, 2, 100, 30, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 30, }, + { 1, 1, 0, 2, 104, 30, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 30, }, + { 1, 1, 0, 2, 108, 30, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 30, }, + { 1, 1, 0, 2, 112, 30, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 30, }, + { 1, 1, 0, 2, 116, 30, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 30, }, + { 1, 1, 0, 2, 120, 30, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 30, }, + { 1, 1, 0, 2, 124, 30, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 30, }, + { 1, 1, 0, 2, 128, 30, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 30, }, + { 1, 1, 0, 2, 132, 30, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 30, }, + { 1, 1, 0, 2, 136, 30, }, + { 0, 1, 0, 2, 140, 32, }, + { 2, 1, 0, 2, 140, 30, }, + { 1, 1, 0, 2, 140, 30, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 30, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 30, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 30, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 30, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 30, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 26, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 34, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 34, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 34, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 34, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 34, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 26, }, + { 2, 1, 1, 2, 38, 30, }, + { 1, 1, 1, 2, 38, 30, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 30, }, + { 1, 1, 1, 2, 46, 30, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 30, }, + { 1, 1, 1, 2, 54, 30, }, + { 0, 1, 1, 2, 62, 24, }, + { 2, 1, 1, 2, 62, 30, }, + { 1, 1, 1, 2, 62, 30, }, + { 0, 1, 1, 2, 102, 24, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 30, }, + { 1, 1, 1, 2, 110, 30, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 30, }, + { 1, 1, 1, 2, 118, 30, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 30, }, + { 1, 1, 1, 2, 126, 30, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 30, }, + { 1, 1, 1, 2, 134, 30, }, + { 0, 1, 1, 2, 151, 30, }, + { 2, 1, 1, 2, 151, 30, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 30, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 28, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 30, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 34, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 34, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 34, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 22, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 30, }, + { 0, 1, 2, 4, 58, 20, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 30, }, + { 0, 1, 2, 4, 106, 20, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 20, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 155, 28, }, + { 2, 1, 2, 4, 155, 30, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 28, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 26, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 28, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 32, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8821a_txpwr_lmt); + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821a[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x004F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5) | BIT(4), BIT(5) | BIT(4)}, + {0x0025, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0063, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0058, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x005A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x002E, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x82}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_lps_8821a[] = { + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x0522, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x05F8, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05F9, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FA, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FB, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0100, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x03}, + {0x0101, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0553, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821a[] = { + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x004F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 1}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[] = { + trans_carddis_to_cardemu_8821a, + trans_cardemu_to_act_8821a, + NULL +}; + +const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[] = { + trans_act_to_lps_8821a, + NULL +}; + +const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = { + trans_act_to_cardemu_8821a, + trans_cardemu_to_carddis_8821a, + NULL +}; + +static const u8 rtw8821a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 rtw8821a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 rtw8821a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 rtw8821a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 rtw8821a_pwrtrk_2gb_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 +}; + +static const u8 rtw8821a_pwrtrk_2gb_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8821a_pwrtrk_2ga_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 +}; + +static const u8 rtw8821a_pwrtrk_2ga_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8821a_pwrtrk_2g_cck_b_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 +}; + +static const u8 rtw8821a_pwrtrk_2g_cck_b_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8821a_pwrtrk_2g_cck_a_n[] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 +}; + +static const u8 rtw8821a_pwrtrk_2g_cck_a_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl = { + .pwrtrk_5gb_n[0] = rtw8821a_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821a_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821a_pwrtrk_5gb_n[2], + .pwrtrk_5gb_p[0] = rtw8821a_pwrtrk_5gb_p[0], + .pwrtrk_5gb_p[1] = rtw8821a_pwrtrk_5gb_p[1], + .pwrtrk_5gb_p[2] = rtw8821a_pwrtrk_5gb_p[2], + .pwrtrk_5ga_n[0] = rtw8821a_pwrtrk_5ga_n[0], + .pwrtrk_5ga_n[1] = rtw8821a_pwrtrk_5ga_n[1], + .pwrtrk_5ga_n[2] = rtw8821a_pwrtrk_5ga_n[2], + .pwrtrk_5ga_p[0] = rtw8821a_pwrtrk_5ga_p[0], + .pwrtrk_5ga_p[1] = rtw8821a_pwrtrk_5ga_p[1], + .pwrtrk_5ga_p[2] = rtw8821a_pwrtrk_5ga_p[2], + .pwrtrk_2gb_n = rtw8821a_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8821a_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8821a_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8821a_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8821a_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8821a_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8821a_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8821a_pwrtrk_2g_cck_a_p, +}; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h new file mode 100644 index 000000000..90379ac7a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW8821A_TABLE_H__ +#define __RTW8821A_TABLE_H__ + +extern const struct rtw_table rtw8821a_mac_tbl; +extern const struct rtw_table rtw8821a_agc_tbl; +extern const struct rtw_table rtw8821a_bb_tbl; +extern const struct rtw_table rtw8821a_bb_pg_tbl; +extern const struct rtw_table rtw8821a_rf_a_tbl; +extern const struct rtw_table rtw8821a_txpwr_lmt_tbl; + +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[]; +extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[]; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[]; + +extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821au.c b/drivers/net/wireless/realtek/rtw88/rtw8821au.c new file mode 100644 index 000000000..28c281b32 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8821a.h" +#include "usb.h" + +static const struct usb_device_id rtw_8821au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0820, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0821, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0823, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xa811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0242, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x029b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ + { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0953, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* I-O DATA */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4007, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9052, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Netgear */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0023, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* HAWKING */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3314, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3318, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab32, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Planex */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x804b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TRENDnet */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0120, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3823, 0x6249, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Obihai */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa813, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb611, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); + +static struct usb_driver rtw_8821au_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8821au_id_table, + .probe = rtw_usb_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8821au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c new file mode 100644 index 000000000..ee689fa3d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -0,0 +1,2071 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8821c.h" +#include "rtw8821c_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" +#include "bf.h" +#include "regd.h" + +static const s8 lna_gain_table_0[8] = {22, 8, -6, -22, -31, -40, -46, -52}; +static const s8 lna_gain_table_1[16] = {10, 6, 2, -2, -6, -10, -14, -17, + -20, -24, -28, -31, -34, -37, -40, -44}; + +static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8821c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8821c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->u.mac_addr); +} + +static void rtw8821cs_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8821c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->s.mac_addr); +} + +enum rtw8821ce_rf_set { + SWITCH_TO_BTG, + SWITCH_TO_WLG, + SWITCH_TO_WLA, + SWITCH_TO_BT, +}; + +static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8821c_efuse *map; + int i; + + map = (struct rtw8821c_efuse *)log_map; + + efuse->rfe_option = map->rfe_option & 0x1f; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->pa_type_2g = map->pa_type; + efuse->pa_type_5g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g[0]; + efuse->lna_type_5g = map->lna_type_5g[0]; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + hal->pkg_type = map->rfe_option & BIT(5) ? 1 : 0; + + switch (efuse->rfe_option) { + case 0x2: + case 0x4: + case 0x7: + case 0xa: + case 0xc: + case 0xf: + hal->rfe_btg = true; + break; + } + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + if (rtwdev->efuse.rfe_option == 2 || rtwdev->efuse.rfe_option == 4) + efuse->txpwr_idx_table[0].pwr_idx_2g = map->txpwr_idx_table[1].pwr_idx_2g; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8821ce_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_USB: + rtw8821cu_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_SDIO: + rtw8821cs_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -ENOTSUPP; + } + + return 0; +} + +static const u32 rtw8821c_txscale_tbl[] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u8 rtw8821c_get_swing_index(struct rtw_dev *rtwdev) +{ + u8 i = 0; + u32 swing, table_value; + + swing = rtw_read32_mask(rtwdev, REG_TXSCALE_A, 0xffe00000); + for (i = 0; i < ARRAY_SIZE(rtw8821c_txscale_tbl); i++) { + table_value = rtw8821c_txscale_tbl[i]; + if (swing == table_value) + break; + } + + return i; +} + +static void rtw8821c_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_idx = rtw8821c_get_swing_index(rtwdev); + + if (swing_idx >= ARRAY_SIZE(rtw8821c_txscale_tbl)) + dm_info->default_ofdm_index = 24; + else + dm_info->default_ofdm_index = swing_idx; + + ewma_thermal_init(&dm_info->avg_thermal[RF_PATH_A]); + dm_info->delta_power_index[RF_PATH_A] = 0; + dm_info->delta_power_index_last[RF_PATH_A] = 0; + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev) +{ + rtw_bf_phy_init(rtwdev); + /* Grouping bitmap parameters */ + rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); +} + +static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 crystal_cap, val; + + /* power on BB/RF domain */ + val = rtw_read8(rtwdev, REG_SYS_FUNC_EN); + val |= BIT_FEN_PCIEA; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + + /* toggle BB reset */ + val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + val &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST); + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + + rtw_write8(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + usleep_range(10, 11); + rtw_write8(rtwdev, REG_WLRF1 + 3, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + usleep_range(10, 11); + + /* pre init before header files config */ + rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + rtw_phy_load_tables(rtwdev); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap); + rtw_write32_mask(rtwdev, REG_AFE_PLL_CTRL, 0x7e, crystal_cap); + rtw_write32_mask(rtwdev, REG_CCK0_FAREPORT, BIT(18) | BIT(22), 0); + + /* post init after header files config */ + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + hal->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD); + hal->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD); + hal->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD); + + rtw_phy_init(rtwdev); + rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; + + rtw8821c_pwrtrack_init(rtwdev); + + rtw8821c_phy_bf_init(rtwdev); +} + +static int rtw8821c_mac_init(struct rtw_dev *rtwdev) +{ + u32 value32; + u16 pre_txcnt; + + /* protocol configuration */ + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); + rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); + pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; + rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); + rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); + value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | + (WLAN_MAX_AGG_PKT_LIMIT << 16) | + (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); + rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); + rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, + WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); + rtw_write8_set(rtwdev, REG_INIRTS_RATE_SEL, BIT(5)); + + /* EDCA configuration */ + rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); + rtw_write16(rtwdev, REG_TXPAUSE, 0); + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); + rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); + rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT); + rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT); + rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); + rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); + + /* Set beacon cotnrol - enable TSF and other related functions */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* Set send beacon related registers */ + rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); + + /* WMAC configuration */ + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); + rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40); + rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1)); + rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, + BIT_DIS_CHK_VHTSIGB_CRC); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); + + return 0; +} + +static void rtw8821c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); + ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7); + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +} + +static void rtw8821c_switch_rf_set(struct rtw_dev *rtwdev, u8 rf_set) +{ + u32 reg; + + rtw_write32_set(rtwdev, REG_DMEM_CTRL, BIT_WL_RST); + rtw_write32_set(rtwdev, REG_SYS_CTRL, BIT_FEN_EN); + + reg = rtw_read32(rtwdev, REG_RFECTL); + switch (rf_set) { + case SWITCH_TO_BTG: + reg |= B_BTG_SWITCH; + reg &= ~(B_CTRL_SWITCH | B_WL_SWITCH | B_WLG_SWITCH | + B_WLA_SWITCH); + rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, BTG_CCA); + rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, BTG_LNA); + break; + case SWITCH_TO_WLG: + reg |= B_WL_SWITCH | B_WLG_SWITCH; + reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLA_SWITCH); + rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, WLG_CCA); + rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, WLG_LNA); + break; + case SWITCH_TO_WLA: + reg |= B_WL_SWITCH | B_WLA_SWITCH; + reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLG_SWITCH); + break; + case SWITCH_TO_BT: + default: + break; + } + + rtw_write32(rtwdev, REG_RFECTL, reg); +} + +static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 rf_reg18; + + rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); + + rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | + RF18_BW_MASK); + + rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (channel & RF18_CHANNEL_MASK); + + if (channel >= 100 && channel <= 140) + rf_reg18 |= RF18_RFSI_GE; + else if (channel > 140) + rf_reg18 |= RF18_RFSI_GT; + + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rf_reg18 |= RF18_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_reg18 |= RF18_BW_40M; + break; + case RTW_CHANNEL_WIDTH_80: + rf_reg18 |= RF18_BW_80M; + break; + } + + if (channel <= 14) { + if (hal->rfe_btg) + rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_BTG); + else + rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf); + } else { + rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLA); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x0); + } + + rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1); +} + +static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw) +{ + if (bw == RTW_CHANNEL_WIDTH_40) { + /* RX DFIR for BW40 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); + } else if (bw == RTW_CHANNEL_WIDTH_80) { + /* RX DFIR for BW80 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x1); + } else { + /* RX DFIR for BW20, BW10 and BW5 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); + } +} + +static void rtw8821c_cck_tx_filter_srrc(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + struct rtw_hal *hal = &rtwdev->hal; + + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); + } else if (channel == 13 || + (channel == 11 && bw == RTW_CHANNEL_WIDTH_40)) { + rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xf8fe); + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x64b80c1c); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x8810); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x01235667); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00029); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00026); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); + } else { + rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, + hal->ch_param[0]); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, + hal->ch_param[1] & MASKLWORD); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, + hal->ch_param[2]); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); + } +} + +static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 val32; + + if (channel <= 14) { + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0); + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); + + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0); + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a); + + if (rtw_regd_srrc(rtwdev)) { + rtw8821c_cck_tx_filter_srrc(rtwdev, channel, bw); + goto set_bw; + } + + /* CCK TX filter parameters for default case */ + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); + } else { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, + hal->ch_param[0]); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, + hal->ch_param[1] & MASKLWORD); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, + hal->ch_param[2]); + } + } else if (channel > 35) { + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); + + if (channel >= 36 && channel <= 64) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x1); + else if (channel >= 100 && channel <= 144) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x2); + else if (channel >= 149) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x3); + + if (channel >= 36 && channel <= 48) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494); + else if (channel >= 52 && channel <= 64) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453); + else if (channel >= 100 && channel <= 116) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452); + else if (channel >= 118 && channel <= 177) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412); + } + +set_bw: + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + default: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xffcffc00; + val32 |= 0x10010000; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_40: + if (primary_ch_idx == 1) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xff3ff300; + val32 |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) | + RTW_CHANNEL_WIDTH_40; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_80: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xfcffcf00; + val32 |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) | + RTW_CHANNEL_WIDTH_80; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_5: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xefcefc00; + val32 |= 0x200240; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + case RTW_CHANNEL_WIDTH_10: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xefcefc00; + val32 |= 0x300380; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + } +} + +static u32 rtw8821c_get_bb_swing(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_efuse efuse = rtwdev->efuse; + u8 tx_bb_swing; + u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + + tx_bb_swing = channel <= 14 ? efuse.tx_bb_swing_setting_2g : + efuse.tx_bb_swing_setting_5g; + if (tx_bb_swing > 9) + tx_bb_swing = 0; + + return swing2setting[(tx_bb_swing / 3)]; +} + +static void rtw8821c_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 channel, + u8 bw, u8 primary_ch_idx) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), + rtw8821c_get_bb_swing(rtwdev, channel)); + rtw8821c_pwrtrack_init(rtwdev); +} + +static void rtw8821c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + rtw8821c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); + rtw8821c_set_channel_bb_swing(rtwdev, channel, bw, primary_chan_idx); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8821c_set_channel_rf(rtwdev, channel, bw); + rtw8821c_set_channel_rxdfir(rtwdev, bw); +} + +static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + const s8 *lna_gain_table; + int lna_gain_table_size; + s8 rx_pwr_all = 0; + s8 lna_gain = 0; + + if (efuse->rfe_option == 0) { + lna_gain_table = lna_gain_table_0; + lna_gain_table_size = ARRAY_SIZE(lna_gain_table_0); + } else { + lna_gain_table = lna_gain_table_1; + lna_gain_table_size = ARRAY_SIZE(lna_gain_table_1); + } + + if (lna_idx >= lna_gain_table_size) { + rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); + return -120; + } + + lna_gain = lna_gain_table[lna_idx]; + rx_pwr_all = lna_gain - 2 * vga_idx; + + return rx_pwr_all; +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 rx_power; + u8 lna_idx = 0; + u8 vga_idx = 0; + + vga_idx = GET_PHY_STAT_P0_VGA(phy_status); + lna_idx = FIELD_PREP(BIT_LNA_H_MASK, GET_PHY_STAT_P0_LNA_H(phy_status)) | + FIELD_PREP(BIT_LNA_L_MASK, GET_PHY_STAT_P0_LNA_L(phy_status)); + rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx); + + pkt_stat->rx_power[RF_PATH_A] = rx_power; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = rx_power; +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 rxsc, bw; + s8 min_rx_power = -120; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (rxsc >= 1 && rxsc <= 8) + bw = RTW_CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) + bw = RTW_CHANNEL_WIDTH_40; + else if (rxsc >= 13) + bw = RTW_CHANNEL_WIDTH_80; + else + bw = GET_PHY_STAT_P1_RF_MODE(phy_status); + + pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->bw = bw; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static void +rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) +{ + struct rtw_hal *hal = &rtwdev->hal; + static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate, rate_idx, pwr_index, shift; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + shift = rate & 0x3; + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) { + rate_idx = rate & 0xfc; + rtw_write32(rtwdev, offset_txagc[path] + rate_idx, + *phy_pwr_idx); + *phy_pwr_idx = 0; + } + } +} + +static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { + if (rs == RTW_RATE_SECTION_HT_2S || + rs == RTW_RATE_SECTION_VHT_2S) + continue; + rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); + } + } +} + +static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_enable; + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 crc32_cnt; + u32 cca32_cnt; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15)); + rtw_write32_set(rtwdev, REG_RXDESC, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} + +static void rtw8821c_do_iqk(struct rtw_dev *rtwdev) +{ + static int do_iqk_cnt; + struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0}; + u32 rf_reg, iqk_fail_mask; + int counter; + bool reload; + + if (rtw_is_assoc(rtwdev)) + para.segment_iqk = 1; + + rtw_fw_do_iqk(rtwdev, ¶); + + for (counter = 0; counter < 300; counter++) { + rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK); + if (rf_reg == 0xabcde) + break; + msleep(20); + } + rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0); + + reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16)); + iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0)); + rtw_dbg(rtwdev, RTW_DBG_PHY, + "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n", + counter, reload, ++do_iqk_cnt, iqk_fail_mask); +} + +static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8821c_do_iqk(rtwdev); +} + +/* for coex */ +static void rtw8821c_coex_cfg_init(struct rtw_dev *rtwdev) +{ + /* enable TBTT nterrupt */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* BT report packet sample rate */ + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, BT_CNT_ENABLE); + + /* enable PTA (3-wire function form BT side) */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); + + /* enable PTA (tx/rx signal form WiFi side) */ + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); + /* wl tx signal to PTA not case EDCCA */ + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); + /* GNT_BT=1 while select both */ + rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); + + /* beacon queue always hi-pri */ + rtw_write8_mask(rtwdev, REG_BT_COEX_TABLE_H + 3, BIT_BCN_QUEUE, + BCN_PRI_EN); +} + +static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + u8 pos_type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + u32 switch_status = FIELD_PREP(CTRL_TYPE_MASK, ctrl_type) | pos_type; + bool polarity_inverse; + u8 regval = 0; + + if (switch_status == coex_dm->cur_switch_status) + return; + + if (coex_rfe->wlg_at_btg) { + ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; + + if (coex_rfe->ant_switch_polarity) + pos_type = COEX_SWITCH_TO_WLA; + else + pos_type = COEX_SWITCH_TO_WLG_BT; + } + + coex_dm->cur_switch_status = switch_status; + + if (coex_rfe->ant_switch_diversity && + ctrl_type == COEX_SWITCH_CTRL_BY_BBSW) + ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV; + + polarity_inverse = (coex_rfe->ant_switch_polarity == 1); + + switch (ctrl_type) { + default: + case COEX_SWITCH_CTRL_BY_BBSW: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, + DPDT_CTRL_PIN); + + if (pos_type == COEX_SWITCH_TO_WLG_BT) { + if (coex_rfe->rfe_module_type != 0x4 && + coex_rfe->rfe_module_type != 0x2) + regval = 0x3; + else + regval = (!polarity_inverse ? 0x2 : 0x1); + } else if (pos_type == COEX_SWITCH_TO_WLG) { + regval = (!polarity_inverse ? 0x2 : 0x1); + } else { + regval = (!polarity_inverse ? 0x1 : 0x2); + } + + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, + regval); + break; + case COEX_SWITCH_CTRL_BY_PTA: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, + PTA_CTRL_PIN); + + regval = (!polarity_inverse ? 0x2 : 0x1); + rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, + regval); + break; + case COEX_SWITCH_CTRL_BY_ANTDIV: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, + ANTDIC_CTRL_PIN); + break; + case COEX_SWITCH_CTRL_BY_MAC: + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + + regval = (!polarity_inverse ? 0x0 : 0x1); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, + regval); + break; + case COEX_SWITCH_CTRL_BY_FW: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + break; + case COEX_SWITCH_CTRL_BY_BT: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); + break; + } + + if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) { + rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); + rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } else { + rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); + rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } +} + +static void rtw8821c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{} + +static void rtw8821c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ + rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_SPI_EN); + rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_JTAG_EN); + rtw_write32_clr(rtwdev, REG_GPIO_MUXCFG, BIT_FSPI_EN); + rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_LED1DIS); + rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_SDIO_INT); + rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_DBG_GNT_WL_BT); +} + +static void rtw8821c_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + struct rtw_efuse *efuse = &rtwdev->efuse; + + coex_rfe->rfe_module_type = efuse->rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_exist = true; + coex_rfe->wlg_at_btg = false; + + switch (coex_rfe->rfe_module_type) { + case 0: + case 8: + case 1: + case 9: /* 1-Ant, Main, WLG */ + default: /* 2-Ant, DPDT, WLG */ + break; + case 2: + case 10: /* 1-Ant, Main, BTG */ + case 7: + case 15: /* 2-Ant, DPDT, BTG */ + coex_rfe->wlg_at_btg = true; + break; + case 3: + case 11: /* 1-Ant, Aux, WLG */ + coex_rfe->ant_switch_polarity = 1; + break; + case 4: + case 12: /* 1-Ant, Aux, BTG */ + coex_rfe->wlg_at_btg = true; + coex_rfe->ant_switch_polarity = 1; + break; + case 5: + case 13: /* 2-Ant, no switch, WLG */ + case 6: + case 14: /* 2-Ant, no antenna switch, WLG */ + coex_rfe->ant_switch_exist = false; + break; + } +} + +static void rtw8821c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool share_ant = efuse->share_ant; + + if (share_ant) + return; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; +} + +static void rtw8821c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{} + +static void +rtw8821c_txagc_swing_offset(struct rtw_dev *rtwdev, u8 pwr_idx_offset, + s8 pwr_idx_offset_lower, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 delta_pwr_idx = dm_info->delta_power_index[RF_PATH_A]; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + u8 swing_lower_bound = 0; + u8 max_pwr_idx_offset = 0xf; + s8 agc_index = 0; + u8 swing_index = dm_info->default_ofdm_index; + + pwr_idx_offset = min_t(u8, pwr_idx_offset, max_pwr_idx_offset); + pwr_idx_offset_lower = max_t(s8, pwr_idx_offset_lower, -15); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > pwr_idx_offset) { + agc_index = pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else if (delta_pwr_idx < 0) { + if (delta_pwr_idx >= pwr_idx_offset_lower) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx < pwr_idx_offset_lower) { + if (dm_info->default_ofdm_index > + (pwr_idx_offset_lower - delta_pwr_idx)) + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - pwr_idx_offset_lower; + else + swing_index = swing_lower_bound; + + agc_index = pwr_idx_offset_lower; + } + } + + if (swing_index >= ARRAY_SIZE(rtw8821c_txscale_tbl)) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = ARRAY_SIZE(rtw8821c_txscale_tbl) - 1; + } + + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8821c_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 pwr_idx_offset, + s8 pwr_idx_offset_lower) +{ + s8 txagc_idx; + u8 swing_idx; + + rtw8821c_txagc_swing_offset(rtwdev, pwr_idx_offset, pwr_idx_offset_lower, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, GENMASK(6, 1), txagc_idx); + rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), + rtw8821c_txscale_tbl[swing_idx]); +} + +static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pwr_idx_offset, tx_pwr_idx; + s8 pwr_idx_offset_lower; + u8 channel = rtwdev->hal.current_channel; + u8 band_width = rtwdev->hal.current_band_width; + u8 regd = rtw_regd_get(rtwdev); + u8 tx_rate = dm_info->tx_rate; + u8 max_pwr_idx = rtwdev->chip->max_power_index; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, RF_PATH_A, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + pwr_idx_offset_lower = 0 - tx_pwr_idx; + + rtw8821c_pwrtrack_set_pwr(rtwdev, pwr_idx_offset, pwr_idx_offset_lower); +} + +static void rtw8821c_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, delta; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); + + dm_info->delta_power_index[RF_PATH_A] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, RF_PATH_A, + RF_PATH_A, delta); + if (dm_info->delta_power_index[RF_PATH_A] == + dm_info->delta_power_index_last[RF_PATH_A]) + goto iqk; + else + dm_info->delta_power_index_last[RF_PATH_A] = + dm_info->delta_power_index[RF_PATH_A]; + rtw8821c_pwrtrack_set(rtwdev); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8821c_do_iqk(rtwdev); +} + +static void rtw8821c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8821c_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + +static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; + u8 cck_n_rx; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + cck_n_rx = (rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_2RX) && + rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_MRC)) ? 2 : 1; + rtw_dbg(rtwdev, RTW_DBG_PHY, + "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x, cck_fa_avg=%d\n", + rtw_is_assoc(rtwdev), new_lvl, cck_n_rx, + dm_info->cck_pd_default + new_lvl * 2, + pd[new_lvl], dm_info->cck_fa_avg); + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]); + rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000, + dm_info->cck_pd_default + new_lvl * 2); +} + +static void rtw8821c_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + fill_txdesc_checksum_common(txdesc, 16); +} + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, + {0x0300, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0074, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0022, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), + (BIT(7) | BIT(6) | BIT(5))}, + {0x0061, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, + {0x007C, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x004F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0090, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0044, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0040, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x90}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = { + trans_carddis_to_cardemu_8821c, + trans_cardemu_to_act_8821c, + NULL +}; + +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = { + trans_act_to_cardemu_8821c, + trans_cardemu_to_carddis_8821c, + NULL +}; + +static const struct rtw_intf_phy_para usb2_param_8821c[] = { + {0xFFFF, 0x00, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para usb3_param_8821c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen1_param_8821c[] = { + {0x0009, 0x6380, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen2_param_8821c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8821c = { + .usb2_para = usb2_param_8821c, + .usb3_para = usb3_param_8821c, + .gen1_para = pcie_gen1_param_8821c, + .gen2_para = pcie_gen2_param_8821c, + .n_usb2_para = ARRAY_SIZE(usb2_param_8821c), + .n_usb3_para = ARRAY_SIZE(usb2_param_8821c), + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8821c), + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), +}; + +static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, +}; + +static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + +static const struct rtw_page_table page_table_8821c[] = { + /* not sure what [0] stands for */ + {16, 16, 16, 14, 1}, + {16, 16, 16, 14, 1}, + {16, 16, 0, 0, 1}, + {16, 16, 16, 0, 1}, + {16, 16, 16, 14, 1}, +}; + +static const struct rtw_rqpn rqpn_table_8821c[] = { + /* not sure what [0] stands for */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8821c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static const struct rtw_chip_ops rtw8821c_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_phy_status = query_phy_status, + .set_channel = rtw8821c_set_channel, + .mac_init = rtw8821c_mac_init, + .mac_postinit = NULL, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw8821c_set_tx_power_index, + .cfg_ldo25 = rtw8821c_cfg_ldo25, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw8821c_false_alarm_statistics, + .phy_calibration = rtw8821c_phy_calibration, + .cck_pd_set = rtw8821c_phy_cck_pd_set, + .pwr_track = rtw8821c_pwr_track, + .config_bfee = rtw8821c_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .led_set = rtw8821c_led_set, + .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, + + .coex_set_init = rtw8821c_coex_cfg_init, + .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8821c_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8821c_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8821c_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8821c_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8821c_coex_cfg_wl_rx_gain, +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8821c[] = {101, 45, 101, 40}; +static const u8 bt_rssi_step_8821c[] = {101, 101, 101, 101}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8821c[] = { + {0x55555555, 0x55555555}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0xaaaaaaaa}, + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x6aaa6aaa}, + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x66555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8821c[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0xffff55ff, 0xfafafafa}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xffffffff, 0xffffffff}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-110 */ + {0x66555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xffff55ff, 0xffff55ff}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffff55ff, 0xfafafafa}, + {0xffffffff, 0xaaaaaaaa}, /* case-120 */ + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0x5afa5afa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8821c[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x35, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x35, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x15} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x11, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x08, 0x03, 0x30, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8821c[] = { + { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, + { {0x61, 0x25, 0x03, 0x11, 0x11} }, + { {0x61, 0x35, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x10, 0x03, 0x11, 0x11} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, + { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x10, 0x03, 0x10, 0x50} } +}; + +static const struct coex_5g_afh_map afh_5g_8821c[] = { {0, 0, 0} }; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8821c[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {8, 17, true, 4}, + {7, 18, true, 4}, + {6, 19, true, 4}, + {5, 20, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8821c[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {3, 24, true, 5}, + {2, 26, true, 5}, + {1, 27, true, 5}, + {0, 28, true, 5} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8821c) == ARRAY_SIZE(rf_para_rx_8821c)); + +static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_2gb_n[] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 +}; + +static const u8 rtw8821c_pwrtrk_2gb_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2ga_n[] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 +}; + +static const u8 rtw8821c_pwrtrk_2ga_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_b_n[] = { + 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_b_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_a_n[] = { + 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 +}; + +static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], + .pwrtrk_5gb_p[0] = rtw8821c_pwrtrk_5gb_p[0], + .pwrtrk_5gb_p[1] = rtw8821c_pwrtrk_5gb_p[1], + .pwrtrk_5gb_p[2] = rtw8821c_pwrtrk_5gb_p[2], + .pwrtrk_5ga_n[0] = rtw8821c_pwrtrk_5ga_n[0], + .pwrtrk_5ga_n[1] = rtw8821c_pwrtrk_5ga_n[1], + .pwrtrk_5ga_n[2] = rtw8821c_pwrtrk_5ga_n[2], + .pwrtrk_5ga_p[0] = rtw8821c_pwrtrk_5ga_p[0], + .pwrtrk_5ga_p[1] = rtw8821c_pwrtrk_5ga_p[1], + .pwrtrk_5ga_p[2] = rtw8821c_pwrtrk_5ga_p[2], + .pwrtrk_2gb_n = rtw8821c_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8821c_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8821c_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8821c_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8821c_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8821c_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8821c_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, +}; + +static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { + [0] = RTW_DEF_RFE(8821c, 0, 0, 0), + [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), + [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), + [6] = RTW_DEF_RFE(8821c, 0, 0, 0), +}; + +static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = { + {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + +const struct rtw_chip_info rtw8821c_hw_spec = { + .ops = &rtw8821c_ops, + .id = RTW_CHIP_TYPE_8821C, + .fw_name = "rtw88/rtw8821c_fw.bin", + .wlan_cpu = RTW_WCPU_3081, + .tx_pkt_desc_sz = 48, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 96, + .txff_size = 65536, + .rxff_size = 16384, + .rsvd_drv_pg_num = 8, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .amsdu_in_ampdu = true, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), + .sys_func_en = 0xD8, + .pwr_on_seq = card_enable_flow_8821c, + .pwr_off_seq = card_disable_flow_8821c, + .page_table = page_table_8821c, + .rqpn_table = rqpn_table_8821c, + .prioq_addrs = &prioq_addrs_8821c, + .intf_table = &phy_para_table_8821c, + .dig = rtw8821c_dig, + .rf_base_addr = {0x2800, 0x2c00}, + .rf_sipi_addr = {0xc90, 0xe90}, + .ltecoex_addr = &rtw8821c_ltecoex_addr, + .mac_tbl = &rtw8821c_mac_tbl, + .agc_tbl = &rtw8821c_agc_tbl, + .bb_tbl = &rtw8821c_bb_tbl, + .rf_tbl = {&rtw8821c_rf_a_tbl}, + .rfe_defs = rtw8821c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0x19092746, + .bt_desired_ver = 0x46, + .scbd_support = true, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8821c, + .bt_rssi_step = bt_rssi_step_8821c, + .table_sant_num = ARRAY_SIZE(table_sant_8821c), + .table_sant = table_sant_8821c, + .table_nsant_num = ARRAY_SIZE(table_nsant_8821c), + .table_nsant = table_nsant_8821c, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821c), + .tdma_sant = tdma_sant_8821c, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821c), + .tdma_nsant = tdma_nsant_8821c, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821c), + .wl_rf_para_tx = rf_para_tx_8821c, + .wl_rf_para_rx = rf_para_rx_8821c, + .bt_afh_span_bw20 = 0x24, + .bt_afh_span_bw40 = 0x36, + .afh_5g_num = ARRAY_SIZE(afh_5g_8821c), + .afh_5g = afh_5g_8821c, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821c), + .coex_info_hw_regs = coex_info_hw_regs_8821c, +}; +EXPORT_SYMBOL(rtw8821c_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8821c_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821c driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h new file mode 100644 index 000000000..ea85b7e73 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8821C_H__ +#define __RTW8821C_H__ + +#include + +#define RCR_VHT_ACK BIT(26) + +struct rtw8821cu_efuse { + u8 res4[4]; /* 0xd0 */ + u8 usb_optional_function; + u8 res5[0x1e]; + u8 res6[2]; + u8 serial[0x0b]; /* 0xf5 */ + u8 vid; /* 0x100 */ + u8 res7; + u8 pid; + u8 res8[4]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 res9[2]; + u8 vendor_name[0x07]; + u8 res10[2]; + u8 device_name[0x14]; + u8 res11[0xcf]; + u8 package_type; /* 0x1fb */ + u8 res12[0x4]; +} __packed; + +struct rtw8821ce_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vender_id[2]; + u8 device_id[2]; + u8 sub_vender_id[2]; + u8 sub_device_id[2]; + u8 pmc[2]; + u8 exp_device_cap[2]; + u8 msi_cap; + u8 ltr_cap; /* 0xe3 */ + u8 exp_link_control[2]; + u8 link_cap[4]; + u8 link_control[2]; + u8 serial_number[8]; + u8 res0:2; /* 0xf4 */ + u8 ltr_en:1; + u8 res1:2; + u8 obff:2; + u8 res2_1:1; + u8 res2_2:2; + u8 obff_cap:2; + u8 res3:4; + u8 res4[3]; + u8 class_code[3]; + u8 pci_pm_L1_2_supp:1; + u8 pci_pm_L1_1_supp:1; + u8 aspm_pm_L1_2_supp:1; + u8 aspm_pm_L1_1_supp:1; + u8 L1_pm_substates_supp:1; + u8 res5:3; + u8 port_common_mode_restore_time; + u8 port_t_power_on_scale:2; + u8 res6:1; + u8 port_t_power_on_value:5; + u8 res7; +} __packed; + +struct rtw8821cs_efuse { + u8 res4[0x4a]; /* 0xd0 */ + u8 mac_addr[ETH_ALEN]; /* 0x11a */ +} __packed; + +struct rtw8821c_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res[3]; + union { + struct rtw8821ce_efuse e; + struct rtw8821cu_efuse u; + struct rtw8821cs_efuse s; + }; +} __packed; + +static inline void +_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) +{ + /* 0xC00-0xCFF and 0xE00-0xEFF have the same layout */ + rtw_write32_mask(rtwdev, addr, mask, data); + rtw_write32_mask(rtwdev, addr + 0x200, mask, data); +} + +extern const struct rtw_chip_info rtw8821c_hw_spec; + +#define rtw_write32s_mask(rtwdev, addr, mask, data) \ + do { \ + BUILD_BUG_ON((addr) < 0xC00 || (addr) >= 0xD00); \ + \ + _rtw_write32s_mask(rtwdev, addr, mask, data); \ + } while (0) + +#define BIT_FEN_PCIEA BIT(6) +#define WLAN_SLOT_TIME 0x09 +#define WLAN_PIFS_TIME 0x19 +#define WLAN_SIFS_CCK_CONT_TX 0xA +#define WLAN_SIFS_OFDM_CONT_TX 0xE +#define WLAN_SIFS_CCK_TRX 0x10 +#define WLAN_SIFS_OFDM_TRX 0x10 +#define WLAN_VO_TXOP_LIMIT 0x186 +#define WLAN_VI_TXOP_LIMIT 0x3BC +#define WLAN_RDG_NAV 0x05 +#define WLAN_TXOP_NAV 0x1B +#define WLAN_CCK_RX_TSF 0x30 +#define WLAN_OFDM_RX_TSF 0x30 +#define WLAN_TBTT_PROHIBIT 0x04 +#define WLAN_TBTT_HOLD_TIME 0x064 +#define WLAN_DRV_EARLY_INT 0x04 +#define WLAN_BCN_DMA_TIME 0x02 + +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0x0FFF +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0xE400220E +#define WLAN_RXPKT_MAX_SZ 12288 +#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) + +#define WLAN_AMPDU_MAX_TIME 0x70 +#define WLAN_RTS_LEN_TH 0xFF +#define WLAN_RTS_TX_TIME_TH 0x08 +#define WLAN_MAX_AGG_PKT_LIMIT 0x20 +#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20 +#define FAST_EDCA_VO_TH 0x06 +#define FAST_EDCA_VI_TH 0x06 +#define FAST_EDCA_BE_TH 0x06 +#define FAST_EDCA_BK_TH 0x06 +#define WLAN_BAR_RETRY_LIMIT 0x01 +#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 + +#define WLAN_TX_FUNC_CFG1 0x30 +#define WLAN_TX_FUNC_CFG2 0x30 +#define WLAN_MAC_OPT_NORM_FUNC1 0x98 +#define WLAN_MAC_OPT_LB_FUNC1 0x80 +#define WLAN_MAC_OPT_FUNC2 0xb0810041 + +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) + +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) +#define WLAN_PRE_TXCNT_TIME_TH 0x1E4 + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P0_VGA(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(12, 8)) +#define GET_PHY_STAT_P0_LNA_L(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(15, 13)) +#define GET_PHY_STAT_P0_LNA_H(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), BIT(23)) +#define BIT_LNA_H_MASK BIT(3) +#define BIT_LNA_L_MASK GENMASK(2, 0) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) + +#define REG_SYS_CTRL 0x000 +#define BIT_FEN_EN BIT(26) +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_HTSTFWT 0x800 +#define REG_RXCCAMSK 0x814 +#define REG_L1WT 0x83c +#define REG_L1PKWT 0x840 +#define REG_MRC 0x850 +#define REG_ADC40 0x8c8 +#define REG_CHFIR 0x8f0 +#define REG_CDDTXP 0x93c +#define REG_TXPSEL1 0x940 +#define REG_ACBB0 0x948 +#define REG_ACBBRXFIR 0x94c +#define REG_ACGG2TBL 0x958 +#define REG_ADCINI 0xa04 +#define REG_PWRTH 0xa08 +#define REG_CCA_FLTR 0xa20 +#define REG_TXSF2 0xa24 +#define REG_TXSF6 0xa28 +#define REG_RXDESC 0xa2c +#define REG_ENTXCCK 0xa80 +#define BTG_LNA 0xfc84 +#define WLG_LNA 0x7532 +#define REG_ENRXCCA 0xa84 +#define BTG_CCA 0x0e +#define WLG_CCA 0x12 +#define REG_PWRTH2 0xaa8 +#define REG_CSRATIO 0xaaa +#define REG_TXFILTER 0xaac +#define REG_AGCTR_A 0xc08 +#define REG_TXDFIR 0xc20 +#define REG_TRSW 0xca0 +#define REG_RFESEL0 0xcb0 +#define REG_RFESEL8 0xcb4 +#define REG_RFECTL 0xcb8 +#define B_BTG_SWITCH BIT(16) +#define B_CTRL_SWITCH BIT(18) +#define B_WL_SWITCH (BIT(20) | BIT(22)) +#define B_WLG_SWITCH BIT(21) +#define B_WLA_SWITCH BIT(23) +#define REG_RFEINV 0xcbc +#define REG_AGCTR_B 0xe08 +#define REG_DMEM_CTRL 0x1080 +#define BIT_WL_RST BIT(16) +#define REG_ANTWT 0x1904 +#define REG_IQKFAILMSK 0x1bf0 +#define BIT_MASK_R_RFE_SEL_15 GENMASK(31, 28) +#define BIT_SDIO_INT BIT(18) +#define BT_CNT_ENABLE 0x1 +#define BIT_BCN_QUEUE BIT(3) +#define BCN_PRI_EN 0x1 +#define PTA_CTRL_PIN 0x66 +#define DPDT_CTRL_PIN 0x77 +#define ANTDIC_CTRL_PIN 0x88 +#define REG_CTRL_TYPE 0x67 +#define BIT_CTRL_TYPE1 BIT(5) +#define BIT_CTRL_TYPE2 BIT(4) +#define CTRL_TYPE_MASK GENMASK(15, 8) + +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_BAND_2G (0) +#define RF18_BAND_5G (BIT(16) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF18_RFSI_GE (BIT(17)) +#define RF18_RFSI_GT (BIT(18)) +#define RF18_BW_MASK (BIT(11) | BIT(10)) +#define RF18_BW_20M (BIT(11) | BIT(10)) +#define RF18_BW_40M (BIT(11)) +#define RF18_BW_80M (BIT(10)) + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c new file mode 100644 index 000000000..0393b9a0c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c @@ -0,0 +1,7504 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8821c_table.h" + +static const u32 rtw8821c_mac[] = { + 0x010, 0x00000043, + 0x025, 0x0000001D, + 0x026, 0x000000CE, + 0x04F, 0x00000001, + 0x029, 0x000000F9, + 0x420, 0x00000080, + 0x421, 0x0000001F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x000000F0, + 0x446, 0x00000001, + 0x447, 0x000000FE, + 0x448, 0x00000000, + 0x449, 0x00000000, + 0x44A, 0x00000000, + 0x44B, 0x00000040, + 0x44C, 0x00000010, + 0x44D, 0x000000F0, + 0x44E, 0x0000003F, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x00000000, + 0x452, 0x00000000, + 0x453, 0x00000040, + 0x455, 0x00000070, + 0x45E, 0x00000004, + 0x49C, 0x00000010, + 0x49D, 0x000000F0, + 0x49E, 0x00000000, + 0x49F, 0x00000006, + 0x4A0, 0x000000E0, + 0x4A1, 0x00000003, + 0x4A2, 0x00000000, + 0x4A3, 0x00000040, + 0x4A4, 0x00000015, + 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, + 0x4A7, 0x00000006, + 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, + 0x4AA, 0x00000000, + 0x4AB, 0x00000000, + 0x7DA, 0x00000008, + 0x1448, 0x00000006, + 0x144A, 0x00000006, + 0x144C, 0x00000006, + 0x144E, 0x00000006, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4CF, 0x00000008, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x521, 0x0000002F, + 0x525, 0x0000004F, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x577, 0x0000000B, + 0x578, 0x00000014, + 0x579, 0x00000014, + 0x57A, 0x00000014, + 0x5BE, 0x00000064, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x00000022, + 0x60C, 0x00000018, + 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, + 0x6A2, 0x000000FF, + 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, + 0x6A5, 0x000000FF, + 0x6DE, 0x00000084, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, + 0x7D4, 0x00000098, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_mac, rtw_phy_cfg_mac); + +static const u32 rtw8821c_agc[] = { + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xE52C0003, + 0x81C, 0xE42E0003, + 0x81C, 0xE3300003, + 0x81C, 0xE2320003, + 0x81C, 0xE1340003, + 0x81C, 0xC4360003, + 0x81C, 0xC3380003, + 0x81C, 0xC23A0003, + 0x81C, 0xC13C0003, + 0x81C, 0x883E0003, + 0x81C, 0x87400003, + 0x81C, 0x86420003, + 0x81C, 0x85440003, + 0x81C, 0x84460003, + 0x81C, 0x83480003, + 0x81C, 0x824A0003, + 0x81C, 0x814C0003, + 0x81C, 0x804E0003, + 0x81C, 0x64500003, + 0x81C, 0x63520003, + 0x81C, 0x62540003, + 0x81C, 0x61560003, + 0x81C, 0x60580003, + 0x81C, 0x475A0003, + 0x81C, 0x465C0003, + 0x81C, 0x455E0003, + 0x81C, 0x44600003, + 0x81C, 0x43620003, + 0x81C, 0x42640003, + 0x81C, 0x41660003, + 0x81C, 0x40680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x056E0003, + 0x81C, 0x04700003, + 0x81C, 0x03720003, + 0x81C, 0x02740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xE52C0003, + 0x81C, 0xE42E0003, + 0x81C, 0xE3300003, + 0x81C, 0xE2320003, + 0x81C, 0xE1340003, + 0x81C, 0xC4360003, + 0x81C, 0xC3380003, + 0x81C, 0xC23A0003, + 0x81C, 0xC13C0003, + 0x81C, 0x883E0003, + 0x81C, 0x87400003, + 0x81C, 0x86420003, + 0x81C, 0x85440003, + 0x81C, 0x84460003, + 0x81C, 0x83480003, + 0x81C, 0x824A0003, + 0x81C, 0x814C0003, + 0x81C, 0x804E0003, + 0x81C, 0x64500003, + 0x81C, 0x63520003, + 0x81C, 0x62540003, + 0x81C, 0x61560003, + 0x81C, 0x60580003, + 0x81C, 0x475A0003, + 0x81C, 0x465C0003, + 0x81C, 0x455E0003, + 0x81C, 0x44600003, + 0x81C, 0x43620003, + 0x81C, 0x42640003, + 0x81C, 0x41660003, + 0x81C, 0x40680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x056E0003, + 0x81C, 0x04700003, + 0x81C, 0x03720003, + 0x81C, 0x02740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0xA0000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xCA2C0003, + 0x81C, 0xC92E0003, + 0x81C, 0xC8300003, + 0x81C, 0xC7320003, + 0x81C, 0xC6340003, + 0x81C, 0xC5360003, + 0x81C, 0xC4380003, + 0x81C, 0xC33A0003, + 0x81C, 0xC23C0003, + 0x81C, 0xC13E0003, + 0x81C, 0x88400003, + 0x81C, 0x87420003, + 0x81C, 0x86440003, + 0x81C, 0x85460003, + 0x81C, 0x84480003, + 0x81C, 0x834A0003, + 0x81C, 0x674C0003, + 0x81C, 0x664E0003, + 0x81C, 0x65500003, + 0x81C, 0x64520003, + 0x81C, 0x63540003, + 0x81C, 0x62560003, + 0x81C, 0x61580003, + 0x81C, 0x455A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x25640003, + 0x81C, 0x24660003, + 0x81C, 0x23680003, + 0x81C, 0x226A0003, + 0x81C, 0x216C0003, + 0x81C, 0x016E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xE03A0103, + 0x81C, 0xC33C0103, + 0x81C, 0xC23E0103, + 0x81C, 0xC1400103, + 0x81C, 0xC0420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x60560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x225C0103, + 0x81C, 0x215E0103, + 0x81C, 0x20600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF6000103, + 0x81C, 0xF5020103, + 0x81C, 0xF4040103, + 0x81C, 0xF3060103, + 0x81C, 0xF2080103, + 0x81C, 0xF10A0103, + 0x81C, 0xF00C0103, + 0x81C, 0xEF0E0103, + 0x81C, 0xEE100103, + 0x81C, 0xED120103, + 0x81C, 0xEC140103, + 0x81C, 0xCE160103, + 0x81C, 0xEA180103, + 0x81C, 0xE91A0103, + 0x81C, 0xE81C0103, + 0x81C, 0xE71E0103, + 0x81C, 0xE6200103, + 0x81C, 0xE5220103, + 0x81C, 0xE4240103, + 0x81C, 0xE3260103, + 0x81C, 0xE2280103, + 0x81C, 0xE12A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xA62E0103, + 0x81C, 0xC1300103, + 0x81C, 0xA4320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0x833A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x63400103, + 0x81C, 0x62420103, + 0x81C, 0x61440103, + 0x81C, 0x60460103, + 0x81C, 0x25480103, + 0x81C, 0x244A0103, + 0x81C, 0x234C0103, + 0x81C, 0x064E0103, + 0x81C, 0x21500103, + 0x81C, 0x04520103, + 0x81C, 0x03540103, + 0x81C, 0x02560103, + 0x81C, 0x01580103, + 0x81C, 0x005A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xE03A0103, + 0x81C, 0xA83C0103, + 0x81C, 0xA73E0103, + 0x81C, 0xA6400103, + 0x81C, 0xA5420103, + 0x81C, 0xA4440103, + 0x81C, 0xA3460103, + 0x81C, 0xA2480103, + 0x81C, 0xA14A0103, + 0x81C, 0x834C0103, + 0x81C, 0x824E0103, + 0x81C, 0x81500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x61560103, + 0x81C, 0x25580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000203, + 0x81C, 0xFA020203, + 0x81C, 0xF9040203, + 0x81C, 0xF8060203, + 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, + 0x81C, 0xF50C0203, + 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, + 0x81C, 0xF2120203, + 0x81C, 0xF1140203, + 0x81C, 0xF0160203, + 0x81C, 0xEF180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xE1340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xC23C0203, + 0x81C, 0xC13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0xA0480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x60560203, + 0x81C, 0x23580203, + 0x81C, 0x225A0203, + 0x81C, 0x215C0203, + 0x81C, 0x205E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF6000203, + 0x81C, 0xF5020203, + 0x81C, 0xF4040203, + 0x81C, 0xF3060203, + 0x81C, 0xF2080203, + 0x81C, 0xF10A0203, + 0x81C, 0xF00C0203, + 0x81C, 0xEF0E0203, + 0x81C, 0xEE100203, + 0x81C, 0xED120203, + 0x81C, 0xEC140203, + 0x81C, 0xEB160203, + 0x81C, 0xEA180203, + 0x81C, 0xE91A0203, + 0x81C, 0xE81C0203, + 0x81C, 0xE71E0203, + 0x81C, 0xE6200203, + 0x81C, 0xE5220203, + 0x81C, 0xE4240203, + 0x81C, 0xE3260203, + 0x81C, 0xE2280203, + 0x81C, 0xE12A0203, + 0x81C, 0xE02C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x833C0203, + 0x81C, 0x823E0203, + 0x81C, 0x81400203, + 0x81C, 0x80420203, + 0x81C, 0x62440203, + 0x81C, 0x61460203, + 0x81C, 0x42480203, + 0x81C, 0x414A0203, + 0x81C, 0x234C0203, + 0x81C, 0x224E0203, + 0x81C, 0x21500203, + 0x81C, 0x20520203, + 0x81C, 0x03540203, + 0x81C, 0x02560203, + 0x81C, 0x01580203, + 0x81C, 0x005A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xC23E0203, + 0x81C, 0xA6400203, + 0x81C, 0xA5420203, + 0x81C, 0xA4440203, + 0x81C, 0xA3460203, + 0x81C, 0xA2480203, + 0x81C, 0x844A0203, + 0x81C, 0x834C0203, + 0x81C, 0x824E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xC4360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x644E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x60560303, + 0x81C, 0x23580303, + 0x81C, 0x225A0303, + 0x81C, 0x215C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF5000303, + 0x81C, 0xF4020303, + 0x81C, 0xF3040303, + 0x81C, 0xF2060303, + 0x81C, 0xF1080303, + 0x81C, 0xF00A0303, + 0x81C, 0xEF0C0303, + 0x81C, 0xEE0E0303, + 0x81C, 0xED100303, + 0x81C, 0xEC120303, + 0x81C, 0xEB140303, + 0x81C, 0xEA160303, + 0x81C, 0xE9180303, + 0x81C, 0xE81A0303, + 0x81C, 0xE71C0303, + 0x81C, 0xE61E0303, + 0x81C, 0xE5200303, + 0x81C, 0xE4220303, + 0x81C, 0xE3240303, + 0x81C, 0xE2260303, + 0x81C, 0xE1280303, + 0x81C, 0xE02A0303, + 0x81C, 0xA72C0303, + 0x81C, 0xA62E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x643E0303, + 0x81C, 0x63400303, + 0x81C, 0x62420303, + 0x81C, 0x61440303, + 0x81C, 0x60460303, + 0x81C, 0x24480303, + 0x81C, 0x234A0303, + 0x81C, 0x224C0303, + 0x81C, 0x054E0303, + 0x81C, 0x04500303, + 0x81C, 0x03520303, + 0x81C, 0x02540303, + 0x81C, 0x01560303, + 0x81C, 0x00580303, + 0x81C, 0x005A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xE1360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xC23C0303, + 0x81C, 0xC13E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0xA1480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x24580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000022, + 0xA0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xB0000000, 0x00000000, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_agc, rtw_phy_cfg_agc); + +static const u32 rtw8821c_agc_btg_type2[] = { + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000013, + 0x81C, 0xFE020013, + 0x81C, 0xFD040013, + 0x81C, 0xFC060013, + 0x81C, 0xFB080013, + 0x81C, 0xFA0A0013, + 0x81C, 0xF90C0013, + 0x81C, 0xF80E0013, + 0x81C, 0xF7100013, + 0x81C, 0xF6120013, + 0x81C, 0xF5140013, + 0x81C, 0xF4160013, + 0x81C, 0xF3180013, + 0x81C, 0xF21A0013, + 0x81C, 0xF11C0013, + 0x81C, 0xF01E0013, + 0x81C, 0xEF200013, + 0x81C, 0xEE220013, + 0x81C, 0xED240013, + 0x81C, 0xEC260013, + 0x81C, 0xEB280013, + 0x81C, 0xEA2A0013, + 0x81C, 0xE92C0013, + 0x81C, 0xE82E0013, + 0x81C, 0xE7300013, + 0x81C, 0x8B320013, + 0x81C, 0x8A340013, + 0x81C, 0x89360013, + 0x81C, 0x88380013, + 0x81C, 0x873A0013, + 0x81C, 0x863C0013, + 0x81C, 0x853E0013, + 0x81C, 0x84400013, + 0x81C, 0x83420013, + 0x81C, 0x82440013, + 0x81C, 0x81460013, + 0x81C, 0x08480013, + 0x81C, 0x074A0013, + 0x81C, 0x064C0013, + 0x81C, 0x054E0013, + 0x81C, 0x04500013, + 0x81C, 0x03520013, + 0x81C, 0x88540003, + 0x81C, 0x87560003, + 0x81C, 0x86580003, + 0x81C, 0x855A0003, + 0x81C, 0x845C0003, + 0x81C, 0x835E0003, + 0x81C, 0x82600003, + 0x81C, 0x81620003, + 0x81C, 0x07640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0x81C, 0xFF000813, + 0x81C, 0xFE020813, + 0x81C, 0xFD040813, + 0x81C, 0xFC060813, + 0x81C, 0xFB080813, + 0x81C, 0xFA0A0813, + 0x81C, 0xF90C0813, + 0x81C, 0xF80E0813, + 0x81C, 0xF7100813, + 0x81C, 0xF6120813, + 0x81C, 0xF5140813, + 0x81C, 0xF4160813, + 0x81C, 0xF3180813, + 0x81C, 0xF21A0813, + 0x81C, 0xF11C0813, + 0x81C, 0x941E0813, + 0x81C, 0x93200813, + 0x81C, 0x92220813, + 0x81C, 0x91240813, + 0x81C, 0x90260813, + 0x81C, 0x8F280813, + 0x81C, 0x8E2A0813, + 0x81C, 0x8D2C0813, + 0x81C, 0x8C2E0813, + 0x81C, 0x8B300813, + 0x81C, 0x8A320813, + 0x81C, 0x89340813, + 0x81C, 0x88360813, + 0x81C, 0x87380813, + 0x81C, 0x863A0813, + 0x81C, 0x853C0813, + 0x81C, 0x843E0813, + 0x81C, 0x83400813, + 0x81C, 0x82420813, + 0x81C, 0x81440813, + 0x81C, 0x07460813, + 0x81C, 0x06480813, + 0x81C, 0x054A0813, + 0x81C, 0x044C0813, + 0x81C, 0x034E0813, + 0x81C, 0x02500813, + 0x81C, 0x01520813, + 0x81C, 0x88540803, + 0x81C, 0x87560803, + 0x81C, 0x86580803, + 0x81C, 0x855A0803, + 0x81C, 0x845C0803, + 0x81C, 0x835E0803, + 0x81C, 0x82600803, + 0x81C, 0x81620803, + 0x81C, 0x07640803, + 0x81C, 0x06660803, + 0x81C, 0x05680803, + 0x81C, 0x046A0803, + 0x81C, 0x036C0803, + 0x81C, 0x026E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000013, + 0x81C, 0xFE020013, + 0x81C, 0xFD040013, + 0x81C, 0xFC060013, + 0x81C, 0xFB080013, + 0x81C, 0xFA0A0013, + 0x81C, 0xF90C0013, + 0x81C, 0xF80E0013, + 0x81C, 0xF7100013, + 0x81C, 0xF6120013, + 0x81C, 0xF5140013, + 0x81C, 0xF4160013, + 0x81C, 0xF3180013, + 0x81C, 0xF21A0013, + 0x81C, 0xF11C0013, + 0x81C, 0xF01E0013, + 0x81C, 0xEF200013, + 0x81C, 0xEE220013, + 0x81C, 0xED240013, + 0x81C, 0xEC260013, + 0x81C, 0xEB280013, + 0x81C, 0xEA2A0013, + 0x81C, 0xE92C0013, + 0x81C, 0xE82E0013, + 0x81C, 0xE7300013, + 0x81C, 0x8B320013, + 0x81C, 0x8A340013, + 0x81C, 0x89360013, + 0x81C, 0x88380013, + 0x81C, 0x873A0013, + 0x81C, 0x863C0013, + 0x81C, 0x853E0013, + 0x81C, 0x84400013, + 0x81C, 0x83420013, + 0x81C, 0x82440013, + 0x81C, 0x81460013, + 0x81C, 0x08480013, + 0x81C, 0x074A0013, + 0x81C, 0x064C0013, + 0x81C, 0x054E0013, + 0x81C, 0x04500013, + 0x81C, 0x03520013, + 0x81C, 0x88540003, + 0x81C, 0x87560003, + 0x81C, 0x86580003, + 0x81C, 0x855A0003, + 0x81C, 0x845C0003, + 0x81C, 0x835E0003, + 0x81C, 0x82600003, + 0x81C, 0x81620003, + 0x81C, 0x07640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0x81C, 0xFF000813, + 0x81C, 0xFE020813, + 0x81C, 0xFD040813, + 0x81C, 0xFC060813, + 0x81C, 0xFB080813, + 0x81C, 0xFA0A0813, + 0x81C, 0xF90C0813, + 0x81C, 0xF80E0813, + 0x81C, 0xF7100813, + 0x81C, 0xF6120813, + 0x81C, 0xF5140813, + 0x81C, 0xF4160813, + 0x81C, 0xF3180813, + 0x81C, 0xF21A0813, + 0x81C, 0xF11C0813, + 0x81C, 0x941E0813, + 0x81C, 0x93200813, + 0x81C, 0x92220813, + 0x81C, 0x91240813, + 0x81C, 0x90260813, + 0x81C, 0x8F280813, + 0x81C, 0x8E2A0813, + 0x81C, 0x8D2C0813, + 0x81C, 0x8C2E0813, + 0x81C, 0x8B300813, + 0x81C, 0x8A320813, + 0x81C, 0x89340813, + 0x81C, 0x88360813, + 0x81C, 0x87380813, + 0x81C, 0x863A0813, + 0x81C, 0x853C0813, + 0x81C, 0x843E0813, + 0x81C, 0x83400813, + 0x81C, 0x82420813, + 0x81C, 0x81440813, + 0x81C, 0x07460813, + 0x81C, 0x06480813, + 0x81C, 0x054A0813, + 0x81C, 0x044C0813, + 0x81C, 0x034E0813, + 0x81C, 0x02500813, + 0x81C, 0x01520813, + 0x81C, 0x88540803, + 0x81C, 0x87560803, + 0x81C, 0x86580803, + 0x81C, 0x855A0803, + 0x81C, 0x845C0803, + 0x81C, 0x835E0803, + 0x81C, 0x82600803, + 0x81C, 0x81620803, + 0x81C, 0x07640803, + 0x81C, 0x06660803, + 0x81C, 0x05680803, + 0x81C, 0x046A0803, + 0x81C, 0x036C0803, + 0x81C, 0x026E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000013, + 0x81C, 0xFE020013, + 0x81C, 0xFD040013, + 0x81C, 0xFC060013, + 0x81C, 0xFB080013, + 0x81C, 0xFA0A0013, + 0x81C, 0xF90C0013, + 0x81C, 0xF80E0013, + 0x81C, 0xF7100013, + 0x81C, 0xF6120013, + 0x81C, 0xF5140013, + 0x81C, 0xF4160013, + 0x81C, 0xF3180013, + 0x81C, 0xF21A0013, + 0x81C, 0xF11C0013, + 0x81C, 0xF01E0013, + 0x81C, 0xEF200013, + 0x81C, 0xEE220013, + 0x81C, 0xED240013, + 0x81C, 0xEC260013, + 0x81C, 0xEB280013, + 0x81C, 0xEA2A0013, + 0x81C, 0xE92C0013, + 0x81C, 0xE82E0013, + 0x81C, 0xE7300013, + 0x81C, 0x8A320013, + 0x81C, 0x89340013, + 0x81C, 0x88360013, + 0x81C, 0x87380013, + 0x81C, 0x863A0013, + 0x81C, 0x853C0013, + 0x81C, 0x843E0013, + 0x81C, 0x83400013, + 0x81C, 0x82420013, + 0x81C, 0x81440013, + 0x81C, 0x07460013, + 0x81C, 0x06480013, + 0x81C, 0x054A0013, + 0x81C, 0x044C0013, + 0x81C, 0x034E0013, + 0x81C, 0x02500013, + 0x81C, 0x01520013, + 0x81C, 0x88540003, + 0x81C, 0x87560003, + 0x81C, 0x86580003, + 0x81C, 0x855A0003, + 0x81C, 0x845C0003, + 0x81C, 0x835E0003, + 0x81C, 0x82600003, + 0x81C, 0x81620003, + 0x81C, 0x07640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0x81C, 0xFF000813, + 0x81C, 0xFE020813, + 0x81C, 0xFD040813, + 0x81C, 0xFC060813, + 0x81C, 0xFB080813, + 0x81C, 0xFA0A0813, + 0x81C, 0xF90C0813, + 0x81C, 0xF80E0813, + 0x81C, 0xF7100813, + 0x81C, 0xF6120813, + 0x81C, 0xF5140813, + 0x81C, 0xF4160813, + 0x81C, 0xF3180813, + 0x81C, 0xF21A0813, + 0x81C, 0xF11C0813, + 0x81C, 0x961E0813, + 0x81C, 0x95200813, + 0x81C, 0x94220813, + 0x81C, 0x93240813, + 0x81C, 0x92260813, + 0x81C, 0x91280813, + 0x81C, 0x8F2A0813, + 0x81C, 0x8E2C0813, + 0x81C, 0x8D2E0813, + 0x81C, 0x8C300813, + 0x81C, 0x8B320813, + 0x81C, 0x8A340813, + 0x81C, 0x89360813, + 0x81C, 0x88380813, + 0x81C, 0x873A0813, + 0x81C, 0x863C0813, + 0x81C, 0x853E0813, + 0x81C, 0x84400813, + 0x81C, 0x83420813, + 0x81C, 0x82440813, + 0x81C, 0x08460813, + 0x81C, 0x07480813, + 0x81C, 0x064A0813, + 0x81C, 0x054C0813, + 0x81C, 0x044E0813, + 0x81C, 0x03500813, + 0x81C, 0x02520813, + 0x81C, 0x89540803, + 0x81C, 0x88560803, + 0x81C, 0x87580803, + 0x81C, 0x865A0803, + 0x81C, 0x855C0803, + 0x81C, 0x845E0803, + 0x81C, 0x83600803, + 0x81C, 0x82620803, + 0x81C, 0x07640803, + 0x81C, 0x06660803, + 0x81C, 0x05680803, + 0x81C, 0x046A0803, + 0x81C, 0x036C0803, + 0x81C, 0x026E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_agc_btg_type2, rtw_phy_cfg_agc); + +static const u32 rtw8821c_bb[] = { + 0x800, 0x9020D010, + 0x804, 0x80018180, + 0x808, 0x04028211, + 0x80C, 0x13D10011, + 0x810, 0x21104255, + 0x814, 0x020C3D10, + 0x818, 0x84A10385, + 0x81C, 0x1E1E081F, + 0x820, 0x0001AAAA, + 0x824, 0x00030FE0, + 0x828, 0x0000CCCC, + 0x82C, 0x75CB7010, + 0x830, 0x79A0EAAA, + 0x834, 0x072E698A, + 0x838, 0x87766461, + 0x83C, 0x9194B2B6, + 0x840, 0x171740E0, + 0x844, 0x4D3D7CDB, + 0x848, 0x4AD0408B, + 0x84C, 0x6AFBF7A5, + 0x850, 0x28A74706, + 0x854, 0x0001520C, + 0x858, 0x4060C000, + 0x85C, 0x74010160, + 0x860, 0x68A7C321, + 0x864, 0x79F27432, + 0x868, 0x8CA7A314, + 0x86C, 0x558C2878, + 0x870, 0x55555555, + 0x874, 0x27612C2E, + 0x878, 0xC0003152, + 0x87C, 0x5C8FC000, + 0x880, 0x00000000, + 0x884, 0x00000000, + 0x888, 0x00000000, + 0x88C, 0x00000000, + 0x890, 0x00000000, + 0x894, 0x00000000, + 0x898, 0x00000000, + 0x89C, 0x00000000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0x2202033E, + 0x8AC, 0xF00F000A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0xEC0057FF, + 0x8BC, 0x2CB520A3, + 0x8C0, 0xFFE04020, + 0x8C4, 0x47C00000, + 0x8C8, 0x00025165, + 0x82000400, 0x00000000, 0x40000000, 0x00000000, + 0x8CC, 0x08190492, + 0xA0000000, 0x00000000, + 0x8CC, 0x08188492, + 0xB0000000, 0x00000000, + 0x8D0, 0x0000B800, + 0x8D4, 0x860308A0, + 0x8D8, 0x290B5612, + 0x8DC, 0x00000000, + 0x8E0, 0x32D16777, + 0x8E4, 0x49092925, + 0x8E8, 0xFFFFC42C, + 0x8EC, 0x99999999, + 0x8F0, 0x00009999, + 0x8F4, 0x00D80FA1, + 0x8F8, 0x400000C0, + 0x8FC, 0x00000130, + 0x900, 0x00C00000, + 0x904, 0x0FFF0FFF, + 0x908, 0x00000000, + 0x90C, 0x13000000, + 0x910, 0x0000FC00, + 0x914, 0xC6380000, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x855A2500, + 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFEB200, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x938, 0x00008480, + 0x93C, 0xE41C0642, + 0x940, 0x0E470430, + 0x944, 0x00000000, + 0x948, 0xAC000000, + 0x94C, 0x10000083, + 0x950, 0xB2010080, + 0x954, 0x86510080, + 0x958, 0x00000181, + 0x95C, 0x04248000, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x00001FFF, + 0x974, 0x04000FFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x98C, 0x23440000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x80000088, + 0x9A8, 0x0C2F0000, + 0x9AC, 0x01560000, + 0x9B0, 0x70000000, + 0x9B4, 0x00000000, + 0x9B8, 0x00000000, + 0x9BC, 0x00000000, + 0x9C0, 0x00000000, + 0x9C4, 0x00000000, + 0x9C8, 0x00000000, + 0x9CC, 0x00000000, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00000000, + 0x9E4, 0x02000402, + 0x9E8, 0x000022D4, + 0x9EC, 0x00000000, + 0x9F0, 0x00000000, + 0x9F4, 0x00000000, + 0x9F8, 0x00000000, + 0x9FC, 0xEFFFF7FF, + 0xA00, 0x00D040C8, + 0xA04, 0x80FF800C, + 0xA08, 0x9C838300, + 0xA0C, 0x297E000F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xE82C0000, + 0xA24, 0x64B80C1C, + 0xA28, 0x00008810, + 0xA2C, 0x00D20000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000107, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x21807532, + 0xA84, 0x80120000, + 0xA88, 0x048C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x00000000, + 0xA9C, 0x3F000000, + 0xAA0, 0x00000000, + 0xAA4, 0x00080000, + 0xAA8, 0xEACF0004, + 0xAAC, 0x01235667, + 0xAB0, 0x00000000, + 0xB00, 0xE1000440, + 0xB04, 0x00800000, + 0xB08, 0xFF02030B, + 0xB0C, 0x01EAA406, + 0xB10, 0x00030690, + 0xB14, 0x006000FA, + 0xB18, 0x00000002, + 0xB1C, 0x00000002, + 0xB20, 0x4B00001F, + 0xB24, 0x4E8E3E40, + 0xB28, 0x03020100, + 0xB2C, 0x07060504, + 0xB30, 0x0B0A0908, + 0xB34, 0x0F0E0D0C, + 0xB38, 0x13121110, + 0xB3C, 0x0000003A, + 0xB40, 0x00000000, + 0xB44, 0x80000000, + 0xB48, 0x3F0000FA, + 0xB4C, 0x88C80020, + 0xB50, 0x00000000, + 0xB54, 0x00004241, + 0xB58, 0xE0008208, + 0xB5C, 0x41EFFFF9, + 0xB60, 0x00000000, + 0xB64, 0x00200063, + 0xB68, 0x0000003A, + 0xB6C, 0x00000102, + 0xB70, 0x4E6D1870, + 0xB74, 0x03020100, + 0xB78, 0x07060504, + 0xB7C, 0x0B0A0908, + 0xB80, 0x0F0E0D0C, + 0xB84, 0x13121110, + 0xB88, 0x00000000, + 0xB8C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x03050020, + 0xC08, 0x60403231, + 0xC0C, 0x00012345, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC18, 0x00000000, + 0xC1C, 0x40040053, + 0xC20, 0x400503A3, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x00000000, + 0xC34, 0x00000000, + 0xC38, 0x00000000, + 0xC3C, 0x00000000, + 0xC40, 0x00000000, + 0xC44, 0x00000000, + 0xC48, 0x00000000, + 0xC4C, 0x00000000, + 0xC50, 0x00000020, + 0xC54, 0x00000000, + 0xC58, 0xD8020402, + 0xC5C, 0xDE000120, + 0xC68, 0x0000003F, + 0xC6C, 0x0000122A, + 0xC70, 0x00000000, + 0xC74, 0x00000000, + 0xC78, 0x00000000, + 0xC7C, 0x00000000, + 0xC80, 0x00000000, + 0xC84, 0x00000000, + 0xC88, 0x00000000, + 0xC8C, 0x07000000, + 0xC94, 0x01000100, + 0xC98, 0x201C8000, + 0xC9C, 0x00000000, + 0xCA0, 0x0000A555, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCAC, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0xCB0, 0x77777717, + 0xCB4, 0x00000073, + 0xA0000000, 0x00000000, + 0xCB0, 0x77775747, + 0xCB4, 0x10000077, + 0xB0000000, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x00000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x00000000, + 0xCDC, 0x00000000, + 0xCE0, 0x00000000, + 0xCE4, 0x00000000, + 0xCE8, 0x00000000, + 0xCEC, 0x00000000, + 0xE00, 0x00000007, + 0xE04, 0x00000020, + 0xE08, 0x60403231, + 0xE0C, 0x00012345, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE18, 0x00000000, + 0xE1C, 0x40040053, + 0xE20, 0x00020103, + 0xE24, 0x00000000, + 0xE28, 0x00000000, + 0xE2C, 0x00000000, + 0xE30, 0x00000000, + 0xE34, 0x00000000, + 0xE38, 0x00000000, + 0xE3C, 0x00000000, + 0xE40, 0x00000000, + 0xE44, 0x00000000, + 0xE48, 0x00000000, + 0xE4C, 0x00000000, + 0xE50, 0x00000020, + 0xE54, 0x00000000, + 0xE58, 0xD8020402, + 0xE5C, 0xDE000120, + 0xE68, 0x59799979, + 0xE6C, 0x0000122A, + 0xE70, 0x99795979, + 0xE74, 0x99795979, + 0xE78, 0x99799979, + 0xE7C, 0x99791979, + 0xE80, 0x19791979, + 0xE84, 0x19791979, + 0xE88, 0x00000000, + 0xE8C, 0x07000000, + 0xE94, 0x01000100, + 0xE98, 0x201C8000, + 0xE9C, 0x00000000, + 0xEA0, 0x0000A555, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEAC, 0x00000000, + 0xEB0, 0x98543210, + 0xEB4, 0x000000BA, + 0xEB8, 0x00000000, + 0xEBC, 0x00000000, + 0xEC0, 0x00000000, + 0xEC4, 0x00000000, + 0xEC8, 0x00000000, + 0xECC, 0x00000000, + 0xED0, 0x00000000, + 0xED4, 0x00000000, + 0xED8, 0x00000000, + 0xEDC, 0x00000000, + 0xEE0, 0x00000000, + 0xEE4, 0x00000000, + 0xEE8, 0x00000000, + 0xEEC, 0x00000000, + 0x1900, 0x00000000, + 0x1904, 0x00238000, + 0x1908, 0x00000000, + 0x190C, 0x00000000, + 0x1910, 0x00001800, + 0x1914, 0x00000000, + 0x1918, 0x00000000, + 0x191C, 0x00000000, + 0x1920, 0x00000000, + 0x1924, 0x00000000, + 0x1928, 0x00000000, + 0x192C, 0x00000000, + 0x1930, 0x00000000, + 0x1934, 0x00000000, + 0x1938, 0x00000000, + 0x193C, 0x00000000, + 0x1940, 0x00000000, + 0x1944, 0x00000000, + 0x1948, 0x00000000, + 0x194C, 0x00000000, + 0x1950, 0x00000000, + 0x1954, 0x00000000, + 0x1958, 0x00000000, + 0x195C, 0x00000000, + 0x1960, 0x00000000, + 0x1964, 0x00000000, + 0x1968, 0x00000000, + 0x196C, 0x00000000, + 0x1970, 0x00000000, + 0x1974, 0x00000000, + 0x1978, 0x00000000, + 0x197C, 0x00000000, + 0x1980, 0x00000000, + 0x1984, 0x03000000, + 0x1988, 0x21401E88, + 0x198C, 0x00004000, + 0x1990, 0x00000000, + 0x1994, 0x00000000, + 0x1998, 0x00000053, + 0x199C, 0x00000000, + 0x19A0, 0x00000000, + 0x19A4, 0x00000000, + 0x19A8, 0x010A0000, + 0x19AC, 0x0E47E47F, + 0x19B0, 0x00008000, + 0x19B4, 0x0E47E47F, + 0x19B8, 0x00000000, + 0x19BC, 0x00000000, + 0x19C0, 0x00000000, + 0x19C4, 0x00000000, + 0x19C8, 0x00000000, + 0x19CC, 0x00000000, + 0x19D0, 0x00000000, + 0x19D4, 0x77777777, + 0x19D8, 0x00000777, + 0x19DC, 0x133E0F37, + 0x19E0, 0x00000000, + 0x19E4, 0x00000000, + 0x19E8, 0x00000000, + 0x19EC, 0x00000000, + 0x19F0, 0x00000000, + 0x19F4, 0x00000000, + 0x19F8, 0x01A00000, + 0x19FC, 0x00000000, + 0x1C00, 0x00000100, + 0x1C04, 0x01000000, + 0x1C08, 0x00000100, + 0x1C0C, 0x01000000, + 0x1C10, 0x00000100, + 0x1C14, 0x01000000, + 0x1C18, 0x00000100, + 0x1C1C, 0x01000000, + 0x1C20, 0x00000100, + 0x1C24, 0x01000000, + 0x1C28, 0x00000100, + 0x1C2C, 0x01000000, + 0x1C30, 0x00000100, + 0x1C34, 0x01000000, + 0x1C38, 0x00000000, + 0x1C3C, 0x00008000, + 0x1C40, 0x000C0100, + 0x1C44, 0x000000F3, + 0x1C48, 0x1A8249A8, + 0x1C4C, 0x1461C826, + 0x1C50, 0x0001469E, + 0x1C54, 0x58D158D1, + 0x1C58, 0x04490088, + 0x1C5C, 0x04004400, + 0x1C60, 0x00000000, + 0x1C64, 0x04004400, + 0x1C68, 0x0B7B7B75, + 0x1C6C, 0x01000000, + 0x1C70, 0x00A08145, + 0x1C74, 0x2080E0E0, + 0x1C78, 0x00000000, + 0x1C7C, 0x00000010, + 0x1C80, 0x00000100, + 0x1C84, 0x01000000, + 0x1C88, 0x00000100, + 0x1C8C, 0x01000000, + 0x1C90, 0x00000100, + 0x1C94, 0x01000000, + 0x1C98, 0x00000100, + 0x1C9C, 0x01000000, + 0x1CA0, 0x00000100, + 0x1CA4, 0x01000000, + 0x1CA8, 0x00000100, + 0x1CAC, 0x01000000, + 0x1CB0, 0x00000100, + 0x1CB4, 0x01000000, + 0x1CB8, 0x00000000, + 0x1CBC, 0x00000000, + 0x1CC0, 0x201B0100, + 0x1CC4, 0x00308000, + 0x1CC8, 0x5B74B6E9, + 0x1CCC, 0x01000000, + 0x1CD0, 0x00000400, + 0x1CD4, 0x01000000, + 0x1CD8, 0x01B8ADEB, + 0x1CDC, 0x01000000, + 0x1CE0, 0x00030003, + 0x1CE4, 0x4E4A0306, + 0x1CE8, 0x00000100, + 0x1CEC, 0x01000000, + 0x1CF0, 0x00000100, + 0x1CF4, 0x01000000, + 0x1CF8, 0x01B8ADEB, + 0x1CFC, 0x00000000, + 0xC60, 0x700B8040, + 0xC60, 0x700B8040, + 0xC60, 0x70146040, + 0xC60, 0x70246040, + 0xC60, 0x70346040, + 0xC60, 0x70446040, + 0xC60, 0x705B2040, + 0xC60, 0x70646040, + 0xC60, 0x707B8040, + 0xC60, 0x708B8040, + 0xC60, 0x709B8040, + 0xC60, 0x70AB8040, + 0xC60, 0x70BB6040, + 0xC60, 0x70C06040, + 0xC60, 0x70D06040, + 0xC60, 0x70EF6040, + 0xC60, 0x70F06040, + 0xE60, 0x700B8040, + 0xE60, 0x700B8040, + 0xE60, 0x70146040, + 0xE60, 0x70246040, + 0xE60, 0x70346040, + 0xE60, 0x70446040, + 0xE60, 0x705B2040, + 0xE60, 0x70646040, + 0xE60, 0x707B8040, + 0xE60, 0x708B8040, + 0xE60, 0x709B8040, + 0xE60, 0x70AB8040, + 0xE60, 0x70BB6040, + 0xE60, 0x70C06040, + 0xE60, 0x70D06040, + 0xE60, 0x70EF6040, + 0xE60, 0x70F06040, + 0xC64, 0x00800000, + 0xC64, 0x08800001, + 0xC64, 0x00800002, + 0xC64, 0x00800003, + 0xC64, 0x00800004, + 0xC64, 0x00800005, + 0xC64, 0x00800006, + 0xC64, 0x08800007, + 0xC64, 0x00004000, + 0xE64, 0x00800000, + 0xE64, 0x08800001, + 0xE64, 0x00800002, + 0xE64, 0x00800003, + 0xE64, 0x00800004, + 0xE64, 0x00800005, + 0xE64, 0x00800006, + 0xE64, 0x08800007, + 0xE64, 0x00004000, + 0x1B00, 0xF8000008, + 0x1B00, 0xF80A7008, + 0x1B00, 0xF8015008, + 0x1B00, 0xF8000008, + 0x1B04, 0xE24629D2, + 0x1B08, 0x00000080, + 0x1B0C, 0x00000000, + 0x1B10, 0x00011C00, + 0x1B14, 0x00000000, + 0x1B18, 0x00292903, + 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, + 0x1B24, 0x01860008, + 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, + 0x1B30, 0x20000000, + 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, + 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, + 0x1B90, 0x0001E018, + 0x1B94, 0xF76D9F84, + 0x1BC8, 0x000C44AA, + 0x1BCC, 0x11978200, + 0x1B8C, 0x00002000, + 0x1B9C, 0x5B554F48, + 0x1BA0, 0x6F6B6661, + 0x1BA4, 0x817D7874, + 0x1BA8, 0x908C8884, + 0x1BAC, 0x9D9A9793, + 0x1BB0, 0xAAA7A4A1, + 0x1BB4, 0xB6B3B0AD, + 0x1B40, 0x02CE03E8, + 0x1B44, 0x01FD024C, + 0x1B48, 0x01A101C9, + 0x1B4C, 0x016A0183, + 0x1B50, 0x01430153, + 0x1B54, 0x01280134, + 0x1B58, 0x0112011C, + 0x1B5C, 0x01000107, + 0x1B60, 0x00F200F9, + 0x1B64, 0x00E500EB, + 0x1B68, 0x00DA00E0, + 0x1B6C, 0x00D200D6, + 0x1B70, 0x00C900CD, + 0x1B74, 0x00C200C5, + 0x1B78, 0x00BB00BE, + 0x1B7C, 0x00B500B8, + 0x1BDC, 0x40CAFFE1, + 0x1BDC, 0x4080A1E3, + 0x1BDC, 0x405165E5, + 0x1BDC, 0x403340E7, + 0x1BDC, 0x402028E9, + 0x1BDC, 0x401419EB, + 0x1BDC, 0x400D10ED, + 0x1BDC, 0x40080AEF, + 0x1BDC, 0x400506F1, + 0x1BDC, 0x400304F3, + 0x1BDC, 0x400203F5, + 0x1BDC, 0x400102F7, + 0x1BDC, 0x400101F9, + 0x1BDC, 0x400101FB, + 0x1BDC, 0x400101FD, + 0x1BDC, 0x400101FF, + 0x1BDC, 0x40CAFF81, + 0x1BDC, 0x4080A183, + 0x1BDC, 0x40516585, + 0x1BDC, 0x40334087, + 0x1BDC, 0x40202889, + 0x1BDC, 0x4014198B, + 0x1BDC, 0x400D108D, + 0x1BDC, 0x40080A8F, + 0x1BDC, 0x40050691, + 0x1BDC, 0x40030493, + 0x1BDC, 0x40020395, + 0x1BDC, 0x40010297, + 0x1BDC, 0x40010199, + 0x1BDC, 0x4001019B, + 0x1BDC, 0x4001019D, + 0x1BDC, 0x4001019F, + 0x1BDC, 0x00000000, + 0x1BDC, 0xD0000001, + 0x1BDC, 0xD0000003, + 0x1BDC, 0xD0000005, + 0x1BDC, 0xD0000007, + 0x1BDC, 0xD0000009, + 0x1BDC, 0xD000000B, + 0x1BDC, 0xD000000D, + 0x1BDC, 0xD000000F, + 0x1BDC, 0xD0000011, + 0x1BDC, 0xD0000013, + 0x1BDC, 0xD0000015, + 0x1BDC, 0xD0000017, + 0x1BDC, 0xD0000019, + 0x1BDC, 0xD000001B, + 0x1BDC, 0xD000001D, + 0x1BDC, 0xD000001F, + 0x1BDC, 0xD0000021, + 0x1BDC, 0xD0000023, + 0x1BDC, 0xD0000025, + 0x1BDC, 0xD0000027, + 0x1BDC, 0xD0000029, + 0x1BDC, 0xD000002B, + 0x1BDC, 0xD000002D, + 0x1BDC, 0xD000002F, + 0x1BDC, 0xD0000031, + 0x1BDC, 0xD0000033, + 0x1BDC, 0xD0000035, + 0x1BDC, 0xD0000037, + 0x1BDC, 0xD0000039, + 0x1BDC, 0xD000003B, + 0x1BDC, 0xD000003D, + 0x1BDC, 0xD000003F, + 0x1BDC, 0xD0000041, + 0x1BDC, 0xD0000043, + 0x1BDC, 0xD0000045, + 0x1BDC, 0xD0000047, + 0x1BDC, 0xD0000049, + 0x1BDC, 0xD000004B, + 0x1BDC, 0xD000004D, + 0x1BDC, 0xD000004F, + 0x1BDC, 0xD0000051, + 0x1BDC, 0xD0000053, + 0x1BDC, 0xD0000055, + 0x1BDC, 0xD0000057, + 0x1BDC, 0xD0000059, + 0x1BDC, 0xD000005B, + 0x1BDC, 0xD000005D, + 0x1BDC, 0xD000005F, + 0x1BDC, 0xD0000061, + 0x1BDC, 0xD0000063, + 0x1BDC, 0xD0000065, + 0x1BDC, 0xD0000067, + 0x1BDC, 0xD0000069, + 0x1BDC, 0xD000006B, + 0x1BDC, 0xD000006D, + 0x1BDC, 0xD000006F, + 0x1BDC, 0xD0000071, + 0x1BDC, 0xD0000073, + 0x1BDC, 0xD0000075, + 0x1BDC, 0xD0000077, + 0x1BDC, 0xD0000079, + 0x1BDC, 0xD000007B, + 0x1BDC, 0xD000007D, + 0x1BDC, 0xD000007F, + 0x1BDC, 0x90000081, + 0x1BDC, 0x90000083, + 0x1BDC, 0x90000085, + 0x1BDC, 0x90000087, + 0x1BDC, 0x90000089, + 0x1BDC, 0x9000008B, + 0x1BDC, 0x9000008D, + 0x1BDC, 0x9000008F, + 0x1BDC, 0x90000091, + 0x1BDC, 0x90000093, + 0x1BDC, 0x90000095, + 0x1BDC, 0x90000097, + 0x1BDC, 0x90000099, + 0x1BDC, 0x9000009B, + 0x1BDC, 0x9000009D, + 0x1BDC, 0x9000009F, + 0x1BDC, 0x900000A1, + 0x1BDC, 0x900000A3, + 0x1BDC, 0x900000A5, + 0x1BDC, 0x900000A7, + 0x1BDC, 0x900000A9, + 0x1BDC, 0x900000AB, + 0x1BDC, 0x900000AD, + 0x1BDC, 0x900000AF, + 0x1BDC, 0x900000B1, + 0x1BDC, 0x900000B3, + 0x1BDC, 0x900000B5, + 0x1BDC, 0x900000B7, + 0x1BDC, 0x900000B9, + 0x1BDC, 0x900000BB, + 0x1BDC, 0x900000BD, + 0x1BDC, 0x900000BF, + 0x1BDC, 0x900000C1, + 0x1BDC, 0x900000C3, + 0x1BDC, 0x900000C5, + 0x1BDC, 0x900000C7, + 0x1BDC, 0x900000C9, + 0x1BDC, 0x900000CB, + 0x1BDC, 0x900000CD, + 0x1BDC, 0x900000CF, + 0x1BDC, 0x900000D1, + 0x1BDC, 0x900000D3, + 0x1BDC, 0x900000D5, + 0x1BDC, 0x900000D7, + 0x1BDC, 0x900000D9, + 0x1BDC, 0x900000DB, + 0x1BDC, 0x900000DD, + 0x1BDC, 0x900000DF, + 0x1BDC, 0x900000E1, + 0x1BDC, 0x900000E3, + 0x1BDC, 0x900000E5, + 0x1BDC, 0x900000E7, + 0x1BDC, 0x900000E9, + 0x1BDC, 0x900000EB, + 0x1BDC, 0x900000ED, + 0x1BDC, 0x900000EF, + 0x1BDC, 0x900000F1, + 0x1BDC, 0x900000F3, + 0x1BDC, 0x900000F5, + 0x1BDC, 0x900000F7, + 0x1BDC, 0x900000F9, + 0x1BDC, 0x900000FB, + 0x1BDC, 0x900000FD, + 0x1BDC, 0x900000FF, + 0x1BDC, 0x00000000, + 0x1B00, 0xF8000000, + 0x1B80, 0x00000007, + 0x1B80, 0x090A0005, + 0x1B80, 0x090A0007, + 0x1B80, 0x0FFE0015, + 0x1B80, 0x0FFE0017, + 0x1B80, 0x00220025, + 0x1B80, 0x00220027, + 0x1B80, 0x00040035, + 0x1B80, 0x00040037, + 0x1B80, 0x05C00045, + 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, + 0x1B80, 0x00070057, + 0x1B80, 0x64000065, + 0x1B80, 0x64000067, + 0x1B80, 0x00020075, + 0x1B80, 0x00020077, + 0x1B80, 0x00080085, + 0x1B80, 0x00080087, + 0x1B80, 0x80000095, + 0x1B80, 0x80000097, + 0x1B80, 0x090800A5, + 0x1B80, 0x090800A7, + 0x1B80, 0x0F0200B5, + 0x1B80, 0x0F0200B7, + 0x1B80, 0x002200C5, + 0x1B80, 0x002200C7, + 0x1B80, 0x000400D5, + 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, + 0x1B80, 0x05C000E7, + 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, + 0x1B80, 0x64020105, + 0x1B80, 0x64020107, + 0x1B80, 0x00020115, + 0x1B80, 0x00020117, + 0x1B80, 0x00040125, + 0x1B80, 0x00040127, + 0x1B80, 0x4A000135, + 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, + 0x1B80, 0x4B040147, + 0x1B80, 0x85030155, + 0x1B80, 0x85030157, + 0x1B80, 0x40090165, + 0x1B80, 0x40090167, + 0x1B80, 0xE02A0175, + 0x1B80, 0xE02A0177, + 0x1B80, 0x4B050185, + 0x1B80, 0x4B050187, + 0x1B80, 0x86030195, + 0x1B80, 0x86030197, + 0x1B80, 0x400B01A5, + 0x1B80, 0x400B01A7, + 0x1B80, 0xE02A01B5, + 0x1B80, 0xE02A01B7, + 0x1B80, 0x4B0001C5, + 0x1B80, 0x4B0001C7, + 0x1B80, 0x000701D5, + 0x1B80, 0x000701D7, + 0x1B80, 0x4C0001E5, + 0x1B80, 0x4C0001E7, + 0x1B80, 0x000401F5, + 0x1B80, 0x000401F7, + 0x1B80, 0x4D040205, + 0x1B80, 0x4D040207, + 0x1B80, 0x2EE00215, + 0x1B80, 0x2EE00217, + 0x1B80, 0x00000225, + 0x1B80, 0x00000227, + 0x1B80, 0x2EF00235, + 0x1B80, 0x2EF00237, + 0x1B80, 0x00000245, + 0x1B80, 0x00000247, + 0x1B80, 0x20810255, + 0x1B80, 0x20810257, + 0x1B80, 0x23450265, + 0x1B80, 0x23450267, + 0x1B80, 0x4D000275, + 0x1B80, 0x4D000277, + 0x1B80, 0x00040285, + 0x1B80, 0x00040287, + 0x1B80, 0x30000295, + 0x1B80, 0x30000297, + 0x1B80, 0xE1D602A5, + 0x1B80, 0xE1D602A7, + 0x1B80, 0xF01102B5, + 0x1B80, 0xF01102B7, + 0x1B80, 0xF11102C5, + 0x1B80, 0xF11102C7, + 0x1B80, 0xF21102D5, + 0x1B80, 0xF21102D7, + 0x1B80, 0xF31102E5, + 0x1B80, 0xF31102E7, + 0x1B80, 0xF41102F5, + 0x1B80, 0xF41102F7, + 0x1B80, 0xF5110305, + 0x1B80, 0xF5110307, + 0x1B80, 0xF6110315, + 0x1B80, 0xF6110317, + 0x1B80, 0xF7110325, + 0x1B80, 0xF7110327, + 0x1B80, 0xF8110335, + 0x1B80, 0xF8110337, + 0x1B80, 0xF9110345, + 0x1B80, 0xF9110347, + 0x1B80, 0xFA110355, + 0x1B80, 0xFA110357, + 0x1B80, 0xFB110365, + 0x1B80, 0xFB110367, + 0x1B80, 0xFC110375, + 0x1B80, 0xFC110377, + 0x1B80, 0xFD110385, + 0x1B80, 0xFD110387, + 0x1B80, 0xFE110395, + 0x1B80, 0xFE110397, + 0x1B80, 0xFF1103A5, + 0x1B80, 0xFF1103A7, + 0x1B80, 0x000103B5, + 0x1B80, 0x000103B7, + 0x1B80, 0x305503C5, + 0x1B80, 0x305503C7, + 0x1B80, 0x306D03D5, + 0x1B80, 0x306D03D7, + 0x1B80, 0x30B803E5, + 0x1B80, 0x30B803E7, + 0x1B80, 0x30BB03F5, + 0x1B80, 0x30BB03F7, + 0x1B80, 0x306F0405, + 0x1B80, 0x306F0407, + 0x1B80, 0x307A0415, + 0x1B80, 0x307A0417, + 0x1B80, 0x30850425, + 0x1B80, 0x30850427, + 0x1B80, 0x30C50435, + 0x1B80, 0x30C50437, + 0x1B80, 0x30BF0445, + 0x1B80, 0x30BF0447, + 0x1B80, 0x30D30455, + 0x1B80, 0x30D30457, + 0x1B80, 0x30DE0465, + 0x1B80, 0x30DE0467, + 0x1B80, 0x30E90475, + 0x1B80, 0x30E90477, + 0x1B80, 0x304C0485, + 0x1B80, 0x304C0487, + 0x1B80, 0x31180495, + 0x1B80, 0x31180497, + 0x1B80, 0x312904A5, + 0x1B80, 0x312904A7, + 0x1B80, 0x313E04B5, + 0x1B80, 0x313E04B7, + 0x1B80, 0x4D0404C5, + 0x1B80, 0x4D0404C7, + 0x1B80, 0x2EE004D5, + 0x1B80, 0x2EE004D7, + 0x1B80, 0x000004E5, + 0x1B80, 0x000004E7, + 0x1B80, 0x2EF004F5, + 0x1B80, 0x2EF004F7, + 0x1B80, 0x00000505, + 0x1B80, 0x00000507, + 0x1B80, 0x20810515, + 0x1B80, 0x20810517, + 0x1B80, 0xA3B50525, + 0x1B80, 0xA3B50527, + 0x1B80, 0x4D000535, + 0x1B80, 0x4D000537, + 0x1B80, 0x30000545, + 0x1B80, 0x30000547, + 0x1B80, 0xE1690555, + 0x1B80, 0xE1690557, + 0x1B80, 0x4D040565, + 0x1B80, 0x4D040567, + 0x1B80, 0x20800575, + 0x1B80, 0x20800577, + 0x1B80, 0x00000585, + 0x1B80, 0x00000587, + 0x1B80, 0x4D000595, + 0x1B80, 0x4D000597, + 0x1B80, 0x550705A5, + 0x1B80, 0x550705A7, + 0x1B80, 0xE16105B5, + 0x1B80, 0xE16105B7, + 0x1B80, 0xE16105C5, + 0x1B80, 0xE16105C7, + 0x1B80, 0x4D0405D5, + 0x1B80, 0x4D0405D7, + 0x1B80, 0x208805E5, + 0x1B80, 0x208805E7, + 0x1B80, 0x020005F5, + 0x1B80, 0x020005F7, + 0x1B80, 0x4D000605, + 0x1B80, 0x4D000607, + 0x1B80, 0x550F0615, + 0x1B80, 0x550F0617, + 0x1B80, 0xE1610625, + 0x1B80, 0xE1610627, + 0x1B80, 0x4F020635, + 0x1B80, 0x4F020637, + 0x1B80, 0x4E000645, + 0x1B80, 0x4E000647, + 0x1B80, 0x53020655, + 0x1B80, 0x53020657, + 0x1B80, 0x52010665, + 0x1B80, 0x52010667, + 0x1B80, 0xE1650675, + 0x1B80, 0xE1650677, + 0x1B80, 0x4D080685, + 0x1B80, 0x4D080687, + 0x1B80, 0x57100695, + 0x1B80, 0x57100697, + 0x1B80, 0x570006A5, + 0x1B80, 0x570006A7, + 0x1B80, 0x4D0006B5, + 0x1B80, 0x4D0006B7, + 0x1B80, 0x000106C5, + 0x1B80, 0x000106C7, + 0x1B80, 0xE16906D5, + 0x1B80, 0xE16906D7, + 0x1B80, 0x000106E5, + 0x1B80, 0x000106E7, + 0x1B80, 0x308F06F5, + 0x1B80, 0x308F06F7, + 0x1B80, 0x00230705, + 0x1B80, 0x00230707, + 0x1B80, 0xE1C90715, + 0x1B80, 0xE1C90717, + 0x1B80, 0x00020725, + 0x1B80, 0x00020727, + 0x1B80, 0x54E90735, + 0x1B80, 0x54E90737, + 0x1B80, 0x0BA60745, + 0x1B80, 0x0BA60747, + 0x1B80, 0x00230755, + 0x1B80, 0x00230757, + 0x1B80, 0xE1C90765, + 0x1B80, 0xE1C90767, + 0x1B80, 0x00020775, + 0x1B80, 0x00020777, + 0x1B80, 0x4D300785, + 0x1B80, 0x4D300787, + 0x1B80, 0x30A80795, + 0x1B80, 0x30A80797, + 0x1B80, 0x308B07A5, + 0x1B80, 0x308B07A7, + 0x1B80, 0x002207B5, + 0x1B80, 0x002207B7, + 0x1B80, 0xE1C907C5, + 0x1B80, 0xE1C907C7, + 0x1B80, 0x000207D5, + 0x1B80, 0x000207D7, + 0x1B80, 0x54E807E5, + 0x1B80, 0x54E807E7, + 0x1B80, 0x0BA607F5, + 0x1B80, 0x0BA607F7, + 0x1B80, 0x00220805, + 0x1B80, 0x00220807, + 0x1B80, 0xE1C90815, + 0x1B80, 0xE1C90817, + 0x1B80, 0x00020825, + 0x1B80, 0x00020827, + 0x1B80, 0x4D300835, + 0x1B80, 0x4D300837, + 0x1B80, 0x30A80845, + 0x1B80, 0x30A80847, + 0x1B80, 0x63F10855, + 0x1B80, 0x63F10857, + 0x1B80, 0xE1690865, + 0x1B80, 0xE1690867, + 0x1B80, 0xE1C90875, + 0x1B80, 0xE1C90877, + 0x1B80, 0x63F40885, + 0x1B80, 0x63F40887, + 0x1B80, 0xE1690895, + 0x1B80, 0xE1690897, + 0x1B80, 0xE1C908A5, + 0x1B80, 0xE1C908A7, + 0x1B80, 0x0BA808B5, + 0x1B80, 0x0BA808B7, + 0x1B80, 0x63F808C5, + 0x1B80, 0x63F808C7, + 0x1B80, 0xE16908D5, + 0x1B80, 0xE16908D7, + 0x1B80, 0xE1C908E5, + 0x1B80, 0xE1C908E7, + 0x1B80, 0x0BA908F5, + 0x1B80, 0x0BA908F7, + 0x1B80, 0x63FC0905, + 0x1B80, 0x63FC0907, + 0x1B80, 0xE1690915, + 0x1B80, 0xE1690917, + 0x1B80, 0xE1C90925, + 0x1B80, 0xE1C90927, + 0x1B80, 0x63FF0935, + 0x1B80, 0x63FF0937, + 0x1B80, 0xE1690945, + 0x1B80, 0xE1690947, + 0x1B80, 0xE1C90955, + 0x1B80, 0xE1C90957, + 0x1B80, 0x63000965, + 0x1B80, 0x63000967, + 0x1B80, 0xE1690975, + 0x1B80, 0xE1690977, + 0x1B80, 0xE1C90985, + 0x1B80, 0xE1C90987, + 0x1B80, 0x63030995, + 0x1B80, 0x63030997, + 0x1B80, 0xE16909A5, + 0x1B80, 0xE16909A7, + 0x1B80, 0xE1C909B5, + 0x1B80, 0xE1C909B7, + 0x1B80, 0xF4D409C5, + 0x1B80, 0xF4D409C7, + 0x1B80, 0x630709D5, + 0x1B80, 0x630709D7, + 0x1B80, 0xE16909E5, + 0x1B80, 0xE16909E7, + 0x1B80, 0xE1C909F5, + 0x1B80, 0xE1C909F7, + 0x1B80, 0xF5DB0A05, + 0x1B80, 0xF5DB0A07, + 0x1B80, 0x630B0A15, + 0x1B80, 0x630B0A17, + 0x1B80, 0xE1690A25, + 0x1B80, 0xE1690A27, + 0x1B80, 0xE1C90A35, + 0x1B80, 0xE1C90A37, + 0x1B80, 0x630E0A45, + 0x1B80, 0x630E0A47, + 0x1B80, 0xE1690A55, + 0x1B80, 0xE1690A57, + 0x1B80, 0xE1C90A65, + 0x1B80, 0xE1C90A67, + 0x1B80, 0x4D300A75, + 0x1B80, 0x4D300A77, + 0x1B80, 0x55010A85, + 0x1B80, 0x55010A87, + 0x1B80, 0x57040A95, + 0x1B80, 0x57040A97, + 0x1B80, 0x57000AA5, + 0x1B80, 0x57000AA7, + 0x1B80, 0x96000AB5, + 0x1B80, 0x96000AB7, + 0x1B80, 0x57080AC5, + 0x1B80, 0x57080AC7, + 0x1B80, 0x57000AD5, + 0x1B80, 0x57000AD7, + 0x1B80, 0x95000AE5, + 0x1B80, 0x95000AE7, + 0x1B80, 0x4D000AF5, + 0x1B80, 0x4D000AF7, + 0x1B80, 0x6C070B05, + 0x1B80, 0x6C070B07, + 0x1B80, 0x7B200B15, + 0x1B80, 0x7B200B17, + 0x1B80, 0x7A000B25, + 0x1B80, 0x7A000B27, + 0x1B80, 0x79000B35, + 0x1B80, 0x79000B37, + 0x1B80, 0x7F200B45, + 0x1B80, 0x7F200B47, + 0x1B80, 0x7E000B55, + 0x1B80, 0x7E000B57, + 0x1B80, 0x7D000B65, + 0x1B80, 0x7D000B67, + 0x1B80, 0x00010B75, + 0x1B80, 0x00010B77, + 0x1B80, 0x62850B85, + 0x1B80, 0x62850B87, + 0x1B80, 0xE1690B95, + 0x1B80, 0xE1690B97, + 0x1B80, 0x00010BA5, + 0x1B80, 0x00010BA7, + 0x1B80, 0x5C320BB5, + 0x1B80, 0x5C320BB7, + 0x1B80, 0xE1C50BC5, + 0x1B80, 0xE1C50BC7, + 0x1B80, 0xE1950BD5, + 0x1B80, 0xE1950BD7, + 0x1B80, 0x00010BE5, + 0x1B80, 0x00010BE7, + 0x1B80, 0x5C320BF5, + 0x1B80, 0x5C320BF7, + 0x1B80, 0x63F40C05, + 0x1B80, 0x63F40C07, + 0x1B80, 0x62850C15, + 0x1B80, 0x62850C17, + 0x1B80, 0x0BB00C25, + 0x1B80, 0x0BB00C27, + 0x1B80, 0xE1690C35, + 0x1B80, 0xE1690C37, + 0x1B80, 0xE1C90C45, + 0x1B80, 0xE1C90C47, + 0x1B80, 0x5C320C55, + 0x1B80, 0x5C320C57, + 0x1B80, 0x63FC0C65, + 0x1B80, 0x63FC0C67, + 0x1B80, 0x62850C75, + 0x1B80, 0x62850C77, + 0x1B80, 0x0BB10C85, + 0x1B80, 0x0BB10C87, + 0x1B80, 0xE1690C95, + 0x1B80, 0xE1690C97, + 0x1B80, 0xE1C90CA5, + 0x1B80, 0xE1C90CA7, + 0x1B80, 0x63030CB5, + 0x1B80, 0x63030CB7, + 0x1B80, 0xE1690CC5, + 0x1B80, 0xE1690CC7, + 0x1B80, 0xE1C90CD5, + 0x1B80, 0xE1C90CD7, + 0x1B80, 0xF7040CE5, + 0x1B80, 0xF7040CE7, + 0x1B80, 0x630B0CF5, + 0x1B80, 0x630B0CF7, + 0x1B80, 0xE1690D05, + 0x1B80, 0xE1690D07, + 0x1B80, 0xE1C90D15, + 0x1B80, 0xE1C90D17, + 0x1B80, 0x00010D25, + 0x1B80, 0x00010D27, + 0x1B80, 0x30F70D35, + 0x1B80, 0x30F70D37, + 0x1B80, 0x00230D45, + 0x1B80, 0x00230D47, + 0x1B80, 0xE1CE0D55, + 0x1B80, 0xE1CE0D57, + 0x1B80, 0x00020D65, + 0x1B80, 0x00020D67, + 0x1B80, 0x54E90D75, + 0x1B80, 0x54E90D77, + 0x1B80, 0x0BA60D85, + 0x1B80, 0x0BA60D87, + 0x1B80, 0x00230D95, + 0x1B80, 0x00230D97, + 0x1B80, 0xE1CE0DA5, + 0x1B80, 0xE1CE0DA7, + 0x1B80, 0x00020DB5, + 0x1B80, 0x00020DB7, + 0x1B80, 0x4D100DC5, + 0x1B80, 0x4D100DC7, + 0x1B80, 0x30A80DD5, + 0x1B80, 0x30A80DD7, + 0x1B80, 0x30F10DE5, + 0x1B80, 0x30F10DE7, + 0x1B80, 0x00220DF5, + 0x1B80, 0x00220DF7, + 0x1B80, 0xE1CE0E05, + 0x1B80, 0xE1CE0E07, + 0x1B80, 0x00020E15, + 0x1B80, 0x00020E17, + 0x1B80, 0x54E80E25, + 0x1B80, 0x54E80E27, + 0x1B80, 0x0BA60E35, + 0x1B80, 0x0BA60E37, + 0x1B80, 0x00220E45, + 0x1B80, 0x00220E47, + 0x1B80, 0xE1CE0E55, + 0x1B80, 0xE1CE0E57, + 0x1B80, 0x00020E65, + 0x1B80, 0x00020E67, + 0x1B80, 0x4D100E75, + 0x1B80, 0x4D100E77, + 0x1B80, 0x30A80E85, + 0x1B80, 0x30A80E87, + 0x1B80, 0x5C320E95, + 0x1B80, 0x5C320E97, + 0x1B80, 0x54F00EA5, + 0x1B80, 0x54F00EA7, + 0x1B80, 0x67F10EB5, + 0x1B80, 0x67F10EB7, + 0x1B80, 0xE1950EC5, + 0x1B80, 0xE1950EC7, + 0x1B80, 0xE1CE0ED5, + 0x1B80, 0xE1CE0ED7, + 0x1B80, 0x67F40EE5, + 0x1B80, 0x67F40EE7, + 0x1B80, 0xE1950EF5, + 0x1B80, 0xE1950EF7, + 0x1B80, 0xE1CE0F05, + 0x1B80, 0xE1CE0F07, + 0x1B80, 0x5C320F15, + 0x1B80, 0x5C320F17, + 0x1B80, 0x54F10F25, + 0x1B80, 0x54F10F27, + 0x1B80, 0x0BA80F35, + 0x1B80, 0x0BA80F37, + 0x1B80, 0x67F80F45, + 0x1B80, 0x67F80F47, + 0x1B80, 0xE1950F55, + 0x1B80, 0xE1950F57, + 0x1B80, 0xE1CE0F65, + 0x1B80, 0xE1CE0F67, + 0x1B80, 0x5C320F75, + 0x1B80, 0x5C320F77, + 0x1B80, 0x54F10F85, + 0x1B80, 0x54F10F87, + 0x1B80, 0x0BA90F95, + 0x1B80, 0x0BA90F97, + 0x1B80, 0x67FC0FA5, + 0x1B80, 0x67FC0FA7, + 0x1B80, 0xE1950FB5, + 0x1B80, 0xE1950FB7, + 0x1B80, 0xE1CE0FC5, + 0x1B80, 0xE1CE0FC7, + 0x1B80, 0x67FF0FD5, + 0x1B80, 0x67FF0FD7, + 0x1B80, 0xE1950FE5, + 0x1B80, 0xE1950FE7, + 0x1B80, 0xE1CE0FF5, + 0x1B80, 0xE1CE0FF7, + 0x1B80, 0x5C321005, + 0x1B80, 0x5C321007, + 0x1B80, 0x54F21015, + 0x1B80, 0x54F21017, + 0x1B80, 0x67001025, + 0x1B80, 0x67001027, + 0x1B80, 0xE1951035, + 0x1B80, 0xE1951037, + 0x1B80, 0xE1CE1045, + 0x1B80, 0xE1CE1047, + 0x1B80, 0x67031055, + 0x1B80, 0x67031057, + 0x1B80, 0xE1951065, + 0x1B80, 0xE1951067, + 0x1B80, 0xE1CE1075, + 0x1B80, 0xE1CE1077, + 0x1B80, 0xF9CC1085, + 0x1B80, 0xF9CC1087, + 0x1B80, 0x67071095, + 0x1B80, 0x67071097, + 0x1B80, 0xE19510A5, + 0x1B80, 0xE19510A7, + 0x1B80, 0xE1CE10B5, + 0x1B80, 0xE1CE10B7, + 0x1B80, 0xFAD310C5, + 0x1B80, 0xFAD310C7, + 0x1B80, 0x5C3210D5, + 0x1B80, 0x5C3210D7, + 0x1B80, 0x54F310E5, + 0x1B80, 0x54F310E7, + 0x1B80, 0x670B10F5, + 0x1B80, 0x670B10F7, + 0x1B80, 0xE1951105, + 0x1B80, 0xE1951107, + 0x1B80, 0xE1CE1115, + 0x1B80, 0xE1CE1117, + 0x1B80, 0x670E1125, + 0x1B80, 0x670E1127, + 0x1B80, 0xE1951135, + 0x1B80, 0xE1951137, + 0x1B80, 0xE1CE1145, + 0x1B80, 0xE1CE1147, + 0x1B80, 0x4D101155, + 0x1B80, 0x4D101157, + 0x1B80, 0x30A81165, + 0x1B80, 0x30A81167, + 0x1B80, 0x00011175, + 0x1B80, 0x00011177, + 0x1B80, 0x6C001185, + 0x1B80, 0x6C001187, + 0x1B80, 0x00061195, + 0x1B80, 0x00061197, + 0x1B80, 0x530011A5, + 0x1B80, 0x530011A7, + 0x1B80, 0x57F711B5, + 0x1B80, 0x57F711B7, + 0x1B80, 0x582111C5, + 0x1B80, 0x582111C7, + 0x1B80, 0x592E11D5, + 0x1B80, 0x592E11D7, + 0x1B80, 0x5A3811E5, + 0x1B80, 0x5A3811E7, + 0x1B80, 0x5B4111F5, + 0x1B80, 0x5B4111F7, + 0x1B80, 0x00071205, + 0x1B80, 0x00071207, + 0x1B80, 0x5C001215, + 0x1B80, 0x5C001217, + 0x1B80, 0x4B001225, + 0x1B80, 0x4B001227, + 0x1B80, 0x4E8F1235, + 0x1B80, 0x4E8F1237, + 0x1B80, 0x4F151245, + 0x1B80, 0x4F151247, + 0x1B80, 0x00041255, + 0x1B80, 0x00041257, + 0x1B80, 0xE1B31265, + 0x1B80, 0xE1B31267, + 0x1B80, 0xAB001275, + 0x1B80, 0xAB001277, + 0x1B80, 0x00011285, + 0x1B80, 0x00011287, + 0x1B80, 0x6C001295, + 0x1B80, 0x6C001297, + 0x1B80, 0x000612A5, + 0x1B80, 0x000612A7, + 0x1B80, 0x530012B5, + 0x1B80, 0x530012B7, + 0x1B80, 0x57F712C5, + 0x1B80, 0x57F712C7, + 0x1B80, 0x582112D5, + 0x1B80, 0x582112D7, + 0x1B80, 0x592E12E5, + 0x1B80, 0x592E12E7, + 0x1B80, 0x5A3812F5, + 0x1B80, 0x5A3812F7, + 0x1B80, 0x5B411305, + 0x1B80, 0x5B411307, + 0x1B80, 0x00071315, + 0x1B80, 0x00071317, + 0x1B80, 0x5C001325, + 0x1B80, 0x5C001327, + 0x1B80, 0x4B401335, + 0x1B80, 0x4B401337, + 0x1B80, 0x4E971345, + 0x1B80, 0x4E971347, + 0x1B80, 0x4F111355, + 0x1B80, 0x4F111357, + 0x1B80, 0x00041365, + 0x1B80, 0x00041367, + 0x1B80, 0xE1B31375, + 0x1B80, 0xE1B31377, + 0x1B80, 0xAB001385, + 0x1B80, 0xAB001387, + 0x1B80, 0x8B001395, + 0x1B80, 0x8B001397, + 0x1B80, 0xAB0013A5, + 0x1B80, 0xAB0013A7, + 0x1B80, 0x8A1913B5, + 0x1B80, 0x8A1913B7, + 0x1B80, 0x301D13C5, + 0x1B80, 0x301D13C7, + 0x1B80, 0x000113D5, + 0x1B80, 0x000113D7, + 0x1B80, 0x6C0113E5, + 0x1B80, 0x6C0113E7, + 0x1B80, 0x000613F5, + 0x1B80, 0x000613F7, + 0x1B80, 0x53011405, + 0x1B80, 0x53011407, + 0x1B80, 0x57F71415, + 0x1B80, 0x57F71417, + 0x1B80, 0x58211425, + 0x1B80, 0x58211427, + 0x1B80, 0x592E1435, + 0x1B80, 0x592E1437, + 0x1B80, 0x5A381445, + 0x1B80, 0x5A381447, + 0x1B80, 0x5B411455, + 0x1B80, 0x5B411457, + 0x1B80, 0x00071465, + 0x1B80, 0x00071467, + 0x1B80, 0x5C001475, + 0x1B80, 0x5C001477, + 0x1B80, 0x4B001485, + 0x1B80, 0x4B001487, + 0x1B80, 0x4E871495, + 0x1B80, 0x4E871497, + 0x1B80, 0x4F1114A5, + 0x1B80, 0x4F1114A7, + 0x1B80, 0x000414B5, + 0x1B80, 0x000414B7, + 0x1B80, 0xE1B314C5, + 0x1B80, 0xE1B314C7, + 0x1B80, 0xAB0014D5, + 0x1B80, 0xAB0014D7, + 0x1B80, 0x000614E5, + 0x1B80, 0x000614E7, + 0x1B80, 0x577714F5, + 0x1B80, 0x577714F7, + 0x1B80, 0x00071505, + 0x1B80, 0x00071507, + 0x1B80, 0x4E861515, + 0x1B80, 0x4E861517, + 0x1B80, 0x00041525, + 0x1B80, 0x00041527, + 0x1B80, 0x00011535, + 0x1B80, 0x00011537, + 0x1B80, 0x00011545, + 0x1B80, 0x00011547, + 0x1B80, 0x7B241555, + 0x1B80, 0x7B241557, + 0x1B80, 0x7A401565, + 0x1B80, 0x7A401567, + 0x1B80, 0x79001575, + 0x1B80, 0x79001577, + 0x1B80, 0x55031585, + 0x1B80, 0x55031587, + 0x1B80, 0x31611595, + 0x1B80, 0x31611597, + 0x1B80, 0x7B1C15A5, + 0x1B80, 0x7B1C15A7, + 0x1B80, 0x7A4015B5, + 0x1B80, 0x7A4015B7, + 0x1B80, 0x550B15C5, + 0x1B80, 0x550B15C7, + 0x1B80, 0x316115D5, + 0x1B80, 0x316115D7, + 0x1B80, 0x7B2015E5, + 0x1B80, 0x7B2015E7, + 0x1B80, 0x7A0015F5, + 0x1B80, 0x7A0015F7, + 0x1B80, 0x55131605, + 0x1B80, 0x55131607, + 0x1B80, 0x74011615, + 0x1B80, 0x74011617, + 0x1B80, 0x74001625, + 0x1B80, 0x74001627, + 0x1B80, 0x8E001635, + 0x1B80, 0x8E001637, + 0x1B80, 0x00011645, + 0x1B80, 0x00011647, + 0x1B80, 0x57021655, + 0x1B80, 0x57021657, + 0x1B80, 0x57001665, + 0x1B80, 0x57001667, + 0x1B80, 0x97001675, + 0x1B80, 0x97001677, + 0x1B80, 0x00011685, + 0x1B80, 0x00011687, + 0x1B80, 0x4F781695, + 0x1B80, 0x4F781697, + 0x1B80, 0x538816A5, + 0x1B80, 0x538816A7, + 0x1B80, 0xE17516B5, + 0x1B80, 0xE17516B7, + 0x1B80, 0x548016C5, + 0x1B80, 0x548016C7, + 0x1B80, 0x540016D5, + 0x1B80, 0x540016D7, + 0x1B80, 0x548116E5, + 0x1B80, 0x548116E7, + 0x1B80, 0x540016F5, + 0x1B80, 0x540016F7, + 0x1B80, 0x54821705, + 0x1B80, 0x54821707, + 0x1B80, 0x54001715, + 0x1B80, 0x54001717, + 0x1B80, 0xE1801725, + 0x1B80, 0xE1801727, + 0x1B80, 0xBF1D1735, + 0x1B80, 0xBF1D1737, + 0x1B80, 0x301D1745, + 0x1B80, 0x301D1747, + 0x1B80, 0xE1551755, + 0x1B80, 0xE1551757, + 0x1B80, 0xE15A1765, + 0x1B80, 0xE15A1767, + 0x1B80, 0xE15E1775, + 0x1B80, 0xE15E1777, + 0x1B80, 0xE1651785, + 0x1B80, 0xE1651787, + 0x1B80, 0xE1C51795, + 0x1B80, 0xE1C51797, + 0x1B80, 0x551317A5, + 0x1B80, 0x551317A7, + 0x1B80, 0xE16117B5, + 0x1B80, 0xE16117B7, + 0x1B80, 0x551517C5, + 0x1B80, 0x551517C7, + 0x1B80, 0xE16517D5, + 0x1B80, 0xE16517D7, + 0x1B80, 0xE1C517E5, + 0x1B80, 0xE1C517E7, + 0x1B80, 0x000117F5, + 0x1B80, 0x000117F7, + 0x1B80, 0x54BF1805, + 0x1B80, 0x54BF1807, + 0x1B80, 0x54C01815, + 0x1B80, 0x54C01817, + 0x1B80, 0x54A31825, + 0x1B80, 0x54A31827, + 0x1B80, 0x54C11835, + 0x1B80, 0x54C11837, + 0x1B80, 0x54A41845, + 0x1B80, 0x54A41847, + 0x1B80, 0x4C181855, + 0x1B80, 0x4C181857, + 0x1B80, 0xBF071865, + 0x1B80, 0xBF071867, + 0x1B80, 0x54C21875, + 0x1B80, 0x54C21877, + 0x1B80, 0x54A41885, + 0x1B80, 0x54A41887, + 0x1B80, 0xBF041895, + 0x1B80, 0xBF041897, + 0x1B80, 0x54C118A5, + 0x1B80, 0x54C118A7, + 0x1B80, 0x54A318B5, + 0x1B80, 0x54A318B7, + 0x1B80, 0xBF0118C5, + 0x1B80, 0xBF0118C7, + 0x1B80, 0xE1D318D5, + 0x1B80, 0xE1D318D7, + 0x1B80, 0x54DF18E5, + 0x1B80, 0x54DF18E7, + 0x1B80, 0x000118F5, + 0x1B80, 0x000118F7, + 0x1B80, 0x54BF1905, + 0x1B80, 0x54BF1907, + 0x1B80, 0x54E51915, + 0x1B80, 0x54E51917, + 0x1B80, 0x050A1925, + 0x1B80, 0x050A1927, + 0x1B80, 0x54DF1935, + 0x1B80, 0x54DF1937, + 0x1B80, 0x00011945, + 0x1B80, 0x00011947, + 0x1B80, 0x7F201955, + 0x1B80, 0x7F201957, + 0x1B80, 0x7E001965, + 0x1B80, 0x7E001967, + 0x1B80, 0x7D001975, + 0x1B80, 0x7D001977, + 0x1B80, 0x55011985, + 0x1B80, 0x55011987, + 0x1B80, 0x5C311995, + 0x1B80, 0x5C311997, + 0x1B80, 0xE16119A5, + 0x1B80, 0xE16119A7, + 0x1B80, 0xE16519B5, + 0x1B80, 0xE16519B7, + 0x1B80, 0x548019C5, + 0x1B80, 0x548019C7, + 0x1B80, 0x540019D5, + 0x1B80, 0x540019D7, + 0x1B80, 0x548119E5, + 0x1B80, 0x548119E7, + 0x1B80, 0x540019F5, + 0x1B80, 0x540019F7, + 0x1B80, 0x54821A05, + 0x1B80, 0x54821A07, + 0x1B80, 0x54001A15, + 0x1B80, 0x54001A17, + 0x1B80, 0xE1801A25, + 0x1B80, 0xE1801A27, + 0x1B80, 0xBFED1A35, + 0x1B80, 0xBFED1A37, + 0x1B80, 0x301D1A45, + 0x1B80, 0x301D1A47, + 0x1B80, 0x00231A55, + 0x1B80, 0x00231A57, + 0x1B80, 0x7B201A65, + 0x1B80, 0x7B201A67, + 0x1B80, 0x7A001A75, + 0x1B80, 0x7A001A77, + 0x1B80, 0x79001A85, + 0x1B80, 0x79001A87, + 0x1B80, 0xE1C91A95, + 0x1B80, 0xE1C91A97, + 0x1B80, 0x00021AA5, + 0x1B80, 0x00021AA7, + 0x1B80, 0x00011AB5, + 0x1B80, 0x00011AB7, + 0x1B80, 0x00221AC5, + 0x1B80, 0x00221AC7, + 0x1B80, 0x7B201AD5, + 0x1B80, 0x7B201AD7, + 0x1B80, 0x7A001AE5, + 0x1B80, 0x7A001AE7, + 0x1B80, 0x79001AF5, + 0x1B80, 0x79001AF7, + 0x1B80, 0xE1C91B05, + 0x1B80, 0xE1C91B07, + 0x1B80, 0x00021B15, + 0x1B80, 0x00021B17, + 0x1B80, 0x00011B25, + 0x1B80, 0x00011B27, + 0x1B80, 0x74021B35, + 0x1B80, 0x74021B37, + 0x1B80, 0x003F1B45, + 0x1B80, 0x003F1B47, + 0x1B80, 0x74001B55, + 0x1B80, 0x74001B57, + 0x1B80, 0x00021B65, + 0x1B80, 0x00021B67, + 0x1B80, 0x00011B75, + 0x1B80, 0x00011B77, + 0x1B80, 0x4D041B85, + 0x1B80, 0x4D041B87, + 0x1B80, 0x2EF81B95, + 0x1B80, 0x2EF81B97, + 0x1B80, 0x00001BA5, + 0x1B80, 0x00001BA7, + 0x1B80, 0x23301BB5, + 0x1B80, 0x23301BB7, + 0x1B80, 0x00241BC5, + 0x1B80, 0x00241BC7, + 0x1B80, 0x23E01BD5, + 0x1B80, 0x23E01BD7, + 0x1B80, 0x003F1BE5, + 0x1B80, 0x003F1BE7, + 0x1B80, 0x23FC1BF5, + 0x1B80, 0x23FC1BF7, + 0x1B80, 0xBFCE1C05, + 0x1B80, 0xBFCE1C07, + 0x1B80, 0x2EF01C15, + 0x1B80, 0x2EF01C17, + 0x1B80, 0x00001C25, + 0x1B80, 0x00001C27, + 0x1B80, 0x4D001C35, + 0x1B80, 0x4D001C37, + 0x1B80, 0x00011C45, + 0x1B80, 0x00011C47, + 0x1B80, 0x549F1C55, + 0x1B80, 0x549F1C57, + 0x1B80, 0x54FF1C65, + 0x1B80, 0x54FF1C67, + 0x1B80, 0x54001C75, + 0x1B80, 0x54001C77, + 0x1B80, 0x00011C85, + 0x1B80, 0x00011C87, + 0x1B80, 0x5C311C95, + 0x1B80, 0x5C311C97, + 0x1B80, 0x07141CA5, + 0x1B80, 0x07141CA7, + 0x1B80, 0x54001CB5, + 0x1B80, 0x54001CB7, + 0x1B80, 0x5C321CC5, + 0x1B80, 0x5C321CC7, + 0x1B80, 0x00011CD5, + 0x1B80, 0x00011CD7, + 0x1B80, 0x5C321CE5, + 0x1B80, 0x5C321CE7, + 0x1B80, 0x07141CF5, + 0x1B80, 0x07141CF7, + 0x1B80, 0x54001D05, + 0x1B80, 0x54001D07, + 0x1B80, 0x5C311D15, + 0x1B80, 0x5C311D17, + 0x1B80, 0x00011D25, + 0x1B80, 0x00011D27, + 0x1B80, 0x4C981D35, + 0x1B80, 0x4C981D37, + 0x1B80, 0x4C181D45, + 0x1B80, 0x4C181D47, + 0x1B80, 0x00011D55, + 0x1B80, 0x00011D57, + 0x1B80, 0x5C321D65, + 0x1B80, 0x5C321D67, + 0x1B80, 0x62841D75, + 0x1B80, 0x62841D77, + 0x1B80, 0x66861D85, + 0x1B80, 0x66861D87, + 0x1B80, 0x6C031D95, + 0x1B80, 0x6C031D97, + 0x1B80, 0x7B201DA5, + 0x1B80, 0x7B201DA7, + 0x1B80, 0x7A001DB5, + 0x1B80, 0x7A001DB7, + 0x1B80, 0x79001DC5, + 0x1B80, 0x79001DC7, + 0x1B80, 0x7F201DD5, + 0x1B80, 0x7F201DD7, + 0x1B80, 0x7E001DE5, + 0x1B80, 0x7E001DE7, + 0x1B80, 0x7D001DF5, + 0x1B80, 0x7D001DF7, + 0x1B80, 0x09011E05, + 0x1B80, 0x09011E07, + 0x1B80, 0x0C011E15, + 0x1B80, 0x0C011E17, + 0x1B80, 0x0BA61E25, + 0x1B80, 0x0BA61E27, + 0x1B80, 0x00011E35, + 0x1B80, 0x00011E37, + 0x1B80, 0x00000006, + 0x1B80, 0x00000002, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8821c_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363636, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363636, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363636, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x22222224, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x20202022, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8821c_bb_pg_type0); + +static const u32 rtw8821c_rf_a[] = { + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0xA0000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0006FFFC, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0006FFFC, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0007060C, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0xA0000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0007060C, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0xA0000000, 0x00000000, + 0x0DD, 0x00000020, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00020000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0xA0000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0xA0000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0xA0000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0xA0000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0xA0000000, 0x00000000, + 0x018, 0x00018D24, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0xA0000000, 0x00000000, + 0x018, 0x00010D24, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0xA0000000, 0x00000000, + 0x01B, 0x00003A40, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A3, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A3, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A1, + 0x062, 0x0000D3A3, + 0x063, 0x00000002, + 0xA0000000, 0x00000000, + 0x061, 0x0004D3A1, + 0x062, 0x0000D3A3, + 0x063, 0x00000002, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x00033303, + 0x030, 0x00001000, + 0x03F, 0x00033303, + 0x030, 0x00002000, + 0x03F, 0x00033303, + 0x030, 0x00003000, + 0x03F, 0x00033303, + 0x030, 0x00004000, + 0x03F, 0x00033303, + 0x030, 0x00005000, + 0x03F, 0x00033303, + 0x030, 0x00006000, + 0x03F, 0x00033303, + 0x030, 0x00007000, + 0x03F, 0x00033303, + 0x030, 0x00008000, + 0x03F, 0x00033303, + 0x030, 0x00009000, + 0x03F, 0x00033303, + 0x030, 0x0000A000, + 0x03F, 0x00033303, + 0x030, 0x0000B000, + 0x03F, 0x00033303, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000333A3, + 0x030, 0x00001000, + 0x03F, 0x000333A3, + 0x030, 0x00002000, + 0x03F, 0x000333A3, + 0x030, 0x00003000, + 0x03F, 0x000333A3, + 0x030, 0x00004000, + 0x03F, 0x000313A3, + 0x030, 0x00005000, + 0x03F, 0x000313A3, + 0x030, 0x00006000, + 0x03F, 0x000313A3, + 0x030, 0x00007000, + 0x03F, 0x000313A3, + 0x030, 0x00008000, + 0x03F, 0x000333A3, + 0x030, 0x00009000, + 0x03F, 0x000333A3, + 0x030, 0x0000A000, + 0x03F, 0x000333A3, + 0x030, 0x0000B000, + 0x03F, 0x000333A3, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000335A3, + 0x030, 0x00001000, + 0x03F, 0x000335A3, + 0x030, 0x00002000, + 0x03F, 0x000335A3, + 0x030, 0x00003000, + 0x03F, 0x000335A3, + 0x030, 0x00004000, + 0x03F, 0x000335A3, + 0x030, 0x00005000, + 0x03F, 0x000335A3, + 0x030, 0x00006000, + 0x03F, 0x000335A3, + 0x030, 0x00007000, + 0x03F, 0x000335A3, + 0x030, 0x00008000, + 0x03F, 0x000335A3, + 0x030, 0x00009000, + 0x03F, 0x000335A3, + 0x030, 0x0000A000, + 0x03F, 0x000335A3, + 0x030, 0x0000B000, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000335A3, + 0x030, 0x00001000, + 0x03F, 0x000335A3, + 0x030, 0x00002000, + 0x03F, 0x000335A3, + 0x030, 0x00003000, + 0x03F, 0x000335A3, + 0x030, 0x00004000, + 0x03F, 0x000335A3, + 0x030, 0x00005000, + 0x03F, 0x000335A3, + 0x030, 0x00006000, + 0x03F, 0x000335A3, + 0x030, 0x00007000, + 0x03F, 0x000335A3, + 0x030, 0x00008000, + 0x03F, 0x000335A3, + 0x030, 0x00009000, + 0x03F, 0x000335A3, + 0x030, 0x0000A000, + 0x03F, 0x000335A3, + 0x030, 0x0000B000, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x00033303, + 0x033, 0x00000001, + 0x03F, 0x00033303, + 0x033, 0x00000002, + 0x03F, 0x00033303, + 0x033, 0x00000003, + 0x03F, 0x00033303, + 0x033, 0x00000004, + 0x03F, 0x00033303, + 0x033, 0x00000005, + 0x03F, 0x00033303, + 0x033, 0x00000006, + 0x03F, 0x00033303, + 0x033, 0x00000007, + 0x03F, 0x00033303, + 0x033, 0x00000008, + 0x03F, 0x00033303, + 0x033, 0x00000009, + 0x03F, 0x00033303, + 0x033, 0x0000000A, + 0x03F, 0x00033303, + 0x033, 0x0000000B, + 0x03F, 0x00033303, + 0x033, 0x0000000C, + 0x03F, 0x00033303, + 0x033, 0x0000000D, + 0x03F, 0x00033303, + 0x033, 0x0000000E, + 0x03F, 0x00033303, + 0x033, 0x0000000F, + 0x03F, 0x00033303, + 0x033, 0x00000010, + 0x03F, 0x00033303, + 0x033, 0x00000011, + 0x03F, 0x00033303, + 0x033, 0x00000012, + 0x03F, 0x00033303, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000333A3, + 0x033, 0x00000001, + 0x03F, 0x000333A3, + 0x033, 0x00000002, + 0x03F, 0x000333A3, + 0x033, 0x00000003, + 0x03F, 0x000333A3, + 0x033, 0x00000004, + 0x03F, 0x000333A3, + 0x033, 0x00000005, + 0x03F, 0x000333A3, + 0x033, 0x00000006, + 0x03F, 0x000333A3, + 0x033, 0x00000007, + 0x03F, 0x000333A3, + 0x033, 0x00000008, + 0x03F, 0x000313A3, + 0x033, 0x00000009, + 0x03F, 0x000313A3, + 0x033, 0x0000000A, + 0x03F, 0x000313A3, + 0x033, 0x0000000B, + 0x03F, 0x000313A3, + 0x033, 0x0000000C, + 0x03F, 0x000313A3, + 0x033, 0x0000000D, + 0x03F, 0x000333A3, + 0x033, 0x0000000E, + 0x03F, 0x000333A3, + 0x033, 0x0000000F, + 0x03F, 0x000333A3, + 0x033, 0x00000010, + 0x03F, 0x000333A3, + 0x033, 0x00000011, + 0x03F, 0x000333A3, + 0x033, 0x00000012, + 0x03F, 0x000333A3, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000335A3, + 0x033, 0x00000001, + 0x03F, 0x000335A3, + 0x033, 0x00000002, + 0x03F, 0x000335A3, + 0x033, 0x00000003, + 0x03F, 0x000335A3, + 0x033, 0x00000004, + 0x03F, 0x000335A3, + 0x033, 0x00000005, + 0x03F, 0x000335A3, + 0x033, 0x00000006, + 0x03F, 0x000335A3, + 0x033, 0x00000007, + 0x03F, 0x000335A3, + 0x033, 0x00000008, + 0x03F, 0x000335A3, + 0x033, 0x00000009, + 0x03F, 0x000335A3, + 0x033, 0x0000000A, + 0x03F, 0x000335A3, + 0x033, 0x0000000B, + 0x03F, 0x000335A3, + 0x033, 0x0000000C, + 0x03F, 0x000335A3, + 0x033, 0x0000000D, + 0x03F, 0x000335A3, + 0x033, 0x0000000E, + 0x03F, 0x000335A3, + 0x033, 0x0000000F, + 0x03F, 0x000335A3, + 0x033, 0x00000010, + 0x03F, 0x000335A3, + 0x033, 0x00000011, + 0x03F, 0x000335A3, + 0x033, 0x00000012, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000335A3, + 0x033, 0x00000001, + 0x03F, 0x000335A3, + 0x033, 0x00000002, + 0x03F, 0x000335A3, + 0x033, 0x00000003, + 0x03F, 0x000335A3, + 0x033, 0x00000004, + 0x03F, 0x000335A3, + 0x033, 0x00000005, + 0x03F, 0x000335A3, + 0x033, 0x00000006, + 0x03F, 0x000335A3, + 0x033, 0x00000007, + 0x03F, 0x000335A3, + 0x033, 0x00000008, + 0x03F, 0x000335A3, + 0x033, 0x00000009, + 0x03F, 0x000335A3, + 0x033, 0x0000000A, + 0x03F, 0x000335A3, + 0x033, 0x0000000B, + 0x03F, 0x000335A3, + 0x033, 0x0000000C, + 0x03F, 0x000335A3, + 0x033, 0x0000000D, + 0x03F, 0x000335A3, + 0x033, 0x0000000E, + 0x03F, 0x000335A3, + 0x033, 0x0000000F, + 0x03F, 0x000335A3, + 0x033, 0x00000010, + 0x03F, 0x000335A3, + 0x033, 0x00000011, + 0x03F, 0x000335A3, + 0x033, 0x00000012, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000644, + 0x030, 0x00001135, + 0x030, 0x00002133, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000644, + 0x030, 0x00001412, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000640, + 0x030, 0x00001512, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000640, + 0x030, 0x00001512, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000800, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000001, + 0x033, 0x00000021, + 0x03F, 0x00000004, + 0x033, 0x00000022, + 0x03F, 0x00000007, + 0x033, 0x00000023, + 0x03F, 0x00000024, + 0x033, 0x00000024, + 0x03F, 0x00000027, + 0x033, 0x00000025, + 0x03F, 0x0000002A, + 0x033, 0x00000026, + 0x03F, 0x0000002D, + 0x033, 0x00000027, + 0x03F, 0x00000030, + 0x033, 0x00000028, + 0x03F, 0x00000033, + 0x033, 0x00000029, + 0x03F, 0x00000036, + 0x033, 0x0000002A, + 0x03F, 0x00000039, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E65, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000EE4, + 0x033, 0x00000025, + 0x03F, 0x00000EE7, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E48, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000E6B, + 0x033, 0x00000025, + 0x03F, 0x00000EAA, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E65, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000EE4, + 0x033, 0x00000025, + 0x03F, 0x00000EE7, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000001, + 0x033, 0x00000061, + 0x03F, 0x00000004, + 0x033, 0x00000062, + 0x03F, 0x00000007, + 0x033, 0x00000063, + 0x03F, 0x00000024, + 0x033, 0x00000064, + 0x03F, 0x00000027, + 0x033, 0x00000065, + 0x03F, 0x0000002A, + 0x033, 0x00000066, + 0x03F, 0x0000002D, + 0x033, 0x00000067, + 0x03F, 0x00000030, + 0x033, 0x00000068, + 0x03F, 0x00000033, + 0x033, 0x00000069, + 0x03F, 0x00000036, + 0x033, 0x0000006A, + 0x03F, 0x00000039, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E42, + 0x033, 0x00000061, + 0x03F, 0x00000E45, + 0x033, 0x00000062, + 0x03F, 0x00000E65, + 0x033, 0x00000063, + 0x03F, 0x00000E68, + 0x033, 0x00000064, + 0x03F, 0x00000EE5, + 0x033, 0x00000065, + 0x03F, 0x00000EE8, + 0x033, 0x00000066, + 0x03F, 0x00000EEB, + 0x033, 0x00000067, + 0x03F, 0x00000EEE, + 0x033, 0x00000068, + 0x03F, 0x00000EF1, + 0x033, 0x00000069, + 0x03F, 0x00000EF4, + 0x033, 0x0000006A, + 0x03F, 0x00000EF7, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E09, + 0x033, 0x00000061, + 0x03F, 0x00000E43, + 0x033, 0x00000062, + 0x03F, 0x00000E46, + 0x033, 0x00000063, + 0x03F, 0x00000E49, + 0x033, 0x00000064, + 0x03F, 0x00000E88, + 0x033, 0x00000065, + 0x03F, 0x00000E8B, + 0x033, 0x00000066, + 0x03F, 0x00000ECB, + 0x033, 0x00000067, + 0x03F, 0x00000ECE, + 0x033, 0x00000068, + 0x03F, 0x00000EF0, + 0x033, 0x00000069, + 0x03F, 0x00000EF3, + 0x033, 0x0000006A, + 0x03F, 0x00000EF6, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E42, + 0x033, 0x00000061, + 0x03F, 0x00000E45, + 0x033, 0x00000062, + 0x03F, 0x00000E65, + 0x033, 0x00000063, + 0x03F, 0x00000E68, + 0x033, 0x00000064, + 0x03F, 0x00000EE5, + 0x033, 0x00000065, + 0x03F, 0x00000EE8, + 0x033, 0x00000066, + 0x03F, 0x00000EEB, + 0x033, 0x00000067, + 0x03F, 0x00000EEE, + 0x033, 0x00000068, + 0x03F, 0x00000EF1, + 0x033, 0x00000069, + 0x03F, 0x00000EF4, + 0x033, 0x0000006A, + 0x03F, 0x00000EF7, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000001, + 0x033, 0x000000A1, + 0x03F, 0x00000004, + 0x033, 0x000000A2, + 0x03F, 0x00000007, + 0x033, 0x000000A3, + 0x03F, 0x00000025, + 0x033, 0x000000A4, + 0x03F, 0x00000028, + 0x033, 0x000000A5, + 0x03F, 0x0000002B, + 0x033, 0x000000A6, + 0x03F, 0x0000002E, + 0x033, 0x000000A7, + 0x03F, 0x00000031, + 0x033, 0x000000A8, + 0x03F, 0x00000034, + 0x033, 0x000000A9, + 0x03F, 0x00000037, + 0x033, 0x000000AA, + 0x03F, 0x0000003A, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E09, + 0x033, 0x000000A1, + 0x03F, 0x00000E43, + 0x033, 0x000000A2, + 0x03F, 0x00000E64, + 0x033, 0x000000A3, + 0x03F, 0x00000E67, + 0x033, 0x000000A4, + 0x03F, 0x00000EE4, + 0x033, 0x000000A5, + 0x03F, 0x00000EE7, + 0x033, 0x000000A6, + 0x03F, 0x00000EEA, + 0x033, 0x000000A7, + 0x03F, 0x00000EED, + 0x033, 0x000000A8, + 0x03F, 0x00000EF0, + 0x033, 0x000000A9, + 0x03F, 0x00000EF3, + 0x033, 0x000000AA, + 0x03F, 0x00000EF6, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E08, + 0x033, 0x000000A1, + 0x03F, 0x00000E42, + 0x033, 0x000000A2, + 0x03F, 0x00000E45, + 0x033, 0x000000A3, + 0x03F, 0x00000E48, + 0x033, 0x000000A4, + 0x03F, 0x00000EA5, + 0x033, 0x000000A5, + 0x03F, 0x00000EA8, + 0x033, 0x000000A6, + 0x03F, 0x00000ECA, + 0x033, 0x000000A7, + 0x03F, 0x00000ECD, + 0x033, 0x000000A8, + 0x03F, 0x00000EEF, + 0x033, 0x000000A9, + 0x03F, 0x00000EF2, + 0x033, 0x000000AA, + 0x03F, 0x00000EF5, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E09, + 0x033, 0x000000A1, + 0x03F, 0x00000E43, + 0x033, 0x000000A2, + 0x03F, 0x00000E64, + 0x033, 0x000000A3, + 0x03F, 0x00000E67, + 0x033, 0x000000A4, + 0x03F, 0x00000EE4, + 0x033, 0x000000A5, + 0x03F, 0x00000EE7, + 0x033, 0x000000A6, + 0x03F, 0x00000EEA, + 0x033, 0x000000A7, + 0x03F, 0x00000EED, + 0x033, 0x000000A8, + 0x03F, 0x00000EF0, + 0x033, 0x000000A9, + 0x03F, 0x00000EF3, + 0x033, 0x000000AA, + 0x03F, 0x00000EF6, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0xA0000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051429, + 0x033, 0x00000001, + 0x03F, 0x00051449, + 0x033, 0x00000002, + 0x03F, 0x0005144C, + 0x033, 0x00000003, + 0x03F, 0x00051C66, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051CE8, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051429, + 0x033, 0x00000001, + 0x03F, 0x00051449, + 0x033, 0x00000002, + 0x03F, 0x0005144C, + 0x033, 0x00000003, + 0x03F, 0x00051C66, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051CE8, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C67, + 0x033, 0x00000005, + 0x03F, 0x00051C6A, + 0x033, 0x00000006, + 0x03F, 0x00051C8B, + 0x033, 0x00000007, + 0x03F, 0x00051CE9, + 0x033, 0x00000008, + 0x03F, 0x00051CEC, + 0x033, 0x00000009, + 0x03F, 0x00051CEF, + 0x033, 0x0000000A, + 0x03F, 0x00051CF2, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C67, + 0x033, 0x00000005, + 0x03F, 0x00051C6A, + 0x033, 0x00000006, + 0x03F, 0x00051C8B, + 0x033, 0x00000007, + 0x03F, 0x00051CE9, + 0x033, 0x00000008, + 0x03F, 0x00051CEC, + 0x033, 0x00000009, + 0x03F, 0x00051CEF, + 0x033, 0x0000000A, + 0x03F, 0x00051CF2, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0xA0000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8821c_rf_a, A); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8821c_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 30, }, + { 2, 0, 0, 0, 1, 30, }, + { 1, 0, 0, 0, 1, 34, }, + { 3, 0, 0, 0, 1, 30, }, + { 4, 0, 0, 0, 1, 34, }, + { 5, 0, 0, 0, 1, 30, }, + { 6, 0, 0, 0, 1, 30, }, + { 7, 0, 0, 0, 1, 30, }, + { 8, 0, 0, 0, 1, 30, }, + { 9, 0, 0, 0, 1, 28, }, + { 10, 0, 0, 0, 1, 30, }, + { 11, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 30, }, + { 1, 0, 0, 0, 2, 34, }, + { 3, 0, 0, 0, 2, 32, }, + { 4, 0, 0, 0, 2, 34, }, + { 5, 0, 0, 0, 2, 30, }, + { 6, 0, 0, 0, 2, 32, }, + { 7, 0, 0, 0, 2, 30, }, + { 8, 0, 0, 0, 2, 32, }, + { 9, 0, 0, 0, 2, 28, }, + { 10, 0, 0, 0, 2, 30, }, + { 11, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 30, }, + { 1, 0, 0, 0, 3, 34, }, + { 3, 0, 0, 0, 3, 32, }, + { 4, 0, 0, 0, 3, 34, }, + { 5, 0, 0, 0, 3, 30, }, + { 6, 0, 0, 0, 3, 32, }, + { 7, 0, 0, 0, 3, 30, }, + { 8, 0, 0, 0, 3, 32, }, + { 9, 0, 0, 0, 3, 28, }, + { 10, 0, 0, 0, 3, 30, }, + { 11, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 30, }, + { 1, 0, 0, 0, 4, 34, }, + { 3, 0, 0, 0, 4, 32, }, + { 4, 0, 0, 0, 4, 34, }, + { 5, 0, 0, 0, 4, 30, }, + { 6, 0, 0, 0, 4, 32, }, + { 7, 0, 0, 0, 4, 30, }, + { 8, 0, 0, 0, 4, 32, }, + { 9, 0, 0, 0, 4, 28, }, + { 10, 0, 0, 0, 4, 30, }, + { 11, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 30, }, + { 1, 0, 0, 0, 5, 34, }, + { 3, 0, 0, 0, 5, 32, }, + { 4, 0, 0, 0, 5, 34, }, + { 5, 0, 0, 0, 5, 30, }, + { 6, 0, 0, 0, 5, 32, }, + { 7, 0, 0, 0, 5, 30, }, + { 8, 0, 0, 0, 5, 32, }, + { 9, 0, 0, 0, 5, 28, }, + { 10, 0, 0, 0, 5, 30, }, + { 11, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 30, }, + { 1, 0, 0, 0, 6, 34, }, + { 3, 0, 0, 0, 6, 32, }, + { 4, 0, 0, 0, 6, 34, }, + { 5, 0, 0, 0, 6, 30, }, + { 6, 0, 0, 0, 6, 32, }, + { 7, 0, 0, 0, 6, 30, }, + { 8, 0, 0, 0, 6, 32, }, + { 9, 0, 0, 0, 6, 28, }, + { 10, 0, 0, 0, 6, 30, }, + { 11, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 30, }, + { 1, 0, 0, 0, 7, 34, }, + { 3, 0, 0, 0, 7, 32, }, + { 4, 0, 0, 0, 7, 34, }, + { 5, 0, 0, 0, 7, 30, }, + { 6, 0, 0, 0, 7, 32, }, + { 7, 0, 0, 0, 7, 30, }, + { 8, 0, 0, 0, 7, 32, }, + { 9, 0, 0, 0, 7, 28, }, + { 10, 0, 0, 0, 7, 30, }, + { 11, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 30, }, + { 1, 0, 0, 0, 8, 34, }, + { 3, 0, 0, 0, 8, 32, }, + { 4, 0, 0, 0, 8, 34, }, + { 5, 0, 0, 0, 8, 30, }, + { 6, 0, 0, 0, 8, 32, }, + { 7, 0, 0, 0, 8, 30, }, + { 8, 0, 0, 0, 8, 32, }, + { 9, 0, 0, 0, 8, 28, }, + { 10, 0, 0, 0, 8, 30, }, + { 11, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 30, }, + { 1, 0, 0, 0, 9, 34, }, + { 3, 0, 0, 0, 9, 32, }, + { 4, 0, 0, 0, 9, 34, }, + { 5, 0, 0, 0, 9, 30, }, + { 6, 0, 0, 0, 9, 32, }, + { 7, 0, 0, 0, 9, 30, }, + { 8, 0, 0, 0, 9, 32, }, + { 9, 0, 0, 0, 9, 28, }, + { 10, 0, 0, 0, 9, 30, }, + { 11, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 30, }, + { 1, 0, 0, 0, 10, 34, }, + { 3, 0, 0, 0, 10, 32, }, + { 4, 0, 0, 0, 10, 34, }, + { 5, 0, 0, 0, 10, 30, }, + { 6, 0, 0, 0, 10, 32, }, + { 7, 0, 0, 0, 10, 30, }, + { 8, 0, 0, 0, 10, 32, }, + { 9, 0, 0, 0, 10, 28, }, + { 10, 0, 0, 0, 10, 30, }, + { 11, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 30, }, + { 1, 0, 0, 0, 11, 34, }, + { 3, 0, 0, 0, 11, 32, }, + { 4, 0, 0, 0, 11, 34, }, + { 5, 0, 0, 0, 11, 30, }, + { 6, 0, 0, 0, 11, 32, }, + { 7, 0, 0, 0, 11, 30, }, + { 8, 0, 0, 0, 11, 32, }, + { 9, 0, 0, 0, 11, 28, }, + { 10, 0, 0, 0, 11, 30, }, + { 11, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 30, }, + { 1, 0, 0, 0, 12, 34, }, + { 3, 0, 0, 0, 12, 24, }, + { 4, 0, 0, 0, 12, 34, }, + { 5, 0, 0, 0, 12, 30, }, + { 6, 0, 0, 0, 12, 24, }, + { 7, 0, 0, 0, 12, 30, }, + { 8, 0, 0, 0, 12, 24, }, + { 9, 0, 0, 0, 12, 24, }, + { 10, 0, 0, 0, 12, 30, }, + { 11, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 30, }, + { 1, 0, 0, 0, 13, 34, }, + { 3, 0, 0, 0, 13, 16, }, + { 4, 0, 0, 0, 13, 34, }, + { 5, 0, 0, 0, 13, 30, }, + { 6, 0, 0, 0, 13, 16, }, + { 7, 0, 0, 0, 13, 30, }, + { 8, 0, 0, 0, 13, 16, }, + { 9, 0, 0, 0, 13, 18, }, + { 10, 0, 0, 0, 13, 30, }, + { 11, 0, 0, 0, 13, 30, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 34, }, + { 3, 0, 0, 0, 14, 63, }, + { 4, 0, 0, 0, 14, 63, }, + { 5, 0, 0, 0, 14, 63, }, + { 6, 0, 0, 0, 14, 63, }, + { 7, 0, 0, 0, 14, 63, }, + { 8, 0, 0, 0, 14, 63, }, + { 9, 0, 0, 0, 14, 63, }, + { 10, 0, 0, 0, 14, 63, }, + { 11, 0, 0, 0, 14, 63, }, + { 0, 0, 0, 1, 1, 30, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 34, }, + { 3, 0, 0, 1, 1, 30, }, + { 4, 0, 0, 1, 1, 32, }, + { 5, 0, 0, 1, 1, 30, }, + { 6, 0, 0, 1, 1, 30, }, + { 7, 0, 0, 1, 1, 30, }, + { 8, 0, 0, 1, 1, 30, }, + { 9, 0, 0, 1, 1, 30, }, + { 10, 0, 0, 1, 1, 30, }, + { 11, 0, 0, 1, 1, 30, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 3, 0, 0, 1, 2, 32, }, + { 4, 0, 0, 1, 2, 34, }, + { 5, 0, 0, 1, 2, 30, }, + { 6, 0, 0, 1, 2, 32, }, + { 7, 0, 0, 1, 2, 30, }, + { 8, 0, 0, 1, 2, 32, }, + { 9, 0, 0, 1, 2, 30, }, + { 10, 0, 0, 1, 2, 30, }, + { 11, 0, 0, 1, 2, 30, }, + { 0, 0, 0, 1, 3, 34, }, + { 2, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 3, 0, 0, 1, 3, 34, }, + { 4, 0, 0, 1, 3, 34, }, + { 5, 0, 0, 1, 3, 30, }, + { 6, 0, 0, 1, 3, 34, }, + { 7, 0, 0, 1, 3, 30, }, + { 8, 0, 0, 1, 3, 34, }, + { 9, 0, 0, 1, 3, 30, }, + { 10, 0, 0, 1, 3, 30, }, + { 11, 0, 0, 1, 3, 30, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 3, 0, 0, 1, 4, 34, }, + { 4, 0, 0, 1, 4, 34, }, + { 5, 0, 0, 1, 4, 30, }, + { 6, 0, 0, 1, 4, 34, }, + { 7, 0, 0, 1, 4, 30, }, + { 8, 0, 0, 1, 4, 34, }, + { 9, 0, 0, 1, 4, 30, }, + { 10, 0, 0, 1, 4, 30, }, + { 11, 0, 0, 1, 4, 30, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 3, 0, 0, 1, 5, 34, }, + { 4, 0, 0, 1, 5, 34, }, + { 5, 0, 0, 1, 5, 30, }, + { 6, 0, 0, 1, 5, 34, }, + { 7, 0, 0, 1, 5, 30, }, + { 8, 0, 0, 1, 5, 34, }, + { 9, 0, 0, 1, 5, 30, }, + { 10, 0, 0, 1, 5, 30, }, + { 11, 0, 0, 1, 5, 30, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 3, 0, 0, 1, 6, 34, }, + { 4, 0, 0, 1, 6, 34, }, + { 5, 0, 0, 1, 6, 30, }, + { 6, 0, 0, 1, 6, 34, }, + { 7, 0, 0, 1, 6, 30, }, + { 8, 0, 0, 1, 6, 34, }, + { 9, 0, 0, 1, 6, 30, }, + { 10, 0, 0, 1, 6, 30, }, + { 11, 0, 0, 1, 6, 30, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 3, 0, 0, 1, 7, 34, }, + { 4, 0, 0, 1, 7, 34, }, + { 5, 0, 0, 1, 7, 30, }, + { 6, 0, 0, 1, 7, 34, }, + { 7, 0, 0, 1, 7, 30, }, + { 8, 0, 0, 1, 7, 34, }, + { 9, 0, 0, 1, 7, 30, }, + { 10, 0, 0, 1, 7, 30, }, + { 11, 0, 0, 1, 7, 30, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 3, 0, 0, 1, 8, 34, }, + { 4, 0, 0, 1, 8, 34, }, + { 5, 0, 0, 1, 8, 30, }, + { 6, 0, 0, 1, 8, 34, }, + { 7, 0, 0, 1, 8, 30, }, + { 8, 0, 0, 1, 8, 34, }, + { 9, 0, 0, 1, 8, 30, }, + { 10, 0, 0, 1, 8, 30, }, + { 11, 0, 0, 1, 8, 30, }, + { 0, 0, 0, 1, 9, 34, }, + { 2, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 3, 0, 0, 1, 9, 34, }, + { 4, 0, 0, 1, 9, 34, }, + { 5, 0, 0, 1, 9, 30, }, + { 6, 0, 0, 1, 9, 34, }, + { 7, 0, 0, 1, 9, 30, }, + { 8, 0, 0, 1, 9, 34, }, + { 9, 0, 0, 1, 9, 30, }, + { 10, 0, 0, 1, 9, 30, }, + { 11, 0, 0, 1, 9, 30, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 3, 0, 0, 1, 10, 32, }, + { 4, 0, 0, 1, 10, 34, }, + { 5, 0, 0, 1, 10, 30, }, + { 6, 0, 0, 1, 10, 32, }, + { 7, 0, 0, 1, 10, 30, }, + { 8, 0, 0, 1, 10, 32, }, + { 9, 0, 0, 1, 10, 26, }, + { 10, 0, 0, 1, 10, 30, }, + { 11, 0, 0, 1, 10, 30, }, + { 0, 0, 0, 1, 11, 30, }, + { 2, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 3, 0, 0, 1, 11, 30, }, + { 4, 0, 0, 1, 11, 34, }, + { 5, 0, 0, 1, 11, 30, }, + { 6, 0, 0, 1, 11, 30, }, + { 7, 0, 0, 1, 11, 30, }, + { 8, 0, 0, 1, 11, 30, }, + { 9, 0, 0, 1, 11, 22, }, + { 10, 0, 0, 1, 11, 30, }, + { 11, 0, 0, 1, 11, 30, }, + { 0, 0, 0, 1, 12, 28, }, + { 2, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 3, 0, 0, 1, 12, 28, }, + { 4, 0, 0, 1, 12, 34, }, + { 5, 0, 0, 1, 12, 30, }, + { 6, 0, 0, 1, 12, 28, }, + { 7, 0, 0, 1, 12, 30, }, + { 8, 0, 0, 1, 12, 28, }, + { 9, 0, 0, 1, 12, 18, }, + { 10, 0, 0, 1, 12, 30, }, + { 11, 0, 0, 1, 12, 30, }, + { 0, 0, 0, 1, 13, 16, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 3, 0, 0, 1, 13, 16, }, + { 4, 0, 0, 1, 13, 32, }, + { 5, 0, 0, 1, 13, 30, }, + { 6, 0, 0, 1, 13, 16, }, + { 7, 0, 0, 1, 13, 30, }, + { 8, 0, 0, 1, 13, 16, }, + { 9, 0, 0, 1, 13, 2, }, + { 10, 0, 0, 1, 13, 30, }, + { 11, 0, 0, 1, 13, 30, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 3, 0, 0, 1, 14, 63, }, + { 4, 0, 0, 1, 14, 63, }, + { 5, 0, 0, 1, 14, 63, }, + { 6, 0, 0, 1, 14, 63, }, + { 7, 0, 0, 1, 14, 63, }, + { 8, 0, 0, 1, 14, 63, }, + { 9, 0, 0, 1, 14, 63, }, + { 10, 0, 0, 1, 14, 63, }, + { 11, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 1, 34, }, + { 3, 0, 0, 2, 1, 26, }, + { 4, 0, 0, 2, 1, 32, }, + { 5, 0, 0, 2, 1, 30, }, + { 6, 0, 0, 2, 1, 26, }, + { 7, 0, 0, 2, 1, 30, }, + { 8, 0, 0, 2, 1, 26, }, + { 9, 0, 0, 2, 1, 30, }, + { 10, 0, 0, 2, 1, 30, }, + { 11, 0, 0, 2, 1, 30, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 3, 0, 0, 2, 2, 30, }, + { 4, 0, 0, 2, 2, 34, }, + { 5, 0, 0, 2, 2, 30, }, + { 6, 0, 0, 2, 2, 30, }, + { 7, 0, 0, 2, 2, 30, }, + { 8, 0, 0, 2, 2, 30, }, + { 9, 0, 0, 2, 2, 30, }, + { 10, 0, 0, 2, 2, 30, }, + { 11, 0, 0, 2, 2, 30, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 3, 0, 0, 2, 3, 32, }, + { 4, 0, 0, 2, 3, 34, }, + { 5, 0, 0, 2, 3, 30, }, + { 6, 0, 0, 2, 3, 32, }, + { 7, 0, 0, 2, 3, 30, }, + { 8, 0, 0, 2, 3, 32, }, + { 9, 0, 0, 2, 3, 30, }, + { 10, 0, 0, 2, 3, 30, }, + { 11, 0, 0, 2, 3, 30, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 3, 0, 0, 2, 4, 34, }, + { 4, 0, 0, 2, 4, 34, }, + { 5, 0, 0, 2, 4, 30, }, + { 6, 0, 0, 2, 4, 34, }, + { 7, 0, 0, 2, 4, 30, }, + { 8, 0, 0, 2, 4, 34, }, + { 9, 0, 0, 2, 4, 30, }, + { 10, 0, 0, 2, 4, 30, }, + { 11, 0, 0, 2, 4, 30, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 3, 0, 0, 2, 5, 34, }, + { 4, 0, 0, 2, 5, 34, }, + { 5, 0, 0, 2, 5, 30, }, + { 6, 0, 0, 2, 5, 34, }, + { 7, 0, 0, 2, 5, 30, }, + { 8, 0, 0, 2, 5, 34, }, + { 9, 0, 0, 2, 5, 30, }, + { 10, 0, 0, 2, 5, 30, }, + { 11, 0, 0, 2, 5, 30, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 3, 0, 0, 2, 6, 34, }, + { 4, 0, 0, 2, 6, 34, }, + { 5, 0, 0, 2, 6, 30, }, + { 6, 0, 0, 2, 6, 34, }, + { 7, 0, 0, 2, 6, 30, }, + { 8, 0, 0, 2, 6, 34, }, + { 9, 0, 0, 2, 6, 30, }, + { 10, 0, 0, 2, 6, 30, }, + { 11, 0, 0, 2, 6, 30, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 3, 0, 0, 2, 7, 34, }, + { 4, 0, 0, 2, 7, 34, }, + { 5, 0, 0, 2, 7, 30, }, + { 6, 0, 0, 2, 7, 34, }, + { 7, 0, 0, 2, 7, 30, }, + { 8, 0, 0, 2, 7, 34, }, + { 9, 0, 0, 2, 7, 30, }, + { 10, 0, 0, 2, 7, 30, }, + { 11, 0, 0, 2, 7, 30, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 3, 0, 0, 2, 8, 34, }, + { 4, 0, 0, 2, 8, 34, }, + { 5, 0, 0, 2, 8, 30, }, + { 6, 0, 0, 2, 8, 34, }, + { 7, 0, 0, 2, 8, 30, }, + { 8, 0, 0, 2, 8, 34, }, + { 9, 0, 0, 2, 8, 30, }, + { 10, 0, 0, 2, 8, 30, }, + { 11, 0, 0, 2, 8, 30, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 3, 0, 0, 2, 9, 32, }, + { 4, 0, 0, 2, 9, 34, }, + { 5, 0, 0, 2, 9, 30, }, + { 6, 0, 0, 2, 9, 32, }, + { 7, 0, 0, 2, 9, 30, }, + { 8, 0, 0, 2, 9, 32, }, + { 9, 0, 0, 2, 9, 30, }, + { 10, 0, 0, 2, 9, 30, }, + { 11, 0, 0, 2, 9, 30, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 3, 0, 0, 2, 10, 30, }, + { 4, 0, 0, 2, 10, 34, }, + { 5, 0, 0, 2, 10, 30, }, + { 6, 0, 0, 2, 10, 30, }, + { 7, 0, 0, 2, 10, 30, }, + { 8, 0, 0, 2, 10, 30, }, + { 9, 0, 0, 2, 10, 24, }, + { 10, 0, 0, 2, 10, 30, }, + { 11, 0, 0, 2, 10, 30, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 3, 0, 0, 2, 11, 28, }, + { 4, 0, 0, 2, 11, 34, }, + { 5, 0, 0, 2, 11, 30, }, + { 6, 0, 0, 2, 11, 28, }, + { 7, 0, 0, 2, 11, 30, }, + { 8, 0, 0, 2, 11, 28, }, + { 9, 0, 0, 2, 11, 20, }, + { 10, 0, 0, 2, 11, 30, }, + { 11, 0, 0, 2, 11, 30, }, + { 0, 0, 0, 2, 12, 26, }, + { 2, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 3, 0, 0, 2, 12, 26, }, + { 4, 0, 0, 2, 12, 34, }, + { 5, 0, 0, 2, 12, 30, }, + { 6, 0, 0, 2, 12, 26, }, + { 7, 0, 0, 2, 12, 30, }, + { 8, 0, 0, 2, 12, 26, }, + { 9, 0, 0, 2, 12, 16, }, + { 10, 0, 0, 2, 12, 30, }, + { 11, 0, 0, 2, 12, 30, }, + { 0, 0, 0, 2, 13, 12, }, + { 2, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 3, 0, 0, 2, 13, 12, }, + { 4, 0, 0, 2, 13, 32, }, + { 5, 0, 0, 2, 13, 30, }, + { 6, 0, 0, 2, 13, 12, }, + { 7, 0, 0, 2, 13, 30, }, + { 8, 0, 0, 2, 13, 12, }, + { 9, 0, 0, 2, 13, 0, }, + { 10, 0, 0, 2, 13, 30, }, + { 11, 0, 0, 2, 13, 30, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 3, 0, 0, 2, 14, 63, }, + { 4, 0, 0, 2, 14, 63, }, + { 5, 0, 0, 2, 14, 63, }, + { 6, 0, 0, 2, 14, 63, }, + { 7, 0, 0, 2, 14, 63, }, + { 8, 0, 0, 2, 14, 63, }, + { 9, 0, 0, 2, 14, 63, }, + { 10, 0, 0, 2, 14, 63, }, + { 11, 0, 0, 2, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 3, 0, 1, 2, 1, 63, }, + { 4, 0, 1, 2, 1, 63, }, + { 5, 0, 1, 2, 1, 63, }, + { 6, 0, 1, 2, 1, 63, }, + { 7, 0, 1, 2, 1, 63, }, + { 8, 0, 1, 2, 1, 63, }, + { 9, 0, 1, 2, 1, 63, }, + { 10, 0, 1, 2, 1, 63, }, + { 11, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 3, 0, 1, 2, 2, 63, }, + { 4, 0, 1, 2, 2, 63, }, + { 5, 0, 1, 2, 2, 63, }, + { 6, 0, 1, 2, 2, 63, }, + { 7, 0, 1, 2, 2, 63, }, + { 8, 0, 1, 2, 2, 63, }, + { 9, 0, 1, 2, 2, 63, }, + { 10, 0, 1, 2, 2, 63, }, + { 11, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 3, 30, }, + { 3, 0, 1, 2, 3, 26, }, + { 4, 0, 1, 2, 3, 30, }, + { 5, 0, 1, 2, 3, 30, }, + { 6, 0, 1, 2, 3, 26, }, + { 7, 0, 1, 2, 3, 30, }, + { 8, 0, 1, 2, 3, 26, }, + { 9, 0, 1, 2, 3, 29, }, + { 10, 0, 1, 2, 3, 30, }, + { 11, 0, 1, 2, 3, 30, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 4, 30, }, + { 3, 0, 1, 2, 4, 26, }, + { 4, 0, 1, 2, 4, 30, }, + { 5, 0, 1, 2, 4, 30, }, + { 6, 0, 1, 2, 4, 26, }, + { 7, 0, 1, 2, 4, 30, }, + { 8, 0, 1, 2, 4, 26, }, + { 9, 0, 1, 2, 4, 29, }, + { 10, 0, 1, 2, 4, 30, }, + { 11, 0, 1, 2, 4, 30, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 5, 30, }, + { 3, 0, 1, 2, 5, 30, }, + { 4, 0, 1, 2, 5, 30, }, + { 5, 0, 1, 2, 5, 30, }, + { 6, 0, 1, 2, 5, 30, }, + { 7, 0, 1, 2, 5, 30, }, + { 8, 0, 1, 2, 5, 30, }, + { 9, 0, 1, 2, 5, 29, }, + { 10, 0, 1, 2, 5, 30, }, + { 11, 0, 1, 2, 5, 30, }, + { 0, 0, 1, 2, 6, 30, }, + { 2, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 6, 30, }, + { 3, 0, 1, 2, 6, 30, }, + { 4, 0, 1, 2, 6, 30, }, + { 5, 0, 1, 2, 6, 30, }, + { 6, 0, 1, 2, 6, 30, }, + { 7, 0, 1, 2, 6, 30, }, + { 8, 0, 1, 2, 6, 30, }, + { 9, 0, 1, 2, 6, 29, }, + { 10, 0, 1, 2, 6, 30, }, + { 11, 0, 1, 2, 6, 30, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 7, 30, }, + { 3, 0, 1, 2, 7, 30, }, + { 4, 0, 1, 2, 7, 30, }, + { 5, 0, 1, 2, 7, 30, }, + { 6, 0, 1, 2, 7, 30, }, + { 7, 0, 1, 2, 7, 30, }, + { 8, 0, 1, 2, 7, 30, }, + { 9, 0, 1, 2, 7, 29, }, + { 10, 0, 1, 2, 7, 30, }, + { 11, 0, 1, 2, 7, 30, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 8, 30, }, + { 3, 0, 1, 2, 8, 26, }, + { 4, 0, 1, 2, 8, 30, }, + { 5, 0, 1, 2, 8, 30, }, + { 6, 0, 1, 2, 8, 26, }, + { 7, 0, 1, 2, 8, 30, }, + { 8, 0, 1, 2, 8, 26, }, + { 9, 0, 1, 2, 8, 25, }, + { 10, 0, 1, 2, 8, 30, }, + { 11, 0, 1, 2, 8, 30, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 9, 30, }, + { 3, 0, 1, 2, 9, 26, }, + { 4, 0, 1, 2, 9, 30, }, + { 5, 0, 1, 2, 9, 30, }, + { 6, 0, 1, 2, 9, 26, }, + { 7, 0, 1, 2, 9, 30, }, + { 8, 0, 1, 2, 9, 26, }, + { 9, 0, 1, 2, 9, 21, }, + { 10, 0, 1, 2, 9, 30, }, + { 11, 0, 1, 2, 9, 30, }, + { 0, 0, 1, 2, 10, 28, }, + { 2, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 10, 30, }, + { 3, 0, 1, 2, 10, 28, }, + { 4, 0, 1, 2, 10, 30, }, + { 5, 0, 1, 2, 10, 30, }, + { 6, 0, 1, 2, 10, 28, }, + { 7, 0, 1, 2, 10, 30, }, + { 8, 0, 1, 2, 10, 28, }, + { 9, 0, 1, 2, 10, 17, }, + { 10, 0, 1, 2, 10, 30, }, + { 11, 0, 1, 2, 10, 30, }, + { 0, 0, 1, 2, 11, 20, }, + { 2, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 11, 30, }, + { 3, 0, 1, 2, 11, 20, }, + { 4, 0, 1, 2, 11, 30, }, + { 5, 0, 1, 2, 11, 30, }, + { 6, 0, 1, 2, 11, 20, }, + { 7, 0, 1, 2, 11, 30, }, + { 8, 0, 1, 2, 11, 20, }, + { 9, 0, 1, 2, 11, 5, }, + { 10, 0, 1, 2, 11, 30, }, + { 11, 0, 1, 2, 11, 30, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 3, 0, 1, 2, 12, 63, }, + { 4, 0, 1, 2, 12, 63, }, + { 5, 0, 1, 2, 12, 63, }, + { 6, 0, 1, 2, 12, 63, }, + { 7, 0, 1, 2, 12, 63, }, + { 8, 0, 1, 2, 12, 63, }, + { 9, 0, 1, 2, 12, 63, }, + { 10, 0, 1, 2, 12, 63, }, + { 11, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 3, 0, 1, 2, 13, 63, }, + { 4, 0, 1, 2, 13, 63, }, + { 5, 0, 1, 2, 13, 63, }, + { 6, 0, 1, 2, 13, 63, }, + { 7, 0, 1, 2, 13, 63, }, + { 8, 0, 1, 2, 13, 63, }, + { 9, 0, 1, 2, 13, 63, }, + { 10, 0, 1, 2, 13, 63, }, + { 11, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 3, 0, 1, 2, 14, 63, }, + { 4, 0, 1, 2, 14, 63, }, + { 5, 0, 1, 2, 14, 63, }, + { 6, 0, 1, 2, 14, 63, }, + { 7, 0, 1, 2, 14, 63, }, + { 8, 0, 1, 2, 14, 63, }, + { 9, 0, 1, 2, 14, 63, }, + { 10, 0, 1, 2, 14, 63, }, + { 11, 0, 1, 2, 14, 63, }, + { 0, 1, 0, 1, 36, 31, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 33, }, + { 3, 1, 0, 1, 36, 31, }, + { 4, 1, 0, 1, 36, 29, }, + { 5, 1, 0, 1, 36, 32, }, + { 6, 1, 0, 1, 36, 31, }, + { 7, 1, 0, 1, 36, 27, }, + { 8, 1, 0, 1, 36, 31, }, + { 9, 1, 0, 1, 36, 29, }, + { 10, 1, 0, 1, 36, 63, }, + { 11, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 33, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 33, }, + { 3, 1, 0, 1, 40, 31, }, + { 4, 1, 0, 1, 40, 28, }, + { 5, 1, 0, 1, 40, 32, }, + { 6, 1, 0, 1, 40, 33, }, + { 7, 1, 0, 1, 40, 27, }, + { 8, 1, 0, 1, 40, 31, }, + { 9, 1, 0, 1, 40, 29, }, + { 10, 1, 0, 1, 40, 63, }, + { 11, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 33, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 33, }, + { 3, 1, 0, 1, 44, 31, }, + { 4, 1, 0, 1, 44, 28, }, + { 5, 1, 0, 1, 44, 32, }, + { 6, 1, 0, 1, 44, 33, }, + { 7, 1, 0, 1, 44, 27, }, + { 8, 1, 0, 1, 44, 31, }, + { 9, 1, 0, 1, 44, 29, }, + { 10, 1, 0, 1, 44, 63, }, + { 11, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 31, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 33, }, + { 3, 1, 0, 1, 48, 31, }, + { 4, 1, 0, 1, 48, 27, }, + { 5, 1, 0, 1, 48, 32, }, + { 6, 1, 0, 1, 48, 31, }, + { 7, 1, 0, 1, 48, 27, }, + { 8, 1, 0, 1, 48, 31, }, + { 9, 1, 0, 1, 48, 29, }, + { 10, 1, 0, 1, 48, 63, }, + { 11, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 33, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 33, }, + { 3, 1, 0, 1, 52, 32, }, + { 4, 1, 0, 1, 52, 16, }, + { 5, 1, 0, 1, 52, 32, }, + { 6, 1, 0, 1, 52, 33, }, + { 7, 1, 0, 1, 52, 27, }, + { 8, 1, 0, 1, 52, 33, }, + { 9, 1, 0, 1, 52, 29, }, + { 10, 1, 0, 1, 52, 63, }, + { 11, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 33, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 33, }, + { 3, 1, 0, 1, 56, 32, }, + { 4, 1, 0, 1, 56, 33, }, + { 5, 1, 0, 1, 56, 32, }, + { 6, 1, 0, 1, 56, 33, }, + { 7, 1, 0, 1, 56, 27, }, + { 8, 1, 0, 1, 56, 33, }, + { 9, 1, 0, 1, 56, 29, }, + { 10, 1, 0, 1, 56, 63, }, + { 11, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 33, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 33, }, + { 3, 1, 0, 1, 60, 32, }, + { 4, 1, 0, 1, 60, 33, }, + { 5, 1, 0, 1, 60, 32, }, + { 6, 1, 0, 1, 60, 33, }, + { 7, 1, 0, 1, 60, 27, }, + { 8, 1, 0, 1, 60, 33, }, + { 9, 1, 0, 1, 60, 29, }, + { 10, 1, 0, 1, 60, 63, }, + { 11, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 30, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 33, }, + { 3, 1, 0, 1, 64, 30, }, + { 4, 1, 0, 1, 64, 33, }, + { 5, 1, 0, 1, 64, 32, }, + { 6, 1, 0, 1, 64, 30, }, + { 7, 1, 0, 1, 64, 27, }, + { 8, 1, 0, 1, 64, 30, }, + { 9, 1, 0, 1, 64, 29, }, + { 10, 1, 0, 1, 64, 63, }, + { 11, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 30, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 33, }, + { 3, 1, 0, 1, 100, 30, }, + { 4, 1, 0, 1, 100, 33, }, + { 5, 1, 0, 1, 100, 32, }, + { 6, 1, 0, 1, 100, 33, }, + { 7, 1, 0, 1, 100, 27, }, + { 8, 1, 0, 1, 100, 30, }, + { 9, 1, 0, 1, 100, 63, }, + { 10, 1, 0, 1, 100, 63, }, + { 11, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 33, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 33, }, + { 3, 1, 0, 1, 104, 33, }, + { 4, 1, 0, 1, 104, 33, }, + { 5, 1, 0, 1, 104, 32, }, + { 6, 1, 0, 1, 104, 33, }, + { 7, 1, 0, 1, 104, 27, }, + { 8, 1, 0, 1, 104, 33, }, + { 9, 1, 0, 1, 104, 63, }, + { 10, 1, 0, 1, 104, 63, }, + { 11, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 33, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 33, }, + { 3, 1, 0, 1, 108, 33, }, + { 4, 1, 0, 1, 108, 33, }, + { 5, 1, 0, 1, 108, 32, }, + { 6, 1, 0, 1, 108, 33, }, + { 7, 1, 0, 1, 108, 27, }, + { 8, 1, 0, 1, 108, 33, }, + { 9, 1, 0, 1, 108, 63, }, + { 10, 1, 0, 1, 108, 63, }, + { 11, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 33, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 33, }, + { 3, 1, 0, 1, 112, 33, }, + { 4, 1, 0, 1, 112, 33, }, + { 5, 1, 0, 1, 112, 32, }, + { 6, 1, 0, 1, 112, 33, }, + { 7, 1, 0, 1, 112, 27, }, + { 8, 1, 0, 1, 112, 33, }, + { 9, 1, 0, 1, 112, 63, }, + { 10, 1, 0, 1, 112, 63, }, + { 11, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 33, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 33, }, + { 3, 1, 0, 1, 116, 33, }, + { 4, 1, 0, 1, 116, 33, }, + { 5, 1, 0, 1, 116, 32, }, + { 6, 1, 0, 1, 116, 33, }, + { 7, 1, 0, 1, 116, 27, }, + { 8, 1, 0, 1, 116, 33, }, + { 9, 1, 0, 1, 116, 63, }, + { 10, 1, 0, 1, 116, 63, }, + { 11, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 33, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 33, }, + { 3, 1, 0, 1, 120, 63, }, + { 4, 1, 0, 1, 120, 33, }, + { 5, 1, 0, 1, 120, 63, }, + { 6, 1, 0, 1, 120, 33, }, + { 7, 1, 0, 1, 120, 27, }, + { 8, 1, 0, 1, 120, 33, }, + { 9, 1, 0, 1, 120, 63, }, + { 10, 1, 0, 1, 120, 63, }, + { 11, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 33, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 33, }, + { 3, 1, 0, 1, 124, 63, }, + { 4, 1, 0, 1, 124, 33, }, + { 5, 1, 0, 1, 124, 63, }, + { 6, 1, 0, 1, 124, 33, }, + { 7, 1, 0, 1, 124, 27, }, + { 8, 1, 0, 1, 124, 33, }, + { 9, 1, 0, 1, 124, 63, }, + { 10, 1, 0, 1, 124, 63, }, + { 11, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 33, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 33, }, + { 3, 1, 0, 1, 128, 63, }, + { 4, 1, 0, 1, 128, 33, }, + { 5, 1, 0, 1, 128, 63, }, + { 6, 1, 0, 1, 128, 33, }, + { 7, 1, 0, 1, 128, 27, }, + { 8, 1, 0, 1, 128, 33, }, + { 9, 1, 0, 1, 128, 63, }, + { 10, 1, 0, 1, 128, 63, }, + { 11, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 33, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 33, }, + { 3, 1, 0, 1, 132, 33, }, + { 4, 1, 0, 1, 132, 33, }, + { 5, 1, 0, 1, 132, 32, }, + { 6, 1, 0, 1, 132, 33, }, + { 7, 1, 0, 1, 132, 27, }, + { 8, 1, 0, 1, 132, 33, }, + { 9, 1, 0, 1, 132, 63, }, + { 10, 1, 0, 1, 132, 63, }, + { 11, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 33, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 33, }, + { 3, 1, 0, 1, 136, 33, }, + { 4, 1, 0, 1, 136, 33, }, + { 5, 1, 0, 1, 136, 32, }, + { 6, 1, 0, 1, 136, 33, }, + { 7, 1, 0, 1, 136, 27, }, + { 8, 1, 0, 1, 136, 33, }, + { 9, 1, 0, 1, 136, 63, }, + { 10, 1, 0, 1, 136, 63, }, + { 11, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 31, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 33, }, + { 3, 1, 0, 1, 140, 31, }, + { 4, 1, 0, 1, 140, 33, }, + { 5, 1, 0, 1, 140, 32, }, + { 6, 1, 0, 1, 140, 33, }, + { 7, 1, 0, 1, 140, 27, }, + { 8, 1, 0, 1, 140, 31, }, + { 9, 1, 0, 1, 140, 63, }, + { 10, 1, 0, 1, 140, 63, }, + { 11, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 30, }, + { 2, 1, 0, 1, 144, 63, }, + { 1, 1, 0, 1, 144, 63, }, + { 3, 1, 0, 1, 144, 30, }, + { 4, 1, 0, 1, 144, 33, }, + { 5, 1, 0, 1, 144, 63, }, + { 6, 1, 0, 1, 144, 33, }, + { 7, 1, 0, 1, 144, 63, }, + { 8, 1, 0, 1, 144, 30, }, + { 9, 1, 0, 1, 144, 63, }, + { 10, 1, 0, 1, 144, 63, }, + { 11, 1, 0, 1, 144, 32, }, + { 0, 1, 0, 1, 149, 33, }, + { 2, 1, 0, 1, 149, 14, }, + { 1, 1, 0, 1, 149, 63, }, + { 3, 1, 0, 1, 149, 30, }, + { 4, 1, 0, 1, 149, 33, }, + { 5, 1, 0, 1, 149, 33, }, + { 6, 1, 0, 1, 149, 33, }, + { 7, 1, 0, 1, 149, 27, }, + { 8, 1, 0, 1, 149, 33, }, + { 9, 1, 0, 1, 149, 30, }, + { 10, 1, 0, 1, 149, 14, }, + { 11, 1, 0, 1, 149, 31, }, + { 0, 1, 0, 1, 153, 33, }, + { 2, 1, 0, 1, 153, 14, }, + { 1, 1, 0, 1, 153, 63, }, + { 3, 1, 0, 1, 153, 33, }, + { 4, 1, 0, 1, 153, 33, }, + { 5, 1, 0, 1, 153, 33, }, + { 6, 1, 0, 1, 153, 33, }, + { 7, 1, 0, 1, 153, 27, }, + { 8, 1, 0, 1, 153, 33, }, + { 9, 1, 0, 1, 153, 30, }, + { 10, 1, 0, 1, 153, 14, }, + { 11, 1, 0, 1, 153, 31, }, + { 0, 1, 0, 1, 157, 33, }, + { 2, 1, 0, 1, 157, 14, }, + { 1, 1, 0, 1, 157, 63, }, + { 3, 1, 0, 1, 157, 33, }, + { 4, 1, 0, 1, 157, 33, }, + { 5, 1, 0, 1, 157, 33, }, + { 6, 1, 0, 1, 157, 33, }, + { 7, 1, 0, 1, 157, 27, }, + { 8, 1, 0, 1, 157, 33, }, + { 9, 1, 0, 1, 157, 30, }, + { 10, 1, 0, 1, 157, 14, }, + { 11, 1, 0, 1, 157, 31, }, + { 0, 1, 0, 1, 161, 33, }, + { 2, 1, 0, 1, 161, 14, }, + { 1, 1, 0, 1, 161, 63, }, + { 3, 1, 0, 1, 161, 33, }, + { 4, 1, 0, 1, 161, 31, }, + { 5, 1, 0, 1, 161, 33, }, + { 6, 1, 0, 1, 161, 33, }, + { 7, 1, 0, 1, 161, 27, }, + { 8, 1, 0, 1, 161, 33, }, + { 9, 1, 0, 1, 161, 30, }, + { 10, 1, 0, 1, 161, 14, }, + { 11, 1, 0, 1, 161, 31, }, + { 0, 1, 0, 1, 165, 33, }, + { 2, 1, 0, 1, 165, 14, }, + { 1, 1, 0, 1, 165, 63, }, + { 3, 1, 0, 1, 165, 33, }, + { 4, 1, 0, 1, 165, 33, }, + { 5, 1, 0, 1, 165, 33, }, + { 6, 1, 0, 1, 165, 33, }, + { 7, 1, 0, 1, 165, 27, }, + { 8, 1, 0, 1, 165, 30, }, + { 9, 1, 0, 1, 165, 30, }, + { 10, 1, 0, 1, 165, 14, }, + { 11, 1, 0, 1, 165, 31, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 33, }, + { 3, 1, 0, 2, 36, 30, }, + { 4, 1, 0, 2, 36, 27, }, + { 5, 1, 0, 2, 36, 32, }, + { 6, 1, 0, 2, 36, 30, }, + { 7, 1, 0, 2, 36, 27, }, + { 8, 1, 0, 2, 36, 30, }, + { 9, 1, 0, 2, 36, 29, }, + { 10, 1, 0, 2, 36, 63, }, + { 11, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 33, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 33, }, + { 3, 1, 0, 2, 40, 31, }, + { 4, 1, 0, 2, 40, 29, }, + { 5, 1, 0, 2, 40, 32, }, + { 6, 1, 0, 2, 40, 33, }, + { 7, 1, 0, 2, 40, 27, }, + { 8, 1, 0, 2, 40, 31, }, + { 9, 1, 0, 2, 40, 29, }, + { 10, 1, 0, 2, 40, 63, }, + { 11, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 33, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 33, }, + { 3, 1, 0, 2, 44, 31, }, + { 4, 1, 0, 2, 44, 29, }, + { 5, 1, 0, 2, 44, 32, }, + { 6, 1, 0, 2, 44, 33, }, + { 7, 1, 0, 2, 44, 27, }, + { 8, 1, 0, 2, 44, 31, }, + { 9, 1, 0, 2, 44, 29, }, + { 10, 1, 0, 2, 44, 63, }, + { 11, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 33, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 33, }, + { 3, 1, 0, 2, 48, 31, }, + { 4, 1, 0, 2, 48, 26, }, + { 5, 1, 0, 2, 48, 32, }, + { 6, 1, 0, 2, 48, 33, }, + { 7, 1, 0, 2, 48, 27, }, + { 8, 1, 0, 2, 48, 31, }, + { 9, 1, 0, 2, 48, 29, }, + { 10, 1, 0, 2, 48, 63, }, + { 11, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 33, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 33, }, + { 3, 1, 0, 2, 52, 32, }, + { 4, 1, 0, 2, 52, 7, }, + { 5, 1, 0, 2, 52, 32, }, + { 6, 1, 0, 2, 52, 33, }, + { 7, 1, 0, 2, 52, 27, }, + { 8, 1, 0, 2, 52, 33, }, + { 9, 1, 0, 2, 52, 29, }, + { 10, 1, 0, 2, 52, 63, }, + { 11, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 33, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 33, }, + { 3, 1, 0, 2, 56, 32, }, + { 4, 1, 0, 2, 56, 33, }, + { 5, 1, 0, 2, 56, 32, }, + { 6, 1, 0, 2, 56, 33, }, + { 7, 1, 0, 2, 56, 27, }, + { 8, 1, 0, 2, 56, 33, }, + { 9, 1, 0, 2, 56, 29, }, + { 10, 1, 0, 2, 56, 63, }, + { 11, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 33, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 33, }, + { 3, 1, 0, 2, 60, 32, }, + { 4, 1, 0, 2, 60, 33, }, + { 5, 1, 0, 2, 60, 32, }, + { 6, 1, 0, 2, 60, 33, }, + { 7, 1, 0, 2, 60, 27, }, + { 8, 1, 0, 2, 60, 33, }, + { 9, 1, 0, 2, 60, 29, }, + { 10, 1, 0, 2, 60, 63, }, + { 11, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 30, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 33, }, + { 3, 1, 0, 2, 64, 30, }, + { 4, 1, 0, 2, 64, 33, }, + { 5, 1, 0, 2, 64, 32, }, + { 6, 1, 0, 2, 64, 30, }, + { 7, 1, 0, 2, 64, 27, }, + { 8, 1, 0, 2, 64, 30, }, + { 9, 1, 0, 2, 64, 29, }, + { 10, 1, 0, 2, 64, 63, }, + { 11, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 30, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 33, }, + { 3, 1, 0, 2, 100, 30, }, + { 4, 1, 0, 2, 100, 33, }, + { 5, 1, 0, 2, 100, 32, }, + { 6, 1, 0, 2, 100, 33, }, + { 7, 1, 0, 2, 100, 27, }, + { 8, 1, 0, 2, 100, 30, }, + { 9, 1, 0, 2, 100, 63, }, + { 10, 1, 0, 2, 100, 63, }, + { 11, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 33, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 33, }, + { 3, 1, 0, 2, 104, 33, }, + { 4, 1, 0, 2, 104, 33, }, + { 5, 1, 0, 2, 104, 32, }, + { 6, 1, 0, 2, 104, 33, }, + { 7, 1, 0, 2, 104, 27, }, + { 8, 1, 0, 2, 104, 33, }, + { 9, 1, 0, 2, 104, 63, }, + { 10, 1, 0, 2, 104, 63, }, + { 11, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 33, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 33, }, + { 3, 1, 0, 2, 108, 33, }, + { 4, 1, 0, 2, 108, 33, }, + { 5, 1, 0, 2, 108, 32, }, + { 6, 1, 0, 2, 108, 33, }, + { 7, 1, 0, 2, 108, 27, }, + { 8, 1, 0, 2, 108, 33, }, + { 9, 1, 0, 2, 108, 63, }, + { 10, 1, 0, 2, 108, 63, }, + { 11, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 33, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 33, }, + { 3, 1, 0, 2, 112, 33, }, + { 4, 1, 0, 2, 112, 33, }, + { 5, 1, 0, 2, 112, 32, }, + { 6, 1, 0, 2, 112, 33, }, + { 7, 1, 0, 2, 112, 27, }, + { 8, 1, 0, 2, 112, 33, }, + { 9, 1, 0, 2, 112, 63, }, + { 10, 1, 0, 2, 112, 63, }, + { 11, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 33, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 33, }, + { 3, 1, 0, 2, 116, 33, }, + { 4, 1, 0, 2, 116, 33, }, + { 5, 1, 0, 2, 116, 32, }, + { 6, 1, 0, 2, 116, 33, }, + { 7, 1, 0, 2, 116, 27, }, + { 8, 1, 0, 2, 116, 33, }, + { 9, 1, 0, 2, 116, 63, }, + { 10, 1, 0, 2, 116, 63, }, + { 11, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 33, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 33, }, + { 3, 1, 0, 2, 120, 63, }, + { 4, 1, 0, 2, 120, 33, }, + { 5, 1, 0, 2, 120, 63, }, + { 6, 1, 0, 2, 120, 33, }, + { 7, 1, 0, 2, 120, 27, }, + { 8, 1, 0, 2, 120, 33, }, + { 9, 1, 0, 2, 120, 63, }, + { 10, 1, 0, 2, 120, 63, }, + { 11, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 33, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 33, }, + { 3, 1, 0, 2, 124, 63, }, + { 4, 1, 0, 2, 124, 33, }, + { 5, 1, 0, 2, 124, 63, }, + { 6, 1, 0, 2, 124, 33, }, + { 7, 1, 0, 2, 124, 27, }, + { 8, 1, 0, 2, 124, 33, }, + { 9, 1, 0, 2, 124, 63, }, + { 10, 1, 0, 2, 124, 63, }, + { 11, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 33, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 33, }, + { 3, 1, 0, 2, 128, 63, }, + { 4, 1, 0, 2, 128, 33, }, + { 5, 1, 0, 2, 128, 63, }, + { 6, 1, 0, 2, 128, 33, }, + { 7, 1, 0, 2, 128, 27, }, + { 8, 1, 0, 2, 128, 33, }, + { 9, 1, 0, 2, 128, 63, }, + { 10, 1, 0, 2, 128, 63, }, + { 11, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 33, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 33, }, + { 3, 1, 0, 2, 132, 33, }, + { 4, 1, 0, 2, 132, 33, }, + { 5, 1, 0, 2, 132, 32, }, + { 6, 1, 0, 2, 132, 33, }, + { 7, 1, 0, 2, 132, 27, }, + { 8, 1, 0, 2, 132, 33, }, + { 9, 1, 0, 2, 132, 63, }, + { 10, 1, 0, 2, 132, 63, }, + { 11, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 33, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 33, }, + { 3, 1, 0, 2, 136, 33, }, + { 4, 1, 0, 2, 136, 33, }, + { 5, 1, 0, 2, 136, 32, }, + { 6, 1, 0, 2, 136, 33, }, + { 7, 1, 0, 2, 136, 27, }, + { 8, 1, 0, 2, 136, 33, }, + { 9, 1, 0, 2, 136, 63, }, + { 10, 1, 0, 2, 136, 63, }, + { 11, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 29, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 33, }, + { 3, 1, 0, 2, 140, 29, }, + { 4, 1, 0, 2, 140, 33, }, + { 5, 1, 0, 2, 140, 32, }, + { 6, 1, 0, 2, 140, 33, }, + { 7, 1, 0, 2, 140, 27, }, + { 8, 1, 0, 2, 140, 29, }, + { 9, 1, 0, 2, 140, 63, }, + { 10, 1, 0, 2, 140, 63, }, + { 11, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 27, }, + { 2, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 3, 1, 0, 2, 144, 27, }, + { 4, 1, 0, 2, 144, 33, }, + { 5, 1, 0, 2, 144, 63, }, + { 6, 1, 0, 2, 144, 33, }, + { 7, 1, 0, 2, 144, 63, }, + { 8, 1, 0, 2, 144, 27, }, + { 9, 1, 0, 2, 144, 63, }, + { 10, 1, 0, 2, 144, 63, }, + { 11, 1, 0, 2, 144, 31, }, + { 0, 1, 0, 2, 149, 33, }, + { 2, 1, 0, 2, 149, 14, }, + { 1, 1, 0, 2, 149, 63, }, + { 3, 1, 0, 2, 149, 33, }, + { 4, 1, 0, 2, 149, 33, }, + { 5, 1, 0, 2, 149, 33, }, + { 6, 1, 0, 2, 149, 33, }, + { 7, 1, 0, 2, 149, 27, }, + { 8, 1, 0, 2, 149, 33, }, + { 9, 1, 0, 2, 149, 31, }, + { 10, 1, 0, 2, 149, 14, }, + { 11, 1, 0, 2, 149, 31, }, + { 0, 1, 0, 2, 153, 33, }, + { 2, 1, 0, 2, 153, 14, }, + { 1, 1, 0, 2, 153, 63, }, + { 3, 1, 0, 2, 153, 33, }, + { 4, 1, 0, 2, 153, 33, }, + { 5, 1, 0, 2, 153, 33, }, + { 6, 1, 0, 2, 153, 33, }, + { 7, 1, 0, 2, 153, 27, }, + { 8, 1, 0, 2, 153, 33, }, + { 9, 1, 0, 2, 153, 31, }, + { 10, 1, 0, 2, 153, 14, }, + { 11, 1, 0, 2, 153, 31, }, + { 0, 1, 0, 2, 157, 33, }, + { 2, 1, 0, 2, 157, 14, }, + { 1, 1, 0, 2, 157, 63, }, + { 3, 1, 0, 2, 157, 33, }, + { 4, 1, 0, 2, 157, 33, }, + { 5, 1, 0, 2, 157, 33, }, + { 6, 1, 0, 2, 157, 33, }, + { 7, 1, 0, 2, 157, 27, }, + { 8, 1, 0, 2, 157, 33, }, + { 9, 1, 0, 2, 157, 31, }, + { 10, 1, 0, 2, 157, 14, }, + { 11, 1, 0, 2, 157, 31, }, + { 0, 1, 0, 2, 161, 33, }, + { 2, 1, 0, 2, 161, 14, }, + { 1, 1, 0, 2, 161, 63, }, + { 3, 1, 0, 2, 161, 33, }, + { 4, 1, 0, 2, 161, 31, }, + { 5, 1, 0, 2, 161, 33, }, + { 6, 1, 0, 2, 161, 33, }, + { 7, 1, 0, 2, 161, 27, }, + { 8, 1, 0, 2, 161, 33, }, + { 9, 1, 0, 2, 161, 31, }, + { 10, 1, 0, 2, 161, 14, }, + { 11, 1, 0, 2, 161, 31, }, + { 0, 1, 0, 2, 165, 33, }, + { 2, 1, 0, 2, 165, 14, }, + { 1, 1, 0, 2, 165, 63, }, + { 3, 1, 0, 2, 165, 33, }, + { 4, 1, 0, 2, 165, 33, }, + { 5, 1, 0, 2, 165, 33, }, + { 6, 1, 0, 2, 165, 33, }, + { 7, 1, 0, 2, 165, 27, }, + { 8, 1, 0, 2, 165, 30, }, + { 9, 1, 0, 2, 165, 31, }, + { 10, 1, 0, 2, 165, 14, }, + { 11, 1, 0, 2, 165, 31, }, + { 0, 1, 1, 2, 38, 22, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 3, 1, 1, 2, 38, 22, }, + { 4, 1, 1, 2, 38, 26, }, + { 5, 1, 1, 2, 38, 32, }, + { 6, 1, 1, 2, 38, 22, }, + { 7, 1, 1, 2, 38, 27, }, + { 8, 1, 1, 2, 38, 22, }, + { 9, 1, 1, 2, 38, 29, }, + { 10, 1, 1, 2, 38, 63, }, + { 11, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 3, 1, 1, 2, 46, 32, }, + { 4, 1, 1, 2, 46, 28, }, + { 5, 1, 1, 2, 46, 32, }, + { 6, 1, 1, 2, 46, 32, }, + { 7, 1, 1, 2, 46, 27, }, + { 8, 1, 1, 2, 46, 31, }, + { 9, 1, 1, 2, 46, 29, }, + { 10, 1, 1, 2, 46, 63, }, + { 11, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 3, 1, 1, 2, 54, 32, }, + { 4, 1, 1, 2, 54, 22, }, + { 5, 1, 1, 2, 54, 32, }, + { 6, 1, 1, 2, 54, 32, }, + { 7, 1, 1, 2, 54, 27, }, + { 8, 1, 1, 2, 54, 32, }, + { 9, 1, 1, 2, 54, 28, }, + { 10, 1, 1, 2, 54, 63, }, + { 11, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 23, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 3, 1, 1, 2, 62, 23, }, + { 4, 1, 1, 2, 62, 31, }, + { 5, 1, 1, 2, 62, 32, }, + { 6, 1, 1, 2, 62, 23, }, + { 7, 1, 1, 2, 62, 27, }, + { 8, 1, 1, 2, 62, 23, }, + { 9, 1, 1, 2, 62, 28, }, + { 10, 1, 1, 2, 62, 63, }, + { 11, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 21, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 3, 1, 1, 2, 102, 21, }, + { 4, 1, 1, 2, 102, 31, }, + { 5, 1, 1, 2, 102, 32, }, + { 6, 1, 1, 2, 102, 32, }, + { 7, 1, 1, 2, 102, 27, }, + { 8, 1, 1, 2, 102, 21, }, + { 9, 1, 1, 2, 102, 63, }, + { 10, 1, 1, 2, 102, 63, }, + { 11, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 3, 1, 1, 2, 110, 32, }, + { 4, 1, 1, 2, 110, 32, }, + { 5, 1, 1, 2, 110, 32, }, + { 6, 1, 1, 2, 110, 32, }, + { 7, 1, 1, 2, 110, 27, }, + { 8, 1, 1, 2, 110, 32, }, + { 9, 1, 1, 2, 110, 63, }, + { 10, 1, 1, 2, 110, 63, }, + { 11, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 3, 1, 1, 2, 118, 63, }, + { 4, 1, 1, 2, 118, 32, }, + { 5, 1, 1, 2, 118, 63, }, + { 6, 1, 1, 2, 118, 32, }, + { 7, 1, 1, 2, 118, 27, }, + { 8, 1, 1, 2, 118, 32, }, + { 9, 1, 1, 2, 118, 63, }, + { 10, 1, 1, 2, 118, 63, }, + { 11, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 3, 1, 1, 2, 126, 63, }, + { 4, 1, 1, 2, 126, 32, }, + { 5, 1, 1, 2, 126, 63, }, + { 6, 1, 1, 2, 126, 32, }, + { 7, 1, 1, 2, 126, 27, }, + { 8, 1, 1, 2, 126, 32, }, + { 9, 1, 1, 2, 126, 63, }, + { 10, 1, 1, 2, 126, 63, }, + { 11, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 3, 1, 1, 2, 134, 32, }, + { 4, 1, 1, 2, 134, 32, }, + { 5, 1, 1, 2, 134, 32, }, + { 6, 1, 1, 2, 134, 32, }, + { 7, 1, 1, 2, 134, 27, }, + { 8, 1, 1, 2, 134, 32, }, + { 9, 1, 1, 2, 134, 63, }, + { 10, 1, 1, 2, 134, 63, }, + { 11, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 142, 29, }, + { 2, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 3, 1, 1, 2, 142, 29, }, + { 4, 1, 1, 2, 142, 32, }, + { 5, 1, 1, 2, 142, 63, }, + { 6, 1, 1, 2, 142, 32, }, + { 7, 1, 1, 2, 142, 63, }, + { 8, 1, 1, 2, 142, 29, }, + { 9, 1, 1, 2, 142, 63, }, + { 10, 1, 1, 2, 142, 63, }, + { 11, 1, 1, 2, 142, 31, }, + { 0, 1, 1, 2, 151, 32, }, + { 2, 1, 1, 2, 151, 14, }, + { 1, 1, 1, 2, 151, 63, }, + { 3, 1, 1, 2, 151, 32, }, + { 4, 1, 1, 2, 151, 27, }, + { 5, 1, 1, 2, 151, 32, }, + { 6, 1, 1, 2, 151, 32, }, + { 7, 1, 1, 2, 151, 27, }, + { 8, 1, 1, 2, 151, 32, }, + { 9, 1, 1, 2, 151, 27, }, + { 10, 1, 1, 2, 151, 14, }, + { 11, 1, 1, 2, 151, 30, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 14, }, + { 1, 1, 1, 2, 159, 63, }, + { 3, 1, 1, 2, 159, 32, }, + { 4, 1, 1, 2, 159, 26, }, + { 5, 1, 1, 2, 159, 32, }, + { 6, 1, 1, 2, 159, 32, }, + { 7, 1, 1, 2, 159, 27, }, + { 8, 1, 1, 2, 159, 32, }, + { 9, 1, 1, 2, 159, 31, }, + { 10, 1, 1, 2, 159, 14, }, + { 11, 1, 1, 2, 159, 30, }, + { 0, 1, 2, 4, 42, 19, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 28, }, + { 3, 1, 2, 4, 42, 19, }, + { 4, 1, 2, 4, 42, 25, }, + { 5, 1, 2, 4, 42, 32, }, + { 6, 1, 2, 4, 42, 19, }, + { 7, 1, 2, 4, 42, 27, }, + { 8, 1, 2, 4, 42, 19, }, + { 9, 1, 2, 4, 42, 25, }, + { 10, 1, 2, 4, 42, 63, }, + { 11, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 22, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 28, }, + { 3, 1, 2, 4, 58, 22, }, + { 4, 1, 2, 4, 58, 28, }, + { 5, 1, 2, 4, 58, 32, }, + { 6, 1, 2, 4, 58, 22, }, + { 7, 1, 2, 4, 58, 27, }, + { 8, 1, 2, 4, 58, 22, }, + { 9, 1, 2, 4, 58, 23, }, + { 10, 1, 2, 4, 58, 63, }, + { 11, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 18, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 3, 1, 2, 4, 106, 18, }, + { 4, 1, 2, 4, 106, 30, }, + { 5, 1, 2, 4, 106, 32, }, + { 6, 1, 2, 4, 106, 32, }, + { 7, 1, 2, 4, 106, 27, }, + { 8, 1, 2, 4, 106, 18, }, + { 9, 1, 2, 4, 106, 63, }, + { 10, 1, 2, 4, 106, 63, }, + { 11, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 32, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 3, 1, 2, 4, 122, 63, }, + { 4, 1, 2, 4, 122, 26, }, + { 5, 1, 2, 4, 122, 63, }, + { 6, 1, 2, 4, 122, 32, }, + { 7, 1, 2, 4, 122, 27, }, + { 8, 1, 2, 4, 122, 32, }, + { 9, 1, 2, 4, 122, 63, }, + { 10, 1, 2, 4, 122, 63, }, + { 11, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 138, 28, }, + { 2, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 138, 63, }, + { 3, 1, 2, 4, 138, 28, }, + { 4, 1, 2, 4, 138, 32, }, + { 5, 1, 2, 4, 138, 63, }, + { 6, 1, 2, 4, 138, 32, }, + { 7, 1, 2, 4, 138, 63, }, + { 8, 1, 2, 4, 138, 28, }, + { 9, 1, 2, 4, 138, 63, }, + { 10, 1, 2, 4, 138, 63, }, + { 11, 1, 2, 4, 138, 30, }, + { 0, 1, 2, 4, 155, 32, }, + { 2, 1, 2, 4, 155, 14, }, + { 1, 1, 2, 4, 155, 63, }, + { 3, 1, 2, 4, 155, 32, }, + { 4, 1, 2, 4, 155, 27, }, + { 5, 1, 2, 4, 155, 32, }, + { 6, 1, 2, 4, 155, 32, }, + { 7, 1, 2, 4, 155, 27, }, + { 8, 1, 2, 4, 155, 32, }, + { 9, 1, 2, 4, 155, 20, }, + { 10, 1, 2, 4, 155, 14, }, + { 11, 1, 2, 4, 155, 30, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8821c_txpwr_lmt_type0); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h new file mode 100644 index 000000000..cda98f5c4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8821C_TABLE_H__ +#define __RTW8821C_TABLE_H__ + +extern const struct rtw_table rtw8821c_mac_tbl; +extern const struct rtw_table rtw8821c_agc_tbl; +extern const struct rtw_table rtw8821c_agc_btg_type2_tbl; +extern const struct rtw_table rtw8821c_bb_tbl; +extern const struct rtw_table rtw8821c_bb_pg_type0_tbl; +extern const struct rtw_table rtw8821c_rf_a_tbl; +extern const struct rtw_table rtw8821c_txpwr_lmt_type0_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.c b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c new file mode 100644 index 000000000..52a19cb17 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8821c.h" + +static const struct pci_device_id rtw_8821ce_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB821), + .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC821), + .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8821ce_id_table); + +static struct pci_driver rtw_8821ce_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8821ce_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, +}; +module_pci_driver(rtw_8821ce_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821ce driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cs.c b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c new file mode 100644 index 000000000..58e0ef219 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl + */ + +#include +#include +#include +#include "main.h" +#include "rtw8821c.h" +#include "sdio.h" + +static const struct sdio_device_id rtw_8821cs_id_table[] = { + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8821CS), + .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec, + }, + {} +}; +MODULE_DEVICE_TABLE(sdio, rtw_8821cs_id_table); + +static struct sdio_driver rtw_8821cs_driver = { + .name = KBUILD_MODNAME, + .probe = rtw_sdio_probe, + .remove = rtw_sdio_remove, + .shutdown = rtw_sdio_shutdown, + .id_table = rtw_8821cs_id_table, + .drv = { + .pm = &rtw_sdio_pm_ops, + } +}; +module_sdio_driver(rtw_8821cs_driver); + +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c new file mode 100644 index 000000000..8cd09d666 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8821c.h" +#include "usb.h" + +static const struct usb_device_id rtw_8821cu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8731, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc80c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0105, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Mercusys */ + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); + +static int rtw_8821cu_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtw_usb_probe(intf, id); +} + +static struct usb_driver rtw_8821cu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8821cu_id_table, + .probe = rtw_8821cu_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8821cu_driver); + +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c new file mode 100644 index 000000000..a56c8befa --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -0,0 +1,2621 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8822b.h" +#include "rtw8822b_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" +#include "bf.h" +#include "regd.h" + +static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path); + +static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822b_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static void rtw8822bu_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822b_efuse *map) +{ + ether_addr_copy(efuse->addr, map->u.mac_addr); +} + +static void rtw8822bs_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822b_efuse *map) +{ + ether_addr_copy(efuse->addr, map->s.mac_addr); +} + +static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8822b_efuse *map; + int i; + + map = (struct rtw8822b_efuse *)log_map; + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->pa_type_2g = map->pa_type; + efuse->pa_type_5g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g[0]; + efuse->lna_type_5g = map->lna_type_5g[0]; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8822be_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_USB: + rtw8822bu_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_SDIO: + rtw8822bs_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -ENOTSUPP; + } + + return 0; +} + +static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev) +{ + /* chip top mux */ + rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3); + rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1); + + /* from s0 or s1 */ + rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30); + rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3); + + /* input or output */ + rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f); + rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3); +} + +#define RTW_TXSCALE_SIZE 37 +static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev) +{ + u8 i = 0; + u32 swing, table_value; + + swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000); + for (i = 0; i < RTW_TXSCALE_SIZE; i++) { + table_value = rtw8822b_txscale_tbl[i]; + if (swing == table_value) + break; + } + + return i; +} + +static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_idx = rtw8822b_get_swing_index(rtwdev); + u8 path; + + if (swing_idx >= RTW_TXSCALE_SIZE) + dm_info->default_ofdm_index = 24; + else + dm_info->default_ofdm_index = swing_idx; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev) +{ + rtw_bf_phy_init(rtwdev); + /* Grouping bitmap parameters */ + rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); +} + +static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 crystal_cap; + bool is_tx2_path; + + /* power on BB/RF domain */ + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN); + + /* pre init before header files config */ + rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + rtw_phy_load_tables(rtwdev); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, 0x24, 0x7e000000, crystal_cap); + rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap); + + /* post init after header files config */ + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + is_tx2_path = false; + rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx, + is_tx2_path); + rtw_phy_init(rtwdev); + + rtw8822b_phy_rfe_init(rtwdev); + rtw8822b_pwrtrack_init(rtwdev); + + rtw8822b_phy_bf_init(rtwdev); +} + +#define WLAN_SLOT_TIME 0x09 +#define WLAN_PIFS_TIME 0x19 +#define WLAN_SIFS_CCK_CONT_TX 0xA +#define WLAN_SIFS_OFDM_CONT_TX 0xE +#define WLAN_SIFS_CCK_TRX 0x10 +#define WLAN_SIFS_OFDM_TRX 0x10 +#define WLAN_VO_TXOP_LIMIT 0x186 /* unit : 32us */ +#define WLAN_VI_TXOP_LIMIT 0x3BC /* unit : 32us */ +#define WLAN_RDG_NAV 0x05 +#define WLAN_TXOP_NAV 0x1B +#define WLAN_CCK_RX_TSF 0x30 +#define WLAN_OFDM_RX_TSF 0x30 +#define WLAN_TBTT_PROHIBIT 0x04 /* unit : 32us */ +#define WLAN_TBTT_HOLD_TIME 0x064 /* unit : 32us */ +#define WLAN_DRV_EARLY_INT 0x04 +#define WLAN_BCN_DMA_TIME 0x02 + +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0x0FFF +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0xE400220E +#define WLAN_RXPKT_MAX_SZ 12288 +#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) + +#define WLAN_AMPDU_MAX_TIME 0x70 +#define WLAN_RTS_LEN_TH 0xFF +#define WLAN_RTS_TX_TIME_TH 0x08 +#define WLAN_MAX_AGG_PKT_LIMIT 0x20 +#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20 +#define FAST_EDCA_VO_TH 0x06 +#define FAST_EDCA_VI_TH 0x06 +#define FAST_EDCA_BE_TH 0x06 +#define FAST_EDCA_BK_TH 0x06 +#define WLAN_BAR_RETRY_LIMIT 0x01 +#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 + +#define WLAN_TX_FUNC_CFG1 0x30 +#define WLAN_TX_FUNC_CFG2 0x30 +#define WLAN_MAC_OPT_NORM_FUNC1 0x98 +#define WLAN_MAC_OPT_LB_FUNC1 0x80 +#define WLAN_MAC_OPT_FUNC2 0xb0810041 + +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) + +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) + +static int rtw8822b_mac_init(struct rtw_dev *rtwdev) +{ + u32 value32; + + /* protocol configuration */ + rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, BIT_PRE_TX_CMD); + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); + rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); + value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | + (WLAN_MAX_AGG_PKT_LIMIT << 16) | + (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); + rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); + rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, + WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); + /* EDCA configuration */ + rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); + rtw_write16(rtwdev, REG_TXPAUSE, 0x0000); + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); + rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); + rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT); + rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT); + rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); + rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); + /* Set beacon cotnrol - enable TSF and other related functions */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + /* Set send beacon related registers */ + rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); + /* WMAC configuration */ + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); + rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); + rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, + BIT_DIS_CHK_VHTSIGB_CRC); + + return 0; +} + +static void rtw8822b_set_channel_rfe_efem(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + + if (IS_CH_2G_BAND(channel)) { + rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x705770); + rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57); + rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(4), 0); + } else { + rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x177517); + rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75); + rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(5), 0); + } + + rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0); + + if (hal->antenna_rx == BB_PATH_AB || + hal->antenna_tx == BB_PATH_AB) { + /* 2TX or 2RX */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501); + } else if (hal->antenna_rx == hal->antenna_tx) { + /* TXA+RXA or TXB+RXB */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005); + } +} + +static void rtw8822b_set_channel_rfe_ifem(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + + if (IS_CH_2G_BAND(channel)) { + /* signal source */ + rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x745774); + rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57); + } else { + /* signal source */ + rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x477547); + rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75); + } + + rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0); + + if (IS_CH_2G_BAND(channel)) { + if (hal->antenna_rx == BB_PATH_AB || + hal->antenna_tx == BB_PATH_AB) { + /* 2TX or 2RX */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501); + } else if (hal->antenna_rx == hal->antenna_tx) { + /* TXA+RXA or TXB+RXB */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005); + } + } else { + rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa5a5); + } +} + +enum { + CCUT_IDX_1R_2G, + CCUT_IDX_2R_2G, + CCUT_IDX_1R_5G, + CCUT_IDX_2R_5G, + CCUT_IDX_NR, +}; + +struct cca_ccut { + u32 reg82c[CCUT_IDX_NR]; + u32 reg830[CCUT_IDX_NR]; + u32 reg838[CCUT_IDX_NR]; +}; + +static const struct cca_ccut cca_ifem_ccut = { + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x79a0eaaa, 0x79A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/ + {0x87765541, 0x87746341, 0x87765541, 0x87746341}, /*Reg838*/ +}; + +static const struct cca_ccut cca_efem_ccut = { + {0x75B86010, 0x75B76010, 0x75B86010, 0x75B76010}, /*Reg82C*/ + {0x79A0EAA8, 0x79A0EAAC, 0x79A0EAA8, 0x79a0eaaa}, /*Reg830*/ + {0x87766451, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/ +}; + +static const struct cca_ccut cca_ifem_ccut_ext = { + {0x75da8010, 0x75da8010, 0x75da8010, 0x75da8010}, /*Reg82C*/ + {0x79a0eaaa, 0x97A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/ + {0x87765541, 0x86666341, 0x87765561, 0x86666361}, /*Reg838*/ +}; + +static void rtw8822b_get_cca_val(const struct cca_ccut *cca_ccut, u8 col, + u32 *reg82c, u32 *reg830, u32 *reg838) +{ + *reg82c = cca_ccut->reg82c[col]; + *reg830 = cca_ccut->reg830[col]; + *reg838 = cca_ccut->reg838[col]; +} + +struct rtw8822b_rfe_info { + const struct cca_ccut *cca_ccut_2g; + const struct cca_ccut *cca_ccut_5g; + enum rtw_rfe_fem fem; + bool ifem_ext; + void (*rtw_set_channel_rfe)(struct rtw_dev *rtwdev, u8 channel); +}; + +#define I2GE5G_CCUT(set_ch) { \ + .cca_ccut_2g = &cca_ifem_ccut, \ + .cca_ccut_5g = &cca_efem_ccut, \ + .fem = RTW_RFE_IFEM2G_EFEM5G, \ + .ifem_ext = false, \ + .rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch, \ + } +#define IFEM_EXT_CCUT(set_ch) { \ + .cca_ccut_2g = &cca_ifem_ccut_ext, \ + .cca_ccut_5g = &cca_ifem_ccut_ext, \ + .fem = RTW_RFE_IFEM, \ + .ifem_ext = true, \ + .rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch, \ + } + +static const struct rtw8822b_rfe_info rtw8822b_rfe_info[] = { + [2] = I2GE5G_CCUT(efem), + [3] = IFEM_EXT_CCUT(ifem), + [5] = IFEM_EXT_CCUT(ifem), +}; + +static void rtw8822b_set_channel_cca(struct rtw_dev *rtwdev, u8 channel, u8 bw, + const struct rtw8822b_rfe_info *rfe_info) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + const struct cca_ccut *cca_ccut; + u8 col; + u32 reg82c, reg830, reg838; + bool is_efem_cca = false, is_ifem_cca = false, is_rfe_type = false; + + if (IS_CH_2G_BAND(channel)) { + cca_ccut = rfe_info->cca_ccut_2g; + + if (hal->antenna_rx == BB_PATH_A || + hal->antenna_rx == BB_PATH_B) + col = CCUT_IDX_1R_2G; + else + col = CCUT_IDX_2R_2G; + } else { + cca_ccut = rfe_info->cca_ccut_5g; + + if (hal->antenna_rx == BB_PATH_A || + hal->antenna_rx == BB_PATH_B) + col = CCUT_IDX_1R_5G; + else + col = CCUT_IDX_2R_5G; + } + + rtw8822b_get_cca_val(cca_ccut, col, ®82c, ®830, ®838); + + switch (rfe_info->fem) { + case RTW_RFE_IFEM: + default: + is_ifem_cca = true; + if (rfe_info->ifem_ext) + is_rfe_type = true; + break; + case RTW_RFE_EFEM: + is_efem_cca = true; + break; + case RTW_RFE_IFEM2G_EFEM5G: + if (IS_CH_2G_BAND(channel)) + is_ifem_cca = true; + else + is_efem_cca = true; + break; + } + + if (is_ifem_cca) { + if ((hal->cut_version == RTW_CHIP_VER_CUT_B && + (col == CCUT_IDX_2R_2G || col == CCUT_IDX_2R_5G) && + bw == RTW_CHANNEL_WIDTH_40) || + (!is_rfe_type && col == CCUT_IDX_2R_5G && + bw == RTW_CHANNEL_WIDTH_40) || + (efuse->rfe_option == 5 && col == CCUT_IDX_2R_5G)) + reg830 = 0x79a0ea28; + } + + rtw_write32_mask(rtwdev, REG_CCASEL, MASKDWORD, reg82c); + rtw_write32_mask(rtwdev, REG_PDMFTH, MASKDWORD, reg830); + rtw_write32_mask(rtwdev, REG_CCA2ND, MASKDWORD, reg838); + + if (is_efem_cca && !(hal->cut_version == RTW_CHIP_VER_CUT_B)) + rtw_write32_mask(rtwdev, REG_L1WT, MASKDWORD, 0x9194b2b9); + + if (bw == RTW_CHANNEL_WIDTH_20 && IS_CH_5G_BAND_MID(channel)) + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0, 0x4); +} + +static const u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, 0x6, + 0x5, 0x0, 0x0, 0x7, 0x6, 0x6}; +static const u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, 0x0, + 0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, 0x7, 0x6, + 0x6, 0x5, 0x0, 0x0, 0x7}; +static const u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, 0x0, + 0x7, 0x7, 0x6, 0x5, 0x5, 0x0}; + +static void rtw8822b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_BAND_2G (0) +#define RF18_BAND_5G (BIT(16) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF18_RFSI_GE_CH80 (BIT(17)) +#define RF18_RFSI_GT_CH144 (BIT(18)) +#define RF18_BW_MASK (BIT(11) | BIT(10)) +#define RF18_BW_20M (BIT(11) | BIT(10)) +#define RF18_BW_40M (BIT(11)) +#define RF18_BW_80M (BIT(10)) +#define RFBE_MASK (BIT(17) | BIT(16) | BIT(15)) + + struct rtw_hal *hal = &rtwdev->hal; + u32 rf_reg18, rf_reg_be; + + rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); + + rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | + RF18_BW_MASK); + + rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (channel & RF18_CHANNEL_MASK); + if (channel > 144) + rf_reg18 |= RF18_RFSI_GT_CH144; + else if (channel >= 80) + rf_reg18 |= RF18_RFSI_GE_CH80; + + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rf_reg18 |= RF18_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_reg18 |= RF18_BW_40M; + break; + case RTW_CHANNEL_WIDTH_80: + rf_reg18 |= RF18_BW_80M; + break; + } + + if (IS_CH_2G_BAND(channel)) + rf_reg_be = 0x0; + else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) + rf_reg_be = low_band[(channel - 36) >> 1]; + else if (IS_CH_5G_BAND_3(channel)) + rf_reg_be = middle_band[(channel - 100) >> 1]; + else if (IS_CH_5G_BAND_4(channel)) + rf_reg_be = high_band[(channel - 149) >> 1]; + else + goto err; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_MALSEL, RFBE_MASK, rf_reg_be); + + /* need to set 0xdf[18]=1 before writing RF18 when channel 144 */ + if (channel == 144) + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x1); + else + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x0); + + rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18); + if (hal->rf_type > RF_1T1R) + rtw_write_rf(rtwdev, RF_PATH_B, 0x18, RFREG_MASK, rf_reg18); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1); + + return; + +err: + WARN_ON(1); +} + +static void rtw8822b_toggle_igi(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 igi; + + igi = rtw_read32_mask(rtwdev, REG_RXIGI_A, 0x7f); + rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi - 2); + rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi); + rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi - 2); + rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi); + + rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, 0x0); + rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, + hal->antenna_rx | (hal->antenna_rx << 4)); +} + +static void rtw8822b_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw) +{ + if (bw == RTW_CHANNEL_WIDTH_40) { + /* RX DFIR for BW40 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x0); + rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + } else if (bw == RTW_CHANNEL_WIDTH_80) { + /* RX DFIR for BW80 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1); + rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + } else { + /* RX DFIR for BW20, BW10 and BW5*/ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); + rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1); + } +} + +static void rtw8822b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 rfe_option = efuse->rfe_option; + u32 val32; + + if (IS_CH_2G_BAND(channel)) { + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0); + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); + + rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x0); + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a); + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x00006577); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); + } else { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x384f6577); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x1525); + } + + rtw_write32_mask(rtwdev, REG_RFEINV, 0x300, 0x2); + } else if (IS_CH_5G_BAND(channel)) { + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 34); + + if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) + rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x1); + else if (IS_CH_5G_BAND_3(channel)) + rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x2); + else if (IS_CH_5G_BAND_4(channel)) + rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x3); + + if (IS_CH_5G_BAND_1(channel)) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494); + else if (IS_CH_5G_BAND_2(channel)) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453); + else if (channel >= 100 && channel <= 116) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452); + else if (channel >= 118 && channel <= 177) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412); + + rtw_write32_mask(rtwdev, 0xcbc, 0x300, 0x1); + } + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + default: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xFFCFFC00; + val32 |= (RTW_CHANNEL_WIDTH_20); + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_40: + if (primary_ch_idx == RTW_SC_20_UPPER) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xFF3FF300; + val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_40); + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_80: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xFCEFCF00; + val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_80); + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + + if (rfe_option == 2 || rfe_option == 3) { + rtw_write32_mask(rtwdev, REG_L1PKWT, 0x0000f000, 0x6); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(10), 0x1); + } + break; + case RTW_CHANNEL_WIDTH_5: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xEFEEFE00; + val32 |= ((BIT(6) | RTW_CHANNEL_WIDTH_20)); + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + case RTW_CHANNEL_WIDTH_10: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xEFFEFF00; + val32 |= ((BIT(7) | RTW_CHANNEL_WIDTH_20)); + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + } +} + +static void rtw8822b_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + const struct rtw8822b_rfe_info *rfe_info; + + if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info), + "rfe_option %d is out of boundary\n", efuse->rfe_option)) + return; + + rfe_info = &rtw8822b_rfe_info[efuse->rfe_option]; + + rtw8822b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8822b_set_channel_rf(rtwdev, channel, bw); + rtw8822b_set_channel_rxdfir(rtwdev, bw); + rtw8822b_toggle_igi(rtwdev); + rtw8822b_set_channel_cca(rtwdev, channel, bw, rfe_info); + (*rfe_info->rtw_set_channel_rfe)(rtwdev, channel); +} + +static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + const struct rtw8822b_rfe_info *rfe_info; + u8 ch = rtwdev->hal.current_channel; + u8 tx_path_sel, rx_path_sel; + int counter; + + if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info), + "rfe_option %d is out of boundary\n", efuse->rfe_option)) + return; + + rfe_info = &rtw8822b_rfe_info[efuse->rfe_option]; + + if ((tx_path | rx_path) & BB_PATH_A) + rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x3231); + else + rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x1111); + + if ((tx_path | rx_path) & BB_PATH_B) + rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x3231); + else + rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x1111); + + rtw_write32_mask(rtwdev, REG_CDDTXP, (BIT(19) | BIT(18)), 0x3); + rtw_write32_mask(rtwdev, REG_TXPSEL, (BIT(29) | BIT(28)), 0x1); + rtw_write32_mask(rtwdev, REG_TXPSEL, BIT(30), 0x1); + + if (tx_path & BB_PATH_A) { + rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x001); + rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x8); + } else if (tx_path & BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x002); + rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x4); + } + + if (tx_path == BB_PATH_A || tx_path == BB_PATH_B) + rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x01); + else + rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x43); + + tx_path_sel = (tx_path << 4) | tx_path; + rtw_write32_mask(rtwdev, REG_TXPSEL, MASKBYTE0, tx_path_sel); + + if (tx_path != BB_PATH_A && tx_path != BB_PATH_B) { + if (is_tx2_path || rtwdev->mp_mode) { + rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x043); + rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0xc); + } + } + + rtw_write32_mask(rtwdev, REG_RXDESC, BIT(22), 0x0); + rtw_write32_mask(rtwdev, REG_RXDESC, BIT(18), 0x0); + + if (rx_path & BB_PATH_A) + rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x0); + else if (rx_path & BB_PATH_B) + rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x5); + + rx_path_sel = (rx_path << 4) | rx_path; + rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, rx_path_sel); + + if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x0); + rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x0); + } else { + rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x1); + rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x1); + } + + for (counter = 100; counter > 0; counter--) { + u32 rf_reg33; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001); + + udelay(2); + rf_reg33 = rtw_read_rf(rtwdev, RF_PATH_A, 0x33, RFREG_MASK); + + if (rf_reg33 == 0x00001) + break; + } + + if (WARN(counter <= 0, "write RF mode table fail\n")) + return; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x00034); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x4080c); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + + rtw8822b_toggle_igi(rtwdev); + rtw8822b_set_channel_cca(rtwdev, 1, RTW_CHANNEL_WIDTH_20, rfe_info); + (*rfe_info->rtw_set_channel_rfe)(rtwdev, ch); +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 min_rx_power = -120; + u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); + + /* 8822B uses only 1 antenna to RX CCK rates */ + pkt_stat->rx_power[RF_PATH_A] = pwdb - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 rxsc, bw; + s8 min_rx_power = -120; + s8 rx_evm; + u8 evm_dbm = 0; + u8 rssi; + int path; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (rxsc >= 1 && rxsc <= 8) + bw = RTW_CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) + bw = RTW_CHANNEL_WIDTH_40; + else if (rxsc >= 13) + bw = RTW_CHANNEL_WIDTH_80; + else + bw = GET_PHY_STAT_P1_RF_MODE(phy_status); + + pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; + pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2); + pkt_stat->bw = bw; + pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], + pkt_stat->rx_power[RF_PATH_B], + min_rx_power); + + dm_info->curr_rx_rate = pkt_stat->rate; + + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); + + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); + + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; + + rx_evm = pkt_stat->rx_evm[path]; + + if (rx_evm < 0) { + if (rx_evm == S8_MIN) + evm_dbm = 0; + else + evm_dbm = ((u8)-rx_evm >> 1); + } + dm_info->rx_evm_dbm[path] = evm_dbm; + } +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static void +rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) +{ + struct rtw_hal *hal = &rtwdev->hal; + static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate, rate_idx, pwr_index, shift; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + shift = rate & 0x3; + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + if (shift == 0x3) { + rate_idx = rate & 0xfc; + rtw_write32(rtwdev, offset_txagc[path] + rate_idx, + *phy_pwr_idx); + *phy_pwr_idx = 0; + } + } +} + +static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) + rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); + } +} + +static bool rtw8822b_check_rf_path(u8 antenna) +{ + switch (antenna) { + case BB_PATH_A: + case BB_PATH_B: + case BB_PATH_AB: + return true; + default: + return false; + } +} + +static int rtw8822b_set_antenna(struct rtw_dev *rtwdev, + int radio_idx, + u32 antenna_tx, + u32 antenna_rx) +{ + struct rtw_hal *hal = &rtwdev->hal; + + rtw_dbg(rtwdev, RTW_DBG_PHY, "config RF path, tx=0x%x rx=0x%x\n", + antenna_tx, antenna_rx); + + if (!rtw8822b_check_rf_path(antenna_tx)) { + rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); + return -EINVAL; + } + + if (!rtw8822b_check_rf_path(antenna_rx)) { + rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); + return -EINVAL; + } + + hal->antenna_tx = antenna_tx; + hal->antenna_rx = antenna_rx; + + if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); + + return 0; +} + +static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); + ldo_pwr = enable ? ldo_pwr | BIT_LDO25_EN : ldo_pwr & ~BIT_LDO25_EN; + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +} + +static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_enable; + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 crc32_cnt; + u32 cca32_cnt; + + cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, 0xa5c); + ofdm_fa_cnt = rtw_read16(rtwdev, 0xf48); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0; + + crc32_cnt = rtw_read32(rtwdev, 0xf04); + dm_info->cck_ok_cnt = crc32_cnt & 0xffff; + dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0xf14); + dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff; + dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0xf10); + dm_info->ht_ok_cnt = crc32_cnt & 0xffff; + dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0xf0c); + dm_info->vht_ok_cnt = crc32_cnt & 0xffff; + dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + + cca32_cnt = rtw_read32(rtwdev, 0xf08); + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, 0xfcc); + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, 0x9a4, BIT(17)); + rtw_write32_clr(rtwdev, 0x9a4, BIT(17)); + rtw_write32_clr(rtwdev, 0xa2c, BIT(15)); + rtw_write32_set(rtwdev, 0xa2c, BIT(15)); + rtw_write32_set(rtwdev, 0xb58, BIT(0)); + rtw_write32_clr(rtwdev, 0xb58, BIT(0)); +} + +static void rtw8822b_do_iqk(struct rtw_dev *rtwdev) +{ + static int do_iqk_cnt; + struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0}; + u32 rf_reg, iqk_fail_mask; + int counter; + bool reload; + + rtw_fw_do_iqk(rtwdev, ¶); + + for (counter = 0; counter < 300; counter++) { + rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK); + if (rf_reg == 0xabcde) + break; + msleep(20); + } + rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0); + + reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16)); + iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0)); + rtw_dbg(rtwdev, RTW_DBG_PHY, + "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n", + counter, reload, ++do_iqk_cnt, iqk_fail_mask); +} + +static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8822b_do_iqk(rtwdev); +} + +static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev) +{ + /* enable TBTT nterrupt */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* BT report packet sample rate */ + /* 0x790[5:0]=0x5 */ + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); + + /* enable PTA (3-wire function form BT side) */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); + + /* enable PTA (tx/rx signal form WiFi side) */ + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); + /* wl tx signal to PTA not case EDCCA */ + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); + /* GNT_BT=1 while select both */ + rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); +} + +static void rtw8822b_coex_cfg_ant_switch(struct rtw_dev *rtwdev, + u8 ctrl_type, u8 pos_type) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + bool polarity_inverse; + u8 regval = 0; + + if (((ctrl_type << 8) + pos_type) == coex_dm->cur_switch_status) + return; + + coex_dm->cur_switch_status = (ctrl_type << 8) + pos_type; + + if (coex_rfe->ant_switch_diversity && + ctrl_type == COEX_SWITCH_CTRL_BY_BBSW) + ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV; + + polarity_inverse = (coex_rfe->ant_switch_polarity == 1); + + switch (ctrl_type) { + default: + case COEX_SWITCH_CTRL_BY_BBSW: + /* 0x4c[23] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0); + /* 0x4c[24] = 1 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1); + /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x77); + + if (pos_type == COEX_SWITCH_TO_WLG_BT) { + if (coex_rfe->rfe_module_type != 0x4 && + coex_rfe->rfe_module_type != 0x2) + regval = 0x3; + else + regval = (!polarity_inverse ? 0x2 : 0x1); + } else if (pos_type == COEX_SWITCH_TO_WLG) { + regval = (!polarity_inverse ? 0x2 : 0x1); + } else { + regval = (!polarity_inverse ? 0x1 : 0x2); + } + + rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval); + break; + case COEX_SWITCH_CTRL_BY_PTA: + /* 0x4c[23] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0); + /* 0x4c[24] = 1 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1); + /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x66); + + regval = (!polarity_inverse ? 0x2 : 0x1); + rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval); + break; + case COEX_SWITCH_CTRL_BY_ANTDIV: + /* 0x4c[23] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0); + /* 0x4c[24] = 1 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1); + rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x88); + break; + case COEX_SWITCH_CTRL_BY_MAC: + /* 0x4c[23] = 1 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x1); + + regval = (!polarity_inverse ? 0x0 : 0x1); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, regval); + break; + case COEX_SWITCH_CTRL_BY_FW: + /* 0x4c[23] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0); + /* 0x4c[24] = 1 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1); + break; + case COEX_SWITCH_CTRL_BY_BT: + /* 0x4c[23] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0); + /* 0x4c[24] = 0 */ + rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x0); + break; + } +} + +static void rtw8822b_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8822b_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0); + rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0); + rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0); +} + +static void rtw8822b_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool is_ext_fem = false; + + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_diversity = false; + if (coex_rfe->rfe_module_type == 0x12 || + coex_rfe->rfe_module_type == 0x15 || + coex_rfe->rfe_module_type == 0x16) + coex_rfe->ant_switch_exist = false; + else + coex_rfe->ant_switch_exist = true; + + if (coex_rfe->rfe_module_type == 2 || + coex_rfe->rfe_module_type == 4) { + rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, true); + is_ext_fem = true; + } else { + rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, false); + } + + coex_rfe->wlg_at_btg = false; + + if (efuse->share_ant && + coex_rfe->ant_switch_exist && !is_ext_fem) + coex_rfe->ant_switch_with_bt = true; + else + coex_rfe->ant_switch_with_bt = false; + + /* Ext switch buffer mux */ + rtw_write8(rtwdev, REG_RFE_CTRL_E, 0xff); + rtw_write8_mask(rtwdev, REG_RFESEL_CTRL + 1, 0x3, 0x0); + rtw_write8_mask(rtwdev, REG_RFE_INV16, BIT_RFE_BUF_EN, 0x0); + + /* Disable LTE Coex Function in WiFi side */ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0); + + /* BTC_CTT_WL_VS_LTE */ + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); + + /* BTC_CTT_BT_VS_LTE */ + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); +} + +static void rtw8822b_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + static const u16 reg_addr[] = {0xc58, 0xe58}; + static const u8 wl_tx_power[] = {0xd8, 0xd4, 0xd0, 0xcc, 0xc8}; + u8 i, pwr; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; + + if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power)) + coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1; + + pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl]; + + for (i = 0; i < ARRAY_SIZE(reg_addr); i++) + rtw_write8_mask(rtwdev, reg_addr[i], 0xff, pwr); +} + +static void rtw8822b_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + /* WL Rx Low gain on */ + static const u32 wl_rx_low_gain_on[] = { + 0xff000003, 0xbd120003, 0xbe100003, 0xbf080003, 0xbf060003, + 0xbf050003, 0xbc140003, 0xbb160003, 0xba180003, 0xb91a0003, + 0xb81c0003, 0xb71e0003, 0xb4200003, 0xb5220003, 0xb4240003, + 0xb3260003, 0xb2280003, 0xb12a0003, 0xb02c0003, 0xaf2e0003, + 0xae300003, 0xad320003, 0xac340003, 0xab360003, 0x8d380003, + 0x8c3a0003, 0x8b3c0003, 0x8a3e0003, 0x6e400003, 0x6d420003, + 0x6c440003, 0x6b460003, 0x6a480003, 0x694a0003, 0x684c0003, + 0x674e0003, 0x66500003, 0x65520003, 0x64540003, 0x64560003, + 0x007e0403 + }; + + /* WL Rx Low gain off */ + static const u32 wl_rx_low_gain_off[] = { + 0xff000003, 0xf4120003, 0xf5100003, 0xf60e0003, 0xf70c0003, + 0xf80a0003, 0xf3140003, 0xf2160003, 0xf1180003, 0xf01a0003, + 0xef1c0003, 0xee1e0003, 0xed200003, 0xec220003, 0xeb240003, + 0xea260003, 0xe9280003, 0xe82a0003, 0xe72c0003, 0xe62e0003, + 0xe5300003, 0xc8320003, 0xc7340003, 0xc6360003, 0xc5380003, + 0xc43a0003, 0xc33c0003, 0xc23e0003, 0xc1400003, 0xc0420003, + 0xa5440003, 0xa4460003, 0xa3480003, 0xa24a0003, 0xa14c0003, + 0x834e0003, 0x82500003, 0x81520003, 0x80540003, 0x65560003, + 0x007e0403 + }; + u8 i; + + if (low_gain == coex_dm->cur_wl_rx_low_gain_en) + return; + + coex_dm->cur_wl_rx_low_gain_en = low_gain; + + if (coex_dm->cur_wl_rx_low_gain_en) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n"); + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++) + rtw_write32(rtwdev, REG_RX_GAIN_EN, wl_rx_low_gain_on[i]); + + /* set Rx filter corner RCK offset */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x3f); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x1); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x3f); + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n"); + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) + rtw_write32(rtwdev, 0x81c, wl_rx_low_gain_off[i]); + + /* set Rx filter corner RCK offset */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x4); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x0); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x4); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x0); + } +} + +static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path, + u8 tx_pwr_idx_offset, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 delta_pwr_idx = dm_info->delta_power_index[path]; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + u8 swing_lower_bound = 0; + u8 max_tx_pwr_idx_offset = 0xf; + s8 agc_index = 0; + u8 swing_index = dm_info->default_ofdm_index; + + tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= tx_pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > tx_pwr_idx_offset) { + agc_index = tx_pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - tx_pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else { + if (dm_info->default_ofdm_index > abs(delta_pwr_idx)) + swing_index = + dm_info->default_ofdm_index + delta_pwr_idx; + else + swing_index = swing_lower_bound; + swing_index = max_t(u8, swing_index, swing_lower_bound); + + agc_index = 0; + } + + if (swing_index >= RTW_TXSCALE_SIZE) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = RTW_TXSCALE_SIZE - 1; + } + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path, + u8 pwr_idx_offset) +{ + s8 txagc_idx; + u8 swing_idx; + u32 reg1, reg2; + + if (path == RF_PATH_A) { + reg1 = 0xc94; + reg2 = 0xc1c; + } else if (path == RF_PATH_B) { + reg1 = 0xe94; + reg2 = 0xe1c; + } else { + return; + } + + rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx); + rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21), + rtw8822b_txscale_tbl[swing_idx]); +} + +static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pwr_idx_offset, tx_pwr_idx; + u8 channel = rtwdev->hal.current_channel; + u8 band_width = rtwdev->hal.current_band_width; + u8 regd = rtw_regd_get(rtwdev); + u8 tx_rate = dm_info->tx_rate; + u8 max_pwr_idx = rtwdev->chip->max_power_index; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + + rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset); +} + +static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 power_idx_cur, power_idx_last; + u8 delta; + + /* 8822B only has one thermal meter at PATH A */ + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + power_idx_last = dm_info->delta_power_index[path]; + power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, + path, RF_PATH_A, delta); + + /* if delta of power indexes are the same, just skip */ + if (power_idx_cur == power_idx_last) + return; + + dm_info->delta_power_index[path] = power_idx_cur; + rtw8822b_pwrtrack_set(rtwdev, path); +} + +static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, path; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) + rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8822b_do_iqk(rtwdev); +} + +static void rtw8822b_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8822b_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8822b_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8822b_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8822b_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8822b_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + +static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev) +{ + rtw_phy_set_edcca_th(rtwdev, RTW8822B_EDCCA_MAX, RTW8822B_EDCCA_MAX); + + /* mac edcca state setting */ + rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA); + rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN); + rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION, + RTW8822B_EDCCA_SRC_DEF); + rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0); + + /* edcca decision opt */ + rtw_write32_set(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION); +} + +static void rtw8822b_adaptivity(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 l2h, h2l; + u8 igi; + + igi = dm_info->igi_history[0]; + if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { + l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); + h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; + } else { + l2h = min_t(s8, igi, dm_info->l2h_th_ini); + h2l = l2h - EDCCA_L2H_H2L_DIFF; + } + + rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +} + +static void rtw8822b_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + + fill_txdesc_checksum_common(txdesc, words); +} + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, + {0x0300, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822b[] = { + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0xFF1A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x10A8, + RTW_PWR_CUT_C_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x10A9, + RTW_PWR_CUT_C_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xef}, + {0x10AA, + RTW_PWR_CUT_C_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x0c}, + {0x0068, + RTW_PWR_CUT_C_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0029, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xF9}, + {0x0024, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0074, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x00AF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822b[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x00EF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFF1A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x30}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x004F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0090, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0044, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0040, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x90}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = { + trans_carddis_to_cardemu_8822b, + trans_cardemu_to_act_8822b, + NULL +}; + +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = { + trans_act_to_cardemu_8822b, + trans_cardemu_to_carddis_8822b, + NULL +}; + +static const struct rtw_intf_phy_para usb2_param_8822b[] = { + {0xFFFF, 0x00, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para usb3_param_8822b[] = { + {0x0001, 0xA841, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_D, + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen1_param_8822b[] = { + {0x0001, 0xA841, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0002, 0x60C6, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0008, 0x3596, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0009, 0x321C, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x000A, 0x9623, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0020, 0x94FF, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0021, 0xFFCF, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0026, 0xC006, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0029, 0xFF0E, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x002A, 0x1840, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen2_param_8822b[] = { + {0x0001, 0xA841, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0002, 0x60C6, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0008, 0x3597, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0009, 0x321C, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x000A, 0x9623, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0020, 0x94FF, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0021, 0xFFCF, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0026, 0xC006, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0029, 0xFF0E, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x002A, 0x3040, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_C, + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8822b = { + .usb2_para = usb2_param_8822b, + .usb3_para = usb3_param_8822b, + .gen1_para = pcie_gen1_param_8822b, + .gen2_para = pcie_gen2_param_8822b, + .n_usb2_para = ARRAY_SIZE(usb2_param_8822b), + .n_usb3_para = ARRAY_SIZE(usb2_param_8822b), + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8822b), + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b), +}; + +static const struct rtw_hw_reg rtw8822b_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, +}; + +static const struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + +static const struct rtw_page_table page_table_8822b[] = { + {64, 64, 64, 64, 1}, + {64, 64, 64, 64, 1}, + {64, 64, 0, 0, 1}, + {64, 64, 64, 0, 1}, + {64, 64, 64, 64, 1}, +}; + +static const struct rtw_rqpn rqpn_table_8822b[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8822b = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static const struct rtw_chip_ops rtw8822b_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_phy_status = query_phy_status, + .set_channel = rtw8822b_set_channel, + .mac_init = rtw8822b_mac_init, + .mac_postinit = NULL, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8822b_set_tx_power_index, + .set_antenna = rtw8822b_set_antenna, + .cfg_ldo25 = rtw8822b_cfg_ldo25, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw8822b_false_alarm_statistics, + .phy_calibration = rtw8822b_phy_calibration, + .pwr_track = rtw8822b_pwr_track, + .config_bfee = rtw8822b_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .adaptivity_init = rtw8822b_adaptivity_init, + .adaptivity = rtw8822b_adaptivity, + .led_set = rtw8822b_led_set, + .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, + + .coex_set_init = rtw8822b_coex_cfg_init, + .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8822b_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8822b_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8822b_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8822b_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8822b_coex_cfg_wl_rx_gain, +}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8822b[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5aaa}, + {0x66555555, 0x6aaa5aaa}, + {0x66555555, 0xaaaa5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x6a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x55555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8822b[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-110 */ + {0x66555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xffff55ff, 0xffff55ff}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffffffff, 0x5afa5afa}, + {0xffffffff, 0xaaaaaaaa}, /* case-120 */ + {0x55ff55ff, 0x5afa5afa}, + {0x55ff55ff, 0xaaaaaaaa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8822b[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8822b[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} } +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8822b[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8822b[] = {30, 30, 30, 30}; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8822b[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static const struct coex_rf_para rf_para_rx_8822b[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static const struct coex_5g_afh_map afh_5g_8822b[] = { + {120, 2, 4}, + {124, 8, 8}, + {128, 17, 8}, + {132, 26, 10}, + {136, 34, 8}, + {140, 42, 10}, + {144, 51, 8}, + {149, 62, 8}, + {153, 71, 10}, + {157, 77, 4}, + {118, 2, 4}, + {126, 12, 16}, + {134, 29, 16}, + {142, 46, 16}, + {151, 66, 16}, + {159, 76, 4}, + {122, 10, 20}, + {138, 37, 34}, + {155, 68, 20} +}; +static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b)); + +static const u8 +rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, +}; + +static const u8 +rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, +}; + +static const u8 +rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, +}; + +static const u8 +rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 +}; + +static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 +}; + +static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, +}; + +static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { + [2] = RTW_DEF_RFE(8822b, 2, 2, 0), + [3] = RTW_DEF_RFE(8822b, 3, 0, 0), + [5] = RTW_DEF_RFE(8822b, 5, 5, 0), +}; + +static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + +static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0}, + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0}, +}; + +const struct rtw_chip_info rtw8822b_hw_spec = { + .ops = &rtw8822b_ops, + .id = RTW_CHIP_TYPE_8822B, + .fw_name = "rtw88/rtw8822b_fw.bin", + .wlan_cpu = RTW_WCPU_3081, + .tx_pkt_desc_sz = 48, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 1024, + .log_efuse_size = 768, + .ptct_efuse_size = 96, + .txff_size = 262144, + .rxff_size = 24576, + .fw_rxff_size = 12288, + .rsvd_drv_pg_num = 8, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .amsdu_in_ampdu = true, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), + .sys_func_en = 0xDC, + .pwr_on_seq = card_enable_flow_8822b, + .pwr_off_seq = card_disable_flow_8822b, + .page_table = page_table_8822b, + .rqpn_table = rqpn_table_8822b, + .prioq_addrs = &prioq_addrs_8822b, + .intf_table = &phy_para_table_8822b, + .dig = rtw8822b_dig, + .dig_cck = NULL, + .rf_base_addr = {0x2800, 0x2c00}, + .rf_sipi_addr = {0xc90, 0xe90}, + .ltecoex_addr = &rtw8822b_ltecoex_addr, + .mac_tbl = &rtw8822b_mac_tbl, + .agc_tbl = &rtw8822b_agc_tbl, + .bb_tbl = &rtw8822b_bb_tbl, + .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, + .rfe_defs = rtw8822b_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, + .rx_ldpc = true, + .edcca_th = rtw8822b_edcca_th, + .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE, + .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0x20070206, + .bt_desired_ver = 0x6, + .scbd_support = true, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8822b, + .bt_rssi_step = bt_rssi_step_8822b, + .table_sant_num = ARRAY_SIZE(table_sant_8822b), + .table_sant = table_sant_8822b, + .table_nsant_num = ARRAY_SIZE(table_nsant_8822b), + .table_nsant = table_nsant_8822b, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8822b), + .tdma_sant = tdma_sant_8822b, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822b), + .tdma_nsant = tdma_nsant_8822b, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822b), + .wl_rf_para_tx = rf_para_tx_8822b, + .wl_rf_para_rx = rf_para_rx_8822b, + .bt_afh_span_bw20 = 0x24, + .bt_afh_span_bw40 = 0x36, + .afh_5g_num = ARRAY_SIZE(afh_5g_8822b), + .afh_5g = afh_5g_8822b, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), + .coex_info_hw_regs = coex_info_hw_regs_8822b, + + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, +}; +EXPORT_SYMBOL(rtw8822b_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8822b_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822b driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h new file mode 100644 index 000000000..9fca9ba67 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8822B_H__ +#define __RTW8822B_H__ + +#include + +#define RCR_VHT_ACK BIT(26) + +struct rtw8822bu_efuse { + u8 res4[4]; /* 0xd0 */ + u8 usb_optional_function; + u8 res5[0x1e]; + u8 res6[2]; + u8 serial[0x0b]; /* 0xf5 */ + u8 vid; /* 0x100 */ + u8 res7; + u8 pid; + u8 res8[4]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 res9[2]; + u8 vendor_name[0x07]; + u8 res10[2]; + u8 device_name[0x14]; + u8 res11[0xcf]; + u8 package_type; /* 0x1fb */ + u8 res12[0x4]; +} __packed; + +struct rtw8822be_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vender_id[2]; + u8 device_id[2]; + u8 sub_vender_id[2]; + u8 sub_device_id[2]; + u8 pmc[2]; + u8 exp_device_cap[2]; + u8 msi_cap; + u8 ltr_cap; /* 0xe3 */ + u8 exp_link_control[2]; + u8 link_cap[4]; + u8 link_control[2]; + u8 serial_number[8]; + u8 res0:2; /* 0xf4 */ + u8 ltr_en:1; + u8 res1:2; + u8 obff:2; + u8 res2_1:1; + u8 res2_2:2; + u8 obff_cap:2; + u8 res3:4; + u8 res4[3]; + u8 class_code[3]; + u8 pci_pm_L1_2_supp:1; + u8 pci_pm_L1_1_supp:1; + u8 aspm_pm_L1_2_supp:1; + u8 aspm_pm_L1_1_supp:1; + u8 L1_pm_substates_supp:1; + u8 res5:3; + u8 port_common_mode_restore_time; + u8 port_t_power_on_scale:2; + u8 res6:1; + u8 port_t_power_on_value:5; + u8 res7; +} __packed; + +struct rtw8822bs_efuse { + u8 res4[0x4a]; /* 0xd0 */ + u8 mac_addr[ETH_ALEN]; /* 0x11a */ +} __packed; + +struct rtw8822b_efuse { + __le16 rtl_id; + u8 res0[4]; + u8 usb_mode; + u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res[3]; + union { + struct rtw8822be_efuse e; + struct rtw8822bu_efuse u; + struct rtw8822bs_efuse s; + }; +} __packed; + +static inline void +_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) +{ + /* 0xC00-0xCFF and 0xE00-0xEFF have the same layout */ + rtw_write32_mask(rtwdev, addr, mask, data); + rtw_write32_mask(rtwdev, addr + 0x200, mask, data); +} + +#define rtw_write32s_mask(rtwdev, addr, mask, data) \ + do { \ + BUILD_BUG_ON((addr) < 0xC00 || (addr) >= 0xD00); \ + \ + _rtw_write32s_mask(rtwdev, addr, mask, data); \ + } while (0) + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) + +#define RTW8822B_EDCCA_MAX 0x7f +#define RTW8822B_EDCCA_SRC_DEF 1 +#define REG_HTSTFWT 0x800 +#define REG_RXCCAMSK 0x814 +#define REG_L1WT 0x83c +#define REG_L1PKWT 0x840 +#define REG_MRC 0x850 +#define REG_EDCCA_POW_MA 0x8a0 +#define BIT_MA_LEVEL GENMASK(1, 0) +#define REG_ADC40 0x8c8 +#define REG_EDCCA_DECISION 0x8dc +#define BIT_EDCCA_OPTION BIT(5) +#define REG_CDDTXP 0x93c +#define REG_TXPSEL1 0x940 +#define REG_EDCCA_SOURCE 0x944 +#define BIT_SOURCE_OPTION GENMASK(29, 28) +#define REG_ACBB0 0x948 +#define REG_ACBBRXFIR 0x94c +#define REG_ACGG2TBL 0x958 +#define REG_ADCINI 0xa04 +#define REG_TXSF2 0xa24 +#define REG_TXSF6 0xa28 +#define REG_RXDESC 0xa2c +#define REG_ENTXCCK 0xa80 +#define REG_AGCTR_A 0xc08 +#define REG_TXDFIR 0xc20 +#define REG_TRSW 0xca0 +#define REG_RFESEL0 0xcb0 +#define REG_RFESEL8 0xcb4 +#define REG_RFECTL 0xcb8 +#define REG_RFEINV 0xcbc +#define REG_AGCTR_B 0xe08 +#define REG_ANTWT 0x1904 +#define REG_IQKFAILMSK 0x1bf0 + +extern const struct rtw_chip_info rtw8822b_hw_spec; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b_table.c b/drivers/net/wireless/realtek/rtw88/rtw8822b_table.c new file mode 100644 index 000000000..b9010b111 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b_table.c @@ -0,0 +1,22204 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8822b_table.h" + +static const u32 rtw8822b_mac[] = { + 0x029, 0x000000F9, + 0x420, 0x00000080, + 0x421, 0x0000001F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x000000F0, + 0x446, 0x00000001, + 0x447, 0x000000FE, + 0x448, 0x00000000, + 0x449, 0x00000000, + 0x44A, 0x00000000, + 0x44B, 0x00000040, + 0x44C, 0x00000010, + 0x44D, 0x000000F0, + 0x44E, 0x0000003F, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x00000000, + 0x452, 0x00000000, + 0x453, 0x00000040, + 0x455, 0x00000070, + 0x45E, 0x00000004, + 0x49C, 0x00000010, + 0x49D, 0x000000F0, + 0x49E, 0x00000000, + 0x49F, 0x00000006, + 0x4A0, 0x000000E0, + 0x4A1, 0x00000003, + 0x4A2, 0x00000000, + 0x4A3, 0x00000040, + 0x4A4, 0x00000015, + 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, + 0x4A7, 0x00000006, + 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, + 0x4AA, 0x00000000, + 0x4AB, 0x00000000, + 0x7DA, 0x00000008, + 0x1448, 0x00000006, + 0x144A, 0x00000006, + 0x144C, 0x00000006, + 0x144E, 0x00000006, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CA, 0x00000020, + 0x4CB, 0x00000020, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4CF, 0x00000008, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x521, 0x0000002F, + 0x525, 0x0000004F, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x577, 0x0000000B, + 0x5BE, 0x00000064, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x00000022, + 0x60C, 0x00000018, + 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, + 0x6A2, 0x000000FF, + 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, + 0x6A5, 0x000000FF, + 0x6DE, 0x00000084, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x718, 0x00000040, + 0x7D4, 0x00000098, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822b_mac, rtw_phy_cfg_mac); + +static const u32 rtw8822b_agc[] = { + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xF5000003, + 0x81C, 0xF4020003, + 0x81C, 0xF3040003, + 0x81C, 0xF2060003, + 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, + 0x81C, 0xEC120003, + 0x81C, 0xEB140003, + 0x81C, 0xEA160003, + 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, + 0x81C, 0xE4220003, + 0x81C, 0xE3240003, + 0x81C, 0xE2260003, + 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, + 0x81C, 0xC0320003, + 0x81C, 0xA4340003, + 0x81C, 0xA3360003, + 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, + 0x81C, 0x81400003, + 0x81C, 0x80420003, + 0x81C, 0x64440003, + 0x81C, 0x63460003, + 0x81C, 0x62480003, + 0x81C, 0x614A0003, + 0x81C, 0x604C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x42540003, + 0x81C, 0x41560003, + 0x81C, 0x40580003, + 0x81C, 0x055A0003, + 0x81C, 0x045C0003, + 0x81C, 0x035E0003, + 0x81C, 0x02600003, + 0x81C, 0x01620003, + 0x81C, 0x00640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFD000003, + 0x81C, 0xFC020003, + 0x81C, 0xFB040003, + 0x81C, 0xFA060003, + 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, + 0x81C, 0xF4120003, + 0x81C, 0xF3140003, + 0x81C, 0xF2160003, + 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, + 0x81C, 0xEC220003, + 0x81C, 0xEB240003, + 0x81C, 0xEA260003, + 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, + 0x81C, 0xC0420003, + 0x81C, 0xA5440003, + 0x81C, 0xA4460003, + 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x80540003, + 0x81C, 0x65560003, + 0x81C, 0x64580003, + 0x81C, 0x635A0003, + 0x81C, 0x625C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x40640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFD000003, + 0x81C, 0xFC020003, + 0x81C, 0xFB040003, + 0x81C, 0xFA060003, + 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, + 0x81C, 0xF4120003, + 0x81C, 0xF3140003, + 0x81C, 0xF2160003, + 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, + 0x81C, 0xEC220003, + 0x81C, 0xEB240003, + 0x81C, 0xEA260003, + 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, + 0x81C, 0xC0420003, + 0x81C, 0xA5440003, + 0x81C, 0xA4460003, + 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x80540003, + 0x81C, 0x65560003, + 0x81C, 0x64580003, + 0x81C, 0x635A0003, + 0x81C, 0x625C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x40640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xDC000003, + 0x81C, 0xDB020003, + 0x81C, 0xDA040003, + 0x81C, 0xD9060003, + 0x81C, 0xD8080003, + 0x81C, 0xD70A0003, + 0x81C, 0xD60C0003, + 0x81C, 0xD50E0003, + 0x81C, 0xD4100003, + 0x81C, 0xD3120003, + 0x81C, 0xD2140003, + 0x81C, 0xD1160003, + 0x81C, 0xD0180003, + 0x81C, 0xB41A0003, + 0x81C, 0xB31C0003, + 0x81C, 0xB21E0003, + 0x81C, 0xB1200003, + 0x81C, 0xB0220003, + 0x81C, 0xAF240003, + 0x81C, 0xAE260003, + 0x81C, 0xAD280003, + 0x81C, 0xAC2A0003, + 0x81C, 0xAB2C0003, + 0x81C, 0x8C2E0003, + 0x81C, 0x8B300003, + 0x81C, 0x8A320003, + 0x81C, 0x89340003, + 0x81C, 0x88360003, + 0x81C, 0x87380003, + 0x81C, 0x863A0003, + 0x81C, 0x853C0003, + 0x81C, 0x693E0003, + 0x81C, 0x68400003, + 0x81C, 0x67420003, + 0x81C, 0x66440003, + 0x81C, 0x65460003, + 0x81C, 0x48480003, + 0x81C, 0x474A0003, + 0x81C, 0x464C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x27540003, + 0x81C, 0x26560003, + 0x81C, 0x25580003, + 0x81C, 0x245A0003, + 0x81C, 0x235C0003, + 0x81C, 0x045E0003, + 0x81C, 0x03600003, + 0x81C, 0x02620003, + 0x81C, 0x01640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFD000003, + 0x81C, 0xFC020003, + 0x81C, 0xFB040003, + 0x81C, 0xFA060003, + 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, + 0x81C, 0xF4120003, + 0x81C, 0xF3140003, + 0x81C, 0xF2160003, + 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, + 0x81C, 0xEC220003, + 0x81C, 0xEB240003, + 0x81C, 0xEA260003, + 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, + 0x81C, 0xC0420003, + 0x81C, 0xA5440003, + 0x81C, 0xA4460003, + 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x80540003, + 0x81C, 0x65560003, + 0x81C, 0x64580003, + 0x81C, 0x635A0003, + 0x81C, 0x625C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x40640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xF5000003, + 0x81C, 0xF4020003, + 0x81C, 0xF3040003, + 0x81C, 0xF2060003, + 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, + 0x81C, 0xEC120003, + 0x81C, 0xEB140003, + 0x81C, 0xEA160003, + 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, + 0x81C, 0xE4220003, + 0x81C, 0xE3240003, + 0x81C, 0xE2260003, + 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, + 0x81C, 0xC0320003, + 0x81C, 0xA4340003, + 0x81C, 0xA3360003, + 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, + 0x81C, 0x81400003, + 0x81C, 0x80420003, + 0x81C, 0x64440003, + 0x81C, 0x63460003, + 0x81C, 0x62480003, + 0x81C, 0x614A0003, + 0x81C, 0x604C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x42540003, + 0x81C, 0x41560003, + 0x81C, 0x40580003, + 0x81C, 0x055A0003, + 0x81C, 0x045C0003, + 0x81C, 0x035E0003, + 0x81C, 0x02600003, + 0x81C, 0x01620003, + 0x81C, 0x00640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xF5000003, + 0x81C, 0xF4020003, + 0x81C, 0xF3040003, + 0x81C, 0xF2060003, + 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, + 0x81C, 0xEC120003, + 0x81C, 0xEB140003, + 0x81C, 0xEA160003, + 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, + 0x81C, 0xE4220003, + 0x81C, 0xE3240003, + 0x81C, 0xE2260003, + 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, + 0x81C, 0xC0320003, + 0x81C, 0xA4340003, + 0x81C, 0xA3360003, + 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, + 0x81C, 0x81400003, + 0x81C, 0x80420003, + 0x81C, 0x64440003, + 0x81C, 0x63460003, + 0x81C, 0x62480003, + 0x81C, 0x614A0003, + 0x81C, 0x604C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x42540003, + 0x81C, 0x41560003, + 0x81C, 0x40580003, + 0x81C, 0x055A0003, + 0x81C, 0x045C0003, + 0x81C, 0x035E0003, + 0x81C, 0x02600003, + 0x81C, 0x01620003, + 0x81C, 0x00640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xF5000003, + 0x81C, 0xF4020003, + 0x81C, 0xF3040003, + 0x81C, 0xF2060003, + 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, + 0x81C, 0xEC120003, + 0x81C, 0xEB140003, + 0x81C, 0xEA160003, + 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, + 0x81C, 0xE4220003, + 0x81C, 0xE3240003, + 0x81C, 0xE2260003, + 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, + 0x81C, 0xC0320003, + 0x81C, 0xA4340003, + 0x81C, 0xA3360003, + 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, + 0x81C, 0x81400003, + 0x81C, 0x80420003, + 0x81C, 0x64440003, + 0x81C, 0x63460003, + 0x81C, 0x62480003, + 0x81C, 0x614A0003, + 0x81C, 0x604C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x42540003, + 0x81C, 0x41560003, + 0x81C, 0x40580003, + 0x81C, 0x055A0003, + 0x81C, 0x045C0003, + 0x81C, 0x035E0003, + 0x81C, 0x02600003, + 0x81C, 0x01620003, + 0x81C, 0x00640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xF5000003, + 0x81C, 0xF4020003, + 0x81C, 0xF3040003, + 0x81C, 0xF2060003, + 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, + 0x81C, 0xEC120003, + 0x81C, 0xEB140003, + 0x81C, 0xEA160003, + 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, + 0x81C, 0xE4220003, + 0x81C, 0xE3240003, + 0x81C, 0xE2260003, + 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, + 0x81C, 0xC0320003, + 0x81C, 0xA4340003, + 0x81C, 0xA3360003, + 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, + 0x81C, 0x81400003, + 0x81C, 0x80420003, + 0x81C, 0x64440003, + 0x81C, 0x63460003, + 0x81C, 0x62480003, + 0x81C, 0x614A0003, + 0x81C, 0x604C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x42540003, + 0x81C, 0x41560003, + 0x81C, 0x40580003, + 0x81C, 0x055A0003, + 0x81C, 0x045C0003, + 0x81C, 0x035E0003, + 0x81C, 0x02600003, + 0x81C, 0x01620003, + 0x81C, 0x00640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFD000003, + 0x81C, 0xFC020003, + 0x81C, 0xFB040003, + 0x81C, 0xFA060003, + 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, + 0x81C, 0xF4120003, + 0x81C, 0xF3140003, + 0x81C, 0xF2160003, + 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, + 0x81C, 0xEC220003, + 0x81C, 0xEB240003, + 0x81C, 0xEA260003, + 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, + 0x81C, 0xC0420003, + 0x81C, 0xA5440003, + 0x81C, 0xA4460003, + 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x80540003, + 0x81C, 0x65560003, + 0x81C, 0x64580003, + 0x81C, 0x635A0003, + 0x81C, 0x625C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x40640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFC000003, + 0x81C, 0xFB020003, + 0x81C, 0xFA040003, + 0x81C, 0xF9060003, + 0x81C, 0xF8080003, + 0x81C, 0xF70A0003, + 0x81C, 0xF60C0003, + 0x81C, 0xF50E0003, + 0x81C, 0xF4100003, + 0x81C, 0xF3120003, + 0x81C, 0xF2140003, + 0x81C, 0xF1160003, + 0x81C, 0xF0180003, + 0x81C, 0xEF1A0003, + 0x81C, 0xEE1C0003, + 0x81C, 0xED1E0003, + 0x81C, 0xEC200003, + 0x81C, 0xEB220003, + 0x81C, 0xEA240003, + 0x81C, 0xE9260003, + 0x81C, 0xE8280003, + 0x81C, 0xE72A0003, + 0x81C, 0xE62C0003, + 0x81C, 0xE52E0003, + 0x81C, 0xC8300003, + 0x81C, 0xC7320003, + 0x81C, 0xC6340003, + 0x81C, 0xC5360003, + 0x81C, 0xC4380003, + 0x81C, 0xC33A0003, + 0x81C, 0xC23C0003, + 0x81C, 0xC13E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0xA1460003, + 0x81C, 0xA0480003, + 0x81C, 0x684A0003, + 0x81C, 0x674C0003, + 0x81C, 0x664E0003, + 0x81C, 0x65500003, + 0x81C, 0x64520003, + 0x81C, 0x63540003, + 0x81C, 0x44560003, + 0x81C, 0x43580003, + 0x81C, 0x425A0003, + 0x81C, 0x415C0003, + 0x81C, 0x405E0003, + 0x81C, 0x23600003, + 0x81C, 0x22620003, + 0x81C, 0x21640003, + 0x81C, 0x03660003, + 0x81C, 0x02680003, + 0x81C, 0x016A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFD000003, + 0x81C, 0xFC020003, + 0x81C, 0xFB040003, + 0x81C, 0xFA060003, + 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, + 0x81C, 0xF4120003, + 0x81C, 0xF3140003, + 0x81C, 0xF2160003, + 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, + 0x81C, 0xEC220003, + 0x81C, 0xEB240003, + 0x81C, 0xEA260003, + 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, + 0x81C, 0xC0420003, + 0x81C, 0xA5440003, + 0x81C, 0xA4460003, + 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x80540003, + 0x81C, 0x65560003, + 0x81C, 0x64580003, + 0x81C, 0x635A0003, + 0x81C, 0x625C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x40640003, + 0x81C, 0x06660003, + 0x81C, 0x05680003, + 0x81C, 0x046A0003, + 0x81C, 0x036C0003, + 0x81C, 0x026E0003, + 0x81C, 0x01700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xDC000003, + 0x81C, 0xDB020003, + 0x81C, 0xDA040003, + 0x81C, 0xD9060003, + 0x81C, 0xD8080003, + 0x81C, 0xD70A0003, + 0x81C, 0xD60C0003, + 0x81C, 0xD50E0003, + 0x81C, 0xD4100003, + 0x81C, 0xD3120003, + 0x81C, 0xD2140003, + 0x81C, 0xD1160003, + 0x81C, 0xD0180003, + 0x81C, 0xB41A0003, + 0x81C, 0xB31C0003, + 0x81C, 0xB21E0003, + 0x81C, 0xB1200003, + 0x81C, 0xB0220003, + 0x81C, 0xAF240003, + 0x81C, 0xAE260003, + 0x81C, 0xAD280003, + 0x81C, 0xAC2A0003, + 0x81C, 0xAB2C0003, + 0x81C, 0x8C2E0003, + 0x81C, 0x8B300003, + 0x81C, 0x8A320003, + 0x81C, 0x89340003, + 0x81C, 0x88360003, + 0x81C, 0x87380003, + 0x81C, 0x863A0003, + 0x81C, 0x853C0003, + 0x81C, 0x693E0003, + 0x81C, 0x68400003, + 0x81C, 0x67420003, + 0x81C, 0x66440003, + 0x81C, 0x65460003, + 0x81C, 0x48480003, + 0x81C, 0x474A0003, + 0x81C, 0x464C0003, + 0x81C, 0x454E0003, + 0x81C, 0x44500003, + 0x81C, 0x43520003, + 0x81C, 0x27540003, + 0x81C, 0x26560003, + 0x81C, 0x25580003, + 0x81C, 0x245A0003, + 0x81C, 0x235C0003, + 0x81C, 0x045E0003, + 0x81C, 0x03600003, + 0x81C, 0x02620003, + 0x81C, 0x01640003, + 0x81C, 0x00660003, + 0x81C, 0x00680003, + 0x81C, 0x006A0003, + 0x81C, 0x006C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xC8340003, + 0x81C, 0xC7360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xC0440003, + 0x81C, 0xA3460003, + 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, + 0x81C, 0x81500003, + 0x81C, 0x80520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x445A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x40620003, + 0x81C, 0x05640003, + 0x81C, 0x04660003, + 0x81C, 0x03680003, + 0x81C, 0x026A0003, + 0x81C, 0x016C0003, + 0x81C, 0x006E0003, + 0x81C, 0x00700003, + 0x81C, 0x00720003, + 0x81C, 0x00740003, + 0x81C, 0x00760003, + 0x81C, 0x00780003, + 0x81C, 0x007A0003, + 0x81C, 0x007C0003, + 0x81C, 0x007E0003, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xC5360103, + 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, + 0x81C, 0xC23C0103, + 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, + 0x81C, 0xA3420103, + 0x81C, 0xA2440103, + 0x81C, 0xA1460103, + 0x81C, 0x83480103, + 0x81C, 0x824A0103, + 0x81C, 0x814C0103, + 0x81C, 0x804E0103, + 0x81C, 0x63500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x43560103, + 0x81C, 0x42580103, + 0x81C, 0x415A0103, + 0x81C, 0x405C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, + 0x81C, 0xC1300103, + 0x81C, 0xC0320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x63420103, + 0x81C, 0x62440103, + 0x81C, 0x61460103, + 0x81C, 0x60480103, + 0x81C, 0x424A0103, + 0x81C, 0x414C0103, + 0x81C, 0x404E0103, + 0x81C, 0x06500103, + 0x81C, 0x05520103, + 0x81C, 0x04540103, + 0x81C, 0x03560103, + 0x81C, 0x02580103, + 0x81C, 0x015A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, + 0x81C, 0xC1300103, + 0x81C, 0xC0320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x63420103, + 0x81C, 0x62440103, + 0x81C, 0x61460103, + 0x81C, 0x60480103, + 0x81C, 0x424A0103, + 0x81C, 0x414C0103, + 0x81C, 0x404E0103, + 0x81C, 0x22500103, + 0x81C, 0x21520103, + 0x81C, 0x20540103, + 0x81C, 0x03560103, + 0x81C, 0x02580103, + 0x81C, 0x015A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000103, + 0x81C, 0xFD020103, + 0x81C, 0xFC040103, + 0x81C, 0xFB060103, + 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, + 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, + 0x81C, 0xF5120103, + 0x81C, 0xF4140103, + 0x81C, 0xF3160103, + 0x81C, 0xF2180103, + 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, + 0x81C, 0xEE200103, + 0x81C, 0xED220103, + 0x81C, 0xEC240103, + 0x81C, 0xEB260103, + 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, + 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, + 0x81C, 0xE5320103, + 0x81C, 0xE4340103, + 0x81C, 0xE3360103, + 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, + 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x605A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, + 0x81C, 0xC1300103, + 0x81C, 0xC0320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x63420103, + 0x81C, 0x62440103, + 0x81C, 0x61460103, + 0x81C, 0x60480103, + 0x81C, 0x424A0103, + 0x81C, 0x414C0103, + 0x81C, 0x404E0103, + 0x81C, 0x22500103, + 0x81C, 0x21520103, + 0x81C, 0x20540103, + 0x81C, 0x03560103, + 0x81C, 0x02580103, + 0x81C, 0x015A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, + 0x81C, 0xC33C0103, + 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x64500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x61560103, + 0x81C, 0x42580103, + 0x81C, 0x415A0103, + 0x81C, 0x405C0103, + 0x81C, 0x065E0103, + 0x81C, 0x05600103, + 0x81C, 0x04620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000103, + 0x81C, 0xF9020103, + 0x81C, 0xF8040103, + 0x81C, 0xF7060103, + 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, + 0x81C, 0xF40C0103, + 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, + 0x81C, 0xF1120103, + 0x81C, 0xF0140103, + 0x81C, 0xEF160103, + 0x81C, 0xEE180103, + 0x81C, 0xED1A0103, + 0x81C, 0xEC1C0103, + 0x81C, 0xEB1E0103, + 0x81C, 0xEA200103, + 0x81C, 0xE9220103, + 0x81C, 0xE8240103, + 0x81C, 0xE7260103, + 0x81C, 0xE6280103, + 0x81C, 0xE52A0103, + 0x81C, 0xC42C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0x833C0103, + 0x81C, 0x823E0103, + 0x81C, 0x81400103, + 0x81C, 0x63420103, + 0x81C, 0x62440103, + 0x81C, 0x61460103, + 0x81C, 0x60480103, + 0x81C, 0x424A0103, + 0x81C, 0x414C0103, + 0x81C, 0x404E0103, + 0x81C, 0x22500103, + 0x81C, 0x21520103, + 0x81C, 0x20540103, + 0x81C, 0x03560103, + 0x81C, 0x02580103, + 0x81C, 0x015A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x61480103, + 0x81C, 0x434A0103, + 0x81C, 0x424C0103, + 0x81C, 0x414E0103, + 0x81C, 0x40500103, + 0x81C, 0x22520103, + 0x81C, 0x21540103, + 0x81C, 0x20560103, + 0x81C, 0x04580103, + 0x81C, 0x035A0103, + 0x81C, 0x025C0103, + 0x81C, 0x015E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xC6360103, + 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, + 0x81C, 0xC33C0103, + 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x63500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x43560103, + 0x81C, 0x42580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x04620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x61480103, + 0x81C, 0x434A0103, + 0x81C, 0x424C0103, + 0x81C, 0x414E0103, + 0x81C, 0x40500103, + 0x81C, 0x22520103, + 0x81C, 0x21540103, + 0x81C, 0x20560103, + 0x81C, 0x04580103, + 0x81C, 0x035A0103, + 0x81C, 0x025C0103, + 0x81C, 0x015E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xC5360103, + 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, + 0x81C, 0xC23C0103, + 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, + 0x81C, 0xA3420103, + 0x81C, 0xA2440103, + 0x81C, 0xA1460103, + 0x81C, 0x83480103, + 0x81C, 0x824A0103, + 0x81C, 0x814C0103, + 0x81C, 0x804E0103, + 0x81C, 0x63500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x43560103, + 0x81C, 0x42580103, + 0x81C, 0x415A0103, + 0x81C, 0x405C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0xA03C0103, + 0x81C, 0x823E0103, + 0x81C, 0x81400103, + 0x81C, 0x80420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x61480103, + 0x81C, 0x604A0103, + 0x81C, 0x244C0103, + 0x81C, 0x234E0103, + 0x81C, 0x22500103, + 0x81C, 0x21520103, + 0x81C, 0x20540103, + 0x81C, 0x05560103, + 0x81C, 0x04580103, + 0x81C, 0x035A0103, + 0x81C, 0x025C0103, + 0x81C, 0x015E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000103, + 0x81C, 0xFD020103, + 0x81C, 0xFC040103, + 0x81C, 0xFB060103, + 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, + 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, + 0x81C, 0xF5120103, + 0x81C, 0xF4140103, + 0x81C, 0xF3160103, + 0x81C, 0xF2180103, + 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, + 0x81C, 0xEE200103, + 0x81C, 0xED220103, + 0x81C, 0xEC240103, + 0x81C, 0xEB260103, + 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, + 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, + 0x81C, 0xE5320103, + 0x81C, 0xE4340103, + 0x81C, 0xE3360103, + 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, + 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x605A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000103, + 0x81C, 0xFB020103, + 0x81C, 0xFA040103, + 0x81C, 0xF9060103, + 0x81C, 0xF8080103, + 0x81C, 0xF70A0103, + 0x81C, 0xF60C0103, + 0x81C, 0xF50E0103, + 0x81C, 0xF4100103, + 0x81C, 0xF3120103, + 0x81C, 0xF2140103, + 0x81C, 0xF1160103, + 0x81C, 0xF0180103, + 0x81C, 0xEE1A0103, + 0x81C, 0xED1C0103, + 0x81C, 0xEC1E0103, + 0x81C, 0xEB200103, + 0x81C, 0xEA220103, + 0x81C, 0xE9240103, + 0x81C, 0xE8260103, + 0x81C, 0xE7280103, + 0x81C, 0xE62A0103, + 0x81C, 0xE52C0103, + 0x81C, 0xE42E0103, + 0x81C, 0xE3300103, + 0x81C, 0xE2320103, + 0x81C, 0xE1340103, + 0x81C, 0xC5360103, + 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, + 0x81C, 0xC23C0103, + 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, + 0x81C, 0xA3420103, + 0x81C, 0xA2440103, + 0x81C, 0xA1460103, + 0x81C, 0x83480103, + 0x81C, 0x824A0103, + 0x81C, 0x814C0103, + 0x81C, 0x804E0103, + 0x81C, 0x63500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x43560103, + 0x81C, 0x42580103, + 0x81C, 0x415A0103, + 0x81C, 0x405C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xC5360103, + 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, + 0x81C, 0xC23C0103, + 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, + 0x81C, 0xA3420103, + 0x81C, 0xA2440103, + 0x81C, 0xA1460103, + 0x81C, 0x83480103, + 0x81C, 0x824A0103, + 0x81C, 0x814C0103, + 0x81C, 0x804E0103, + 0x81C, 0x63500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x43560103, + 0x81C, 0x42580103, + 0x81C, 0x415A0103, + 0x81C, 0x405C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000103, + 0x81C, 0xFB020103, + 0x81C, 0xFA040103, + 0x81C, 0xF9060103, + 0x81C, 0xF8080103, + 0x81C, 0xF70A0103, + 0x81C, 0xF60C0103, + 0x81C, 0xF50E0103, + 0x81C, 0xF4100103, + 0x81C, 0xF3120103, + 0x81C, 0xF2140103, + 0x81C, 0xF1160103, + 0x81C, 0xF0180103, + 0x81C, 0xEF1A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xE1360103, + 0x81C, 0xC3380103, + 0x81C, 0xC23A0103, + 0x81C, 0xC13C0103, + 0x81C, 0xC03E0103, + 0x81C, 0xA4400103, + 0x81C, 0xA3420103, + 0x81C, 0xA2440103, + 0x81C, 0xA1460103, + 0x81C, 0x82480103, + 0x81C, 0x814A0103, + 0x81C, 0x804C0103, + 0x81C, 0x634E0103, + 0x81C, 0x62500103, + 0x81C, 0x61520103, + 0x81C, 0x42540103, + 0x81C, 0x41560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x225C0103, + 0x81C, 0x215E0103, + 0x81C, 0x20600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000103, + 0x81C, 0xFD020103, + 0x81C, 0xFC040103, + 0x81C, 0xFB060103, + 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, + 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, + 0x81C, 0xF5120103, + 0x81C, 0xF4140103, + 0x81C, 0xF3160103, + 0x81C, 0xF2180103, + 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, + 0x81C, 0xEE200103, + 0x81C, 0xED220103, + 0x81C, 0xEC240103, + 0x81C, 0xEB260103, + 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, + 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, + 0x81C, 0xE5320103, + 0x81C, 0xE4340103, + 0x81C, 0xE3360103, + 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, + 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x605A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, + 0x81C, 0xC1300103, + 0x81C, 0xC0320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x80400103, + 0x81C, 0x63420103, + 0x81C, 0x62440103, + 0x81C, 0x61460103, + 0x81C, 0x60480103, + 0x81C, 0x424A0103, + 0x81C, 0x414C0103, + 0x81C, 0x404E0103, + 0x81C, 0x22500103, + 0x81C, 0x21520103, + 0x81C, 0x20540103, + 0x81C, 0x03560103, + 0x81C, 0x02580103, + 0x81C, 0x015A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0xA0000000, 0x00000000, + 0x81C, 0xFE000103, + 0x81C, 0xFD020103, + 0x81C, 0xFC040103, + 0x81C, 0xFB060103, + 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, + 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, + 0x81C, 0xF5120103, + 0x81C, 0xF4140103, + 0x81C, 0xF3160103, + 0x81C, 0xF2180103, + 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, + 0x81C, 0xEE200103, + 0x81C, 0xED220103, + 0x81C, 0xEC240103, + 0x81C, 0xEB260103, + 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, + 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, + 0x81C, 0xE5320103, + 0x81C, 0xE4340103, + 0x81C, 0xE3360103, + 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, + 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, + 0x81C, 0xA4420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x605A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x21600103, + 0x81C, 0x20620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xC6340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xA63C0203, + 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x83480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x804E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x42560203, + 0x81C, 0x41580203, + 0x81C, 0x405A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x63420203, + 0x81C, 0x62440203, + 0x81C, 0x61460203, + 0x81C, 0x60480203, + 0x81C, 0x424A0203, + 0x81C, 0x414C0203, + 0x81C, 0x404E0203, + 0x81C, 0x06500203, + 0x81C, 0x05520203, + 0x81C, 0x04540203, + 0x81C, 0x03560203, + 0x81C, 0x02580203, + 0x81C, 0x015A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x62460203, + 0x81C, 0x61480203, + 0x81C, 0x604A0203, + 0x81C, 0x414C0203, + 0x81C, 0x404E0203, + 0x81C, 0x22500203, + 0x81C, 0x21520203, + 0x81C, 0x20540203, + 0x81C, 0x03560203, + 0x81C, 0x02580203, + 0x81C, 0x015A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xC6360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, + 0x81C, 0xA4420203, + 0x81C, 0xA3440203, + 0x81C, 0xA2460203, + 0x81C, 0xA1480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x405A0203, + 0x81C, 0x215C0203, + 0x81C, 0x205E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x62460203, + 0x81C, 0x61480203, + 0x81C, 0x604A0203, + 0x81C, 0x414C0203, + 0x81C, 0x404E0203, + 0x81C, 0x22500203, + 0x81C, 0x21520203, + 0x81C, 0x20540203, + 0x81C, 0x03560203, + 0x81C, 0x02580203, + 0x81C, 0x015A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xC23E0203, + 0x81C, 0xC1400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0xA0480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x25580203, + 0x81C, 0x245A0203, + 0x81C, 0x235C0203, + 0x81C, 0x225E0203, + 0x81C, 0x21600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000203, + 0x81C, 0xF8020203, + 0x81C, 0xF7040203, + 0x81C, 0xF6060203, + 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, + 0x81C, 0xF30C0203, + 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, + 0x81C, 0xF0120203, + 0x81C, 0xEF140203, + 0x81C, 0xEE160203, + 0x81C, 0xED180203, + 0x81C, 0xEC1A0203, + 0x81C, 0xEB1C0203, + 0x81C, 0xEA1E0203, + 0x81C, 0xE9200203, + 0x81C, 0xE8220203, + 0x81C, 0xE7240203, + 0x81C, 0xE6260203, + 0x81C, 0xE5280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x62460203, + 0x81C, 0x61480203, + 0x81C, 0x604A0203, + 0x81C, 0x414C0203, + 0x81C, 0x404E0203, + 0x81C, 0x22500203, + 0x81C, 0x21520203, + 0x81C, 0x20540203, + 0x81C, 0x03560203, + 0x81C, 0x02580203, + 0x81C, 0x015A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, + 0x81C, 0xC2300203, + 0x81C, 0xC1320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x65420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x424C0203, + 0x81C, 0x414E0203, + 0x81C, 0x40500203, + 0x81C, 0x22520203, + 0x81C, 0x21540203, + 0x81C, 0x20560203, + 0x81C, 0x04580203, + 0x81C, 0x035A0203, + 0x81C, 0x025C0203, + 0x81C, 0x015E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000203, + 0x81C, 0xFA020203, + 0x81C, 0xF9040203, + 0x81C, 0xF8060203, + 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, + 0x81C, 0xF50C0203, + 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, + 0x81C, 0xF2120203, + 0x81C, 0xF1140203, + 0x81C, 0xF0160203, + 0x81C, 0xEF180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xC6340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xC23C0203, + 0x81C, 0xC13E0203, + 0x81C, 0xC0400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0xA0480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x804E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x60560203, + 0x81C, 0x24580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, + 0x81C, 0xC2300203, + 0x81C, 0xC1320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x65420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x424C0203, + 0x81C, 0x414E0203, + 0x81C, 0x40500203, + 0x81C, 0x22520203, + 0x81C, 0x21540203, + 0x81C, 0x20560203, + 0x81C, 0x04580203, + 0x81C, 0x035A0203, + 0x81C, 0x025C0203, + 0x81C, 0x015E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xC6340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xA63C0203, + 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x83480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x804E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x42560203, + 0x81C, 0x41580203, + 0x81C, 0x405A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000203, + 0x81C, 0xF8020203, + 0x81C, 0xF7040203, + 0x81C, 0xF6060203, + 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, + 0x81C, 0xF30C0203, + 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, + 0x81C, 0xF0120203, + 0x81C, 0xEF140203, + 0x81C, 0xEE160203, + 0x81C, 0xED180203, + 0x81C, 0xEC1A0203, + 0x81C, 0xEB1C0203, + 0x81C, 0xEA1E0203, + 0x81C, 0xE9200203, + 0x81C, 0xE8220203, + 0x81C, 0xE7240203, + 0x81C, 0xE6260203, + 0x81C, 0xE5280203, + 0x81C, 0xE42A0203, + 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, + 0x81C, 0xC2300203, + 0x81C, 0xC1320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x62460203, + 0x81C, 0x61480203, + 0x81C, 0x604A0203, + 0x81C, 0x244C0203, + 0x81C, 0x234E0203, + 0x81C, 0x22500203, + 0x81C, 0x21520203, + 0x81C, 0x20540203, + 0x81C, 0x05560203, + 0x81C, 0x04580203, + 0x81C, 0x035A0203, + 0x81C, 0x025C0203, + 0x81C, 0x015E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xC6360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, + 0x81C, 0xA4420203, + 0x81C, 0xA3440203, + 0x81C, 0xA2460203, + 0x81C, 0xA1480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x405A0203, + 0x81C, 0x215C0203, + 0x81C, 0x205E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xC6340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xA63C0203, + 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x83480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x804E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x42560203, + 0x81C, 0x41580203, + 0x81C, 0x405A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xC6340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xA63C0203, + 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x83480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x804E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x42560203, + 0x81C, 0x41580203, + 0x81C, 0x405A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xE0380203, + 0x81C, 0xC33A0203, + 0x81C, 0xC23C0203, + 0x81C, 0xC13E0203, + 0x81C, 0xA3400203, + 0x81C, 0xA2420203, + 0x81C, 0xA1440203, + 0x81C, 0xA0460203, + 0x81C, 0x83480203, + 0x81C, 0x824A0203, + 0x81C, 0x814C0203, + 0x81C, 0x644E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x42560203, + 0x81C, 0x41580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xC6360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, + 0x81C, 0xA4420203, + 0x81C, 0xA3440203, + 0x81C, 0xA2460203, + 0x81C, 0xA1480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x405A0203, + 0x81C, 0x215C0203, + 0x81C, 0x205E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x823C0203, + 0x81C, 0x813E0203, + 0x81C, 0x80400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x62460203, + 0x81C, 0x61480203, + 0x81C, 0x604A0203, + 0x81C, 0x414C0203, + 0x81C, 0x404E0203, + 0x81C, 0x22500203, + 0x81C, 0x21520203, + 0x81C, 0x20540203, + 0x81C, 0x03560203, + 0x81C, 0x02580203, + 0x81C, 0x015A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000203, + 0x81C, 0xFC020203, + 0x81C, 0xFB040203, + 0x81C, 0xFA060203, + 0x81C, 0xF9080203, + 0x81C, 0xF80A0203, + 0x81C, 0xF70C0203, + 0x81C, 0xF60E0203, + 0x81C, 0xF5100203, + 0x81C, 0xF4120203, + 0x81C, 0xF3140203, + 0x81C, 0xF2160203, + 0x81C, 0xF1180203, + 0x81C, 0xF01A0203, + 0x81C, 0xEF1C0203, + 0x81C, 0xEE1E0203, + 0x81C, 0xED200203, + 0x81C, 0xEC220203, + 0x81C, 0xEB240203, + 0x81C, 0xEA260203, + 0x81C, 0xE9280203, + 0x81C, 0xE82A0203, + 0x81C, 0xE72C0203, + 0x81C, 0xE62E0203, + 0x81C, 0xE5300203, + 0x81C, 0xE4320203, + 0x81C, 0xE3340203, + 0x81C, 0xC6360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, + 0x81C, 0xA4420203, + 0x81C, 0xA3440203, + 0x81C, 0xA2460203, + 0x81C, 0xA1480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x20600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xC6340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xA63C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x42560303, + 0x81C, 0x41580303, + 0x81C, 0x405A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xCA1E0303, + 0x81C, 0xC9200303, + 0x81C, 0xC8220303, + 0x81C, 0xC7240303, + 0x81C, 0xC6260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xC1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x414C0303, + 0x81C, 0x404E0303, + 0x81C, 0x06500303, + 0x81C, 0x05520303, + 0x81C, 0x04540303, + 0x81C, 0x03560303, + 0x81C, 0x02580303, + 0x81C, 0x015A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xCA1E0303, + 0x81C, 0xC9200303, + 0x81C, 0xC8220303, + 0x81C, 0xC7240303, + 0x81C, 0xC6260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xC1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x414C0303, + 0x81C, 0x404E0303, + 0x81C, 0x22500303, + 0x81C, 0x21520303, + 0x81C, 0x20540303, + 0x81C, 0x03560303, + 0x81C, 0x02580303, + 0x81C, 0x015A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xC6360303, + 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, + 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x80500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x60580303, + 0x81C, 0x225A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xCA1E0303, + 0x81C, 0xC9200303, + 0x81C, 0xC8220303, + 0x81C, 0xC7240303, + 0x81C, 0xC6260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xC1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x414C0303, + 0x81C, 0x404E0303, + 0x81C, 0x22500303, + 0x81C, 0x21520303, + 0x81C, 0x20540303, + 0x81C, 0x03560303, + 0x81C, 0x02580303, + 0x81C, 0x015A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xC23C0303, + 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x60580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000303, + 0x81C, 0xF8020303, + 0x81C, 0xF7040303, + 0x81C, 0xF6060303, + 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, + 0x81C, 0xF30C0303, + 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, + 0x81C, 0xF0120303, + 0x81C, 0xEF140303, + 0x81C, 0xEE160303, + 0x81C, 0xED180303, + 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, + 0x81C, 0xEA1E0303, + 0x81C, 0xC9200303, + 0x81C, 0xC8220303, + 0x81C, 0xC7240303, + 0x81C, 0xC6260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xC1300303, + 0x81C, 0xC0320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x414C0303, + 0x81C, 0x404E0303, + 0x81C, 0x22500303, + 0x81C, 0x21520303, + 0x81C, 0x20540303, + 0x81C, 0x03560303, + 0x81C, 0x02580303, + 0x81C, 0x015A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000303, + 0x81C, 0xF7020303, + 0x81C, 0xF6040303, + 0x81C, 0xF5060303, + 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, + 0x81C, 0xF20C0303, + 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, + 0x81C, 0xEF120303, + 0x81C, 0xEE140303, + 0x81C, 0xED160303, + 0x81C, 0xEC180303, + 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, + 0x81C, 0xE91E0303, + 0x81C, 0xCA200303, + 0x81C, 0xC9220303, + 0x81C, 0xC8240303, + 0x81C, 0xC7260303, + 0x81C, 0xC6280303, + 0x81C, 0xC52A0303, + 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, + 0x81C, 0xC2300303, + 0x81C, 0xC1320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x65420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x424C0303, + 0x81C, 0x414E0303, + 0x81C, 0x40500303, + 0x81C, 0x22520303, + 0x81C, 0x21540303, + 0x81C, 0x20560303, + 0x81C, 0x04580303, + 0x81C, 0x035A0303, + 0x81C, 0x025C0303, + 0x81C, 0x015E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xC6340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xC23C0303, + 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x43540303, + 0x81C, 0x42560303, + 0x81C, 0x41580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000303, + 0x81C, 0xF7020303, + 0x81C, 0xF6040303, + 0x81C, 0xF5060303, + 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, + 0x81C, 0xF20C0303, + 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, + 0x81C, 0xEF120303, + 0x81C, 0xEE140303, + 0x81C, 0xED160303, + 0x81C, 0xEC180303, + 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, + 0x81C, 0xE91E0303, + 0x81C, 0xCA200303, + 0x81C, 0xC9220303, + 0x81C, 0xC8240303, + 0x81C, 0xC7260303, + 0x81C, 0xC6280303, + 0x81C, 0xC52A0303, + 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, + 0x81C, 0xC2300303, + 0x81C, 0xC1320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x65420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x424C0303, + 0x81C, 0x414E0303, + 0x81C, 0x40500303, + 0x81C, 0x22520303, + 0x81C, 0x21540303, + 0x81C, 0x20560303, + 0x81C, 0x04580303, + 0x81C, 0x035A0303, + 0x81C, 0x025C0303, + 0x81C, 0x015E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xC6340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xA63C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x42560303, + 0x81C, 0x41580303, + 0x81C, 0x405A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000303, + 0x81C, 0xF7020303, + 0x81C, 0xF6040303, + 0x81C, 0xF5060303, + 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, + 0x81C, 0xF20C0303, + 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, + 0x81C, 0xEF120303, + 0x81C, 0xEE140303, + 0x81C, 0xED160303, + 0x81C, 0xEC180303, + 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, + 0x81C, 0xE91E0303, + 0x81C, 0xCA200303, + 0x81C, 0xC9220303, + 0x81C, 0xC8240303, + 0x81C, 0xC7260303, + 0x81C, 0xC6280303, + 0x81C, 0xC52A0303, + 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, + 0x81C, 0xC2300303, + 0x81C, 0xC1320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x234C0303, + 0x81C, 0x224E0303, + 0x81C, 0x21500303, + 0x81C, 0x20520303, + 0x81C, 0x06540303, + 0x81C, 0x05560303, + 0x81C, 0x04580303, + 0x81C, 0x035A0303, + 0x81C, 0x025C0303, + 0x81C, 0x015E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xC6360303, + 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, + 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x80500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x60580303, + 0x81C, 0x225A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xEF160303, + 0x81C, 0xEE180303, + 0x81C, 0xED1A0303, + 0x81C, 0xEC1C0303, + 0x81C, 0xEB1E0303, + 0x81C, 0xEA200303, + 0x81C, 0xE9220303, + 0x81C, 0xE8240303, + 0x81C, 0xE7260303, + 0x81C, 0xE6280303, + 0x81C, 0xE52A0303, + 0x81C, 0xE42C0303, + 0x81C, 0xE32E0303, + 0x81C, 0xE2300303, + 0x81C, 0xE1320303, + 0x81C, 0xC6340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xA63C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x42560303, + 0x81C, 0x41580303, + 0x81C, 0x405A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xEF160303, + 0x81C, 0xEE180303, + 0x81C, 0xED1A0303, + 0x81C, 0xEC1C0303, + 0x81C, 0xEB1E0303, + 0x81C, 0xEA200303, + 0x81C, 0xE9220303, + 0x81C, 0xE8240303, + 0x81C, 0xE7260303, + 0x81C, 0xE6280303, + 0x81C, 0xE52A0303, + 0x81C, 0xE42C0303, + 0x81C, 0xE32E0303, + 0x81C, 0xE2300303, + 0x81C, 0xE1320303, + 0x81C, 0xC6340303, + 0x81C, 0xC5360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xA63C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x804E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x42560303, + 0x81C, 0x41580303, + 0x81C, 0x405A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xE0360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xC03E0303, + 0x81C, 0xA3400303, + 0x81C, 0xA2420303, + 0x81C, 0xA1440303, + 0x81C, 0xA0460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x644E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x225A0303, + 0x81C, 0x215C0303, + 0x81C, 0x055E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xC6360303, + 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, + 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x80500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x60580303, + 0x81C, 0x225A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xCA1E0303, + 0x81C, 0xC9200303, + 0x81C, 0xC8220303, + 0x81C, 0xC7240303, + 0x81C, 0xC6260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xC1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x813E0303, + 0x81C, 0x80400303, + 0x81C, 0x64420303, + 0x81C, 0x63440303, + 0x81C, 0x62460303, + 0x81C, 0x61480303, + 0x81C, 0x604A0303, + 0x81C, 0x414C0303, + 0x81C, 0x404E0303, + 0x81C, 0x22500303, + 0x81C, 0x21520303, + 0x81C, 0x20540303, + 0x81C, 0x03560303, + 0x81C, 0x02580303, + 0x81C, 0x015A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xC6360303, + 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, + 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x80500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x60580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x20600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF5000403, + 0x81C, 0xF4020403, + 0x81C, 0xF3040403, + 0x81C, 0xF2060403, + 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, + 0x81C, 0xEC120403, + 0x81C, 0xEB140403, + 0x81C, 0xEA160403, + 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, + 0x81C, 0xE4220403, + 0x81C, 0xE3240403, + 0x81C, 0xE2260403, + 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, + 0x81C, 0xC0320403, + 0x81C, 0xA4340403, + 0x81C, 0xA3360403, + 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, + 0x81C, 0x81400403, + 0x81C, 0x80420403, + 0x81C, 0x64440403, + 0x81C, 0x63460403, + 0x81C, 0x62480403, + 0x81C, 0x614A0403, + 0x81C, 0x604C0403, + 0x81C, 0x454E0403, + 0x81C, 0x44500403, + 0x81C, 0x43520403, + 0x81C, 0x42540403, + 0x81C, 0x41560403, + 0x81C, 0x40580403, + 0x81C, 0x055A0403, + 0x81C, 0x045C0403, + 0x81C, 0x035E0403, + 0x81C, 0x02600403, + 0x81C, 0x01620403, + 0x81C, 0x00640403, + 0x81C, 0x00660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF6000403, + 0x81C, 0xF5020403, + 0x81C, 0xF4040403, + 0x81C, 0xF3060403, + 0x81C, 0xF2080403, + 0x81C, 0xF10A0403, + 0x81C, 0xF00C0403, + 0x81C, 0xEF0E0403, + 0x81C, 0xD6100403, + 0x81C, 0xD5120403, + 0x81C, 0xD4140403, + 0x81C, 0xD3160403, + 0x81C, 0xD2180403, + 0x81C, 0xD11A0403, + 0x81C, 0xD01C0403, + 0x81C, 0xCF1E0403, + 0x81C, 0x95200403, + 0x81C, 0x94220403, + 0x81C, 0x93240403, + 0x81C, 0x92260403, + 0x81C, 0x91280403, + 0x81C, 0x902A0403, + 0x81C, 0x8F2C0403, + 0x81C, 0x8E2E0403, + 0x81C, 0x8D300403, + 0x81C, 0x8C320403, + 0x81C, 0x8B340403, + 0x81C, 0x8A360403, + 0x81C, 0x89380403, + 0x81C, 0x883A0403, + 0x81C, 0x873C0403, + 0x81C, 0x863E0403, + 0x81C, 0x68400403, + 0x81C, 0x67420403, + 0x81C, 0x66440403, + 0x81C, 0x65460403, + 0x81C, 0x64480403, + 0x81C, 0x634A0403, + 0x81C, 0x484C0403, + 0x81C, 0x474E0403, + 0x81C, 0x46500403, + 0x81C, 0x45520403, + 0x81C, 0x44540403, + 0x81C, 0x27560403, + 0x81C, 0x26580403, + 0x81C, 0x255A0403, + 0x81C, 0x245C0403, + 0x81C, 0x235E0403, + 0x81C, 0x04600403, + 0x81C, 0x03620403, + 0x81C, 0x02640403, + 0x81C, 0x01660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF5000403, + 0x81C, 0xF4020403, + 0x81C, 0xF3040403, + 0x81C, 0xF2060403, + 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, + 0x81C, 0xEC120403, + 0x81C, 0xEB140403, + 0x81C, 0xEA160403, + 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, + 0x81C, 0xE4220403, + 0x81C, 0xE3240403, + 0x81C, 0xE2260403, + 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, + 0x81C, 0xC0320403, + 0x81C, 0xA4340403, + 0x81C, 0xA3360403, + 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, + 0x81C, 0x81400403, + 0x81C, 0x80420403, + 0x81C, 0x64440403, + 0x81C, 0x63460403, + 0x81C, 0x62480403, + 0x81C, 0x614A0403, + 0x81C, 0x604C0403, + 0x81C, 0x454E0403, + 0x81C, 0x44500403, + 0x81C, 0x43520403, + 0x81C, 0x42540403, + 0x81C, 0x41560403, + 0x81C, 0x40580403, + 0x81C, 0x055A0403, + 0x81C, 0x045C0403, + 0x81C, 0x035E0403, + 0x81C, 0x02600403, + 0x81C, 0x01620403, + 0x81C, 0x00640403, + 0x81C, 0x00660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF5000403, + 0x81C, 0xF4020403, + 0x81C, 0xF3040403, + 0x81C, 0xF2060403, + 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, + 0x81C, 0xEC120403, + 0x81C, 0xEB140403, + 0x81C, 0xEA160403, + 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, + 0x81C, 0xE4220403, + 0x81C, 0xE3240403, + 0x81C, 0xE2260403, + 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, + 0x81C, 0xC0320403, + 0x81C, 0xA4340403, + 0x81C, 0xA3360403, + 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, + 0x81C, 0x81400403, + 0x81C, 0x80420403, + 0x81C, 0x64440403, + 0x81C, 0x63460403, + 0x81C, 0x62480403, + 0x81C, 0x614A0403, + 0x81C, 0x604C0403, + 0x81C, 0x454E0403, + 0x81C, 0x44500403, + 0x81C, 0x43520403, + 0x81C, 0x42540403, + 0x81C, 0x41560403, + 0x81C, 0x40580403, + 0x81C, 0x055A0403, + 0x81C, 0x045C0403, + 0x81C, 0x035E0403, + 0x81C, 0x02600403, + 0x81C, 0x01620403, + 0x81C, 0x00640403, + 0x81C, 0x00660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF5000403, + 0x81C, 0xF4020403, + 0x81C, 0xF3040403, + 0x81C, 0xF2060403, + 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, + 0x81C, 0xEC120403, + 0x81C, 0xEB140403, + 0x81C, 0xEA160403, + 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, + 0x81C, 0xE4220403, + 0x81C, 0xE3240403, + 0x81C, 0xE2260403, + 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, + 0x81C, 0xC0320403, + 0x81C, 0xA4340403, + 0x81C, 0xA3360403, + 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, + 0x81C, 0x81400403, + 0x81C, 0x80420403, + 0x81C, 0x64440403, + 0x81C, 0x63460403, + 0x81C, 0x62480403, + 0x81C, 0x614A0403, + 0x81C, 0x604C0403, + 0x81C, 0x454E0403, + 0x81C, 0x44500403, + 0x81C, 0x43520403, + 0x81C, 0x42540403, + 0x81C, 0x41560403, + 0x81C, 0x40580403, + 0x81C, 0x055A0403, + 0x81C, 0x045C0403, + 0x81C, 0x035E0403, + 0x81C, 0x02600403, + 0x81C, 0x01620403, + 0x81C, 0x00640403, + 0x81C, 0x00660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF5000403, + 0x81C, 0xF4020403, + 0x81C, 0xF3040403, + 0x81C, 0xF2060403, + 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, + 0x81C, 0xEC120403, + 0x81C, 0xEB140403, + 0x81C, 0xEA160403, + 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, + 0x81C, 0xE4220403, + 0x81C, 0xE3240403, + 0x81C, 0xE2260403, + 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, + 0x81C, 0xC0320403, + 0x81C, 0xA4340403, + 0x81C, 0xA3360403, + 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, + 0x81C, 0x81400403, + 0x81C, 0x80420403, + 0x81C, 0x64440403, + 0x81C, 0x63460403, + 0x81C, 0x62480403, + 0x81C, 0x614A0403, + 0x81C, 0x604C0403, + 0x81C, 0x454E0403, + 0x81C, 0x44500403, + 0x81C, 0x43520403, + 0x81C, 0x42540403, + 0x81C, 0x41560403, + 0x81C, 0x40580403, + 0x81C, 0x055A0403, + 0x81C, 0x045C0403, + 0x81C, 0x035E0403, + 0x81C, 0x02600403, + 0x81C, 0x01620403, + 0x81C, 0x00640403, + 0x81C, 0x00660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xF6000403, + 0x81C, 0xF5020403, + 0x81C, 0xF4040403, + 0x81C, 0xF3060403, + 0x81C, 0xF2080403, + 0x81C, 0xF10A0403, + 0x81C, 0xF00C0403, + 0x81C, 0xEF0E0403, + 0x81C, 0xD6100403, + 0x81C, 0xD5120403, + 0x81C, 0xD4140403, + 0x81C, 0xD3160403, + 0x81C, 0xD2180403, + 0x81C, 0xD11A0403, + 0x81C, 0xD01C0403, + 0x81C, 0xCF1E0403, + 0x81C, 0x95200403, + 0x81C, 0x94220403, + 0x81C, 0x93240403, + 0x81C, 0x92260403, + 0x81C, 0x91280403, + 0x81C, 0x902A0403, + 0x81C, 0x8F2C0403, + 0x81C, 0x8E2E0403, + 0x81C, 0x8D300403, + 0x81C, 0x8C320403, + 0x81C, 0x8B340403, + 0x81C, 0x8A360403, + 0x81C, 0x89380403, + 0x81C, 0x883A0403, + 0x81C, 0x873C0403, + 0x81C, 0x863E0403, + 0x81C, 0x68400403, + 0x81C, 0x67420403, + 0x81C, 0x66440403, + 0x81C, 0x65460403, + 0x81C, 0x64480403, + 0x81C, 0x634A0403, + 0x81C, 0x484C0403, + 0x81C, 0x474E0403, + 0x81C, 0x46500403, + 0x81C, 0x45520403, + 0x81C, 0x44540403, + 0x81C, 0x27560403, + 0x81C, 0x26580403, + 0x81C, 0x255A0403, + 0x81C, 0x245C0403, + 0x81C, 0x235E0403, + 0x81C, 0x04600403, + 0x81C, 0x03620403, + 0x81C, 0x02640403, + 0x81C, 0x01660403, + 0x81C, 0x00680403, + 0x81C, 0x006A0403, + 0x81C, 0x006C0403, + 0x81C, 0x006E0403, + 0x81C, 0x00700403, + 0x81C, 0x00720403, + 0x81C, 0x00740403, + 0x81C, 0x00760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000403, + 0x81C, 0xFF000403, + 0x81C, 0xFF020403, + 0x81C, 0xFE040403, + 0x81C, 0xFD060403, + 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, + 0x81C, 0xF7120403, + 0x81C, 0xF6140403, + 0x81C, 0xF5160403, + 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, + 0x81C, 0xD3220403, + 0x81C, 0xD2240403, + 0x81C, 0xB6260403, + 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, + 0x81C, 0xB0320403, + 0x81C, 0xAF340403, + 0x81C, 0xAE360403, + 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, + 0x81C, 0xA8420403, + 0x81C, 0xA7440403, + 0x81C, 0xA6460403, + 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, + 0x81C, 0x84500403, + 0x81C, 0x83520403, + 0x81C, 0x82540403, + 0x81C, 0x81560403, + 0x81C, 0x80580403, + 0x81C, 0x485A0403, + 0x81C, 0x475C0403, + 0x81C, 0x465E0403, + 0x81C, 0x45600403, + 0x81C, 0x44620403, + 0x81C, 0x0A640403, + 0x81C, 0x09660403, + 0x81C, 0x08680403, + 0x81C, 0x076A0403, + 0x81C, 0x066C0403, + 0x81C, 0x056E0403, + 0x81C, 0x04700403, + 0x81C, 0x03720403, + 0x81C, 0x02740403, + 0x81C, 0x01760403, + 0x81C, 0x00780403, + 0x81C, 0x007A0403, + 0x81C, 0x007C0403, + 0x81C, 0x007E0403, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEE1C0503, + 0x81C, 0xED1E0503, + 0x81C, 0xEC200503, + 0x81C, 0xEB220503, + 0x81C, 0xEA240503, + 0x81C, 0xE9260503, + 0x81C, 0xE8280503, + 0x81C, 0xE72A0503, + 0x81C, 0xE62C0503, + 0x81C, 0xE52E0503, + 0x81C, 0xE4300503, + 0x81C, 0xE3320503, + 0x81C, 0xE2340503, + 0x81C, 0xC5360503, + 0x81C, 0xC4380503, + 0x81C, 0xC33A0503, + 0x81C, 0xC23C0503, + 0x81C, 0xA53E0503, + 0x81C, 0xA4400503, + 0x81C, 0xA3420503, + 0x81C, 0xA2440503, + 0x81C, 0xA1460503, + 0x81C, 0x83480503, + 0x81C, 0x824A0503, + 0x81C, 0x814C0503, + 0x81C, 0x804E0503, + 0x81C, 0x63500503, + 0x81C, 0x62520503, + 0x81C, 0x61540503, + 0x81C, 0x43560503, + 0x81C, 0x42580503, + 0x81C, 0x415A0503, + 0x81C, 0x405C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBE000503, + 0x81C, 0xBD020503, + 0x81C, 0xBC040503, + 0x81C, 0xBB060503, + 0x81C, 0xBA080503, + 0x81C, 0xB90A0503, + 0x81C, 0xB80C0503, + 0x81C, 0xB70E0503, + 0x81C, 0xB6100503, + 0x81C, 0xB5120503, + 0x81C, 0xB4140503, + 0x81C, 0xB3160503, + 0x81C, 0xB2180503, + 0x81C, 0xB11A0503, + 0x81C, 0xB01C0503, + 0x81C, 0xAF1E0503, + 0x81C, 0xAE200503, + 0x81C, 0xAD220503, + 0x81C, 0xAC240503, + 0x81C, 0xAB260503, + 0x81C, 0x8D280503, + 0x81C, 0x8C2A0503, + 0x81C, 0x8B2C0503, + 0x81C, 0x8A2E0503, + 0x81C, 0x89300503, + 0x81C, 0x88320503, + 0x81C, 0x6A340503, + 0x81C, 0x69360503, + 0x81C, 0x68380503, + 0x81C, 0x673A0503, + 0x81C, 0x663C0503, + 0x81C, 0x653E0503, + 0x81C, 0x64400503, + 0x81C, 0x63420503, + 0x81C, 0x62440503, + 0x81C, 0x61460503, + 0x81C, 0x60480503, + 0x81C, 0x424A0503, + 0x81C, 0x414C0503, + 0x81C, 0x404E0503, + 0x81C, 0x06500503, + 0x81C, 0x05520503, + 0x81C, 0x04540503, + 0x81C, 0x03560503, + 0x81C, 0x02580503, + 0x81C, 0x015A0503, + 0x81C, 0x005C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007C0503, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000503, + 0x81C, 0xF7020503, + 0x81C, 0xF6040503, + 0x81C, 0xF5060503, + 0x81C, 0xF4080503, + 0x81C, 0xF30A0503, + 0x81C, 0xF20C0503, + 0x81C, 0xF10E0503, + 0x81C, 0xF0100503, + 0x81C, 0xEF120503, + 0x81C, 0xEE140503, + 0x81C, 0xED160503, + 0x81C, 0xEC180503, + 0x81C, 0xEB1A0503, + 0x81C, 0xEA1C0503, + 0x81C, 0xE91E0503, + 0x81C, 0xE8200503, + 0x81C, 0xE7220503, + 0x81C, 0xE6240503, + 0x81C, 0xE5260503, + 0x81C, 0xE4280503, + 0x81C, 0xE32A0503, + 0x81C, 0xC32C0503, + 0x81C, 0xC22E0503, + 0x81C, 0xC1300503, + 0x81C, 0xC0320503, + 0x81C, 0xA3340503, + 0x81C, 0xA2360503, + 0x81C, 0xA1380503, + 0x81C, 0xA03A0503, + 0x81C, 0x823C0503, + 0x81C, 0x813E0503, + 0x81C, 0x80400503, + 0x81C, 0x63420503, + 0x81C, 0x62440503, + 0x81C, 0x61460503, + 0x81C, 0x60480503, + 0x81C, 0x424A0503, + 0x81C, 0x414C0503, + 0x81C, 0x404E0503, + 0x81C, 0x22500503, + 0x81C, 0x21520503, + 0x81C, 0x20540503, + 0x81C, 0x03560503, + 0x81C, 0x02580503, + 0x81C, 0x015A0503, + 0x81C, 0x005C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000503, + 0x81C, 0xFD020503, + 0x81C, 0xFC040503, + 0x81C, 0xFB060503, + 0x81C, 0xFA080503, + 0x81C, 0xF90A0503, + 0x81C, 0xF80C0503, + 0x81C, 0xF70E0503, + 0x81C, 0xF6100503, + 0x81C, 0xF5120503, + 0x81C, 0xF4140503, + 0x81C, 0xF3160503, + 0x81C, 0xF2180503, + 0x81C, 0xF11A0503, + 0x81C, 0xF01C0503, + 0x81C, 0xEF1E0503, + 0x81C, 0xEE200503, + 0x81C, 0xED220503, + 0x81C, 0xEC240503, + 0x81C, 0xEB260503, + 0x81C, 0xEA280503, + 0x81C, 0xE92A0503, + 0x81C, 0xE82C0503, + 0x81C, 0xE72E0503, + 0x81C, 0xE6300503, + 0x81C, 0xE5320503, + 0x81C, 0xE4340503, + 0x81C, 0xE3360503, + 0x81C, 0xC6380503, + 0x81C, 0xC53A0503, + 0x81C, 0xC43C0503, + 0x81C, 0xC33E0503, + 0x81C, 0xA5400503, + 0x81C, 0xA4420503, + 0x81C, 0xA3440503, + 0x81C, 0xA2460503, + 0x81C, 0xA1480503, + 0x81C, 0xA04A0503, + 0x81C, 0x824C0503, + 0x81C, 0x814E0503, + 0x81C, 0x80500503, + 0x81C, 0x64520503, + 0x81C, 0x63540503, + 0x81C, 0x62560503, + 0x81C, 0x61580503, + 0x81C, 0x605A0503, + 0x81C, 0x235C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000503, + 0x81C, 0xF7020503, + 0x81C, 0xF6040503, + 0x81C, 0xF5060503, + 0x81C, 0xF4080503, + 0x81C, 0xF30A0503, + 0x81C, 0xF20C0503, + 0x81C, 0xF10E0503, + 0x81C, 0xF0100503, + 0x81C, 0xEF120503, + 0x81C, 0xEE140503, + 0x81C, 0xED160503, + 0x81C, 0xEC180503, + 0x81C, 0xEB1A0503, + 0x81C, 0xEA1C0503, + 0x81C, 0xE91E0503, + 0x81C, 0xE8200503, + 0x81C, 0xE7220503, + 0x81C, 0xE6240503, + 0x81C, 0xE5260503, + 0x81C, 0xE4280503, + 0x81C, 0xE32A0503, + 0x81C, 0xC32C0503, + 0x81C, 0xC22E0503, + 0x81C, 0xC1300503, + 0x81C, 0xC0320503, + 0x81C, 0xA3340503, + 0x81C, 0xA2360503, + 0x81C, 0xA1380503, + 0x81C, 0xA03A0503, + 0x81C, 0x823C0503, + 0x81C, 0x813E0503, + 0x81C, 0x80400503, + 0x81C, 0x63420503, + 0x81C, 0x62440503, + 0x81C, 0x61460503, + 0x81C, 0x60480503, + 0x81C, 0x424A0503, + 0x81C, 0x414C0503, + 0x81C, 0x404E0503, + 0x81C, 0x22500503, + 0x81C, 0x21520503, + 0x81C, 0x20540503, + 0x81C, 0x03560503, + 0x81C, 0x02580503, + 0x81C, 0x015A0503, + 0x81C, 0x005C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEF1C0503, + 0x81C, 0xEE1E0503, + 0x81C, 0xED200503, + 0x81C, 0xEC220503, + 0x81C, 0xEB240503, + 0x81C, 0xEA260503, + 0x81C, 0xE9280503, + 0x81C, 0xE82A0503, + 0x81C, 0xE72C0503, + 0x81C, 0xE62E0503, + 0x81C, 0xE5300503, + 0x81C, 0xE4320503, + 0x81C, 0xE3340503, + 0x81C, 0xE2360503, + 0x81C, 0xC5380503, + 0x81C, 0xC43A0503, + 0x81C, 0xC33C0503, + 0x81C, 0xC23E0503, + 0x81C, 0xA5400503, + 0x81C, 0xA4420503, + 0x81C, 0xA3440503, + 0x81C, 0xA2460503, + 0x81C, 0xA1480503, + 0x81C, 0x834A0503, + 0x81C, 0x824C0503, + 0x81C, 0x814E0503, + 0x81C, 0x64500503, + 0x81C, 0x63520503, + 0x81C, 0x62540503, + 0x81C, 0x61560503, + 0x81C, 0x42580503, + 0x81C, 0x415A0503, + 0x81C, 0x405C0503, + 0x81C, 0x065E0503, + 0x81C, 0x05600503, + 0x81C, 0x04620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000503, + 0x81C, 0xF9020503, + 0x81C, 0xF8040503, + 0x81C, 0xF7060503, + 0x81C, 0xF6080503, + 0x81C, 0xF50A0503, + 0x81C, 0xF40C0503, + 0x81C, 0xF30E0503, + 0x81C, 0xF2100503, + 0x81C, 0xF1120503, + 0x81C, 0xF0140503, + 0x81C, 0xEF160503, + 0x81C, 0xEE180503, + 0x81C, 0xED1A0503, + 0x81C, 0xEC1C0503, + 0x81C, 0xEB1E0503, + 0x81C, 0xEA200503, + 0x81C, 0xE9220503, + 0x81C, 0xE8240503, + 0x81C, 0xE7260503, + 0x81C, 0xE6280503, + 0x81C, 0xE52A0503, + 0x81C, 0xC42C0503, + 0x81C, 0xC32E0503, + 0x81C, 0xC2300503, + 0x81C, 0xC1320503, + 0x81C, 0xA4340503, + 0x81C, 0xA3360503, + 0x81C, 0xA2380503, + 0x81C, 0xA13A0503, + 0x81C, 0x833C0503, + 0x81C, 0x823E0503, + 0x81C, 0x81400503, + 0x81C, 0x63420503, + 0x81C, 0x62440503, + 0x81C, 0x61460503, + 0x81C, 0x60480503, + 0x81C, 0x424A0503, + 0x81C, 0x414C0503, + 0x81C, 0x404E0503, + 0x81C, 0x22500503, + 0x81C, 0x21520503, + 0x81C, 0x20540503, + 0x81C, 0x03560503, + 0x81C, 0x02580503, + 0x81C, 0x015A0503, + 0x81C, 0x005C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBF000503, + 0x81C, 0xBE020503, + 0x81C, 0xBD040503, + 0x81C, 0xBC060503, + 0x81C, 0xBB080503, + 0x81C, 0xBA0A0503, + 0x81C, 0xB90C0503, + 0x81C, 0xB80E0503, + 0x81C, 0xB7100503, + 0x81C, 0xB6120503, + 0x81C, 0xB5140503, + 0x81C, 0xB4160503, + 0x81C, 0xB3180503, + 0x81C, 0xB21A0503, + 0x81C, 0xB11C0503, + 0x81C, 0x931E0503, + 0x81C, 0x92200503, + 0x81C, 0x91220503, + 0x81C, 0x90240503, + 0x81C, 0x8F260503, + 0x81C, 0x8E280503, + 0x81C, 0x8D2A0503, + 0x81C, 0x8C2C0503, + 0x81C, 0x8B2E0503, + 0x81C, 0x8A300503, + 0x81C, 0x89320503, + 0x81C, 0x88340503, + 0x81C, 0x6A360503, + 0x81C, 0x69380503, + 0x81C, 0x683A0503, + 0x81C, 0x673C0503, + 0x81C, 0x663E0503, + 0x81C, 0x65400503, + 0x81C, 0x64420503, + 0x81C, 0x63440503, + 0x81C, 0x62460503, + 0x81C, 0x61480503, + 0x81C, 0x604A0503, + 0x81C, 0x424C0503, + 0x81C, 0x414E0503, + 0x81C, 0x40500503, + 0x81C, 0x06520503, + 0x81C, 0x05540503, + 0x81C, 0x04560503, + 0x81C, 0x03580503, + 0x81C, 0x025A0503, + 0x81C, 0x015C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEF1C0503, + 0x81C, 0xEE1E0503, + 0x81C, 0xED200503, + 0x81C, 0xEC220503, + 0x81C, 0xEB240503, + 0x81C, 0xEA260503, + 0x81C, 0xE9280503, + 0x81C, 0xE82A0503, + 0x81C, 0xE72C0503, + 0x81C, 0xE62E0503, + 0x81C, 0xE5300503, + 0x81C, 0xE4320503, + 0x81C, 0xE3340503, + 0x81C, 0xC6360503, + 0x81C, 0xC5380503, + 0x81C, 0xC43A0503, + 0x81C, 0xC33C0503, + 0x81C, 0xC23E0503, + 0x81C, 0xA5400503, + 0x81C, 0xA4420503, + 0x81C, 0xA3440503, + 0x81C, 0xA2460503, + 0x81C, 0xA1480503, + 0x81C, 0x834A0503, + 0x81C, 0x824C0503, + 0x81C, 0x814E0503, + 0x81C, 0x63500503, + 0x81C, 0x62520503, + 0x81C, 0x61540503, + 0x81C, 0x43560503, + 0x81C, 0x42580503, + 0x81C, 0x245A0503, + 0x81C, 0x235C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x04620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000503, + 0x81C, 0xF7020503, + 0x81C, 0xF6040503, + 0x81C, 0xF5060503, + 0x81C, 0xF4080503, + 0x81C, 0xF30A0503, + 0x81C, 0xF20C0503, + 0x81C, 0xF10E0503, + 0x81C, 0xF0100503, + 0x81C, 0xEF120503, + 0x81C, 0xEE140503, + 0x81C, 0xED160503, + 0x81C, 0xEC180503, + 0x81C, 0xEB1A0503, + 0x81C, 0xEA1C0503, + 0x81C, 0xE91E0503, + 0x81C, 0xE8200503, + 0x81C, 0xE7220503, + 0x81C, 0xE6240503, + 0x81C, 0xE5260503, + 0x81C, 0xE4280503, + 0x81C, 0xE32A0503, + 0x81C, 0xE22C0503, + 0x81C, 0xC32E0503, + 0x81C, 0xC2300503, + 0x81C, 0xC1320503, + 0x81C, 0xA3340503, + 0x81C, 0xA2360503, + 0x81C, 0xA1380503, + 0x81C, 0xA03A0503, + 0x81C, 0x823C0503, + 0x81C, 0x813E0503, + 0x81C, 0x80400503, + 0x81C, 0x64420503, + 0x81C, 0x63440503, + 0x81C, 0x62460503, + 0x81C, 0x61480503, + 0x81C, 0x434A0503, + 0x81C, 0x424C0503, + 0x81C, 0x414E0503, + 0x81C, 0x40500503, + 0x81C, 0x22520503, + 0x81C, 0x21540503, + 0x81C, 0x20560503, + 0x81C, 0x04580503, + 0x81C, 0x035A0503, + 0x81C, 0x025C0503, + 0x81C, 0x015E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEE1C0503, + 0x81C, 0xED1E0503, + 0x81C, 0xEC200503, + 0x81C, 0xEB220503, + 0x81C, 0xEA240503, + 0x81C, 0xE9260503, + 0x81C, 0xE8280503, + 0x81C, 0xE72A0503, + 0x81C, 0xE62C0503, + 0x81C, 0xE52E0503, + 0x81C, 0xE4300503, + 0x81C, 0xE3320503, + 0x81C, 0xE2340503, + 0x81C, 0xC5360503, + 0x81C, 0xC4380503, + 0x81C, 0xC33A0503, + 0x81C, 0xC23C0503, + 0x81C, 0xA53E0503, + 0x81C, 0xA4400503, + 0x81C, 0xA3420503, + 0x81C, 0xA2440503, + 0x81C, 0xA1460503, + 0x81C, 0x83480503, + 0x81C, 0x824A0503, + 0x81C, 0x814C0503, + 0x81C, 0x804E0503, + 0x81C, 0x63500503, + 0x81C, 0x62520503, + 0x81C, 0x61540503, + 0x81C, 0x43560503, + 0x81C, 0x42580503, + 0x81C, 0x415A0503, + 0x81C, 0x405C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000503, + 0x81C, 0xF8020503, + 0x81C, 0xF7040503, + 0x81C, 0xF6060503, + 0x81C, 0xF5080503, + 0x81C, 0xF40A0503, + 0x81C, 0xF30C0503, + 0x81C, 0xF20E0503, + 0x81C, 0xF1100503, + 0x81C, 0xF0120503, + 0x81C, 0xEF140503, + 0x81C, 0xEE160503, + 0x81C, 0xED180503, + 0x81C, 0xEC1A0503, + 0x81C, 0xEB1C0503, + 0x81C, 0xEA1E0503, + 0x81C, 0xE9200503, + 0x81C, 0xE8220503, + 0x81C, 0xE7240503, + 0x81C, 0xE6260503, + 0x81C, 0xE5280503, + 0x81C, 0xE42A0503, + 0x81C, 0xE32C0503, + 0x81C, 0xC32E0503, + 0x81C, 0xC2300503, + 0x81C, 0xC1320503, + 0x81C, 0xA4340503, + 0x81C, 0xA3360503, + 0x81C, 0xA2380503, + 0x81C, 0xA13A0503, + 0x81C, 0xA03C0503, + 0x81C, 0x823E0503, + 0x81C, 0x81400503, + 0x81C, 0x80420503, + 0x81C, 0x63440503, + 0x81C, 0x62460503, + 0x81C, 0x61480503, + 0x81C, 0x604A0503, + 0x81C, 0x244C0503, + 0x81C, 0x234E0503, + 0x81C, 0x22500503, + 0x81C, 0x21520503, + 0x81C, 0x20540503, + 0x81C, 0x05560503, + 0x81C, 0x04580503, + 0x81C, 0x035A0503, + 0x81C, 0x025C0503, + 0x81C, 0x015E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000503, + 0x81C, 0xFD020503, + 0x81C, 0xFC040503, + 0x81C, 0xFB060503, + 0x81C, 0xFA080503, + 0x81C, 0xF90A0503, + 0x81C, 0xF80C0503, + 0x81C, 0xF70E0503, + 0x81C, 0xF6100503, + 0x81C, 0xF5120503, + 0x81C, 0xF4140503, + 0x81C, 0xF3160503, + 0x81C, 0xF2180503, + 0x81C, 0xF11A0503, + 0x81C, 0xF01C0503, + 0x81C, 0xEF1E0503, + 0x81C, 0xEE200503, + 0x81C, 0xED220503, + 0x81C, 0xEC240503, + 0x81C, 0xEB260503, + 0x81C, 0xEA280503, + 0x81C, 0xE92A0503, + 0x81C, 0xE82C0503, + 0x81C, 0xE72E0503, + 0x81C, 0xE6300503, + 0x81C, 0xE5320503, + 0x81C, 0xE4340503, + 0x81C, 0xE3360503, + 0x81C, 0xC6380503, + 0x81C, 0xC53A0503, + 0x81C, 0xC43C0503, + 0x81C, 0xC33E0503, + 0x81C, 0xA5400503, + 0x81C, 0xA4420503, + 0x81C, 0xA3440503, + 0x81C, 0xA2460503, + 0x81C, 0xA1480503, + 0x81C, 0xA04A0503, + 0x81C, 0x824C0503, + 0x81C, 0x814E0503, + 0x81C, 0x80500503, + 0x81C, 0x64520503, + 0x81C, 0x63540503, + 0x81C, 0x62560503, + 0x81C, 0x61580503, + 0x81C, 0x605A0503, + 0x81C, 0x235C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEE1C0503, + 0x81C, 0xED1E0503, + 0x81C, 0xEC200503, + 0x81C, 0xEB220503, + 0x81C, 0xEA240503, + 0x81C, 0xE9260503, + 0x81C, 0xE8280503, + 0x81C, 0xE72A0503, + 0x81C, 0xE62C0503, + 0x81C, 0xE52E0503, + 0x81C, 0xE4300503, + 0x81C, 0xE3320503, + 0x81C, 0xE2340503, + 0x81C, 0xC5360503, + 0x81C, 0xC4380503, + 0x81C, 0xC33A0503, + 0x81C, 0xC23C0503, + 0x81C, 0xA53E0503, + 0x81C, 0xA4400503, + 0x81C, 0xA3420503, + 0x81C, 0xA2440503, + 0x81C, 0xA1460503, + 0x81C, 0x83480503, + 0x81C, 0x824A0503, + 0x81C, 0x814C0503, + 0x81C, 0x804E0503, + 0x81C, 0x63500503, + 0x81C, 0x62520503, + 0x81C, 0x61540503, + 0x81C, 0x43560503, + 0x81C, 0x42580503, + 0x81C, 0x415A0503, + 0x81C, 0x405C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEE1C0503, + 0x81C, 0xED1E0503, + 0x81C, 0xEC200503, + 0x81C, 0xEB220503, + 0x81C, 0xEA240503, + 0x81C, 0xE9260503, + 0x81C, 0xE8280503, + 0x81C, 0xE72A0503, + 0x81C, 0xE62C0503, + 0x81C, 0xE52E0503, + 0x81C, 0xE4300503, + 0x81C, 0xE3320503, + 0x81C, 0xE2340503, + 0x81C, 0xC5360503, + 0x81C, 0xC4380503, + 0x81C, 0xC33A0503, + 0x81C, 0xC23C0503, + 0x81C, 0xA53E0503, + 0x81C, 0xA4400503, + 0x81C, 0xA3420503, + 0x81C, 0xA2440503, + 0x81C, 0xA1460503, + 0x81C, 0x83480503, + 0x81C, 0x824A0503, + 0x81C, 0x814C0503, + 0x81C, 0x804E0503, + 0x81C, 0x63500503, + 0x81C, 0x62520503, + 0x81C, 0x61540503, + 0x81C, 0x43560503, + 0x81C, 0x42580503, + 0x81C, 0x415A0503, + 0x81C, 0x405C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBF000503, + 0x81C, 0xBF020503, + 0x81C, 0xBF040503, + 0x81C, 0xBF060503, + 0x81C, 0xBF080503, + 0x81C, 0xBF0A0503, + 0x81C, 0xBE0C0503, + 0x81C, 0xBD0E0503, + 0x81C, 0xBC100503, + 0x81C, 0xBB120503, + 0x81C, 0xBA140503, + 0x81C, 0xB9160503, + 0x81C, 0xB8180503, + 0x81C, 0xB71A0503, + 0x81C, 0xB61C0503, + 0x81C, 0xB51E0503, + 0x81C, 0xB2200503, + 0x81C, 0xB3220503, + 0x81C, 0xB2240503, + 0x81C, 0xB1260503, + 0x81C, 0xB0280503, + 0x81C, 0xAF2A0503, + 0x81C, 0xAE2C0503, + 0x81C, 0xAD2E0503, + 0x81C, 0xAC300503, + 0x81C, 0xAB320503, + 0x81C, 0xAA340503, + 0x81C, 0xC6360503, + 0x81C, 0xC5380503, + 0x81C, 0xC43A0503, + 0x81C, 0xC33C0503, + 0x81C, 0x883E0503, + 0x81C, 0x87400503, + 0x81C, 0x86420503, + 0x81C, 0x85440503, + 0x81C, 0x84460503, + 0x81C, 0x83480503, + 0x81C, 0x674A0503, + 0x81C, 0x664C0503, + 0x81C, 0x654E0503, + 0x81C, 0x64500503, + 0x81C, 0x27520503, + 0x81C, 0x26540503, + 0x81C, 0x25560503, + 0x81C, 0x24580503, + 0x81C, 0x235A0503, + 0x81C, 0x225C0503, + 0x81C, 0x215E0503, + 0x81C, 0x20600503, + 0x81C, 0x03620503, + 0x81C, 0x02640503, + 0x81C, 0x01660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000403, + 0x81C, 0xFD000503, + 0x81C, 0xFC020503, + 0x81C, 0xFB040503, + 0x81C, 0xFA060503, + 0x81C, 0xF9080503, + 0x81C, 0xF80A0503, + 0x81C, 0xF70C0503, + 0x81C, 0xF60E0503, + 0x81C, 0xF5100503, + 0x81C, 0xF4120503, + 0x81C, 0xF3140503, + 0x81C, 0xF2160503, + 0x81C, 0xF1180503, + 0x81C, 0xF01A0503, + 0x81C, 0xEF1C0503, + 0x81C, 0xEE1E0503, + 0x81C, 0xED200503, + 0x81C, 0xEC220503, + 0x81C, 0xEB240503, + 0x81C, 0xEA260503, + 0x81C, 0xE9280503, + 0x81C, 0xE82A0503, + 0x81C, 0xE72C0503, + 0x81C, 0xE62E0503, + 0x81C, 0xE5300503, + 0x81C, 0xE4320503, + 0x81C, 0xE3340503, + 0x81C, 0xC6360503, + 0x81C, 0xC5380503, + 0x81C, 0xC43A0503, + 0x81C, 0xC33C0503, + 0x81C, 0xA53E0503, + 0x81C, 0xA4400503, + 0x81C, 0xA3420503, + 0x81C, 0xA2440503, + 0x81C, 0xA1460503, + 0x81C, 0xA0480503, + 0x81C, 0x824A0503, + 0x81C, 0x814C0503, + 0x81C, 0x804E0503, + 0x81C, 0x64500503, + 0x81C, 0x63520503, + 0x81C, 0x62540503, + 0x81C, 0x61560503, + 0x81C, 0x60580503, + 0x81C, 0x235A0503, + 0x81C, 0x225C0503, + 0x81C, 0x215E0503, + 0x81C, 0x20600503, + 0x81C, 0x03620503, + 0x81C, 0x02640503, + 0x81C, 0x01660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000503, + 0x81C, 0xF7020503, + 0x81C, 0xF6040503, + 0x81C, 0xF5060503, + 0x81C, 0xF4080503, + 0x81C, 0xF30A0503, + 0x81C, 0xF20C0503, + 0x81C, 0xF10E0503, + 0x81C, 0xF0100503, + 0x81C, 0xEF120503, + 0x81C, 0xEE140503, + 0x81C, 0xED160503, + 0x81C, 0xEC180503, + 0x81C, 0xEB1A0503, + 0x81C, 0xEA1C0503, + 0x81C, 0xE91E0503, + 0x81C, 0xE8200503, + 0x81C, 0xE7220503, + 0x81C, 0xE6240503, + 0x81C, 0xE5260503, + 0x81C, 0xE4280503, + 0x81C, 0xE32A0503, + 0x81C, 0xC32C0503, + 0x81C, 0xC22E0503, + 0x81C, 0xC1300503, + 0x81C, 0xC0320503, + 0x81C, 0xA3340503, + 0x81C, 0xA2360503, + 0x81C, 0xA1380503, + 0x81C, 0xA03A0503, + 0x81C, 0x823C0503, + 0x81C, 0x813E0503, + 0x81C, 0x80400503, + 0x81C, 0x63420503, + 0x81C, 0x62440503, + 0x81C, 0x61460503, + 0x81C, 0x60480503, + 0x81C, 0x424A0503, + 0x81C, 0x414C0503, + 0x81C, 0x404E0503, + 0x81C, 0x22500503, + 0x81C, 0x21520503, + 0x81C, 0x20540503, + 0x81C, 0x03560503, + 0x81C, 0x02580503, + 0x81C, 0x015A0503, + 0x81C, 0x005C0503, + 0x81C, 0x005E0503, + 0x81C, 0x00600503, + 0x81C, 0x00620503, + 0x81C, 0x00640503, + 0x81C, 0x00660503, + 0x81C, 0x00680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0xA0000000, 0x00000000, + 0x81C, 0xFE000503, + 0x81C, 0xFD020503, + 0x81C, 0xFC040503, + 0x81C, 0xFB060503, + 0x81C, 0xFA080503, + 0x81C, 0xF90A0503, + 0x81C, 0xF80C0503, + 0x81C, 0xF70E0503, + 0x81C, 0xF6100503, + 0x81C, 0xF5120503, + 0x81C, 0xF4140503, + 0x81C, 0xF3160503, + 0x81C, 0xF2180503, + 0x81C, 0xF11A0503, + 0x81C, 0xF01C0503, + 0x81C, 0xEF1E0503, + 0x81C, 0xEE200503, + 0x81C, 0xED220503, + 0x81C, 0xEC240503, + 0x81C, 0xEB260503, + 0x81C, 0xEA280503, + 0x81C, 0xE92A0503, + 0x81C, 0xE82C0503, + 0x81C, 0xE72E0503, + 0x81C, 0xE6300503, + 0x81C, 0xE5320503, + 0x81C, 0xE4340503, + 0x81C, 0xE3360503, + 0x81C, 0xC6380503, + 0x81C, 0xC53A0503, + 0x81C, 0xC43C0503, + 0x81C, 0xC33E0503, + 0x81C, 0xA5400503, + 0x81C, 0xA4420503, + 0x81C, 0xA3440503, + 0x81C, 0xA2460503, + 0x81C, 0xA1480503, + 0x81C, 0xA04A0503, + 0x81C, 0x824C0503, + 0x81C, 0x814E0503, + 0x81C, 0x80500503, + 0x81C, 0x64520503, + 0x81C, 0x63540503, + 0x81C, 0x62560503, + 0x81C, 0x61580503, + 0x81C, 0x605A0503, + 0x81C, 0x235C0503, + 0x81C, 0x225E0503, + 0x81C, 0x21600503, + 0x81C, 0x20620503, + 0x81C, 0x03640503, + 0x81C, 0x02660503, + 0x81C, 0x01680503, + 0x81C, 0x006A0503, + 0x81C, 0x006C0503, + 0x81C, 0x006E0503, + 0x81C, 0x00700503, + 0x81C, 0x00720503, + 0x81C, 0x00740503, + 0x81C, 0x00760503, + 0x81C, 0x00780503, + 0x81C, 0x007A0503, + 0x81C, 0x007C0503, + 0x81C, 0x007E0503, + 0x81C, 0x007E0503, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xA63C0603, + 0x81C, 0xA53E0603, + 0x81C, 0xA4400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0x83480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x804E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x42560603, + 0x81C, 0x41580603, + 0x81C, 0x405A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x04620603, + 0x81C, 0x03640603, + 0x81C, 0x02660603, + 0x81C, 0x01680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBD000603, + 0x81C, 0xBC020603, + 0x81C, 0xBB040603, + 0x81C, 0xBA060603, + 0x81C, 0xB9080603, + 0x81C, 0xB80A0603, + 0x81C, 0xB70C0603, + 0x81C, 0xB60E0603, + 0x81C, 0xB5100603, + 0x81C, 0xB4120603, + 0x81C, 0xB3140603, + 0x81C, 0xB2160603, + 0x81C, 0xB1180603, + 0x81C, 0xB01A0603, + 0x81C, 0xAF1C0603, + 0x81C, 0xAE1E0603, + 0x81C, 0xAD200603, + 0x81C, 0x8F220603, + 0x81C, 0x8E240603, + 0x81C, 0x8D260603, + 0x81C, 0x8C280603, + 0x81C, 0x8B2A0603, + 0x81C, 0x8A2C0603, + 0x81C, 0x892E0603, + 0x81C, 0x88300603, + 0x81C, 0x6B320603, + 0x81C, 0x6A340603, + 0x81C, 0x69360603, + 0x81C, 0x68380603, + 0x81C, 0x673A0603, + 0x81C, 0x663C0603, + 0x81C, 0x653E0603, + 0x81C, 0x64400603, + 0x81C, 0x63420603, + 0x81C, 0x62440603, + 0x81C, 0x61460603, + 0x81C, 0x60480603, + 0x81C, 0x424A0603, + 0x81C, 0x414C0603, + 0x81C, 0x404E0603, + 0x81C, 0x06500603, + 0x81C, 0x05520603, + 0x81C, 0x04540603, + 0x81C, 0x03560603, + 0x81C, 0x02580603, + 0x81C, 0x015A0603, + 0x81C, 0x005C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007C0603, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000603, + 0x81C, 0xF6020603, + 0x81C, 0xF5040603, + 0x81C, 0xF4060603, + 0x81C, 0xF3080603, + 0x81C, 0xF20A0603, + 0x81C, 0xF10C0603, + 0x81C, 0xF00E0603, + 0x81C, 0xEF100603, + 0x81C, 0xEE120603, + 0x81C, 0xED140603, + 0x81C, 0xEC160603, + 0x81C, 0xEB180603, + 0x81C, 0xEA1A0603, + 0x81C, 0xE91C0603, + 0x81C, 0xE81E0603, + 0x81C, 0xE7200603, + 0x81C, 0xE6220603, + 0x81C, 0xE5240603, + 0x81C, 0xE4260603, + 0x81C, 0xE3280603, + 0x81C, 0xC42A0603, + 0x81C, 0xC32C0603, + 0x81C, 0xC22E0603, + 0x81C, 0xC1300603, + 0x81C, 0xC0320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x414C0603, + 0x81C, 0x404E0603, + 0x81C, 0x22500603, + 0x81C, 0x21520603, + 0x81C, 0x20540603, + 0x81C, 0x03560603, + 0x81C, 0x02580603, + 0x81C, 0x015A0603, + 0x81C, 0x005C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEF1A0603, + 0x81C, 0xEE1C0603, + 0x81C, 0xED1E0603, + 0x81C, 0xEC200603, + 0x81C, 0xEB220603, + 0x81C, 0xEA240603, + 0x81C, 0xE9260603, + 0x81C, 0xE8280603, + 0x81C, 0xE72A0603, + 0x81C, 0xE62C0603, + 0x81C, 0xE52E0603, + 0x81C, 0xE4300603, + 0x81C, 0xE3320603, + 0x81C, 0xE2340603, + 0x81C, 0xC6360603, + 0x81C, 0xC5380603, + 0x81C, 0xC43A0603, + 0x81C, 0xC33C0603, + 0x81C, 0xA63E0603, + 0x81C, 0xA5400603, + 0x81C, 0xA4420603, + 0x81C, 0xA3440603, + 0x81C, 0xA2460603, + 0x81C, 0xA1480603, + 0x81C, 0x834A0603, + 0x81C, 0x824C0603, + 0x81C, 0x814E0603, + 0x81C, 0x64500603, + 0x81C, 0x63520603, + 0x81C, 0x62540603, + 0x81C, 0x61560603, + 0x81C, 0x60580603, + 0x81C, 0x405A0603, + 0x81C, 0x215C0603, + 0x81C, 0x205E0603, + 0x81C, 0x03600603, + 0x81C, 0x02620603, + 0x81C, 0x01640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000603, + 0x81C, 0xF6020603, + 0x81C, 0xF5040603, + 0x81C, 0xF4060603, + 0x81C, 0xF3080603, + 0x81C, 0xF20A0603, + 0x81C, 0xF10C0603, + 0x81C, 0xF00E0603, + 0x81C, 0xEF100603, + 0x81C, 0xEE120603, + 0x81C, 0xED140603, + 0x81C, 0xEC160603, + 0x81C, 0xEB180603, + 0x81C, 0xEA1A0603, + 0x81C, 0xE91C0603, + 0x81C, 0xE81E0603, + 0x81C, 0xE7200603, + 0x81C, 0xE6220603, + 0x81C, 0xE5240603, + 0x81C, 0xE4260603, + 0x81C, 0xE3280603, + 0x81C, 0xC42A0603, + 0x81C, 0xC32C0603, + 0x81C, 0xC22E0603, + 0x81C, 0xC1300603, + 0x81C, 0xC0320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x414C0603, + 0x81C, 0x404E0603, + 0x81C, 0x22500603, + 0x81C, 0x21520603, + 0x81C, 0x20540603, + 0x81C, 0x03560603, + 0x81C, 0x02580603, + 0x81C, 0x015A0603, + 0x81C, 0x005C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEF1A0603, + 0x81C, 0xEE1C0603, + 0x81C, 0xED1E0603, + 0x81C, 0xEC200603, + 0x81C, 0xEB220603, + 0x81C, 0xEA240603, + 0x81C, 0xE9260603, + 0x81C, 0xE8280603, + 0x81C, 0xE72A0603, + 0x81C, 0xE62C0603, + 0x81C, 0xE52E0603, + 0x81C, 0xE4300603, + 0x81C, 0xE3320603, + 0x81C, 0xE2340603, + 0x81C, 0xE1360603, + 0x81C, 0xC5380603, + 0x81C, 0xC43A0603, + 0x81C, 0xC33C0603, + 0x81C, 0xC23E0603, + 0x81C, 0xC1400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0xA0480603, + 0x81C, 0x834A0603, + 0x81C, 0x824C0603, + 0x81C, 0x814E0603, + 0x81C, 0x64500603, + 0x81C, 0x63520603, + 0x81C, 0x62540603, + 0x81C, 0x61560603, + 0x81C, 0x25580603, + 0x81C, 0x245A0603, + 0x81C, 0x235C0603, + 0x81C, 0x225E0603, + 0x81C, 0x21600603, + 0x81C, 0x04620603, + 0x81C, 0x03640603, + 0x81C, 0x02660603, + 0x81C, 0x01680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000603, + 0x81C, 0xF8020603, + 0x81C, 0xF7040603, + 0x81C, 0xF6060603, + 0x81C, 0xF5080603, + 0x81C, 0xF40A0603, + 0x81C, 0xF30C0603, + 0x81C, 0xF20E0603, + 0x81C, 0xF1100603, + 0x81C, 0xF0120603, + 0x81C, 0xEF140603, + 0x81C, 0xEE160603, + 0x81C, 0xED180603, + 0x81C, 0xEC1A0603, + 0x81C, 0xEB1C0603, + 0x81C, 0xEA1E0603, + 0x81C, 0xE9200603, + 0x81C, 0xE8220603, + 0x81C, 0xE7240603, + 0x81C, 0xE6260603, + 0x81C, 0xE5280603, + 0x81C, 0xC42A0603, + 0x81C, 0xC32C0603, + 0x81C, 0xC22E0603, + 0x81C, 0xC1300603, + 0x81C, 0xC0320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x414C0603, + 0x81C, 0x404E0603, + 0x81C, 0x22500603, + 0x81C, 0x21520603, + 0x81C, 0x20540603, + 0x81C, 0x03560603, + 0x81C, 0x02580603, + 0x81C, 0x015A0603, + 0x81C, 0x005C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBE000603, + 0x81C, 0xBD020603, + 0x81C, 0xBC040603, + 0x81C, 0xBB060603, + 0x81C, 0xBA080603, + 0x81C, 0xB90A0603, + 0x81C, 0xB80C0603, + 0x81C, 0xB70E0603, + 0x81C, 0xB6100603, + 0x81C, 0xB5120603, + 0x81C, 0xB4140603, + 0x81C, 0xB3160603, + 0x81C, 0xB2180603, + 0x81C, 0xB11A0603, + 0x81C, 0xB01C0603, + 0x81C, 0x921E0603, + 0x81C, 0x91200603, + 0x81C, 0x90220603, + 0x81C, 0x8F240603, + 0x81C, 0x8E260603, + 0x81C, 0x8D280603, + 0x81C, 0x8C2A0603, + 0x81C, 0x8B2C0603, + 0x81C, 0x8A2E0603, + 0x81C, 0x89300603, + 0x81C, 0x88320603, + 0x81C, 0x6B340603, + 0x81C, 0x6A360603, + 0x81C, 0x69380603, + 0x81C, 0x683A0603, + 0x81C, 0x673C0603, + 0x81C, 0x663E0603, + 0x81C, 0x65400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x424C0603, + 0x81C, 0x414E0603, + 0x81C, 0x40500603, + 0x81C, 0x06520603, + 0x81C, 0x05540603, + 0x81C, 0x04560603, + 0x81C, 0x03580603, + 0x81C, 0x025A0603, + 0x81C, 0x015C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000603, + 0x81C, 0xFA020603, + 0x81C, 0xF9040603, + 0x81C, 0xF8060603, + 0x81C, 0xF7080603, + 0x81C, 0xF60A0603, + 0x81C, 0xF50C0603, + 0x81C, 0xF40E0603, + 0x81C, 0xF3100603, + 0x81C, 0xF2120603, + 0x81C, 0xF1140603, + 0x81C, 0xF0160603, + 0x81C, 0xEF180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xC23C0603, + 0x81C, 0xC13E0603, + 0x81C, 0xC0400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0xA0480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x804E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x60560603, + 0x81C, 0x24580603, + 0x81C, 0x235A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x03620603, + 0x81C, 0x02640603, + 0x81C, 0x01660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000603, + 0x81C, 0xF7020603, + 0x81C, 0xF6040603, + 0x81C, 0xF5060603, + 0x81C, 0xF4080603, + 0x81C, 0xF30A0603, + 0x81C, 0xF20C0603, + 0x81C, 0xF10E0603, + 0x81C, 0xF0100603, + 0x81C, 0xEF120603, + 0x81C, 0xEE140603, + 0x81C, 0xED160603, + 0x81C, 0xEC180603, + 0x81C, 0xEB1A0603, + 0x81C, 0xEA1C0603, + 0x81C, 0xE91E0603, + 0x81C, 0xE8200603, + 0x81C, 0xE7220603, + 0x81C, 0xE6240603, + 0x81C, 0xE5260603, + 0x81C, 0xE4280603, + 0x81C, 0xE32A0603, + 0x81C, 0xC42C0603, + 0x81C, 0xC32E0603, + 0x81C, 0xC2300603, + 0x81C, 0xC1320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x65420603, + 0x81C, 0x64440603, + 0x81C, 0x63460603, + 0x81C, 0x62480603, + 0x81C, 0x614A0603, + 0x81C, 0x424C0603, + 0x81C, 0x414E0603, + 0x81C, 0x40500603, + 0x81C, 0x22520603, + 0x81C, 0x21540603, + 0x81C, 0x20560603, + 0x81C, 0x04580603, + 0x81C, 0x035A0603, + 0x81C, 0x025C0603, + 0x81C, 0x015E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xA63C0603, + 0x81C, 0xA53E0603, + 0x81C, 0xA4400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0x83480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x804E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x42560603, + 0x81C, 0x41580603, + 0x81C, 0x405A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x04620603, + 0x81C, 0x03640603, + 0x81C, 0x02660603, + 0x81C, 0x01680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000603, + 0x81C, 0xF8020603, + 0x81C, 0xF7040603, + 0x81C, 0xF6060603, + 0x81C, 0xF5080603, + 0x81C, 0xF40A0603, + 0x81C, 0xF30C0603, + 0x81C, 0xF20E0603, + 0x81C, 0xF1100603, + 0x81C, 0xF0120603, + 0x81C, 0xEF140603, + 0x81C, 0xEE160603, + 0x81C, 0xED180603, + 0x81C, 0xEC1A0603, + 0x81C, 0xEB1C0603, + 0x81C, 0xEA1E0603, + 0x81C, 0xE9200603, + 0x81C, 0xE8220603, + 0x81C, 0xE7240603, + 0x81C, 0xE6260603, + 0x81C, 0xE5280603, + 0x81C, 0xE42A0603, + 0x81C, 0xC42C0603, + 0x81C, 0xC32E0603, + 0x81C, 0xC2300603, + 0x81C, 0xC1320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x244C0603, + 0x81C, 0x234E0603, + 0x81C, 0x22500603, + 0x81C, 0x21520603, + 0x81C, 0x20540603, + 0x81C, 0x05560603, + 0x81C, 0x04580603, + 0x81C, 0x035A0603, + 0x81C, 0x025C0603, + 0x81C, 0x015E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEF1A0603, + 0x81C, 0xEE1C0603, + 0x81C, 0xED1E0603, + 0x81C, 0xEC200603, + 0x81C, 0xEB220603, + 0x81C, 0xEA240603, + 0x81C, 0xE9260603, + 0x81C, 0xE8280603, + 0x81C, 0xE72A0603, + 0x81C, 0xE62C0603, + 0x81C, 0xE52E0603, + 0x81C, 0xE4300603, + 0x81C, 0xE3320603, + 0x81C, 0xE2340603, + 0x81C, 0xC6360603, + 0x81C, 0xC5380603, + 0x81C, 0xC43A0603, + 0x81C, 0xC33C0603, + 0x81C, 0xA63E0603, + 0x81C, 0xA5400603, + 0x81C, 0xA4420603, + 0x81C, 0xA3440603, + 0x81C, 0xA2460603, + 0x81C, 0xA1480603, + 0x81C, 0x834A0603, + 0x81C, 0x824C0603, + 0x81C, 0x814E0603, + 0x81C, 0x64500603, + 0x81C, 0x63520603, + 0x81C, 0x62540603, + 0x81C, 0x61560603, + 0x81C, 0x60580603, + 0x81C, 0x405A0603, + 0x81C, 0x215C0603, + 0x81C, 0x205E0603, + 0x81C, 0x03600603, + 0x81C, 0x02620603, + 0x81C, 0x01640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xA63C0603, + 0x81C, 0xA53E0603, + 0x81C, 0xA4400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0x83480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x804E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x42560603, + 0x81C, 0x41580603, + 0x81C, 0x405A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x04620603, + 0x81C, 0x03640603, + 0x81C, 0x02660603, + 0x81C, 0x01680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000603, + 0x81C, 0xFB020603, + 0x81C, 0xFA040603, + 0x81C, 0xF9060603, + 0x81C, 0xF8080603, + 0x81C, 0xF70A0603, + 0x81C, 0xF60C0603, + 0x81C, 0xF50E0603, + 0x81C, 0xF4100603, + 0x81C, 0xF3120603, + 0x81C, 0xF2140603, + 0x81C, 0xF1160603, + 0x81C, 0xF0180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xA63C0603, + 0x81C, 0xA53E0603, + 0x81C, 0xA4400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0x83480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x804E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x42560603, + 0x81C, 0x41580603, + 0x81C, 0x405A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x04620603, + 0x81C, 0x03640603, + 0x81C, 0x02660603, + 0x81C, 0x01680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBF000603, + 0x81C, 0xBF020603, + 0x81C, 0xBF040603, + 0x81C, 0xBF060603, + 0x81C, 0xBF080603, + 0x81C, 0xBE0A0603, + 0x81C, 0xBD0C0603, + 0x81C, 0xBC0E0603, + 0x81C, 0xBB100603, + 0x81C, 0xBA120603, + 0x81C, 0xB9140603, + 0x81C, 0xB8160603, + 0x81C, 0xB7180603, + 0x81C, 0xB61A0603, + 0x81C, 0xB51C0603, + 0x81C, 0xB41E0603, + 0x81C, 0xB1200603, + 0x81C, 0xB2220603, + 0x81C, 0xB1240603, + 0x81C, 0xB0260603, + 0x81C, 0xAF280603, + 0x81C, 0xAE2A0603, + 0x81C, 0xAD2C0603, + 0x81C, 0xAC2E0603, + 0x81C, 0xAB300603, + 0x81C, 0xAA320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0x883C0603, + 0x81C, 0x873E0603, + 0x81C, 0x86400603, + 0x81C, 0x85420603, + 0x81C, 0x84440603, + 0x81C, 0x83460603, + 0x81C, 0x67480603, + 0x81C, 0x664A0603, + 0x81C, 0x654C0603, + 0x81C, 0x644E0603, + 0x81C, 0x27500603, + 0x81C, 0x26520603, + 0x81C, 0x25540603, + 0x81C, 0x24560603, + 0x81C, 0x23580603, + 0x81C, 0x225A0603, + 0x81C, 0x215C0603, + 0x81C, 0x205E0603, + 0x81C, 0x03600603, + 0x81C, 0x02620603, + 0x81C, 0x01640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000403, + 0x81C, 0xFB000603, + 0x81C, 0xFA020603, + 0x81C, 0xF9040603, + 0x81C, 0xF8060603, + 0x81C, 0xF7080603, + 0x81C, 0xF60A0603, + 0x81C, 0xF50C0603, + 0x81C, 0xF40E0603, + 0x81C, 0xF3100603, + 0x81C, 0xF2120603, + 0x81C, 0xF1140603, + 0x81C, 0xF0160603, + 0x81C, 0xEF180603, + 0x81C, 0xEE1A0603, + 0x81C, 0xED1C0603, + 0x81C, 0xEC1E0603, + 0x81C, 0xEB200603, + 0x81C, 0xEA220603, + 0x81C, 0xE9240603, + 0x81C, 0xE8260603, + 0x81C, 0xE7280603, + 0x81C, 0xE62A0603, + 0x81C, 0xE52C0603, + 0x81C, 0xE42E0603, + 0x81C, 0xE3300603, + 0x81C, 0xE2320603, + 0x81C, 0xC6340603, + 0x81C, 0xC5360603, + 0x81C, 0xC4380603, + 0x81C, 0xC33A0603, + 0x81C, 0xA63C0603, + 0x81C, 0xA53E0603, + 0x81C, 0xA4400603, + 0x81C, 0xA3420603, + 0x81C, 0xA2440603, + 0x81C, 0xA1460603, + 0x81C, 0x83480603, + 0x81C, 0x824A0603, + 0x81C, 0x814C0603, + 0x81C, 0x644E0603, + 0x81C, 0x63500603, + 0x81C, 0x62520603, + 0x81C, 0x61540603, + 0x81C, 0x60560603, + 0x81C, 0x40580603, + 0x81C, 0x215A0603, + 0x81C, 0x205C0603, + 0x81C, 0x035E0603, + 0x81C, 0x02600603, + 0x81C, 0x01620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000603, + 0x81C, 0xF6020603, + 0x81C, 0xF5040603, + 0x81C, 0xF4060603, + 0x81C, 0xF3080603, + 0x81C, 0xF20A0603, + 0x81C, 0xF10C0603, + 0x81C, 0xF00E0603, + 0x81C, 0xEF100603, + 0x81C, 0xEE120603, + 0x81C, 0xED140603, + 0x81C, 0xEC160603, + 0x81C, 0xEB180603, + 0x81C, 0xEA1A0603, + 0x81C, 0xE91C0603, + 0x81C, 0xE81E0603, + 0x81C, 0xE7200603, + 0x81C, 0xE6220603, + 0x81C, 0xE5240603, + 0x81C, 0xE4260603, + 0x81C, 0xE3280603, + 0x81C, 0xC42A0603, + 0x81C, 0xC32C0603, + 0x81C, 0xC22E0603, + 0x81C, 0xC1300603, + 0x81C, 0xC0320603, + 0x81C, 0xA3340603, + 0x81C, 0xA2360603, + 0x81C, 0xA1380603, + 0x81C, 0xA03A0603, + 0x81C, 0x823C0603, + 0x81C, 0x813E0603, + 0x81C, 0x80400603, + 0x81C, 0x64420603, + 0x81C, 0x63440603, + 0x81C, 0x62460603, + 0x81C, 0x61480603, + 0x81C, 0x604A0603, + 0x81C, 0x414C0603, + 0x81C, 0x404E0603, + 0x81C, 0x22500603, + 0x81C, 0x21520603, + 0x81C, 0x20540603, + 0x81C, 0x03560603, + 0x81C, 0x02580603, + 0x81C, 0x015A0603, + 0x81C, 0x005C0603, + 0x81C, 0x005E0603, + 0x81C, 0x00600603, + 0x81C, 0x00620603, + 0x81C, 0x00640603, + 0x81C, 0x00660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000603, + 0x81C, 0xFC020603, + 0x81C, 0xFB040603, + 0x81C, 0xFA060603, + 0x81C, 0xF9080603, + 0x81C, 0xF80A0603, + 0x81C, 0xF70C0603, + 0x81C, 0xF60E0603, + 0x81C, 0xF5100603, + 0x81C, 0xF4120603, + 0x81C, 0xF3140603, + 0x81C, 0xF2160603, + 0x81C, 0xF1180603, + 0x81C, 0xF01A0603, + 0x81C, 0xEF1C0603, + 0x81C, 0xEE1E0603, + 0x81C, 0xED200603, + 0x81C, 0xEC220603, + 0x81C, 0xEB240603, + 0x81C, 0xEA260603, + 0x81C, 0xE9280603, + 0x81C, 0xE82A0603, + 0x81C, 0xE72C0603, + 0x81C, 0xE62E0603, + 0x81C, 0xE5300603, + 0x81C, 0xE4320603, + 0x81C, 0xE3340603, + 0x81C, 0xC6360603, + 0x81C, 0xC5380603, + 0x81C, 0xC43A0603, + 0x81C, 0xC33C0603, + 0x81C, 0xA63E0603, + 0x81C, 0xA5400603, + 0x81C, 0xA4420603, + 0x81C, 0xA3440603, + 0x81C, 0xA2460603, + 0x81C, 0xA1480603, + 0x81C, 0x834A0603, + 0x81C, 0x824C0603, + 0x81C, 0x814E0603, + 0x81C, 0x64500603, + 0x81C, 0x63520603, + 0x81C, 0x62540603, + 0x81C, 0x61560603, + 0x81C, 0x60580603, + 0x81C, 0x235A0603, + 0x81C, 0x225C0603, + 0x81C, 0x215E0603, + 0x81C, 0x20600603, + 0x81C, 0x03620603, + 0x81C, 0x02640603, + 0x81C, 0x01660603, + 0x81C, 0x00680603, + 0x81C, 0x006A0603, + 0x81C, 0x006C0603, + 0x81C, 0x006E0603, + 0x81C, 0x00700603, + 0x81C, 0x00720603, + 0x81C, 0x00740603, + 0x81C, 0x00760603, + 0x81C, 0x00780603, + 0x81C, 0x007A0603, + 0x81C, 0x007C0603, + 0x81C, 0x007E0603, + 0x81C, 0x007E0603, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000703, + 0x81C, 0xFB020703, + 0x81C, 0xFA040703, + 0x81C, 0xF9060703, + 0x81C, 0xF8080703, + 0x81C, 0xF70A0703, + 0x81C, 0xF60C0703, + 0x81C, 0xF50E0703, + 0x81C, 0xF4100703, + 0x81C, 0xF3120703, + 0x81C, 0xF2140703, + 0x81C, 0xF1160703, + 0x81C, 0xEF180703, + 0x81C, 0xEE1A0703, + 0x81C, 0xED1C0703, + 0x81C, 0xEC1E0703, + 0x81C, 0xEB200703, + 0x81C, 0xEA220703, + 0x81C, 0xE9240703, + 0x81C, 0xE8260703, + 0x81C, 0xE7280703, + 0x81C, 0xE62A0703, + 0x81C, 0xE52C0703, + 0x81C, 0xE42E0703, + 0x81C, 0xE3300703, + 0x81C, 0xE2320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xA63C0703, + 0x81C, 0xA53E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x61540703, + 0x81C, 0x42560703, + 0x81C, 0x41580703, + 0x81C, 0x405A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBD000703, + 0x81C, 0xBC020703, + 0x81C, 0xBB040703, + 0x81C, 0xBA060703, + 0x81C, 0xB9080703, + 0x81C, 0xB80A0703, + 0x81C, 0xB70C0703, + 0x81C, 0xB60E0703, + 0x81C, 0xB5100703, + 0x81C, 0xB4120703, + 0x81C, 0xB3140703, + 0x81C, 0xB2160703, + 0x81C, 0xB1180703, + 0x81C, 0xB01A0703, + 0x81C, 0xAF1C0703, + 0x81C, 0xAE1E0703, + 0x81C, 0xAD200703, + 0x81C, 0xAC220703, + 0x81C, 0x8E240703, + 0x81C, 0x8D260703, + 0x81C, 0x8C280703, + 0x81C, 0x6F2A0703, + 0x81C, 0x6E2C0703, + 0x81C, 0x6D2E0703, + 0x81C, 0x6C300703, + 0x81C, 0x6B320703, + 0x81C, 0x6A340703, + 0x81C, 0x69360703, + 0x81C, 0x68380703, + 0x81C, 0x673A0703, + 0x81C, 0x663C0703, + 0x81C, 0x653E0703, + 0x81C, 0x64400703, + 0x81C, 0x63420703, + 0x81C, 0x62440703, + 0x81C, 0x61460703, + 0x81C, 0x60480703, + 0x81C, 0x424A0703, + 0x81C, 0x414C0703, + 0x81C, 0x404E0703, + 0x81C, 0x06500703, + 0x81C, 0x05520703, + 0x81C, 0x04540703, + 0x81C, 0x03560703, + 0x81C, 0x02580703, + 0x81C, 0x015A0703, + 0x81C, 0x005C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007C0703, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000703, + 0x81C, 0xF6020703, + 0x81C, 0xF5040703, + 0x81C, 0xF4060703, + 0x81C, 0xF3080703, + 0x81C, 0xF20A0703, + 0x81C, 0xF10C0703, + 0x81C, 0xF00E0703, + 0x81C, 0xEF100703, + 0x81C, 0xEE120703, + 0x81C, 0xED140703, + 0x81C, 0xEC160703, + 0x81C, 0xEB180703, + 0x81C, 0xEA1A0703, + 0x81C, 0xE91C0703, + 0x81C, 0xCA1E0703, + 0x81C, 0xC9200703, + 0x81C, 0xC8220703, + 0x81C, 0xC7240703, + 0x81C, 0xC6260703, + 0x81C, 0xC5280703, + 0x81C, 0xC42A0703, + 0x81C, 0xC32C0703, + 0x81C, 0xC22E0703, + 0x81C, 0xC1300703, + 0x81C, 0xA4320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x414C0703, + 0x81C, 0x404E0703, + 0x81C, 0x22500703, + 0x81C, 0x21520703, + 0x81C, 0x20540703, + 0x81C, 0x03560703, + 0x81C, 0x02580703, + 0x81C, 0x015A0703, + 0x81C, 0x005C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000703, + 0x81C, 0xFB020703, + 0x81C, 0xFA040703, + 0x81C, 0xF9060703, + 0x81C, 0xF8080703, + 0x81C, 0xF70A0703, + 0x81C, 0xF60C0703, + 0x81C, 0xF50E0703, + 0x81C, 0xF4100703, + 0x81C, 0xF3120703, + 0x81C, 0xF2140703, + 0x81C, 0xF1160703, + 0x81C, 0xF0180703, + 0x81C, 0xEF1A0703, + 0x81C, 0xEE1C0703, + 0x81C, 0xED1E0703, + 0x81C, 0xEC200703, + 0x81C, 0xEB220703, + 0x81C, 0xEA240703, + 0x81C, 0xE9260703, + 0x81C, 0xE8280703, + 0x81C, 0xE72A0703, + 0x81C, 0xE62C0703, + 0x81C, 0xE52E0703, + 0x81C, 0xE4300703, + 0x81C, 0xE3320703, + 0x81C, 0xE2340703, + 0x81C, 0xC6360703, + 0x81C, 0xC5380703, + 0x81C, 0xC43A0703, + 0x81C, 0xC33C0703, + 0x81C, 0xA63E0703, + 0x81C, 0xA5400703, + 0x81C, 0xA4420703, + 0x81C, 0xA3440703, + 0x81C, 0xA2460703, + 0x81C, 0x84480703, + 0x81C, 0x834A0703, + 0x81C, 0x824C0703, + 0x81C, 0x814E0703, + 0x81C, 0x80500703, + 0x81C, 0x63520703, + 0x81C, 0x62540703, + 0x81C, 0x61560703, + 0x81C, 0x60580703, + 0x81C, 0x225A0703, + 0x81C, 0x055C0703, + 0x81C, 0x045E0703, + 0x81C, 0x03600703, + 0x81C, 0x02620703, + 0x81C, 0x01640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000703, + 0x81C, 0xF6020703, + 0x81C, 0xF5040703, + 0x81C, 0xF4060703, + 0x81C, 0xF3080703, + 0x81C, 0xF20A0703, + 0x81C, 0xF10C0703, + 0x81C, 0xF00E0703, + 0x81C, 0xEF100703, + 0x81C, 0xEE120703, + 0x81C, 0xED140703, + 0x81C, 0xEC160703, + 0x81C, 0xEB180703, + 0x81C, 0xEA1A0703, + 0x81C, 0xE91C0703, + 0x81C, 0xCA1E0703, + 0x81C, 0xC9200703, + 0x81C, 0xC8220703, + 0x81C, 0xC7240703, + 0x81C, 0xC6260703, + 0x81C, 0xC5280703, + 0x81C, 0xC42A0703, + 0x81C, 0xC32C0703, + 0x81C, 0xC22E0703, + 0x81C, 0xC1300703, + 0x81C, 0xA4320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x414C0703, + 0x81C, 0x404E0703, + 0x81C, 0x22500703, + 0x81C, 0x21520703, + 0x81C, 0x20540703, + 0x81C, 0x03560703, + 0x81C, 0x02580703, + 0x81C, 0x015A0703, + 0x81C, 0x005C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000703, + 0x81C, 0xFA020703, + 0x81C, 0xF9040703, + 0x81C, 0xF8060703, + 0x81C, 0xF7080703, + 0x81C, 0xF60A0703, + 0x81C, 0xF50C0703, + 0x81C, 0xF40E0703, + 0x81C, 0xF3100703, + 0x81C, 0xF2120703, + 0x81C, 0xF1140703, + 0x81C, 0xF0160703, + 0x81C, 0xEF180703, + 0x81C, 0xEE1A0703, + 0x81C, 0xED1C0703, + 0x81C, 0xEC1E0703, + 0x81C, 0xEB200703, + 0x81C, 0xEA220703, + 0x81C, 0xE9240703, + 0x81C, 0xE8260703, + 0x81C, 0xE7280703, + 0x81C, 0xE62A0703, + 0x81C, 0xE52C0703, + 0x81C, 0xE42E0703, + 0x81C, 0xE3300703, + 0x81C, 0xE2320703, + 0x81C, 0xE1340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xC23C0703, + 0x81C, 0xC13E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x64500703, + 0x81C, 0x63520703, + 0x81C, 0x62540703, + 0x81C, 0x61560703, + 0x81C, 0x60580703, + 0x81C, 0x235A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000703, + 0x81C, 0xF8020703, + 0x81C, 0xF7040703, + 0x81C, 0xF6060703, + 0x81C, 0xF5080703, + 0x81C, 0xF40A0703, + 0x81C, 0xF30C0703, + 0x81C, 0xF20E0703, + 0x81C, 0xF1100703, + 0x81C, 0xF0120703, + 0x81C, 0xEF140703, + 0x81C, 0xEE160703, + 0x81C, 0xED180703, + 0x81C, 0xEC1A0703, + 0x81C, 0xEB1C0703, + 0x81C, 0xEA1E0703, + 0x81C, 0xC9200703, + 0x81C, 0xC8220703, + 0x81C, 0xC7240703, + 0x81C, 0xC6260703, + 0x81C, 0xC5280703, + 0x81C, 0xC42A0703, + 0x81C, 0xC32C0703, + 0x81C, 0xC22E0703, + 0x81C, 0xC1300703, + 0x81C, 0xC0320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x414C0703, + 0x81C, 0x404E0703, + 0x81C, 0x22500703, + 0x81C, 0x21520703, + 0x81C, 0x20540703, + 0x81C, 0x03560703, + 0x81C, 0x02580703, + 0x81C, 0x015A0703, + 0x81C, 0x005C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBE000703, + 0x81C, 0xBD020703, + 0x81C, 0xBC040703, + 0x81C, 0xBB060703, + 0x81C, 0xBA080703, + 0x81C, 0xB90A0703, + 0x81C, 0xB80C0703, + 0x81C, 0xB70E0703, + 0x81C, 0xB6100703, + 0x81C, 0xB5120703, + 0x81C, 0xB4140703, + 0x81C, 0xB3160703, + 0x81C, 0xB2180703, + 0x81C, 0xB11A0703, + 0x81C, 0xB01C0703, + 0x81C, 0x921E0703, + 0x81C, 0x91200703, + 0x81C, 0x90220703, + 0x81C, 0x8F240703, + 0x81C, 0x8E260703, + 0x81C, 0x8D280703, + 0x81C, 0x8C2A0703, + 0x81C, 0x6F2C0703, + 0x81C, 0x6E2E0703, + 0x81C, 0x6D300703, + 0x81C, 0x6C320703, + 0x81C, 0x6B340703, + 0x81C, 0x6A360703, + 0x81C, 0x69380703, + 0x81C, 0x683A0703, + 0x81C, 0x673C0703, + 0x81C, 0x663E0703, + 0x81C, 0x65400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x424C0703, + 0x81C, 0x414E0703, + 0x81C, 0x40500703, + 0x81C, 0x06520703, + 0x81C, 0x05540703, + 0x81C, 0x04560703, + 0x81C, 0x03580703, + 0x81C, 0x025A0703, + 0x81C, 0x015C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000703, + 0x81C, 0xFA020703, + 0x81C, 0xF9040703, + 0x81C, 0xF8060703, + 0x81C, 0xF7080703, + 0x81C, 0xF60A0703, + 0x81C, 0xF50C0703, + 0x81C, 0xF40E0703, + 0x81C, 0xF3100703, + 0x81C, 0xF2120703, + 0x81C, 0xF1140703, + 0x81C, 0xF0160703, + 0x81C, 0xEF180703, + 0x81C, 0xEE1A0703, + 0x81C, 0xED1C0703, + 0x81C, 0xEC1E0703, + 0x81C, 0xEB200703, + 0x81C, 0xEA220703, + 0x81C, 0xE9240703, + 0x81C, 0xE8260703, + 0x81C, 0xE7280703, + 0x81C, 0xE62A0703, + 0x81C, 0xE52C0703, + 0x81C, 0xE42E0703, + 0x81C, 0xE3300703, + 0x81C, 0xE2320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xC23C0703, + 0x81C, 0xC13E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x43540703, + 0x81C, 0x42560703, + 0x81C, 0x41580703, + 0x81C, 0x235A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000703, + 0x81C, 0xF7020703, + 0x81C, 0xF6040703, + 0x81C, 0xF5060703, + 0x81C, 0xF4080703, + 0x81C, 0xF30A0703, + 0x81C, 0xF20C0703, + 0x81C, 0xF10E0703, + 0x81C, 0xF0100703, + 0x81C, 0xEF120703, + 0x81C, 0xEE140703, + 0x81C, 0xED160703, + 0x81C, 0xEC180703, + 0x81C, 0xEB1A0703, + 0x81C, 0xEA1C0703, + 0x81C, 0xE91E0703, + 0x81C, 0xCA200703, + 0x81C, 0xC9220703, + 0x81C, 0xC8240703, + 0x81C, 0xC7260703, + 0x81C, 0xC6280703, + 0x81C, 0xC52A0703, + 0x81C, 0xC42C0703, + 0x81C, 0xC32E0703, + 0x81C, 0xC2300703, + 0x81C, 0xC1320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x65420703, + 0x81C, 0x64440703, + 0x81C, 0x63460703, + 0x81C, 0x62480703, + 0x81C, 0x614A0703, + 0x81C, 0x424C0703, + 0x81C, 0x414E0703, + 0x81C, 0x40500703, + 0x81C, 0x22520703, + 0x81C, 0x21540703, + 0x81C, 0x20560703, + 0x81C, 0x04580703, + 0x81C, 0x035A0703, + 0x81C, 0x025C0703, + 0x81C, 0x015E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000703, + 0x81C, 0xFB020703, + 0x81C, 0xFA040703, + 0x81C, 0xF9060703, + 0x81C, 0xF8080703, + 0x81C, 0xF70A0703, + 0x81C, 0xF60C0703, + 0x81C, 0xF50E0703, + 0x81C, 0xF4100703, + 0x81C, 0xF3120703, + 0x81C, 0xF2140703, + 0x81C, 0xF1160703, + 0x81C, 0xEF180703, + 0x81C, 0xEE1A0703, + 0x81C, 0xED1C0703, + 0x81C, 0xEC1E0703, + 0x81C, 0xEB200703, + 0x81C, 0xEA220703, + 0x81C, 0xE9240703, + 0x81C, 0xE8260703, + 0x81C, 0xE7280703, + 0x81C, 0xE62A0703, + 0x81C, 0xE52C0703, + 0x81C, 0xE42E0703, + 0x81C, 0xE3300703, + 0x81C, 0xE2320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xA63C0703, + 0x81C, 0xA53E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x61540703, + 0x81C, 0x42560703, + 0x81C, 0x41580703, + 0x81C, 0x405A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000703, + 0x81C, 0xF7020703, + 0x81C, 0xF6040703, + 0x81C, 0xF5060703, + 0x81C, 0xF4080703, + 0x81C, 0xF30A0703, + 0x81C, 0xF20C0703, + 0x81C, 0xF10E0703, + 0x81C, 0xF0100703, + 0x81C, 0xEF120703, + 0x81C, 0xEE140703, + 0x81C, 0xED160703, + 0x81C, 0xEC180703, + 0x81C, 0xEB1A0703, + 0x81C, 0xEA1C0703, + 0x81C, 0xE91E0703, + 0x81C, 0xCA200703, + 0x81C, 0xC9220703, + 0x81C, 0xC8240703, + 0x81C, 0xC7260703, + 0x81C, 0xC6280703, + 0x81C, 0xC52A0703, + 0x81C, 0xC42C0703, + 0x81C, 0xC32E0703, + 0x81C, 0xC2300703, + 0x81C, 0xC1320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x234C0703, + 0x81C, 0x224E0703, + 0x81C, 0x21500703, + 0x81C, 0x20520703, + 0x81C, 0x06540703, + 0x81C, 0x05560703, + 0x81C, 0x04580703, + 0x81C, 0x035A0703, + 0x81C, 0x025C0703, + 0x81C, 0x015E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000703, + 0x81C, 0xFB020703, + 0x81C, 0xFA040703, + 0x81C, 0xF9060703, + 0x81C, 0xF8080703, + 0x81C, 0xF70A0703, + 0x81C, 0xF60C0703, + 0x81C, 0xF50E0703, + 0x81C, 0xF4100703, + 0x81C, 0xF3120703, + 0x81C, 0xF2140703, + 0x81C, 0xF1160703, + 0x81C, 0xF0180703, + 0x81C, 0xEF1A0703, + 0x81C, 0xEE1C0703, + 0x81C, 0xED1E0703, + 0x81C, 0xEC200703, + 0x81C, 0xEB220703, + 0x81C, 0xEA240703, + 0x81C, 0xE9260703, + 0x81C, 0xE8280703, + 0x81C, 0xE72A0703, + 0x81C, 0xE62C0703, + 0x81C, 0xE52E0703, + 0x81C, 0xE4300703, + 0x81C, 0xE3320703, + 0x81C, 0xE2340703, + 0x81C, 0xC6360703, + 0x81C, 0xC5380703, + 0x81C, 0xC43A0703, + 0x81C, 0xC33C0703, + 0x81C, 0xA63E0703, + 0x81C, 0xA5400703, + 0x81C, 0xA4420703, + 0x81C, 0xA3440703, + 0x81C, 0xA2460703, + 0x81C, 0x84480703, + 0x81C, 0x834A0703, + 0x81C, 0x824C0703, + 0x81C, 0x814E0703, + 0x81C, 0x80500703, + 0x81C, 0x63520703, + 0x81C, 0x62540703, + 0x81C, 0x61560703, + 0x81C, 0x60580703, + 0x81C, 0x225A0703, + 0x81C, 0x055C0703, + 0x81C, 0x045E0703, + 0x81C, 0x03600703, + 0x81C, 0x02620703, + 0x81C, 0x01640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000703, + 0x81C, 0xFA020703, + 0x81C, 0xF9040703, + 0x81C, 0xF8060703, + 0x81C, 0xF7080703, + 0x81C, 0xF60A0703, + 0x81C, 0xF50C0703, + 0x81C, 0xF40E0703, + 0x81C, 0xF3100703, + 0x81C, 0xF2120703, + 0x81C, 0xF1140703, + 0x81C, 0xEF160703, + 0x81C, 0xEE180703, + 0x81C, 0xED1A0703, + 0x81C, 0xEC1C0703, + 0x81C, 0xEB1E0703, + 0x81C, 0xEA200703, + 0x81C, 0xE9220703, + 0x81C, 0xE8240703, + 0x81C, 0xE7260703, + 0x81C, 0xE6280703, + 0x81C, 0xE52A0703, + 0x81C, 0xE42C0703, + 0x81C, 0xE32E0703, + 0x81C, 0xE2300703, + 0x81C, 0xE1320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xA63C0703, + 0x81C, 0xA53E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x61540703, + 0x81C, 0x42560703, + 0x81C, 0x41580703, + 0x81C, 0x405A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000703, + 0x81C, 0xFA020703, + 0x81C, 0xF9040703, + 0x81C, 0xF8060703, + 0x81C, 0xF7080703, + 0x81C, 0xF60A0703, + 0x81C, 0xF50C0703, + 0x81C, 0xF40E0703, + 0x81C, 0xF3100703, + 0x81C, 0xF2120703, + 0x81C, 0xF1140703, + 0x81C, 0xEF160703, + 0x81C, 0xEE180703, + 0x81C, 0xED1A0703, + 0x81C, 0xEC1C0703, + 0x81C, 0xEB1E0703, + 0x81C, 0xEA200703, + 0x81C, 0xE9220703, + 0x81C, 0xE8240703, + 0x81C, 0xE7260703, + 0x81C, 0xE6280703, + 0x81C, 0xE52A0703, + 0x81C, 0xE42C0703, + 0x81C, 0xE32E0703, + 0x81C, 0xE2300703, + 0x81C, 0xE1320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xA63C0703, + 0x81C, 0xA53E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0xA1460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x61540703, + 0x81C, 0x42560703, + 0x81C, 0x41580703, + 0x81C, 0x405A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x04620703, + 0x81C, 0x03640703, + 0x81C, 0x02660703, + 0x81C, 0x01680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x9000000f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xBF000703, + 0x81C, 0xBF020703, + 0x81C, 0xBF040703, + 0x81C, 0xBF060703, + 0x81C, 0xBF080703, + 0x81C, 0xBE0A0703, + 0x81C, 0xBD0C0703, + 0x81C, 0xBC0E0703, + 0x81C, 0xBB100703, + 0x81C, 0xBA120703, + 0x81C, 0xB9140703, + 0x81C, 0xB8160703, + 0x81C, 0xB7180703, + 0x81C, 0xB61A0703, + 0x81C, 0xB51C0703, + 0x81C, 0xB41E0703, + 0x81C, 0xB1200703, + 0x81C, 0xB2220703, + 0x81C, 0xB1240703, + 0x81C, 0xB0260703, + 0x81C, 0xAF280703, + 0x81C, 0xAE2A0703, + 0x81C, 0xAD2C0703, + 0x81C, 0xAC2E0703, + 0x81C, 0xAB300703, + 0x81C, 0xAA320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0x883C0703, + 0x81C, 0x873E0703, + 0x81C, 0x86400703, + 0x81C, 0x85420703, + 0x81C, 0x84440703, + 0x81C, 0x83460703, + 0x81C, 0x67480703, + 0x81C, 0x664A0703, + 0x81C, 0x654C0703, + 0x81C, 0x644E0703, + 0x81C, 0x27500703, + 0x81C, 0x26520703, + 0x81C, 0x25540703, + 0x81C, 0x24560703, + 0x81C, 0x23580703, + 0x81C, 0x225A0703, + 0x81C, 0x215C0703, + 0x81C, 0x205E0703, + 0x81C, 0x03600703, + 0x81C, 0x02620703, + 0x81C, 0x01640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0x90000010, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000403, + 0x81C, 0xFB000703, + 0x81C, 0xFA020703, + 0x81C, 0xF9040703, + 0x81C, 0xF8060703, + 0x81C, 0xF7080703, + 0x81C, 0xF60A0703, + 0x81C, 0xF50C0703, + 0x81C, 0xF40E0703, + 0x81C, 0xF3100703, + 0x81C, 0xF2120703, + 0x81C, 0xF1140703, + 0x81C, 0xF0160703, + 0x81C, 0xEF180703, + 0x81C, 0xEE1A0703, + 0x81C, 0xED1C0703, + 0x81C, 0xEC1E0703, + 0x81C, 0xEB200703, + 0x81C, 0xEA220703, + 0x81C, 0xE9240703, + 0x81C, 0xE8260703, + 0x81C, 0xE7280703, + 0x81C, 0xE62A0703, + 0x81C, 0xE52C0703, + 0x81C, 0xE42E0703, + 0x81C, 0xE3300703, + 0x81C, 0xE2320703, + 0x81C, 0xC6340703, + 0x81C, 0xC5360703, + 0x81C, 0xC4380703, + 0x81C, 0xC33A0703, + 0x81C, 0xA63C0703, + 0x81C, 0xA53E0703, + 0x81C, 0xA4400703, + 0x81C, 0xA3420703, + 0x81C, 0xA2440703, + 0x81C, 0x84460703, + 0x81C, 0x83480703, + 0x81C, 0x824A0703, + 0x81C, 0x814C0703, + 0x81C, 0x804E0703, + 0x81C, 0x63500703, + 0x81C, 0x62520703, + 0x81C, 0x61540703, + 0x81C, 0x60560703, + 0x81C, 0x22580703, + 0x81C, 0x055A0703, + 0x81C, 0x045C0703, + 0x81C, 0x035E0703, + 0x81C, 0x02600703, + 0x81C, 0x01620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x90000012, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000703, + 0x81C, 0xF6020703, + 0x81C, 0xF5040703, + 0x81C, 0xF4060703, + 0x81C, 0xF3080703, + 0x81C, 0xF20A0703, + 0x81C, 0xF10C0703, + 0x81C, 0xF00E0703, + 0x81C, 0xEF100703, + 0x81C, 0xEE120703, + 0x81C, 0xED140703, + 0x81C, 0xEC160703, + 0x81C, 0xEB180703, + 0x81C, 0xEA1A0703, + 0x81C, 0xE91C0703, + 0x81C, 0xCA1E0703, + 0x81C, 0xC9200703, + 0x81C, 0xC8220703, + 0x81C, 0xC7240703, + 0x81C, 0xC6260703, + 0x81C, 0xC5280703, + 0x81C, 0xC42A0703, + 0x81C, 0xC32C0703, + 0x81C, 0xC22E0703, + 0x81C, 0xC1300703, + 0x81C, 0xA4320703, + 0x81C, 0xA3340703, + 0x81C, 0xA2360703, + 0x81C, 0xA1380703, + 0x81C, 0xA03A0703, + 0x81C, 0x823C0703, + 0x81C, 0x813E0703, + 0x81C, 0x80400703, + 0x81C, 0x64420703, + 0x81C, 0x63440703, + 0x81C, 0x62460703, + 0x81C, 0x61480703, + 0x81C, 0x604A0703, + 0x81C, 0x414C0703, + 0x81C, 0x404E0703, + 0x81C, 0x22500703, + 0x81C, 0x21520703, + 0x81C, 0x20540703, + 0x81C, 0x03560703, + 0x81C, 0x02580703, + 0x81C, 0x015A0703, + 0x81C, 0x005C0703, + 0x81C, 0x005E0703, + 0x81C, 0x00600703, + 0x81C, 0x00620703, + 0x81C, 0x00640703, + 0x81C, 0x00660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000703, + 0x81C, 0xFB020703, + 0x81C, 0xFA040703, + 0x81C, 0xF9060703, + 0x81C, 0xF8080703, + 0x81C, 0xF70A0703, + 0x81C, 0xF60C0703, + 0x81C, 0xF50E0703, + 0x81C, 0xF4100703, + 0x81C, 0xF3120703, + 0x81C, 0xF2140703, + 0x81C, 0xF1160703, + 0x81C, 0xF0180703, + 0x81C, 0xEF1A0703, + 0x81C, 0xEE1C0703, + 0x81C, 0xED1E0703, + 0x81C, 0xEC200703, + 0x81C, 0xEB220703, + 0x81C, 0xEA240703, + 0x81C, 0xE9260703, + 0x81C, 0xE8280703, + 0x81C, 0xE72A0703, + 0x81C, 0xE62C0703, + 0x81C, 0xE52E0703, + 0x81C, 0xE4300703, + 0x81C, 0xE3320703, + 0x81C, 0xE2340703, + 0x81C, 0xC6360703, + 0x81C, 0xC5380703, + 0x81C, 0xC43A0703, + 0x81C, 0xC33C0703, + 0x81C, 0xA63E0703, + 0x81C, 0xA5400703, + 0x81C, 0xA4420703, + 0x81C, 0xA3440703, + 0x81C, 0xA2460703, + 0x81C, 0x84480703, + 0x81C, 0x834A0703, + 0x81C, 0x824C0703, + 0x81C, 0x814E0703, + 0x81C, 0x80500703, + 0x81C, 0x63520703, + 0x81C, 0x62540703, + 0x81C, 0x61560703, + 0x81C, 0x60580703, + 0x81C, 0x235A0703, + 0x81C, 0x225C0703, + 0x81C, 0x215E0703, + 0x81C, 0x20600703, + 0x81C, 0x03620703, + 0x81C, 0x02640703, + 0x81C, 0x01660703, + 0x81C, 0x00680703, + 0x81C, 0x006A0703, + 0x81C, 0x006C0703, + 0x81C, 0x006E0703, + 0x81C, 0x00700703, + 0x81C, 0x00720703, + 0x81C, 0x00740703, + 0x81C, 0x00760703, + 0x81C, 0x00780703, + 0x81C, 0x007A0703, + 0x81C, 0x007C0703, + 0x81C, 0x007E0703, + 0x81C, 0x007E0703, + 0xB0000000, 0x00000000, + 0x80000000, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0x9000000d, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0x9000000e, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0xA0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0xB0000000, 0x00000000, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822b_agc, rtw_phy_cfg_agc); + +static const u32 rtw8822b_bb[] = { + 0x800, 0x9020D010, + 0x804, 0x800181A0, + 0x808, 0x0E028233, + 0x80C, 0x10000013, + 0x810, 0x22101243, + 0x814, 0x020C3D11, + 0x818, 0x84A10385, + 0x81C, 0x1E1E081F, + 0x820, 0x0001AAAA, + 0x824, 0x00030FE0, + 0x828, 0x0000CCCC, + 0x82C, 0x75CB7010, + 0x830, 0x79A0EAAA, + 0x834, 0x072E6986, + 0x838, 0x87766441, + 0x83C, 0x9194B2B7, + 0x840, 0x171750E0, + 0x844, 0x4D3D7CDB, + 0x848, 0x4AD0408B, + 0x84C, 0x6AFBF7A5, + 0x850, 0x28A74706, + 0x854, 0x0001520C, + 0x858, 0x4060C000, + 0x85C, 0x74010160, + 0x860, 0x68A7C321, + 0x864, 0x79F27032, + 0x868, 0x8CA7A314, + 0x86C, 0x778C2878, + 0x870, 0x77777777, + 0x874, 0x27612C2E, + 0x878, 0xC0003152, + 0x87C, 0x5C8FC000, + 0x880, 0x00000000, + 0x884, 0x00000000, + 0x888, 0x00000000, + 0x88C, 0x00000000, + 0x890, 0x00000000, + 0x894, 0x00000000, + 0x898, 0x00000000, + 0x89C, 0x00000000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0x2202033E, + 0x8AC, 0xF00F000A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0xEC0057F7, + 0x8BC, 0xACB520A3, + 0x8C0, 0xFFE04020, + 0x8C4, 0x47C00000, + 0x8C8, 0x000251A5, + 0x8CC, 0x08108492, + 0x8D0, 0x0000B800, + 0x8D4, 0x860308A0, + 0x8D8, 0x29095612, + 0x8DC, 0x00000000, + 0x8E0, 0x32D16777, + 0x8E4, 0x4C098935, + 0x8E8, 0xFFFFC42C, + 0x8EC, 0x99999999, + 0x8F0, 0x00009999, + 0x8F4, 0x00D80FA1, + 0x8F8, 0x40000080, + 0x8FC, 0x00000130, + 0x900, 0x00800000, + 0x904, 0x00000000, + 0x908, 0x00000000, + 0x90C, 0xD3000000, + 0x910, 0x0000FC00, + 0x914, 0xC6380000, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x855A2500, + 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFEB200, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x938, 0x00008480, + 0x93C, 0xE41C0642, + 0x940, 0x0E470430, + 0x944, 0x00000000, + 0x948, 0xAC000000, + 0x94C, 0x10000083, + 0x950, 0x32010080, + 0x954, 0x84510080, + 0x958, 0x00000001, + 0x95C, 0x04248000, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x00001FFF, + 0x974, 0x44000FFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x98C, 0x43440000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x80000088, + 0x9A8, 0x0C2F0000, + 0x9AC, 0x01560000, + 0x9B0, 0x70000000, + 0x9B4, 0x00000000, + 0x9B8, 0x00000000, + 0x9BC, 0x00000000, + 0x9C0, 0x00000000, + 0x9C4, 0x00000000, + 0x9C8, 0x00000000, + 0x9CC, 0x00000000, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00000000, + 0x9E4, 0x02000402, + 0x9E8, 0x000022D4, + 0x9EC, 0x00000000, + 0x9F0, 0x00010080, + 0x9F4, 0x00000000, + 0x9F8, 0x00000000, + 0x9FC, 0xEFFFF7F7, + 0xA00, 0x00D047C8, + 0xA04, 0x81FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E20100F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x84880000, + 0xA24, 0x384F6577, + 0xA28, 0x00001525, + 0xA2C, 0x00920000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000148, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218675B2, + 0xA84, 0x80208C00, + 0xA88, 0x040C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x030A0000, + 0xA9C, 0x00060000, + 0xAA0, 0x00000000, + 0xAA4, 0x0004000F, + 0xAA8, 0x00000200, + 0xB00, 0xE1000440, + 0xB04, 0x00800000, + 0xB08, 0xFF02030B, + 0xB0C, 0x01EAA406, + 0xB10, 0x00030690, + 0xB14, 0x006000FA, + 0xB18, 0x00000002, + 0xB1C, 0x00000002, + 0xB20, 0x4B00001F, + 0xB24, 0x4E8E3E40, + 0xB28, 0x03020100, + 0xB2C, 0x07060504, + 0xB30, 0x0B0A0908, + 0xB34, 0x0F0E0D0C, + 0xB38, 0x13121110, + 0xB3C, 0x0000003A, + 0xB40, 0x00000000, + 0xB44, 0x80000000, + 0xB48, 0x3F0000FA, + 0xB4C, 0x88C80020, + 0xB50, 0x00000000, + 0xB54, 0x00004241, + 0xB58, 0xE0008208, + 0xB5C, 0x41EFFFF9, + 0xB60, 0x00000000, + 0xB64, 0x00200063, + 0xB68, 0x0000003A, + 0xB6C, 0x00000102, + 0xB70, 0x4E6D1870, + 0xB74, 0x03020100, + 0xB78, 0x07060504, + 0xB7C, 0x0B0A0908, + 0xB80, 0x0F0E0D0C, + 0xB84, 0x13121110, + 0xB88, 0x00000000, + 0xB8C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x00000020, + 0xC08, 0x60403231, + 0xC0C, 0x00012345, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC18, 0x00000000, + 0xC1C, 0x40040053, + 0xC20, 0x40020103, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x00000000, + 0xC34, 0x00000000, + 0xC38, 0x00000000, + 0xC3C, 0x00000000, + 0xC40, 0x00000000, + 0xC44, 0x00000000, + 0xC48, 0x00000000, + 0xC4C, 0x00000000, + 0xC50, 0x00000020, + 0xC54, 0x00000000, + 0xC58, 0xD8020402, + 0xC5C, 0xDE000120, + 0xC68, 0x5979993F, + 0xC6C, 0x0000122A, + 0xC70, 0x99795979, + 0xC74, 0x99795979, + 0xC78, 0x99799979, + 0xC7C, 0x99791979, + 0xC80, 0x19791979, + 0xC84, 0x19791979, + 0xC88, 0x00000000, + 0xC8C, 0x07000000, + 0xC94, 0x01000100, + 0xC98, 0x201C8000, + 0xC9C, 0x00000000, + 0xCA0, 0x0000A555, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCAC, 0x00000000, + 0xCB0, 0x77777777, + 0xCB4, 0x00007777, + 0xCB8, 0x00000000, + 0xCBC, 0x00000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x00000000, + 0xCDC, 0x00000000, + 0xCE0, 0x00000000, + 0xCE4, 0x00000000, + 0xCE8, 0x00000000, + 0xCEC, 0x00000000, + 0xE00, 0x00000007, + 0xE04, 0x00000020, + 0xE08, 0x60403231, + 0xE0C, 0x00012345, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE18, 0x00000000, + 0xE1C, 0x40040053, + 0xE20, 0x40020103, + 0xE24, 0x00000000, + 0xE28, 0x00000000, + 0xE2C, 0x00000000, + 0xE30, 0x00000000, + 0xE34, 0x00000000, + 0xE38, 0x00000000, + 0xE3C, 0x00000000, + 0xE40, 0x00000000, + 0xE44, 0x00000000, + 0xE48, 0x00000000, + 0xE4C, 0x00000000, + 0xE50, 0x00000020, + 0xE54, 0x00000000, + 0xE58, 0xD8120402, + 0xE5C, 0xDE000120, + 0xE68, 0x5979993F, + 0xE6C, 0x0000122A, + 0xE70, 0x99795979, + 0xE74, 0x99795979, + 0xE78, 0x99799979, + 0xE7C, 0x99791979, + 0xE80, 0x19791979, + 0xE84, 0x19791979, + 0xE88, 0x00000000, + 0xE8C, 0x07000000, + 0xE94, 0x01000100, + 0xE98, 0x201C8000, + 0xE9C, 0x00000000, + 0xEA0, 0x0000A555, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEAC, 0x00000000, + 0xEB0, 0x77777777, + 0xEB4, 0x00007777, + 0xEB8, 0x00000000, + 0xEBC, 0x00000000, + 0xEC0, 0x00000000, + 0xEC4, 0x00000000, + 0xEC8, 0x00000000, + 0xECC, 0x00000000, + 0xED0, 0x00000000, + 0xED4, 0x00000000, + 0xED8, 0x00000000, + 0xEDC, 0x00000000, + 0xEE0, 0x00000000, + 0xEE4, 0x00000000, + 0xEE8, 0x00000000, + 0xEEC, 0x00000000, + 0x1900, 0x00000000, + 0x1904, 0x00238000, + 0x1908, 0x00000000, + 0x190C, 0x00000000, + 0x1910, 0x00000000, + 0x1914, 0x00000000, + 0x1918, 0x00000000, + 0x191C, 0x00000000, + 0x1920, 0x00000000, + 0x1924, 0x00000000, + 0x1928, 0x00000000, + 0x192C, 0x00000000, + 0x1930, 0x00000000, + 0x1934, 0x00000000, + 0x1938, 0x00000000, + 0x193C, 0x00000000, + 0x1940, 0x00000000, + 0x1944, 0x00000000, + 0x1948, 0x00000000, + 0x194C, 0x00000000, + 0x1950, 0x00000000, + 0x1954, 0x00000000, + 0x1958, 0x00000000, + 0x195C, 0x00000000, + 0x1960, 0x00000000, + 0x1964, 0x00000000, + 0x1968, 0x00000000, + 0x196C, 0x00000000, + 0x1970, 0x00000000, + 0x1974, 0x00000000, + 0x1978, 0x00000000, + 0x197C, 0x00000000, + 0x1980, 0x00000000, + 0x1984, 0x03000000, + 0x1988, 0x21401E88, + 0x198C, 0x00004000, + 0x1990, 0x00000000, + 0x1994, 0x00000000, + 0x1998, 0x00000053, + 0x199C, 0x00000000, + 0x19A0, 0x00000000, + 0x19A4, 0x00000000, + 0x19A8, 0x00000000, + 0x19AC, 0x0E47E47F, + 0x19B0, 0x00000000, + 0x19B4, 0x0E47E47F, + 0x19B8, 0x00000000, + 0x19BC, 0x00000000, + 0x19C0, 0x00000000, + 0x19C4, 0x00000000, + 0x19C8, 0x00000000, + 0x19CC, 0x00000000, + 0x19D0, 0x00000000, + 0x19D4, 0xAAAAAAAA, + 0x19D8, 0x00000AAA, + 0x19DC, 0x133E0F37, + 0x19E0, 0x00000000, + 0x19E4, 0x00000000, + 0x19E8, 0x00000000, + 0x19EC, 0x00000000, + 0x19F0, 0x00000000, + 0x19F4, 0x00000000, + 0x19F8, 0x01A00000, + 0x19FC, 0x00000000, + 0x1C00, 0x00000100, + 0x1C04, 0x01000000, + 0x1C08, 0x00000100, + 0x1C0C, 0x01000000, + 0x1C10, 0x00000100, + 0x1C14, 0x01000000, + 0x1C18, 0x00000100, + 0x1C1C, 0x01000000, + 0x1C20, 0x00000100, + 0x1C24, 0x01000000, + 0x1C28, 0x00000100, + 0x1C2C, 0x01000000, + 0x1C30, 0x00000100, + 0x1C34, 0x01000000, + 0x1C38, 0x00000000, + 0x1C3C, 0x00000000, + 0x1C40, 0x000C0100, + 0x1C44, 0x000000F3, + 0x1C48, 0x1A8249A8, + 0x1C4C, 0x1461C826, + 0x1C50, 0x0001469E, + 0x1C54, 0x58D158D1, + 0x1C58, 0x04490088, + 0x1C5C, 0x04004400, + 0x1C60, 0x00000000, + 0x1C64, 0x04004400, + 0x1C68, 0x00000100, + 0x1C6C, 0x01000000, + 0x1C70, 0x00000100, + 0x1C74, 0x01000000, + 0x1C78, 0x00000000, + 0x1C7C, 0x00000010, + 0x1C80, 0x5FFF5FFF, + 0x1C84, 0x5FFF5FFF, + 0x1C88, 0x5FFF5FFF, + 0x1C8C, 0x5FFF5FFF, + 0x1C90, 0x5FFF5FFF, + 0x1C94, 0x5FFF5FFF, + 0x1C98, 0x5FFF5FFF, + 0x1C9C, 0x5FFF5FFF, + 0x1CA0, 0x00000100, + 0x1CA4, 0x01000000, + 0x1CA8, 0x00000100, + 0x1CAC, 0x5FFF5FFF, + 0x1CB0, 0x00000100, + 0x1CB4, 0x01000000, + 0x1CB8, 0x00000000, + 0x1CBC, 0x00000000, + 0x1CC0, 0x00000100, + 0x1CC4, 0x01000000, + 0x1CC8, 0x00000100, + 0x1CCC, 0x01000000, + 0x1CD0, 0x00000100, + 0x1CD4, 0x01000000, + 0x1CD8, 0x00000100, + 0x1CDC, 0x01000000, + 0x1CE0, 0x00000100, + 0x1CE4, 0x01000000, + 0x1CE8, 0x00000100, + 0x1CEC, 0x01000000, + 0x1CF0, 0x00000100, + 0x1CF4, 0x01000000, + 0x1CF8, 0x00000000, + 0x1CFC, 0x00000000, + 0xC60, 0x70038040, + 0xC60, 0x70038040, + 0xC60, 0x70146040, + 0xC60, 0x70246040, + 0xC60, 0x70346040, + 0xC60, 0x70446040, + 0xC60, 0x70532040, + 0xC60, 0x70646040, + 0xC60, 0x70738040, + 0xC60, 0x70838040, + 0xC60, 0x70938040, + 0xC60, 0x70A38040, + 0xC60, 0x70B36040, + 0xC60, 0x70C06040, + 0xC60, 0x70D06040, + 0xC60, 0x70E76040, + 0xC60, 0x70F06040, + 0xE60, 0x70038040, + 0xE60, 0x70038040, + 0xE60, 0x70146040, + 0xE60, 0x70246040, + 0xE60, 0x70346040, + 0xE60, 0x70446040, + 0xE60, 0x70532040, + 0xE60, 0x70646040, + 0xE60, 0x70738040, + 0xE60, 0x70838040, + 0xE60, 0x70938040, + 0xE60, 0x70A38040, + 0xE60, 0x70B36040, + 0xE60, 0x70C06040, + 0xE60, 0x70D06040, + 0xE60, 0x70E76040, + 0xE60, 0x70F06040, + 0xC64, 0x00800000, + 0xC64, 0x08800001, + 0xC64, 0x00800002, + 0xC64, 0x00800003, + 0xC64, 0x00800004, + 0xC64, 0x00800005, + 0xC64, 0x00800006, + 0xC64, 0x08800007, + 0xC64, 0x00004000, + 0xE64, 0x00800000, + 0xE64, 0x08800001, + 0xE64, 0x00800002, + 0xE64, 0x00800003, + 0xE64, 0x00800004, + 0xE64, 0x00800005, + 0xE64, 0x00800006, + 0xE64, 0x08800007, + 0xE64, 0x00004000, + 0x1B00, 0xF8000008, + 0x1B00, 0xF80A7008, + 0x1B00, 0xF8015008, + 0x1B00, 0xF8000008, + 0x1B04, 0xE24629D2, + 0x1B08, 0x00000080, + 0x1B0C, 0x00000000, + 0x1B10, 0x00011C00, + 0x1B14, 0x00000000, + 0x1B18, 0x00292903, + 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, + 0x1B24, 0x01860008, + 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, + 0x1B30, 0x20000000, + 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, + 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, + 0x1B00, 0xF800000A, + 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, + 0x1B24, 0x01860008, + 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, + 0x1B30, 0x20000000, + 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, + 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, + 0x1B00, 0xF8000000, + 0x1B80, 0x00000007, + 0x1B80, 0x090A0005, + 0x1B80, 0x090A0007, + 0x1B80, 0x0FFE0015, + 0x1B80, 0x0FFE0017, + 0x1B80, 0x00220025, + 0x1B80, 0x00220027, + 0x1B80, 0x00040035, + 0x1B80, 0x00040037, + 0x1B80, 0x05C00045, + 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, + 0x1B80, 0x00070057, + 0x1B80, 0x64000065, + 0x1B80, 0x64000067, + 0x1B80, 0x00020075, + 0x1B80, 0x00020077, + 0x1B80, 0x00080085, + 0x1B80, 0x00080087, + 0x1B80, 0x80000095, + 0x1B80, 0x80000097, + 0x1B80, 0x090800A5, + 0x1B80, 0x090800A7, + 0x1B80, 0x0F0200B5, + 0x1B80, 0x0F0200B7, + 0x1B80, 0x002200C5, + 0x1B80, 0x002200C7, + 0x1B80, 0x000400D5, + 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, + 0x1B80, 0x05C000E7, + 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, + 0x1B80, 0x64020105, + 0x1B80, 0x64020107, + 0x1B80, 0x00020115, + 0x1B80, 0x00020117, + 0x1B80, 0x00040125, + 0x1B80, 0x00040127, + 0x1B80, 0x4A000135, + 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, + 0x1B80, 0x4B040147, + 0x1B80, 0x85030155, + 0x1B80, 0x85030157, + 0x1B80, 0x40090165, + 0x1B80, 0x40090167, + 0x1B80, 0xE0280175, + 0x1B80, 0xE0280177, + 0x1B80, 0x4B050185, + 0x1B80, 0x4B050187, + 0x1B80, 0x86030195, + 0x1B80, 0x86030197, + 0x1B80, 0x400B01A5, + 0x1B80, 0x400B01A7, + 0x1B80, 0xE02801B5, + 0x1B80, 0xE02801B7, + 0x1B80, 0x4B0001C5, + 0x1B80, 0x4B0001C7, + 0x1B80, 0x000701D5, + 0x1B80, 0x000701D7, + 0x1B80, 0x4C0001E5, + 0x1B80, 0x4C0001E7, + 0x1B80, 0x000401F5, + 0x1B80, 0x000401F7, + 0x1B80, 0x4D040205, + 0x1B80, 0x4D040207, + 0x1B80, 0x2EF00215, + 0x1B80, 0x2EF00217, + 0x1B80, 0x00000225, + 0x1B80, 0x00000227, + 0x1B80, 0x20810235, + 0x1B80, 0x20810237, + 0x1B80, 0x23450245, + 0x1B80, 0x23450247, + 0x1B80, 0x4D000255, + 0x1B80, 0x4D000257, + 0x1B80, 0x00040265, + 0x1B80, 0x00040267, + 0x1B80, 0x30000275, + 0x1B80, 0x30000277, + 0x1B80, 0xE1D80285, + 0x1B80, 0xE1D80287, + 0x1B80, 0xF0110295, + 0x1B80, 0xF0110297, + 0x1B80, 0xF11102A5, + 0x1B80, 0xF11102A7, + 0x1B80, 0xF21102B5, + 0x1B80, 0xF21102B7, + 0x1B80, 0xF31102C5, + 0x1B80, 0xF31102C7, + 0x1B80, 0xF41102D5, + 0x1B80, 0xF41102D7, + 0x1B80, 0xF51102E5, + 0x1B80, 0xF51102E7, + 0x1B80, 0xF61102F5, + 0x1B80, 0xF61102F7, + 0x1B80, 0xF7110305, + 0x1B80, 0xF7110307, + 0x1B80, 0xF8110315, + 0x1B80, 0xF8110317, + 0x1B80, 0xF9110325, + 0x1B80, 0xF9110327, + 0x1B80, 0xFA110335, + 0x1B80, 0xFA110337, + 0x1B80, 0xFB110345, + 0x1B80, 0xFB110347, + 0x1B80, 0xFC110355, + 0x1B80, 0xFC110357, + 0x1B80, 0xFD110365, + 0x1B80, 0xFD110367, + 0x1B80, 0xFE110375, + 0x1B80, 0xFE110377, + 0x1B80, 0xFF110385, + 0x1B80, 0xFF110387, + 0x1B80, 0x00010395, + 0x1B80, 0x00010397, + 0x1B80, 0x305103A5, + 0x1B80, 0x305103A7, + 0x1B80, 0x306903B5, + 0x1B80, 0x306903B7, + 0x1B80, 0x30B403C5, + 0x1B80, 0x30B403C7, + 0x1B80, 0x30B703D5, + 0x1B80, 0x30B703D7, + 0x1B80, 0x306B03E5, + 0x1B80, 0x306B03E7, + 0x1B80, 0x307603F5, + 0x1B80, 0x307603F7, + 0x1B80, 0x30810405, + 0x1B80, 0x30810407, + 0x1B80, 0x30C10415, + 0x1B80, 0x30C10417, + 0x1B80, 0x30BB0425, + 0x1B80, 0x30BB0427, + 0x1B80, 0x30CF0435, + 0x1B80, 0x30CF0437, + 0x1B80, 0x30DA0445, + 0x1B80, 0x30DA0447, + 0x1B80, 0x30E50455, + 0x1B80, 0x30E50457, + 0x1B80, 0x304A0465, + 0x1B80, 0x304A0467, + 0x1B80, 0x31140475, + 0x1B80, 0x31140477, + 0x1B80, 0x31250485, + 0x1B80, 0x31250487, + 0x1B80, 0x313A0495, + 0x1B80, 0x313A0497, + 0x1B80, 0x4D0404A5, + 0x1B80, 0x4D0404A7, + 0x1B80, 0x2EF004B5, + 0x1B80, 0x2EF004B7, + 0x1B80, 0x000004C5, + 0x1B80, 0x000004C7, + 0x1B80, 0x208104D5, + 0x1B80, 0x208104D7, + 0x1B80, 0xA3B504E5, + 0x1B80, 0xA3B504E7, + 0x1B80, 0x4D0004F5, + 0x1B80, 0x4D0004F7, + 0x1B80, 0x30000505, + 0x1B80, 0x30000507, + 0x1B80, 0xE1650515, + 0x1B80, 0xE1650517, + 0x1B80, 0x4D040525, + 0x1B80, 0x4D040527, + 0x1B80, 0x20800535, + 0x1B80, 0x20800537, + 0x1B80, 0x00000545, + 0x1B80, 0x00000547, + 0x1B80, 0x4D000555, + 0x1B80, 0x4D000557, + 0x1B80, 0x55070565, + 0x1B80, 0x55070567, + 0x1B80, 0xE15D0575, + 0x1B80, 0xE15D0577, + 0x1B80, 0xE15D0585, + 0x1B80, 0xE15D0587, + 0x1B80, 0x4D040595, + 0x1B80, 0x4D040597, + 0x1B80, 0x208805A5, + 0x1B80, 0x208805A7, + 0x1B80, 0x020005B5, + 0x1B80, 0x020005B7, + 0x1B80, 0x4D0005C5, + 0x1B80, 0x4D0005C7, + 0x1B80, 0x550F05D5, + 0x1B80, 0x550F05D7, + 0x1B80, 0xE15D05E5, + 0x1B80, 0xE15D05E7, + 0x1B80, 0x4F0205F5, + 0x1B80, 0x4F0205F7, + 0x1B80, 0x4E000605, + 0x1B80, 0x4E000607, + 0x1B80, 0x53020615, + 0x1B80, 0x53020617, + 0x1B80, 0x52010625, + 0x1B80, 0x52010627, + 0x1B80, 0xE1610635, + 0x1B80, 0xE1610637, + 0x1B80, 0x4D080645, + 0x1B80, 0x4D080647, + 0x1B80, 0x57100655, + 0x1B80, 0x57100657, + 0x1B80, 0x57000665, + 0x1B80, 0x57000667, + 0x1B80, 0x4D000675, + 0x1B80, 0x4D000677, + 0x1B80, 0x00010685, + 0x1B80, 0x00010687, + 0x1B80, 0xE1650695, + 0x1B80, 0xE1650697, + 0x1B80, 0x000106A5, + 0x1B80, 0x000106A7, + 0x1B80, 0x308B06B5, + 0x1B80, 0x308B06B7, + 0x1B80, 0x002306C5, + 0x1B80, 0x002306C7, + 0x1B80, 0xE1CB06D5, + 0x1B80, 0xE1CB06D7, + 0x1B80, 0x000206E5, + 0x1B80, 0x000206E7, + 0x1B80, 0x54E906F5, + 0x1B80, 0x54E906F7, + 0x1B80, 0x0BA60705, + 0x1B80, 0x0BA60707, + 0x1B80, 0x00230715, + 0x1B80, 0x00230717, + 0x1B80, 0xE1CB0725, + 0x1B80, 0xE1CB0727, + 0x1B80, 0x00020735, + 0x1B80, 0x00020737, + 0x1B80, 0x4D300745, + 0x1B80, 0x4D300747, + 0x1B80, 0x30A40755, + 0x1B80, 0x30A40757, + 0x1B80, 0x30870765, + 0x1B80, 0x30870767, + 0x1B80, 0x00220775, + 0x1B80, 0x00220777, + 0x1B80, 0xE1CB0785, + 0x1B80, 0xE1CB0787, + 0x1B80, 0x00020795, + 0x1B80, 0x00020797, + 0x1B80, 0x54E807A5, + 0x1B80, 0x54E807A7, + 0x1B80, 0x0BA607B5, + 0x1B80, 0x0BA607B7, + 0x1B80, 0x002207C5, + 0x1B80, 0x002207C7, + 0x1B80, 0xE1CB07D5, + 0x1B80, 0xE1CB07D7, + 0x1B80, 0x000207E5, + 0x1B80, 0x000207E7, + 0x1B80, 0x4D3007F5, + 0x1B80, 0x4D3007F7, + 0x1B80, 0x30A40805, + 0x1B80, 0x30A40807, + 0x1B80, 0x63F10815, + 0x1B80, 0x63F10817, + 0x1B80, 0xE1650825, + 0x1B80, 0xE1650827, + 0x1B80, 0xE1CB0835, + 0x1B80, 0xE1CB0837, + 0x1B80, 0x63F40845, + 0x1B80, 0x63F40847, + 0x1B80, 0xE1650855, + 0x1B80, 0xE1650857, + 0x1B80, 0xE1CB0865, + 0x1B80, 0xE1CB0867, + 0x1B80, 0x0BA80875, + 0x1B80, 0x0BA80877, + 0x1B80, 0x63F80885, + 0x1B80, 0x63F80887, + 0x1B80, 0xE1650895, + 0x1B80, 0xE1650897, + 0x1B80, 0xE1CB08A5, + 0x1B80, 0xE1CB08A7, + 0x1B80, 0x0BA908B5, + 0x1B80, 0x0BA908B7, + 0x1B80, 0x63FC08C5, + 0x1B80, 0x63FC08C7, + 0x1B80, 0xE16508D5, + 0x1B80, 0xE16508D7, + 0x1B80, 0xE1CB08E5, + 0x1B80, 0xE1CB08E7, + 0x1B80, 0x63FF08F5, + 0x1B80, 0x63FF08F7, + 0x1B80, 0xE1650905, + 0x1B80, 0xE1650907, + 0x1B80, 0xE1CB0915, + 0x1B80, 0xE1CB0917, + 0x1B80, 0x63000925, + 0x1B80, 0x63000927, + 0x1B80, 0xE1650935, + 0x1B80, 0xE1650937, + 0x1B80, 0xE1CB0945, + 0x1B80, 0xE1CB0947, + 0x1B80, 0x63030955, + 0x1B80, 0x63030957, + 0x1B80, 0xE1650965, + 0x1B80, 0xE1650967, + 0x1B80, 0xE1CB0975, + 0x1B80, 0xE1CB0977, + 0x1B80, 0xF4D40985, + 0x1B80, 0xF4D40987, + 0x1B80, 0x63070995, + 0x1B80, 0x63070997, + 0x1B80, 0xE16509A5, + 0x1B80, 0xE16509A7, + 0x1B80, 0xE1CB09B5, + 0x1B80, 0xE1CB09B7, + 0x1B80, 0xF5DB09C5, + 0x1B80, 0xF5DB09C7, + 0x1B80, 0x630B09D5, + 0x1B80, 0x630B09D7, + 0x1B80, 0xE16509E5, + 0x1B80, 0xE16509E7, + 0x1B80, 0xE1CB09F5, + 0x1B80, 0xE1CB09F7, + 0x1B80, 0x630E0A05, + 0x1B80, 0x630E0A07, + 0x1B80, 0xE1650A15, + 0x1B80, 0xE1650A17, + 0x1B80, 0xE1CB0A25, + 0x1B80, 0xE1CB0A27, + 0x1B80, 0x4D300A35, + 0x1B80, 0x4D300A37, + 0x1B80, 0x55010A45, + 0x1B80, 0x55010A47, + 0x1B80, 0x57040A55, + 0x1B80, 0x57040A57, + 0x1B80, 0x57000A65, + 0x1B80, 0x57000A67, + 0x1B80, 0x96000A75, + 0x1B80, 0x96000A77, + 0x1B80, 0x57080A85, + 0x1B80, 0x57080A87, + 0x1B80, 0x57000A95, + 0x1B80, 0x57000A97, + 0x1B80, 0x95000AA5, + 0x1B80, 0x95000AA7, + 0x1B80, 0x4D000AB5, + 0x1B80, 0x4D000AB7, + 0x1B80, 0x6C070AC5, + 0x1B80, 0x6C070AC7, + 0x1B80, 0x7B200AD5, + 0x1B80, 0x7B200AD7, + 0x1B80, 0x7A000AE5, + 0x1B80, 0x7A000AE7, + 0x1B80, 0x79000AF5, + 0x1B80, 0x79000AF7, + 0x1B80, 0x7F200B05, + 0x1B80, 0x7F200B07, + 0x1B80, 0x7E000B15, + 0x1B80, 0x7E000B17, + 0x1B80, 0x7D000B25, + 0x1B80, 0x7D000B27, + 0x1B80, 0x00010B35, + 0x1B80, 0x00010B37, + 0x1B80, 0x62850B45, + 0x1B80, 0x62850B47, + 0x1B80, 0xE1650B55, + 0x1B80, 0xE1650B57, + 0x1B80, 0x00010B65, + 0x1B80, 0x00010B67, + 0x1B80, 0x5C320B75, + 0x1B80, 0x5C320B77, + 0x1B80, 0xE1C70B85, + 0x1B80, 0xE1C70B87, + 0x1B80, 0xE1930B95, + 0x1B80, 0xE1930B97, + 0x1B80, 0x00010BA5, + 0x1B80, 0x00010BA7, + 0x1B80, 0x5C320BB5, + 0x1B80, 0x5C320BB7, + 0x1B80, 0x63F40BC5, + 0x1B80, 0x63F40BC7, + 0x1B80, 0x62850BD5, + 0x1B80, 0x62850BD7, + 0x1B80, 0x0BB00BE5, + 0x1B80, 0x0BB00BE7, + 0x1B80, 0xE1650BF5, + 0x1B80, 0xE1650BF7, + 0x1B80, 0xE1CB0C05, + 0x1B80, 0xE1CB0C07, + 0x1B80, 0x5C320C15, + 0x1B80, 0x5C320C17, + 0x1B80, 0x63FC0C25, + 0x1B80, 0x63FC0C27, + 0x1B80, 0x62850C35, + 0x1B80, 0x62850C37, + 0x1B80, 0x0BB10C45, + 0x1B80, 0x0BB10C47, + 0x1B80, 0xE1650C55, + 0x1B80, 0xE1650C57, + 0x1B80, 0xE1CB0C65, + 0x1B80, 0xE1CB0C67, + 0x1B80, 0x63030C75, + 0x1B80, 0x63030C77, + 0x1B80, 0xE1650C85, + 0x1B80, 0xE1650C87, + 0x1B80, 0xE1CB0C95, + 0x1B80, 0xE1CB0C97, + 0x1B80, 0xF7040CA5, + 0x1B80, 0xF7040CA7, + 0x1B80, 0x630B0CB5, + 0x1B80, 0x630B0CB7, + 0x1B80, 0xE1650CC5, + 0x1B80, 0xE1650CC7, + 0x1B80, 0xE1CB0CD5, + 0x1B80, 0xE1CB0CD7, + 0x1B80, 0x00010CE5, + 0x1B80, 0x00010CE7, + 0x1B80, 0x30F30CF5, + 0x1B80, 0x30F30CF7, + 0x1B80, 0x00230D05, + 0x1B80, 0x00230D07, + 0x1B80, 0xE1D00D15, + 0x1B80, 0xE1D00D17, + 0x1B80, 0x00020D25, + 0x1B80, 0x00020D27, + 0x1B80, 0x54E90D35, + 0x1B80, 0x54E90D37, + 0x1B80, 0x0BA60D45, + 0x1B80, 0x0BA60D47, + 0x1B80, 0x00230D55, + 0x1B80, 0x00230D57, + 0x1B80, 0xE1D00D65, + 0x1B80, 0xE1D00D67, + 0x1B80, 0x00020D75, + 0x1B80, 0x00020D77, + 0x1B80, 0x4D100D85, + 0x1B80, 0x4D100D87, + 0x1B80, 0x30A40D95, + 0x1B80, 0x30A40D97, + 0x1B80, 0x30ED0DA5, + 0x1B80, 0x30ED0DA7, + 0x1B80, 0x00220DB5, + 0x1B80, 0x00220DB7, + 0x1B80, 0xE1D00DC5, + 0x1B80, 0xE1D00DC7, + 0x1B80, 0x00020DD5, + 0x1B80, 0x00020DD7, + 0x1B80, 0x54E80DE5, + 0x1B80, 0x54E80DE7, + 0x1B80, 0x0BA60DF5, + 0x1B80, 0x0BA60DF7, + 0x1B80, 0x00220E05, + 0x1B80, 0x00220E07, + 0x1B80, 0xE1D00E15, + 0x1B80, 0xE1D00E17, + 0x1B80, 0x00020E25, + 0x1B80, 0x00020E27, + 0x1B80, 0x4D100E35, + 0x1B80, 0x4D100E37, + 0x1B80, 0x30A40E45, + 0x1B80, 0x30A40E47, + 0x1B80, 0x5C320E55, + 0x1B80, 0x5C320E57, + 0x1B80, 0x54F00E65, + 0x1B80, 0x54F00E67, + 0x1B80, 0x67F10E75, + 0x1B80, 0x67F10E77, + 0x1B80, 0xE1930E85, + 0x1B80, 0xE1930E87, + 0x1B80, 0xE1D00E95, + 0x1B80, 0xE1D00E97, + 0x1B80, 0x67F40EA5, + 0x1B80, 0x67F40EA7, + 0x1B80, 0xE1930EB5, + 0x1B80, 0xE1930EB7, + 0x1B80, 0xE1D00EC5, + 0x1B80, 0xE1D00EC7, + 0x1B80, 0x5C320ED5, + 0x1B80, 0x5C320ED7, + 0x1B80, 0x54F10EE5, + 0x1B80, 0x54F10EE7, + 0x1B80, 0x0BA80EF5, + 0x1B80, 0x0BA80EF7, + 0x1B80, 0x67F80F05, + 0x1B80, 0x67F80F07, + 0x1B80, 0xE1930F15, + 0x1B80, 0xE1930F17, + 0x1B80, 0xE1D00F25, + 0x1B80, 0xE1D00F27, + 0x1B80, 0x5C320F35, + 0x1B80, 0x5C320F37, + 0x1B80, 0x54F10F45, + 0x1B80, 0x54F10F47, + 0x1B80, 0x0BA90F55, + 0x1B80, 0x0BA90F57, + 0x1B80, 0x67FC0F65, + 0x1B80, 0x67FC0F67, + 0x1B80, 0xE1930F75, + 0x1B80, 0xE1930F77, + 0x1B80, 0xE1D00F85, + 0x1B80, 0xE1D00F87, + 0x1B80, 0x67FF0F95, + 0x1B80, 0x67FF0F97, + 0x1B80, 0xE1930FA5, + 0x1B80, 0xE1930FA7, + 0x1B80, 0xE1D00FB5, + 0x1B80, 0xE1D00FB7, + 0x1B80, 0x5C320FC5, + 0x1B80, 0x5C320FC7, + 0x1B80, 0x54F20FD5, + 0x1B80, 0x54F20FD7, + 0x1B80, 0x67000FE5, + 0x1B80, 0x67000FE7, + 0x1B80, 0xE1930FF5, + 0x1B80, 0xE1930FF7, + 0x1B80, 0xE1D01005, + 0x1B80, 0xE1D01007, + 0x1B80, 0x67031015, + 0x1B80, 0x67031017, + 0x1B80, 0xE1931025, + 0x1B80, 0xE1931027, + 0x1B80, 0xE1D01035, + 0x1B80, 0xE1D01037, + 0x1B80, 0xF9CC1045, + 0x1B80, 0xF9CC1047, + 0x1B80, 0x67071055, + 0x1B80, 0x67071057, + 0x1B80, 0xE1931065, + 0x1B80, 0xE1931067, + 0x1B80, 0xE1D01075, + 0x1B80, 0xE1D01077, + 0x1B80, 0xFAD31085, + 0x1B80, 0xFAD31087, + 0x1B80, 0x5C321095, + 0x1B80, 0x5C321097, + 0x1B80, 0x54F310A5, + 0x1B80, 0x54F310A7, + 0x1B80, 0x670B10B5, + 0x1B80, 0x670B10B7, + 0x1B80, 0xE19310C5, + 0x1B80, 0xE19310C7, + 0x1B80, 0xE1D010D5, + 0x1B80, 0xE1D010D7, + 0x1B80, 0x670E10E5, + 0x1B80, 0x670E10E7, + 0x1B80, 0xE19310F5, + 0x1B80, 0xE19310F7, + 0x1B80, 0xE1D01105, + 0x1B80, 0xE1D01107, + 0x1B80, 0x4D101115, + 0x1B80, 0x4D101117, + 0x1B80, 0x30A41125, + 0x1B80, 0x30A41127, + 0x1B80, 0x00011135, + 0x1B80, 0x00011137, + 0x1B80, 0x6C001145, + 0x1B80, 0x6C001147, + 0x1B80, 0x00061155, + 0x1B80, 0x00061157, + 0x1B80, 0x53001165, + 0x1B80, 0x53001167, + 0x1B80, 0x57F71175, + 0x1B80, 0x57F71177, + 0x1B80, 0x58211185, + 0x1B80, 0x58211187, + 0x1B80, 0x592E1195, + 0x1B80, 0x592E1197, + 0x1B80, 0x5A3811A5, + 0x1B80, 0x5A3811A7, + 0x1B80, 0x5B4111B5, + 0x1B80, 0x5B4111B7, + 0x1B80, 0x000711C5, + 0x1B80, 0x000711C7, + 0x1B80, 0x5C0011D5, + 0x1B80, 0x5C0011D7, + 0x1B80, 0x4B0011E5, + 0x1B80, 0x4B0011E7, + 0x1B80, 0x4E8F11F5, + 0x1B80, 0x4E8F11F7, + 0x1B80, 0x4F151205, + 0x1B80, 0x4F151207, + 0x1B80, 0x00041215, + 0x1B80, 0x00041217, + 0x1B80, 0xE1B51225, + 0x1B80, 0xE1B51227, + 0x1B80, 0xAB001235, + 0x1B80, 0xAB001237, + 0x1B80, 0x00011245, + 0x1B80, 0x00011247, + 0x1B80, 0x6C001255, + 0x1B80, 0x6C001257, + 0x1B80, 0x00061265, + 0x1B80, 0x00061267, + 0x1B80, 0x53001275, + 0x1B80, 0x53001277, + 0x1B80, 0x57F71285, + 0x1B80, 0x57F71287, + 0x1B80, 0x58211295, + 0x1B80, 0x58211297, + 0x1B80, 0x592E12A5, + 0x1B80, 0x592E12A7, + 0x1B80, 0x5A3812B5, + 0x1B80, 0x5A3812B7, + 0x1B80, 0x5B4112C5, + 0x1B80, 0x5B4112C7, + 0x1B80, 0x000712D5, + 0x1B80, 0x000712D7, + 0x1B80, 0x5C0012E5, + 0x1B80, 0x5C0012E7, + 0x1B80, 0x4B4012F5, + 0x1B80, 0x4B4012F7, + 0x1B80, 0x4E971305, + 0x1B80, 0x4E971307, + 0x1B80, 0x4F111315, + 0x1B80, 0x4F111317, + 0x1B80, 0x00041325, + 0x1B80, 0x00041327, + 0x1B80, 0xE1B51335, + 0x1B80, 0xE1B51337, + 0x1B80, 0xAB001345, + 0x1B80, 0xAB001347, + 0x1B80, 0x8B001355, + 0x1B80, 0x8B001357, + 0x1B80, 0xAB001365, + 0x1B80, 0xAB001367, + 0x1B80, 0x8A191375, + 0x1B80, 0x8A191377, + 0x1B80, 0x301D1385, + 0x1B80, 0x301D1387, + 0x1B80, 0x00011395, + 0x1B80, 0x00011397, + 0x1B80, 0x6C0113A5, + 0x1B80, 0x6C0113A7, + 0x1B80, 0x000613B5, + 0x1B80, 0x000613B7, + 0x1B80, 0x530113C5, + 0x1B80, 0x530113C7, + 0x1B80, 0x57F713D5, + 0x1B80, 0x57F713D7, + 0x1B80, 0x582113E5, + 0x1B80, 0x582113E7, + 0x1B80, 0x592E13F5, + 0x1B80, 0x592E13F7, + 0x1B80, 0x5A381405, + 0x1B80, 0x5A381407, + 0x1B80, 0x5B411415, + 0x1B80, 0x5B411417, + 0x1B80, 0x00071425, + 0x1B80, 0x00071427, + 0x1B80, 0x5C001435, + 0x1B80, 0x5C001437, + 0x1B80, 0x4B001445, + 0x1B80, 0x4B001447, + 0x1B80, 0x4E871455, + 0x1B80, 0x4E871457, + 0x1B80, 0x4F111465, + 0x1B80, 0x4F111467, + 0x1B80, 0x00041475, + 0x1B80, 0x00041477, + 0x1B80, 0xE1B51485, + 0x1B80, 0xE1B51487, + 0x1B80, 0xAB001495, + 0x1B80, 0xAB001497, + 0x1B80, 0x000614A5, + 0x1B80, 0x000614A7, + 0x1B80, 0x577714B5, + 0x1B80, 0x577714B7, + 0x1B80, 0x000714C5, + 0x1B80, 0x000714C7, + 0x1B80, 0x4E8614D5, + 0x1B80, 0x4E8614D7, + 0x1B80, 0x000414E5, + 0x1B80, 0x000414E7, + 0x1B80, 0x000114F5, + 0x1B80, 0x000114F7, + 0x1B80, 0x00011505, + 0x1B80, 0x00011507, + 0x1B80, 0x7B241515, + 0x1B80, 0x7B241517, + 0x1B80, 0x7A401525, + 0x1B80, 0x7A401527, + 0x1B80, 0x79001535, + 0x1B80, 0x79001537, + 0x1B80, 0x55031545, + 0x1B80, 0x55031547, + 0x1B80, 0x315D1555, + 0x1B80, 0x315D1557, + 0x1B80, 0x7B1C1565, + 0x1B80, 0x7B1C1567, + 0x1B80, 0x7A401575, + 0x1B80, 0x7A401577, + 0x1B80, 0x550B1585, + 0x1B80, 0x550B1587, + 0x1B80, 0x315D1595, + 0x1B80, 0x315D1597, + 0x1B80, 0x7B2015A5, + 0x1B80, 0x7B2015A7, + 0x1B80, 0x7A0015B5, + 0x1B80, 0x7A0015B7, + 0x1B80, 0x551315C5, + 0x1B80, 0x551315C7, + 0x1B80, 0x740115D5, + 0x1B80, 0x740115D7, + 0x1B80, 0x740015E5, + 0x1B80, 0x740015E7, + 0x1B80, 0x8E0015F5, + 0x1B80, 0x8E0015F7, + 0x1B80, 0x00011605, + 0x1B80, 0x00011607, + 0x1B80, 0x57021615, + 0x1B80, 0x57021617, + 0x1B80, 0x57001625, + 0x1B80, 0x57001627, + 0x1B80, 0x97001635, + 0x1B80, 0x97001637, + 0x1B80, 0x00011645, + 0x1B80, 0x00011647, + 0x1B80, 0x4F781655, + 0x1B80, 0x4F781657, + 0x1B80, 0x53881665, + 0x1B80, 0x53881667, + 0x1B80, 0xE1731675, + 0x1B80, 0xE1731677, + 0x1B80, 0x54801685, + 0x1B80, 0x54801687, + 0x1B80, 0x54001695, + 0x1B80, 0x54001697, + 0x1B80, 0xE17316A5, + 0x1B80, 0xE17316A7, + 0x1B80, 0x548116B5, + 0x1B80, 0x548116B7, + 0x1B80, 0x540016C5, + 0x1B80, 0x540016C7, + 0x1B80, 0xE17316D5, + 0x1B80, 0xE17316D7, + 0x1B80, 0x548216E5, + 0x1B80, 0x548216E7, + 0x1B80, 0x540016F5, + 0x1B80, 0x540016F7, + 0x1B80, 0xE17E1705, + 0x1B80, 0xE17E1707, + 0x1B80, 0xBF1D1715, + 0x1B80, 0xBF1D1717, + 0x1B80, 0x301D1725, + 0x1B80, 0x301D1727, + 0x1B80, 0xE1511735, + 0x1B80, 0xE1511737, + 0x1B80, 0xE1561745, + 0x1B80, 0xE1561747, + 0x1B80, 0xE15A1755, + 0x1B80, 0xE15A1757, + 0x1B80, 0xE1611765, + 0x1B80, 0xE1611767, + 0x1B80, 0xE1C71775, + 0x1B80, 0xE1C71777, + 0x1B80, 0x55131785, + 0x1B80, 0x55131787, + 0x1B80, 0xE15D1795, + 0x1B80, 0xE15D1797, + 0x1B80, 0x551517A5, + 0x1B80, 0x551517A7, + 0x1B80, 0xE16117B5, + 0x1B80, 0xE16117B7, + 0x1B80, 0xE1C717C5, + 0x1B80, 0xE1C717C7, + 0x1B80, 0x000117D5, + 0x1B80, 0x000117D7, + 0x1B80, 0x54BF17E5, + 0x1B80, 0x54BF17E7, + 0x1B80, 0x54C017F5, + 0x1B80, 0x54C017F7, + 0x1B80, 0x54A31805, + 0x1B80, 0x54A31807, + 0x1B80, 0x54C11815, + 0x1B80, 0x54C11817, + 0x1B80, 0x54A41825, + 0x1B80, 0x54A41827, + 0x1B80, 0x4C181835, + 0x1B80, 0x4C181837, + 0x1B80, 0xBF071845, + 0x1B80, 0xBF071847, + 0x1B80, 0x54C21855, + 0x1B80, 0x54C21857, + 0x1B80, 0x54A41865, + 0x1B80, 0x54A41867, + 0x1B80, 0xBF041875, + 0x1B80, 0xBF041877, + 0x1B80, 0x54C11885, + 0x1B80, 0x54C11887, + 0x1B80, 0x54A31895, + 0x1B80, 0x54A31897, + 0x1B80, 0xBF0118A5, + 0x1B80, 0xBF0118A7, + 0x1B80, 0xE1D518B5, + 0x1B80, 0xE1D518B7, + 0x1B80, 0x54DF18C5, + 0x1B80, 0x54DF18C7, + 0x1B80, 0x000118D5, + 0x1B80, 0x000118D7, + 0x1B80, 0x54BF18E5, + 0x1B80, 0x54BF18E7, + 0x1B80, 0x54E518F5, + 0x1B80, 0x54E518F7, + 0x1B80, 0x050A1905, + 0x1B80, 0x050A1907, + 0x1B80, 0x54DF1915, + 0x1B80, 0x54DF1917, + 0x1B80, 0x00011925, + 0x1B80, 0x00011927, + 0x1B80, 0x7F201935, + 0x1B80, 0x7F201937, + 0x1B80, 0x7E001945, + 0x1B80, 0x7E001947, + 0x1B80, 0x7D001955, + 0x1B80, 0x7D001957, + 0x1B80, 0x55011965, + 0x1B80, 0x55011967, + 0x1B80, 0x5C311975, + 0x1B80, 0x5C311977, + 0x1B80, 0xE15D1985, + 0x1B80, 0xE15D1987, + 0x1B80, 0xE1611995, + 0x1B80, 0xE1611997, + 0x1B80, 0x548019A5, + 0x1B80, 0x548019A7, + 0x1B80, 0x540019B5, + 0x1B80, 0x540019B7, + 0x1B80, 0xE15D19C5, + 0x1B80, 0xE15D19C7, + 0x1B80, 0xE16119D5, + 0x1B80, 0xE16119D7, + 0x1B80, 0x548119E5, + 0x1B80, 0x548119E7, + 0x1B80, 0x540019F5, + 0x1B80, 0x540019F7, + 0x1B80, 0xE15D1A05, + 0x1B80, 0xE15D1A07, + 0x1B80, 0xE1611A15, + 0x1B80, 0xE1611A17, + 0x1B80, 0x54821A25, + 0x1B80, 0x54821A27, + 0x1B80, 0x54001A35, + 0x1B80, 0x54001A37, + 0x1B80, 0xE17E1A45, + 0x1B80, 0xE17E1A47, + 0x1B80, 0xBFE91A55, + 0x1B80, 0xBFE91A57, + 0x1B80, 0x301D1A65, + 0x1B80, 0x301D1A67, + 0x1B80, 0x00231A75, + 0x1B80, 0x00231A77, + 0x1B80, 0x7B201A85, + 0x1B80, 0x7B201A87, + 0x1B80, 0x7A001A95, + 0x1B80, 0x7A001A97, + 0x1B80, 0x79001AA5, + 0x1B80, 0x79001AA7, + 0x1B80, 0xE1CB1AB5, + 0x1B80, 0xE1CB1AB7, + 0x1B80, 0x00021AC5, + 0x1B80, 0x00021AC7, + 0x1B80, 0x00011AD5, + 0x1B80, 0x00011AD7, + 0x1B80, 0x00221AE5, + 0x1B80, 0x00221AE7, + 0x1B80, 0x7B201AF5, + 0x1B80, 0x7B201AF7, + 0x1B80, 0x7A001B05, + 0x1B80, 0x7A001B07, + 0x1B80, 0x79001B15, + 0x1B80, 0x79001B17, + 0x1B80, 0xE1CB1B25, + 0x1B80, 0xE1CB1B27, + 0x1B80, 0x00021B35, + 0x1B80, 0x00021B37, + 0x1B80, 0x00011B45, + 0x1B80, 0x00011B47, + 0x1B80, 0x74021B55, + 0x1B80, 0x74021B57, + 0x1B80, 0x003F1B65, + 0x1B80, 0x003F1B67, + 0x1B80, 0x74001B75, + 0x1B80, 0x74001B77, + 0x1B80, 0x00021B85, + 0x1B80, 0x00021B87, + 0x1B80, 0x00011B95, + 0x1B80, 0x00011B97, + 0x1B80, 0x4D041BA5, + 0x1B80, 0x4D041BA7, + 0x1B80, 0x2EF81BB5, + 0x1B80, 0x2EF81BB7, + 0x1B80, 0x00001BC5, + 0x1B80, 0x00001BC7, + 0x1B80, 0x23301BD5, + 0x1B80, 0x23301BD7, + 0x1B80, 0x00241BE5, + 0x1B80, 0x00241BE7, + 0x1B80, 0x23E01BF5, + 0x1B80, 0x23E01BF7, + 0x1B80, 0x003F1C05, + 0x1B80, 0x003F1C07, + 0x1B80, 0x23FC1C15, + 0x1B80, 0x23FC1C17, + 0x1B80, 0xBFCE1C25, + 0x1B80, 0xBFCE1C27, + 0x1B80, 0x2EF01C35, + 0x1B80, 0x2EF01C37, + 0x1B80, 0x00001C45, + 0x1B80, 0x00001C47, + 0x1B80, 0x4D001C55, + 0x1B80, 0x4D001C57, + 0x1B80, 0x00011C65, + 0x1B80, 0x00011C67, + 0x1B80, 0x549F1C75, + 0x1B80, 0x549F1C77, + 0x1B80, 0x54FF1C85, + 0x1B80, 0x54FF1C87, + 0x1B80, 0x54001C95, + 0x1B80, 0x54001C97, + 0x1B80, 0x00011CA5, + 0x1B80, 0x00011CA7, + 0x1B80, 0x5C311CB5, + 0x1B80, 0x5C311CB7, + 0x1B80, 0x07141CC5, + 0x1B80, 0x07141CC7, + 0x1B80, 0x54001CD5, + 0x1B80, 0x54001CD7, + 0x1B80, 0x5C321CE5, + 0x1B80, 0x5C321CE7, + 0x1B80, 0x00011CF5, + 0x1B80, 0x00011CF7, + 0x1B80, 0x5C321D05, + 0x1B80, 0x5C321D07, + 0x1B80, 0x07141D15, + 0x1B80, 0x07141D17, + 0x1B80, 0x54001D25, + 0x1B80, 0x54001D27, + 0x1B80, 0x5C311D35, + 0x1B80, 0x5C311D37, + 0x1B80, 0x00011D45, + 0x1B80, 0x00011D47, + 0x1B80, 0x4C981D55, + 0x1B80, 0x4C981D57, + 0x1B80, 0x4C181D65, + 0x1B80, 0x4C181D67, + 0x1B80, 0x00011D75, + 0x1B80, 0x00011D77, + 0x1B80, 0x5C321D85, + 0x1B80, 0x5C321D87, + 0x1B80, 0x62841D95, + 0x1B80, 0x62841D97, + 0x1B80, 0x66861DA5, + 0x1B80, 0x66861DA7, + 0x1B80, 0x6C031DB5, + 0x1B80, 0x6C031DB7, + 0x1B80, 0x7B201DC5, + 0x1B80, 0x7B201DC7, + 0x1B80, 0x7A001DD5, + 0x1B80, 0x7A001DD7, + 0x1B80, 0x79001DE5, + 0x1B80, 0x79001DE7, + 0x1B80, 0x7F201DF5, + 0x1B80, 0x7F201DF7, + 0x1B80, 0x7E001E05, + 0x1B80, 0x7E001E07, + 0x1B80, 0x7D001E15, + 0x1B80, 0x7D001E17, + 0x1B80, 0x09011E25, + 0x1B80, 0x09011E27, + 0x1B80, 0x0C011E35, + 0x1B80, 0x0C011E37, + 0x1B80, 0x0BA61E45, + 0x1B80, 0x0BA61E47, + 0x1B80, 0x00011E55, + 0x1B80, 0x00011E57, + 0x1B80, 0x00000006, + 0x1B80, 0x00000002, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822b_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type2[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x40424446, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x30323436, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404244, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x30323436, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x30323436, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42442628, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x34363840, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x40424446, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x30323436, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404244, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x30323436, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x30323436, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42442628, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x34363840, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x26283032, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type2); + +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type3[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type3); + +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type5[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type5); + +static const u32 rtw8822b_rf_a[] = { + 0x000, 0x00030000, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0xA0000000, 0x00000000, + 0x001, 0x00040029, + 0xB0000000, 0x00000000, + 0x018, 0x00010D24, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x8300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000D0F4E, + 0xA0000000, 0x00000000, + 0x03F, 0x000C0F4E, + 0xB0000000, 0x00000000, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x0EF, 0x00080000, + 0x0DF, 0x00002449, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, + 0x07F, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FB0F8, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xB0000000, 0x00000000, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C330, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0003C360, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0xA0000000, 0x00000000, + 0x0B3, 0x000FC760, + 0xB0000000, 0x00000000, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000000, + 0x0BC, 0x00040030, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C146, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0x018, 0x00010524, + 0x089, 0x00000207, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0xA0000000, 0x00000000, + 0x08A, 0x000FF186, + 0xB0000000, 0x00000000, + 0x08B, 0x00061E3C, + 0x08C, 0x000112C7, + 0x08D, 0x000F4988, + 0x08E, 0x00064D40, + 0x0EF, 0x00020000, + 0x033, 0x00000007, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000DFF86, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000DFF86, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x00000006, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0xA0000000, 0x00000000, + 0x03E, 0x00004080, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004084, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040C8, + 0xA0000000, 0x00000000, + 0x03E, 0x000040C8, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004108, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, + 0xA0000000, 0x00000000, + 0x03E, 0x00004190, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x0000490C, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004998, + 0xA0000000, 0x00000000, + 0x03E, 0x00004998, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005E00, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005840, + 0xA0000000, 0x00000000, + 0x03E, 0x00005840, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005862, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, + 0xA0000000, 0x00000000, + 0x03E, 0x000058C2, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005948, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00005930, + 0xA0000000, 0x00000000, + 0x03E, 0x00005930, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x0000000F, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000DFF86, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000DFF86, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x0000000E, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000040C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00004190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00004998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00005840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000058C2, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00005930, + 0x03F, 0x000C3186, + 0x033, 0x00000017, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000DFF86, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x00000016, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000040C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00004190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00004998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00005840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000058C2, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00005930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000A, + 0x033, 0x00000001, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000006, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0xA0000000, 0x00000000, + 0x03F, 0x00000005, + 0xB0000000, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0xA0000000, 0x00000000, + 0x087, 0x000E8180, + 0xB0000000, 0x00000000, + 0x088, 0x00070020, + 0x0DE, 0x00000010, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x0B8, 0x00080A00, + 0x0FE, 0x00000000, + 0x0B0, 0x000FF0FA, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0CA, 0x00080000, + 0x0FE, 0x00000000, + 0x0C9, 0x0001C141, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x018, 0x00018D24, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x00010D24, + 0x01B, 0x00075A40, + 0x0EE, 0x00000002, + 0x033, 0x00000000, + 0x03F, 0x00000004, + 0x033, 0x00000001, + 0x03F, 0x00000004, + 0x033, 0x00000002, + 0x03F, 0x00000004, + 0x033, 0x00000003, + 0x03F, 0x00000004, + 0x033, 0x00000004, + 0x03F, 0x00000004, + 0x033, 0x00000005, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000004, + 0x033, 0x00000007, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0xA0000000, 0x00000000, + 0x061, 0x0005D3D0, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x0EF, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000303, + 0x030, 0x00001303, + 0x030, 0x00002303, + 0x030, 0x00003303, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A3, + 0x030, 0x000013A3, + 0x030, 0x000023A3, + 0x030, 0x000033A3, + 0x030, 0x00004355, + 0x030, 0x00005355, + 0x030, 0x00006355, + 0x030, 0x00007355, + 0x030, 0x00008315, + 0x030, 0x00009315, + 0x030, 0x0000A315, + 0x030, 0x0000B315, + 0x0EF, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000384, + 0x030, 0x00001384, + 0x030, 0x00002384, + 0x030, 0x00003384, + 0x030, 0x00004425, + 0x030, 0x00005425, + 0x030, 0x00006425, + 0x030, 0x00007425, + 0x030, 0x000084A6, + 0x030, 0x000094A6, + 0x030, 0x0000A4A6, + 0x030, 0x0000B4A6, + 0x0EF, 0x00000000, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000463, + 0x030, 0x00001463, + 0x030, 0x00002463, + 0x030, 0x00003463, + 0x030, 0x00004545, + 0x030, 0x00005545, + 0x030, 0x00006545, + 0x030, 0x00007545, + 0x030, 0x00008565, + 0x030, 0x00009565, + 0x030, 0x0000A565, + 0x030, 0x0000B565, + 0x0EF, 0x00000000, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x0EF, 0x00000000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000443, + 0x030, 0x00001443, + 0x030, 0x00002443, + 0x030, 0x00003443, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x0EF, 0x00000000, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000443, + 0x030, 0x00001443, + 0x030, 0x00002443, + 0x030, 0x00003443, + 0x030, 0x00004483, + 0x030, 0x00005483, + 0x030, 0x00006483, + 0x030, 0x00007483, + 0x030, 0x000084A4, + 0x030, 0x000094A4, + 0x030, 0x0000A4A4, + 0x030, 0x0000B4A4, + 0x0EF, 0x00000000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000361, + 0x030, 0x00001361, + 0x030, 0x00002361, + 0x030, 0x00003361, + 0x030, 0x00004443, + 0x030, 0x00005443, + 0x030, 0x00006443, + 0x030, 0x00007443, + 0x030, 0x00008424, + 0x030, 0x00009424, + 0x030, 0x0000A424, + 0x030, 0x0000B424, + 0x0EF, 0x00000000, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x0EF, 0x00000000, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000403, + 0x030, 0x00001403, + 0x030, 0x00002403, + 0x030, 0x00003403, + 0x030, 0x000044A2, + 0x030, 0x000054A2, + 0x030, 0x000064A2, + 0x030, 0x000074A2, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x0EF, 0x00000000, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A3, + 0x030, 0x000013A3, + 0x030, 0x000023A3, + 0x030, 0x000033A3, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x0EF, 0x00000000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x0EF, 0x00000000, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0x0EF, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000002A1, + 0x030, 0x000012A1, + 0x030, 0x000022A1, + 0x030, 0x000032A1, + 0x030, 0x000042A1, + 0x030, 0x000052A1, + 0x030, 0x000062A1, + 0x030, 0x000072A1, + 0x030, 0x000082A1, + 0x030, 0x000092A1, + 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, + 0x0EF, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A0, + 0x030, 0x000013A0, + 0x030, 0x000023A0, + 0x030, 0x000033A0, + 0x030, 0x000043A1, + 0x030, 0x000053A1, + 0x030, 0x000063A1, + 0x030, 0x000073A1, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x0EF, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000002A1, + 0x030, 0x000012A1, + 0x030, 0x000022A1, + 0x030, 0x000032A1, + 0x030, 0x000042A1, + 0x030, 0x000052A1, + 0x030, 0x000062A1, + 0x030, 0x000072A1, + 0x030, 0x000082A1, + 0x030, 0x000092A1, + 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, + 0x0EF, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003A0, + 0x030, 0x000013A0, + 0x030, 0x000023A0, + 0x030, 0x000033A0, + 0x030, 0x00004430, + 0x030, 0x00005430, + 0x030, 0x00006430, + 0x030, 0x00007430, + 0x030, 0x00008372, + 0x030, 0x00009372, + 0x030, 0x0000A372, + 0x030, 0x0000B372, + 0x0EF, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0x0EF, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x000003D0, + 0x030, 0x000013D0, + 0x030, 0x000023D0, + 0x030, 0x000033D0, + 0x030, 0x000043D0, + 0x030, 0x000053D0, + 0x030, 0x000063D0, + 0x030, 0x000073D0, + 0x030, 0x000083D0, + 0x030, 0x000093D0, + 0x030, 0x0000A3D0, + 0x030, 0x0000B3D0, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A3, + 0x030, 0x000013A3, + 0x030, 0x000023A3, + 0x030, 0x000033A3, + 0x030, 0x000043A3, + 0x030, 0x000053A3, + 0x030, 0x000063A3, + 0x030, 0x000073A3, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000080, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000776, + 0x030, 0x00001455, + 0x030, 0x00002335, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000660, + 0x030, 0x00001443, + 0x030, 0x00002221, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000767, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000765, + 0x030, 0x00001632, + 0x030, 0x00002451, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000777, + 0x030, 0x00001454, + 0x030, 0x00002224, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000775, + 0x030, 0x00001422, + 0x030, 0x00002210, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000775, + 0x030, 0x00001343, + 0x030, 0x00002210, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042B, + 0x033, 0x00000021, + 0x03F, 0x0000082A, + 0x033, 0x00000022, + 0x03F, 0x00000849, + 0x033, 0x00000023, + 0x03F, 0x0000084C, + 0x033, 0x00000024, + 0x03F, 0x00000C4C, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000CAC, + 0x033, 0x00000027, + 0x03F, 0x00000CED, + 0x033, 0x00000028, + 0x03F, 0x00000CF0, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C0C, + 0x033, 0x00000021, + 0x03F, 0x00000C29, + 0x033, 0x00000022, + 0x03F, 0x00000C2C, + 0x033, 0x00000023, + 0x03F, 0x00000C69, + 0x033, 0x00000024, + 0x03F, 0x00000CA8, + 0x033, 0x00000025, + 0x03F, 0x00000CE8, + 0x033, 0x00000026, + 0x03F, 0x00000CEB, + 0x033, 0x00000027, + 0x03F, 0x00000CEE, + 0x033, 0x00000028, + 0x03F, 0x00000CF1, + 0x033, 0x00000029, + 0x03F, 0x00000CF4, + 0x033, 0x0000002A, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000CE5, + 0x033, 0x00000026, + 0x03F, 0x00000CE8, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C0B, + 0x033, 0x00000021, + 0x03F, 0x00000C0E, + 0x033, 0x00000022, + 0x03F, 0x00000C2B, + 0x033, 0x00000023, + 0x03F, 0x00000C2E, + 0x033, 0x00000024, + 0x03F, 0x00000C89, + 0x033, 0x00000025, + 0x03F, 0x00000CE8, + 0x033, 0x00000026, + 0x03F, 0x00000CEB, + 0x033, 0x00000027, + 0x03F, 0x00000CEE, + 0x033, 0x00000028, + 0x03F, 0x00000CF1, + 0x033, 0x00000029, + 0x03F, 0x00000CF4, + 0x033, 0x0000002A, + 0x03F, 0x00000CF7, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x0000086A, + 0x033, 0x00000025, + 0x03F, 0x0000086D, + 0x033, 0x00000026, + 0x03F, 0x00000870, + 0x033, 0x00000027, + 0x03F, 0x00000891, + 0x033, 0x00000028, + 0x03F, 0x00000894, + 0x033, 0x00000029, + 0x03F, 0x000008B5, + 0x033, 0x0000002A, + 0x03F, 0x000008F5, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x00000068, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042B, + 0x033, 0x00000021, + 0x03F, 0x0000082A, + 0x033, 0x00000022, + 0x03F, 0x00000849, + 0x033, 0x00000023, + 0x03F, 0x0000084C, + 0x033, 0x00000024, + 0x03F, 0x00000C4C, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x00000068, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042B, + 0x033, 0x00000021, + 0x03F, 0x0000082A, + 0x033, 0x00000022, + 0x03F, 0x00000849, + 0x033, 0x00000023, + 0x03F, 0x0000084C, + 0x033, 0x00000024, + 0x03F, 0x00000C4C, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042A, + 0x033, 0x00000061, + 0x03F, 0x00000829, + 0x033, 0x00000062, + 0x03F, 0x00000848, + 0x033, 0x00000063, + 0x03F, 0x0000084B, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000CAC, + 0x033, 0x00000067, + 0x03F, 0x00000CED, + 0x033, 0x00000068, + 0x03F, 0x00000CF0, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000080B, + 0x033, 0x00000061, + 0x03F, 0x0000080E, + 0x033, 0x00000062, + 0x03F, 0x00000848, + 0x033, 0x00000063, + 0x03F, 0x00000869, + 0x033, 0x00000064, + 0x03F, 0x000008A9, + 0x033, 0x00000065, + 0x03F, 0x00000CE8, + 0x033, 0x00000066, + 0x03F, 0x00000CEB, + 0x033, 0x00000067, + 0x03F, 0x00000CEE, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000CE5, + 0x033, 0x00000066, + 0x03F, 0x00000CE8, + 0x033, 0x00000067, + 0x03F, 0x00000CEB, + 0x033, 0x00000068, + 0x03F, 0x00000CEE, + 0x033, 0x00000069, + 0x03F, 0x00000CF1, + 0x033, 0x0000006A, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C10, + 0x033, 0x00000063, + 0x03F, 0x00000C4A, + 0x033, 0x00000064, + 0x03F, 0x00000C4D, + 0x033, 0x00000065, + 0x03F, 0x00000CC9, + 0x033, 0x00000066, + 0x03F, 0x00000CEB, + 0x033, 0x00000067, + 0x03F, 0x00000CEE, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x0000086A, + 0x033, 0x00000065, + 0x03F, 0x0000086D, + 0x033, 0x00000066, + 0x03F, 0x00000870, + 0x033, 0x00000067, + 0x03F, 0x00000891, + 0x033, 0x00000068, + 0x03F, 0x00000894, + 0x033, 0x00000069, + 0x03F, 0x000008B5, + 0x033, 0x0000006A, + 0x03F, 0x000008F5, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042C, + 0x033, 0x00000061, + 0x03F, 0x0000082B, + 0x033, 0x00000062, + 0x03F, 0x0000084A, + 0x033, 0x00000063, + 0x03F, 0x0000084D, + 0x033, 0x00000064, + 0x03F, 0x00000C4D, + 0x033, 0x00000065, + 0x03F, 0x00000C8B, + 0x033, 0x00000066, + 0x03F, 0x00000C8E, + 0x033, 0x00000067, + 0x03F, 0x00000CEC, + 0x033, 0x00000068, + 0x03F, 0x00000CEF, + 0x033, 0x00000069, + 0x03F, 0x00000CF2, + 0x033, 0x0000006A, + 0x03F, 0x00000CF5, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042C, + 0x033, 0x00000061, + 0x03F, 0x0000082B, + 0x033, 0x00000062, + 0x03F, 0x0000084A, + 0x033, 0x00000063, + 0x03F, 0x0000084D, + 0x033, 0x00000064, + 0x03F, 0x00000C4D, + 0x033, 0x00000065, + 0x03F, 0x00000C8B, + 0x033, 0x00000066, + 0x03F, 0x00000C8E, + 0x033, 0x00000067, + 0x03F, 0x00000CEC, + 0x033, 0x00000068, + 0x03F, 0x00000CEF, + 0x033, 0x00000069, + 0x03F, 0x00000CF2, + 0x033, 0x0000006A, + 0x03F, 0x00000CF5, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000CAC, + 0x033, 0x000000A7, + 0x03F, 0x00000CED, + 0x033, 0x000000A8, + 0x03F, 0x00000CF0, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C0A, + 0x033, 0x000000A1, + 0x03F, 0x00000C0D, + 0x033, 0x000000A2, + 0x03F, 0x00000C2A, + 0x033, 0x000000A3, + 0x03F, 0x00000C2D, + 0x033, 0x000000A4, + 0x03F, 0x00000C6A, + 0x033, 0x000000A5, + 0x03F, 0x00000CE8, + 0x033, 0x000000A6, + 0x03F, 0x00000CEB, + 0x033, 0x000000A7, + 0x03F, 0x00000CEE, + 0x033, 0x000000A8, + 0x03F, 0x00000CF1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF4, + 0x033, 0x000000AA, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000CE5, + 0x033, 0x000000A6, + 0x03F, 0x00000CE8, + 0x033, 0x000000A7, + 0x03F, 0x00000CEB, + 0x033, 0x000000A8, + 0x03F, 0x00000CEE, + 0x033, 0x000000A9, + 0x03F, 0x00000CF1, + 0x033, 0x000000AA, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000824, + 0x033, 0x000000A1, + 0x03F, 0x00000827, + 0x033, 0x000000A2, + 0x03F, 0x0000082A, + 0x033, 0x000000A3, + 0x03F, 0x0000082D, + 0x033, 0x000000A4, + 0x03F, 0x00000C68, + 0x033, 0x000000A5, + 0x03F, 0x00000C6B, + 0x033, 0x000000A6, + 0x03F, 0x00000CCA, + 0x033, 0x000000A7, + 0x03F, 0x00000CCD, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C08, + 0x033, 0x000000A1, + 0x03F, 0x00000C0B, + 0x033, 0x000000A2, + 0x03F, 0x00000C0E, + 0x033, 0x000000A3, + 0x03F, 0x00000C2B, + 0x033, 0x000000A4, + 0x03F, 0x00000C2E, + 0x033, 0x000000A5, + 0x03F, 0x00000C31, + 0x033, 0x000000A6, + 0x03F, 0x00000CCA, + 0x033, 0x000000A7, + 0x03F, 0x00000CCD, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x0000086A, + 0x033, 0x000000A5, + 0x03F, 0x0000086D, + 0x033, 0x000000A6, + 0x03F, 0x00000870, + 0x033, 0x000000A7, + 0x03F, 0x00000891, + 0x033, 0x000000A8, + 0x03F, 0x00000894, + 0x033, 0x000000A9, + 0x03F, 0x000008B5, + 0x033, 0x000000AA, + 0x03F, 0x000008F5, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x00000047, + 0x033, 0x000000A5, + 0x03F, 0x0000004A, + 0x033, 0x000000A6, + 0x03F, 0x0000004D, + 0x033, 0x000000A7, + 0x03F, 0x00000050, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x00000094, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000042A, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x00000848, + 0x033, 0x000000A3, + 0x03F, 0x0000084B, + 0x033, 0x000000A4, + 0x03F, 0x00000C4C, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CEB, + 0x033, 0x000000A8, + 0x03F, 0x00000CEE, + 0x033, 0x000000A9, + 0x03F, 0x00000CF1, + 0x033, 0x000000AA, + 0x03F, 0x00000CF4, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x00000047, + 0x033, 0x000000A5, + 0x03F, 0x0000004A, + 0x033, 0x000000A6, + 0x03F, 0x0000004D, + 0x033, 0x000000A7, + 0x03F, 0x00000050, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x00000094, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000042A, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x00000848, + 0x033, 0x000000A3, + 0x03F, 0x0000084B, + 0x033, 0x000000A4, + 0x03F, 0x00000C4C, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CEB, + 0x033, 0x000000A8, + 0x03F, 0x00000CEE, + 0x033, 0x000000A9, + 0x03F, 0x00000CF1, + 0x033, 0x000000AA, + 0x03F, 0x00000CF4, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000400, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x000008BB, + 0x033, 0x00000001, + 0x03F, 0x000008BB, + 0x033, 0x00000002, + 0x03F, 0x000008BB, + 0x033, 0x00000003, + 0x03F, 0x000008BB, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000047C, + 0x033, 0x00000001, + 0x03F, 0x0000047C, + 0x033, 0x00000002, + 0x03F, 0x0000047C, + 0x033, 0x00000003, + 0x03F, 0x0000047C, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x000004BB, + 0x033, 0x00000001, + 0x03F, 0x000004BB, + 0x033, 0x00000002, + 0x03F, 0x000004BB, + 0x033, 0x00000003, + 0x03F, 0x000004BB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000100, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00001726, + 0x033, 0x00000001, + 0x03F, 0x00001726, + 0x033, 0x00000002, + 0x03F, 0x00001726, + 0x033, 0x00000003, + 0x03F, 0x00001726, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000F34, + 0x033, 0x00000001, + 0x03F, 0x00000F34, + 0x033, 0x00000002, + 0x03F, 0x00000F34, + 0x033, 0x00000003, + 0x03F, 0x00000F34, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0xA0000000, 0x00000000, + 0x081, 0x0000F000, + 0x087, 0x00016040, + 0x051, 0x00000C00, + 0x052, 0x0007C241, + 0x053, 0x0001C069, + 0x054, 0x00078032, + 0x057, 0x0000CE0A, + 0x058, 0x00058750, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000800, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000002, + 0x033, 0x00000001, + 0x03F, 0x00000005, + 0x033, 0x00000002, + 0x03F, 0x00000008, + 0x033, 0x00000003, + 0x03F, 0x0000000B, + 0x033, 0x00000004, + 0x03F, 0x0000000E, + 0x033, 0x00000005, + 0x03F, 0x0000002B, + 0x033, 0x00000006, + 0x03F, 0x0000002E, + 0x033, 0x00000007, + 0x03F, 0x00000031, + 0x033, 0x00000008, + 0x03F, 0x0000006E, + 0x033, 0x00000009, + 0x03F, 0x00000071, + 0x033, 0x0000000A, + 0x03F, 0x00000074, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000002, + 0x033, 0x00000001, + 0x03F, 0x00000005, + 0x033, 0x00000002, + 0x03F, 0x00000008, + 0x033, 0x00000003, + 0x03F, 0x0000000B, + 0x033, 0x00000004, + 0x03F, 0x0000000E, + 0x033, 0x00000005, + 0x03F, 0x0000002B, + 0x033, 0x00000006, + 0x03F, 0x0000002E, + 0x033, 0x00000007, + 0x03F, 0x00000031, + 0x033, 0x00000008, + 0x03F, 0x0000006E, + 0x033, 0x00000009, + 0x03F, 0x00000071, + 0x033, 0x0000000A, + 0x03F, 0x00000074, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0005142C, + 0x033, 0x00000001, + 0x03F, 0x0005144B, + 0x033, 0x00000002, + 0x03F, 0x0005144E, + 0x033, 0x00000003, + 0x03F, 0x00051C69, + 0x033, 0x00000004, + 0x03F, 0x00051C6C, + 0x033, 0x00000005, + 0x03F, 0x00051C6F, + 0x033, 0x00000006, + 0x03F, 0x00051CEB, + 0x033, 0x00000007, + 0x03F, 0x00051CEE, + 0x033, 0x00000008, + 0x03F, 0x00051CF1, + 0x033, 0x00000009, + 0x03F, 0x00051CF4, + 0x033, 0x0000000A, + 0x03F, 0x00051CF7, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x033, 0x000000A2, + 0x0EF, 0x00080000, + 0x03E, 0x0000593F, + 0x8300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000D0F4F, + 0xA0000000, 0x00000000, + 0x03F, 0x000C0F4F, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x033, 0x000000A3, + 0x0EF, 0x00080000, + 0x03E, 0x00005934, + 0x03F, 0x0005AFCF, + 0x0EF, 0x00000000, + 0x83000002, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0CE, 0x00094400, + 0xA0000000, 0x00000000, + 0x0CE, 0x00094C00, + 0xB0000000, 0x00000000, + 0x83000002, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00064700, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0CF, 0x00072F00, + 0xA0000000, 0x00000000, + 0x0CF, 0x00064700, + 0xB0000000, 0x00000000, + 0x83000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000096, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x00000056, + 0x0EF, 0x00000000, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000004, + 0x033, 0x00000000, + 0x03F, 0x00000056, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000096, + 0x033, 0x00000001, + 0x03F, 0x000000D6, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0B0, 0x000FF0FC, + 0x0C4, 0x00081402, + 0x0CC, 0x00082000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8822b_rf_a, A); + +static const u32 rtw8822b_rf_b[] = { + 0x000, 0x00030000, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, + 0xA0000000, 0x00000000, + 0x001, 0x00040029, + 0xB0000000, 0x00000000, + 0x018, 0x00010D24, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x8300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000D0F4E, + 0xA0000000, 0x00000000, + 0x03F, 0x000C0F4E, + 0xB0000000, 0x00000000, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x0EF, 0x00080000, + 0x0DF, 0x00002449, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, + 0x0DF, 0x00000009, + 0x018, 0x00010524, + 0x089, 0x00000207, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, + 0xA0000000, 0x00000000, + 0x08A, 0x000FF186, + 0xB0000000, 0x00000000, + 0x08B, 0x00061E3C, + 0x08C, 0x000112C7, + 0x08D, 0x000F4988, + 0x08E, 0x00064D40, + 0x0EF, 0x00020000, + 0x033, 0x00000007, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x00000006, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000040C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00004190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00004998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00005840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000058C2, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00005930, + 0x03F, 0x000C3186, + 0x033, 0x0000000F, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x0000000E, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x8300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040D0, + 0xA0000000, 0x00000000, + 0x03E, 0x000040C8, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00004190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00004998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00005840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000058C2, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00005930, + 0x03F, 0x000C3186, + 0x033, 0x00000017, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000DFF86, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000DFF86, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C0006, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x03E, 0x00004000, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x033, 0x00000016, + 0x03E, 0x00004080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x8300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000040D0, + 0xA0000000, 0x00000000, + 0x03E, 0x000040C8, + 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00004190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00004998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00005840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000058C2, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00005930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000A, + 0x033, 0x00000001, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000002, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000005, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00000000, + 0xA0000000, 0x00000000, + 0x03F, 0x00000005, + 0xB0000000, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x087, 0x00068080, + 0xA0000000, 0x00000000, + 0x087, 0x000E8180, + 0xB0000000, 0x00000000, + 0x088, 0x00070020, + 0x0DE, 0x00000010, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x018, 0x00018D24, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x00010D24, + 0x01B, 0x00075A40, + 0x0EE, 0x00000002, + 0x033, 0x00000000, + 0x03F, 0x00000004, + 0x033, 0x00000001, + 0x03F, 0x00000004, + 0x033, 0x00000002, + 0x03F, 0x00000004, + 0x033, 0x00000003, + 0x03F, 0x00000004, + 0x033, 0x00000004, + 0x03F, 0x00000004, + 0x033, 0x00000005, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000004, + 0x033, 0x00000007, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000062, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, + 0x063, 0x00000002, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, + 0x062, 0x0000D203, + 0x063, 0x00000062, + 0xA0000000, 0x00000000, + 0x061, 0x0005D3D0, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A3, + 0x030, 0x000053A3, + 0x030, 0x000063A3, + 0x030, 0x000073A3, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000303, + 0x030, 0x00001303, + 0x030, 0x00002303, + 0x030, 0x00003303, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A4, + 0x030, 0x000014A4, + 0x030, 0x000024A4, + 0x030, 0x000034A4, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x000083A5, + 0x030, 0x000093A5, + 0x030, 0x0000A3A5, + 0x030, 0x0000B3A5, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002F4, + 0x030, 0x000012F4, + 0x030, 0x000022F4, + 0x030, 0x000032F4, + 0x030, 0x00004365, + 0x030, 0x00005365, + 0x030, 0x00006365, + 0x030, 0x00007365, + 0x030, 0x000082A4, + 0x030, 0x000092A4, + 0x030, 0x0000A2A4, + 0x030, 0x0000B2A4, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000382, + 0x030, 0x00001382, + 0x030, 0x00002382, + 0x030, 0x00003382, + 0x030, 0x00004445, + 0x030, 0x00005445, + 0x030, 0x00006445, + 0x030, 0x00007445, + 0x030, 0x00008425, + 0x030, 0x00009425, + 0x030, 0x0000A425, + 0x030, 0x0000B425, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A3, + 0x030, 0x000053A3, + 0x030, 0x000063A3, + 0x030, 0x000073A3, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, + 0x030, 0x000014A3, + 0x030, 0x000024A3, + 0x030, 0x000034A3, + 0x030, 0x000044A3, + 0x030, 0x000054A3, + 0x030, 0x000064A3, + 0x030, 0x000074A3, + 0x030, 0x000084A3, + 0x030, 0x000094A3, + 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000443, + 0x030, 0x00001443, + 0x030, 0x00002443, + 0x030, 0x00003443, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000343, + 0x030, 0x00001343, + 0x030, 0x00002343, + 0x030, 0x00003343, + 0x030, 0x00004483, + 0x030, 0x00005483, + 0x030, 0x00006483, + 0x030, 0x00007483, + 0x030, 0x000083A4, + 0x030, 0x000093A4, + 0x030, 0x0000A3A4, + 0x030, 0x0000B3A4, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x00004423, + 0x030, 0x00005423, + 0x030, 0x00006423, + 0x030, 0x00007423, + 0x030, 0x00008324, + 0x030, 0x00009324, + 0x030, 0x0000A324, + 0x030, 0x0000B324, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000303, + 0x030, 0x00001303, + 0x030, 0x00002303, + 0x030, 0x00003303, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000403, + 0x030, 0x00001403, + 0x030, 0x00002403, + 0x030, 0x00003403, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A3, + 0x030, 0x000013A3, + 0x030, 0x000023A3, + 0x030, 0x000033A3, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x00008365, + 0x030, 0x00009365, + 0x030, 0x0000A365, + 0x030, 0x0000B365, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A6, + 0x030, 0x000012A6, + 0x030, 0x000022A6, + 0x030, 0x000032A6, + 0x030, 0x000042A6, + 0x030, 0x000052A6, + 0x030, 0x000062A6, + 0x030, 0x000072A6, + 0x030, 0x000082A6, + 0x030, 0x000092A6, + 0x030, 0x0000A2A6, + 0x030, 0x0000B2A6, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A1, + 0x030, 0x000012A1, + 0x030, 0x000022A1, + 0x030, 0x000032A1, + 0x030, 0x000042A1, + 0x030, 0x000052A1, + 0x030, 0x000062A1, + 0x030, 0x000072A1, + 0x030, 0x000082A1, + 0x030, 0x000092A1, + 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000043A1, + 0x030, 0x000053A1, + 0x030, 0x000063A1, + 0x030, 0x000073A1, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A1, + 0x030, 0x000012A1, + 0x030, 0x000022A1, + 0x030, 0x000032A1, + 0x030, 0x000042A1, + 0x030, 0x000052A1, + 0x030, 0x000062A1, + 0x030, 0x000072A1, + 0x030, 0x000082A1, + 0x030, 0x000092A1, + 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A1, + 0x030, 0x000014A1, + 0x030, 0x000024A1, + 0x030, 0x000034A1, + 0x030, 0x000043A1, + 0x030, 0x000053A1, + 0x030, 0x000063A1, + 0x030, 0x000073A1, + 0x030, 0x000083A1, + 0x030, 0x000093A1, + 0x030, 0x0000A3A1, + 0x030, 0x0000B3A1, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, + 0x030, 0x000014A0, + 0x030, 0x000024A0, + 0x030, 0x000034A0, + 0x030, 0x000044A0, + 0x030, 0x000054A0, + 0x030, 0x000064A0, + 0x030, 0x000074A0, + 0x030, 0x000084A0, + 0x030, 0x000094A0, + 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, + 0xA0000000, 0x00000000, + 0x030, 0x000002D0, + 0x030, 0x000012D0, + 0x030, 0x000022D0, + 0x030, 0x000032D0, + 0x030, 0x000042D0, + 0x030, 0x000052D0, + 0x030, 0x000062D0, + 0x030, 0x000072D0, + 0x030, 0x000082D0, + 0x030, 0x000092D0, + 0x030, 0x0000A2D0, + 0x030, 0x0000B2D0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000080, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A3, + 0x030, 0x000013A3, + 0x030, 0x000023A3, + 0x030, 0x000033A3, + 0x030, 0x000043A4, + 0x030, 0x000053A4, + 0x030, 0x000063A4, + 0x030, 0x000073A4, + 0x030, 0x000083A3, + 0x030, 0x000093A3, + 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, + 0x030, 0x00001203, + 0x030, 0x00002203, + 0x030, 0x00003203, + 0x030, 0x00004203, + 0x030, 0x00005203, + 0x030, 0x00006203, + 0x030, 0x00007203, + 0x030, 0x00008203, + 0x030, 0x00009203, + 0x030, 0x0000A203, + 0x030, 0x0000B203, + 0xA0000000, 0x00000000, + 0x030, 0x000003A2, + 0x030, 0x000013A2, + 0x030, 0x000023A2, + 0x030, 0x000033A2, + 0x030, 0x000043A2, + 0x030, 0x000053A2, + 0x030, 0x000063A2, + 0x030, 0x000073A2, + 0x030, 0x000083A2, + 0x030, 0x000093A2, + 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000040, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001452, + 0x030, 0x00002220, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000660, + 0x030, 0x00001341, + 0x030, 0x00002220, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000767, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000765, + 0x030, 0x00001632, + 0x030, 0x00002451, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000776, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000777, + 0x030, 0x00001442, + 0x030, 0x00002222, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004777, + 0x030, 0x00005777, + 0x030, 0x00006777, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000775, + 0x030, 0x00001422, + 0x030, 0x00002210, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000775, + 0x030, 0x00001222, + 0x030, 0x00002210, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, + 0x030, 0x00001333, + 0x030, 0x00002011, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0xA0000000, 0x00000000, + 0x030, 0x00000764, + 0x030, 0x00001632, + 0x030, 0x00002421, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042C, + 0x033, 0x00000021, + 0x03F, 0x0000082B, + 0x033, 0x00000022, + 0x03F, 0x0000084A, + 0x033, 0x00000023, + 0x03F, 0x0000084D, + 0x033, 0x00000024, + 0x03F, 0x00000C4E, + 0x033, 0x00000025, + 0x03F, 0x00000C6E, + 0x033, 0x00000026, + 0x03F, 0x00000CAD, + 0x033, 0x00000027, + 0x03F, 0x00000CED, + 0x033, 0x00000028, + 0x03F, 0x00000CF0, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000828, + 0x033, 0x00000021, + 0x03F, 0x0000082B, + 0x033, 0x00000022, + 0x03F, 0x00000868, + 0x033, 0x00000023, + 0x03F, 0x00000889, + 0x033, 0x00000024, + 0x03F, 0x000008AA, + 0x033, 0x00000025, + 0x03F, 0x00000CE8, + 0x033, 0x00000026, + 0x03F, 0x00000CEB, + 0x033, 0x00000027, + 0x03F, 0x00000CEE, + 0x033, 0x00000028, + 0x03F, 0x00000CF1, + 0x033, 0x00000029, + 0x03F, 0x00000CF4, + 0x033, 0x0000002A, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000CE5, + 0x033, 0x00000026, + 0x03F, 0x00000CE8, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C25, + 0x033, 0x00000021, + 0x03F, 0x00000C28, + 0x033, 0x00000022, + 0x03F, 0x00000C2B, + 0x033, 0x00000023, + 0x03F, 0x00000C68, + 0x033, 0x00000024, + 0x03F, 0x00000C6B, + 0x033, 0x00000025, + 0x03F, 0x00000C6E, + 0x033, 0x00000026, + 0x03F, 0x00000CEB, + 0x033, 0x00000027, + 0x03F, 0x00000CEE, + 0x033, 0x00000028, + 0x03F, 0x00000CF1, + 0x033, 0x00000029, + 0x03F, 0x00000CF4, + 0x033, 0x0000002A, + 0x03F, 0x00000CF7, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000CEA, + 0x033, 0x00000027, + 0x03F, 0x00000CED, + 0x033, 0x00000028, + 0x03F, 0x00000CF0, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000429, + 0x033, 0x00000021, + 0x03F, 0x00000828, + 0x033, 0x00000022, + 0x03F, 0x00000847, + 0x033, 0x00000023, + 0x03F, 0x0000084A, + 0x033, 0x00000024, + 0x03F, 0x00000C4B, + 0x033, 0x00000025, + 0x03F, 0x00000C6C, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CAF, + 0x033, 0x00000028, + 0x03F, 0x00000CD1, + 0x033, 0x00000029, + 0x03F, 0x00000CF3, + 0x033, 0x0000002A, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x0000002E, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x00000068, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042B, + 0x033, 0x00000021, + 0x03F, 0x0000082A, + 0x033, 0x00000022, + 0x03F, 0x00000849, + 0x033, 0x00000023, + 0x03F, 0x0000084C, + 0x033, 0x00000024, + 0x03F, 0x00000C4C, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000005, + 0x033, 0x00000021, + 0x03F, 0x00000008, + 0x033, 0x00000022, + 0x03F, 0x0000000B, + 0x033, 0x00000023, + 0x03F, 0x0000000E, + 0x033, 0x00000024, + 0x03F, 0x0000002B, + 0x033, 0x00000025, + 0x03F, 0x00000068, + 0x033, 0x00000026, + 0x03F, 0x0000006B, + 0x033, 0x00000027, + 0x03F, 0x0000006E, + 0x033, 0x00000028, + 0x03F, 0x00000071, + 0x033, 0x00000029, + 0x03F, 0x00000074, + 0x033, 0x0000002A, + 0x03F, 0x00000077, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x0000042B, + 0x033, 0x00000021, + 0x03F, 0x0000082A, + 0x033, 0x00000022, + 0x03F, 0x00000849, + 0x033, 0x00000023, + 0x03F, 0x0000084C, + 0x033, 0x00000024, + 0x03F, 0x00000C4C, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000CEB, + 0x033, 0x00000028, + 0x03F, 0x00000CEE, + 0x033, 0x00000029, + 0x03F, 0x00000CF1, + 0x033, 0x0000002A, + 0x03F, 0x00000CF4, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000007, + 0x033, 0x00000021, + 0x03F, 0x0000000A, + 0x033, 0x00000022, + 0x03F, 0x0000000D, + 0x033, 0x00000023, + 0x03F, 0x0000002A, + 0x033, 0x00000024, + 0x03F, 0x0000002D, + 0x033, 0x00000025, + 0x03F, 0x00000030, + 0x033, 0x00000026, + 0x03F, 0x0000006D, + 0x033, 0x00000027, + 0x03F, 0x00000070, + 0x033, 0x00000028, + 0x03F, 0x000000ED, + 0x033, 0x00000029, + 0x03F, 0x000000F0, + 0x033, 0x0000002A, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000C09, + 0x033, 0x00000021, + 0x03F, 0x00000C0C, + 0x033, 0x00000022, + 0x03F, 0x00000C0F, + 0x033, 0x00000023, + 0x03F, 0x00000C2C, + 0x033, 0x00000024, + 0x03F, 0x00000C2F, + 0x033, 0x00000025, + 0x03F, 0x00000C8A, + 0x033, 0x00000026, + 0x03F, 0x00000C8D, + 0x033, 0x00000027, + 0x03F, 0x00000C90, + 0x033, 0x00000028, + 0x03F, 0x00000CD0, + 0x033, 0x00000029, + 0x03F, 0x00000CF2, + 0x033, 0x0000002A, + 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042A, + 0x033, 0x00000061, + 0x03F, 0x00000829, + 0x033, 0x00000062, + 0x03F, 0x00000848, + 0x033, 0x00000063, + 0x03F, 0x0000084B, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000CAC, + 0x033, 0x00000067, + 0x03F, 0x00000CED, + 0x033, 0x00000068, + 0x03F, 0x00000CF0, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000842, + 0x033, 0x00000061, + 0x03F, 0x00000845, + 0x033, 0x00000062, + 0x03F, 0x00000866, + 0x033, 0x00000063, + 0x03F, 0x000008A6, + 0x033, 0x00000064, + 0x03F, 0x000008C8, + 0x033, 0x00000065, + 0x03F, 0x00000CE8, + 0x033, 0x00000066, + 0x03F, 0x00000CEB, + 0x033, 0x00000067, + 0x03F, 0x00000CEE, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000CE5, + 0x033, 0x00000066, + 0x03F, 0x00000CE8, + 0x033, 0x00000067, + 0x03F, 0x00000CEB, + 0x033, 0x00000068, + 0x03F, 0x00000CEE, + 0x033, 0x00000069, + 0x03F, 0x00000CF1, + 0x033, 0x0000006A, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C10, + 0x033, 0x00000063, + 0x03F, 0x00000C4A, + 0x033, 0x00000064, + 0x03F, 0x00000C4D, + 0x033, 0x00000065, + 0x03F, 0x00000CC9, + 0x033, 0x00000066, + 0x03F, 0x00000CEB, + 0x033, 0x00000067, + 0x03F, 0x00000CEE, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C8A, + 0x033, 0x00000066, + 0x03F, 0x00000CEA, + 0x033, 0x00000067, + 0x03F, 0x00000CED, + 0x033, 0x00000068, + 0x03F, 0x00000CF0, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000429, + 0x033, 0x00000061, + 0x03F, 0x00000828, + 0x033, 0x00000062, + 0x03F, 0x00000847, + 0x033, 0x00000063, + 0x03F, 0x0000084A, + 0x033, 0x00000064, + 0x03F, 0x00000C4B, + 0x033, 0x00000065, + 0x03F, 0x00000C6C, + 0x033, 0x00000066, + 0x03F, 0x00000C8D, + 0x033, 0x00000067, + 0x03F, 0x00000CAF, + 0x033, 0x00000068, + 0x03F, 0x00000CD1, + 0x033, 0x00000069, + 0x03F, 0x00000CF3, + 0x033, 0x0000006A, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x0000002E, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042C, + 0x033, 0x00000061, + 0x03F, 0x0000082B, + 0x033, 0x00000062, + 0x03F, 0x0000084A, + 0x033, 0x00000063, + 0x03F, 0x0000084D, + 0x033, 0x00000064, + 0x03F, 0x00000C4E, + 0x033, 0x00000065, + 0x03F, 0x00000C8C, + 0x033, 0x00000066, + 0x03F, 0x00000C8F, + 0x033, 0x00000067, + 0x03F, 0x00000CEC, + 0x033, 0x00000068, + 0x03F, 0x00000CEF, + 0x033, 0x00000069, + 0x03F, 0x00000CF2, + 0x033, 0x0000006A, + 0x03F, 0x00000CF5, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000005, + 0x033, 0x00000061, + 0x03F, 0x00000008, + 0x033, 0x00000062, + 0x03F, 0x0000000B, + 0x033, 0x00000063, + 0x03F, 0x0000000E, + 0x033, 0x00000064, + 0x03F, 0x0000002B, + 0x033, 0x00000065, + 0x03F, 0x00000068, + 0x033, 0x00000066, + 0x03F, 0x0000006B, + 0x033, 0x00000067, + 0x03F, 0x0000006E, + 0x033, 0x00000068, + 0x03F, 0x00000071, + 0x033, 0x00000069, + 0x03F, 0x00000074, + 0x033, 0x0000006A, + 0x03F, 0x00000077, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x0000042C, + 0x033, 0x00000061, + 0x03F, 0x0000082B, + 0x033, 0x00000062, + 0x03F, 0x0000084A, + 0x033, 0x00000063, + 0x03F, 0x0000084D, + 0x033, 0x00000064, + 0x03F, 0x00000C4E, + 0x033, 0x00000065, + 0x03F, 0x00000C8C, + 0x033, 0x00000066, + 0x03F, 0x00000C8F, + 0x033, 0x00000067, + 0x03F, 0x00000CEC, + 0x033, 0x00000068, + 0x03F, 0x00000CEF, + 0x033, 0x00000069, + 0x03F, 0x00000CF2, + 0x033, 0x0000006A, + 0x03F, 0x00000CF5, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000007, + 0x033, 0x00000061, + 0x03F, 0x0000000A, + 0x033, 0x00000062, + 0x03F, 0x0000000D, + 0x033, 0x00000063, + 0x03F, 0x0000002A, + 0x033, 0x00000064, + 0x03F, 0x0000002D, + 0x033, 0x00000065, + 0x03F, 0x00000030, + 0x033, 0x00000066, + 0x03F, 0x0000006D, + 0x033, 0x00000067, + 0x03F, 0x00000070, + 0x033, 0x00000068, + 0x03F, 0x000000ED, + 0x033, 0x00000069, + 0x03F, 0x000000F0, + 0x033, 0x0000006A, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000C0A, + 0x033, 0x00000061, + 0x03F, 0x00000C0D, + 0x033, 0x00000062, + 0x03F, 0x00000C2A, + 0x033, 0x00000063, + 0x03F, 0x00000C2D, + 0x033, 0x00000064, + 0x03F, 0x00000C6A, + 0x033, 0x00000065, + 0x03F, 0x00000CAA, + 0x033, 0x00000066, + 0x03F, 0x00000CAD, + 0x033, 0x00000067, + 0x03F, 0x00000CB0, + 0x033, 0x00000068, + 0x03F, 0x00000CF1, + 0x033, 0x00000069, + 0x03F, 0x00000CF4, + 0x033, 0x0000006A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000042A, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x00000848, + 0x033, 0x000000A3, + 0x03F, 0x0000084B, + 0x033, 0x000000A4, + 0x03F, 0x00000C4C, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000CAC, + 0x033, 0x000000A7, + 0x03F, 0x00000CED, + 0x033, 0x000000A8, + 0x03F, 0x00000CF0, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x93000008, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000826, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x0000082C, + 0x033, 0x000000A3, + 0x03F, 0x0000082F, + 0x033, 0x000000A4, + 0x03F, 0x0000086C, + 0x033, 0x000000A5, + 0x03F, 0x00000CE8, + 0x033, 0x000000A6, + 0x03F, 0x00000CEB, + 0x033, 0x000000A7, + 0x03F, 0x00000CEE, + 0x033, 0x000000A8, + 0x03F, 0x00000CF1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF4, + 0x033, 0x000000AA, + 0x03F, 0x00000CF7, + 0x93000009, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000a, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000CE5, + 0x033, 0x000000A6, + 0x03F, 0x00000CE8, + 0x033, 0x000000A7, + 0x03F, 0x00000CEB, + 0x033, 0x000000A8, + 0x03F, 0x00000CEE, + 0x033, 0x000000A9, + 0x03F, 0x00000CF1, + 0x033, 0x000000AA, + 0x03F, 0x00000CF4, + 0x9300000d, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000080A, + 0x033, 0x000000A1, + 0x03F, 0x0000080D, + 0x033, 0x000000A2, + 0x03F, 0x00000810, + 0x033, 0x000000A3, + 0x03F, 0x00000868, + 0x033, 0x000000A4, + 0x03F, 0x00000C68, + 0x033, 0x000000A5, + 0x03F, 0x00000C6B, + 0x033, 0x000000A6, + 0x03F, 0x00000CAB, + 0x033, 0x000000A7, + 0x03F, 0x00000CAE, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000e, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C08, + 0x033, 0x000000A1, + 0x03F, 0x00000C0B, + 0x033, 0x000000A2, + 0x03F, 0x00000C0E, + 0x033, 0x000000A3, + 0x03F, 0x00000C2B, + 0x033, 0x000000A4, + 0x03F, 0x00000C2E, + 0x033, 0x000000A5, + 0x03F, 0x00000C31, + 0x033, 0x000000A6, + 0x03F, 0x00000CAB, + 0x033, 0x000000A7, + 0x03F, 0x00000CAE, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000CEA, + 0x033, 0x000000A7, + 0x03F, 0x00000CED, + 0x033, 0x000000A8, + 0x03F, 0x00000CF0, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000010, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000011, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000429, + 0x033, 0x000000A1, + 0x03F, 0x00000828, + 0x033, 0x000000A2, + 0x03F, 0x00000847, + 0x033, 0x000000A3, + 0x03F, 0x0000084A, + 0x033, 0x000000A4, + 0x03F, 0x00000C4B, + 0x033, 0x000000A5, + 0x03F, 0x00000C6C, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CAF, + 0x033, 0x000000A8, + 0x03F, 0x00000CD1, + 0x033, 0x000000A9, + 0x03F, 0x00000CF3, + 0x033, 0x000000AA, + 0x03F, 0x00000CF6, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x0000002B, + 0x033, 0x000000A5, + 0x03F, 0x0000002E, + 0x033, 0x000000A6, + 0x03F, 0x00000031, + 0x033, 0x000000A7, + 0x03F, 0x00000034, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x000000D1, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x00000047, + 0x033, 0x000000A5, + 0x03F, 0x0000004A, + 0x033, 0x000000A6, + 0x03F, 0x0000004D, + 0x033, 0x000000A7, + 0x03F, 0x00000050, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x00000094, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000042A, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x00000848, + 0x033, 0x000000A3, + 0x03F, 0x0000084B, + 0x033, 0x000000A4, + 0x03F, 0x00000C4C, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CEC, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000005, + 0x033, 0x000000A1, + 0x03F, 0x00000008, + 0x033, 0x000000A2, + 0x03F, 0x0000000B, + 0x033, 0x000000A3, + 0x03F, 0x0000000E, + 0x033, 0x000000A4, + 0x03F, 0x00000047, + 0x033, 0x000000A5, + 0x03F, 0x0000004A, + 0x033, 0x000000A6, + 0x03F, 0x0000004D, + 0x033, 0x000000A7, + 0x03F, 0x00000050, + 0x033, 0x000000A8, + 0x03F, 0x00000053, + 0x033, 0x000000A9, + 0x03F, 0x00000056, + 0x033, 0x000000AA, + 0x03F, 0x00000094, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x0000042A, + 0x033, 0x000000A1, + 0x03F, 0x00000829, + 0x033, 0x000000A2, + 0x03F, 0x00000848, + 0x033, 0x000000A3, + 0x03F, 0x0000084B, + 0x033, 0x000000A4, + 0x03F, 0x00000C4C, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000CEC, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000007, + 0x033, 0x000000A1, + 0x03F, 0x0000000A, + 0x033, 0x000000A2, + 0x03F, 0x0000000D, + 0x033, 0x000000A3, + 0x03F, 0x0000002A, + 0x033, 0x000000A4, + 0x03F, 0x0000002D, + 0x033, 0x000000A5, + 0x03F, 0x00000030, + 0x033, 0x000000A6, + 0x03F, 0x0000006D, + 0x033, 0x000000A7, + 0x03F, 0x00000070, + 0x033, 0x000000A8, + 0x03F, 0x000000ED, + 0x033, 0x000000A9, + 0x03F, 0x000000F0, + 0x033, 0x000000AA, + 0x03F, 0x000000F3, + 0xA0000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000C09, + 0x033, 0x000000A1, + 0x03F, 0x00000C0C, + 0x033, 0x000000A2, + 0x03F, 0x00000C0F, + 0x033, 0x000000A3, + 0x03F, 0x00000C2C, + 0x033, 0x000000A4, + 0x03F, 0x00000C2F, + 0x033, 0x000000A5, + 0x03F, 0x00000C8A, + 0x033, 0x000000A6, + 0x03F, 0x00000C8D, + 0x033, 0x000000A7, + 0x03F, 0x00000C90, + 0x033, 0x000000A8, + 0x03F, 0x00000CEF, + 0x033, 0x000000A9, + 0x03F, 0x00000CF2, + 0x033, 0x000000AA, + 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000400, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x000004FB, + 0x033, 0x00000001, + 0x03F, 0x000004FB, + 0x033, 0x00000002, + 0x03F, 0x000004FB, + 0x033, 0x00000003, + 0x03F, 0x000004FB, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0000265A, + 0x033, 0x00000001, + 0x03F, 0x0000265A, + 0x033, 0x00000002, + 0x03F, 0x0000265A, + 0x033, 0x00000003, + 0x03F, 0x0000265A, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x000004BB, + 0x033, 0x00000001, + 0x03F, 0x000004BB, + 0x033, 0x00000002, + 0x03F, 0x000004BB, + 0x033, 0x00000003, + 0x03F, 0x000004BB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000100, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000745, + 0x033, 0x00000001, + 0x03F, 0x00000745, + 0x033, 0x00000002, + 0x03F, 0x00000745, + 0x033, 0x00000003, + 0x03F, 0x00000745, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000F34, + 0x033, 0x00000001, + 0x03F, 0x00000F34, + 0x033, 0x00000002, + 0x03F, 0x00000F34, + 0x033, 0x00000003, + 0x03F, 0x00000F34, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, + 0x087, 0x00016040, + 0x051, 0x00000808, + 0x052, 0x00098002, + 0x053, 0x0000FA47, + 0x054, 0x00058032, + 0x056, 0x00051000, + 0x057, 0x0000CE0A, + 0x058, 0x00082030, + 0xA0000000, 0x00000000, + 0x081, 0x0000F000, + 0x087, 0x00016040, + 0x051, 0x00000C00, + 0x052, 0x0007C241, + 0x053, 0x0001C069, + 0x054, 0x00078032, + 0x057, 0x0000CE0A, + 0x058, 0x00058750, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000800, + 0x83000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000002, + 0x033, 0x00000001, + 0x03F, 0x00000005, + 0x033, 0x00000002, + 0x03F, 0x00000008, + 0x033, 0x00000003, + 0x03F, 0x0000000B, + 0x033, 0x00000004, + 0x03F, 0x0000000E, + 0x033, 0x00000005, + 0x03F, 0x0000002B, + 0x033, 0x00000006, + 0x03F, 0x0000002E, + 0x033, 0x00000007, + 0x03F, 0x00000031, + 0x033, 0x00000008, + 0x03F, 0x0000006E, + 0x033, 0x00000009, + 0x03F, 0x00000071, + 0x033, 0x0000000A, + 0x03F, 0x00000074, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x93000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x9300000b, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x9300000c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0005142C, + 0x033, 0x00000001, + 0x03F, 0x0005142F, + 0x033, 0x00000002, + 0x03F, 0x00051432, + 0x033, 0x00000003, + 0x03F, 0x00051CA5, + 0x033, 0x00000004, + 0x03F, 0x00051CA8, + 0x033, 0x00000005, + 0x03F, 0x00051CAB, + 0x033, 0x00000006, + 0x03F, 0x00051CEB, + 0x033, 0x00000007, + 0x03F, 0x00051CEE, + 0x033, 0x00000008, + 0x03F, 0x00051CF1, + 0x033, 0x00000009, + 0x03F, 0x00051CF4, + 0x033, 0x0000000A, + 0x03F, 0x00051CF7, + 0x9300000f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0005142C, + 0x033, 0x00000001, + 0x03F, 0x0005144B, + 0x033, 0x00000002, + 0x03F, 0x00051868, + 0x033, 0x00000003, + 0x03F, 0x0005186B, + 0x033, 0x00000004, + 0x03F, 0x0005186E, + 0x033, 0x00000005, + 0x03F, 0x00051871, + 0x033, 0x00000006, + 0x03F, 0x00051874, + 0x033, 0x00000007, + 0x03F, 0x00051895, + 0x033, 0x00000008, + 0x03F, 0x000518B6, + 0x033, 0x00000009, + 0x03F, 0x000518F6, + 0x033, 0x0000000A, + 0x03F, 0x00051CF7, + 0x93000012, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000002, + 0x033, 0x00000001, + 0x03F, 0x00000005, + 0x033, 0x00000002, + 0x03F, 0x00000008, + 0x033, 0x00000003, + 0x03F, 0x0000000B, + 0x033, 0x00000004, + 0x03F, 0x0000000E, + 0x033, 0x00000005, + 0x03F, 0x0000002B, + 0x033, 0x00000006, + 0x03F, 0x0000002E, + 0x033, 0x00000007, + 0x03F, 0x00000031, + 0x033, 0x00000008, + 0x03F, 0x0000006E, + 0x033, 0x00000009, + 0x03F, 0x00000071, + 0x033, 0x0000000A, + 0x03F, 0x00000074, + 0x90000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x00000003, + 0x033, 0x00000001, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000009, + 0x033, 0x00000003, + 0x03F, 0x00000026, + 0x033, 0x00000004, + 0x03F, 0x00000029, + 0x033, 0x00000005, + 0x03F, 0x0000002C, + 0x033, 0x00000006, + 0x03F, 0x0000002F, + 0x033, 0x00000007, + 0x03F, 0x00000033, + 0x033, 0x00000008, + 0x03F, 0x00000036, + 0x033, 0x00000009, + 0x03F, 0x00000039, + 0x033, 0x0000000A, + 0x03F, 0x0000003C, + 0xA0000000, 0x00000000, + 0x033, 0x00000000, + 0x03F, 0x0005142C, + 0x033, 0x00000001, + 0x03F, 0x0005142F, + 0x033, 0x00000002, + 0x03F, 0x00051432, + 0x033, 0x00000003, + 0x03F, 0x00051C87, + 0x033, 0x00000004, + 0x03F, 0x00051C8A, + 0x033, 0x00000005, + 0x03F, 0x00051C8D, + 0x033, 0x00000006, + 0x03F, 0x00051CEB, + 0x033, 0x00000007, + 0x03F, 0x00051CEE, + 0x033, 0x00000008, + 0x03F, 0x00051CF1, + 0x033, 0x00000009, + 0x03F, 0x00051CF4, + 0x033, 0x0000000A, + 0x03F, 0x00051CF7, + 0xB0000000, 0x00000000, + 0x8300000c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x033, 0x000000A2, + 0x0EF, 0x00080000, + 0x03E, 0x0000593F, + 0x8300000c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000D0F4F, + 0xA0000000, 0x00000000, + 0x03F, 0x000C0F4F, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x033, 0x000000A3, + 0x0EF, 0x00080000, + 0x03E, 0x00005934, + 0x03F, 0x0005AFCF, + 0x0EF, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8822b_rf_b, B); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8822b_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 28, }, + { 1, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 28, }, + { 1, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 28, }, + { 1, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 28, }, + { 1, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 28, }, + { 1, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 28, }, + { 1, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 28, }, + { 1, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 28, }, + { 1, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 28, }, + { 1, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 28, }, + { 1, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 28, }, + { 1, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 26, }, + { 2, 0, 0, 0, 12, 28, }, + { 1, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 20, }, + { 2, 0, 0, 0, 13, 28, }, + { 1, 0, 0, 0, 13, 28, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 26, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 34, }, + { 0, 0, 0, 1, 2, 30, }, + { 2, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 0, 0, 0, 1, 10, 30, }, + { 2, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 0, 0, 0, 1, 12, 22, }, + { 2, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 0, 0, 0, 1, 13, 14, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 1, 34, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 0, 0, 0, 2, 12, 20, }, + { 2, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 0, 0, 0, 2, 13, 14, }, + { 2, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 18, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 28, }, + { 2, 0, 0, 3, 2, 18, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 18, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 18, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 32, }, + { 2, 0, 0, 3, 5, 18, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 32, }, + { 2, 0, 0, 3, 6, 18, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 32, }, + { 2, 0, 0, 3, 7, 18, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 18, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 18, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 28, }, + { 2, 0, 0, 3, 10, 18, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 18, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 20, }, + { 2, 0, 0, 3, 12, 18, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 14, }, + { 2, 0, 0, 3, 13, 18, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 20, }, + { 2, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 14, }, + { 2, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 18, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 24, }, + { 2, 0, 1, 3, 4, 18, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 26, }, + { 2, 0, 1, 3, 5, 18, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 28, }, + { 2, 0, 1, 3, 6, 18, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 26, }, + { 2, 0, 1, 3, 7, 18, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 26, }, + { 2, 0, 1, 3, 8, 18, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 26, }, + { 2, 0, 1, 3, 9, 18, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 20, }, + { 2, 0, 1, 3, 10, 18, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 14, }, + { 2, 0, 1, 3, 11, 18, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 63, }, + { 1, 0, 1, 3, 12, 63, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 63, }, + { 1, 0, 1, 3, 13, 63, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 30, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 30, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 30, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 30, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 28, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 28, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 28, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 28, }, + { 0, 1, 0, 1, 100, 26, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 28, }, + { 2, 1, 0, 1, 144, 32, }, + { 1, 1, 0, 1, 144, 63, }, + { 0, 1, 0, 1, 149, 32, }, + { 2, 1, 0, 1, 149, 63, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 63, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 63, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 63, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 63, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 28, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 28, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 28, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 28, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 28, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 28, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 28, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 28, }, + { 0, 1, 0, 2, 100, 26, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 26, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 26, }, + { 2, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 63, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 63, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 63, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 63, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 63, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 20, }, + { 1, 1, 0, 3, 36, 22, }, + { 0, 1, 0, 3, 40, 30, }, + { 2, 1, 0, 3, 40, 20, }, + { 1, 1, 0, 3, 40, 22, }, + { 0, 1, 0, 3, 44, 30, }, + { 2, 1, 0, 3, 44, 20, }, + { 1, 1, 0, 3, 44, 22, }, + { 0, 1, 0, 3, 48, 30, }, + { 2, 1, 0, 3, 48, 20, }, + { 1, 1, 0, 3, 48, 22, }, + { 0, 1, 0, 3, 52, 30, }, + { 2, 1, 0, 3, 52, 20, }, + { 1, 1, 0, 3, 52, 22, }, + { 0, 1, 0, 3, 56, 30, }, + { 2, 1, 0, 3, 56, 20, }, + { 1, 1, 0, 3, 56, 22, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 20, }, + { 1, 1, 0, 3, 60, 22, }, + { 0, 1, 0, 3, 64, 28, }, + { 2, 1, 0, 3, 64, 20, }, + { 1, 1, 0, 3, 64, 22, }, + { 0, 1, 0, 3, 100, 26, }, + { 2, 1, 0, 3, 100, 20, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 30, }, + { 2, 1, 0, 3, 104, 20, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 32, }, + { 2, 1, 0, 3, 108, 20, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 20, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 20, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 32, }, + { 2, 1, 0, 3, 120, 20, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 20, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 32, }, + { 2, 1, 0, 3, 128, 20, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 32, }, + { 2, 1, 0, 3, 132, 20, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 30, }, + { 2, 1, 0, 3, 136, 20, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 20, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 144, 26, }, + { 2, 1, 0, 3, 144, 63, }, + { 1, 1, 0, 3, 144, 63, }, + { 0, 1, 0, 3, 149, 32, }, + { 2, 1, 0, 3, 149, 63, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 32, }, + { 2, 1, 0, 3, 153, 63, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 32, }, + { 2, 1, 0, 3, 157, 63, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 32, }, + { 2, 1, 0, 3, 161, 63, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 32, }, + { 2, 1, 0, 3, 165, 63, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 22, }, + { 2, 1, 1, 2, 38, 30, }, + { 1, 1, 1, 2, 38, 30, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 30, }, + { 1, 1, 1, 2, 46, 30, }, + { 0, 1, 1, 2, 54, 30, }, + { 2, 1, 1, 2, 54, 30, }, + { 1, 1, 1, 2, 54, 30, }, + { 0, 1, 1, 2, 62, 24, }, + { 2, 1, 1, 2, 62, 30, }, + { 1, 1, 1, 2, 62, 30, }, + { 0, 1, 1, 2, 102, 24, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 30, }, + { 2, 1, 1, 2, 110, 30, }, + { 1, 1, 1, 2, 110, 30, }, + { 0, 1, 1, 2, 118, 30, }, + { 2, 1, 1, 2, 118, 30, }, + { 1, 1, 1, 2, 118, 30, }, + { 0, 1, 1, 2, 126, 30, }, + { 2, 1, 1, 2, 126, 30, }, + { 1, 1, 1, 2, 126, 30, }, + { 0, 1, 1, 2, 134, 30, }, + { 2, 1, 1, 2, 134, 30, }, + { 1, 1, 1, 2, 134, 30, }, + { 0, 1, 1, 2, 142, 30, }, + { 2, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 0, 1, 1, 2, 151, 30, }, + { 2, 1, 1, 2, 151, 63, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 30, }, + { 2, 1, 1, 2, 159, 63, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 20, }, + { 2, 1, 1, 3, 38, 20, }, + { 1, 1, 1, 3, 38, 22, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 20, }, + { 1, 1, 1, 3, 46, 22, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 20, }, + { 1, 1, 1, 3, 54, 22, }, + { 0, 1, 1, 3, 62, 22, }, + { 2, 1, 1, 3, 62, 20, }, + { 1, 1, 1, 3, 62, 22, }, + { 0, 1, 1, 3, 102, 22, }, + { 2, 1, 1, 3, 102, 20, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 20, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 30, }, + { 2, 1, 1, 3, 118, 20, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 30, }, + { 2, 1, 1, 3, 126, 20, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 20, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 142, 30, }, + { 2, 1, 1, 3, 142, 63, }, + { 1, 1, 1, 3, 142, 63, }, + { 0, 1, 1, 3, 151, 30, }, + { 2, 1, 1, 3, 151, 63, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 63, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 20, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 28, }, + { 0, 1, 2, 4, 58, 20, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 28, }, + { 0, 1, 2, 4, 106, 20, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 30, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 138, 30, }, + { 2, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 138, 63, }, + { 0, 1, 2, 4, 155, 30, }, + { 2, 1, 2, 4, 155, 63, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 18, }, + { 2, 1, 2, 5, 42, 20, }, + { 1, 1, 2, 5, 42, 22, }, + { 0, 1, 2, 5, 58, 18, }, + { 2, 1, 2, 5, 58, 20, }, + { 1, 1, 2, 5, 58, 22, }, + { 0, 1, 2, 5, 106, 20, }, + { 2, 1, 2, 5, 106, 20, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 30, }, + { 2, 1, 2, 5, 122, 20, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 138, 30, }, + { 2, 1, 2, 5, 138, 63, }, + { 1, 1, 2, 5, 138, 63, }, + { 0, 1, 2, 5, 155, 30, }, + { 2, 1, 2, 5, 155, 63, }, + { 1, 1, 2, 5, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822b_txpwr_lmt_type0); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8822b_txpwr_lmt_type2[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 28, }, + { 1, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 28, }, + { 1, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 28, }, + { 1, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 28, }, + { 1, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 28, }, + { 1, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 28, }, + { 1, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 28, }, + { 1, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 28, }, + { 1, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 28, }, + { 1, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 28, }, + { 1, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 28, }, + { 1, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 26, }, + { 2, 0, 0, 0, 12, 28, }, + { 1, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 20, }, + { 2, 0, 0, 0, 13, 28, }, + { 1, 0, 0, 0, 13, 28, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 26, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 34, }, + { 0, 0, 0, 1, 2, 30, }, + { 2, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 0, 0, 0, 1, 10, 30, }, + { 2, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 0, 0, 0, 1, 12, 22, }, + { 2, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 0, 0, 0, 1, 13, 14, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 1, 34, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 0, 0, 0, 2, 12, 20, }, + { 2, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 0, 0, 0, 2, 13, 14, }, + { 2, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 18, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 28, }, + { 2, 0, 0, 3, 2, 18, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 18, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 18, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 32, }, + { 2, 0, 0, 3, 5, 18, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 32, }, + { 2, 0, 0, 3, 6, 18, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 32, }, + { 2, 0, 0, 3, 7, 18, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 18, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 18, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 28, }, + { 2, 0, 0, 3, 10, 18, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 18, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 20, }, + { 2, 0, 0, 3, 12, 18, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 14, }, + { 2, 0, 0, 3, 13, 18, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 20, }, + { 2, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 14, }, + { 2, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 18, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 24, }, + { 2, 0, 1, 3, 4, 18, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 26, }, + { 2, 0, 1, 3, 5, 18, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 28, }, + { 2, 0, 1, 3, 6, 18, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 26, }, + { 2, 0, 1, 3, 7, 18, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 26, }, + { 2, 0, 1, 3, 8, 18, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 26, }, + { 2, 0, 1, 3, 9, 18, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 20, }, + { 2, 0, 1, 3, 10, 18, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 14, }, + { 2, 0, 1, 3, 11, 18, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 63, }, + { 1, 0, 1, 3, 12, 63, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 63, }, + { 1, 0, 1, 3, 13, 63, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 36, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 30, }, + { 0, 1, 0, 1, 40, 38, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 30, }, + { 0, 1, 0, 1, 44, 38, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 30, }, + { 0, 1, 0, 1, 48, 38, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 30, }, + { 0, 1, 0, 1, 52, 38, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 28, }, + { 0, 1, 0, 1, 56, 38, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 28, }, + { 0, 1, 0, 1, 60, 38, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 28, }, + { 0, 1, 0, 1, 64, 34, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 28, }, + { 0, 1, 0, 1, 100, 32, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 38, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 38, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 38, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 38, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 38, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 38, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 38, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 38, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 38, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 34, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 34, }, + { 2, 1, 0, 1, 144, 32, }, + { 1, 1, 0, 1, 144, 63, }, + { 0, 1, 0, 1, 149, 38, }, + { 2, 1, 0, 1, 149, 63, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 38, }, + { 2, 1, 0, 1, 153, 63, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 38, }, + { 2, 1, 0, 1, 157, 63, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 38, }, + { 2, 1, 0, 1, 161, 63, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 38, }, + { 2, 1, 0, 1, 165, 63, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 36, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 28, }, + { 0, 1, 0, 2, 40, 38, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 28, }, + { 0, 1, 0, 2, 44, 38, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 28, }, + { 0, 1, 0, 2, 48, 38, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 28, }, + { 0, 1, 0, 2, 52, 38, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 28, }, + { 0, 1, 0, 2, 56, 38, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 28, }, + { 0, 1, 0, 2, 60, 38, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 28, }, + { 0, 1, 0, 2, 64, 34, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 28, }, + { 0, 1, 0, 2, 100, 32, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 38, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 38, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 38, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 38, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 38, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 38, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 38, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 38, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 38, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 32, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 26, }, + { 2, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 0, 1, 0, 2, 149, 38, }, + { 2, 1, 0, 2, 149, 63, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 38, }, + { 2, 1, 0, 2, 153, 63, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 38, }, + { 2, 1, 0, 2, 157, 63, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 38, }, + { 2, 1, 0, 2, 161, 63, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 38, }, + { 2, 1, 0, 2, 165, 63, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 34, }, + { 2, 1, 0, 3, 36, 20, }, + { 1, 1, 0, 3, 36, 22, }, + { 0, 1, 0, 3, 40, 36, }, + { 2, 1, 0, 3, 40, 20, }, + { 1, 1, 0, 3, 40, 22, }, + { 0, 1, 0, 3, 44, 36, }, + { 2, 1, 0, 3, 44, 20, }, + { 1, 1, 0, 3, 44, 22, }, + { 0, 1, 0, 3, 48, 36, }, + { 2, 1, 0, 3, 48, 20, }, + { 1, 1, 0, 3, 48, 22, }, + { 0, 1, 0, 3, 52, 36, }, + { 2, 1, 0, 3, 52, 20, }, + { 1, 1, 0, 3, 52, 22, }, + { 0, 1, 0, 3, 56, 36, }, + { 2, 1, 0, 3, 56, 20, }, + { 1, 1, 0, 3, 56, 22, }, + { 0, 1, 0, 3, 60, 36, }, + { 2, 1, 0, 3, 60, 20, }, + { 1, 1, 0, 3, 60, 22, }, + { 0, 1, 0, 3, 64, 34, }, + { 2, 1, 0, 3, 64, 20, }, + { 1, 1, 0, 3, 64, 22, }, + { 0, 1, 0, 3, 100, 32, }, + { 2, 1, 0, 3, 100, 20, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 36, }, + { 2, 1, 0, 3, 104, 20, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 38, }, + { 2, 1, 0, 3, 108, 20, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 38, }, + { 2, 1, 0, 3, 112, 20, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 38, }, + { 2, 1, 0, 3, 116, 20, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 38, }, + { 2, 1, 0, 3, 120, 20, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 38, }, + { 2, 1, 0, 3, 124, 20, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 38, }, + { 2, 1, 0, 3, 128, 20, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 38, }, + { 2, 1, 0, 3, 132, 20, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 36, }, + { 2, 1, 0, 3, 136, 20, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 32, }, + { 2, 1, 0, 3, 140, 20, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 144, 26, }, + { 2, 1, 0, 3, 144, 63, }, + { 1, 1, 0, 3, 144, 63, }, + { 0, 1, 0, 3, 149, 38, }, + { 2, 1, 0, 3, 149, 63, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 38, }, + { 2, 1, 0, 3, 153, 63, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 38, }, + { 2, 1, 0, 3, 157, 63, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 38, }, + { 2, 1, 0, 3, 161, 63, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 38, }, + { 2, 1, 0, 3, 165, 63, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 28, }, + { 2, 1, 1, 2, 38, 30, }, + { 1, 1, 1, 2, 38, 30, }, + { 0, 1, 1, 2, 46, 36, }, + { 2, 1, 1, 2, 46, 30, }, + { 1, 1, 1, 2, 46, 30, }, + { 0, 1, 1, 2, 54, 36, }, + { 2, 1, 1, 2, 54, 30, }, + { 1, 1, 1, 2, 54, 30, }, + { 0, 1, 1, 2, 62, 30, }, + { 2, 1, 1, 2, 62, 30, }, + { 1, 1, 1, 2, 62, 30, }, + { 0, 1, 1, 2, 102, 30, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 36, }, + { 2, 1, 1, 2, 110, 30, }, + { 1, 1, 1, 2, 110, 30, }, + { 0, 1, 1, 2, 118, 36, }, + { 2, 1, 1, 2, 118, 30, }, + { 1, 1, 1, 2, 118, 30, }, + { 0, 1, 1, 2, 126, 36, }, + { 2, 1, 1, 2, 126, 30, }, + { 1, 1, 1, 2, 126, 30, }, + { 0, 1, 1, 2, 134, 36, }, + { 2, 1, 1, 2, 134, 30, }, + { 1, 1, 1, 2, 134, 30, }, + { 0, 1, 1, 2, 142, 30, }, + { 2, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 63, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 36, }, + { 2, 1, 1, 2, 159, 63, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 26, }, + { 2, 1, 1, 3, 38, 20, }, + { 1, 1, 1, 3, 38, 22, }, + { 0, 1, 1, 3, 46, 36, }, + { 2, 1, 1, 3, 46, 20, }, + { 1, 1, 1, 3, 46, 22, }, + { 0, 1, 1, 3, 54, 36, }, + { 2, 1, 1, 3, 54, 20, }, + { 1, 1, 1, 3, 54, 22, }, + { 0, 1, 1, 3, 62, 28, }, + { 2, 1, 1, 3, 62, 20, }, + { 1, 1, 1, 3, 62, 22, }, + { 0, 1, 1, 3, 102, 28, }, + { 2, 1, 1, 3, 102, 20, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 36, }, + { 2, 1, 1, 3, 110, 20, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 36, }, + { 2, 1, 1, 3, 118, 20, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 36, }, + { 2, 1, 1, 3, 126, 20, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 36, }, + { 2, 1, 1, 3, 134, 20, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 142, 30, }, + { 2, 1, 1, 3, 142, 63, }, + { 1, 1, 1, 3, 142, 63, }, + { 0, 1, 1, 3, 151, 36, }, + { 2, 1, 1, 3, 151, 63, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 36, }, + { 2, 1, 1, 3, 159, 63, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 26, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 28, }, + { 0, 1, 2, 4, 58, 26, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 28, }, + { 0, 1, 2, 4, 106, 26, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 36, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 138, 36, }, + { 2, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 138, 63, }, + { 0, 1, 2, 4, 155, 36, }, + { 2, 1, 2, 4, 155, 63, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 24, }, + { 2, 1, 2, 5, 42, 20, }, + { 1, 1, 2, 5, 42, 22, }, + { 0, 1, 2, 5, 58, 24, }, + { 2, 1, 2, 5, 58, 20, }, + { 1, 1, 2, 5, 58, 22, }, + { 0, 1, 2, 5, 106, 26, }, + { 2, 1, 2, 5, 106, 20, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 36, }, + { 2, 1, 2, 5, 122, 20, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 138, 36, }, + { 2, 1, 2, 5, 138, 63, }, + { 1, 1, 2, 5, 138, 63, }, + { 0, 1, 2, 5, 155, 36, }, + { 2, 1, 2, 5, 155, 63, }, + { 1, 1, 2, 5, 155, 63 }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822b_txpwr_lmt_type2); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8822b_txpwr_lmt_type5[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 28, }, + { 1, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 28, }, + { 1, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 28, }, + { 1, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 28, }, + { 1, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 28, }, + { 1, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 28, }, + { 1, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 28, }, + { 1, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 28, }, + { 1, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 28, }, + { 1, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 28, }, + { 1, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 28, }, + { 1, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 26, }, + { 2, 0, 0, 0, 12, 28, }, + { 1, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 20, }, + { 2, 0, 0, 0, 13, 28, }, + { 1, 0, 0, 0, 13, 28, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 26, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 34, }, + { 0, 0, 0, 1, 2, 30, }, + { 2, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 0, 0, 0, 1, 10, 30, }, + { 2, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 0, 0, 0, 1, 12, 22, }, + { 2, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 0, 0, 0, 1, 13, 14, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 1, 34, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 0, 0, 0, 2, 12, 20, }, + { 2, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 0, 0, 0, 2, 13, 14, }, + { 2, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 18, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 28, }, + { 2, 0, 0, 3, 2, 18, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 18, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 18, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 32, }, + { 2, 0, 0, 3, 5, 18, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 32, }, + { 2, 0, 0, 3, 6, 18, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 32, }, + { 2, 0, 0, 3, 7, 18, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 18, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 18, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 28, }, + { 2, 0, 0, 3, 10, 18, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 18, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 20, }, + { 2, 0, 0, 3, 12, 18, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 14, }, + { 2, 0, 0, 3, 13, 18, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 20, }, + { 2, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 14, }, + { 2, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 18, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 24, }, + { 2, 0, 1, 3, 4, 18, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 26, }, + { 2, 0, 1, 3, 5, 18, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 28, }, + { 2, 0, 1, 3, 6, 18, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 26, }, + { 2, 0, 1, 3, 7, 18, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 26, }, + { 2, 0, 1, 3, 8, 18, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 26, }, + { 2, 0, 1, 3, 9, 18, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 20, }, + { 2, 0, 1, 3, 10, 18, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 14, }, + { 2, 0, 1, 3, 11, 18, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 63, }, + { 1, 0, 1, 3, 12, 63, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 63, }, + { 1, 0, 1, 3, 13, 63, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 30, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 30, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 30, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 30, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 28, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 28, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 28, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 28, }, + { 0, 1, 0, 1, 100, 26, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 28, }, + { 2, 1, 0, 1, 144, 63, }, + { 1, 1, 0, 1, 144, 63, }, + { 0, 1, 0, 1, 149, 32, }, + { 2, 1, 0, 1, 149, 63, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 63, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 63, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 63, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 63, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 28, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 28, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 28, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 28, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 28, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 28, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 28, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 28, }, + { 0, 1, 0, 2, 100, 26, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 26, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 26, }, + { 2, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 63, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 63, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 63, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 63, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 63, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 20, }, + { 1, 1, 0, 3, 36, 22, }, + { 0, 1, 0, 3, 40, 30, }, + { 2, 1, 0, 3, 40, 20, }, + { 1, 1, 0, 3, 40, 22, }, + { 0, 1, 0, 3, 44, 30, }, + { 2, 1, 0, 3, 44, 20, }, + { 1, 1, 0, 3, 44, 22, }, + { 0, 1, 0, 3, 48, 30, }, + { 2, 1, 0, 3, 48, 20, }, + { 1, 1, 0, 3, 48, 22, }, + { 0, 1, 0, 3, 52, 30, }, + { 2, 1, 0, 3, 52, 20, }, + { 1, 1, 0, 3, 52, 22, }, + { 0, 1, 0, 3, 56, 30, }, + { 2, 1, 0, 3, 56, 20, }, + { 1, 1, 0, 3, 56, 22, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 20, }, + { 1, 1, 0, 3, 60, 22, }, + { 0, 1, 0, 3, 64, 28, }, + { 2, 1, 0, 3, 64, 20, }, + { 1, 1, 0, 3, 64, 22, }, + { 0, 1, 0, 3, 100, 26, }, + { 2, 1, 0, 3, 100, 20, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 30, }, + { 2, 1, 0, 3, 104, 20, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 32, }, + { 2, 1, 0, 3, 108, 20, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 20, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 20, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 32, }, + { 2, 1, 0, 3, 120, 20, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 20, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 32, }, + { 2, 1, 0, 3, 128, 20, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 32, }, + { 2, 1, 0, 3, 132, 20, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 30, }, + { 2, 1, 0, 3, 136, 20, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 20, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 144, 26, }, + { 2, 1, 0, 3, 144, 63, }, + { 1, 1, 0, 3, 144, 63, }, + { 0, 1, 0, 3, 149, 32, }, + { 2, 1, 0, 3, 149, 63, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 32, }, + { 2, 1, 0, 3, 153, 63, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 32, }, + { 2, 1, 0, 3, 157, 63, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 32, }, + { 2, 1, 0, 3, 161, 63, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 32, }, + { 2, 1, 0, 3, 165, 63, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 22, }, + { 2, 1, 1, 2, 38, 30, }, + { 1, 1, 1, 2, 38, 30, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 30, }, + { 1, 1, 1, 2, 46, 30, }, + { 0, 1, 1, 2, 54, 30, }, + { 2, 1, 1, 2, 54, 30, }, + { 1, 1, 1, 2, 54, 30, }, + { 0, 1, 1, 2, 62, 24, }, + { 2, 1, 1, 2, 62, 30, }, + { 1, 1, 1, 2, 62, 30, }, + { 0, 1, 1, 2, 102, 24, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 30, }, + { 2, 1, 1, 2, 110, 30, }, + { 1, 1, 1, 2, 110, 30, }, + { 0, 1, 1, 2, 118, 30, }, + { 2, 1, 1, 2, 118, 30, }, + { 1, 1, 1, 2, 118, 30, }, + { 0, 1, 1, 2, 126, 30, }, + { 2, 1, 1, 2, 126, 30, }, + { 1, 1, 1, 2, 126, 30, }, + { 0, 1, 1, 2, 134, 30, }, + { 2, 1, 1, 2, 134, 30, }, + { 1, 1, 1, 2, 134, 30, }, + { 0, 1, 1, 2, 142, 30, }, + { 2, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 0, 1, 1, 2, 151, 30, }, + { 2, 1, 1, 2, 151, 63, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 30, }, + { 2, 1, 1, 2, 159, 63, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 20, }, + { 2, 1, 1, 3, 38, 20, }, + { 1, 1, 1, 3, 38, 22, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 20, }, + { 1, 1, 1, 3, 46, 22, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 20, }, + { 1, 1, 1, 3, 54, 22, }, + { 0, 1, 1, 3, 62, 22, }, + { 2, 1, 1, 3, 62, 20, }, + { 1, 1, 1, 3, 62, 22, }, + { 0, 1, 1, 3, 102, 22, }, + { 2, 1, 1, 3, 102, 20, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 20, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 30, }, + { 2, 1, 1, 3, 118, 20, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 30, }, + { 2, 1, 1, 3, 126, 20, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 20, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 142, 30, }, + { 2, 1, 1, 3, 142, 63, }, + { 1, 1, 1, 3, 142, 63, }, + { 0, 1, 1, 3, 151, 30, }, + { 2, 1, 1, 3, 151, 63, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 63, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 20, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 28, }, + { 0, 1, 2, 4, 58, 20, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 28, }, + { 0, 1, 2, 4, 106, 20, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 30, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 138, 30, }, + { 2, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 138, 63, }, + { 0, 1, 2, 4, 155, 30, }, + { 2, 1, 2, 4, 155, 63, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 18, }, + { 2, 1, 2, 5, 42, 20, }, + { 1, 1, 2, 5, 42, 22, }, + { 0, 1, 2, 5, 58, 18, }, + { 2, 1, 2, 5, 58, 20, }, + { 1, 1, 2, 5, 58, 22, }, + { 0, 1, 2, 5, 106, 20, }, + { 2, 1, 2, 5, 106, 20, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 30, }, + { 2, 1, 2, 5, 122, 20, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 138, 30, }, + { 2, 1, 2, 5, 138, 63, }, + { 1, 1, 2, 5, 138, 63, }, + { 0, 1, 2, 5, 155, 30, }, + { 2, 1, 2, 5, 155, 63, }, + { 1, 1, 2, 5, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822b_txpwr_lmt_type5); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b_table.h b/drivers/net/wireless/realtek/rtw88/rtw8822b_table.h new file mode 100644 index 000000000..4140e1ccb --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b_table.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8822B_TABLE_H__ +#define __RTW8822B_TABLE_H__ + +extern const struct rtw_table rtw8822b_mac_tbl; +extern const struct rtw_table rtw8822b_agc_tbl; +extern const struct rtw_table rtw8822b_bb_tbl; +extern const struct rtw_table rtw8822b_bb_pg_type2_tbl; +extern const struct rtw_table rtw8822b_bb_pg_type3_tbl; +extern const struct rtw_table rtw8822b_bb_pg_type5_tbl; +extern const struct rtw_table rtw8822b_rf_a_tbl; +extern const struct rtw_table rtw8822b_rf_b_tbl; +extern const struct rtw_table rtw8822b_txpwr_lmt_type0_tbl; +extern const struct rtw_table rtw8822b_txpwr_lmt_type2_tbl; +extern const struct rtw_table rtw8822b_txpwr_lmt_type5_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822be.c b/drivers/net/wireless/realtek/rtw88/rtw8822be.c new file mode 100644 index 000000000..dda597d73 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822be.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8822b.h" + +static const struct pci_device_id rtw_8822be_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822), + .driver_data = (kernel_ulong_t)&rtw8822b_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8822be_id_table); + +static struct pci_driver rtw_8822be_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8822be_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, +}; +module_pci_driver(rtw_8822be_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822be driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822bs.c b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c new file mode 100644 index 000000000..2de9b1154 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Jernej Skrabec + */ + +#include +#include +#include +#include "main.h" +#include "rtw8822b.h" +#include "sdio.h" + +static const struct sdio_device_id rtw_8822bs_id_table[] = { + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8822BS), + .driver_data = (kernel_ulong_t)&rtw8822b_hw_spec, + }, + {} +}; +MODULE_DEVICE_TABLE(sdio, rtw_8822bs_id_table); + +static struct sdio_driver rtw_8822bs_driver = { + .name = KBUILD_MODNAME, + .probe = rtw_sdio_probe, + .remove = rtw_sdio_remove, + .shutdown = rtw_sdio_shutdown, + .id_table = rtw_8822bs_id_table, + .drv = { + .pm = &rtw_sdio_pm_ops, + } +}; +module_sdio_driver(rtw_8822bs_driver); + +MODULE_AUTHOR("Jernej Skrabec "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bs driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822bu.c b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c new file mode 100644 index 000000000..2769b86ce --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8822b.h" +#include "usb.h" + +static const struct usb_device_id rtw_8822bu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ + {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */ + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */ + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ + { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x010a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30N */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d1, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U2-866DM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d0, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U3-866DHP */ + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); + +static int rtw8822bu_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtw_usb_probe(intf, id); +} + +static struct usb_driver rtw_8822bu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8822bu_id_table, + .probe = rtw8822bu_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8822bu_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c new file mode 100644 index 000000000..32d9709f2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -0,0 +1,5451 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8822c.h" +#include "rtw8822c_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" +#include "util.h" +#include "bf.h" +#include "efuse.h" + +#define IQK_DONE_8822C 0xaa + +static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path); + +static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->u.mac_addr); +} + +static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8822c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->s.mac_addr); +} + +static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8822c_efuse *map; + int i; + + map = (struct rtw8822c_efuse *)log_map; + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k & XCAP_MASK; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal; + efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal; + efuse->thermal_meter_k = + (map->path_a_thermal + map->path_b_thermal) >> 1; + efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8822ce_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_USB: + rtw8822cu_efuse_parsing(efuse, map); + break; + case RTW_HCI_TYPE_SDIO: + rtw8822cs_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -ENOTSUPP; + } + + return 0; +} + +static void rtw8822c_header_file_init(struct rtw_dev *rtwdev, bool pre) +{ + rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); + rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_PI_ON); + rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); + rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_PI_ON); + + if (pre) + rtw_write32_clr(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); + else + rtw_write32_set(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); +} + +static void rtw8822c_bb_reset(struct rtw_dev *rtwdev) +{ + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); + rtw_write16_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); +} + +static void rtw8822c_dac_backup_reg(struct rtw_dev *rtwdev, + struct rtw_backup_info *backup, + struct rtw_backup_info *backup_rf) +{ + u32 path, i; + u32 val; + u32 reg; + u32 rf_addr[DACK_RF_8822C] = {0x8f}; + u32 addrs[DACK_REG_8822C] = {0x180c, 0x1810, 0x410c, 0x4110, + 0x1c3c, 0x1c24, 0x1d70, 0x9b4, + 0x1a00, 0x1a14, 0x1d58, 0x1c38, + 0x1e24, 0x1e28, 0x1860, 0x4160}; + + for (i = 0; i < DACK_REG_8822C; i++) { + backup[i].len = 4; + backup[i].reg = addrs[i]; + backup[i].val = rtw_read32(rtwdev, addrs[i]); + } + + for (path = 0; path < DACK_PATH_8822C; path++) { + for (i = 0; i < DACK_RF_8822C; i++) { + reg = rf_addr[i]; + val = rtw_read_rf(rtwdev, path, reg, RFREG_MASK); + backup_rf[path * i + i].reg = reg; + backup_rf[path * i + i].val = val; + } + } +} + +static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev, + struct rtw_backup_info *backup, + struct rtw_backup_info *backup_rf) +{ + u32 path, i; + u32 val; + u32 reg; + + rtw_restore_reg(rtwdev, backup, DACK_REG_8822C); + + for (path = 0; path < DACK_PATH_8822C; path++) { + for (i = 0; i < DACK_RF_8822C; i++) { + val = backup_rf[path * i + i].val; + reg = backup_rf[path * i + i].reg; + rtw_write_rf(rtwdev, path, reg, RFREG_MASK, val); + } + } +} + +static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value, + u32 *min, u32 *max) +{ + if (value >= 0x200) { + if (*min >= 0x200) { + if (*min > value) + *min = value; + } else { + *min = value; + } + if (*max >= 0x200) { + if (*max < value) + *max = value; + } + } else { + if (*min < 0x200) { + if (*min > value) + *min = value; + } + + if (*max >= 0x200) { + *max = value; + } else { + if (*max < value) + *max = value; + } + } +} + +static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2) +{ + if (*v1 >= 0x200 && *v2 >= 0x200) { + if (*v1 > *v2) + swap(*v1, *v2); + } else if (*v1 < 0x200 && *v2 < 0x200) { + if (*v1 > *v2) + swap(*v1, *v2); + } else if (*v1 < 0x200 && *v2 >= 0x200) { + swap(*v1, *v2); + } +} + +static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) +{ + u32 i, j; + + for (i = 0; i < DACK_SN_8822C - 1; i++) { + for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) { + __rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]); + __rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]); + } + } +} + +static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val) +{ + u32 p, m, t, i; + + m = 0; + p = 0; + for (i = 10; i < DACK_SN_8822C - 10; i++) { + if (vec[i] > 0x200) + m = (0x400 - vec[i]) + m; + else + p = vec[i] + p; + } + + if (p > m) { + t = p - m; + t = t / (DACK_SN_8822C - 20); + } else { + t = m - p; + t = t / (DACK_SN_8822C - 20); + if (t != 0x0) + t = 0x400 - t; + } + + *val = t; +} + +static u32 rtw8822c_get_path_write_addr(u8 path) +{ + u32 base_addr; + + switch (path) { + case RF_PATH_A: + base_addr = 0x1800; + break; + case RF_PATH_B: + base_addr = 0x4100; + break; + default: + WARN_ON(1); + return -1; + } + + return base_addr; +} + +static u32 rtw8822c_get_path_read_addr(u8 path) +{ + u32 base_addr; + + switch (path) { + case RF_PATH_A: + base_addr = 0x2800; + break; + case RF_PATH_B: + base_addr = 0x4500; + break; + default: + WARN_ON(1); + return -1; + } + + return base_addr; +} + +static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value) +{ + bool ret = true; + + if ((value >= 0x200 && (0x400 - value) > 0x64) || + (value < 0x200 && value > 0x64)) { + ret = false; + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n"); + } + + return ret; +} + +static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) +{ + u32 temp; + int i = 0, cnt = 0; + + while (i < DACK_SN_8822C && cnt < 10000) { + cnt++; + temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); + iv[i] = (temp & 0x3ff000) >> 12; + qv[i] = temp & 0x3ff; + + if (rtw8822c_dac_iq_check(rtwdev, iv[i]) && + rtw8822c_dac_iq_check(rtwdev, qv[i])) + i++; + } +} + +static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev, + u32 *iv, u32 *qv, + u32 *i_value, u32 *q_value) +{ + u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0; + u32 i_delta, q_delta; + u32 temp; + int i, cnt = 0; + + do { + i_min = iv[0]; + i_max = iv[0]; + q_min = qv[0]; + q_max = qv[0]; + for (i = 0; i < DACK_SN_8822C; i++) { + rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max); + rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max); + } + + if (i_max < 0x200 && i_min < 0x200) + i_delta = i_max - i_min; + else if (i_max >= 0x200 && i_min >= 0x200) + i_delta = i_max - i_min; + else + i_delta = i_max + (0x400 - i_min); + + if (q_max < 0x200 && q_min < 0x200) + q_delta = q_max - q_min; + else if (q_max >= 0x200 && q_min >= 0x200) + q_delta = q_max - q_min; + else + q_delta = q_max + (0x400 - q_min); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n", + i_min, i_max, i_delta); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DACK] q: min=0x%08x, max=0x%08x, delta=0x%08x\n", + q_min, q_max, q_delta); + + rtw8822c_dac_iq_sort(rtwdev, iv, qv); + + if (i_delta > 5 || q_delta > 5) { + temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); + iv[0] = (temp & 0x3ff000) >> 12; + qv[0] = temp & 0x3ff; + temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); + iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12; + qv[DACK_SN_8822C - 1] = temp & 0x3ff; + } else { + break; + } + } while (cnt++ < 100); + + rtw8822c_dac_iq_offset(rtwdev, iv, i_value); + rtw8822c_dac_iq_offset(rtwdev, qv, q_value); +} + +static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev, + u32 *i_value, u32 *q_value) +{ + u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C]; + u32 rf_a, rf_b; + + rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK); + rf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-A=0x%05x\n", rf_a); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-B=0x%05x\n", rf_b); + + rtw8822c_dac_cal_iq_sample(rtwdev, iv, qv); + rtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value); +} + +static void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, 0x1d58, 0xff8, 0x1ff); + rtw_write32_mask(rtwdev, 0x1a00, 0x3, 0x2); + rtw_write32_mask(rtwdev, 0x1a14, 0x300, 0x3); + rtw_write32(rtwdev, 0x1d70, 0x7e7e7e7e); + rtw_write32_mask(rtwdev, 0x180c, 0x3, 0x0); + rtw_write32_mask(rtwdev, 0x410c, 0x3, 0x0); + rtw_write32(rtwdev, 0x1b00, 0x00000008); + rtw_write8(rtwdev, 0x1bcc, 0x3f); + rtw_write32(rtwdev, 0x1b00, 0x0000000a); + rtw_write8(rtwdev, 0x1bcc, 0x3f); + rtw_write32_mask(rtwdev, 0x1e24, BIT(31), 0x0); + rtw_write32_mask(rtwdev, 0x1e28, 0xf, 0x3); +} + +static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, + u8 path, u32 *adc_ic, u32 *adc_qc) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 ic = 0, qc = 0, temp = 0; + u32 base_addr; + u32 path_sel; + int i; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK path(%d)\n", path); + + base_addr = rtw8822c_get_path_write_addr(path); + switch (path) { + case RF_PATH_A: + path_sel = 0xa0000; + break; + case RF_PATH_B: + path_sel = 0x80000; + break; + default: + WARN_ON(1); + return; + } + + /* ADCK step1 */ + rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x0); + if (path == RF_PATH_B) + rtw_write32(rtwdev, base_addr + 0x30, 0x30db8041); + rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); + rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); + rtw_write32(rtwdev, base_addr + 0x10, 0x02dd08c4); + rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); + rtw_write_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK, 0x10000); + rtw_write_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK, 0x10000); + for (i = 0; i < 10; i++) { + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK count=%d\n", i); + rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8003); + rtw_write32(rtwdev, 0x1c24, 0x00010002); + rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DACK] before: i=0x%x, q=0x%x\n", ic, qc); + + /* compensation value */ + if (ic != 0x0) { + ic = 0x400 - ic; + *adc_ic = ic; + } + if (qc != 0x0) { + qc = 0x400 - qc; + *adc_qc = qc; + } + temp = (ic & 0x3ff) | ((qc & 0x3ff) << 10); + rtw_write32(rtwdev, base_addr + 0x68, temp); + dm_info->dack_adck[path] = temp; + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK 0x%08x=0x08%x\n", + base_addr + 0x68, temp); + /* check ADC DC offset */ + rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103); + rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DACK] after: i=0x%08x, q=0x%08x\n", ic, qc); + if (ic >= 0x200) + ic = 0x400 - ic; + if (qc >= 0x200) + qc = 0x400 - qc; + if (ic < 5 && qc < 5) + break; + } + + /* ADCK step2 */ + rtw_write32(rtwdev, 0x1c3c, 0x00000003); + rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); + + /* release pull low switch on IQ path */ + rtw_write_rf(rtwdev, path, 0x8f, BIT(13), 0x1); +} + +static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 base_addr; + u32 read_addr; + + base_addr = rtw8822c_get_path_write_addr(path); + read_addr = rtw8822c_get_path_read_addr(path); + + rtw_write32(rtwdev, base_addr + 0x68, dm_info->dack_adck[path]); + rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); + if (path == RF_PATH_A) { + rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); + rtw_write32(rtwdev, 0x1c38, 0xffffffff); + } + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); + rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff81); + rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); + rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); + rtw_write32(rtwdev, base_addr + 0xd8, 0x0008ff81); + rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); + rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); + mdelay(2); + rtw_write32(rtwdev, base_addr + 0xbc, 0x000aff8d); + mdelay(2); + rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); + rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); + mdelay(1); + rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); + rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); + mdelay(20); + if (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff)) + rtw_err(rtwdev, "failed to wait for dack ready\n"); + rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); + mdelay(1); + rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); + rtw_write32(rtwdev, 0x9b4, 0xdb6db600); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); + rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); + rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); +} + +static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev, + u8 path, u32 *ic_out, u32 *qc_out) +{ + u32 base_addr; + u32 ic, qc, ic_in, qc_in; + + base_addr = rtw8822c_get_path_write_addr(path); + rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0); + rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, 0x8); + rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, 0x0); + rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, 0x8); + + rtw_write32(rtwdev, 0x1b00, 0x00000008); + rtw_write8(rtwdev, 0x1bcc, 0x03f); + rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); + rtw_write32(rtwdev, 0x1c3c, 0x00088103); + + rtw8822c_dac_cal_rf_mode(rtwdev, &ic_in, &qc_in); + ic = ic_in; + qc = qc_in; + + /* compensation value */ + if (ic != 0x0) + ic = 0x400 - ic; + if (qc != 0x0) + qc = 0x400 - qc; + if (ic < 0x300) { + ic = ic * 2 * 6 / 5; + ic = ic + 0x80; + } else { + ic = (0x400 - ic) * 2 * 6 / 5; + ic = 0x7f - ic; + } + if (qc < 0x300) { + qc = qc * 2 * 6 / 5; + qc = qc + 0x80; + } else { + qc = (0x400 - qc) * 2 * 6 / 5; + qc = 0x7f - qc; + } + + *ic_out = ic; + *qc_out = qc; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] before i=0x%x, q=0x%x\n", ic_in, qc_in); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] after i=0x%x, q=0x%x\n", ic, qc); +} + +static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, + u32 adc_ic, u32 adc_qc, + u32 *ic_in, u32 *qc_in, + u32 *i_out, u32 *q_out) +{ + u32 base_addr; + u32 read_addr; + u32 ic, qc; + u32 temp; + + base_addr = rtw8822c_get_path_write_addr(path); + read_addr = rtw8822c_get_path_read_addr(path); + ic = *ic_in; + qc = *qc_in; + + rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); + rtw_write32(rtwdev, base_addr + 0xbc, 0xc008ff81); + rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); + rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, ic & 0xf); + rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, (ic & 0xf0) >> 4); + rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); + rtw_write32(rtwdev, base_addr + 0xd8, 0xe008ff81); + rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); + rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, qc & 0xf); + rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, (qc & 0xf0) >> 4); + rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); + mdelay(2); + rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x6); + mdelay(2); + rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); + rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); + mdelay(1); + rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); + rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); + mdelay(20); + if (!check_hw_ready(rtwdev, read_addr + 0x24, 0x07f80000, ic) || + !check_hw_ready(rtwdev, read_addr + 0x50, 0x07f80000, qc)) + rtw_err(rtwdev, "failed to write IQ vector to hardware\n"); + rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); + mdelay(1); + rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x3); + rtw_write32(rtwdev, 0x9b4, 0xdb6db600); + + /* check DAC DC offset */ + temp = ((adc_ic + 0x10) & 0x3ff) | (((adc_qc + 0x10) & 0x3ff) << 10); + rtw_write32(rtwdev, base_addr + 0x68, temp); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); + rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); + rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); + if (ic >= 0x10) + ic = ic - 0x10; + else + ic = 0x400 - (0x10 - ic); + + if (qc >= 0x10) + qc = qc - 0x10; + else + qc = 0x400 - (0x10 - qc); + + *i_out = ic; + *q_out = qc; + + if (ic >= 0x200) + ic = 0x400 - ic; + if (qc >= 0x200) + qc = 0x400 - qc; + + *ic_in = ic; + *qc_in = qc; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DACK] after DACK i=0x%x, q=0x%x\n", *i_out, *q_out); +} + +static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path) +{ + u32 base_addr = rtw8822c_get_path_write_addr(path); + + rtw_write32(rtwdev, base_addr + 0x68, 0x0); + rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); + rtw_write32_mask(rtwdev, base_addr + 0xbc, 0x1, 0x0); + rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x1); +} + +static void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev, + u8 path, u8 vec, u32 w_addr, u32 r_addr) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u16 val; + u32 i; + + if (WARN_ON(vec >= 2)) + return; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_addr, 0xf0000000, i); + val = (u16)rtw_read32_mask(rtwdev, r_addr, 0x7fc0000); + dm_info->dack_msbk[path][vec][i] = val; + } +} + +static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path) +{ + u32 w_off = 0x1c; + u32 r_off = 0x2c; + u32 w_addr, r_addr; + + if (WARN_ON(path >= 2)) + return; + + /* backup I vector */ + w_addr = rtw8822c_get_path_write_addr(path) + 0xb0; + r_addr = rtw8822c_get_path_read_addr(path) + 0x10; + rtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr); + + /* backup Q vector */ + w_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; + r_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off; + rtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr); +} + +static void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 val; + + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_A][0][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_1, 0xf); + dm_info->dack_dck[RF_PATH_A][0][1] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_A][1][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_1, 0xf); + dm_info->dack_dck[RF_PATH_A][1][1] = val; + + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_B][0][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_1, 0xf); + dm_info->dack_dck[RF_PATH_B][1][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_B][0][1] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_1, 0xf); + dm_info->dack_dck[RF_PATH_B][1][1] = val; +} + +static void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev) +{ + u32 temp[3]; + + temp[0] = rtw_read32(rtwdev, 0x1860); + temp[1] = rtw_read32(rtwdev, 0x4160); + temp[2] = rtw_read32(rtwdev, 0x9b4); + + /* set clock */ + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + + /* backup path-A I/Q */ + rtw_write32_clr(rtwdev, 0x1830, BIT(30)); + rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); + rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A); + + /* backup path-B I/Q */ + rtw_write32_clr(rtwdev, 0x4130, BIT(30)); + rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); + rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B); + + rtw8822c_dac_cal_backup_dck(rtwdev); + rtw_write32_set(rtwdev, 0x1830, BIT(30)); + rtw_write32_set(rtwdev, 0x4130, BIT(30)); + + rtw_write32(rtwdev, 0x1860, temp[0]); + rtw_write32(rtwdev, 0x4160, temp[1]); + rtw_write32(rtwdev, 0x9b4, temp[2]); +} + +static void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 val; + + rtw_write32_set(rtwdev, REG_DCKA_I_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_A][0][0]; + rtw_write32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_A][0][1]; + rtw_write32_mask(rtwdev, REG_DCKA_I_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKA_Q_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_A][1][0]; + rtw_write32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_A][1][1]; + rtw_write32_mask(rtwdev, REG_DCKA_Q_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKB_I_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_B][0][0]; + rtw_write32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_B][0][1]; + rtw_write32_mask(rtwdev, REG_DCKB_I_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKB_Q_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_B][1][0]; + rtw_write32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_B][1][1]; + rtw_write32_mask(rtwdev, REG_DCKB_Q_1, 0xf, val); +} + +static void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + + rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x0); + + rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x0); + rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); + rtw_write32_mask(rtwdev, 0x18b4, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x18d0, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x0); + rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); + rtw_write32_mask(rtwdev, 0x41b4, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x41d0, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x18b0, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x18c0, BIT(14), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x18dc, BIT(14), 0x0); + + rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x1); + + rtw8822c_dac_cal_restore_dck(rtwdev); + + rtw_write32_mask(rtwdev, 0x18c0, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x18dc, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x41c0, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x41dc, 0x38000, 0x7); + + rtw_write32_mask(rtwdev, 0x18b8, BIT(26) | BIT(25), 0x1); + rtw_write32_mask(rtwdev, 0x18d4, BIT(26) | BIT(25), 0x1); + + rtw_write32_mask(rtwdev, 0x41b0, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x41c0, BIT(14), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x41dc, BIT(14), 0x0); + + rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x41b8, BIT(26) | BIT(25), 0x1); + rtw_write32_mask(rtwdev, 0x41d4, BIT(26) | BIT(25), 0x1); +} + +static bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev, + u32 target_addr, u32 toggle_addr) +{ + u32 cnt = 0; + + do { + rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x2); + + if (rtw_read32_mask(rtwdev, target_addr, 0xf) == 0x6) + return true; + + } while (cnt++ < 100); + + return false; +} + +static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 w_off = 0x1c; + u32 r_off = 0x2c; + u32 w_i, r_i, w_q, r_q; + u32 value; + u32 i; + + w_i = rtw8822c_get_path_write_addr(path) + 0xb0; + r_i = rtw8822c_get_path_read_addr(path) + 0x08; + w_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; + r_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off; + + if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8)) + return false; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); + value = dm_info->dack_msbk[path][0][i]; + rtw_write32_mask(rtwdev, w_i + 0x4, 0xff8, value); + rtw_write32_mask(rtwdev, w_i, 0xf0000000, i); + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x1); + } + + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); + + if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8)) + return false; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); + value = dm_info->dack_msbk[path][1][i]; + rtw_write32_mask(rtwdev, w_q + 0x4, 0xff8, value); + rtw_write32_mask(rtwdev, w_q, 0xf0000000, i); + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x1); + } + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); + + rtw_write32_mask(rtwdev, w_i + 0x8, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, w_q + 0x8, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(0), 0x0); + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(0), 0x0); + + return true; +} + +static bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) +{ + if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A)) + return false; + + if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B)) + return false; + + return true; +} + +static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 temp[3]; + + /* sample the first element for both path's IQ vector */ + if (dm_info->dack_msbk[RF_PATH_A][0][0] == 0 && + dm_info->dack_msbk[RF_PATH_A][1][0] == 0 && + dm_info->dack_msbk[RF_PATH_B][0][0] == 0 && + dm_info->dack_msbk[RF_PATH_B][1][0] == 0) + return false; + + temp[0] = rtw_read32(rtwdev, 0x1860); + temp[1] = rtw_read32(rtwdev, 0x4160); + temp[2] = rtw_read32(rtwdev, 0x9b4); + + rtw8822c_dac_cal_restore_prepare(rtwdev); + if (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x2834, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x4508, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x4534, 0x7fff80, 0xffff)) + return false; + + if (!__rtw8822c_dac_cal_restore(rtwdev)) { + rtw_err(rtwdev, "failed to restore dack vectors\n"); + return false; + } + + rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x1); + rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); + rtw_write32(rtwdev, 0x1860, temp[0]); + rtw_write32(rtwdev, 0x4160, temp[1]); + rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x1); + rtw_write32(rtwdev, 0x9b4, temp[2]); + + return true; +} + +static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) +{ + struct rtw_backup_info backup_rf[DACK_RF_8822C * DACK_PATH_8822C]; + struct rtw_backup_info backup[DACK_REG_8822C]; + u32 ic = 0, qc = 0, i; + u32 i_a = 0x0, q_a = 0x0, i_b = 0x0, q_b = 0x0; + u32 ic_a = 0x0, qc_a = 0x0, ic_b = 0x0, qc_b = 0x0; + u32 adc_ic_a = 0x0, adc_qc_a = 0x0, adc_ic_b = 0x0, adc_qc_b = 0x0; + + if (rtw8822c_dac_cal_restore(rtwdev)) + return; + + /* not able to restore, do it */ + + rtw8822c_dac_backup_reg(rtwdev, backup, backup_rf); + + rtw8822c_dac_bb_setting(rtwdev); + + /* path-A */ + rtw8822c_dac_cal_adc(rtwdev, RF_PATH_A, &adc_ic_a, &adc_qc_a); + for (i = 0; i < 10; i++) { + rtw8822c_dac_cal_step1(rtwdev, RF_PATH_A); + rtw8822c_dac_cal_step2(rtwdev, RF_PATH_A, &ic, &qc); + ic_a = ic; + qc_a = qc; + + rtw8822c_dac_cal_step3(rtwdev, RF_PATH_A, adc_ic_a, adc_qc_a, + &ic, &qc, &i_a, &q_a); + + if (ic < 5 && qc < 5) + break; + } + rtw8822c_dac_cal_step4(rtwdev, RF_PATH_A); + + /* path-B */ + rtw8822c_dac_cal_adc(rtwdev, RF_PATH_B, &adc_ic_b, &adc_qc_b); + for (i = 0; i < 10; i++) { + rtw8822c_dac_cal_step1(rtwdev, RF_PATH_B); + rtw8822c_dac_cal_step2(rtwdev, RF_PATH_B, &ic, &qc); + ic_b = ic; + qc_b = qc; + + rtw8822c_dac_cal_step3(rtwdev, RF_PATH_B, adc_ic_b, adc_qc_b, + &ic, &qc, &i_b, &q_b); + + if (ic < 5 && qc < 5) + break; + } + rtw8822c_dac_cal_step4(rtwdev, RF_PATH_B); + + rtw_write32(rtwdev, 0x1b00, 0x00000008); + rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); + rtw_write8(rtwdev, 0x1bcc, 0x0); + rtw_write32(rtwdev, 0x1b00, 0x0000000a); + rtw_write8(rtwdev, 0x1bcc, 0x0); + + rtw8822c_dac_restore_reg(rtwdev, backup, backup_rf); + + /* backup results to restore, saving a lot of time */ + rtw8822c_dac_cal_backup(rtwdev); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: ic=0x%x, qc=0x%x\n", ic_a, qc_a); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: ic=0x%x, qc=0x%x\n", ic_b, qc_b); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: i=0x%x, q=0x%x\n", i_a, q_a); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: i=0x%x, q=0x%x\n", i_b, q_b); +} + +static void rtw8822c_rf_x2_check(struct rtw_dev *rtwdev) +{ + u8 x2k_busy; + + mdelay(1); + x2k_busy = rtw_read_rf(rtwdev, RF_PATH_A, 0xb8, BIT(15)); + if (x2k_busy == 1) { + rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0xC4440); + rtw_write_rf(rtwdev, RF_PATH_A, 0xba, RFREG_MASK, 0x6840D); + rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0x80440); + mdelay(1); + } +} + +static void rtw8822c_set_power_trim(struct rtw_dev *rtwdev, s8 bb_gain[2][8]) +{ +#define RF_SET_POWER_TRIM(_path, _seq, _idx) \ + do { \ + rtw_write_rf(rtwdev, _path, 0x33, RFREG_MASK, _seq); \ + rtw_write_rf(rtwdev, _path, 0x3f, RFREG_MASK, \ + bb_gain[_path][_idx]); \ + } while (0) + u8 path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_write_rf(rtwdev, path, 0xee, BIT(19), 1); + RF_SET_POWER_TRIM(path, 0x0, 0); + RF_SET_POWER_TRIM(path, 0x1, 1); + RF_SET_POWER_TRIM(path, 0x2, 2); + RF_SET_POWER_TRIM(path, 0x3, 2); + RF_SET_POWER_TRIM(path, 0x4, 3); + RF_SET_POWER_TRIM(path, 0x5, 4); + RF_SET_POWER_TRIM(path, 0x6, 5); + RF_SET_POWER_TRIM(path, 0x7, 6); + RF_SET_POWER_TRIM(path, 0x8, 7); + RF_SET_POWER_TRIM(path, 0x9, 3); + RF_SET_POWER_TRIM(path, 0xa, 4); + RF_SET_POWER_TRIM(path, 0xb, 5); + RF_SET_POWER_TRIM(path, 0xc, 6); + RF_SET_POWER_TRIM(path, 0xd, 7); + RF_SET_POWER_TRIM(path, 0xe, 7); + rtw_write_rf(rtwdev, path, 0xee, BIT(19), 0); + } +#undef RF_SET_POWER_TRIM +} + +static void rtw8822c_power_trim(struct rtw_dev *rtwdev) +{ + u8 pg_pwr = 0xff, i, path, idx; + s8 bb_gain[2][8] = {}; + u16 rf_efuse_2g[3] = {PPG_2GL_TXAB, PPG_2GM_TXAB, PPG_2GH_TXAB}; + u16 rf_efuse_5g[2][5] = {{PPG_5GL1_TXA, PPG_5GL2_TXA, PPG_5GM1_TXA, + PPG_5GM2_TXA, PPG_5GH1_TXA}, + {PPG_5GL1_TXB, PPG_5GL2_TXB, PPG_5GM1_TXB, + PPG_5GM2_TXB, PPG_5GH1_TXB} }; + bool set = false; + + for (i = 0; i < ARRAY_SIZE(rf_efuse_2g); i++) { + rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[i], &pg_pwr); + if (pg_pwr == EFUSE_READ_FAIL) + continue; + set = true; + bb_gain[RF_PATH_A][i] = FIELD_GET(PPG_2G_A_MASK, pg_pwr); + bb_gain[RF_PATH_B][i] = FIELD_GET(PPG_2G_B_MASK, pg_pwr); + } + + for (i = 0; i < ARRAY_SIZE(rf_efuse_5g[0]); i++) { + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path][i], + &pg_pwr); + if (pg_pwr == EFUSE_READ_FAIL) + continue; + set = true; + idx = i + ARRAY_SIZE(rf_efuse_2g); + bb_gain[path][idx] = FIELD_GET(PPG_5G_MASK, pg_pwr); + } + } + if (set) + rtw8822c_set_power_trim(rtwdev, bb_gain); + + rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); +} + +static void rtw8822c_thermal_trim(struct rtw_dev *rtwdev) +{ + u16 rf_efuse[2] = {PPG_THERMAL_A, PPG_THERMAL_B}; + u8 pg_therm = 0xff, thermal[2] = {0}, path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_read8_physical_efuse(rtwdev, rf_efuse[path], &pg_therm); + if (pg_therm == EFUSE_READ_FAIL) + return; + /* Efuse value of BIT(0) shall be move to BIT(3), and the value + * of BIT(1) to BIT(3) should be right shifted 1 bit. + */ + thermal[path] = FIELD_GET(GENMASK(3, 1), pg_therm); + thermal[path] |= FIELD_PREP(BIT(3), pg_therm & BIT(0)); + rtw_write_rf(rtwdev, path, 0x43, RF_THEMAL_MASK, thermal[path]); + } +} + +static void rtw8822c_pa_bias(struct rtw_dev *rtwdev) +{ + u16 rf_efuse_2g[2] = {PPG_PABIAS_2GA, PPG_PABIAS_2GB}; + u16 rf_efuse_5g[2] = {PPG_PABIAS_5GA, PPG_PABIAS_5GB}; + u8 pg_pa_bias = 0xff, path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[path], + &pg_pa_bias); + if (pg_pa_bias == EFUSE_READ_FAIL) + return; + pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); + rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_2G_MASK, pg_pa_bias); + } + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path], + &pg_pa_bias); + pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); + rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_5G_MASK, pg_pa_bias); + } +} + +static void rtw8822c_rfk_handshake(struct rtw_dev *rtwdev, bool is_before_k) +{ + struct rtw_dm_info *dm = &rtwdev->dm_info; + u8 u1b_tmp; + u8 u4b_tmp; + int ret; + + if (is_before_k) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[RFK] WiFi / BT RFK handshake start!!\n"); + + if (!dm->is_bt_iqk_timeout) { + ret = read_poll_timeout(rtw_read32_mask, u4b_tmp, + u4b_tmp == 0, 20, 600000, false, + rtwdev, REG_PMC_DBG_CTRL1, + BITS_PMC_BT_IQK_STS); + if (ret) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[RFK] Wait BT IQK finish timeout!!\n"); + dm->is_bt_iqk_timeout = true; + } + } + + rtw_fw_inform_rfk_status(rtwdev, true); + + ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, + u1b_tmp == 1, 20, 100000, false, + rtwdev, REG_ARFR4, BIT_WL_RFK); + if (ret) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[RFK] Send WiFi RFK start H2C cmd FAIL!!\n"); + } else { + rtw_fw_inform_rfk_status(rtwdev, false); + ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, + u1b_tmp == 1, 20, 100000, false, + rtwdev, REG_ARFR4, + BIT_WL_RFK); + if (ret) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[RFK] Send WiFi RFK finish H2C cmd FAIL!!\n"); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[RFK] WiFi / BT RFK handshake finish!!\n"); + } +} + +static void rtw8822c_rfk_power_save(struct rtw_dev *rtwdev, + bool is_power_save) +{ + u8 path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_PS_EN, + is_power_save ? 0 : 1); + } +} + +static void rtw8822c_txgapk_backup_bb_reg(struct rtw_dev *rtwdev, const u32 reg[], + u32 reg_backup[], u32 reg_num) +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + reg_backup[i] = rtw_read32(rtwdev, reg[i]); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Backup BB 0x%x = 0x%x\n", + reg[i], reg_backup[i]); + } +} + +static void rtw8822c_txgapk_reload_bb_reg(struct rtw_dev *rtwdev, + const u32 reg[], u32 reg_backup[], + u32 reg_num) +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + rtw_write32(rtwdev, reg[i], reg_backup[i]); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Reload BB 0x%x = 0x%x\n", + reg[i], reg_backup[i]); + } +} + +static bool check_rf_status(struct rtw_dev *rtwdev, u8 status) +{ + u8 reg_rf0_a, reg_rf0_b; + + reg_rf0_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, + RF_MODE_TRXAGC, BIT_RF_MODE); + reg_rf0_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, + RF_MODE_TRXAGC, BIT_RF_MODE); + + if (reg_rf0_a == status || reg_rf0_b == status) + return false; + + return true; +} + +static void rtw8822c_txgapk_tx_pause(struct rtw_dev *rtwdev) +{ + bool status; + int ret; + + rtw_write8(rtwdev, REG_TXPAUSE, BIT_AC_QUEUE); + rtw_write32_mask(rtwdev, REG_TX_FIFO, BIT_STOP_TX, 0x2); + + ret = read_poll_timeout_atomic(check_rf_status, status, status, + 2, 5000, false, rtwdev, 2); + if (ret) + rtw_warn(rtwdev, "failed to pause TX\n"); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Tx pause!!\n"); +} + +static void rtw8822c_txgapk_bb_dpk(struct rtw_dev *rtwdev, u8 path) +{ + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + rtw_write32_mask(rtwdev, REG_ENFN, BIT_IQK_DPK_EN, 0x1); + rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, + BIT_IQK_DPK_CLOCK_SRC, 0x1); + rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, + BIT_IQK_DPK_RESET_SRC, 0x1); + rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_EN_IOQ_IQK_DPK, 0x1); + rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_TST_IQK2SET_SRC, 0x0); + rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x1ff); + + if (path == RF_PATH_A) { + rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, + BIT_RFTXEN_GCK_FORCE_ON, 0x1); + rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x1); + rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, + BIT_TX_SCALE_0DB, 0x1); + rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x0); + } else if (path == RF_PATH_B) { + rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, + BIT_RFTXEN_GCK_FORCE_ON, 0x1); + rtw_write32_mask(rtwdev, REG_3WIRE2, + BIT_DIS_SHARERX_TXGAT, 0x1); + rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, + BIT_TX_SCALE_0DB, 0x1); + rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x0); + } + rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x2); +} + +static void rtw8822c_txgapk_afe_dpk(struct rtw_dev *rtwdev, u8 path) +{ + u32 reg; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (path == RF_PATH_A) { + reg = REG_ANAPAR_A; + } else if (path == RF_PATH_B) { + reg = REG_ANAPAR_B; + } else { + rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); + return; + } + + rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, MASKDWORD); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x701f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x702f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x703f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x704f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x706f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709f0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70af0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bf0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cf0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70df0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ef0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); +} + +static void rtw8822c_txgapk_afe_dpk_restore(struct rtw_dev *rtwdev, u8 path) +{ + u32 reg; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (path == RF_PATH_A) { + reg = REG_ANAPAR_A; + } else if (path == RF_PATH_B) { + reg = REG_ANAPAR_B; + } else { + rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); + return; + } + rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, 0xffa1005e); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700b8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70144041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70244041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70344041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70444041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705b8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70644041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707b8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708b8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709b8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ab8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bb8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cb8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70db8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70eb8041); + rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70fb8041); +} + +static void rtw8822c_txgapk_bb_dpk_restore(struct rtw_dev *rtwdev, u8 path) +{ + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x0); + rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TIA_BYPASS, 0x0); + rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TXBB, 0x0); + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); + rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x1); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); + rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); + rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x0); + + if (path == RF_PATH_A) { + rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, + BIT_RFTXEN_GCK_FORCE_ON, 0x0); + rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x0); + rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, + BIT_TX_SCALE_0DB, 0x0); + rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x3); + } else if (path == RF_PATH_B) { + rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, + BIT_RFTXEN_GCK_FORCE_ON, 0x0); + rtw_write32_mask(rtwdev, REG_3WIRE2, + BIT_DIS_SHARERX_TXGAT, 0x0); + rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, + BIT_TX_SCALE_0DB, 0x0); + rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x3); + } + + rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x0); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_CFIR_EN, 0x5); +} + +static bool _rtw8822c_txgapk_gain_valid(struct rtw_dev *rtwdev, u32 gain) +{ + if ((FIELD_GET(BIT_GAIN_TX_PAD_H, gain) >= 0xc) && + (FIELD_GET(BIT_GAIN_TX_PAD_L, gain) >= 0xe)) + return true; + + return false; +} + +static void _rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev, + u8 band, u8 path) +{ + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + u32 v, tmp_3f = 0; + u8 gain, check_txgain; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + + switch (band) { + case RF_BAND_2G_OFDM: + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); + break; + case RF_BAND_5G_L: + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); + break; + case RF_BAND_5G_M: + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); + break; + case RF_BAND_5G_H: + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); + break; + default: + break; + } + + rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, MASKBYTE0, 0x88); + + check_txgain = 0; + for (gain = 0; gain < RF_GAIN_NUM; gain++) { + v = txgapk->rf3f_bp[band][gain][path]; + if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { + if (!check_txgain) { + tmp_3f = txgapk->rf3f_bp[band][gain][path]; + check_txgain = 1; + } + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", + txgapk->rf3f_bp[band][gain][path]); + } else { + tmp_3f = txgapk->rf3f_bp[band][gain][path]; + } + + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN, tmp_3f); + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_I_GAIN, gain); + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x1); + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x0); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] Band=%d 0x1b98[11:0]=0x%03X path=%d\n", + band, tmp_3f, path); + } +} + +static void rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev) +{ + u8 path, band; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", + __func__, rtwdev->dm_info.gapk.channel); + + for (band = 0; band < RF_BAND_MAX; band++) { + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + _rtw8822c_txgapk_write_gain_bb_table(rtwdev, + band, path); + } + } +} + +static void rtw8822c_txgapk_read_offset(struct rtw_dev *rtwdev, u8 path) +{ + static const u32 cfg1_1b00[2] = {0x00000d18, 0x00000d2a}; + static const u32 cfg2_1b00[2] = {0x00000d19, 0x00000d2b}; + static const u32 set_pi[2] = {REG_RSV_CTRL, REG_WLRF1}; + static const u32 path_setting[2] = {REG_ORITXCODE, REG_ORITXCODE2}; + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + u8 channel = txgapk->channel; + u32 val; + int i; + + if (path >= ARRAY_SIZE(cfg1_1b00) || + path >= ARRAY_SIZE(cfg2_1b00) || + path >= ARRAY_SIZE(set_pi) || + path >= ARRAY_SIZE(path_setting)) { + rtw_warn(rtwdev, "[TXGAPK] wrong path %d\n", path); + return; + } + + rtw_write32_mask(rtwdev, REG_ANTMAP0, BIT_ANT_PATH, path + 1); + rtw_write32_mask(rtwdev, REG_TXLGMAP, MASKDWORD, 0xe4e40000); + rtw_write32_mask(rtwdev, REG_TXANTSEG, BIT_ANTSEG, 0x3); + rtw_write32_mask(rtwdev, path_setting[path], MASK20BITS, 0x33312); + rtw_write32_mask(rtwdev, path_setting[path], BIT_PATH_EN, 0x1); + rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x0); + rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT_TXA_TANK, 0x1); + rtw_write_rf(rtwdev, path, RF_IDAC, BIT_TX_MODE, 0x820); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); + + rtw_write32_mask(rtwdev, REG_TX_TONE_IDX, MASKBYTE0, 0x018); + fsleep(1000); + if (channel >= 1 && channel <= 14) + rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_2G_SWING); + else + rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_5G_SWING); + fsleep(1000); + + rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg1_1b00[path]); + rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg2_1b00[path]); + + read_poll_timeout(rtw_read32_mask, val, + val == 0x55, 1000, 100000, false, + rtwdev, REG_RPT_CIP, BIT_RPT_CIP_STATUS); + + rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x2); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_EN, 0x1); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x12); + rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x3); + val = rtw_read32(rtwdev, REG_STAT_RPT); + + txgapk->offset[0][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); + txgapk->offset[1][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); + txgapk->offset[2][path] = (s8)FIELD_GET(BIT_GAPK_RPT2, val); + txgapk->offset[3][path] = (s8)FIELD_GET(BIT_GAPK_RPT3, val); + txgapk->offset[4][path] = (s8)FIELD_GET(BIT_GAPK_RPT4, val); + txgapk->offset[5][path] = (s8)FIELD_GET(BIT_GAPK_RPT5, val); + txgapk->offset[6][path] = (s8)FIELD_GET(BIT_GAPK_RPT6, val); + txgapk->offset[7][path] = (s8)FIELD_GET(BIT_GAPK_RPT7, val); + + rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x4); + val = rtw_read32(rtwdev, REG_STAT_RPT); + + txgapk->offset[8][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); + txgapk->offset[9][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); + + for (i = 0; i < RF_HW_OFFSET_NUM; i++) + if (txgapk->offset[i][path] & BIT(3)) + txgapk->offset[i][path] = txgapk->offset[i][path] | + 0xf0; + for (i = 0; i < RF_HW_OFFSET_NUM; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] offset %d %d path=%d\n", + txgapk->offset[i][path], i, path); +} + +static void rtw8822c_txgapk_calculate_offset(struct rtw_dev *rtwdev, u8 path) +{ + static const u32 bb_reg[] = {REG_ANTMAP0, REG_TXLGMAP, REG_TXANTSEG, + REG_ORITXCODE, REG_ORITXCODE2}; + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + u8 channel = txgapk->channel; + u32 reg_backup[ARRAY_SIZE(bb_reg)] = {0}; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", + __func__, channel); + + rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, + reg_backup, ARRAY_SIZE(bb_reg)); + + if (channel >= 1 && channel <= 14) { + rtw_write32_mask(rtwdev, + REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x5000f); + rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x0); + rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x1); + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0f); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); + rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); + + rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x00); + rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); + + rtw8822c_txgapk_read_offset(rtwdev, path); + rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); + + } else { + rtw_write32_mask(rtwdev, + REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50011); + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x3); + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x3); + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); + rtw_write_rf(rtwdev, path, + RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0x2); + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x12); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); + rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x5); + + rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); + + if (channel >= 36 && channel <= 64) + rtw_write32_mask(rtwdev, + REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); + else if (channel >= 100 && channel <= 144) + rtw_write32_mask(rtwdev, + REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); + else if (channel >= 149 && channel <= 177) + rtw_write32_mask(rtwdev, + REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); + + rtw8822c_txgapk_read_offset(rtwdev, path); + rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); + } + rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, + reg_backup, ARRAY_SIZE(bb_reg)); +} + +static void rtw8822c_txgapk_rf_restore(struct rtw_dev *rtwdev, u8 path) +{ + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (path >= rtwdev->hal.rf_path_num) + return; + + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x3); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x0); + rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x0); +} + +static u32 rtw8822c_txgapk_cal_gain(struct rtw_dev *rtwdev, u32 gain, s8 offset) +{ + u32 gain_x2, new_gain; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (_rtw8822c_txgapk_gain_valid(rtwdev, gain)) { + new_gain = gain; + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] gain=0x%03X(>=0xCEX) offset=%d new_gain=0x%03X\n", + gain, offset, new_gain); + return new_gain; + } + + gain_x2 = (gain << 1) + offset; + new_gain = (gain_x2 >> 1) | (gain_x2 & BIT(0) ? BIT_GAIN_EXT : 0); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] gain=0x%X offset=%d new_gain=0x%X\n", + gain, offset, new_gain); + + return new_gain; +} + +static void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev) +{ + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + u32 i, j, tmp = 0x20, tmp_3f, v; + s8 offset_tmp[RF_GAIN_NUM] = {0}; + u8 path, band = RF_BAND_2G_OFDM, channel = txgapk->channel; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (channel >= 1 && channel <= 14) { + tmp = 0x20; + band = RF_BAND_2G_OFDM; + } else if (channel >= 36 && channel <= 64) { + tmp = 0x200; + band = RF_BAND_5G_L; + } else if (channel >= 100 && channel <= 144) { + tmp = 0x280; + band = RF_BAND_5G_M; + } else if (channel >= 149 && channel <= 177) { + tmp = 0x300; + band = RF_BAND_5G_H; + } else { + rtw_err(rtwdev, "[TXGAPK] unknown channel %d!!\n", channel); + return; + } + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + for (i = 0; i < RF_GAIN_NUM; i++) { + offset_tmp[i] = 0; + for (j = i; j < RF_GAIN_NUM; j++) { + v = txgapk->rf3f_bp[band][j][path]; + if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) + continue; + + offset_tmp[i] += txgapk->offset[j][path]; + txgapk->fianl_offset[i][path] = offset_tmp[i]; + } + + v = txgapk->rf3f_bp[band][i][path]; + if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", + txgapk->rf3f_bp[band][i][path]); + } else { + txgapk->rf3f_fs[path][i] = offset_tmp[i]; + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] offset %d %d\n", + offset_tmp[i], i); + } + } + + rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x10000); + for (i = 0; i < RF_GAIN_NUM; i++) { + rtw_write_rf(rtwdev, path, + RF_LUTWA, RFREG_MASK, tmp + i); + + tmp_3f = rtw8822c_txgapk_cal_gain(rtwdev, + txgapk->rf3f_bp[band][i][path], + offset_tmp[i]); + rtw_write_rf(rtwdev, path, RF_LUTWD0, + BIT_GAIN_EXT | BIT_DATA_L, tmp_3f); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] 0x33=0x%05X 0x3f=0x%04X\n", + tmp + i, tmp_3f); + } + rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x0); + } +} + +static void rtw8822c_txgapk_save_all_tx_gain_table(struct rtw_dev *rtwdev) +{ + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + static const u32 three_wire[2] = {REG_3WIRE, REG_3WIRE2}; + static const u8 ch_num[RF_BAND_MAX] = {1, 1, 36, 100, 149}; + static const u8 band_num[RF_BAND_MAX] = {0x0, 0x0, 0x1, 0x3, 0x5}; + static const u8 cck[RF_BAND_MAX] = {0x1, 0x0, 0x0, 0x0, 0x0}; + u8 path, band, gain, rf0_idx; + u32 rf18, v; + + if (rtwdev->dm_info.dm_flags & BIT(RTW_DM_CAP_TXGAPK)) + return; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + if (txgapk->read_txgain == 1) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] Already Read txgapk->read_txgain return!!!\n"); + rtw8822c_txgapk_write_gain_bb_table(rtwdev); + return; + } + + for (band = 0; band < RF_BAND_MAX; band++) { + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rf18 = rtw_read_rf(rtwdev, path, RF_CFGCH, RFREG_MASK); + + rtw_write32_mask(rtwdev, + three_wire[path], BIT_3WIRE_EN, 0x0); + rtw_write_rf(rtwdev, path, + RF_CFGCH, MASKBYTE0, ch_num[band]); + rtw_write_rf(rtwdev, path, + RF_CFGCH, BIT_BAND, band_num[band]); + rtw_write_rf(rtwdev, path, + RF_BW_TRXBB, BIT_DBG_CCK_CCA, cck[band]); + rtw_write_rf(rtwdev, path, + RF_BW_TRXBB, BIT_TX_CCK_IND, cck[band]); + gain = 0; + for (rf0_idx = 1; rf0_idx < 32; rf0_idx += 3) { + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, + MASKBYTE0, rf0_idx); + v = rtw_read_rf(rtwdev, path, + RF_TX_RESULT, RFREG_MASK); + txgapk->rf3f_bp[band][gain][path] = v & BIT_DATA_L; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] 0x5f=0x%03X band=%d path=%d\n", + txgapk->rf3f_bp[band][gain][path], + band, path); + gain++; + } + rtw_write_rf(rtwdev, path, RF_CFGCH, RFREG_MASK, rf18); + rtw_write32_mask(rtwdev, + three_wire[path], BIT_3WIRE_EN, 0x3); + } + } + rtw8822c_txgapk_write_gain_bb_table(rtwdev); + txgapk->read_txgain = 1; +} + +static void rtw8822c_txgapk(struct rtw_dev *rtwdev) +{ + static const u32 bb_reg[2] = {REG_TX_PTCL_CTRL, REG_TX_FIFO}; + struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; + u32 bb_reg_backup[2]; + u8 path; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); + + rtw8822c_txgapk_save_all_tx_gain_table(rtwdev); + + if (txgapk->read_txgain == 0) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] txgapk->read_txgain == 0 return!!!\n"); + return; + } + + if (rtwdev->efuse.power_track_type >= 4 && + rtwdev->efuse.power_track_type <= 7) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[TXGAPK] Normal Mode in TSSI mode. return!!!\n"); + return; + } + + rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, + bb_reg_backup, ARRAY_SIZE(bb_reg)); + rtw8822c_txgapk_tx_pause(rtwdev); + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + txgapk->channel = rtw_read_rf(rtwdev, path, + RF_CFGCH, RFREG_MASK) & MASKBYTE0; + rtw8822c_txgapk_bb_dpk(rtwdev, path); + rtw8822c_txgapk_afe_dpk(rtwdev, path); + rtw8822c_txgapk_calculate_offset(rtwdev, path); + rtw8822c_txgapk_rf_restore(rtwdev, path); + rtw8822c_txgapk_afe_dpk_restore(rtwdev, path); + rtw8822c_txgapk_bb_dpk_restore(rtwdev, path); + } + rtw8822c_txgapk_write_tx_gain(rtwdev); + rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, + bb_reg_backup, ARRAY_SIZE(bb_reg)); +} + +static void rtw8822c_do_gapk(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm = &rtwdev->dm_info; + + if (dm->dm_flags & BIT(RTW_DM_CAP_TXGAPK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] feature disable!!!\n"); + return; + } + rtw8822c_rfk_handshake(rtwdev, true); + rtw8822c_txgapk(rtwdev); + rtw8822c_rfk_handshake(rtwdev, false); +} + +static void rtw8822c_rf_init(struct rtw_dev *rtwdev) +{ + rtw8822c_rf_dac_cal(rtwdev); + rtw8822c_rf_x2_check(rtwdev); + rtw8822c_thermal_trim(rtwdev); + rtw8822c_power_trim(rtwdev); + rtw8822c_pa_bias(rtwdev); +} + +static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) { + dm_info->delta_power_index[path] = 0; + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->thermal_avg[path] = 0xff; + } + + dm_info->pwr_trk_triggered = false; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + u8 crystal_cap; + u8 cck_gi_u_bnd_msb = 0; + u8 cck_gi_u_bnd_lsb = 0; + u8 cck_gi_l_bnd_msb = 0; + u8 cck_gi_l_bnd_lsb = 0; + bool is_tx2_path; + + /* power on BB/RF domain */ + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN); + + /* disable low rate DPD */ + rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); + + /* pre init before header files config */ + rtw8822c_header_file_init(rtwdev, true); + + rtw_phy_load_tables(rtwdev); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x7f; + rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, 0xfffc00, + crystal_cap | (crystal_cap << 7)); + + /* post init after header files config */ + rtw8822c_header_file_init(rtwdev, false); + + is_tx2_path = false; + rtw8822c_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx, + is_tx2_path); + rtw_phy_init(rtwdev); + + cck_gi_u_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc000); + cck_gi_u_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1aa8, 0xf0000); + cck_gi_l_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc0); + cck_gi_l_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1a70, 0x0f000000); + + dm_info->cck_gi_u_bnd = ((cck_gi_u_bnd_msb << 4) | (cck_gi_u_bnd_lsb)); + dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb)); + + rtw8822c_rf_init(rtwdev); + rtw8822c_pwrtrack_init(rtwdev); + + rtw_bf_phy_init(rtwdev); +} + +#define WLAN_TXQ_RPT_EN 0x1F +#define WLAN_SLOT_TIME 0x09 +#define WLAN_PIFS_TIME 0x1C +#define WLAN_SIFS_CCK_CONT_TX 0x0A +#define WLAN_SIFS_OFDM_CONT_TX 0x0E +#define WLAN_SIFS_CCK_TRX 0x0A +#define WLAN_SIFS_OFDM_TRX 0x10 +#define WLAN_NAV_MAX 0xC8 +#define WLAN_RDG_NAV 0x05 +#define WLAN_TXOP_NAV 0x1B +#define WLAN_CCK_RX_TSF 0x30 +#define WLAN_OFDM_RX_TSF 0x30 +#define WLAN_TBTT_PROHIBIT 0x04 /* unit : 32us */ +#define WLAN_TBTT_HOLD_TIME 0x064 /* unit : 32us */ +#define WLAN_DRV_EARLY_INT 0x04 +#define WLAN_BCN_CTRL_CLT0 0x10 +#define WLAN_BCN_DMA_TIME 0x02 +#define WLAN_BCN_MAX_ERR 0xFF +#define WLAN_SIFS_CCK_DUR_TUNE 0x0A +#define WLAN_SIFS_OFDM_DUR_TUNE 0x10 +#define WLAN_SIFS_CCK_CTX 0x0A +#define WLAN_SIFS_CCK_IRX 0x0A +#define WLAN_SIFS_OFDM_CTX 0x0E +#define WLAN_SIFS_OFDM_IRX 0x0E +#define WLAN_EIFS_DUR_TUNE 0x40 +#define WLAN_EDCA_VO_PARAM 0x002FA226 +#define WLAN_EDCA_VI_PARAM 0x005EA328 +#define WLAN_EDCA_BE_PARAM 0x005EA42B +#define WLAN_EDCA_BK_PARAM 0x0000A44F + +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0xFFFF +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0xE400220E +#define WLAN_RXPKT_MAX_SZ 12288 +#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) + +#define WLAN_AMPDU_MAX_TIME 0x70 +#define WLAN_RTS_LEN_TH 0xFF +#define WLAN_RTS_TX_TIME_TH 0x08 +#define WLAN_MAX_AGG_PKT_LIMIT 0x3f +#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x3f +#define WLAN_PRE_TXCNT_TIME_TH 0x1E0 +#define FAST_EDCA_VO_TH 0x06 +#define FAST_EDCA_VI_TH 0x06 +#define FAST_EDCA_BE_TH 0x06 +#define FAST_EDCA_BK_TH 0x06 +#define WLAN_BAR_RETRY_LIMIT 0x01 +#define WLAN_BAR_ACK_TYPE 0x05 +#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 +#define WLAN_RESP_TXRATE 0x84 +#define WLAN_ACK_TO 0x21 +#define WLAN_ACK_TO_CCK 0x6A +#define WLAN_DATA_RATE_FB_CNT_1_4 0x01000000 +#define WLAN_DATA_RATE_FB_CNT_5_8 0x08070504 +#define WLAN_RTS_RATE_FB_CNT_5_8 0x08070504 +#define WLAN_DATA_RATE_FB_RATE0 0xFE01F010 +#define WLAN_DATA_RATE_FB_RATE0_H 0x40000000 +#define WLAN_RTS_RATE_FB_RATE1 0x003FF010 +#define WLAN_RTS_RATE_FB_RATE1_H 0x40000000 +#define WLAN_RTS_RATE_FB_RATE4 0x0600F010 +#define WLAN_RTS_RATE_FB_RATE4_H 0x400003E0 +#define WLAN_RTS_RATE_FB_RATE5 0x0600F015 +#define WLAN_RTS_RATE_FB_RATE5_H 0x000000E0 +#define WLAN_MULTI_ADDR 0xFFFFFFFF + +#define WLAN_TX_FUNC_CFG1 0x30 +#define WLAN_TX_FUNC_CFG2 0x30 +#define WLAN_MAC_OPT_NORM_FUNC1 0x98 +#define WLAN_MAC_OPT_LB_FUNC1 0x80 +#define WLAN_MAC_OPT_FUNC2 0xb0810041 +#define WLAN_MAC_INT_MIG_CFG 0x33330000 + +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) + +#define WLAN_SIFS_DUR_TUNE (WLAN_SIFS_CCK_DUR_TUNE | \ + (WLAN_SIFS_OFDM_DUR_TUNE << 8)) + +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) + +#define MAC_CLK_SPEED 80 /* 80M */ +#define EFUSE_PCB_INFO_OFFSET 0xCA + +static int rtw8822c_mac_init(struct rtw_dev *rtwdev) +{ + u8 value8; + u16 value16; + u32 value32; + u16 pre_txcnt; + + /* txq control */ + value8 = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL); + value8 |= (BIT(7) & ~BIT(1) & ~BIT(2)); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, value8); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + /* sifs control */ + rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SIFS_DUR_TUNE); + rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); + rtw_write16(rtwdev, REG_RESP_SIFS_CCK, + WLAN_SIFS_CCK_CTX | WLAN_SIFS_CCK_IRX << 8); + rtw_write16(rtwdev, REG_RESP_SIFS_OFDM, + WLAN_SIFS_OFDM_CTX | WLAN_SIFS_OFDM_IRX << 8); + /* rate fallback control */ + rtw_write32(rtwdev, REG_DARFRC, WLAN_DATA_RATE_FB_CNT_1_4); + rtw_write32(rtwdev, REG_DARFRCH, WLAN_DATA_RATE_FB_CNT_5_8); + rtw_write32(rtwdev, REG_RARFRCH, WLAN_RTS_RATE_FB_CNT_5_8); + rtw_write32(rtwdev, REG_ARFR0, WLAN_DATA_RATE_FB_RATE0); + rtw_write32(rtwdev, REG_ARFRH0, WLAN_DATA_RATE_FB_RATE0_H); + rtw_write32(rtwdev, REG_ARFR1_V1, WLAN_RTS_RATE_FB_RATE1); + rtw_write32(rtwdev, REG_ARFRH1_V1, WLAN_RTS_RATE_FB_RATE1_H); + rtw_write32(rtwdev, REG_ARFR4, WLAN_RTS_RATE_FB_RATE4); + rtw_write32(rtwdev, REG_ARFRH4, WLAN_RTS_RATE_FB_RATE4_H); + rtw_write32(rtwdev, REG_ARFR5, WLAN_RTS_RATE_FB_RATE5); + rtw_write32(rtwdev, REG_ARFRH5, WLAN_RTS_RATE_FB_RATE5_H); + /* protocol configuration */ + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); + rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); + pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; + rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); + rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); + value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | + (WLAN_MAX_AGG_PKT_LIMIT << 16) | + (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); + rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); + rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, + WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); + /* close BA parser */ + rtw_write8_clr(rtwdev, REG_LIFETIME_EN, BIT_BA_PARSER_EN); + rtw_write32_clr(rtwdev, REG_RRSR, BITS_RRSR_RSC); + + /* EDCA configuration */ + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, WLAN_EDCA_VO_PARAM); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, WLAN_EDCA_VI_PARAM); + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, WLAN_EDCA_BE_PARAM); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, WLAN_EDCA_BK_PARAM); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); + rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); + rtw_write8_set(rtwdev, REG_RD_CTRL + 1, + (BIT_DIS_TXOP_CFE | BIT_DIS_LSIG_CFE | + BIT_DIS_STBC_CFE) >> 8); + + /* MAC clock configuration */ + rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BIT_MAC_CLK_SEL); + rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED); + rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED); + + rtw_write8_set(rtwdev, REG_MISC_CTRL, + BIT_EN_FREE_CNT | BIT_DIS_SECOND_CCA); + rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); + rtw_write16(rtwdev, REG_TXPAUSE, 0x0000); + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); + rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); + /* Set beacon cotnrol - enable TSF and other related functions */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + /* Set send beacon related registers */ + rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); + rtw_write8(rtwdev, REG_BCN_CTRL_CLINT0, WLAN_BCN_CTRL_CLT0); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write8(rtwdev, REG_BCN_MAX_ERR, WLAN_BCN_MAX_ERR); + + /* WMAC configuration */ + rtw_write32(rtwdev, REG_MAR, WLAN_MULTI_ADDR); + rtw_write32(rtwdev, REG_MAR + 4, WLAN_MULTI_ADDR); + rtw_write8(rtwdev, REG_BBPSF_CTRL + 2, WLAN_RESP_TXRATE); + rtw_write8(rtwdev, REG_ACKTO, WLAN_ACK_TO); + rtw_write8(rtwdev, REG_ACKTO_CCK, WLAN_ACK_TO_CCK); + rtw_write16(rtwdev, REG_EIFS, WLAN_EIFS_DUR_TUNE); + rtw_write8(rtwdev, REG_NAV_CTRL + 2, WLAN_NAV_MAX); + rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H + 2, WLAN_BAR_ACK_TYPE); + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); + rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write32_set(rtwdev, REG_GENERAL_OPTION, BIT_DUMMY_FCS_READY_MASK_EN); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION_1, WLAN_MAC_OPT_NORM_FUNC1); + + /* init low power */ + value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL + 2) & 0xF00F; + value16 |= (BIT_RXGCK_VHT_FIFOTHR(1) | BIT_RXGCK_HT_FIFOTHR(1) | + BIT_RXGCK_OFDM_FIFOTHR(1) | BIT_RXGCK_CCK_FIFOTHR(1)) >> 16; + rtw_write16(rtwdev, REG_RXPSF_CTRL + 2, value16); + value16 = 0; + value16 = BIT_SET_RXPSF_PKTLENTHR(value16, 1); + value16 |= BIT_RXPSF_CTRLEN | BIT_RXPSF_VHTCHKEN | BIT_RXPSF_HTCHKEN + | BIT_RXPSF_OFDMCHKEN | BIT_RXPSF_CCKCHKEN + | BIT_RXPSF_OFDMRST; + rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); + rtw_write32(rtwdev, REG_RXPSF_TYPE_CTRL, 0xFFFFFFFF); + /* rx ignore configuration */ + value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL); + value16 &= ~(BIT_RXPSF_MHCHKEN | BIT_RXPSF_CCKRST | + BIT_RXPSF_CONT_ERRCHKEN); + value16 = BIT_SET_RXPSF_ERRTHR(value16, 0x07); + rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); + rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, + BIT_DIS_CHK_VHTSIGB_CRC); + + /* Interrupt migration configuration */ + rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG); + + return 0; +} + +#define FWCD_SIZE_REG_8822C 0x2000 +#define FWCD_SIZE_DMEM_8822C 0x10000 +#define FWCD_SIZE_IMEM_8822C 0x10000 +#define FWCD_SIZE_EMEM_8822C 0x20000 +#define FWCD_SIZE_ROM_8822C 0x10000 + +static const u32 __fwcd_segs_8822c[] = { + FWCD_SIZE_REG_8822C, + FWCD_SIZE_DMEM_8822C, + FWCD_SIZE_IMEM_8822C, + FWCD_SIZE_EMEM_8822C, + FWCD_SIZE_ROM_8822C, +}; + +static const struct rtw_fwcd_segs rtw8822c_fwcd_segs = { + .segs = __fwcd_segs_8822c, + .num = ARRAY_SIZE(__fwcd_segs_8822c), +}; + +static int rtw8822c_dump_fw_crash(struct rtw_dev *rtwdev) +{ +#define __dump_fw_8822c(_dev, _mem) \ + rtw_dump_fw(_dev, OCPBASE_ ## _mem ## _88XX, \ + FWCD_SIZE_ ## _mem ## _8822C, RTW_FWCD_ ## _mem) + int ret; + + ret = rtw_dump_reg(rtwdev, 0x0, FWCD_SIZE_REG_8822C); + if (ret) + return ret; + ret = __dump_fw_8822c(rtwdev, DMEM); + if (ret) + return ret; + ret = __dump_fw_8822c(rtwdev, IMEM); + if (ret) + return ret; + ret = __dump_fw_8822c(rtwdev, EMEM); + if (ret) + return ret; + ret = __dump_fw_8822c(rtwdev, ROM); + if (ret) + return ret; + + return 0; + +#undef __dump_fw_8822c +} + +static void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable) +{ + if (enable) { + rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x1); + rtw_write32_mask(rtwdev, REG_ANAPAR_A, BIT_ANAPAR_UPDATE, 0x1); + rtw_write32_mask(rtwdev, REG_ANAPAR_B, BIT_ANAPAR_UPDATE, 0x1); + } else { + rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x0); + } +} + +static void rtw8822c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_BAND_2G (0) +#define RF18_BAND_5G (BIT(16) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF18_RFSI_GE_CH80 (BIT(17)) +#define RF18_RFSI_GT_CH140 (BIT(18)) +#define RF18_BW_MASK (BIT(13) | BIT(12)) +#define RF18_BW_20M (BIT(13) | BIT(12)) +#define RF18_BW_40M (BIT(13)) +#define RF18_BW_80M (BIT(12)) + + u32 rf_reg18 = 0; + u32 rf_rxbb = 0; + + rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); + + rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | + RF18_BW_MASK); + + rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (channel & RF18_CHANNEL_MASK); + if (IS_CH_5G_BAND_4(channel)) + rf_reg18 |= RF18_RFSI_GT_CH140; + else if (IS_CH_5G_BAND_3(channel)) + rf_reg18 |= RF18_RFSI_GE_CH80; + + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rf_reg18 |= RF18_BW_20M; + rf_rxbb = 0x18; + break; + case RTW_CHANNEL_WIDTH_40: + /* RF bandwidth */ + rf_reg18 |= RF18_BW_40M; + rf_rxbb = 0x10; + break; + case RTW_CHANNEL_WIDTH_80: + rf_reg18 |= RF18_BW_80M; + rf_rxbb = 0x8; + break; + } + + rtw8822c_rstb_3wire(rtwdev, false); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x01); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, 0x1f, 0x12); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, 0xfffff, rf_rxbb); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x00); + + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x01); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWA, 0x1f, 0x12); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWD0, 0xfffff, rf_rxbb); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x00); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_reg18); + rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_reg18); + + rtw8822c_rstb_3wire(rtwdev, true); +} + +static void rtw8822c_toggle_igi(struct rtw_dev *rtwdev) +{ + u32 igi; + + igi = rtw_read32_mask(rtwdev, REG_RXIGI, 0x7f); + rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi - 2); + rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi - 2); + rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi); + rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi); +} + +static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + if (IS_CH_2G_BAND(channel)) { + rtw_write32_clr(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); + rtw_write32_set(rtwdev, REG_TXF4, BIT(20)); + rtw_write32_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + rtw_write32_clr(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); + rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0xF); + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, + 0x5); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, + 0x5); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x6); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x6); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, + 0x4); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, + 0x4); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x0); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x0); + break; + } + if (channel == 13 || channel == 14) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x969); + else if (channel == 11 || channel == 12) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x96a); + else + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x9aa); + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x3da0); + rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, + 0x4962c931); + rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x6aa3); + rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xaa7b); + rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xf3d7); + rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 0x0); + rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, + 0xff012455); + rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 0xffff); + } else { + rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x5284); + rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, + 0x3e18fec8); + rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x0a88); + rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xacc4); + rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xc8b2); + rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, + 0x00faf0de); + rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, + 0x00122344); + rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, + 0x0fffffff); + } + if (channel == 13) + rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); + else + rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x1); + } else if (IS_CH_5G_BAND(channel)) { + rtw_write32_set(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); + rtw_write32_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + rtw_write32_set(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); + rtw_write32_clr(rtwdev, REG_TXF4, BIT(20)); + rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22); + rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); + if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x1); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x1); + } else if (IS_CH_5G_BAND_3(channel)) { + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x2); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x2); + } else if (IS_CH_5G_BAND_4(channel)) { + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x3); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x3); + } + + if (channel >= 36 && channel <= 51) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x494); + else if (channel >= 52 && channel <= 55) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x493); + else if (channel >= 56 && channel <= 111) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x453); + else if (channel >= 112 && channel <= 119) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x452); + else if (channel >= 120 && channel <= 172) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x412); + else if (channel >= 173 && channel <= 177) + rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x411); + } + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x19B); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x0); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x7); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x6); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4), + (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x5); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, + (primary_ch_idx | (primary_ch_idx << 4))); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x1); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0xa); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, + (primary_ch_idx | (primary_ch_idx << 4))); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x6); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); + break; + case RTW_CHANNEL_WIDTH_5: + rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x1); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x4); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x4); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); + break; + case RTW_CHANNEL_WIDTH_10: + rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); + rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x2); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x6); + rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x5); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); + break; + } +} + +static void rtw8822c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + rtw8822c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8822c_set_channel_rf(rtwdev, channel, bw); + rtw8822c_toggle_igi(rtwdev); +} + +static void rtw8822c_config_cck_rx_path(struct rtw_dev *rtwdev, u8 rx_path) +{ + if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x0); + rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x0); + } else if (rx_path == BB_PATH_AB) { + rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x1); + rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x1); + } + + if (rx_path == BB_PATH_A) + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x0); + else if (rx_path == BB_PATH_B) + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x5); + else if (rx_path == BB_PATH_AB) + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x1); +} + +static void rtw8822c_config_ofdm_rx_path(struct rtw_dev *rtwdev, u8 rx_path) +{ + if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x0); + rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x0); + rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x0); + rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x0); + rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x0); + } else if (rx_path == BB_PATH_AB) { + rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x1); + rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x1); + rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x1); + rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x1); + rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x1); + } + + rtw_write32_mask(rtwdev, 0x824, 0x0f000000, rx_path); + rtw_write32_mask(rtwdev, 0x824, 0x000f0000, rx_path); +} + +static void rtw8822c_config_rx_path(struct rtw_dev *rtwdev, u8 rx_path) +{ + rtw8822c_config_cck_rx_path(rtwdev, rx_path); + rtw8822c_config_ofdm_rx_path(rtwdev, rx_path); +} + +static void rtw8822c_config_cck_tx_path(struct rtw_dev *rtwdev, u8 tx_path, + bool is_tx2_path) +{ + if (tx_path == BB_PATH_A) { + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); + } else if (tx_path == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x4); + } else { + if (is_tx2_path) + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0xc); + else + rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); + } + rtw8822c_bb_reset(rtwdev); +} + +static void rtw8822c_config_ofdm_tx_path(struct rtw_dev *rtwdev, u8 tx_path, + enum rtw_bb_path tx_path_sel_1ss) +{ + if (tx_path == BB_PATH_A) { + rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x11); + rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); + } else if (tx_path == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x12); + rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); + } else { + if (tx_path_sel_1ss == BB_PATH_AB) { + rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x33); + rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0404); + } else if (tx_path_sel_1ss == BB_PATH_B) { + rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x32); + rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); + } else if (tx_path_sel_1ss == BB_PATH_A) { + rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x31); + rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); + } + } + rtw8822c_bb_reset(rtwdev); +} + +static void rtw8822c_config_tx_path(struct rtw_dev *rtwdev, u8 tx_path, + enum rtw_bb_path tx_path_sel_1ss, + enum rtw_bb_path tx_path_cck, + bool is_tx2_path) +{ + rtw8822c_config_cck_tx_path(rtwdev, tx_path_cck, is_tx2_path); + rtw8822c_config_ofdm_tx_path(rtwdev, tx_path, tx_path_sel_1ss); + rtw8822c_bb_reset(rtwdev); +} + +static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path) +{ + if ((tx_path | rx_path) & BB_PATH_A) + rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x33312); + else + rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x11111); + if ((tx_path | rx_path) & BB_PATH_B) + rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x33312); + else + rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x11111); + + rtw8822c_config_rx_path(rtwdev, rx_path); + rtw8822c_config_tx_path(rtwdev, tx_path, BB_PATH_A, BB_PATH_A, + is_tx2_path); + + rtw8822c_toggle_igi(rtwdev); +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 l_bnd, u_bnd; + u8 gain_a, gain_b; + s8 rx_power[RTW_RF_PATH_MAX]; + s8 min_rx_power = -120; + u8 rssi; + u8 channel; + int path; + + rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status); + rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status); + l_bnd = dm_info->cck_gi_l_bnd; + u_bnd = dm_info->cck_gi_u_bnd; + gain_a = GET_PHY_STAT_P0_GAIN_A(phy_status); + gain_b = GET_PHY_STAT_P0_GAIN_B(phy_status); + if (gain_a < l_bnd) + rx_power[RF_PATH_A] += (l_bnd - gain_a) << 1; + else if (gain_a > u_bnd) + rx_power[RF_PATH_A] -= (gain_a - u_bnd) << 1; + if (gain_b < l_bnd) + rx_power[RF_PATH_B] += (l_bnd - gain_b) << 1; + else if (gain_b > u_bnd) + rx_power[RF_PATH_B] -= (gain_b - u_bnd) << 1; + + rx_power[RF_PATH_A] -= 110; + rx_power[RF_PATH_B] -= 110; + + channel = GET_PHY_STAT_P0_CHANNEL(phy_status); + if (channel != 0) + rtw_set_rx_freq_band(pkt_stat, channel); + else + pkt_stat->channel_invalid = true; + + pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; + pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + } + + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_path_div *p_div = &rtwdev->dm_path_div; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 rxsc, bw; + s8 min_rx_power = -120; + s8 rx_evm; + u8 evm_dbm = 0; + u8 rssi; + int path; + u8 channel; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (rxsc == 0) + bw = rtwdev->hal.current_band_width; + else if (rxsc >= 1 && rxsc <= 8) + bw = RTW_CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) + bw = RTW_CHANNEL_WIDTH_40; + else + bw = RTW_CHANNEL_WIDTH_80; + + channel = GET_PHY_STAT_P1_CHANNEL(phy_status); + rtw_set_rx_freq_band(pkt_stat, channel); + + pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; + pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2); + pkt_stat->bw = bw; + pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], + pkt_stat->rx_power[RF_PATH_B], + min_rx_power); + + dm_info->curr_rx_rate = pkt_stat->rate; + + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); + + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); + + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + if (path == RF_PATH_A) { + p_div->path_a_sum += rssi; + p_div->path_a_cnt++; + } else if (path == RF_PATH_B) { + p_div->path_b_sum += rssi; + p_div->path_b_cnt++; + } + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; + + rx_evm = pkt_stat->rx_evm[path]; + + if (rx_evm < 0) { + if (rx_evm == S8_MIN) + evm_dbm = 0; + else + evm_dbm = ((u8)-rx_evm >> 1); + } + dm_info->rx_evm_dbm[path] = evm_dbm; + } + rtw_phy_parsing_cfo(rtwdev, pkt_stat); +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static void +rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, + u8 *tx_pwr_ref_ofdm) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 txref_cck[2] = {0x18a0, 0x41a0}; + u32 txref_ofdm[2] = {0x18e8, 0x41e8}; + u8 path; + + for (path = 0; path < hal->rf_path_num; path++) { + rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); + rtw_write32_mask(rtwdev, txref_cck[path], 0x7f0000, + tx_pwr_ref_cck[path]); + } + for (path = 0; path < hal->rf_path_num; path++) { + rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); + rtw_write32_mask(rtwdev, txref_ofdm[path], 0x1fc00, + tx_pwr_ref_ofdm[path]); + } +} + +static void rtw8822c_set_tx_power_diff(struct rtw_dev *rtwdev, u8 rate, + s8 *diff_idx) +{ + u32 offset_txagc = 0x3a00; + u8 rate_idx = rate & 0xfc; + u8 pwr_idx[4]; + u32 phy_pwr_idx; + int i; + + for (i = 0; i < 4; i++) + pwr_idx[i] = diff_idx[i] & 0x7f; + + phy_pwr_idx = pwr_idx[0] | + (pwr_idx[1] << 8) | + (pwr_idx[2] << 16) | + (pwr_idx[3] << 24); + + rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0x0); + rtw_write32_mask(rtwdev, offset_txagc + rate_idx, MASKDWORD, + phy_pwr_idx); +} + +static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 rs, rate, j; + u8 pwr_ref_cck[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATE11M], + hal->tx_pwr_tbl[RF_PATH_B][DESC_RATE11M]}; + u8 pwr_ref_ofdm[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATEMCS7], + hal->tx_pwr_tbl[RF_PATH_B][DESC_RATEMCS7]}; + s8 diff_a, diff_b; + u8 pwr_a, pwr_b; + s8 diff_idx[4]; + + rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; + pwr_b = hal->tx_pwr_tbl[RF_PATH_B][rate]; + if (rs == 0) { + diff_a = (s8)pwr_a - (s8)pwr_ref_cck[0]; + diff_b = (s8)pwr_b - (s8)pwr_ref_cck[1]; + } else { + diff_a = (s8)pwr_a - (s8)pwr_ref_ofdm[0]; + diff_b = (s8)pwr_b - (s8)pwr_ref_ofdm[1]; + } + diff_idx[rate % 4] = min(diff_a, diff_b); + if (rate % 4 == 3) + rtw8822c_set_tx_power_diff(rtwdev, rate - 3, + diff_idx); + } + } +} + +static int rtw8822c_set_antenna(struct rtw_dev *rtwdev, + int radio_idx, + u32 antenna_tx, + u32 antenna_rx) +{ + struct rtw_hal *hal = &rtwdev->hal; + + switch (antenna_tx) { + case BB_PATH_A: + case BB_PATH_B: + case BB_PATH_AB: + break; + default: + rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); + return -EINVAL; + } + + /* path B only is not available for RX */ + switch (antenna_rx) { + case BB_PATH_A: + case BB_PATH_AB: + break; + default: + rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); + return -EINVAL; + } + + hal->antenna_tx = antenna_tx; + hal->antenna_rx = antenna_rx; + + rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); + + return 0; +} + +static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_ANAPARLDO_POW_MAC); + ldo_pwr = enable ? ldo_pwr | BIT_LDOE25_PON : ldo_pwr & ~BIT_LDOE25_PON; + rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr); +} + +static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_enable; + u32 cck_fa_cnt; + u32 crc32_cnt; + u32 cca32_cnt; + u32 ofdm_fa_cnt; + u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; + u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, + fast_fsync, crc8_fail_vhta, mcs_fail_vht; + + cck_enable = rtw_read32(rtwdev, REG_ENCCK) & BIT_CCK_BLK_EN; + cck_fa_cnt = rtw_read16(rtwdev, REG_CCK_FACNT); + + ofdm_fa_cnt1 = rtw_read32(rtwdev, REG_OFDM_FACNT1); + ofdm_fa_cnt2 = rtw_read32(rtwdev, REG_OFDM_FACNT2); + ofdm_fa_cnt3 = rtw_read32(rtwdev, REG_OFDM_FACNT3); + ofdm_fa_cnt4 = rtw_read32(rtwdev, REG_OFDM_FACNT4); + ofdm_fa_cnt5 = rtw_read32(rtwdev, REG_OFDM_FACNT5); + + parity_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt1); + rate_illegal = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt2); + crc8_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt2); + crc8_fail_vhta = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt3); + mcs_fail = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt4); + mcs_fail_vht = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt4); + fast_fsync = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt5); + sb_search_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt5); + + ofdm_fa_cnt = parity_fail + rate_illegal + crc8_fail + crc8_fail_vhta + + mcs_fail + mcs_fail_vht + fast_fsync + sb_search_fail; + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0; + + crc32_cnt = rtw_read32(rtwdev, 0x2c04); + dm_info->cck_ok_cnt = crc32_cnt & 0xffff; + dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0x2c14); + dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff; + dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0x2c10); + dm_info->ht_ok_cnt = crc32_cnt & 0xffff; + dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + crc32_cnt = rtw_read32(rtwdev, 0x2c0c); + dm_info->vht_ok_cnt = crc32_cnt & 0xffff; + dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + + cca32_cnt = rtw_read32(rtwdev, 0x2c08); + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + + rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0); + rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2); + rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0); + rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 2); + + /* disable rx clk gating to reset counters */ + rtw_write32_clr(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); + rtw_write32_set(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); + rtw_write32_clr(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); + rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); +} + +static void rtw8822c_do_lck(struct rtw_dev *rtwdev) +{ + u32 val; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010); + rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA); + fsleep(1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001); + read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000, + true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8); + rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000); + fsleep(1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); +} + +static void rtw8822c_do_iqk(struct rtw_dev *rtwdev) +{ + struct rtw_iqk_para para = {0}; + u8 iqk_chk; + int ret; + + para.clear = 1; + rtw_fw_do_iqk(rtwdev, ¶); + + ret = read_poll_timeout(rtw_read8, iqk_chk, iqk_chk == IQK_DONE_8822C, + 20000, 300000, false, rtwdev, REG_RPT_CIP); + if (ret) + rtw_warn(rtwdev, "failed to poll iqk status bit\n"); + + rtw_write8(rtwdev, REG_IQKSTAT, 0x0); +} + +/* for coex */ +static void rtw8822c_coex_cfg_init(struct rtw_dev *rtwdev) +{ + /* enable TBTT nterrupt */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* BT report packet sample rate */ + /* 0x790[5:0]=0x5 */ + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); + + /* enable PTA (3-wire function form BT side) */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); + + /* enable PTA (tx/rx signal form WiFi side) */ + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); + /* wl tx signal to PTA not case EDCCA */ + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); + /* GNT_BT=1 while select both */ + rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); + /* BT_CCA = ~GNT_WL_BB, not or GNT_BT_BB, LTE_Rx */ + rtw_write8_clr(rtwdev, REG_DUMMY_PAGE4_V1, BIT_BTCCA_CTRL); + + /* to avoid RF parameter error */ + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODOPT, 0xfffff, 0x40000); +} + +static void rtw8822c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + u32 rf_0x1; + + if (coex_stat->gnt_workaround_state == coex_stat->wl_coex_mode) + return; + + coex_stat->gnt_workaround_state = coex_stat->wl_coex_mode; + + if ((coex_stat->kt_ver == 0 && coex->under_5g) || coex->freerun) + rf_0x1 = 0x40021; + else + rf_0x1 = 0x40000; + + /* BT at S1 for Shared-Ant */ + if (efuse->share_ant) + rf_0x1 |= BIT(13); + + rtw_write_rf(rtwdev, RF_PATH_B, 0x1, 0xfffff, rf_0x1); + + /* WL-S0 2G RF TRX cannot be masked by GNT_BT + * enable "WLS0 BB chage RF mode if GNT_BT = 1" for shared-antenna type + * disable:0x1860[3] = 1, enable:0x1860[3] = 0 + * + * enable "DAC off if GNT_WL = 0" for non-shared-antenna + * disable 0x1c30[22] = 0, + * enable: 0x1c30[22] = 1, 0x1c38[12] = 0, 0x1c38[28] = 1 + */ + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + rtw_write8_mask(rtwdev, REG_ANAPAR + 2, + BIT_ANAPAR_BTPS >> 16, 0); + } else { + rtw_write8_mask(rtwdev, REG_ANAPAR + 2, + BIT_ANAPAR_BTPS >> 16, 1); + rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1, + BIT_DAC_OFF_ENABLE, 0); + rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3, + BIT_DAC_OFF_ENABLE, 1); + } + + /* disable WL-S1 BB chage RF mode if GNT_BT + * since RF TRx mask can do it + */ + rtw_write8_mask(rtwdev, REG_IGN_GNTBT4, + BIT_PI_IGNORE_GNT_BT, 1); + + /* disable WL-S0 BB chage RF mode if wifi is at 5G, + * or antenna path is separated + */ + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, + BIT_PI_IGNORE_GNT_BT, 1); + rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, + BIT_NOMASK_TXBT_ENABLE, 1); + } else if (coex_stat->wl_coex_mode == COEX_WLINK_5G || + coex->under_5g || !efuse->share_ant) { + if (coex_stat->kt_ver >= 3) { + rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, + BIT_PI_IGNORE_GNT_BT, 0); + rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, + BIT_NOMASK_TXBT_ENABLE, 1); + } else { + rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, + BIT_PI_IGNORE_GNT_BT, 1); + } + } else { + /* shared-antenna */ + rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, + BIT_PI_IGNORE_GNT_BT, 0); + if (coex_stat->kt_ver >= 3) { + rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, + BIT_NOMASK_TXBT_ENABLE, 0); + } + } +} + +static void rtw8822c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0); + rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0); + rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0); +} + +static void rtw8822c_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + struct rtw_efuse *efuse = &rtwdev->efuse; + + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_exist = false; + coex_rfe->ant_switch_with_bt = false; + coex_rfe->ant_switch_diversity = false; + + if (efuse->share_ant) + coex_rfe->wlg_at_btg = true; + else + coex_rfe->wlg_at_btg = false; + + /* disable LTE coex in wifi side */ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); +} + +static void rtw8822c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; +} + +static void rtw8822c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + + if (low_gain == coex_dm->cur_wl_rx_low_gain_en) + return; + + coex_dm->cur_wl_rx_low_gain_en = low_gain; + + if (coex_dm->cur_wl_rx_low_gain_en) { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n"); + + /* set Rx filter corner RCK offset */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x22); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x36); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x22); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x36); + + } else { + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n"); + + /* set Rx filter corner RCK offset */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x20); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x20); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x0); + } +} + +static void rtw8822c_bf_enable_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + u8 csi_rsc = 0; + u32 tmp6dc; + + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + + tmp6dc = rtw_read32(rtwdev, REG_BBPSF_CTRL) | + BIT_WMAC_USE_NDPARATE | + (csi_rsc << 13); + if (vif->net_type == RTW_NET_AP_MODE) + rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc | BIT(12)); + else + rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc & ~BIT(12)); + + rtw_write32(rtwdev, REG_CSI_RRSR, 0x550); +} + +static void rtw8822c_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw8822c_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8822c_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8822c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8822c_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8822c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + +struct dpk_cfg_pair { + u32 addr; + u32 bitmask; + u32 data; +}; + +void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev, + const struct rtw_table *tbl) +{ + const struct dpk_cfg_pair *p = tbl->data; + const struct dpk_cfg_pair *end = p + tbl->size / 3; + + BUILD_BUG_ON(sizeof(struct dpk_cfg_pair) != sizeof(u32) * 3); + + for (; p < end; p++) + rtw_write32_mask(rtwdev, p->addr, p->bitmask, p->data); +} + +static void rtw8822c_dpk_set_gnt_wl(struct rtw_dev *rtwdev, bool is_before_k) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + + if (is_before_k) { + dpk_info->gnt_control = rtw_read32(rtwdev, 0x70); + dpk_info->gnt_value = rtw_coex_read_indirect_reg(rtwdev, 0x38); + rtw_write32_mask(rtwdev, 0x70, BIT(26), 0x1); + rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKBYTE1, 0x77); + } else { + rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKDWORD, + dpk_info->gnt_value); + rtw_write32(rtwdev, 0x70, dpk_info->gnt_control); + } +} + +static void +rtw8822c_dpk_restore_registers(struct rtw_dev *rtwdev, u32 reg_num, + struct rtw_backup_info *bckp) +{ + rtw_restore_reg(rtwdev, bckp, reg_num); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0x4); +} + +static void +rtw8822c_dpk_backup_registers(struct rtw_dev *rtwdev, u32 *reg, + u32 reg_num, struct rtw_backup_info *bckp) +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + bckp[i].len = 4; + bckp[i].reg = reg[i]; + bckp[i].val = rtw_read32(rtwdev, reg[i]); + } +} + +static void rtw8822c_dpk_backup_rf_registers(struct rtw_dev *rtwdev, + u32 *rf_reg, + u32 rf_reg_bak[][2]) +{ + u32 i; + + for (i = 0; i < DPK_RF_REG_NUM; i++) { + rf_reg_bak[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A, + rf_reg[i], RFREG_MASK); + rf_reg_bak[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B, + rf_reg[i], RFREG_MASK); + } +} + +static void rtw8822c_dpk_reload_rf_registers(struct rtw_dev *rtwdev, + u32 *rf_reg, + u32 rf_reg_bak[][2]) +{ + u32 i; + + for (i = 0; i < DPK_RF_REG_NUM; i++) { + rtw_write_rf(rtwdev, RF_PATH_A, rf_reg[i], RFREG_MASK, + rf_reg_bak[i][RF_PATH_A]); + rtw_write_rf(rtwdev, RF_PATH_B, rf_reg[i], RFREG_MASK, + rf_reg_bak[i][RF_PATH_B]); + } +} + +static void rtw8822c_dpk_information(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u32 reg; + u8 band_shift; + + reg = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); + + band_shift = FIELD_GET(BIT(16), reg); + dpk_info->dpk_band = 1 << band_shift; + dpk_info->dpk_ch = FIELD_GET(0xff, reg); + dpk_info->dpk_bw = FIELD_GET(0x3000, reg); +} + +static void rtw8822c_dpk_rxbb_dc_cal(struct rtw_dev *rtwdev, u8 path) +{ + rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); + udelay(5); + rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84801); + usleep_range(600, 610); + rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); +} + +static u8 rtw8822c_dpk_dc_corr_check(struct rtw_dev *rtwdev, u8 path) +{ + u16 dc_i, dc_q; + u8 corr_idx; + + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000900f0); + dc_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); + dc_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(11, 0)); + + if (dc_i & BIT(11)) + dc_i = 0x1000 - dc_i; + if (dc_q & BIT(11)) + dc_q = 0x1000 - dc_q; + + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); + corr_idx = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(7, 0)); + rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(15, 8)); + + if (dc_i > 200 || dc_q > 200 || corr_idx < 40 || corr_idx > 65) + return 1; + else + return 0; + +} + +static void rtw8822c_dpk_tx_pause(struct rtw_dev *rtwdev) +{ + u8 reg_a, reg_b; + u16 count = 0; + + rtw_write8(rtwdev, 0x522, 0xff); + rtw_write32_mask(rtwdev, 0x1e70, 0xf, 0x2); + + do { + reg_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 0x00, 0xf0000); + reg_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 0x00, 0xf0000); + udelay(2); + count++; + } while ((reg_a == 2 || reg_b == 2) && count < 2500); +} + +static void rtw8822c_dpk_mac_bb_setting(struct rtw_dev *rtwdev) +{ + rtw8822c_dpk_tx_pause(rtwdev); + rtw_load_table(rtwdev, &rtw8822c_dpk_mac_bb_tbl); +} + +static void rtw8822c_dpk_afe_setting(struct rtw_dev *rtwdev, bool is_do_dpk) +{ + if (is_do_dpk) + rtw_load_table(rtwdev, &rtw8822c_dpk_afe_is_dpk_tbl); + else + rtw_load_table(rtwdev, &rtw8822c_dpk_afe_no_dpk_tbl); +} + +static void rtw8822c_dpk_pre_setting(struct rtw_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_write_rf(rtwdev, path, RF_RXAGC_OFFSET, RFREG_MASK, 0x0); + rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); + if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) + rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); + else + rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); + rtw_write32_mask(rtwdev, REG_DPD_LUT0, BIT_GLOSS_DB, 0x4); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x3); + } + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + rtw_write32(rtwdev, REG_DPD_CTL11, 0x3b23170b); + rtw_write32(rtwdev, REG_DPD_CTL12, 0x775f5347); +} + +static u32 rtw8822c_dpk_rf_setting(struct rtw_dev *rtwdev, u8 path) +{ + u32 ori_txbb; + + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50017); + ori_txbb = rtw_read_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK); + + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_PWR_TRIM, 0x1); + rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_BB_GAIN, 0x0); + rtw_write_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK, ori_txbb); + + if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) { + rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x1); + rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x0); + } else { + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x0); + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x6); + rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); + rtw_write_rf(rtwdev, path, RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0); + } + + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); + rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); + + if (rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80) + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x2); + else + rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); + + rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT(1), 0x1); + + usleep_range(100, 110); + + return ori_txbb & 0x1f; +} + +static u16 rtw8822c_dpk_get_cmd(struct rtw_dev *rtwdev, u8 action, u8 path) +{ + u16 cmd; + u8 bw = rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80 ? 2 : 0; + + switch (action) { + case RTW_DPK_GAIN_LOSS: + cmd = 0x14 + path; + break; + case RTW_DPK_DO_DPK: + cmd = 0x16 + path + bw; + break; + case RTW_DPK_DPK_ON: + cmd = 0x1a + path; + break; + case RTW_DPK_DAGC: + cmd = 0x1c + path + bw; + break; + default: + return 0; + } + + return (cmd << 8) | 0x48; +} + +static u8 rtw8822c_dpk_one_shot(struct rtw_dev *rtwdev, u8 path, u8 action) +{ + u16 dpk_cmd; + u8 result = 0; + + rtw8822c_dpk_set_gnt_wl(rtwdev, true); + + if (action == RTW_DPK_CAL_PWR) { + rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x1); + rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x0); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); + fsleep(10000); + if (!check_hw_ready(rtwdev, REG_STAT_RPT, BIT(31), 0x1)) { + result = 1; + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); + } + } else { + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, + 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); + + dpk_cmd = rtw8822c_dpk_get_cmd(rtwdev, action, path); + rtw_write32(rtwdev, REG_NCTL0, dpk_cmd); + rtw_write32(rtwdev, REG_NCTL0, dpk_cmd + 1); + fsleep(10000); + if (!check_hw_ready(rtwdev, 0x2d9c, 0xff, 0x55)) { + result = 1; + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); + } + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, + 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); + } + + rtw8822c_dpk_set_gnt_wl(rtwdev, false); + + rtw_write8(rtwdev, 0x1b10, 0x0); + + return result; +} + +static u16 rtw8822c_dpk_dgain_read(struct rtw_dev *rtwdev, u8 path) +{ + u16 dgain; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, 0x00ff0000, 0x0); + + dgain = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); + + return dgain; +} + +static u8 rtw8822c_dpk_thermal_read(struct rtw_dev *rtwdev, u8 path) +{ + rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); + rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x0); + rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); + udelay(15); + + return (u8)rtw_read_rf(rtwdev, path, RF_T_METER, 0x0007e); +} + +static u32 rtw8822c_dpk_pas_read(struct rtw_dev *rtwdev, u8 path) +{ + u32 i_val, q_val; + + rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060001); + rtw_write32(rtwdev, 0x1b4c, 0x00000000); + rtw_write32(rtwdev, 0x1b4c, 0x00080000); + + q_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD); + i_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD); + + if (i_val & BIT(15)) + i_val = 0x10000 - i_val; + if (q_val & BIT(15)) + q_val = 0x10000 - q_val; + + rtw_write32(rtwdev, 0x1b4c, 0x00000000); + + return i_val * i_val + q_val * q_val; +} + +static u32 rtw8822c_psd_log2base(u32 val) +{ + u32 tmp, val_integerd_b, tindex; + u32 result, val_fractiond_b; + u32 table_fraction[21] = {0, 432, 332, 274, 232, 200, 174, + 151, 132, 115, 100, 86, 74, 62, 51, + 42, 32, 23, 15, 7, 0}; + + if (val == 0) + return 0; + + val_integerd_b = __fls(val) + 1; + + tmp = (val * 100) / (1 << val_integerd_b); + tindex = tmp / 5; + + if (tindex >= ARRAY_SIZE(table_fraction)) + tindex = ARRAY_SIZE(table_fraction) - 1; + + val_fractiond_b = table_fraction[tindex]; + + result = val_integerd_b * 100 - val_fractiond_b; + + return result; +} + +static u8 rtw8822c_dpk_gainloss_result(struct rtw_dev *rtwdev, u8 path) +{ + u8 result; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x1); + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060000); + + result = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, 0x000000f0); + + rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); + + return result; +} + +static u8 rtw8822c_dpk_agc_gain_chk(struct rtw_dev *rtwdev, u8 path, + u8 limited_pga) +{ + u8 result = 0; + u16 dgain; + + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); + dgain = rtw8822c_dpk_dgain_read(rtwdev, path); + + if (dgain > 1535 && !limited_pga) + return RTW_DPK_GAIN_LESS; + else if (dgain < 768 && !limited_pga) + return RTW_DPK_GAIN_LARGE; + else + return result; +} + +static u8 rtw8822c_dpk_agc_loss_chk(struct rtw_dev *rtwdev, u8 path) +{ + u32 loss, loss_db; + + loss = rtw8822c_dpk_pas_read(rtwdev, path); + if (loss < 0x4000000) + return RTW_DPK_GL_LESS; + loss_db = 3 * rtw8822c_psd_log2base(loss >> 13) - 3870; + + if (loss_db > 1000) + return RTW_DPK_GL_LARGE; + else if (loss_db < 250) + return RTW_DPK_GL_LESS; + else + return RTW_DPK_AGC_OUT; +} + +struct rtw8822c_dpk_data { + u8 txbb; + u8 pga; + u8 limited_pga; + u8 agc_cnt; + bool loss_only; + bool gain_only; + u8 path; +}; + +static u8 rtw8822c_gain_check_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + u8 state; + + data->txbb = (u8)rtw_read_rf(rtwdev, data->path, RF_TX_GAIN, + BIT_GAIN_TXBB); + data->pga = (u8)rtw_read_rf(rtwdev, data->path, RF_MODE_TRXAGC, + BIT_RXAGC); + + if (data->loss_only) { + state = RTW_DPK_LOSS_CHECK; + goto check_end; + } + + state = rtw8822c_dpk_agc_gain_chk(rtwdev, data->path, + data->limited_pga); + if (state == RTW_DPK_GAIN_CHECK && data->gain_only) + state = RTW_DPK_AGC_OUT; + else if (state == RTW_DPK_GAIN_CHECK) + state = RTW_DPK_LOSS_CHECK; + +check_end: + data->agc_cnt++; + if (data->agc_cnt >= 6) + state = RTW_DPK_AGC_OUT; + + return state; +} + +static u8 rtw8822c_gain_large_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + u8 pga = data->pga; + + if (pga > 0xe) + rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); + else if (pga > 0xb && pga < 0xf) + rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0); + else if (pga < 0xc) + data->limited_pga = 1; + + return RTW_DPK_GAIN_CHECK; +} + +static u8 rtw8822c_gain_less_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + u8 pga = data->pga; + + if (pga < 0xc) + rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); + else if (pga > 0xb && pga < 0xf) + rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); + else if (pga > 0xe) + data->limited_pga = 1; + + return RTW_DPK_GAIN_CHECK; +} + +static u8 rtw8822c_gl_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data, u8 is_large) +{ + u8 txbb_bound[] = {0x1f, 0}; + + if (data->txbb == txbb_bound[is_large]) + return RTW_DPK_AGC_OUT; + + if (is_large == 1) + data->txbb -= 2; + else + data->txbb += 3; + + rtw_write_rf(rtwdev, data->path, RF_TX_GAIN, BIT_GAIN_TXBB, data->txbb); + data->limited_pga = 0; + + return RTW_DPK_GAIN_CHECK; +} + +static u8 rtw8822c_gl_large_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + return rtw8822c_gl_state(rtwdev, data, 1); +} + +static u8 rtw8822c_gl_less_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + return rtw8822c_gl_state(rtwdev, data, 0); +} + +static u8 rtw8822c_loss_check_state(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) +{ + u8 path = data->path; + u8 state; + + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_GAIN_LOSS); + state = rtw8822c_dpk_agc_loss_chk(rtwdev, path); + + return state; +} + +static u8 (*dpk_state[])(struct rtw_dev *rtwdev, + struct rtw8822c_dpk_data *data) = { + rtw8822c_gain_check_state, rtw8822c_gain_large_state, + rtw8822c_gain_less_state, rtw8822c_gl_large_state, + rtw8822c_gl_less_state, rtw8822c_loss_check_state }; + +static u8 rtw8822c_dpk_pas_agc(struct rtw_dev *rtwdev, u8 path, + bool gain_only, bool loss_only) +{ + struct rtw8822c_dpk_data data = {0}; + u8 (*func)(struct rtw_dev *rtwdev, struct rtw8822c_dpk_data *data); + u8 state = RTW_DPK_GAIN_CHECK; + + data.loss_only = loss_only; + data.gain_only = gain_only; + data.path = path; + + for (;;) { + func = dpk_state[state]; + state = func(rtwdev, &data); + if (state == RTW_DPK_AGC_OUT) + break; + } + + return data.txbb; +} + +static bool rtw8822c_dpk_coef_iq_check(struct rtw_dev *rtwdev, + u16 coef_i, u16 coef_q) +{ + if (coef_i == 0x1000 || coef_i == 0x0fff || + coef_q == 0x1000 || coef_q == 0x0fff) + return true; + + return false; +} + +static u32 rtw8822c_dpk_coef_transfer(struct rtw_dev *rtwdev) +{ + u32 reg = 0; + u16 coef_i = 0, coef_q = 0; + + reg = rtw_read32(rtwdev, REG_STAT_RPT); + + coef_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD) & 0x1fff; + coef_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD) & 0x1fff; + + coef_q = ((0x2000 - coef_q) & 0x1fff) - 1; + + reg = (coef_i << 16) | coef_q; + + return reg; +} + +static const u32 rtw8822c_dpk_get_coef_tbl[] = { + 0x000400f0, 0x040400f0, 0x080400f0, 0x010400f0, 0x050400f0, + 0x090400f0, 0x020400f0, 0x060400f0, 0x0a0400f0, 0x030400f0, + 0x070400f0, 0x0b0400f0, 0x0c0400f0, 0x100400f0, 0x0d0400f0, + 0x110400f0, 0x0e0400f0, 0x120400f0, 0x0f0400f0, 0x130400f0, +}; + +static void rtw8822c_dpk_coef_tbl_apply(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + int i; + + for (i = 0; i < 20; i++) { + rtw_write32(rtwdev, REG_RXSRAM_CTL, + rtw8822c_dpk_get_coef_tbl[i]); + dpk_info->coef[path][i] = rtw8822c_dpk_coef_transfer(rtwdev); + } +} + +static void rtw8822c_dpk_get_coef(struct rtw_dev *rtwdev, u8 path) +{ + rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); + + if (path == RF_PATH_A) { + rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x0); + rtw_write32(rtwdev, REG_DPD_CTL0_S0, 0x30000080); + } else if (path == RF_PATH_B) { + rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x1); + rtw_write32(rtwdev, REG_DPD_CTL0_S1, 0x30000080); + } + + rtw8822c_dpk_coef_tbl_apply(rtwdev, path); +} + +static u8 rtw8822c_dpk_coef_read(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 addr, result = 1; + u16 coef_i, coef_q; + + for (addr = 0; addr < 20; addr++) { + coef_i = FIELD_GET(0x1fff0000, dpk_info->coef[path][addr]); + coef_q = FIELD_GET(0x1fff, dpk_info->coef[path][addr]); + + if (rtw8822c_dpk_coef_iq_check(rtwdev, coef_i, coef_q)) { + result = 0; + break; + } + } + return result; +} + +static void rtw8822c_dpk_coef_write(struct rtw_dev *rtwdev, u8 path, u8 result) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u16 reg[DPK_RF_PATH_NUM] = {0x1b0c, 0x1b64}; + u32 coef; + u8 addr; + + rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); + + for (addr = 0; addr < 20; addr++) { + if (result == 0) { + if (addr == 3) + coef = 0x04001fff; + else + coef = 0x00001fff; + } else { + coef = dpk_info->coef[path][addr]; + } + rtw_write32(rtwdev, reg[path] + addr * 4, coef); + } +} + +static void rtw8822c_dpk_fill_result(struct rtw_dev *rtwdev, u32 dpk_txagc, + u8 path, u8 result) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + + if (result) + rtw_write8(rtwdev, REG_DPD_AGC, (u8)(dpk_txagc - 6)); + else + rtw_write8(rtwdev, REG_DPD_AGC, 0x00); + + dpk_info->result[path] = result; + dpk_info->dpk_txagc[path] = rtw_read8(rtwdev, REG_DPD_AGC); + + rtw8822c_dpk_coef_write(rtwdev, path, result); +} + +static u32 rtw8822c_dpk_gainloss(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 tx_agc, tx_bb, ori_txbb, ori_txagc, tx_agc_search, t1, t2; + + ori_txbb = rtw8822c_dpk_rf_setting(rtwdev, path); + ori_txagc = (u8)rtw_read_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_TXAGC); + + rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); + rtw8822c_dpk_dgain_read(rtwdev, path); + + if (rtw8822c_dpk_dc_corr_check(rtwdev, path)) { + rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); + rtw8822c_dpk_dc_corr_check(rtwdev, path); + } + + t1 = rtw8822c_dpk_thermal_read(rtwdev, path); + tx_bb = rtw8822c_dpk_pas_agc(rtwdev, path, false, true); + tx_agc_search = rtw8822c_dpk_gainloss_result(rtwdev, path); + + if (tx_bb < tx_agc_search) + tx_bb = 0; + else + tx_bb = tx_bb - tx_agc_search; + + rtw_write_rf(rtwdev, path, RF_TX_GAIN, BIT_GAIN_TXBB, tx_bb); + + tx_agc = ori_txagc - (ori_txbb - tx_bb); + + t2 = rtw8822c_dpk_thermal_read(rtwdev, path); + + dpk_info->thermal_dpk_delta[path] = abs(t2 - t1); + + return tx_agc; +} + +static u8 rtw8822c_dpk_by_path(struct rtw_dev *rtwdev, u32 tx_agc, u8 path) +{ + u8 result; + + result = rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DO_DPK); + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + + result = result | (u8)rtw_read32_mask(rtwdev, REG_DPD_CTL1_S0, BIT(26)); + + rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x33e14); + + rtw8822c_dpk_get_coef(rtwdev, path); + + return result; +} + +static void rtw8822c_dpk_cal_gs(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u32 tmp_gs = 0; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_BYPASS_DPD, 0x0); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x1); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0xf); + + if (path == RF_PATH_A) { + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, + 0x1066680); + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 0x1); + } else { + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, + 0x1066680); + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 0x1); + } + + if (dpk_info->dpk_bw == DPK_CHANNEL_WIDTH_80) { + rtw_write32(rtwdev, REG_DPD_CTL16, 0x80001310); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x00001310); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x810000db); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x010000db); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); + rtw_write32(rtwdev, REG_DPD_CTL15, + 0x05020000 | (BIT(path) << 28)); + } else { + rtw_write32(rtwdev, REG_DPD_CTL16, 0x8200190c); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x0200190c); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x8301ee14); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x0301ee14); + rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); + rtw_write32(rtwdev, REG_DPD_CTL15, + 0x05020008 | (BIT(path) << 28)); + } + + rtw_write32_mask(rtwdev, REG_DPD_CTL0, MASKBYTE3, 0x8 | path); + + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_CAL_PWR); + + rtw_write32_mask(rtwdev, REG_DPD_CTL15, MASKBYTE3, 0x0); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); + rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x0); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + + if (path == RF_PATH_A) + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 0x5b); + else + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 0x5b); + + rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); + + tmp_gs = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, BIT_RPT_DGAIN); + tmp_gs = (tmp_gs * 910) >> 10; + tmp_gs = DIV_ROUND_CLOSEST(tmp_gs, 10); + + if (path == RF_PATH_A) + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, tmp_gs); + else + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, tmp_gs); + + dpk_info->dpk_gs[path] = tmp_gs; +} + +static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u32 offset[DPK_RF_PATH_NUM] = {0, 0x58}; + u32 i_scaling; + u8 path; + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); + rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); + rtw_write32(rtwdev, REG_NCTL0, 0x00001148); + rtw_write32(rtwdev, REG_NCTL0, 0x00001149); + + if (!check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55)) + rtw_warn(rtwdev, "DPK stuck, performance may be suboptimal"); + + rtw_write8(rtwdev, 0x1b10, 0x0); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + i_scaling = 0x16c00 / dpk_info->dpk_gs[path]; + + rtw_write32_mask(rtwdev, 0x1b18 + offset[path], MASKHWORD, + i_scaling); + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], + GENMASK(31, 28), 0x9); + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], + GENMASK(31, 28), 0x1); + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], + GENMASK(31, 28), 0x0); + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0 + offset[path], + BIT(14), 0x0); + } +} + +static void rtw8822c_dpk_on(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); + + if (test_bit(path, dpk_info->dpk_path_ok)) + rtw8822c_dpk_cal_gs(rtwdev, path); +} + +static bool rtw8822c_dpk_check_pass(struct rtw_dev *rtwdev, bool is_fail, + u32 dpk_txagc, u8 path) +{ + bool result; + + if (!is_fail) { + if (rtw8822c_dpk_coef_read(rtwdev, path)) + result = true; + else + result = false; + } else { + result = false; + } + + rtw8822c_dpk_fill_result(rtwdev, dpk_txagc, path, result); + + return result; +} + +static void rtw8822c_dpk_result_reset(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 path; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + clear_bit(path, dpk_info->dpk_path_ok); + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, + 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, 0x1b58, 0x0000007f, 0x0); + + dpk_info->dpk_txagc[path] = 0; + dpk_info->result[path] = 0; + dpk_info->dpk_gs[path] = 0x5b; + dpk_info->pre_pwsf[path] = 0; + dpk_info->thermal_dpk[path] = rtw8822c_dpk_thermal_read(rtwdev, + path); + } +} + +static void rtw8822c_dpk_calibrate(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u32 dpk_txagc; + u8 dpk_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk start\n", path); + + dpk_txagc = rtw8822c_dpk_gainloss(rtwdev, path); + + dpk_fail = rtw8822c_dpk_by_path(rtwdev, dpk_txagc, path); + + if (!rtw8822c_dpk_check_pass(rtwdev, dpk_fail, dpk_txagc, path)) + rtw_err(rtwdev, "failed to do dpk calibration\n"); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk finish\n", path); + + if (dpk_info->result[path]) + set_bit(path, dpk_info->dpk_path_ok); +} + +static void rtw8822c_dpk_path_select(struct rtw_dev *rtwdev) +{ + rtw8822c_dpk_calibrate(rtwdev, RF_PATH_A); + rtw8822c_dpk_calibrate(rtwdev, RF_PATH_B); + rtw8822c_dpk_on(rtwdev, RF_PATH_A); + rtw8822c_dpk_on(rtwdev, RF_PATH_B); + rtw8822c_dpk_cal_coef1(rtwdev); +} + +static void rtw8822c_dpk_enable_disable(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u32 mask = BIT(15) | BIT(14); + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, + dpk_info->is_dpk_pwr_on); + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, + dpk_info->is_dpk_pwr_on); + + if (test_bit(RF_PATH_A, dpk_info->dpk_path_ok)) { + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, mask, 0x0); + rtw_write8(rtwdev, REG_DPD_CTL0_S0, dpk_info->dpk_gs[RF_PATH_A]); + } + if (test_bit(RF_PATH_B, dpk_info->dpk_path_ok)) { + rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, mask, 0x0); + rtw_write8(rtwdev, REG_DPD_CTL0_S1, dpk_info->dpk_gs[RF_PATH_B]); + } +} + +static void rtw8822c_dpk_reload_data(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 path; + + if (!test_bit(RF_PATH_A, dpk_info->dpk_path_ok) && + !test_bit(RF_PATH_B, dpk_info->dpk_path_ok) && + dpk_info->dpk_ch == 0) + return; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, + 0x8 | (path << 1)); + if (dpk_info->dpk_band == RTW_BAND_2G) + rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); + else + rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); + + rtw_write8(rtwdev, REG_DPD_AGC, dpk_info->dpk_txagc[path]); + + rtw8822c_dpk_coef_write(rtwdev, path, + test_bit(path, dpk_info->dpk_path_ok)); + + rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); + + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); + + if (path == RF_PATH_A) + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, + dpk_info->dpk_gs[path]); + else + rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, + dpk_info->dpk_gs[path]); + } + rtw8822c_dpk_cal_coef1(rtwdev); +} + +static bool rtw8822c_dpk_reload(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 channel; + + dpk_info->is_reload = false; + + channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK) & 0xff); + + if (channel == dpk_info->dpk_ch) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[DPK] DPK reload for CH%d!!\n", dpk_info->dpk_ch); + rtw8822c_dpk_reload_data(rtwdev); + dpk_info->is_reload = true; + } + + return dpk_info->is_reload; +} + +static void rtw8822c_do_dpk(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + struct rtw_backup_info bckp[DPK_BB_REG_NUM]; + u32 rf_reg_backup[DPK_RF_REG_NUM][DPK_RF_PATH_NUM]; + u32 bb_reg[DPK_BB_REG_NUM] = { + 0x520, 0x820, 0x824, 0x1c3c, 0x1d58, 0x1864, + 0x4164, 0x180c, 0x410c, 0x186c, 0x416c, + 0x1a14, 0x1e70, 0x80c, 0x1d70, 0x1e7c, 0x18a4, 0x41a4}; + u32 rf_reg[DPK_RF_REG_NUM] = { + 0x0, 0x1a, 0x55, 0x63, 0x87, 0x8f, 0xde}; + u8 path; + + if (!dpk_info->is_dpk_pwr_on) { + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] Skip DPK due to DPD PWR off\n"); + return; + } else if (rtw8822c_dpk_reload(rtwdev)) { + return; + } + + for (path = RF_PATH_A; path < DPK_RF_PATH_NUM; path++) + ewma_thermal_init(&dpk_info->avg_thermal[path]); + + rtw8822c_dpk_information(rtwdev); + + rtw8822c_dpk_backup_registers(rtwdev, bb_reg, DPK_BB_REG_NUM, bckp); + rtw8822c_dpk_backup_rf_registers(rtwdev, rf_reg, rf_reg_backup); + + rtw8822c_dpk_mac_bb_setting(rtwdev); + rtw8822c_dpk_afe_setting(rtwdev, true); + rtw8822c_dpk_pre_setting(rtwdev); + rtw8822c_dpk_result_reset(rtwdev); + rtw8822c_dpk_path_select(rtwdev); + rtw8822c_dpk_afe_setting(rtwdev, false); + rtw8822c_dpk_enable_disable(rtwdev); + + rtw8822c_dpk_reload_rf_registers(rtwdev, rf_reg, rf_reg_backup); + for (path = 0; path < rtwdev->hal.rf_path_num; path++) + rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); + rtw8822c_dpk_restore_registers(rtwdev, DPK_BB_REG_NUM, bckp); +} + +static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8822c_rfk_power_save(rtwdev, false); + rtw8822c_do_gapk(rtwdev); + rtw8822c_do_iqk(rtwdev); + rtw8822c_do_dpk(rtwdev); + rtw8822c_rfk_power_save(rtwdev, true); +} + +static void rtw8822c_dpk_track(struct rtw_dev *rtwdev) +{ + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + u8 path; + u8 thermal_value[DPK_RF_PATH_NUM] = {0}; + s8 offset[DPK_RF_PATH_NUM], delta_dpk[DPK_RF_PATH_NUM]; + + if (dpk_info->thermal_dpk[0] == 0 && dpk_info->thermal_dpk[1] == 0) + return; + + for (path = 0; path < DPK_RF_PATH_NUM; path++) { + thermal_value[path] = rtw8822c_dpk_thermal_read(rtwdev, path); + ewma_thermal_add(&dpk_info->avg_thermal[path], + thermal_value[path]); + thermal_value[path] = + ewma_thermal_read(&dpk_info->avg_thermal[path]); + delta_dpk[path] = dpk_info->thermal_dpk[path] - + thermal_value[path]; + offset[path] = delta_dpk[path] - + dpk_info->thermal_dpk_delta[path]; + offset[path] &= 0x7f; + + if (offset[path] != dpk_info->pre_pwsf[path]) { + rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, + 0x8 | (path << 1)); + rtw_write32_mask(rtwdev, 0x1b58, GENMASK(6, 0), + offset[path]); + dpk_info->pre_pwsf[path] = offset[path]; + } + } +} + +#define XCAP_EXTEND(val) ({typeof(val) _v = (val); _v | _v << 7; }) +static void rtw8822c_set_crystal_cap_reg(struct rtw_dev *rtwdev, u8 crystal_cap) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + u32 val = 0; + + val = XCAP_EXTEND(crystal_cap); + cfo->crystal_cap = crystal_cap; + rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, BIT_XCAP_0, val); +} + +static void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + + if (cfo->crystal_cap == crystal_cap) + return; + + rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap); +} + +static void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + + cfo->is_adjust = true; + + if (cfo->crystal_cap > rtwdev->efuse.crystal_cap) + rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1); + else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap) + rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1); +} + +static void rtw8822c_cfo_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + + cfo->crystal_cap = rtwdev->efuse.crystal_cap; + cfo->is_adjust = true; +} + +#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); }) +static s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum; + u8 i; + + for (i = 0; i < path_num; i++) { + cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]); + + if (cfo->cfo_cnt[i]) + cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i]; + else + cfo_avg = 0; + + cfo_path_sum += cfo_avg; + } + + for (i = 0; i < path_num; i++) { + cfo->cfo_tail[i] = 0; + cfo->cfo_cnt[i] = 0; + } + + return cfo_path_sum / path_num; +} + +static void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + + if (!cfo->is_adjust) { + if (abs(cfo_avg) > CFO_TRK_ENABLE_TH) + cfo->is_adjust = true; + } else { + if (abs(cfo_avg) <= CFO_TRK_STOP_TH) + cfo->is_adjust = false; + } + + if (!rtw_coex_disabled(rtwdev)) { + cfo->is_adjust = false; + rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); + } +} + +static void rtw8822c_cfo_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_cfo_track *cfo = &dm_info->cfo_track; + u8 path_num = rtwdev->hal.rf_path_num; + s8 crystal_cap = cfo->crystal_cap; + s32 cfo_avg = 0; + + if (rtwdev->sta_cnt != 1) { + rtw8822c_cfo_tracking_reset(rtwdev); + return; + } + + if (cfo->packet_count == cfo->packet_count_pre) + return; + + cfo->packet_count_pre = cfo->packet_count; + cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num); + rtw8822c_cfo_need_adjust(rtwdev, cfo_avg); + + if (cfo->is_adjust) { + if (cfo_avg > CFO_TRK_ADJ_TH) + crystal_cap++; + else if (cfo_avg < -CFO_TRK_ADJ_TH) + crystal_cap--; + + crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK); + rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap); + } +} + +static const struct rtw_phy_cck_pd_reg +rtw8822c_cck_pd_reg[RTW_CHANNEL_WIDTH_40 + 1][RTW_RF_PATH_MAX] = { + { + {0x1ac8, 0x00ff, 0x1ad0, 0x01f}, + {0x1ac8, 0xff00, 0x1ad0, 0x3e0} + }, + { + {0x1acc, 0x00ff, 0x1ad0, 0x01F00000}, + {0x1acc, 0xff00, 0x1ad0, 0x3E000000} + }, +}; + +#define RTW_CCK_PD_MAX 255 +#define RTW_CCK_CS_MAX 31 +#define RTW_CCK_CS_ERR1 27 +#define RTW_CCK_CS_ERR2 29 +static void +rtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev, + s8 pd_diff, s8 cs_diff, u8 bw, u8 nrx) +{ + u32 pd, cs; + + if (WARN_ON(bw > RTW_CHANNEL_WIDTH_40 || nrx >= RTW_RF_PATH_MAX)) + return; + + pd = rtw_read32_mask(rtwdev, + rtw8822c_cck_pd_reg[bw][nrx].reg_pd, + rtw8822c_cck_pd_reg[bw][nrx].mask_pd); + cs = rtw_read32_mask(rtwdev, + rtw8822c_cck_pd_reg[bw][nrx].reg_cs, + rtw8822c_cck_pd_reg[bw][nrx].mask_cs); + pd += pd_diff; + cs += cs_diff; + if (pd > RTW_CCK_PD_MAX) + pd = RTW_CCK_PD_MAX; + if (cs == RTW_CCK_CS_ERR1 || cs == RTW_CCK_CS_ERR2) + cs++; + else if (cs > RTW_CCK_CS_MAX) + cs = RTW_CCK_CS_MAX; + rtw_write32_mask(rtwdev, + rtw8822c_cck_pd_reg[bw][nrx].reg_pd, + rtw8822c_cck_pd_reg[bw][nrx].mask_pd, + pd); + rtw_write32_mask(rtwdev, + rtw8822c_cck_pd_reg[bw][nrx].reg_cs, + rtw8822c_cck_pd_reg[bw][nrx].mask_cs, + cs); + + rtw_dbg(rtwdev, RTW_DBG_PHY, + "is_linked=%d, bw=%d, nrx=%d, cs_ratio=0x%x, pd_th=0x%x\n", + rtw_is_assoc(rtwdev), bw, nrx, cs, pd); +} + +static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8}; + s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4}; + u8 cur_lvl; + u8 nrx, bw; + + nrx = (u8)rtw_read32_mask(rtwdev, 0x1a2c, 0x60000); + bw = (u8)rtw_read32_mask(rtwdev, 0x9b0, 0xc); + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d) bw=%d nr=%d cck_fa_avg=%d\n", + dm_info->cck_pd_lv[bw][nrx], new_lvl, bw, nrx, + dm_info->cck_fa_avg); + + if (dm_info->cck_pd_lv[bw][nrx] == new_lvl) + return; + + cur_lvl = dm_info->cck_pd_lv[bw][nrx]; + + /* update cck pd info */ + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + + rtw8822c_phy_cck_pd_set_reg(rtwdev, + pd_lvl[new_lvl] - pd_lvl[cur_lvl], + cs_lvl[new_lvl] - cs_lvl[cur_lvl], + bw, nrx); + dm_info->cck_pd_lv[bw][nrx] = new_lvl; +} + +#define PWR_TRACK_MASK 0x7f +static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + switch (rf_path) { + case RF_PATH_A: + rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK, + dm_info->delta_power_index[rf_path]); + break; + case RF_PATH_B: + rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK, + dm_info->delta_power_index[rf_path]); + break; + default: + break; + } +} + +static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path) +{ + u8 thermal_value; + + if (rtwdev->efuse.thermal_meter[path] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); +} + +static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 delta; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); + dm_info->delta_power_index[path] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, + delta); + rtw8822c_pwrtrack_set(rtwdev, path); +} + +static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_swing_table swing_table; + u8 i; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + for (i = 0; i < rtwdev->hal.rf_path_num; i++) + rtw8822c_pwr_track_stats(rtwdev, i); + if (rtw_phy_pwrtrack_need_lck(rtwdev)) + rtw8822c_do_lck(rtwdev); + for (i = 0; i < rtwdev->hal.rf_path_num; i++) + rtw8822c_pwr_track_path(rtwdev, &swing_table, i); +} + +static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00); + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); + + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00); + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); + + dm_info->pwr_trk_triggered = true; + return; + } + + __rtw8822c_pwr_track(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev) +{ + rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX); + + /* mac edcca state setting */ + rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA); + rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN); + + /* edcca decistion opt */ + rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION); +} + +static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 l2h, h2l; + u8 igi; + + igi = dm_info->igi_history[0]; + if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { + l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); + h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; + } else { + if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF) + l2h = igi + EDCCA_ADC_BACKOFF; + else + l2h = dm_info->l2h_th_ini; + h2l = l2h - EDCCA_L2H_H2L_DIFF; + } + + rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +} + +static void rtw8822c_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + size_t words; + + words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2; + + fill_txdesc_checksum_common(txdesc, words); +} + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x002E, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x002D, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x007F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822c[] = { + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0xFF1A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x002E, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x1018, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0074, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0071, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), + (BIT(7) | BIT(6) | BIT(5))}, + {0x0061, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, + {0x00EF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, + {0x1045, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x1064, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822c[] = { + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x00EF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x1045, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0xFF1A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x30}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, + {0x0090, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0092, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = { + trans_carddis_to_cardemu_8822c, + trans_cardemu_to_act_8822c, + NULL +}; + +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = { + trans_act_to_cardemu_8822c, + trans_cardemu_to_carddis_8822c, + NULL +}; + +static const struct rtw_intf_phy_para usb2_param_8822c[] = { + {0xFFFF, 0x00, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para usb3_param_8822c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen1_param_8822c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen2_param_8822c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8822c = { + .usb2_para = usb2_param_8822c, + .usb3_para = usb3_param_8822c, + .gen1_para = pcie_gen1_param_8822c, + .gen2_para = pcie_gen2_param_8822c, + .n_usb2_para = ARRAY_SIZE(usb2_param_8822c), + .n_usb3_para = ARRAY_SIZE(usb2_param_8822c), + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8822c), + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), +}; + +static const struct rtw_hw_reg rtw8822c_dig[] = { + [0] = { .addr = 0x1d70, .mask = 0x7f }, + [1] = { .addr = 0x1d70, .mask = 0x7f00 }, +}; + +static const struct rtw_ltecoex_addr rtw8822c_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + +static const struct rtw_page_table page_table_8822c[] = { + {64, 64, 64, 64, 1}, + {64, 64, 64, 64, 1}, + {64, 64, 0, 0, 1}, + {64, 64, 64, 0, 1}, + {64, 64, 64, 64, 1}, +}; + +static const struct rtw_rqpn rqpn_table_8822c[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8822c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static const struct rtw_chip_ops rtw8822c_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_phy_status = query_phy_status, + .set_channel = rtw8822c_set_channel, + .mac_init = rtw8822c_mac_init, + .mac_postinit = NULL, + .dump_fw_crash = rtw8822c_dump_fw_crash, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_mix, + .set_tx_power_index = rtw8822c_set_tx_power_index, + .set_antenna = rtw8822c_set_antenna, + .cfg_ldo25 = rtw8822c_cfg_ldo25, + .set_ampdu_factor = NULL, + .false_alarm_statistics = rtw8822c_false_alarm_statistics, + .dpk_track = rtw8822c_dpk_track, + .phy_calibration = rtw8822c_phy_calibration, + .cck_pd_set = rtw8822c_phy_cck_pd_set, + .pwr_track = rtw8822c_pwr_track, + .config_bfee = rtw8822c_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .adaptivity_init = rtw8822c_adaptivity_init, + .adaptivity = rtw8822c_adaptivity, + .cfo_init = rtw8822c_cfo_init, + .cfo_track = rtw8822c_cfo_track, + .config_tx_path = rtw8822c_config_tx_path, + .config_txrx_mode = rtw8822c_config_trx_mode, + .led_set = rtw8822c_led_set, + .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, + + .coex_set_init = rtw8822c_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8822c_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8822c_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8822c_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8822c_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8822c_coex_cfg_wl_rx_gain, +}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8822c[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0x6a5a5555, 0xaaaaaaaa}, + {0x6a5a56aa, 0x6a5a56aa}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-10 */ + {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, + {0x66555555, 0x6aaa5aaa}, + {0x66555555, 0xaaaa5aaa}, + {0x66555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x55555555, 0x6a5a6a5a}, + {0x66556655, 0x66556655}, + {0x66556aaa, 0x6a5a6aaa}, /*case-30*/ + {0xffffffff, 0x5aaa5aaa}, + {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, + {0xe5555555, 0xe5555555}, /* case-35 */ + {0xea5a5a5a, 0xea5a5a5a}, + {0xea6a6a6a, 0xea6a6a6a}, +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8822c[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0x55555555, 0x55555555}, + {0x66555555, 0x66555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x66555555, 0xfafafafa}, + {0x66555555, 0x5a5a5a5a}, + {0x66555555, 0x6a5a5a5a}, /* case-110 */ + {0x66555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xffff55ff, 0xffff55ff}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffffffff, 0x5afa5afa}, + {0xffffffff, 0xaaaaaaaa}, /* case-120 */ + {0x55ff55ff, 0x5afa5afa}, + {0x55ff55ff, 0xaaaaaaaa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8822c[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x10} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8822c[] = { + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} } +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8822c[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8822c[] = {8, 15, 20, 25}; +static const struct coex_5g_afh_map afh_5g_8822c[] = { {0, 0, 0} }; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8822c[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {8, 17, true, 4}, + {7, 18, true, 4}, + {6, 19, true, 4}, + {5, 20, true, 4}, + {0, 21, true, 4} /* for gamg hid */ +}; + +static const struct coex_rf_para rf_para_rx_8822c[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {3, 24, true, 5}, + {2, 26, true, 5}, + {1, 27, true, 5}, + {0, 28, true, 5}, + {0, 28, true, 5} /* for gamg hid */ +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); + +static const u8 +rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, +}; + +static const u8 +rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, +}; + +static const u8 +rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, +}; + +static const u8 +rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, +}; + +static const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, + 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, + 17, 18, 19, 20, 20, 21, 22, 23, 24, 25 +}; + +static const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 +}; + +static const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, + 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, + 13, 14, 15, 15, 16, 17, 17, 18, 19, 19 +}; + +static const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 25, 26, 27 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, + 17, 18, 19, 20, 21, 22, 23, 23, 24, 25 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, + 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 17, 18, 18, 19, 20, 21, 21, 22 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 +}; + +static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, +}; + +static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { + [0] = RTW_DEF_RFE(8822c, 0, 0, 0), + [1] = RTW_DEF_RFE(8822c, 0, 0, 0), + [2] = RTW_DEF_RFE(8822c, 0, 0, 0), + [3] = RTW_DEF_RFE(8822c, 0, 0, 0), + [4] = RTW_DEF_RFE(8822c, 0, 0, 0), + [5] = RTW_DEF_RFE(8822c, 0, 5, 0), + [6] = RTW_DEF_RFE(8822c, 0, 0, 0), +}; + +static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 + }, + [EDCCA_TH_H2L_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80 + }, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_NET_DETECT, + .n_patterns = RTW_MAX_PATTERN_NUM, + .pattern_max_len = RTW_MAX_PATTERN_SIZE, + .pattern_min_len = 1, + .max_nd_match_sets = 4, +}; +#endif + +static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = { + {0x1860, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x4160, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8}, + {0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + +const struct rtw_chip_info rtw8822c_hw_spec = { + .ops = &rtw8822c_ops, + .id = RTW_CHIP_TYPE_8822C, + .fw_name = "rtw88/rtw8822c_fw.bin", + .wlan_cpu = RTW_WCPU_3081, + .tx_pkt_desc_sz = 48, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 768, + .ptct_efuse_size = 124, + .txff_size = 262144, + .rxff_size = 24576, + .fw_rxff_size = 12288, + .rsvd_drv_pg_num = 16, + .txgi_factor = 2, + .is_pwr_by_rate_dec = false, + .max_power_index = 0x7f, + .csi_buf_pg_num = 50, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .amsdu_in_ampdu = true, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK) | BIT(LPS_DEEP_MODE_PG), + .sys_func_en = 0xD8, + .pwr_on_seq = card_enable_flow_8822c, + .pwr_off_seq = card_disable_flow_8822c, + .page_table = page_table_8822c, + .rqpn_table = rqpn_table_8822c, + .prioq_addrs = &prioq_addrs_8822c, + .intf_table = &phy_para_table_8822c, + .dig = rtw8822c_dig, + .dig_cck = NULL, + .rf_base_addr = {0x3c00, 0x4c00}, + .rf_sipi_addr = {0x1808, 0x4108}, + .ltecoex_addr = &rtw8822c_ltecoex_addr, + .mac_tbl = &rtw8822c_mac_tbl, + .agc_tbl = &rtw8822c_agc_tbl, + .bb_tbl = &rtw8822c_bb_tbl, + .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, + .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, + .rfe_defs = rtw8822c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), + .en_dis_dpd = true, + .dpd_ratemask = DIS_DPD_RATEALL, + .iqk_threshold = 8, + .lck_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, + .rx_ldpc = true, + .tx_stbc = true, + .edcca_th = rtw8822c_edcca_th, + .l2h_th_ini_cs = 60, + .l2h_th_ini_ad = 45, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + +#ifdef CONFIG_PM + .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", + .wowlan_stub = &rtw_wowlan_stub_8822c, + .max_sched_scan_ssids = 4, +#endif + .max_scan_ie_len = (RTW_PROBE_PG_CNT - 1) * TX_PAGE_SIZE, + .coex_para_ver = 0x26020420, + .bt_desired_ver = 0x20, + .scbd_support = true, + .new_scbd10_def = true, + .ble_hid_profile_support = true, + .wl_mimo_ps_support = true, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_DBM, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8822c, + .bt_rssi_step = bt_rssi_step_8822c, + .table_sant_num = ARRAY_SIZE(table_sant_8822c), + .table_sant = table_sant_8822c, + .table_nsant_num = ARRAY_SIZE(table_nsant_8822c), + .table_nsant = table_nsant_8822c, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8822c), + .tdma_sant = tdma_sant_8822c, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822c), + .tdma_nsant = tdma_nsant_8822c, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822c), + .wl_rf_para_tx = rf_para_tx_8822c, + .wl_rf_para_rx = rf_para_rx_8822c, + .bt_afh_span_bw20 = 0x24, + .bt_afh_span_bw40 = 0x36, + .afh_5g_num = ARRAY_SIZE(afh_5g_8822c), + .afh_5g = afh_5g_8822c, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), + .coex_info_hw_regs = coex_info_hw_regs_8822c, + + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, + .fwcd_segs = &rtw8822c_fwcd_segs, +}; +EXPORT_SYMBOL(rtw8822c_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8822c_fw.bin"); +MODULE_FIRMWARE("rtw88/rtw8822c_wow_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822c driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h new file mode 100644 index 000000000..fc62b67a1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h @@ -0,0 +1,429 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8822C_H__ +#define __RTW8822C_H__ + +#include + +struct rtw8822cu_efuse { + u8 res0[0x30]; /* 0x120 */ + u8 vid[2]; /* 0x150 */ + u8 pid[2]; + u8 res1[3]; + u8 mac_addr[ETH_ALEN]; /* 0x157 */ + u8 res2[0x3d]; +} __packed; + +struct rtw8822cs_efuse { + u8 res0[0x4a]; /* 0x120 */ + u8 mac_addr[ETH_ALEN]; /* 0x16a */ +} __packed; + +struct rtw8822ce_efuse { + u8 mac_addr[ETH_ALEN]; /* 0x120 */ + u8 vender_id[2]; + u8 device_id[2]; + u8 sub_vender_id[2]; + u8 sub_device_id[2]; + u8 pmc[2]; + u8 exp_device_cap[2]; + u8 msi_cap; + u8 ltr_cap; /* 0x133 */ + u8 exp_link_control[2]; + u8 link_cap[4]; + u8 link_control[2]; + u8 serial_number[8]; + u8 res0:2; /* 0x144 */ + u8 ltr_en:1; + u8 res1:2; + u8 obff:2; + u8 res2_1:1; + u8 res2_2:2; + u8 obff_cap:2; + u8 res3:4; + u8 class_code[3]; + u8 res4; + u8 pci_pm_L1_2_supp:1; + u8 pci_pm_L1_1_supp:1; + u8 aspm_pm_L1_2_supp:1; + u8 aspm_pm_L1_1_supp:1; + u8 L1_pm_substates_supp:1; + u8 res5:3; + u8 port_common_mode_restore_time; + u8 port_t_power_on_scale:2; + u8 res6:1; + u8 port_t_power_on_value:5; + u8 res7; +} __packed; + +struct rtw8822c_efuse { + __le16 rtl_id; + u8 res0[4]; + u8 usb_mode; + u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 res2; + u8 iqk_lck; + u8 res3[5]; /* 0xbc */ + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res4[3]; + u8 path_a_thermal; /* 0xd0 */ + u8 path_b_thermal; + u8 res5[2]; + u8 rx_gain_gap_2g_ofdm; + u8 res6; + u8 rx_gain_gap_2g_cck; + u8 res7; + u8 rx_gain_gap_5gl; + u8 res8; + u8 rx_gain_gap_5gm; + u8 res9; + u8 rx_gain_gap_5gh; + u8 res10; + u8 res11[0x42]; + union { + struct rtw8822ce_efuse e; + struct rtw8822cu_efuse u; + struct rtw8822cs_efuse s; + }; +} __packed; + +enum rtw8822c_dpk_agc_phase { + RTW_DPK_GAIN_CHECK, + RTW_DPK_GAIN_LARGE, + RTW_DPK_GAIN_LESS, + RTW_DPK_GL_LARGE, + RTW_DPK_GL_LESS, + RTW_DPK_LOSS_CHECK, + RTW_DPK_AGC_OUT, +}; + +enum rtw8822c_dpk_one_shot_action { + RTW_DPK_CAL_PWR, + RTW_DPK_GAIN_LOSS, + RTW_DPK_DO_DPK, + RTW_DPK_DPK_ON, + RTW_DPK_DAGC, + RTW_DPK_ACTION_MAX +}; + +void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev, + const struct rtw_table *tbl); + +extern const struct rtw_chip_info rtw8822c_hw_spec; + +#define RTW_DECL_TABLE_DPK(name) \ +const struct rtw_table name ## _tbl = { \ + .data = name, \ + .size = ARRAY_SIZE(name), \ + .parse = rtw8822c_parse_tbl_dpk, \ +} + +#define DACK_PATH_8822C 2 +#define DACK_REG_8822C 16 +#define DACK_RF_8822C 1 +#define DACK_SN_8822C 100 + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P0_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P0_GAIN_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(21, 16)) +#define GET_PHY_STAT_P0_CHANNEL(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(23, 16)) +#define GET_PHY_STAT_P0_GAIN_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(29, 24)) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_CHANNEL(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) + +#define RTW8822C_EDCCA_MAX 0x7f +#define REG_ANAPARLDO_POW_MAC 0x0029 +#define BIT_LDOE25_PON BIT(0) +#define XCAP_MASK GENMASK(6, 0) +#define CFO_TRK_ENABLE_TH 20 +#define CFO_TRK_STOP_TH 10 +#define CFO_TRK_ADJ_TH 10 + +#define REG_TXDFIR0 0x808 +#define REG_DFIRBW 0x810 +#define REG_ANTMAP0 0x820 +#define BIT_ANT_PATH GENMASK(1, 0) +#define REG_ANTMAP 0x824 +#define REG_EDCCA_DECISION 0x844 +#define BIT_EDCCA_OPTION GENMASK(30, 29) +#define REG_DYMPRITH 0x86c +#define REG_DYMENTH0 0x870 +#define REG_DYMENTH 0x874 +#define REG_SBD 0x88c +#define BITS_SUBTUNE GENMASK(15, 12) +#define REG_DYMTHMIN 0x8a4 + +#define REG_TXBWCTL 0x9b0 +#define REG_TXCLK 0x9b4 + +#define REG_SCOTRK 0xc30 +#define REG_MRCM 0xc38 +#define REG_AGCSWSH 0xc44 +#define REG_ANTWTPD 0xc54 +#define REG_PT_CHSMO 0xcbc +#define BIT_PT_OPT BIT(21) + +#define REG_ORITXCODE 0x1800 +#define BIT_PATH_EN BIT(31) +#define REG_3WIRE 0x180c +#define BIT_DIS_SHARERX_TXGAT BIT(27) +#define BIT_3WIRE_TX_EN BIT(0) +#define BIT_3WIRE_RX_EN BIT(1) +#define BIT_3WIRE_EN GENMASK(1, 0) +#define BIT_3WIRE_PI_ON BIT(28) +#define REG_ANAPAR_A 0x1830 +#define BIT_ANAPAR_UPDATE BIT(29) +#define REG_RFTXEN_GCK_A 0x1864 +#define BIT_RFTXEN_GCK_FORCE_ON BIT(31) +#define REG_DIS_SHARE_RX_A 0x186c +#define BIT_TX_SCALE_0DB BIT(7) +#define REG_RXAGCCTL0 0x18ac +#define BITS_RXAGC_CCK GENMASK(15, 12) +#define BITS_RXAGC_OFDM GENMASK(8, 4) +#define REG_DCKA_I_0 0x18bc +#define REG_DCKA_I_1 0x18c0 +#define REG_DCKA_Q_0 0x18d8 +#define REG_DCKA_Q_1 0x18dc + +#define REG_CCKSB 0x1a00 +#define BIT_BBMODE GENMASK(2, 1) +#define REG_RXCCKSEL 0x1a04 +#define REG_BGCTRL 0x1a14 +#define BITS_RX_IQ_WEIGHT (BIT(8) | BIT(9)) +#define REG_TXF0 0x1a20 +#define REG_TXF1 0x1a24 +#define REG_TXF2 0x1a28 +#define REG_CCANRX 0x1a2c +#define BIT_CCK_FA_RST (BIT(14) | BIT(15)) +#define BIT_OFDM_FA_RST (BIT(12) | BIT(13)) +#define REG_CCK_FACNT 0x1a5c +#define REG_CCKTXONLY 0x1a80 +#define BIT_BB_CCK_CHECK_EN BIT(18) +#define REG_TXF3 0x1a98 +#define REG_TXF4 0x1a9c +#define REG_TXF5 0x1aa0 +#define REG_TXF6 0x1aac +#define REG_TXF7 0x1ab0 +#define REG_CCK_SOURCE 0x1abc +#define BIT_NBI_EN BIT(30) + +#define REG_NCTL0 0x1b00 +#define BIT_SEL_PATH GENMASK(2, 1) +#define BIT_SUBPAGE GENMASK(3, 0) +#define REG_DPD_CTL0_S0 0x1b04 +#define BIT_GS_PWSF GENMASK(27, 0) +#define REG_DPD_CTL1_S0 0x1b08 +#define BIT_DPD_EN BIT(31) +#define BIT_PS_EN BIT(7) +#define REG_IQKSTAT 0x1b10 +#define REG_IQK_CTL1 0x1b20 +#define BIT_TX_CFIR GENMASK(31, 30) +#define BIT_CFIR_EN GENMASK(26, 24) +#define BIT_BYPASS_DPD BIT(25) + +#define REG_TX_TONE_IDX 0x1b2c +#define REG_DPD_LUT0 0x1b44 +#define BIT_GLOSS_DB GENMASK(14, 12) +#define REG_DPD_CTL0_S1 0x1b5c +#define REG_DPD_CTL1_S1 0x1b60 +#define REG_DPD_AGC 0x1b67 +#define REG_TABLE_SEL 0x1b98 +#define BIT_I_GAIN GENMASK(19, 16) +#define BIT_GAIN_RST BIT(15) +#define BIT_Q_GAIN_SEL GENMASK(14, 12) +#define BIT_Q_GAIN GENMASK(11, 0) +#define REG_TX_GAIN_SET 0x1b9c +#define BIT_GAPK_RPT_IDX GENMASK(11, 8) +#define REG_DPD_CTL0 0x1bb4 +#define REG_SINGLE_TONE_SW 0x1bb8 +#define BIT_IRQ_TEST_MODE BIT(20) +#define REG_R_CONFIG 0x1bcc +#define BIT_INNER_LB BIT(21) +#define BIT_IQ_SWITCH GENMASK(5, 0) +#define BIT_2G_SWING 0x2d +#define BIT_5G_SWING 0x36 +#define REG_RXSRAM_CTL 0x1bd4 +#define BIT_RPT_EN BIT(21) +#define BIT_RPT_SEL GENMASK(20, 16) +#define BIT_DPD_CLK GENMASK(7, 4) +#define REG_DPD_CTL11 0x1be4 +#define REG_DPD_CTL12 0x1be8 +#define REG_DPD_CTL15 0x1bf4 +#define REG_DPD_CTL16 0x1bf8 +#define REG_STAT_RPT 0x1bfc +#define BIT_RPT_DGAIN GENMASK(27, 16) +#define BIT_GAPK_RPT0 GENMASK(3, 0) +#define BIT_GAPK_RPT1 GENMASK(7, 4) +#define BIT_GAPK_RPT2 GENMASK(11, 8) +#define BIT_GAPK_RPT3 GENMASK(15, 12) +#define BIT_GAPK_RPT4 GENMASK(19, 16) +#define BIT_GAPK_RPT5 GENMASK(23, 20) +#define BIT_GAPK_RPT6 GENMASK(27, 24) +#define BIT_GAPK_RPT7 GENMASK(31, 28) + +#define REG_TXANT 0x1c28 +#define REG_IQK_CTRL 0x1c38 +#define REG_ENCCK 0x1c3c +#define BIT_CCK_BLK_EN BIT(1) +#define BIT_CCK_OFDM_BLK_EN (BIT(0) | BIT(1)) +#define REG_CCAMSK 0x1c80 +#define REG_RSTB 0x1c90 +#define BIT_RSTB_3WIRE BIT(8) +#define REG_CH_DELAY_EXTR2 0x1cd0 +#define BIT_TST_IQK2SET_SRC BIT(31) +#define BIT_EN_IOQ_IQK_DPK BIT(30) +#define BIT_IQK_DPK_RESET_SRC BIT(29) +#define BIT_IQK_DPK_CLOCK_SRC BIT(28) + +#define REG_RX_BREAK 0x1d2c +#define BIT_COM_RX_GCK_EN BIT(31) +#define REG_RXFNCTL 0x1d30 +#define REG_CCA_OFF 0x1d58 +#define BIT_CCA_ON_BY_PW GENMASK(11, 3) +#define REG_RXIGI 0x1d70 + +#define REG_ENFN 0x1e24 +#define BIT_IQK_DPK_EN BIT(17) +#define REG_TXANTSEG 0x1e28 +#define BIT_ANTSEG GENMASK(3, 0) +#define REG_TXLGMAP 0x1e2c +#define REG_CCKPATH 0x1e5c +#define REG_TX_FIFO 0x1e70 +#define BIT_STOP_TX GENMASK(3, 0) +#define REG_CNT_CTRL 0x1eb4 +#define BIT_ALL_CNT_RST BIT(25) + +#define REG_OFDM_FACNT 0x2d00 +#define REG_OFDM_FACNT1 0x2d04 +#define REG_OFDM_FACNT2 0x2d08 +#define REG_OFDM_FACNT3 0x2d0c +#define REG_OFDM_FACNT4 0x2d10 +#define REG_OFDM_FACNT5 0x2d20 +#define REG_RPT_CIP 0x2d9c +#define BIT_RPT_CIP_STATUS GENMASK(7, 0) +#define REG_OFDM_TXCNT 0x2de0 + +#define REG_ORITXCODE2 0x4100 +#define REG_3WIRE2 0x410c +#define REG_ANAPAR_B 0x4130 +#define REG_RFTXEN_GCK_B 0x4164 +#define REG_DIS_SHARE_RX_B 0x416c +#define BIT_EXT_TIA_BW BIT(1) +#define REG_RXAGCCTL 0x41ac +#define REG_DCKB_I_0 0x41bc +#define REG_DCKB_I_1 0x41c0 +#define REG_DCKB_Q_0 0x41d8 +#define REG_DCKB_Q_1 0x41dc + +#define RF_MODE_TRXAGC 0x00 +#define BIT_RF_MODE GENMASK(19, 16) +#define BIT_RXAGC GENMASK(9, 5) +#define BIT_TXAGC GENMASK(4, 0) +#define RF_RXAGC_OFFSET 0x19 +#define RF_BW_TRXBB 0x1a +#define BIT_TX_CCK_IND BIT(16) +#define BIT_BW_TXBB GENMASK(14, 12) +#define BIT_BW_RXBB GENMASK(11, 10) +#define BIT_DBG_CCK_CCA BIT(1) +#define RF_TX_GAIN_OFFSET 0x55 +#define BIT_BB_GAIN GENMASK(18, 14) +#define BIT_RF_GAIN GENMASK(4, 2) +#define RF_TX_GAIN 0x56 +#define BIT_GAIN_TXBB GENMASK(4, 0) +#define RF_IDAC 0x58 +#define BIT_TX_MODE GENMASK(19, 8) +#define RF_TX_RESULT 0x5f +#define BIT_GAIN_TX_PAD_H GENMASK(11, 8) +#define BIT_GAIN_TX_PAD_L GENMASK(7, 4) +#define RF_PA 0x60 +#define RF_PABIAS_2G_MASK GENMASK(15, 12) +#define RF_PABIAS_5G_MASK GENMASK(19, 16) +#define RF_TXA_LB_SW 0x63 +#define BIT_TXA_LB_ATT GENMASK(15, 14) +#define BIT_LB_SW GENMASK(13, 12) +#define BIT_LB_ATT GENMASK(4, 2) +#define RF_RXG_GAIN 0x87 +#define BIT_RXG_GAIN BIT(18) +#define RF_RXA_MIX_GAIN 0x8a +#define BIT_RXA_MIX_GAIN GENMASK(4, 3) +#define RF_EXT_TIA_BW 0x8f +#define BIT_PW_EXT_TIA BIT(1) +#define RF_DIS_BYPASS_TXBB 0x9e +#define BIT_TXBB BIT(10) +#define BIT_TIA_BYPASS BIT(5) +#define RF_DEBUG 0xde +#define BIT_DE_PWR_TRIM BIT(19) +#define BIT_DE_TX_GAIN BIT(16) +#define BIT_DE_TRXBW BIT(2) + +#define PPG_THERMAL_B 0x1b0 +#define RF_THEMAL_MASK GENMASK(19, 16) +#define PPG_2GH_TXAB 0x1d2 +#define PPG_2G_A_MASK GENMASK(3, 0) +#define PPG_2G_B_MASK GENMASK(7, 4) +#define PPG_2GL_TXAB 0x1d4 +#define PPG_PABIAS_2GB 0x1d5 +#define PPG_PABIAS_2GA 0x1d6 +#define PPG_PABIAS_MASK GENMASK(3, 0) +#define PPG_PABIAS_5GB 0x1d7 +#define PPG_PABIAS_5GA 0x1d8 +#define PPG_5G_MASK GENMASK(4, 0) +#define PPG_5GH1_TXB 0x1db +#define PPG_5GH1_TXA 0x1dc +#define PPG_5GM2_TXB 0x1df +#define PPG_5GM2_TXA 0x1e0 +#define PPG_5GM1_TXB 0x1e3 +#define PPG_5GM1_TXA 0x1e4 +#define PPG_5GL2_TXB 0x1e7 +#define PPG_5GL2_TXA 0x1e8 +#define PPG_5GL1_TXB 0x1eb +#define PPG_5GL1_TXA 0x1ec +#define PPG_2GM_TXAB 0x1ee +#define PPG_THERMAL_A 0x1ef +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c new file mode 100644 index 000000000..5699846a3 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c @@ -0,0 +1,46105 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8822c.h" +#include "rtw8822c_table.h" + +static const u32 rtw8822c_mac[] = { +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822c_mac, rtw_phy_cfg_mac); + +static const u32 rtw8822c_agc[] = { + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x300001FF, + 0x1D90, 0x300101FE, + 0x1D90, 0x300201FD, + 0x1D90, 0x300301FC, + 0x1D90, 0x300401FB, + 0x1D90, 0x300501FA, + 0x1D90, 0x300601F9, + 0x1D90, 0x300701F8, + 0x1D90, 0x300801F7, + 0x1D90, 0x300901F6, + 0x1D90, 0x300A01F5, + 0x1D90, 0x300B01F4, + 0x1D90, 0x300C01F3, + 0x1D90, 0x300D01F2, + 0x1D90, 0x300E01F1, + 0x1D90, 0x300F01F0, + 0x1D90, 0x301001EF, + 0x1D90, 0x301101EE, + 0x1D90, 0x301201ED, + 0x1D90, 0x301301EC, + 0x1D90, 0x301401EB, + 0x1D90, 0x301501EA, + 0x1D90, 0x301601E9, + 0x1D90, 0x301701E8, + 0x1D90, 0x301801E7, + 0x1D90, 0x301901E5, + 0x1D90, 0x301A01E4, + 0x1D90, 0x301B01C5, + 0x1D90, 0x301C01C4, + 0x1D90, 0x301D01C3, + 0x1D90, 0x301E01C2, + 0x1D90, 0x301F0188, + 0x1D90, 0x30200187, + 0x1D90, 0x30210186, + 0x1D90, 0x30220184, + 0x1D90, 0x30230183, + 0x1D90, 0x30240182, + 0x1D90, 0x30250181, + 0x1D90, 0x30260148, + 0x1D90, 0x30270147, + 0x1D90, 0x30280146, + 0x1D90, 0x30290144, + 0x1D90, 0x302A0143, + 0x1D90, 0x302B0142, + 0x1D90, 0x302C0141, + 0x1D90, 0x302D00C8, + 0x1D90, 0x302E00C7, + 0x1D90, 0x302F00C6, + 0x1D90, 0x303000C5, + 0x1D90, 0x303100C4, + 0x1D90, 0x303200C3, + 0x1D90, 0x30330048, + 0x1D90, 0x30340047, + 0x1D90, 0x30350046, + 0x1D90, 0x30360045, + 0x1D90, 0x30370025, + 0x1D90, 0x30380024, + 0x1D90, 0x30390023, + 0x1D90, 0x303A0022, + 0x1D90, 0x303B0021, + 0x1D90, 0x303C0020, + 0x1D90, 0x303D0003, + 0x1D90, 0x303E0002, + 0x1D90, 0x303F0001, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x300001FF, + 0x1D90, 0x300101FE, + 0x1D90, 0x300201FD, + 0x1D90, 0x300301FC, + 0x1D90, 0x300401FB, + 0x1D90, 0x300501FA, + 0x1D90, 0x300601F9, + 0x1D90, 0x300701F8, + 0x1D90, 0x300801F7, + 0x1D90, 0x300901F6, + 0x1D90, 0x300A01F5, + 0x1D90, 0x300B01F4, + 0x1D90, 0x300C01F3, + 0x1D90, 0x300D01F2, + 0x1D90, 0x300E01F1, + 0x1D90, 0x300F01F0, + 0x1D90, 0x301001EF, + 0x1D90, 0x301101EE, + 0x1D90, 0x301201ED, + 0x1D90, 0x301301EC, + 0x1D90, 0x301401EB, + 0x1D90, 0x301501EA, + 0x1D90, 0x301601E9, + 0x1D90, 0x301701E8, + 0x1D90, 0x301801E7, + 0x1D90, 0x301901E5, + 0x1D90, 0x301A01E4, + 0x1D90, 0x301B01C5, + 0x1D90, 0x301C01C4, + 0x1D90, 0x301D01C3, + 0x1D90, 0x301E01C2, + 0x1D90, 0x301F0188, + 0x1D90, 0x30200187, + 0x1D90, 0x30210186, + 0x1D90, 0x30220184, + 0x1D90, 0x30230183, + 0x1D90, 0x30240182, + 0x1D90, 0x30250181, + 0x1D90, 0x30260148, + 0x1D90, 0x30270147, + 0x1D90, 0x30280146, + 0x1D90, 0x30290144, + 0x1D90, 0x302A0143, + 0x1D90, 0x302B0142, + 0x1D90, 0x302C0141, + 0x1D90, 0x302D00C8, + 0x1D90, 0x302E00C7, + 0x1D90, 0x302F00C6, + 0x1D90, 0x303000C5, + 0x1D90, 0x303100C4, + 0x1D90, 0x303200C3, + 0x1D90, 0x30330048, + 0x1D90, 0x30340047, + 0x1D90, 0x30350046, + 0x1D90, 0x30360045, + 0x1D90, 0x30370025, + 0x1D90, 0x30380024, + 0x1D90, 0x30390023, + 0x1D90, 0x303A0022, + 0x1D90, 0x303B0021, + 0x1D90, 0x303C0020, + 0x1D90, 0x303D0003, + 0x1D90, 0x303E0002, + 0x1D90, 0x303F0001, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x300001FF, + 0x1D90, 0x300101FE, + 0x1D90, 0x300201FD, + 0x1D90, 0x300301FC, + 0x1D90, 0x300401FB, + 0x1D90, 0x300501FA, + 0x1D90, 0x300601F9, + 0x1D90, 0x300701F8, + 0x1D90, 0x300801F7, + 0x1D90, 0x300901F6, + 0x1D90, 0x300A01F5, + 0x1D90, 0x300B01F4, + 0x1D90, 0x300C01F3, + 0x1D90, 0x300D01F2, + 0x1D90, 0x300E01F1, + 0x1D90, 0x300F01F0, + 0x1D90, 0x301001EF, + 0x1D90, 0x301101EE, + 0x1D90, 0x301201ED, + 0x1D90, 0x301301EC, + 0x1D90, 0x301401EB, + 0x1D90, 0x301501EA, + 0x1D90, 0x301601E9, + 0x1D90, 0x301701E8, + 0x1D90, 0x301801E7, + 0x1D90, 0x301901E5, + 0x1D90, 0x301A01E4, + 0x1D90, 0x301B01C5, + 0x1D90, 0x301C01C4, + 0x1D90, 0x301D01C3, + 0x1D90, 0x301E01C2, + 0x1D90, 0x301F0188, + 0x1D90, 0x30200187, + 0x1D90, 0x30210186, + 0x1D90, 0x30220184, + 0x1D90, 0x30230183, + 0x1D90, 0x30240182, + 0x1D90, 0x30250181, + 0x1D90, 0x30260148, + 0x1D90, 0x30270147, + 0x1D90, 0x30280146, + 0x1D90, 0x30290144, + 0x1D90, 0x302A0143, + 0x1D90, 0x302B0142, + 0x1D90, 0x302C0141, + 0x1D90, 0x302D00C8, + 0x1D90, 0x302E00C7, + 0x1D90, 0x302F00C6, + 0x1D90, 0x303000C5, + 0x1D90, 0x303100C4, + 0x1D90, 0x303200C3, + 0x1D90, 0x30330048, + 0x1D90, 0x30340047, + 0x1D90, 0x30350046, + 0x1D90, 0x30360045, + 0x1D90, 0x30370025, + 0x1D90, 0x30380024, + 0x1D90, 0x30390023, + 0x1D90, 0x303A0022, + 0x1D90, 0x303B0021, + 0x1D90, 0x303C0020, + 0x1D90, 0x303D0003, + 0x1D90, 0x303E0002, + 0x1D90, 0x303F0001, + 0xA0000000, 0x00000000, + 0x1D90, 0x300001FF, + 0x1D90, 0x300101FE, + 0x1D90, 0x300201FD, + 0x1D90, 0x300301FC, + 0x1D90, 0x300401FB, + 0x1D90, 0x300501FA, + 0x1D90, 0x300601F9, + 0x1D90, 0x300701F8, + 0x1D90, 0x300801F7, + 0x1D90, 0x300901F6, + 0x1D90, 0x300A01F5, + 0x1D90, 0x300B01F4, + 0x1D90, 0x300C01F3, + 0x1D90, 0x300D01F2, + 0x1D90, 0x300E01F1, + 0x1D90, 0x300F01F0, + 0x1D90, 0x301001EF, + 0x1D90, 0x301101EE, + 0x1D90, 0x301201ED, + 0x1D90, 0x301301EC, + 0x1D90, 0x301401EB, + 0x1D90, 0x301501EA, + 0x1D90, 0x301601E9, + 0x1D90, 0x301701E8, + 0x1D90, 0x301801E7, + 0x1D90, 0x301901E5, + 0x1D90, 0x301A01E4, + 0x1D90, 0x301B01C5, + 0x1D90, 0x301C01C4, + 0x1D90, 0x301D01C3, + 0x1D90, 0x301E01C2, + 0x1D90, 0x301F0188, + 0x1D90, 0x30200187, + 0x1D90, 0x30210186, + 0x1D90, 0x30220184, + 0x1D90, 0x30230183, + 0x1D90, 0x30240182, + 0x1D90, 0x30250181, + 0x1D90, 0x30260148, + 0x1D90, 0x30270147, + 0x1D90, 0x30280146, + 0x1D90, 0x30290144, + 0x1D90, 0x302A0143, + 0x1D90, 0x302B0142, + 0x1D90, 0x302C0141, + 0x1D90, 0x302D00C8, + 0x1D90, 0x302E00C7, + 0x1D90, 0x302F00C6, + 0x1D90, 0x303000C5, + 0x1D90, 0x303100C4, + 0x1D90, 0x303200C3, + 0x1D90, 0x30330048, + 0x1D90, 0x30340047, + 0x1D90, 0x30350046, + 0x1D90, 0x30360045, + 0x1D90, 0x30370025, + 0x1D90, 0x30380024, + 0x1D90, 0x30390023, + 0x1D90, 0x303A0022, + 0x1D90, 0x303B0021, + 0x1D90, 0x303C0020, + 0x1D90, 0x303D0003, + 0x1D90, 0x303E0002, + 0x1D90, 0x303F0001, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x3040011F, + 0x1D90, 0x3041011F, + 0x1D90, 0x3042011F, + 0x1D90, 0x3043011F, + 0x1D90, 0x3044011F, + 0x1D90, 0x3045011F, + 0x1D90, 0x3046011F, + 0x1D90, 0x3047011F, + 0x1D90, 0x3048011F, + 0x1D90, 0x3049011F, + 0x1D90, 0x304A011F, + 0x1D90, 0x304B011F, + 0x1D90, 0x304C011F, + 0x1D90, 0x304D011F, + 0x1D90, 0x304E011F, + 0x1D90, 0x304F00F4, + 0x1D90, 0x305000F3, + 0x1D90, 0x305100F2, + 0x1D90, 0x305200F1, + 0x1D90, 0x305300F0, + 0x1D90, 0x305400EF, + 0x1D90, 0x305500EE, + 0x1D90, 0x305600ED, + 0x1D90, 0x305700EC, + 0x1D90, 0x305800EB, + 0x1D90, 0x305900EA, + 0x1D90, 0x305A00E9, + 0x1D90, 0x305B00E8, + 0x1D90, 0x305C00E7, + 0x1D90, 0x305D00E6, + 0x1D90, 0x305E00E4, + 0x1D90, 0x305F00E3, + 0x1D90, 0x306000E2, + 0x1D90, 0x306100C4, + 0x1D90, 0x306200C3, + 0x1D90, 0x306300C2, + 0x1D90, 0x306400A4, + 0x1D90, 0x306500A3, + 0x1D90, 0x306600A2, + 0x1D90, 0x306700A1, + 0x1D90, 0x30680084, + 0x1D90, 0x30690083, + 0x1D90, 0x306A0082, + 0x1D90, 0x306B0081, + 0x1D90, 0x306C0080, + 0x1D90, 0x306D0067, + 0x1D90, 0x306E0066, + 0x1D90, 0x306F0065, + 0x1D90, 0x30700064, + 0x1D90, 0x30710063, + 0x1D90, 0x30720044, + 0x1D90, 0x30730043, + 0x1D90, 0x30740042, + 0x1D90, 0x30750041, + 0x1D90, 0x30760024, + 0x1D90, 0x30770023, + 0x1D90, 0x30780022, + 0x1D90, 0x30790021, + 0x1D90, 0x307A0020, + 0x1D90, 0x307B0004, + 0x1D90, 0x307C0003, + 0x1D90, 0x307D0002, + 0x1D90, 0x307E0001, + 0x1D90, 0x307F0000, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x304001FD, + 0x1D90, 0x304101FC, + 0x1D90, 0x304201FB, + 0x1D90, 0x304301FA, + 0x1D90, 0x304401F9, + 0x1D90, 0x304501F8, + 0x1D90, 0x304601F7, + 0x1D90, 0x304701F6, + 0x1D90, 0x304801F5, + 0x1D90, 0x304901F4, + 0x1D90, 0x304A01F3, + 0x1D90, 0x304B01F2, + 0x1D90, 0x304C01F1, + 0x1D90, 0x304D01F0, + 0x1D90, 0x304E01EF, + 0x1D90, 0x304F00EE, + 0x1D90, 0x305000ED, + 0x1D90, 0x305100EC, + 0x1D90, 0x305200EB, + 0x1D90, 0x305300EA, + 0x1D90, 0x305400E9, + 0x1D90, 0x305500E8, + 0x1D90, 0x305600E7, + 0x1D90, 0x305700E6, + 0x1D90, 0x305800E5, + 0x1D90, 0x305900E4, + 0x1D90, 0x305A00E3, + 0x1D90, 0x305B00C3, + 0x1D90, 0x305C00C2, + 0x1D90, 0x305D00A4, + 0x1D90, 0x305E00A3, + 0x1D90, 0x305F00A2, + 0x1D90, 0x306000A1, + 0x1D90, 0x30610085, + 0x1D90, 0x30620084, + 0x1D90, 0x30630083, + 0x1D90, 0x30640082, + 0x1D90, 0x30650069, + 0x1D90, 0x30660068, + 0x1D90, 0x30670067, + 0x1D90, 0x30680066, + 0x1D90, 0x30690065, + 0x1D90, 0x306A0064, + 0x1D90, 0x306B0063, + 0x1D90, 0x306C0043, + 0x1D90, 0x306D0042, + 0x1D90, 0x306E0041, + 0x1D90, 0x306F0025, + 0x1D90, 0x30700024, + 0x1D90, 0x30710023, + 0x1D90, 0x30720022, + 0x1D90, 0x30730021, + 0x1D90, 0x30740020, + 0x1D90, 0x30750004, + 0x1D90, 0x30760003, + 0x1D90, 0x30770002, + 0x1D90, 0x30780001, + 0x1D90, 0x30790000, + 0x1D90, 0x307A0000, + 0x1D90, 0x307B0000, + 0x1D90, 0x307C0000, + 0x1D90, 0x307D0000, + 0x1D90, 0x307E0000, + 0x1D90, 0x307F0000, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x304001FD, + 0x1D90, 0x304101FC, + 0x1D90, 0x304201FB, + 0x1D90, 0x304301FA, + 0x1D90, 0x304401F9, + 0x1D90, 0x304501F8, + 0x1D90, 0x304601F7, + 0x1D90, 0x304701F6, + 0x1D90, 0x304801F5, + 0x1D90, 0x304901F4, + 0x1D90, 0x304A01F3, + 0x1D90, 0x304B01F2, + 0x1D90, 0x304C01F1, + 0x1D90, 0x304D01F0, + 0x1D90, 0x304E01EF, + 0x1D90, 0x304F00EE, + 0x1D90, 0x305000ED, + 0x1D90, 0x305100EC, + 0x1D90, 0x305200EB, + 0x1D90, 0x305300EA, + 0x1D90, 0x305400E9, + 0x1D90, 0x305500E8, + 0x1D90, 0x305600E7, + 0x1D90, 0x305700E6, + 0x1D90, 0x305800E5, + 0x1D90, 0x305900E4, + 0x1D90, 0x305A00E3, + 0x1D90, 0x305B00C3, + 0x1D90, 0x305C00C2, + 0x1D90, 0x305D00A4, + 0x1D90, 0x305E00A3, + 0x1D90, 0x305F00A2, + 0x1D90, 0x306000A1, + 0x1D90, 0x30610085, + 0x1D90, 0x30620084, + 0x1D90, 0x30630083, + 0x1D90, 0x30640082, + 0x1D90, 0x30650069, + 0x1D90, 0x30660068, + 0x1D90, 0x30670067, + 0x1D90, 0x30680066, + 0x1D90, 0x30690065, + 0x1D90, 0x306A0064, + 0x1D90, 0x306B0063, + 0x1D90, 0x306C0043, + 0x1D90, 0x306D0042, + 0x1D90, 0x306E0041, + 0x1D90, 0x306F0025, + 0x1D90, 0x30700024, + 0x1D90, 0x30710023, + 0x1D90, 0x30720022, + 0x1D90, 0x30730021, + 0x1D90, 0x30740020, + 0x1D90, 0x30750004, + 0x1D90, 0x30760003, + 0x1D90, 0x30770002, + 0x1D90, 0x30780001, + 0x1D90, 0x30790000, + 0x1D90, 0x307A0000, + 0x1D90, 0x307B0000, + 0x1D90, 0x307C0000, + 0x1D90, 0x307D0000, + 0x1D90, 0x307E0000, + 0x1D90, 0x307F0000, + 0xA0000000, 0x00000000, + 0x1D90, 0x3040011F, + 0x1D90, 0x3041011F, + 0x1D90, 0x3042011F, + 0x1D90, 0x3043011F, + 0x1D90, 0x3044011F, + 0x1D90, 0x3045011F, + 0x1D90, 0x3046011F, + 0x1D90, 0x3047011F, + 0x1D90, 0x3048011F, + 0x1D90, 0x3049011F, + 0x1D90, 0x304A011F, + 0x1D90, 0x304B011F, + 0x1D90, 0x304C011F, + 0x1D90, 0x304D011F, + 0x1D90, 0x304E011F, + 0x1D90, 0x304F00F4, + 0x1D90, 0x305000F3, + 0x1D90, 0x305100F2, + 0x1D90, 0x305200F1, + 0x1D90, 0x305300F0, + 0x1D90, 0x305400EF, + 0x1D90, 0x305500EE, + 0x1D90, 0x305600ED, + 0x1D90, 0x305700EC, + 0x1D90, 0x305800EB, + 0x1D90, 0x305900EA, + 0x1D90, 0x305A00E9, + 0x1D90, 0x305B00E8, + 0x1D90, 0x305C00E7, + 0x1D90, 0x305D00E6, + 0x1D90, 0x305E00E4, + 0x1D90, 0x305F00E3, + 0x1D90, 0x306000E2, + 0x1D90, 0x306100C4, + 0x1D90, 0x306200C3, + 0x1D90, 0x306300C2, + 0x1D90, 0x306400A4, + 0x1D90, 0x306500A3, + 0x1D90, 0x306600A2, + 0x1D90, 0x306700A1, + 0x1D90, 0x30680084, + 0x1D90, 0x30690083, + 0x1D90, 0x306A0082, + 0x1D90, 0x306B0081, + 0x1D90, 0x306C0080, + 0x1D90, 0x306D0067, + 0x1D90, 0x306E0066, + 0x1D90, 0x306F0065, + 0x1D90, 0x30700064, + 0x1D90, 0x30710063, + 0x1D90, 0x30720044, + 0x1D90, 0x30730043, + 0x1D90, 0x30740042, + 0x1D90, 0x30750041, + 0x1D90, 0x30760024, + 0x1D90, 0x30770023, + 0x1D90, 0x30780022, + 0x1D90, 0x30790021, + 0x1D90, 0x307A0020, + 0x1D90, 0x307B0004, + 0x1D90, 0x307C0003, + 0x1D90, 0x307D0002, + 0x1D90, 0x307E0001, + 0x1D90, 0x307F0000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x308000FF, + 0x1D90, 0x308100FF, + 0x1D90, 0x308200FF, + 0x1D90, 0x308300FF, + 0x1D90, 0x308400FF, + 0x1D90, 0x308500FF, + 0x1D90, 0x308600FE, + 0x1D90, 0x308700FD, + 0x1D90, 0x308800FC, + 0x1D90, 0x308900FB, + 0x1D90, 0x308A00FA, + 0x1D90, 0x308B00F9, + 0x1D90, 0x308C00F8, + 0x1D90, 0x308D00F7, + 0x1D90, 0x308E00F6, + 0x1D90, 0x308F00F5, + 0x1D90, 0x309000F4, + 0x1D90, 0x309100F3, + 0x1D90, 0x309200F2, + 0x1D90, 0x309300F1, + 0x1D90, 0x309400F0, + 0x1D90, 0x309500EF, + 0x1D90, 0x309600EE, + 0x1D90, 0x309700ED, + 0x1D90, 0x309800EC, + 0x1D90, 0x309900EB, + 0x1D90, 0x309A00EA, + 0x1D90, 0x309B00E8, + 0x1D90, 0x309C00E7, + 0x1D90, 0x309D00E6, + 0x1D90, 0x309E00E5, + 0x1D90, 0x309F00E4, + 0x1D90, 0x30A000C4, + 0x1D90, 0x30A100C3, + 0x1D90, 0x30A200C2, + 0x1D90, 0x30A300C1, + 0x1D90, 0x30A400A3, + 0x1D90, 0x30A500A2, + 0x1D90, 0x30A600A1, + 0x1D90, 0x30A70085, + 0x1D90, 0x30A80084, + 0x1D90, 0x30A90083, + 0x1D90, 0x30AA0082, + 0x1D90, 0x30AB0081, + 0x1D90, 0x30AC0067, + 0x1D90, 0x30AD0066, + 0x1D90, 0x30AE0065, + 0x1D90, 0x30AF0064, + 0x1D90, 0x30B00063, + 0x1D90, 0x30B10044, + 0x1D90, 0x30B20043, + 0x1D90, 0x30B30042, + 0x1D90, 0x30B40026, + 0x1D90, 0x30B50025, + 0x1D90, 0x30B60024, + 0x1D90, 0x30B70023, + 0x1D90, 0x30B80022, + 0x1D90, 0x30B90021, + 0x1D90, 0x30BA0005, + 0x1D90, 0x30BB0004, + 0x1D90, 0x30BC0003, + 0x1D90, 0x30BD0002, + 0x1D90, 0x30BE0001, + 0x1D90, 0x30BF0000, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x308000FA, + 0x1D90, 0x308100F9, + 0x1D90, 0x308200F8, + 0x1D90, 0x308300F7, + 0x1D90, 0x308400F6, + 0x1D90, 0x308500F5, + 0x1D90, 0x308600F4, + 0x1D90, 0x308700F3, + 0x1D90, 0x308800F2, + 0x1D90, 0x308900F1, + 0x1D90, 0x308A00F0, + 0x1D90, 0x308B00EF, + 0x1D90, 0x308C00EE, + 0x1D90, 0x308D00ED, + 0x1D90, 0x308E00EC, + 0x1D90, 0x308F00EB, + 0x1D90, 0x309000EA, + 0x1D90, 0x309100E8, + 0x1D90, 0x309200E7, + 0x1D90, 0x309300E6, + 0x1D90, 0x309400E5, + 0x1D90, 0x309500E4, + 0x1D90, 0x309600C4, + 0x1D90, 0x309700C3, + 0x1D90, 0x309800C2, + 0x1D90, 0x309900C1, + 0x1D90, 0x309A00A3, + 0x1D90, 0x309B00A2, + 0x1D90, 0x309C00A1, + 0x1D90, 0x309D0085, + 0x1D90, 0x309E0084, + 0x1D90, 0x309F0083, + 0x1D90, 0x30A00082, + 0x1D90, 0x30A10081, + 0x1D90, 0x30A20067, + 0x1D90, 0x30A30066, + 0x1D90, 0x30A40065, + 0x1D90, 0x30A50064, + 0x1D90, 0x30A60063, + 0x1D90, 0x30A70044, + 0x1D90, 0x30A80043, + 0x1D90, 0x30A90042, + 0x1D90, 0x30AA0026, + 0x1D90, 0x30AB0025, + 0x1D90, 0x30AC0024, + 0x1D90, 0x30AD0023, + 0x1D90, 0x30AE0022, + 0x1D90, 0x30AF0021, + 0x1D90, 0x30B00005, + 0x1D90, 0x30B10004, + 0x1D90, 0x30B20003, + 0x1D90, 0x30B30002, + 0x1D90, 0x30B40001, + 0x1D90, 0x30B50000, + 0x1D90, 0x30B60000, + 0x1D90, 0x30B70000, + 0x1D90, 0x30B80000, + 0x1D90, 0x30B90000, + 0x1D90, 0x30BA0000, + 0x1D90, 0x30BB0000, + 0x1D90, 0x30BC0000, + 0x1D90, 0x30BD0000, + 0x1D90, 0x30BE0000, + 0x1D90, 0x30BF0000, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x308000FA, + 0x1D90, 0x308100F9, + 0x1D90, 0x308200F8, + 0x1D90, 0x308300F7, + 0x1D90, 0x308400F6, + 0x1D90, 0x308500F5, + 0x1D90, 0x308600F4, + 0x1D90, 0x308700F3, + 0x1D90, 0x308800F2, + 0x1D90, 0x308900F1, + 0x1D90, 0x308A00F0, + 0x1D90, 0x308B00EF, + 0x1D90, 0x308C00EE, + 0x1D90, 0x308D00ED, + 0x1D90, 0x308E00EC, + 0x1D90, 0x308F00EB, + 0x1D90, 0x309000EA, + 0x1D90, 0x309100E8, + 0x1D90, 0x309200E7, + 0x1D90, 0x309300E6, + 0x1D90, 0x309400E5, + 0x1D90, 0x309500E4, + 0x1D90, 0x309600C4, + 0x1D90, 0x309700C3, + 0x1D90, 0x309800C2, + 0x1D90, 0x309900C1, + 0x1D90, 0x309A00A3, + 0x1D90, 0x309B00A2, + 0x1D90, 0x309C00A1, + 0x1D90, 0x309D0085, + 0x1D90, 0x309E0084, + 0x1D90, 0x309F0083, + 0x1D90, 0x30A00082, + 0x1D90, 0x30A10081, + 0x1D90, 0x30A20067, + 0x1D90, 0x30A30066, + 0x1D90, 0x30A40065, + 0x1D90, 0x30A50064, + 0x1D90, 0x30A60063, + 0x1D90, 0x30A70044, + 0x1D90, 0x30A80043, + 0x1D90, 0x30A90042, + 0x1D90, 0x30AA0026, + 0x1D90, 0x30AB0025, + 0x1D90, 0x30AC0024, + 0x1D90, 0x30AD0023, + 0x1D90, 0x30AE0022, + 0x1D90, 0x30AF0021, + 0x1D90, 0x30B00005, + 0x1D90, 0x30B10004, + 0x1D90, 0x30B20003, + 0x1D90, 0x30B30002, + 0x1D90, 0x30B40001, + 0x1D90, 0x30B50000, + 0x1D90, 0x30B60000, + 0x1D90, 0x30B70000, + 0x1D90, 0x30B80000, + 0x1D90, 0x30B90000, + 0x1D90, 0x30BA0000, + 0x1D90, 0x30BB0000, + 0x1D90, 0x30BC0000, + 0x1D90, 0x30BD0000, + 0x1D90, 0x30BE0000, + 0x1D90, 0x30BF0000, + 0xA0000000, 0x00000000, + 0x1D90, 0x308000FF, + 0x1D90, 0x308100FF, + 0x1D90, 0x308200FF, + 0x1D90, 0x308300FF, + 0x1D90, 0x308400FF, + 0x1D90, 0x308500FF, + 0x1D90, 0x308600FE, + 0x1D90, 0x308700FD, + 0x1D90, 0x308800FC, + 0x1D90, 0x308900FB, + 0x1D90, 0x308A00FA, + 0x1D90, 0x308B00F9, + 0x1D90, 0x308C00F8, + 0x1D90, 0x308D00F7, + 0x1D90, 0x308E00F6, + 0x1D90, 0x308F00F5, + 0x1D90, 0x309000F4, + 0x1D90, 0x309100F3, + 0x1D90, 0x309200F2, + 0x1D90, 0x309300F1, + 0x1D90, 0x309400F0, + 0x1D90, 0x309500EF, + 0x1D90, 0x309600EE, + 0x1D90, 0x309700ED, + 0x1D90, 0x309800EC, + 0x1D90, 0x309900EB, + 0x1D90, 0x309A00EA, + 0x1D90, 0x309B00E8, + 0x1D90, 0x309C00E7, + 0x1D90, 0x309D00E6, + 0x1D90, 0x309E00E5, + 0x1D90, 0x309F00E4, + 0x1D90, 0x30A000C4, + 0x1D90, 0x30A100C3, + 0x1D90, 0x30A200C2, + 0x1D90, 0x30A300C1, + 0x1D90, 0x30A400A3, + 0x1D90, 0x30A500A2, + 0x1D90, 0x30A600A1, + 0x1D90, 0x30A70085, + 0x1D90, 0x30A80084, + 0x1D90, 0x30A90083, + 0x1D90, 0x30AA0082, + 0x1D90, 0x30AB0081, + 0x1D90, 0x30AC0067, + 0x1D90, 0x30AD0066, + 0x1D90, 0x30AE0065, + 0x1D90, 0x30AF0064, + 0x1D90, 0x30B00063, + 0x1D90, 0x30B10044, + 0x1D90, 0x30B20043, + 0x1D90, 0x30B30042, + 0x1D90, 0x30B40026, + 0x1D90, 0x30B50025, + 0x1D90, 0x30B60024, + 0x1D90, 0x30B70023, + 0x1D90, 0x30B80022, + 0x1D90, 0x30B90021, + 0x1D90, 0x30BA0005, + 0x1D90, 0x30BB0004, + 0x1D90, 0x30BC0003, + 0x1D90, 0x30BD0002, + 0x1D90, 0x30BE0001, + 0x1D90, 0x30BF0000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x30C000FF, + 0x1D90, 0x30C100FF, + 0x1D90, 0x30C200FF, + 0x1D90, 0x30C300FF, + 0x1D90, 0x30C400FF, + 0x1D90, 0x30C500FF, + 0x1D90, 0x30C600FE, + 0x1D90, 0x30C700FD, + 0x1D90, 0x30C800FC, + 0x1D90, 0x30C900FB, + 0x1D90, 0x30CA00FA, + 0x1D90, 0x30CB00F9, + 0x1D90, 0x30CC00F8, + 0x1D90, 0x30CD00F7, + 0x1D90, 0x30CE00F6, + 0x1D90, 0x30CF00F5, + 0x1D90, 0x30D000F4, + 0x1D90, 0x30D100F3, + 0x1D90, 0x30D200F2, + 0x1D90, 0x30D300F1, + 0x1D90, 0x30D400F0, + 0x1D90, 0x30D500EF, + 0x1D90, 0x30D600EE, + 0x1D90, 0x30D700ED, + 0x1D90, 0x30D800EC, + 0x1D90, 0x30D900EB, + 0x1D90, 0x30DA00EA, + 0x1D90, 0x30DB00E8, + 0x1D90, 0x30DC00E7, + 0x1D90, 0x30DD00E6, + 0x1D90, 0x30DE00E5, + 0x1D90, 0x30DF00E4, + 0x1D90, 0x30E000E3, + 0x1D90, 0x30E100E2, + 0x1D90, 0x30E200A6, + 0x1D90, 0x30E300A5, + 0x1D90, 0x30E400A4, + 0x1D90, 0x30E500A3, + 0x1D90, 0x30E600A2, + 0x1D90, 0x30E70086, + 0x1D90, 0x30E80085, + 0x1D90, 0x30E90084, + 0x1D90, 0x30EA0083, + 0x1D90, 0x30EB0082, + 0x1D90, 0x30EC0067, + 0x1D90, 0x30ED0066, + 0x1D90, 0x30EE0065, + 0x1D90, 0x30EF0064, + 0x1D90, 0x30F00063, + 0x1D90, 0x30F10045, + 0x1D90, 0x30F20044, + 0x1D90, 0x30F30043, + 0x1D90, 0x30F40042, + 0x1D90, 0x30F50025, + 0x1D90, 0x30F60024, + 0x1D90, 0x30F70023, + 0x1D90, 0x30F80022, + 0x1D90, 0x30F90021, + 0x1D90, 0x30FA0005, + 0x1D90, 0x30FB0004, + 0x1D90, 0x30FC0003, + 0x1D90, 0x30FD0002, + 0x1D90, 0x30FE0001, + 0x1D90, 0x30FF0000, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x30C000F8, + 0x1D90, 0x30C100F7, + 0x1D90, 0x30C200F6, + 0x1D90, 0x30C300F5, + 0x1D90, 0x30C400F4, + 0x1D90, 0x30C500F3, + 0x1D90, 0x30C600F2, + 0x1D90, 0x30C700F1, + 0x1D90, 0x30C800F0, + 0x1D90, 0x30C900EF, + 0x1D90, 0x30CA00EE, + 0x1D90, 0x30CB00ED, + 0x1D90, 0x30CC00EC, + 0x1D90, 0x30CD00EB, + 0x1D90, 0x30CE00EA, + 0x1D90, 0x30CF00E8, + 0x1D90, 0x30D000E7, + 0x1D90, 0x30D100E6, + 0x1D90, 0x30D200E5, + 0x1D90, 0x30D300E4, + 0x1D90, 0x30D400E3, + 0x1D90, 0x30D500E2, + 0x1D90, 0x30D600A6, + 0x1D90, 0x30D700A5, + 0x1D90, 0x30D800A4, + 0x1D90, 0x30D900A3, + 0x1D90, 0x30DA00A2, + 0x1D90, 0x30DB0086, + 0x1D90, 0x30DC0085, + 0x1D90, 0x30DD0084, + 0x1D90, 0x30DE0083, + 0x1D90, 0x30DF0081, + 0x1D90, 0x30E00068, + 0x1D90, 0x30E10067, + 0x1D90, 0x30E20066, + 0x1D90, 0x30E30065, + 0x1D90, 0x30E40064, + 0x1D90, 0x30E50045, + 0x1D90, 0x30E60044, + 0x1D90, 0x30E70043, + 0x1D90, 0x30E80042, + 0x1D90, 0x30E90025, + 0x1D90, 0x30EA0024, + 0x1D90, 0x30EB0023, + 0x1D90, 0x30EC0022, + 0x1D90, 0x30ED0021, + 0x1D90, 0x30EE0005, + 0x1D90, 0x30EF0004, + 0x1D90, 0x30F00003, + 0x1D90, 0x30F10002, + 0x1D90, 0x30F20001, + 0x1D90, 0x30F30000, + 0x1D90, 0x30F40000, + 0x1D90, 0x30F50000, + 0x1D90, 0x30F60000, + 0x1D90, 0x30F70000, + 0x1D90, 0x30F80000, + 0x1D90, 0x30F90000, + 0x1D90, 0x30FA0000, + 0x1D90, 0x30FB0000, + 0x1D90, 0x30FC0000, + 0x1D90, 0x30FD0000, + 0x1D90, 0x30FE0000, + 0x1D90, 0x30FF0000, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x30C000F8, + 0x1D90, 0x30C100F7, + 0x1D90, 0x30C200F6, + 0x1D90, 0x30C300F5, + 0x1D90, 0x30C400F4, + 0x1D90, 0x30C500F3, + 0x1D90, 0x30C600F2, + 0x1D90, 0x30C700F1, + 0x1D90, 0x30C800F0, + 0x1D90, 0x30C900EF, + 0x1D90, 0x30CA00EE, + 0x1D90, 0x30CB00ED, + 0x1D90, 0x30CC00EC, + 0x1D90, 0x30CD00EB, + 0x1D90, 0x30CE00EA, + 0x1D90, 0x30CF00E8, + 0x1D90, 0x30D000E7, + 0x1D90, 0x30D100E6, + 0x1D90, 0x30D200E5, + 0x1D90, 0x30D300E4, + 0x1D90, 0x30D400E3, + 0x1D90, 0x30D500E2, + 0x1D90, 0x30D600A6, + 0x1D90, 0x30D700A5, + 0x1D90, 0x30D800A4, + 0x1D90, 0x30D900A3, + 0x1D90, 0x30DA00A2, + 0x1D90, 0x30DB0086, + 0x1D90, 0x30DC0085, + 0x1D90, 0x30DD0084, + 0x1D90, 0x30DE0083, + 0x1D90, 0x30DF0081, + 0x1D90, 0x30E00068, + 0x1D90, 0x30E10067, + 0x1D90, 0x30E20066, + 0x1D90, 0x30E30065, + 0x1D90, 0x30E40064, + 0x1D90, 0x30E50045, + 0x1D90, 0x30E60044, + 0x1D90, 0x30E70043, + 0x1D90, 0x30E80042, + 0x1D90, 0x30E90025, + 0x1D90, 0x30EA0024, + 0x1D90, 0x30EB0023, + 0x1D90, 0x30EC0022, + 0x1D90, 0x30ED0021, + 0x1D90, 0x30EE0005, + 0x1D90, 0x30EF0004, + 0x1D90, 0x30F00003, + 0x1D90, 0x30F10002, + 0x1D90, 0x30F20001, + 0x1D90, 0x30F30000, + 0x1D90, 0x30F40000, + 0x1D90, 0x30F50000, + 0x1D90, 0x30F60000, + 0x1D90, 0x30F70000, + 0x1D90, 0x30F80000, + 0x1D90, 0x30F90000, + 0x1D90, 0x30FA0000, + 0x1D90, 0x30FB0000, + 0x1D90, 0x30FC0000, + 0x1D90, 0x30FD0000, + 0x1D90, 0x30FE0000, + 0x1D90, 0x30FF0000, + 0xA0000000, 0x00000000, + 0x1D90, 0x30C000FF, + 0x1D90, 0x30C100FF, + 0x1D90, 0x30C200FF, + 0x1D90, 0x30C300FF, + 0x1D90, 0x30C400FF, + 0x1D90, 0x30C500FF, + 0x1D90, 0x30C600FE, + 0x1D90, 0x30C700FD, + 0x1D90, 0x30C800FC, + 0x1D90, 0x30C900FB, + 0x1D90, 0x30CA00FA, + 0x1D90, 0x30CB00F9, + 0x1D90, 0x30CC00F8, + 0x1D90, 0x30CD00F7, + 0x1D90, 0x30CE00F6, + 0x1D90, 0x30CF00F5, + 0x1D90, 0x30D000F4, + 0x1D90, 0x30D100F3, + 0x1D90, 0x30D200F2, + 0x1D90, 0x30D300F1, + 0x1D90, 0x30D400F0, + 0x1D90, 0x30D500EF, + 0x1D90, 0x30D600EE, + 0x1D90, 0x30D700ED, + 0x1D90, 0x30D800EC, + 0x1D90, 0x30D900EB, + 0x1D90, 0x30DA00EA, + 0x1D90, 0x30DB00E8, + 0x1D90, 0x30DC00E7, + 0x1D90, 0x30DD00E6, + 0x1D90, 0x30DE00E5, + 0x1D90, 0x30DF00E4, + 0x1D90, 0x30E000E3, + 0x1D90, 0x30E100E2, + 0x1D90, 0x30E200A6, + 0x1D90, 0x30E300A5, + 0x1D90, 0x30E400A4, + 0x1D90, 0x30E500A3, + 0x1D90, 0x30E600A2, + 0x1D90, 0x30E70086, + 0x1D90, 0x30E80085, + 0x1D90, 0x30E90084, + 0x1D90, 0x30EA0083, + 0x1D90, 0x30EB0082, + 0x1D90, 0x30EC0067, + 0x1D90, 0x30ED0066, + 0x1D90, 0x30EE0065, + 0x1D90, 0x30EF0064, + 0x1D90, 0x30F00063, + 0x1D90, 0x30F10045, + 0x1D90, 0x30F20044, + 0x1D90, 0x30F30043, + 0x1D90, 0x30F40042, + 0x1D90, 0x30F50025, + 0x1D90, 0x30F60024, + 0x1D90, 0x30F70023, + 0x1D90, 0x30F80022, + 0x1D90, 0x30F90021, + 0x1D90, 0x30FA0005, + 0x1D90, 0x30FB0004, + 0x1D90, 0x30FC0003, + 0x1D90, 0x30FD0002, + 0x1D90, 0x30FE0001, + 0x1D90, 0x30FF0000, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x310001FF, + 0x1D90, 0x310101FF, + 0x1D90, 0x310201FF, + 0x1D90, 0x310301FF, + 0x1D90, 0x310401FE, + 0x1D90, 0x310501FD, + 0x1D90, 0x310601FC, + 0x1D90, 0x310701FB, + 0x1D90, 0x310801FA, + 0x1D90, 0x310901F9, + 0x1D90, 0x310A01F8, + 0x1D90, 0x310B01F7, + 0x1D90, 0x310C01F6, + 0x1D90, 0x310D01F5, + 0x1D90, 0x310E01F4, + 0x1D90, 0x310F01F3, + 0x1D90, 0x311001F2, + 0x1D90, 0x311101F1, + 0x1D90, 0x311201F0, + 0x1D90, 0x311301EF, + 0x1D90, 0x311401EE, + 0x1D90, 0x311501ED, + 0x1D90, 0x311601EC, + 0x1D90, 0x311701EB, + 0x1D90, 0x311801EA, + 0x1D90, 0x311901E9, + 0x1D90, 0x311A01E8, + 0x1D90, 0x311B01E7, + 0x1D90, 0x311C01E5, + 0x1D90, 0x311D01E4, + 0x1D90, 0x311E01C5, + 0x1D90, 0x311F01C4, + 0x1D90, 0x312001C3, + 0x1D90, 0x312101C2, + 0x1D90, 0x31220188, + 0x1D90, 0x31230187, + 0x1D90, 0x31240186, + 0x1D90, 0x31250184, + 0x1D90, 0x31260183, + 0x1D90, 0x31270182, + 0x1D90, 0x31280181, + 0x1D90, 0x31290148, + 0x1D90, 0x312A0147, + 0x1D90, 0x312B0146, + 0x1D90, 0x312C0144, + 0x1D90, 0x312D0143, + 0x1D90, 0x312E0142, + 0x1D90, 0x312F0141, + 0x1D90, 0x313000C8, + 0x1D90, 0x313100C7, + 0x1D90, 0x313200C6, + 0x1D90, 0x313300C5, + 0x1D90, 0x313400C4, + 0x1D90, 0x313500C3, + 0x1D90, 0x31360048, + 0x1D90, 0x31370047, + 0x1D90, 0x31380046, + 0x1D90, 0x31390045, + 0x1D90, 0x313A0025, + 0x1D90, 0x313B0024, + 0x1D90, 0x313C0023, + 0x1D90, 0x313D0022, + 0x1D90, 0x313E0021, + 0x1D90, 0x313F0020, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x310001FF, + 0x1D90, 0x310101FF, + 0x1D90, 0x310201FF, + 0x1D90, 0x310301FF, + 0x1D90, 0x310401FE, + 0x1D90, 0x310501FD, + 0x1D90, 0x310601FC, + 0x1D90, 0x310701FB, + 0x1D90, 0x310801FA, + 0x1D90, 0x310901F9, + 0x1D90, 0x310A01F8, + 0x1D90, 0x310B01F7, + 0x1D90, 0x310C01F6, + 0x1D90, 0x310D01F5, + 0x1D90, 0x310E01F4, + 0x1D90, 0x310F01F3, + 0x1D90, 0x311001F2, + 0x1D90, 0x311101F1, + 0x1D90, 0x311201F0, + 0x1D90, 0x311301EF, + 0x1D90, 0x311401EE, + 0x1D90, 0x311501ED, + 0x1D90, 0x311601EC, + 0x1D90, 0x311701EB, + 0x1D90, 0x311801EA, + 0x1D90, 0x311901E9, + 0x1D90, 0x311A01E8, + 0x1D90, 0x311B01E7, + 0x1D90, 0x311C01E5, + 0x1D90, 0x311D01E4, + 0x1D90, 0x311E01C5, + 0x1D90, 0x311F01C4, + 0x1D90, 0x312001C3, + 0x1D90, 0x312101C2, + 0x1D90, 0x31220188, + 0x1D90, 0x31230187, + 0x1D90, 0x31240186, + 0x1D90, 0x31250184, + 0x1D90, 0x31260183, + 0x1D90, 0x31270182, + 0x1D90, 0x31280181, + 0x1D90, 0x31290148, + 0x1D90, 0x312A0147, + 0x1D90, 0x312B0146, + 0x1D90, 0x312C0144, + 0x1D90, 0x312D0143, + 0x1D90, 0x312E0142, + 0x1D90, 0x312F0141, + 0x1D90, 0x313000C8, + 0x1D90, 0x313100C7, + 0x1D90, 0x313200C6, + 0x1D90, 0x313300C5, + 0x1D90, 0x313400C4, + 0x1D90, 0x313500C3, + 0x1D90, 0x31360048, + 0x1D90, 0x31370047, + 0x1D90, 0x31380046, + 0x1D90, 0x31390045, + 0x1D90, 0x313A0025, + 0x1D90, 0x313B0024, + 0x1D90, 0x313C0023, + 0x1D90, 0x313D0022, + 0x1D90, 0x313E0021, + 0x1D90, 0x313F0020, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x310001FF, + 0x1D90, 0x310101FF, + 0x1D90, 0x310201FF, + 0x1D90, 0x310301FF, + 0x1D90, 0x310401FE, + 0x1D90, 0x310501FD, + 0x1D90, 0x310601FC, + 0x1D90, 0x310701FB, + 0x1D90, 0x310801FA, + 0x1D90, 0x310901F9, + 0x1D90, 0x310A01F8, + 0x1D90, 0x310B01F7, + 0x1D90, 0x310C01F6, + 0x1D90, 0x310D01F5, + 0x1D90, 0x310E01F4, + 0x1D90, 0x310F01F3, + 0x1D90, 0x311001F2, + 0x1D90, 0x311101F1, + 0x1D90, 0x311201F0, + 0x1D90, 0x311301EF, + 0x1D90, 0x311401EE, + 0x1D90, 0x311501ED, + 0x1D90, 0x311601EC, + 0x1D90, 0x311701EB, + 0x1D90, 0x311801EA, + 0x1D90, 0x311901E9, + 0x1D90, 0x311A01E8, + 0x1D90, 0x311B01E7, + 0x1D90, 0x311C01E5, + 0x1D90, 0x311D01E4, + 0x1D90, 0x311E01C5, + 0x1D90, 0x311F01C4, + 0x1D90, 0x312001C3, + 0x1D90, 0x312101C2, + 0x1D90, 0x31220188, + 0x1D90, 0x31230187, + 0x1D90, 0x31240186, + 0x1D90, 0x31250184, + 0x1D90, 0x31260183, + 0x1D90, 0x31270182, + 0x1D90, 0x31280181, + 0x1D90, 0x31290148, + 0x1D90, 0x312A0147, + 0x1D90, 0x312B0146, + 0x1D90, 0x312C0144, + 0x1D90, 0x312D0143, + 0x1D90, 0x312E0142, + 0x1D90, 0x312F0141, + 0x1D90, 0x313000C8, + 0x1D90, 0x313100C7, + 0x1D90, 0x313200C6, + 0x1D90, 0x313300C5, + 0x1D90, 0x313400C4, + 0x1D90, 0x313500C3, + 0x1D90, 0x31360048, + 0x1D90, 0x31370047, + 0x1D90, 0x31380046, + 0x1D90, 0x31390045, + 0x1D90, 0x313A0025, + 0x1D90, 0x313B0024, + 0x1D90, 0x313C0023, + 0x1D90, 0x313D0022, + 0x1D90, 0x313E0021, + 0x1D90, 0x313F0020, + 0xA0000000, 0x00000000, + 0x1D90, 0x310001FF, + 0x1D90, 0x310101FF, + 0x1D90, 0x310201FF, + 0x1D90, 0x310301FF, + 0x1D90, 0x310401FE, + 0x1D90, 0x310501FD, + 0x1D90, 0x310601FC, + 0x1D90, 0x310701FB, + 0x1D90, 0x310801FA, + 0x1D90, 0x310901F9, + 0x1D90, 0x310A01F8, + 0x1D90, 0x310B01F7, + 0x1D90, 0x310C01F6, + 0x1D90, 0x310D01F5, + 0x1D90, 0x310E01F4, + 0x1D90, 0x310F01F3, + 0x1D90, 0x311001F2, + 0x1D90, 0x311101F1, + 0x1D90, 0x311201F0, + 0x1D90, 0x311301EF, + 0x1D90, 0x311401EE, + 0x1D90, 0x311501ED, + 0x1D90, 0x311601EC, + 0x1D90, 0x311701EB, + 0x1D90, 0x311801EA, + 0x1D90, 0x311901E9, + 0x1D90, 0x311A01E8, + 0x1D90, 0x311B01E7, + 0x1D90, 0x311C01E5, + 0x1D90, 0x311D01E4, + 0x1D90, 0x311E01C5, + 0x1D90, 0x311F01C4, + 0x1D90, 0x312001C3, + 0x1D90, 0x312101C2, + 0x1D90, 0x31220188, + 0x1D90, 0x31230187, + 0x1D90, 0x31240186, + 0x1D90, 0x31250184, + 0x1D90, 0x31260183, + 0x1D90, 0x31270182, + 0x1D90, 0x31280181, + 0x1D90, 0x31290148, + 0x1D90, 0x312A0147, + 0x1D90, 0x312B0146, + 0x1D90, 0x312C0144, + 0x1D90, 0x312D0143, + 0x1D90, 0x312E0142, + 0x1D90, 0x312F0141, + 0x1D90, 0x313000C8, + 0x1D90, 0x313100C7, + 0x1D90, 0x313200C6, + 0x1D90, 0x313300C5, + 0x1D90, 0x313400C4, + 0x1D90, 0x313500C3, + 0x1D90, 0x31360048, + 0x1D90, 0x31370047, + 0x1D90, 0x31380046, + 0x1D90, 0x31390045, + 0x1D90, 0x313A0025, + 0x1D90, 0x313B0024, + 0x1D90, 0x313C0023, + 0x1D90, 0x313D0022, + 0x1D90, 0x313E0021, + 0x1D90, 0x313F0020, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x314001FF, + 0x1D90, 0x314101FF, + 0x1D90, 0x314201FF, + 0x1D90, 0x314301FF, + 0x1D90, 0x314401FF, + 0x1D90, 0x314501FF, + 0x1D90, 0x314601FE, + 0x1D90, 0x314701FD, + 0x1D90, 0x314801FC, + 0x1D90, 0x314901FB, + 0x1D90, 0x314A01FA, + 0x1D90, 0x314B01F9, + 0x1D90, 0x314C01F8, + 0x1D90, 0x314D01F7, + 0x1D90, 0x314E01F6, + 0x1D90, 0x314F01F5, + 0x1D90, 0x315001F4, + 0x1D90, 0x315101F3, + 0x1D90, 0x315201F2, + 0x1D90, 0x315301F1, + 0x1D90, 0x315401F0, + 0x1D90, 0x315501EF, + 0x1D90, 0x315601EE, + 0x1D90, 0x315701ED, + 0x1D90, 0x315801EC, + 0x1D90, 0x315901EB, + 0x1D90, 0x315A01EA, + 0x1D90, 0x315B01E9, + 0x1D90, 0x315C01E7, + 0x1D90, 0x315D01E6, + 0x1D90, 0x315E01E5, + 0x1D90, 0x315F01E4, + 0x1D90, 0x316001A8, + 0x1D90, 0x316101A7, + 0x1D90, 0x316201A6, + 0x1D90, 0x316301A5, + 0x1D90, 0x31640185, + 0x1D90, 0x31650184, + 0x1D90, 0x31660183, + 0x1D90, 0x31670182, + 0x1D90, 0x31680149, + 0x1D90, 0x31690148, + 0x1D90, 0x316A0147, + 0x1D90, 0x316B0145, + 0x1D90, 0x316C0144, + 0x1D90, 0x316D0143, + 0x1D90, 0x316E0142, + 0x1D90, 0x316F00E6, + 0x1D90, 0x317000E5, + 0x1D90, 0x317100C9, + 0x1D90, 0x317200C8, + 0x1D90, 0x317300C7, + 0x1D90, 0x317400C6, + 0x1D90, 0x317500C5, + 0x1D90, 0x317600C4, + 0x1D90, 0x317700C3, + 0x1D90, 0x31780088, + 0x1D90, 0x31790087, + 0x1D90, 0x317A0086, + 0x1D90, 0x317B0085, + 0x1D90, 0x317C0026, + 0x1D90, 0x317D0025, + 0x1D90, 0x317E0024, + 0x1D90, 0x317F0023, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x314001FF, + 0x1D90, 0x314101FF, + 0x1D90, 0x314201FF, + 0x1D90, 0x314301FF, + 0x1D90, 0x314401FF, + 0x1D90, 0x314501FF, + 0x1D90, 0x314601FE, + 0x1D90, 0x314701FD, + 0x1D90, 0x314801FC, + 0x1D90, 0x314901FB, + 0x1D90, 0x314A01FA, + 0x1D90, 0x314B01F9, + 0x1D90, 0x314C01F8, + 0x1D90, 0x314D01F7, + 0x1D90, 0x314E01F6, + 0x1D90, 0x314F01F5, + 0x1D90, 0x315001F4, + 0x1D90, 0x315101F3, + 0x1D90, 0x315201F2, + 0x1D90, 0x315301F1, + 0x1D90, 0x315401F0, + 0x1D90, 0x315501EF, + 0x1D90, 0x315601EE, + 0x1D90, 0x315701ED, + 0x1D90, 0x315801EC, + 0x1D90, 0x315901EB, + 0x1D90, 0x315A01EA, + 0x1D90, 0x315B01E9, + 0x1D90, 0x315C01E7, + 0x1D90, 0x315D01E6, + 0x1D90, 0x315E01E5, + 0x1D90, 0x315F01E4, + 0x1D90, 0x316001A8, + 0x1D90, 0x316101A7, + 0x1D90, 0x316201A6, + 0x1D90, 0x316301A5, + 0x1D90, 0x31640185, + 0x1D90, 0x31650184, + 0x1D90, 0x31660183, + 0x1D90, 0x31670182, + 0x1D90, 0x31680149, + 0x1D90, 0x31690148, + 0x1D90, 0x316A0147, + 0x1D90, 0x316B0145, + 0x1D90, 0x316C0144, + 0x1D90, 0x316D0143, + 0x1D90, 0x316E0142, + 0x1D90, 0x316F00E6, + 0x1D90, 0x317000E5, + 0x1D90, 0x317100C9, + 0x1D90, 0x317200C8, + 0x1D90, 0x317300C7, + 0x1D90, 0x317400C6, + 0x1D90, 0x317500C5, + 0x1D90, 0x317600C4, + 0x1D90, 0x317700C3, + 0x1D90, 0x31780088, + 0x1D90, 0x31790087, + 0x1D90, 0x317A0086, + 0x1D90, 0x317B0085, + 0x1D90, 0x317C0026, + 0x1D90, 0x317D0025, + 0x1D90, 0x317E0024, + 0x1D90, 0x317F0023, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x314001FF, + 0x1D90, 0x314101FF, + 0x1D90, 0x314201FF, + 0x1D90, 0x314301FF, + 0x1D90, 0x314401FF, + 0x1D90, 0x314501FF, + 0x1D90, 0x314601FE, + 0x1D90, 0x314701FD, + 0x1D90, 0x314801FC, + 0x1D90, 0x314901FB, + 0x1D90, 0x314A01FA, + 0x1D90, 0x314B01F9, + 0x1D90, 0x314C01F8, + 0x1D90, 0x314D01F7, + 0x1D90, 0x314E01F6, + 0x1D90, 0x314F01F5, + 0x1D90, 0x315001F4, + 0x1D90, 0x315101F3, + 0x1D90, 0x315201F2, + 0x1D90, 0x315301F1, + 0x1D90, 0x315401F0, + 0x1D90, 0x315501EF, + 0x1D90, 0x315601EE, + 0x1D90, 0x315701ED, + 0x1D90, 0x315801EC, + 0x1D90, 0x315901EB, + 0x1D90, 0x315A01EA, + 0x1D90, 0x315B01E9, + 0x1D90, 0x315C01E7, + 0x1D90, 0x315D01E6, + 0x1D90, 0x315E01E5, + 0x1D90, 0x315F01E4, + 0x1D90, 0x316001A8, + 0x1D90, 0x316101A7, + 0x1D90, 0x316201A6, + 0x1D90, 0x316301A5, + 0x1D90, 0x31640185, + 0x1D90, 0x31650184, + 0x1D90, 0x31660183, + 0x1D90, 0x31670182, + 0x1D90, 0x31680149, + 0x1D90, 0x31690148, + 0x1D90, 0x316A0147, + 0x1D90, 0x316B0145, + 0x1D90, 0x316C0144, + 0x1D90, 0x316D0143, + 0x1D90, 0x316E0142, + 0x1D90, 0x316F00E6, + 0x1D90, 0x317000E5, + 0x1D90, 0x317100C9, + 0x1D90, 0x317200C8, + 0x1D90, 0x317300C7, + 0x1D90, 0x317400C6, + 0x1D90, 0x317500C5, + 0x1D90, 0x317600C4, + 0x1D90, 0x317700C3, + 0x1D90, 0x31780088, + 0x1D90, 0x31790087, + 0x1D90, 0x317A0086, + 0x1D90, 0x317B0085, + 0x1D90, 0x317C0026, + 0x1D90, 0x317D0025, + 0x1D90, 0x317E0024, + 0x1D90, 0x317F0023, + 0xA0000000, 0x00000000, + 0x1D90, 0x314001FF, + 0x1D90, 0x314101FF, + 0x1D90, 0x314201FF, + 0x1D90, 0x314301FF, + 0x1D90, 0x314401FF, + 0x1D90, 0x314501FF, + 0x1D90, 0x314601FE, + 0x1D90, 0x314701FD, + 0x1D90, 0x314801FC, + 0x1D90, 0x314901FB, + 0x1D90, 0x314A01FA, + 0x1D90, 0x314B01F9, + 0x1D90, 0x314C01F8, + 0x1D90, 0x314D01F7, + 0x1D90, 0x314E01F6, + 0x1D90, 0x314F01F5, + 0x1D90, 0x315001F4, + 0x1D90, 0x315101F3, + 0x1D90, 0x315201F2, + 0x1D90, 0x315301F1, + 0x1D90, 0x315401F0, + 0x1D90, 0x315501EF, + 0x1D90, 0x315601EE, + 0x1D90, 0x315701ED, + 0x1D90, 0x315801EC, + 0x1D90, 0x315901EB, + 0x1D90, 0x315A01EA, + 0x1D90, 0x315B01E9, + 0x1D90, 0x315C01E7, + 0x1D90, 0x315D01E6, + 0x1D90, 0x315E01E5, + 0x1D90, 0x315F01E4, + 0x1D90, 0x316001A8, + 0x1D90, 0x316101A7, + 0x1D90, 0x316201A6, + 0x1D90, 0x316301A5, + 0x1D90, 0x31640185, + 0x1D90, 0x31650184, + 0x1D90, 0x31660183, + 0x1D90, 0x31670182, + 0x1D90, 0x31680149, + 0x1D90, 0x31690148, + 0x1D90, 0x316A0147, + 0x1D90, 0x316B0145, + 0x1D90, 0x316C0144, + 0x1D90, 0x316D0143, + 0x1D90, 0x316E0142, + 0x1D90, 0x316F00E6, + 0x1D90, 0x317000E5, + 0x1D90, 0x317100C9, + 0x1D90, 0x317200C8, + 0x1D90, 0x317300C7, + 0x1D90, 0x317400C6, + 0x1D90, 0x317500C5, + 0x1D90, 0x317600C4, + 0x1D90, 0x317700C3, + 0x1D90, 0x31780088, + 0x1D90, 0x31790087, + 0x1D90, 0x317A0086, + 0x1D90, 0x317B0085, + 0x1D90, 0x317C0026, + 0x1D90, 0x317D0025, + 0x1D90, 0x317E0024, + 0x1D90, 0x317F0023, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x318001FE, + 0x1D90, 0x318101FD, + 0x1D90, 0x318201FC, + 0x1D90, 0x318301FB, + 0x1D90, 0x318401FA, + 0x1D90, 0x318501F9, + 0x1D90, 0x318601F8, + 0x1D90, 0x318701F7, + 0x1D90, 0x318801F6, + 0x1D90, 0x318901F5, + 0x1D90, 0x318A01F4, + 0x1D90, 0x318B01F3, + 0x1D90, 0x318C01F2, + 0x1D90, 0x318D01F1, + 0x1D90, 0x318E01F0, + 0x1D90, 0x318F01EF, + 0x1D90, 0x319001EE, + 0x1D90, 0x319101ED, + 0x1D90, 0x319201EC, + 0x1D90, 0x319301EB, + 0x1D90, 0x319401EA, + 0x1D90, 0x319501E9, + 0x1D90, 0x319601E7, + 0x1D90, 0x319701E6, + 0x1D90, 0x319801E5, + 0x1D90, 0x319901E4, + 0x1D90, 0x319A01A8, + 0x1D90, 0x319B01A7, + 0x1D90, 0x319C01A6, + 0x1D90, 0x319D01A5, + 0x1D90, 0x319E0185, + 0x1D90, 0x319F0184, + 0x1D90, 0x31A00183, + 0x1D90, 0x31A10182, + 0x1D90, 0x31A20149, + 0x1D90, 0x31A30148, + 0x1D90, 0x31A40147, + 0x1D90, 0x31A50145, + 0x1D90, 0x31A60144, + 0x1D90, 0x31A70143, + 0x1D90, 0x31A80142, + 0x1D90, 0x31A900E6, + 0x1D90, 0x31AA00E5, + 0x1D90, 0x31AB00C9, + 0x1D90, 0x31AC00C8, + 0x1D90, 0x31AD00C7, + 0x1D90, 0x31AE00C6, + 0x1D90, 0x31AF00C5, + 0x1D90, 0x31B000C4, + 0x1D90, 0x31B100C3, + 0x1D90, 0x31B20088, + 0x1D90, 0x31B30087, + 0x1D90, 0x31B40086, + 0x1D90, 0x31B50085, + 0x1D90, 0x31B60026, + 0x1D90, 0x31B70025, + 0x1D90, 0x31B80024, + 0x1D90, 0x31B90023, + 0x1D90, 0x31BA0022, + 0x1D90, 0x31BB0021, + 0x1D90, 0x31BC0020, + 0x1D90, 0x31BD0003, + 0x1D90, 0x31BE0002, + 0x1D90, 0x31BF0001, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x318001FE, + 0x1D90, 0x318101FD, + 0x1D90, 0x318201FC, + 0x1D90, 0x318301FB, + 0x1D90, 0x318401FA, + 0x1D90, 0x318501F9, + 0x1D90, 0x318601F8, + 0x1D90, 0x318701F7, + 0x1D90, 0x318801F6, + 0x1D90, 0x318901F5, + 0x1D90, 0x318A01F4, + 0x1D90, 0x318B01F3, + 0x1D90, 0x318C01F2, + 0x1D90, 0x318D01F1, + 0x1D90, 0x318E01F0, + 0x1D90, 0x318F01EF, + 0x1D90, 0x319001EE, + 0x1D90, 0x319101ED, + 0x1D90, 0x319201EC, + 0x1D90, 0x319301EB, + 0x1D90, 0x319401EA, + 0x1D90, 0x319501E9, + 0x1D90, 0x319601E7, + 0x1D90, 0x319701E6, + 0x1D90, 0x319801E5, + 0x1D90, 0x319901E4, + 0x1D90, 0x319A01A8, + 0x1D90, 0x319B01A7, + 0x1D90, 0x319C01A6, + 0x1D90, 0x319D01A5, + 0x1D90, 0x319E0185, + 0x1D90, 0x319F0184, + 0x1D90, 0x31A00183, + 0x1D90, 0x31A10182, + 0x1D90, 0x31A20149, + 0x1D90, 0x31A30148, + 0x1D90, 0x31A40147, + 0x1D90, 0x31A50145, + 0x1D90, 0x31A60144, + 0x1D90, 0x31A70143, + 0x1D90, 0x31A80142, + 0x1D90, 0x31A900E6, + 0x1D90, 0x31AA00E5, + 0x1D90, 0x31AB00C9, + 0x1D90, 0x31AC00C8, + 0x1D90, 0x31AD00C7, + 0x1D90, 0x31AE00C6, + 0x1D90, 0x31AF00C5, + 0x1D90, 0x31B000C4, + 0x1D90, 0x31B100C3, + 0x1D90, 0x31B20088, + 0x1D90, 0x31B30087, + 0x1D90, 0x31B40086, + 0x1D90, 0x31B50085, + 0x1D90, 0x31B60026, + 0x1D90, 0x31B70025, + 0x1D90, 0x31B80024, + 0x1D90, 0x31B90023, + 0x1D90, 0x31BA0022, + 0x1D90, 0x31BB0021, + 0x1D90, 0x31BC0020, + 0x1D90, 0x31BD0003, + 0x1D90, 0x31BE0002, + 0x1D90, 0x31BF0001, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D90, 0x318001FE, + 0x1D90, 0x318101FD, + 0x1D90, 0x318201FC, + 0x1D90, 0x318301FB, + 0x1D90, 0x318401FA, + 0x1D90, 0x318501F9, + 0x1D90, 0x318601F8, + 0x1D90, 0x318701F7, + 0x1D90, 0x318801F6, + 0x1D90, 0x318901F5, + 0x1D90, 0x318A01F4, + 0x1D90, 0x318B01F3, + 0x1D90, 0x318C01F2, + 0x1D90, 0x318D01F1, + 0x1D90, 0x318E01F0, + 0x1D90, 0x318F01EF, + 0x1D90, 0x319001EE, + 0x1D90, 0x319101ED, + 0x1D90, 0x319201EC, + 0x1D90, 0x319301EB, + 0x1D90, 0x319401EA, + 0x1D90, 0x319501E9, + 0x1D90, 0x319601E7, + 0x1D90, 0x319701E6, + 0x1D90, 0x319801E5, + 0x1D90, 0x319901E4, + 0x1D90, 0x319A01A8, + 0x1D90, 0x319B01A7, + 0x1D90, 0x319C01A6, + 0x1D90, 0x319D01A5, + 0x1D90, 0x319E0185, + 0x1D90, 0x319F0184, + 0x1D90, 0x31A00183, + 0x1D90, 0x31A10182, + 0x1D90, 0x31A20149, + 0x1D90, 0x31A30148, + 0x1D90, 0x31A40147, + 0x1D90, 0x31A50145, + 0x1D90, 0x31A60144, + 0x1D90, 0x31A70143, + 0x1D90, 0x31A80142, + 0x1D90, 0x31A900E6, + 0x1D90, 0x31AA00E5, + 0x1D90, 0x31AB00C9, + 0x1D90, 0x31AC00C8, + 0x1D90, 0x31AD00C7, + 0x1D90, 0x31AE00C6, + 0x1D90, 0x31AF00C5, + 0x1D90, 0x31B000C4, + 0x1D90, 0x31B100C3, + 0x1D90, 0x31B20088, + 0x1D90, 0x31B30087, + 0x1D90, 0x31B40086, + 0x1D90, 0x31B50085, + 0x1D90, 0x31B60026, + 0x1D90, 0x31B70025, + 0x1D90, 0x31B80024, + 0x1D90, 0x31B90023, + 0x1D90, 0x31BA0022, + 0x1D90, 0x31BB0021, + 0x1D90, 0x31BC0020, + 0x1D90, 0x31BD0003, + 0x1D90, 0x31BE0002, + 0x1D90, 0x31BF0001, + 0xA0000000, 0x00000000, + 0x1D90, 0x318001FE, + 0x1D90, 0x318101FD, + 0x1D90, 0x318201FC, + 0x1D90, 0x318301FB, + 0x1D90, 0x318401FA, + 0x1D90, 0x318501F9, + 0x1D90, 0x318601F8, + 0x1D90, 0x318701F7, + 0x1D90, 0x318801F6, + 0x1D90, 0x318901F5, + 0x1D90, 0x318A01F4, + 0x1D90, 0x318B01F3, + 0x1D90, 0x318C01F2, + 0x1D90, 0x318D01F1, + 0x1D90, 0x318E01F0, + 0x1D90, 0x318F01EF, + 0x1D90, 0x319001EE, + 0x1D90, 0x319101ED, + 0x1D90, 0x319201EC, + 0x1D90, 0x319301EB, + 0x1D90, 0x319401EA, + 0x1D90, 0x319501E9, + 0x1D90, 0x319601E7, + 0x1D90, 0x319701E6, + 0x1D90, 0x319801E5, + 0x1D90, 0x319901E4, + 0x1D90, 0x319A01A8, + 0x1D90, 0x319B01A7, + 0x1D90, 0x319C01A6, + 0x1D90, 0x319D01A5, + 0x1D90, 0x319E0185, + 0x1D90, 0x319F0184, + 0x1D90, 0x31A00183, + 0x1D90, 0x31A10182, + 0x1D90, 0x31A20149, + 0x1D90, 0x31A30148, + 0x1D90, 0x31A40147, + 0x1D90, 0x31A50145, + 0x1D90, 0x31A60144, + 0x1D90, 0x31A70143, + 0x1D90, 0x31A80142, + 0x1D90, 0x31A900E6, + 0x1D90, 0x31AA00E5, + 0x1D90, 0x31AB00C9, + 0x1D90, 0x31AC00C8, + 0x1D90, 0x31AD00C7, + 0x1D90, 0x31AE00C6, + 0x1D90, 0x31AF00C5, + 0x1D90, 0x31B000C4, + 0x1D90, 0x31B100C3, + 0x1D90, 0x31B20088, + 0x1D90, 0x31B30087, + 0x1D90, 0x31B40086, + 0x1D90, 0x31B50085, + 0x1D90, 0x31B60026, + 0x1D90, 0x31B70025, + 0x1D90, 0x31B80024, + 0x1D90, 0x31B90023, + 0x1D90, 0x31BA0022, + 0x1D90, 0x31BB0021, + 0x1D90, 0x31BC0020, + 0x1D90, 0x31BD0003, + 0x1D90, 0x31BE0002, + 0x1D90, 0x31BF0001, + 0xB0000000, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1D70, 0x22222222, + 0x1D70, 0x20202020, + 0x90000015, 0x00000000, 0x40000000, 0x00000000, + 0x1D70, 0x22222222, + 0x1D70, 0x20202020, + 0x90000016, 0x00000000, 0x40000000, 0x00000000, + 0x1D70, 0x22222222, + 0x1D70, 0x20202020, + 0xA0000000, 0x00000000, + 0x1D70, 0x22222222, + 0x1D70, 0x20202020, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822c_agc, rtw_phy_cfg_agc); + +static const u32 rtw8822c_bb[] = { + 0x1D0C, 0x00410000, + 0x1C3C, 0x01038040, + 0x1C90, 0x00E49708, + 0x800, 0x00000000, + 0x804, 0xD6300000, + 0x808, 0x60956093, + 0x80C, 0x00000025, + 0x810, 0x11B019B0, + 0x814, 0x00904080, + 0x818, 0xC30056F1, + 0x81C, 0x00050000, + 0x820, 0x11111111, + 0x824, 0xC3C3CCC4, + 0x828, 0x30FB186C, + 0x82C, 0x185D6556, + 0x830, 0x1751145B, + 0x834, 0x776995D7, + 0x838, 0x74777A7D, + 0x83C, 0xF9AA9982, + 0x840, 0x89AA9ABB, + 0x844, 0x0DEEDDC1, + 0x848, 0xCDEEDEFF, + 0x84C, 0xFFFF5555, + 0x850, 0x6F7A727D, + 0x854, 0x6C776F7A, + 0x858, 0x6F7A6C77, + 0x85C, 0x69746974, + 0x860, 0x6F7A6C77, + 0x864, 0x6C776C77, + 0x868, 0x727D6F7A, + 0x86C, 0x69D7B196, + 0x870, 0x1A6D769B, + 0x874, 0x55823917, + 0x878, 0x00C025BD, + 0x87C, 0x4140557D, + 0x880, 0x9A1D9D47, + 0x884, 0x1DE7134F, + 0x888, 0x2857A857, + 0x88C, 0x520E8A24, + 0x890, 0x8F628C44, + 0x894, 0x72745F43, + 0x898, 0x03F02F0D, + 0x89C, 0x5DB6886F, + 0x8A0, 0x07DC309F, + 0x8A4, 0x09412495, + 0x8A8, 0x222222A9, + 0x8AC, 0x89628C44, + 0x8B0, 0x72745F43, + 0x8B4, 0x03F02F0D, + 0x8B8, 0x55B6886F, + 0x8BC, 0x07D0309F, + 0x8C0, 0x70404023, + 0x8C4, 0x00440001, + 0x8C8, 0x7A7A2E26, + 0x8CC, 0x25297777, + 0x8D0, 0x6CEB6DCE, + 0x8D4, 0x0005A632, + 0x8D8, 0x00000000, + 0x8DC, 0x00000000, + 0x8E0, 0x00000000, + 0x8E4, 0x00000000, + 0x8E8, 0x00000000, + 0x8EC, 0x00000000, + 0x8F0, 0x00000000, + 0x8F4, 0x00000000, + 0x8F8, 0x25239843, + 0x900, 0x00000000, + 0x904, 0x00000000, + 0x908, 0x000008CB, + 0x90C, 0x00000000, + 0x910, 0x00000000, + 0x914, 0x20000000, + 0x918, 0x20000000, + 0x91C, 0x20000000, + 0x920, 0x20000000, + 0x924, 0x00000000, + 0x928, 0x0000003A, + 0x92C, 0x0000003A, + 0x930, 0x0000003A, + 0x934, 0x0000003A, + 0x938, 0x0000000F, + 0x93C, 0x00000000, + 0x940, 0x4E1F3E81, + 0x944, 0x4E1F3E81, + 0x948, 0x4E1F3E81, + 0x94C, 0x4E1F3E81, + 0x950, 0x03020100, + 0x954, 0x07060504, + 0x958, 0x0B0A0908, + 0x95C, 0x0F0E0D0C, + 0x960, 0x13121110, + 0x964, 0x17161514, + 0x968, 0x03020100, + 0x96C, 0x07060504, + 0x970, 0x0B0A0908, + 0x974, 0x0F0E0D0C, + 0x978, 0x13121110, + 0x97C, 0x17161514, + 0x980, 0x03020100, + 0x984, 0x07060504, + 0x988, 0x0B0A0908, + 0x98C, 0x0F0E0D0C, + 0x990, 0x13121110, + 0x994, 0x17161514, + 0x998, 0x03020100, + 0x99C, 0x07060504, + 0x9A0, 0x0B0A0908, + 0x9A4, 0x0F0E0D0C, + 0x9A8, 0x13121110, + 0x9AC, 0x17161514, + 0x9B0, 0x00002200, + 0x9B4, 0xDB6FFF00, + 0x9B8, 0x00400064, + 0x9BC, 0x00000000, + 0x9C0, 0x01010101, + 0x9C4, 0x00640064, + 0x9C8, 0x00640064, + 0x9CC, 0x00007777, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00000000, + 0x9E4, 0x00000000, + 0x9E8, 0x00000000, + 0x9EC, 0x00000000, + 0x9F0, 0x100024E0, + 0x9F4, 0x00000000, + 0x9F8, 0x00000000, + 0xA00, 0x02001208, + 0xA04, 0x00000000, + 0xA08, 0x00000000, + 0xA0C, 0x00000000, + 0xA10, 0x00000000, + 0xA14, 0x00000000, + 0xA18, 0x00000000, + 0xA1C, 0x00000000, + 0xA20, 0xCB31B333, + 0xA24, 0x00275485, + 0xA28, 0x00166366, + 0xA2C, 0x00275485, + 0xA30, 0x00166366, + 0xA34, 0x00275485, + 0xA38, 0x00200400, + 0xA3C, 0x00200400, + 0xA40, 0xB35DC5BD, + 0xA44, 0x3033BEBD, + 0xA48, 0x2A521254, + 0xA4C, 0xA2733345, + 0xA50, 0x617BE003, + 0xA54, 0x50000968, + 0xA58, 0x00020000, + 0xA5C, 0x01000000, + 0xA60, 0x02000000, + 0xA64, 0x03000000, + 0xA68, 0x00020000, + 0xA6C, 0x00000000, + 0xA70, 0x00000000, + 0xA74, 0x00000000, + 0xA78, 0x00000000, + 0xA7C, 0x00000000, + 0xA80, 0x00000000, + 0xA84, 0x00000000, + 0xA88, 0x00000000, + 0xA8C, 0x00000000, + 0xA90, 0x00000000, + 0xA94, 0x00000000, + 0xA98, 0x00000000, + 0xA9C, 0x00000000, + 0xAA0, 0x00000000, + 0xAA4, 0x00000000, + 0xAA8, 0x00000000, + 0xAAC, 0x00000000, + 0xAB0, 0x00000000, + 0xAB4, 0x00000000, + 0xAB8, 0x00000000, + 0xABC, 0x00000000, + 0xAC0, 0x00000000, + 0xAC4, 0x00000000, + 0xAC8, 0x00000000, + 0xACC, 0x00000000, + 0xAD0, 0x00000000, + 0xAD4, 0x00000000, + 0xAD8, 0x00000000, + 0xADC, 0x00000000, + 0xAE0, 0x00000000, + 0xAE4, 0x00000000, + 0xAE8, 0x00000000, + 0xAEC, 0x00000000, + 0xAF0, 0x00000000, + 0xAF4, 0x00000000, + 0xAF8, 0x00000000, + 0xB00, 0x00000000, + 0xB04, 0x00000000, + 0xB08, 0x00000000, + 0xB0C, 0x00000000, + 0xB10, 0x00000000, + 0xB14, 0x00000000, + 0xB18, 0x00000000, + 0xB1C, 0x00000000, + 0xB20, 0x00000000, + 0xB24, 0x00000000, + 0xB28, 0x00000000, + 0xB2C, 0x00000000, + 0xB30, 0x00000000, + 0xB34, 0x00000000, + 0xB38, 0x00000000, + 0xB3C, 0x00000000, + 0xB40, 0x00000000, + 0xB44, 0x00000000, + 0xB48, 0x00000000, + 0xB4C, 0x00000000, + 0xB50, 0x00000000, + 0xB54, 0x00000000, + 0xB58, 0x00060100, + 0xB5C, 0x00000000, + 0xB60, 0x00000000, + 0xB64, 0x00000000, + 0xB68, 0x00000000, + 0xB6C, 0x00000000, + 0xB70, 0x00000000, + 0xB74, 0x00000000, + 0xB78, 0x00000000, + 0xB7C, 0x00000000, + 0xB80, 0x00000000, + 0xB84, 0x00000000, + 0xB88, 0x00000000, + 0xB8C, 0x00000000, + 0xB90, 0x00000000, + 0xB94, 0x00000000, + 0xB98, 0x00000000, + 0xB9C, 0x00000000, + 0xBA0, 0x00000000, + 0xBA4, 0x00000000, + 0xBA8, 0x00000000, + 0xBAC, 0x00000000, + 0xBB0, 0x00000000, + 0xBB4, 0x00000000, + 0xBB8, 0x00000000, + 0xBBC, 0x00000000, + 0xBC0, 0x00000000, + 0xBC4, 0x00000000, + 0xBC8, 0x00000000, + 0xBCC, 0x00000000, + 0xBD0, 0x00000000, + 0xBD4, 0x00000000, + 0xBD8, 0x00000000, + 0xBDC, 0x00000000, + 0xBE0, 0x00000000, + 0xBE4, 0x00000000, + 0xBE8, 0x00000000, + 0xBEC, 0x00000000, + 0xBF0, 0x00000000, + 0xBF4, 0x00000000, + 0xBF8, 0x00000000, + 0xC00, 0x0C8BA0D6, + 0xC04, 0x00000001, + 0xC08, 0x00000000, + 0xC0C, 0x02F1D8B7, + 0xC10, 0x000000B0, + 0xC14, 0x0000D891, + 0xC18, 0x00087672, + 0xC1C, 0x15260000, + 0xC20, 0x00000000, + 0xC24, 0x406000FF, + 0xC28, 0x06400F76, + 0xC2C, 0xE30020E1, + 0xC30, 0x140C9494, + 0xC34, 0x00A04946, + 0xC38, 0x011D4820, + 0xC3C, 0x168DB61B, + 0xC40, 0x009C50F8, + 0xC44, 0x2013BAD1, + 0xC48, 0xFFFFF7CC, + 0xC4C, 0xA000FFFF, + 0xC50, 0x20D0F800, + 0xC54, 0x941A0200, + 0xC58, 0x18380111, + 0xC5C, 0x006E01B8, + 0xC60, 0x2CA5555B, + 0xC64, 0x0210005F, + 0xC68, 0x039A5300, + 0xC6C, 0x0265C2BA, + 0xC70, 0x000CEB21, + 0xC74, 0x0E149CA1, + 0xC78, 0x1AB4956B, + 0xC7C, 0x00000ABF, + 0xC80, 0xC02A8799, + 0xC84, 0x06C636C6, + 0xC88, 0x08090202, + 0xC8C, 0x00204048, + 0xC90, 0x00F85F85, + 0xC94, 0x00000F85, + 0xC98, 0x58385858, + 0xC9C, 0x18382838, + 0xCA0, 0x00002838, + 0xCA4, 0x3A253A3A, + 0xCA8, 0x10251A25, + 0xCAC, 0x00001025, + 0xCB0, 0x3A133A3A, + 0xCB4, 0x08130D13, + 0xCB8, 0x00000813, + 0xCBC, 0x001F1066, + 0xCC0, 0x88A00400, + 0xCC4, 0x00200400, + 0xCC8, 0x0B200400, + 0xCCC, 0x00600400, + 0xCD0, 0x22220092, + 0xCD4, 0x22220707, + 0xCD8, 0x22222222, + 0xCDC, 0x22222222, + 0xCE0, 0x22222222, + 0xCE4, 0x22222222, + 0xCE8, 0x00002222, + 0xCEC, 0x00000000, + 0xCF0, 0x00000000, + 0xCF4, 0x00000000, + 0xCF8, 0x00000000, + 0xD00, 0x1083A10A, + 0xD04, 0x0EC42948, + 0xD08, 0x10852108, + 0xD0C, 0x0CC41D08, + 0xD10, 0x108620EC, + 0xD14, 0x0CA42108, + 0xD18, 0x107620E8, + 0xD1C, 0x0E742108, + 0xD20, 0x0E8618C8, + 0xD24, 0x00000108, + 0xD28, 0x288C224C, + 0xD2C, 0x11C6320C, + 0xD30, 0x30CEBD98, + 0xD34, 0x10C31908, + 0xD38, 0x310A318C, + 0xD3C, 0x18C41D08, + 0xD40, 0x28CC4190, + 0xD44, 0x19062108, + 0xD48, 0x294A5A17, + 0xD4C, 0x00000108, + 0xD50, 0x10A3A908, + 0xD54, 0x10842148, + 0xD58, 0x14C5314A, + 0xD5C, 0x1086258C, + 0xD60, 0x10A42948, + 0xD64, 0x10842108, + 0xD68, 0x08C42108, + 0xD6C, 0x10842148, + 0xD70, 0x08822084, + 0xD74, 0x10841D04, + 0xD78, 0x08421088, + 0xD7C, 0x1083A104, + 0xD80, 0x10842108, + 0xD84, 0x1085294A, + 0xD88, 0x08822104, + 0xD8C, 0x10852948, + 0xD90, 0x08421084, + 0xD94, 0x10852104, + 0xD98, 0x08421084, + 0xD9C, 0x10863184, + 0xDA0, 0x1083B10A, + 0xDA4, 0x10842148, + 0xDA8, 0x1984718C, + 0xDAC, 0x108C33AF, + 0xDB0, 0x00000000, + 0xDB4, 0x00000000, + 0xDB8, 0x00000000, + 0xDBC, 0x00000000, + 0xDC0, 0x00000000, + 0xDC4, 0x00000000, + 0xDC8, 0x00000000, + 0xDCC, 0x00000000, + 0xDD0, 0x00000000, + 0xDD4, 0x00000000, + 0xDD8, 0x00000000, + 0xDDC, 0x00000000, + 0xDE0, 0x00000000, + 0xDE4, 0x00000000, + 0xDE8, 0x00000000, + 0xDEC, 0x00000000, + 0xDF0, 0x00000000, + 0xDF4, 0x00000000, + 0xDF8, 0x00000000, + 0x1800, 0x00033312, + 0x1804, 0x00033312, + 0x180C, 0x17F40060, + 0x1810, 0x62F508C4, + 0x1814, 0x506AA5B4, + 0x1818, 0x000014FF, + 0x181C, 0x00000000, + 0x1820, 0x02D508CC, + 0x1824, 0x506AA5B4, + 0x1828, 0x000004FD, + 0x182C, 0x00000000, + 0x1834, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x1838, 0x20100000, + 0xA0000000, 0x00000000, + 0x1838, 0x20000000, + 0xB0000000, 0x00000000, + 0x183C, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x1840, 0x00002300, + 0xA0000000, 0x00000000, + 0x1840, 0x00000000, + 0xB0000000, 0x00000000, + 0x1844, 0x00000000, + 0x1848, 0x00000000, + 0x184C, 0x00000000, + 0x1850, 0x00000000, + 0x1854, 0x00000000, + 0x1858, 0x00000000, + 0x185C, 0x00000000, + 0x1860, 0xF0040FF8, + 0x1864, 0x7F000000, + 0x1868, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF00, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x186C, 0x0000FF02, + 0xA0000000, 0x00000000, + 0x186C, 0x0000FF00, + 0xB0000000, 0x00000000, + 0x1870, 0x00000000, + 0x1874, 0x00000000, + 0x1878, 0x00000000, + 0x187C, 0x00000000, + 0x1880, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x02B00000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x1884, 0x03B00000, + 0xA0000000, 0x00000000, + 0x1884, 0x02B00000, + 0xB0000000, 0x00000000, + 0x1888, 0x00000000, + 0x188C, 0x00000000, + 0x1890, 0x00000000, + 0x1894, 0x00000000, + 0x1898, 0x00000000, + 0x18A0, 0x00510000, + 0x18A4, 0x183C1F7F, + 0x18A8, 0x0A02C99A, + 0x18AC, 0x00004200, + 0x18B0, 0x0809FB08, + 0x18B0, 0x0809FB09, + 0x18B4, 0x00000000, + 0x18B8, 0x00000000, + 0x18BC, 0x00C3FF80, + 0x18C0, 0x0002D100, + 0x18C4, 0x00000004, + 0x18C8, 0x001FFFE0, + 0x18CC, 0x0809FB08, + 0x18CC, 0x0809FB09, + 0x18D0, 0x00000000, + 0x18D4, 0x00000000, + 0x18D8, 0x00C3FF80, + 0x18DC, 0x0002D100, + 0x18E0, 0x00000004, + 0x18E4, 0x001FFFE0, + 0x18E8, 0x00800000, + 0x18EC, 0x1EC08000, + 0x18F0, 0x7F000064, + 0x18F4, 0x1F7DE75C, + 0x18F8, 0x7F7F7F7F, + 0x18FC, 0x7F7F7F7F, + 0x1900, 0xA7A7A7A7, + 0x1904, 0x95959595, + 0x1908, 0x00777788, + 0x190C, 0x77776666, + 0x1910, 0x00033333, + 0x1914, 0xAAAC875A, + 0x1918, 0x2AA2A8A2, + 0x191C, 0x2AAAA8A2, + 0x1920, 0x00878766, + 0x1924, 0x000C4924, + 0x1928, 0x5669B6C0, + 0x192C, 0x00409190, + 0x1930, 0xB85C0492, + 0x1934, 0x00B4A298, + 0x1938, 0x00030151, + 0x193C, 0x0058C618, + 0x1940, 0x41000000, + 0x1944, 0x00000BCB, + 0x1948, 0xAAAAAAAA, + 0x194C, 0x00B99999, + 0x1950, 0x88886665, + 0x1954, 0x08888888, + 0x1958, 0x00000618, + 0x195C, 0x00000000, + 0x1960, 0x00000000, + 0x1964, 0x00000000, + 0x1968, 0x00000000, + 0x196C, 0x00000000, + 0x1970, 0x00000000, + 0x1974, 0x00000000, + 0x1978, 0x00000000, + 0x197C, 0x00000000, + 0x1980, 0x00000000, + 0x1984, 0x00000000, + 0x1988, 0x00000000, + 0x198C, 0x00000000, + 0x1990, 0x00000000, + 0x1994, 0x00000000, + 0x1998, 0x00000000, + 0x199C, 0x00000000, + 0x19A0, 0x00000000, + 0x19A4, 0x00000000, + 0x19A8, 0x00000000, + 0x19AC, 0x00000000, + 0x19B0, 0x00000000, + 0x19B4, 0x00000000, + 0x19B8, 0x00000000, + 0x19BC, 0x00000000, + 0x19C0, 0x00000000, + 0x19C4, 0x00000000, + 0x19C8, 0x00000000, + 0x19CC, 0x00000000, + 0x19D0, 0x00000000, + 0x19D4, 0x00000000, + 0x19D8, 0x00000000, + 0x19DC, 0x00000000, + 0x19E0, 0x00000000, + 0x19E4, 0x00000000, + 0x19E8, 0x00000000, + 0x19EC, 0x00000000, + 0x19F0, 0x00000000, + 0x19F4, 0x00000000, + 0x19F8, 0x00000000, + 0x1C00, 0x00000000, + 0x1C04, 0x00000000, + 0x1C08, 0x00000000, + 0x1C0C, 0x00000000, + 0x1C10, 0x00000000, + 0x1C14, 0x00000000, + 0x1C18, 0x00000000, + 0x1C1C, 0x00000000, + 0x1C20, 0x03C23F00, + 0x1C24, 0xF101F002, + 0x1C28, 0x0FFE0010, + 0x1C2C, 0x453090FF, + 0x1C30, 0xFE0090FE, + 0x1C34, 0xE4E42000, + 0x1C38, 0xFFA1005E, + 0x1C40, 0x8F588837, + 0x1C44, 0x04400700, + 0x1C48, 0x00000000, + 0x1C4C, 0x00000200, + 0x1C50, 0x8E588837, + 0x1C54, 0x04400300, + 0x1C58, 0x00000000, + 0x1C5C, 0xFFFFFFFF, + 0x1C60, 0x0F030032, + 0x1C64, 0x360F0008, + 0x1C68, 0x007F0000, + 0x1C6C, 0x00010000, + 0x1C70, 0x00037FFE, + 0x1C74, 0x00000000, + 0x1C78, 0x00020000, + 0x1C7C, 0x00310000, + 0x1C80, 0x0E38E000, + 0x1C84, 0x245120D4, + 0x1C88, 0xC8400483, + 0x1C8C, 0x40005A20, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000000, + 0x1C98, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x1C94, 0x00000B0E, + 0x1C98, 0x00450000, + 0xA0000000, 0x00000000, + 0x1C94, 0x00000000, + 0x1C98, 0x00000000, + 0xB0000000, 0x00000000, + 0x1C9C, 0x00000000, + 0x1CA0, 0x00000000, + 0x1CA4, 0x20000000, + 0x1CA8, 0x0E000000, + 0x1CAC, 0xE424A2CC, + 0x1CB0, 0x00000000, + 0x1CB4, 0x00000000, + 0x1CB8, 0x24800000, + 0x1CBC, 0x60004800, + 0x1CC0, 0x24800000, + 0x1CC4, 0x60004800, + 0x1CC8, 0xF0444900, + 0x1CCC, 0x030300F1, + 0x1CD0, 0x0F000000, + 0x1CD4, 0x02024B00, + 0x1CD8, 0x04000000, + 0x1CDC, 0x10000000, + 0x1CE0, 0x60000000, + 0x1CE4, 0x00000000, + 0x1CE8, 0xC0000000, + 0x1CEC, 0x00000000, + 0x1CF0, 0x00000000, + 0x1CF4, 0xE4000000, + 0x1CF8, 0x00000000, + 0x1D00, 0x00000000, + 0x1D04, 0x08A3C000, + 0x1D08, 0xA0000000, + 0x1D10, 0x08B5BBBB, + 0x1D14, 0x77777777, + 0x1D18, 0x99999999, + 0x1D1C, 0x99999999, + 0x1D20, 0x000081E0, + 0x1D24, 0x00000000, + 0x1D28, 0x00000000, + 0x1D2C, 0xC0000000, + 0x1D30, 0x50009C00, + 0x1D34, 0x00000000, + 0x1D38, 0x00000000, + 0x1D3C, 0xF8000000, + 0x1D40, 0x00000000, + 0x1D44, 0x74740000, + 0x1D48, 0x14147474, + 0x1D4C, 0x00FFFF14, + 0x1D50, 0x00000000, + 0x1D54, 0x03A00000, + 0x1D58, 0x80800000, + 0x1D5C, 0x00000000, + 0x1D60, 0x00000000, + 0x1D64, 0x88000000, + 0x1D68, 0x00000000, + 0x1D6C, 0x666D8001, + 0x1D70, 0x20202020, + 0x1D74, 0x4E4E4E4E, + 0x1D78, 0x18189818, + 0x1D7C, 0x0005A000, + 0x1D80, 0x00080000, + 0x1D84, 0x00080000, + 0x1D88, 0x000000EF, + 0x1D8C, 0x0C0C0C0C, + 0x1D90, 0x103F003F, + 0x1D94, 0x00000000, + 0x1D98, 0x00000000, + 0x1D9C, 0x00000000, + 0x1DA0, 0x00000000, + 0x1DA4, 0x00000000, + 0x1DA8, 0x00000000, + 0x1DAC, 0x00000000, + 0x1DB0, 0x00000000, + 0x1DB4, 0x00000000, + 0x1DB8, 0x00000000, + 0x1DBC, 0x00000000, + 0x1DC0, 0x00000000, + 0x1DC4, 0x00000000, + 0x1DC8, 0x00000000, + 0x1DCC, 0x00000000, + 0x1DD0, 0x00000000, + 0x1DD4, 0x00000000, + 0x1DD8, 0x00000000, + 0x1DDC, 0x1FDF0000, + 0x1DE0, 0x01010000, + 0x1DE4, 0x05210123, + 0x1DE8, 0xFFFF4848, + 0x1DEC, 0x00000000, + 0x1DF0, 0x00000000, + 0x1DF4, 0x80000002, + 0x1DF8, 0x00000000, + 0x1E00, 0x00000000, + 0x1E04, 0x00000000, + 0x1E08, 0x00000000, + 0x1E0C, 0x00000000, + 0x1E10, 0x00000000, + 0x1E14, 0x00000000, + 0x1E18, 0x00000000, + 0x1E1C, 0x00000000, + 0x1E20, 0x00000000, + 0x1E24, 0x80003000, + 0x1E28, 0x000CC0C3, + 0x1E2C, 0xE4E40000, + 0x1E30, 0xE4E4E4E4, + 0x1E34, 0xF3001234, + 0x1E38, 0x00000000, + 0x1E3C, 0x00000000, + 0x1E40, 0x00000000, + 0x1E44, 0x00000000, + 0x1E48, 0x00000000, + 0x1E4C, 0x00000000, + 0x1E50, 0x00000000, + 0x1E54, 0x00000000, + 0x1E58, 0x00000000, + 0x1E5C, 0xC1000000, + 0x1E60, 0x00000000, + 0x1E64, 0xF3A00001, + 0x1E68, 0x0028846E, + 0x1E6C, 0x40274906, + 0x1E70, 0x00001000, + 0x1E74, 0x00000000, + 0x1E78, 0x00000000, + 0x1E7C, 0x00000000, + 0x1E80, 0x00000000, + 0x1E84, 0x00000000, + 0x1E84, 0x40000000, + 0x1E84, 0x41000000, + 0x1E84, 0x42000000, + 0x1E84, 0x43000000, + 0x1E84, 0x44000000, + 0x1E84, 0x45000000, + 0x1E84, 0x46000000, + 0x1E84, 0x47000000, + 0x1E84, 0x48000000, + 0x1E84, 0x49000000, + 0x1E84, 0x4A000000, + 0x1E84, 0x4B000000, + 0x1E84, 0x4C000000, + 0x1E84, 0x4D000000, + 0x1E84, 0x4E000000, + 0x1E84, 0x4F000000, + 0x1E84, 0x50000000, + 0x1E84, 0x51000000, + 0x1E84, 0x52000000, + 0x1E84, 0x53000000, + 0x1E84, 0x54000000, + 0x1E84, 0x55000000, + 0x1E84, 0x56000000, + 0x1E84, 0x57000000, + 0x1E84, 0x58000000, + 0x1E84, 0x59000000, + 0x1E84, 0x5A000000, + 0x1E84, 0x5B000000, + 0x1E84, 0x5C000000, + 0x1E84, 0x5D000000, + 0x1E84, 0x5E000000, + 0x1E84, 0x5F000000, + 0x1E84, 0x60000000, + 0x1E84, 0x61000000, + 0x1E84, 0x62000000, + 0x1E84, 0x63000000, + 0x1E84, 0x64000000, + 0x1E84, 0x65000000, + 0x1E84, 0x66000000, + 0x1E84, 0x67000000, + 0x1E84, 0x68000000, + 0x1E84, 0x69000000, + 0x1E84, 0x6A000000, + 0x1E84, 0x6B000000, + 0x1E84, 0x6C000000, + 0x1E84, 0x6D000000, + 0x1E84, 0x6E000000, + 0x1E84, 0x6F000000, + 0x1E84, 0x70000000, + 0x1E84, 0x71000000, + 0x1E84, 0x72000000, + 0x1E84, 0x73000000, + 0x1E84, 0x74000000, + 0x1E84, 0x75000000, + 0x1E84, 0x76000000, + 0x1E84, 0x77000000, + 0x1E84, 0x78000000, + 0x1E84, 0x79000000, + 0x1E84, 0x7A000000, + 0x1E84, 0x7B000000, + 0x1E84, 0x7C000000, + 0x1E84, 0x7D000000, + 0x1E84, 0x7E000000, + 0x1E84, 0x7F000000, + 0x1E84, 0x80000000, + 0x1E84, 0x00000000, + 0x1E88, 0x0200FC1C, + 0x1E8C, 0x00000000, + 0x1E90, 0x00000000, + 0x1E94, 0x04000000, + 0x1E98, 0x00000000, + 0x1E9C, 0x00000000, + 0x1EA0, 0x00000000, + 0x1EA4, 0x00000000, + 0x1EA8, 0xAA464646, + 0x1EAC, 0x01800030, + 0x1EB0, 0x00003002, + 0x1EB4, 0x31800002, + 0x1EB8, 0x00000000, + 0x1EBC, 0x00000000, + 0x1EC0, 0x00000000, + 0x1EC4, 0x00000000, + 0x1EC8, 0x00000000, + 0x1ECC, 0x00000000, + 0x1ED0, 0x00000000, + 0x1ED4, 0x8000000A, + 0x1ED8, 0x800B03E8, + 0x1EDC, 0x83E90FFF, + 0x1EE0, 0x8000FFFF, + 0x1EE4, 0x70000000, + 0x1EE8, 0x00000000, + 0x1EEC, 0x0280A933, + 0x1EF0, 0x00000A80, + 0x1EF4, 0x00001266, + 0x1EF8, 0x01000100, + 0x3A00, 0x0004080C, + 0x3A04, 0x1C202428, + 0x3A08, 0x0C101418, + 0x3A0C, 0x181C2024, + 0x3A10, 0x080C1014, + 0x3A14, 0x181C2024, + 0x3A18, 0x080C1014, + 0x3A1C, 0x00000000, + 0x3A20, 0x00000000, + 0x3A24, 0x00000000, + 0x3A28, 0x00000000, + 0x3A2C, 0x181C2024, + 0x3A30, 0x080C1014, + 0x3A34, 0x20240004, + 0x3A38, 0x1014181C, + 0x3A3C, 0x0004080C, + 0x3A40, 0x00000000, + 0x3A44, 0x00000000, + 0x3A48, 0x00000000, + 0x3A4C, 0x00000000, + 0x3A50, 0x00000000, + 0x3A54, 0x00000000, + 0x3A58, 0x00000000, + 0x3A5C, 0x00000000, + 0x3A60, 0x00000000, + 0x3A64, 0x00000000, + 0x3A68, 0x00000000, + 0x3A6C, 0x00000000, + 0x3A70, 0x00000000, + 0x3A74, 0x00000000, + 0x3A78, 0x00000000, + 0x3A7C, 0x00000000, + 0x3A80, 0x00000000, + 0x3A84, 0x00000000, + 0x3A88, 0x00000000, + 0x3A8C, 0x00000000, + 0x3A90, 0x00000000, + 0x3A94, 0x00000000, + 0x3A98, 0x00000000, + 0x3A9C, 0x00000000, + 0x3AA0, 0x00000000, + 0x3AA4, 0x00000000, + 0x4000, 0xA6A6A6A6, + 0x4004, 0x95959595, + 0x4008, 0x00777777, + 0x400C, 0x77776666, + 0x4010, 0x00033333, + 0x4014, 0xAAAC875A, + 0x4018, 0x2AA2A8A2, + 0x401C, 0x2AAAA8A2, + 0x4020, 0x00878766, + 0x4024, 0x000C4924, + 0x4028, 0x5669B6C0, + 0x402C, 0x00409190, + 0x4030, 0xB85C0492, + 0x4034, 0x00B4A298, + 0x4038, 0x00030151, + 0x403C, 0x0058C618, + 0x4040, 0x41000000, + 0x4044, 0x00000BCB, + 0x4048, 0xAAAAAAAA, + 0x404C, 0x00B98989, + 0x4050, 0x88886665, + 0x4054, 0x08888888, + 0x4058, 0x00000618, + 0x405C, 0x00000000, + 0x4060, 0x00000000, + 0x4064, 0x00000000, + 0x4068, 0x00000000, + 0x406C, 0x00000000, + 0x4070, 0x00000000, + 0x4074, 0x00000000, + 0x4078, 0x00000000, + 0x407C, 0x00000000, + 0x4080, 0x00000000, + 0x4084, 0x00000000, + 0x4088, 0x00000000, + 0x408C, 0x00000000, + 0x4090, 0x00000000, + 0x4094, 0x00000000, + 0x4098, 0x00000000, + 0x409C, 0x00000000, + 0x40A0, 0x00000000, + 0x40A4, 0x00000000, + 0x40A8, 0x00000000, + 0x40AC, 0x00000000, + 0x40B0, 0x00000000, + 0x40B4, 0x00000000, + 0x40B8, 0x00000000, + 0x40BC, 0x00000000, + 0x40C0, 0x00000000, + 0x40C4, 0x00000000, + 0x40C8, 0x00000000, + 0x40CC, 0x00000000, + 0x40D0, 0x00000000, + 0x40D4, 0x00000000, + 0x40D8, 0x00000000, + 0x40DC, 0x00000000, + 0x40E0, 0x00000000, + 0x40E4, 0x00000000, + 0x40E8, 0x00000000, + 0x40EC, 0x00000000, + 0x40F0, 0x00000000, + 0x40F4, 0x00000000, + 0x40F8, 0x00000000, + 0x4100, 0x00033312, + 0x4104, 0x00033312, + 0x410C, 0x17F40060, + 0x4110, 0x62D508C4, + 0x4114, 0x506AA5B4, + 0x4118, 0x000014FF, + 0x411C, 0x00000000, + 0x4120, 0x02D508CC, + 0x4124, 0x506AA5B4, + 0x4128, 0x000004FD, + 0x412C, 0x00000000, + 0x4134, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x4138, 0x20100000, + 0xA0000000, 0x00000000, + 0x4138, 0x20000000, + 0xB0000000, 0x00000000, + 0x413C, 0x00000000, + 0x4140, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x4144, 0x00002030, + 0xA0000000, 0x00000000, + 0x4144, 0x00000000, + 0xB0000000, 0x00000000, + 0x4148, 0x00000000, + 0x414C, 0x00000000, + 0x4150, 0x00000000, + 0x4154, 0x00000000, + 0x4158, 0x00000000, + 0x415C, 0x00000000, + 0x4160, 0xF0040FF8, + 0x4164, 0x7F000000, + 0x4168, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x416C, 0x00008002, + 0xA0000000, 0x00000000, + 0x416C, 0x00008000, + 0xB0000000, 0x00000000, + 0x4170, 0x00000000, + 0x4174, 0x00000000, + 0x4178, 0x00000000, + 0x417C, 0x00000000, + 0x4180, 0x00000000, + 0x83000000, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x02B00000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x4184, 0x03B00000, + 0xA0000000, 0x00000000, + 0x4184, 0x02B00000, + 0xB0000000, 0x00000000, + 0x4188, 0x00000000, + 0x418C, 0x00000000, + 0x4190, 0x00000000, + 0x4194, 0x00000000, + 0x4198, 0x00000000, + 0x41A0, 0x00510000, + 0x41A4, 0x183C1F7F, + 0x41A8, 0x1402C99A, + 0x41AC, 0x00004200, + 0x41B0, 0x0809FB08, + 0x41B0, 0x0809FB09, + 0x41B4, 0x00000000, + 0x41B8, 0x00000000, + 0x41BC, 0x00C3FF80, + 0x41C0, 0x0002D100, + 0x41C4, 0x00000004, + 0x41C8, 0x001FFFE0, + 0x41CC, 0x0809FB08, + 0x41CC, 0x0809FB09, + 0x41D0, 0x00000000, + 0x41D4, 0x00000000, + 0x41D8, 0x00C3FF80, + 0x41DC, 0x0002D100, + 0x41E0, 0x00000004, + 0x41E4, 0x001FFFE0, + 0x41E8, 0x00000200, + 0x41EC, 0x1E008000, + 0x41F0, 0x7F000064, + 0x41F4, 0x1F7DE75C, + 0x41F8, 0x7F7F7F7F, + 0x41FC, 0x7F7F7F7F, + 0x1830, 0x700B8001, + 0x1830, 0x700B8001, + 0x1830, 0x70144001, + 0x1830, 0x70244001, + 0x1830, 0x70344001, + 0x1830, 0x70444001, + 0x1830, 0x705B8001, + 0x1830, 0x70644001, + 0x1830, 0x707B8001, + 0x1830, 0x708B8001, + 0x1830, 0x709B8001, + 0x1830, 0x70AB8001, + 0x1830, 0x70BB8001, + 0x1830, 0x70CB8001, + 0x1830, 0x70DB8001, + 0x1830, 0x70EB8001, + 0x1830, 0x70FB8001, + 0x1830, 0x70FB8001, + 0x4130, 0x700B8001, + 0x4130, 0x700B8001, + 0x4130, 0x70144001, + 0x4130, 0x70244001, + 0x4130, 0x70344001, + 0x4130, 0x70444001, + 0x4130, 0x705B8001, + 0x4130, 0x70644001, + 0x4130, 0x707B8001, + 0x4130, 0x708B8001, + 0x4130, 0x709B8001, + 0x4130, 0x70AB8001, + 0x4130, 0x70BB8001, + 0x4130, 0x70CB8001, + 0x4130, 0x70DB8001, + 0x4130, 0x70EB8001, + 0x4130, 0x70FB8001, + 0x4130, 0x70FB8001, + 0x1A00, 0x00D047C8, + 0x1A04, 0xC0000008, + 0x1A08, 0x88838300, + 0x1A0C, 0x2E20100F, + 0x1A10, 0x9500BB78, + 0x1A14, 0x111440A8, + 0x1A18, 0x00881117, + 0x1A1C, 0x89140F00, + 0x1A20, 0x52840000, + 0x1A24, 0x3E18FEC8, + 0x1A28, 0x00150A88, + 0x1A2C, 0x12988000, + 0x1A30, 0x10114007, + 0x1A34, 0x1011C007, + 0x1A38, 0x00000000, + 0x1A3C, 0x00000000, + 0x1A40, 0x00000000, + 0x1A44, 0x00000000, + 0x1A48, 0x000C0000, + 0x1A4C, 0xB00000C0, + 0x1A50, 0x22040700, + 0x1A54, 0x09003000, + 0x1A58, 0x00000881, + 0x1A5C, 0x00000128, + 0x1A60, 0x85830000, + 0x1A64, 0x00000128, + 0x1A68, 0x00222211, + 0x1A6C, 0x00000000, + 0x1A70, 0x00008000, + 0x1A74, 0x00000048, + 0x1A78, 0x000089F0, + 0x1A7C, 0x225B0606, + 0x1A80, 0x208A7532, + 0x1A84, 0x85200200, + 0x1A88, 0x048C0000, + 0x1A8C, 0x00000000, + 0x1A90, 0x00000000, + 0x1A94, 0x00000000, + 0x1A98, 0xACC4C040, + 0x1A9C, 0x0016C8B2, + 0x1AA0, 0x00FAF0DE, + 0x1AA4, 0x00020000, + 0x1AA8, 0xBA0F0004, + 0x1AAC, 0x00122344, + 0x1AB0, 0x0FFFFFFF, + 0x1AB4, 0x0F201402, + 0x1AB8, 0x00000000, + 0x1ABC, 0xC2008080, + 0x1AC0, 0x54D0A742, + 0x1AC4, 0x00000000, + 0x1AC8, 0x00000807, + 0x1ACC, 0x00000707, + 0x1AD0, 0xA33529CE, + 0x1AD4, 0x0D8D8452, + 0x1AD8, 0x08024024, + 0x1ADC, 0x000D0001, + 0x1AE0, 0x00600391, + 0x1AE4, 0x08000080, + 0x1AE8, 0xC2100002, + 0x1AEC, 0x000000F6, + 0x1AF0, 0x00000000, + 0x1AF4, 0x00000000, + 0x1AF8, 0x00000000, + 0x1AFC, 0x00000000, + 0x1D0C, 0x00400000, + 0x1D0C, 0x00410000, + 0x1EE8, 0x00000003, + 0xC0C, 0x02F1D8BF, + 0x1D94, 0x40000000, + 0x1D94, 0x40010000, + 0x1D94, 0x40020000, + 0x1D94, 0x40030000, + 0x1D94, 0x40040000, + 0x1D94, 0x40050000, + 0x1D94, 0x40060000, + 0x1D94, 0x40070000, + 0x1D94, 0x40080000, + 0x1D94, 0x40090000, + 0x1D94, 0x400A0000, + 0x1D94, 0x400B0000, + 0x1D94, 0x400C0000, + 0x1D94, 0x400D0000, + 0x1D94, 0x400E0000, + 0x1D94, 0x400F0000, + 0x1D94, 0x40100000, + 0x1D94, 0x40110000, + 0x1D94, 0x40120000, + 0x1D94, 0x40130000, + 0x1D94, 0x40140000, + 0x1D94, 0x40150000, + 0x1D94, 0x40160000, + 0x1D94, 0x40170000, + 0x1D94, 0x40180000, + 0x1D94, 0x40190000, + 0x1D94, 0x401A0000, + 0x1D94, 0x401B0000, + 0x1D94, 0x401C0000, + 0x1D94, 0x401D0000, + 0x1D94, 0x401E0000, + 0x1D94, 0x401F0000, + 0x1D94, 0x40200000, + 0x1D94, 0x40210000, + 0x1D94, 0x40220000, + 0x1D94, 0x40230000, + 0x1D94, 0x40240000, + 0x1D94, 0x40250000, + 0x1D94, 0x40260000, + 0x1D94, 0x40270000, + 0x1D94, 0x40280000, + 0x1D94, 0x40290000, + 0x1D94, 0x402A0000, + 0x1D94, 0x402B0000, + 0x1D94, 0x402C0000, + 0x1D94, 0x402D0000, + 0x1D94, 0x402E0000, + 0x1D94, 0x402F0000, + 0x1D94, 0x40300000, + 0x1D94, 0x40310000, + 0x1D94, 0x40320000, + 0x1D94, 0x40330000, + 0x1D94, 0x40340000, + 0x1D94, 0x40350000, + 0x1D94, 0x40360000, + 0x1D94, 0x40370000, + 0x1D94, 0x40380000, + 0x1D94, 0x40390000, + 0x1D94, 0x403A0000, + 0x1D94, 0x403B0000, + 0x1D94, 0x403C0000, + 0x1D94, 0x403D0000, + 0x1D94, 0x403E0000, + 0x1D94, 0x403F0000, + 0x1D94, 0x40400000, + 0x1D94, 0x40410000, + 0x1D94, 0x40420000, + 0x1D94, 0x40430000, + 0x1D94, 0x40440000, + 0x1D94, 0x40450000, + 0x1D94, 0x40460000, + 0x1D94, 0x40470000, + 0x1D94, 0x40480000, + 0x1D94, 0x40490000, + 0x1D94, 0x404A0000, + 0x1D94, 0x404B0000, + 0x1D94, 0x404C0000, + 0x1D94, 0x404D0000, + 0x1D94, 0x404E0000, + 0x1D94, 0x404F0000, + 0x1D94, 0x40500000, + 0x1D94, 0x40510000, + 0x1D94, 0x40520000, + 0x1D94, 0x40530000, + 0x1D94, 0x40540000, + 0x1D94, 0x40550000, + 0x1D94, 0x40560000, + 0x1D94, 0x40570000, + 0x1D94, 0x40580000, + 0x1D94, 0x40590000, + 0x1D94, 0x405A0000, + 0x1D94, 0x405B0000, + 0x1D94, 0x405C0000, + 0x1D94, 0x405D0000, + 0x1D94, 0x405E0000, + 0x1D94, 0x405F0000, + 0x1D94, 0x40600000, + 0x1D94, 0x40610000, + 0x1D94, 0x40620000, + 0x1D94, 0x40630000, + 0x1D94, 0x40640000, + 0x1D94, 0x40650000, + 0x1D94, 0x40660000, + 0x1D94, 0x40670000, + 0x1D94, 0x40680000, + 0x1D94, 0x40690000, + 0x1D94, 0x406A0000, + 0x1D94, 0x406B0000, + 0x1D94, 0x406C0000, + 0x1D94, 0x406D0000, + 0x1D94, 0x406E0000, + 0x1D94, 0x406F0000, + 0x1D94, 0x40700000, + 0x1D94, 0x40710000, + 0x1D94, 0x40720000, + 0x1D94, 0x40730000, + 0x1D94, 0x40740000, + 0x1D94, 0x40750000, + 0x1D94, 0x40760000, + 0x1D94, 0x40770000, + 0x1D94, 0x40780000, + 0x1D94, 0x40790000, + 0x1D94, 0x407A0000, + 0x1D94, 0x407B0000, + 0x1D94, 0x407C0000, + 0x1D94, 0x407D0000, + 0x1D94, 0x407E0000, + 0x1D94, 0x407F0000, + 0x1D94, 0x40800000, + 0x1D94, 0x40810000, + 0x1D94, 0x40820000, + 0x1D94, 0x40830000, + 0x1D94, 0x40840000, + 0x1D94, 0x40850000, + 0x1D94, 0x40860000, + 0x1D94, 0x40870000, + 0x1D94, 0x40880000, + 0x1D94, 0x40890000, + 0x1D94, 0x408A0000, + 0x1D94, 0x408B0000, + 0x1D94, 0x408C0000, + 0x1D94, 0x408D0000, + 0x1D94, 0x408E0000, + 0x1D94, 0x408F0000, + 0x1D94, 0x40900000, + 0x1D94, 0x40910000, + 0x1D94, 0x40920000, + 0x1D94, 0x40930000, + 0x1D94, 0x40940000, + 0x1D94, 0x40950000, + 0x1D94, 0x40960000, + 0x1D94, 0x40970000, + 0x1D94, 0x40980000, + 0x1D94, 0x40990000, + 0x1D94, 0x409A0000, + 0x1D94, 0x409B0000, + 0x1D94, 0x409C0000, + 0x1D94, 0x409D0000, + 0x1D94, 0x409E0000, + 0x1D94, 0x409F0000, + 0x1D94, 0x40A00000, + 0x1D94, 0x40A10000, + 0x1D94, 0x40A20000, + 0x1D94, 0x40A30000, + 0x1D94, 0x40A40000, + 0x1D94, 0x40A50000, + 0x1D94, 0x40A60000, + 0x1D94, 0x40A70000, + 0x1D94, 0x40A80000, + 0x1D94, 0x40A90000, + 0x1D94, 0x40AA0000, + 0x1D94, 0x40AB0000, + 0x1D94, 0x40AC0000, + 0x1D94, 0x40AD0000, + 0x1D94, 0x40AE0000, + 0x1D94, 0x40AF0000, + 0x1D94, 0x40B00000, + 0x1D94, 0x40B10000, + 0x1D94, 0x40B20000, + 0x1D94, 0x40B30000, + 0x1D94, 0x40B40000, + 0x1D94, 0x40B50000, + 0x1D94, 0x40B60000, + 0x1D94, 0x40B70000, + 0x1D94, 0x40B80000, + 0x1D94, 0x40B90000, + 0x1D94, 0x40BA0000, + 0x1D94, 0x40BB0000, + 0x1D94, 0x40BC0000, + 0x1D94, 0x40BD0000, + 0x1D94, 0x40BE0000, + 0x1D94, 0x40BF0000, + 0x1D94, 0x40C00000, + 0x1D94, 0x40C10000, + 0x1D94, 0x40C20000, + 0x1D94, 0x40C30000, + 0x1D94, 0x40C40000, + 0x1D94, 0x40C50000, + 0x1D94, 0x40C60000, + 0x1D94, 0x40C70000, + 0x1D94, 0x40C80000, + 0x1D94, 0x40C90000, + 0x1D94, 0x40CA0000, + 0x1D94, 0x40CB0000, + 0x1D94, 0x40CC0000, + 0x1D94, 0x40CD0000, + 0x1D94, 0x40CE0000, + 0x1D94, 0x40CF0000, + 0x1D94, 0x40D00000, + 0x1D94, 0x40D10000, + 0x1D94, 0x40D20000, + 0x1D94, 0x40D30000, + 0x1D94, 0x40D40000, + 0x1D94, 0x40D50000, + 0x1D94, 0x40D60000, + 0x1D94, 0x40D70000, + 0x1D94, 0x40D80000, + 0x1D94, 0x40D90000, + 0x1D94, 0x40DA0000, + 0x1D94, 0x40DB0000, + 0x1D94, 0x40DC0000, + 0x1D94, 0x40DD0000, + 0x1D94, 0x40DE0000, + 0x1D94, 0x40DF0000, + 0x1D94, 0x40E00000, + 0x1D94, 0x40E10000, + 0x1D94, 0x40E20000, + 0x1D94, 0x40E30000, + 0x1D94, 0x40E40000, + 0x1D94, 0x40E50000, + 0x1D94, 0x40E60000, + 0x1D94, 0x40E70000, + 0x1D94, 0x40E80000, + 0x1D94, 0x40E90000, + 0x1D94, 0x40EA0000, + 0x1D94, 0x40EB0000, + 0x1D94, 0x40EC0000, + 0x1D94, 0x40ED0000, + 0x1D94, 0x40EE0000, + 0x1D94, 0x40EF0000, + 0x1D94, 0x40F00000, + 0x1D94, 0x40F10000, + 0x1D94, 0x40F20000, + 0x1D94, 0x40F30000, + 0x1D94, 0x40F40000, + 0x1D94, 0x40F50000, + 0x1D94, 0x40F60000, + 0x1D94, 0x40F70000, + 0x1D94, 0x40F80000, + 0x1D94, 0x40F90000, + 0x1D94, 0x40FA0000, + 0x1D94, 0x40FB0000, + 0x1D94, 0x40FC0000, + 0x1D94, 0x40FD0000, + 0x1D94, 0x40FE0000, + 0x1D94, 0x40FF0000, + 0xC0C, 0x02F1D8B7, + 0x1EE8, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822c_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8822c_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x484c5054, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x54585858, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x50545858, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x50545858, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x50545858, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x5858383c, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x484c5054, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x54585858, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x50545858, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x50545858, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x50545858, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x5858383c, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x54585858, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x50545858, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x50545858, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x50545858, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x5858383c, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x54585858, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x50545858, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x50545858, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x50545858, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x5858383c, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8822c_bb_pg_type0); + +static const u32 rtw8822c_rf_a[] = { + 0x000, 0x00030000, + 0x018, 0x00013124, + 0x093, 0x0008483F, + 0x0DE, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000B9140, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000B9140, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0xA0000000, 0x00000000, + 0x08E, 0x000A5540, + 0xB0000000, 0x00000000, + 0x081, 0x0000FC01, + 0x081, 0x0002FC01, + 0x081, 0x0003FC01, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x0006A06C, + 0xA0000000, 0x00000000, + 0x085, 0x0006A06C, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000013, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000023, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000033, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000043, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000053, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x08A, 0x000E7DE3, + 0x08B, 0x0008FE00, + 0x0EE, 0x00000008, + 0x033, 0x00000000, + 0x03F, 0x00000023, + 0x033, 0x00000001, + 0x03F, 0x00000023, + 0x0EE, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x0EF, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0FE, 0x00000000, + 0x01B, 0x00003A40, + 0x061, 0x0000D233, + 0x062, 0x0004D232, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000C02, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000C02, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0xA0000000, 0x00000000, + 0x063, 0x00000C02, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0xA0000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000080, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0xA0000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000770, + 0x030, 0x00001770, + 0x030, 0x00002440, + 0x030, 0x00003440, + 0x030, 0x00004330, + 0x030, 0x00005330, + 0x030, 0x00008770, + 0x030, 0x0000A440, + 0x030, 0x0000C330, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0xA0000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0xA0000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x051, 0x0003C800, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000942CA, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000942CA, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0xA0000000, 0x00000000, + 0x052, 0x000942CA, + 0xB0000000, 0x00000000, + 0x053, 0x000090F9, + 0x054, 0x00088000, + 0x057, 0x0004C80A, + 0x0EF, 0x00000020, + 0x033, 0x00000000, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000001, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000002, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000003, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000004, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000005, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000006, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000008, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000009, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000A, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000B, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000C, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000D, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00028246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000E, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00010E46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030246, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000010, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000011, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000012, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000013, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000014, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000015, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000016, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000018, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000019, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001A, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001B, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001C, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001D, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00031E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001E, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001F, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000020, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000021, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000022, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000023, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000024, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000025, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000026, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000027, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000028, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00025E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x00000029, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0003D646, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x033, 0x0000002A, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00002A46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000EA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00021E46, + 0xA0000000, 0x00000000, + 0x03F, 0x00002A46, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x000008C8, + 0x033, 0x00000064, + 0x03F, 0x000008CB, + 0x033, 0x00000065, + 0x03F, 0x000008CE, + 0x033, 0x00000066, + 0x03F, 0x000008D1, + 0x033, 0x00000067, + 0x03F, 0x000008D4, + 0x033, 0x00000068, + 0x03F, 0x00000DD1, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0xB0000000, 0x00000000, + 0x0EE, 0x00000000, + 0x05C, 0x000FC000, + 0x067, 0x0000A505, + 0x0D3, 0x00000542, + 0x043, 0x00005000, + 0x07F, 0x00000000, + 0x0B0, 0x0001F0FC, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x00022400, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0xA0000000, 0x00000000, + 0x0B3, 0x0007C760, + 0xB0000000, 0x00000000, + 0x0B4, 0x00099D40, + 0x0B5, 0x0004103F, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000187F8, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B6, 0x000387F8, + 0xA0000000, 0x00000000, + 0x0B6, 0x000187F8, + 0xB0000000, 0x00000000, + 0x0B7, 0x00030018, + 0x0BC, 0x00000008, + 0x0D3, 0x00000542, + 0x0DD, 0x00000500, + 0x0BB, 0x00040010, + 0x0B0, 0x0001F0FA, + 0x0FE, 0x00000000, + 0x0CA, 0x00080000, + 0x0CA, 0x00080001, + 0x0FE, 0x00000000, + 0x0B0, 0x0001F0F8, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C700, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0xA0000000, 0x00000000, + 0x0B3, 0x0007C700, + 0xB0000000, 0x00000000, + 0x018, 0x0001B124, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C760, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, + 0xA0000000, 0x00000000, + 0x0B3, 0x0007C760, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0CC, 0x0000F000, + 0x0CD, 0x00089600, + 0x018, 0x00013108, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0B8, 0x000C0440, + 0x0BA, 0x000E840D, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x018, 0x00013124, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x059, 0x000A0000, + 0x05A, 0x00060000, + 0x05B, 0x00014000, + 0x0ED, 0x00000008, + 0x033, 0x00000001, + 0x03F, 0x0000000F, + 0x0ED, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000500, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000540, + 0xA0000000, 0x00000000, + 0x0DD, 0x00000500, + 0xB0000000, 0x00000000, + 0x0BC, 0x00000004, + 0x0EE, 0x00000002, + 0x033, 0x00000017, + 0x03F, 0x0000003F, + 0x033, 0x00000018, + 0x03F, 0x0000003F, + 0x033, 0x00000019, + 0x03F, 0x00000000, + 0x033, 0x0000001A, + 0x03F, 0x0000003F, + 0x033, 0x0000001B, + 0x03F, 0x0000003F, + 0x033, 0x0000001C, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x0ED, 0x00000200, + 0x033, 0x00000000, + 0x03F, 0x000F45A4, + 0x033, 0x00000001, + 0x03F, 0x000F49A4, + 0x033, 0x00000002, + 0x03F, 0x000F49A4, + 0x033, 0x00000003, + 0x03F, 0x000F69A4, + 0x033, 0x00000004, + 0x03F, 0x000F69A4, + 0x033, 0x00000005, + 0x03F, 0x000F69A4, + 0x033, 0x00000006, + 0x03F, 0x000F6DA4, + 0x033, 0x00000007, + 0x03F, 0x000F6DA4, + 0x033, 0x00000008, + 0x03F, 0x000F6DA4, + 0x033, 0x00000009, + 0x03F, 0x000F8DA4, + 0x033, 0x0000000A, + 0x03F, 0x000F8DA4, + 0x033, 0x0000000B, + 0x03F, 0x000F8DA4, + 0x033, 0x0000000C, + 0x03F, 0x000F91A4, + 0x033, 0x0000000D, + 0x03F, 0x000F91A4, + 0x033, 0x0000000E, + 0x03F, 0x000F91A4, + 0x033, 0x0000000F, + 0x03F, 0x000FB1A4, + 0x033, 0x00000010, + 0x03F, 0x000FB1A4, + 0x033, 0x00000011, + 0x03F, 0x000FB1A4, + 0x033, 0x00000012, + 0x03F, 0x000FB5A4, + 0x033, 0x00000013, + 0x03F, 0x000FB5A4, + 0x033, 0x00000014, + 0x03F, 0x000FD9A4, + 0x033, 0x00000015, + 0x03F, 0x000FD9A4, + 0x033, 0x00000016, + 0x03F, 0x000FF9A4, + 0x033, 0x00000017, + 0x03F, 0x000FF9A4, + 0x033, 0x00000018, + 0x03F, 0x000FFDA4, + 0x033, 0x00000019, + 0x03F, 0x000FFDA4, + 0x033, 0x0000001A, + 0x03F, 0x000FFDA4, + 0x0ED, 0x00000000, + 0x092, 0x00084800, + 0x092, 0x00084801, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x092, 0x00084800, + 0x08F, 0x00001B4C, + 0x088, 0x0004326B, + 0x019, 0x00000005, + 0x0EF, 0x00080000, + 0x033, 0x00000004, + 0x03E, 0x00000003, + 0x03F, 0x000F60FF, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000006, + 0x03E, 0x00000003, + 0x03F, 0x000760FF, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000007, + 0x03E, 0x00000003, + 0x03F, 0x0007DEFF, + 0x0EF, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8822c_rf_a, A); + +static const u32 rtw8822c_rf_b[] = { + 0x000, 0x00030000, + 0x018, 0x00013124, + 0x093, 0x0008483F, + 0x0EF, 0x00080000, + 0x033, 0x00000001, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00091230, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0009123E, + 0xA0000000, 0x00000000, + 0x03F, 0x00091230, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DE, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000B9140, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000B9140, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x08E, 0x000A5540, + 0xA0000000, 0x00000000, + 0x08E, 0x000A5540, + 0xB0000000, 0x00000000, + 0x081, 0x0000FC01, + 0x081, 0x0002FC01, + 0x081, 0x0003FC01, + 0x085, 0x0006A06C, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000001, + 0x03F, 0x0000002A, + 0x033, 0x00000002, + 0x03F, 0x0000002A, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000010, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000001, + 0x03F, 0x0000003F, + 0x033, 0x00000002, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773C0, + 0x033, 0x0000000E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000000D, + 0x03F, 0x000773E8, + 0x033, 0x0000000C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000000B, + 0x03F, 0x00000287, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000207, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x0EF, 0x00010000, + 0x033, 0x0000000F, + 0x03F, 0x000773E8, + 0x033, 0x0000000E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000000D, + 0x03F, 0x00000380, + 0x033, 0x0000000C, + 0x03F, 0x000FF380, + 0x033, 0x0000000B, + 0x03F, 0x00000300, + 0x033, 0x0000000A, + 0x03F, 0x000002A8, + 0x033, 0x00000009, + 0x03F, 0x00000280, + 0x033, 0x00000008, + 0x03F, 0x000FF280, + 0x033, 0x00000007, + 0x03F, 0x00000200, + 0x033, 0x00000006, + 0x03F, 0x000001C0, + 0x033, 0x00000005, + 0x03F, 0x00000180, + 0x033, 0x00000004, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773C0, + 0x033, 0x0000001E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000001D, + 0x03F, 0x000773E8, + 0x033, 0x0000001C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000001B, + 0x03F, 0x00000287, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000207, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000001F, + 0x03F, 0x000773E8, + 0x033, 0x0000001E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000001D, + 0x03F, 0x00000380, + 0x033, 0x0000001C, + 0x03F, 0x000FF380, + 0x033, 0x0000001B, + 0x03F, 0x00000300, + 0x033, 0x0000001A, + 0x03F, 0x000002A8, + 0x033, 0x00000019, + 0x03F, 0x00000280, + 0x033, 0x00000018, + 0x03F, 0x000FF280, + 0x033, 0x00000017, + 0x03F, 0x00000200, + 0x033, 0x00000016, + 0x03F, 0x000001C0, + 0x033, 0x00000015, + 0x03F, 0x00000180, + 0x033, 0x00000014, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000013, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773C0, + 0x033, 0x0000002E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000002D, + 0x03F, 0x000773E8, + 0x033, 0x0000002C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000002B, + 0x03F, 0x00000287, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000207, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000002F, + 0x03F, 0x000773E8, + 0x033, 0x0000002E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000002D, + 0x03F, 0x00000380, + 0x033, 0x0000002C, + 0x03F, 0x000FF380, + 0x033, 0x0000002B, + 0x03F, 0x00000300, + 0x033, 0x0000002A, + 0x03F, 0x000002A8, + 0x033, 0x00000029, + 0x03F, 0x00000280, + 0x033, 0x00000028, + 0x03F, 0x000FF280, + 0x033, 0x00000027, + 0x03F, 0x00000200, + 0x033, 0x00000026, + 0x03F, 0x000001C0, + 0x033, 0x00000025, + 0x03F, 0x00000180, + 0x033, 0x00000024, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000023, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773C0, + 0x033, 0x0000003E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000003D, + 0x03F, 0x000773E8, + 0x033, 0x0000003C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000003B, + 0x03F, 0x00000287, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000207, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000003F, + 0x03F, 0x000773E8, + 0x033, 0x0000003E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000003D, + 0x03F, 0x00000380, + 0x033, 0x0000003C, + 0x03F, 0x000FF380, + 0x033, 0x0000003B, + 0x03F, 0x00000300, + 0x033, 0x0000003A, + 0x03F, 0x000002A8, + 0x033, 0x00000039, + 0x03F, 0x00000280, + 0x033, 0x00000038, + 0x03F, 0x000FF280, + 0x033, 0x00000037, + 0x03F, 0x00000200, + 0x033, 0x00000036, + 0x03F, 0x000001C0, + 0x033, 0x00000035, + 0x03F, 0x00000180, + 0x033, 0x00000034, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000033, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773C0, + 0x033, 0x0000004E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000004D, + 0x03F, 0x000773E8, + 0x033, 0x0000004C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000004B, + 0x03F, 0x00000287, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000207, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000004F, + 0x03F, 0x000773E8, + 0x033, 0x0000004E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000004D, + 0x03F, 0x00000380, + 0x033, 0x0000004C, + 0x03F, 0x000FF380, + 0x033, 0x0000004B, + 0x03F, 0x00000300, + 0x033, 0x0000004A, + 0x03F, 0x000002A8, + 0x033, 0x00000049, + 0x03F, 0x00000280, + 0x033, 0x00000048, + 0x03F, 0x000FF280, + 0x033, 0x00000047, + 0x03F, 0x00000200, + 0x033, 0x00000046, + 0x03F, 0x000001C0, + 0x033, 0x00000045, + 0x03F, 0x00000180, + 0x033, 0x00000044, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000043, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773C0, + 0x033, 0x0000005E, + 0x03F, 0x000FF3C0, + 0x033, 0x0000005D, + 0x03F, 0x000773E8, + 0x033, 0x0000005C, + 0x03F, 0x000FF3E8, + 0x033, 0x0000005B, + 0x03F, 0x00000287, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000207, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0xA0000000, 0x00000000, + 0x033, 0x0000005F, + 0x03F, 0x000773E8, + 0x033, 0x0000005E, + 0x03F, 0x000FF3A0, + 0x033, 0x0000005D, + 0x03F, 0x00000380, + 0x033, 0x0000005C, + 0x03F, 0x000FF380, + 0x033, 0x0000005B, + 0x03F, 0x00000300, + 0x033, 0x0000005A, + 0x03F, 0x000002A8, + 0x033, 0x00000059, + 0x03F, 0x00000280, + 0x033, 0x00000058, + 0x03F, 0x000FF280, + 0x033, 0x00000057, + 0x03F, 0x00000200, + 0x033, 0x00000056, + 0x03F, 0x000001C0, + 0x033, 0x00000055, + 0x03F, 0x00000180, + 0x033, 0x00000054, + 0x03F, 0x00000040, + 0xB0000000, 0x00000000, + 0x033, 0x00000053, + 0x03F, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x08A, 0x000E7DE3, + 0x08B, 0x0008FE00, + 0x0EE, 0x00000008, + 0x033, 0x00000000, + 0x03F, 0x00000023, + 0x033, 0x00000001, + 0x03F, 0x00000023, + 0x0EE, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x0EF, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000008, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002F81C, + 0x033, 0x00000010, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001C86, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00020000, + 0x033, 0x00000000, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000001, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000002, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000003, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000004, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000005, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000006, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000007, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000008, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000009, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000000A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000000B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000000C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000000D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000000E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000000F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000010, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000011, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000012, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000013, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000014, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000015, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000016, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000017, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000018, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000019, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000001A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000001B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000001C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000001D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000001E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000001F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000020, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000021, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x00000022, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x00000023, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x00000024, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x00000025, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x00000026, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x00000027, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x033, 0x00000028, + 0x03E, 0x00001910, + 0x03F, 0x00020000, + 0x033, 0x00000029, + 0x03E, 0x00001C02, + 0x03F, 0x00020000, + 0x033, 0x0000002A, + 0x03E, 0x00000F02, + 0x03F, 0x00020000, + 0x033, 0x0000002B, + 0x03E, 0x00000F00, + 0x03F, 0x00020000, + 0x033, 0x0000002C, + 0x03E, 0x00000086, + 0x03F, 0x00020000, + 0x033, 0x0000002D, + 0x03E, 0x00000002, + 0x03F, 0x00020000, + 0x033, 0x0000002E, + 0x03E, 0x00000000, + 0x03F, 0x00020000, + 0x033, 0x0000002F, + 0x03E, 0x00000000, + 0x03F, 0x0002C010, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0FE, 0x00000000, + 0x01B, 0x00003A40, + 0x061, 0x0000D233, + 0x062, 0x0004D232, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000C02, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000C02, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x00000002, + 0xA0000000, 0x00000000, + 0x063, 0x00000C02, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000237, + 0x030, 0x00001237, + 0x030, 0x00002237, + 0x030, 0x00003237, + 0x030, 0x00004207, + 0x030, 0x00005237, + 0x030, 0x00006237, + 0x030, 0x00007237, + 0x030, 0x00008207, + 0x030, 0x00009237, + 0x030, 0x0000A237, + 0x030, 0x0000B237, + 0x030, 0x0000C237, + 0x030, 0x0000D237, + 0x030, 0x0000E207, + 0x030, 0x0000F237, + 0x030, 0x00010237, + 0x030, 0x00011237, + 0x030, 0x00012207, + 0x030, 0x00013237, + 0x030, 0x00014237, + 0x030, 0x00015237, + 0x030, 0x00016207, + 0x030, 0x00017237, + 0x030, 0x00018207, + 0x030, 0x00019237, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000238, + 0x030, 0x00001238, + 0x030, 0x00002238, + 0x030, 0x00003238, + 0x030, 0x00004228, + 0x030, 0x00005238, + 0x030, 0x00006238, + 0x030, 0x00007238, + 0x030, 0x00008228, + 0x030, 0x00009238, + 0x030, 0x0000A238, + 0x030, 0x0000B238, + 0x030, 0x0000C238, + 0x030, 0x0000D238, + 0x030, 0x0000E228, + 0x030, 0x0000F238, + 0x030, 0x00010238, + 0x030, 0x00011238, + 0x030, 0x00012228, + 0x030, 0x00013238, + 0x030, 0x00014238, + 0x030, 0x00015238, + 0x030, 0x00016228, + 0x030, 0x00017238, + 0x030, 0x00018228, + 0x030, 0x00019238, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000239, + 0x030, 0x00001239, + 0x030, 0x00002239, + 0x030, 0x00003239, + 0x030, 0x00004239, + 0x030, 0x00005239, + 0x030, 0x00006239, + 0x030, 0x00007239, + 0x030, 0x00008239, + 0x030, 0x00009239, + 0x030, 0x0000A239, + 0x030, 0x0000B239, + 0x030, 0x0000C239, + 0x030, 0x0000D239, + 0x030, 0x0000E209, + 0x030, 0x0000F239, + 0x030, 0x00010239, + 0x030, 0x00011239, + 0x030, 0x00012209, + 0x030, 0x00013239, + 0x030, 0x00014239, + 0x030, 0x00015239, + 0x030, 0x00016209, + 0x030, 0x00017239, + 0x030, 0x00018209, + 0x030, 0x00019239, + 0xA0000000, 0x00000000, + 0x030, 0x00000233, + 0x030, 0x00001233, + 0x030, 0x00002233, + 0x030, 0x00003233, + 0x030, 0x00004203, + 0x030, 0x00005233, + 0x030, 0x00006233, + 0x030, 0x00007233, + 0x030, 0x00008203, + 0x030, 0x00009233, + 0x030, 0x0000A233, + 0x030, 0x0000B233, + 0x030, 0x0000C233, + 0x030, 0x0000D233, + 0x030, 0x0000E203, + 0x030, 0x0000F233, + 0x030, 0x00010233, + 0x030, 0x00011233, + 0x030, 0x00012203, + 0x030, 0x00013233, + 0x030, 0x00014233, + 0x030, 0x00015233, + 0x030, 0x00016203, + 0x030, 0x00017233, + 0x030, 0x00018203, + 0x030, 0x00019233, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000080, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000334, + 0x030, 0x00001334, + 0x030, 0x00002334, + 0x030, 0x00003334, + 0x030, 0x00004334, + 0x030, 0x00005334, + 0x030, 0x00006334, + 0x030, 0x00007334, + 0x030, 0x00008334, + 0x030, 0x00009334, + 0x030, 0x0000A334, + 0x030, 0x0000B334, + 0xA0000000, 0x00000000, + 0x030, 0x00000232, + 0x030, 0x00001232, + 0x030, 0x00002232, + 0x030, 0x00003232, + 0x030, 0x00004232, + 0x030, 0x00005232, + 0x030, 0x00006232, + 0x030, 0x00007232, + 0x030, 0x00008232, + 0x030, 0x00009232, + 0x030, 0x0000A232, + 0x030, 0x0000B232, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000770, + 0x030, 0x00001770, + 0x030, 0x00002440, + 0x030, 0x00003440, + 0x030, 0x00004330, + 0x030, 0x00005330, + 0x030, 0x00008770, + 0x030, 0x0000A440, + 0x030, 0x0000C330, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x00000005, + 0x033, 0x00000201, + 0x03F, 0x00000008, + 0x033, 0x00000202, + 0x03F, 0x0000000B, + 0x033, 0x00000203, + 0x03F, 0x0000000E, + 0x033, 0x00000204, + 0x03F, 0x0000002B, + 0x033, 0x00000205, + 0x03F, 0x0000002E, + 0x033, 0x00000206, + 0x03F, 0x0000006B, + 0x033, 0x00000207, + 0x03F, 0x0000006E, + 0x033, 0x00000208, + 0x03F, 0x00000071, + 0x033, 0x00000209, + 0x03F, 0x00000074, + 0x033, 0x0000020A, + 0x03F, 0x00000077, + 0xA0000000, 0x00000000, + 0x033, 0x00000200, + 0x03F, 0x0000006A, + 0x033, 0x00000201, + 0x03F, 0x0000006D, + 0x033, 0x00000202, + 0x03F, 0x0000046A, + 0x033, 0x00000203, + 0x03F, 0x0000086A, + 0x033, 0x00000204, + 0x03F, 0x00000C89, + 0x033, 0x00000205, + 0x03F, 0x00000CE8, + 0x033, 0x00000206, + 0x03F, 0x00000CEB, + 0x033, 0x00000207, + 0x03F, 0x00000CEE, + 0x033, 0x00000208, + 0x03F, 0x00000CF1, + 0x033, 0x00000209, + 0x03F, 0x00000CF4, + 0x033, 0x0000020A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x00000005, + 0x033, 0x00000281, + 0x03F, 0x00000008, + 0x033, 0x00000282, + 0x03F, 0x0000000B, + 0x033, 0x00000283, + 0x03F, 0x0000000E, + 0x033, 0x00000284, + 0x03F, 0x0000002B, + 0x033, 0x00000285, + 0x03F, 0x0000002E, + 0x033, 0x00000286, + 0x03F, 0x0000006B, + 0x033, 0x00000287, + 0x03F, 0x0000006E, + 0x033, 0x00000288, + 0x03F, 0x00000071, + 0x033, 0x00000289, + 0x03F, 0x00000074, + 0x033, 0x0000028A, + 0x03F, 0x00000077, + 0xA0000000, 0x00000000, + 0x033, 0x00000280, + 0x03F, 0x0000006A, + 0x033, 0x00000281, + 0x03F, 0x0000006D, + 0x033, 0x00000282, + 0x03F, 0x0000046A, + 0x033, 0x00000283, + 0x03F, 0x0000086A, + 0x033, 0x00000284, + 0x03F, 0x00000C89, + 0x033, 0x00000285, + 0x03F, 0x00000CE8, + 0x033, 0x00000286, + 0x03F, 0x00000CEB, + 0x033, 0x00000287, + 0x03F, 0x00000CEE, + 0x033, 0x00000288, + 0x03F, 0x00000CF1, + 0x033, 0x00000289, + 0x03F, 0x00000CF4, + 0x033, 0x0000028A, + 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x00000005, + 0x033, 0x00000301, + 0x03F, 0x00000008, + 0x033, 0x00000302, + 0x03F, 0x0000000B, + 0x033, 0x00000303, + 0x03F, 0x0000000E, + 0x033, 0x00000304, + 0x03F, 0x0000002B, + 0x033, 0x00000305, + 0x03F, 0x0000002E, + 0x033, 0x00000306, + 0x03F, 0x00000031, + 0x033, 0x00000307, + 0x03F, 0x00000034, + 0x033, 0x00000308, + 0x03F, 0x00000053, + 0x033, 0x00000309, + 0x03F, 0x00000056, + 0x033, 0x0000030A, + 0x03F, 0x000000D1, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x00000300, + 0x03F, 0x0000006A, + 0x033, 0x00000301, + 0x03F, 0x0000006D, + 0x033, 0x00000302, + 0x03F, 0x0000046A, + 0x033, 0x00000303, + 0x03F, 0x0000086A, + 0x033, 0x00000304, + 0x03F, 0x00000C89, + 0x033, 0x00000305, + 0x03F, 0x00000CE8, + 0x033, 0x00000306, + 0x03F, 0x00000CEB, + 0x033, 0x00000307, + 0x03F, 0x00000CEE, + 0x033, 0x00000308, + 0x03F, 0x00000CF1, + 0x033, 0x00000309, + 0x03F, 0x00000CF4, + 0x033, 0x0000030A, + 0x03F, 0x00000CF7, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x051, 0x0003C800, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000942C0, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000942C0, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x052, 0x000902CA, + 0xA0000000, 0x00000000, + 0x052, 0x000942C0, + 0xB0000000, 0x00000000, + 0x053, 0x000090F9, + 0x054, 0x00088000, + 0x057, 0x0004C80A, + 0x0EF, 0x00000020, + 0x033, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000001, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000002, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0xA0000000, 0x00000000, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000003, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000004, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000005, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0xA0000000, 0x00000000, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000006, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000007, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000008, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0000C246, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0xA0000000, 0x00000000, + 0x03F, 0x0000C246, + 0xB0000000, 0x00000000, + 0x033, 0x00000009, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000A, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000B, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000C, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000D, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000241C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000E, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002C246, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000000F, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000010, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000011, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00024246, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000012, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000013, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000014, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000015, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000016, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000018, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000019, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001A, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001B, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001C, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001D, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001E, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000001F, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000020, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000021, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000022, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000023, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000024, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000025, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000026, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000027, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000028, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00000030, + 0x03F, 0x000209C6, + 0xA0000000, 0x00000000, + 0x03E, 0x00000020, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x00000029, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0002CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x033, 0x0000002A, + 0x03E, 0x00000020, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00008E46, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x0001CA46, + 0xA0000000, 0x00000000, + 0x03F, 0x00008E46, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000468, + 0x033, 0x00000061, + 0x03F, 0x00000868, + 0x033, 0x00000062, + 0x03F, 0x00000909, + 0x033, 0x00000063, + 0x03F, 0x00000D0A, + 0x033, 0x00000064, + 0x03F, 0x00000D4A, + 0x033, 0x00000065, + 0x03F, 0x00000D8B, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000467, + 0x033, 0x00000061, + 0x03F, 0x00000867, + 0x033, 0x00000062, + 0x03F, 0x00000908, + 0x033, 0x00000063, + 0x03F, 0x00000CC6, + 0x033, 0x00000064, + 0x03F, 0x00000CC9, + 0x033, 0x00000065, + 0x03F, 0x00000CCC, + 0x033, 0x00000066, + 0x03F, 0x00000CCF, + 0x033, 0x00000067, + 0x03F, 0x00000CD2, + 0x033, 0x00000068, + 0x03F, 0x00000CD5, + 0x033, 0x00000069, + 0x03F, 0x00000DD4, + 0x033, 0x0000006A, + 0x03F, 0x00000DD7, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000487, + 0x033, 0x00000061, + 0x03F, 0x00000887, + 0x033, 0x00000062, + 0x03F, 0x00000947, + 0x033, 0x00000063, + 0x03F, 0x00000D48, + 0x033, 0x00000064, + 0x03F, 0x00000D88, + 0x033, 0x00000065, + 0x03F, 0x00000DE8, + 0x033, 0x00000066, + 0x03F, 0x00000DEB, + 0x033, 0x00000067, + 0x03F, 0x00000DEE, + 0x033, 0x00000068, + 0x03F, 0x00000DF1, + 0x033, 0x00000069, + 0x03F, 0x00000DF4, + 0x033, 0x0000006A, + 0x03F, 0x00000DF7, + 0xB0000000, 0x00000000, + 0x8f000000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x9f000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x91000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x91000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x92000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x92000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000468, + 0x033, 0x00000021, + 0x03F, 0x00000868, + 0x033, 0x00000022, + 0x03F, 0x00000909, + 0x033, 0x00000023, + 0x03F, 0x00000D0A, + 0x033, 0x00000024, + 0x03F, 0x00000D4A, + 0x033, 0x00000025, + 0x03F, 0x00000D8B, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x93000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x94000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000001, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000002, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000003, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000006, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000015, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0x95000016, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000467, + 0x033, 0x00000021, + 0x03F, 0x00000867, + 0x033, 0x00000022, + 0x03F, 0x00000908, + 0x033, 0x00000023, + 0x03F, 0x00000D09, + 0x033, 0x00000024, + 0x03F, 0x00000D49, + 0x033, 0x00000025, + 0x03F, 0x00000D8A, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000487, + 0x033, 0x00000021, + 0x03F, 0x00000887, + 0x033, 0x00000022, + 0x03F, 0x00000947, + 0x033, 0x00000023, + 0x03F, 0x00000D48, + 0x033, 0x00000024, + 0x03F, 0x00000D88, + 0x033, 0x00000025, + 0x03F, 0x00000DE8, + 0x033, 0x00000026, + 0x03F, 0x00000DEB, + 0x033, 0x00000027, + 0x03F, 0x00000DEE, + 0x033, 0x00000028, + 0x03F, 0x00000DF1, + 0x033, 0x00000029, + 0x03F, 0x00000DF4, + 0x033, 0x0000002A, + 0x03F, 0x00000DF7, + 0xB0000000, 0x00000000, + 0x0EE, 0x00000000, + 0x05C, 0x000FC000, + 0x067, 0x0000A505, + 0x0D3, 0x00000542, + 0x043, 0x00005000, + 0x059, 0x000A0000, + 0x05A, 0x00060000, + 0x05B, 0x00014000, + 0x001, 0x00040000, + 0x0EE, 0x00000002, + 0x033, 0x00000017, + 0x03F, 0x0000003F, + 0x033, 0x00000018, + 0x03F, 0x0000003F, + 0x033, 0x00000019, + 0x03F, 0x00000000, + 0x033, 0x0000001A, + 0x03F, 0x0000003F, + 0x033, 0x0000001B, + 0x03F, 0x0000003F, + 0x033, 0x0000001C, + 0x03F, 0x0000003F, + 0x0EE, 0x00000000, + 0x092, 0x00084800, + 0x092, 0x00084801, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x0FE, 0x00000000, + 0x092, 0x00084800, + 0x08F, 0x00001B4C, + 0x088, 0x0004326B, + 0x019, 0x00000005, + 0x0EF, 0x00080000, + 0x033, 0x00000004, + 0x03F, 0x000FD83F, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000006, + 0x03F, 0x000DD83F, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000007, + 0x03F, 0x000DF7BF, + 0x0EF, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000006, + 0x03F, 0x00000002, + 0x033, 0x00000007, + 0x03F, 0x00000002, + 0x0EF, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8822c_rf_b, B); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8822c_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 72, }, + { 2, 0, 0, 0, 1, 60, }, + { 1, 0, 0, 0, 1, 68, }, + { 3, 0, 0, 0, 1, 72, }, + { 4, 0, 0, 0, 1, 76, }, + { 5, 0, 0, 0, 1, 60, }, + { 6, 0, 0, 0, 1, 72, }, + { 7, 0, 0, 0, 1, 60, }, + { 8, 0, 0, 0, 1, 72, }, + { 9, 0, 0, 0, 1, 60, }, + { 10, 0, 0, 0, 1, 60, }, + { 11, 0, 0, 0, 1, 60, }, + { 0, 0, 0, 0, 2, 72, }, + { 2, 0, 0, 0, 2, 60, }, + { 1, 0, 0, 0, 2, 68, }, + { 3, 0, 0, 0, 2, 72, }, + { 4, 0, 0, 0, 2, 76, }, + { 5, 0, 0, 0, 2, 60, }, + { 6, 0, 0, 0, 2, 72, }, + { 7, 0, 0, 0, 2, 60, }, + { 8, 0, 0, 0, 2, 72, }, + { 9, 0, 0, 0, 2, 60, }, + { 10, 0, 0, 0, 2, 60, }, + { 11, 0, 0, 0, 2, 60, }, + { 0, 0, 0, 0, 3, 76, }, + { 2, 0, 0, 0, 3, 60, }, + { 1, 0, 0, 0, 3, 68, }, + { 3, 0, 0, 0, 3, 76, }, + { 4, 0, 0, 0, 3, 76, }, + { 5, 0, 0, 0, 3, 60, }, + { 6, 0, 0, 0, 3, 76, }, + { 7, 0, 0, 0, 3, 60, }, + { 8, 0, 0, 0, 3, 76, }, + { 9, 0, 0, 0, 3, 60, }, + { 10, 0, 0, 0, 3, 60, }, + { 11, 0, 0, 0, 3, 60, }, + { 0, 0, 0, 0, 4, 76, }, + { 2, 0, 0, 0, 4, 60, }, + { 1, 0, 0, 0, 4, 68, }, + { 3, 0, 0, 0, 4, 76, }, + { 4, 0, 0, 0, 4, 76, }, + { 5, 0, 0, 0, 4, 60, }, + { 6, 0, 0, 0, 4, 76, }, + { 7, 0, 0, 0, 4, 60, }, + { 8, 0, 0, 0, 4, 76, }, + { 9, 0, 0, 0, 4, 60, }, + { 10, 0, 0, 0, 4, 60, }, + { 11, 0, 0, 0, 4, 60, }, + { 0, 0, 0, 0, 5, 76, }, + { 2, 0, 0, 0, 5, 60, }, + { 1, 0, 0, 0, 5, 68, }, + { 3, 0, 0, 0, 5, 76, }, + { 4, 0, 0, 0, 5, 76, }, + { 5, 0, 0, 0, 5, 60, }, + { 6, 0, 0, 0, 5, 76, }, + { 7, 0, 0, 0, 5, 60, }, + { 8, 0, 0, 0, 5, 76, }, + { 9, 0, 0, 0, 5, 60, }, + { 10, 0, 0, 0, 5, 60, }, + { 11, 0, 0, 0, 5, 60, }, + { 0, 0, 0, 0, 6, 76, }, + { 2, 0, 0, 0, 6, 60, }, + { 1, 0, 0, 0, 6, 68, }, + { 3, 0, 0, 0, 6, 76, }, + { 4, 0, 0, 0, 6, 76, }, + { 5, 0, 0, 0, 6, 60, }, + { 6, 0, 0, 0, 6, 76, }, + { 7, 0, 0, 0, 6, 60, }, + { 8, 0, 0, 0, 6, 76, }, + { 9, 0, 0, 0, 6, 60, }, + { 10, 0, 0, 0, 6, 60, }, + { 11, 0, 0, 0, 6, 60, }, + { 0, 0, 0, 0, 7, 76, }, + { 2, 0, 0, 0, 7, 60, }, + { 1, 0, 0, 0, 7, 68, }, + { 3, 0, 0, 0, 7, 76, }, + { 4, 0, 0, 0, 7, 76, }, + { 5, 0, 0, 0, 7, 60, }, + { 6, 0, 0, 0, 7, 76, }, + { 7, 0, 0, 0, 7, 60, }, + { 8, 0, 0, 0, 7, 76, }, + { 9, 0, 0, 0, 7, 60, }, + { 10, 0, 0, 0, 7, 60, }, + { 11, 0, 0, 0, 7, 60, }, + { 0, 0, 0, 0, 8, 76, }, + { 2, 0, 0, 0, 8, 60, }, + { 1, 0, 0, 0, 8, 68, }, + { 3, 0, 0, 0, 8, 76, }, + { 4, 0, 0, 0, 8, 76, }, + { 5, 0, 0, 0, 8, 60, }, + { 6, 0, 0, 0, 8, 76, }, + { 7, 0, 0, 0, 8, 60, }, + { 8, 0, 0, 0, 8, 76, }, + { 9, 0, 0, 0, 8, 60, }, + { 10, 0, 0, 0, 8, 60, }, + { 11, 0, 0, 0, 8, 60, }, + { 0, 0, 0, 0, 9, 76, }, + { 2, 0, 0, 0, 9, 60, }, + { 1, 0, 0, 0, 9, 68, }, + { 3, 0, 0, 0, 9, 76, }, + { 4, 0, 0, 0, 9, 76, }, + { 5, 0, 0, 0, 9, 60, }, + { 6, 0, 0, 0, 9, 76, }, + { 7, 0, 0, 0, 9, 60, }, + { 8, 0, 0, 0, 9, 76, }, + { 9, 0, 0, 0, 9, 60, }, + { 10, 0, 0, 0, 9, 60, }, + { 11, 0, 0, 0, 9, 60, }, + { 0, 0, 0, 0, 10, 72, }, + { 2, 0, 0, 0, 10, 60, }, + { 1, 0, 0, 0, 10, 68, }, + { 3, 0, 0, 0, 10, 72, }, + { 4, 0, 0, 0, 10, 76, }, + { 5, 0, 0, 0, 10, 60, }, + { 6, 0, 0, 0, 10, 72, }, + { 7, 0, 0, 0, 10, 60, }, + { 8, 0, 0, 0, 10, 72, }, + { 9, 0, 0, 0, 10, 60, }, + { 10, 0, 0, 0, 10, 60, }, + { 11, 0, 0, 0, 10, 60, }, + { 0, 0, 0, 0, 11, 72, }, + { 2, 0, 0, 0, 11, 60, }, + { 1, 0, 0, 0, 11, 68, }, + { 3, 0, 0, 0, 11, 72, }, + { 4, 0, 0, 0, 11, 76, }, + { 5, 0, 0, 0, 11, 60, }, + { 6, 0, 0, 0, 11, 72, }, + { 7, 0, 0, 0, 11, 60, }, + { 8, 0, 0, 0, 11, 72, }, + { 9, 0, 0, 0, 11, 60, }, + { 10, 0, 0, 0, 11, 60, }, + { 11, 0, 0, 0, 11, 60, }, + { 0, 0, 0, 0, 12, 52, }, + { 2, 0, 0, 0, 12, 60, }, + { 1, 0, 0, 0, 12, 68, }, + { 3, 0, 0, 0, 12, 52, }, + { 4, 0, 0, 0, 12, 76, }, + { 5, 0, 0, 0, 12, 60, }, + { 6, 0, 0, 0, 12, 52, }, + { 7, 0, 0, 0, 12, 60, }, + { 8, 0, 0, 0, 12, 52, }, + { 9, 0, 0, 0, 12, 60, }, + { 10, 0, 0, 0, 12, 60, }, + { 11, 0, 0, 0, 12, 60, }, + { 0, 0, 0, 0, 13, 48, }, + { 2, 0, 0, 0, 13, 60, }, + { 1, 0, 0, 0, 13, 68, }, + { 3, 0, 0, 0, 13, 48, }, + { 4, 0, 0, 0, 13, 76, }, + { 5, 0, 0, 0, 13, 60, }, + { 6, 0, 0, 0, 13, 48, }, + { 7, 0, 0, 0, 13, 60, }, + { 8, 0, 0, 0, 13, 48, }, + { 9, 0, 0, 0, 13, 60, }, + { 10, 0, 0, 0, 13, 60, }, + { 11, 0, 0, 0, 13, 60, }, + { 0, 0, 0, 0, 14, 127, }, + { 2, 0, 0, 0, 14, 127, }, + { 1, 0, 0, 0, 14, 68, }, + { 3, 0, 0, 0, 14, 127, }, + { 4, 0, 0, 0, 14, 127, }, + { 5, 0, 0, 0, 14, 127, }, + { 6, 0, 0, 0, 14, 127, }, + { 7, 0, 0, 0, 14, 127, }, + { 8, 0, 0, 0, 14, 127, }, + { 9, 0, 0, 0, 14, 127, }, + { 10, 0, 0, 0, 14, 127, }, + { 11, 0, 0, 0, 14, 127, }, + { 0, 0, 0, 1, 1, 52, }, + { 2, 0, 0, 1, 1, 60, }, + { 1, 0, 0, 1, 1, 76, }, + { 3, 0, 0, 1, 1, 52, }, + { 4, 0, 0, 1, 1, 76, }, + { 5, 0, 0, 1, 1, 60, }, + { 6, 0, 0, 1, 1, 52, }, + { 7, 0, 0, 1, 1, 60, }, + { 8, 0, 0, 1, 1, 52, }, + { 9, 0, 0, 1, 1, 60, }, + { 10, 0, 0, 1, 1, 60, }, + { 11, 0, 0, 1, 1, 60, }, + { 0, 0, 0, 1, 2, 60, }, + { 2, 0, 0, 1, 2, 60, }, + { 1, 0, 0, 1, 2, 76, }, + { 3, 0, 0, 1, 2, 60, }, + { 4, 0, 0, 1, 2, 76, }, + { 5, 0, 0, 1, 2, 60, }, + { 6, 0, 0, 1, 2, 60, }, + { 7, 0, 0, 1, 2, 60, }, + { 8, 0, 0, 1, 2, 60, }, + { 9, 0, 0, 1, 2, 60, }, + { 10, 0, 0, 1, 2, 60, }, + { 11, 0, 0, 1, 2, 60, }, + { 0, 0, 0, 1, 3, 64, }, + { 2, 0, 0, 1, 3, 60, }, + { 1, 0, 0, 1, 3, 76, }, + { 3, 0, 0, 1, 3, 64, }, + { 4, 0, 0, 1, 3, 76, }, + { 5, 0, 0, 1, 3, 60, }, + { 6, 0, 0, 1, 3, 64, }, + { 7, 0, 0, 1, 3, 60, }, + { 8, 0, 0, 1, 3, 64, }, + { 9, 0, 0, 1, 3, 60, }, + { 10, 0, 0, 1, 3, 60, }, + { 11, 0, 0, 1, 3, 60, }, + { 0, 0, 0, 1, 4, 68, }, + { 2, 0, 0, 1, 4, 60, }, + { 1, 0, 0, 1, 4, 76, }, + { 3, 0, 0, 1, 4, 68, }, + { 4, 0, 0, 1, 4, 76, }, + { 5, 0, 0, 1, 4, 60, }, + { 6, 0, 0, 1, 4, 68, }, + { 7, 0, 0, 1, 4, 60, }, + { 8, 0, 0, 1, 4, 68, }, + { 9, 0, 0, 1, 4, 60, }, + { 10, 0, 0, 1, 4, 60, }, + { 11, 0, 0, 1, 4, 60, }, + { 0, 0, 0, 1, 5, 76, }, + { 2, 0, 0, 1, 5, 60, }, + { 1, 0, 0, 1, 5, 76, }, + { 3, 0, 0, 1, 5, 76, }, + { 4, 0, 0, 1, 5, 76, }, + { 5, 0, 0, 1, 5, 60, }, + { 6, 0, 0, 1, 5, 76, }, + { 7, 0, 0, 1, 5, 60, }, + { 8, 0, 0, 1, 5, 76, }, + { 9, 0, 0, 1, 5, 60, }, + { 10, 0, 0, 1, 5, 60, }, + { 11, 0, 0, 1, 5, 60, }, + { 0, 0, 0, 1, 6, 76, }, + { 2, 0, 0, 1, 6, 60, }, + { 1, 0, 0, 1, 6, 76, }, + { 3, 0, 0, 1, 6, 76, }, + { 4, 0, 0, 1, 6, 76, }, + { 5, 0, 0, 1, 6, 60, }, + { 6, 0, 0, 1, 6, 76, }, + { 7, 0, 0, 1, 6, 60, }, + { 8, 0, 0, 1, 6, 76, }, + { 9, 0, 0, 1, 6, 60, }, + { 10, 0, 0, 1, 6, 60, }, + { 11, 0, 0, 1, 6, 60, }, + { 0, 0, 0, 1, 7, 76, }, + { 2, 0, 0, 1, 7, 60, }, + { 1, 0, 0, 1, 7, 76, }, + { 3, 0, 0, 1, 7, 76, }, + { 4, 0, 0, 1, 7, 76, }, + { 5, 0, 0, 1, 7, 60, }, + { 6, 0, 0, 1, 7, 76, }, + { 7, 0, 0, 1, 7, 60, }, + { 8, 0, 0, 1, 7, 76, }, + { 9, 0, 0, 1, 7, 60, }, + { 10, 0, 0, 1, 7, 60, }, + { 11, 0, 0, 1, 7, 60, }, + { 0, 0, 0, 1, 8, 68, }, + { 2, 0, 0, 1, 8, 60, }, + { 1, 0, 0, 1, 8, 76, }, + { 3, 0, 0, 1, 8, 68, }, + { 4, 0, 0, 1, 8, 76, }, + { 5, 0, 0, 1, 8, 60, }, + { 6, 0, 0, 1, 8, 68, }, + { 7, 0, 0, 1, 8, 60, }, + { 8, 0, 0, 1, 8, 68, }, + { 9, 0, 0, 1, 8, 60, }, + { 10, 0, 0, 1, 8, 60, }, + { 11, 0, 0, 1, 8, 60, }, + { 0, 0, 0, 1, 9, 64, }, + { 2, 0, 0, 1, 9, 60, }, + { 1, 0, 0, 1, 9, 76, }, + { 3, 0, 0, 1, 9, 64, }, + { 4, 0, 0, 1, 9, 76, }, + { 5, 0, 0, 1, 9, 60, }, + { 6, 0, 0, 1, 9, 64, }, + { 7, 0, 0, 1, 9, 60, }, + { 8, 0, 0, 1, 9, 64, }, + { 9, 0, 0, 1, 9, 60, }, + { 10, 0, 0, 1, 9, 60, }, + { 11, 0, 0, 1, 9, 60, }, + { 0, 0, 0, 1, 10, 60, }, + { 2, 0, 0, 1, 10, 60, }, + { 1, 0, 0, 1, 10, 76, }, + { 3, 0, 0, 1, 10, 60, }, + { 4, 0, 0, 1, 10, 76, }, + { 5, 0, 0, 1, 10, 60, }, + { 6, 0, 0, 1, 10, 60, }, + { 7, 0, 0, 1, 10, 60, }, + { 8, 0, 0, 1, 10, 60, }, + { 9, 0, 0, 1, 10, 60, }, + { 10, 0, 0, 1, 10, 60, }, + { 11, 0, 0, 1, 10, 60, }, + { 0, 0, 0, 1, 11, 52, }, + { 2, 0, 0, 1, 11, 60, }, + { 1, 0, 0, 1, 11, 76, }, + { 3, 0, 0, 1, 11, 52, }, + { 4, 0, 0, 1, 11, 76, }, + { 5, 0, 0, 1, 11, 60, }, + { 6, 0, 0, 1, 11, 52, }, + { 7, 0, 0, 1, 11, 60, }, + { 8, 0, 0, 1, 11, 52, }, + { 9, 0, 0, 1, 11, 44, }, + { 10, 0, 0, 1, 11, 60, }, + { 11, 0, 0, 1, 11, 60, }, + { 0, 0, 0, 1, 12, 40, }, + { 2, 0, 0, 1, 12, 60, }, + { 1, 0, 0, 1, 12, 76, }, + { 3, 0, 0, 1, 12, 40, }, + { 4, 0, 0, 1, 12, 76, }, + { 5, 0, 0, 1, 12, 60, }, + { 6, 0, 0, 1, 12, 40, }, + { 7, 0, 0, 1, 12, 60, }, + { 8, 0, 0, 1, 12, 40, }, + { 9, 0, 0, 1, 12, 44, }, + { 10, 0, 0, 1, 12, 60, }, + { 11, 0, 0, 1, 12, 60, }, + { 0, 0, 0, 1, 13, 28, }, + { 2, 0, 0, 1, 13, 60, }, + { 1, 0, 0, 1, 13, 76, }, + { 3, 0, 0, 1, 13, 28, }, + { 4, 0, 0, 1, 13, 70, }, + { 5, 0, 0, 1, 13, 60, }, + { 6, 0, 0, 1, 13, 28, }, + { 7, 0, 0, 1, 13, 60, }, + { 8, 0, 0, 1, 13, 28, }, + { 9, 0, 0, 1, 13, 36, }, + { 10, 0, 0, 1, 13, 60, }, + { 11, 0, 0, 1, 13, 60, }, + { 0, 0, 0, 1, 14, 127, }, + { 2, 0, 0, 1, 14, 127, }, + { 1, 0, 0, 1, 14, 127, }, + { 3, 0, 0, 1, 14, 127, }, + { 4, 0, 0, 1, 14, 127, }, + { 5, 0, 0, 1, 14, 127, }, + { 6, 0, 0, 1, 14, 127, }, + { 7, 0, 0, 1, 14, 127, }, + { 8, 0, 0, 1, 14, 127, }, + { 9, 0, 0, 1, 14, 127, }, + { 10, 0, 0, 1, 14, 127, }, + { 11, 0, 0, 1, 14, 127, }, + { 0, 0, 0, 2, 1, 52, }, + { 2, 0, 0, 2, 1, 60, }, + { 1, 0, 0, 2, 1, 76, }, + { 3, 0, 0, 2, 1, 52, }, + { 4, 0, 0, 2, 1, 76, }, + { 5, 0, 0, 2, 1, 60, }, + { 6, 0, 0, 2, 1, 52, }, + { 7, 0, 0, 2, 1, 60, }, + { 8, 0, 0, 2, 1, 52, }, + { 9, 0, 0, 2, 1, 60, }, + { 10, 0, 0, 2, 1, 60, }, + { 11, 0, 0, 2, 1, 60, }, + { 0, 0, 0, 2, 2, 60, }, + { 2, 0, 0, 2, 2, 60, }, + { 1, 0, 0, 2, 2, 76, }, + { 3, 0, 0, 2, 2, 60, }, + { 4, 0, 0, 2, 2, 76, }, + { 5, 0, 0, 2, 2, 60, }, + { 6, 0, 0, 2, 2, 60, }, + { 7, 0, 0, 2, 2, 60, }, + { 8, 0, 0, 2, 2, 60, }, + { 9, 0, 0, 2, 2, 60, }, + { 10, 0, 0, 2, 2, 60, }, + { 11, 0, 0, 2, 2, 60, }, + { 0, 0, 0, 2, 3, 64, }, + { 2, 0, 0, 2, 3, 60, }, + { 1, 0, 0, 2, 3, 76, }, + { 3, 0, 0, 2, 3, 64, }, + { 4, 0, 0, 2, 3, 76, }, + { 5, 0, 0, 2, 3, 60, }, + { 6, 0, 0, 2, 3, 64, }, + { 7, 0, 0, 2, 3, 60, }, + { 8, 0, 0, 2, 3, 64, }, + { 9, 0, 0, 2, 3, 60, }, + { 10, 0, 0, 2, 3, 60, }, + { 11, 0, 0, 2, 3, 60, }, + { 0, 0, 0, 2, 4, 68, }, + { 2, 0, 0, 2, 4, 60, }, + { 1, 0, 0, 2, 4, 76, }, + { 3, 0, 0, 2, 4, 68, }, + { 4, 0, 0, 2, 4, 76, }, + { 5, 0, 0, 2, 4, 60, }, + { 6, 0, 0, 2, 4, 68, }, + { 7, 0, 0, 2, 4, 60, }, + { 8, 0, 0, 2, 4, 68, }, + { 9, 0, 0, 2, 4, 60, }, + { 10, 0, 0, 2, 4, 60, }, + { 11, 0, 0, 2, 4, 60, }, + { 0, 0, 0, 2, 5, 76, }, + { 2, 0, 0, 2, 5, 60, }, + { 1, 0, 0, 2, 5, 76, }, + { 3, 0, 0, 2, 5, 76, }, + { 4, 0, 0, 2, 5, 76, }, + { 5, 0, 0, 2, 5, 60, }, + { 6, 0, 0, 2, 5, 76, }, + { 7, 0, 0, 2, 5, 60, }, + { 8, 0, 0, 2, 5, 76, }, + { 9, 0, 0, 2, 5, 60, }, + { 10, 0, 0, 2, 5, 60, }, + { 11, 0, 0, 2, 5, 60, }, + { 0, 0, 0, 2, 6, 76, }, + { 2, 0, 0, 2, 6, 60, }, + { 1, 0, 0, 2, 6, 76, }, + { 3, 0, 0, 2, 6, 76, }, + { 4, 0, 0, 2, 6, 76, }, + { 5, 0, 0, 2, 6, 60, }, + { 6, 0, 0, 2, 6, 76, }, + { 7, 0, 0, 2, 6, 60, }, + { 8, 0, 0, 2, 6, 76, }, + { 9, 0, 0, 2, 6, 60, }, + { 10, 0, 0, 2, 6, 60, }, + { 11, 0, 0, 2, 6, 60, }, + { 0, 0, 0, 2, 7, 76, }, + { 2, 0, 0, 2, 7, 60, }, + { 1, 0, 0, 2, 7, 76, }, + { 3, 0, 0, 2, 7, 76, }, + { 4, 0, 0, 2, 7, 76, }, + { 5, 0, 0, 2, 7, 60, }, + { 6, 0, 0, 2, 7, 76, }, + { 7, 0, 0, 2, 7, 60, }, + { 8, 0, 0, 2, 7, 76, }, + { 9, 0, 0, 2, 7, 60, }, + { 10, 0, 0, 2, 7, 60, }, + { 11, 0, 0, 2, 7, 60, }, + { 0, 0, 0, 2, 8, 68, }, + { 2, 0, 0, 2, 8, 60, }, + { 1, 0, 0, 2, 8, 76, }, + { 3, 0, 0, 2, 8, 68, }, + { 4, 0, 0, 2, 8, 76, }, + { 5, 0, 0, 2, 8, 60, }, + { 6, 0, 0, 2, 8, 68, }, + { 7, 0, 0, 2, 8, 60, }, + { 8, 0, 0, 2, 8, 68, }, + { 9, 0, 0, 2, 8, 60, }, + { 10, 0, 0, 2, 8, 60, }, + { 11, 0, 0, 2, 8, 60, }, + { 0, 0, 0, 2, 9, 64, }, + { 2, 0, 0, 2, 9, 60, }, + { 1, 0, 0, 2, 9, 76, }, + { 3, 0, 0, 2, 9, 64, }, + { 4, 0, 0, 2, 9, 76, }, + { 5, 0, 0, 2, 9, 60, }, + { 6, 0, 0, 2, 9, 64, }, + { 7, 0, 0, 2, 9, 60, }, + { 8, 0, 0, 2, 9, 64, }, + { 9, 0, 0, 2, 9, 60, }, + { 10, 0, 0, 2, 9, 60, }, + { 11, 0, 0, 2, 9, 60, }, + { 0, 0, 0, 2, 10, 60, }, + { 2, 0, 0, 2, 10, 60, }, + { 1, 0, 0, 2, 10, 76, }, + { 3, 0, 0, 2, 10, 60, }, + { 4, 0, 0, 2, 10, 76, }, + { 5, 0, 0, 2, 10, 60, }, + { 6, 0, 0, 2, 10, 60, }, + { 7, 0, 0, 2, 10, 60, }, + { 8, 0, 0, 2, 10, 60, }, + { 9, 0, 0, 2, 10, 60, }, + { 10, 0, 0, 2, 10, 60, }, + { 11, 0, 0, 2, 10, 60, }, + { 0, 0, 0, 2, 11, 52, }, + { 2, 0, 0, 2, 11, 60, }, + { 1, 0, 0, 2, 11, 76, }, + { 3, 0, 0, 2, 11, 52, }, + { 4, 0, 0, 2, 11, 76, }, + { 5, 0, 0, 2, 11, 60, }, + { 6, 0, 0, 2, 11, 52, }, + { 7, 0, 0, 2, 11, 60, }, + { 8, 0, 0, 2, 11, 52, }, + { 9, 0, 0, 2, 11, 46, }, + { 10, 0, 0, 2, 11, 60, }, + { 11, 0, 0, 2, 11, 60, }, + { 0, 0, 0, 2, 12, 40, }, + { 2, 0, 0, 2, 12, 60, }, + { 1, 0, 0, 2, 12, 76, }, + { 3, 0, 0, 2, 12, 40, }, + { 4, 0, 0, 2, 12, 76, }, + { 5, 0, 0, 2, 12, 60, }, + { 6, 0, 0, 2, 12, 40, }, + { 7, 0, 0, 2, 12, 60, }, + { 8, 0, 0, 2, 12, 40, }, + { 9, 0, 0, 2, 12, 42, }, + { 10, 0, 0, 2, 12, 60, }, + { 11, 0, 0, 2, 12, 60, }, + { 0, 0, 0, 2, 13, 28, }, + { 2, 0, 0, 2, 13, 60, }, + { 1, 0, 0, 2, 13, 76, }, + { 3, 0, 0, 2, 13, 28, }, + { 4, 0, 0, 2, 13, 72, }, + { 5, 0, 0, 2, 13, 60, }, + { 6, 0, 0, 2, 13, 28, }, + { 7, 0, 0, 2, 13, 60, }, + { 8, 0, 0, 2, 13, 28, }, + { 9, 0, 0, 2, 13, 34, }, + { 10, 0, 0, 2, 13, 60, }, + { 11, 0, 0, 2, 13, 60, }, + { 0, 0, 0, 2, 14, 127, }, + { 2, 0, 0, 2, 14, 127, }, + { 1, 0, 0, 2, 14, 127, }, + { 3, 0, 0, 2, 14, 127, }, + { 4, 0, 0, 2, 14, 127, }, + { 5, 0, 0, 2, 14, 127, }, + { 6, 0, 0, 2, 14, 127, }, + { 7, 0, 0, 2, 14, 127, }, + { 8, 0, 0, 2, 14, 127, }, + { 9, 0, 0, 2, 14, 127, }, + { 10, 0, 0, 2, 14, 127, }, + { 11, 0, 0, 2, 14, 127, }, + { 0, 0, 0, 3, 1, 52, }, + { 2, 0, 0, 3, 1, 36, }, + { 1, 0, 0, 3, 1, 66, }, + { 3, 0, 0, 3, 1, 52, }, + { 4, 0, 0, 3, 1, 68, }, + { 5, 0, 0, 3, 1, 36, }, + { 6, 0, 0, 3, 1, 52, }, + { 7, 0, 0, 3, 1, 36, }, + { 8, 0, 0, 3, 1, 52, }, + { 9, 0, 0, 3, 1, 36, }, + { 10, 0, 0, 3, 1, 36, }, + { 11, 0, 0, 3, 1, 36, }, + { 0, 0, 0, 3, 2, 60, }, + { 2, 0, 0, 3, 2, 36, }, + { 1, 0, 0, 3, 2, 66, }, + { 3, 0, 0, 3, 2, 60, }, + { 4, 0, 0, 3, 2, 70, }, + { 5, 0, 0, 3, 2, 36, }, + { 6, 0, 0, 3, 2, 60, }, + { 7, 0, 0, 3, 2, 36, }, + { 8, 0, 0, 3, 2, 60, }, + { 9, 0, 0, 3, 2, 36, }, + { 10, 0, 0, 3, 2, 36, }, + { 11, 0, 0, 3, 2, 36, }, + { 0, 0, 0, 3, 3, 64, }, + { 2, 0, 0, 3, 3, 36, }, + { 1, 0, 0, 3, 3, 66, }, + { 3, 0, 0, 3, 3, 64, }, + { 4, 0, 0, 3, 3, 70, }, + { 5, 0, 0, 3, 3, 36, }, + { 6, 0, 0, 3, 3, 64, }, + { 7, 0, 0, 3, 3, 36, }, + { 8, 0, 0, 3, 3, 64, }, + { 9, 0, 0, 3, 3, 36, }, + { 10, 0, 0, 3, 3, 36, }, + { 11, 0, 0, 3, 3, 36, }, + { 0, 0, 0, 3, 4, 68, }, + { 2, 0, 0, 3, 4, 36, }, + { 1, 0, 0, 3, 4, 66, }, + { 3, 0, 0, 3, 4, 68, }, + { 4, 0, 0, 3, 4, 70, }, + { 5, 0, 0, 3, 4, 36, }, + { 6, 0, 0, 3, 4, 68, }, + { 7, 0, 0, 3, 4, 36, }, + { 8, 0, 0, 3, 4, 68, }, + { 9, 0, 0, 3, 4, 36, }, + { 10, 0, 0, 3, 4, 36, }, + { 11, 0, 0, 3, 4, 36, }, + { 0, 0, 0, 3, 5, 76, }, + { 2, 0, 0, 3, 5, 36, }, + { 1, 0, 0, 3, 5, 66, }, + { 3, 0, 0, 3, 5, 76, }, + { 4, 0, 0, 3, 5, 70, }, + { 5, 0, 0, 3, 5, 36, }, + { 6, 0, 0, 3, 5, 76, }, + { 7, 0, 0, 3, 5, 36, }, + { 8, 0, 0, 3, 5, 76, }, + { 9, 0, 0, 3, 5, 36, }, + { 10, 0, 0, 3, 5, 36, }, + { 11, 0, 0, 3, 5, 36, }, + { 0, 0, 0, 3, 6, 76, }, + { 2, 0, 0, 3, 6, 36, }, + { 1, 0, 0, 3, 6, 66, }, + { 3, 0, 0, 3, 6, 76, }, + { 4, 0, 0, 3, 6, 70, }, + { 5, 0, 0, 3, 6, 36, }, + { 6, 0, 0, 3, 6, 76, }, + { 7, 0, 0, 3, 6, 36, }, + { 8, 0, 0, 3, 6, 76, }, + { 9, 0, 0, 3, 6, 36, }, + { 10, 0, 0, 3, 6, 36, }, + { 11, 0, 0, 3, 6, 36, }, + { 0, 0, 0, 3, 7, 76, }, + { 2, 0, 0, 3, 7, 36, }, + { 1, 0, 0, 3, 7, 66, }, + { 3, 0, 0, 3, 7, 76, }, + { 4, 0, 0, 3, 7, 70, }, + { 5, 0, 0, 3, 7, 36, }, + { 6, 0, 0, 3, 7, 76, }, + { 7, 0, 0, 3, 7, 36, }, + { 8, 0, 0, 3, 7, 76, }, + { 9, 0, 0, 3, 7, 36, }, + { 10, 0, 0, 3, 7, 36, }, + { 11, 0, 0, 3, 7, 36, }, + { 0, 0, 0, 3, 8, 68, }, + { 2, 0, 0, 3, 8, 36, }, + { 1, 0, 0, 3, 8, 66, }, + { 3, 0, 0, 3, 8, 68, }, + { 4, 0, 0, 3, 8, 70, }, + { 5, 0, 0, 3, 8, 36, }, + { 6, 0, 0, 3, 8, 68, }, + { 7, 0, 0, 3, 8, 36, }, + { 8, 0, 0, 3, 8, 68, }, + { 9, 0, 0, 3, 8, 36, }, + { 10, 0, 0, 3, 8, 36, }, + { 11, 0, 0, 3, 8, 36, }, + { 0, 0, 0, 3, 9, 64, }, + { 2, 0, 0, 3, 9, 36, }, + { 1, 0, 0, 3, 9, 66, }, + { 3, 0, 0, 3, 9, 64, }, + { 4, 0, 0, 3, 9, 70, }, + { 5, 0, 0, 3, 9, 36, }, + { 6, 0, 0, 3, 9, 64, }, + { 7, 0, 0, 3, 9, 36, }, + { 8, 0, 0, 3, 9, 64, }, + { 9, 0, 0, 3, 9, 36, }, + { 10, 0, 0, 3, 9, 36, }, + { 11, 0, 0, 3, 9, 36, }, + { 0, 0, 0, 3, 10, 60, }, + { 2, 0, 0, 3, 10, 36, }, + { 1, 0, 0, 3, 10, 66, }, + { 3, 0, 0, 3, 10, 60, }, + { 4, 0, 0, 3, 10, 70, }, + { 5, 0, 0, 3, 10, 36, }, + { 6, 0, 0, 3, 10, 60, }, + { 7, 0, 0, 3, 10, 36, }, + { 8, 0, 0, 3, 10, 60, }, + { 9, 0, 0, 3, 10, 36, }, + { 10, 0, 0, 3, 10, 36, }, + { 11, 0, 0, 3, 10, 36, }, + { 0, 0, 0, 3, 11, 52, }, + { 2, 0, 0, 3, 11, 36, }, + { 1, 0, 0, 3, 11, 66, }, + { 3, 0, 0, 3, 11, 52, }, + { 4, 0, 0, 3, 11, 70, }, + { 5, 0, 0, 3, 11, 36, }, + { 6, 0, 0, 3, 11, 52, }, + { 7, 0, 0, 3, 11, 36, }, + { 8, 0, 0, 3, 11, 52, }, + { 9, 0, 0, 3, 11, 36, }, + { 10, 0, 0, 3, 11, 36, }, + { 11, 0, 0, 3, 11, 36, }, + { 0, 0, 0, 3, 12, 40, }, + { 2, 0, 0, 3, 12, 36, }, + { 1, 0, 0, 3, 12, 66, }, + { 3, 0, 0, 3, 12, 40, }, + { 4, 0, 0, 3, 12, 70, }, + { 5, 0, 0, 3, 12, 36, }, + { 6, 0, 0, 3, 12, 40, }, + { 7, 0, 0, 3, 12, 36, }, + { 8, 0, 0, 3, 12, 40, }, + { 9, 0, 0, 3, 12, 36, }, + { 10, 0, 0, 3, 12, 36, }, + { 11, 0, 0, 3, 12, 36, }, + { 0, 0, 0, 3, 13, 28, }, + { 2, 0, 0, 3, 13, 36, }, + { 1, 0, 0, 3, 13, 66, }, + { 3, 0, 0, 3, 13, 28, }, + { 4, 0, 0, 3, 13, 62, }, + { 5, 0, 0, 3, 13, 36, }, + { 6, 0, 0, 3, 13, 28, }, + { 7, 0, 0, 3, 13, 36, }, + { 8, 0, 0, 3, 13, 28, }, + { 9, 0, 0, 3, 13, 34, }, + { 10, 0, 0, 3, 13, 36, }, + { 11, 0, 0, 3, 13, 36, }, + { 0, 0, 0, 3, 14, 127, }, + { 2, 0, 0, 3, 14, 127, }, + { 1, 0, 0, 3, 14, 127, }, + { 3, 0, 0, 3, 14, 127, }, + { 4, 0, 0, 3, 14, 127, }, + { 5, 0, 0, 3, 14, 127, }, + { 6, 0, 0, 3, 14, 127, }, + { 7, 0, 0, 3, 14, 127, }, + { 8, 0, 0, 3, 14, 127, }, + { 9, 0, 0, 3, 14, 127, }, + { 10, 0, 0, 3, 14, 127, }, + { 11, 0, 0, 3, 14, 127, }, + { 0, 0, 1, 2, 1, 127, }, + { 2, 0, 1, 2, 1, 127, }, + { 1, 0, 1, 2, 1, 127, }, + { 3, 0, 1, 2, 1, 127, }, + { 4, 0, 1, 2, 1, 127, }, + { 5, 0, 1, 2, 1, 127, }, + { 6, 0, 1, 2, 1, 127, }, + { 7, 0, 1, 2, 1, 127, }, + { 8, 0, 1, 2, 1, 127, }, + { 9, 0, 1, 2, 1, 127, }, + { 10, 0, 1, 2, 1, 127, }, + { 11, 0, 1, 2, 1, 127, }, + { 0, 0, 1, 2, 2, 127, }, + { 2, 0, 1, 2, 2, 127, }, + { 1, 0, 1, 2, 2, 127, }, + { 3, 0, 1, 2, 2, 127, }, + { 4, 0, 1, 2, 2, 127, }, + { 5, 0, 1, 2, 2, 127, }, + { 6, 0, 1, 2, 2, 127, }, + { 7, 0, 1, 2, 2, 127, }, + { 8, 0, 1, 2, 2, 127, }, + { 9, 0, 1, 2, 2, 127, }, + { 10, 0, 1, 2, 2, 127, }, + { 11, 0, 1, 2, 2, 127, }, + { 0, 0, 1, 2, 3, 52, }, + { 2, 0, 1, 2, 3, 60, }, + { 1, 0, 1, 2, 3, 72, }, + { 3, 0, 1, 2, 3, 52, }, + { 4, 0, 1, 2, 3, 72, }, + { 5, 0, 1, 2, 3, 60, }, + { 6, 0, 1, 2, 3, 52, }, + { 7, 0, 1, 2, 3, 60, }, + { 8, 0, 1, 2, 3, 52, }, + { 9, 0, 1, 2, 3, 60, }, + { 10, 0, 1, 2, 3, 60, }, + { 11, 0, 1, 2, 3, 60, }, + { 0, 0, 1, 2, 4, 52, }, + { 2, 0, 1, 2, 4, 60, }, + { 1, 0, 1, 2, 4, 72, }, + { 3, 0, 1, 2, 4, 52, }, + { 4, 0, 1, 2, 4, 72, }, + { 5, 0, 1, 2, 4, 60, }, + { 6, 0, 1, 2, 4, 52, }, + { 7, 0, 1, 2, 4, 60, }, + { 8, 0, 1, 2, 4, 52, }, + { 9, 0, 1, 2, 4, 60, }, + { 10, 0, 1, 2, 4, 60, }, + { 11, 0, 1, 2, 4, 60, }, + { 0, 0, 1, 2, 5, 60, }, + { 2, 0, 1, 2, 5, 60, }, + { 1, 0, 1, 2, 5, 72, }, + { 3, 0, 1, 2, 5, 60, }, + { 4, 0, 1, 2, 5, 72, }, + { 5, 0, 1, 2, 5, 60, }, + { 6, 0, 1, 2, 5, 60, }, + { 7, 0, 1, 2, 5, 60, }, + { 8, 0, 1, 2, 5, 60, }, + { 9, 0, 1, 2, 5, 60, }, + { 10, 0, 1, 2, 5, 60, }, + { 11, 0, 1, 2, 5, 60, }, + { 0, 0, 1, 2, 6, 64, }, + { 2, 0, 1, 2, 6, 60, }, + { 1, 0, 1, 2, 6, 72, }, + { 3, 0, 1, 2, 6, 64, }, + { 4, 0, 1, 2, 6, 72, }, + { 5, 0, 1, 2, 6, 60, }, + { 6, 0, 1, 2, 6, 64, }, + { 7, 0, 1, 2, 6, 60, }, + { 8, 0, 1, 2, 6, 64, }, + { 9, 0, 1, 2, 6, 60, }, + { 10, 0, 1, 2, 6, 60, }, + { 11, 0, 1, 2, 6, 60, }, + { 0, 0, 1, 2, 7, 60, }, + { 2, 0, 1, 2, 7, 60, }, + { 1, 0, 1, 2, 7, 72, }, + { 3, 0, 1, 2, 7, 60, }, + { 4, 0, 1, 2, 7, 72, }, + { 5, 0, 1, 2, 7, 60, }, + { 6, 0, 1, 2, 7, 60, }, + { 7, 0, 1, 2, 7, 60, }, + { 8, 0, 1, 2, 7, 60, }, + { 9, 0, 1, 2, 7, 60, }, + { 10, 0, 1, 2, 7, 60, }, + { 11, 0, 1, 2, 7, 60, }, + { 0, 0, 1, 2, 8, 52, }, + { 2, 0, 1, 2, 8, 60, }, + { 1, 0, 1, 2, 8, 72, }, + { 3, 0, 1, 2, 8, 52, }, + { 4, 0, 1, 2, 8, 72, }, + { 5, 0, 1, 2, 8, 60, }, + { 6, 0, 1, 2, 8, 52, }, + { 7, 0, 1, 2, 8, 60, }, + { 8, 0, 1, 2, 8, 52, }, + { 9, 0, 1, 2, 8, 60, }, + { 10, 0, 1, 2, 8, 60, }, + { 11, 0, 1, 2, 8, 60, }, + { 0, 0, 1, 2, 9, 52, }, + { 2, 0, 1, 2, 9, 60, }, + { 1, 0, 1, 2, 9, 72, }, + { 3, 0, 1, 2, 9, 52, }, + { 4, 0, 1, 2, 9, 72, }, + { 5, 0, 1, 2, 9, 60, }, + { 6, 0, 1, 2, 9, 52, }, + { 7, 0, 1, 2, 9, 60, }, + { 8, 0, 1, 2, 9, 52, }, + { 9, 0, 1, 2, 9, 44, }, + { 10, 0, 1, 2, 9, 60, }, + { 11, 0, 1, 2, 9, 60, }, + { 0, 0, 1, 2, 10, 40, }, + { 2, 0, 1, 2, 10, 60, }, + { 1, 0, 1, 2, 10, 72, }, + { 3, 0, 1, 2, 10, 40, }, + { 4, 0, 1, 2, 10, 72, }, + { 5, 0, 1, 2, 10, 60, }, + { 6, 0, 1, 2, 10, 40, }, + { 7, 0, 1, 2, 10, 60, }, + { 8, 0, 1, 2, 10, 40, }, + { 9, 0, 1, 2, 10, 44, }, + { 10, 0, 1, 2, 10, 60, }, + { 11, 0, 1, 2, 10, 60, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 60, }, + { 1, 0, 1, 2, 11, 72, }, + { 3, 0, 1, 2, 11, 28, }, + { 4, 0, 1, 2, 11, 70, }, + { 5, 0, 1, 2, 11, 60, }, + { 6, 0, 1, 2, 11, 28, }, + { 7, 0, 1, 2, 11, 60, }, + { 8, 0, 1, 2, 11, 28, }, + { 9, 0, 1, 2, 11, 16, }, + { 10, 0, 1, 2, 11, 60, }, + { 11, 0, 1, 2, 11, 60, }, + { 0, 0, 1, 2, 12, 127, }, + { 2, 0, 1, 2, 12, 127, }, + { 1, 0, 1, 2, 12, 127, }, + { 3, 0, 1, 2, 12, 127, }, + { 4, 0, 1, 2, 12, 127, }, + { 5, 0, 1, 2, 12, 127, }, + { 6, 0, 1, 2, 12, 127, }, + { 7, 0, 1, 2, 12, 127, }, + { 8, 0, 1, 2, 12, 127, }, + { 9, 0, 1, 2, 12, 127, }, + { 10, 0, 1, 2, 12, 127, }, + { 11, 0, 1, 2, 12, 127, }, + { 0, 0, 1, 2, 13, 127, }, + { 2, 0, 1, 2, 13, 127, }, + { 1, 0, 1, 2, 13, 127, }, + { 3, 0, 1, 2, 13, 127, }, + { 4, 0, 1, 2, 13, 127, }, + { 5, 0, 1, 2, 13, 127, }, + { 6, 0, 1, 2, 13, 127, }, + { 7, 0, 1, 2, 13, 127, }, + { 8, 0, 1, 2, 13, 127, }, + { 9, 0, 1, 2, 13, 127, }, + { 10, 0, 1, 2, 13, 127, }, + { 11, 0, 1, 2, 13, 127, }, + { 0, 0, 1, 2, 14, 127, }, + { 2, 0, 1, 2, 14, 127, }, + { 1, 0, 1, 2, 14, 127, }, + { 3, 0, 1, 2, 14, 127, }, + { 4, 0, 1, 2, 14, 127, }, + { 5, 0, 1, 2, 14, 127, }, + { 6, 0, 1, 2, 14, 127, }, + { 7, 0, 1, 2, 14, 127, }, + { 8, 0, 1, 2, 14, 127, }, + { 9, 0, 1, 2, 14, 127, }, + { 10, 0, 1, 2, 14, 127, }, + { 11, 0, 1, 2, 14, 127, }, + { 0, 0, 1, 3, 1, 127, }, + { 2, 0, 1, 3, 1, 127, }, + { 1, 0, 1, 3, 1, 127, }, + { 3, 0, 1, 3, 1, 127, }, + { 4, 0, 1, 3, 1, 127, }, + { 5, 0, 1, 3, 1, 127, }, + { 6, 0, 1, 3, 1, 127, }, + { 7, 0, 1, 3, 1, 127, }, + { 8, 0, 1, 3, 1, 127, }, + { 9, 0, 1, 3, 1, 127, }, + { 10, 0, 1, 3, 1, 127, }, + { 11, 0, 1, 3, 1, 127, }, + { 0, 0, 1, 3, 2, 127, }, + { 2, 0, 1, 3, 2, 127, }, + { 1, 0, 1, 3, 2, 127, }, + { 3, 0, 1, 3, 2, 127, }, + { 4, 0, 1, 3, 2, 127, }, + { 5, 0, 1, 3, 2, 127, }, + { 6, 0, 1, 3, 2, 127, }, + { 7, 0, 1, 3, 2, 127, }, + { 8, 0, 1, 3, 2, 127, }, + { 9, 0, 1, 3, 2, 127, }, + { 10, 0, 1, 3, 2, 127, }, + { 11, 0, 1, 3, 2, 127, }, + { 0, 0, 1, 3, 3, 48, }, + { 2, 0, 1, 3, 3, 36, }, + { 1, 0, 1, 3, 3, 66, }, + { 3, 0, 1, 3, 3, 48, }, + { 4, 0, 1, 3, 3, 66, }, + { 5, 0, 1, 3, 3, 36, }, + { 6, 0, 1, 3, 3, 48, }, + { 7, 0, 1, 3, 3, 36, }, + { 8, 0, 1, 3, 3, 48, }, + { 9, 0, 1, 3, 3, 36, }, + { 10, 0, 1, 3, 3, 36, }, + { 11, 0, 1, 3, 3, 36, }, + { 0, 0, 1, 3, 4, 48, }, + { 2, 0, 1, 3, 4, 36, }, + { 1, 0, 1, 3, 4, 66, }, + { 3, 0, 1, 3, 4, 48, }, + { 4, 0, 1, 3, 4, 70, }, + { 5, 0, 1, 3, 4, 36, }, + { 6, 0, 1, 3, 4, 48, }, + { 7, 0, 1, 3, 4, 36, }, + { 8, 0, 1, 3, 4, 48, }, + { 9, 0, 1, 3, 4, 36, }, + { 10, 0, 1, 3, 4, 36, }, + { 11, 0, 1, 3, 4, 36, }, + { 0, 0, 1, 3, 5, 60, }, + { 2, 0, 1, 3, 5, 36, }, + { 1, 0, 1, 3, 5, 66, }, + { 3, 0, 1, 3, 5, 60, }, + { 4, 0, 1, 3, 5, 70, }, + { 5, 0, 1, 3, 5, 36, }, + { 6, 0, 1, 3, 5, 60, }, + { 7, 0, 1, 3, 5, 36, }, + { 8, 0, 1, 3, 5, 60, }, + { 9, 0, 1, 3, 5, 36, }, + { 10, 0, 1, 3, 5, 36, }, + { 11, 0, 1, 3, 5, 36, }, + { 0, 0, 1, 3, 6, 64, }, + { 2, 0, 1, 3, 6, 36, }, + { 1, 0, 1, 3, 6, 66, }, + { 3, 0, 1, 3, 6, 64, }, + { 4, 0, 1, 3, 6, 70, }, + { 5, 0, 1, 3, 6, 36, }, + { 6, 0, 1, 3, 6, 64, }, + { 7, 0, 1, 3, 6, 36, }, + { 8, 0, 1, 3, 6, 64, }, + { 9, 0, 1, 3, 6, 36, }, + { 10, 0, 1, 3, 6, 36, }, + { 11, 0, 1, 3, 6, 36, }, + { 0, 0, 1, 3, 7, 60, }, + { 2, 0, 1, 3, 7, 36, }, + { 1, 0, 1, 3, 7, 66, }, + { 3, 0, 1, 3, 7, 60, }, + { 4, 0, 1, 3, 7, 70, }, + { 5, 0, 1, 3, 7, 36, }, + { 6, 0, 1, 3, 7, 60, }, + { 7, 0, 1, 3, 7, 36, }, + { 8, 0, 1, 3, 7, 60, }, + { 9, 0, 1, 3, 7, 36, }, + { 10, 0, 1, 3, 7, 36, }, + { 11, 0, 1, 3, 7, 36, }, + { 0, 0, 1, 3, 8, 52, }, + { 2, 0, 1, 3, 8, 36, }, + { 1, 0, 1, 3, 8, 66, }, + { 3, 0, 1, 3, 8, 52, }, + { 4, 0, 1, 3, 8, 70, }, + { 5, 0, 1, 3, 8, 36, }, + { 6, 0, 1, 3, 8, 52, }, + { 7, 0, 1, 3, 8, 36, }, + { 8, 0, 1, 3, 8, 52, }, + { 9, 0, 1, 3, 8, 36, }, + { 10, 0, 1, 3, 8, 36, }, + { 11, 0, 1, 3, 8, 36, }, + { 0, 0, 1, 3, 9, 52, }, + { 2, 0, 1, 3, 9, 36, }, + { 1, 0, 1, 3, 9, 66, }, + { 3, 0, 1, 3, 9, 52, }, + { 4, 0, 1, 3, 9, 70, }, + { 5, 0, 1, 3, 9, 36, }, + { 6, 0, 1, 3, 9, 52, }, + { 7, 0, 1, 3, 9, 36, }, + { 8, 0, 1, 3, 9, 52, }, + { 9, 0, 1, 3, 9, 36, }, + { 10, 0, 1, 3, 9, 36, }, + { 11, 0, 1, 3, 9, 36, }, + { 0, 0, 1, 3, 10, 40, }, + { 2, 0, 1, 3, 10, 36, }, + { 1, 0, 1, 3, 10, 66, }, + { 3, 0, 1, 3, 10, 40, }, + { 4, 0, 1, 3, 10, 70, }, + { 5, 0, 1, 3, 10, 36, }, + { 6, 0, 1, 3, 10, 40, }, + { 7, 0, 1, 3, 10, 36, }, + { 8, 0, 1, 3, 10, 40, }, + { 9, 0, 1, 3, 10, 36, }, + { 10, 0, 1, 3, 10, 36, }, + { 11, 0, 1, 3, 10, 36, }, + { 0, 0, 1, 3, 11, 26, }, + { 2, 0, 1, 3, 11, 36, }, + { 1, 0, 1, 3, 11, 66, }, + { 3, 0, 1, 3, 11, 26, }, + { 4, 0, 1, 3, 11, 66, }, + { 5, 0, 1, 3, 11, 36, }, + { 6, 0, 1, 3, 11, 26, }, + { 7, 0, 1, 3, 11, 36, }, + { 8, 0, 1, 3, 11, 26, }, + { 9, 0, 1, 3, 11, 16, }, + { 10, 0, 1, 3, 11, 36, }, + { 11, 0, 1, 3, 11, 36, }, + { 0, 0, 1, 3, 12, 127, }, + { 2, 0, 1, 3, 12, 127, }, + { 1, 0, 1, 3, 12, 127, }, + { 3, 0, 1, 3, 12, 127, }, + { 4, 0, 1, 3, 12, 127, }, + { 5, 0, 1, 3, 12, 127, }, + { 6, 0, 1, 3, 12, 127, }, + { 7, 0, 1, 3, 12, 127, }, + { 8, 0, 1, 3, 12, 127, }, + { 9, 0, 1, 3, 12, 127, }, + { 10, 0, 1, 3, 12, 127, }, + { 11, 0, 1, 3, 12, 127, }, + { 0, 0, 1, 3, 13, 127, }, + { 2, 0, 1, 3, 13, 127, }, + { 1, 0, 1, 3, 13, 127, }, + { 3, 0, 1, 3, 13, 127, }, + { 4, 0, 1, 3, 13, 127, }, + { 5, 0, 1, 3, 13, 127, }, + { 6, 0, 1, 3, 13, 127, }, + { 7, 0, 1, 3, 13, 127, }, + { 8, 0, 1, 3, 13, 127, }, + { 9, 0, 1, 3, 13, 127, }, + { 10, 0, 1, 3, 13, 127, }, + { 11, 0, 1, 3, 13, 127, }, + { 0, 0, 1, 3, 14, 127, }, + { 2, 0, 1, 3, 14, 127, }, + { 1, 0, 1, 3, 14, 127, }, + { 3, 0, 1, 3, 14, 127, }, + { 4, 0, 1, 3, 14, 127, }, + { 5, 0, 1, 3, 14, 127, }, + { 6, 0, 1, 3, 14, 127, }, + { 7, 0, 1, 3, 14, 127, }, + { 8, 0, 1, 3, 14, 127, }, + { 9, 0, 1, 3, 14, 127, }, + { 10, 0, 1, 3, 14, 127, }, + { 11, 0, 1, 3, 14, 127, }, + { 0, 1, 0, 1, 36, 74, }, + { 2, 1, 0, 1, 36, 62, }, + { 1, 1, 0, 1, 36, 60, }, + { 3, 1, 0, 1, 36, 62, }, + { 4, 1, 0, 1, 36, 76, }, + { 5, 1, 0, 1, 36, 62, }, + { 6, 1, 0, 1, 36, 64, }, + { 7, 1, 0, 1, 36, 54, }, + { 8, 1, 0, 1, 36, 62, }, + { 9, 1, 0, 1, 36, 62, }, + { 10, 1, 0, 1, 36, 62, }, + { 11, 1, 0, 1, 36, 62, }, + { 0, 1, 0, 1, 40, 76, }, + { 2, 1, 0, 1, 40, 62, }, + { 1, 1, 0, 1, 40, 62, }, + { 3, 1, 0, 1, 40, 62, }, + { 4, 1, 0, 1, 40, 76, }, + { 5, 1, 0, 1, 40, 62, }, + { 6, 1, 0, 1, 40, 64, }, + { 7, 1, 0, 1, 40, 54, }, + { 8, 1, 0, 1, 40, 62, }, + { 9, 1, 0, 1, 40, 62, }, + { 10, 1, 0, 1, 40, 62, }, + { 11, 1, 0, 1, 40, 62, }, + { 0, 1, 0, 1, 44, 76, }, + { 2, 1, 0, 1, 44, 62, }, + { 1, 1, 0, 1, 44, 62, }, + { 3, 1, 0, 1, 44, 62, }, + { 4, 1, 0, 1, 44, 76, }, + { 5, 1, 0, 1, 44, 62, }, + { 6, 1, 0, 1, 44, 64, }, + { 7, 1, 0, 1, 44, 54, }, + { 8, 1, 0, 1, 44, 62, }, + { 9, 1, 0, 1, 44, 62, }, + { 10, 1, 0, 1, 44, 62, }, + { 11, 1, 0, 1, 44, 62, }, + { 0, 1, 0, 1, 48, 76, }, + { 2, 1, 0, 1, 48, 62, }, + { 1, 1, 0, 1, 48, 62, }, + { 3, 1, 0, 1, 48, 62, }, + { 4, 1, 0, 1, 48, 54, }, + { 5, 1, 0, 1, 48, 62, }, + { 6, 1, 0, 1, 48, 64, }, + { 7, 1, 0, 1, 48, 54, }, + { 8, 1, 0, 1, 48, 62, }, + { 9, 1, 0, 1, 48, 62, }, + { 10, 1, 0, 1, 48, 62, }, + { 11, 1, 0, 1, 48, 62, }, + { 0, 1, 0, 1, 52, 76, }, + { 2, 1, 0, 1, 52, 62, }, + { 1, 1, 0, 1, 52, 62, }, + { 3, 1, 0, 1, 52, 64, }, + { 4, 1, 0, 1, 52, 76, }, + { 5, 1, 0, 1, 52, 62, }, + { 6, 1, 0, 1, 52, 76, }, + { 7, 1, 0, 1, 52, 54, }, + { 8, 1, 0, 1, 52, 76, }, + { 9, 1, 0, 1, 52, 62, }, + { 10, 1, 0, 1, 52, 62, }, + { 11, 1, 0, 1, 52, 62, }, + { 0, 1, 0, 1, 56, 76, }, + { 2, 1, 0, 1, 56, 62, }, + { 1, 1, 0, 1, 56, 62, }, + { 3, 1, 0, 1, 56, 64, }, + { 4, 1, 0, 1, 56, 76, }, + { 5, 1, 0, 1, 56, 62, }, + { 6, 1, 0, 1, 56, 76, }, + { 7, 1, 0, 1, 56, 54, }, + { 8, 1, 0, 1, 56, 76, }, + { 9, 1, 0, 1, 56, 62, }, + { 10, 1, 0, 1, 56, 62, }, + { 11, 1, 0, 1, 56, 62, }, + { 0, 1, 0, 1, 60, 76, }, + { 2, 1, 0, 1, 60, 62, }, + { 1, 1, 0, 1, 60, 62, }, + { 3, 1, 0, 1, 60, 64, }, + { 4, 1, 0, 1, 60, 76, }, + { 5, 1, 0, 1, 60, 62, }, + { 6, 1, 0, 1, 60, 76, }, + { 7, 1, 0, 1, 60, 54, }, + { 8, 1, 0, 1, 60, 76, }, + { 9, 1, 0, 1, 60, 62, }, + { 10, 1, 0, 1, 60, 62, }, + { 11, 1, 0, 1, 60, 62, }, + { 0, 1, 0, 1, 64, 74, }, + { 2, 1, 0, 1, 64, 62, }, + { 1, 1, 0, 1, 64, 60, }, + { 3, 1, 0, 1, 64, 64, }, + { 4, 1, 0, 1, 64, 76, }, + { 5, 1, 0, 1, 64, 62, }, + { 6, 1, 0, 1, 64, 74, }, + { 7, 1, 0, 1, 64, 54, }, + { 8, 1, 0, 1, 64, 74, }, + { 9, 1, 0, 1, 64, 62, }, + { 10, 1, 0, 1, 64, 62, }, + { 11, 1, 0, 1, 64, 62, }, + { 0, 1, 0, 1, 100, 72, }, + { 2, 1, 0, 1, 100, 62, }, + { 1, 1, 0, 1, 100, 76, }, + { 3, 1, 0, 1, 100, 72, }, + { 4, 1, 0, 1, 100, 76, }, + { 5, 1, 0, 1, 100, 62, }, + { 6, 1, 0, 1, 100, 72, }, + { 7, 1, 0, 1, 100, 54, }, + { 8, 1, 0, 1, 100, 72, }, + { 9, 1, 0, 1, 100, 127, }, + { 10, 1, 0, 1, 100, 54, }, + { 11, 1, 0, 1, 100, 62, }, + { 0, 1, 0, 1, 104, 76, }, + { 2, 1, 0, 1, 104, 62, }, + { 1, 1, 0, 1, 104, 76, }, + { 3, 1, 0, 1, 104, 76, }, + { 4, 1, 0, 1, 104, 76, }, + { 5, 1, 0, 1, 104, 62, }, + { 6, 1, 0, 1, 104, 76, }, + { 7, 1, 0, 1, 104, 54, }, + { 8, 1, 0, 1, 104, 76, }, + { 9, 1, 0, 1, 104, 127, }, + { 10, 1, 0, 1, 104, 54, }, + { 11, 1, 0, 1, 104, 62, }, + { 0, 1, 0, 1, 108, 76, }, + { 2, 1, 0, 1, 108, 62, }, + { 1, 1, 0, 1, 108, 76, }, + { 3, 1, 0, 1, 108, 76, }, + { 4, 1, 0, 1, 108, 76, }, + { 5, 1, 0, 1, 108, 62, }, + { 6, 1, 0, 1, 108, 76, }, + { 7, 1, 0, 1, 108, 54, }, + { 8, 1, 0, 1, 108, 76, }, + { 9, 1, 0, 1, 108, 127, }, + { 10, 1, 0, 1, 108, 54, }, + { 11, 1, 0, 1, 108, 62, }, + { 0, 1, 0, 1, 112, 76, }, + { 2, 1, 0, 1, 112, 62, }, + { 1, 1, 0, 1, 112, 76, }, + { 3, 1, 0, 1, 112, 76, }, + { 4, 1, 0, 1, 112, 76, }, + { 5, 1, 0, 1, 112, 62, }, + { 6, 1, 0, 1, 112, 76, }, + { 7, 1, 0, 1, 112, 54, }, + { 8, 1, 0, 1, 112, 76, }, + { 9, 1, 0, 1, 112, 127, }, + { 10, 1, 0, 1, 112, 54, }, + { 11, 1, 0, 1, 112, 62, }, + { 0, 1, 0, 1, 116, 76, }, + { 2, 1, 0, 1, 116, 62, }, + { 1, 1, 0, 1, 116, 76, }, + { 3, 1, 0, 1, 116, 76, }, + { 4, 1, 0, 1, 116, 76, }, + { 5, 1, 0, 1, 116, 62, }, + { 6, 1, 0, 1, 116, 76, }, + { 7, 1, 0, 1, 116, 54, }, + { 8, 1, 0, 1, 116, 76, }, + { 9, 1, 0, 1, 116, 127, }, + { 10, 1, 0, 1, 116, 54, }, + { 11, 1, 0, 1, 116, 62, }, + { 0, 1, 0, 1, 120, 76, }, + { 2, 1, 0, 1, 120, 62, }, + { 1, 1, 0, 1, 120, 76, }, + { 3, 1, 0, 1, 120, 127, }, + { 4, 1, 0, 1, 120, 76, }, + { 5, 1, 0, 1, 120, 127, }, + { 6, 1, 0, 1, 120, 76, }, + { 7, 1, 0, 1, 120, 54, }, + { 8, 1, 0, 1, 120, 76, }, + { 9, 1, 0, 1, 120, 127, }, + { 10, 1, 0, 1, 120, 54, }, + { 11, 1, 0, 1, 120, 62, }, + { 0, 1, 0, 1, 124, 76, }, + { 2, 1, 0, 1, 124, 62, }, + { 1, 1, 0, 1, 124, 76, }, + { 3, 1, 0, 1, 124, 127, }, + { 4, 1, 0, 1, 124, 76, }, + { 5, 1, 0, 1, 124, 127, }, + { 6, 1, 0, 1, 124, 76, }, + { 7, 1, 0, 1, 124, 54, }, + { 8, 1, 0, 1, 124, 76, }, + { 9, 1, 0, 1, 124, 127, }, + { 10, 1, 0, 1, 124, 54, }, + { 11, 1, 0, 1, 124, 62, }, + { 0, 1, 0, 1, 128, 76, }, + { 2, 1, 0, 1, 128, 62, }, + { 1, 1, 0, 1, 128, 76, }, + { 3, 1, 0, 1, 128, 127, }, + { 4, 1, 0, 1, 128, 76, }, + { 5, 1, 0, 1, 128, 127, }, + { 6, 1, 0, 1, 128, 76, }, + { 7, 1, 0, 1, 128, 54, }, + { 8, 1, 0, 1, 128, 76, }, + { 9, 1, 0, 1, 128, 127, }, + { 10, 1, 0, 1, 128, 54, }, + { 11, 1, 0, 1, 128, 62, }, + { 0, 1, 0, 1, 132, 76, }, + { 2, 1, 0, 1, 132, 62, }, + { 1, 1, 0, 1, 132, 76, }, + { 3, 1, 0, 1, 132, 76, }, + { 4, 1, 0, 1, 132, 76, }, + { 5, 1, 0, 1, 132, 62, }, + { 6, 1, 0, 1, 132, 76, }, + { 7, 1, 0, 1, 132, 54, }, + { 8, 1, 0, 1, 132, 76, }, + { 9, 1, 0, 1, 132, 127, }, + { 10, 1, 0, 1, 132, 54, }, + { 11, 1, 0, 1, 132, 62, }, + { 0, 1, 0, 1, 136, 76, }, + { 2, 1, 0, 1, 136, 62, }, + { 1, 1, 0, 1, 136, 76, }, + { 3, 1, 0, 1, 136, 76, }, + { 4, 1, 0, 1, 136, 76, }, + { 5, 1, 0, 1, 136, 62, }, + { 6, 1, 0, 1, 136, 76, }, + { 7, 1, 0, 1, 136, 54, }, + { 8, 1, 0, 1, 136, 76, }, + { 9, 1, 0, 1, 136, 127, }, + { 10, 1, 0, 1, 136, 54, }, + { 11, 1, 0, 1, 136, 62, }, + { 0, 1, 0, 1, 140, 72, }, + { 2, 1, 0, 1, 140, 62, }, + { 1, 1, 0, 1, 140, 76, }, + { 3, 1, 0, 1, 140, 72, }, + { 4, 1, 0, 1, 140, 76, }, + { 5, 1, 0, 1, 140, 62, }, + { 6, 1, 0, 1, 140, 72, }, + { 7, 1, 0, 1, 140, 54, }, + { 8, 1, 0, 1, 140, 72, }, + { 9, 1, 0, 1, 140, 127, }, + { 10, 1, 0, 1, 140, 54, }, + { 11, 1, 0, 1, 140, 62, }, + { 0, 1, 0, 1, 144, 76, }, + { 2, 1, 0, 1, 144, 127, }, + { 1, 1, 0, 1, 144, 127, }, + { 3, 1, 0, 1, 144, 76, }, + { 4, 1, 0, 1, 144, 76, }, + { 5, 1, 0, 1, 144, 127, }, + { 6, 1, 0, 1, 144, 76, }, + { 7, 1, 0, 1, 144, 127, }, + { 8, 1, 0, 1, 144, 76, }, + { 9, 1, 0, 1, 144, 127, }, + { 10, 1, 0, 1, 144, 127, }, + { 11, 1, 0, 1, 144, 76, }, + { 0, 1, 0, 1, 149, 76, }, + { 2, 1, 0, 1, 149, 28, }, + { 1, 1, 0, 1, 149, 127, }, + { 3, 1, 0, 1, 149, 76, }, + { 4, 1, 0, 1, 149, 74, }, + { 5, 1, 0, 1, 149, 76, }, + { 6, 1, 0, 1, 149, 76, }, + { 7, 1, 0, 1, 149, 54, }, + { 8, 1, 0, 1, 149, 76, }, + { 9, 1, 0, 1, 149, 28, }, + { 10, 1, 0, 1, 149, 28, }, + { 11, 1, 0, 1, 149, 58, }, + { 0, 1, 0, 1, 153, 76, }, + { 2, 1, 0, 1, 153, 28, }, + { 1, 1, 0, 1, 153, 127, }, + { 3, 1, 0, 1, 153, 76, }, + { 4, 1, 0, 1, 153, 74, }, + { 5, 1, 0, 1, 153, 76, }, + { 6, 1, 0, 1, 153, 76, }, + { 7, 1, 0, 1, 153, 54, }, + { 8, 1, 0, 1, 153, 76, }, + { 9, 1, 0, 1, 153, 28, }, + { 10, 1, 0, 1, 153, 28, }, + { 11, 1, 0, 1, 153, 58, }, + { 0, 1, 0, 1, 157, 76, }, + { 2, 1, 0, 1, 157, 28, }, + { 1, 1, 0, 1, 157, 127, }, + { 3, 1, 0, 1, 157, 76, }, + { 4, 1, 0, 1, 157, 74, }, + { 5, 1, 0, 1, 157, 76, }, + { 6, 1, 0, 1, 157, 76, }, + { 7, 1, 0, 1, 157, 54, }, + { 8, 1, 0, 1, 157, 76, }, + { 9, 1, 0, 1, 157, 28, }, + { 10, 1, 0, 1, 157, 28, }, + { 11, 1, 0, 1, 157, 58, }, + { 0, 1, 0, 1, 161, 76, }, + { 2, 1, 0, 1, 161, 28, }, + { 1, 1, 0, 1, 161, 127, }, + { 3, 1, 0, 1, 161, 76, }, + { 4, 1, 0, 1, 161, 74, }, + { 5, 1, 0, 1, 161, 76, }, + { 6, 1, 0, 1, 161, 76, }, + { 7, 1, 0, 1, 161, 54, }, + { 8, 1, 0, 1, 161, 76, }, + { 9, 1, 0, 1, 161, 28, }, + { 10, 1, 0, 1, 161, 28, }, + { 11, 1, 0, 1, 161, 58, }, + { 0, 1, 0, 1, 165, 76, }, + { 2, 1, 0, 1, 165, 28, }, + { 1, 1, 0, 1, 165, 127, }, + { 3, 1, 0, 1, 165, 76, }, + { 4, 1, 0, 1, 165, 74, }, + { 5, 1, 0, 1, 165, 76, }, + { 6, 1, 0, 1, 165, 76, }, + { 7, 1, 0, 1, 165, 54, }, + { 8, 1, 0, 1, 165, 76, }, + { 9, 1, 0, 1, 165, 28, }, + { 10, 1, 0, 1, 165, 28, }, + { 11, 1, 0, 1, 165, 58, }, + { 0, 1, 0, 2, 36, 72, }, + { 2, 1, 0, 2, 36, 62, }, + { 1, 1, 0, 2, 36, 62, }, + { 3, 1, 0, 2, 36, 62, }, + { 4, 1, 0, 2, 36, 76, }, + { 5, 1, 0, 2, 36, 62, }, + { 6, 1, 0, 2, 36, 64, }, + { 7, 1, 0, 2, 36, 54, }, + { 8, 1, 0, 2, 36, 62, }, + { 9, 1, 0, 2, 36, 62, }, + { 10, 1, 0, 2, 36, 62, }, + { 11, 1, 0, 2, 36, 62, }, + { 0, 1, 0, 2, 40, 76, }, + { 2, 1, 0, 2, 40, 62, }, + { 1, 1, 0, 2, 40, 62, }, + { 3, 1, 0, 2, 40, 62, }, + { 4, 1, 0, 2, 40, 76, }, + { 5, 1, 0, 2, 40, 62, }, + { 6, 1, 0, 2, 40, 64, }, + { 7, 1, 0, 2, 40, 54, }, + { 8, 1, 0, 2, 40, 62, }, + { 9, 1, 0, 2, 40, 62, }, + { 10, 1, 0, 2, 40, 62, }, + { 11, 1, 0, 2, 40, 62, }, + { 0, 1, 0, 2, 44, 76, }, + { 2, 1, 0, 2, 44, 62, }, + { 1, 1, 0, 2, 44, 62, }, + { 3, 1, 0, 2, 44, 62, }, + { 4, 1, 0, 2, 44, 76, }, + { 5, 1, 0, 2, 44, 62, }, + { 6, 1, 0, 2, 44, 64, }, + { 7, 1, 0, 2, 44, 54, }, + { 8, 1, 0, 2, 44, 62, }, + { 9, 1, 0, 2, 44, 62, }, + { 10, 1, 0, 2, 44, 62, }, + { 11, 1, 0, 2, 44, 62, }, + { 0, 1, 0, 2, 48, 76, }, + { 2, 1, 0, 2, 48, 62, }, + { 1, 1, 0, 2, 48, 62, }, + { 3, 1, 0, 2, 48, 62, }, + { 4, 1, 0, 2, 48, 54, }, + { 5, 1, 0, 2, 48, 62, }, + { 6, 1, 0, 2, 48, 64, }, + { 7, 1, 0, 2, 48, 54, }, + { 8, 1, 0, 2, 48, 62, }, + { 9, 1, 0, 2, 48, 62, }, + { 10, 1, 0, 2, 48, 62, }, + { 11, 1, 0, 2, 48, 62, }, + { 0, 1, 0, 2, 52, 76, }, + { 2, 1, 0, 2, 52, 62, }, + { 1, 1, 0, 2, 52, 62, }, + { 3, 1, 0, 2, 52, 64, }, + { 4, 1, 0, 2, 52, 76, }, + { 5, 1, 0, 2, 52, 62, }, + { 6, 1, 0, 2, 52, 76, }, + { 7, 1, 0, 2, 52, 54, }, + { 8, 1, 0, 2, 52, 76, }, + { 9, 1, 0, 2, 52, 62, }, + { 10, 1, 0, 2, 52, 62, }, + { 11, 1, 0, 2, 52, 62, }, + { 0, 1, 0, 2, 56, 76, }, + { 2, 1, 0, 2, 56, 62, }, + { 1, 1, 0, 2, 56, 62, }, + { 3, 1, 0, 2, 56, 64, }, + { 4, 1, 0, 2, 56, 76, }, + { 5, 1, 0, 2, 56, 62, }, + { 6, 1, 0, 2, 56, 76, }, + { 7, 1, 0, 2, 56, 54, }, + { 8, 1, 0, 2, 56, 76, }, + { 9, 1, 0, 2, 56, 62, }, + { 10, 1, 0, 2, 56, 62, }, + { 11, 1, 0, 2, 56, 62, }, + { 0, 1, 0, 2, 60, 76, }, + { 2, 1, 0, 2, 60, 62, }, + { 1, 1, 0, 2, 60, 62, }, + { 3, 1, 0, 2, 60, 64, }, + { 4, 1, 0, 2, 60, 76, }, + { 5, 1, 0, 2, 60, 62, }, + { 6, 1, 0, 2, 60, 76, }, + { 7, 1, 0, 2, 60, 54, }, + { 8, 1, 0, 2, 60, 76, }, + { 9, 1, 0, 2, 60, 62, }, + { 10, 1, 0, 2, 60, 62, }, + { 11, 1, 0, 2, 60, 62, }, + { 0, 1, 0, 2, 64, 74, }, + { 2, 1, 0, 2, 64, 62, }, + { 1, 1, 0, 2, 64, 60, }, + { 3, 1, 0, 2, 64, 64, }, + { 4, 1, 0, 2, 64, 74, }, + { 5, 1, 0, 2, 64, 62, }, + { 6, 1, 0, 2, 64, 74, }, + { 7, 1, 0, 2, 64, 54, }, + { 8, 1, 0, 2, 64, 74, }, + { 9, 1, 0, 2, 64, 62, }, + { 10, 1, 0, 2, 64, 62, }, + { 11, 1, 0, 2, 64, 62, }, + { 0, 1, 0, 2, 100, 70, }, + { 2, 1, 0, 2, 100, 62, }, + { 1, 1, 0, 2, 100, 76, }, + { 3, 1, 0, 2, 100, 70, }, + { 4, 1, 0, 2, 100, 76, }, + { 5, 1, 0, 2, 100, 62, }, + { 6, 1, 0, 2, 100, 70, }, + { 7, 1, 0, 2, 100, 54, }, + { 8, 1, 0, 2, 100, 70, }, + { 9, 1, 0, 2, 100, 127, }, + { 10, 1, 0, 2, 100, 54, }, + { 11, 1, 0, 2, 100, 62, }, + { 0, 1, 0, 2, 104, 76, }, + { 2, 1, 0, 2, 104, 62, }, + { 1, 1, 0, 2, 104, 76, }, + { 3, 1, 0, 2, 104, 76, }, + { 4, 1, 0, 2, 104, 76, }, + { 5, 1, 0, 2, 104, 62, }, + { 6, 1, 0, 2, 104, 76, }, + { 7, 1, 0, 2, 104, 54, }, + { 8, 1, 0, 2, 104, 76, }, + { 9, 1, 0, 2, 104, 127, }, + { 10, 1, 0, 2, 104, 54, }, + { 11, 1, 0, 2, 104, 62, }, + { 0, 1, 0, 2, 108, 76, }, + { 2, 1, 0, 2, 108, 62, }, + { 1, 1, 0, 2, 108, 76, }, + { 3, 1, 0, 2, 108, 76, }, + { 4, 1, 0, 2, 108, 76, }, + { 5, 1, 0, 2, 108, 62, }, + { 6, 1, 0, 2, 108, 76, }, + { 7, 1, 0, 2, 108, 54, }, + { 8, 1, 0, 2, 108, 76, }, + { 9, 1, 0, 2, 108, 127, }, + { 10, 1, 0, 2, 108, 54, }, + { 11, 1, 0, 2, 108, 62, }, + { 0, 1, 0, 2, 112, 76, }, + { 2, 1, 0, 2, 112, 62, }, + { 1, 1, 0, 2, 112, 76, }, + { 3, 1, 0, 2, 112, 76, }, + { 4, 1, 0, 2, 112, 76, }, + { 5, 1, 0, 2, 112, 62, }, + { 6, 1, 0, 2, 112, 76, }, + { 7, 1, 0, 2, 112, 54, }, + { 8, 1, 0, 2, 112, 76, }, + { 9, 1, 0, 2, 112, 127, }, + { 10, 1, 0, 2, 112, 54, }, + { 11, 1, 0, 2, 112, 62, }, + { 0, 1, 0, 2, 116, 76, }, + { 2, 1, 0, 2, 116, 62, }, + { 1, 1, 0, 2, 116, 76, }, + { 3, 1, 0, 2, 116, 76, }, + { 4, 1, 0, 2, 116, 76, }, + { 5, 1, 0, 2, 116, 62, }, + { 6, 1, 0, 2, 116, 76, }, + { 7, 1, 0, 2, 116, 54, }, + { 8, 1, 0, 2, 116, 76, }, + { 9, 1, 0, 2, 116, 127, }, + { 10, 1, 0, 2, 116, 54, }, + { 11, 1, 0, 2, 116, 62, }, + { 0, 1, 0, 2, 120, 76, }, + { 2, 1, 0, 2, 120, 62, }, + { 1, 1, 0, 2, 120, 76, }, + { 3, 1, 0, 2, 120, 127, }, + { 4, 1, 0, 2, 120, 76, }, + { 5, 1, 0, 2, 120, 127, }, + { 6, 1, 0, 2, 120, 76, }, + { 7, 1, 0, 2, 120, 54, }, + { 8, 1, 0, 2, 120, 76, }, + { 9, 1, 0, 2, 120, 127, }, + { 10, 1, 0, 2, 120, 54, }, + { 11, 1, 0, 2, 120, 62, }, + { 0, 1, 0, 2, 124, 76, }, + { 2, 1, 0, 2, 124, 62, }, + { 1, 1, 0, 2, 124, 76, }, + { 3, 1, 0, 2, 124, 127, }, + { 4, 1, 0, 2, 124, 76, }, + { 5, 1, 0, 2, 124, 127, }, + { 6, 1, 0, 2, 124, 76, }, + { 7, 1, 0, 2, 124, 54, }, + { 8, 1, 0, 2, 124, 76, }, + { 9, 1, 0, 2, 124, 127, }, + { 10, 1, 0, 2, 124, 54, }, + { 11, 1, 0, 2, 124, 62, }, + { 0, 1, 0, 2, 128, 76, }, + { 2, 1, 0, 2, 128, 62, }, + { 1, 1, 0, 2, 128, 76, }, + { 3, 1, 0, 2, 128, 127, }, + { 4, 1, 0, 2, 128, 76, }, + { 5, 1, 0, 2, 128, 127, }, + { 6, 1, 0, 2, 128, 76, }, + { 7, 1, 0, 2, 128, 54, }, + { 8, 1, 0, 2, 128, 76, }, + { 9, 1, 0, 2, 128, 127, }, + { 10, 1, 0, 2, 128, 54, }, + { 11, 1, 0, 2, 128, 62, }, + { 0, 1, 0, 2, 132, 76, }, + { 2, 1, 0, 2, 132, 62, }, + { 1, 1, 0, 2, 132, 76, }, + { 3, 1, 0, 2, 132, 76, }, + { 4, 1, 0, 2, 132, 76, }, + { 5, 1, 0, 2, 132, 62, }, + { 6, 1, 0, 2, 132, 76, }, + { 7, 1, 0, 2, 132, 54, }, + { 8, 1, 0, 2, 132, 76, }, + { 9, 1, 0, 2, 132, 127, }, + { 10, 1, 0, 2, 132, 54, }, + { 11, 1, 0, 2, 132, 62, }, + { 0, 1, 0, 2, 136, 76, }, + { 2, 1, 0, 2, 136, 62, }, + { 1, 1, 0, 2, 136, 76, }, + { 3, 1, 0, 2, 136, 76, }, + { 4, 1, 0, 2, 136, 76, }, + { 5, 1, 0, 2, 136, 62, }, + { 6, 1, 0, 2, 136, 76, }, + { 7, 1, 0, 2, 136, 54, }, + { 8, 1, 0, 2, 136, 76, }, + { 9, 1, 0, 2, 136, 127, }, + { 10, 1, 0, 2, 136, 54, }, + { 11, 1, 0, 2, 136, 62, }, + { 0, 1, 0, 2, 140, 70, }, + { 2, 1, 0, 2, 140, 62, }, + { 1, 1, 0, 2, 140, 76, }, + { 3, 1, 0, 2, 140, 70, }, + { 4, 1, 0, 2, 140, 76, }, + { 5, 1, 0, 2, 140, 62, }, + { 6, 1, 0, 2, 140, 70, }, + { 7, 1, 0, 2, 140, 54, }, + { 8, 1, 0, 2, 140, 70, }, + { 9, 1, 0, 2, 140, 127, }, + { 10, 1, 0, 2, 140, 54, }, + { 11, 1, 0, 2, 140, 62, }, + { 0, 1, 0, 2, 144, 76, }, + { 2, 1, 0, 2, 144, 127, }, + { 1, 1, 0, 2, 144, 127, }, + { 3, 1, 0, 2, 144, 76, }, + { 4, 1, 0, 2, 144, 76, }, + { 5, 1, 0, 2, 144, 127, }, + { 6, 1, 0, 2, 144, 76, }, + { 7, 1, 0, 2, 144, 127, }, + { 8, 1, 0, 2, 144, 76, }, + { 9, 1, 0, 2, 144, 127, }, + { 10, 1, 0, 2, 144, 127, }, + { 11, 1, 0, 2, 144, 76, }, + { 0, 1, 0, 2, 149, 76, }, + { 2, 1, 0, 2, 149, 28, }, + { 1, 1, 0, 2, 149, 127, }, + { 3, 1, 0, 2, 149, 76, }, + { 4, 1, 0, 2, 149, 74, }, + { 5, 1, 0, 2, 149, 76, }, + { 6, 1, 0, 2, 149, 76, }, + { 7, 1, 0, 2, 149, 54, }, + { 8, 1, 0, 2, 149, 76, }, + { 9, 1, 0, 2, 149, 28, }, + { 10, 1, 0, 2, 149, 28, }, + { 11, 1, 0, 2, 149, 60, }, + { 0, 1, 0, 2, 153, 76, }, + { 2, 1, 0, 2, 153, 28, }, + { 1, 1, 0, 2, 153, 127, }, + { 3, 1, 0, 2, 153, 76, }, + { 4, 1, 0, 2, 153, 74, }, + { 5, 1, 0, 2, 153, 76, }, + { 6, 1, 0, 2, 153, 76, }, + { 7, 1, 0, 2, 153, 54, }, + { 8, 1, 0, 2, 153, 76, }, + { 9, 1, 0, 2, 153, 28, }, + { 10, 1, 0, 2, 153, 28, }, + { 11, 1, 0, 2, 153, 60, }, + { 0, 1, 0, 2, 157, 76, }, + { 2, 1, 0, 2, 157, 28, }, + { 1, 1, 0, 2, 157, 127, }, + { 3, 1, 0, 2, 157, 76, }, + { 4, 1, 0, 2, 157, 74, }, + { 5, 1, 0, 2, 157, 76, }, + { 6, 1, 0, 2, 157, 76, }, + { 7, 1, 0, 2, 157, 54, }, + { 8, 1, 0, 2, 157, 76, }, + { 9, 1, 0, 2, 157, 28, }, + { 10, 1, 0, 2, 157, 28, }, + { 11, 1, 0, 2, 157, 60, }, + { 0, 1, 0, 2, 161, 76, }, + { 2, 1, 0, 2, 161, 28, }, + { 1, 1, 0, 2, 161, 127, }, + { 3, 1, 0, 2, 161, 76, }, + { 4, 1, 0, 2, 161, 74, }, + { 5, 1, 0, 2, 161, 76, }, + { 6, 1, 0, 2, 161, 76, }, + { 7, 1, 0, 2, 161, 54, }, + { 8, 1, 0, 2, 161, 76, }, + { 9, 1, 0, 2, 161, 28, }, + { 10, 1, 0, 2, 161, 28, }, + { 11, 1, 0, 2, 161, 60, }, + { 0, 1, 0, 2, 165, 76, }, + { 2, 1, 0, 2, 165, 28, }, + { 1, 1, 0, 2, 165, 127, }, + { 3, 1, 0, 2, 165, 76, }, + { 4, 1, 0, 2, 165, 74, }, + { 5, 1, 0, 2, 165, 76, }, + { 6, 1, 0, 2, 165, 76, }, + { 7, 1, 0, 2, 165, 54, }, + { 8, 1, 0, 2, 165, 76, }, + { 9, 1, 0, 2, 165, 28, }, + { 10, 1, 0, 2, 165, 28, }, + { 11, 1, 0, 2, 165, 60, }, + { 0, 1, 0, 3, 36, 68, }, + { 2, 1, 0, 3, 36, 38, }, + { 1, 1, 0, 3, 36, 50, }, + { 3, 1, 0, 3, 36, 38, }, + { 4, 1, 0, 3, 36, 66, }, + { 5, 1, 0, 3, 36, 38, }, + { 6, 1, 0, 3, 36, 52, }, + { 7, 1, 0, 3, 36, 30, }, + { 8, 1, 0, 3, 36, 50, }, + { 9, 1, 0, 3, 36, 38, }, + { 10, 1, 0, 3, 36, 38, }, + { 11, 1, 0, 3, 36, 38, }, + { 0, 1, 0, 3, 40, 68, }, + { 2, 1, 0, 3, 40, 38, }, + { 1, 1, 0, 3, 40, 50, }, + { 3, 1, 0, 3, 40, 38, }, + { 4, 1, 0, 3, 40, 66, }, + { 5, 1, 0, 3, 40, 38, }, + { 6, 1, 0, 3, 40, 52, }, + { 7, 1, 0, 3, 40, 30, }, + { 8, 1, 0, 3, 40, 50, }, + { 9, 1, 0, 3, 40, 38, }, + { 10, 1, 0, 3, 40, 38, }, + { 11, 1, 0, 3, 40, 38, }, + { 0, 1, 0, 3, 44, 68, }, + { 2, 1, 0, 3, 44, 38, }, + { 1, 1, 0, 3, 44, 50, }, + { 3, 1, 0, 3, 44, 38, }, + { 4, 1, 0, 3, 44, 66, }, + { 5, 1, 0, 3, 44, 38, }, + { 6, 1, 0, 3, 44, 52, }, + { 7, 1, 0, 3, 44, 30, }, + { 8, 1, 0, 3, 44, 50, }, + { 9, 1, 0, 3, 44, 38, }, + { 10, 1, 0, 3, 44, 38, }, + { 11, 1, 0, 3, 44, 38, }, + { 0, 1, 0, 3, 48, 68, }, + { 2, 1, 0, 3, 48, 38, }, + { 1, 1, 0, 3, 48, 50, }, + { 3, 1, 0, 3, 48, 38, }, + { 4, 1, 0, 3, 48, 36, }, + { 5, 1, 0, 3, 48, 38, }, + { 6, 1, 0, 3, 48, 52, }, + { 7, 1, 0, 3, 48, 30, }, + { 8, 1, 0, 3, 48, 50, }, + { 9, 1, 0, 3, 48, 38, }, + { 10, 1, 0, 3, 48, 38, }, + { 11, 1, 0, 3, 48, 38, }, + { 0, 1, 0, 3, 52, 68, }, + { 2, 1, 0, 3, 52, 38, }, + { 1, 1, 0, 3, 52, 50, }, + { 3, 1, 0, 3, 52, 40, }, + { 4, 1, 0, 3, 52, 66, }, + { 5, 1, 0, 3, 52, 38, }, + { 6, 1, 0, 3, 52, 68, }, + { 7, 1, 0, 3, 52, 30, }, + { 8, 1, 0, 3, 52, 68, }, + { 9, 1, 0, 3, 52, 38, }, + { 10, 1, 0, 3, 52, 38, }, + { 11, 1, 0, 3, 52, 38, }, + { 0, 1, 0, 3, 56, 68, }, + { 2, 1, 0, 3, 56, 38, }, + { 1, 1, 0, 3, 56, 50, }, + { 3, 1, 0, 3, 56, 40, }, + { 4, 1, 0, 3, 56, 66, }, + { 5, 1, 0, 3, 56, 38, }, + { 6, 1, 0, 3, 56, 68, }, + { 7, 1, 0, 3, 56, 30, }, + { 8, 1, 0, 3, 56, 68, }, + { 9, 1, 0, 3, 56, 38, }, + { 10, 1, 0, 3, 56, 38, }, + { 11, 1, 0, 3, 56, 38, }, + { 0, 1, 0, 3, 60, 66, }, + { 2, 1, 0, 3, 60, 38, }, + { 1, 1, 0, 3, 60, 50, }, + { 3, 1, 0, 3, 60, 40, }, + { 4, 1, 0, 3, 60, 66, }, + { 5, 1, 0, 3, 60, 38, }, + { 6, 1, 0, 3, 60, 66, }, + { 7, 1, 0, 3, 60, 30, }, + { 8, 1, 0, 3, 60, 66, }, + { 9, 1, 0, 3, 60, 38, }, + { 10, 1, 0, 3, 60, 38, }, + { 11, 1, 0, 3, 60, 38, }, + { 0, 1, 0, 3, 64, 68, }, + { 2, 1, 0, 3, 64, 38, }, + { 1, 1, 0, 3, 64, 50, }, + { 3, 1, 0, 3, 64, 40, }, + { 4, 1, 0, 3, 64, 66, }, + { 5, 1, 0, 3, 64, 38, }, + { 6, 1, 0, 3, 64, 68, }, + { 7, 1, 0, 3, 64, 30, }, + { 8, 1, 0, 3, 64, 68, }, + { 9, 1, 0, 3, 64, 38, }, + { 10, 1, 0, 3, 64, 38, }, + { 11, 1, 0, 3, 64, 38, }, + { 0, 1, 0, 3, 100, 60, }, + { 2, 1, 0, 3, 100, 38, }, + { 1, 1, 0, 3, 100, 70, }, + { 3, 1, 0, 3, 100, 60, }, + { 4, 1, 0, 3, 100, 64, }, + { 5, 1, 0, 3, 100, 38, }, + { 6, 1, 0, 3, 100, 60, }, + { 7, 1, 0, 3, 100, 30, }, + { 8, 1, 0, 3, 100, 60, }, + { 9, 1, 0, 3, 100, 127, }, + { 10, 1, 0, 3, 100, 30, }, + { 11, 1, 0, 3, 100, 38, }, + { 0, 1, 0, 3, 104, 68, }, + { 2, 1, 0, 3, 104, 38, }, + { 1, 1, 0, 3, 104, 70, }, + { 3, 1, 0, 3, 104, 68, }, + { 4, 1, 0, 3, 104, 64, }, + { 5, 1, 0, 3, 104, 38, }, + { 6, 1, 0, 3, 104, 68, }, + { 7, 1, 0, 3, 104, 30, }, + { 8, 1, 0, 3, 104, 68, }, + { 9, 1, 0, 3, 104, 127, }, + { 10, 1, 0, 3, 104, 30, }, + { 11, 1, 0, 3, 104, 38, }, + { 0, 1, 0, 3, 108, 68, }, + { 2, 1, 0, 3, 108, 38, }, + { 1, 1, 0, 3, 108, 70, }, + { 3, 1, 0, 3, 108, 68, }, + { 4, 1, 0, 3, 108, 64, }, + { 5, 1, 0, 3, 108, 38, }, + { 6, 1, 0, 3, 108, 68, }, + { 7, 1, 0, 3, 108, 30, }, + { 8, 1, 0, 3, 108, 68, }, + { 9, 1, 0, 3, 108, 127, }, + { 10, 1, 0, 3, 108, 30, }, + { 11, 1, 0, 3, 108, 38, }, + { 0, 1, 0, 3, 112, 68, }, + { 2, 1, 0, 3, 112, 38, }, + { 1, 1, 0, 3, 112, 70, }, + { 3, 1, 0, 3, 112, 68, }, + { 4, 1, 0, 3, 112, 64, }, + { 5, 1, 0, 3, 112, 38, }, + { 6, 1, 0, 3, 112, 68, }, + { 7, 1, 0, 3, 112, 30, }, + { 8, 1, 0, 3, 112, 68, }, + { 9, 1, 0, 3, 112, 127, }, + { 10, 1, 0, 3, 112, 30, }, + { 11, 1, 0, 3, 112, 38, }, + { 0, 1, 0, 3, 116, 68, }, + { 2, 1, 0, 3, 116, 38, }, + { 1, 1, 0, 3, 116, 70, }, + { 3, 1, 0, 3, 116, 68, }, + { 4, 1, 0, 3, 116, 64, }, + { 5, 1, 0, 3, 116, 38, }, + { 6, 1, 0, 3, 116, 68, }, + { 7, 1, 0, 3, 116, 30, }, + { 8, 1, 0, 3, 116, 68, }, + { 9, 1, 0, 3, 116, 127, }, + { 10, 1, 0, 3, 116, 30, }, + { 11, 1, 0, 3, 116, 38, }, + { 0, 1, 0, 3, 120, 68, }, + { 2, 1, 0, 3, 120, 38, }, + { 1, 1, 0, 3, 120, 70, }, + { 3, 1, 0, 3, 120, 127, }, + { 4, 1, 0, 3, 120, 64, }, + { 5, 1, 0, 3, 120, 127, }, + { 6, 1, 0, 3, 120, 68, }, + { 7, 1, 0, 3, 120, 30, }, + { 8, 1, 0, 3, 120, 68, }, + { 9, 1, 0, 3, 120, 127, }, + { 10, 1, 0, 3, 120, 30, }, + { 11, 1, 0, 3, 120, 38, }, + { 0, 1, 0, 3, 124, 68, }, + { 2, 1, 0, 3, 124, 38, }, + { 1, 1, 0, 3, 124, 70, }, + { 3, 1, 0, 3, 124, 127, }, + { 4, 1, 0, 3, 124, 64, }, + { 5, 1, 0, 3, 124, 127, }, + { 6, 1, 0, 3, 124, 68, }, + { 7, 1, 0, 3, 124, 30, }, + { 8, 1, 0, 3, 124, 68, }, + { 9, 1, 0, 3, 124, 127, }, + { 10, 1, 0, 3, 124, 30, }, + { 11, 1, 0, 3, 124, 38, }, + { 0, 1, 0, 3, 128, 68, }, + { 2, 1, 0, 3, 128, 38, }, + { 1, 1, 0, 3, 128, 70, }, + { 3, 1, 0, 3, 128, 127, }, + { 4, 1, 0, 3, 128, 64, }, + { 5, 1, 0, 3, 128, 127, }, + { 6, 1, 0, 3, 128, 68, }, + { 7, 1, 0, 3, 128, 30, }, + { 8, 1, 0, 3, 128, 68, }, + { 9, 1, 0, 3, 128, 127, }, + { 10, 1, 0, 3, 128, 30, }, + { 11, 1, 0, 3, 128, 38, }, + { 0, 1, 0, 3, 132, 68, }, + { 2, 1, 0, 3, 132, 38, }, + { 1, 1, 0, 3, 132, 70, }, + { 3, 1, 0, 3, 132, 68, }, + { 4, 1, 0, 3, 132, 64, }, + { 5, 1, 0, 3, 132, 38, }, + { 6, 1, 0, 3, 132, 68, }, + { 7, 1, 0, 3, 132, 30, }, + { 8, 1, 0, 3, 132, 68, }, + { 9, 1, 0, 3, 132, 127, }, + { 10, 1, 0, 3, 132, 30, }, + { 11, 1, 0, 3, 132, 38, }, + { 0, 1, 0, 3, 136, 68, }, + { 2, 1, 0, 3, 136, 38, }, + { 1, 1, 0, 3, 136, 70, }, + { 3, 1, 0, 3, 136, 68, }, + { 4, 1, 0, 3, 136, 64, }, + { 5, 1, 0, 3, 136, 38, }, + { 6, 1, 0, 3, 136, 68, }, + { 7, 1, 0, 3, 136, 30, }, + { 8, 1, 0, 3, 136, 68, }, + { 9, 1, 0, 3, 136, 127, }, + { 10, 1, 0, 3, 136, 30, }, + { 11, 1, 0, 3, 136, 38, }, + { 0, 1, 0, 3, 140, 60, }, + { 2, 1, 0, 3, 140, 38, }, + { 1, 1, 0, 3, 140, 70, }, + { 3, 1, 0, 3, 140, 60, }, + { 4, 1, 0, 3, 140, 64, }, + { 5, 1, 0, 3, 140, 38, }, + { 6, 1, 0, 3, 140, 60, }, + { 7, 1, 0, 3, 140, 30, }, + { 8, 1, 0, 3, 140, 60, }, + { 9, 1, 0, 3, 140, 127, }, + { 10, 1, 0, 3, 140, 30, }, + { 11, 1, 0, 3, 140, 38, }, + { 0, 1, 0, 3, 144, 68, }, + { 2, 1, 0, 3, 144, 127, }, + { 1, 1, 0, 3, 144, 127, }, + { 3, 1, 0, 3, 144, 68, }, + { 4, 1, 0, 3, 144, 64, }, + { 5, 1, 0, 3, 144, 127, }, + { 6, 1, 0, 3, 144, 68, }, + { 7, 1, 0, 3, 144, 127, }, + { 8, 1, 0, 3, 144, 68, }, + { 9, 1, 0, 3, 144, 127, }, + { 10, 1, 0, 3, 144, 127, }, + { 11, 1, 0, 3, 144, 60, }, + { 0, 1, 0, 3, 149, 76, }, + { 2, 1, 0, 3, 149, 4, }, + { 1, 1, 0, 3, 149, 127, }, + { 3, 1, 0, 3, 149, 76, }, + { 4, 1, 0, 3, 149, 60, }, + { 5, 1, 0, 3, 149, 76, }, + { 6, 1, 0, 3, 149, 76, }, + { 7, 1, 0, 3, 149, 30, }, + { 8, 1, 0, 3, 149, 72, }, + { 9, 1, 0, 3, 149, 4, }, + { 10, 1, 0, 3, 149, 4, }, + { 11, 1, 0, 3, 149, 36, }, + { 0, 1, 0, 3, 153, 76, }, + { 2, 1, 0, 3, 153, 4, }, + { 1, 1, 0, 3, 153, 127, }, + { 3, 1, 0, 3, 153, 76, }, + { 4, 1, 0, 3, 153, 60, }, + { 5, 1, 0, 3, 153, 76, }, + { 6, 1, 0, 3, 153, 76, }, + { 7, 1, 0, 3, 153, 30, }, + { 8, 1, 0, 3, 153, 76, }, + { 9, 1, 0, 3, 153, 4, }, + { 10, 1, 0, 3, 153, 4, }, + { 11, 1, 0, 3, 153, 36, }, + { 0, 1, 0, 3, 157, 76, }, + { 2, 1, 0, 3, 157, 4, }, + { 1, 1, 0, 3, 157, 127, }, + { 3, 1, 0, 3, 157, 76, }, + { 4, 1, 0, 3, 157, 60, }, + { 5, 1, 0, 3, 157, 76, }, + { 6, 1, 0, 3, 157, 76, }, + { 7, 1, 0, 3, 157, 30, }, + { 8, 1, 0, 3, 157, 76, }, + { 9, 1, 0, 3, 157, 4, }, + { 10, 1, 0, 3, 157, 4, }, + { 11, 1, 0, 3, 157, 36, }, + { 0, 1, 0, 3, 161, 76, }, + { 2, 1, 0, 3, 161, 4, }, + { 1, 1, 0, 3, 161, 127, }, + { 3, 1, 0, 3, 161, 76, }, + { 4, 1, 0, 3, 161, 60, }, + { 5, 1, 0, 3, 161, 76, }, + { 6, 1, 0, 3, 161, 76, }, + { 7, 1, 0, 3, 161, 30, }, + { 8, 1, 0, 3, 161, 76, }, + { 9, 1, 0, 3, 161, 4, }, + { 10, 1, 0, 3, 161, 4, }, + { 11, 1, 0, 3, 161, 36, }, + { 0, 1, 0, 3, 165, 76, }, + { 2, 1, 0, 3, 165, 4, }, + { 1, 1, 0, 3, 165, 127, }, + { 3, 1, 0, 3, 165, 76, }, + { 4, 1, 0, 3, 165, 60, }, + { 5, 1, 0, 3, 165, 76, }, + { 6, 1, 0, 3, 165, 76, }, + { 7, 1, 0, 3, 165, 30, }, + { 8, 1, 0, 3, 165, 76, }, + { 9, 1, 0, 3, 165, 4, }, + { 10, 1, 0, 3, 165, 4, }, + { 11, 1, 0, 3, 165, 36, }, + { 0, 1, 1, 2, 38, 66, }, + { 2, 1, 1, 2, 38, 64, }, + { 1, 1, 1, 2, 38, 62, }, + { 3, 1, 1, 2, 38, 64, }, + { 4, 1, 1, 2, 38, 72, }, + { 5, 1, 1, 2, 38, 64, }, + { 6, 1, 1, 2, 38, 64, }, + { 7, 1, 1, 2, 38, 54, }, + { 8, 1, 1, 2, 38, 62, }, + { 9, 1, 1, 2, 38, 64, }, + { 10, 1, 1, 2, 38, 64, }, + { 11, 1, 1, 2, 38, 64, }, + { 0, 1, 1, 2, 46, 72, }, + { 2, 1, 1, 2, 46, 64, }, + { 1, 1, 1, 2, 46, 62, }, + { 3, 1, 1, 2, 46, 64, }, + { 4, 1, 1, 2, 46, 60, }, + { 5, 1, 1, 2, 46, 64, }, + { 6, 1, 1, 2, 46, 64, }, + { 7, 1, 1, 2, 46, 54, }, + { 8, 1, 1, 2, 46, 62, }, + { 9, 1, 1, 2, 46, 64, }, + { 10, 1, 1, 2, 46, 64, }, + { 11, 1, 1, 2, 46, 64, }, + { 0, 1, 1, 2, 54, 72, }, + { 2, 1, 1, 2, 54, 64, }, + { 1, 1, 1, 2, 54, 62, }, + { 3, 1, 1, 2, 54, 64, }, + { 4, 1, 1, 2, 54, 72, }, + { 5, 1, 1, 2, 54, 64, }, + { 6, 1, 1, 2, 54, 72, }, + { 7, 1, 1, 2, 54, 54, }, + { 8, 1, 1, 2, 54, 72, }, + { 9, 1, 1, 2, 54, 64, }, + { 10, 1, 1, 2, 54, 64, }, + { 11, 1, 1, 2, 54, 64, }, + { 0, 1, 1, 2, 62, 64, }, + { 2, 1, 1, 2, 62, 64, }, + { 1, 1, 1, 2, 62, 62, }, + { 3, 1, 1, 2, 62, 64, }, + { 4, 1, 1, 2, 62, 70, }, + { 5, 1, 1, 2, 62, 64, }, + { 6, 1, 1, 2, 62, 64, }, + { 7, 1, 1, 2, 62, 54, }, + { 8, 1, 1, 2, 62, 64, }, + { 9, 1, 1, 2, 62, 64, }, + { 10, 1, 1, 2, 62, 64, }, + { 11, 1, 1, 2, 62, 64, }, + { 0, 1, 1, 2, 102, 58, }, + { 2, 1, 1, 2, 102, 64, }, + { 1, 1, 1, 2, 102, 72, }, + { 3, 1, 1, 2, 102, 58, }, + { 4, 1, 1, 2, 102, 72, }, + { 5, 1, 1, 2, 102, 64, }, + { 6, 1, 1, 2, 102, 58, }, + { 7, 1, 1, 2, 102, 54, }, + { 8, 1, 1, 2, 102, 58, }, + { 9, 1, 1, 2, 102, 127, }, + { 10, 1, 1, 2, 102, 54, }, + { 11, 1, 1, 2, 102, 64, }, + { 0, 1, 1, 2, 110, 72, }, + { 2, 1, 1, 2, 110, 64, }, + { 1, 1, 1, 2, 110, 72, }, + { 3, 1, 1, 2, 110, 72, }, + { 4, 1, 1, 2, 110, 72, }, + { 5, 1, 1, 2, 110, 64, }, + { 6, 1, 1, 2, 110, 72, }, + { 7, 1, 1, 2, 110, 54, }, + { 8, 1, 1, 2, 110, 72, }, + { 9, 1, 1, 2, 110, 127, }, + { 10, 1, 1, 2, 110, 54, }, + { 11, 1, 1, 2, 110, 64, }, + { 0, 1, 1, 2, 118, 72, }, + { 2, 1, 1, 2, 118, 64, }, + { 1, 1, 1, 2, 118, 72, }, + { 3, 1, 1, 2, 118, 127, }, + { 4, 1, 1, 2, 118, 72, }, + { 5, 1, 1, 2, 118, 127, }, + { 6, 1, 1, 2, 118, 72, }, + { 7, 1, 1, 2, 118, 54, }, + { 8, 1, 1, 2, 118, 72, }, + { 9, 1, 1, 2, 118, 127, }, + { 10, 1, 1, 2, 118, 54, }, + { 11, 1, 1, 2, 118, 64, }, + { 0, 1, 1, 2, 126, 72, }, + { 2, 1, 1, 2, 126, 64, }, + { 1, 1, 1, 2, 126, 72, }, + { 3, 1, 1, 2, 126, 127, }, + { 4, 1, 1, 2, 126, 72, }, + { 5, 1, 1, 2, 126, 127, }, + { 6, 1, 1, 2, 126, 72, }, + { 7, 1, 1, 2, 126, 54, }, + { 8, 1, 1, 2, 126, 72, }, + { 9, 1, 1, 2, 126, 127, }, + { 10, 1, 1, 2, 126, 54, }, + { 11, 1, 1, 2, 126, 64, }, + { 0, 1, 1, 2, 134, 72, }, + { 2, 1, 1, 2, 134, 64, }, + { 1, 1, 1, 2, 134, 72, }, + { 3, 1, 1, 2, 134, 72, }, + { 4, 1, 1, 2, 134, 72, }, + { 5, 1, 1, 2, 134, 64, }, + { 6, 1, 1, 2, 134, 72, }, + { 7, 1, 1, 2, 134, 54, }, + { 8, 1, 1, 2, 134, 72, }, + { 9, 1, 1, 2, 134, 127, }, + { 10, 1, 1, 2, 134, 54, }, + { 11, 1, 1, 2, 134, 64, }, + { 0, 1, 1, 2, 142, 72, }, + { 2, 1, 1, 2, 142, 127, }, + { 1, 1, 1, 2, 142, 127, }, + { 3, 1, 1, 2, 142, 72, }, + { 4, 1, 1, 2, 142, 72, }, + { 5, 1, 1, 2, 142, 127, }, + { 6, 1, 1, 2, 142, 72, }, + { 7, 1, 1, 2, 142, 127, }, + { 8, 1, 1, 2, 142, 72, }, + { 9, 1, 1, 2, 142, 127, }, + { 10, 1, 1, 2, 142, 127, }, + { 11, 1, 1, 2, 142, 72, }, + { 0, 1, 1, 2, 151, 72, }, + { 2, 1, 1, 2, 151, 28, }, + { 1, 1, 1, 2, 151, 127, }, + { 3, 1, 1, 2, 151, 72, }, + { 4, 1, 1, 2, 151, 72, }, + { 5, 1, 1, 2, 151, 72, }, + { 6, 1, 1, 2, 151, 72, }, + { 7, 1, 1, 2, 151, 54, }, + { 8, 1, 1, 2, 151, 72, }, + { 9, 1, 1, 2, 151, 28, }, + { 10, 1, 1, 2, 151, 28, }, + { 11, 1, 1, 2, 151, 64, }, + { 0, 1, 1, 2, 159, 72, }, + { 2, 1, 1, 2, 159, 28, }, + { 1, 1, 1, 2, 159, 127, }, + { 3, 1, 1, 2, 159, 72, }, + { 4, 1, 1, 2, 159, 72, }, + { 5, 1, 1, 2, 159, 72, }, + { 6, 1, 1, 2, 159, 72, }, + { 7, 1, 1, 2, 159, 54, }, + { 8, 1, 1, 2, 159, 72, }, + { 9, 1, 1, 2, 159, 28, }, + { 10, 1, 1, 2, 159, 28, }, + { 11, 1, 1, 2, 159, 64, }, + { 0, 1, 1, 3, 38, 60, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 50, }, + { 3, 1, 1, 3, 38, 40, }, + { 4, 1, 1, 3, 38, 62, }, + { 5, 1, 1, 3, 38, 40, }, + { 6, 1, 1, 3, 38, 52, }, + { 7, 1, 1, 3, 38, 30, }, + { 8, 1, 1, 3, 38, 50, }, + { 9, 1, 1, 3, 38, 40, }, + { 10, 1, 1, 3, 38, 40, }, + { 11, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 68, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 50, }, + { 3, 1, 1, 3, 46, 40, }, + { 4, 1, 1, 3, 46, 46, }, + { 5, 1, 1, 3, 46, 40, }, + { 6, 1, 1, 3, 46, 52, }, + { 7, 1, 1, 3, 46, 30, }, + { 8, 1, 1, 3, 46, 50, }, + { 9, 1, 1, 3, 46, 40, }, + { 10, 1, 1, 3, 46, 40, }, + { 11, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 68, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 50, }, + { 3, 1, 1, 3, 54, 40, }, + { 4, 1, 1, 3, 54, 62, }, + { 5, 1, 1, 3, 54, 40, }, + { 6, 1, 1, 3, 54, 68, }, + { 7, 1, 1, 3, 54, 30, }, + { 8, 1, 1, 3, 54, 68, }, + { 9, 1, 1, 3, 54, 40, }, + { 10, 1, 1, 3, 54, 40, }, + { 11, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 58, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 48, }, + { 3, 1, 1, 3, 62, 40, }, + { 4, 1, 1, 3, 62, 58, }, + { 5, 1, 1, 3, 62, 40, }, + { 6, 1, 1, 3, 62, 58, }, + { 7, 1, 1, 3, 62, 30, }, + { 8, 1, 1, 3, 62, 58, }, + { 9, 1, 1, 3, 62, 40, }, + { 10, 1, 1, 3, 62, 40, }, + { 11, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 54, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 70, }, + { 3, 1, 1, 3, 102, 54, }, + { 4, 1, 1, 3, 102, 64, }, + { 5, 1, 1, 3, 102, 40, }, + { 6, 1, 1, 3, 102, 54, }, + { 7, 1, 1, 3, 102, 30, }, + { 8, 1, 1, 3, 102, 54, }, + { 9, 1, 1, 3, 102, 127, }, + { 10, 1, 1, 3, 102, 30, }, + { 11, 1, 1, 3, 102, 40, }, + { 0, 1, 1, 3, 110, 68, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 70, }, + { 3, 1, 1, 3, 110, 68, }, + { 4, 1, 1, 3, 110, 64, }, + { 5, 1, 1, 3, 110, 40, }, + { 6, 1, 1, 3, 110, 68, }, + { 7, 1, 1, 3, 110, 30, }, + { 8, 1, 1, 3, 110, 68, }, + { 9, 1, 1, 3, 110, 127, }, + { 10, 1, 1, 3, 110, 30, }, + { 11, 1, 1, 3, 110, 40, }, + { 0, 1, 1, 3, 118, 68, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 70, }, + { 3, 1, 1, 3, 118, 127, }, + { 4, 1, 1, 3, 118, 64, }, + { 5, 1, 1, 3, 118, 127, }, + { 6, 1, 1, 3, 118, 68, }, + { 7, 1, 1, 3, 118, 30, }, + { 8, 1, 1, 3, 118, 68, }, + { 9, 1, 1, 3, 118, 127, }, + { 10, 1, 1, 3, 118, 30, }, + { 11, 1, 1, 3, 118, 40, }, + { 0, 1, 1, 3, 126, 68, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 70, }, + { 3, 1, 1, 3, 126, 127, }, + { 4, 1, 1, 3, 126, 64, }, + { 5, 1, 1, 3, 126, 127, }, + { 6, 1, 1, 3, 126, 68, }, + { 7, 1, 1, 3, 126, 30, }, + { 8, 1, 1, 3, 126, 68, }, + { 9, 1, 1, 3, 126, 127, }, + { 10, 1, 1, 3, 126, 30, }, + { 11, 1, 1, 3, 126, 40, }, + { 0, 1, 1, 3, 134, 68, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 70, }, + { 3, 1, 1, 3, 134, 68, }, + { 4, 1, 1, 3, 134, 64, }, + { 5, 1, 1, 3, 134, 40, }, + { 6, 1, 1, 3, 134, 68, }, + { 7, 1, 1, 3, 134, 30, }, + { 8, 1, 1, 3, 134, 68, }, + { 9, 1, 1, 3, 134, 127, }, + { 10, 1, 1, 3, 134, 30, }, + { 11, 1, 1, 3, 134, 40, }, + { 0, 1, 1, 3, 142, 68, }, + { 2, 1, 1, 3, 142, 127, }, + { 1, 1, 1, 3, 142, 127, }, + { 3, 1, 1, 3, 142, 68, }, + { 4, 1, 1, 3, 142, 64, }, + { 5, 1, 1, 3, 142, 127, }, + { 6, 1, 1, 3, 142, 68, }, + { 7, 1, 1, 3, 142, 127, }, + { 8, 1, 1, 3, 142, 68, }, + { 9, 1, 1, 3, 142, 127, }, + { 10, 1, 1, 3, 142, 127, }, + { 11, 1, 1, 3, 142, 62, }, + { 0, 1, 1, 3, 151, 72, }, + { 2, 1, 1, 3, 151, 4, }, + { 1, 1, 1, 3, 151, 127, }, + { 3, 1, 1, 3, 151, 72, }, + { 4, 1, 1, 3, 151, 66, }, + { 5, 1, 1, 3, 151, 72, }, + { 6, 1, 1, 3, 151, 72, }, + { 7, 1, 1, 3, 151, 30, }, + { 8, 1, 1, 3, 151, 68, }, + { 9, 1, 1, 3, 151, 4, }, + { 10, 1, 1, 3, 151, 4, }, + { 11, 1, 1, 3, 151, 40, }, + { 0, 1, 1, 3, 159, 72, }, + { 2, 1, 1, 3, 159, 4, }, + { 1, 1, 1, 3, 159, 127, }, + { 3, 1, 1, 3, 159, 72, }, + { 4, 1, 1, 3, 159, 66, }, + { 5, 1, 1, 3, 159, 72, }, + { 6, 1, 1, 3, 159, 72, }, + { 7, 1, 1, 3, 159, 30, }, + { 8, 1, 1, 3, 159, 72, }, + { 9, 1, 1, 3, 159, 4, }, + { 10, 1, 1, 3, 159, 4, }, + { 11, 1, 1, 3, 159, 40, }, + { 0, 1, 2, 4, 42, 64, }, + { 2, 1, 2, 4, 42, 64, }, + { 1, 1, 2, 4, 42, 64, }, + { 3, 1, 2, 4, 42, 64, }, + { 4, 1, 2, 4, 42, 68, }, + { 5, 1, 2, 4, 42, 64, }, + { 6, 1, 2, 4, 42, 64, }, + { 7, 1, 2, 4, 42, 54, }, + { 8, 1, 2, 4, 42, 62, }, + { 9, 1, 2, 4, 42, 64, }, + { 10, 1, 2, 4, 42, 64, }, + { 11, 1, 2, 4, 42, 64, }, + { 0, 1, 2, 4, 58, 62, }, + { 2, 1, 2, 4, 58, 64, }, + { 1, 1, 2, 4, 58, 64, }, + { 3, 1, 2, 4, 58, 62, }, + { 4, 1, 2, 4, 58, 64, }, + { 5, 1, 2, 4, 58, 64, }, + { 6, 1, 2, 4, 58, 62, }, + { 7, 1, 2, 4, 58, 54, }, + { 8, 1, 2, 4, 58, 62, }, + { 9, 1, 2, 4, 58, 64, }, + { 10, 1, 2, 4, 58, 64, }, + { 11, 1, 2, 4, 58, 64, }, + { 0, 1, 2, 4, 106, 58, }, + { 2, 1, 2, 4, 106, 64, }, + { 1, 1, 2, 4, 106, 72, }, + { 3, 1, 2, 4, 106, 58, }, + { 4, 1, 2, 4, 106, 66, }, + { 5, 1, 2, 4, 106, 64, }, + { 6, 1, 2, 4, 106, 58, }, + { 7, 1, 2, 4, 106, 54, }, + { 8, 1, 2, 4, 106, 58, }, + { 9, 1, 2, 4, 106, 127, }, + { 10, 1, 2, 4, 106, 54, }, + { 11, 1, 2, 4, 106, 64, }, + { 0, 1, 2, 4, 122, 72, }, + { 2, 1, 2, 4, 122, 64, }, + { 1, 1, 2, 4, 122, 72, }, + { 3, 1, 2, 4, 122, 127, }, + { 4, 1, 2, 4, 122, 68, }, + { 5, 1, 2, 4, 122, 127, }, + { 6, 1, 2, 4, 122, 72, }, + { 7, 1, 2, 4, 122, 54, }, + { 8, 1, 2, 4, 122, 72, }, + { 9, 1, 2, 4, 122, 127, }, + { 10, 1, 2, 4, 122, 54, }, + { 11, 1, 2, 4, 122, 64, }, + { 0, 1, 2, 4, 138, 72, }, + { 2, 1, 2, 4, 138, 127, }, + { 1, 1, 2, 4, 138, 127, }, + { 3, 1, 2, 4, 138, 72, }, + { 4, 1, 2, 4, 138, 68, }, + { 5, 1, 2, 4, 138, 127, }, + { 6, 1, 2, 4, 138, 72, }, + { 7, 1, 2, 4, 138, 127, }, + { 8, 1, 2, 4, 138, 72, }, + { 9, 1, 2, 4, 138, 127, }, + { 10, 1, 2, 4, 138, 127, }, + { 11, 1, 2, 4, 138, 72, }, + { 0, 1, 2, 4, 155, 72, }, + { 2, 1, 2, 4, 155, 28, }, + { 1, 1, 2, 4, 155, 127, }, + { 3, 1, 2, 4, 155, 72, }, + { 4, 1, 2, 4, 155, 68, }, + { 5, 1, 2, 4, 155, 72, }, + { 6, 1, 2, 4, 155, 72, }, + { 7, 1, 2, 4, 155, 54, }, + { 8, 1, 2, 4, 155, 68, }, + { 9, 1, 2, 4, 155, 28, }, + { 10, 1, 2, 4, 155, 28, }, + { 11, 1, 2, 4, 155, 64, }, + { 0, 1, 2, 5, 42, 54, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 50, }, + { 3, 1, 2, 5, 42, 40, }, + { 4, 1, 2, 5, 42, 58, }, + { 5, 1, 2, 5, 42, 40, }, + { 6, 1, 2, 5, 42, 52, }, + { 7, 1, 2, 5, 42, 30, }, + { 8, 1, 2, 5, 42, 50, }, + { 9, 1, 2, 5, 42, 40, }, + { 10, 1, 2, 5, 42, 40, }, + { 11, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 52, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 50, }, + { 3, 1, 2, 5, 58, 40, }, + { 4, 1, 2, 5, 58, 56, }, + { 5, 1, 2, 5, 58, 40, }, + { 6, 1, 2, 5, 58, 52, }, + { 7, 1, 2, 5, 58, 30, }, + { 8, 1, 2, 5, 58, 52, }, + { 9, 1, 2, 5, 58, 40, }, + { 10, 1, 2, 5, 58, 40, }, + { 11, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 50, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 72, }, + { 3, 1, 2, 5, 106, 50, }, + { 4, 1, 2, 5, 106, 56, }, + { 5, 1, 2, 5, 106, 40, }, + { 6, 1, 2, 5, 106, 50, }, + { 7, 1, 2, 5, 106, 30, }, + { 8, 1, 2, 5, 106, 50, }, + { 9, 1, 2, 5, 106, 127, }, + { 10, 1, 2, 5, 106, 30, }, + { 11, 1, 2, 5, 106, 40, }, + { 0, 1, 2, 5, 122, 66, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 72, }, + { 3, 1, 2, 5, 122, 127, }, + { 4, 1, 2, 5, 122, 56, }, + { 5, 1, 2, 5, 122, 127, }, + { 6, 1, 2, 5, 122, 66, }, + { 7, 1, 2, 5, 122, 30, }, + { 8, 1, 2, 5, 122, 66, }, + { 9, 1, 2, 5, 122, 127, }, + { 10, 1, 2, 5, 122, 30, }, + { 11, 1, 2, 5, 122, 40, }, + { 0, 1, 2, 5, 138, 66, }, + { 2, 1, 2, 5, 138, 127, }, + { 1, 1, 2, 5, 138, 127, }, + { 3, 1, 2, 5, 138, 66, }, + { 4, 1, 2, 5, 138, 58, }, + { 5, 1, 2, 5, 138, 127, }, + { 6, 1, 2, 5, 138, 66, }, + { 7, 1, 2, 5, 138, 127, }, + { 8, 1, 2, 5, 138, 66, }, + { 9, 1, 2, 5, 138, 127, }, + { 10, 1, 2, 5, 138, 127, }, + { 11, 1, 2, 5, 138, 60, }, + { 0, 1, 2, 5, 155, 62, }, + { 2, 1, 2, 5, 155, 4, }, + { 1, 1, 2, 5, 155, 127, }, + { 3, 1, 2, 5, 155, 62, }, + { 4, 1, 2, 5, 155, 58, }, + { 5, 1, 2, 5, 155, 72, }, + { 6, 1, 2, 5, 155, 62, }, + { 7, 1, 2, 5, 155, 30, }, + { 8, 1, 2, 5, 155, 62, }, + { 9, 1, 2, 5, 155, 4, }, + { 10, 1, 2, 5, 155, 4, }, + { 11, 1, 2, 5, 155, 40, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822c_txpwr_lmt_type0); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8822c_txpwr_lmt_type5[] = { + { 0, 0, 0, 0, 1, 72, }, + { 2, 0, 0, 0, 1, 56, }, + { 1, 0, 0, 0, 1, 72, }, + { 3, 0, 0, 0, 1, 72, }, + { 4, 0, 0, 0, 1, 76, }, + { 5, 0, 0, 0, 1, 56, }, + { 9, 0, 0, 0, 1, 60, }, + { 0, 0, 0, 0, 2, 72, }, + { 2, 0, 0, 0, 2, 56, }, + { 1, 0, 0, 0, 2, 72, }, + { 3, 0, 0, 0, 2, 72, }, + { 4, 0, 0, 0, 2, 76, }, + { 5, 0, 0, 0, 2, 56, }, + { 9, 0, 0, 0, 2, 60, }, + { 0, 0, 0, 0, 3, 76, }, + { 2, 0, 0, 0, 3, 56, }, + { 1, 0, 0, 0, 3, 72, }, + { 3, 0, 0, 0, 3, 76, }, + { 4, 0, 0, 0, 3, 76, }, + { 5, 0, 0, 0, 3, 56, }, + { 9, 0, 0, 0, 3, 60, }, + { 0, 0, 0, 0, 4, 76, }, + { 2, 0, 0, 0, 4, 56, }, + { 1, 0, 0, 0, 4, 72, }, + { 3, 0, 0, 0, 4, 76, }, + { 4, 0, 0, 0, 4, 76, }, + { 5, 0, 0, 0, 4, 56, }, + { 9, 0, 0, 0, 4, 60, }, + { 0, 0, 0, 0, 5, 76, }, + { 2, 0, 0, 0, 5, 56, }, + { 1, 0, 0, 0, 5, 72, }, + { 3, 0, 0, 0, 5, 76, }, + { 4, 0, 0, 0, 5, 76, }, + { 5, 0, 0, 0, 5, 56, }, + { 9, 0, 0, 0, 5, 60, }, + { 0, 0, 0, 0, 6, 76, }, + { 2, 0, 0, 0, 6, 56, }, + { 1, 0, 0, 0, 6, 72, }, + { 3, 0, 0, 0, 6, 76, }, + { 4, 0, 0, 0, 6, 76, }, + { 5, 0, 0, 0, 6, 56, }, + { 9, 0, 0, 0, 6, 60, }, + { 0, 0, 0, 0, 7, 76, }, + { 2, 0, 0, 0, 7, 56, }, + { 1, 0, 0, 0, 7, 72, }, + { 3, 0, 0, 0, 7, 76, }, + { 4, 0, 0, 0, 7, 76, }, + { 5, 0, 0, 0, 7, 56, }, + { 9, 0, 0, 0, 7, 60, }, + { 0, 0, 0, 0, 8, 76, }, + { 2, 0, 0, 0, 8, 56, }, + { 1, 0, 0, 0, 8, 72, }, + { 3, 0, 0, 0, 8, 76, }, + { 4, 0, 0, 0, 8, 76, }, + { 5, 0, 0, 0, 8, 56, }, + { 9, 0, 0, 0, 8, 60, }, + { 0, 0, 0, 0, 9, 76, }, + { 2, 0, 0, 0, 9, 56, }, + { 1, 0, 0, 0, 9, 72, }, + { 3, 0, 0, 0, 9, 76, }, + { 4, 0, 0, 0, 9, 76, }, + { 5, 0, 0, 0, 9, 56, }, + { 9, 0, 0, 0, 9, 60, }, + { 0, 0, 0, 0, 10, 72, }, + { 2, 0, 0, 0, 10, 56, }, + { 1, 0, 0, 0, 10, 72, }, + { 3, 0, 0, 0, 10, 72, }, + { 4, 0, 0, 0, 10, 76, }, + { 5, 0, 0, 0, 10, 56, }, + { 9, 0, 0, 0, 10, 60, }, + { 0, 0, 0, 0, 11, 72, }, + { 2, 0, 0, 0, 11, 56, }, + { 1, 0, 0, 0, 11, 72, }, + { 3, 0, 0, 0, 11, 72, }, + { 4, 0, 0, 0, 11, 76, }, + { 5, 0, 0, 0, 11, 56, }, + { 9, 0, 0, 0, 11, 60, }, + { 0, 0, 0, 0, 12, 52, }, + { 2, 0, 0, 0, 12, 56, }, + { 1, 0, 0, 0, 12, 72, }, + { 3, 0, 0, 0, 12, 52, }, + { 4, 0, 0, 0, 12, 76, }, + { 5, 0, 0, 0, 12, 56, }, + { 9, 0, 0, 0, 12, 60, }, + { 0, 0, 0, 0, 13, 48, }, + { 2, 0, 0, 0, 13, 56, }, + { 1, 0, 0, 0, 13, 72, }, + { 3, 0, 0, 0, 13, 48, }, + { 4, 0, 0, 0, 13, 76, }, + { 5, 0, 0, 0, 13, 56, }, + { 9, 0, 0, 0, 13, 60, }, + { 0, 0, 0, 0, 14, 127, }, + { 2, 0, 0, 0, 14, 127, }, + { 1, 0, 0, 0, 14, 72, }, + { 3, 0, 0, 0, 14, 127, }, + { 4, 0, 0, 0, 14, 127, }, + { 5, 0, 0, 0, 14, 127, }, + { 9, 0, 0, 0, 14, 127, }, + { 0, 0, 0, 1, 1, 52, }, + { 2, 0, 0, 1, 1, 60, }, + { 1, 0, 0, 1, 1, 76, }, + { 3, 0, 0, 1, 1, 52, }, + { 4, 0, 0, 1, 1, 76, }, + { 5, 0, 0, 1, 1, 60, }, + { 9, 0, 0, 1, 1, 60, }, + { 0, 0, 0, 1, 2, 60, }, + { 2, 0, 0, 1, 2, 60, }, + { 1, 0, 0, 1, 2, 76, }, + { 3, 0, 0, 1, 2, 60, }, + { 4, 0, 0, 1, 2, 76, }, + { 5, 0, 0, 1, 2, 60, }, + { 9, 0, 0, 1, 2, 60, }, + { 0, 0, 0, 1, 3, 64, }, + { 2, 0, 0, 1, 3, 60, }, + { 1, 0, 0, 1, 3, 76, }, + { 3, 0, 0, 1, 3, 64, }, + { 4, 0, 0, 1, 3, 76, }, + { 5, 0, 0, 1, 3, 60, }, + { 9, 0, 0, 1, 3, 60, }, + { 0, 0, 0, 1, 4, 68, }, + { 2, 0, 0, 1, 4, 60, }, + { 1, 0, 0, 1, 4, 76, }, + { 3, 0, 0, 1, 4, 68, }, + { 4, 0, 0, 1, 4, 76, }, + { 5, 0, 0, 1, 4, 60, }, + { 9, 0, 0, 1, 4, 60, }, + { 0, 0, 0, 1, 5, 76, }, + { 2, 0, 0, 1, 5, 60, }, + { 1, 0, 0, 1, 5, 76, }, + { 3, 0, 0, 1, 5, 76, }, + { 4, 0, 0, 1, 5, 76, }, + { 5, 0, 0, 1, 5, 60, }, + { 9, 0, 0, 1, 5, 60, }, + { 0, 0, 0, 1, 6, 76, }, + { 2, 0, 0, 1, 6, 60, }, + { 1, 0, 0, 1, 6, 76, }, + { 3, 0, 0, 1, 6, 76, }, + { 4, 0, 0, 1, 6, 76, }, + { 5, 0, 0, 1, 6, 60, }, + { 9, 0, 0, 1, 6, 60, }, + { 0, 0, 0, 1, 7, 76, }, + { 2, 0, 0, 1, 7, 60, }, + { 1, 0, 0, 1, 7, 76, }, + { 3, 0, 0, 1, 7, 76, }, + { 4, 0, 0, 1, 7, 76, }, + { 5, 0, 0, 1, 7, 60, }, + { 9, 0, 0, 1, 7, 60, }, + { 0, 0, 0, 1, 8, 68, }, + { 2, 0, 0, 1, 8, 60, }, + { 1, 0, 0, 1, 8, 76, }, + { 3, 0, 0, 1, 8, 68, }, + { 4, 0, 0, 1, 8, 76, }, + { 5, 0, 0, 1, 8, 60, }, + { 9, 0, 0, 1, 8, 60, }, + { 0, 0, 0, 1, 9, 64, }, + { 2, 0, 0, 1, 9, 60, }, + { 1, 0, 0, 1, 9, 76, }, + { 3, 0, 0, 1, 9, 64, }, + { 4, 0, 0, 1, 9, 76, }, + { 5, 0, 0, 1, 9, 60, }, + { 9, 0, 0, 1, 9, 60, }, + { 0, 0, 0, 1, 10, 60, }, + { 2, 0, 0, 1, 10, 60, }, + { 1, 0, 0, 1, 10, 76, }, + { 3, 0, 0, 1, 10, 60, }, + { 4, 0, 0, 1, 10, 76, }, + { 5, 0, 0, 1, 10, 60, }, + { 9, 0, 0, 1, 10, 60, }, + { 0, 0, 0, 1, 11, 52, }, + { 2, 0, 0, 1, 11, 60, }, + { 1, 0, 0, 1, 11, 76, }, + { 3, 0, 0, 1, 11, 52, }, + { 4, 0, 0, 1, 11, 76, }, + { 5, 0, 0, 1, 11, 60, }, + { 9, 0, 0, 1, 11, 52, }, + { 0, 0, 0, 1, 12, 40, }, + { 2, 0, 0, 1, 12, 60, }, + { 1, 0, 0, 1, 12, 76, }, + { 3, 0, 0, 1, 12, 40, }, + { 4, 0, 0, 1, 12, 76, }, + { 5, 0, 0, 1, 12, 60, }, + { 9, 0, 0, 1, 12, 48, }, + { 0, 0, 0, 1, 13, 28, }, + { 2, 0, 0, 1, 13, 60, }, + { 1, 0, 0, 1, 13, 76, }, + { 3, 0, 0, 1, 13, 28, }, + { 4, 0, 0, 1, 13, 74, }, + { 5, 0, 0, 1, 13, 60, }, + { 9, 0, 0, 1, 13, 40, }, + { 0, 0, 0, 1, 14, 127, }, + { 2, 0, 0, 1, 14, 127, }, + { 1, 0, 0, 1, 14, 127, }, + { 3, 0, 0, 1, 14, 127, }, + { 4, 0, 0, 1, 14, 127, }, + { 5, 0, 0, 1, 14, 127, }, + { 9, 0, 0, 1, 14, 127, }, + { 0, 0, 0, 2, 1, 52, }, + { 2, 0, 0, 2, 1, 60, }, + { 1, 0, 0, 2, 1, 76, }, + { 3, 0, 0, 2, 1, 52, }, + { 4, 0, 0, 2, 1, 76, }, + { 5, 0, 0, 2, 1, 60, }, + { 9, 0, 0, 2, 1, 60, }, + { 0, 0, 0, 2, 2, 60, }, + { 2, 0, 0, 2, 2, 60, }, + { 1, 0, 0, 2, 2, 76, }, + { 3, 0, 0, 2, 2, 60, }, + { 4, 0, 0, 2, 2, 76, }, + { 5, 0, 0, 2, 2, 60, }, + { 9, 0, 0, 2, 2, 60, }, + { 0, 0, 0, 2, 3, 64, }, + { 2, 0, 0, 2, 3, 60, }, + { 1, 0, 0, 2, 3, 76, }, + { 3, 0, 0, 2, 3, 64, }, + { 4, 0, 0, 2, 3, 76, }, + { 5, 0, 0, 2, 3, 60, }, + { 9, 0, 0, 2, 3, 60, }, + { 0, 0, 0, 2, 4, 68, }, + { 2, 0, 0, 2, 4, 60, }, + { 1, 0, 0, 2, 4, 76, }, + { 3, 0, 0, 2, 4, 68, }, + { 4, 0, 0, 2, 4, 76, }, + { 5, 0, 0, 2, 4, 60, }, + { 9, 0, 0, 2, 4, 60, }, + { 0, 0, 0, 2, 5, 76, }, + { 2, 0, 0, 2, 5, 60, }, + { 1, 0, 0, 2, 5, 76, }, + { 3, 0, 0, 2, 5, 76, }, + { 4, 0, 0, 2, 5, 76, }, + { 5, 0, 0, 2, 5, 60, }, + { 9, 0, 0, 2, 5, 60, }, + { 0, 0, 0, 2, 6, 76, }, + { 2, 0, 0, 2, 6, 60, }, + { 1, 0, 0, 2, 6, 76, }, + { 3, 0, 0, 2, 6, 76, }, + { 4, 0, 0, 2, 6, 76, }, + { 5, 0, 0, 2, 6, 60, }, + { 9, 0, 0, 2, 6, 60, }, + { 0, 0, 0, 2, 7, 76, }, + { 2, 0, 0, 2, 7, 60, }, + { 1, 0, 0, 2, 7, 76, }, + { 3, 0, 0, 2, 7, 76, }, + { 4, 0, 0, 2, 7, 76, }, + { 5, 0, 0, 2, 7, 60, }, + { 9, 0, 0, 2, 7, 60, }, + { 0, 0, 0, 2, 8, 68, }, + { 2, 0, 0, 2, 8, 60, }, + { 1, 0, 0, 2, 8, 76, }, + { 3, 0, 0, 2, 8, 68, }, + { 4, 0, 0, 2, 8, 76, }, + { 5, 0, 0, 2, 8, 60, }, + { 9, 0, 0, 2, 8, 60, }, + { 0, 0, 0, 2, 9, 64, }, + { 2, 0, 0, 2, 9, 60, }, + { 1, 0, 0, 2, 9, 76, }, + { 3, 0, 0, 2, 9, 64, }, + { 4, 0, 0, 2, 9, 76, }, + { 5, 0, 0, 2, 9, 60, }, + { 9, 0, 0, 2, 9, 60, }, + { 0, 0, 0, 2, 10, 60, }, + { 2, 0, 0, 2, 10, 60, }, + { 1, 0, 0, 2, 10, 76, }, + { 3, 0, 0, 2, 10, 60, }, + { 4, 0, 0, 2, 10, 76, }, + { 5, 0, 0, 2, 10, 60, }, + { 9, 0, 0, 2, 10, 60, }, + { 0, 0, 0, 2, 11, 52, }, + { 2, 0, 0, 2, 11, 60, }, + { 1, 0, 0, 2, 11, 76, }, + { 3, 0, 0, 2, 11, 52, }, + { 4, 0, 0, 2, 11, 76, }, + { 5, 0, 0, 2, 11, 60, }, + { 9, 0, 0, 2, 11, 52, }, + { 0, 0, 0, 2, 12, 40, }, + { 2, 0, 0, 2, 12, 60, }, + { 1, 0, 0, 2, 12, 76, }, + { 3, 0, 0, 2, 12, 40, }, + { 4, 0, 0, 2, 12, 76, }, + { 5, 0, 0, 2, 12, 60, }, + { 9, 0, 0, 2, 12, 48, }, + { 0, 0, 0, 2, 13, 28, }, + { 2, 0, 0, 2, 13, 60, }, + { 1, 0, 0, 2, 13, 76, }, + { 3, 0, 0, 2, 13, 28, }, + { 4, 0, 0, 2, 13, 74, }, + { 5, 0, 0, 2, 13, 60, }, + { 9, 0, 0, 2, 13, 40, }, + { 0, 0, 0, 2, 14, 127, }, + { 2, 0, 0, 2, 14, 127, }, + { 1, 0, 0, 2, 14, 127, }, + { 3, 0, 0, 2, 14, 127, }, + { 4, 0, 0, 2, 14, 127, }, + { 5, 0, 0, 2, 14, 127, }, + { 9, 0, 0, 2, 14, 127, }, + { 0, 0, 0, 3, 1, 52, }, + { 2, 0, 0, 3, 1, 36, }, + { 1, 0, 0, 3, 1, 66, }, + { 3, 0, 0, 3, 1, 52, }, + { 4, 0, 0, 3, 1, 72, }, + { 5, 0, 0, 3, 1, 36, }, + { 9, 0, 0, 3, 1, 36, }, + { 0, 0, 0, 3, 2, 60, }, + { 2, 0, 0, 3, 2, 36, }, + { 1, 0, 0, 3, 2, 66, }, + { 3, 0, 0, 3, 2, 60, }, + { 4, 0, 0, 3, 2, 72, }, + { 5, 0, 0, 3, 2, 36, }, + { 9, 0, 0, 3, 2, 36, }, + { 0, 0, 0, 3, 3, 64, }, + { 2, 0, 0, 3, 3, 36, }, + { 1, 0, 0, 3, 3, 66, }, + { 3, 0, 0, 3, 3, 64, }, + { 4, 0, 0, 3, 3, 72, }, + { 5, 0, 0, 3, 3, 36, }, + { 9, 0, 0, 3, 3, 36, }, + { 0, 0, 0, 3, 4, 68, }, + { 2, 0, 0, 3, 4, 36, }, + { 1, 0, 0, 3, 4, 66, }, + { 3, 0, 0, 3, 4, 68, }, + { 4, 0, 0, 3, 4, 72, }, + { 5, 0, 0, 3, 4, 36, }, + { 9, 0, 0, 3, 4, 36, }, + { 0, 0, 0, 3, 5, 76, }, + { 2, 0, 0, 3, 5, 36, }, + { 1, 0, 0, 3, 5, 66, }, + { 3, 0, 0, 3, 5, 76, }, + { 4, 0, 0, 3, 5, 72, }, + { 5, 0, 0, 3, 5, 36, }, + { 9, 0, 0, 3, 5, 36, }, + { 0, 0, 0, 3, 6, 76, }, + { 2, 0, 0, 3, 6, 36, }, + { 1, 0, 0, 3, 6, 66, }, + { 3, 0, 0, 3, 6, 76, }, + { 4, 0, 0, 3, 6, 72, }, + { 5, 0, 0, 3, 6, 36, }, + { 9, 0, 0, 3, 6, 36, }, + { 0, 0, 0, 3, 7, 76, }, + { 2, 0, 0, 3, 7, 36, }, + { 1, 0, 0, 3, 7, 66, }, + { 3, 0, 0, 3, 7, 76, }, + { 4, 0, 0, 3, 7, 72, }, + { 5, 0, 0, 3, 7, 36, }, + { 9, 0, 0, 3, 7, 36, }, + { 0, 0, 0, 3, 8, 68, }, + { 2, 0, 0, 3, 8, 36, }, + { 1, 0, 0, 3, 8, 66, }, + { 3, 0, 0, 3, 8, 68, }, + { 4, 0, 0, 3, 8, 72, }, + { 5, 0, 0, 3, 8, 36, }, + { 9, 0, 0, 3, 8, 36, }, + { 0, 0, 0, 3, 9, 64, }, + { 2, 0, 0, 3, 9, 36, }, + { 1, 0, 0, 3, 9, 66, }, + { 3, 0, 0, 3, 9, 64, }, + { 4, 0, 0, 3, 9, 72, }, + { 5, 0, 0, 3, 9, 36, }, + { 9, 0, 0, 3, 9, 36, }, + { 0, 0, 0, 3, 10, 60, }, + { 2, 0, 0, 3, 10, 36, }, + { 1, 0, 0, 3, 10, 66, }, + { 3, 0, 0, 3, 10, 60, }, + { 4, 0, 0, 3, 10, 72, }, + { 5, 0, 0, 3, 10, 36, }, + { 9, 0, 0, 3, 10, 36, }, + { 0, 0, 0, 3, 11, 52, }, + { 2, 0, 0, 3, 11, 36, }, + { 1, 0, 0, 3, 11, 66, }, + { 3, 0, 0, 3, 11, 52, }, + { 4, 0, 0, 3, 11, 72, }, + { 5, 0, 0, 3, 11, 36, }, + { 9, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 40, }, + { 2, 0, 0, 3, 12, 36, }, + { 1, 0, 0, 3, 12, 66, }, + { 3, 0, 0, 3, 12, 40, }, + { 4, 0, 0, 3, 12, 72, }, + { 5, 0, 0, 3, 12, 36, }, + { 9, 0, 0, 3, 12, 36, }, + { 0, 0, 0, 3, 13, 28, }, + { 2, 0, 0, 3, 13, 36, }, + { 1, 0, 0, 3, 13, 66, }, + { 3, 0, 0, 3, 13, 28, }, + { 4, 0, 0, 3, 13, 68, }, + { 5, 0, 0, 3, 13, 36, }, + { 9, 0, 0, 3, 13, 28, }, + { 0, 0, 0, 3, 14, 127, }, + { 2, 0, 0, 3, 14, 127, }, + { 1, 0, 0, 3, 14, 127, }, + { 3, 0, 0, 3, 14, 127, }, + { 4, 0, 0, 3, 14, 127, }, + { 5, 0, 0, 3, 14, 127, }, + { 9, 0, 0, 3, 14, 127, }, + { 0, 0, 1, 2, 1, 127, }, + { 2, 0, 1, 2, 1, 127, }, + { 1, 0, 1, 2, 1, 127, }, + { 3, 0, 1, 2, 1, 127, }, + { 4, 0, 1, 2, 1, 127, }, + { 5, 0, 1, 2, 1, 127, }, + { 9, 0, 1, 2, 1, 60, }, + { 0, 0, 1, 2, 2, 127, }, + { 2, 0, 1, 2, 2, 127, }, + { 1, 0, 1, 2, 2, 127, }, + { 3, 0, 1, 2, 2, 127, }, + { 4, 0, 1, 2, 2, 127, }, + { 5, 0, 1, 2, 2, 127, }, + { 9, 0, 1, 2, 2, 60, }, + { 0, 0, 1, 2, 3, 52, }, + { 2, 0, 1, 2, 3, 60, }, + { 1, 0, 1, 2, 3, 72, }, + { 3, 0, 1, 2, 3, 52, }, + { 4, 0, 1, 2, 3, 72, }, + { 5, 0, 1, 2, 3, 60, }, + { 9, 0, 1, 2, 3, 60, }, + { 0, 0, 1, 2, 4, 52, }, + { 2, 0, 1, 2, 4, 60, }, + { 1, 0, 1, 2, 4, 72, }, + { 3, 0, 1, 2, 4, 52, }, + { 4, 0, 1, 2, 4, 72, }, + { 5, 0, 1, 2, 4, 60, }, + { 9, 0, 1, 2, 4, 60, }, + { 0, 0, 1, 2, 5, 60, }, + { 2, 0, 1, 2, 5, 60, }, + { 1, 0, 1, 2, 5, 72, }, + { 3, 0, 1, 2, 5, 60, }, + { 4, 0, 1, 2, 5, 72, }, + { 5, 0, 1, 2, 5, 60, }, + { 9, 0, 1, 2, 5, 60, }, + { 0, 0, 1, 2, 6, 64, }, + { 2, 0, 1, 2, 6, 60, }, + { 1, 0, 1, 2, 6, 72, }, + { 3, 0, 1, 2, 6, 64, }, + { 4, 0, 1, 2, 6, 72, }, + { 5, 0, 1, 2, 6, 60, }, + { 9, 0, 1, 2, 6, 60, }, + { 0, 0, 1, 2, 7, 60, }, + { 2, 0, 1, 2, 7, 60, }, + { 1, 0, 1, 2, 7, 72, }, + { 3, 0, 1, 2, 7, 60, }, + { 4, 0, 1, 2, 7, 72, }, + { 5, 0, 1, 2, 7, 60, }, + { 9, 0, 1, 2, 7, 60, }, + { 0, 0, 1, 2, 8, 52, }, + { 2, 0, 1, 2, 8, 60, }, + { 1, 0, 1, 2, 8, 72, }, + { 3, 0, 1, 2, 8, 52, }, + { 4, 0, 1, 2, 8, 72, }, + { 5, 0, 1, 2, 8, 60, }, + { 9, 0, 1, 2, 8, 60, }, + { 0, 0, 1, 2, 9, 52, }, + { 2, 0, 1, 2, 9, 60, }, + { 1, 0, 1, 2, 9, 72, }, + { 3, 0, 1, 2, 9, 52, }, + { 4, 0, 1, 2, 9, 72, }, + { 5, 0, 1, 2, 9, 60, }, + { 9, 0, 1, 2, 9, 60, }, + { 0, 0, 1, 2, 10, 40, }, + { 2, 0, 1, 2, 10, 60, }, + { 1, 0, 1, 2, 10, 72, }, + { 3, 0, 1, 2, 10, 40, }, + { 4, 0, 1, 2, 10, 72, }, + { 5, 0, 1, 2, 10, 60, }, + { 9, 0, 1, 2, 10, 60, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 60, }, + { 1, 0, 1, 2, 11, 72, }, + { 3, 0, 1, 2, 11, 28, }, + { 4, 0, 1, 2, 11, 70, }, + { 5, 0, 1, 2, 11, 60, }, + { 9, 0, 1, 2, 11, 44, }, + { 0, 0, 1, 2, 12, 127, }, + { 2, 0, 1, 2, 12, 127, }, + { 1, 0, 1, 2, 12, 127, }, + { 3, 0, 1, 2, 12, 127, }, + { 4, 0, 1, 2, 12, 127, }, + { 5, 0, 1, 2, 12, 127, }, + { 9, 0, 1, 2, 12, 44, }, + { 0, 0, 1, 2, 13, 127, }, + { 2, 0, 1, 2, 13, 127, }, + { 1, 0, 1, 2, 13, 127, }, + { 3, 0, 1, 2, 13, 127, }, + { 4, 0, 1, 2, 13, 127, }, + { 5, 0, 1, 2, 13, 127, }, + { 9, 0, 1, 2, 13, 20, }, + { 0, 0, 1, 2, 14, 127, }, + { 2, 0, 1, 2, 14, 127, }, + { 1, 0, 1, 2, 14, 127, }, + { 3, 0, 1, 2, 14, 127, }, + { 4, 0, 1, 2, 14, 127, }, + { 5, 0, 1, 2, 14, 127, }, + { 9, 0, 1, 2, 14, 127, }, + { 0, 0, 1, 3, 1, 127, }, + { 2, 0, 1, 3, 1, 127, }, + { 1, 0, 1, 3, 1, 127, }, + { 3, 0, 1, 3, 1, 127, }, + { 4, 0, 1, 3, 1, 127, }, + { 5, 0, 1, 3, 1, 127, }, + { 9, 0, 1, 3, 1, 36, }, + { 0, 0, 1, 3, 2, 127, }, + { 2, 0, 1, 3, 2, 127, }, + { 1, 0, 1, 3, 2, 127, }, + { 3, 0, 1, 3, 2, 127, }, + { 4, 0, 1, 3, 2, 127, }, + { 5, 0, 1, 3, 2, 127, }, + { 9, 0, 1, 3, 2, 36, }, + { 0, 0, 1, 3, 3, 48, }, + { 2, 0, 1, 3, 3, 36, }, + { 1, 0, 1, 3, 3, 66, }, + { 3, 0, 1, 3, 3, 48, }, + { 4, 0, 1, 3, 3, 68, }, + { 5, 0, 1, 3, 3, 36, }, + { 9, 0, 1, 3, 3, 36, }, + { 0, 0, 1, 3, 4, 48, }, + { 2, 0, 1, 3, 4, 36, }, + { 1, 0, 1, 3, 4, 66, }, + { 3, 0, 1, 3, 4, 48, }, + { 4, 0, 1, 3, 4, 70, }, + { 5, 0, 1, 3, 4, 36, }, + { 9, 0, 1, 3, 4, 36, }, + { 0, 0, 1, 3, 5, 60, }, + { 2, 0, 1, 3, 5, 36, }, + { 1, 0, 1, 3, 5, 66, }, + { 3, 0, 1, 3, 5, 60, }, + { 4, 0, 1, 3, 5, 70, }, + { 5, 0, 1, 3, 5, 36, }, + { 9, 0, 1, 3, 5, 36, }, + { 0, 0, 1, 3, 6, 64, }, + { 2, 0, 1, 3, 6, 36, }, + { 1, 0, 1, 3, 6, 66, }, + { 3, 0, 1, 3, 6, 64, }, + { 4, 0, 1, 3, 6, 70, }, + { 5, 0, 1, 3, 6, 36, }, + { 9, 0, 1, 3, 6, 36, }, + { 0, 0, 1, 3, 7, 60, }, + { 2, 0, 1, 3, 7, 36, }, + { 1, 0, 1, 3, 7, 66, }, + { 3, 0, 1, 3, 7, 60, }, + { 4, 0, 1, 3, 7, 70, }, + { 5, 0, 1, 3, 7, 36, }, + { 9, 0, 1, 3, 7, 36, }, + { 0, 0, 1, 3, 8, 52, }, + { 2, 0, 1, 3, 8, 36, }, + { 1, 0, 1, 3, 8, 66, }, + { 3, 0, 1, 3, 8, 52, }, + { 4, 0, 1, 3, 8, 70, }, + { 5, 0, 1, 3, 8, 36, }, + { 9, 0, 1, 3, 8, 36, }, + { 0, 0, 1, 3, 9, 52, }, + { 2, 0, 1, 3, 9, 36, }, + { 1, 0, 1, 3, 9, 66, }, + { 3, 0, 1, 3, 9, 52, }, + { 4, 0, 1, 3, 9, 70, }, + { 5, 0, 1, 3, 9, 36, }, + { 9, 0, 1, 3, 9, 36, }, + { 0, 0, 1, 3, 10, 40, }, + { 2, 0, 1, 3, 10, 36, }, + { 1, 0, 1, 3, 10, 66, }, + { 3, 0, 1, 3, 10, 40, }, + { 4, 0, 1, 3, 10, 70, }, + { 5, 0, 1, 3, 10, 36, }, + { 9, 0, 1, 3, 10, 36, }, + { 0, 0, 1, 3, 11, 26, }, + { 2, 0, 1, 3, 11, 36, }, + { 1, 0, 1, 3, 11, 66, }, + { 3, 0, 1, 3, 11, 26, }, + { 4, 0, 1, 3, 11, 66, }, + { 5, 0, 1, 3, 11, 36, }, + { 9, 0, 1, 3, 11, 32, }, + { 0, 0, 1, 3, 12, 127, }, + { 2, 0, 1, 3, 12, 127, }, + { 1, 0, 1, 3, 12, 127, }, + { 3, 0, 1, 3, 12, 127, }, + { 4, 0, 1, 3, 12, 127, }, + { 5, 0, 1, 3, 12, 127, }, + { 9, 0, 1, 3, 12, 32, }, + { 0, 0, 1, 3, 13, 127, }, + { 2, 0, 1, 3, 13, 127, }, + { 1, 0, 1, 3, 13, 127, }, + { 3, 0, 1, 3, 13, 127, }, + { 4, 0, 1, 3, 13, 127, }, + { 5, 0, 1, 3, 13, 127, }, + { 9, 0, 1, 3, 13, 8, }, + { 0, 0, 1, 3, 14, 127, }, + { 2, 0, 1, 3, 14, 127, }, + { 1, 0, 1, 3, 14, 127, }, + { 3, 0, 1, 3, 14, 127, }, + { 4, 0, 1, 3, 14, 127, }, + { 5, 0, 1, 3, 14, 127, }, + { 9, 0, 1, 3, 14, 127, }, + { 0, 1, 0, 1, 36, 74, }, + { 2, 1, 0, 1, 36, 58, }, + { 1, 1, 0, 1, 36, 62, }, + { 3, 1, 0, 1, 36, 62, }, + { 4, 1, 0, 1, 36, 74, }, + { 5, 1, 0, 1, 36, 58, }, + { 9, 1, 0, 1, 36, 64, }, + { 0, 1, 0, 1, 40, 76, }, + { 2, 1, 0, 1, 40, 58, }, + { 1, 1, 0, 1, 40, 62, }, + { 3, 1, 0, 1, 40, 62, }, + { 4, 1, 0, 1, 40, 76, }, + { 5, 1, 0, 1, 40, 58, }, + { 9, 1, 0, 1, 40, 64, }, + { 0, 1, 0, 1, 44, 76, }, + { 2, 1, 0, 1, 44, 58, }, + { 1, 1, 0, 1, 44, 62, }, + { 3, 1, 0, 1, 44, 62, }, + { 4, 1, 0, 1, 44, 76, }, + { 5, 1, 0, 1, 44, 58, }, + { 9, 1, 0, 1, 44, 64, }, + { 0, 1, 0, 1, 48, 76, }, + { 2, 1, 0, 1, 48, 58, }, + { 1, 1, 0, 1, 48, 62, }, + { 3, 1, 0, 1, 48, 62, }, + { 4, 1, 0, 1, 48, 58, }, + { 5, 1, 0, 1, 48, 58, }, + { 9, 1, 0, 1, 48, 64, }, + { 0, 1, 0, 1, 52, 76, }, + { 2, 1, 0, 1, 52, 58, }, + { 1, 1, 0, 1, 52, 62, }, + { 3, 1, 0, 1, 52, 64, }, + { 4, 1, 0, 1, 52, 76, }, + { 5, 1, 0, 1, 52, 58, }, + { 9, 1, 0, 1, 52, 64, }, + { 0, 1, 0, 1, 56, 76, }, + { 2, 1, 0, 1, 56, 58, }, + { 1, 1, 0, 1, 56, 62, }, + { 3, 1, 0, 1, 56, 64, }, + { 4, 1, 0, 1, 56, 76, }, + { 5, 1, 0, 1, 56, 58, }, + { 9, 1, 0, 1, 56, 64, }, + { 0, 1, 0, 1, 60, 76, }, + { 2, 1, 0, 1, 60, 58, }, + { 1, 1, 0, 1, 60, 62, }, + { 3, 1, 0, 1, 60, 64, }, + { 4, 1, 0, 1, 60, 76, }, + { 5, 1, 0, 1, 60, 58, }, + { 9, 1, 0, 1, 60, 64, }, + { 0, 1, 0, 1, 64, 76, }, + { 2, 1, 0, 1, 64, 58, }, + { 1, 1, 0, 1, 64, 62, }, + { 3, 1, 0, 1, 64, 64, }, + { 4, 1, 0, 1, 64, 76, }, + { 5, 1, 0, 1, 64, 58, }, + { 9, 1, 0, 1, 64, 64, }, + { 0, 1, 0, 1, 100, 68, }, + { 2, 1, 0, 1, 100, 58, }, + { 1, 1, 0, 1, 100, 76, }, + { 3, 1, 0, 1, 100, 68, }, + { 4, 1, 0, 1, 100, 76, }, + { 5, 1, 0, 1, 100, 58, }, + { 9, 1, 0, 1, 100, 127, }, + { 0, 1, 0, 1, 104, 76, }, + { 2, 1, 0, 1, 104, 58, }, + { 1, 1, 0, 1, 104, 76, }, + { 3, 1, 0, 1, 104, 76, }, + { 4, 1, 0, 1, 104, 76, }, + { 5, 1, 0, 1, 104, 58, }, + { 9, 1, 0, 1, 104, 127, }, + { 0, 1, 0, 1, 108, 76, }, + { 2, 1, 0, 1, 108, 58, }, + { 1, 1, 0, 1, 108, 76, }, + { 3, 1, 0, 1, 108, 76, }, + { 4, 1, 0, 1, 108, 76, }, + { 5, 1, 0, 1, 108, 58, }, + { 9, 1, 0, 1, 108, 127, }, + { 0, 1, 0, 1, 112, 76, }, + { 2, 1, 0, 1, 112, 58, }, + { 1, 1, 0, 1, 112, 76, }, + { 3, 1, 0, 1, 112, 76, }, + { 4, 1, 0, 1, 112, 76, }, + { 5, 1, 0, 1, 112, 58, }, + { 9, 1, 0, 1, 112, 127, }, + { 0, 1, 0, 1, 116, 76, }, + { 2, 1, 0, 1, 116, 58, }, + { 1, 1, 0, 1, 116, 76, }, + { 3, 1, 0, 1, 116, 76, }, + { 4, 1, 0, 1, 116, 76, }, + { 5, 1, 0, 1, 116, 58, }, + { 9, 1, 0, 1, 116, 127, }, + { 0, 1, 0, 1, 120, 76, }, + { 2, 1, 0, 1, 120, 58, }, + { 1, 1, 0, 1, 120, 76, }, + { 3, 1, 0, 1, 120, 127, }, + { 4, 1, 0, 1, 120, 76, }, + { 5, 1, 0, 1, 120, 127, }, + { 9, 1, 0, 1, 120, 127, }, + { 0, 1, 0, 1, 124, 76, }, + { 2, 1, 0, 1, 124, 58, }, + { 1, 1, 0, 1, 124, 76, }, + { 3, 1, 0, 1, 124, 127, }, + { 4, 1, 0, 1, 124, 76, }, + { 5, 1, 0, 1, 124, 127, }, + { 9, 1, 0, 1, 124, 127, }, + { 0, 1, 0, 1, 128, 76, }, + { 2, 1, 0, 1, 128, 58, }, + { 1, 1, 0, 1, 128, 76, }, + { 3, 1, 0, 1, 128, 127, }, + { 4, 1, 0, 1, 128, 76, }, + { 5, 1, 0, 1, 128, 127, }, + { 9, 1, 0, 1, 128, 127, }, + { 0, 1, 0, 1, 132, 76, }, + { 2, 1, 0, 1, 132, 58, }, + { 1, 1, 0, 1, 132, 76, }, + { 3, 1, 0, 1, 132, 76, }, + { 4, 1, 0, 1, 132, 76, }, + { 5, 1, 0, 1, 132, 58, }, + { 9, 1, 0, 1, 132, 127, }, + { 0, 1, 0, 1, 136, 76, }, + { 2, 1, 0, 1, 136, 58, }, + { 1, 1, 0, 1, 136, 76, }, + { 3, 1, 0, 1, 136, 76, }, + { 4, 1, 0, 1, 136, 76, }, + { 5, 1, 0, 1, 136, 58, }, + { 9, 1, 0, 1, 136, 127, }, + { 0, 1, 0, 1, 140, 74, }, + { 2, 1, 0, 1, 140, 58, }, + { 1, 1, 0, 1, 140, 76, }, + { 3, 1, 0, 1, 140, 74, }, + { 4, 1, 0, 1, 140, 76, }, + { 5, 1, 0, 1, 140, 58, }, + { 9, 1, 0, 1, 140, 127, }, + { 0, 1, 0, 1, 144, 76, }, + { 2, 1, 0, 1, 144, 127, }, + { 1, 1, 0, 1, 144, 76, }, + { 3, 1, 0, 1, 144, 76, }, + { 4, 1, 0, 1, 144, 76, }, + { 5, 1, 0, 1, 144, 127, }, + { 9, 1, 0, 1, 144, 127, }, + { 0, 1, 0, 1, 149, 76, }, + { 2, 1, 0, 1, 149, 28, }, + { 1, 1, 0, 1, 149, 127, }, + { 3, 1, 0, 1, 149, 76, }, + { 4, 1, 0, 1, 149, 74, }, + { 5, 1, 0, 1, 149, 76, }, + { 9, 1, 0, 1, 149, 76, }, + { 0, 1, 0, 1, 153, 76, }, + { 2, 1, 0, 1, 153, 28, }, + { 1, 1, 0, 1, 153, 127, }, + { 3, 1, 0, 1, 153, 76, }, + { 4, 1, 0, 1, 153, 74, }, + { 5, 1, 0, 1, 153, 76, }, + { 9, 1, 0, 1, 153, 76, }, + { 0, 1, 0, 1, 157, 76, }, + { 2, 1, 0, 1, 157, 28, }, + { 1, 1, 0, 1, 157, 127, }, + { 3, 1, 0, 1, 157, 76, }, + { 4, 1, 0, 1, 157, 74, }, + { 5, 1, 0, 1, 157, 76, }, + { 9, 1, 0, 1, 157, 76, }, + { 0, 1, 0, 1, 161, 76, }, + { 2, 1, 0, 1, 161, 28, }, + { 1, 1, 0, 1, 161, 127, }, + { 3, 1, 0, 1, 161, 76, }, + { 4, 1, 0, 1, 161, 74, }, + { 5, 1, 0, 1, 161, 76, }, + { 9, 1, 0, 1, 161, 76, }, + { 0, 1, 0, 1, 165, 76, }, + { 2, 1, 0, 1, 165, 28, }, + { 1, 1, 0, 1, 165, 127, }, + { 3, 1, 0, 1, 165, 76, }, + { 4, 1, 0, 1, 165, 74, }, + { 5, 1, 0, 1, 165, 76, }, + { 9, 1, 0, 1, 165, 76, }, + { 0, 1, 0, 2, 36, 70, }, + { 2, 1, 0, 2, 36, 58, }, + { 1, 1, 0, 2, 36, 64, }, + { 3, 1, 0, 2, 36, 62, }, + { 4, 1, 0, 2, 36, 76, }, + { 5, 1, 0, 2, 36, 58, }, + { 9, 1, 0, 2, 36, 60, }, + { 0, 1, 0, 2, 40, 76, }, + { 2, 1, 0, 2, 40, 58, }, + { 1, 1, 0, 2, 40, 62, }, + { 3, 1, 0, 2, 40, 62, }, + { 4, 1, 0, 2, 40, 76, }, + { 5, 1, 0, 2, 40, 58, }, + { 9, 1, 0, 2, 40, 60, }, + { 0, 1, 0, 2, 44, 76, }, + { 2, 1, 0, 2, 44, 58, }, + { 1, 1, 0, 2, 44, 62, }, + { 3, 1, 0, 2, 44, 62, }, + { 4, 1, 0, 2, 44, 76, }, + { 5, 1, 0, 2, 44, 58, }, + { 9, 1, 0, 2, 44, 60, }, + { 0, 1, 0, 2, 48, 76, }, + { 2, 1, 0, 2, 48, 58, }, + { 1, 1, 0, 2, 48, 62, }, + { 3, 1, 0, 2, 48, 62, }, + { 4, 1, 0, 2, 48, 58, }, + { 5, 1, 0, 2, 48, 58, }, + { 9, 1, 0, 2, 48, 60, }, + { 0, 1, 0, 2, 52, 76, }, + { 2, 1, 0, 2, 52, 58, }, + { 1, 1, 0, 2, 52, 62, }, + { 3, 1, 0, 2, 52, 64, }, + { 4, 1, 0, 2, 52, 76, }, + { 5, 1, 0, 2, 52, 58, }, + { 9, 1, 0, 2, 52, 60, }, + { 0, 1, 0, 2, 56, 76, }, + { 2, 1, 0, 2, 56, 58, }, + { 1, 1, 0, 2, 56, 62, }, + { 3, 1, 0, 2, 56, 64, }, + { 4, 1, 0, 2, 56, 76, }, + { 5, 1, 0, 2, 56, 58, }, + { 9, 1, 0, 2, 56, 60, }, + { 0, 1, 0, 2, 60, 76, }, + { 2, 1, 0, 2, 60, 58, }, + { 1, 1, 0, 2, 60, 62, }, + { 3, 1, 0, 2, 60, 64, }, + { 4, 1, 0, 2, 60, 76, }, + { 5, 1, 0, 2, 60, 58, }, + { 9, 1, 0, 2, 60, 60, }, + { 0, 1, 0, 2, 64, 70, }, + { 2, 1, 0, 2, 64, 58, }, + { 1, 1, 0, 2, 64, 62, }, + { 3, 1, 0, 2, 64, 64, }, + { 4, 1, 0, 2, 64, 74, }, + { 5, 1, 0, 2, 64, 58, }, + { 9, 1, 0, 2, 64, 60, }, + { 0, 1, 0, 2, 100, 66, }, + { 2, 1, 0, 2, 100, 58, }, + { 1, 1, 0, 2, 100, 76, }, + { 3, 1, 0, 2, 100, 66, }, + { 4, 1, 0, 2, 100, 76, }, + { 5, 1, 0, 2, 100, 58, }, + { 9, 1, 0, 2, 100, 127, }, + { 0, 1, 0, 2, 104, 76, }, + { 2, 1, 0, 2, 104, 58, }, + { 1, 1, 0, 2, 104, 76, }, + { 3, 1, 0, 2, 104, 76, }, + { 4, 1, 0, 2, 104, 76, }, + { 5, 1, 0, 2, 104, 58, }, + { 9, 1, 0, 2, 104, 127, }, + { 0, 1, 0, 2, 108, 76, }, + { 2, 1, 0, 2, 108, 58, }, + { 1, 1, 0, 2, 108, 76, }, + { 3, 1, 0, 2, 108, 76, }, + { 4, 1, 0, 2, 108, 76, }, + { 5, 1, 0, 2, 108, 58, }, + { 9, 1, 0, 2, 108, 127, }, + { 0, 1, 0, 2, 112, 76, }, + { 2, 1, 0, 2, 112, 58, }, + { 1, 1, 0, 2, 112, 76, }, + { 3, 1, 0, 2, 112, 76, }, + { 4, 1, 0, 2, 112, 76, }, + { 5, 1, 0, 2, 112, 58, }, + { 9, 1, 0, 2, 112, 127, }, + { 0, 1, 0, 2, 116, 76, }, + { 2, 1, 0, 2, 116, 58, }, + { 1, 1, 0, 2, 116, 76, }, + { 3, 1, 0, 2, 116, 76, }, + { 4, 1, 0, 2, 116, 76, }, + { 5, 1, 0, 2, 116, 58, }, + { 9, 1, 0, 2, 116, 127, }, + { 0, 1, 0, 2, 120, 76, }, + { 2, 1, 0, 2, 120, 58, }, + { 1, 1, 0, 2, 120, 76, }, + { 3, 1, 0, 2, 120, 127, }, + { 4, 1, 0, 2, 120, 76, }, + { 5, 1, 0, 2, 120, 127, }, + { 9, 1, 0, 2, 120, 127, }, + { 0, 1, 0, 2, 124, 76, }, + { 2, 1, 0, 2, 124, 58, }, + { 1, 1, 0, 2, 124, 76, }, + { 3, 1, 0, 2, 124, 127, }, + { 4, 1, 0, 2, 124, 76, }, + { 5, 1, 0, 2, 124, 127, }, + { 9, 1, 0, 2, 124, 127, }, + { 0, 1, 0, 2, 128, 76, }, + { 2, 1, 0, 2, 128, 58, }, + { 1, 1, 0, 2, 128, 76, }, + { 3, 1, 0, 2, 128, 127, }, + { 4, 1, 0, 2, 128, 76, }, + { 5, 1, 0, 2, 128, 127, }, + { 9, 1, 0, 2, 128, 127, }, + { 0, 1, 0, 2, 132, 76, }, + { 2, 1, 0, 2, 132, 58, }, + { 1, 1, 0, 2, 132, 76, }, + { 3, 1, 0, 2, 132, 76, }, + { 4, 1, 0, 2, 132, 76, }, + { 5, 1, 0, 2, 132, 58, }, + { 9, 1, 0, 2, 132, 127, }, + { 0, 1, 0, 2, 136, 76, }, + { 2, 1, 0, 2, 136, 58, }, + { 1, 1, 0, 2, 136, 76, }, + { 3, 1, 0, 2, 136, 76, }, + { 4, 1, 0, 2, 136, 76, }, + { 5, 1, 0, 2, 136, 58, }, + { 9, 1, 0, 2, 136, 127, }, + { 0, 1, 0, 2, 140, 66, }, + { 2, 1, 0, 2, 140, 58, }, + { 1, 1, 0, 2, 140, 76, }, + { 3, 1, 0, 2, 140, 66, }, + { 4, 1, 0, 2, 140, 76, }, + { 5, 1, 0, 2, 140, 58, }, + { 9, 1, 0, 2, 140, 127, }, + { 0, 1, 0, 2, 144, 76, }, + { 2, 1, 0, 2, 144, 127, }, + { 1, 1, 0, 2, 144, 76, }, + { 3, 1, 0, 2, 144, 76, }, + { 4, 1, 0, 2, 144, 76, }, + { 5, 1, 0, 2, 144, 127, }, + { 9, 1, 0, 2, 144, 127, }, + { 0, 1, 0, 2, 149, 76, }, + { 2, 1, 0, 2, 149, 28, }, + { 1, 1, 0, 2, 149, 127, }, + { 3, 1, 0, 2, 149, 76, }, + { 4, 1, 0, 2, 149, 74, }, + { 5, 1, 0, 2, 149, 76, }, + { 9, 1, 0, 2, 149, 76, }, + { 0, 1, 0, 2, 153, 76, }, + { 2, 1, 0, 2, 153, 28, }, + { 1, 1, 0, 2, 153, 127, }, + { 3, 1, 0, 2, 153, 76, }, + { 4, 1, 0, 2, 153, 74, }, + { 5, 1, 0, 2, 153, 76, }, + { 9, 1, 0, 2, 153, 76, }, + { 0, 1, 0, 2, 157, 76, }, + { 2, 1, 0, 2, 157, 28, }, + { 1, 1, 0, 2, 157, 127, }, + { 3, 1, 0, 2, 157, 76, }, + { 4, 1, 0, 2, 157, 74, }, + { 5, 1, 0, 2, 157, 76, }, + { 9, 1, 0, 2, 157, 76, }, + { 0, 1, 0, 2, 161, 76, }, + { 2, 1, 0, 2, 161, 28, }, + { 1, 1, 0, 2, 161, 127, }, + { 3, 1, 0, 2, 161, 76, }, + { 4, 1, 0, 2, 161, 74, }, + { 5, 1, 0, 2, 161, 76, }, + { 9, 1, 0, 2, 161, 76, }, + { 0, 1, 0, 2, 165, 76, }, + { 2, 1, 0, 2, 165, 28, }, + { 1, 1, 0, 2, 165, 127, }, + { 3, 1, 0, 2, 165, 76, }, + { 4, 1, 0, 2, 165, 74, }, + { 5, 1, 0, 2, 165, 76, }, + { 9, 1, 0, 2, 165, 76, }, + { 0, 1, 0, 3, 36, 64, }, + { 2, 1, 0, 3, 36, 36, }, + { 1, 1, 0, 3, 36, 50, }, + { 3, 1, 0, 3, 36, 38, }, + { 4, 1, 0, 3, 36, 66, }, + { 5, 1, 0, 3, 36, 36, }, + { 9, 1, 0, 3, 36, 36, }, + { 0, 1, 0, 3, 40, 68, }, + { 2, 1, 0, 3, 40, 36, }, + { 1, 1, 0, 3, 40, 50, }, + { 3, 1, 0, 3, 40, 38, }, + { 4, 1, 0, 3, 40, 66, }, + { 5, 1, 0, 3, 40, 36, }, + { 9, 1, 0, 3, 40, 36, }, + { 0, 1, 0, 3, 44, 68, }, + { 2, 1, 0, 3, 44, 36, }, + { 1, 1, 0, 3, 44, 50, }, + { 3, 1, 0, 3, 44, 38, }, + { 4, 1, 0, 3, 44, 66, }, + { 5, 1, 0, 3, 44, 36, }, + { 9, 1, 0, 3, 44, 36, }, + { 0, 1, 0, 3, 48, 68, }, + { 2, 1, 0, 3, 48, 36, }, + { 1, 1, 0, 3, 48, 50, }, + { 3, 1, 0, 3, 48, 38, }, + { 4, 1, 0, 3, 48, 42, }, + { 5, 1, 0, 3, 48, 36, }, + { 9, 1, 0, 3, 48, 36, }, + { 0, 1, 0, 3, 52, 68, }, + { 2, 1, 0, 3, 52, 36, }, + { 1, 1, 0, 3, 52, 50, }, + { 3, 1, 0, 3, 52, 40, }, + { 4, 1, 0, 3, 52, 66, }, + { 5, 1, 0, 3, 52, 36, }, + { 9, 1, 0, 3, 52, 36, }, + { 0, 1, 0, 3, 56, 68, }, + { 2, 1, 0, 3, 56, 36, }, + { 1, 1, 0, 3, 56, 50, }, + { 3, 1, 0, 3, 56, 40, }, + { 4, 1, 0, 3, 56, 66, }, + { 5, 1, 0, 3, 56, 36, }, + { 9, 1, 0, 3, 56, 36, }, + { 0, 1, 0, 3, 60, 68, }, + { 2, 1, 0, 3, 60, 36, }, + { 1, 1, 0, 3, 60, 50, }, + { 3, 1, 0, 3, 60, 40, }, + { 4, 1, 0, 3, 60, 66, }, + { 5, 1, 0, 3, 60, 36, }, + { 9, 1, 0, 3, 60, 36, }, + { 0, 1, 0, 3, 64, 66, }, + { 2, 1, 0, 3, 64, 36, }, + { 1, 1, 0, 3, 64, 50, }, + { 3, 1, 0, 3, 64, 40, }, + { 4, 1, 0, 3, 64, 66, }, + { 5, 1, 0, 3, 64, 36, }, + { 9, 1, 0, 3, 64, 36, }, + { 0, 1, 0, 3, 100, 64, }, + { 2, 1, 0, 3, 100, 36, }, + { 1, 1, 0, 3, 100, 70, }, + { 3, 1, 0, 3, 100, 64, }, + { 4, 1, 0, 3, 100, 66, }, + { 5, 1, 0, 3, 100, 36, }, + { 9, 1, 0, 3, 100, 127, }, + { 0, 1, 0, 3, 104, 68, }, + { 2, 1, 0, 3, 104, 36, }, + { 1, 1, 0, 3, 104, 70, }, + { 3, 1, 0, 3, 104, 68, }, + { 4, 1, 0, 3, 104, 66, }, + { 5, 1, 0, 3, 104, 36, }, + { 9, 1, 0, 3, 104, 127, }, + { 0, 1, 0, 3, 108, 68, }, + { 2, 1, 0, 3, 108, 36, }, + { 1, 1, 0, 3, 108, 70, }, + { 3, 1, 0, 3, 108, 68, }, + { 4, 1, 0, 3, 108, 66, }, + { 5, 1, 0, 3, 108, 36, }, + { 9, 1, 0, 3, 108, 127, }, + { 0, 1, 0, 3, 112, 68, }, + { 2, 1, 0, 3, 112, 36, }, + { 1, 1, 0, 3, 112, 70, }, + { 3, 1, 0, 3, 112, 68, }, + { 4, 1, 0, 3, 112, 66, }, + { 5, 1, 0, 3, 112, 36, }, + { 9, 1, 0, 3, 112, 127, }, + { 0, 1, 0, 3, 116, 68, }, + { 2, 1, 0, 3, 116, 36, }, + { 1, 1, 0, 3, 116, 70, }, + { 3, 1, 0, 3, 116, 68, }, + { 4, 1, 0, 3, 116, 66, }, + { 5, 1, 0, 3, 116, 36, }, + { 9, 1, 0, 3, 116, 127, }, + { 0, 1, 0, 3, 120, 68, }, + { 2, 1, 0, 3, 120, 36, }, + { 1, 1, 0, 3, 120, 70, }, + { 3, 1, 0, 3, 120, 127, }, + { 4, 1, 0, 3, 120, 66, }, + { 5, 1, 0, 3, 120, 127, }, + { 9, 1, 0, 3, 120, 127, }, + { 0, 1, 0, 3, 124, 68, }, + { 2, 1, 0, 3, 124, 36, }, + { 1, 1, 0, 3, 124, 70, }, + { 3, 1, 0, 3, 124, 127, }, + { 4, 1, 0, 3, 124, 66, }, + { 5, 1, 0, 3, 124, 127, }, + { 9, 1, 0, 3, 124, 127, }, + { 0, 1, 0, 3, 128, 68, }, + { 2, 1, 0, 3, 128, 36, }, + { 1, 1, 0, 3, 128, 70, }, + { 3, 1, 0, 3, 128, 127, }, + { 4, 1, 0, 3, 128, 66, }, + { 5, 1, 0, 3, 128, 127, }, + { 9, 1, 0, 3, 128, 127, }, + { 0, 1, 0, 3, 132, 68, }, + { 2, 1, 0, 3, 132, 36, }, + { 1, 1, 0, 3, 132, 70, }, + { 3, 1, 0, 3, 132, 68, }, + { 4, 1, 0, 3, 132, 66, }, + { 5, 1, 0, 3, 132, 36, }, + { 9, 1, 0, 3, 132, 127, }, + { 0, 1, 0, 3, 136, 68, }, + { 2, 1, 0, 3, 136, 36, }, + { 1, 1, 0, 3, 136, 70, }, + { 3, 1, 0, 3, 136, 68, }, + { 4, 1, 0, 3, 136, 66, }, + { 5, 1, 0, 3, 136, 36, }, + { 9, 1, 0, 3, 136, 127, }, + { 0, 1, 0, 3, 140, 58, }, + { 2, 1, 0, 3, 140, 36, }, + { 1, 1, 0, 3, 140, 70, }, + { 3, 1, 0, 3, 140, 58, }, + { 4, 1, 0, 3, 140, 66, }, + { 5, 1, 0, 3, 140, 36, }, + { 9, 1, 0, 3, 140, 127, }, + { 0, 1, 0, 3, 144, 68, }, + { 2, 1, 0, 3, 144, 127, }, + { 1, 1, 0, 3, 144, 70, }, + { 3, 1, 0, 3, 144, 68, }, + { 4, 1, 0, 3, 144, 66, }, + { 5, 1, 0, 3, 144, 127, }, + { 9, 1, 0, 3, 144, 127, }, + { 0, 1, 0, 3, 149, 76, }, + { 2, 1, 0, 3, 149, 4, }, + { 1, 1, 0, 3, 149, 127, }, + { 3, 1, 0, 3, 149, 76, }, + { 4, 1, 0, 3, 149, 62, }, + { 5, 1, 0, 3, 149, 76, }, + { 9, 1, 0, 3, 149, 68, }, + { 0, 1, 0, 3, 153, 76, }, + { 2, 1, 0, 3, 153, 4, }, + { 1, 1, 0, 3, 153, 127, }, + { 3, 1, 0, 3, 153, 76, }, + { 4, 1, 0, 3, 153, 62, }, + { 5, 1, 0, 3, 153, 76, }, + { 9, 1, 0, 3, 153, 68, }, + { 0, 1, 0, 3, 157, 76, }, + { 2, 1, 0, 3, 157, 4, }, + { 1, 1, 0, 3, 157, 127, }, + { 3, 1, 0, 3, 157, 76, }, + { 4, 1, 0, 3, 157, 62, }, + { 5, 1, 0, 3, 157, 76, }, + { 9, 1, 0, 3, 157, 68, }, + { 0, 1, 0, 3, 161, 76, }, + { 2, 1, 0, 3, 161, 4, }, + { 1, 1, 0, 3, 161, 127, }, + { 3, 1, 0, 3, 161, 76, }, + { 4, 1, 0, 3, 161, 62, }, + { 5, 1, 0, 3, 161, 76, }, + { 9, 1, 0, 3, 161, 72, }, + { 0, 1, 0, 3, 165, 76, }, + { 2, 1, 0, 3, 165, 4, }, + { 1, 1, 0, 3, 165, 127, }, + { 3, 1, 0, 3, 165, 76, }, + { 4, 1, 0, 3, 165, 62, }, + { 5, 1, 0, 3, 165, 76, }, + { 9, 1, 0, 3, 165, 72, }, + { 0, 1, 1, 2, 38, 66, }, + { 2, 1, 1, 2, 38, 64, }, + { 1, 1, 1, 2, 38, 64, }, + { 3, 1, 1, 2, 38, 64, }, + { 4, 1, 1, 2, 38, 64, }, + { 5, 1, 1, 2, 38, 64, }, + { 9, 1, 1, 2, 38, 64, }, + { 0, 1, 1, 2, 46, 72, }, + { 2, 1, 1, 2, 46, 64, }, + { 1, 1, 1, 2, 46, 64, }, + { 3, 1, 1, 2, 46, 64, }, + { 4, 1, 1, 2, 46, 70, }, + { 5, 1, 1, 2, 46, 64, }, + { 9, 1, 1, 2, 46, 64, }, + { 0, 1, 1, 2, 54, 72, }, + { 2, 1, 1, 2, 54, 64, }, + { 1, 1, 1, 2, 54, 64, }, + { 3, 1, 1, 2, 54, 64, }, + { 4, 1, 1, 2, 54, 72, }, + { 5, 1, 1, 2, 54, 64, }, + { 9, 1, 1, 2, 54, 64, }, + { 0, 1, 1, 2, 62, 60, }, + { 2, 1, 1, 2, 62, 64, }, + { 1, 1, 1, 2, 62, 62, }, + { 3, 1, 1, 2, 62, 60, }, + { 4, 1, 1, 2, 62, 60, }, + { 5, 1, 1, 2, 62, 64, }, + { 9, 1, 1, 2, 62, 64, }, + { 0, 1, 1, 2, 102, 60, }, + { 2, 1, 1, 2, 102, 64, }, + { 1, 1, 1, 2, 102, 72, }, + { 3, 1, 1, 2, 102, 60, }, + { 4, 1, 1, 2, 102, 64, }, + { 5, 1, 1, 2, 102, 64, }, + { 9, 1, 1, 2, 102, 127, }, + { 0, 1, 1, 2, 110, 72, }, + { 2, 1, 1, 2, 110, 64, }, + { 1, 1, 1, 2, 110, 72, }, + { 3, 1, 1, 2, 110, 72, }, + { 4, 1, 1, 2, 110, 72, }, + { 5, 1, 1, 2, 110, 64, }, + { 9, 1, 1, 2, 110, 127, }, + { 0, 1, 1, 2, 118, 72, }, + { 2, 1, 1, 2, 118, 64, }, + { 1, 1, 1, 2, 118, 72, }, + { 3, 1, 1, 2, 118, 127, }, + { 4, 1, 1, 2, 118, 72, }, + { 5, 1, 1, 2, 118, 127, }, + { 9, 1, 1, 2, 118, 127, }, + { 0, 1, 1, 2, 126, 72, }, + { 2, 1, 1, 2, 126, 64, }, + { 1, 1, 1, 2, 126, 72, }, + { 3, 1, 1, 2, 126, 127, }, + { 4, 1, 1, 2, 126, 72, }, + { 5, 1, 1, 2, 126, 127, }, + { 9, 1, 1, 2, 126, 127, }, + { 0, 1, 1, 2, 134, 72, }, + { 2, 1, 1, 2, 134, 64, }, + { 1, 1, 1, 2, 134, 72, }, + { 3, 1, 1, 2, 134, 72, }, + { 4, 1, 1, 2, 134, 72, }, + { 5, 1, 1, 2, 134, 64, }, + { 9, 1, 1, 2, 134, 127, }, + { 0, 1, 1, 2, 142, 72, }, + { 2, 1, 1, 2, 142, 127, }, + { 1, 1, 1, 2, 142, 72, }, + { 3, 1, 1, 2, 142, 72, }, + { 4, 1, 1, 2, 142, 72, }, + { 5, 1, 1, 2, 142, 127, }, + { 9, 1, 1, 2, 142, 127, }, + { 0, 1, 1, 2, 151, 72, }, + { 2, 1, 1, 2, 151, 28, }, + { 1, 1, 1, 2, 151, 127, }, + { 3, 1, 1, 2, 151, 72, }, + { 4, 1, 1, 2, 151, 72, }, + { 5, 1, 1, 2, 151, 72, }, + { 9, 1, 1, 2, 151, 72, }, + { 0, 1, 1, 2, 159, 72, }, + { 2, 1, 1, 2, 159, 28, }, + { 1, 1, 1, 2, 159, 127, }, + { 3, 1, 1, 2, 159, 72, }, + { 4, 1, 1, 2, 159, 72, }, + { 5, 1, 1, 2, 159, 72, }, + { 9, 1, 1, 2, 159, 72, }, + { 0, 1, 1, 3, 38, 60, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 50, }, + { 3, 1, 1, 3, 38, 40, }, + { 4, 1, 1, 3, 38, 54, }, + { 5, 1, 1, 3, 38, 40, }, + { 9, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 68, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 50, }, + { 3, 1, 1, 3, 46, 40, }, + { 4, 1, 1, 3, 46, 54, }, + { 5, 1, 1, 3, 46, 40, }, + { 9, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 68, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 50, }, + { 3, 1, 1, 3, 54, 40, }, + { 4, 1, 1, 3, 54, 66, }, + { 5, 1, 1, 3, 54, 40, }, + { 9, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 58, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 48, }, + { 3, 1, 1, 3, 62, 40, }, + { 4, 1, 1, 3, 62, 50, }, + { 5, 1, 1, 3, 62, 40, }, + { 9, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 56, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 70, }, + { 3, 1, 1, 3, 102, 56, }, + { 4, 1, 1, 3, 102, 54, }, + { 5, 1, 1, 3, 102, 40, }, + { 9, 1, 1, 3, 102, 127, }, + { 0, 1, 1, 3, 110, 68, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 70, }, + { 3, 1, 1, 3, 110, 68, }, + { 4, 1, 1, 3, 110, 66, }, + { 5, 1, 1, 3, 110, 40, }, + { 9, 1, 1, 3, 110, 127, }, + { 0, 1, 1, 3, 118, 68, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 70, }, + { 3, 1, 1, 3, 118, 127, }, + { 4, 1, 1, 3, 118, 66, }, + { 5, 1, 1, 3, 118, 127, }, + { 9, 1, 1, 3, 118, 127, }, + { 0, 1, 1, 3, 126, 68, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 70, }, + { 3, 1, 1, 3, 126, 127, }, + { 4, 1, 1, 3, 126, 66, }, + { 5, 1, 1, 3, 126, 127, }, + { 9, 1, 1, 3, 126, 127, }, + { 0, 1, 1, 3, 134, 68, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 70, }, + { 3, 1, 1, 3, 134, 68, }, + { 4, 1, 1, 3, 134, 66, }, + { 5, 1, 1, 3, 134, 40, }, + { 9, 1, 1, 3, 134, 127, }, + { 0, 1, 1, 3, 142, 68, }, + { 2, 1, 1, 3, 142, 127, }, + { 1, 1, 1, 3, 142, 70, }, + { 3, 1, 1, 3, 142, 68, }, + { 4, 1, 1, 3, 142, 66, }, + { 5, 1, 1, 3, 142, 127, }, + { 9, 1, 1, 3, 142, 127, }, + { 0, 1, 1, 3, 151, 72, }, + { 2, 1, 1, 3, 151, 4, }, + { 1, 1, 1, 3, 151, 127, }, + { 3, 1, 1, 3, 151, 72, }, + { 4, 1, 1, 3, 151, 66, }, + { 5, 1, 1, 3, 151, 72, }, + { 9, 1, 1, 3, 151, 64, }, + { 0, 1, 1, 3, 159, 72, }, + { 2, 1, 1, 3, 159, 4, }, + { 1, 1, 1, 3, 159, 127, }, + { 3, 1, 1, 3, 159, 72, }, + { 4, 1, 1, 3, 159, 66, }, + { 5, 1, 1, 3, 159, 72, }, + { 9, 1, 1, 3, 159, 72, }, + { 0, 1, 2, 4, 42, 68, }, + { 2, 1, 2, 4, 42, 64, }, + { 1, 1, 2, 4, 42, 64, }, + { 3, 1, 2, 4, 42, 64, }, + { 4, 1, 2, 4, 42, 60, }, + { 5, 1, 2, 4, 42, 64, }, + { 9, 1, 2, 4, 42, 64, }, + { 0, 1, 2, 4, 58, 60, }, + { 2, 1, 2, 4, 58, 64, }, + { 1, 1, 2, 4, 58, 64, }, + { 3, 1, 2, 4, 58, 60, }, + { 4, 1, 2, 4, 58, 56, }, + { 5, 1, 2, 4, 58, 64, }, + { 9, 1, 2, 4, 58, 64, }, + { 0, 1, 2, 4, 106, 60, }, + { 2, 1, 2, 4, 106, 64, }, + { 1, 1, 2, 4, 106, 72, }, + { 3, 1, 2, 4, 106, 60, }, + { 4, 1, 2, 4, 106, 58, }, + { 5, 1, 2, 4, 106, 64, }, + { 9, 1, 2, 4, 106, 127, }, + { 0, 1, 2, 4, 122, 72, }, + { 2, 1, 2, 4, 122, 64, }, + { 1, 1, 2, 4, 122, 72, }, + { 3, 1, 2, 4, 122, 127, }, + { 4, 1, 2, 4, 122, 68, }, + { 5, 1, 2, 4, 122, 127, }, + { 9, 1, 2, 4, 122, 127, }, + { 0, 1, 2, 4, 138, 72, }, + { 2, 1, 2, 4, 138, 127, }, + { 1, 1, 2, 4, 138, 72, }, + { 3, 1, 2, 4, 138, 72, }, + { 4, 1, 2, 4, 138, 70, }, + { 5, 1, 2, 4, 138, 127, }, + { 9, 1, 2, 4, 138, 127, }, + { 0, 1, 2, 4, 155, 72, }, + { 2, 1, 2, 4, 155, 28, }, + { 1, 1, 2, 4, 155, 127, }, + { 3, 1, 2, 4, 155, 72, }, + { 4, 1, 2, 4, 155, 62, }, + { 5, 1, 2, 4, 155, 72, }, + { 9, 1, 2, 4, 155, 72, }, + { 0, 1, 2, 5, 42, 56, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 50, }, + { 3, 1, 2, 5, 42, 40, }, + { 4, 1, 2, 5, 42, 50, }, + { 5, 1, 2, 5, 42, 40, }, + { 9, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 54, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 50, }, + { 3, 1, 2, 5, 58, 40, }, + { 4, 1, 2, 5, 58, 46, }, + { 5, 1, 2, 5, 58, 40, }, + { 9, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 48, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 72, }, + { 3, 1, 2, 5, 106, 48, }, + { 4, 1, 2, 5, 106, 50, }, + { 5, 1, 2, 5, 106, 40, }, + { 9, 1, 2, 5, 106, 127, }, + { 0, 1, 2, 5, 122, 70, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 72, }, + { 3, 1, 2, 5, 122, 127, }, + { 4, 1, 2, 5, 122, 62, }, + { 5, 1, 2, 5, 122, 127, }, + { 9, 1, 2, 5, 122, 127, }, + { 0, 1, 2, 5, 138, 70, }, + { 2, 1, 2, 5, 138, 127, }, + { 1, 1, 2, 5, 138, 72, }, + { 3, 1, 2, 5, 138, 70, }, + { 4, 1, 2, 5, 138, 62, }, + { 5, 1, 2, 5, 138, 127, }, + { 9, 1, 2, 5, 138, 127, }, + { 0, 1, 2, 5, 155, 72, }, + { 2, 1, 2, 5, 155, 4, }, + { 1, 1, 2, 5, 155, 127, }, + { 3, 1, 2, 5, 155, 72, }, + { 4, 1, 2, 5, 155, 52, }, + { 5, 1, 2, 5, 155, 72, }, + { 9, 1, 2, 5, 155, 66, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822c_txpwr_lmt_type5); + +static const u32 rtw8822c_dpk_afe_no_dpk[] = { + 0x18a4, BIT(7), 0, + 0x41a4, BIT(7), 0, + 0x1c38, MASKDWORD, 0xffa1005e, + 0x1830, MASKDWORD, 0x700b8041, + 0x1830, MASKDWORD, 0x70144041, + 0x1830, MASKDWORD, 0x70244041, + 0x1830, MASKDWORD, 0x70344041, + 0x1830, MASKDWORD, 0x70444041, + 0x1830, MASKDWORD, 0x705b8041, + 0x1830, MASKDWORD, 0x70644041, + 0x4130, MASKDWORD, 0x700b8041, + 0x4130, MASKDWORD, 0x70144041, + 0x4130, MASKDWORD, 0x70244041, + 0x4130, MASKDWORD, 0x70344041, + 0x4130, MASKDWORD, 0x70444041, + 0x4130, MASKDWORD, 0x705b8041, + 0x4130, MASKDWORD, 0x70644041, + 0x1830, MASKDWORD, 0x707b8041, + 0x1830, MASKDWORD, 0x708b8041, + 0x1830, MASKDWORD, 0x709b8041, + 0x1830, MASKDWORD, 0x70ab8041, + 0x1830, MASKDWORD, 0x70bb8041, + 0x1830, MASKDWORD, 0x70cb8041, + 0x1830, MASKDWORD, 0x70db8041, + 0x1830, MASKDWORD, 0x70eb8041, + 0x1830, MASKDWORD, 0x70fb8041, + 0x4130, MASKDWORD, 0x707b8041, + 0x4130, MASKDWORD, 0x708b8041, + 0x4130, MASKDWORD, 0x709b8041, + 0x4130, MASKDWORD, 0x70ab8041, + 0x4130, MASKDWORD, 0x70bb8041, + 0x4130, MASKDWORD, 0x70cb8041, + 0x4130, MASKDWORD, 0x70db8041, + 0x4130, MASKDWORD, 0x70eb8041, + 0x4130, MASKDWORD, 0x70fb8041, +}; + +RTW_DECL_TABLE_DPK(rtw8822c_dpk_afe_no_dpk); + +static const u32 rtw8822c_dpk_afe_is_dpk[] = { + 0x1c38, MASKDWORD, 0xFFFFFFFF, + 0x1830, MASKDWORD, 0x700f0001, + 0x1830, MASKDWORD, 0x700f0001, + 0x1830, MASKDWORD, 0x701f0001, + 0x1830, MASKDWORD, 0x702f0001, + 0x1830, MASKDWORD, 0x703f0001, + 0x1830, MASKDWORD, 0x704f0001, + 0x1830, MASKDWORD, 0x705f0001, + 0x1830, MASKDWORD, 0x706f0001, + 0x1830, MASKDWORD, 0x707f0001, + 0x1830, MASKDWORD, 0x708f0001, + 0x1830, MASKDWORD, 0x709f0001, + 0x1830, MASKDWORD, 0x70af0001, + 0x1830, MASKDWORD, 0x70bf0001, + 0x1830, MASKDWORD, 0x70cf0001, + 0x1830, MASKDWORD, 0x70df0001, + 0x1830, MASKDWORD, 0x70ef0001, + 0x1830, MASKDWORD, 0x70ff0001, + 0x1830, MASKDWORD, 0x70ff0001, + 0x4130, MASKDWORD, 0x700f0001, + 0x4130, MASKDWORD, 0x700f0001, + 0x4130, MASKDWORD, 0x701f0001, + 0x4130, MASKDWORD, 0x702f0001, + 0x4130, MASKDWORD, 0x703f0001, + 0x4130, MASKDWORD, 0x704f0001, + 0x4130, MASKDWORD, 0x705f0001, + 0x4130, MASKDWORD, 0x706f0001, + 0x4130, MASKDWORD, 0x707f0001, + 0x4130, MASKDWORD, 0x708f0001, + 0x4130, MASKDWORD, 0x709f0001, + 0x4130, MASKDWORD, 0x70af0001, + 0x4130, MASKDWORD, 0x70bf0001, + 0x4130, MASKDWORD, 0x70cf0001, + 0x4130, MASKDWORD, 0x70df0001, + 0x4130, MASKDWORD, 0x70ef0001, + 0x4130, MASKDWORD, 0x70ff0001, + 0x4130, MASKDWORD, 0x70ff0001, + 0x18a4, BIT(7), 1, + 0x41a4, BIT(7), 1, +}; + +RTW_DECL_TABLE_DPK(rtw8822c_dpk_afe_is_dpk); + +static const u32 rtw8822c_dpk_mac_bb[] = { + 0x1e24, BIT(17), 0x1, + 0x1d58, GENMASK(11, 3), 0x1ff, + 0x1864, BIT(31), 0x1, + 0x4164, BIT(31), 0x1, + 0x180c, BIT(27), 0x1, + 0x410c, BIT(27), 0x1, + 0x186c, BIT(7), 0x1, + 0x416c, BIT(7), 0x1, + 0x180c, GENMASK(1, 0), 0x0, + 0x410c, GENMASK(1, 0), 0x0, + 0x1a14, GENMASK(9, 8), 0x3, + 0x80c, GENMASK(3, 0), 0x8, + 0x824, GENMASK(19, 16), 0x3, + 0x824, GENMASK(27, 24), 0x3, +}; + +RTW_DECL_TABLE_DPK(rtw8822c_dpk_mac_bb); + +static const u32 rtw8822c_array_mp_cal_init[] = { + 0x1b00, 0x00000008, + 0x1b00, 0x00A70008, + 0x1b00, 0x00150008, + 0x1b00, 0x00000008, + 0x1b04, 0xE2462952, + 0x1b08, 0x00000080, + 0x1b0c, 0x00000000, + 0x1b10, 0x00010C00, + 0x1b14, 0x00000000, + 0x1b18, 0x00292903, + 0x1b1c, 0xA218FC32, + 0x1b20, 0x01040008, + 0x1b24, 0x00060008, + 0x1b28, 0x00060300, + 0x1b2C, 0x00180018, + 0x1b30, 0x40000000, + 0x1b34, 0x00000800, + 0x1b38, 0x40000000, + 0x1b3C, 0x40000000, + 0x1b98, 0x00000000, + 0x1b9c, 0x00000000, + 0x1bc0, 0x01000000, + 0x1bcc, 0x00000000, + 0x1bd8, 0xe0000001, + 0x1be4, 0x00000000, + 0x1bec, 0x40000000, + 0x1b40, 0x40000000, + 0x1b44, 0x20004064, + 0x1b48, 0x0005002D, + 0x1b4c, 0x00000000, + 0x1b60, 0x1F100000, + 0x1b64, 0x12000000, + 0x1b4c, 0x00000000, + 0x1b4c, 0x008a0000, + 0x1b50, 0x000003BE, + 0x1b4c, 0x018a0000, + 0x1b50, 0x0000057A, + 0x1b4c, 0x028a0000, + 0x1b50, 0x000006C8, + 0x1b4c, 0x038a0000, + 0x1b50, 0x000007E0, + 0x1b4c, 0x048a0000, + 0x1b50, 0x000008D5, + 0x1b4c, 0x058a0000, + 0x1b50, 0x000009B2, + 0x1b4c, 0x068a0000, + 0x1b50, 0x00000A7D, + 0x1b4c, 0x078a0000, + 0x1b50, 0x00000B3A, + 0x1b4c, 0x088a0000, + 0x1b50, 0x00000BEB, + 0x1b4c, 0x098a0000, + 0x1b50, 0x00000C92, + 0x1b4c, 0x0A8a0000, + 0x1b50, 0x00000D31, + 0x1b4c, 0x0B8a0000, + 0x1b50, 0x00000DC9, + 0x1b4c, 0x0C8a0000, + 0x1b50, 0x00000E5A, + 0x1b4c, 0x0D8a0000, + 0x1b50, 0x00000EE6, + 0x1b4c, 0x0E8a0000, + 0x1b50, 0x00000F6D, + 0x1b4c, 0x0F8a0000, + 0x1b50, 0x00000FF0, + 0x1b4c, 0x108a0000, + 0x1b50, 0x0000106F, + 0x1b4c, 0x118a0000, + 0x1b50, 0x000010E9, + 0x1b4c, 0x128a0000, + 0x1b50, 0x00001161, + 0x1b4c, 0x138a0000, + 0x1b50, 0x000011D5, + 0x1b4c, 0x148a0000, + 0x1b50, 0x00001247, + 0x1b4c, 0x158a0000, + 0x1b50, 0x000012B5, + 0x1b4c, 0x168a0000, + 0x1b50, 0x00001322, + 0x1b4c, 0x178a0000, + 0x1b50, 0x0000138B, + 0x1b4c, 0x188a0000, + 0x1b50, 0x000013F3, + 0x1b4c, 0x198a0000, + 0x1b50, 0x00001459, + 0x1b4c, 0x1A8a0000, + 0x1b50, 0x000014BD, + 0x1b4c, 0x1B8a0000, + 0x1b50, 0x0000151E, + 0x1b4c, 0x1C8a0000, + 0x1b50, 0x0000157F, + 0x1b4c, 0x1D8a0000, + 0x1b50, 0x000015DD, + 0x1b4c, 0x1E8a0000, + 0x1b50, 0x0000163A, + 0x1b4c, 0x1F8a0000, + 0x1b50, 0x00001695, + 0x1b4c, 0x208a0000, + 0x1b50, 0x000016EF, + 0x1b4c, 0x218a0000, + 0x1b50, 0x00001748, + 0x1b4c, 0x228a0000, + 0x1b50, 0x0000179F, + 0x1b4c, 0x238a0000, + 0x1b50, 0x000017F5, + 0x1b4c, 0x248a0000, + 0x1b50, 0x0000184A, + 0x1b4c, 0x258a0000, + 0x1b50, 0x0000189E, + 0x1b4c, 0x268a0000, + 0x1b50, 0x000018F1, + 0x1b4c, 0x278a0000, + 0x1b50, 0x00001942, + 0x1b4c, 0x288a0000, + 0x1b50, 0x00001993, + 0x1b4c, 0x298a0000, + 0x1b50, 0x000019E2, + 0x1b4c, 0x2A8a0000, + 0x1b50, 0x00001A31, + 0x1b4c, 0x2B8a0000, + 0x1b50, 0x00001A7F, + 0x1b4c, 0x2C8a0000, + 0x1b50, 0x00001ACC, + 0x1b4c, 0x2D8a0000, + 0x1b50, 0x00001B18, + 0x1b4c, 0x2E8a0000, + 0x1b50, 0x00001B63, + 0x1b4c, 0x2F8a0000, + 0x1b50, 0x00001BAD, + 0x1b4c, 0x308a0000, + 0x1b50, 0x00001BF7, + 0x1b4c, 0x318a0000, + 0x1b50, 0x00001C40, + 0x1b4c, 0x328a0000, + 0x1b50, 0x00001C88, + 0x1b4c, 0x338a0000, + 0x1b50, 0x00001CCF, + 0x1b4c, 0x348a0000, + 0x1b50, 0x00001D16, + 0x1b4c, 0x358a0000, + 0x1b50, 0x00001D5C, + 0x1b4c, 0x368a0000, + 0x1b50, 0x00001DA2, + 0x1b4c, 0x378a0000, + 0x1b50, 0x00001DE6, + 0x1b4c, 0x388a0000, + 0x1b50, 0x00001E2B, + 0x1b4c, 0x398a0000, + 0x1b50, 0x00001E6E, + 0x1b4c, 0x3A8a0000, + 0x1b50, 0x00001EB1, + 0x1b4c, 0x3B8a0000, + 0x1b50, 0x00001EF4, + 0x1b4c, 0x3C8a0000, + 0x1b50, 0x00001F35, + 0x1b4c, 0x3D8a0000, + 0x1b50, 0x00001F77, + 0x1b4c, 0x3E8a0000, + 0x1b50, 0x00001FB8, + 0x1b4c, 0x3F8a0000, + 0x1b50, 0x00001FF8, + 0x1b4c, 0x00000000, + 0x1b50, 0x00000000, + 0x1b58, 0x00890000, + 0x1b5C, 0x3C6B3FFF, + 0x1b58, 0x02890000, + 0x1b5C, 0x35D9390A, + 0x1b58, 0x04890000, + 0x1b5C, 0x2FFE32D6, + 0x1b58, 0x06890000, + 0x1b5C, 0x2AC62D4F, + 0x1b58, 0x08890000, + 0x1b5C, 0x261F2862, + 0x1b58, 0x0A890000, + 0x1b5C, 0x21FA23FD, + 0x1b58, 0x0C890000, + 0x1b5C, 0x1E482013, + 0x1b58, 0x0E890000, + 0x1b5C, 0x1AFD1C96, + 0x1b58, 0x10890000, + 0x1b5C, 0x180E197B, + 0x1b58, 0x12890000, + 0x1b5C, 0x157016B5, + 0x1b58, 0x14890000, + 0x1b5C, 0x131B143D, + 0x1b58, 0x16890000, + 0x1b5C, 0x1107120A, + 0x1b58, 0x18890000, + 0x1b5C, 0x0F2D1013, + 0x1b58, 0x1A890000, + 0x1b5C, 0x0D870E54, + 0x1b58, 0x1C890000, + 0x1b5C, 0x0C0E0CC5, + 0x1b58, 0x1E890000, + 0x1b5C, 0x0ABF0B62, + 0x1b58, 0x20890000, + 0x1b5C, 0x09930A25, + 0x1b58, 0x22890000, + 0x1b5C, 0x0889090A, + 0x1b58, 0x24890000, + 0x1b5C, 0x079B080F, + 0x1b58, 0x26890000, + 0x1b5C, 0x06C7072E, + 0x1b58, 0x28890000, + 0x1b5C, 0x060B0666, + 0x1b58, 0x2A890000, + 0x1b5C, 0x056305B4, + 0x1b58, 0x2C890000, + 0x1b5C, 0x04CD0515, + 0x1b58, 0x2E890000, + 0x1b5C, 0x04470488, + 0x1b58, 0x30890000, + 0x1b5C, 0x03D0040A, + 0x1b58, 0x32890000, + 0x1b5C, 0x03660399, + 0x1b58, 0x34890000, + 0x1b5C, 0x03070335, + 0x1b58, 0x36890000, + 0x1b5C, 0x02B302DC, + 0x1b58, 0x38890000, + 0x1b5C, 0x0268028C, + 0x1b58, 0x3A890000, + 0x1b5C, 0x02250245, + 0x1b58, 0x3C890000, + 0x1b5C, 0x01E90206, + 0x1b58, 0x3E890000, + 0x1b5C, 0x01B401CE, + 0x1b58, 0x40890000, + 0x1b5C, 0x0185019C, + 0x1b58, 0x42890000, + 0x1b5C, 0x015A016F, + 0x1b58, 0x44890000, + 0x1b5C, 0x01350147, + 0x1b58, 0x46890000, + 0x1b5C, 0x01130123, + 0x1b58, 0x48890000, + 0x1b5C, 0x00F50104, + 0x1b58, 0x4A890000, + 0x1b5C, 0x00DA00E7, + 0x1b58, 0x4C890000, + 0x1b5C, 0x00C300CE, + 0x1b58, 0x4E890000, + 0x1b5C, 0x00AE00B8, + 0x1b58, 0x50890000, + 0x1b5C, 0x009B00A4, + 0x1b58, 0x52890000, + 0x1b5C, 0x008A0092, + 0x1b58, 0x54890000, + 0x1b5C, 0x007B0082, + 0x1b58, 0x56890000, + 0x1b5C, 0x006E0074, + 0x1b58, 0x58890000, + 0x1b5C, 0x00620067, + 0x1b58, 0x5A890000, + 0x1b5C, 0x0057005C, + 0x1b58, 0x5C890000, + 0x1b5C, 0x004E0052, + 0x1b58, 0x5E890000, + 0x1b5C, 0x00450049, + 0x1b58, 0x60890000, + 0x1b5C, 0x003E0041, + 0x1b58, 0x62890000, + 0x1b5C, 0x0037003A, + 0x1b58, 0x62010000, + 0x1b00, 0x0000000A, + 0x1b00, 0x00A7000A, + 0x1b00, 0x0015000A, + 0x1b00, 0x0000000A, + 0x1b04, 0xE2462952, + 0x1b08, 0x00000080, + 0x1b0c, 0x00000000, + 0x1b10, 0x00010C00, + 0x1b14, 0x00000000, + 0x1b18, 0x00292903, + 0x1b1c, 0xA218FC32, + 0x1b20, 0x01040008, + 0x1b24, 0x00060008, + 0x1b28, 0x00060300, + 0x1b2C, 0x00180018, + 0x1b30, 0x40000000, + 0x1b34, 0x00000800, + 0x1b38, 0x40000000, + 0x1b3C, 0x40000000, + 0x1b98, 0x00000000, + 0x1b9c, 0x00000000, + 0x1bc0, 0x01000000, + 0x1bcc, 0x00000000, + 0x1bd8, 0xe0000001, + 0x1be4, 0x00000000, + 0x1bec, 0x40000000, + 0x1b60, 0x1F100000, + 0x1b64, 0x12000000, + 0x1b58, 0x00890000, + 0x1b5C, 0x3C6B3FFF, + 0x1b58, 0x02890000, + 0x1b5C, 0x35D9390A, + 0x1b58, 0x04890000, + 0x1b5C, 0x2FFE32D6, + 0x1b58, 0x06890000, + 0x1b5C, 0x2AC62D4F, + 0x1b58, 0x08890000, + 0x1b5C, 0x261F2862, + 0x1b58, 0x0A890000, + 0x1b5C, 0x21FA23FD, + 0x1b58, 0x0C890000, + 0x1b5C, 0x1E482013, + 0x1b58, 0x0E890000, + 0x1b5C, 0x1AFD1C96, + 0x1b58, 0x10890000, + 0x1b5C, 0x180E197B, + 0x1b58, 0x12890000, + 0x1b5C, 0x157016B5, + 0x1b58, 0x14890000, + 0x1b5C, 0x131B143D, + 0x1b58, 0x16890000, + 0x1b5C, 0x1107120A, + 0x1b58, 0x18890000, + 0x1b5C, 0x0F2D1013, + 0x1b58, 0x1A890000, + 0x1b5C, 0x0D870E54, + 0x1b58, 0x1C890000, + 0x1b5C, 0x0C0E0CC5, + 0x1b58, 0x1E890000, + 0x1b5C, 0x0ABF0B62, + 0x1b58, 0x20890000, + 0x1b5C, 0x09930A25, + 0x1b58, 0x22890000, + 0x1b5C, 0x0889090A, + 0x1b58, 0x24890000, + 0x1b5C, 0x079B080F, + 0x1b58, 0x26890000, + 0x1b5C, 0x06C7072E, + 0x1b58, 0x28890000, + 0x1b5C, 0x060B0666, + 0x1b58, 0x2A890000, + 0x1b5C, 0x056305B4, + 0x1b58, 0x2C890000, + 0x1b5C, 0x04CD0515, + 0x1b58, 0x2E890000, + 0x1b5C, 0x04470488, + 0x1b58, 0x30890000, + 0x1b5C, 0x03D0040A, + 0x1b58, 0x32890000, + 0x1b5C, 0x03660399, + 0x1b58, 0x34890000, + 0x1b5C, 0x03070335, + 0x1b58, 0x36890000, + 0x1b5C, 0x02B302DC, + 0x1b58, 0x38890000, + 0x1b5C, 0x0268028C, + 0x1b58, 0x3A890000, + 0x1b5C, 0x02250245, + 0x1b58, 0x3C890000, + 0x1b5C, 0x01E90206, + 0x1b58, 0x3E890000, + 0x1b5C, 0x01B401CE, + 0x1b58, 0x40890000, + 0x1b5C, 0x0185019C, + 0x1b58, 0x42890000, + 0x1b5C, 0x015A016F, + 0x1b58, 0x44890000, + 0x1b5C, 0x01350147, + 0x1b58, 0x46890000, + 0x1b5C, 0x01130123, + 0x1b58, 0x48890000, + 0x1b5C, 0x00F50104, + 0x1b58, 0x4A890000, + 0x1b5C, 0x00DA00E7, + 0x1b58, 0x4C890000, + 0x1b5C, 0x00C300CE, + 0x1b58, 0x4E890000, + 0x1b5C, 0x00AE00B8, + 0x1b58, 0x50890000, + 0x1b5C, 0x009B00A4, + 0x1b58, 0x52890000, + 0x1b5C, 0x008A0092, + 0x1b58, 0x54890000, + 0x1b5C, 0x007B0082, + 0x1b58, 0x56890000, + 0x1b5C, 0x006E0074, + 0x1b58, 0x58890000, + 0x1b5C, 0x00620067, + 0x1b58, 0x5A890000, + 0x1b5C, 0x0057005C, + 0x1b58, 0x5C890000, + 0x1b5C, 0x004E0052, + 0x1b58, 0x5E890000, + 0x1b5C, 0x00450049, + 0x1b58, 0x60890000, + 0x1b5C, 0x003E0041, + 0x1b58, 0x62890000, + 0x1b5C, 0x0037003A, + 0x1b58, 0x62010000, + 0x1b00, 0x0000000C, + 0x1bd4, 0x000000F0, + 0x1bb8, 0x20202020, + 0x1bbc, 0x20202020, + 0x1bc0, 0x20202020, + 0x1bc4, 0x20202020, + 0x1bc8, 0x04040404, + 0x1bcc, 0x04040404, + 0x1bd0, 0x04040404, + 0x1bd8, 0x04040404, + 0x1bdc, 0x20202020, + 0x1be0, 0x04040404, + 0x1be4, 0x77472F17, + 0x1be8, 0xEFBFA78F, + 0x1bec, 0x00000000, + 0x1bf0, 0x1F1F1939, + 0x1b04, 0x0000005B, + 0x1b08, 0xB000C000, + 0x1b5c, 0x0000005B, + 0x1b60, 0xB000C000, + 0x1bb4, 0x20000000, + 0x1b00, 0x00000008, + 0x1b80, 0x00000007, + 0x1b80, 0x00080005, + 0x1b80, 0x00080007, + 0x1b80, 0x80000015, + 0x1b80, 0x80000017, + 0x1b80, 0x09080025, + 0x1b80, 0x09080027, + 0x1b80, 0x0f020035, + 0x1b80, 0x0f020037, + 0x1b80, 0x00220045, + 0x1b80, 0x00220047, + 0x1b80, 0x00040055, + 0x1b80, 0x00040057, + 0x1b80, 0x05c00065, + 0x1b80, 0x05c00067, + 0x1b80, 0x00070075, + 0x1b80, 0x00070077, + 0x1b80, 0x64020085, + 0x1b80, 0x64020087, + 0x1b80, 0x00020095, + 0x1b80, 0x00020097, + 0x1b80, 0x000400a5, + 0x1b80, 0x000400a7, + 0x1b80, 0x4a0000b5, + 0x1b80, 0x4a0000b7, + 0x1b80, 0x4b0400c5, + 0x1b80, 0x4b0400c7, + 0x1b80, 0x860300d5, + 0x1b80, 0x860300d7, + 0x1b80, 0x400900e5, + 0x1b80, 0x400900e7, + 0x1b80, 0xe02700f5, + 0x1b80, 0xe02700f7, + 0x1b80, 0x4b050105, + 0x1b80, 0x4b050107, + 0x1b80, 0x87030115, + 0x1b80, 0x87030117, + 0x1b80, 0x400b0125, + 0x1b80, 0x400b0127, + 0x1b80, 0xe0270135, + 0x1b80, 0xe0270137, + 0x1b80, 0x4b060145, + 0x1b80, 0x4b060147, + 0x1b80, 0x88030155, + 0x1b80, 0x88030157, + 0x1b80, 0x400d0165, + 0x1b80, 0x400d0167, + 0x1b80, 0xe0270175, + 0x1b80, 0xe0270177, + 0x1b80, 0x4b000185, + 0x1b80, 0x4b000187, + 0x1b80, 0x00070195, + 0x1b80, 0x00070197, + 0x1b80, 0x4c0001a5, + 0x1b80, 0x4c0001a7, + 0x1b80, 0x000401b5, + 0x1b80, 0x000401b7, + 0x1b80, 0x400801c5, + 0x1b80, 0x400801c7, + 0x1b80, 0x505501d5, + 0x1b80, 0x505501d7, + 0x1b80, 0x090a01e5, + 0x1b80, 0x090a01e7, + 0x1b80, 0x0ffe01f5, + 0x1b80, 0x0ffe01f7, + 0x1b80, 0x00220205, + 0x1b80, 0x00220207, + 0x1b80, 0x00040215, + 0x1b80, 0x00040217, + 0x1b80, 0x05c00225, + 0x1b80, 0x05c00227, + 0x1b80, 0x00070235, + 0x1b80, 0x00070237, + 0x1b80, 0x64000245, + 0x1b80, 0x64000247, + 0x1b80, 0x00020255, + 0x1b80, 0x00020257, + 0x1b80, 0x30000265, + 0x1b80, 0x30000267, + 0x1b80, 0xa5110275, + 0x1b80, 0xa5110277, + 0x1b80, 0xe3ef0285, + 0x1b80, 0xe3ef0287, + 0x1b80, 0xf01f0295, + 0x1b80, 0xf01f0297, + 0x1b80, 0xf11f02a5, + 0x1b80, 0xf11f02a7, + 0x1b80, 0xf21f02b5, + 0x1b80, 0xf21f02b7, + 0x1b80, 0xf31f02c5, + 0x1b80, 0xf31f02c7, + 0x1b80, 0xf41f02d5, + 0x1b80, 0xf41f02d7, + 0x1b80, 0xf51f02e5, + 0x1b80, 0xf51f02e7, + 0x1b80, 0xf61f02f5, + 0x1b80, 0xf61f02f7, + 0x1b80, 0xf71f0305, + 0x1b80, 0xf71f0307, + 0x1b80, 0xf81f0315, + 0x1b80, 0xf81f0317, + 0x1b80, 0xf91f0325, + 0x1b80, 0xf91f0327, + 0x1b80, 0xfa1f0335, + 0x1b80, 0xfa1f0337, + 0x1b80, 0xfb1f0345, + 0x1b80, 0xfb1f0347, + 0x1b80, 0xfc1f0355, + 0x1b80, 0xfc1f0357, + 0x1b80, 0xfd1f0365, + 0x1b80, 0xfd1f0367, + 0x1b80, 0xfe1f0375, + 0x1b80, 0xfe1f0377, + 0x1b80, 0xf11f0385, + 0x1b80, 0xf11f0387, + 0x1b80, 0xf21f0395, + 0x1b80, 0xf21f0397, + 0x1b80, 0xf31f03a5, + 0x1b80, 0xf31f03a7, + 0x1b80, 0xf41f03b5, + 0x1b80, 0xf41f03b7, + 0x1b80, 0xf51f03c5, + 0x1b80, 0xf51f03c7, + 0x1b80, 0xf61f03d5, + 0x1b80, 0xf61f03d7, + 0x1b80, 0xf71f03e5, + 0x1b80, 0xf71f03e7, + 0x1b80, 0xf81f03f5, + 0x1b80, 0xf81f03f7, + 0x1b80, 0xf91f0405, + 0x1b80, 0xf91f0407, + 0x1b80, 0xfa1f0415, + 0x1b80, 0xfa1f0417, + 0x1b80, 0xfb1f0425, + 0x1b80, 0xfb1f0427, + 0x1b80, 0xfc1f0435, + 0x1b80, 0xfc1f0437, + 0x1b80, 0xfd1f0445, + 0x1b80, 0xfd1f0447, + 0x1b80, 0xfe1f0455, + 0x1b80, 0xfe1f0457, + 0x1b80, 0xff1f0465, + 0x1b80, 0xff1f0467, + 0x1b80, 0x00010475, + 0x1b80, 0x00010477, + 0x1b80, 0x30660485, + 0x1b80, 0x30660487, + 0x1b80, 0x307e0495, + 0x1b80, 0x307e0497, + 0x1b80, 0x308204a5, + 0x1b80, 0x308204a7, + 0x1b80, 0x310c04b5, + 0x1b80, 0x310c04b7, + 0x1b80, 0x308904c5, + 0x1b80, 0x308904c7, + 0x1b80, 0x309804d5, + 0x1b80, 0x309804d7, + 0x1b80, 0x30a704e5, + 0x1b80, 0x30a704e7, + 0x1b80, 0x308804f5, + 0x1b80, 0x308804f7, + 0x1b80, 0x30970505, + 0x1b80, 0x30970507, + 0x1b80, 0x30a60515, + 0x1b80, 0x30a60517, + 0x1b80, 0x31100525, + 0x1b80, 0x31100527, + 0x1b80, 0x311b0535, + 0x1b80, 0x311b0537, + 0x1b80, 0x31260545, + 0x1b80, 0x31260547, + 0x1b80, 0x31ae0555, + 0x1b80, 0x31ae0557, + 0x1b80, 0x318b0565, + 0x1b80, 0x318b0567, + 0x1b80, 0x31cb0575, + 0x1b80, 0x31cb0577, + 0x1b80, 0x307e0585, + 0x1b80, 0x307e0587, + 0x1b80, 0x310a0595, + 0x1b80, 0x310a0597, + 0x1b80, 0x31db05a5, + 0x1b80, 0x31db05a7, + 0x1b80, 0x31f405b5, + 0x1b80, 0x31f405b7, + 0x1b80, 0x320e05c5, + 0x1b80, 0x320e05c7, + 0x1b80, 0x321605d5, + 0x1b80, 0x321605d7, + 0x1b80, 0x321e05e5, + 0x1b80, 0x321e05e7, + 0x1b80, 0x322605f5, + 0x1b80, 0x322605f7, + 0x1b80, 0x322e0605, + 0x1b80, 0x322e0607, + 0x1b80, 0x323d0615, + 0x1b80, 0x323d0617, + 0x1b80, 0x324c0625, + 0x1b80, 0x324c0627, + 0x1b80, 0x32520635, + 0x1b80, 0x32520637, + 0x1b80, 0x32580645, + 0x1b80, 0x32580647, + 0x1b80, 0x325e0655, + 0x1b80, 0x325e0657, + 0x1b80, 0xe3880665, + 0x1b80, 0xe3880667, + 0x1b80, 0x4d040675, + 0x1b80, 0x4d040677, + 0x1b80, 0x20800685, + 0x1b80, 0x20800687, + 0x1b80, 0x00000695, + 0x1b80, 0x00000697, + 0x1b80, 0x4d0006a5, + 0x1b80, 0x4d0006a7, + 0x1b80, 0x550706b5, + 0x1b80, 0x550706b7, + 0x1b80, 0xe38006c5, + 0x1b80, 0xe38006c7, + 0x1b80, 0xe38006d5, + 0x1b80, 0xe38006d7, + 0x1b80, 0x4d0406e5, + 0x1b80, 0x4d0406e7, + 0x1b80, 0x208806f5, + 0x1b80, 0x208806f7, + 0x1b80, 0x02000705, + 0x1b80, 0x02000707, + 0x1b80, 0x4d000715, + 0x1b80, 0x4d000717, + 0x1b80, 0x550f0725, + 0x1b80, 0x550f0727, + 0x1b80, 0xe3800735, + 0x1b80, 0xe3800737, + 0x1b80, 0x4f020745, + 0x1b80, 0x4f020747, + 0x1b80, 0x4e000755, + 0x1b80, 0x4e000757, + 0x1b80, 0x53020765, + 0x1b80, 0x53020767, + 0x1b80, 0x52010775, + 0x1b80, 0x52010777, + 0x1b80, 0xe3840785, + 0x1b80, 0xe3840787, + 0x1b80, 0x4d080795, + 0x1b80, 0x4d080797, + 0x1b80, 0x571007a5, + 0x1b80, 0x571007a7, + 0x1b80, 0x570007b5, + 0x1b80, 0x570007b7, + 0x1b80, 0x4d0007c5, + 0x1b80, 0x4d0007c7, + 0x1b80, 0x000107d5, + 0x1b80, 0x000107d7, + 0x1b80, 0xe38807e5, + 0x1b80, 0xe38807e7, + 0x1b80, 0x0bbd07f5, + 0x1b80, 0x0bbd07f7, + 0x1b80, 0xe3e20805, + 0x1b80, 0xe3e20807, + 0x1b80, 0x00010815, + 0x1b80, 0x00010817, + 0x1b80, 0x62060825, + 0x1b80, 0x62060827, + 0x1b80, 0xe3880835, + 0x1b80, 0xe3880837, + 0x1b80, 0x0bbd0845, + 0x1b80, 0x0bbd0847, + 0x1b80, 0xe3e20855, + 0x1b80, 0xe3e20857, + 0x1b80, 0x00010865, + 0x1b80, 0x00010867, + 0x1b80, 0x00010875, + 0x1b80, 0x00010877, + 0x1b80, 0x62060885, + 0x1b80, 0x62060887, + 0x1b80, 0x30bc0895, + 0x1b80, 0x30bc0897, + 0x1b80, 0x002608a5, + 0x1b80, 0x002608a7, + 0x1b80, 0xe3e208b5, + 0x1b80, 0xe3e208b7, + 0x1b80, 0x000208c5, + 0x1b80, 0x000208c7, + 0x1b80, 0x54ec08d5, + 0x1b80, 0x54ec08d7, + 0x1b80, 0x0ba608e5, + 0x1b80, 0x0ba608e7, + 0x1b80, 0x002608f5, + 0x1b80, 0x002608f7, + 0x1b80, 0xe3e20905, + 0x1b80, 0xe3e20907, + 0x1b80, 0x00020915, + 0x1b80, 0x00020917, + 0x1b80, 0xf7f50925, + 0x1b80, 0xf7f50927, + 0x1b80, 0x00300935, + 0x1b80, 0x00300937, + 0x1b80, 0x63c30945, + 0x1b80, 0x63c30947, + 0x1b80, 0x00020955, + 0x1b80, 0x00020957, + 0x1b80, 0x318b0965, + 0x1b80, 0x318b0967, + 0x1b80, 0x62060975, + 0x1b80, 0x62060977, + 0x1b80, 0x30b40985, + 0x1b80, 0x30b40987, + 0x1b80, 0x00240995, + 0x1b80, 0x00240997, + 0x1b80, 0xe3e209a5, + 0x1b80, 0xe3e209a7, + 0x1b80, 0x000209b5, + 0x1b80, 0x000209b7, + 0x1b80, 0x54ea09c5, + 0x1b80, 0x54ea09c7, + 0x1b80, 0x0ba609d5, + 0x1b80, 0x0ba609d7, + 0x1b80, 0x002409e5, + 0x1b80, 0x002409e7, + 0x1b80, 0xe3e209f5, + 0x1b80, 0xe3e209f7, + 0x1b80, 0x00020a05, + 0x1b80, 0x00020a07, + 0x1b80, 0xf8e60a15, + 0x1b80, 0xf8e60a17, + 0x1b80, 0x00300a25, + 0x1b80, 0x00300a27, + 0x1b80, 0x63c30a35, + 0x1b80, 0x63c30a37, + 0x1b80, 0x00020a45, + 0x1b80, 0x00020a47, + 0x1b80, 0x318b0a55, + 0x1b80, 0x318b0a57, + 0x1b80, 0x62060a65, + 0x1b80, 0x62060a67, + 0x1b80, 0x6c100a75, + 0x1b80, 0x6c100a77, + 0x1b80, 0x6d0f0a85, + 0x1b80, 0x6d0f0a87, + 0x1b80, 0xe3880a95, + 0x1b80, 0xe3880a97, + 0x1b80, 0xe3e20aa5, + 0x1b80, 0xe3e20aa7, + 0x1b80, 0x6c240ab5, + 0x1b80, 0x6c240ab7, + 0x1b80, 0xe3880ac5, + 0x1b80, 0xe3880ac7, + 0x1b80, 0xe3e20ad5, + 0x1b80, 0xe3e20ad7, + 0x1b80, 0x6c440ae5, + 0x1b80, 0x6c440ae7, + 0x1b80, 0xe3880af5, + 0x1b80, 0xe3880af7, + 0x1b80, 0xe3e20b05, + 0x1b80, 0xe3e20b07, + 0x1b80, 0x6c640b15, + 0x1b80, 0x6c640b17, + 0x1b80, 0xe3880b25, + 0x1b80, 0xe3880b27, + 0x1b80, 0xe3e20b35, + 0x1b80, 0xe3e20b37, + 0x1b80, 0x0baa0b45, + 0x1b80, 0x0baa0b47, + 0x1b80, 0x6c840b55, + 0x1b80, 0x6c840b57, + 0x1b80, 0x6d0f0b65, + 0x1b80, 0x6d0f0b67, + 0x1b80, 0xe3880b75, + 0x1b80, 0xe3880b77, + 0x1b80, 0xe3e20b85, + 0x1b80, 0xe3e20b87, + 0x1b80, 0x6ca40b95, + 0x1b80, 0x6ca40b97, + 0x1b80, 0xe3880ba5, + 0x1b80, 0xe3880ba7, + 0x1b80, 0xe3e20bb5, + 0x1b80, 0xe3e20bb7, + 0x1b80, 0x0bac0bc5, + 0x1b80, 0x0bac0bc7, + 0x1b80, 0x6cc40bd5, + 0x1b80, 0x6cc40bd7, + 0x1b80, 0x6d0f0be5, + 0x1b80, 0x6d0f0be7, + 0x1b80, 0xe3880bf5, + 0x1b80, 0xe3880bf7, + 0x1b80, 0xe3e20c05, + 0x1b80, 0xe3e20c07, + 0x1b80, 0x6ce40c15, + 0x1b80, 0x6ce40c17, + 0x1b80, 0xe3880c25, + 0x1b80, 0xe3880c27, + 0x1b80, 0xe3e20c35, + 0x1b80, 0xe3e20c37, + 0x1b80, 0x6cf40c45, + 0x1b80, 0x6cf40c47, + 0x1b80, 0xe3880c55, + 0x1b80, 0xe3880c57, + 0x1b80, 0xe3e20c65, + 0x1b80, 0xe3e20c67, + 0x1b80, 0x6c0c0c75, + 0x1b80, 0x6c0c0c77, + 0x1b80, 0x6d000c85, + 0x1b80, 0x6d000c87, + 0x1b80, 0xe3880c95, + 0x1b80, 0xe3880c97, + 0x1b80, 0xe3e20ca5, + 0x1b80, 0xe3e20ca7, + 0x1b80, 0x6c1c0cb5, + 0x1b80, 0x6c1c0cb7, + 0x1b80, 0xe3880cc5, + 0x1b80, 0xe3880cc7, + 0x1b80, 0xe3e20cd5, + 0x1b80, 0xe3e20cd7, + 0x1b80, 0x6c3c0ce5, + 0x1b80, 0x6c3c0ce7, + 0x1b80, 0xe3880cf5, + 0x1b80, 0xe3880cf7, + 0x1b80, 0xe3e20d05, + 0x1b80, 0xe3e20d07, + 0x1b80, 0xf4b90d15, + 0x1b80, 0xf4b90d17, + 0x1b80, 0xf7b80d25, + 0x1b80, 0xf7b80d27, + 0x1b80, 0x6c5c0d35, + 0x1b80, 0x6c5c0d37, + 0x1b80, 0xe3880d45, + 0x1b80, 0xe3880d47, + 0x1b80, 0xe3e20d55, + 0x1b80, 0xe3e20d57, + 0x1b80, 0x6c7c0d65, + 0x1b80, 0x6c7c0d67, + 0x1b80, 0xe3880d75, + 0x1b80, 0xe3880d77, + 0x1b80, 0xe3e20d85, + 0x1b80, 0xe3e20d87, + 0x1b80, 0xf5c00d95, + 0x1b80, 0xf5c00d97, + 0x1b80, 0xf8bf0da5, + 0x1b80, 0xf8bf0da7, + 0x1b80, 0x6c9c0db5, + 0x1b80, 0x6c9c0db7, + 0x1b80, 0xe3880dc5, + 0x1b80, 0xe3880dc7, + 0x1b80, 0xe3e20dd5, + 0x1b80, 0xe3e20dd7, + 0x1b80, 0x6cbc0de5, + 0x1b80, 0x6cbc0de7, + 0x1b80, 0xe3880df5, + 0x1b80, 0xe3880df7, + 0x1b80, 0xe3e20e05, + 0x1b80, 0xe3e20e07, + 0x1b80, 0x6cdc0e15, + 0x1b80, 0x6cdc0e17, + 0x1b80, 0xe3880e25, + 0x1b80, 0xe3880e27, + 0x1b80, 0xe3e20e35, + 0x1b80, 0xe3e20e37, + 0x1b80, 0x6cf00e45, + 0x1b80, 0x6cf00e47, + 0x1b80, 0xe3880e55, + 0x1b80, 0xe3880e57, + 0x1b80, 0xe3e20e65, + 0x1b80, 0xe3e20e67, + 0x1b80, 0xf9a00e75, + 0x1b80, 0xf9a00e77, + 0x1b80, 0x00300e85, + 0x1b80, 0x00300e87, + 0x1b80, 0x63c30e95, + 0x1b80, 0x63c30e97, + 0x1b80, 0x00020ea5, + 0x1b80, 0x00020ea7, + 0x1b80, 0x318b0eb5, + 0x1b80, 0x318b0eb7, + 0x1b80, 0x00300ec5, + 0x1b80, 0x00300ec7, + 0x1b80, 0x00000ed5, + 0x1b80, 0x00000ed7, + 0x1b80, 0x00020ee5, + 0x1b80, 0x00020ee7, + 0x1b80, 0x55010ef5, + 0x1b80, 0x55010ef7, + 0x1b80, 0x57040f05, + 0x1b80, 0x57040f07, + 0x1b80, 0x57000f15, + 0x1b80, 0x57000f17, + 0x1b80, 0x96000f25, + 0x1b80, 0x96000f27, + 0x1b80, 0x00070f35, + 0x1b80, 0x00070f37, + 0x1b80, 0x5be00f45, + 0x1b80, 0x5be00f47, + 0x1b80, 0x5a000f55, + 0x1b80, 0x5a000f57, + 0x1b80, 0x59000f65, + 0x1b80, 0x59000f67, + 0x1b80, 0x58000f75, + 0x1b80, 0x58000f77, + 0x1b80, 0x00040f85, + 0x1b80, 0x00040f87, + 0x1b80, 0x57080f95, + 0x1b80, 0x57080f97, + 0x1b80, 0x57000fa5, + 0x1b80, 0x57000fa7, + 0x1b80, 0x95000fb5, + 0x1b80, 0x95000fb7, + 0x1b80, 0x00070fc5, + 0x1b80, 0x00070fc7, + 0x1b80, 0x58010fd5, + 0x1b80, 0x58010fd7, + 0x1b80, 0x00040fe5, + 0x1b80, 0x00040fe7, + 0x1b80, 0x00300ff5, + 0x1b80, 0x00300ff7, + 0x1b80, 0x00001005, + 0x1b80, 0x00001007, + 0x1b80, 0x00021015, + 0x1b80, 0x00021017, + 0x1b80, 0x63051025, + 0x1b80, 0x63051027, + 0x1b80, 0x7b401035, + 0x1b80, 0x7b401037, + 0x1b80, 0x7a001045, + 0x1b80, 0x7a001047, + 0x1b80, 0x79001055, + 0x1b80, 0x79001057, + 0x1b80, 0x7f401065, + 0x1b80, 0x7f401067, + 0x1b80, 0x7e001075, + 0x1b80, 0x7e001077, + 0x1b80, 0x7d001085, + 0x1b80, 0x7d001087, + 0x1b80, 0x00011095, + 0x1b80, 0x00011097, + 0x1b80, 0xe3b410a5, + 0x1b80, 0xe3b410a7, + 0x1b80, 0x000110b5, + 0x1b80, 0x000110b7, + 0x1b80, 0x5c3210c5, + 0x1b80, 0x5c3210c7, + 0x1b80, 0x54fd10d5, + 0x1b80, 0x54fd10d7, + 0x1b80, 0xe3b410e5, + 0x1b80, 0xe3b410e7, + 0x1b80, 0x000110f5, + 0x1b80, 0x000110f7, + 0x1b80, 0x31471105, + 0x1b80, 0x31471107, + 0x1b80, 0x00261115, + 0x1b80, 0x00261117, + 0x1b80, 0xe3e71125, + 0x1b80, 0xe3e71127, + 0x1b80, 0x00021135, + 0x1b80, 0x00021137, + 0x1b80, 0x54ec1145, + 0x1b80, 0x54ec1147, + 0x1b80, 0x0ba61155, + 0x1b80, 0x0ba61157, + 0x1b80, 0x00261165, + 0x1b80, 0x00261167, + 0x1b80, 0xe3e71175, + 0x1b80, 0xe3e71177, + 0x1b80, 0x00021185, + 0x1b80, 0x00021187, + 0x1b80, 0x63431195, + 0x1b80, 0x63431197, + 0x1b80, 0x30ec11a5, + 0x1b80, 0x30ec11a7, + 0x1b80, 0x313b11b5, + 0x1b80, 0x313b11b7, + 0x1b80, 0x002411c5, + 0x1b80, 0x002411c7, + 0x1b80, 0xe3e711d5, + 0x1b80, 0xe3e711d7, + 0x1b80, 0x000211e5, + 0x1b80, 0x000211e7, + 0x1b80, 0x54ea11f5, + 0x1b80, 0x54ea11f7, + 0x1b80, 0x0ba61205, + 0x1b80, 0x0ba61207, + 0x1b80, 0x00241215, + 0x1b80, 0x00241217, + 0x1b80, 0xe3e71225, + 0x1b80, 0xe3e71227, + 0x1b80, 0x00021235, + 0x1b80, 0x00021237, + 0x1b80, 0x63431245, + 0x1b80, 0x63431247, + 0x1b80, 0x30ec1255, + 0x1b80, 0x30ec1257, + 0x1b80, 0x5c321265, + 0x1b80, 0x5c321267, + 0x1b80, 0x54e61275, + 0x1b80, 0x54e61277, + 0x1b80, 0x6e101285, + 0x1b80, 0x6e101287, + 0x1b80, 0x6f0f1295, + 0x1b80, 0x6f0f1297, + 0x1b80, 0xe3b412a5, + 0x1b80, 0xe3b412a7, + 0x1b80, 0xe3e712b5, + 0x1b80, 0xe3e712b7, + 0x1b80, 0x5c3212c5, + 0x1b80, 0x5c3212c7, + 0x1b80, 0x54e712d5, + 0x1b80, 0x54e712d7, + 0x1b80, 0x6e2412e5, + 0x1b80, 0x6e2412e7, + 0x1b80, 0xe3b412f5, + 0x1b80, 0xe3b412f7, + 0x1b80, 0xe3e71305, + 0x1b80, 0xe3e71307, + 0x1b80, 0x5c321315, + 0x1b80, 0x5c321317, + 0x1b80, 0x54e81325, + 0x1b80, 0x54e81327, + 0x1b80, 0x6e441335, + 0x1b80, 0x6e441337, + 0x1b80, 0xe3b41345, + 0x1b80, 0xe3b41347, + 0x1b80, 0xe3e71355, + 0x1b80, 0xe3e71357, + 0x1b80, 0x5c321365, + 0x1b80, 0x5c321367, + 0x1b80, 0x54e91375, + 0x1b80, 0x54e91377, + 0x1b80, 0x6e641385, + 0x1b80, 0x6e641387, + 0x1b80, 0xe3b41395, + 0x1b80, 0xe3b41397, + 0x1b80, 0xe3e713a5, + 0x1b80, 0xe3e713a7, + 0x1b80, 0x5c3213b5, + 0x1b80, 0x5c3213b7, + 0x1b80, 0x54ea13c5, + 0x1b80, 0x54ea13c7, + 0x1b80, 0x0baa13d5, + 0x1b80, 0x0baa13d7, + 0x1b80, 0x6e8413e5, + 0x1b80, 0x6e8413e7, + 0x1b80, 0x6f0f13f5, + 0x1b80, 0x6f0f13f7, + 0x1b80, 0xe3b41405, + 0x1b80, 0xe3b41407, + 0x1b80, 0xe3e71415, + 0x1b80, 0xe3e71417, + 0x1b80, 0x5c321425, + 0x1b80, 0x5c321427, + 0x1b80, 0x54eb1435, + 0x1b80, 0x54eb1437, + 0x1b80, 0x6ea41445, + 0x1b80, 0x6ea41447, + 0x1b80, 0xe3b41455, + 0x1b80, 0xe3b41457, + 0x1b80, 0xe3e71465, + 0x1b80, 0xe3e71467, + 0x1b80, 0x5c321475, + 0x1b80, 0x5c321477, + 0x1b80, 0x54ec1485, + 0x1b80, 0x54ec1487, + 0x1b80, 0x0bac1495, + 0x1b80, 0x0bac1497, + 0x1b80, 0x6ec414a5, + 0x1b80, 0x6ec414a7, + 0x1b80, 0x6f0f14b5, + 0x1b80, 0x6f0f14b7, + 0x1b80, 0xe3b414c5, + 0x1b80, 0xe3b414c7, + 0x1b80, 0xe3e714d5, + 0x1b80, 0xe3e714d7, + 0x1b80, 0x5c3214e5, + 0x1b80, 0x5c3214e7, + 0x1b80, 0x54ed14f5, + 0x1b80, 0x54ed14f7, + 0x1b80, 0x6ee41505, + 0x1b80, 0x6ee41507, + 0x1b80, 0xe3b41515, + 0x1b80, 0xe3b41517, + 0x1b80, 0xe3e71525, + 0x1b80, 0xe3e71527, + 0x1b80, 0x5c321535, + 0x1b80, 0x5c321537, + 0x1b80, 0x54ee1545, + 0x1b80, 0x54ee1547, + 0x1b80, 0x6ef41555, + 0x1b80, 0x6ef41557, + 0x1b80, 0xe3b41565, + 0x1b80, 0xe3b41567, + 0x1b80, 0xe3e71575, + 0x1b80, 0xe3e71577, + 0x1b80, 0x5c321585, + 0x1b80, 0x5c321587, + 0x1b80, 0x54ef1595, + 0x1b80, 0x54ef1597, + 0x1b80, 0x6e0c15a5, + 0x1b80, 0x6e0c15a7, + 0x1b80, 0x6f0015b5, + 0x1b80, 0x6f0015b7, + 0x1b80, 0xe3b415c5, + 0x1b80, 0xe3b415c7, + 0x1b80, 0xe3e715d5, + 0x1b80, 0xe3e715d7, + 0x1b80, 0x5c3215e5, + 0x1b80, 0x5c3215e7, + 0x1b80, 0x54f015f5, + 0x1b80, 0x54f015f7, + 0x1b80, 0x6e1c1605, + 0x1b80, 0x6e1c1607, + 0x1b80, 0xe3b41615, + 0x1b80, 0xe3b41617, + 0x1b80, 0xe3e71625, + 0x1b80, 0xe3e71627, + 0x1b80, 0x5c321635, + 0x1b80, 0x5c321637, + 0x1b80, 0x54f11645, + 0x1b80, 0x54f11647, + 0x1b80, 0x6e3c1655, + 0x1b80, 0x6e3c1657, + 0x1b80, 0xe3b41665, + 0x1b80, 0xe3b41667, + 0x1b80, 0xe3e71675, + 0x1b80, 0xe3e71677, + 0x1b80, 0xfaa91685, + 0x1b80, 0xfaa91687, + 0x1b80, 0x5c321695, + 0x1b80, 0x5c321697, + 0x1b80, 0x54f216a5, + 0x1b80, 0x54f216a7, + 0x1b80, 0x6e5c16b5, + 0x1b80, 0x6e5c16b7, + 0x1b80, 0xe3b416c5, + 0x1b80, 0xe3b416c7, + 0x1b80, 0xe3e716d5, + 0x1b80, 0xe3e716d7, + 0x1b80, 0x5c3216e5, + 0x1b80, 0x5c3216e7, + 0x1b80, 0x54f316f5, + 0x1b80, 0x54f316f7, + 0x1b80, 0x6e7c1705, + 0x1b80, 0x6e7c1707, + 0x1b80, 0xe3b41715, + 0x1b80, 0xe3b41717, + 0x1b80, 0xe3e71725, + 0x1b80, 0xe3e71727, + 0x1b80, 0xfba91735, + 0x1b80, 0xfba91737, + 0x1b80, 0x5c321745, + 0x1b80, 0x5c321747, + 0x1b80, 0x54f41755, + 0x1b80, 0x54f41757, + 0x1b80, 0x6e9c1765, + 0x1b80, 0x6e9c1767, + 0x1b80, 0xe3b41775, + 0x1b80, 0xe3b41777, + 0x1b80, 0xe3e71785, + 0x1b80, 0xe3e71787, + 0x1b80, 0x5c321795, + 0x1b80, 0x5c321797, + 0x1b80, 0x54f517a5, + 0x1b80, 0x54f517a7, + 0x1b80, 0x6ebc17b5, + 0x1b80, 0x6ebc17b7, + 0x1b80, 0xe3b417c5, + 0x1b80, 0xe3b417c7, + 0x1b80, 0xe3e717d5, + 0x1b80, 0xe3e717d7, + 0x1b80, 0x5c3217e5, + 0x1b80, 0x5c3217e7, + 0x1b80, 0x54f617f5, + 0x1b80, 0x54f617f7, + 0x1b80, 0x6edc1805, + 0x1b80, 0x6edc1807, + 0x1b80, 0xe3b41815, + 0x1b80, 0xe3b41817, + 0x1b80, 0xe3e71825, + 0x1b80, 0xe3e71827, + 0x1b80, 0x5c321835, + 0x1b80, 0x5c321837, + 0x1b80, 0x54f71845, + 0x1b80, 0x54f71847, + 0x1b80, 0x6ef01855, + 0x1b80, 0x6ef01857, + 0x1b80, 0xe3b41865, + 0x1b80, 0xe3b41867, + 0x1b80, 0xe3e71875, + 0x1b80, 0xe3e71877, + 0x1b80, 0x63431885, + 0x1b80, 0x63431887, + 0x1b80, 0x30ec1895, + 0x1b80, 0x30ec1897, + 0x1b80, 0x000118a5, + 0x1b80, 0x000118a7, + 0x1b80, 0x63c318b5, + 0x1b80, 0x63c318b7, + 0x1b80, 0x003018c5, + 0x1b80, 0x003018c7, + 0x1b80, 0x000018d5, + 0x1b80, 0x000018d7, + 0x1b80, 0x000218e5, + 0x1b80, 0x000218e7, + 0x1b80, 0x550118f5, + 0x1b80, 0x550118f7, + 0x1b80, 0x57041905, + 0x1b80, 0x57041907, + 0x1b80, 0x57001915, + 0x1b80, 0x57001917, + 0x1b80, 0x96001925, + 0x1b80, 0x96001927, + 0x1b80, 0x00301935, + 0x1b80, 0x00301937, + 0x1b80, 0x00071945, + 0x1b80, 0x00071947, + 0x1b80, 0x5be01955, + 0x1b80, 0x5be01957, + 0x1b80, 0x5a001965, + 0x1b80, 0x5a001967, + 0x1b80, 0x59001975, + 0x1b80, 0x59001977, + 0x1b80, 0x58001985, + 0x1b80, 0x58001987, + 0x1b80, 0x00041995, + 0x1b80, 0x00041997, + 0x1b80, 0x000219a5, + 0x1b80, 0x000219a7, + 0x1b80, 0x570819b5, + 0x1b80, 0x570819b7, + 0x1b80, 0x570019c5, + 0x1b80, 0x570019c7, + 0x1b80, 0x950019d5, + 0x1b80, 0x950019d7, + 0x1b80, 0x003019e5, + 0x1b80, 0x003019e7, + 0x1b80, 0x000719f5, + 0x1b80, 0x000719f7, + 0x1b80, 0x58011a05, + 0x1b80, 0x58011a07, + 0x1b80, 0x00041a15, + 0x1b80, 0x00041a17, + 0x1b80, 0x00021a25, + 0x1b80, 0x00021a27, + 0x1b80, 0x00301a35, + 0x1b80, 0x00301a37, + 0x1b80, 0x00001a45, + 0x1b80, 0x00001a47, + 0x1b80, 0x00021a55, + 0x1b80, 0x00021a57, + 0x1b80, 0x63051a65, + 0x1b80, 0x63051a67, + 0x1b80, 0x7b401a75, + 0x1b80, 0x7b401a77, + 0x1b80, 0x7a001a85, + 0x1b80, 0x7a001a87, + 0x1b80, 0x79001a95, + 0x1b80, 0x79001a97, + 0x1b80, 0x7f401aa5, + 0x1b80, 0x7f401aa7, + 0x1b80, 0x7e001ab5, + 0x1b80, 0x7e001ab7, + 0x1b80, 0x7d001ac5, + 0x1b80, 0x7d001ac7, + 0x1b80, 0x00011ad5, + 0x1b80, 0x00011ad7, + 0x1b80, 0x00041ae5, + 0x1b80, 0x00041ae7, + 0x1b80, 0x55011af5, + 0x1b80, 0x55011af7, + 0x1b80, 0x5c311b05, + 0x1b80, 0x5c311b07, + 0x1b80, 0x5f821b15, + 0x1b80, 0x5f821b17, + 0x1b80, 0x66051b25, + 0x1b80, 0x66051b27, + 0x1b80, 0x00061b35, + 0x1b80, 0x00061b37, + 0x1b80, 0x5d801b45, + 0x1b80, 0x5d801b47, + 0x1b80, 0x09001b55, + 0x1b80, 0x09001b57, + 0x1b80, 0x0a011b65, + 0x1b80, 0x0a011b67, + 0x1b80, 0x0b401b75, + 0x1b80, 0x0b401b77, + 0x1b80, 0x0d001b85, + 0x1b80, 0x0d001b87, + 0x1b80, 0x0f011b95, + 0x1b80, 0x0f011b97, + 0x1b80, 0x002a1ba5, + 0x1b80, 0x002a1ba7, + 0x1b80, 0x055a1bb5, + 0x1b80, 0x055a1bb7, + 0x1b80, 0x05db1bc5, + 0x1b80, 0x05db1bc7, + 0x1b80, 0xe3d21bd5, + 0x1b80, 0xe3d21bd7, + 0x1b80, 0xe3801be5, + 0x1b80, 0xe3801be7, + 0x1b80, 0x00061bf5, + 0x1b80, 0x00061bf7, + 0x1b80, 0x06da1c05, + 0x1b80, 0x06da1c07, + 0x1b80, 0x07db1c15, + 0x1b80, 0x07db1c17, + 0x1b80, 0xe3d21c25, + 0x1b80, 0xe3d21c27, + 0x1b80, 0xe3801c35, + 0x1b80, 0xe3801c37, + 0x1b80, 0xe3c91c45, + 0x1b80, 0xe3c91c47, + 0x1b80, 0x00021c55, + 0x1b80, 0x00021c57, + 0x1b80, 0xe3ce1c65, + 0x1b80, 0xe3ce1c67, + 0x1b80, 0x5d001c75, + 0x1b80, 0x5d001c77, + 0x1b80, 0x00041c85, + 0x1b80, 0x00041c87, + 0x1b80, 0x5fa21c95, + 0x1b80, 0x5fa21c97, + 0x1b80, 0x00011ca5, + 0x1b80, 0x00011ca7, + 0x1b80, 0x00041cb5, + 0x1b80, 0x00041cb7, + 0x1b80, 0xe2711cc5, + 0x1b80, 0xe2711cc7, + 0x1b80, 0xe2821cd5, + 0x1b80, 0xe2821cd7, + 0x1b80, 0xe28b1ce5, + 0x1b80, 0xe28b1ce7, + 0x1b80, 0xe29c1cf5, + 0x1b80, 0xe29c1cf7, + 0x1b80, 0x00051d05, + 0x1b80, 0x00051d07, + 0x1b80, 0xe2641d15, + 0x1b80, 0xe2641d17, + 0x1b80, 0xe2711d25, + 0x1b80, 0xe2711d27, + 0x1b80, 0xe28b1d35, + 0x1b80, 0xe28b1d37, + 0x1b80, 0xe29c1d45, + 0x1b80, 0xe29c1d47, + 0x1b80, 0x00061d55, + 0x1b80, 0x00061d57, + 0x1b80, 0xe2641d65, + 0x1b80, 0xe2641d67, + 0x1b80, 0xe2711d75, + 0x1b80, 0xe2711d77, + 0x1b80, 0xe2821d85, + 0x1b80, 0xe2821d87, + 0x1b80, 0xe28b1d95, + 0x1b80, 0xe28b1d97, + 0x1b80, 0x00011da5, + 0x1b80, 0x00011da7, + 0x1b80, 0xe2f41db5, + 0x1b80, 0xe2f41db7, + 0x1b80, 0x74081dc5, + 0x1b80, 0x74081dc7, + 0x1b80, 0xe33e1dd5, + 0x1b80, 0xe33e1dd7, + 0x1b80, 0xe3201de5, + 0x1b80, 0xe3201de7, + 0x1b80, 0xe35e1df5, + 0x1b80, 0xe35e1df7, + 0x1b80, 0xb9001e05, + 0x1b80, 0xb9001e07, + 0x1b80, 0x99001e15, + 0x1b80, 0x99001e17, + 0x1b80, 0x00061e25, + 0x1b80, 0x00061e27, + 0x1b80, 0x77001e35, + 0x1b80, 0x77001e37, + 0x1b80, 0x00041e45, + 0x1b80, 0x00041e47, + 0x1b80, 0x49041e55, + 0x1b80, 0x49041e57, + 0x1b80, 0x4bb01e65, + 0x1b80, 0x4bb01e67, + 0x1b80, 0x00061e75, + 0x1b80, 0x00061e77, + 0x1b80, 0x75041e85, + 0x1b80, 0x75041e87, + 0x1b80, 0x77081e95, + 0x1b80, 0x77081e97, + 0x1b80, 0x00071ea5, + 0x1b80, 0x00071ea7, + 0x1b80, 0x77101eb5, + 0x1b80, 0x77101eb7, + 0x1b80, 0x00041ec5, + 0x1b80, 0x00041ec7, + 0x1b80, 0x44801ed5, + 0x1b80, 0x44801ed7, + 0x1b80, 0x45ff1ee5, + 0x1b80, 0x45ff1ee7, + 0x1b80, 0x463f1ef5, + 0x1b80, 0x463f1ef7, + 0x1b80, 0x47311f05, + 0x1b80, 0x47311f07, + 0x1b80, 0x40081f15, + 0x1b80, 0x40081f17, + 0x1b80, 0xe2db1f25, + 0x1b80, 0xe2db1f27, + 0x1b80, 0x00011f35, + 0x1b80, 0x00011f37, + 0x1b80, 0xe2f41f45, + 0x1b80, 0xe2f41f47, + 0x1b80, 0x74081f55, + 0x1b80, 0x74081f57, + 0x1b80, 0xe34e1f65, + 0x1b80, 0xe34e1f67, + 0x1b80, 0xe3201f75, + 0x1b80, 0xe3201f77, + 0x1b80, 0xe3641f85, + 0x1b80, 0xe3641f87, + 0x1b80, 0xb9001f95, + 0x1b80, 0xb9001f97, + 0x1b80, 0x99001fa5, + 0x1b80, 0x99001fa7, + 0x1b80, 0x00061fb5, + 0x1b80, 0x00061fb7, + 0x1b80, 0x77001fc5, + 0x1b80, 0x77001fc7, + 0x1b80, 0x00051fd5, + 0x1b80, 0x00051fd7, + 0x1b80, 0x61041fe5, + 0x1b80, 0x61041fe7, + 0x1b80, 0x63b01ff5, + 0x1b80, 0x63b01ff7, + 0x1b80, 0x00062005, + 0x1b80, 0x00062007, + 0x1b80, 0x75082015, + 0x1b80, 0x75082017, + 0x1b80, 0x77082025, + 0x1b80, 0x77082027, + 0x1b80, 0x00072035, + 0x1b80, 0x00072037, + 0x1b80, 0x77202045, + 0x1b80, 0x77202047, + 0x1b80, 0x00052055, + 0x1b80, 0x00052057, + 0x1b80, 0x5c802065, + 0x1b80, 0x5c802067, + 0x1b80, 0x5dff2075, + 0x1b80, 0x5dff2077, + 0x1b80, 0x5e3f2085, + 0x1b80, 0x5e3f2087, + 0x1b80, 0x5f312095, + 0x1b80, 0x5f312097, + 0x1b80, 0x000420a5, + 0x1b80, 0x000420a7, + 0x1b80, 0x400a20b5, + 0x1b80, 0x400a20b7, + 0x1b80, 0xe2db20c5, + 0x1b80, 0xe2db20c7, + 0x1b80, 0x000120d5, + 0x1b80, 0x000120d7, + 0x1b80, 0xe2f420e5, + 0x1b80, 0xe2f420e7, + 0x1b80, 0x740820f5, + 0x1b80, 0x740820f7, + 0x1b80, 0xe33e2105, + 0x1b80, 0xe33e2107, + 0x1b80, 0xe3202115, + 0x1b80, 0xe3202117, + 0x1b80, 0xe35e2125, + 0x1b80, 0xe35e2127, + 0x1b80, 0xe36a2135, + 0x1b80, 0xe36a2137, + 0x1b80, 0xe2ad2145, + 0x1b80, 0xe2ad2147, + 0x1b80, 0x00012155, + 0x1b80, 0x00012157, + 0x1b80, 0xe2f42165, + 0x1b80, 0xe2f42167, + 0x1b80, 0x74082175, + 0x1b80, 0x74082177, + 0x1b80, 0xe34e2185, + 0x1b80, 0xe34e2187, + 0x1b80, 0xe3202195, + 0x1b80, 0xe3202197, + 0x1b80, 0xe36421a5, + 0x1b80, 0xe36421a7, + 0x1b80, 0xe36a21b5, + 0x1b80, 0xe36a21b7, + 0x1b80, 0xe2c321c5, + 0x1b80, 0xe2c321c7, + 0x1b80, 0x000121d5, + 0x1b80, 0x000121d7, + 0x1b80, 0xe30a21e5, + 0x1b80, 0xe30a21e7, + 0x1b80, 0x740021f5, + 0x1b80, 0x740021f7, + 0x1b80, 0xe33e2205, + 0x1b80, 0xe33e2207, + 0x1b80, 0xe32f2215, + 0x1b80, 0xe32f2217, + 0x1b80, 0xe35e2225, + 0x1b80, 0xe35e2227, + 0x1b80, 0xe36a2235, + 0x1b80, 0xe36a2237, + 0x1b80, 0xe2ad2245, + 0x1b80, 0xe2ad2247, + 0x1b80, 0x00012255, + 0x1b80, 0x00012257, + 0x1b80, 0xe30a2265, + 0x1b80, 0xe30a2267, + 0x1b80, 0x74002275, + 0x1b80, 0x74002277, + 0x1b80, 0xe34e2285, + 0x1b80, 0xe34e2287, + 0x1b80, 0xe32f2295, + 0x1b80, 0xe32f2297, + 0x1b80, 0xe36422a5, + 0x1b80, 0xe36422a7, + 0x1b80, 0xe36a22b5, + 0x1b80, 0xe36a22b7, + 0x1b80, 0xe2c322c5, + 0x1b80, 0xe2c322c7, + 0x1b80, 0x000122d5, + 0x1b80, 0x000122d7, + 0x1b80, 0x000422e5, + 0x1b80, 0x000422e7, + 0x1b80, 0x445b22f5, + 0x1b80, 0x445b22f7, + 0x1b80, 0x47b02305, + 0x1b80, 0x47b02307, + 0x1b80, 0x47302315, + 0x1b80, 0x47302317, + 0x1b80, 0x47002325, + 0x1b80, 0x47002327, + 0x1b80, 0x00062335, + 0x1b80, 0x00062337, + 0x1b80, 0x77082345, + 0x1b80, 0x77082347, + 0x1b80, 0x00042355, + 0x1b80, 0x00042357, + 0x1b80, 0x49402365, + 0x1b80, 0x49402367, + 0x1b80, 0x4bb02375, + 0x1b80, 0x4bb02377, + 0x1b80, 0x00072385, + 0x1b80, 0x00072387, + 0x1b80, 0x54402395, + 0x1b80, 0x54402397, + 0x1b80, 0x000423a5, + 0x1b80, 0x000423a7, + 0x1b80, 0x400823b5, + 0x1b80, 0x400823b7, + 0x1b80, 0x000123c5, + 0x1b80, 0x000123c7, + 0x1b80, 0x000523d5, + 0x1b80, 0x000523d7, + 0x1b80, 0x5c5b23e5, + 0x1b80, 0x5c5b23e7, + 0x1b80, 0x5fb023f5, + 0x1b80, 0x5fb023f7, + 0x1b80, 0x5f302405, + 0x1b80, 0x5f302407, + 0x1b80, 0x5f002415, + 0x1b80, 0x5f002417, + 0x1b80, 0x00062425, + 0x1b80, 0x00062427, + 0x1b80, 0x77082435, + 0x1b80, 0x77082437, + 0x1b80, 0x00052445, + 0x1b80, 0x00052447, + 0x1b80, 0x61402455, + 0x1b80, 0x61402457, + 0x1b80, 0x63b02465, + 0x1b80, 0x63b02467, + 0x1b80, 0x00072475, + 0x1b80, 0x00072477, + 0x1b80, 0x54402485, + 0x1b80, 0x54402487, + 0x1b80, 0x00042495, + 0x1b80, 0x00042497, + 0x1b80, 0x400824a5, + 0x1b80, 0x400824a7, + 0x1b80, 0x000124b5, + 0x1b80, 0x000124b7, + 0x1b80, 0xe2f424c5, + 0x1b80, 0xe2f424c7, + 0x1b80, 0x740824d5, + 0x1b80, 0x740824d7, + 0x1b80, 0xe33e24e5, + 0x1b80, 0xe33e24e7, + 0x1b80, 0x000424f5, + 0x1b80, 0x000424f7, + 0x1b80, 0x40082505, + 0x1b80, 0x40082507, + 0x1b80, 0x00012515, + 0x1b80, 0x00012517, + 0x1b80, 0xe2f42525, + 0x1b80, 0xe2f42527, + 0x1b80, 0x74082535, + 0x1b80, 0x74082537, + 0x1b80, 0xe34e2545, + 0x1b80, 0xe34e2547, + 0x1b80, 0x00042555, + 0x1b80, 0x00042557, + 0x1b80, 0x40082565, + 0x1b80, 0x40082567, + 0x1b80, 0x00012575, + 0x1b80, 0x00012577, + 0x1b80, 0xe30a2585, + 0x1b80, 0xe30a2587, + 0x1b80, 0x74002595, + 0x1b80, 0x74002597, + 0x1b80, 0xe33e25a5, + 0x1b80, 0xe33e25a7, + 0x1b80, 0x000425b5, + 0x1b80, 0x000425b7, + 0x1b80, 0x400825c5, + 0x1b80, 0x400825c7, + 0x1b80, 0x000125d5, + 0x1b80, 0x000125d7, + 0x1b80, 0xe30a25e5, + 0x1b80, 0xe30a25e7, + 0x1b80, 0x740025f5, + 0x1b80, 0x740025f7, + 0x1b80, 0xe34e2605, + 0x1b80, 0xe34e2607, + 0x1b80, 0x00042615, + 0x1b80, 0x00042617, + 0x1b80, 0x40082625, + 0x1b80, 0x40082627, + 0x1b80, 0x00012635, + 0x1b80, 0x00012637, + 0x1b80, 0x40ff2645, + 0x1b80, 0x40ff2647, + 0x1b80, 0x411f2655, + 0x1b80, 0x411f2657, + 0x1b80, 0x42002665, + 0x1b80, 0x42002667, + 0x1b80, 0x43002675, + 0x1b80, 0x43002677, + 0x1b80, 0x44ff2685, + 0x1b80, 0x44ff2687, + 0x1b80, 0x451f2695, + 0x1b80, 0x451f2697, + 0x1b80, 0x460026a5, + 0x1b80, 0x460026a7, + 0x1b80, 0x470026b5, + 0x1b80, 0x470026b7, + 0x1b80, 0x48ff26c5, + 0x1b80, 0x48ff26c7, + 0x1b80, 0x491f26d5, + 0x1b80, 0x491f26d7, + 0x1b80, 0x4a0026e5, + 0x1b80, 0x4a0026e7, + 0x1b80, 0x4b0026f5, + 0x1b80, 0x4b0026f7, + 0x1b80, 0x00012705, + 0x1b80, 0x00012707, + 0x1b80, 0x4cff2715, + 0x1b80, 0x4cff2717, + 0x1b80, 0x4d1f2725, + 0x1b80, 0x4d1f2727, + 0x1b80, 0x4e002735, + 0x1b80, 0x4e002737, + 0x1b80, 0x4f002745, + 0x1b80, 0x4f002747, + 0x1b80, 0x50ff2755, + 0x1b80, 0x50ff2757, + 0x1b80, 0x511f2765, + 0x1b80, 0x511f2767, + 0x1b80, 0x52002775, + 0x1b80, 0x52002777, + 0x1b80, 0x53002785, + 0x1b80, 0x53002787, + 0x1b80, 0x54ff2795, + 0x1b80, 0x54ff2797, + 0x1b80, 0x551f27a5, + 0x1b80, 0x551f27a7, + 0x1b80, 0x560027b5, + 0x1b80, 0x560027b7, + 0x1b80, 0x570027c5, + 0x1b80, 0x570027c7, + 0x1b80, 0x58ff27d5, + 0x1b80, 0x58ff27d7, + 0x1b80, 0x591f27e5, + 0x1b80, 0x591f27e7, + 0x1b80, 0x5a0027f5, + 0x1b80, 0x5a0027f7, + 0x1b80, 0x5b002805, + 0x1b80, 0x5b002807, + 0x1b80, 0x00012815, + 0x1b80, 0x00012817, + 0x1b80, 0x5cff2825, + 0x1b80, 0x5cff2827, + 0x1b80, 0x5d1f2835, + 0x1b80, 0x5d1f2837, + 0x1b80, 0x5e002845, + 0x1b80, 0x5e002847, + 0x1b80, 0x5f002855, + 0x1b80, 0x5f002857, + 0x1b80, 0x60ff2865, + 0x1b80, 0x60ff2867, + 0x1b80, 0x611f2875, + 0x1b80, 0x611f2877, + 0x1b80, 0x62002885, + 0x1b80, 0x62002887, + 0x1b80, 0x63002895, + 0x1b80, 0x63002897, + 0x1b80, 0x000128a5, + 0x1b80, 0x000128a7, + 0x1b80, 0x64ff28b5, + 0x1b80, 0x64ff28b7, + 0x1b80, 0x651f28c5, + 0x1b80, 0x651f28c7, + 0x1b80, 0x660028d5, + 0x1b80, 0x660028d7, + 0x1b80, 0x670028e5, + 0x1b80, 0x670028e7, + 0x1b80, 0x68ff28f5, + 0x1b80, 0x68ff28f7, + 0x1b80, 0x691f2905, + 0x1b80, 0x691f2907, + 0x1b80, 0x6a002915, + 0x1b80, 0x6a002917, + 0x1b80, 0x6b002925, + 0x1b80, 0x6b002927, + 0x1b80, 0x6cff2935, + 0x1b80, 0x6cff2937, + 0x1b80, 0x6d1f2945, + 0x1b80, 0x6d1f2947, + 0x1b80, 0x6e002955, + 0x1b80, 0x6e002957, + 0x1b80, 0x6f002965, + 0x1b80, 0x6f002967, + 0x1b80, 0x70ff2975, + 0x1b80, 0x70ff2977, + 0x1b80, 0x711f2985, + 0x1b80, 0x711f2987, + 0x1b80, 0x72002995, + 0x1b80, 0x72002997, + 0x1b80, 0x730029a5, + 0x1b80, 0x730029a7, + 0x1b80, 0x000129b5, + 0x1b80, 0x000129b7, + 0x1b80, 0x70ff29c5, + 0x1b80, 0x70ff29c7, + 0x1b80, 0x711f29d5, + 0x1b80, 0x711f29d7, + 0x1b80, 0x720029e5, + 0x1b80, 0x720029e7, + 0x1b80, 0x730029f5, + 0x1b80, 0x730029f7, + 0x1b80, 0x74ff2a05, + 0x1b80, 0x74ff2a07, + 0x1b80, 0x751f2a15, + 0x1b80, 0x751f2a17, + 0x1b80, 0x76002a25, + 0x1b80, 0x76002a27, + 0x1b80, 0x77002a35, + 0x1b80, 0x77002a37, + 0x1b80, 0x78ff2a45, + 0x1b80, 0x78ff2a47, + 0x1b80, 0x791f2a55, + 0x1b80, 0x791f2a57, + 0x1b80, 0x7a002a65, + 0x1b80, 0x7a002a67, + 0x1b80, 0x7b002a75, + 0x1b80, 0x7b002a77, + 0x1b80, 0x7cff2a85, + 0x1b80, 0x7cff2a87, + 0x1b80, 0x7d1f2a95, + 0x1b80, 0x7d1f2a97, + 0x1b80, 0x7e002aa5, + 0x1b80, 0x7e002aa7, + 0x1b80, 0x7f002ab5, + 0x1b80, 0x7f002ab7, + 0x1b80, 0x00012ac5, + 0x1b80, 0x00012ac7, + 0x1b80, 0x00042ad5, + 0x1b80, 0x00042ad7, + 0x1b80, 0x49042ae5, + 0x1b80, 0x49042ae7, + 0x1b80, 0x4bb02af5, + 0x1b80, 0x4bb02af7, + 0x1b80, 0x00062b05, + 0x1b80, 0x00062b07, + 0x1b80, 0x75042b15, + 0x1b80, 0x75042b17, + 0x1b80, 0x77082b25, + 0x1b80, 0x77082b27, + 0x1b80, 0x00042b35, + 0x1b80, 0x00042b37, + 0x1b80, 0x44802b45, + 0x1b80, 0x44802b47, + 0x1b80, 0x45ff2b55, + 0x1b80, 0x45ff2b57, + 0x1b80, 0x463f2b65, + 0x1b80, 0x463f2b67, + 0x1b80, 0x47312b75, + 0x1b80, 0x47312b77, + 0x1b80, 0x40082b85, + 0x1b80, 0x40082b87, + 0x1b80, 0xe2db2b95, + 0x1b80, 0xe2db2b97, + 0x1b80, 0x00042ba5, + 0x1b80, 0x00042ba7, + 0x1b80, 0x400c2bb5, + 0x1b80, 0x400c2bb7, + 0x1b80, 0x00062bc5, + 0x1b80, 0x00062bc7, + 0x1b80, 0x75002bd5, + 0x1b80, 0x75002bd7, + 0x1b80, 0x00042be5, + 0x1b80, 0x00042be7, + 0x1b80, 0x445b2bf5, + 0x1b80, 0x445b2bf7, + 0x1b80, 0x47002c05, + 0x1b80, 0x47002c07, + 0x1b80, 0x40082c15, + 0x1b80, 0x40082c17, + 0x1b80, 0x00012c25, + 0x1b80, 0x00012c27, + 0x1b80, 0x00052c35, + 0x1b80, 0x00052c37, + 0x1b80, 0x61042c45, + 0x1b80, 0x61042c47, + 0x1b80, 0x63b02c55, + 0x1b80, 0x63b02c57, + 0x1b80, 0x00062c65, + 0x1b80, 0x00062c67, + 0x1b80, 0x75082c75, + 0x1b80, 0x75082c77, + 0x1b80, 0x77082c85, + 0x1b80, 0x77082c87, + 0x1b80, 0x00052c95, + 0x1b80, 0x00052c97, + 0x1b80, 0x5c802ca5, + 0x1b80, 0x5c802ca7, + 0x1b80, 0x5dff2cb5, + 0x1b80, 0x5dff2cb7, + 0x1b80, 0x5e3f2cc5, + 0x1b80, 0x5e3f2cc7, + 0x1b80, 0x5f312cd5, + 0x1b80, 0x5f312cd7, + 0x1b80, 0x00042ce5, + 0x1b80, 0x00042ce7, + 0x1b80, 0x400a2cf5, + 0x1b80, 0x400a2cf7, + 0x1b80, 0xe2db2d05, + 0x1b80, 0xe2db2d07, + 0x1b80, 0x00042d15, + 0x1b80, 0x00042d17, + 0x1b80, 0x400c2d25, + 0x1b80, 0x400c2d27, + 0x1b80, 0x00062d35, + 0x1b80, 0x00062d37, + 0x1b80, 0x75002d45, + 0x1b80, 0x75002d47, + 0x1b80, 0x00052d55, + 0x1b80, 0x00052d57, + 0x1b80, 0x5c5b2d65, + 0x1b80, 0x5c5b2d67, + 0x1b80, 0x5f002d75, + 0x1b80, 0x5f002d77, + 0x1b80, 0x00042d85, + 0x1b80, 0x00042d87, + 0x1b80, 0x40082d95, + 0x1b80, 0x40082d97, + 0x1b80, 0x00012da5, + 0x1b80, 0x00012da7, + 0x1b80, 0x00072db5, + 0x1b80, 0x00072db7, + 0x1b80, 0x4c122dc5, + 0x1b80, 0x4c122dc7, + 0x1b80, 0x4e202dd5, + 0x1b80, 0x4e202dd7, + 0x1b80, 0x00052de5, + 0x1b80, 0x00052de7, + 0x1b80, 0x598f2df5, + 0x1b80, 0x598f2df7, + 0x1b80, 0x40022e05, + 0x1b80, 0x40022e07, + 0x1b80, 0x4c012e15, + 0x1b80, 0x4c012e17, + 0x1b80, 0x4c002e25, + 0x1b80, 0x4c002e27, + 0x1b80, 0xab002e35, + 0x1b80, 0xab002e37, + 0x1b80, 0x40032e45, + 0x1b80, 0x40032e47, + 0x1b80, 0x49802e55, + 0x1b80, 0x49802e57, + 0x1b80, 0x56c02e65, + 0x1b80, 0x56c02e67, + 0x1b80, 0x54022e75, + 0x1b80, 0x54022e77, + 0x1b80, 0x4c012e85, + 0x1b80, 0x4c012e87, + 0x1b80, 0x4c002e95, + 0x1b80, 0x4c002e97, + 0x1b80, 0xab002ea5, + 0x1b80, 0xab002ea7, + 0x1b80, 0x54002eb5, + 0x1b80, 0x54002eb7, + 0x1b80, 0x00072ec5, + 0x1b80, 0x00072ec7, + 0x1b80, 0x4c002ed5, + 0x1b80, 0x4c002ed7, + 0x1b80, 0x4e002ee5, + 0x1b80, 0x4e002ee7, + 0x1b80, 0x00052ef5, + 0x1b80, 0x00052ef7, + 0x1b80, 0x40042f05, + 0x1b80, 0x40042f07, + 0x1b80, 0x4c012f15, + 0x1b80, 0x4c012f17, + 0x1b80, 0x4c002f25, + 0x1b80, 0x4c002f27, + 0x1b80, 0x00012f35, + 0x1b80, 0x00012f37, + 0x1b80, 0x00042f45, + 0x1b80, 0x00042f47, + 0x1b80, 0x44802f55, + 0x1b80, 0x44802f57, + 0x1b80, 0x4b002f65, + 0x1b80, 0x4b002f67, + 0x1b80, 0x00052f75, + 0x1b80, 0x00052f77, + 0x1b80, 0x5c802f85, + 0x1b80, 0x5c802f87, + 0x1b80, 0x63002f95, + 0x1b80, 0x63002f97, + 0x1b80, 0x00072fa5, + 0x1b80, 0x00072fa7, + 0x1b80, 0x780c2fb5, + 0x1b80, 0x780c2fb7, + 0x1b80, 0x79192fc5, + 0x1b80, 0x79192fc7, + 0x1b80, 0x7a002fd5, + 0x1b80, 0x7a002fd7, + 0x1b80, 0x7b822fe5, + 0x1b80, 0x7b822fe7, + 0x1b80, 0x7b022ff5, + 0x1b80, 0x7b022ff7, + 0x1b80, 0x78143005, + 0x1b80, 0x78143007, + 0x1b80, 0x79ee3015, + 0x1b80, 0x79ee3017, + 0x1b80, 0x7a013025, + 0x1b80, 0x7a013027, + 0x1b80, 0x7b833035, + 0x1b80, 0x7b833037, + 0x1b80, 0x7b033045, + 0x1b80, 0x7b033047, + 0x1b80, 0x78283055, + 0x1b80, 0x78283057, + 0x1b80, 0x79b43065, + 0x1b80, 0x79b43067, + 0x1b80, 0x7a003075, + 0x1b80, 0x7a003077, + 0x1b80, 0x7b003085, + 0x1b80, 0x7b003087, + 0x1b80, 0x00013095, + 0x1b80, 0x00013097, + 0x1b80, 0x000430a5, + 0x1b80, 0x000430a7, + 0x1b80, 0x448030b5, + 0x1b80, 0x448030b7, + 0x1b80, 0x4b0030c5, + 0x1b80, 0x4b0030c7, + 0x1b80, 0x000530d5, + 0x1b80, 0x000530d7, + 0x1b80, 0x5c8030e5, + 0x1b80, 0x5c8030e7, + 0x1b80, 0x630030f5, + 0x1b80, 0x630030f7, + 0x1b80, 0x00073105, + 0x1b80, 0x00073107, + 0x1b80, 0x78103115, + 0x1b80, 0x78103117, + 0x1b80, 0x79133125, + 0x1b80, 0x79133127, + 0x1b80, 0x7a003135, + 0x1b80, 0x7a003137, + 0x1b80, 0x7b803145, + 0x1b80, 0x7b803147, + 0x1b80, 0x7b003155, + 0x1b80, 0x7b003157, + 0x1b80, 0x78db3165, + 0x1b80, 0x78db3167, + 0x1b80, 0x79003175, + 0x1b80, 0x79003177, + 0x1b80, 0x7a003185, + 0x1b80, 0x7a003187, + 0x1b80, 0x7b813195, + 0x1b80, 0x7b813197, + 0x1b80, 0x7b0131a5, + 0x1b80, 0x7b0131a7, + 0x1b80, 0x782831b5, + 0x1b80, 0x782831b7, + 0x1b80, 0x79b431c5, + 0x1b80, 0x79b431c7, + 0x1b80, 0x7a0031d5, + 0x1b80, 0x7a0031d7, + 0x1b80, 0x7b0031e5, + 0x1b80, 0x7b0031e7, + 0x1b80, 0x000131f5, + 0x1b80, 0x000131f7, + 0x1b80, 0x00073205, + 0x1b80, 0x00073207, + 0x1b80, 0x783e3215, + 0x1b80, 0x783e3217, + 0x1b80, 0x79f93225, + 0x1b80, 0x79f93227, + 0x1b80, 0x7a013235, + 0x1b80, 0x7a013237, + 0x1b80, 0x7b823245, + 0x1b80, 0x7b823247, + 0x1b80, 0x7b023255, + 0x1b80, 0x7b023257, + 0x1b80, 0x78a93265, + 0x1b80, 0x78a93267, + 0x1b80, 0x79ed3275, + 0x1b80, 0x79ed3277, + 0x1b80, 0x7b833285, + 0x1b80, 0x7b833287, + 0x1b80, 0x7b033295, + 0x1b80, 0x7b033297, + 0x1b80, 0x782832a5, + 0x1b80, 0x782832a7, + 0x1b80, 0x79b432b5, + 0x1b80, 0x79b432b7, + 0x1b80, 0x7a0032c5, + 0x1b80, 0x7a0032c7, + 0x1b80, 0x7b0032d5, + 0x1b80, 0x7b0032d7, + 0x1b80, 0x000132e5, + 0x1b80, 0x000132e7, + 0x1b80, 0x000732f5, + 0x1b80, 0x000732f7, + 0x1b80, 0x78ae3305, + 0x1b80, 0x78ae3307, + 0x1b80, 0x79fa3315, + 0x1b80, 0x79fa3317, + 0x1b80, 0x7a013325, + 0x1b80, 0x7a013327, + 0x1b80, 0x7b803335, + 0x1b80, 0x7b803337, + 0x1b80, 0x7b003345, + 0x1b80, 0x7b003347, + 0x1b80, 0x787a3355, + 0x1b80, 0x787a3357, + 0x1b80, 0x79f13365, + 0x1b80, 0x79f13367, + 0x1b80, 0x7b813375, + 0x1b80, 0x7b813377, + 0x1b80, 0x7b013385, + 0x1b80, 0x7b013387, + 0x1b80, 0x78283395, + 0x1b80, 0x78283397, + 0x1b80, 0x79b433a5, + 0x1b80, 0x79b433a7, + 0x1b80, 0x7a0033b5, + 0x1b80, 0x7a0033b7, + 0x1b80, 0x7b0033c5, + 0x1b80, 0x7b0033c7, + 0x1b80, 0x000133d5, + 0x1b80, 0x000133d7, + 0x1b80, 0x000733e5, + 0x1b80, 0x000733e7, + 0x1b80, 0x750033f5, + 0x1b80, 0x750033f7, + 0x1b80, 0x76023405, + 0x1b80, 0x76023407, + 0x1b80, 0x77153415, + 0x1b80, 0x77153417, + 0x1b80, 0x00063425, + 0x1b80, 0x00063427, + 0x1b80, 0x74003435, + 0x1b80, 0x74003437, + 0x1b80, 0x76003445, + 0x1b80, 0x76003447, + 0x1b80, 0x77003455, + 0x1b80, 0x77003457, + 0x1b80, 0x75103465, + 0x1b80, 0x75103467, + 0x1b80, 0x75003475, + 0x1b80, 0x75003477, + 0x1b80, 0xb3003485, + 0x1b80, 0xb3003487, + 0x1b80, 0x93003495, + 0x1b80, 0x93003497, + 0x1b80, 0x000734a5, + 0x1b80, 0x000734a7, + 0x1b80, 0x760034b5, + 0x1b80, 0x760034b7, + 0x1b80, 0x770034c5, + 0x1b80, 0x770034c7, + 0x1b80, 0x000134d5, + 0x1b80, 0x000134d7, + 0x1b80, 0x000734e5, + 0x1b80, 0x000734e7, + 0x1b80, 0x750034f5, + 0x1b80, 0x750034f7, + 0x1b80, 0x76023505, + 0x1b80, 0x76023507, + 0x1b80, 0x77253515, + 0x1b80, 0x77253517, + 0x1b80, 0x00063525, + 0x1b80, 0x00063527, + 0x1b80, 0x74003535, + 0x1b80, 0x74003537, + 0x1b80, 0x76003545, + 0x1b80, 0x76003547, + 0x1b80, 0x77013555, + 0x1b80, 0x77013557, + 0x1b80, 0x75103565, + 0x1b80, 0x75103567, + 0x1b80, 0x75003575, + 0x1b80, 0x75003577, + 0x1b80, 0xb3003585, + 0x1b80, 0xb3003587, + 0x1b80, 0x93003595, + 0x1b80, 0x93003597, + 0x1b80, 0x000735a5, + 0x1b80, 0x000735a7, + 0x1b80, 0x760035b5, + 0x1b80, 0x760035b7, + 0x1b80, 0x770035c5, + 0x1b80, 0x770035c7, + 0x1b80, 0x000135d5, + 0x1b80, 0x000135d7, + 0x1b80, 0x000435e5, + 0x1b80, 0x000435e7, + 0x1b80, 0x448035f5, + 0x1b80, 0x448035f7, + 0x1b80, 0x47303605, + 0x1b80, 0x47303607, + 0x1b80, 0x00063615, + 0x1b80, 0x00063617, + 0x1b80, 0x776c3625, + 0x1b80, 0x776c3627, + 0x1b80, 0x00013635, + 0x1b80, 0x00013637, + 0x1b80, 0x00053645, + 0x1b80, 0x00053647, + 0x1b80, 0x5c803655, + 0x1b80, 0x5c803657, + 0x1b80, 0x5f303665, + 0x1b80, 0x5f303667, + 0x1b80, 0x00063675, + 0x1b80, 0x00063677, + 0x1b80, 0x776d3685, + 0x1b80, 0x776d3687, + 0x1b80, 0x00013695, + 0x1b80, 0x00013697, + 0x1b80, 0xb90036a5, + 0x1b80, 0xb90036a7, + 0x1b80, 0x990036b5, + 0x1b80, 0x990036b7, + 0x1b80, 0x000636c5, + 0x1b80, 0x000636c7, + 0x1b80, 0x770036d5, + 0x1b80, 0x770036d7, + 0x1b80, 0x980536e5, + 0x1b80, 0x980536e7, + 0x1b80, 0x000436f5, + 0x1b80, 0x000436f7, + 0x1b80, 0x40083705, + 0x1b80, 0x40083707, + 0x1b80, 0x4a023715, + 0x1b80, 0x4a023717, + 0x1b80, 0x30193725, + 0x1b80, 0x30193727, + 0x1b80, 0x00013735, + 0x1b80, 0x00013737, + 0x1b80, 0x7b483745, + 0x1b80, 0x7b483747, + 0x1b80, 0x7a903755, + 0x1b80, 0x7a903757, + 0x1b80, 0x79003765, + 0x1b80, 0x79003767, + 0x1b80, 0x55033775, + 0x1b80, 0x55033777, + 0x1b80, 0x33803785, + 0x1b80, 0x33803787, + 0x1b80, 0x7b383795, + 0x1b80, 0x7b383797, + 0x1b80, 0x7a8037a5, + 0x1b80, 0x7a8037a7, + 0x1b80, 0x550b37b5, + 0x1b80, 0x550b37b7, + 0x1b80, 0x338037c5, + 0x1b80, 0x338037c7, + 0x1b80, 0x7b4037d5, + 0x1b80, 0x7b4037d7, + 0x1b80, 0x7a0037e5, + 0x1b80, 0x7a0037e7, + 0x1b80, 0x551337f5, + 0x1b80, 0x551337f7, + 0x1b80, 0x74013805, + 0x1b80, 0x74013807, + 0x1b80, 0x74003815, + 0x1b80, 0x74003817, + 0x1b80, 0x8e003825, + 0x1b80, 0x8e003827, + 0x1b80, 0x00013835, + 0x1b80, 0x00013837, + 0x1b80, 0x57023845, + 0x1b80, 0x57023847, + 0x1b80, 0x57003855, + 0x1b80, 0x57003857, + 0x1b80, 0x97003865, + 0x1b80, 0x97003867, + 0x1b80, 0x00013875, + 0x1b80, 0x00013877, + 0x1b80, 0x4f783885, + 0x1b80, 0x4f783887, + 0x1b80, 0x53883895, + 0x1b80, 0x53883897, + 0x1b80, 0xe39438a5, + 0x1b80, 0xe39438a7, + 0x1b80, 0x548038b5, + 0x1b80, 0x548038b7, + 0x1b80, 0x540038c5, + 0x1b80, 0x540038c7, + 0x1b80, 0x548138d5, + 0x1b80, 0x548138d7, + 0x1b80, 0x540038e5, + 0x1b80, 0x540038e7, + 0x1b80, 0x548238f5, + 0x1b80, 0x548238f7, + 0x1b80, 0x54003905, + 0x1b80, 0x54003907, + 0x1b80, 0xe39f3915, + 0x1b80, 0xe39f3917, + 0x1b80, 0xbf1d3925, + 0x1b80, 0xbf1d3927, + 0x1b80, 0x30193935, + 0x1b80, 0x30193937, + 0x1b80, 0xe3743945, + 0x1b80, 0xe3743947, + 0x1b80, 0xe3793955, + 0x1b80, 0xe3793957, + 0x1b80, 0xe37d3965, + 0x1b80, 0xe37d3967, + 0x1b80, 0xe3843975, + 0x1b80, 0xe3843977, + 0x1b80, 0xe3de3985, + 0x1b80, 0xe3de3987, + 0x1b80, 0x55133995, + 0x1b80, 0x55133997, + 0x1b80, 0xe38039a5, + 0x1b80, 0xe38039a7, + 0x1b80, 0x551539b5, + 0x1b80, 0x551539b7, + 0x1b80, 0xe38439c5, + 0x1b80, 0xe38439c7, + 0x1b80, 0xe3de39d5, + 0x1b80, 0xe3de39d7, + 0x1b80, 0x000139e5, + 0x1b80, 0x000139e7, + 0x1b80, 0x54bf39f5, + 0x1b80, 0x54bf39f7, + 0x1b80, 0x54c03a05, + 0x1b80, 0x54c03a07, + 0x1b80, 0x54a33a15, + 0x1b80, 0x54a33a17, + 0x1b80, 0x54c13a25, + 0x1b80, 0x54c13a27, + 0x1b80, 0x54a43a35, + 0x1b80, 0x54a43a37, + 0x1b80, 0x4c183a45, + 0x1b80, 0x4c183a47, + 0x1b80, 0xbf073a55, + 0x1b80, 0xbf073a57, + 0x1b80, 0x54c23a65, + 0x1b80, 0x54c23a67, + 0x1b80, 0x54a43a75, + 0x1b80, 0x54a43a77, + 0x1b80, 0xbf043a85, + 0x1b80, 0xbf043a87, + 0x1b80, 0x54c13a95, + 0x1b80, 0x54c13a97, + 0x1b80, 0x54a33aa5, + 0x1b80, 0x54a33aa7, + 0x1b80, 0xbf013ab5, + 0x1b80, 0xbf013ab7, + 0x1b80, 0xe3ec3ac5, + 0x1b80, 0xe3ec3ac7, + 0x1b80, 0x54df3ad5, + 0x1b80, 0x54df3ad7, + 0x1b80, 0x00013ae5, + 0x1b80, 0x00013ae7, + 0x1b80, 0x54bf3af5, + 0x1b80, 0x54bf3af7, + 0x1b80, 0x54e53b05, + 0x1b80, 0x54e53b07, + 0x1b80, 0x050a3b15, + 0x1b80, 0x050a3b17, + 0x1b80, 0x54df3b25, + 0x1b80, 0x54df3b27, + 0x1b80, 0x00013b35, + 0x1b80, 0x00013b37, + 0x1b80, 0x7f403b45, + 0x1b80, 0x7f403b47, + 0x1b80, 0x7e003b55, + 0x1b80, 0x7e003b57, + 0x1b80, 0x7d003b65, + 0x1b80, 0x7d003b67, + 0x1b80, 0x55013b75, + 0x1b80, 0x55013b77, + 0x1b80, 0x5c313b85, + 0x1b80, 0x5c313b87, + 0x1b80, 0xe3803b95, + 0x1b80, 0xe3803b97, + 0x1b80, 0xe3843ba5, + 0x1b80, 0xe3843ba7, + 0x1b80, 0x54803bb5, + 0x1b80, 0x54803bb7, + 0x1b80, 0x54003bc5, + 0x1b80, 0x54003bc7, + 0x1b80, 0x54813bd5, + 0x1b80, 0x54813bd7, + 0x1b80, 0x54003be5, + 0x1b80, 0x54003be7, + 0x1b80, 0x54823bf5, + 0x1b80, 0x54823bf7, + 0x1b80, 0x54003c05, + 0x1b80, 0x54003c07, + 0x1b80, 0xe39f3c15, + 0x1b80, 0xe39f3c17, + 0x1b80, 0xbfed3c25, + 0x1b80, 0xbfed3c27, + 0x1b80, 0x30193c35, + 0x1b80, 0x30193c37, + 0x1b80, 0x74023c45, + 0x1b80, 0x74023c47, + 0x1b80, 0x003f3c55, + 0x1b80, 0x003f3c57, + 0x1b80, 0x74003c65, + 0x1b80, 0x74003c67, + 0x1b80, 0x00023c75, + 0x1b80, 0x00023c77, + 0x1b80, 0x00013c85, + 0x1b80, 0x00013c87, + 0x1b80, 0x00063c95, + 0x1b80, 0x00063c97, + 0x1b80, 0x5a803ca5, + 0x1b80, 0x5a803ca7, + 0x1b80, 0x5a003cb5, + 0x1b80, 0x5a003cb7, + 0x1b80, 0x92003cc5, + 0x1b80, 0x92003cc7, + 0x1b80, 0x00013cd5, + 0x1b80, 0x00013cd7, + 0x1b80, 0x5b8f3ce5, + 0x1b80, 0x5b8f3ce7, + 0x1b80, 0x5b0f3cf5, + 0x1b80, 0x5b0f3cf7, + 0x1b80, 0x91003d05, + 0x1b80, 0x91003d07, + 0x1b80, 0x00013d15, + 0x1b80, 0x00013d17, + 0x1b80, 0x00063d25, + 0x1b80, 0x00063d27, + 0x1b80, 0x5d803d35, + 0x1b80, 0x5d803d37, + 0x1b80, 0x5e563d45, + 0x1b80, 0x5e563d47, + 0x1b80, 0x00043d55, + 0x1b80, 0x00043d57, + 0x1b80, 0x4d083d65, + 0x1b80, 0x4d083d67, + 0x1b80, 0x57103d75, + 0x1b80, 0x57103d77, + 0x1b80, 0x57003d85, + 0x1b80, 0x57003d87, + 0x1b80, 0x4d003d95, + 0x1b80, 0x4d003d97, + 0x1b80, 0x00063da5, + 0x1b80, 0x00063da7, + 0x1b80, 0x5d003db5, + 0x1b80, 0x5d003db7, + 0x1b80, 0x00043dc5, + 0x1b80, 0x00043dc7, + 0x1b80, 0x00013dd5, + 0x1b80, 0x00013dd7, + 0x1b80, 0x549f3de5, + 0x1b80, 0x549f3de7, + 0x1b80, 0x54ff3df5, + 0x1b80, 0x54ff3df7, + 0x1b80, 0x54003e05, + 0x1b80, 0x54003e07, + 0x1b80, 0x00013e15, + 0x1b80, 0x00013e17, + 0x1b80, 0x5c313e25, + 0x1b80, 0x5c313e27, + 0x1b80, 0x07143e35, + 0x1b80, 0x07143e37, + 0x1b80, 0x54003e45, + 0x1b80, 0x54003e47, + 0x1b80, 0x5c323e55, + 0x1b80, 0x5c323e57, + 0x1b80, 0x00013e65, + 0x1b80, 0x00013e67, + 0x1b80, 0x5c323e75, + 0x1b80, 0x5c323e77, + 0x1b80, 0x07143e85, + 0x1b80, 0x07143e87, + 0x1b80, 0x54003e95, + 0x1b80, 0x54003e97, + 0x1b80, 0x5c313ea5, + 0x1b80, 0x5c313ea7, + 0x1b80, 0x00013eb5, + 0x1b80, 0x00013eb7, + 0x1b80, 0x4c983ec5, + 0x1b80, 0x4c983ec7, + 0x1b80, 0x4c183ed5, + 0x1b80, 0x4c183ed7, + 0x1b80, 0x00013ee5, + 0x1b80, 0x00013ee7, + 0x1b80, 0x5c323ef5, + 0x1b80, 0x5c323ef7, + 0x1b80, 0x62043f05, + 0x1b80, 0x62043f07, + 0x1b80, 0x63033f15, + 0x1b80, 0x63033f17, + 0x1b80, 0x66073f25, + 0x1b80, 0x66073f27, + 0x1b80, 0x7b403f35, + 0x1b80, 0x7b403f37, + 0x1b80, 0x7a003f45, + 0x1b80, 0x7a003f47, + 0x1b80, 0x79003f55, + 0x1b80, 0x79003f57, + 0x1b80, 0x7f403f65, + 0x1b80, 0x7f403f67, + 0x1b80, 0x7e003f75, + 0x1b80, 0x7e003f77, + 0x1b80, 0x7d003f85, + 0x1b80, 0x7d003f87, + 0x1b80, 0x09013f95, + 0x1b80, 0x09013f97, + 0x1b80, 0x0c013fa5, + 0x1b80, 0x0c013fa7, + 0x1b80, 0x0ba63fb5, + 0x1b80, 0x0ba63fb7, + 0x1b80, 0x00013fc5, + 0x1b80, 0x00013fc7, + 0x1b80, 0x00000006, + 0x1b80, 0x00000002, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8822c_array_mp_cal_init, rtw_phy_cfg_bb); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.h b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.h new file mode 100644 index 000000000..2ae2b0aa5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8822C_TABLE_H__ +#define __RTW8822C_TABLE_H__ + +extern const struct rtw_table rtw8822c_mac_tbl; +extern const struct rtw_table rtw8822c_agc_tbl; +extern const struct rtw_table rtw8822c_bb_tbl; +extern const struct rtw_table rtw8822c_bb_pg_type0_tbl; +extern const struct rtw_table rtw8822c_rf_a_tbl; +extern const struct rtw_table rtw8822c_rf_b_tbl; +extern const struct rtw_table rtw8822c_txpwr_lmt_type0_tbl; +extern const struct rtw_table rtw8822c_txpwr_lmt_type5_tbl; +extern const struct rtw_table rtw8822c_dpk_afe_no_dpk_tbl; +extern const struct rtw_table rtw8822c_dpk_afe_is_dpk_tbl; +extern const struct rtw_table rtw8822c_dpk_mac_bb_tbl; +extern const struct rtw_table rtw8822c_array_mp_cal_init_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822ce.c b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c new file mode 100644 index 000000000..7ae95415c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8822c.h" + +static const struct pci_device_id rtw_8822ce_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC822), + .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC82F), + .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8822ce_id_table); + +static struct pci_driver rtw_8822ce_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8822ce_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, +}; +module_pci_driver(rtw_8822ce_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822ce driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822cs.c b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c new file mode 100644 index 000000000..b00ef4173 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl + */ + +#include +#include +#include +#include "main.h" +#include "rtw8822c.h" +#include "sdio.h" + +static const struct sdio_device_id rtw_8822cs_id_table[] = { + { + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, + SDIO_DEVICE_ID_REALTEK_RTW8822CS), + .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec, + }, + {} +}; +MODULE_DEVICE_TABLE(sdio, rtw_8822cs_id_table); + +static struct sdio_driver rtw_8822cs_driver = { + .name = KBUILD_MODNAME, + .probe = rtw_sdio_probe, + .remove = rtw_sdio_remove, + .shutdown = rtw_sdio_shutdown, + .id_table = rtw_8822cs_id_table, + .drv = { + .pm = &rtw_sdio_pm_ops, + } +}; +module_sdio_driver(rtw_8822cs_driver); + +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822cu.c b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c new file mode 100644 index 000000000..755f76840 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8822c.h" +#include "usb.h" + +static const struct usb_device_id rtw_8822cu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */ + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table); + +static int rtw8822cu_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return rtw_usb_probe(intf, id); +} + +static struct usb_driver rtw_8822cu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8822cu_id_table, + .probe = rtw8822cu_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8822cu_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c new file mode 100644 index 000000000..2eaadcfec --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c @@ -0,0 +1,1990 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "phy.h" +#include "rtw88xxa.h" +#include "mac.h" +#include "reg.h" +#include "sec.h" +#include "debug.h" +#include "bf.h" +#include "efuse.h" +#include "usb.h" + +void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, + BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} +EXPORT_SYMBOL(rtw88xxa_efuse_grant); + +static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && + (efuse->pa_type_2g & BIT(4)); + efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && + (efuse->lna_type_2g & BIT(3)); + + efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && + (efuse->pa_type_5g & BIT(0)); + efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && + (efuse->lna_type_5g & BIT(3)); + + /* For rtw_phy_cond2: */ + if (efuse->ext_pa_2g) { + u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); + u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); + + efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; + } + + if (efuse->ext_pa_5g) { + u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); + u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); + + efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; + } + + if (efuse->ext_lna_2g) { + u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, + BIT(1) | BIT(0)); + u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, + BIT(5) | BIT(4)); + + efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; + } + + if (efuse->ext_lna_5g) { + u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, + BIT(1) | BIT(0)); + u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, + BIT(5) | BIT(4)); + + efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; + } +} + +static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, + struct rtw88xxa_efuse *map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (map->rfe_option == 0xff) { + if (rtwdev->hci.type == RTW_HCI_TYPE_USB) + efuse->rfe_option = 0; + else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 2; + else + efuse->rfe_option = 4; + } else if (map->rfe_option & BIT(7)) { + if (efuse->ext_lna_5g) { + if (efuse->ext_pa_5g) { + if (efuse->ext_lna_2g && efuse->ext_pa_2g) + efuse->rfe_option = 3; + else + efuse->rfe_option = 0; + } else { + efuse->rfe_option = 2; + } + } else { + efuse->rfe_option = 4; + } + } else { + efuse->rfe_option = map->rfe_option & 0x3f; + + /* Due to other customer already use incorrect EFUSE map for + * their product. We need to add workaround to prevent to + * modify spec and notify all customer to revise the IC 0xca + * content. + */ + if (efuse->rfe_option == 4 && + (efuse->ext_pa_5g || efuse->ext_pa_2g || + efuse->ext_lna_5g || efuse->ext_lna_2g)) { + if (rtwdev->hci.type == RTW_HCI_TYPE_USB) + efuse->rfe_option = 0; + else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 2; + } + } +} + +static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + u8 antenna = 0; + u8 wmode = 0; + u8 val8, i; + + efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | + BIT(RTW_CHANNEL_WIDTH_40) | + BIT(RTW_CHANNEL_WIDTH_80); + efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + efuse->hw_cap.nss = 1; + else + efuse->hw_cap.nss = 2; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + goto print_hw_cap; + + for (i = 0; i < 2; i++) { + rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); + + antenna = u8_get_bits(val8, GENMASK(7, 5)); + if (antenna) + break; + antenna = u8_get_bits(val8, GENMASK(3, 1)); + if (antenna) + break; + } + + for (i = 0; i < 2; i++) { + rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); + + wmode = u8_get_bits(val8, GENMASK(3, 2)); + if (wmode) + break; + } + + if (antenna == 1) { + rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); + + efuse->hw_cap.nss = 1; + hal->rf_type = RF_1T1R; + hal->rf_path_num = 1; + hal->rf_phy_num = 1; + hal->antenna_tx = BB_PATH_A; + hal->antenna_rx = BB_PATH_A; + } else { + /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ + efuse->hw_cap.nss = 2; + hal->rf_type = RF_2T2R; + hal->rf_path_num = 2; + hal->rf_phy_num = 2; + hal->antenna_tx = BB_PATH_AB; + hal->antenna_rx = BB_PATH_AB; + + if (antenna == 2 && wmode == 2) { + rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); + + /* Can't be EFUSE_HW_CAP_IGNORE and can't be + * EFUSE_HW_CAP_PTCL_VHT, so make it 1. + */ + efuse->hw_cap.ptcl = 1; + efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); + } + } + +print_hw_cap: + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, + efuse->hw_cap.ant_num, efuse->hw_cap.nss); +} + +int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw88xxa_efuse *map; + int i; + + if (chip->id == RTW_CHIP_TYPE_8812A) + rtwdev->hal.cut_version += 1; + + if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, + log_map, chip->log_efuse_size, true); + + map = (struct rtw88xxa_efuse *)log_map; + + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + if (efuse->crystal_cap == 0xff) + efuse->crystal_cap = 0x20; + efuse->pa_type_2g = map->pa_type; + efuse->pa_type_5g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g; + efuse->lna_type_5g = map->lna_type_5g; + if (chip->id == RTW_CHIP_TYPE_8812A) { + rtw8812a_read_amplifier_type(rtwdev); + rtw8812a_read_rfe_type(rtwdev, map); + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); + } + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter[1] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + rtw88xxa_read_usb_type(rtwdev); + + if (chip->id == RTW_CHIP_TYPE_8821A) + efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, + BIT_BT_FUNC_EN); + else + efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; + efuse->share_ant = !!(efuse->bt_setting & BIT(0)); + + /* No antenna diversity because it's disabled in the vendor driver */ + efuse->ant_div_cfg = 0; + + efuse->ant_div_type = map->rf_antenna_option; + if (efuse->ant_div_type == 0xff) + efuse->ant_div_type = 0x3; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_USB: + if (chip->id == RTW_CHIP_TYPE_8821A) + ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); + else + ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); + break; + case RTW_HCI_TYPE_PCIE: + case RTW_HCI_TYPE_SDIO: + default: + /* unsupported now */ + return -EOPNOTSUPP; + } + + return 0; +} +EXPORT_SYMBOL(rtw88xxa_read_efuse); + +static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 val8; + + /* Reset MCU IO Wrapper */ + rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); + else + rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); + + val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); + rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); + + /* Enable MCU IO Wrapper */ + rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); + else + rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); + + rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); +} + +/* A lightweight deinit function */ +static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev) +{ + u8 val8; + + if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) + return; + + rtw88xxa_reset_8051(rtwdev); + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); + + /* before BB reset should do clock gated */ + rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); + + /* reset BB */ + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); + + /* reset RF */ + rtw_write8(rtwdev, REG_RF_CTRL, 0); + + /* reset TRX path */ + rtw_write16(rtwdev, REG_CR, 0); + + /* reset MAC, reg0x5[1], auto FSM off */ + rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); + + /* check if reg0x5[1] auto cleared */ + if (read_poll_timeout_atomic(rtw_read8, val8, + !(val8 & (APS_FSMCO_MAC_OFF >> 8)), + 1, 5000, false, + rtwdev, REG_APS_FSMCO + 1)) + rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); + + /* reg0x5[0], auto FSM on */ + val8 |= APS_FSMCO_MAC_ENABLE >> 8; + rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); + + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); +} + +static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u16 val16; + int ret; + + ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); + if (ret) { + rtw_err(rtwdev, "power on flow failed\n"); + return ret; + } + + rtw_write16(rtwdev, REG_CR, 0); + val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | + BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN; + rtw_write16_set(rtwdev, REG_CR, val16); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) + rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); + } + + return ret; +} + +static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) +{ + u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; + int count = 0; + + rtw_write32(rtwdev, REG_LLT_INIT, value); + + do { + if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) + break; + + if (count > 20) { + rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", + address); + return -EBUSY; + } + } while (++count); + + return 0; +} + +static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary) +{ + u32 last_entry = 255; + int status = 0; + u32 i; + + for (i = 0; i < boundary - 1; i++) { + status = rtw88xxa_llt_write(rtwdev, i, i + 1); + if (status) + return status; + } + + status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF); + if (status) + return status; + + for (i = boundary; i < last_entry; i++) { + status = rtw88xxa_llt_write(rtwdev, i, i + 1); + if (status) + return status; + } + + status = rtw88xxa_llt_write(rtwdev, last_entry, boundary); + + return status; +} + +static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + const struct rtw_page_table *pg_tbl = NULL; + u16 pubq_num; + u32 val32; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + pg_tbl = &chip->page_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (rtwdev->hci.bulkout_num == 2) + pg_tbl = &chip->page_table[2]; + else if (rtwdev->hci.bulkout_num == 3) + pg_tbl = &chip->page_table[3]; + else if (rtwdev->hci.bulkout_num == 4) + pg_tbl = &chip->page_table[4]; + break; + case RTW_HCI_TYPE_SDIO: + pg_tbl = &chip->page_table[0]; + break; + default: + break; + } + + pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - + pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; + + val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); + rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + + val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); + rtw_write32(rtwdev, REG_RQPN, val32); +} + +static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + + rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); +} + +static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 bulkout_num = rtwdev->hci.bulkout_num; + const struct rtw_rqpn *rqpn = NULL; + u16 txdma_pq_map; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rqpn = &chip->rqpn_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (bulkout_num == 2) + rqpn = &chip->rqpn_table[2]; + else if (bulkout_num == 3) + rqpn = &chip->rqpn_table[3]; + else if (bulkout_num == 4) + rqpn = &chip->rqpn_table[4]; + else + return -EINVAL; + break; + case RTW_HCI_TYPE_SDIO: + rqpn = &chip->rqpn_table[0]; + break; + default: + return -EINVAL; + } + + rtwdev->fifo.rqpn = rqpn; + + txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; + txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); + txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); + txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); + txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); + txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); + txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); + rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); + + /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) + rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); + + return 0; +} + +static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev) +{ + rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); + rtwdev->hal.rxfltmap1 = 0x0400; + rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1); + rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); + + rtw_write32(rtwdev, REG_MAR, 0xffffffff); + rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); +} + +static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); + rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); +} + +static void rtw88xxa_init_edca(struct rtw_dev *rtwdev) +{ + rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); + + rtw_write16(rtwdev, REG_SIFS, 0x100a); + rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); + + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + + rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); + rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); +} + +static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, + chip->usb_tx_agg_desc_num); + + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw_write8(rtwdev, REG_DWBCN1_CTRL, + chip->usb_tx_agg_desc_num << 1); +} + +static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) +{ + u16 val16; + + val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; + if (rtwdev->efuse.btcoex) + val16 |= BIT_EN_BCN_FUNCTION; + rtw_write16(rtwdev, REG_BCN_CTRL, val16); + + rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); +} + +static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) +{ + u8 val8, crystal_cap; + + /* power on BB/RF domain */ + val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); + val8 |= BIT_FEN_USBA; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); + + /* toggle BB reset */ + val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); + + rtw_write8(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write8(rtwdev, REG_RF_B_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + + rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); + rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, + crystal_cap | (crystal_cap << 6)); + else + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, + crystal_cap | (crystal_cap << 6)); +} + +static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) +{ + u8 rf_path; + + for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) + rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); +} + +static void rtw8812a_config_1t(struct rtw_dev *rtwdev) +{ + /* BB OFDM RX Path_A */ + rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); + + /* BB OFDM TX Path_A */ + rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); + + /* BB CCK R/Rx Path_A */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); + + /* MCS support */ + rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4); + + /* RF Path_B HSSI OFF */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); + + /* RF Path_B Power Down */ + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); + + /* ADDA Path_B OFF */ + rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); + rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); +} + +static const u32 rtw88xxa_txscale_tbl[] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) +{ + static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 tx_bb_swing; + + if (band == RTW_BAND_2G) + tx_bb_swing = efuse->tx_bb_swing_setting_2g; + else + tx_bb_swing = efuse->tx_bb_swing_setting_5g; + + if (path == RF_PATH_B) + tx_bb_swing >>= 2; + tx_bb_swing &= 0x3; + + return swing2setting[tx_bb_swing]; +} + +static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev) +{ + u32 swing, table_value; + u8 i; + + swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, + RF_PATH_A); + + for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) { + table_value = rtw88xxa_txscale_tbl[i]; + if (swing == table_value) + return i; + } + + return 24; +} + +static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + dm_info->default_cck_index = 0; + else + dm_info->default_cck_index = 24; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + dm_info->delta_power_index_last[path] = 0; + } + + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +void rtw88xxa_power_off(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd *const *enter_lps_flow) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + enum usb_device_speed speed = rtwusb->udev->speed; + u16 ori_fsmc0; + u8 reg_cr; + + reg_cr = rtw_read8(rtwdev, REG_CR); + + /* Already powered off */ + if (reg_cr == 0 || reg_cr == 0xEA) + return; + + rtw_hci_stop(rtwdev); + + if (!rtwdev->efuse.btcoex) + rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); + + /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ + if (speed == USB_SPEED_SUPER) + rtw_write8_set(rtwdev, REG_USB_MOD, 0x18); + + rtw_write32(rtwdev, REG_HISR0, 0xffffffff); + rtw_write32(rtwdev, REG_HISR1, 0xffffffff); + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + if (rtwdev->efuse.btcoex) + rtw_coex_power_off_setting(rtwdev); + + ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); + rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); + + /* Stop Tx Report Timer. */ + rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); + + /* Stop Rx */ + rtw_write8(rtwdev, REG_CR, 0); + + rtw_pwr_seq_parser(rtwdev, enter_lps_flow); + + if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) + rtw88xxa_reset_8051(rtwdev); + + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); + + rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); + + if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) + rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); + + clear_bit(RTW_FLAG_POWERON, rtwdev->flags); +} +EXPORT_SYMBOL(rtw88xxa_power_off); + +static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, + rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A)); + rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, + rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B)); + rtw88xxa_pwrtrack_init(rtwdev); +} + +static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); + rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); + + if (band == RTW_BAND_2G) + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); + else + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); +} + +static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + /* Turn off RF PA and LNA */ + + /* 0xCB0[15:12] = 0x7 (LNA_On)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); + /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); + + if (efuse->ext_lna_2g) { + /* Turn on 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); + } else { + /* Bypass 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); + } +} + +static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + /* Turn ON RF PA and LNA */ + + /* 0xCB0[15:12] = 0x7 (LNA_On)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); + /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); + + /* Bypass 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); +} + +static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 0: + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + break; + case 1: + if (rtwdev->efuse.btcoex) { + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } + break; + case 3: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); + break; + case 4: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); + break; + case 5: + rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + break; + case 6: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + break; + default: + break; + } +} + +static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 0: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 1: + if (rtwdev->efuse.btcoex) { + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } + break; + case 2: + case 4: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 3: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); + break; + case 5: + rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); + rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 6: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + break; + default: + break; + } +} + +static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u16 basic_rates, reg_41a; + + /* 8811au one antenna module doesn't support antenna div, so driver must + * control antenna band, otherwise one of the band will have issue + */ + if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && + rtwdev->efuse.ant_div_cfg == 0) + rtw8821a_set_ext_band_switch(rtwdev, new_band); + + if (new_band == RTW_BAND_2G) { + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + rtw8821a_phy_set_rfe_reg_24g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); + } else { + rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); + + if (bw == RTW_CHANNEL_WIDTH_20 && + rtwdev->hal.rf_type == RF_1T1R && + !rtwdev->efuse.ext_lna_2g) + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); + else + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); + + rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); + + rtw8812a_phy_set_rfe_reg_24g(rtwdev); + } + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); + + basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | + BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | + BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | + BIT(DESC_RATE24M); + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); + + rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + } else { /* RTW_BAND_5G */ + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw8821a_phy_set_rfe_reg_5g(rtwdev); + + rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + + read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, + 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); + + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); + } else { + rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); + + rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); + + rtw8812a_phy_set_rfe_reg_5g(rtwdev); + } + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); + + basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | + BIT(DESC_RATE24M); + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); + } + + rtw88xxa_set_channel_bb_swing(rtwdev, new_band); +} + +int rtw88xxa_power_on(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + int ret; + + if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + return 0; + + /* Override rtw_chip_efuse_info_setup() */ + if (chip->id == RTW_CHIP_TYPE_8821A) + efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, + BIT_BT_FUNC_EN); + + /* Override rtw_chip_efuse_info_setup() */ + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_read_amplifier_type(rtwdev); + + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + goto err; + } + + /* Revise for U2/U3 switch we can not update RF-A/B reset. + * Reset after MAC power on to prevent RF R/W error. + * Is it a right method? + */ + if (chip->id == RTW_CHIP_TYPE_8812A) { + rtw_write8(rtwdev, REG_RF_CTRL, 5); + rtw_write8(rtwdev, REG_RF_CTRL, 7); + rtw_write8(rtwdev, REG_RF_B_CTRL, 5); + rtw_write8(rtwdev, REG_RF_B_CTRL, 7); + } + + /* If HW didn't go through a complete de-initial procedure, + * it probably occurs some problem for double initial + * procedure. + */ + rtw88xxau_hw_reset(rtwdev); + + ret = rtw88xxau_init_power_on(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to power on\n"); + goto err; + } + + ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to set trx fifo info\n"); + goto err; + } + + ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); + if (ret) { + rtw_err(rtwdev, "failed to init llt\n"); + goto err; + } + + rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + + ret = rtw_wait_firmware_completion(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to wait firmware completion\n"); + goto err_off; + } + + ret = rtw_download_firmware(rtwdev, &rtwdev->fw); + if (ret) { + rtw_err(rtwdev, "failed to download firmware\n"); + goto err_off; + } + + rtw_write8(rtwdev, REG_HMETFR, 0xf); + + rtw_load_table(rtwdev, chip->mac_tbl); + + rtw88xxau_init_queue_reserved_page(rtwdev); + rtw88xxau_init_tx_buffer_boundary(rtwdev); + rtw88xxau_init_queue_priority(rtwdev); + + rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, + chip->rxff_size - REPORT_BUF - 1); + + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8(rtwdev, REG_PBP, + u8_encode_bits(PBP_512, PBP_TX_MASK) | + u8_encode_bits(PBP_64, PBP_RX_MASK)); + + rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); + + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); + + rtw88xxa_init_wmac_setting(rtwdev); + rtw88xxa_init_adaptive_ctrl(rtwdev); + rtw88xxa_init_edca(rtwdev); + + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + rtw_write8(rtwdev, REG_ACKTO, 0x80); + + rtw88xxau_tx_aggregation(rtwdev); + + rtw88xxa_init_beacon_parameters(rtwdev); + rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); + + rtw_hci_interface_cfg(rtwdev); + + /* usb3 rx interval */ + rtw_write8(rtwdev, REG_USB3_RXITV, 0x01); + + /* burst length=4, set 0x3400 for burst length=2 */ + rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); + rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); + + /* 0x456 = 0x70, sugguested by Zhilin */ + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); + else + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); + rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); + rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); + + if (rtwusb->udev->speed == USB_SPEED_SUPER) + /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ + rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); + + rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + + /* for VHT packet length 11K */ + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); + + rtw_write8(rtwdev, REG_PIFS, 0x00); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */ + rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); + rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); + } else { + rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); + rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + } + + /* to prevent mac is reseted by bus. */ + rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); + + /* ARFB table 9 for 11ac 5G 2SS */ + rtw_write32(rtwdev, REG_ARFR0, 0x00000010); + rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); + + /* ARFB table 10 for 11ac 5G 1SS */ + rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); + rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); + + /* ARFB table 11 for 11ac 24G 1SS */ + rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); + rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); + + /* ARFB table 12 for 11ac 24G 2SS */ + rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); + rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); + + rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); + + rtw88xxa_phy_bb_config(rtwdev); + rtw88xxa_phy_rf_config(rtwdev); + + if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) + rtw8812a_config_1t(rtwdev); + + rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); + + rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); + + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); + + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); + + rtw_phy_init(rtwdev); + + rtw88xxa_pwrtrack_init(rtwdev); + + /* 0x4c6[3] 1: RTS BW = Data BW + * 0: RTS BW depends on CCA / secondary CCA result. + */ + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); + + /* enable Tx report. */ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); + + /* Pretx_en, for WEP/TKIP SEC */ + rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); + + rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); + + /* Reset USB mode switch setting */ + rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); + rtw_write8(rtwdev, REG_ACLK_MON, 0x0); + + rtw_write8(rtwdev, REG_USB_HRPWM, 0); + + /* ack for xmit mgmt frames. */ + rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); + + hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, + BIT_CCK_RPT_FORMAT); + + ret = rtw_hci_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start hci\n"); + goto err_off; + } + + if (efuse->btcoex) { + rtw_coex_power_on_setting(rtwdev); + rtw_coex_init_hw_config(rtwdev, false); + } + + set_bit(RTW_FLAG_POWERON, rtwdev->flags); + + return 0; + +err_off: + chip->ops->power_off(rtwdev); + +err: + return ret; +} +EXPORT_SYMBOL(rtw88xxa_power_on); + +u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path rf_path, u32 addr, u32 mask) +{ + static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB }; + static const u32 read_addr[2][2] = { + { REG_SI_READ_A, REG_SI_READ_B }, + { REG_PI_READ_A, REG_PI_READ_B } + }; + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_hal *hal = &rtwdev->hal; + bool set_cca, pi_mode; + u32 val; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + /* CCA off to avoid reading the wrong value. + * Toggling CCA would affect RF 0x0, skip it. + */ + set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && + hal->cut_version != RTW_CHIP_VER_CUT_C; + + if (set_cca) + rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); + + addr &= 0xff; + + pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); + + rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); + + if (chip->id == RTW_CHIP_TYPE_8821A || + hal->cut_version == RTW_CHIP_VER_CUT_C) + udelay(20); + + val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); + + /* CCA on */ + if (set_cca) + rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); + + return val; +} +EXPORT_SYMBOL(rtw88xxa_phy_read_rf); + +static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + /* C cut Item12 ADC FIFO CLOCK */ + if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { + if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) + rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); + else + rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); + + /* A workaround to resolve 2480Mhz spur by setting ADC clock + * as 160M. + */ + if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + } else if (bw != RTW_CHANNEL_WIDTH_80) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + } + } else { + /* A workaround to resolve 2480Mhz spur by setting ADC clock + * as 160M. + */ + if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); + else if (channel <= 14) /* 2.4G only */ + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); + } +} + +static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 fc_area, rf_mod_ag; + u8 path; + + switch (channel) { + case 36 ... 48: + fc_area = 0x494; + break; + case 50 ... 64: + fc_area = 0x453; + break; + case 100 ... 116: + fc_area = 0x452; + break; + default: + if (channel >= 118) + fc_area = 0x412; + else + fc_area = 0x96a; + break; + } + + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); + + for (path = 0; path < hal->rf_path_num; path++) { + switch (channel) { + case 36 ... 64: + rf_mod_ag = 0x101; + break; + case 100 ... 140: + rf_mod_ag = 0x301; + break; + default: + if (channel > 140) + rf_mod_ag = 0x501; + else + rf_mod_ag = 0x000; + break; + } + + rtw_write_rf(rtwdev, path, RF_CFGCH, + RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_phy_fix_spur(rtwdev, channel, bw); + + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel); + } +} + +static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) +{ + u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); + + val16 &= ~BIT_RFMOD; + if (bw == RTW_CHANNEL_WIDTH_80) + val16 |= BIT_RFMOD_80M; + else if (bw == RTW_CHANNEL_WIDTH_40) + val16 |= BIT_RFMOD_40M; + + rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); +} + +static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, + u8 bw, u8 primary_chan_idx) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 txsc40 = 0, txsc20, txsc; + u8 reg_837, l1pkval; + + rtw88xxa_set_reg_bw(rtwdev, bw); + + txsc20 = primary_chan_idx; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } + + txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); + rtw_write8(rtwdev, REG_DATA_SC, txsc); + + reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); + + switch (bw) { + default: + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + + if (hal->rf_type == RF_2T2R) + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); + else + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); + + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); + + if (reg_837 & BIT(2)) { + l1pkval = 6; + } else { + if (hal->rf_type == RF_2T2R) + l1pkval = 7; + else + l1pkval = 8; + } + + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); + + if (txsc == RTW_SC_20_UPPER) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); + + if (reg_837 & BIT(2)) { + l1pkval = 5; + } else { + if (hal->rf_type == RF_2T2R) + l1pkval = 6; + else + l1pkval = 7; + } + + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); + + break; + } +} + +static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u8 path; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); + break; + } + } +} + +void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + u8 old_band, new_band; + + if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) + old_band = RTW_BAND_5G; + else + old_band = RTW_BAND_2G; + + if (channel > 14) + new_band = RTW_BAND_5G; + else + new_band = RTW_BAND_2G; + + if (new_band != old_band) + rtw88xxa_switch_band(rtwdev, new_band, bw); + + rtw88xxa_switch_channel(rtwdev, channel, bw); + + rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_phy_fix_spur(rtwdev, channel, bw); + + rtw88xxa_set_channel_rf(rtwdev, channel, bw); +} +EXPORT_SYMBOL(rtw88xxa_set_channel); + +void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat, + s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_jaguar_phy_status_rpt *rpt; + u8 gain[RTW_RF_PATH_MAX], rssi, i; + s8 rx_pwr_db, power_a, power_b; + const s8 min_rx_power = -120; + u8 lna_idx, vga_idx; + + rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; + + if (pkt_stat->rate <= DESC_RATE11M) { + lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); + vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); + + rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx); + + pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = rx_pwr_db; + } else { /* OFDM rate */ + gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); + gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); + + for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { + pkt_stat->rx_power[i] = gain[i] - 110; + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); + dm_info->rssi[i] = rssi; + } + + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, + rtwdev->hal.rf_path_num); + + power_a = pkt_stat->rx_power[RF_PATH_A]; + power_b = pkt_stat->rx_power[RF_PATH_B]; + if (rtwdev->hal.rf_path_num == 1) + power_b = power_a; + + pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); + } +} +EXPORT_SYMBOL(rtw88xxa_query_phy_status); + +static void +rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) +{ + static const u32 offset_txagc[2] = { + REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1 + }; + u8 rate, rate_idx, pwr_index, shift; + struct rtw_hal *hal = &rtwdev->hal; + bool write_1ss_mcs9; + u32 mask; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + + pwr_index = hal->tx_pwr_tbl[path][rate]; + + shift = rate & 0x3; + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + + write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && + hal->rf_path_num == 1; + + if (write_1ss_mcs9) + mask = MASKLWORD; + else + mask = MASKDWORD; + + if (shift == 0x3 || write_1ss_mcs9) { + rate_idx = rate & 0xfc; + if (rate >= DESC_RATEVHT1SS_MCS0) + rate_idx -= 0x10; + + rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, + mask, *phy_pwr_idx); + + *phy_pwr_idx = 0; + } + } +} + +static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw, + u8 channel, u8 path) +{ + static const u32 write_offset[] = { + REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, + }; + u32 power_level, write_data; + u8 i; + + power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; + write_data = 0; + + for (i = 0; i < 3; i++) { + if (i == 0) + power_level -= 10; + else if (i == 1) + power_level -= 8; + else + power_level -= 6; + + write_data |= max_t(u32, power_level, 2) << (i * 8); + } + + rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); +} + +void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { + if (hal->rf_path_num == 1 && + (rs == RTW_RATE_SECTION_HT_2S || + rs == RTW_RATE_SECTION_VHT_2S)) + continue; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && + rs > RTW_RATE_SECTION_OFDM) + continue; + + if (hal->current_band_type == RTW_BAND_5G && + rs == RTW_RATE_SECTION_CCK) + continue; + + rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); + } + + rtw88xxa_tx_power_training(rtwdev, hal->current_band_width, + hal->current_channel, path); + } +} +EXPORT_SYMBOL(rtw88xxa_set_tx_power_index); + +void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt, ofdm_fa_cnt; + u32 crc32_cnt, cca32_cnt; + u32 cck_enable; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} +EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics); + +void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* save MACBB default value */ + for (i = 0; i < macbb_num; i++) + macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb); + +void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Save AFE Parameters */ + for (i = 0; i < afe_num; i++) + afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe); + +void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Reload MacBB Parameters */ + for (i = 0; i < macbb_num; i++) + rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb); + +void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev) +{ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + rtw_write32_mask(rtwdev, REG_BCN_CTRL, + (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); + + /* RX ante off */ + rtw_write8(rtwdev, REG_RXPSEL, 0x00); + + /* CCA off */ + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); + + /* CCK RX path off */ + rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); +} +EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac); + +bool rtw88xxa_iqk_finish(int average, int threshold, + int *x_temp, int *y_temp, int *x, int *y, + bool break_inner, bool break_outer) +{ + bool finish = false; + int i, ii, dx, dy; + + for (i = 0; i < average; i++) { + for (ii = i + 1; ii < average; ii++) { + dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21); + dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21); + + if (dx < threshold && dy < threshold) { + *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21)); + *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21)); + + *x /= 2; + *y /= 2; + + finish = true; + + if (break_inner) + break; + } + } + + if (finish && break_outer) + break; + } + + return finish; +} +EXPORT_SYMBOL(rtw88xxa_iqk_finish); + +static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) +{ + static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 cck_swing_idx, ofdm_swing_idx; + u8 pwr_tracking_limit; + + switch (tx_rate) { + case DESC_RATE1M ... DESC_RATE11M: + pwr_tracking_limit = 32; + break; + case DESC_RATE6M ... DESC_RATE48M: + case DESC_RATEMCS3 ... DESC_RATEMCS4: + case DESC_RATEMCS11 ... DESC_RATEMCS12: + case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: + pwr_tracking_limit = 30; + break; + case DESC_RATE54M: + case DESC_RATEMCS5 ... DESC_RATEMCS7: + case DESC_RATEMCS13 ... DESC_RATEMCS15: + case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: + pwr_tracking_limit = 28; + break; + case DESC_RATEMCS0 ... DESC_RATEMCS2: + case DESC_RATEMCS8 ... DESC_RATEMCS10: + case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: + pwr_tracking_limit = 34; + break; + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT2SS_MCS7: + pwr_tracking_limit = 26; + break; + default: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT2SS_MCS8: + pwr_tracking_limit = 24; + break; + case DESC_RATEVHT1SS_MCS9: + case DESC_RATEVHT2SS_MCS9: + pwr_tracking_limit = 22; + break; + } + + cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; + ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; + + if (ofdm_swing_idx > pwr_tracking_limit) { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; + dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; + + ofdm_swing_idx = pwr_tracking_limit; + } else if (ofdm_swing_idx == 0) { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = cck_swing_idx; + dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; + } else { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = 0; + dm_info->txagc_remnant_ofdm[path] = 0; + } + + rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), + rtw88xxa_txscale_tbl[ofdm_swing_idx]); +} + +void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, + void (*do_lck)(struct rtw_dev *rtwdev), + void (*do_iqk)(struct rtw_dev *rtwdev)) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_swing_table swing_table; + s8 remnant_pre[RTW_RF_PATH_MAX]; + u8 thermal_value, delta, path; + bool need_iqk; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) { + pr_err_once("efuse thermal meter is 0xff\n"); + return; + } + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (need_iqk && do_lck) + do_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { + remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; + + dm_info->delta_power_index[path] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, + RF_PATH_A, delta); + + if (dm_info->delta_power_index[path] != + dm_info->delta_power_index_last[path]) { + dm_info->delta_power_index_last[path] = + dm_info->delta_power_index[path]; + + rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path); + } + } + + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { + if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { + rtw_phy_set_tx_power_level(rtwdev, + hal->current_channel); + break; + } + } + +iqk: + if (need_iqk) + do_iqk(rtwdev); +} +EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); + +void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* Override rtw_phy_cck_pd_lv_link(). It implements something + * like type 2/3/4. We need type 1 here. + */ + if (rtw_is_assoc(rtwdev)) { + if (dm_info->min_rssi > 60) { + new_lvl = CCK_PD_LV3; + } else if (dm_info->min_rssi > 35) { + new_lvl = CCK_PD_LV2; + } else if (dm_info->min_rssi > 20) { + if (dm_info->cck_fa_avg > 500) + new_lvl = CCK_PD_LV2; + else if (dm_info->cck_fa_avg < 250) + new_lvl = CCK_PD_LV1; + else + return; + } else { + new_lvl = CCK_PD_LV1; + } + } + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + + rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); +} +EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h new file mode 100644 index 000000000..09a45c1a4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW88XXA_H__ +#define __RTW88XXA_H__ + +#include +#include "reg.h" + +struct rtw8821au_efuse { + u8 res4[48]; /* 0xd0 */ + u8 vid[2]; /* 0x100 */ + u8 pid[2]; + u8 res8[3]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 res9[243]; +} __packed; + +struct rtw8812au_efuse { + u8 vid[2]; /* 0xd0 */ + u8 pid[2]; /* 0xd2 */ + u8 res0[3]; + u8 mac_addr[ETH_ALEN]; /* 0xd7 */ + u8 res1[291]; +} __packed; + +struct rtw88xxa_efuse { + __le16 rtl_id; + u8 res0[6]; /* 0x02 */ + u8 usb_mode; /* 0x08 */ + u8 res1[7]; /* 0x09 */ + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g; /* 0xbd */ + u8 res2; + u8 lna_type_5g; /* 0xbf */ + u8 res3; + u8 rf_board_option; /* 0xc1 */ + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; /* 0xc5 */ + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res4[3]; + union { + struct rtw8821au_efuse rtw8821au; + struct rtw8812au_efuse rtw8812au; + }; +} __packed; + +static_assert(sizeof(struct rtw88xxa_efuse) == 512); + +#define WLAN_BCN_DMA_TIME 0x02 +#define WLAN_TBTT_PROHIBIT 0x04 +#define WLAN_TBTT_HOLD_TIME 0x064 +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +struct rtw_jaguar_phy_status_rpt { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; +} __packed; + +#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0) +#define RTW_JGRPHY_W0_TRSW_A BIT(7) +#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8) +#define RTW_JGRPHY_W0_TRSW_B BIT(15) +#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16) +#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26) +#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30) + +/* CCK: */ +#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0) +#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8) +#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13) +#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16) +/* OFDM: */ +#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0) +#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30) + +#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0) +#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1) +#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2) +#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24) + +#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0) +/* Stream 1 and 2 RX EVM: */ +#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */ + +#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */ +#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8) +#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22) +#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */ + +#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */ +/* 8812a, stream 1 and 2 CSI: */ +#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8) +#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16) +/* 8814a: */ +#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24) +#define RTW_JGRPHY_W5_TRSW_C BIT(31) + +#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0) +#define RTW_JGRPHY_W6_TRSW_D BIT(7) +#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16) +#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19) +#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22) +#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23) +#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24) +#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27) +#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30) + +#define RF18_BW_MASK (BIT(11) | BIT(10)) + +void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on); +int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map); +void rtw88xxa_power_off(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd *const *enter_lps_flow); +int rtw88xxa_power_on(struct rtw_dev *rtwdev); +u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path rf_path, u32 addr, u32 mask); +void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx); +void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat, + s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)); +void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev); +void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev); +void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num); +void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num); +void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num); +void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev); +bool rtw88xxa_iqk_finish(int average, int threshold, + int *x_temp, int *y_temp, int *x, int *y, + bool break_inner, bool break_outer); +void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, + void (*do_lck)(struct rtw_dev *rtwdev), + void (*do_iqk)(struct rtw_dev *rtwdev)); +void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c new file mode 100644 index 000000000..01fd299ab --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rx.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "mac.h" +#include "rx.h" +#include "ps.h" +#include "debug.h" +#include "fw.h" + +void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + struct rtw_vif *rtwvif; + + hdr = (struct ieee80211_hdr *)skb->data; + + if (!ieee80211_is_data(hdr->frame_control)) + return; + + if (!is_broadcast_ether_addr(hdr->addr1) && + !is_multicast_ether_addr(hdr->addr1)) { + rtwdev->stats.rx_unicast += skb->len; + rtwdev->stats.rx_cnt++; + if (vif) { + rtwvif = (struct rtw_vif *)vif->drv_priv; + rtwvif->stats.rx_unicast += skb->len; + rtwvif->stats.rx_cnt++; + } + } +} +EXPORT_SYMBOL(rtw_rx_stats); + +struct rtw_rx_addr_match_data { + struct rtw_dev *rtwdev; + struct ieee80211_hdr *hdr; + struct rtw_rx_pkt_stat *pkt_stat; + u8 *bssid; +}; + +static void rtw_rx_phy_stat(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_pkt_count *cur_pkt_cnt = &dm_info->cur_pkt_count; + u8 rate_ss, rate_ss_evm, evm_id; + u8 i, idx; + + dm_info->curr_rx_rate = pkt_stat->rate; + + if (ieee80211_is_beacon(hdr->frame_control)) + cur_pkt_cnt->num_bcn_pkt++; + + switch (pkt_stat->rate) { + case DESC_RATE1M...DESC_RATE11M: + goto pkt_num; + case DESC_RATE6M...DESC_RATE54M: + rate_ss = 0; + rate_ss_evm = 1; + evm_id = RTW_EVM_OFDM; + break; + case DESC_RATEMCS0...DESC_RATEMCS7: + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT1SS_MCS9: + rate_ss = 1; + rate_ss_evm = 1; + evm_id = RTW_EVM_1SS; + break; + case DESC_RATEMCS8...DESC_RATEMCS15: + case DESC_RATEVHT2SS_MCS0...DESC_RATEVHT2SS_MCS9: + rate_ss = 2; + rate_ss_evm = 2; + evm_id = RTW_EVM_2SS_A; + break; + case DESC_RATEMCS16...DESC_RATEMCS23: + case DESC_RATEVHT3SS_MCS0...DESC_RATEVHT3SS_MCS9: + rate_ss = 3; + rate_ss_evm = 3; + evm_id = RTW_EVM_3SS_A; + break; + default: + rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate); + return; + } + + for (i = 0; i < rate_ss_evm; i++) { + idx = evm_id + i; + ewma_evm_add(&dm_info->ewma_evm[idx], + dm_info->rx_evm_dbm[i]); + } + + for (i = 0; i < rtwdev->hal.rf_path_num; i++) { + idx = RTW_SNR_OFDM_A + 4 * rate_ss + i; + ewma_snr_add(&dm_info->ewma_snr[idx], + dm_info->rx_snr[i]); + } +pkt_num: + cur_pkt_cnt->num_qry_pkt[pkt_stat->rate]++; +} + +static void rtw_rx_addr_match_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_rx_addr_match_data *iter_data = data; + struct ieee80211_sta *sta; + struct ieee80211_hdr *hdr = iter_data->hdr; + struct rtw_dev *rtwdev = iter_data->rtwdev; + struct rtw_sta_info *si; + struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat; + u8 *bssid = iter_data->bssid; + + if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) + return; + + if (!(ether_addr_equal(vif->addr, hdr->addr1) || + ieee80211_is_beacon(hdr->frame_control))) + return; + + rtw_rx_phy_stat(rtwdev, pkt_stat, hdr); + sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2, + vif->addr); + if (!sta) + return; + + si = (struct rtw_sta_info *)sta->drv_priv; + ewma_rssi_add(&si->avg_rssi, pkt_stat->rssi); +} + +static void rtw_rx_addr_match(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr) +{ + struct rtw_rx_addr_match_data data = {}; + + if (pkt_stat->crc_err || pkt_stat->icv_err || !pkt_stat->phy_status || + ieee80211_is_ctl(hdr->frame_control)) + return; + + data.rtwdev = rtwdev; + data.hdr = hdr; + data.pkt_stat = pkt_stat; + data.bssid = get_hdr_bssid(hdr); + + rtw_iterate_vifs_atomic(rtwdev, rtw_rx_addr_match_iter, &data); +} + +static void rtw_set_rx_freq_by_pktstat(struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + rx_status->freq = pkt_stat->freq; + rx_status->band = pkt_stat->band; +} + +void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + int channel = rtwdev->hal.current_channel; + size_t hdr_len, ielen; + int channel_number; + u8 *variable; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + goto fill_rx_status; + + if (ieee80211_is_beacon(mgmt->frame_control)) { + variable = mgmt->u.beacon.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { + variable = mgmt->u.probe_resp.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + } else { + goto fill_rx_status; + } + + if (skb->len > hdr_len) + ielen = skb->len - hdr_len; + else + goto fill_rx_status; + + channel_number = cfg80211_get_ies_channel_number(variable, ielen, + NL80211_BAND_2GHZ); + if (channel_number != -1) + channel = channel_number; + +fill_rx_status: + rtw_set_rx_freq_band(pkt_stat, channel); + rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); +} +EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); + +static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_hw *hw = rtwdev->hw; + u8 path; + + memset(rx_status, 0, sizeof(*rx_status)); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && + test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); + if (pkt_stat->crc_err) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (pkt_stat->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + + if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0) + rx_status->encoding = RX_ENC_VHT; + else if (pkt_stat->rate >= DESC_RATEMCS0) + rx_status->encoding = RX_ENC_HT; + + if (rx_status->band == NL80211_BAND_5GHZ && + pkt_stat->rate >= DESC_RATE6M && + pkt_stat->rate <= DESC_RATE54M) { + rx_status->rate_idx = pkt_stat->rate - DESC_RATE6M; + } else if (rx_status->band == NL80211_BAND_2GHZ && + pkt_stat->rate >= DESC_RATE1M && + pkt_stat->rate <= DESC_RATE54M) { + rx_status->rate_idx = pkt_stat->rate - DESC_RATE1M; + } else if (pkt_stat->rate >= DESC_RATEMCS0) { + rtw_desc_to_mcsrate(pkt_stat->rate, &rx_status->rate_idx, + &rx_status->nss); + } + + rx_status->flag |= RX_FLAG_MACTIME_START; + rx_status->mactime = pkt_stat->tsf_low; + + if (pkt_stat->bw == RTW_CHANNEL_WIDTH_80) + rx_status->bw = RATE_INFO_BW_80; + else if (pkt_stat->bw == RTW_CHANNEL_WIDTH_40) + rx_status->bw = RATE_INFO_BW_40; + else + rx_status->bw = RATE_INFO_BW_20; + + if (pkt_stat->phy_status) { + rx_status->signal = pkt_stat->signal_power; + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rx_status->chains |= BIT(path); + rx_status->chain_signal[path] = pkt_stat->rx_power[path]; + } + } else { + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + } + + rtw_rx_addr_match(rtwdev, pkt_stat, hdr); + + /* Rtl8723cs driver checks for size < 14 or size > 8192 and + * simply drops the packet. + */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) { + rx_status->flag |= RX_FLAG_NO_PSDU; + rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); + } +} + +int rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; + struct rtw_rx_desc *rx_desc = rx_desc8; + struct ieee80211_hdr *hdr; + u32 enc_type, swdec; + void *phy_status; + + memset(pkt_stat, 0, sizeof(*pkt_stat)); + + pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN); + pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32); + pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR); + pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0, + RTW_RX_DESC_W0_DRV_INFO_SIZE); + enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE); + pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT); + pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST); + swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC); + pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE; + + pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID); + + pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H); + pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT); + + pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE); + + pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW); + + pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL); + + if (unlikely(pkt_stat->rate >= DESC_RATE_MAX)) + return -EINVAL; + + if (unlikely(pkt_stat->drv_info_sz && + pkt_stat->drv_info_sz != PHY_STATUS_SIZE)) + return -EINVAL; + + if (unlikely(pkt_stat->phy_status && !pkt_stat->drv_info_sz)) + return -EINVAL; + + if (unlikely(pkt_stat->pkt_len > IEEE80211_MAX_MPDU_LEN_VHT_11454)) + return -EINVAL; + + /* drv_info_sz is in unit of 8-bytes */ + pkt_stat->drv_info_sz *= 8; + + /* c2h cmd pkt's rx/phy status is not interested */ + if (pkt_stat->is_c2h) + return 0; + + if (unlikely(pkt_stat->pkt_len <= FCS_LEN)) + return -EINVAL; + + phy_status = rx_desc8 + desc_sz + pkt_stat->shift; + hdr = phy_status + pkt_stat->drv_info_sz; + pkt_stat->hdr = hdr; + + if (pkt_stat->phy_status) + rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat); + + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status); + + return 0; +} +EXPORT_SYMBOL(rtw_rx_query_rx_desc); diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h new file mode 100644 index 000000000..74359f641 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rx.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_RX_H_ +#define __RTW_RX_H_ + +enum rtw_rx_desc_enc { + RX_DESC_ENC_NONE = 0, + RX_DESC_ENC_WEP40 = 1, + RX_DESC_ENC_TKIP_WO_MIC = 2, + RX_DESC_ENC_TKIP_MIC = 3, + RX_DESC_ENC_AES = 4, + RX_DESC_ENC_WEP104 = 5, +}; + +struct rtw_rx_desc { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; +} __packed; + +#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0) +#define RTW_RX_DESC_W0_CRC32 BIT(14) +#define RTW_RX_DESC_W0_ICV_ERR BIT(15) +#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16) +#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20) +#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24) +#define RTW_RX_DESC_W0_PHYST BIT(26) +#define RTW_RX_DESC_W0_SWDEC BIT(27) + +#define RTW_RX_DESC_W1_MACID GENMASK(6, 0) + +#define RTW_RX_DESC_W2_C2H BIT(28) +#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29) + +#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0) + +#define RTW_RX_DESC_W4_BW GENMASK(5, 4) + +#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0) + +void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb); +int rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status); +void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat); + +static inline +void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + if (pkt_stat->channel_invalid) + rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat); +} + + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/sar.c b/drivers/net/wireless/realtek/rtw88/sar.c new file mode 100644 index 000000000..50b9c2412 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sar.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2021 Realtek Corporation + */ + +#include "sar.h" +#include "phy.h" +#include "debug.h" + +s8 rtw_query_sar(struct rtw_dev *rtwdev, const struct rtw_sar_arg *arg) +{ + const struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_sar *sar = &hal->sar; + + switch (sar->src) { + default: + rtw_warn(rtwdev, "unknown SAR source: %d\n", sar->src); + fallthrough; + case RTW_SAR_SOURCE_NONE: + return (s8)rtwdev->chip->max_power_index; + case RTW_SAR_SOURCE_COMMON: + return sar->cfg[arg->path][arg->rs].common[arg->sar_band]; + } +} + +static int rtw_apply_sar(struct rtw_dev *rtwdev, const struct rtw_sar *new) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_sar *sar = &hal->sar; + + if (sar->src != RTW_SAR_SOURCE_NONE && new->src != sar->src) { + rtw_warn(rtwdev, "SAR source: %d is in use\n", sar->src); + return -EBUSY; + } + + *sar = *new; + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); + + return 0; +} + +static s8 rtw_sar_to_phy(struct rtw_dev *rtwdev, u8 fct, s32 sar, + const struct rtw_sar_arg *arg) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 txgi = rtwdev->chip->txgi_factor; + u8 max = rtwdev->chip->max_power_index; + s32 tmp; + s8 base; + + tmp = fct > txgi ? sar >> (fct - txgi) : sar << (txgi - fct); + base = arg->sar_band == RTW_SAR_BAND_0 ? + hal->tx_pwr_by_rate_base_2g[arg->path][arg->rs] : + hal->tx_pwr_by_rate_base_5g[arg->path][arg->rs]; + + return (s8)clamp_t(s32, tmp, -max - 1, max) - base; +} + +static const struct cfg80211_sar_freq_ranges rtw_common_sar_freq_ranges[] = { + [RTW_SAR_BAND_0] = { .start_freq = 2412, .end_freq = 2484, }, + [RTW_SAR_BAND_1] = { .start_freq = 5180, .end_freq = 5320, }, + [RTW_SAR_BAND_3] = { .start_freq = 5500, .end_freq = 5720, }, + [RTW_SAR_BAND_4] = { .start_freq = 5745, .end_freq = 5825, }, +}; + +static_assert(ARRAY_SIZE(rtw_common_sar_freq_ranges) == RTW_SAR_BAND_NR); + +const struct cfg80211_sar_capa rtw_sar_capa = { + .type = NL80211_SAR_TYPE_POWER, + .num_freq_ranges = RTW_SAR_BAND_NR, + .freq_ranges = rtw_common_sar_freq_ranges, +}; + +int rtw_set_sar_specs(struct rtw_dev *rtwdev, + const struct cfg80211_sar_specs *sar) +{ + struct rtw_sar_arg arg = {0}; + struct rtw_sar new = {0}; + u32 idx, i, j, k; + s32 power; + s8 val; + + if (sar->type != NL80211_SAR_TYPE_POWER) + return -EINVAL; + + memset(&new, rtwdev->chip->max_power_index, sizeof(new)); + new.src = RTW_SAR_SOURCE_COMMON; + + for (i = 0; i < sar->num_sub_specs; i++) { + idx = sar->sub_specs[i].freq_range_index; + if (idx >= RTW_SAR_BAND_NR) + return -EINVAL; + + power = sar->sub_specs[i].power; + rtw_dbg(rtwdev, RTW_DBG_REGD, "On freq %u to %u, set SAR %d in 1/%lu dBm\n", + rtw_common_sar_freq_ranges[idx].start_freq, + rtw_common_sar_freq_ranges[idx].end_freq, + power, BIT(RTW_COMMON_SAR_FCT)); + + for (j = 0; j < RTW_RF_PATH_MAX; j++) { + for (k = 0; k < RTW_RATE_SECTION_NUM; k++) { + arg = (struct rtw_sar_arg){ + .sar_band = idx, + .path = j, + .rs = k, + }; + val = rtw_sar_to_phy(rtwdev, RTW_COMMON_SAR_FCT, + power, &arg); + new.cfg[j][k].common[idx] = val; + } + } + } + + return rtw_apply_sar(rtwdev, &new); +} diff --git a/drivers/net/wireless/realtek/rtw88/sar.h b/drivers/net/wireless/realtek/rtw88/sar.h new file mode 100644 index 000000000..e01e7bb79 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sar.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2021 Realtek Corporation + */ + +#include "main.h" + +/* NL80211_SAR_TYPE_POWER means unit is in 0.25 dBm, + * where 0.25 = 1/4 = 2^(-2), so make factor 2. + */ +#define RTW_COMMON_SAR_FCT 2 + +struct rtw_sar_arg { + u8 sar_band; + u8 path; + u8 rs; +}; + +extern const struct cfg80211_sar_capa rtw_sar_capa; + +s8 rtw_query_sar(struct rtw_dev *rtwdev, const struct rtw_sar_arg *arg); +int rtw_set_sar_specs(struct rtw_dev *rtwdev, + const struct cfg80211_sar_specs *sar); diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c new file mode 100644 index 000000000..5b40d74b1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -0,0 +1,1443 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright (C) 2021 Martin Blumenstingl + * Copyright (C) 2021 Jernej Skrabec + * + * Based on rtw88/pci.c: + * Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include +#include "main.h" +#include "mac.h" +#include "debug.h" +#include "fw.h" +#include "ps.h" +#include "reg.h" +#include "rx.h" +#include "sdio.h" +#include "tx.h" + +#define RTW_SDIO_INDIRECT_RW_RETRIES 50 + +static bool rtw_sdio_is_bus_addr(u32 addr) +{ + return !!(addr & RTW_SDIO_BUS_MSK); +} + +static bool rtw_sdio_bus_claim_needed(struct rtw_sdio *rtwsdio) +{ + return !rtwsdio->irq_thread || + rtwsdio->irq_thread != current; +} + +static u32 rtw_sdio_to_bus_offset(struct rtw_dev *rtwdev, u32 addr) +{ + switch (addr & RTW_SDIO_BUS_MSK) { + case WLAN_IOREG_OFFSET: + addr &= WLAN_IOREG_REG_MSK; + addr |= FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_MAC_REG); + break; + case SDIO_LOCAL_OFFSET: + addr &= SDIO_LOCAL_REG_MSK; + addr |= FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_SDIO_REG); + break; + default: + rtw_warn(rtwdev, "Cannot convert addr 0x%08x to bus offset", + addr); + } + + return addr; +} + +static bool rtw_sdio_use_memcpy_io(struct rtw_dev *rtwdev, u32 addr, + u8 alignment) +{ + return IS_ALIGNED(addr, alignment) && + test_bit(RTW_FLAG_POWERON, rtwdev->flags); +} + +static void rtw_sdio_writel(struct rtw_dev *rtwdev, u32 val, u32 addr, + int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u8 buf[4]; + int i; + + if (rtw_sdio_use_memcpy_io(rtwdev, addr, 4)) { + sdio_writel(rtwsdio->sdio_func, val, addr, err_ret); + return; + } + + *(__le32 *)buf = cpu_to_le32(val); + + for (i = 0; i < 4; i++) { + sdio_writeb(rtwsdio->sdio_func, buf[i], addr + i, err_ret); + if (*err_ret) + return; + } +} + +static void rtw_sdio_writew(struct rtw_dev *rtwdev, u16 val, u32 addr, + int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u8 buf[2]; + int i; + + *(__le16 *)buf = cpu_to_le16(val); + + for (i = 0; i < 2; i++) { + sdio_writeb(rtwsdio->sdio_func, buf[i], addr + i, err_ret); + if (*err_ret) + return; + } +} + +static u32 rtw_sdio_readl(struct rtw_dev *rtwdev, u32 addr, int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u8 buf[4]; + int i; + + if (rtw_sdio_use_memcpy_io(rtwdev, addr, 4)) + return sdio_readl(rtwsdio->sdio_func, addr, err_ret); + + for (i = 0; i < 4; i++) { + buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret); + if (*err_ret) + return 0; + } + + return le32_to_cpu(*(__le32 *)buf); +} + +static u16 rtw_sdio_readw(struct rtw_dev *rtwdev, u32 addr, int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u8 buf[2]; + int i; + + for (i = 0; i < 2; i++) { + buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret); + if (*err_ret) + return 0; + } + + return le16_to_cpu(*(__le16 *)buf); +} + +static u32 rtw_sdio_to_io_address(struct rtw_dev *rtwdev, u32 addr, + bool direct) +{ + if (!direct) + return addr; + + if (!rtw_sdio_is_bus_addr(addr)) + addr |= WLAN_IOREG_OFFSET; + + return rtw_sdio_to_bus_offset(rtwdev, addr); +} + +static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr) +{ + bool might_indirect_under_power_off = rtwdev->chip->id == RTW_CHIP_TYPE_8822C; + + if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags) && + !rtw_sdio_is_bus_addr(addr) && might_indirect_under_power_off) + return false; + + return !rtw_sdio_is_sdio30_supported(rtwdev) || + rtw_sdio_is_bus_addr(addr); +} + +static int rtw_sdio_indirect_reg_cfg(struct rtw_dev *rtwdev, u32 addr, u32 cfg) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + unsigned int retry; + u32 reg_cfg; + int ret; + u8 tmp; + + reg_cfg = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_CFG); + + rtw_sdio_writel(rtwdev, addr | cfg | BIT_SDIO_INDIRECT_REG_CFG_UNK20, + reg_cfg, &ret); + if (ret) + return ret; + + for (retry = 0; retry < RTW_SDIO_INDIRECT_RW_RETRIES; retry++) { + tmp = sdio_readb(rtwsdio->sdio_func, reg_cfg + 2, &ret); + if (!ret && (tmp & BIT(4))) + return 0; + } + + return -ETIMEDOUT; +} + +static u8 rtw_sdio_indirect_read8(struct rtw_dev *rtwdev, u32 addr, + int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u32 reg_data; + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_READ); + if (*err_ret) + return 0; + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + return sdio_readb(rtwsdio->sdio_func, reg_data, err_ret); +} + +static int rtw_sdio_indirect_read_bytes(struct rtw_dev *rtwdev, u32 addr, + u8 *buf, int count) +{ + int i, ret = 0; + + for (i = 0; i < count; i++) { + buf[i] = rtw_sdio_indirect_read8(rtwdev, addr + i, &ret); + if (ret) + break; + } + + return ret; +} + +static u16 rtw_sdio_indirect_read16(struct rtw_dev *rtwdev, u32 addr, + int *err_ret) +{ + u32 reg_data; + u8 buf[2]; + + if (!IS_ALIGNED(addr, 2)) { + *err_ret = rtw_sdio_indirect_read_bytes(rtwdev, addr, buf, 2); + if (*err_ret) + return 0; + + return le16_to_cpu(*(__le16 *)buf); + } + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_READ); + if (*err_ret) + return 0; + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + return rtw_sdio_readw(rtwdev, reg_data, err_ret); +} + +static u32 rtw_sdio_indirect_read32(struct rtw_dev *rtwdev, u32 addr, + int *err_ret) +{ + u32 reg_data; + u8 buf[4]; + + if (!IS_ALIGNED(addr, 4)) { + *err_ret = rtw_sdio_indirect_read_bytes(rtwdev, addr, buf, 4); + if (*err_ret) + return 0; + + return le32_to_cpu(*(__le32 *)buf); + } + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_READ); + if (*err_ret) + return 0; + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + return rtw_sdio_readl(rtwdev, reg_data, err_ret); +} + +static u8 rtw_sdio_read8(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + int ret; + u8 val; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + val = sdio_readb(rtwsdio->sdio_func, addr, &ret); + else + val = rtw_sdio_indirect_read8(rtwdev, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio read8 failed (0x%x): %d", addr, ret); + + return val; +} + +static u16 rtw_sdio_read16(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + int ret; + u16 val; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + val = rtw_sdio_readw(rtwdev, addr, &ret); + else + val = rtw_sdio_indirect_read16(rtwdev, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio read16 failed (0x%x): %d", addr, ret); + + return val; +} + +static u32 rtw_sdio_read32(struct rtw_dev *rtwdev, u32 addr) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + u32 val; + int ret; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + val = rtw_sdio_readl(rtwdev, addr, &ret); + else + val = rtw_sdio_indirect_read32(rtwdev, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio read32 failed (0x%x): %d", addr, ret); + + return val; +} + +static void rtw_sdio_indirect_write8(struct rtw_dev *rtwdev, u8 val, u32 addr, + int *err_ret) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + u32 reg_data; + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + sdio_writeb(rtwsdio->sdio_func, val, reg_data, err_ret); + if (*err_ret) + return; + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_WRITE); +} + +static void rtw_sdio_indirect_write16(struct rtw_dev *rtwdev, u16 val, u32 addr, + int *err_ret) +{ + u32 reg_data; + + if (!IS_ALIGNED(addr, 2)) { + addr = rtw_sdio_to_io_address(rtwdev, addr, true); + rtw_sdio_writew(rtwdev, val, addr, err_ret); + return; + } + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + rtw_sdio_writew(rtwdev, val, reg_data, err_ret); + if (*err_ret) + return; + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_WRITE | + BIT_SDIO_INDIRECT_REG_CFG_WORD); +} + +static void rtw_sdio_indirect_write32(struct rtw_dev *rtwdev, u32 val, + u32 addr, int *err_ret) +{ + u32 reg_data; + + if (!IS_ALIGNED(addr, 4)) { + addr = rtw_sdio_to_io_address(rtwdev, addr, true); + rtw_sdio_writel(rtwdev, val, addr, err_ret); + return; + } + + reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); + rtw_sdio_writel(rtwdev, val, reg_data, err_ret); + + *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, + BIT_SDIO_INDIRECT_REG_CFG_WRITE | + BIT_SDIO_INDIRECT_REG_CFG_DWORD); +} + +static void rtw_sdio_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + int ret; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + sdio_writeb(rtwsdio->sdio_func, val, addr, &ret); + else + rtw_sdio_indirect_write8(rtwdev, val, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio write8 failed (0x%x): %d", addr, ret); +} + +static void rtw_sdio_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + int ret; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + rtw_sdio_writew(rtwdev, val, addr, &ret); + else + rtw_sdio_indirect_write16(rtwdev, val, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio write16 failed (0x%x): %d", addr, ret); +} + +static void rtw_sdio_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool direct, bus_claim; + int ret; + + direct = rtw_sdio_use_direct_io(rtwdev, addr); + addr = rtw_sdio_to_io_address(rtwdev, addr, direct); + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + if (direct) + rtw_sdio_writel(rtwdev, val, addr, &ret); + else + rtw_sdio_indirect_write32(rtwdev, val, addr, &ret); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, "sdio write32 failed (0x%x): %d", addr, ret); +} + +static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size, + enum rtw_tx_queue_type queue) +{ + u32 txaddr; + + switch (queue) { + case RTW_TX_QUEUE_BCN: + case RTW_TX_QUEUE_H2C: + case RTW_TX_QUEUE_HI0: + txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_TXFF_HIGH); + break; + case RTW_TX_QUEUE_VI: + case RTW_TX_QUEUE_VO: + txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_TXFF_NORMAL); + break; + case RTW_TX_QUEUE_BE: + case RTW_TX_QUEUE_BK: + txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_TXFF_LOW); + break; + case RTW_TX_QUEUE_MGMT: + txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, + REG_SDIO_CMD_ADDR_TXFF_EXTRA); + break; + default: + rtw_warn(rtwdev, "Unsupported queue for TX addr: 0x%02x\n", + queue); + return 0; + } + + txaddr += DIV_ROUND_UP(size, 4); + + return txaddr; +}; + +static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + struct mmc_host *host = rtwsdio->sdio_func->card->host; + bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + u32 rxaddr = rtwsdio->rx_addr++; + int ret = 0, err; + size_t bytes; + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + while (count > 0) { + bytes = min_t(size_t, host->max_req_size, count); + + err = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, + RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), + bytes); + if (err) { + rtw_warn(rtwdev, + "Failed to read %zu byte(s) from SDIO port 0x%08x: %d", + bytes, rxaddr, err); + + /* Signal to the caller that reading did not work and + * that the data in the buffer is short/corrupted. + */ + ret = err; + + /* Don't stop here - instead drain the remaining data + * from the card's buffer, else the card will return + * corrupt data for the next rtw_sdio_read_port() call. + */ + } + + count -= bytes; + buf += bytes; + } + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + return ret; +} + +static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue, + size_t count) +{ + unsigned int pages_free, pages_needed; + + if (rtw_chip_wcpu_8051(rtwdev)) { + u32 free_txpg; + + free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); + + switch (queue) { + case RTW_TX_QUEUE_BCN: + case RTW_TX_QUEUE_H2C: + case RTW_TX_QUEUE_HI0: + case RTW_TX_QUEUE_MGMT: + /* high */ + pages_free = free_txpg & 0xff; + break; + case RTW_TX_QUEUE_VI: + case RTW_TX_QUEUE_VO: + /* normal */ + pages_free = (free_txpg >> 8) & 0xff; + break; + case RTW_TX_QUEUE_BE: + case RTW_TX_QUEUE_BK: + /* low */ + pages_free = (free_txpg >> 16) & 0xff; + break; + default: + rtw_warn(rtwdev, "Unknown mapping for queue %u\n", queue); + return -EINVAL; + } + + /* add the pages from the public queue */ + pages_free += (free_txpg >> 24) & 0xff; + } else { + u32 free_txpg[3]; + + free_txpg[0] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); + free_txpg[1] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 4); + free_txpg[2] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 8); + + switch (queue) { + case RTW_TX_QUEUE_BCN: + case RTW_TX_QUEUE_H2C: + case RTW_TX_QUEUE_HI0: + /* high */ + pages_free = free_txpg[0] & 0xfff; + break; + case RTW_TX_QUEUE_VI: + case RTW_TX_QUEUE_VO: + /* normal */ + pages_free = (free_txpg[0] >> 16) & 0xfff; + break; + case RTW_TX_QUEUE_BE: + case RTW_TX_QUEUE_BK: + /* low */ + pages_free = free_txpg[1] & 0xfff; + break; + case RTW_TX_QUEUE_MGMT: + /* extra */ + pages_free = free_txpg[2] & 0xfff; + break; + default: + rtw_warn(rtwdev, "Unknown mapping for queue %u\n", queue); + return -EINVAL; + } + + /* add the pages from the public queue */ + pages_free += (free_txpg[1] >> 16) & 0xfff; + } + + pages_needed = DIV_ROUND_UP(count, rtwdev->chip->page_size); + + if (pages_needed > pages_free) { + rtw_dbg(rtwdev, RTW_DBG_SDIO, + "Not enough free pages (%u needed, %u free) in queue %u for %zu bytes\n", + pages_needed, pages_free, queue, count); + return -EBUSY; + } + + return 0; +} + +static int rtw_sdio_write_port(struct rtw_dev *rtwdev, struct sk_buff *skb, + enum rtw_tx_queue_type queue) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool bus_claim; + size_t txsize; + u32 txaddr; + int ret; + + txaddr = rtw_sdio_get_tx_addr(rtwdev, skb->len, queue); + if (!txaddr) + return -EINVAL; + + txsize = sdio_align_size(rtwsdio->sdio_func, skb->len); + + ret = rtw_sdio_check_free_txpg(rtwdev, queue, txsize); + if (ret) + return ret; + + if (!IS_ALIGNED((unsigned long)skb->data, RTW_SDIO_DATA_PTR_ALIGN)) + rtw_warn(rtwdev, "Got unaligned SKB in %s() for queue %u\n", + __func__, queue); + + bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + + ret = sdio_memcpy_toio(rtwsdio->sdio_func, txaddr, skb->data, txsize); + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); + + if (ret) + rtw_warn(rtwdev, + "Failed to write %zu byte(s) to SDIO port 0x%08x", + txsize, txaddr); + + return ret; +} + +static void rtw_sdio_init(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + rtwsdio->irq_mask = REG_SDIO_HIMR_RX_REQUEST | REG_SDIO_HIMR_CPWM1; +} + +static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev) +{ + u8 size, timeout; + + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8703B: + case RTW_CHIP_TYPE_8821A: + case RTW_CHIP_TYPE_8812A: + size = 0x6; + timeout = 0x6; + break; + case RTW_CHIP_TYPE_8723D: + size = 0xa; + timeout = 0x3; + rtw_write8_set(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); + break; + default: + size = 0xff; + timeout = 0x1; + break; + } + + /* Make the firmware honor the size limit configured below */ + rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); + + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); + + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, + FIELD_PREP(BIT_RXDMA_AGG_PG_TH, size) | + FIELD_PREP(BIT_DMA_AGG_TO_V1, timeout)); + + rtw_write8_set(rtwdev, REG_RXDMA_MODE, BIT_DMA_MODE); +} + +static void rtw_sdio_enable_interrupt(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + rtw_write32(rtwdev, REG_SDIO_HIMR, rtwsdio->irq_mask); +} + +static void rtw_sdio_disable_interrupt(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, REG_SDIO_HIMR, 0x0); +} + +static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb, + u8 queue) +{ + switch (queue) { + case RTW_TX_QUEUE_BCN: + return TX_DESC_QSEL_BEACON; + case RTW_TX_QUEUE_H2C: + return TX_DESC_QSEL_H2C; + case RTW_TX_QUEUE_MGMT: + return TX_DESC_QSEL_MGMT; + case RTW_TX_QUEUE_HI0: + return TX_DESC_QSEL_HIGH; + default: + return skb->priority; + } +} + +static int rtw_sdio_setup(struct rtw_dev *rtwdev) +{ + /* nothing to do */ + return 0; +} + +static int rtw_sdio_start(struct rtw_dev *rtwdev) +{ + rtw_sdio_enable_rx_aggregation(rtwdev); + rtw_sdio_enable_interrupt(rtwdev); + + return 0; +} + +static void rtw_sdio_stop(struct rtw_dev *rtwdev) +{ + rtw_sdio_disable_interrupt(rtwdev); +} + +static void rtw_sdio_deep_ps_enter(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + bool tx_empty = true; + u8 queue; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) { + /* Deep PS state is not allowed to TX-DMA */ + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { + /* BCN queue is rsvd page, does not have DMA interrupt + * H2C queue is managed by firmware + */ + if (queue == RTW_TX_QUEUE_BCN || + queue == RTW_TX_QUEUE_H2C) + continue; + + /* check if there is any skb DMAing */ + if (skb_queue_len(&rtwsdio->tx_queue[queue])) { + tx_empty = false; + break; + } + } + } + + if (!tx_empty) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "TX path not empty, cannot enter deep power save state\n"); + return; + } + + set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); + rtw_power_mode_change(rtwdev, true); +} + +static void rtw_sdio_deep_ps_leave(struct rtw_dev *rtwdev) +{ + if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_power_mode_change(rtwdev, false); +} + +static void rtw_sdio_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + if (enter && !test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_sdio_deep_ps_enter(rtwdev); + + if (!enter && test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_sdio_deep_ps_leave(rtwdev); +} + +static void rtw_sdio_tx_kick_off(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + queue_work(rtwsdio->txwq, &rtwsdio->tx_handler_data->work); +} + +static void rtw_sdio_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + /* nothing to do */ +} + +static void rtw_sdio_interface_cfg(struct rtw_dev *rtwdev) +{ + u32 val; + + rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); + + val = rtw_read32(rtwdev, REG_SDIO_TX_CTRL); + val &= 0xfff8; + rtw_write32(rtwdev, REG_SDIO_TX_CTRL, val); +} + +static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) > + sizeof(info->status.status_driver_data)); + + return (struct rtw_sdio_tx_data *)info->status.status_driver_data; +} + +static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_tx_queue_type queue) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + unsigned long data_addr, aligned_addr; + size_t offset; + u8 *pkt_desc; + + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + + data_addr = (unsigned long)pkt_desc; + aligned_addr = ALIGN(data_addr, RTW_SDIO_DATA_PTR_ALIGN); + + if (data_addr != aligned_addr) { + /* Ensure that the start of the pkt_desc is always aligned at + * RTW_SDIO_DATA_PTR_ALIGN. + */ + offset = RTW_SDIO_DATA_PTR_ALIGN - (aligned_addr - data_addr); + + pkt_desc = skb_push(skb, offset); + + /* By inserting padding to align the start of the pkt_desc we + * need to inform the firmware that the actual data starts at + * a different offset than normal. + */ + pkt_info->offset += offset; + } + + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + + pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); + + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc); +} + +static int rtw_sdio_write_data(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_tx_queue_type queue) +{ + int ret; + + rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue); + + ret = rtw_sdio_write_port(rtwdev, skb, queue); + dev_kfree_skb_any(skb); + + return ret; +} + +static int rtw_sdio_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, + u32 size) +{ + struct rtw_tx_pkt_info pkt_info = {}; + struct sk_buff *skb; + + skb = rtw_tx_write_data_rsvd_page_get(rtwdev, &pkt_info, buf, size); + if (!skb) + return -ENOMEM; + + return rtw_sdio_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_BCN); +} + +static int rtw_sdio_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + struct rtw_tx_pkt_info pkt_info = {}; + struct sk_buff *skb; + + skb = rtw_tx_write_data_h2c_get(rtwdev, &pkt_info, buf, size); + if (!skb) + return -ENOMEM; + + return rtw_sdio_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_H2C); +} + +static int rtw_sdio_tx_write(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + enum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb); + struct rtw_sdio_tx_data *tx_data; + + rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue); + + tx_data = rtw_sdio_get_tx_data(skb); + tx_data->sn = pkt_info->sn; + + skb_queue_tail(&rtwsdio->tx_queue[queue], skb); + + return 0; +} + +static void rtw_sdio_tx_err_isr(struct rtw_dev *rtwdev) +{ + u32 val = rtw_read32(rtwdev, REG_TXDMA_STATUS); + + rtw_write32(rtwdev, REG_TXDMA_STATUS, val); +} + +static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb, + u32 pkt_offset, struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + *IEEE80211_SKB_RXCB(skb) = *rx_status; + + if (pkt_stat->is_c2h) { + skb_put(skb, pkt_stat->pkt_len + pkt_offset); + rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); + return; + } + + skb_put(skb, pkt_stat->pkt_len); + skb_reserve(skb, pkt_offset); + + rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat); + rtw_rx_stats(rtwdev, pkt_stat->vif, skb); + + ieee80211_rx_irqsafe(rtwdev->hw, skb); +} + +static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + const struct rtw_chip_info *chip = rtwdev->chip; + u32 pkt_desc_sz = chip->rx_pkt_desc_sz; + struct ieee80211_rx_status rx_status; + struct rtw_rx_pkt_stat pkt_stat; + struct sk_buff *skb, *split_skb; + u32 pkt_offset, curr_pkt_len; + size_t bufsz; + u8 *rx_desc; + int ret; + + bufsz = sdio_align_size(rtwsdio->sdio_func, rx_len); + + skb = dev_alloc_skb(bufsz); + if (!skb) + return; + + ret = rtw_sdio_read_port(rtwdev, skb->data, bufsz); + if (ret) { + dev_kfree_skb_any(skb); + return; + } + + while (true) { + rx_desc = skb->data; + ret = rtw_rx_query_rx_desc(rtwdev, rx_desc, + &pkt_stat, &rx_status); + if (ret) { + dev_kfree_skb_any(skb); + return; + } + + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + + curr_pkt_len = ALIGN(pkt_offset + pkt_stat.pkt_len, + RTW_SDIO_DATA_PTR_ALIGN); + + if ((curr_pkt_len + pkt_desc_sz) >= rx_len) { + /* Use the original skb (with it's adjusted offset) + * when processing the last (or even the only) entry to + * have it's memory freed automatically. + */ + rtw_sdio_rx_skb(rtwdev, skb, pkt_offset, &pkt_stat, + &rx_status); + break; + } + + split_skb = dev_alloc_skb(curr_pkt_len); + if (!split_skb) { + rtw_sdio_rx_skb(rtwdev, skb, pkt_offset, &pkt_stat, + &rx_status); + break; + } + + skb_copy_header(split_skb, skb); + memcpy(split_skb->data, skb->data, curr_pkt_len); + + rtw_sdio_rx_skb(rtwdev, split_skb, pkt_offset, &pkt_stat, + &rx_status); + + /* Move to the start of the next RX descriptor */ + skb_reserve(skb, curr_pkt_len); + rx_len -= curr_pkt_len; + } +} + +static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) +{ + u32 rx_len, hisr, total_rx_bytes = 0; + + do { + if (rtw_chip_wcpu_8051(rtwdev)) + rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); + else + rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN); + + if (!rx_len) + break; + + rtw_sdio_rxfifo_recv(rtwdev, rx_len); + + total_rx_bytes += rx_len; + + if (rtw_chip_wcpu_8051(rtwdev)) { + /* Stop if no more RX requests are pending, even if + * rx_len could be greater than zero in the next + * iteration. This is needed because the RX buffer may + * already contain data while either HW or FW are not + * done filling that buffer yet. Still reading the + * buffer can result in packets where + * rtw_rx_pkt_stat.pkt_len is zero or points beyond the + * end of the buffer. + */ + hisr = rtw_read32(rtwdev, REG_SDIO_HISR); + } else { + /* RTW_WCPU_3081 chips have improved hardware or + * firmware and can use rx_len unconditionally. + */ + hisr = REG_SDIO_HISR_RX_REQUEST; + } + } while (total_rx_bytes < SZ_64K && hisr & REG_SDIO_HISR_RX_REQUEST); +} + +static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func) +{ + struct ieee80211_hw *hw = sdio_get_drvdata(sdio_func); + struct rtw_sdio *rtwsdio; + struct rtw_dev *rtwdev; + u32 hisr; + + rtwdev = hw->priv; + rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + rtwsdio->irq_thread = current; + + hisr = rtw_read32(rtwdev, REG_SDIO_HISR); + + if (hisr & REG_SDIO_HISR_TXERR) + rtw_sdio_tx_err_isr(rtwdev); + if (hisr & REG_SDIO_HISR_RX_REQUEST) { + hisr &= ~REG_SDIO_HISR_RX_REQUEST; + rtw_sdio_rx_isr(rtwdev); + } + + rtw_write32(rtwdev, REG_SDIO_HISR, hisr); + + rtwsdio->irq_thread = NULL; +} + +static int __maybe_unused rtw_sdio_suspend(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw_dev *rtwdev = hw->priv; + int ret; + + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (ret) + rtw_err(rtwdev, "Failed to host PM flag MMC_PM_KEEP_POWER"); + + return ret; +} + +static int __maybe_unused rtw_sdio_resume(struct device *dev) +{ + return 0; +} + +SIMPLE_DEV_PM_OPS(rtw_sdio_pm_ops, rtw_sdio_suspend, rtw_sdio_resume); +EXPORT_SYMBOL(rtw_sdio_pm_ops); + +static int rtw_sdio_claim(struct rtw_dev *rtwdev, struct sdio_func *sdio_func) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + int ret; + + sdio_claim_host(sdio_func); + + ret = sdio_enable_func(sdio_func); + if (ret) { + rtw_err(rtwdev, "Failed to enable SDIO func"); + goto err_release_host; + } + + ret = sdio_set_block_size(sdio_func, RTW_SDIO_BLOCK_SIZE); + if (ret) { + rtw_err(rtwdev, "Failed to set SDIO block size to 512"); + goto err_disable_func; + } + + rtwsdio->sdio_func = sdio_func; + + rtwsdio->sdio3_bus_mode = mmc_card_uhs(sdio_func->card); + + sdio_set_drvdata(sdio_func, rtwdev->hw); + SET_IEEE80211_DEV(rtwdev->hw, &sdio_func->dev); + + sdio_release_host(sdio_func); + + return 0; + +err_disable_func: + sdio_disable_func(sdio_func); +err_release_host: + sdio_release_host(sdio_func); + return ret; +} + +static void rtw_sdio_declaim(struct rtw_dev *rtwdev, + struct sdio_func *sdio_func) +{ + sdio_claim_host(sdio_func); + sdio_disable_func(sdio_func); + sdio_release_host(sdio_func); +} + +static const struct rtw_hci_ops rtw_sdio_ops = { + .tx_write = rtw_sdio_tx_write, + .tx_kick_off = rtw_sdio_tx_kick_off, + .setup = rtw_sdio_setup, + .start = rtw_sdio_start, + .stop = rtw_sdio_stop, + .deep_ps = rtw_sdio_deep_ps, + .link_ps = rtw_sdio_link_ps, + .interface_cfg = rtw_sdio_interface_cfg, + .dynamic_rx_agg = NULL, + .write_firmware_page = rtw_write_firmware_page, + + .read8 = rtw_sdio_read8, + .read16 = rtw_sdio_read16, + .read32 = rtw_sdio_read32, + .write8 = rtw_sdio_write8, + .write16 = rtw_sdio_write16, + .write32 = rtw_sdio_write32, + .write_data_rsvd_page = rtw_sdio_write_data_rsvd_page, + .write_data_h2c = rtw_sdio_write_data_h2c, +}; + +static int rtw_sdio_request_irq(struct rtw_dev *rtwdev, + struct sdio_func *sdio_func) +{ + int ret; + + sdio_claim_host(sdio_func); + ret = sdio_claim_irq(sdio_func, &rtw_sdio_handle_interrupt); + sdio_release_host(sdio_func); + + if (ret) { + rtw_err(rtwdev, "failed to claim SDIO IRQ"); + return ret; + } + + return 0; +} + +static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = rtwdev->hw; + + skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + + /* enqueue to wait for tx report */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); + return; + } + + /* always ACK for others, then they won't be marked as drop */ + ieee80211_tx_info_clear_status(info); + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + else + info->flags |= IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(hw, skb); +} + +static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev, + enum rtw_tx_queue_type queue) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + struct sk_buff *skb; + int ret; + + skb = skb_dequeue(&rtwsdio->tx_queue[queue]); + if (!skb) + return; + + ret = rtw_sdio_write_port(rtwdev, skb, queue); + if (ret) { + skb_queue_head(&rtwsdio->tx_queue[queue], skb); + return; + } + + rtw_sdio_indicate_tx_status(rtwdev, skb); +} + +static void rtw_sdio_tx_handler(struct work_struct *work) +{ + struct rtw_sdio_work_data *work_data = + container_of(work, struct rtw_sdio_work_data, work); + struct rtw_sdio *rtwsdio; + struct rtw_dev *rtwdev; + int limit, queue; + + rtwdev = work_data->rtwdev; + rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + rtw_sdio_deep_ps_leave(rtwdev); + + for (queue = RTK_MAX_TX_QUEUE_NUM - 1; queue >= 0; queue--) { + for (limit = 0; limit < 1000; limit++) { + rtw_sdio_process_tx_queue(rtwdev, queue); + + if (skb_queue_empty(&rtwsdio->tx_queue[queue])) + break; + } + } +} + +static void rtw_sdio_free_irq(struct rtw_dev *rtwdev, + struct sdio_func *sdio_func) +{ + sdio_claim_host(sdio_func); + sdio_release_irq(sdio_func); + sdio_release_host(sdio_func); +} + +static int rtw_sdio_init_tx(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + int i; + + rtwsdio->txwq = create_singlethread_workqueue("rtw88_sdio: tx wq"); + if (!rtwsdio->txwq) { + rtw_err(rtwdev, "failed to create TX work queue\n"); + return -ENOMEM; + } + + for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) + skb_queue_head_init(&rtwsdio->tx_queue[i]); + rtwsdio->tx_handler_data = kmalloc_obj(*rtwsdio->tx_handler_data); + if (!rtwsdio->tx_handler_data) + goto err_destroy_wq; + + rtwsdio->tx_handler_data->rtwdev = rtwdev; + INIT_WORK(&rtwsdio->tx_handler_data->work, rtw_sdio_tx_handler); + + return 0; + +err_destroy_wq: + destroy_workqueue(rtwsdio->txwq); + return -ENOMEM; +} + +static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + int i; + + destroy_workqueue(rtwsdio->txwq); + kfree(rtwsdio->tx_handler_data); + + for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) + ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]); +} + +int rtw_sdio_probe(struct sdio_func *sdio_func, + const struct sdio_device_id *id) +{ + struct ieee80211_hw *hw; + struct rtw_dev *rtwdev; + int drv_data_size; + int ret; + + drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_sdio); + hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops); + if (!hw) { + dev_err(&sdio_func->dev, "failed to allocate hw"); + return -ENOMEM; + } + + rtwdev = hw->priv; + rtwdev->hw = hw; + rtwdev->dev = &sdio_func->dev; + rtwdev->chip = (struct rtw_chip_info *)id->driver_data; + rtwdev->hci.ops = &rtw_sdio_ops; + rtwdev->hci.type = RTW_HCI_TYPE_SDIO; + + ret = rtw_core_init(rtwdev); + if (ret) + goto err_release_hw; + + rtw_dbg(rtwdev, RTW_DBG_SDIO, + "rtw88 SDIO probe: vendor=0x%04x device=%04x class=%02x", + id->vendor, id->device, id->class); + + ret = rtw_sdio_claim(rtwdev, sdio_func); + if (ret) { + rtw_err(rtwdev, "failed to claim SDIO device"); + goto err_deinit_core; + } + + rtw_sdio_init(rtwdev); + + ret = rtw_sdio_init_tx(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to init SDIO TX queue\n"); + goto err_sdio_declaim; + } + + ret = rtw_chip_info_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip information"); + goto err_destroy_txwq; + } + + ret = rtw_sdio_request_irq(rtwdev, sdio_func); + if (ret) + goto err_destroy_txwq; + + ret = rtw_register_hw(rtwdev, hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw"); + goto err_free_irq; + } + + return 0; + +err_free_irq: + rtw_sdio_free_irq(rtwdev, sdio_func); +err_destroy_txwq: + rtw_sdio_deinit_tx(rtwdev); +err_sdio_declaim: + rtw_sdio_declaim(rtwdev, sdio_func); +err_deinit_core: + rtw_core_deinit(rtwdev); +err_release_hw: + ieee80211_free_hw(hw); + + return ret; +} +EXPORT_SYMBOL(rtw_sdio_probe); + +void rtw_sdio_remove(struct sdio_func *sdio_func) +{ + struct ieee80211_hw *hw = sdio_get_drvdata(sdio_func); + struct rtw_dev *rtwdev; + + if (!hw) + return; + + rtwdev = hw->priv; + + rtw_unregister_hw(rtwdev, hw); + rtw_sdio_disable_interrupt(rtwdev); + rtw_sdio_free_irq(rtwdev, sdio_func); + rtw_sdio_declaim(rtwdev, sdio_func); + rtw_sdio_deinit_tx(rtwdev); + rtw_core_deinit(rtwdev); + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtw_sdio_remove); + +void rtw_sdio_shutdown(struct sdio_func *sdio_func) +{ + const struct rtw_chip_info *chip; + struct ieee80211_hw *hw; + struct rtw_dev *rtwdev; + + hw = sdio_get_drvdata(sdio_func); + if (!hw) + return; + + rtwdev = hw->priv; + chip = rtwdev->chip; + + if (chip->ops->shutdown) + chip->ops->shutdown(rtwdev); +} +EXPORT_SYMBOL(rtw_sdio_shutdown); + +MODULE_AUTHOR("Martin Blumenstingl"); +MODULE_AUTHOR("Jernej Skrabec"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless SDIO driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/sdio.h b/drivers/net/wireless/realtek/rtw88/sdio.h new file mode 100644 index 000000000..457e8b023 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sdio.h @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright (C) 2021 Martin Blumenstingl + * Copyright (C) 2021 Jernej Skrabec + */ + +#ifndef __REG_SDIO_H_ +#define __REG_SDIO_H_ + +/* I/O bus domain address mapping */ +#define SDIO_LOCAL_OFFSET 0x10250000 +#define WLAN_IOREG_OFFSET 0x10260000 +#define FIRMWARE_FIFO_OFFSET 0x10270000 +#define TX_HIQ_OFFSET 0x10310000 +#define TX_MIQ_OFFSET 0x10320000 +#define TX_LOQ_OFFSET 0x10330000 +#define TX_EPQ_OFFSET 0x10350000 +#define RX_RX0FF_OFFSET 0x10340000 + +#define RTW_SDIO_BUS_MSK 0xffff0000 +#define SDIO_LOCAL_REG_MSK 0x00000fff +#define WLAN_IOREG_REG_MSK 0x0000ffff + +/* SDIO Tx Control */ +#define REG_SDIO_TX_CTRL (SDIO_LOCAL_OFFSET + 0x0000) + +/*SDIO status timeout*/ +#define REG_SDIO_TIMEOUT (SDIO_LOCAL_OFFSET + 0x0002) + +/* SDIO Host Interrupt Mask */ +#define REG_SDIO_HIMR (SDIO_LOCAL_OFFSET + 0x0014) +#define REG_SDIO_HIMR_RX_REQUEST BIT(0) +#define REG_SDIO_HIMR_AVAL BIT(1) +#define REG_SDIO_HIMR_TXERR BIT(2) +#define REG_SDIO_HIMR_RXERR BIT(3) +#define REG_SDIO_HIMR_TXFOVW BIT(4) +#define REG_SDIO_HIMR_RXFOVW BIT(5) +#define REG_SDIO_HIMR_TXBCNOK BIT(6) +#define REG_SDIO_HIMR_TXBCNERR BIT(7) +#define REG_SDIO_HIMR_BCNERLY_INT BIT(16) +#define REG_SDIO_HIMR_C2HCMD BIT(17) +#define REG_SDIO_HIMR_CPWM1 BIT(18) +#define REG_SDIO_HIMR_CPWM2 BIT(19) +#define REG_SDIO_HIMR_HSISR_IND BIT(20) +#define REG_SDIO_HIMR_GTINT3_IND BIT(21) +#define REG_SDIO_HIMR_GTINT4_IND BIT(22) +#define REG_SDIO_HIMR_PSTIMEOUT BIT(23) +#define REG_SDIO_HIMR_OCPINT BIT(24) +#define REG_SDIO_HIMR_ATIMEND BIT(25) +#define REG_SDIO_HIMR_ATIMEND_E BIT(26) +#define REG_SDIO_HIMR_CTWEND BIT(27) +/* the following two are RTL8188 SDIO Specific */ +#define REG_SDIO_HIMR_MCU_ERR BIT(28) +#define REG_SDIO_HIMR_TSF_BIT32_TOGGLE BIT(29) + +/* SDIO Host Interrupt Service Routine */ +#define REG_SDIO_HISR (SDIO_LOCAL_OFFSET + 0x0018) +#define REG_SDIO_HISR_RX_REQUEST BIT(0) +#define REG_SDIO_HISR_AVAL BIT(1) +#define REG_SDIO_HISR_TXERR BIT(2) +#define REG_SDIO_HISR_RXERR BIT(3) +#define REG_SDIO_HISR_TXFOVW BIT(4) +#define REG_SDIO_HISR_RXFOVW BIT(5) +#define REG_SDIO_HISR_TXBCNOK BIT(6) +#define REG_SDIO_HISR_TXBCNERR BIT(7) +#define REG_SDIO_HISR_BCNERLY_INT BIT(16) +#define REG_SDIO_HISR_C2HCMD BIT(17) +#define REG_SDIO_HISR_CPWM1 BIT(18) +#define REG_SDIO_HISR_CPWM2 BIT(19) +#define REG_SDIO_HISR_HSISR_IND BIT(20) +#define REG_SDIO_HISR_GTINT3_IND BIT(21) +#define REG_SDIO_HISR_GTINT4_IND BIT(22) +#define REG_SDIO_HISR_PSTIMEOUT BIT(23) +#define REG_SDIO_HISR_OCPINT BIT(24) +#define REG_SDIO_HISR_ATIMEND BIT(25) +#define REG_SDIO_HISR_ATIMEND_E BIT(26) +#define REG_SDIO_HISR_CTWEND BIT(27) +/* the following two are RTL8188 SDIO Specific */ +#define REG_SDIO_HISR_MCU_ERR BIT(28) +#define REG_SDIO_HISR_TSF_BIT32_TOGGLE BIT(29) + +/* HCI Current Power Mode */ +#define REG_SDIO_HCPWM (SDIO_LOCAL_OFFSET + 0x0019) +/* RXDMA Request Length */ +#define REG_SDIO_RX0_REQ_LEN (SDIO_LOCAL_OFFSET + 0x001C) +/* OQT Free Page */ +#define REG_SDIO_OQT_FREE_PG (SDIO_LOCAL_OFFSET + 0x001E) +/* Free Tx Buffer Page */ +#define REG_SDIO_FREE_TXPG (SDIO_LOCAL_OFFSET + 0x0020) +/* HCI Current Power Mode 1 */ +#define REG_SDIO_HCPWM1 (SDIO_LOCAL_OFFSET + 0x0024) +/* HCI Current Power Mode 2 */ +#define REG_SDIO_HCPWM2 (SDIO_LOCAL_OFFSET + 0x0026) +/* Free Tx Page Sequence */ +#define REG_SDIO_FREE_TXPG_SEQ (SDIO_LOCAL_OFFSET + 0x0028) +/* HTSF Information */ +#define REG_SDIO_HTSFR_INFO (SDIO_LOCAL_OFFSET + 0x0030) +#define REG_SDIO_HCPWM1_V2 (SDIO_LOCAL_OFFSET + 0x0038) +/* H2C */ +#define REG_SDIO_H2C (SDIO_LOCAL_OFFSET + 0x0060) +/* HCI Request Power Mode 1 */ +#define REG_SDIO_HRPWM1 (SDIO_LOCAL_OFFSET + 0x0080) +/* HCI Request Power Mode 2 */ +#define REG_SDIO_HRPWM2 (SDIO_LOCAL_OFFSET + 0x0082) +/* HCI Power Save Clock */ +#define REG_SDIO_HPS_CLKR (SDIO_LOCAL_OFFSET + 0x0084) +/* SDIO HCI Suspend Control */ +#define REG_SDIO_HSUS_CTRL (SDIO_LOCAL_OFFSET + 0x0086) +#define BIT_HCI_SUS_REQ BIT(0) +#define BIT_HCI_RESUME_RDY BIT(1) +/* SDIO Host Extension Interrupt Mask Always */ +#define REG_SDIO_HIMR_ON (SDIO_LOCAL_OFFSET + 0x0090) +/* SDIO Host Extension Interrupt Status Always */ +#define REG_SDIO_HISR_ON (SDIO_LOCAL_OFFSET + 0x0091) + +#define REG_SDIO_INDIRECT_REG_CFG (SDIO_LOCAL_OFFSET + 0x0040) +#define BIT_SDIO_INDIRECT_REG_CFG_WORD BIT(16) +#define BIT_SDIO_INDIRECT_REG_CFG_DWORD BIT(17) +#define BIT_SDIO_INDIRECT_REG_CFG_WRITE BIT(18) +#define BIT_SDIO_INDIRECT_REG_CFG_READ BIT(19) +#define BIT_SDIO_INDIRECT_REG_CFG_UNK20 BIT(20) +#define REG_SDIO_INDIRECT_REG_DATA (SDIO_LOCAL_OFFSET + 0x0044) + +/* Sdio Address for SDIO Local Reg, TRX FIFO, MAC Reg */ +#define REG_SDIO_CMD_ADDR_MSK GENMASK(16, 13) +#define REG_SDIO_CMD_ADDR_SDIO_REG 0 +#define REG_SDIO_CMD_ADDR_MAC_REG 8 +#define REG_SDIO_CMD_ADDR_TXFF_HIGH 4 +#define REG_SDIO_CMD_ADDR_TXFF_LOW 6 +#define REG_SDIO_CMD_ADDR_TXFF_NORMAL 5 +#define REG_SDIO_CMD_ADDR_TXFF_EXTRA 7 +#define REG_SDIO_CMD_ADDR_RXFF 7 + +#define RTW_SDIO_BLOCK_SIZE 512 +#define RTW_SDIO_ADDR_RX_RX0FF_GEN(_id) (0x0e000 | ((_id) & 0x3)) + +#define RTW_SDIO_DATA_PTR_ALIGN 8 + +struct sdio_func; +struct sdio_device_id; + +struct rtw_sdio_tx_data { + u8 sn; +}; + +struct rtw_sdio_work_data { + struct work_struct work; + struct rtw_dev *rtwdev; +}; + +struct rtw_sdio { + struct sdio_func *sdio_func; + + u32 irq_mask; + u8 rx_addr; + bool sdio3_bus_mode; + + void *irq_thread; + + struct workqueue_struct *txwq; + struct rtw_sdio_work_data *tx_handler_data; + struct sk_buff_head tx_queue[RTK_MAX_TX_QUEUE_NUM]; +}; + +extern const struct dev_pm_ops rtw_sdio_pm_ops; + +int rtw_sdio_probe(struct sdio_func *sdio_func, + const struct sdio_device_id *id); +void rtw_sdio_remove(struct sdio_func *sdio_func); +void rtw_sdio_shutdown(struct sdio_func *sdio_func); + +static inline bool rtw_sdio_is_sdio30_supported(struct rtw_dev *rtwdev) +{ + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + + return rtwsdio->sdio3_bus_mode; +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/sec.c b/drivers/net/wireless/realtek/rtw88/sec.c new file mode 100644 index 000000000..ce46e5b4a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sec.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "sec.h" +#include "reg.h" + +int rtw_sec_get_free_cam(struct rtw_sec_desc *sec) +{ + /* if default key search is enabled, the first 4 cam entries + * are used to direct map to group key with its key->key_idx, so + * driver should use cam entries after 4 to install pairwise key + */ + if (sec->default_key_search) + return find_next_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, + RTW_SEC_DEFAULT_KEY_NUM); + + return find_first_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM); +} + +void rtw_sec_write_cam(struct rtw_dev *rtwdev, + struct rtw_sec_desc *sec, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + u8 hw_key_type, u8 hw_key_idx) +{ + struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx]; + u32 write_cmd; + u32 command; + u32 content; + u32 addr; + int i, j; + + set_bit(hw_key_idx, sec->cam_map); + cam->valid = true; + cam->group = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); + cam->hw_key_type = hw_key_type; + cam->key = key; + if (sta) + ether_addr_copy(cam->addr, sta->addr); + else + eth_broadcast_addr(cam->addr); + + write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING; + addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT; + for (i = 7; i >= 0; i--) { + switch (i) { + case 0: + content = ((key->keyidx & 0x3)) | + ((hw_key_type & 0x7) << 2) | + (cam->group << 6) | + (cam->valid << 15) | + (cam->addr[0] << 16) | + (cam->addr[1] << 24); + break; + case 1: + content = (cam->addr[2]) | + (cam->addr[3] << 8) | + (cam->addr[4] << 16) | + (cam->addr[5] << 24); + break; + case 6: + case 7: + content = 0; + break; + default: + j = (i - 2) << 2; + content = (key->key[j]) | + (key->key[j + 1] << 8) | + (key->key[j + 2] << 16) | + (key->key[j + 3] << 24); + break; + } + + command = write_cmd | (addr + i); + rtw_write32(rtwdev, RTW_SEC_WRITE_REG, content); + rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); + } +} + +void rtw_sec_clear_cam(struct rtw_dev *rtwdev, + struct rtw_sec_desc *sec, + u8 hw_key_idx) +{ + struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx]; + u32 write_cmd; + u32 command; + u32 addr; + + clear_bit(hw_key_idx, sec->cam_map); + cam->valid = false; + cam->key = NULL; + eth_zero_addr(cam->addr); + + write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING; + addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT; + command = write_cmd | addr; + rtw_write32(rtwdev, RTW_SEC_WRITE_REG, 0); + rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); +} + +u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam) +{ + struct rtw_sec_desc *sec = &rtwdev->sec; + u8 offset = 0; + u8 count, n; + + if (!used_cam) + return 0; + + for (count = 0; count < MAX_PG_CAM_BACKUP_NUM; count++) { + n = find_next_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, offset); + if (n == RTW_MAX_SEC_CAM_NUM) + break; + + used_cam[count] = n; + offset = n + 1; + } + + return count; +} + +void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev) +{ + struct rtw_sec_desc *sec = &rtwdev->sec; + u16 ctrl_reg; + u16 sec_config; + + /* default use default key search for now */ + sec->default_key_search = true; + + ctrl_reg = rtw_read16(rtwdev, REG_CR); + ctrl_reg |= RTW_SEC_ENGINE_EN; + rtw_write16(rtwdev, REG_CR, ctrl_reg); + + sec_config = rtw_read16(rtwdev, RTW_SEC_CONFIG); + + sec_config |= RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN; + if (sec->default_key_search) + sec_config |= RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK | + RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK; + + rtw_write16(rtwdev, RTW_SEC_CONFIG, sec_config); +} diff --git a/drivers/net/wireless/realtek/rtw88/sec.h b/drivers/net/wireless/realtek/rtw88/sec.h new file mode 100644 index 000000000..efcf45433 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/sec.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_SEC_H_ +#define __RTW_SEC_H_ + +#define RTW_SEC_CMD_REG 0x670 +#define RTW_SEC_WRITE_REG 0x674 +#define RTW_SEC_READ_REG 0x678 +#define RTW_SEC_CONFIG 0x680 + +#define RTW_SEC_CAM_ENTRY_SHIFT 3 +#define RTW_SEC_DEFAULT_KEY_NUM 4 +#define RTW_SEC_CMD_WRITE_ENABLE BIT(16) +#define RTW_SEC_CMD_CLEAR BIT(30) +#define RTW_SEC_CMD_POLLING BIT(31) + +#define RTW_SEC_TX_UNI_USE_DK BIT(0) +#define RTW_SEC_RX_UNI_USE_DK BIT(1) +#define RTW_SEC_TX_DEC_EN BIT(2) +#define RTW_SEC_RX_DEC_EN BIT(3) +#define RTW_SEC_TX_BC_USE_DK BIT(6) +#define RTW_SEC_RX_BC_USE_DK BIT(7) + +#define RTW_SEC_ENGINE_EN BIT(9) + +int rtw_sec_get_free_cam(struct rtw_sec_desc *sec); +void rtw_sec_write_cam(struct rtw_dev *rtwdev, + struct rtw_sec_desc *sec, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + u8 hw_key_type, u8 hw_key_idx); +void rtw_sec_clear_cam(struct rtw_dev *rtwdev, + struct rtw_sec_desc *sec, + u8 hw_key_idx); +u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam); +void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c new file mode 100644 index 000000000..8786bbb42 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -0,0 +1,746 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "tx.h" +#include "fw.h" +#include "ps.h" +#include "debug.h" + +static +void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + struct rtw_vif *rtwvif; + + hdr = (struct ieee80211_hdr *)skb->data; + + if (!ieee80211_is_data(hdr->frame_control)) + return; + + if (!is_broadcast_ether_addr(hdr->addr1) && + !is_multicast_ether_addr(hdr->addr1)) { + rtwdev->stats.tx_unicast += skb->len; + rtwdev->stats.tx_cnt++; + if (vif) { + rtwvif = (struct rtw_vif *)vif->drv_priv; + rtwvif->stats.tx_unicast += skb->len; + rtwvif->stats.tx_cnt++; + } + } +} + +void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) +{ + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + bool more_data = false; + + if (pkt_info->qsel == TX_DESC_QSEL_HIGH) + more_data = true; + + tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | + le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | + le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | + le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | + le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); + + tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) | + le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | + le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | + le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | + le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | + le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); + + tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | + le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | + le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | + le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); + + tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | + le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | + le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | + le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | + le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | + le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); + + tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); + + if (rtwdev->chip->old_datarate_fb_limit) + tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT); + + tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | + le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | + le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | + le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); + + tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); + + tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); + + tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); + + if (pkt_info->rts) { + tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); + tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); + } + + if (pkt_info->tim_offset) + tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | + le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); +} +EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + +static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta) +{ + u8 exp = sta->deflink.ht_cap.ampdu_factor; + + /* the least ampdu factor is 8K, and the value in the tx desc is the + * max aggregation num, which represents val * 2 packets can be + * aggregated in an AMPDU, so here we should use 8/2=4 as the base + */ + return (BIT(2) << exp) - 1; +} + +static u8 get_tx_ampdu_density(struct ieee80211_sta *sta) +{ + return sta->deflink.ht_cap.ampdu_density; +} + +static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev, + struct ieee80211_sta *sta) +{ + u8 rate; + + if (rtwdev->hal.rf_type == RF_2T2R && sta->deflink.ht_cap.mcs.rx_mask[1] != 0) + rate = DESC_RATEMCS15; + else + rate = DESC_RATEMCS7; + + return rate; +} + +static u8 get_highest_vht_tx_rate(struct rtw_dev *rtwdev, + struct ieee80211_sta *sta) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 rate; + u16 tx_mcs_map; + + tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); + if (efuse->hw_cap.nss == 1) { + switch (tx_mcs_map & 0x3) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + rate = DESC_RATEVHT1SS_MCS7; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + rate = DESC_RATEVHT1SS_MCS8; + break; + default: + case IEEE80211_VHT_MCS_SUPPORT_0_9: + rate = DESC_RATEVHT1SS_MCS9; + break; + } + } else if (efuse->hw_cap.nss >= 2) { + switch ((tx_mcs_map & 0xc) >> 2) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + rate = DESC_RATEVHT2SS_MCS7; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + rate = DESC_RATEVHT2SS_MCS8; + break; + default: + case IEEE80211_VHT_MCS_SUPPORT_0_9: + rate = DESC_RATEVHT2SS_MCS9; + break; + } + } else { + rate = DESC_RATEVHT1SS_MCS9; + } + + return rate; +} + +static void rtw_tx_report_enable(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info) +{ + struct rtw_tx_report *tx_report = &rtwdev->tx_report; + + /* [11:8], reserved, fills with zero + * [7:2], tx report sequence number + * [1:0], firmware use, fills with zero + */ + pkt_info->sn = (atomic_inc_return(&tx_report->sn) << 2) & 0xfc; + pkt_info->report = true; +} + +void rtw_tx_report_purge_timer(struct timer_list *t) +{ + struct rtw_dev *rtwdev = timer_container_of(rtwdev, t, + tx_report.purge_timer); + struct rtw_tx_report *tx_report = &rtwdev->tx_report; + unsigned long flags; + + if (skb_queue_len(&tx_report->queue) == 0) + return; + + rtw_warn(rtwdev, "failed to get tx report from firmware\n"); + + spin_lock_irqsave(&tx_report->q_lock, flags); + skb_queue_purge(&tx_report->queue); + spin_unlock_irqrestore(&tx_report->q_lock, flags); +} + +void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) +{ + struct rtw_tx_report *tx_report = &rtwdev->tx_report; + unsigned long timeout = RTW_TX_PROBE_TIMEOUT; + unsigned long flags; + u8 *drv_data; + + /* pass sn to tx report handler through driver data */ + drv_data = (u8 *)IEEE80211_SKB_CB(skb)->status.status_driver_data; + *drv_data = sn; + + spin_lock_irqsave(&tx_report->q_lock, flags); + __skb_queue_tail(&tx_report->queue, skb); + spin_unlock_irqrestore(&tx_report->q_lock, flags); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D && + rtwdev->hci.type == RTW_HCI_TYPE_USB) + timeout = msecs_to_jiffies(2500); + + mod_timer(&tx_report->purge_timer, jiffies + timeout); +} +EXPORT_SYMBOL(rtw_tx_report_enqueue); + +static void rtw_tx_report_tx_status(struct rtw_dev *rtwdev, + struct sk_buff *skb, bool acked) +{ + struct ieee80211_tx_info *info; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + if (acked) + info->flags |= IEEE80211_TX_STAT_ACK; + else + info->flags &= ~IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(rtwdev->hw, skb); +} + +void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src) +{ + struct rtw_tx_report *tx_report = &rtwdev->tx_report; + struct rtw_c2h_cmd *c2h; + struct sk_buff *cur, *tmp; + unsigned long flags; + u8 sn, st; + u8 *n; + + c2h = get_c2h_from_skb(skb); + + if (src == C2H_CCX_TX_RPT) { + sn = GET_CCX_REPORT_SEQNUM_V0(c2h->payload); + st = GET_CCX_REPORT_STATUS_V0(c2h->payload); + } else { + sn = GET_CCX_REPORT_SEQNUM_V1(c2h->payload); + st = GET_CCX_REPORT_STATUS_V1(c2h->payload); + } + + spin_lock_irqsave(&tx_report->q_lock, flags); + skb_queue_walk_safe(&tx_report->queue, cur, tmp) { + n = (u8 *)IEEE80211_SKB_CB(cur)->status.status_driver_data; + if (*n == sn) { + __skb_unlink(cur, &tx_report->queue); + rtw_tx_report_tx_status(rtwdev, cur, st == 0); + break; + } + } + spin_unlock_irqrestore(&tx_report->q_lock, flags); +} + +static u8 rtw_get_mgmt_rate(struct rtw_dev *rtwdev, struct sk_buff *skb, + u8 lowest_rate, bool ignore_rate) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = tx_info->control.vif; + bool force_lowest = test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); + + if (!vif || !vif->bss_conf.basic_rates || ignore_rate || force_lowest) + return lowest_rate; + + return __ffs(vif->bss_conf.basic_rates) + lowest_rate; +} + +static void rtw_tx_pkt_info_update_rate(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + bool ignore_rate) +{ + if (rtwdev->hal.current_band_type == RTW_BAND_2G) { + pkt_info->rate_id = RTW_RATEID_B_20M; + pkt_info->rate = rtw_get_mgmt_rate(rtwdev, skb, DESC_RATE1M, + ignore_rate); + } else { + pkt_info->rate_id = RTW_RATEID_G; + pkt_info->rate = rtw_get_mgmt_rate(rtwdev, skb, DESC_RATE6M, + ignore_rate); + } + + pkt_info->use_rate = true; + pkt_info->dis_rate_fallback = true; +} + +static void rtw_tx_pkt_info_update_sec(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + u8 sec_type = 0; + + if (info && info->control.hw_key) { + struct ieee80211_key_conf *key = info->control.hw_key; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + sec_type = 0x01; + break; + case WLAN_CIPHER_SUITE_CCMP: + sec_type = 0x03; + break; + default: + break; + } + } + + pkt_info->sec_type = sec_type; +} + +static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb, false); + pkt_info->dis_qselseq = true; + pkt_info->en_hwseq = true; + pkt_info->hw_ssn_sel = 0; + /* TODO: need to change hw port and hw ssn sel for multiple vifs */ +} + +static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_sta_info *si; + u8 fix_rate; + u16 seq; + u8 ampdu_factor = 0; + u8 ampdu_density = 0; + bool ampdu_en = false; + u8 rate = DESC_RATE6M; + u8 rate_id = 6; + u8 bw = RTW_CHANNEL_WIDTH_20; + bool stbc = false; + bool ldpc = false; + + seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + /* for broadcast/multicast, use default values */ + if (!sta) + goto out; + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + ampdu_en = true; + ampdu_factor = get_tx_ampdu_factor(sta); + ampdu_density = get_tx_ampdu_density(sta); + } + + if (info->control.use_rts || skb->len > hw->wiphy->rts_threshold) + pkt_info->rts = true; + + if (sta->deflink.vht_cap.vht_supported) + rate = get_highest_vht_tx_rate(rtwdev, sta); + else if (sta->deflink.ht_cap.ht_supported) + rate = get_highest_ht_tx_rate(rtwdev, sta); + else if (sta->deflink.supp_rates[0] <= 0xf) + rate = DESC_RATE11M; + else + rate = DESC_RATE54M; + + si = (struct rtw_sta_info *)sta->drv_priv; + + bw = si->bw_mode; + rate_id = si->rate_id; + stbc = rtwdev->hal.txrx_1ss ? false : si->stbc_en; + ldpc = si->ldpc_en; + +out: + pkt_info->seq = seq; + pkt_info->ampdu_factor = ampdu_factor; + pkt_info->ampdu_density = ampdu_density; + pkt_info->ampdu_en = ampdu_en; + pkt_info->rate = rate; + pkt_info->rate_id = rate_id; + pkt_info->bw = bw; + pkt_info->stbc = stbc; + pkt_info->ldpc = ldpc; + + fix_rate = dm_info->fix_rate; + if (fix_rate < DESC_RATE_MAX) { + pkt_info->rate = fix_rate; + pkt_info->dis_rate_fallback = true; + pkt_info->use_rate = true; + } +} + +void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_vif *vif = info->control.vif; + struct rtw_sta_info *si; + struct rtw_vif *rtwvif; + __le16 fc = hdr->frame_control; + bool bmc; + + if (sta) { + si = (struct rtw_sta_info *)sta->drv_priv; + pkt_info->mac_id = si->mac_id; + } else if (vif) { + rtwvif = (struct rtw_vif *)vif->drv_priv; + pkt_info->mac_id = rtwvif->mac_id; + } + + if (ieee80211_is_mgmt(fc) || ieee80211_is_any_nullfunc(fc)) + rtw_tx_mgmt_pkt_info_update(rtwdev, pkt_info, sta, skb); + else if (ieee80211_is_data(fc)) + rtw_tx_data_pkt_info_update(rtwdev, pkt_info, sta, skb); + + bmc = is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1); + + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) + rtw_tx_report_enable(rtwdev, pkt_info); + + pkt_info->bmc = bmc; + rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb); + pkt_info->tx_pkt_size = skb->len; + pkt_info->offset = chip->tx_pkt_desc_sz; + pkt_info->qsel = skb->priority; + pkt_info->ls = true; + + /* maybe merge with tx status ? */ + rtw_tx_stats(rtwdev, vif, skb); +} + +void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_rsvd_packet_type type) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + bool bmc; + + /* A beacon or dummy reserved page packet indicates that it is the first + * reserved page, and the qsel of it will be set in each hci. + */ + if (type != RSVD_BEACON && type != RSVD_DUMMY) + pkt_info->qsel = TX_DESC_QSEL_MGMT; + + rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb, true); + + bmc = is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1); + pkt_info->bmc = bmc; + pkt_info->tx_pkt_size = skb->len; + pkt_info->offset = chip->tx_pkt_desc_sz; + pkt_info->ls = true; + if (type == RSVD_PS_POLL) { + pkt_info->nav_use_hdr = true; + } else { + pkt_info->dis_qselseq = true; + pkt_info->en_hwseq = true; + pkt_info->hw_ssn_sel = 0; + } + if (type == RSVD_QOS_NULL) + pkt_info->bt_null = true; + + if (type == RSVD_BEACON) { + struct rtw_rsvd_page *rsvd_pkt; + int hdr_len; + + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, + build_list); + if (rsvd_pkt && rsvd_pkt->tim_offset != 0) { + hdr_len = sizeof(struct ieee80211_hdr_3addr); + pkt_info->tim_offset = rsvd_pkt->tim_offset - hdr_len; + } + } + + rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb); + + /* TODO: need to change hw port and hw ssn sel for multiple vifs */ +} + +struct sk_buff * +rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + u32 tx_pkt_desc_sz; + u32 length; + + tx_pkt_desc_sz = chip->tx_pkt_desc_sz; + length = size + tx_pkt_desc_sz; + skb = dev_alloc_skb(length); + if (!skb) { + rtw_err(rtwdev, "failed to alloc write data rsvd page skb\n"); + return NULL; + } + + skb_reserve(skb, tx_pkt_desc_sz); + skb_put_data(skb, buf, size); + rtw_tx_rsvd_page_pkt_info_update(rtwdev, pkt_info, skb, RSVD_BEACON); + + return skb; +} +EXPORT_SYMBOL(rtw_tx_write_data_rsvd_page_get); + +struct sk_buff * +rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + u32 tx_pkt_desc_sz; + u32 length; + + tx_pkt_desc_sz = chip->tx_pkt_desc_sz; + length = size + tx_pkt_desc_sz; + skb = dev_alloc_skb(length); + if (!skb) { + rtw_err(rtwdev, "failed to alloc write data h2c skb\n"); + return NULL; + } + + skb_reserve(skb, tx_pkt_desc_sz); + skb_put_data(skb, buf, size); + pkt_info->tx_pkt_size = size; + + return skb; +} +EXPORT_SYMBOL(rtw_tx_write_data_h2c_get); + +void rtw_tx(struct rtw_dev *rtwdev, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtw_tx_pkt_info pkt_info = {0}; + int ret; + + rtw_tx_pkt_info_update(rtwdev, &pkt_info, control->sta, skb); + ret = rtw_hci_tx_write(rtwdev, &pkt_info, skb); + if (ret) { + rtw_err(rtwdev, "failed to write TX skb to HCI\n"); + goto out; + } + + rtw_hci_tx_kick_off(rtwdev); + + return; + +out: + ieee80211_free_txskb(rtwdev->hw, skb); +} + +static void rtw_txq_check_agg(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + struct sk_buff *skb) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct ieee80211_tx_info *info; + struct rtw_sta_info *si; + + if (test_bit(RTW_TXQ_AMPDU, &rtwtxq->flags)) { + info = IEEE80211_SKB_CB(skb); + info->flags |= IEEE80211_TX_CTL_AMPDU; + return; + } + + if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) + return; + + if (test_bit(RTW_TXQ_BLOCK_BA, &rtwtxq->flags)) + return; + + if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) + return; + + if (!txq->sta) + return; + + si = (struct rtw_sta_info *)txq->sta->drv_priv; + set_bit(txq->tid, si->tid_ba); + + ieee80211_queue_work(rtwdev->hw, &rtwdev->ba_work); +} + +static int rtw_txq_push_skb(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + struct sk_buff *skb) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct rtw_tx_pkt_info pkt_info = {0}; + int ret; + + rtw_txq_check_agg(rtwdev, rtwtxq, skb); + + rtw_tx_pkt_info_update(rtwdev, &pkt_info, txq->sta, skb); + ret = rtw_hci_tx_write(rtwdev, &pkt_info, skb); + if (ret) { + rtw_err(rtwdev, "failed to write TX skb to HCI\n"); + ieee80211_free_txskb(rtwdev->hw, skb); + return ret; + } + return 0; +} + +static void rtw_txq_push(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + unsigned long frames) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct sk_buff *skb; + unsigned long i; + int ret; + + rcu_read_lock(); + + for (i = 0; i < frames; i++) { + skb = ieee80211_tx_dequeue(rtwdev->hw, txq); + if (!skb) + break; + + ret = rtw_txq_push_skb(rtwdev, rtwtxq, skb); + if (ret) { + rtw_err(rtwdev, "failed to pusk skb, ret %d\n", ret); + break; + } + } + + rcu_read_unlock(); +} + +void __rtw_tx_work(struct rtw_dev *rtwdev) +{ + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); + + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->txqs, list) { + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + unsigned long frame_cnt; + + ieee80211_txq_get_depth(txq, &frame_cnt, NULL); + rtw_txq_push(rtwdev, rtwtxq, frame_cnt); + + list_del_init(&rtwtxq->list); + } + + rtw_hci_tx_kick_off(rtwdev); + + spin_unlock_bh(&rtwdev->txq_lock); +} + +void rtw_tx_work(struct work_struct *w) +{ + struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + + __rtw_tx_work(rtwdev); +} + +void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) +{ + struct rtw_txq *rtwtxq; + + if (!txq) + return; + + rtwtxq = (struct rtw_txq *)txq->drv_priv; + INIT_LIST_HEAD(&rtwtxq->list); +} + +void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) +{ + struct rtw_txq *rtwtxq; + + if (!txq) + return; + + rtwtxq = (struct rtw_txq *)txq->drv_priv; + spin_lock_bh(&rtwdev->txq_lock); + if (!list_empty(&rtwtxq->list)) + list_del_init(&rtwtxq->list); + spin_unlock_bh(&rtwdev->txq_lock); +} + +static const enum rtw_tx_queue_type ac_to_hwq[] = { + [IEEE80211_AC_VO] = RTW_TX_QUEUE_VO, + [IEEE80211_AC_VI] = RTW_TX_QUEUE_VI, + [IEEE80211_AC_BE] = RTW_TX_QUEUE_BE, + [IEEE80211_AC_BK] = RTW_TX_QUEUE_BK, +}; + +static_assert(ARRAY_SIZE(ac_to_hwq) == IEEE80211_NUM_ACS); + +enum rtw_tx_queue_type rtw_tx_ac_to_hwq(enum ieee80211_ac_numbers ac) +{ + if (WARN_ON(unlikely(ac >= IEEE80211_NUM_ACS))) + return RTW_TX_QUEUE_BE; + + return ac_to_hwq[ac]; +} +EXPORT_SYMBOL(rtw_tx_ac_to_hwq); + +enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + u8 q_mapping = skb_get_queue_mapping(skb); + enum rtw_tx_queue_type queue; + + if (unlikely(ieee80211_is_beacon(fc))) + queue = RTW_TX_QUEUE_BCN; + else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + queue = RTW_TX_QUEUE_MGMT; + else if (is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1)) + queue = RTW_TX_QUEUE_HI0; + else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq))) + queue = ac_to_hwq[IEEE80211_AC_BE]; + else + queue = ac_to_hwq[q_mapping]; + + return queue; +} +EXPORT_SYMBOL(rtw_tx_queue_mapping); diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h new file mode 100644 index 000000000..d34cdeca1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/tx.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_TX_H_ +#define __RTW_TX_H_ + +#define RTK_TX_MAX_AGG_NUM_MASK 0x1f + +#define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) + +struct rtw_tx_desc { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; +} __packed; + +#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) +#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) +#define RTW_TX_DESC_W0_BMC BIT(24) +#define RTW_TX_DESC_W0_LS BIT(26) +#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) +#define RTW_TX_DESC_W1_MACID GENMASK(7, 0) +#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) +#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) +#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) +#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) +#define RTW_TX_DESC_W1_MORE_DATA BIT(29) +#define RTW_TX_DESC_W2_AGG_EN BIT(12) +#define RTW_TX_DESC_W2_SPE_RPT BIT(19) +#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) +#define RTW_TX_DESC_W2_BT_NULL BIT(23) +#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) +#define RTW_TX_DESC_W3_USE_RATE BIT(8) +#define RTW_TX_DESC_W3_DISDATAFB BIT(10) +#define RTW_TX_DESC_W3_USE_RTS BIT(12) +#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) +#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) +#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) +#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8) +#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) +#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) +#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) +#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) +#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) +#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) +#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) +#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) +#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) +#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) +#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) +#define RTW_TX_DESC_W9_TIM_EN BIT(7) +#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) + +enum rtw_tx_desc_queue_select { + TX_DESC_QSEL_TID0 = 0, + TX_DESC_QSEL_TID1 = 1, + TX_DESC_QSEL_TID2 = 2, + TX_DESC_QSEL_TID3 = 3, + TX_DESC_QSEL_TID4 = 4, + TX_DESC_QSEL_TID5 = 5, + TX_DESC_QSEL_TID6 = 6, + TX_DESC_QSEL_TID7 = 7, + TX_DESC_QSEL_TID8 = 8, + TX_DESC_QSEL_TID9 = 9, + TX_DESC_QSEL_TID10 = 10, + TX_DESC_QSEL_TID11 = 11, + TX_DESC_QSEL_TID12 = 12, + TX_DESC_QSEL_TID13 = 13, + TX_DESC_QSEL_TID14 = 14, + TX_DESC_QSEL_TID15 = 15, + TX_DESC_QSEL_BEACON = 16, + TX_DESC_QSEL_HIGH = 17, + TX_DESC_QSEL_MGMT = 18, + TX_DESC_QSEL_H2C = 19, +}; + +enum rtw_rsvd_packet_type; + +void rtw_tx(struct rtw_dev *rtwdev, + struct ieee80211_tx_control *control, + struct sk_buff *skb); +void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); +void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); +void rtw_tx_work(struct work_struct *w); +void __rtw_tx_work(struct rtw_dev *rtwdev); +void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb); +void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); +void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); +void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); +void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_rsvd_packet_type type); +struct sk_buff * +rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size); +struct sk_buff * +rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size); + +enum rtw_tx_queue_type rtw_tx_ac_to_hwq(enum ieee80211_ac_numbers ac); +enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb); + +static inline +void fill_txdesc_checksum_common(u8 *txdesc, size_t words) +{ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + + le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), + RTW_TX_DESC_W7_TXDESC_CHECKSUM); +} + +static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c new file mode 100644 index 000000000..64e1c3420 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -0,0 +1,1392 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include +#include +#include "main.h" +#include "debug.h" +#include "mac.h" +#include "reg.h" +#include "tx.h" +#include "rx.h" +#include "fw.h" +#include "ps.h" +#include "usb.h" + +static bool rtw_switch_usb_mode = true; +module_param_named(switch_usb_mode, rtw_switch_usb_mode, bool, 0644); +MODULE_PARM_DESC(switch_usb_mode, + "Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y)"); + +#define RTW_USB_MAX_RXQ_LEN 512 + +struct rtw_usb_txcb { + struct rtw_dev *rtwdev; + struct sk_buff_head tx_ack_queue; +}; + +static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, + struct sk_buff *skb, int agg_num) +{ + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_pkt_info pkt_info; + + le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); + pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); +} + +static void rtw_usb_reg_sec(struct rtw_dev *rtwdev, u32 addr, __le32 *data) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + bool reg_on_section = false; + u16 t_reg = 0x4e0; + u8 t_len = 1; + int status; + + /* There are three sections: + * 1. on (0x00~0xFF; 0x1000~0x10FF): this section is always powered on + * 2. off (< 0xFE00, excluding "on" section): this section could be + * powered off + * 3. local (>= 0xFE00): usb specific registers section + */ + if (addr <= 0xff || (addr >= 0x1000 && addr <= 0x10ff)) + reg_on_section = true; + + if (!reg_on_section) + return; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + t_reg, 0, data, t_len, 500); + + if (status != t_len && status != -ENODEV) + rtw_err(rtwdev, "%s: reg 0x%x, usb write %u fail, status: %d\n", + __func__, t_reg, t_len, status); +} + +static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + __le32 *data; + unsigned long flags; + int idx, ret; + static int count; + + spin_lock_irqsave(&rtwusb->usb_lock, flags); + + idx = rtwusb->usb_data_index; + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1); + + spin_unlock_irqrestore(&rtwusb->usb_lock, flags); + + data = &rtwusb->usb_data[idx]; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr, + RTW_USB_VENQT_CMD_IDX, data, len, 1000); + if (ret < 0 && ret != -ENODEV && count++ < 4) + rtw_err(rtwdev, "read register 0x%x failed with %d\n", + addr, ret); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C || + rtwdev->chip->id == RTW_CHIP_TYPE_8822B || + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_usb_reg_sec(rtwdev, addr, data); + + return le32_to_cpu(*data); +} + +static u8 rtw_usb_read8(struct rtw_dev *rtwdev, u32 addr) +{ + return (u8)rtw_usb_read(rtwdev, addr, 1); +} + +static u16 rtw_usb_read16(struct rtw_dev *rtwdev, u32 addr) +{ + return (u16)rtw_usb_read(rtwdev, addr, 2); +} + +static u32 rtw_usb_read32(struct rtw_dev *rtwdev, u32 addr) +{ + return (u32)rtw_usb_read(rtwdev, addr, 4); +} + +static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) +{ + struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv; + struct usb_device *udev = rtwusb->udev; + unsigned long flags; + __le32 *data; + int idx, ret; + static int count; + + spin_lock_irqsave(&rtwusb->usb_lock, flags); + + idx = rtwusb->usb_data_index; + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1); + + spin_unlock_irqrestore(&rtwusb->usb_lock, flags); + + data = &rtwusb->usb_data[idx]; + + *data = cpu_to_le32(val); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + addr, 0, data, len, 500); + if (ret < 0 && ret != -ENODEV && count++ < 4) + rtw_err(rtwdev, "write register 0x%x failed with %d\n", + addr, ret); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C || + rtwdev->chip->id == RTW_CHIP_TYPE_8822B || + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_usb_reg_sec(rtwdev, addr, data); +} + +static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) +{ + rtw_usb_write(rtwdev, addr, val, 1); +} + +static void rtw_usb_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) +{ + rtw_usb_write(rtwdev, addr, val, 2); +} + +static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) +{ + rtw_usb_write(rtwdev, addr, val, 4); +} + +static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + u32 addr = FW_START_ADDR_LEGACY; + u8 *data_dup, *buf; + u32 n, block_size; + int ret; + + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8723D: + block_size = 254; + break; + default: + block_size = 196; + break; + } + + data_dup = kmemdup(data, size, GFP_KERNEL); + if (!data_dup) + return; + + buf = data_dup; + + rtw_write32_mask(rtwdev, REG_MCUFW_CTRL, BIT_ROM_PGE, page); + + while (size > 0) { + if (size >= block_size) + n = block_size; + else if (size >= 8) + n = 8; + else + n = 1; + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + addr, 0, buf, n, 500); + if (ret != n) { + if (ret != -ENODEV) + rtw_err(rtwdev, + "write 0x%x len %d failed: %d\n", + addr, n, ret); + break; + } + + addr += n; + buf += n; + size -= n; + } + + kfree(data_dup); +} + +static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping) +{ + switch (dma_mapping) { + case RTW_DMA_MAPPING_HIGH: + return 0; + case RTW_DMA_MAPPING_NORMAL: + return 1; + case RTW_DMA_MAPPING_LOW: + return 2; + case RTW_DMA_MAPPING_EXTRA: + return 3; + default: + return -EINVAL; + } +} + +static int rtw_usb_parse(struct rtw_dev *rtwdev, + struct usb_interface *interface) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_host_interface *host_interface = &interface->altsetting[0]; + struct usb_interface_descriptor *interface_desc = &host_interface->desc; + struct usb_endpoint_descriptor *endpoint; + int num_out_pipes = 0; + int i; + u8 num; + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_rqpn *rqpn; + + for (i = 0; i < interface_desc->bNumEndpoints; i++) { + endpoint = &host_interface->endpoint[i].desc; + num = usb_endpoint_num(endpoint); + + if (usb_endpoint_dir_in(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (rtwusb->pipe_in) { + rtw_err(rtwdev, "IN pipes overflow\n"); + return -EINVAL; + } + + rtwusb->pipe_in = num; + } + + if (usb_endpoint_dir_in(endpoint) && + usb_endpoint_xfer_int(endpoint)) { + if (rtwusb->pipe_interrupt) { + rtw_err(rtwdev, "INT pipes overflow\n"); + return -EINVAL; + } + + rtwusb->pipe_interrupt = num; + } + + if (usb_endpoint_dir_out(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (num_out_pipes >= ARRAY_SIZE(rtwusb->out_ep)) { + rtw_err(rtwdev, "OUT pipes overflow\n"); + return -EINVAL; + } + + rtwusb->out_ep[num_out_pipes++] = num; + } + } + + rtwdev->hci.bulkout_num = num_out_pipes; + + if (num_out_pipes < 1 || num_out_pipes > 4) { + rtw_err(rtwdev, "invalid number of endpoints %d\n", num_out_pipes); + return -EINVAL; + } + + rqpn = &chip->rqpn_table[num_out_pipes]; + + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = dma_mapping_to_ep(rqpn->dma_map_be); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = dma_mapping_to_ep(rqpn->dma_map_bk); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = dma_mapping_to_ep(rqpn->dma_map_bk); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = dma_mapping_to_ep(rqpn->dma_map_be); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = dma_mapping_to_ep(rqpn->dma_map_vi); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = dma_mapping_to_ep(rqpn->dma_map_vi); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = dma_mapping_to_ep(rqpn->dma_map_vo); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = dma_mapping_to_ep(rqpn->dma_map_vo); + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID8] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID9] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID10] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID11] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID12] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID13] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID14] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID15] = -EINVAL; + rtwusb->qsel_to_ep[TX_DESC_QSEL_BEACON] = dma_mapping_to_ep(rqpn->dma_map_hi); + rtwusb->qsel_to_ep[TX_DESC_QSEL_HIGH] = dma_mapping_to_ep(rqpn->dma_map_hi); + rtwusb->qsel_to_ep[TX_DESC_QSEL_MGMT] = dma_mapping_to_ep(rqpn->dma_map_mg); + rtwusb->qsel_to_ep[TX_DESC_QSEL_H2C] = dma_mapping_to_ep(rqpn->dma_map_hi); + + return 0; +} + +static void rtw_usb_write_port_tx_complete(struct urb *urb) +{ + struct rtw_usb_txcb *txcb = urb->context; + struct rtw_dev *rtwdev = txcb->rtwdev; + struct ieee80211_hw *hw = rtwdev->hw; + + while (true) { + struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue); + struct ieee80211_tx_info *info; + struct rtw_usb_tx_data *tx_data; + + if (!skb) + break; + + info = IEEE80211_SKB_CB(skb); + tx_data = rtw_usb_get_tx_data(skb); + + skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + + /* enqueue to wait for tx report */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); + continue; + } + + /* always ACK for others, then they won't be marked as drop */ + ieee80211_tx_info_clear_status(info); + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + else + info->flags |= IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(hw, skb); + } + + kfree(txcb); +} + +static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel) +{ + if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep)) + return -EINVAL; + + return rtwusb->qsel_to_ep[qsel]; +} + +static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *skb, + usb_complete_t cb, void *context) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *usbd = rtwusb->udev; + struct urb *urb; + unsigned int pipe; + int ret; + int ep = qsel_to_ep(rtwusb, qsel); + + if (ep < 0) + return ep; + + pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]); + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + usb_fill_bulk_urb(urb, usbd, pipe, skb->data, skb->len, cb, context); + urb->transfer_flags |= URB_ZERO_PACKET; + ret = usb_submit_urb(urb, GFP_ATOMIC); + + usb_free_urb(urb); + + return ret; +} + +static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) +{ + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_desc *tx_desc; + struct rtw_usb_txcb *txcb; + struct sk_buff *skb_head; + struct sk_buff *skb_iter; + int agg_num = 0; + unsigned int align_next = 0; + u8 qsel; + int ret; + + if (skb_queue_empty(list)) + return false; + + txcb = kmalloc_obj(*txcb, GFP_ATOMIC); + if (!txcb) + return false; + + txcb->rtwdev = rtwdev; + skb_queue_head_init(&txcb->tx_ack_queue); + + skb_iter = skb_dequeue(list); + + if (skb_queue_empty(list)) { + skb_head = skb_iter; + goto queue; + } + + skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ); + if (!skb_head) { + skb_head = skb_iter; + goto queue; + } + + while (skb_iter) { + unsigned long flags; + + skb_put(skb_head, align_next); + skb_put_data(skb_head, skb_iter->data, skb_iter->len); + + align_next = ALIGN(skb_iter->len, 8) - skb_iter->len; + + agg_num++; + + skb_queue_tail(&txcb->tx_ack_queue, skb_iter); + + spin_lock_irqsave(&list->lock, flags); + + skb_iter = skb_peek(list); + + if (skb_iter && + skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ && + agg_num < rtwdev->chip->usb_tx_agg_desc_num) + __skb_unlink(skb_iter, list); + else + skb_iter = NULL; + spin_unlock_irqrestore(&list->lock, flags); + } + + if (agg_num > 1) + rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num); + +queue: + skb_queue_tail(&txcb->tx_ack_queue, skb_head); + tx_desc = (struct rtw_tx_desc *)skb_head->data; + qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + + ret = rtw_usb_write_port(rtwdev, qsel, skb_head, + rtw_usb_write_port_tx_complete, txcb); + if (ret) { + ieee80211_purge_tx_queue(rtwdev->hw, &txcb->tx_ack_queue); + kfree(txcb); + return false; + } + + return true; +} + +static void rtw_usb_tx_handler(struct work_struct *work) +{ + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work); + int i, limit; + + for (i = ARRAY_SIZE(rtwusb->tx_queue) - 1; i >= 0; i--) { + for (limit = 0; limit < 200; limit++) { + struct sk_buff_head *list = &rtwusb->tx_queue[i]; + + if (!rtw_usb_tx_agg_skb(rtwusb, list)) + break; + } + } +} + +static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb) +{ + struct rtw_dev *rtwdev = rtwusb->rtwdev; + int i; + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) + ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]); +} + +static void rtw_usb_write_port_complete(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + + dev_kfree_skb_any(skb); +} + +static int rtw_usb_write_data(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + unsigned int size; + u8 qsel; + int ret = 0; + + size = pkt_info->tx_pkt_size; + qsel = pkt_info->qsel; + + skb = dev_alloc_skb(chip->tx_pkt_desc_sz + size); + if (unlikely(!skb)) + return -ENOMEM; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + skb_put_data(skb, buf, size); + skb_push(skb, chip->tx_pkt_desc_sz); + memset(skb->data, 0, chip->tx_pkt_desc_sz); + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + + ret = rtw_usb_write_port(rtwdev, qsel, skb, + rtw_usb_write_port_complete, skb); + if (unlikely(ret)) { + rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret); + dev_kfree_skb_any(skb); + } + + return ret; +} + +static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, + u32 size) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_tx_pkt_info pkt_info = {0}; + + pkt_info.tx_pkt_size = size; + pkt_info.qsel = TX_DESC_QSEL_BEACON; + pkt_info.offset = chip->tx_pkt_desc_sz; + pkt_info.ls = true; + + return rtw_usb_write_data(rtwdev, &pkt_info, buf); +} + +static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) +{ + struct rtw_tx_pkt_info pkt_info = {0}; + + pkt_info.tx_pkt_size = size; + pkt_info.qsel = TX_DESC_QSEL_H2C; + + return rtw_usb_write_data(rtwdev, &pkt_info, buf); +} + +static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + u8 qsel; + + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + qsel = TX_DESC_QSEL_MGMT; + else if (is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1)) + qsel = TX_DESC_QSEL_HIGH; + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) + qsel = skb->priority; + else + qsel = TX_DESC_QSEL_BEACON; + + return qsel; +} + +static int rtw_usb_tx_write(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_usb_tx_data *tx_data; + u8 *pkt_desc; + int ep; + + pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb); + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + ep = qsel_to_ep(rtwusb, pkt_info->qsel); + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + tx_data = rtw_usb_get_tx_data(skb); + tx_data->sn = pkt_info->sn; + + skb_queue_tail(&rtwusb->tx_queue[ep], skb); + + return 0; +} + +static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + queue_work(rtwusb->txwq, &rtwusb->tx_work); +} + +static void rtw_usb_rx_handler(struct work_struct *work) +{ + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct ieee80211_rx_status rx_status; + struct rtw_rx_pkt_stat pkt_stat; + struct sk_buff *rx_skb; + struct sk_buff *skb; + u32 pkt_desc_sz = rtwdev->chip->rx_pkt_desc_sz; + u32 max_skb_len = pkt_desc_sz + PHY_STATUS_SIZE * 8 + + IEEE80211_MAX_MPDU_LEN_VHT_11454; + u32 pkt_offset, next_pkt, skb_len; + int limit, ret; + u8 *rx_desc; + + for (limit = 0; limit < 200; limit++) { + rx_skb = skb_dequeue(&rtwusb->rx_queue); + if (!rx_skb) + break; + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { + dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(rx_skb); + continue; + } + + rx_desc = rx_skb->data; + + do { + ret = rtw_rx_query_rx_desc(rtwdev, rx_desc, + &pkt_stat, &rx_status); + if (ret) + break; + + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + + skb_len = pkt_stat.pkt_len + pkt_offset; + if (skb_len > max_skb_len) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "skipping too big packet: %u\n", + skb_len); + goto skip_packet; + } + + skb = alloc_skb(skb_len, GFP_ATOMIC); + if (!skb) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "failed to allocate RX skb of size %u\n", + skb_len); + goto skip_packet; + } + + skb_put_data(skb, rx_desc, skb_len); + + if (pkt_stat.is_c2h) { + rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); + } else { + skb_pull(skb, pkt_offset); + rtw_update_rx_freq_for_invalid(rtwdev, skb, + &rx_status, + &pkt_stat); + rtw_rx_stats(rtwdev, pkt_stat.vif, skb); + memcpy(skb->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(rtwdev->hw, skb); + } + +skip_packet: + next_pkt = round_up(skb_len, 8); + rx_desc += next_pkt; + } while (rx_desc + pkt_desc_sz < rx_skb->data + rx_skb->len); + + if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW_USB_RX_SKB_NUM) + dev_kfree_skb_any(rx_skb); + else + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } +} + +static void rtw_usb_read_port_complete(struct urb *urb); + +static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, + struct rx_usb_ctrl_block *rxcb, + gfp_t gfp) +{ + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct sk_buff *rx_skb; + int error; + + rx_skb = skb_dequeue(&rtwusb->rx_free_queue); + if (!rx_skb) + rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, gfp); + + if (!rx_skb) + goto try_later; + + skb_reset_tail_pointer(rx_skb); + rx_skb->len = 0; + + rxcb->rx_skb = rx_skb; + + usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, + usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in), + rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ, + rtw_usb_read_port_complete, rxcb); + + error = usb_submit_urb(rxcb->rx_urb, gfp); + if (error) { + skb_queue_tail(&rtwusb->rx_free_queue, rxcb->rx_skb); + + if (error != -ENODEV) + rtw_err(rtwdev, "Err sending rx data urb %d\n", + error); + + if (error == -ENOMEM) + goto try_later; + } + + return; + +try_later: + rxcb->rx_skb = NULL; + queue_work(rtwusb->rxwq, &rtwusb->rx_urb_work); +} + +static void rtw_usb_rx_resubmit_work(struct work_struct *work) +{ + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_urb_work); + struct rx_usb_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + + if (!rxcb->rx_skb) + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); + } +} + +static void rtw_usb_read_port_complete(struct urb *urb) +{ + struct rx_usb_ctrl_block *rxcb = urb->context; + struct rtw_dev *rtwdev = rxcb->rtwdev; + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct sk_buff *skb = rxcb->rx_skb; + + if (urb->status == 0) { + if (urb->actual_length >= RTW_USB_MAX_RECVBUF_SZ || + urb->actual_length < 24) { + rtw_err(rtwdev, "failed to get urb length:%d\n", + urb->actual_length); + skb_queue_tail(&rtwusb->rx_free_queue, skb); + } else { + skb_put(skb, urb->actual_length); + skb_queue_tail(&rtwusb->rx_queue, skb); + queue_work(rtwusb->rxwq, &rtwusb->rx_work); + } + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); + } else { + skb_queue_tail(&rtwusb->rx_free_queue, skb); + + switch (urb->status) { + case -EINVAL: + case -EPIPE: + case -ENODEV: + case -ESHUTDOWN: + case -ENOENT: + case -EPROTO: + case -EILSEQ: + case -ETIME: + case -ECOMM: + case -EOVERFLOW: + case -EINPROGRESS: + break; + default: + rtw_err(rtwdev, "status %d\n", urb->status); + break; + } + } +} + +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb) +{ + struct rx_usb_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + usb_kill_urb(rxcb->rx_urb); + } +} + +static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb) +{ + struct rx_usb_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + usb_kill_urb(rxcb->rx_urb); + usb_free_urb(rxcb->rx_urb); + } +} + +static int rtw_usb_alloc_rx_bufs(struct rtw_usb *rtwusb) +{ + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; + + rxcb->rtwdev = rtwusb->rtwdev; + rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rxcb->rx_urb) + goto err; + } + + return 0; +err: + rtw_usb_free_rx_bufs(rtwusb); + return -ENOMEM; +} + +static int rtw_usb_setup(struct rtw_dev *rtwdev) +{ + /* empty function for rtw_hci_ops */ + return 0; +} + +static int rtw_usb_start(struct rtw_dev *rtwdev) +{ + return 0; +} + +static void rtw_usb_stop(struct rtw_dev *rtwdev) +{ +} + +static void rtw_usb_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + /* empty function for rtw_hci_ops */ +} + +static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + /* empty function for rtw_hci_ops */ +} + +static void rtw_usb_init_burst_pkt_len(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + enum usb_device_speed speed = rtwusb->udev->speed; + u8 rxdma, burst_size; + + rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; + + if (speed == USB_SPEED_SUPER) + burst_size = BIT_DMA_BURST_SIZE_1024; + else if (speed == USB_SPEED_HIGH) + burst_size = BIT_DMA_BURST_SIZE_512; + else + burst_size = BIT_DMA_BURST_SIZE_64; + + u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); + + rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); +} + +static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev) +{ + rtw_usb_init_burst_pkt_len(rtwdev); +} + +static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable) +{ + u8 size, timeout; + u16 val16; + + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); + rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); + + if (enable) { + size = 0x5; + timeout = 0x20; + } else { + size = 0x0; + timeout = 0x1; + } + val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | + u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); + + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); +} + +static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + u8 size, timeout; + u16 val16; + + if (!enable) { + size = 0x0; + timeout = 0x1; + } else if (rtwusb->udev->speed == USB_SPEED_SUPER) { + size = 0x6; + timeout = 0x1a; + } else { + size = 0x5; + timeout = 0x20; + } + + val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | + u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); + + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); +} + +static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) +{ + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8822C: + case RTW_CHIP_TYPE_8822B: + case RTW_CHIP_TYPE_8821C: + case RTW_CHIP_TYPE_8814A: + rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); + break; + case RTW_CHIP_TYPE_8821A: + case RTW_CHIP_TYPE_8812A: + rtw_usb_dynamic_rx_agg_v2(rtwdev, enable); + break; + case RTW_CHIP_TYPE_8723D: + /* Doesn't like aggregation. */ + break; + case RTW_CHIP_TYPE_8703B: + /* Likely not found in USB devices. */ + break; + } +} + +static const struct rtw_hci_ops rtw_usb_ops = { + .tx_write = rtw_usb_tx_write, + .tx_kick_off = rtw_usb_tx_kick_off, + .setup = rtw_usb_setup, + .start = rtw_usb_start, + .stop = rtw_usb_stop, + .deep_ps = rtw_usb_deep_ps, + .link_ps = rtw_usb_link_ps, + .interface_cfg = rtw_usb_interface_cfg, + .dynamic_rx_agg = rtw_usb_dynamic_rx_agg, + .write_firmware_page = rtw_usb_write_firmware_page, + + .write8 = rtw_usb_write8, + .write16 = rtw_usb_write16, + .write32 = rtw_usb_write32, + .read8 = rtw_usb_read8, + .read16 = rtw_usb_read16, + .read32 = rtw_usb_read32, + + .write_data_rsvd_page = rtw_usb_write_data_rsvd_page, + .write_data_h2c = rtw_usb_write_data_h2c, +}; + +static int rtw_usb_init_rx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct sk_buff *rx_skb; + int i; + + rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_PERCPU, + 0); + if (!rtwusb->rxwq) { + rtw_err(rtwdev, "failed to create RX work queue\n"); + return -ENOMEM; + } + + skb_queue_head_init(&rtwusb->rx_queue); + skb_queue_head_init(&rtwusb->rx_free_queue); + + INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler); + INIT_WORK(&rtwusb->rx_urb_work, rtw_usb_rx_resubmit_work); + + for (i = 0; i < RTW_USB_RX_SKB_NUM; i++) { + rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL); + if (rx_skb) + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } + + return 0; +} + +static void rtw_usb_setup_rx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; + + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_KERNEL); + } +} + +static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + skb_queue_purge(&rtwusb->rx_queue); + + destroy_workqueue(rtwusb->rxwq); + + skb_queue_purge(&rtwusb->rx_free_queue); +} + +static int rtw_usb_init_tx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + int i; + + rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq"); + if (!rtwusb->txwq) { + rtw_err(rtwdev, "failed to create TX work queue\n"); + return -ENOMEM; + } + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) + skb_queue_head_init(&rtwusb->tx_queue[i]); + + INIT_WORK(&rtwusb->tx_work, rtw_usb_tx_handler); + + return 0; +} + +static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + destroy_workqueue(rtwusb->txwq); + rtw_usb_tx_queue_purge(rtwusb); +} + +static int rtw_usb_intf_init(struct rtw_dev *rtwdev, + struct usb_interface *intf) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = interface_to_usbdev(intf); + int ret; + + rtwusb->udev = udev; + ret = rtw_usb_parse(rtwdev, intf); + if (ret) + return ret; + + rtwusb->usb_data = kcalloc(RTW_USB_MAX_RXTX_COUNT, sizeof(u32), + GFP_KERNEL); + if (!rtwusb->usb_data) + return -ENOMEM; + + usb_set_intfdata(intf, rtwdev->hw); + + SET_IEEE80211_DEV(rtwdev->hw, &intf->dev); + spin_lock_init(&rtwusb->usb_lock); + + return 0; +} + +static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev, + struct usb_interface *intf) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + kfree(rtwusb->usb_data); + usb_set_intfdata(intf, NULL); +} + +static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + enum usb_device_speed cur_speed = rtwusb->udev->speed; + u8 hci_opt; + + if (cur_speed == USB_SPEED_HIGH) { + hci_opt = rtw_read8(rtwdev, REG_HCI_OPT_CTRL); + + if ((hci_opt & (BIT(2) | BIT(3))) != BIT(3)) { + rtw_write8(rtwdev, REG_HCI_OPT_CTRL, 0x8); + rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x2); + rtw_write8(rtwdev, REG_ACLK_MON, 0x1); + rtw_write8(rtwdev, 0x3d, 0x3); + /* usb disconnect */ + rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80); + return 1; + } + } else if (cur_speed == USB_SPEED_SUPER) { + rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT(1)); + rtw_write8_clr(rtwdev, REG_ACLK_MON, BIT(0)); + } + + return 0; +} + +static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) +{ + enum usb_device_speed cur_speed; + u8 id = rtwdev->chip->id; + bool can_switch; + u32 pad_ctrl2; + + if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) + cur_speed = USB_SPEED_SUPER; + else + cur_speed = USB_SPEED_HIGH; + + if (cur_speed == USB_SPEED_SUPER) + return 0; + + pad_ctrl2 = rtw_read32(rtwdev, REG_PAD_CTRL2); + + can_switch = !!(pad_ctrl2 & (BIT_MASK_USB23_SW_MODE_V1 | + BIT_USB3_USB2_TRANSITION)); + + if (!can_switch) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "Switching to USB 3 mode unsupported by the chip\n"); + return 0; + } + + /* At this point cur_speed is USB_SPEED_HIGH. If we already tried + * to switch don't try again - it's a USB 2 port. + */ + if (u32_get_bits(pad_ctrl2, BIT_MASK_USB23_SW_MODE_V1) == BIT_USB_MODE_U3) + return 0; + + /* Enable IO wrapper timeout */ + if (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C) + rtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0)); + + u32p_replace_bits(&pad_ctrl2, BIT_USB_MODE_U3, BIT_MASK_USB23_SW_MODE_V1); + pad_ctrl2 |= BIT_RSM_EN_V1; + + rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2); + rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4); + + rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC); + usleep_range(1000, 1001); + rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1); + + return 1; +} + +static bool rtw_usb3_chip_old(u8 chip_id) +{ + return chip_id == RTW_CHIP_TYPE_8812A || + chip_id == RTW_CHIP_TYPE_8814A; +} + +static bool rtw_usb3_chip_new(u8 chip_id) +{ + return chip_id == RTW_CHIP_TYPE_8822C || + chip_id == RTW_CHIP_TYPE_8822B; +} + +static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) +{ + u8 id = rtwdev->chip->id; + + if (!rtw_usb3_chip_new(id) && !rtw_usb3_chip_old(id)) + return 0; + + if (!rtwdev->efuse.usb_mode_switch) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "Switching to USB 3 mode disabled by chip's efuse\n"); + return 0; + } + + if (!rtw_switch_usb_mode) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "Switching to USB 3 mode disabled by module parameter\n"); + return 0; + } + + if (rtw_usb3_chip_old(id)) + return rtw_usb_switch_mode_old(rtwdev); + else + return rtw_usb_switch_mode_new(rtwdev); +} + +#define USB_REG_PAGE 0xf4 +#define USB_PHY_PAGE0 0x9b +#define USB_PHY_PAGE1 0xbb + +static void rtw_usb_phy_write(struct rtw_dev *rtwdev, u8 addr, u16 data, + enum usb_device_speed speed) +{ + if (speed == USB_SPEED_SUPER) { + rtw_write8(rtwdev, REG_USB3_PHY_DAT_L, data & 0xff); + rtw_write8(rtwdev, REG_USB3_PHY_DAT_H, data >> 8); + rtw_write8(rtwdev, REG_USB3_PHY_ADR, addr | BIT_USB3_PHY_ADR_WR); + } else if (speed == USB_SPEED_HIGH) { + rtw_write8(rtwdev, REG_USB2_PHY_DAT, data); + rtw_write8(rtwdev, REG_USB2_PHY_ADR, addr); + rtw_write8(rtwdev, REG_USB2_PHY_CMD, BIT_USB2_PHY_CMD_TRG); + } +} + +static void rtw_usb_page_switch(struct rtw_dev *rtwdev, + enum usb_device_speed speed, u8 page) +{ + if (speed == USB_SPEED_SUPER) + return; + + rtw_usb_phy_write(rtwdev, USB_REG_PAGE, page, speed); +} + +static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev, + enum usb_device_speed speed) +{ + const struct rtw_intf_phy_para *para = NULL; + u16 offset; + + if (!rtwdev->chip->intf_table) + return; + + if (speed == USB_SPEED_SUPER) + para = rtwdev->chip->intf_table->usb3_para; + else if (speed == USB_SPEED_HIGH) + para = rtwdev->chip->intf_table->usb2_para; + + if (!para) + return; + + for ( ; para->offset != 0xffff; para++) { + if (!(para->cut_mask & BIT(rtwdev->hal.cut_version))) + continue; + + offset = para->offset; + + if (para->ip_sel == RTW_IP_SEL_MAC) { + rtw_write8(rtwdev, offset, para->value); + } else { + if (offset > 0x100) + rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE1); + else + rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE0); + + offset &= 0xff; + + rtw_usb_phy_write(rtwdev, offset, para->value, speed); + } + } +} + +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct rtw_dev *rtwdev; + struct ieee80211_hw *hw; + struct rtw_usb *rtwusb; + int drv_data_size; + int ret; + + drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_usb); + hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops); + if (!hw) + return -ENOMEM; + + rtwdev = hw->priv; + rtwdev->hw = hw; + rtwdev->dev = &intf->dev; + rtwdev->chip = (struct rtw_chip_info *)id->driver_info; + rtwdev->hci.ops = &rtw_usb_ops; + rtwdev->hci.type = RTW_HCI_TYPE_USB; + + rtwusb = rtw_get_usb_priv(rtwdev); + rtwusb->rtwdev = rtwdev; + + ret = rtw_usb_alloc_rx_bufs(rtwusb); + if (ret) + goto err_release_hw; + + ret = rtw_core_init(rtwdev); + if (ret) + goto err_free_rx_bufs; + + ret = rtw_usb_intf_init(rtwdev, intf); + if (ret) { + rtw_err(rtwdev, "failed to init USB interface\n"); + goto err_deinit_core; + } + + ret = rtw_usb_init_tx(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to init USB TX\n"); + goto err_destroy_usb; + } + + ret = rtw_usb_init_rx(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to init USB RX\n"); + goto err_destroy_txwq; + } + + ret = rtw_chip_info_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup chip information\n"); + goto err_destroy_rxwq; + } + + rtw_usb_phy_cfg(rtwdev, USB_SPEED_HIGH); + rtw_usb_phy_cfg(rtwdev, USB_SPEED_SUPER); + + ret = rtw_usb_switch_mode(rtwdev); + if (ret) { + /* Not a fail, but we do need to skip rtw_register_hw. */ + rtw_dbg(rtwdev, RTW_DBG_USB, "switching to USB 3 mode\n"); + ret = 0; + goto err_destroy_rxwq; + } + + ret = rtw_register_hw(rtwdev, rtwdev->hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw\n"); + goto err_destroy_rxwq; + } + + rtw_usb_setup_rx(rtwdev); + + return 0; + +err_destroy_rxwq: + rtw_usb_deinit_rx(rtwdev); + +err_destroy_txwq: + rtw_usb_deinit_tx(rtwdev); + +err_destroy_usb: + rtw_usb_intf_deinit(rtwdev, intf); + +err_deinit_core: + rtw_core_deinit(rtwdev); + +err_free_rx_bufs: + rtw_usb_free_rx_bufs(rtwusb); + +err_release_hw: + ieee80211_free_hw(hw); + + return ret; +} +EXPORT_SYMBOL(rtw_usb_probe); + +void rtw_usb_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct rtw_dev *rtwdev; + struct rtw_usb *rtwusb; + + if (!hw) + return; + + rtwdev = hw->priv; + rtwusb = rtw_get_usb_priv(rtwdev); + + rtw_usb_cancel_rx_bufs(rtwusb); + + rtw_unregister_hw(rtwdev, hw); + rtw_usb_deinit_tx(rtwdev); + rtw_usb_deinit_rx(rtwdev); + + if (rtwusb->udev->state != USB_STATE_NOTATTACHED) + usb_reset_device(rtwusb->udev); + + rtw_usb_free_rx_bufs(rtwusb); + + rtw_usb_intf_deinit(rtwdev, intf); + rtw_core_deinit(rtwdev); + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtw_usb_disconnect); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek USB 802.11ac wireless driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h new file mode 100644 index 000000000..9b695b688 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/usb.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_USB_H_ +#define __RTW_USB_H_ + +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x5fff + +#define RTW_USB_MAX_RXTX_COUNT 128 +#define RTW_USB_VENQT_MAX_BUF_SIZE 254 +#define MAX_USBCTRL_VENDORREQ_TIMES 10 + +#define RTW_USB_CMD_READ 0xc0 +#define RTW_USB_CMD_WRITE 0x40 +#define RTW_USB_CMD_REQ 0x05 + +#define RTW_USB_VENQT_CMD_IDX 0x00 + +#define RTW_USB_TX_SEL_HQ BIT(0) +#define RTW_USB_TX_SEL_LQ BIT(1) +#define RTW_USB_TX_SEL_NQ BIT(2) +#define RTW_USB_TX_SEL_EQ BIT(3) + +#define RTW_USB_BULK_IN_ADDR 0x80 +#define RTW_USB_INT_IN_ADDR 0x81 + +#define RTW_USB_HW_QUEUE_ENTRY 8 + +#define RTW_USB_PACKET_OFFSET_SZ 8 +#define RTW_USB_MAX_XMITBUF_SZ (1024 * 20) +#define RTW_USB_MAX_RECVBUF_SZ 32768 + +#define RTW_USB_RECVBUFF_ALIGN_SZ 8 + +#define RTW_USB_RXAGG_SIZE 6 +#define RTW_USB_RXAGG_TIMEOUT 10 + +#define RTW_USB_RXCB_NUM 4 +#define RTW_USB_RX_SKB_NUM 8 + +#define RTW_USB_EP_MAX 4 + +#define TX_DESC_QSEL_MAX 20 + +#define RTW_USB_VENDOR_ID_REALTEK 0x0bda + +static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev) +{ + return (struct rtw_usb *)rtwdev->priv; +} + +struct rx_usb_ctrl_block { + struct rtw_dev *rtwdev; + struct urb *rx_urb; + struct sk_buff *rx_skb; +}; + +struct rtw_usb_tx_data { + u8 sn; +}; + +struct rtw_usb { + struct rtw_dev *rtwdev; + struct usb_device *udev; + + /* protects usb_data_index */ + spinlock_t usb_lock; + __le32 *usb_data; + unsigned int usb_data_index; + + u8 pipe_interrupt; + u8 pipe_in; + u8 out_ep[RTW_USB_EP_MAX]; + int qsel_to_ep[TX_DESC_QSEL_MAX]; + + struct workqueue_struct *txwq, *rxwq; + + struct sk_buff_head tx_queue[RTW_USB_EP_MAX]; + struct work_struct tx_work; + + struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM]; + struct sk_buff_head rx_queue; + struct sk_buff_head rx_free_queue; + struct work_struct rx_work; + struct work_struct rx_urb_work; +}; + +static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) > + sizeof(info->status.status_driver_data)); + + return (struct rtw_usb_tx_data *)info->status.status_driver_data; +} + +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); +void rtw_usb_disconnect(struct usb_interface *intf); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c new file mode 100644 index 000000000..fcd6eb1ab --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/util.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "util.h" +#include "reg.h" + +bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target) +{ + u32 cnt; + + for (cnt = 0; cnt < 1000; cnt++) { + if (rtw_read32_mask(rtwdev, addr, mask) == target) + return true; + + udelay(10); + } + + return false; +} +EXPORT_SYMBOL(check_hw_ready); + +bool ltecoex_read_reg(struct rtw_dev *rtwdev, u16 offset, u32 *val) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr; + + if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1)) + return false; + + rtw_write32(rtwdev, ltecoex->ctrl, 0x800F0000 | offset); + *val = rtw_read32(rtwdev, ltecoex->rdata); + + return true; +} + +bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr; + + if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1)) + return false; + + rtw_write32(rtwdev, ltecoex->wdata, value); + rtw_write32(rtwdev, ltecoex->ctrl, 0xC00F0000 | offset); + + return true; +} + +void rtw_restore_reg(struct rtw_dev *rtwdev, + struct rtw_backup_info *bckp, u32 num) +{ + u8 len; + u32 reg; + u32 val; + int i; + + for (i = 0; i < num; i++, bckp++) { + len = bckp->len; + reg = bckp->reg; + val = bckp->val; + + switch (len) { + case 1: + rtw_write8(rtwdev, reg, (u8)val); + break; + case 2: + rtw_write16(rtwdev, reg, (u16)val); + break; + case 4: + rtw_write32(rtwdev, reg, (u32)val); + break; + default: + break; + } + } +} +EXPORT_SYMBOL(rtw_restore_reg); + +void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) +{ + if (rate <= DESC_RATE54M) + return; + + if (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT1SS_MCS9) { + *nss = 1; + *mcs = rate - DESC_RATEVHT1SS_MCS0; + } else if (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9) { + *nss = 2; + *mcs = rate - DESC_RATEVHT2SS_MCS0; + } else if (rate >= DESC_RATEVHT3SS_MCS0 && + rate <= DESC_RATEVHT3SS_MCS9) { + *nss = 3; + *mcs = rate - DESC_RATEVHT3SS_MCS0; + } else if (rate >= DESC_RATEVHT4SS_MCS0 && + rate <= DESC_RATEVHT4SS_MCS9) { + *nss = 4; + *mcs = rate - DESC_RATEVHT4SS_MCS0; + } else if (rate >= DESC_RATEMCS0 && + rate <= DESC_RATEMCS31) { + *nss = 0; + *mcs = rate - DESC_RATEMCS0; + } +} + +struct rtw_stas_entry { + struct list_head list; + struct ieee80211_sta *sta; +}; + +struct rtw_iter_stas_data { + struct rtw_dev *rtwdev; + struct list_head list; +}; + +static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_iter_stas_data *iter_stas = data; + struct rtw_stas_entry *stas_entry; + + stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC); + if (!stas_entry) + return; + + stas_entry->sta = sta; + list_add_tail(&stas_entry->list, &iter_stas->list); +} + +void rtw_iterate_stas(struct rtw_dev *rtwdev, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data) +{ + struct rtw_iter_stas_data iter_data; + struct rtw_stas_entry *sta_entry, *tmp; + + /* &rtwdev->mutex makes sure no stations can be removed between + * collecting the stations and iterating over them. + */ + lockdep_assert_held(&rtwdev->mutex); + + iter_data.rtwdev = rtwdev; + INIT_LIST_HEAD(&iter_data.list); + + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter, + &iter_data); + + list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, + list) { + list_del_init(&sta_entry->list); + iterator(data, sta_entry->sta); + kfree(sta_entry); + } +} + +struct rtw_vifs_entry { + struct list_head list; + struct ieee80211_vif *vif; +}; + +struct rtw_iter_vifs_data { + struct rtw_dev *rtwdev; + struct list_head list; +}; + +static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct rtw_iter_vifs_data *iter_stas = data; + struct rtw_vifs_entry *vifs_entry; + + vifs_entry = kmalloc_obj(*vifs_entry, GFP_ATOMIC); + if (!vifs_entry) + return; + + vifs_entry->vif = vif; + list_add_tail(&vifs_entry->list, &iter_stas->list); +} + +void rtw_iterate_vifs(struct rtw_dev *rtwdev, + void (*iterator)(void *data, struct ieee80211_vif *vif), + void *data) +{ + struct rtw_iter_vifs_data iter_data; + struct rtw_vifs_entry *vif_entry, *tmp; + + /* &rtwdev->mutex makes sure no interfaces can be removed between + * collecting the interfaces and iterating over them. + */ + lockdep_assert_held(&rtwdev->mutex); + + iter_data.rtwdev = rtwdev; + INIT_LIST_HEAD(&iter_data.list); + + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, + IEEE80211_IFACE_ITER_NORMAL, + rtw_collect_vif_iter, &iter_data); + + list_for_each_entry_safe(vif_entry, tmp, &iter_data.list, + list) { + list_del_init(&vif_entry->list); + iterator(data, vif_entry->vif); + kfree(vif_entry); + } +} diff --git a/drivers/net/wireless/realtek/rtw88/util.h b/drivers/net/wireless/realtek/rtw88/util.h new file mode 100644 index 000000000..f8399128a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/util.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_UTIL_H__ +#define __RTW_UTIL_H__ + +struct rtw_dev; + +#define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \ + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \ + IEEE80211_IFACE_ITER_NORMAL, iterator, data) +#define rtw_iterate_stas_atomic(rtwdev, iterator, data) \ + ieee80211_iterate_stations_atomic(rtwdev->hw, iterator, data) +#define rtw_iterate_keys(rtwdev, vif, iterator, data) \ + ieee80211_iter_keys(rtwdev->hw, vif, iterator, data) +#define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data) \ + ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data) + +void rtw_iterate_vifs(struct rtw_dev *rtwdev, + void (*iterator)(void *data, struct ieee80211_vif *vif), + void *data); +void rtw_iterate_stas(struct rtw_dev *rtwdev, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data); + +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) +{ + __le16 fc = hdr->frame_control; + u8 *bssid; + + if (ieee80211_has_tods(fc)) + bssid = hdr->addr1; + else if (ieee80211_has_fromds(fc)) + bssid = hdr->addr2; + else + bssid = hdr->addr3; + + return bssid; +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/wow.c b/drivers/net/wireless/realtek/rtw88/wow.c new file mode 100644 index 000000000..16ddee577 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/wow.c @@ -0,0 +1,913 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "fw.h" +#include "wow.h" +#include "reg.h" +#include "debug.h" +#include "mac.h" +#include "ps.h" + +static void rtw_wow_show_wakeup_reason(struct rtw_dev *rtwdev) +{ + struct cfg80211_wowlan_nd_info nd_info; + struct cfg80211_wowlan_wakeup wakeup = { + .pattern_idx = -1, + }; + u8 reason; + + reason = rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON); + + switch (reason) { + case RTW_WOW_RSN_RX_DEAUTH: + wakeup.disconnect = true; + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx deauth\n"); + break; + case RTW_WOW_RSN_DISCONNECT: + wakeup.disconnect = true; + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: AP is off\n"); + break; + case RTW_WOW_RSN_RX_MAGIC_PKT: + wakeup.magic_pkt = true; + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx magic packet\n"); + break; + case RTW_WOW_RSN_RX_GTK_REKEY: + wakeup.gtk_rekey_failure = true; + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx gtk rekey\n"); + break; + case RTW_WOW_RSN_RX_PATTERN_MATCH: + /* Current firmware and driver don't report pattern index + * Use pattern_idx to 0 defaultly. + */ + wakeup.pattern_idx = 0; + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx pattern match packet\n"); + break; + case RTW_WOW_RSN_RX_NLO: + /* Current firmware and driver don't report ssid index. + * Use 0 for n_matches based on its comment. + */ + nd_info.n_matches = 0; + wakeup.net_detect = &nd_info; + rtw_dbg(rtwdev, RTW_DBG_WOW, "Rx NLO\n"); + break; + default: + rtw_warn(rtwdev, "Unknown wakeup reason %x\n", reason); + ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL, + GFP_KERNEL); + return; + } + ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup, + GFP_KERNEL); +} + +static void rtw_wow_pattern_write_cam(struct rtw_dev *rtwdev, u8 addr, + u32 wdata) +{ + rtw_write32(rtwdev, REG_WKFMCAM_RWD, wdata); + rtw_write32(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | + BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr)); + + if (!check_hw_ready(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1, 0)) + rtw_err(rtwdev, "failed to write pattern cam\n"); +} + +static void rtw_wow_pattern_write_cam_ent(struct rtw_dev *rtwdev, u8 id, + struct rtw_wow_pattern *rtw_pattern) +{ + int i; + u8 addr; + u32 wdata; + + for (i = 0; i < RTW_MAX_PATTERN_MASK_SIZE / 4; i++) { + addr = (id << 3) + i; + wdata = rtw_pattern->mask[i * 4]; + wdata |= rtw_pattern->mask[i * 4 + 1] << 8; + wdata |= rtw_pattern->mask[i * 4 + 2] << 16; + wdata |= rtw_pattern->mask[i * 4 + 3] << 24; + rtw_wow_pattern_write_cam(rtwdev, addr, wdata); + } + + wdata = rtw_pattern->crc; + addr = (id << 3) + RTW_MAX_PATTERN_MASK_SIZE / 4; + + switch (rtw_pattern->type) { + case RTW_PATTERN_BROADCAST: + wdata |= BIT_WKFMCAM_BC | BIT_WKFMCAM_VALID; + break; + case RTW_PATTERN_MULTICAST: + wdata |= BIT_WKFMCAM_MC | BIT_WKFMCAM_VALID; + break; + case RTW_PATTERN_UNICAST: + wdata |= BIT_WKFMCAM_UC | BIT_WKFMCAM_VALID; + break; + default: + break; + } + rtw_wow_pattern_write_cam(rtwdev, addr, wdata); +} + +/* RTK internal CRC16 for Pattern Cam */ +static u16 __rtw_cal_crc16(u8 data, u16 crc) +{ + u8 shift_in, data_bit; + u8 crc_bit4, crc_bit11, crc_bit15; + u16 crc_result; + int index; + + for (index = 0; index < 8; index++) { + crc_bit15 = ((crc & BIT(15)) ? 1 : 0); + data_bit = (data & (BIT(0) << index) ? 1 : 0); + shift_in = crc_bit15 ^ data_bit; + + crc_result = crc << 1; + + if (shift_in == 0) + crc_result &= (~BIT(0)); + else + crc_result |= BIT(0); + + crc_bit11 = ((crc & BIT(11)) ? 1 : 0) ^ shift_in; + + if (crc_bit11 == 0) + crc_result &= (~BIT(12)); + else + crc_result |= BIT(12); + + crc_bit4 = ((crc & BIT(4)) ? 1 : 0) ^ shift_in; + + if (crc_bit4 == 0) + crc_result &= (~BIT(5)); + else + crc_result |= BIT(5); + + crc = crc_result; + } + return crc; +} + +static u16 rtw_calc_crc(u8 *pdata, int length) +{ + u16 crc = 0xffff; + int i; + + for (i = 0; i < length; i++) + crc = __rtw_cal_crc16(pdata[i], crc); + + /* get 1' complement */ + return ~crc; +} + +static void rtw_wow_pattern_generate(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + const struct cfg80211_pkt_pattern *pkt_pattern, + struct rtw_wow_pattern *rtw_pattern) +{ + const u8 *mask; + const u8 *pattern; + u8 mask_hw[RTW_MAX_PATTERN_MASK_SIZE] = {0}; + u8 content[RTW_MAX_PATTERN_SIZE] = {0}; + u8 mac_addr[ETH_ALEN] = {0}; + u8 mask_len; + u16 count; + int len; + int i; + + pattern = pkt_pattern->pattern; + len = pkt_pattern->pattern_len; + mask = pkt_pattern->mask; + + ether_addr_copy(mac_addr, rtwvif->mac_addr); + memset(rtw_pattern, 0, sizeof(*rtw_pattern)); + + mask_len = DIV_ROUND_UP(len, 8); + + if (is_broadcast_ether_addr(pattern)) + rtw_pattern->type = RTW_PATTERN_BROADCAST; + else if (is_multicast_ether_addr(pattern)) + rtw_pattern->type = RTW_PATTERN_MULTICAST; + else if (ether_addr_equal(pattern, mac_addr)) + rtw_pattern->type = RTW_PATTERN_UNICAST; + else + rtw_pattern->type = RTW_PATTERN_INVALID; + + /* translate mask from os to mask for hw + * pattern from OS uses 'ethenet frame', like this: + * | 6 | 6 | 2 | 20 | Variable | 4 | + * |--------+--------+------+-----------+------------+-----| + * | 802.3 Mac Header | IP Header | TCP Packet | FCS | + * | DA | SA | Type | + * + * BUT, packet catched by our HW is in '802.11 frame', begin from LLC + * | 24 or 30 | 6 | 2 | 20 | Variable | 4 | + * |-------------------+--------+------+-----------+------------+-----| + * | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | + * | Others | Tpye | + * + * Therefore, we need translate mask_from_OS to mask_to_hw. + * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, + * because new mask[0~5] means 'SA', but our HW packet begins from LLC, + * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. + */ + + /* Shift 6 bits */ + for (i = 0; i < mask_len - 1; i++) { + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); + mask_hw[i] |= u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2; + } + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); + + /* Set bit 0-5 to zero */ + mask_hw[0] &= (~GENMASK(5, 0)); + + memcpy(rtw_pattern->mask, mask_hw, RTW_MAX_PATTERN_MASK_SIZE); + + /* To get the wake up pattern from the mask. + * We do not count first 12 bits which means + * DA[6] and SA[6] in the pattern to match HW design. + */ + count = 0; + for (i = 12; i < len; i++) { + if ((mask[i / 8] >> (i % 8)) & 0x01) { + content[count] = pattern[i]; + count++; + } + } + + rtw_pattern->crc = rtw_calc_crc(content, count); +} + +static void rtw_wow_pattern_clear_cam(struct rtw_dev *rtwdev) +{ + bool ret; + + rtw_write32(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | + BIT_WKFCAM_CLR_V1); + + ret = check_hw_ready(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1, 0); + if (!ret) + rtw_err(rtwdev, "failed to clean pattern cam\n"); +} + +static void rtw_wow_pattern_write(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_wow_pattern *rtw_pattern = rtw_wow->patterns; + int i = 0; + + for (i = 0; i < rtw_wow->pattern_cnt; i++) + rtw_wow_pattern_write_cam_ent(rtwdev, i, rtw_pattern + i); +} + +static void rtw_wow_pattern_clear(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + rtw_wow_pattern_clear_cam(rtwdev); + + rtw_wow->pattern_cnt = 0; + memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); +} + +static void rtw_wow_bb_stop(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + /* wait 100ms for firmware to finish TX */ + msleep(100); + + if (!rtw_read32_mask(rtwdev, REG_BCNQ_INFO, BIT_MGQ_CPU_EMPTY)) + rtw_warn(rtwdev, "Wrong status of MGQ_CPU empty!\n"); + + rtw_wow->txpause = rtw_read8(rtwdev, REG_TXPAUSE); + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); +} + +static void rtw_wow_bb_start(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); + rtw_write8(rtwdev, REG_TXPAUSE, rtw_wow->txpause); +} + +static void rtw_wow_rx_dma_stop(struct rtw_dev *rtwdev) +{ + /* wait 100ms for HW to finish rx dma */ + msleep(100); + + rtw_write32_set(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE); + + if (!check_hw_ready(rtwdev, REG_RXPKT_NUM, BIT_RXDMA_IDLE, 1)) + rtw_err(rtwdev, "failed to stop rx dma\n"); +} + +static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev) +{ + rtw_write32_clr(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE); +} + +static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable) +{ + int ret; + u8 check; + u32 check_dis; + + if (wow_enable) { + ret = read_poll_timeout(rtw_read8, check, !check, 1000, + 100000, true, rtwdev, + REG_WOWLAN_WAKE_REASON); + if (ret) + goto wow_fail; + } else { + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, true, rtwdev, + REG_FE1IMR, BIT_FS_RXDONE); + if (ret) + goto wow_fail; + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, false, rtwdev, + REG_RXPKT_NUM, BIT_RW_RELEASE); + if (ret) + goto wow_fail; + } + + return 0; + +wow_fail: + rtw_err(rtwdev, "failed to check wow status %s\n", + wow_enable ? "enabled" : "disabled"); + return -EBUSY; +} + +static void rtw_wow_fw_security_type_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw_fw_key_type_iter_data *iter_data = data; + struct rtw_dev *rtwdev = hw->priv; + u8 hw_key_type; + + if (vif != rtwdev->wow.wow_vif) + return; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + hw_key_type = RTW_CAM_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + hw_key_type = RTW_CAM_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + hw_key_type = RTW_CAM_TKIP; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + case WLAN_CIPHER_SUITE_CCMP: + hw_key_type = RTW_CAM_AES; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + default: + rtw_err(rtwdev, "Unsupported key type for wowlan mode: %#x\n", + key->cipher); + hw_key_type = 0; + break; + } + + if (sta) + iter_data->pairwise_key_type = hw_key_type; + else + iter_data->group_key_type = hw_key_type; +} + +static void rtw_wow_fw_security_type(struct rtw_dev *rtwdev) +{ + struct rtw_fw_key_type_iter_data data = {}; + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + + data.rtwdev = rtwdev; + rtw_iterate_keys(rtwdev, wow_vif, + rtw_wow_fw_security_type_iter, &data); + rtw_fw_set_aoac_global_info_cmd(rtwdev, data.pairwise_key_type, + data.group_key_type); +} + +static int rtw_wow_fw_start(struct rtw_dev *rtwdev) +{ + if (rtw_wow_mgd_linked(rtwdev)) { + rtw_send_rsvd_page_h2c(rtwdev); + rtw_wow_pattern_write(rtwdev); + rtw_wow_fw_security_type(rtwdev); + rtw_fw_set_disconnect_decision_cmd(rtwdev, true); + rtw_fw_set_keep_alive_cmd(rtwdev, true); + } else if (rtw_wow_no_link(rtwdev)) { + rtw_fw_set_nlo_info(rtwdev, true); + rtw_fw_update_pkt_probe_req(rtwdev, NULL); + rtw_fw_channel_switch(rtwdev, true); + } + + rtw_fw_set_wowlan_ctrl_cmd(rtwdev, true); + rtw_fw_set_remote_wake_ctrl_cmd(rtwdev, true); + + return rtw_wow_check_fw_status(rtwdev, true); +} + +static int rtw_wow_fw_stop(struct rtw_dev *rtwdev) +{ + if (rtw_wow_mgd_linked(rtwdev)) { + rtw_fw_set_disconnect_decision_cmd(rtwdev, false); + rtw_fw_set_keep_alive_cmd(rtwdev, false); + rtw_wow_pattern_clear(rtwdev); + } else if (rtw_wow_no_link(rtwdev)) { + rtw_fw_channel_switch(rtwdev, false); + rtw_fw_set_nlo_info(rtwdev, false); + } + + rtw_fw_set_wowlan_ctrl_cmd(rtwdev, false); + rtw_fw_set_remote_wake_ctrl_cmd(rtwdev, false); + + return rtw_wow_check_fw_status(rtwdev, false); +} + +static void rtw_wow_avoid_reset_mac(struct rtw_dev *rtwdev) +{ + /* When resuming from wowlan mode, some hosts issue signal + * (PCIE: PREST, USB: SE0RST) to device, and lead to reset + * mac core. If it happens, the connection to AP will be lost. + * Setting REG_RSV_CTRL Register can avoid this process. + */ + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + case RTW_HCI_TYPE_USB: + rtw_write8(rtwdev, REG_RSV_CTRL, BIT_WLOCK_1C_B6); + rtw_write8(rtwdev, REG_RSV_CTRL, + BIT_WLOCK_1C_B6 | BIT_R_DIS_PRST); + break; + default: + rtw_warn(rtwdev, "Unsupported hci type to disable reset MAC\n"); + break; + } +} + +static void rtw_wow_fw_media_status_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct rtw_fw_media_status_iter_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + + rtw_fw_media_status_report(rtwdev, si->mac_id, iter_data->connect); +} + +static void rtw_wow_fw_media_status(struct rtw_dev *rtwdev, bool connect) +{ + struct rtw_fw_media_status_iter_data data; + + data.rtwdev = rtwdev; + data.connect = connect; + + rtw_iterate_stas_atomic(rtwdev, rtw_wow_fw_media_status_iter, &data); +} + +static int rtw_wow_config_wow_fw_rsvd_page(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + rtw_remove_rsvd_page(rtwdev, rtwvif); + + if (rtw_wow_no_link(rtwdev)) + rtw_add_rsvd_page_pno(rtwdev, rtwvif); + else + rtw_add_rsvd_page_sta(rtwdev, rtwvif); + + return rtw_fw_download_rsvd_page(rtwdev); +} + +static int rtw_wow_config_normal_fw_rsvd_page(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + rtw_remove_rsvd_page(rtwdev, rtwvif); + rtw_add_rsvd_page_sta(rtwdev, rtwvif); + + if (rtw_wow_no_link(rtwdev)) + return 0; + + return rtw_fw_download_rsvd_page(rtwdev); +} + +static int rtw_wow_swap_fw(struct rtw_dev *rtwdev, enum rtw_fw_type type) +{ + struct rtw_fw_state *fw; + int ret; + + switch (type) { + case RTW_WOWLAN_FW: + fw = &rtwdev->wow_fw; + break; + + case RTW_NORMAL_FW: + fw = &rtwdev->fw; + break; + + default: + rtw_warn(rtwdev, "unsupported firmware type to swap\n"); + return -ENOENT; + } + + ret = rtw_download_firmware(rtwdev, fw); + if (ret) + goto out; + + rtw_fw_send_general_info(rtwdev); + rtw_fw_send_phydm_info(rtwdev); + rtw_wow_fw_media_status(rtwdev, true); + +out: + return ret; +} + +static void rtw_wow_check_pno(struct rtw_dev *rtwdev, + struct cfg80211_sched_scan_request *nd_config) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *pno_req = &rtw_wow->pno_req; + struct ieee80211_channel *channel; + int i, size; + + if (!nd_config->n_match_sets || !nd_config->n_channels) + goto err; + + pno_req->match_set_cnt = nd_config->n_match_sets; + size = sizeof(*pno_req->match_sets) * pno_req->match_set_cnt; + pno_req->match_sets = kmemdup(nd_config->match_sets, size, GFP_KERNEL); + if (!pno_req->match_sets) + goto err; + + pno_req->channel_cnt = nd_config->n_channels; + size = sizeof(*nd_config->channels[0]) * nd_config->n_channels; + pno_req->channels = kmalloc(size, GFP_KERNEL); + if (!pno_req->channels) + goto channel_err; + + for (i = 0 ; i < pno_req->channel_cnt; i++) { + channel = pno_req->channels + i; + memcpy(channel, nd_config->channels[i], sizeof(*channel)); + } + + pno_req->scan_plan = *nd_config->scan_plans; + pno_req->inited = true; + + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: net-detect is enabled\n"); + + return; + +channel_err: + kfree(pno_req->match_sets); + +err: + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: net-detect is disabled\n"); +} + +static int rtw_wow_leave_linked_ps(struct rtw_dev *rtwdev) +{ + if (!test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) + cancel_delayed_work_sync(&rtwdev->watch_dog_work); + + rtw_leave_lps(rtwdev); + + return 0; +} + +static int rtw_wow_leave_no_link_ps(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + int ret = 0; + + if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) { + if (rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE) + rtw_leave_lps_deep(rtwdev); + } else { + if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags)) { + rtw_wow->ips_enabled = true; + ret = rtw_leave_ips(rtwdev); + if (ret) + return ret; + } + } + + return 0; +} + +static int rtw_wow_leave_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_mgd_linked(rtwdev)) + ret = rtw_wow_leave_linked_ps(rtwdev); + else if (rtw_wow_no_link(rtwdev)) + ret = rtw_wow_leave_no_link_ps(rtwdev); + + return ret; +} + +static int rtw_wow_restore_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_no_link(rtwdev) && rtwdev->wow.ips_enabled) + ret = rtw_enter_ips(rtwdev); + + return ret; +} + +static int rtw_wow_enter_linked_ps(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + rtw_enter_lps(rtwdev, rtwvif->port); + + return 0; +} + +static int rtw_wow_enter_no_link_ps(struct rtw_dev *rtwdev) +{ + /* firmware enters deep ps by itself if supported */ + set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); + + return 0; +} + +static int rtw_wow_enter_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_mgd_linked(rtwdev)) + ret = rtw_wow_enter_linked_ps(rtwdev); + else if (rtw_wow_no_link(rtwdev) && + rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE) + ret = rtw_wow_enter_no_link_ps(rtwdev); + + return ret; +} + +static void rtw_wow_stop_trx(struct rtw_dev *rtwdev) +{ + rtw_wow_bb_stop(rtwdev); + rtw_wow_rx_dma_stop(rtwdev); +} + +static int rtw_wow_start(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtw_wow_fw_start(rtwdev); + if (ret) + goto out; + + rtw_hci_stop(rtwdev); + rtw_wow_bb_start(rtwdev); + rtw_wow_avoid_reset_mac(rtwdev); + +out: + return ret; +} + +static int rtw_wow_enable(struct rtw_dev *rtwdev) +{ + int ret = 0; + + rtw_wow_stop_trx(rtwdev); + + ret = rtw_wow_swap_fw(rtwdev, RTW_WOWLAN_FW); + if (ret) { + rtw_err(rtwdev, "failed to swap wow fw\n"); + goto error; + } + + set_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + + ret = rtw_wow_config_wow_fw_rsvd_page(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to download wowlan rsvd page\n"); + goto error; + } + + ret = rtw_wow_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start wow\n"); + goto error; + } + + return ret; + +error: + clear_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + return ret; +} + +static int rtw_wow_stop(struct rtw_dev *rtwdev) +{ + int ret; + + /* some HCI related registers will be reset after resume, + * need to set them again. + */ + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + return ret; + } + + ret = rtw_hci_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start hci\n"); + return ret; + } + + ret = rtw_wow_fw_stop(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to stop wowlan fw\n"); + + rtw_wow_bb_stop(rtwdev); + + return ret; +} + +static void rtw_wow_resume_trx(struct rtw_dev *rtwdev) +{ + rtw_wow_rx_dma_start(rtwdev); + rtw_wow_bb_start(rtwdev); + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, + RTW_WATCH_DOG_DELAY_TIME); +} + +static int rtw_wow_disable(struct rtw_dev *rtwdev) +{ + int ret; + + clear_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + + ret = rtw_wow_stop(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to stop wow\n"); + goto out; + } + + ret = rtw_wow_swap_fw(rtwdev, RTW_NORMAL_FW); + if (ret) { + rtw_err(rtwdev, "failed to swap normal fw\n"); + goto out; + } + + ret = rtw_wow_config_normal_fw_rsvd_page(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to download normal rsvd page\n"); + +out: + rtw_wow_resume_trx(rtwdev); + return ret; +} + +static void rtw_wow_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + /* Current wowlan function support setting of only one STATION vif. + * So when one suitable vif is found, stop the iteration. + */ + if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION) + return; + + switch (rtwvif->net_type) { + case RTW_NET_MGD_LINKED: + rtw_wow->wow_vif = vif; + break; + case RTW_NET_NO_LINK: + if (rtw_wow->pno_req.inited) + rtwdev->wow.wow_vif = vif; + break; + default: + break; + } +} + +static int rtw_wow_set_wakeups(struct rtw_dev *rtwdev, + struct cfg80211_wowlan *wowlan) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_wow_pattern *rtw_patterns = rtw_wow->patterns; + struct rtw_vif *rtwvif; + int i; + + if (wowlan->disconnect) + set_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); + if (wowlan->magic_pkt) + set_bit(RTW_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); + if (wowlan->gtk_rekey_failure) + set_bit(RTW_WOW_FLAG_EN_REKEY_PKT, rtw_wow->flags); + + if (wowlan->nd_config) + rtw_wow_check_pno(rtwdev, wowlan->nd_config); + + rtw_iterate_vifs_atomic(rtwdev, rtw_wow_vif_iter, rtwdev); + if (!rtw_wow->wow_vif) + return -EPERM; + + rtwvif = (struct rtw_vif *)rtw_wow->wow_vif->drv_priv; + if (wowlan->n_patterns && wowlan->patterns) { + rtw_wow->pattern_cnt = wowlan->n_patterns; + for (i = 0; i < wowlan->n_patterns; i++) + rtw_wow_pattern_generate(rtwdev, rtwvif, + wowlan->patterns + i, + rtw_patterns + i); + } + + return 0; +} + +static void rtw_wow_clear_wakeups(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *pno_req = &rtw_wow->pno_req; + + if (pno_req->inited) { + kfree(pno_req->channels); + kfree(pno_req->match_sets); + } + + memset(rtw_wow, 0, sizeof(rtwdev->wow)); +} + +int rtw_wow_suspend(struct rtw_dev *rtwdev, struct cfg80211_wowlan *wowlan) +{ + int ret = 0; + + ret = rtw_wow_set_wakeups(rtwdev, wowlan); + if (ret) { + rtw_err(rtwdev, "failed to set wakeup event\n"); + goto out; + } + + ret = rtw_wow_leave_ps(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave ps from normal mode\n"); + goto out; + } + + ret = rtw_wow_enable(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to enable wow\n"); + rtw_wow_restore_ps(rtwdev); + goto out; + } + + ret = rtw_wow_enter_ps(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to enter ps for wow\n"); + +out: + return ret; +} + +int rtw_wow_resume(struct rtw_dev *rtwdev) +{ + int ret; + + /* If wowlan mode is not enabled, do nothing */ + if (!test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) { + rtw_err(rtwdev, "wow is not enabled\n"); + ret = -EPERM; + goto out; + } + + ret = rtw_wow_leave_ps(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave ps from wowlan mode\n"); + goto out; + } + + rtw_wow_show_wakeup_reason(rtwdev); + + ret = rtw_wow_disable(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to disable wow\n"); + goto out; + } + + ret = rtw_wow_restore_ps(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to restore ps to normal mode\n"); + +out: + rtw_wow_clear_wakeups(rtwdev); + return ret; +} diff --git a/drivers/net/wireless/realtek/rtw88/wow.h b/drivers/net/wireless/realtek/rtw88/wow.h new file mode 100644 index 000000000..289368a2c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/wow.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_WOW_H__ +#define __RTW_WOW_H__ + +#define PNO_CHECK_BYTE 4 + +enum rtw_wow_pattern_type { + RTW_PATTERN_BROADCAST = 0, + RTW_PATTERN_MULTICAST, + RTW_PATTERN_UNICAST, + RTW_PATTERN_VALID, + RTW_PATTERN_INVALID, +}; + +enum rtw_wake_reason { + RTW_WOW_RSN_RX_PTK_REKEY = 0x1, + RTW_WOW_RSN_RX_GTK_REKEY = 0x2, + RTW_WOW_RSN_RX_DEAUTH = 0x8, + RTW_WOW_RSN_DISCONNECT = 0x10, + RTW_WOW_RSN_RX_MAGIC_PKT = 0x21, + RTW_WOW_RSN_RX_PATTERN_MATCH = 0x23, + RTW_WOW_RSN_RX_NLO = 0x55, +}; + +struct rtw_fw_media_status_iter_data { + struct rtw_dev *rtwdev; + u8 connect; +}; + +struct rtw_fw_key_type_iter_data { + struct rtw_dev *rtwdev; + u8 group_key_type; + u8 pairwise_key_type; +}; + +static inline bool rtw_wow_mgd_linked(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + return (rtwvif->net_type == RTW_NET_MGD_LINKED); +} + +static inline bool rtw_wow_no_link(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + return (rtwvif->net_type == RTW_NET_NO_LINK); +} + +int rtw_wow_suspend(struct rtw_dev *rtwdev, struct cfg80211_wowlan *wowlan); +int rtw_wow_resume(struct rtw_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig new file mode 100644 index 000000000..7c678dd1f --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/Kconfig @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +menuconfig RTW89 + tristate "Realtek 802.11ax wireless chips support" + depends on MAC80211 + help + This module adds support for mac80211-based wireless drivers that + enables Realtek IEEE 802.11ax wireless chipsets. + + If you choose to build a module, it'll be called rtw89. + +if RTW89 + +config RTW89_CORE + tristate + select WANT_DEV_COREDUMP + +config RTW89_PCI + tristate + +config RTW89_USB + tristate + +config RTW89_8851B + tristate + +config RTW89_8852A + tristate + +config RTW89_8852B_COMMON + tristate + +config RTW89_8852B + tristate + +config RTW89_8852BT + tristate + +config RTW89_8852C + tristate + +config RTW89_8922A + tristate + +config RTW89_8922D + tristate + +config RTW89_8851BE + tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8851B + help + Select this option will enable support for 8851BE chipset + + 802.11ax PCIe wireless network (Wi-Fi 6) adapter + +config RTW89_8851BU + tristate "Realtek 8851BU USB wireless network (Wi-Fi 6) adapter" + depends on USB + select RTW89_CORE + select RTW89_USB + select RTW89_8851B + help + Select this option will enable support for 8851BU chipset + + 802.11ax USB wireless network (Wi-Fi 6) adapter + +config RTW89_8852AE + tristate "Realtek 8852AE PCI wireless network (Wi-Fi 6) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8852A + help + Select this option will enable support for 8852AE chipset + + 802.11ax PCIe wireless network (Wi-Fi 6) adapter + +config RTW89_8852AU + tristate "Realtek 8852AU USB wireless network (Wi-Fi 6) adapter" + depends on USB + select RTW89_CORE + select RTW89_USB + select RTW89_8852A + help + Select this option will enable support for 8852AU chipset + + 802.11ax USB wireless network (Wi-Fi 6) adapter + +config RTW89_8852BE + tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8852B + select RTW89_8852B_COMMON + help + Select this option will enable support for 8852BE chipset + + 802.11ax PCIe wireless network (Wi-Fi 6) adapter + +config RTW89_8852BU + tristate "Realtek 8852BU USB wireless network (Wi-Fi 6) adapter" + depends on USB + select RTW89_CORE + select RTW89_USB + select RTW89_8852B + select RTW89_8852B_COMMON + help + Select this option will enable support for 8852BU chipset + + 802.11ax USB wireless network (Wi-Fi 6) adapter + +config RTW89_8852BTE + tristate "Realtek 8852BE-VT PCI wireless network (Wi-Fi 6) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8852BT + select RTW89_8852B_COMMON + help + Select this option will enable support for 8852BE-VT chipset + + 802.11ax PCIe wireless network (Wi-Fi 6) adapter + +config RTW89_8852CE + tristate "Realtek 8852CE PCI wireless network (Wi-Fi 6E) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8852C + help + Select this option will enable support for 8852CE chipset + + 802.11ax PCIe wireless network (Wi-Fi 6E) adapter + +config RTW89_8852CU + tristate "Realtek 8852CU USB wireless network (Wi-Fi 6E) adapter" + depends on USB + select RTW89_CORE + select RTW89_USB + select RTW89_8852C + help + Select this option will enable support for 8852CU chipset + + 802.11ax USB wireless network (Wi-Fi 6E) adapter + +config RTW89_8922AE + tristate "Realtek 8922AE/8922AE-VS PCI wireless network (Wi-Fi 7) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8922A + help + Select this option will enable support for 8922AE/8922AE-VS chipset + + 802.11be PCIe wireless network (Wi-Fi 7) adapter + supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels. + + The variant 8922AE-VS has the same features except 1024-QAM. + +config RTW89_8922AU + tristate "Realtek 8922AU USB wireless network (Wi-Fi 7) adapter" + depends on USB + select RTW89_CORE + select RTW89_USB + select RTW89_8922A + help + Select this option will enable support for 8922AU chipset + + 802.11be USB wireless network (Wi-Fi 7) adapter + supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels. + +config RTW89_8922DE + tristate "Realtek 8922DE/8922DE-VS PCI wireless network (Wi-Fi 7) adapter" + depends on PCI + select RTW89_CORE + select RTW89_PCI + select RTW89_8922D + help + Select this option will enable support for 8922DE/8922DE-VS chipset + + 802.11be PCIe wireless network (Wi-Fi 7) adapter + supporting 2x2 2GHz/5GHz/6GHz 4096/1024-QAM 160MHz channels. + +config RTW89_DEBUG + bool + +config RTW89_DEBUGMSG + bool "Realtek rtw89 debug message support" + depends on RTW89_CORE + select RTW89_DEBUG + help + Enable debug message support + + If unsure, say Y to simplify debug problems + +config RTW89_DEBUGFS + bool "Realtek rtw89 debugfs support" + depends on RTW89_CORE && CFG80211_DEBUGFS + select RTW89_DEBUG + help + Enable debugfs support + + If unsure, say Y to simplify debug problems + +config RTW89_LEDS + bool + depends on RTW89_CORE + depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211 + imply MAC80211_LEDS + default y + +config RTW89_LEDS_MC + bool + depends on RTW89_LEDS + depends on LEDS_CLASS_MULTICOLOR + imply LEDS_TRIGGER_TIMER + default y + +endif diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile new file mode 100644 index 000000000..a85b77853 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/Makefile @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +obj-$(CONFIG_RTW89_CORE) += rtw89_core.o +rtw89_core-y += core.o \ + mac80211.o \ + mac.o \ + mac_be.o \ + phy.o \ + phy_be.o \ + fw.o \ + cam.o \ + efuse.o \ + efuse_be.o \ + regd.o \ + sar.o \ + coex.o \ + ps.o \ + chan.o \ + ser.o \ + acpi.o \ + util.o + +rtw89_core-$(CONFIG_PM) += wow.o + +obj-$(CONFIG_RTW89_8851B) += rtw89_8851b.o +rtw89_8851b-objs := rtw8851b.o \ + rtw8851b_table.o \ + rtw8851b_rfk.o \ + rtw8851b_rfk_table.o + +obj-$(CONFIG_RTW89_8851BE) += rtw89_8851be.o +rtw89_8851be-objs := rtw8851be.o + +obj-$(CONFIG_RTW89_8851BU) += rtw89_8851bu.o +rtw89_8851bu-objs := rtw8851bu.o + +obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o +rtw89_8852a-objs := rtw8852a.o \ + rtw8852a_table.o \ + rtw8852a_rfk.o \ + rtw8852a_rfk_table.o + +obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o +rtw89_8852ae-objs := rtw8852ae.o + +obj-$(CONFIG_RTW89_8852AU) += rtw89_8852au.o +rtw89_8852au-objs := rtw8852au.o + +obj-$(CONFIG_RTW89_8852B_COMMON) += rtw89_8852b_common.o +rtw89_8852b_common-objs := rtw8852b_common.o + +obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o +rtw89_8852b-objs := rtw8852b.o \ + rtw8852b_table.o \ + rtw8852b_rfk.o \ + rtw8852b_rfk_table.o + +obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o +rtw89_8852be-objs := rtw8852be.o + +obj-$(CONFIG_RTW89_8852BU) += rtw89_8852bu.o +rtw89_8852bu-objs := rtw8852bu.o + +obj-$(CONFIG_RTW89_8852BT) += rtw89_8852bt.o +rtw89_8852bt-objs := rtw8852bt.o \ + rtw8852bt_rfk.o \ + rtw8852bt_rfk_table.o + +obj-$(CONFIG_RTW89_8852BTE) += rtw89_8852bte.o +rtw89_8852bte-objs := rtw8852bte.o + +obj-$(CONFIG_RTW89_8852C) += rtw89_8852c.o +rtw89_8852c-objs := rtw8852c.o \ + rtw8852c_table.o \ + rtw8852c_rfk.o \ + rtw8852c_rfk_table.o + +obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o +rtw89_8852ce-objs := rtw8852ce.o + +obj-$(CONFIG_RTW89_8852CU) += rtw89_8852cu.o +rtw89_8852cu-objs := rtw8852cu.o + +obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o +rtw89_8922a-objs := rtw8922a.o \ + rtw8922a_rfk.o + +obj-$(CONFIG_RTW89_8922AE) += rtw89_8922ae.o +rtw89_8922ae-objs := rtw8922ae.o + +obj-$(CONFIG_RTW89_8922AU) += rtw89_8922au.o +rtw89_8922au-objs := rtw8922au.o + +obj-$(CONFIG_RTW89_8922D) += rtw89_8922d.o +rtw89_8922d-objs := rtw8922d.o \ + rtw8922d_rfk.o + +obj-$(CONFIG_RTW89_8922DE) += rtw89_8922de.o +rtw89_8922de-objs := rtw8922de.o + +rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o +rtw89_core-$(CONFIG_RTW89_LEDS) += led.o +rtw89_core-$(CONFIG_RTW89_LEDS_MC) += led_mc.o + +obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o +rtw89_pci-y := pci.o pci_be.o + +obj-$(CONFIG_RTW89_USB) += rtw89_usb.o +rtw89_usb-y := usb.o + diff --git a/drivers/net/wireless/realtek/rtw89/acpi.c b/drivers/net/wireless/realtek/rtw89/acpi.c new file mode 100644 index 000000000..ebb6cf555 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/acpi.c @@ -0,0 +1,1281 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2021-2023 Realtek Corporation + */ + +#include +#include + +#include "acpi.h" +#include "debug.h" + +static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00, + 0x82, 0xBD, 0xFE, 0x86, + 0x07, 0x80, 0x3A, 0xA7); + +static u32 rtw89_acpi_traversal_object(struct rtw89_dev *rtwdev, + const union acpi_object *obj, u8 *pos) +{ + const union acpi_object *elm; + unsigned int i; + u32 sub_len; + u32 len = 0; + u8 *tmp; + + switch (obj->type) { + case ACPI_TYPE_INTEGER: + if (pos) + pos[len] = obj->integer.value; + + len++; + break; + case ACPI_TYPE_BUFFER: + if (unlikely(obj->buffer.length == 0)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "%s: invalid buffer type\n", __func__); + goto err; + } + + if (pos) + memcpy(pos, obj->buffer.pointer, obj->buffer.length); + + len += obj->buffer.length; + break; + case ACPI_TYPE_PACKAGE: + if (unlikely(obj->package.count == 0)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "%s: invalid package type\n", __func__); + goto err; + } + + for (i = 0; i < obj->package.count; i++) { + elm = &obj->package.elements[i]; + tmp = pos ? pos + len : NULL; + + sub_len = rtw89_acpi_traversal_object(rtwdev, elm, tmp); + if (unlikely(sub_len == 0)) + goto err; + + len += sub_len; + } + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: unhandled type: %d\n", + __func__, obj->type); + goto err; + } + + return len; + +err: + return 0; +} + +static u32 rtw89_acpi_calculate_object_length(struct rtw89_dev *rtwdev, + const union acpi_object *obj) +{ + return rtw89_acpi_traversal_object(rtwdev, obj, NULL); +} + +static struct rtw89_acpi_data * +rtw89_acpi_evaluate_method(struct rtw89_dev *rtwdev, const char *method) +{ + struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; + struct rtw89_acpi_data *data = NULL; + acpi_handle root, handle; + union acpi_object *obj; + acpi_status status; + u32 len; + + root = ACPI_HANDLE(rtwdev->dev); + if (!root) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi (%s): failed to get root\n", method); + return NULL; + } + + status = acpi_get_handle(root, (acpi_string)method, &handle); + if (ACPI_FAILURE(status)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi (%s): failed to get handle\n", method); + return NULL; + } + + status = acpi_evaluate_object(handle, NULL, NULL, &buf); + if (ACPI_FAILURE(status)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi (%s): failed to evaluate object\n", method); + return NULL; + } + + obj = buf.pointer; + len = rtw89_acpi_calculate_object_length(rtwdev, obj); + if (unlikely(len == 0)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi (%s): failed to traversal obj len\n", method); + goto out; + } + + data = kzalloc_flex(*data, buf, len); + if (!data) + goto out; + + data->len = len; + rtw89_acpi_traversal_object(rtwdev, obj, data->buf); + +out: + ACPI_FREE(obj); + return data; +} + +static +int rtw89_acpi_dsm_get_value(struct rtw89_dev *rtwdev, union acpi_object *obj, + u8 *value) +{ + if (obj->type != ACPI_TYPE_INTEGER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect integer but type: %d\n", obj->type); + return -EINVAL; + } + + *value = (u8)obj->integer.value; + return 0; +} + +static bool chk_acpi_policy_6ghz_sig(const struct rtw89_acpi_policy_6ghz *p) +{ + return p->signature[0] == 0x00 && + p->signature[1] == 0xE0 && + p->signature[2] == 0x4C; +} + +static +int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_6ghz **policy_6ghz) +{ + const struct rtw89_acpi_policy_6ghz *ptr; + u32 expect_len; + u32 len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + len = obj->buffer.length; + if (len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_6ghz_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + expect_len = struct_size(ptr, country_list, ptr->country_count); + if (len < expect_len) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: expect %u but length: %u\n", + __func__, expect_len, len); + return -EINVAL; + } + + *policy_6ghz = kmemdup(ptr, expect_len, GFP_KERNEL); + if (!*policy_6ghz) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz: ", *policy_6ghz, + expect_len); + return 0; +} + +static bool chk_acpi_policy_6ghz_sp_sig(const struct rtw89_acpi_policy_6ghz_sp *p) +{ + return p->signature[0] == 0x52 && + p->signature[1] == 0x54 && + p->signature[2] == 0x4B && + p->signature[3] == 0x07; +} + +static +int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_6ghz_sp **policy) +{ + const struct rtw89_acpi_policy_6ghz_sp *ptr; + u32 buf_len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + buf_len = obj->buffer.length; + if (buf_len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_6ghz_sp_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL); + if (!*policy) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_sp: ", *policy, + sizeof(*ptr)); + return 0; +} + +static bool chk_acpi_policy_6ghz_vlp_sig(const struct rtw89_acpi_policy_6ghz_vlp *p) +{ + return p->signature[0] == 0x52 && + p->signature[1] == 0x54 && + p->signature[2] == 0x4B && + p->signature[3] == 0x0B; +} + +static +int rtw89_acpi_dsm_get_policy_6ghz_vlp(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_6ghz_vlp **policy) +{ + const struct rtw89_acpi_policy_6ghz_vlp *ptr; + u32 buf_len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + buf_len = obj->buffer.length; + if (buf_len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_6ghz_vlp_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL); + if (!*policy) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_vlp: ", *policy, + sizeof(*ptr)); + return 0; +} + +static bool chk_acpi_policy_tas_sig(const struct rtw89_acpi_policy_tas *p) +{ + return p->signature[0] == 0x52 && + p->signature[1] == 0x54 && + p->signature[2] == 0x4B && + p->signature[3] == 0x05; +} + +static int rtw89_acpi_dsm_get_policy_tas(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_tas **policy) +{ + const struct rtw89_acpi_policy_tas *ptr; + u32 buf_len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + buf_len = obj->buffer.length; + if (buf_len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_tas_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL); + if (!*policy) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_tas: ", *policy, + sizeof(*ptr)); + return 0; +} + +static +bool chk_acpi_policy_reg_rules_sig(const struct rtw89_acpi_policy_reg_rules *p) +{ + return p->signature[0] == 0x52 && + p->signature[1] == 0x54 && + p->signature[2] == 0x4B && + p->signature[3] == 0x0A; +} + +static +int rtw89_acpi_dsm_get_policy_reg_rules(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_reg_rules **policy) +{ + const struct rtw89_acpi_policy_reg_rules *ptr; + u32 buf_len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + buf_len = obj->buffer.length; + if (buf_len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_reg_rules_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL); + if (!*policy) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_reg_rules: ", *policy, + sizeof(*ptr)); + return 0; +} + +int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, + enum rtw89_acpi_dsm_func func, + struct rtw89_acpi_dsm_result *res) +{ + union acpi_object *obj; + int ret; + + obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid, + 0, func, NULL); + if (!obj) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi dsm fail to evaluate func: %d\n", func); + return -ENOENT; + } + + if (func == RTW89_ACPI_DSM_FUNC_6G_BP) + ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj, + &res->u.policy_6ghz); + else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP) + ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj, + &res->u.policy_6ghz_sp); + else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP) + ret = rtw89_acpi_dsm_get_policy_6ghz_vlp(rtwdev, obj, + &res->u.policy_6ghz_vlp); + else if (func == RTW89_ACPI_DSM_FUNC_TAS_EN) + ret = rtw89_acpi_dsm_get_policy_tas(rtwdev, obj, &res->u.policy_tas); + else if (func == RTW89_ACPI_DSM_FUNC_REG_RULES_EN) + ret = rtw89_acpi_dsm_get_policy_reg_rules(rtwdev, obj, + &res->u.policy_reg_rules); + else + ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value); + + ACPI_FREE(obj); + return ret; +} + +int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev, + struct rtw89_acpi_rtag_result *res) +{ + const struct rtw89_acpi_data *data; + u32 buf_len; + int ret = 0; + + data = rtw89_acpi_evaluate_method(rtwdev, "RTAG"); + if (!data) + return -EIO; + + buf_len = data->len; + if (buf_len != sizeof(*res)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + ret = -EINVAL; + goto out; + } + + *res = *(struct rtw89_acpi_rtag_result *)data->buf; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "antenna_gain: ", res, sizeof(*res)); + +out: + kfree(data); + return ret; +} + +enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev, + u32 center_freq) +{ + switch (center_freq) { + default: + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "center freq %u to ACPI SAR subband is unhandled\n", + center_freq); + fallthrough; + case 2412 ... 2484: + return RTW89_ACPI_SAR_2GHZ_SUBBAND; + case 5180 ... 5240: + return RTW89_ACPI_SAR_5GHZ_SUBBAND_1; + case 5250 ... 5320: + return RTW89_ACPI_SAR_5GHZ_SUBBAND_2; + case 5500 ... 5720: + return RTW89_ACPI_SAR_5GHZ_SUBBAND_2E; + case 5745 ... 5885: + return RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4; + case 5955 ... 6155: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L; + case 6175 ... 6415: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H; + case 6435 ... 6515: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_6; + case 6535 ... 6695: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L; + case 6715 ... 6855: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H; + + /* freq 6875 (ch 185, 20MHz) spans RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H + * and RTW89_ACPI_SAR_6GHZ_SUBBAND_8, so directly describe it with + * struct rtw89_6ghz_span. + */ + + case 6895 ... 7115: + return RTW89_ACPI_SAR_6GHZ_SUBBAND_8; + } +} + +enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev, + enum rtw89_acpi_sar_subband subband) +{ + switch (subband) { + default: + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "ACPI SAR subband %u to band is unhandled\n", subband); + fallthrough; + case RTW89_ACPI_SAR_2GHZ_SUBBAND: + return RTW89_BAND_2G; + case RTW89_ACPI_SAR_5GHZ_SUBBAND_1: + return RTW89_BAND_5G; + case RTW89_ACPI_SAR_5GHZ_SUBBAND_2: + return RTW89_BAND_5G; + case RTW89_ACPI_SAR_5GHZ_SUBBAND_2E: + return RTW89_BAND_5G; + case RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4: + return RTW89_BAND_5G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L: + return RTW89_BAND_6G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H: + return RTW89_BAND_6G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_6: + return RTW89_BAND_6G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L: + return RTW89_BAND_6G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H: + return RTW89_BAND_6G; + case RTW89_ACPI_SAR_6GHZ_SUBBAND_8: + return RTW89_BAND_6G; + } +} + +static u8 rtw89_acpi_sar_rfpath_to_hp_antidx(enum rtw89_rf_path rfpath) +{ + switch (rfpath) { + default: + case RF_PATH_B: + return 0; + case RF_PATH_A: + return 1; + } +} + +static u8 rtw89_acpi_sar_rfpath_to_rt_antidx(enum rtw89_rf_path rfpath) +{ + switch (rfpath) { + default: + case RF_PATH_A: + return 0; + case RF_PATH_B: + return 1; + } +} + +static s16 rtw89_acpi_sar_normalize_hp_val(u8 v) +{ + static const u8 bias = 10; + static const u8 fct = 1; + u16 res; + + BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR); + + res = (bias << TXPWR_FACTOR_OF_RTW89_ACPI_SAR) + + (v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct)); + + return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR); +} + +static s16 rtw89_acpi_sar_normalize_rt_val(u8 v) +{ + static const u8 fct = 3; + u16 res; + + BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR); + + res = v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct); + + return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR); +} + +static +void rtw89_acpi_sar_load_std_legacy(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_recognition *rec, + const void *content, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_sar_std_legacy *ptr = content; + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) { + u8 antidx = rec->rfpath_to_antidx(path); + + if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY) + ent->v[subband][path] = + rec->normalize(ptr->v[antidx][subband]); + else + ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR; + } + } +} + +static +void rtw89_acpi_sar_load_std_has_6ghz(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_recognition *rec, + const void *content, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_sar_std_has_6ghz *ptr = content; + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + + BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND); + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) { + u8 antidx = rec->rfpath_to_antidx(path); + + ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]); + } + } +} + +static +void rtw89_acpi_sar_load_sml_legacy(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_recognition *rec, + const void *content, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_sar_sml_legacy *ptr = content; + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) { + u8 antidx = rec->rfpath_to_antidx(path); + + if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY) + ent->v[subband][path] = + rec->normalize(ptr->v[antidx][subband]); + else + ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR; + } + } +} + +static +void rtw89_acpi_sar_load_sml_has_6ghz(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_recognition *rec, + const void *content, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_sar_sml_has_6ghz *ptr = content; + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + + BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND); + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) { + u8 antidx = rec->rfpath_to_antidx(path); + + ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]); + } + } +} + +static s16 rtw89_acpi_geo_sar_normalize_delta(s8 delta) +{ + static const u8 fct = 1; + + BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR); + + return delta << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct); +} + +static enum rtw89_acpi_geo_sar_regd_hp +rtw89_acpi_geo_sar_regd_convert_hp_idx(enum rtw89_regulation_type regd) +{ + switch (regd) { + case RTW89_FCC: + case RTW89_IC: + case RTW89_NCC: + case RTW89_CHILE: + case RTW89_MEXICO: + return RTW89_ACPI_GEO_SAR_REGD_HP_FCC; + case RTW89_ETSI: + case RTW89_MKK: + case RTW89_ACMA: + return RTW89_ACPI_GEO_SAR_REGD_HP_ETSI; + default: + case RTW89_WW: + case RTW89_NA: + case RTW89_KCC: + return RTW89_ACPI_GEO_SAR_REGD_HP_WW; + } +} + +static enum rtw89_acpi_geo_sar_regd_rt +rtw89_acpi_geo_sar_regd_convert_rt_idx(enum rtw89_regulation_type regd) +{ + switch (regd) { + case RTW89_FCC: + case RTW89_NCC: + case RTW89_CHILE: + case RTW89_MEXICO: + return RTW89_ACPI_GEO_SAR_REGD_RT_FCC; + case RTW89_ETSI: + case RTW89_ACMA: + return RTW89_ACPI_GEO_SAR_REGD_RT_ETSI; + case RTW89_MKK: + return RTW89_ACPI_GEO_SAR_REGD_RT_MKK; + case RTW89_IC: + return RTW89_ACPI_GEO_SAR_REGD_RT_IC; + case RTW89_KCC: + return RTW89_ACPI_GEO_SAR_REGD_RT_KCC; + default: + case RTW89_WW: + case RTW89_NA: + return RTW89_ACPI_GEO_SAR_REGD_RT_WW; + } +} + +static +void rtw89_acpi_geo_sar_load_by_hp(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_geo_sar_hp_val *ptr, + enum rtw89_rf_path path, s16 *val) +{ + u8 antidx = rtw89_acpi_sar_rfpath_to_hp_antidx(path); + s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta[antidx]); + s16 max = rtw89_acpi_sar_normalize_hp_val(ptr->max); + + *val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max); +} + +static +void rtw89_acpi_geo_sar_load_by_rt(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_geo_sar_rt_val *ptr, + s16 *val) +{ + s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta); + s16 max = rtw89_acpi_sar_normalize_rt_val(ptr->max); + + *val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max); +} + +static +void rtw89_acpi_geo_sar_load_hp_legacy(struct rtw89_dev *rtwdev, + const void *content, + enum rtw89_regulation_type regd, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_geo_sar_hp_legacy *ptr = content; + const struct rtw89_acpi_geo_sar_hp_legacy_entry *ptr_ent; + const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val; + enum rtw89_acpi_geo_sar_regd_hp geo_idx = + rtw89_acpi_geo_sar_regd_convert_hp_idx(regd); + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + enum rtw89_band band; + + ptr_ent = &ptr->entries[geo_idx]; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + band = rtw89_acpi_sar_subband_to_band(rtwdev, subband); + switch (band) { + case RTW89_BAND_2G: + ptr_ent_val = &ptr_ent->val_2ghz; + break; + case RTW89_BAND_5G: + ptr_ent_val = &ptr_ent->val_5ghz; + break; + default: + case RTW89_BAND_6G: + ptr_ent_val = NULL; + break; + } + + if (!ptr_ent_val) + continue; + + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) + rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path, + &ent->v[subband][path]); + } +} + +static +void rtw89_acpi_geo_sar_load_hp_has_6ghz(struct rtw89_dev *rtwdev, + const void *content, + enum rtw89_regulation_type regd, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_geo_sar_hp_has_6ghz *ptr = content; + const struct rtw89_acpi_geo_sar_hp_has_6ghz_entry *ptr_ent; + const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val; + enum rtw89_acpi_geo_sar_regd_hp geo_idx = + rtw89_acpi_geo_sar_regd_convert_hp_idx(regd); + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + enum rtw89_band band; + + ptr_ent = &ptr->entries[geo_idx]; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + band = rtw89_acpi_sar_subband_to_band(rtwdev, subband); + switch (band) { + case RTW89_BAND_2G: + ptr_ent_val = &ptr_ent->val_2ghz; + break; + case RTW89_BAND_5G: + ptr_ent_val = &ptr_ent->val_5ghz; + break; + case RTW89_BAND_6G: + ptr_ent_val = &ptr_ent->val_6ghz; + break; + default: + ptr_ent_val = NULL; + break; + } + + if (!ptr_ent_val) + continue; + + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) + rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path, + &ent->v[subband][path]); + } +} + +static +void rtw89_acpi_geo_sar_load_rt_legacy(struct rtw89_dev *rtwdev, + const void *content, + enum rtw89_regulation_type regd, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_geo_sar_rt_legacy *ptr = content; + const struct rtw89_acpi_geo_sar_rt_legacy_entry *ptr_ent; + const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val; + enum rtw89_acpi_geo_sar_regd_rt geo_idx = + rtw89_acpi_geo_sar_regd_convert_rt_idx(regd); + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + enum rtw89_band band; + + ptr_ent = &ptr->entries[geo_idx]; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + band = rtw89_acpi_sar_subband_to_band(rtwdev, subband); + switch (band) { + case RTW89_BAND_2G: + ptr_ent_val = &ptr_ent->val_2ghz; + break; + case RTW89_BAND_5G: + ptr_ent_val = &ptr_ent->val_5ghz; + break; + default: + case RTW89_BAND_6G: + ptr_ent_val = NULL; + break; + } + + if (!ptr_ent_val) + continue; + + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) + rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val, + &ent->v[subband][path]); + } +} + +static +void rtw89_acpi_geo_sar_load_rt_has_6ghz(struct rtw89_dev *rtwdev, + const void *content, + enum rtw89_regulation_type regd, + struct rtw89_sar_entry_from_acpi *ent) +{ + const struct rtw89_acpi_geo_sar_rt_has_6ghz *ptr = content; + const struct rtw89_acpi_geo_sar_rt_has_6ghz_entry *ptr_ent; + const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val; + enum rtw89_acpi_geo_sar_regd_rt geo_idx = + rtw89_acpi_geo_sar_regd_convert_rt_idx(regd); + enum rtw89_acpi_sar_subband subband; + enum rtw89_rf_path path; + enum rtw89_band band; + + ptr_ent = &ptr->entries[geo_idx]; + + for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) { + band = rtw89_acpi_sar_subband_to_band(rtwdev, subband); + switch (band) { + case RTW89_BAND_2G: + ptr_ent_val = &ptr_ent->val_2ghz; + break; + case RTW89_BAND_5G: + ptr_ent_val = &ptr_ent->val_5ghz; + break; + case RTW89_BAND_6G: + ptr_ent_val = &ptr_ent->val_6ghz; + break; + default: + ptr_ent_val = NULL; + break; + } + + if (!ptr_ent_val) + continue; + + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) + rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val, + &ent->v[subband][path]); + } +} + +#define RTW89_ACPI_GEO_SAR_DECL_HANDLER(type) \ +static const struct rtw89_acpi_geo_sar_handler \ +rtw89_acpi_geo_sar_handler_ ## type = { \ + .data_size = RTW89_ACPI_GEO_SAR_SIZE_OF(type), \ + .load = rtw89_acpi_geo_sar_load_ ## type, \ +} + +RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_legacy); +RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_has_6ghz); +RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_legacy); +RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_has_6ghz); + +static const struct rtw89_acpi_sar_recognition rtw89_acpi_sar_recs[] = { + { + .id = { + .cid = RTW89_ACPI_SAR_CID_HP, + .rev = RTW89_ACPI_SAR_REV_LEGACY, + .size = RTW89_ACPI_SAR_SIZE_OF(std_legacy), + }, + .geo = &rtw89_acpi_geo_sar_handler_hp_legacy, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx, + .normalize = rtw89_acpi_sar_normalize_hp_val, + .load = rtw89_acpi_sar_load_std_legacy, + }, + { + .id = { + .cid = RTW89_ACPI_SAR_CID_HP, + .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ, + .size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz), + }, + .geo = &rtw89_acpi_geo_sar_handler_hp_has_6ghz, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx, + .normalize = rtw89_acpi_sar_normalize_hp_val, + .load = rtw89_acpi_sar_load_std_has_6ghz, + }, + { + .id = { + .cid = RTW89_ACPI_SAR_CID_RT, + .rev = RTW89_ACPI_SAR_REV_LEGACY, + .size = RTW89_ACPI_SAR_SIZE_OF(std_legacy), + }, + .geo = &rtw89_acpi_geo_sar_handler_rt_legacy, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx, + .normalize = rtw89_acpi_sar_normalize_rt_val, + .load = rtw89_acpi_sar_load_std_legacy, + }, + { + .id = { + .cid = RTW89_ACPI_SAR_CID_RT, + .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ, + .size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz), + }, + .geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx, + .normalize = rtw89_acpi_sar_normalize_rt_val, + .load = rtw89_acpi_sar_load_std_has_6ghz, + }, + { + .id = { + .cid = RTW89_ACPI_SAR_CID_RT, + .rev = RTW89_ACPI_SAR_REV_LEGACY, + .size = RTW89_ACPI_SAR_SIZE_OF(sml_legacy), + }, + .geo = &rtw89_acpi_geo_sar_handler_rt_legacy, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx, + .normalize = rtw89_acpi_sar_normalize_rt_val, + .load = rtw89_acpi_sar_load_sml_legacy, + }, + { + .id = { + .cid = RTW89_ACPI_SAR_CID_RT, + .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ, + .size = RTW89_ACPI_SAR_SIZE_OF(sml_has_6ghz), + }, + .geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz, + + .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx, + .normalize = rtw89_acpi_sar_normalize_rt_val, + .load = rtw89_acpi_sar_load_sml_has_6ghz, + }, +}; + +struct rtw89_acpi_sar_rec_parm { + u32 pld_len; + u8 tbl_cnt; + u16 cid; + u8 rev; +}; + +static const struct rtw89_acpi_sar_recognition * +rtw89_acpi_sar_recognize(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_rec_parm *parm) +{ + const u32 tbl_len = parm->pld_len / parm->tbl_cnt; + const struct rtw89_acpi_sar_recognition *rec; + struct rtw89_acpi_sar_identifier id = {}; + + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "%s: cid %u, rev %u, tbl len %u, tbl cnt %u\n", + __func__, parm->cid, parm->rev, tbl_len, parm->tbl_cnt); + + if (unlikely(parm->pld_len % parm->tbl_cnt)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid pld len %u\n", + parm->pld_len); + return NULL; + } + + if (unlikely(tbl_len > RTW89_ACPI_SAR_SIZE_MAX)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl len %u\n", + tbl_len); + return NULL; + } + + if (unlikely(parm->tbl_cnt > MAX_NUM_OF_RTW89_ACPI_SAR_TBL)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl cnt %u\n", + parm->tbl_cnt); + return NULL; + } + + switch (parm->cid) { + case RTW89_ACPI_SAR_CID_HP: + case RTW89_ACPI_SAR_CID_RT: + id.cid = parm->cid; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid cid 0x%x\n", + parm->cid); + return NULL; + } + + switch (parm->rev) { + case RTW89_ACPI_SAR_REV_LEGACY: + case RTW89_ACPI_SAR_REV_HAS_6GHZ: + id.rev = parm->rev; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid rev %u\n", + parm->rev); + return NULL; + } + + id.size = tbl_len; + for (unsigned int i = 0; i < ARRAY_SIZE(rtw89_acpi_sar_recs); i++) { + rec = &rtw89_acpi_sar_recs[i]; + if (memcmp(&rec->id, &id, sizeof(rec->id)) == 0) + return rec; + } + + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "failed to recognize\n"); + return NULL; +} + +static const struct rtw89_acpi_sar_recognition * +rtw89_acpi_evaluate_static_sar(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg) +{ + const struct rtw89_acpi_sar_recognition *rec = NULL; + const struct rtw89_acpi_static_sar_hdr *hdr; + struct rtw89_sar_entry_from_acpi tmp = {}; + struct rtw89_acpi_sar_rec_parm parm = {}; + struct rtw89_sar_table_from_acpi *tbl; + const struct rtw89_acpi_data *data; + u32 len; + + data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_STATIC_SAR); + if (!data) + return NULL; + + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load static sar\n"); + + len = data->len; + if (len <= sizeof(*hdr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len); + goto out; + } + + hdr = (typeof(hdr))data->buf; + + parm.cid = le16_to_cpu(hdr->cid); + parm.rev = hdr->rev; + parm.tbl_cnt = 1; + parm.pld_len = len - sizeof(*hdr); + + rec = rtw89_acpi_sar_recognize(rtwdev, &parm); + if (!rec) + goto out; + + rec->load(rtwdev, rec, hdr->content, &tmp); + + tbl = &cfg->tables[0]; + for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++) + tbl->entries[regd] = tmp; + + cfg->valid_num = 1; + +out: + kfree(data); + return rec; +} + +static const struct rtw89_acpi_sar_recognition * +rtw89_acpi_evaluate_dynamic_sar(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg) +{ + const struct rtw89_acpi_sar_recognition *rec = NULL; + const struct rtw89_acpi_dynamic_sar_hdr *hdr; + struct rtw89_acpi_sar_rec_parm parm = {}; + struct rtw89_sar_table_from_acpi *tbl; + const struct rtw89_acpi_data *data; + u32 len; + + data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR); + if (!data) + return NULL; + + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar\n"); + + len = data->len; + if (len <= sizeof(*hdr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len); + goto out; + } + + hdr = (typeof(hdr))data->buf; + + parm.cid = le16_to_cpu(hdr->cid); + parm.rev = hdr->rev; + parm.tbl_cnt = hdr->cnt; + parm.pld_len = len - sizeof(*hdr); + + rec = rtw89_acpi_sar_recognize(rtwdev, &parm); + if (!rec) + goto out; + + for (unsigned int i = 0; i < hdr->cnt; i++) { + const u8 *content = hdr->content + rec->id.size * i; + struct rtw89_sar_entry_from_acpi tmp = {}; + + rec->load(rtwdev, rec, content, &tmp); + + tbl = &cfg->tables[i]; + for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++) + tbl->entries[regd] = tmp; + } + + cfg->valid_num = hdr->cnt; + +out: + kfree(data); + return rec; +} + +int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg, + bool *poll_changed) +{ + struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator; + struct rtw89_sar_indicator_from_acpi tmp = *ind; + const struct rtw89_acpi_data *data; + const u8 *tbl_base1_by_ant; + enum rtw89_rf_path path; + int ret = 0; + u32 len; + + data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR); + if (!data) + return -EFAULT; + + if (!poll_changed) + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar indicator\n"); + + len = data->len; + if (len != ind->fields) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len); + ret = -EINVAL; + goto out; + } + + tbl_base1_by_ant = data->buf; + + for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) { + u8 antidx = ind->rfpath_to_antidx(path); + u8 sel; + + if (antidx >= ind->fields) + antidx = 0; + + /* convert the table index from 1-based to 0-based */ + sel = tbl_base1_by_ant[antidx] - 1; + if (sel >= cfg->valid_num) + sel = 0; + + tmp.tblsel[path] = sel; + } + + if (memcmp(ind, &tmp, sizeof(*ind)) == 0) { + if (poll_changed) + *poll_changed = false; + } else { + if (poll_changed) + *poll_changed = true; + + *ind = tmp; + } + +out: + kfree(data); + return ret; +} + +static +void rtw89_acpi_evaluate_geo_sar(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_geo_sar_handler *hdl, + struct rtw89_sar_cfg_acpi *cfg) +{ + const struct rtw89_acpi_data *data; + u32 len; + + data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_GEO_SAR); + if (!data) + return; + + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load geo sar\n"); + + len = data->len; + if (len != hdl->data_size) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u (expected %u)\n", + len, hdl->data_size); + goto out; + } + + for (unsigned int i = 0; i < cfg->valid_num; i++) + for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++) + hdl->load(rtwdev, data->buf, regd, &cfg->tables[i].entries[regd]); + +out: + kfree(data); +} + +int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg) +{ + struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator; + const struct rtw89_acpi_sar_recognition *rec; + bool fetch_indicator = false; + int ret; + + rec = rtw89_acpi_evaluate_static_sar(rtwdev, cfg); + if (rec) + goto recognized; + + rec = rtw89_acpi_evaluate_dynamic_sar(rtwdev, cfg); + if (!rec) + return -ENOENT; + + fetch_indicator = true; + +recognized: + rtw89_acpi_evaluate_geo_sar(rtwdev, rec->geo, cfg); + + switch (rec->id.cid) { + case RTW89_ACPI_SAR_CID_HP: + cfg->downgrade_2tx = 3 << TXPWR_FACTOR_OF_RTW89_ACPI_SAR; + ind->fields = RTW89_ACPI_SAR_ANT_NR_STD; + break; + case RTW89_ACPI_SAR_CID_RT: + cfg->downgrade_2tx = 0; + ind->fields = 1; + break; + default: + return -EFAULT; + } + + if (fetch_indicator) { + ind->rfpath_to_antidx = rec->rfpath_to_antidx; + ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, NULL); + if (ret) + fetch_indicator = false; + } + + if (!fetch_indicator) + memset(ind->tblsel, 0, sizeof(ind->tblsel)); + + ind->enable_sync = fetch_indicator; + return 0; +} diff --git a/drivers/net/wireless/realtek/rtw89/acpi.h b/drivers/net/wireless/realtek/rtw89/acpi.h new file mode 100644 index 000000000..48a46f200 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/acpi.h @@ -0,0 +1,298 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2021-2023 Realtek Corporation + */ + +#ifndef __RTW89_ACPI_H__ +#define __RTW89_ACPI_H__ + +#include "core.h" + +struct rtw89_acpi_data { + u32 len; + u8 buf[] __counted_by(len); +}; + +enum rtw89_acpi_dsm_func { + RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2, + RTW89_ACPI_DSM_FUNC_6G_DIS = 3, + RTW89_ACPI_DSM_FUNC_6G_BP = 4, + RTW89_ACPI_DSM_FUNC_TAS_EN = 5, + RTW89_ACPI_DSM_FUNC_UNII4_SUP = 6, + RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7, + RTW89_ACPI_DSM_FUNC_REG_RULES_EN = 10, + RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP = 11, +}; + +enum rtw89_acpi_conf_unii4 { + RTW89_ACPI_CONF_UNII4_US = BIT(0), + RTW89_ACPI_CONF_UNII4_CA = BIT(1), +}; + +enum rtw89_acpi_policy_mode { + RTW89_ACPI_POLICY_BLOCK = 0, + RTW89_ACPI_POLICY_ALLOW = 1, +}; + +enum rtw89_acpi_conf_tas { + RTW89_ACPI_CONF_TAS_US = BIT(0), + RTW89_ACPI_CONF_TAS_CA = BIT(1), + RTW89_ACPI_CONF_TAS_KR = BIT(2), + RTW89_ACPI_CONF_TAS_OTHERS = BIT(7), +}; + +struct rtw89_acpi_country_code { + /* below are allowed: + * * ISO alpha2 country code + * * EU for countries in Europe + */ + char alpha2[2]; +} __packed; + +struct rtw89_acpi_policy_6ghz { + u8 signature[3]; + u8 rsvd; + u8 policy_mode; + u8 country_count; + struct rtw89_acpi_country_code country_list[] __counted_by(country_count); +} __packed; + +enum rtw89_acpi_conf_6ghz_sp { + RTW89_ACPI_CONF_6GHZ_SP_US = BIT(0), + RTW89_ACPI_CONF_6GHZ_SP_CA = BIT(1), +}; + +struct rtw89_acpi_policy_6ghz_sp { + u8 signature[4]; + u8 revision; + u8 override; + u8 conf; + u8 rsvd; +} __packed; + +enum rtw89_acpi_conf_6ghz_vlp { + RTW89_ACPI_CONF_6GHZ_VLP_US = BIT(0), + RTW89_ACPI_CONF_6GHZ_VLP_CA = BIT(1), +}; + +struct rtw89_acpi_policy_6ghz_vlp { + u8 signature[4]; + u8 revision; + u8 override; + u8 conf; + u8 rsvd; +} __packed; + +struct rtw89_acpi_policy_tas { + u8 signature[4]; + u8 revision; + u8 enable; + u8 enabled_countries; + u8 rsvd[3]; +} __packed; + +enum rtw89_acpi_conf_reg_rules { + RTW89_ACPI_CONF_REG_RULE_REGD_UK = BIT(0), +}; + +struct rtw89_acpi_policy_reg_rules { + u8 signature[4]; + u8 revision; + u8 conf; + u8 rsvd[3]; +} __packed; + +struct rtw89_acpi_dsm_result { + union { + u8 value; + /* caller needs to free it after using */ + struct rtw89_acpi_policy_6ghz *policy_6ghz; + struct rtw89_acpi_policy_6ghz_sp *policy_6ghz_sp; + struct rtw89_acpi_policy_6ghz_vlp *policy_6ghz_vlp; + struct rtw89_acpi_policy_tas *policy_tas; + struct rtw89_acpi_policy_reg_rules *policy_reg_rules; + } u; +}; + +struct rtw89_acpi_rtag_result { + u8 tag[4]; + u8 revision; + __le32 domain; + u8 ant_gain_table[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR]; +} __packed; + +enum rtw89_acpi_sar_cid { + RTW89_ACPI_SAR_CID_HP = 0x5048, + RTW89_ACPI_SAR_CID_RT = 0x5452, +}; + +enum rtw89_acpi_sar_rev { + RTW89_ACPI_SAR_REV_LEGACY = 1, + RTW89_ACPI_SAR_REV_HAS_6GHZ = 2, +}; + +#define RTW89_ACPI_SAR_ANT_NR_STD 4 +#define RTW89_ACPI_SAR_ANT_NR_SML 2 + +#define RTW89_ACPI_METHOD_STATIC_SAR "WRDS" +#define RTW89_ACPI_METHOD_DYNAMIC_SAR "RWRD" +#define RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR "RWSI" +#define RTW89_ACPI_METHOD_GEO_SAR "RWGS" + +struct rtw89_acpi_sar_std_legacy { + u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY]; +} __packed; + +struct rtw89_acpi_sar_std_has_6ghz { + u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ]; +} __packed; + +struct rtw89_acpi_sar_sml_legacy { + u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY]; +} __packed; + +struct rtw89_acpi_sar_sml_has_6ghz { + u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ]; +} __packed; + +struct rtw89_acpi_static_sar_hdr { + __le16 cid; + u8 rev; + u8 content[]; +} __packed; + +struct rtw89_acpi_dynamic_sar_hdr { + __le16 cid; + u8 rev; + u8 cnt; + u8 content[]; +} __packed; + +struct rtw89_acpi_sar_identifier { + enum rtw89_acpi_sar_cid cid; + enum rtw89_acpi_sar_rev rev; + u8 size; +}; + +/* for rtw89_acpi_sar_identifier::size */ +#define RTW89_ACPI_SAR_SIZE_MAX U8_MAX +#define RTW89_ACPI_SAR_SIZE_OF(type) \ + (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_sar_ ## type) > \ + RTW89_ACPI_SAR_SIZE_MAX) + \ + sizeof(struct rtw89_acpi_sar_ ## type)) + +struct rtw89_acpi_sar_recognition { + struct rtw89_acpi_sar_identifier id; + const struct rtw89_acpi_geo_sar_handler *geo; + + u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath); + s16 (*normalize)(u8 v); + void (*load)(struct rtw89_dev *rtwdev, + const struct rtw89_acpi_sar_recognition *rec, + const void *content, + struct rtw89_sar_entry_from_acpi *ent); +}; + +struct rtw89_acpi_geo_sar_hp_val { + u8 max; + s8 delta[RTW89_ACPI_SAR_ANT_NR_STD]; +} __packed; + +struct rtw89_acpi_geo_sar_hp_legacy_entry { + struct rtw89_acpi_geo_sar_hp_val val_2ghz; + struct rtw89_acpi_geo_sar_hp_val val_5ghz; +} __packed; + +struct rtw89_acpi_geo_sar_hp_has_6ghz_entry { + struct rtw89_acpi_geo_sar_hp_val val_2ghz; + struct rtw89_acpi_geo_sar_hp_val val_5ghz; + struct rtw89_acpi_geo_sar_hp_val val_6ghz; +} __packed; + +enum rtw89_acpi_geo_sar_regd_hp { + RTW89_ACPI_GEO_SAR_REGD_HP_FCC = 0, + RTW89_ACPI_GEO_SAR_REGD_HP_ETSI = 1, + RTW89_ACPI_GEO_SAR_REGD_HP_WW = 2, + + RTW89_ACPI_GEO_SAR_REGD_NR_HP, +}; + +struct rtw89_acpi_geo_sar_hp_legacy { + struct rtw89_acpi_geo_sar_hp_legacy_entry + entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP]; +} __packed; + +struct rtw89_acpi_geo_sar_hp_has_6ghz { + struct rtw89_acpi_geo_sar_hp_has_6ghz_entry + entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP]; +} __packed; + +struct rtw89_acpi_geo_sar_rt_val { + u8 max; + s8 delta; +} __packed; + +struct rtw89_acpi_geo_sar_rt_legacy_entry { + struct rtw89_acpi_geo_sar_rt_val val_2ghz; + struct rtw89_acpi_geo_sar_rt_val val_5ghz; +} __packed; + +struct rtw89_acpi_geo_sar_rt_has_6ghz_entry { + struct rtw89_acpi_geo_sar_rt_val val_2ghz; + struct rtw89_acpi_geo_sar_rt_val val_5ghz; + struct rtw89_acpi_geo_sar_rt_val val_6ghz; +} __packed; + +enum rtw89_acpi_geo_sar_regd_rt { + RTW89_ACPI_GEO_SAR_REGD_RT_FCC = 0, + RTW89_ACPI_GEO_SAR_REGD_RT_ETSI = 1, + RTW89_ACPI_GEO_SAR_REGD_RT_MKK = 2, + RTW89_ACPI_GEO_SAR_REGD_RT_IC = 3, + RTW89_ACPI_GEO_SAR_REGD_RT_KCC = 4, + RTW89_ACPI_GEO_SAR_REGD_RT_WW = 5, + + RTW89_ACPI_GEO_SAR_REGD_NR_RT, +}; + +struct rtw89_acpi_geo_sar_rt_legacy { + struct rtw89_acpi_geo_sar_rt_legacy_entry + entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT]; +} __packed; + +struct rtw89_acpi_geo_sar_rt_has_6ghz { + struct rtw89_acpi_geo_sar_rt_has_6ghz_entry + entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT]; +} __packed; + +struct rtw89_acpi_geo_sar_handler { + u8 data_size; + + void (*load)(struct rtw89_dev *rtwdev, + const void *content, + enum rtw89_regulation_type regd, + struct rtw89_sar_entry_from_acpi *ent); +}; + +/* for rtw89_acpi_geo_sar_handler::data_size */ +#define RTW89_ACPI_GEO_SAR_SIZE_MAX U8_MAX +#define RTW89_ACPI_GEO_SAR_SIZE_OF(type) \ + (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_geo_sar_ ## type) > \ + RTW89_ACPI_GEO_SAR_SIZE_MAX) + \ + sizeof(struct rtw89_acpi_geo_sar_ ## type)) + +enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev, + u32 center_freq); +enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev, + enum rtw89_acpi_sar_subband subband); + +int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, + enum rtw89_acpi_dsm_func func, + struct rtw89_acpi_dsm_result *res); +int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev, + struct rtw89_acpi_rtag_result *res); +int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg); +int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev, + struct rtw89_sar_cfg_acpi *cfg, + bool *changed); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c new file mode 100644 index 000000000..7c62ece13 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -0,0 +1,1276 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "cam.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "ps.h" + +static struct sk_buff * +rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev, + struct rtw89_sec_cam_entry *sec_cam, + bool ext_key) +{ + struct sk_buff *skb; + u32 cmd_len = H2C_SEC_CAM_LEN; + u32 key32[4]; + u8 *cmd; + int i, j; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, cmd_len); + if (!skb) + return NULL; + + skb_put_zero(skb, cmd_len); + + for (i = 0; i < 4; i++) { + j = i * 4; + j += ext_key ? 16 : 0; + key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) | + FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) | + FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) | + FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]); + } + + cmd = skb->data; + RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0)); + RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset); + RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len); + RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type); + RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key); + RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode); + RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]); + RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]); + RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]); + RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]); + + return skb; +} + +static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev, + struct rtw89_sec_cam_entry *sec_cam) +{ + struct sk_buff *skb, *ext_skb; + int ret; + + skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false); + if (!skb) { + rtw89_err(rtwdev, "failed to get sec key command\n"); + return -ENOMEM; + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, + FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_SEC_CAM, + H2C_FUNC_MAC_SEC_UPD, 1, 0, + H2C_SEC_CAM_LEN); + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret); + dev_kfree_skb(skb); + return ret; + } + + if (!sec_cam->ext_key) + return 0; + + ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true); + if (!ext_skb) { + rtw89_err(rtwdev, "failed to get ext sec key command\n"); + return -ENOMEM; + } + + rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb, + FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_SEC_CAM, + H2C_FUNC_MAC_SEC_UPD, + 1, 0, H2C_SEC_CAM_LEN); + ret = rtw89_h2c_tx(rtwdev, ext_skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret); + dev_kfree_skb(ext_skb); + return ret; + } + + return 0; +} + +static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev, + u8 *sec_cam_idx, bool ext_key) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + u8 sec_cam_num = chip->scam_num; + u8 idx = 0; + + if (!ext_key) { + idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num); + if (idx >= sec_cam_num) + return -EBUSY; + + set_bit(idx, cam_info->sec_cam_map); + *sec_cam_idx = idx; + + return 0; + } + +again: + idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx); + if (idx >= sec_cam_num - 1) + return -EBUSY; + /* ext keys need two cam entries for 256-bit key */ + if (test_bit(idx + 1, cam_info->sec_cam_map)) { + idx++; + goto again; + } + + set_bit(idx, cam_info->sec_cam_map); + set_bit(idx + 1, cam_info->sec_cam_map); + *sec_cam_idx = idx; + + return 0; +} + +static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam, + const struct rtw89_sec_cam_entry *sec_cam, + const struct ieee80211_key_conf *key, + u8 *key_idx) +{ + u8 idx; + + /* RTW89_ADDR_CAM_SEC_NONE : not enabled + * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast + * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP + * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP + */ + switch (addr_cam->sec_ent_mode) { + case RTW89_ADDR_CAM_SEC_NONE: + return -EINVAL; + case RTW89_ADDR_CAM_SEC_ALL_UNI: + idx = find_first_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM); + if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM) + return -EBUSY; + *key_idx = idx; + break; + case RTW89_ADDR_CAM_SEC_NORMAL: + if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) { + idx = find_next_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM, 5); + if (idx > 6) + return -EBUSY; + *key_idx = idx; + break; + } + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + idx = find_next_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM, 0); + if (idx > 1) + return -EBUSY; + *key_idx = idx; + break; + } + + /* Group keys */ + idx = find_next_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM, 2); + if (idx > 4) + return -EBUSY; + *key_idx = idx; + break; + case RTW89_ADDR_CAM_SEC_4GROUP: + if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) { + if (test_bit(6, addr_cam->sec_cam_map)) + return -EINVAL; + *key_idx = 6; + break; + } + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + idx = find_next_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM, 0); + if (idx > 1) + return -EBUSY; + *key_idx = idx; + break; + } + + /* Group keys */ + idx = find_next_zero_bit(addr_cam->sec_cam_map, + RTW89_SEC_CAM_IN_ADDR_CAM, 2); + if (idx > 5) + return -EBUSY; + *key_idx = idx; + break; + } + + return 0; +} + +static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + const struct rtw89_sec_cam_entry *sec_cam, + bool inform_fw) +{ + struct rtw89_addr_cam_entry *addr_cam; + unsigned int i; + int ret = 0; + + addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + + for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) { + if (addr_cam->sec_ent[i] != sec_cam->sec_cam_idx) + continue; + + clear_bit(i, addr_cam->sec_cam_map); + } + + if (inform_fw) { + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + rtw89_err(rtwdev, + "failed to update dctl cam del key: %d\n", ret); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_INFO_CHANGE); + if (ret) + rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret); + } + + return ret; +} + +static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + const struct ieee80211_key_conf *key, + const struct rtw89_sec_cam_entry *sec_cam) +{ + struct rtw89_addr_cam_entry *addr_cam; + u8 key_idx = 0; + int ret; + + addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) + addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_ALL_UNI; + + ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx); + if (ret) { + rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n", + addr_cam->sec_ent_mode, sec_cam->type); + return ret; + } + + addr_cam->sec_ent_keyid[key_idx] = key->keyidx; + addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx; + set_bit(key_idx, addr_cam->sec_cam_map); + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", + ret); + return ret; + } + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_INFO_CHANGE); + if (ret) { + rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n", + ret); + clear_bit(key_idx, addr_cam->sec_cam_map); + return ret; + } + + return 0; +} + +int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + u8 sec_cam_idx) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + const struct rtw89_sec_cam_entry *sec_cam; + + sec_cam = cam_info->sec_entries[sec_cam_idx]; + if (!sec_cam) + return -ENOENT; + + return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link, rtwsta_link, + sec_cam->key_conf, sec_cam); +} + +static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + const struct rtw89_sec_cam_entry *sec_cam, + bool inform_fw) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + int ret; + + if (!vif) { + rtw89_err(rtwdev, "No iface for deleting sec cam\n"); + return -EINVAL; + } + + rtwvif = vif_to_rtwvif(vif); + + if (rtwsta) + clear_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL; + if (rtwsta && !rtwsta_link) + continue; + + ret = __rtw89_cam_detach_sec_cam(rtwdev, rtwvif_link, rtwsta_link, + sec_cam, inform_fw); + if (ret) + return ret; + } + + return 0; +} + +static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + struct rtw89_sec_cam_entry *sec_cam) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + int key_link_id; + int ret; + + if (!vif) { + rtw89_err(rtwdev, "No iface for adding sec cam\n"); + return -EINVAL; + } + + rtwvif = vif_to_rtwvif(vif); + + key_link_id = ieee80211_vif_is_mld(vif) ? key->link_id : 0; + if (key_link_id >= 0) { + rtwvif_link = rtwvif->links[key_link_id]; + rtwsta_link = rtwsta ? rtwsta->links[key_link_id] : NULL; + + if (!rtwvif_link || (rtwsta && !rtwsta_link)) { + rtw89_err(rtwdev, "No drv link for adding sec cam\n"); + return -ENOLINK; + } + + return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link, + rtwsta_link, key, sec_cam); + } + + /* key_link_id < 0: MLD pairwise key */ + if (!rtwsta) { + rtw89_err(rtwdev, "No sta for adding MLD pairwise sec cam\n"); + return -EINVAL; + } + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link, + rtwsta_link, key, sec_cam); + if (ret) + return ret; + } + + set_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map); + + return 0; +} + +static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + u8 hw_key_type, bool ext_key) +{ + struct rtw89_sec_cam_entry *sec_cam = NULL; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + u8 sec_cam_idx; + int ret; + + /* maximum key length 256-bit */ + if (key->keylen > 32) { + rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen); + return -EINVAL; + } + + ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key); + if (ret) { + rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n", + ret, ext_key); + return ret; + } + + sec_cam = kzalloc_obj(*sec_cam); + if (!sec_cam) { + ret = -ENOMEM; + goto err_release_cam; + } + + key->hw_key_idx = sec_cam_idx; + cam_info->sec_entries[sec_cam_idx] = sec_cam; + + sec_cam->sec_cam_idx = sec_cam_idx; + sec_cam->type = hw_key_type; + sec_cam->len = RTW89_SEC_CAM_LEN; + sec_cam->ext_key = ext_key; + memcpy(sec_cam->key, key->key, key->keylen); + + sec_cam->key_conf = key; + + ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam); + if (ret) { + rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret); + goto err_release_cam; + } + + /* associate with addr cam */ + ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam); + if (ret) { + rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret); + goto err_release_cam; + } + + return 0; + +err_release_cam: + cam_info->sec_entries[sec_cam_idx] = NULL; + kfree(sec_cam); + clear_bit(sec_cam_idx, cam_info->sec_cam_map); + if (ext_key) + clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map); + + return ret; +} + +int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 hw_key_type; + bool ext_key = false; + int ret; + + if (ieee80211_vif_is_mld(vif) && !chip->hw_mlo_bmc_crypto && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + rtw89_leave_ips_by_hwflags(rtwdev); + hw_key_type = RTW89_SEC_KEY_TYPE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + rtw89_leave_ips_by_hwflags(rtwdev); + hw_key_type = RTW89_SEC_KEY_TYPE_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + if (!chip->hw_tkip_crypto) + return -EOPNOTSUPP; + hw_key_type = RTW89_SEC_KEY_TYPE_TKIP; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + case WLAN_CIPHER_SUITE_CCMP: + hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128; + if (!chip->hw_mgmt_tx_encrypt) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256; + if (!chip->hw_mgmt_tx_encrypt) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + ext_key = true; + break; + case WLAN_CIPHER_SUITE_GCMP: + hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128; + if (!chip->hw_mgmt_tx_encrypt) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256; + if (!chip->hw_mgmt_tx_encrypt) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + ext_key = true; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + hw_key_type = RTW89_SEC_KEY_TYPE_BIP_CCMP128; + break; + default: + return -EOPNOTSUPP; + } + + if (!chip->hw_sec_hdr) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type, + ext_key); + if (ret) { + rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n", + hw_key_type, ext_key, ret); + return ret; + } + + return 0; +} + +int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + bool inform_fw) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + const struct rtw89_sec_cam_entry *sec_cam; + u8 sec_cam_idx; + int ret; + + sec_cam_idx = key->hw_key_idx; + sec_cam = cam_info->sec_entries[sec_cam_idx]; + if (!sec_cam) + return -EINVAL; + + ret = rtw89_cam_detach_sec_cam(rtwdev, vif, sta, sec_cam, inform_fw); + + /* clear valid bit in addr cam will disable sec cam, + * so we don't need to send H2C command again + */ + cam_info->sec_entries[sec_cam_idx] = NULL; + clear_bit(sec_cam_idx, cam_info->sec_cam_map); + if (sec_cam->ext_key) + clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map); + + kfree(sec_cam); + + return ret; +} + +static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; + + rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false); +} + +void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev, + struct rtw89_addr_cam_entry *addr_cam) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + + addr_cam->valid = false; + clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map); +} + +void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev, + struct rtw89_bssid_cam_entry *bssid_cam) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + + bssid_cam->valid = false; + clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map); +} + +void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam; + struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; + + rtw89_cam_deinit_addr_cam(rtwdev, addr_cam); + rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam); +} + +void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev) +{ + rcu_read_lock(); + ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev); + rcu_read_unlock(); +} + +static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev, + u8 *addr_cam_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + u8 addr_cam_num = chip->acam_num; + u8 idx; + + idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num); + if (idx >= addr_cam_num) + return -EBUSY; + + set_bit(idx, cam_info->addr_cam_map); + *addr_cam_idx = idx; + + return 0; +} + +static u8 rtw89_get_addr_cam_entry_size(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + switch (chip->chip_id) { + case RTL8852A: + case RTL8852B: + case RTL8851B: + case RTL8852BT: + return ADDR_CAM_ENT_SIZE; + default: + return ADDR_CAM_ENT_SHORT_SIZE; + } +} + +int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, + struct rtw89_addr_cam_entry *addr_cam, + const struct rtw89_bssid_cam_entry *bssid_cam) +{ + u8 addr_cam_idx; + int i; + int ret; + + if (unlikely(addr_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "addr cam is already valid; skip init\n"); + return 0; + } + + ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx); + if (ret) { + rtw89_err(rtwdev, "failed to get available addr cam\n"); + return ret; + } + + addr_cam->addr_cam_idx = addr_cam_idx; + addr_cam->len = rtw89_get_addr_cam_entry_size(rtwdev); + addr_cam->offset = 0; + addr_cam->valid = true; + addr_cam->addr_mask = 0; + addr_cam->mask_sel = RTW89_NO_MSK; + addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; + bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); + + for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) { + addr_cam->sec_ent_keyid[i] = 0; + addr_cam->sec_ent[i] = 0; + } + + /* associate addr cam with bssid cam */ + addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx; + + return 0; +} + +static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev, + u8 *bssid_cam_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + u8 bssid_cam_num = chip->bcam_num; + u8 idx; + + idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num); + if (idx >= bssid_cam_num) + return -EBUSY; + + set_bit(idx, cam_info->bssid_cam_map); + *bssid_cam_idx = idx; + + return 0; +} + +int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_bssid_cam_entry *bssid_cam, + const u8 *bssid) +{ + u8 bssid_cam_idx; + int ret; + + if (unlikely(bssid_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "bssid cam is already valid; skip init\n"); + return 0; + } + + ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx); + if (ret) { + rtw89_err(rtwdev, "failed to get available bssid cam\n"); + return ret; + } + + bssid_cam->bssid_cam_idx = bssid_cam_idx; + bssid_cam->phy_idx = rtwvif_link->phy_idx; + bssid_cam->len = BSSID_CAM_ENT_SIZE; + bssid_cam->offset = 0; + bssid_cam->valid = true; + ether_addr_copy(bssid_cam->bssid, bssid); + + return 0; +} + +void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; + + ether_addr_copy(bssid_cam->bssid, rtwvif_link->bssid); +} + +int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam; + struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; + int ret; + + ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam, + rtwvif_link->bssid); + if (ret) { + rtw89_err(rtwdev, "failed to init bssid cam\n"); + return ret; + } + + ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam); + if (ret) { + rtw89_err(rtwdev, "failed to init addr cam\n"); + return ret; + } + + return 0; +} + +int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_addr_cam_v0 *h2c) +{ + struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, + rtwsta_link); + struct ieee80211_bss_conf *bss_conf; + u8 bss_color; + u8 bss_mask; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + bss_color = bss_conf->he_bss_color.color; + + if (bss_conf->nontransmitted) + bss_mask = RTW89_BSSID_MATCH_5_BYTES; + else + bss_mask = RTW89_BSSID_MATCH_ALL; + + rcu_read_unlock(); + + h2c->w12 = le32_encode_bits(bssid_cam->bssid_cam_idx, ADDR_CAM_W12_BSSID_IDX) | + le32_encode_bits(bssid_cam->offset, ADDR_CAM_W12_BSSID_OFFSET) | + le32_encode_bits(bssid_cam->len, ADDR_CAM_W12_BSSID_LEN); + h2c->w13 = le32_encode_bits(bssid_cam->valid, ADDR_CAM_W13_BSSID_VALID) | + le32_encode_bits(bss_mask, ADDR_CAM_W13_BSSID_MASK) | + le32_encode_bits(bssid_cam->phy_idx, ADDR_CAM_W13_BSSID_BB_SEL) | + le32_encode_bits(bss_color, ADDR_CAM_W13_BSSID_BSS_COLOR) | + le32_encode_bits(bssid_cam->bssid[0], ADDR_CAM_W13_BSSID_BSSID0) | + le32_encode_bits(bssid_cam->bssid[1], ADDR_CAM_W13_BSSID_BSSID1); + h2c->w14 = le32_encode_bits(bssid_cam->bssid[2], ADDR_CAM_W14_BSSID_BSSID2) | + le32_encode_bits(bssid_cam->bssid[3], ADDR_CAM_W14_BSSID_BSSID3) | + le32_encode_bits(bssid_cam->bssid[4], ADDR_CAM_W14_BSSID_BSSID4) | + le32_encode_bits(bssid_cam->bssid[5], ADDR_CAM_W14_BSSID_BSSID5); + + return 0; +} + +static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr) +{ + u8 hash = 0; + u8 i; + + for (i = start; i < ETH_ALEN; i++) + hash ^= addr[i]; + + return hash; +} + +void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + const u8 *scan_mac_addr, + struct rtw89_h2c_addr_cam_v0 *h2c) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_addr_cam_entry *addr_cam = + rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_link_sta *link_sta; + const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr; + u8 sma_hash, tma_hash, addr_msk_start; + u8 ver = chip->addrcam_ver; + u8 sma_start = 0; + u8 tma_start = 0; + const u8 *tma; + u8 mac_id; + + rcu_read_lock(); + + if (sta) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + tma = link_sta->addr; + } else { + tma = rtwvif_link->bssid; + } + + if (addr_cam->addr_mask != 0) { + addr_msk_start = __ffs(addr_cam->addr_mask); + if (addr_cam->mask_sel == RTW89_SMA) + sma_start = addr_msk_start; + else if (addr_cam->mask_sel == RTW89_TMA) + tma_start = addr_msk_start; + } + sma_hash = rtw89_cam_addr_hash(sma_start, sma); + tma_hash = rtw89_cam_addr_hash(tma_start, tma); + + mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + + if (ver == 0) + h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_IDX) | + le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_OFFSET) | + le32_encode_bits(addr_cam->len, ADDR_CAM_W1_LEN); + else + h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_V1_IDX) | + le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_V1_OFFSET) | + le32_encode_bits(addr_cam->len, ADDR_CAM_W1_V1_LEN); + + h2c->w2 = le32_encode_bits(addr_cam->valid, ADDR_CAM_W2_VALID) | + le32_encode_bits(rtwvif_link->net_type, ADDR_CAM_W2_NET_TYPE) | + le32_encode_bits(rtwvif_link->bcn_hit_cond, ADDR_CAM_W2_BCN_HIT_COND) | + le32_encode_bits(rtwvif_link->hit_rule, ADDR_CAM_W2_HIT_RULE) | + le32_encode_bits(rtwvif_link->phy_idx, ADDR_CAM_W2_BB_SEL) | + le32_encode_bits(addr_cam->addr_mask, ADDR_CAM_W2_ADDR_MASK) | + le32_encode_bits(addr_cam->mask_sel, ADDR_CAM_W2_MASK_SEL) | + le32_encode_bits(sma_hash, ADDR_CAM_W2_SMA_HASH) | + le32_encode_bits(tma_hash, ADDR_CAM_W2_TMA_HASH); + h2c->w3 = le32_encode_bits(addr_cam->bssid_cam_idx, ADDR_CAM_W3_BSSID_CAM_IDX); + h2c->w4 = le32_encode_bits(sma[0], ADDR_CAM_W4_SMA0) | + le32_encode_bits(sma[1], ADDR_CAM_W4_SMA1) | + le32_encode_bits(sma[2], ADDR_CAM_W4_SMA2) | + le32_encode_bits(sma[3], ADDR_CAM_W4_SMA3); + h2c->w5 = le32_encode_bits(sma[4], ADDR_CAM_W5_SMA4) | + le32_encode_bits(sma[5], ADDR_CAM_W5_SMA5) | + le32_encode_bits(tma[0], ADDR_CAM_W5_TMA0) | + le32_encode_bits(tma[1], ADDR_CAM_W5_TMA1); + h2c->w6 = le32_encode_bits(tma[2], ADDR_CAM_W6_TMA2) | + le32_encode_bits(tma[3], ADDR_CAM_W6_TMA3) | + le32_encode_bits(tma[4], ADDR_CAM_W6_TMA4) | + le32_encode_bits(tma[5], ADDR_CAM_W6_TMA5); + if (ver == 0) + h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_PORT_INT) | + le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_TSF_SYNC) | + le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_TF_TRS) | + le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_LSIG_TXOP) | + le32_encode_bits(rtwvif_link->tgt_ind, ADDR_CAM_W8_TGT_IND) | + le32_encode_bits(rtwvif_link->frm_tgt_ind, ADDR_CAM_W8_FRM_TGT_IND) | + le32_encode_bits(mac_id, ADDR_CAM_W8_MACID); + else + h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_PORT_INT) | + le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_TSF_SYNC) | + le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_V1_TF_TRS) | + le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_V1_LSIG_TXOP) | + le32_encode_bits(mac_id, ADDR_CAM_W8_V1_MACID); + + if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) + h2c->w9 = le32_encode_bits(vif->cfg.aid & 0xfff, ADDR_CAM_W9_AID12); + else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + h2c->w9 = le32_encode_bits(sta ? sta->aid & 0xfff : 0, ADDR_CAM_W9_AID12); + + h2c->w9 |= le32_encode_bits(rtwvif_link->wowlan_pattern, ADDR_CAM_W9_WOL_PATTERN) | + le32_encode_bits(rtwvif_link->wowlan_uc, ADDR_CAM_W9_WOL_UC) | + le32_encode_bits(rtwvif_link->wowlan_magic, ADDR_CAM_W9_WOL_MAGIC) | + le32_encode_bits(addr_cam->wapi, ADDR_CAM_W9_WAPI) | + le32_encode_bits(addr_cam->sec_ent_mode, ADDR_CAM_W9_SEC_ENT_MODE) | + le32_encode_bits(addr_cam->sec_ent_keyid[0], ADDR_CAM_W9_SEC_ENT0_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[1], ADDR_CAM_W9_SEC_ENT1_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[2], ADDR_CAM_W9_SEC_ENT2_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[3], ADDR_CAM_W9_SEC_ENT3_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[4], ADDR_CAM_W9_SEC_ENT4_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[5], ADDR_CAM_W9_SEC_ENT5_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[6], ADDR_CAM_W9_SEC_ENT6_KEYID); + h2c->w10 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff, ADDR_CAM_W10_SEC_ENT_VALID) | + le32_encode_bits(addr_cam->sec_ent[0], ADDR_CAM_W10_SEC_ENT0) | + le32_encode_bits(addr_cam->sec_ent[1], ADDR_CAM_W10_SEC_ENT1) | + le32_encode_bits(addr_cam->sec_ent[2], ADDR_CAM_W10_SEC_ENT2); + h2c->w11 = le32_encode_bits(addr_cam->sec_ent[3], ADDR_CAM_W11_SEC_ENT3) | + le32_encode_bits(addr_cam->sec_ent[4], ADDR_CAM_W11_SEC_ENT4) | + le32_encode_bits(addr_cam->sec_ent[5], ADDR_CAM_W11_SEC_ENT5) | + le32_encode_bits(addr_cam->sec_ent[6], ADDR_CAM_W11_SEC_ENT6); + + rcu_read_unlock(); +} + +void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v1 *h2c) +{ + struct rtw89_addr_cam_entry *addr_cam = + rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv; + + h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id : + rtwvif_link->mac_id, + DCTLINFO_V1_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V1_C0_OP); + + h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0], + DCTLINFO_V1_W4_SEC_ENT0_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[1], + DCTLINFO_V1_W4_SEC_ENT1_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[2], + DCTLINFO_V1_W4_SEC_ENT2_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[3], + DCTLINFO_V1_W4_SEC_ENT3_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[4], + DCTLINFO_V1_W4_SEC_ENT4_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[5], + DCTLINFO_V1_W4_SEC_ENT5_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[6], + DCTLINFO_V1_W4_SEC_ENT6_KEYID); + h2c->m4 = cpu_to_le32(DCTLINFO_V1_W4_SEC_ENT0_KEYID | + DCTLINFO_V1_W4_SEC_ENT1_KEYID | + DCTLINFO_V1_W4_SEC_ENT2_KEYID | + DCTLINFO_V1_W4_SEC_ENT3_KEYID | + DCTLINFO_V1_W4_SEC_ENT4_KEYID | + DCTLINFO_V1_W4_SEC_ENT5_KEYID | + DCTLINFO_V1_W4_SEC_ENT6_KEYID); + + h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff, + DCTLINFO_V1_W5_SEC_ENT_VALID) | + le32_encode_bits(addr_cam->sec_ent[0], + DCTLINFO_V1_W5_SEC_ENT0) | + le32_encode_bits(addr_cam->sec_ent[1], + DCTLINFO_V1_W5_SEC_ENT1) | + le32_encode_bits(addr_cam->sec_ent[2], + DCTLINFO_V1_W5_SEC_ENT2); + h2c->m5 = cpu_to_le32(DCTLINFO_V1_W5_SEC_ENT_VALID | + DCTLINFO_V1_W5_SEC_ENT0 | + DCTLINFO_V1_W5_SEC_ENT1 | + DCTLINFO_V1_W5_SEC_ENT2); + + h2c->w6 = le32_encode_bits(addr_cam->sec_ent[3], + DCTLINFO_V1_W6_SEC_ENT3) | + le32_encode_bits(addr_cam->sec_ent[4], + DCTLINFO_V1_W6_SEC_ENT4) | + le32_encode_bits(addr_cam->sec_ent[5], + DCTLINFO_V1_W6_SEC_ENT5) | + le32_encode_bits(addr_cam->sec_ent[6], + DCTLINFO_V1_W6_SEC_ENT6); + h2c->m6 = cpu_to_le32(DCTLINFO_V1_W6_SEC_ENT3 | + DCTLINFO_V1_W6_SEC_ENT4 | + DCTLINFO_V1_W6_SEC_ENT5 | + DCTLINFO_V1_W6_SEC_ENT6); + + if (rtw_wow->ptk_alg) { + h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8, + DCTLINFO_V1_W0_AES_IV_L); + h2c->m0 = cpu_to_le32(DCTLINFO_V1_W0_AES_IV_L); + + h2c->w1 = le32_encode_bits(ptk_tx_iv[4] | + ptk_tx_iv[5] << 8 | + ptk_tx_iv[6] << 16 | + ptk_tx_iv[7] << 24, + DCTLINFO_V1_W1_AES_IV_H); + h2c->m1 = cpu_to_le32(DCTLINFO_V1_W1_AES_IV_H); + + h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx, + DCTLINFO_V1_W4_SEC_KEY_ID); + h2c->m4 |= cpu_to_le32(DCTLINFO_V1_W4_SEC_KEY_ID); + } +} + +void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v2 *h2c) +{ + struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_addr_cam_entry *addr_cam = + rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + bool is_mld = sta ? sta->mlo : ieee80211_vif_is_mld(vif); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv; + u8 *mld_sma, *mld_tma, *mld_bssid; + + h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id : + rtwvif_link->mac_id, + DCTLINFO_V2_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V2_C0_OP); + + h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V2_W2_IS_MLD); + h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_IS_MLD); + + h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0], + DCTLINFO_V2_W4_SEC_ENT0_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[1], + DCTLINFO_V2_W4_SEC_ENT1_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[2], + DCTLINFO_V2_W4_SEC_ENT2_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[3], + DCTLINFO_V2_W4_SEC_ENT3_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[4], + DCTLINFO_V2_W4_SEC_ENT4_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[5], + DCTLINFO_V2_W4_SEC_ENT5_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[6], + DCTLINFO_V2_W4_SEC_ENT6_KEYID); + h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_SEC_ENT0_KEYID | + DCTLINFO_V2_W4_SEC_ENT1_KEYID | + DCTLINFO_V2_W4_SEC_ENT2_KEYID | + DCTLINFO_V2_W4_SEC_ENT3_KEYID | + DCTLINFO_V2_W4_SEC_ENT4_KEYID | + DCTLINFO_V2_W4_SEC_ENT5_KEYID | + DCTLINFO_V2_W4_SEC_ENT6_KEYID); + + h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0], + DCTLINFO_V2_W5_SEC_ENT_VALID_V1) | + le32_encode_bits(addr_cam->sec_ent[0], + DCTLINFO_V2_W5_SEC_ENT0_V1); + h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_SEC_ENT_VALID_V1 | + DCTLINFO_V2_W5_SEC_ENT0_V1); + + h2c->w6 = le32_encode_bits(addr_cam->sec_ent[1], + DCTLINFO_V2_W6_SEC_ENT1_V1) | + le32_encode_bits(addr_cam->sec_ent[2], + DCTLINFO_V2_W6_SEC_ENT2_V1) | + le32_encode_bits(addr_cam->sec_ent[3], + DCTLINFO_V2_W6_SEC_ENT3_V1) | + le32_encode_bits(addr_cam->sec_ent[4], + DCTLINFO_V2_W6_SEC_ENT4_V1); + h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_SEC_ENT1_V1 | + DCTLINFO_V2_W6_SEC_ENT2_V1 | + DCTLINFO_V2_W6_SEC_ENT3_V1 | + DCTLINFO_V2_W6_SEC_ENT4_V1); + + h2c->w7 = le32_encode_bits(addr_cam->sec_ent[5], + DCTLINFO_V2_W7_SEC_ENT5_V1) | + le32_encode_bits(addr_cam->sec_ent[6], + DCTLINFO_V2_W7_SEC_ENT6_V1); + h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_SEC_ENT5_V1 | + DCTLINFO_V2_W7_SEC_ENT6_V1); + + if (rtw_wow->ptk_alg) { + h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8, + DCTLINFO_V2_W0_AES_IV_L); + h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_AES_IV_L); + + h2c->w1 = le32_encode_bits(ptk_tx_iv[4] | + ptk_tx_iv[5] << 8 | + ptk_tx_iv[6] << 16 | + ptk_tx_iv[7] << 24, + DCTLINFO_V2_W1_AES_IV_H); + h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_AES_IV_H); + + h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx, + DCTLINFO_V2_W4_SEC_KEY_ID); + h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID); + } + + if (!is_mld) + return; + + if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) { + mld_sma = rtwvif->mac_addr; + mld_tma = vif->cfg.ap_addr; + mld_bssid = vif->cfg.ap_addr; + } else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE && sta) { + mld_sma = rtwvif->mac_addr; + mld_tma = sta->addr; + mld_bssid = rtwvif->mac_addr; + } else { + return; + } + + h2c->w8 = le32_encode_bits(mld_sma[0], DCTLINFO_V2_W8_MLD_SMA_0) | + le32_encode_bits(mld_sma[1], DCTLINFO_V2_W8_MLD_SMA_1) | + le32_encode_bits(mld_sma[2], DCTLINFO_V2_W8_MLD_SMA_2) | + le32_encode_bits(mld_sma[3], DCTLINFO_V2_W8_MLD_SMA_3); + h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL); + + h2c->w9 = le32_encode_bits(mld_sma[4], DCTLINFO_V2_W9_MLD_SMA_4) | + le32_encode_bits(mld_sma[5], DCTLINFO_V2_W9_MLD_SMA_5) | + le32_encode_bits(mld_tma[0], DCTLINFO_V2_W9_MLD_TMA_0) | + le32_encode_bits(mld_tma[1], DCTLINFO_V2_W9_MLD_TMA_1); + h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL); + + h2c->w10 = le32_encode_bits(mld_tma[2], DCTLINFO_V2_W10_MLD_TMA_2) | + le32_encode_bits(mld_tma[3], DCTLINFO_V2_W10_MLD_TMA_3) | + le32_encode_bits(mld_tma[4], DCTLINFO_V2_W10_MLD_TMA_4) | + le32_encode_bits(mld_tma[5], DCTLINFO_V2_W10_MLD_TMA_5); + h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL); + + h2c->w11 = le32_encode_bits(mld_bssid[0], DCTLINFO_V2_W11_MLD_BSSID_0) | + le32_encode_bits(mld_bssid[1], DCTLINFO_V2_W11_MLD_BSSID_1) | + le32_encode_bits(mld_bssid[2], DCTLINFO_V2_W11_MLD_BSSID_2) | + le32_encode_bits(mld_bssid[3], DCTLINFO_V2_W11_MLD_BSSID_3); + h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL); + + h2c->w12 = le32_encode_bits(mld_bssid[4], DCTLINFO_V2_W12_MLD_BSSID_4) | + le32_encode_bits(mld_bssid[5], DCTLINFO_V2_W12_MLD_BSSID_5); + h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL); +} + +void rtw89_cam_fill_dctl_sec_cam_info_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v3 *h2c) +{ + struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_addr_cam_entry *addr_cam = + rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + bool is_mld = sta ? sta->mlo : ieee80211_vif_is_mld(vif); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv; + u8 *mld_sma, *mld_tma, *mld_bssid; + + h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id : + rtwvif_link->mac_id, + DCTLINFO_V3_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V3_C0_OP); + + h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V3_W2_IS_MLD); + h2c->m2 = cpu_to_le32(DCTLINFO_V3_W2_IS_MLD); + + h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0], + DCTLINFO_V3_W4_SEC_ENT0_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[1], + DCTLINFO_V3_W4_SEC_ENT1_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[2], + DCTLINFO_V3_W4_SEC_ENT2_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[3], + DCTLINFO_V3_W4_SEC_ENT3_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[4], + DCTLINFO_V3_W4_SEC_ENT4_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[5], + DCTLINFO_V3_W4_SEC_ENT5_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[6], + DCTLINFO_V3_W4_SEC_ENT6_KEYID); + h2c->m4 = cpu_to_le32(DCTLINFO_V3_W4_SEC_ENT0_KEYID | + DCTLINFO_V3_W4_SEC_ENT1_KEYID | + DCTLINFO_V3_W4_SEC_ENT2_KEYID | + DCTLINFO_V3_W4_SEC_ENT3_KEYID | + DCTLINFO_V3_W4_SEC_ENT4_KEYID | + DCTLINFO_V3_W4_SEC_ENT5_KEYID | + DCTLINFO_V3_W4_SEC_ENT6_KEYID); + + h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0], + DCTLINFO_V3_W5_SEC_ENT_VALID_V1); + h2c->m5 = cpu_to_le32(DCTLINFO_V3_W5_SEC_ENT_VALID_V1); + + h2c->w6 = le32_encode_bits(addr_cam->sec_ent[0], + DCTLINFO_V3_W6_SEC_ENT0_V2) | + le32_encode_bits(addr_cam->sec_ent[1], + DCTLINFO_V3_W6_SEC_ENT1_V2) | + le32_encode_bits(addr_cam->sec_ent[2], + DCTLINFO_V3_W6_SEC_ENT2_V2); + h2c->m6 = cpu_to_le32(DCTLINFO_V3_W6_SEC_ENT0_V2 | + DCTLINFO_V3_W6_SEC_ENT1_V2 | + DCTLINFO_V3_W6_SEC_ENT2_V2); + + h2c->w7 = le32_encode_bits(addr_cam->sec_ent[3], + DCTLINFO_V3_W7_SEC_ENT3_V2) | + le32_encode_bits(addr_cam->sec_ent[4], + DCTLINFO_V3_W7_SEC_ENT4_V2) | + le32_encode_bits(addr_cam->sec_ent[5], + DCTLINFO_V3_W7_SEC_ENT5_V2); + h2c->m7 = cpu_to_le32(DCTLINFO_V3_W7_SEC_ENT3_V2 | + DCTLINFO_V3_W7_SEC_ENT4_V2 | + DCTLINFO_V3_W7_SEC_ENT5_V2); + + h2c->w8 = le32_encode_bits(addr_cam->sec_ent[6], + DCTLINFO_V3_W8_SEC_ENT6_V2); + h2c->m8 = cpu_to_le32(DCTLINFO_V3_W8_SEC_ENT6_V2); + + if (rtw_wow->ptk_alg) { + h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8, + DCTLINFO_V3_W0_AES_IV_L); + h2c->m0 = cpu_to_le32(DCTLINFO_V3_W0_AES_IV_L); + + h2c->w1 = le32_encode_bits(ptk_tx_iv[4] | + ptk_tx_iv[5] << 8 | + ptk_tx_iv[6] << 16 | + ptk_tx_iv[7] << 24, + DCTLINFO_V3_W1_AES_IV_H); + h2c->m1 = cpu_to_le32(DCTLINFO_V3_W1_AES_IV_H); + + h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx, + DCTLINFO_V3_W4_SEC_KEY_ID); + h2c->m4 |= cpu_to_le32(DCTLINFO_V3_W4_SEC_KEY_ID); + } + + if (!is_mld) + return; + + if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) { + mld_sma = rtwvif->mac_addr; + mld_tma = vif->cfg.ap_addr; + mld_bssid = vif->cfg.ap_addr; + } else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE && sta) { + mld_sma = rtwvif->mac_addr; + mld_tma = sta->addr; + mld_bssid = rtwvif->mac_addr; + } else { + return; + } + + h2c->w9 = le32_encode_bits(mld_sma[0], DCTLINFO_V3_W9_MLD_SMA_0_V2) | + le32_encode_bits(mld_sma[1], DCTLINFO_V3_W9_MLD_SMA_1_V2) | + le32_encode_bits(mld_sma[2], DCTLINFO_V3_W9_MLD_SMA_2_V2) | + le32_encode_bits(mld_sma[3], DCTLINFO_V3_W9_MLD_SMA_3_V2); + h2c->m9 = cpu_to_le32(DCTLINFO_V3_W9_ALL); + + h2c->w10 = le32_encode_bits(mld_sma[4], DCTLINFO_V3_W10_MLD_SMA_4_V2) | + le32_encode_bits(mld_sma[5], DCTLINFO_V3_W10_MLD_SMA_5_V2) | + le32_encode_bits(mld_tma[0], DCTLINFO_V3_W10_MLD_TMA_0_V2) | + le32_encode_bits(mld_tma[1], DCTLINFO_V3_W10_MLD_TMA_1_V2); + h2c->m10 = cpu_to_le32(DCTLINFO_V3_W10_ALL); + + h2c->w11 = le32_encode_bits(mld_tma[2], DCTLINFO_V3_W11_MLD_TMA_2_V2) | + le32_encode_bits(mld_tma[3], DCTLINFO_V3_W11_MLD_TMA_3_V2) | + le32_encode_bits(mld_tma[4], DCTLINFO_V3_W11_MLD_TMA_4_V2) | + le32_encode_bits(mld_tma[5], DCTLINFO_V3_W11_MLD_TMA_5_V2); + h2c->m11 = cpu_to_le32(DCTLINFO_V3_W11_ALL); + + h2c->w12 = le32_encode_bits(mld_bssid[0], DCTLINFO_V3_W12_MLD_TA_BSSID_0_V2) | + le32_encode_bits(mld_bssid[1], DCTLINFO_V3_W12_MLD_TA_BSSID_1_V2) | + le32_encode_bits(mld_bssid[2], DCTLINFO_V3_W12_MLD_TA_BSSID_2_V2) | + le32_encode_bits(mld_bssid[3], DCTLINFO_V3_W12_MLD_TA_BSSID_3_V2); + h2c->m12 = cpu_to_le32(DCTLINFO_V3_W12_ALL); + + h2c->w13 = le32_encode_bits(mld_bssid[4], DCTLINFO_V3_W13_MLD_TA_BSSID_4_V2) | + le32_encode_bits(mld_bssid[5], DCTLINFO_V3_W13_MLD_TA_BSSID_5_V2); + h2c->m13 = cpu_to_le32(DCTLINFO_V3_W13_ALL); +} diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h new file mode 100644 index 000000000..22868f262 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -0,0 +1,481 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_CAM_H__ +#define __RTW89_CAM_H__ + +#include "core.h" + +#define RTW89_SEC_CAM_LEN 20 + +#define RTW89_BSSID_MATCH_ALL GENMASK(5, 0) +#define RTW89_BSSID_MATCH_5_BYTES GENMASK(4, 0) + +struct rtw89_h2c_addr_cam_v0 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; +} __packed; + +struct rtw89_h2c_addr_cam { + struct rtw89_h2c_addr_cam_v0 v0; + __le32 w15; +} __packed; + +#define ADDR_CAM_W1_IDX GENMASK(7, 0) +#define ADDR_CAM_W1_OFFSET GENMASK(15, 8) +#define ADDR_CAM_W1_LEN GENMASK(23, 16) +#define ADDR_CAM_W1_V1_IDX GENMASK(9, 0) +#define ADDR_CAM_W1_V1_OFFSET GENMASK(23, 16) +#define ADDR_CAM_W1_V1_LEN GENMASK(31, 24) +#define ADDR_CAM_W2_VALID BIT(0) +#define ADDR_CAM_W2_NET_TYPE GENMASK(2, 1) +#define ADDR_CAM_W2_BCN_HIT_COND GENMASK(4, 3) +#define ADDR_CAM_W2_HIT_RULE GENMASK(6, 5) +#define ADDR_CAM_W2_BB_SEL BIT(7) +#define ADDR_CAM_W2_ADDR_MASK GENMASK(13, 8) +#define ADDR_CAM_W2_MASK_SEL GENMASK(15, 14) +#define ADDR_CAM_W2_SMA_HASH GENMASK(23, 16) +#define ADDR_CAM_W2_TMA_HASH GENMASK(31, 24) +#define ADDR_CAM_W3_BSSID_CAM_IDX GENMASK(5, 0) +#define ADDR_CAM_W4_SMA0 GENMASK(7, 0) +#define ADDR_CAM_W4_SMA1 GENMASK(15, 8) +#define ADDR_CAM_W4_SMA2 GENMASK(23, 16) +#define ADDR_CAM_W4_SMA3 GENMASK(31, 24) +#define ADDR_CAM_W5_SMA4 GENMASK(7, 0) +#define ADDR_CAM_W5_SMA5 GENMASK(15, 8) +#define ADDR_CAM_W5_TMA0 GENMASK(23, 16) +#define ADDR_CAM_W5_TMA1 GENMASK(31, 24) +#define ADDR_CAM_W6_TMA2 GENMASK(7, 0) +#define ADDR_CAM_W6_TMA3 GENMASK(15, 8) +#define ADDR_CAM_W6_TMA4 GENMASK(23, 16) +#define ADDR_CAM_W6_TMA5 GENMASK(31, 24) +#define ADDR_CAM_W8_MACID GENMASK(7, 0) +#define ADDR_CAM_W8_PORT_INT GENMASK(10, 8) +#define ADDR_CAM_W8_TSF_SYNC GENMASK(13, 11) +#define ADDR_CAM_W8_TF_TRS BIT(14) +#define ADDR_CAM_W8_LSIG_TXOP BIT(15) +#define ADDR_CAM_W8_TGT_IND GENMASK(26, 24) +#define ADDR_CAM_W8_FRM_TGT_IND GENMASK(29, 27) +#define ADDR_CAM_W8_V1_MACID GENMASK(9, 0) +#define ADDR_CAM_W8_V1_PORT_INT GENMASK(18, 16) +#define ADDR_CAM_W8_V1_TSF_SYNC GENMASK(21, 19) +#define ADDR_CAM_W8_V1_TF_TRS BIT(22) +#define ADDR_CAM_W8_V1_LSIG_TXOP BIT(23) +#define ADDR_CAM_W8_V1_TB_RANGING BIT(24) +#define ADDR_CAM_W8_V1_TB_SENSING BIT(25) +#define ADDR_CAM_W8_V1_SENS_EN BIT(26) +#define ADDR_CAM_W9_AID12 GENMASK(11, 0) +#define ADDR_CAM_W9_AID12_0 GENMASK(7, 0) +#define ADDR_CAM_W9_AID12_1 GENMASK(11, 8) +#define ADDR_CAM_W9_WOL_PATTERN BIT(12) +#define ADDR_CAM_W9_WOL_UC BIT(13) +#define ADDR_CAM_W9_WOL_MAGIC BIT(14) +#define ADDR_CAM_W9_WAPI BIT(15) +#define ADDR_CAM_W9_SEC_ENT_MODE GENMASK(17, 16) +#define ADDR_CAM_W9_SEC_ENT0_KEYID GENMASK(19, 18) +#define ADDR_CAM_W9_SEC_ENT1_KEYID GENMASK(21, 20) +#define ADDR_CAM_W9_SEC_ENT2_KEYID GENMASK(23, 22) +#define ADDR_CAM_W9_SEC_ENT3_KEYID GENMASK(25, 24) +#define ADDR_CAM_W9_SEC_ENT4_KEYID GENMASK(27, 26) +#define ADDR_CAM_W9_SEC_ENT5_KEYID GENMASK(29, 28) +#define ADDR_CAM_W9_SEC_ENT6_KEYID GENMASK(31, 30) +#define ADDR_CAM_W10_SEC_ENT_VALID GENMASK(7, 0) +#define ADDR_CAM_W10_SEC_ENT0 GENMASK(15, 8) +#define ADDR_CAM_W10_SEC_ENT1 GENMASK(23, 16) +#define ADDR_CAM_W10_SEC_ENT2 GENMASK(31, 24) +#define ADDR_CAM_W11_SEC_ENT3 GENMASK(7, 0) +#define ADDR_CAM_W11_SEC_ENT4 GENMASK(15, 8) +#define ADDR_CAM_W11_SEC_ENT5 GENMASK(23, 16) +#define ADDR_CAM_W11_SEC_ENT6 GENMASK(31, 24) +#define ADDR_CAM_W12_BSSID_IDX GENMASK(7, 0) +#define ADDR_CAM_W12_BSSID_OFFSET GENMASK(15, 8) +#define ADDR_CAM_W12_BSSID_LEN GENMASK(23, 16) +#define ADDR_CAM_W13_BSSID_VALID BIT(0) +#define ADDR_CAM_W13_BSSID_BB_SEL BIT(1) +#define ADDR_CAM_W13_BSSID_MASK GENMASK(7, 2) +#define ADDR_CAM_W13_BSSID_BSS_COLOR GENMASK(13, 8) +#define ADDR_CAM_W13_BSSID_BSSID0 GENMASK(23, 16) +#define ADDR_CAM_W13_BSSID_BSSID1 GENMASK(31, 24) +#define ADDR_CAM_W14_BSSID_BSSID2 GENMASK(7, 0) +#define ADDR_CAM_W14_BSSID_BSSID3 GENMASK(15, 8) +#define ADDR_CAM_W14_BSSID_BSSID4 GENMASK(23, 16) +#define ADDR_CAM_W14_BSSID_BSSID5 GENMASK(31, 24) +#define ADDR_CAM_W15_UPD_MODE GENMASK(2, 0) + +struct rtw89_h2c_dctlinfo_ud_v1 { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; +} __packed; + +#define DCTLINFO_V1_C0_MACID GENMASK(6, 0) +#define DCTLINFO_V1_C0_OP BIT(7) + +#define DCTLINFO_V1_W0_QOS_FIELD_H GENMASK(7, 0) +#define DCTLINFO_V1_W0_HW_EXSEQ_MACID GENMASK(14, 8) +#define DCTLINFO_V1_W0_QOS_DATA BIT(15) +#define DCTLINFO_V1_W0_AES_IV_L GENMASK(31, 16) +#define DCTLINFO_V1_W0_ALL GENMASK(31, 0) +#define DCTLINFO_V1_W1_AES_IV_H GENMASK(31, 0) +#define DCTLINFO_V1_W1_ALL GENMASK(31, 0) +#define DCTLINFO_V1_W2_SEQ0 GENMASK(11, 0) +#define DCTLINFO_V1_W2_SEQ1 GENMASK(23, 12) +#define DCTLINFO_V1_W2_AMSDU_MAX_LEN GENMASK(26, 24) +#define DCTLINFO_V1_W2_STA_AMSDU_EN BIT(27) +#define DCTLINFO_V1_W2_CHKSUM_OFLD_EN BIT(28) +#define DCTLINFO_V1_W2_WITH_LLC BIT(29) +#define DCTLINFO_V1_W2_ALL GENMASK(29, 0) +#define DCTLINFO_V1_W3_SEQ2 GENMASK(11, 0) +#define DCTLINFO_V1_W3_SEQ3 GENMASK(23, 12) +#define DCTLINFO_V1_W3_TGT_IND GENMASK(27, 24) +#define DCTLINFO_V1_W3_TGT_IND_EN BIT(28) +#define DCTLINFO_V1_W3_HTC_LB GENMASK(31, 29) +#define DCTLINFO_V1_W3_ALL GENMASK(31, 0) +#define DCTLINFO_V1_W4_MHDR_LEN GENMASK(4, 0) +#define DCTLINFO_V1_W4_VLAN_TAG_VALID BIT(5) +#define DCTLINFO_V1_W4_VLAN_TAG_SEL GENMASK(7, 6) +#define DCTLINFO_V1_W4_HTC_ORDER BIT(8) +#define DCTLINFO_V1_W4_SEC_KEY_ID GENMASK(10, 9) +#define DCTLINFO_V1_W4_WAPI BIT(15) +#define DCTLINFO_V1_W4_SEC_ENT_MODE GENMASK(17, 16) +#define DCTLINFO_V1_W4_SEC_ENT0_KEYID GENMASK(19, 18) +#define DCTLINFO_V1_W4_SEC_ENT1_KEYID GENMASK(21, 20) +#define DCTLINFO_V1_W4_SEC_ENT2_KEYID GENMASK(23, 22) +#define DCTLINFO_V1_W4_SEC_ENT3_KEYID GENMASK(25, 24) +#define DCTLINFO_V1_W4_SEC_ENT4_KEYID GENMASK(27, 26) +#define DCTLINFO_V1_W4_SEC_ENT5_KEYID GENMASK(29, 28) +#define DCTLINFO_V1_W4_SEC_ENT6_KEYID GENMASK(31, 30) +#define DCTLINFO_V1_W4_ALL (GENMASK(31, 15) | GENMASK(10, 0)) +#define DCTLINFO_V1_W5_SEC_ENT_VALID GENMASK(7, 0) +#define DCTLINFO_V1_W5_SEC_ENT0 GENMASK(15, 8) +#define DCTLINFO_V1_W5_SEC_ENT1 GENMASK(23, 16) +#define DCTLINFO_V1_W5_SEC_ENT2 GENMASK(31, 24) +#define DCTLINFO_V1_W5_ALL GENMASK(31, 0) +#define DCTLINFO_V1_W6_SEC_ENT3 GENMASK(7, 0) +#define DCTLINFO_V1_W6_SEC_ENT4 GENMASK(15, 8) +#define DCTLINFO_V1_W6_SEC_ENT5 GENMASK(23, 16) +#define DCTLINFO_V1_W6_SEC_ENT6 GENMASK(31, 24) +#define DCTLINFO_V1_W6_ALL GENMASK(31, 0) + +struct rtw89_h2c_dctlinfo_ud_v2 { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define DCTLINFO_V2_C0_MACID GENMASK(6, 0) +#define DCTLINFO_V2_C0_OP BIT(7) + +#define DCTLINFO_V2_W0_QOS_FIELD_H GENMASK(7, 0) +#define DCTLINFO_V2_W0_HW_EXSEQ_MACID GENMASK(14, 8) +#define DCTLINFO_V2_W0_QOS_DATA BIT(15) +#define DCTLINFO_V2_W0_AES_IV_L GENMASK(31, 16) +#define DCTLINFO_V2_W0_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W1_AES_IV_H GENMASK(31, 0) +#define DCTLINFO_V2_W1_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W2_SEQ0 GENMASK(11, 0) +#define DCTLINFO_V2_W2_SEQ1 GENMASK(23, 12) +#define DCTLINFO_V2_W2_AMSDU_MAX_LEN GENMASK(26, 24) +#define DCTLINFO_V2_W2_STA_AMSDU_EN BIT(27) +#define DCTLINFO_V2_W2_CHKSUM_OFLD_EN BIT(28) +#define DCTLINFO_V2_W2_WITH_LLC BIT(29) +#define DCTLINFO_V2_W2_NAT25_EN BIT(30) +#define DCTLINFO_V2_W2_IS_MLD BIT(31) +#define DCTLINFO_V2_W2_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W3_SEQ2 GENMASK(11, 0) +#define DCTLINFO_V2_W3_SEQ3 GENMASK(23, 12) +#define DCTLINFO_V2_W3_TGT_IND GENMASK(27, 24) +#define DCTLINFO_V2_W3_TGT_IND_EN BIT(28) +#define DCTLINFO_V2_W3_HTC_LB GENMASK(31, 29) +#define DCTLINFO_V2_W3_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W4_VLAN_TAG_SEL GENMASK(7, 5) +#define DCTLINFO_V2_W4_HTC_ORDER BIT(8) +#define DCTLINFO_V2_W4_SEC_KEY_ID GENMASK(10, 9) +#define DCTLINFO_V2_W4_VLAN_RX_DYNAMIC_PCP_EN BIT(11) +#define DCTLINFO_V2_W4_VLAN_RX_PKT_DROP BIT(12) +#define DCTLINFO_V2_W4_VLAN_RX_VALID BIT(13) +#define DCTLINFO_V2_W4_VLAN_TX_VALID BIT(14) +#define DCTLINFO_V2_W4_WAPI BIT(15) +#define DCTLINFO_V2_W4_SEC_ENT_MODE GENMASK(17, 16) +#define DCTLINFO_V2_W4_SEC_ENT0_KEYID GENMASK(19, 18) +#define DCTLINFO_V2_W4_SEC_ENT1_KEYID GENMASK(21, 20) +#define DCTLINFO_V2_W4_SEC_ENT2_KEYID GENMASK(23, 22) +#define DCTLINFO_V2_W4_SEC_ENT3_KEYID GENMASK(25, 24) +#define DCTLINFO_V2_W4_SEC_ENT4_KEYID GENMASK(27, 26) +#define DCTLINFO_V2_W4_SEC_ENT5_KEYID GENMASK(29, 28) +#define DCTLINFO_V2_W4_SEC_ENT6_KEYID GENMASK(31, 30) +#define DCTLINFO_V2_W4_ALL GENMASK(31, 5) +#define DCTLINFO_V2_W5_SEC_ENT7_KEYID GENMASK(1, 0) +#define DCTLINFO_V2_W5_SEC_ENT8_KEYID GENMASK(3, 2) +#define DCTLINFO_V2_W5_SEC_ENT_VALID_V1 GENMASK(23, 8) +#define DCTLINFO_V2_W5_SEC_ENT0_V1 GENMASK(31, 24) +#define DCTLINFO_V2_W5_ALL (GENMASK(31, 8) | GENMASK(3, 0)) +#define DCTLINFO_V2_W6_SEC_ENT1_V1 GENMASK(7, 0) +#define DCTLINFO_V2_W6_SEC_ENT2_V1 GENMASK(15, 8) +#define DCTLINFO_V2_W6_SEC_ENT3_V1 GENMASK(23, 16) +#define DCTLINFO_V2_W6_SEC_ENT4_V1 GENMASK(31, 24) +#define DCTLINFO_V2_W6_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W7_SEC_ENT5_V1 GENMASK(7, 0) +#define DCTLINFO_V2_W7_SEC_ENT6_V1 GENMASK(15, 8) +#define DCTLINFO_V2_W7_SEC_ENT7 GENMASK(23, 16) +#define DCTLINFO_V2_W7_SEC_ENT8 GENMASK(31, 24) +#define DCTLINFO_V2_W7_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W8_MLD_SMA_0 GENMASK(7, 0) +#define DCTLINFO_V2_W8_MLD_SMA_1 GENMASK(15, 8) +#define DCTLINFO_V2_W8_MLD_SMA_2 GENMASK(23, 16) +#define DCTLINFO_V2_W8_MLD_SMA_3 GENMASK(31, 24) +#define DCTLINFO_V2_W8_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W9_MLD_SMA_4 GENMASK(7, 0) +#define DCTLINFO_V2_W9_MLD_SMA_5 GENMASK(15, 8) +#define DCTLINFO_V2_W9_MLD_TMA_0 GENMASK(23, 16) +#define DCTLINFO_V2_W9_MLD_TMA_1 GENMASK(31, 24) +#define DCTLINFO_V2_W9_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W10_MLD_TMA_2 GENMASK(7, 0) +#define DCTLINFO_V2_W10_MLD_TMA_3 GENMASK(15, 8) +#define DCTLINFO_V2_W10_MLD_TMA_4 GENMASK(23, 16) +#define DCTLINFO_V2_W10_MLD_TMA_5 GENMASK(31, 24) +#define DCTLINFO_V2_W10_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W11_MLD_BSSID_0 GENMASK(7, 0) +#define DCTLINFO_V2_W11_MLD_BSSID_1 GENMASK(15, 8) +#define DCTLINFO_V2_W11_MLD_BSSID_2 GENMASK(23, 16) +#define DCTLINFO_V2_W11_MLD_BSSID_3 GENMASK(31, 24) +#define DCTLINFO_V2_W11_ALL GENMASK(31, 0) +#define DCTLINFO_V2_W12_MLD_BSSID_4 GENMASK(7, 0) +#define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8) +#define DCTLINFO_V2_W12_ALL GENMASK(15, 0) + +struct rtw89_h2c_dctlinfo_ud_v3 { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define DCTLINFO_V3_C0_MACID GENMASK(15, 0) +#define DCTLINFO_V3_C0_OP BIT(16) + +#define DCTLINFO_V3_W0_QOS_FIELD_H GENMASK(7, 0) +#define DCTLINFO_V3_W0_HW_EXSEQ_MACID GENMASK(14, 8) +#define DCTLINFO_V3_W0_QOS_DATA BIT(15) +#define DCTLINFO_V3_W0_AES_IV_L GENMASK(31, 16) +#define DCTLINFO_V3_W0_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W1_AES_IV_H GENMASK(31, 0) +#define DCTLINFO_V3_W1_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W2_SEQ0 GENMASK(11, 0) +#define DCTLINFO_V3_W2_SEQ1 GENMASK(23, 12) +#define DCTLINFO_V3_W2_AMSDU_MAX_LEN GENMASK(26, 24) +#define DCTLINFO_V3_W2_STA_AMSDU_EN BIT(27) +#define DCTLINFO_V3_W2_CHKSUM_OFLD_EN BIT(28) +#define DCTLINFO_V3_W2_WITH_LLC BIT(29) +#define DCTLINFO_V3_W2_NAT25_EN BIT(30) +#define DCTLINFO_V3_W2_IS_MLD BIT(31) +#define DCTLINFO_V3_W2_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W3_SEQ2 GENMASK(11, 0) +#define DCTLINFO_V3_W3_SEQ3 GENMASK(23, 12) +#define DCTLINFO_V3_W3_TGT_IND GENMASK(27, 24) +#define DCTLINFO_V3_W3_TGT_IND_EN BIT(28) +#define DCTLINFO_V3_W3_HTC_LB GENMASK(31, 29) +#define DCTLINFO_V3_W3_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W4_VLAN_TAG_SEL GENMASK(7, 5) +#define DCTLINFO_V3_W4_HTC_ORDER BIT(8) +#define DCTLINFO_V3_W4_SEC_KEY_ID GENMASK(10, 9) +#define DCTLINFO_V3_W4_VLAN_RX_DYNAMIC_PCP_EN BIT(11) +#define DCTLINFO_V3_W4_VLAN_RX_PKT_DROP BIT(12) +#define DCTLINFO_V3_W4_VLAN_RX_VALID BIT(13) +#define DCTLINFO_V3_W4_VLAN_TX_VALID BIT(14) +#define DCTLINFO_V3_W4_WAPI BIT(15) +#define DCTLINFO_V3_W4_SEC_ENT_MODE GENMASK(17, 16) +#define DCTLINFO_V3_W4_SEC_ENT0_KEYID GENMASK(19, 18) +#define DCTLINFO_V3_W4_SEC_ENT1_KEYID GENMASK(21, 20) +#define DCTLINFO_V3_W4_SEC_ENT2_KEYID GENMASK(23, 22) +#define DCTLINFO_V3_W4_SEC_ENT3_KEYID GENMASK(25, 24) +#define DCTLINFO_V3_W4_SEC_ENT4_KEYID GENMASK(27, 26) +#define DCTLINFO_V3_W4_SEC_ENT5_KEYID GENMASK(29, 28) +#define DCTLINFO_V3_W4_SEC_ENT6_KEYID GENMASK(31, 30) +#define DCTLINFO_V3_W4_ALL GENMASK(31, 5) +#define DCTLINFO_V3_W5_SEC_ENT7_KEYID GENMASK(1, 0) +#define DCTLINFO_V3_W5_SEC_ENT8_KEYID GENMASK(3, 2) +#define DCTLINFO_V3_W5_SEC_ENT_VALID_V1 GENMASK(23, 8) +#define DCTLINFO_V3_W5_ALL (GENMASK(23, 8) | GENMASK(3, 0)) +#define DCTLINFO_V3_W6_SEC_ENT0_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W6_SEC_ENT1_V2 GENMASK(18, 10) +#define DCTLINFO_V3_W6_SEC_ENT2_V2 GENMASK(28, 20) +#define DCTLINFO_V3_W6_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W7_SEC_ENT3_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W7_SEC_ENT4_V2 GENMASK(18, 10) +#define DCTLINFO_V3_W7_SEC_ENT5_V2 GENMASK(28, 20) +#define DCTLINFO_V3_W7_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W8_SEC_ENT6_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W8_SEC_ENT7_V1 GENMASK(18, 10) +#define DCTLINFO_V3_W8_SEC_ENT8_V1 GENMASK(28, 20) +#define DCTLINFO_V3_W8_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W9_MLD_SMA_0_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W9_MLD_SMA_1_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W9_MLD_SMA_2_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W9_MLD_SMA_3_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W9_MLD_SMA_L_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W9_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W10_MLD_SMA_4_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W10_MLD_SMA_5_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W10_MLD_SMA_H_V2 GENMASK(15, 0) +#define DCTLINFO_V3_W10_MLD_TMA_0_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W10_MLD_TMA_1_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W10_MLD_TMA_L_V2 GENMASK(31, 16) +#define DCTLINFO_V3_W10_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W11_MLD_TMA_2_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W11_MLD_TMA_3_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W11_MLD_TMA_4_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W11_MLD_TMA_5_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W11_MLD_TMA_H_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W11_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_0_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_1_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_2_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_3_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_L_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W12_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_4_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_5_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_H_V2 GENMASK(15, 0) +#define DCTLINFO_V3_W13_HW_EXSEQ_MACID_V1 GENMASK(24, 16) +#define DCTLINFO_V3_W13_ALL GENMASK(24, 0) + +int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); +void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); +int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, + struct rtw89_addr_cam_entry *addr_cam, + const struct rtw89_bssid_cam_entry *bssid_cam); +void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev, + struct rtw89_addr_cam_entry *addr_cam); +int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_bssid_cam_entry *bssid_cam, + const u8 *bssid); +void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev, + struct rtw89_bssid_cam_entry *bssid_cam); +void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + const u8 *scan_mac_addr, + struct rtw89_h2c_addr_cam_v0 *h2c); +void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v1 *h2c); +void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v2 *h2c); +void rtw89_cam_fill_dctl_sec_cam_info_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v3 *h2c); +int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_addr_cam_v0 *h2c); +int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + bool inform_fw); +void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev); +int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + u8 sec_cam_idx); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c new file mode 100644 index 000000000..6f11335b4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -0,0 +1,3535 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2020-2022 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "sar.h" +#include "util.h" + +static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx1, + enum rtw89_chanctx_idx idx2); + +static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band, + u8 center_chan) +{ + switch (band) { + default: + case RTW89_BAND_2G: + switch (center_chan) { + default: + case 1 ... 14: + return RTW89_CH_2G; + } + case RTW89_BAND_5G: + switch (center_chan) { + default: + case 36 ... 64: + return RTW89_CH_5G_BAND_1; + case 100 ... 144: + return RTW89_CH_5G_BAND_3; + case 149 ... 177: + return RTW89_CH_5G_BAND_4; + } + case RTW89_BAND_6G: + switch (center_chan) { + default: + case 1 ... 29: + return RTW89_CH_6G_BAND_IDX0; + case 33 ... 61: + return RTW89_CH_6G_BAND_IDX1; + case 65 ... 93: + return RTW89_CH_6G_BAND_IDX2; + case 97 ... 125: + return RTW89_CH_6G_BAND_IDX3; + case 129 ... 157: + return RTW89_CH_6G_BAND_IDX4; + case 161 ... 189: + return RTW89_CH_6G_BAND_IDX5; + case 193 ... 221: + return RTW89_CH_6G_BAND_IDX6; + case 225 ... 253: + return RTW89_CH_6G_BAND_IDX7; + } + } +} + +static enum rtw89_tx_comp_band rtw89_get_tx_comp_band(enum rtw89_band band, + u8 center_chan) +{ + switch (band) { + default: + case RTW89_BAND_2G: + return RTW89_TX_COMP_BAND_2GHZ; + case RTW89_BAND_5G: + if (center_chan < 149) + return RTW89_TX_COMP_BAND_5GHZ_L; + else + return RTW89_TX_COMP_BAND_5GHZ_H; + case RTW89_BAND_6G: + if (center_chan < 65) + return RTW89_TX_COMP_BAND_5GHZ_H; + else if (center_chan < 193) + return RTW89_TX_COMP_BAND_6GHZ_M; + else + return RTW89_TX_COMP_BAND_6GHZ_UH; + } +} + +static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw, + u32 center_freq, + u32 primary_freq) +{ + u8 primary_chan_idx; + u32 offset; + + switch (bw) { + default: + case RTW89_CHANNEL_WIDTH_20: + primary_chan_idx = RTW89_SC_DONT_CARE; + break; + case RTW89_CHANNEL_WIDTH_40: + if (primary_freq > center_freq) + primary_chan_idx = RTW89_SC_20_UPPER; + else + primary_chan_idx = RTW89_SC_20_LOWER; + break; + case RTW89_CHANNEL_WIDTH_80: + case RTW89_CHANNEL_WIDTH_160: + if (primary_freq > center_freq) { + offset = (primary_freq - center_freq - 10) / 20; + primary_chan_idx = RTW89_SC_20_UPPER + offset * 2; + } else { + offset = (center_freq - primary_freq - 10) / 20; + primary_chan_idx = RTW89_SC_20_LOWER + offset * 2; + } + break; + } + + return primary_chan_idx; +} + +static u8 rtw89_get_primary_sb_idx(u8 central_ch, u8 pri_ch, + enum rtw89_bandwidth bw) +{ + static const u8 prisb_cal_ofst[RTW89_CHANNEL_WIDTH_ORDINARY_NUM] = { + 0, 2, 6, 14, 30 + }; + + if (bw >= RTW89_CHANNEL_WIDTH_ORDINARY_NUM) + return 0; + + return (prisb_cal_ofst[bw] + pri_ch - central_ch) / 4; +} + +void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan, + enum rtw89_band band, enum rtw89_bandwidth bandwidth) +{ + enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); + u32 center_freq, primary_freq; + + memset(chan, 0, sizeof(*chan)); + chan->channel = center_chan; + chan->primary_channel = primary_chan; + chan->band_type = band; + chan->band_width = bandwidth; + + center_freq = ieee80211_channel_to_frequency(center_chan, nl_band); + primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band); + + chan->freq = center_freq; + chan->subband_type = rtw89_get_subband_type(band, center_chan); + chan->tx_comp_band = rtw89_get_tx_comp_band(band, center_chan); + chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq, + primary_freq); + chan->pri_sb_idx = rtw89_get_primary_sb_idx(center_chan, primary_chan, + bandwidth); + chan->rfsi_band = band == RTW89_BAND_2G ? RFSI_CTRL_BAND_2GHZ : + RFSI_CTRL_BAND_5_6GHZ; +} + +static void _rtw89_chan_update_punctured(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_chan_def *chandef) +{ + struct ieee80211_bss_conf *bss_conf; + + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) + return; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->eht_support) { + rcu_read_unlock(); + return; + } + + rcu_read_unlock(); + + rtw89_chip_h2c_punctured_cmac_tbl(rtwdev, rtwvif_link, chandef->punctured); +} + +static void rtw89_chan_update_punctured(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct cfg80211_chan_def *chandef) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + if (!rtwvif_link->chanctx_assigned || + rtwvif_link->chanctx_idx != idx) + continue; + + _rtw89_chan_update_punctured(rtwdev, rtwvif_link, chandef); + } + } +} + +bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct rtw89_chan *new) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_chan *chan = &hal->chanctx[idx].chan; + struct rtw89_chan_rcd *rcd = &hal->chanctx[idx].rcd; + bool band_changed; + + rcd->prev_primary_channel = chan->primary_channel; + rcd->prev_band_type = chan->band_type; + band_changed = new->band_type != chan->band_type; + rcd->band_changed = band_changed; + + *chan = *new; + return band_changed; +} + +int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev, + int (*iterator)(const struct rtw89_chan *chan, + void *data), + void *data) +{ + struct rtw89_hal *hal = &rtwdev->hal; + const struct rtw89_chan *chan; + int ret; + u8 idx; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { + chan = rtw89_chan_get(rtwdev, idx); + ret = iterator(chan, data); + if (ret) + return ret; + } + + return 0; +} + +static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct cfg80211_chan_def *chandef) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + hal->chanctx[idx].chandef = *chandef; +} + +void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct cfg80211_chan_def *chandef) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + if (!chandef) { + clear_bit(idx, hal->entity_map); + return; + } + + __rtw89_config_entity_chandef(rtwdev, idx, chandef); + set_bit(idx, hal->entity_map); +} + +void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_chan_def *chandef) +{ + enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_chanctx_idx cur; + + if (chandef) { + cur = atomic_cmpxchg(&hal->roc_chanctx_idx, + RTW89_CHANCTX_IDLE, idx); + if (cur != RTW89_CHANCTX_IDLE) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "ROC still processing on entity %d\n", idx); + return; + } + + hal->roc_chandef = *chandef; + } else { + cur = atomic_cmpxchg(&hal->roc_chanctx_idx, idx, + RTW89_CHANCTX_IDLE); + if (cur == idx) + return; + + if (cur == RTW89_CHANCTX_IDLE) + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "ROC already finished on entity %d\n", idx); + else + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "ROC is processing on entity %d\n", cur); + } +} + +static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev) +{ + struct cfg80211_chan_def chandef = {0}; + + rtw89_get_default_chandef(&chandef); + __rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef); +} + +void rtw89_entity_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; + int i, j; + + hal->entity_pause = false; + bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX); + bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES); + atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE); + + INIT_LIST_HEAD(&mgnt->active_list); + + for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) { + for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++) + mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE; + } + + hal->entity_force_hw = RTW89_PHY_NUM; + + rtw89_config_default_chandef(rtwdev); +} + +static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + if (rtwvif_link->chanctx_assigned) + return true; + + return false; +} + +static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev, + struct rtw89_entity_weight *w) +{ + struct rtw89_hal *hal = &rtwdev->hal; + const struct rtw89_chanctx_cfg *cfg; + struct rtw89_vif *rtwvif; + int idx; + + w->registered_chanctxs = bitmap_weight(hal->entity_map, NUM_OF_RTW89_CHANCTX); + + for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { + cfg = hal->chanctx[idx].cfg; + if (!cfg) { + /* doesn't run with chanctx ops; one channel at most */ + w->active_chanctxs = 1; + break; + } + + if (cfg->ref_count > 0) + w->active_chanctxs++; + } + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (rtw89_vif_is_active_role(rtwvif)) + w->active_roles++; + } +} + +static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_vif_link *cur; + + if (unlikely(!rtwvif_link->chanctx_assigned)) + return; + + cur = rtw89_get_designated_link(rtwvif); + if (unlikely(!cur) || !cur->chanctx_assigned) + return; + + if (cur == rtwvif_link) + return; + + rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx); +} + +static u8 rtw89_entity_role_get_index(struct rtw89_dev *rtwdev) +{ + enum rtw89_entity_mode mode; + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + default: + WARN(1, "Invalid ent mode: %d\n", mode); + fallthrough; + case RTW89_ENTITY_MODE_SCC_OR_SMLD: + case RTW89_ENTITY_MODE_MCC: + return 0; + case RTW89_ENTITY_MODE_MCC_PREPARE: + return 1; + } +} + +bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + switch (rtwdev->mlo_dbcc_mode) { + case MLO_2_PLUS_0_1RF: + return phy_idx == RTW89_PHY_0; + case MLO_0_PLUS_2_1RF: + return phy_idx == RTW89_PHY_1; + default: + return false; + } +} + +void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtwdev->hal.entity_force_hw = phy_idx; + + if (phy_idx != RTW89_PHY_NUM) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: %d\n", __func__, phy_idx); + else + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: (none)\n", __func__); +} + +void rtw89_entity_get_conf(struct rtw89_dev *rtwdev, struct rtw89_entity_conf *conf) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + enum rtw89_chanctx_idx idxes[ARRAY_SIZE(conf->chans)]; + struct rtw89_vif *role; + u8 ridx; + int i; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + memset(conf, 0, sizeof(*conf)); + + ridx = rtw89_entity_role_get_index(rtwdev); + role = mgnt->active_roles[ridx]; + if (role) { + struct ieee80211_vif *vif = rtwvif_to_vif(role); + + conf->is_mld = ieee80211_vif_is_mld(vif); + conf->en_emlsr = role->mlo_mode == RTW89_MLO_MODE_EMLSR; + } + + for (i = 0; i < ARRAY_SIZE(idxes); i++) + idxes[i] = RTW89_CHANCTX_IDLE; + + switch (rtwdev->mlo_dbcc_mode) { + default: + case MLO_2_PLUS_0_1RF: + set_bit(0, conf->hw_bitmap); + idxes[0] = mgnt->chanctx_tbl[ridx][0]; + idxes[1] = idxes[0]; + break; + case MLO_0_PLUS_2_1RF: + set_bit(1, conf->hw_bitmap); + idxes[1] = mgnt->chanctx_tbl[ridx][1]; + idxes[0] = idxes[1]; + break; + case MLO_1_PLUS_1_1RF: + set_bit(0, conf->hw_bitmap); + set_bit(1, conf->hw_bitmap); + idxes[0] = mgnt->chanctx_tbl[ridx][0]; + idxes[1] = mgnt->chanctx_tbl[ridx][1]; + break; + } + + for (i = 0; i < ARRAY_SIZE(idxes); i++) { + if (idxes[i] == RTW89_CHANCTX_IDLE) + idxes[i] = RTW89_CHANCTX_0; + + conf->chans[i] = rtw89_chan_get(rtwdev, idxes[i]); + } +} +EXPORT_SYMBOL(rtw89_entity_get_conf); + +static enum rtw89_mlo_dbcc_mode +rtw89_entity_sel_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws) +{ + if (rtwdev->chip->chip_gen != RTW89_CHIP_BE) + return MLO_DBCC_NOT_SUPPORT; + + switch (rtwdev->hal.entity_force_hw) { + case RTW89_PHY_0: + return MLO_2_PLUS_0_1RF; + case RTW89_PHY_1: + return MLO_0_PLUS_2_1RF; + default: + break; + } + + switch (active_hws) { + case BIT(0): + return MLO_2_PLUS_0_1RF; + case BIT(1): + return MLO_0_PLUS_2_1RF; + case BIT(0) | BIT(1): + default: + return MLO_1_PLUS_1_1RF; + } +} + +static void rtw89_entity_recalc_mlo_dbcc_mode(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + enum rtw89_mlo_dbcc_mode mode; + struct rtw89_vif *role; + u8 active_hws = 0; + u8 ridx; + + ridx = rtw89_entity_role_get_index(rtwdev); + role = mgnt->active_roles[ridx]; + if (role) { + struct rtw89_vif_link *link; + int i; + + for (i = 0; i < role->links_inst_valid_num; i++) { + link = rtw89_vif_get_link_inst(role, i); + if (!link || !link->chanctx_assigned) + continue; + + active_hws |= BIT(i); + } + } + + mode = rtw89_entity_sel_mlo_dbcc_mode(rtwdev, active_hws); + rtwdev->mlo_dbcc_mode = mode; + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "recalc mlo dbcc mode to %d\n", mode); +} + +static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; + struct rtw89_vif_link *link; + struct rtw89_vif *role; + u8 pos = 0; + int i, j; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) + mgnt->active_roles[i] = NULL; + + for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) { + for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++) + mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE; + } + + /* To be consistent with legacy behavior, expect the first active role + * which uses RTW89_CHANCTX_0 to put at position 0 and its designated + * link take RTW89_CHANCTX_0. (normalizing) + */ + list_for_each_entry(role, &mgnt->active_list, mgnt_entry) { + for (i = 0; i < role->links_inst_valid_num; i++) { + link = rtw89_vif_get_link_inst(role, i); + if (!link || !link->chanctx_assigned) + continue; + + if (link->chanctx_idx == RTW89_CHANCTX_0) { + rtw89_normalize_link_chanctx(rtwdev, link); + + list_del(&role->mgnt_entry); + list_add(&role->mgnt_entry, &mgnt->active_list); + goto fill; + } + } + } + +fill: + list_for_each_entry(role, &mgnt->active_list, mgnt_entry) { + if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) { + rtw89_warn(rtwdev, + "%s: active roles are over max iface num\n", + __func__); + break; + } + + for (i = 0; i < role->links_inst_valid_num; i++) { + link = rtw89_vif_get_link_inst(role, i); + if (!link || !link->chanctx_assigned) + continue; + + mgnt->chanctx_tbl[pos][i] = link->chanctx_idx; + } + + mgnt->active_roles[pos++] = role; + } +} + +enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev) +{ + DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {}; + struct rtw89_hal *hal = &rtwdev->hal; + const struct cfg80211_chan_def *chandef; + struct rtw89_entity_weight w = {}; + enum rtw89_entity_mode mode; + struct rtw89_chan chan; + u8 idx; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX); + + rtw89_entity_calculate_weight(rtwdev, &w); + switch (w.active_chanctxs) { + default: + rtw89_warn(rtwdev, "unknown ent chanctxs weight: %d\n", + w.active_chanctxs); + bitmap_zero(recalc_map, NUM_OF_RTW89_CHANCTX); + fallthrough; + case 0: + if (!w.registered_chanctxs) + rtw89_config_default_chandef(rtwdev); + set_bit(RTW89_CHANCTX_0, recalc_map); + fallthrough; + case 1: + mode = RTW89_ENTITY_MODE_SCC_OR_SMLD; + break; + case 2 ... NUM_OF_RTW89_CHANCTX: + if (w.active_roles == 1) { + mode = RTW89_ENTITY_MODE_SCC_OR_SMLD; + break; + } + + if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "unhandled ent: %d chanctxs %d roles\n", + w.active_chanctxs, w.active_roles); + return RTW89_ENTITY_MODE_UNHANDLED; + } + + mode = rtw89_get_entity_mode(rtwdev); + if (mode == RTW89_ENTITY_MODE_MCC) + break; + + mode = RTW89_ENTITY_MODE_MCC_PREPARE; + break; + } + + for_each_set_bit(idx, recalc_map, NUM_OF_RTW89_CHANCTX) { + chandef = rtw89_chandef_get(rtwdev, idx); + rtw89_get_channel_params(chandef, &chan); + if (chan.channel == 0) { + WARN(1, "Invalid channel on chanctx %d\n", idx); + return RTW89_ENTITY_MODE_INVALID; + } + + rtw89_assign_entity_chan(rtwdev, idx, &chan); + } + + rtw89_entity_recalc_mgnt_roles(rtwdev); + + if (hal->entity_pause) + return rtw89_get_entity_mode(rtwdev); + + rtw89_set_entity_mode(rtwdev, mode); + + rtw89_entity_recalc_mlo_dbcc_mode(rtwdev); + + return mode; +} + +static void rtw89_chanctx_notify(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_chanctx_listener *listener = chip->chanctx_listener; + int i; + + if (!listener) + return; + + for (i = 0; i < NUM_OF_RTW89_CHANCTX_CALLBACKS; i++) { + if (!listener->callbacks[i]) + continue; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "chanctx notify listener: cb %d, state %d\n", + i, state); + + listener->callbacks[i](rtwdev, state); + } +} + +static bool rtw89_concurrent_via_mrc(struct rtw89_dev *rtwdev) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + + return chip_gen == RTW89_CHIP_BE; +} + +/* This function centrally manages how MCC roles are sorted and iterated. + * And, it guarantees that ordered_idx is less than NUM_OF_RTW89_MCC_ROLES. + * So, if data needs to pass an array for ordered_idx, the array can declare + * with NUM_OF_RTW89_MCC_ROLES. Besides, the entire iteration will stop + * immediately as long as iterator returns a non-zero value. + */ +static +int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev, + int (*iterator)(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data), + void *data) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role * const roles[] = { + &mcc->role_ref, + &mcc->role_aux, + }; + unsigned int idx; + int ret; + + BUILD_BUG_ON(ARRAY_SIZE(roles) != NUM_OF_RTW89_MCC_ROLES); + + for (idx = 0; idx < NUM_OF_RTW89_MCC_ROLES; idx++) { + ret = iterator(rtwdev, roles[idx], idx, data); + if (ret) + return ret; + } + + return 0; +} + +static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *role, u64 tsf) +{ + struct rtw89_vif_link *rtwvif_link = role->rtwvif_link; + u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval); + u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); + u32 remainder; + + if (role->is_go) { + sync_tsf = 0; + } else if (tsf < sync_tsf) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC get tbtt ofst: tsf might not update yet\n"); + sync_tsf = 0; + } + + div_u64_rem(tsf - sync_tsf, bcn_intvl_us, &remainder); + + return remainder; +} + +static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mac_mcc_tsf_rpt rpt = {}; + struct rtw89_fw_mcc_tsf_req req = {}; + int ret; + + req.group = mcc->group; + req.macid_x = ref->rtwvif_link->mac_id; + req.macid_y = aux->rtwvif_link->mac_id; + ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to request tsf: %d\n", ret); + return ret; + } + + *tsf_ref = (u64)rpt.tsf_x_high << 32 | rpt.tsf_x_low; + *tsf_aux = (u64)rpt.tsf_y_high << 32 | rpt.tsf_y_low; + + return 0; +} + +static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_fw_mrc_req_tsf_arg arg = {}; + struct rtw89_mac_mrc_tsf_rpt rpt = {}; + int ret; + + BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES); + + arg.num = 2; + arg.infos[0].band = ref->rtwvif_link->mac_idx; + arg.infos[0].port = ref->rtwvif_link->port; + arg.infos[1].band = aux->rtwvif_link->mac_idx; + arg.infos[1].port = aux->rtwvif_link->port; + + ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to request tsf: %d\n", ret); + return ret; + } + + *tsf_ref = rpt.tsfs[0]; + *tsf_aux = rpt.tsfs[1]; + + return 0; +} + +static u16 rtw89_mcc_get_bcn_ofst(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval); + u32 tbtt_ofst_ref, tbtt_ofst_aux; + u64 tsf_ref, tsf_aux; + int ret; + + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_req_tsf(rtwdev, &tsf_ref, &tsf_aux); + else + ret = __mcc_fw_req_tsf(rtwdev, &tsf_ref, &tsf_aux); + + if (ret) + return RTW89_MCC_DFLT_BCN_OFST_TIME; + + tbtt_ofst_ref = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf_ref); + tbtt_ofst_aux = rtw89_mcc_get_tbtt_ofst(rtwdev, aux, tsf_aux); + + while (tbtt_ofst_ref < tbtt_ofst_aux) + tbtt_ofst_ref += bcn_intvl_ref_us; + + return (tbtt_ofst_ref - tbtt_ofst_aux) / 1024; +} + +static +void rtw89_mcc_role_fw_macid_bitmap_set_bit(struct rtw89_mcc_role *mcc_role, + unsigned int bit) +{ + unsigned int idx = bit / 8; + unsigned int pos = bit % 8; + + if (idx >= ARRAY_SIZE(mcc_role->macid_bitmap)) + return; + + mcc_role->macid_bitmap[idx] |= BIT(pos); +} + +static +u32 rtw89_mcc_role_fw_macid_bitmap_to_u32(struct rtw89_mcc_role *mcc_role) +{ + unsigned int macid; + unsigned int i, j; + u32 bitmap = 0; + + for (i = 0; i < ARRAY_SIZE(mcc_role->macid_bitmap); i++) { + for (j = 0; j < 8; j++) { + macid = i * 8 + j; + if (macid >= 32) + goto out; + + if (mcc_role->macid_bitmap[i] & BIT(j)) + bitmap |= BIT(macid); + } + } + +out: + return bitmap; +} + +static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_mcc_role *mcc_role = data; + struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + u8 macid; + + if (rtwvif != target) + return; + + macid = rtw89_sta_get_main_macid(rtwsta); + rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, macid); +} + +static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role) +{ + struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; + + rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id); + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_mcc_role_macid_sta_iter, + mcc_role); +} + +static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role) +{ + struct rtw89_mcc_policy *policy = &mcc_role->policy; + + policy->c2h_rpt = RTW89_FW_MCC_C2H_RPT_ALL; + policy->tx_null_early = RTW89_MCC_DFLT_TX_NULL_EARLY; + policy->in_curr_ch = false; + policy->dis_sw_retry = true; + policy->sw_retry_count = false; + + if (mcc_role->is_go) + policy->dis_tx_null = true; + else + policy->dis_tx_null = false; +} + +static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role) +{ + struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; + struct ieee80211_p2p_noa_desc *noa_desc; + struct ieee80211_bss_conf *bss_conf; + u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval); + u32 max_toa_us, max_tob_us, max_dur_us; + u32 start_time, interval, duration; + u64 tsf, tsf_lmt; + int ret; + int i; + + if (!mcc_role->is_gc) + return; + + rtw89_p2p_noa_once_recalc(rtwvif_link); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + /* find the first periodic NoA */ + for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) { + noa_desc = &bss_conf->p2p_noa_attr.desc[i]; + if (noa_desc->count == 255) + goto fill; + } + + rcu_read_unlock(); + return; + +fill: + start_time = le32_to_cpu(noa_desc->start_time); + interval = le32_to_cpu(noa_desc->interval); + duration = le32_to_cpu(noa_desc->duration); + + rcu_read_unlock(); + + if (interval != bcn_intvl_us) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC role limit: mismatch interval: %d vs. %d\n", + interval, bcn_intvl_us); + return; + } + + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); + if (ret) { + rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret); + return; + } + + tsf_lmt = (tsf & GENMASK_ULL(63, 32)) | start_time; + if (tsf_lmt < tsf) + tsf_lmt += roundup_u64(tsf - tsf_lmt, interval); + + max_toa_us = rtw89_mcc_get_tbtt_ofst(rtwdev, mcc_role, tsf_lmt); + max_dur_us = interval - duration; + max_tob_us = max_dur_us - max_toa_us; + + if (!max_toa_us || !max_tob_us) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC role limit: hit boundary\n"); + return; + } + + if (max_dur_us < max_toa_us) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC role limit: insufficient duration\n"); + return; + } + + mcc_role->limit.max_toa = max_toa_us / 1024; + mcc_role->limit.max_tob = max_tob_us / 1024; + mcc_role->limit.max_dur = mcc_role->limit.max_toa + mcc_role->limit.max_tob; + mcc_role->limit.enable = true; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC role limit: max_toa %d, max_tob %d, max_dur %d\n", + mcc_role->limit.max_toa, mcc_role->limit.max_tob, + mcc_role->limit.max_dur); +} + +static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_mcc_role *role) +{ + struct ieee80211_bss_conf *bss_conf; + const struct rtw89_chan *chan; + + memset(role, 0, sizeof(*role)); + role->rtwvif_link = rtwvif_link; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + role->beacon_interval = bss_conf->beacon_int; + + rcu_read_unlock(); + + if (!role->beacon_interval) { + rtw89_warn(rtwdev, + "cannot handle MCC role without beacon interval\n"); + return -EINVAL; + } + + role->duration = role->beacon_interval / 2; + + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + role->is_2ghz = chan->band_type == RTW89_BAND_2G; + role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO; + role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; + + rtw89_mcc_fill_role_macid_bitmap(rtwdev, role); + rtw89_mcc_fill_role_policy(rtwdev, role); + rtw89_mcc_fill_role_limit(rtwdev, role); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC role: bcn_intvl %d, is_2ghz %d, is_go %d, is_gc %d\n", + role->beacon_interval, role->is_2ghz, role->is_go, role->is_gc); + return 0; +} + +static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; + + memset(bt_role, 0, sizeof(*bt_role)); + bt_role->duration = rtw89_coex_query_bt_req_len(rtwdev, RTW89_PHY_0); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC bt role: dur %d\n", + bt_role->duration); +} + +struct rtw89_mcc_fill_role_selector { + struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX]; +}; + +static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES); +static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES); + +static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_fill_role_selector *sel = data; + struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx]; + int ret; + + if (!role_vif) { + rtw89_warn(rtwdev, "cannot handle MCC without role[%d]\n", + ordered_idx); + return -EINVAL; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC fill role[%d] with vif \n", + ordered_idx, role_vif->mac_id); + + ret = rtw89_mcc_fill_role(rtwdev, role_vif, mcc_role); + if (ret) + return ret; + + return 0; +} + +static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; + struct rtw89_mcc_fill_role_selector sel = {}; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + int ret; + int i; + + for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) { + rtwvif = mgnt->active_roles[i]; + if (!rtwvif) + break; + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n"); + continue; + } + + sel.bind_vif[i] = rtwvif_link; + rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, NULL); + } + + ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel); + if (ret) + return ret; + + rtw89_mcc_fill_bt_role(rtwdev); + return 0; +} + +static bool rtw89_mcc_can_courtesy(const struct rtw89_mcc_role *provider, + const struct rtw89_mcc_role *receiver) +{ + if (provider->is_go || receiver->is_gc) + return false; + + return true; +} + +static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev, + const struct rtw89_mcc_pattern *new) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_pattern *pattern = &config->pattern; + struct rtw89_mcc_courtesy_cfg *crtz; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC assign pattern: ref {%d | %d}, aux {%d | %d}\n", + new->tob_ref, new->toa_ref, new->tob_aux, new->toa_aux); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC pattern plan: %d\n", new->plan); + + *pattern = *new; + memset(&pattern->courtesy, 0, sizeof(pattern->courtesy)); + + if (RTW89_MCC_REQ_COURTESY(pattern, aux) && aux->is_gc) + aux->ignore_bcn = true; + else + aux->ignore_bcn = false; + + if (RTW89_MCC_REQ_COURTESY(pattern, aux) && rtw89_mcc_can_courtesy(ref, aux)) { + crtz = &pattern->courtesy.ref; + ref->crtz = crtz; + + crtz->macid_tgt = aux->rtwvif_link->mac_id; + crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC courtesy ref: tgt %d, slot %d\n", + crtz->macid_tgt, crtz->slot_num); + } else { + ref->crtz = NULL; + } + + if (RTW89_MCC_REQ_COURTESY(pattern, ref) && ref->is_gc) + ref->ignore_bcn = true; + else + ref->ignore_bcn = false; + + if (RTW89_MCC_REQ_COURTESY(pattern, ref) && rtw89_mcc_can_courtesy(aux, ref)) { + crtz = &pattern->courtesy.aux; + aux->crtz = crtz; + + crtz->macid_tgt = ref->rtwvif_link->mac_id; + crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC courtesy aux: tgt %d, slot %d\n", + crtz->macid_tgt, crtz->slot_num); + } else { + aux->crtz = NULL; + } +} + +/* The follow-up roughly shows the relationship between the parameters + * for pattern calculation. + * + * |< duration ref >| (if mid bt) |< duration aux >| + * |< tob ref >|< toa ref >| ... |< tob aux >|< toa aux >| + * V V + * tbtt ref tbtt aux + * |< beacon offset >| + * + * In loose pattern calculation, we only ensure at least tob_ref and + * toa_ref have positive results. If tob_aux or toa_aux is negative + * unfortunately, FW will be notified to handle it with courtesy + * mechanism. + */ +static void __rtw89_mcc_calc_pattern_loose(struct rtw89_dev *rtwdev, + struct rtw89_mcc_pattern *ptrn, + bool hdl_bt) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 mcc_intvl = config->mcc_interval; + u16 bcn_ofst = config->beacon_offset; + u16 bt_dur_in_mid = 0; + u16 max_bcn_ofst; + s16 upper, lower; + u16 res; + + *ptrn = (typeof(*ptrn)){ + .plan = hdl_bt ? RTW89_MCC_PLAN_TAIL_BT : RTW89_MCC_PLAN_NO_BT, + }; + + if (!hdl_bt) + goto calc; + + max_bcn_ofst = ref->duration + aux->duration; + if (ref->limit.enable) + max_bcn_ofst = min_t(u16, max_bcn_ofst, + ref->limit.max_toa + aux->duration); + else if (aux->limit.enable) + max_bcn_ofst = min_t(u16, max_bcn_ofst, + ref->duration + aux->limit.max_tob); + + if (bcn_ofst > max_bcn_ofst && bcn_ofst >= mcc->bt_role.duration) { + bt_dur_in_mid = mcc->bt_role.duration; + ptrn->plan = RTW89_MCC_PLAN_MID_BT; + } + +calc: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_ls: plan %d, bcn_ofst %d\n", + ptrn->plan, bcn_ofst); + + res = bcn_ofst - bt_dur_in_mid; + upper = min_t(s16, ref->duration, res); + lower = max_t(s16, 0, ref->duration - (mcc_intvl - bcn_ofst)); + + if (ref->limit.enable) { + upper = min_t(s16, upper, ref->limit.max_toa); + lower = max_t(s16, lower, ref->duration - ref->limit.max_tob); + } else if (aux->limit.enable) { + upper = min_t(s16, upper, + res - (aux->duration - aux->limit.max_toa)); + lower = max_t(s16, lower, res - aux->limit.max_tob); + } + + if (lower < upper) + ptrn->toa_ref = (upper + lower) / 2; + else + ptrn->toa_ref = lower; + + ptrn->tob_ref = ref->duration - ptrn->toa_ref; + ptrn->tob_aux = res - ptrn->toa_ref; + ptrn->toa_aux = aux->duration - ptrn->tob_aux; +} + +/* In strict pattern calculation, we consider timing that might need + * for HW stuffs, i.e. min_tob and min_toa. + */ +static int __rtw89_mcc_calc_pattern_strict(struct rtw89_dev *rtwdev, + struct rtw89_mcc_pattern *ptrn) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 min_tob = RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_SWITCH_CH_TIME; + u16 min_toa = RTW89_MCC_MIN_RX_BCN_TIME; + u16 bcn_ofst = config->beacon_offset; + s16 upper_toa_ref, lower_toa_ref; + s16 upper_tob_aux, lower_tob_aux; + u16 bt_dur_in_mid; + s16 res; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: plan %d, bcn_ofst %d\n", + ptrn->plan, bcn_ofst); + + if (ptrn->plan == RTW89_MCC_PLAN_MID_BT) + bt_dur_in_mid = mcc->bt_role.duration; + else + bt_dur_in_mid = 0; + + if (ref->duration < min_tob + min_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: not meet ref dur cond\n"); + return -EINVAL; + } + + if (aux->duration < min_tob + min_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: not meet aux dur cond\n"); + return -EINVAL; + } + + res = bcn_ofst - min_toa - min_tob - bt_dur_in_mid; + if (res < 0) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: not meet bcn_ofst cond\n"); + return -EINVAL; + } + + upper_toa_ref = min_t(s16, min_toa + res, ref->duration - min_tob); + lower_toa_ref = min_toa; + upper_tob_aux = min_t(s16, min_tob + res, aux->duration - min_toa); + lower_tob_aux = min_tob; + + if (ref->limit.enable) { + if (min_tob > ref->limit.max_tob || min_toa > ref->limit.max_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: conflict ref limit\n"); + return -EINVAL; + } + + upper_toa_ref = min_t(s16, upper_toa_ref, ref->limit.max_toa); + lower_toa_ref = max_t(s16, lower_toa_ref, + ref->duration - ref->limit.max_tob); + } else if (aux->limit.enable) { + if (min_tob > aux->limit.max_tob || min_toa > aux->limit.max_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: conflict aux limit\n"); + return -EINVAL; + } + + upper_tob_aux = min_t(s16, upper_tob_aux, aux->limit.max_tob); + lower_tob_aux = max_t(s16, lower_tob_aux, + aux->duration - aux->limit.max_toa); + } + + upper_toa_ref = min_t(s16, upper_toa_ref, + bcn_ofst - bt_dur_in_mid - lower_tob_aux); + lower_toa_ref = max_t(s16, lower_toa_ref, + bcn_ofst - bt_dur_in_mid - upper_tob_aux); + if (lower_toa_ref > upper_toa_ref) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st: conflict boundary\n"); + return -EINVAL; + } + + ptrn->toa_ref = (upper_toa_ref + lower_toa_ref) / 2; + ptrn->tob_ref = ref->duration - ptrn->toa_ref; + ptrn->tob_aux = bcn_ofst - ptrn->toa_ref - bt_dur_in_mid; + ptrn->toa_aux = aux->duration - ptrn->tob_aux; + return 0; +} + +static void __rtw89_mcc_fill_ptrn_anchor_ref(struct rtw89_dev *rtwdev, + struct rtw89_mcc_pattern *ptrn, + bool small_bcn_ofst) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 bcn_ofst = config->beacon_offset; + u16 ref_tob; + u16 ref_toa; + + if (ref->limit.enable) { + ref_tob = ref->limit.max_tob; + ref_toa = ref->limit.max_toa; + } else { + ref_tob = ref->duration / 2; + ref_toa = ref->duration / 2; + } + + if (small_bcn_ofst) { + ptrn->toa_ref = ref_toa; + ptrn->tob_ref = ref->duration - ptrn->toa_ref; + } else { + ptrn->tob_ref = ref_tob; + ptrn->toa_ref = ref->duration - ptrn->tob_ref; + } + + ptrn->tob_aux = bcn_ofst - ptrn->toa_ref; + ptrn->toa_aux = aux->duration - ptrn->tob_aux; +} + +static void __rtw89_mcc_fill_ptrn_anchor_aux(struct rtw89_dev *rtwdev, + struct rtw89_mcc_pattern *ptrn, + bool small_bcn_ofst) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 bcn_ofst = config->beacon_offset; + u16 aux_tob; + u16 aux_toa; + + if (aux->limit.enable) { + aux_tob = aux->limit.max_tob; + aux_toa = aux->limit.max_toa; + } else { + aux_tob = aux->duration / 2; + aux_toa = aux->duration / 2; + } + + if (small_bcn_ofst) { + ptrn->tob_aux = aux_tob; + ptrn->toa_aux = aux->duration - ptrn->tob_aux; + } else { + ptrn->toa_aux = aux_toa; + ptrn->tob_aux = aux->duration - ptrn->toa_aux; + } + + ptrn->toa_ref = bcn_ofst - ptrn->tob_aux; + ptrn->tob_ref = ref->duration - ptrn->toa_ref; +} + +static int __rtw89_mcc_calc_pattern_anchor(struct rtw89_dev *rtwdev, + struct rtw89_mcc_pattern *ptrn, + bool hdl_bt) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 mcc_intvl = config->mcc_interval; + u16 bcn_ofst = config->beacon_offset; + bool small_bcn_ofst; + + if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME) + small_bcn_ofst = true; + else if (bcn_ofst < aux->duration - aux->limit.max_toa) + small_bcn_ofst = true; + else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME) + small_bcn_ofst = false; + else + return -EPERM; + + *ptrn = (typeof(*ptrn)){ + .plan = hdl_bt ? RTW89_MCC_PLAN_TAIL_BT : RTW89_MCC_PLAN_NO_BT, + }; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_ac: plan %d, bcn_ofst %d\n", + ptrn->plan, bcn_ofst); + + if (ref->is_go || ref->is_gc) + __rtw89_mcc_fill_ptrn_anchor_ref(rtwdev, ptrn, small_bcn_ofst); + else if (aux->is_go || aux->is_gc) + __rtw89_mcc_fill_ptrn_anchor_aux(rtwdev, ptrn, small_bcn_ofst); + else + __rtw89_mcc_fill_ptrn_anchor_ref(rtwdev, ptrn, small_bcn_ofst); + + return 0; +} + +static int rtw89_mcc_calc_pattern(struct rtw89_dev *rtwdev, bool hdl_bt) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + bool sel_plan[NUM_OF_RTW89_MCC_PLAN] = {}; + struct rtw89_mcc_pattern ptrn; + int ret; + int i; + + if (ref->limit.enable && aux->limit.enable) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn: not support dual limited roles\n"); + return -EINVAL; + } + + if (ref->limit.enable && + ref->duration > ref->limit.max_tob + ref->limit.max_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn: not fit ref limit\n"); + return -EINVAL; + } + + if (aux->limit.enable && + aux->duration > aux->limit.max_tob + aux->limit.max_toa) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn: not fit aux limit\n"); + return -EINVAL; + } + + if (hdl_bt) { + sel_plan[RTW89_MCC_PLAN_TAIL_BT] = true; + sel_plan[RTW89_MCC_PLAN_MID_BT] = true; + } else { + sel_plan[RTW89_MCC_PLAN_NO_BT] = true; + } + + for (i = 0; i < NUM_OF_RTW89_MCC_PLAN; i++) { + if (!sel_plan[i]) + continue; + + ptrn = (typeof(ptrn)){ + .plan = i, + }; + + ret = __rtw89_mcc_calc_pattern_strict(rtwdev, &ptrn); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC calc ptrn_st with plan %d: fail\n", i); + else + goto done; + } + + ret = __rtw89_mcc_calc_pattern_anchor(rtwdev, &ptrn, hdl_bt); + if (!ret) + goto done; + + __rtw89_mcc_calc_pattern_loose(rtwdev, &ptrn, hdl_bt); + +done: + rtw89_mcc_assign_pattern(rtwdev, &ptrn); + return 0; +} + +static void rtw89_mcc_set_default_pattern(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_pattern tmp = {}; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC use default pattern unexpectedly\n"); + + tmp.plan = RTW89_MCC_PLAN_NO_BT; + tmp.tob_ref = ref->duration / 2; + tmp.toa_ref = ref->duration - tmp.tob_ref; + tmp.tob_aux = aux->duration / 2; + tmp.toa_aux = aux->duration - tmp.tob_aux; + + rtw89_mcc_assign_pattern(rtwdev, &tmp); +} + +static void rtw89_mcc_set_duration_go_sta(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *role_go, + struct rtw89_mcc_role *role_sta) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + u16 mcc_intvl = config->mcc_interval; + u16 dur_go, dur_sta; + + dur_go = clamp_t(u16, role_go->duration, RTW89_MCC_MIN_GO_DURATION, + mcc_intvl - RTW89_MCC_MIN_STA_DURATION); + if (role_go->limit.enable) + dur_go = min(dur_go, role_go->limit.max_dur); + dur_sta = mcc_intvl - dur_go; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC set dur: (go, sta) {%d, %d} -> {%d, %d}\n", + role_go->duration, role_sta->duration, dur_go, dur_sta); + + role_go->duration = dur_go; + role_sta->duration = dur_sta; +} + +static void rtw89_mcc_set_duration_gc_sta(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u16 mcc_intvl = config->mcc_interval; + u16 dur_ref, dur_aux; + + if (ref->duration < RTW89_MCC_MIN_STA_DURATION) { + dur_ref = RTW89_MCC_MIN_STA_DURATION; + dur_aux = mcc_intvl - dur_ref; + } else if (aux->duration < RTW89_MCC_MIN_STA_DURATION) { + dur_aux = RTW89_MCC_MIN_STA_DURATION; + dur_ref = mcc_intvl - dur_aux; + } else { + dur_ref = ref->duration; + dur_aux = mcc_intvl - dur_ref; + } + + if (ref->limit.enable) { + dur_ref = min(dur_ref, ref->limit.max_dur); + dur_aux = mcc_intvl - dur_ref; + } else if (aux->limit.enable) { + dur_aux = min(dur_aux, aux->limit.max_dur); + dur_ref = mcc_intvl - dur_aux; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC set dur: (ref, aux) {%d ~ %d} -> {%d ~ %d}\n", + ref->duration, aux->duration, dur_ref, dur_aux); + + ref->duration = dur_ref; + aux->duration = dur_aux; +} + +struct rtw89_mcc_mod_dur_data { + u16 available; + struct { + u16 dur; + u16 room; + } parm[NUM_OF_RTW89_MCC_ROLES]; +}; + +static int rtw89_mcc_mod_dur_get_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_mod_dur_data *p = data; + u16 min; + + p->parm[ordered_idx].dur = mcc_role->duration; + + if (mcc_role->is_go) + min = RTW89_MCC_MIN_GO_DURATION; + else + min = RTW89_MCC_MIN_STA_DURATION; + + p->parm[ordered_idx].room = max_t(s32, p->parm[ordered_idx].dur - min, 0); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: chk role[%u]: dur %u, min %u, room %u\n", + ordered_idx, p->parm[ordered_idx].dur, min, + p->parm[ordered_idx].room); + + p->available += p->parm[ordered_idx].room; + return 0; +} + +static int rtw89_mcc_mod_dur_put_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_mod_dur_data *p = data; + + mcc_role->duration = p->parm[ordered_idx].dur; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: set role[%u]: dur %u\n", + ordered_idx, p->parm[ordered_idx].dur); + return 0; +} + +static void rtw89_mcc_mod_duration_dual_2ghz_with_bt(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_mod_dur_data data = {}; + u16 mcc_intvl = config->mcc_interval; + u16 bt_dur = mcc->bt_role.duration; + u16 wifi_dur; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur (dual 2ghz): mcc_intvl %u, raw bt_dur %u\n", + mcc_intvl, bt_dur); + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_mod_dur_get_iterator, &data); + + bt_dur = clamp_t(u16, bt_dur, 1, data.available / 3); + wifi_dur = mcc_intvl - bt_dur; + + if (data.parm[0].room <= data.parm[1].room) { + data.parm[0].dur -= min_t(u16, bt_dur / 2, data.parm[0].room); + data.parm[1].dur = wifi_dur - data.parm[0].dur; + } else { + data.parm[1].dur -= min_t(u16, bt_dur / 2, data.parm[1].room); + data.parm[0].dur = wifi_dur - data.parm[1].dur; + } + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_mod_dur_put_iterator, &data); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC mod dur: set bt: dur %u\n", bt_dur); + mcc->bt_role.duration = bt_dur; +} + +static +void rtw89_mcc_mod_duration_diff_band_with_bt(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *role_2ghz, + struct rtw89_mcc_role *role_non_2ghz) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + u16 dur_2ghz, dur_non_2ghz; + u16 bt_dur, mcc_intvl; + + dur_2ghz = role_2ghz->duration; + dur_non_2ghz = role_non_2ghz->duration; + mcc_intvl = config->mcc_interval; + bt_dur = mcc->bt_role.duration; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur (diff band): mcc_intvl %u, bt_dur %u\n", + mcc_intvl, bt_dur); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: check dur_2ghz %u, dur_non_2ghz %u\n", + dur_2ghz, dur_non_2ghz); + + if (dur_non_2ghz >= bt_dur) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: dur_non_2ghz is enough for bt\n"); + return; + } + + dur_non_2ghz = bt_dur; + dur_2ghz = mcc_intvl - dur_non_2ghz; + + if (role_non_2ghz->limit.enable) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: dur_non_2ghz is limited with max %u\n", + role_non_2ghz->limit.max_dur); + + dur_non_2ghz = min(dur_non_2ghz, role_non_2ghz->limit.max_dur); + dur_2ghz = mcc_intvl - dur_non_2ghz; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC mod dur: set dur_2ghz %u, dur_non_2ghz %u\n", + dur_2ghz, dur_non_2ghz); + + role_2ghz->duration = dur_2ghz; + role_non_2ghz->duration = dur_non_2ghz; +} + +static bool rtw89_mcc_duration_decision_on_bt(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; + + if (!bt_role->duration) + return false; + + if (ref->is_2ghz && aux->is_2ghz) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC dual roles are on 2GHz; consider BT duration\n"); + + rtw89_mcc_mod_duration_dual_2ghz_with_bt(rtwdev); + return true; + } + + if (!ref->is_2ghz && !aux->is_2ghz) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC dual roles are not on 2GHz; ignore BT duration\n"); + return false; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC one role is on 2GHz; modify another for BT duration\n"); + + if (ref->is_2ghz) + rtw89_mcc_mod_duration_diff_band_with_bt(rtwdev, ref, aux); + else + rtw89_mcc_mod_duration_diff_band_with_bt(rtwdev, aux, ref); + + return false; +} + +void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + mcc_prepare_done_work.work); + + lockdep_assert_wiphy(wiphy); + + ieee80211_wake_queues(rtwdev->hw); +} + +static void rtw89_mcc_prepare(struct rtw89_dev *rtwdev, bool start) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + + if (start) { + ieee80211_stop_queues(rtwdev->hw); + + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->mcc_prepare_done_work, + usecs_to_jiffies(config->prepare_delay)); + } else { + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->mcc_prepare_done_work, 0); + wiphy_delayed_work_flush(rtwdev->hw->wiphy, + &rtwdev->mcc_prepare_done_work); + } +} + +static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval); + s32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref); + u64 tsf, start_tsf; + u32 cur_tbtt_ofst; + u64 min_time; + u64 tsf_aux; + int ret; + + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_req_tsf(rtwdev, &tsf, &tsf_aux); + else + ret = __mcc_fw_req_tsf(rtwdev, &tsf, &tsf_aux); + + if (ret) + return ret; + + min_time = tsf; + if (ref->is_go || aux->is_go) + min_time += ieee80211_tu_to_usec(RTW89_MCC_SHORT_TRIGGER_TIME); + else + min_time += ieee80211_tu_to_usec(RTW89_MCC_LONG_TRIGGER_TIME); + + cur_tbtt_ofst = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf); + start_tsf = tsf - cur_tbtt_ofst + bcn_intvl_ref_us - tob_ref_us; + if (start_tsf < min_time) + start_tsf += roundup_u64(min_time - start_tsf, bcn_intvl_ref_us); + + config->start_tsf = start_tsf; + config->start_tsf_in_aux_domain = tsf_aux + start_tsf - tsf; + config->prepare_delay = start_tsf - tsf; + + return 0; +} + +static int rtw89_mcc_fill_config(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + bool hdl_bt; + int ret; + + memset(config, 0, sizeof(*config)); + + switch (mcc->mode) { + case RTW89_MCC_MODE_GO_STA: + config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev); + if (ref->is_go) { + config->mcc_interval = ref->beacon_interval; + rtw89_mcc_set_duration_go_sta(rtwdev, ref, aux); + } else { + config->mcc_interval = aux->beacon_interval; + rtw89_mcc_set_duration_go_sta(rtwdev, aux, ref); + } + break; + case RTW89_MCC_MODE_GC_STA: + config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev); + config->mcc_interval = ref->beacon_interval; + rtw89_mcc_set_duration_gc_sta(rtwdev); + break; + default: + rtw89_warn(rtwdev, "MCC unknown mode: %d\n", mcc->mode); + return -EFAULT; + } + + hdl_bt = rtw89_mcc_duration_decision_on_bt(rtwdev); + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC handle bt: %d\n", hdl_bt); + + ret = rtw89_mcc_calc_pattern(rtwdev, hdl_bt); + if (!ret) + goto bottom; + + rtw89_mcc_set_default_pattern(rtwdev); + +bottom: + return rtw89_mcc_fill_start_tsf(rtwdev); +} + +static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role) +{ + const struct rtw89_mcc_courtesy_cfg *crtz = role->crtz; + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_policy *policy = &role->policy; + struct rtw89_fw_mcc_add_req req = {}; + const struct rtw89_chan *chan; + int ret; + + chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); + req.central_ch_seg0 = chan->channel; + req.primary_ch = chan->primary_channel; + req.bandwidth = chan->band_width; + req.ch_band_type = chan->band_type; + + req.macid = role->rtwvif_link->mac_id; + req.group = mcc->group; + req.c2h_rpt = policy->c2h_rpt; + req.tx_null_early = policy->tx_null_early; + req.dis_tx_null = policy->dis_tx_null; + req.in_curr_ch = policy->in_curr_ch; + req.sw_retry_count = policy->sw_retry_count; + req.dis_sw_retry = policy->dis_sw_retry; + req.duration = role->duration; + req.btc_in_2g = false; + + if (crtz) { + req.courtesy_target = crtz->macid_tgt; + req.courtesy_num = crtz->slot_num; + req.courtesy_en = true; + } + + ret = rtw89_fw_h2c_add_mcc(rtwdev, &req); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to add wifi role: %d\n", ret); + return ret; + } + + ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, + role->rtwvif_link->mac_id, + role->macid_bitmap); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to set macid bitmap: %d\n", ret); + return ret; + } + + return 0; +} + +static +void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role, + struct rtw89_fw_mrc_add_arg *arg, u8 slot_idx) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_policy *policy = &role->policy; + struct rtw89_fw_mrc_add_slot_arg *slot_arg; + const struct rtw89_chan *chan; + + slot_arg = &arg->slots[slot_idx]; + role->slot_idx = slot_idx; + + slot_arg->duration = role->duration; + slot_arg->role_num = 1; + + chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); + + slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI; + slot_arg->roles[0].is_master = role == ref; + slot_arg->roles[0].band = chan->band_type; + slot_arg->roles[0].bw = chan->band_width; + slot_arg->roles[0].central_ch = chan->channel; + slot_arg->roles[0].primary_ch = chan->primary_channel; + slot_arg->roles[0].en_tx_null = !policy->dis_tx_null; + slot_arg->roles[0].null_early = policy->tx_null_early; + slot_arg->roles[0].macid = role->rtwvif_link->mac_id; + slot_arg->roles[0].macid_main_bitmap = + rtw89_mcc_role_fw_macid_bitmap_to_u32(role); +} + +static int __mcc_fw_add_bt_role(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; + struct rtw89_fw_mcc_add_req req = {}; + int ret; + + req.group = mcc->group; + req.duration = bt_role->duration; + req.btc_in_2g = true; + + ret = rtw89_fw_h2c_add_mcc(rtwdev, &req); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to add bt role: %d\n", ret); + return ret; + } + + return 0; +} + +static +void __mrc_fw_add_bt_role(struct rtw89_dev *rtwdev, + struct rtw89_fw_mrc_add_arg *arg, u8 slot_idx) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; + struct rtw89_fw_mrc_add_slot_arg *slot_arg = &arg->slots[slot_idx]; + + slot_arg->duration = bt_role->duration; + slot_arg->role_num = 1; + + slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_BT; +} + +static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_pattern *pattern = &config->pattern; + struct rtw89_mcc_sync *sync = &config->sync; + struct rtw89_fw_mcc_start_req req = {}; + int ret; + + if (replace) { + req.old_group = mcc->group; + req.old_group_action = RTW89_FW_MCC_OLD_GROUP_ACT_REPLACE; + mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group); + } + + req.group = mcc->group; + + switch (pattern->plan) { + case RTW89_MCC_PLAN_TAIL_BT: + ret = __mcc_fw_add_role(rtwdev, ref); + if (ret) + return ret; + ret = __mcc_fw_add_role(rtwdev, aux); + if (ret) + return ret; + ret = __mcc_fw_add_bt_role(rtwdev); + if (ret) + return ret; + + req.btc_in_group = true; + break; + case RTW89_MCC_PLAN_MID_BT: + ret = __mcc_fw_add_role(rtwdev, ref); + if (ret) + return ret; + ret = __mcc_fw_add_bt_role(rtwdev); + if (ret) + return ret; + ret = __mcc_fw_add_role(rtwdev, aux); + if (ret) + return ret; + + req.btc_in_group = true; + break; + case RTW89_MCC_PLAN_NO_BT: + ret = __mcc_fw_add_role(rtwdev, ref); + if (ret) + return ret; + ret = __mcc_fw_add_role(rtwdev, aux); + if (ret) + return ret; + + req.btc_in_group = false; + break; + default: + rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan); + return -EFAULT; + } + + if (sync->enable) { + ret = rtw89_fw_h2c_mcc_sync(rtwdev, req.group, sync->macid_src, + sync->macid_tgt, sync->offset); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to trigger sync: %d\n", ret); + return ret; + } + } + + req.macid = ref->rtwvif_link->mac_id; + req.tsf_high = config->start_tsf >> 32; + req.tsf_low = config->start_tsf; + + ret = rtw89_fw_h2c_start_mcc(rtwdev, &req); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to trigger start: %d\n", ret); + return ret; + } + + return 0; +} + +static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev, + struct rtw89_fw_mrc_add_arg *arg) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_fw_mrc_add_slot_arg *slot_arg_src; + + if (ref->crtz) { + slot_arg_src = &arg->slots[ref->slot_idx]; + + slot_arg_src->courtesy_target = aux->slot_idx; + slot_arg_src->courtesy_period = ref->crtz->slot_num; + slot_arg_src->courtesy_en = true; + } + + if (aux->crtz) { + slot_arg_src = &arg->slots[aux->slot_idx]; + + slot_arg_src->courtesy_target = ref->slot_idx; + slot_arg_src->courtesy_period = aux->crtz->slot_num; + slot_arg_src->courtesy_en = true; + } +} + +static int __mrc_fw_start(struct rtw89_dev *rtwdev, bool replace) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_pattern *pattern = &config->pattern; + struct rtw89_mcc_sync *sync = &config->sync; + struct rtw89_fw_mrc_start_arg start_arg = {}; + struct rtw89_fw_mrc_add_arg add_arg = {}; + int ret; + + BUILD_BUG_ON(RTW89_MAC_MRC_MAX_ADD_SLOT_NUM < + NUM_OF_RTW89_MCC_ROLES + 1 /* bt role */); + + if (replace) { + start_arg.old_sch_idx = mcc->group; + start_arg.action = RTW89_H2C_MRC_START_ACTION_REPLACE_OLD; + mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group); + } + + add_arg.sch_idx = mcc->group; + add_arg.sch_type = RTW89_H2C_MRC_SCH_BAND0_ONLY; + + switch (pattern->plan) { + case RTW89_MCC_PLAN_TAIL_BT: + __mrc_fw_add_role(rtwdev, ref, &add_arg, 0); + __mrc_fw_add_role(rtwdev, aux, &add_arg, 1); + __mrc_fw_add_bt_role(rtwdev, &add_arg, 2); + + add_arg.slot_num = 3; + add_arg.btc_in_sch = true; + break; + case RTW89_MCC_PLAN_MID_BT: + __mrc_fw_add_role(rtwdev, ref, &add_arg, 0); + __mrc_fw_add_bt_role(rtwdev, &add_arg, 1); + __mrc_fw_add_role(rtwdev, aux, &add_arg, 2); + + add_arg.slot_num = 3; + add_arg.btc_in_sch = true; + break; + case RTW89_MCC_PLAN_NO_BT: + __mrc_fw_add_role(rtwdev, ref, &add_arg, 0); + __mrc_fw_add_role(rtwdev, aux, &add_arg, 1); + + add_arg.slot_num = 2; + add_arg.btc_in_sch = false; + break; + default: + rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan); + return -EFAULT; + } + + __mrc_fw_add_courtesy(rtwdev, &add_arg); + + ret = rtw89_fw_h2c_mrc_add(rtwdev, &add_arg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to trigger add: %d\n", ret); + return ret; + } + + if (sync->enable) { + struct rtw89_fw_mrc_sync_arg sync_arg = { + .offset = sync->offset, + .src = { + .band = sync->band_src, + .port = sync->port_src, + }, + .dest = { + .band = sync->band_tgt, + .port = sync->port_tgt, + }, + }; + + ret = rtw89_fw_h2c_mrc_sync(rtwdev, &sync_arg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to trigger sync: %d\n", ret); + return ret; + } + } + + start_arg.sch_idx = mcc->group; + start_arg.start_tsf = config->start_tsf; + + ret = rtw89_fw_h2c_mrc_start(rtwdev, &start_arg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to trigger start: %d\n", ret); + return ret; + } + + return 0; +} + +static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_changed) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_sync *sync = &config->sync; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_fw_mcc_duration req = { + .group = mcc->group, + .btc_in_group = false, + .start_macid = ref->rtwvif_link->mac_id, + .macid_x = ref->rtwvif_link->mac_id, + .macid_y = aux->rtwvif_link->mac_id, + .duration_x = ref->duration, + .duration_y = aux->duration, + .start_tsf_high = config->start_tsf >> 32, + .start_tsf_low = config->start_tsf, + }; + int ret; + + ret = rtw89_fw_h2c_mcc_set_duration(rtwdev, &req); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to set duration: %d\n", ret); + return ret; + } + + if (!sync->enable || !sync_changed) + return 0; + + ret = rtw89_fw_h2c_mcc_sync(rtwdev, mcc->group, sync->macid_src, + sync->macid_tgt, sync->offset); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to trigger sync: %d\n", ret); + return ret; + } + + return 0; +} + +static int __mrc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_changed) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_sync *sync = &config->sync; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_fw_mrc_upd_duration_arg dur_arg = { + .sch_idx = mcc->group, + .start_tsf = config->start_tsf, + .slot_num = 2, + .slots[0] = { + .slot_idx = ref->slot_idx, + .duration = ref->duration, + }, + .slots[1] = { + .slot_idx = aux->slot_idx, + .duration = aux->duration, + }, + }; + struct rtw89_fw_mrc_sync_arg sync_arg = { + .offset = sync->offset, + .src = { + .band = sync->band_src, + .port = sync->port_src, + }, + .dest = { + .band = sync->band_tgt, + .port = sync->port_tgt, + }, + + }; + int ret; + + ret = rtw89_fw_h2c_mrc_upd_duration(rtwdev, &dur_arg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to update duration: %d\n", ret); + return ret; + } + + if (!sync->enable || !sync_changed) + return 0; + + ret = rtw89_fw_h2c_mrc_sync(rtwdev, &sync_arg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to trigger sync: %d\n", ret); + return ret; + } + + return 0; +} + +static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config *config = &mcc->config; + struct ieee80211_p2p_noa_desc noa_desc = {}; + u32 interval = config->mcc_interval; + struct rtw89_vif_link *rtwvif_go; + u64 start_time; + u32 duration; + + if (mcc->mode != RTW89_MCC_MODE_GO_STA) + return; + + if (ref->is_go) { + start_time = config->start_tsf; + rtwvif_go = ref->rtwvif_link; + start_time += ieee80211_tu_to_usec(ref->duration); + duration = config->mcc_interval - ref->duration; + } else if (aux->is_go) { + start_time = config->start_tsf_in_aux_domain; + rtwvif_go = aux->rtwvif_link; + duration = config->mcc_interval - aux->duration; + } else { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC find no GO: skip updating beacon NoA\n"); + return; + } + + rtw89_p2p_noa_renew(rtwvif_go); + + if (enable) { + duration += RTW89_MCC_SWITCH_CH_TIME; + noa_desc.start_time = cpu_to_le32(start_time); + noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(interval)); + noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(duration)); + noa_desc.count = 255; + rtw89_p2p_noa_append(rtwvif_go, &noa_desc); + } + + /* without chanctx, we cannot get beacon from mac80211 stack */ + if (!rtwvif_go->chanctx_assigned) + return; + + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_go); +} + +static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + + if (mcc->mode != RTW89_MCC_MODE_GO_STA) + return; + + if (ref->is_go) + rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true); + else if (aux->is_go) + rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true); + + rtw89_mcc_handle_beacon_noa(rtwdev, true); +} + +static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + + if (mcc->mode != RTW89_MCC_MODE_GO_STA) + return; + + if (ref->is_go) + rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false); + else if (aux->is_go) + rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false); + + rtw89_mcc_handle_beacon_noa(rtwdev, false); +} + +static bool rtw89_mcc_ignore_bcn(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + + if (role->is_go) + return true; + else if (chip_gen == RTW89_CHIP_BE && role->is_gc) + return true; + else + return false; +} + +static int rtw89_mcc_start(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + int ret; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + rtw89_leave_lps(rtwdev); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC start\n"); + + ret = rtw89_mcc_fill_all_roles(rtwdev); + if (ret) + return ret; + + if (ref->is_go || aux->is_go) + mcc->mode = RTW89_MCC_MODE_GO_STA; + else + mcc->mode = RTW89_MCC_MODE_GC_STA; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode); + + mcc->group = RTW89_MCC_DFLT_GROUP; + + ret = rtw89_mcc_fill_config(rtwdev); + if (ret) + return ret; + + if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn) { + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false); + } else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn) { + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false); + } else { + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true); + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true); + } + + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_start(rtwdev, false); + else + ret = __mcc_fw_start(rtwdev, false); + + if (ret) + return ret; + + rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START); + + rtw89_mcc_start_beacon_noa(rtwdev); + rtw89_phy_dig_suspend(rtwdev); + + rtw89_mcc_prepare(rtwdev, true); + return 0; +} + +struct rtw89_mcc_stop_sel { + struct { + const struct rtw89_vif_link *target; + } hint; + + /* selection content */ + bool filled; + u8 mac_id; + u8 slot_idx; +}; + +static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel, + const struct rtw89_mcc_role *mcc_role) +{ + sel->mac_id = mcc_role->rtwvif_link->mac_id; + sel->slot_idx = mcc_role->slot_idx; + sel->filled = true; +} + +static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_stop_sel *sel = data; + + if (mcc_role->rtwvif_link == sel->hint.target) { + rtw89_mcc_stop_sel_fill(sel, mcc_role); + return 1; /* break iteration */ + } + + if (sel->filled) + return 0; + + if (!mcc_role->rtwvif_link->chanctx_assigned) + return 0; + + rtw89_mcc_stop_sel_fill(sel, mcc_role); + return 0; +} + +static void rtw89_mcc_stop(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_pause_parm *pause) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_stop_sel sel = { + .hint.target = pause ? pause->trigger : NULL, + }; + bool rsn_scan; + int ret; + + if (!pause) { + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->chanctx_work); + bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES); + } + + rsn_scan = pause && pause->rsn == RTW89_CHANCTX_PAUSE_REASON_HW_SCAN; + if (rsn_scan && ref->is_go) + sel.hint.target = ref->rtwvif_link; + else if (rsn_scan && aux->is_go) + sel.hint.target = aux->rtwvif_link; + + /* by default, stop at ref */ + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel); + if (!sel.filled) + rtw89_mcc_stop_sel_fill(&sel, ref); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop at \n", sel.mac_id); + + if (rtw89_concurrent_via_mrc(rtwdev)) { + ret = rtw89_fw_h2c_mrc_del(rtwdev, mcc->group, sel.slot_idx); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to trigger del: %d\n", ret); + } else { + ret = rtw89_fw_h2c_stop_mcc(rtwdev, mcc->group, + sel.mac_id, true); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to trigger stop: %d\n", ret); + + ret = rtw89_fw_h2c_del_mcc_group(rtwdev, mcc->group, true); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to delete group: %d\n", ret); + } + + rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP); + + rtw89_mcc_stop_beacon_noa(rtwdev); + rtw89_fw_h2c_mcc_dig(rtwdev, RTW89_CHANCTX_0, 0, 0, false); + rtw89_phy_dig_resume(rtwdev, true); + + rtw89_mcc_prepare(rtwdev, false); +} + +static int rtw89_mcc_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + bool old_ref_ignore_bcn = mcc->role_ref.ignore_bcn; + bool old_aux_ignore_bcn = mcc->role_aux.ignore_bcn; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + struct rtw89_mcc_config old_cfg = *config; + bool courtesy_changed; + bool sync_changed; + int ret; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC update\n"); + + ret = rtw89_mcc_fill_config(rtwdev); + if (ret) + return ret; + + if (old_ref_ignore_bcn != ref->ignore_bcn) + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, !ref->ignore_bcn); + else if (old_aux_ignore_bcn != aux->ignore_bcn) + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, !aux->ignore_bcn); + + if (memcmp(&old_cfg.pattern.courtesy, &config->pattern.courtesy, + sizeof(old_cfg.pattern.courtesy)) == 0) + courtesy_changed = false; + else + courtesy_changed = true; + + if (old_cfg.pattern.plan != RTW89_MCC_PLAN_NO_BT || + config->pattern.plan != RTW89_MCC_PLAN_NO_BT || + courtesy_changed) { + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_start(rtwdev, true); + else + ret = __mcc_fw_start(rtwdev, true); + + if (ret) + return ret; + } else { + if (memcmp(&old_cfg.sync, &config->sync, sizeof(old_cfg.sync)) == 0) + sync_changed = false; + else + sync_changed = true; + + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_set_duration_no_bt(rtwdev, sync_changed); + else + ret = __mcc_fw_set_duration_no_bt(rtwdev, sync_changed); + + if (ret) + return ret; + } + + rtw89_mcc_handle_beacon_noa(rtwdev, true); + return 0; +} + +static int rtw89_mcc_search_gc_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_role **role = data; + + if (mcc_role->is_gc) + *role = mcc_role; + + return 0; +} + +static struct rtw89_mcc_role *rtw89_mcc_get_gc_role(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_role *role = NULL; + + if (mcc->mode != RTW89_MCC_MODE_GC_STA) + return NULL; + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_search_gc_iterator, &role); + + return role; +} + +void rtw89_mcc_gc_detect_beacon_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, + mcc_gc_detect_beacon_work.work); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + enum rtw89_entity_mode mode; + struct rtw89_dev *rtwdev; + + lockdep_assert_wiphy(wiphy); + + rtwdev = rtwvif_link->rtwvif->rtwdev; + + mode = rtw89_get_entity_mode(rtwdev); + if (mode != RTW89_ENTITY_MODE_MCC) + return; + + if (READ_ONCE(rtwvif_link->sync_bcn_tsf) > rtwvif_link->last_sync_bcn_tsf) + rtwvif_link->detect_bcn_count = 0; + else + rtwvif_link->detect_bcn_count++; + + if (rtwvif_link->detect_bcn_count < RTW89_MCC_DETECT_BCN_MAX_TRIES) + rtw89_chanctx_proceed(rtwdev, NULL); + else + ieee80211_connection_loss(vif); +} + +bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); + struct rtw89_chanctx_pause_parm pause_parm = { + .rsn = RTW89_CHANCTX_PAUSE_REASON_GC_BCN_LOSS, + .trigger = rtwvif_link, + }; + struct ieee80211_bss_conf *bss_conf; + struct rtw89_mcc_role *role; + u16 bcn_int; + + if (mode != RTW89_ENTITY_MODE_MCC) + return false; + + role = rtw89_mcc_get_gc_role(rtwdev); + if (!role) + return false; + + if (role->rtwvif_link != rtwvif_link) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC GC beacon loss, pause MCC to detect GO beacon\n"); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + bcn_int = bss_conf->beacon_int; + + rcu_read_unlock(); + + rtw89_chanctx_pause(rtwdev, &pause_parm); + rtwvif_link->last_sync_bcn_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwvif_link->mcc_gc_detect_beacon_work, + usecs_to_jiffies(ieee80211_tu_to_usec(bcn_int))); + + return true; +} + +static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *role) +{ + struct rtw89_vif_link *rtwvif_link = role->rtwvif_link; + struct ieee80211_vif *vif; + bool start_detect; + int ret; + + ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false, + RTW89_MCC_PROBE_TIMEOUT); + if (ret && + READ_ONCE(rtwvif_link->sync_bcn_tsf) == rtwvif_link->last_sync_bcn_tsf) + role->probe_count++; + else + role->probe_count = 0; + + rtwvif_link->last_sync_bcn_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); + if (role->probe_count < RTW89_MCC_PROBE_MAX_TRIES) + return; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC can not detect AP/GO\n", role->rtwvif_link->mac_id); + + start_detect = rtw89_mcc_detect_go_bcn(rtwdev, role->rtwvif_link); + if (start_detect) + return; + + vif = rtwvif_link_to_vif(role->rtwvif_link); + ieee80211_connection_loss(vif); +} + +static void rtw89_mcc_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_mcc_config *config = &mcc->config; + struct rtw89_mcc_pattern *pattern = &config->pattern; + struct rtw89_mcc_role *ref = &mcc->role_ref; + struct rtw89_mcc_role *aux = &mcc->role_aux; + u16 tolerance; + u16 bcn_ofst; + u16 diff; + + if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn) + rtw89_mcc_detect_connection(rtwdev, aux); + else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn) + rtw89_mcc_detect_connection(rtwdev, ref); + + if (mcc->mode != RTW89_MCC_MODE_GC_STA) + return; + + bcn_ofst = rtw89_mcc_get_bcn_ofst(rtwdev); + if (bcn_ofst == config->beacon_offset) + return; + + if (bcn_ofst > config->beacon_offset) { + diff = bcn_ofst - config->beacon_offset; + if (pattern->tob_aux < 0) + tolerance = -pattern->tob_aux; + else if (pattern->toa_aux > 0) + tolerance = pattern->toa_aux; + else + return; /* no chance to improve */ + } else { + diff = config->beacon_offset - bcn_ofst; + if (pattern->toa_aux < 0) + tolerance = -pattern->toa_aux; + else if (pattern->tob_aux > 0) + tolerance = pattern->tob_aux; + else + return; /* no chance to improve */ + } + + if (diff <= tolerance) + return; + + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_BCN_OFFSET_CHANGE); +} + +static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *upd) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + int ret; + + ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, + upd->rtwvif_link->mac_id, + upd->macid_bitmap); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC h2c failed to update macid bitmap: %d\n", ret); + return ret; + } + + return 0; +} + +static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *cur, + struct rtw89_mcc_role *upd) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + struct rtw89_fw_mrc_upd_bitmap_arg arg = {}; + u32 old = rtw89_mcc_role_fw_macid_bitmap_to_u32(cur); + u32 new = rtw89_mcc_role_fw_macid_bitmap_to_u32(upd); + u32 add = new & ~old; + u32 del = old & ~new; + int ret; + int i; + + arg.sch_idx = mcc->group; + arg.macid = upd->rtwvif_link->mac_id; + + for (i = 0; i < 32; i++) { + if (add & BIT(i)) { + arg.client_macid = i; + arg.action = RTW89_H2C_MRC_UPD_BITMAP_ACTION_ADD; + + ret = rtw89_fw_h2c_mrc_upd_bitmap(rtwdev, &arg); + if (ret) + goto err; + } + } + + for (i = 0; i < 32; i++) { + if (del & BIT(i)) { + arg.client_macid = i; + arg.action = RTW89_H2C_MRC_UPD_BITMAP_ACTION_DEL; + + ret = rtw89_fw_h2c_mrc_upd_bitmap(rtwdev, &arg); + if (ret) + goto err; + } + } + + return 0; + +err: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC h2c failed to update bitmap: %d\n", ret); + return ret; +} + +static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_role upd = { + .rtwvif_link = mcc_role->rtwvif_link, + }; + int ret; + + if (!mcc_role->is_go) + return 0; + + rtw89_mcc_fill_role_macid_bitmap(rtwdev, &upd); + if (memcmp(mcc_role->macid_bitmap, upd.macid_bitmap, + sizeof(mcc_role->macid_bitmap)) == 0) + return 0; + + if (rtw89_concurrent_via_mrc(rtwdev)) + ret = __mrc_fw_upd_macid_bitmap(rtwdev, mcc_role, &upd); + else + ret = __mcc_fw_upd_macid_bitmap(rtwdev, &upd); + + if (ret) + return ret; + + memcpy(mcc_role->macid_bitmap, upd.macid_bitmap, + sizeof(mcc_role->macid_bitmap)); + return 0; +} + +static void rtw89_mcc_update_macid_bitmap(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + + if (mcc->mode != RTW89_MCC_MODE_GO_STA) + return; + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_map_iterator, NULL); +} + +static int rtw89_mcc_upd_lmt_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + memset(&mcc_role->limit, 0, sizeof(mcc_role->limit)); + rtw89_mcc_fill_role_limit(rtwdev, mcc_role); + return 0; +} + +static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc = &rtwdev->mcc; + + if (mcc->mode != RTW89_MCC_MODE_GC_STA) + return; + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL); +} + +static int rtw89_mcc_get_links_iterator(struct rtw89_dev *rtwdev, + struct rtw89_mcc_role *mcc_role, + unsigned int ordered_idx, + void *data) +{ + struct rtw89_mcc_links_info *info = data; + + info->links[ordered_idx] = mcc_role->rtwvif_link; + return 0; +} + +void rtw89_mcc_get_links(struct rtw89_dev *rtwdev, struct rtw89_mcc_links_info *info) +{ + enum rtw89_entity_mode mode; + + memset(info, 0, sizeof(*info)); + + mode = rtw89_get_entity_mode(rtwdev); + if (unlikely(mode != RTW89_ENTITY_MODE_MCC)) + return; + + rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_get_links_iterator, info); +} + +void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + chanctx_work.work); + struct rtw89_hal *hal = &rtwdev->hal; + bool update_mcc_pattern = false; + enum rtw89_entity_mode mode; + u32 changed = 0; + int ret; + int i; + + lockdep_assert_wiphy(wiphy); + + if (hal->entity_pause) + return; + + for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) { + if (test_and_clear_bit(i, hal->changes)) + changed |= BIT(i); + } + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + case RTW89_ENTITY_MODE_MCC_PREPARE: + rtw89_set_entity_mode(rtwdev, RTW89_ENTITY_MODE_MCC); + rtw89_set_channel(rtwdev); + + ret = rtw89_mcc_start(rtwdev); + if (ret) + rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret); + break; + case RTW89_ENTITY_MODE_MCC: + if (changed & BIT(RTW89_CHANCTX_BCN_OFFSET_CHANGE) || + changed & BIT(RTW89_CHANCTX_P2P_PS_CHANGE) || + changed & BIT(RTW89_CHANCTX_BT_SLOT_CHANGE) || + changed & BIT(RTW89_CHANCTX_TSF32_TOGGLE_CHANGE)) + update_mcc_pattern = true; + if (changed & BIT(RTW89_CHANCTX_REMOTE_STA_CHANGE)) + rtw89_mcc_update_macid_bitmap(rtwdev); + if (changed & BIT(RTW89_CHANCTX_P2P_PS_CHANGE)) + rtw89_mcc_update_limit(rtwdev); + if (changed & BIT(RTW89_CHANCTX_BT_SLOT_CHANGE)) + rtw89_mcc_fill_bt_role(rtwdev); + if (update_mcc_pattern) { + ret = rtw89_mcc_update(rtwdev); + if (ret) + rtw89_warn(rtwdev, "failed to update MCC: %d\n", + ret); + } + break; + default: + break; + } +} + +void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_changes change) +{ + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_entity_mode mode; + u32 delay; + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + default: + return; + case RTW89_ENTITY_MODE_MCC_PREPARE: + delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE); + rtw89_phy_dig_suspend(rtwdev); + break; + case RTW89_ENTITY_MODE_MCC: + delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC); + break; + } + + if (change != RTW89_CHANCTX_CHANGE_DFLT) { + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "set chanctx change %d\n", + change); + set_bit(change, hal->changes); + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "queue chanctx work for mode %d with delay %d us\n", + mode, delay); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->chanctx_work, + usecs_to_jiffies(delay)); +} + +void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev) +{ + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_CHANGE_DFLT); +} + +static enum rtw89_mr_wtype __rtw89_query_mr_wtype(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + enum rtw89_chanctx_idx chanctx_idx; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + unsigned int num_mld = 0; + unsigned int num_ml = 0; + unsigned int cnt = 0; + u8 role_idx; + u8 idx; + + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { + rtwvif = mgnt->active_roles[role_idx]; + if (!rtwvif) + continue; + + cnt++; + + vif = rtwvif_to_vif(rtwvif); + if (!ieee80211_vif_is_mld(vif)) + continue; + + num_mld++; + + for (idx = 0; idx < __RTW89_MLD_MAX_LINK_NUM; idx++) { + chanctx_idx = mgnt->chanctx_tbl[role_idx][idx]; + if (chanctx_idx != RTW89_CHANCTX_IDLE) + num_ml++; + } + } + + if (num_mld > 1) + goto err; + + switch (cnt) { + case 0: + return RTW89_MR_WTYPE_NONE; + case 1: + if (!num_mld) + return RTW89_MR_WTYPE_NONMLD; + switch (num_ml) { + case 1: + return RTW89_MR_WTYPE_MLD1L1R; + case 2: + return RTW89_MR_WTYPE_MLD2L1R; + default: + break; + } + break; + case 2: + if (!num_mld) + return RTW89_MR_WTYPE_NONMLD_NONMLD; + switch (num_ml) { + case 1: + return RTW89_MR_WTYPE_MLD1L1R_NONMLD; + case 2: + return RTW89_MR_WTYPE_MLD2L1R_NONMLD; + default: + break; + } + break; + default: + break; + } + +err: + rtw89_warn(rtwdev, "%s: unhandled cnt %u mld %u ml %u\n", __func__, + cnt, num_mld, num_ml); + return RTW89_MR_WTYPE_UNKNOWN; +} + +static enum rtw89_mr_wmode __rtw89_query_mr_wmode(struct rtw89_dev *rtwdev, + u8 inst_idx) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + unsigned int num[NUM_NL80211_IFTYPES] = {}; + enum rtw89_chanctx_idx chanctx_idx; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + unsigned int cnt = 0; + u8 role_idx; + + if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM)) + return RTW89_MR_WMODE_UNKNOWN; + + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { + chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; + if (chanctx_idx == RTW89_CHANCTX_IDLE) + continue; + + rtwvif = mgnt->active_roles[role_idx]; + if (unlikely(!rtwvif)) + continue; + + vif = rtwvif_to_vif(rtwvif); + num[vif->type]++; + cnt++; + } + + switch (cnt) { + case 0: + return RTW89_MR_WMODE_NONE; + case 1: + if (num[NL80211_IFTYPE_STATION]) + return RTW89_MR_WMODE_1CLIENT; + if (num[NL80211_IFTYPE_AP]) + return RTW89_MR_WMODE_1AP; + break; + case 2: + if (num[NL80211_IFTYPE_STATION] == 2) + return RTW89_MR_WMODE_2CLIENTS; + if (num[NL80211_IFTYPE_AP] == 2) + return RTW89_MR_WMODE_2APS; + if (num[NL80211_IFTYPE_STATION] && num[NL80211_IFTYPE_AP]) + return RTW89_MR_WMODE_1AP_1CLIENT; + break; + default: + break; + } + + rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt); + return RTW89_MR_WMODE_UNKNOWN; +} + +static enum rtw89_mr_ctxtype __rtw89_query_mr_ctxtype(struct rtw89_dev *rtwdev, + u8 inst_idx) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + DECLARE_BITMAP(map, NUM_OF_RTW89_CHANCTX) = {}; + unsigned int num[RTW89_BAND_NUM] = {}; + enum rtw89_chanctx_idx chanctx_idx; + const struct rtw89_chan *chan; + unsigned int cnt = 0; + u8 role_idx; + + if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM)) + return RTW89_MR_CTX_UNKNOWN; + + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { + chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; + if (chanctx_idx == RTW89_CHANCTX_IDLE) + continue; + + if (__test_and_set_bit(chanctx_idx, map)) + continue; + + chan = rtw89_chan_get(rtwdev, chanctx_idx); + num[chan->band_type]++; + cnt++; + } + + switch (cnt) { + case 0: + return RTW89_MR_CTX_NONE; + case 1: + if (num[RTW89_BAND_2G]) + return RTW89_MR_CTX1_2GHZ; + if (num[RTW89_BAND_5G]) + return RTW89_MR_CTX1_5GHZ; + if (num[RTW89_BAND_6G]) + return RTW89_MR_CTX1_6GHZ; + break; + case 2: + if (num[RTW89_BAND_2G] == 2) + return RTW89_MR_CTX2_2GHZ; + if (num[RTW89_BAND_5G] == 2) + return RTW89_MR_CTX2_5GHZ; + if (num[RTW89_BAND_6G] == 2) + return RTW89_MR_CTX2_6GHZ; + if (num[RTW89_BAND_2G] && num[RTW89_BAND_5G]) + return RTW89_MR_CTX2_2GHZ_5GHZ; + if (num[RTW89_BAND_2G] && num[RTW89_BAND_6G]) + return RTW89_MR_CTX2_2GHZ_6GHZ; + if (num[RTW89_BAND_5G] && num[RTW89_BAND_6G]) + return RTW89_MR_CTX2_5GHZ_6GHZ; + break; + default: + break; + } + + rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt); + return RTW89_MR_CTX_UNKNOWN; +} + +void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx, + struct rtw89_mr_chanctx_info *info) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + info->wtype = __rtw89_query_mr_wtype(rtwdev); + info->wmode = __rtw89_query_mr_wmode(rtwdev, inst_idx); + info->ctxtype = __rtw89_query_mr_ctxtype(rtwdev, inst_idx); +} + +void rtw89_chanctx_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_entity_mode mode; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (hal->entity_pause) + return; + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + case RTW89_ENTITY_MODE_MCC: + rtw89_mcc_track(rtwdev); + break; + default: + break; + } +} + +void rtw89_chanctx_pause(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_pause_parm *pause_parm) +{ + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_entity_mode mode; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (hal->entity_pause) + return; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", pause_parm->rsn); + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + case RTW89_ENTITY_MODE_MCC: + rtw89_mcc_stop(rtwdev, pause_parm); + break; + default: + break; + } + + hal->entity_pause = true; +} + +static void rtw89_chanctx_proceed_cb(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_cb_parm *parm) +{ + int ret; + + if (!parm || !parm->cb) + return; + + ret = parm->cb(rtwdev, parm->data); + if (ret) + rtw89_warn(rtwdev, "%s (%s): cb failed: %d\n", __func__, + parm->caller ?: "unknown", ret); +} + +/* pass @cb_parm if there is a @cb_parm->cb which needs to invoke right after + * call rtw89_set_channel() and right before proceed entity according to mode. + */ +void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_cb_parm *cb_parm) +{ + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_entity_mode mode; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (unlikely(!hal->entity_pause)) { + rtw89_chanctx_proceed_cb(rtwdev, cb_parm); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx proceed\n"); + + hal->entity_pause = false; + rtw89_set_channel(rtwdev); + + rtw89_chanctx_proceed_cb(rtwdev, cb_parm); + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + case RTW89_ENTITY_MODE_MCC: + ret = rtw89_mcc_start(rtwdev); + if (ret) + rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret); + break; + default: + break; + } + + rtw89_queue_chanctx_work(rtwdev); +} + +static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif, + enum rtw89_chanctx_idx idx1, + enum rtw89_chanctx_idx idx2) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + if (!rtwvif_link->chanctx_assigned) + continue; + + if (rtwvif_link->chanctx_idx == idx1) + rtwvif_link->chanctx_idx = idx2; + else if (rtwvif_link->chanctx_idx == idx2) + rtwvif_link->chanctx_idx = idx1; + } +} + +static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx1, + enum rtw89_chanctx_idx idx2) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_vif *rtwvif; + u8 cur; + + if (idx1 == idx2) + return; + + hal->chanctx[idx1].cfg->idx = idx2; + hal->chanctx[idx2].cfg->idx = idx1; + + swap(hal->chanctx[idx1], hal->chanctx[idx2]); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + __rtw89_swap_chanctx(rtwvif, idx1, idx2); + + cur = atomic_read(&hal->roc_chanctx_idx); + if (cur == idx1) + atomic_set(&hal->roc_chanctx_idx, idx2); + else if (cur == idx2) + atomic_set(&hal->roc_chanctx_idx, idx1); +} + +int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 idx; + + idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX); + if (idx >= chip->support_chanctx_num) + return -ENOENT; + + rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); + cfg->idx = idx; + cfg->ref_count = 0; + hal->chanctx[idx].cfg = cfg; + return 0; +} + +void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; + + rtw89_config_entity_chandef(rtwdev, cfg->idx, NULL); +} + +void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx, + u32 changed) +{ + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; + u8 idx = cfg->idx; + + if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) { + rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); + rtw89_set_channel(rtwdev); + } + + if (changed & IEEE80211_CHANCTX_CHANGE_PUNCTURING) + rtw89_chan_update_punctured(rtwdev, idx, &ctx->def); +} + +int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; + struct rtw89_entity_weight w = {}; + int ret; + + rtwvif_link->chanctx_idx = cfg->idx; + rtwvif_link->chanctx_assigned = true; + cfg->ref_count++; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + if (list_empty(&rtwvif->mgnt_entry)) + list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list); + + if (cfg->idx == RTW89_CHANCTX_0) + goto out; + + rtw89_entity_calculate_weight(rtwdev, &w); + if (w.active_chanctxs != 1) + goto out; + + /* put the first active chanctx at RTW89_CHANCTX_0 */ + rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0); + +out: + ret = rtw89_set_channel(rtwdev); + if (ret) + return ret; + + rtw89_tas_reset(rtwdev, true); + + return 0; +} + +void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_chanctx_idx roll; + enum rtw89_entity_mode cur; + enum rtw89_entity_mode new; + int ret; + + rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; + rtwvif_link->chanctx_assigned = false; + cfg->ref_count--; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + if (!rtw89_vif_is_active_role(rtwvif)) + list_del_init(&rtwvif->mgnt_entry); + + if (cfg->ref_count != 0) + goto out; + + if (cfg->idx != RTW89_CHANCTX_0) + goto out; + + roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX, + cfg->idx + 1); + /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */ + if (roll == NUM_OF_RTW89_CHANCTX) + goto out; + + /* RTW89_CHANCTX_0 is going to release, and another exists. + * Make another roll down to RTW89_CHANCTX_0 to replace. + */ + rtw89_swap_chanctx(rtwdev, cfg->idx, roll); + +out: + if (!hal->entity_pause) { + cur = rtw89_get_entity_mode(rtwdev); + switch (cur) { + case RTW89_ENTITY_MODE_MCC: + rtw89_mcc_stop(rtwdev, NULL); + break; + default: + break; + } + } + + ret = rtw89_set_channel(rtwdev); + if (ret) + return; + + if (hal->entity_pause) + return; + + new = rtw89_get_entity_mode(rtwdev); + switch (new) { + case RTW89_ENTITY_MODE_MCC: + /* re-plan MCC for chanctx changes. */ + ret = rtw89_mcc_start(rtwdev); + if (ret) + rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret); + break; + default: + break; + } +} + +int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *old_ctx, + struct ieee80211_chanctx_conf *new_ctx, + bool replace) +{ + int ret; + + rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, old_ctx); + + if (!replace) + goto assign; + + rtw89_chanctx_ops_remove(rtwdev, old_ctx); + ret = rtw89_chanctx_ops_add(rtwdev, new_ctx); + if (ret) { + rtw89_err(rtwdev, "%s: failed to add chanctx: %d\n", + __func__, ret); + return ret; + } + +assign: + ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, new_ctx); + if (ret) { + rtw89_err(rtwdev, "%s: failed to assign chanctx: %d\n", + __func__, ret); + return ret; + } + + _rtw89_chan_update_punctured(rtwdev, rtwvif_link, &new_ctx->def); + + return 0; +} diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h new file mode 100644 index 000000000..a9a5f1b30 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/chan.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + * Copyright(c) 2020-2022 Realtek Corporation + */ + +#ifndef __RTW89_CHAN_H__ +#define __RTW89_CHAN_H__ + +#include "core.h" + +/* The dwell time in TU before doing rtw89_chanctx_work(). */ +#define RTW89_CHANCTX_TIME_MCC_PREPARE 100 +#define RTW89_CHANCTX_TIME_MCC 100 + +/* various MCC setting time in TU */ +#define RTW89_MCC_LONG_TRIGGER_TIME 300 +#define RTW89_MCC_SHORT_TRIGGER_TIME 100 +#define RTW89_MCC_EARLY_TX_BCN_TIME 10 +#define RTW89_MCC_EARLY_RX_BCN_TIME 5 +#define RTW89_MCC_MIN_RX_BCN_TIME 10 +#define RTW89_MCC_DFLT_BCN_OFST_TIME 40 +#define RTW89_MCC_SWITCH_CH_TIME 3 + +#define RTW89_MCC_PROBE_TIMEOUT 100 +#define RTW89_MCC_PROBE_MAX_TRIES 3 + +#define RTW89_MCC_DETECT_BCN_MAX_TRIES 2 + +#define RTW89_MCC_MIN_GO_DURATION \ + (RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME) + +#define RTW89_MCC_MIN_STA_DURATION \ + (RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME) + +#define RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME \ + (RTW89_MCC_MIN_RX_BCN_TIME + RTW89_MCC_SWITCH_CH_TIME) + +#define RTW89_MCC_DFLT_GROUP 0 +#define RTW89_MCC_NEXT_GROUP(cur) (((cur) + 1) % 4) + +#define RTW89_MCC_DFLT_TX_NULL_EARLY 7 +#define RTW89_MCC_DFLT_COURTESY_SLOT 3 + +#define RTW89_MCC_REQ_COURTESY_TIME 5 +#define RTW89_MCC_REQ_COURTESY(pattern, role) \ +({ \ + const struct rtw89_mcc_pattern *p = pattern; \ + p->tob_ ## role <= RTW89_MCC_REQ_COURTESY_TIME || \ + p->toa_ ## role <= RTW89_MCC_REQ_COURTESY_TIME; \ +}) + +#define NUM_OF_RTW89_MCC_ROLES 2 + +enum rtw89_mr_wtype { + RTW89_MR_WTYPE_NONE, + RTW89_MR_WTYPE_NONMLD, + RTW89_MR_WTYPE_MLD1L1R, + RTW89_MR_WTYPE_MLD2L1R, + RTW89_MR_WTYPE_MLD2L2R, + RTW89_MR_WTYPE_NONMLD_NONMLD, + RTW89_MR_WTYPE_MLD1L1R_NONMLD, + RTW89_MR_WTYPE_MLD2L1R_NONMLD, + RTW89_MR_WTYPE_MLD2L2R_NONMLD, + RTW89_MR_WTYPE_UNKNOWN, +}; + +enum rtw89_mr_wmode { + RTW89_MR_WMODE_NONE, + RTW89_MR_WMODE_1CLIENT, + RTW89_MR_WMODE_1AP, + RTW89_MR_WMODE_1AP_1CLIENT, + RTW89_MR_WMODE_2CLIENTS, + RTW89_MR_WMODE_2APS, + RTW89_MR_WMODE_UNKNOWN, +}; + +enum rtw89_mr_ctxtype { + RTW89_MR_CTX_NONE, + RTW89_MR_CTX1_2GHZ, + RTW89_MR_CTX1_5GHZ, + RTW89_MR_CTX1_6GHZ, + RTW89_MR_CTX2_2GHZ, + RTW89_MR_CTX2_5GHZ, + RTW89_MR_CTX2_6GHZ, + RTW89_MR_CTX2_2GHZ_5GHZ, + RTW89_MR_CTX2_2GHZ_6GHZ, + RTW89_MR_CTX2_5GHZ_6GHZ, + RTW89_MR_CTX_UNKNOWN, +}; + +struct rtw89_mr_chanctx_info { + enum rtw89_mr_wtype wtype; + enum rtw89_mr_wmode wmode; + enum rtw89_mr_ctxtype ctxtype; +}; + +enum rtw89_chanctx_pause_reasons { + RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, + RTW89_CHANCTX_PAUSE_REASON_ROC, + RTW89_CHANCTX_PAUSE_REASON_GC_BCN_LOSS, +}; + +struct rtw89_chanctx_pause_parm { + const struct rtw89_vif_link *trigger; + enum rtw89_chanctx_pause_reasons rsn; +}; + +struct rtw89_chanctx_cb_parm { + int (*cb)(struct rtw89_dev *rtwdev, void *data); + void *data; + const char *caller; +}; + +struct rtw89_entity_weight { + unsigned int registered_chanctxs; + unsigned int active_chanctxs; + unsigned int active_roles; +}; + +struct rtw89_entity_conf { + bool is_mld; + bool en_emlsr; + DECLARE_BITMAP(hw_bitmap, __RTW89_MLD_MAX_LINK_NUM); + const struct rtw89_chan *chans[__RTW89_MLD_MAX_LINK_NUM]; +}; + +static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + return READ_ONCE(hal->entity_active[phy_idx]); +} + +static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + bool active) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + WRITE_ONCE(hal->entity_active[phy_idx], active); +} + +static inline +enum rtw89_entity_mode rtw89_get_entity_mode(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + return READ_ONCE(hal->entity_mode); +} + +static inline void rtw89_set_entity_mode(struct rtw89_dev *rtwdev, + enum rtw89_entity_mode mode) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + WRITE_ONCE(hal->entity_mode, mode); +} + +void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan, + enum rtw89_band band, enum rtw89_bandwidth bandwidth); +bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct rtw89_chan *new); +int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev, + int (*iterator)(const struct rtw89_chan *chan, + void *data), + void *data); +void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx, + const struct cfg80211_chan_def *chandef); +void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_chan_def *chandef); +void rtw89_entity_init(struct rtw89_dev *rtwdev); +enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev); +bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw89_entity_get_conf(struct rtw89_dev *rtwdev, struct rtw89_entity_conf *conf); +void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev); +void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_changes change); +void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx, + struct rtw89_mr_chanctx_info *info); +void rtw89_chanctx_track(struct rtw89_dev *rtwdev); +void rtw89_chanctx_pause(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_pause_parm *parm); +void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev, + const struct rtw89_chanctx_cb_parm *cb_parm); + +struct rtw89_mcc_links_info { + struct rtw89_vif_link *links[NUM_OF_RTW89_MCC_ROLES]; +}; + +void rtw89_mcc_get_links(struct rtw89_dev *rtwdev, struct rtw89_mcc_links_info *info); +void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_mcc_gc_detect_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); +bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); + +int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx); +void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx); +void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, + struct ieee80211_chanctx_conf *ctx, + u32 changed); +int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *ctx); +void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *ctx); +int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_chanctx_conf *old_ctx, + struct ieee80211_chanctx_conf *new_ctx, + bool replace); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c new file mode 100644 index 000000000..5a9dc4d8a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -0,0 +1,13370 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" + +#define RTW89_COEX_VERSION 0x09180113 +#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ +#define BTC_E2G_LIMIT_DEF 80 + +enum btc_fbtc_tdma_template { + CXTD_OFF = 0x0, + CXTD_OFF_B2, + CXTD_OFF_EXT, + CXTD_FIX, + CXTD_PFIX, + CXTD_AUTO, + CXTD_PAUTO, + CXTD_AUTO2, + CXTD_PAUTO2, + CXTD_MAX, +}; + +enum btc_fbtc_tdma_type { + CXTDMA_OFF = 0x0, + CXTDMA_FIX = 0x1, + CXTDMA_AUTO = 0x2, + CXTDMA_AUTO2 = 0x3, + CXTDMA_MAX +}; + +enum btc_fbtc_tdma_rx_flow_ctrl { + CXFLC_OFF = 0x0, + CXFLC_NULLP = 0x1, + CXFLC_QOSNULL = 0x2, + CXFLC_CTS = 0x3, + CXFLC_MAX +}; + +enum btc_fbtc_tdma_wlan_tx_pause { + CXTPS_OFF = 0x0, /* no wl tx pause*/ + CXTPS_ON = 0x1, + CXTPS_MAX +}; + +enum btc_mlme_state { + MLME_NO_LINK, + MLME_LINKING, + MLME_LINKED, +}; + +struct btc_fbtc_1slot { + u8 fver; + u8 sid; /* slot id */ + struct rtw89_btc_fbtc_slot slot; +} __packed; + +static const struct rtw89_btc_fbtc_tdma t_def[] = { + [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, + [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0}, + [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0}, + [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, + [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, + [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, + [CXTD_PAUTO] = { CXTDMA_AUTO, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, + [CXTD_AUTO2] = {CXTDMA_AUTO2, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, + [CXTD_PAUTO2] = {CXTDMA_AUTO2, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0} +}; + +#define __DEF_FBTC_SLOT(__dur, __cxtbl, __cxtype) \ + { .dur = cpu_to_le16(__dur), .cxtbl = cpu_to_le32(__cxtbl), \ + .cxtype = cpu_to_le16(__cxtype),} + +static const struct rtw89_btc_fbtc_slot s_def[] = { + [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), + [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO), + [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO), + [CXST_W2] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), + [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), + [CXST_B1] = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX), + [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX), + [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), + [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), + [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), + [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), + [CXST_E2G] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_MIX), + [CXST_E5G] = __DEF_FBTC_SLOT(5, 0xffffffff, SLOT_ISO), + [CXST_EBT] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), + [CXST_ENULL] = __DEF_FBTC_SLOT(5, 0x55555555, SLOT_MIX), + [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), + [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), + [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), +}; + +static const u32 cxtbl[] = { + 0xffffffff, /* 0 */ + 0xaaaaaaaa, /* 1 */ + 0xe5555555, /* 2 */ + 0xee555555, /* 3 */ + 0xd5555555, /* 4 */ + 0x5a5a5a5a, /* 5 */ + 0xfa5a5a5a, /* 6 */ + 0xda5a5a5a, /* 7 */ + 0xea5a5a5a, /* 8 */ + 0x6a5a5aaa, /* 9 */ + 0x6a5a6a5a, /* 10 */ + 0x6a5a6aaa, /* 11 */ + 0x6afa5afa, /* 12 */ + 0xaaaa5aaa, /* 13 */ + 0xaaffffaa, /* 14 */ + 0xaa5555aa, /* 15 */ + 0xfafafafa, /* 16 */ + 0xffffddff, /* 17 */ + 0xdaffdaff, /* 18 */ + 0xfafadafa, /* 19 */ + 0xea6a6a6a, /* 20 */ + 0xea55556a, /* 21 */ + 0xaafafafa, /* 22 */ + 0xfafaaafa, /* 23 */ + 0xfafffaff, /* 24 */ + 0xea6a5a5a, /* 25 */ + 0xfaff5aff, /* 26 */ + 0xffffdfff, /* 27 */ + 0xe6555555, /* 28 */ +}; + +static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { + /* firmware version must be in decreasing order for each chip */ + {RTL8922D, RTW89_FW_VER_CODE(0, 35, 111, 0), + .fcxbtcrpt = 11, .fcxtdma = 8, .fcxslots = 7, .fcxcysta = 8, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 8, .fcxbtscan = 8, .fcxbtafh = 8, .fcxbtdevinfo = 8, + .fwlrole = 10, .frptmap = 5, .fcxctrl = 9, .fcxinit = 11, + .fwevntrptl = 1, .fwc2hfunc = 4, .drvinfo_ver = 3, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 6, .fcxmlo = 2, .bt_desired = 8, + .fcxtrx = 9, + }, + {RTL8922D, RTW89_FW_VER_CODE(0, 35, 94, 0), + .fcxbtcrpt = 11, .fcxtdma = 8, .fcxslots = 7, .fcxcysta = 8, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 8, .fcxbtscan = 8, .fcxbtafh = 8, .fcxbtdevinfo = 8, + .fwlrole = 10, .frptmap = 5, .fcxctrl = 9, .fcxinit = 10, + .fwevntrptl = 1, .fwc2hfunc = 4, .drvinfo_ver = 3, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 6, .fcxmlo = 2, .bt_desired = 8, + .fcxtrx = 9, + }, + {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 133, 0), + .fcxbtcrpt = 9, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 5, .fcxctrl = 7, .fcxinit = 107, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 103, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 107, + }, + {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 122, 0), + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 0, + }, + {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0), + .fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 0, + }, + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 111, 0), + .fcxbtcrpt = 11, .fcxtdma = 8, .fcxslots = 7, .fcxcysta = 8, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 8, .fcxbtscan = 8, .fcxbtafh = 8, .fcxbtdevinfo = 8, + .fwlrole = 10, .frptmap = 5, .fcxctrl = 9, .fcxinit = 11, + .fwevntrptl = 1, .fwc2hfunc = 4, .drvinfo_ver = 3, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 6, .fcxmlo = 2, .bt_desired = 8, + .fcxtrx = 9, + }, + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 71, 0), + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 3, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9, + .fcxtrx = 7, + }, + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 63, 0), + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 2, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9, + .fcxtrx = 0, + }, + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_ver = 1, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8851B, RTW89_FW_VER_CODE(0, 29, 133, 0), + .fcxbtcrpt = 9, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 5, .fcxctrl = 7, .fcxinit = 107, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 103, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 107, + }, + {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), + .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852C, RTW89_FW_VER_CODE(0, 27, 97, 0), + .fcxbtcrpt = 4, .fcxtdma = 4, .fcxslots = 2, .fcxcysta = 105, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 101, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 107, + }, + {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), + .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0), + .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0), + .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 133, 0), + .fcxbtcrpt = 9, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 105, .fcxctrl = 7, .fcxinit = 107, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 103, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 107, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 122, 0), + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, + .fcxtrx = 0, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), + .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), + .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800, + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0), + .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0), + .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_ver = 0, .info_buf = 1280, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0), + .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, + .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, + .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_ver = 0, .info_buf = 1024, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, + + /* keep it to be the last as default entry */ + {0, RTW89_FW_VER_CODE(0, 0, 0, 0), + .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, + .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, + .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1024, + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, + .fcxtrx = 0, + }, +}; + +#define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1) + +static const union rtw89_btc_wl_state_map btc_scanning_map = { + .map = { + .scan = 1, + .dhcp = 1, + .roaming = 1, + .transacting = 1, + ._4way = 1, + .handshake = 1, + }, +}; + +static u32 chip_id_to_bt_rom_code_id(u32 id) +{ + switch (id) { + case RTL8852A: + case RTL8852B: + case RTL8852C: + case RTL8852BT: + return 0x8852; + case RTL8851B: + return 0x8851; + case RTL8922A: + case RTL8922D: + return 0x8922; + default: + return 0; + } +} + +#define CASE_BTC_MLME_STATE(e) case MLME_##e: return #e + +static const char *id_to_mlme_state(u32 id) +{ + switch (id) { + CASE_BTC_MLME_STATE(NO_LINK); + CASE_BTC_MLME_STATE(LINKING); + CASE_BTC_MLME_STATE(LINKED); + default: + return "unknown"; + } +} + +static char *chip_id_str(u32 id) +{ + switch (id) { + case RTL8852A: + return "RTL8852A"; + case RTL8852B: + return "RTL8852B"; + case RTL8852C: + return "RTL8852C"; + case RTL8852BT: + return "RTL8852BT"; + case RTL8851B: + return "RTL8851B"; + case RTL8922A: + return "RTL8922A"; + case RTL8922D: + return "RTL8922D"; + default: + return "UNKNOWN"; + } +} + +struct rtw89_btc_btf_tlv { + u8 type; + u8 len; + u8 val[]; +} __packed; + +struct rtw89_btc_btf_tlv_v7 { + u8 type; + u8 ver; + u8 len; + u8 val[]; +} __packed; + +enum btc_btf_set_report_en { + RPT_EN_TDMA, + RPT_EN_CYCLE, + RPT_EN_MREG, + RPT_EN_BT_VER_INFO, + RPT_EN_BT_SCAN_INFO, + RPT_EN_BT_DEVICE_INFO, + RPT_EN_BT_AFH_MAP, + RPT_EN_BT_AFH_MAP_LE, + RPT_EN_BT_TX_PWR_LVL, + RPT_EN_FW_STEP_INFO, + RPT_EN_TEST, + RPT_EN_WL_ALL, + RPT_EN_BT_ALL, + RPT_EN_ALL, + RPT_EN_MONITER, +}; + +struct rtw89_btc_btf_set_report_v1 { + u8 fver; + __le32 enable; + __le32 para; +} __packed; + +struct rtw89_btc_btf_set_report_v8 { + u8 type; + u8 fver; + u8 len; + __le32 map; +} __packed; + +union rtw89_fbtc_rtp_ctrl { + struct rtw89_btc_btf_set_report_v1 v1; + struct rtw89_btc_btf_set_report_v8 v8; +}; + +#define BTF_SET_SLOT_TABLE_VER 1 +struct rtw89_btc_btf_set_slot_table { + u8 fver; + u8 tbl_num; + struct rtw89_btc_fbtc_slot tbls[] __counted_by(tbl_num); +} __packed; + +struct rtw89_btc_btf_set_slot_table_v7 { + u8 type; + u8 ver; + u8 len; + struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; +} __packed; + +struct rtw89_btc_btf_set_mon_reg_v1 { + u8 fver; + u8 reg_num; + struct rtw89_btc_fbtc_mreg regs[] __counted_by(reg_num); +} __packed; + +struct rtw89_btc_btf_set_mon_reg_v7 { + u8 type; + u8 fver; + u8 len; + struct rtw89_btc_fbtc_mreg regs[] __counted_by(len); +} __packed; + +union rtw89_fbtc_set_mon_reg { + struct rtw89_btc_btf_set_mon_reg_v1 v1; + struct rtw89_btc_btf_set_mon_reg_v7 v7; +} __packed; + +enum btc_btf_set_cx_policy { + CXPOLICY_TDMA = 0x0, + CXPOLICY_SLOT = 0x1, + CXPOLICY_TYPE = 0x2, + CXPOLICY_MAX, +}; + +enum btc_b2w_scoreboard { + BTC_BSCB_ACT = BIT(0), + BTC_BSCB_ON = BIT(1), + BTC_BSCB_WHQL = BIT(2), + BTC_BSCB_BT_S1 = BIT(3), + BTC_BSCB_A2DP_ACT = BIT(4), + BTC_BSCB_RFK_RUN = BIT(5), + BTC_BSCB_RFK_REQ = BIT(6), + BTC_BSCB_LPS = BIT(7), + BTC_BSCB_BT_LNAB0 = BIT(8), + BTC_BSCB_BT_LNAB1 = BIT(10), + BTC_BSCB_WLRFK = BIT(11), + BTC_BSCB_BT_HILNA = BIT(13), + BTC_BSCB_BT_HILNA_56G = BIT(14), + BTC_BSCB_CTCODE = BIT(15), + BTC_BSCB_BT_CONNECT = BIT(16), + BTC_BSCB_BT_CONNECT_56G = BIT(17), + BTC_BSCB_BT_LNAB0_56G = BIT(18), + BTC_BSCB_BT_LNAB1_56G = BIT(19), + BTC_BSCB_BT_15DOT4 = BIT(24), + BTC_BSCB_BT_PROTECT = BIT(27), + BTC_BSCB_PAN_ACT = BIT(28), + BTC_BSCB_HFP_ACT = BIT(29), + BTC_BSCB_PATCH_CODE = BIT(30), + BTC_BSCB_ALL = GENMASK(30, 0), +}; + +enum btc_phymap { + BTC_PHY_0 = BIT(0), + BTC_PHY_1 = BIT(1), + BTC_PHY_ALL = BIT(0) | BIT(1), +}; + +enum btc_cx_state_map { + BTC_WIDLE = 0, + BTC_WBUSY_BNOSCAN, + BTC_WBUSY_BSCAN, + BTC_WSCAN_BNOSCAN, + BTC_WSCAN_BSCAN, + BTC_WLINKING +}; + +enum btc_ant_phase { + BTC_ANT_WPOWERON = 0, + BTC_ANT_WINIT, + BTC_ANT_WONLY, + BTC_ANT_WOFF, + BTC_ANT_W2G, + BTC_ANT_FDD, + BTC_ANT_W25G, + BTC_ANT_FREERUN, + BTC_ANT_WRFK, + BTC_ANT_WRFK2, + BTC_ANT_PTA, /* for Multi-PTA, each hw-band has its own PTA */ + BTC_ANT_MAX +}; + +enum btc_plt { + BTC_PLT_NONE = 0, + BTC_PLT_LTE_RX = BIT(0), + BTC_PLT_GNT_BT_TX = BIT(1), + BTC_PLT_GNT_BT_RX = BIT(2), + BTC_PLT_GNT_WL = BIT(3), + BTC_PLT_BT = BIT(1) | BIT(2), + BTC_PLT_ALL = 0xf +}; + +enum btc_cx_poicy_main_type { + BTC_CXP_OFF = 0, + BTC_CXP_OFFB, + BTC_CXP_OFFE, + BTC_CXP_FIX, + BTC_CXP_PFIX, + BTC_CXP_AUTO, + BTC_CXP_PAUTO, + BTC_CXP_AUTO2, + BTC_CXP_PAUTO2, + BTC_CXP_MANUAL, + BTC_CXP_USERDEF0, + BTC_CXP_MAIN_MAX +}; + +enum btc_bslot_length { + BTC_BSLOT_A2DP_HID = 60, + BTC_BSLOT_A2DP = 50, + BTC_BSLOT_A2DP_2 = 40, + BTC_BSLOT_INQ = 30, + BTC_BSLOT_IDLE = 20, +}; + +enum btc_cx_poicy_type { + /* TDMA off + pri: BT > WL */ + BTC_CXP_OFF_BT = (BTC_CXP_OFF << 8) | 0, + + /* TDMA off + pri: WL > BT */ + BTC_CXP_OFF_WL = (BTC_CXP_OFF << 8) | 1, + + /* TDMA off + pri: BT = WL */ + BTC_CXP_OFF_EQ0 = (BTC_CXP_OFF << 8) | 2, + + /* TDMA off + pri: BT = WL > BT_Lo */ + BTC_CXP_OFF_EQ1 = (BTC_CXP_OFF << 8) | 3, + + /* TDMA off + pri: WL = BT, BT_Rx > WL_Lo_Tx */ + BTC_CXP_OFF_EQ2 = (BTC_CXP_OFF << 8) | 4, + + /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ + BTC_CXP_OFF_EQ3 = (BTC_CXP_OFF << 8) | 5, + + /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ + BTC_CXP_OFF_EQ4 = (BTC_CXP_OFF << 8) | 6, + + /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ + BTC_CXP_OFF_EQ5 = (BTC_CXP_OFF << 8) | 7, + + /* TDMA off + pri: BT_Hi > WL > BT_Lo */ + BTC_CXP_OFF_BWB0 = (BTC_CXP_OFF << 8) | 8, + + /* TDMA off + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */ + BTC_CXP_OFF_BWB1 = (BTC_CXP_OFF << 8) | 9, + + /* TDMA off + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */ + BTC_CXP_OFF_BWB2 = (BTC_CXP_OFF << 8) | 10, + + /* TDMA off + pri: WL_Hi-Tx = BT */ + BTC_CXP_OFF_BWB3 = (BTC_CXP_OFF << 8) | 11, + + /* TDMA off + pri: WL > BT, Block-BT*/ + BTC_CXP_OFF_WL2 = (BTC_CXP_OFF << 8) | 12, + + /* TDMA off+Bcn-Protect + pri: BT_Hi > WL > BT_Lo */ + BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0, + + /* TDMA off+Bcn-Protect + pri: BT_Hi_Tx = WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */ + BTC_CXP_OFFB_BWB1 = (BTC_CXP_OFFB << 8) | 1, + + /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */ + BTC_CXP_OFFB_BWB2 = (BTC_CXP_OFFB << 8) | 2, + + /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx = BT*/ + BTC_CXP_OFFB_BWB3 = (BTC_CXP_OFFB << 8) | 3, + + /* TDMA off+Bcn-Protect + pri: BT > WL*/ + BTC_CXP_OFFB_BWB4 = (BTC_CXP_OFFB << 8) | 4, + + /* TDMA off + Ext-Ctrl + pri: default */ + BTC_CXP_OFFE_DEF = (BTC_CXP_OFFE << 8) | 0, + + /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ + BTC_CXP_OFFE_DEF2 = (BTC_CXP_OFFE << 8) | 1, + + /* TDMA off + Ext-Ctrl + pri: default */ + BTC_CXP_OFFE_2GBWISOB = (BTC_CXP_OFFE << 8) | 2, + + /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ + BTC_CXP_OFFE_2GISOB = (BTC_CXP_OFFE << 8) | 3, + + /* TDMA off + Ext-Ctrl + pri: E2G-slot WL > BT */ + BTC_CXP_OFFE_2GBWMIXB = (BTC_CXP_OFFE << 8) | 4, + + /* TDMA off + Ext-Ctrl + pri: E2G/EBT-slot WL > BT */ + BTC_CXP_OFFE_WL = (BTC_CXP_OFFE << 8) | 5, + + /* TDMA off + Ext-Ctrl + pri: default */ + BTC_CXP_OFFE_2GBWMIXB2 = (BTC_CXP_OFFE << 8) | 6, + + /* TDMA Fix slot-0: W1:B1 = 30:30 */ + BTC_CXP_FIX_TD3030 = (BTC_CXP_FIX << 8) | 0, + + /* TDMA Fix slot-1: W1:B1 = 50:50 */ + BTC_CXP_FIX_TD5050 = (BTC_CXP_FIX << 8) | 1, + + /* TDMA Fix slot-2: W1:B1 = 20:30 */ + BTC_CXP_FIX_TD2030 = (BTC_CXP_FIX << 8) | 2, + + /* TDMA Fix slot-3: W1:B1 = 40:10 */ + BTC_CXP_FIX_TD4010 = (BTC_CXP_FIX << 8) | 3, + + /* TDMA Fix slot-4: W1:B1 = 70:10 */ + BTC_CXP_FIX_TD7010 = (BTC_CXP_FIX << 8) | 4, + + /* TDMA Fix slot-5: W1:B1 = 20:60 */ + BTC_CXP_FIX_TD2060 = (BTC_CXP_FIX << 8) | 5, + + /* TDMA Fix slot-6: W1:B1 = 30:60 */ + BTC_CXP_FIX_TD3060 = (BTC_CXP_FIX << 8) | 6, + + /* TDMA Fix slot-7: W1:B1 = 20:80 */ + BTC_CXP_FIX_TD2080 = (BTC_CXP_FIX << 8) | 7, + + /* TDMA Fix slot-8: W1:B1 = user-define */ + BTC_CXP_FIX_TDW1B1 = (BTC_CXP_FIX << 8) | 8, + + /* TDMA Fix slot-9: W1:B1 = 40:10 */ + BTC_CXP_FIX_TD4010ISO = (BTC_CXP_FIX << 8) | 9, + + /* TDMA Fix slot-10: W1:B1 = 40:10 */ + BTC_CXP_FIX_TD4010ISO_DL = (BTC_CXP_FIX << 8) | 10, + + /* TDMA Fix slot-11: W1:B1 = 40:10 */ + BTC_CXP_FIX_TD4010ISO_UL = (BTC_CXP_FIX << 8) | 11, + + /* PS-TDMA Fix slot-0: W1:B1 = 30:30 */ + BTC_CXP_PFIX_TD3030 = (BTC_CXP_PFIX << 8) | 0, + + /* PS-TDMA Fix slot-1: W1:B1 = 50:50 */ + BTC_CXP_PFIX_TD5050 = (BTC_CXP_PFIX << 8) | 1, + + /* PS-TDMA Fix slot-2: W1:B1 = 20:30 */ + BTC_CXP_PFIX_TD2030 = (BTC_CXP_PFIX << 8) | 2, + + /* PS-TDMA Fix slot-3: W1:B1 = 20:60 */ + BTC_CXP_PFIX_TD2060 = (BTC_CXP_PFIX << 8) | 3, + + /* PS-TDMA Fix slot-4: W1:B1 = 30:70 */ + BTC_CXP_PFIX_TD3070 = (BTC_CXP_PFIX << 8) | 4, + + /* PS-TDMA Fix slot-5: W1:B1 = 20:80 */ + BTC_CXP_PFIX_TD2080 = (BTC_CXP_PFIX << 8) | 5, + + /* PS-TDMA Fix slot-6: W1:B1 = user-define */ + BTC_CXP_PFIX_TDW1B1 = (BTC_CXP_PFIX << 8) | 6, + + /* TDMA Auto slot-0: W1:B1 = 50:200 */ + BTC_CXP_AUTO_TD50B1 = (BTC_CXP_AUTO << 8) | 0, + + /* TDMA Auto slot-1: W1:B1 = 60:200 */ + BTC_CXP_AUTO_TD60B1 = (BTC_CXP_AUTO << 8) | 1, + + /* TDMA Auto slot-2: W1:B1 = 20:200 */ + BTC_CXP_AUTO_TD20B1 = (BTC_CXP_AUTO << 8) | 2, + + /* TDMA Auto slot-3: W1:B1 = user-define */ + BTC_CXP_AUTO_TDW1B1 = (BTC_CXP_AUTO << 8) | 3, + + /* PS-TDMA Auto slot-0: W1:B1 = 50:200 */ + BTC_CXP_PAUTO_TD50B1 = (BTC_CXP_PAUTO << 8) | 0, + + /* PS-TDMA Auto slot-1: W1:B1 = 60:200 */ + BTC_CXP_PAUTO_TD60B1 = (BTC_CXP_PAUTO << 8) | 1, + + /* PS-TDMA Auto slot-2: W1:B1 = 20:200 */ + BTC_CXP_PAUTO_TD20B1 = (BTC_CXP_PAUTO << 8) | 2, + + /* PS-TDMA Auto slot-3: W1:B1 = user-define */ + BTC_CXP_PAUTO_TDW1B1 = (BTC_CXP_PAUTO << 8) | 3, + + /* TDMA Auto slot2-0: W1:B4 = 30:50 */ + BTC_CXP_AUTO2_TD3050 = (BTC_CXP_AUTO2 << 8) | 0, + + /* TDMA Auto slot2-1: W1:B4 = 30:70 */ + BTC_CXP_AUTO2_TD3070 = (BTC_CXP_AUTO2 << 8) | 1, + + /* TDMA Auto slot2-2: W1:B4 = 50:50 */ + BTC_CXP_AUTO2_TD5050 = (BTC_CXP_AUTO2 << 8) | 2, + + /* TDMA Auto slot2-3: W1:B4 = 60:60 */ + BTC_CXP_AUTO2_TD6060 = (BTC_CXP_AUTO2 << 8) | 3, + + /* TDMA Auto slot2-4: W1:B4 = 20:80 */ + BTC_CXP_AUTO2_TD2080 = (BTC_CXP_AUTO2 << 8) | 4, + + /* TDMA Auto slot2-5: W1:B4 = user-define */ + BTC_CXP_AUTO2_TDW1B4 = (BTC_CXP_AUTO2 << 8) | 5, + + /* PS-TDMA Auto slot2-0: W1:B4 = 30:50 */ + BTC_CXP_PAUTO2_TD3050 = (BTC_CXP_PAUTO2 << 8) | 0, + + /* PS-TDMA Auto slot2-1: W1:B4 = 30:70 */ + BTC_CXP_PAUTO2_TD3070 = (BTC_CXP_PAUTO2 << 8) | 1, + + /* PS-TDMA Auto slot2-2: W1:B4 = 50:50 */ + BTC_CXP_PAUTO2_TD5050 = (BTC_CXP_PAUTO2 << 8) | 2, + + /* PS-TDMA Auto slot2-3: W1:B4 = 60:60 */ + BTC_CXP_PAUTO2_TD6060 = (BTC_CXP_PAUTO2 << 8) | 3, + + /* PS-TDMA Auto slot2-4: W1:B4 = 20:80 */ + BTC_CXP_PAUTO2_TD2080 = (BTC_CXP_PAUTO2 << 8) | 4, + + /* PS-TDMA Auto slot2-5: W1:B4 = user-define */ + BTC_CXP_PAUTO2_TDW1B4 = (BTC_CXP_PAUTO2 << 8) | 5, + + BTC_CXP_MAX = 0xffff +}; + +enum btc_wl_rfk_result { + BTC_WRFK_REJECT = 0, + BTC_WRFK_ALLOW = 1, +}; + +enum btc_coex_info_map_en { + BTC_COEX_INFO_CX = BIT(0), + BTC_COEX_INFO_WL = BIT(1), + BTC_COEX_INFO_BT = BIT(2), + BTC_COEX_INFO_DM = BIT(3), + BTC_COEX_INFO_MREG = BIT(4), + BTC_COEX_INFO_SUMMARY = BIT(5), + BTC_COEX_INFO_ALL = GENMASK(7, 0), +}; + +#define BTC_CXP_MASK GENMASK(15, 8) + +enum btc_w2b_scoreboard { + BTC_WSCB_ACTIVE = BIT(0), + BTC_WSCB_ON = BIT(1), + BTC_WSCB_SCAN = BIT(2), + BTC_WSCB_UNDERTEST = BIT(3), + BTC_WSCB_RXGAIN = BIT(4), + BTC_WSCB_5GHICH = BIT(6), + BTC_WSCB_WLBUSY = BIT(7), + BTC_WSCB_EXTFEM = BIT(8), + BTC_WSCB_TDMA = BIT(9), + BTC_WSCB_FIX2M = BIT(10), + BTC_WSCB_WLRFK = BIT(11), + BTC_WSCB_RXSCAN_PRI = BIT(12), + BTC_WSCB_BT_HILNA = BIT(13), + BTC_WSCB_BTLOG = BIT(14), + BTC_WSCB_CTCODE = BIT(15), + BTC_WSCB_RXGAIN_56G = BIT(16), + BTC_WSCB_BT_HILNA_56G = BIT(17), + BTC_WSCB_ALL = GENMASK(23, 0), +}; + +enum btc_wl_link_mode_v0 { + BTC_WLINK_V0_NOLINK = 0x0, + BTC_WLINK_V0_2G_STA, + BTC_WLINK_V0_2G_AP, + BTC_WLINK_V0_2G_GO, + BTC_WLINK_V0_2G_GC, + BTC_WLINK_V0_2G_SCC, + BTC_WLINK_V0_2G_MCC, + BTC_WLINK_V0_25G_MCC, + BTC_WLINK_V0_25G_DBCC, + BTC_WLINK_V0_5G, + BTC_WLINK_V0_2G_NAN, + BTC_WLINK_V0_OTHER, + BTC_WLINK_V0_MAX +}; + +enum btc_wl_link_mode_v1 { + BTC_WLINK_NOLINK = 0x0, + BTC_WLINK_STA, + BTC_WLINK_AP, + BTC_WLINK_GO, + BTC_WLINK_GC, + BTC_WLINK_SCC, + BTC_WLINK_SB_MCC, + BTC_WLINK_DB_MCC, /* 2+0/0+2 Dual-RF-band MCC */ + BTC_WLINK_MAX +}; + +#define CASE_BTC_WL_LINK_MODE(e) case BTC_WLINK_## e: return #e + +static const char *id_to_linkmode(u8 id) +{ + switch (id) { + CASE_BTC_WL_LINK_MODE(NOLINK); + CASE_BTC_WL_LINK_MODE(STA); + CASE_BTC_WL_LINK_MODE(AP); + CASE_BTC_WL_LINK_MODE(GO); + CASE_BTC_WL_LINK_MODE(GC); + CASE_BTC_WL_LINK_MODE(SCC); + CASE_BTC_WL_LINK_MODE(SB_MCC); + CASE_BTC_WL_LINK_MODE(DB_MCC); + default: + return "unknown"; + } +} + +enum btc_wl_mrole_type { + BTC_WLMROLE_NONE = 0x0, + BTC_WLMROLE_STA_GC, + BTC_WLMROLE_STA_GC_NOA, + BTC_WLMROLE_STA_GO, + BTC_WLMROLE_STA_GO_NOA, + BTC_WLMROLE_STA_STA, + BTC_WLMROLE_MAX +}; + +enum btc_bt_hid_type { + BTC_HID_218 = BIT(0), + BTC_HID_418 = BIT(1), + BTC_HID_BLE = BIT(2), + BTC_HID_RCU = BIT(3), + BTC_HID_RCU_VOICE = BIT(4), + BTC_HID_OTHER_LEGACY = BIT(5) +}; + +enum btc_reset_module { + BTC_RESET_CX = BIT(0), + BTC_RESET_DM = BIT(1), + BTC_RESET_CTRL = BIT(2), + BTC_RESET_CXDM = BIT(0) | BIT(1), + BTC_RESET_BTINFO = BIT(3), + BTC_RESET_MDINFO = BIT(4), + BTC_RESET_BT_PSD_DM = BIT(5), + BTC_RESET_BTINFO2 = BIT(6), + BTC_RESET_ALL = GENMASK(7, 0), +}; + +enum btc_gnt_state { + BTC_GNT_HW = 0, + BTC_GNT_SW_LO, + BTC_GNT_SW_HI, + BTC_GNT_MAX, + + BTC_GNT_SET_SKIP = 0xff, +}; + +enum btc_ctr_path { + BTC_CTRL_BY_BT = 0, + BTC_CTRL_BY_WL +}; + +enum btc_wlact_state { + BTC_WLACT_HW = 0, + BTC_WLACT_SW_LO, + BTC_WLACT_SW_HI, + BTC_WLACT_MAX, +}; + +enum btc_wl_max_tx_time { + BTC_MAX_TX_TIME_L1 = 500, + BTC_MAX_TX_TIME_L2 = 1000, + BTC_MAX_TX_TIME_L3 = 2000, + BTC_MAX_TX_TIME_DEF = 5280 +}; + +enum btc_wl_max_tx_retry { + BTC_MAX_TX_RETRY_L1 = 7, + BTC_MAX_TX_RETRY_L2 = 15, + BTC_MAX_TX_RETRY_DEF = 31, +}; + +enum btc_reason_and_action { + BTC_RSN_NONE, + BTC_RSN_NTFY_INIT, + BTC_RSN_NTFY_SWBAND, + BTC_RSN_NTFY_WL_STA, + BTC_RSN_NTFY_RADIO_STATE, + BTC_RSN_UPDATE_BT_SCBD, + BTC_RSN_NTFY_WL_RFK, + BTC_RSN_UPDATE_BT_INFO, + BTC_RSN_NTFY_SCAN_START, + BTC_RSN_NTFY_SCAN_FINISH, + BTC_RSN_NTFY_SPECIFIC_PACKET, + BTC_RSN_NTFY_POWEROFF, + BTC_RSN_NTFY_ROLE_INFO, + BTC_RSN_CMD_SET_COEX, + BTC_RSN_ACT1_WORK, + BTC_RSN_BT_DEVINFO_WORK, + BTC_RSN_RFK_CHK_WORK, + BTC_RSN_UPDATE_BT_LEAUDINFO, + BTC_RSN_NUM, + BTC_ACT_NONE = 100, + BTC_ACT_WL_ONLY, + BTC_ACT_WL_5G, + BTC_ACT_WL_OTHER, + BTC_ACT_WL_IDLE, + BTC_ACT_WL_NC, + BTC_ACT_WL_RFK, + BTC_ACT_WL_INIT, + BTC_ACT_WL_OFF, + BTC_ACT_FREERUN, + BTC_ACT_BT_WHQL, + BTC_ACT_BT_RFK, + BTC_ACT_BT_OFF, + BTC_ACT_BT_IDLE, + BTC_ACT_BT_HFP, + BTC_ACT_BT_HID, + BTC_ACT_BT_A2DP, + BTC_ACT_BT_A2DPSINK, + BTC_ACT_BT_PAN, + BTC_ACT_BT_A2DP_HID, + BTC_ACT_BT_A2DP_PAN, + BTC_ACT_BT_PAN_HID, + BTC_ACT_BT_A2DP_PAN_HID, + BTC_ACT_BT_BIS, + BTC_ACT_BT_CIS, + BTC_ACT_WL_25G_MCC, + BTC_ACT_WL_2G_MCC, + BTC_ACT_WL_2G_SCC, + BTC_ACT_WL_2G_AP, + BTC_ACT_WL_2G_GO, + BTC_ACT_WL_2G_GC, + BTC_ACT_WL_2G_NAN, + BTC_ACT_LAST, + BTC_ACT_NUM = BTC_ACT_LAST - BTC_ACT_NONE, + BTC_ACT_EXT_BIT = BIT(14), + BTC_POLICY_EXT_BIT = BIT(15), +}; + +#define BTC_FREERUN_ANTISO_MIN 30 +#define BTC_TDMA_BTHID_MAX 2 +#define BTC_BLINK_NOCONNECT 0 +#define BTC_B1_MAX 250 /* unit ms */ + +static void _run_coex(struct rtw89_dev *rtwdev, + enum btc_reason_and_action reason); +static void _write_scbd(struct rtw89_dev *rtwdev, u8 bid, u32 val, bool state); +static u8 _sned_h2c_w2bscbd(struct rtw89_dev *rtwdev, bool force_exec, u8 bid); +static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid); +static const char *id_to_h2c(u32 id); + +static void _reset_h2c_macro(struct rtw89_btc *btc) +{ + btc->hbuf_len = 0; + btc->hbuf_cnt = 0; + memset(btc->hbuf, 0, BTC_H2C_MAXLEN); +} + +static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, + void *param, u16 len) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_dm *dm = &btc->dm; + u8 h2c_func_mask, bid = BTC_BT_1ST; + u8 *buf = param; + int ret; + + if (len > BTC_H2C_MAXLEN || len == 0) { + btc->fwinfo.cnt_h2c_fail++; + dm->error.map.h2c_buffer_over = true; + return -EINVAL; + } else if (!wl->status.map.init_ok) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return by btc not init!!\n", __func__); + pfwinfo->cnt_h2c_fail++; + return -EINVAL; + } else if ((wl->status.map.rf_off_pre == BTC_LPS_RF_OFF && + wl->status.map.rf_off == BTC_LPS_RF_OFF) || + (wl->status.map.lps_pre == BTC_LPS_RF_OFF && + wl->status.map.lps == BTC_LPS_RF_OFF)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return by wl off!!\n", __func__); + pfwinfo->cnt_h2c_fail++; + return -EINVAL; + } + + h2c_func_mask = h2c_func & (~BT_H2C_FUNC_BT2ND); + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) + bid = !!(h2c_func & BT_H2C_FUNC_BT2ND); + + if (btc->io_oflld_type != BTC_IO_OFLD_BTC_H2C || btc->cli_h2c_cmd || + h2c_func_mask == SET_H2C_MACRO || + (h2c_func_mask == SET_DRV_INFO && buf[0] == CXDRVINFO_TRX) || + (h2c_func_mask == SET_IOFLD_SCBD && dm->scbd_write_instant) || + h2c_func_mask == SET_BT_LNA_CONSTRAIN) { + h2c_class = BTFC_SET; + + ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, + buf, len, false, true); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s():class=%d, bt%d-func=%s, len=%d\n", + __func__, h2c_class, bid, + id_to_h2c(h2c_func_mask), len); + + if (h2c_func_mask == SET_H2C_MACRO) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s():Send H2C-MACRO cnt=%d, len=%d\n", + __func__, btc->hbuf_cnt, btc->hbuf_len); + _reset_h2c_macro(btc); /* clear H2C MACRO buffer */ + } + + if (ret != 0) { /* Send H2C fail */ + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s():return by rtw_hal_mac_send_h2c\n", + __func__); + btc->fwinfo.cnt_h2c_fail++; + return 0; + } + + btc->fwinfo.cnt_h2c++; + return 0; + } else { /* Fill H2C MACRO buffer(TLV format) temporarily */ + if (btc->hbuf_cnt == 0) + _reset_h2c_macro(btc); + + /* Type:1 byte, Length:2 Bytes, Data:len bytes */ + if (btc->hbuf_len + len + 3 >= BTC_H2C_MAXLEN) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s():return by MACRO buf full(%d)\n", + __func__, btc->hbuf_len + len + 3); + btc->fwinfo.cnt_h2c_fail++; + return 0; + } + + btc->hbuf[btc->hbuf_len] = h2c_func; + btc->hbuf[btc->hbuf_len + 1] = len & GENMASK(7, 0); + btc->hbuf[btc->hbuf_len + 2] = (len & GENMASK(15, 8)) >> 8; + + memcpy(&btc->hbuf[btc->hbuf_len + 3], buf, len); + btc->hbuf_len = btc->hbuf_len + len + 3; + btc->hbuf_cnt++; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s():Buffer H2C-MACRO cnt=%d/bt%d-func=%s/len=%d\n", + __func__, btc->hbuf_cnt, bid, + id_to_h2c(h2c_func_mask), len); + } + + ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, buf, len, + false, true); + if (ret) + pfwinfo->cnt_h2c_fail++; + else + pfwinfo->cnt_h2c++; + + return ret; +} + +#define BTC_DEFAULT_SIR_THRES 51 /* dB, BT Pin - This = TDD/FDD swtch thres */ +#define BTC_FDDR_TP_SETUP_TIME 1 /* in second */ +#define BTC_FDDR_TP_HOLD_TIME 3 /* in second */ +#define BTC_FDDR_RX_LOW_RATE_THRES 4 /* low rate for TDD swotch */ + +static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_bt_info *bt0 = &cx->bt0; + struct rtw89_btc_bt_info *bt1 = &cx->bt1; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); + + if (type & BTC_RESET_CX) { + memset(cx, 0, sizeof(*cx)); + cx->bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR; + cx->bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO; + } + + if (type & BTC_RESET_BTINFO) {/* only for BT enable */ + memset(bt0, 0, sizeof(*bt0)); + bt0->link_info.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR; + bt0->link_info_56g.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR; + bt0->link_info.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR; + bt0->link_info_56g.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR; + bt0->ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO; + } else if (type & BTC_RESET_BTINFO2) { + memset(bt1, 0, sizeof(*bt1)); + bt1->link_info.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR; + bt1->link_info_56g.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR; + bt1->link_info.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR; + bt1->link_info_56g.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR; + bt1->ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO; + } + + if (type & BTC_RESET_CTRL) { + memset(&btc->ctrl, 0, sizeof(btc->ctrl)); + btc->ctrl.trace_step = FCXDEF_STEP; + } + + /* Init Coex variables that are not zero */ + if (type & BTC_RESET_DM) { + memset(&btc->dm, 0, sizeof(btc->dm)); + + /* set the slot_now table to original */ + btc->dm.tdma_now = t_def[CXTD_OFF]; + btc->dm.tdma = t_def[CXTD_OFF]; + if (ver->fcxslots >= 2) { + for (i = 0; i < ARRAY_SIZE(s_def); i++) { + btc->dm.slot.v7[i].dur = s_def[i].dur; + btc->dm.slot.v7[i].cxtype = s_def[i].cxtype; + btc->dm.slot.v7[i].cxtbl = s_def[i].cxtbl; + } + memcpy(&btc->dm.slot_now.v7, &btc->dm.slot.v7, + sizeof(btc->dm.slot_now.v7)); + } else { + memcpy(&btc->dm.slot_now.v1, s_def, + sizeof(btc->dm.slot_now.v1)); + memcpy(&btc->dm.slot.v1, s_def, + sizeof(btc->dm.slot.v1)); + } + + btc->policy_len = 0; + btc->bt_req_len[RTW89_PHY_0] = 0; + btc->bt_req_len[RTW89_PHY_1] = 0; + btc->hubmsg_cnt = 0; + + btc->dm.coex_info_map = BTC_COEX_INFO_ALL; + btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF; + btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF; + btc->dm.bt_slot_flood = BTC_B1_MAX; + btc->dm.sir_thres = BTC_DEFAULT_SIR_THRES; + btc->dm.fddr_info.tp_setup_time = BTC_FDDR_TP_SETUP_TIME; + btc->dm.fddr_info.tp_hold_time = BTC_FDDR_TP_HOLD_TIME; + btc->dm.fddr_info.wl_rx_rate_thres = BTC_FDDR_RX_LOW_RATE_THRES; + btc->dm.fddt_info.type = BTC_FDDT_TYPE_AUTO; + + btc->dm.wl_pre_agc_rb = BTC_PREAGC_NOTFOUND; + btc->dm.wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_NOTFOUND; + } + + if (type & BTC_RESET_MDINFO) { + memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); + btc->mdinfo.ant.isolation = RTW89_BTC_DEFAULT_ANISO; + } +} + +static u8 _search_reg_index(struct rtw89_dev *rtwdev, u8 mreg_num, u16 reg_type, u32 target) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 i; + + for (i = 0; i < mreg_num; i++) + if (le16_to_cpu(chip->mon_reg[i].type) == reg_type && + le32_to_cpu(chip->mon_reg[i].offset) == target) { + return i; + } + return BTC_REG_NOTFOUND; +} + +static void _get_reg_status(struct rtw89_dev *rtwdev, u8 type, u8 *val) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_module *md = &btc->mdinfo; + union rtw89_btc_fbtc_mreg_val *pmreg; + u32 pre_agc_addr = R_BTC_BB_PRE_AGC_S1; + u32 reg_val; + u8 idx; + + if (btc->btg_pos == RF_PATH_A) + pre_agc_addr = R_BTC_BB_PRE_AGC_S0; + + switch (type) { + case BTC_CSTATUS_TXDIV_POS: + if (md->bt0_sw_type == BTC_SWITCH_INTERNAL) + *val = BTC_ANT_DIV_MAIN; + break; + case BTC_CSTATUS_RXDIV_POS: + if (md->bt0_sw_type == BTC_SWITCH_INTERNAL) + *val = BTC_ANT_DIV_MAIN; + break; + case BTC_CSTATUS_BB_GNT_MUX: + reg_val = rtw89_phy_read32(rtwdev, R_BTC_BB_BTG_RX); + *val = !(reg_val & B_BTC_BB_GNT_MUX); + break; + case BTC_CSTATUS_BB_GNT_MUX_MON: + if (!btc->fwinfo.rpt_fbtc_mregval.cinfo.valid) + return; + + pmreg = &btc->fwinfo.rpt_fbtc_mregval.finfo; + if (ver->fcxmreg == 1) { + idx = _search_reg_index(rtwdev, pmreg->v1.reg_num, + REG_BB, R_BTC_BB_BTG_RX); + if (idx == BTC_REG_NOTFOUND) { + *val = BTC_BTGCTRL_BB_GNT_NOTFOUND; + } else { + reg_val = le32_to_cpu(pmreg->v1.mreg_val[idx]); + *val = !(reg_val & B_BTC_BB_GNT_MUX); + } + } else if (ver->fcxmreg == 2) { + idx = _search_reg_index(rtwdev, pmreg->v2.reg_num, + REG_BB, R_BTC_BB_BTG_RX); + if (idx == BTC_REG_NOTFOUND) { + *val = BTC_BTGCTRL_BB_GNT_NOTFOUND; + } else { + reg_val = le32_to_cpu(pmreg->v2.mreg_val[idx]); + *val = !(reg_val & B_BTC_BB_GNT_MUX); + } + } + break; + case BTC_CSTATUS_BB_PRE_AGC: + reg_val = rtw89_phy_read32(rtwdev, pre_agc_addr); + reg_val &= B_BTC_BB_PRE_AGC_MASK; + *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); + break; + case BTC_CSTATUS_BB_PRE_AGC_MON: + if (!btc->fwinfo.rpt_fbtc_mregval.cinfo.valid) + return; + + pmreg = &btc->fwinfo.rpt_fbtc_mregval.finfo; + if (ver->fcxmreg == 1) { + idx = _search_reg_index(rtwdev, pmreg->v1.reg_num, + REG_BB, pre_agc_addr); + if (idx == BTC_REG_NOTFOUND) { + *val = BTC_PREAGC_NOTFOUND; + } else { + reg_val = le32_to_cpu(pmreg->v1.mreg_val[idx]) & + B_BTC_BB_PRE_AGC_MASK; + *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); + } + } else if (ver->fcxmreg == 2) { + idx = _search_reg_index(rtwdev, pmreg->v2.reg_num, + REG_BB, pre_agc_addr); + if (idx == BTC_REG_NOTFOUND) { + *val = BTC_PREAGC_NOTFOUND; + } else { + reg_val = le32_to_cpu(pmreg->v2.mreg_val[idx]) & + B_BTC_BB_PRE_AGC_MASK; + *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); + } + } + break; + default: + break; + } +} + +#define BTC_RPT_HDR_SIZE 3 +#define BTC_CHK_WLSLOT_DRIFT_MAX 15 +#define BTC_CHK_BTSLOT_DRIFT_MAX 15 +#define BTC_CHK_HANG_MAX 3 + +static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt = &cx->bt0; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_dm *dm = &btc->dm; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): type:%d cnt:%d\n", + __func__, type, cnt); + + switch (type) { + case BTC_DCNT_WL_FW_VER_MATCH: + if ((wl->ver_info.fw_coex & 0xffff0000) != + rtwdev->chip->wlcx_desired) { + wl->fw_ver_mismatch = true; + dm->error.map.wl_ver_mismatch = true; + } else { + wl->fw_ver_mismatch = false; + dm->error.map.wl_ver_mismatch = false; + } + break; + case BTC_DCNT_RPT_HANG: + if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map) + dm->cnt_dm[BTC_DCNT_RPT_HANG]++; + else + dm->cnt_dm[BTC_DCNT_RPT_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_RPT_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.wl_fw_hang = true; + else + dm->error.map.wl_fw_hang = false; + + dm->cnt_dm[BTC_DCNT_RPT] = cnt; + break; + case BTC_DCNT_CYCLE_HANG: + if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt && + (dm->tdma_now.type != CXTDMA_OFF || + dm->tdma_now.ext_ctrl == CXECTL_EXT)) + dm->cnt_dm[BTC_DCNT_CYCLE_HANG]++; + else + dm->cnt_dm[BTC_DCNT_CYCLE_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_CYCLE_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.cycle_hang = true; + else + dm->error.map.cycle_hang = false; + + dm->cnt_dm[BTC_DCNT_CYCLE] = cnt; + break; + case BTC_DCNT_W1_HANG: + if (dm->cnt_dm[BTC_DCNT_W1] == cnt && + dm->tdma_now.type != CXTDMA_OFF) + dm->cnt_dm[BTC_DCNT_W1_HANG]++; + else + dm->cnt_dm[BTC_DCNT_W1_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_W1_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.w1_hang = true; + else + dm->error.map.w1_hang = false; + + dm->cnt_dm[BTC_DCNT_W1] = cnt; + break; + case BTC_DCNT_B1_HANG: + if (dm->cnt_dm[BTC_DCNT_B1] == cnt && + dm->tdma_now.type != CXTDMA_OFF) + dm->cnt_dm[BTC_DCNT_B1_HANG]++; + else + dm->cnt_dm[BTC_DCNT_B1_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_B1_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.b1_hang = true; + else + dm->error.map.b1_hang = false; + + dm->cnt_dm[BTC_DCNT_B1] = cnt; + break; + case BTC_DCNT_E2G_HANG: + if (dm->cnt_dm[BTC_DCNT_E2G] == cnt && + dm->tdma_now.ext_ctrl == CXECTL_EXT) + dm->cnt_dm[BTC_DCNT_E2G_HANG]++; + else + dm->cnt_dm[BTC_DCNT_E2G_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_E2G_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.wl_e2g_hang = true; + else + dm->error.map.wl_e2g_hang = false; + + dm->cnt_dm[BTC_DCNT_E2G] = cnt; + break; + case BTC_DCNT_TDMA_NONSYNC: + if (cnt != 0) /* if tdma not sync between drv/fw */ + dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++; + else + dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] = 0; + + if (dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] >= BTC_CHK_HANG_MAX) + dm->error.map.tdma_no_sync = true; + else + dm->error.map.tdma_no_sync = false; + break; + case BTC_DCNT_SLOT_NONSYNC: + if (cnt != 0) /* if slot not sync between drv/fw */ + dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC]++; + else + dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0; + + if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX) + dm->error.map.slot_no_sync = true; + else + dm->error.map.slot_no_sync = false; + break; + case BTC_DCNT_BTTX_HANG: + cnt = bt->bcnt[BTC_BCNT_LOPRI_TX]; + + if (cnt == 0 && bt->link_info.slave_role) + dm->cnt_dm[BTC_DCNT_BTTX_HANG]++; + else + dm->cnt_dm[BTC_DCNT_BTTX_HANG] = 0; + + if (dm->cnt_dm[BTC_DCNT_BTTX_HANG] >= BTC_CHK_HANG_MAX) + dm->error.map.bt_tx_hang = true; + else + dm->error.map.bt_tx_hang = false; + break; + case BTC_DCNT_BTCNT_HANG: + cnt = bt->bcnt[BTC_BCNT_HIPRI_RX] + + bt->bcnt[BTC_BCNT_HIPRI_TX] + + bt->bcnt[BTC_BCNT_LOPRI_RX] + + bt->bcnt[BTC_BCNT_LOPRI_TX]; + + if (cnt == 0) + dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++; + else + dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; + break; + case BTC_DCNT_WL_SLOT_DRIFT: + if (cnt >= BTC_CHK_WLSLOT_DRIFT_MAX) + dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT]++; + else + dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] = 0; + + if (dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) + dm->error.map.wl_slot_drift = true; + else + dm->error.map.wl_slot_drift = false; + break; + case BTC_DCNT_BT_SLOT_DRIFT: + if (cnt >= BTC_CHK_BTSLOT_DRIFT_MAX) + dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT]++; + else + dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] = 0; + + if (dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) + dm->error.map.bt_slot_drift = true; + else + dm->error.map.bt_slot_drift = false; + + break; + case BTC_DCNT_WL_STA_NTFY: + cnt = dm->cnt_notify[BTC_NCNT_WL_STA] - + dm->cnt_notify[BTC_NCNT_WL_STA_LAST]; + + dm->cnt_notify[BTC_NCNT_WL_STA_LAST] = + dm->cnt_notify[BTC_NCNT_WL_STA]; + + if (cnt == 0 && + (dm->tdd_bind.wl_link_mode != BTC_WLINK_NOLINK || + dm->fdd_bind.wl_link_mode != BTC_WLINK_NOLINK)) + dm->cnt_dm[BTC_DCNT_WL_STA_NTFY]++; + else + dm->cnt_dm[BTC_DCNT_WL_STA_NTFY] = 0; + + if (dm->cnt_dm[BTC_DCNT_WL_STA_NTFY] >= BTC_CHK_HANG_MAX) + dm->error.map.wl_no_sta_ntfy = true; + else + dm->error.map.wl_no_sta_ntfy = false; + break; + case BTC_DCNT_W2B_SCBD_NOSYNC: + if (!(rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA)) + return; /* return if no-support W2B scbd readback */ + + if (wl->scbd_rb[BTC_BT_1ST] != wl->scbd[BTC_BT_1ST] || + wl->scbd_rb[BTC_BT_2ND] != wl->scbd[BTC_BT_2ND]) + dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC]++; + else + dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC] = 0; + + if (dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC] >= BTC_CHK_HANG_MAX) + dm->error.map.w2b_scbd_no_sync = true; + else + dm->error.map.w2b_scbd_no_sync = false; + break; + } +} + +static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; + union rtw89_btc_fbtc_btver *pver = &btc->fwinfo.rpt_fbtc_btver.finfo; + struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL; + struct rtw89_btc_fbtc_btafh_v7 *pafh_v7 = NULL; + struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; + struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL; + struct rtw89_btc_fbtc_btscan_v1 *pscan_v1; + struct rtw89_btc_fbtc_btscan_v2 *pscan_v2; + struct rtw89_btc_fbtc_btscan_v7 *pscan_v7; + bool scan_update = true; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): rpt_type:%d\n", + __func__, rpt_type); + + switch (rpt_type) { + case BTC_RPT_TYPE_BT_VER: + if (ver->fcxbtver == 8) { + pver->v8 = *(struct rtw89_btc_fbtc_btver_v8 *)pfinfo; + bt = pver->v8.bt_id ? &btc->cx.bt1 : &btc->cx.bt0; + bt->ver_info.fw = le32_to_cpu(pver->v8.fw_ver); + bt->ver_info.fw_coex = le32_get_bits(pver->v8.coex_ver, + GENMASK(7, 0)); + bt->feature = le32_to_cpu(pver->v8.feature); + } else if (ver->fcxbtver == 7) { + pver->v7 = *(struct rtw89_btc_fbtc_btver_v7 *)pfinfo; + bt->ver_info.fw = le32_to_cpu(pver->v7.fw_ver); + bt->ver_info.fw_coex = le32_get_bits(pver->v7.coex_ver, + GENMASK(7, 0)); + bt->feature = le32_to_cpu(pver->v7.feature); + } else { + pver->v1 = *(struct rtw89_btc_fbtc_btver_v1 *)pfinfo; + bt->ver_info.fw = le32_to_cpu(pver->v1.fw_ver); + bt->ver_info.fw_coex = le32_get_bits(pver->v1.coex_ver, + GENMASK(7, 0)); + bt->feature = le32_to_cpu(pver->v1.feature); + } + break; + case BTC_RPT_TYPE_BT_SCAN: + if (ver->fcxbtscan == 1) { + pscan_v1 = (struct rtw89_btc_fbtc_btscan_v1 *)pfinfo; + for (i = 0; i < BTC_SCAN_MAX1; i++) { + bt->scan_info_v1[i] = pscan_v1->scan[i]; + if (bt->scan_info_v1[i].win == 0 && + bt->scan_info_v1[i].intvl == 0) + scan_update = false; + } + } else if (ver->fcxbtscan == 2) { + pscan_v2 = (struct rtw89_btc_fbtc_btscan_v2 *)pfinfo; + for (i = 0; i < CXSCAN_MAX; i++) { + bt->scan_info_v2[i] = pscan_v2->para[i]; + if ((pscan_v2->type & BIT(i)) && + pscan_v2->para[i].win == 0 && + pscan_v2->para[i].intvl == 0) + scan_update = false; + } + } else if (ver->fcxbtscan == 7) { + pscan_v7 = (struct rtw89_btc_fbtc_btscan_v7 *)pfinfo; + for (i = 0; i < CXSCAN_MAX; i++) { + bt->scan_info_v2[i] = pscan_v7->para[i]; + if ((pscan_v7->type & BIT(i)) && + pscan_v7->para[i].win == 0 && + pscan_v7->para[i].intvl == 0) + scan_update = false; + } + } else if (ver->fcxbtscan == 8) { + struct rtw89_btc_fbtc_btscan_v8 *pscan_v8 = + (struct rtw89_btc_fbtc_btscan_v8 *)pfinfo; + struct rtw89_btc_bt_info *tbt = + pscan_v8->bt_id ? &btc->cx.bt1 : &btc->cx.bt0; + + for (i = 0; i < CXSCAN_MAX; i++) { + tbt->scan_info_v2[i] = pscan_v8->para[i]; + if ((pscan_v8->type & BIT(i)) && + pscan_v8->para[i].win == 0 && + pscan_v8->para[i].intvl == 0) + scan_update = false; + } + } + if (scan_update) + bt->scan_info_update = 1; + break; + case BTC_RPT_TYPE_BT_AFH: + if (ver->fcxbtafh == 2) { + pafh_v2 = (struct rtw89_btc_fbtc_btafh_v2 *)pfinfo; + if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LEGACY) { + memcpy(&bt_linfo->afh_map[0], pafh_v2->afh_l, 4); + memcpy(&bt_linfo->afh_map[4], pafh_v2->afh_m, 4); + memcpy(&bt_linfo->afh_map[8], pafh_v2->afh_h, 2); + } + if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LE) { + memcpy(&bt_linfo->afh_map_le[0], pafh_v2->afh_le_a, 4); + memcpy(&bt_linfo->afh_map_le[4], pafh_v2->afh_le_b, 1); + } + } else if (ver->fcxbtafh == 7) { + pafh_v7 = (struct rtw89_btc_fbtc_btafh_v7 *)pfinfo; + if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LEGACY) { + memcpy(&bt_linfo->afh_map[0], pafh_v7->afh_l, 4); + memcpy(&bt_linfo->afh_map[4], pafh_v7->afh_m, 4); + memcpy(&bt_linfo->afh_map[8], pafh_v7->afh_h, 2); + } + if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LE) { + memcpy(&bt_linfo->afh_map_le[0], pafh_v7->afh_le_a, 4); + memcpy(&bt_linfo->afh_map_le[4], pafh_v7->afh_le_b, 1); + } + } else if (ver->fcxbtafh == 8) { + struct rtw89_btc_fbtc_btafh_v8 *pafh_v8 = + (struct rtw89_btc_fbtc_btafh_v8 *)pfinfo; + struct rtw89_btc_bt_info *tbt = + pafh_v8->bt_id ? &btc->cx.bt1 : &btc->cx.bt0; + struct rtw89_btc_bt_link_info *tbt_linfo = &tbt->link_info; + + if (pafh_v8->map_type & RPT_BT_AFH_SEQ_LEGACY) { + memcpy(&tbt_linfo->afh_map[0], pafh_v8->afh_l, 4); + memcpy(&tbt_linfo->afh_map[4], pafh_v8->afh_m, 4); + memcpy(&tbt_linfo->afh_map[8], pafh_v8->afh_h, 2); + } + if (pafh_v8->map_type & RPT_BT_AFH_SEQ_LE) { + memcpy(&tbt_linfo->afh_map_le[0], pafh_v8->afh_le_a, 4); + memcpy(&tbt_linfo->afh_map_le[4], pafh_v8->afh_le_b, 1); + } + } else if (ver->fcxbtafh == 1) { + pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo; + memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4); + memcpy(&bt_linfo->afh_map[4], pafh_v1->afh_m, 4); + memcpy(&bt_linfo->afh_map[8], pafh_v1->afh_h, 2); + } + break; + case BTC_RPT_TYPE_BT_DEVICE: + pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; + a2dp->device_name = le32_to_cpu(pdev->dev_name); + a2dp->vendor_id = le16_to_cpu(pdev->vendor_id); + a2dp->flush_time = le32_to_cpu(pdev->flush_time); + break; + default: + break; + } +} + +static void rtw89_btc_fw_rpt_evnt_ver(struct rtw89_dev *rtwdev, u8 *index) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + + if (ver->fwevntrptl == 1) + return; + + if (*index <= __BTC_RPT_TYPE_V0_SAME) + return; + else if (*index <= __BTC_RPT_TYPE_V0_MAX) + (*index)++; + else + *index = BTC_RPT_TYPE_MAX; +} + +#define BTC_LEAK_AP_TH 10 +#define BTC_CYSTA_CHK_PERIOD 100 + +struct rtw89_btc_prpt { + u8 type; + __le16 len; + u8 content[]; +} __packed; + +static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_btf_fwinfo *pfwinfo, + u8 *prptbuf, u32 index) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_ver *fwsubver = &btc->fwinfo.fw_subver; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL; + union rtw89_btc_fbtc_cysta_info *pcysta = NULL; + struct rtw89_btc_prpt *btc_prpt = NULL; + void *rpt_content = NULL, *pfinfo = NULL; + u8 rpt_type = 0; + u16 wl_slot_set = 0, wl_slot_real = 0, val16; + u32 trace_step = 0, rpt_len = 0, diff_t = 0; + u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr; + u8 i, j, val = 0, val1, val2; + u32 *bt_cnt, start_idx; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): index:%d\n", + __func__, index); + + if (!prptbuf) { + pfwinfo->err[BTFRE_INVALID_INPUT]++; + return 0; + } + + btc_prpt = (struct rtw89_btc_prpt *)&prptbuf[index]; + rpt_type = btc_prpt->type; + rpt_len = le16_to_cpu(btc_prpt->len); + rpt_content = btc_prpt->content; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): rpt_type:%d\n", + __func__, rpt_type); + + rtw89_btc_fw_rpt_evnt_ver(rtwdev, &rpt_type); + + switch (rpt_type) { + case BTC_RPT_TYPE_CTRL: + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + prpt = &pfwinfo->rpt_ctrl.finfo; + if (ver->fcxbtcrpt == 1) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v1.fver; + } else if (ver->fcxbtcrpt == 4) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v4.fver; + } else if (ver->fcxbtcrpt == 5) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v5.fver; + } else if (ver->fcxbtcrpt == 105) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v105; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v105.fver; + pcinfo->req_fver = 5; + break; + } else if (ver->fcxbtcrpt == 8) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v8; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v8.fver; + } else if (ver->fcxbtcrpt == 7) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v7.fver; + } else if (ver->fcxbtcrpt == 9) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v9; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v9); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v9.fver; + } else if (ver->fcxbtcrpt == 11) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v11; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v11); + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v11.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxbtcrpt; + break; + case BTC_RPT_TYPE_TDMA: + pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; + if (ver->fcxtdma == 1) { + pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); + fwsubver->fcxtdma = 0; + } else if (ver->fcxtdma == 3 || ver->fcxtdma == 4 || + ver->fcxtdma == 7 || ver->fcxtdma == 8) { + pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); + fwsubver->fcxtdma = pfwinfo->rpt_fbtc_tdma.finfo.v3.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxtdma; + break; + case BTC_RPT_TYPE_SLOT: + pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; + if (ver->fcxslots == 1) { + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v1); + fwsubver->fcxslots = pfwinfo->rpt_fbtc_slots.finfo.v1.fver; + } else if (ver->fcxslots == 2) { + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v2); + fwsubver->fcxslots = pfwinfo->rpt_fbtc_slots.finfo.v2.fver; + } else if (ver->fcxslots == 7) { + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v7); + fwsubver->fcxslots = pfwinfo->rpt_fbtc_slots.finfo.v7.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxslots; + break; + case BTC_RPT_TYPE_CYSTA: + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + if (ver->fcxcysta == 2) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2; + pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v2.fver; + } else if (ver->fcxcysta == 3) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3; + pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v3.fver; + } else if (ver->fcxcysta == 4) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4; + pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v4.fver; + } else if (ver->fcxcysta == 5) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5; + pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v5.fver; + } else if (ver->fcxcysta == 105) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v105; + pcysta->v105 = pfwinfo->rpt_fbtc_cysta.finfo.v105; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v105); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v105.fver; + } else if (ver->fcxcysta == 7) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v7; + pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v7); + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v7.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxcysta; + break; + case BTC_RPT_TYPE_STEP: + pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; + if (ver->fcxctrl != 7) + trace_step = btc->ctrl.trace_step; + + if (ver->fcxstep == 2) { + pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v2.step[0]) * + trace_step + + offsetof(struct rtw89_btc_fbtc_steps_v2, step); + fwsubver->fcxstep = pfwinfo->rpt_fbtc_step.finfo.v2.fver; + } else if (ver->fcxstep == 3) { + pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v3; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v3.step[0]) * + trace_step + + offsetof(struct rtw89_btc_fbtc_steps_v3, step); + fwsubver->fcxstep = pfwinfo->rpt_fbtc_step.finfo.v3.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxstep; + break; + case BTC_RPT_TYPE_NULLSTA: + pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; + if (ver->fcxnullsta == 1) { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v1.fver; + } else if (ver->fcxnullsta == 2) { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2); + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v2.fver; + } else if (ver->fcxnullsta == 7) { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v7); + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v7.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxnullsta; + break; + case BTC_RPT_TYPE_MREG: + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + if (ver->fcxmreg == 1) { + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v1); + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v1.fver; + } else if (ver->fcxmreg == 2) { + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2); + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v2.fver; + } else if (ver->fcxmreg == 7) { + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v7); + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v7.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxmreg; + break; + case BTC_RPT_TYPE_GPIO_DBG: + pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; + if (ver->fcxgpiodbg == 7) { + pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7); + fwsubver->fcxgpiodbg = pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7.fver; + } else { + pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1); + fwsubver->fcxgpiodbg = pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1.fver; + } + pcinfo->req_fver = ver->fcxgpiodbg; + break; + case BTC_RPT_TYPE_BT_VER: + pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; + if (ver->fcxbtver == 1) { + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v1); + fwsubver->fcxbtver = pfwinfo->rpt_fbtc_btver.finfo.v1.fver; + } else if (ver->fcxbtver == 7) { + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v7); + fwsubver->fcxbtver = pfwinfo->rpt_fbtc_btver.finfo.v7.fver; + } else if (ver->fcxbtver == 8) { + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v8; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v8); + fwsubver->fcxbtver = pfwinfo->rpt_fbtc_btver.finfo.v8.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxbtver; + break; + case BTC_RPT_TYPE_BT_SCAN: + pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; + if (ver->fcxbtscan == 1) { + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v1); + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v1.fver; + } else if (ver->fcxbtscan == 2) { + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2); + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v2.fver; + } else if (ver->fcxbtscan == 7) { + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v7); + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v7.fver; + } else if (ver->fcxbtscan == 8) { + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v8; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v8); + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v8.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxbtscan; + break; + case BTC_RPT_TYPE_BT_AFH: + pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; + if (ver->fcxbtafh == 1) { + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1); + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v1.fver; + } else if (ver->fcxbtafh == 2) { + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2); + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v2.fver; + } else if (ver->fcxbtafh == 7) { + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v7); + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v7.fver; + } else if (ver->fcxbtafh == 8) { + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v8; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v8); + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v8.fver; + } else { + goto err; + } + pcinfo->req_fver = ver->fcxbtafh; + break; + case BTC_RPT_TYPE_BT_DEVICE: + pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); + fwsubver->fcxbtdevinfo = pfwinfo->rpt_fbtc_btdev.finfo.fver; + pcinfo->req_fver = ver->fcxbtdevinfo; + break; + default: + pfwinfo->err[BTFRE_UNDEF_TYPE]++; + return 0; + } + + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + + if (rpt_len != pcinfo->req_len) { + if (rpt_type < BTC_RPT_TYPE_MAX) + pfwinfo->len_mismch |= (0x1 << rpt_type); + else + pfwinfo->len_mismch |= BIT(31); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): %d rpt_len:%d!=req_len:%d\n", + __func__, rpt_type, rpt_len, pcinfo->req_len); + + pcinfo->valid = 0; + return 0; + } else if (!pfinfo || !rpt_content || !pcinfo->req_len) { + pfwinfo->err[BTFRE_EXCEPTION]++; + pcinfo->valid = 0; + return 0; + } + + memcpy(pfinfo, rpt_content, pcinfo->req_len); + pcinfo->valid = 1; + + switch (rpt_type) { + case BTC_RPT_TYPE_CTRL: + if (ver->fcxbtcrpt == 1) { + prpt->v1 = pfwinfo->rpt_ctrl.finfo.v1; + btc->fwinfo.rpt_en_map = prpt->v1.rpt_enable; + wl->ver_info.fw_coex = prpt->v1.wl_fw_coex_ver; + wl->ver_info.fw = prpt->v1.wl_fw_ver; + dm->wl_fw_cx_offload = !!prpt->v1.wl_fw_cx_offload; + + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, + pfwinfo->event[BTF_EVNT_RPT]); + + /* To avoid I/O if WL LPS or power-off */ + if (wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + rtwdev->chip->ops->btc_update_bt_cnt(rtwdev); + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + + bt->bcnt[BTC_BCNT_POLLUTED] = + rtw89_mac_get_plt_cnt(rtwdev, + RTW89_MAC_0); + } + } else if (ver->fcxbtcrpt == 4) { + prpt->v4 = pfwinfo->rpt_ctrl.finfo.v4; + btc->fwinfo.rpt_en_map = le32_to_cpu(prpt->v4.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v4.wl_fw_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver); + dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload); + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v4.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]); + bt->bcnt[BTC_BCNT_POLLUTED] = + le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, + pfwinfo->event[BTF_EVNT_RPT]); + + if (le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) + bt->rfk_info.map.timeout = 1; + else + bt->rfk_info.map.timeout = 0; + + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else if (ver->fcxbtcrpt == 5) { + prpt->v5 = pfwinfo->rpt_ctrl.finfo.v5; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v5.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v5.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver); + dm->wl_fw_cx_offload = 0; + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v5.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]); + bt->bcnt[BTC_BCNT_POLLUTED] = + le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, + pfwinfo->event[BTF_EVNT_RPT]); + + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else if (ver->fcxbtcrpt == 105) { + prpt->v105 = pfwinfo->rpt_ctrl.finfo.v105; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v105.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v105.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver); + dm->wl_fw_cx_offload = 0; + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v105.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]); + bt->bcnt[BTC_BCNT_POLLUTED] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, + pfwinfo->event[BTF_EVNT_RPT]); + + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else if (ver->fcxbtcrpt == 7) { + prpt->v7 = pfwinfo->rpt_ctrl.finfo.v7; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v7.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v7.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v7.rpt_info.fw_ver); + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v7.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_TX_V105]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_RX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_TX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_RX_V105]); + + val1 = le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]); + if (val1 > bt->bcnt[BTC_BCNT_POLUT_NOW]) + val1 -= bt->bcnt[BTC_BCNT_POLUT_NOW]; /* diff */ + + bt->bcnt[BTC_BCNT_POLUT_DIFF] = val1; + bt->bcnt[BTC_BCNT_POLUT_NOW] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + val1 = pfwinfo->event[BTF_EVNT_RPT]; + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1); + _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); + _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); + } else if (ver->fcxbtcrpt == 8) { + prpt->v8 = pfwinfo->rpt_ctrl.finfo.v8; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v8.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v8.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v8.rpt_info.fw_ver); + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v8.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_TX_V105]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_RX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_TX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_RX_V105]); + + val1 = le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]); + if (val1 > bt->bcnt[BTC_BCNT_POLUT_NOW]) + val1 -= bt->bcnt[BTC_BCNT_POLUT_NOW]; /* diff */ + + bt->bcnt[BTC_BCNT_POLUT_DIFF] = val1; + bt->bcnt[BTC_BCNT_POLUT_NOW] = + le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + val1 = pfwinfo->event[BTF_EVNT_RPT]; + if (((prpt->v8.rpt_len_max_h << 8) + + prpt->v8.rpt_len_max_l) != ver->info_buf) + dm->error.map.h2c_c2h_buffer_mismatch = true; + else + dm->error.map.h2c_c2h_buffer_mismatch = false; + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1); + _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); + _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); + } else if (ver->fcxbtcrpt == 9) { + prpt->v9 = pfwinfo->rpt_ctrl.finfo.v9; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v9.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v9.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v9.rpt_info.fw_ver); + + memcpy(wl->ver_info.build_time, + prpt->v9.build_time, + sizeof(wl->ver_info.build_time)); + memcpy(wl->ver_info.build_date, + prpt->v9.build_date, + sizeof(wl->ver_info.build_date)); + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v9.gnt_val[i], + sizeof(dm->gnt_val[i])); + + bt->bcnt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_HI_TX_V105]); + bt->bcnt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_HI_RX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_LO_TX_V105]); + bt->bcnt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_LO_RX_V105]); + + val1 = le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_POLLUTED_V105]); + if (val1 > bt->bcnt[BTC_BCNT_POLUT_NOW]) + val1 -= bt->bcnt[BTC_BCNT_POLUT_NOW]; /* diff */ + + bt->bcnt[BTC_BCNT_POLUT_DIFF] = val1; + bt->bcnt[BTC_BCNT_POLUT_NOW] = + le16_to_cpu(prpt->v9.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + dm->pta_owner = prpt->v9.pta_owner; + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1); + _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); + _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); + } else if (ver->fcxbtcrpt == 11) { + prpt->v11 = pfwinfo->rpt_ctrl.finfo.v11; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v11.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v11.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v11.rpt_info.fw_ver); + + memcpy(wl->ver_info.build_time, + prpt->v11.build_time, + sizeof(wl->ver_info.build_time)); + memcpy(wl->ver_info.build_date, + prpt->v11.build_date, + sizeof(wl->ver_info.build_date)); + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) + memcpy(&dm->gnt_val[i], &prpt->v11.gnt_val[i][0], + sizeof(dm->gnt_val[i])); + + for (i = BTC_BT_1ST; i <= BTC_BT_EXT; i++) { + if (i == BTC_BT_EXT) { + if (cx->bt_ext.func_type == BTC_BTF_NONE) + continue; + bt_cnt = cx->bt_ext.bcnt; + } else if (i == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + continue; + bt_cnt = cx->bt1.bcnt; + wl->scbd_rb[i] = le32_to_cpu(prpt->v11.scbd_w2b[i]); + cx->bt1.scbd_rb = le32_to_cpu(prpt->v11.scbd_b2w[i]); + } else { + bt_cnt = cx->bt0.bcnt; + wl->scbd_rb[i] = le32_to_cpu(prpt->v11.scbd_w2b[i]); + cx->bt0.scbd_rb = le32_to_cpu(prpt->v11.scbd_b2w[i]); + } + + start_idx = BTC_BCNT_HIPRI_TX; + for (j = BTC_BCNT_HI_TX_V105; j <= BTC_BCNT_LO_RX_V105 ; j++) + bt_cnt[start_idx++] = le16_to_cpu(prpt->v11.bt_cnt[i][j]); + + /* check if polut counter increase */ + val1 = le16_to_cpu(prpt->v11.bt_cnt[i][BTC_BCNT_POLLUTED_V105]); + if (val1 > bt_cnt[BTC_BCNT_POLUT_NOW]) /* cnt increase*/ + val2 = val1 - bt_cnt[BTC_BCNT_POLUT_NOW]; + else + val2 = val1; /* overflow */ + + bt_cnt[BTC_BCNT_POLUT_DIFF] = val2; + bt_cnt[BTC_BCNT_POLUT_NOW] = val1; + + if (i <= BTC_BT_2ND) + bt_cnt[BTC_BCNT_SCBDREAD]++; + } + dm->scbd_w2b_update = true; + dm->scbd_b2w_update = true; + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); + _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_WL_STA_NTFY, 0); + _chk_btc_err(rtwdev, BTC_DCNT_W2B_SCBD_NOSYNC, 0); + } else { + goto err; + } + break; + case BTC_RPT_TYPE_TDMA: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", __func__, + BTC_DCNT_TDMA_NONSYNC, + sizeof(dm->tdma_now)); + if (ver->fcxtdma == 1) + _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, + memcmp(&dm->tdma_now, + &pfwinfo->rpt_fbtc_tdma.finfo.v1, + sizeof(dm->tdma_now))); + else if (ver->fcxtdma == 3 || ver->fcxtdma == 4 || + ver->fcxtdma == 7 || ver->fcxtdma == 8) + _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, + memcmp(&dm->tdma_now, + &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma, + sizeof(dm->tdma_now))); + else + goto err; + break; + case BTC_RPT_TYPE_SLOT: + if (ver->fcxslots == 7) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", + __func__, BTC_DCNT_SLOT_NONSYNC, + sizeof(dm->slot_now.v7)); + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, + memcmp(dm->slot_now.v7, + pfwinfo->rpt_fbtc_slots.finfo.v7.slot, + sizeof(dm->slot_now.v7))); + } else if (ver->fcxslots == 2) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", + __func__, BTC_DCNT_SLOT_NONSYNC, + sizeof(dm->slot_now.v7)); + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, + memcmp(dm->slot_now.v7, + pfwinfo->rpt_fbtc_slots.finfo.v2.slot, + sizeof(dm->slot_now.v7))); + } else if (ver->fcxslots == 1) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", + __func__, BTC_DCNT_SLOT_NONSYNC, + sizeof(dm->slot_now.v1)); + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, + memcmp(dm->slot_now.v1, + pfwinfo->rpt_fbtc_slots.finfo.v1.slot, + sizeof(dm->slot_now.v1))); + } + break; + case BTC_RPT_TYPE_CYSTA: + if (ver->fcxcysta == 2) { + if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD) + break; + /* Check Leak-AP */ + if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) != 0 && + le32_to_cpu(pcysta->v2.leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { + if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) < + BTC_LEAK_AP_TH * le32_to_cpu(pcysta->v2.leakrx_cnt)) + dm->leak_ap = 1; + } + + /* Check diff time between WL slot and W1/E2G slot */ + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT) { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_E2G].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_E2G].dur); + } else { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); + } + + if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) { + diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set; + _chk_btc_err(rtwdev, + BTC_DCNT_WL_SLOT_DRIFT, diff_t); + } + + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v2.cycles)); + } else if (ver->fcxcysta == 3) { + if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD) + break; + + cnt_leak_slot = le32_to_cpu(pcysta->v3.slot_cnt[CXST_LK]); + cnt_rx_imr = le32_to_cpu(pcysta->v3.leak_slot.cnt_rximr); + + /* Check Leak-AP */ + if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && + dm->tdma_now.rxflctrl) { + if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) + dm->leak_ap = 1; + } + + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); + wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]); + if (wl_slot_real > wl_slot_set) { + diff_t = wl_slot_real - wl_slot_set; + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); + } + } + + /* Check diff time between real BT slot and EBT/E5G slot */ + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + btc->bt_req_len[RTW89_PHY_0] != 0) { + bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]); + if (btc->bt_req_len[RTW89_PHY_0] > bt_slot_real) { + diff_t = btc->bt_req_len[RTW89_PHY_0] - bt_slot_real; + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); + } + } + + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, + le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v3.cycles)); + } else if (ver->fcxcysta == 4) { + if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD) + break; + + cnt_leak_slot = le16_to_cpu(pcysta->v4.slot_cnt[CXST_LK]); + cnt_rx_imr = le32_to_cpu(pcysta->v4.leak_slot.cnt_rximr); + + /* Check Leak-AP */ + if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && + dm->tdma_now.rxflctrl) { + if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) + dm->leak_ap = 1; + } + + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); + wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]); + if (wl_slot_real > wl_slot_set) { + diff_t = wl_slot_real - wl_slot_set; + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); + } + } + + /* Check diff time between real BT slot and EBT/E5G slot */ + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + btc->bt_req_len[RTW89_PHY_0] != 0) { + bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]); + + if (btc->bt_req_len[RTW89_PHY_0] > bt_slot_real) { + diff_t = btc->bt_req_len[RTW89_PHY_0] - bt_slot_real; + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); + } + } + + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, + le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v4.cycles)); + } else if (ver->fcxcysta == 5) { + if (dm->fddt_train == BTC_FDDT_ENABLE) + break; + cnt_leak_slot = le16_to_cpu(pcysta->v5.slot_cnt[CXST_LK]); + cnt_rx_imr = le32_to_cpu(pcysta->v5.leak_slot.cnt_rximr); + + /* Check Leak-AP */ + if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && + dm->tdma_now.rxflctrl) { + if (le16_to_cpu(pcysta->v5.cycles) >= BTC_CYSTA_CHK_PERIOD && + cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) + dm->leak_ap = 1; + } + + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); + wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]); + + if (wl_slot_real > wl_slot_set) + diff_t = wl_slot_real - wl_slot_set; + else + diff_t = wl_slot_set - wl_slot_real; + } + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); + + /* Check diff time between real BT slot and EBT/E5G slot */ + bt_slot_set = btc->bt_req_len[RTW89_PHY_0]; + bt_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_BT]); + diff_t = 0; + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + bt_slot_set != 0) { + if (bt_slot_set > bt_slot_real) + diff_t = bt_slot_set - bt_slot_real; + else + diff_t = bt_slot_real - bt_slot_set; + } + + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); + _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, + le16_to_cpu(pcysta->v5.slot_cnt[CXST_E2G])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le16_to_cpu(pcysta->v5.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, + le16_to_cpu(pcysta->v5.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v5.cycles)); + } else if (ver->fcxcysta == 105) { + if (dm->fddt_train == BTC_FDDT_ENABLE) + break; + + cnt_leak_slot = le16_to_cpu(pcysta->v105.slot_cnt[CXST_LK]); + cnt_rx_imr = le32_to_cpu(pcysta->v105.leak_slot.cnt_rximr); + + /* Check Leak-AP */ + if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && + dm->tdma_now.rxflctrl) { + if (le16_to_cpu(pcysta->v5.cycles) >= BTC_CYSTA_CHK_PERIOD && + cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) + dm->leak_ap = 1; + } + + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + if (ver->fcxslots == 1) + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); + else if (ver->fcxslots == 7) + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); + wl_slot_real = le16_to_cpu(pcysta->v105.cycle_time.tavg[CXT_WL]); + + if (wl_slot_real > wl_slot_set) + diff_t = wl_slot_real - wl_slot_set; + else + diff_t = wl_slot_set - wl_slot_real; + } + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); + + /* Check diff time between real BT slot and EBT/E5G slot */ + bt_slot_set = btc->bt_req_len[RTW89_PHY_0]; + bt_slot_real = le16_to_cpu(pcysta->v105.cycle_time.tavg[CXT_BT]); + diff_t = 0; + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + bt_slot_set != 0) { + if (bt_slot_set > bt_slot_real) + diff_t = bt_slot_set - bt_slot_real; + else + diff_t = bt_slot_real - bt_slot_set; + } + + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); + _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, + le16_to_cpu(pcysta->v105.slot_cnt[CXST_E2G])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le16_to_cpu(pcysta->v105.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, + le16_to_cpu(pcysta->v105.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v105.cycles)); + } else if (ver->fcxcysta == 7) { + if (dm->fddt_train == BTC_FDDT_ENABLE) + break; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + + if (dm->tdma_now.type != CXTDMA_OFF) { + /* Check diff time between real WL slot and W1 slot */ + val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_WL]); + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, val16); + + /* Check Leak-AP */ + val1 = le32_to_cpu(pcysta->v7.leak_slot.cnt_rximr) * + BTC_LEAK_AP_TH; + val2 = le16_to_cpu(pcysta->v7.slot_cnt[CXST_LK]); + + val16 = le16_to_cpu(pcysta->v7.cycles); + if (dm->tdma_now.rxflctrl && + val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2) + dm->leak_ap = 1; + } else if (dm->tdma_now.ext_ctrl == CXECTL_EXT) { + val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_BT]); + /* Check diff between real BT slot and EBT/E5G slot */ + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, val16); + + /* Check bt slot length for P2P mode*/ + val1 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt_timeout) * + BTC_SLOT_REQ_TH; + val2 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt); + + val16 = le16_to_cpu(pcysta->v7.cycles); + if (val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2) + dm->slot_req_more = 1; + else if (bt->link_info.status.map.connect == 0) + dm->slot_req_more = 0; + } + + _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, + le16_to_cpu(pcysta->v7.slot_cnt[CXST_E2G])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, + le16_to_cpu(pcysta->v7.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, + le16_to_cpu(pcysta->v7.slot_cnt[CXST_B1])); + + /* "BT_SLOT_FLOOD" error-check MUST before "CYCLE_HANG" */ + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_FLOOD, + le16_to_cpu(pcysta->v7.cycles)); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, + le16_to_cpu(pcysta->v7.cycles)); + } else { + goto err; + } + break; + case BTC_RPT_TYPE_MREG: + if (ver->fcxmreg == 7) + break; + _get_reg_status(rtwdev, BTC_CSTATUS_BB_GNT_MUX_MON, &val); + if (dm->wl_btg_rx == BTC_BTGCTRL_BB_GNT_FWCTRL) + dm->wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_FWCTRL; + else + dm->wl_btg_rx_rb = val; + + _get_reg_status(rtwdev, BTC_CSTATUS_BB_PRE_AGC_MON, &val); + if (dm->wl_pre_agc == BTC_PREAGC_BB_FWCTRL) + dm->wl_pre_agc_rb = BTC_PREAGC_BB_FWCTRL; + else + dm->wl_pre_agc_rb = val; + break; + case BTC_RPT_TYPE_BT_VER: + case BTC_RPT_TYPE_BT_SCAN: + case BTC_RPT_TYPE_BT_AFH: + case BTC_RPT_TYPE_BT_DEVICE: + _update_bt_report(rtwdev, rpt_type, pfinfo); + break; + } + return (rpt_len + BTC_RPT_HDR_SIZE); + +err: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): Undefined version for type=%d\n", __func__, rpt_type); + return 0; +} + +static void _parse_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_btf_fwinfo *pfwinfo, + u8 *pbuf, u32 buf_len) +{ + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + struct rtw89_btc_prpt *btc_prpt = NULL; + u32 index = 0, rpt_len = 0; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): buf_len:%d\n", + __func__, buf_len); + + while (pbuf) { + btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; + if (index + 2 >= ver->info_buf) + break; + /* At least 3 bytes: type(1) & len(2) */ + rpt_len = le16_to_cpu(btc_prpt->len); + if ((index + rpt_len + BTC_RPT_HDR_SIZE) > buf_len) + break; + + rpt_len = _chk_btc_report(rtwdev, pfwinfo, pbuf, index); + if (!rpt_len) + break; + index += rpt_len; + } +} + +#define BTC_TLV_HDR_LEN 2 +#define BTC_TLV_HDR_LEN_V7 3 + +static void _append_tdma(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_btf_tlv *tlv; + struct rtw89_btc_btf_tlv_v7 *tlv_v7; + struct rtw89_btc_fbtc_tdma *v; + struct rtw89_btc_fbtc_tdma_v3 *v3; + u16 len = btc->policy_len; + + if (!btc->update_policy_force && + !memcmp(&dm->tdma, &dm->tdma_now, sizeof(dm->tdma))) { + rtw89_debug(rtwdev, + RTW89_DBG_BTC, "[BTC], %s(): tdma no change!\n", + __func__); + return; + } + + tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; + tlv->type = CXPOLICY_TDMA; + if (ver->fcxtdma == 1) { + v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; + tlv->len = sizeof(*v); + *v = dm->tdma; + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); + } else if (ver->fcxtdma == 7 || ver->fcxtdma == 4) { + tlv_v7 = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; + tlv_v7->len = sizeof(dm->tdma); + tlv_v7->ver = ver->fcxtdma; + tlv_v7->type = CXPOLICY_TDMA; + memcpy(tlv_v7->val, &dm->tdma, tlv_v7->len); + btc->policy_len += BTC_TLV_HDR_LEN_V7 + tlv_v7->len; + } else { + tlv->len = sizeof(*v3); + v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0]; + v3->fver = ver->fcxtdma; + v3->tdma = dm->tdma; + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v3); + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): type:%d, rxflctrl=%d, txflctrl=%d, bind=%d, leak_n=%d, ext_ctrl=%d\n", + __func__, dm->tdma.type, dm->tdma.rxflctrl, + dm->tdma.txflctrl, dm->tdma.bind, dm->tdma.leak_n, + dm->tdma.ext_ctrl); +} + +static void _append_slot_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_btf_tlv *tlv = NULL; + struct btc_fbtc_1slot *v = NULL; + u16 len = 0; + u8 i, cnt = 0; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): A:btc->policy_len = %d\n", + __func__, btc->policy_len); + + for (i = 0; i < CXST_MAX; i++) { + if (!btc->update_policy_force && + !memcmp(&dm->slot.v1[i], &dm->slot_now.v1[i], + sizeof(dm->slot.v1[i]))) + continue; + + len = btc->policy_len; + + tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; + v = (struct btc_fbtc_1slot *)&tlv->val[0]; + tlv->type = CXPOLICY_SLOT; + tlv->len = sizeof(*v); + + v->fver = btc->ver->fcxslots; + v->sid = i; + v->slot = dm->slot.v1[i]; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n", + __func__, i, dm->slot.v1[i].dur, dm->slot.v1[i].cxtbl, + dm->slot.v1[i].cxtype); + cnt++; + + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); + } + + if (cnt > 0) + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): slot update (cnt=%d)!!\n", + __func__, cnt); +} + +static void _append_slot_v7(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_btf_tlv_v7 *tlv = NULL; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + u8 i, cnt = 0; + u16 len; + + for (i = 0; i < CXST_MAX; i++) { + if (!btc->update_policy_force && + !memcmp(&dm->slot.v7[i], &dm->slot_now.v7[i], + sizeof(dm->slot.v7[i]))) + continue; + + len = btc->policy_len; + + if (!tlv) { + if ((len + BTC_TLV_HDR_LEN_V7) > RTW89_BTC_POLICY_MAXLEN) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): buff overflow!\n", __func__); + break; + } + + tlv = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; + tlv->type = CXPOLICY_SLOT; + tlv->ver = btc->ver->fcxslots; + tlv->len = sizeof(dm->slot.v7[0]) + BTC_TLV_SLOT_ID_LEN_V7; + len += BTC_TLV_HDR_LEN_V7; + } + + if ((len + (u16)tlv->len) > RTW89_BTC_POLICY_MAXLEN) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): buff overflow!\n", __func__); + break; + } + + btc->policy[len] = i; /* slot-id */ + memcpy(&btc->policy[len + 1], &dm->slot.v7[i], + sizeof(dm->slot.v7[0])); + len += tlv->len; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s: policy_len=%d, slot-%d: dur=%d, type=%d, table=0x%08x\n", + __func__, btc->policy_len, i, dm->slot.v7[i].dur, + dm->slot.v7[i].cxtype, dm->slot.v7[i].cxtbl); + cnt++; + btc->policy_len = len; /* update total length */ + } + + if (cnt > 0) + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s: slot update (cnt=%d, len=%d)!!\n", + __func__, cnt, btc->policy_len); +} + +static void _append_slot(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) + _append_slot_v7(rtwdev); + else + _append_slot_v1(rtwdev); +} + +static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + u32 bit_map = 0; + + switch (rpt_map) { + case RPT_EN_TDMA: + bit_map = BIT(0); + break; + case RPT_EN_CYCLE: + bit_map = BIT(1); + break; + case RPT_EN_MREG: + bit_map = BIT(2); + break; + case RPT_EN_BT_VER_INFO: + bit_map = BIT(3); + break; + case RPT_EN_BT_SCAN_INFO: + bit_map = BIT(4); + break; + case RPT_EN_BT_DEVICE_INFO: + switch (ver->frptmap) { + case 0: + case 1: + case 2: + bit_map = BIT(6); + break; + case 3: + case 4: + case 5: + case 105: + bit_map = BIT(5); + break; + default: + break; + } + break; + case RPT_EN_BT_AFH_MAP: + switch (ver->frptmap) { + case 0: + case 1: + case 2: + bit_map = BIT(5); + break; + case 3: + case 4: + case 5: + case 105: + bit_map = BIT(6); + break; + default: + break; + } + break; + case RPT_EN_BT_AFH_MAP_LE: + switch (ver->frptmap) { + case 2: + bit_map = BIT(8); + break; + case 3: + case 4: + case 5: + case 105: + bit_map = BIT(7); + break; + default: + break; + } + break; + case RPT_EN_BT_TX_PWR_LVL: + switch (ver->frptmap) { + case 0: + case 1: + case 2: + case 3: + case 105: + break; + case 4: + case 5: + bit_map = BIT(8); + break; + default: + break; + } + break; + case RPT_EN_FW_STEP_INFO: + switch (ver->frptmap) { + case 1: + case 2: + bit_map = BIT(7); + break; + case 3: + case 105: + bit_map = BIT(8); + break; + case 4: + case 5: + bit_map = BIT(9); + break; + default: + break; + } + break; + case RPT_EN_TEST: + if (ver->frptmap == 5) + bit_map = BIT(10); + else if (ver->frptmap == 105) + bit_map = BIT(9); + else + bit_map = BIT(31); + break; + case RPT_EN_WL_ALL: + switch (ver->frptmap) { + case 0: + case 1: + case 2: + bit_map = GENMASK(2, 0); + break; + case 3: + case 105: + bit_map = GENMASK(2, 0) | BIT(8); + break; + case 4: + case 5: + bit_map = GENMASK(2, 0) | BIT(9); + break; + default: + break; + } + break; + case RPT_EN_BT_ALL: + switch (ver->frptmap) { + case 0: + case 1: + bit_map = GENMASK(6, 3); + break; + case 2: + bit_map = GENMASK(6, 3) | BIT(8); + break; + case 3: + case 105: + bit_map = GENMASK(7, 3); + break; + case 4: + case 5: + bit_map = GENMASK(8, 3); + break; + default: + break; + } + break; + case RPT_EN_ALL: + switch (ver->frptmap) { + case 0: + bit_map = GENMASK(6, 0); + break; + case 1: + bit_map = GENMASK(7, 0); + break; + case 2: + case 3: + bit_map = GENMASK(8, 0); + break; + case 4: + case 5: + case 105: + bit_map = GENMASK(9, 0); + break; + default: + break; + } + break; + case RPT_EN_MONITER: + switch (ver->frptmap) { + case 0: + case 1: + bit_map = GENMASK(6, 2); + break; + case 2: + bit_map = GENMASK(6, 2) | BIT(8); + break; + case 3: + case 105: + bit_map = GENMASK(8, 2); + break; + case 4: + case 5: + bit_map = GENMASK(9, 2); + break; + default: + break; + } + break; + } + + return bit_map; +} + +static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_btf_tlv_v7 *tlv_v7 = NULL; + struct rtw89_btc_btf_set_slot_table *tbl; + struct rtw89_btc_dm *dm = &btc->dm; + u16 n, len; + + if (ver->fcxslots == 2 || ver->fcxslots == 7) { + len = sizeof(*tlv_v7) + sizeof(dm->slot.v7); + tlv_v7 = kmalloc(len, GFP_KERNEL); + if (!tlv_v7) + return; + + tlv_v7->type = SET_SLOT_TABLE; + tlv_v7->ver = ver->fcxslots; + tlv_v7->len = ARRAY_SIZE(dm->slot.v7); + memcpy(tlv_v7->val, dm->slot.v7, sizeof(dm->slot.v7)); + + _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, (u8 *)tlv_v7, len); + + kfree(tlv_v7); + } else { + n = struct_size(tbl, tbls, CXST_MAX); + tbl = kmalloc(n, GFP_KERNEL); + if (!tbl) + return; + + tbl->fver = BTF_SET_SLOT_TABLE_VER; + tbl->tbl_num = CXST_MAX; + memcpy(tbl->tbls, dm->slot.v1, flex_array_size(tbl, tbls, CXST_MAX)); + + _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n); + + kfree(tbl); + } +} + +static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, + bool force_exec, u32 rpt_map) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; + union rtw89_fbtc_rtp_ctrl r; + int ret; + u32 i; + + if (!force_exec && rpt_map == fwinfo->rpt_en_map) + return; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rpt_map=%x\n", + __func__, fwinfo->rpt_en_map); + + if (btc->ver->fcxbtcrpt == 7 || + btc->ver->fcxbtcrpt == 8 || + btc->ver->fcxbtcrpt == 9 || + btc->ver->fcxbtcrpt == 11) { + r.v8.type = SET_REPORT_EN; + r.v8.fver = btc->ver->fcxbtcrpt; + r.v8.len = sizeof(r.v8.map); + r.v8.map = cpu_to_le32(rpt_map); + ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v8, + sizeof(r.v8)); + } else { + if (btc->ver->fcxbtcrpt == 105) + r.v1.fver = 5; + else + r.v1.fver = btc->ver->fcxbtcrpt; + + for (i = 0; i < RPT_EN_MONITER; i++) { + r.v1.enable = cpu_to_le32(i); + if (rpt_map & BIT(i)) + r.v1.para = cpu_to_le32(1); + else + r.v1.para = 0; + + ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, + &r.v1, sizeof(r.v1)); + } + } + + if (!ret) + fwinfo->rpt_en_map = rpt_map; +} + +static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + struct rtw89_btc_btf_set_mon_reg_v1 *v1 = NULL; + struct rtw89_btc_btf_set_mon_reg_v7 *v7 = NULL; + u8 i, n, ulen, cxmreg_max; + u16 sz = 0; + + n = chip->mon_reg_num; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): mon_reg_num=%d\n", __func__, n); + + if (ver->fcxmreg == 1) + cxmreg_max = CXMREG_MAX; + else + cxmreg_max = CXMREG_MAX_V2; + + if (n > cxmreg_max) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): mon reg count %d > %d\n", + __func__, n, cxmreg_max); + return; + } + + ulen = sizeof(struct rtw89_btc_fbtc_mreg); + + if (ver->fcxmreg == 7) { + sz = struct_size(v7, regs, n); + v7 = kmalloc(sz, GFP_KERNEL); + if (!v7) + return; + v7->type = RPT_EN_MREG; + v7->fver = ver->fcxmreg; + v7->len = n; + for (i = 0; i < n; i++) { + v7->regs[i].type = chip->mon_reg[i].type; + v7->regs[i].bytes = chip->mon_reg[i].bytes; + v7->regs[i].offset = chip->mon_reg[i].offset; + } + + _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v7, sz); + kfree(v7); + } else { + sz = struct_size(v1, regs, n); + v1 = kmalloc(sz, GFP_KERNEL); + if (!v1) + return; + v1->fver = ver->fcxmreg; + v1->reg_num = n; + memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n)); + + _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v1, sz); + kfree(v1); + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): sz=%d ulen=%d n=%d\n", + __func__, sz, ulen, n); +} + +static void _update_dm_step(struct rtw89_dev *rtwdev, + enum btc_reason_and_action reason_or_action) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + + /* use ring-structure to store dm step */ + dm->dm_step.step[dm->dm_step.step_pos] = reason_or_action; + dm->dm_step.step_pos++; + + if (dm->dm_step.step_pos >= ARRAY_SIZE(dm->dm_step.step)) { + dm->dm_step.step_pos = 0; + dm->dm_step.step_ov = true; + } +} + +static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type, + enum btc_reason_and_action action) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + int ret; + + dm->run_action = action; + + _update_dm_step(rtwdev, action | BTC_ACT_EXT_BIT); + _update_dm_step(rtwdev, policy_type | BTC_POLICY_EXT_BIT); + + btc->policy_len = 0; + btc->policy_type = policy_type; + + _append_tdma(rtwdev); + _append_slot(rtwdev); + + if (btc->policy_len == 0 || btc->policy_len > RTW89_BTC_POLICY_MAXLEN) + return; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): action = %d -> policy type/len: 0x%04x/%d\n", + __func__, action, policy_type, btc->policy_len); + + if (dm->tdma.rxflctrl == CXFLC_NULLP || + dm->tdma.rxflctrl == CXFLC_QOSNULL) + btc->btc_ctrl_lps = 1; + else + btc->btc_ctrl_lps = dm->lps_ctrl_scbd; + + if (btc->btc_ctrl_lps == 1) + rtw89_set_coex_ctrl_lps(rtwdev, btc->btc_ctrl_lps); + + ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_CX_POLICY, + btc->policy, btc->policy_len); + if (!ret) { + memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now)); + if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) + memcpy(&dm->slot_now.v7, &dm->slot.v7, sizeof(dm->slot_now.v7)); + else + memcpy(&dm->slot_now.v1, &dm->slot.v1, sizeof(dm->slot_now.v1)); + } + + if (btc->update_policy_force) + btc->update_policy_force = false; + + if (btc->btc_ctrl_lps == 0) + rtw89_set_coex_ctrl_lps(rtwdev, btc->btc_ctrl_lps); +} + +static u8 _get_gpiosig_for_ver(struct rtw89_dev *rtwdev, u8 sig_v8) +{ + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + + /* v8: gpio_ver >= 8, directly use v8 signal ID */ + if (ver->fcxgpiodbg >= 8) + return sig_v8; + + /* v7: gpio_ver < 8, convert v8 signal ID to v7 signal ID */ + if (sig_v8 <= BTC_DBG_GNT_WL) { + return sig_v8; + } else if (sig_v8 <= BTC_DBG_GNT_WL1) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): sig %d not supported in v7\n", + __func__, sig_v8); + return BTC_DBG_NUM; + } else if (sig_v8 >= BTC_DBG_NUM) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): sig %d not available\n", + __func__, sig_v8); + return BTC_DBG_NUM; + } else { + return sig_v8 - 2; + } +} + +static u32 _convert_gpio_enmap_to_ver(struct rtw89_dev *rtwdev, u32 en_map_v8) +{ + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + u32 en_map_v7 = 0; + u32 bit; + + /* v8: gpio_ver >= 8, directly use v8 en_map */ + if (ver->fcxgpiodbg >= 8) + return en_map_v8; + + /* v7: gpio_ver < 8, convert v8 en_map bitmap to v7 en_map bitmap */ + /* bit 0-1: GNT_BT, GNT_WL - same position in both versions */ + en_map_v7 |= en_map_v8 & GENMASK(1, 0); + + /* bit 2-3: GNT_BT1, GNT_WL1 - not supported in v7, skip these bits */ + + /* bit 4-31: shift right by 2 positions (become bit 2-29 in v7) */ + for (bit = BTC_DBG_BCN_EARLY; bit < BTC_DBG_NUM; bit++) { + if (en_map_v8 & BIT(bit)) + en_map_v7 |= BIT(bit - 2); + } + + return en_map_v7; +} + +static u32 _convert_gpio_enmap_from_ver(struct rtw89_dev *rtwdev, u32 en_map) +{ + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + u32 en_map_v8 = 0; + u32 bit; + + if (ver->fcxgpiodbg >= 8) + return en_map; + + /* bit 0-1: GNT_BT, GNT_WL - same position in both versions */ + en_map_v8 |= en_map & GENMASK(1, 0); + + /* bit 2-29: shift left by 2 positions (become bit 4-31 in v8) */ + for (bit = BTC_DBG_GNT_BT1; bit < BTC_DBG_NUM - 2; bit++) { + if (en_map & BIT(bit)) + en_map_v8 |= BIT(bit + 2); + } + + return en_map_v8; +} + +static void _fw_set_gpio(struct rtw89_dev *rtwdev, u8 type, u32 val) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_fbtc_h2c_set_gpio *gpio = &btc->gpio; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_fbtc_h2c_set_gpio_2b l2_h2c; + struct rtw89_fbtc_h2c_set_gpio_4b l4_h2c; + u8 gpio_ver = ver->fcxgpiodbg; + u8 buf[sizeof(l4_h2c)]; + u8 len; + + if (gpio_ver < 8 && type > CXDGPIO_MUX_MAP) + return; + + if (type >= CXDGPIO_MAX) + return; + + switch (type) { + case CXDGPIO_EN_MAP: /* GPIO debug signal en-map 0~31 */ + val = _convert_gpio_enmap_to_ver(rtwdev, val); + gpio->en_map.data.type = CXDGPIO_EN_MAP; + gpio->en_map.data.fver = gpio_ver; + gpio->en_map.data.dlen = CXDGPIO_SET_L4; + gpio->en_map.data.en_map = val; + l4_h2c = gpio->en_map.fmt; + put_unaligned_le32(val, (u32 *)l4_h2c.data); + memcpy(buf, &l4_h2c, sizeof(l4_h2c)); + len = sizeof(l4_h2c); + break; + case CXDGPIO_MUX_MAP: /* GPIO dbg: Signal to GPIO Mux */ + gpio->mux.data.type = CXDGPIO_MUX_MAP; + gpio->mux.data.fver = gpio_ver; + gpio->mux.data.dlen = CXDGPIO_SET_L2; + gpio->mux.data.sig = _get_gpiosig_for_ver(rtwdev, + FIELD_GET(GENMASK(7, 0), val)); + if (gpio->mux.data.sig == 0xff) + return; + gpio->mux.data.gpio = FIELD_GET(GENMASK(15, 8), val); + l2_h2c = gpio->mux.fmt; + memcpy(buf, &l2_h2c, sizeof(l2_h2c)); + len = sizeof(l2_h2c); + break; + case CXDGPIO_EXT_HPTA: /* GPIO config for Ext HW-PTA */ + gpio->ext_pta.data.type = CXDGPIO_EXT_HPTA; + gpio->ext_pta.data.fver = gpio_ver; + gpio->ext_pta.data.dlen = CXDGPIO_SET_L2; + gpio->ext_pta.data.map_low = FIELD_GET(GENMASK(7, 0), val); + gpio->ext_pta.data.map_high = FIELD_GET(GENMASK(15, 8), val); + l2_h2c = gpio->ext_pta.fmt; + memcpy(buf, &l2_h2c, sizeof(l2_h2c)); + len = sizeof(l2_h2c); + break; + case CXDGPIO_EXT_HMBX: /* GPIO config for Ext HW-mailbox */ + gpio->ext_mb.data.type = CXDGPIO_EXT_HMBX; + gpio->ext_mb.data.fver = gpio_ver; + gpio->ext_mb.data.dlen = CXDGPIO_SET_L2; + gpio->ext_mb.data.map_low = FIELD_GET(GENMASK(7, 0), val); + gpio->ext_mb.data.map_high = FIELD_GET(GENMASK(15, 8), val); + l2_h2c = gpio->ext_mb.fmt; + memcpy(buf, &l2_h2c, sizeof(l2_h2c)); + len = sizeof(l2_h2c); + break; + case CXDGPIO_EXT_SWOUT: /* GPIO config for Ext SW output (wlan_act) */ + gpio->ext_swout.data.type = CXDGPIO_EXT_SWOUT; + gpio->ext_swout.data.fver = gpio_ver; + gpio->ext_swout.data.dlen = CXDGPIO_SET_L2; + gpio->ext_swout.data.map_low = FIELD_GET(GENMASK(7, 0), val); + gpio->ext_swout.data.map_high = FIELD_GET(GENMASK(15, 8), val); + l2_h2c = gpio->ext_swout.fmt; + memcpy(buf, &l2_h2c, sizeof(l2_h2c)); + len = sizeof(l2_h2c); + break; + case CXDGPIO_EXT_SWIN: /* GPIO config for Ext SW input control */ + gpio->ext_swin.data.type = CXDGPIO_EXT_SWIN; + gpio->ext_swin.data.fver = gpio_ver; + gpio->ext_swin.data.dlen = CXDGPIO_SET_L4; + gpio->ext_swin.data.in_map_low = FIELD_GET(GENMASK(7, 0), val); + gpio->ext_swin.data.in_map_high = FIELD_GET(GENMASK(15, 8), val); + gpio->ext_swin.data.int_map_low = FIELD_GET(GENMASK(23, 16), val); + gpio->ext_swin.data.int_map_high = FIELD_GET(GENMASK(31, 24), val); + l4_h2c = gpio->ext_swin.fmt; + put_unaligned_le32(val, (u32 *)l4_h2c.data); + memcpy(buf, &l4_h2c, sizeof(l4_h2c)); + len = sizeof(l4_h2c); + break; + default: + return; + } + + _send_fw_cmd(rtwdev, BTFC_SET, SET_GPIO_DBG, buf, len); +} + +static void _set_ext_interface(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + u8 bt1_sw_type = BTC_SWITCH_INTERNAL; + u32 val; + + if (btc->ver->fcxgpiodbg < 7) + return; + + /* if BT1+WL-S0, route DBG_GNT_BT1 to control SPDT */ + if ((rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) && + btc->ver->fcxinit >= 10) { + if (btc->ver->fcxinit >= 10) + bt1_sw_type = btc->mdinfo.bt1_sw_type; + else + return; + + if (bt1_sw_type > BTC_SWITCH_INTERNAL) { + _fw_set_gpio(rtwdev, CXDGPIO_EN_MAP, + BIT(BTC_DBG_GNT_BT1)); + + val = (bt1_sw_type << 8) + BTC_DBG_GNT_BT1; + _fw_set_gpio(rtwdev, CXDGPIO_MUX_MAP, val); + } + } + + /* set GPIO as Ext-PTA interface wire */ + if (cx->bt_ext.hw_coex & BTC_EXTSOC_INTF_PTA) + _fw_set_gpio(rtwdev, CXDGPIO_EXT_HPTA, cx->bt_ext.hpta_cfg); + + /* set GPIO as Ext-mailbox interface wire */ + if (cx->bt_ext.hw_coex & BTC_EXTSOC_INTF_MBX) + _fw_set_gpio(rtwdev, CXDGPIO_EXT_HMBX, cx->bt_ext.hmbx_cfg); + + /* set GPIO as Ext-SWIO interface wire */ + if (cx->bt_ext.hw_coex & BTC_EXTSOC_INTF_SWIO) { + _fw_set_gpio(rtwdev, CXDGPIO_EXT_SWOUT, cx->bt_ext.swout_cfg); + _fw_set_gpio(rtwdev, CXDGPIO_EXT_SWIN, cx->bt_ext.swin_cfg); + } +} + +static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + + switch (index) { + case CXDRVINFO_INIT: + if (ver->fcxinit == 7 || ver->fcxinit == 107) + rtw89_fw_h2c_cxdrv_init_v7(rtwdev, index); + else if (ver->fcxinit == 10) + rtw89_fw_h2c_cxdrv_init_v10(rtwdev, index); + else if (ver->fcxinit == 11) + rtw89_fw_h2c_cxdrv_init_v11(rtwdev, index); + else + rtw89_fw_h2c_cxdrv_init(rtwdev, index); + break; + case CXDRVINFO_ROLE: + if (ver->fwlrole == 0) + rtw89_fw_h2c_cxdrv_role(rtwdev, index); + else if (ver->fwlrole == 1) + rtw89_fw_h2c_cxdrv_role_v1(rtwdev, index); + else if (ver->fwlrole == 101) + rtw89_fw_h2c_cxdrv_role_v101(rtwdev, index); + else if (ver->fwlrole == 2) + rtw89_fw_h2c_cxdrv_role_v2(rtwdev, index); + else if (ver->fwlrole == 7) + rtw89_fw_h2c_cxdrv_role_v7(rtwdev, index); + else if (ver->fwlrole == 8) + rtw89_fw_h2c_cxdrv_role_v8(rtwdev, index); + else if (ver->fwlrole == 10) + rtw89_fw_h2c_cxdrv_role_v10(rtwdev, index); + break; + case CXDRVINFO_CTRL: + if (ver->drvinfo_ver != 0) + index = 2; + + if (ver->fcxctrl == 7) + rtw89_fw_h2c_cxdrv_ctrl_v7(rtwdev, index); + else if (ver->fcxctrl == 9) + rtw89_fw_h2c_cxdrv_ctrl_v9(rtwdev, index); + else + rtw89_fw_h2c_cxdrv_ctrl(rtwdev, index); + break; + case CXDRVINFO_TRX: + if (ver->drvinfo_ver > 1) + index = 3; + + if (ver->fcxtrx == 0) + return; + + if (ver->fcxtrx == 7) + rtw89_fw_h2c_cxdrv_trx_v7(rtwdev, index); + else if (ver->fcxtrx == 9) + rtw89_fw_h2c_cxdrv_trx_v9(rtwdev, index); + else if (ver->fcxtrx == 107) + rtw89_fw_h2c_cxdrv_trx_v107(rtwdev, index); + break; + case CXDRVINFO_RFK: + if (ver->drvinfo_ver != 0) + return; + + rtw89_fw_h2c_cxdrv_rfk(rtwdev, index); + break; + case CXDRVINFO_TXPWR: + if (ver->drvinfo_ver == 3 || ver->drvinfo_ver == 103) + index = 4; + + if (ver->fcxtrx == 7 || ver->fcxtrx == 107) + rtw89_fw_h2c_cxtxpwr_v7(rtwdev, index); + else if (ver->fcxtrx == 9) + rtw89_fw_h2c_cxtxpwr_v9(rtwdev, index); + break; + case CXDRVINFO_FDDT: + if (ver->drvinfo_ver == 3 || ver->drvinfo_ver == 103) + index = 5; + else + return; + + break; + case CXDRVINFO_MLO: + if (!ver->fcxmlo || ver->drvinfo_ver == 103) + return; + + if (ver->drvinfo_ver == 3) + index = 6; + else + return; + + if (ver->fcxmlo == 2) + rtw89_fw_h2c_cxdrv_mlo_v2(rtwdev, index); + + break; + case CXDRVINFO_OSI: + if (!ver->fcxosi || ver->drvinfo_ver == 103) + return; + + if (ver->drvinfo_ver == 3) + index = 7; + else + return; + + if (ver->fcxosi == 1) + rtw89_fw_h2c_cxdrv_osi_info(rtwdev, index); + else if (ver->fcxosi == 6) + rtw89_fw_h2c_cxdrv_osi_info_v6(rtwdev, index); + else + return; + break; + default: + break; + } +} + +static +void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + u8 i; + + _parse_btc_report(rtwdev, pfwinfo, data, len); + + if (!rtwdev->chip->scbd) + return; + + if (!btc->dm.scbd_b2w_update) + return; /* skip if init or no-update */ + + for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++) { + bt = (i == BTC_BT_1ST) ? &btc->cx.bt0 : &btc->cx.bt1; + + if (bt->scbd_c2h != bt->scbd_rb) { + /* if btx b2w scbd non-sync */ + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s() bt%d:c2h->0x%08x, rb->0x%08x\n", + __func__, i, bt->scbd_c2h, bt->scbd_rb); + bt->scbd_c2h = bt->scbd_rb; + _update_bt_scbd(rtwdev, i); + btc->dm.scbd_b2w_update = false; + } + } + + if (!btc->dm.scbd_b2w_update) + _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); + else + btc->dm.scbd_b2w_update = 0; +} + +static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, + u8 wl_state, u8 bt_state, u8 wlact_state) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_outsrc_set_info *o = &dm->ost_info; + struct rtw89_mac_ax_wl_act *wlact_set; + struct rtw89_mac_ax_coex_gnt mg; + u8 i; + + if (phy_map > BTC_PHY_ALL) + return; + + for (i = 0; i < RTW89_PHY_NUM; i++) { + if (!(phy_map & BIT(i))) + continue; + + switch (wl_state) { + case BTC_GNT_HW: + dm->gnt_set[i].gnt_wl_sw_en = 0; + dm->gnt_set[i].gnt_wl = 0; + break; + case BTC_GNT_SW_LO: + dm->gnt_set[i].gnt_wl_sw_en = 1; + dm->gnt_set[i].gnt_wl = 0; + break; + case BTC_GNT_SW_HI: + dm->gnt_set[i].gnt_wl_sw_en = 1; + dm->gnt_set[i].gnt_wl = 1; + break; + case BTC_GNT_SET_SKIP: + default: + break; + } + + switch (bt_state) { + case BTC_GNT_HW: + dm->gnt_set[i].gnt_bt0_sw_en = 0; + dm->gnt_set[i].gnt_bt0 = 0; + dm->gnt_set[i].gnt_bt1_sw_en = 0; + dm->gnt_set[i].gnt_bt1 = 0; + dm->gnt_set[i].gnt_zb_sw_en = 0; + dm->gnt_set[i].gnt_zb = 0; + break; + case BTC_GNT_SW_LO: + dm->gnt_set[i].gnt_bt0_sw_en = 1; + dm->gnt_set[i].gnt_bt0 = 0; + dm->gnt_set[i].gnt_bt1_sw_en = 1; + dm->gnt_set[i].gnt_bt1 = 0; + dm->gnt_set[i].gnt_zb_sw_en = 1; + dm->gnt_set[i].gnt_zb = 0; + break; + case BTC_GNT_SW_HI: + dm->gnt_set[i].gnt_bt0_sw_en = 1; + dm->gnt_set[i].gnt_bt0 = 1; + dm->gnt_set[i].gnt_bt1_sw_en = 1; + dm->gnt_set[i].gnt_bt1 = 1; + dm->gnt_set[i].gnt_zb_sw_en = 1; + dm->gnt_set[i].gnt_zb = 1; + break; + case BTC_GNT_SET_SKIP: + default: + break; + } + } + + for (i = 0; i < BTC_ALL_BT_EZL; i++) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX)) + break; + + switch (wlact_state) { + case BTC_WLACT_HW: + dm->wlact_set[i].wlan_act_en = 0; + dm->wlact_set[i].wlan_act = 0; + break; + case BTC_WLACT_SW_LO: + dm->wlact_set[i].wlan_act_en = 1; + dm->wlact_set[i].wlan_act = 0; + break; + case BTC_WLACT_SW_HI: + dm->wlact_set[i].wlan_act_en = 1; + dm->wlact_set[i].wlan_act = 1; + break; + default: + break; + } + + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_map=0x%x, gnt_wl:%d, gnt_bt:%d, wl_act:%d\n", + __func__, phy_map, wl_state, bt_state, wlact_state); + + if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) { + if (o->rf_band[BTC_RF_S0] == 1 && o->rf_band[BTC_RF_S1] == 0) + o->rf_gbt_source = BTC_RF_S1; + else + o->rf_gbt_source = BTC_RF_S0; + + memcpy(o->wlact_set, dm->wlact_set, sizeof(o->wlact_set)); + + if (btc->ver->fcxosi == 6) { + memcpy(o->gnt_set_be, dm->gnt_set, sizeof(o->gnt_set_be)); + return; + } else if (btc->ver->fcxosi == 1) { + for (i = 0; i < RTW89_PHY_NUM; i++) { /* gnt[MAC0/MAC1] */ + mg.band[i].gnt_bt_sw_en = dm->gnt_set[i].gnt_bt0_sw_en; + mg.band[i].gnt_bt = dm->gnt_set[i].gnt_bt0; + mg.band[i].gnt_wl_sw_en = dm->gnt_set[i].gnt_wl_sw_en; + mg.band[i].gnt_wl = dm->gnt_set[i].gnt_wl; + memcpy(o->gnt_set, mg.band, sizeof(o->gnt_set)); + } + return; + } + } + + for (i = 0; i < RTW89_PHY_NUM; i++) { /* gnt[MAC0/MAC1] */ + mg.band[i].gnt_bt_sw_en = dm->gnt_set[i].gnt_bt0_sw_en; + mg.band[i].gnt_bt = dm->gnt_set[i].gnt_bt0; + mg.band[i].gnt_wl_sw_en = dm->gnt_set[i].gnt_wl_sw_en; + mg.band[i].gnt_wl = dm->gnt_set[i].gnt_wl; + } + for (i = 0; i < BTC_ALL_BT; i++) { /* wlact[BT0/BT1] */ + wlact_set = &dm->wlact_set[i]; + mg.bt[i].wlan_act_en = wlact_set->wlan_act_en; + mg.bt[i].wlan_act = wlact_set->wlan_act; + } + + rtw89_chip_mac_cfg_gnt(rtwdev, &mg); +} + +#define BTC_TDMA_WLROLE_MAX 3 + +static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable) +{ + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): set bt %s wlan_act\n", __func__, + enable ? "ignore" : "do not ignore"); + + _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_IGNORE_WLAN_ACT, &enable, 1); +} + +#define WL_TX_POWER_NO_BTC_CTRL GENMASK(31, 0) +#define WL_TX_POWER_ALL_TIME GENMASK(15, 0) +#define WL_TX_POWER_WITH_BT GENMASK(31, 16) +#define WL_TX_POWER_INT_PART GENMASK(8, 2) +#define WL_TX_POWER_FRA_PART GENMASK(1, 0) +#define B_BTC_WL_TX_POWER_SIGN BIT(7) +#define B_TSSI_WL_TX_POWER_SIGN BIT(8) +#define SET_RF_PARA_AX_LEN 1 + +static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level, u8 phy_map) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + bool level_chg = false; + u32 pwr_val; + + if (phy_map & BIT(RTW89_PHY_0)) + level_chg = !(dm->rf_trx_para.wl_tx_power[RTW89_PHY_0] == level); + + if (phy_map & BIT(RTW89_PHY_1)) + level_chg |= !(dm->rf_trx_para.wl_tx_power[RTW89_PHY_1] == level); + + if (!level_chg && !btc->cli_h2c_cmd) + return; + + if (phy_map & BIT(RTW89_PHY_0)) + dm->rf_trx_para.wl_tx_power[RTW89_PHY_0] = level; + + if (phy_map & BIT(RTW89_PHY_1)) + dm->rf_trx_para.wl_tx_power[RTW89_PHY_1] = level; + + dm->wl_tx_pwr_phy_map = phy_map; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_map=0x%x, wl_tx_pwr-> phy0=%d, phy1=%d\n", + __func__, phy_map, + dm->rf_trx_para.wl_tx_power[RTW89_PHY_0], + dm->rf_trx_para.wl_tx_power[RTW89_PHY_1]); + + if ((ver->fcxtrx == 7 && chip->chip_id == RTL8922A) || + ver->fcxtrx == 107) { + _fw_set_drv_info(rtwdev, CXDRVINFO_TXPWR); + } else if (ver->fcxtrx == 9) { + _fw_set_drv_info(rtwdev, CXDRVINFO_TXPWR); + } else { + if (level == RTW89_BTC_WL_DEF_TX_PWR) { + pwr_val = WL_TX_POWER_NO_BTC_CTRL; + } else { /* only apply "force tx power" */ + pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level); + if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR) + pwr_val = RTW89_BTC_WL_DEF_TX_PWR; + + if (level & B_BTC_WL_TX_POWER_SIGN) + pwr_val |= B_TSSI_WL_TX_POWER_SIGN; + pwr_val |= WL_TX_POWER_WITH_BT; + } + chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val); + } +} + +static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level, u8 phy_map) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + bool level_chg = false; + + if (phy_map & BIT(RTW89_PHY_0)) + level_chg = !(dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0] == level); + + if (phy_map & BIT(RTW89_PHY_1)) + level_chg |= !(dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1] == level); + + if (!level_chg && !btc->cli_h2c_cmd) + return; + + if (phy_map & BIT(RTW89_PHY_0)) + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0] = level; + + if (phy_map & BIT(RTW89_PHY_1)) + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1] = level; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_map=0x%x, wl_rx_gain-> phy0=%d, phy1=%d\n", + __func__, phy_map, + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0], + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1]); + + chip->ops->btc_set_wl_rx_gain(rtwdev, level); +} + +static void _set_bt_tx_power(struct rtw89_dev *rtwdev, bool force_exec, u8 bid, + u8 rf_band, u8 level) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + u8 h2c_func = SET_BT_TX_PWR; + u8 i, id_start, id_stop; + u8 buf[2] = {}; + u8 len = sizeof(*buf); + + if (bt->bcnt[BTC_BCNT_INFOUPDATE] == 0 || !rf_band) + return; + + if (bt->rf_para.tx_pwr_freerun == level) + return; + + if (bid == BTC_ALL_BT) { + id_start = BTC_BT_1ST; + id_stop = BTC_BT_2ND; + } else { + id_start = bid; + id_stop = bid; + } + + for (i = id_start; i <= id_stop; i++) { + if (i == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + continue; + + bt = &btc->cx.bt1; + h2c_func |= BT_H2C_FUNC_BT2ND; + } + + buf[0] = (s8)(-level); + buf[1] = rf_band; /* bit-map: bit1->5GHz/6Ghz, bit0->2.4GHz */ + + if (!force_exec && !btc->cli_h2c_cmd) { + if (rf_band == RTW89_BAND_2G && + bt->tx_power_now == level) + continue; + else if (rf_band != RTW89_BAND_2G && + bt->tx_power_now_6g == level) + continue; + } + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + len = SET_RF_PARA_AX_LEN; + + if (!_send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, len)) { + btc->dm.rf_trx_para.bt_tx_power[i] = level; + if (rf_band == RTW89_BAND_2G) + bt->tx_power_now = level; + else + bt->tx_power_now_6g = level; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): bt%d_tx_power_level = %d\n", + __func__, i, level); + } + } +} + +#define BTC_BT_RX_NORMAL_LVL 7 +static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, bool force_exec, u8 bid, + u8 rf_band, u8 level) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt = &cx->bt0; + u8 h2c_func = SET_BT_LNA_CONSTRAIN; + u8 i, id_start, id_stop; + bool state = false; + u32 scbd_bit = 0; + u8 buf[2] = {}; + u8 len = sizeof(*buf); + + if (bt->bcnt[BTC_BCNT_INFOUPDATE] == 0 || !rf_band) + return; + + if (bt->rf_para.rx_gain_freerun == level || + level > BTC_BT_RX_NORMAL_LVL || !rtwdev->chip->scbd || + bid > BTC_ALL_BT) + return; + + if (bid == BTC_ALL_BT) { + id_start = BTC_BT_1ST; + id_stop = BTC_BT_2ND; + } else { + id_start = bid; + id_stop = bid; + } + + if (rf_band == RTW89_BAND_2G) + scbd_bit |= BTC_WSCB_RXGAIN; + else + scbd_bit |= BTC_WSCB_RXGAIN_56G; + + for (i = id_start; i <= id_stop; i++) { + if (i == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + continue; + + bt = &cx->bt1; + h2c_func |= BT_H2C_FUNC_BT2ND; + } + + /* return if same setup */ + if (!force_exec && !btc->cli_h2c_cmd) { + if (rf_band == RTW89_BAND_2G && + bt->lna_constrain == level) + continue; + else if (rf_band != RTW89_BAND_2G && + bt->lna_constrain_6g == level) + continue; + } + + buf[0] = level; + buf[1] = rf_band; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + len = SET_RF_PARA_AX_LEN; + + if (_send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, len)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): bt%d_rx_gain_level = %d\n", + __func__, i, level); + } + + btc->dm.rf_trx_para.bt_rx_gain[i] = level; + + if (buf[0] != BTC_BT_RX_NORMAL_LVL) + state = true; + + _write_scbd(rtwdev, bid, scbd_bit, state); + } +} + +static void _set_bt_corx_table(struct rtw89_dev *rtwdev, bool en) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt = &cx->bt0; + struct rtw89_btc_dm *dm = &btc->dm; + u8 is_24g, is_56g, i; + u32 scbd_bit; + + /* + * true: bt use Hi-LNA rx gain table (f/e/3/2) in -3x~-9xdBm for co-rx + * false: bt use original rx gain table (f/b/7/3/2) + */ + + if (btc->dm.fdd_bind.bt_sel == BIT(BTC_BT_EXT)) + return; + + for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++) { + scbd_bit = 0; + if (i == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + continue; + bt = &cx->bt1; + } + + is_24g = (dm->corx_map[BTC_RF_S0][i] || + dm->corx_map[BTC_RF_S1][i]) & BIT(RTW89_BAND_2G); + is_56g = (dm->corx_map[BTC_RF_S0][i] || + dm->corx_map[BTC_RF_S1][i]) & BIT(RTW89_BAND_5G); + if (is_24g) + scbd_bit |= BTC_WSCB_BT_HILNA; + if (is_56g) + scbd_bit |= BTC_WSCB_BT_HILNA_56G; + + if ((is_24g && (en != (!!bt->hi_lna_rx))) || + (is_56g && (en != (!!bt->hi_lna_rx_6g)))) + _write_scbd(rtwdev, i, scbd_bit, en); + } +} + +static void _set_rf_trx_para_v9(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_smap *wl_smap = &cx->wl.status.map; + struct rtw89_btc_dm *dm = &btc->dm; + bool bt_2r = false; + u8 wl_stb_chg = 0; + + if (wl_smap->rf_off || wl_smap->lps == BTC_LPS_RF_OFF) + return; + + /* must call after _set_halbb_btg_ctrl() */ + if (dm->tdd_bind.wl_link_mode != BTC_WLINK_NOLINK) { + wl_stb_chg = 1; + if (dm->wl_btg_rx) + bt_2r = true; + } + + _set_bt_corx_table(rtwdev, bt_2r); + + if (wl_stb_chg != dm->wl_stb_chg) { + dm->wl_stb_chg = wl_stb_chg; + dm->ost_info.wl_btg_standby_chg = wl_stb_chg; + rtwdev->chip->ops->btc_wl_s1_standby(rtwdev, dm->wl_stb_chg); + } +} + +static void _set_rf_trx_para(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *r = &wl->role_info; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + struct rtw89_btc_wl_smap *wl_smap = &wl->status.map; + struct rtw89_btc_rf_trx_para_v9 para; + u8 bmode = dm->tdd_bind.wl_link_mode; + u8 rf_band = dm->tdd_bind.rf_band; + u8 i, ul_para_num, dl_para_num; + u8 mode = BTC_WLINK_NOLINK; + u8 bid = BTC_BT_1ST, lv; + u32 wl_stb_chg; + + if (ver->fcxtrx == 9) { + /* Early v9 need to assign UL/DL RF para at driver */ + if (chip->rf_para_ulink_v9) { + ul_para_num = chip->rf_para_ulink_num_v9; + dl_para_num = chip->rf_para_dlink_num_v9; + } else { + _set_rf_trx_para_v9(rtwdev); + return; + } + } else if ((ver->fcxtrx == 0 || ver->fcxtrx == 7 || ver->fcxtrx == 107) && + chip->rf_para_ulink_v0) { + ul_para_num = chip->rf_para_ulink_num_v0; + dl_para_num = chip->rf_para_dlink_num_v0; + } else { + rtw89_warn(rtwdev, "[BTC]%s(), No rf_para for verseion %d\n", + __func__, ver->fcxtrx); + goto next; + } + + if (bmode == BTC_WLINK_NOLINK) { + return; + } else if (rf_band == RTW89_BAND_5G) { + mode = BTC_WLINK_V0_5G; + } else if (rf_band == RTW89_BAND_2G && bmode == BTC_WLINK_STA) { + mode = BTC_WLINK_V0_2G_STA; + } + + /* decide trx_para_level */ + if (btc->ant_type == BTC_ANT_SHARED) { + /* fix LNA2 + TIA gain not change by GNT_BT */ + if ((btc->dm.wl_btg_rx && b->link_cnt.now != 0) || + dm->bt_only == 1) + dm->trx_para_level = 1; /* for better BT ACI issue */ + else + dm->trx_para_level = 0; + } else { /* non-shared antenna */ + dm->trx_para_level = 5; + /* modify trx_para if WK 2.4G-STA-DL + bt link */ + if (b->link_cnt.now != 0 && + mode == BTC_WLINK_V0_2G_STA && + wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { /* uplink */ + if (wl->rssi_level == 4 && bt->rssi_level > 2) + dm->trx_para_level = 6; + else if (wl->rssi_level == 3 && bt->rssi_level > 3) + dm->trx_para_level = 7; + } + } + + lv = dm->trx_para_level; + if (lv >= ul_para_num || + lv >= dl_para_num) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): invalid level_id: %d\n", + __func__, lv); + return; + } + + if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + if (ver->fcxtrx == 9) { + para = chip->rf_para_ulink_v9[lv]; + } else { + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) { + para.wl_tx_power[i] = chip->rf_para_ulink_v0[lv].wl_tx_power; + para.wl_rx_gain[i] = chip->rf_para_ulink_v0[lv].wl_rx_gain; + } + for (i = BTC_BT_1ST; i < BTC_ALL_BT; i++) { + para.bt_tx_power[i] = chip->rf_para_ulink_v0[lv].bt_tx_power; + para.bt_rx_gain[i] = chip->rf_para_ulink_v0[lv].bt_rx_gain; + } + } + } else { + if (ver->fcxtrx == 9) { + para = chip->rf_para_dlink_v9[lv]; + } else { + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) { + para.wl_tx_power[i] = chip->rf_para_dlink_v0[lv].wl_tx_power; + para.wl_rx_gain[i] = chip->rf_para_dlink_v0[lv].wl_rx_gain; + } + for (i = BTC_BT_1ST; i < BTC_ALL_BT; i++) { + para.bt_tx_power[i] = chip->rf_para_dlink_v0[lv].bt_tx_power; + para.bt_rx_gain[i] = chip->rf_para_dlink_v0[lv].bt_rx_gain; + } + } + } + + if (dm->fddt_train) { + _set_wl_rx_gain(rtwdev, 1, RTW89_PHY_0); + _write_scbd(rtwdev, bid, BTC_WSCB_RXGAIN, true); + } else { + _set_wl_tx_power(rtwdev, para.wl_tx_power[RTW89_PHY_0], RTW89_PHY_0); + _set_wl_rx_gain(rtwdev, para.wl_rx_gain[RTW89_PHY_0], RTW89_PHY_0); + _set_bt_tx_power(rtwdev, true, bid, rf_band, para.bt_tx_power[BTC_BT_1ST]); + _set_bt_rx_gain(rtwdev, true, bid, rf_band, para.bt_rx_gain[BTC_BT_1ST]); + } + +next: + if (!bt->enable.now || dm->wl_only || wl_smap->rf_off || + wl_smap->lps == BTC_LPS_RF_OFF || mode == BTC_WLINK_V0_5G || + (rtwdev->dbcc_en && r->dbcc_2g_phy != RTW89_PHY_1)) + wl_stb_chg = 0; + else + wl_stb_chg = 1; + + if (wl_stb_chg != dm->wl_stb_chg) { + dm->wl_stb_chg = wl_stb_chg; + chip->ops->btc_wl_s1_standby(rtwdev, dm->wl_stb_chg); + } +} + +static void _update_btc_state_map(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt0; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + + if (wl->status.map.dhcp || wl->status.map._4way || + wl->status.map.roaming || wl->status.map.transacting || + wl->status.map.handshake) { + cx->state_map = BTC_WLINKING; + } else if (wl->status.map.scan) { /* wl scan */ + if (bt_linfo->status.map.inq_pag) + cx->state_map = BTC_WSCAN_BSCAN; + else + cx->state_map = BTC_WSCAN_BNOSCAN; + } else if (wl->status.map.busy) { /* only busy */ + if (bt_linfo->status.map.inq_pag) + cx->state_map = BTC_WBUSY_BSCAN; + else + cx->state_map = BTC_WBUSY_BNOSCAN; + } else { /* wl idle */ + cx->state_map = BTC_WIDLE; + } +} + +static u8 _get_wl_guard_bw(struct rtw89_dev *rtwdev, u8 index) +{ + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + u8 guard_ch = rtwdev->chip->afh_guard_ch; + u8 bw = 0; + + /* default AFH channel sapn = center-ch +- 6MHz */ + switch (index) { + case RTW89_CHANNEL_WIDTH_20: + if (dm->freerun || dm->fddt_train) + bw = 48; + else + bw = 20 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_40: + bw = 40 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_80: + bw = 80 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_160: + case RTW89_CHANNEL_WIDTH_80_80: + bw = 160 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_320: + bw = 320 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_5: + bw = 5 + guard_ch * 2; + break; + case RTW89_CHANNEL_WIDTH_10: + bw = 10 + guard_ch * 2; + break; + default: + bw = 0; + break; + } + + return bw; +} + +static void _set_wl_ch_map(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_afh_info *afh; + u16 ch_start, ch_end, i; + u8 b_group, b_pos; /* byte-group, bit-position */ + u8 hwb; + + if (wl->afh_info[RTW89_MAC_0][RTW89_BAND_2G].en && + wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].en) { + /* select wilder bw if 1+1 */ + if (wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].bw > + wl->afh_info[RTW89_MAC_0][RTW89_BAND_2G].bw) + hwb = RTW89_MAC_1; + else + hwb = RTW89_MAC_0; + } else if (wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].en) { + hwb = RTW89_MAC_1; + } else { + hwb = RTW89_MAC_0; + } + + afh = &wl->afh_info[hwb][RTW89_BAND_2G]; + + /* focus on WL 2.4GHz link */ + if (!afh->en || afh->band != RTW89_BAND_2G) + return; + + memset(wl->ch_map, 0x0, sizeof(wl->ch_map)); + memset(wl->ch_map_le, 0x0, sizeof(wl->ch_map_le)); + + ch_start = afh->ch * 5 + 2407 - afh->bw / 2; + ch_end = ch_start + afh->bw; + + for (i = ch_start; i < ch_end; i++) { + if (i < 2402 || i > 2480) + continue; + b_group = (i - 2402) / 8; + b_pos = 7 - ((i - 2402) % 8); + wl->ch_map[b_group] |= BIT(b_pos); + + if (i % 2) /* BLE ch = even-freq (ex:2402,2404) */ + continue; + + b_group = (i - 2402) / 16; + b_pos = 7 - (((i - 2402) / 2) % 8); + wl->ch_map_le[b_group] |= BIT(b_pos); + } +} + +static u8 _get_w2b_fbd_ch(struct rtw89_dev *rtwdev, + u8 bt_fb_band, u32 wl_vco_freq, + u32 *ch_lo_bound, u32 *ch_up_bound) +{ + u32 ch_lo, ch_pup, ch_min, ch_max; + u8 out_of_range = 0; + s32 val_lo, val_up; + u32 vco_lo_in_KHz; /* VCO pulling lower bound */ + u32 vco_up_in_KHz; /* VCO pulling Upper bound */ + u32 freq_start; + + vco_lo_in_KHz = wl_vco_freq - BTC_VCO_GUARD_W2B * 1000; /* KHz */ + vco_up_in_KHz = wl_vco_freq + BTC_VCO_GUARD_W2B * 1000; + + switch (bt_fb_band) { + default: + case BTC_BT_B2G: /* BT 2GHz forbiddened Channel */ + val_lo = vco_lo_in_KHz * BTC_LO_2G_DNM / BTC_LO_2G_NMR; + val_up = vco_up_in_KHz * BTC_LO_2G_DNM / BTC_LO_2G_NMR; + freq_start = BTC_FREQ_B2G * 1000; /* KHz */ + ch_min = BTC_CH_B2G_MIN; + ch_max = BTC_CH_B2G_MAX; + break; + case BTC_BT_B5G: /* BT 5/6GHz forbiddened Channel */ + val_lo = vco_lo_in_KHz * BTC_LO_6G_DNM / BTC_LO_6G_NMR; + val_up = vco_up_in_KHz * BTC_LO_6G_DNM / BTC_LO_6G_NMR; + freq_start = BTC_FREQ_B6G * 1000; /* KHz */ + ch_min = BTC_CH_B5G_MIN; + ch_max = BTC_CH_B5G_MAX; + break; + } + + /* Search forbiddened Channel (un-process range)*/ + ch_lo = (val_lo - freq_start) / 1000; + if ((val_lo - freq_start) % 1000 != 0) /* Round-UP */ + ch_lo++; + + ch_pup = (val_up - freq_start) / 1000; /* Round-down */ + + /* Search forbiddened Channel */ + if (ch_lo > ch_max || ch_pup < ch_min) { /* out-of-range -> NA */ + out_of_range = 1; + *ch_lo_bound = 0; + *ch_up_bound = 0; + } + + if (ch_lo < ch_min) + *ch_lo_bound = ch_min; + else if (ch_lo <= ch_max) + *ch_lo_bound = ch_lo; + + if (ch_pup > ch_max) + *ch_up_bound = ch_max; + else if (ch_pup >= ch_min) + *ch_up_bound = ch_pup; + + if (bt_fb_band == BTC_BT_B5G) { /* BT ch is 8MHz-spacing for 5/6GHz */ + *ch_lo_bound = *ch_lo_bound / 8; /* low-bound -> Round-down */ + + if (*ch_up_bound % 8 != 0) /* Up-bound -> cover wider range */ + *ch_up_bound = *ch_up_bound / 8 + 1; + else + *ch_up_bound = *ch_up_bound / 8; + } + + return out_of_range; +} + +static void _set_wl_ch_info(struct rtw89_dev *rtwdev) +{ + static const u8 path_hwb[BTC_RF_NUM] = {RTW89_PHY_0, RTW89_PHY_1}; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 vco_freq, ch_lo = 0, ch_up = 0; + u16 rf_band, freq, f_diff; + u8 i, j, ch; + + if (!(rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA)) /* only new-PTA require setup */ + return; + + for (i = RTW89_PHY_0; i <= RTW89_PHY_1; i++) { + if (wl->mlo_info.wmode[i] == RTW89_MR_WMODE_NONE) { /* no-connect */ + dm->ost_info.rf_center_freq[i] = 0; + dm->ost_info.fbd_group_en[i][0] = 0; + dm->ost_info.fbd_group_en[i][1] = 0; + dm->ost_info.fbd_group_bound[i][0] = 0; + dm->ost_info.fbd_group_bound[i][1] = 0; + continue; + } + + ch = wl->rf_ch_info[i].center_ch; + switch (wl->rf_ch_info[i].band) { + case RTW89_BAND_2G: + default: + rf_band = 0; + if (ch == 14) + freq = BTC_FREQ_W2G_CH14; + else + freq = BTC_FREQ_W2G + (ch - 1) * 5; + vco_freq = freq * 1000 * BTC_LO_2G_NMR / BTC_LO_2G_DNM; + break; + case RTW89_BAND_5G: + rf_band = BIT(15); + freq = BTC_FREQ_W5G + (ch - 1) * 5; + vco_freq = freq * 1000 * BTC_LO_5G_NMR / BTC_LO_5G_DNM; + break; + case RTW89_BAND_6G: + rf_band = BIT(15); + freq = BTC_FREQ_W6G + (ch - 1) * 5; + vco_freq = freq * 1000 * BTC_LO_6G_NMR / BTC_LO_6G_DNM; + break; + } + + dm->ost_info.rf_center_freq[i] = rf_band + freq; + + for (j = BTC_BT_B2G; j <= BTC_BT_B5G; j++) { + /* no WL->BT forbidden channel */ + if (_get_w2b_fbd_ch(rtwdev, j, vco_freq, &ch_lo, &ch_up)) { + dm->ost_info.fbd_group_en[i][j] = j << 1; + dm->ost_info.fbd_group_bound[i][j] = 0; + continue; + } + + dm->ost_info.fbd_group_en[i][j] = (j << 1) + 0x1; + dm->ost_info.fbd_group_bound[i][j] = (ch_up << 8) + ch_lo; + } + } + + for (i = BTC_RF_S0; i <= BTC_RF_S1; i++) { + for (j = BTC_BT_1ST; j <= BTC_BT_EXT; j++) { + /* + * If WL & BT share same ANT/Path, set freq-diff > 2GHz, + * because TDD will always run in 5/6GHz band. + * Otherwise, the frq-diff thres is decided by the RF + * out-of-channel rejection capability. + */ + if (dm->ant_xmap[i][j]) + f_diff = 0x7ff; /* 2047MHz */ + else + f_diff = rtwdev->chip->fdd_iso_freq; + + dm->ost_info.freq_diff_thres[path_hwb[i]][j] = f_diff; + } + } +} + +static void _set_bt_afh_info(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_rlink *rlink; + u8 h2c_func, hwb, bt_link_chg; + u8 i, j, sz, bw; + u8 buf[4]; + + if (btc->manual_ctrl || wl->status.map.rf_off || + (wl->status.val & btc_scanning_map.val)) + return; + + memset(wl->afh_info, 0, sizeof(wl->afh_info)); + + for (j = RTW89_MAC_0; j < RTW89_MAC_NUM; j++) { + /* skip HW-Band if no fdd/fdd bind */ + if ((!(btc->dm.tdd_bind.wl_hwb_sel & BIT(j))) && + (!(btc->dm.fdd_bind.wl_hwb_sel & BIT(j)))) + continue; + + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { + rlink = &wl_rinfo->rlink[i][j]; + + /* Skip no-active case */ + if (!rlink->connected || !rlink->active || + rlink->rf_band >= RTW89_BAND_NUM) + continue; + + /* In addition to AP/P2P, skip if same-rf-band*/ + if (wl->afh_info[j][rlink->rf_band].en && + (rlink->role != RTW89_WIFI_ROLE_AP && + rlink->role != RTW89_WIFI_ROLE_P2P_GO && + rlink->role != RTW89_WIFI_ROLE_P2P_CLIENT)) + continue; + + bw = _get_wl_guard_bw(rtwdev, rlink->bw); + wl->afh_info[j][rlink->rf_band].en = 1; + wl->afh_info[j][rlink->rf_band].ch = rlink->ch; + wl->afh_info[j][rlink->rf_band].bw = bw; + wl->afh_info[j][rlink->rf_band].band = rlink->rf_band; + } + } + + for (j = RTW89_BAND_2G; j < RTW89_BAND_NUM; j++) { + /* skip non-2.4GHz if BT is 2.4GHz only*/ + if (!(rtwdev->chip->para_ver & BTC_FEAT_BT_6G)) { + if (j != RTW89_BAND_2G) + continue; + sz = 3; + } else { + sz = 4; + } + + if (wl->afh_info[RTW89_MAC_0][j].en && + wl->afh_info[RTW89_MAC_1][j].en) { + /* select wilder bw if 1+1 */ + if (wl->afh_info[RTW89_MAC_1][j].bw > + wl->afh_info[RTW89_MAC_0][j].bw) + hwb = RTW89_MAC_1; + else + hwb = RTW89_MAC_0; + } else if (wl->afh_info[RTW89_MAC_1][j].en) { + hwb = RTW89_MAC_1; + } else { + hwb = RTW89_MAC_0; + } + + if (j == RTW89_BAND_2G) { + if (cx->bt0.link_info.link_cnt.chg || + cx->bt1.link_info.link_cnt.chg) + bt_link_chg = 1; + else + bt_link_chg = 0; + } else { + if (cx->bt0.link_info_56g.link_cnt.chg || + cx->bt1.link_info_56g.link_cnt.chg) + bt_link_chg = 1; + else + bt_link_chg = 0; + } + + /* return if no-afh-info-change/no wl-bt link change */ + if (!memcmp(&wl->afh_info_last[hwb][j], + &wl->afh_info[hwb][j], + sizeof(struct rtw89_btc_wl_afh_info)) && + !bt_link_chg && + !wl->link_mode_chg) + continue; + + memcpy(&wl->afh_info_last[hwb][j], + &wl->afh_info[hwb][j], + sizeof(struct rtw89_btc_wl_afh_info)); + + buf[0] = wl->afh_info[hwb][j].en; + buf[1] = wl->afh_info[hwb][j].ch; + buf[2] = wl->afh_info[hwb][j].bw; + buf[3] = wl->afh_info[hwb][j].band; + + h2c_func = SET_BT_WL_CH_INFO; + if (cx->bt0.enable.now) + _send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, sz); + + /* send mailbox to 2nd-BT if exist */ + if (cx->bt1.enable.now) { + h2c_func |= BT_H2C_FUNC_BT2ND; + _send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, sz); + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): en=%d, ch=%d, bw=%d, rf_band=%d\n", + __func__, buf[0], buf[1], buf[2], buf[3]); + + wl->wcnt[BTC_WCNT_CH_UPDATE]++; + + /* ToDo: Remove if BT update new-define to support 6GHz */ + if (j == RTW89_BAND_2G) + break; + } + + /* for AFH map display in coex log */ + _set_wl_ch_map(rtwdev); + + /* set HWB center-ch/forbidden group to ost_info for CR setup in FW */ + _set_wl_ch_info(rtwdev); +} + +static bool _check_freerun(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc; + struct rtw89_btc_module *md = &btc->mdinfo; + + if (btc->ant_type == BTC_ANT_SHARED) { + btc->dm.trx_para_level = 0; + return false; + } + + /* The below is dedicated antenna case */ + if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) { + btc->dm.trx_para_level = 5; + return true; + } + + if (bt_linfo->link_cnt.now == 0) { + btc->dm.trx_para_level = 5; + return true; + } + + if (hid->pair_cnt > BTC_TDMA_BTHID_MAX) { + btc->dm.trx_para_level = 5; + return true; + } + + /* TODO get isolation by BT psd */ + if (md->ant.isolation >= BTC_FREERUN_ANTISO_MIN) { + btc->dm.trx_para_level = 5; + return true; + } + + if (!wl->status.map.busy) {/* wl idle -> freerun */ + btc->dm.trx_para_level = 5; + return true; + } else if (wl->rssi_level > 1) {/* WL rssi < 50% (-60dBm) */ + btc->dm.trx_para_level = 0; + return false; + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + if (wl->rssi_level == 0 && bt_linfo->rssi > 31) { + btc->dm.trx_para_level = 6; + return true; + } else if (wl->rssi_level == 1 && bt_linfo->rssi > 36) { + btc->dm.trx_para_level = 7; + return true; + } + btc->dm.trx_para_level = 0; + return false; + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) { + if (bt_linfo->rssi > 28) { + btc->dm.trx_para_level = 6; + return true; + } + } + + btc->dm.trx_para_level = 0; + return false; +} + +#define _tdma_set_flctrl(btc, flc) ({(btc)->dm.tdma.rxflctrl = flc; }) +#define _tdma_set_flctrl_role(btc, role) ({(btc)->dm.tdma.rxflctrl_role = role; }) +#define _tdma_set_rxflctrl(btc, rxflc) ({(btc)->dm.tdma.rxflctrl = rxflc; }) +#define _tdma_set_txflctrl(btc, txflc) ({(btc)->dm.tdma.txflctrl = txflc; }) +#define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; }) + +struct btc_btinfo_lb2 { + u8 connect: 1; + u8 sco_busy: 1; + u8 inq_pag: 1; + u8 acl_busy: 1; + u8 hfp: 1; + u8 hid: 1; + u8 a2dp: 1; + u8 pan: 1; +}; + +struct btc_btinfo_lb3 { + u8 retry: 4; + u8 cqddr: 1; + u8 inq: 1; + u8 mesh_busy: 1; + u8 pag: 1; +}; + +struct btc_btinfo_hb0 { + s8 rssi; +}; + +struct btc_btinfo_hb1 { + u8 ble_connect: 1; + u8 reinit: 1; + u8 relink: 1; + u8 igno_wl: 1; + u8 voice: 1; + u8 ble_scan: 1; + u8 role_sw: 1; + u8 multi_link: 1; +}; + +struct btc_btinfo_hb2 { + u8 pan_active: 1; + u8 afh_update: 1; + u8 a2dp_active: 1; + u8 slave: 1; + u8 hid_slot: 2; + u8 hid_cnt: 2; +}; + +struct btc_btinfo_hb3 { + u8 a2dp_bitpool: 6; + u8 tx_3m: 1; + u8 a2dp_sink: 1; +}; + +union btc_btinfo { + u8 val; + struct btc_btinfo_lb2 lb2; + struct btc_btinfo_lb3 lb3; + struct btc_btinfo_hb0 hb0; + struct btc_btinfo_hb1 hb1; + struct btc_btinfo_hb2 hb2; + struct btc_btinfo_hb3 hb3; +}; + +static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, + enum btc_reason_and_action action) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->btc_set_policy(rtwdev, policy_type); + _fw_set_policy(rtwdev, policy_type, action); +} + +static void _set_tdma_bind(struct rtw89_dev *rtwdev, bool tdma_on) +{ + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_bind_info *bind; + u8 null_role = RTW89_WIFI_ROLE_STATION; + u8 bt_sel; + + if (dm->tdd_en) + bind = &dm->tdd_bind; /* tdd = 1 && fdd = 0 or 1 */ + else + bind = &dm->fdd_bind; /* tdd = 0 && fdd = 1 */ + + if (bind->bt_sel >= (BIT(BTC_BT_1ST) | BIT(BTC_BT_2ND))) + bt_sel = BTC_ALL_BT; + else if (bind->bt_sel == BIT(BTC_BT_2ND)) + bt_sel = BTC_BT_2ND; + else + bt_sel = BTC_BT_1ST; + + /* notify BT TDMA on/off by scoreboard for ACL/Scan schedule */ + _write_scbd(rtwdev, bt_sel, BTC_WSCB_TDMA, tdma_on); + + /* + * set hwb/bt bind to TDMA policy parameter + * FW-BTC will setup related hwbx vs. BTx coex tables by slot toggle + * ex: HWb0 + BT0 + BT1, HWB0-BT0/HWB0-BT1 coex by WL/BT slot toggle + */ + dm->tdma.bind = ((bind->bt_sel & 0xf) << 4) + (bind->wl_hwb_sel & 0x3); + if (dm->tdd_en) + dm->tdma.bind |= BIT(2); + if (dm->fdd_en) + dm->tdma.bind |= BIT(3); + if (rtwdev->btc.ver->fcxtdma != 8) + dm->tdma.bind |= 0; + + /* set Null-tx role for 2 HW-BAND TDMA (MLMR) */ + if (!dm->eslot_ctrl.en && dm->tdma.rxflctrl && + (bind->wl_hwb_sel == (BIT(RTW89_PHY_1) | BIT(RTW89_PHY_0)))) { + null_role = (null_role << 4) + null_role; + _tdma_set_flctrl_role(&rtwdev->btc, null_role); + } +} + +#define BTC_B1_MAX 250 /* unit ms */ +void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_tdma *t = &dm->tdma; + u8 type; + u32 tbl_w1, tbl_b1, tbl_b4; + bool tdma_on = false; + + if (btc->ant_type == BTC_ANT_SHARED) { + if (btc->cx.wl.status.map._4way) + tbl_w1 = cxtbl[1]; + else + tbl_w1 = cxtbl[8]; + tbl_b1 = cxtbl[3]; + tbl_b4 = cxtbl[3]; + } else { + tbl_w1 = cxtbl[16]; + tbl_b1 = cxtbl[17]; + tbl_b4 = cxtbl[17]; + } + + type = (u8)((policy_type & BTC_CXP_MASK) >> 8); + btc->bt_req_en = false; + + switch (type) { + case BTC_CXP_USERDEF0: + *t = t_def[CXTD_OFF]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + btc->update_policy_force = true; + break; + case BTC_CXP_OFF: /* TDMA off */ + tdma_on = false; + *t = t_def[CXTD_OFF]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + + switch (policy_type) { + case BTC_CXP_OFF_BT: + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + case BTC_CXP_OFF_WL: + _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); + break; + case BTC_CXP_OFF_EQ0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + break; + case BTC_CXP_OFF_EQ1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); + break; + case BTC_CXP_OFF_EQ2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); + break; + case BTC_CXP_OFF_EQ3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); + break; + case BTC_CXP_OFF_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); + break; + case BTC_CXP_OFF_BWB1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + case BTC_CXP_OFF_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; + } + break; + case BTC_CXP_OFFB: /* TDMA off + beacon protect */ + tdma_on = false; + *t = t_def[CXTD_OFF_B2]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + _slot_set(btc, CXST_B2, 10, cxtbl[1], SLOT_ISO); + + switch (policy_type) { + case BTC_CXP_OFFB_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); + break; + case BTC_CXP_OFFB_BWB1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + case BTC_CXP_OFFB_BWB2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[7]); + break; + case BTC_CXP_OFFB_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; + case BTC_CXP_OFFB_BWB4: + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + } + break; + case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ + btc->bt_req_en = true; + tdma_on = true; + *t = t_def[CXTD_OFF_EXT]; + switch (policy_type) { + case BTC_CXP_OFFE_DEF: + _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, + s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); + break; + case BTC_CXP_OFFE_DEF2: + _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); + break; + } + break; + case BTC_CXP_FIX: /* TDMA Fix-Slot */ + tdma_on = true; + *t = t_def[CXTD_FIX]; + switch (policy_type) { + case BTC_CXP_FIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010: + _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010ISO: + _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010ISO_DL: + _slot_set(btc, CXST_W1, 40, cxtbl[25], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_ISO); + break; + case BTC_CXP_FIX_TD4010ISO_UL: + _slot_set(btc, CXST_W1, 40, cxtbl[20], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_MIX); + break; + case BTC_CXP_FIX_TD7010: + _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD3060: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ + tdma_on = true; + *t = t_def[CXTD_PFIX]; + if (btc->cx.wl.role_info.role_map & BIT(RTW89_WIFI_ROLE_AP)) + _tdma_set_flctrl(btc, CXFLC_QOSNULL); + + switch (policy_type) { + case BTC_CXP_PFIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_AUTO: /* TDMA Auto-Slot */ + tdma_on = true; + *t = t_def[CXTD_AUTO]; + switch (policy_type) { + case BTC_CXP_AUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ + tdma_on = true; + *t = t_def[CXTD_PAUTO]; + switch (policy_type) { + case BTC_CXP_PAUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TDW1B1: + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ + tdma_on = true; + *t = t_def[CXTD_AUTO2]; + switch (policy_type) { + case BTC_CXP_AUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + } + break; + case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ + tdma_on = true; + *t = t_def[CXTD_PAUTO2]; + switch (policy_type) { + case BTC_CXP_PAUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + } + break; + } + _set_tdma_bind(rtwdev, tdma_on); +} +EXPORT_SYMBOL(rtw89_btc_set_policy); + +void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_tdma *t = &dm->tdma; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt0.link_info.hid_desc; + struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt0.link_info.hfp_desc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + u8 type, null_role; + u32 tbl_w1, tbl_b1, tbl_b4; + bool tdma_on = false; + u16 dur_1 = 0, dur_2; + + if (wl->status.map.lps) { + _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, + s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + } + + type = FIELD_GET(BTC_CXP_MASK, policy_type); + + if (btc->ant_type == BTC_ANT_SHARED) { + if (btc->cx.wl.status.map._4way) + tbl_w1 = cxtbl[1]; + else if (hid->exist && hid->type == BTC_HID_218) + tbl_w1 = cxtbl[7]; /* Ack/BA no break bt Hi-Pri-rx */ + else + tbl_w1 = cxtbl[8]; + + if (dm->leak_ap && + (type == BTC_CXP_PFIX || type == BTC_CXP_PAUTO2)) { + tbl_b1 = cxtbl[3]; + tbl_b4 = cxtbl[3]; + } else if (hid->exist && hid->type == BTC_HID_218) { + tbl_b1 = cxtbl[4]; /* Ack/BA no break bt Hi-Pri-rx */ + tbl_b4 = cxtbl[4]; + } else { + tbl_b1 = cxtbl[2]; + tbl_b4 = cxtbl[2]; + } + } else { + tbl_b1 = cxtbl[17]; + tbl_b4 = cxtbl[17]; + + if (wl->bg_mode) + tbl_w1 = cxtbl[8]; + else if ((wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) && + hid->exist) + tbl_w1 = cxtbl[19]; + else + tbl_w1 = cxtbl[16]; + } + + switch (type) { + case BTC_CXP_USERDEF0: + btc->update_policy_force = true; + *t = t_def[CXTD_OFF]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + case BTC_CXP_OFF: /* TDMA off */ + tdma_on = false; + *t = t_def[CXTD_OFF]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + + switch (policy_type) { + case BTC_CXP_OFF_BT: + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + case BTC_CXP_OFF_WL: + _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); + break; + case BTC_CXP_OFF_WL2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); + _slot_set_type(btc, CXST_OFF, SLOT_ISO); + break; + case BTC_CXP_OFF_EQ0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + _slot_set_type(btc, CXST_OFF, SLOT_ISO); + break; + case BTC_CXP_OFF_EQ1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); + break; + case BTC_CXP_OFF_EQ2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + break; + case BTC_CXP_OFF_EQ3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); + break; + case BTC_CXP_OFF_EQ4: + _slot_set_tbl(btc, CXST_OFF, cxtbl[26]); + break; + case BTC_CXP_OFF_EQ5: + _slot_set_tbl(btc, CXST_OFF, cxtbl[27]); + break; + case BTC_CXP_OFF_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); + break; + case BTC_CXP_OFF_BWB1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + case BTC_CXP_OFF_BWB2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[7]); + break; + case BTC_CXP_OFF_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; + default: + break; + } + break; + case BTC_CXP_OFFB: /* TDMA off + beacon protect */ + tdma_on = false; + *t = t_def[CXTD_OFF_B2]; + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + _slot_set(btc, CXST_B2, 10, cxtbl[1], SLOT_ISO); + + switch (policy_type) { + case BTC_CXP_OFFB_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); + break; + case BTC_CXP_OFFB_BWB1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + case BTC_CXP_OFFB_BWB2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[7]); + break; + case BTC_CXP_OFFB_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; + case BTC_CXP_OFFB_BWB4: + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + } + break; + case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ + tdma_on = true; + *t = t_def[CXTD_OFF_EXT]; + + /* To avoid wl-s0 tx break by hid/hfp tx */ + if (hid->exist || hfp->exist) + tbl_w1 = cxtbl[16]; + + if (dm->eslot_ctrl.en) { + null_role = u8_encode_bits(dm->eslot_ctrl.nulltx_role1, 0x0f) | + u8_encode_bits(dm->eslot_ctrl.nulltx_role2, 0xf0); + _tdma_set_flctrl_role(btc, null_role); + _tdma_set_rxflctrl(btc, 1); + _tdma_set_txflctrl(btc, 1); + /* Set Null-Tx time-tick by E2G duration */ + dm->eslot_ctrl.nulltx_pre_time = 5; /* TODO: BIS COEX */ + dur_1 = dm->eslot_ctrl.nulltx_pre_time; + } + + dur_2 = dm->e2g_slot_limit; + + switch (policy_type) { + case BTC_CXP_OFFE_2GBWISOB: /* for normal-case */ + _slot_set(btc, CXST_E2G, dur_1, tbl_w1, SLOT_ISO); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_dur(btc, CXST_EBT, dur_2); + break; + case BTC_CXP_OFFE_2GISOB: /* for bt no-link */ + _slot_set(btc, CXST_E2G, dur_1, cxtbl[1], SLOT_ISO); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_dur(btc, CXST_EBT, dur_2); + break; + case BTC_CXP_OFFE_DEF: + _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, + s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); + _slot_set_dur(btc, CXST_EBT, dur_2); + break; + case BTC_CXP_OFFE_DEF2: + _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); + _slot_set_dur(btc, CXST_EBT, dur_2); + break; + case BTC_CXP_OFFE_2GBWMIXB: + if (a2dp->exist) + _slot_set(btc, CXST_E2G, dur_1, cxtbl[2], SLOT_MIX); + else + _slot_set(btc, CXST_E2G, dur_1, tbl_w1, SLOT_MIX); + _slot_set_le(btc, CXST_EBT, cpu_to_le16(40), + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); + _slot_set_dur(btc, CXST_EBT, dur_2); + break; + case BTC_CXP_OFFE_WL: /* for 4-way */ + _slot_set(btc, CXST_E2G, dur_1, cxtbl[1], SLOT_MIX); + _slot_set(btc, CXST_EBT, dur_1, cxtbl[1], SLOT_MIX); + break; + default: + break; + } + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); + break; + case BTC_CXP_FIX: /* TDMA Fix-Slot */ + tdma_on = true; + *t = t_def[CXTD_FIX]; + + switch (policy_type) { + case BTC_CXP_FIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010: + _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010ISO: + _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010ISO_DL: + _slot_set(btc, CXST_W1, 40, cxtbl[25], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_ISO); + break; + case BTC_CXP_FIX_TD4010ISO_UL: + _slot_set(btc, CXST_W1, 40, cxtbl[20], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_MIX); + break; + case BTC_CXP_FIX_TD7010: + _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD3060: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ + tdma_on = true; + *t = t_def[CXTD_PFIX]; + + switch (policy_type) { + case BTC_CXP_PFIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_AUTO: /* TDMA Auto-Slot */ + tdma_on = true; + *t = t_def[CXTD_AUTO]; + + switch (policy_type) { + case BTC_CXP_AUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ + tdma_on = true; + *t = t_def[CXTD_PAUTO]; + + switch (policy_type) { + case BTC_CXP_PAUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TDW1B1: + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ + tdma_on = true; + *t = t_def[CXTD_AUTO2]; + + switch (policy_type) { + case BTC_CXP_AUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ + tdma_on = true; + *t = t_def[CXTD_PAUTO2]; + + switch (policy_type) { + case BTC_CXP_PAUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + default: + break; + } + break; + } + + /* enter leak_slot after each null-1 */ + if (dm->leak_ap && dm->tdma.leak_n > 1) + _tdma_set_lek(btc, 1); + + if (dm->tdma_instant_excute || + dm->error.map.tdma_no_sync || + dm->error.map.slot_no_sync || + dm->lps_ctrl_change) { + btc->dm.tdma.option_ctrl |= BIT(0); + btc->update_policy_force = true; + } + + if (btc->cli_h2c_cmd) + btc->update_policy_force = true; + + _set_tdma_bind(rtwdev, tdma_on); +} +EXPORT_SYMBOL(rtw89_btc_set_policy_v1); + +static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map, + u8 tx_val, u8 rx_val) +{ + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; + struct rtw89_mac_ax_plt plt; + + plt.tx = tx_val; + plt.rx = rx_val; + + if (rtwdev->btc.ver->fwlrole == 8) { + plt.band = wl->pta_req_mac; + if (wl->bt_polut_type[plt.band] == tx_val) + return; + + wl->bt_polut_type[plt.band] = tx_val; + rtw89_mac_cfg_plt(rtwdev, &plt); + } else { + plt.band = RTW89_MAC_0; + + if (phy_map & BTC_PHY_0) + rtw89_mac_cfg_plt(rtwdev, &plt); + + if (!rtwdev->dbcc_en) + return; + + plt.band = RTW89_MAC_1; + if (phy_map & BTC_PHY_1) + rtw89_mac_cfg_plt(rtwdev, &plt); + } +} + +static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, + u8 phy_map, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + u32 ant_path_type = rtw89_get_antpath_type(phy_map, type); + struct rtw89_btc_dm *dm = &btc->dm; + u8 gwl = BTC_GNT_HW, gwl0, gwl1, gbt; + bool cx_ctrl; + + if (btc->cli_h2c_cmd || wl_rinfo->dbcc_chg || + dm->run_reason == BTC_RSN_NTFY_POWEROFF || + dm->run_reason == BTC_RSN_NTFY_RADIO_STATE || + dm->run_reason == BTC_RSN_CMD_SET_COEX) + force_exec = FC_EXEC; + + if (wl_rinfo->link_mode != BTC_WLINK_DB_MCC && + btc->dm.wl_btg_rx == 2) + force_exec = FC_EXEC; + + if (!force_exec && ant_path_type == dm->set_ant_path) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return by no change!!\n", + __func__); + return; + } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK && + wl->rfk_info.state != BTC_WRFK_STOP) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return by wl rfk!!\n", __func__); + return; + } + + dm->set_ant_path = ant_path_type; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): path=0x%x, set_type=0x%x\n", + __func__, phy_map, dm->set_ant_path & 0xff); + + switch (type) { + case BTC_ANT_WPOWERON: + cx_ctrl = BTC_CTRL_BY_BT; + break; + case BTC_ANT_WINIT: + cx_ctrl = BTC_CTRL_BY_WL; + /* To avoid BT MP driver case (bt_enable but no mailbox) */ + if ((cx->bt0.enable.now && cx->bt0.run_patch_code) || + (cx->bt1.enable.now && cx->bt1.run_patch_code)) + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_LO, BTC_GNT_SW_HI, + BTC_WLACT_SW_LO); + else + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO, + BTC_WLACT_SW_HI); + break; + case BTC_ANT_WONLY: + cx_ctrl = BTC_CTRL_BY_WL; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO, + BTC_WLACT_SW_HI); + break; + case BTC_ANT_WOFF: + cx_ctrl = BTC_CTRL_BY_BT; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_LO, BTC_GNT_SW_HI, + BTC_WLACT_SW_LO); + break; + case BTC_ANT_PTA: + default: + cx_ctrl = BTC_CTRL_BY_WL; + gbt = BTC_GNT_HW; + if ((rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA) || + !wl_rinfo->dbcc_en) { + gwl = BTC_GNT_HW; + _set_gnt(rtwdev, BTC_PHY_ALL, gwl, gbt, BTC_WLACT_HW); + } else { + /* for DBCC Only-1-PTA */ + if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_0) { + gwl0 = BTC_GNT_HW; + gwl1 = BTC_GNT_SW_HI; + } else { + gwl0 = BTC_GNT_SW_HI; + gwl1 = BTC_GNT_HW; + } + _set_gnt(rtwdev, BTC_PHY_0, gwl0, gbt, BTC_WLACT_HW); + _set_gnt(rtwdev, BTC_PHY_1, gwl1, gbt, BTC_WLACT_HW); + } + break; + case BTC_ANT_FDD: + cx_ctrl = BTC_CTRL_BY_WL; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_HW, + BTC_WLACT_HW); + break; + case BTC_ANT_FREERUN: + cx_ctrl = BTC_CTRL_BY_WL; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_HI, + BTC_WLACT_SW_LO); + break; + case BTC_ANT_WRFK: + cx_ctrl = BTC_CTRL_BY_WL; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO, + BTC_WLACT_HW); + break; + case BTC_ANT_WRFK2: + cx_ctrl = BTC_CTRL_BY_WL; + _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO, + BTC_WLACT_SW_HI); /* no BT-Tx */ + break; + } + + rtw89_chip_cfg_ctrl_path(rtwdev, cx_ctrl); + _set_bt_plut(rtwdev, phy_map, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); +} + +static void _action_wl_only(struct rtw89_dev *rtwdev) +{ + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_ONLY); +} + +static void _action_wl_init(struct rtw89_dev *rtwdev) +{ + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WINIT); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_INIT); +} + +static void _action_wl_off(struct rtw89_dev *rtwdev, u8 mode) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + + if (wl->status.map.rf_off || btc->dm.bt_only) + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF); + else if (wl->status.map.lps == BTC_LPS_RF_ON || + cx->bt0.whql_test || cx->bt1.whql_test) + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_PTA); + + if (dm->out_of_band) + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OFF); + else if (cx->bt0.whql_test || cx->bt1.whql_test) + _set_policy(rtwdev, BTC_CXP_OFFB_BWB4, BTC_ACT_WL_OFF); + else + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF); +} + +static void _action_freerun(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_FREERUN); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_FREERUN); + + btc->dm.freerun = true; +} + +static void _action_bt_whql(struct rtw89_dev *rtwdev) +{ + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_WHQL); +} + +static void _action_bt_off(struct rtw89_dev *rtwdev) +{ + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_OFF); +} + +static void _action_bt_idle(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_link_info *b = &btc->cx.bt0.link_info; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /*wl-busy + bt idle*/ + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-idle */ + if (b->status.map.connect) + _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_IDLE); + else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) + _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO_DL, BTC_ACT_BT_IDLE); + else + _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO_UL, BTC_ACT_BT_IDLE); + break; + case BTC_WBUSY_BSCAN: /*wl-busy + bt-inq */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, + BTC_ACT_BT_IDLE); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq */ + _set_policy(rtwdev, BTC_CXP_FIX_TD5050, + BTC_ACT_BT_IDLE); + break; + case BTC_WLINKING: /* wl-connecting + bt-inq or bt-idle */ + _set_policy(rtwdev, BTC_CXP_FIX_TD7010, + BTC_ACT_BT_IDLE); + break; + case BTC_WIDLE: /* wl-idle + bt-idle */ + _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_IDLE); + break; + } + } else { /* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_BT_IDLE); + } +} + +static void _action_bt_hfp(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { + if (btc->cx.wl.status.map._4way) { + _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP); + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + btc->cx.bt0.scan_rx_low_pri = true; + _set_policy(rtwdev, BTC_CXP_OFF_BWB2, BTC_ACT_BT_HFP); + } else { + _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP); + } + } else { + if (wl->bg_mode) + _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP); + else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) + _set_policy(rtwdev, BTC_CXP_OFF_EQ5, BTC_ACT_BT_HFP); + else + _set_policy(rtwdev, BTC_CXP_OFF_EQ2, BTC_ACT_BT_HFP); + } +} + +static void _action_bt_hid(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_bt_hid_desc *hid = &bt->link_info.hid_desc; + u16 policy_type = BTC_CXP_OFF_BT; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + if (wl->status.map._4way) { + policy_type = BTC_CXP_OFF_WL; + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + btc->cx.bt0.scan_rx_low_pri = true; + if (hid->type & BTC_HID_BLE) + policy_type = BTC_CXP_OFF_BWB0; + else + policy_type = BTC_CXP_OFF_BWB2; + } else if (hid->type == BTC_HID_218) { + bt->scan_rx_low_pri = true; + policy_type = BTC_CXP_OFF_BWB2; + } else if (chip->para_ver == 0x1) { + policy_type = BTC_CXP_OFF_BWB3; + } else { + policy_type = BTC_CXP_OFF_BWB1; + } + } else { /* dedicated-antenna */ + if (wl->bg_mode) + policy_type = BTC_CXP_OFF_BWB1; + else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) + policy_type = BTC_CXP_OFF_EQ4; + else + policy_type = BTC_CXP_OFF_EQ3; + } + + _set_policy(rtwdev, policy_type, BTC_ACT_BT_HID); +} + +static void _action_bt_a2dp(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + dm->slot_dur[CXST_W1] = 20; + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */ + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */ + case BTC_WLINKING: /* wl-connecting + bt-A2DP */ + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP); + break; + case BTC_WIDLE: /* wl-idle + bt-A2DP */ + _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP); + break; + } +} + +static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2dp_Sink */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD2030, BTC_ACT_BT_A2DPSINK); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2dp_Sink */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD2060, BTC_ACT_BT_A2DPSINK); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2dp_Sink */ + _set_policy(rtwdev, BTC_CXP_FIX_TD2030, BTC_ACT_BT_A2DPSINK); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2dp_Sink */ + _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK); + break; + case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */ + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DPSINK); + else + _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); + break; + case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */ + _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK); + break; + } +} + +static void _action_bt_pan(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */ + if (a2dp.active || !pan.exist) { + btc->dm.slot_dur[CXST_W1] = 80; + btc->dm.slot_dur[CXST_B1] = 20; + _set_policy(rtwdev, BTC_CXP_PFIX_TDW1B1, BTC_ACT_BT_PAN); + } else { + _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN); + } + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN */ + _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN */ + _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN); + break; + case BTC_WLINKING: /* wl-connecting + bt-PAN */ + _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO, BTC_ACT_BT_PAN); + break; + case BTC_WIDLE: /* wl-idle + bt-pan */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN); + break; + } +} + +static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + dm->slot_dur[CXST_W1] = 20; + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */ + case BTC_WIDLE: /* wl-idle + bt-A2DP */ + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_HID); + break; + + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_HID); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */ + case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */ + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP_HID); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); + break; + } +} + +static void _action_bt_a2dp_pan(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD5050, BTC_ACT_BT_A2DP_PAN); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); + break; + case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_PAN); + break; + case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, BTC_ACT_BT_A2DP_PAN); + break; + } +} + +static void _action_bt_pan_hid(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD3030, BTC_ACT_BT_PAN_HID); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN_HID); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN_HID); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN_HID); + break; + case BTC_WLINKING: /* wl-connecting + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_PAN_HID); + break; + case BTC_WIDLE: /* wl-idle + bt-PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN_HID); + break; + } +} + +static void _action_bt_bis(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + u16 policy_type; + + if (dm->bis_tdma) + policy_type = BTC_CXP_OFFE_2GBWISOB; + else + policy_type = BTC_CXP_OFF_EQ0; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_PTA); + _set_policy(rtwdev, policy_type, BTC_ACT_BT_BIS); +} + +static void _action_bt_cis(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_dm *dm = &btc->dm; + u16 policy_type; + + if (bt_linfo->a2dp_desc.active) { + dm->slot_dur[CXST_W1] = 80; + dm->slot_dur[CXST_B1] = 20; + policy_type = BTC_CXP_PFIX_TDW1B1; + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + policy_type = BTC_CXP_OFF_BWB0; + } else { + policy_type = BTC_CXP_OFF_BWB1; + } + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_PTA); + _set_policy(rtwdev, policy_type, BTC_ACT_BT_CIS); +} + +static void _action_bt_a2dp_pan_hid(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + switch (btc->cx.state_map) { + case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, + BTC_ACT_BT_A2DP_PAN_HID); + break; + case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, + BTC_ACT_BT_A2DP_PAN_HID); + break; + case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN+HID */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, + BTC_ACT_BT_A2DP_PAN_HID); + break; + case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN+HID */ + case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN+HID */ + _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, + BTC_ACT_BT_A2DP_PAN_HID); + break; + case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN+HID */ + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, + BTC_ACT_BT_A2DP_PAN_HID); + break; + } +} + +static void _action_wl_5g(struct rtw89_dev *rtwdev) +{ + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_FDD); + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_5G); +} + +static void _action_wl_other(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) + _set_policy(rtwdev, BTC_CXP_OFFB_BWB0, BTC_ACT_WL_OTHER); + else + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OTHER); +} + +static void _action_wl_nc(struct rtw89_dev *rtwdev) +{ + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_NC); +} + +static void _action_wl_rfk(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_rfk_info rfk = btc->cx.wl.rfk_info; + + if (rfk.state != BTC_WRFK_START) + return; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n", + __func__, rfk.band); + + btc->dm.tdma_instant_excute = 1; + + if (rfk.state == BTC_WRFK_ONESHOT_START || + btc->ant_type == BTC_ANT_SHARED) { + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK2); + _set_policy(rtwdev, BTC_CXP_OFF_WL2, BTC_ACT_WL_RFK); + } else { + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK); + _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK); + } +} + +static void _set_btg_ctrl(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_outsrc_set_info *o_info = &dm->ost_info; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + u32 is_btg = BTC_BTGCTRL_DISABLE; + + if (btc->manual_ctrl) + return; + + /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */ + if (btc->ant_type == BTC_ANT_SHARED) { + if (!(bt->run_patch_code && bt->enable.now)) + is_btg = BTC_BTGCTRL_DISABLE; + else if (wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G) || + wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G)) + is_btg = BTC_BTGCTRL_ENABLE; + else + is_btg = BTC_BTGCTRL_DISABLE; + + /* bb call ctrl_btg() in WL FW by slot */ + if (!btc->ver->fcxosi && + wl_rinfo->link_mode == BTC_WLINK_DB_MCC) + is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL; + } + + if (is_btg == dm->wl_btg_rx) + return; + else + dm->wl_btg_rx = is_btg; + + /* skip setup if btg_ctrl set by wl fw */ + if (!btc->ver->fcxosi && is_btg > BTC_BTGCTRL_ENABLE) + return; + + /* Below flow is for BTC_FEAT_NEW_BBAPI_FLOW = 1 */ + if (o_info->rf_band[BTC_RF_S0] != o_info->rf_band[BTC_RF_S1]) {/* 1+1 */ + if (o_info->rf_band[BTC_RF_S0]) /* Non-2G */ + o_info->btg_rx[BTC_RF_S0] = BTC_BTGCTRL_DISABLE; + else + o_info->btg_rx[BTC_RF_S0] = is_btg; + + if (o_info->rf_band[BTC_RF_S1]) /* Non-2G */ + o_info->btg_rx[BTC_RF_S1] = BTC_BTGCTRL_DISABLE; + else + o_info->btg_rx[BTC_RF_S1] = is_btg; + } else { /* 2+0 or 0+2 */ + o_info->btg_rx[BTC_RF_S0] = is_btg; + o_info->btg_rx[BTC_RF_S1] = is_btg; + } + + if (btc->ver->fcxosi) + return; + + chip->ops->ctrl_btg_bt_rx(rtwdev, o_info->btg_rx[BTC_RF_S0], + RTW89_PHY_0); + if (chip->chip_id != RTL8922A) + return; + + chip->ops->ctrl_btg_bt_rx(rtwdev, o_info->btg_rx[BTC_RF_S1], + RTW89_PHY_1); +} + +static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info; + struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *rinfo = &wl->role_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_dm *dm = &btc->dm; + u8 is_preagc, val; + + if (btc->manual_ctrl) + return; + + if (!(bt->run_patch_code && bt->enable.now)) { + is_preagc = BTC_PREAGC_DISABLE; + } else if (dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G)) { + is_preagc = BTC_PREAGC_DISABLE; + } else if (rinfo->link_mode == BTC_WLINK_NOLINK || + btc->cx.bt0.link_info.link_cnt.now == 0) { + is_preagc = BTC_PREAGC_DISABLE; + } else if (dm->tdma_now.type != CXTDMA_OFF && + !bt_linfo->hfp_desc.exist && + !bt_linfo->hid_desc.exist && + dm->fddt_train == BTC_FDDT_DISABLE) { + is_preagc = BTC_PREAGC_DISABLE; + } else if (rinfo->dbcc_en && (rinfo->dbcc_2g_phy != RTW89_PHY_1)) { + is_preagc = BTC_PREAGC_DISABLE; + } else if (btc->ant_type == BTC_ANT_SHARED) { + is_preagc = BTC_PREAGC_DISABLE; + } else { + is_preagc = BTC_PREAGC_ENABLE; + } + + if (!btc->ver->fcxosi && rinfo->link_mode == BTC_WLINK_DB_MCC) + is_preagc = BTC_PREAGC_BB_FWCTRL; + + if (dm->wl_pre_agc_rb != dm->wl_pre_agc && + dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND) { + _get_reg_status(rtwdev, BTC_CSTATUS_BB_PRE_AGC, &val); + dm->wl_pre_agc_rb = val; + } + + if ((wl->coex_mode == BTC_MODE_NORMAL && + (dm->run_reason == BTC_RSN_NTFY_INIT || + dm->run_reason == BTC_RSN_NTFY_SWBAND || + dm->wl_pre_agc_rb != dm->wl_pre_agc)) || + is_preagc != dm->wl_pre_agc) { + dm->wl_pre_agc = is_preagc; + + if (!btc->ver->fcxosi && is_preagc > BTC_PREAGC_ENABLE) + return; + + if (o_info->rf_band[BTC_RF_S0] != o_info->rf_band[BTC_RF_S1]) {/* 1+1 */ + if (o_info->rf_band[BTC_RF_S0]) /* Non-2G */ + o_info->nbtg_tx[BTC_RF_S0] = BTC_PREAGC_DISABLE; + else + o_info->nbtg_tx[BTC_RF_S0] = is_preagc; + + if (o_info->rf_band[BTC_RF_S1]) /* Non-2G */ + o_info->nbtg_tx[BTC_RF_S1] = BTC_PREAGC_DISABLE; + else + o_info->nbtg_tx[BTC_RF_S1] = is_preagc; + + } else { /* 2+0 or 0+2 */ + o_info->nbtg_tx[BTC_RF_S0] = is_preagc; + o_info->nbtg_tx[BTC_RF_S1] = is_preagc; + } + + if (btc->ver->fcxosi) + return; + + chip->ops->ctrl_nbtg_bt_tx(rtwdev, o_info->nbtg_tx[BTC_RF_S0], + RTW89_PHY_0); + if (chip->chip_id != RTL8922A) + return; + chip->ops->ctrl_nbtg_bt_tx(rtwdev, o_info->nbtg_tx[BTC_RF_S1], + RTW89_PHY_1); + } +} + +struct rtw89_txtime_data { + struct rtw89_dev *rtwdev; + int type; + u32 tx_time; + u8 tx_retry; + u16 enable; + bool reenable; +}; + +static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_txtime_data *iter_data) +{ + struct rtw89_dev *rtwdev = iter_data->rtwdev; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_wl_link_info *plink = NULL; + u8 port = rtwvif_link->port; + u32 tx_time = iter_data->tx_time; + u8 tx_retry = iter_data->tx_retry; + u16 enable = iter_data->enable; + bool reenable = iter_data->reenable; + + plink = &wl->rlink_info[port][rtwsta_link->link_id]; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): port = %d\n", __func__, port); + + if (!plink->connected) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): connected = %d\n", + __func__, plink->connected); + return; + } + + /* backup the original tx time before tx-limit on */ + if (reenable) { + rtw89_mac_get_tx_time(rtwdev, rtwsta_link, &plink->tx_time); + rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, &plink->tx_retry); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n", + __func__, plink->tx_time, plink->tx_retry); + } + + /* restore the original tx time if no tx-limit */ + if (!enable) { + rtw89_mac_set_tx_time(rtwdev, rtwsta_link, true, plink->tx_time); + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, true, + plink->tx_retry); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): restore, tx_time=%d tx_retry= %d\n", + __func__, plink->tx_time, plink->tx_retry); + + } else { + rtw89_mac_set_tx_time(rtwdev, rtwsta_link, false, tx_time); + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, tx_retry); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): set, tx_time=%d tx_retry= %d\n", + __func__, tx_time, tx_retry); + } +} + +static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_txtime_data *iter_data = + (struct rtw89_txtime_data *)data; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + __rtw89_tx_time_iter(rtwvif_link, rtwsta_link, iter_data); + } +} + +static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt0; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; + struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_txtime_data data = {.rtwdev = rtwdev}; + bool reenable = false; + u8 tx_retry; + u32 tx_time; + u16 enable; + + if (btc->manual_ctrl) + return; + + if (btc->dm.freerun || btc->ctrl.igno_bt || b->link_cnt.now == 0 || + dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G) || + wl_rinfo->link_mode == BTC_WLINK_NOLINK) { + enable = 0; + tx_time = BTC_MAX_TX_TIME_DEF; + tx_retry = BTC_MAX_TX_RETRY_DEF; + } else if ((hfp->exist && hid->exist) || hid->pair_cnt > 1) { + enable = 1; + tx_time = BTC_MAX_TX_TIME_L2; + tx_retry = BTC_MAX_TX_RETRY_L1; + } else if (hfp->exist || hid->exist) { + enable = 1; + tx_time = BTC_MAX_TX_TIME_L3; + tx_retry = BTC_MAX_TX_RETRY_L1; + } else { + enable = 0; + tx_time = BTC_MAX_TX_TIME_DEF; + tx_retry = BTC_MAX_TX_RETRY_DEF; + } + + if (dm->wl_tx_limit.enable == enable && + dm->wl_tx_limit.tx_time == tx_time && + dm->wl_tx_limit.tx_retry == tx_retry) + return; + + if (!dm->wl_tx_limit.enable && enable) + reenable = true; + + dm->wl_tx_limit.enable = enable; + dm->wl_tx_limit.tx_time = tx_time; + dm->wl_tx_limit.tx_retry = tx_retry; + + data.enable = enable; + data.tx_time = tx_time; + data.tx_retry = tx_retry; + data.reenable = reenable; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_tx_time_iter, + &data); +} + +static void _set_phl_bt_slot_req(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_dm *dm = &btc->dm; + u8 len = 0; + u8 i; + + /* don't change bt slot req state during RFK for p2p/mcc case */ + if (dm->run_reason == BTC_RSN_NTFY_WL_RFK || + wl->status.map.transacting) + return; + + /* enable bt-slot req if ext-slot-control */ + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + dm->tdd_bind.bt_sel != 0) { + if (btc->cx.wl.status.val & btc_scanning_map.val) + btc->bt_req_en = false; + else + btc->bt_req_en = true; + } else { + btc->bt_req_en = false; + } + + if (dm->slot_req_more) { + len = BTC_BSLOT_A2DP_HID; + } else { + if (dm->tdd_bind.bt_link_weight >= BTC_BSLOT_A2DP_HID) + len = BTC_BSLOT_A2DP_HID; + else if (dm->tdd_bind.bt_link_weight <= BTC_BSLOT_IDLE) + len = BTC_BSLOT_IDLE; + else + len = dm->tdd_bind.bt_link_weight; + } + + if (dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G)) + len = 100 - len; + + if (!btc->bt_req_en) + len = 0; + + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) { + if (!(dm->tdd_bind.wl_hwb_sel & BIT(i))) + continue; + + if (len == btc->bt_req_len[i]) + continue; + + btc->bt_req_len[i] = len; + + rtw89_core_ntfy_btc_event(rtwdev, + RTW89_BTC_HMSG_SET_BT_REQ_SLOT, i); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): HWB%d bt_req_len = %d\n", + __func__, i, btc->bt_req_len[i]); + } +} + +static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + bool bt_hi_lna_rx = false; + + if (wl_rinfo->link_mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) + bt_hi_lna_rx = true; + + if (bt_hi_lna_rx == bt->hi_lna_rx) + return; + + _write_scbd(rtwdev, BTC_BT_1ST, BTC_WSCB_BT_HILNA, bt_hi_lna_rx); +} + +static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_RXSCAN_PRI, + (bool)(!!bt->scan_rx_low_pri)); +} + +static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_dm *dm = &btc->dm; + u32 add; + + if (mac == wl->pta_req_mac) + return; + + dm->ost_info.pta_req_hw_band = mac; + wl->pta_req_mac = mac; + wl->pta_reg_mac_chg = true; + + if (btc->ver->fcxosi) + return; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + add = R_BE_BTC_CFG; + else + add = R_AX_BTC_CFG; + + if (mac == RTW89_MAC_0) + rtw89_write32_clr(rtwdev, add, B_AX_WL_SRC); + else + rtw89_write32_set(rtwdev, add, B_AX_WL_SRC); +} + +static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a; + u8 link_mode_chg = btc->cx.wl.link_mode_chg; + u8 mode = btc->cx.wl.role_info.link_mode; + + if (btc->dm.run_reason != BTC_RSN_NTFY_INIT && !link_mode_chg) + return; + + if (!(btc->mdinfo.wa_type & BTC_WA_HFP_ZB)) + return; + + if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_5G) || + rtwdev->btc.dm.freerun) { + zb_tbl0 = 0xffffffff; + zb_tbl1 = 0xffffffff; + } else if (mode == BTC_WLINK_DB_MCC) { + zb_tbl0 = 0xffffffff; /* for E5G slot */ + zb_tbl1 = 0xda5a5a5a; /* for E2G slot */ + } + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0); + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1); +} + +static void _set_fw_report_map(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map; + struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0; + struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1; + u32 rpt_map = btc->fwinfo.rpt_en_map; + u32 bt_rom_code_id, bt_fw_ver; + bool bt_ver_unknown = false; + u32 bitmap; + + if (wl_smap->rf_off == 1 || wl_smap->lps != BTC_LPS_OFF) { + rtw89_btc_fw_en_rpt(rtwdev, false, 0); + return; + } + + rpt_map |= rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_MREG); + + bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_SCAN_INFO); + if ((bt0->run_patch_code && bt0->enable.now) || + (bt1->run_patch_code && bt1->enable.now)) + rpt_map |= bitmap; + else + rpt_map &= ~bitmap; + + bt_rom_code_id = chip_id_to_bt_rom_code_id(rtwdev->btc.ver->chip_id); + bt_fw_ver = bt0->ver_info.fw & 0xffff; + if (bt_fw_ver == 0 || + (bt_fw_ver == bt_rom_code_id && bt0->run_patch_code)) + bt_ver_unknown = true; + + bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_VER_INFO); + if (bt0->enable.now && bt_ver_unknown) + rpt_map |= bitmap; + else + rpt_map &= ~bitmap; + + bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_AFH_MAP) | + rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_AFH_MAP_LE) | + rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_TX_PWR_LVL); + if (bt0->link_info.link_cnt.now || + bt0->link_info_56g.link_cnt.now || + bt1->link_info.link_cnt.now || + bt1->link_info_56g.link_cnt.now) + rpt_map |= bitmap; + else + rpt_map &= ~bitmap; + + bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_DEVICE_INFO); + if ((bt0->link_info.a2dp_desc.exist && + bt0->link_info.a2dp_desc.play_latency) || + (bt1->link_info.a2dp_desc.exist && + bt1->link_info.a2dp_desc.play_latency)) + rpt_map |= bitmap; + else + rpt_map &= ~bitmap; + + rtw89_btc_fw_en_rpt(rtwdev, false, rpt_map); +} + +static void _action_common(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *rinfo = &wl->role_info; + struct rtw89_btc_dm *dm = &btc->dm; + u8 i; + + _wl_req_mac(rtwdev, rinfo->pta_req_band); + _update_zb_coex_tbl(rtwdev); + _set_btg_ctrl(rtwdev); + _set_wl_preagc_ctrl(rtwdev); + _set_wl_tx_limit(rtwdev); + _set_phl_bt_slot_req(rtwdev); + _set_bt_afh_info(rtwdev); + _set_bt_rx_agc(rtwdev); + _set_rf_trx_para(rtwdev); + _set_bt_rx_scan_pri(rtwdev); + _set_fw_report_map(rtwdev); + + if (dm->run_reason == BTC_RSN_NTFY_INIT || + dm->run_reason == BTC_RSN_NTFY_RADIO_STATE || + dm->run_reason == BTC_RSN_NTFY_POWEROFF) + _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); + + for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++) + _sned_h2c_w2bscbd(rtwdev, false, i); + + if (btc->ver->fcxosi) { + if (memcmp(&dm->ost_info_last, &dm->ost_info, + sizeof(dm->ost_info_last)) || + dm->run_reason == BTC_RSN_NTFY_INIT || + dm->run_reason == BTC_RSN_NTFY_RADIO_STATE) { + dm->ost_info_last = dm->ost_info; + _fw_set_drv_info(rtwdev, CXDRVINFO_OSI); + } + } + dm->tdma_instant_excute = 0; + dm->lps_ctrl_change = false; + wl->role_info.link_mode_chg = 0; + wl->pta_reg_mac_chg = false; + dm->pre_agc_chg = false; + wl->dbcc_chg = 0; +} + +static void _action_by_bt(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_bt_leaudio_desc leaudio = bt_linfo->leaudio_desc; + struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; + struct rtw89_btc_dm *dm = &btc->dm; + u8 profile_map = 0; + + if (dm->freerun_chk) { + _action_freerun(rtwdev); + return; + } + + if (bt_linfo->hfp_desc.exist) + profile_map |= BTC_BT_HFP; + + if (bt_linfo->hid_desc.exist) + profile_map |= BTC_BT_HID; + + if (bt_linfo->a2dp_desc.exist) + profile_map |= BTC_BT_A2DP; + + if (bt_linfo->pan_desc.exist) + profile_map |= BTC_BT_PAN; + + if (leaudio.bis_exist) + profile_map |= BTC_BT_BIS; + + if (leaudio.cis_exist) + profile_map |= BTC_BT_CIS; + + switch (profile_map) { + case BTC_BT_NOPROFILE: + if (pan.active) + _action_bt_pan(rtwdev); + else + _action_bt_idle(rtwdev); + break; + case BTC_BT_HFP: + _action_bt_hfp(rtwdev); + break; + case BTC_BT_HFP | BTC_BT_HID: + case BTC_BT_HID: + _action_bt_hid(rtwdev); + break; + case BTC_BT_A2DP: + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else if (bt_linfo->multi_link.now && !hid.pair_cnt) + _action_bt_a2dp_pan(rtwdev); + else + _action_bt_a2dp(rtwdev); + break; + case BTC_BT_PAN: + _action_bt_pan(rtwdev); + break; + case BTC_BT_BIS: + _action_bt_bis(rtwdev); + break; + case BTC_BT_CIS: + case BTC_BT_CIS | BTC_BT_HID: + _action_bt_cis(rtwdev); + break; + case BTC_BT_A2DP | BTC_BT_HFP: + case BTC_BT_A2DP | BTC_BT_HID: + case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID: + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else if (pan.active) + _action_bt_a2dp_pan_hid(rtwdev); + else + _action_bt_a2dp_hid(rtwdev); + break; + case BTC_BT_A2DP | BTC_BT_PAN: + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else + _action_bt_a2dp_pan(rtwdev); + break; + case BTC_BT_PAN | BTC_BT_HFP: + case BTC_BT_PAN | BTC_BT_HID: + case BTC_BT_PAN | BTC_BT_HFP | BTC_BT_HID: + _action_bt_pan_hid(rtwdev); + break; + case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID: + case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP: + default: + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else + _action_bt_a2dp_pan_hid(rtwdev); + break; + } +} + +static void _action_wl_2g_sta(struct rtw89_dev *rtwdev) +{ + _action_by_bt(rtwdev); +} + +static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + u16 policy_type = BTC_CXP_OFF_BT; + + if (btc->ant_type == BTC_ANT_SHARED) { + if (btc->cx.wl.status.map._4way) + policy_type = BTC_CXP_OFFE_WL; + else if (btc->cx.wl.status.val & btc_scanning_map.val) + policy_type = BTC_CXP_OFFE_2GBWMIXB; + else if (btc->cx.bt0.link_info.status.map.connect == 0) + policy_type = BTC_CXP_OFFE_2GISOB; + else + policy_type = BTC_CXP_OFFE_2GBWISOB; + } else { /* dedicated-antenna */ + policy_type = BTC_CXP_OFF_EQ0; + } + + btc->dm.e2g_slot_limit = BTC_E2G_LIMIT_DEF; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G); + _set_policy(rtwdev, policy_type, BTC_ACT_WL_25G_MCC); +} + +static void _action_wl_scan(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; + + if (btc->cx.state_map != BTC_WLINKING && + btc->ctrl.wl_ctrl_info.fw_scan) { + _action_wl_25g_mcc(rtwdev); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n"); + } else if (rtwdev->dbcc_en) { + if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G && + wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) + _action_wl_5g(rtwdev); + else + _action_by_bt(rtwdev); + } else { + if (wl->scan_info.band[RTW89_PHY_0] != RTW89_BAND_2G) + _action_wl_5g(rtwdev); + else + _action_by_bt(rtwdev); + } +} + +static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev) +{ struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + if (btc->cx.bt0.link_info.link_cnt.now == 0) + _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, + BTC_ACT_WL_2G_MCC); + else + _set_policy(rtwdev, BTC_CXP_OFFE_DEF, + BTC_ACT_WL_2G_MCC); + } else { /* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_MCC); + } +} + +static void _action_wl_2g_scc(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + u16 policy_type; + + if (!dm->tdd_bind.bt_smap.connect) + policy_type = BTC_CXP_OFFE_2GISOB; + else + policy_type = BTC_CXP_OFFE_2GBWISOB; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_PTA); + _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); +} + +static void _action_wl_2g_ap(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { + if (btc->cx.bt0.link_info.link_cnt.now == 0) + _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, + BTC_ACT_WL_2G_AP); + else + _set_policy(rtwdev, BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_AP); + } else {/* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_AP); + } +} + +static void _action_wl_2g_go(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + if (btc->cx.bt0.link_info.link_cnt.now == 0) + _set_policy(rtwdev, + BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_GO); + else + _set_policy(rtwdev, + BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_GO); + } else { /* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GO); + } +} + +static void _action_wl_2g_gc(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + _action_by_bt(rtwdev); + } else {/* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GC); + } +} + +static void _action_wl_2g_nan(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + + if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ + if (btc->cx.bt0.link_info.link_cnt.now == 0) + _set_policy(rtwdev, + BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_NAN); + else + _set_policy(rtwdev, + BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_NAN); + } else { /* dedicated-antenna */ + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_NAN); + } +} + +static u8 _sned_h2c_w2bscbd(struct rtw89_dev *rtwdev, bool force_exec, u8 bid) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + u8 cnt_idx = BTC_WCNT_SCBDUPDATE; + u8 h2c_func = SET_IOFLD_SCBD; + u8 buf[4]; + + if (bid == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + return 0; + + h2c_func |= BT_H2C_FUNC_BT2ND; + cnt_idx = BTC_WCNT_SCBDUPDATE2; + } + + if (wl->scbd_chg[bid] || force_exec) { + /* Add delay to avoid BT FW loss information */ + + btc_dw2b(buf, 0, (wl->scbd[bid] | BIT(31))); /* trig */ + if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) { + if (!_send_fw_cmd(rtwdev, BTFC_SET, + h2c_func, buf, sizeof(buf))) + return 0; + } else { + rtw89_mac_cfg_sb(rtwdev, wl->scbd[bid]); + } + wl->scbd_chg[bid] = 0; + wl->wcnt[cnt_idx]++; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s() write BT%d scbd:0x%08x\n", + __func__, bid, wl->scbd[bid]); + } + return 1; +} + +static void _write_scbd(struct rtw89_dev *rtwdev, u8 bid, u32 val, bool state) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_dm *dm = &btc->dm; + u8 force_exec, id, id_start, id_stop; + u32 scbd = 0; + + if (!chip->scbd) + return; + + if (bid == BTC_ALL_BT) { + id_start = BTC_BT_1ST; + id_stop = BTC_BT_2ND; + } else { + id_start = bid; + id_stop = bid; + } + + for (id = id_start; id <= id_stop; id++) { + force_exec = false; + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) && + id == BTC_BT_2ND) + continue; + + if (state) + scbd = wl->scbd[id] | val; + else + scbd = wl->scbd[id] & (~val); + + if (val & BTC_WSCB_CTCODE || + val & BTC_WSCB_RXGAIN || + val & BTC_WSCB_RXGAIN_56G) { /* instant exec */ + force_exec = true; + wl->scbd[id] = scbd; + dm->scbd_write_instant = 1; + if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) + _sned_h2c_w2bscbd(rtwdev, force_exec, id); + else + rtw89_mac_cfg_sb(rtwdev, wl->scbd[id]); + dm->scbd_write_instant = 0; + } else if ((val & BTC_WSCB_ACTIVE || + val & BTC_WSCB_ON || + val & BTC_WSCB_WLRFK) || + scbd != wl->scbd[id]) { + /* + * Just update wl->scbd[] and set wl->scbd_chg[], + * moved "Write scoreboard I/O" to _action_common() + * _write_scbd will be executed if run_coex() + */ + wl->scbd[id] = scbd; + wl->scbd_chg[id] = 1; + } + } +} + +static u8 +_update_rssi_state(struct rtw89_dev *rtwdev, u8 pre_state, u8 rssi, u8 thresh) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 next_state, tol = chip->rssi_tol; + + if (pre_state == BTC_RSSI_ST_LOW || + pre_state == BTC_RSSI_ST_STAY_LOW) { + if (rssi >= (thresh + tol)) + next_state = BTC_RSSI_ST_HIGH; + else + next_state = BTC_RSSI_ST_STAY_LOW; + } else { + if (rssi < thresh) + next_state = BTC_RSSI_ST_LOW; + else + next_state = BTC_RSSI_ST_STAY_HIGH; + } + + return next_state; +} + +static +void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + btc->cx.wl.dbcc_info.real_band[phy_idx] = + btc->cx.wl.scan_info.phy_map & BIT(phy_idx) ? + btc->cx.wl.dbcc_info.scan_band[phy_idx] : + btc->cx.wl.dbcc_info.op_band[phy_idx]; +} + +#define BTC_CHK_HANG_MAX 3 +#define BTC_SCB_INV_VALUE GENMASK(31, 0) + +static u8 _get_role_link_mode(u8 role) +{ + switch (role) { + case RTW89_WIFI_ROLE_STATION: + default: + return BTC_WLINK_STA; + case RTW89_WIFI_ROLE_P2P_GO: + return BTC_WLINK_GO; + case RTW89_WIFI_ROLE_P2P_CLIENT: + return BTC_WLINK_GC; + case RTW89_WIFI_ROLE_AP: + return BTC_WLINK_AP; + } +} + +static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1, + const struct rtw89_btc_chdef *r2) +{ + if (r1->chan != r2->chan) { /* primary ch is different */ + return false; + } else if (r1->bw == RTW89_CHANNEL_WIDTH_40 && + r2->bw == RTW89_CHANNEL_WIDTH_40) { + if (r1->offset != r2->offset) + return false; + } + return true; +} + +static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch, + u8 *phy, u8 *role, u8 link_cnt) +{ + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; + struct rtw89_btc_wl_role_info *rinfo = &wl->role_info; + bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false; + u8 j, k, dbcc_2g_cid = 0, dbcc_2g_cid2 = 0; + + /* find out the 2G-PHY by connect-id ->ch */ + for (j = 0; j < link_cnt; j++) { + if (ch[j].center_ch <= 14) { + is_2g_ch_exist = true; + break; + } + } + + /* If no any 2G-port exist, it's impossible because 5G-exclude */ + if (!is_2g_ch_exist) + return BTC_WLINK_SB_MCC; + + dbcc_2g_cid = j; + rinfo->dbcc_2g_phy = phy[dbcc_2g_cid]; + + if (rinfo->dbcc_2g_phy == RTW89_PHY_1) + rinfo->pta_req_band = RTW89_PHY_1; + else + rinfo->pta_req_band = RTW89_PHY_0; + + /* connect_cnt <= 2 */ + if (link_cnt < BTC_TDMA_WLROLE_MAX) + return _get_role_link_mode(role[dbcc_2g_cid]); + + /* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */ + for (k = 0; k < link_cnt; k++) { + if (k == dbcc_2g_cid) + continue; + + if (phy[k] == rinfo->dbcc_2g_phy) { + is_multi_role_in_2g_phy = true; + dbcc_2g_cid2 = k; + break; + } + } + + /* Single-role in 2G-PHY */ + if (!is_multi_role_in_2g_phy) + return _get_role_link_mode(role[dbcc_2g_cid]); + + /* 2-role in 2G-PHY */ + if (ch[dbcc_2g_cid2].center_ch > 14) + return BTC_WLINK_DB_MCC; + else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2])) + return BTC_WLINK_SCC; + else + return BTC_WLINK_SB_MCC; +} + +static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info; + struct rtw89_btc_wl_role_info *r = &wl->role_info; + u8 p2p_exist = wl->role_info.p2p_exist; + + if (hw_band == RTW89_PHY_1) + p2p_exist = wl->role_info.p2p_exist_hb1; + + /* MLD: nLmR --> 2L1R: 2-Link by 1-RF, 2L2R: 2-link by 2-RF */ + switch (type) { + case RTW89_MR_WTYPE_NONE: /* no-link */ + r->link_mode = BTC_WLINK_NOLINK; + break; + case RTW89_MR_WTYPE_NONMLD: /* Non_MLO 1-role 2+0/0+2 */ + case RTW89_MR_WTYPE_MLD1L1R: /* MLO only-1 link 2+0/0+2 */ + if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) { + r->link_mode = BTC_WLINK_GO; + } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT && + p2p_exist) { + r->link_mode = BTC_WLINK_GC; + } else { + r->link_mode = BTC_WLINK_STA; + } + break; + case RTW89_MR_WTYPE_NONMLD_NONMLD: /* Non_MLO 2-role 2+0/0+2 */ + case RTW89_MR_WTYPE_MLD1L1R_NONMLD: /* MLO only-1 link + P2P 2+0/0+2 */ + if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_5GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_6GHZ) { + r->link_mode = BTC_WLINK_DB_MCC; + } else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_5GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_6GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_5GHZ_6GHZ) { + r->link_mode = BTC_WLINK_SB_MCC; + } else { + r->link_mode = BTC_WLINK_SCC; + } + break; + case RTW89_MR_WTYPE_MLD2L1R: /* MLO_MLSR 2+0/0+2 */ + if (p2p_exist) /* MLO_MLSR only support STA/GC */ + r->link_mode = BTC_WLINK_GC; + else + r->link_mode = BTC_WLINK_STA; + break; + case RTW89_MR_WTYPE_MLD2L1R_NONMLD: /* MLO_MLSR + P2P 2+0/0+2 */ + case RTW89_MR_WTYPE_MLD2L2R_NONMLD: /* MLO_MLMR + P2P 1+1/2+2*/ + /* driver may doze 1-link (1+1) or 2+0->0+2->1+1 + * 2G+5G -> TDMA slot switch by E2G/E5G + * 5G only -> TDMA slot switch by E5G + */ + r->link_mode = BTC_WLINK_DB_MCC; + break; + case RTW89_MR_WTYPE_MLD2L2R: /* MLO_MLMR 1+1/2+2 */ + /* MLMR only support STA now (2024) */ + r->link_mode = BTC_WLINK_STA; + break; + } +} + +static void _update_wl_mlo_info(struct rtw89_dev *rtwdev, u8 hw_band) +{ + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info; + struct rtw89_mr_chanctx_info qinfo; + struct rtw89_chanctx *ch; + u8 rf_band = RTW89_BAND_2G; + u8 i, type; + + /* parse MLO info form PHL API for each HW-band */ + for (i = RTW89_MAC_0; i <= RTW89_MAC_1; i++) { + memset(&qinfo, 0, sizeof(qinfo)); + + rtw89_query_mr_chanctx_info(rtwdev, i, &qinfo); + + switch (qinfo.ctxtype) { + default: + mlo_info->hwb_rf_band[i] = 0; + break; + case RTW89_MR_CTX1_2GHZ: + case RTW89_MR_CTX2_2GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G); + break; + case RTW89_MR_CTX1_5GHZ: + case RTW89_MR_CTX2_5GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_5G); + break; + case RTW89_MR_CTX1_6GHZ: + case RTW89_MR_CTX2_6GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_6G); + break; + case RTW89_MR_CTX2_2GHZ_5GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G) | + BIT(RTW89_BAND_5G); + break; + case RTW89_MR_CTX2_2GHZ_6GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G) | + BIT(RTW89_BAND_6G); + break; + case RTW89_MR_CTX2_5GHZ_6GHZ: + mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_5G) | + BIT(RTW89_BAND_6G); + break; + } + mlo_info->wmode[i] = qinfo.wmode; + mlo_info->ch_type[i] = qinfo.ctxtype; + mlo_info->wtype = qinfo.wtype; + wl->rf_band_map[i] = mlo_info->hwb_rf_band[i]; + ch = &rtwdev->hal.chanctx[i]; + wl->rf_ch_info[i].center_ch = ch->chan.channel; + wl->rf_ch_info[i].band = ch->chan.band_type; + wl->rf_ch_info[i].chan = ch->chan.channel; + wl->rf_ch_info[i].offset = ch->chan.pri_ch_idx; + wl->rf_ch_info[i].bw = ch->chan.band_width; + } + + mlo_info->link_status = rtwdev->mlo_dbcc_mode; + type = mlo_info->wtype; + + if (mlo_info->wtype == RTW89_MR_WTYPE_MLD1L1R || + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L1R || + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L2R || + mlo_info->wtype == RTW89_MR_WTYPE_MLD1L1R_NONMLD || + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD || + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L2R_NONMLD) + mlo_info->mlo_en = 1; + else + mlo_info->mlo_en = 0; + + if (mlo_info->ch_type[RTW89_MAC_0] != RTW89_MR_CTX_NONE && + mlo_info->ch_type[RTW89_MAC_0] != RTW89_MR_CTX_UNKNOWN && + mlo_info->ch_type[RTW89_MAC_1] != RTW89_MR_CTX_NONE && + mlo_info->ch_type[RTW89_MAC_1] != RTW89_MR_CTX_UNKNOWN) + mlo_info->dual_hw_band_en = 1; /* two HW-hand link exist */ + else + mlo_info->dual_hw_band_en = 0; + + if (mlo_info->link_status == MLO_2_PLUS_0_2RF || + mlo_info->link_status == MLO_0_PLUS_2_2RF || + mlo_info->link_status == MLO_2_PLUS_2_2RF) + mlo_info->mlo_adie = 2; + else + mlo_info->mlo_adie = 1; + + switch (mlo_info->link_status) { + default: + case MLO_2_PLUS_0_1RF: /* 2+0 */ + case MLO_2_PLUS_0_2RF: + _update_wl_link_mode(rtwdev, RTW89_MAC_0, type); + wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode; + wl_rinfo->pta_req_band = RTW89_MAC_0; + wl_rinfo->dbcc_2g_phy = RTW89_PHY_0; + wl_rinfo->dbcc_en = 0; + + rf_band = wl->rf_band_map[RTW89_PHY_0]; + mlo_info->path_rf_band[BTC_RF_S0] = rf_band; + mlo_info->path_rf_band[BTC_RF_S1] = rf_band; + break; + case MLO_0_PLUS_2_1RF: /* 0+2 */ + case MLO_0_PLUS_2_2RF: + _update_wl_link_mode(rtwdev, RTW89_MAC_1, type); + wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode; + wl_rinfo->pta_req_band = RTW89_MAC_1; + wl_rinfo->dbcc_2g_phy = RTW89_PHY_1; + wl_rinfo->dbcc_en = 0; + + rf_band = wl->rf_band_map[RTW89_PHY_1]; + mlo_info->path_rf_band[BTC_RF_S0] = rf_band; + mlo_info->path_rf_band[BTC_RF_S1] = rf_band; + break; + case MLO_1_PLUS_1_1RF: /* 1+1 */ + case MLO_1_PLUS_1_2RF: /* 1+1 */ + case MLO_2_PLUS_2_2RF: /* 2+2 */ + case DBCC_LEGACY: /* DBCC 1+1 */ + /* Check ch count from ch_type and modify type*/ + if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_2GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_5GHZ || + mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_6GHZ) + type = RTW89_MR_WTYPE_NONMLD; /* only 1-role */ + else + type = RTW89_MR_WTYPE_NONMLD_NONMLD; + + rf_band = wl->rf_band_map[hw_band]; + _update_wl_link_mode(rtwdev, hw_band, type); + + if (hw_band == RTW89_MAC_0) { + mlo_info->path_rf_band[BTC_RF_S0] = rf_band; + } else { + wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode; + mlo_info->path_rf_band[BTC_RF_S1] = rf_band; + } + + /* set pta_req_band for 1-PTA architecture */ + if (wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G)) { + wl_rinfo->pta_req_band = RTW89_MAC_0; + wl_rinfo->dbcc_2g_phy = RTW89_PHY_0; + } else if (wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G)) { + wl_rinfo->pta_req_band = RTW89_MAC_1; + wl_rinfo->dbcc_2g_phy = RTW89_PHY_1; + } else { /* Both HW-BAND are not on 2.4G*/ + wl_rinfo->pta_req_band = RTW89_MAC_0; + wl_rinfo->dbcc_2g_phy = RTW89_PHY_0; + } + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(), mode=%s, pta_band=%d", + __func__, id_to_linkmode(wl_rinfo->link_mode), + wl_rinfo->pta_req_band); +} + +static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; + struct rtw89_btc_wl_rlink *rlink = NULL; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; + u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; + u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; + bool b2g = false, b5g = false, outloop = false; + u8 mode = BTC_WLINK_NOLINK; + u8 cnt_2g = 0, cnt_5g = 0; + u8 i, j, cnt = 0; + + for (j = RTW89_PHY_0; j < RTW89_PHY_NUM; j++) { + wl->rf_band_map[j] = 0; /* j=link id, is the link use which band */ + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { + rlink = &wl_rinfo->rlink[i][j]; + + if (!rlink->active || !rlink->connected) + continue; + + if (cnt >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER) { + outloop = true; + break; + } + + cid_ch[cnt] = wl->rlink_info[i][j].chdef; + cid_phy[cnt] = rlink->phy; + cid_role[cnt] = rlink->role; + cnt++; + + if (rlink->rf_band != RTW89_BAND_2G) { + cnt_5g++; + b5g = true; + } else { + cnt_2g++; + b2g = true; + } + wl->rf_band_map[j] |= BIT(rlink->rf_band); + } + if (outloop) + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): cnt_2g=%d, cnt_5g=%d\n", __func__, cnt_2g, cnt_5g); + + wl_rinfo->pta_req_band = RTW89_PHY_0; /* no 0+2 for non-MLO */ + wl_rinfo->dbcc_en = rtwdev->dbcc_en; + + /* Be careful to change the following sequence!! */ + if (cnt == 0) { + mode = BTC_WLINK_NOLINK; + } else if (wl_rinfo->dbcc_en) { + /* update pta_req_band to 2.4GHz HW-BAND for DBCC = 1*/ + mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt); + } else if (!b2g && b5g) { + mode = _get_role_link_mode(cid_role[0]); + } else if (b2g && b5g) { + mode = BTC_WLINK_DB_MCC; + } else if (cnt >= 2) { + if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1])) + mode = BTC_WLINK_SCC; + else + mode = BTC_WLINK_SB_MCC; + } else { + mode = _get_role_link_mode(cid_role[0]); + } + + wl_rinfo->link_mode = mode; + wl_rinfo->link_mode_hb1 = mode; +} + +static void _sync_wl_link_mode_v0(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; + bool has_2g = false; + int i, j; + + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER && !has_2g; i++) + for (j = 0; j < RTW89_MAC_NUM && !has_2g; j++) + if (r->rlink[i][j].connected && + r->rlink[i][j].rf_band == RTW89_BAND_2G) + has_2g = true; + + if (!has_2g && r->link_mode != BTC_WLINK_NOLINK) { + r->link_mode_v0 = BTC_WLINK_V0_5G; + return; + } + + switch (r->link_mode) { + case BTC_WLINK_NOLINK: + r->link_mode_v0 = BTC_WLINK_V0_NOLINK; + break; + case BTC_WLINK_STA: + r->link_mode_v0 = BTC_WLINK_V0_2G_STA; + break; + case BTC_WLINK_AP: + r->link_mode_v0 = BTC_WLINK_V0_2G_AP; + break; + case BTC_WLINK_GO: + r->link_mode_v0 = BTC_WLINK_V0_2G_GO; + break; + case BTC_WLINK_GC: + r->link_mode_v0 = BTC_WLINK_V0_2G_GC; + break; + case BTC_WLINK_SCC: + r->link_mode_v0 = BTC_WLINK_V0_2G_SCC; + break; + case BTC_WLINK_SB_MCC: + r->link_mode_v0 = BTC_WLINK_V0_2G_MCC; + break; + case BTC_WLINK_DB_MCC: + r->link_mode_v0 = BTC_WLINK_V0_25G_MCC; + break; + default: + r->link_mode_v0 = BTC_WLINK_V0_OTHER; + break; + } +} + +static void _modify_role_link_mode(struct rtw89_dev *rtwdev, u8 hw_band) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + u8 go_cleint_exist = wl->go_client_exist; + u8 *link_mode = &wl_rinfo->link_mode; + u32 role_map = wl_rinfo->role_map; + u8 noa_exist = wl->noa_exist; + u32 mrole = BTC_WLMROLE_NONE; + + if (hw_band == RTW89_PHY_1) { + *link_mode = wl_rinfo->link_mode_hb1; + role_map = wl_rinfo->role_map_hb1; + go_cleint_exist = wl->go_client_exist_hb1; + } + + /* if no client_joined, don't care P2P-GO/AP role */ + if (((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) || + (role_map & BIT(RTW89_WIFI_ROLE_AP))) && !go_cleint_exist) { + if (*link_mode == BTC_WLINK_SCC) { + *link_mode = BTC_WLINK_STA; + } else if (*link_mode == BTC_WLINK_GO || + *link_mode == BTC_WLINK_AP) { + *link_mode = BTC_WLINK_NOLINK; + } + } + + /* Identify 2-Role type */ + if (*link_mode == BTC_WLINK_SCC || + *link_mode == BTC_WLINK_SB_MCC || + *link_mode == BTC_WLINK_DB_MCC) { + if ((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) || + (role_map & BIT(RTW89_WIFI_ROLE_AP))) { + if (noa_exist) + mrole = BTC_WLMROLE_STA_GO_NOA; + else + mrole = BTC_WLMROLE_STA_GO; + } else if (role_map & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)) { + if (noa_exist) + mrole = BTC_WLMROLE_STA_GC_NOA; + else + mrole = BTC_WLMROLE_STA_GC; + } else { + mrole = BTC_WLMROLE_STA_STA; + } + + if (hw_band == RTW89_PHY_0) { + wl_rinfo->mrole_type &= GENMASK(31, 16); /* clear Low-Word */ + wl_rinfo->mrole_type |= mrole; + } else { + wl_rinfo->mrole_type &= GENMASK(15, 0); /* clear high-Word */ + wl_rinfo->mrole_type |= (mrole << 16); + } + } else { + wl_rinfo->mrole_type = BTC_WLMROLE_NONE; + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): link_mode=%s, mrole_type=%d\n", __func__, + id_to_linkmode(wl_rinfo->link_mode), wl_rinfo->mrole_type); +} + +static void _update_wl_info(struct rtw89_dev *rtwdev, struct rtw89_btc_wl_link_info *wl_linfo) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_rlink *rlink = NULL; + u8 dbcc_en_ori, is_5g_hi_ch = 0, bg_mode = 0, p2p_exist = 0; + u8 go_client_exist = 0, noa_exist = 0; + u8 rlink_id = wl_linfo->phy; + u8 role_id = wl_linfo->pid; + u8 i, link_mode_ori; + u32 role_map = 0; + + if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id >= RTW89_BAND_NUM) + return; + + /* + * Extract wl->link_info[role_id][rlink_id] to wl->role_info + * role_id: role index + * rlink_id: rlink index (= HW-band index) + * pid: port_index + */ + rlink = &wl_rinfo->rlink[role_id][rlink_id]; + + rlink->role = wl_linfo->role; + rlink->active = wl_linfo->active; /* Doze or not */ + rlink->pid = wl_linfo->pid; + rlink->mac_id = wl_linfo->mac_id; + rlink->phy = wl_linfo->phy; + rlink->rf_band = wl_linfo->chdef.band; + rlink->ch = wl_linfo->chdef.center_ch; + rlink->bw = wl_linfo->chdef.bw; + rlink->noa = wl_linfo->noa; + rlink->noa_dur = wl_linfo->noa_duration / 1000; + rlink->client_cnt = wl_linfo->client_cnt; + rlink->mode = wl_linfo->mode; + + /* check if rlink connect? */ + switch (wl_linfo->connected) { + case MLME_NO_LINK: + rlink->connected = 0; + break; + case MLME_LINKED: + rlink->connected = 1; + + /* reset special-AP flag if station mode linked */ + dm->leak_ap = 0; + break; + default: + return; + } + + /* update by HW-Band */ + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { /* i = role_id */ + rlink = &wl_rinfo->rlink[i][rlink_id]; + + if (!rlink->active || !rlink->connected) + continue; + + role_map |= BIT(rlink->role); + + /* Identify if P2P-Go (GO/GC/AP) exist at 2GHz band */ + if (((rlink->role == RTW89_WIFI_ROLE_P2P_GO || + rlink->role == RTW89_WIFI_ROLE_AP) && + rlink->client_cnt > 1)) { + p2p_exist = 1; + go_client_exist = 1; + } + + if (rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT) + p2p_exist = 1; + + /* only one noa-role exist */ + if (rlink->noa && rlink->noa_dur > 0) + noa_exist = 1; + + /* for WL 5G-Rx interfered with BT issue */ + if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100) + is_5g_hi_ch = 1; + + if ((rlink->mode & BIT(BTC_WL_MODE_11B)) || + (rlink->mode & BIT(BTC_WL_MODE_11G))) + bg_mode = 1; + } + + if (rlink_id == RTW89_PHY_0) { + link_mode_ori = wl_rinfo->link_mode; + wl->is_5g_hi_ch = is_5g_hi_ch; + wl->bg_mode = bg_mode; + wl->go_client_exist = go_client_exist; + wl->noa_exist = noa_exist; + wl_rinfo->p2p_exist = p2p_exist; + wl_rinfo->role_map = role_map; + } else { + link_mode_ori = wl_rinfo->link_mode_hb1; + wl->is_5g_hi_ch_hb1 = is_5g_hi_ch; + wl->bg_mode_hb1 = bg_mode; + wl->go_client_exist_hb1 = go_client_exist; + wl->noa_exist_hb1 = noa_exist; + wl_rinfo->p2p_exist_hb1 = p2p_exist; + wl_rinfo->role_map_hb1 = role_map; + } + + dbcc_en_ori = wl_rinfo->dbcc_en; + + /* for MLO-supported, link-mode from driver directly */ + if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) { + _update_wl_mlo_info(rtwdev, rlink_id); + } else { /* for non-MLO-supported, link-mode by BTC */ + _update_wl_non_mlo_info(rtwdev); + } + + _modify_role_link_mode(rtwdev, rlink_id); + _sync_wl_link_mode_v0(rtwdev); + + if ((rlink_id == RTW89_PHY_0 && wl_rinfo->link_mode != link_mode_ori) || + (rlink_id == RTW89_PHY_1 && wl_rinfo->link_mode_hb1 != link_mode_ori)) { + wl_rinfo->link_mode_chg = 1; + wl->link_mode_chg = 1; + } + + if (wl_rinfo->dbcc_en != dbcc_en_ori) { + wl->dbcc_chg = 1; + wl->role_info.dbcc_chg = 1; + wl->wcnt[BTC_WCNT_DBCC_CHG]++; + } +} + +void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + coex_act1_work.work); + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + + lockdep_assert_wiphy(wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); + dm->cnt_notify[BTC_NCNT_TIMER]++; + if (wl->status.map.handshake || + wl->status.map._4way || + wl->status.map.dhcp) { + wl->status.map._4way = 0; + wl->status.map.dhcp = 0; + wl->status.map.handshake = 0; + } + _run_coex(rtwdev, BTC_RSN_ACT1_WORK); +} + +void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + coex_bt_devinfo_work.work); + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + + lockdep_assert_wiphy(wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); + dm->cnt_notify[BTC_NCNT_TIMER]++; + a2dp->play_latency = 0; + _run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK); +} + +void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + coex_rfk_chk_work.work); + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + + lockdep_assert_wiphy(wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); + dm->cnt_notify[BTC_NCNT_TIMER]++; + if (wl->rfk_info.state != BTC_WRFK_STOP) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): RFK timeout\n", __func__); + wl->wcnt[BTC_WCNT_RFK_TIMEOUT]++; + dm->error.map.wl_rfk_timeout = true; + wl->rfk_info.state = BTC_WRFK_STOP; + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, false); + _run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK); + } +} + +static void _update_bt_ctrl_lps(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0; + struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1; + struct rtw89_btc_dm *dm = &btc->dm; + bool lps_ctrl = false; + + if (dm->out_of_band || dm->freerun) + lps_ctrl = false; + else if (bt0->whql_test || bt1->whql_test) + lps_ctrl = true; + else if (bt0->link_info.a2dp_desc.exist || + bt0->link_info.hfp_desc.exist || + bt0->link_info.pan_desc.exist) + lps_ctrl = true; + else if (bt1->link_info.a2dp_desc.exist || + bt1->link_info.hfp_desc.exist || + bt1->link_info.pan_desc.exist) + lps_ctrl = true; + + if (dm->lps_ctrl_scbd != lps_ctrl) { + dm->lps_ctrl_scbd = lps_ctrl; + dm->lps_ctrl_change = true; + } else { + dm->lps_ctrl_change = false; + } +} + +static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid) +{ + struct rtw89_btc_bt_link_info *bt_2g, *bt_56g; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_bt_info *bt; + u32 val, any_bt_connect, any_bt_6g_connect = 0; + bool bt_link_change = false; + u8 id, id_start, id_stop; + + if (!rtwdev->chip->scbd || bid > BTC_ALL_BT) + return; + + if (bid == BTC_ALL_BT) { + id_start = BTC_BT_1ST; + id_stop = BTC_BT_2ND; + } else { + id_start = bid; + id_stop = bid; + } + + dm->lps_ctrl_change = false; + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s()\n", __func__); + + for (id = id_start; id <= id_stop; id++) { + bt = (id == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1; + bt_2g = &bt->link_info; + bt_56g = &bt->link_info_56g; + + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) && id == BTC_BT_2ND) + break; + + val = bt->scbd_c2h; + + if (val == 0xffffffff) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s return by invalid scbd value\n", + __func__); + return; + } + + if (!(val & BTC_BSCB_ON)) + bt->enable.now = 0; + else + bt->enable.now = 1; + + if (bt->enable.now != bt->enable.last) + bt_link_change = true; + + /* reset bt info if bt re-enable */ + if (bt->enable.now && !bt->enable.last) { + if (id == BTC_BT_1ST) + _reset_btc_var(rtwdev, BTC_RESET_BTINFO); + else + _reset_btc_var(rtwdev, BTC_RESET_BTINFO2); + + bt->bcnt[BTC_BCNT_REENABLE]++; + bt->enable.now = 1; + bt->rf_band_map = BIT(RTW89_BAND_2G); + bt->link_weight[BTC_BT_B2G] = 5; /* no-profile */ + } + bt->enable.last = bt->enable.now; + + /* if BT will disconnect and adopt protect plan */ + if ((val & BTC_BSCB_BT_PROTECT) && + !(bt->scbd & BTC_BSCB_BT_PROTECT)) + bt->bcnt[BTC_BCNT_PROTECT]++; + + bt->mbx_avl = !!(val & BTC_BSCB_ACT); + if (bt->whql_test != !!(val & BTC_BSCB_WHQL)) + bt_link_change = true; + + bt->whql_test = !!(val & BTC_BSCB_WHQL); + bt->btg_type = (val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE); + + bt_2g->a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT); + bt_2g->pan_desc.exist = !!(val & BTC_BSCB_PAN_ACT); + bt_2g->hfp_desc.exist = !!(val & BTC_BSCB_HFP_ACT); + + bt->lna_constrain = 4 + !!(val & BTC_BSCB_BT_LNAB0) + + !!(val & BTC_BSCB_BT_LNAB1) * 2; + + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) { + if (val & BTC_BSCB_BT_15DOT4) + bt->func_type |= (BTC_BTF_THREAD | BTC_BTF_ZB); + else + bt->func_type &= ~(BTC_BTF_THREAD | BTC_BTF_ZB); + } + + bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA); + any_bt_connect = !!(val & BTC_BSCB_BT_CONNECT); + + /* if connect change */ + if (bt_2g->status.map.connect != any_bt_connect || + bt_56g->status.map.connect != any_bt_6g_connect) { + bt_link_change = true; + bt_2g->status.map.connect = any_bt_connect; + bt_56g->status.map.connect = any_bt_6g_connect; + } + + bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE); + bt->scbd = val; + } + + _update_bt_ctrl_lps(rtwdev); + + if (bt_link_change) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s: bt status change!!\n", __func__); + /* TODO: Need to notify driver to update EXT-CTRL-BT-SLOT */ + } +} + +static void _update_bt_link_cnt(struct rtw89_dev *rtwdev, + struct rtw89_btc_bt_info *bt, bool b56g) +{ + struct rtw89_btc_bt_link_info *b = b56g ? &bt->link_info_56g : + &bt->link_info; + struct rtw89_btc_bt_leaudio_desc *leaudio = &b->leaudio_desc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &b->a2dp_desc; + struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; + struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; + struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc; + u8 bt_rf_band = b56g ? BTC_BT_B5G : BTC_BT_B2G; + u8 val; + + b->link_cnt.last = b->link_cnt.now; + b->link_cnt.now = 0; + b->link_cnt.chg = 0; + + b->link_cnt.now += hfp->exist; + b->link_cnt.now += hid->exist; + b->link_cnt.now += a2dp->exist; + b->link_cnt.now += pan->exist; + b->link_cnt.now += leaudio->bis_exist; + b->link_cnt.now += leaudio->cis_exist; + + if (leaudio->bis_exist || a2dp->sink) { + val = 70; + } else if (a2dp->exist) { + val = 40; + if (a2dp->vendor_id == 0x4c) + val += 10; + if (hid->exist) + val += 10; + } else if (pan->exist || pan->active || a2dp->active || + b->status.map.inq_pag) { + val = 30; + } else if (b->link_cnt.now == 0) { + val = 5; + } else { + val = 9; + } + bt->link_weight[bt_rf_band] = val; + + if (b->link_cnt.last != b->link_cnt.now) + b->link_cnt.chg = 1; +} + +static void _update_bt_leaudio_info(struct rtw89_dev *rtwdev, u8 bid, + void *buf, u32 len) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt = (bid == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + struct rtw89_btc_bt_leaudio_info *src = buf; + struct rtw89_btc_bt_leaudio_desc *leaudio; + bool bt_56g = false, cis_exist, bis_exist; + u8 bis_cnt, cis_cnt; + + if ((src->len & BIT(7)) && bt->band_56G_support) { + b = &bt->link_info_56g; + bt_56g = true; + } + + leaudio = &b->leaudio_desc; + + if (!memcmp(b->leaudio_raw_info, src, BTC_BTINFO_MAX)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s return by leaudio-info duplicate!\n", + __func__); + bt->bcnt[BTC_BCNT_LEAUDIO_INFOSAME]++; + return; + } + + memcpy(b->leaudio_raw_info, src, BTC_BTINFO_MAX); + + bis_exist = u8_get_bits(src->bis_cis, RTW89_BTC_LEAU_INFO_L2_BIS_EX); + cis_exist = u8_get_bits(src->bis_cis, RTW89_BTC_LEAU_INFO_L2_CIS_EX); + bis_cnt = u8_get_bits(src->bis_cis, RTW89_BTC_LEAU_INFO_L2_BIS_CNT); + cis_cnt = u8_get_bits(src->bis_cis, RTW89_BTC_LEAU_INFO_L2_CIS_CNT); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s: bis_exist:%d bis_cnt:%d cis_exist:%d cis_cnt:%d rssi:%d\n", + __func__, bis_exist, bis_cnt, cis_exist, cis_cnt, src->rssi); + + if (!bis_exist && !cis_exist) + memset(leaudio, 0, sizeof(*leaudio)); + + leaudio->bis_cnt = bis_cnt; + leaudio->bis_exist = bis_exist; + leaudio->cis_cnt = cis_cnt; + leaudio->cis_exist = cis_exist; + + if (leaudio->bis_exist) + b->status.map.profile_map |= BTC_BT_BIS; + else + b->status.map.profile_map &= ~BTC_BT_BIS; + + if (leaudio->cis_exist) + b->status.map.profile_map |= BTC_BT_CIS; + else + b->status.map.profile_map &= ~BTC_BT_CIS; + + _update_bt_link_cnt(rtwdev, bt, bt_56g); + + leaudio->rssi = chip->ops->btc_get_bt_rssi(rtwdev, src->rssi); + + leaudio->bis_cnt_last = leaudio->bis_cnt; + leaudio->bis_exist_last = leaudio->bis_exist; + leaudio->cis_cnt_last = leaudio->cis_cnt; + leaudio->cis_exist_last = leaudio->cis_exist; +} + +static void _update_bt_bistdma_info(struct rtw89_dev *rtwdev, u8 bid, + void *buf, u32 len) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_bt_info *bt = (bid == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + struct rtw89_btc_bt_bistdma_info_le *src = buf; + struct rtw89_btc_bt_leaudio_desc *leaudio; + + if ((src->len & BIT(7)) && bt->band_56G_support) + b = &bt->link_info_56g; + + leaudio = &b->leaudio_desc; + + if (!memcmp(b->bistdma_raw_info, src, BTC_BTINFO_MAX)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s return by bistdma-info duplicate!\n", + __func__); + bt->bcnt[BTC_BCNT_LEAUDIO_INFOSAME]++; + return; + } + + memcpy(b->bistdma_raw_info, src, BTC_BTINFO_MAX); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s: bis_start_end:%d bis_trx:%d\n", + __func__, + u8_get_bits(src->bis, RTW89_BTC_BIS_INFO_L2_START_END), + u8_get_bits(src->bis, RTW89_BTC_BIS_INFO_L2_TRX)); + + leaudio->bis_trx = u8_get_bits(src->bis, RTW89_BTC_BIS_INFO_L2_TRX); + leaudio->bis_start_end = u8_get_bits(src->bis, + RTW89_BTC_BIS_INFO_L2_START_END); + + leaudio->diff_t = (src->diff_t_hb * 256 + src->diff_t_lb) * 625 / 1000; + + if (btc->ant_type == BTC_ANT_SHARED && leaudio->diff_t > 13) + dm->bis_tdma = true; + else + dm->bis_tdma = false; +} + +#define BTC_BTINFO_PWR_LEN 5 +static void _update_bt_txpwr_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) +{ + struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + + if (len != BTC_BTINFO_PWR_LEN) + return; + + if (!memcmp(bt->txpwr_info, buf, sizeof(bt->txpwr_info))) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s return by info duplicate!\n", __func__); + return; + } + + memcpy(bt->txpwr_info, buf, BTC_BTINFO_MAX); + memcpy(&b->bt_txpwr_desc, &buf[2], sizeof(b->bt_txpwr_desc)); +} + +static void _set_bind_info(struct rtw89_btc *btc, u8 type) +{ + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt0; + struct rtw89_btc_bt_link_info *b; + struct rtw89_btc_bind_info *bd; + u8 path_hwb[BTC_RF_NUM] = {RTW89_PHY_0, RTW89_PHY_1}; + u8 link_weight[BTC_ALL_BT_EZL][BTC_BT_BMAX]; + u8 map[BTC_RF_NUM][BTC_ALL_BT_EZL]; + u8 b2g_score = 0, b5g_score = 0; + u8 i, j, rf_band_map, thres; + u8 weight[BTC_BT_BMAX] = {}; + + if (type == BTC_MECH_TDD) { + bd = &dm->tdd_bind; + memcpy(map, dm->tdd_map, sizeof(map)); + thres = 30; /* BT profile score threshold for TDMA */ + } else { + bd = &dm->fdd_bind; + memcpy(map, dm->fdd_map, sizeof(map)); + thres = 5; + } + + memset(bd, 0, sizeof(*bd)); + /* compare BT 2GHz/5GHz profile by link-weighting */ + for (i = 0; i < BTC_BT_BMAX; i++) { + if (!cx->bt0.enable.now) + cx->bt0.link_weight[i] = 0; + if (!cx->bt1.enable.now) + cx->bt1.link_weight[i] = 0; + link_weight[BTC_BT_1ST][i] = cx->bt0.link_weight[i]; + link_weight[BTC_BT_2ND][i] = cx->bt1.link_weight[i]; + link_weight[BTC_BT_EXT][i] = cx->bt_ext.link_weight[i]; + } + + /* + * get 2GHz/5GHz link weight score by "band-overlap" map + * link_weight from _update_bt_link_cnt(), + * if link_weight >30 --> TDMA-required + */ + for (j = 0; j < BTC_ALL_BT_EZL; j++) { + rf_band_map = map[BTC_RF_S0][j] | map[BTC_RF_S1][j]; + if (rf_band_map & BIT(RTW89_BAND_2G)) + b2g_score += link_weight[j][BTC_BT_B2G]; + if (rf_band_map & BIT(RTW89_BAND_5G)) + b5g_score += link_weight[j][BTC_BT_B5G]; + } + + /* rf-band bound by comparing link weight */ + if (b2g_score == 0 && b5g_score == 0) /* no-rf-band overlap */ + bd->rf_band = 0; + else if (b5g_score > b2g_score) + bd->rf_band = BIT(BTC_BT_B5G); + else + bd->rf_band = BIT(BTC_BT_B2G); + + /* + * if MR_WTYPE_MLD2L1R_NONMLD, FW will change 2+0/0+2/1+1 + * Therefore, BTC_MLO_RF_xxx is not real-time state. + * In this case, RF_S0->HWB0, RF_S1->HWB1 + * If link-mode change by _ntfy_generic(BTC_GNTFY_MRCX_INFO) + * HW-Band is decided by wl->mlo_info.mrcx_act_hwb_map + */ + if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD) { + if (wl->role_info.link_mode != BTC_WLINK_DB_MCC) { /* mode chg */ + if (wl->mlo_info.mrcx_act_hwb_map == BIT(RTW89_MAC_1)) + path_hwb[BTC_RF_S0] = RTW89_PHY_1; /* S0/1->HWB1 */ + else + path_hwb[BTC_RF_S1] = RTW89_PHY_0; /* S0/1->HWB0 */ + } + } else { + /* + * Dual-RF_band(HWB)TDMA if BT-profile is TDMA-type at both + * 2GHz and 5GHz. + * ex: 1+1: HWB0 5GHz + BT0 5GHz (BIS, HDT) + * && HWB1 2.4GHz + BT1 2.4GHz(PAN) + * for TDD: the link score must > 30 (from _bt_link_cnt) + * for FDD: the link score must > 5 (bt enable) + */ + if ((wl->mlo_info.rf_combination == BTC_MLO_RF_1_PLUS_1 || + wl->mlo_info.rf_combination == BTC_MLO_RF_2_PLUS_2) && + (b2g_score >= thres && b5g_score >= thres)) { + bd->rf_band = BIT(BTC_BT_B2G) | BIT(BTC_BT_B5G); + } + + if (wl->mlo_info.rf_combination == BTC_MLO_RF_2_PLUS_0) + path_hwb[BTC_RF_S1] = RTW89_PHY_0; /* 2+0 RF-S0/1->HWB0 */ + else if (wl->mlo_info.rf_combination == BTC_MLO_RF_0_PLUS_2) + path_hwb[BTC_RF_S0] = RTW89_PHY_1; /* 2+0 RF-S0/1->HWB1 */ + } + + /* Get HWB-sel and BT-sel by rf-band-binding */ + for (i = 0; i < BTC_RF_NUM; i++) { + for (j = 0; j < BTC_ALL_BT_EZL; j++) { + if (!(map[i][j] & bd->rf_band)) /* no-overlap */ + continue; + + bd->wl_hwb_sel |= BIT(path_hwb[i]); + bd->bt_sel |= BIT(j); + } + } + + if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L2R && + (bd->wl_hwb_sel == (BIT(RTW89_MAC_1) | BIT(RTW89_MAC_0)))) { + if (wl->role_info.link_mode == BTC_WLINK_AP || + wl->role_info.link_mode_hb1 == BTC_WLINK_AP) + bd->wl_link_mode = BTC_WLINK_DB_MCC; + else + bd->wl_link_mode = BTC_WLINK_STA; + bd->wl_bg_mode = wl->bg_mode | wl->bg_mode_hb1; + } else if (bd->wl_hwb_sel == (BIT(RTW89_MAC_1))) { + bd->wl_link_mode = wl->role_info.link_mode_hb1; + bd->wl_bg_mode = wl->bg_mode_hb1; + } else {/* HW-BAND-0 or no-hw-band */ + bd->wl_hwb_sel = BIT(RTW89_MAC_0); + bd->wl_link_mode = wl->role_info.link_mode; + bd->wl_bg_mode = wl->bg_mode; + } + + /* update Bind-BT status map for BT0/BT1 */ + for (i = BTC_BT_1ST; i < BTC_ALL_BT_EZL; i++) { + if (!(bd->bt_sel & BIT(i))) + continue; + + for (j = BTC_BT_B2G; j <= BTC_BT_B5G; j++) { + if (!(bd->rf_band & BIT(j))) + continue; + + if (i == BTC_BT_EXT) { + bd->bt_profile |= cx->bt_ext.profile_map[j]; + weight[j] = cx->bt_ext.link_weight[j]; + if (weight[j] > bd->bt_link_weight) /* max */ + bd->bt_link_weight = weight[j]; + continue; + } else if (i == BTC_BT_1ST) { + bt = &cx->bt0; + } else { + bt = &cx->bt1; + } + + if (j == BTC_BT_B2G) + b = &bt->link_info; + else + b = &bt->link_info_56g; + + bd->bt_profile |= b->status.map.profile_map; + bd->bt_smap.a2dp_active |= b->a2dp_desc.active; + bd->bt_smap.a2dp_sink |= b->a2dp_desc.sink; + bd->bt_smap.pan_active |= b->pan_desc.active; + bd->bt_smap.connect |= b->status.map.connect; + bd->bt_smap.hid_cnt += b->hid_desc.pair_cnt; + bd->bt_smap.hid_type |= b->hid_desc.type; + bd->bt_smap.cis_cnt += b->leaudio_desc.cis_cnt; + bd->bt_smap.link_cnt += b->link_cnt.now; + bd->bt_smap.inq_page |= b->status.map.inq_pag; + bd->bt_smap.page |= b->pag; + + if (bt->link_weight[j] > bd->bt_link_weight) /* max */ + bd->bt_link_weight = bt->link_weight[j]; + + if (b->slave_role) + bd->bt_smap.slave_role = b->slave_role; + + if (b->a2dp_desc.vendor_id != 0) + bd->bt_smap.a2dp_vendor_id = + b->a2dp_desc.vendor_id; + } + } + + if (bd->bt_profile & BTC_BT_HFP) + bd->bt_smap.hfp_exist = 1; + if (bd->bt_profile & BTC_BT_HID) + bd->bt_smap.hid_exist = 1; + if (bd->bt_profile & BTC_BT_A2DP) + bd->bt_smap.a2dp_exist = 1; + if (bd->bt_profile & BTC_BT_PAN) + bd->bt_smap.pan_exist = 1; + if (bd->bt_profile & BTC_BT_BIS) + bd->bt_smap.bis_exist = 1; + if (bd->bt_profile & BTC_BT_CIS) + bd->bt_smap.cis_exist = 1; + if (bd->bt_profile & BTC_BT_THREAD) + bd->bt_smap.thread_exist = 1; + if (bd->bt_profile & BTC_BT_ULL) + bd->bt_smap.ull_exist = 1; +} + +#define _bind_is_btonly 0x7 +static void _set_coex_binding(struct rtw89_btc *btc) +{ + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_extsoc_info *bt2 = &cx->bt_ext; + struct rtw89_btc_bt_info *bt0 = &cx->bt0; + struct rtw89_btc_bt_info *bt1 = &cx->bt1; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_dm *dm = &btc->dm; + u8 path_hwb[BTC_RF_NUM] = {RTW89_PHY_0, RTW89_PHY_1}; + u8 wl_rf_band[RTW89_BAND_NUM] = {}; + u8 i, j, val = 0; + + /* + * sit_xmap(Space-Interaction) = ant_xmap | xtk_xmap + * 1: WL-BT space-interference, always 1 if BTG/BTA/SPDT = 1 + * if dedicated-ant, it may be 1 if BT-Tx is bigger than WL-Rx(xtk_xmap) + * + * ant_xmap(ANT-Division-Multiplexing) + * ==> dedicated-ant->0, BTG/BTA/SPDT->1 + * + * xtk_xmap(Cross-talk map)-> calculate WL/BT interference by SIR + * ==> 1: interference, 0: no-interference + * + * fdm_map(Frequency-Division-Multiplexing): WL/BT RF_Band overlap-map + * 2bit-map: bit[1]:5/6GHz, bit[0]:2.4GHz + */ + for (i = 0; i < RTW89_PHY_NUM; i++) { + if (wl->rf_band_map[i] & BIT(RTW89_BAND_2G)) + wl_rf_band[i] |= BIT(RTW89_BAND_2G); + + if (wl->rf_band_map[i] & (BIT(RTW89_BAND_5G) | BIT(RTW89_BAND_6G))) + wl_rf_band[i] |= BIT(RTW89_BAND_5G); + + dm->fit_xmap[i][BTC_BT_1ST] = wl_rf_band[i] & bt0->rf_band_map; + dm->fit_xmap[i][BTC_BT_2ND] = wl_rf_band[i] & bt1->rf_band_map; + dm->fit_xmap[i][BTC_BT_EXT] = wl_rf_band[i] & bt2->rf_band_map; + } + + /* + * if MR_WTYPE_MLD2L1R_NONMLD, FW will change 2+0/0+2/1+1 + * Therefore, BTC_MLO_RF_xxx is not real-time state. + * if link mode change by _ntfy_generic(BTC_GNTFY_MRCX_INFO) + * the HW-BAND is decided by wl->mlo_info.mrcx_act_hwb_map + * In this case, BTC_RF_S0->HWB0, BTC_RF_S1->HWB1 + */ + if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD) { + if (wl->role_info.link_mode != BTC_WLINK_DB_MCC) {/* mode chg */ + if (wl->mlo_info.mrcx_act_hwb_map == BIT(RTW89_PHY_1)) + path_hwb[BTC_RF_S0] = RTW89_PHY_1;/* S0/1->HWB1 */ + else + path_hwb[BTC_RF_S1] = RTW89_PHY_0;/* S0/1->HWB0 */ + } + } else { + if (wl->mlo_info.rf_combination == BTC_MLO_RF_2_PLUS_0) + path_hwb[BTC_RF_S1] = RTW89_PHY_0; /* 2+0 RF-S0/1->HWB0 */ + else if (wl->mlo_info.rf_combination == BTC_MLO_RF_0_PLUS_2) + path_hwb[BTC_RF_S0] = RTW89_PHY_1; /* 2+0 RF-S0/1->HWB1 */ + } + + /* + * tdd_map = sit_xmap * fdm_map, 1: WL-RF-Sx vs. BTx take TDD-Action + * fdd_map =(!sit_xmap) * fdm_map, 1: WL-RF-Sx vs.BTx take FDD-Action + * co-rx map = ant_xmap * fdm_map 1:WL/BT co-rx (for halbb-btg-ctrl) + * sit_xmap,ant_xmap = 0 or 1, so tdd/fdd use multiplication (*) + */ + + for (i = 0; i < BTC_RF_NUM; i++) + for (j = 0; j < BTC_ALL_BT_EZL; j++) { + dm->tdd_map[i][j] = dm->sit_xmap[i][j] * + dm->fit_xmap[path_hwb[i]][j]; + dm->fdd_map[i][j] = !dm->sit_xmap[i][j] * + dm->fit_xmap[path_hwb[i]][j]; + dm->corx_map[i][j] = dm->ant_xmap[i][j] * + dm->fit_xmap[path_hwb[i]][j]; + } + + /* TDD-Binding */ + _set_bind_info(btc, BTC_MECH_TDD); + + /* FDD-Binding */ + _set_bind_info(btc, BTC_MECH_FDD); + + dm->out_of_band = !dm->tdd_bind.rf_band && !dm->fdd_bind.rf_band; + dm->fdd_en = !!dm->fdd_bind.rf_band; + dm->tdd_en = !!dm->tdd_bind.rf_band; + + /* set BT on/off state for GNT_WL Combined-MUX control */ + if (bt0->enable.now) + val |= BIT(0); + + if (bt1->enable.now) + val |= BIT(1); + + if (bt2->func_type) + val |= BIT(2); + + dm->ost_info.bt_enable_state = dm->bt_only ? _bind_is_btonly : val; +} + +static void _update_run_ctrl_info(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_ctrl ctrl = btc->ctrl; + struct rtw89_fbtc_wl_ctrl_info *wl_ctrl_info = &ctrl.wl_ctrl_info; + u8 i; + + ctrl.wl_only = dm->wl_only; + ctrl.bt_only = dm->bt_only; + ctrl.ntfy_type = dm->run_reason; + + wl_ctrl_info->smap_val = wl->status.val; + wl_ctrl_info->rfk_state = wl->rfk_info.state; + wl_ctrl_info->rfk_type = wl->rfk_info.type; + wl_ctrl_info->client_pstdma_on = dm->client_ps_tdma_on; + wl_ctrl_info->fw_scan = wl->scan_info.fw_scan; + + for (i = RTW89_MAC_0; i <= RTW89_MAC_1; i++) { + wl_ctrl_info->rf_band_map[i] = wl->rf_band_map[i]; + wl_ctrl_info->rf_ch[i] = wl->rf_ch_info[i].center_ch; + } + + if (!memcmp(&btc->ctrl, &ctrl, sizeof(struct rtw89_btc_ctrl))) { + memcpy(&btc->ctrl, &ctrl, sizeof(struct rtw89_btc_ctrl)); + if (btc->ver->fcxctrl >= 9) + _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); + } +} + +static +void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + u8 mode = btc->dm.tdd_bind.wl_link_mode; + u8 mode_v0 = BTC_WLINK_V0_OTHER; + bool has_2ghz; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + dm->run_reason = reason; + _update_dm_step(rtwdev, reason); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", + __func__, reason, mode); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n", + __func__, dm->wl_only, dm->bt_only); + + /* Be careful to change the following function sequence!! */ + if (btc->manual_ctrl) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return for Manual CTRL!!\n", + __func__); + return; + } + + if (!wl->status.map.init_ok) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return for WL init fail!!\n", + __func__); + return; + } + + if (wl->status.map.rf_off_pre == wl->status.map.rf_off && + wl->status.map.lps_pre == wl->status.map.lps && + !dm->lps_ctrl_change && !dm->lps_ctrl_scbd) { + if (reason == BTC_RSN_NTFY_POWEROFF || + reason == BTC_RSN_NTFY_RADIO_STATE) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return for WL rf off state no change!!\n", + __func__); + return; + } + if (wl->status.map.rf_off == 1 || + wl->status.map.lps == BTC_LPS_RF_OFF) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return for WL rf off state!!\n", + __func__); + return; + } + } + + _update_run_ctrl_info(rtwdev); + + if (reason == BTC_RSN_NTFY_INIT || reason == BTC_RSN_NTFY_RADIO_STATE) + _update_bt_scbd(rtwdev, false); + + dm->freerun = false; + dm->cnt_dm[BTC_DCNT_RUN]++; + dm->fddt_train = BTC_FDDT_DISABLE; + bt->scan_rx_low_pri = false; + + _set_coex_binding(btc); + _update_btc_state_map(rtwdev); + + dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */ + + if (btc->ctrl.always_freerun) { + _action_freerun(rtwdev); + goto exit; + } + + if (dm->wl_only) { + _action_wl_only(rtwdev); + goto exit; + } + + if (wl->status.map.rf_off || dm->bt_only || wl->status.map.lps) { + _action_wl_off(rtwdev, mode); + goto exit; + } + + if (reason == BTC_RSN_NTFY_INIT) { + _action_wl_init(rtwdev); + goto exit; + } + + if (!cx->bt0.enable.now && !cx->bt_ext.func_type) { + _action_bt_off(rtwdev); + goto exit; + } + + if (cx->bt0.whql_test) { + _action_bt_whql(rtwdev); + goto exit; + } + + if (wl->rfk_info.state != BTC_WRFK_STOP) { + _action_wl_rfk(rtwdev); + goto exit; + } + + if (wl->status.val & btc_scanning_map.val && !wl->rfk_info.con_rfk) { + _action_wl_scan(rtwdev); + bt->scan_rx_low_pri = true; + goto exit; + } + + if (mode == BTC_WLINK_NOLINK) { + mode_v0 = BTC_WLINK_V0_NOLINK; + } else if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_5G)) { + mode_v0 = BTC_WLINK_V0_5G; + } else if (btc->dm.tdd_bind.rf_band & BIT(RTW89_BAND_5G) && + btc->dm.tdd_bind.rf_band & BIT(RTW89_BAND_2G)) { + mode_v0 = BTC_WLINK_V0_25G_MCC; + } else if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_2G)) { + switch (mode) { + case BTC_WLINK_STA: + mode_v0 = BTC_WLINK_V0_2G_STA; + break; + case BTC_WLINK_AP: + mode_v0 = BTC_WLINK_V0_2G_AP; + break; + case BTC_WLINK_GO: + mode_v0 = BTC_WLINK_V0_2G_GO; + break; + case BTC_WLINK_GC: + mode_v0 = BTC_WLINK_V0_2G_GC; + break; + case BTC_WLINK_SCC: + mode_v0 = BTC_WLINK_V0_2G_SCC; + break; + case BTC_WLINK_SB_MCC: + mode_v0 = BTC_WLINK_V0_2G_MCC; + break; + default: + mode_v0 = BTC_WLINK_V0_OTHER; + break; + } + } else { + /* No binding (out_of_band): derive mode_v0 from link_mode + rf_band_map */ + has_2ghz = wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G) || + wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G); + + if (!has_2ghz) { + mode_v0 = BTC_WLINK_V0_5G; + } else if (mode == BTC_WLINK_DB_MCC) { + mode_v0 = BTC_WLINK_V0_25G_MCC; + } else { + switch (mode) { + case BTC_WLINK_STA: + mode_v0 = BTC_WLINK_V0_2G_STA; + break; + case BTC_WLINK_AP: + mode_v0 = BTC_WLINK_V0_2G_AP; + break; + case BTC_WLINK_GO: + mode_v0 = BTC_WLINK_V0_2G_GO; + break; + case BTC_WLINK_GC: + mode_v0 = BTC_WLINK_V0_2G_GC; + break; + case BTC_WLINK_SCC: + mode_v0 = BTC_WLINK_V0_2G_SCC; + break; + case BTC_WLINK_SB_MCC: + mode_v0 = BTC_WLINK_V0_2G_MCC; + break; + default: + mode_v0 = BTC_WLINK_V0_OTHER; + break; + } + } + } + + switch (mode_v0) { + case BTC_WLINK_NOLINK: + _action_wl_nc(rtwdev); + break; + case BTC_WLINK_V0_2G_STA: + if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) + bt->scan_rx_low_pri = true; + _action_wl_2g_sta(rtwdev); + break; + case BTC_WLINK_V0_2G_AP: + bt->scan_rx_low_pri = true; + _action_wl_2g_ap(rtwdev); + break; + case BTC_WLINK_V0_2G_GO: + bt->scan_rx_low_pri = true; + _action_wl_2g_go(rtwdev); + break; + case BTC_WLINK_V0_2G_GC: + bt->scan_rx_low_pri = true; + _action_wl_2g_gc(rtwdev); + break; + case BTC_WLINK_V0_2G_SCC: + bt->scan_rx_low_pri = true; + _action_wl_2g_scc(rtwdev); + break; + case BTC_WLINK_V0_2G_MCC: + bt->scan_rx_low_pri = true; + _action_wl_2g_mcc(rtwdev); + break; + case BTC_WLINK_V0_25G_MCC: + bt->scan_rx_low_pri = true; + _action_wl_25g_mcc(rtwdev); + break; + case BTC_WLINK_V0_5G: + _action_wl_5g(rtwdev); + break; + case BTC_WLINK_V0_2G_NAN: + _action_wl_2g_nan(rtwdev); + break; + default: + _action_wl_other(rtwdev); + break; + } + +exit: + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): exit\n", __func__); + _action_common(rtwdev); +} + +void rtw89_btc_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): Init %s !!\n", __func__, + chip_id_str(chip->chip_id)); + + _reset_btc_var(rtwdev, BTC_RESET_ALL); + + btc->dm.run_reason = BTC_RSN_NONE; + btc->dm.run_action = BTC_ACT_NONE; + wl->status.map.init_ok = true; +} + +void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + btc->dm.cnt_notify[BTC_NCNT_POWER_ON]++; +} + +void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); + btc->dm.cnt_notify[BTC_NCNT_POWER_OFF]++; + + btc->cx.wl.status.map.rf_off = 1; + btc->cx.wl.status.map.busy = 0; + wl->status.map.lps = BTC_LPS_OFF; + + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ALL, false); + _run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF); + + btc->cx.wl.status.map.rf_off_pre = btc->cx.wl.status.map.rf_off; +} + +#define BTC_PLATFORM_LITTLE_ENDIAN 0 +static void _set_init_info(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + dm->init_info.init_mode = wl->coex_mode; + dm->init_info.wl_init_ok = wl->status.map.init_ok; + dm->init_info.endian_type = BTC_PLATFORM_LITTLE_ENDIAN; + dm->init_info.bt0_function = cx->bt0.func_type; + dm->init_info.bt1_function = cx->bt1.func_type; + dm->init_info.bt2_function = cx->bt_ext.func_type; + dm->init_info.pta_mode = RTW89_MAC_AX_COEX_RTK_MODE; + dm->init_info.pta_direction = RTW89_MAC_AX_COEX_INNER; + dm->init_info.wl_only = dm->wl_only; + dm->init_info.bt_only = dm->bt_only; + dm->init_info.wl_init_ok = wl->status.map.init_ok; + dm->init_info.cx_other = btc->cx.bt_ext.func_type; + dm->init_info.wl_guard_ch = chip->afh_guard_ch; + dm->init_info.dbcc_en = rtwdev->dbcc_en; + + dm->init_info.module = btc->mdinfo; + + _fw_set_drv_info(rtwdev, CXDRVINFO_INIT); + _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); + rtw89_btc_fw_set_slots(rtwdev); + btc_fw_set_monreg(rtwdev); + _set_ext_interface(rtwdev); + _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR, RTW89_PHY_0); +} + +void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + const struct rtw89_chip_info *chip = rtwdev->chip; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): mode=%d\n", __func__, mode); + + wl->coex_mode = mode; + dm->cnt_notify[BTC_NCNT_INIT_COEX]++; + dm->wl_only = mode == BTC_MODE_WL ? 1 : 0; + dm->bt_only = mode == BTC_MODE_BT ? 1 : 0; + wl->status.map.rf_off = mode == BTC_MODE_WLOFF ? 1 : 0; + dm->vid = rtwdev->custid; + btc->ctrl.always_freerun = mode == BTC_MODE_COTX; + + if (!wl->status.map.init_ok) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return for WL init fail!!\n", + __func__); + dm->error.map.init = true; + return; + } + + btc->cx.bt0.enable.now = 1; + btc->cx.bt0.run_patch_code = 1; + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) { + btc->cx.bt1.enable.now = 1; + btc->cx.bt1.run_patch_code = 1; + } + + if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) + btc->io_oflld_type = BTC_IO_OFLD_BTC_H2C; + else + btc->io_oflld_type = BTC_IO_OFLD_NO_SUPPORT; + + chip->ops->btc_set_rfe(rtwdev); + chip->ops->btc_init_cfg(rtwdev); + + _write_scbd(rtwdev, BTC_ALL_BT, + BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); + + if (rtw89_mac_get_ctrl_path(rtwdev)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): PTA owner warning!!\n", + __func__); + dm->error.map.pta_owner = true; + } + + _set_init_info(rtwdev); + _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR, RTW89_PHY_0); + btc_fw_set_monreg(rtwdev); + rtw89_btc_fw_set_slots(rtwdev); + _fw_set_drv_info(rtwdev, CXDRVINFO_INIT); + _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); + + _run_coex(rtwdev, BTC_RSN_NTFY_INIT); +} + +void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_idx=%d, band=%d\n", + __func__, phy_idx, band); + + if (phy_idx >= RTW89_PHY_NUM) + return; + + btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++; + wl->status.map.scan = true; + wl->scan_info.band[phy_idx] = band; + wl->scan_info.phy_map |= BIT(phy_idx); + _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); + + if (rtwdev->dbcc_en) { + wl->dbcc_info.scan_band[phy_idx] = band; + _update_dbcc_band(rtwdev, phy_idx); + _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); + } + + if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) + btc->ctrl.wl_ctrl_info.fw_scan = 1; + + _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_START); +} + +void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_idx=%d\n", __func__, phy_idx); + btc->dm.cnt_notify[BTC_NCNT_SCAN_FINISH]++; + + wl->status.map.scan = false; + wl->scan_info.phy_map &= ~BIT(phy_idx); + _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); + + if (rtwdev->dbcc_en) { + _update_dbcc_band(rtwdev, phy_idx); + _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); + } + + btc->dm.tdma_instant_excute = 1; + + _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH); +} + +void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): phy_idx=%d, band=%d\n", + __func__, phy_idx, band); + + if (phy_idx >= RTW89_PHY_NUM) + return; + + btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++; + + if (rtwdev->dbcc_en) { + wl->dbcc_info.scan_band[phy_idx] = band; + _update_dbcc_band(rtwdev, phy_idx); + _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); + } + _run_coex(rtwdev, BTC_RSN_NTFY_SWBAND); +} + +void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, + enum btc_pkt_type pkt_type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_link_info *b = &cx->bt0.link_info; + struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; + struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; + u32 cnt; + u32 delay = RTW89_COEX_ACT1_WORK_PERIOD; + bool delay_work = false; + + switch (pkt_type) { + case PACKET_DHCP: + cnt = ++wl->wcnt[BTC_WCNT_DHCP]; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): DHCP cnt=%d\n", __func__, cnt); + wl->status.map.handshake = 0; + wl->status.map._4way = 0; + wl->status.map.dhcp = 1; + delay_work = true; + break; + case PACKET_EAPOL: + cnt = ++wl->wcnt[BTC_WCNT_EAPOL]; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt); + wl->status.map.handshake = 0; + wl->status.map._4way = 1; + wl->status.map.dhcp = 0; + delay_work = true; + if (hfp->exist || hid->exist) + delay /= 2; + break; + case PACKET_EAPOL_END: + cnt = ++wl->wcnt[BTC_WCNT_EAPOL]; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): EAPOL_End cnt=%d\n", + __func__, cnt); + wl->status.map._4way = 0; + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work); + break; + case PACKET_ARP: + cnt = ++wl->wcnt[BTC_WCNT_ARP]; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): ARP cnt=%d\n", __func__, cnt); + return; + case PACKET_ICMP: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): ICMP pkt\n", __func__); + return; + default: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): unknown packet type %d\n", + __func__, pkt_type); + return; + } + + if (delay_work) { + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work, delay); + } + + btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++; + _run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET); +} + +void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + btc.eapol_notify_work); + + lockdep_assert_wiphy(wiphy); + + rtw89_leave_ps_mode(rtwdev); + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL); +} + +void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + btc.arp_notify_work); + + lockdep_assert_wiphy(wiphy); + + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP); +} + +void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + btc.dhcp_notify_work); + + lockdep_assert_wiphy(wiphy); + + rtw89_leave_ps_mode(rtwdev); + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP); +} + +void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + btc.icmp_notify_work); + + lockdep_assert_wiphy(wiphy); + + rtw89_leave_ps_mode(rtwdev); + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP); +} + +static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + u8 *rssi_st, rssi_th, rssi_level = 0; + u8 i; + + /* for rssi locate in which {40, 36, 31, 28} + * if rssi >= 40% (-60dBm) --> rssi_level = 4 + * if 36% <= rssi < 40% --> rssi_level = 3 + * if 31% <= rssi < 36% --> rssi_level = 2 + * if 28% <= rssi < 31% --> rssi_level = 1 + * if rssi < 28% --> rssi_level = 0 + */ + + /* check if rssi across bt_rssi_thres boundary */ + for (i = 0; i < BTC_BT_RSSI_THMAX; i++) { + rssi_th = chip->bt_rssi_thres[i]; + rssi_st = &bt->link_info.rssi_state[i]; + + *rssi_st = _update_rssi_state(rtwdev, *rssi_st, rssi, rssi_th); + + if (BTC_RSSI_HIGH(*rssi_st)) { + rssi_level = BTC_BT_RSSI_THMAX - i; + break; + } + } + return rssi_level; +} + +#define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4) + +static void _update_bt_info(struct rtw89_dev *rtwdev, u8 bid, u8 *buf, u32 len) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_hfp_desc *hfp; + struct rtw89_btc_bt_hid_desc *hid; + struct rtw89_btc_bt_pan_desc *pan; + struct rtw89_btc_bt_link_info *b; + struct rtw89_btc_bt_info *bt; + union btc_btinfo btinfo; + u8 is_bt_56g = 0; + u8 *raw_info; + + /* Bit7 is used for RF-band: 0:BT_2.4 GHz, 1:BT_5/6 GHz */ + if ((buf[BTC_BTINFO_L1] & 0x7f) != 6) + return; + + bt = (bid == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1; + + if ((buf[BTC_BTINFO_L1] & BIT(7)) && bt->band_56G_support) { + b = &bt->link_info_56g; + is_bt_56g = 1; + if (b->status.map.connect) + bt->rf_band_map |= BIT(RTW89_BAND_5G); + else + bt->rf_band_map &= ~BIT(RTW89_BAND_5G); + } else { + b = &bt->link_info; + bt->rf_band_map |= BIT(RTW89_BAND_2G); + } + + hfp = &b->hfp_desc; + hid = &b->hid_desc; + a2dp = &b->a2dp_desc; + pan = &b->pan_desc; + raw_info = is_bt_56g ? bt->raw_info_56g : bt->raw_info; + + if (!memcmp(raw_info, buf, BTC_BTINFO_MAX)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): return by bt-info duplicate!!\n", + __func__); + bt->bcnt[BTC_BCNT_INFOSAME]++; + return; + } + + memcpy(raw_info, buf, BTC_BTINFO_MAX); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): bt_info[2]=0x%02x\n", + __func__, raw_info[2]); + + hid->type = 0; + + /* parse raw info low-Byte2 */ + btinfo.val = raw_info[BTC_BTINFO_L2]; + b->status.map.connect = btinfo.lb2.connect; + b->status.map.sco_busy = btinfo.lb2.sco_busy; + b->status.map.acl_busy = btinfo.lb2.acl_busy; + b->status.map.inq_pag = btinfo.lb2.inq_pag; + bt->inq_pag.now = btinfo.lb2.inq_pag; + bt->bcnt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last); + + hfp->exist = btinfo.lb2.hfp; + hid->exist = btinfo.lb2.hid; + a2dp->exist = btinfo.lb2.a2dp; + pan->exist = btinfo.lb2.pan; + _update_bt_link_cnt(rtwdev, bt, is_bt_56g); + btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK); + + /* parse raw info low-Byte3 */ + btinfo.val = raw_info[BTC_BTINFO_L3]; + if (btinfo.lb3.retry != 0) + bt->bcnt[BTC_BCNT_RETRY]++; + b->cqddr = btinfo.lb3.cqddr; + bt->bcnt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq); + bt->inq = btinfo.lb3.inq; + bt->bcnt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag); + bt->pag = btinfo.lb3.pag; + + b->status.map.mesh_busy = btinfo.lb3.mesh_busy; + /* parse raw info high-Byte0 */ + btinfo.val = raw_info[BTC_BTINFO_H0]; + /* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/ + b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi); + bt->rssi_level = _update_bt_rssi_level(rtwdev, b->rssi); + btc->dm.trx_info.bt_rssi = bt->rssi_level; + + /* parse raw info high-Byte1 */ + btinfo.val = raw_info[BTC_BTINFO_H1]; + b->status.map.ble_connect = btinfo.hb1.ble_connect; + if (btinfo.hb1.ble_connect) { + if (hid->exist) + hid->type |= BTC_HID_BLE; + else if (btinfo.hb1.voice) + hid->type |= BTC_HID_RCU_VOICE; + else + hid->type |= BTC_HID_RCU; + } + + bt->bcnt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit); + bt->reinit = btinfo.hb1.reinit; + bt->bcnt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now); + b->relink.now = btinfo.hb1.relink; + bt->bcnt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl); + bt->igno_wl = btinfo.hb1.igno_wl; + + if (bt->igno_wl && !cx->wl.status.map.rf_off) + _set_bt_ignore_wlan_act(rtwdev, false); + + bt->ble_scan_en = btinfo.hb1.ble_scan; + + bt->bcnt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw); + b->role_sw = btinfo.hb1.role_sw; + + b->multi_link.now = btinfo.hb1.multi_link; + + /* parse raw info high-Byte2 */ + btinfo.val = raw_info[BTC_BTINFO_H2]; + pan->active = !!btinfo.hb2.pan_active; + + bt->bcnt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update); + b->afh_update = btinfo.hb2.afh_update; + a2dp->active = btinfo.hb2.a2dp_active; + b->slave_role = btinfo.hb2.slave; + hid->slot_info = btinfo.hb2.hid_slot; + hid->pair_cnt = btinfo.hb2.hid_cnt; + if (!b->status.map.ble_connect || hid->pair_cnt > 1) + hid->type |= (hid->slot_info == BTC_HID_218 ? + BTC_HID_218 : BTC_HID_418); + /* parse raw info high-Byte3 */ + btinfo.val = raw_info[BTC_BTINFO_H3]; + a2dp->bitpool = btinfo.hb3.a2dp_bitpool; + + if (b->tx_3m != (u32)btinfo.hb3.tx_3m) + bt->bcnt[BTC_BCNT_RATECHG]++; + b->tx_3m = (u32)btinfo.hb3.tx_3m; + + a2dp->sink = btinfo.hb3.a2dp_sink; + + if (!a2dp->exist_last && a2dp->exist) { + a2dp->vendor_id = 0; + a2dp->flush_time = 0; + a2dp->play_latency = 1; + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_bt_devinfo_work, + RTW89_COEX_BT_DEVINFO_WORK_PERIOD); + } + + _update_bt_ctrl_lps(rtwdev); + _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); +} + +static void _ntfy_role_info(struct rtw89_dev *rtwdev, u8 rid, + struct rtw89_btc_wl_link_info *info, + enum btc_role_state reason) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_link_info *wlinfo = NULL; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + const struct rtw89_btc_ver *ver = btc->ver; + u8 rlink_id = info->phy; /* 1 role_id has 2 rlink_id(by HW_Band0/1) */ + bool refresh_role = false; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(), role_id=%d, reason=%d\n", + __func__, rid, reason); + + if (rid >= ver->max_role_num || rlink_id >= RTW89_PHY_NUM) + return; + + btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++; + + wlinfo = &wl->rlink_info[rid][rlink_id]; + memcpy(wlinfo, info, sizeof(struct rtw89_btc_wl_link_info)); + + switch (reason) { + case BTC_ROLE_START: + wlinfo->active = true; + return; + case BTC_ROLE_STOP: + wlinfo->active = false; + return; + case BTC_ROLE_MSTS_STA_CONN_START: + wl->status.map.transacting = 1; + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work, + RTW89_COEX_ACT1_WORK_PERIOD); + break; + case BTC_ROLE_MSTS_STA_CONN_END: + wl->status.map.transacting = 0; + refresh_role = true; + break; + case BTC_ROLE_MSTS_STA_DIS_CONN: + wl->status.map.transacting = 1; + refresh_role = false; + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work, + RTW89_COEX_ACT1_WORK_PERIOD); + break; + case BTC_ROLE_MSTS_AP_START: + case BTC_ROLE_MSTS_AP_STOP: + refresh_role = true; + break; + case BTC_ROLE_STATE_UNKNOWN: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(), role_id=%d, Unknown reason return!\n", + __func__, rid); + return; + default: + return; + } + + if (refresh_role) { + _update_wl_info(rtwdev, wlinfo); + _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); + } + + _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO); +} + +void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + enum btc_role_state state) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct ieee80211_p2p_noa_attr *noa_attr; + struct ieee80211_p2p_noa_desc *noa_desc; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; + struct rtw89_btc_wl_link_info r = {0}; + u8 i, role_id, mode = 0; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + + role_id = rtwvif_link->port; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], role is STA=%d\n", + vif->type == NL80211_IFTYPE_STATION); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", role_id); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n", + chan->band_type, chan->channel, chan->band_width); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n", + state == BTC_ROLE_MSTS_STA_CONN_END); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], bcn_period=%d dtim_period=%d\n", + bss_conf->beacon_int, bss_conf->dtim_period); + + if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", + rtwsta_link->mac_id); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], STA support HE=%d VHT=%d HT=%d\n", + link_sta->he_cap.has_he, + link_sta->vht_cap.vht_supported, + link_sta->ht_cap.ht_supported); + if (link_sta->he_cap.has_he) + mode |= BIT(BTC_WL_MODE_HE); + if (link_sta->vht_cap.vht_supported) + mode |= BIT(BTC_WL_MODE_VHT); + if (link_sta->ht_cap.ht_supported) + mode |= BIT(BTC_WL_MODE_HT); + + r.mode = mode; + } + + if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) { + rcu_read_unlock(); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role); + + if (vif->type == NL80211_IFTYPE_P2P_GO || + vif->type == NL80211_IFTYPE_P2P_CLIENT) { + noa_attr = &bss_conf->p2p_noa_attr; + + for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) { + noa_desc = &noa_attr->desc[i]; + if (noa_desc->count != 0) { + r.noa = 1; + r.noa_duration = le32_to_cpu(noa_desc->duration); + break; + } + } + } + + r.mode = mode; + r.role = rtwvif_link->wifi_role; + r.phy = rtwvif_link->phy_idx; + r.pid = role_id; + r.active = true; + if (vif->active_links) { + if (rtwvif_link->link_id < 16) + r.active = !!(vif->active_links & BIT(rtwvif_link->link_id)); + } + r.bcn_period = bss_conf->beacon_int; + r.dtim_period = bss_conf->dtim_period; + r.band = chan->band_type; + r.ch = chan->channel; + r.bw = chan->band_width; + r.chdef.band = chan->band_type; + r.chdef.center_ch = chan->channel; + r.chdef.bw = chan->band_width; + r.chdef.chan = chan->primary_channel; + + if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION) { + r.mac_id = rtwsta_link->mac_id; + ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr); + } + + switch (state) { + case BTC_ROLE_MSTS_STA_CONN_END: + case BTC_ROLE_MSTS_AP_START: + r.connected = MLME_LINKED; + break; + default: + r.connected = MLME_NO_LINK; + break; + } + + rcu_read_unlock(); + + _ntfy_role_info(rtwdev, role_id, &r, state); +} + +void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + u32 val; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rf_state = %d\n", + __func__, rf_state); + btc->dm.cnt_notify[BTC_NCNT_RADIO_STATE]++; + + switch (rf_state) { + case BTC_RFCTRL_WL_OFF: + wl->status.map.rf_off = 1; + wl->status.map.lps = BTC_LPS_OFF; + wl->status.map.busy = 0; + break; + case BTC_RFCTRL_FW_CTRL: + wl->status.map.rf_off = 0; + wl->status.map.lps = BTC_LPS_RF_OFF; + wl->status.map.busy = 0; + break; + case BTC_RFCTRL_LPS_WL_ON: /* LPS-Protocol (RFon) */ + wl->status.map.rf_off = 0; + wl->status.map.lps = BTC_LPS_RF_ON; + wl->status.map.busy = 0; + break; + case BTC_RFCTRL_WL_ON: + default: + wl->status.map.rf_off = 0; + wl->status.map.lps = BTC_LPS_OFF; + break; + } + + if (rf_state == BTC_RFCTRL_WL_ON) { + val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; + _write_scbd(rtwdev, BTC_ALL_BT, val, true); + chip->ops->btc_init_cfg(rtwdev); + } else { + if (rf_state == BTC_RFCTRL_FW_CTRL) + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ACTIVE, false); + else if (rf_state == BTC_RFCTRL_WL_OFF) + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ALL, false); + else + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ACTIVE, false); + } + + btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; + btc->dm.tdma_instant_excute = 1; + + _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); + wl->status.map.rf_off_pre = wl->status.map.rf_off; + wl->status.map.lps_pre = wl->status.map.lps; +} + +static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path, + enum btc_wl_rfk_type type, + enum btc_wl_rfk_state state) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + bool result = BTC_WRFK_REJECT; + + wl->rfk_info.type = type; + wl->rfk_info.path_map = FIELD_GET(BTC_RFK_PATH_MAP, phy_path); + wl->rfk_info.phy_map = FIELD_GET(BTC_RFK_PHY_MAP, phy_path); + wl->rfk_info.band = FIELD_GET(BTC_RFK_BAND_MAP, phy_path); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s()_start: phy=0x%x, path=0x%x, type=%d, state=%d\n", + __func__, wl->rfk_info.phy_map, wl->rfk_info.path_map, + type, state); + + switch (state) { + case BTC_WRFK_START: + result = BTC_WRFK_ALLOW; + wl->rfk_info.state = BTC_WRFK_START; + + btc->cx.wl.wcnt[BTC_WCNT_RFK_REQ]++; + btc->dm.cnt_notify[BTC_NCNT_WL_RFK]++; + + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, true); + break; + case BTC_WRFK_ONESHOT_START: + case BTC_WRFK_ONESHOT_STOP: + btc->cx.wl.wcnt[BTC_WCNT_RFK_GO]++; + if (type != BTC_WRFKT_RXDCK) + return BTC_WRFK_ALLOW; + break; + case BTC_WRFK_STOP: + result = BTC_WRFK_ALLOW; + wl->rfk_info.state = BTC_WRFK_STOP; + + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, false); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_rfk_chk_work); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s() warning state=%d\n", __func__, state); + return result; + } + + if (result == BTC_WRFK_ALLOW) { + if (wl->rfk_info.state == BTC_WRFK_START || + wl->rfk_info.state == BTC_WRFK_STOP) + _run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK); + + if (wl->rfk_info.state == BTC_WRFK_START) + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_rfk_chk_work, + RTW89_COEX_RFK_CHK_WORK_PERIOD); + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s()_finish: rfk_cnt=%d, result=%d\n", + __func__, btc->dm.cnt_notify[BTC_NCNT_WL_RFK], result); + + return result; +} + +void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, + enum btc_wl_rfk_type type, + enum btc_wl_rfk_state state) +{ + u8 band; + bool allow; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] RFK notify (%s / PHY%u / K_type = %u / path_idx = %lu / process = %s)\n", + band == RTW89_BAND_2G ? "2G" : + band == RTW89_BAND_5G ? "5G" : "6G", + !!(FIELD_GET(BTC_RFK_PHY_MAP, phy_map) & BIT(RTW89_PHY_1)), + type, + FIELD_GET(BTC_RFK_PATH_MAP, phy_map), + state == BTC_WRFK_STOP ? "RFK_STOP" : + state == BTC_WRFK_START ? "RFK_START" : + state == BTC_WRFK_ONESHOT_START ? "ONE-SHOT_START" : + "ONE-SHOT_STOP"); + + if (state != BTC_WRFK_START || rtwdev->is_bt_iqk_timeout) { + _ntfy_wl_rfk(rtwdev, phy_map, type, state); + return; + } + + ret = read_poll_timeout(_ntfy_wl_rfk, allow, allow, 40, 100000, false, + rtwdev, phy_map, type, state); + if (ret) { + rtw89_warn(rtwdev, "RFK notify timeout\n"); + rtwdev->is_bt_iqk_timeout = true; + } +} +EXPORT_SYMBOL(rtw89_btc_ntfy_wl_rfk); + +struct rtw89_btc_wl_sta_iter_data { + struct rtw89_dev *rtwdev; + u8 busy_all; + u8 dir_all; + u8 rssi_map_all; + bool is_sta_change; + bool is_traffic_change; +}; + +static +void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_btc_wl_sta_iter_data *iter_data) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_dev *rtwdev = iter_data->rtwdev; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_link_info *link_info = NULL; + struct rtw89_traffic_stats *link_info_t = NULL; + struct rtw89_traffic_stats *stats = &rtwvif->stats; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc_wl_role_info *r; + u32 last_tx_rate, last_rx_rate; + u8 link = rtwvif_link->phy_idx; + u16 last_tx_lvl, last_rx_lvl; + u8 port = rtwvif_link->port; + u8 rssi; + u8 busy = 0; + u8 dir = 0; + u8 rssi_map = 0; + u8 i = 0; + bool is_sta_change = false, is_traffic_change = false; + + rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); + + link_info = &wl->rlink_info[port][link]; + + link_info->stat.traffic = *stats; + link_info_t = &link_info->stat.traffic; + + if (link_info->connected == MLME_NO_LINK) { + link_info->rx_rate_drop_cnt = 0; + return; + } + + link_info->stat.rssi = rssi; + for (i = 0; i < BTC_WL_RSSI_THMAX; i++) { + link_info->rssi_state[i] = + _update_rssi_state(rtwdev, + link_info->rssi_state[i], + link_info->stat.rssi, + chip->wl_rssi_thres[i]); + if (BTC_RSSI_LOW(link_info->rssi_state[i])) + rssi_map |= BIT(i); + + if (btc->ant_type == BTC_ANT_DEDICATED && + BTC_RSSI_CHANGE(link_info->rssi_state[i])) + is_sta_change = true; + } + iter_data->rssi_map_all |= rssi_map; + + last_tx_rate = link_info_t->tx_rate; + last_rx_rate = link_info_t->rx_rate; + last_tx_lvl = (u16)link_info_t->tx_tfc_lv; + last_rx_lvl = (u16)link_info_t->rx_tfc_lv; + + if (stats->tx_tfc_lv != RTW89_TFC_IDLE || + stats->rx_tfc_lv != RTW89_TFC_IDLE) + busy = 1; + + if (stats->tx_tfc_lv > stats->rx_tfc_lv) + dir = RTW89_TFC_UL; + else + dir = RTW89_TFC_DL; + + if (link_info->busy != busy || link_info->dir != dir) { + is_sta_change = true; + link_info->busy = busy; + link_info->dir = dir; + } + + iter_data->busy_all |= busy; + iter_data->dir_all |= BIT(dir); + + if (rtwsta_link->rx_hw_rate <= RTW89_HW_RATE_CCK2 && + last_rx_rate > RTW89_HW_RATE_CCK2 && + link_info_t->rx_tfc_lv > RTW89_TFC_IDLE) + link_info->rx_rate_drop_cnt++; + + if (last_tx_rate != rtwsta_link->ra_report.hw_rate || + last_rx_rate != rtwsta_link->rx_hw_rate || + last_tx_lvl != link_info_t->tx_tfc_lv || + last_rx_lvl != link_info_t->rx_tfc_lv) + is_traffic_change = true; + + link_info_t->tx_rate = rtwsta_link->ra_report.hw_rate; + link_info_t->rx_rate = rtwsta_link->rx_hw_rate; + + if (link_info->role == RTW89_WIFI_ROLE_STATION || + link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) { + dm->trx_info.tx_rate = link_info_t->tx_rate; + dm->trx_info.rx_rate = link_info_t->rx_rate; + } + + r = &wl->role_info; + r->rlink[port][link].tx_lvl = stats->tx_tfc_lv; + r->rlink[port][link].rx_lvl = stats->rx_tfc_lv; + r->rlink[port][link].tx_rate = rtwsta_link->ra_report.hw_rate; + r->rlink[port][link].rx_rate = rtwsta_link->rx_hw_rate; + + dm->trx_info.tx_lvl = stats->tx_tfc_lv; + dm->trx_info.rx_lvl = stats->rx_tfc_lv; + dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate; + dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate; + dm->trx_info.tx_tp = link_info_t->tx_throughput; + dm->trx_info.rx_tp = link_info_t->rx_throughput; + + /* Trigger coex-run if 0x10980 reg-value is diff with coex setup */ + if ((dm->wl_btg_rx_rb != dm->wl_btg_rx && + dm->wl_btg_rx_rb != BTC_BTGCTRL_BB_GNT_NOTFOUND) || + (dm->wl_pre_agc_rb != dm->wl_pre_agc && + dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND)) + iter_data->is_sta_change = true; + + if (is_sta_change) + iter_data->is_sta_change = true; + + if (is_traffic_change) + iter_data->is_traffic_change = true; +} + +static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_btc_wl_sta_iter_data *iter_data = + (struct rtw89_btc_wl_sta_iter_data *)data; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + __rtw89_btc_ntfy_wl_sta_iter(rtwvif_link, rtwsta_link, iter_data); + } +} + +#define BTC_NHM_CHK_INTVL 20 + +void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_sta_iter_data data = {.rtwdev = rtwdev}; + u8 i; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_btc_ntfy_wl_sta_iter, + &data); + + wl->rssi_level = 0; + btc->dm.cnt_notify[BTC_NCNT_WL_STA]++; + for (i = BTC_WL_RSSI_THMAX; i > 0; i--) { + /* set RSSI level 4 ~ 0 if rssi bit map match */ + if (data.rssi_map_all & BIT(i - 1)) { + wl->rssi_level = i; + break; + } + } + + if (dm->trx_info.wl_rssi != wl->rssi_level) + dm->trx_info.wl_rssi = wl->rssi_level; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n", + __func__, !!wl->status.map.busy); + + _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLBUSY, (!!wl->status.map.busy)); + + if (data.is_traffic_change) + _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); + if (data.is_sta_change) { + wl->status.map.busy = data.busy_all; + wl->status.map.traffic_dir = data.dir_all; + _run_coex(rtwdev, BTC_RSN_NTFY_WL_STA); + } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] >= + btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] + BTC_NHM_CHK_INTVL) { + btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = + btc->dm.cnt_notify[BTC_NCNT_WL_STA]; + } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] < + btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST]) { + btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = + btc->dm.cnt_notify[BTC_NCNT_WL_STA]; + } +} + +static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + + switch (func) { + case BTF_EVNT_RPT: + case BTF_EVNT_BT_INFO: + case BTF_EVNT_BT_SCBD: + case BTF_EVNT_BT_REG: + case BTF_EVNT_CX_RUNINFO: + case BTF_EVNT_BT_PSD: + return func; + case BTF_EVNT_BT_DEV_INFO: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_BUF_OVERFLOW; + else + return BTF_EVNT_BT_DEV_INFO; + case BTF_EVNT_BT_LEAUDIO_INFO: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_C2H_LOOPBACK; + else if (ver->fwc2hfunc == 1) + return BTF_EVNT_BUF_OVERFLOW; + else if (ver->fwc2hfunc == 2) + return func; + else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4) + return BTF_EVNT_BUF_OVERFLOW; + else + return BTF_EVNT_MAX; + case BTF_EVNT_BUF_OVERFLOW: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_MAX; + else if (ver->fwc2hfunc == 1) + return BTF_EVNT_C2H_LOOPBACK; + else if (ver->fwc2hfunc == 2) + return func; + else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4) + return BTF_EVNT_C2H_LOOPBACK; + else + return BTF_EVNT_MAX; + case BTF_EVNT_C2H_LOOPBACK: + if (ver->fwc2hfunc == 2) + return func; + else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4) + return BTF_EVNT_BT_LEAUDIO_INFO; + else + return BTF_EVNT_MAX; + case BTF_EVNT_BT_QUERY_TXPWR: + if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4) + return func; + else + return BTF_EVNT_MAX; + case BTF_EVNT_ZB_INFO: + case BTF_EVNT_ZB_CH: + case BTF_EVNT_ZB_QUERY_TXPWR: + if (ver->fwc2hfunc == 4) + return func; + else + return BTF_EVNT_MAX; + case BTF_EVNT_MAX: + default: + return BTF_EVNT_MAX; + } +} + +void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN]; + u8 bid = BTC_BT_1ST; + + len -= RTW89_C2H_HEADER_LEN; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): C2H BT len:%d class:%d fun:%d\n", + __func__, len, class, func); + + if (class != BTFC_FW_EVENT) + return; + + if (func & BT_C2H_FUNC_BT2ND) { + bid = BTC_BT_2ND; + func &= ~BT_C2H_FUNC_BT2ND; + bt = &btc->cx.bt1; + } + + func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func); + pfwinfo->cnt_c2h++; + + switch (func) { + case BTF_EVNT_BUF_OVERFLOW: + pfwinfo->event[func]++; + break; + case BTF_EVNT_RPT: + pfwinfo->event[func]++; + /* Don't need rtw89_leave_ps_mode() */ + btc_fw_event(rtwdev, func, buf, len); + break; + case BTF_EVNT_BT_INFO: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], handle C2H BT INFO with data %8ph\n", buf); + bt->bcnt[BTC_BCNT_INFOUPDATE]++; + _update_bt_info(rtwdev, bid, buf, len); + break; + case BTF_EVNT_BT_SCBD: + bt->bcnt[BTC_BCNT_SCBDUPDATE]++; + bt->scbd_c2h = ((buf[3] << 24) | (buf[2] << 16) | + (buf[1] << 8) | (buf[0])); + bt->scbd_rb = bt->scbd_c2h; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], handle C2H BT%d SCBD with data 0x%08x\n", + bid, bt->scbd_c2h); + _update_bt_scbd(rtwdev, bid); + _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); + break; + case BTF_EVNT_BT_PSD: + break; + case BTF_EVNT_BT_REG: + btc->dbg.rb_done = true; + btc->dbg.rb_val = le32_to_cpu(*((__le32 *)buf)); + + break; + case BTF_EVNT_C2H_LOOPBACK: + btc->dbg.rb_done = true; + btc->dbg.rb_val = buf[0]; + break; + case BTF_EVNT_CX_RUNINFO: + btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++; + break; + case BTF_EVNT_BT_LEAUDIO_INFO: + bt->bcnt[BTC_BCNT_LEAUDIO_INFOUPDATE]++; + if (buf[BTC_BTINFO_L0] == BTC_BTINFO_BISTDMA) + _update_bt_bistdma_info(rtwdev, bid, buf, len); + else + _update_bt_leaudio_info(rtwdev, bid, buf, len); + _run_coex(rtwdev, BTC_RSN_UPDATE_BT_LEAUDINFO); + break; + case BTF_EVNT_BT_QUERY_TXPWR: + bt->bcnt[BTC_BCNT_TXPWR_UPDATE]++; + _update_bt_txpwr_info(rtwdev, buf, len); + } +} + +#define BTC_CX_FW_OFFLOAD 0 + +static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0; + char *p = buf, *end = buf + bufsz; + + if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) + return 0; + + p += scnprintf(p, end - p, + "\n========== [BTC COEX INFO (%s)] ==========\n", + chip_id_str(chip->chip_id)); + + ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION); + ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION); + ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION); + id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION); + p += scnprintf(p, end - p, " %-15s : Coex:%d.%d.%d(branch:%d), ", + "[coex_version]", ver_main, ver_sub, ver_hotfix, + id_branch); + + ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); + ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex); + ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex); + id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex); + p += scnprintf(p, end - p, "WL_FW_coex:%d.%d.%d(branch:%d)", + ver_main, ver_sub, ver_hotfix, id_branch); + + ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired); + ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired); + ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired); + p += scnprintf(p, end - p, "(%s, desired:%d.%d.%d), ", + (wl->ver_info.fw_coex >= chip->wlcx_desired ? + "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix); + + p += scnprintf(p, end - p, "BT_FW_coex:%d(%s, desired:%d)\n", + bt->ver_info.fw_coex, + (bt->ver_info.fw_coex >= ver->bt_desired ? + "Match" : "Mismatch"), ver->bt_desired); + + ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw); + ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw); + ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw); + id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw); + p += scnprintf(p, end - p, + " %-15s : WL_FW:%d.%d.%d.%d(built:%.12s-%.12s), BT_FW:0x%x(%s)\n", + "[sub_module]", + ver_main, ver_sub, ver_hotfix, id_branch, + wl->ver_info.build_time, wl->ver_info.build_date, + bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM"); + + p += scnprintf(p, end - p, + " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s", + "[hw_info]", + md->kt_ver, md->rfe_type, md->ant.isolation, + md->ant.num, md->ant.num > 1 ? "" : + md->ant.single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, "); + + p += scnprintf(p, end - p, + "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n", + btc->cx.bt_ext.func_type, rtwdev->dbcc_en, hal->tx_nss, + hal->rx_nss); + + return p - buf; +} + +static int _show_wl_role_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_link_info *plink = NULL; + struct rtw89_traffic_stats *t; + char *p = buf, *end = buf + bufsz; + u8 i, j; + + for (i = 0; i < btc->ver->max_role_num; i++) { + for (j = 0; j < RTW89_MAC_NUM; j++) { + plink = &btc->cx.wl.rlink_info[i][j]; + + if (!plink->active) + continue; + + p += scnprintf(p, end - p, + " [port_%d] : role=%d(phy-%d), connect=%s(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", + plink->pid, plink->role, plink->phy, + id_to_mlme_state(plink->connected), + plink->client_cnt - 1, plink->mode, + plink->ch, plink->bw); + + if (plink->connected == MLME_NO_LINK) { + p += scnprintf(p, end - p, "\n"); + continue; + } + + p += scnprintf(p, end - p, + ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", + plink->mac_id, plink->tx_time, plink->tx_retry); + + p += scnprintf(p, end - p, + " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", + plink->pid, 110 - plink->stat.rssi, + plink->stat.rssi, plink->busy, + plink->dir == RTW89_TFC_UL ? "UL" : "DL"); + + t = &plink->stat.traffic; + + p += scnprintf(p, end - p, + "tx[rate:%d/busy_level:%d], ", + t->tx_rate, t->tx_tfc_lv); + + p += scnprintf(p, end - p, + "rx[rate:%d/busy_level:%d/drop:%d]\n", + t->rx_rate, + t->rx_tfc_lv, plink->rx_rate_drop_cnt); + } + } + return p - buf; +} + +static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + char *p = buf, *end = buf + bufsz; + u8 mode; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) + return 0; + + p += scnprintf(p, end - p, "========== [WL Status] ==========\n"); + + mode = wl_rinfo->link_mode; + + p += scnprintf(p, end - p, " %-15s : link_mode:%s, ", "[status]", + id_to_linkmode(mode)); + + p += scnprintf(p, end - p, + "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", + wl->status.map.rf_off, wl->status.map.lps, + wl->status.map.scan ? "Y" : "N", + wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); + + p += scnprintf(p, end - p, + "handshake:%s, roam:%s, 4way:%s, init_ok:%s\n", + wl->status.map.handshake ? "Y" : "N", + wl->status.map.roaming ? "Y" : "N", + wl->status.map._4way ? "Y" : "N", + wl->status.map.init_ok ? "Y" : "N"); + + p += _show_wl_role_info(rtwdev, p, end - p); + + return p - buf; +} + +enum btc_bt_a2dp_type { + BTC_A2DP_LEGACY = 0, + BTC_A2DP_TWS_SNIFF = 1, + BTC_A2DP_TWS_RELAY = 2, +}; + +static int _show_bt_profile_info(struct rtw89_dev *rtwdev, char *buf, + size_t bufsz, u8 bid) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = (bid == BTC_BT_1ST) ? + &btc->cx.bt0 : &btc->cx.bt1; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_bt_hfp_desc hfp = bt_linfo->hfp_desc; + struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; + char *p = buf, *end = buf + bufsz; + + if (hfp.exist) { + p += scnprintf(p, end - p, + " %-15s : type:%s, sut_pwr:%d, golden-rx:%d", + "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"), + bt_linfo->sut_pwr_level[0], + bt_linfo->golden_rx_shift[0]); + } + + if (hid.exist) { + p += scnprintf(p, end - p, + "\n %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n", + "[HID]", + hid.type & BTC_HID_218 ? "2/18," : "", + hid.type & BTC_HID_418 ? "4/18," : "", + hid.type & BTC_HID_BLE ? "BLE," : "", + hid.type & BTC_HID_RCU ? "RCU," : "", + hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "", + hid.pair_cnt, bt_linfo->sut_pwr_level[1], + bt_linfo->golden_rx_shift[1]); + } + + if (a2dp.exist) { + p += scnprintf(p, end - p, + " %-15s : type:%s, bit-pool:%d, flush-time:%d, ", + "[A2DP]", + a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS", + a2dp.bitpool, a2dp.flush_time); + + p += scnprintf(p, end - p, + "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n", + a2dp.vendor_id, a2dp.device_name, + bt_linfo->sut_pwr_level[2], + bt_linfo->golden_rx_shift[2]); + } + + if (pan.exist) { + p += scnprintf(p, end - p, + " %-15s : sut_pwr:%d, golden-rx:%d\n", + "[PAN]", + bt_linfo->sut_pwr_level[3], + bt_linfo->golden_rx_shift[3]); + } + + return p - buf; +} + +static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, u8 bid) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt = (bid == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_module *md = &btc->mdinfo; + u8 bt_pos = (bid == BTC_BT_1ST) ? md->bt0_pos : md->bt1_pos; + s8 br_dbm = bt->link_info.bt_txpwr_desc.br_dbm; + s8 le_dbm = bt->link_info.bt_txpwr_desc.le_dbm; + u8 hw_band = wl->role_info.pta_req_band; + struct rtw89_btc_wl_afh_info *wl_afh; + char *p = buf, *end = buf + bufsz; + u8 *afh = bt_linfo->afh_map; + u8 *afh_le = bt_linfo->afh_map_le; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) + return 0; + + if (bid == BTC_BT_2ND) { + if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)) + return 0; + if (!bt->enable.now) + return 0; + } + + p += scnprintf(p, end - p, "========== [BT_%s Status] ==========\n", + bid == BTC_BT_1ST ? "1ST" : "2ND"); + + p += scnprintf(p, end - p, + " %-15s : enable:%s, btg:%s%s, connect:%s, ", + "[status]", bt->enable.now ? "Y" : "N", + bt->btg_type ? "Y" : "N", + (bt->enable.now && (bt->btg_type != bt_pos) ? + "(efuse-mismatch!!)" : ""), + (bt_linfo->status.map.connect ? "Y" : "N")); + + p += scnprintf(p, end - p, + "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n", + bt->igno_wl ? "Y" : "N", + bt->mbx_avl ? "Y" : "N", bt->rfk_info.val); + + p += scnprintf(p, end - p, " %-15s : profile:%s%s%s%s%s ", + "[profile]", + (bt_linfo->link_cnt.now == 0) ? "None," : "", + bt_linfo->hfp_desc.exist ? "HFP," : "", + bt_linfo->hid_desc.exist ? "HID," : "", + bt_linfo->a2dp_desc.exist ? + (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "", + bt_linfo->pan_desc.exist ? "PAN," : ""); + + p += scnprintf(p, end - p, + "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n", + bt_linfo->multi_link.now ? "Y" : "N", + bt_linfo->slave_role ? "Slave" : "Master", + bt_linfo->status.map.ble_connect ? "Y" : "N", + bt_linfo->cqddr ? "Y" : "N", + bt_linfo->a2dp_desc.active ? "Y" : "N", + bt_linfo->pan_desc.active ? "Y" : "N"); + + p += scnprintf(p, end - p, + " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s", + "[link]", bt_linfo->rssi - 100, + bt->rssi_level, + bt_linfo->tx_3m ? 3 : 2, + bt_linfo->status.map.inq_pag ? " inq-page!!" : "", + bt_linfo->status.map.acl_busy ? " acl_busy!!" : "", + bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : ""); + + p += scnprintf(p, end - p, + "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", + bt_linfo->relink.now ? " ReLink!!" : "", + afh[0], afh[1], afh[2], afh[3], afh[4], + afh[5], afh[6], afh[7], afh[8], afh[9]); + + if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) + p += scnprintf(p, end - p, + "LE[%02x%02x_%02x_%02x%02x]", + afh_le[0], afh_le[1], afh_le[2], + afh_le[3], afh_le[4]); + + wl_afh = &wl->afh_info[hw_band][RTW89_BAND_2G]; + p += scnprintf(p, end - p, "wl_ch_map[hwb:%d/en:%d/ch:%d/bw:%d/rf_band:%d]\n", + hw_band, wl_afh->en, wl_afh->ch, wl_afh->bw, wl_afh->band); + + p += scnprintf(p, end - p, + " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", + "[stat_cnt]", bt->bcnt[BTC_BCNT_RETRY], + bt->bcnt[BTC_BCNT_RELINK], + bt->bcnt[BTC_BCNT_RATECHG], + bt->bcnt[BTC_BCNT_REINIT], + bt->bcnt[BTC_BCNT_REENABLE]); + + p += scnprintf(p, end - p, + "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n", + bt->bcnt[BTC_BCNT_ROLESW], bt->bcnt[BTC_BCNT_AFH], + bt->bcnt[BTC_BCNT_INQPAG], bt->bcnt[BTC_BCNT_INQ], + bt->bcnt[BTC_BCNT_PAGE], bt->bcnt[BTC_BCNT_IGNOWL]); + + p += _show_bt_profile_info(rtwdev, p, end - p, bid); + + p += scnprintf(p, end - p, + " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n", + "[bt_info]", bt->raw_info[2], bt->raw_info[3], + bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], + bt->raw_info[7], + bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", + bt->bcnt[BTC_BCNT_INFOUPDATE], + bt->bcnt[BTC_BCNT_INFOSAME]); + + p += scnprintf(p, end - p, + " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", + "[trx_req_cnt]", bt->bcnt[BTC_BCNT_HIPRI_RX], + bt->bcnt[BTC_BCNT_HIPRI_TX], + bt->bcnt[BTC_BCNT_LOPRI_RX], + bt->bcnt[BTC_BCNT_LOPRI_TX], + bt->bcnt[BTC_BCNT_POLLUTED]); + + if (ver->fcxbtscan == 1) { + p += scnprintf(p, end - p, + "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)", + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl)); + } else if (ver->fcxbtscan == 2) { + p += scnprintf(p, end - p, + "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)", + le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl), + le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl), + le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl)); + } + p += scnprintf(p, end - p, "\n"); + + if (bt->bcnt[BTC_BCNT_TXPWR_UPDATE]) { + p += scnprintf(p, end - p, + " %-15s : br_index:0x%x, le_index:0x%x", + "[bt_txpwr_lvl]", + bt->link_info.bt_txpwr_desc.br_gain_index, + bt->link_info.bt_txpwr_desc.le_gain_index); + p += scnprintf(p, end - p, ", br_dbm:%d dBm", br_dbm); + p += scnprintf(p, end - p, ", le_dbm:%d dBm", le_dbm); + } else { + p += scnprintf(p, end - p, + " %-15s : br_index:NA, le_index:NA, br_dbm:%d dBm[def], le_dbm:%d dBm[def]", + "[bt_txpwr_lvl]", + bt->link_info.bt_txpwr_desc.br_dbm, + bt->link_info.bt_txpwr_desc.le_dbm); + } + p += scnprintf(p, end - p, "\n"); + + return p - buf; +} + +#define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e +#define CASE_BTC_ACT_STR(e) case BTC_ACT_ ## e | BTC_ACT_EXT_BIT: return #e +#define CASE_BTC_POLICY_STR(e) \ + case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e +#define CASE_BTC_SLOT_STR(e) case CXST_ ## e: return #e +#define CASE_BTC_EVT_STR(e) case CXEVNT_## e: return #e +#define CASE_BTC_INIT(e) case BTC_MODE_## e: return #e +#define CASE_BTC_ANTPATH_STR(e) case BTC_ANT_##e: return #e +#define CASE_BTC_POLUT_STR(e) case BTC_PLT_## e: return #e +#define CASE_BTC_REGTYPE_STR(e) case REG_## e: return #e +#define CASE_BTC_GDBG_STR(e) case BTC_DBG_## e: return #e +#define CASE_BTC_H2CCMD(e) case SET_##e: return #e + +static const char *id_to_polut(u32 id) +{ + switch (id) { + CASE_BTC_POLUT_STR(NONE); + CASE_BTC_POLUT_STR(GNT_BT_TX); + CASE_BTC_POLUT_STR(GNT_BT_RX); + CASE_BTC_POLUT_STR(GNT_WL); + CASE_BTC_POLUT_STR(BT); + CASE_BTC_POLUT_STR(ALL); + default: + return "unknown"; + } +} + +static const char *id_to_regtype(u32 id) +{ + switch (id) { + CASE_BTC_REGTYPE_STR(MAC); + CASE_BTC_REGTYPE_STR(BB); + CASE_BTC_REGTYPE_STR(RF); + CASE_BTC_REGTYPE_STR(BT_RF); + CASE_BTC_REGTYPE_STR(BT_MODEM); + CASE_BTC_REGTYPE_STR(BT_BLUEWIZE); + CASE_BTC_REGTYPE_STR(BT_VENDOR); + CASE_BTC_REGTYPE_STR(BT_LE); + default: + return "unknown"; + } +} + +static const char *id_to_gdbg(u32 id) +{ + switch (id) { + CASE_BTC_GDBG_STR(GNT_BT); + CASE_BTC_GDBG_STR(GNT_WL); + CASE_BTC_GDBG_STR(GNT_BT1); + CASE_BTC_GDBG_STR(GNT_WL1); + CASE_BTC_GDBG_STR(BCN_EARLY); + CASE_BTC_GDBG_STR(WL_NULL0); + CASE_BTC_GDBG_STR(WL_NULL1); + CASE_BTC_GDBG_STR(WL_RXISR); + CASE_BTC_GDBG_STR(TDMA_ENTRY); + CASE_BTC_GDBG_STR(A2DP_EMPTY); + CASE_BTC_GDBG_STR(BT_RETRY); + CASE_BTC_GDBG_STR(BT_RELINK); + CASE_BTC_GDBG_STR(SLOT_WL); + CASE_BTC_GDBG_STR(SLOT_BT); + CASE_BTC_GDBG_STR(WL_ERR); + CASE_BTC_GDBG_STR(WL_OK); + CASE_BTC_GDBG_STR(SLOT_B2W); + CASE_BTC_GDBG_STR(SLOT_W1); + CASE_BTC_GDBG_STR(SLOT_W2); + CASE_BTC_GDBG_STR(SLOT_W2B); + CASE_BTC_GDBG_STR(SLOT_B1); + CASE_BTC_GDBG_STR(SLOT_B2); + CASE_BTC_GDBG_STR(SLOT_B3); + CASE_BTC_GDBG_STR(SLOT_B4); + CASE_BTC_GDBG_STR(SLOT_LK); + CASE_BTC_GDBG_STR(SLOT_E2G); + CASE_BTC_GDBG_STR(SLOT_E5G); + CASE_BTC_GDBG_STR(SLOT_EBT); + CASE_BTC_GDBG_STR(SLOT_WLK); + CASE_BTC_GDBG_STR(SLOT_B1FDD); + CASE_BTC_GDBG_STR(BT_CHANGE); + CASE_BTC_GDBG_STR(WL_CCA); + default: + return "unknown"; + } +} + +static const char *steps_to_str(u16 step) +{ + switch (step) { + CASE_BTC_RSN_STR(NONE); + CASE_BTC_RSN_STR(NTFY_INIT); + CASE_BTC_RSN_STR(NTFY_SWBAND); + CASE_BTC_RSN_STR(NTFY_WL_STA); + CASE_BTC_RSN_STR(NTFY_RADIO_STATE); + CASE_BTC_RSN_STR(UPDATE_BT_SCBD); + CASE_BTC_RSN_STR(NTFY_WL_RFK); + CASE_BTC_RSN_STR(UPDATE_BT_INFO); + CASE_BTC_RSN_STR(NTFY_SCAN_START); + CASE_BTC_RSN_STR(NTFY_SCAN_FINISH); + CASE_BTC_RSN_STR(NTFY_SPECIFIC_PACKET); + CASE_BTC_RSN_STR(NTFY_POWEROFF); + CASE_BTC_RSN_STR(NTFY_ROLE_INFO); + CASE_BTC_RSN_STR(CMD_SET_COEX); + CASE_BTC_RSN_STR(ACT1_WORK); + CASE_BTC_RSN_STR(BT_DEVINFO_WORK); + CASE_BTC_RSN_STR(RFK_CHK_WORK); + CASE_BTC_RSN_STR(UPDATE_BT_LEAUDINFO); + + CASE_BTC_ACT_STR(NONE); + CASE_BTC_ACT_STR(WL_ONLY); + CASE_BTC_ACT_STR(WL_5G); + CASE_BTC_ACT_STR(WL_OTHER); + CASE_BTC_ACT_STR(WL_IDLE); + CASE_BTC_ACT_STR(WL_NC); + CASE_BTC_ACT_STR(WL_RFK); + CASE_BTC_ACT_STR(WL_INIT); + CASE_BTC_ACT_STR(WL_OFF); + CASE_BTC_ACT_STR(FREERUN); + CASE_BTC_ACT_STR(BT_WHQL); + CASE_BTC_ACT_STR(BT_RFK); + CASE_BTC_ACT_STR(BT_OFF); + CASE_BTC_ACT_STR(BT_IDLE); + CASE_BTC_ACT_STR(BT_HFP); + CASE_BTC_ACT_STR(BT_HID); + CASE_BTC_ACT_STR(BT_A2DP); + CASE_BTC_ACT_STR(BT_A2DPSINK); + CASE_BTC_ACT_STR(BT_PAN); + CASE_BTC_ACT_STR(BT_A2DP_HID); + CASE_BTC_ACT_STR(BT_A2DP_PAN); + CASE_BTC_ACT_STR(BT_PAN_HID); + CASE_BTC_ACT_STR(BT_A2DP_PAN_HID); + CASE_BTC_ACT_STR(BT_BIS); + CASE_BTC_ACT_STR(BT_CIS); + CASE_BTC_ACT_STR(WL_25G_MCC); + CASE_BTC_ACT_STR(WL_2G_MCC); + CASE_BTC_ACT_STR(WL_2G_SCC); + CASE_BTC_ACT_STR(WL_2G_AP); + CASE_BTC_ACT_STR(WL_2G_GO); + CASE_BTC_ACT_STR(WL_2G_GC); + CASE_BTC_ACT_STR(WL_2G_NAN); + + CASE_BTC_POLICY_STR(OFF_BT); + CASE_BTC_POLICY_STR(OFF_WL); + CASE_BTC_POLICY_STR(OFF_EQ0); + CASE_BTC_POLICY_STR(OFF_EQ1); + CASE_BTC_POLICY_STR(OFF_EQ2); + CASE_BTC_POLICY_STR(OFF_EQ3); + CASE_BTC_POLICY_STR(OFF_EQ4); + CASE_BTC_POLICY_STR(OFF_EQ5); + CASE_BTC_POLICY_STR(OFF_BWB0); + CASE_BTC_POLICY_STR(OFF_BWB1); + CASE_BTC_POLICY_STR(OFF_BWB2); + CASE_BTC_POLICY_STR(OFF_BWB3); + CASE_BTC_POLICY_STR(OFF_WL2); + CASE_BTC_POLICY_STR(OFFB_BWB0); + CASE_BTC_POLICY_STR(OFFE_DEF); + CASE_BTC_POLICY_STR(OFFE_DEF2); + CASE_BTC_POLICY_STR(OFFE_2GBWISOB); + CASE_BTC_POLICY_STR(OFFE_2GISOB); + CASE_BTC_POLICY_STR(OFFE_2GBWMIXB); + CASE_BTC_POLICY_STR(OFFE_WL); + CASE_BTC_POLICY_STR(OFFE_2GBWMIXB2); + CASE_BTC_POLICY_STR(FIX_TD3030); + CASE_BTC_POLICY_STR(FIX_TD5050); + CASE_BTC_POLICY_STR(FIX_TD2030); + CASE_BTC_POLICY_STR(FIX_TD4010); + CASE_BTC_POLICY_STR(FIX_TD7010); + CASE_BTC_POLICY_STR(FIX_TD2060); + CASE_BTC_POLICY_STR(FIX_TD3060); + CASE_BTC_POLICY_STR(FIX_TD2080); + CASE_BTC_POLICY_STR(FIX_TDW1B1); + CASE_BTC_POLICY_STR(FIX_TD4010ISO); + CASE_BTC_POLICY_STR(FIX_TD4010ISO_DL); + CASE_BTC_POLICY_STR(FIX_TD4010ISO_UL); + CASE_BTC_POLICY_STR(PFIX_TD3030); + CASE_BTC_POLICY_STR(PFIX_TD5050); + CASE_BTC_POLICY_STR(PFIX_TD2030); + CASE_BTC_POLICY_STR(PFIX_TD2060); + CASE_BTC_POLICY_STR(PFIX_TD3070); + CASE_BTC_POLICY_STR(PFIX_TD2080); + CASE_BTC_POLICY_STR(PFIX_TDW1B1); + CASE_BTC_POLICY_STR(AUTO_TD50B1); + CASE_BTC_POLICY_STR(AUTO_TD60B1); + CASE_BTC_POLICY_STR(AUTO_TD20B1); + CASE_BTC_POLICY_STR(AUTO_TDW1B1); + CASE_BTC_POLICY_STR(PAUTO_TD50B1); + CASE_BTC_POLICY_STR(PAUTO_TD60B1); + CASE_BTC_POLICY_STR(PAUTO_TD20B1); + CASE_BTC_POLICY_STR(PAUTO_TDW1B1); + CASE_BTC_POLICY_STR(AUTO2_TD3050); + CASE_BTC_POLICY_STR(AUTO2_TD3070); + CASE_BTC_POLICY_STR(AUTO2_TD5050); + CASE_BTC_POLICY_STR(AUTO2_TD6060); + CASE_BTC_POLICY_STR(AUTO2_TD2080); + CASE_BTC_POLICY_STR(AUTO2_TDW1B4); + CASE_BTC_POLICY_STR(PAUTO2_TD3050); + CASE_BTC_POLICY_STR(PAUTO2_TD3070); + CASE_BTC_POLICY_STR(PAUTO2_TD5050); + CASE_BTC_POLICY_STR(PAUTO2_TD6060); + CASE_BTC_POLICY_STR(PAUTO2_TD2080); + CASE_BTC_POLICY_STR(PAUTO2_TDW1B4); + default: + return "unknown step"; + } +} + +static const char *id_to_slot(u32 id) +{ + switch (id) { + CASE_BTC_SLOT_STR(OFF); + CASE_BTC_SLOT_STR(B2W); + CASE_BTC_SLOT_STR(W1); + CASE_BTC_SLOT_STR(W2); + CASE_BTC_SLOT_STR(W2B); + CASE_BTC_SLOT_STR(B1); + CASE_BTC_SLOT_STR(B2); + CASE_BTC_SLOT_STR(B3); + CASE_BTC_SLOT_STR(B4); + CASE_BTC_SLOT_STR(LK); + CASE_BTC_SLOT_STR(BLK); + CASE_BTC_SLOT_STR(E2G); + CASE_BTC_SLOT_STR(E5G); + CASE_BTC_SLOT_STR(EBT); + CASE_BTC_SLOT_STR(ENULL); + CASE_BTC_SLOT_STR(WLK); + CASE_BTC_SLOT_STR(W1FDD); + CASE_BTC_SLOT_STR(B1FDD); + default: + return "unknown"; + } +} + +static const char *id_to_evt(u32 id) +{ + switch (id) { + CASE_BTC_EVT_STR(TDMA_ENTRY); + CASE_BTC_EVT_STR(WL_TMR); + CASE_BTC_EVT_STR(B1_TMR); + CASE_BTC_EVT_STR(B2_TMR); + CASE_BTC_EVT_STR(B3_TMR); + CASE_BTC_EVT_STR(B4_TMR); + CASE_BTC_EVT_STR(W2B_TMR); + CASE_BTC_EVT_STR(B2W_TMR); + CASE_BTC_EVT_STR(BCN_EARLY); + CASE_BTC_EVT_STR(A2DP_EMPTY); + CASE_BTC_EVT_STR(LK_END); + CASE_BTC_EVT_STR(RX_ISR); + CASE_BTC_EVT_STR(RX_FC0); + CASE_BTC_EVT_STR(RX_FC1); + CASE_BTC_EVT_STR(BT_RELINK); + CASE_BTC_EVT_STR(BT_RETRY); + CASE_BTC_EVT_STR(E2G); + CASE_BTC_EVT_STR(E5G); + CASE_BTC_EVT_STR(EBT); + CASE_BTC_EVT_STR(ENULL); + CASE_BTC_EVT_STR(DRV_WLK); + CASE_BTC_EVT_STR(BCN_OK); + CASE_BTC_EVT_STR(BT_CHANGE); + CASE_BTC_EVT_STR(EBT_EXTEND); + CASE_BTC_EVT_STR(E2G_NULL1); + CASE_BTC_EVT_STR(B1FDD_TMR); + default: + return "unknown"; + } +} + +static const char *id_to_mode(u8 id) +{ + switch (id) { + CASE_BTC_INIT(NORMAL); + CASE_BTC_INIT(WL); + CASE_BTC_INIT(BT); + CASE_BTC_INIT(WLOFF); + default: + return "unknown"; + } +} + +static const char *id_to_ant(u32 id) +{ + switch (id) { + CASE_BTC_ANTPATH_STR(WPOWERON); + CASE_BTC_ANTPATH_STR(WINIT); + CASE_BTC_ANTPATH_STR(WONLY); + CASE_BTC_ANTPATH_STR(WOFF); + CASE_BTC_ANTPATH_STR(W2G); + CASE_BTC_ANTPATH_STR(FDD); + CASE_BTC_ANTPATH_STR(W25G); + CASE_BTC_ANTPATH_STR(FREERUN); + CASE_BTC_ANTPATH_STR(WRFK); + CASE_BTC_ANTPATH_STR(WRFK2); + CASE_BTC_ANTPATH_STR(PTA); + CASE_BTC_ANTPATH_STR(MAX); + default: + return "unknown"; + } +} + +static const char *id_to_h2c(u32 id) +{ + switch (id) { + CASE_BTC_H2CCMD(REPORT_EN); + CASE_BTC_H2CCMD(SLOT_TABLE); + CASE_BTC_H2CCMD(MREG_TABLE); + CASE_BTC_H2CCMD(CX_POLICY); + CASE_BTC_H2CCMD(GPIO_DBG); + CASE_BTC_H2CCMD(DRV_INFO); + CASE_BTC_H2CCMD(DRV_EVENT); + CASE_BTC_H2CCMD(BT_WREG_ADDR); + CASE_BTC_H2CCMD(BT_WREG_VAL); + CASE_BTC_H2CCMD(BT_RREG_ADDR); + CASE_BTC_H2CCMD(BT_WL_CH_INFO); + CASE_BTC_H2CCMD(BT_INFO_REPORT); + CASE_BTC_H2CCMD(BT_IGNORE_WLAN_ACT); + CASE_BTC_H2CCMD(BT_TX_PWR); + CASE_BTC_H2CCMD(BT_LNA_CONSTRAIN); + CASE_BTC_H2CCMD(BT_QUERY_DEV_LIST); + CASE_BTC_H2CCMD(BT_QUERY_DEV_INFO); + CASE_BTC_H2CCMD(BT_PSD_REPORT); + CASE_BTC_H2CCMD(H2C_TEST); + CASE_BTC_H2CCMD(IOFLD_RF); + CASE_BTC_H2CCMD(IOFLD_BB); + CASE_BTC_H2CCMD(IOFLD_MAC); + CASE_BTC_H2CCMD(IOFLD_SCBD); + CASE_BTC_H2CCMD(H2C_MACRO); + default: + return "unknown"; + } +} + +static +int scnprintf_segment(char *buf, size_t bufsz, const char *prefix, const u16 *data, + u8 len, u8 seg_len, u8 start_idx, u8 ring_len) +{ + char *p = buf, *end = buf + bufsz; + u8 cur_index; + u8 i; + + for (i = 0; i < len ; i++) { + if ((i % seg_len) == 0) + p += scnprintf(p, end - p, " %-15s : ", prefix); + cur_index = (start_idx + i) % ring_len; + if (i % 3 == 0) + p += scnprintf(p, end - p, "-> %-20s", + steps_to_str(*(data + cur_index))); + else if (i % 3 == 1) + p += scnprintf(p, end - p, "-> %-15s", + steps_to_str(*(data + cur_index))); + else + p += scnprintf(p, end - p, "-> %-13s", + steps_to_str(*(data + cur_index))); + if (i == (len - 1) || (i % seg_len) == (seg_len - 1)) + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +static int _show_dm_step(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; + u8 start_idx; + u8 len; + + len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos; + start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0; + + p += scnprintf_segment(p, end - p, "[dm_steps]", dm->dm_step.step, len, + 6, start_idx, ARRAY_SIZE(dm->dm_step.step)); + + return p - buf; +} + +static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt0; + char *p = buf, *end = buf + bufsz; + + if (!(dm->coex_info_map & BTC_COEX_INFO_DM)) + return 0; + + p += scnprintf(p, end - p, + "========== [Mechanism Status %s] ==========\n", + (btc->manual_ctrl ? "(Manual)" : "(Auto)")); + + p += scnprintf(p, end - p, + " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n", + "[status]", + btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated", + steps_to_str(dm->run_reason), + steps_to_str(dm->run_action | BTC_ACT_EXT_BIT), + id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)), + id_to_mode(wl->coex_mode), + dm->cnt_dm[BTC_DCNT_RUN]); + + p += _show_dm_step(rtwdev, p, end - p); + + p += scnprintf(p, end - p, + " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ", + "[dm_flag]", dm->wl_only, dm->bt_only, btc->ctrl.igno_bt, + dm->freerun, btc->btc_ctrl_lps, dm->wl_mimo_ps); + + p += scnprintf(p, end - p, "leak_ap:%d, fw_offload:%s%s\n", + dm->leak_ap, + (BTC_CX_FW_OFFLOAD ? "Y" : "N"), + (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ? + "" : "(Mismatch!!)")); + + p += scnprintf(p, end - p, + " %-15s : wl[rssi_lvl:%d/para:%d/tx_pwr:[%d %d]/rx_lvl:[%d %d]/lna2:%d/stb_chg:%d]\n", + "[dm_rf_ctrl]", + wl->rssi_level, dm->trx_para_level, + dm->rf_trx_para.wl_tx_power[RTW89_PHY_0], + dm->rf_trx_para.wl_tx_power[RTW89_PHY_1], + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0], + dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1], + dm->wl_lna2, dm->wl_stb_chg); + + p += scnprintf(p, end - p, + " %-15s : pre_agc:%d, btg_rx:%d\n", + "[dm_bb_ctrl]", dm->wl_pre_agc, dm->wl_btg_rx); + + p += scnprintf(p, end - p, + " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n", + "[dm_ctrl]", dm->wl_tx_limit.enable, + dm->wl_tx_limit.tx_time, + dm->wl_tx_limit.tx_retry, btc->bt_req_len[RTW89_PHY_0], + bt->scan_rx_low_pri); + + return p - buf; +} + +static int _show_error(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + union rtw89_btc_fbtc_cysta_info *pcysta; + char *p = buf, *end = buf + bufsz; + u32 except_cnt, exception_map; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + if (ver->fcxcysta == 2) { + pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; + except_cnt = le32_to_cpu(pcysta->v2.except_cnt); + exception_map = le32_to_cpu(pcysta->v2.exception); + } else if (ver->fcxcysta == 3) { + pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; + except_cnt = le32_to_cpu(pcysta->v3.except_cnt); + exception_map = le32_to_cpu(pcysta->v3.except_map); + } else if (ver->fcxcysta == 4) { + pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; + except_cnt = pcysta->v4.except_cnt; + exception_map = le32_to_cpu(pcysta->v4.except_map); + } else if (ver->fcxcysta == 5) { + pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; + except_cnt = pcysta->v5.except_cnt; + exception_map = le32_to_cpu(pcysta->v5.except_map); + } else if (ver->fcxcysta == 7) { + pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7; + except_cnt = pcysta->v7.except_cnt; + exception_map = le32_to_cpu(pcysta->v7.except_map); + } else { + return 0; + } + + if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && + !pfwinfo->len_mismch && !pfwinfo->fver_mismch) + return 0; + + p += scnprintf(p, end - p, " %-15s : ", "[error]"); + + if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) { + p += scnprintf(p, end - p, + "overflow-cnt: %d, ", + pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); + } + + if (pfwinfo->len_mismch) { + p += scnprintf(p, end - p, + "len-mismatch: 0x%x, ", + pfwinfo->len_mismch); + } + + if (pfwinfo->fver_mismch) { + p += scnprintf(p, end - p, + "fver-mismatch: 0x%x, ", + pfwinfo->fver_mismch); + } + + /* cycle statistics exceptions */ + if (exception_map || except_cnt) { + p += scnprintf(p, end - p, + "exception-type: 0x%x, exception-cnt = %d", + exception_map, except_cnt); + } + p += scnprintf(p, end - p, "\n"); + + return p - buf; +} + +static int _show_fbtc_tdma(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_tdma *t = NULL; + char *p = buf, *end = buf + bufsz; + + pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; + if (!pcinfo->valid) + return 0; + + if (ver->fcxtdma == 1) + t = &pfwinfo->rpt_fbtc_tdma.finfo.v1; + else + t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma; + + p += scnprintf(p, end - p, + " %-15s : ", "[tdma_policy]"); + p += scnprintf(p, end - p, + "type:%d, rx_flow_ctrl:%d, txflctrl:%d, ", + (u32)t->type, + t->rxflctrl, t->txflctrl); + + p += scnprintf(p, end - p, + "bind:%d, leak_n:%d, ext_ctrl:%d, ", + t->bind, t->leak_n, t->ext_ctrl); + + p += scnprintf(p, end - p, + "policy_type:%d\n", + (u32)btc->policy_type); + + return p - buf; +} + +static int _show_fbtc_slots(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; + u16 dur, cxtype; + u32 tbl; + u8 i = 0; + + for (i = 0; i < CXST_MAX; i++) { + if (ver->fcxslots == 1) { + dur = le16_to_cpu(dm->slot_now.v1[i].dur); + tbl = le32_to_cpu(dm->slot_now.v1[i].cxtbl); + cxtype = le16_to_cpu(dm->slot_now.v1[i].cxtype); + } else if (ver->fcxslots == 2 || ver->fcxslots == 7) { + dur = le16_to_cpu(dm->slot_now.v7[i].dur); + tbl = le32_to_cpu(dm->slot_now.v7[i].cxtbl); + cxtype = le16_to_cpu(dm->slot_now.v7[i].cxtype); + } else { + return 0; + } + + if (i % 5 == 0) + p += scnprintf(p, end - p, + " %-15s : %5s[%03d/0x%x/%d]", + "[slot_list]", + id_to_slot((u32)i), + dur, tbl, cxtype); + else + p += scnprintf(p, end - p, + ", %5s[%03d/0x%x/%d]", + id_to_slot((u32)i), + dur, tbl, cxtype); + + if (i % 5 == 4) + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +static int _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL; + union rtw89_btc_fbtc_rxflct r; + u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + u8 i, cnt = 0, slot_pair; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2; + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta_le32->cycles), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) + continue; + p += scnprintf(p, end - p, ", %s:%d", id_to_slot((u32)i), + le32_to_cpu(pcysta_le32->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) { + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta_le32->leakrx_cnt)); + } + + if (le32_to_cpu(pcysta_le32->collision_cnt)) { + p += scnprintf(p, end - p, ", collision:%d", + le32_to_cpu(pcysta_le32->collision_cnt)); + } + + if (le32_to_cpu(pcysta_le32->skip_cnt)) { + p += scnprintf(p, end - p, ", skip:%d", + le32_to_cpu(pcysta_le32->skip_cnt)); + } + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]), + le16_to_cpu(pcysta_le32->tavg_lk) / 1000, + le16_to_cpu(pcysta_le32->tavg_lk) % 1000); + p += scnprintf(p, end - p, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]), + le16_to_cpu(pcysta_le32->tmax_lk) / 1000, + le16_to_cpu(pcysta_le32->tmax_lk) % 1000); + p += scnprintf(p, end - p, ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); + + if (le16_to_cpu(pcysta_le32->cycles) <= 1) + goto out; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (le16_to_cpu(pcysta_le32->cycles) <= slot_pair) + c_begin = 1; + else + c_begin = le16_to_cpu(pcysta_le32->cycles) - slot_pair + 1; + + c_end = le16_to_cpu(pcysta_le32->cycles); + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) + p += scnprintf(p, end - p, + " %-15s : ->b%02d->w%02d", + "[cycle_step]", + le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), + le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); + else + p += scnprintf(p, end - p, + "->b%02d->w%02d", + le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), + le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); + if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) + p += scnprintf(p, end - p, "\n"); + } + + if (a2dp->exist) { + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta_le32->a2dpept), + le16_to_cpu(pcysta_le32->a2dpeptto)); + + p += scnprintf(p, end - p, + ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta_le32->tavg_a2dpept), + le16_to_cpu(pcysta_le32->tmax_a2dpept)); + r.val = dm->tdma_now.rxflctrl; + + if (r.type && r.tgln_n) { + p += scnprintf(p, end - p, + ", cycle[PSTDMA:%d/TDMA:%d], ", + le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); + + p += scnprintf(p, end - p, + "avg_t[PSTDMA:%d/TDMA:%d], ", + le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); + + p += scnprintf(p, end - p, + "max_t[PSTDMA:%d/TDMA:%d]", + le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); + } + p += scnprintf(p, end - p, "\n"); + } + +out: + return p - buf; +} + +static int _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx; + struct rtw89_btc_fbtc_cysta_v3 *pcysta; + struct rtw89_btc_rpt_cmn_info *pcinfo; + u8 i, cnt = 0, slot_pair, divide_cnt; + u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3; + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le32_to_cpu(pcysta->slot_cnt[i])) + continue; + + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le32_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (le32_to_cpu(pcysta->collision_cnt)) + p += scnprintf(p, end - p, ", collision:%d", + le32_to_cpu(pcysta->collision_cnt)); + + if (le32_to_cpu(pcysta->skip_cnt)) + p += scnprintf(p, end - p, ", skip:%d", + le32_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + p += scnprintf(p, end - p, + ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + + cycle = le16_to_cpu(pcysta->cycles); + if (cycle <= 1) + goto out; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (cycle <= slot_pair) + c_begin = 1; + else + c_begin = cycle - slot_pair + 1; + + c_end = cycle; + + if (a2dp->exist) + divide_cnt = 3; + else + divide_cnt = BTC_CYCLE_SLOT_MAX / 4; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); + + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) + p += scnprintf(p, end - p, "\n"); + } + + if (a2dp->exist) { + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d\n", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + } + +out: + return p - buf; +} + +static int _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; + struct rtw89_btc_fbtc_cysta_v4 *pcysta; + struct rtw89_btc_rpt_cmn_info *pcinfo; + u8 i, cnt = 0, slot_pair, divide_cnt; + u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4; + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le16_to_cpu(pcysta->slot_cnt[i])) + continue; + + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (pcysta->collision_cnt) + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); + + if (le16_to_cpu(pcysta->skip_cnt)) + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + p += scnprintf(p, end - p, + ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + + cycle = le16_to_cpu(pcysta->cycles); + if (cycle <= 1) + goto out; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (cycle <= slot_pair) + c_begin = 1; + else + c_begin = cycle - slot_pair + 1; + + c_end = cycle; + + if (a2dp->exist) + divide_cnt = 3; + else + divide_cnt = BTC_CYCLE_SLOT_MAX / 4; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); + + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) + p += scnprintf(p, end - p, "\n"); + } + + if (a2dp->exist) { + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d\n", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + } + +out: + return p - buf; +} + +static int _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; + struct rtw89_btc_fbtc_cysta_v5 *pcysta; + struct rtw89_btc_rpt_cmn_info *pcinfo; + u8 i, cnt = 0, slot_pair, divide_cnt; + u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5; + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le16_to_cpu(pcysta->slot_cnt[i])) + continue; + + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (pcysta->collision_cnt) + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); + + if (le16_to_cpu(pcysta->skip_cnt)) + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + + cycle = le16_to_cpu(pcysta->cycles); + if (cycle <= 1) + goto out; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (cycle <= slot_pair) + c_begin = 1; + else + c_begin = cycle - slot_pair + 1; + + c_end = cycle; + + if (a2dp->exist) + divide_cnt = 3; + else + divide_cnt = BTC_CYCLE_SLOT_MAX / 4; + + if (c_begin > c_end) + goto out; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); + + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) + p += scnprintf(p, end - p, "\n"); + } + + if (a2dp->exist) { + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d\n", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + } + +out: + return p - buf; +} + +static int _show_fbtc_cysta_v105(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; + struct rtw89_btc_fbtc_cysta_v105 *pcysta; + struct rtw89_btc_rpt_cmn_info *pcinfo; + u8 i, cnt = 0, slot_pair, divide_cnt; + u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v105; + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le16_to_cpu(pcysta->slot_cnt[i])) + continue; + + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (pcysta->collision_cnt) + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); + + if (le16_to_cpu(pcysta->skip_cnt)) + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + + cycle = le16_to_cpu(pcysta->cycles); + if (cycle <= 1) + goto out; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (cycle <= slot_pair) + c_begin = 1; + else + c_begin = cycle - slot_pair + 1; + + c_end = cycle; + + if (a2dp->exist) + divide_cnt = 3; + else + divide_cnt = BTC_CYCLE_SLOT_MAX / 4; + + if (c_begin > c_end) + goto out; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); + + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) + p += scnprintf(p, end - p, "\n"); + } + + if (a2dp->exist) { + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d\n", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + } + +out: + return p - buf; +} + +static int _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0; + struct rtw89_btc_bt_a2dp_desc *a2dp = &bt->link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_fbtc_cysta_v7 *pcysta = NULL; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_rpt_cmn_info *pcinfo; + char *p = buf, *end = buf + bufsz; + u16 cycle, c_begin, c_end, s_id; + u8 i, cnt = 0, divide_cnt; + u8 slot_pair; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return 0; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v7; + p += scnprintf(p, end - p, "\n %-15s : cycle:%d", "[slot_stat]", + le16_to_cpu(pcysta->cycles)); + + for (i = 0; i < CXST_MAX; i++) { + if (!le16_to_cpu(pcysta->slot_cnt[i])) + continue; + p += scnprintf(p, end - p, ", %s:%d", + id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (pcysta->collision_cnt) + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); + + if (pcysta->skip_cnt) + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, + "\n %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_stat]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d(>%dms:%d)/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + dm->bt_slot_flood, dm->cnt_dm[BTC_DCNT_BT_SLOT_FLOOD], + le16_to_cpu(pcysta->leak_slot.tamx) / 1000, + le16_to_cpu(pcysta->leak_slot.tamx) % 1000); + p += scnprintf(p, end - p, ", bcn[all:%d/ok:%d/in_bt:%d/in_bt_ok:%d]", + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + if (a2dp->exist) { + p += scnprintf(p, end - p, + "\n %-15s : a2dp_ept:%d, a2dp_late:%d(streak 2S:%d/max:%d)", + "[a2dp_stat]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout), + a2dp->no_empty_streak_2s, + a2dp->no_empty_streak_max); + + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + } + + if (le16_to_cpu(pcysta->cycles) <= 1) + goto out; + + /* 1 cycle = 1 wl-slot + 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (le16_to_cpu(pcysta->cycles) <= slot_pair) + c_begin = 1; + else + c_begin = le16_to_cpu(pcysta->cycles) - slot_pair + 1; + + c_end = le16_to_cpu(pcysta->cycles); + + if (a2dp->exist) + divide_cnt = 2; + else + divide_cnt = 6; + + if (c_begin > c_end) + goto out; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + s_id = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) { + if (a2dp->exist) + p += scnprintf(p, end - p, "\n %-15s : ", + "[slotT_wermtan]"); + else + p += scnprintf(p, end - p, "\n %-15s : ", + "[slotT_rxerr]"); + } + + p += scnprintf(p, end - p, "->b%d", + le16_to_cpu(pcysta->slot_step_time[s_id])); + + if (a2dp->exist) + p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)", + pcysta->wl_rx_err_ratio[s_id], + pcysta->a2dp_trx[s_id].empty_cnt, + pcysta->a2dp_trx[s_id].retry_cnt, + (pcysta->a2dp_trx[s_id].tx_rate ? 3 : 2), + pcysta->a2dp_trx[s_id].tx_cnt, + pcysta->a2dp_trx[s_id].ack_cnt, + pcysta->a2dp_trx[s_id].nack_cnt); + else + p += scnprintf(p, end - p, "(%d)", + pcysta->wl_rx_err_ratio[s_id]); + + p += scnprintf(p, end - p, "->w%d", + le16_to_cpu(pcysta->slot_step_time[s_id + 1])); + + if (a2dp->exist) + p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)", + pcysta->wl_rx_err_ratio[s_id + 1], + pcysta->a2dp_trx[s_id + 1].empty_cnt, + pcysta->a2dp_trx[s_id + 1].retry_cnt, + (pcysta->a2dp_trx[s_id + 1].tx_rate ? 3 : 2), + pcysta->a2dp_trx[s_id + 1].tx_cnt, + pcysta->a2dp_trx[s_id + 1].ack_cnt, + pcysta->a2dp_trx[s_id + 1].nack_cnt); + else + p += scnprintf(p, end - p, "(%d)", + pcysta->wl_rx_err_ratio[s_id + 1]); + } + +out: + return p - buf; +} + +static int _show_fbtc_nullsta(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo; + union rtw89_btc_fbtc_cynullsta_info *ns; + char *p = buf, *end = buf + bufsz; + u8 i = 0; + + if (!btc->dm.tdma_now.rxflctrl) + return 0; + + pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; + if (!pcinfo->valid) + return 0; + + ns = &pfwinfo->rpt_fbtc_nullsta.finfo; + if (ver->fcxnullsta == 1) { + for (i = 0; i < 2; i++) { + p += scnprintf(p, end - p, "\n %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v1.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v1.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v1.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v1.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v1.avg_t[i]) / 1000, + le32_to_cpu(ns->v1.avg_t[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]", + le32_to_cpu(ns->v1.max_t[i]) / 1000, + le32_to_cpu(ns->v1.max_t[i]) % 1000); + } + } else if (ver->fcxnullsta == 7) { + for (i = 0; i < 2; i++) { + p += scnprintf(p, end - p, "\n %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[Tx:%d/", + le32_to_cpu(ns->v7.result[i][4])); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v7.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v7.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v7.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v7.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v7.tavg[i]) / 1000, + le32_to_cpu(ns->v7.tavg[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]", + le32_to_cpu(ns->v7.tmax[i]) / 1000, + le32_to_cpu(ns->v7.tmax[i]) % 1000); + } + } else { + for (i = 0; i < 2; i++) { + p += scnprintf(p, end - p, "\n %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[Tx:%d/", + le32_to_cpu(ns->v2.result[i][4])); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v2.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v2.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v2.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v2.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v2.avg_t[i]) / 1000, + le32_to_cpu(ns->v2.avg_t[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]", + le32_to_cpu(ns->v2.max_t[i]) / 1000, + le32_to_cpu(ns->v2.max_t[i]) % 1000); + } + } + + return p - buf; +} + +static int _show_fbtc_step_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_steps_v2 *pstep = NULL; + const struct rtw89_btc_ver *ver = btc->ver; + char *p = buf, *end = buf + bufsz; + u8 type, val, cnt = 0, state = 0; + bool outloop = false; + u16 i, diff_t, n_start = 0, n_stop = 0; + u16 pos_old, pos_new, trace_step; + + pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; + if (!pcinfo->valid) + return 0; + + pstep = &pfwinfo->rpt_fbtc_step.finfo.v2; + pos_old = le16_to_cpu(pstep->pos_old); + pos_new = le16_to_cpu(pstep->pos_new); + + if (pcinfo->req_fver != pstep->fver) + return 0; + + /* store step info by using ring instead of FIFO*/ + do { + switch (state) { + case 0: + if (ver->fcxctrl == 7 || ver->fcxctrl == 1) + trace_step = 50; + else + trace_step = btc->ctrl.trace_step; + + n_start = pos_old; + if (pos_new >= pos_old) + n_stop = pos_new; + else + n_stop = trace_step - 1; + + state = 1; + break; + case 1: + for (i = n_start; i <= n_stop; i++) { + type = pstep->step[i].type; + val = pstep->step[i].val; + diff_t = le16_to_cpu(pstep->step[i].difft); + + if (type == CXSTEP_NONE || type >= CXSTEP_MAX) + continue; + + if (cnt % 10 == 0) + p += scnprintf(p, end - p, + " %-15s : ", "[steps]"); + + p += scnprintf(p, end - p, + "-> %s(%02d)(%02d)", + (type == CXSTEP_SLOT ? "SLT" : + "EVT"), (u32)val, diff_t); + if (cnt % 10 == 9) + p += scnprintf(p, end - p, "\n"); + cnt++; + } + + state = 2; + break; + case 2: + if (pos_new < pos_old && n_start != 0) { + n_start = 0; + n_stop = pos_new; + state = 1; + } else { + outloop = true; + } + break; + } + } while (!outloop); + + return p - buf; +} + +static int _show_fbtc_step_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_fbtc_steps_v3 *pstep; + u32 i, n_begin, n_end, array_idx, cnt = 0; + char *p = buf, *end = buf + bufsz; + u8 type, val; + u16 diff_t; + + if ((pfwinfo->rpt_en_map & + rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0) + return 0; + + pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; + if (!pcinfo->valid) + return 0; + + pstep = &pfwinfo->rpt_fbtc_step.finfo.v3; + if (pcinfo->req_fver != pstep->fver) + return 0; + + if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP) + n_begin = 1; + else + n_begin = le32_to_cpu(pstep->cnt) - FCXDEF_STEP + 1; + + n_end = le32_to_cpu(pstep->cnt); + + if (n_begin > n_end) + return 0; + + /* restore step info by using ring instead of FIFO */ + for (i = n_begin; i <= n_end; i++) { + array_idx = (i - 1) % FCXDEF_STEP; + type = pstep->step[array_idx].type; + val = pstep->step[array_idx].val; + diff_t = le16_to_cpu(pstep->step[array_idx].difft); + + if (type == CXSTEP_NONE || type >= CXSTEP_MAX) + continue; + + if (cnt % 10 == 0) + p += scnprintf(p, end - p, " %-15s : ", "[steps]"); + + p += scnprintf(p, end - p, "-> %s(%02d)", + (type == CXSTEP_SLOT ? + id_to_slot((u32)val) : + id_to_evt((u32)val)), diff_t); + + if (cnt % 10 == 9) + p += scnprintf(p, end - p, "\n"); + + cnt++; + } + + return p - buf; +} + +static int _show_fw_dm_msg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + char *p = buf, *end = buf + bufsz; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) + goto out; + + p += _show_error(rtwdev, p, end - p); + p += _show_fbtc_tdma(rtwdev, p, end - p); + p += _show_fbtc_slots(rtwdev, p, end - p); + + if (ver->fcxcysta == 2) + p += _show_fbtc_cysta_v2(rtwdev, p, end - p); + else if (ver->fcxcysta == 3) + p += _show_fbtc_cysta_v3(rtwdev, p, end - p); + else if (ver->fcxcysta == 4) + p += _show_fbtc_cysta_v4(rtwdev, p, end - p); + else if (ver->fcxcysta == 5) + p += _show_fbtc_cysta_v5(rtwdev, p, end - p); + else if (ver->fcxcysta == 105) + p += _show_fbtc_cysta_v105(rtwdev, p, end - p); + else if (ver->fcxcysta == 7) + p += _show_fbtc_cysta_v7(rtwdev, p, end - p); + + p += _show_fbtc_nullsta(rtwdev, p, end - p); + + if (ver->fcxstep == 2) + p += _show_fbtc_step_v2(rtwdev, p, end - p); + else if (ver->fcxstep == 3) + p += _show_fbtc_step_v3(rtwdev, p, end - p); + +out: + return p - buf; +} + +static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_mac_ax_wl_act *bt; + struct rtw89_mac_ax_gnt *gnt; + u32 val, status; + + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || + chip->chip_id == RTL8851B || chip->chip_id == RTL8852BT) { + rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); + rtw89_mac_read_lte(rtwdev, R_AX_GNT_VAL, &status); + + gnt = &gnt_cfg->band[0]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SW_CTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0_STA); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SW_CTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0_STA); + + gnt = &gnt_cfg->band[1]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SW_CTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1_STA); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SW_CTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1_STA); + } else if (chip->chip_id == RTL8852C) { + val = rtw89_read32(rtwdev, R_AX_GNT_SW_CTRL); + status = rtw89_read32(rtwdev, R_AX_GNT_VAL_V1); + + gnt = &gnt_cfg->band[0]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SWCTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SWCTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0); + + gnt = &gnt_cfg->band[1]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SWCTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SWCTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1); + + bt = &gnt_cfg->bt[0]; + bt->wlan_act_en = !!(val & B_BE_WL_ACT_SWCTRL); + bt->wlan_act = !!(status & B_BE_WL_ACT_VAL); + + bt = &gnt_cfg->bt[1]; + bt->wlan_act_en = !!(val & B_BE_WL_ACT2_SWCTRL); + bt->wlan_act = !!(status & B_BE_WL_ACT2_VAL); + } else if (chip->chip_id == RTL8922A) { + val = rtw89_read32(rtwdev, R_BE_GNT_SW_CTRL); + status = rtw89_read32(rtwdev, R_BE_PTA_GNT_VAL); + + gnt = &gnt_cfg->band[0]; + gnt->gnt_bt_sw_en = !!(val & B_BE_GNT_BT_BB0_SWCTRL); + gnt->gnt_bt = !!(status & B_BE_GNT_BT_BB0_VAL); + gnt->gnt_wl_sw_en = !!(val & B_BE_GNT_WL_BB0_SWCTRL); + gnt->gnt_wl = !!(status & B_BE_GNT_WL_BB0_VAL); + + gnt = &gnt_cfg->band[1]; + gnt->gnt_bt_sw_en = !!(val & B_BE_GNT_BT_BB1_SWCTRL); + gnt->gnt_bt = !!(status & B_BE_GNT_BT_BB1_VAL); + gnt->gnt_wl_sw_en = !!(val & B_BE_GNT_WL_BB1_SWCTRL); + gnt->gnt_wl = !!(status & B_BE_GNT_WL_BB1_VAL); + + bt = &gnt_cfg->bt[0]; + bt->wlan_act_en = !!(val & B_BE_WL_ACT_SWCTRL); + bt->wlan_act = !!(status & B_BE_WL_ACT_VAL); + + bt = &gnt_cfg->bt[1]; + bt->wlan_act_en = !!(val & B_BE_WL_ACT2_SWCTRL); + bt->wlan_act = !!(status & B_BE_WL_ACT2_VAL); + } else if (chip->chip_id == RTL8922D) { + /* Get from firmware */ + return; + } +} + +static int _show_gpio_dbg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + union rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; + char *p = buf, *end = buf + bufsz; + u32 en_map_raw, en_map; + u8 *gpio_map, i, sig; + + pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; + gdbg = &rtwdev->btc.fwinfo.rpt_fbtc_gpio_dbg.finfo; + if (!pcinfo->valid) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", + __func__); + goto out; + } + + if (ver->fcxgpiodbg == 7 || ver->fcxgpiodbg == 8) { + en_map_raw = le32_to_cpu(gdbg->v7.en_map); + gpio_map = gdbg->v7.gpio_map; + } else { + en_map_raw = le32_to_cpu(gdbg->v1.en_map); + gpio_map = gdbg->v1.gpio_map; + } + + en_map = _convert_gpio_enmap_from_ver(rtwdev, en_map_raw); + if (!en_map) + goto out; + + p += scnprintf(p, end - p, "\n %-15s : enable_map:0x%08x", + "[gpio_dbg]", en_map); + + for (i = 0; i < BTC_DBG_NUM; i++) { + if (!(en_map & BIT(i))) + continue; + + sig = ver->fcxgpiodbg >= 8 ? i : _get_gpiosig_for_ver(rtwdev, i); + if (sig >= BTC_DBG_NUM) + continue; + + p += scnprintf(p, end - p, ", %s->GPIO%d", id_to_gdbg(i), + gpio_map[sig]); + } + +out: + return p - buf; +} + +static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL; + struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0; + struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; + struct rtw89_mac_ax_gnt gnt; + char *p = buf, *end = buf + bufsz; + u8 i = 0, type = 0, cnt = 0; + u32 val, offset; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) + return 0; + + p += scnprintf(p, end - p, "========== [HW Status] ==========\n"); + + p += scnprintf(p, end - p, + " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_1ST], + wl->wcnt[BTC_WCNT_SCBDUPDATE], + bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD], + bt0->bcnt[BTC_BCNT_SCBDUPDATE]); + + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) { + p += scnprintf(p, end - p, + " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_2ND], + wl->wcnt[BTC_WCNT_SCBDUPDATE2], + bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD], + bt1->bcnt[BTC_BCNT_SCBDUPDATE]); + } + + btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); + _get_gnt(rtwdev, &gnt_cfg); + + gnt = gnt_cfg.band[0]; + p += scnprintf(p, end - p, + " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", + "[gnt_status]", + chip->chip_id == RTL8852C ? "HW" : + btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); + + gnt = gnt_cfg.band[1]; + p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", + gnt.gnt_wl_sw_en ? "SW" : "HW", + gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", + gnt.gnt_bt); + + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + if (!pcinfo->valid) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", + __func__); + goto out; + } + + pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", + __func__, pmreg->reg_num); + + for (i = 0; i < pmreg->reg_num; i++) { + type = (u8)le16_to_cpu(chip->mon_reg[i].type); + offset = le32_to_cpu(chip->mon_reg[i].offset); + val = le32_to_cpu(pmreg->mreg_val[i]); + + if (cnt % 6 == 0) + p += scnprintf(p, end - p, + " %-15s : %d_0x%04x=0x%08x", + "[reg]", (u32)type, offset, val); + else + p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x", + (u32)type, + offset, val); + if (cnt % 6 == 5) + p += scnprintf(p, end - p, "\n"); + cnt++; + + if (i >= pmreg->reg_num) + p += scnprintf(p, end - p, "\n"); + } + +out: + return p - buf; +} + +static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL; + struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0; + struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; + struct rtw89_mac_ax_gnt gnt; + char *p = buf, *end = buf + bufsz; + u8 i = 0, type = 0, cnt = 0; + u32 val, offset; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) + return 0; + + p += scnprintf(p, end - p, "========== [HW Status] ==========\n"); + + p += scnprintf(p, end - p, + " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_1ST], + wl->wcnt[BTC_WCNT_SCBDUPDATE], + bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD], + bt0->bcnt[BTC_BCNT_SCBDUPDATE]); + + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) { + p += scnprintf(p, end - p, + " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_2ND], + wl->wcnt[BTC_WCNT_SCBDUPDATE2], + bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD], + bt1->bcnt[BTC_BCNT_SCBDUPDATE]); + } + + btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); + _get_gnt(rtwdev, &gnt_cfg); + + gnt = gnt_cfg.band[0]; + p += scnprintf(p, end - p, + " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], polut_type:%s", + "[gnt_status]", + chip->chip_id == RTL8852C ? "HW" : + btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt, + id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); + + gnt = gnt_cfg.band[1]; + p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", + gnt.gnt_wl_sw_en ? "SW" : "HW", + gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", + gnt.gnt_bt); + + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + if (!pcinfo->valid) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", + __func__); + goto out; + } + + pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2; + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", + __func__, pmreg->reg_num); + + for (i = 0; i < pmreg->reg_num; i++) { + type = (u8)le16_to_cpu(chip->mon_reg[i].type); + offset = le32_to_cpu(chip->mon_reg[i].offset); + val = le32_to_cpu(pmreg->mreg_val[i]); + + if (cnt % 6 == 0) + p += scnprintf(p, end - p, + " %-15s : %d_0x%04x=0x%08x", + "[reg]", (u32)type, offset, val); + else + p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x", + (u32)type, + offset, val); + if (cnt % 6 == 5) + p += scnprintf(p, end - p, "\n"); + cnt++; + + if (i >= pmreg->reg_num) + p += scnprintf(p, end - p, "\n"); + } + +out: + return p - buf; +} + +static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_mreg_val_v7 *pmreg = NULL; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_bt_info *bt0 = &cx->bt0; + struct rtw89_btc_bt_info *bt1 = &cx->bt1; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; + u8 i, type, cnt = 0; + u32 val, offset; + + if (!(dm->coex_info_map & BTC_COEX_INFO_MREG)) + return 0; + + p += scnprintf(p, end - p, "\n========== [HW Status] ==========\n"); + + p += scnprintf(p, end - p, + " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_1ST], + wl->wcnt[BTC_WCNT_SCBDUPDATE], + bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD], + bt0->bcnt[BTC_BCNT_SCBDUPDATE]); + + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) { + p += scnprintf(p, end - p, + " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd[BTC_BT_2ND], + wl->wcnt[BTC_WCNT_SCBDUPDATE2], + bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD], + bt1->bcnt[BTC_BCNT_SCBDUPDATE]); + } + + /* To avoid I/O if WL LPS or power-off */ + dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev); + + p += scnprintf(p, end - p, + " %-15s : pta_owner:%s, pta_req_mac:MAC%d, rf_gnt_source: polut_type:%s\n", + "[gnt_status]", + rtwdev->chip->para_ver & BTC_FEAT_PTA_ONOFF_CTRL ? "HW" : + dm->pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + wl->pta_req_mac, + id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); + + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) + p += scnprintf(p, end - p, + " %-15s : phy-0[gnt_wl:%s-%d/gnt_bt0:%s-%d/gnt_bt1:%s-%d]", + "[gnt_status]", + dm->gnt_set[RTW89_PHY_0].gnt_wl_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_0].gnt_wl, + dm->gnt_set[RTW89_PHY_0].gnt_bt0_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_0].gnt_bt0, + dm->gnt_set[RTW89_PHY_0].gnt_bt1_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_0].gnt_bt1); + else + p += scnprintf(p, end - p, + " %-15s : phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]", + "[gnt_status]", + dm->gnt_set[RTW89_PHY_0].gnt_wl_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_0].gnt_wl, + dm->gnt_set[RTW89_PHY_0].gnt_bt0_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_0].gnt_bt0); + + if (rtwdev->dbcc_en) { + if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) + p += scnprintf(p, end - p, + ", phy-1[gnt_wl:%s-%d/gnt_bt0:%s-%d/gnt_bt1:%s-%d]", + dm->gnt_set[RTW89_PHY_1].gnt_wl_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_1].gnt_wl, + dm->gnt_set[RTW89_PHY_1].gnt_bt0_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_1].gnt_bt0, + dm->gnt_set[RTW89_PHY_1].gnt_bt1_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_1].gnt_bt1); + else + p += scnprintf(p, end - p, + ", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]", + dm->gnt_set[RTW89_PHY_1].gnt_wl_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_1].gnt_wl, + dm->gnt_set[RTW89_PHY_1].gnt_bt0_sw_en ? "SW" : "HW", + dm->gnt_set[RTW89_PHY_1].gnt_bt0); + } + + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + if (!pcinfo->valid) + goto out; + + pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v7; + + for (i = 0; i < pmreg->reg_num; i++) { + type = (u8)le16_to_cpu(rtwdev->chip->mon_reg[i].type); + offset = le32_to_cpu(rtwdev->chip->mon_reg[i].offset); + val = le32_to_cpu(pmreg->mreg_val[i]); + + if (cnt % 6 == 0) + p += scnprintf(p, end - p, + "\n %-15s : %s_0x%x=0x%x", "[reg]", + id_to_regtype(type), offset, val); + else + p += scnprintf(p, end - p, ", %s_0x%x=0x%x", + id_to_regtype(type), offset, val); + cnt++; + } + +out: + return p - buf; +} + +static int _show_summary_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl = NULL; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt0; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v1; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt, + pfwinfo->cnt_c2h, prptctrl->c2h_cnt); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", + pfwinfo->event[BTF_EVNT_RPT], + prptctrl->rpt_cnt, + prptctrl->rpt_enable, dm->error.val); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d", + "[mailbox]", prptctrl->mb_send_ok_cnt, + prptctrl->mb_send_fail_cnt, + prptctrl->mb_recv_cnt); + + p += scnprintf(p, end - p, + "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n", + prptctrl->mb_a2dp_empty_cnt, + prptctrl->mb_a2dp_flct_cnt, + prptctrl->mb_a2dp_full_cnt); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", + "[RFK]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); + + if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0) + bt->rfk_info.map.timeout = 1; + else + bt->rfk_info.map.timeout = 0; + + dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, + pfwinfo->event[BTF_EVNT_RPT], + btc->fwinfo.rpt_en_map); + p += scnprintf(p, end - p, " (WL FW report invalid!!)\n"); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], + cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d\n", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); + + return p - buf; +} + +static int _show_summary_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v4 *prptctrl; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt0; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v4; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le32_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le32_to_cpu(prptctrl->rpt_info.cnt_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le32_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en), + dm->error.val); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", + "[RFK]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL])); + + if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) + bt->rfk_info.map.timeout = 1; + else + bt->rfk_info.map.timeout = 0; + + dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, + pfwinfo->event[BTF_EVNT_RPT], + btc->fwinfo.rpt_en_map); + p += scnprintf(p, end - p, " (WL FW report invalid!!)\n"); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], + cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d\n", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); + + return p - buf; +} + +static int _show_summary_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v5 *prptctrl; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v5; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, + ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); + } + + if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || + pfwinfo->err[BTFRE_EXCEPTION]) { + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" + "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", + "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, + pfwinfo->fver_mismch, + pfwinfo->err[BTFRE_EXCEPTION], + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); + + return p - buf; +} + +static int _show_summary_v105(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v105 *prptctrl; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v105; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, + ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); + } + + if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || + pfwinfo->err[BTFRE_EXCEPTION]) { + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" + "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", + "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, + pfwinfo->fver_mismch, + pfwinfo->err[BTFRE_EXCEPTION], + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); + + return p - buf; +} + +static int _show_summary_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v7 *prptctrl = NULL; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u32 cnt_sum = 0; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "%s", + "\n========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v7; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d)," + "c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + rtwdev->btc.ver->info_buf); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]\n", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)\n", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); + + return p - buf; +} + +static int _show_summary_v8(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_rpt_ctrl_v8 *prptctrl = NULL; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u32 cnt_sum = 0; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "%s", + "\n========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v8; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l, + rtwdev->btc.ver->info_buf); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]\n", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)\n", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); + + return p - buf; +} + +static int _show_summary_v9(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_rpt_ctrl_v9 *prptctrl = NULL; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u32 cnt_sum = 0; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "%s", + "\n========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v9; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]\n", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)\n", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); + + return p - buf; +} + +static int _show_summary_v11(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_rpt_ctrl_v11 *prptctrl = NULL; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; + u32 cnt_sum = 0; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return 0; + + p += scnprintf(p, end - p, "%s", + "\n========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v11; + + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l, + rtwdev->btc.ver->info_buf); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ], + wl->wcnt[BTC_WCNT_RFK_GO], + wl->wcnt[BTC_WCNT_RFK_REJECT], + wl->wcnt[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]\n", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)\n", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); + + return p - buf; +} + +ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_ver *fwsubver = &btc->fwinfo.fw_subver; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; + + dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; + + p += scnprintf(p, end - p, + "\n\n\n** Page:%3d/RunCNT:%3d **", + dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO], + dm->cnt_dm[BTC_DCNT_RUN]); + p += scnprintf(p, end - p, + "\n========== [BTC FEATURE SUB VER] =========="); + p += scnprintf(p, end - p, + "\n %-15s : fcxbtcrpt[%d/%d], fcxtdma[%d/%d], fcxslots[%d/%d], fcxcysta[%d/%d]", + "[FW/DRV]", fwsubver->fcxbtcrpt, ver->fcxbtcrpt, + fwsubver->fcxtdma, ver->fcxtdma, fwsubver->fcxslots, + ver->fcxslots, fwsubver->fcxcysta, ver->fcxcysta); + p += scnprintf(p, end - p, + "\n %-15s : fcxstep[%d/%d], fcxnullsta[%d/%d], fcxmreg[%d/%d], fcxgpiodbg[%d/%d]", + "[FW/DRV]", fwsubver->fcxstep, ver->fcxstep, + fwsubver->fcxnullsta, ver->fcxnullsta, fwsubver->fcxmreg, + ver->fcxmreg, fwsubver->fcxgpiodbg, ver->fcxgpiodbg); + p += scnprintf(p, end - p, + "\n %-15s : fcxbtver[%d/%d], fcxbtscan[%d/%d], fcxbtafh[%d/%d], fcxbtdevinfo[%d/%d]", + "[FW/DRV]", fwsubver->fcxbtver, ver->fcxbtver, + fwsubver->fcxbtscan, ver->fcxbtscan, fwsubver->fcxbtafh, + ver->fcxbtafh, fwsubver->fcxbtdevinfo, ver->fcxbtdevinfo); + p += scnprintf(p, end - p, + "\n %-15s : fcxosi[%d/%d], fcxmlo[%d/%d],", + "[FW/DRV]", fwsubver->fcxosi, ver->fcxosi, + fwsubver->fcxmlo, ver->fcxmlo); + + p += _show_cx_info(rtwdev, p, end - p); + p += _show_wl_info(rtwdev, p, end - p); + p += _show_bt_info(rtwdev, p, end - p, BTC_BT_1ST); + p += _show_bt_info(rtwdev, p, end - p, BTC_BT_2ND); + p += _show_dm_info(rtwdev, p, end - p); + p += _show_fw_dm_msg(rtwdev, p, end - p); + + if (ver->fcxmreg == 1) + p += _show_mreg_v1(rtwdev, p, end - p); + else if (ver->fcxmreg == 2) + p += _show_mreg_v2(rtwdev, p, end - p); + else if (ver->fcxmreg == 7) + p += _show_mreg_v7(rtwdev, p, end - p); + + p += _show_gpio_dbg(rtwdev, p, end - p); + + if (ver->fcxbtcrpt == 1) + p += _show_summary_v1(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 4) + p += _show_summary_v4(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 5) + p += _show_summary_v5(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 105) + p += _show_summary_v105(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 7) + p += _show_summary_v7(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 8) + p += _show_summary_v8(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 9) + p += _show_summary_v9(rtwdev, p, end - p); + else if (ver->fcxbtcrpt == 11) + p += _show_summary_v11(rtwdev, p, end - p); + + p += scnprintf(p, end - p, "\n"); + + return p - buf; +} + +void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *btc_ver_def; + const struct rtw89_fw_suit *fw_suit; + u32 suit_ver_code; + int i; + + fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); + suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); + + for (i = 0; i < ARRAY_SIZE(rtw89_btc_ver_defs); i++) { + btc_ver_def = &rtw89_btc_ver_defs[i]; + + if (chip->chip_id != btc_ver_def->chip_id) + continue; + + if (suit_ver_code >= btc_ver_def->fw_ver_code) { + btc->ver = btc_ver_def; + goto out; + } + } + + btc->ver = &rtw89_btc_ver_defs[RTW89_DEFAULT_BTC_VER_IDX]; + +out: + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n", + (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code); +} + +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms) +{ + struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt0.link_info; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + return; + + if (!a2dp.exist) + return; + + fsleep(ms * 1000); +} +EXPORT_SYMBOL(rtw89_btc_ntfy_preserve_bt_time); + +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state) +{ + rtwdev->btc.cx.wl.rfk_info.con_rfk = state; +} +EXPORT_SYMBOL(rtw89_btc_ntfy_conn_rfk); diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h new file mode 100644 index 000000000..3e9e1510c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -0,0 +1,460 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_COEX_H__ +#define __RTW89_COEX_H__ + +#include "core.h" + +#define BTC_H2C_MAXLEN 2020 +#define BTC_TLV_SLOT_ID_LEN_V7 1 +#define BTC_SLOT_REQ_TH 2 + +#define BTC_FREQ_W2G 2412 +#define BTC_FREQ_W5G 5005 +#define BTC_FREQ_W6G 5955 + +#define BTC_FREQ_B2G 2402 +#define BTC_FREQ_B6G 5125 + +#define BTC_FREQ_W2G_CH14 2484 + +#define BTC_LO_2G_DNM 125 /* LO Coefficient Denominator */ +#define BTC_LO_5G_DNM 125 +#define BTC_LO_6G_DNM 150 + +#define BTC_LO_2G_NMR 400 /* LO Coefficient Numerator */ +#define BTC_LO_5G_NMR 200 +#define BTC_LO_6G_NMR 200 + +#define BTC_CH_W2G_MIN 1 /* start from 2412MHz */ +#define BTC_CH_W2G_MAX 14 +#define BTC_CH_W5G_MIN 1 /* start from 5005MHz */ +#define BTC_CH_W5G_MAX 165 +#define BTC_CH_W6G_MIN 1 /* start from 5955MHz */ +#define BTC_CH_W6G_MAX 233 + +#define BTC_CH_B2G_MIN 0 /* start from 2402MHz */ +#define BTC_CH_B2G_MAX 78 + +#define BTC_CH_B5G_MIN 600 /* start from 5725MHz */ +#define BTC_CH_B5G_MAX 1300 + +#define BTC_VCO_GUARD_W2W 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ +#define BTC_VCO_GUARD_W2B 25 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ +#define BTC_VCO_GUARD_B2B 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ + +enum btc_mode { + BTC_MODE_NORMAL, + BTC_MODE_WL, + BTC_MODE_BT, + BTC_MODE_WLOFF, + BTC_MODE_COTX, + BTC_MODE_MECHANISM_INIT, + BTC_MODE_MAX +}; + +enum btc_wl_rfk_type { + BTC_WRFKT_IQK = 0, + BTC_WRFKT_LCK = 1, + BTC_WRFKT_DPK = 2, + BTC_WRFKT_TXGAPK = 3, + BTC_WRFKT_DACK = 4, + BTC_WRFKT_RXDCK = 5, + BTC_WRFKT_TSSI = 6, + BTC_WRFKT_CHLK = 7, +}; + +#define NM_EXEC false +#define FC_EXEC true + +#define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ) +#define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16) +#define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300) +#define BTC_RFK_PATH_MAP GENMASK(3, 0) +#define BTC_RFK_PHY_MAP GENMASK(5, 4) +#define BTC_RFK_BAND_MAP GENMASK(7, 6) + +enum btc_wl_rfk_state { + BTC_WRFK_STOP = 0, + BTC_WRFK_START = 1, + BTC_WRFK_ONESHOT_START = 2, + BTC_WRFK_ONESHOT_STOP = 3, +}; + +enum btc_pri { + BTC_PRI_MASK_RX_RESP = 0, + BTC_PRI_MASK_TX_RESP, + BTC_PRI_MASK_BEACON, + BTC_PRI_MASK_RX_CCK, + BTC_PRI_MASK_TX_MNGQ, + BTC_PRI_MASK_MAX, +}; + +enum btc_bt_trs { + BTC_BT_SS_GROUP = 0x0, + BTC_BT_TX_GROUP = 0x2, + BTC_BT_RX_GROUP = 0x3, + BTC_BT_MAX_GROUP, +}; + +enum btc_rssi_st { + BTC_RSSI_ST_LOW = 0x0, + BTC_RSSI_ST_HIGH, + BTC_RSSI_ST_STAY_LOW, + BTC_RSSI_ST_STAY_HIGH, + BTC_RSSI_ST_MAX +}; + +enum btc_fddt_en { + BTC_FDDT_DISABLE, + BTC_FDDT_ENABLE, +}; + +#define BTC_RSSI_HIGH(_rssi_) \ + ({typeof(_rssi_) __rssi = (_rssi_); \ + ((__rssi == BTC_RSSI_ST_HIGH || \ + __rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); }) + +#define BTC_RSSI_LOW(_rssi_) \ + ({typeof(_rssi_) __rssi = (_rssi_); \ + ((__rssi == BTC_RSSI_ST_LOW || \ + __rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); }) + +#define BTC_RSSI_CHANGE(_rssi_) \ + ({typeof(_rssi_) __rssi = (_rssi_); \ + ((__rssi == BTC_RSSI_ST_LOW || \ + __rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); }) + +/* Antenna TX/RX path position masks and helpers */ +#define BTC_ANT_TX_MASK 0xf0 +#define BTC_ANT_RX_MASK 0x0f +#define BTC_ANT_SHIFT 4 + +enum btc_ant { + BTC_ANT_SHARED = 0, + BTC_ANT_DEDICATED, + BTC_ANTTYPE_MAX +}; + +enum btc_bt_btg { + BTC_BT_ALONE = 0, + BTC_BT_BTG +}; + +enum btc_switch { + BTC_SWITCH_INTERNAL = 0, + BTC_SWITCH_EXTERNAL +}; + +enum btc_ant_switch_type { + BTC_SWITCH_V1_NONE = 0, /* independent antenna */ + BTC_SWITCH_V1_INTERNAL, /* internal-switch: BTGA structure */ +}; + +enum btc_pkt_type { + PACKET_DHCP, + PACKET_ARP, + PACKET_EAPOL, + PACKET_EAPOL_END, + PACKET_ICMP, + PACKET_MAX +}; + +enum btc_bt_mailbox_id { + BTC_BTINFO_REPLY = 0x23, + BTC_BTINFO_AUTO = 0x27 +}; + +enum btc_role_state { + BTC_ROLE_START, + BTC_ROLE_STOP, + BTC_ROLE_CHG_TYPE, + BTC_ROLE_MSTS_STA_CONN_START, + BTC_ROLE_MSTS_STA_CONN_END, + BTC_ROLE_MSTS_STA_DIS_CONN, + BTC_ROLE_MSTS_AP_START, + BTC_ROLE_MSTS_AP_STOP, + BTC_ROLE_STATE_UNKNOWN +}; + +enum btc_rfctrl { + BTC_RFCTRL_WL_OFF, + BTC_RFCTRL_WL_ON, + BTC_RFCTRL_LPS_WL_ON, + BTC_RFCTRL_FW_CTRL, + BTC_RFCTRL_MAX +}; + +enum btc_lps_state { + BTC_LPS_OFF = 0, + BTC_LPS_RF_OFF = 1, + BTC_LPS_RF_ON = 2 +}; + +#define R_BTC_BB_BTG_RX 0x980 +#define R_BTC_BB_PRE_AGC_S1 0x476C +#define R_BTC_BB_PRE_AGC_S0 0x4688 + +#define B_BTC_BB_GNT_MUX GENMASK(20, 17) +#define B_BTC_BB_PRE_AGC_MASK GENMASK(31, 24) +#define B_BTC_BB_PRE_AGC_VAL BIT(31) + +#define BTC_REG_NOTFOUND 0xff + +#define R_BTC_ZB_COEX_TBL_0 0xE328 +#define R_BTC_ZB_COEX_TBL_1 0xE32c +#define R_BTC_ZB_BREAK_TBL 0xE350 + +enum btc_ant_div_pos { + BTC_ANT_DIV_MAIN = 0, + BTC_ANT_DIV_AUX = 1, +}; + +enum btc_get_reg_status { + BTC_CSTATUS_TXDIV_POS = 0, + BTC_CSTATUS_RXDIV_POS = 1, + BTC_CSTATUS_BB_GNT_MUX = 2, + BTC_CSTATUS_BB_GNT_MUX_MON = 3, + BTC_CSTATUS_BB_PRE_AGC = 4, + BTC_CSTATUS_BB_PRE_AGC_MON = 5, +}; + +enum btc_preagc_type { + BTC_PREAGC_DISABLE, + BTC_PREAGC_ENABLE, + BTC_PREAGC_BB_FWCTRL, + BTC_PREAGC_NOTFOUND, +}; + +enum btc_btgctrl_type { + BTC_BTGCTRL_DISABLE, + BTC_BTGCTRL_ENABLE, + BTC_BTGCTRL_BB_GNT_FWCTRL, + BTC_BTGCTRL_BB_GNT_NOTFOUND, +}; + +enum btc_wa_type { + BTC_WA_5G_HI_CH_RX = BIT(0), + BTC_WA_NULL_AP = BIT(1), + BTC_WA_HFP_ZB = BIT(2), /* HFP PTA req bit4 define issue */ + BTC_WA_HFP_LAG = BIT(3), /* 52BT WL break BT Rx lag issue */ + BTC_WA_INIT_SCAN = BIT(4) /* 52A/C/D init scan move to wl slot WA */ +}; + +enum btc_3cx_type { + BTC_3CX_NONE = 0, + BTC_3CX_BT2 = BIT(0), + BTC_3CX_ZB = BIT(1), + BTC_3CX_LTE = BIT(2), + BTC_3CX_MAX, +}; + +enum btc_fddt_type { + BTC_FDDT_TYPE_STOP, + BTC_FDDT_TYPE_AUTO, + BTC_FDDT_TYPE_FIX_TDD, + BTC_FDDT_TYPE_FIX_FULL_FDD, + BTC_FDDT_MAX, +}; + +enum btc_chip_feature { + BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */ + BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */ + BTC_FEAT_WLAN_ACT_MUX = BIT(2), /* separate wlan_act/gnt mux */ + BTC_FEAT_NEW_BBAPI_FLOW = BIT(3), /* new btg_ctrl/pre_agc_ctrl */ + BTC_FEAT_MLO_SUPPORT = BIT(4), + BTC_FEAT_H2C_MACRO = BIT(5), + BTC_FEAT_DUAL_BT = BIT(6), + BTC_FEAT_BT_6G = BIT(7), + BTC_FEAT_MULTI_PTA = BIT(8), + BTC_FEAT_DUAL_BTGA = BIT(9) /* the future A-Die */ +}; + +enum btc_efuse_ant_function_map { + BTC_EFMAP_NONE = 0, + BTC_EFMAP_BT0 = BIT(0), + BTC_EFMAP_BT1 = BIT(1), + BTC_EFMAP_ZB = BIT(2), /* ZB or thread */ + BTC_EFMAP_24GP = BIT(3), + BTC_EFMAP_ULL = BIT(4), +}; + +enum btc_extsoc_interface { /* cx->other.hw_coex */ + BTC_EXTSOC_INTF_NONE = 0, + BTC_EXTSOC_INTF_PTA = BIT(0), + BTC_EXTSOC_INTF_MBX = BIT(1), + BTC_EXTSOC_INTF_SWIO = BIT(2), + BTC_EXTSOC_INTF_MAX, +}; + +enum btc_esoc_type { + BTC_ESOC_NONE, + BTC_ESOC_8761, + BTC_ESOC_8771, + BTC_ESOC_SILAB_MG21, + BTC_ESOC_NORDI_NRF52840, + BTC_ESOC_MAX, +}; + +enum btc_wl_mode { + BTC_WL_MODE_11B = 0, + BTC_WL_MODE_11A = 1, + BTC_WL_MODE_11G = 2, + BTC_WL_MODE_HT = 3, + BTC_WL_MODE_VHT = 4, + BTC_WL_MODE_HE = 5, + BTC_WL_MODE_NUM, +}; + +enum btc_mlo_rf_combin { + BTC_MLO_RF_2_PLUS_0 = 0, + BTC_MLO_RF_0_PLUS_2 = 1, + BTC_MLO_RF_1_PLUS_1 = 2, + BTC_MLO_RF_2_PLUS_2 = 3, +}; + +void rtw89_btc_init(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode); +void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); +void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx); +void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); +void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, + enum btc_pkt_type pkt_type); +void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + enum btc_role_state state); +void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); +void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, + enum btc_wl_rfk_type type, + enum btc_wl_rfk_state state); +void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev); +void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func); +ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); +void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_coex_power_on(struct rtw89_dev *rtwdev); +void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); +void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); +void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms); +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state); + +static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + enum rtw89_rf_path_bit paths, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 phy_map; + + phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) | + FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) | + FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type); + + return phy_map; +} + +static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + enum rtw89_rf_path path, + enum rtw89_chanctx_idx chanctx_idx) +{ + return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path), chanctx_idx); +} + +/* return bt req len in TU */ +static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + return btc->bt_req_len[phy_idx]; +} + +static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type) +{ + return ((phy_map << 8) + type); +} + +static inline +void _slot_set_le(struct rtw89_btc *btc, u8 sid, __le16 dura, __le32 tbl, __le16 type) +{ + if (btc->ver->fcxslots == 1) { + btc->dm.slot.v1[sid].dur = dura; + btc->dm.slot.v1[sid].cxtbl = tbl; + btc->dm.slot.v1[sid].cxtype = type; + } else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) { + btc->dm.slot.v7[sid].dur = dura; + btc->dm.slot.v7[sid].cxtype = type; + btc->dm.slot.v7[sid].cxtbl = tbl; + } +} + +static inline +void _slot_set(struct rtw89_btc *btc, u8 sid, u16 dura, u32 tbl, u16 type) +{ + _slot_set_le(btc, sid, cpu_to_le16(dura), cpu_to_le32(tbl), cpu_to_le16(type)); +} + +static inline +void _slot_set_dur(struct rtw89_btc *btc, u8 sid, u16 dura) +{ + if (btc->ver->fcxslots == 1) + btc->dm.slot.v1[sid].dur = cpu_to_le16(dura); + else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) + btc->dm.slot.v7[sid].dur = cpu_to_le16(dura); +} + +static inline +void _slot_set_type(struct rtw89_btc *btc, u8 sid, u16 type) +{ + if (btc->ver->fcxslots == 1) + btc->dm.slot.v1[sid].cxtype = cpu_to_le16(type); + else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) + btc->dm.slot.v7[sid].cxtype = cpu_to_le16(type); +} + +static inline +void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl) +{ + if (btc->ver->fcxslots == 1) + btc->dm.slot.v1[sid].cxtbl = cpu_to_le32(tbl); + else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) + btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl); +} + +static inline +void btc_dw2b(u8 *buf, size_t idx, u32 val) +{ + buf[idx] = u32_get_bits(val, MASKBYTE0); + buf[idx + 1] = u32_get_bits(val, MASKBYTE1); + buf[idx + 2] = u32_get_bits(val, MASKBYTE2); + buf[idx + 3] = u32_get_bits(val, MASKBYTE3); +} + +static inline +u8 _btc_get_rf_path_from_ant_num(struct rtw89_btc *btc, u8 antnum) +{ + switch (antnum) { + default: + case 1: + return btc->mdinfo.ant.single_pos; + case 2: + return RF_PATH_AB; + case 3: + return RF_PATH_ABC; + } +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c new file mode 100644 index 000000000..397ebbfca --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -0,0 +1,7738 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ +#include +#include +#include + +#include "cam.h" +#include "chan.h" +#include "coex.h" +#include "core.h" +#include "efuse.h" +#include "fw.h" +#include "led.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "sar.h" +#include "ser.h" +#include "txrx.h" +#include "util.h" +#include "wow.h" + +static bool rtw89_disable_ps_mode; +module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644); +MODULE_PARM_DESC(disable_ps_mode, "Set Y to disable low power mode"); + +#define RTW89_DEF_CHAN(_freq, _hw_val, _flags, _band) \ + { .center_freq = _freq, .hw_value = _hw_val, .flags = _flags, .band = _band, } +#define RTW89_DEF_CHAN_2G(_freq, _hw_val) \ + RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_2GHZ) +#define RTW89_DEF_CHAN_5G(_freq, _hw_val) \ + RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_5GHZ) +#define RTW89_DEF_CHAN_5G_NO_HT40MINUS(_freq, _hw_val) \ + RTW89_DEF_CHAN(_freq, _hw_val, IEEE80211_CHAN_NO_HT40MINUS, NL80211_BAND_5GHZ) +#define RTW89_DEF_CHAN_6G(_freq, _hw_val) \ + RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_6GHZ) + +static struct ieee80211_channel rtw89_channels_2ghz[] = { + RTW89_DEF_CHAN_2G(2412, 1), + RTW89_DEF_CHAN_2G(2417, 2), + RTW89_DEF_CHAN_2G(2422, 3), + RTW89_DEF_CHAN_2G(2427, 4), + RTW89_DEF_CHAN_2G(2432, 5), + RTW89_DEF_CHAN_2G(2437, 6), + RTW89_DEF_CHAN_2G(2442, 7), + RTW89_DEF_CHAN_2G(2447, 8), + RTW89_DEF_CHAN_2G(2452, 9), + RTW89_DEF_CHAN_2G(2457, 10), + RTW89_DEF_CHAN_2G(2462, 11), + RTW89_DEF_CHAN_2G(2467, 12), + RTW89_DEF_CHAN_2G(2472, 13), + RTW89_DEF_CHAN_2G(2484, 14), +}; + +static struct ieee80211_channel rtw89_channels_5ghz[] = { + RTW89_DEF_CHAN_5G(5180, 36), + RTW89_DEF_CHAN_5G(5200, 40), + RTW89_DEF_CHAN_5G(5220, 44), + RTW89_DEF_CHAN_5G(5240, 48), + RTW89_DEF_CHAN_5G(5260, 52), + RTW89_DEF_CHAN_5G(5280, 56), + RTW89_DEF_CHAN_5G(5300, 60), + RTW89_DEF_CHAN_5G(5320, 64), + RTW89_DEF_CHAN_5G(5500, 100), + RTW89_DEF_CHAN_5G(5520, 104), + RTW89_DEF_CHAN_5G(5540, 108), + RTW89_DEF_CHAN_5G(5560, 112), + RTW89_DEF_CHAN_5G(5580, 116), + RTW89_DEF_CHAN_5G(5600, 120), + RTW89_DEF_CHAN_5G(5620, 124), + RTW89_DEF_CHAN_5G(5640, 128), + RTW89_DEF_CHAN_5G(5660, 132), + RTW89_DEF_CHAN_5G(5680, 136), + RTW89_DEF_CHAN_5G(5700, 140), + RTW89_DEF_CHAN_5G(5720, 144), + RTW89_DEF_CHAN_5G(5745, 149), + RTW89_DEF_CHAN_5G(5765, 153), + RTW89_DEF_CHAN_5G(5785, 157), + RTW89_DEF_CHAN_5G(5805, 161), + RTW89_DEF_CHAN_5G_NO_HT40MINUS(5825, 165), + RTW89_DEF_CHAN_5G(5845, 169), + RTW89_DEF_CHAN_5G(5865, 173), + RTW89_DEF_CHAN_5G(5885, 177), +}; + +static_assert(RTW89_5GHZ_UNII4_START_INDEX + RTW89_5GHZ_UNII4_CHANNEL_NUM == + ARRAY_SIZE(rtw89_channels_5ghz)); + +static struct ieee80211_channel rtw89_channels_6ghz[] = { + RTW89_DEF_CHAN_6G(5955, 1), + RTW89_DEF_CHAN_6G(5975, 5), + RTW89_DEF_CHAN_6G(5995, 9), + RTW89_DEF_CHAN_6G(6015, 13), + RTW89_DEF_CHAN_6G(6035, 17), + RTW89_DEF_CHAN_6G(6055, 21), + RTW89_DEF_CHAN_6G(6075, 25), + RTW89_DEF_CHAN_6G(6095, 29), + RTW89_DEF_CHAN_6G(6115, 33), + RTW89_DEF_CHAN_6G(6135, 37), + RTW89_DEF_CHAN_6G(6155, 41), + RTW89_DEF_CHAN_6G(6175, 45), + RTW89_DEF_CHAN_6G(6195, 49), + RTW89_DEF_CHAN_6G(6215, 53), + RTW89_DEF_CHAN_6G(6235, 57), + RTW89_DEF_CHAN_6G(6255, 61), + RTW89_DEF_CHAN_6G(6275, 65), + RTW89_DEF_CHAN_6G(6295, 69), + RTW89_DEF_CHAN_6G(6315, 73), + RTW89_DEF_CHAN_6G(6335, 77), + RTW89_DEF_CHAN_6G(6355, 81), + RTW89_DEF_CHAN_6G(6375, 85), + RTW89_DEF_CHAN_6G(6395, 89), + RTW89_DEF_CHAN_6G(6415, 93), + RTW89_DEF_CHAN_6G(6435, 97), + RTW89_DEF_CHAN_6G(6455, 101), + RTW89_DEF_CHAN_6G(6475, 105), + RTW89_DEF_CHAN_6G(6495, 109), + RTW89_DEF_CHAN_6G(6515, 113), + RTW89_DEF_CHAN_6G(6535, 117), + RTW89_DEF_CHAN_6G(6555, 121), + RTW89_DEF_CHAN_6G(6575, 125), + RTW89_DEF_CHAN_6G(6595, 129), + RTW89_DEF_CHAN_6G(6615, 133), + RTW89_DEF_CHAN_6G(6635, 137), + RTW89_DEF_CHAN_6G(6655, 141), + RTW89_DEF_CHAN_6G(6675, 145), + RTW89_DEF_CHAN_6G(6695, 149), + RTW89_DEF_CHAN_6G(6715, 153), + RTW89_DEF_CHAN_6G(6735, 157), + RTW89_DEF_CHAN_6G(6755, 161), + RTW89_DEF_CHAN_6G(6775, 165), + RTW89_DEF_CHAN_6G(6795, 169), + RTW89_DEF_CHAN_6G(6815, 173), + RTW89_DEF_CHAN_6G(6835, 177), + RTW89_DEF_CHAN_6G(6855, 181), + RTW89_DEF_CHAN_6G(6875, 185), + RTW89_DEF_CHAN_6G(6895, 189), + RTW89_DEF_CHAN_6G(6915, 193), + RTW89_DEF_CHAN_6G(6935, 197), + RTW89_DEF_CHAN_6G(6955, 201), + RTW89_DEF_CHAN_6G(6975, 205), + RTW89_DEF_CHAN_6G(6995, 209), + RTW89_DEF_CHAN_6G(7015, 213), + RTW89_DEF_CHAN_6G(7035, 217), + RTW89_DEF_CHAN_6G(7055, 221), + RTW89_DEF_CHAN_6G(7075, 225), + RTW89_DEF_CHAN_6G(7095, 229), + RTW89_DEF_CHAN_6G(7115, 233), +}; + +static struct ieee80211_rate rtw89_bitrates[] = { + { .bitrate = 10, .hw_value = 0x00, }, + { .bitrate = 20, .hw_value = 0x01, }, + { .bitrate = 55, .hw_value = 0x02, }, + { .bitrate = 110, .hw_value = 0x03, }, + { .bitrate = 60, .hw_value = 0x04, }, + { .bitrate = 90, .hw_value = 0x05, }, + { .bitrate = 120, .hw_value = 0x06, }, + { .bitrate = 180, .hw_value = 0x07, }, + { .bitrate = 240, .hw_value = 0x08, }, + { .bitrate = 360, .hw_value = 0x09, }, + { .bitrate = 480, .hw_value = 0x0a, }, + { .bitrate = 540, .hw_value = 0x0b, }, +}; + +static const struct ieee80211_iface_limit rtw89_iface_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_AP), + }, +}; + +static const struct ieee80211_iface_limit rtw89_iface_limits_mcc[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO), + }, +}; + +static const struct ieee80211_iface_combination rtw89_iface_combs[] = { + { + .limits = rtw89_iface_limits, + .n_limits = ARRAY_SIZE(rtw89_iface_limits), + .max_interfaces = RTW89_MAX_INTERFACE_NUM, + .num_different_channels = 1, + }, + { + .limits = rtw89_iface_limits_mcc, + .n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc), + .max_interfaces = RTW89_MAX_INTERFACE_NUM, + .num_different_channels = 2, + }, +}; + +static const u8 rtw89_ext_capa_sta[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, +}; + +static const struct wiphy_iftype_ext_capab rtw89_iftypes_ext_capa[] = { + { + .iftype = NL80211_IFTYPE_STATION, + .extended_capabilities = rtw89_ext_capa_sta, + .extended_capabilities_mask = rtw89_ext_capa_sta, + .extended_capabilities_len = sizeof(rtw89_ext_capa_sta), + /* relevant only if EHT is supported */ + .eml_capabilities = 0, + .mld_capa_and_ops = 0, + }, +}; + +#define RTW89_6GHZ_SPAN_HEAD 6145 +#define RTW89_6GHZ_SPAN_IDX(center_freq) \ + ((((int)(center_freq) - RTW89_6GHZ_SPAN_HEAD) / 5) / 2) + +#define RTW89_DECL_6GHZ_SPAN(center_freq, subband_l, subband_h) \ + [RTW89_6GHZ_SPAN_IDX(center_freq)] = { \ + .sar_subband_low = RTW89_SAR_6GHZ_ ## subband_l, \ + .sar_subband_high = RTW89_SAR_6GHZ_ ## subband_h, \ + .acpi_sar_subband_low = RTW89_ACPI_SAR_6GHZ_ ## subband_l, \ + .acpi_sar_subband_high = RTW89_ACPI_SAR_6GHZ_ ## subband_h, \ + .ant_gain_subband_low = RTW89_ANT_GAIN_6GHZ_ ## subband_l, \ + .ant_gain_subband_high = RTW89_ANT_GAIN_6GHZ_ ## subband_h, \ + } + +/* Since 6GHz subbands are not edge aligned, some cases span two subbands. + * In the following, we describe each of them with rtw89_6ghz_span. + */ +static const struct rtw89_6ghz_span rtw89_overlapping_6ghz[] = { + RTW89_DECL_6GHZ_SPAN(6145, SUBBAND_5_L, SUBBAND_5_H), + RTW89_DECL_6GHZ_SPAN(6165, SUBBAND_5_L, SUBBAND_5_H), + RTW89_DECL_6GHZ_SPAN(6185, SUBBAND_5_L, SUBBAND_5_H), + RTW89_DECL_6GHZ_SPAN(6505, SUBBAND_6, SUBBAND_7_L), + RTW89_DECL_6GHZ_SPAN(6525, SUBBAND_6, SUBBAND_7_L), + RTW89_DECL_6GHZ_SPAN(6545, SUBBAND_6, SUBBAND_7_L), + RTW89_DECL_6GHZ_SPAN(6665, SUBBAND_7_L, SUBBAND_7_H), + RTW89_DECL_6GHZ_SPAN(6705, SUBBAND_7_L, SUBBAND_7_H), + RTW89_DECL_6GHZ_SPAN(6825, SUBBAND_7_H, SUBBAND_8), + RTW89_DECL_6GHZ_SPAN(6865, SUBBAND_7_H, SUBBAND_8), + RTW89_DECL_6GHZ_SPAN(6875, SUBBAND_7_H, SUBBAND_8), + RTW89_DECL_6GHZ_SPAN(6885, SUBBAND_7_H, SUBBAND_8), +}; + +const struct rtw89_6ghz_span * +rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq) +{ + int idx; + + if (center_freq >= RTW89_6GHZ_SPAN_HEAD) { + idx = RTW89_6GHZ_SPAN_IDX(center_freq); + /* To decrease size of rtw89_overlapping_6ghz[], + * RTW89_6GHZ_SPAN_IDX() truncates the leading NULLs + * to make first span as index 0 of the table. So, if center + * frequency is less than the first one, it will get netative. + */ + if (idx >= 0 && idx < ARRAY_SIZE(rtw89_overlapping_6ghz)) + return &rtw89_overlapping_6ghz[idx]; + } + + return NULL; +} + +bool rtw89_legacy_rate_to_bitrate(struct rtw89_dev *rtwdev, u8 legacy_rate, u16 *bitrate) +{ + const struct ieee80211_rate *rate; + + if (unlikely(legacy_rate >= ARRAY_SIZE(rtw89_bitrates))) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "invalid legacy rate %d\n", legacy_rate); + return false; + } + + rate = &rtw89_bitrates[legacy_rate]; + *bitrate = rate->bitrate; + + return true; +} + +static const struct ieee80211_supported_band rtw89_sband_2ghz = { + .band = NL80211_BAND_2GHZ, + .channels = rtw89_channels_2ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), + .bitrates = rtw89_bitrates, + .n_bitrates = ARRAY_SIZE(rtw89_bitrates), + .ht_cap = {0}, + .vht_cap = {0}, +}; + +static const struct ieee80211_supported_band rtw89_sband_5ghz = { + .band = NL80211_BAND_5GHZ, + .channels = rtw89_channels_5ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), + + /* 5G has no CCK rates, 1M/2M/5.5M/11M */ + .bitrates = rtw89_bitrates + 4, + .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, + .ht_cap = {0}, + .vht_cap = {0}, +}; + +static const struct ieee80211_supported_band rtw89_sband_6ghz = { + .band = NL80211_BAND_6GHZ, + .channels = rtw89_channels_6ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_6ghz), + + /* 6G has no CCK rates, 1M/2M/5.5M/11M */ + .bitrates = rtw89_bitrates + 4, + .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, +}; + +static const struct rtw89_hw_rate_def { + enum rtw89_hw_rate ht; + enum rtw89_hw_rate vht[RTW89_NSS_NUM]; +} rtw89_hw_rate[RTW89_CHIP_GEN_NUM] = { + [RTW89_CHIP_AX] = { + .ht = RTW89_HW_RATE_MCS0, + .vht = {RTW89_HW_RATE_VHT_NSS1_MCS0, + RTW89_HW_RATE_VHT_NSS2_MCS0, + RTW89_HW_RATE_VHT_NSS3_MCS0, + RTW89_HW_RATE_VHT_NSS4_MCS0}, + }, + [RTW89_CHIP_BE] = { + .ht = RTW89_HW_RATE_V1_MCS0, + .vht = {RTW89_HW_RATE_V1_VHT_NSS1_MCS0, + RTW89_HW_RATE_V1_VHT_NSS2_MCS0, + RTW89_HW_RATE_V1_VHT_NSS3_MCS0, + RTW89_HW_RATE_V1_VHT_NSS4_MCS0}, + }, +}; + +static void rtw89_core_tx_skb_proto_stats(struct rtw89_traffic_stats *stats, + struct sk_buff *skb) +{ + switch (ip_hdr(skb)->protocol) { + case IPPROTO_TCP: + stats->tcp++; + break; + case IPPROTO_UDP: + stats->udp++; + break; + default: + break; + } +} + +static void __rtw89_traffic_stats_accu(struct rtw89_traffic_stats *stats, + struct sk_buff *skb, bool tx) +{ + if (tx) { + rtw89_core_tx_skb_proto_stats(stats, skb); + stats->tx_cnt++; + stats->tx_unicast += skb->len; + } else { + stats->rx_cnt++; + stats->rx_unicast += skb->len; + } +} + +static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct sk_buff *skb, + bool accu_dev, bool tx) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (!ieee80211_is_data(hdr->frame_control)) + return; + + if (is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1)) + return; + + if (accu_dev) + __rtw89_traffic_stats_accu(&rtwdev->stats, skb, tx); + + if (rtwvif) { + __rtw89_traffic_stats_accu(&rtwvif->stats, skb, tx); + __rtw89_traffic_stats_accu(&rtwvif->stats_ps, skb, tx); + } +} + +void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef) +{ + cfg80211_chandef_create(chandef, &rtw89_channels_2ghz[0], + NL80211_CHAN_NO_HT); +} + +void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef, + struct rtw89_chan *chan) +{ + struct ieee80211_channel *channel = chandef->chan; + enum nl80211_chan_width width = chandef->width; + u32 primary_freq, center_freq; + u8 center_chan; + u8 bandwidth = RTW89_CHANNEL_WIDTH_20; + u32 offset; + u8 band; + + center_chan = channel->hw_value; + primary_freq = channel->center_freq; + center_freq = chandef->center_freq1; + + switch (width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + bandwidth = RTW89_CHANNEL_WIDTH_20; + break; + case NL80211_CHAN_WIDTH_40: + bandwidth = RTW89_CHANNEL_WIDTH_40; + if (primary_freq > center_freq) { + center_chan -= 2; + } else { + center_chan += 2; + } + break; + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_160: + bandwidth = nl_to_rtw89_bandwidth(width); + if (primary_freq > center_freq) { + offset = (primary_freq - center_freq - 10) / 20; + center_chan -= 2 + offset * 4; + } else { + offset = (center_freq - primary_freq - 10) / 20; + center_chan += 2 + offset * 4; + } + break; + default: + center_chan = 0; + break; + } + + switch (channel->band) { + default: + case NL80211_BAND_2GHZ: + band = RTW89_BAND_2G; + break; + case NL80211_BAND_5GHZ: + band = RTW89_BAND_5G; + break; + case NL80211_BAND_6GHZ: + band = RTW89_BAND_6G; + break; + } + + rtw89_chan_create(chan, center_chan, channel->hw_value, band, bandwidth); +} + +static void __rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool entity_active; + + entity_active = rtw89_get_entity_state(rtwdev, phy_idx); + if (!entity_active) + return; + + chip->ops->set_txpwr(rtwdev, chan, phy_idx); +} + +void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_conf conf; + + rtw89_entity_get_conf(rtwdev, &conf); + + __rtw89_core_set_chip_txpwr(rtwdev, conf.chans[0], RTW89_PHY_0); + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + return; + + __rtw89_core_set_chip_txpwr(rtwdev, conf.chans[1], RTW89_PHY_1); +} + +static void rtw89_core_rfk_record(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait; + struct rtw89_rfk_record *record = &info->records[info->record_idx]; + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 path_num = min(chip->rf_path_num, RTW89_RFK_RECORD_PATH_NR); + int path; + + if (!start) + goto end; + + info->record_ptr = record; + record->phy_idx = rtwvif_link->phy_idx; + + for (path = 0; path < path_num; path++) { + record->ch[path] = rtw89_read_rf(rtwdev, path, RR_CFGCH, + RR_CFGCH_BAND0 | RR_CFGCH_CH); + record->cv[path] = rtw89_read_rf(rtwdev, path, RR_VCO, + RR_VCO_SEL | RR_VCO_STS); + record->c5[path] = rtw89_read_rf(rtwdev, path, RR_SYNFB, RFREG_MASK); + } + + return; + +end: + info->record_idx = (info->record_idx + 1) % RTW89_RFK_RECORD_HISTORY_NR; + info->record_ptr = NULL; +} + +void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool mon = !!rtwdev->pure_monitor_mode_vif; + bool prehdl_link = false; + + if (chip->chip_gen != RTW89_CHIP_AX && + !RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw) && + !mon && !rtw89_entity_check_hw(rtwdev, rtwvif_link->phy_idx)) + prehdl_link = true; + + if (prehdl_link) { + rtw89_entity_force_hw(rtwdev, rtwvif_link->phy_idx); + rtw89_set_channel(rtwdev); + } + + if (chip->ops->rfk_channel) { + rtw89_core_rfk_record(rtwdev, rtwvif_link, true); + + chip->ops->rfk_channel(rtwdev, rtwvif_link); + + rtw89_core_rfk_record(rtwdev, rtwvif_link, false); + } + + if (prehdl_link) { + rtw89_entity_force_hw(rtwdev, RTW89_PHY_NUM); + rtw89_set_channel(rtwdev); + } +} + +static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_vif *rtwvif = rtwdev->pure_monitor_mode_vif; + struct rtw89_vif_link *rtwvif_link; + + if (!rtwvif) + return; + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, phy_idx); + if (!rtwvif_link) + return; + + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); +} + +static void __rtw89_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_chan_rcd *chan_rcd; + struct rtw89_channel_help_params bak; + bool entity_active; + + entity_active = rtw89_get_entity_state(rtwdev, phy_idx); + + chan_rcd = rtw89_chan_rcd_get_by_chan(chan); + + rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx); + + chip->ops->set_channel(rtwdev, chan, mac_idx, phy_idx); + + chip->ops->set_txpwr(rtwdev, chan, phy_idx); + + rtw89_chip_set_channel_done(rtwdev, &bak, chan, mac_idx, phy_idx); + + if (!entity_active || chan_rcd->band_changed) { + rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, chan->band_type); + rtw89_chip_rfk_band_changed(rtwdev, phy_idx, chan); + } + + rtw89_set_entity_state(rtwdev, phy_idx, true); + + rtw89_chip_rfk_channel_for_pure_mon_vif(rtwdev, phy_idx); +} + +int rtw89_set_channel(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_conf conf; + enum rtw89_entity_mode mode; + + mode = rtw89_entity_recalc(rtwdev); + if (mode < 0 || mode >= NUM_OF_RTW89_ENTITY_MODE) { + WARN(1, "Invalid ent mode: %d\n", mode); + return -EINVAL; + } + + rtw89_entity_get_conf(rtwdev, &conf); + + __rtw89_set_channel(rtwdev, conf.chans[0], RTW89_MAC_0, RTW89_PHY_0); + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + return 0; + + __rtw89_set_channel(rtwdev, conf.chans[1], RTW89_MAC_1, RTW89_PHY_1); + + return 0; +} + +static enum rtw89_core_tx_type +rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (void *)skb->data; + __le16 fc = hdr->frame_control; + + if (ieee80211_is_mgmt(fc) || ieee80211_is_any_nullfunc(fc)) + return RTW89_CORE_TX_TYPE_MGMT; + + return RTW89_CORE_TX_TYPE_DATA; +} + +static void +rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req, + enum btc_pkt_type pkt_type) +{ + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct ieee80211_link_sta *link_sta; + struct sk_buff *skb = tx_req->skb; + struct rtw89_sta *rtwsta; + u8 ampdu_num; + u8 tid; + + if (pkt_type == PACKET_EAPOL) { + desc_info->bk = true; + return; + } + + if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU)) + return; + + if (!rtwsta_link) { + rtw89_warn(rtwdev, "cannot set ampdu info without sta\n"); + return; + } + + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + rtwsta = rtwsta_link->rtwsta; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? + rtwsta->ampdu_params[tid].agg_num : + 4 << link_sta->ht_cap.ampdu_factor) - 1); + + desc_info->agg_en = true; + desc_info->ampdu_density = link_sta->ht_cap.ampdu_density; + desc_info->ampdu_num = ampdu_num; + + rcu_read_unlock(); +} + +static void +rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_sec_cam_entry *sec_cam; + struct ieee80211_tx_info *info; + struct ieee80211_key_conf *key; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct sk_buff *skb = tx_req->skb; + u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; + u8 sec_cam_idx; + u64 pn64; + + info = IEEE80211_SKB_CB(skb); + key = info->control.hw_key; + sec_cam_idx = key->hw_key_idx; + sec_cam = cam_info->sec_entries[sec_cam_idx]; + if (!sec_cam) { + rtw89_warn(rtwdev, "sec cam entry is empty\n"); + return; + } + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + sec_type = RTW89_SEC_KEY_TYPE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + sec_type = RTW89_SEC_KEY_TYPE_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + sec_type = RTW89_SEC_KEY_TYPE_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + sec_type = RTW89_SEC_KEY_TYPE_CCMP128; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + sec_type = RTW89_SEC_KEY_TYPE_CCMP256; + break; + case WLAN_CIPHER_SUITE_GCMP: + sec_type = RTW89_SEC_KEY_TYPE_GCMP128; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + sec_type = RTW89_SEC_KEY_TYPE_GCMP256; + break; + default: + rtw89_warn(rtwdev, "key cipher not supported %d\n", key->cipher); + return; + } + + desc_info->sec_en = true; + desc_info->sec_keyid = key->keyidx; + desc_info->sec_type = sec_type; + desc_info->sec_cam_idx = sec_cam->sec_cam_idx; + + if (!chip->hw_sec_hdr) + return; + + pn64 = atomic64_inc_return(&key->tx_pn); + desc_info->sec_seq[0] = pn64; + desc_info->sec_seq[1] = pn64 >> 8; + desc_info->sec_seq[2] = pn64 >> 16; + desc_info->sec_seq[3] = pn64 >> 24; + desc_info->sec_seq[4] = pn64 >> 32; + desc_info->sec_seq[5] = pn64 >> 40; + desc_info->wp_offset = 1; /* in unit of 8 bytes for security header */ +} + +static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req, + const struct rtw89_chan *chan) +{ + struct sk_buff *skb = tx_req->skb; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = tx_info->control.vif; + struct ieee80211_bss_conf *bss_conf; + u16 lowest_rate; + u16 rate; + + if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || + (vif && vif->p2p)) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + if (!rtwvif_link) + return lowest_rate; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->basic_rates || !rtwsta_link) { + rate = lowest_rate; + goto out; + } + + rate = __ffs(bss_conf->basic_rates) + lowest_rate; + +out: + rcu_read_unlock(); + + return rate; +} + +static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + + if (desc_info->mlo && !desc_info->sw_mld) { + if (rtwsta_link) + return rtw89_sta_get_main_macid(rtwsta_link->rtwsta); + else + return rtw89_vif_get_main_macid(rtwvif_link->rtwvif); + } + + if (!rtwsta_link) + return rtwvif_link->mac_id; + + return rtwsta_link->mac_id; +} + +static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (void *)skb->data; + __le16 fc = hdr->frame_control; + + desc_info->hdr_llc_len = ieee80211_hdrlen(fc); + desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */ +} + +u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel) +{ + switch (qsel) { + default: + rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel); + fallthrough; + case RTW89_TX_QSEL_BE_0: + case RTW89_TX_QSEL_BE_1: + case RTW89_TX_QSEL_BE_2: + case RTW89_TX_QSEL_BE_3: + return RTW89_TXCH_ACH0; + case RTW89_TX_QSEL_BK_0: + case RTW89_TX_QSEL_BK_1: + case RTW89_TX_QSEL_BK_2: + case RTW89_TX_QSEL_BK_3: + return RTW89_TXCH_ACH1; + case RTW89_TX_QSEL_VI_0: + case RTW89_TX_QSEL_VI_1: + case RTW89_TX_QSEL_VI_2: + case RTW89_TX_QSEL_VI_3: + return RTW89_TXCH_ACH2; + case RTW89_TX_QSEL_VO_0: + case RTW89_TX_QSEL_VO_1: + case RTW89_TX_QSEL_VO_2: + case RTW89_TX_QSEL_VO_3: + return RTW89_TXCH_ACH3; + case RTW89_TX_QSEL_B0_MGMT: + return RTW89_TXCH_CH8; + case RTW89_TX_QSEL_B0_HI: + return RTW89_TXCH_CH9; + case RTW89_TX_QSEL_B1_MGMT: + return RTW89_TXCH_CH10; + case RTW89_TX_QSEL_B1_HI: + return RTW89_TXCH_CH11; + } +} +EXPORT_SYMBOL(rtw89_core_get_ch_dma); + +u8 rtw89_core_get_ch_dma_v1(struct rtw89_dev *rtwdev, u8 qsel) +{ + switch (qsel) { + default: + rtw89_warn(rtwdev, "Cannot map qsel to dma v1: %d\n", qsel); + fallthrough; + case RTW89_TX_QSEL_BE_0: + case RTW89_TX_QSEL_BK_0: + return RTW89_TXCH_ACH0; + case RTW89_TX_QSEL_VI_0: + case RTW89_TX_QSEL_VO_0: + return RTW89_TXCH_ACH2; + case RTW89_TX_QSEL_B0_MGMT: + case RTW89_TX_QSEL_B0_HI: + return RTW89_TXCH_CH8; + case RTW89_TX_QSEL_B1_MGMT: + case RTW89_TX_QSEL_B1_HI: + return RTW89_TXCH_CH10; + } +} +EXPORT_SYMBOL(rtw89_core_get_ch_dma_v1); + +u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel) +{ + switch (qsel) { + default: + rtw89_warn(rtwdev, "Cannot map qsel to dma v2: %d\n", qsel); + fallthrough; + case RTW89_TX_QSEL_BE_0: + case RTW89_TX_QSEL_VO_0: + return RTW89_TXCH_ACH0; + case RTW89_TX_QSEL_BK_0: + case RTW89_TX_QSEL_VI_0: + return RTW89_TXCH_ACH2; + case RTW89_TX_QSEL_B0_MGMT: + case RTW89_TX_QSEL_B0_HI: + return RTW89_TXCH_CH8; + case RTW89_TX_QSEL_B1_MGMT: + case RTW89_TX_QSEL_B1_HI: + return RTW89_TXCH_CH10; + } +} +EXPORT_SYMBOL(rtw89_core_get_ch_dma_v2); + +static void +rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct sk_buff *skb = tx_req->skb; + u8 qsel, ch_dma; + + qsel = rtw89_core_get_qsel_mgmt(rtwdev, tx_req); + ch_dma = rtw89_chip_get_ch_dma(rtwdev, qsel); + + desc_info->qsel = qsel; + desc_info->ch_dma = ch_dma; + desc_info->sw_mld = true; + desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; + desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); + desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL; + desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE; + + /* fixed data rate for mgmt frames */ + desc_info->en_wd_info = true; + desc_info->use_rate = true; + desc_info->dis_data_fb = true; + desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req, chan); + + if (chip->hw_mgmt_tx_encrypt && IEEE80211_SKB_CB(skb)->control.hw_key) { + rtw89_core_tx_update_sec_key(rtwdev, tx_req); + rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); + } + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n", + desc_info->data_rate, chan->channel, chan->band_type, + chan->band_width); +} + +static void +rtw89_core_tx_update_h2c_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + + desc_info->is_bmc = false; + desc_info->wd_page = false; + desc_info->ch_dma = RTW89_DMA_H2C; +} + +static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc, + const struct rtw89_chan *chan) +{ + static const u8 rtw89_bandwidth_to_om[] = { + [RTW89_CHANNEL_WIDTH_20] = HTC_OM_CHANNEL_WIDTH_20, + [RTW89_CHANNEL_WIDTH_40] = HTC_OM_CHANNEL_WIDTH_40, + [RTW89_CHANNEL_WIDTH_80] = HTC_OM_CHANNEL_WIDTH_80, + [RTW89_CHANNEL_WIDTH_160] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, + [RTW89_CHANNEL_WIDTH_80_80] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, + }; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + u8 om_bandwidth; + + if (!chip->dis_2g_40m_ul_ofdma || + chan->band_type != RTW89_BAND_2G || + chan->band_width != RTW89_CHANNEL_WIDTH_40) + return; + + om_bandwidth = chan->band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ? + rtw89_bandwidth_to_om[chan->band_width] : 0; + *htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | + le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) | + le32_encode_bits(hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) | + le32_encode_bits(om_bandwidth, RTW89_HTC_MASK_HTC_OM_CH_WIDTH) | + le32_encode_bits(1, RTW89_HTC_MASK_HTC_OM_UL_MU_DIS) | + le32_encode_bits(hal->tx_nss - 1, RTW89_HTC_MASK_HTC_OM_TX_NSTS) | + le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_ER_SU_DIS) | + le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR) | + le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS); +} + +static bool +__rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req, + enum btc_pkt_type pkt_type) +{ + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct ieee80211_vif *vif = tx_req->vif; + struct sk_buff *skb = tx_req->skb; + struct ieee80211_hdr *hdr = (void *)skb->data; + struct ieee80211_link_sta *link_sta; + __le16 fc = hdr->frame_control; + + /* AP IOT issue with EAPoL, ARP and DHCP */ + if (pkt_type < PACKET_MAX) + return false; + + if (!rtwsta_link) + return false; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (!link_sta->he_cap.has_he) { + rcu_read_unlock(); + return false; + } + + rcu_read_unlock(); + + if (!ieee80211_is_data_qos(fc)) + return false; + + if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN) + return false; + + if (rtwsta_link && rtwsta_link->ra_report.might_fallback_legacy) + return false; + + if (vif->type == NL80211_IFTYPE_AP) + return false; + + return true; +} + +static void +__rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct sk_buff *skb = tx_req->skb; + struct ieee80211_hdr *hdr = (void *)skb->data; + __le16 fc = hdr->frame_control; + void *data; + __le32 *htc; + u8 *qc; + int hdr_len; + + hdr_len = ieee80211_has_a4(fc) ? 32 : 26; + data = skb_push(skb, IEEE80211_HT_CTL_LEN); + memmove(data, data + IEEE80211_HT_CTL_LEN, hdr_len); + + hdr = data; + htc = data + hdr_len; + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER); + *htc = rtwsta_link->htc_template ? rtwsta_link->htc_template : + le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | + le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID); + + qc = data + hdr_len - IEEE80211_QOS_CTL_LEN; + qc[0] |= IEEE80211_QOS_CTL_EOSP; +} + +static void +rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req, + enum btc_pkt_type pkt_type) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + + if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) + goto desc_bk; + + __rtw89_core_tx_adjust_he_qos_htc(rtwdev, tx_req); + + desc_info->pkt_size += IEEE80211_HT_CTL_LEN; + desc_info->a_ctrl_bsr = true; + +desc_bk: + if (!rtwvif_link || rtwvif_link->last_a_ctrl == desc_info->a_ctrl_bsr) + return; + + rtwvif_link->last_a_ctrl = desc_info->a_ctrl_bsr; + desc_info->bk = true; +} + +static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; + enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); + struct ieee80211_link_sta *link_sta; + u16 lowest_rate; + u16 rate; + + if (rate_pattern->enable) + return rate_pattern->rate; + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + if (!rtwsta_link) + return lowest_rate; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (!link_sta->supp_rates[chan->band_type]) { + rate = lowest_rate; + goto out; + } + + rate = __ffs(link_sta->supp_rates[chan->band_type]) + lowest_rate; + +out: + rcu_read_unlock(); + + return rate; +} + +static void +rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct sk_buff *skb = tx_req->skb; + u8 tid, tid_indicate; + u8 qsel, ch_dma; + + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + tid_indicate = rtw89_core_get_tid_indicate(rtwdev, tid); + qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : rtw89_core_get_qsel(rtwdev, tid); + ch_dma = rtw89_chip_get_ch_dma(rtwdev, qsel); + + desc_info->ch_dma = ch_dma; + desc_info->tid_indicate = tid_indicate; + desc_info->qsel = qsel; + desc_info->sw_mld = false; + desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); + desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; + desc_info->er_cap = rtwsta_link ? rtwsta_link->er_cap : false; + desc_info->stbc = rtwsta_link ? rtwsta_link->ra.stbc_cap : false; + desc_info->ldpc = rtwsta_link ? rtwsta_link->ra.ldpc_cap : false; + + /* enable wd_info for AMPDU */ + desc_info->en_wd_info = true; + + if (IEEE80211_SKB_CB(skb)->control.hw_key) + rtw89_core_tx_update_sec_key(rtwdev, tx_req); + + desc_info->data_retry_lowest_rate = rtw89_core_get_data_rate(rtwdev, tx_req); +} + +static enum btc_pkt_type +rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + struct sk_buff *skb = tx_req->skb; + struct udphdr *udphdr; + + if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { + wiphy_work_queue(wiphy, &rtwdev->btc.eapol_notify_work); + return PACKET_EAPOL; + } + + if (skb->protocol == htons(ETH_P_ARP)) { + wiphy_work_queue(wiphy, &rtwdev->btc.arp_notify_work); + return PACKET_ARP; + } + + if (skb->protocol == htons(ETH_P_IP) && + ip_hdr(skb)->protocol == IPPROTO_UDP) { + udphdr = udp_hdr(skb); + if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) || + (udphdr->source == htons(68) && udphdr->dest == htons(67))) && + skb->len > 282) { + wiphy_work_queue(wiphy, &rtwdev->btc.dhcp_notify_work); + return PACKET_DHCP; + } + } + + if (skb->protocol == htons(ETH_P_IP) && + ip_hdr(skb)->protocol == IPPROTO_ICMP) { + wiphy_work_queue(wiphy, &rtwdev->btc.icmp_notify_work); + return PACKET_ICMP; + } + + return PACKET_MAX; +} + +static void +rtw89_core_tx_wake(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!RTW89_CHK_FW_FEATURE(TX_WAKE, &rtwdev->fw)) + return; + + switch (chip->chip_id) { + case RTL8852BT: + if (test_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) + goto notify; + break; + case RTL8852C: + if (test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) + goto notify; + break; + default: + if (test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags) && + tx_req->tx_type == RTW89_CORE_TX_TYPE_MGMT) + goto notify; + break; + } + + return; + +notify: + rtw89_mac_notify_wake(rtwdev); +} + +static void rtw89_core_tx_update_injection(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req, + struct ieee80211_tx_info *info) +{ + const struct rtw89_hw_rate_def *hw_rate = &rtw89_hw_rate[rtwdev->chip->chip_gen]; + enum mac80211_rate_control_flags flags = info->control.rates[0].flags; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + const struct rtw89_chan *chan; + u8 idx = info->control.rates[0].idx; + u8 nss, mcs; + + desc_info->use_rate = true; + desc_info->dis_data_fb = true; + + if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH) + desc_info->data_bw = 3; + else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + desc_info->data_bw = 2; + else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + desc_info->data_bw = 1; + + if (flags & IEEE80211_TX_RC_SHORT_GI) + desc_info->gi_ltf = 1; + + if (flags & IEEE80211_TX_RC_VHT_MCS) { + nss = umin(idx >> 4, ARRAY_SIZE(hw_rate->vht) - 1); + mcs = idx & 0xf; + desc_info->data_rate = hw_rate->vht[nss] + mcs; + } else if (flags & IEEE80211_TX_RC_MCS) { + desc_info->data_rate = hw_rate->ht + idx; + } else { + chan = rtw89_chan_get(rtwdev, tx_req->rtwvif_link->chanctx_idx); + + desc_info->data_rate = idx + (chan->band_type == RTW89_BAND_2G ? + RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6); + } +} + +static void +rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct sk_buff *skb = tx_req->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + struct rtw89_addr_cam_entry *addr_cam; + enum btc_pkt_type pkt_type; + bool upd_wlan_hdr = false; + bool is_bmc; + u16 seq; + + desc_info->pkt_size = skb->len; + + if (unlikely(tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD)) { + rtw89_core_tx_update_h2c_info(rtwdev, tx_req); + return; + } + + tx_req->tx_type = rtw89_core_get_tx_type(rtwdev, skb); + + if (tx_req->sta) + desc_info->mlo = tx_req->sta->mlo; + else if (tx_req->vif) + desc_info->mlo = ieee80211_vif_is_mld(tx_req->vif); + + seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link, + tx_req->rtwsta_link); + if (addr_cam->valid && desc_info->mlo) + upd_wlan_hdr = true; + + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS || tx_req->with_wait) + rtw89_tx_rpt_init(rtwdev, tx_req); + + is_bmc = (is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1)); + + desc_info->seq = seq; + desc_info->is_bmc = is_bmc; + desc_info->wd_page = true; + desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM; + desc_info->upd_wlan_hdr = upd_wlan_hdr; + + switch (tx_req->tx_type) { + case RTW89_CORE_TX_TYPE_MGMT: + rtw89_core_tx_update_mgmt_info(rtwdev, tx_req); + break; + case RTW89_CORE_TX_TYPE_DATA: + rtw89_core_tx_update_data_info(rtwdev, tx_req); + pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); + rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); + rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, pkt_type); + rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); + break; + default: + break; + } + + if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) + rtw89_core_tx_update_injection(rtwdev, tx_req, info); +} + +static void rtw89_tx_wait_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + tx_wait_work.work); + + rtw89_tx_wait_list_clear(rtwdev); +} + +void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel) +{ + u8 ch_dma; + + ch_dma = rtw89_chip_get_ch_dma(rtwdev, qsel); + + rtw89_hci_tx_kick_off(rtwdev, ch_dma); +} + +int rtw89_core_tx_kick_off_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, + struct rtw89_tx_wait_info *wait, int qsel, + unsigned int timeout) +{ + unsigned long time_left; + int ret = 0; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_core_tx_kick_off(rtwdev, qsel); + time_left = wait_for_completion_timeout(&wait->completion, + msecs_to_jiffies(timeout)); + + if (time_left == 0) { + ret = -ETIMEDOUT; + list_add_tail(&wait->list, &rtwdev->tx_waits); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->tx_wait_work, + RTW89_TX_WAIT_WORK_TIMEOUT); + } else { + if (!wait->tx_done) + ret = -EAGAIN; + rtw89_tx_wait_release(wait); + } + + return ret; +} + +int rtw89_h2c_tx(struct rtw89_dev *rtwdev, + struct sk_buff *skb, bool fwdl) +{ + struct rtw89_core_tx_request tx_req = {0}; + u32 cnt; + int ret; + + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "ignore h2c due to power is off with firmware state=%d\n", + test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)); + dev_kfree_skb(skb); + return 0; + } + + tx_req.skb = skb; + tx_req.tx_type = RTW89_CORE_TX_TYPE_FWCMD; + if (fwdl) + tx_req.desc_info.fw_dl = true; + + rtw89_core_tx_update_desc_info(rtwdev, &tx_req); + + if (!fwdl) + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "H2C: ", skb->data, skb->len); + + cnt = rtw89_hci_check_and_reclaim_tx_resource(rtwdev, RTW89_TXCH_CH12); + if (cnt == 0) { + rtw89_err(rtwdev, "no tx fwcmd resource\n"); + return -ENOSPC; + } + + ret = rtw89_hci_tx_write(rtwdev, &tx_req); + if (ret) { + rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); + return ret; + } + rtw89_hci_tx_kick_off(rtwdev, RTW89_TXCH_CH12); + + return 0; +} + +static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct sk_buff *skb, int *qsel, + struct rtw89_tx_wait_info *wait) +{ + struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_core_tx_request tx_req = {}; + int ret; + + tx_req.skb = skb; + tx_req.vif = vif; + tx_req.sta = sta; + tx_req.rtwvif_link = rtwvif_link; + tx_req.rtwsta_link = rtwsta_link; + tx_req.with_wait = !!wait; + + rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true); + rtw89_wow_parse_akm(rtwdev, skb); + rtw89_core_tx_update_desc_info(rtwdev, &tx_req); + rtw89_core_tx_wake(rtwdev, &tx_req); + + rcu_assign_pointer(skb_data->wait, wait); + + ret = rtw89_hci_tx_write(rtwdev, &tx_req); + if (ret) { + rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); + return ret; + } + + if (qsel) + *qsel = tx_req.desc_info.qsel; + + return 0; +} + +int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_vif_link *rtwvif_link; + + if (rtwsta) { + rtwsta_link = rtw89_get_designated_link(rtwsta); + if (unlikely(!rtwsta_link)) { + rtw89_err(rtwdev, "tx: find no sta designated link\n"); + return -ENOLINK; + } + + rtwvif_link = rtwsta_link->rtwvif_link; + } else { + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "tx: find no vif designated link\n"); + return -ENOLINK; + } + } + + return rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, qsel, NULL); +} + +static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET, desc_info->wp_offset) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | + FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | + FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | + FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl) | + FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_SEL, desc_info->hw_ssn_sel) | + FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_MODE, desc_info->hw_seq_mode); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET_V1, desc_info->wp_offset) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | + FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | + FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | + FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | + FIELD_PREP(RTW89_TXWD_BODY1_SEC_KEYID, desc_info->sec_keyid) | + FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) | + FIELD_PREP(RTW89_TXWD_BODY2_QSEL, desc_info->qsel) | + FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size) | + FIELD_PREP(RTW89_TXWD_BODY2_MACID, desc_info->mac_id); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY3_SW_SEQ, desc_info->seq) | + FIELD_PREP(RTW89_TXWD_BODY3_AGG_EN, desc_info->agg_en) | + FIELD_PREP(RTW89_TXWD_BODY3_BK, desc_info->bk); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body4(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | + FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body5(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | + FIELD_PREP(RTW89_TXWD_BODY7_DATA_BW, desc_info->data_bw) | + FIELD_PREP(RTW89_TXWD_BODY7_GI_LTF, desc_info->gi_ltf) | + FIELD_PREP(RTW89_TXWD_BODY7_DATA_RATE, desc_info->data_rate); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW, desc_info->data_bw) | + FIELD_PREP(RTW89_TXWD_INFO0_GI_LTF, desc_info->gi_ltf) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) | + FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) | + FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) | + FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) | + FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_ER, desc_info->er_cap) | + FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW_ER, 0); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | + FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | + FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, + desc_info->data_retry_lowest_rate) | + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL, + desc_info->tx_cnt_lmt_en) | + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(RTW89_TXWD_INFO2_SEC_TYPE, desc_info->sec_type) | + FIELD_PREP(RTW89_TXWD_INFO2_SEC_HW_ENC, desc_info->sec_en) | + FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info2_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(RTW89_TXWD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | + FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO3_SPE_RPT, desc_info->report); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) +{ + bool rts_en = !desc_info->is_bmc; + u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, rts_en) | + FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1) | + FIELD_PREP(RTW89_TXWD_INFO4_SW_DEFINE, desc_info->sn); + + return cpu_to_le32(dword); +} + +void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body *txwd_body = (struct rtw89_txwd_body *)txdesc; + struct rtw89_txwd_info *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); + + if (!desc_info->en_wd_info) + return; + + txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2(desc_info); + txwd_info->dword3 = rtw89_build_txwd_info3(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); + +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc); + +void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body_v1 *txwd_body = (struct rtw89_txwd_body_v1 *)txdesc; + struct rtw89_txwd_info *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0_v1(desc_info); + txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); + if (desc_info->sec_en) { + txwd_body->dword4 = rtw89_build_txwd_body4(desc_info); + txwd_body->dword5 = rtw89_build_txwd_body5(desc_info); + } + txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info); + + if (!desc_info->en_wd_info) + return; + + txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0_v1(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2_v1(desc_info); + txwd_info->dword3 = rtw89_build_txwd_info3(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1); + +static __le32 rtw89_build_txwd_body0_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY0_WP_OFFSET_V1, desc_info->wp_offset) | + FIELD_PREP(BE_TXD_BODY0_WDINFO_EN, desc_info->en_wd_info) | + FIELD_PREP(BE_TXD_BODY0_CH_DMA, desc_info->ch_dma) | + FIELD_PREP(BE_TXD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | + FIELD_PREP(BE_TXD_BODY0_WD_PAGE, desc_info->wd_page); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body1_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | + FIELD_PREP(BE_TXD_BODY1_SEC_KEYID, desc_info->sec_keyid) | + FIELD_PREP(BE_TXD_BODY1_SEC_TYPE, desc_info->sec_type); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body2_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY2_TID_IND, desc_info->tid_indicate) | + FIELD_PREP(BE_TXD_BODY2_QSEL, desc_info->qsel) | + FIELD_PREP(BE_TXD_BODY2_TXPKTSIZE, desc_info->pkt_size) | + FIELD_PREP(BE_TXD_BODY2_AGG_EN, desc_info->agg_en) | + FIELD_PREP(BE_TXD_BODY2_BK, desc_info->bk) | + FIELD_PREP(BE_TXD_BODY2_MACID, desc_info->mac_id); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body2_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY2_TID_IND_V1, desc_info->tid_indicate) | + FIELD_PREP(BE_TXD_BODY2_QSEL_V1, desc_info->qsel) | + FIELD_PREP(BE_TXD_BODY2_TXPKTSIZE, desc_info->pkt_size) | + FIELD_PREP(BE_TXD_BODY2_AGG_EN, desc_info->agg_en) | + FIELD_PREP(BE_TXD_BODY2_MACID_V1, desc_info->mac_id); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body3_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq) | + FIELD_PREP(BE_TXD_BODY3_MLO_FLAG, desc_info->mlo) | + FIELD_PREP(BE_TXD_BODY3_IS_MLD_SW_EN, desc_info->sw_mld); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body3_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq) | + FIELD_PREP(BE_TXD_BODY3_MLO_FLAG, desc_info->mlo) | + FIELD_PREP(BE_TXD_BODY3_IS_MLD_SW_EN, desc_info->sw_mld) | + FIELD_PREP(BE_TXD_BODY3_BK_V1, desc_info->bk); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body4_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | + FIELD_PREP(BE_TXD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body5_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) | + FIELD_PREP(BE_TXD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) | + FIELD_PREP(BE_TXD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) | + FIELD_PREP(BE_TXD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body6_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY6_UPD_WLAN_HDR, desc_info->upd_wlan_hdr); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) | + FIELD_PREP(BE_TXD_BODY7_DATA_BW, desc_info->data_bw) | + FIELD_PREP(BE_TXD_BODY7_GI_LTF, desc_info->gi_ltf) | + FIELD_PREP(BE_TXD_BODY7_DATA_ER, desc_info->er_cap) | + FIELD_PREP(BE_TXD_BODY7_DATA_BW_ER, 0) | + FIELD_PREP(BE_TXD_BODY7_DATARATE, desc_info->data_rate); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info0_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_INFO0_DATA_STBC, desc_info->stbc) | + FIELD_PREP(BE_TXD_INFO0_DATA_LDPC, desc_info->ldpc) | + FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) | + FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port) | + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT_SEL, + desc_info->tx_cnt_lmt_en) | + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info1_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_INFO1_MAX_AGG_NUM, desc_info->ampdu_num) | + FIELD_PREP(BE_TXD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | + FIELD_PREP(BE_TXD_INFO1_DATA_RTY_LOWEST_RATE, + desc_info->data_retry_lowest_rate) | + FIELD_PREP(BE_TXD_INFO1_SW_DEFINE, desc_info->sn); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info2_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | + FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx) | + FIELD_PREP(BE_TXD_INFO2_SPE_RPT_V1, desc_info->report); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info2_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN_V1, desc_info->sec_en) | + FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX_V1, desc_info->sec_cam_idx); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_info4_v2(struct rtw89_tx_desc_info *desc_info) +{ + bool rts_en = !desc_info->is_bmc; + u32 dword = FIELD_PREP(BE_TXD_INFO4_RTS_EN, rts_en) | + FIELD_PREP(BE_TXD_INFO4_HW_RTS_EN, 1); + + return cpu_to_le32(dword); +} + +void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body_v2 *txwd_body = txdesc; + struct rtw89_txwd_info_v2 *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0_v2(desc_info); + txwd_body->dword1 = rtw89_build_txwd_body1_v2(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2_v2(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3_v2(desc_info); + if (desc_info->sec_en) { + txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info); + txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info); + } + txwd_body->dword6 = rtw89_build_txwd_body6_v2(desc_info); + txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info); + + if (!desc_info->en_wd_info) + return; + + txwd_info = (struct rtw89_txwd_info_v2 *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0_v2(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1_v2(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2_v2(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4_v2(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_v2); + +void rtw89_core_fill_txdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body_v2 *txwd_body = txdesc; + struct rtw89_txwd_info_v2 *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0_v2(desc_info); + txwd_body->dword1 = rtw89_build_txwd_body1_v2(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2_v3(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3_v3(desc_info); + if (desc_info->sec_en) { + txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info); + txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info); + } + txwd_body->dword6 = rtw89_build_txwd_body6_v2(desc_info); + txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info); + + if (!desc_info->en_wd_info) + return; + + txwd_info = (struct rtw89_txwd_info_v2 *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0_v2(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1_v2(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2_v3(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4_v2(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_v3); + +static __le32 rtw89_build_txwd_fwcmd0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(AX_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | + FIELD_PREP(AX_RXD_RPKT_TYPE_MASK, desc_info->fw_dl ? + RTW89_CORE_RX_TYPE_FWDL : + RTW89_CORE_RX_TYPE_H2C); + + return cpu_to_le32(dword); +} + +void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_rxdesc_short *txwd_v1 = (struct rtw89_rxdesc_short *)txdesc; + + txwd_v1->dword0 = rtw89_build_txwd_fwcmd0_v1(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_fwcmd_v1); + +static __le32 rtw89_build_txwd_fwcmd0_v2(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | + FIELD_PREP(BE_RXD_RPKT_TYPE_MASK, desc_info->fw_dl ? + RTW89_CORE_RX_TYPE_FWDL : + RTW89_CORE_RX_TYPE_H2C); + + return cpu_to_le32(dword); +} + +void rtw89_core_fill_txdesc_fwcmd_v2(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_rxdesc_short_v2 *txwd_v2 = (struct rtw89_rxdesc_short_v2 *)txdesc; + + txwd_v2->dword0 = rtw89_build_txwd_fwcmd0_v2(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_fwcmd_v2); + +static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_rxinfo *rxinfo = (const struct rtw89_rxinfo *)skb->data; + const struct rtw89_rxinfo_user *user; + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + int rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE; + bool rx_cnt_valid = false; + bool invalid = false; + u8 plcp_size = 0; + u8 *phy_sts; + u8 usr_num; + int i; + + if (chip_gen == RTW89_CHIP_BE) { + invalid = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_INVALID_V1); + rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE_V1; + } + + if (invalid) + return -EINVAL; + + rx_cnt_valid = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_RX_CNT_VLD); + if (chip_gen == RTW89_CHIP_BE) { + plcp_size = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_PLCP_LEN_V1) << 3; + usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM_V1); + } else { + plcp_size = le32_get_bits(rxinfo->w1, RTW89_RXINFO_W1_PLCP_LEN) << 3; + usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM); + } + if (usr_num > chip->ppdu_max_usr) { + rtw89_warn(rtwdev, "Invalid user number (%d) in mac info\n", + usr_num); + return -EINVAL; + } + + for (i = 0; i < usr_num; i++) { + user = &rxinfo->user[i]; + if (!le32_get_bits(user->w0, RTW89_RXINFO_USER_MAC_ID_VALID)) + continue; + /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set + * by hardware, so update mac_id by rxinfo_user[].mac_id. + */ + if (chip->chip_id == RTL8922A) + phy_ppdu->mac_id = + le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID); + else if (chip->chip_id == RTL8922D) + phy_ppdu->mac_id = + le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID_V1); + + phy_ppdu->has_data = + le32_get_bits(user->w0, RTW89_RXINFO_USER_DATA); + phy_ppdu->has_bcn = + le32_get_bits(user->w0, RTW89_RXINFO_USER_BCN); + break; + } + + phy_sts = skb->data + RTW89_PPDU_MAC_INFO_SIZE; + phy_sts += usr_num * RTW89_PPDU_MAC_INFO_USR_SIZE; + /* 8-byte alignment */ + if (usr_num & BIT(0)) + phy_sts += RTW89_PPDU_MAC_INFO_USR_SIZE; + if (rx_cnt_valid) + phy_sts += rx_cnt_size; + phy_sts += plcp_size; + + if (phy_sts > skb->data + skb->len) + return -EINVAL; + + phy_ppdu->buf = phy_sts; + phy_ppdu->len = skb->data + skb->len - phy_sts; + + return 0; +} + +static u8 rtw89_get_data_rate_nss(struct rtw89_dev *rtwdev, u16 data_rate) +{ + u8 data_rate_mode; + + data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate); + switch (data_rate_mode) { + case DATA_RATE_MODE_NON_HT: + return 1; + case DATA_RATE_MODE_HT: + return rtw89_get_data_ht_nss(rtwdev, data_rate) + 1; + case DATA_RATE_MODE_VHT: + case DATA_RATE_MODE_HE: + case DATA_RATE_MODE_EHT: + return rtw89_get_data_nss(rtwdev, data_rate) + 1; + default: + rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); + return 0; + } +} + +static void rtw89_core_rx_process_phy_ppdu_iter(void *data, + struct ieee80211_sta *sta) +{ + struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_sta_link *rtwsta_link; + u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; + u8 ant_pos = U8_MAX; + u8 evm_pos = 0; + int i; + + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, phy_ppdu->phy_idx); + if (unlikely(!rtwsta_link)) + return; + + if (rtwsta_link->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) + return; + + if (hal->ant_diversity && hal->antenna_rx) { + ant_pos = __ffs(hal->antenna_rx); + evm_pos = ant_pos; + } + + ewma_rssi_add(&rtwsta_link->avg_rssi, phy_ppdu->rssi_avg); + + if (ant_pos < ant_num) { + ewma_rssi_add(&rtwsta_link->rssi[ant_pos], phy_ppdu->rssi[0]); + } else { + for (i = 0; i < rtwdev->chip->rf_path_num; i++) + ewma_rssi_add(&rtwsta_link->rssi[i], phy_ppdu->rssi[i]); + } + + if (phy_ppdu->ofdm.has && (phy_ppdu->has_data || phy_ppdu->has_bcn)) { + ewma_snr_add(&rtwsta_link->avg_snr, phy_ppdu->ofdm.avg_snr); + if (rtw89_get_data_rate_nss(rtwdev, phy_ppdu->rate) == 1) { + ewma_evm_add(&rtwsta_link->evm_1ss, phy_ppdu->ofdm.evm_min); + } else { + ewma_evm_add(&rtwsta_link->evm_min[evm_pos], + phy_ppdu->ofdm.evm_min); + ewma_evm_add(&rtwsta_link->evm_max[evm_pos], + phy_ppdu->ofdm.evm_max); + } + } +} + +static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const u8 *physts_ie_len_tab = phy->physt_ie_len; + u16 ie_len; + u8 ie; + + ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); + if (physts_ie_len_tab[ie] != VAR_LEN) + ie_len = physts_ie_len_tab[ie]; + else + ie_len = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_LEN) * VAR_LEN_UNIT; + + return ie_len; +} + +static void rtw89_core_parse_phy_status_ie01_v2(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_ie01_v2 *ie; + u8 *rpl_fd = phy_ppdu->rpl_fd; + + ie = (const struct rtw89_phy_sts_ie01_v2 *)iehdr; + rpl_fd[RF_PATH_A] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A); + rpl_fd[RF_PATH_B] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B); + rpl_fd[RF_PATH_C] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C); + rpl_fd[RF_PATH_D] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D); + + phy_ppdu->bw_idx = le32_get_bits(ie->w5, RTW89_PHY_STS_IE01_V2_W5_BW_IDX); +} + +static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_ie01 *ie = (const struct rtw89_phy_sts_ie01 *)iehdr; + s16 cfo; + u32 t; + + phy_ppdu->chan_idx = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_CH_IDX); + phy_ppdu->ldpc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_LDPC); + phy_ppdu->stbc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_STBC); + phy_ppdu->bf = le32_get_bits(ie->w3, RTW89_PHY_STS_IE01_W3_BF); + + if (!phy_ppdu->hdr_2_en) + phy_ppdu->rx_path_en = + le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RX_PATH_EN); + + if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) + return; + + if (!phy_ppdu->to_self) + return; + + phy_ppdu->rpl_avg = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD); + phy_ppdu->su = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_SU); + phy_ppdu->ofdm.avg_snr = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_AVG_SNR); + phy_ppdu->ofdm.evm_max = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MAX); + phy_ppdu->ofdm.evm_min = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MIN); + phy_ppdu->ofdm.has = true; + + /* sign conversion for S(12,2) */ + if (rtwdev->chip->cfo_src_fd) { + t = le32_get_bits(ie->w1, RTW89_PHY_STS_IE01_W1_FD_CFO); + cfo = sign_extend32(t, 11); + } else { + t = le32_get_bits(ie->w1, RTW89_PHY_STS_IE01_W1_PREMB_CFO); + cfo = sign_extend32(t, 11); + } + + rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + rtw89_core_parse_phy_status_ie01_v2(rtwdev, iehdr, phy_ppdu); +} + +static void rtw89_core_parse_phy_status_ie00(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_ie00 *ie = (const struct rtw89_phy_sts_ie00 *)iehdr; + u16 tmp_rpl; + + tmp_rpl = le32_get_bits(ie->w0, RTW89_PHY_STS_IE00_W0_RPL); + phy_ppdu->rpl_avg = tmp_rpl >> 1; + + if (!phy_ppdu->hdr_2_en) + phy_ppdu->rx_path_en = + le32_get_bits(ie->w3, RTW89_PHY_STS_IE00_W3_RX_PATH_EN); +} + +static void rtw89_core_parse_phy_status_ie00_v2(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_ie00_v2 *ie; + u8 *rpl_path = phy_ppdu->rpl_path; + u16 tmp_rpl[RF_PATH_MAX]; + u8 i; + + ie = (const struct rtw89_phy_sts_ie00_v2 *)iehdr; + tmp_rpl[RF_PATH_A] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A); + tmp_rpl[RF_PATH_B] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B); + tmp_rpl[RF_PATH_C] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C); + tmp_rpl[RF_PATH_D] = le32_get_bits(ie->w5, RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D); + + for (i = 0; i < RF_PATH_MAX; i++) + rpl_path[i] = tmp_rpl[i] >> 1; +} + +static void rtw89_core_parse_phy_status_ie09(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const union rtw89_phy_sts_ie09 *ie09; + u16 ie_len; + + ie09 = (const void *)iehdr; + + if (phy->physt_gen >= 2) { + ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, (const void *)iehdr); + if (ie_len < sizeof(ie09->gen2)) + return; + } + + phy_ppdu->ie09 = ie09; +} + +static void rtw89_core_parse_phy_status_ie10(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + phy_ppdu->ie10 = (const void *)iehdr; +} + +static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_iehdr *iehdr, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + bool accept; + u8 ie; + + ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); + + /* + * For normal mode, only parse ppdu_sts that are A1-matched, except for + * scanning that needs to get chan_idx in IE01. + */ + accept = phy_ppdu->to_self || ie == RTW89_PHYSTS_IE01_CMN_OFDM || + rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR; + if (!accept) + return 0; + + switch (ie) { + case RTW89_PHYSTS_IE00_CMN_CCK: + rtw89_core_parse_phy_status_ie00(rtwdev, iehdr, phy_ppdu); + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + rtw89_core_parse_phy_status_ie00_v2(rtwdev, iehdr, phy_ppdu); + break; + case RTW89_PHYSTS_IE01_CMN_OFDM: + rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu); + break; + case RTW89_PHYSTS_IE09_FTR_0: + rtw89_core_parse_phy_status_ie09(rtwdev, iehdr, phy_ppdu); + break; + case RTW89_PHYSTS_IE10_FTR_PLCP_EXT: + rtw89_core_parse_phy_status_ie10(rtwdev, iehdr, phy_ppdu); + break; + default: + break; + } + + return 0; +} + +static void rtw89_core_update_phy_ppdu_hdr_v2(struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_hdr_v2 *hdr = phy_ppdu->buf + PHY_STS_HDR_LEN; + + phy_ppdu->rx_path_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_V2_W0_PATH_EN); +} + +static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; + u8 *rssi = phy_ppdu->rssi; + + phy_ppdu->ie = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_IE_MAP); + phy_ppdu->rssi_avg = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_RSSI_AVG); + rssi[RF_PATH_A] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_A); + rssi[RF_PATH_B] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_B); + rssi[RF_PATH_C] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_C); + rssi[RF_PATH_D] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_D); + + phy_ppdu->hdr_2_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_HDR_2_EN); + if (phy_ppdu->hdr_2_en) + rtw89_core_update_phy_ppdu_hdr_v2(phy_ppdu); +} + +static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; + u32 len_from_header; + bool physts_valid; + + physts_valid = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_VALID); + if (!physts_valid) + return -EINVAL; + + len_from_header = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_LEN) << 3; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + len_from_header += PHY_STS_HDR_LEN; + + if (len_from_header != phy_ppdu->len) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "phy ppdu len mismatch\n"); + return -EINVAL; + } + rtw89_core_update_phy_ppdu(phy_ppdu); + + return 0; +} + +static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + void *pos, *end; + bool accept; + u16 ie_len; + + /* for normal mode, mark invalid reports and bypass them */ + accept = phy_ppdu->ie >= RTW89_CCK_PKT || + rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR; + if (!accept) + return -EINVAL; + + pos = phy_ppdu->buf + PHY_STS_HDR_LEN; + if (phy_ppdu->hdr_2_en) + pos += PHY_STS_HDR_LEN; + end = phy_ppdu->buf + phy_ppdu->len; + while (pos < end) { + const struct rtw89_phy_sts_iehdr *iehdr = pos; + + /* + * RTL8922D might reports 8 bytes zeros at end if IE09 presents. + * Check and ignore the zeros. + */ + if (unlikely(phy_ppdu->ie09 && end - pos == 8 && iehdr->w0 == 0)) + break; + + ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, iehdr); + pos += ie_len; + if (pos > end || ie_len == 0) { + /* clear pointers to prevent accessing out of IE */ + phy_ppdu->ie09 = NULL; + phy_ppdu->ie10 = NULL; + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "phy status parse failed\n"); + + return -EINVAL; + } + + rtw89_core_process_phy_status_ie(rtwdev, iehdr, phy_ppdu); + } + + rtw89_chip_convert_rpl_to_rssi(rtwdev, phy_ppdu); + rtw89_phy_antdiv_parse(rtwdev, phy_ppdu); + + return 0; +} + +static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + int ret; + + ret = rtw89_core_rx_parse_phy_sts(rtwdev, phy_ppdu); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_TXRX, "parse phy sts failed\n"); + else + phy_ppdu->valid = true; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_core_rx_process_phy_ppdu_iter, + phy_ppdu); +} + +static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev, + u8 desc_info_gi, + bool rx_status) +{ + switch (desc_info_gi) { + case RTW89_GILTF_SGI_4XHE08: + case RTW89_GILTF_2XHE08: + case RTW89_GILTF_1XHE08: + return NL80211_RATE_INFO_HE_GI_0_8; + case RTW89_GILTF_2XHE16: + case RTW89_GILTF_1XHE16: + return NL80211_RATE_INFO_HE_GI_1_6; + case RTW89_GILTF_LGI_4XHE32: + return NL80211_RATE_INFO_HE_GI_3_2; + default: + rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi); + if (rx_status) + return NL80211_RATE_INFO_HE_GI_3_2; + return U8_MAX; + } +} + +static u8 rtw89_rxdesc_to_nl_eht_gi(struct rtw89_dev *rtwdev, + u8 desc_info_gi, + bool rx_status) +{ + switch (desc_info_gi) { + case RTW89_GILTF_SGI_4XHE08: + case RTW89_GILTF_2XHE08: + case RTW89_GILTF_1XHE08: + return NL80211_RATE_INFO_EHT_GI_0_8; + case RTW89_GILTF_2XHE16: + case RTW89_GILTF_1XHE16: + return NL80211_RATE_INFO_EHT_GI_1_6; + case RTW89_GILTF_LGI_4XHE32: + return NL80211_RATE_INFO_EHT_GI_3_2; + default: + rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi); + if (rx_status) + return NL80211_RATE_INFO_EHT_GI_3_2; + return U8_MAX; + } +} + +static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev, + u8 desc_info_gi, + bool rx_status, bool eht) +{ + return eht ? rtw89_rxdesc_to_nl_eht_gi(rtwdev, desc_info_gi, rx_status) : + rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info_gi, rx_status); +} + +static +bool rtw89_check_rx_statu_gi_match(struct ieee80211_rx_status *status, u8 gi_ltf, + bool eht) +{ + if (eht) + return status->eht.gi == gi_ltf; + + return status->he_gi == gi_ltf; +} + +static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *status) +{ + u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; + u8 data_rate_mode, bw, rate_idx = MASKBYTE0, gi_ltf; + bool eht = false; + u16 data_rate; + bool ret; + + data_rate = desc_info->data_rate; + data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate); + if (data_rate_mode == DATA_RATE_MODE_NON_HT) { + rate_idx = rtw89_get_data_not_ht_idx(rtwdev, data_rate); + /* rate_idx is still hardware value here */ + } else if (data_rate_mode == DATA_RATE_MODE_HT) { + rate_idx = rtw89_get_data_ht_mcs(rtwdev, data_rate); + } else if (data_rate_mode == DATA_RATE_MODE_VHT || + data_rate_mode == DATA_RATE_MODE_HE || + data_rate_mode == DATA_RATE_MODE_EHT) { + rate_idx = rtw89_get_data_mcs(rtwdev, data_rate); + } else { + rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); + } + + eht = data_rate_mode == DATA_RATE_MODE_EHT; + bw = rtw89_hw_to_rate_info_bw(desc_info->bw); + gi_ltf = rtw89_rxdesc_to_nl_he_eht_gi(rtwdev, desc_info->gi_ltf, false, eht); + ret = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band] == desc_info->ppdu_cnt && + status->rate_idx == rate_idx && + rtw89_check_rx_statu_gi_match(status, gi_ltf, eht) && + status->bw == bw; + + return ret; +} + +struct rtw89_vif_rx_stats_iter_data { + struct rtw89_dev *rtwdev; + struct rtw89_rx_phy_ppdu *phy_ppdu; + struct rtw89_rx_desc_info *desc_info; + struct sk_buff *skb; + const u8 *bssid; +}; + +static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf, + struct sk_buff *skb) +{ + struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + u8 *pos, *end, type, tf_bw; + u16 aid, tf_rua; + + if (!ether_addr_equal(bss_conf->bssid, tf->ta) || + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION || + rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK) + return; + + type = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_TYPE_MASK); + if (type != IEEE80211_TRIGGER_TYPE_BASIC && type != IEEE80211_TRIGGER_TYPE_MU_BAR) + return; + + end = (u8 *)tf + skb->len; + pos = tf->variable; + + while (end - pos >= RTW89_TF_BASIC_USER_INFO_SZ) { + aid = RTW89_GET_TF_USER_INFO_AID12(pos); + tf_rua = RTW89_GET_TF_USER_INFO_RUA(pos); + tf_bw = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_ULBW_MASK); + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "[TF] aid: %d, ul_mcs: %d, rua: %d, bw: %d\n", + aid, RTW89_GET_TF_USER_INFO_UL_MCS(pos), + tf_rua, tf_bw); + + if (aid == RTW89_TF_PAD) + break; + + if (aid == vif->cfg.aid) { + enum nl80211_he_ru_alloc rua; + + rtwvif->stats.rx_tf_acc++; + rtwdev->stats.rx_tf_acc++; + + /* The following only required for HE trigger frame, but we + * cannot use UL HE-SIG-A2 reserved subfield to identify it + * since some 11ax APs will fill it with all 0s, which will + * be misunderstood as EHT trigger frame. + */ + if (bss_conf->eht_support) + break; + + rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1); + + if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ && + rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106) + rtwvif_link->pwr_diff_en = true; + break; + } + + pos += RTW89_TF_BASIC_USER_INFO_SZ; + } +} + +static void rtw89_cancel_6ghz_probe_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + cancel_6ghz_probe_work); + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; + struct rtw89_pktofld_info *info; + + lockdep_assert_wiphy(wiphy); + + if (!rtwdev->scanning) + return; + + list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { + if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload)) + continue; + + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + + /* Don't delete/free info from pkt_list at this moment. Let it + * be deleted/freed in rtw89_release_pkt_list() after scanning, + * since if during scanning, pkt_list is accessed in bottom half. + */ + } +} + +static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; + struct rtw89_pktofld_info *info; + const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; + bool queue_work = false; + + if (rx_status->band != NL80211_BAND_6GHZ) + return; + + if (unlikely(!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rx on unsupported 6 GHz\n"); + return; + } + + ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, ies, skb->len); + + list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { + if (ether_addr_equal(info->bssid, mgmt->bssid)) { + info->cancel = true; + queue_work = true; + continue; + } + + if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) + continue; + + if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) { + info->cancel = true; + queue_work = true; + } + } + + if (queue_work) + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->cancel_6ghz_probe_work); +} + +static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link, + struct ieee80211_hdr *hdr, size_t len) +{ + struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr; + + if (len < offsetof(typeof(*mgmt), u.beacon.variable)) + return; + + WRITE_ONCE(rtwvif_link->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp)); +} + +static u32 rtw89_bcn_calc_min_tbtt(struct rtw89_dev *rtwdev, u32 tbtt1, u32 tbtt2) +{ + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + u32 close_bcn_intvl_th = bcn_track->close_bcn_intvl_th; + u32 tbtt_diff_th = bcn_track->tbtt_diff_th; + + if (tbtt2 > tbtt1) + swap(tbtt1, tbtt2); + + if (tbtt1 - tbtt2 > tbtt_diff_th) + return tbtt1; + else if (tbtt2 > close_bcn_intvl_th) + return tbtt2; + else if (tbtt1 > close_bcn_intvl_th) + return tbtt1; + else + return tbtt2; +} + +static void rtw89_bcn_cfg_tbtt_offset(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 offset = bcn_track->tbtt_offset; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u32 bcnspc, val; + + bcnspc = rtw89_read32_port_mask(rtwdev, rtwvif_link, + p->bcn_space, B_AX_BCN_SPACE_MASK); + val = bcnspc - (offset / 1024); + val = u32_encode_bits(val, B_AX_TBTT_SHIFT_OFST_MAG) | + B_AX_TBTT_SHIFT_OFST_SIGN; + + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_shift, + B_AX_TBTT_SHIFT_OFST_MASK, val); + + return; + } + + rtw89_fw_h2c_tbtt_tuning(rtwdev, rtwvif_link, offset); +} + +static void rtw89_bcn_update_tbtt_offset(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + u32 *tbtt_us = bcn_stat->tbtt_us; + u32 offset = tbtt_us[0]; + u8 i; + + for (i = 1; i < RTW89_BCN_TRACK_STAT_NR; i++) + offset = rtw89_bcn_calc_min_tbtt(rtwdev, tbtt_us[i], offset); + + if (bcn_track->tbtt_offset == offset) + return; + + bcn_track->tbtt_offset = offset; + rtw89_bcn_cfg_tbtt_offset(rtwdev, rtwvif_link); +} + +static int cmp_u16(const void *a, const void *b) +{ + return *(const u16 *)a - *(const u16 *)b; +} + +static u16 _rtw89_bcn_calc_drift(u16 tbtt, u16 offset, u16 beacon_int) +{ + if (tbtt < offset) + return beacon_int - offset + tbtt; + + return tbtt - offset; +} + +static void rtw89_bcn_calc_drift(struct rtw89_dev *rtwdev) +{ + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + u16 offset_tu = bcn_track->tbtt_offset / 1024; + u16 *tbtt_tu = bcn_stat->tbtt_tu; + u16 *drift = bcn_stat->drift; + u8 i; + + bcn_stat->tbtt_tu_min = U16_MAX; + bcn_stat->tbtt_tu_max = 0; + for (i = 0; i < RTW89_BCN_TRACK_STAT_NR; i++) { + drift[i] = _rtw89_bcn_calc_drift(tbtt_tu[i], offset_tu, + bcn_track->beacon_int); + + bcn_stat->tbtt_tu_min = min(bcn_stat->tbtt_tu_min, tbtt_tu[i]); + bcn_stat->tbtt_tu_max = max(bcn_stat->tbtt_tu_max, tbtt_tu[i]); + } + + sort(drift, RTW89_BCN_TRACK_STAT_NR, sizeof(*drift), cmp_u16, NULL); +} + +static void rtw89_bcn_calc_distribution(struct rtw89_dev *rtwdev) +{ + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_dist *bcn_dist = &bcn_stat->bcn_dist; + u16 lower_bound, upper_bound, outlier_count = 0; + u16 *drift = bcn_stat->drift; + u16 *bins = bcn_dist->bins; + u16 q1, q3, iqr, tmp; + u8 i; + + BUILD_BUG_ON(RTW89_BCN_TRACK_STAT_NR % 4 != 0); + + memset(bcn_dist, 0, sizeof(*bcn_dist)); + + bcn_dist->min = drift[0]; + bcn_dist->max = drift[RTW89_BCN_TRACK_STAT_NR - 1]; + + tmp = RTW89_BCN_TRACK_STAT_NR / 4; + q1 = ((drift[tmp] + drift[tmp - 1]) * RTW89_BCN_TRACK_SCALE_FACTOR) / 2; + + tmp = (RTW89_BCN_TRACK_STAT_NR * 3) / 4; + q3 = ((drift[tmp] + drift[tmp - 1]) * RTW89_BCN_TRACK_SCALE_FACTOR) / 2; + + iqr = q3 - q1; + tmp = (3 * iqr) / 2; + + if (bcn_dist->min <= 5) + lower_bound = bcn_dist->min; + else if (q1 > tmp) + lower_bound = (q1 - tmp) / RTW89_BCN_TRACK_SCALE_FACTOR; + else + lower_bound = 0; + + upper_bound = (q3 + tmp) / RTW89_BCN_TRACK_SCALE_FACTOR; + + for (i = 0; i < RTW89_BCN_TRACK_STAT_NR; i++) { + u16 tbtt = bcn_stat->tbtt_tu[i]; + u16 min = bcn_stat->tbtt_tu_min; + u8 bin_idx; + + /* histogram */ + bin_idx = min((tbtt - min) / RTW89_BCN_TRACK_BIN_WIDTH, + RTW89_BCN_TRACK_MAX_BIN_NUM - 1); + bins[bin_idx]++; + + /* boxplot outlier */ + if (drift[i] < lower_bound || drift[i] > upper_bound) + outlier_count++; + } + + bcn_dist->outlier_count = outlier_count; + bcn_dist->lower_bound = lower_bound; + bcn_dist->upper_bound = upper_bound; +} + +static u8 rtw89_bcn_get_coverage(struct rtw89_dev *rtwdev, u16 threshold) +{ + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + int l = 0, r = RTW89_BCN_TRACK_STAT_NR - 1, m; + u16 *drift = bcn_stat->drift; + int index = -1; + u8 count = 0; + + while (l <= r) { + m = l + (r - l) / 2; + + if (drift[m] <= threshold) { + index = m; + l = m + 1; + } else { + r = m - 1; + } + } + + count = (index == -1) ? 0 : (index + 1); + + return (count * PERCENT) / RTW89_BCN_TRACK_STAT_NR; +} + +static u16 rtw89_bcn_get_histogram_bound(struct rtw89_dev *rtwdev, u8 target) +{ + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_dist *bcn_dist = &bcn_stat->bcn_dist; + u16 tbtt_tu_max = bcn_stat->tbtt_tu_max; + u16 upper, lower = bcn_stat->tbtt_tu_min; + u8 i, count = 0; + + for (i = 0; i < RTW89_BCN_TRACK_MAX_BIN_NUM; i++) { + upper = lower + RTW89_BCN_TRACK_BIN_WIDTH - 1; + if (i == RTW89_BCN_TRACK_MAX_BIN_NUM - 1) + upper = max(upper, tbtt_tu_max); + + count += bcn_dist->bins[i]; + if (count > target) + break; + + lower = upper + 1; + } + + return upper; +} + +static u16 rtw89_bcn_get_rx_time(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ +#define RTW89_SYMBOL_TIME_2GHZ 192 +#define RTW89_SYMBOL_TIME_5GHZ 20 +#define RTW89_SYMBOL_TIME_6GHZ 20 + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + struct rtw89_pkt_stat *pkt_stat = &bb->cur_pkt_stat; + u16 bitrate, val; + + if (!rtw89_legacy_rate_to_bitrate(rtwdev, pkt_stat->beacon_rate, &bitrate)) + return 0; + + val = (pkt_stat->beacon_len * 8 * RTW89_BCN_TRACK_SCALE_FACTOR) / bitrate; + + switch (chan->band_type) { + default: + case RTW89_BAND_2G: + val += RTW89_SYMBOL_TIME_2GHZ; + break; + case RTW89_BAND_5G: + val += RTW89_SYMBOL_TIME_5GHZ; + break; + case RTW89_BAND_6G: + val += RTW89_SYMBOL_TIME_6GHZ; + break; + } + + /* convert to millisecond */ + return DIV_ROUND_UP(val, 1000); +} + +static void rtw89_bcn_calc_timeout(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ +#define RTW89_BCN_TRACK_EXTEND_TIMEOUT 5 +#define RTW89_BCN_TRACK_COVERAGE_TH 0 /* unit: TU */ +#define RTW89_BCN_TRACK_STRONG_RSSI 80 + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + struct rtw89_pkt_stat *pkt_stat = &bb->cur_pkt_stat; + struct rtw89_beacon_dist *bcn_dist = &bcn_stat->bcn_dist; + u16 outlier_high_bcn_th = bcn_track->outlier_high_bcn_th; + u16 outlier_low_bcn_th = bcn_track->outlier_low_bcn_th; + u16 target_bcn_th = bcn_track->target_bcn_th; + u8 rssi = ewma_rssi_read(&bb->bcn_rssi); + u16 low_bcn_th = bcn_track->low_bcn_th; + u16 med_bcn_th = bcn_track->med_bcn_th; + u16 beacon_int = bcn_track->beacon_int; + u16 bcn_timeout; + + if (pkt_stat->beacon_nr < low_bcn_th) { + bcn_timeout = (RTW89_BCN_TRACK_TARGET_BCN * beacon_int) / PERCENT; + goto out; + } + + if (bcn_dist->outlier_count >= outlier_high_bcn_th) { + bcn_timeout = bcn_dist->max; + goto out; + } + + if (pkt_stat->beacon_nr < med_bcn_th) { + if (bcn_dist->outlier_count > outlier_low_bcn_th) + bcn_timeout = (bcn_dist->max + bcn_dist->upper_bound) / 2; + else + bcn_timeout = bcn_dist->upper_bound + + RTW89_BCN_TRACK_EXTEND_TIMEOUT; + + goto out; + } + + if (rssi >= RTW89_BCN_TRACK_STRONG_RSSI) { + if (rtw89_bcn_get_coverage(rtwdev, RTW89_BCN_TRACK_COVERAGE_TH) >= 90) { + /* ideal case */ + bcn_timeout = 0; + } else { + u16 offset_tu = bcn_track->tbtt_offset / 1024; + u16 upper_bound; + + upper_bound = + rtw89_bcn_get_histogram_bound(rtwdev, target_bcn_th); + bcn_timeout = + _rtw89_bcn_calc_drift(upper_bound, offset_tu, beacon_int); + } + + goto out; + } + + bcn_timeout = bcn_stat->drift[target_bcn_th]; + +out: + bcn_track->bcn_timeout = bcn_timeout + rtw89_bcn_get_rx_time(rtwdev, rtwvif_link); +} + +static void rtw89_bcn_update_timeout(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + rtw89_bcn_calc_drift(rtwdev); + rtw89_bcn_calc_distribution(rtwdev); + rtw89_bcn_calc_timeout(rtwdev, rtwvif_link); +} + +static void rtw89_core_bcn_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + if (!RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw)) + return; + + if (!rtwdev->lps_enabled) + return; + + if (!bcn_track->is_data_ready) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + if (!(rtwvif_link->wifi_role == RTW89_WIFI_ROLE_STATION || + rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)) + continue; + + rtw89_bcn_update_tbtt_offset(rtwdev, rtwvif_link); + rtw89_bcn_update_timeout(rtwdev, rtwvif_link); + } + } +} + +static bool rtw89_core_bcn_track_can_lps(struct rtw89_dev *rtwdev) +{ + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + + if (!RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw)) + return true; + + return bcn_track->is_data_ready; +} + +static void rtw89_core_bcn_track_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ +#define RTW89_BCN_TRACK_MED_BCN 70 +#define RTW89_BCN_TRACK_LOW_BCN 30 +#define RTW89_BCN_TRACK_OUTLIER_HIGH_BCN 30 +#define RTW89_BCN_TRACK_OUTLIER_LOW_BCN 20 + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + u32 period = jiffies_to_msecs(RTW89_TRACK_WORK_PERIOD); + struct ieee80211_bss_conf *bss_conf; + u32 beacons_in_period; + u32 bcn_intvl_us; + u16 beacon_int; + u8 dtim; + + rcu_read_lock(); + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + beacon_int = bss_conf->beacon_int ?: 100; + dtim = bss_conf->dtim_period; + rcu_read_unlock(); + + beacons_in_period = period / beacon_int / dtim; + bcn_intvl_us = ieee80211_tu_to_usec(beacon_int); + + bcn_track->low_bcn_th = + (beacons_in_period * RTW89_BCN_TRACK_LOW_BCN) / PERCENT; + bcn_track->med_bcn_th = + (beacons_in_period * RTW89_BCN_TRACK_MED_BCN) / PERCENT; + bcn_track->outlier_low_bcn_th = + (RTW89_BCN_TRACK_STAT_NR * RTW89_BCN_TRACK_OUTLIER_LOW_BCN) / PERCENT; + bcn_track->outlier_high_bcn_th = + (RTW89_BCN_TRACK_STAT_NR * RTW89_BCN_TRACK_OUTLIER_HIGH_BCN) / PERCENT; + bcn_track->target_bcn_th = + (RTW89_BCN_TRACK_STAT_NR * RTW89_BCN_TRACK_TARGET_BCN) / PERCENT; + + bcn_track->close_bcn_intvl_th = ieee80211_tu_to_usec(beacon_int - 3); + bcn_track->tbtt_diff_th = (bcn_intvl_us * 85) / PERCENT; + bcn_track->beacon_int = beacon_int; + bcn_track->dtim = dtim; +} + +static void rtw89_core_bcn_track_reset(struct rtw89_dev *rtwdev) +{ + memset(&rtwdev->phystat.bcn_stat, 0, sizeof(rtwdev->phystat.bcn_stat)); + memset(&rtwdev->bcn_track, 0, sizeof(rtwdev->bcn_track)); +} + +static bool rtw89_core_proto_stats_can_lps(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + enum rtw89_tfc_interval interval) +{ + if (rtwdev->chip->chip_id != RTL8852A) + return true; + + if (rtwvif->burst_active) + return false; + + if (interval == RTW89_TFC_INTERVAL_100MS && + hweight8(rtwvif->stats_ps.active_histogram) < 3) + return false; + + return true; +} + +static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ +#define RTW89_APPEND_TSF_2GHZ 384 +#define RTW89_APPEND_TSF_5GHZ 52 +#define RTW89_APPEND_TSF_6GHZ 52 + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + u32 bcn_intvl_us = ieee80211_tu_to_usec(bcn_track->beacon_int); + u64 tsf = le64_to_cpu(mgmt->u.beacon.timestamp); + u8 wp, num = bcn_stat->num; + u16 append; + + if (!RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw)) + return; + + /* Skip if not yet associated */ + if (!bcn_intvl_us) + return; + + switch (rx_status->band) { + default: + case NL80211_BAND_2GHZ: + append = RTW89_APPEND_TSF_2GHZ; + break; + case NL80211_BAND_5GHZ: + append = RTW89_APPEND_TSF_5GHZ; + break; + case NL80211_BAND_6GHZ: + append = RTW89_APPEND_TSF_6GHZ; + break; + } + + wp = bcn_stat->wp; + div_u64_rem(tsf - append, bcn_intvl_us, &bcn_stat->tbtt_us[wp]); + bcn_stat->tbtt_tu[wp] = bcn_stat->tbtt_us[wp] / 1024; + bcn_stat->wp = (wp + 1) % RTW89_BCN_TRACK_STAT_NR; + bcn_stat->num = umin(num + 1, RTW89_BCN_TRACK_STAT_NR); + bcn_track->is_data_ready = bcn_stat->num == RTW89_BCN_TRACK_STAT_NR; +} + +static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw89_vif_rx_stats_iter_data *iter_data = data; + struct rtw89_dev *rtwdev = iter_data->rtwdev; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; + struct sk_buff *skb = iter_data->skb; + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu; + bool is_mld = ieee80211_vif_is_mld(vif); + struct ieee80211_bss_conf *bss_conf; + struct rtw89_vif_link *rtwvif_link; + const u8 *bssid = iter_data->bssid; + struct rtw89_pkt_stat *pkt_stat; + struct rtw89_bb_ctx *bb; + const u8 *target_bssid; + + if (rtwdev->scanning && + (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control))) + rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb); + + rcu_read_lock(); + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, desc_info->bb_sel); + if (unlikely(!rtwvif_link)) + goto out; + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->bssid) + goto out; + + if (ieee80211_is_trigger(hdr->frame_control)) { + rtw89_stats_trigger_frame(rtwdev, rtwvif_link, bss_conf, skb); + goto out; + } + + target_bssid = ieee80211_is_beacon(hdr->frame_control) && + bss_conf->nontransmitted ? + bss_conf->transmitter_bssid : bss_conf->bssid; + if (!ether_addr_equal(target_bssid, bssid)) + goto out; + + if (is_mld) { + rx_status->link_valid = true; + rx_status->link_id = rtwvif_link->link_id; + } + + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + pkt_stat = &bb->cur_pkt_stat; + + if (ieee80211_is_beacon(hdr->frame_control)) { + if (vif->type == NL80211_IFTYPE_STATION && + !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { + rtw89_vif_sync_bcn_tsf(rtwvif_link, hdr, skb->len); + rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu); + } + + if (phy_ppdu) { + ewma_rssi_add(&bb->bcn_rssi, phy_ppdu->rssi_avg); + if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) + rtwvif_link->bcn_bw_idx = phy_ppdu->bw_idx; + } + + pkt_stat->beacon_nr++; + pkt_stat->beacon_rate = desc_info->data_rate; + pkt_stat->beacon_len = skb->len; + + rtw89_vif_rx_bcn_stat(rtwdev, skb); + } + + if (!ether_addr_equal(bss_conf->addr, hdr->addr1)) + goto out; + + if (desc_info->data_rate < RTW89_HW_RATE_NR) + pkt_stat->rx_rate_cnt[desc_info->data_rate]++; + + if (phy_ppdu && phy_ppdu->ofdm.has) { + if (phy_ppdu->ldpc) + pkt_stat->rx.ldpc++; + else + pkt_stat->rx.bcc++; + + if (phy_ppdu->stbc) + pkt_stat->rx.stbc++; + + if (!phy_ppdu->su) + pkt_stat->rx.mu++; + else if (phy_ppdu->bf) + pkt_stat->rx.su_bf++; + else + pkt_stat->rx.su_non_bf++; + } + + rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, false, false); + +out: + rcu_read_unlock(); +} + +static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct rtw89_vif_rx_stats_iter_data iter_data; + + rtw89_traffic_stats_accu(rtwdev, NULL, skb, true, false); + + iter_data.rtwdev = rtwdev; + iter_data.phy_ppdu = phy_ppdu; + iter_data.desc_info = desc_info; + iter_data.skb = skb; + iter_data.bssid = get_hdr_bssid((struct ieee80211_hdr *)skb->data); + rtw89_iterate_vifs_bh(rtwdev, rtw89_vif_rx_stats_iter, &iter_data); +} + +static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev, + struct ieee80211_rx_status *status) +{ + const struct rtw89_chan_rcd *rcd = + rtw89_chan_rcd_get(rtwdev, RTW89_CHANCTX_0); + u16 chan = rcd->prev_primary_channel; + u8 band = rtw89_hw_to_nl80211_band(rcd->prev_band_type); + + if (status->band != NL80211_BAND_2GHZ && + status->encoding == RX_ENC_LEGACY && + status->rate_idx < RTW89_HW_RATE_OFDM6) { + status->freq = ieee80211_channel_to_frequency(chan, band); + status->band = band; + } +} + +static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status) +{ + if (rx_status->band == NL80211_BAND_2GHZ || + rx_status->encoding != RX_ENC_LEGACY) + return; + + /* Some control frames' freq(ACKs in this case) are reported wrong due + * to FW notify timing, set to lowest rate to prevent overflow. + */ + if (rx_status->rate_idx < RTW89_HW_RATE_OFDM6) { + rx_status->rate_idx = 0; + return; + } + + /* No 4 CCK rates for non-2G */ + rx_status->rate_idx -= 4; +} + +static +void rtw89_core_update_rx_status_by_ppdu(struct rtw89_dev *rtwdev, + struct ieee80211_rx_status *rx_status, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)) + return; + + if (!phy_ppdu) + return; + + if (phy_ppdu->bf) + rx_status->enc_flags |= RX_ENC_FLAG_BF; + if (phy_ppdu->ldpc) + rx_status->enc_flags |= RX_ENC_FLAG_LDPC; + if (phy_ppdu->stbc) + rx_status->enc_flags |= u8_encode_bits(1, RX_ENC_FLAG_STBC_MASK); +} + +static void rtw89_core_update_radiotap_vht(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const union rtw89_phy_sts_ie09 *ie09; + struct ieee80211_radiotap_vht *vht; + u8 group_id; + u32 sig_a1; + u16 paid; + u8 nss; + + if (!phy_ppdu) + return; + + ie09 = phy_ppdu->ie09; + if (!ie09) + return; + + vht = skb_push(skb, sizeof(*vht)); + memset(vht, 0, sizeof(*vht)); + rx_status->flag |= RX_FLAG_RADIOTAP_VHT; + + if (phy->physt_gen >= 2) + sig_a1 = le64_get_bits(ie09->gen2.qw0, RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK_GEN2); + else + sig_a1 = le64_get_bits(ie09->gen0.qw0, RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK); + + group_id = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_VHT_SIG_A1_GRP_ID); + vht->group_id = group_id; + + if (group_id == 0 || group_id == 63) { + paid = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_VHT_SIG_A1_SU_PAID); + vht->partial_aid = cpu_to_le16(paid); + } else { + /* let mac80211 fill vht->mcs_nss[0] */ +#define WITH_MCS_IS_NOT_KNOWN(nss) ((nss) ? (15 << 4) | (nss) : 0) + nss = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS1); + vht->mcs_nss[1] = WITH_MCS_IS_NOT_KNOWN(nss); + nss = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS2); + vht->mcs_nss[2] = WITH_MCS_IS_NOT_KNOWN(nss); + nss = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS3); + vht->mcs_nss[3] = WITH_MCS_IS_NOT_KNOWN(nss); +#undef WITH_MCS_IS_NOT_KNOWN + } +} + +static void rtw89_core_update_radiotap_he_su(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct ieee80211_radiotap_he *he, + const union rtw89_phy_sts_ie09 *ie09) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + u32 sig_a1, sig_a2; + u16 t; + + if (!ie09) + return; + + if (phy->physt_gen >= 2) { + sig_a1 = le64_get_bits(ie09->gen2.qw0, + RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK_GEN2); + sig_a2 = le64_get_bits(ie09->gen2.qw0, + RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_L0); + sig_a2 |= le64_get_bits(ie09->gen2.qw1, + RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_H6) << 6; + } else { + sig_a1 = le64_get_bits(ie09->gen0.qw0, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK); + sig_a2 = le64_get_bits(ie09->gen0.qw0, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK); + } + + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | + 0); + + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | + 0); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BEAM_CHANGE); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_ULDL); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_UL_DL); + + rx_status->he_dcm = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_DCM); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BSS_COLOR); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_SU_SIG_A1_SR); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_TXOP); + he->data6 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA6_TXOP); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_LDPC_XSYMSEG); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_BEAMFORMED); + he->data5 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA5_TXBF); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PREFEC); + he->data5 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PE); + he->data5 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_SU_SIG_A2_DOPPLER); + he->data6 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); +} + +static void rtw89_core_update_radiotap_he_tb(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct ieee80211_radiotap_he *he, + const union rtw89_phy_sts_ie09 *sig) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + u32 sig_a1, sig_a2; + u16 t; + + if (!sig) + return; + + if (phy->physt_gen >= 2) { + sig_a1 = le64_get_bits(sig->gen2.qw0, + RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK_GEN2); + sig_a2 = le64_get_bits(sig->gen2.qw0, + RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_L0); + sig_a2 |= le64_get_bits(sig->gen2.qw1, + RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_H6); + } else { + sig_a1 = le64_get_bits(sig->gen0.qw0, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK); + sig_a2 = le64_get_bits(sig->gen0.qw0, RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK); + } + + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); + + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_BSS_COLOR); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB1); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB2); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB3); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB4); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_TB_SIG_A2_TXOP); + he->data6 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA6_TXOP); +} + +static u8 rtw89_core_he_mu_get_n_user_fields_by_ru_alloc(struct rtw89_dev *rtwdev, + u8 ru_alloc) +{ + u8 mu_users; + + if (ru_alloc <= 15) { + static const u8 entries_0_15[16] = { + 9, 8, 8, 7, 8, 7, 7, 6, 8, 7, 7, 6, 7, 6, 6, 5, + }; + + return entries_0_15[ru_alloc]; + } + + if (ru_alloc >= 16 && ru_alloc <= 95) { + mu_users = ru_alloc & 0x07; + + switch (ru_alloc & 0xF8) { + case 16: case 24: return mu_users + 3; + case 32: case 64: return mu_users + 6; + case 40: case 48: case 72: case 80: return mu_users + 5; + case 56: case 88: return mu_users + 4; + } + } + + if (ru_alloc >= 96 && ru_alloc <= 111) { + mu_users = ru_alloc & 0x03; + mu_users += ru_alloc >> 2 & 0x03; + + return mu_users + 2; + } + + if (ru_alloc == 112) + return 4; + + if (ru_alloc >= 113 && ru_alloc <= 115) + return 0; + + if (ru_alloc >= 128 && ru_alloc <= 191) { + mu_users = ru_alloc & 0x07; + mu_users += ru_alloc >> 3 & 0x07; + + return mu_users + 3; + } + + if (ru_alloc >= 192 && ru_alloc <= 215) + return (ru_alloc & 0x07) + 1; + + return 0; +} + +static int rtw89_core_he_mu_get_n_ru_alloc(struct rtw89_dev *rtwdev, u8 bw) +{ + switch (bw) { + case 0: + case 1: + return 1; + case 2: + case 4: + case 5: + return 2; + case 3: + case 6: + case 7: + return 3; + } + + return 0; +} + +static void rtw89_core_he_mu_get_cc_ptr(struct rtw89_dev *rtwdev, + const struct rtw89_phy_sts_ie10 *ie10, + u8 bw, int n_ru, int n_center_26tone, + const u8 **c1, const u8 **c2) +{ + const u8 *sigb, *end_sigb; + int total_bits, c2_offset; + int n_user_fields = 0; + const u8 *ptr; + int i; + + sigb = &ie10->sigb[0]; + end_sigb = (const void *)ie10 + + rtw89_core_get_phy_status_ie_len(rtwdev, (const void *)ie10); + + ptr = sigb; + if (ptr + n_ru + n_center_26tone >= end_sigb) + return; + *c1 = ptr; + + if (bw == 0) /* 20MHz doesn't have content channel 2 */ + return; + + for (i = 0; i < n_ru; i++) + n_user_fields += + rtw89_core_he_mu_get_n_user_fields_by_ru_alloc(rtwdev, (*c1)[i]); + + /* hardware report max 15 recordes, align 8 */ + n_user_fields = min(n_user_fields, 15); + + total_bits = n_ru * 8 + n_center_26tone + 10 + + n_user_fields * 21 + DIV_ROUND_UP(n_user_fields, 2) * 10; + c2_offset = ALIGN(DIV_ROUND_UP(total_bits, 8), 8); + + ptr = &sigb[c2_offset]; + if (ptr + n_ru + n_center_26tone >= end_sigb) + return; + + *c2 = ptr; +} + +static void rtw89_core_update_radiotap_he_mu(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct ieee80211_radiotap_he *he, + struct ieee80211_radiotap_he_mu *he_mu, + const union rtw89_phy_sts_ie09 *ie09, + const struct rtw89_phy_sts_ie10 *ie10) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const u8 *c1 = NULL, *c2 = NULL; + int n_center_26tone, n_ru, i; + bool doppler, comp; + u32 sig_a1, sig_a2; + u16 t; + u8 bw; + + if (!ie09) + return; + + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN); + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN); + + if (phy->physt_gen >= 2) { + sig_a1 = le64_get_bits(ie09->gen2.qw0, + RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK_GEN2); + sig_a2 = le64_get_bits(ie09->gen2.qw0, + RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_L0); + sig_a2 |= le64_get_bits(ie09->gen2.qw1, + RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_H6) << 6; + } else { + sig_a1 = le64_get_bits(ie09->gen0.qw0, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK); + sig_a2 = le64_get_bits(ie09->gen0.qw0, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK); + } + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_ULDL); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_UL_DL); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BSS_COLOR); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SR); + he->data4 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); + + doppler = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_DOPPLER); + he->data6 |= le16_encode_bits(doppler, IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_TXOP); + he->data6 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA6_TXOP); + + if (doppler) { + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MID); + he->data6 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA6_MIDAMBLE_PDCTY); + } + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_LPDC_XSYMSEG); + he->data3 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_FEC); + he->data5 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); + + t = u32_get_bits(sig_a2, RTW89_PHY_STS_IE09_HE_MU_SIG_A2_PE); + he->data5 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); + + he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN); + he_mu->flags2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_MCS); + he_mu->flags1 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_DCM); + he_mu->flags1 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); + + t = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_SYM_USR); + he_mu->flags2 |= le16_encode_bits(t, IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); + + comp = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_COM); + he_mu->flags2 |= le16_encode_bits(comp, IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); + + bw = u32_get_bits(sig_a1, RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BW); + he_mu->flags2 |= le16_encode_bits(bw, IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); + + if (comp == 0 && bw <= 5) { + u8 punc = clamp_t(int, bw - 3, 0, 2); + + he_mu->flags2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN); + he_mu->flags2 |= + le16_encode_bits(punc, IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); + } + + /* the Common field in the HE-SIG-B field is not present */ + if (comp || !ie10) + return; + + n_ru = rtw89_core_he_mu_get_n_ru_alloc(rtwdev, bw); + n_center_26tone = bw >= 1; + + rtw89_core_he_mu_get_cc_ptr(rtwdev, ie10, bw, n_ru, n_center_26tone, &c1, &c2); + if (!c1) + return; + + he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); + + for (i = 0; i < n_ru; i++) { + he_mu->ru_ch1[i] = c1[i]; + if (c2) + he_mu->ru_ch2[i] = c2[i]; + } + + if (n_center_26tone) { + u8 ru; + + ru = c1[n_ru] & BIT(0); + he_mu->flags1 |= + le16_encode_bits(ru, IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU); + + ru = c2 ? c2[n_ru] & BIT(0) : 0; + he_mu->flags1 |= + le16_encode_bits(ru, IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU); + } +} + +static u16 rtw89_core_get_radiotap_he_format(struct rtw89_rx_desc_info *desc_info) +{ + switch (desc_info->ppdu_type) { + case RTW89_RX_PPDU_T_HE_MU: + return IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU; + case RTW89_RX_PPDU_T_HE_ERSU: + return IEEE80211_RADIOTAP_HE_DATA1_FORMAT_EXT_SU; + case RTW89_RX_PPDU_T_HE_TB: + return IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG; + default: + return IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU; + } +} + +static void rtw89_core_update_radiotap_he(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + static const struct ieee80211_radiotap_he known_he = { + .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), + .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), + }; + struct ieee80211_radiotap_he_mu *he_mu = NULL; + const union rtw89_phy_sts_ie09 *ie09; + const struct rtw89_phy_sts_ie10 *ie10; + struct ieee80211_radiotap_he *he; + u16 he_format; + + he_format = rtw89_core_get_radiotap_he_format(desc_info); + + /* Radiotap of HE-MU must be placed after HE (skb_push ahead) */ + if (he_format == IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU) { + rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; + he_mu = skb_push(skb, sizeof(*he_mu)); + memset(he_mu, 0, sizeof(*he_mu)); + } + + rx_status->flag |= RX_FLAG_RADIOTAP_HE; + he = skb_push(skb, sizeof(*he)); + *he = known_he; + + he->data1 |= le16_encode_bits(he_format, IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MASK); + + if (!phy_ppdu) + return; + + ie09 = phy_ppdu->ie09; + ie10 = phy_ppdu->ie10; + + switch (he_format) { + case IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU: + rtw89_core_update_radiotap_he_mu(rtwdev, skb, rx_status, he, he_mu, + ie09, ie10); + break; + case IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG: + rtw89_core_update_radiotap_he_tb(rtwdev, skb, rx_status, he, ie09); + break; + default: + rtw89_core_update_radiotap_he_su(rtwdev, skb, rx_status, he, ie09); + break; + } +} + +static const u8 rx_status_bw_to_radiotap_eht_usig[] = { + [RATE_INFO_BW_20] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_20MHZ, + [RATE_INFO_BW_5] = U8_MAX, + [RATE_INFO_BW_10] = U8_MAX, + [RATE_INFO_BW_40] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_40MHZ, + [RATE_INFO_BW_80] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_80MHZ, + [RATE_INFO_BW_160] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_160MHZ, + [RATE_INFO_BW_HE_RU] = U8_MAX, + [RATE_INFO_BW_320] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_320MHZ_1, + [RATE_INFO_BW_EHT_RU] = U8_MAX, +}; + +static void rtw89_core_update_radiotap_eht(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_radiotap_eht_usig *usig; + struct ieee80211_radiotap_eht *eht; + struct ieee80211_radiotap_tlv *tlv; + int eht_len = struct_size(eht, user_info, 1); + int usig_len = sizeof(*usig); + int len; + u8 bw; + + len = sizeof(*tlv) + ALIGN(eht_len, 4) + + sizeof(*tlv) + ALIGN(usig_len, 4); + + rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; + skb_reset_mac_header(skb); + + /* EHT */ + tlv = skb_push(skb, len); + memset(tlv, 0, len); + tlv->type = cpu_to_le16(IEEE80211_RADIOTAP_EHT); + tlv->len = cpu_to_le16(eht_len); + + eht = (struct ieee80211_radiotap_eht *)tlv->data; + eht->known = cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_GI); + eht->data[0] = + le32_encode_bits(rx_status->eht.gi, IEEE80211_RADIOTAP_EHT_DATA0_GI); + + eht->user_info[0] = + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN); + eht->user_info[0] |= + le32_encode_bits(rx_status->rate_idx, IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + le32_encode_bits(rx_status->nss, IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O); + if (rx_status->enc_flags & RX_ENC_FLAG_LDPC) + eht->user_info[0] |= + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_CODING); + + /* U-SIG */ + tlv = (void *)tlv + sizeof(*tlv) + ALIGN(eht_len, 4); + tlv->type = cpu_to_le16(IEEE80211_RADIOTAP_EHT_USIG); + tlv->len = cpu_to_le16(usig_len); + + if (rx_status->bw >= ARRAY_SIZE(rx_status_bw_to_radiotap_eht_usig)) + return; + + bw = rx_status_bw_to_radiotap_eht_usig[rx_status->bw]; + if (bw == U8_MAX) + return; + + usig = (struct ieee80211_radiotap_eht_usig *)tlv->data; + usig->common = + le32_encode_bits(1, IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN) | + le32_encode_bits(bw, IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW); +} + +static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)) + return; + + /* + * At transient adding a monitor vif from a station vif, the headroom + * might not include radiotap. + */ + if (unlikely(skb_headroom(skb) < RTW89_RADIOTAP_ROOM + NET_SKB_PAD)) + return; + + if (rx_status->encoding == RX_ENC_VHT) + rtw89_core_update_radiotap_vht(rtwdev, skb, rx_status, phy_ppdu); + else if (rx_status->encoding == RX_ENC_HE) + rtw89_core_update_radiotap_he(rtwdev, desc_info, skb, rx_status, phy_ppdu); + else if (rx_status->encoding == RX_ENC_EHT) + rtw89_core_update_radiotap_eht(rtwdev, skb, rx_status); +} + +static void rtw89_core_validate_rx_signal(struct ieee80211_rx_status *rx_status) +{ + if (!rx_status->signal) + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; +} + +static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + size_t hdr_len, ielen; + u8 *variable; + int chan; + + if (!rtwdev->chip->rx_freq_from_ie) + return; + + if (!rtwdev->scanning) + return; + + if (ieee80211_is_beacon(mgmt->frame_control)) { + variable = mgmt->u.beacon.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { + variable = mgmt->u.probe_resp.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + } else { + return; + } + + if (skb->len > hdr_len) + ielen = skb->len - hdr_len; + else + return; + + /* The parsing code for both 2GHz and 5GHz bands is the same in this + * function. + */ + chan = cfg80211_get_ies_channel_number(variable, ielen, NL80211_BAND_2GHZ); + if (chan == -1) + return; + + rx_status->band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G; + rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band); +} + +static void rtw89_core_correct_mcc_chan(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + const struct rtw89_chan *chan; + u8 mac_id = desc_info->mac_id; + enum rtw89_entity_mode mode; + enum nl80211_band band; + + mode = rtw89_get_entity_mode(rtwdev); + if (likely(mode != RTW89_ENTITY_MODE_MCC)) + return; + + if (chip_gen == RTW89_CHIP_BE && phy_ppdu) + mac_id = phy_ppdu->mac_id; + + rcu_read_lock(); + + rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, mac_id); + if (!rtwsta_link) + goto out; + + rtwvif_link = rtwsta_link->rtwvif_link; + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + band = rtw89_hw_to_nl80211_band(chan->band_type); + rx_status->freq = ieee80211_channel_to_frequency(chan->primary_channel, band); + +out: + rcu_read_unlock(); +} + +static void __rtw89_core_tid_rx_stats_reset(struct rtw89_tid_stats *tid_stats) +{ + tid_stats->last_pn = -1LL; + tid_stats->last_sn = IEEE80211_SN_MASK; +} + +void rtw89_core_tid_rx_stats_ctrl(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, + struct ieee80211_ampdu_params *params, bool enable) +{ + struct rtw89_tid_stats *tid_stats; + u16 tid = params->tid; + + tid_stats = &rtwsta->tid_rx_stats[tid]; + + if (enable) { + __rtw89_core_tid_rx_stats_reset(tid_stats); + tid_stats->started = true; + } else { + tid_stats->started = false; + } +} + +void rtw89_core_tid_rx_stats_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_tid_stats *tid_stats; + struct ieee80211_sta *sta; + struct rtw89_sta *rtwsta; + u16 tid; + + for_each_station(sta, rtwdev->hw) { + rtwsta = sta_to_rtwsta(sta); + + for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { + tid_stats = &rtwsta->tid_rx_stats[tid]; + + if (!tid_stats->started) + continue; + + __rtw89_core_tid_rx_stats_reset(tid_stats); + } + } +} + +static bool rtw89_core_skb_pn_valid(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_sta_link *rtwsta_link; + struct rtw89_tid_stats *tid_stats; + struct rtw89_sta *rtwsta; + u8 tid, *ccmp_hdr_ptr; + s64 pn, last_pn; + u16 mpdu_sn; + int hdrlen; + + if (chip->chip_gen != RTW89_CHIP_AX) + return true; + + if (!ieee80211_is_data_qos(hdr->frame_control)) + return true; + + if (!desc_info->hw_dec || !desc_info->addr1_match) + return true; + + guard(rcu)(); + + rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, desc_info->mac_id); + if (!rtwsta_link) + return true; + + rtwsta = rtwsta_link->rtwsta; + tid = ieee80211_get_tid(hdr); + tid_stats = &rtwsta->tid_rx_stats[tid]; + + if (!tid_stats->started) + return true; + + switch (desc_info->sec_type) { + case RTW89_SEC_KEY_TYPE_CCMP128: + case RTW89_SEC_KEY_TYPE_CCMP256: + case RTW89_SEC_KEY_TYPE_GCMP128: + case RTW89_SEC_KEY_TYPE_GCMP256: + mpdu_sn = ieee80211_get_sn(hdr); + hdrlen = ieee80211_hdrlen(hdr->frame_control); + ccmp_hdr_ptr = skb->data + hdrlen; + ccmp_hdr2pn(&pn, ccmp_hdr_ptr); + last_pn = tid_stats->last_pn; + + if (pn > last_pn) { + if (last_pn != -1LL && + ieee80211_sn_less(mpdu_sn, tid_stats->last_sn)) { + dev_kfree_skb_any(skb); + + return false; + } + + tid_stats->last_sn = mpdu_sn; + tid_stats->last_pn = pn; + } + break; + default: + break; + } + + return true; +} + +static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb_ppdu, + struct ieee80211_rx_status *rx_status) +{ + struct napi_struct *napi = &rtwdev->napi; + + /* In low power mode, napi isn't scheduled. Receive it to netif. */ + if (unlikely(!napi_is_scheduled(napi))) + napi = NULL; + + rtw89_core_hw_to_sband_rate(rx_status); + rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); + rtw89_core_update_rx_status_by_ppdu(rtwdev, rx_status, phy_ppdu); + rtw89_core_update_radiotap(rtwdev, desc_info, skb_ppdu, rx_status, phy_ppdu); + rtw89_core_validate_rx_signal(rx_status); + rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status); + rtw89_core_correct_mcc_chan(rtwdev, desc_info, rx_status, phy_ppdu); + + /* In low power mode, it does RX in thread context. */ + local_bh_disable(); + ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, napi); + local_bh_enable(); + rtwdev->napi_budget_countdown--; +} + +static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; + int curr = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band]; + struct sk_buff *skb_ppdu = NULL, *tmp; + struct ieee80211_rx_status *rx_status; + + if (curr > RTW89_MAX_PPDU_CNT) + return; + + skb_queue_walk_safe(&rtwdev->ppdu_sts.rx_queue[band], skb_ppdu, tmp) { + skb_unlink(skb_ppdu, &rtwdev->ppdu_sts.rx_queue[band]); + rx_status = IEEE80211_SKB_RXCB(skb_ppdu); + if (rtw89_core_rx_ppdu_match(rtwdev, desc_info, rx_status)) + rtw89_chip_query_ppdu(rtwdev, phy_ppdu, rx_status); + rtw89_correct_cck_chan(rtwdev, rx_status); + rtw89_core_rx_to_mac80211(rtwdev, phy_ppdu, desc_info, skb_ppdu, rx_status); + } +} + +static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct rtw89_rx_phy_ppdu phy_ppdu = {.buf = skb->data, .valid = false, + .len = skb->len, + .to_self = desc_info->addr1_match, + .rate = desc_info->data_rate, + .mac_id = desc_info->mac_id, + .phy_idx = desc_info->bb_sel}; + int ret; + + if (desc_info->mac_info_valid) { + ret = rtw89_core_rx_process_mac_ppdu(rtwdev, skb, &phy_ppdu); + if (ret) + goto out; + } + + ret = rtw89_core_rx_process_phy_ppdu(rtwdev, &phy_ppdu); + if (ret) + goto out; + + rtw89_core_rx_process_phy_sts(rtwdev, &phy_ppdu); + +out: + rtw89_core_rx_pending_skb(rtwdev, &phy_ppdu, desc_info, skb); + dev_kfree_skb_any(skb); +} + +static void rtw89_core_rx_process_report(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + switch (desc_info->pkt_type) { + case RTW89_CORE_RX_TYPE_C2H: + rtw89_fw_c2h_irqsafe(rtwdev, skb); + break; + case RTW89_CORE_RX_TYPE_PPDU_STAT: + rtw89_core_rx_process_ppdu_sts(rtwdev, desc_info, skb); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_TXRX, "unhandled pkt_type=%d\n", + desc_info->pkt_type); + dev_kfree_skb_any(skb); + break; + } +} + +void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_rxdesc_short *rxd_s; + struct rtw89_rxdesc_long *rxd_l; + u8 shift_len, drv_info_len; + + rxd_s = (struct rtw89_rxdesc_short *)(data + data_offset); + desc_info->pkt_size = le32_get_bits(rxd_s->dword0, AX_RXD_RPKT_LEN_MASK); + desc_info->drv_info_size = le32_get_bits(rxd_s->dword0, AX_RXD_DRV_INFO_SIZE_MASK); + desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, AX_RXD_LONG_RXD); + desc_info->pkt_type = le32_get_bits(rxd_s->dword0, AX_RXD_RPKT_TYPE_MASK); + desc_info->mac_info_valid = le32_get_bits(rxd_s->dword0, AX_RXD_MAC_INFO_VLD); + if (chip->chip_id == RTL8852C) + desc_info->bw = le32_get_bits(rxd_s->dword1, AX_RXD_BW_v1_MASK); + else + desc_info->bw = le32_get_bits(rxd_s->dword1, AX_RXD_BW_MASK); + desc_info->data_rate = le32_get_bits(rxd_s->dword1, AX_RXD_RX_DATARATE_MASK); + desc_info->gi_ltf = le32_get_bits(rxd_s->dword1, AX_RXD_RX_GI_LTF_MASK); + desc_info->user_id = le32_get_bits(rxd_s->dword1, AX_RXD_USER_ID_MASK); + desc_info->sr_en = le32_get_bits(rxd_s->dword1, AX_RXD_SR_EN); + desc_info->ppdu_cnt = le32_get_bits(rxd_s->dword1, AX_RXD_PPDU_CNT_MASK); + desc_info->ppdu_type = le32_get_bits(rxd_s->dword1, AX_RXD_PPDU_TYPE_MASK); + desc_info->free_run_cnt = le32_get_bits(rxd_s->dword2, AX_RXD_FREERUN_CNT_MASK); + desc_info->icv_err = le32_get_bits(rxd_s->dword3, AX_RXD_ICV_ERR); + desc_info->crc32_err = le32_get_bits(rxd_s->dword3, AX_RXD_CRC32_ERR); + desc_info->hw_dec = le32_get_bits(rxd_s->dword3, AX_RXD_HW_DEC); + desc_info->sw_dec = le32_get_bits(rxd_s->dword3, AX_RXD_SW_DEC); + desc_info->addr1_match = le32_get_bits(rxd_s->dword3, AX_RXD_A1_MATCH); + desc_info->ampdu = le32_get_bits(rxd_s->dword3, AX_RXD_AMPDU); + + shift_len = desc_info->shift << 1; /* 2-byte unit */ + drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ + desc_info->offset = data_offset + shift_len + drv_info_len; + if (desc_info->long_rxdesc) + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long); + else + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short); + desc_info->ready = true; + + if (!desc_info->long_rxdesc) + return; + + rxd_l = (struct rtw89_rxdesc_long *)(data + data_offset); + desc_info->frame_type = le32_get_bits(rxd_l->dword4, AX_RXD_TYPE_MASK); + desc_info->addr_cam_valid = le32_get_bits(rxd_l->dword5, AX_RXD_ADDR_CAM_VLD); + desc_info->addr_cam_id = le32_get_bits(rxd_l->dword5, AX_RXD_ADDR_CAM_MASK); + desc_info->sec_cam_id = le32_get_bits(rxd_l->dword5, AX_RXD_SEC_CAM_IDX_MASK); + desc_info->mac_id = le32_get_bits(rxd_l->dword5, AX_RXD_MAC_ID_MASK); + desc_info->rx_pl_id = le32_get_bits(rxd_l->dword5, AX_RXD_RX_PL_ID_MASK); + desc_info->sec_type = le32_get_bits(rxd_l->dword7, AX_RXD_SEC_TYPE_MASK); +} +EXPORT_SYMBOL(rtw89_core_query_rxdesc); + +void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset) +{ + struct rtw89_rxdesc_phy_rpt_v2 *rxd_rpt; + struct rtw89_rxdesc_short_v2 *rxd_s; + struct rtw89_rxdesc_long_v2 *rxd_l; + u16 shift_len, drv_info_len, phy_rtp_len, hdr_cnv_len; + + rxd_s = (struct rtw89_rxdesc_short_v2 *)(data + data_offset); + + desc_info->pkt_size = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_LEN_MASK); + desc_info->drv_info_size = le32_get_bits(rxd_s->dword0, BE_RXD_DRV_INFO_SZ_MASK); + desc_info->phy_rpt_size = le32_get_bits(rxd_s->dword0, BE_RXD_PHY_RPT_SZ_MASK); + desc_info->hdr_cnv_size = le32_get_bits(rxd_s->dword0, BE_RXD_HDR_CNV_SZ_MASK); + desc_info->shift = le32_get_bits(rxd_s->dword0, BE_RXD_SHIFT_MASK); + desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, BE_RXD_LONG_RXD); + desc_info->pkt_type = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_TYPE_MASK); + desc_info->bb_sel = le32_get_bits(rxd_s->dword0, BE_RXD_BB_SEL); + if (desc_info->pkt_type == RTW89_CORE_RX_TYPE_PPDU_STAT) + desc_info->mac_info_valid = true; + + desc_info->frame_type = le32_get_bits(rxd_s->dword2, BE_RXD_TYPE_MASK); + desc_info->mac_id = le32_get_bits(rxd_s->dword2, BE_RXD_MAC_ID_MASK); + desc_info->addr_cam_valid = le32_get_bits(rxd_s->dword2, BE_RXD_ADDR_CAM_VLD); + + desc_info->sec_type = le32_get_bits(rxd_s->dword3, BE_RXD_SEC_TYPE_MASK); + desc_info->icv_err = le32_get_bits(rxd_s->dword3, BE_RXD_ICV_ERR); + desc_info->crc32_err = le32_get_bits(rxd_s->dword3, BE_RXD_CRC32_ERR); + desc_info->hw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_HW_DEC); + desc_info->sw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_SW_DEC); + desc_info->addr1_match = le32_get_bits(rxd_s->dword3, BE_RXD_A1_MATCH); + desc_info->ampdu = le32_get_bits(rxd_s->dword3, BE_RXD_AMPDU); + + desc_info->bw = le32_get_bits(rxd_s->dword4, BE_RXD_BW_MASK); + desc_info->data_rate = le32_get_bits(rxd_s->dword4, BE_RXD_RX_DATARATE_MASK); + desc_info->gi_ltf = le32_get_bits(rxd_s->dword4, BE_RXD_RX_GI_LTF_MASK); + desc_info->ppdu_cnt = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_CNT_MASK); + desc_info->ppdu_type = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_TYPE_MASK); + + desc_info->free_run_cnt = le32_to_cpu(rxd_s->dword5); + + shift_len = desc_info->shift << 1; /* 2-byte unit */ + drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ + phy_rtp_len = desc_info->phy_rpt_size << 3; /* 8-byte unit */ + hdr_cnv_len = desc_info->hdr_cnv_size << 4; /* 16-byte unit */ + desc_info->offset = data_offset + shift_len + drv_info_len + + phy_rtp_len + hdr_cnv_len; + + if (desc_info->long_rxdesc) + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long_v2); + else + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short_v2); + desc_info->ready = true; + + if (phy_rtp_len == sizeof(*rxd_rpt)) { + rxd_rpt = (struct rtw89_rxdesc_phy_rpt_v2 *)(data + data_offset + + desc_info->rxd_len); + desc_info->rssi = le32_get_bits(rxd_rpt->dword0, BE_RXD_PHY_RSSI); + } + + if (!desc_info->long_rxdesc) + return; + + rxd_l = (struct rtw89_rxdesc_long_v2 *)(data + data_offset); + + desc_info->sr_en = le32_get_bits(rxd_l->dword6, BE_RXD_SR_EN); + desc_info->user_id = le32_get_bits(rxd_l->dword6, BE_RXD_USER_ID_MASK); + desc_info->addr_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_ADDR_CAM_MASK); + desc_info->sec_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_SEC_CAM_IDX_MASK); + + desc_info->rx_pl_id = le32_get_bits(rxd_l->dword7, BE_RXD_RX_PL_ID_MASK); +} +EXPORT_SYMBOL(rtw89_core_query_rxdesc_v2); + +void rtw89_core_query_rxdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset) +{ + struct rtw89_rxdesc_phy_rpt_v2 *rxd_rpt; + struct rtw89_rxdesc_short_v3 *rxd_s; + struct rtw89_rxdesc_long_v3 *rxd_l; + u16 shift_len, drv_info_len, phy_rtp_len, hdr_cnv_len; + + rxd_s = (struct rtw89_rxdesc_short_v3 *)(data + data_offset); + + desc_info->pkt_size = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_LEN_MASK); + desc_info->drv_info_size = le32_get_bits(rxd_s->dword0, BE_RXD_DRV_INFO_SZ_MASK); + desc_info->phy_rpt_size = le32_get_bits(rxd_s->dword0, BE_RXD_PHY_RPT_SZ_MASK); + desc_info->hdr_cnv_size = le32_get_bits(rxd_s->dword0, BE_RXD_HDR_CNV_SZ_MASK); + desc_info->shift = le32_get_bits(rxd_s->dword0, BE_RXD_SHIFT_MASK); + desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, BE_RXD_LONG_RXD); + desc_info->pkt_type = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_TYPE_MASK); + desc_info->bb_sel = le32_get_bits(rxd_s->dword0, BE_RXD_BB_SEL); + if (desc_info->pkt_type == RTW89_CORE_RX_TYPE_PPDU_STAT) + desc_info->mac_info_valid = true; + + desc_info->frame_type = le32_get_bits(rxd_s->dword2, BE_RXD_TYPE_MASK); + desc_info->mac_id = le32_get_bits(rxd_s->dword2, BE_RXD_MAC_ID_V1); + desc_info->addr_cam_valid = le32_get_bits(rxd_s->dword2, BE_RXD_ADDR_CAM_VLD); + + desc_info->sec_type = le32_get_bits(rxd_s->dword3, BE_RXD_SEC_TYPE_MASK); + desc_info->icv_err = le32_get_bits(rxd_s->dword3, BE_RXD_ICV_ERR); + desc_info->crc32_err = le32_get_bits(rxd_s->dword3, BE_RXD_CRC32_ERR); + desc_info->hw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_HW_DEC); + desc_info->sw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_SW_DEC); + desc_info->addr1_match = le32_get_bits(rxd_s->dword3, BE_RXD_A1_MATCH); + desc_info->ampdu = le32_get_bits(rxd_s->dword3, BE_RXD_AMPDU); + + desc_info->bw = le32_get_bits(rxd_s->dword4, BE_RXD_BW_MASK); + desc_info->data_rate = le32_get_bits(rxd_s->dword4, BE_RXD_RX_DATARATE_MASK); + desc_info->gi_ltf = le32_get_bits(rxd_s->dword4, BE_RXD_RX_GI_LTF_MASK); + desc_info->ppdu_cnt = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_CNT_MASK); + desc_info->ppdu_type = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_TYPE_MASK); + + desc_info->free_run_cnt = le32_to_cpu(rxd_s->dword5); + + shift_len = desc_info->shift << 1; /* 2-byte unit */ + drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ + phy_rtp_len = desc_info->phy_rpt_size << 3; /* 8-byte unit */ + hdr_cnv_len = desc_info->hdr_cnv_size << 4; /* 16-byte unit */ + desc_info->offset = data_offset + shift_len + drv_info_len + + phy_rtp_len + hdr_cnv_len; + + if (desc_info->long_rxdesc) + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long_v3); + else + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short_v3); + desc_info->ready = true; + + if (phy_rtp_len == sizeof(*rxd_rpt)) { + rxd_rpt = (struct rtw89_rxdesc_phy_rpt_v2 *)(data + data_offset + + desc_info->rxd_len); + desc_info->rssi = le32_get_bits(rxd_rpt->dword0, BE_RXD_PHY_RSSI); + } + + if (!desc_info->long_rxdesc) + return; + + rxd_l = (struct rtw89_rxdesc_long_v3 *)(data + data_offset); + + desc_info->sr_en = le32_get_bits(rxd_l->dword6, BE_RXD_SR_EN); + desc_info->user_id = le32_get_bits(rxd_l->dword6, BE_RXD_USER_ID_MASK); + desc_info->addr_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_ADDR_CAM_V1); + desc_info->sec_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_SEC_CAM_IDX_V1); + + desc_info->rx_pl_id = le32_get_bits(rxd_l->dword7, BE_RXD_RX_PL_ID_MASK); +} +EXPORT_SYMBOL(rtw89_core_query_rxdesc_v3); + +struct rtw89_core_iter_rx_status { + struct rtw89_dev *rtwdev; + struct ieee80211_rx_status *rx_status; + struct rtw89_rx_desc_info *desc_info; + u8 mac_id; +}; + +static +void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_core_iter_rx_status *iter_data = + (struct rtw89_core_iter_rx_status *)data; + struct ieee80211_rx_status *rx_status = iter_data->rx_status; + struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + u8 mac_id = iter_data->mac_id; + + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, desc_info->bb_sel); + if (unlikely(!rtwsta_link)) + return; + + if (mac_id != rtwsta_link->mac_id) + return; + + rtwsta_link->rx_status = *rx_status; + rtwsta_link->rx_hw_rate = desc_info->data_rate; +} + +static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status) +{ + struct rtw89_core_iter_rx_status iter_data; + + if (!desc_info->addr1_match || !desc_info->long_rxdesc) + return; + + if (desc_info->frame_type != RTW89_RX_TYPE_DATA) + return; + + iter_data.rtwdev = rtwdev; + iter_data.rx_status = rx_status; + iter_data.desc_info = desc_info; + iter_data.mac_id = desc_info->mac_id; + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_core_stats_sta_rx_status_iter, + &iter_data); +} + +static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const struct cfg80211_chan_def *chandef = + rtw89_chandef_get(rtwdev, RTW89_CHANCTX_0); + u16 data_rate; + u8 data_rate_mode; + bool eht = false; + u8 gi; + + /* currently using single PHY */ + rx_status->freq = chandef->chan->center_freq; + rx_status->band = chandef->chan->band; + + if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) + rx_status->boottime_ns = ktime_get_boottime_ns(); + + if (rtwdev->scanning && + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { + const struct rtw89_chan *cur = rtw89_scan_chan_get(rtwdev); + u8 chan = cur->primary_channel; + u8 band = cur->band_type; + enum nl80211_band nl_band; + + nl_band = rtw89_hw_to_nl80211_band(band); + rx_status->freq = ieee80211_channel_to_frequency(chan, nl_band); + rx_status->band = nl_band; + } + + if (desc_info->icv_err || desc_info->crc32_err) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (desc_info->hw_dec && + !(desc_info->sw_dec || desc_info->icv_err)) + rx_status->flag |= RX_FLAG_DECRYPTED; + + if (desc_info->ampdu) { + rx_status->flag |= RX_FLAG_AMPDU_DETAILS; + rx_status->ampdu_reference = desc_info->ppdu_cnt; + } + + rx_status->bw = rtw89_hw_to_rate_info_bw(desc_info->bw); + + data_rate = desc_info->data_rate; + data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate); + if (data_rate_mode == DATA_RATE_MODE_NON_HT) { + rx_status->encoding = RX_ENC_LEGACY; + rx_status->rate_idx = rtw89_get_data_not_ht_idx(rtwdev, data_rate); + /* convert rate_idx after we get the correct band */ + } else if (data_rate_mode == DATA_RATE_MODE_HT) { + rx_status->encoding = RX_ENC_HT; + rx_status->rate_idx = rtw89_get_data_ht_mcs(rtwdev, data_rate); + if (desc_info->gi_ltf) + rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + } else if (data_rate_mode == DATA_RATE_MODE_VHT) { + rx_status->encoding = RX_ENC_VHT; + rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, data_rate); + rx_status->nss = rtw89_get_data_nss(rtwdev, data_rate) + 1; + if (desc_info->gi_ltf) + rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + } else if (data_rate_mode == DATA_RATE_MODE_HE) { + rx_status->encoding = RX_ENC_HE; + rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, data_rate); + rx_status->nss = rtw89_get_data_nss(rtwdev, data_rate) + 1; + } else if (data_rate_mode == DATA_RATE_MODE_EHT) { + rx_status->encoding = RX_ENC_EHT; + rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, data_rate); + rx_status->nss = rtw89_get_data_nss(rtwdev, data_rate) + 1; + eht = true; + } else { + rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); + } + + /* he_gi is used to match ppdu, so we always fill it. */ + gi = rtw89_rxdesc_to_nl_he_eht_gi(rtwdev, desc_info->gi_ltf, true, eht); + if (eht) + rx_status->eht.gi = gi; + else + rx_status->he_gi = gi; + rx_status->flag |= RX_FLAG_MACTIME_START; + rx_status->mactime = desc_info->free_run_cnt; + + rtw89_chip_phy_rpt_to_rssi(rtwdev, desc_info, rx_status); + rtw89_core_stats_sta_rx_status(rtwdev, desc_info, rx_status); +} + +static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return RTW89_PS_MODE_NONE; + + if (rtw89_disable_ps_mode || !chip->ps_mode_supported || + RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw)) + return RTW89_PS_MODE_NONE; + + if ((chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) && + !RTW89_CHK_FW_FEATURE(NO_LPS_PG, &rtwdev->fw)) + return RTW89_PS_MODE_PWR_GATED; + + if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) + return RTW89_PS_MODE_CLK_GATED; + + if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_RFOFF)) + return RTW89_PS_MODE_RFOFF; + + return RTW89_PS_MODE_NONE; +} + +static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info) +{ + struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; + u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; + struct ieee80211_rx_status *rx_status; + struct sk_buff *skb_ppdu, *tmp; + + skb_queue_walk_safe(&ppdu_sts->rx_queue[band], skb_ppdu, tmp) { + skb_unlink(skb_ppdu, &ppdu_sts->rx_queue[band]); + rx_status = IEEE80211_SKB_RXCB(skb_ppdu); + rtw89_core_rx_to_mac80211(rtwdev, NULL, desc_info, skb_ppdu, rx_status); + } +} + +static +void rtw89_core_rx_pkt_hdl(struct rtw89_dev *rtwdev, const struct sk_buff *skb, + const struct rtw89_rx_desc_info *desc) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct rtw89_sta_link *rtwsta_link; + struct ieee80211_sta *sta; + struct rtw89_sta *rtwsta; + u8 macid = desc->mac_id; + + if (!refcount_read(&rtwdev->refcount_ap_info)) + return; + + rcu_read_lock(); + + rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, macid); + if (!rtwsta_link) + goto out; + + rtwsta = rtwsta_link->rtwsta; + if (!test_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags)) + goto out; + + sta = rtwsta_to_sta(rtwsta); + if (ieee80211_is_pspoll(hdr->frame_control)) + ieee80211_sta_pspoll(sta); + else if (ieee80211_has_pm(hdr->frame_control) && + (ieee80211_is_data_qos(hdr->frame_control) || + ieee80211_is_qos_nullfunc(hdr->frame_control))) + ieee80211_sta_uapsd_trigger(sta, ieee80211_get_tid(hdr)); + +out: + rcu_read_unlock(); +} + +void rtw89_core_rx(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status; + struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; + u8 ppdu_cnt = desc_info->ppdu_cnt; + u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; + + if (desc_info->pkt_type != RTW89_CORE_RX_TYPE_WIFI) { + rtw89_core_rx_process_report(rtwdev, desc_info, skb); + return; + } + + if (ppdu_sts->curr_rx_ppdu_cnt[band] != ppdu_cnt) { + rtw89_core_flush_ppdu_rx_queue(rtwdev, desc_info); + ppdu_sts->curr_rx_ppdu_cnt[band] = ppdu_cnt; + } + + rx_status = IEEE80211_SKB_RXCB(skb); + memset(rx_status, 0, sizeof(*rx_status)); + rtw89_core_update_rx_status(rtwdev, skb, desc_info, rx_status); + rtw89_core_rx_pkt_hdl(rtwdev, skb, desc_info); + + if (!rtw89_core_skb_pn_valid(rtwdev, desc_info, skb)) + return; + + if (desc_info->long_rxdesc && + BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) + skb_queue_tail(&ppdu_sts->rx_queue[band], skb); + else + rtw89_core_rx_to_mac80211(rtwdev, NULL, desc_info, skb, rx_status); +} +EXPORT_SYMBOL(rtw89_core_rx); + +void rtw89_core_napi_start(struct rtw89_dev *rtwdev) +{ + if (test_and_set_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) + return; + + napi_enable(&rtwdev->napi); +} +EXPORT_SYMBOL(rtw89_core_napi_start); + +void rtw89_core_napi_stop(struct rtw89_dev *rtwdev) +{ + if (!test_and_clear_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) + return; + + napi_synchronize(&rtwdev->napi); + napi_disable(&rtwdev->napi); +} +EXPORT_SYMBOL(rtw89_core_napi_stop); + +int rtw89_core_napi_init(struct rtw89_dev *rtwdev) +{ + rtwdev->netdev = alloc_netdev_dummy(0); + if (!rtwdev->netdev) + return -ENOMEM; + + netif_napi_add(rtwdev->netdev, &rtwdev->napi, + rtwdev->hci.ops->napi_poll); + return 0; +} +EXPORT_SYMBOL(rtw89_core_napi_init); + +void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev) +{ + rtw89_core_napi_stop(rtwdev); + netif_napi_del(&rtwdev->napi); + free_netdev(rtwdev->netdev); +} +EXPORT_SYMBOL(rtw89_core_napi_deinit); + +static void rtw89_core_ba_work(struct work_struct *work) +{ + struct rtw89_dev *rtwdev = + container_of(work, struct rtw89_dev, ba_work); + struct rtw89_txq *rtwtxq, *tmp; + int ret; + + spin_lock_bh(&rtwdev->ba_lock); + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + struct ieee80211_sta *sta = txq->sta; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + u8 tid = txq->tid; + + if (!sta) { + rtw89_warn(rtwdev, "cannot start BA without sta\n"); + goto skip_ba_work; + } + + if (rtwsta->disassoc) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "cannot start BA with disassoc sta\n"); + goto skip_ba_work; + } + + ret = ieee80211_start_tx_ba_session(sta, tid, 0); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "failed to setup BA session for %pM:%2d: %d\n", + sta->addr, tid, ret); + if (ret == -EINVAL) + set_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags); + } +skip_ba_work: + list_del_init(&rtwtxq->list); + } + spin_unlock_bh(&rtwdev->ba_lock); +} + +void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) +{ + struct rtw89_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->ba_lock); + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + + if (sta == txq->sta) + list_del_init(&rtwtxq->list); + } + spin_unlock_bh(&rtwdev->ba_lock); +} + +void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) +{ + struct rtw89_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->ba_lock); + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->forbid_ba_list, list) { + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + + if (sta == txq->sta) { + clear_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags); + list_del_init(&rtwtxq->list); + } + } + spin_unlock_bh(&rtwdev->ba_lock); +} + +void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&rtwsta->roc_queue))) + dev_kfree_skb_any(skb); +} + +static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, + struct rtw89_txq *rtwtxq) +{ + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + struct ieee80211_sta *sta = txq->sta; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + + if (unlikely(!rtwsta) || unlikely(rtwsta->disassoc)) + return; + + if (!test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags) || + test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) + return; + + spin_lock_bh(&rtwdev->ba_lock); + if (!test_and_set_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) + list_add_tail(&rtwtxq->list, &rtwdev->forbid_ba_list); + spin_unlock_bh(&rtwdev->ba_lock); + + ieee80211_stop_tx_ba_session(sta, txq->tid); + cancel_delayed_work(&rtwdev->forbid_ba_work); + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->forbid_ba_work, + RTW89_FORBID_BA_TIMER); +} + +static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, + struct rtw89_txq *rtwtxq, + struct sk_buff *skb) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + struct ieee80211_sta *sta = txq->sta; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + + if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) + return; + + if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + rtw89_core_stop_tx_ba_session(rtwdev, rtwtxq); + return; + } + + if (unlikely(!sta)) + return; + + if (unlikely(test_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags))) + return; + + if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) { + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_AMPDU; + return; + } + + spin_lock_bh(&rtwdev->ba_lock); + if (!rtwsta->disassoc && list_empty(&rtwtxq->list)) { + list_add_tail(&rtwtxq->list, &rtwdev->ba_list); + ieee80211_queue_work(hw, &rtwdev->ba_work); + } + spin_unlock_bh(&rtwdev->ba_lock); +} + +static void rtw89_core_txq_push(struct rtw89_dev *rtwdev, + struct rtw89_txq *rtwtxq, + unsigned long frame_cnt, + unsigned long byte_cnt) +{ + struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); + struct ieee80211_vif *vif = txq->vif; + struct ieee80211_sta *sta = txq->sta; + struct sk_buff *skb; + unsigned long i; + int ret; + + rcu_read_lock(); + for (i = 0; i < frame_cnt; i++) { + skb = ieee80211_tx_dequeue_ni(rtwdev->hw, txq); + if (!skb) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, "dequeue a NULL skb\n"); + goto out; + } + rtw89_core_txq_check_agg(rtwdev, rtwtxq, skb); + ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, NULL); + if (ret) { + rtw89_err(rtwdev, "failed to push txq: %d\n", ret); + ieee80211_free_txskb(rtwdev->hw, skb); + break; + } + } +out: + rcu_read_unlock(); +} + +static u32 rtw89_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 tid) +{ + u8 qsel, ch_dma; + + qsel = rtw89_core_get_qsel(rtwdev, tid); + ch_dma = rtw89_chip_get_ch_dma(rtwdev, qsel); + + return rtw89_hci_check_and_reclaim_tx_resource(rtwdev, ch_dma); +} + +static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, + struct ieee80211_txq *txq, + unsigned long *frame_cnt, + bool *sched_txq, bool *reinvoke) +{ + struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(txq->sta); + struct rtw89_sta_link *rtwsta_link; + + if (!rtwsta) + return false; + + rtwsta_link = rtw89_get_designated_link(rtwsta); + if (unlikely(!rtwsta_link)) { + rtw89_err(rtwdev, "agg wait: find no designated link\n"); + return false; + } + + if (rtwsta_link->max_agg_wait <= 0) + return false; + + if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) + return false; + + if (*frame_cnt > 1) { + *frame_cnt -= 1; + *sched_txq = true; + *reinvoke = true; + rtwtxq->wait_cnt = 1; + return false; + } + + if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta_link->max_agg_wait) { + *reinvoke = true; + rtwtxq->wait_cnt++; + return true; + } + + rtwtxq->wait_cnt = 0; + return false; +} + +static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinvoke) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_txq *txq; + struct rtw89_vif *rtwvif; + struct rtw89_txq *rtwtxq; + unsigned long frame_cnt; + unsigned long byte_cnt; + u32 tx_resource; + bool sched_txq; + + ieee80211_txq_schedule_start(hw, ac); + while ((txq = ieee80211_next_txq(hw, ac))) { + rtwtxq = (struct rtw89_txq *)txq->drv_priv; + rtwvif = vif_to_rtwvif(txq->vif); + + if (rtwvif->offchan) { + ieee80211_return_txq(hw, txq, true); + continue; + } + tx_resource = rtw89_check_and_reclaim_tx_resource(rtwdev, txq->tid); + sched_txq = false; + + ieee80211_txq_get_depth(txq, &frame_cnt, &byte_cnt); + if (rtw89_core_txq_agg_wait(rtwdev, txq, &frame_cnt, &sched_txq, reinvoke)) { + ieee80211_return_txq(hw, txq, true); + continue; + } + frame_cnt = min_t(unsigned long, frame_cnt, tx_resource); + rtw89_core_txq_push(rtwdev, rtwtxq, frame_cnt, byte_cnt); + ieee80211_return_txq(hw, txq, sched_txq); + if (frame_cnt != 0) + rtw89_core_tx_kick_off(rtwdev, rtw89_core_get_qsel(rtwdev, txq->tid)); + + /* bound of tx_resource could get stuck due to burst traffic */ + if (frame_cnt == tx_resource) + *reinvoke = true; + } + ieee80211_txq_schedule_end(hw, ac); +} + +static void rtw89_ips_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + ips_work); + + lockdep_assert_wiphy(wiphy); + + rtw89_enter_ips_by_hwflags(rtwdev); +} + +static void rtw89_core_txq_work(struct work_struct *w) +{ + struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work); + bool reinvoke = false; + u8 ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + rtw89_core_txq_schedule(rtwdev, ac, &reinvoke); + + if (reinvoke) { + /* reinvoke to process the last frame */ + mod_delayed_work(rtwdev->txq_wq, &rtwdev->txq_reinvoke_work, 1); + } +} + +static void rtw89_core_txq_reinvoke_work(struct work_struct *w) +{ + struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, + txq_reinvoke_work.work); + + queue_work(rtwdev->txq_wq, &rtwdev->txq_work); +} + +static void rtw89_forbid_ba_work(struct work_struct *w) +{ + struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, + forbid_ba_work.work); + struct rtw89_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->ba_lock); + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->forbid_ba_list, list) { + clear_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags); + list_del_init(&rtwtxq->list); + } + spin_unlock_bh(&rtwdev->ba_lock); +} + +static void rtw89_core_sta_pending_tx_iter(void *data, + struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_vif_link *target = data; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + struct sk_buff *skb; + int qsel, ret; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + if (rtwvif_link->chanctx_idx == target->chanctx_idx) + goto bottom; + + return; + +bottom: + if (skb_queue_len(&rtwsta->roc_queue) == 0) + return; + + while ((skb = skb_dequeue(&rtwsta->roc_queue))) { + ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); + if (ret) { + rtw89_warn(rtwdev, "pending tx failed with %d\n", ret); + dev_kfree_skb_any(skb); + } else { + rtw89_core_tx_kick_off(rtwdev, qsel); + } + } +} + +static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_core_sta_pending_tx_iter, + rtwvif_link); +} + +int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool qos, bool ps, int timeout) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1; + struct rtw89_sta_link *rtwsta_link; + struct rtw89_tx_wait_info *wait; + struct ieee80211_sta *sta; + struct ieee80211_hdr *hdr; + struct rtw89_sta *rtwsta; + struct sk_buff *skb; + int ret, qsel; + + if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) + return 0; + + wait = kzalloc_obj(*wait); + if (!wait) + return -ENOMEM; + + init_completion(&wait->completion); + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, vif->cfg.ap_addr); + if (!sta) { + ret = -EINVAL; + goto out; + } + rtwsta = sta_to_rtwsta(sta); + + skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, qos); + if (!skb) { + ret = -ENOMEM; + goto out; + } + + wait->skb = skb; + + hdr = (struct ieee80211_hdr *)skb->data; + if (ps) + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); + + rtwsta_link = rtwsta->links[rtwvif_link->link_id]; + if (unlikely(!rtwsta_link)) { + ret = -ENOLINK; + dev_kfree_skb_any(skb); + goto out; + } + + ret = rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, &qsel, wait); + if (ret) { + rtw89_warn(rtwdev, "nullfunc transmit failed: %d\n", ret); + dev_kfree_skb_any(skb); + goto out; + } + + rcu_read_unlock(); + + return rtw89_core_tx_kick_off_and_wait(rtwdev, skb, wait, qsel, + timeout); +out: + rcu_read_unlock(); + kfree(wait); + + return ret; +} + +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_chanctx_pause_parm pause_parm = { + .rsn = RTW89_CHANCTX_PAUSE_REASON_ROC, + }; + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link; + struct cfg80211_chan_def roc_chan; + struct rtw89_vif *tmp_vif; + u32 reg; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ips_by_hwflags(rtwdev); + rtw89_leave_lps(rtwdev); + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "roc start: find no designated link\n"); + return; + } + + roc->link_id = rtwvif_link->link_id; + + pause_parm.trigger = rtwvif_link; + rtw89_chanctx_pause(rtwdev, &pause_parm); + + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true, + RTW89_ROC_TX_TIMEOUT); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "roc send null-1 failed: %d\n", ret); + + rtw89_for_each_rtwvif(rtwdev, tmp_vif) { + struct rtw89_vif_link *tmp_link; + unsigned int link_id; + + rtw89_vif_for_each_link(tmp_vif, tmp_link, link_id) { + if (tmp_link->chanctx_idx == rtwvif_link->chanctx_idx) { + tmp_vif->offchan = true; + break; + } + } + } + + cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT); + rtw89_config_roc_chandef(rtwdev, rtwvif_link, &roc_chan); + rtw89_set_channel(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); + + rtw89_phy_dig_suspend(rtwdev); + ieee80211_ready_on_channel(hw); + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); + wiphy_delayed_work_queue(hw->wiphy, &rtwvif->roc.roc_work, + msecs_to_jiffies(rtwvif->roc.duration)); +} + +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *tmp_vif; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + ieee80211_remain_on_channel_expired(hw); + + rtw89_leave_ips_by_hwflags(rtwdev); + rtw89_leave_lps(rtwdev); + + rtwvif_link = rtwvif->links[roc->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "roc end: find no link (link id %u)\n", + roc->link_id); + return; + } + + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr); + + roc->state = RTW89_ROC_IDLE; + rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL); + rtw89_chanctx_proceed(rtwdev, NULL); + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false, + RTW89_ROC_TX_TIMEOUT); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "roc send null-0 failed: %d\n", ret); + + rtw89_for_each_rtwvif(rtwdev, tmp_vif) + tmp_vif->offchan = false; + + rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif_link); + queue_work(rtwdev->txq_wq, &rtwdev->txq_work); + rtw89_phy_dig_resume(rtwdev, true); + + if (hw->conf.flags & IEEE80211_CONF_IDLE) + wiphy_delayed_work_queue(hw->wiphy, &roc->roc_work, + msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); +} + +void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, + roc.roc_work.work); + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_roc *roc = &rtwvif->roc; + + lockdep_assert_wiphy(wiphy); + + switch (roc->state) { + case RTW89_ROC_IDLE: + rtw89_enter_ips_by_hwflags(rtwdev); + break; + case RTW89_ROC_MGMT: + case RTW89_ROC_NORMAL: + rtw89_roc_end(rtwdev, rtwvif); + break; + default: + break; + } +} + +static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, + u32 throughput, u64 cnt, + enum rtw89_tfc_interval interval) +{ + u64 cnt_level; + + switch (interval) { + default: + case RTW89_TFC_INTERVAL_100MS: + cnt_level = 5; + break; + case RTW89_TFC_INTERVAL_2SEC: + cnt_level = 100; + break; + } + + if (cnt < cnt_level) + return RTW89_TFC_IDLE; + if (throughput > 50) + return RTW89_TFC_HIGH; + if (throughput > 10) + return RTW89_TFC_MID; + if (throughput > 2) + return RTW89_TFC_LOW; + return RTW89_TFC_ULTRA_LOW; +} + +static void rtw89_calc_vif_active_histogram(struct rtw89_dev *rtwdev, + struct rtw89_traffic_stats *stats, + enum rtw89_tfc_interval interval) +{ + struct rtw89_vif *rtwvif; + + stats->udp_ratio = stats->tx_cnt ? + DIV_ROUND_DOWN_ULL(stats->udp * 100, stats->tx_cnt) : 0; + stats->active_histogram <<= 1; + + switch (interval) { + case RTW89_TFC_INTERVAL_2SEC: + rtwvif = container_of(stats, struct rtw89_vif, stats); + + if (stats->tcp >= RTW89_TCP_TH && stats->tx_cnt >= stats->rx_cnt) + stats->active_histogram |= BIT(0); + + if (stats->active_histogram & RTW89_RECENT_ACTIVE_HIST) + rtwvif->burst_active = true; + else + rtwvif->burst_active = false; + + break; + case RTW89_TFC_INTERVAL_100MS: + if (stats->udp_ratio >= RTW89_UDP_RATIO_TH) + stats->active_histogram |= BIT(0); + break; + } + + stats->tcp = 0; + stats->udp = 0; +} + +static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, + struct rtw89_traffic_stats *stats, + enum rtw89_tfc_interval interval, bool by_vif) +{ + enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; + enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; + + stats->tx_throughput_raw = rtw89_bytes_to_mbps(stats->tx_unicast, interval); + stats->rx_throughput_raw = rtw89_bytes_to_mbps(stats->rx_unicast, interval); + + ewma_tp_add(&stats->tx_ewma_tp, stats->tx_throughput_raw); + ewma_tp_add(&stats->rx_ewma_tp, stats->rx_throughput_raw); + + stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); + stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); + stats->tx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->tx_throughput, + stats->tx_cnt, interval); + stats->rx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->rx_throughput, + stats->rx_cnt, interval); + stats->tx_avg_len = stats->tx_cnt ? + DIV_ROUND_DOWN_ULL(stats->tx_unicast, stats->tx_cnt) : 0; + stats->rx_avg_len = stats->rx_cnt ? + DIV_ROUND_DOWN_ULL(stats->rx_unicast, stats->rx_cnt) : 0; + + if (by_vif) + rtw89_calc_vif_active_histogram(rtwdev, stats, interval); + + stats->tx_unicast = 0; + stats->rx_unicast = 0; + stats->tx_cnt = 0; + stats->rx_cnt = 0; + stats->rx_tf_periodic = stats->rx_tf_acc; + stats->rx_tf_acc = 0; + + if (tx_tfc_lv != stats->tx_tfc_lv || rx_tfc_lv != stats->rx_tfc_lv) + return true; + + return false; +} + +static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + bool tfc_changed; + + tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats, + RTW89_TFC_INTERVAL_2SEC, false); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats, + RTW89_TFC_INTERVAL_2SEC, true); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link); + } + + return tfc_changed; +} + +static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev, + enum rtw89_tfc_interval interval) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + + /* + * If vcore level is set, temperature is high and voltage is low. As + * entering power save must reset voltage to default, avoid power save + * until vcore decreases to zero resulting from temperature becomes low. + */ + if (hal->thermal_prot_vlv) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (rtwvif->tdls_peer) + continue; + if (rtwvif->offchan) + continue; + + if (rtwvif->stats_ps.tx_tfc_lv >= RTW89_TFC_MID || + rtwvif->stats_ps.rx_tfc_lv >= RTW89_TFC_MID) + continue; + + vif = rtwvif_to_vif(rtwvif); + + if (!(vif->type == NL80211_IFTYPE_STATION || + vif->type == NL80211_IFTYPE_P2P_CLIENT)) + continue; + + if (!rtw89_core_bcn_track_can_lps(rtwdev)) + continue; + + if (!rtw89_core_proto_stats_can_lps(rtwdev, rtwvif, interval)) + continue; + + rtw89_enter_lps(rtwdev, rtwvif, true); + } +} + +static void rtw89_core_rfk_tssi_record(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 path_num = min(chip->rf_path_num, RTW89_RFK_RECORD_PATH_NR); + struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait; + int i = info->record_tssi_idx; + u32 base; + u32 mask; + int path; + + if (chip->chip_gen == RTW89_CHIP_AX) + return; + + info->record_tssi_idx = (info->record_tssi_idx + 1) % + RTW89_RFK_RECORD_HISTORY_NR; + + if (chip->chip_id == RTL8922A) { + base = 0x2ee10; + mask = 0x7fc00; + } else { + base = 0x2f918; + mask = 0x000001ff; + } + + for (path = 0; path < path_num; path++) { + u32 addr = base + 0x100 * path; + + info->tssi_code[i][path] = rtw89_read32_mask(rtwdev, addr, mask); + } +} + +static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev) +{ + enum rtw89_entity_mode mode; + + mode = rtw89_get_entity_mode(rtwdev); + if (mode == RTW89_ENTITY_MODE_MCC) + return; + + rtw89_chip_rfk_track(rtwdev); + + rtw89_core_rfk_tssi_record(rtwdev); +} + +void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) +{ + enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); + + if (mode == RTW89_ENTITY_MODE_MCC) + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_P2P_PS_CHANGE); + else + rtw89_process_p2p_ps(rtwdev, rtwvif_link, bss_conf); +} + +void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, + struct rtw89_traffic_stats *stats) +{ + stats->tx_unicast = 0; + stats->rx_unicast = 0; + stats->tx_cnt = 0; + stats->rx_cnt = 0; + ewma_tp_init(&stats->tx_ewma_tp); + ewma_tp_init(&stats->rx_ewma_tp); +} + +#define RTW89_MLSR_GOTO_2GHZ_THRESHOLD -53 +#define RTW89_MLSR_EXIT_2GHZ_THRESHOLD -38 +static void rtw89_core_mlsr_link_decision(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif) +{ + unsigned int sel_link_id = IEEE80211_MLD_MAX_NUM_LINKS; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 decided_bands = BIT(RTW89_BAND_NUM) - 1; + struct rtw89_vif_link *rtwvif_link; + const struct rtw89_chan *chan; + unsigned long usable_links; + struct rtw89_bb_ctx *bb; + unsigned int link_id; + u8 rssi; + + usable_links = ieee80211_vif_usable_links(vif); + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) + goto select; + + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + rssi = ewma_rssi_read(&bb->bcn_rssi); + if (unlikely(!rssi)) + return; + + if (RTW89_RSSI_RAW_TO_DBM(rssi) >= RTW89_MLSR_EXIT_2GHZ_THRESHOLD) + decided_bands = BIT(RTW89_BAND_5G) | BIT(RTW89_BAND_6G); + else if (RTW89_RSSI_RAW_TO_DBM(rssi) <= RTW89_MLSR_GOTO_2GHZ_THRESHOLD) + decided_bands = BIT(RTW89_BAND_2G); + else + return; + + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (decided_bands & BIT(chan->band_type)) + return; + + usable_links &= ~BIT(rtwvif_link->link_id); + +select: + rcu_read_lock(); + + for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) { + struct ieee80211_bss_conf *link_conf; + struct ieee80211_channel *channel; + enum rtw89_band band; + + link_conf = rcu_dereference(vif->link_conf[link_id]); + if (unlikely(!link_conf)) + continue; + + channel = link_conf->chanreq.oper.chan; + if (unlikely(!channel)) + continue; + + band = rtw89_nl80211_to_hw_band(channel->band); + if (decided_bands & BIT(band)) { + sel_link_id = link_id; + break; + } + } + + rcu_read_unlock(); + + if (sel_link_id == IEEE80211_MLD_MAX_NUM_LINKS) + return; + + rtw89_core_mlsr_switch(rtwdev, rtwvif, sel_link_id); +} + +static void rtw89_core_mlo_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_MLO)) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + vif = rtwvif_to_vif(rtwvif); + if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif)) + continue; + + switch (rtwvif->mlo_mode) { + case RTW89_MLO_MODE_MLSR: + rtw89_core_mlsr_link_decision(rtwdev, rtwvif); + break; + default: + break; + } + } +} + +static void rtw89_track_ps_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + track_ps_work.work); + struct rtw89_vif *rtwvif; + + lockdep_assert_wiphy(wiphy); + + if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags)) + return; + + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) + return; + + wiphy_delayed_work_queue(wiphy, &rtwdev->track_ps_work, + RTW89_TRACK_PS_WORK_PERIOD); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats_ps, + RTW89_TFC_INTERVAL_100MS, true); + + if (rtwdev->scanning) + return; + + if (rtwdev->lps_enabled && !rtwdev->btc.btc_ctrl_lps) + rtw89_enter_lps_track(rtwdev, RTW89_TFC_INTERVAL_100MS); +} + +static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + track_work.work); + bool tfc_changed; + + lockdep_assert_wiphy(wiphy); + + if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags)) + return; + + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) + return; + + wiphy_delayed_work_queue(wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); + + tfc_changed = rtw89_traffic_stats_track(rtwdev); + if (rtwdev->scanning) + return; + + rtw89_leave_lps(rtwdev); + + if (tfc_changed) { + rtw89_hci_recalc_int_mit(rtwdev); + rtw89_btc_ntfy_wl_sta(rtwdev); + } + rtw89_mac_bf_monitor_track(rtwdev); + rtw89_core_bcn_track(rtwdev); + rtw89_phy_stat_track(rtwdev); + rtw89_phy_env_monitor_track(rtwdev); + rtw89_phy_dig(rtwdev); + rtw89_core_rfk_track(rtwdev); + rtw89_phy_ra_update(rtwdev); + rtw89_phy_cfo_track(rtwdev); + rtw89_phy_tx_path_div_track(rtwdev); + rtw89_phy_antdiv_track(rtwdev); + rtw89_phy_ul_tb_ctrl_track(rtwdev); + rtw89_phy_edcca_track(rtwdev); + rtw89_sar_track(rtwdev); + rtw89_chanctx_track(rtwdev); + rtw89_core_rfkill_poll(rtwdev, false); + rtw89_core_mlo_track(rtwdev); + + if (rtwdev->lps_enabled && !rtwdev->btc.btc_ctrl_lps) + rtw89_enter_lps_track(rtwdev, RTW89_TFC_INTERVAL_2SEC); +} + +void rtw89_core_dm_disable_cfg(struct rtw89_dev *rtwdev, u32 new) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 old = hal->disabled_dm_bitmap; + + if (new == old) + return; + + hal->disabled_dm_bitmap = new; + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "Disable DM: 0x%x -> 0x%x\n", old, new); +} + +void rtw89_core_dm_disable_set(struct rtw89_dev *rtwdev, enum rtw89_dm_type type) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 cur = hal->disabled_dm_bitmap; + + rtw89_core_dm_disable_cfg(rtwdev, cur | BIT(type)); +} + +void rtw89_core_dm_disable_clr(struct rtw89_dev *rtwdev, enum rtw89_dm_type type) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 cur = hal->disabled_dm_bitmap; + + rtw89_core_dm_disable_cfg(rtwdev, cur & ~BIT(type)); +} + +u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size) +{ + unsigned long bit; + + bit = find_first_zero_bit(addr, size); + if (bit < size) + set_bit(bit, addr); + + return bit; +} + +void rtw89_core_release_bit_map(unsigned long *addr, u8 bit) +{ + clear_bit(bit, addr); +} + +void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits) +{ + bitmap_zero(addr, nbits); +} + +int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + struct rtw89_ba_cam_entry *entry = NULL, *tmp; + u8 idx; + int i; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + idx = rtw89_core_acquire_bit_map(cam_info->ba_cam_map, chip->bacam_num); + if (idx == chip->bacam_num) { + /* allocate a static BA CAM to tid=0/5, so replace the existing + * one if BA CAM is full. Hardware will process the original tid + * automatically. + */ + if (tid != 0 && tid != 5) + return -ENOSPC; + + for_each_set_bit(i, cam_info->ba_cam_map, chip->bacam_num) { + tmp = &cam_info->ba_cam_entry[i]; + if (tmp->tid == 0 || tmp->tid == 5) + continue; + + idx = i; + entry = tmp; + list_del(&entry->list); + break; + } + + if (!entry) + return -ENOSPC; + } else { + entry = &cam_info->ba_cam_entry[idx]; + } + + entry->tid = tid; + list_add_tail(&entry->list, &rtwsta_link->ba_cam_list); + + *cam_idx = idx; + + return 0; +} + +int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + struct rtw89_ba_cam_entry *entry = NULL, *tmp; + u8 idx; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) { + if (entry->tid != tid) + continue; + + idx = entry - cam_info->ba_cam_entry; + list_del(&entry->list); + + rtw89_core_release_bit_map(cam_info->ba_cam_map, idx); + *cam_idx = idx; + return 0; + } + + return -ENOENT; +} + +#define RTW89_TYPE_MAPPING(_type) \ + case NL80211_IFTYPE_ ## _type: \ + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ + break +void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_bss_conf *bss_conf; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (vif->p2p) + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT; + else + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_STATION; + break; + case NL80211_IFTYPE_AP: + if (vif->p2p) + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_GO; + else + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_AP; + break; + RTW89_TYPE_MAPPING(ADHOC); + RTW89_TYPE_MAPPING(MONITOR); + RTW89_TYPE_MAPPING(MESH_POINT); + default: + WARN_ON(1); + break; + } + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: + rtwvif_link->net_type = RTW89_NET_TYPE_AP_MODE; + rtwvif_link->self_role = RTW89_SELF_ROLE_AP; + break; + case NL80211_IFTYPE_ADHOC: + rtwvif_link->net_type = RTW89_NET_TYPE_AD_HOC; + rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT; + break; + case NL80211_IFTYPE_STATION: + if (assoc) { + rtwvif_link->net_type = RTW89_NET_TYPE_INFRA; + + rcu_read_lock(); + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + rtwvif_link->trigger = bss_conf->he_support; + rcu_read_unlock(); + } else { + rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; + rtwvif_link->trigger = false; + } + rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT; + rtwvif_link->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; + break; + case NL80211_IFTYPE_MONITOR: + break; + default: + WARN_ON(1); + break; + } +} + +int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + struct rtw89_hal *hal = &rtwdev->hal; + u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; + int i; + int ret; + + rtwsta_link->prev_rssi = 0; + INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); + ewma_rssi_init(&rtwsta_link->avg_rssi); + ewma_snr_init(&rtwsta_link->avg_snr); + ewma_evm_init(&rtwsta_link->evm_1ss); + for (i = 0; i < ant_num; i++) { + ewma_rssi_init(&rtwsta_link->rssi[i]); + ewma_evm_init(&rtwsta_link->evm_min[i]); + ewma_evm_init(&rtwsta_link->evm_max[i]); + } + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + /* must do rtw89_reg_6ghz_recalc() before rfk channel */ + ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); + if (ret) + return ret; + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, + BTC_ROLE_MSTS_STA_CONN_START); + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); + + if (vif->p2p) { + rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, + &rtwsta_link->tx_retry); + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 60); + } + rtw89_phy_dig_suspend(rtwdev); + } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); + return ret; + } + + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, + RTW89_ROLE_CREATE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c role info\n"); + return ret; + } + + ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } + + return 0; +} + +int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + + rtw89_assoc_link_clr(rtwsta_link); + + if (vif->type == NL80211_IFTYPE_STATION) { + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, false); + rtw89_core_bcn_track_reset(rtwdev); + } + + if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + rtw89_p2p_noa_once_deinit(rtwvif_link); + + return 0; +} + +int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + int ret; + + rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, true); + rtw89_mac_bf_disassoc(rtwdev, rtwvif_link, rtwsta_link); + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); + if (sta->tdls) + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + rtw89_vif_type_mapping(rtwvif_link, false); + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true); + } + + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); + return ret; + } + + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, true); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c join info\n"); + return ret; + } + + /* update cam aid mac_id net_type */ + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_CON_DISCONN); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cam\n"); + return ret; + } + + return ret; +} + +static bool rtw89_sta_link_can_er(struct rtw89_dev *rtwdev, + struct ieee80211_bss_conf *bss_conf, + struct ieee80211_link_sta *link_sta) +{ + if (!bss_conf->he_support || + bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE) + return false; + + if (rtwdev->chip->chip_id == RTL8852C && + rtw89_sta_link_has_su_mu_4xhe08(link_sta) && + !rtw89_sta_link_has_er_su_4xhe08(link_sta)) + return false; + + return true; +} + +int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, + rtwsta_link); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + struct ieee80211_link_sta *link_sta; + int ret; + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + if (sta->tdls) { + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam, + link_sta->addr); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n"); + rcu_read_unlock(); + return ret; + } + + rcu_read_unlock(); + } + + ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta_link->addr_cam, bssid_cam); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c init addr cam\n"); + return ret; + } + } + + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); + return ret; + } + + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, false); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c join info\n"); + return ret; + } + + /* update cam aid mac_id net_type */ + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_CON_DISCONN); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cam\n"); + return ret; + } + + rtw89_phy_ra_assoc(rtwdev, rtwsta_link); + rtw89_mac_bf_assoc(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, false); + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + struct ieee80211_bss_conf *bss_conf; + u8 link_mode = 0; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + rtwsta_link->er_cap = rtw89_sta_link_can_er(rtwdev, bss_conf, link_sta); + + if (link_sta->he_cap.has_he || link_sta->eht_cap.has_eht) + link_mode = 2; + else if (link_sta->vht_cap.vht_supported) + link_mode = 1; + bb->path_diff.link_mode = link_mode; + + rcu_read_unlock(); + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, + BTC_ROLE_MSTS_STA_CONN_END); + rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan); + rtw89_phy_ul_tb_assoc(rtwdev, rtwvif_link); + rtw89_core_bcn_track_assoc(rtwdev, rtwvif_link); + + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c general packet\n"); + return ret; + } + + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + + if (vif->p2p) + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, + rtwsta_link->tx_retry); + rtw89_phy_dig_resume(rtwdev, false); + } + + rtw89_assoc_link_set(rtwsta_link); + return ret; +} + +int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + int ret; + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false); + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, + BTC_ROLE_MSTS_STA_DIS_CONN); + + if (vif->p2p) + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, + rtwsta_link->tx_retry); + } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, + RTW89_ROLE_REMOVE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c role info\n"); + return ret; + } + } + + return 0; +} + +static void _rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta, + struct cfg80211_tid_cfg *tid_conf) +{ + struct ieee80211_txq *txq; + struct rtw89_txq *rtwtxq; + u32 mask = tid_conf->mask; + u8 tids = tid_conf->tids; + int tids_nbit = BITS_PER_BYTE; + int i; + + for (i = 0; i < tids_nbit; i++, tids >>= 1) { + if (!tids) + break; + + if (!(tids & BIT(0))) + continue; + + txq = sta->txq[i]; + rtwtxq = (struct rtw89_txq *)txq->drv_priv; + + if (mask & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) { + if (tid_conf->ampdu == NL80211_TID_CONFIG_ENABLE) { + clear_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags); + } else { + if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) + ieee80211_stop_tx_ba_session(sta, txq->tid); + spin_lock_bh(&rtwdev->ba_lock); + list_del_init(&rtwtxq->list); + set_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags); + spin_unlock_bh(&rtwdev->ba_lock); + } + } + + if (mask & BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL) && tids == 0xff) { + if (tid_conf->amsdu == NL80211_TID_CONFIG_ENABLE) + sta->max_amsdu_subframes = 0; + else + sta->max_amsdu_subframes = 1; + } + } +} + +void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta, + struct cfg80211_tid_config *tid_config) +{ + int i; + + for (i = 0; i < tid_config->n_tid_conf; i++) + _rtw89_core_set_tid_config(rtwdev, sta, + &tid_config->tid_conf[i]); +} + +static void rtw89_init_ht_cap(struct rtw89_dev *rtwdev, + struct ieee80211_sta_ht_cap *ht_cap) +{ + static const __le16 highest[RF_PATH_MAX] = { + cpu_to_le16(150), cpu_to_le16(300), cpu_to_le16(450), cpu_to_le16(600), + }; + struct rtw89_hal *hal = &rtwdev->hal; + u8 nss = hal->rx_nss; + int i; + + ht_cap->ht_supported = true; + ht_cap->cap = 0; + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_MAX_AMSDU | + IEEE80211_HT_CAP_TX_STBC | + (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_DSSSCCK40 | + IEEE80211_HT_CAP_SGI_40; + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + for (i = 0; i < nss; i++) + ht_cap->mcs.rx_mask[i] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + ht_cap->mcs.rx_highest = highest[nss - 1]; +} + +static void rtw89_init_vht_cap(struct rtw89_dev *rtwdev, + struct ieee80211_sta_vht_cap *vht_cap) +{ + static const __le16 highest_bw80[RF_PATH_MAX] = { + cpu_to_le16(433), cpu_to_le16(867), cpu_to_le16(1300), cpu_to_le16(1733), + }; + static const __le16 highest_bw160[RF_PATH_MAX] = { + cpu_to_le16(867), cpu_to_le16(1733), cpu_to_le16(2600), cpu_to_le16(3467), + }; + const struct rtw89_chip_info *chip = rtwdev->chip; + const __le16 *highest = chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160) ? + highest_bw160 : highest_bw80; + struct rtw89_hal *hal = &rtwdev->hal; + u16 tx_mcs_map = 0, rx_mcs_map = 0; + u8 sts_cap = 3; + int i; + + for (i = 0; i < 8; i++) { + if (i < hal->tx_nss) + tx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); + else + tx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); + if (i < hal->rx_nss) + rx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); + else + rx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); + } + + vht_cap->vht_supported = true; + vht_cap->cap = chip->max_vht_mpdu_cap | + IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_HTC_VHT | + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | + 0; + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + vht_cap->cap |= sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) + vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | + IEEE80211_VHT_CAP_SHORT_GI_160; + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rx_mcs_map); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(tx_mcs_map); + vht_cap->vht_mcs.rx_highest = highest[hal->rx_nss - 1]; + vht_cap->vht_mcs.tx_highest = highest[hal->tx_nss - 1]; + + if (ieee80211_hw_check(rtwdev->hw, SUPPORTS_VHT_EXT_NSS_BW)) + vht_cap->vht_mcs.tx_highest |= + cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); +} + +static void rtw89_init_he_cap(struct rtw89_dev *rtwdev, + enum nl80211_band band, + enum nl80211_iftype iftype, + struct ieee80211_sband_iftype_data *iftype_data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + bool no_ng16 = (chip->chip_id == RTL8852A && hal->cv == CHIP_CBV) || + (chip->chip_id == RTL8852B && hal->cv == CHIP_CAV); + struct ieee80211_sta_he_cap *he_cap; + int nss = hal->rx_nss; + u8 *mac_cap_info; + u8 *phy_cap_info; + u16 mcs_map = 0; + int i; + + for (i = 0; i < 8; i++) { + if (i < nss) + mcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); + else + mcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); + } + + he_cap = &iftype_data->he_cap; + mac_cap_info = he_cap->he_cap_elem.mac_cap_info; + phy_cap_info = he_cap->he_cap_elem.phy_cap_info; + + he_cap->has_he = true; + mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; + if (iftype == NL80211_IFTYPE_STATION) + mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; + mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_ALL_ACK | + IEEE80211_HE_MAC_CAP2_BSR; + mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2; + if (iftype == NL80211_IFTYPE_AP) + mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL; + mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_OPS | + IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; + if (iftype == NL80211_IFTYPE_STATION) + mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; + if (band == NL80211_BAND_2GHZ) { + phy_cap_info[0] = + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; + } else { + phy_cap_info[0] = + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) + phy_cap_info[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + } + phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | + IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; + phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | + IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | + IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ | + IEEE80211_HE_PHY_CAP2_DOPPLER_TX; + phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM; + if (iftype == NL80211_IFTYPE_STATION) + phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM | + IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2; + if (iftype == NL80211_IFTYPE_AP) + phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; + phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) + phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; + phy_cap_info[5] = no_ng16 ? 0 : + IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | + IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; + phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | + IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | + IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE; + phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | + IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | + IEEE80211_HE_PHY_CAP7_MAX_NC_1; + phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | + IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI | + IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996; + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) + phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | + IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; + phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | + IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB | + u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, + IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK); + if (iftype == NL80211_IFTYPE_STATION) + phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; + he_cap->he_mcs_nss_supp.rx_mcs_80 = cpu_to_le16(mcs_map); + he_cap->he_mcs_nss_supp.tx_mcs_80 = cpu_to_le16(mcs_map); + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) { + he_cap->he_mcs_nss_supp.rx_mcs_160 = cpu_to_le16(mcs_map); + he_cap->he_mcs_nss_supp.tx_mcs_160 = cpu_to_le16(mcs_map); + } + + if (band == NL80211_BAND_6GHZ) { + __le16 capa; + + capa = le16_encode_bits(IEEE80211_HT_MPDU_DENSITY_NONE, + IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) | + le16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K, + IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) | + le16_encode_bits(chip->max_vht_mpdu_cap, + IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN); + iftype_data->he_6ghz_capa.capa = capa; + } +} + +static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev, + enum nl80211_band band, + enum nl80211_iftype iftype, + struct ieee80211_sband_iftype_data *iftype_data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_eht_cap_elem_fixed *eht_cap_elem; + struct ieee80211_eht_mcs_nss_supp *eht_nss; + struct ieee80211_sta_eht_cap *eht_cap; + struct rtw89_hal *hal = &rtwdev->hal; + bool support_mcs_12_13 = true; + bool support_320mhz = false; + u8 val, val_mcs13; + int sts = 8; + + if (chip->chip_gen == RTW89_CHIP_AX || hal->no_eht) + return; + + if (hal->no_mcs_12_13) + support_mcs_12_13 = false; + + if (band == NL80211_BAND_6GHZ && + chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_320)) + support_320mhz = true; + + eht_cap = &iftype_data->eht_cap; + eht_cap_elem = &eht_cap->eht_cap_elem; + eht_nss = &eht_cap->eht_mcs_nss_supp; + + eht_cap->has_eht = true; + + eht_cap_elem->mac_cap_info[0] = + u8_encode_bits(chip->max_eht_mpdu_cap, + IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); + eht_cap_elem->mac_cap_info[1] = 0; + + eht_cap_elem->phy_cap_info[0] = + IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | + IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; + if (support_320mhz) + eht_cap_elem->phy_cap_info[0] |= + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; + + eht_cap_elem->phy_cap_info[0] |= + u8_encode_bits(u8_get_bits(sts - 1, BIT(0)), + IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK); + eht_cap_elem->phy_cap_info[1] = + u8_encode_bits(u8_get_bits(sts - 1, GENMASK(2, 1)), + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) | + u8_encode_bits(sts - 1, + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK); + if (support_320mhz) + eht_cap_elem->phy_cap_info[1] |= + u8_encode_bits(sts - 1, + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK); + + eht_cap_elem->phy_cap_info[2] = 0; + + eht_cap_elem->phy_cap_info[3] = + IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | + IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK; + + eht_cap_elem->phy_cap_info[4] = + IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP | + u8_encode_bits(1, IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK); + + eht_cap_elem->phy_cap_info[5] = + u8_encode_bits(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US, + IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); + + eht_cap_elem->phy_cap_info[6] = 0; + eht_cap_elem->phy_cap_info[7] = 0; + eht_cap_elem->phy_cap_info[8] = 0; + + val = u8_encode_bits(hal->rx_nss, IEEE80211_EHT_MCS_NSS_RX) | + u8_encode_bits(hal->tx_nss, IEEE80211_EHT_MCS_NSS_TX); + val_mcs13 = support_mcs_12_13 ? val : 0; + + eht_nss->bw._80.rx_tx_mcs9_max_nss = val; + eht_nss->bw._80.rx_tx_mcs11_max_nss = val; + eht_nss->bw._80.rx_tx_mcs13_max_nss = val_mcs13; + eht_nss->bw._160.rx_tx_mcs9_max_nss = val; + eht_nss->bw._160.rx_tx_mcs11_max_nss = val; + eht_nss->bw._160.rx_tx_mcs13_max_nss = val_mcs13; + if (support_320mhz) { + eht_nss->bw._320.rx_tx_mcs9_max_nss = val; + eht_nss->bw._320.rx_tx_mcs11_max_nss = val; + eht_nss->bw._320.rx_tx_mcs13_max_nss = val_mcs13; + } +} + +#define RTW89_SBAND_IFTYPES_NR 2 + +static int rtw89_init_he_eht_cap(struct rtw89_dev *rtwdev, + enum nl80211_band band, + struct ieee80211_supported_band *sband) +{ + struct ieee80211_sband_iftype_data *iftype_data; + enum nl80211_iftype iftype; + int idx = 0; + + iftype_data = devm_kcalloc(rtwdev->dev, RTW89_SBAND_IFTYPES_NR, + sizeof(*iftype_data), GFP_KERNEL); + if (!iftype_data) + return -ENOMEM; + + for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { + switch (iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_AP: + break; + default: + continue; + } + + if (idx >= RTW89_SBAND_IFTYPES_NR) { + rtw89_warn(rtwdev, "run out of iftype_data\n"); + break; + } + + iftype_data[idx].types_mask = BIT(iftype); + + rtw89_init_he_cap(rtwdev, band, iftype, &iftype_data[idx]); + rtw89_init_eht_cap(rtwdev, band, iftype, &iftype_data[idx]); + + idx++; + } + + _ieee80211_set_sband_iftype_data(sband, iftype_data, idx); + return 0; +} + +static struct ieee80211_supported_band * +rtw89_core_sband_dup(struct rtw89_dev *rtwdev, + const struct ieee80211_supported_band *sband) +{ + struct ieee80211_supported_band *dup; + + dup = devm_kmemdup(rtwdev->dev, sband, sizeof(*sband), GFP_KERNEL); + if (!dup) + return NULL; + + dup->channels = devm_kmemdup(rtwdev->dev, sband->channels, + sizeof(*sband->channels) * sband->n_channels, + GFP_KERNEL); + if (!dup->channels) + return NULL; + + dup->bitrates = devm_kmemdup(rtwdev->dev, sband->bitrates, + sizeof(*sband->bitrates) * sband->n_bitrates, + GFP_KERNEL); + if (!dup->bitrates) + return NULL; + + return dup; +} + +static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_supported_band *sband; + u8 support_bands = rtwdev->chip->support_bands; + int ret; + + if (test_bit(RTW89_QUIRK_DISABLE_2GHZ, rtwdev->quirks)) + support_bands &= ~BIT(NL80211_BAND_2GHZ); + + if (support_bands & BIT(NL80211_BAND_2GHZ)) { + sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_2ghz); + if (!sband) + return -ENOMEM; + rtw89_init_ht_cap(rtwdev, &sband->ht_cap); + ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_2GHZ, sband); + if (ret) + return ret; + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; + } + + if (support_bands & BIT(NL80211_BAND_5GHZ)) { + sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_5ghz); + if (!sband) + return -ENOMEM; + rtw89_init_ht_cap(rtwdev, &sband->ht_cap); + rtw89_init_vht_cap(rtwdev, &sband->vht_cap); + ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_5GHZ, sband); + if (ret) + return ret; + hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; + } + + if (support_bands & BIT(NL80211_BAND_6GHZ)) { + sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_6ghz); + if (!sband) + return -ENOMEM; + ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_6GHZ, sband); + if (ret) + return ret; + hw->wiphy->bands[NL80211_BAND_6GHZ] = sband; + } + + return 0; +} + +static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) +{ + int i; + + for (i = 0; i < RTW89_PHY_NUM; i++) + skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]); + for (i = 0; i < RTW89_PHY_NUM; i++) + rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX; +} + +void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev; + struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, + update_beacon_work); + + lockdep_assert_wiphy(wiphy); + + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) + return; + + rtwdev = rtwvif_link->rtwvif->rtwdev; + + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); +} + +void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_vif_link *rtwvif_link = + container_of(work, struct rtw89_vif_link, csa_beacon_work.work); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct ieee80211_bss_conf *bss_conf; + unsigned int delay; + + lockdep_assert_wiphy(wiphy); + + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) + return; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->csa_active) { + rcu_read_unlock(); + return; + } + + delay = ieee80211_tu_to_usec(bss_conf->beacon_int); + + rcu_read_unlock(); + + if (!ieee80211_beacon_cntdwn_is_complete(vif, rtwvif_link->link_id)) { + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); + + wiphy_delayed_work_queue(wiphy, &rtwvif_link->csa_beacon_work, + usecs_to_jiffies(delay)); + } else { + ieee80211_csa_finish(vif, rtwvif_link->link_id); + } +} + +struct rtw89_wait_response * +rtw89_wait_for_cond_prep(struct rtw89_wait_info *wait, unsigned int cond) +{ + struct rtw89_wait_response *prep; + unsigned int cur; + + /* use -EPERM _iff_ telling eval side not to make any changes */ + + cur = atomic_cmpxchg(&wait->cond, RTW89_WAIT_COND_IDLE, cond); + if (cur != RTW89_WAIT_COND_IDLE) + return ERR_PTR(-EPERM); + + prep = kzalloc_obj(*prep); + if (!prep) + return ERR_PTR(-ENOMEM); + + init_completion(&prep->completion); + + rcu_assign_pointer(wait->resp, prep); + + return prep; +} + +int rtw89_wait_for_cond_eval(struct rtw89_wait_info *wait, + struct rtw89_wait_response *prep, int err) +{ + unsigned long time_left; + + if (IS_ERR(prep)) { + err = err ?: PTR_ERR(prep); + + /* special error case: no permission to reset anything */ + if (PTR_ERR(prep) == -EPERM) + return err; + + goto reset; + } + + if (err) + goto cleanup; + + time_left = wait_for_completion_timeout(&prep->completion, + RTW89_WAIT_FOR_COND_TIMEOUT); + if (time_left == 0) { + err = -ETIMEDOUT; + goto cleanup; + } + + wait->data = prep->data; + +cleanup: + rcu_assign_pointer(wait->resp, NULL); + kfree_rcu(prep, rcu_head); + +reset: + atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); + + if (err) + return err; + + if (wait->data.err) + return -EFAULT; + + return 0; +} + +static void rtw89_complete_cond_resp(struct rtw89_wait_response *resp, + const struct rtw89_completion_data *data) +{ + resp->data = *data; + complete(&resp->completion); +} + +void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, + const struct rtw89_completion_data *data) +{ + struct rtw89_wait_response *resp; + unsigned int cur; + + guard(rcu)(); + + resp = rcu_dereference(wait->resp); + if (!resp) + return; + + cur = atomic_cmpxchg(&wait->cond, cond, RTW89_WAIT_COND_IDLE); + if (cur != cond) + return; + + rtw89_complete_cond_resp(resp, data); +} + +void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, + enum rtw89_btc_hmsg event, + enum rtw89_phy_idx phy_idx) +{ + u16 bt_slot_req[RTW89_PHY_NUM]; + + switch (event) { + case RTW89_BTC_HMSG_SET_BT_REQ_SLOT: + bt_slot_req[phy_idx] = rtw89_coex_query_bt_req_len(rtwdev, phy_idx); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "coex updates PHY-%d BT req len to %d TU\n", + phy_idx, bt_slot_req[phy_idx]); + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_BT_SLOT_CHANGE); + break; + default: + if (event < NUM_OF_RTW89_BTC_HMSG) + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "unhandled BTC HMSG event: %d\n", event); + else + rtw89_warn(rtwdev, + "unrecognized BTC HMSG event: %d\n", event); + break; + } +} + +void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks) +{ + const struct dmi_system_id *match; + enum rtw89_quirks quirk; + + if (!quirks) + return; + + for (match = dmi_first_match(quirks); match; match = dmi_first_match(match + 1)) { + quirk = (uintptr_t)match->driver_data; + if (quirk >= NUM_OF_RTW89_QUIRKS) + continue; + + set_bit(quirk, rtwdev->quirks); + } +} +EXPORT_SYMBOL(rtw89_check_quirks); + +int rtw89_core_start(struct rtw89_dev *rtwdev) +{ + bool no_bbmcu = !rtwdev->chip->bbmcu_nr; + int ret; + + ret = rtw89_mac_preinit(rtwdev); + if (ret) { + rtw89_err(rtwdev, "mac preinit fail, ret: %d\n", ret); + return ret; + } + + if (no_bbmcu) + rtw89_chip_bb_preinit(rtwdev); + + rtw89_phy_init_bb_afe(rtwdev); + + /* above do preinit before downloading firmware */ + + ret = rtw89_mac_init(rtwdev); + if (ret) { + rtw89_err(rtwdev, "mac init fail, ret:%d\n", ret); + return ret; + } + + rtw89_btc_ntfy_poweron(rtwdev); + + /* efuse process */ + + /* pre-config BB/RF, BB reset/RFC reset */ + ret = rtw89_chip_reset_bb_rf(rtwdev); + if (ret) + return ret; + + rtw89_phy_init_bb_reg(rtwdev); + rtw89_chip_bb_postinit(rtwdev); + rtw89_phy_init_rf_reg(rtwdev, false); + + rtw89_btc_ntfy_init(rtwdev, BTC_MODE_NORMAL); + + rtw89_phy_dm_init(rtwdev); + + rtw89_mac_set_edcca_mode_bands(rtwdev, true); + rtw89_mac_cfg_ppdu_status_bands(rtwdev, true); + rtw89_mac_cfg_phy_rpt_bands(rtwdev, true); + rtw89_mac_update_rts_threshold(rtwdev); + + ret = rtw89_hci_start(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to start hci\n"); + return ret; + } + + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_ps_work, + RTW89_TRACK_PS_WORK_PERIOD); + + set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); + + rtw89_chip_rfk_init_late(rtwdev); + rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); + rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable); + rtw89_fw_h2c_init_ba_cam(rtwdev); + rtw89_tas_fw_timer_enable(rtwdev, true); + rtwdev->ps_hang_cnt = 0; + + return 0; +} + +void rtw89_core_stop(struct rtw89_dev *rtwdev) +{ + struct wiphy *wiphy = rtwdev->hw->wiphy; + struct rtw89_btc *btc = &rtwdev->btc; + + lockdep_assert_wiphy(wiphy); + + /* Prvent to stop twice; enter_ips and ops_stop */ + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) + return; + + rtw89_tas_fw_timer_enable(rtwdev, false); + rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_OFF); + + clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); + + wiphy_work_cancel(wiphy, &rtwdev->c2h_work); + wiphy_work_cancel(wiphy, &rtwdev->cancel_6ghz_probe_work); + wiphy_work_cancel(wiphy, &btc->eapol_notify_work); + wiphy_work_cancel(wiphy, &btc->arp_notify_work); + wiphy_work_cancel(wiphy, &btc->dhcp_notify_work); + wiphy_work_cancel(wiphy, &btc->icmp_notify_work); + cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->tx_wait_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->chanctx_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_act1_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->mcc_prepare_done_work); + cancel_delayed_work_sync(&rtwdev->forbid_ba_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work); + + rtw89_btc_ntfy_poweroff(rtwdev); + rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true); + rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, true); + rtw89_hci_stop(rtwdev); + rtw89_hci_deinit(rtwdev); + rtw89_mac_pwr_off(rtwdev); + rtw89_hci_reset(rtwdev); +} + +u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 mac_id_num; + u8 mac_id; + + if (rtwdev->support_mlo) + mac_id_num = chip->support_macid_num / chip->support_link_num; + else + mac_id_num = chip->support_macid_num; + + mac_id = find_first_zero_bit(rtwdev->mac_id_map, mac_id_num); + if (mac_id == mac_id_num) + return RTW89_MAX_MAC_ID_NUM; + + set_bit(mac_id, rtwdev->mac_id_map); + return mac_id; +} + +void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id) +{ + clear_bit(mac_id, rtwdev->mac_id_map); +} + +void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u8 mac_id, u8 port) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 support_link_num = chip->support_link_num; + u8 support_mld_num = 0; + unsigned int link_id; + u8 index; + + bitmap_zero(rtwvif->links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) + rtwvif->links[link_id] = NULL; + + rtwvif->rtwdev = rtwdev; + + if (rtwdev->support_mlo) { + rtwvif->links_inst_valid_num = support_link_num; + support_mld_num = chip->support_macid_num / support_link_num; + } else { + rtwvif->links_inst_valid_num = 1; + } + + for (index = 0; index < rtwvif->links_inst_valid_num; index++) { + struct rtw89_vif_link *inst = &rtwvif->links_inst[index]; + + inst->rtwvif = rtwvif; + inst->mac_id = mac_id + index * support_mld_num; + inst->mac_idx = RTW89_MAC_0 + index; + inst->phy_idx = RTW89_PHY_0 + index; + + /* multi-link use the same port id on different HW bands */ + inst->port = port; + } +} + +void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, u8 mac_id) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 support_link_num = chip->support_link_num; + u8 support_mld_num = 0; + unsigned int link_id; + u8 index; + + bitmap_zero(rtwsta->links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) + rtwsta->links[link_id] = NULL; + + rtwsta->rtwdev = rtwdev; + rtwsta->rtwvif = rtwvif; + + if (rtwdev->support_mlo) { + rtwsta->links_inst_valid_num = support_link_num; + support_mld_num = chip->support_macid_num / support_link_num; + } else { + rtwsta->links_inst_valid_num = 1; + } + + for (index = 0; index < rtwsta->links_inst_valid_num; index++) { + struct rtw89_sta_link *inst = &rtwsta->links_inst[index]; + + inst->rtwvif_link = &rtwvif->links_inst[index]; + + inst->rtwsta = rtwsta; + inst->mac_id = mac_id + index * support_mld_num; + } +} + +struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif, + unsigned int link_id) +{ + struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id]; + u8 index; + int ret; + + if (rtwvif_link) + return rtwvif_link; + + index = find_first_zero_bit(rtwvif->links_inst_map, + rtwvif->links_inst_valid_num); + if (index == rtwvif->links_inst_valid_num) { + ret = -EBUSY; + goto err; + } + + rtwvif_link = &rtwvif->links_inst[index]; + rtwvif_link->link_id = link_id; + + set_bit(index, rtwvif->links_inst_map); + rtwvif->links[link_id] = rtwvif_link; + list_add_tail(&rtwvif_link->dlink_schd, &rtwvif->dlink_pool); + return rtwvif_link; + +err: + rtw89_err(rtwvif->rtwdev, "vif (link_id %u) failed to set link: %d\n", + link_id, ret); + return NULL; +} + +void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id) +{ + struct rtw89_vif_link **container = &rtwvif->links[link_id]; + struct rtw89_vif_link *link = *container; + u8 index; + + if (!link) + return; + + index = rtw89_vif_link_inst_get_index(link); + clear_bit(index, rtwvif->links_inst_map); + *container = NULL; + list_del(&link->dlink_schd); +} + +struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta, + unsigned int link_id) +{ + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id]; + struct rtw89_sta_link *rtwsta_link = rtwsta->links[link_id]; + u8 index; + int ret; + + if (rtwsta_link) + return rtwsta_link; + + if (!rtwvif_link) { + ret = -ENOLINK; + goto err; + } + + index = rtw89_vif_link_inst_get_index(rtwvif_link); + if (test_bit(index, rtwsta->links_inst_map)) { + ret = -EBUSY; + goto err; + } + + rtwsta_link = &rtwsta->links_inst[index]; + rtwsta_link->link_id = link_id; + + set_bit(index, rtwsta->links_inst_map); + rtwsta->links[link_id] = rtwsta_link; + list_add_tail(&rtwsta_link->dlink_schd, &rtwsta->dlink_pool); + return rtwsta_link; + +err: + rtw89_err(rtwsta->rtwdev, "sta (link_id %u) failed to set link: %d\n", + link_id, ret); + return NULL; +} + +void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id) +{ + struct rtw89_sta_link **container = &rtwsta->links[link_id]; + struct rtw89_sta_link *link = *container; + u8 index; + + if (!link) + return; + + index = rtw89_sta_link_inst_get_index(link); + clear_bit(index, rtwsta->links_inst_map); + *container = NULL; + list_del(&link->dlink_schd); +} + +int rtw89_core_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_btc *btc = &rtwdev->btc; + u8 band; + + rtwdev->io = rtw89_fw_cmd_ofld_alloc_and_get_io_ops(rtwdev); + + bitmap_or(rtwdev->quirks, rtwdev->quirks, &rtwdev->chip->default_quirks, + NUM_OF_RTW89_QUIRKS); + + INIT_LIST_HEAD(&rtwdev->ba_list); + INIT_LIST_HEAD(&rtwdev->forbid_ba_list); + INIT_LIST_HEAD(&rtwdev->rtwvifs_list); + INIT_LIST_HEAD(&rtwdev->early_h2c_list); + for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { + if (!(rtwdev->chip->support_bands & BIT(band))) + continue; + INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); + } + INIT_LIST_HEAD(&rtwdev->scan_info.chan_list); + INIT_LIST_HEAD(&rtwdev->tx_waits); + INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); + INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); + INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); + wiphy_delayed_work_init(&rtwdev->track_work, rtw89_track_work); + wiphy_delayed_work_init(&rtwdev->track_ps_work, rtw89_track_ps_work); + wiphy_delayed_work_init(&rtwdev->chanctx_work, rtw89_chanctx_work); + wiphy_delayed_work_init(&rtwdev->coex_act1_work, rtw89_coex_act1_work); + wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); + wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); + wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); + wiphy_delayed_work_init(&rtwdev->mcc_prepare_done_work, rtw89_mcc_prepare_done_work); + wiphy_delayed_work_init(&rtwdev->tx_wait_work, rtw89_tx_wait_work); + INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work); + wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); + rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); + if (!rtwdev->txq_wq) + return -ENOMEM; + spin_lock_init(&rtwdev->ba_lock); + spin_lock_init(&rtwdev->rpwm_lock); + rtwdev->total_sta_assoc = 0; + + rtw89_init_wait(&rtwdev->mcc.wait); + rtw89_init_wait(&rtwdev->mlo.wait); + rtw89_init_wait(&rtwdev->mac.fw_ofld_wait); + rtw89_init_wait(&rtwdev->wow.wait); + rtw89_init_wait(&rtwdev->mac.ps_wait); + + wiphy_work_init(&rtwdev->c2h_work, rtw89_fw_c2h_work); + wiphy_work_init(&rtwdev->ips_work, rtw89_ips_work); + wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); + INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); + + spin_lock_init(&rtwdev->tx_rpt.skb_lock); + skb_queue_head_init(&rtwdev->c2h_queue); + rtw89_core_ppdu_sts_init(rtwdev); + rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); + + rtwdev->hal.rx_fltr = mac->default_rx_fltr; + rtwdev->dbcc_en = false; + rtwdev->mlo_dbcc_mode = MLO_DBCC_NOT_SUPPORT; + rtwdev->mac.qta_mode = RTW89_QTA_SCC; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { + rtwdev->dbcc_en = true; + rtwdev->mac.qta_mode = RTW89_QTA_DBCC; + rtwdev->mlo_dbcc_mode = MLO_1_PLUS_1_1RF; + } + + rtwdev->bbs[RTW89_PHY_0].phy_idx = RTW89_PHY_0; + rtwdev->bbs[RTW89_PHY_1].phy_idx = RTW89_PHY_1; + + wiphy_work_init(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); + wiphy_work_init(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); + wiphy_work_init(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); + wiphy_work_init(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); + + init_completion(&rtwdev->fw.req.completion); + init_completion(&rtwdev->rfk_wait.completion); + + schedule_work(&rtwdev->load_firmware_work); + + rtw89_ser_init(rtwdev); + rtw89_entity_init(rtwdev); + rtw89_sar_init(rtwdev); + rtw89_phy_ant_gain_init(rtwdev); + + return 0; +} +EXPORT_SYMBOL(rtw89_core_init); + +void rtw89_core_deinit(struct rtw89_dev *rtwdev) +{ + rtw89_ser_deinit(rtwdev); + rtw89_unload_firmware(rtwdev); + __rtw89_fw_free_all_early_h2c(rtwdev); + + destroy_workqueue(rtwdev->txq_wq); +} +EXPORT_SYMBOL(rtw89_core_deinit); + +void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool hw_scan) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + + rtwdev->scanning = true; + + ether_addr_copy(rtwvif_link->mac_addr, mac_addr); + rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type); + rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true); + rtw89_hci_recalc_int_mit(rtwdev); + rtw89_phy_config_edcca(rtwdev, bb, true); + rtw89_tas_scan(rtwdev, true); + + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr, + RTW89_ROLE_INFO_CHANGE); +} + +void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool hw_scan) +{ + struct ieee80211_bss_conf *bss_conf; + struct rtw89_bb_ctx *bb; + int ret; + + if (!rtwvif_link) + return; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); + + rcu_read_unlock(); + + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, + RTW89_ROLE_INFO_CHANGE); + + rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); + rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx); + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + rtw89_phy_config_edcca(rtwdev, bb, false); + rtw89_tas_scan(rtwdev, false); + + if (hw_scan) { + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, false, false, + RTW89_SCAN_NULL_TIMEOUT); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "scan send null-0 failed: %d\n", ret); + } + + rtwdev->scanning = false; + rtw89_for_each_active_bb(rtwdev, bb) + bb->dig.bypass_dig = true; + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->ips_work); +} + +static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + int ret; + u8 val2; + u8 val; + u8 cv; + + cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK); + if (chip->chip_id == RTL8852A && cv <= CHIP_CBV) { + if (rtw89_read32(rtwdev, R_AX_GPIO0_7_FUNC_SEL) == RTW89_R32_DEAD) + cv = CHIP_CAV; + else + cv = CHIP_CBV; + } + + hal->cv = cv; + + if (rtw89_is_rtl885xb(rtwdev) || chip->chip_gen >= RTW89_CHIP_BE) { + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CV, &val); + if (ret) + return; + + hal->acv = u8_get_bits(val, XTAL_SI_ACV_MASK); + } + + if (chip->chip_gen >= RTW89_CHIP_BE) { + hal->cid = + rtw89_read32_mask(rtwdev, R_BE_SYS_CHIPINFO, B_BE_HW_ID_MASK); + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CHIP_ID_L, &val); + if (ret) + return; + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CHIP_ID_H, &val2); + if (ret) + return; + + hal->aid = val | val2 << 8; + } +} + +static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + rtwdev->hal.support_cckpd = + !(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) && + !(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV); + rtwdev->hal.support_igi = + rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV; + + if (test_bit(RTW89_QUIRK_THERMAL_PROT_120C, rtwdev->quirks)) + rtwdev->hal.thermal_prot_th = chip->thermal_th[1]; + else if (test_bit(RTW89_QUIRK_THERMAL_PROT_110C, rtwdev->quirks)) + rtwdev->hal.thermal_prot_th = chip->thermal_th[0]; + else + rtwdev->hal.thermal_prot_th = 0; +} + +static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_rfe_parms_conf *conf = chip->rfe_parms_conf; + struct rtw89_efuse *efuse = &rtwdev->efuse; + const struct rtw89_rfe_parms *sel; + u8 rfe_type = efuse->rfe_type; + + if (!conf) { + sel = chip->dflt_parms; + goto out; + } + + while (conf->rfe_parms) { + if (rfe_type == conf->rfe_type) { + sel = conf->rfe_parms; + goto out; + } + conf++; + } + + sel = chip->dflt_parms; + +out: + rtwdev->rfe_parms = rtw89_load_rfe_data_from_fw(rtwdev, sel); + rtw89_load_txpwr_table(rtwdev, rtwdev->rfe_parms->byr_tbl); +} + +int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + unsigned int link_id) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u16 usable_links = ieee80211_vif_usable_links(vif); + u16 active_links = vif->active_links; + struct rtw89_vif_link *target; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (unlikely(!ieee80211_vif_is_mld(vif))) + return -EOPNOTSUPP; + + if (unlikely(link_id >= IEEE80211_MLD_MAX_NUM_LINKS || + !(usable_links & BIT(link_id)))) { + rtw89_warn(rtwdev, "%s: link id %u is not usable\n", __func__, + link_id); + return -ENOLINK; + } + + if (active_links == BIT(link_id)) + return 0; + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "%s: switch to link id %u MLSR\n", + __func__, link_id); + + rtw89_leave_lps(rtwdev); + + ieee80211_stop_queues(rtwdev->hw); + flush_work(&rtwdev->txq_work); + + ret = ieee80211_set_active_links(vif, BIT(link_id)); + if (ret) { + rtw89_err(rtwdev, "%s: failed to work on link id %u\n", + __func__, link_id); + goto wake_queue; + } + + target = rtwvif->links[link_id]; + if (unlikely(!target)) { + rtw89_err(rtwdev, "%s: failed to confirm link id %u\n", + __func__, link_id); + + ieee80211_set_active_links(vif, active_links); + ret = -EFAULT; + goto wake_queue; + } + + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) + rtw89_chip_rfk_channel(rtwdev, target); + + rtw89_fw_h2c_tx_history(rtwdev, target->mac_id); + + rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; + +wake_queue: + ieee80211_wake_queues(rtwdev->hw); + + return ret; +} + +static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + bool bb_preinit = false; + int ret; + + /* + * Normally in probe stage, we don't need to do BB pre-initialization. + * However, RTL8922D firmware can access BB registers at firmware + * initial state, so initialize it to avoid BB IO stuck in firmware. + */ + if (chip->chip_id == RTL8922D) + bb_preinit = true; + + ret = rtw89_mac_partial_init(rtwdev, false, bb_preinit); + if (ret) + return ret; + + ret = mac->parse_efuse_map(rtwdev); + if (ret) + return ret; + + ret = mac->parse_phycap_map(rtwdev); + if (ret) + return ret; + + ret = rtw89_mac_setup_phycap(rtwdev); + if (ret) + return ret; + + rtw89_core_setup_phycap(rtwdev); + + rtw89_hci_mac_pre_deinit(rtwdev); + + return 0; +} + +static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev) +{ + rtw89_chip_fem_setup(rtwdev); + + return 0; +} + +static bool rtw89_chip_has_rfkill(struct rtw89_dev *rtwdev) +{ + return !!rtwdev->chip->rfkill_init; +} + +static void rtw89_core_rfkill_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_rfkill_regs *regs = rtwdev->chip->rfkill_init; + + rtw89_write16_mask(rtwdev, regs->pinmux.addr, + regs->pinmux.mask, regs->pinmux.data); + rtw89_write16_mask(rtwdev, regs->mode.addr, + regs->mode.mask, regs->mode.data); +} + +static bool rtw89_core_rfkill_get(struct rtw89_dev *rtwdev) +{ + const struct rtw89_reg_def *reg = &rtwdev->chip->rfkill_get; + + return !rtw89_read8_mask(rtwdev, reg->addr, reg->mask); +} + +static void rtw89_rfkill_polling_init(struct rtw89_dev *rtwdev) +{ + if (!rtw89_chip_has_rfkill(rtwdev)) + return; + + rtw89_core_rfkill_init(rtwdev); + rtw89_core_rfkill_poll(rtwdev, true); + wiphy_rfkill_start_polling(rtwdev->hw->wiphy); +} + +static void rtw89_rfkill_polling_deinit(struct rtw89_dev *rtwdev) +{ + if (!rtw89_chip_has_rfkill(rtwdev)) + return; + + wiphy_rfkill_stop_polling(rtwdev->hw->wiphy); +} + +void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force) +{ + bool prev, blocked; + + if (!rtw89_chip_has_rfkill(rtwdev)) + return; + + prev = test_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags); + blocked = rtw89_core_rfkill_get(rtwdev); + + if (!force && prev == blocked) + return; + + rtw89_info(rtwdev, "rfkill hardware state changed to %s\n", + str_enable_disable(!blocked)); + + if (blocked) + set_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags); + else + clear_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags); + + wiphy_rfkill_set_hw_state(rtwdev->hw->wiphy, blocked); +} + +int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + int ret; + + rtw89_read_chip_ver(rtwdev); + + ret = rtw89_mac_pwr_on(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to power on\n"); + return ret; + } + + ret = rtw89_wait_firmware_completion(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to wait firmware completion\n"); + goto out; + } + + ret = rtw89_fw_recognize(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to recognize firmware\n"); + goto out; + } + + ret = rtw89_chip_efuse_info_setup(rtwdev); + if (ret) + goto out; + + ret = rtw89_fw_recognize_elements(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to recognize firmware elements\n"); + goto out; + } + + ret = rtw89_chip_board_info_setup(rtwdev); + if (ret) + goto out; + + ret = rtw89_chip_data_setup(rtwdev); + if (ret) + goto out; + + rtw89_core_setup_rfe_parms(rtwdev); + rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); + + rtw89_info(rtwdev, "chip info CID: %x, CV: %x, AID: %x, ACV: %x, RFE: %d\n", + hal->cid, hal->cv, hal->aid, hal->acv, efuse->rfe_type); + +out: + rtw89_mac_pwr_off(rtwdev); + + return ret; +} +EXPORT_SYMBOL(rtw89_chip_info_setup); + +void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_bss_conf *bss_conf; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->he_support || !vif->cfg.assoc) { + rcu_read_unlock(); + return; + } + + rcu_read_unlock(); + + if (chip->ops->set_txpwr_ul_tb_offset) + chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx); +} + +static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 n = rtwdev->support_mlo ? chip->support_link_num : 1; + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + int ret; + int tx_headroom = IEEE80211_HT_CTL_LEN; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + tx_headroom += chip->txwd_body_size + chip->txwd_info_size; + + hw->vif_data_size = struct_size_t(struct rtw89_vif, links_inst, n); + hw->sta_data_size = struct_size_t(struct rtw89_sta, links_inst, n); + hw->txq_data_size = sizeof(struct rtw89_txq); + hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg); + + SET_IEEE80211_PERM_ADDR(hw, efuse->addr); + + hw->extra_tx_headroom = tx_headroom; + hw->queues = IEEE80211_NUM_ACS; + hw->max_rx_aggregation_subframes = chip->max_rx_agg_num; + hw->max_tx_aggregation_subframes = chip->max_tx_agg_num; + hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; + + hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC | + IEEE80211_RADIOTAP_MCS_HAVE_STBC; + hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | + IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; + + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, MFP_CAPABLE); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, RX_INCLUDES_FCS); + ieee80211_hw_set(hw, TX_AMSDU); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); + ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); + ieee80211_hw_set(hw, WANT_MONITOR_VIF); + ieee80211_hw_set(hw, CHANCTX_STA_CSA); + + if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + + if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) + ieee80211_hw_set(hw, CONNECTION_MONITOR); + + if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) + ieee80211_hw_set(hw, AP_LINK_PS); + + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); + + if (hal->ant_diversity) { + hw->wiphy->available_antennas_tx = 0x3; + hw->wiphy->available_antennas_rx = 0x3; + } else { + hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; + hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; + } + + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | + WIPHY_FLAG_TDLS_EXTERNAL_SETUP | + WIPHY_FLAG_AP_UAPSD | + WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK; + + if (!chip->support_rnr) + hw->wiphy->flags |= WIPHY_FLAG_SPLIT_SCAN_6GHZ; + + if (rtwdev->support_mlo) { + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO; + hw->wiphy->iftype_ext_capab = rtw89_iftypes_ext_capa; + hw->wiphy->num_iftype_ext_capab = ARRAY_SIZE(rtw89_iftypes_ext_capa); + } + + hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + + hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID; + hw->wiphy->max_scan_ie_len = RTW89_SCANOFLD_MAX_IE_LEN; + +#ifdef CONFIG_PM + hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; + hw->wiphy->max_sched_scan_ssids = RTW89_SCANOFLD_MAX_SSID; +#endif + + hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); + hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); + hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); + hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); + hw->wiphy->max_remain_on_channel_duration = 1000; + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); + + ret = rtw89_core_set_supported_band(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to set supported band\n"); + return ret; + } + + ret = rtw89_regd_setup(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to set up regd\n"); + return ret; + } + + hw->wiphy->sar_capa = &rtw89_sar_capa; + + ret = ieee80211_register_hw(hw); + if (ret) { + rtw89_err(rtwdev, "failed to register hw\n"); + return ret; + } + + ret = rtw89_regd_init_hint(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to init regd\n"); + goto err_unregister_hw; + } + + rtw89_rfkill_polling_init(rtwdev); + rtw89_btc_init(rtwdev); + rtw89_led_init(rtwdev); + + return 0; + +err_unregister_hw: + ieee80211_unregister_hw(hw); + + return ret; +} + +static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev) +{ + struct ieee80211_hw *hw = rtwdev->hw; + + rtw89_led_deinit(rtwdev); + rtw89_rfkill_polling_deinit(rtwdev); + ieee80211_unregister_hw(hw); +} + +int rtw89_core_register(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_core_register_hw(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to register core hw\n"); + return ret; + } + + rtw89_phy_dm_init_data(rtwdev); + rtw89_debugfs_init(rtwdev); + + return 0; +} +EXPORT_SYMBOL(rtw89_core_register); + +void rtw89_core_unregister(struct rtw89_dev *rtwdev) +{ + rtw89_core_unregister_hw(rtwdev); + + rtw89_debugfs_deinit(rtwdev); +} +EXPORT_SYMBOL(rtw89_core_unregister); + +struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + u32 bus_data_size, + const struct rtw89_driver_info *info) +{ + const unsigned long *dev_id_quirks = &info->dev_id_quirks; + const struct rtw89_chip_variant *variant = info->variant; + const struct rtw89_chip_info *chip = info->chip; + struct rtw89_fw_info early_fw = {}; + const struct firmware *firmware; + struct ieee80211_hw *hw; + struct rtw89_dev *rtwdev; + struct ieee80211_ops *ops; + u32 driver_data_size; + int fw_format = -1; + bool support_mlo; + bool no_chanctx; + + firmware = rtw89_early_fw_feature_recognize(device, chip, variant, + &early_fw, &fw_format); + + ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); + if (!ops) + goto err; + + no_chanctx = chip->support_chanctx_num == 0 || + !RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &early_fw) || + !RTW89_CHK_FW_FEATURE(BEACON_FILTER, &early_fw); + + if (no_chanctx) { + ops->add_chanctx = ieee80211_emulate_add_chanctx; + ops->remove_chanctx = ieee80211_emulate_remove_chanctx; + ops->change_chanctx = ieee80211_emulate_change_chanctx; + ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx; + ops->assign_vif_chanctx = NULL; + ops->unassign_vif_chanctx = NULL; + ops->remain_on_channel = NULL; + ops->cancel_remain_on_channel = NULL; + } + + if (!chip->support_noise) + ops->get_survey = NULL; + + driver_data_size = sizeof(struct rtw89_dev) + bus_data_size; + hw = ieee80211_alloc_hw(driver_data_size, ops); + if (!hw) + goto err; + + /* Currently, our AP_LINK_PS handling only works for non-MLD softap + * or MLD-single-link softap. If RTW89_MLD_NON_STA_LINK_NUM enlarges, + * please tweak entire AP_LINKS_PS handling before supporting MLO. + */ + support_mlo = !no_chanctx && chip->support_link_num && + RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &early_fw) && + RTW89_MLD_NON_STA_LINK_NUM == 1; + + hw->wiphy->iface_combinations = rtw89_iface_combs; + + if (no_chanctx || chip->support_chanctx_num == 1) + hw->wiphy->n_iface_combinations = 1; + else + hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw89_iface_combs); + + rtwdev = hw->priv; + rtwdev->hw = hw; + rtwdev->dev = device; + rtwdev->ops = ops; + rtwdev->chip = chip; + rtwdev->variant = variant; + rtwdev->board = info->board; + rtwdev->fw.req.firmware = firmware; + rtwdev->fw.fw_format = fw_format; + rtwdev->support_mlo = support_mlo; + + bitmap_or(rtwdev->quirks, rtwdev->quirks, dev_id_quirks, + NUM_OF_RTW89_QUIRKS); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "probe driver %s chanctx\n", + no_chanctx ? "without" : "with"); + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "probe driver %s MLO cap\n", + support_mlo ? "with" : "without"); + + return rtwdev; + +err: + kfree(ops); + release_firmware(firmware); + return NULL; +} +EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); + +void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev) +{ + kfree(rtwdev->ops); + kfree(rtwdev->rfe_data); + release_firmware(rtwdev->fw.req.firmware); + ieee80211_free_hw(rtwdev->hw); +} +EXPORT_SYMBOL(rtw89_free_ieee80211_hw); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless core module"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h new file mode 100644 index 000000000..2b21d969e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -0,0 +1,9391 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_CORE_H__ +#define __RTW89_CORE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct rtw89_dev; +struct rtw89_bb_ctx; +struct rtw89_pci_info; +struct rtw89_usb_info; +struct rtw89_mac_gen_def; +struct rtw89_phy_gen_def; +struct rtw89_fw_blacklist; +struct rtw89_efuse_block_cfg; +struct rtw89_h2c_rf_tssi; +struct rtw89_fw_txpwr_track_cfg; +struct rtw89_phy_rfk_log_fmt; +struct rtw89_phy_calc_efuse_gain; +union rtw89_phy_sts_ie09; +struct rtw89_phy_sts_ie10; +struct rtw89_debugfs; +struct rtw89_regd_data; +struct rtw89_wow_cam_info; +struct rtw89_bb_wrap_data; +struct rtw89_fw_cmd_ofld_info; + +extern const struct ieee80211_ops rtw89_ops; + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKBYTE4 0xff00000000ULL +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define RFREG_MASK 0xfffff +#define INV_RF_DATA 0xffffffff +#define BYPASS_CR_DATA 0xbabecafe +#define RTW89_R32_EA 0xEAEAEAEA +#define RTW89_R32_DEAD 0xDEADBEEF + +#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2) +#define RTW89_TRACK_PS_WORK_PERIOD msecs_to_jiffies(100) +#define RTW89_FORBID_BA_TIMER round_jiffies_relative(HZ * 4) +#define RTW89_PS_HANG_MAX_CNT 3 +#define CFO_TRACK_MAX_USER 64 +#define MAX_RSSI 110 +#define RSSI_FACTOR 1 +#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI) +#define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR) +#define DELTA_SWINGIDX_SIZE 30 + +#define RTW89_RADIOTAP_ROOM_VHT sizeof(struct ieee80211_radiotap_vht) +#define RTW89_RADIOTAP_ROOM_HE (sizeof(struct ieee80211_radiotap_he) + \ + sizeof(struct ieee80211_radiotap_he_mu)) +#define RTW89_RADIOTAP_ROOM_EHT \ + (sizeof(struct ieee80211_radiotap_tlv) + \ + ALIGN(struct_size((struct ieee80211_radiotap_eht *)0, user_info, 1), 4) + \ + sizeof(struct ieee80211_radiotap_tlv) + \ + ALIGN(sizeof(struct ieee80211_radiotap_eht_usig), 4)) +#define RTW89_RADIOTAP_ROOM \ + ALIGN(max3(RTW89_RADIOTAP_ROOM_VHT, RTW89_RADIOTAP_ROOM_HE, \ + RTW89_RADIOTAP_ROOM_EHT), 64) + +#define RTW89_HTC_MASK_VARIANT GENMASK(1, 0) +#define RTW89_HTC_VARIANT_HE 3 +#define RTW89_HTC_MASK_CTL_ID GENMASK(5, 2) +#define RTW89_HTC_VARIANT_HE_CID_OM 1 +#define RTW89_HTC_VARIANT_HE_CID_CAS 6 +#define RTW89_HTC_MASK_CTL_INFO GENMASK(31, 6) + +#define RTW89_HTC_MASK_HTC_OM_RX_NSS GENMASK(8, 6) +enum htc_om_channel_width { + HTC_OM_CHANNEL_WIDTH_20 = 0, + HTC_OM_CHANNEL_WIDTH_40 = 1, + HTC_OM_CHANNEL_WIDTH_80 = 2, + HTC_OM_CHANNEL_WIDTH_160_OR_80_80 = 3, +}; +#define RTW89_HTC_MASK_HTC_OM_CH_WIDTH GENMASK(10, 9) +#define RTW89_HTC_MASK_HTC_OM_UL_MU_DIS BIT(11) +#define RTW89_HTC_MASK_HTC_OM_TX_NSTS GENMASK(14, 12) +#define RTW89_HTC_MASK_HTC_OM_ER_SU_DIS BIT(15) +#define RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR BIT(16) +#define RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS BIT(17) + +#define RTW89_TF_PAD GENMASK(11, 0) +#define RTW89_TF_BASIC_USER_INFO_SZ 6 + +#define RTW89_GET_TF_USER_INFO_AID12(data) \ + le32_get_bits(*((const __le32 *)(data)), GENMASK(11, 0)) +#define RTW89_GET_TF_USER_INFO_RUA(data) \ + le32_get_bits(*((const __le32 *)(data)), GENMASK(19, 12)) +#define RTW89_GET_TF_USER_INFO_UL_MCS(data) \ + le32_get_bits(*((const __le32 *)(data)), GENMASK(24, 21)) + +enum rtw89_subband { + RTW89_CH_2G = 0, + RTW89_CH_5G_BAND_1 = 1, + /* RTW89_CH_5G_BAND_2 = 2, unused */ + RTW89_CH_5G_BAND_3 = 3, + RTW89_CH_5G_BAND_4 = 4, + + RTW89_CH_6G_BAND_IDX0, /* Low */ + RTW89_CH_6G_BAND_IDX1, /* Low */ + RTW89_CH_6G_BAND_IDX2, /* Mid */ + RTW89_CH_6G_BAND_IDX3, /* Mid */ + RTW89_CH_6G_BAND_IDX4, /* High */ + RTW89_CH_6G_BAND_IDX5, /* High */ + RTW89_CH_6G_BAND_IDX6, /* Ultra-high */ + RTW89_CH_6G_BAND_IDX7, /* Ultra-high */ + + RTW89_SUBBAND_NR, + RTW89_SUBBAND_2GHZ_5GHZ_NR = RTW89_CH_5G_BAND_4 + 1, +}; + +enum rtw89_tx_comp_band { + RTW89_TX_COMP_BAND_2GHZ, + RTW89_TX_COMP_BAND_5GHZ_L, + RTW89_TX_COMP_BAND_5GHZ_H, + RTW89_TX_COMP_BAND_6GHZ_M, + RTW89_TX_COMP_BAND_6GHZ_UH, + + RTW89_TX_COMP_BAND_NR, +}; + +enum rtw89_gain_offset { + RTW89_GAIN_OFFSET_2G_CCK, + RTW89_GAIN_OFFSET_2G_OFDM, + RTW89_GAIN_OFFSET_5G_LOW, + RTW89_GAIN_OFFSET_5G_MID, + RTW89_GAIN_OFFSET_5G_HIGH, + RTW89_GAIN_OFFSET_6G_L0, + RTW89_GAIN_OFFSET_6G_L1, + RTW89_GAIN_OFFSET_6G_M0, + RTW89_GAIN_OFFSET_6G_M1, + RTW89_GAIN_OFFSET_6G_H0, + RTW89_GAIN_OFFSET_6G_H1, + RTW89_GAIN_OFFSET_6G_UH0, + RTW89_GAIN_OFFSET_6G_UH1, + + RTW89_GAIN_OFFSET_NR, +}; + +enum rtw89_hci_type { + RTW89_HCI_TYPE_PCIE, + RTW89_HCI_TYPE_USB, + RTW89_HCI_TYPE_SDIO, + + RTW89_HCI_TYPE_NUM, +}; + +enum rtw89_hci_dle_type { + RTW89_HCI_DLE_TYPE_PCIE, + RTW89_HCI_DLE_TYPE_USB2, + RTW89_HCI_DLE_TYPE_USB3, + RTW89_HCI_DLE_TYPE_SDIO, + + RTW89_HCI_DLE_TYPE_NUM, +}; + +enum rtw89_core_chip_id { + RTL8852A, + RTL8852B, + RTL8852BT, + RTL8852C, + RTL8851B, + RTL8922A, + RTL8922D, +}; + +enum rtw89_core_chip_cid { + RTL8922D_CID7025 = 0x74, + RTL8922D_CID7090 = 0x79, +}; + +enum rtw89_core_chip_aid { + RTL8922D_AID1348 = 0x1348, + RTL8922D_AID7060 = 0x7060, + RTL8922D_AID7102 = 0x7102, +}; + +enum rtw89_chip_gen { + RTW89_CHIP_AX, + RTW89_CHIP_BE, + + RTW89_CHIP_GEN_NUM, +}; + +enum rtw89_cv { + CHIP_CAV, + CHIP_CBV, + CHIP_CCV, + CHIP_CDV, + CHIP_CEV, + CHIP_CFV, + CHIP_CV_MAX, + CHIP_CV_INVALID = CHIP_CV_MAX, +}; + +enum rtw89_bacam_ver { + RTW89_BACAM_V0, + RTW89_BACAM_V1, + + RTW89_BACAM_V0_EXT = 99, +}; + +enum rtw89_core_tx_type { + RTW89_CORE_TX_TYPE_DATA, + RTW89_CORE_TX_TYPE_MGMT, + RTW89_CORE_TX_TYPE_FWCMD, +}; + +enum rtw89_core_rx_type { + RTW89_CORE_RX_TYPE_WIFI = 0, + RTW89_CORE_RX_TYPE_PPDU_STAT = 1, + RTW89_CORE_RX_TYPE_CHAN_INFO = 2, + RTW89_CORE_RX_TYPE_BB_SCOPE = 3, + RTW89_CORE_RX_TYPE_F2P_TXCMD = 4, + RTW89_CORE_RX_TYPE_SS2FW = 5, + RTW89_CORE_RX_TYPE_TX_REPORT = 6, + RTW89_CORE_RX_TYPE_TX_REL_HOST = 7, + RTW89_CORE_RX_TYPE_DFS_REPORT = 8, + RTW89_CORE_RX_TYPE_TX_REL_CPU = 9, + RTW89_CORE_RX_TYPE_C2H = 10, + RTW89_CORE_RX_TYPE_CSI = 11, + RTW89_CORE_RX_TYPE_CQI = 12, + RTW89_CORE_RX_TYPE_H2C = 13, + RTW89_CORE_RX_TYPE_FWDL = 14, +}; + +enum rtw89_txq_flags { + RTW89_TXQ_F_AMPDU = 0, + RTW89_TXQ_F_BLOCK_BA = 1, + RTW89_TXQ_F_FORBID_BA = 2, +}; + +enum rtw89_net_type { + RTW89_NET_TYPE_NO_LINK = 0, + RTW89_NET_TYPE_AD_HOC = 1, + RTW89_NET_TYPE_INFRA = 2, + RTW89_NET_TYPE_AP_MODE = 3, +}; + +enum rtw89_wifi_role { + RTW89_WIFI_ROLE_NONE, + RTW89_WIFI_ROLE_STATION, + RTW89_WIFI_ROLE_AP, + RTW89_WIFI_ROLE_AP_VLAN, + RTW89_WIFI_ROLE_ADHOC, + RTW89_WIFI_ROLE_ADHOC_MASTER, + RTW89_WIFI_ROLE_MESH_POINT, + RTW89_WIFI_ROLE_MONITOR, + RTW89_WIFI_ROLE_P2P_DEVICE, + RTW89_WIFI_ROLE_P2P_CLIENT, + RTW89_WIFI_ROLE_P2P_GO, + RTW89_WIFI_ROLE_NAN, + RTW89_WIFI_ROLE_MLME_MAX +}; + +enum rtw89_upd_mode { + RTW89_ROLE_CREATE, + RTW89_ROLE_REMOVE, + RTW89_ROLE_TYPE_CHANGE, + RTW89_ROLE_INFO_CHANGE, + RTW89_ROLE_CON_DISCONN, + RTW89_ROLE_BAND_SW, + RTW89_ROLE_FW_RESTORE, +}; + +enum rtw89_self_role { + RTW89_SELF_ROLE_CLIENT, + RTW89_SELF_ROLE_AP, + RTW89_SELF_ROLE_AP_CLIENT +}; + +enum rtw89_msk_sO_el { + RTW89_NO_MSK, + RTW89_SMA, + RTW89_TMA, + RTW89_BSSID +}; + +enum rtw89_sch_tx_sel { + RTW89_SCH_TX_SEL_ALL, + RTW89_SCH_TX_SEL_HIQ, + RTW89_SCH_TX_SEL_MG0, + RTW89_SCH_TX_SEL_MACID, +}; + +/* RTW89_ADDR_CAM_SEC_NONE : not enabled + * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast + * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP + * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP + */ +enum rtw89_add_cam_sec_mode { + RTW89_ADDR_CAM_SEC_NONE = 0, + RTW89_ADDR_CAM_SEC_ALL_UNI = 1, + RTW89_ADDR_CAM_SEC_NORMAL = 2, + RTW89_ADDR_CAM_SEC_4GROUP = 3, +}; + +enum rtw89_sec_key_type { + RTW89_SEC_KEY_TYPE_NONE = 0, + RTW89_SEC_KEY_TYPE_WEP40 = 1, + RTW89_SEC_KEY_TYPE_WEP104 = 2, + RTW89_SEC_KEY_TYPE_TKIP = 3, + RTW89_SEC_KEY_TYPE_WAPI = 4, + RTW89_SEC_KEY_TYPE_GCMSMS4 = 5, + RTW89_SEC_KEY_TYPE_CCMP128 = 6, + RTW89_SEC_KEY_TYPE_CCMP256 = 7, + RTW89_SEC_KEY_TYPE_GCMP128 = 8, + RTW89_SEC_KEY_TYPE_GCMP256 = 9, + RTW89_SEC_KEY_TYPE_BIP_CCMP128 = 10, +}; + +enum rtw89_port { + RTW89_PORT_0 = 0, + RTW89_PORT_1 = 1, + RTW89_PORT_2 = 2, + RTW89_PORT_3 = 3, + RTW89_PORT_4 = 4, + RTW89_PORT_NUM +}; + +enum rtw89_band { + RTW89_BAND_2G = 0, + RTW89_BAND_5G = 1, + RTW89_BAND_6G = 2, + RTW89_BAND_NUM, +}; + +enum rtw89_hw_rate { + RTW89_HW_RATE_CCK1 = 0x0, + RTW89_HW_RATE_CCK2 = 0x1, + RTW89_HW_RATE_CCK5_5 = 0x2, + RTW89_HW_RATE_CCK11 = 0x3, + RTW89_HW_RATE_OFDM6 = 0x4, + RTW89_HW_RATE_OFDM9 = 0x5, + RTW89_HW_RATE_OFDM12 = 0x6, + RTW89_HW_RATE_OFDM18 = 0x7, + RTW89_HW_RATE_OFDM24 = 0x8, + RTW89_HW_RATE_OFDM36 = 0x9, + RTW89_HW_RATE_OFDM48 = 0xA, + RTW89_HW_RATE_OFDM54 = 0xB, + RTW89_HW_RATE_MCS0 = 0x80, + RTW89_HW_RATE_MCS1 = 0x81, + RTW89_HW_RATE_MCS2 = 0x82, + RTW89_HW_RATE_MCS3 = 0x83, + RTW89_HW_RATE_MCS4 = 0x84, + RTW89_HW_RATE_MCS5 = 0x85, + RTW89_HW_RATE_MCS6 = 0x86, + RTW89_HW_RATE_MCS7 = 0x87, + RTW89_HW_RATE_MCS8 = 0x88, + RTW89_HW_RATE_MCS9 = 0x89, + RTW89_HW_RATE_MCS10 = 0x8A, + RTW89_HW_RATE_MCS11 = 0x8B, + RTW89_HW_RATE_MCS12 = 0x8C, + RTW89_HW_RATE_MCS13 = 0x8D, + RTW89_HW_RATE_MCS14 = 0x8E, + RTW89_HW_RATE_MCS15 = 0x8F, + RTW89_HW_RATE_MCS16 = 0x90, + RTW89_HW_RATE_MCS17 = 0x91, + RTW89_HW_RATE_MCS18 = 0x92, + RTW89_HW_RATE_MCS19 = 0x93, + RTW89_HW_RATE_MCS20 = 0x94, + RTW89_HW_RATE_MCS21 = 0x95, + RTW89_HW_RATE_MCS22 = 0x96, + RTW89_HW_RATE_MCS23 = 0x97, + RTW89_HW_RATE_MCS24 = 0x98, + RTW89_HW_RATE_MCS25 = 0x99, + RTW89_HW_RATE_MCS26 = 0x9A, + RTW89_HW_RATE_MCS27 = 0x9B, + RTW89_HW_RATE_MCS28 = 0x9C, + RTW89_HW_RATE_MCS29 = 0x9D, + RTW89_HW_RATE_MCS30 = 0x9E, + RTW89_HW_RATE_MCS31 = 0x9F, + RTW89_HW_RATE_VHT_NSS1_MCS0 = 0x100, + RTW89_HW_RATE_VHT_NSS1_MCS1 = 0x101, + RTW89_HW_RATE_VHT_NSS1_MCS2 = 0x102, + RTW89_HW_RATE_VHT_NSS1_MCS3 = 0x103, + RTW89_HW_RATE_VHT_NSS1_MCS4 = 0x104, + RTW89_HW_RATE_VHT_NSS1_MCS5 = 0x105, + RTW89_HW_RATE_VHT_NSS1_MCS6 = 0x106, + RTW89_HW_RATE_VHT_NSS1_MCS7 = 0x107, + RTW89_HW_RATE_VHT_NSS1_MCS8 = 0x108, + RTW89_HW_RATE_VHT_NSS1_MCS9 = 0x109, + RTW89_HW_RATE_VHT_NSS2_MCS0 = 0x110, + RTW89_HW_RATE_VHT_NSS2_MCS1 = 0x111, + RTW89_HW_RATE_VHT_NSS2_MCS2 = 0x112, + RTW89_HW_RATE_VHT_NSS2_MCS3 = 0x113, + RTW89_HW_RATE_VHT_NSS2_MCS4 = 0x114, + RTW89_HW_RATE_VHT_NSS2_MCS5 = 0x115, + RTW89_HW_RATE_VHT_NSS2_MCS6 = 0x116, + RTW89_HW_RATE_VHT_NSS2_MCS7 = 0x117, + RTW89_HW_RATE_VHT_NSS2_MCS8 = 0x118, + RTW89_HW_RATE_VHT_NSS2_MCS9 = 0x119, + RTW89_HW_RATE_VHT_NSS3_MCS0 = 0x120, + RTW89_HW_RATE_VHT_NSS3_MCS1 = 0x121, + RTW89_HW_RATE_VHT_NSS3_MCS2 = 0x122, + RTW89_HW_RATE_VHT_NSS3_MCS3 = 0x123, + RTW89_HW_RATE_VHT_NSS3_MCS4 = 0x124, + RTW89_HW_RATE_VHT_NSS3_MCS5 = 0x125, + RTW89_HW_RATE_VHT_NSS3_MCS6 = 0x126, + RTW89_HW_RATE_VHT_NSS3_MCS7 = 0x127, + RTW89_HW_RATE_VHT_NSS3_MCS8 = 0x128, + RTW89_HW_RATE_VHT_NSS3_MCS9 = 0x129, + RTW89_HW_RATE_VHT_NSS4_MCS0 = 0x130, + RTW89_HW_RATE_VHT_NSS4_MCS1 = 0x131, + RTW89_HW_RATE_VHT_NSS4_MCS2 = 0x132, + RTW89_HW_RATE_VHT_NSS4_MCS3 = 0x133, + RTW89_HW_RATE_VHT_NSS4_MCS4 = 0x134, + RTW89_HW_RATE_VHT_NSS4_MCS5 = 0x135, + RTW89_HW_RATE_VHT_NSS4_MCS6 = 0x136, + RTW89_HW_RATE_VHT_NSS4_MCS7 = 0x137, + RTW89_HW_RATE_VHT_NSS4_MCS8 = 0x138, + RTW89_HW_RATE_VHT_NSS4_MCS9 = 0x139, + RTW89_HW_RATE_HE_NSS1_MCS0 = 0x180, + RTW89_HW_RATE_HE_NSS1_MCS1 = 0x181, + RTW89_HW_RATE_HE_NSS1_MCS2 = 0x182, + RTW89_HW_RATE_HE_NSS1_MCS3 = 0x183, + RTW89_HW_RATE_HE_NSS1_MCS4 = 0x184, + RTW89_HW_RATE_HE_NSS1_MCS5 = 0x185, + RTW89_HW_RATE_HE_NSS1_MCS6 = 0x186, + RTW89_HW_RATE_HE_NSS1_MCS7 = 0x187, + RTW89_HW_RATE_HE_NSS1_MCS8 = 0x188, + RTW89_HW_RATE_HE_NSS1_MCS9 = 0x189, + RTW89_HW_RATE_HE_NSS1_MCS10 = 0x18A, + RTW89_HW_RATE_HE_NSS1_MCS11 = 0x18B, + RTW89_HW_RATE_HE_NSS2_MCS0 = 0x190, + RTW89_HW_RATE_HE_NSS2_MCS1 = 0x191, + RTW89_HW_RATE_HE_NSS2_MCS2 = 0x192, + RTW89_HW_RATE_HE_NSS2_MCS3 = 0x193, + RTW89_HW_RATE_HE_NSS2_MCS4 = 0x194, + RTW89_HW_RATE_HE_NSS2_MCS5 = 0x195, + RTW89_HW_RATE_HE_NSS2_MCS6 = 0x196, + RTW89_HW_RATE_HE_NSS2_MCS7 = 0x197, + RTW89_HW_RATE_HE_NSS2_MCS8 = 0x198, + RTW89_HW_RATE_HE_NSS2_MCS9 = 0x199, + RTW89_HW_RATE_HE_NSS2_MCS10 = 0x19A, + RTW89_HW_RATE_HE_NSS2_MCS11 = 0x19B, + RTW89_HW_RATE_HE_NSS3_MCS0 = 0x1A0, + RTW89_HW_RATE_HE_NSS3_MCS1 = 0x1A1, + RTW89_HW_RATE_HE_NSS3_MCS2 = 0x1A2, + RTW89_HW_RATE_HE_NSS3_MCS3 = 0x1A3, + RTW89_HW_RATE_HE_NSS3_MCS4 = 0x1A4, + RTW89_HW_RATE_HE_NSS3_MCS5 = 0x1A5, + RTW89_HW_RATE_HE_NSS3_MCS6 = 0x1A6, + RTW89_HW_RATE_HE_NSS3_MCS7 = 0x1A7, + RTW89_HW_RATE_HE_NSS3_MCS8 = 0x1A8, + RTW89_HW_RATE_HE_NSS3_MCS9 = 0x1A9, + RTW89_HW_RATE_HE_NSS3_MCS10 = 0x1AA, + RTW89_HW_RATE_HE_NSS3_MCS11 = 0x1AB, + RTW89_HW_RATE_HE_NSS4_MCS0 = 0x1B0, + RTW89_HW_RATE_HE_NSS4_MCS1 = 0x1B1, + RTW89_HW_RATE_HE_NSS4_MCS2 = 0x1B2, + RTW89_HW_RATE_HE_NSS4_MCS3 = 0x1B3, + RTW89_HW_RATE_HE_NSS4_MCS4 = 0x1B4, + RTW89_HW_RATE_HE_NSS4_MCS5 = 0x1B5, + RTW89_HW_RATE_HE_NSS4_MCS6 = 0x1B6, + RTW89_HW_RATE_HE_NSS4_MCS7 = 0x1B7, + RTW89_HW_RATE_HE_NSS4_MCS8 = 0x1B8, + RTW89_HW_RATE_HE_NSS4_MCS9 = 0x1B9, + RTW89_HW_RATE_HE_NSS4_MCS10 = 0x1BA, + RTW89_HW_RATE_HE_NSS4_MCS11 = 0x1BB, + + RTW89_HW_RATE_V1_MCS0 = 0x100, + RTW89_HW_RATE_V1_MCS1 = 0x101, + RTW89_HW_RATE_V1_MCS2 = 0x102, + RTW89_HW_RATE_V1_MCS3 = 0x103, + RTW89_HW_RATE_V1_MCS4 = 0x104, + RTW89_HW_RATE_V1_MCS5 = 0x105, + RTW89_HW_RATE_V1_MCS6 = 0x106, + RTW89_HW_RATE_V1_MCS7 = 0x107, + RTW89_HW_RATE_V1_MCS8 = 0x108, + RTW89_HW_RATE_V1_MCS9 = 0x109, + RTW89_HW_RATE_V1_MCS10 = 0x10A, + RTW89_HW_RATE_V1_MCS11 = 0x10B, + RTW89_HW_RATE_V1_MCS12 = 0x10C, + RTW89_HW_RATE_V1_MCS13 = 0x10D, + RTW89_HW_RATE_V1_MCS14 = 0x10E, + RTW89_HW_RATE_V1_MCS15 = 0x10F, + RTW89_HW_RATE_V1_MCS16 = 0x110, + RTW89_HW_RATE_V1_MCS17 = 0x111, + RTW89_HW_RATE_V1_MCS18 = 0x112, + RTW89_HW_RATE_V1_MCS19 = 0x113, + RTW89_HW_RATE_V1_MCS20 = 0x114, + RTW89_HW_RATE_V1_MCS21 = 0x115, + RTW89_HW_RATE_V1_MCS22 = 0x116, + RTW89_HW_RATE_V1_MCS23 = 0x117, + RTW89_HW_RATE_V1_MCS24 = 0x118, + RTW89_HW_RATE_V1_MCS25 = 0x119, + RTW89_HW_RATE_V1_MCS26 = 0x11A, + RTW89_HW_RATE_V1_MCS27 = 0x11B, + RTW89_HW_RATE_V1_MCS28 = 0x11C, + RTW89_HW_RATE_V1_MCS29 = 0x11D, + RTW89_HW_RATE_V1_MCS30 = 0x11E, + RTW89_HW_RATE_V1_MCS31 = 0x11F, + RTW89_HW_RATE_V1_VHT_NSS1_MCS0 = 0x200, + RTW89_HW_RATE_V1_VHT_NSS1_MCS1 = 0x201, + RTW89_HW_RATE_V1_VHT_NSS1_MCS2 = 0x202, + RTW89_HW_RATE_V1_VHT_NSS1_MCS3 = 0x203, + RTW89_HW_RATE_V1_VHT_NSS1_MCS4 = 0x204, + RTW89_HW_RATE_V1_VHT_NSS1_MCS5 = 0x205, + RTW89_HW_RATE_V1_VHT_NSS1_MCS6 = 0x206, + RTW89_HW_RATE_V1_VHT_NSS1_MCS7 = 0x207, + RTW89_HW_RATE_V1_VHT_NSS1_MCS8 = 0x208, + RTW89_HW_RATE_V1_VHT_NSS1_MCS9 = 0x209, + RTW89_HW_RATE_V1_VHT_NSS1_MCS10 = 0x20A, + RTW89_HW_RATE_V1_VHT_NSS1_MCS11 = 0x20B, + RTW89_HW_RATE_V1_VHT_NSS2_MCS0 = 0x220, + RTW89_HW_RATE_V1_VHT_NSS2_MCS1 = 0x221, + RTW89_HW_RATE_V1_VHT_NSS2_MCS2 = 0x222, + RTW89_HW_RATE_V1_VHT_NSS2_MCS3 = 0x223, + RTW89_HW_RATE_V1_VHT_NSS2_MCS4 = 0x224, + RTW89_HW_RATE_V1_VHT_NSS2_MCS5 = 0x225, + RTW89_HW_RATE_V1_VHT_NSS2_MCS6 = 0x226, + RTW89_HW_RATE_V1_VHT_NSS2_MCS7 = 0x227, + RTW89_HW_RATE_V1_VHT_NSS2_MCS8 = 0x228, + RTW89_HW_RATE_V1_VHT_NSS2_MCS9 = 0x229, + RTW89_HW_RATE_V1_VHT_NSS2_MCS10 = 0x22A, + RTW89_HW_RATE_V1_VHT_NSS2_MCS11 = 0x22B, + RTW89_HW_RATE_V1_VHT_NSS3_MCS0 = 0x240, + RTW89_HW_RATE_V1_VHT_NSS3_MCS1 = 0x241, + RTW89_HW_RATE_V1_VHT_NSS3_MCS2 = 0x242, + RTW89_HW_RATE_V1_VHT_NSS3_MCS3 = 0x243, + RTW89_HW_RATE_V1_VHT_NSS3_MCS4 = 0x244, + RTW89_HW_RATE_V1_VHT_NSS3_MCS5 = 0x245, + RTW89_HW_RATE_V1_VHT_NSS3_MCS6 = 0x246, + RTW89_HW_RATE_V1_VHT_NSS3_MCS7 = 0x247, + RTW89_HW_RATE_V1_VHT_NSS3_MCS8 = 0x248, + RTW89_HW_RATE_V1_VHT_NSS3_MCS9 = 0x249, + RTW89_HW_RATE_V1_VHT_NSS3_MCS10 = 0x24A, + RTW89_HW_RATE_V1_VHT_NSS3_MCS11 = 0x24B, + RTW89_HW_RATE_V1_VHT_NSS4_MCS0 = 0x260, + RTW89_HW_RATE_V1_VHT_NSS4_MCS1 = 0x261, + RTW89_HW_RATE_V1_VHT_NSS4_MCS2 = 0x262, + RTW89_HW_RATE_V1_VHT_NSS4_MCS3 = 0x263, + RTW89_HW_RATE_V1_VHT_NSS4_MCS4 = 0x264, + RTW89_HW_RATE_V1_VHT_NSS4_MCS5 = 0x265, + RTW89_HW_RATE_V1_VHT_NSS4_MCS6 = 0x266, + RTW89_HW_RATE_V1_VHT_NSS4_MCS7 = 0x267, + RTW89_HW_RATE_V1_VHT_NSS4_MCS8 = 0x268, + RTW89_HW_RATE_V1_VHT_NSS4_MCS9 = 0x269, + RTW89_HW_RATE_V1_VHT_NSS4_MCS10 = 0x26A, + RTW89_HW_RATE_V1_VHT_NSS4_MCS11 = 0x26B, + RTW89_HW_RATE_V1_HE_NSS1_MCS0 = 0x300, + RTW89_HW_RATE_V1_HE_NSS1_MCS1 = 0x301, + RTW89_HW_RATE_V1_HE_NSS1_MCS2 = 0x302, + RTW89_HW_RATE_V1_HE_NSS1_MCS3 = 0x303, + RTW89_HW_RATE_V1_HE_NSS1_MCS4 = 0x304, + RTW89_HW_RATE_V1_HE_NSS1_MCS5 = 0x305, + RTW89_HW_RATE_V1_HE_NSS1_MCS6 = 0x306, + RTW89_HW_RATE_V1_HE_NSS1_MCS7 = 0x307, + RTW89_HW_RATE_V1_HE_NSS1_MCS8 = 0x308, + RTW89_HW_RATE_V1_HE_NSS1_MCS9 = 0x309, + RTW89_HW_RATE_V1_HE_NSS1_MCS10 = 0x30A, + RTW89_HW_RATE_V1_HE_NSS1_MCS11 = 0x30B, + RTW89_HW_RATE_V1_HE_NSS2_MCS0 = 0x320, + RTW89_HW_RATE_V1_HE_NSS2_MCS1 = 0x321, + RTW89_HW_RATE_V1_HE_NSS2_MCS2 = 0x322, + RTW89_HW_RATE_V1_HE_NSS2_MCS3 = 0x323, + RTW89_HW_RATE_V1_HE_NSS2_MCS4 = 0x324, + RTW89_HW_RATE_V1_HE_NSS2_MCS5 = 0x325, + RTW89_HW_RATE_V1_HE_NSS2_MCS6 = 0x326, + RTW89_HW_RATE_V1_HE_NSS2_MCS7 = 0x327, + RTW89_HW_RATE_V1_HE_NSS2_MCS8 = 0x328, + RTW89_HW_RATE_V1_HE_NSS2_MCS9 = 0x329, + RTW89_HW_RATE_V1_HE_NSS2_MCS10 = 0x32A, + RTW89_HW_RATE_V1_HE_NSS2_MCS11 = 0x32B, + RTW89_HW_RATE_V1_HE_NSS3_MCS0 = 0x340, + RTW89_HW_RATE_V1_HE_NSS3_MCS1 = 0x341, + RTW89_HW_RATE_V1_HE_NSS3_MCS2 = 0x342, + RTW89_HW_RATE_V1_HE_NSS3_MCS3 = 0x343, + RTW89_HW_RATE_V1_HE_NSS3_MCS4 = 0x344, + RTW89_HW_RATE_V1_HE_NSS3_MCS5 = 0x345, + RTW89_HW_RATE_V1_HE_NSS3_MCS6 = 0x346, + RTW89_HW_RATE_V1_HE_NSS3_MCS7 = 0x347, + RTW89_HW_RATE_V1_HE_NSS3_MCS8 = 0x348, + RTW89_HW_RATE_V1_HE_NSS3_MCS9 = 0x349, + RTW89_HW_RATE_V1_HE_NSS3_MCS10 = 0x34A, + RTW89_HW_RATE_V1_HE_NSS3_MCS11 = 0x34B, + RTW89_HW_RATE_V1_HE_NSS4_MCS0 = 0x360, + RTW89_HW_RATE_V1_HE_NSS4_MCS1 = 0x361, + RTW89_HW_RATE_V1_HE_NSS4_MCS2 = 0x362, + RTW89_HW_RATE_V1_HE_NSS4_MCS3 = 0x363, + RTW89_HW_RATE_V1_HE_NSS4_MCS4 = 0x364, + RTW89_HW_RATE_V1_HE_NSS4_MCS5 = 0x365, + RTW89_HW_RATE_V1_HE_NSS4_MCS6 = 0x366, + RTW89_HW_RATE_V1_HE_NSS4_MCS7 = 0x367, + RTW89_HW_RATE_V1_HE_NSS4_MCS8 = 0x368, + RTW89_HW_RATE_V1_HE_NSS4_MCS9 = 0x369, + RTW89_HW_RATE_V1_HE_NSS4_MCS10 = 0x36A, + RTW89_HW_RATE_V1_HE_NSS4_MCS11 = 0x36B, + RTW89_HW_RATE_V1_EHT_NSS1_MCS0 = 0x400, + RTW89_HW_RATE_V1_EHT_NSS1_MCS1 = 0x401, + RTW89_HW_RATE_V1_EHT_NSS1_MCS2 = 0x402, + RTW89_HW_RATE_V1_EHT_NSS1_MCS3 = 0x403, + RTW89_HW_RATE_V1_EHT_NSS1_MCS4 = 0x404, + RTW89_HW_RATE_V1_EHT_NSS1_MCS5 = 0x405, + RTW89_HW_RATE_V1_EHT_NSS1_MCS6 = 0x406, + RTW89_HW_RATE_V1_EHT_NSS1_MCS7 = 0x407, + RTW89_HW_RATE_V1_EHT_NSS1_MCS8 = 0x408, + RTW89_HW_RATE_V1_EHT_NSS1_MCS9 = 0x409, + RTW89_HW_RATE_V1_EHT_NSS1_MCS10 = 0x40A, + RTW89_HW_RATE_V1_EHT_NSS1_MCS11 = 0x40B, + RTW89_HW_RATE_V1_EHT_NSS1_MCS12 = 0x40C, + RTW89_HW_RATE_V1_EHT_NSS1_MCS13 = 0x40D, + RTW89_HW_RATE_V1_EHT_NSS1_MCS14 = 0x40E, + RTW89_HW_RATE_V1_EHT_NSS1_MCS15 = 0x40F, + RTW89_HW_RATE_V1_EHT_NSS2_MCS0 = 0x420, + RTW89_HW_RATE_V1_EHT_NSS2_MCS1 = 0x421, + RTW89_HW_RATE_V1_EHT_NSS2_MCS2 = 0x422, + RTW89_HW_RATE_V1_EHT_NSS2_MCS3 = 0x423, + RTW89_HW_RATE_V1_EHT_NSS2_MCS4 = 0x424, + RTW89_HW_RATE_V1_EHT_NSS2_MCS5 = 0x425, + RTW89_HW_RATE_V1_EHT_NSS2_MCS6 = 0x426, + RTW89_HW_RATE_V1_EHT_NSS2_MCS7 = 0x427, + RTW89_HW_RATE_V1_EHT_NSS2_MCS8 = 0x428, + RTW89_HW_RATE_V1_EHT_NSS2_MCS9 = 0x429, + RTW89_HW_RATE_V1_EHT_NSS2_MCS10 = 0x42A, + RTW89_HW_RATE_V1_EHT_NSS2_MCS11 = 0x42B, + RTW89_HW_RATE_V1_EHT_NSS2_MCS12 = 0x42C, + RTW89_HW_RATE_V1_EHT_NSS2_MCS13 = 0x42D, + RTW89_HW_RATE_V1_EHT_NSS3_MCS0 = 0x440, + RTW89_HW_RATE_V1_EHT_NSS3_MCS1 = 0x441, + RTW89_HW_RATE_V1_EHT_NSS3_MCS2 = 0x442, + RTW89_HW_RATE_V1_EHT_NSS3_MCS3 = 0x443, + RTW89_HW_RATE_V1_EHT_NSS3_MCS4 = 0x444, + RTW89_HW_RATE_V1_EHT_NSS3_MCS5 = 0x445, + RTW89_HW_RATE_V1_EHT_NSS3_MCS6 = 0x446, + RTW89_HW_RATE_V1_EHT_NSS3_MCS7 = 0x447, + RTW89_HW_RATE_V1_EHT_NSS3_MCS8 = 0x448, + RTW89_HW_RATE_V1_EHT_NSS3_MCS9 = 0x449, + RTW89_HW_RATE_V1_EHT_NSS3_MCS10 = 0x44A, + RTW89_HW_RATE_V1_EHT_NSS3_MCS11 = 0x44B, + RTW89_HW_RATE_V1_EHT_NSS3_MCS12 = 0x44C, + RTW89_HW_RATE_V1_EHT_NSS3_MCS13 = 0x44D, + RTW89_HW_RATE_V1_EHT_NSS4_MCS0 = 0x460, + RTW89_HW_RATE_V1_EHT_NSS4_MCS1 = 0x461, + RTW89_HW_RATE_V1_EHT_NSS4_MCS2 = 0x462, + RTW89_HW_RATE_V1_EHT_NSS4_MCS3 = 0x463, + RTW89_HW_RATE_V1_EHT_NSS4_MCS4 = 0x464, + RTW89_HW_RATE_V1_EHT_NSS4_MCS5 = 0x465, + RTW89_HW_RATE_V1_EHT_NSS4_MCS6 = 0x466, + RTW89_HW_RATE_V1_EHT_NSS4_MCS7 = 0x467, + RTW89_HW_RATE_V1_EHT_NSS4_MCS8 = 0x468, + RTW89_HW_RATE_V1_EHT_NSS4_MCS9 = 0x469, + RTW89_HW_RATE_V1_EHT_NSS4_MCS10 = 0x46A, + RTW89_HW_RATE_V1_EHT_NSS4_MCS11 = 0x46B, + RTW89_HW_RATE_V1_EHT_NSS4_MCS12 = 0x46C, + RTW89_HW_RATE_V1_EHT_NSS4_MCS13 = 0x46D, + + RTW89_HW_RATE_NR, + RTW89_HW_RATE_INVAL, + + RTW89_HW_RATE_MASK_MOD = GENMASK(8, 7), + RTW89_HW_RATE_MASK_VAL = GENMASK(6, 0), + RTW89_HW_RATE_V1_MASK_MOD = GENMASK(10, 8), + RTW89_HW_RATE_V1_MASK_VAL = GENMASK(7, 0), +}; + +/* 2G channels, + * 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ +#define RTW89_2G_CH_NUM 14 + +/* 5G channels, + * 36, 38, 40, 42, 44, 46, 48, 50, + * 52, 54, 56, 58, 60, 62, 64, + * 100, 102, 104, 106, 108, 110, 112, 114, + * 116, 118, 120, 122, 124, 126, 128, 130, + * 132, 134, 136, 138, 140, 142, 144, + * 149, 151, 153, 155, 157, 159, 161, 163, + * 165, 167, 169, 171, 173, 175, 177 + */ +#define RTW89_5G_CH_NUM 53 + +/* 6G channels, + * 1, 3, 5, 7, 9, 11, 13, 15, + * 17, 19, 21, 23, 25, 27, 29, 33, + * 35, 37, 39, 41, 43, 45, 47, 49, + * 51, 53, 55, 57, 59, 61, 65, 67, + * 69, 71, 73, 75, 77, 79, 81, 83, + * 85, 87, 89, 91, 93, 97, 99, 101, + * 103, 105, 107, 109, 111, 113, 115, 117, + * 119, 121, 123, 125, 129, 131, 133, 135, + * 137, 139, 141, 143, 145, 147, 149, 151, + * 153, 155, 157, 161, 163, 165, 167, 169, + * 171, 173, 175, 177, 179, 181, 183, 185, + * 187, 189, 193, 195, 197, 199, 201, 203, + * 205, 207, 209, 211, 213, 215, 217, 219, + * 221, 225, 227, 229, 231, 233, 235, 237, + * 239, 241, 243, 245, 247, 249, 251, 253, + */ +#define RTW89_6G_CH_NUM 120 + +enum rtw89_rate_section { + RTW89_RS_CCK, + RTW89_RS_OFDM, + RTW89_RS_MCS, /* for HT/VHT/HE */ + RTW89_RS_HEDCM, + RTW89_RS_OFFSET, + RTW89_RS_NUM, + RTW89_RS_LMT_NUM = RTW89_RS_MCS + 1, + RTW89_RS_TX_SHAPE_NUM = RTW89_RS_OFDM + 1, +}; + +enum rtw89_rate_offset_indexes { + RTW89_RATE_OFFSET_HE, + RTW89_RATE_OFFSET_VHT, + RTW89_RATE_OFFSET_HT, + RTW89_RATE_OFFSET_OFDM, + RTW89_RATE_OFFSET_CCK, + RTW89_RATE_OFFSET_DLRU_EHT, + RTW89_RATE_OFFSET_DLRU_HE, + RTW89_RATE_OFFSET_EHT, + __RTW89_RATE_OFFSET_NUM, + + RTW89_RATE_OFFSET_NUM_AX = RTW89_RATE_OFFSET_CCK + 1, + RTW89_RATE_OFFSET_NUM_BE = RTW89_RATE_OFFSET_EHT + 1, +}; + +enum rtw89_rate_num { + RTW89_RATE_CCK_NUM = 4, + RTW89_RATE_OFDM_NUM = 8, + RTW89_RATE_HEDCM_NUM = 4, /* for HEDCM MCS0/1/3/4 */ + + RTW89_RATE_MCS_NUM_AX = 12, + RTW89_RATE_MCS_NUM_BE = 16, + __RTW89_RATE_MCS_NUM = 16, +}; + +enum rtw89_nss { + RTW89_NSS_1 = 0, + RTW89_NSS_2 = 1, + /* HE DCM only support 1ss and 2ss */ + RTW89_NSS_HEDCM_NUM = RTW89_NSS_2 + 1, + RTW89_NSS_3 = 2, + RTW89_NSS_4 = 3, + RTW89_NSS_NUM, +}; + +enum rtw89_ntx { + RTW89_1TX = 0, + RTW89_2TX = 1, + RTW89_NTX_NUM, +}; + +enum rtw89_beamforming_type { + RTW89_NONBF = 0, + RTW89_BF = 1, + RTW89_BF_NUM, +}; + +enum rtw89_ofdma_type { + RTW89_NON_OFDMA = 0, + RTW89_OFDMA = 1, + RTW89_OFDMA_NUM, +}; + +/* neither insert new in the middle, nor change any given definition */ +enum rtw89_regulation_type { + RTW89_WW = 0, + RTW89_ETSI = 1, + RTW89_FCC = 2, + RTW89_MKK = 3, + RTW89_NA = 4, + RTW89_IC = 5, + RTW89_KCC = 6, + RTW89_ACMA = 7, + RTW89_NCC = 8, + RTW89_MEXICO = 9, + RTW89_CHILE = 10, + RTW89_UKRAINE = 11, + RTW89_CN = 12, + RTW89_QATAR = 13, + RTW89_UK = 14, + RTW89_THAILAND = 15, + RTW89_REGD_NUM, +}; + +enum rtw89_reg_6ghz_power { + RTW89_REG_6GHZ_POWER_VLP = 0, + RTW89_REG_6GHZ_POWER_LPI = 1, + RTW89_REG_6GHZ_POWER_STD = 2, + + NUM_OF_RTW89_REG_6GHZ_POWER, + RTW89_REG_6GHZ_POWER_DFLT = RTW89_REG_6GHZ_POWER_VLP, +}; + +#define RTW89_MIN_VALID_POWER_CONSTRAINT (-10) /* unit: dBm */ + +/* calculate based on ieee80211 Transmit Power Envelope */ +struct rtw89_reg_6ghz_tpe { + bool valid; + s8 constraint; /* unit: dBm */ +}; + +enum rtw89_fw_pkt_ofld_type { + RTW89_PKT_OFLD_TYPE_PROBE_RSP = 0, + RTW89_PKT_OFLD_TYPE_PS_POLL = 1, + RTW89_PKT_OFLD_TYPE_NULL_DATA = 2, + RTW89_PKT_OFLD_TYPE_QOS_NULL = 3, + RTW89_PKT_OFLD_TYPE_CTS2SELF = 4, + RTW89_PKT_OFLD_TYPE_ARP_RSP = 5, + RTW89_PKT_OFLD_TYPE_NDP = 6, + RTW89_PKT_OFLD_TYPE_EAPOL_KEY = 7, + RTW89_PKT_OFLD_TYPE_SA_QUERY = 8, + RTW89_PKT_OFLD_TYPE_PROBE_REQ = 12, + RTW89_PKT_OFLD_TYPE_NUM, +}; + +struct rtw89_txpwr_byrate { + s8 cck[RTW89_RATE_CCK_NUM]; + s8 ofdm[RTW89_RATE_OFDM_NUM]; + s8 mcs[RTW89_OFDMA_NUM][RTW89_NSS_NUM][__RTW89_RATE_MCS_NUM]; + s8 hedcm[RTW89_OFDMA_NUM][RTW89_NSS_HEDCM_NUM][RTW89_RATE_HEDCM_NUM]; + s8 offset[__RTW89_RATE_OFFSET_NUM]; + s8 trap; +}; + +struct rtw89_rate_desc { + enum rtw89_nss nss; + enum rtw89_rate_section rs; + enum rtw89_ofdma_type ofdma; + u8 idx; +}; + +#define PHY_STS_HDR_LEN 8 +#define RF_PATH_MAX 4 +#define RTW89_MAX_PPDU_CNT 8 +struct rtw89_rx_phy_ppdu { + void *buf; + u32 len; + u8 rssi_avg; + u8 rssi[RF_PATH_MAX]; + u8 mac_id; + u8 chan_idx; + u8 phy_idx; + u8 ie; /* enum rtw89_phy_status_bitmap */ + u16 rate; + u8 rpl_avg; + u8 rpl_path[RF_PATH_MAX]; + u8 rpl_fd[RF_PATH_MAX]; + u8 bw_idx; + u8 rx_path_en; + struct { + bool has; + u8 avg_snr; + u8 evm_max; + u8 evm_min; + } ofdm; + bool has_data; + bool has_bcn; + bool su; + bool ldpc; + bool stbc; + bool bf; + bool to_self; + bool valid; + bool hdr_2_en; + const union rtw89_phy_sts_ie09 *ie09; /* SIG-A */ + const struct rtw89_phy_sts_ie10 *ie10; /* SIG-B */ +}; + +enum rtw89_mac_idx { + RTW89_MAC_0 = 0, + RTW89_MAC_1 = 1, + RTW89_MAC_NUM, +}; + +enum rtw89_phy_idx { + RTW89_PHY_0 = 0, + RTW89_PHY_1 = 1, + RTW89_PHY_NUM, +}; + +enum rtw89_fbtc_bt_index { + BTC_BT_1ST = 0x0, + BTC_BT_2ND = 0x1, + BTC_BT_EXT = 0x2, + BTC_ALL_BT = 0x2, + BTC_ALL_BT_EZL = 0x3 /* BT0+BT1+Ext-ZB(or Thread, or LTE) */ +}; + +#define __RTW89_MLD_MAX_LINK_NUM 2 +#define RTW89_MLD_NON_STA_LINK_NUM 1 + +enum rtw89_chanctx_idx { + RTW89_CHANCTX_0 = 0, + RTW89_CHANCTX_1 = 1, + + NUM_OF_RTW89_CHANCTX, + RTW89_CHANCTX_IDLE = NUM_OF_RTW89_CHANCTX, +}; + +enum rtw89_rf_path { + RF_PATH_A = 0, + RF_PATH_B = 1, + RF_PATH_C = 2, + RF_PATH_D = 3, + RF_PATH_AB, + RF_PATH_AC, + RF_PATH_AD, + RF_PATH_BC, + RF_PATH_BD, + RF_PATH_CD, + RF_PATH_ABC, + RF_PATH_ABD, + RF_PATH_ACD, + RF_PATH_BCD, + RF_PATH_ABCD, +}; + +enum rtw89_rf_path_bit { + RF_A = BIT(0), + RF_B = BIT(1), + RF_C = BIT(2), + RF_D = BIT(3), + + RF_AB = (RF_A | RF_B), + RF_AC = (RF_A | RF_C), + RF_AD = (RF_A | RF_D), + RF_BC = (RF_B | RF_C), + RF_BD = (RF_B | RF_D), + RF_CD = (RF_C | RF_D), + + RF_ABC = (RF_A | RF_B | RF_C), + RF_ABD = (RF_A | RF_B | RF_D), + RF_ACD = (RF_A | RF_C | RF_D), + RF_BCD = (RF_B | RF_C | RF_D), + + RF_ABCD = (RF_A | RF_B | RF_C | RF_D), +}; + +enum rtw89_bandwidth { + RTW89_CHANNEL_WIDTH_20 = 0, + RTW89_CHANNEL_WIDTH_40 = 1, + RTW89_CHANNEL_WIDTH_80 = 2, + RTW89_CHANNEL_WIDTH_160 = 3, + RTW89_CHANNEL_WIDTH_320 = 4, + + /* keep index order above */ + RTW89_CHANNEL_WIDTH_ORDINARY_NUM = 5, + + RTW89_CHANNEL_WIDTH_80_80 = 5, + RTW89_CHANNEL_WIDTH_5 = 6, + RTW89_CHANNEL_WIDTH_10 = 7, +}; + +enum rtw89_rx_ppdu_type { + RTW89_RX_PPDU_T_LCCK = 0, + RTW89_RX_PPDU_T_SCCK = 1, + RTW89_RX_PPDU_T_OFDM = 2, + RTW89_RX_PPDU_T_HT = 3, + RTW89_RX_PPDU_T_HTGF = 4, + RTW89_RX_PPDU_T_VHT_SU = 5, + RTW89_RX_PPDU_T_VHT_MU = 6, + RTW89_RX_PPDU_T_HE_SU = 7, + RTW89_RX_PPDU_T_HE_ERSU = 8, + RTW89_RX_PPDU_T_HE_MU = 9, + RTW89_RX_PPDU_T_HE_TB = 10, + RTW89_RX_PPDU_T_UNKNOWN = 15, +}; + +enum rtw89_ps_mode { + RTW89_PS_MODE_NONE = 0, + RTW89_PS_MODE_RFOFF = 1, + RTW89_PS_MODE_CLK_GATED = 2, + RTW89_PS_MODE_PWR_GATED = 3, +}; + +#define RTW89_2G_BW_NUM (RTW89_CHANNEL_WIDTH_40 + 1) +#define RTW89_5G_BW_NUM (RTW89_CHANNEL_WIDTH_160 + 1) +#define RTW89_6G_BW_NUM (RTW89_CHANNEL_WIDTH_320 + 1) +#define RTW89_BYR_BW_NUM (RTW89_CHANNEL_WIDTH_320 + 1) +#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_320 + 1) + +enum rtw89_pe_duration { + RTW89_PE_DURATION_0 = 0, + RTW89_PE_DURATION_8 = 1, + RTW89_PE_DURATION_16 = 2, + RTW89_PE_DURATION_16_20 = 3, +}; + +enum rtw89_ru_bandwidth { + RTW89_RU26 = 0, + RTW89_RU52 = 1, + RTW89_RU106 = 2, + RTW89_RU52_26 = 3, + RTW89_RU106_26 = 4, + RTW89_RU484_242 = 5, + RTW89_RU996_484 = 6, + RTW89_RU996_484_242 = 7, + RTW89_RU_NUM, +}; + +enum rtw89_sc_offset { + RTW89_SC_DONT_CARE = 0, + RTW89_SC_20_UPPER = 1, + RTW89_SC_20_LOWER = 2, + RTW89_SC_20_UPMOST = 3, + RTW89_SC_20_LOWEST = 4, + RTW89_SC_20_UP2X = 5, + RTW89_SC_20_LOW2X = 6, + RTW89_SC_20_UP3X = 7, + RTW89_SC_20_LOW3X = 8, + RTW89_SC_40_UPPER = 9, + RTW89_SC_40_LOWER = 10, +}; + +enum rtw89_rfsi_ctrl_band { + RFSI_CTRL_BAND_5_6GHZ, + RFSI_CTRL_BAND_2GHZ, + + RFSI_CTRL_BAND_NUM, +}; + +/* only mgd features can be added to the enum */ +enum rtw89_wow_flags { + RTW89_WOW_FLAG_EN_MAGIC_PKT, + RTW89_WOW_FLAG_EN_REKEY_PKT, + RTW89_WOW_FLAG_EN_DISCONNECT, + RTW89_WOW_FLAG_EN_PATTERN, + RTW89_WOW_FLAG_NUM, +}; + +struct rtw89_chan { + u8 channel; + u8 primary_channel; + enum rtw89_band band_type; + enum rtw89_bandwidth band_width; + + /* The follow-up are derived from the above. We must ensure that it + * is assigned correctly in rtw89_chan_create() if new one is added. + */ + u32 freq; + enum rtw89_subband subband_type; + enum rtw89_tx_comp_band tx_comp_band; + enum rtw89_sc_offset pri_ch_idx; + u8 pri_sb_idx; + enum rtw89_rfsi_ctrl_band rfsi_band; +}; + +struct rtw89_chan_rcd { + u8 prev_primary_channel; + enum rtw89_band prev_band_type; + bool band_changed; +}; + +struct rtw89_channel_help_params { + u32 tx_en; +}; + +struct rtw89_port_reg { + u32 port_cfg; + u32 tbtt_prohib; + u32 bcn_area; + u32 bcn_early; + u32 tbtt_early; + u32 tbtt_agg; + u32 bcn_space; + u32 bcn_forcetx; + u32 bcn_err_cnt; + u32 bcn_err_flag; + u32 dtim_ctrl; + u32 tbtt_shift; + u32 bcn_cnt_tmr; + u32 tsftr_l; + u32 tsftr_h; + u32 md_tsft; + u32 bss_color; + u32 mbssid; + u32 mbssid_drop; + u32 tsf_sync; + u32 ptcl_dbg; + u32 ptcl_dbg_info; + u32 bcn_drop_all; + u32 bcn_psr_rpt; + u32 hiq_win[RTW89_PORT_NUM]; +}; + +struct rtw89_txwd_body { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; +} __packed; + +struct rtw89_txwd_body_v1 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; +} __packed; + +struct rtw89_txwd_body_v2 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; +} __packed; + +struct rtw89_txwd_info { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; +} __packed; + +struct rtw89_txwd_info_v2 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; +} __packed; + +struct rtw89_rx_desc_info { + u16 pkt_size; + u8 pkt_type; + u8 drv_info_size; + u8 phy_rpt_size; + u8 hdr_cnv_size; + u8 shift; + u8 wl_hd_iv_len; + bool long_rxdesc; + bool bb_sel; + bool mac_info_valid; + u16 data_rate; + u8 gi_ltf; + u8 bw; + u32 free_run_cnt; + u8 user_id; + bool sr_en; + u8 ppdu_cnt; + u8 ppdu_type; + bool icv_err; + bool crc32_err; + bool hw_dec; + bool sw_dec; + bool addr1_match; + bool ampdu; + u8 frag; + u16 seq; + u8 frame_type; + u8 rx_pl_id; + bool addr_cam_valid; + u8 addr_cam_id; + u8 sec_cam_id; + u8 sec_type; + u8 mac_id; + u16 offset; + u16 rxd_len; + bool ready; + u16 rssi; +}; + +struct rtw89_rxdesc_short { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; +} __packed; + +struct rtw89_rxdesc_short_v2 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; +} __packed; + +struct rtw89_rxdesc_short_v3 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; +} __packed; + +struct rtw89_rxdesc_long { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; +} __packed; + +struct rtw89_rxdesc_long_v2 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; + __le32 dword8; + __le32 dword9; +} __packed; + +struct rtw89_rxdesc_long_v3 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; + __le32 dword8; + __le32 dword9; +} __packed; + +struct rtw89_rxdesc_phy_rpt_v2 { + __le32 dword0; + __le32 dword1; +} __packed; + +struct rtw89_tx_desc_info { + u16 pkt_size; + u8 wp_offset; + u8 mac_id; + u8 qsel; + u8 ch_dma; + u8 hdr_llc_len; + bool is_bmc; + bool en_wd_info; + bool wd_page; + bool use_rate; + bool dis_data_fb; + bool tid_indicate; + bool agg_en; + bool bk; + u8 ampdu_density; + u8 ampdu_num; + bool sec_en; + bool report; + bool tx_cnt_lmt_en; + u8 sn: 4; + u8 tx_cnt_lmt: 6; + u8 addr_info_nr; + u8 sec_keyid; + u8 sec_type; + u8 sec_cam_idx; + u8 sec_seq[6]; + u16 data_rate; + u16 data_retry_lowest_rate; + u8 data_bw; + u8 gi_ltf; + bool fw_dl; + u16 seq; + bool a_ctrl_bsr; + u8 hw_ssn_sel; +#define RTW89_MGMT_HW_SSN_SEL 1 + u8 hw_seq_mode; +#define RTW89_MGMT_HW_SEQ_MODE 1 + bool hiq; + u8 port; + bool er_cap; + bool stbc; + bool ldpc; + bool upd_wlan_hdr; + bool mlo; + bool sw_mld; +}; + +struct rtw89_core_tx_request { + enum rtw89_core_tx_type tx_type; + + struct sk_buff *skb; + struct ieee80211_vif *vif; + struct ieee80211_sta *sta; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + struct rtw89_tx_desc_info desc_info; + + bool with_wait; +}; + +struct rtw89_txq { + struct list_head list; + unsigned long flags; + int wait_cnt; +}; + +struct rtw89_mac_ax_gnt { + u8 gnt_bt_sw_en; + u8 gnt_bt; + u8 gnt_wl_sw_en; + u8 gnt_wl; +} __packed; + +struct rtw89_btc_gnt_ctrl { + u8 gnt_zb_sw_en; + u8 gnt_zb; + u8 gnt_bt1_sw_en; + u8 gnt_bt1; + u8 gnt_bt0_sw_en; + u8 gnt_bt0; + u8 gnt_wl_sw_en; + u8 gnt_wl; +} __packed; + +struct rtw89_mac_ax_wl_act { + u8 wlan_act_en; + u8 wlan_act; +} __packed; + +#define RTW89_MAC_AX_COEX_GNT_NR 2 +struct rtw89_mac_ax_coex_gnt { + struct rtw89_mac_ax_gnt band[RTW89_MAC_AX_COEX_GNT_NR]; + struct rtw89_mac_ax_wl_act bt[RTW89_MAC_AX_COEX_GNT_NR]; +}; + +enum rtw89_btc_ncnt { + BTC_NCNT_POWER_ON = 0x0, + BTC_NCNT_POWER_OFF, + BTC_NCNT_INIT_COEX, + BTC_NCNT_SCAN_START, + BTC_NCNT_SCAN_FINISH, + BTC_NCNT_SPECIAL_PACKET, + BTC_NCNT_SWITCH_BAND, + BTC_NCNT_RFK_TIMEOUT, + BTC_NCNT_SHOW_COEX_INFO, + BTC_NCNT_ROLE_INFO, + BTC_NCNT_CONTROL, + BTC_NCNT_RADIO_STATE, + BTC_NCNT_CUSTOMERIZE, + BTC_NCNT_WL_RFK, + BTC_NCNT_WL_STA, + BTC_NCNT_WL_STA_LAST, + BTC_NCNT_FWINFO, + BTC_NCNT_TIMER, + BTC_NCNT_SWITCH_CHBW, + BTC_NCNT_RESUME_DL_FW, + BTC_NCNT_COUNTRYCODE, + BTC_NCNT_NUM, +}; + +enum rtw89_btc_btinfo { + BTC_BTINFO_L0 = 0, + BTC_BTINFO_L1, + BTC_BTINFO_L2, + BTC_BTINFO_L3, + BTC_BTINFO_H0, + BTC_BTINFO_H1, + BTC_BTINFO_H2, + BTC_BTINFO_H3, + BTC_BTINFO_MAX +}; + +#define BTC_BTINFO_BISTDMA 0x48 /* cmd value that identifies BISTDMA data */ + +enum rtw89_btc_dcnt { + BTC_DCNT_RUN = 0x0, + BTC_DCNT_CX_RUNINFO, + BTC_DCNT_RPT, + BTC_DCNT_RPT_HANG, + BTC_DCNT_CYCLE, + BTC_DCNT_CYCLE_HANG, + BTC_DCNT_W1, + BTC_DCNT_W1_HANG, + BTC_DCNT_B1, + BTC_DCNT_B1_HANG, + BTC_DCNT_TDMA_NONSYNC, + BTC_DCNT_SLOT_NONSYNC, + BTC_DCNT_BTCNT_HANG, + BTC_DCNT_BTTX_HANG, + BTC_DCNT_WL_SLOT_DRIFT, + BTC_DCNT_WL_STA_LAST, + BTC_DCNT_BT_SLOT_DRIFT, + BTC_DCNT_BT_SLOT_FLOOD, + BTC_DCNT_FDDT_TRIG, + BTC_DCNT_E2G, + BTC_DCNT_E2G_HANG, + BTC_DCNT_WL_FW_VER_MATCH, + BTC_DCNT_NULL_TX_FAIL, + BTC_DCNT_WL_STA_NTFY, + BTC_DCNT_W2B_SCBD_NOSYNC, + BTC_DCNT_NUM, +}; + +enum rtw89_btc_wl_state_cnt { + BTC_WCNT_SCANAP = 0x0, + BTC_WCNT_DHCP, + BTC_WCNT_EAPOL, + BTC_WCNT_ARP, + BTC_WCNT_SCBDUPDATE, + BTC_WCNT_RFK_REQ, + BTC_WCNT_RFK_GO, + BTC_WCNT_RFK_REJECT, + BTC_WCNT_RFK_TIMEOUT, + BTC_WCNT_CH_UPDATE, + BTC_WCNT_DBCC_ALL_2G, + BTC_WCNT_DBCC_CHG, + BTC_WCNT_RX_OK_LAST, + BTC_WCNT_RX_OK_LAST2S, + BTC_WCNT_RX_ERR_LAST, + BTC_WCNT_RX_ERR_LAST2S, + BTC_WCNT_RX_LAST, + BTC_WCNT_SCBDUPDATE2, + BTC_WCNT_NUM +}; + +enum rtw89_btc_bt_state_cnt { + BTC_BCNT_RETRY = 0x0, + BTC_BCNT_REINIT, + BTC_BCNT_REENABLE, + BTC_BCNT_SCBDREAD, + BTC_BCNT_RELINK, + BTC_BCNT_IGNOWL, + BTC_BCNT_INQPAG, + BTC_BCNT_INQ, + BTC_BCNT_PAGE, + BTC_BCNT_ROLESW, + BTC_BCNT_AFH, + BTC_BCNT_INFOUPDATE, + BTC_BCNT_LEAUDIO_INFOUPDATE, + BTC_BCNT_INFOSAME, + BTC_BCNT_LEAUDIO_INFOSAME, + BTC_BCNT_SCBDUPDATE, + BTC_BCNT_HIPRI_TX, + BTC_BCNT_HIPRI_RX, + BTC_BCNT_LOPRI_TX, + BTC_BCNT_LOPRI_RX, + BTC_BCNT_POLUT_NOW, + BTC_BCNT_POLUT_DIFF, + BTC_BCNT_RATECHG, + BTC_BCNT_AFH_CONFLICT, + BTC_BCNT_AFH_LE_CONFLICT, + BTC_BCNT_AFH_UPDATE, + BTC_BCNT_AFH_LE_UPDATE, + BTC_BCNT_AFH_CHN, + BTC_BCNT_AFH_LE_CHN, + BTC_BCNT_TXPWR_UPDATE, + BTC_BCNT_PROTECT, + BTC_BCNT_NUM, +}; + +enum rtw89_btc_bt_mech_type { + BTC_MECH_TDD = 0, + BTC_MECH_FDD = 1, +}; + +enum rtw89_btc_bt_rf_band { + BTC_BT_B2G = 0x0, /* 2.4GHz */ + BTC_BT_B5G = 0x1, /* 5GHz or 6GHz */ + BTC_BT_BMAX = 0x2 +}; + +enum rtw89_btc_io_offload_type { + BTC_IO_OFLD_NO_SUPPORT = 0, + BTC_IO_OFLD_MAC_API = 1, + BTC_IO_OFLD_BTC_H2C = 2 +}; + +enum rtw89_btc_bt_profile { + BTC_BT_NOPROFILE = 0, + BTC_BT_HFP = BIT(0), + BTC_BT_HID = BIT(1), + BTC_BT_A2DP = BIT(2), + BTC_BT_PAN = BIT(3), + BTC_BT_BIS = BIT(4), + BTC_BT_CIS = BIT(5), + BTC_BT_THREAD = BIT(6), + BTC_BT_ULL = BIT(7), + BTC_BT_LEGACY = 0xf, + BTC_BT_FULL = 0x3f, + BTC_PROFILE_MAX = 4, +}; + +struct rtw89_btc_ant_info_v0 { + u8 type; /* shared, dedicated */ + u8 num; + u8 isolation; + + u8 single_pos: 1;/* Single antenna at S0 or S1 */ + u8 diversity: 1; + u8 btg_pos: 2; + u8 stream_cnt: 4; +}; + +struct rtw89_btc_ant_info_v7 { + u8 type; /* shared, dedicated(non-shared) */ + u8 num; /* antenna count */ + u8 isolation; + u8 single_pos;/* wifi 1ss-1ant at 0:S0 or 1:S1 */ + + u8 diversity; /* only for wifi use 1-antenna */ + u8 btg_pos; /* btg-circuit at 0:S0/1:S1/others:all */ + u8 stream_cnt; /* spatial_stream count */ + u8 rsvd; +} __packed; + +struct rtw89_btc_ant_info_v10 { + u8 type; /* shared, dedicated(non-shared) */ + u8 num; /* antenna count */ + u8 isolation; /* Ant-Iso between WL/BT */ + u8 single_pos; /* wifi 1ss-1ant at 0:S0 or 1:S1 */ + + u8 stream_cnt; /* spatial_stream count: Tx[7:4], Rx[3:0] */ + u8 btg_pos; /* BT0 btg-circuit at 0:WL-S0/1:WL-S1 */ + u8 btg1_pos; /* BT1 btg-circuit at 0:WL-S0/1:WL-S1 */ + u8 func[5]; /* function at 1~5 Ant refer to enum btc_bt_func_type */ + u8 ant_xmap[2][4]; +} __packed; + +struct rtw89_btc_ant_info_v11 { + u8 type; + u8 num; + u8 isolation; + u8 single_pos; + + u8 stream_cnt; + u8 path_pos; /* WL path position: Tx[7:4], Rx[3:0] */ + u8 btg_pos; + u8 btg1_pos; + u8 func[5]; + u8 ant_xmap[2][4]; + u8 rsvd0[3]; +} __packed; + +struct rtw89_btc_ant_info { + u8 type; /* shared, dedicated(non-shared) */ + u8 num; /* antenna count */ + u8 isolation; /* Ant-Iso between WL/BT */ + u8 single_pos; /* wifi 1ss-1ant at 0:S0 or 1:S1 */ + + u8 stream_cnt; /* spatial_stream count: Tx[7:4], Rx[3:0] */ + u8 btg_pos; /* BT0 btg-circuit at 0:WL-S0/1:WL-S1 */ + u8 btg1_pos; /* BT1 btg-circuit at 0:WL-S0/1:WL-S1 */ + u8 path_pos; /* WL path position: Tx[7:4], Rx[3:0] */ + u8 func[5]; /* function at 1~5 Ant refer to enum btc_bt_func_type */ + u8 ant_xmap[2][4]; + + u8 diversity; /* only for wifi use 1-antenna */ +}; + +enum rtw89_tfc_dir { + RTW89_TFC_UL, + RTW89_TFC_DL, +}; + +struct rtw89_btc_wl_smap { + u32 busy: 1; + u32 scan: 1; + u32 dhcp: 1; + u32 roaming: 1; + u32 transacting: 1; + u32 _4way: 1; + u32 handshake: 1; + u32 rf_off: 1; + u32 rf_off_pre: 1; + u32 ips: 1; + u32 lps: 2; + u32 lps_pre: 2; + u32 lps_exiting: 1; + u32 emlsr: 1; + u32 init_ok: 1; + u32 traffic_dir : 2; +}; + +enum rtw89_tfc_interval { + RTW89_TFC_INTERVAL_100MS, + RTW89_TFC_INTERVAL_2SEC, +}; + +enum rtw89_tfc_lv { + RTW89_TFC_IDLE, + RTW89_TFC_ULTRA_LOW, + RTW89_TFC_LOW, + RTW89_TFC_MID, + RTW89_TFC_HIGH, +}; + +DECLARE_EWMA(tp, 10, 2); + +#define RTW89_TCP_TH 40 +#define RTW89_UDP_RATIO_TH 70 +#define RTW89_RECENT_ACTIVE_HIST GENMASK(4, 0) + +struct rtw89_traffic_stats { + /* units in bytes */ + u64 tx_unicast; + u64 rx_unicast; + u32 tx_avg_len; + u32 rx_avg_len; + + /* count for packets */ + u64 tx_cnt; + u64 rx_cnt; + + /* units in Mbps */ + u32 tx_throughput; + u32 rx_throughput; + u32 tx_throughput_raw; + u32 rx_throughput_raw; + + u32 rx_tf_acc; + u32 rx_tf_periodic; + + enum rtw89_tfc_lv tx_tfc_lv; + enum rtw89_tfc_lv rx_tfc_lv; + struct ewma_tp tx_ewma_tp; + struct ewma_tp rx_ewma_tp; + + u16 tx_rate; + u16 rx_rate; + + /* used by rtwvif only */ + u64 tcp, udp, udp_ratio; + u8 active_histogram; +}; + +struct rtw89_btc_chdef { + u8 center_ch; + u8 band; + u8 chan; + enum rtw89_sc_offset offset; + enum rtw89_bandwidth bw; +}; + +struct rtw89_btc_statistic { + u8 rssi; /* 0%~110% (dBm = rssi -110) */ + struct rtw89_traffic_stats traffic; +}; + +#define BTC_WL_RSSI_THMAX 4 + +struct rtw89_btc_wl_link_info { + struct rtw89_btc_chdef chdef; + struct rtw89_btc_statistic stat; + enum rtw89_tfc_dir dir; + u8 rssi_state[BTC_WL_RSSI_THMAX]; + u8 mac_addr[ETH_ALEN]; + u8 busy; + u8 ch; + u8 bw; + u8 band; + u8 role; + u8 pid; + u8 phy; + u8 dtim_period; + u8 mode; + u8 tx_1ss_limit; + + u8 mac_id; + u8 tx_retry; + + u32 bcn_period; + u32 busy_t; + u32 tx_time; + u32 client_cnt; + u32 rx_rate_drop_cnt; + u32 noa_duration; + + u32 active: 1; + u32 noa: 1; + u32 client_ps: 1; + u32 connected: 2; +}; + +union rtw89_btc_wl_state_map { + u32 val; + struct rtw89_btc_wl_smap map; +}; + +struct rtw89_btc_bt_hfp_desc { + u32 exist: 1; + u32 type: 2; + u32 rsvd: 29; +}; + +struct rtw89_btc_bt_hid_desc { + u32 exist: 1; + u32 slot_info: 2; + u32 pair_cnt: 2; + u32 type: 8; + u32 rsvd: 19; +}; + +struct rtw89_btc_bt_a2dp_desc { + u8 exist: 1; + u8 exist_last: 1; + u8 play_latency: 1; + u8 type: 3; + u8 active: 1; + u8 sink: 1; + u32 handle_update: 1; + u32 devinfo_query: 1; + u32 no_empty_streak_2s: 8; + u32 no_empty_streak_max: 8; + u32 rsvd: 6; + + u8 bitpool; + u16 vendor_id; + u32 device_name; + u32 flush_time; +}; + +struct rtw89_btc_bt_pan_desc { + u32 exist: 1; + u32 type: 1; + u32 active: 1; + u32 rsvd: 29; +}; + +struct rtw89_btc_bt_rfk_info { + u32 run: 1; + u32 req: 1; + u32 timeout: 1; + u32 rsvd: 29; +}; + +union rtw89_btc_bt_rfk_info_map { + u32 val; + struct rtw89_btc_bt_rfk_info map; +}; + +struct rtw89_btc_bt_ver_info { + u32 fw_coex; /* match with which coex_ver */ + u32 fw; +}; + +struct rtw89_btc_bool_sta_chg { + u8 now: 1; + u8 last: 1; + u8 remain: 1; + u8 srvd: 5; +}; + +struct rtw89_btc_u8_sta_chg { + u8 now; + u8 last; + u8 chg; + u8 rsvd; +}; + +struct rtw89_btc_wl_scan_info { + u8 band[RTW89_PHY_NUM]; + u8 phy_map; + u8 hw_band_map; + u8 type; + u8 fw_scan; +}; + +struct rtw89_btc_wl_dbcc_info { + u8 op_band[RTW89_PHY_NUM]; /* op band in each phy */ + u8 scan_band[RTW89_PHY_NUM]; /* scan band in each phy */ + u8 real_band[RTW89_PHY_NUM]; + u8 role[RTW89_PHY_NUM]; /* role in each phy */ +}; + +struct rtw89_btc_wl_mlo_info_v2 { + u8 wmode[RTW89_PHY_NUM]; + u8 ch_type[RTW89_PHY_NUM]; + u8 hwb_rf_band[RTW89_PHY_NUM]; + u8 path_rf_band[RTW89_PHY_NUM]; + + u8 wtype; + u8 mrcx_mode; + u8 mrcx_act_hwb_map; + u8 mrcx_bt_slot_rsp; + + u8 rf_combination; + u8 mlo_en; + u8 mlo_adie; + u8 dual_hw_band_en; + + __le32 link_status; +} __packed; + +struct rtw89_btc_wl_mlo_info { + u8 wmode[RTW89_PHY_NUM]; /* enum phl_mr_wmode */ + u8 ch_type[RTW89_PHY_NUM]; /* enum phl_mr_ch_type */ + u8 hwb_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for HW-band */ + u8 path_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for PHY0/1 */ + + u8 wtype; /* enum phl_mr_wtype */ + u8 mrcx_mode; + u8 mrcx_act_hwb_map; + u8 mrcx_bt_slot_rsp; + + u8 rf_combination; /* enum btc_mlo_rf_combin 0:2+0, 1:0+2, 2:1+1,3:2+2 */ + u8 mlo_en; /* MLO enable */ + u8 mlo_adie; /* a-die count */ + u8 dual_hw_band_en; /* both 2 HW-band link exist */ + + u32 link_status; /* enum mlo_dbcc_mode_type */ +}; + +struct rtw89_btc_wl_active_role { + u8 connected: 1; + u8 pid: 3; + u8 phy: 1; + u8 noa: 1; + u8 band: 2; + + u8 client_ps: 1; + u8 bw: 7; + + u8 role; + u8 ch; + + u16 tx_lvl; + u16 rx_lvl; + u16 tx_rate; + u16 rx_rate; +}; + +struct rtw89_btc_wl_active_role_v1 { + u8 connected: 1; + u8 pid: 3; + u8 phy: 1; + u8 noa: 1; + u8 band: 2; + + u8 client_ps: 1; + u8 bw: 7; + + u8 role; + u8 ch; + + u16 tx_lvl; + u16 rx_lvl; + u16 tx_rate; + u16 rx_rate; + + u32 noa_duration; /* ms */ +}; + +struct rtw89_btc_wl_active_role_v2 { + u8 connected: 1; + u8 pid: 3; + u8 phy: 1; + u8 noa: 1; + u8 band: 2; + + u8 client_ps: 1; + u8 bw: 7; + + u8 role; + u8 ch; + + u32 noa_duration; /* ms */ +}; + +struct rtw89_btc_wl_active_role_v7 { + u8 connected; + u8 pid; + u8 phy; + u8 noa; + + u8 band; + u8 client_ps; + u8 bw; + u8 role; + + u8 ch; + u8 noa_dur; + u8 client_cnt; + u8 rsvd2; +} __packed; + +struct rtw89_btc_wl_role_info_bpos { + u16 none: 1; + u16 station: 1; + u16 ap: 1; + u16 vap: 1; + u16 adhoc: 1; + u16 adhoc_master: 1; + u16 mesh: 1; + u16 moniter: 1; + u16 p2p_device: 1; + u16 p2p_gc: 1; + u16 p2p_go: 1; + u16 nan: 1; +}; + +struct rtw89_btc_eslot_ctrl { + u8 en; /* 1: toggle tx-flow-ctrl (null 0/1), tx-pause by Ext-slot */ + u8 nulltx_role1; + u8 nulltx_role2; + u8 nulltx_pre_time; /* null-tx time prior to EBT-start (from E2G-end) */ +}; + +union rtw89_btc_wl_role_info_map { + u16 val; + struct rtw89_btc_wl_role_info_bpos role; +}; + +struct rtw89_btc_wl_role_info_v0 { /* struct size must be n*4 bytes */ + u8 connect_cnt; + u8 link_mode; + union rtw89_btc_wl_role_info_map role_map; + struct rtw89_btc_wl_active_role active_role[RTW89_PORT_NUM]; +}; + +struct rtw89_btc_wl_role_info_v1 { /* struct size must be n*4 bytes */ + u8 connect_cnt; + u8 link_mode; + union rtw89_btc_wl_role_info_map role_map; + struct rtw89_btc_wl_active_role_v1 active_role_v1[RTW89_PORT_NUM]; + u32 mrole_type; /* btc_wl_mrole_type */ + u32 mrole_noa_duration; /* ms */ + + u32 dbcc_en: 1; + u32 dbcc_chg: 1; + u32 dbcc_2g_phy: 2; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ + u32 link_mode_chg: 1; + u32 rsvd: 27; +}; + +struct rtw89_btc_wl_role_info_v2 { /* struct size must be n*4 bytes */ + u8 connect_cnt; + u8 link_mode; + union rtw89_btc_wl_role_info_map role_map; + struct rtw89_btc_wl_active_role_v2 active_role_v2[RTW89_PORT_NUM]; + u32 mrole_type; /* btc_wl_mrole_type */ + u32 mrole_noa_duration; /* ms */ + + u32 dbcc_en: 1; + u32 dbcc_chg: 1; + u32 dbcc_2g_phy: 2; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ + u32 link_mode_chg: 1; + u32 rsvd: 27; +}; + +struct rtw89_btc_wl_rlink_v0 { /* H2C info, struct size must be n*4 bytes */ + u8 connected; + u8 pid; + u8 phy; + u8 noa; + + u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */ + u8 active; /* 0:rlink is under doze */ + u8 bw; /* enum channel_width */ + u8 role; /*enum role_type */ + + u8 ch; + u8 noa_dur; /* ms */ + u8 client_cnt; /* for Role = P2P-Go/AP */ + u8 mode; /* wifi protocol */ +} __packed; + +struct rtw89_btc_wl_rlink_v10 { /* H2C info, struct size must be n*4 bytes */ + u8 connected; + u8 pid; + u8 phy; + u8 noa; + + u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */ + u8 active; /* 0:rlink is under doze */ + u8 bw; /* enum channel_width */ + u8 role; /*enum role_type */ + + u8 ch; + u8 noa_dur; /* ms */ + u8 client_cnt; /* for Role = P2P-Go/AP */ + u8 mode; /* wifi protocol */ + + u8 mac_id; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; +} __packed; + +#define RTW89_BE_BTC_WL_MAX_ROLE_NUMBER 6 +struct rtw89_btc_wl_role_info_v7 { /* struct size must be n*4 bytes */ + u8 connect_cnt; + u8 link_mode; + u8 link_mode_chg; + u8 p2p_2g; + + struct rtw89_btc_wl_active_role_v7 active_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER]; + + __le32 role_map; + __le32 mrole_type; /* btc_wl_mrole_type */ + __le32 mrole_noa_duration; /* ms */ + __le32 dbcc_en; + __le32 dbcc_chg; + __le32 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ +} __packed; + +struct rtw89_btc_wl_role_info_v8 { /* H2C info, struct size must be n*4 bytes */ + u8 connect_cnt; + u8 link_mode; + u8 link_mode_chg; + u8 p2p_2g; + + u8 pta_req_band; + u8 dbcc_en; /* 1+1 and 2.4G-included */ + u8 dbcc_chg; + u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ + + struct rtw89_btc_wl_rlink_v0 rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; + + __le32 role_map; + __le32 mrole_type; /* btc_wl_mrole_type */ + __le32 mrole_noa_duration; /* ms */ +} __packed; + +struct rtw89_btc_wl_role_info_v10 { /* H2C info, struct size must be n*4 bytes */ + struct rtw89_btc_wl_rlink_v10 rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; + u8 link_mode; + u8 link_mode_hb1; + u8 p2p_exist; + u8 p2p_exist_hb1; + + u8 pta_req_band; + u8 dbcc_en; /* 1+1 and 2.4G-included */ + u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ + u8 rsvd; + + __le32 role_map; + __le32 role_map_hb1; + __le32 mrole_type; /* btc_wl_mrole_type: [31:16]:band1, [15:0]:band0 */ +} __packed; + +struct rtw89_btc_wl_rlink { /* Logic dynamic using */ + u8 connected; + u8 pid; + u8 phy; + u8 noa; + + u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */ + u8 active; /* 0:rlink is under doze */ + u8 bw; /* enum channel_width */ + u8 role; /*enum role_type */ + + u8 ch; + u8 noa_dur; /* ms */ + u8 client_cnt; /* for Role = P2P-Go/AP */ + u8 mode; /* wifi protocol */ + + /*v0 v1*/ + u16 tx_lvl; + u16 rx_lvl; + u16 tx_rate; + u16 rx_rate; + + /* v7 */ + u8 client_ps; /*v7 v2 v1 v0*/ + + /* v10 */ + u8 mac_id; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; +}; + +struct rtw89_btc_wl_role_info { /* Logic dynamic using */ + struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; + u8 link_mode; + u8 link_mode_hb1; + u8 p2p_exist; + u8 p2p_exist_hb1; + + u8 pta_req_band; + u8 dbcc_en; /* 1+1 and 2.4G-included */ + u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ + u8 rsvd; + + u32 role_map; + u32 role_map_hb1; + u32 mrole_type; /* btc_wl_mrole_type: [31:16]:band1, [15:0]:band0 */ + + /* Before v10 use this linkmode */ + u8 link_mode_v0; + + /* v7 */ + u8 connect_cnt; + u32 dbcc_chg; /* v7 v2*/ + + /* v8 */ + u8 link_mode_chg; /* v8, v7 v2*/ + u8 p2p_2g; /* v8, v7 */ + u32 mrole_noa_duration; /* v8, v7 v2*/ +}; + +struct rtw89_btc_wl_ver_info { + char build_time[12]; + char build_date[12]; + u32 fw_coex; /* match with which coex_ver */ + u32 fw; + u32 mac; + u32 bb; + u32 rf; +}; + +struct rtw89_btc_wl_afh_info { + u8 en; + u8 ch; + u8 bw; + u8 band; +} __packed; + +struct rtw89_btc_wl_rfk_info { + u32 state: 2; + u32 path_map: 4; + u32 phy_map: 2; + u32 band: 2; + u32 type: 8; + u32 con_rfk: 1; + u32 rsvd: 13; + + u32 start_time; + u32 proc_time; +}; + +struct rtw89_btc_bt_smap { + u32 connect: 1; + u32 ble_connect: 1; + u32 acl_busy: 1; + u32 sco_busy: 1; + u32 mesh_busy: 1; + u32 inq_pag: 1; + u32 profile_map: 8; + u32 rsvd: 18; +}; + +union rtw89_btc_bt_state_map { + u32 val; + struct rtw89_btc_bt_smap map; +}; + +#define BTC_BT_RSSI_THMAX 4 +#define BTC_BT_AFH_GROUP 12 +#define BTC_BT_AFH_LE_GROUP 5 + +struct rtw89_btc_bt_txpwr_desc { + s8 br_dbm; + s8 le_dbm; + u8 br_gain_index; + u8 le_gain_index; +}; + +struct rtw89_btc_bt_leaudio_info { + u8 cmd; + u8 len; + u8 bis_cis; +#define RTW89_BTC_LEAU_INFO_L2_BIS_EX BIT(0) +#define RTW89_BTC_LEAU_INFO_L2_BIS_CNT GENMASK(3, 1) +#define RTW89_BTC_LEAU_INFO_L2_CIS_EX BIT(4) +#define RTW89_BTC_LEAU_INFO_L2_CIS_CNT GENMASK(7, 5) + u8 rssi; + __le32 hbrsvd; +} __packed; + +struct rtw89_btc_bt_bistdma_info_le { + u8 cmd; + u8 len; + u8 bis; /* BIT(2) ~ BIT(7) is rsvd */ +#define RTW89_BTC_BIS_INFO_L2_START_END BIT(0) /* 0: BIS start, 1: BIS end */ +#define RTW89_BTC_BIS_INFO_L2_TRX BIT(1) /* 0: BIS Tx, 1: BIS Rx */ + u8 diff_t_lb; + u8 diff_t_hb; /* diff_t = (diff_t_hb * 256 + diff_t_lb) * 0.625 ms */ + u8 hb1rsvd; + u8 hb2rsvd; + u8 hb3rsvd; +} __packed; + +struct rtw89_btc_bt_leaudio_desc { + u32 bis_exist: 1; + u32 bis_exist_last: 1; + u32 cis_exist: 1; + u32 cis_exist_last: 1; + u32 bis_cnt: 3; + u32 cis_cnt: 3; + u32 rssi: 8; + u32 bis_cnt_last: 3; + u32 cis_cnt_last: 3; + u32 bis_trx: 1; + u32 bis_start_end: 1; + u32 rsvd: 6; + + u16 diff_t; +}; + +struct rtw89_btc_bt_link_info { + struct rtw89_btc_u8_sta_chg link_cnt; + struct rtw89_btc_bool_sta_chg multi_link; + struct rtw89_btc_bool_sta_chg relink; + struct rtw89_btc_bt_hfp_desc hfp_desc; + struct rtw89_btc_bt_hid_desc hid_desc; + struct rtw89_btc_bt_a2dp_desc a2dp_desc; + struct rtw89_btc_bt_pan_desc pan_desc; + struct rtw89_btc_bt_leaudio_desc leaudio_desc; + union rtw89_btc_bt_state_map status; + struct rtw89_btc_bt_txpwr_desc bt_txpwr_desc; + + u8 sut_pwr_level[BTC_PROFILE_MAX]; + u8 golden_rx_shift[BTC_PROFILE_MAX]; + u8 rssi_state[BTC_BT_RSSI_THMAX]; + u8 afh_map[BTC_BT_AFH_GROUP]; + u8 afh_map_le[BTC_BT_AFH_LE_GROUP]; + u8 rssi; + + u8 role_sw: 1; + u8 slave_role: 1; + u8 afh_update: 1; + u8 cqddr: 1; + u8 tx_3m: 1; + u8 inq: 1; + u8 pag: 1; + u8 igno_wl: 1; + + u8 ble_scan_en: 1; + u8 reinit: 1; + u8 rsvd: 6; + + u8 leaudio_raw_info[BTC_BTINFO_MAX]; /* raw LE audio info from BT mailbox */ + u8 bistdma_raw_info[BTC_BTINFO_MAX]; /* raw BIS-TDMA info from BT mailbox */ +}; + +struct rtw89_btc_bind_bt_status { + u8 a2dp_active: 1; + u8 a2dp_sink: 1; + u8 pan_active: 1; + u8 connect: 1; + u8 inq_page: 1; + u8 multi_link: 1; + u8 slave_role: 1; + u8 page: 1; + + u8 hfp_exist: 1; + u8 hid_exist: 1; + u8 a2dp_exist: 1; + u8 pan_exist: 1; + u8 bis_exist: 1; + u8 cis_exist: 1; + u8 thread_exist: 1; + u8 ull_exist: 1; + + u8 hid_cnt; + u8 hid_type; + u8 cis_cnt; + u8 link_cnt; + + u16 a2dp_vendor_id; +}; + +struct rtw89_btc_bind_info { + u8 wl_hwb_sel; /* map */ + u8 wl_link_mode; + u8 wl_bg_mode; + u8 rf_band; /* map, 0: no any rf-band bind */ + u8 bt_sel; /* map */ + u8 bt_link_weight; /* select the highest weight between bt/rf-band */ + + u32 bt_profile; /* map */ + struct rtw89_btc_bind_bt_status bt_smap; +}; + +struct rtw89_btc_extsoc_info { + u8 chip_id; + u8 max_tx_pwr; + u8 rf_band_map; + u8 ant_iso_to_wl; + + u8 link_weight[BTC_BT_BMAX]; + + u8 func_type; /* 0: none, 1:zigbee, 2:LTE */ + u8 hw_coex; /* Hard-Wire coex interface support */ + u8 pta_type; /* 0: RTK 4-wire mode, 1: 3-wire mode */ + u8 pta_req_exist; + + u32 hpta_cfg; + u32 hmbx_cfg; + u32 swout_cfg; + u32 swin_cfg; + u32 profile_map[BTC_BT_BMAX]; + u32 bcnt[BTC_BCNT_NUM]; +}; + +struct rtw89_btc_dm_emap { + u32 init: 1; + u32 pta_owner: 1; + u32 wl_rfk_timeout: 1; + u32 bt_rfk_timeout: 1; + u32 wl_fw_hang: 1; + u32 cycle_hang: 1; + u32 w1_hang: 1; + u32 b1_hang: 1; + u32 tdma_no_sync: 1; + u32 slot_no_sync: 1; + u32 wl_slot_drift: 1; + u32 bt_slot_drift: 1; + u32 role_num_mismatch: 1; + u32 null1_tx_late: 1; + u32 bt_afh_conflict: 1; + u32 bt_leafh_conflict: 1; + u32 bt_slot_flood: 1; + u32 wl_e2g_hang: 1; + u32 wl_ver_mismatch: 1; + u32 bt_ver_mismatch: 1; + u32 rfe_type0: 1; + u32 h2c_buffer_over: 1; + u32 bt_tx_hang: 1; /* for SNR too low bug, BT has no Tx req*/ + u32 wl_no_sta_ntfy: 1; + u32 w2b_scbd_no_sync: 1; + + u32 h2c_bmap_mismatch: 1; + u32 c2h_bmap_mismatch: 1; + u32 h2c_struct_invalid: 1; + u32 c2h_struct_invalid: 1; + u32 h2c_c2h_buffer_mismatch: 1; +}; + +union rtw89_btc_dm_error_map { + u32 val; + struct rtw89_btc_dm_emap map; +}; + +struct rtw89_btc_rf_para { + u32 tx_pwr_freerun; + u32 rx_gain_freerun; + u32 tx_pwr_perpkt; + u32 rx_gain_perpkt; +}; + +struct rtw89_btc_wl_nhm { + u8 instant_wl_nhm_dbm; + u8 instant_wl_nhm_per_mhz; + u16 valid_record_times; + s8 record_pwr[16]; + u8 record_ratio[16]; + s8 pwr; /* dbm_per_MHz */ + u8 ratio; + u8 current_status; + u8 refresh; + bool start_flag; + s8 pwr_max; + s8 pwr_min; +}; + +struct rtw89_btc_wl_info { + struct rtw89_btc_wl_link_info rlink_info[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; + struct rtw89_btc_chdef rf_ch_info[RTW89_PHY_NUM]; + struct rtw89_btc_wl_rfk_info rfk_info; + struct rtw89_btc_wl_ver_info ver_info; + struct rtw89_btc_wl_afh_info afh_info[RTW89_MAC_NUM][RTW89_BAND_NUM]; + struct rtw89_btc_wl_afh_info afh_info_last[RTW89_MAC_NUM][RTW89_BAND_NUM]; + struct rtw89_btc_wl_role_info role_info; + struct rtw89_btc_wl_scan_info scan_info; + struct rtw89_btc_wl_dbcc_info dbcc_info; + struct rtw89_btc_wl_mlo_info mlo_info; + struct rtw89_btc_rf_para rf_para; + struct rtw89_btc_wl_nhm nhm; + union rtw89_btc_wl_state_map status; + + u8 port_id[RTW89_WIFI_ROLE_MLME_MAX]; + u8 rssi_level; + u8 cn_report; + u8 coex_mode; + u8 pta_req_mac; + u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */ + u8 rf_band_map[RTW89_PHY_NUM]; /* rf_band bit-map */ + u8 ch_map[12]; + u8 ch_map_le[5]; + + bool is_5g_hi_ch; + bool is_5g_hi_ch_hb1; + bool go_client_exist; + bool go_client_exist_hb1; + bool noa_exist; + bool noa_exist_hb1; + bool pta_reg_mac_chg; + bool bg_mode; + bool bg_mode_hb1; + bool he_mode; + bool scbd_chg[BTC_ALL_BT]; + bool fw_ver_mismatch; + bool client_cnt_inc_2g; + bool link_mode_chg; + bool dbcc_chg; + u32 scbd[BTC_ALL_BT]; + u32 scbd_rb[BTC_ALL_BT]; + u32 wcnt[BTC_WCNT_NUM]; +}; + +struct rtw89_btc_module_v0 { + struct rtw89_btc_ant_info_v0 ant; + u8 rfe_type; + u8 cv; + + u8 bt_solo: 1; + u8 bt_pos: 1; + u8 switch_type: 1; + u8 wa_type: 3; + + u8 kt_ver_adie; +}; + +struct rtw89_btc_module_v7 { + u8 rfe_type; + u8 kt_ver; + u8 bt_solo; + u8 bt_pos; /* wl-end view: get from efuse, must compare bt.btg_type*/ + + u8 switch_type; /* WL/BT switch type: 0: internal, 1: external */ + u8 wa_type; /* WA type: 0:none, 1: 51B 5G_Hi-Ch_Rx */ + u8 kt_ver_adie; + u8 rsvd; + + struct rtw89_btc_ant_info_v7 ant; +} __packed; + +struct rtw89_btc_module_v10 { + u8 rfe_type; + u8 wa_type; /* Refer to enum btc_wa_type */ + u8 kt_ver; + u8 kt_ver_adie; + + u8 bt0_pos; /* wl-end view: get from efuse, must compare bt.btg_type*/ + u8 bt0_sw_type; /* BT Ant-switch: None(non-share), Int(BTG), Ext(SPDT)*/ + u8 bt1_pos; /* BTC_BT_ALONE or BTC_BT_BTG */ + u8 bt1_sw_type; + + struct rtw89_btc_ant_info_v10 ant; +} __packed; + +struct rtw89_btc_module_v11 { + u8 rfe_type; + u8 wa_type; + u8 kt_ver; + u8 kt_ver_adie; + + u8 bt0_pos; + u8 bt0_sw_type; + u8 bt1_pos; + u8 bt1_sw_type; + + struct rtw89_btc_ant_info_v11 ant; +} __packed; + +union rtw89_btc_module_info { + struct rtw89_btc_module_v0 md_v0; + struct rtw89_btc_module_v7 md_v7; + struct rtw89_btc_module_v10 md_v10; + struct rtw89_btc_module_v11 md_v11; +}; + +struct rtw89_btc_module { + u8 rfe_type; + u8 wa_type; /* Refer to enum btc_wa_type */ + u8 kt_ver; + u8 kt_ver_adie; + + u8 bt0_pos; /* wl-end view: get from efuse, must compare bt.btg_type*/ + u8 bt0_sw_type; /* BT Ant-switch: None(non-share), Int(BTG), Ext(SPDT)*/ + u8 bt1_pos; /* BTC_BT_ALONE or BTC_BT_BTG */ + u8 bt1_sw_type; + + u8 bt_solo; + + struct rtw89_btc_ant_info ant; +}; + +#define RTW89_BTC_DM_MAXSTEP 30 +#define RTW89_BTC_DM_CNT_MAX (RTW89_BTC_DM_MAXSTEP * 8) + +struct rtw89_btc_dm_step { + u16 step[RTW89_BTC_DM_MAXSTEP]; + u8 step_pos; + bool step_ov; +}; + +struct rtw89_btc_init_info_v0 { + struct rtw89_btc_module_v0 module; + u8 wl_guard_ch; + + u8 wl_only: 1; + u8 wl_init_ok: 1; + u8 dbcc_en: 1; + u8 cx_other: 1; + u8 bt_only: 1; + + u16 rsvd; +} __packed; + +struct rtw89_btc_init_info_v7 { + u8 wl_guard_ch; + u8 wl_only; + u8 wl_init_ok; + u8 rsvd3; + + u8 cx_other; + u8 bt_only; + u8 pta_mode; + u8 pta_direction; + + struct rtw89_btc_module_v7 module; +} __packed; + +struct rtw89_btc_init_info_v107 { + u8 wl_guard_ch; + u8 wl_only; + u8 wl_init_ok; + u8 dbcc_en; + + u8 cx_other; + u8 bt_only; + u8 rsvd; + u8 rsvd1; + + struct rtw89_btc_module_v7 module; +} __packed; + +struct rtw89_btc_init_info_v10 { + u8 endian_type; /* 0: little-endian, 1:big-endian */ + u8 init_mode; /* refer to enum BTC_MODE_xxx */ + u8 wl_init_ok; + u8 bt0_function; + + u8 bt1_function; + u8 bt2_function; + u8 pta_mode; + u8 pta_direction; + + struct rtw89_btc_module_v10 module; +} __packed; + +struct rtw89_btc_init_info_v11 { + u8 endian_type; /* 0: little-endian, 1:big-endian */ + u8 init_mode; /* refer to enum BTC_MODE_xxx */ + u8 wl_init_ok; + u8 bt0_function; + + u8 bt1_function; + u8 bt2_function; + u8 pta_mode; + u8 pta_direction; + + struct rtw89_btc_module_v11 module; +}; + +union rtw89_btc_init_info_u { + struct rtw89_btc_init_info_v0 init_v0; + struct rtw89_btc_init_info_v7 init_v7; + struct rtw89_btc_init_info_v10 init_v10; + struct rtw89_btc_init_info_v107 init_v107; + struct rtw89_btc_init_info_v11 init_v11; +}; + +struct rtw89_btc_init_info { + u8 endian_type; /* 0: little-endian, 1:big-endian */ + u8 init_mode; /* refer to enum BTC_MODE_xxx */ + u8 wl_init_ok; + u8 bt0_function; + + u8 bt1_function; + u8 bt2_function; + u8 pta_mode; + u8 pta_direction; + + u8 dbcc_en; + u8 cx_other; + u8 bt_only; + u8 wl_only; + + u8 wl_guard_ch; + + struct rtw89_btc_module module; +}; + +struct rtw89_btc_wl_tx_limit_para { + u16 enable; + u32 tx_time; /* unit: us */ + u16 tx_retry; +}; + +struct rtw89_btc_wl_trx_nss_para { + u8 tx_limit; + u8 rx_limit; + u8 tx_ss; + u8 rx_ss; + u8 tx_path; + u8 rx_path; +}; + +enum rtw89_btc_bt_scan_type { + BTC_SCAN_INQ = 0, + BTC_SCAN_PAGE, + BTC_SCAN_BLE, + BTC_SCAN_INIT, + BTC_SCAN_TV, + BTC_SCAN_ADV, + BTC_SCAN_MAX1, +}; + +enum rtw89_btc_ble_scan_type { + CXSCAN_BG = 0, + CXSCAN_INIT, + CXSCAN_LE, + CXSCAN_MAX +}; + +enum rtw89_btc_bt_func_type { + BTC_BTF_NONE = 0, + BTC_BTF_BT = BIT(0), + BTC_BTF_ZB = BIT(1), + BTC_BTF_THREAD = BIT(2), + BTC_BTF_24GPRO = BIT(3), /* 2.4GHz Proprietary */ + BTC_BTF_ULL = BIT(4), +}; + +#define RTW89_BTC_BTC_SCAN_V1_FLAG_ENABLE BIT(0) +#define RTW89_BTC_BTC_SCAN_V1_FLAG_INTERLACE BIT(1) +#define RTW89_BTC_BT_DEF_BR_TX_PWR 4 +#define RTW89_BTC_BT_DEF_LE_TX_PWR 4 +#define RTW89_BTC_DEFAULT_ANISO 10 +#define RTW89_BTC_BT_DEF_LE_TX_PWR_1 10 + +struct rtw89_btc_bt_scan_info_v1 { + __le16 win; + __le16 intvl; + __le32 flags; +} __packed; + +struct rtw89_btc_bt_scan_info_v2 { + __le16 win; + __le16 intvl; +} __packed; + +struct rtw89_btc_fbtc_btscan_v1 { + u8 fver; /* btc_ver::fcxbtscan */ + u8 rsvd; + __le16 rsvd2; + struct rtw89_btc_bt_scan_info_v1 scan[BTC_SCAN_MAX1]; +} __packed; + +struct rtw89_btc_fbtc_btscan_v2 { + u8 fver; /* btc_ver::fcxbtscan */ + u8 type; + __le16 rsvd2; + struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX]; +} __packed; + +struct rtw89_btc_fbtc_btscan_v7 { + u8 fver; /* btc_ver::fcxbtscan */ + u8 type; + u8 rsvd0; + u8 rsvd1; + struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX]; +} __packed; + +struct rtw89_btc_fbtc_btscan_v8 { + u8 fver; /* btc_ver::fcxbtscan */ + u8 type; + u8 bt_id; /* 0:BT0, 1:BT1 */ + u8 rsvd1; + struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX]; +} __packed; + +union rtw89_btc_fbtc_btscan { + struct rtw89_btc_fbtc_btscan_v1 v1; + struct rtw89_btc_fbtc_btscan_v2 v2; + struct rtw89_btc_fbtc_btscan_v7 v7; + struct rtw89_btc_fbtc_btscan_v8 v8; +}; + +struct rtw89_btc_bt_info { + struct rtw89_btc_bt_link_info link_info; + struct rtw89_btc_bt_link_info link_info_56g; + struct rtw89_btc_bt_scan_info_v1 scan_info_v1[BTC_SCAN_MAX1]; + struct rtw89_btc_bt_scan_info_v2 scan_info_v2[CXSCAN_MAX]; + struct rtw89_btc_bt_ver_info ver_info; + struct rtw89_btc_bool_sta_chg enable; + struct rtw89_btc_bool_sta_chg inq_pag; + struct rtw89_btc_rf_para rf_para; + union rtw89_btc_bt_rfk_info_map rfk_info; + + u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox (2.4G) */ + u8 raw_info_56g[BTC_BTINFO_MAX]; /* raw bt info from mailbox (5/6G) */ + u8 txpwr_info[BTC_BTINFO_MAX]; + u8 link_weight[BTC_BT_BMAX]; /* Link Weight for RF-band/HWB selection */ + u8 rssi_level; + u8 rf_band_map; + u8 func_type; + u8 tx_power_now; + u8 tx_power_now_6g; + u8 ant_iso_to_wl; /* ant isolation between BTx and WL */ + + u8 fw_ver_mismatch: 1; + u8 band_56G_support: 1; + u8 hi_lna_rx: 1; + u8 lna_constrain: 3; + u8 hi_lna_rx_6g: 1; + u8 lna_constrain_6g: 3; + u8 rsvd: 6; + + u32 scbd; + u32 scbd_rb; + u32 scbd_c2h; + u32 feature; + + u32 mbx_avl: 1; + u32 whql_test: 1; + u32 igno_wl: 1; + u32 reinit: 1; + u32 ble_scan_en: 1; + u32 btg_type: 1; + u32 inq: 1; + u32 pag: 1; + u32 run_patch_code: 1; + u32 scan_rx_low_pri: 1; + u32 scan_info_update: 1; + u32 rsvd1: 22; + + u32 bcnt[BTC_BCNT_NUM]; +}; + +#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0) +struct rtw89_btc_rf_trx_para_v0 { + u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ + u32 wl_rx_gain; /* rx gain table index (TBD.) */ + u8 bt_tx_power; /* decrease Tx power (dB) */ + u8 bt_rx_gain; /* LNA constrain level */ +}; + +struct rtw89_btc_rf_trx_para_v9 { + u32 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 1's complement -5->0x85 */ + u32 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */ + u32 bt_tx_power[BTC_ALL_BT]; /* decrease Tx power (dB) */ + u32 bt_rx_gain[BTC_ALL_BT]; /* LNA constrain level */ + u32 zb_tx_power[BTC_ALL_BT]; /* 15.4 devrease Tx power (dB) */ + u32 zb_rx_gain[BTC_ALL_BT]; /* 15.4 constrain level */ +}; + +struct rtw89_btc_cx { + struct rtw89_btc_wl_info wl; + struct rtw89_btc_bt_info bt0; + struct rtw89_btc_bt_info bt1; + struct rtw89_btc_extsoc_info bt_ext; + struct rtw89_btc_rf_trx_para_v9 rf_para; + u32 state_map; +}; + +struct rtw89_btc_fbtc_tdma { + u8 type; /* btc_ver::fcxtdma */ + u8 rxflctrl; + u8 txflctrl; + u8 bind; + u8 leak_n; + u8 ext_ctrl; + u8 rxflctrl_role; + u8 option_ctrl; +} __packed; + +struct rtw89_btc_fbtc_tdma_v3 { + u8 fver; /* btc_ver::fcxtdma */ + u8 rsvd; + __le16 rsvd1; + struct rtw89_btc_fbtc_tdma tdma; +} __packed; + +union rtw89_btc_fbtc_tdma_le32 { + struct rtw89_btc_fbtc_tdma v1; + struct rtw89_btc_fbtc_tdma_v3 v3; +}; + +#define CXMREG_MAX 30 +#define CXMREG_MAX_V2 20 +#define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ +#define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ + +enum rtw89_btc_bt_sta_counter { + BTC_BCNT_RFK_REQ = 0, + BTC_BCNT_RFK_GO = 1, + BTC_BCNT_RFK_REJECT = 2, + BTC_BCNT_RFK_FAIL = 3, + BTC_BCNT_RFK_TIMEOUT = 4, + BTC_BCNT_HI_TX = 5, + BTC_BCNT_HI_RX = 6, + BTC_BCNT_LO_TX = 7, + BTC_BCNT_LO_RX = 8, + BTC_BCNT_POLLUTED = 9, + BTC_BCNT_STA_MAX +}; + +enum rtw89_btc_bt_sta_counter_v105 { + BTC_BCNT_RFK_REQ_V105 = 0, + BTC_BCNT_HI_TX_V105 = 1, + BTC_BCNT_HI_RX_V105 = 2, + BTC_BCNT_LO_TX_V105 = 3, + BTC_BCNT_LO_RX_V105 = 4, + BTC_BCNT_POLLUTED_V105 = 5, + BTC_BCNT_STA_MAX_V105 +}; + +struct rtw89_btc_fbtc_rpt_ctrl_v1 { + u16 fver; /* btc_ver::fcxbtcrpt */ + u16 rpt_cnt; /* tmr counters */ + u32 wl_fw_coex_ver; /* match which driver's coex version */ + u32 wl_fw_cx_offload; + u32 wl_fw_ver; + u32 rpt_enable; + u32 rpt_para; /* ms */ + u32 mb_send_fail_cnt; /* fw send mailbox fail counter */ + u32 mb_send_ok_cnt; /* fw send mailbox ok counter */ + u32 mb_recv_cnt; /* fw recv mailbox counter */ + u32 mb_a2dp_empty_cnt; /* a2dp empty count */ + u32 mb_a2dp_flct_cnt; /* a2dp empty flow control counter */ + u32 mb_a2dp_full_cnt; /* a2dp empty full counter */ + u32 bt_rfk_cnt[BTC_BCNT_HI_TX]; + u32 c2h_cnt; /* fw send c2h counter */ + u32 h2c_cnt; /* fw recv h2c counter */ +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_info { + __le32 cnt; /* fw report counter */ + __le32 en; /* report map */ + __le32 para; /* not used */ + + __le32 cnt_c2h; /* fw send c2h counter */ + __le32 cnt_h2c; /* fw recv h2c counter */ + __le32 len_c2h; /* The total length of the last C2H */ + + __le32 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */ + __le32 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */ +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_info_v5 { + __le32 cx_ver; /* match which driver's coex version */ + __le32 fw_ver; + __le32 en; /* report map */ + + __le16 cnt; /* fw report counter */ + __le16 cnt_c2h; /* fw send c2h counter */ + __le16 cnt_h2c; /* fw recv h2c counter */ + __le16 len_c2h; /* The total length of the last C2H */ + + __le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */ + __le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */ +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_info_v8 { + __le16 cnt; /* fw report counter */ + __le16 cnt_c2h; /* fw send c2h counter */ + __le16 cnt_h2c; /* fw recv h2c counter */ + __le16 len_c2h; /* The total length of the last C2H */ + + __le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */ + __le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */ + + __le32 cx_ver; /* match which driver's coex version */ + __le32 fw_ver; + __le32 en; /* report map */ +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info { + __le32 cx_ver; /* match which driver's coex version */ + __le32 cx_offload; + __le32 fw_ver; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_a2dp_empty { + __le32 cnt_empty; /* a2dp empty count */ + __le32 cnt_flowctrl; /* a2dp empty flow control counter */ + __le32 cnt_tx; + __le32 cnt_ack; + __le32 cnt_nack; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox { + __le32 cnt_send_ok; /* fw send mailbox ok counter */ + __le32 cnt_send_fail; /* fw send mailbox fail counter */ + __le32 cnt_recv; /* fw recv mailbox counter */ + struct rtw89_btc_fbtc_rpt_ctrl_a2dp_empty a2dp; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v4 { + u8 fver; + u8 rsvd; + __le16 rsvd1; + struct rtw89_btc_fbtc_rpt_ctrl_info rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info wl_fw_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; + __le32 bt_cnt[BTC_BCNT_STA_MAX]; + struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_NUM]; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v5 { + u8 fver; + u8 rsvd; + __le16 rsvd1; + + u8 gnt_val[RTW89_PHY_NUM][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v105 { + u8 fver; + u8 rsvd; + __le16 rsvd1; + + u8 gnt_val[RTW89_PHY_NUM][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v7 { + u8 fver; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + u8 gnt_val[RTW89_PHY_NUM][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v8 { + u8 fver; + u8 rsvd0; + u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */ + u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */ + + u8 gnt_val[RTW89_PHY_NUM][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + +#define RTW89_BTC_TIME_DATE_FMT 12 +struct rtw89_btc_fbtc_rpt_ctrl_v9 { + u8 fver; + u8 ext_req_exist; + u8 pta_owner; + u8 rsvd; + + u8 build_time[RTW89_BTC_TIME_DATE_FMT]; + u8 build_date[RTW89_BTC_TIME_DATE_FMT]; + + u8 gnt_val[RTW89_PHY_NUM][4]; /* gwl/gbt012 refer to struct btc_gnt_ctrl */ + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + +struct rtw89_btc_fbtc_rpt_ctrl_v11 { + u8 fver; + u8 rsvd0; + u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */ + u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */ + + u8 build_time[12]; + u8 build_date[12]; + + u8 gnt_val[RTW89_PHY_NUM][8]; /* gwl/gbt012 refer to struct btc_gnt_ctrl */ + __le16 bt_cnt[BTC_ALL_BT_EZL][BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; + + __le32 error_code; + __le32 scbd_w2b[2]; + __le32 scbd_b2w[2]; +} __packed; + +union rtw89_btc_fbtc_rpt_ctrl_ver_info { + struct rtw89_btc_fbtc_rpt_ctrl_v1 v1; + struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; + struct rtw89_btc_fbtc_rpt_ctrl_v5 v5; + struct rtw89_btc_fbtc_rpt_ctrl_v105 v105; + struct rtw89_btc_fbtc_rpt_ctrl_v7 v7; + struct rtw89_btc_fbtc_rpt_ctrl_v8 v8; + struct rtw89_btc_fbtc_rpt_ctrl_v9 v9; + struct rtw89_btc_fbtc_rpt_ctrl_v11 v11; +}; + +enum rtw89_fbtc_ext_ctrl_type { + CXECTL_OFF = 0x0, /* tdma off */ + CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ + CXECTL_EXT = 0x2, + CXECTL_MAX +}; + +union rtw89_btc_fbtc_rxflct { + u8 val; + u8 type: 3; + u8 tgln_n: 5; +}; + +enum rtw89_btc_cxst_state { + CXST_OFF = 0x0, + CXST_B2W = 0x1, + CXST_W1 = 0x2, + CXST_W2 = 0x3, + CXST_W2B = 0x4, + CXST_B1 = 0x5, + CXST_B2 = 0x6, + CXST_B3 = 0x7, + CXST_B4 = 0x8, + CXST_LK = 0x9, + CXST_BLK = 0xa, + CXST_E2G = 0xb, + CXST_E5G = 0xc, + CXST_EBT = 0xd, + CXST_ENULL = 0xe, + CXST_WLK = 0xf, + CXST_W1FDD = 0x10, + CXST_B1FDD = 0x11, + CXST_MAX = 0x12, +}; + +enum rtw89_btc_cxevnt { + CXEVNT_TDMA_ENTRY = 0x0, + CXEVNT_WL_TMR, + CXEVNT_B1_TMR, + CXEVNT_B2_TMR, + CXEVNT_B3_TMR, + CXEVNT_B4_TMR, + CXEVNT_W2B_TMR, + CXEVNT_B2W_TMR, + CXEVNT_BCN_EARLY, + CXEVNT_A2DP_EMPTY, + CXEVNT_LK_END, + CXEVNT_RX_ISR, + CXEVNT_RX_FC0, + CXEVNT_RX_FC1, + CXEVNT_BT_RELINK, + CXEVNT_BT_RETRY, + CXEVNT_E2G, + CXEVNT_E5G, + CXEVNT_EBT, + CXEVNT_ENULL, + CXEVNT_DRV_WLK, + CXEVNT_BCN_OK, + CXEVNT_BT_CHANGE, + CXEVNT_EBT_EXTEND, + CXEVNT_E2G_NULL1, + CXEVNT_B1FDD_TMR, + CXEVNT_MAX +}; + +enum { + CXBCN_ALL = 0x0, + CXBCN_ALL_OK, + CXBCN_BT_SLOT, + CXBCN_BT_OK, + CXBCN_MAX +}; + +enum btc_slot_type { + SLOT_MIX = 0x0, /* accept BT Lower-Pri Tx/Rx request 0x778 = 1 */ + SLOT_ISO = 0x1, /* no accept BT Lower-Pri Tx/Rx request 0x778 = d*/ + CXSTYPE_NUM, +}; + +enum { /* TIME */ + CXT_BT = 0x0, + CXT_WL = 0x1, + CXT_MAX +}; + +enum { /* TIME-A2DP */ + CXT_FLCTRL_OFF = 0x0, + CXT_FLCTRL_ON = 0x1, + CXT_FLCTRL_MAX +}; + +enum { /* STEP TYPE */ + CXSTEP_NONE = 0x0, + CXSTEP_EVNT = 0x1, + CXSTEP_SLOT = 0x2, + CXSTEP_MAX, +}; + +enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */ + RPT_BT_AFH_SEQ_LEGACY = 0x10, + RPT_BT_AFH_SEQ_LE = 0x20 +}; + +enum btc_wl_gpio_debug { + BTC_DBG_GNT_BT = 0, + BTC_DBG_GNT_WL = 1, + BTC_DBG_GNT_BT1 = 2, + BTC_DBG_GNT_WL1 = 3, + /* The following signals should 0-1 tiggle by each function-call */ + BTC_DBG_BCN_EARLY = 4, + BTC_DBG_WL_NULL0 = 5, + BTC_DBG_WL_NULL1 = 6, + BTC_DBG_WL_RXISR = 7, + BTC_DBG_TDMA_ENTRY = 8, + BTC_DBG_A2DP_EMPTY = 9, + BTC_DBG_BT_RETRY = 10, + /* The following signals should 0-1 tiggle by state L/H */ + BTC_DBG_BT_RELINK = 11, + BTC_DBG_SLOT_WL = 12, + BTC_DBG_SLOT_BT = 13, + /* The following signals should 0-1 tiggle by external*/ + BTC_DBG_WL_ERR = 14, + BTC_DBG_WL_OK = 15, + /* The following signals appear only 1-active at same time*/ + BTC_DBG_SLOT_B2W = 16, + BTC_DBG_SLOT_W1 = 17, + BTC_DBG_SLOT_W2 = 18, + BTC_DBG_SLOT_W2B = 19, + BTC_DBG_SLOT_B1 = 20, + BTC_DBG_SLOT_B2 = 21, + BTC_DBG_SLOT_B3 = 22, + BTC_DBG_SLOT_B4 = 23, + BTC_DBG_SLOT_LK = 24, + BTC_DBG_SLOT_E2G = 25, + BTC_DBG_SLOT_E5G = 26, + BTC_DBG_SLOT_EBT = 27, + BTC_DBG_SLOT_WLK = 28, + BTC_DBG_SLOT_B1FDD = 29, + BTC_DBG_BT_CHANGE = 30, + /* The following signals should 0-1 tiggle by external*/ + BTC_DBG_WL_CCA = 31, + + BTC_DBG_NUM, +}; + +struct rtw89_btc_fbtc_gpio_dbg_v1 { + u8 fver; /* btc_ver::fcxgpiodbg */ + u8 rsvd; + __le16 rsvd2; + __le32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ + __le32 pre_state; /* the debug signal is 1 or 0 */ + u8 gpio_map[BTC_DBG_NUM]; /*the debug signals to GPIO-Position */ +} __packed; + +struct rtw89_btc_fbtc_gpio_dbg_v7 { + u8 fver; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + u8 gpio_map[BTC_DBG_NUM]; + + __le32 en_map; + __le32 pre_state; +} __packed; + +union rtw89_btc_fbtc_gpio_dbg { + struct rtw89_btc_fbtc_gpio_dbg_v1 v1; + struct rtw89_btc_fbtc_gpio_dbg_v7 v7; +}; + +/* + * SET_GPIO_CTRL payload (max len = 7 bytes) + * + * type = CXDGPIO_EN_MAP + * data.val[31:0] = debug signal enable map + * + * type = CXDGPIO_MUX_MAP + * data.mux.sig = debug signal id + * data.mux.gpio = GPIO id + * + * type = CXDGPIO_EXT_HPTA / CXDGPIO_EXT_HMBX / CXDGPIO_EXT_SWOUT + * data.map.map_low = GPIO 7~0 map + * data.map.map_high = GPIO 15~8 map + * + * type = CXDGPIO_EXT_SWIN + * data.swin.in_map_low = GPIO 7~0 input-en-map + * data.swin.in_map_high = GPIO 15~8 input-en-map + * data.swin.int_map_low = GPIO 7~0 interrupt source map + * data.swin.int_map_high = GPIO 15~8 interrupt source map + */ +#define CXDGPIO_SET_L4 4 +#define CXDGPIO_SET_L2 2 +struct rtw89_fbtc_h2c_set_gpio_en_map { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u32 en_map; +}; + +struct rtw89_fbtc_h2c_set_gpio_mux { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 sig; + u8 gpio; +}; + +struct rtw89_fbtc_h2c_set_gpio_ext_pta { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 map_low; + u8 map_high; +}; + +struct rtw89_fbtc_h2c_set_gpio_ext_mb { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 map_low; + u8 map_high; +}; + +struct rtw89_fbtc_h2c_set_gpio_ext_swout { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 map_low; + u8 map_high; +}; + +struct rtw89_fbtc_h2c_set_gpio_ext_swin { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 in_map_low; + u8 in_map_high; + u8 int_map_low; + u8 int_map_high; +}; + +struct rtw89_fbtc_h2c_set_gpio_2b { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 data[CXDGPIO_SET_L2]; +} __packed; + +struct rtw89_fbtc_h2c_set_gpio_4b { + u8 type; /* gpio_type */ + u8 fver; /* FCX_VER_GPIODBG */ + u8 dlen; + u8 data[CXDGPIO_SET_L4]; +} __packed; + +union rtw89_fbtc_h2c_set_gpio_en_map_u { + struct rtw89_fbtc_h2c_set_gpio_4b fmt; + struct rtw89_fbtc_h2c_set_gpio_en_map data; +}; + +union rtw89_fbtc_h2c_set_gpio_mux_u { + struct rtw89_fbtc_h2c_set_gpio_2b fmt; + struct rtw89_fbtc_h2c_set_gpio_mux data; +}; + +union rtw89_fbtc_h2c_set_gpio_ext_pta_u { + struct rtw89_fbtc_h2c_set_gpio_2b fmt; + struct rtw89_fbtc_h2c_set_gpio_ext_pta data; +}; + +union rtw89_fbtc_h2c_set_gpio_ext_swin_u { + struct rtw89_fbtc_h2c_set_gpio_4b fmt; + struct rtw89_fbtc_h2c_set_gpio_ext_swin data; +}; + +struct rtw89_fbtc_h2c_set_gpio { + union rtw89_fbtc_h2c_set_gpio_en_map_u en_map; + union rtw89_fbtc_h2c_set_gpio_mux_u mux; + union rtw89_fbtc_h2c_set_gpio_ext_pta_u ext_pta; + union rtw89_fbtc_h2c_set_gpio_ext_pta_u ext_mb; + union rtw89_fbtc_h2c_set_gpio_ext_pta_u ext_swout; + union rtw89_fbtc_h2c_set_gpio_ext_swin_u ext_swin; +}; + +struct rtw89_btc_fbtc_mreg_val_v1 { + u8 fver; /* btc_ver::fcxmreg */ + u8 reg_num; + __le16 rsvd; + __le32 mreg_val[CXMREG_MAX]; +} __packed; + +struct rtw89_btc_fbtc_mreg_val_v2 { + u8 fver; /* btc_ver::fcxmreg */ + u8 reg_num; + __le16 rsvd; + __le32 mreg_val[CXMREG_MAX_V2]; +} __packed; + +struct rtw89_btc_fbtc_mreg_val_v7 { + u8 fver; + u8 reg_num; + u8 rsvd0; + u8 rsvd1; + __le32 mreg_val[CXMREG_MAX_V2]; +} __packed; + +union rtw89_btc_fbtc_mreg_val { + struct rtw89_btc_fbtc_mreg_val_v1 v1; + struct rtw89_btc_fbtc_mreg_val_v2 v2; + struct rtw89_btc_fbtc_mreg_val_v7 v7; +}; + +#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \ + { .type = cpu_to_le16(__type), .bytes = cpu_to_le16(__bytes), \ + .offset = cpu_to_le32(__offset), } + +struct rtw89_btc_fbtc_mreg { + __le16 type; + __le16 bytes; + __le32 offset; +} __packed; + +struct rtw89_btc_fbtc_slot { + __le16 dur; + __le32 cxtbl; + __le16 cxtype; +} __packed; + +struct rtw89_btc_fbtc_slots { + u8 fver; /* btc_ver::fcxslots */ + u8 tbl_num; + __le16 rsvd; + __le32 update_map; + struct rtw89_btc_fbtc_slot slot[CXST_MAX]; +} __packed; + +struct rtw89_btc_fbtc_slot_v7 { + __le16 dur; /* slot duration */ + __le16 cxtype; + __le32 cxtbl; +} __packed; + +struct rtw89_btc_fbtc_slots_v2 { + u8 fver; /* btc_ver::fcxslots */ + u8 tbl_num; + __le16 rsvd; + __le32 update_map; + struct rtw89_btc_fbtc_slot_v7 slot[CXST_MAX]; +} __packed; + +struct rtw89_btc_fbtc_slot_u16 { + __le16 dur; /* slot duration */ + __le16 cxtype; + __le16 cxtbl_l16; /* coex table [15:0] */ + __le16 cxtbl_h16; /* coex table [31:16] */ +} __packed; + +struct rtw89_btc_fbtc_1slot_v7 { + u8 fver; + u8 sid; /* slot id */ + __le16 rsvd; + struct rtw89_btc_fbtc_slot_v7 slot; +} __packed; + +struct rtw89_btc_fbtc_slots_v7 { + u8 fver; + u8 slot_cnt; + u8 rsvd0; + u8 rsvd1; + struct rtw89_btc_fbtc_slot_u16 slot[CXST_MAX]; + __le32 update_map; +} __packed; + +union rtw89_btc_fbtc_slots_info { + struct rtw89_btc_fbtc_slots v1; + struct rtw89_btc_fbtc_slots_v2 v2; + struct rtw89_btc_fbtc_slots_v7 v7; +} __packed; + +struct rtw89_btc_fbtc_step { + u8 type; + u8 val; + __le16 difft; +} __packed; + +struct rtw89_btc_fbtc_steps_v2 { + u8 fver; /* btc_ver::fcxstep */ + u8 rsvd; + __le16 cnt; + __le16 pos_old; + __le16 pos_new; + struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; +} __packed; + +struct rtw89_btc_fbtc_steps_v3 { + u8 fver; + u8 en; + __le16 rsvd; + __le32 cnt; + struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; +} __packed; + +union rtw89_btc_fbtc_steps_info { + struct rtw89_btc_fbtc_steps_v2 v2; + struct rtw89_btc_fbtc_steps_v3 v3; +}; + +struct rtw89_btc_fbtc_cysta_v2 { /* statistics for cycles */ + u8 fver; /* btc_ver::fcxcysta */ + u8 rsvd; + __le16 cycles; /* total cycle number */ + __le16 cycles_a2dp[CXT_FLCTRL_MAX]; + __le16 a2dpept; /* a2dp empty cnt */ + __le16 a2dpeptto; /* a2dp empty timeout cnt*/ + __le16 tavg_cycle[CXT_MAX]; /* avg wl/bt cycle time */ + __le16 tmax_cycle[CXT_MAX]; /* max wl/bt cycle time */ + __le16 tmaxdiff_cycle[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ + __le16 tavg_a2dp[CXT_FLCTRL_MAX]; /* avg a2dp PSTDMA/TDMA time */ + __le16 tmax_a2dp[CXT_FLCTRL_MAX]; /* max a2dp PSTDMA/TDMA time */ + __le16 tavg_a2dpept; /* avg a2dp empty time */ + __le16 tmax_a2dpept; /* max a2dp empty time */ + __le16 tavg_lk; /* avg leak-slot time */ + __le16 tmax_lk; /* max leak-slot time */ + __le32 slot_cnt[CXST_MAX]; /* slot count */ + __le32 bcn_cnt[CXBCN_MAX]; + __le32 leakrx_cnt; /* the rximr occur at leak slot */ + __le32 collision_cnt; /* counter for event/timer occur at same time */ + __le32 skip_cnt; + __le32 exception; + __le32 except_cnt; + __le16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; +} __packed; + +struct rtw89_btc_fbtc_fdd_try_info { + __le16 cycles[CXT_FLCTRL_MAX]; + __le16 tavg[CXT_FLCTRL_MAX]; /* avg try BT-Slot-TDD/BT-slot-FDD time */ + __le16 tmax[CXT_FLCTRL_MAX]; /* max try BT-Slot-TDD/BT-slot-FDD time */ +} __packed; + +struct rtw89_btc_fbtc_cycle_time_info { + __le16 tavg[CXT_MAX]; /* avg wl/bt cycle time */ + __le16 tmax[CXT_MAX]; /* max wl/bt cycle time */ + __le16 tmaxdiff[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ +} __packed; + +struct rtw89_btc_fbtc_cycle_time_info_v5 { + __le16 tavg[CXT_MAX]; /* avg wl/bt cycle time */ + __le16 tmax[CXT_MAX]; /* max wl/bt cycle time */ +} __packed; + +struct rtw89_btc_fbtc_a2dp_trx_stat { + u8 empty_cnt; + u8 retry_cnt; + u8 tx_rate; + u8 tx_cnt; + u8 ack_cnt; + u8 nack_cnt; + u8 rsvd1; + u8 rsvd2; +} __packed; + +struct rtw89_btc_fbtc_a2dp_trx_stat_v4 { + u8 empty_cnt; + u8 retry_cnt; + u8 tx_rate; + u8 tx_cnt; + u8 ack_cnt; + u8 nack_cnt; + u8 no_empty_cnt; + u8 rsvd; +} __packed; + +struct rtw89_btc_fbtc_cycle_a2dp_empty_info { + __le16 cnt; /* a2dp empty cnt */ + __le16 cnt_timeout; /* a2dp empty timeout cnt*/ + __le16 tavg; /* avg a2dp empty time */ + __le16 tmax; /* max a2dp empty time */ +} __packed; + +struct rtw89_btc_fbtc_cycle_leak_info { + __le32 cnt_rximr; /* the rximr occur at leak slot */ + __le16 tavg; /* avg leak-slot time */ + __le16 tmax; /* max leak-slot time */ +} __packed; + +struct rtw89_btc_fbtc_cycle_leak_info_v7 { + __le16 tavg; + __le16 tamx; + __le32 cnt_rximr; +} __packed; + +#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0) +#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10) + +struct rtw89_btc_fbtc_cycle_fddt_info { + __le16 train_cycle; + __le16 tp; + + s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ + s8 bt_tx_power; /* decrease Tx power (dB) */ + s8 bt_rx_gain; /* LNA constrain level */ + u8 no_empty_cnt; + + u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */ + u8 cn; /* condition_num */ + u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */ + u8 train_result; /* refer to enum btc_fddt_check_map */ +} __packed; + +#define RTW89_BTC_FDDT_CELL_TRAIN_STATE GENMASK(3, 0) +#define RTW89_BTC_FDDT_CELL_TRAIN_PHASE GENMASK(7, 4) + +struct rtw89_btc_fbtc_cycle_fddt_info_v5 { + __le16 train_cycle; + __le16 tp; + + s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ + s8 bt_tx_power; /* decrease Tx power (dB) */ + s8 bt_rx_gain; /* LNA constrain level */ + u8 no_empty_cnt; + + u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */ + u8 cn; /* condition_num */ + u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */ + u8 train_result; /* refer to enum btc_fddt_check_map */ +} __packed; + +struct rtw89_btc_fbtc_fddt_cell_status { + s8 wl_tx_pwr; + s8 bt_tx_pwr; + s8 bt_rx_gain; + u8 state_phase; /* [0:3] train state, [4:7] train phase */ +} __packed; + +struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ + u8 fver; + u8 rsvd; + __le16 cycles; /* total cycle number */ + __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_cycle_time_info cycle_time; + struct rtw89_btc_fbtc_fdd_try_info fdd_try; + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_a2dp_trx_stat a2dp_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_cycle_leak_info leak_slot; + __le32 slot_cnt[CXST_MAX]; /* slot count */ + __le32 bcn_cnt[CXBCN_MAX]; + __le32 collision_cnt; /* counter for event/timer occur at the same time */ + __le32 skip_cnt; + __le32 except_cnt; + __le32 except_map; +} __packed; + +#define FDD_TRAIN_WL_DIRECTION 2 +#define FDD_TRAIN_WL_RSSI_LEVEL 5 +#define FDD_TRAIN_BT_RSSI_LEVEL 5 + +struct rtw89_btc_fbtc_cysta_v4 { /* statistics for cycles */ + u8 fver; + u8 rsvd; + u8 collision_cnt; /* counter for event/timer occur at the same time */ + u8 except_cnt; + + __le16 skip_cnt; + __le16 cycles; /* total cycle number */ + + __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */ + __le16 slot_cnt[CXST_MAX]; /* slot count */ + __le16 bcn_cnt[CXBCN_MAX]; + struct rtw89_btc_fbtc_cycle_time_info cycle_time; + struct rtw89_btc_fbtc_cycle_leak_info leak_slot; + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_cycle_fddt_info fddt_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION] + [FDD_TRAIN_WL_RSSI_LEVEL] + [FDD_TRAIN_BT_RSSI_LEVEL]; + __le32 except_map; +} __packed; + +struct rtw89_btc_fbtc_cysta_v5 { /* statistics for cycles */ + u8 fver; + u8 rsvd; + u8 collision_cnt; /* counter for event/timer occur at the same time */ + u8 except_cnt; + u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX]; + + __le16 skip_cnt; + __le16 cycles; /* total cycle number */ + + __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */ + __le16 slot_cnt[CXST_MAX]; /* slot count */ + __le16 bcn_cnt[CXBCN_MAX]; + struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time; + struct rtw89_btc_fbtc_cycle_leak_info leak_slot; + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_cycle_fddt_info_v5 fddt_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION] + [FDD_TRAIN_WL_RSSI_LEVEL] + [FDD_TRAIN_BT_RSSI_LEVEL]; + __le32 except_map; +} __packed; + +struct rtw89_btc_fbtc_cysta_v105 { + u8 fver; + u8 rsvd; + u8 collision_cnt; + u8 except_cnt; + u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX]; + + __le16 skip_cnt; + __le16 cycles; + + __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; + __le16 slot_cnt[CXST_MAX]; + __le16 bcn_cnt[CXBCN_MAX]; + struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time; + struct rtw89_btc_fbtc_cycle_leak_info leak_slot; + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; + __le32 except_map; +} __packed; + +struct rtw89_btc_fbtc_cysta_v7 { /* statistics for cycles */ + u8 fver; + u8 rsvd; + u8 collision_cnt; /* counter for event/timer occur at the same time */ + u8 except_cnt; + + u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX]; + + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; + + __le16 skip_cnt; + __le16 cycles; /* total cycle number */ + + __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */ + __le16 slot_cnt[CXST_MAX]; /* slot count */ + __le16 bcn_cnt[CXBCN_MAX]; + + struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time; + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_cycle_leak_info_v7 leak_slot; + + __le32 except_map; +} __packed; + +union rtw89_btc_fbtc_cysta_info { + struct rtw89_btc_fbtc_cysta_v2 v2; + struct rtw89_btc_fbtc_cysta_v3 v3; + struct rtw89_btc_fbtc_cysta_v4 v4; + struct rtw89_btc_fbtc_cysta_v5 v5; + struct rtw89_btc_fbtc_cysta_v105 v105; + struct rtw89_btc_fbtc_cysta_v7 v7; +}; + +struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ + u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; + __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ + __le32 avg_t[2]; /* avg_t for 0:null0/1:null1 */ + __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ +} __packed; + +struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */ + u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; + __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ + __le32 avg_t[2]; /* avg_t for 0:null0/1:null1 */ + __le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */ +} __packed; + +struct rtw89_btc_fbtc_cynullsta_v7 { /* cycle null statistics */ + u8 fver; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + __le32 tmax[2]; + __le32 tavg[2]; + __le32 result[2][5]; +} __packed; + +union rtw89_btc_fbtc_cynullsta_info { + struct rtw89_btc_fbtc_cynullsta_v1 v1; /* info from fw */ + struct rtw89_btc_fbtc_cynullsta_v2 v2; + struct rtw89_btc_fbtc_cynullsta_v7 v7; +}; + +struct rtw89_btc_fbtc_btver_v1 { + u8 fver; /* btc_ver::fcxbtver */ + u8 rsvd; + __le16 rsvd2; + __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ + __le32 fw_ver; + __le32 feature; +} __packed; + +struct rtw89_btc_fbtc_btver_v7 { + u8 fver; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ + __le32 fw_ver; + __le32 feature; +} __packed; + +struct rtw89_btc_fbtc_btver_v8 { + u8 fver; + u8 bt_id; /* 0:BT0, 1:BT1 */ + u8 rsvd1; + u8 rsvd2; + + __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ + __le32 fw_ver; + __le32 feature; +} __packed; + +union rtw89_btc_fbtc_btver { + struct rtw89_btc_fbtc_btver_v1 v1; + struct rtw89_btc_fbtc_btver_v7 v7; + struct rtw89_btc_fbtc_btver_v8 v8; +} __packed; + +struct rtw89_btc_fbtc_btafh { + u8 fver; /* btc_ver::fcxbtafh */ + u8 rsvd; + __le16 rsvd2; + u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ + u8 afh_m[4]; /*bit0:2434, bit1: 2435.... bit31:2465 */ + u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */ +} __packed; + +struct rtw89_btc_fbtc_btafh_v2 { + u8 fver; /* btc_ver::fcxbtafh */ + u8 rsvd; + u8 rsvd2; + u8 map_type; + u8 afh_l[4]; + u8 afh_m[4]; + u8 afh_h[4]; + u8 afh_le_a[4]; + u8 afh_le_b[4]; +} __packed; + +struct rtw89_btc_fbtc_btafh_v7 { + u8 fver; + u8 map_type; + u8 rsvd0; + u8 rsvd1; + u8 afh_l[4]; /*bit0:2402, bit1:2403.... bit31:2433 */ + u8 afh_m[4]; /*bit0:2434, bit1:2435.... bit31:2465 */ + u8 afh_h[4]; /*bit0:2466, bit1:2467.....bit14:2480 */ + u8 afh_le_a[4]; + u8 afh_le_b[4]; +} __packed; + +struct rtw89_btc_fbtc_btafh_v8 { + u8 fver; + u8 map_type; + u8 bt_id; /* 0:BT0, 1:BT1 */ + u8 rsvd1; + u8 afh_l[4]; /*bit0:2402, bit1:2403.... bit31:2433 */ + u8 afh_m[4]; /*bit0:2434, bit1:2435.... bit31:2465 */ + u8 afh_h[4]; /*bit0:2466, bit1:2467.....bit14:2480 */ + u8 afh_le_a[4]; + u8 afh_le_b[4]; +} __packed; + +struct rtw89_btc_fbtc_btdevinfo { + u8 fver; /* btc_ver::fcxbtdevinfo */ + u8 rsvd; + __le16 vendor_id; + __le32 dev_name; /* only 24 bits valid */ + __le32 flush_time; +} __packed; + +struct rtw89_btc_trx_info { + u8 tx_lvl; + u8 rx_lvl; + u8 wl_rssi; + u8 bt_rssi; + + s8 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 0xff-> no BTC control */ + s8 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */ + s8 bt_tx_power[BTC_ALL_BT]; /* decrease Tx power (dB) */ + s8 bt_rx_gain[BTC_ALL_BT]; /* LNA constrain level */ + s8 zb_tx_power[BTC_ALL_BT]; + s8 zb_rx_gain[BTC_ALL_BT]; + + u8 cn; /* condition_num */ + s8 nhm; + u8 bt_profile; + u8 rsvd2; + + u16 tx_rate; + u16 rx_rate; + + u32 tx_tp; + u32 rx_tp; + u32 rx_err_ratio; +}; + +enum btc_rf_path { + BTC_RF_S0 = 0, + BTC_RF_S1 = 1, + BTC_RF_NUM, +}; + +struct rtw89_btc_fbtc_outsrc_set_info_v1 { + u8 rf_band[BTC_RF_NUM]; + u8 btg_rx[BTC_RF_NUM]; + u8 nbtg_tx[BTC_RF_NUM]; + + struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; + struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT]; + + u8 pta_req_hw_band; + u8 rf_gbt_source; + u8 bt_enable_state; + u8 wl_btg_standby_chg; + + u8 fbd_group_en[RTW89_MAC_NUM][2]; + __le16 rf_center_freq[RTW89_MAC_NUM]; + __le16 fbd_group_bound[RTW89_MAC_NUM][2]; + __le16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT]; +} __packed; + +struct rtw89_btc_fbtc_outsrc_set_info_v6 { + u8 rf_band[BTC_RF_NUM]; + u8 btg_rx[BTC_RF_NUM]; + u8 nbtg_tx[BTC_RF_NUM]; + + struct rtw89_btc_gnt_ctrl gnt_set[RTW89_MAC_AX_COEX_GNT_NR]; + struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL]; + + u8 pta_req_hw_band; + u8 rf_gbt_source; + u8 bt_enable_state; + u8 bt_plut_type; + u8 wl_tx_limit_en; + u8 fc_exec; + u8 wl_btg_standby_chg; + u8 rsvd; + u8 bb_path_sel_bt[BTC_RF_NUM]; + u8 bb_phy_sel_bt[RTW89_PHY_NUM]; + u8 fbd_group_en[RTW89_MAC_NUM][2]; + __le16 rf_center_freq[RTW89_MAC_NUM]; + __le16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT_EZL]; + __le16 fbd_group_bound[RTW89_MAC_NUM][2]; + __le32 wl_tx_limit_time; +} __packed; + +struct rtw89_btc_fbtc_outsrc_set_info { + u8 rf_band[BTC_RF_NUM]; /* 0:2GHz/1:5GHz for MPI_bb_hwsi_ignore_gnt_wl() */ + u8 btg_rx[BTC_RF_NUM]; /* for MPI_bb_btg_bt_rx() */ + u8 nbtg_tx[BTC_RF_NUM]; /* for MPI_bb_nbtg_bt_tx pre=AGC control */ + + struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; /* refer to btc_gnt_ctrl */ + struct rtw89_btc_gnt_ctrl gnt_set_be[RTW89_MAC_AX_COEX_GNT_NR]; + struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL]; + + u8 pta_req_hw_band; /* Bind PTA to HWB0 or HWB1, only for 8922a 1-PTA */ + u8 rf_gbt_source; /* gbt from S0 or S1 for RF 0x2[9], only for 8922a */ + + /* The followngs are for 8922c/d new Multi-PTA design */ + /* 0:BT0/1:BT1/2:ZB on/off for MAC(0xe580[0]/0xe680[0])/ RF 0x4[3:2] */ + u8 bt_enable_state; + u8 bt_plut_type; /* BT polluted type, refer to enum btc_plt_map */ + + u8 wl_tx_limit_en; + u8 fc_exec; + u8 wl_btg_standby_chg; /* keep RX-IQGen on in standby mode */ + u8 rsvd; + + u8 bb_path_sel_bt[BTC_RF_NUM]; /* bb s0(1) select GNT_BT0 or BT1 */ + u8 bb_phy_sel_bt[RTW89_PHY_NUM]; /* bb phy0(1) select GNT_BT0 or BT1 */ + + /* forbidden group-> bit[1]:fbd rf-band, bit[0]: fbd enable */ + u8 fbd_group_en[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */ + + /* bit[15]-> 0:2G/1:5G,6G, bit[14:0]-> WL HWBx ch freq in MHz */ + u16 rf_center_freq[RTW89_MAC_NUM]; /* HWB0/1 */ + + /* 11-bit in MHz, freq diff threshold */ + u16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT_EZL]; /* HWB0/1 vs.BT0/1/2 */ + + /* forbidden group boundary: [15:8]->UP, [7:0]->LO */ + u16 fbd_group_bound[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */ + + u32 wl_tx_limit_time; +}; + +union rtw89_btc_fbtc_slot_u { + struct rtw89_btc_fbtc_slot v1[CXST_MAX]; + struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; +}; + +struct rtw89_btc_fddr_cell { + u8 en; + u8 wl_rx_max; + u8 wl_rx_min; +}; + +struct rtw89_btc_fddr_result { + u8 wl_rx_limit; + u8 wl_rx_limit_step[6]; /* record search process */ + u8 search_cnt; /* the rx-limit serach count */ + u32 wl_tp; + u32 wl_tp_step[6]; /* record search process */ +}; + +struct rtw89_btc_fddr_train_info { + u8 rx_limit_pre; + u8 rx_limit_now; + + u32 tp_rec_cnt; + u32 tp_avg_cnt; + + u32 wl_tp_pre; + u32 wl_tp_now; +}; + +struct rtw89_btc_fddr_info { + u8 state; /* refer to enum btc_fddr_state */ + u8 cell_now; /* wl rssi_level after filter LNA != 6 */ + u8 cell_change; + u8 wl_low_rate; + + u8 tp_setup_time; /* calculate TP after this value (in second) */ + u8 tp_hold_time; /* TP calculation period (in second) */ + u8 wl_rssi_thres[BTC_WL_RSSI_THMAX]; /* index 0 -> Max RSSI */ + + u8 search_mode; /* 0: search, 1:look-up */ + u8 search_dir; /* 0: Max->Min, 1:Min->Max */ + + struct rtw89_btc_fddr_train_info tctrl; /* train flag */ + struct rtw89_btc_fddr_result cell_result[BTC_WL_RSSI_THMAX + 1]; + struct rtw89_btc_fddr_cell cell[BTC_WL_RSSI_THMAX + 1]; /* parameters */ + + u16 wl_rx_rate_thres; /* switch to TDD if rx_rate < this threshold */ + + u32 nrsn_map; /* the reason map for no-run fdd-traing */ + u32 wl_rx_rate_now; +}; + +struct rtw89_btc_rpt_ctrl_a2dp_empty { + u32 cnt_empty; /* a2dp empty count */ + u32 cnt_flowctrl; /* a2dp empty flow control counter */ + u32 cnt_tx; + u32 cnt_ack; + u32 cnt_nack; +}; + +struct rtw89_btc_fddt_bt_stat { + struct rtw89_btc_rpt_ctrl_a2dp_empty a2dp_last; + u32 retry_last; +}; + +struct rtw89_btc_fddt_cell { + s8 wl_pwr_min; + s8 wl_pwr_max; + s8 bt_pwr_dec_max; + s8 bt_rx_gain; +}; + +struct rtw89_btc_fddt_fail_check { /* for cell stay in training */ + u8 check_map; /* check pass condition if bit-map = 1 */ + u8 bt_no_empty_cnt; /* 0-fail if no bt-empty >= th in train_cycle */ + u8 wl_tp_ratio; /* 1-fail if wl tp rise ratio < th */ + u8 wl_kpibtr_ratio; /* 2-fail if phase_now_tp < phase_last_tp * kpibtr_ratio */ +}; + +struct rtw89_btc_fddt_break_check { /* for cell stay in training or train-ok */ + u8 check_map; /* check break condition if bit-map = 1 */ + u8 bt_no_empty_cnt; /* 0-break if no empty count >= th */ + u8 wl_tp_ratio; /* 1-break if wl tp ratio < th (%) */ + u8 wl_tp_low_bound; /* 2-break if wl tp (in Mbps) < th */ + + u8 cn; /* 3-break if (cn >= cn_limit) >= th cycle */ + u8 cell_chg; /* 4-break if non-matched-RSSI >= th cycle */ + s8 nhm_limit; /* 5-break if nhm >= th --> ill-condition */ + u8 cn_limit; /* if condition number >= th --> ill-condition */ +}; + +struct rtw89_btc_fddt_time_ctrl { + /* 1 TDD cycle = w1 + b1, FDD 1cycle = w1fdd-slot + b1fdd-slot */ + u8 m_cycle; /* KPI Moving-Average-Cycle: 1~32 cycles */ + u8 w_cycle; /* Start to calcul WKPI after this if train-phase change */ + u8 k_cycle; /* Total kpi-estimate cycles for each training-step */ + u8 rsvd; +}; + +struct rtw89_btc_fddt_train_info { + struct rtw89_btc_fddt_time_ctrl t_ctrl; + struct rtw89_btc_fddt_break_check b_chk; + struct rtw89_btc_fddt_fail_check f_chk; + struct rtw89_btc_fddt_cell cell_ul[5][5]; + struct rtw89_btc_fddt_cell cell_dl[5][5]; +}; + +struct rtw89_btc_fddt_info { + u8 type; /* refer to enum btc_fddt_type */ + u8 result; /* fw send fdd-training status by c2h */ + u8 state; /* refer to enum btc_fddt_state */ + + u8 wl_iot[6]; /* wl bssid */ + u16 bt_iot; /* bt vendor-id */ + + u32 nrsn_map; /* the reason map for no-run fdd-traing */ + struct rtw89_btc_fddt_bt_stat bt_stat; /* bt statistics */ + struct rtw89_btc_fddt_train_info train; + struct rtw89_btc_fddt_train_info train_now; +}; + +struct rtw89_btc_dm { + struct rtw89_btc_fbtc_outsrc_set_info ost_info_last; /* outsrc API setup info */ + struct rtw89_btc_fbtc_outsrc_set_info ost_info; /* outsrc API setup info */ + union rtw89_btc_fbtc_slot_u slot; + union rtw89_btc_fbtc_slot_u slot_now; + struct rtw89_btc_fbtc_tdma tdma; + struct rtw89_btc_fbtc_tdma tdma_now; + struct rtw89_btc_gnt_ctrl gnt_set[RTW89_MAC_AX_COEX_GNT_NR]; + struct rtw89_btc_gnt_ctrl gnt_val[RTW89_MAC_AX_COEX_GNT_NR]; + struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL]; + struct rtw89_btc_init_info init_info; /* pass to wl_fw if offload */ + struct rtw89_btc_rf_trx_para_v9 rf_trx_para; + struct rtw89_btc_wl_tx_limit_para wl_tx_limit; + struct rtw89_btc_dm_step dm_step; + struct rtw89_btc_eslot_ctrl eslot_ctrl; + struct rtw89_btc_trx_info trx_info; + union rtw89_btc_dm_error_map error; + struct rtw89_btc_bind_info tdd_bind; + struct rtw89_btc_bind_info fdd_bind; + struct rtw89_btc_fddt_info fddt_info; + struct rtw89_btc_fddr_info fddr_info; + struct rtw89_btc_wl_trx_nss_para wl_trx_nss; + u32 cnt_dm[BTC_DCNT_NUM]; + u32 cnt_notify[BTC_NCNT_NUM]; + u8 ant_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT ANT interact-map */ + u8 xtk_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* 1: If RSSI<(BT-Pin -SIR) */ + u8 sit_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT space interact-map */ + u8 fit_xmap[RTW89_PHY_NUM][BTC_ALL_BT_EZL]; /* HWB-BT freq interact-map */ + u8 tdd_map[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT tdd-map */ + u8 fdd_map[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT fdd-map */ + u8 corx_map[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT Co-Rx */ + + u8 sit_xmap_last[BTC_RF_NUM][BTC_ALL_BT_EZL]; + u8 fit_xmap_last[RTW89_PHY_NUM][BTC_ALL_BT_EZL]; + + u8 tdd_rssi_thres; /* The FDD/TDD switch RSSI (in %) */ + u8 sir_thres; /* WL(Signal) to BT(interference Pin) ratio */ + u8 sir_state[BTC_ALL_BT_EZL]; /* 1: WL RSSI > BTx-interference */ + + u32 update_slot_map; + u32 set_ant_path; + u32 e2g_slot_limit; + u32 e2g_slot_nulltx_time; + + u32 wl_only: 1; + u32 wl_fw_cx_offload: 1; + u32 freerun: 1; + u32 fddt_train: 1; + u32 wl_ps_ctrl: 2; + u32 wl_mimo_ps: 1; + u32 leak_ap: 1; + u32 noisy_level: 3; + u32 coex_info_map: 8; + u32 bt_only: 1; + u32 wl_btg_rx: 2; + u32 trx_para_level: 8; + u32 wl_stb_chg: 1; + u32 pta_owner: 1; + + u32 tdma_instant_excute: 1; + u32 wl_btg_rx_rb: 2; + + u16 slot_dur[CXST_MAX]; + u16 bt_slot_flood; + + u8 run_reason; + u8 run_action; + u8 wl_tx_pwr_phy_map; + u8 vid; + u8 client_ps_tdma_on; + u8 wl_trx_nss_en; + + u8 wl_pre_agc: 2; + u8 wl_lna2: 1; + u8 freerun_chk: 1; + u8 wl_pre_agc_rb: 2; + u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */ + + u8 slot_req_more: 1; + u8 out_of_band: 1; + u8 fdd_en: 1; + u8 tdd_en: 1; + u8 lps_ctrl_scbd: 1; + u8 lps_ctrl_change: 1; + u8 bis_tdma: 1; /* BIS TDMA mode active */ + u8 scbd_write_instant; + bool scbd_b2w_update; + bool scbd_w2b_update; + bool pre_agc_chg; +}; + +struct rtw89_fbtc_wl_ctrl_info { + u8 rf_band_map[RTW89_MAC_NUM]; + u8 rf_ch[RTW89_MAC_NUM]; + + u8 client_pstdma_on; + u8 fw_scan; + u8 rfk_state; + u8 rfk_type; + + u32 smap_val; +}; + +struct rtw89_btc_ctrl { + u32 manual; + u32 igno_bt: 1; + u32 always_freerun: 1; + u32 trace_step: 16; + + u8 wl_only; + u8 bt_only; + + u8 ntfy_type; + struct rtw89_fbtc_wl_ctrl_info wl_ctrl_info; +}; + +struct rtw89_btc_ctrl_v0 { + u32 manual: 1; + u32 igno_bt: 1; + u32 always_freerun: 1; + u32 trace_step: 16; + u32 rsvd: 12; +} __packed; + +struct rtw89_btc_ctrl_v7 { + u8 manual; + u8 igno_bt; + u8 always_freerun; + u8 rsvd; +} __packed; + +struct rtw89_fbtc_wl_ctrl_info_v9 { + u8 rf_band_map[RTW89_MAC_NUM]; + u8 rf_ch[RTW89_MAC_NUM]; + + u8 client_pstdma_on; + u8 fw_scan; + u8 rfk_state; + u8 rfk_type; + + __le32 smap_val; +} __packed; + +struct rtw89_btc_ctrl_v9 { + u8 manual; + u8 always_freerun; + u8 wl_only; + u8 bt_only; + + u8 ntfy_type; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + struct rtw89_fbtc_wl_ctrl_info_v9 wl_ctrl_info; +} __packed; + +struct rtw89_btc_dbg { + /* cmd "rb" */ + bool rb_done; + u32 rb_val; +}; + +enum rtw89_btc_btf_fw_event { + BTF_EVNT_RPT = 0, + BTF_EVNT_BT_INFO = 1, + BTF_EVNT_BT_SCBD = 2, + BTF_EVNT_BT_REG = 3, + BTF_EVNT_CX_RUNINFO = 4, + BTF_EVNT_BT_PSD = 5, + BTF_EVNT_BT_DEV_INFO = 6, /* fwc2hfunc > 0 */ + BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */ + BTF_EVNT_BUF_OVERFLOW, + BTF_EVNT_C2H_LOOPBACK, + BTF_EVNT_BT_QUERY_TXPWR, /* fwc2hfunc > 3 */ + BTF_EVNT_ZB_INFO = 11, + BTF_EVNT_ZB_CH = 12, + BTF_EVNT_ZB_QUERY_TXPWR = 13, + BTF_EVNT_MAX, +}; + +enum btf_fw_event_report { + BTC_RPT_TYPE_CTRL = 0x0, + BTC_RPT_TYPE_TDMA, + BTC_RPT_TYPE_SLOT, + BTC_RPT_TYPE_CYSTA, + BTC_RPT_TYPE_STEP, + BTC_RPT_TYPE_NULLSTA, + BTC_RPT_TYPE_FDDT, /* added by ver->fwevntrptl == 1 */ + BTC_RPT_TYPE_MREG, + BTC_RPT_TYPE_GPIO_DBG, + BTC_RPT_TYPE_BT_VER, + BTC_RPT_TYPE_BT_SCAN, + BTC_RPT_TYPE_BT_AFH, + BTC_RPT_TYPE_BT_DEVICE, + BTC_RPT_TYPE_TEST, + BTC_RPT_TYPE_MAX = 31, + + __BTC_RPT_TYPE_V0_SAME = BTC_RPT_TYPE_NULLSTA, + __BTC_RPT_TYPE_V0_MAX = 12, +}; + +enum rtw_btc_btf_reg_type { + REG_MAC = 0x0, + REG_BB = 0x1, + REG_RF = 0x2, + REG_BT_RF = 0x3, + REG_BT_MODEM = 0x4, + REG_BT_BLUEWIZE = 0x5, + REG_BT_VENDOR = 0x6, + REG_BT_LE = 0x7, + REG_MAX_TYPE, +}; + +struct rtw89_btc_rpt_cmn_info { + u32 rx_cnt; + u32 rx_len; + u32 req_len; /* expected rsp len */ + u8 req_fver; /* expected rsp fver */ + u8 rsp_fver; /* fver from fw */ + u8 valid; +} __packed; + +union rtw89_btc_fbtc_btafh_info { + struct rtw89_btc_fbtc_btafh v1; + struct rtw89_btc_fbtc_btafh_v2 v2; + struct rtw89_btc_fbtc_btafh_v7 v7; + struct rtw89_btc_fbtc_btafh_v8 v8; +}; + +struct rtw89_btc_report_ctrl_state { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_rpt_ctrl_ver_info finfo; +}; + +struct rtw89_btc_rpt_fbtc_tdma { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_tdma_le32 finfo; +}; + +struct rtw89_btc_rpt_fbtc_slots { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_slots_info finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_cysta { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_cysta_info finfo; +}; + +struct rtw89_btc_rpt_fbtc_step { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_steps_info finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_nullsta { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_cynullsta_info finfo; +}; + +struct rtw89_btc_rpt_fbtc_mreg { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_gpio_dbg { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_btver { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_btver finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_btscan { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_btscan finfo; /* info from fw */ +}; + +struct rtw89_btc_rpt_fbtc_btafh { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union rtw89_btc_fbtc_btafh_info finfo; +}; + +struct rtw89_btc_rpt_fbtc_btdev { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + struct rtw89_btc_fbtc_btdevinfo finfo; /* info from fw */ +}; + +enum rtw89_btc_btfre_type { + BTFRE_INVALID_INPUT = 0x0, /* invalid input parameters */ + BTFRE_UNDEF_TYPE, + BTFRE_EXCEPTION, + BTFRE_MAX, +}; + +struct rtw89_btc_ver { + enum rtw89_core_chip_id chip_id; + u32 fw_ver_code; + + u8 fcxbtcrpt; + u8 fcxtdma; + u8 fcxslots; + u8 fcxcysta; + u8 fcxstep; + u8 fcxnullsta; + u8 fcxmreg; + u8 fcxgpiodbg; + u8 fcxbtver; + u8 fcxbtscan; + u8 fcxbtafh; + u8 fcxbtdevinfo; + u8 fwlrole; + u8 frptmap; + u8 fcxctrl; + u8 fcxinit; + + u8 fwevntrptl; + u8 fwc2hfunc; + u8 drvinfo_ver; + u16 info_buf; + u8 max_role_num; + u8 fcxosi; + u8 fcxmlo; + u8 bt_desired; + u8 fcxtrx; +}; + +struct rtw89_btc_btf_fwinfo { + u32 cnt_c2h; + u32 cnt_h2c; + u32 cnt_h2c_fail; + u32 event[BTF_EVNT_MAX]; + + u32 err[BTFRE_MAX]; + u32 len_mismch; + u32 fver_mismch; + u32 rpt_en_map; + + struct rtw89_btc_ver fw_subver; + struct rtw89_btc_report_ctrl_state rpt_ctrl; + struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; + struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; + struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; + struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; + struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; + struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; + struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; + struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; + struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; + struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; + struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; +}; + +#define RTW89_BTC_POLICY_MAXLEN 512 +#define BTC_H2C_MAXLENC 2020 + +struct rtw89_btc { + const struct rtw89_btc_ver *ver; + + struct rtw89_btc_cx cx; + struct rtw89_btc_dm dm; + struct rtw89_btc_ctrl ctrl; + struct rtw89_btc_module mdinfo; + struct rtw89_btc_btf_fwinfo fwinfo; + struct rtw89_btc_dbg dbg; + struct rtw89_fbtc_h2c_set_gpio gpio; + + struct wiphy_work eapol_notify_work; + struct wiphy_work arp_notify_work; + struct wiphy_work dhcp_notify_work; + struct wiphy_work icmp_notify_work; + + u32 bt_req_len[RTW89_PHY_NUM]; + + u8 policy[RTW89_BTC_POLICY_MAXLEN]; + u8 hbuf[BTC_H2C_MAXLENC]; /* H2C Macro buffer */ + u8 hbuf_cnt; /* H2C cmd count in buffer */ + u8 ant_type; + u8 btg_pos; + u8 io_oflld_type; + u16 policy_len; + u16 policy_type; + u16 hbuf_len; /* H2C used length, it sshould be <= BTC_H2C_MAXLEN */ + u32 hubmsg_cnt; + bool bt_req_en; + bool update_policy_force; + bool btc_ctrl_lps; + bool manual_ctrl; + bool cli_h2c_cmd; +}; + +enum rtw89_btc_hmsg { + RTW89_BTC_HMSG_TMR_EN = 0x0, + RTW89_BTC_HMSG_BT_REG_READBACK = 0x1, + RTW89_BTC_HMSG_SET_BT_REQ_SLOT = 0x2, + RTW89_BTC_HMSG_FW_EV = 0x3, + RTW89_BTC_HMSG_BT_LINK_CHG = 0x4, + RTW89_BTC_HMSG_SET_BT_REQ_STBC = 0x5, + + NUM_OF_RTW89_BTC_HMSG, +}; + +enum rtw89_ra_mode { + RTW89_RA_MODE_CCK = BIT(0), + RTW89_RA_MODE_OFDM = BIT(1), + RTW89_RA_MODE_HT = BIT(2), + RTW89_RA_MODE_VHT = BIT(3), + RTW89_RA_MODE_HE = BIT(4), + RTW89_RA_MODE_EHT = BIT(5), +}; + +enum rtw89_ra_report_mode { + RTW89_RA_RPT_MODE_LEGACY, + RTW89_RA_RPT_MODE_HT, + RTW89_RA_RPT_MODE_VHT, + RTW89_RA_RPT_MODE_HE, + RTW89_RA_RPT_MODE_EHT, +}; + +enum rtw89_dig_noisy_level { + RTW89_DIG_NOISY_LEVEL0 = -1, + RTW89_DIG_NOISY_LEVEL1 = 0, + RTW89_DIG_NOISY_LEVEL2 = 1, + RTW89_DIG_NOISY_LEVEL3 = 2, + RTW89_DIG_NOISY_LEVEL_MAX = 3, +}; + +enum rtw89_gi_ltf { + RTW89_GILTF_LGI_4XHE32 = 0, + RTW89_GILTF_SGI_4XHE08 = 1, + RTW89_GILTF_2XHE16 = 2, + RTW89_GILTF_2XHE08 = 3, + RTW89_GILTF_1XHE16 = 4, + RTW89_GILTF_1XHE08 = 5, + RTW89_GILTF_MAX +}; + +enum rtw89_rx_frame_type { + RTW89_RX_TYPE_MGNT = 0, + RTW89_RX_TYPE_CTRL = 1, + RTW89_RX_TYPE_DATA = 2, + RTW89_RX_TYPE_RSVD = 3, +}; + +enum rtw89_efuse_block { + RTW89_EFUSE_BLOCK_SYS = 0, + RTW89_EFUSE_BLOCK_RF = 1, + RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO = 2, + RTW89_EFUSE_BLOCK_HCI_DIG_USB = 3, + RTW89_EFUSE_BLOCK_HCI_PHY_PCIE = 4, + RTW89_EFUSE_BLOCK_HCI_PHY_USB3 = 5, + RTW89_EFUSE_BLOCK_HCI_PHY_USB2 = 6, + RTW89_EFUSE_BLOCK_ADIE = 7, + + RTW89_EFUSE_BLOCK_NUM, + RTW89_EFUSE_BLOCK_IGNORE, +}; + +struct rtw89_ra_info { + u8 is_dis_ra:1; + /* Bit0 : CCK + * Bit1 : OFDM + * Bit2 : HT + * Bit3 : VHT + * Bit4 : HE + * Bit5 : EHT + */ + u8 mode_ctrl:6; + u8 bw_cap:3; /* enum rtw89_bandwidth */ + u8 macid; + u8 dcm_cap:1; + u8 er_cap:1; + u8 init_rate_lv:2; + u8 upd_all:1; + u8 en_sgi:1; + u8 ldpc_cap:1; + u8 stbc_cap:1; + u8 ss_num:3; + u8 giltf:3; + u8 upd_bw_nss_mask:1; + u8 upd_mask:1; + u64 ra_mask; /* 63 bits ra_mask + 1 bit CSI ctrl */ + /* BFee CSI */ + u8 band_num; + u8 ra_csi_rate_en:1; + u8 fixed_csi_rate_en:1; + u8 cr_tbl_sel:1; + u8 fix_giltf_en:1; + u8 fix_giltf:3; + u8 partial_bw_er:1; + u8 csi_mcs_ss_idx; + u8 csi_mode:2; + u8 csi_gi_ltf:3; + u8 csi_bw:3; + /* after v1 */ + u8 is_noisy:1; + u8 psra_en:1; + u8 rsvd0:1; + u8 macid_msb:2; + u8 band:2; /* enum rtw89_band */ + u8 is_new_dbgreg:1; +}; + +#define RTW89_PPDU_MAC_INFO_USR_SIZE 4 +#define RTW89_PPDU_MAC_INFO_SIZE 8 +#define RTW89_PPDU_MAC_RX_CNT_SIZE 96 +#define RTW89_PPDU_MAC_RX_CNT_SIZE_V1 128 + +struct rtw89_ampdu_params { + u16 agg_num; + bool amsdu; +}; + +struct rtw89_ra_report { + struct rate_info txrate; + u32 bit_rate; + u16 hw_rate; + u8 retry_ratio; + bool might_fallback_legacy; +}; + +DECLARE_EWMA(rssi, 10, 16); +DECLARE_EWMA(evm, 10, 16); +DECLARE_EWMA(snr, 10, 16); + +struct rtw89_ba_cam_entry { + struct list_head list; + u8 tid; +}; + +#define RTW89_MAX_ADDR_CAM_NUM 128 +#define RTW89_MAX_BSSID_CAM_NUM 20 +#define RTW89_MAX_SEC_CAM_NUM 128 +#define RTW89_MAX_BA_CAM_NUM 24 +#define RTW89_SEC_CAM_IN_ADDR_CAM 7 + +struct rtw89_addr_cam_entry { + u8 addr_cam_idx; + u8 offset; + u8 len; + u8 valid : 1; + u8 addr_mask : 6; + u8 wapi : 1; + u8 mask_sel : 2; + u8 bssid_cam_idx: 6; + + u8 sec_ent_mode; + DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); + u8 sec_ent_keyid[RTW89_SEC_CAM_IN_ADDR_CAM]; + u8 sec_ent[RTW89_SEC_CAM_IN_ADDR_CAM]; +}; + +struct rtw89_bssid_cam_entry { + u8 bssid[ETH_ALEN]; + u8 phy_idx; + u8 bssid_cam_idx; + u8 offset; + u8 len; + u8 valid : 1; + u8 num; +}; + +struct rtw89_sec_cam_entry { + u8 sec_cam_idx; + u8 offset; + u8 len; + u8 type : 4; + u8 ext_key : 1; + u8 spp_mode : 1; + /* 256 bits */ + u8 key[32]; + + struct ieee80211_key_conf *key_conf; +}; + +struct rtw89_sta_link { + struct rtw89_sta *rtwsta; + struct list_head dlink_schd; + unsigned int link_id; + + u8 mac_id; + u8 tx_retry; + bool er_cap; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_ra_info ra; + struct rtw89_ra_report ra_report; + int max_agg_wait; + u8 prev_rssi; + struct ewma_rssi avg_rssi; + struct ewma_rssi rssi[RF_PATH_MAX]; + struct ewma_snr avg_snr; + struct ewma_evm evm_1ss; + struct ewma_evm evm_min[RF_PATH_MAX]; + struct ewma_evm evm_max[RF_PATH_MAX]; + struct ieee80211_rx_status rx_status; + u16 rx_hw_rate; + __le32 htc_template; + struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */ + struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */ + struct list_head ba_cam_list; + + bool use_cfg_mask; + struct cfg80211_bitrate_mask mask; + + bool cctl_tx_time; + u32 ampdu_max_time:4; + bool cctl_tx_retry_limit; + u32 data_tx_cnt_lmt:6; +}; + +#define RTW89_EFUSE_SN_LEN 5 +#define RTW89_EFUSE_UUID_LEN 16 + +struct rtw89_efuse { + bool valid; + bool power_k_valid; + bool vcore_valid; + bool dswr_valid; + u8 xtal_cap; + u8 addr[ETH_ALEN]; + u8 rfe_type; + char country_code[2]; + u8 adc_td; + u8 bt_setting_2; + u8 bt_setting_3; + u8 sn[RTW89_EFUSE_SN_LEN]; + u8 uuid[RTW89_EFUSE_UUID_LEN]; + u8 vcore_vmax_reduce; + u8 dswr_vmin; +}; + +struct rtw89_phy_rate_pattern { + u64 ra_mask; + u16 rate; + u8 ra_mode; + bool enable; +}; + +#define RTW89_TX_DONE 0x0 +#define RTW89_TX_RETRY_LIMIT 0x1 +#define RTW89_TX_LIFE_TIME 0x2 +#define RTW89_TX_MACID_DROP 0x3 + +#define RTW89_MAX_TX_RPTS 16 +#define RTW89_MAX_TX_RPTS_MASK (RTW89_MAX_TX_RPTS - 1) +struct rtw89_tx_rpt { + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; + /* protect skbs array access/modification */ + spinlock_t skb_lock; + atomic_t sn; +}; + +#define RTW89_TX_WAIT_WORK_TIMEOUT msecs_to_jiffies(500) +struct rtw89_tx_wait_info { + struct rcu_head rcu_head; + struct list_head list; + struct completion completion; + struct sk_buff *skb; + bool tx_done; +}; + +struct rtw89_tx_skb_data { + struct rtw89_tx_wait_info __rcu *wait; + u8 tx_rpt_sn; + u8 tx_pkt_cnt_lmt; + u8 hci_priv[]; +}; + +#define RTW89_SCAN_NULL_TIMEOUT 30 + +#define RTW89_ROC_IDLE_TIMEOUT 500 +#define RTW89_ROC_TX_TIMEOUT 30 +enum rtw89_roc_state { + RTW89_ROC_IDLE, + RTW89_ROC_NORMAL, + RTW89_ROC_MGMT, +}; + +struct rtw89_roc { + struct ieee80211_channel chan; + struct wiphy_delayed_work roc_work; + enum ieee80211_roc_type type; + enum rtw89_roc_state state; + int duration; + unsigned int link_id; +}; + +#define RTW89_P2P_MAX_NOA_NUM 2 + +struct rtw89_p2p_ie_head { + u8 eid; + u8 ie_len; + u8 oui[3]; + u8 oui_type; +} __packed; + +struct rtw89_noa_attr_head { + u8 attr_type; + __le16 attr_len; + u8 index; + u8 oppps_ctwindow; +} __packed; + +struct rtw89_p2p_noa_ie { + struct rtw89_p2p_ie_head p2p_head; + struct rtw89_noa_attr_head noa_head; + struct ieee80211_p2p_noa_desc noa_desc[RTW89_P2P_MAX_NOA_NUM]; +} __packed; + +struct rtw89_p2p_noa_setter { + struct rtw89_p2p_noa_ie ie; + u8 noa_count; + u8 noa_index; +}; + +struct rtw89_ps_noa_once_handler { + bool in_duration; + u64 tsf_begin; + u64 tsf_end; + struct wiphy_delayed_work set_work; + struct wiphy_delayed_work clr_work; +}; + +struct rtw89_vif_link { + struct rtw89_vif *rtwvif; + struct list_head dlink_schd; + unsigned int link_id; + + bool chanctx_assigned; /* only valid when running with chanctx_ops */ + enum rtw89_chanctx_idx chanctx_idx; + enum rtw89_reg_6ghz_power reg_6ghz_power; + struct rtw89_reg_6ghz_tpe reg_6ghz_tpe; + + u8 mac_id; + u8 port; + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 phy_idx; + u8 mac_idx; + u8 net_type; + u8 wifi_role; + u8 self_role; + u8 wmm; + u8 bcn_hit_cond; + u8 bcn_bw_idx; + u8 hit_rule; + u8 last_noa_nr; + u64 sync_bcn_tsf; + u64 last_sync_bcn_tsf; + bool rand_tsf_done; + bool trigger; + bool lsig_txop; + u8 tgt_ind; + u8 frm_tgt_ind; + bool wowlan_pattern; + bool wowlan_uc; + bool wowlan_magic; + bool is_hesta; + bool last_a_ctrl; + bool dyn_tb_bedge_en; + bool pre_pwr_diff_en; + bool pwr_diff_en; + u8 def_tri_idx; + struct wiphy_work update_beacon_work; + struct wiphy_delayed_work csa_beacon_work; + struct rtw89_addr_cam_entry addr_cam; + struct rtw89_bssid_cam_entry bssid_cam; + struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; + struct rtw89_phy_rate_pattern rate_pattern; + struct list_head general_pkt_list; + struct rtw89_p2p_noa_setter p2p_noa; + struct rtw89_ps_noa_once_handler noa_once; + struct wiphy_delayed_work mcc_gc_detect_beacon_work; + u8 detect_bcn_count; +}; + +enum rtw89_lv1_rcvy_step { + RTW89_LV1_RCVY_STEP_1, + RTW89_LV1_RCVY_STEP_2, +}; + +struct rtw89_hci_ops { + int (*tx_write)(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req); + void (*tx_kick_off)(struct rtw89_dev *rtwdev, u8 txch); + void (*flush_queues)(struct rtw89_dev *rtwdev, u32 queues, bool drop); + void (*reset)(struct rtw89_dev *rtwdev); + int (*start)(struct rtw89_dev *rtwdev); + void (*stop)(struct rtw89_dev *rtwdev); + void (*pause)(struct rtw89_dev *rtwdev, bool pause); + void (*switch_mode)(struct rtw89_dev *rtwdev, bool low_power); + void (*recalc_int_mit)(struct rtw89_dev *rtwdev); + + u8 (*read8)(struct rtw89_dev *rtwdev, u32 addr); + u16 (*read16)(struct rtw89_dev *rtwdev, u32 addr); + u32 (*read32)(struct rtw89_dev *rtwdev, u32 addr); + void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); + void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); + void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); + + u32 (*read32_pci_cfg)(struct rtw89_dev *rtwdev, u32 addr); + + int (*mac_pre_init)(struct rtw89_dev *rtwdev); + int (*mac_pre_deinit)(struct rtw89_dev *rtwdev); + int (*mac_post_init)(struct rtw89_dev *rtwdev); + int (*deinit)(struct rtw89_dev *rtwdev); + + u32 (*check_and_reclaim_tx_resource)(struct rtw89_dev *rtwdev, u8 txch); + int (*mac_lv1_rcvy)(struct rtw89_dev *rtwdev, enum rtw89_lv1_rcvy_step step); + void (*dump_err_status)(struct rtw89_dev *rtwdev); + int (*napi_poll)(struct napi_struct *napi, int budget); + + /* Deal with locks inside recovery_start and recovery_complete callbacks + * by hci instance, and handle things which need to consider under SER. + * e.g. turn on/off interrupts except for the one for halt notification. + */ + void (*recovery_start)(struct rtw89_dev *rtwdev); + void (*recovery_complete)(struct rtw89_dev *rtwdev); + + void (*ctrl_txdma_ch)(struct rtw89_dev *rtwdev, bool enable); + void (*ctrl_txdma_fw_ch)(struct rtw89_dev *rtwdev, bool enable); + void (*ctrl_trxhci)(struct rtw89_dev *rtwdev, bool enable); + int (*poll_txdma_ch_idle)(struct rtw89_dev *rtwdev); + void (*clr_idx_all)(struct rtw89_dev *rtwdev); + void (*clear)(struct rtw89_dev *rtwdev, struct pci_dev *pdev); + void (*disable_intr)(struct rtw89_dev *rtwdev); + void (*enable_intr)(struct rtw89_dev *rtwdev); + int (*rst_bdram)(struct rtw89_dev *rtwdev); +}; + +struct rtw89_hci_info { + const struct rtw89_hci_ops *ops; + enum rtw89_hci_type type; + enum rtw89_hci_dle_type dle_type; + u32 rpwm_addr; + u32 cpwm_addr; + bool paused; + bool tx_rpt_enabled; +}; + +struct rtw89_chip_ops { + int (*enable_bb_rf)(struct rtw89_dev *rtwdev); + int (*disable_bb_rf)(struct rtw89_dev *rtwdev); + void (*bb_preinit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void (*bb_postinit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void (*bb_reset)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); + void (*bb_sethw)(struct rtw89_dev *rtwdev); + u32 (*read_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask); + bool (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); + void (*set_channel)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx); + void (*set_channel_help)(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx); + int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block); + int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); + void (*fem_setup)(struct rtw89_dev *rtwdev); + int (*data_setup)(struct rtw89_dev *rtwdev); + void (*rfe_gpio)(struct rtw89_dev *rtwdev); + void (*rfk_hw_init)(struct rtw89_dev *rtwdev); + void (*rfk_init)(struct rtw89_dev *rtwdev); + void (*rfk_init_late)(struct rtw89_dev *rtwdev); + void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); + void (*rfk_band_changed)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); + void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool start); + void (*rfk_track)(struct rtw89_dev *rtwdev); + void (*power_trim)(struct rtw89_dev *rtwdev); + void (*set_txpwr)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); + int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); + u32 (*chan_to_rf18_val)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan); + void (*ctrl_btg_bt_rx)(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx); + void (*query_ppdu)(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status); + void (*convert_rpl_to_rssi)(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu); + void (*phy_rpt_to_rssi)(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status); + void (*ctrl_nbtg_bt_tx)(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx); + void (*cfg_txrx_path)(struct rtw89_dev *rtwdev); + void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx); + void (*digital_pwr_comp)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); + void (*calc_rx_gain_normal)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx, + struct rtw89_phy_calc_efuse_gain *calc); + void (*path_diff_update)(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb); + int (*pwr_on_func)(struct rtw89_dev *rtwdev); + int (*pwr_off_func)(struct rtw89_dev *rtwdev); + void (*query_rxdesc)(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset); + void (*fill_txdesc)(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); + void (*fill_txdesc_fwcmd)(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); + u8 (*get_ch_dma[RTW89_HCI_TYPE_NUM])(struct rtw89_dev *rtwdev, u8 qsel); + int (*cfg_ctrl_path)(struct rtw89_dev *rtwdev, bool wl); + int (*mac_cfg_gnt)(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); + int (*stop_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel); + int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); + int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_txtime_cmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_punctured_cmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured); + int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + int (*h2c_update_beacon)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); + int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + bool valid, struct ieee80211_ampdu_params *params); + int (*h2c_wow_cam_update)(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); + + void (*btc_set_rfe)(struct rtw89_dev *rtwdev); + void (*btc_init_cfg)(struct rtw89_dev *rtwdev); + void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); + void (*btc_set_wl_txpwr_ctrl)(struct rtw89_dev *rtwdev, u32 txpwr_val); + s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); + void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); + void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); + void (*btc_set_policy)(struct rtw89_dev *rtwdev, u16 policy_type); + void (*btc_set_wl_rx_gain)(struct rtw89_dev *rtwdev, u32 level); +}; + +enum rtw89_dma_ch { + RTW89_DMA_ACH0 = 0, + RTW89_DMA_ACH1 = 1, + RTW89_DMA_ACH2 = 2, + RTW89_DMA_ACH3 = 3, + RTW89_DMA_ACH4 = 4, + RTW89_DMA_ACH5 = 5, + RTW89_DMA_ACH6 = 6, + RTW89_DMA_ACH7 = 7, + RTW89_DMA_B0MG = 8, + RTW89_DMA_B0HI = 9, + RTW89_DMA_B1MG = 10, + RTW89_DMA_B1HI = 11, + RTW89_DMA_H2C = 12, + RTW89_DMA_CH_NUM = 13 +}; + +#define MLO_MODE_FOR_BB0_BB1_RF(bb0, bb1, rf) ((rf) << 12 | (bb1) << 4 | (bb0)) + +enum rtw89_mlo_dbcc_mode { + MLO_DBCC_NOT_SUPPORT = 1, + MLO_0_PLUS_2_1RF = MLO_MODE_FOR_BB0_BB1_RF(0, 2, 1), + MLO_0_PLUS_2_2RF = MLO_MODE_FOR_BB0_BB1_RF(0, 2, 2), + MLO_1_PLUS_1_1RF = MLO_MODE_FOR_BB0_BB1_RF(1, 1, 1), + MLO_1_PLUS_1_2RF = MLO_MODE_FOR_BB0_BB1_RF(1, 1, 2), + MLO_2_PLUS_0_1RF = MLO_MODE_FOR_BB0_BB1_RF(2, 0, 1), + MLO_2_PLUS_0_2RF = MLO_MODE_FOR_BB0_BB1_RF(2, 0, 2), + MLO_2_PLUS_2_2RF = MLO_MODE_FOR_BB0_BB1_RF(2, 2, 2), + DBCC_LEGACY = 0xffffffff, +}; + +enum rtw89_scan_be_operation { + RTW89_SCAN_OP_STOP, + RTW89_SCAN_OP_START, + RTW89_SCAN_OP_SETPARM, + RTW89_SCAN_OP_GETRPT, + RTW89_SCAN_OP_NUM +}; + +enum rtw89_scan_be_mode { + RTW89_SCAN_MODE_SA, + RTW89_SCAN_MODE_MACC, + RTW89_SCAN_MODE_NUM +}; + +enum rtw89_scan_be_opmode { + RTW89_SCAN_OPMODE_NONE, + RTW89_SCAN_OPMODE_TBTT, + RTW89_SCAN_OPMODE_INTV, + RTW89_SCAN_OPMODE_CNT, + RTW89_SCAN_OPMODE_NUM, +}; + +struct rtw89_scan_option { + bool enable; + bool target_ch_mode; + u8 num_macc_role; + u8 num_opch; + u8 repeat; + u16 norm_pd; + u16 slow_pd; + u16 norm_cy; + u8 opch_end; + u16 delay; /* in unit of ms */ + u64 prohib_chan; + enum rtw89_phy_idx band; + enum rtw89_scan_be_operation operation; + enum rtw89_scan_be_mode scan_mode; + enum rtw89_mlo_dbcc_mode mlo_mode; +}; + +enum rtw89_qta_mode { + RTW89_QTA_SCC, + RTW89_QTA_DBCC, + RTW89_QTA_DLFW, + RTW89_QTA_WOW, + + /* keep last */ + RTW89_QTA_INVALID, +}; + +struct rtw89_hfc_ch_cfg { + u16 min; + u16 max; +#define grp_0 0 +#define grp_1 1 +#define grp_num 2 + u8 grp; +}; + +struct rtw89_hfc_ch_info { + u16 aval; + u16 used; +}; + +struct rtw89_hfc_pub_cfg { + u16 grp0; + u16 grp1; + u16 pub_max; + u16 wp_thrd; +}; + +struct rtw89_hfc_pub_info { + u16 g0_used; + u16 g1_used; + u16 g0_aval; + u16 g1_aval; + u16 pub_aval; + u16 wp_aval; +}; + +struct rtw89_hfc_prec_cfg { + u16 ch011_prec; + u16 h2c_prec; + u16 wp_ch07_prec; + u16 wp_ch811_prec; + u8 ch011_full_cond; + u8 h2c_full_cond; + u8 wp_ch07_full_cond; + u8 wp_ch811_full_cond; + /* for WiFi 7 chips after 8922D */ + u16 ch011_full_page; + u16 h2c_full_page; + u16 wp_ch07_full_page; + u16 wp_ch811_full_page; +}; + +struct rtw89_hfc_param { + bool en; + bool h2c_en; + u8 mode; + const struct rtw89_hfc_ch_cfg *ch_cfg; + struct rtw89_hfc_ch_info ch_info[RTW89_DMA_CH_NUM]; + struct rtw89_hfc_pub_cfg pub_cfg; + struct rtw89_hfc_pub_info pub_info; + struct rtw89_hfc_prec_cfg prec_cfg; +}; + +struct rtw89_hfc_param_ini { + const struct rtw89_hfc_ch_cfg *ch_cfg; + const struct rtw89_hfc_pub_cfg *pub_cfg; + const struct rtw89_hfc_prec_cfg *prec_cfg; + u8 mode; +}; + +struct rtw89_dle_size { + u16 pge_size; + u16 lnk_pge_num; + u16 unlnk_pge_num; + /* for WiFi 7 chips below (suffix v1) */ + u32 srt_ofst; +}; + +struct rtw89_wde_quota { + u16 hif; + u16 wcpu; + /* unused dcpu isn't listed */ + u16 pkt_in; + u16 cpu_io; +}; + +struct rtw89_ple_quota { + u16 cma0_tx; + u16 cma1_tx; + u16 c2h; + u16 h2c; + u16 wcpu; + u16 mpdu_proc; + u16 cma0_dma; + u16 cma1_dma; + u16 bb_rpt; + u16 wd_rel; + u16 cpu_io; + u16 tx_rpt; + /* for WiFi 7 chips below (suffix v1) */ + u16 h2d; + /* for WiFi 7 chips after 8922D (suffix v2) */ + u16 snrpt; +}; + +struct rtw89_rsvd_quota { + u16 mpdu_info_tbl; + u16 b0_csi; + u16 b1_csi; + u16 b0_lmr; + u16 b1_lmr; + u16 b0_ftm; + u16 b1_ftm; + u16 b0_smr; + u16 b1_smr; + u16 others; +}; + +struct rtw89_dle_rsvd_size { + u32 srt_ofst; + u32 size; +}; + +struct rtw89_dle_input { + u32 tx_ampdu_num_b0; + u32 tx_ampdu_num_b1; + u32 tx_amsdu_size; /* unit: KB */ + u32 h2c_max_size; + u32 rx_amsdu_size; /* unit: KB */ + u32 c2h_max_size; + u32 rls_rpt_max_size; + u32 mpdu_info_tbl_b0; + u32 mpdu_info_tbl_b1; +}; + +struct rtw89_dle_mem { + enum rtw89_qta_mode mode; + const struct rtw89_dle_size *wde_size; + const struct rtw89_dle_size *ple_size; + const struct rtw89_wde_quota *wde_min_qt; + const struct rtw89_wde_quota *wde_max_qt; + const struct rtw89_ple_quota *ple_min_qt; + const struct rtw89_ple_quota *ple_max_qt; + /* for WiFi 7 chips below */ + const struct rtw89_rsvd_quota *rsvd_qt; + const struct rtw89_dle_rsvd_size *rsvd0_size; + const struct rtw89_dle_rsvd_size *rsvd1_size; + /* for WiFi 7 chips after 8922D */ + const struct rtw89_dle_input *dle_input; +}; + +struct rtw89_reg_def { + u32 addr; + u32 mask; +}; + +struct rtw89_reg2_def { + u32 addr; + u32 data; +}; + +struct rtw89_reg3_def { + u32 addr; + u32 mask; + u32 data; +}; + +struct rtw89_reg5_def { + u8 flag; /* recognized by parsers */ + u8 path; + u32 addr; + u32 mask; + u32 data; +}; + +#define RTW89_REGS_DEF(x) {x, ARRAY_SIZE(x)} +struct rtw89_regs_def { + const u32 *regs; + u32 reg_nr; +}; + +struct rtw89_reg_imr { + u32 addr; + u32 clr; + u32 set; +}; + +#define RTW89_MODULE_FWNAME_PLACEHOLDER_0 0, +#define __RTW89_GEN_MODULE_FWNAME_FMT(placeholder_or_ignored, strfmt) \ + __take_second_arg(placeholder_or_ignored, strfmt) +#define RTW89_GEN_MODULE_FWNAME_FMT(maxfmt) \ + __RTW89_GEN_MODULE_FWNAME_FMT(RTW89_MODULE_FWNAME_PLACEHOLDER_ ## maxfmt, \ + "-" __stringify(maxfmt)) +#define RTW89_GEN_MODULE_FWNAME(basename, maxformat) \ + basename RTW89_GEN_MODULE_FWNAME_FMT(maxformat) ".bin" + +struct rtw89_fw_def { + const char *fw_basename; + u8 fw_format_max; + u16 fw_b_aid; +}; + +struct rtw89_qta_def { + const struct rtw89_hfc_param_ini *hfc_param_ini[RTW89_HCI_DLE_TYPE_NUM]; + const struct rtw89_dle_mem *dle_mem[RTW89_HCI_DLE_TYPE_NUM]; +}; + +struct rtw89_phy_table { + const struct rtw89_reg2_def *regs; + u32 n_regs; + enum rtw89_rf_path rf_path; + void (*config)(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, void *data); +}; + +struct rtw89_txpwr_table { + const void *data; + u32 size; + void (*load)(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl); +}; + +struct rtw89_txpwr_rule_2ghz { + const s8 (*lmt)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; + const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; +}; + +struct rtw89_txpwr_rule_5ghz { + const s8 (*lmt)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; + const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; +}; + +struct rtw89_txpwr_rule_6ghz { + const s8 (*lmt)[RTW89_6G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM]; + const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM]; +}; + +struct rtw89_tx_shape { + const u8 (*lmt)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM] + [NUM_OF_RTW89_REG_6GHZ_POWER]; + const u8 (*lmt_ru)[RTW89_BAND_NUM][RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER]; + + const u8 (*lmt_v0)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM]; + const u8 (*lmt_ru_v0)[RTW89_BAND_NUM][RTW89_REGD_NUM]; +}; + +struct rtw89_rfe_parms { + const struct rtw89_txpwr_table *byr_tbl; + struct rtw89_txpwr_rule_2ghz rule_2ghz; + struct rtw89_txpwr_rule_5ghz rule_5ghz; + struct rtw89_txpwr_rule_6ghz rule_6ghz; + struct rtw89_txpwr_rule_2ghz rule_da_2ghz; + struct rtw89_txpwr_rule_5ghz rule_da_5ghz; + struct rtw89_txpwr_rule_6ghz rule_da_6ghz; + struct rtw89_tx_shape tx_shape; + bool has_da; +}; + +struct rtw89_rfe_parms_conf { + const struct rtw89_rfe_parms *rfe_parms; + u8 rfe_type; +}; + +#define RTW89_TXPWR_CONF_DFLT_RFE_TYPE 0x0 + +struct rtw89_txpwr_conf { + u8 rfe_type; + u8 ent_sz; + u32 num_ents; + const void *data; +}; + +static inline bool rtw89_txpwr_entcpy(void *entry, const void *cursor, u8 size, + const struct rtw89_txpwr_conf *conf) +{ + u8 valid_size = min(size, conf->ent_sz); + + memcpy(entry, cursor, valid_size); + return true; +} + +#define rtw89_txpwr_conf_valid(conf) (!!(conf)->data) + +#define rtw89_for_each_in_txpwr_conf(entry, cursor, conf) \ + for (typecheck(const void *, cursor), (cursor) = (conf)->data; \ + (cursor) < (conf)->data + (conf)->num_ents * (conf)->ent_sz; \ + (cursor) += (conf)->ent_sz) \ + if (rtw89_txpwr_entcpy(&(entry), cursor, sizeof(entry), conf)) + +struct rtw89_txpwr_byrate_data { + struct rtw89_txpwr_conf conf; + struct rtw89_txpwr_table tbl; +}; + +struct rtw89_txpwr_lmt_2ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; +}; + +struct rtw89_txpwr_lmt_5ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; +}; + +struct rtw89_txpwr_lmt_6ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_6G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM]; +}; + +struct rtw89_txpwr_lmt_ru_2ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; +}; + +struct rtw89_txpwr_lmt_ru_5ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; +}; + +struct rtw89_txpwr_lmt_ru_6ghz_data { + struct rtw89_txpwr_conf conf; + s8 v[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM]; +}; + +struct rtw89_tx_shape_lmt_data { + struct rtw89_txpwr_conf conf; + u8 v[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM] + [NUM_OF_RTW89_REG_6GHZ_POWER]; +}; + +struct rtw89_tx_shape_lmt_ru_data { + struct rtw89_txpwr_conf conf; + u8 v[RTW89_BAND_NUM][RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER]; +}; + +struct rtw89_rfe_data { + struct rtw89_txpwr_byrate_data byrate; + struct rtw89_txpwr_lmt_2ghz_data lmt_2ghz; + struct rtw89_txpwr_lmt_5ghz_data lmt_5ghz; + struct rtw89_txpwr_lmt_6ghz_data lmt_6ghz; + struct rtw89_txpwr_lmt_2ghz_data da_lmt_2ghz; + struct rtw89_txpwr_lmt_5ghz_data da_lmt_5ghz; + struct rtw89_txpwr_lmt_6ghz_data da_lmt_6ghz; + struct rtw89_txpwr_lmt_ru_2ghz_data lmt_ru_2ghz; + struct rtw89_txpwr_lmt_ru_5ghz_data lmt_ru_5ghz; + struct rtw89_txpwr_lmt_ru_6ghz_data lmt_ru_6ghz; + struct rtw89_txpwr_lmt_ru_2ghz_data da_lmt_ru_2ghz; + struct rtw89_txpwr_lmt_ru_5ghz_data da_lmt_ru_5ghz; + struct rtw89_txpwr_lmt_ru_6ghz_data da_lmt_ru_6ghz; + struct rtw89_tx_shape_lmt_data tx_shape_lmt; + struct rtw89_tx_shape_lmt_ru_data tx_shape_lmt_ru; + struct rtw89_rfe_parms rfe_parms; +}; + +struct rtw89_page_regs { + u32 hci_fc_ctrl; + u32 ch_page_ctrl; + u32 ach_page_ctrl; + u32 ach_page_info; + u32 pub_page_info3; + u32 pub_page_ctrl1; + u32 pub_page_ctrl2; + u32 pub_page_info1; + u32 pub_page_info2; + u32 wp_page_ctrl1; + u32 wp_page_ctrl2; + u32 wp_page_info1; +}; + +struct rtw89_imr_info { + u32 wdrls_imr_set; + u32 wsec_imr_reg; + u32 wsec_imr_set; + u32 mpdu_tx_imr_set; + u32 mpdu_rx_imr_set; + u32 sta_sch_imr_set; + u32 txpktctl_imr_b0_reg; + u32 txpktctl_imr_b0_clr; + u32 txpktctl_imr_b0_set; + u32 txpktctl_imr_b1_reg; + u32 txpktctl_imr_b1_clr; + u32 txpktctl_imr_b1_set; + u32 wde_imr_clr; + u32 wde_imr_set; + u32 ple_imr_clr; + u32 ple_imr_set; + u32 host_disp_imr_clr; + u32 host_disp_imr_set; + u32 cpu_disp_imr_clr; + u32 cpu_disp_imr_set; + u32 other_disp_imr_clr; + u32 other_disp_imr_set; + u32 bbrpt_com_err_imr_reg; + u32 bbrpt_chinfo_err_imr_reg; + u32 bbrpt_err_imr_set; + u32 bbrpt_dfs_err_imr_reg; + u32 ptcl_imr_clr; + u32 ptcl_imr_set; + u32 cdma_imr_0_reg; + u32 cdma_imr_0_clr; + u32 cdma_imr_0_set; + u32 cdma_imr_1_reg; + u32 cdma_imr_1_clr; + u32 cdma_imr_1_set; + u32 phy_intf_imr_reg; + u32 phy_intf_imr_clr; + u32 phy_intf_imr_set; + u32 rmac_imr_reg; + u32 rmac_imr_clr; + u32 rmac_imr_set; + u32 tmac_imr_reg; + u32 tmac_imr_clr; + u32 tmac_imr_set; +}; + +struct rtw89_imr_table { + const struct rtw89_reg_imr *regs; + u32 n_regs; +}; + +struct rtw89_xtal_info { + u32 xcap_reg; + u32 sc_xo_mask; + u32 sc_xi_mask; +}; + +struct rtw89_rrsr_cfgs { + struct rtw89_reg3_def ref_rate; + struct rtw89_reg3_def rsc; +}; + +struct rtw89_rfkill_regs { + struct rtw89_reg3_def pinmux; + struct rtw89_reg3_def mode; +}; + +struct rtw89_sb_regs { + struct { + u32 cfg; + u32 get; + } n[2]; +}; + +struct rtw89_dig_regs { + u32 seg0_pd_reg; + u32 pd_lower_bound_mask; + u32 pd_spatial_reuse_en; + u32 bmode_pd_reg; + u32 bmode_cca_rssi_limit_en; + u32 bmode_pd_lower_bound_reg; + u32 bmode_rssi_nocca_low_th_mask; + struct rtw89_reg_def p0_lna_init; + struct rtw89_reg_def p1_lna_init; + struct rtw89_reg_def p0_tia_init; + struct rtw89_reg_def p1_tia_init; + struct rtw89_reg_def p0_rxb_init; + struct rtw89_reg_def p1_rxb_init; + struct rtw89_reg_def p0_p20_pagcugc_en; + struct rtw89_reg_def p0_s20_pagcugc_en; + struct rtw89_reg_def p1_p20_pagcugc_en; + struct rtw89_reg_def p1_s20_pagcugc_en; +}; + +struct rtw89_edcca_regs { + u32 edcca_level; + u32 edcca_mask; + u32 edcca_p_mask; + u32 ppdu_level; + u32 ppdu_mask; + struct rtw89_edcca_p_regs { + u32 rpt_a; + u32 rpt_b; + u32 rpt_sel; + u32 rpt_sel_mask; + } p[RTW89_PHY_NUM]; + u32 rpt_sel_be; + u32 rpt_sel_be_mask; + u32 tx_collision_t2r_st; + u32 tx_collision_t2r_st_mask; +}; + +struct rtw89_pmac_regs { + struct rtw89_reg_def cck_txon; + struct rtw89_reg_def cck_txen; + struct rtw89_reg_def cck_cca; + struct rtw89_reg_def cck_sfd_gg; + struct rtw89_reg_def cck_sig_gg; + struct rtw89_reg_def cck_spoofing; + struct rtw89_reg_def cck_brk; + struct rtw89_reg_def brk; + struct rtw89_reg_def brk_option; + struct rtw89_reg_def search_fail; + struct rtw89_reg_def lsig_brk_s_th; + struct rtw89_reg_def lsig_brk_l_th; + struct rtw89_reg_def rxl_err_parity; + struct rtw89_reg_def rxl_err_rate; + struct rtw89_reg_def ofdm_cca; + struct rtw89_reg_def cca_spoofing; + struct rtw89_reg_def ampdu_miss; + struct rtw89_reg_def r1b_rx_rpt_rst; + struct rtw89_reg_def r1b_rr_sel; + struct rtw89_reg_def enable_all_cnt; + struct rtw89_reg_def rst_all_cnt; + u32 cck_crc32; + u32 cck_crc32_ok_mask; + u32 cck_crc32_fail_mask; + u32 ofdm_txon; + u32 ofdm_txon_mask; + u32 ofdm_txen_mask; + u32 l_crc; + u32 l_crc_ok_mask; + u32 l_crc_err_mask; + u32 ht_crc; + u32 ht_crc_ok_mask; + u32 ht_crc_err_mask; + u32 vht_crc; + u32 vht_crc_ok_mask; + u32 vht_crc_err_mask; + u32 he_crc; + u32 he_crc_ok_mask; + u32 he_crc_err_mask; + u32 eht_crc; + u32 eht_crc_ok_mask; + u32 eht_crc_err_mask; + u32 ampdu_crc; + u32 ampdu_crc_ok_mask; + u32 ampdu_crc_err_mask; +}; + +struct rtw89_phy_ul_tb_info { + bool dyn_tb_tri_en; + u8 def_if_bandedge; +}; + +struct rtw89_antdiv_stats { + struct ewma_rssi cck_rssi_avg; + struct ewma_rssi ofdm_rssi_avg; + struct ewma_rssi non_legacy_rssi_avg; + u16 pkt_cnt_cck; + u16 pkt_cnt_ofdm; + u16 pkt_cnt_non_legacy; + u32 evm; +}; + +struct rtw89_antdiv_info { + struct rtw89_antdiv_stats target_stats; + struct rtw89_antdiv_stats main_stats; + struct rtw89_antdiv_stats aux_stats; + u8 training_count; + u8 rssi_pre; + bool get_stats; +}; + +struct rtw89_bb_stat_cfg { + bool enable; + u16 mac_id; +}; + +struct rtw89_phy_info { + const struct rtw89_bb_wrap_data *bb_wrap_data; + struct rtw89_bb_stat_cfg bb_stat_cfg; +}; + +enum rtw89_chanctx_state { + RTW89_CHANCTX_STATE_MCC_START, + RTW89_CHANCTX_STATE_MCC_STOP, +}; + +enum rtw89_chanctx_callbacks { + RTW89_CHANCTX_CALLBACK_PLACEHOLDER, + RTW89_CHANCTX_CALLBACK_RFK, + RTW89_CHANCTX_CALLBACK_TAS, + + NUM_OF_RTW89_CHANCTX_CALLBACKS, +}; + +struct rtw89_chanctx_listener { + void (*callbacks[NUM_OF_RTW89_CHANCTX_CALLBACKS]) + (struct rtw89_dev *rtwdev, enum rtw89_chanctx_state state); +}; + +#define RTW89_NHM_TH_NUM 11 +#define RTW89_NHM_RPT_NUM 12 + +#define RTW89_LED_MAX_NUM 4 + +struct rtw89_led_gpio_entry { + u8 pin; + unsigned int color; + u8 intensity; + struct rtw89_reg3_def pinmux; + struct rtw89_reg2_def mode; + struct rtw89_reg2_def out; +}; + +struct rtw89_led_desc { + const struct rtw89_led_gpio_entry *gpios; + u8 n_gpio; +}; + +struct rtw89_led { + bool registered; + const struct rtw89_led_desc *desc; + struct led_classdev led; + struct led_classdev_mc led_mc; + struct mc_subled subled[RTW89_LED_MAX_NUM]; + enum led_brightness brightness_cache[RTW89_LED_MAX_NUM]; + char name[32]; +}; + +struct rtw89_chip_info { + enum rtw89_core_chip_id chip_id; + enum rtw89_chip_gen chip_gen; + const struct rtw89_chip_ops *ops; + const struct rtw89_mac_gen_def *mac_def; + const struct rtw89_phy_gen_def *phy_def; + struct rtw89_fw_def fw_def; + bool try_ce_fw; + u8 bbmcu_nr; + u32 needed_fw_elms; + const struct rtw89_fw_blacklist *fw_blacklist; + u32 fifo_size; + bool small_fifo_size; + u32 dle_scc_rsvd_size; + u16 max_amsdu_limit; + u16 max_vht_mpdu_cap; + u16 max_eht_mpdu_cap; + u16 max_tx_agg_num; + u16 max_rx_agg_num; + bool dis_2g_40m_ul_ofdma; + u32 rsvd_ple_ofst; + struct rtw89_qta_def qta_def; + u8 wde_qempty_acq_grpnum; + u8 wde_qempty_mgq_grpsel; + u32 rf_base_addr[2]; + u8 thermal_th[2]; + u8 support_macid_num; + u8 support_link_num; + u8 support_chanctx_num; + u8 support_bands; + u16 support_bandwidths; + bool support_unii4; + bool support_rnr; + bool support_ant_gain; + bool support_tas; + bool support_sar_by_ant; + bool support_noise; + bool support_fw_cmd_ofld; + bool ul_tb_waveform_ctrl; + bool ul_tb_pwr_diff; + bool rx_freq_from_ie; + bool hw_sec_hdr; + bool hw_mgmt_tx_encrypt; + bool hw_tkip_crypto; + bool hw_mlo_bmc_crypto; + u8 rf_path_num; + u8 tx_nss; + u8 rx_nss; + u8 acam_num; + u8 bcam_num; + u8 scam_num; + u8 bacam_num; + u8 bacam_dynamic_num; + enum rtw89_bacam_ver bacam_ver; + u8 addrcam_ver; + u8 ppdu_max_usr; + + u8 sec_ctrl_efuse_size; + u32 physical_efuse_size; + u32 logical_efuse_size; + u32 limit_efuse_size; + u32 dav_phy_efuse_size; + u32 dav_log_efuse_size; + u32 phycap_addr; + u32 phycap_size; + const struct rtw89_efuse_block_cfg *efuse_blocks; + + const struct rtw89_pwr_cfg * const *pwr_on_seq; + const struct rtw89_pwr_cfg * const *pwr_off_seq; + const struct rtw89_phy_table *bb_table; + const struct rtw89_phy_table *bb_gain_table; + const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; + const struct rtw89_phy_table *nctl_table; + const struct rtw89_rfk_tbl *nctl_post_table; + const struct rtw89_phy_dig_gain_table *dig_table; + const struct rtw89_dig_regs *dig_regs; + const struct rtw89_phy_tssi_dbw_table *tssi_dbw_table; + + /* NULL if no rfe-specific, or a null-terminated array by rfe_parms */ + const struct rtw89_rfe_parms_conf *rfe_parms_conf; + const struct rtw89_rfe_parms *dflt_parms; + const struct rtw89_chanctx_listener *chanctx_listener; + + u8 txpwr_factor_bb; + u8 txpwr_factor_rf; + u8 txpwr_factor_mac; + + u32 para_ver; + u32 wlcx_desired; + u8 scbd; + u8 mailbox; + + u8 afh_guard_ch; + u16 fdd_iso_freq; + const u8 *wl_rssi_thres; + const u8 *bt_rssi_thres; + u8 rssi_tol; + + u8 mon_reg_num; + const struct rtw89_btc_fbtc_mreg *mon_reg; + const struct rtw89_btc_rf_trx_para_v0 *rf_para_ulink_v0; + const struct rtw89_btc_rf_trx_para_v0 *rf_para_dlink_v0; + u8 rf_para_ulink_num_v0; + u8 rf_para_dlink_num_v0; + const struct rtw89_btc_rf_trx_para_v9 *rf_para_ulink_v9; + const struct rtw89_btc_rf_trx_para_v9 *rf_para_dlink_v9; + u8 rf_para_ulink_num_v9; + u8 rf_para_dlink_num_v9; + u8 ps_mode_supported; + u8 low_power_hci_modes; + + u32 h2c_cctl_func_id; + u32 hci_func_en_addr; + u32 h2c_desc_size; + u32 txwd_body_size; + u32 txwd_info_size; + u32 h2c_ctrl_reg; + const u32 *h2c_regs; + struct rtw89_reg_def h2c_counter_reg; + u32 c2h_ctrl_reg; + const u32 *c2h_regs; + struct rtw89_reg_def c2h_counter_reg; + const struct rtw89_page_regs *page_regs; + const u32 *wow_reason_reg; + bool cfo_src_fd; + bool cfo_hw_comp; + const struct rtw89_reg_def *dcfo_comp; + u8 dcfo_comp_sft; + const struct rtw89_reg_def (*nhm_report)[RTW89_NHM_RPT_NUM]; + const struct rtw89_reg_def (*nhm_th)[RTW89_NHM_TH_NUM]; + const struct rtw89_imr_info *imr_info; + const struct rtw89_imr_table *imr_dmac_table; + const struct rtw89_imr_table *imr_cmac_table; + const struct rtw89_rrsr_cfgs *rrsr_cfgs; + struct rtw89_reg_def bss_clr_vld; + u32 bss_clr_map_reg; + const struct rtw89_rfkill_regs *rfkill_init; + struct rtw89_reg_def rfkill_get; + struct rtw89_sb_regs btc_sb; + u32 dma_ch_mask; + const struct rtw89_edcca_regs *edcca_regs; + const struct rtw89_pmac_regs *pmac_regs; + const struct wiphy_wowlan_support *wowlan_stub; + const struct rtw89_xtal_info *xtal_info; + unsigned long default_quirks; /* bitmap of rtw89_quirks */ + u16 txtime_limit_2ghz; +}; + +struct rtw89_chip_variant { + bool no_mcs_12_13: 1; + u32 fw_min_ver_code; + const struct rtw89_fw_def *fw_def_override; + const struct rtw89_qta_def *qta_def_override; +}; + +struct rtw89_board_variant { + const struct rtw89_led_desc *led_desc; +}; + +union rtw89_bus_info { + const struct rtw89_pci_info *pci; + const struct rtw89_usb_info *usb; +}; + +struct rtw89_driver_info { + const struct rtw89_chip_info *chip; + const struct rtw89_chip_variant *variant; + const struct rtw89_board_variant *board; + const struct dmi_system_id *quirks; + unsigned long dev_id_quirks; /* bitmap of rtw89_quirks */ + union rtw89_bus_info bus; +}; + +enum rtw89_hcifc_mode { + RTW89_HCIFC_POH = 0, + RTW89_HCIFC_STF = 1, + RTW89_HCIFC_SDIO = 2, + + /* keep last */ + RTW89_HCIFC_MODE_INVALID, +}; + +struct rtw89_dle_info { + const struct rtw89_rsvd_quota *rsvd_qt; + const struct rtw89_dle_input *dle_input; + enum rtw89_qta_mode qta_mode; + u16 ple_pg_size; + u16 ple_free_pg; + u16 c0_rx_qta; + u16 c1_rx_qta; +}; + +enum rtw89_host_rpr_mode { + RTW89_RPR_MODE_POH = 0, + RTW89_RPR_MODE_STF +}; + +#define RTW89_COMPLETION_BUF_SIZE 40 +#define RTW89_WAIT_COND_IDLE UINT_MAX + +struct rtw89_completion_data { + bool err; + u8 buf[RTW89_COMPLETION_BUF_SIZE]; +}; + +struct rtw89_wait_response { + struct rcu_head rcu_head; + struct completion completion; + struct rtw89_completion_data data; +}; + +struct rtw89_wait_info { + atomic_t cond; + struct rtw89_completion_data data; + struct rtw89_wait_response __rcu *resp; +}; + +#define RTW89_WAIT_FOR_COND_TIMEOUT msecs_to_jiffies(100) + +static inline void rtw89_init_wait(struct rtw89_wait_info *wait) +{ + rcu_assign_pointer(wait->resp, NULL); + atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); +} + +struct rtw89_mac_info { + struct rtw89_dle_info dle_info; + struct rtw89_hfc_param hfc_param; + enum rtw89_qta_mode qta_mode; + u8 rpwm_seq_num; + u8 cpwm_seq_num; + + /* see RTW89_FW_OFLD_WAIT_COND series for wait condition */ + struct rtw89_wait_info fw_ofld_wait; + /* see RTW89_PS_WAIT_COND series for wait condition */ + struct rtw89_wait_info ps_wait; +}; + +enum rtw89_fwdl_check_type { + RTW89_FWDL_CHECK_FREERTOS_DONE, + RTW89_FWDL_CHECK_WCPU_FWDL_DONE, + RTW89_FWDL_CHECK_DCPU_FWDL_DONE, + RTW89_FWDL_CHECK_BB0_FWDL_DONE, + RTW89_FWDL_CHECK_BB1_FWDL_DONE, +}; + +enum rtw89_fw_type { + RTW89_FW_NORMAL = 1, + RTW89_FW_WOWLAN = 3, + RTW89_FW_NORMAL_CE = 5, + RTW89_FW_NORMAL_B = 14, + RTW89_FW_WOWLAN_B = 15, + RTW89_FW_BBMCU0 = 64, + RTW89_FW_BBMCU1 = 65, + RTW89_FW_LOGFMT = 255, +}; + +#define RTW89_FW_FEATURE_GROUP(_grp, _features...) \ + RTW89_FW_FEATURE_##_grp##_MIN, \ + __RTW89_FW_FEATURE_##_grp##_S = RTW89_FW_FEATURE_##_grp##_MIN - 1, \ + _features \ + __RTW89_FW_FEATURE_##_grp##_E, \ + RTW89_FW_FEATURE_##_grp##_MAX = __RTW89_FW_FEATURE_##_grp##_E - 1 + +enum rtw89_fw_feature { + RTW89_FW_FEATURE_OLD_HT_RA_FORMAT, + RTW89_FW_FEATURE_SCAN_OFFLOAD, + RTW89_FW_FEATURE_TX_WAKE, + RTW89_FW_FEATURE_GROUP(CRASH_TRIGGER, + RTW89_FW_FEATURE_CRASH_TRIGGER_TYPE_0, + RTW89_FW_FEATURE_CRASH_TRIGGER_TYPE_1, + ), + RTW89_FW_FEATURE_NO_PACKET_DROP, + RTW89_FW_FEATURE_NO_DEEP_PS, + RTW89_FW_FEATURE_NO_LPS_PG, + RTW89_FW_FEATURE_BEACON_FILTER, + RTW89_FW_FEATURE_MACID_PAUSE_SLEEP, + RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0, + RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V1, + RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V2, + RTW89_FW_FEATURE_WOW_REASON_V1, + RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V3, + ), + RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V0, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V1, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V2, + ), + RTW89_FW_FEATURE_RFK_RXDCK_V0, + RTW89_FW_FEATURE_RFK_IQK_V0, + RTW89_FW_FEATURE_RFK_TXIQK_V0, + RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX, + RTW89_FW_FEATURE_NOTIFY_AP_INFO, + RTW89_FW_FEATURE_CH_INFO_BE_V0, + RTW89_FW_FEATURE_LPS_CH_INFO, + RTW89_FW_FEATURE_NO_PHYCAP_P1, + RTW89_FW_FEATURE_NO_POWER_DIFFERENCE, + RTW89_FW_FEATURE_BEACON_LOSS_COUNT_V1, + RTW89_FW_FEATURE_SCAN_OFFLOAD_EXTRA_OP, + RTW89_FW_FEATURE_RFK_NTFY_MCC_V0, + RTW89_FW_FEATURE_LPS_DACK_BY_C2H_REG, + RTW89_FW_FEATURE_BEACON_TRACKING, + RTW89_FW_FEATURE_ADDR_CAM_V0, + RTW89_FW_FEATURE_SER_L1_BY_EVENT, + RTW89_FW_FEATURE_SIM_SER_L0L1_BY_HALT_H2C, + RTW89_FW_FEATURE_LPS_ML_INFO_V1, + RTW89_FW_FEATURE_SER_POST_RECOVER_DMAC, + RTW89_FW_FEATURE_TX_HISTORY_V1, + + NUM_OF_RTW89_FW_FEATURES, +}; + +struct rtw89_fw_suit { + enum rtw89_fw_type type; + const u8 *data; + u32 size; + u8 major_ver; + u8 minor_ver; + u8 sub_ver; + u8 sub_idex; + u16 build_year; + u16 build_mon; + u16 build_date; + u16 build_hour; + u16 build_min; + u8 cmd_ver; + u8 hdr_ver; + u32 commitid; +}; + +#define RTW89_FW_VER_CODE(major, minor, sub, idx) \ + (((major) << 24) | ((minor) << 16) | ((sub) << 8) | (idx)) +#define RTW89_FW_SUIT_VER_CODE(s) \ + RTW89_FW_VER_CODE((s)->major_ver, (s)->minor_ver, (s)->sub_ver, (s)->sub_idex) + +#define RTW89_MFW_HDR_VER_CODE(mfw_hdr) \ + RTW89_FW_VER_CODE((mfw_hdr)->ver.major, \ + (mfw_hdr)->ver.minor, \ + (mfw_hdr)->ver.sub, \ + (mfw_hdr)->ver.idx) + +#define RTW89_FW_HDR_VER_CODE(fw_hdr) \ + RTW89_FW_VER_CODE(le32_get_bits((fw_hdr)->w1, FW_HDR_W1_MAJOR_VERSION), \ + le32_get_bits((fw_hdr)->w1, FW_HDR_W1_MINOR_VERSION), \ + le32_get_bits((fw_hdr)->w1, FW_HDR_W1_SUBVERSION), \ + le32_get_bits((fw_hdr)->w1, FW_HDR_W1_SUBINDEX)) + +struct rtw89_fw_req_info { + const struct firmware *firmware; + struct completion completion; +}; + +struct rtw89_fw_log { + struct rtw89_fw_suit suit; + bool enable; + u32 last_fmt_id; + u32 fmt_count; + const __le32 *fmt_ids; + const char *(*fmts)[]; +}; + +struct rtw89_fw_elm_info { + struct rtw89_phy_table *bb_tbl; + struct rtw89_phy_table *bb_gain; + struct rtw89_phy_table *rf_radio[RF_PATH_MAX]; + struct rtw89_phy_table *rf_nctl; + struct rtw89_fw_txpwr_track_cfg *txpwr_trk; + struct rtw89_phy_rfk_log_fmt *rfk_log_fmt; + const struct rtw89_regd_data *regd; + const struct rtw89_fw_element_hdr *afe; + const struct rtw89_fw_element_hdr *diag_mac; + const struct rtw89_fw_element_hdr *tx_comp; +}; + +enum rtw89_fw_mss_dev_type { + RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF = 0xF, + RTW89_FW_MSS_DEV_TYPE_FWSEC_INV = 0xFF, +}; + +struct rtw89_fw_secure { + bool secure_boot: 1; + bool can_mss_v1: 1; + bool can_mss_v0: 1; + u32 sb_sel_mgn; + u8 mss_dev_type; + u8 mss_cust_idx; + u8 mss_key_num; + u8 mss_idx; /* v0 */ +}; + +struct rtw89_fw_info { + struct rtw89_fw_req_info req; + int fw_format; + u8 h2c_seq; + u8 rec_seq; + u8 h2c_counter; + u8 c2h_counter; + struct rtw89_fw_suit normal; + struct rtw89_fw_suit wowlan; + struct rtw89_fw_suit bbmcu0; + struct rtw89_fw_suit bbmcu1; + struct rtw89_fw_log log; + struct rtw89_fw_elm_info elm_info; + struct rtw89_fw_secure sec; + + DECLARE_BITMAP(feature_map, NUM_OF_RTW89_FW_FEATURES); +}; + +#define RTW89_CHK_FW_FEATURE(_feat, _fw) \ + test_bit(RTW89_FW_FEATURE_ ## _feat, (_fw)->feature_map) + +#define RTW89_CHK_FW_FEATURE_GROUP(_grp, _fw) \ +({ \ + unsigned int bit = find_next_bit((_fw)->feature_map, \ + NUM_OF_RTW89_FW_FEATURES, \ + RTW89_FW_FEATURE_ ## _grp ## _MIN); \ + bit <= RTW89_FW_FEATURE_ ## _grp ## _MAX; \ +}) + +#define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \ + set_bit(_fw_feature, (_fw)->feature_map) + +#define RTW89_CLR_FW_FEATURE(_fw_feature, _fw) \ + clear_bit(_fw_feature, (_fw)->feature_map) + +struct rtw89_cam_info { + DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); + DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); + DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM); + DECLARE_BITMAP(ba_cam_map, RTW89_MAX_BA_CAM_NUM); + struct rtw89_ba_cam_entry ba_cam_entry[RTW89_MAX_BA_CAM_NUM]; + const struct rtw89_sec_cam_entry *sec_entries[RTW89_MAX_SEC_CAM_NUM]; +}; + +enum rtw89_sar_sources { + RTW89_SAR_SOURCE_NONE, + RTW89_SAR_SOURCE_COMMON, + RTW89_SAR_SOURCE_ACPI, + + RTW89_SAR_SOURCE_NR, +}; + +enum rtw89_sar_subband { + RTW89_SAR_2GHZ_SUBBAND, + RTW89_SAR_5GHZ_SUBBAND_1_2, /* U-NII-1 and U-NII-2 */ + RTW89_SAR_5GHZ_SUBBAND_2_E, /* U-NII-2-Extended */ + RTW89_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */ + RTW89_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */ + RTW89_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */ + RTW89_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */ + RTW89_SAR_6GHZ_SUBBAND_7_L, /* U-NII-7 lower part */ + RTW89_SAR_6GHZ_SUBBAND_7_H, /* U-NII-7 higher part */ + RTW89_SAR_6GHZ_SUBBAND_8, /* U-NII-8 */ + + RTW89_SAR_SUBBAND_NR, +}; + +struct rtw89_sar_cfg_common { + bool set[RTW89_SAR_SUBBAND_NR]; + s32 cfg[RTW89_SAR_SUBBAND_NR]; +}; + +enum rtw89_acpi_sar_subband { + RTW89_ACPI_SAR_2GHZ_SUBBAND, + RTW89_ACPI_SAR_5GHZ_SUBBAND_1, /* U-NII-1 */ + RTW89_ACPI_SAR_5GHZ_SUBBAND_2, /* U-NII-2 */ + RTW89_ACPI_SAR_5GHZ_SUBBAND_2E, /* U-NII-2-Extended */ + RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L, /* U-NII-7 lower part */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H, /* U-NII-7 higher part */ + RTW89_ACPI_SAR_6GHZ_SUBBAND_8, /* U-NII-8 */ + + NUM_OF_RTW89_ACPI_SAR_SUBBAND, + RTW89_ACPI_SAR_SUBBAND_NR_LEGACY = RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4 + 1, + RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ = RTW89_ACPI_SAR_6GHZ_SUBBAND_8 + 1, +}; + +#define TXPWR_FACTOR_OF_RTW89_ACPI_SAR 3 /* unit: 0.125 dBm */ +#define MAX_VAL_OF_RTW89_ACPI_SAR S16_MAX +#define MIN_VAL_OF_RTW89_ACPI_SAR S16_MIN +#define MAX_NUM_OF_RTW89_ACPI_SAR_TBL 6 +#define NUM_OF_RTW89_ACPI_SAR_RF_PATH (RF_PATH_B + 1) + +struct rtw89_sar_entry_from_acpi { + s16 v[NUM_OF_RTW89_ACPI_SAR_SUBBAND][NUM_OF_RTW89_ACPI_SAR_RF_PATH]; +}; + +struct rtw89_sar_table_from_acpi { + /* If this table is active, must fill all fields according to either + * configuration in BIOS or some default values for SAR to work well. + */ + struct rtw89_sar_entry_from_acpi entries[RTW89_REGD_NUM]; +}; + +struct rtw89_sar_indicator_from_acpi { + bool enable_sync; + unsigned int fields; + u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath); + + /* Select among @tables of container, rtw89_sar_cfg_acpi, by path. + * Not design with pointers since addresses will be invalid after + * sync content with local container instance. + */ + u8 tblsel[NUM_OF_RTW89_ACPI_SAR_RF_PATH]; +}; + +struct rtw89_sar_cfg_acpi { + u8 downgrade_2tx; + unsigned int valid_num; + struct rtw89_sar_table_from_acpi tables[MAX_NUM_OF_RTW89_ACPI_SAR_TBL]; + struct rtw89_sar_indicator_from_acpi indicator; +}; + +struct rtw89_sar_info { + /* used to decide how to access SAR cfg union */ + enum rtw89_sar_sources src; + + /* reserved for different knids of SAR cfg struct. + * supposed that a single cfg struct cannot handle various SAR sources. + */ + union { + struct rtw89_sar_cfg_common cfg_common; + struct rtw89_sar_cfg_acpi cfg_acpi; + }; +}; + +enum rtw89_ant_gain_subband { + RTW89_ANT_GAIN_2GHZ_SUBBAND, + RTW89_ANT_GAIN_5GHZ_SUBBAND_1, /* U-NII-1 */ + RTW89_ANT_GAIN_5GHZ_SUBBAND_2, /* U-NII-2 */ + RTW89_ANT_GAIN_5GHZ_SUBBAND_2E, /* U-NII-2-Extended */ + RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_6, /* U-NII-6 */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L, /* U-NII-7 lower part */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H, /* U-NII-7 higher part */ + RTW89_ANT_GAIN_6GHZ_SUBBAND_8, /* U-NII-8 */ + + RTW89_ANT_GAIN_SUBBAND_NR, +}; + +enum rtw89_ant_gain_domain_type { + RTW89_ANT_GAIN_ETSI = 0, + + RTW89_ANT_GAIN_DOMAIN_NUM, +}; + +#define RTW89_ANT_GAIN_CHAIN_NUM 2 +struct rtw89_ant_gain_info { + s8 offset[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR]; + u32 regd_enabled; + bool block_country; +}; + +struct rtw89_6ghz_span { + enum rtw89_sar_subband sar_subband_low; + enum rtw89_sar_subband sar_subband_high; + enum rtw89_acpi_sar_subband acpi_sar_subband_low; + enum rtw89_acpi_sar_subband acpi_sar_subband_high; + enum rtw89_ant_gain_subband ant_gain_subband_low; + enum rtw89_ant_gain_subband ant_gain_subband_high; +}; + +#define RTW89_SAR_SPAN_VALID(span) ((span)->sar_subband_high) +#define RTW89_ACPI_SAR_SPAN_VALID(span) ((span)->acpi_sar_subband_high) +#define RTW89_ANT_GAIN_SPAN_VALID(span) ((span)->ant_gain_subband_high) + +enum rtw89_tas_state { + RTW89_TAS_STATE_DPR_OFF, + RTW89_TAS_STATE_DPR_ON, + RTW89_TAS_STATE_STATIC_SAR, +}; + +#define RTW89_TAS_TX_RATIO_WINDOW 6 +#define RTW89_TAS_TXPWR_WINDOW 180 +struct rtw89_tas_info { + u16 tx_ratio_history[RTW89_TAS_TX_RATIO_WINDOW]; + u64 txpwr_history[RTW89_TAS_TXPWR_WINDOW]; + u8 enabled_countries; + u8 txpwr_head_idx; + u8 txpwr_tail_idx; + u8 tx_ratio_idx; + u16 total_tx_ratio; + u64 total_txpwr; + u64 instant_txpwr; + u32 window_size; + s8 dpr_on_threshold; + s8 dpr_off_threshold; + enum rtw89_tas_state backup_state; + enum rtw89_tas_state state; + bool keep_history; + bool block_regd; + bool enable; + bool pause; +}; + +struct rtw89_chanctx_cfg { + enum rtw89_chanctx_idx idx; + int ref_count; +}; + +enum rtw89_chanctx_changes { + RTW89_CHANCTX_REMOTE_STA_CHANGE, + RTW89_CHANCTX_BCN_OFFSET_CHANGE, + RTW89_CHANCTX_P2P_PS_CHANGE, + RTW89_CHANCTX_BT_SLOT_CHANGE, + RTW89_CHANCTX_TSF32_TOGGLE_CHANGE, + + NUM_OF_RTW89_CHANCTX_CHANGES, + RTW89_CHANCTX_CHANGE_DFLT = NUM_OF_RTW89_CHANCTX_CHANGES, +}; + +enum rtw89_entity_mode { + RTW89_ENTITY_MODE_SCC_OR_SMLD, + RTW89_ENTITY_MODE_MCC_PREPARE, + RTW89_ENTITY_MODE_MCC, + + NUM_OF_RTW89_ENTITY_MODE, + RTW89_ENTITY_MODE_INVALID = -EINVAL, + RTW89_ENTITY_MODE_UNHANDLED = -ESRCH, +}; + +#define RTW89_MAX_INTERFACE_NUM 2 + +/* only valid when running with chanctx_ops */ +struct rtw89_entity_mgnt { + struct list_head active_list; + struct rtw89_vif *active_roles[RTW89_MAX_INTERFACE_NUM]; + enum rtw89_chanctx_idx chanctx_tbl[RTW89_MAX_INTERFACE_NUM] + [__RTW89_MLD_MAX_LINK_NUM]; +}; + +struct rtw89_chanctx { + struct cfg80211_chan_def chandef; + struct rtw89_chan chan; + struct rtw89_chan_rcd rcd; + + /* only assigned when running with chanctx_ops */ + struct rtw89_chanctx_cfg *cfg; +}; + +struct rtw89_edcca_bak { + u8 a; + u8 p; + u8 ppdu; + u8 th_old; +}; + +enum rtw89_dm_type { + RTW89_DM_DYNAMIC_EDCCA, + RTW89_DM_THERMAL_PROTECT, + RTW89_DM_TAS, + RTW89_DM_MLO, + RTW89_DM_HW_SCAN, + RTW89_DM_INACTIVE_PS, + RTW89_DM_DIG_PD, + RTW89_DM_VCORE, +}; + +#define RTW89_THERMAL_PROT_LV_MAX 5 +#define RTW89_THERMAL_PROT_STEP 5 /* -5% for each level */ +#define RTW89_THERMAL_PROT_VLV_MAX 6 +#define RTW89_THERMAL_PROT_VLV_TH_OFFSET 20 + +struct rtw89_hal { + u32 rx_fltr; + u8 cv; + u8 cid; /* enum rtw89_core_chip_cid */ + u8 acv; + u16 aid; /* enum rtw89_core_chip_aid */ + u32 antenna_tx; + u32 antenna_rx; + u8 tx_nss; + u8 rx_nss; + bool tx_path_diversity; + bool ant_diversity; + bool ant_diversity_fixed; + bool support_cckpd; + bool support_igi; + bool no_mcs_12_13; + bool no_eht; + + atomic_t roc_chanctx_idx; + + DECLARE_BITMAP(changes, NUM_OF_RTW89_CHANCTX_CHANGES); + DECLARE_BITMAP(entity_map, NUM_OF_RTW89_CHANCTX); + struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX]; + struct cfg80211_chan_def roc_chandef; + + bool entity_active[RTW89_PHY_NUM]; + bool entity_pause; + enum rtw89_entity_mode entity_mode; + struct rtw89_entity_mgnt entity_mgnt; + + enum rtw89_phy_idx entity_force_hw; + + u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */ + + u8 thermal_prot_th; + u8 thermal_prot_lv; /* 0 ~ RTW89_THERMAL_PROT_LV_MAX */ + + u8 thermal_prot_vmax; + u8 thermal_prot_vmin; + u8 thermal_prot_vlv; /* 0 ~ RTW89_THERMAL_PROT_VLV_MAX (6) */ + + u8 fixed_dig_pd_th; /* v = (X(dBm) + 102)/2 */ + s8 fixed_dig_cck_pd_th; /* dBm */ +}; + +#define RTW89_MAX_MAC_ID_NUM 128 +#define RTW89_MAX_PKT_OFLD_NUM 255 + +enum rtw89_flags { + RTW89_FLAG_POWERON, + RTW89_FLAG_DMAC_FUNC, + RTW89_FLAG_CMAC0_FUNC, + RTW89_FLAG_CMAC1_FUNC, + RTW89_FLAG_CMAC0_PWR, + RTW89_FLAG_CMAC1_PWR, + RTW89_FLAG_FW_RDY, + RTW89_FLAG_RUNNING, + RTW89_FLAG_PROBE_DONE, + RTW89_FLAG_BFEE_MON, + RTW89_FLAG_BFEE_EN, + RTW89_FLAG_BFEE_TIMER_KEEP, + RTW89_FLAG_NAPI_RUNNING, + RTW89_FLAG_LEISURE_PS, + RTW89_FLAG_LOW_POWER_MODE, + RTW89_FLAG_INACTIVE_PS, + RTW89_FLAG_CRASH_SIMULATING, + RTW89_FLAG_SER_HANDLING, + RTW89_FLAG_WOWLAN, + RTW89_FLAG_FORBIDDEN_TRACK_WORK, + RTW89_FLAG_CHANGING_INTERFACE, + RTW89_FLAG_HW_RFKILL_STATE, + RTW89_FLAG_UNPLUGGED, + RTW89_FLAG_SHUTDOWN, + + NUM_OF_RTW89_FLAGS, +}; + +enum rtw89_quirks { + RTW89_QUIRK_PCI_BER, + RTW89_QUIRK_THERMAL_PROT_120C, + RTW89_QUIRK_THERMAL_PROT_110C, + RTW89_QUIRK_HW_INFO_SYSFS, + RTW89_QUIRK_DISABLE_2GHZ, + + NUM_OF_RTW89_QUIRKS, +}; + +enum rtw89_custid { + RTW89_CUSTID_NONE = 0, + RTW89_CUSTID_HP = 1, + RTW89_CUSTID_ASUS = 2, + RTW89_CUSTID_ACER = 3, + RTW89_CUSTID_LENOVO = 4, + RTW89_CUSTID_NEC = 5, + RTW89_CUSTID_AMD = 6, + RTW89_CUSTID_FUJITSU = 7, + RTW89_CUSTID_DELL = 8, +}; + +enum rtw89_pkt_drop_sel { + RTW89_PKT_DROP_SEL_MACID_BE_ONCE, + RTW89_PKT_DROP_SEL_MACID_BK_ONCE, + RTW89_PKT_DROP_SEL_MACID_VI_ONCE, + RTW89_PKT_DROP_SEL_MACID_VO_ONCE, + RTW89_PKT_DROP_SEL_MACID_ALL, + RTW89_PKT_DROP_SEL_MG0_ONCE, + RTW89_PKT_DROP_SEL_HIQ_ONCE, + RTW89_PKT_DROP_SEL_HIQ_PORT, + RTW89_PKT_DROP_SEL_HIQ_MBSSID, + RTW89_PKT_DROP_SEL_BAND, + RTW89_PKT_DROP_SEL_BAND_ONCE, + RTW89_PKT_DROP_SEL_REL_MACID, + RTW89_PKT_DROP_SEL_REL_HIQ_PORT, + RTW89_PKT_DROP_SEL_REL_HIQ_MBSSID, +}; + +struct rtw89_pkt_drop_params { + enum rtw89_pkt_drop_sel sel; + enum rtw89_mac_idx mac_band; + u8 macid; + u8 port; + u8 mbssid; + bool tf_trs; + u32 macid_band_sel[4]; +}; + +struct rtw89_pkt_stat { + u16 beacon_nr; + u8 beacon_rate; + u32 beacon_len; + u32 rx_rate_cnt[RTW89_HW_RATE_NR]; + struct { + u32 ldpc; + u32 bcc; + u32 stbc; + u32 su_bf; + u32 su_non_bf; + u32 mu; + } rx; +}; + +#define RTW89_BCN_TRACK_STAT_NR 32 +#define RTW89_BCN_TRACK_SCALE_FACTOR 10 +#define RTW89_BCN_TRACK_MAX_BIN_NUM 6 +#define RTW89_BCN_TRACK_BIN_WIDTH 5 +#define RTW89_BCN_TRACK_TARGET_BCN 80 + +struct rtw89_beacon_dist { + u16 min; + u16 max; + u16 outlier_count; + u16 lower_bound; + u16 upper_bound; + u16 bins[RTW89_BCN_TRACK_MAX_BIN_NUM]; +}; + +struct rtw89_beacon_stat { + u8 num; + u8 wp; + u16 tbtt_tu_min; + u16 tbtt_tu_max; + u16 drift[RTW89_BCN_TRACK_STAT_NR]; + u32 tbtt_us[RTW89_BCN_TRACK_STAT_NR]; + u16 tbtt_tu[RTW89_BCN_TRACK_STAT_NR]; + struct rtw89_beacon_dist bcn_dist; +}; + +DECLARE_EWMA(thermal, 4, 4); +DECLARE_EWMA(path_diff, 4, 2); + +struct rtw89_phy_path_diff { + struct ewma_path_diff avg; + u8 raw; + bool bf_smo_en; + u8 link_mode; +}; + +#define RTW89_TX_RATE_NR 40 +struct rtw89_phy_stat { + struct ewma_thermal avg_thermal[RF_PATH_MAX]; + u8 last_thermal_max; + u32 tx_rate_cnt[RTW89_TX_RATE_NR]; + struct rtw89_beacon_stat bcn_stat; +}; + +enum rtw89_rfk_report_state { + RTW89_RFK_STATE_START = 0x0, + RTW89_RFK_STATE_OK = 0x1, + RTW89_RFK_STATE_FAIL = 0x2, + RTW89_RFK_STATE_TIMEOUT = 0x3, + RTW89_RFK_STATE_H2C_CMD_ERR = 0x4, +}; + +enum rtw89_rfk_report_types { + RTW89_RFK_REPORT_PRE_NTFY, + RTW89_RFK_REPORT_TSSI, + RTW89_RFK_REPORT_IQK, + RTW89_RFK_REPORT_DPK, + RTW89_RFK_REPORT_TXGAPK, + RTW89_RFK_REPORT_DACK, + RTW89_RFK_REPORT_RX_DCK, + RTW89_RFK_REPORT_TX_IQK, + RTW89_RFK_REPORT_CIM3k, + + NUM_OF_RTW89_RFK_REPORT_TYPES, +}; + +#define RTW89_RFK_RECORD_PATH_NR 2 +#define RTW89_RFK_RECORD_HISTORY_NR 10 + +struct rtw89_rfk_record { + u32 ch[RTW89_RFK_RECORD_PATH_NR]; + u32 cv[RTW89_RFK_RECORD_PATH_NR]; + u32 c5[RTW89_RFK_RECORD_PATH_NR]; + enum rtw89_phy_idx phy_idx; + enum rtw89_rfk_report_state states[NUM_OF_RTW89_RFK_REPORT_TYPES]; +}; + +struct rtw89_rfk_wait_info { + struct completion completion; + ktime_t start_time; + enum rtw89_rfk_report_state state; + u8 version; + + int record_idx; + struct rtw89_rfk_record *record_ptr; + struct rtw89_rfk_record records[RTW89_RFK_RECORD_HISTORY_NR]; + + int record_tssi_idx; + u32 tssi_code[RTW89_RFK_RECORD_HISTORY_NR][RTW89_RFK_RECORD_PATH_NR]; +}; + +#define RTW89_DACK_PATH_NR 2 +#define RTW89_DACK_IDX_NR 2 +#define RTW89_DACK_MSBK_NR 16 +struct rtw89_dack_info { + bool dack_done; + u8 msbk_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR][RTW89_DACK_MSBK_NR]; + u8 dadck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; + u16 addck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; + u16 biask_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; + u32 dack_cnt; + bool addck_timeout[RTW89_DACK_PATH_NR]; + bool dadck_timeout[RTW89_DACK_PATH_NR]; + bool msbk_timeout[RTW89_DACK_PATH_NR]; +}; + +enum rtw89_rfk_chs_nrs { + __RTW89_RFK_CHS_NR_V0 = 2, + __RTW89_RFK_CHS_NR_V1 = 3, + + RTW89_RFK_CHS_NR = __RTW89_RFK_CHS_NR_V1, +}; + +struct rtw89_rfk_mcc_info_data { + u8 ch[RTW89_RFK_CHS_NR]; + u8 band[RTW89_RFK_CHS_NR]; + u8 bw[RTW89_RFK_CHS_NR]; + u32 rf18[RTW89_RFK_CHS_NR]; + u8 table_idx; +}; + +struct rtw89_rfk_mcc_info { + struct rtw89_rfk_mcc_info_data data[2]; +}; + +#define RTW89_IQK_CHS_NR 2 +#define RTW89_IQK_PATH_NR 4 + +struct rtw89_lck_info { + u8 thermal[RF_PATH_MAX]; +}; + +struct rtw89_rx_dck_info { + u8 thermal[RF_PATH_MAX]; +}; + +struct rtw89_iqk_info { + bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + bool lok_fail[RTW89_IQK_PATH_NR]; + bool iqk_tx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + bool iqk_rx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + u32 iqk_fail_cnt; + bool is_iqk_init; + u32 iqk_channel[RTW89_IQK_CHS_NR]; + u8 iqk_band[RTW89_IQK_PATH_NR]; + u8 iqk_ch[RTW89_IQK_PATH_NR]; + u8 iqk_bw[RTW89_IQK_PATH_NR]; + u8 iqk_times; + u8 version; + u32 nb_txcfir[RTW89_IQK_PATH_NR]; + u32 nb_rxcfir[RTW89_IQK_PATH_NR]; + u32 bp_txkresult[RTW89_IQK_PATH_NR]; + u32 bp_rxkresult[RTW89_IQK_PATH_NR]; + u32 bp_iqkenable[RTW89_IQK_PATH_NR]; + bool is_wb_txiqk[RTW89_IQK_PATH_NR]; + bool is_wb_rxiqk[RTW89_IQK_PATH_NR]; + bool is_nbiqk; + bool iqk_fft_en; + bool iqk_xym_en; + bool iqk_sram_en; + bool iqk_cfir_en; + u32 syn1to2; + u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + u8 iqk_table_idx[RTW89_IQK_PATH_NR]; + u32 lok_idac[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + u32 lok_vbuf[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + u32 iqc_bak[2]; +}; + +#define RTW89_DPK_RF_PATH 2 +#define RTW89_DPK_AVG_THERMAL_NUM 8 +#define RTW89_DPK_BKUP_NUM 2 +struct rtw89_dpk_bkup_para { + enum rtw89_band band; + enum rtw89_bandwidth bw; + u8 ch; + u8 path_ok; + u8 mdpd_en; + u8 txagc_dpk; + u8 ther_dpk; + u8 gs; + u16 pwsf; +}; + +struct rtw89_dpk_info { + bool is_dpk_enable; + bool is_dpk_reload_en; + u8 dpk_gs[RTW89_PHY_NUM]; + u16 dc_i[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; + u16 dc_q[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; + u8 corr_val[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; + u8 corr_idx[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; + u8 cur_idx[RTW89_DPK_RF_PATH]; + u8 cur_k_set; + struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; + u8 max_dpk_txagc[RTW89_DPK_RF_PATH]; + u32 dpk_order[RTW89_DPK_RF_PATH]; +}; + +struct rtw89_fem_info { + bool elna_2g; + bool elna_5g; + bool epa_2g; + bool epa_5g; + bool epa_6g; +}; + +struct rtw89_phy_ch_info { + u8 rssi_min; + u16 rssi_min_macid; + u8 pre_rssi_min; + u8 rssi_max; + u16 rssi_max_macid; + u8 rxsc_160; + u8 rxsc_80; + u8 rxsc_40; + u8 rxsc_20; + u8 rxsc_l; + u8 is_noisy; +}; + +struct rtw89_pmac_stat_info { + u32 cck_phy_txon; + u32 cck_mac_txen; + u32 ofdm_mac_txen; + u32 ofdm_phy_txon; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_cck_spoofing; + u32 cnt_ofdm_spoofing; + u32 cnt_ampdu_miss; + u32 cnt_ampdu_crc_error; + u32 cnt_ampdu_crc_ok; + u32 cnt_cck_crc32_error; + u32 cnt_cck_crc32_ok; + u32 cnt_ofdm_crc32_error; + u32 cnt_ofdm_crc32_ok; + u32 cnt_ht_crc32_error; + u32 cnt_ht_crc32_ok; + u32 cnt_vht_crc32_error; + u32 cnt_vht_crc32_ok; + u32 cnt_he_crc32_ok; + u32 cnt_he_crc32_error; + u32 cnt_eht_crc32_ok; + u32 cnt_eht_crc32_error; + u32 cnt_crc32_error_all; + u32 cnt_crc32_ok_all; + u32 cnt_sfd_gg; + u32 cnt_sig_gg; + u32 cnt_cck_fail; + u32 cnt_ofdm_fail; + u32 cnt_fail_all; + u32 cnt_lsig_brk_s_th; + u32 cnt_lsig_brk_l_th; + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_sb_search_fail; +}; + +struct rtw89_tx_stat_info { + u32 info[6]; + u32 common_ctrl[2]; + u32 txpwr[2]; + u8 type; + u8 subtype; + u8 txcmd; + u8 txsc; + u8 bw; + u16 tmac_txpwr; + u8 tx_path_en; + u8 path_map; + u8 max_mcs; + bool stbc; +}; + +enum rtw89_diag_bb_type { + RTW89_DIAG_BB_HANG, + RTW89_DIAG_BB_PD, + RTW89_DIAG_BB_NO_RX, + RTW89_DIAG_BB_FA, + RTW89_DIAG_BB_EDCCA, + + RTW89_DIAG_BB_NR, +}; + +struct rtw89_diag_bb { + u32 diag_bb_bitmap; /* bitmap of enum rtw89_diag_bb_type */ + u32 diag_bb_cnt[RTW89_DIAG_BB_NR]; + u16 consecutive_no_tx_cnt; + u16 consecutive_no_rx_cnt; +}; + +struct rtw89_agc_gaincode_set { + u8 lna_idx; + u8 tia_idx; + u8 rxb_idx; +}; + +#define IGI_RSSI_TH_NUM 5 +#define FA_TH_NUM 4 +#define TIA_LNA_OP1DB_NUM 8 +#define LNA_GAIN_NUM 7 +#define TIA_GAIN_NUM 2 +struct rtw89_dig_info { + struct rtw89_agc_gaincode_set cur_gaincode; + bool force_gaincode_idx_en; + struct rtw89_agc_gaincode_set force_gaincode; + enum rtw89_dig_noisy_level noisy_lv; + u8 igi_rssi_th[IGI_RSSI_TH_NUM]; + u16 fa_th[FA_TH_NUM]; + u8 igi_rssi; + u8 igi_fa_rssi; + u8 fa_rssi_ofst; + u8 dyn_igi_max; + u8 dyn_igi_min; + bool dyn_pd_th_en; + u8 dyn_pd_th_max; + u8 dyn_pd_max_cnt; + u8 pd_low_th_ofst; + u8 ib_pbk; + s8 ib_pkpwr; + s8 lna_gain_a[LNA_GAIN_NUM]; + s8 lna_gain_g[LNA_GAIN_NUM]; + s8 *lna_gain; + s8 tia_gain_a[TIA_GAIN_NUM]; + s8 tia_gain_g[TIA_GAIN_NUM]; + s8 *tia_gain; + u32 bak_dig; + bool is_linked_pre; + bool bypass_dig; + bool pause_dig; +}; + +enum rtw89_multi_cfo_mode { + RTW89_PKT_BASED_AVG_MODE = 0, + RTW89_ENTRY_BASED_AVG_MODE = 1, + RTW89_TP_BASED_AVG_MODE = 2, +}; + +enum rtw89_phy_cfo_status { + RTW89_PHY_DCFO_STATE_NORMAL = 0, + RTW89_PHY_DCFO_STATE_ENHANCE = 1, + RTW89_PHY_DCFO_STATE_HOLD = 2, + RTW89_PHY_DCFO_STATE_MAX +}; + +enum rtw89_phy_cfo_ul_ofdma_acc_mode { + RTW89_CFO_UL_OFDMA_ACC_DISABLE = 0, + RTW89_CFO_UL_OFDMA_ACC_ENABLE = 1 +}; + +struct rtw89_cfo_tracking_info { + u16 cfo_timer_ms; + bool cfo_trig_by_timer_en; + enum rtw89_phy_cfo_status phy_cfo_status; + enum rtw89_phy_cfo_ul_ofdma_acc_mode cfo_ul_ofdma_acc_mode; + u8 phy_cfo_trk_cnt; + bool is_adjust; + enum rtw89_multi_cfo_mode rtw89_multi_cfo_mode; + bool apply_compensation; + u8 crystal_cap; + u8 crystal_cap_default; + u8 def_x_cap; + s8 x_cap_ofst; + u32 sta_cfo_tolerance; + s32 cfo_tail[CFO_TRACK_MAX_USER]; + u16 cfo_cnt[CFO_TRACK_MAX_USER]; + s32 cfo_avg_pre; + s32 cfo_avg[CFO_TRACK_MAX_USER]; + s32 pre_cfo_avg[CFO_TRACK_MAX_USER]; + s32 dcfo_avg; + s32 dcfo_avg_pre; + u32 packet_count; + u32 packet_count_pre; + s32 residual_cfo_acc; + u8 phy_cfotrk_state; + u8 phy_cfotrk_cnt; + bool divergence_lock_en; + u8 x_cap_lb; + u8 x_cap_ub; + u8 lock_cnt; +}; + +enum rtw89_tssi_mode { + RTW89_TSSI_NORMAL = 0, + RTW89_TSSI_SCAN = 1, +}; + +enum rtw89_tssi_alimk_band { + TSSI_ALIMK_2G = 0, + TSSI_ALIMK_5GL, + TSSI_ALIMK_5GM, + TSSI_ALIMK_5GH, + TSSI_ALIMK_MAX +}; + +/* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ +#define TSSI_TRIM_CH_GROUP_NUM 8 +#define TSSI_TRIM_CH_GROUP_NUM_6G 16 + +#define TSSI_CCK_CH_GROUP_NUM 6 +#define TSSI_MCS_2G_CH_GROUP_NUM 5 +#define TSSI_MCS_5G_CH_GROUP_NUM 14 +#define TSSI_MCS_6G_CH_GROUP_NUM 32 +#define TSSI_MCS_CH_GROUP_NUM \ + (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM) +#define TSSI_MAX_CH_NUM 67 +#define TSSI_ALIMK_VALUE_NUM 8 + +struct rtw89_tssi_info { + u8 thermal[RF_PATH_MAX]; + s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM]; + s8 tssi_trim_6g[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM_6G]; + s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM]; + s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM]; + s8 tssi_6g_mcs[RF_PATH_MAX][TSSI_MCS_6G_CH_GROUP_NUM]; + s8 extra_ofst[RF_PATH_MAX]; + bool tssi_tracking_check[RF_PATH_MAX]; + u8 default_txagc_offset[RF_PATH_MAX]; + u32 base_thermal[RF_PATH_MAX]; + bool check_backup_aligmk[RF_PATH_MAX][TSSI_MAX_CH_NUM]; + u32 alignment_backup_by_ch[RF_PATH_MAX][TSSI_MAX_CH_NUM][TSSI_ALIMK_VALUE_NUM]; + u32 alignment_value[RF_PATH_MAX][TSSI_ALIMK_MAX][TSSI_ALIMK_VALUE_NUM]; + bool alignment_done[RF_PATH_MAX][TSSI_ALIMK_MAX]; + u64 tssi_alimk_time; +}; + +struct rtw89_power_trim_info { + bool pg_thermal_trim; + bool pg_pa_bias_trim; + bool pg_vco_trim; + u8 thermal_trim[RF_PATH_MAX]; + u8 pa_bias_trim[RF_PATH_MAX]; + u8 pad_bias_trim[RF_PATH_MAX]; + u8 vco_trim[RF_PATH_MAX]; + + s16 thermal_k; +}; + +enum rtw89_regd_func { + RTW89_REGD_FUNC_TAS = 0, /* TAS (Time Average SAR) */ + RTW89_REGD_FUNC_DAG = 1, /* DAG (Dynamic Antenna Gain) */ + + NUM_OF_RTW89_REGD_FUNC, +}; + +struct rtw89_regd { + char alpha2[3]; + u8 txpwr_regd[RTW89_BAND_NUM]; + DECLARE_BITMAP(func_bitmap, NUM_OF_RTW89_REGD_FUNC); +}; + +struct rtw89_regd_data { + unsigned int nr; + struct rtw89_regd map[] __counted_by(nr); +}; + +struct rtw89_regd_ctrl { + unsigned int nr; + const struct rtw89_regd *map; +}; + +#define RTW89_REGD_MAX_COUNTRY_NUM U8_MAX +#define RTW89_5GHZ_UNII4_CHANNEL_NUM 3 +#define RTW89_5GHZ_UNII4_START_INDEX 25 + +struct rtw89_regulatory_info { + struct rtw89_regd_ctrl ctrl; + const struct rtw89_regd *regd; + bool programmed; + + enum rtw89_reg_6ghz_power reg_6ghz_power; + struct rtw89_reg_6ghz_tpe reg_6ghz_tpe; + bool txpwr_uk_follow_etsi; + + DECLARE_BITMAP(block_unii4, RTW89_REGD_MAX_COUNTRY_NUM); + DECLARE_BITMAP(block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM); + DECLARE_BITMAP(block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM); + DECLARE_BITMAP(block_6ghz_vlp, RTW89_REGD_MAX_COUNTRY_NUM); +}; + +enum rtw89_ifs_clm_application { + RTW89_IFS_CLM_INIT = 0, + RTW89_IFS_CLM_BACKGROUND = 1, + RTW89_IFS_CLM_ACS = 2, + RTW89_IFS_CLM_DIG = 3, + RTW89_IFS_CLM_TDMA_DIG = 4, + RTW89_IFS_CLM_DBG = 5, + RTW89_IFS_CLM_DBG_MANUAL = 6 +}; + +enum rtw89_env_racing_lv { + RTW89_RAC_RELEASE = 0, + RTW89_RAC_LV_1 = 1, + RTW89_RAC_LV_2 = 2, + RTW89_RAC_LV_3 = 3, + RTW89_RAC_LV_4 = 4, + RTW89_RAC_MAX_NUM = 5 +}; + +struct rtw89_ccx_para_info { + enum rtw89_env_racing_lv rac_lv; + u16 mntr_time; + bool nhm_incld_cca; + u8 nhm_manual_th_ofst; + u8 nhm_manual_th0; + enum rtw89_ifs_clm_application ifs_clm_app; + u32 ifs_clm_manual_th_times; + u32 ifs_clm_manual_th0; + u8 fahm_manual_th_ofst; + u8 fahm_manual_th0; + u8 fahm_numer_opt; + u8 fahm_denom_opt; +}; + +enum rtw89_ccx_edcca_opt_sc_idx { + RTW89_CCX_EDCCA_SEG0_P0 = 0, + RTW89_CCX_EDCCA_SEG0_S1 = 1, + RTW89_CCX_EDCCA_SEG0_S2 = 2, + RTW89_CCX_EDCCA_SEG0_S3 = 3, + RTW89_CCX_EDCCA_SEG1_P0 = 4, + RTW89_CCX_EDCCA_SEG1_S1 = 5, + RTW89_CCX_EDCCA_SEG1_S2 = 6, + RTW89_CCX_EDCCA_SEG1_S3 = 7 +}; + +enum rtw89_ccx_edcca_opt_bw_idx { + RTW89_CCX_EDCCA_BW20_0 = 0, + RTW89_CCX_EDCCA_BW20_1 = 1, + RTW89_CCX_EDCCA_BW20_2 = 2, + RTW89_CCX_EDCCA_BW20_3 = 3, + RTW89_CCX_EDCCA_BW20_4 = 4, + RTW89_CCX_EDCCA_BW20_5 = 5, + RTW89_CCX_EDCCA_BW20_6 = 6, + RTW89_CCX_EDCCA_BW20_7 = 7 +}; + +struct rtw89_nhm_report { + struct list_head list; + struct ieee80211_channel *channel; + u8 noise; +}; + +#define RTW89_FAHM_TH_NUM 11 +#define RTW89_FAHM_RPT_NUM 12 +#define RTW89_IFS_CLM_NUM 4 +struct rtw89_env_monitor_info { + u8 ccx_watchdog_result; + bool ccx_ongoing; + u8 ccx_rac_lv; + bool ccx_manual_ctrl; + u16 ifs_clm_mntr_time; + enum rtw89_ifs_clm_application ifs_clm_app; + u16 ccx_period; + u8 ccx_unit_idx; + u16 ifs_clm_th_l[RTW89_IFS_CLM_NUM]; + u16 ifs_clm_th_h[RTW89_IFS_CLM_NUM]; + u16 ifs_clm_tx; + u16 ifs_clm_edcca_excl_cca; + u16 ifs_clm_ofdmfa; + u16 ifs_clm_ofdmcca_excl_fa; + u16 ifs_clm_cckfa; + u16 ifs_clm_cckcca_excl_fa; + u16 ifs_clm_total_ifs; + u16 ifs_clm_his[RTW89_IFS_CLM_NUM]; + u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; + u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; + u8 ifs_clm_tx_ratio; + u8 ifs_clm_edcca_excl_cca_ratio; + u8 ifs_clm_cck_fa_ratio; + u8 ifs_clm_ofdm_fa_ratio; + u8 ifs_clm_cck_cca_excl_fa_ratio; + u8 ifs_clm_ofdm_cca_excl_fa_ratio; + u16 ifs_clm_cck_fa_permil; + u16 ifs_clm_ofdm_fa_permil; + u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM]; + u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM]; + bool nhm_include_cca; + u32 nhm_sum; + u32 nhm_mntr_time; + u16 nhm_result[RTW89_NHM_RPT_NUM]; + u8 nhm_th[RTW89_NHM_RPT_NUM]; + struct rtw89_nhm_report *nhm_his[RTW89_BAND_NUM]; + struct list_head nhm_rpt_list; + u8 edcca_clm_ratio; +}; + +enum rtw89_ser_rcvy_step { + RTW89_SER_DRV_STOP_TX, + RTW89_SER_DRV_STOP_RX, + RTW89_SER_DRV_STOP_RUN, + RTW89_SER_HAL_STOP_DMA, + RTW89_SER_SUPPRESS_LOG, + RTW89_NUM_OF_SER_FLAGS +}; + +struct rtw89_ser_count { + unsigned int l1; + unsigned int l2; +}; + +struct rtw89_ser { + u8 state; + u8 alarm_event; + bool prehandle_l1; + + struct rtw89_ser_count sw_cnt; + + struct work_struct ser_hdl_work; + struct delayed_work ser_alarm_work; + const struct state_ent *st_tbl; + const struct event_ent *ev_tbl; + struct list_head msg_q; + spinlock_t msg_q_lock; /* lock when read/write ser msg */ + DECLARE_BITMAP(flags, RTW89_NUM_OF_SER_FLAGS); +}; + +enum rtw89_mac_ax_ps_mode { + RTW89_MAC_AX_PS_MODE_ACTIVE = 0, + RTW89_MAC_AX_PS_MODE_LEGACY = 1, + RTW89_MAC_AX_PS_MODE_WMMPS = 2, + RTW89_MAC_AX_PS_MODE_MAX = 3, +}; + +enum rtw89_last_rpwm_mode { + RTW89_LAST_RPWM_PS = 0x0, + RTW89_LAST_RPWM_ACTIVE = 0x6, +}; + +struct rtw89_lps_parm { + u8 macid; + u8 psmode; /* enum rtw89_mac_ax_ps_mode */ + u8 lastrpwm; /* enum rtw89_last_rpwm_mode */ +}; + +struct rtw89_ppdu_sts_info { + struct sk_buff_head rx_queue[RTW89_PHY_NUM]; + u8 curr_rx_ppdu_cnt[RTW89_PHY_NUM]; +}; + +struct rtw89_early_h2c { + struct list_head list; + u8 *h2c; + u16 h2c_len; +}; + +struct rtw89_hw_scan_extra_op { + bool set; + u8 macid; + u8 port; + struct rtw89_chan chan; + struct rtw89_vif_link *rtwvif_link; +}; + +struct rtw89_hw_scan_info { + struct rtw89_vif_link *scanning_vif; + struct list_head pkt_list[NUM_NL80211_BANDS]; + struct list_head chan_list; + struct rtw89_chan op_chan; + struct rtw89_hw_scan_extra_op extra_op; + u8 wildcard_pkt_id[NUM_NL80211_BANDS]; + u16 ssid_total_len; + int n_ssids; + bool connected; + bool abort; + u16 delay; /* in unit of ms */ + u8 seq: 2; +}; + +enum rtw89_phy_bb_gain_band { + RTW89_BB_GAIN_BAND_2G = 0, + RTW89_BB_GAIN_BAND_5G_L = 1, + RTW89_BB_GAIN_BAND_5G_M = 2, + RTW89_BB_GAIN_BAND_5G_H = 3, + RTW89_BB_GAIN_BAND_6G_L = 4, + RTW89_BB_GAIN_BAND_6G_M = 5, + RTW89_BB_GAIN_BAND_6G_H = 6, + RTW89_BB_GAIN_BAND_6G_UH = 7, + + RTW89_BB_GAIN_BAND_NR, +}; + +enum rtw89_phy_gain_band_be { + RTW89_BB_GAIN_BAND_2G_BE = 0, + RTW89_BB_GAIN_BAND_5G_L_BE = 1, + RTW89_BB_GAIN_BAND_5G_M_BE = 2, + RTW89_BB_GAIN_BAND_5G_H_BE = 3, + RTW89_BB_GAIN_BAND_6G_L0_BE = 4, + RTW89_BB_GAIN_BAND_6G_L1_BE = 5, + RTW89_BB_GAIN_BAND_6G_M0_BE = 6, + RTW89_BB_GAIN_BAND_6G_M1_BE = 7, + RTW89_BB_GAIN_BAND_6G_H0_BE = 8, + RTW89_BB_GAIN_BAND_6G_H1_BE = 9, + RTW89_BB_GAIN_BAND_6G_UH0_BE = 10, + RTW89_BB_GAIN_BAND_6G_UH1_BE = 11, + + RTW89_BB_GAIN_BAND_NR_BE, +}; + +enum rtw89_phy_bb_bw_be { + RTW89_BB_BW_20_40 = 0, + RTW89_BB_BW_80_160_320 = 1, + + RTW89_BB_BW_NR_BE, +}; + +enum rtw89_bw20_sc { + RTW89_BW20_SC_20M = 1, + RTW89_BW20_SC_40M = 2, + RTW89_BW20_SC_80M = 4, + RTW89_BW20_SC_160M = 8, + RTW89_BW20_SC_320M = 16, +}; + +enum rtw89_cmac_table_bw { + RTW89_CMAC_BW_20M = 0, + RTW89_CMAC_BW_40M = 1, + RTW89_CMAC_BW_80M = 2, + RTW89_CMAC_BW_160M = 3, + RTW89_CMAC_BW_320M = 4, + + RTW89_CMAC_BW_NR, +}; + +enum rtw89_phy_bb_rxsc_num { + RTW89_BB_RXSC_NUM_40 = 9, /* SC: 0, 1~8 */ + RTW89_BB_RXSC_NUM_80 = 13, /* SC: 0, 1~8, 9~12 */ + RTW89_BB_RXSC_NUM_160 = 15, /* SC: 0, 1~8, 9~12, 13~14 */ +}; + +struct rtw89_phy_bb_gain_info { + s8 lna_gain[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 tia_gain[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][TIA_GAIN_NUM]; + s8 lna_gain_bypass[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 lna_op1db[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 tia_lna_op1db[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [LNA_GAIN_NUM + 1]; /* TIA0_LNA0~6 + TIA1_LNA6 */ + s8 rpl_ofst_20[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX]; + s8 rpl_ofst_40[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_40]; + s8 rpl_ofst_80[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_80]; + s8 rpl_ofst_160[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_160]; +}; + +struct rtw89_phy_bb_gain_info_be { + s8 lna_gain[RTW89_BB_GAIN_BAND_NR_BE][RTW89_BB_BW_NR_BE][RF_PATH_MAX] + [LNA_GAIN_NUM]; + s8 tia_gain[RTW89_BB_GAIN_BAND_NR_BE][RTW89_BB_BW_NR_BE][RF_PATH_MAX] + [TIA_GAIN_NUM]; + s8 lna_gain_bypass[RTW89_BB_GAIN_BAND_NR_BE][RTW89_BB_BW_NR_BE] + [RF_PATH_MAX][LNA_GAIN_NUM]; + s8 lna_op1db[RTW89_BB_GAIN_BAND_NR_BE][RTW89_BB_BW_NR_BE] + [RF_PATH_MAX][LNA_GAIN_NUM]; + s8 tia_lna_op1db[RTW89_BB_GAIN_BAND_NR_BE][RTW89_BB_BW_NR_BE] + [RF_PATH_MAX][LNA_GAIN_NUM + 1]; + s8 rpl_ofst_20[RTW89_BB_GAIN_BAND_NR_BE][RF_PATH_MAX] + [RTW89_BW20_SC_20M]; + s8 rpl_ofst_40[RTW89_BB_GAIN_BAND_NR_BE][RF_PATH_MAX] + [RTW89_BW20_SC_40M]; + s8 rpl_ofst_80[RTW89_BB_GAIN_BAND_NR_BE][RF_PATH_MAX] + [RTW89_BW20_SC_80M]; + s8 rpl_ofst_160[RTW89_BB_GAIN_BAND_NR_BE][RF_PATH_MAX] + [RTW89_BW20_SC_160M]; +}; + +struct rtw89_phy_efuse_gain { + bool offset_valid; + bool comp_valid; + s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ + s8 offset2[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ + s8 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */ + s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */ + s8 ref_gain_base[RTW89_PHY_NUM]; /* S(8, 2) */ + s8 cck_rpl_base[RTW89_PHY_NUM]; /* S(8, 0) */ + s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ +}; + +struct rtw89_phy_calc_efuse_gain { + s8 cck_mean_gain_bias; + s8 cck_rpl_ofst; + s8 rssi_ofst; +}; + +#define RTW89_MAX_PATTERN_NUM 18 +#define RTW89_MAX_PATTERN_MASK_SIZE 4 +#define RTW89_MAX_PATTERN_SIZE 128 + +struct rtw89_wow_cam_info { + bool r_w; + u8 idx; + __le32 mask[RTW89_MAX_PATTERN_MASK_SIZE]; + u16 crc; + bool negative_pattern_match; + bool skip_mac_hdr; + bool uc; + bool mc; + bool bc; + bool valid; +}; + +struct rtw89_wow_key_info { + u8 ptk_tx_iv[8]; + u8 valid_check; + u8 symbol_check_en; + u8 gtk_keyidx; + u8 rsvd[5]; + u8 ptk_rx_iv[8]; + u8 gtk_rx_iv[4][8]; +} __packed; + +struct rtw89_wow_gtk_info { + u8 kck[32]; + u8 kek[32]; + u8 tk1[16]; + u8 rxmickey[8]; + u8 txmickey[8]; + __le32 igtk_keyid; + __le64 ipn; + u8 igtk[2][32]; + u8 psk[32]; +} __packed; + +struct rtw89_wow_aoac_report { + u8 rpt_ver; + u8 sec_type; + u8 key_idx; + u8 pattern_idx; + u8 rekey_ok; + u8 ptk_tx_iv[8]; + u8 eapol_key_replay_count[8]; + u8 gtk[32]; + u8 ptk_rx_iv[8]; + u8 gtk_rx_iv[4][8]; + u64 igtk_key_id; + u64 igtk_ipn; + u8 igtk[32]; + u8 csa_pri_ch; + u8 csa_bw; + u8 csa_ch_offset; + u8 csa_chsw_failed; + u8 csa_ch_band; +}; + +struct rtw89_wow_param { + struct rtw89_vif_link *rtwvif_link; + DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); + struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; + struct rtw89_wow_key_info key_info; + struct rtw89_wow_gtk_info gtk_info; + struct rtw89_wow_aoac_report aoac_rpt; + u8 pattern_cnt; + u8 ptk_alg; + u8 gtk_alg; + u8 ptk_keyidx; + u8 akm; + + /* see RTW89_WOW_WAIT_COND series for wait condition */ + struct rtw89_wait_info wait; + + bool pno_inited; + struct list_head pno_pkt_list; + struct cfg80211_sched_scan_request *nd_config; +}; + +struct rtw89_mcc_limit { + bool enable; + u16 max_tob; /* TU; max time offset behind */ + u16 max_toa; /* TU; max time offset ahead */ + u16 max_dur; /* TU */ +}; + +struct rtw89_mcc_policy { + u8 c2h_rpt; + u8 tx_null_early; + u8 dis_tx_null; + u8 in_curr_ch; + u8 dis_sw_retry; + u8 sw_retry_count; +}; + +struct rtw89_mcc_role { + struct rtw89_vif_link *rtwvif_link; + struct rtw89_mcc_policy policy; + struct rtw89_mcc_limit limit; + + const struct rtw89_mcc_courtesy_cfg *crtz; + + /* only valid when running with FW MRC mechanism */ + u8 slot_idx; + + /* byte-array in LE order for FW */ + u8 macid_bitmap[BITS_TO_BYTES(RTW89_MAX_MAC_ID_NUM)]; + u8 probe_count; + + u16 duration; /* TU */ + u16 beacon_interval; /* TU */ + bool is_2ghz; + bool is_go; + bool is_gc; + bool ignore_bcn; +}; + +struct rtw89_mcc_bt_role { + u16 duration; /* TU */ +}; + +struct rtw89_mcc_courtesy_cfg { + u8 slot_num; + u8 macid_tgt; +}; + +struct rtw89_mcc_courtesy { + struct rtw89_mcc_courtesy_cfg ref; + struct rtw89_mcc_courtesy_cfg aux; +}; + +enum rtw89_mcc_plan { + RTW89_MCC_PLAN_TAIL_BT, + RTW89_MCC_PLAN_MID_BT, + RTW89_MCC_PLAN_NO_BT, + + NUM_OF_RTW89_MCC_PLAN, +}; + +struct rtw89_mcc_pattern { + s16 tob_ref; /* TU; time offset behind of reference role */ + s16 toa_ref; /* TU; time offset ahead of reference role */ + s16 tob_aux; /* TU; time offset behind of auxiliary role */ + s16 toa_aux; /* TU; time offset ahead of auxiliary role */ + + enum rtw89_mcc_plan plan; + struct rtw89_mcc_courtesy courtesy; +}; + +struct rtw89_mcc_sync { + bool enable; + u16 offset; /* TU */ + u8 macid_src; + u8 band_src; + u8 port_src; + u8 macid_tgt; + u8 band_tgt; + u8 port_tgt; +}; + +struct rtw89_mcc_config { + struct rtw89_mcc_pattern pattern; + struct rtw89_mcc_sync sync; + u64 start_tsf; + u64 start_tsf_in_aux_domain; + u64 prepare_delay; + u16 mcc_interval; /* TU */ + u16 beacon_offset; /* TU */ +}; + +enum rtw89_mcc_mode { + RTW89_MCC_MODE_GO_STA, + RTW89_MCC_MODE_GC_STA, +}; + +struct rtw89_mcc_info { + struct rtw89_wait_info wait; + + u8 group; + enum rtw89_mcc_mode mode; + struct rtw89_mcc_role role_ref; /* reference role */ + struct rtw89_mcc_role role_aux; /* auxiliary role */ + struct rtw89_mcc_bt_role bt_role; + struct rtw89_mcc_config config; +}; + +enum rtw89_mlo_mode { + RTW89_MLO_MODE_MLSR = 0, + RTW89_MLO_MODE_EMLSR = 1, + + NUM_OF_RTW89_MLO_MODE, +}; + +struct rtw89_mlo_info { + struct rtw89_wait_info wait; +}; + +struct rtw89_beacon_track_info { + bool is_data_ready; + u32 tbtt_offset; /* in unit of microsecond */ + u16 bcn_timeout; /* in unit of millisecond */ + + /* The following are constant and set at association. */ + u8 dtim; + u16 beacon_int; + u16 low_bcn_th; + u16 med_bcn_th; + u16 high_bcn_th; + u16 target_bcn_th; + u16 outlier_low_bcn_th; + u16 outlier_high_bcn_th; + u32 close_bcn_intvl_th; + u32 tbtt_diff_th; +}; + +struct rtw89_tid_stats { + s64 last_pn; + u16 last_sn; + bool started; +}; + +struct rtw89_io_ops { + int (*pack)(struct rtw89_dev *rtwdev); + int (*unpack)(struct rtw89_dev *rtwdev); + void (*do_udelay)(struct rtw89_dev *rtwdev, u32 us); + void (*do_mdelay)(struct rtw89_dev *rtwdev, u32 ms); + void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); + void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); + void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); + void (*phy_write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); + void (*phy_write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); + void (*phy_write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); + void (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +}; + +struct rtw89_dev { + struct ieee80211_hw *hw; + struct device *dev; + const struct ieee80211_ops *ops; + const struct rtw89_io_ops *io; + + bool dbcc_en; + bool support_mlo; + enum rtw89_mlo_dbcc_mode mlo_dbcc_mode; + struct rtw89_hw_scan_info scan_info; + const struct rtw89_chip_info *chip; + const struct rtw89_chip_variant *variant; + const struct rtw89_board_variant *board; + const struct rtw89_pci_info *pci_info; + const struct rtw89_rfe_parms *rfe_parms; + struct rtw89_hal hal; + struct rtw89_beacon_track_info bcn_track; + struct rtw89_mcc_info mcc; + struct rtw89_mlo_info mlo; + struct rtw89_mac_info mac; + struct rtw89_fw_info fw; + struct rtw89_hci_info hci; + struct rtw89_efuse efuse; + struct rtw89_traffic_stats stats; + struct rtw89_rfe_data *rfe_data; + enum rtw89_custid custid; + + struct rtw89_fw_cmd_ofld_info *fw_cmd_ofld_info; + + struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM]; + refcount_t refcount_ap_info; + + struct list_head rtwvifs_list; + struct workqueue_struct *txq_wq; + struct work_struct txq_work; + struct delayed_work txq_reinvoke_work; + /* used to protect ba_list and forbid_ba_list */ + spinlock_t ba_lock; + /* txqs to setup ba session */ + struct list_head ba_list; + /* txqs to forbid ba session */ + struct list_head forbid_ba_list; + struct work_struct ba_work; + /* used to protect rpwm */ + spinlock_t rpwm_lock; + + struct list_head tx_waits; + struct wiphy_delayed_work tx_wait_work; + + struct rtw89_tx_rpt tx_rpt; + + struct rtw89_cam_info cam_info; + + struct sk_buff_head c2h_queue; + struct wiphy_work c2h_work; + struct wiphy_work ips_work; + struct wiphy_work cancel_6ghz_probe_work; + struct work_struct load_firmware_work; + + struct list_head early_h2c_list; + + struct rtw89_ser ser; + + DECLARE_BITMAP(hw_port, RTW89_PORT_NUM); + DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); + DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); + DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM); + DECLARE_BITMAP(quirks, NUM_OF_RTW89_QUIRKS); + + struct rtw89_phy_stat phystat; + struct rtw89_rfk_wait_info rfk_wait; + struct rtw89_dack_info dack; + struct rtw89_iqk_info iqk; + struct rtw89_dpk_info dpk; + struct rtw89_rfk_mcc_info rfk_mcc; + struct rtw89_lck_info lck; + struct rtw89_rx_dck_info rx_dck; + bool is_tssi_mode[RF_PATH_MAX]; + bool is_bt_iqk_timeout; + + struct rtw89_fem_info fem; + struct rtw89_txpwr_byrate byr[RTW89_BAND_NUM][RTW89_BYR_BW_NUM]; + struct rtw89_tssi_info tssi; + struct rtw89_power_trim_info pwr_trim; + + struct rtw89_cfo_tracking_info cfo_tracking; + union { + struct rtw89_phy_bb_gain_info ax; + struct rtw89_phy_bb_gain_info_be be; + } bb_gain; + struct rtw89_phy_efuse_gain efuse_gain; + struct rtw89_phy_ul_tb_info ul_tb_info; + struct rtw89_antdiv_info antdiv; + struct rtw89_phy_info phy_info; + + struct rtw89_bb_ctx { + enum rtw89_phy_idx phy_idx; + struct rtw89_env_monitor_info env_monitor; + struct rtw89_dig_info dig; + struct rtw89_phy_ch_info ch_info; + struct rtw89_edcca_bak edcca_bak; + struct ewma_rssi bcn_rssi; + struct rtw89_pkt_stat cur_pkt_stat; + struct rtw89_pkt_stat last_pkt_stat; + struct rtw89_pmac_stat_info pmac_stat; + struct rtw89_tx_stat_info tx_stat; + struct rtw89_diag_bb diag; + struct rtw89_phy_path_diff path_diff; + } bbs[RTW89_PHY_NUM]; + + struct wiphy_delayed_work track_work; + struct wiphy_delayed_work track_ps_work; + struct wiphy_delayed_work chanctx_work; + struct wiphy_delayed_work coex_act1_work; + struct wiphy_delayed_work coex_bt_devinfo_work; + struct wiphy_delayed_work coex_rfk_chk_work; + struct wiphy_delayed_work cfo_track_work; + struct wiphy_delayed_work mcc_prepare_done_work; + struct delayed_work forbid_ba_work; + struct wiphy_delayed_work antdiv_work; + struct rtw89_ppdu_sts_info ppdu_sts; + u8 total_sta_assoc; + bool scanning; + + struct rtw89_regulatory_info regulatory; + struct rtw89_sar_info sar; + struct rtw89_tas_info tas; + struct rtw89_ant_gain_info ant_gain; + + struct rtw89_btc btc; + enum rtw89_ps_mode ps_mode; + bool lps_enabled; + u8 ps_hang_cnt; + + struct rtw89_wow_param wow; + + /* napi structure */ + struct net_device *netdev; + struct napi_struct napi; + int napi_budget_countdown; + + struct rtw89_debugfs *debugfs; + struct rtw89_vif *pure_monitor_mode_vif; + struct rtw89_led led; + + /* HCI related data, keep last */ + u8 priv[] __aligned(sizeof(void *)); +}; + +struct rtw89_link_conf_container { + struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; +}; + +struct rtw89_vif_ml_trans { + u16 mediate_links; + u16 links_to_del; + u16 links_to_add; +}; + +#define RTW89_VIF_IDLE_LINK_ID 0 + +struct rtw89_vif { + struct rtw89_dev *rtwdev; + struct list_head list; + struct list_head mgnt_entry; + struct rtw89_link_conf_container __rcu *snap_link_confs; + + u8 mac_addr[ETH_ALEN]; + __be32 ip_addr; + + struct rtw89_traffic_stats stats; + struct rtw89_traffic_stats stats_ps; + u32 tdls_peer; + + struct ieee80211_scan_ies *scan_ies; + struct cfg80211_scan_request *scan_req; + + struct rtw89_roc roc; + bool offchan; + bool burst_active; + + enum rtw89_mlo_mode mlo_mode; + struct rtw89_vif_ml_trans ml_trans; + + struct list_head dlink_pool; + u8 links_inst_valid_num; + DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS]; + struct rtw89_vif_link links_inst[] __counted_by(links_inst_valid_num); +}; + +static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwvif_link, + const struct rtw89_vif *rtwvif, + unsigned int link_id) +{ + *rtwvif_link = rtwvif->links[link_id]; + return !!*rtwvif_link; +} + +#define rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) \ + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \ + if (rtw89_vif_assign_link_is_valid(&(rtwvif_link), rtwvif, link_id)) + +enum rtw89_sta_flags { + RTW89_REMOTE_STA_IN_PS, + + NUM_OF_RTW89_STA_FLAGS, +}; + +struct rtw89_sta { + struct rtw89_dev *rtwdev; + struct rtw89_vif *rtwvif; + + DECLARE_BITMAP(flags, NUM_OF_RTW89_STA_FLAGS); + + bool disassoc; + + struct sk_buff_head roc_queue; + + struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; + struct rtw89_tid_stats tid_rx_stats[IEEE80211_NUM_TIDS]; + DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS); + + DECLARE_BITMAP(pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM); + + struct list_head dlink_pool; + u8 links_inst_valid_num; + DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS]; + struct rtw89_sta_link links_inst[] __counted_by(links_inst_valid_num); +}; + +static inline bool rtw89_sta_assign_link_is_valid(struct rtw89_sta_link **rtwsta_link, + const struct rtw89_sta *rtwsta, + unsigned int link_id) +{ + *rtwsta_link = rtwsta->links[link_id]; + return !!*rtwsta_link; +} + +#define rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) \ + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \ + if (rtw89_sta_assign_link_is_valid(&(rtwsta_link), rtwsta, link_id)) + +static inline u8 rtw89_vif_get_main_macid(struct rtw89_vif *rtwvif) +{ + /* const after init, so no need to check if active first */ + return rtwvif->links_inst[0].mac_id; +} + +static inline u8 rtw89_vif_get_main_port(struct rtw89_vif *rtwvif) +{ + /* const after init, so no need to check if active first */ + return rtwvif->links_inst[0].port; +} + +static inline struct rtw89_vif_link * +rtw89_vif_get_link_inst(struct rtw89_vif *rtwvif, u8 index) +{ + if (index >= rtwvif->links_inst_valid_num || + !test_bit(index, rtwvif->links_inst_map)) + return NULL; + return &rtwvif->links_inst[index]; +} + +static inline +u8 rtw89_vif_link_inst_get_index(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + + return rtwvif_link - rtwvif->links_inst; +} + +static inline u8 rtw89_sta_get_main_macid(struct rtw89_sta *rtwsta) +{ + /* const after init, so no need to check if active first */ + return rtwsta->links_inst[0].mac_id; +} + +static inline struct rtw89_sta_link * +rtw89_sta_get_link_inst(struct rtw89_sta *rtwsta, u8 index) +{ + if (index >= rtwsta->links_inst_valid_num || + !test_bit(index, rtwsta->links_inst_map)) + return NULL; + return &rtwsta->links_inst[index]; +} + +static inline +u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + + return rtwsta_link - rtwsta->links_inst; +} + +static inline void rtw89_assoc_link_set(struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + + rcu_assign_pointer(rtwdev->assoc_link_on_macid[rtwsta_link->mac_id], + rtwsta_link); +} + +static inline void rtw89_assoc_link_clr(struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + + rcu_assign_pointer(rtwdev->assoc_link_on_macid[rtwsta_link->mac_id], + NULL); + synchronize_rcu(); +} + +static inline struct rtw89_sta_link * +rtw89_assoc_link_rcu_dereference(struct rtw89_dev *rtwdev, u8 macid) +{ + if (unlikely(macid >= RTW89_MAX_MAC_ID_NUM)) + return NULL; + + return rcu_dereference(rtwdev->assoc_link_on_macid[macid]); +} + +#define rtw89_get_designated_link(links_holder) \ +({ \ + typeof(links_holder) p = links_holder; \ + list_first_entry_or_null(&p->dlink_pool, typeof(*p->links_inst), dlink_schd); \ +}) + +static inline void rtw89_tx_wait_release(struct rtw89_tx_wait_info *wait) +{ + dev_kfree_skb_any(wait->skb); + kfree_rcu(wait, rcu_head); +} + +static inline void rtw89_tx_wait_list_clear(struct rtw89_dev *rtwdev) +{ + struct rtw89_tx_wait_info *wait, *tmp; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + list_for_each_entry_safe(wait, tmp, &rtwdev->tx_waits, list) { + if (!completion_done(&wait->completion)) + continue; + list_del(&wait->list); + rtw89_tx_wait_release(wait); + } +} + +static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + return rtwdev->hci.ops->tx_write(rtwdev, tx_req); +} + +static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) +{ + rtwdev->hci.ops->reset(rtwdev); + /* hci.ops->reset must complete all pending TX wait SKBs */ + rtw89_tx_wait_list_clear(rtwdev); +} + +static inline int rtw89_hci_start(struct rtw89_dev *rtwdev) +{ + return rtwdev->hci.ops->start(rtwdev); +} + +static inline void rtw89_hci_stop(struct rtw89_dev *rtwdev) +{ + rtwdev->hci.ops->stop(rtwdev); +} + +static inline int rtw89_hci_deinit(struct rtw89_dev *rtwdev) +{ + return rtwdev->hci.ops->deinit(rtwdev); +} + +static inline void rtw89_hci_pause(struct rtw89_dev *rtwdev, bool pause) +{ + rtwdev->hci.ops->pause(rtwdev, pause); +} + +static inline void rtw89_hci_switch_mode(struct rtw89_dev *rtwdev, bool low_power) +{ + rtwdev->hci.ops->switch_mode(rtwdev, low_power); +} + +static inline void rtw89_hci_recalc_int_mit(struct rtw89_dev *rtwdev) +{ + rtwdev->hci.ops->recalc_int_mit(rtwdev); +} + +static inline u32 rtw89_hci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) +{ + return rtwdev->hci.ops->check_and_reclaim_tx_resource(rtwdev, txch); +} + +static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) +{ + return rtwdev->hci.ops->tx_kick_off(rtwdev, txch); +} + +static inline int rtw89_hci_mac_pre_deinit(struct rtw89_dev *rtwdev) +{ + return rtwdev->hci.ops->mac_pre_deinit(rtwdev); +} + +static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, + bool drop) +{ + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return; + + if (rtwdev->hci.ops->flush_queues) + return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); +} + +static inline void rtw89_hci_recovery_start(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->recovery_start) + rtwdev->hci.ops->recovery_start(rtwdev); +} + +static inline void rtw89_hci_recovery_complete(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->recovery_complete) + rtwdev->hci.ops->recovery_complete(rtwdev); +} + +static inline void rtw89_hci_enable_intr(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->enable_intr) + rtwdev->hci.ops->enable_intr(rtwdev); +} + +static inline void rtw89_hci_disable_intr(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->disable_intr) + rtwdev->hci.ops->disable_intr(rtwdev); +} + +static inline void rtw89_hci_ctrl_txdma_ch(struct rtw89_dev *rtwdev, bool enable) +{ + if (rtwdev->hci.ops->ctrl_txdma_ch) + rtwdev->hci.ops->ctrl_txdma_ch(rtwdev, enable); +} + +static inline void rtw89_hci_ctrl_txdma_fw_ch(struct rtw89_dev *rtwdev, bool enable) +{ + if (rtwdev->hci.ops->ctrl_txdma_fw_ch) + rtwdev->hci.ops->ctrl_txdma_fw_ch(rtwdev, enable); +} + +static inline void rtw89_hci_ctrl_trxhci(struct rtw89_dev *rtwdev, bool enable) +{ + if (rtwdev->hci.ops->ctrl_trxhci) + rtwdev->hci.ops->ctrl_trxhci(rtwdev, enable); +} + +static inline int rtw89_hci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev) +{ + int ret = 0; + + if (rtwdev->hci.ops->poll_txdma_ch_idle) + ret = rtwdev->hci.ops->poll_txdma_ch_idle(rtwdev); + return ret; +} + +static inline void rtw89_hci_clr_idx_all(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->clr_idx_all) + rtwdev->hci.ops->clr_idx_all(rtwdev); +} + +static inline int rtw89_hci_rst_bdram(struct rtw89_dev *rtwdev) +{ + int ret = 0; + + if (rtwdev->hci.ops->rst_bdram) + ret = rtwdev->hci.ops->rst_bdram(rtwdev); + return ret; +} + +static inline void rtw89_hci_clear(struct rtw89_dev *rtwdev, struct pci_dev *pdev) +{ + if (rtwdev->hci.ops->clear) + rtwdev->hci.ops->clear(rtwdev, pdev); +} + +static inline +struct rtw89_tx_skb_data *RTW89_TX_SKB_CB(struct sk_buff *skb) +{ + /* + * This should be used by/after rtw89_hci_tx_write() and before doing + * ieee80211_tx_info_clear_status(). + */ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + return (struct rtw89_tx_skb_data *)info->driver_data; +} + +static inline int rtw89_io_pack(struct rtw89_dev *rtwdev) +{ + if (rtwdev->io->pack) + return rtwdev->io->pack(rtwdev); + + return 0; +} + +static inline int rtw89_io_unpack(struct rtw89_dev *rtwdev) +{ + if (rtwdev->io->unpack) + return rtwdev->io->unpack(rtwdev); + + return 0; +} + +static inline void rtw89_io_udelay(struct rtw89_dev *rtwdev, u32 us) +{ + if (rtwdev->io->do_udelay) + rtwdev->io->do_udelay(rtwdev, us); + else + udelay(us); +} + +static inline void rtw89_io_mdelay(struct rtw89_dev *rtwdev, u32 ms) +{ + if (rtwdev->io->do_mdelay) + rtwdev->io->do_mdelay(rtwdev, ms); + else + mdelay(ms); +} + +static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read8(rtwdev, addr); +} + +static inline u16 rtw89_read16(struct rtw89_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read16(rtwdev, addr); +} + +static inline u32 rtw89_read32(struct rtw89_dev *rtwdev, u32 addr) +{ + return rtwdev->hci.ops->read32(rtwdev, addr); +} + +static inline void rtw89_raw_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + rtwdev->hci.ops->write8(rtwdev, addr, data); +} + +static inline void rtw89_raw_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + rtwdev->hci.ops->write16(rtwdev, addr, data); +} + +static inline void rtw89_raw_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + rtwdev->hci.ops->write32(rtwdev, addr, data); +} + +static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + rtwdev->io->write8(rtwdev, addr, data); +} + +static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + rtwdev->io->write16(rtwdev, addr, data); +} + +static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + rtwdev->io->write32(rtwdev, addr, data); +} + +static inline void +rtw89_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) +{ + u8 val; + + val = rtw89_read8(rtwdev, addr); + rtw89_write8(rtwdev, addr, val | bit); +} + +static inline void +rtw89_write16_set(struct rtw89_dev *rtwdev, u32 addr, u16 bit) +{ + u16 val; + + val = rtw89_read16(rtwdev, addr); + rtw89_write16(rtwdev, addr, val | bit); +} + +static inline void +rtw89_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bit) +{ + u32 val; + + val = rtw89_read32(rtwdev, addr); + rtw89_write32(rtwdev, addr, val | bit); +} + +static inline void +rtw89_write8_clr(struct rtw89_dev *rtwdev, u32 addr, u8 bit) +{ + u8 val; + + val = rtw89_read8(rtwdev, addr); + rtw89_write8(rtwdev, addr, val & ~bit); +} + +static inline void +rtw89_write16_clr(struct rtw89_dev *rtwdev, u32 addr, u16 bit) +{ + u16 val; + + val = rtw89_read16(rtwdev, addr); + rtw89_write16(rtwdev, addr, val & ~bit); +} + +static inline void +rtw89_write32_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bit) +{ + u32 val; + + val = rtw89_read32(rtwdev, addr); + rtw89_write32(rtwdev, addr, val & ~bit); +} + +static inline u32 +rtw89_read32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw89_read32(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline u16 +rtw89_read16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw89_read16(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline u8 +rtw89_read8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw89_read8(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline void +rtw89_write32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 set; + + WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr); + + orig = rtw89_read32(rtwdev, addr); + set = (orig & ~mask) | ((data << shift) & mask); + rtw89_write32(rtwdev, addr, set); +} + +static inline void +rtw89_write16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u16 data) +{ + u32 shift; + u16 orig, set; + + mask &= 0xffff; + shift = __ffs(mask); + + orig = rtw89_read16(rtwdev, addr); + set = (orig & ~mask) | ((data << shift) & mask); + rtw89_write16(rtwdev, addr, set); +} + +static inline void +rtw89_write8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u8 data) +{ + u32 shift; + u8 orig, set; + + mask &= 0xff; + shift = __ffs(mask); + + orig = rtw89_read8(rtwdev, addr); + set = (orig & ~mask) | ((data << shift) & mask); + rtw89_write8(rtwdev, addr, set); +} + +static inline u32 +rtw89_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + return rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); +} + +static inline void +rtw89_raw_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); +} + +static inline void +rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtwdev->io->write_rf(rtwdev, rf_path, addr, mask, data); +} + +static inline u32 rtw89_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr) +{ + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE || + !rtwdev->hci.ops->read32_pci_cfg) + return RTW89_R32_EA; + + return rtwdev->hci.ops->read32_pci_cfg(rtwdev, addr); +} + +static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq) +{ + void *p = rtwtxq; + + return container_of(p, struct ieee80211_txq, drv_priv); +} + +static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, + struct ieee80211_txq *txq) +{ + struct rtw89_txq *rtwtxq; + + if (!txq) + return; + + rtwtxq = (struct rtw89_txq *)txq->drv_priv; + INIT_LIST_HEAD(&rtwtxq->list); +} + +static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) +{ + void *p = rtwvif; + + return container_of(p, struct ieee80211_vif, drv_priv); +} + +static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif) +{ + return rtwvif ? rtwvif_to_vif(rtwvif) : NULL; +} + +static inline +struct ieee80211_vif *rtwvif_link_to_vif(struct rtw89_vif_link *rtwvif_link) +{ + return rtwvif_to_vif(rtwvif_link->rtwvif); +} + +static inline +struct ieee80211_vif *rtwvif_link_to_vif_safe(struct rtw89_vif_link *rtwvif_link) +{ + return rtwvif_link ? rtwvif_link_to_vif(rtwvif_link) : NULL; +} + +static inline struct rtw89_vif *vif_to_rtwvif(struct ieee80211_vif *vif) +{ + return (struct rtw89_vif *)vif->drv_priv; +} + +static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif) +{ + return vif ? vif_to_rtwvif(vif) : NULL; +} + +static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) +{ + void *p = rtwsta; + + return container_of(p, struct ieee80211_sta, drv_priv); +} + +static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta) +{ + return rtwsta ? rtwsta_to_sta(rtwsta) : NULL; +} + +static inline +struct ieee80211_sta *rtwsta_link_to_sta(struct rtw89_sta_link *rtwsta_link) +{ + return rtwsta_to_sta(rtwsta_link->rtwsta); +} + +static inline +struct ieee80211_sta *rtwsta_link_to_sta_safe(struct rtw89_sta_link *rtwsta_link) +{ + return rtwsta_link ? rtwsta_link_to_sta(rtwsta_link) : NULL; +} + +static inline struct rtw89_sta *sta_to_rtwsta(struct ieee80211_sta *sta) +{ + return (struct rtw89_sta *)sta->drv_priv; +} + +static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta) +{ + return sta ? sta_to_rtwsta(sta) : NULL; +} + +static inline struct ieee80211_bss_conf * +__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_link_conf_container *snap; + struct ieee80211_bss_conf *bss_conf; + + snap = rcu_dereference(rtwvif->snap_link_confs); + if (snap) { + bss_conf = snap->link_conf[rtwvif_link->link_id]; + goto out; + } + + bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]); + +out: + if (unlikely(!bss_conf)) { + *nolink = true; + return &vif->bss_conf; + } + + *nolink = false; + return bss_conf; +} + +#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert) \ +({ \ + typeof(rtwvif_link) p = rtwvif_link; \ + struct ieee80211_bss_conf *bss_conf; \ + bool nolink; \ + \ + bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \ + if (unlikely(nolink) && (assert)) \ + rtw89_err(p->rtwvif->rtwdev, \ + "%s: cannot find exact bss_conf for link_id %u\n",\ + __func__, p->link_id); \ + bss_conf; \ +}) + +static inline struct ieee80211_link_sta * +__rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink) +{ + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + struct ieee80211_link_sta *link_sta; + + link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]); + if (unlikely(!link_sta)) { + *nolink = true; + return &sta->deflink; + } + + *nolink = false; + return link_sta; +} + +#define rtw89_sta_rcu_dereference_link(rtwsta_link, assert) \ +({ \ + typeof(rtwsta_link) p = rtwsta_link; \ + struct ieee80211_link_sta *link_sta; \ + bool nolink; \ + \ + link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \ + if (unlikely(nolink) && (assert)) \ + rtw89_err(p->rtwsta->rtwdev, \ + "%s: cannot find exact link_sta for link_id %u\n",\ + __func__, p->link_id); \ + link_sta; \ +}) + +static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw) +{ + if (hw_bw == RTW89_CHANNEL_WIDTH_160) + return RATE_INFO_BW_160; + else if (hw_bw == RTW89_CHANNEL_WIDTH_80) + return RATE_INFO_BW_80; + else if (hw_bw == RTW89_CHANNEL_WIDTH_40) + return RATE_INFO_BW_40; + else + return RATE_INFO_BW_20; +} + +static inline +enum nl80211_band rtw89_hw_to_nl80211_band(enum rtw89_band hw_band) +{ + switch (hw_band) { + default: + case RTW89_BAND_2G: + return NL80211_BAND_2GHZ; + case RTW89_BAND_5G: + return NL80211_BAND_5GHZ; + case RTW89_BAND_6G: + return NL80211_BAND_6GHZ; + } +} + +static inline +enum rtw89_band rtw89_nl80211_to_hw_band(enum nl80211_band nl_band) +{ + switch (nl_band) { + default: + case NL80211_BAND_2GHZ: + return RTW89_BAND_2G; + case NL80211_BAND_5GHZ: + return RTW89_BAND_5G; + case NL80211_BAND_6GHZ: + return RTW89_BAND_6G; + } +} + +static inline +enum rtw89_bandwidth nl_to_rtw89_bandwidth(enum nl80211_chan_width width) +{ + switch (width) { + default: + WARN(1, "Not support bandwidth %d\n", width); + fallthrough; + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + return RTW89_CHANNEL_WIDTH_20; + case NL80211_CHAN_WIDTH_40: + return RTW89_CHANNEL_WIDTH_40; + case NL80211_CHAN_WIDTH_80: + return RTW89_CHANNEL_WIDTH_80; + case NL80211_CHAN_WIDTH_160: + return RTW89_CHANNEL_WIDTH_160; + } +} + +static inline +enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua) +{ + switch (rua) { + default: + WARN(1, "Invalid RU allocation: %d\n", rua); + fallthrough; + case 0 ... 36: + return NL80211_RATE_INFO_HE_RU_ALLOC_26; + case 37 ... 52: + return NL80211_RATE_INFO_HE_RU_ALLOC_52; + case 53 ... 60: + return NL80211_RATE_INFO_HE_RU_ALLOC_106; + case 61 ... 64: + return NL80211_RATE_INFO_HE_RU_ALLOC_242; + case 65 ... 66: + return NL80211_RATE_INFO_HE_RU_ALLOC_484; + case 67: + return NL80211_RATE_INFO_HE_RU_ALLOC_996; + case 68: + return NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + } +} + +static inline +struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + if (rtwsta_link) { + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + return &rtwsta_link->addr_cam; + } + return &rtwvif_link->addr_cam; +} + +static inline +struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + if (rtwsta_link) { + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); + + if (sta->tdls) + return &rtwsta_link->bssid_cam; + } + return &rtwvif_link->bssid_cam; +} + +static inline +void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtwdev->chip->ops->set_channel_help(rtwdev, true, p, chan, + mac_idx, phy_idx); +} + +static inline +void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtwdev->chip->ops->set_channel_help(rtwdev, false, p, chan, + mac_idx, phy_idx); +} + +static inline +const struct cfg80211_chan_def *rtw89_chandef_get(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_chanctx_idx roc_idx = atomic_read(&hal->roc_chanctx_idx); + + if (roc_idx == idx) + return &hal->roc_chandef; + + return &hal->chanctx[idx].chandef; +} + +static inline +const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + return &hal->chanctx[idx].chan; +} + +static inline +const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx idx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + return &hal->chanctx[idx].rcd; +} + +static inline +const struct rtw89_chan_rcd *rtw89_chan_rcd_get_by_chan(const struct rtw89_chan *chan) +{ + const struct rtw89_chanctx *chanctx = + container_of_const(chan, struct rtw89_chanctx, chan); + + return &chanctx->rcd; +} + +static inline +const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + + if (rtwvif_link) + return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + else + return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); +} + +static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->fem_setup) + chip->ops->fem_setup(rtwdev); +} + +static inline int rtw89_chip_data_setup(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->data_setup) + return 0; + + return chip->ops->data_setup(rtwdev); +} + +static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfe_gpio) + chip->ops->rfe_gpio(rtwdev); +} + +static inline void rtw89_chip_rfk_hw_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_hw_init) + chip->ops->rfk_hw_init(rtwdev); +} + +static inline +void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->bb_preinit) + return; + + chip->ops->bb_preinit(rtwdev, RTW89_PHY_0); + + if (rtwdev->dbcc_en) + chip->ops->bb_preinit(rtwdev, RTW89_PHY_1); +} + +static inline +void rtw89_chip_bb_postinit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->bb_postinit) + return; + + chip->ops->bb_postinit(rtwdev, RTW89_PHY_0); + + if (rtwdev->dbcc_en) + chip->ops->bb_postinit(rtwdev, RTW89_PHY_1); +} + +static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + rtw89_io_pack(rtwdev); + + if (chip->ops->bb_sethw) + chip->ops->bb_sethw(rtwdev); + + rtw89_io_unpack(rtwdev); +} + +static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_init) + chip->ops->rfk_init(rtwdev); +} + +static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_init_late) + chip->ops->rfk_init_late(rtwdev); +} + +static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_band_changed) + chip->ops->rfk_band_changed(rtwdev, phy_idx, chan); +} + +static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_scan) + chip->ops->rfk_scan(rtwdev, rtwvif_link, start); +} + +static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->rfk_track) + chip->ops->rfk_track(rtwdev); +} + +static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->set_txpwr_ctrl) + return; + + chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_1); +} + +static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->power_trim) + chip->ops->power_trim(rtwdev); +} + +static inline void rtw89_chip_path_diff_update(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->path_diff_update) + chip->ops->path_diff_update(rtwdev, bb); +} + +static inline void __rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->init_txpwr_unit) + chip->ops->init_txpwr_unit(rtwdev, phy_idx); +} + +static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev) +{ + __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_1); +} + +static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->get_thermal) + return 0x10; + + return chip->ops->get_thermal(rtwdev, rf_path); +} + +static inline u32 rtw89_chip_chan_to_rf18_val(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->chan_to_rf18_val) + return 0; + + return chip->ops->chan_to_rf18_val(rtwdev, chan); +} + +static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->query_ppdu) + chip->ops->query_ppdu(rtwdev, phy_ppdu, status); +} + +static inline void rtw89_chip_convert_rpl_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->convert_rpl_to_rssi) + chip->ops->convert_rpl_to_rssi(rtwdev, phy_ppdu); +} + +static inline void rtw89_chip_phy_rpt_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->phy_rpt_to_rssi) + chip->ops->phy_rpt_to_rssi(rtwdev, desc_info, rx_status); +} + +static inline void rtw89_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->ctrl_nbtg_bt_tx) + chip->ops->ctrl_nbtg_bt_tx(rtwdev, en, phy_idx); +} + +static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->cfg_txrx_path) + chip->ops->cfg_txrx_path(rtwdev); +} + +static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->digital_pwr_comp) + chip->ops->digital_pwr_comp(rtwdev, phy_idx); +} + +static inline +void rtw89_chip_calc_rx_gain_normal(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx, + struct rtw89_phy_calc_efuse_gain *calc) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->calc_rx_gain_normal) + chip->ops->calc_rx_gain_normal(rtwdev, chan, path, phy_idx, calc); +} + +static inline const struct rtw89_fw_def * +__rtw89_chip_get_fw_def(const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant) +{ + if (variant && variant->fw_def_override) + return variant->fw_def_override; + + return &chip->fw_def; +} + +static inline +const struct rtw89_fw_def *rtw89_chip_get_fw_def(struct rtw89_dev *rtwdev) +{ + return __rtw89_chip_get_fw_def(rtwdev->chip, rtwdev->variant); +} + +static inline +const struct rtw89_qta_def *rtw89_chip_get_qta_def(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_variant *variant = rtwdev->variant; + + if (variant && variant->qta_def_override) + return variant->qta_def_override; + + return &rtwdev->chip->qta_def; +} + +static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl) +{ + tbl->load(rtwdev, tbl); +} + +static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band) +{ + const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + u8 txpwr_regd = regd->txpwr_regd[band]; + + if (regulatory->txpwr_uk_follow_etsi && txpwr_regd == RTW89_UK) + return RTW89_ETSI; + + return txpwr_regd; +} + +static inline u8 rtw89_get_tx_shape_idx(struct rtw89_dev *rtwdev, u8 band, + enum rtw89_rate_section rs) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; + const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape; + u8 reg6_pwr = regulatory->reg_6ghz_power; + u8 regd = rtw89_regd_get(rtwdev, band); + + if (unlikely(rs >= RTW89_RS_TX_SHAPE_NUM)) + rs = RTW89_RS_OFDM; + + if (!tx_shape->lmt) + goto v0; + + if (band != RTW89_BAND_6G) + reg6_pwr = RTW89_REG_6GHZ_POWER_DFLT; + + return (*tx_shape->lmt)[band][rs][regd][reg6_pwr]; + +v0: + return (*tx_shape->lmt_v0)[band][rs][regd]; +} + +static inline void rtw89_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->ctrl_btg_bt_rx) + chip->ops->ctrl_btg_bt_rx(rtwdev, en, phy_idx); +} + +static inline +void rtw89_chip_query_rxdesc(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->query_rxdesc(rtwdev, desc_info, data, data_offset); +} + +static inline +void rtw89_chip_fill_txdesc(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->fill_txdesc(rtwdev, desc_info, txdesc); +} + +static inline +void rtw89_chip_fill_txdesc_fwcmd(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->fill_txdesc_fwcmd(rtwdev, desc_info, txdesc); +} + +static inline +u8 rtw89_chip_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->get_ch_dma[rtwdev->hci.type](rtwdev, qsel); +} + +static inline +void rtw89_chip_mac_cfg_gnt(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->mac_cfg_gnt(rtwdev, gnt_cfg); +} + +static inline void rtw89_chip_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->cfg_ctrl_path(rtwdev, wl); +} + +static inline +int rtw89_chip_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->stop_sch_tx(rtwdev, mac_idx, tx_en, sel); +} + +static inline +int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->resume_sch_tx(rtwdev, mac_idx, tx_en); +} + +static inline +int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->h2c_dctl_sec_cam) + return 0; + return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); +} + +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) +{ + __le16 fc = hdr->frame_control; + + if (ieee80211_has_tods(fc)) + return hdr->addr1; + else if (ieee80211_has_fromds(fc)) + return hdr->addr2; + else + return hdr->addr3; +} + +static inline +bool rtw89_sta_has_beamformer_cap(struct ieee80211_link_sta *link_sta) +{ + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || + (link_sta->he_cap.he_cap_elem.phy_cap_info[3] & + IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || + (link_sta->he_cap.he_cap_elem.phy_cap_info[4] & + IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) + return true; + return false; +} + +static inline +bool rtw89_sta_link_has_su_mu_4xhe08(struct ieee80211_link_sta *link_sta) +{ + if (link_sta->he_cap.he_cap_elem.phy_cap_info[7] & + IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI) + return true; + + return false; +} + +static inline +bool rtw89_sta_link_has_er_su_4xhe08(struct ieee80211_link_sta *link_sta) +{ + if (link_sta->he_cap.he_cap_elem.phy_cap_info[8] & + IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI) + return true; + + return false; +} + +static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, + enum rtw89_fw_type type) +{ + struct rtw89_fw_info *fw_info = &rtwdev->fw; + + switch (type) { + case RTW89_FW_WOWLAN: + case RTW89_FW_WOWLAN_B: + return &fw_info->wowlan; + case RTW89_FW_LOGFMT: + return &fw_info->log.suit; + case RTW89_FW_BBMCU0: + return &fw_info->bbmcu0; + case RTW89_FW_BBMCU1: + return &fw_info->bbmcu1; + default: + break; + } + + return &fw_info->normal; +} + +static inline struct sk_buff *rtw89_alloc_skb_for_rx(struct rtw89_dev *rtwdev, + unsigned int length) +{ + struct sk_buff *skb; + + if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) { + skb = dev_alloc_skb(length + RTW89_RADIOTAP_ROOM); + if (!skb) + return NULL; + + skb_reserve(skb, RTW89_RADIOTAP_ROOM); + return skb; + } + + return dev_alloc_skb(length); +} + +static inline bool rtw89_core_is_tx_wait(struct rtw89_dev *rtwdev, + struct rtw89_tx_skb_data *skb_data) +{ + return rcu_access_pointer(skb_data->wait); +} + +static inline bool rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev, + struct rtw89_tx_skb_data *skb_data, + u8 tx_status) +{ + struct rtw89_tx_wait_info *wait; + + guard(rcu)(); + + wait = rcu_dereference(skb_data->wait); + if (!wait) + return false; + + wait->tx_done = tx_status == RTW89_TX_DONE; + /* Don't access skb anymore after completion */ + complete_all(&wait->completion); + return true; +} + +static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev) +{ + switch (rtwdev->mlo_dbcc_mode) { + case MLO_1_PLUS_1_1RF: + case MLO_1_PLUS_1_2RF: + case DBCC_LEGACY: + return true; + default: + return false; + } +} + +static inline u8 rtw89_get_active_phy_bitmap(struct rtw89_dev *rtwdev) +{ + if (!rtwdev->dbcc_en) + return BIT(RTW89_PHY_0); + + switch (rtwdev->mlo_dbcc_mode) { + case MLO_0_PLUS_2_1RF: + case MLO_0_PLUS_2_2RF: + return BIT(RTW89_PHY_1); + case MLO_1_PLUS_1_1RF: + case MLO_1_PLUS_1_2RF: + case MLO_2_PLUS_2_2RF: + case DBCC_LEGACY: + return BIT(RTW89_PHY_0) | BIT(RTW89_PHY_1); + case MLO_2_PLUS_0_1RF: + case MLO_2_PLUS_0_2RF: + default: + return BIT(RTW89_PHY_0); + } +} + +#define rtw89_for_each_active_bb(rtwdev, bb) \ + for (u8 __active_bb_bitmap = rtw89_get_active_phy_bitmap(rtwdev), \ + __phy_idx = 0; __phy_idx < RTW89_PHY_NUM; __phy_idx++) \ + if (__active_bb_bitmap & BIT(__phy_idx) && \ + (bb = &rtwdev->bbs[__phy_idx])) + +#define rtw89_for_each_capab_bb(rtwdev, bb) \ + for (u8 __phy_idx_max = rtwdev->dbcc_en ? RTW89_PHY_1 : RTW89_PHY_0, \ + __phy_idx = 0; __phy_idx <= __phy_idx_max; __phy_idx++) \ + if ((bb = &rtwdev->bbs[__phy_idx])) + +static inline +struct rtw89_bb_ctx *rtw89_get_bb_ctx(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + if (phy_idx >= RTW89_PHY_NUM) + return &rtwdev->bbs[RTW89_PHY_0]; + + return &rtwdev->bbs[phy_idx]; +} + +static inline bool rtw89_is_rtl885xb(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + if (chip_id == RTL8852B || chip_id == RTL8851B || chip_id == RTL8852BT) + return true; + + return false; +} + +static inline u32 rtw89_bytes_to_mbps(u64 bytes, enum rtw89_tfc_interval interval) +{ + switch (interval) { + default: + case RTW89_TFC_INTERVAL_2SEC: + return bytes >> 18; /* bytes/2s --> Mbps */; + case RTW89_TFC_INTERVAL_100MS: + return (bytes * 10) >> 17; /* bytes/100ms --> Mbps */ + } +} + +int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); +int rtw89_h2c_tx(struct rtw89_dev *rtwdev, + struct sk_buff *skb, bool fwdl); +void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); +int rtw89_core_tx_kick_off_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, + struct rtw89_tx_wait_info *wait, int qsel, + unsigned int timeout); +void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +void rtw89_core_fill_txdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +void rtw89_core_fill_txdesc_fwcmd_v2(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); +u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel); +u8 rtw89_core_get_ch_dma_v1(struct rtw89_dev *rtwdev, u8 qsel); +u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel); +void rtw89_core_rx(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct sk_buff *skb); +void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset); +void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset); +void rtw89_core_query_rxdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset); +void rtw89_core_napi_start(struct rtw89_dev *rtwdev); +void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); +int rtw89_core_napi_init(struct rtw89_dev *rtwdev); +void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev); +int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta, + struct cfg80211_tid_config *tid_config); +void rtw89_core_tid_rx_stats_ctrl(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, + struct ieee80211_ampdu_params *params, bool enable); +void rtw89_core_tid_rx_stats_reset(struct rtw89_dev *rtwdev); +void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force); +void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks); +int rtw89_core_init(struct rtw89_dev *rtwdev); +void rtw89_core_deinit(struct rtw89_dev *rtwdev); +int rtw89_core_register(struct rtw89_dev *rtwdev); +void rtw89_core_unregister(struct rtw89_dev *rtwdev); +struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + u32 bus_data_size, + const struct rtw89_driver_info *info); +void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev); +u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev); +void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id); +void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u8 mac_id, u8 port); +void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, u8 mac_id); +struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif, + unsigned int link_id); +void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id); +struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta, + unsigned int link_id); +void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id); +void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev); +void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +const struct rtw89_6ghz_span * +rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq); +void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef); +void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef, + struct rtw89_chan *chan); +int rtw89_set_channel(struct rtw89_dev *rtwdev); +u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); +void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); +void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); +int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx); +int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx); +void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); +void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); +void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); +void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc); +int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); +void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +bool rtw89_legacy_rate_to_bitrate(struct rtw89_dev *rtwdev, u8 legacy_rate, u16 *bitrate); +int rtw89_regd_setup(struct rtw89_dev *rtwdev); +int rtw89_regd_init_hint(struct rtw89_dev *rtwdev); +const char *rtw89_regd_get_string(enum rtw89_regulation_type regd); +void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, + struct rtw89_traffic_stats *stats); +struct rtw89_wait_response * +rtw89_wait_for_cond_prep(struct rtw89_wait_info *wait, unsigned int cond) +__acquires(rtw89_wait); +int rtw89_wait_for_cond_eval(struct rtw89_wait_info *wait, + struct rtw89_wait_response *prep, int err) +__releases(rtw89_wait); +void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, + const struct rtw89_completion_data *data); +int rtw89_core_start(struct rtw89_dev *rtwdev); +void rtw89_core_stop(struct rtw89_dev *rtwdev); +void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); +int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool qos, bool ps, int timeout); +void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool hw_scan); +void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool hw_scan); +int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool active); +void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf); +void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, + enum rtw89_btc_hmsg event, + enum rtw89_phy_idx phy_idx); +int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + unsigned int link_id); +void rtw89_core_dm_disable_cfg(struct rtw89_dev *rtwdev, u32 new); +void rtw89_core_dm_disable_set(struct rtw89_dev *rtwdev, enum rtw89_dm_type type); +void rtw89_core_dm_disable_clr(struct rtw89_dev *rtwdev, enum rtw89_dm_type type); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c new file mode 100644 index 000000000..7e640c716 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -0,0 +1,5725 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include +#include + +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "pci.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "sar.h" +#include "util.h" + +#ifdef CONFIG_RTW89_DEBUGMSG +unsigned int rtw89_debug_mask; +EXPORT_SYMBOL(rtw89_debug_mask); +module_param_named(debug_mask, rtw89_debug_mask, uint, 0644); +MODULE_PARM_DESC(debug_mask, "Debugging mask"); +#endif + +#ifdef CONFIG_RTW89_DEBUGFS +struct rtw89_debugfs_priv_opt { + bool rlock:1; + bool wlock:1; + size_t rsize; +}; + +struct rtw89_debugfs_priv { + struct rtw89_dev *rtwdev; + ssize_t (*cb_read)(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz); + ssize_t (*cb_write)(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count); + struct rtw89_debugfs_priv_opt opt; + union { + u32 cb_data; + struct { + u32 addr; + u32 len; + } read_reg; + struct { + u32 addr; + u32 mask; + u8 path; + } read_rf; + struct { + u8 ss_dbg:1; + u8 dle_dbg:1; + u8 dmac_dbg:1; + u8 cmac_dbg:1; + u8 dbg_port:1; + } dbgpkg_en; + struct { + u32 start; + u32 len; + u8 sel; + } mac_mem; + }; + ssize_t rused; + char *rbuf; +}; + +struct rtw89_debugfs { + struct rtw89_debugfs_priv read_reg; + struct rtw89_debugfs_priv write_reg; + struct rtw89_debugfs_priv read_rf; + struct rtw89_debugfs_priv write_rf; + struct rtw89_debugfs_priv rf_reg_dump; + struct rtw89_debugfs_priv txpwr_table; + struct rtw89_debugfs_priv mac_reg_dump; + struct rtw89_debugfs_priv mac_mem_dump; + struct rtw89_debugfs_priv mac_dbg_port_dump; + struct rtw89_debugfs_priv send_h2c; + struct rtw89_debugfs_priv early_h2c; + struct rtw89_debugfs_priv fw_crash; + struct rtw89_debugfs_priv ser_counters; + struct rtw89_debugfs_priv btc_info; + struct rtw89_debugfs_priv btc_manual; + struct rtw89_debugfs_priv fw_log_manual; + struct rtw89_debugfs_priv phy_info; + struct rtw89_debugfs_priv bb_info; + struct rtw89_debugfs_priv stations; + struct rtw89_debugfs_priv disable_dm; + struct rtw89_debugfs_priv static_pd_th; + struct rtw89_debugfs_priv mlo_mode; + struct rtw89_debugfs_priv beacon_info; + struct rtw89_debugfs_priv diag_mac; + struct rtw89_debugfs_priv diag_bb; + struct rtw89_debugfs_priv diag_rf; + struct rtw89_debugfs_priv monitor_opts; +}; + +struct rtw89_debugfs_iter_data { + char *buf; + size_t bufsz; + int written_sz; +}; + +static void rtw89_debugfs_iter_data_setup(struct rtw89_debugfs_iter_data *iter_data, + char *buf, size_t bufsz) +{ + iter_data->buf = buf; + iter_data->bufsz = bufsz; + iter_data->written_sz = 0; +} + +static void rtw89_debugfs_iter_data_next(struct rtw89_debugfs_iter_data *iter_data, + char *buf, size_t bufsz, int written_sz) +{ + iter_data->buf = buf; + iter_data->bufsz = bufsz; + iter_data->written_sz += written_sz; +} + +static const u16 rtw89_rate_info_bw_to_mhz_map[] = { + [RATE_INFO_BW_20] = 20, + [RATE_INFO_BW_40] = 40, + [RATE_INFO_BW_80] = 80, + [RATE_INFO_BW_160] = 160, + [RATE_INFO_BW_320] = 320, +}; + +static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw) +{ + if (bw < ARRAY_SIZE(rtw89_rate_info_bw_to_mhz_map)) + return rtw89_rate_info_bw_to_mhz_map[bw]; + + return 0; +} + +static ssize_t rtw89_debugfs_file_read_helper(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsz, void *data) +{ + struct rtw89_debugfs_priv *debugfs_priv = data; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + ssize_t n; + + n = debugfs_priv->cb_read(rtwdev, debugfs_priv, buf, bufsz); + rtw89_might_trailing_ellipsis(buf, bufsz, n); + + return n; +} + +static ssize_t rtw89_debugfs_file_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct rtw89_debugfs_priv *debugfs_priv = file->private_data; + struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + size_t bufsz = opt->rsize ? opt->rsize : PAGE_SIZE; + char *buf; + ssize_t n; + + if (!debugfs_priv->rbuf) + debugfs_priv->rbuf = devm_kzalloc(rtwdev->dev, bufsz, GFP_KERNEL); + + buf = debugfs_priv->rbuf; + if (!buf) + return -ENOMEM; + + if (*ppos) { + n = debugfs_priv->rused; + goto out; + } + + if (opt->rlock) { + n = wiphy_locked_debugfs_read(rtwdev->hw->wiphy, file, buf, bufsz, + userbuf, count, ppos, + rtw89_debugfs_file_read_helper, + debugfs_priv); + debugfs_priv->rused = n; + + return n; + } + + n = rtw89_debugfs_file_read_helper(rtwdev->hw->wiphy, file, buf, bufsz, + debugfs_priv); + debugfs_priv->rused = n; + +out: + return simple_read_from_buffer(userbuf, count, ppos, buf, n); +} + +static ssize_t rtw89_debugfs_file_write_helper(struct wiphy *wiphy, struct file *file, + char *buf, size_t count, void *data) +{ + struct rtw89_debugfs_priv *debugfs_priv = data; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + + return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count); +} + +static ssize_t rtw89_debugfs_file_write(struct file *file, + const char __user *userbuf, + size_t count, loff_t *loff) +{ + struct rtw89_debugfs_priv *debugfs_priv = file->private_data; + struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *buf __free(kfree) = kmalloc(count + 1, GFP_KERNEL); + ssize_t n; + + if (!buf) + return -ENOMEM; + + if (opt->wlock) { + n = wiphy_locked_debugfs_write(rtwdev->hw->wiphy, + file, buf, count + 1, + userbuf, count, + rtw89_debugfs_file_write_helper, + debugfs_priv); + return n; + } + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = '\0'; + + return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count); +} + +static const struct debugfs_short_fops file_ops_single_r = { + .read = rtw89_debugfs_file_read, + .llseek = generic_file_llseek, +}; + +static const struct debugfs_short_fops file_ops_common_rw = { + .read = rtw89_debugfs_file_read, + .write = rtw89_debugfs_file_write, + .llseek = generic_file_llseek, +}; + +static const struct debugfs_short_fops file_ops_single_w = { + .write = rtw89_debugfs_file_write, + .llseek = generic_file_llseek, +}; + +static ssize_t +rtw89_debug_priv_read_reg_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 addr, len; + int num; + + num = sscanf(buf, "%x %x", &addr, &len); + if (num != 2) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + debugfs_priv->read_reg.addr = addr; + debugfs_priv->read_reg.len = len; + + rtw89_info(rtwdev, "select read %d bytes from 0x%08x\n", len, addr); + + return count; +} + +static +ssize_t rtw89_debug_priv_read_reg_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + u32 addr, addr_end, data, k; + u32 len; + + len = debugfs_priv->read_reg.len; + addr = debugfs_priv->read_reg.addr; + + if (len > 4) + goto ndata; + + switch (len) { + case 1: + data = rtw89_read8(rtwdev, addr); + break; + case 2: + data = rtw89_read16(rtwdev, addr); + break; + case 4: + data = rtw89_read32(rtwdev, addr); + break; + default: + rtw89_info(rtwdev, "invalid read reg len %d\n", len); + return -EINVAL; + } + + p += scnprintf(p, end - p, "get %d bytes at 0x%08x=0x%08x\n", len, + addr, data); + + return p - buf; + +ndata: + addr_end = addr + len; + + for (; addr < addr_end; addr += 16) { + p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + addr); + for (k = 0; k < 16; k += 4) { + data = rtw89_read32(rtwdev, addr + k); + p += scnprintf(p, end - p, "%08x ", data); + } + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +static +ssize_t rtw89_debug_priv_write_reg_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 addr, val, len; + int num; + + num = sscanf(buf, "%x %x %x", &addr, &val, &len); + if (num != 3) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + switch (len) { + case 1: + rtw89_info(rtwdev, "reg write8 0x%08x: 0x%02x\n", addr, val); + rtw89_write8(rtwdev, addr, (u8)val); + break; + case 2: + rtw89_info(rtwdev, "reg write16 0x%08x: 0x%04x\n", addr, val); + rtw89_write16(rtwdev, addr, (u16)val); + break; + case 4: + rtw89_info(rtwdev, "reg write32 0x%08x: 0x%08x\n", addr, val); + rtw89_write32(rtwdev, addr, (u32)val); + break; + default: + rtw89_info(rtwdev, "invalid read write len %d\n", len); + break; + } + + return count; +} + +static ssize_t +rtw89_debug_priv_read_rf_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 addr, mask; + u8 path; + int num; + + num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask); + if (num != 3) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + if (path >= rtwdev->chip->rf_path_num) { + rtw89_info(rtwdev, "wrong rf path\n"); + return -EINVAL; + } + debugfs_priv->read_rf.addr = addr; + debugfs_priv->read_rf.mask = mask; + debugfs_priv->read_rf.path = path; + + rtw89_info(rtwdev, "select read rf path %d from 0x%08x\n", path, addr); + + return count; +} + +static +ssize_t rtw89_debug_priv_read_rf_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + u32 addr, data, mask; + u8 path; + + addr = debugfs_priv->read_rf.addr; + mask = debugfs_priv->read_rf.mask; + path = debugfs_priv->read_rf.path; + + data = rtw89_read_rf(rtwdev, path, addr, mask); + + p += scnprintf(p, end - p, "path %d, rf register 0x%08x=0x%08x\n", + path, addr, data); + + return p - buf; +} + +static +ssize_t rtw89_debug_priv_write_rf_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 addr, val, mask; + u8 path; + int num; + + num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val); + if (num != 4) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + if (path >= rtwdev->chip->rf_path_num) { + rtw89_info(rtwdev, "wrong rf path\n"); + return -EINVAL; + } + + rtw89_info(rtwdev, "path %d, rf register write 0x%08x=0x%08x (mask = 0x%08x)\n", + path, addr, val, mask); + rtw89_write_rf(rtwdev, path, addr, mask, val); + + return count; +} + +static +ssize_t rtw89_debug_priv_rf_reg_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; + u32 addr, offset, data; + u8 path; + + for (path = 0; path < chip->rf_path_num; path++) { + p += scnprintf(p, end - p, "RF path %d:\n\n", path); + for (addr = 0; addr < 0x100; addr += 4) { + p += scnprintf(p, end - p, "0x%08x: ", addr); + for (offset = 0; offset < 4; offset++) { + data = rtw89_read_rf(rtwdev, path, + addr + offset, RFREG_MASK); + p += scnprintf(p, end - p, "0x%05x ", data); + } + p += scnprintf(p, end - p, "\n"); + } + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +struct txpwr_ent { + bool nested; + union { + const char *txt; + const struct txpwr_ent *ptr; + }; + u8 len; +}; + +struct txpwr_map { + const struct txpwr_ent *ent; + u8 size; + u32 addr_from; + u32 addr_to; + u32 addr_to_1ss; +}; + +#define __GEN_TXPWR_ENT_NESTED(_e) \ + { .nested = true, .ptr = __txpwr_ent_##_e, \ + .len = ARRAY_SIZE(__txpwr_ent_##_e) } + +#define __GEN_TXPWR_ENT0(_t) { .len = 0, .txt = _t } + +#define __GEN_TXPWR_ENT2(_t, _e0, _e1) \ + { .len = 2, .txt = _t "\t- " _e0 " " _e1 } + +#define __GEN_TXPWR_ENT4(_t, _e0, _e1, _e2, _e3) \ + { .len = 4, .txt = _t "\t- " _e0 " " _e1 " " _e2 " " _e3 } + +#define __GEN_TXPWR_ENT8(_t, _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7) \ + { .len = 8, .txt = _t "\t- " \ + _e0 " " _e1 " " _e2 " " _e3 " " \ + _e4 " " _e5 " " _e6 " " _e7 } + +static const struct txpwr_ent __txpwr_ent_byr_ax[] = { + __GEN_TXPWR_ENT4("CCK ", "1M ", "2M ", "5.5M ", "11M "), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + /* 1NSS */ + __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT4("HEDCM_1NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), + /* 2NSS */ + __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT4("HEDCM_2NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), +}; + +static_assert((ARRAY_SIZE(__txpwr_ent_byr_ax) * 4) == + (R_AX_PWR_BY_RATE_MAX - R_AX_PWR_BY_RATE + 4)); + +static const struct txpwr_map __txpwr_map_byr_ax = { + .ent = __txpwr_ent_byr_ax, + .size = ARRAY_SIZE(__txpwr_ent_byr_ax), + .addr_from = R_AX_PWR_BY_RATE, + .addr_to = R_AX_PWR_BY_RATE_MAX, + .addr_to_1ss = R_AX_PWR_BY_RATE_1SS_MAX, +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ax[] = { + /* 1TX */ + __GEN_TXPWR_ENT2("CCK_1TX_20M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("CCK_1TX_40M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("OFDM_1TX ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_4 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_5 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_6 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_20M_7 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_80M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_80M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_160M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_0p5", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_1TX_40M_2p5", "NON_BF", "BF"), + /* 2TX */ + __GEN_TXPWR_ENT2("CCK_2TX_20M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("CCK_2TX_40M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("OFDM_2TX ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_4 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_5 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_6 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_20M_7 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_80M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_80M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_160M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_0p5", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_2TX_40M_2p5", "NON_BF", "BF"), +}; + +static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ax) * 2) == + (R_AX_PWR_LMT_MAX - R_AX_PWR_LMT + 4)); + +static const struct txpwr_map __txpwr_map_lmt_ax = { + .ent = __txpwr_ent_lmt_ax, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ax), + .addr_from = R_AX_PWR_LMT, + .addr_to = R_AX_PWR_LMT_MAX, + .addr_to_1ss = R_AX_PWR_LMT_1SS_MAX, +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru_ax[] = { + /* 1TX */ + __GEN_TXPWR_ENT8("1TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", + "RU26__4", "RU26__5", "RU26__6", "RU26__7"), + __GEN_TXPWR_ENT8("1TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", + "RU52__4", "RU52__5", "RU52__6", "RU52__7"), + __GEN_TXPWR_ENT8("1TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", + "RU106_4", "RU106_5", "RU106_6", "RU106_7"), + /* 2TX */ + __GEN_TXPWR_ENT8("2TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", + "RU26__4", "RU26__5", "RU26__6", "RU26__7"), + __GEN_TXPWR_ENT8("2TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", + "RU52__4", "RU52__5", "RU52__6", "RU52__7"), + __GEN_TXPWR_ENT8("2TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", + "RU106_4", "RU106_5", "RU106_6", "RU106_7"), +}; + +static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ru_ax) * 8) == + (R_AX_PWR_RU_LMT_MAX - R_AX_PWR_RU_LMT + 4)); + +static const struct txpwr_map __txpwr_map_lmt_ru_ax = { + .ent = __txpwr_ent_lmt_ru_ax, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ru_ax), + .addr_from = R_AX_PWR_RU_LMT, + .addr_to = R_AX_PWR_RU_LMT_MAX, + .addr_to_1ss = R_AX_PWR_RU_LMT_1SS_MAX, +}; + +static const struct txpwr_ent __txpwr_ent_byr_mcs_be[] = { + __GEN_TXPWR_ENT4("MCS_1SS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("MCS_1SS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("MCS_1SS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT2("MCS_1SS ", "MCS12 ", "MCS13 \t"), + __GEN_TXPWR_ENT4("HEDCM_1SS ", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), + __GEN_TXPWR_ENT4("DLRU_MCS_1SS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("DLRU_MCS_1SS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("DLRU_MCS_1SS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT2("DLRU_MCS_1SS ", "MCS12 ", "MCS13 \t"), + __GEN_TXPWR_ENT4("DLRU_HEDCM_1SS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), + __GEN_TXPWR_ENT4("MCS_2SS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("MCS_2SS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("MCS_2SS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT2("MCS_2SS ", "MCS12 ", "MCS13 \t"), + __GEN_TXPWR_ENT4("HEDCM_2SS ", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), + __GEN_TXPWR_ENT4("DLRU_MCS_2SS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), + __GEN_TXPWR_ENT4("DLRU_MCS_2SS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), + __GEN_TXPWR_ENT4("DLRU_MCS_2SS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), + __GEN_TXPWR_ENT2("DLRU_MCS_2SS ", "MCS12 ", "MCS13 \t"), + __GEN_TXPWR_ENT4("DLRU_HEDCM_2SS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), +}; + +static const struct txpwr_ent __txpwr_ent_byr_be[] = { + __GEN_TXPWR_ENT0("BW20"), + __GEN_TXPWR_ENT4("CCK ", "1M ", "2M ", "5.5M ", "11M "), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + __GEN_TXPWR_ENT2("EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT2("DLRU_EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT_NESTED(byr_mcs_be), + + __GEN_TXPWR_ENT0("BW40"), + __GEN_TXPWR_ENT4("CCK ", "1M ", "2M ", "5.5M ", "11M "), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + __GEN_TXPWR_ENT2("EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT2("DLRU_EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT_NESTED(byr_mcs_be), + + /* there is no CCK section after BW80 */ + __GEN_TXPWR_ENT0("BW80"), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + __GEN_TXPWR_ENT2("EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT2("DLRU_EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT_NESTED(byr_mcs_be), + + __GEN_TXPWR_ENT0("BW160"), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + __GEN_TXPWR_ENT2("EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT2("DLRU_EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT_NESTED(byr_mcs_be), + + __GEN_TXPWR_ENT0("BW320"), + __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), + __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), + __GEN_TXPWR_ENT2("EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT2("DLRU_EHT ", "MCS14 ", "MCS15 \t"), + __GEN_TXPWR_ENT_NESTED(byr_mcs_be), +}; + +static const struct txpwr_map __txpwr_map_byr_be = { + .ent = __txpwr_ent_byr_be, + .size = ARRAY_SIZE(__txpwr_ent_byr_be), + .addr_from = R_BE_PWR_BY_RATE, + .addr_to = R_BE_PWR_BY_RATE_MAX, + .addr_to_1ss = 0, /* not support */ +}; + +static const struct txpwr_ent __txpwr_ent_lmt_mcs_be[] = { + __GEN_TXPWR_ENT2("MCS_20M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_4 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_5 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_6 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_7 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_8 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_9 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_10 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_11 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_12 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_13 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_14 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_20M_15 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_4 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_5 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_6 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_7 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_80M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_80M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_80M_2 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_80M_3 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_160M_0 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_160M_1 ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_320M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_0p5", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_2p5", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_4p5", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("MCS_40M_6p5", "NON_BF", "BF"), +}; + +static const struct txpwr_ent __txpwr_ent_lmt_be[] = { + __GEN_TXPWR_ENT0("1TX"), + __GEN_TXPWR_ENT2("CCK_20M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("CCK_40M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("OFDM ", "NON_BF", "BF"), + __GEN_TXPWR_ENT_NESTED(lmt_mcs_be), + + __GEN_TXPWR_ENT0("2TX"), + __GEN_TXPWR_ENT2("CCK_20M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("CCK_40M ", "NON_BF", "BF"), + __GEN_TXPWR_ENT2("OFDM ", "NON_BF", "BF"), + __GEN_TXPWR_ENT_NESTED(lmt_mcs_be), +}; + +static const struct txpwr_map __txpwr_map_lmt_be = { + .ent = __txpwr_ent_lmt_be, + .size = ARRAY_SIZE(__txpwr_ent_lmt_be), + .addr_from = R_BE_PWR_LMT, + .addr_to = R_BE_PWR_LMT_MAX, + .addr_to_1ss = 0, /* not support */ +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru_indexes_be[] = { + __GEN_TXPWR_ENT8("RU26 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ", + "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "), + __GEN_TXPWR_ENT8("RU26 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11", + "IDX_12", "IDX_13", "IDX_14", "IDX_15"), + __GEN_TXPWR_ENT8("RU52 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ", + "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "), + __GEN_TXPWR_ENT8("RU52 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11", + "IDX_12", "IDX_13", "IDX_14", "IDX_15"), + __GEN_TXPWR_ENT8("RU106 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ", + "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "), + __GEN_TXPWR_ENT8("RU106 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11", + "IDX_12", "IDX_13", "IDX_14", "IDX_15"), + __GEN_TXPWR_ENT8("RU52_26 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ", + "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "), + __GEN_TXPWR_ENT8("RU52_26 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11", + "IDX_12", "IDX_13", "IDX_14", "IDX_15"), + __GEN_TXPWR_ENT8("RU106_26", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ", + "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "), + __GEN_TXPWR_ENT8("RU106_26", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11", + "IDX_12", "IDX_13", "IDX_14", "IDX_15"), +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru_be[] = { + __GEN_TXPWR_ENT0("1TX"), + __GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be), + + __GEN_TXPWR_ENT0("2TX"), + __GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be), +}; + +static const struct txpwr_map __txpwr_map_lmt_ru_be = { + .ent = __txpwr_ent_lmt_ru_be, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ru_be), + .addr_from = R_BE_PWR_RU_LMT, + .addr_to = R_BE_PWR_RU_LMT_MAX, + .addr_to_1ss = 0, /* not support */ +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru484_242_be[] = { + __GEN_TXPWR_ENT4("RU484_242 1TX ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 "), + __GEN_TXPWR_ENT4("RU484_242 2TX ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 "), +}; + +static const struct txpwr_map __txpwr_map_lmt_ru484_242_be = { + .ent = __txpwr_ent_lmt_ru484_242_be, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ru484_242_be), + .addr_from = R_BE_TXAGC_MAX_1TX_RU484_242_0, + .addr_to = R_BE_TXAGC_MAX_1TX_RU484_242_0 + 4, + .addr_to_1ss = 0, /* not support */ +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru996_484_be[] = { + __GEN_TXPWR_ENT2("RU996_484 1TX ", "IDX_0 ", "IDX_1 "), + __GEN_TXPWR_ENT2("RU996_484 2TX ", "IDX_0 ", "IDX_1 "), +}; + +static const struct txpwr_map __txpwr_map_lmt_ru996_484_be = { + .ent = __txpwr_ent_lmt_ru996_484_be, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ru996_484_be), + .addr_from = R_BE_TXAGC_MAX_1TX_RU996_484_0, + .addr_to = R_BE_TXAGC_MAX_1TX_RU996_484_0, + .addr_to_1ss = 0, /* not support */ +}; + +static const struct txpwr_ent __txpwr_ent_lmt_ru996_484_242_be[] = { + __GEN_TXPWR_ENT2("RU996_484_242 1TX ", "IDX_0 ", "IDX_1 "), + __GEN_TXPWR_ENT2("RU996_484_242 2TX ", "IDX_0 ", "IDX_1 "), +}; + +static const struct txpwr_map __txpwr_map_lmt_ru996_484_242_be = { + .ent = __txpwr_ent_lmt_ru996_484_242_be, + .size = ARRAY_SIZE(__txpwr_ent_lmt_ru996_484_242_be), + .addr_from = R_BE_TXAGC_MAX_1TX_RU996_484_242_0, + .addr_to = R_BE_TXAGC_MAX_1TX_RU996_484_242_0, + .addr_to_1ss = 0, /* not support */ +}; + +static unsigned int +__print_txpwr_ent(char *buf, size_t bufsz, const struct txpwr_ent *ent, + const s8 *bufp, const unsigned int cur, unsigned int *ate) +{ + char *p = buf, *end = buf + bufsz; + unsigned int cnt, i; + unsigned int eaten; + char *fmt; + + if (ent->nested) { + for (cnt = 0, i = 0; i < ent->len; i++, cnt += eaten) + p += __print_txpwr_ent(p, end - p, ent->ptr + i, bufp, + cur + cnt, &eaten); + *ate = cnt; + goto out; + } + + switch (ent->len) { + case 0: + p += scnprintf(p, end - p, "\t<< %s >>\n", ent->txt); + *ate = 0; + goto out; + case 2: + fmt = "%s\t| %3d, %3d,\t\tdBm\n"; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1]); + *ate = 2; + goto out; + case 4: + fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n"; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1], + bufp[cur + 2], bufp[cur + 3]); + *ate = 4; + goto out; + case 8: + fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n"; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1], + bufp[cur + 2], bufp[cur + 3], bufp[cur + 4], + bufp[cur + 5], bufp[cur + 6], bufp[cur + 7]); + *ate = 8; + goto out; + default: + return 0; + } + +out: + return p - buf; +} + +static ssize_t __print_txpwr_map(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct txpwr_map *map) +{ + u8 fct = rtwdev->chip->txpwr_factor_mac; + u8 path_num = rtwdev->chip->rf_path_num; + char *p = buf, *end = buf + bufsz; + unsigned int cur, i; + unsigned int eaten; + u32 max_valid_addr; + u32 val, addr; + s8 *bufp, tmp; + int ret; + + if (path_num == 1) + max_valid_addr = map->addr_to_1ss; + else + max_valid_addr = map->addr_to; + + if (max_valid_addr == 0) + return -EOPNOTSUPP; + + bufp = vzalloc(map->addr_to - map->addr_from + 4); + if (!bufp) + return -ENOMEM; + + for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) { + ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val); + if (ret) + val = MASKDWORD; + + cur = addr - map->addr_from; + for (i = 0; i < 4; i++, val >>= 8) { + /* signed 7 bits, and reserved BIT(7) */ + tmp = sign_extend32(val, 6); + bufp[cur + i] = tmp >> fct; + } + } + + for (cur = 0, i = 0; i < map->size; i++, cur += eaten) + p += __print_txpwr_ent(p, end - p, &map->ent[i], bufp, cur, &eaten); + + vfree(bufp); + return p - buf; +} + +static int __print_regd(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan) +{ + const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + char *p = buf, *end = buf + bufsz; + u8 band = chan->band_type; + u8 regd = rtw89_regd_get(rtwdev, band); + + p += scnprintf(p, end - p, "%s\n", rtw89_regd_get_string(regd)); + p += scnprintf(p, end - p, "\t(txpwr UK follow ETSI: %s)\n", + str_yes_no(regulatory->txpwr_uk_follow_etsi)); + + return p - buf; +} + +struct dbgfs_txpwr_table { + const struct txpwr_map *byr; + const struct txpwr_map *lmt; + const struct txpwr_map *lmt_ru; + const struct txpwr_map *lmt_ru484_242; + const struct txpwr_map *lmt_ru996_484; + const struct txpwr_map *lmt_ru996_484_242; +}; + +static const struct dbgfs_txpwr_table dbgfs_txpwr_table_ax = { + .byr = &__txpwr_map_byr_ax, + .lmt = &__txpwr_map_lmt_ax, + .lmt_ru = &__txpwr_map_lmt_ru_ax, +}; + +static const struct dbgfs_txpwr_table dbgfs_txpwr_table_be = { + .byr = &__txpwr_map_byr_be, + .lmt = &__txpwr_map_lmt_be, + .lmt_ru = &__txpwr_map_lmt_ru_be, + .lmt_ru484_242 = &__txpwr_map_lmt_ru484_242_be, + .lmt_ru996_484 = &__txpwr_map_lmt_ru996_484_be, + .lmt_ru996_484_242 = &__txpwr_map_lmt_ru996_484_242_be, +}; + +static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] = { + [RTW89_CHIP_AX] = &dbgfs_txpwr_table_ax, + [RTW89_CHIP_BE] = &dbgfs_txpwr_table_be, +}; + +static +int rtw89_debug_priv_txpwr_table_get_regd(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + const struct rtw89_chan *chan) +{ + const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_reg_6ghz_tpe *tpe6 = ®ulatory->reg_6ghz_tpe; + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, "[Chanctx] band %u, ch %u, bw %u\n", + chan->band_type, chan->channel, chan->band_width); + + p += scnprintf(p, end - p, "[Regulatory] "); + p += __print_regd(rtwdev, p, end - p, chan); + + if (chan->band_type == RTW89_BAND_6G) { + p += scnprintf(p, end - p, "[reg6_pwr_type] %u\n", + regulatory->reg_6ghz_power); + + if (tpe6->valid) + p += scnprintf(p, end - p, "[TPE] %d dBm\n", + tpe6->constraint); + } + + return p - buf; +} + +static +ssize_t rtw89_debug_priv_txpwr_table_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_sar_parm sar_parm = {}; + const struct dbgfs_txpwr_table *tbl; + const struct rtw89_chan *chan; + char *p = buf, *end = buf + bufsz; + ssize_t n; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + sar_parm.center_freq = chan->freq; + + p += rtw89_debug_priv_txpwr_table_get_regd(rtwdev, p, end - p, chan); + + p += scnprintf(p, end - p, "[SAR]\n"); + p += rtw89_print_sar(rtwdev, p, end - p, &sar_parm); + + p += scnprintf(p, end - p, "[TAS]\n"); + p += rtw89_print_tas(rtwdev, p, end - p); + + p += scnprintf(p, end - p, "[DAG]\n"); + p += rtw89_print_ant_gain(rtwdev, p, end - p, chan); + + tbl = dbgfs_txpwr_tables[chip_gen]; + if (!tbl) + return -EOPNOTSUPP; + + p += scnprintf(p, end - p, "\n[TX power byrate]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->byr); + if (n < 0) + return n; + p += n; + + p += scnprintf(p, end - p, "\n[TX power limit]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt); + if (n < 0) + return n; + p += n; + + p += scnprintf(p, end - p, "\n[TX power limit_ru]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru); + if (n < 0) + return n; + p += n; + + switch (chip_gen) { + case RTW89_CHIP_AX: + goto out; + case RTW89_CHIP_BE: + if (!(chip->chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)) + goto out; + break; + default: + return -EOPNOTSUPP; + } + + p += scnprintf(p, end - p, "\n[TX power limit_large_mru]\n"); + + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru484_242); + if (n < 0) + return n; + p += n; + + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru996_484); + if (n < 0) + return n; + p += n; + + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru996_484_242); + if (n < 0) + return n; + p += n; + +out: + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mac_reg_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + int sel; + int ret; + + ret = kstrtoint(buf, 0, &sel); + if (ret) + return ret; + + if (sel < RTW89_DBG_SEL_MAC_00 || sel > RTW89_DBG_SEL_RFC) { + rtw89_info(rtwdev, "invalid args: %d\n", sel); + return -EINVAL; + } + + if (sel == RTW89_DBG_SEL_MAC_30 && chip->chip_id != RTL8852C) { + rtw89_info(rtwdev, "sel %d is address hole on chip %d\n", sel, + chip->chip_id); + return -EINVAL; + } + + debugfs_priv->cb_data = sel; + rtw89_info(rtwdev, "select mac page dump %d\n", debugfs_priv->cb_data); + + return count; +} + +#define RTW89_MAC_PAGE_SIZE 0x100 + +static +ssize_t rtw89_debug_priv_mac_reg_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data; + char *p = buf, *end = buf + bufsz; + u32 start, end_addr; + u32 i, j, k, page; + u32 val; + + switch (reg_sel) { + case RTW89_DBG_SEL_MAC_00: + p += scnprintf(p, end - p, "Debug selected MAC page 0x00\n"); + start = 0x000; + end_addr = 0x014; + break; + case RTW89_DBG_SEL_MAC_30: + p += scnprintf(p, end - p, "Debug selected MAC page 0x30\n"); + start = 0x030; + end_addr = 0x033; + break; + case RTW89_DBG_SEL_MAC_40: + p += scnprintf(p, end - p, "Debug selected MAC page 0x40\n"); + start = 0x040; + end_addr = 0x07f; + break; + case RTW89_DBG_SEL_MAC_80: + p += scnprintf(p, end - p, "Debug selected MAC page 0x80\n"); + start = 0x080; + end_addr = 0x09f; + break; + case RTW89_DBG_SEL_MAC_C0: + p += scnprintf(p, end - p, "Debug selected MAC page 0xc0\n"); + start = 0x0c0; + end_addr = 0x0df; + break; + case RTW89_DBG_SEL_MAC_E0: + p += scnprintf(p, end - p, "Debug selected MAC page 0xe0\n"); + start = 0x0e0; + end_addr = 0x0ff; + break; + case RTW89_DBG_SEL_BB: + p += scnprintf(p, end - p, "Debug selected BB register\n"); + start = 0x100; + end_addr = 0x17f; + break; + case RTW89_DBG_SEL_IQK: + p += scnprintf(p, end - p, "Debug selected IQK register\n"); + start = 0x180; + end_addr = 0x1bf; + break; + case RTW89_DBG_SEL_RFC: + p += scnprintf(p, end - p, "Debug selected RFC register\n"); + start = 0x1c0; + end_addr = 0x1ff; + break; + default: + p += scnprintf(p, end - p, "Selected invalid register page\n"); + return -EINVAL; + } + + for (i = start; i <= end_addr; i++) { + page = i << 8; + for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) { + p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + j); + for (k = 0; k < 4; k++) { + val = rtw89_read32(rtwdev, j + (k << 2)); + p += scnprintf(p, end - p, "%08x ", val); + } + p += scnprintf(p, end - p, "\n"); + } + } + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mac_mem_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 sel, start_addr, len; + int num; + + num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len); + if (num != 3) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + debugfs_priv->mac_mem.sel = sel; + debugfs_priv->mac_mem.start = start_addr; + debugfs_priv->mac_mem.len = len; + + rtw89_info(rtwdev, "select mem %d start %d len %d\n", + sel, start_addr, len); + + return count; +} + +static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + u8 sel, u32 start_addr, u32 len) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 filter_model_addr = mac->filter_model_addr; + u32 indir_access_addr = mac->indir_access_addr; + u32 mem_page_size = mac->mem_page_size; + u32 base_addr, start_page, residue; + char *p = buf, *end = buf + bufsz; + u32 i, j, pp, pages; + u32 dump_len, remain; + u32 val; + + remain = len; + pages = len / mem_page_size + 1; + start_page = start_addr / mem_page_size; + residue = start_addr % mem_page_size; + base_addr = rtw89_mac_mem_base_addrs(rtwdev, sel); + base_addr += start_page * mem_page_size; + + for (pp = 0; pp < pages; pp++) { + dump_len = min_t(u32, remain, mem_page_size); + rtw89_write32(rtwdev, filter_model_addr, base_addr); + for (i = indir_access_addr + residue; + i < indir_access_addr + dump_len;) { + p += scnprintf(p, end - p, "%08xh:", i); + for (j = 0; + j < 4 && i < indir_access_addr + dump_len; + j++, i += 4) { + val = rtw89_read32(rtwdev, i); + p += scnprintf(p, end - p, " %08x", val); + remain -= 4; + } + p += scnprintf(p, end - p, "\n"); + } + base_addr += mem_page_size; + } + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mac_mem_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + bool grant_read = false; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM) + return -ENOENT; + + if (rtwdev->chip->chip_id == RTL8852C) { + switch (debugfs_priv->mac_mem.sel) { + case RTW89_MAC_MEM_TXD_FIFO_0_V1: + case RTW89_MAC_MEM_TXD_FIFO_1_V1: + case RTW89_MAC_MEM_TXDATA_FIFO_0: + case RTW89_MAC_MEM_TXDATA_FIFO_1: + grant_read = true; + break; + default: + break; + } + } + + rtw89_leave_ps_mode(rtwdev); + if (grant_read) + rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); + p += rtw89_debug_dump_mac_mem(rtwdev, p, end - p, + debugfs_priv->mac_mem.sel, + debugfs_priv->mac_mem.start, + debugfs_priv->mac_mem.len); + if (grant_read) + rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mac_dbg_port_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + int sel, set; + int num; + bool enable; + + num = sscanf(buf, "%d %d", &sel, &set); + if (num != 2) { + rtw89_info(rtwdev, "invalid format: \n"); + return -EINVAL; + } + + enable = set != 0; + switch (sel) { + case 0: + debugfs_priv->dbgpkg_en.ss_dbg = enable; + break; + case 1: + debugfs_priv->dbgpkg_en.dle_dbg = enable; + break; + case 2: + debugfs_priv->dbgpkg_en.dmac_dbg = enable; + break; + case 3: + debugfs_priv->dbgpkg_en.cmac_dbg = enable; + break; + case 4: + debugfs_priv->dbgpkg_en.dbg_port = enable; + break; + default: + rtw89_info(rtwdev, "invalid args: sel %d set %d\n", sel, set); + return -EINVAL; + } + + rtw89_info(rtwdev, "%s debug port dump %d\n", + enable ? "Enable" : "Disable", sel); + + return count; +} + +static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ + return 0; +} + +static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ +#define DLE_DFI_DUMP(__type, __target, __sel) \ +({ \ + u32 __ctrl; \ + u32 __reg_ctrl = R_AX_##__type##_DBG_FUN_INTF_CTL; \ + u32 __reg_data = R_AX_##__type##_DBG_FUN_INTF_DATA; \ + u32 __data, __val32; \ + int __ret; \ + \ + __ctrl = FIELD_PREP(B_AX_##__type##_DFI_TRGSEL_MASK, \ + DLE_DFI_TYPE_##__target) | \ + FIELD_PREP(B_AX_##__type##_DFI_ADDR_MASK, __sel) | \ + B_AX_WDE_DFI_ACTIVE; \ + rtw89_write32(rtwdev, __reg_ctrl, __ctrl); \ + __ret = read_poll_timeout(rtw89_read32, __val32, \ + !(__val32 & B_AX_##__type##_DFI_ACTIVE), \ + 1000, 50000, false, \ + rtwdev, __reg_ctrl); \ + if (__ret) { \ + rtw89_err(rtwdev, "failed to dump DLE %s %s %d\n", \ + #__type, #__target, __sel); \ + return __ret; \ + } \ + \ + __data = rtw89_read32(rtwdev, __reg_data); \ + __data; \ +}) + +#define DLE_DFI_FREE_PAGE_DUMP(__p, __end, __type) \ +({ \ + u32 __freepg, __pubpg; \ + u32 __freepg_head, __freepg_tail, __pubpg_num; \ + \ + __freepg = DLE_DFI_DUMP(__type, FREEPG, 0); \ + __pubpg = DLE_DFI_DUMP(__type, FREEPG, 1); \ + __freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \ + __freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \ + __pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \ + __p += scnprintf(__p, __end - __p, "[%s] freepg head: %d\n", \ + #__type, __freepg_head); \ + __p += scnprintf(__p, __end - __p, "[%s] freepg tail: %d\n", \ + #__type, __freepg_tail); \ + __p += scnprintf(__p, __end - __p, "[%s] pubpg num : %d\n", \ + #__type, __pubpg_num); \ +}) + +#define case_QUOTA(__p, __end, __type, __id) \ + case __type##_QTAID_##__id: \ + val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \ + rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \ + use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \ + __p += scnprintf(__p, __end - __p, "[%s][%s] rsv_pgnum: %d\n", \ + #__type, #__id, rsv_pgnum); \ + __p += scnprintf(__p, __end - __p, "[%s][%s] use_pgnum: %d\n", \ + #__type, #__id, use_pgnum); \ + break + char *p = buf, *end = buf + bufsz; + u32 quota_id; + u32 val32; + u16 rsv_pgnum, use_pgnum; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); + if (ret) { + p += scnprintf(p, end - p, "[DLE] : DMAC not enabled\n"); + goto out; + } + + DLE_DFI_FREE_PAGE_DUMP(p, end, WDE); + DLE_DFI_FREE_PAGE_DUMP(p, end, PLE); + for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) { + switch (quota_id) { + case_QUOTA(p, end, WDE, HOST_IF); + case_QUOTA(p, end, WDE, WLAN_CPU); + case_QUOTA(p, end, WDE, DATA_CPU); + case_QUOTA(p, end, WDE, PKTIN); + case_QUOTA(p, end, WDE, CPUIO); + } + } + for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) { + switch (quota_id) { + case_QUOTA(p, end, PLE, B0_TXPL); + case_QUOTA(p, end, PLE, B1_TXPL); + case_QUOTA(p, end, PLE, C2H); + case_QUOTA(p, end, PLE, H2C); + case_QUOTA(p, end, PLE, WLAN_CPU); + case_QUOTA(p, end, PLE, MPDU); + case_QUOTA(p, end, PLE, CMAC0_RX); + case_QUOTA(p, end, PLE, CMAC1_RX); + case_QUOTA(p, end, PLE, CMAC1_BBRPT); + case_QUOTA(p, end, PLE, WDRLS); + case_QUOTA(p, end, PLE, CPUIO); + } + } + +out: + return p - buf; + +#undef case_QUOTA +#undef DLE_DFI_DUMP +#undef DLE_DFI_FREE_PAGE_DUMP +} + +static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; + u32 dmac_err; + int i, ret; + + ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); + if (ret) { + p += scnprintf(p, end - p, "[DMAC] : DMAC not enabled\n"); + goto out; + } + + dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); + p += scnprintf(p, end - p, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); + p += scnprintf(p, end - p, "R_AX_DMAC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); + + if (dmac_err) { + p += scnprintf(p, end - p, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); + p += scnprintf(p, end - p, + "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); + p += scnprintf(p, end - p, + "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); + p += scnprintf(p, end - p, + "R_AX_PLE_DBGERR_STS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); + } + } + + if (dmac_err & B_AX_WDRLS_ERR_FLAG) { + p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); + if (chip->chip_id == RTL8852C) + p += scnprintf(p, end - p, + "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); + else + p += scnprintf(p, end - p, + "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); + } + + if (dmac_err & B_AX_WSEC_ERR_FLAG) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); + p += scnprintf(p, end - p, + "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + p += scnprintf(p, end - p, + "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + p += scnprintf(p, end - p, "R_AX_SEC_DEBUG1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); + p += scnprintf(p, end - p, + "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + + rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, + B_AX_DBG_SEL0, 0x8B); + rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, + B_AX_DBG_SEL1, 0x8B); + rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, + B_AX_SEL_0XC0_MASK, 1); + for (i = 0; i < 0x10; i++) { + rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL, + B_AX_SEC_DBG_PORT_FIELD_MASK, i); + p += scnprintf(p, end - p, + "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", + i, + rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); + } + } else { + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + p += scnprintf(p, end - p, + "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_WDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); + p += scnprintf(p, end - p, + "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); + p += scnprintf(p, end - p, + "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); + } + } + + if (dmac_err & B_AX_MPDU_ERR_FLAG) { + p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); + } + + if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { + p += scnprintf(p, end - p, + "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); + } + + if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { + p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + } + + if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); + } else { + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); + } + } + + if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { + p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, "R_AX_RX_CTRL0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL0)); + p += scnprintf(p, end - p, "R_AX_RX_CTRL1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL1)); + p += scnprintf(p, end - p, "R_AX_RX_CTRL2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL2)); + } else { + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); + } + } + + if (dmac_err & B_AX_PKTIN_ERR_FLAG) { + p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); + } + + if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { + p += scnprintf(p, end - p, + "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); + } + + if (dmac_err & B_AX_BBRPT_ERR_FLAG) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + } else { + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + } + } + + if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); + p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); + } + +out: + return p - buf; +} + +static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + enum rtw89_mac_idx band) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; + u32 offset = 0; + u32 cmac_err; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); + if (ret) { + if (band) + p += scnprintf(p, end - p, + "[CMAC] : CMAC1 not enabled\n"); + else + p += scnprintf(p, end - p, + "[CMAC] : CMAC0 not enabled\n"); + goto out; + } + + if (band) + offset = RTW89_MAC_AX_BAND_REG_OFFSET; + + cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); + p += scnprintf(p, end - p, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); + p += scnprintf(p, end - p, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); + p += scnprintf(p, end - p, "R_AX_CK_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CK_EN + offset)); + + if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { + p += scnprintf(p, end - p, + "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); + p += scnprintf(p, end - p, + "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); + } + + if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { + p += scnprintf(p, end - p, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); + p += scnprintf(p, end - p, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); + } + + if (cmac_err & B_AX_DMA_TOP_ERR_IND) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); + p += scnprintf(p, end - p, + "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); + } else { + p += scnprintf(p, end - p, + "R_AX_DLE_CTRL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); + } + } + + if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + } else { + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + } + } + + if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { + p += scnprintf(p, end - p, "R_AX_TXPWR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); + p += scnprintf(p, end - p, "R_AX_TXPWR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); + } + + if (cmac_err & B_AX_WMAC_TX_ERR_IND) { + if (chip->chip_id == RTL8852C) { + p += scnprintf(p, end - p, + "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TRXPTCL_ERROR_INDICA + offset)); + p += scnprintf(p, end - p, + "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); + } else { + p += scnprintf(p, end - p, + "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TMAC_ERR_IMR_ISR + offset)); + } + p += scnprintf(p, end - p, + "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); + } + + p += scnprintf(p, end - p, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); + +out: + return p - buf; +} + +static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + + p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_0); + if (rtwdev->dbcc_en) + p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_1); + + return p - buf; +} + +static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = { + .sel_addr = R_AX_PTCL_DBG, + .sel_byte = 1, + .sel_msk = B_AX_PTCL_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x3F, + .rd_addr = R_AX_PTCL_DBG_INFO, + .rd_byte = 4, + .rd_msk = B_AX_PTCL_DBG_INFO_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = { + .sel_addr = R_AX_PTCL_DBG_C1, + .sel_byte = 1, + .sel_msk = B_AX_PTCL_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x3F, + .rd_addr = R_AX_PTCL_DBG_INFO_C1, + .rd_byte = 4, + .rd_msk = B_AX_PTCL_DBG_INFO_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx0_5 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0xD, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx6 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x5, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx7 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x9, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx8 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x3, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx9_C = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x1, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_txD = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx0 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0xB, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx1 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x4, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx3 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x8, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx4 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x7, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx5_8 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x1, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx9 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x3, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_txA_C = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx0 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x8, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx1_2 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx3 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x6, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx4 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx5 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 2, + .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_0 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x3, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_1 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x6, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_2 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x0, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p1 = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x8, + .end = 0xE, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_stf_ctrl = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x5, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_addr_ctrl = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x6, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_wde_intf = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0xF, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_ple_intf = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x9, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_dspt_flow_ctrl = { + .sel_addr = R_AX_DISPATCHER_DBG_PORT, + .sel_byte = 1, + .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, + .srt = 0x0, + .end = 0x3, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = { + .sel_addr = R_AX_SCH_DBG_SEL, + .sel_byte = 1, + .sel_msk = B_AX_SCH_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x2F, + .rd_addr = R_AX_SCH_DBG, + .rd_byte = 4, + .rd_msk = B_AX_SCHEDULER_DBG_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = { + .sel_addr = R_AX_SCH_DBG_SEL_C1, + .sel_byte = 1, + .sel_msk = B_AX_SCH_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x2F, + .rd_addr = R_AX_SCH_DBG_C1, + .rd_byte = 4, + .rd_msk = B_AX_SCHEDULER_DBG_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = { + .sel_addr = R_AX_MACTX_DBG_SEL_CNT, + .sel_byte = 1, + .sel_msk = B_AX_DBGSEL_MACTX_MASK, + .srt = 0x00, + .end = 0x19, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = { + .sel_addr = R_AX_MACTX_DBG_SEL_CNT_C1, + .sel_byte = 1, + .sel_msk = B_AX_DBGSEL_MACTX_MASK, + .srt = 0x00, + .end = 0x19, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c0 = { + .sel_addr = R_AX_RX_DEBUG_SELECT, + .sel_byte = 1, + .sel_msk = B_AX_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x58, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c1 = { + .sel_addr = R_AX_RX_DEBUG_SELECT_C1, + .sel_byte = 1, + .sel_msk = B_AX_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x58, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c0 = { + .sel_addr = R_AX_RX_STATE_MONITOR, + .sel_byte = 1, + .sel_msk = B_AX_STATE_SEL_MASK, + .srt = 0x00, + .end = 0x17, + .rd_addr = R_AX_RX_STATE_MONITOR, + .rd_byte = 4, + .rd_msk = B_AX_RX_STATE_MONITOR_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c1 = { + .sel_addr = R_AX_RX_STATE_MONITOR_C1, + .sel_byte = 1, + .sel_msk = B_AX_STATE_SEL_MASK, + .srt = 0x00, + .end = 0x17, + .rd_addr = R_AX_RX_STATE_MONITOR_C1, + .rd_byte = 4, + .rd_msk = B_AX_RX_STATE_MONITOR_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c0 = { + .sel_addr = R_AX_RMAC_PLCP_MON, + .sel_byte = 4, + .sel_msk = B_AX_PCLP_MON_SEL_MASK, + .srt = 0x0, + .end = 0xF, + .rd_addr = R_AX_RMAC_PLCP_MON, + .rd_byte = 4, + .rd_msk = B_AX_RMAC_PLCP_MON_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c1 = { + .sel_addr = R_AX_RMAC_PLCP_MON_C1, + .sel_byte = 4, + .sel_msk = B_AX_PCLP_MON_SEL_MASK, + .srt = 0x0, + .end = 0xF, + .rd_addr = R_AX_RMAC_PLCP_MON_C1, + .rd_byte = 4, + .rd_msk = B_AX_RMAC_PLCP_MON_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c0 = { + .sel_addr = R_AX_DBGSEL_TRXPTCL, + .sel_byte = 1, + .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, + .srt = 0x08, + .end = 0x10, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c1 = { + .sel_addr = R_AX_DBGSEL_TRXPTCL_C1, + .sel_byte = 1, + .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, + .srt = 0x08, + .end = 0x10, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c0 = { + .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, + .sel_byte = 1, + .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x07, + .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG, + .rd_byte = 4, + .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c0 = { + .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, + .sel_byte = 1, + .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x07, + .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG, + .rd_byte = 4, + .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c1 = { + .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, + .sel_byte = 1, + .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x07, + .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG_C1, + .rd_byte = 4, + .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c1 = { + .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, + .sel_byte = 1, + .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, + .srt = 0x00, + .end = 0x07, + .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG_C1, + .rd_byte = 4, + .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c0 = { + .sel_addr = R_AX_WMAC_TX_TF_INFO_0, + .sel_byte = 1, + .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_WMAC_TX_TF_INFO_1, + .rd_byte = 4, + .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c0 = { + .sel_addr = R_AX_WMAC_TX_TF_INFO_0, + .sel_byte = 1, + .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_WMAC_TX_TF_INFO_2, + .rd_byte = 4, + .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c1 = { + .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, + .sel_byte = 1, + .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_WMAC_TX_TF_INFO_1_C1, + .rd_byte = 4, + .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c1 = { + .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, + .sel_byte = 1, + .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_WMAC_TX_TF_INFO_2_C1, + .rd_byte = 4, + .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_freepg = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80000000, + .end = 0x80000001, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_quota = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80010000, + .end = 0x80010004, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pagellt = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80020000, + .end = 0x80020FFF, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pktinfo = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80030000, + .end = 0x80030FFF, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_prepkt = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80040000, + .end = 0x80040FFF, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_nxtpkt = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80050000, + .end = 0x80050FFF, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qlnktbl = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80060000, + .end = 0x80060453, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qempty = { + .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_WDE_DFI_DATA_MASK, + .srt = 0x80070000, + .end = 0x80070011, + .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_WDE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_freepg = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80000000, + .end = 0x80000001, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_quota = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80010000, + .end = 0x8001000A, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pagellt = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80020000, + .end = 0x80020DBF, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pktinfo = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80030000, + .end = 0x80030DBF, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_prepkt = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80040000, + .end = 0x80040DBF, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_nxtpkt = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80050000, + .end = 0x80050DBF, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qlnktbl = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80060000, + .end = 0x80060041, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qempty = { + .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_PLE_DFI_DATA_MASK, + .srt = 0x80070000, + .end = 0x80070001, + .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_PLE_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = { + .sel_addr = R_AX_DBG_FUN_INTF_CTL, + .sel_byte = 4, + .sel_msk = B_AX_DFI_DATA_MASK, + .srt = 0x80000000, + .end = 0x8000017f, + .rd_addr = R_AX_DBG_FUN_INTF_DATA, + .rd_byte = 4, + .rd_msk = B_AX_DFI_DATA_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x03, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x01, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x05, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x05, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = { + .sel_addr = R_AX_PCIE_DBG_CTRL, + .sel_byte = 2, + .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x06, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = { + .sel_addr = R_AX_DBG_CTRL, + .sel_byte = 1, + .sel_msk = B_AX_DBG_SEL0, + .srt = 0x34, + .end = 0x3C, + .rd_addr = R_AX_DBG_PORT_SEL, + .rd_byte = 4, + .rd_msk = B_AX_DEBUG_ST_MASK +}; + +static int +rtw89_debug_mac_dbg_port_sel(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + u32 sel, const struct rtw89_mac_dbg_port_info **ppinfo) +{ + const struct rtw89_mac_dbg_port_info *info = NULL; + char *p = buf, *end = buf + bufsz; + u32 index; + u32 val32; + u16 val16; + u8 val8; + + switch (sel) { + case RTW89_DBG_PORT_SEL_PTCL_C0: + info = &dbg_port_ptcl_c0; + val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG); + val16 |= B_AX_PTCL_DBG_EN; + rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16); + p += scnprintf(p, end - p, "Enable PTCL C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_PTCL_C1: + info = &dbg_port_ptcl_c1; + val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1); + val16 |= B_AX_PTCL_DBG_EN; + rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16); + p += scnprintf(p, end - p, "Enable PTCL C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_SCH_C0: + info = &dbg_port_sch_c0; + val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL); + val32 |= B_AX_SCH_DBG_EN; + rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32); + p += scnprintf(p, end - p, "Enable SCH C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_SCH_C1: + info = &dbg_port_sch_c1; + val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1); + val32 |= B_AX_SCH_DBG_EN; + rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32); + p += scnprintf(p, end - p, "Enable SCH C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_TMAC_C0: + info = &dbg_port_tmac_c0; + val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); + val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + p += scnprintf(p, end - p, "Enable TMAC C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_TMAC_C1: + info = &dbg_port_tmac_c1; + val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); + val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); + + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + p += scnprintf(p, end - p, "Enable TMAC C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMAC_C0: + info = &dbg_port_rmac_c0; + val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); + val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + + val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL); + val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8); + p += scnprintf(p, end - p, "Enable RMAC C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMAC_C1: + info = &dbg_port_rmac_c1; + val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); + val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); + + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + + val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); + val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, + B_AX_DBGSEL_TRXPTCL_MASK); + rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8); + p += scnprintf(p, end - p, "Enable RMAC C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMACST_C0: + info = &dbg_port_rmacst_c0; + p += scnprintf(p, end - p, "Enable RMAC state C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMACST_C1: + info = &dbg_port_rmacst_c1; + p += scnprintf(p, end - p, "Enable RMAC state C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0: + info = &dbg_port_rmac_plcp_c0; + p += scnprintf(p, end - p, "Enable RMAC PLCP C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1: + info = &dbg_port_rmac_plcp_c1; + p += scnprintf(p, end - p, "Enable RMAC PLCP C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_TRXPTCL_C0: + info = &dbg_port_trxptcl_c0; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + p += scnprintf(p, end - p, "Enable TRXPTCL C0 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_TRXPTCL_C1: + info = &dbg_port_trxptcl_c1; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + + val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); + val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); + rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); + p += scnprintf(p, end - p, "Enable TRXPTCL C1 dbgport.\n"); + break; + case RTW89_DBG_PORT_SEL_TX_INFOL_C0: + info = &dbg_port_tx_infol_c0; + val32 = rtw89_read32(rtwdev, R_AX_TCR1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1, val32); + p += scnprintf(p, end - p, "Enable tx infol dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TX_INFOH_C0: + info = &dbg_port_tx_infoh_c0; + val32 = rtw89_read32(rtwdev, R_AX_TCR1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1, val32); + p += scnprintf(p, end - p, "Enable tx infoh dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TX_INFOL_C1: + info = &dbg_port_tx_infol_c1; + val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); + p += scnprintf(p, end - p, "Enable tx infol dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TX_INFOH_C1: + info = &dbg_port_tx_infoh_c1; + val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); + p += scnprintf(p, end - p, "Enable tx infoh dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0: + info = &dbg_port_txtf_infol_c0; + val32 = rtw89_read32(rtwdev, R_AX_TCR1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1, val32); + p += scnprintf(p, end - p, "Enable tx tf infol dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0: + info = &dbg_port_txtf_infoh_c0; + val32 = rtw89_read32(rtwdev, R_AX_TCR1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1, val32); + p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1: + info = &dbg_port_txtf_infol_c1; + val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); + p += scnprintf(p, end - p, "Enable tx tf infol dump.\n"); + break; + case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1: + info = &dbg_port_txtf_infoh_c1; + val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); + val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; + rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); + p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG: + info = &dbg_port_wde_bufmgn_freepg; + p += scnprintf(p, end - p, "Enable wde bufmgn freepg dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA: + info = &dbg_port_wde_bufmgn_quota; + p += scnprintf(p, end - p, "Enable wde bufmgn quota dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT: + info = &dbg_port_wde_bufmgn_pagellt; + p += scnprintf(p, end - p, + "Enable wde bufmgn pagellt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO: + info = &dbg_port_wde_bufmgn_pktinfo; + p += scnprintf(p, end - p, + "Enable wde bufmgn pktinfo dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT: + info = &dbg_port_wde_quemgn_prepkt; + p += scnprintf(p, end - p, "Enable wde quemgn prepkt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT: + info = &dbg_port_wde_quemgn_nxtpkt; + p += scnprintf(p, end - p, "Enable wde quemgn nxtpkt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL: + info = &dbg_port_wde_quemgn_qlnktbl; + p += scnprintf(p, end - p, + "Enable wde quemgn qlnktbl dump.\n"); + break; + case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY: + info = &dbg_port_wde_quemgn_qempty; + p += scnprintf(p, end - p, "Enable wde quemgn qempty dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG: + info = &dbg_port_ple_bufmgn_freepg; + p += scnprintf(p, end - p, "Enable ple bufmgn freepg dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA: + info = &dbg_port_ple_bufmgn_quota; + p += scnprintf(p, end - p, "Enable ple bufmgn quota dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT: + info = &dbg_port_ple_bufmgn_pagellt; + p += scnprintf(p, end - p, + "Enable ple bufmgn pagellt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO: + info = &dbg_port_ple_bufmgn_pktinfo; + p += scnprintf(p, end - p, + "Enable ple bufmgn pktinfo dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT: + info = &dbg_port_ple_quemgn_prepkt; + p += scnprintf(p, end - p, "Enable ple quemgn prepkt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT: + info = &dbg_port_ple_quemgn_nxtpkt; + p += scnprintf(p, end - p, "Enable ple quemgn nxtpkt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL: + info = &dbg_port_ple_quemgn_qlnktbl; + p += scnprintf(p, end - p, + "Enable ple quemgn qlnktbl dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY: + info = &dbg_port_ple_quemgn_qempty; + p += scnprintf(p, end - p, "Enable ple quemgn qempty dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PKTINFO: + info = &dbg_port_pktinfo; + p += scnprintf(p, end - p, "Enable pktinfo dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0: + rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, + B_AX_DBG_SEL0, 0x80); + rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, + B_AX_SEL_0XC0_MASK, 1); + fallthrough; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX1: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX2: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX3: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX4: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX5: + info = &dbg_port_dspt_hdt_tx0_5; + index = sel - RTW89_DBG_PORT_SEL_DSPT_HDT_TX0; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx%x dump.\n", index); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6: + info = &dbg_port_dspt_hdt_tx6; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 6); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx6 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7: + info = &dbg_port_dspt_hdt_tx7; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 7); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx7 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8: + info = &dbg_port_dspt_hdt_tx8; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 8); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx8 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TXB: + case RTW89_DBG_PORT_SEL_DSPT_HDT_TXC: + info = &dbg_port_dspt_hdt_tx9_C; + index = sel + 9 - RTW89_DBG_PORT_SEL_DSPT_HDT_TX9; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx%x dump.\n", index); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD: + info = &dbg_port_dspt_hdt_txD; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 0); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 0xD); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt txD dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0: + info = &dbg_port_dspt_cdt_tx0; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 0); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx0 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1: + info = &dbg_port_dspt_cdt_tx1; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 1); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx1 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3: + info = &dbg_port_dspt_cdt_tx3; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 3); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx3 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4: + info = &dbg_port_dspt_cdt_tx4; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 4); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx4 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5: + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6: + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX7: + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX8: + info = &dbg_port_dspt_cdt_tx5_8; + index = sel + 5 - RTW89_DBG_PORT_SEL_DSPT_CDT_TX5; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, index); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx%x dump.\n", index); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9: + info = &dbg_port_dspt_cdt_tx9; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 9); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx9 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA: + case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB: + case RTW89_DBG_PORT_SEL_DSPT_CDT_TXC: + info = &dbg_port_dspt_cdt_txA_C; + index = sel + 0xA - RTW89_DBG_PORT_SEL_DSPT_CDT_TXA; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 1); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, index); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx%x dump.\n", index); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0: + info = &dbg_port_dspt_hdt_rx0; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 2); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 0); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx0 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1: + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2: + info = &dbg_port_dspt_hdt_rx1_2; + index = sel + 1 - RTW89_DBG_PORT_SEL_DSPT_HDT_RX1; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 2); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx%x dump.\n", index); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3: + info = &dbg_port_dspt_hdt_rx3; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 2); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 3); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx3 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4: + info = &dbg_port_dspt_hdt_rx4; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 2); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 4); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx4 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5: + info = &dbg_port_dspt_hdt_rx5; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 2); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 5); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx5 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0: + info = &dbg_port_dspt_cdt_rx_p0_0; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 3); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 0); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 0 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0: + case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1: + info = &dbg_port_dspt_cdt_rx_p0_1; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 3); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 1); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 1 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2: + info = &dbg_port_dspt_cdt_rx_p0_2; + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 3); + rtw89_write16_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_CH_SEL_MASK, 2); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 2 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1: + info = &dbg_port_dspt_cdt_rx_p1; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 3); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part1 dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL: + info = &dbg_port_dspt_stf_ctrl; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 4); + p += scnprintf(p, end - p, + "Enable Dispatcher stf control dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL: + info = &dbg_port_dspt_addr_ctrl; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 5); + p += scnprintf(p, end - p, + "Enable Dispatcher addr control dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF: + info = &dbg_port_dspt_wde_intf; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 6); + p += scnprintf(p, end - p, + "Enable Dispatcher wde interface dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF: + info = &dbg_port_dspt_ple_intf; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 7); + p += scnprintf(p, end - p, + "Enable Dispatcher ple interface dump.\n"); + break; + case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL: + info = &dbg_port_dspt_flow_ctrl; + rtw89_write8_mask(rtwdev, info->sel_addr, + B_AX_DISPATCHER_INTN_SEL_MASK, 8); + p += scnprintf(p, end - p, + "Enable Dispatcher flow control dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_TXDMA: + info = &dbg_port_pcie_txdma; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie txdma dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_RXDMA: + info = &dbg_port_pcie_rxdma; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie rxdma dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_CVT: + info = &dbg_port_pcie_cvt; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie cvt dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_CXPL: + info = &dbg_port_pcie_cxpl; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie cxpl dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_IO: + info = &dbg_port_pcie_io; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie io dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_MISC: + info = &dbg_port_pcie_misc; + val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); + val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0); + val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1); + rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); + p += scnprintf(p, end - p, "Enable pcie misc dump.\n"); + break; + case RTW89_DBG_PORT_SEL_PCIE_MISC2: + info = &dbg_port_pcie_misc2; + val16 = rtw89_read16(rtwdev, R_AX_PCIE_DBG_CTRL); + val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL, + B_AX_PCIE_DBG_SEL_MASK); + rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); + p += scnprintf(p, end - p, "Enable pcie misc2 dump.\n"); + break; + default: + p += scnprintf(p, end - p, "Dbg port select err\n"); + break; + } + + *ppinfo = info; + + return p - buf; +} + +static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) +{ + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE && + sel >= RTW89_DBG_PORT_SEL_PCIE_TXDMA && + sel <= RTW89_DBG_PORT_SEL_PCIE_MISC2) + return false; + if (rtw89_is_rtl885xb(rtwdev) && + sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && + sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) + return false; + if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) && + sel >= RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG && + sel <= RTW89_DBG_PORT_SEL_PKTINFO) + return false; + if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) && + sel >= RTW89_DBG_PORT_SEL_DSPT_HDT_TX0 && + sel <= RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL) + return false; + if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL) && + sel >= RTW89_DBG_PORT_SEL_PTCL_C0 && + sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C0) + return false; + if (rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL) && + sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && + sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) + return false; + + return true; +} + +static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, u32 sel) +{ + const struct rtw89_mac_dbg_port_info *info = NULL; + char *p = buf, *end = buf + bufsz; + u32 val32; + u16 val16; + u8 val8; + u32 i; + + p += rtw89_debug_mac_dbg_port_sel(rtwdev, p, end - p, sel, &info); + + if (!info) { + rtw89_err(rtwdev, "failed to select debug port %d\n", sel); + goto out; + } + +#define case_DBG_SEL(__sel) \ + case RTW89_DBG_PORT_SEL_##__sel: \ + p += scnprintf(p, end - p, "Dump debug port " #__sel ":\n"); \ + break + + switch (sel) { + case_DBG_SEL(PTCL_C0); + case_DBG_SEL(PTCL_C1); + case_DBG_SEL(SCH_C0); + case_DBG_SEL(SCH_C1); + case_DBG_SEL(TMAC_C0); + case_DBG_SEL(TMAC_C1); + case_DBG_SEL(RMAC_C0); + case_DBG_SEL(RMAC_C1); + case_DBG_SEL(RMACST_C0); + case_DBG_SEL(RMACST_C1); + case_DBG_SEL(TRXPTCL_C0); + case_DBG_SEL(TRXPTCL_C1); + case_DBG_SEL(TX_INFOL_C0); + case_DBG_SEL(TX_INFOH_C0); + case_DBG_SEL(TX_INFOL_C1); + case_DBG_SEL(TX_INFOH_C1); + case_DBG_SEL(TXTF_INFOL_C0); + case_DBG_SEL(TXTF_INFOH_C0); + case_DBG_SEL(TXTF_INFOL_C1); + case_DBG_SEL(TXTF_INFOH_C1); + case_DBG_SEL(WDE_BUFMGN_FREEPG); + case_DBG_SEL(WDE_BUFMGN_QUOTA); + case_DBG_SEL(WDE_BUFMGN_PAGELLT); + case_DBG_SEL(WDE_BUFMGN_PKTINFO); + case_DBG_SEL(WDE_QUEMGN_PREPKT); + case_DBG_SEL(WDE_QUEMGN_NXTPKT); + case_DBG_SEL(WDE_QUEMGN_QLNKTBL); + case_DBG_SEL(WDE_QUEMGN_QEMPTY); + case_DBG_SEL(PLE_BUFMGN_FREEPG); + case_DBG_SEL(PLE_BUFMGN_QUOTA); + case_DBG_SEL(PLE_BUFMGN_PAGELLT); + case_DBG_SEL(PLE_BUFMGN_PKTINFO); + case_DBG_SEL(PLE_QUEMGN_PREPKT); + case_DBG_SEL(PLE_QUEMGN_NXTPKT); + case_DBG_SEL(PLE_QUEMGN_QLNKTBL); + case_DBG_SEL(PLE_QUEMGN_QEMPTY); + case_DBG_SEL(PKTINFO); + case_DBG_SEL(DSPT_HDT_TX0); + case_DBG_SEL(DSPT_HDT_TX1); + case_DBG_SEL(DSPT_HDT_TX2); + case_DBG_SEL(DSPT_HDT_TX3); + case_DBG_SEL(DSPT_HDT_TX4); + case_DBG_SEL(DSPT_HDT_TX5); + case_DBG_SEL(DSPT_HDT_TX6); + case_DBG_SEL(DSPT_HDT_TX7); + case_DBG_SEL(DSPT_HDT_TX8); + case_DBG_SEL(DSPT_HDT_TX9); + case_DBG_SEL(DSPT_HDT_TXA); + case_DBG_SEL(DSPT_HDT_TXB); + case_DBG_SEL(DSPT_HDT_TXC); + case_DBG_SEL(DSPT_HDT_TXD); + case_DBG_SEL(DSPT_HDT_TXE); + case_DBG_SEL(DSPT_HDT_TXF); + case_DBG_SEL(DSPT_CDT_TX0); + case_DBG_SEL(DSPT_CDT_TX1); + case_DBG_SEL(DSPT_CDT_TX3); + case_DBG_SEL(DSPT_CDT_TX4); + case_DBG_SEL(DSPT_CDT_TX5); + case_DBG_SEL(DSPT_CDT_TX6); + case_DBG_SEL(DSPT_CDT_TX7); + case_DBG_SEL(DSPT_CDT_TX8); + case_DBG_SEL(DSPT_CDT_TX9); + case_DBG_SEL(DSPT_CDT_TXA); + case_DBG_SEL(DSPT_CDT_TXB); + case_DBG_SEL(DSPT_CDT_TXC); + case_DBG_SEL(DSPT_HDT_RX0); + case_DBG_SEL(DSPT_HDT_RX1); + case_DBG_SEL(DSPT_HDT_RX2); + case_DBG_SEL(DSPT_HDT_RX3); + case_DBG_SEL(DSPT_HDT_RX4); + case_DBG_SEL(DSPT_HDT_RX5); + case_DBG_SEL(DSPT_CDT_RX_P0); + case_DBG_SEL(DSPT_CDT_RX_P0_0); + case_DBG_SEL(DSPT_CDT_RX_P0_1); + case_DBG_SEL(DSPT_CDT_RX_P0_2); + case_DBG_SEL(DSPT_CDT_RX_P1); + case_DBG_SEL(DSPT_STF_CTRL); + case_DBG_SEL(DSPT_ADDR_CTRL); + case_DBG_SEL(DSPT_WDE_INTF); + case_DBG_SEL(DSPT_PLE_INTF); + case_DBG_SEL(DSPT_FLOW_CTRL); + case_DBG_SEL(PCIE_TXDMA); + case_DBG_SEL(PCIE_RXDMA); + case_DBG_SEL(PCIE_CVT); + case_DBG_SEL(PCIE_CXPL); + case_DBG_SEL(PCIE_IO); + case_DBG_SEL(PCIE_MISC); + case_DBG_SEL(PCIE_MISC2); + } + +#undef case_DBG_SEL + + p += scnprintf(p, end - p, "Sel addr = 0x%X\n", info->sel_addr); + p += scnprintf(p, end - p, "Read addr = 0x%X\n", info->rd_addr); + + for (i = info->srt; i <= info->end; i++) { + switch (info->sel_byte) { + case 1: + default: + rtw89_write8_mask(rtwdev, info->sel_addr, + info->sel_msk, i); + p += scnprintf(p, end - p, "0x%02X: ", i); + break; + case 2: + rtw89_write16_mask(rtwdev, info->sel_addr, + info->sel_msk, i); + p += scnprintf(p, end - p, "0x%04X: ", i); + break; + case 4: + rtw89_write32_mask(rtwdev, info->sel_addr, + info->sel_msk, i); + p += scnprintf(p, end - p, "0x%04X: ", i); + break; + } + + udelay(10); + + switch (info->rd_byte) { + case 1: + default: + val8 = rtw89_read8_mask(rtwdev, + info->rd_addr, info->rd_msk); + p += scnprintf(p, end - p, "0x%02X\n", val8); + break; + case 2: + val16 = rtw89_read16_mask(rtwdev, + info->rd_addr, info->rd_msk); + p += scnprintf(p, end - p, "0x%04X\n", val16); + break; + case 4: + val32 = rtw89_read32_mask(rtwdev, + info->rd_addr, info->rd_msk); + p += scnprintf(p, end - p, "0x%08X\n", val32); + break; + } + } + +out: + return p - buf; +} + +static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + ssize_t n; + u32 sel; + + for (sel = RTW89_DBG_PORT_SEL_PTCL_C0; + sel < RTW89_DBG_PORT_SEL_LAST; sel++) { + if (!is_dbg_port_valid(rtwdev, sel)) + continue; + n = rtw89_debug_mac_dbg_port_dump(rtwdev, p, end - p, sel); + if (n < 0) { + rtw89_err(rtwdev, + "failed to dump debug port %d\n", sel); + break; + } + p += n; + } + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mac_dbg_port_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + + if (debugfs_priv->dbgpkg_en.ss_dbg) + p += rtw89_debug_mac_dump_ss_dbg(rtwdev, p, end - p); + if (debugfs_priv->dbgpkg_en.dle_dbg) + p += rtw89_debug_mac_dump_dle_dbg(rtwdev, p, end - p); + if (debugfs_priv->dbgpkg_en.dmac_dbg) + p += rtw89_debug_mac_dump_dmac_dbg(rtwdev, p, end - p); + if (debugfs_priv->dbgpkg_en.cmac_dbg) + p += rtw89_debug_mac_dump_cmac_dbg(rtwdev, p, end - p); + if (debugfs_priv->dbgpkg_en.dbg_port) + p += rtw89_debug_mac_dump_dbg_port(rtwdev, p, end - p); + + return p - buf; +}; + +static u8 *rtw89_hex2bin(struct rtw89_dev *rtwdev, const char *buf, size_t count) +{ + u8 *bin; + int num; + int err = 0; + + num = count / 2; + bin = kmalloc(num, GFP_KERNEL); + if (!bin) { + err = -EFAULT; + goto out; + } + + if (hex2bin(bin, buf, num)) { + rtw89_info(rtwdev, "valid format: H1H2H3...\n"); + kfree(bin); + err = -EINVAL; + } + +out: + return err ? ERR_PTR(err) : bin; +} + +static ssize_t rtw89_debug_priv_send_h2c_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u8 *h2c; + int ret; + u16 h2c_len = count / 2; + + h2c = rtw89_hex2bin(rtwdev, buf, count); + if (IS_ERR(h2c)) + return -EFAULT; + + ret = rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len); + + kfree(h2c); + + return ret ? ret : count; +} + +static ssize_t +rtw89_debug_priv_early_h2c_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_early_h2c *early_h2c; + char *p = buf, *end = buf + bufsz; + int seq = 0; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) + p += scnprintf(p, end - p, "%d: %*ph\n", ++seq, + early_h2c->h2c_len, early_h2c->h2c); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_early_h2c_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + struct rtw89_early_h2c *early_h2c; + u8 *h2c; + u16 h2c_len = count / 2; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + h2c = rtw89_hex2bin(rtwdev, buf, count); + if (IS_ERR(h2c)) + return -EFAULT; + + if (h2c_len >= 2 && h2c[0] == 0x00 && h2c[1] == 0x00) { + kfree(h2c); + rtw89_fw_free_all_early_h2c(rtwdev); + goto out; + } + + early_h2c = kmalloc_obj(*early_h2c); + if (!early_h2c) { + kfree(h2c); + return -EFAULT; + } + + early_h2c->h2c = h2c; + early_h2c->h2c_len = h2c_len; + + list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list); + +out: + return count; +} + +static int rtw89_dbg_trigger_l1_error_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_cpuio_ctrl ctrl_para = {}; + u16 pkt_id; + int ret; + + ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id); + if (ret) + return ret; + + /* intentionally, enqueue two pkt, but has only one pkt id */ + ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; + ctrl_para.start_pktid = pkt_id; + ctrl_para.end_pktid = pkt_id; + ctrl_para.pkt_num = 1; /* start from 0 */ + ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS; + ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT; + + if (mac->set_cpuio(rtwdev, &ctrl_para, true)) + return -EFAULT; + + return 0; +} + +static int rtw89_dbg_trigger_l1_error_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_FW_TRIGGER_IDCT_ISR, + B_BE_DMAC_FW_TRIG_IDCT | B_BE_DMAC_FW_ERR_IDCT_IMR); + + return 0; +} + +static int rtw89_dbg_trigger_l1_error_by_halt_h2c(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_FORCE); +} + +static int rtw89_dbg_trigger_l1_error(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + int (*sim_l1)(struct rtw89_dev *rtwdev); + + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + sim_l1 = rtw89_dbg_trigger_l1_error_ax; + break; + case RTW89_CHIP_BE: + sim_l1 = rtw89_dbg_trigger_l1_error_be; + break; + default: + return -EOPNOTSUPP; + } + + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) + return rtw89_dbg_trigger_l1_error_by_halt_h2c(rtwdev); + + rtw89_leave_ps_mode(rtwdev); + + return sim_l1(rtwdev); +} + +static int rtw89_dbg_trigger_l0_error_ax(struct rtw89_dev *rtwdev) +{ + u16 val16; + u8 val8; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); + if (ret) + return ret; + + val8 = rtw89_read8(rtwdev, R_AX_CMAC_FUNC_EN); + rtw89_write8(rtwdev, R_AX_CMAC_FUNC_EN, val8 & ~B_AX_TMAC_EN); + mdelay(1); + rtw89_write8(rtwdev, R_AX_CMAC_FUNC_EN, val8); + + val16 = rtw89_read16(rtwdev, R_AX_PTCL_IMR0); + rtw89_write16(rtwdev, R_AX_PTCL_IMR0, val16 | B_AX_F2PCMD_EMPTY_ERR_INT_EN); + rtw89_write16(rtwdev, R_AX_PTCL_IMR0, val16); + + return 0; +} + +static int rtw89_dbg_trigger_l0_error_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_CMAC_FW_TRIGGER_IDCT_ISR, + B_BE_CMAC_FW_TRIG_IDCT | B_BE_CMAC_FW_ERR_IDCT_IMR); + + return 0; +} + +static int rtw89_dbg_trigger_l0_error_by_halt_h2c(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L0_RESET_FORCE); +} + +static int rtw89_dbg_trigger_l0_error(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + int (*sim_l0)(struct rtw89_dev *rtwdev); + + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + sim_l0 = rtw89_dbg_trigger_l0_error_ax; + break; + case RTW89_CHIP_BE: + sim_l0 = rtw89_dbg_trigger_l0_error_be; + break; + default: + return -EOPNOTSUPP; + } + + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) + return rtw89_dbg_trigger_l0_error_by_halt_h2c(rtwdev); + + rtw89_leave_ps_mode(rtwdev); + + return sim_l0(rtwdev); +} + +static ssize_t +rtw89_debug_priv_fw_crash_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, "%d\n", + test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags)); + return p - buf; +} + +enum rtw89_dbg_crash_simulation_type { + RTW89_DBG_SIM_CPU_EXCEPTION = 1, + RTW89_DBG_SIM_L1_ERROR = 2, + RTW89_DBG_SIM_L0_ERROR = 3, +}; + +static ssize_t +rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + int (*sim)(struct rtw89_dev *rtwdev); + bool announce = true; + u8 crash_type; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + ret = kstrtou8(buf, 0, &crash_type); + if (ret) + return -EINVAL; + + switch (crash_type) { + case RTW89_DBG_SIM_CPU_EXCEPTION: + if (!RTW89_CHK_FW_FEATURE_GROUP(CRASH_TRIGGER, &rtwdev->fw)) + return -EOPNOTSUPP; + sim = rtw89_fw_h2c_trigger_cpu_exception; + break; + case RTW89_DBG_SIM_L1_ERROR: + sim = rtw89_dbg_trigger_l1_error; + break; + case RTW89_DBG_SIM_L0_ERROR: + sim = rtw89_dbg_trigger_l0_error; + + /* Driver SER flow won't get involved; only FW will. */ + announce = false; + break; + default: + return -EINVAL; + } + + if (announce) + set_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags); + + ret = sim(rtwdev); + + if (ret) + return ret; + + return count; +} + +struct rtw89_dbg_ser_counters { + unsigned int l0_sim; + unsigned int l0; + unsigned int l1; + unsigned int l0_to_l1; +}; + +static void rtw89_dbg_get_ser_counters_ax(struct rtw89_dev *rtwdev, + struct rtw89_dbg_ser_counters *cnt) +{ + const u32 val = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO); + + cnt->l0 = u32_get_bits(val, B_AX_SER_L0_COUNTER_MASK); + cnt->l1 = u32_get_bits(val, B_AX_SER_L1_COUNTER_MASK); + cnt->l0_to_l1 = u32_get_bits(val, B_AX_L0_TO_L1_EVENT_MASK); +} + +static void rtw89_dbg_get_ser_counters_be(struct rtw89_dev *rtwdev, + struct rtw89_dbg_ser_counters *cnt) +{ + const u32 val = rtw89_read32(rtwdev, R_BE_SER_DBG_INFO); + + cnt->l0_sim = rtw89_read8(rtwdev, R_BE_SER_L0_DBG_CNT1 + 3); + cnt->l0 = u32_get_bits(val, B_BE_SER_L0_COUNTER_MASK); + cnt->l1 = u32_get_bits(val, B_BE_SER_L1_COUNTER_MASK); + cnt->l0_to_l1 = u32_get_bits(val, B_BE_SER_L0_PROMOTE_L1_EVENT_MASK); +} + +static ssize_t rtw89_debug_priv_ser_counters_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + const struct rtw89_ser_count *sw_cnt = &rtwdev->ser.sw_cnt; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_dbg_ser_counters cnt = {}; + char *p = buf, *end = buf + bufsz; + + rtw89_leave_ps_mode(rtwdev); + + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + rtw89_dbg_get_ser_counters_ax(rtwdev, &cnt); + break; + case RTW89_CHIP_BE: + rtw89_dbg_get_ser_counters_be(rtwdev, &cnt); + break; + default: + return -EOPNOTSUPP; + } + + p += scnprintf(p, end - p, "SER L1 SW Count: %u\n", sw_cnt->l1); + p += scnprintf(p, end - p, "SER L2 SW Count: %u\n", sw_cnt->l2); + + /* Some chipsets don't have dedicated cnt for SER simulation. */ + p += scnprintf(p, end - p, "---\n"); + p += scnprintf(p, end - p, "SER L0 Simulation Count: %d\n", cnt.l0_sim); + + /* Some chipsets won't record SER simulation in HW cnt. */ + p += scnprintf(p, end - p, "---\n"); + p += scnprintf(p, end - p, "SER L0 Count: %d\n", cnt.l0); + p += scnprintf(p, end - p, "SER L1 Count: %d\n", cnt.l1); + p += scnprintf(p, end - p, "SER L0 promote event: %d\n", cnt.l0_to_l1); + + return p - buf; +} + +static ssize_t rtw89_debug_priv_btc_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + return rtw89_btc_dump_info(rtwdev, buf, bufsz); +} + +static ssize_t rtw89_debug_priv_btc_manual_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + struct rtw89_btc *btc = &rtwdev->btc; + int ret; + + ret = kstrtobool(buf, &btc->manual_ctrl); + if (ret) + return ret; + + btc->ctrl.manual = btc->manual_ctrl; + + return count; +} + +static ssize_t rtw89_debug_priv_fw_log_manual_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + struct rtw89_fw_log *log = &rtwdev->fw.log; + bool fw_log_manual; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (kstrtobool(buf, &fw_log_manual)) + goto out; + + log->enable = fw_log_manual; + if (log->enable) + rtw89_fw_log_prepare(rtwdev); + rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual); +out: + return count; +} + +static int rtw89_sta_link_info_get_iter(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link) +{ + static const char * const he_gi_str[] = { + [NL80211_RATE_INFO_HE_GI_0_8] = "0.8", + [NL80211_RATE_INFO_HE_GI_1_6] = "1.6", + [NL80211_RATE_INFO_HE_GI_3_2] = "3.2", + }; + static const char * const eht_gi_str[] = { + [NL80211_RATE_INFO_EHT_GI_0_8] = "0.8", + [NL80211_RATE_INFO_EHT_GI_1_6] = "1.6", + [NL80211_RATE_INFO_EHT_GI_3_2] = "3.2", + }; + struct rate_info *rate = &rtwsta_link->ra_report.txrate; + struct ieee80211_rx_status *status = &rtwsta_link->rx_status; + struct rtw89_hal *hal = &rtwdev->hal; + u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; + bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; + struct ieee80211_link_sta *link_sta; + char *p = buf, *end = buf + bufsz; + u8 evm_min, evm_max, evm_1ss; + u16 max_rc_amsdu_len; + u8 rssi; + u8 snr; + int i; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + max_rc_amsdu_len = link_sta->agg.max_rc_amsdu_len; + + rcu_read_unlock(); + + p += scnprintf(p, end - p, "TX rate [%u, %u]: ", rtwsta_link->mac_id, + rtwsta_link->link_id); + + if (rate->flags & RATE_INFO_FLAGS_MCS) + p += scnprintf(p, end - p, "HT MCS-%d%s", rate->mcs, + rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); + else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) + p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", rate->nss, + rate->mcs, + rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); + else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) + p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", rate->nss, + rate->mcs, + rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? + he_gi_str[rate->he_gi] : "N/A"); + else if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) + p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", rate->nss, + rate->mcs, + rate->eht_gi < ARRAY_SIZE(eht_gi_str) ? + eht_gi_str[rate->eht_gi] : "N/A"); + else + p += scnprintf(p, end - p, "Legacy %d", rate->legacy); + p += scnprintf(p, end - p, "%s", + rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); + p += scnprintf(p, end - p, " BW:%u", + rtw89_rate_info_bw_to_mhz(rate->bw)); + p += scnprintf(p, end - p, " (hw_rate=0x%x)", + rtwsta_link->ra_report.hw_rate); + p += scnprintf(p, end - p, " PER:%d", rtwsta_link->ra_report.retry_ratio); + p += scnprintf(p, end - p, " ==> agg_wait=%d (%d)\n", + rtwsta_link->max_agg_wait, + max_rc_amsdu_len); + + p += scnprintf(p, end - p, "RX rate [%u, %u]: ", rtwsta_link->mac_id, + rtwsta_link->link_id); + + switch (status->encoding) { + case RX_ENC_LEGACY: + p += scnprintf(p, end - p, "Legacy %d", status->rate_idx + + (status->band != NL80211_BAND_2GHZ ? 4 : 0)); + break; + case RX_ENC_HT: + p += scnprintf(p, end - p, "HT MCS-%d%s", status->rate_idx, + status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); + break; + case RX_ENC_VHT: + p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", status->nss, + status->rate_idx, + status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); + break; + case RX_ENC_HE: + p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", + status->nss, status->rate_idx, + status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? + he_gi_str[status->he_gi] : "N/A"); + break; + case RX_ENC_EHT: + p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", + status->nss, status->rate_idx, + status->eht.gi < ARRAY_SIZE(eht_gi_str) ? + eht_gi_str[status->eht.gi] : "N/A"); + break; + } + p += scnprintf(p, end - p, " BW:%u", + rtw89_rate_info_bw_to_mhz(status->bw)); + p += scnprintf(p, end - p, " (hw_rate=0x%x)\n", + rtwsta_link->rx_hw_rate); + + rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); + p += scnprintf(p, end - p, "RSSI: %d dBm (raw=%d, prev=%d) [", + RTW89_RSSI_RAW_TO_DBM(rssi), rssi, + rtwsta_link->prev_rssi); + for (i = 0; i < ant_num; i++) { + rssi = ewma_rssi_read(&rtwsta_link->rssi[i]); + p += scnprintf(p, end - p, "%d%s%s", + RTW89_RSSI_RAW_TO_DBM(rssi), + ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", + i + 1 == ant_num ? "" : ", "); + } + p += scnprintf(p, end - p, "]\n"); + + evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss); + p += scnprintf(p, end - p, "EVM: [%2u.%02u, ", evm_1ss >> 2, + (evm_1ss & 0x3) * 25); + for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) { + evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]); + evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]); + + p += scnprintf(p, end - p, "%s(%2u.%02u, %2u.%02u)", + i == 0 ? "" : " ", + evm_min >> 2, (evm_min & 0x3) * 25, + evm_max >> 2, (evm_max & 0x3) * 25); + } + p += scnprintf(p, end - p, "]\t"); + + snr = ewma_snr_read(&rtwsta_link->avg_snr); + p += scnprintf(p, end - p, "SNR: %u\n", snr); + + return p - buf; +} + +static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *rtwsta_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + p += rtw89_sta_link_info_get_iter(rtwdev, p, end - p, rtwsta_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); +} + +static int +rtw89_debug_append_rate(char *buf, size_t bufsz, const u32 *rate_cnt, + int first_rate, int len) +{ + char *p = buf, *end = buf + bufsz; + int i; + + for (i = 0; i < len; i++) + p += scnprintf(p, end - p, "%s%u", i == 0 ? "" : ", ", + rate_cnt[first_rate + i]); + + return p - buf; +} + +#define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate} +#define FIRST_RATE_ENUM(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_V1_ ## rate} +#define FIRST_RATE_GEV1(rate) {RTW89_HW_RATE_INVAL, RTW89_HW_RATE_V1_ ## rate} + +static const struct rtw89_rx_rate_cnt_info { + enum rtw89_hw_rate first_rate[RTW89_CHIP_GEN_NUM]; + int len; + int ext; + const char *rate_mode; +} rtw89_rx_rate_cnt_infos[] = { + {FIRST_RATE_SAME(CCK1), 4, 0, "Legacy:"}, + {FIRST_RATE_SAME(OFDM6), 8, 0, "OFDM:"}, + {FIRST_RATE_ENUM(MCS0), 8, 0, "HT 0:"}, + {FIRST_RATE_ENUM(MCS8), 8, 0, "HT 1:"}, + {FIRST_RATE_ENUM(VHT_NSS1_MCS0), 10, 2, "VHT 1SS:"}, + {FIRST_RATE_ENUM(VHT_NSS2_MCS0), 10, 2, "VHT 2SS:"}, + {FIRST_RATE_ENUM(HE_NSS1_MCS0), 12, 0, "HE 1SS:"}, + {FIRST_RATE_ENUM(HE_NSS2_MCS0), 12, 0, "HE 2SS:"}, + {FIRST_RATE_GEV1(EHT_NSS1_MCS0), 14, 2, "EHT 1SS:"}, + {FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"}, +}; + +static const struct rtw89_tx_rate_cnt_info { + int first_rate; + int len; + const char *rate_mode; +} rtw89_tx_rate_cnt_infos[] = { + {0, 4, "Legacy:"}, + {4, 8, "OFDM:"}, + {12, 14, "MCS 1SS:"}, + {26, 14, "MCS 2SS:"}, +}; + +static int rtw89_get_rx_pkt_stat(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb, + char *buf, size_t bufsz) +{ + struct rtw89_pkt_stat *pkt_stat = &bb->last_pkt_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_rx_rate_cnt_info *info; + u8 rssi = ewma_rssi_read(&bb->bcn_rssi); + char *p = buf, *end = buf + bufsz; + enum rtw89_hw_rate first_rate; + int i; + + p += scnprintf(p, end - p, "Beacon: %u (%d dBm)\n", + pkt_stat->beacon_nr, + RTW89_RSSI_RAW_TO_DBM(rssi)); + + p += scnprintf(p, end - p, "RX count:\n"); + + for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) { + info = &rtw89_rx_rate_cnt_infos[i]; + first_rate = info->first_rate[chip->chip_gen]; + if (first_rate >= RTW89_HW_RATE_NR) + continue; + + p += scnprintf(p, end - p, "%10s [", info->rate_mode); + p += rtw89_debug_append_rate(p, end - p, pkt_stat->rx_rate_cnt, + first_rate, info->len); + if (info->ext) { + p += scnprintf(p, end - p, "]["); + p += rtw89_debug_append_rate(p, end - p, pkt_stat->rx_rate_cnt, + first_rate + info->len, + info->ext); + } + p += scnprintf(p, end - p, "]\n"); + } + + return p - buf; +} + +static ssize_t rtw89_debug_priv_phy_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_traffic_stats *stats = &rtwdev->stats; + struct rtw89_debugfs_iter_data iter_data; + struct rtw89_hal *hal = &rtwdev->hal; + char *p = buf, *end = buf + bufsz; + struct rtw89_bb_ctx *bb; + + p += scnprintf(p, end - p, "TP TX: %u [%u] Mbps (lv: %d", + stats->tx_throughput, stats->tx_throughput_raw, + stats->tx_tfc_lv); + if (hal->thermal_prot_lv) + p += scnprintf(p, end - p, ", duty: %d%%", + 100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP); + p += scnprintf(p, end - p, "), RX: %u [%u] Mbps (lv: %d)\n", + stats->rx_throughput, stats->rx_throughput_raw, + stats->rx_tfc_lv); + p += scnprintf(p, end - p, "Avg packet length: TX=%u, RX=%u\n", + stats->tx_avg_len, + stats->rx_avg_len); + p += scnprintf(p, end - p, "TF: %u\n", stats->rx_tf_periodic); + + rtw89_for_each_active_bb(rtwdev, bb) { + p += scnprintf(p, end - p, "\n[PHY %u]\n", bb->phy_idx); + p += rtw89_get_rx_pkt_stat(rtwdev, bb, p, end - p); + } + p += scnprintf(p, end - p, "\n"); + + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, &iter_data); + p += iter_data.written_sz; + + return p - buf; +} + +static const char *const lcck[] = {"L_CCK"}; +static const char *const scck[] = {"S_CCK"}; +static const char *const ht_gf[] = {"HT_GF"}; +static const char *const vht_mu[] = {"VHT_MU"}; +static const char *const he_er_su[] = {"HE_ER_SU"}; +static const char *const eht_tb[] = {"EHT_TB"}; +static const char *const legacy_ax[] = {"LEGACY"}; +static const char *const ht_ax[] = {"HT"}; +static const char *const vht_su_ax[] = {"VHT_SU"}; +static const char *const he_su_ax[] = {"HE_SU"}; +static const char *const he_mu_ax[] = {"HE_MU"}; +static const char *const he_tb_ax[] = {"HE_TB"}; +static const char *const legacy_be[] = { + "LEGACY", "LEGACY_DUP", "LEGACY_DUP_PUNC" +}; + +static const char *const ht_be[] = { + "HT_MF", "HT_SND_NDP" +}; + +static const char *const vht_su_be[] = { + "VHT_SU", "VHT_SND_NDP" +}; + +static const char *const he_su_be[] = { + "HE_SU", "HE_SND_NDP", "HE_SND_NDP_PUNC", "HE_RANG_NDP" +}; + +static const char *const he_mu_be[] = { + "HE_MU_RU", "HE_MU_MU", "HE_MU_RU_PUNC" +}; + +static const char *const he_tb_be[] = { + "HE_TB", "HE_TB_FB_NDP", "HE_MU_RANG_NDP" +}; + +static const char *const eht_mu[] = { + "EHT_MU_SU", "EHT_MU_ER", "EHT_MU_RU", "EHT_MU_MU", + "EHT_MU_SND_NDP", "EHT_MU_SU_PUNC", "EHT_MU_RU_PUNC", + "EHT_SND_NDP_PUNC", "EHT_MU_MU_PUNC" +}; + +#define PPDU_SAME(ppdu) \ + {.str = {ppdu, ppdu}, \ + .cnt = {ARRAY_SIZE(ppdu), ARRAY_SIZE(ppdu)} } +#define PPDU_VARIANT(ppdu) \ + {.str = {ppdu##_ax, ppdu##_be}, \ + .cnt = {ARRAY_SIZE(ppdu##_ax), ARRAY_SIZE(ppdu##_be)} } +#define PPDU_GEV1(ppdu) \ + {.str = {NULL, ppdu}, \ + .cnt = {0, ARRAY_SIZE(ppdu)} } + +static const struct rtw89_ppdu_info { + const char *const *str[RTW89_CHIP_GEN_NUM]; + u8 cnt[RTW89_CHIP_GEN_NUM]; +} rtw89_ppdu_infos[] = { + [0] = PPDU_SAME(lcck), + [1] = PPDU_SAME(scck), + [2] = PPDU_VARIANT(legacy), + [3] = PPDU_VARIANT(ht), + [4] = PPDU_SAME(ht_gf), + [5] = PPDU_VARIANT(vht_su), + [6] = PPDU_SAME(vht_mu), + [7] = PPDU_VARIANT(he_su), + [8] = PPDU_SAME(he_er_su), + [9] = PPDU_VARIANT(he_mu), + [10] = PPDU_VARIANT(he_tb), + [11] = PPDU_GEV1(eht_mu), + [12] = PPDU_GEV1(eht_tb), +}; + +#define TXCMD_SAME(txcmd) {txcmd, txcmd} +#define TXCMD_DIFF(txcmd, txcmd_v1) {txcmd, txcmd_v1} +#define TXCMD_GEV1(txcmd) {"RSVD", txcmd} + +static const struct rtw89_txcmd_info { + const char *str[RTW89_CHIP_GEN_NUM]; +} rtw89_txcmd_infos[] = { + [0] = {TXCMD_SAME("DATA")}, + [1] = {TXCMD_SAME("BCN")}, + [2] = {TXCMD_SAME("HT_NDPA")}, + [3] = {TXCMD_SAME("VHT_NDPA")}, + [4] = {TXCMD_SAME("HE_NDPA")}, + [5] = {TXCMD_GEV1("EHT_NDPA")}, + [6] = {TXCMD_GEV1("11MC_FTM")}, + [7] = {TXCMD_GEV1("11MC_FTM_ACK")}, + [8] = {TXCMD_SAME("RTS")}, + [9] = {TXCMD_SAME("CTS2S")}, + [10] = {TXCMD_SAME("CF_END")}, + [11] = {TXCMD_SAME("CMP_BAR")}, + [12] = {TXCMD_SAME("BFRP")}, + [13] = {TXCMD_SAME("NDP")}, + [14] = {TXCMD_SAME("QoS_NULL")}, + [15] = {TXCMD_GEV1("CTS_2_MURTS")}, + [16] = {TXCMD_SAME("ACK")}, + [17] = {TXCMD_SAME("CTS")}, + [18] = {TXCMD_SAME("CMP_BA")}, + [19] = {TXCMD_SAME("MSTA_BA")}, + [20] = {TXCMD_SAME("HT_CSI")}, + [21] = {TXCMD_SAME("VHT_CSI")}, + [22] = {TXCMD_SAME("HE_CSI")}, + [23] = {TXCMD_GEV1("EHT_CSI")}, + [24] = {TXCMD_GEV1("NTB_I2R_NDPA")}, + [25] = {TXCMD_GEV1("NTB_I2R_NDP")}, + [26] = {TXCMD_GEV1("NTB_I2R_LMR")}, + [27] = {TXCMD_GEV1("NTB_I2R_NDP")}, + [28] = {TXCMD_GEV1("NTB_I2R_LMR")}, + [29] = {TXCMD_GEV1("NTB_R2I_RANG_NDPA")}, + [30] = {TXCMD_GEV1("NTB_R2I_NDP")}, + [31] = {TXCMD_DIFF("TB_PPDU", "NTB_R2I_LMR")}, + [32] = {TXCMD_SAME("TRIG_BASIC")}, + [33] = {TXCMD_SAME("TRIG_BFRP")}, + [34] = {TXCMD_SAME("TRIG_MUBAR")}, + [35] = {TXCMD_SAME("TRIG_MURTS")}, + [36] = {TXCMD_SAME("TRIG_BSRP")}, + [37] = {TXCMD_SAME("TRIG_BQRP")}, + [38] = {TXCMD_SAME("TRIG_NFRP")}, + [39] = {TXCMD_GEV1("TRIG_BASIC_DATA")}, + [40] = {TXCMD_GEV1("TRIG_RANG_POLL")}, + [41] = {TXCMD_GEV1("TRIG_RANG_SNR")}, + [42] = {TXCMD_GEV1("TRIG_RANG_LMR")}, + [48] = {TXCMD_DIFF("TRIG_BASIC_DATA", "TRIG_TB_CSI")}, + [49] = {TXCMD_GEV1("TRIG_TB_CBA")}, + [50] = {TXCMD_GEV1("TRIG_TB_MBA")}, + [51] = {TXCMD_GEV1("TRIG_TB_BSR")}, + [52] = {TXCMD_GEV1("TRIG_TB_BQR")}, + [53] = {TXCMD_GEV1("TRIG_TB_ACK")}, + [54] = {TXCMD_GEV1("TRIG_TB_PPDU")}, + [55] = {TXCMD_GEV1("TRIG_TB_I2R_CTS2S")}, + [56] = {TXCMD_GEV1("TRIG_TB_I2R_NDP")}, + [57] = {TXCMD_GEV1("TRIG_TB_I2R_LMR")}, +}; + +static const char *rtw89_ppdu_str(struct rtw89_dev *rtwdev, u8 type, u8 subtype) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_ppdu_info *ppdu_info; + + if (type >= ARRAY_SIZE(rtw89_ppdu_infos)) + return "RSVD"; + + ppdu_info = &rtw89_ppdu_infos[type]; + + if (!ppdu_info->str[chip->chip_gen] || + subtype >= ppdu_info->cnt[chip->chip_gen]) + return "RSVD"; + + return ppdu_info->str[chip->chip_gen][subtype]; +} + +static const char *rtw89_txcmd_str(struct rtw89_dev *rtwdev, u8 txcmd) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (txcmd < ARRAY_SIZE(rtw89_txcmd_infos)) + return rtw89_txcmd_infos[txcmd].str[chip->chip_gen] ?: "RSVD"; + + return "RSVD"; +} + +static int rtw89_get_bb_stat(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb, + char *buf, size_t bufsz) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_pkt_stat *pkt_stat = &bb->last_pkt_stat; + const struct rtw89_physts_regs *physts = phy->physts; + struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat; + struct rtw89_tx_stat_info *tx_stat = &bb->tx_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; + u8 factor = chip->txpwr_factor_rf; + u32 reg_nr; + s32 val; + int i; + + p += scnprintf(p, end - p, "\n[PHY %u]\n", bb->phy_idx); + + p += scnprintf(p, end - p, "== PMAC\n"); + p += scnprintf(p, end - p, + "TX [CCK_TXEN, CCK_TXON, OFDM_TXEN, OFDM_TXON]: [%d, %d, %d, %d]\n", + pmac->cck_mac_txen, pmac->cck_phy_txon, + pmac->ofdm_mac_txen, pmac->ofdm_phy_txon); + p += scnprintf(p, end - p, "CRC [CCK, OFDM, HT, VHT, HE, EHT, ALL, MPDU]\n"); + p += scnprintf(p, end - p, " ok: [%d, %d, %d, %d, %d, %d, %d, %d]\n", + pmac->cnt_cck_crc32_ok, pmac->cnt_ofdm_crc32_ok, + pmac->cnt_ht_crc32_ok, pmac->cnt_vht_crc32_ok, + pmac->cnt_he_crc32_ok, pmac->cnt_eht_crc32_ok, + pmac->cnt_crc32_ok_all, pmac->cnt_ampdu_crc_ok); + p += scnprintf(p, end - p, "err: [%d, %d, %d, %d, %d, %d, %d, %d]\n", + pmac->cnt_cck_crc32_error, pmac->cnt_ofdm_crc32_error, + pmac->cnt_ht_crc32_error, pmac->cnt_vht_crc32_error, + pmac->cnt_he_crc32_error, pmac->cnt_eht_crc32_error, + pmac->cnt_crc32_error_all, pmac->cnt_ampdu_crc_error); + p += scnprintf(p, end - p, "CCA [CCK, OFDM]: [%d, %d]\n", + pmac->cnt_cck_cca, pmac->cnt_ofdm_cca); + p += scnprintf(p, end - p, "FA [CCK, OFDM]: [%d, %d]\n", + pmac->cnt_cck_fail, pmac->cnt_ofdm_fail); + + p += scnprintf(p, end - p, "CCA spoofing [CCK, OFDM]: [%d, %d]\n", + pmac->cnt_cck_spoofing, pmac->cnt_ofdm_spoofing); + p += scnprintf(p, end - p, "CCK SFD: %d, SIG_GG: %d\n", + pmac->cnt_sfd_gg, pmac->cnt_sig_gg); + p += scnprintf(p, end - p, + "OFDM Parity: %d, Rate: %d, LSIG_BRK_S: %d, LSIG_BRK_L: %d, SBD: %d\n", + pmac->cnt_parity_fail, pmac->cnt_rate_illegal, + pmac->cnt_lsig_brk_s_th, pmac->cnt_lsig_brk_l_th, + pmac->cnt_sb_search_fail); + p += scnprintf(p, end - p, "AMPDU miss: %d\n\n", pmac->cnt_ampdu_miss); + + p += scnprintf(p, end - p, "== TX General\n"); + p += scnprintf(p, end - p, "%s %s\n", + rtw89_ppdu_str(rtwdev, tx_stat->type, tx_stat->subtype), + rtw89_txcmd_str(rtwdev, tx_stat->txcmd)); + + p += scnprintf(p, end - p, "BW: %d, TX_SC: %d, TX_PATH_EN: %d, PATH_MAP: 0x%x\n", + 20 << tx_stat->bw, tx_stat->txsc, + tx_stat->tx_path_en, tx_stat->path_map); + + val = sign_extend32(tx_stat->tmac_txpwr, 8); + p += scnprintf(p, end - p, "TXPWR TMAC: %d,", val >> factor); + + reg_nr = min(chip->rf_path_num, ARRAY_SIZE(tx_stat->txpwr)); + for (i = 0; i < reg_nr; i++) { + val = sign_extend32(tx_stat->txpwr[i], 8); + p += scnprintf(p, end - p, " P%d: %d%s", + i, val >> factor, (i < reg_nr - 1) ? "," : ""); + } + p += scnprintf(p, end - p, " dBm\n"); + + p += scnprintf(p, end - p, "MCS: %d, STBC: %d\n", + tx_stat->max_mcs, tx_stat->stbc); + + p += scnprintf(p, end - p, "Info: ["); + reg_nr = min(physts->tx_info.reg_nr, ARRAY_SIZE(tx_stat->info)); + for (i = 0; i < reg_nr; i++) + p += scnprintf(p, end - p, "0x%08x%s", + tx_stat->info[i], (i < reg_nr - 1) ? ", " : ""); + p += scnprintf(p, end - p, "]\n"); + + p += scnprintf(p, end - p, "Common ctrl: ["); + reg_nr = min(physts->tx_common_ctrl.reg_nr, ARRAY_SIZE(tx_stat->common_ctrl)); + for (i = 0; i < reg_nr; i++) + p += scnprintf(p, end - p, "0x%08x%s", + tx_stat->common_ctrl[i], (i < reg_nr - 1) ? ", " : ""); + p += scnprintf(p, end - p, "]\n\n"); + + p += scnprintf(p, end - p, "== RX General\n"); + p += scnprintf(p, end - p, + "LDPC: %d, BCC: %d, STBC: %d, SU_NON_BF: %d, SU_BF: %d, MU: %d\n\n", + pkt_stat->rx.ldpc, pkt_stat->rx.bcc, + pkt_stat->rx.stbc, pkt_stat->rx.su_non_bf, + pkt_stat->rx.su_bf, pkt_stat->rx.mu); + + p += scnprintf(p, end - p, "== RSSI/RX Rate\n"); + p += rtw89_get_rx_pkt_stat(rtwdev, bb, p, end - p); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_bb_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_bb_stat_cfg *bb_stat = &rtwdev->phy_info.bb_stat_cfg; + struct rtw89_traffic_stats *stats = &rtwdev->stats; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_tx_rate_cnt_info *info; + struct rtw89_debugfs_iter_data iter_data; + char *p = buf, *end = buf + bufsz; + struct rtw89_bb_ctx *bb; + int i; + + p += scnprintf(p, end - p, "TP TX: %u [%u] Mbps, RX: %u [%u] Mbps\n", + stats->tx_throughput, stats->tx_throughput_raw, + stats->rx_throughput, stats->rx_throughput_raw); + p += scnprintf(p, end - p, "Avg packet length: TX=%u, RX=%u\n", + stats->tx_avg_len, + stats->rx_avg_len); + p += scnprintf(p, end - p, "TF: %u\n", stats->rx_tf_periodic); + + if (chip->chip_gen != RTW89_CHIP_AX) { + p += scnprintf(p, end - p, + "TX count [0x%x]:\n", bb_stat->mac_id); + + for (i = 0; i < ARRAY_SIZE(rtw89_tx_rate_cnt_infos); i++) { + info = &rtw89_tx_rate_cnt_infos[i]; + + p += scnprintf(p, end - p, "%10s [", info->rate_mode); + p += rtw89_debug_append_rate(p, end - p, + rtwdev->phystat.tx_rate_cnt, + info->first_rate, info->len); + p += scnprintf(p, end - p, "]\n"); + } + } + + rtw89_for_each_active_bb(rtwdev, bb) + p += rtw89_get_bb_stat(rtwdev, bb, p, end - p); + p += scnprintf(p, end - p, "\n"); + + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, &iter_data); + p += iter_data.written_sz; + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_bb_info_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + struct rtw89_bb_stat_cfg *bb_stat = &rtwdev->phy_info.bb_stat_cfg; + int val; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (sscanf(buf, "enable %d", &val) == 1) + bb_stat->enable = !!val; + else if (sscanf(buf, "mac_id %x", &val) == 1) + rtw89_fw_h2c_tx_history(rtwdev, val); + else + return -EINVAL; + + return count; +} + +static int rtw89_dump_addr_cam(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_addr_cam_entry *addr_cam) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + const struct rtw89_sec_cam_entry *sec_entry; + char *p = buf, *end = buf + bufsz; + u8 sec_cam_idx; + int i; + + p += scnprintf(p, end - p, "\taddr_cam_idx=%u\n", + addr_cam->addr_cam_idx); + p += scnprintf(p, end - p, "\t-> bssid_cam_idx=%u\n", + addr_cam->bssid_cam_idx); + p += scnprintf(p, end - p, "\tsec_cam_bitmap=%*ph\n", + (int)sizeof(addr_cam->sec_cam_map), + addr_cam->sec_cam_map); + for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) { + sec_cam_idx = addr_cam->sec_ent[i]; + sec_entry = cam_info->sec_entries[sec_cam_idx]; + if (!sec_entry) + continue; + p += scnprintf(p, end - p, "\tsec[%d]: sec_cam_idx %u", i, + sec_entry->sec_cam_idx); + if (sec_entry->ext_key) + p += scnprintf(p, end - p, ", %u", + sec_entry->sec_cam_idx + 1); + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +__printf(4, 5) +static int rtw89_dump_pkt_offload(char *buf, size_t bufsz, struct list_head *pkt_list, + const char *fmt, ...) +{ + char *p = buf, *end = buf + bufsz; + struct rtw89_pktofld_info *info; + struct va_format vaf; + va_list args; + + if (list_empty(pkt_list)) + return 0; + + va_start(args, fmt); + vaf.va = &args; + vaf.fmt = fmt; + + p += scnprintf(p, end - p, "%pV", &vaf); + + va_end(args); + + list_for_each_entry(info, pkt_list, list) + p += scnprintf(p, end - p, "%d ", info->id); + + p += scnprintf(p, end - p, "\n"); + + return p - buf; +} + +static int rtw89_vif_link_ids_get(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, u8 *mac, + struct rtw89_vif_link *rtwvif_link, + bool designated) +{ + struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, " [%u] %pM\n", rtwvif_link->mac_id, + rtwvif_link->mac_addr); + p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwvif_link->link_id, + designated ? " (*)" : ""); + p += scnprintf(p, end - p, "\tbssid_cam_idx=%u\n", + bssid_cam->bssid_cam_idx); + p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwvif_link->addr_cam); + p += rtw89_dump_pkt_offload(p, end - p, &rtwvif_link->general_pkt_list, + "\tpkt_ofld[GENERAL]: "); + + return p - buf; +} + +static +void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *designated_link; + struct rtw89_vif_link *rtwvif_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; + unsigned int link_id; + + designated_link = rtw89_get_designated_link(rtwvif); + + p += scnprintf(p, end - p, "VIF %pM\n", rtwvif->mac_addr); + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + p += rtw89_vif_link_ids_get(rtwdev, p, end - p, mac, rtwvif_link, + rtwvif_link == designated_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); +} + +static int rtw89_dump_ba_cam(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_ba_cam_entry *entry; + char *p = buf, *end = buf + bufsz; + bool first = true; + + list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) { + if (first) { + p += scnprintf(p, end - p, "\tba_cam "); + first = false; + } else { + p += scnprintf(p, end - p, ", "); + } + p += scnprintf(p, end - p, "tid[%u]=%d", entry->tid, + (int)(entry - rtwdev->cam_info.ba_cam_entry)); + } + p += scnprintf(p, end - p, "\n"); + + return p - buf; +} + +static int rtw89_sta_link_ids_get(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link, + bool designated) +{ + struct ieee80211_link_sta *link_sta; + char *p = buf, *end = buf + bufsz; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + p += scnprintf(p, end - p, " [%u] %pM\n", rtwsta_link->mac_id, + link_sta->addr); + + rcu_read_unlock(); + + p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwsta_link->link_id, + designated ? " (*)" : ""); + p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwsta_link->addr_cam); + p += rtw89_dump_ba_cam(rtwdev, p, end - p, rtwsta_link); + + return p - buf; +} + +static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *designated_link; + struct rtw89_sta_link *rtwsta_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; + unsigned int link_id; + + designated_link = rtw89_get_designated_link(rtwsta); + + p += scnprintf(p, end - p, "STA %pM %s\n", sta->addr, + sta->tdls ? "(TDLS)" : ""); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + p += rtw89_sta_link_ids_get(rtwdev, p, end - p, rtwsta_link, + rtwsta_link == designated_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); +} + +static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + struct rtw89_debugfs_iter_data iter_data; + char *p = buf, *end = buf + bufsz; + u8 idx; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + p += scnprintf(p, end - p, "map:\n"); + p += scnprintf(p, end - p, "\tmac_id: %*ph\n", + (int)sizeof(rtwdev->mac_id_map), + rtwdev->mac_id_map); + p += scnprintf(p, end - p, "\taddr_cam: %*ph\n", + (int)sizeof(cam_info->addr_cam_map), + cam_info->addr_cam_map); + p += scnprintf(p, end - p, "\tbssid_cam: %*ph\n", + (int)sizeof(cam_info->bssid_cam_map), + cam_info->bssid_cam_map); + p += scnprintf(p, end - p, "\tsec_cam: %*ph\n", + (int)sizeof(cam_info->sec_cam_map), + cam_info->sec_cam_map); + p += scnprintf(p, end - p, "\tba_cam: %*ph\n", + (int)sizeof(cam_info->ba_cam_map), + cam_info->ba_cam_map); + p += scnprintf(p, end - p, "\tpkt_ofld: %*ph\n", + (int)sizeof(rtwdev->pkt_offload), + rtwdev->pkt_offload); + + for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { + if (!(rtwdev->chip->support_bands & BIT(idx))) + continue; + p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx], + "\t\t[SCAN %u]: ", idx); + } + + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, + IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, &iter_data); + p += iter_data.written_sz; + + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, &iter_data); + p += iter_data.written_sz; + + return p - buf; +} + +#define DM_INFO(type) {RTW89_DM_ ## type, #type} + +static const struct rtw89_disabled_dm_info { + enum rtw89_dm_type type; + const char *name; +} rtw89_disabled_dm_infos[] = { + DM_INFO(DYNAMIC_EDCCA), + DM_INFO(THERMAL_PROTECT), + DM_INFO(TAS), + DM_INFO(MLO), + DM_INFO(HW_SCAN), + DM_INFO(INACTIVE_PS), + DM_INFO(DIG_PD), + DM_INFO(VCORE), +}; + +static ssize_t +rtw89_debug_priv_disable_dm_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + const struct rtw89_disabled_dm_info *info; + struct rtw89_hal *hal = &rtwdev->hal; + char *p = buf, *end = buf + bufsz; + u32 disabled; + int i; + + p += scnprintf(p, end - p, "Disabled DM: 0x%x\n", + hal->disabled_dm_bitmap); + + for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) { + info = &rtw89_disabled_dm_infos[i]; + disabled = BIT(info->type) & hal->disabled_dm_bitmap; + + p += scnprintf(p, end - p, "[%d] %s: %c\n", info->type, + info->name, + disabled ? 'X' : 'O'); + } + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_disable_dm_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 conf; + int ret; + + ret = kstrtou32(buf, 0, &conf); + if (ret) + return -EINVAL; + + rtw89_core_dm_disable_cfg(rtwdev, conf); + + return count; +} + +#define RTW89_DIG_PD_TH_MIN_DBM -102 +#define RTW89_DIG_PD_TH_MAX_DBM -40 +#define RTW89_DIG_PD_TH_STEP 2 + +static s8 rtw89_dig_pd_th_to_dbm(u8 reg_val) +{ + return RTW89_DIG_PD_TH_MIN_DBM + RTW89_DIG_PD_TH_STEP * reg_val; +} + +static u8 rtw89_dig_pd_th_dbm_to_reg(s8 dbm) +{ + return (dbm - RTW89_DIG_PD_TH_MIN_DBM) / RTW89_DIG_PD_TH_STEP; +} + +static ssize_t +rtw89_debug_priv_static_pd_th_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_hal *hal = &rtwdev->hal; + char *p = buf, *end = buf + bufsz; + bool disabled; + s8 pd_th_dbm; + s8 cck_pd_th; + + disabled = hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD); + + if (disabled) { + pd_th_dbm = rtw89_dig_pd_th_to_dbm(hal->fixed_dig_pd_th); + cck_pd_th = hal->fixed_dig_cck_pd_th; + + p += scnprintf(p, end - p, "DIG: static\n"); + p += scnprintf(p, end - p, "OFDM PD threshold: %d dBm\n", pd_th_dbm); + p += scnprintf(p, end - p, "CCK PD threshold: %d dBm\n", cck_pd_th); + } else { + p += scnprintf(p, end - p, "DIG: dynamic\n"); + } + + p += scnprintf(p, end - p, "\nUsage: echo [pd_th] > static_pd_th\n"); + p += scnprintf(p, end - p, " mode: 0 = dynamic, 1 = static\n"); + p += scnprintf(p, end - p, " pd_th: PD threshold in dBm (-102 ~ -40)\n"); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_static_pd_th_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + struct rtw89_hal *hal = &rtwdev->hal; + int ret; + u32 mode; + s32 pd_th_dbm; + + ret = sscanf(buf, "%u %d", &mode, &pd_th_dbm); + if (ret < 1) + return -EINVAL; + + if (mode > 1) + return -EINVAL; + + if (mode == 0) { + rtw89_core_dm_disable_clr(rtwdev, RTW89_DM_DIG_PD); + hal->fixed_dig_pd_th = 0; + hal->fixed_dig_cck_pd_th = 0; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "DIG static mode disabled\n"); + } else { + if (ret < 2 || pd_th_dbm < RTW89_DIG_PD_TH_MIN_DBM || + pd_th_dbm > RTW89_DIG_PD_TH_MAX_DBM) + return -EINVAL; + + rtw89_core_dm_disable_set(rtwdev, RTW89_DM_DIG_PD); + hal->fixed_dig_pd_th = clamp(rtw89_dig_pd_th_dbm_to_reg(pd_th_dbm), + 0, 0x1f); + /* CCK uses dBm directly */ + hal->fixed_dig_cck_pd_th = pd_th_dbm; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "DIG static mode: PD=0x%02x (%d dBm), CCK=%d dBm\n", + hal->fixed_dig_pd_th, + rtw89_dig_pd_th_to_dbm(hal->fixed_dig_pd_th), + hal->fixed_dig_cck_pd_th); + } + + return count; +} + +static void rtw89_debug_mlo_mode_set_mlsr(struct rtw89_dev *rtwdev, + unsigned int link_id) +{ + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + vif = rtwvif_to_vif(rtwvif); + if (!ieee80211_vif_is_mld(vif)) + continue; + + rtw89_core_mlsr_switch(rtwdev, rtwvif, link_id); + } +} + +static ssize_t +rtw89_debug_priv_mlo_mode_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + bool mlo_dm_dis = rtwdev->hal.disabled_dm_bitmap & BIT(RTW89_DM_MLO); + char *p = buf, *end = buf + bufsz; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + int count = 0; + + p += scnprintf(p, end - p, "MLD(s) status: (MLO DM: %s)\n", + str_disable_enable(mlo_dm_dis)); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + vif = rtwvif_to_vif(rtwvif); + if (!ieee80211_vif_is_mld(vif)) + continue; + + p += scnprintf(p, end - p, + "\t#%u: MLO mode %x, valid 0x%x, active 0x%x\n", + count++, rtwvif->mlo_mode, vif->valid_links, + vif->active_links); + } + + if (count == 0) + p += scnprintf(p, end - p, "\t(None)\n"); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_mlo_mode_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u8 num, mlo_mode; + u32 argv; + + num = sscanf(buf, "%hhx %u", &mlo_mode, &argv); + if (num != 2) + return -EINVAL; + + rtw89_core_dm_disable_set(rtwdev, RTW89_DM_MLO); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "Set MLO mode to %x\n", mlo_mode); + + switch (mlo_mode) { + case RTW89_MLO_MODE_MLSR: + rtw89_debug_mlo_mode_set_mlsr(rtwdev, argv); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_STATE, "Unsupported MLO mode\n"); + rtw89_core_dm_disable_clr(rtwdev, RTW89_DM_MLO); + + return -EOPNOTSUPP; + } + + return count; +} + +static int rtw89_get_beacon_info(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb, + char *buf, size_t bufsz) +{ + struct rtw89_pkt_stat *pkt_stat = &bb->last_pkt_stat; + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, "[PHY %u]\n", bb->phy_idx); + p += scnprintf(p, end - p, "Beacon: %u\n", pkt_stat->beacon_nr); + p += scnprintf(p, end - p, "raw rssi: %lu\n", ewma_rssi_read(&bb->bcn_rssi)); + p += scnprintf(p, end - p, "hw rate: %u\n", pkt_stat->beacon_rate); + p += scnprintf(p, end - p, "length: %u\n\n", pkt_stat->beacon_len); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_beacon_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; + struct rtw89_beacon_dist *bcn_dist = &bcn_stat->bcn_dist; + u16 upper, lower = bcn_stat->tbtt_tu_min; + char *p = buf, *end = buf + bufsz; + u16 *drift = bcn_stat->drift; + u8 bcn_num = bcn_stat->num; + struct rtw89_bb_ctx *bb; + u8 count; + u8 i; + + rtw89_for_each_active_bb(rtwdev, bb) + p += rtw89_get_beacon_info(rtwdev, bb, p, end - p); + + p += scnprintf(p, end - p, "[Beacon info]\n"); + p += scnprintf(p, end - p, "interval: %u\n", bcn_track->beacon_int); + p += scnprintf(p, end - p, "dtim: %u\n", bcn_track->dtim); + + p += scnprintf(p, end - p, "\n[Distribution]\n"); + p += scnprintf(p, end - p, "tbtt\n"); + for (i = 0; i < RTW89_BCN_TRACK_MAX_BIN_NUM; i++) { + upper = lower + RTW89_BCN_TRACK_BIN_WIDTH - 1; + if (i == RTW89_BCN_TRACK_MAX_BIN_NUM - 1) + upper = max(upper, bcn_stat->tbtt_tu_max); + + p += scnprintf(p, end - p, "%02u - %02u: %u\n", + lower, upper, bcn_dist->bins[i]); + + lower = upper + 1; + } + + p += scnprintf(p, end - p, "\ndrift\n"); + + for (i = 0; i < bcn_num; i += count) { + count = 1; + while (i + count < bcn_num && drift[i] == drift[i + count]) + count++; + + p += scnprintf(p, end - p, "%u: %u\n", drift[i], count); + } + p += scnprintf(p, end - p, "\nlower bound: %u\n", bcn_dist->lower_bound); + p += scnprintf(p, end - p, "upper bound: %u\n", bcn_dist->upper_bound); + p += scnprintf(p, end - p, "outlier count: %u\n", bcn_dist->outlier_count); + + p += scnprintf(p, end - p, "\n[Tracking]\n"); + p += scnprintf(p, end - p, "tbtt offset: %u\n", bcn_track->tbtt_offset); + p += scnprintf(p, end - p, "bcn timeout: %u\n", bcn_track->bcn_timeout); + + return p - buf; +} + +enum __diag_mac_cmd { + __CMD_EQUALV, + __CMD_EQUALO, + __CMD_NEQUALV, + __CMD_NEQUALO, + __CMD_SETEQUALV, + __CMD_SETEQUALO, + __CMD_CMPWCR, + __CMD_CMPWWD, + __CMD_NEQ_CMPWCR, + __CMD_NEQ_CMPWWD, + __CMD_INCREMENT, + __CMD_MESSAGE, +}; + +enum __diag_mac_io { + __IO_NORMAL, + __IO_NORMAL_PCIE, + __IO_NORMAL_USB, + __IO_NORMAL_SDIO, + __IO_PCIE_CFG, + __IO_SDIO_CCCR, +}; + +struct __diag_mac_rule_header { + u8 sheet; + u8 cmd; + u8 seq_major; + u8 seq_minor; + u8 io_band; + #define __DIAG_MAC_IO GENMASK(3, 0) + #define __DIAG_MAC_N_BAND BIT(4) + #define __DIAG_MAC_HAS_BAND BIT(5) + u8 len; /* include header. Unit: 4 bytes */ + u8 rsvd[2]; +} __packed; + +struct __diag_mac_rule_equal { + struct __diag_mac_rule_header header; + __le32 addr; + __le32 addr_name_offset; + __le32 mask; + __le32 val; + __le32 msg_offset; + u8 rsvd[4]; +} __packed; + +struct __diag_mac_rule_increment { + struct __diag_mac_rule_header header; + __le32 addr; + __le32 addr_name_offset; + __le32 mask; + __le16 sel; + __le16 delay; + __le32 msg_offset; + u8 rsvd[4]; +} __packed; + +struct __diag_mac_msg_buf { + __le16 len; + char string[]; +} __packed; + +static ssize_t rtw89_mac_diag_do_equalv(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + const struct __diag_mac_rule_equal *r, + const void *msg_start, + u64 *positive_bmp) +{ + const struct __diag_mac_msg_buf *name = msg_start + + le32_to_cpu(r->addr_name_offset); + const struct __diag_mac_msg_buf *msg = msg_start + + le32_to_cpu(r->msg_offset); + bool want_eq = r->header.cmd == __CMD_EQUALV; + char *p = buf, *end = buf + bufsz; + bool equal = false; + u32 val; + + *positive_bmp <<= 1; + + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) + val = rtw89_read32_pci_cfg(rtwdev, le32_to_cpu(r->addr)); + else + val = rtw89_read32(rtwdev, le32_to_cpu(r->addr)); + + if ((val & le32_to_cpu(r->mask)) == le32_to_cpu(r->val)) + equal = true; + + if (want_eq == equal) { + *positive_bmp |= BIT(0); + return p - buf; + } + + p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s => %x, %.*s\n", + r->header.sheet, r->header.cmd, le16_to_cpu(name->len), + name->string, val, le16_to_cpu(msg->len), msg->string); + + return p - buf; +} + +static ssize_t rtw89_mac_diag_do_increment(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + const struct __diag_mac_rule_increment *r, + const void *msg_start, + u64 *positive_bmp) +{ + const struct __diag_mac_msg_buf *name = msg_start + + le32_to_cpu(r->addr_name_offset); + const struct __diag_mac_msg_buf *msg = msg_start + + le32_to_cpu(r->msg_offset); + char *p = buf, *end = buf + bufsz; + u32 addr = le32_to_cpu(r->addr); + u32 mask = le32_to_cpu(r->mask); + u16 sel = le16_to_cpu(r->sel); + u32 val1, val2; + + *positive_bmp <<= 1; + + rtw89_write32(rtwdev, addr, sel); + + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) + val1 = rtw89_read32_pci_cfg(rtwdev, addr); + else + val1 = rtw89_read32(rtwdev, addr); + + mdelay(le16_to_cpu(r->delay)); + + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) + val2 = rtw89_read32_pci_cfg(rtwdev, addr); + else + val2 = rtw89_read32(rtwdev, addr); + + if ((val2 & mask) > (val1 & mask)) { + *positive_bmp |= BIT(0); + return p - buf; + } + + p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s [%d]=> %x, %.*s\n", + r->header.sheet, r->header.cmd, le16_to_cpu(name->len), + name->string, le16_to_cpu(r->sel), val1, + le16_to_cpu(msg->len), msg->string); + + return p - buf; +} + +static bool rtw89_mac_diag_match_hci(struct rtw89_dev *rtwdev, + const struct __diag_mac_rule_header *rh) +{ + switch (u8_get_bits(rh->io_band, __DIAG_MAC_IO)) { + case __IO_NORMAL: + default: + return true; + case __IO_NORMAL_PCIE: + case __IO_PCIE_CFG: + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + return true; + break; + case __IO_NORMAL_USB: + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + return true; + break; + case __IO_NORMAL_SDIO: + case __IO_SDIO_CCCR: + if (rtwdev->hci.type == RTW89_HCI_TYPE_SDIO) + return true; + break; + } + + return false; +} + +static bool rtw89_mac_diag_match_band(struct rtw89_dev *rtwdev, + const struct __diag_mac_rule_header *rh) +{ + u8 active_bands; + bool has_band; + u8 band; + + has_band = u8_get_bits(rh->io_band, __DIAG_MAC_HAS_BAND); + if (!has_band) + return true; + + band = u8_get_bits(rh->io_band, __DIAG_MAC_N_BAND); + active_bands = rtw89_get_active_phy_bitmap(rtwdev); + + if (active_bands & BIT(band)) + return true; + + return false; +} + +static ssize_t rtw89_mac_diag_iter_all(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz) +{ + const struct rtw89_fw_element_hdr *elm = rtwdev->fw.elm_info.diag_mac; + u32 n_plains = 0, n_rules = 0, n_positive = 0, n_ignore = 0; + char *p = buf, *end = buf + bufsz, *p_rewind; + const void *rule, *rule_end; + u32 elm_size, rule_size; + const void *msg_start; + u64 positive_bmp = 0; + u8 prev_sheet = 0; + u8 prev_seq = 0; + int limit; + + if (!elm) { + p += scnprintf(p, end - p, "No diag_mac entry\n"); + goto out; + } + + rule_size = le32_to_cpu(elm->u.diag_mac.rule_size); + elm_size = le32_to_cpu(elm->size); + + if (ALIGN(rule_size, 16) > elm_size) { + p += scnprintf(p, end - p, "rule size (%u) exceed elm_size (%u)\n", + ALIGN(rule_size, 16), elm_size); + goto out; + } + + rule = &elm->u.diag_mac.rules_and_msgs[0]; + rule_end = &elm->u.diag_mac.rules_and_msgs[rule_size]; + msg_start = &elm->u.diag_mac.rules_and_msgs[ALIGN(rule_size, 16)]; + + for (limit = 0; limit < 5000 && rule < rule_end; limit++) { + const struct __diag_mac_rule_header *rh = rule; + u8 sheet = rh->sheet; + u8 seq = rh->seq_major; + + if (!rtw89_mac_diag_match_hci(rtwdev, rh) || + !rtw89_mac_diag_match_band(rtwdev, rh)) { + n_ignore++; + goto next; + } + + if (!seq || prev_sheet != sheet || prev_seq != seq) { + if (positive_bmp) { + n_positive++; + /* + * discard output for negative results if one in + * a sequence set is positive. + */ + if (p_rewind) + p = p_rewind; + } + p_rewind = seq ? p : NULL; + positive_bmp = 0; + n_rules++; + } + + switch (rh->cmd) { + case __CMD_EQUALV: + case __CMD_NEQUALV: + p += rtw89_mac_diag_do_equalv(rtwdev, p, end - p, rule, + msg_start, &positive_bmp); + break; + case __CMD_INCREMENT: + p += rtw89_mac_diag_do_increment(rtwdev, p, end - p, rule, + msg_start, &positive_bmp); + break; + default: + p += scnprintf(p, end - p, "unknown rule cmd %u\n", rh->cmd); + break; + } + +next: + n_plains++; + rule += rh->len * 4; + prev_seq = seq; + prev_sheet = sheet; + } + + if (positive_bmp) { + n_positive++; + if (p_rewind) + p = p_rewind; + } + + p += scnprintf(p, end - p, "\nPlain(Ignore)/Rules/Positive: %u(%u)/%u/%u\n", + n_plains, n_ignore, n_rules, n_positive); + +out: + return p - buf; +} + +static ssize_t +rtw89_debug_priv_diag_mac_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_leave_lps(rtwdev); + + return rtw89_mac_diag_iter_all(rtwdev, buf, bufsz); +} + +static int rtw89_get_diag_bb(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb, + char *buf, size_t bufsz) +{ + struct rtw89_diag_bb *diag = &bb->diag; + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, "[PHY %u]\n", bb->phy_idx); + p += scnprintf(p, end - p, "Diag bitmap = 0x%x\n", diag->diag_bb_bitmap); + p += scnprintf(p, end - p, + "Event{Hang, PD MAX, No RX, High FA, High EDCCA Ratio} = "); + p += scnprintf(p, end - p, "{%d, %d, %d, %d, %d}\n", + diag->diag_bb_cnt[RTW89_DIAG_BB_HANG], + diag->diag_bb_cnt[RTW89_DIAG_BB_PD], + diag->diag_bb_cnt[RTW89_DIAG_BB_NO_RX], + diag->diag_bb_cnt[RTW89_DIAG_BB_FA], + diag->diag_bb_cnt[RTW89_DIAG_BB_EDCCA]); + p += scnprintf(p, end - p, + "consecutive_no_tx_cnt=%d, consecutive_no_rx_cnt=%d\n\n", + diag->consecutive_no_tx_cnt, + diag->consecutive_no_rx_cnt); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_diag_bb_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + char *p = buf, *end = buf + bufsz; + struct rtw89_bb_ctx *bb; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_for_each_active_bb(rtwdev, bb) + p += rtw89_get_diag_bb(rtwdev, bb, p, end - p); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_diag_rf_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait; + char *p = buf, *end = buf + bufsz; + int i, j; + + p += scnprintf(p, end - p, "RFK (next index: %d)\n", info->record_idx); + + p += scnprintf(p, end - p, " PHY-X ="); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) { + struct rtw89_rfk_record *record = &info->records[i]; + + p += scnprintf(p, end - p, " %4d ", record->phy_idx); + } + p += scnprintf(p, end - p, "\n"); + + for (j = 0; j < RTW89_RFK_RECORD_PATH_NR; j++) { + p += scnprintf(p, end - p, " S%d-CH =", j); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) { + struct rtw89_rfk_record *record = &info->records[i]; + + p += scnprintf(p, end - p, " %05x", record->ch[j]); + } + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " S%d-CV =", j); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) { + struct rtw89_rfk_record *record = &info->records[i]; + + p += scnprintf(p, end - p, " %05x", record->cv[j]); + } + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " S%d-C5 =", j); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) { + struct rtw89_rfk_record *record = &info->records[i]; + + p += scnprintf(p, end - p, " %05x", record->c5[j]); + } + p += scnprintf(p, end - p, "\n"); + } + + for (j = 0; j < NUM_OF_RTW89_RFK_REPORT_TYPES; j++) { + p += scnprintf(p, end - p, " %-8s =", rtw89_rfk_report_names[j]); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) { + struct rtw89_rfk_record *record = &info->records[i]; + + p += scnprintf(p, end - p, " %4d ", record->states[j]); + } + p += scnprintf(p, end - p, "\n"); + } + + p += scnprintf(p, end - p, "TSSI-track (next index: %d)\n", info->record_tssi_idx); + + for (j = 0; j < RTW89_RFK_RECORD_PATH_NR; j++) { + p += scnprintf(p, end - p, " S%d =", j); + for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) + p += scnprintf(p, end - p, " %03x", info->tssi_code[i][j]); + p += scnprintf(p, end - p, "\n"); + } + + return p - buf; +} + +static void rtw89_dbg_diag_rf_set_rfk(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); +} + +enum rtw89_dbg_diag_rf_type { + RTW89_DBG_DIAG_RF_RSVD = 0, + RTW89_DBG_DIAG_RF_RFK = 1, +}; + +static ssize_t +rtw89_debug_priv_diag_rf_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u8 type; + int ret; + + ret = kstrtou8(buf, 0, &type); + if (ret) + return -EINVAL; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + rtw89_leave_ps_mode(rtwdev); + + switch (type) { + case RTW89_DBG_DIAG_RF_RFK: + rtw89_dbg_diag_rf_set_rfk(rtwdev); + break; + default: + return -EOPNOTSUPP; + } + + return count; +} + +static ssize_t +rtw89_debug_priv_monitor_opts_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; + u32 bss_color; + u32 aid; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + bss_color = rtw89_phy_read32_idx(rtwdev, chip->bss_clr_map_reg, + B_BSS_CLR_MAP_TGT, RTW89_PHY_0); + aid = rtw89_phy_read32_idx(rtwdev, chip->bss_clr_map_reg, + B_BSS_CLR_MAP_STAID, RTW89_PHY_0); + + p += scnprintf(p, end - p, "bss_color=0x%x aid=0x%x\n", bss_color, aid); + + return p - buf; +} + +static ssize_t +rtw89_debug_priv_monitor_opts_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) +{ + u32 bss_color; + u32 aid; + int num; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + num = sscanf(buf, "%x %x", &bss_color, &aid); + if (num != 2) { + rtw89_info(rtwdev, "valid format: \n"); + return -EINVAL; + } + + rtw89_leave_ps_mode(rtwdev); + + __rtw89_phy_set_bss_color(rtwdev, bss_color, aid, RTW89_PHY_0); + + return count; +} + +#define rtw89_debug_priv_get(name, opts...) \ +{ \ + .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ +} + +#define rtw89_debug_priv_set(name, opts...) \ +{ \ + .cb_write = rtw89_debug_priv_ ##name## _set, \ + .opt = { opts }, \ +} + +#define rtw89_debug_priv_select_and_get(name, opts...) \ +{ \ + .cb_write = rtw89_debug_priv_ ##name## _select, \ + .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ +} + +#define rtw89_debug_priv_set_and_get(name, opts...) \ +{ \ + .cb_write = rtw89_debug_priv_ ##name## _set, \ + .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ +} + +#define RSIZE_8K .rsize = 0x2000 +#define RSIZE_12K .rsize = 0x3000 +#define RSIZE_16K .rsize = 0x4000 +#define RSIZE_20K .rsize = 0x5000 +#define RSIZE_32K .rsize = 0x8000 +#define RSIZE_64K .rsize = 0x10000 +#define RSIZE_128K .rsize = 0x20000 +#define RSIZE_1M .rsize = 0x100000 +#define RLOCK .rlock = 1 +#define WLOCK .wlock = 1 +#define RWLOCK RLOCK, WLOCK + +static const struct rtw89_debugfs rtw89_debugfs_templ = { + .read_reg = rtw89_debug_priv_select_and_get(read_reg), + .write_reg = rtw89_debug_priv_set(write_reg), + .read_rf = rtw89_debug_priv_select_and_get(read_rf, RLOCK), + .write_rf = rtw89_debug_priv_set(write_rf, WLOCK), + .rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump, RSIZE_8K, RLOCK), + .txpwr_table = rtw89_debug_priv_get(txpwr_table, RSIZE_20K, RLOCK), + .mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump, RSIZE_128K), + .mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump, RSIZE_16K, RLOCK), + .mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump, RSIZE_1M), + .send_h2c = rtw89_debug_priv_set(send_h2c), + .early_h2c = rtw89_debug_priv_set_and_get(early_h2c, RWLOCK), + .fw_crash = rtw89_debug_priv_set_and_get(fw_crash, WLOCK), + .ser_counters = rtw89_debug_priv_get(ser_counters, RLOCK), + .btc_info = rtw89_debug_priv_get(btc_info, RSIZE_12K), + .btc_manual = rtw89_debug_priv_set(btc_manual), + .fw_log_manual = rtw89_debug_priv_set(fw_log_manual, WLOCK), + .phy_info = rtw89_debug_priv_get(phy_info), + .bb_info = rtw89_debug_priv_set_and_get(bb_info, RWLOCK), + .stations = rtw89_debug_priv_get(stations, RLOCK), + .disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK), + .static_pd_th = rtw89_debug_priv_set_and_get(static_pd_th, RWLOCK), + .mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK), + .beacon_info = rtw89_debug_priv_get(beacon_info), + .diag_mac = rtw89_debug_priv_get(diag_mac, RSIZE_16K, RLOCK), + .diag_bb = rtw89_debug_priv_get(diag_bb, RSIZE_8K, RLOCK), + .diag_rf = rtw89_debug_priv_set_and_get(diag_rf, RWLOCK), + .monitor_opts = rtw89_debug_priv_set_and_get(monitor_opts, RWLOCK), +}; + +#define rtw89_debugfs_add(name, mode, fopname, parent) \ + do { \ + struct rtw89_debugfs_priv *priv = &rtwdev->debugfs->name; \ + priv->rtwdev = rtwdev; \ + if (IS_ERR(debugfs_create_file(#name, mode, parent, priv, \ + &file_ops_ ##fopname))) \ + pr_debug("Unable to initialize debugfs:%s\n", #name); \ + } while (0) + +#define rtw89_debugfs_add_w(name) \ + rtw89_debugfs_add(name, S_IFREG | 0222, single_w, debugfs_topdir) +#define rtw89_debugfs_add_rw(name) \ + rtw89_debugfs_add(name, S_IFREG | 0666, common_rw, debugfs_topdir) +#define rtw89_debugfs_add_r(name) \ + rtw89_debugfs_add(name, S_IFREG | 0444, single_r, debugfs_topdir) + +static +void rtw89_debugfs_add_sec0(struct rtw89_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw89_debugfs_add_rw(read_reg); + rtw89_debugfs_add_w(write_reg); + rtw89_debugfs_add_rw(read_rf); + rtw89_debugfs_add_w(write_rf); + rtw89_debugfs_add_r(rf_reg_dump); + rtw89_debugfs_add_r(txpwr_table); + rtw89_debugfs_add_rw(mac_reg_dump); + rtw89_debugfs_add_rw(mac_mem_dump); + rtw89_debugfs_add_rw(mac_dbg_port_dump); +} + +static +void rtw89_debugfs_add_sec1(struct rtw89_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw89_debugfs_add_w(send_h2c); + rtw89_debugfs_add_rw(early_h2c); + rtw89_debugfs_add_rw(fw_crash); + rtw89_debugfs_add_r(ser_counters); + rtw89_debugfs_add_r(btc_info); + rtw89_debugfs_add_w(btc_manual); + rtw89_debugfs_add_w(fw_log_manual); + rtw89_debugfs_add_r(phy_info); + rtw89_debugfs_add_rw(bb_info); + rtw89_debugfs_add_r(stations); +} + +static +void rtw89_debugfs_add_sec2(struct rtw89_dev *rtwdev, struct dentry *debugfs_topdir) +{ + rtw89_debugfs_add_rw(disable_dm); + rtw89_debugfs_add_rw(static_pd_th); + rtw89_debugfs_add_rw(mlo_mode); + rtw89_debugfs_add_r(beacon_info); + rtw89_debugfs_add_r(diag_mac); + rtw89_debugfs_add_r(diag_bb); + rtw89_debugfs_add_rw(diag_rf); + rtw89_debugfs_add_rw(monitor_opts); +} + +void rtw89_debugfs_init(struct rtw89_dev *rtwdev) +{ + struct dentry *debugfs_topdir; + + rtwdev->debugfs = kmemdup(&rtw89_debugfs_templ, + sizeof(rtw89_debugfs_templ), GFP_KERNEL); + if (!rtwdev->debugfs) + return; + + debugfs_topdir = debugfs_create_dir("rtw89", + rtwdev->hw->wiphy->debugfsdir); + + rtw89_debugfs_add_sec0(rtwdev, debugfs_topdir); + rtw89_debugfs_add_sec1(rtwdev, debugfs_topdir); + rtw89_debugfs_add_sec2(rtwdev, debugfs_topdir); +} + +void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev) +{ + kfree(rtwdev->debugfs); +} +#endif + +#ifdef CONFIG_RTW89_DEBUGMSG +void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask, + const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + if (rtw89_debug_mask & mask) + dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); + + va_end(args); +} +EXPORT_SYMBOL(rtw89_debug); +#endif diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h new file mode 100644 index 000000000..f53d8acbd --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/debug.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_DEBUG_H__ +#define __RTW89_DEBUG_H__ + +#include "core.h" + +enum rtw89_debug_mask { + RTW89_DBG_TXRX = BIT(0), + RTW89_DBG_RFK = BIT(1), + RTW89_DBG_RFK_TRACK = BIT(2), + RTW89_DBG_CFO = BIT(3), + RTW89_DBG_TSSI = BIT(4), + RTW89_DBG_TXPWR = BIT(5), + RTW89_DBG_HCI = BIT(6), + RTW89_DBG_RA = BIT(7), + RTW89_DBG_REGD = BIT(8), + RTW89_DBG_PHY_TRACK = BIT(9), + RTW89_DBG_DIG = BIT(10), + RTW89_DBG_SER = BIT(11), + RTW89_DBG_FW = BIT(12), + RTW89_DBG_BTC = BIT(13), + RTW89_DBG_BF = BIT(14), + RTW89_DBG_HW_SCAN = BIT(15), + RTW89_DBG_SAR = BIT(16), + RTW89_DBG_STATE = BIT(17), + RTW89_DBG_WOW = BIT(18), + RTW89_DBG_UL_TB = BIT(19), + RTW89_DBG_CHAN = BIT(20), + RTW89_DBG_ACPI = BIT(21), + RTW89_DBG_EDCCA = BIT(22), + RTW89_DBG_PS = BIT(23), + RTW89_DBG_LED = BIT(24), + + RTW89_DBG_UNEXP = BIT(31), +}; + +enum rtw89_debug_mac_reg_sel { + RTW89_DBG_SEL_MAC_00, + RTW89_DBG_SEL_MAC_30, + RTW89_DBG_SEL_MAC_40, + RTW89_DBG_SEL_MAC_80, + RTW89_DBG_SEL_MAC_C0, + RTW89_DBG_SEL_MAC_E0, + RTW89_DBG_SEL_BB, + RTW89_DBG_SEL_IQK, + RTW89_DBG_SEL_RFC, +}; + +#ifdef CONFIG_RTW89_DEBUGFS +void rtw89_debugfs_init(struct rtw89_dev *rtwdev); +void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev); +#else +static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {} +static inline void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev) {} +#endif + +#define rtw89_info(rtwdev, a...) dev_info((rtwdev)->dev, ##a) +#define rtw89_info_once(rtwdev, a...) dev_info_once((rtwdev)->dev, ##a) +#define rtw89_warn(rtwdev, a...) dev_warn((rtwdev)->dev, ##a) +#define rtw89_err(rtwdev, a...) dev_err((rtwdev)->dev, ##a) + +#ifdef CONFIG_RTW89_DEBUGMSG +extern unsigned int rtw89_debug_mask; + +__printf(3, 4) +void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask, + const char *fmt, ...); +static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, + enum rtw89_debug_mask mask, + const char *prefix_str, + const void *buf, size_t len) +{ + if (!(rtw89_debug_mask & mask)) + return; + + print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len); +} + +static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev, + enum rtw89_debug_mask mask) +{ + return !!(rtw89_debug_mask & mask); +} +#else +static inline void rtw89_debug(struct rtw89_dev *rtwdev, + enum rtw89_debug_mask mask, + const char *fmt, ...) {} +static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, + enum rtw89_debug_mask mask, + const char *prefix_str, + const void *buf, size_t len) {} +static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev, + enum rtw89_debug_mask mask) +{ + return false; +} +#endif + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c new file mode 100644 index 000000000..89d4b1b86 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/efuse.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "debug.h" +#include "efuse.h" +#include "mac.h" +#include "reg.h" + +#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0) +#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4) +#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0) +#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6) + +#define EFUSE_EXTERNALPN_ADDR_AX 0x5EC +#define EFUSE_CUSTOMER_ADDR_AX 0x5ED +#define EFUSE_SERIALNUM_ADDR_AX 0x5ED + +#define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0) +#define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0) +#define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4) + +#define OTP_KEY_INFO_NUM 2 + +static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0}; +static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1}; +static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1}; + +enum rtw89_efuse_bank { + RTW89_EFUSE_BANK_WIFI, + RTW89_EFUSE_BANK_BT, +}; + +enum rtw89_efuse_mss_dev_type { + MSS_DEV_TYPE_FWSEC_DEF = 0xF, + MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC, + MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA, + MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9, + MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6, +}; + +static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev, + enum rtw89_efuse_bank bank) +{ + u8 val; + + if (rtwdev->chip->chip_id != RTL8852A) + return 0; + + val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, + B_AX_EF_CELL_SEL_MASK); + if (bank == val) + return 0; + + rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK, + bank); + + val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, + B_AX_EF_CELL_SEL_MASK); + if (bank == val) + return 0; + + return -EBUSY; +} + +static void rtw89_enable_otp_burst_mode(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_write32_set(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST); + else + rtw89_write32_clr(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST); +} + +static void rtw89_enable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + + if (chip_id == RTL8852A) + return; + + rtw89_write8_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + + fsleep(1000); + + rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + if (chip_id == RTL8852B && hal->cv == CHIP_CAV) + rtw89_enable_otp_burst_mode(rtwdev, true); +} + +static void rtw89_disable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + + if (chip_id == RTL8852A) + return; + + if (chip_id == RTL8852B && hal->cv == CHIP_CAV) + rtw89_enable_otp_burst_mode(rtwdev, false); + + rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + + fsleep(1000); + + rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + rtw89_write8_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); +} + +static int rtw89_dump_physical_efuse_map_ddv(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size) +{ + u32 efuse_ctl; + u32 addr; + int ret; + + rtw89_enable_efuse_pwr_cut_ddv(rtwdev); + + for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { + efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK); + rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY); + + ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, + efuse_ctl & B_AX_EF_RDY, 1, 1000000, + true, rtwdev, R_AX_EFUSE_CTRL); + if (ret) + return -EBUSY; + + *map++ = (u8)(efuse_ctl & 0xff); + } + + rtw89_disable_efuse_pwr_cut_ddv(rtwdev); + + return 0; +} + +int rtw89_cnv_efuse_state_ax(struct rtw89_dev *rtwdev, bool idle) +{ + return 0; +} + +static int rtw89_dump_physical_efuse_map_dav(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size) +{ + u32 addr; + u8 val8; + int err; + int ret; + + for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR, + addr & 0xff, XTAL_SI_LOW_ADDR_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8, + XTAL_SI_HIGH_ADDR_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0, + XTAL_SI_MODE_SEL_MASK); + if (ret) + return ret; + + ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err, + !err && (val8 & XTAL_SI_RDY), + 1, 10000, false, + rtwdev, XTAL_SI_CTRL, &val8); + if (ret) { + rtw89_warn(rtwdev, "failed to read dav efuse\n"); + return ret; + } + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8); + if (ret) + return ret; + *map++ = val8; + } + + return 0; +} + +static int __rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size, bool dav) +{ + int ret; + + if (!map || dump_size == 0) + return 0; + + rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI); + + if (dav) { + ret = rtw89_dump_physical_efuse_map_dav(rtwdev, map, dump_addr, dump_size); + if (ret) + return ret; + } else { + ret = rtw89_dump_physical_efuse_map_ddv(rtwdev, map, dump_addr, dump_size); + if (ret) + return ret; + } + + return 0; +} + +static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size, bool dav) +{ + int retry; + int ret; + + for (retry = 0; retry < 5; retry++) { + ret = __rtw89_dump_physical_efuse_map(rtwdev, map, dump_addr, + dump_size, dav); + if (!ret) + return 0; + + rtw89_warn(rtwdev, "efuse dump (dav=%d) failed, retrying (%d)\n", + dav, retry); + } + + return ret; +} + +#define invalid_efuse_header(hdr1, hdr2) \ + ((hdr1) == 0xff || (hdr2) == 0xff) +#define invalid_efuse_content(word_en, i) \ + (((word_en) & BIT(i)) != 0x0) +#define get_efuse_blk_idx(hdr1, hdr2) \ + ((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4)) +#define block_idx_to_logical_idx(blk_idx, i) \ + (((blk_idx) << 3) + ((i) << 1)) +static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map, + u8 *log_map) +{ + u32 physical_size = rtwdev->chip->physical_efuse_size; + u32 logical_size = rtwdev->chip->logical_efuse_size; + u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size; + u32 phy_idx = sec_ctrl_size; + u32 log_idx; + u8 hdr1, hdr2; + u8 blk_idx; + u8 word_en; + int i; + + if (!phy_map) + return 0; + + while (phy_idx < physical_size - sec_ctrl_size) { + hdr1 = phy_map[phy_idx]; + hdr2 = phy_map[phy_idx + 1]; + if (invalid_efuse_header(hdr1, hdr2)) + break; + + blk_idx = get_efuse_blk_idx(hdr1, hdr2); + word_en = hdr2 & 0xf; + phy_idx += 2; + + for (i = 0; i < 4; i++) { + if (invalid_efuse_content(word_en, i)) + continue; + + log_idx = block_idx_to_logical_idx(blk_idx, i); + if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 || + log_idx + 1 > logical_size) + return -EINVAL; + + log_map[log_idx] = phy_map[phy_idx]; + log_map[log_idx + 1] = phy_map[phy_idx + 1]; + phy_idx += 2; + } + } + return 0; +} + +int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev) +{ + u32 phy_size = rtwdev->chip->physical_efuse_size; + u32 log_size = rtwdev->chip->logical_efuse_size; + u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size; + u32 dav_log_size = rtwdev->chip->dav_log_efuse_size; + u32 full_log_size = log_size + dav_log_size; + u8 *phy_map = NULL; + u8 *log_map = NULL; + u8 *dav_phy_map = NULL; + u8 *dav_log_map = NULL; + int ret; + + if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS) + rtwdev->efuse.valid = true; + else + rtw89_warn(rtwdev, "failed to check efuse autoload\n"); + + phy_map = kmalloc(phy_size, GFP_KERNEL); + log_map = kmalloc(full_log_size, GFP_KERNEL); + if (dav_phy_size && dav_log_size) { + dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL); + dav_log_map = log_map + log_size; + } + + if (!phy_map || !log_map || (dav_phy_size && !dav_phy_map)) { + ret = -ENOMEM; + goto out_free; + } + + ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); + goto out_free; + } + ret = rtw89_dump_physical_efuse_map(rtwdev, dav_phy_map, 0, dav_phy_size, true); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n"); + goto out_free; + } + + memset(log_map, 0xff, full_log_size); + ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse logical map\n"); + goto out_free; + } + ret = rtw89_dump_logical_efuse_map(rtwdev, dav_phy_map, dav_log_map); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse dav logical map\n"); + goto out_free; + } + + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, full_log_size); + + ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, RTW89_EFUSE_BLOCK_IGNORE); + if (ret) { + rtw89_warn(rtwdev, "failed to read efuse map\n"); + goto out_free; + } + +out_free: + kfree(dav_phy_map); + kfree(log_map); + kfree(phy_map); + + return ret; +} + +int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev) +{ + u32 phycap_addr = rtwdev->chip->phycap_addr; + u32 phycap_size = rtwdev->chip->phycap_size; + u8 *phycap_map = NULL; + int ret = 0; + + if (!phycap_size) + return 0; + + phycap_map = kmalloc(phycap_size, GFP_KERNEL); + if (!phycap_map) + return -ENOMEM; + + ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map, + phycap_addr, phycap_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump phycap map\n"); + goto out_free; + } + + ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); + if (ret) { + rtw89_warn(rtwdev, "failed to read phycap map\n"); + goto out_free; + } + +out_free: + kfree(phycap_map); + + return ret; +} + +int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv) +{ + int ret; + u8 val; + + ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false); + if (ret) + return ret; + + *ecv = u8_get_bits(val, EF_CV_MASK); + if (*ecv == EF_CV_INV) + return -ENOENT; + + return 0; +} +EXPORT_SYMBOL(rtw89_read_efuse_ver); + +static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type) +{ + switch (mss_dev_type) { + case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX: + mss_dev_type = 0x0; + break; + case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB: + mss_dev_type = 0x1; + break; + case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB: + mss_dev_type = 0x2; + break; + case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX: + mss_dev_type = 0x3; + break; + case MSS_DEV_TYPE_FWSEC_DEF: + mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF; + break; + default: + rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type); + mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV; + break; + } + + return mss_dev_type; +} + +int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u8 mss_dev_type; + + if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) { + mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB; + sec->mss_cust_idx = 0; + sec->mss_key_num = 0; + + goto mss_dev_type; + } + + mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK); + sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) | + u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4); + sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK); + +mss_dev_type: + sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type); + if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) { + rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type); + return -ENOENT; + } + + sec->can_mss_v1 = true; + + return 0; +} + +static +int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u8 externalPN; + u8 serialNum; + u8 customer; + u8 i; + + externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK); + customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK); + serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK); + + for (i = 0; i < OTP_KEY_INFO_NUM; i++) { + if (externalPN == otp_key_info_externalPN[i] && + customer == otp_key_info_customer[i] && + serialNum == otp_key_info_serialNum[i]) { + sec->mss_idx = i; + sec->can_mss_v0 = true; + return 0; + } + } + + return -ENOENT; +} + +int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX; + u32 sec_size = 2; + u8 sec_map[2]; + u8 b1, b2; + int ret; + + ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map, + sec_addr, sec_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump secsel map\n"); + return ret; + } + + b1 = sec_map[0]; + b2 = sec_map[1]; + + if (b1 == 0xFF && b2 == 0xFF) + return 0; + + rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2); + rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2); + if (!sec->can_mss_v1 && !sec->can_mss_v0) + goto out; + + sec->secure_boot = true; + +out: + rtw89_debug(rtwdev, RTW89_DBG_FW, + "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n", + sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1, + sec->mss_dev_type, sec->mss_cust_idx, + sec->mss_key_num, sec->mss_idx); + + return 0; +} diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h new file mode 100644 index 000000000..4eb629273 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/efuse.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_EFUSE_H__ +#define __RTW89_EFUSE_H__ + +#include "core.h" + +#define RTW89_EFUSE_BLOCK_ID_MASK GENMASK(31, 16) +#define RTW89_EFUSE_BLOCK_SIZE_MASK GENMASK(15, 0) +#define RTW89_EFUSE_MAX_BLOCK_SIZE 0x10000 + +#define EF_FV_OFSET 0x5EA +#define EF_FV_OFSET_BE_V1 0x17CA +#define EF_CV_MASK GENMASK(7, 4) +#define EF_CV_INV 15 + +#define EFUSE_THERMAL_K_OFFSET_BE 0x17CC +#define EFUSE_THERMAL_K_VALID_BE BIT(9) +#define EFUSE_THERMAL_K_SIGN_BE BIT(8) +#define EFUSE_THERMAL_K_VAL_BE GENMASK(7, 0) + +struct rtw89_efuse_block_cfg { + u32 offset; + u32 size; +}; + +int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev); +int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev); +int rtw89_cnv_efuse_state_ax(struct rtw89_dev *rtwdev, bool idle); +int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev); +int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev); +int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle); +int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv); +int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2); +int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev); +int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev); +int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev); +int rtw89_efuse_read_thermal_k_be(struct rtw89_dev *rtwdev); +int rtw89_efuse_read_pwr_data_be(struct rtw89_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c new file mode 100644 index 000000000..825274bd7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c @@ -0,0 +1,655 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include "debug.h" +#include "efuse.h" +#include "mac.h" +#include "reg.h" + +#define EFUSE_EXTERNALPN_ADDR_BE 0x1580 +#define EFUSE_SERIALNUM_ADDR_BE 0x1581 +#define EFUSE_SB_CRYP_SEL_ADDR 0x1582 +#define EFUSE_SB_CRYP_SEL_SIZE 2 +#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF +#define SB_SEL_MGN_MAX_SIZE 2 +#define EFUSE_SEC_BE_START 0x1580 +#define EFUSE_SEC_BE_SIZE 4 + +#define EFUSE_VCORE_PWR_BE 0x17D6 +#define EFUSE_VCORE_PWR_BE_VALID BIT(12) +#define EFUSE_VCORE_PWR_BE_VAL GENMASK(11, 0) +#define SWR_DIG_MIN 860 +#define EFUSE_DIG_K_STEP 0xC +#define EFUSE_DSWR_V0_86_BE 0x17DA +#define EFUSE_DSWR_V0_86_BE_VALID BIT(5) +#define EFUSE_DSWR_V0_86_BE_VAL GENMASK(4, 0) + +static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = { + 0x8000100, 0xC000180 +}; + +static void rtw89_enable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + bool aphy_patch = true; + + if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) + aphy_patch = false; + + rtw89_write8_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + + if (aphy_patch) { + rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); + mdelay(1); + rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); + rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); + } + + rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST); +} + +static void rtw89_disable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + bool aphy_patch = true; + + if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) + aphy_patch = false; + + if (aphy_patch) { + rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); + rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); + mdelay(1); + rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); + } + + rtw89_write8_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + rtw89_write32_clr(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST); +} + +static int rtw89_dump_physical_efuse_map_ddv_be(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size) +{ + u32 efuse_ctl; + u32 addr; + u32 data; + int ret; + + if (!IS_ALIGNED(dump_addr, 4) || !IS_ALIGNED(dump_size, 4)) { + rtw89_err(rtwdev, "Efuse addr 0x%x or size 0x%x not aligned\n", + dump_addr, dump_size); + return -EINVAL; + } + + rtw89_enable_efuse_pwr_cut_ddv_be(rtwdev); + + for (addr = dump_addr; addr < dump_addr + dump_size; addr += 4, map += 4) { + efuse_ctl = u32_encode_bits(addr, B_BE_EF_ADDR_MASK); + rtw89_write32(rtwdev, R_BE_EFUSE_CTRL, efuse_ctl & ~B_BE_EF_RDY); + + ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, + efuse_ctl & B_BE_EF_RDY, 1, 1000000, + true, rtwdev, R_BE_EFUSE_CTRL); + if (ret) + return -EBUSY; + + data = rtw89_read32(rtwdev, R_BE_EFUSE_CTRL_1_V1); + *((__le32 *)map) = cpu_to_le32(data); + } + + rtw89_disable_efuse_pwr_cut_ddv_be(rtwdev); + + return 0; +} + +static int rtw89_dump_physical_efuse_map_dav_be(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size) +{ + u32 addr; + u8 val8; + int err; + int ret; + + for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, + FULL_BIT_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR, addr & 0xff, + XTAL_SI_LOW_ADDR_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8, + XTAL_SI_HIGH_ADDR_MASK); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0, + XTAL_SI_MODE_SEL_MASK); + if (ret) + return ret; + + ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err, + !err && (val8 & XTAL_SI_RDY), + 1, 10000, false, + rtwdev, XTAL_SI_CTRL, &val8); + if (ret) { + rtw89_warn(rtwdev, "failed to read dav efuse\n"); + return ret; + } + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8); + if (ret) + return ret; + *map++ = val8; + } + + return 0; +} + +int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle) +{ + u32 val; + int ret = 0; + + if (idle) { + rtw89_write32_set(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN); + } else { + rtw89_write32_clr(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val, + val == MAC_AX_SYS_ACT, 50, 5000, + false, rtwdev, R_BE_IC_PWR_STATE, + B_BE_WHOLE_SYS_PWR_STE_MASK); + if (ret) + rtw89_warn(rtwdev, "failed to convert efuse state\n"); + } + + return ret; +} + +static int rtw89_dump_physical_efuse_map_be(struct rtw89_dev *rtwdev, u8 *map, + u32 dump_addr, u32 dump_size, bool dav) +{ + int ret; + + if (!map || dump_size == 0) + return 0; + + rtw89_cnv_efuse_state_be(rtwdev, false); + + if (dav) { + ret = rtw89_dump_physical_efuse_map_dav_be(rtwdev, map, + dump_addr, dump_size); + if (ret) + return ret; + + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map dav: ", map, dump_size); + } else { + ret = rtw89_dump_physical_efuse_map_ddv_be(rtwdev, map, + dump_addr, dump_size); + if (ret) + return ret; + + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map ddv: ", map, dump_size); + } + + rtw89_cnv_efuse_state_be(rtwdev, true); + + return 0; +} + +#define EFUSE_HDR_CONST_MASK GENMASK(23, 20) +#define EFUSE_HDR_PAGE_MASK GENMASK(19, 17) +#define EFUSE_HDR_OFFSET_MASK GENMASK(16, 4) +#define EFUSE_HDR_OFFSET_DAV_MASK GENMASK(11, 4) +#define EFUSE_HDR_WORD_EN_MASK GENMASK(3, 0) + +#define invalid_efuse_header_be(hdr1, hdr2, hdr3) \ + ((hdr1) == 0xff || (hdr2) == 0xff || (hdr3) == 0xff) +#define invalid_efuse_content_be(word_en, i) \ + (((word_en) & BIT(i)) != 0x0) +#define get_efuse_blk_idx_be(hdr1, hdr2, hdr3) \ + (((hdr1) << 16) | ((hdr2) << 8) | (hdr3)) +#define block_idx_to_logical_idx_be(blk_idx, i) \ + (((blk_idx) << 3) + ((i) << 1)) + +#define invalid_efuse_header_dav_be(hdr1, hdr2) \ + ((hdr1) == 0xff || (hdr2) == 0xff) +#define get_efuse_blk_idx_dav_be(hdr1, hdr2) \ + (((hdr1) << 8) | (hdr2)) + +static int rtw89_eeprom_parser_be(struct rtw89_dev *rtwdev, + const u8 *phy_map, u32 phy_size, u8 *log_map, + const struct rtw89_efuse_block_cfg *efuse_block) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + enum rtw89_efuse_block blk_page, page; + u32 size = efuse_block->size; + u32 phy_idx, log_idx; + u32 hdr, page_offset; + u8 hdr1, hdr2, hdr3; + u8 i, val0, val1; + u32 min, max; + u16 blk_idx; + u8 word_en; + + page = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_ID_MASK); + page_offset = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_SIZE_MASK); + + min = ALIGN_DOWN(page_offset, 2); + max = ALIGN(page_offset + size, 2); + + memset(log_map, 0xff, size); + + phy_idx = chip->sec_ctrl_efuse_size; + + do { + if (page == RTW89_EFUSE_BLOCK_ADIE) { + hdr1 = phy_map[phy_idx]; + hdr2 = phy_map[phy_idx + 1]; + if (invalid_efuse_header_dav_be(hdr1, hdr2)) + break; + + phy_idx += 2; + + hdr = get_efuse_blk_idx_dav_be(hdr1, hdr2); + + blk_page = RTW89_EFUSE_BLOCK_ADIE; + blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_DAV_MASK); + word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK); + } else { + hdr1 = phy_map[phy_idx]; + hdr2 = phy_map[phy_idx + 1]; + hdr3 = phy_map[phy_idx + 2]; + if (invalid_efuse_header_be(hdr1, hdr2, hdr3)) + break; + + phy_idx += 3; + + hdr = get_efuse_blk_idx_be(hdr1, hdr2, hdr3); + + blk_page = u32_get_bits(hdr, EFUSE_HDR_PAGE_MASK); + blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_MASK); + word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK); + } + + if (blk_idx >= RTW89_EFUSE_MAX_BLOCK_SIZE >> 3) { + rtw89_err(rtwdev, "[ERR]efuse idx:0x%X\n", phy_idx - 3); + rtw89_err(rtwdev, "[ERR]read hdr:0x%X\n", hdr); + return -EINVAL; + } + + for (i = 0; i < 4; i++) { + if (invalid_efuse_content_be(word_en, i)) + continue; + + if (phy_idx >= phy_size - 1) + return -EINVAL; + + log_idx = block_idx_to_logical_idx_be(blk_idx, i); + + if (blk_page == page && log_idx >= min && log_idx < max) { + val0 = phy_map[phy_idx]; + val1 = phy_map[phy_idx + 1]; + + if (log_idx == min && page_offset > min) { + log_map[log_idx - page_offset + 1] = val1; + } else if (log_idx + 2 == max && + page_offset + size < max) { + log_map[log_idx - page_offset] = val0; + } else { + log_map[log_idx - page_offset] = val0; + log_map[log_idx - page_offset + 1] = val1; + } + } + phy_idx += 2; + } + } while (phy_idx < phy_size); + + return 0; +} + +static int rtw89_parse_logical_efuse_block_be(struct rtw89_dev *rtwdev, + const u8 *phy_map, u32 phy_size, + enum rtw89_efuse_block block) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_efuse_block_cfg *efuse_block; + u8 *log_map; + int ret; + + efuse_block = &chip->efuse_blocks[block]; + + log_map = kmalloc(efuse_block->size, GFP_KERNEL); + if (!log_map) + return -ENOMEM; + + ret = rtw89_eeprom_parser_be(rtwdev, phy_map, phy_size, log_map, efuse_block); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse logical block %d\n", block); + goto out_free; + } + + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, efuse_block->size); + + ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, block); + if (ret) { + rtw89_warn(rtwdev, "failed to read efuse map\n"); + goto out_free; + } + +out_free: + kfree(log_map); + + return ret; +} + +int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev) +{ + u32 phy_size = rtwdev->chip->physical_efuse_size; + u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size; + enum rtw89_efuse_block block; + u8 *phy_map = NULL; + u8 *dav_phy_map = NULL; + int ret; + + if (rtw89_read16(rtwdev, R_BE_SYS_WL_EFUSE_CTRL) & B_BE_AUTOLOAD_SUS) + rtwdev->efuse.valid = true; + else + rtw89_warn(rtwdev, "failed to check efuse autoload\n"); + + phy_map = kmalloc(phy_size, GFP_KERNEL); + if (dav_phy_size) + dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL); + + if (!phy_map || (dav_phy_size && !dav_phy_map)) { + ret = -ENOMEM; + goto out_free; + } + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, phy_map, 0, phy_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); + goto out_free; + } + ret = rtw89_dump_physical_efuse_map_be(rtwdev, dav_phy_map, 0, dav_phy_size, true); + if (ret) { + rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n"); + goto out_free; + } + + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + block = RTW89_EFUSE_BLOCK_HCI_DIG_USB; + else + block = RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO; + + ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, block); + if (ret) { + rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n", + RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO); + goto out_free; + } + + ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, + RTW89_EFUSE_BLOCK_RF); + if (ret) { + rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n", + RTW89_EFUSE_BLOCK_RF); + goto out_free; + } + + if (rtwdev->chip->chip_id != RTL8922D) + goto out_free; + + ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, + RTW89_EFUSE_BLOCK_SYS); + if (ret) { + rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n", + RTW89_EFUSE_BLOCK_SYS); + goto out_free; + } + +out_free: + kfree(dav_phy_map); + kfree(phy_map); + + return ret; +} + +int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev) +{ + u32 phycap_addr = rtwdev->chip->phycap_addr; + u32 phycap_size = rtwdev->chip->phycap_size; + u8 *phycap_map = NULL; + int ret = 0; + + if (!phycap_size) + return 0; + + phycap_map = kmalloc(phycap_size, GFP_KERNEL); + if (!phycap_map) + return -ENOMEM; + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, phycap_map, + phycap_addr, phycap_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump phycap map\n"); + goto out_free; + } + + ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); + if (ret) { + rtw89_warn(rtwdev, "failed to read phycap map\n"); + goto out_free; + } + +out_free: + kfree(phycap_map); + + return ret; +} + +static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel) +{ + u8 low_bit, high_bit, cnt_zero = 0; + u8 idx, sel_form_v, sel_idx_v; + u16 sb_cryp_sel_v = 0x0; + + sel_form_v = u16_get_bits(sb_cryp_sel, MASKBYTE0); + sel_idx_v = u16_get_bits(sb_cryp_sel, MASKBYTE1); + + for (idx = 0; idx < 4; idx++) { + low_bit = !!(sel_form_v & BIT(idx)); + high_bit = !!(sel_form_v & BIT(7 - idx)); + if (low_bit != high_bit) + return U16_MAX; + if (low_bit) + continue; + + cnt_zero++; + if (cnt_zero == 1) + sb_cryp_sel_v = idx * 16; + else if (cnt_zero > 1) + return U16_MAX; + } + + low_bit = u8_get_bits(sel_idx_v, 0x0F); + high_bit = u8_get_bits(sel_idx_v, 0xF0); + + if ((low_bit ^ high_bit) != 0xF) + return U16_MAX; + + return sb_cryp_sel_v + low_bit; +} + +int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u32 sec_addr = EFUSE_SEC_BE_START; + u32 sec_size = EFUSE_SEC_BE_SIZE; + u16 sb_cryp_sel, sb_cryp_sel_idx; + u8 sec_map[EFUSE_SEC_BE_SIZE]; + u8 b1, b2; + int ret; + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, sec_map, + sec_addr, sec_size, false); + if (ret) { + rtw89_warn(rtwdev, "failed to dump secsel map\n"); + return ret; + } + + sb_cryp_sel = sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr] | + sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr + 1] << 8; + if (sb_cryp_sel == EFUSE_SB_CRYP_SEL_DEFAULT) + goto out; + + sb_cryp_sel_idx = get_sb_cryp_sel_idx(sb_cryp_sel); + if (sb_cryp_sel_idx >= SB_SEL_MGN_MAX_SIZE) { + rtw89_warn(rtwdev, "invalid SB cryp sel idx %d\n", sb_cryp_sel_idx); + goto out; + } + + sec->sb_sel_mgn = sb_sel_mgn[sb_cryp_sel_idx]; + + b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr]; + b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr]; + + ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2); + if (ret) + goto out; + + sec->secure_boot = true; + +out: + rtw89_debug(rtwdev, RTW89_DBG_FW, + "MSS secure_boot=%d dev_type=%d cust_idx=%d key_num=%d\n", + sec->secure_boot, sec->mss_dev_type, sec->mss_cust_idx, + sec->mss_key_num); + + return 0; +} + +int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev) +{ + u32 dump_addr; + u8 buff[4]; /* efuse access must 4 bytes align */ + int ret; + u8 ecv; + u8 val; + + dump_addr = ALIGN_DOWN(EF_FV_OFSET_BE_V1, 4); + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false); + if (ret) + return ret; + + val = buff[EF_FV_OFSET_BE_V1 & 0x3]; + + ecv = u8_get_bits(val, EF_CV_MASK); + if (ecv == EF_CV_INV) + return -ENOENT; + + rtwdev->hal.cv = ecv; + + return 0; +} + +int rtw89_efuse_read_thermal_k_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 dump_addr = EFUSE_THERMAL_K_OFFSET_BE; + u8 buff[4]; /* efuse access must be multiple of 4 bytes in size */ + bool no_k; + u16 val16; + int ret; + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false); + if (ret) + return ret; + + val16 = buff[0] | buff[1] << 8; + + no_k = !!u16_get_bits(val16, EFUSE_THERMAL_K_VALID_BE); + if (no_k) { + info->thermal_k = 0; + return -ENOENT; + } + + info->thermal_k = u16_get_bits(val16, EFUSE_THERMAL_K_VAL_BE); + + if (u16_get_bits(val16, EFUSE_THERMAL_K_SIGN_BE)) + info->thermal_k *= -1; + + return 0; +} + +static int rtw89_efuse_read_pwr_data_vcore_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + u32 dump_addr; + u8 buff[4]; /* efuse access must 4 bytes align */ + u16 val16; + int ret; + + dump_addr = ALIGN_DOWN(EFUSE_VCORE_PWR_BE, 4); + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false); + if (ret) + return ret; + + val16 = buff[EFUSE_VCORE_PWR_BE - dump_addr] | + buff[EFUSE_VCORE_PWR_BE - dump_addr + 1] << 8; + + if (val16 & EFUSE_VCORE_PWR_BE_VALID) + return 0; + + efuse->vcore_valid = true; + efuse->vcore_vmax_reduce = + (u16_get_bits(val16, EFUSE_VCORE_PWR_BE_VAL) - SWR_DIG_MIN) / + EFUSE_DIG_K_STEP; + + return 0; +} + +static int rtw89_efuse_read_pwr_data_dswr_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + u32 dump_addr; + u8 buff[4]; /* efuse access must 4 bytes align */ + u8 val8; + int ret; + + dump_addr = ALIGN_DOWN(EFUSE_DSWR_V0_86_BE, 4); + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false); + if (ret) + return ret; + + val8 = buff[EFUSE_DSWR_V0_86_BE - dump_addr]; + + if (val8 & EFUSE_DSWR_V0_86_BE_VALID) + return 0; + + efuse->dswr_valid = true; + efuse->dswr_vmin = u8_get_bits(val8, EFUSE_DSWR_V0_86_BE_VAL); + + return 0; +} + +int rtw89_efuse_read_pwr_data_be(struct rtw89_dev *rtwdev) +{ + int ret; + + if (rtwdev->chip->chip_id != RTL8922D) + return 0; + + ret = rtw89_efuse_read_pwr_data_vcore_be(rtwdev); + if (ret) + return ret; + + return rtw89_efuse_read_pwr_data_dswr_be(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c new file mode 100644 index 000000000..0099c5c03 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -0,0 +1,12910 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include +#include "cam.h" +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "util.h" +#include "wow.h" + +static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev); + +struct rtw89_eapol_2_of_2 { + u8 gtkbody[14]; + u8 key_des_ver; + u8 rsvd[92]; +} __packed; + +struct rtw89_sa_query { + u8 category; + u8 action; +} __packed; + +struct rtw89_arp_rsp { + u8 llc_hdr[sizeof(rfc1042_header)]; + __be16 llc_type; + struct arphdr arp_hdr; + u8 sender_hw[ETH_ALEN]; + __be32 sender_ip; + u8 target_hw[ETH_ALEN]; + __be32 target_ip; +} __packed; + +static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C}; + +const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = { + .ver = 0x00, + .list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + }, +}; +EXPORT_SYMBOL(rtw89_fw_blacklist_default); + +union rtw89_fw_element_arg { + size_t offset; + enum rtw89_rf_path rf_path; + enum rtw89_fw_type fw_type; +}; + +struct rtw89_fw_element_handler { + int (*fn)(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg); + const union rtw89_fw_element_arg arg; + const char *name; +}; + +static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, + struct sk_buff *skb); +static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, + struct rtw89_wait_info *wait, unsigned int cond); +static int __parse_security_section(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_section_info *section_info, + const void *content, + u32 *mssc_len); + +static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, + bool header) +{ + struct sk_buff *skb; + u32 header_len = 0; + u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; + + if (header) + header_len = H2C_HEADER_LEN; + + skb = dev_alloc_skb(len + header_len + h2c_desc_size); + if (!skb) + return NULL; + skb_reserve(skb, header_len + h2c_desc_size); + memset(skb->data, 0, len); + + return skb; +} + +struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) +{ + return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); +} + +struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) +{ + return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); +} + +int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u8 val; + int ret; + + ret = read_poll_timeout_atomic(mac->fwdl_get_status, val, + val == RTW89_FWDL_WCPU_FW_INIT_RDY, + 1, FWDL_WAIT_CNT, false, rtwdev, type); + if (ret) { + switch (val) { + case RTW89_FWDL_CHECKSUM_FAIL: + rtw89_err(rtwdev, "fw checksum fail\n"); + return -EINVAL; + + case RTW89_FWDL_SECURITY_FAIL: + rtw89_err(rtwdev, "fw security fail\n"); + return -EINVAL; + + case RTW89_FWDL_CV_NOT_MATCH: + rtw89_err(rtwdev, "fw cv not match\n"); + return -EINVAL; + + default: + rtw89_err(rtwdev, "fw unexpected status %d\n", val); + return -EBUSY; + } + } + + set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); + + return 0; +} + +static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + struct rtw89_fw_bin_info *info) +{ + const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_hdr_section_info *section_info; + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + const struct rtw89_fw_dynhdr_hdr *fwdynhdr; + const struct rtw89_fw_hdr_section *section; + const u8 *fw_end = fw + len; + const u8 *bin; + u32 base_hdr_len; + u32 mssc_len; + int ret; + u32 i; + + if (!info) + return -EINVAL; + + info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM); + base_hdr_len = struct_size(fw_hdr, sections, info->section_num); + info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); + info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE); + + if (chip->chip_gen == RTW89_CHIP_AX) + info->part_size = FWDL_SECTION_PER_PKT_LEN; + else + info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_W7_PART_SIZE); + + if (info->dynamic_hdr_en) { + info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); + info->dynamic_hdr_len = info->hdr_len - base_hdr_len; + fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); + if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { + rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); + return -EINVAL; + } + } else { + info->hdr_len = base_hdr_len; + info->dynamic_hdr_len = 0; + } + + bin = fw + info->hdr_len; + + /* jump to section header */ + section_info = info->section_info; + for (i = 0; i < info->section_num; i++) { + section = &fw_hdr->sections[i]; + section_info->type = + le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); + section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); + + if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) + section_info->len += FWDL_SECTION_CHKSUM_LEN; + section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); + section_info->dladdr = + le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; + section_info->addr = bin; + + if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { + section_info->mssc = + le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); + + ret = __parse_security_section(rtwdev, info, section_info, + bin, &mssc_len); + if (ret) + return ret; + + if (sec->secure_boot && chip->chip_id == RTL8852B) + section_info->len_override = 960; + } else { + section_info->mssc = 0; + mssc_len = 0; + } + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", + i, section_info->type, section_info->len, + section_info->mssc, mssc_len, bin - fw); + rtw89_debug(rtwdev, RTW89_DBG_FW, + " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", + section_info->ignore, section_info->key_addr, + section_info->key_addr ? + section_info->key_addr - section_info->addr : 0, + section_info->key_len, section_info->key_idx); + + bin += section_info->len + mssc_len; + section_info++; + } + + if (fw_end != bin) { + rtw89_err(rtwdev, "[ERR]fw bin size\n"); + return -EINVAL; + } + + return 0; +} + +static int __get_mssc_key_idx(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mss_pool_hdr *mss_hdr, + u32 rmp_tbl_size, u32 *key_idx) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u32 sel_byte_idx; + u32 mss_sel_idx; + u8 sel_bit_idx; + int i; + + if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF) { + if (!mss_hdr->defen) + return -ENOENT; + + mss_sel_idx = sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + + sec->mss_key_num; + } else { + if (mss_hdr->defen) + mss_sel_idx = FWDL_MSS_POOL_DEFKEYSETS_SIZE << 3; + else + mss_sel_idx = 0; + mss_sel_idx += sec->mss_dev_type * le16_to_cpu(mss_hdr->msskey_num_max) * + le16_to_cpu(mss_hdr->msscust_max) + + sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + + sec->mss_key_num; + } + + sel_byte_idx = mss_sel_idx >> 3; + sel_bit_idx = mss_sel_idx & 0x7; + + if (sel_byte_idx >= rmp_tbl_size) + return -EFAULT; + + if (!(mss_hdr->rmp_tbl[sel_byte_idx] & BIT(sel_bit_idx))) + return -ENOENT; + + *key_idx = hweight8(mss_hdr->rmp_tbl[sel_byte_idx] & (BIT(sel_bit_idx) - 1)); + + for (i = 0; i < sel_byte_idx; i++) + *key_idx += hweight8(mss_hdr->rmp_tbl[i]); + + return 0; +} + +static int __parse_formatted_mssc(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_section_info *section_info, + const void *content, + u32 *mssc_len) +{ + const struct rtw89_fw_mss_pool_hdr *mss_hdr = content + section_info->len; + const union rtw89_fw_section_mssc_content *section_content = content; + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u32 rmp_tbl_size; + u32 key_sign_len; + u32 real_key_idx; + u32 sb_sel_ver; + int ret; + + if (memcmp(mss_signature, mss_hdr->signature, sizeof(mss_signature)) != 0) { + rtw89_err(rtwdev, "[ERR] wrong MSS signature\n"); + return -ENOENT; + } + + if (mss_hdr->rmpfmt == MSS_POOL_RMP_TBL_BITMASK) { + rmp_tbl_size = (le16_to_cpu(mss_hdr->msskey_num_max) * + le16_to_cpu(mss_hdr->msscust_max) * + mss_hdr->mssdev_max) >> 3; + if (mss_hdr->defen) + rmp_tbl_size += FWDL_MSS_POOL_DEFKEYSETS_SIZE; + } else { + rtw89_err(rtwdev, "[ERR] MSS Key Pool Remap Table Format Unsupport:%X\n", + mss_hdr->rmpfmt); + return -EINVAL; + } + + if (rmp_tbl_size + sizeof(*mss_hdr) != le32_to_cpu(mss_hdr->key_raw_offset)) { + rtw89_err(rtwdev, "[ERR] MSS Key Pool Format Error:0x%X + 0x%X != 0x%X\n", + rmp_tbl_size, (int)sizeof(*mss_hdr), + le32_to_cpu(mss_hdr->key_raw_offset)); + return -EINVAL; + } + + key_sign_len = le16_to_cpu(section_content->key_sign_len.v) >> 2; + if (!key_sign_len) + key_sign_len = 512; + + if (info->dsp_checksum) + key_sign_len += FWDL_SECURITY_CHKSUM_LEN; + + *mssc_len = sizeof(*mss_hdr) + rmp_tbl_size + + le16_to_cpu(mss_hdr->keypair_num) * key_sign_len; + + if (!sec->secure_boot) + goto out; + + sb_sel_ver = get_unaligned_le32(§ion_content->sb_sel_ver.v); + if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn) + goto ignore; + + ret = __get_mssc_key_idx(rtwdev, mss_hdr, rmp_tbl_size, &real_key_idx); + if (ret) + goto ignore; + + section_info->key_addr = content + section_info->len + + le32_to_cpu(mss_hdr->key_raw_offset) + + key_sign_len * real_key_idx; + section_info->key_len = key_sign_len; + section_info->key_idx = real_key_idx; + +out: + if (info->secure_section_exist) { + section_info->ignore = true; + return 0; + } + + info->secure_section_exist = true; + + return 0; + +ignore: + section_info->ignore = true; + + return 0; +} + +static int __check_secure_blacklist(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_section_info *section_info, + const void *content) +{ + const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist; + const union rtw89_fw_section_mssc_content *section_content = content; + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u8 byte_idx; + u8 bit_mask; + + if (!sec->secure_boot) + return 0; + + if (!info->secure_section_exist || section_info->ignore) + return 0; + + if (!chip_blacklist) { + rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n"); + return -ENOENT; + } + + byte_idx = section_content->blacklist.bit_in_chip_list >> 3; + bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7); + + if (section_content->blacklist.ver > chip_blacklist->ver) { + rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n", + section_content->blacklist.ver, chip_blacklist->ver); + return -EINVAL; + } + + if (chip_blacklist->list[byte_idx] & bit_mask) { + rtw89_warn(rtwdev, "firmware %u in chip blacklist\n", + section_content->blacklist.ver); + return -EPERM; + } + + return 0; +} + +static int __parse_security_section(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_section_info *section_info, + const void *content, + u32 *mssc_len) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + int ret; + + if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) { + ret = __parse_formatted_mssc(rtwdev, info, section_info, + content, mssc_len); + if (ret) + return -EINVAL; + } else { + *mssc_len = section_info->mssc * FWDL_SECURITY_SIGLEN; + if (info->dsp_checksum) + *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN; + + if (sec->secure_boot) { + if (sec->mss_idx >= section_info->mssc) { + rtw89_err(rtwdev, "unexpected MSS %d >= %d\n", + sec->mss_idx, section_info->mssc); + return -EFAULT; + } + section_info->key_addr = content + section_info->len + + sec->mss_idx * FWDL_SECURITY_SIGLEN; + section_info->key_len = FWDL_SECURITY_SIGLEN; + } + + info->secure_section_exist = true; + } + + ret = __check_secure_blacklist(rtwdev, info, section_info, content); + WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n"); + + return 0; +} + +static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + struct rtw89_fw_bin_info *info) +{ + const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_hdr_section_info *section_info; + const struct rtw89_fw_dynhdr_hdr *fwdynhdr; + const struct rtw89_fw_hdr_section_v1 *section; + const u8 *fw_end = fw + len; + const u8 *bin; + u32 base_hdr_len; + u32 mssc_len; + int ret; + u32 i; + + info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM); + info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM); + base_hdr_len = struct_size(fw_hdr, sections, info->section_num); + info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR); + info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE); + + if (chip->chip_gen == RTW89_CHIP_AX) + info->part_size = FWDL_SECTION_PER_PKT_LEN; + else + info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_PART_SIZE); + + if (info->dynamic_hdr_en) { + info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE); + info->dynamic_hdr_len = info->hdr_len - base_hdr_len; + fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); + if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { + rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); + return -EINVAL; + } + } else { + info->hdr_len = base_hdr_len; + info->dynamic_hdr_len = 0; + } + + bin = fw + info->hdr_len; + + /* jump to section header */ + section_info = info->section_info; + for (i = 0; i < info->section_num; i++) { + section = &fw_hdr->sections[i]; + + section_info->type = + le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE); + section_info->len = + le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE); + if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM)) + section_info->len += FWDL_SECTION_CHKSUM_LEN; + section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL); + section_info->dladdr = + le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR); + section_info->addr = bin; + + if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { + section_info->mssc = + le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC); + + ret = __parse_security_section(rtwdev, info, section_info, + bin, &mssc_len); + if (ret) + return ret; + } else { + section_info->mssc = 0; + mssc_len = 0; + } + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", + i, section_info->type, section_info->len, + section_info->mssc, mssc_len, bin - fw); + rtw89_debug(rtwdev, RTW89_DBG_FW, + " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", + section_info->ignore, section_info->key_addr, + section_info->key_addr ? + section_info->key_addr - section_info->addr : 0, + section_info->key_len, section_info->key_idx); + + bin += section_info->len + mssc_len; + section_info++; + } + + if (fw_end != bin) { + rtw89_err(rtwdev, "[ERR]fw bin size\n"); + return -EINVAL; + } + + if (!info->secure_section_exist) + rtw89_warn(rtwdev, "no firmware secure section\n"); + + return 0; +} + +static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, + const struct rtw89_fw_suit *fw_suit, + struct rtw89_fw_bin_info *info) +{ + const u8 *fw = fw_suit->data; + u32 len = fw_suit->size; + + if (!fw || !len) { + rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type); + return -ENOENT; + } + + switch (fw_suit->hdr_ver) { + case 0: + return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info); + case 1: + return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info); + default: + return -ENOENT; + } +} + +static +const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev, + const struct firmware *firmware) +{ + const struct rtw89_mfw_hdr *mfw_hdr; + + if (sizeof(*mfw_hdr) > firmware->size) + return NULL; + + mfw_hdr = (const struct rtw89_mfw_hdr *)&firmware->data[0]; + + if (mfw_hdr->sig != RTW89_MFW_SIG) + return NULL; + + return mfw_hdr; +} + +static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev, + const struct firmware *firmware, + const struct rtw89_mfw_hdr *mfw_hdr) +{ + const void *mfw = firmware->data; + u32 mfw_len = firmware->size; + u8 fw_nr = mfw_hdr->fw_nr; + const void *ptr; + + if (fw_nr == 0) { + rtw89_err(rtwdev, "mfw header has no fw entry\n"); + return -ENOENT; + } + + ptr = &mfw_hdr->info[fw_nr]; + + if (ptr > mfw + mfw_len) { + rtw89_err(rtwdev, "mfw header out of address\n"); + return -EFAULT; + } + + return 0; +} + +static +int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + struct rtw89_fw_suit *fw_suit, bool nowarn) +{ + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const struct firmware *firmware = fw_info->req.firmware; + const struct rtw89_mfw_info *mfw_info = NULL, *tmp; + const struct rtw89_mfw_hdr *mfw_hdr; + const u8 *mfw = firmware->data; + u32 mfw_len = firmware->size; + int ret; + int i; + + mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); + if (!mfw_hdr) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); + /* legacy firmware support normal type only */ + if (type != RTW89_FW_NORMAL) + return -EINVAL; + fw_suit->data = mfw; + fw_suit->size = mfw_len; + return 0; + } + + ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); + if (ret) + return ret; + + for (i = 0; i < mfw_hdr->fw_nr; i++) { + tmp = &mfw_hdr->info[i]; + if (tmp->type != type) + continue; + + if (type == RTW89_FW_LOGFMT) { + mfw_info = tmp; + goto found; + } + + /* Version order of WiFi firmware in firmware file are not in order, + * pass all firmware to find the equal or less but closest version. + */ + if (tmp->cv <= rtwdev->hal.cv && !tmp->mp) { + if (!mfw_info || mfw_info->cv < tmp->cv) + mfw_info = tmp; + } + } + + if (mfw_info) + goto found; + + if (!nowarn) + rtw89_err(rtwdev, "no suitable firmware found\n"); + return -ENOENT; + +found: + fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); + fw_suit->size = le32_to_cpu(mfw_info->size); + + if (fw_suit->data + fw_suit->size > mfw + mfw_len) { + rtw89_err(rtwdev, "fw_suit %d out of address\n", type); + return -EFAULT; + } + + return 0; +} + +static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const struct firmware *firmware = fw_info->req.firmware; + const struct rtw89_mfw_info *mfw_info; + const struct rtw89_mfw_hdr *mfw_hdr; + u32 size; + int ret; + + mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); + if (!mfw_hdr) { + rtw89_warn(rtwdev, "not mfw format\n"); + return 0; + } + + ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); + if (ret) + return ret; + + mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1]; + size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size); + + return size; +} + +static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev, + struct rtw89_fw_suit *fw_suit, + const struct rtw89_fw_hdr *hdr) +{ + fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); + fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); + fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); + fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); + fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID); + fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); + fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); + fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); + fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); + fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); + fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); +} + +static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev, + struct rtw89_fw_suit *fw_suit, + const struct rtw89_fw_hdr_v1 *hdr) +{ + fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION); + fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION); + fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION); + fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX); + fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID); + fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR); + fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH); + fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE); + fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR); + fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN); + fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION); +} + +static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev, + enum rtw89_fw_type type, + struct rtw89_fw_suit *fw_suit) +{ + const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data; + const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data; + struct wiphy *wiphy = rtwdev->hw->wiphy; + + if (type == RTW89_FW_LOGFMT) + return 0; + + fw_suit->type = type; + fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER); + + switch (fw_suit->hdr_ver) { + case 0: + rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0); + break; + case 1: + rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1); + break; + default: + rtw89_err(rtwdev, "Unknown firmware header version %u\n", + fw_suit->hdr_ver); + return -ENOENT; + } + + rtw89_info(rtwdev, + "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n", + fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, + fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type); + + if (type == RTW89_FW_NORMAL || type == RTW89_FW_NORMAL_CE || + type == RTW89_FW_NORMAL_B) + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), + "%u.%u.%u.%u", + fw_suit->major_ver, fw_suit->minor_ver, + fw_suit->sub_ver, fw_suit->sub_idex); + + return 0; +} + +static +int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + bool nowarn) +{ + struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); + int ret; + + ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); + if (ret) + return ret; + + return rtw89_fw_update_ver(rtwdev, type, fw_suit); +} + +static +int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + enum rtw89_fw_type type = arg.fw_type; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_fw_suit *fw_suit; + + /* Version of BB MCU is in decreasing order in firmware file, so take + * first equal or less version, which is equal or less but closest version. + */ + if (hal->cv < elm->u.bbmcu.cv) + return 1; /* ignore this element */ + + fw_suit = rtw89_fw_suit_get(rtwdev, type); + if (fw_suit->data) + return 1; /* ignore this element (a firmware is taken already) */ + + fw_suit->data = elm->u.bbmcu.contents; + fw_suit->size = le32_to_cpu(elm->size); + + return rtw89_fw_update_ver(rtwdev, type, fw_suit); +} + +#define __DEF_FW_FEAT_COND(__cond, __op) \ +static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ +{ \ + return suit_ver_code __op comp_ver_code; \ +} + +__DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ +__DEF_FW_FEAT_COND(le, <=); /* less or equal */ +__DEF_FW_FEAT_COND(lt, <); /* less than */ + +struct __fw_feat_cfg { + enum rtw89_core_chip_id chip_id; + enum rtw89_fw_feature feature; + u32 ver_code; + bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); + bool disable; + int size; +}; + +#define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _feat, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + } + +#define __S_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _feat, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + .disable = true, \ + .size = 1, \ + } + +#define __G_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _grp) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _grp ## _MIN, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + .disable = true, \ + .size = RTW89_FW_FEATURE_ ## _grp ## _MAX - \ + RTW89_FW_FEATURE_ ## _grp ## _MIN + 1, \ + } + +#define __DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat, _type) \ + __##_type##_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) + +static const struct __fw_feat_cfg fw_feat_tbl[] = { + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX), + __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 15, BEACON_LOSS_COUNT_V1), + __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, BEACON_TRACKING), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 122, 0, BEACON_TRACKING), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0), + __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, CRASH_TRIGGER_TYPE_1), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 129, 1, BEACON_TRACKING), + __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 94, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8922A, ge, 0, 0, 0, 0, RFK_PRE_NOTIFY_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD_EXTRA_OP), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 31, 0, RFK_PRE_NOTIFY_V1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_MCC_V0), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING), + __DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, RFK_PRE_NOTIFY_MCC_V1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 92, 0, TX_HISTORY_V1), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2), + __CFG_FW_FEAT(RTL8922D, ge, 0, 0, 0, 0, MACID_PAUSE_SLEEP), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, BEACON_FILTER), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 84, 0, CRASH_TRIGGER_TYPE_1), + __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 84, 0, ADDR_CAM_V0), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 87, 0, BEACON_LOSS_COUNT_V1), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 91, 0, RFK_PRE_NOTIFY_MCC_V2), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 91, 4, LPS_ML_INFO_V1), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 93, 0, NOTIFY_AP_INFO), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 104, 0, TX_HISTORY_V1), + __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1), + __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 0, RFK_TXIQK_V0), + __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2), +}; + +static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, + const struct rtw89_chip_info *chip, + u32 ver_code) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { + const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; + + if (chip->chip_id != ent->chip_id) + continue; + + if (!ent->cond(ver_code, ent->ver_code)) + continue; + + if (!ent->disable) { + RTW89_SET_FW_FEATURE(ent->feature, fw); + continue; + } + + for (int n = 0; n < ent->size; n++) + RTW89_CLR_FW_FEATURE(ent->feature + n, fw); + } +} + +static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_fw_suit *fw_suit; + u32 suit_ver_code; + + fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); + suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); + + rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code); +} + +const struct firmware * +rtw89_early_fw_feature_recognize(struct device *device, + const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant, + struct rtw89_fw_info *early_fw, + int *used_fw_format) +{ + const struct rtw89_fw_def *fw_def = __rtw89_chip_get_fw_def(chip, variant); + const struct firmware *firmware; + char fw_name[64]; + int fw_format; + u32 ver_code; + int ret; + + for (fw_format = fw_def->fw_format_max; fw_format >= 0; fw_format--) { + rtw89_fw_get_filename(fw_name, sizeof(fw_name), + fw_def->fw_basename, fw_format); + + ret = request_firmware(&firmware, fw_name, device); + if (!ret) { + dev_info(device, "loaded firmware %s\n", fw_name); + *used_fw_format = fw_format; + break; + } + } + + if (ret) { + dev_err(device, "failed to early request firmware: %d\n", ret); + return NULL; + } + + ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); + + if (!ver_code) + goto out; + + rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code); + +out: + return firmware; +} + +static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_variant *variant = rtwdev->variant; + const struct rtw89_fw_suit *fw_suit; + u32 suit_ver_code; + + if (!variant) + return 0; + + fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); + suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); + + if (variant->fw_min_ver_code > suit_ver_code) { + rtw89_err(rtwdev, "minimum required firmware version is 0x%x\n", + variant->fw_min_ver_code); + return -ENOENT; + } + + return 0; +} + +int rtw89_fw_recognize(struct rtw89_dev *rtwdev) +{ + const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_fw_type normal_fw_type = RTW89_FW_NORMAL; + enum rtw89_fw_type wowlan_fw_type = RTW89_FW_WOWLAN; + int ret; + + if (fw_def->fw_b_aid && fw_def->fw_b_aid == hal->aid) { + normal_fw_type = RTW89_FW_NORMAL_B; + wowlan_fw_type = RTW89_FW_WOWLAN_B; + } + + if (chip->try_ce_fw) { + ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); + if (!ret) + goto normal_done; + } + + ret = __rtw89_fw_recognize(rtwdev, normal_fw_type, false); + if (ret) + return ret; + +normal_done: + ret = rtw89_fw_validate_ver_required(rtwdev); + if (ret) + return ret; + + /* It still works if wowlan firmware isn't existing. */ + __rtw89_fw_recognize(rtwdev, wowlan_fw_type, false); + + /* It still works if log format file isn't existing. */ + __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true); + + rtw89_fw_recognize_features(rtwdev); + + rtw89_coex_recognize_ver(rtwdev); + + return 0; +} + +static +int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_phy_table *tbl, **pp; + struct rtw89_reg2_def *regs; + bool radio = false; + u32 n_regs, i; + u16 aid; + u8 idx; + + switch (le32_to_cpu(elm->id)) { + case RTW89_FW_ELEMENT_ID_BB_REG: + pp = &elm_info->bb_tbl; + break; + case RTW89_FW_ELEMENT_ID_BB_GAIN: + pp = &elm_info->bb_gain; + break; + case RTW89_FW_ELEMENT_ID_RADIO_A: + case RTW89_FW_ELEMENT_ID_RADIO_B: + case RTW89_FW_ELEMENT_ID_RADIO_C: + case RTW89_FW_ELEMENT_ID_RADIO_D: + idx = elm->u.reg2.idx; + pp = &elm_info->rf_radio[idx]; + + radio = true; + break; + case RTW89_FW_ELEMENT_ID_RF_NCTL: + pp = &elm_info->rf_nctl; + break; + default: + return -ENOENT; + } + + aid = le16_to_cpu(elm->aid); + if (aid && aid != hal->aid) + return 1; /* ignore if aid not matched */ + else if (*pp) + return 1; /* ignore if an element is existing */ + + tbl = kzalloc_obj(*tbl); + if (!tbl) + return -ENOMEM; + + n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); + regs = kzalloc_objs(*regs, n_regs); + if (!regs) + goto out; + + for (i = 0; i < n_regs; i++) { + regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr); + regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data); + } + + tbl->n_regs = n_regs; + tbl->regs = regs; + + if (radio) { + tbl->rf_path = arg.rf_path; + tbl->config = chip->chip_id == RTL8852A ? + rtw89_phy_config_rf_reg : + rtw89_phy_config_rf_reg_v1; + } + + *pp = tbl; + + return 0; + +out: + kfree(tbl); + return -ENOMEM; +} + +static +int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + const struct __rtw89_fw_txpwr_element *txpwr_elm = &elm->u.txpwr; + const unsigned long offset = arg.offset; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + u16 aid = le16_to_cpu(elm->aid); + struct rtw89_txpwr_conf *conf; + + if (aid && aid != hal->aid) + return 1; + + if (!rtwdev->rfe_data) { + rtwdev->rfe_data = kzalloc_obj(*rtwdev->rfe_data); + if (!rtwdev->rfe_data) + return -ENOMEM; + } + + conf = (void *)rtwdev->rfe_data + offset; + + /* if multiple matched, take the last eventually */ + if (txpwr_elm->rfe_type == efuse->rfe_type) + goto setup; + + /* without one is matched, accept default */ + if (txpwr_elm->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE && + (!rtw89_txpwr_conf_valid(conf) || + conf->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE)) + goto setup; + + rtw89_debug(rtwdev, RTW89_DBG_FW, "skip txpwr element ID %u RFE %u\n", + elm->id, txpwr_elm->rfe_type); + return 0; + +setup: + rtw89_debug(rtwdev, RTW89_DBG_FW, "take txpwr element ID %u RFE %u\n", + elm->id, txpwr_elm->rfe_type); + + conf->rfe_type = txpwr_elm->rfe_type; + conf->ent_sz = txpwr_elm->ent_sz; + conf->num_ents = le32_to_cpu(txpwr_elm->num_ents); + conf->data = txpwr_elm->content; + return 0; +} + +static +int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + u16 aid = le16_to_cpu(elm->aid); + u32 needed_bitmap = 0; + u32 offset = 0; + int subband; + u32 bitmap; + int type; + + if (aid && aid != hal->aid) + return 1; + + if (chip->support_bands & BIT(NL80211_BAND_6GHZ)) + needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ; + if (chip->support_bands & BIT(NL80211_BAND_5GHZ)) + needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ; + if (chip->support_bands & BIT(NL80211_BAND_2GHZ)) + needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ; + + bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap); + + if ((bitmap & needed_bitmap) != needed_bitmap) { + rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n", + needed_bitmap, bitmap); + return -ENOENT; + } + + elm_info->txpwr_trk = kzalloc_obj(*elm_info->txpwr_trk); + if (!elm_info->txpwr_trk) + return -ENOMEM; + + for (type = 0; bitmap; type++, bitmap >>= 1) { + if (!(bitmap & BIT(0))) + continue; + + if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START && + type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX) + subband = 4; + else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START && + type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX) + subband = 3; + else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START && + type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX) + subband = 1; + else + break; + + elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset]; + + offset += subband; + if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size)) + goto err; + } + + return 0; + +err: + rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n", + offset, le32_to_cpu(elm->size)); + kfree(elm_info->txpwr_trk); + elm_info->txpwr_trk = NULL; + + return -EFAULT; +} + +static +int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + u8 rfk_id; + + if (elm_info->rfk_log_fmt) + goto allocated; + + elm_info->rfk_log_fmt = kzalloc_obj(*elm_info->rfk_log_fmt); + if (!elm_info->rfk_log_fmt) + return 1; /* this is an optional element, so just ignore this */ + +allocated: + rfk_id = elm->u.rfk_log_fmt.rfk_id; + if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM) + return 1; + + elm_info->rfk_log_fmt->elm[rfk_id] = elm; + + return 0; +} + +static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor, + u8 cursor_size) +{ + /* fill default values if needed for backward compatibility */ + struct rtw89_fw_regd_entry entry = { + .rule_2ghz = RTW89_NA, + .rule_5ghz = RTW89_NA, + .rule_6ghz = RTW89_NA, + .fmap = cpu_to_le32(0x0), + }; + u8 valid_size = min_t(u8, sizeof(entry), cursor_size); + unsigned int i; + u32 fmap; + + memcpy(&entry, cursor, valid_size); + memset(regd, 0, sizeof(*regd)); + + regd->alpha2[0] = entry.alpha2_0; + regd->alpha2[1] = entry.alpha2_1; + regd->alpha2[2] = '\0'; + + /* also need to consider forward compatibility */ + regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ? + entry.rule_2ghz : RTW89_NA; + regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ? + entry.rule_5ghz : RTW89_NA; + regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ? + entry.rule_6ghz : RTW89_NA; + + BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap)); + BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC); + + fmap = le32_to_cpu(entry.fmap); + for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) { + if (fmap & BIT(i)) + set_bit(i, regd->func_bitmap); + } + + return true; +} + +#define rtw89_for_each_in_regd_element(regd, element) \ + for (const void *cursor = (element)->content, \ + *end = (element)->content + \ + le32_to_cpu((element)->num_ents) * (element)->ent_sz; \ + cursor < end; cursor += (element)->ent_sz) \ + if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz)) + +static +int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd; + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + u32 num_ents = le32_to_cpu(regd_elm->num_ents); + struct rtw89_regd_data *p; + struct rtw89_regd regd; + u32 i = 0; + + if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) { + rtw89_warn(rtwdev, + "regd element ents (%d) are over max num (%d)\n", + num_ents, RTW89_REGD_MAX_COUNTRY_NUM); + rtw89_warn(rtwdev, + "regd element ignore and take another/common\n"); + return 1; + } + + if (elm_info->regd) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "regd element take the latter\n"); + devm_kfree(rtwdev->dev, elm_info->regd); + elm_info->regd = NULL; + } + + p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->nr = num_ents; + rtw89_for_each_in_regd_element(®d, regd_elm) + p->map[i++] = regd; + + if (i != num_ents) { + rtw89_err(rtwdev, "regd element has %d invalid ents\n", + num_ents - i); + devm_kfree(rtwdev->dev, p); + return -EINVAL; + } + + elm_info->regd = p; + return 0; +} + +static +int rtw89_build_afe_pwr_seq_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + + elm_info->afe = elm; + + return 0; +} + +static +int rtw89_recognize_diag_mac_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + + elm_info->diag_mac = elm; + + return 0; +} + +static +int rtw89_build_tx_comp_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + u8 rfe_type; + u16 aid; + + aid = le16_to_cpu(elm->aid); + rfe_type = elm->u.tx_comp.rfe_type; + + if (aid && aid != hal->aid) + return 1; /* ignore if aid not matched */ + else if (rfe_type && rfe_type != efuse->rfe_type) + return 1; /* ignore if rfe_type not matched */ + else if (elm_info->tx_comp) + return 1; /* ignore if an element is existing */ + + elm_info->tx_comp = elm; + + return 0; +} + +static const struct rtw89_fw_element_handler __fw_element_handlers[] = { + [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, + { .fw_type = RTW89_FW_BBMCU0 }, NULL}, + [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm, + { .fw_type = RTW89_FW_BBMCU1 }, NULL}, + [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, {}, "BB"}, + [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, {}, NULL}, + [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm, + { .rf_path = RF_PATH_A }, "radio A"}, + [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm, + { .rf_path = RF_PATH_B }, NULL}, + [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm, + { .rf_path = RF_PATH_C }, NULL}, + [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm, + { .rf_path = RF_PATH_D }, NULL}, + [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, {}, "NCTL"}, + [RTW89_FW_ELEMENT_ID_TXPWR_BYRATE] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, byrate.conf) }, "TXPWR", + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_2ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_5ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_2ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_5ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_6ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_5ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_2ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_5ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_6ghz.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU] = { + rtw89_fw_recognize_txpwr_from_elm, + { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL, + }, + [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = { + rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK", + }, + [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = { + rtw89_build_rfk_log_fmt_from_elm, {}, NULL, + }, + [RTW89_FW_ELEMENT_ID_REGD] = { + rtw89_recognize_regd_from_elm, {}, "REGD", + }, + [RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ] = { + rtw89_build_afe_pwr_seq_from_elm, {}, "AFE", + }, + [RTW89_FW_ELEMENT_ID_DIAG_MAC] = { + rtw89_recognize_diag_mac_from_elm, {}, NULL, + }, + [RTW89_FW_ELEMENT_ID_TX_COMP] = { + rtw89_build_tx_comp_from_elm, {}, NULL, + }, +}; + +int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const struct firmware *firmware = fw_info->req.firmware; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 unrecognized_elements = chip->needed_fw_elms; + const struct rtw89_fw_element_handler *handler; + const struct rtw89_fw_element_hdr *hdr; + bool transition; + u32 elm_size; + u32 elem_id; + u32 offset; + int ret; + + BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM); + + transition = !!((chip->needed_fw_elms & BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION))); + unrecognized_elements &= ~BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION); + + offset = rtw89_mfw_get_size(rtwdev); + offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); + if (offset == 0) + return -EINVAL; + + while (offset + sizeof(*hdr) < firmware->size) { + hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset); + + elm_size = le32_to_cpu(hdr->size); + if (offset + elm_size >= firmware->size) { + rtw89_warn(rtwdev, "firmware element size exceeds\n"); + break; + } + + elem_id = le32_to_cpu(hdr->id); + if (elem_id >= ARRAY_SIZE(__fw_element_handlers)) + goto next; + + handler = &__fw_element_handlers[elem_id]; + if (!handler->fn) + goto next; + + ret = handler->fn(rtwdev, hdr, handler->arg); + if (ret == 1) /* ignore this element */ + goto next; + if (ret) + return ret; + + if (handler->name) + rtw89_info(rtwdev, "Firmware element %s version: %4ph\n", + handler->name, hdr->ver); + + unrecognized_elements &= ~BIT(elem_id); +next: + offset += sizeof(*hdr) + elm_size; + offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); + } + + if (unrecognized_elements) { + if (transition) { + rtw89_info(rtwdev, "NOTE: This firmware is going to be obsolete!\n" + "Please download the latest firmware from https://gitlab.com/kernel-firmware/linux-firmware.git\n"); + return 0; + } + + rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n", + unrecognized_elements); + return -ENOENT; + } + + return 0; +} + +void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u8 type, u8 cat, u8 class, u8 func, + bool rack, bool dack, u32 len) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct fwcmd_hdr *hdr; + + hdr = (struct fwcmd_hdr *)skb_push(skb, 8); + + if (chip->chip_gen == RTW89_CHIP_AX && !(rtwdev->fw.h2c_seq % 4)) + rack = true; + hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | + FIELD_PREP(H2C_HDR_CAT, cat) | + FIELD_PREP(H2C_HDR_CLASS, class) | + FIELD_PREP(H2C_HDR_FUNC, func) | + FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); + + hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, + len + H2C_HEADER_LEN) | + (rack ? H2C_HDR_REC_ACK : 0) | + (dack ? H2C_HDR_DONE_ACK : 0)); + + rtwdev->fw.h2c_seq++; +} + +static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, + struct sk_buff *skb, + u8 type, u8 cat, u8 class, u8 func, + u32 len) +{ + struct fwcmd_hdr *hdr; + + hdr = (struct fwcmd_hdr *)skb_push(skb, 8); + + hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | + FIELD_PREP(H2C_HDR_CAT, cat) | + FIELD_PREP(H2C_HDR_CLASS, class) | + FIELD_PREP(H2C_HDR_FUNC, func) | + FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); + + hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, + len + H2C_HEADER_LEN)); +} + +static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr *fw_hdr) +{ + struct rtw89_fw_hdr_section_info *section_info; + struct rtw89_fw_hdr_section *section; + int i; + + le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_W7_PART_SIZE); + + for (i = 0; i < info->section_num; i++) { + section_info = &info->section_info[i]; + + if (!section_info->len_override) + continue; + + section = &fw_hdr->sections[i]; + le32p_replace_bits(§ion->w1, section_info->len_override, + FWSECTION_HDR_W1_SEC_SIZE); + } + + return 0; +} + +static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_v1 *fw_hdr) +{ + struct rtw89_fw_hdr_section_info *section_info; + struct rtw89_fw_hdr_section_v1 *section; + u8 dst_sec_idx = 0; + u8 sec_idx; + + le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_V1_W7_PART_SIZE); + + for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) { + section_info = &info->section_info[sec_idx]; + section = &fw_hdr->sections[sec_idx]; + + if (section_info->ignore) + continue; + + if (dst_sec_idx != sec_idx) + fw_hdr->sections[dst_sec_idx] = *section; + + dst_sec_idx++; + } + + le32p_replace_bits(&fw_hdr->w6, dst_sec_idx, FW_HDR_V1_W6_SEC_NUM); + + return (info->section_num - dst_sec_idx) * sizeof(*section); +} + +static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, + const struct rtw89_fw_suit *fw_suit, + struct rtw89_fw_bin_info *info) +{ + u32 len = info->hdr_len - info->dynamic_hdr_len; + struct rtw89_fw_hdr_v1 *fw_hdr_v1; + const u8 *fw = fw_suit->data; + struct rtw89_fw_hdr *fw_hdr; + struct sk_buff *skb; + u32 truncated; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); + return -ENOMEM; + } + + skb_put_data(skb, fw, len); + + switch (fw_suit->hdr_ver) { + case 0: + fw_hdr = (struct rtw89_fw_hdr *)skb->data; + truncated = __rtw89_fw_download_tweak_hdr_v0(rtwdev, info, fw_hdr); + break; + case 1: + fw_hdr_v1 = (struct rtw89_fw_hdr_v1 *)skb->data; + truncated = __rtw89_fw_download_tweak_hdr_v1(rtwdev, info, fw_hdr_v1); + break; + default: + ret = -EOPNOTSUPP; + goto fail; + } + + if (truncated) { + len -= truncated; + skb_trim(skb, len); + } + + rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FWDL, + H2C_FUNC_MAC_FWHDR_DL, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, + const struct rtw89_fw_suit *fw_suit, + struct rtw89_fw_bin_info *info) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + int ret; + + ret = __rtw89_fw_download_hdr(rtwdev, fw_suit, info); + if (ret) { + rtw89_err(rtwdev, "[ERR]FW header download\n"); + return ret; + } + + ret = mac->fwdl_check_path_ready(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); + return ret; + } + + rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + + return 0; +} + +static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, + struct rtw89_fw_hdr_section_info *info, + u32 part_size) +{ + struct sk_buff *skb; + const u8 *section = info->addr; + u32 residue_len = info->len; + bool copy_key = false; + u32 pkt_len; + int ret; + + if (info->ignore) + return 0; + + if (info->len_override) { + if (info->len_override > info->len) + rtw89_warn(rtwdev, "override length %u larger than original %u\n", + info->len_override, info->len); + else + residue_len = info->len_override; + } + + if (info->key_addr && info->key_len) { + if (residue_len > part_size || info->len < info->key_len) + rtw89_warn(rtwdev, + "ignore to copy key data because of len %d, %d, %d, %d\n", + info->len, part_size, + info->key_len, residue_len); + else + copy_key = true; + } + + while (residue_len) { + pkt_len = min(residue_len, part_size); + + skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put_data(skb, section, pkt_len); + + if (copy_key) + memcpy(skb->data + pkt_len - info->key_len, + info->key_addr, info->key_len); + + ret = rtw89_h2c_tx(rtwdev, skb, true); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + section += pkt_len; + residue_len -= pkt_len; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static enum rtw89_fwdl_check_type +rtw89_fw_get_fwdl_chk_type_from_suit(struct rtw89_dev *rtwdev, + const struct rtw89_fw_suit *fw_suit) +{ + switch (fw_suit->type) { + case RTW89_FW_BBMCU0: + return RTW89_FWDL_CHECK_BB0_FWDL_DONE; + case RTW89_FW_BBMCU1: + return RTW89_FWDL_CHECK_BB1_FWDL_DONE; + default: + return RTW89_FWDL_CHECK_WCPU_FWDL_DONE; + } +} + +static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, + const struct rtw89_fw_suit *fw_suit, + struct rtw89_fw_bin_info *info) +{ + struct rtw89_fw_hdr_section_info *section_info = info->section_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + enum rtw89_fwdl_check_type chk_type; + u8 section_num = info->section_num; + int ret; + + while (section_num--) { + ret = __rtw89_fw_download_main(rtwdev, section_info, info->part_size); + if (ret) + return ret; + section_info++; + } + + if (chip->chip_gen == RTW89_CHIP_AX) + return 0; + + chk_type = rtw89_fw_get_fwdl_chk_type_from_suit(rtwdev, fw_suit); + ret = rtw89_fw_check_rdy(rtwdev, chk_type); + if (ret) { + rtw89_warn(rtwdev, "failed to download firmware type %u\n", + fw_suit->type); + return ret; + } + + return 0; +} + +static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + u32 addr = R_AX_DBG_PORT_SEL; + u32 val32; + u16 index; + + if (chip_gen == RTW89_CHIP_BE) { + addr = R_BE_WLCPU_PORT_PC; + goto dump; + } + + rtw89_write32(rtwdev, R_AX_DBG_CTRL, + FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | + FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); + rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); + +dump: + for (index = 0; index < 15; index++) { + val32 = rtw89_read32(rtwdev, addr); + rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); + fsleep(10); + } +} + +static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 val32; + + val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); + rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); + + val32 = rtw89_read32(rtwdev, mac->boot_dbg); + rtw89_err(rtwdev, "[ERR]fwdl 0x%x = 0x%x\n", mac->boot_dbg, val32); + + rtw89_fw_prog_cnt_dump(rtwdev); +} + +static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev, + struct rtw89_fw_suit *fw_suit) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_fw_bin_info info = {}; + int ret; + + ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info); + if (ret) { + rtw89_err(rtwdev, "parse fw header fail\n"); + return ret; + } + + rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode); + + if (rtwdev->chip->chip_id == RTL8922A && + (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN)) + rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000); + + ret = mac->fwdl_check_path_ready(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]H2C path ready\n"); + return ret; + } + + ret = rtw89_fw_download_hdr(rtwdev, fw_suit, &info); + if (ret) + return ret; + + ret = rtw89_fw_download_main(rtwdev, fw_suit, &info); + if (ret) + return ret; + + return 0; +} + +static +int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + bool include_bb) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_fw_info *fw_info = &rtwdev->fw; + struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); + u8 bbmcu_nr = rtwdev->chip->bbmcu_nr; + int ret; + int i; + + mac->disable_cpu(rtwdev); + ret = mac->fwdl_enable_wcpu(rtwdev, 0, true, include_bb); + if (ret) + return ret; + + ret = rtw89_fw_download_suit(rtwdev, fw_suit); + if (ret) + goto fwdl_err; + + for (i = 0; i < bbmcu_nr && include_bb; i++) { + fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_BBMCU0 + i); + + ret = rtw89_fw_download_suit(rtwdev, fw_suit); + if (ret) + goto fwdl_err; + } + + fw_info->h2c_seq = 0; + fw_info->rec_seq = 0; + fw_info->h2c_counter = 0; + fw_info->c2h_counter = 0; + rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; + rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; + + mdelay(5); + + ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); + if (ret) { + rtw89_warn(rtwdev, "download firmware fail\n"); + goto fwdl_err; + } + + return ret; + +fwdl_err: + rtw89_fw_dl_fail_dump(rtwdev); + return ret; +} + +int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + bool include_bb) +{ + int retry; + int ret; + + for (retry = 0; retry < 5; retry++) { + ret = __rtw89_fw_download(rtwdev, type, include_bb); + if (!ret) + return 0; + } + + return ret; +} + +int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_info *fw = &rtwdev->fw; + + wait_for_completion(&fw->req.completion); + if (!fw->req.firmware) + return -EINVAL; + + return 0; +} + +static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev, + struct rtw89_fw_req_info *req, + const char *fw_name, bool nowarn) +{ + int ret; + + if (req->firmware) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "full firmware has been early requested\n"); + complete_all(&req->completion); + return 0; + } + + if (nowarn) + ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev); + else + ret = request_firmware(&req->firmware, fw_name, rtwdev->dev); + + complete_all(&req->completion); + + return ret; +} + +void rtw89_load_firmware_work(struct work_struct *work) +{ + struct rtw89_dev *rtwdev = + container_of(work, struct rtw89_dev, load_firmware_work); + const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); + char fw_name[64]; + + rtw89_fw_get_filename(fw_name, sizeof(fw_name), + fw_def->fw_basename, rtwdev->fw.fw_format); + + rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); +} + +static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl) +{ + if (!tbl) + return; + + kfree(tbl->regs); + kfree(tbl); +} + +static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + int i; + + rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl); + rtw89_free_phy_tbl_from_elm(elm_info->bb_gain); + for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++) + rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]); + rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl); + + kfree(elm_info->txpwr_trk); + kfree(elm_info->rfk_log_fmt); +} + +void rtw89_unload_firmware(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_info *fw = &rtwdev->fw; + + cancel_work_sync(&rtwdev->load_firmware_work); + + if (fw->req.firmware) { + release_firmware(fw->req.firmware); + + /* assign NULL back in case rtw89_free_ieee80211_hw() + * try to release the same one again. + */ + fw->req.firmware = NULL; + } + + kfree(fw->log.fmts); + rtw89_unload_firmware_elements(rtwdev); +} + +static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id) +{ + struct rtw89_fw_log *fw_log = &rtwdev->fw.log; + u32 i; + + if (fmt_id > fw_log->last_fmt_id) + return 0; + + for (i = 0; i < fw_log->fmt_count; i++) { + if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id) + return i; + } + return 0; +} + +static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_log *log = &rtwdev->fw.log; + const struct rtw89_fw_logsuit_hdr *suit_hdr; + struct rtw89_fw_suit *suit = &log->suit; + const void *fmts_ptr, *fmts_end_ptr; + u32 fmt_count; + int i; + + suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data; + fmt_count = le32_to_cpu(suit_hdr->count); + log->fmt_ids = suit_hdr->ids; + fmts_ptr = &suit_hdr->ids[fmt_count]; + fmts_end_ptr = suit->data + suit->size; + log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL); + if (!log->fmts) + return -ENOMEM; + + for (i = 0; i < fmt_count; i++) { + fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr); + if (!fmts_ptr) + break; + + (*log->fmts)[i] = fmts_ptr; + log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]); + log->fmt_count++; + fmts_ptr += strlen(fmts_ptr); + } + + return 0; +} + +int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_log *log = &rtwdev->fw.log; + struct rtw89_fw_suit *suit = &log->suit; + + if (!suit || !suit->data) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n"); + return -EINVAL; + } + if (log->fmts) + return 0; + + return rtw89_fw_log_create_fmts_dict(rtwdev); +} + +static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev, + const struct rtw89_fw_c2h_log_fmt *log_fmt, + u32 fmt_idx, u8 para_int, bool raw_data) +{ + const char *(*fmts)[] = rtwdev->fw.log.fmts; + char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE]; + u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0}; + int i; + + if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) { + rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n", + log_fmt->argc); + return; + } + + if (para_int) + for (i = 0 ; i < log_fmt->argc; i++) + args[i] = le32_to_cpu(log_fmt->u.argv[i]); + + if (raw_data) { + if (para_int) + snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, + "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id), + para_int, log_fmt->argc, (int)sizeof(args), args); + else + snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, + "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id), + para_int, log_fmt->argc, log_fmt->u.raw); + } else { + snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx], + args[0x0], args[0x1], args[0x2], args[0x3], args[0x4], + args[0x5], args[0x6], args[0x7], args[0x8], args[0x9], + args[0xa], args[0xb], args[0xc], args[0xd], args[0xe], + args[0xf]); + } + + rtw89_info(rtwdev, "C2H log: %s", str_buf); +} + +void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) +{ + const struct rtw89_fw_c2h_log_fmt *log_fmt; + u8 para_int; + u32 fmt_idx; + + if (len < RTW89_C2H_HEADER_LEN) { + rtw89_err(rtwdev, "c2h log length is wrong!\n"); + return; + } + + buf += RTW89_C2H_HEADER_LEN; + len -= RTW89_C2H_HEADER_LEN; + log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf; + + if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN) + goto plain_log; + + if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE)) + goto plain_log; + + if (!rtwdev->fw.log.fmts) + return; + + para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT); + fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id)); + + if (!para_int && log_fmt->argc != 0 && fmt_idx != 0) + rtw89_info(rtwdev, "C2H log: %s%s", + (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw); + else if (fmt_idx != 0 && para_int) + rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false); + else + rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true); + return; + +plain_log: + rtw89_info(rtwdev, "C2H log: %.*s", len, buf); + +} + +int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, + enum rtw89_upd_mode upd_mode) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_addr_cam_v0 *h2c_v0; + struct rtw89_h2c_addr_cam *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + int ret; + + if (RTW89_CHK_FW_FEATURE(ADDR_CAM_V0, &rtwdev->fw) || + chip->chip_gen == RTW89_CHIP_AX) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c_v0 = (struct rtw89_h2c_addr_cam_v0 *)skb->data; + + rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, + scan_mac_addr, h2c_v0); + rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, h2c_v0); + + if (ver == 0) + goto hdr; + + h2c = (struct rtw89_h2c_addr_cam *)skb->data; + h2c->w15 = le32_encode_bits(upd_mode, ADDR_CAM_W15_UPD_MODE); + +hdr: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_ADDR_CAM_UPDATE, + H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_dctlinfo_ud_v1 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data; + + rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); + +int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_dctlinfo_ud_v2 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; + + rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); + +int rtw89_fw_h2c_dctl_sec_cam_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_dctlinfo_ud_v3 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; + + rtw89_cam_fill_dctl_sec_cam_info_v3(rtwdev, rtwvif_link, rtwsta_link, h2c); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V3, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v3); + +int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_dctlinfo_ud_v2 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V2_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V2_C0_OP); + + h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_ALL); + h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_ALL); + h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_ALL); + h2c->m3 = cpu_to_le32(DCTLINFO_V2_W3_ALL); + h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_ALL); + h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_ALL); + h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_ALL); + h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_ALL); + h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL); + h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL); + h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL); + h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL); + h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); + +int rtw89_fw_h2c_default_dmac_tbl_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_dctlinfo_ud_v3 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V3_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V3_C0_OP); + + h2c->m0 = cpu_to_le32(DCTLINFO_V3_W0_ALL); + h2c->m1 = cpu_to_le32(DCTLINFO_V3_W1_ALL); + h2c->m2 = cpu_to_le32(DCTLINFO_V3_W2_ALL); + h2c->m3 = cpu_to_le32(DCTLINFO_V3_W3_ALL); + h2c->m4 = cpu_to_le32(DCTLINFO_V3_W4_ALL); + h2c->m5 = cpu_to_le32(DCTLINFO_V3_W5_ALL); + h2c->m6 = cpu_to_le32(DCTLINFO_V3_W6_ALL); + h2c->m7 = cpu_to_le32(DCTLINFO_V3_W7_ALL); + h2c->m8 = cpu_to_le32(DCTLINFO_V3_W8_ALL); + h2c->m9 = cpu_to_le32(DCTLINFO_V3_W9_ALL); + h2c->m10 = cpu_to_le32(DCTLINFO_V3_W10_ALL); + h2c->m11 = cpu_to_le32(DCTLINFO_V3_W11_ALL); + h2c->m12 = cpu_to_le32(DCTLINFO_V3_W12_ALL); + h2c->m13 = cpu_to_le32(DCTLINFO_V3_W13_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V3, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v3); + +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + bool valid, struct ieee80211_ampdu_params *params) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ba_cam *h2c; + u8 macid = rtwsta_link->mac_id; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 entry_idx; + int ret; + + ret = valid ? + rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx) : + rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx); + if (ret) { + /* it still works even if we don't have static BA CAM, because + * hardware can create dynamic BA CAM automatically. + */ + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "failed to %s entry tid=%d for h2c ba cam\n", + valid ? "alloc" : "free", params->tid); + return 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_ba_cam *)skb->data; + + h2c->w0 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_W0_MACID); + if (chip->bacam_ver == RTW89_BACAM_V0_EXT) + h2c->w1 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1); + else + h2c->w0 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W0_ENTRY_IDX); + if (!valid) + goto end; + h2c->w0 |= le32_encode_bits(valid, RTW89_H2C_BA_CAM_W0_VALID) | + le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_W0_TID); + if (params->buf_size > 64) + h2c->w0 |= le32_encode_bits(4, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); + else + h2c->w0 |= le32_encode_bits(0, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); + /* If init req is set, hw will set the ssn */ + h2c->w0 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_INIT_REQ) | + le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_W0_SSN); + + if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { + h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) | + le32_encode_bits(rtwvif_link->mac_idx, + RTW89_H2C_BA_CAM_W1_BAND); + } + +end: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_BA_CAM, + H2C_FUNC_MAC_BA_CAM, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam); + +static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev, + u8 entry_idx, u8 uid) +{ + struct rtw89_h2c_ba_cam *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_ba_cam *)skb->data; + + h2c->w0 = le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_VALID); + h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1) | + le32_encode_bits(uid, RTW89_H2C_BA_CAM_W1_UID) | + le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_BAND) | + le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_STD_EN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_BA_CAM, + H2C_FUNC_MAC_BA_CAM, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 entry_idx = chip->bacam_num; + u8 uid = 0; + int i; + + for (i = 0; i < chip->bacam_dynamic_num; i++) { + rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid); + entry_idx++; + uid++; + } +} + +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + bool valid, struct ieee80211_ampdu_params *params) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ba_cam_v1 *h2c; + u8 macid = rtwsta_link->mac_id; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 entry_idx; + u8 bmap_size; + int ret; + + ret = valid ? + rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx) : + rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx); + if (ret) { + /* it still works even if we don't have static BA CAM, because + * hardware can create dynamic BA CAM automatically. + */ + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "failed to %s entry tid=%d for h2c ba cam\n", + valid ? "alloc" : "free", params->tid); + return 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data; + + if (params->buf_size > 512) + bmap_size = 10; + else if (params->buf_size > 256) + bmap_size = 8; + else if (params->buf_size > 64) + bmap_size = 4; + else + bmap_size = 0; + + h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) | + le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) | + le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) | + le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) | + le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) | + le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK); + + entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */ + h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) | + le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) | + le32_encode_bits(!!rtwvif_link->mac_idx, + RTW89_H2C_BA_CAM_V1_W1_BAND_SEL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_BA_CAM, + H2C_FUNC_MAC_BA_CAM_V1, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_v1); + +int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, + u8 offset, u8 mac_idx) +{ + struct rtw89_h2c_ba_cam_init *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam init\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_ba_cam_init *)skb->data; + + h2c->w0 = le32_encode_bits(users, RTW89_H2C_BA_CAM_INIT_USERS_MASK) | + le32_encode_bits(offset, RTW89_H2C_BA_CAM_INIT_OFFSET_MASK) | + le32_encode_bits(mac_idx, RTW89_H2C_BA_CAM_INIT_BAND_SEL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_BA_CAM, + H2C_FUNC_MAC_BA_CAM_INIT, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LOG_CFG_LEN 12 +int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) +{ + struct sk_buff *skb; + u32 comp = 0; + int ret; + + if (enable) + comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | + BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) | + BIT(RTW89_FW_LOG_COMP_MLO) | BIT(RTW89_FW_LOG_COMP_SCAN); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_LOG_CFG_LEN); + SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD); + SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); + SET_LOG_CFG_COMP(skb->data, comp); + SET_LOG_CFG_COMP_EXT(skb->data, 0); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_FW_INFO, + H2C_FUNC_LOG_CFG, 0, 0, + H2C_LOG_CFG_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, + 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03}; + u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_eapol_2_of_2 *eapol_pkt; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_hdr_3addr *hdr; + struct sk_buff *skb; + u8 key_des_ver; + + if (rtw_wow->ptk_alg == 3) + key_des_ver = 1; + else if (rtw_wow->akm == 1 || rtw_wow->akm == 2) + key_des_ver = 2; + else if (rtw_wow->akm > 2 && rtw_wow->akm < 7) + key_des_ver = 3; + else + key_des_ver = 0; + + skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*eapol_pkt)); + if (!skb) + return NULL; + + hdr = skb_put_zero(skb, sizeof(*hdr)); + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_FCTL_TODS | + IEEE80211_FCTL_PROTECTED); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + ether_addr_copy(hdr->addr1, bss_conf->bssid); + ether_addr_copy(hdr->addr2, bss_conf->addr); + ether_addr_copy(hdr->addr3, bss_conf->bssid); + + rcu_read_unlock(); + + skb_put_zero(skb, sec_hdr_len); + + eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt)); + memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody)); + eapol_pkt->key_des_ver = key_des_ver; + + return skb; +} + +static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_hdr_3addr *hdr; + struct rtw89_sa_query *sa_query; + struct sk_buff *skb; + + skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*sa_query)); + if (!skb) + return NULL; + + hdr = skb_put_zero(skb, sizeof(*hdr)); + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION | + IEEE80211_FCTL_PROTECTED); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + ether_addr_copy(hdr->addr1, bss_conf->bssid); + ether_addr_copy(hdr->addr2, bss_conf->addr); + ether_addr_copy(hdr->addr3, bss_conf->bssid); + + rcu_read_unlock(); + + skb_put_zero(skb, sec_hdr_len); + + sa_query = skb_put_zero(skb, sizeof(*sa_query)); + sa_query->category = WLAN_CATEGORY_SA_QUERY; + sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE; + + return skb; +} + +static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct ieee80211_hdr_3addr *hdr; + struct rtw89_arp_rsp *arp_skb; + struct arphdr *arp_hdr; + struct sk_buff *skb; + bool with_qos; + u16 fc; + + with_qos = ieee80211_vif_is_mld(vif); + + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[arp_reply] with qos field: %s\n", + str_yes_no(with_qos)); + + skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb) + + (with_qos ? 2 : 0)); + if (!skb) + return NULL; + + hdr = skb_put_zero(skb, sizeof(*hdr)); + + fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; + + if (rtw_wow->ptk_alg) + fc |= IEEE80211_FCTL_PROTECTED; + + if (with_qos) + fc |= IEEE80211_STYPE_QOS_DATA; + else + fc |= IEEE80211_STYPE_DATA; + + hdr->frame_control = cpu_to_le16(fc); + + ether_addr_copy(hdr->addr1, rtwvif_link->bssid); + ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr); + ether_addr_copy(hdr->addr3, rtwvif_link->bssid); + + if (with_qos) + skb_put_zero(skb, sizeof(__le16)); + + if (sec_hdr_len) + skb_put_zero(skb, sec_hdr_len); + + arp_skb = skb_put_zero(skb, sizeof(*arp_skb)); + memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); + arp_skb->llc_type = htons(ETH_P_ARP); + + arp_hdr = &arp_skb->arp_hdr; + arp_hdr->ar_hrd = htons(ARPHRD_ETHER); + arp_hdr->ar_pro = htons(ETH_P_IP); + arp_hdr->ar_hln = ETH_ALEN; + arp_hdr->ar_pln = 4; + arp_hdr->ar_op = htons(ARPOP_REPLY); + + ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr); + arp_skb->sender_ip = rtwvif->ip_addr; + ether_addr_copy(arp_skb->target_hw, rtwvif->mac_addr); + arp_skb->target_ip = rtwvif->ip_addr; + + return skb; +} + +static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + enum rtw89_fw_pkt_ofld_type type, + u8 *id) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1; + struct rtw89_pktofld_info *info; + struct sk_buff *skb; + int ret; + + info = kzalloc_obj(*info); + if (!info) + return -ENOMEM; + + switch (type) { + case RTW89_PKT_OFLD_TYPE_PS_POLL: + skb = ieee80211_pspoll_get(rtwdev->hw, vif); + break; + case RTW89_PKT_OFLD_TYPE_PROBE_RSP: + skb = ieee80211_proberesp_get(rtwdev->hw, vif); + break; + case RTW89_PKT_OFLD_TYPE_NULL_DATA: + skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, false); + break; + case RTW89_PKT_OFLD_TYPE_QOS_NULL: + skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, true); + break; + case RTW89_PKT_OFLD_TYPE_EAPOL_KEY: + skb = rtw89_eapol_get(rtwdev, rtwvif_link); + break; + case RTW89_PKT_OFLD_TYPE_SA_QUERY: + skb = rtw89_sa_query_get(rtwdev, rtwvif_link); + break; + case RTW89_PKT_OFLD_TYPE_ARP_RSP: + skb = rtw89_arp_response_get(rtwdev, rtwvif_link); + break; + default: + goto err; + } + + if (!skb) + goto err; + + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); + kfree_skb(skb); + + if (ret) + goto err; + + list_add_tail(&info->list, &rtwvif_link->general_pkt_list); + *id = info->id; + return 0; + +err: + kfree(info); + return -ENOMEM; +} + +void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool notify_fw) +{ + struct list_head *pkt_list = &rtwvif_link->general_pkt_list; + struct rtw89_pktofld_info *info, *tmp; + + list_for_each_entry_safe(info, tmp, pkt_list, list) { + if (notify_fw) + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + else + rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); + list_del(&info->list); + kfree(info); + } +} + +void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, + notify_fw); +} + +#define H2C_GENERAL_PKT_LEN 6 +#define H2C_GENERAL_PKT_ID_UND 0xff +int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u8 macid) +{ + u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; + u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; + u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; + struct sk_buff *skb; + int ret; + + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_GENERAL_PKT_LEN); + SET_GENERAL_PKT_MACID(skb->data, macid); + SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); + SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); + SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); + SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); + SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_FW_INFO, + H2C_FUNC_MAC_GENERAL_PKT, 0, 1, + H2C_GENERAL_PKT_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LPS_PARM_LEN 8 +int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, + struct rtw89_lps_parm *lps_param) +{ + struct sk_buff *skb; + bool done_ack; + int ret; + + if (RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw)) + done_ack = false; + else + done_ack = !lps_param->psmode; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_LPS_PARM_LEN); + + SET_LPS_PARM_MACID(skb->data, lps_param->macid); + SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); + SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); + SET_LPS_PARM_RLBM(skb->data, 1); + SET_LPS_PARM_SMARTPS(skb->data, 1); + SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); + SET_LPS_PARM_VOUAPSD(skb->data, 0); + SET_LPS_PARM_VIUAPSD(skb->data, 0); + SET_LPS_PARM_BEUAPSD(skb->data, 0); + SET_LPS_PARM_BKUAPSD(skb->data, 0); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_PS, + H2C_FUNC_MAC_LPS_PARM, 0, done_ack, + H2C_LPS_PARM_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_chan *chan; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_h2c_lps_ch_info *h2c; + u32 len = sizeof(*h2c); + unsigned int link_id; + struct sk_buff *skb; + bool no_chan = true; + u8 phy_idx; + u32 done; + int ret; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ch_info\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_lps_ch_info *)skb->data; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + phy_idx = rtwvif_link->phy_idx; + if (phy_idx >= ARRAY_SIZE(h2c->info)) + continue; + + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + no_chan = false; + + h2c->info[phy_idx].central_ch = chan->channel; + h2c->info[phy_idx].pri_ch = chan->primary_channel; + h2c->info[phy_idx].band = chan->band_type; + h2c->info[phy_idx].bw = chan->band_width; + } + + if (no_chan) { + rtw89_err(rtwdev, "no chan for h2c lps_ch_info\n"); + ret = -ENOENT; + goto fail; + } + + h2c->mlo_dbcc_mode_lps = cpu_to_le32(rtwdev->mlo_dbcc_mode); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, + H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len); + + rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, + true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); + if (ret) + rtw89_warn(rtwdev, "h2c_lps_ch_info done polling timeout\n"); + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_h2c_lps_ml_cmn_info *h2c; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_pkt_stat *pkt_stat; + const struct rtw89_chan *chan; + u8 bw_idx = RTW89_BB_BW_20_40; + struct rtw89_bb_ctx *bb; + u32 len = sizeof(*h2c); + unsigned int link_id; + struct sk_buff *skb; + u8 beacon_bw_ofst; + u8 gain_band; + u32 done; + u8 path; + int ret; + int i; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data; + + h2c->fmt_id = 0x3; + + h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c->rfe_type = efuse->rfe_type; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A; + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + + h2c->central_ch[rtwvif_link->phy_idx] = chan->channel; + h2c->pri_ch[rtwvif_link->phy_idx] = chan->primary_channel; + h2c->band[rtwvif_link->phy_idx] = chan->band_type; + h2c->bw[rtwvif_link->phy_idx] = chan->band_width; + + pkt_stat = &bb->cur_pkt_stat; + if (pkt_stat->beacon_rate < RTW89_HW_RATE_OFDM6) + h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x1; + else + h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x2; + + /* Fill BW20 RX gain table for beacon mode */ + for (i = 0; i < TIA_GAIN_NUM; i++) { + h2c->tia_gain[rtwvif_link->phy_idx][i] = + cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); + } + + if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { + beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; + h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst; + } + + memcpy(h2c->lna_gain[rtwvif_link->phy_idx], + gain->lna_gain[gain_band][bw_idx][path], + LNA_GAIN_NUM); + memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx], + gain->tia_lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM + 1); + memcpy(h2c->lna_op1db[rtwvif_link->phy_idx], + gain->lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, + H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); + + rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, + true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); + if (ret) + rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +void rtw89_bb_lps_cmn_info_rx_gain_fill(struct rtw89_dev *rtwdev, + struct rtw89_bb_link_info_rx_gain *h2c_gain, + const struct rtw89_chan *chan, u8 phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + enum rtw89_bb_link_rx_gain_table_type tab_idx; + struct rtw89_chan chan_bcn; + u8 bw = chan->band_width; + u8 gain_band; + u8 bw_idx; + u8 path; + int i; + + rtw89_chan_create(&chan_bcn, chan->primary_channel, chan->primary_channel, + chan->band_type, RTW89_CHANNEL_WIDTH_20); + + for (tab_idx = RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_A; + tab_idx < RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX; tab_idx++) { + struct rtw89_phy_calc_efuse_gain calc = {}; + + path = (tab_idx & BIT(0)) ? (RF_PATH_B) : (RF_PATH_A); + if (tab_idx & BIT(1)) { + rtw89_chip_calc_rx_gain_normal(rtwdev, chan, path, phy_idx, + &calc); + gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + if (bw > RTW89_CHANNEL_WIDTH_40) + bw_idx = RTW89_BB_BW_80_160_320; + else + bw_idx = RTW89_BB_BW_20_40; + } else { + rtw89_chip_calc_rx_gain_normal(rtwdev, &chan_bcn, path, phy_idx, + &calc); + gain_band = rtw89_subband_to_gain_band_be(chan_bcn.subband_type); + bw_idx = RTW89_BB_BW_20_40; + } + + /* efuse ofst and comp */ + h2c_gain->gain_ofst[tab_idx] = calc.rssi_ofst; + h2c_gain->cck_gain_ofst[tab_idx] = calc.cck_rpl_ofst; + h2c_gain->cck_rpl_bias_comp[tab_idx][0] = calc.cck_mean_gain_bias; + h2c_gain->cck_rpl_bias_comp[tab_idx][1] = calc.cck_mean_gain_bias; + + for (i = 0; i < TIA_GAIN_NUM; i++) { + h2c_gain->gain_err_tia[tab_idx][i] = + cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); + } + memcpy(h2c_gain->gain_err_lna[tab_idx], + gain->lna_gain[gain_band][bw_idx][path], + LNA_GAIN_NUM); + memcpy(h2c_gain->op1db_lna[tab_idx], + gain->lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM); + memcpy(h2c_gain->op1db_tia[tab_idx], + gain->tia_lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM + 1); + + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._20M, + gain->rpl_ofst_20[gain_band][path], + RTW89_BW20_SC_20M); + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._40M, + gain->rpl_ofst_40[gain_band][path], + RTW89_BW20_SC_40M); + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._80M, + gain->rpl_ofst_80[gain_band][path], + RTW89_BW20_SC_80M); + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._160M, + gain->rpl_ofst_160[gain_band][path], + RTW89_BW20_SC_160M); + } +} + +int rtw89_fw_h2c_lps_ml_cmn_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif) +{ + static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_h2c_lps_ml_cmn_info_v1 *h2c; + struct rtw89_vif_link *rtwvif_link; + const struct rtw89_chan *chan; + struct rtw89_bb_ctx *bb; + u32 len = sizeof(*h2c); + unsigned int link_id; + struct sk_buff *skb; + u8 beacon_bw_ofst; + u32 done; + int ret; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info_v1\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_lps_ml_cmn_info_v1 *)skb->data; + + h2c->fmt_id = 0x20; + + h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c->rfe_type = efuse->rfe_type; + h2c->rssi_main = U8_MAX; + + memset(h2c->link_id, RTW89_BB_PS_LINK_ID_SKIP, RTW89_BB_PS_LINK_BUF_MAX); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + u8 phy_idx = rtwvif_link->phy_idx; + + bb = rtw89_get_bb_ctx(rtwdev, phy_idx); + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + + h2c->link_id[phy_idx] = link_id; + h2c->central_ch[phy_idx] = chan->channel; + h2c->pri_ch[phy_idx] = chan->primary_channel; + h2c->band[phy_idx] = chan->band_type; + h2c->bw[phy_idx] = chan->band_width; + + if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { + beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; + h2c->dup_bcn_ofst[phy_idx] = beacon_bw_ofst; + } + + if (h2c->rssi_main > bb->ch_info.rssi_min) + h2c->rssi_main = bb->ch_info.rssi_min; + + rtw89_bb_lps_cmn_info_rx_gain_fill(rtwdev, + &h2c->rx_gain[phy_idx], + chan, phy_idx); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, + H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); + + rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT, 0); + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, + true, rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT); + if (ret) + rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_P2P_ACT_LEN 20 +int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_p2p_noa_desc *desc, + u8 act, u8 noa_id, u8 ctwindow_oppps) +{ + bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; + struct sk_buff *skb; + u8 *cmd; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); + return -ENOMEM; + } + skb_put(skb, H2C_P2P_ACT_LEN); + cmd = skb->data; + + RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id); + RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); + RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); + RTW89_SET_FWCMD_P2P_ACT(cmd, act); + RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc); + RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0); + if (desc) { + RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time); + RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval); + RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration); + RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count); + RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_PS, + H2C_FUNC_P2P_ACT, 0, 0, + H2C_P2P_ACT_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + u8 ntx_path; + u8 map_b; + + if (chip->rf_path_num == 1) { + ntx_path = RF_A; + map_b = 0; + } else { + ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB; + map_b = ntx_path == RF_AB ? 1 : 0; + } + + SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); + SET_CMC_TBL_PATH_MAP_A(skb->data, 0); + SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); + SET_CMC_TBL_PATH_MAP_C(skb->data, 0); + SET_CMC_TBL_PATH_MAP_D(skb->data, 0); +} + +#define H2C_CMC_TBL_LEN 68 +int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_CMC_TBL_LEN); + SET_CTRL_INFO_MACID(skb->data, macid); + SET_CTRL_INFO_OPERATION(skb->data, 1); + if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { + SET_CMC_TBL_TXPWR_MODE(skb->data, 0); + __rtw89_fw_h2c_set_tx_path(rtwdev, skb); + SET_CMC_TBL_ANTSEL_A(skb->data, 0); + SET_CMC_TBL_ANTSEL_B(skb->data, 0); + SET_CMC_TBL_ANTSEL_C(skb->data, 0); + SET_CMC_TBL_ANTSEL_D(skb->data, 0); + } + SET_CMC_TBL_MGQ_RPT_EN(skb->data, rtwdev->hci.tx_rpt_enabled); + SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); + SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + SET_CMC_TBL_DATA_DCM(skb->data, 0); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + chip->h2c_cctl_func_id, 0, 1, + H2C_CMC_TBL_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl); + +int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | + le32_encode_bits(1, CCTLINFO_G7_C0_OP); + + h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE) | + le32_encode_bits(rtwdev->hci.tx_rpt_enabled, CCTLINFO_G7_W0_MGQ_RPT_EN); + h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL); + + h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) | + le32_encode_bits(0xa, CCTLINFO_G7_W1_RTSRATE) | + le32_encode_bits(4, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_ALL); + + h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_ALL); + + h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_ALL); + + h2c->w4 = le32_encode_bits(0xFFFF, CCTLINFO_G7_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ALL); + + h2c->w5 = le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | + le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | + le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | + le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | + le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); + h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_ALL); + + h2c->w6 = le32_encode_bits(0xb, CCTLINFO_G7_W6_RESP_REF_RATE); + h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ALL); + + h2c->w7 = le32_encode_bits(1, CCTLINFO_G7_W7_NC) | + le32_encode_bits(1, CCTLINFO_G7_W7_NR) | + le32_encode_bits(1, CCTLINFO_G7_W7_CB) | + le32_encode_bits(0x1, CCTLINFO_G7_W7_CSI_PARA_EN) | + le32_encode_bits(0xb, CCTLINFO_G7_W7_CSI_FIX_RATE); + h2c->m7 = cpu_to_le32(CCTLINFO_G7_W7_ALL); + + h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_ALL); + + h2c->w14 = le32_encode_bits(0, CCTLINFO_G7_W14_VO_CURR_RATE) | + le32_encode_bits(0, CCTLINFO_G7_W14_VI_CURR_RATE) | + le32_encode_bits(0, CCTLINFO_G7_W14_BE_CURR_RATE_L); + h2c->m14 = cpu_to_le32(CCTLINFO_G7_W14_ALL); + + h2c->w15 = le32_encode_bits(0, CCTLINFO_G7_W15_BE_CURR_RATE_H) | + le32_encode_bits(0, CCTLINFO_G7_W15_BK_CURR_RATE) | + le32_encode_bits(0, CCTLINFO_G7_W15_MGNT_CURR_RATE); + h2c->m15 = cpu_to_le32(CCTLINFO_G7_W15_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7); + +int rtw89_fw_h2c_default_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + bool preld = rtw89_mac_chk_preload_allow(rtwdev); + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for default cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w0 = le32_encode_bits(4, BE_CCTL_INFO_W0_DATARATE); + h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_ALL); + + h2c->w1 = le32_encode_bits(4, BE_CCTL_INFO_W1_DATA_RTY_LOWEST_RATE) | + le32_encode_bits(0xa, BE_CCTL_INFO_W1_RTSRATE) | + le32_encode_bits(4, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_ALL); + + h2c->w2 = le32_encode_bits(preld, BE_CCTL_INFO_W2_PRELOAD_ENABLE); + h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_ALL); + + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_ALL); + + h2c->w4 = le32_encode_bits(0xFFFF, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ALL); + + h2c->w5 = le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_ALL); + + h2c->w6 = le32_encode_bits(0xb, BE_CCTL_INFO_W6_RESP_REF_RATE); + h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_ALL); + + h2c->w7 = le32_encode_bits(1, BE_CCTL_INFO_W7_NC) | + le32_encode_bits(1, BE_CCTL_INFO_W7_NR) | + le32_encode_bits(1, BE_CCTL_INFO_W7_CB) | + le32_encode_bits(0x1, BE_CCTL_INFO_W7_CSI_PARA_EN) | + le32_encode_bits(0xb, BE_CCTL_INFO_W7_CSI_FIX_RATE); + h2c->m7 = cpu_to_le32(BE_CCTL_INFO_W7_ALL); + + h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_ALL); + + h2c->w14 = le32_encode_bits(0, BE_CCTL_INFO_W14_VO_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W14_VI_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W14_BE_CURR_RATE_L); + h2c->m14 = cpu_to_le32(BE_CCTL_INFO_W14_ALL); + + h2c->w15 = le32_encode_bits(0, BE_CCTL_INFO_W15_BE_CURR_RATE_H) | + le32_encode_bits(0, BE_CCTL_INFO_W15_BK_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W15_MGNT_CURR_RATE); + h2c->m15 = cpu_to_le32(BE_CCTL_INFO_W15_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_be); + +static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, + struct ieee80211_link_sta *link_sta, + u8 *pads) +{ + bool ppe_th; + u8 ppe16, ppe8; + u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; + u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0]; + u8 ru_bitmap; + u8 n, idx, sh; + u16 ppe; + int i; + + ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, + link_sta->he_cap.he_cap_elem.phy_cap_info[6]); + if (!ppe_th) { + u8 pad; + + pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, + link_sta->he_cap.he_cap_elem.phy_cap_info[9]); + + for (i = 0; i < RTW89_PPE_BW_NUM; i++) + pads[i] = pad; + + return; + } + + ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); + n = hweight8(ru_bitmap); + n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; + + for (i = 0; i < RTW89_PPE_BW_NUM; i++) { + if (!(ru_bitmap & BIT(i))) { + pads[i] = 1; + continue; + } + + idx = n >> 3; + sh = n & 7; + n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; + + ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx])); + ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; + sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; + ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; + + if (ppe16 != 7 && ppe8 == 7) + pads[i] = RTW89_PE_DURATION_16; + else if (ppe8 != 7) + pads[i] = RTW89_PE_DURATION_8; + else + pads[i] = RTW89_PE_DURATION_0; + } +} + +int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct ieee80211_link_sta *link_sta; + struct sk_buff *skb; + u8 pads[RTW89_PPE_BW_NUM]; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + u16 lowest_rate; + int ret; + + memset(pads, 0, sizeof(pads)); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + if (rtwsta_link) + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (rtwsta_link && link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + skb_put(skb, H2C_CMC_TBL_LEN); + SET_CTRL_INFO_MACID(skb->data, mac_id); + SET_CTRL_INFO_OPERATION(skb->data, 1); + SET_CMC_TBL_DISRTSFB(skb->data, 1); + SET_CMC_TBL_DISDATAFB(skb->data, 1); + SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate); + SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); + SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); + if (vif->type == NL80211_IFTYPE_STATION) + SET_CMC_TBL_ULDL(skb->data, 1); + else + SET_CMC_TBL_ULDL(skb->data, 0); + SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port); + if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { + SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); + SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); + SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); + SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); + } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { + SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); + SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); + SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); + SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); + } + if (rtwsta_link) + SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, + link_sta->he_cap.has_he); + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + SET_CMC_TBL_DATA_DCM(skb->data, 0); + + rcu_read_unlock(); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + chip->h2c_cctl_func_id, 0, 1, + H2C_CMC_TBL_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl); + +static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, + struct ieee80211_link_sta *link_sta, + u8 *pads) +{ + u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; + u16 ppe_thres_hdr; + u8 ppe16, ppe8; + u8 n, idx, sh; + u8 ru_bitmap; + bool ppe_th; + u16 ppe; + int i; + + ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], + IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT); + if (!ppe_th) { + u8 pad; + + pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], + IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); + + for (i = 0; i < RTW89_PPE_BW_NUM; i++) + pads[i] = pad; + + return; + } + + ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres); + ru_bitmap = u16_get_bits(ppe_thres_hdr, + IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); + n = hweight8(ru_bitmap); + n = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE + + (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2) * nss; + + for (i = 0; i < RTW89_PPE_BW_NUM; i++) { + if (!(ru_bitmap & BIT(i))) { + pads[i] = 1; + continue; + } + + idx = n >> 3; + sh = n & 7; + n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2; + + ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx); + ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; + sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE; + ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; + + if (ppe16 != 7 && ppe8 == 7) + pads[i] = RTW89_PE_DURATION_16_20; + else if (ppe8 != 7) + pads[i] = RTW89_PE_DURATION_8; + else + pads[i] = RTW89_PE_DURATION_0; + } +} + +int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; + u8 pads[RTW89_PPE_BW_NUM]; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 lowest_rate; + int ret; + + memset(pads, 0, sizeof(pads)); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); + else if (link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); + } + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | + le32_encode_bits(1, CCTLINFO_G7_C0_OP); + + h2c->w0 = le32_encode_bits(1, CCTLINFO_G7_W0_DISRTSFB) | + le32_encode_bits(1, CCTLINFO_G7_W0_DISDATAFB); + h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_DISRTSFB | + CCTLINFO_G7_W0_DISDATAFB); + + h2c->w1 = le32_encode_bits(lowest_rate, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); + + h2c->w2 = le32_encode_bits(0, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); + h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); + + h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); + h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); + + h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID); + h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID); + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { + h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM); + h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM); + } + + if (bss_conf->eht_support) { + u16 punct = bss_conf->chanreq.oper.punctured; + + h2c->w4 |= le32_encode_bits(~punct, + CCTLINFO_G7_W4_ACT_SUBCH_CBW); + h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); + } + + h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); + h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 | + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 | + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 | + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 | + CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); + + h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) | + le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, + CCTLINFO_G7_W6_ULDL); + h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL); + + if (rtwsta_link) { + h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, + CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); + h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); + } + + rcu_read_unlock(); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7); + +int rtw89_fw_h2c_assoc_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_cctlinfo_ud_be *h2c; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; + u8 pads[RTW89_PPE_BW_NUM]; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 lowest_rate; + int ret; + + memset(pads, 0, sizeof(pads)); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for assoc cmac be\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); + else if (link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); + } + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w0 = le32_encode_bits(1, BE_CCTL_INFO_W0_DISRTSFB) | + le32_encode_bits(1, BE_CCTL_INFO_W0_DISDATAFB); + h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_DISRTSFB | + BE_CCTL_INFO_W0_DISDATAFB); + + h2c->w1 = le32_encode_bits(lowest_rate, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + + h2c->w2 = le32_encode_bits(0, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); + h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); + + h2c->w3 = le32_encode_bits(0, BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); + + h2c->w4 = le32_encode_bits(rtwvif_link->port, BE_CCTL_INFO_W4_MULTI_PORT_ID); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_MULTI_PORT_ID); + + if (bss_conf->eht_support) { + u16 punct = bss_conf->chanreq.oper.punctured; + + h2c->w4 |= le32_encode_bits(~punct, + BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 |= cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + } + + h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { + h2c->w5 |= le32_encode_bits(0, BE_CCTL_INFO_W5_DATA_DCM_V1); + h2c->m5 |= cpu_to_le32(BE_CCTL_INFO_W5_DATA_DCM_V1); + } + + h2c->w6 = le32_encode_bits(vif->cfg.aid, BE_CCTL_INFO_W6_AID12_PAID) | + le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, + BE_CCTL_INFO_W6_ULDL); + h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_AID12_PAID | BE_CCTL_INFO_W6_ULDL); + + if (rtwsta_link) { + h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, + BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); + h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); + } + + rcu_read_unlock(); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_be); + +int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 agg_num = 0; + u8 ba_bmap = 0; + int ret; + u8 tid; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; + + for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { + if (agg_num == 0) + agg_num = rtwsta->ampdu_params[tid].agg_num; + else + agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); + } + + if (agg_num <= 0x20) + ba_bmap = 3; + else if (agg_num > 0x20 && agg_num <= 0x40) + ba_bmap = 0; + else if (agg_num > 0x40 && agg_num <= 0x80) + ba_bmap = 1; + else if (agg_num > 0x80 && agg_num <= 0x100) + ba_bmap = 2; + else if (agg_num > 0x100 && agg_num <= 0x200) + ba_bmap = 4; + else if (agg_num > 0x200 && agg_num <= 0x400) + ba_bmap = 5; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | + le32_encode_bits(1, CCTLINFO_G7_C0_OP); + + h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP); + h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7); + +int rtw89_fw_h2c_ampdu_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 agg_num = 0; + u8 ba_bmap = 0; + int ret; + u8 tid; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { + if (agg_num == 0) + agg_num = rtwsta->ampdu_params[tid].agg_num; + else + agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); + } + + if (agg_num <= 0x20) + ba_bmap = 3; + else if (agg_num > 0x20 && agg_num <= 0x40) + ba_bmap = 0; + else if (agg_num > 0x40 && agg_num <= 0x80) + ba_bmap = 1; + else if (agg_num > 0x80 && agg_num <= 0x100) + ba_bmap = 2; + else if (agg_num > 0x100 && agg_num <= 0x200) + ba_bmap = 4; + else if (agg_num > 0x200 && agg_num <= 0x400) + ba_bmap = 5; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w3 = le32_encode_bits(ba_bmap, BE_CCTL_INFO_W3_BA_BMAP); + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_BA_BMAP); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_be); + +int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_CMC_TBL_LEN); + SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); + SET_CTRL_INFO_OPERATION(skb->data, 1); + if (rtwsta_link->cctl_tx_time) { + SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); + SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time); + } + if (rtwsta_link->cctl_tx_retry_limit) { + SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); + SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + chip->h2c_cctl_func_id, 0, 1, + H2C_CMC_TBL_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl); + +int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | + le32_encode_bits(1, CCTLINFO_G7_C0_OP); + + if (rtwsta_link->cctl_tx_time) { + h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL); + h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL); + + h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, + CCTLINFO_G7_W2_AMPDU_MAX_TIME); + h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME); + } + if (rtwsta_link->cctl_tx_retry_limit) { + h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) | + le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, + CCTLINFO_G7_W2_DATA_TX_CNT_LMT); + h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL | + CCTLINFO_G7_W2_DATA_TX_CNT_LMT); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7); + +int rtw89_fw_h2c_txtime_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + if (rtwsta_link->cctl_tx_time) { + h2c->w3 |= le32_encode_bits(1, BE_CCTL_INFO_W3_AMPDU_TIME_SEL); + h2c->m3 |= cpu_to_le32(BE_CCTL_INFO_W3_AMPDU_TIME_SEL); + + h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, + BE_CCTL_INFO_W2_AMPDU_MAX_TIME); + h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_AMPDU_MAX_TIME); + } + if (rtwsta_link->cctl_tx_retry_limit) { + h2c->w2 |= le32_encode_bits(1, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL) | + le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, + BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); + h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL | + BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_be); + +int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured) +{ + struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for punctured cmac g7\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; + + h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, CCTLINFO_G7_C0_MACID) | + le32_encode_bits(1, CCTLINFO_G7_C0_OP); + + h2c->w4 = le32_encode_bits(~punctured, CCTLINFO_G7_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7); + +int rtw89_fw_h2c_punctured_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured) +{ + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for punctured cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w4 = le32_encode_bits(~punctured, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_be); + +int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + int ret; + + if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_CMC_TBL_LEN); + SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); + SET_CTRL_INFO_OPERATION(skb->data, 1); + + __rtw89_fw_h2c_set_tx_path(rtwdev, skb); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, + H2C_CMC_TBL_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_h2c_bcn_upd *h2c; + struct sk_buff *skb_beacon; + struct ieee80211_hdr *hdr; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int bcn_total_len; + u16 beacon_rate; + u16 tim_offset; + void *noa_data; + u8 noa_len; + int ret; + + if (vif->p2p) + beacon_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + beacon_rate = RTW89_HW_RATE_CCK1; + else + beacon_rate = RTW89_HW_RATE_OFDM6; + + skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, + NULL, 0); + if (!skb_beacon) { + rtw89_err(rtwdev, "failed to get beacon skb\n"); + return -ENOMEM; + } + + noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); + if (noa_len && + (noa_len <= skb_tailroom(skb_beacon) || + pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { + skb_put_data(skb_beacon, noa_data, noa_len); + } + + hdr = (struct ieee80211_hdr *)skb_beacon; + tim_offset -= ieee80211_hdrlen(hdr->frame_control); + + bcn_total_len = len + skb_beacon->len; + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + dev_kfree_skb_any(skb_beacon); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_bcn_upd *)skb->data; + + h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) | + le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) | + le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST); + h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) | + le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) | + le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) | + le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE); + + skb_put_data(skb, skb_beacon->data, skb_beacon->len); + dev_kfree_skb_any(skb_beacon); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_BCN_UPD, 0, 1, + bcn_total_len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon); + +int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_h2c_bcn_upd_be *h2c; + struct sk_buff *skb_beacon; + struct ieee80211_hdr *hdr; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int bcn_total_len; + u16 beacon_rate; + u16 tim_offset; + void *noa_data; + u8 noa_len; + int ret; + + if (vif->p2p) + beacon_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + beacon_rate = RTW89_HW_RATE_CCK1; + else + beacon_rate = RTW89_HW_RATE_OFDM6; + + skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, + NULL, 0); + if (!skb_beacon) { + rtw89_err(rtwdev, "failed to get beacon skb\n"); + return -ENOMEM; + } + + noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); + if (noa_len && + (noa_len <= skb_tailroom(skb_beacon) || + pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { + skb_put_data(skb_beacon, noa_data, noa_len); + } + + hdr = (struct ieee80211_hdr *)skb_beacon; + tim_offset -= ieee80211_hdrlen(hdr->frame_control); + + bcn_total_len = len + skb_beacon->len; + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + dev_kfree_skb_any(skb_beacon); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data; + + h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) | + le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) | + le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST); + h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) | + le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) | + le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) | + le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE); + + skb_put_data(skb, skb_beacon->data, skb_beacon->len); + dev_kfree_skb_any(skb_beacon); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_BCN_UPD_BE, 0, 1, + bcn_total_len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be); + +int rtw89_fw_h2c_tbtt_tuning(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u32 offset) +{ + struct rtw89_h2c_tbtt_tuning *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c tbtt tuning\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_tbtt_tuning *)skb->data; + + h2c->w0 = le32_encode_bits(rtwvif_link->phy_idx, RTW89_H2C_TBTT_TUNING_W0_BAND) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_TBTT_TUNING_W0_PORT); + h2c->w1 = le32_encode_bits(offset, RTW89_H2C_TBTT_TUNING_W1_SHIFT); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_PS, + H2C_FUNC_TBTT_TUNING, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_pwr_lvl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ +#define RTW89_BCN_TO_VAL_MIN 4 +#define RTW89_BCN_TO_VAL_MAX 64 +#define RTW89_DTIM_TO_VAL_MIN 7 +#define RTW89_DTIM_TO_VAL_MAX 15 + struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; + struct rtw89_h2c_pwr_lvl *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 bcn_to_val; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c pwr lvl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_pwr_lvl *)skb->data; + + bcn_to_val = clamp_t(u8, bcn_track->bcn_timeout, + RTW89_BCN_TO_VAL_MIN, RTW89_BCN_TO_VAL_MAX); + + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_PWR_LVL_W0_MACID) | + le32_encode_bits(bcn_to_val, RTW89_H2C_PWR_LVL_W0_BCN_TO_VAL) | + le32_encode_bits(0, RTW89_H2C_PWR_LVL_W0_PS_LVL) | + le32_encode_bits(0, RTW89_H2C_PWR_LVL_W0_TRX_LVL) | + le32_encode_bits(RTW89_DTIM_TO_VAL_MIN, + RTW89_H2C_PWR_LVL_W0_DTIM_TO_VAL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_PS, + H2C_FUNC_PS_POWER_LEVEL, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + enum rtw89_upd_mode upd_mode) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_role_maintain *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 self_role; + int ret; + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { + if (rtwsta_link) + self_role = RTW89_SELF_ROLE_AP_CLIENT; + else + self_role = rtwvif_link->self_role; + } else { + self_role = rtwvif_link->self_role; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_role_maintain *)skb->data; + + h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) | + le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) | + le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) | + le32_encode_bits(rtwvif_link->wifi_role, + RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) | + le32_encode_bits(rtwvif_link->mac_idx, + RTW89_H2C_ROLE_MAINTAIN_W0_BAND) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, + H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static enum rtw89_fw_sta_type +rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; + enum rtw89_fw_sta_type type; + + rcu_read_lock(); + + if (!rtwsta_link) + goto by_vif; + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + type = RTW89_FW_BE_STA; + else if (link_sta->he_cap.has_he) + type = RTW89_FW_AX_STA; + else + type = RTW89_FW_N_AC_STA; + + goto out; + +by_vif: + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (bss_conf->eht_support) + type = RTW89_FW_BE_STA; + else if (bss_conf->he_support) + type = RTW89_FW_AX_STA; + else + type = RTW89_FW_N_AC_STA; + +out: + rcu_read_unlock(); + + return type; +} + +int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool dis_conn) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + bool is_mld = ieee80211_vif_is_mld(vif); + u8 self_role = rtwvif_link->self_role; + enum rtw89_fw_sta_type sta_type; + u8 net_type = rtwvif_link->net_type; + struct rtw89_h2c_join_v1 *h2c_v1; + struct rtw89_h2c_join *h2c; + u32 len = sizeof(*h2c); + bool format_v1 = false; + struct sk_buff *skb; + u8 main_mac_id; + bool init_ps; + int ret; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { + len = sizeof(*h2c_v1); + format_v1 = true; + } + + if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) { + self_role = RTW89_SELF_ROLE_AP_CLIENT; + net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_join *)skb->data; + + h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) | + le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) | + le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) | + le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) | + le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) | + le32_encode_bits(rtwvif_link->wifi_role, + RTW89_H2C_JOININFO_W0_WIFI_ROLE) | + le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE); + + if (!format_v1) + goto done; + + h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data; + + sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link); + init_ps = rtwvif_link != rtw89_get_designated_link(rtwvif_link->rtwvif); + + if (rtwsta_link) + main_mac_id = rtw89_sta_get_main_macid(rtwsta_link->rtwsta); + else + main_mac_id = rtw89_vif_get_main_macid(rtwvif_link->rtwvif); + + h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE) | + le32_encode_bits(is_mld, RTW89_H2C_JOININFO_W1_IS_MLD) | + le32_encode_bits(main_mac_id, RTW89_H2C_JOININFO_W1_MAIN_MACID) | + le32_encode_bits(RTW89_H2C_JOININFO_MLO_MODE_MLSR, + RTW89_H2C_JOININFO_W1_MLO_MODE) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W1_EMLSR_CAB) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W1_NSTR_EN) | + le32_encode_bits(init_ps, RTW89_H2C_JOININFO_W1_INIT_PWR_STATE) | + le32_encode_bits(IEEE80211_EML_CAP_EML_PADDING_DELAY_256US, + RTW89_H2C_JOININFO_W1_EMLSR_PADDING) | + le32_encode_bits(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US, + RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MACID_EXT) | + le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT); + + h2c_v1->w2 = 0; + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, + H2C_FUNC_MAC_JOININFO, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en) +{ + struct rtw89_h2c_notify_dbcc *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_notify_dbcc *)skb->data; + + h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, + H2C_FUNC_NOTIFY_DBCC, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, + bool pause) +{ + struct rtw89_fw_macid_pause_sleep_grp *h2c_new; + struct rtw89_fw_macid_pause_grp *h2c; + __le32 set = cpu_to_le32(BIT(sh)); + u8 h2c_macid_pause_id; + struct sk_buff *skb; + u32 len; + int ret; + + if (RTW89_CHK_FW_FEATURE(MACID_PAUSE_SLEEP, &rtwdev->fw)) { + h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE_SLEEP; + len = sizeof(*h2c_new); + } else { + h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE; + len = sizeof(*h2c); + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c macid pause\n"); + return -ENOMEM; + } + skb_put(skb, len); + + if (h2c_macid_pause_id == H2C_FUNC_MAC_MACID_PAUSE_SLEEP) { + h2c_new = (struct rtw89_fw_macid_pause_sleep_grp *)skb->data; + + h2c_new->n[0].pause_mask_grp[grp] = set; + h2c_new->n[0].sleep_mask_grp[grp] = set; + if (pause) { + h2c_new->n[0].pause_grp[grp] = set; + h2c_new->n[0].sleep_grp[grp] = set; + } + } else { + h2c = (struct rtw89_fw_macid_pause_grp *)skb->data; + + h2c->mask_grp[grp] = set; + if (pause) + h2c->pause_grp[grp] = set; + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + h2c_macid_pause_id, 1, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_EDCA_LEN 12 +int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u8 ac, u32 val) +{ + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); + return -ENOMEM; + } + skb_put(skb, H2C_EDCA_LEN); + RTW89_SET_EDCA_SEL(skb->data, 0); + RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx); + RTW89_SET_EDCA_WMM(skb->data, 0); + RTW89_SET_EDCA_AC(skb->data, ac); + RTW89_SET_EDCA_PARAM(skb->data, val); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_USR_EDCA, 0, 1, + H2C_EDCA_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_TSF32_TOGL_LEN 4 +int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool en) +{ + struct sk_buff *skb; + u16 early_us = en ? 2000 : 0; + u8 *cmd; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); + return -ENOMEM; + } + skb_put(skb, H2C_TSF32_TOGL_LEN); + cmd = skb->data; + + RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx); + RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); + RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port); + RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_TSF32_TOGL, 0, 0, + H2C_TSF32_TOGL_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_OFLD_CFG_LEN 8 +int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) +{ + static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); + return -ENOMEM; + } + skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_OFLD_CFG, 0, 1, + H2C_OFLD_CFG_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv) +{ + struct rtw89_h2c_tx_duty *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 pause, active; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_tx_duty *)skb->data; + + static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100); + + if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) { + h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP); + } else { + active = 100 - lv * RTW89_THERMAL_PROT_STEP; + pause = 100 - active; + + h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) | + le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_TX_DUTY, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool connect) +{ + struct ieee80211_bss_conf *bss_conf; + s32 thold = RTW89_DEFAULT_CQM_THOLD; + u32 hyst = RTW89_DEFAULT_CQM_HYST; + struct rtw89_h2c_bcnfltr *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 max_cnt, cnt; + int ret; + + if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) + return -EINVAL; + + if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) + return -EINVAL; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + + if (bss_conf->cqm_rssi_hyst) + hyst = bss_conf->cqm_rssi_hyst; + if (bss_conf->cqm_rssi_thold) + thold = bss_conf->cqm_rssi_thold; + + rcu_read_unlock(); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_bcnfltr *)skb->data; + + if (RTW89_CHK_FW_FEATURE(BEACON_LOSS_COUNT_V1, &rtwdev->fw)) + max_cnt = BIT(7) - 1; + else + max_cnt = BIT(4) - 1; + + cnt = min(RTW89_BCN_LOSS_CNT, max_cnt); + + h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | + le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | + le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | + le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT, + RTW89_H2C_BCNFLTR_W0_MODE) | + le32_encode_bits(cnt >> 4, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3) | + le32_encode_bits(cnt & 0xf, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4) | + le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | + le32_encode_bits(thold + MAX_RSSI, + RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_CFG_BCNFLTR, 0, 1, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + struct rtw89_h2c_ofld_rssi *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + s8 rssi; + int ret; + + if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) + return -EINVAL; + + if (!phy_ppdu) + return -EINVAL; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n"); + return -ENOMEM; + } + + rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR; + skb_put(skb, len); + h2c = (struct rtw89_h2c_ofld_rssi *)skb->data; + + h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) | + le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM); + h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_OFLD_RSSI, 0, 1, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_traffic_stats *stats = &rtwvif->stats; + struct rtw89_h2c_ofld *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) + return -EINVAL; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_ofld *)skb->data; + + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | + le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | + le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_OFLD_TP, 0, 1, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ra_v1 *h2c_v1; + struct rtw89_h2c_ra *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX) { + len = sizeof(*h2c); + ver = 0; + } else { + len = sizeof(*h2c_v1); + ver = 1; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_ra *)skb->data; + rtw89_debug(rtwdev, RTW89_DBG_RA, + "ra cmd msk: %llx ", ra->ra_mask); + + h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) | + le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) | + le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) | + le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) | + le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) | + le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) | + le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) | + le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) | + le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) | + le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) | + le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) | + le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) | + le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) | + le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK); + h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32); + h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32); + h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) | + le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF); + + if (!csi || ver >= 1) + goto next_v1; + + h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL); + h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) | + le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) | + le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) | + le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) | + le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) | + le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) | + le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) | + le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW); + +next_v1: + if (ver < 1) + goto done; + + h2c->w3 |= le32_encode_bits(ra->partial_bw_er, + RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER) | + le32_encode_bits(ra->band, RTW89_H2C_RA_V1_W3_BAND); + + h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; + h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | + le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, + H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_tx_history(struct rtw89_dev *rtwdev, u16 mac_id) +{ + struct rtw89_bb_stat_cfg *bb_stat = &rtwdev->phy_info.bb_stat_cfg; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ra_tx_history *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c tx history\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_ra_tx_history *)skb->data; + + h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_RA_TX_HISTORY_W0_MACID) | + le32_encode_bits(0, RTW89_H2C_RA_TX_HISTORY_W0_PER_PPDU); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, + H2C_FUNC_OUTSRC_RA_TX_HISTORY, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + bb_stat->mac_id = mac_id; + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_phy_ch_rpt(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ra_phy_ch_rpt *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c phy ch rpt\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_ra_phy_ch_rpt *)skb->data; + + h2c->w1 = le32_encode_bits(1, RTW89_H2C_RA_PHY_CH_RPT_W1_RPT_TX_COUNT); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, + H2C_FUNC_OUTSRC_RA_PHY_CH_RPT, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_drv_ctrl_fw(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_ra_drv_ctrl_fw *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c drv ctrl fw\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_ra_drv_ctrl_fw *)skb->data; + + h2c->w0 = le32_encode_bits(1, RTW89_H2C_RA_DRV_CTRL_FW_W0_RPT_TX_COUNT); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, + H2C_FUNC_OUTSRC_RA_DRV_CTRL_FW, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_init_info *init = &dm->init_info; + struct rtw89_btc_module *md = &init->module; + struct rtw89_btc_ant_info *ant = &md->ant; + struct rtw89_h2c_cxinit *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxinit *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR; + + h2c->ant_type = ant->type; + h2c->ant_num = ant->num; + h2c->ant_iso = ant->isolation; + h2c->ant_info = + u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) | + u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) | + u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) | + u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT); + + h2c->mod_rfe = md->rfe_type; + h2c->mod_cv = md->kt_ver; + h2c->mod_info = + u8_encode_bits(md->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) | + u8_encode_bits(md->bt0_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) | + u8_encode_bits(md->bt0_sw_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) | + u8_encode_bits(md->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE); + h2c->mod_adie_kt = md->kt_ver_adie; + h2c->wl_gch = init->wl_guard_ch; + + h2c->info = + u8_encode_bits(init->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) | + u8_encode_bits(init->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) | + u8_encode_bits(init->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) | + u8_encode_bits(init->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) | + u8_encode_bits(init->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_init_info *init = &dm->init_info; + struct rtw89_btc_module *md = &init->module; + struct rtw89_btc_ant_info *ant = &md->ant; + struct rtw89_h2c_cxinit_v7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxinit_v7 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 7; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + h2c->init.wl_guard_ch = init->wl_guard_ch; + h2c->init.wl_only = init->wl_only; + h2c->init.wl_init_ok = init->wl_init_ok; + h2c->init.cx_other = init->cx_other; + h2c->init.bt_only = init->bt_only; + h2c->init.pta_mode = init->pta_mode; + h2c->init.pta_direction = init->pta_direction; + h2c->init.rsvd3 = init->dbcc_en; /* available at v107 */ + + h2c->init.module.rfe_type = md->rfe_type; + h2c->init.module.kt_ver = md->kt_ver; + h2c->init.module.bt_solo = md->bt_solo; + h2c->init.module.bt_pos = md->bt0_pos; + h2c->init.module.switch_type = md->bt0_sw_type; + h2c->init.module.wa_type = md->wa_type; + h2c->init.module.kt_ver_adie = md->kt_ver_adie; + + h2c->init.module.ant.type = ant->type; + h2c->init.module.ant.num = ant->num; + h2c->init.module.ant.isolation = ant->isolation; + h2c->init.module.ant.single_pos = ant->single_pos; + h2c->init.module.ant.diversity = ant->diversity; + h2c->init.module.ant.btg_pos = ant->btg_pos; + h2c->init.module.ant.stream_cnt = ant->stream_cnt; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_init_v10(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_init_info *init = &dm->init_info; + struct rtw89_btc_module *md = &init->module; + struct rtw89_btc_ant_info *ant = &md->ant; + struct rtw89_h2c_cxinit_v10 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v10\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxinit_v10 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 10; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + h2c->init.endian_type = init->endian_type; + h2c->init.init_mode = init->init_mode; + h2c->init.wl_init_ok = init->wl_init_ok; + h2c->init.bt0_function = init->bt0_function; + h2c->init.bt1_function = init->bt1_function; + h2c->init.bt2_function = init->bt2_function; + h2c->init.pta_mode = init->pta_mode; + h2c->init.pta_direction = init->pta_direction; + + h2c->init.module.rfe_type = md->rfe_type; + h2c->init.module.wa_type = md->wa_type; + h2c->init.module.kt_ver = md->kt_ver; + h2c->init.module.kt_ver_adie = md->kt_ver_adie; + h2c->init.module.bt0_pos = md->bt0_pos; + h2c->init.module.bt0_sw_type = md->bt0_sw_type; + h2c->init.module.bt1_pos = md->bt1_pos; + h2c->init.module.bt1_sw_type = md->bt1_sw_type; + + h2c->init.module.ant.type = ant->type; + h2c->init.module.ant.num = ant->num; + h2c->init.module.ant.isolation = ant->isolation; + h2c->init.module.ant.single_pos = ant->single_pos; + h2c->init.module.ant.stream_cnt = ant->stream_cnt; + h2c->init.module.ant.btg_pos = ant->btg_pos; + h2c->init.module.ant.btg1_pos = ant->btg1_pos; + + memcpy(h2c->init.module.ant.func, ant->func, sizeof(ant->func)); + memcpy(h2c->init.module.ant.ant_xmap, ant->ant_xmap, + sizeof(ant->ant_xmap)); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_init_v11(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_init_info *init = &dm->init_info; + struct rtw89_h2c_cxinit_v11 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v11\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxinit_v11 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 11; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + h2c->init.endian_type = init->endian_type; + h2c->init.init_mode = init->init_mode; + h2c->init.wl_init_ok = init->wl_init_ok; + h2c->init.bt0_function = init->bt0_function; + + h2c->init.bt1_function = init->bt1_function; + h2c->init.bt2_function = init->bt2_function; + h2c->init.pta_mode = init->pta_mode; + h2c->init.pta_direction = init->pta_direction; + + h2c->init.module.rfe_type = init->module.rfe_type; + h2c->init.module.wa_type = init->module.wa_type; + h2c->init.module.kt_ver = init->module.kt_ver; + h2c->init.module.kt_ver_adie = init->module.kt_ver_adie; + + h2c->init.module.bt0_pos = init->module.bt0_pos; + h2c->init.module.bt0_sw_type = init->module.bt0_sw_type; + h2c->init.module.bt1_pos = init->module.bt1_pos; + h2c->init.module.bt1_sw_type = init->module.bt1_sw_type; + + h2c->init.module.ant.type = init->module.ant.type; + h2c->init.module.ant.num = init->module.ant.num; + h2c->init.module.ant.isolation = init->module.ant.isolation; + h2c->init.module.ant.single_pos = init->module.ant.single_pos; + + h2c->init.module.ant.stream_cnt = init->module.ant.stream_cnt; + h2c->init.module.ant.path_pos = init->module.ant.path_pos; + h2c->init.module.ant.btg_pos = init->module.ant.btg_pos; + h2c->init.module.ant.btg1_pos = init->module.ant.btg1_pos; + memcpy(h2c->init.module.ant.func, init->module.ant.func, + sizeof(init->module.ant.func)); + + memcpy(h2c->init.module.ant.ant_xmap, init->module.ant.ant_xmap, + sizeof(init->module.ant.ant_xmap)); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define PORT_DATA_OFFSET 4 +#define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 +#define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ + (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) + +int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *r = &wl->role_info; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_wl_rlink *rl; + struct sk_buff *skb; + u32 rmap = r->role_map; + u8 offset = 0; + u32 len; + u8 *cmd; + int ret; + int i; + + len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); + return -ENOMEM; + } + skb_put(skb, len); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); + RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); + RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode); + + RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); + RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); + RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); + RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); + RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); + RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); + RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); + + for (i = 0; i < RTW89_PORT_NUM; i++) { + rl = &r->rlink[i][RTW89_MAC_0]; + RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ + (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) + +int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *r = &wl->role_info; + struct rtw89_btc_wl_rlink *rl; + struct sk_buff *skb; + u32 rmap = r->role_map; + u8 *cmd, offset; + u32 len; + int ret; + int i; + + len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); + return -ENOMEM; + } + skb_put(skb, len); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); + RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); + RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode); + + RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); + RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); + RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); + RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); + RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); + RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); + RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); + + offset = PORT_DATA_OFFSET; + + for (i = 0; i < RTW89_PORT_NUM; i++) { + rl = &r->rlink[i][RTW89_MAC_0]; + RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, rl->noa_dur, i, offset); + } + + offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; + RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset); + RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset); + RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_role_v101(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *role_info = &wl->role_info; + struct rtw89_btc_wl_rlink *active; + struct rtw89_h2c_cxrole_v101 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + u8 i; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role_v101\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxrole_v101 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR; + + h2c->connect_cnt = role_info->connect_cnt; + h2c->link_mode = role_info->link_mode; + h2c->role_map = cpu_to_le16(role_info->role_map); + + for (i = 0; i < RTW89_PORT_NUM; i++) { + active = &role_info->rlink[i][0]; + h2c->act_role[i].map_role_status = + u8_encode_bits(active->connected, + RTW89_H2C_CXROLE_V101_ROLE_STAT_CONNTECTED) | + u8_encode_bits(active->pid, + RTW89_H2C_CXROLE_V101_ROLE_STAT_PID) | + u8_encode_bits(active->phy, + RTW89_H2C_CXROLE_V101_ROLE_STAT_PHY) | + u8_encode_bits(active->noa, + RTW89_H2C_CXROLE_V101_ROLE_STAT_NOA) | + u8_encode_bits(active->rf_band, + RTW89_H2C_CXROLE_V101_ROLE_STAT_BADN); + h2c->act_role[i].map_clips_bw = + u8_encode_bits(active->client_ps, + RTW89_H2C_CXROLE_V101_CLIPS_BW_CLIENTPS) | + u8_encode_bits(active->bw, + RTW89_H2C_CXROLE_V101_CLIPS_BW_BW); + h2c->act_role[i].role = active->role; + h2c->act_role[i].ch = active->ch; + h2c->act_role[i].noa_duration = cpu_to_le32(active->noa_dur); + } + + h2c->mrole_type = cpu_to_le32(role_info->mrole_type); + h2c->mrole_noa_duration = cpu_to_le32(role_info->mrole_noa_duration); + h2c->map_dbcc_linkmode_chg = + le32_encode_bits(role_info->dbcc_en, + RTW89_H2C_CXROLE_V101_DBCC_EN) | + le32_encode_bits(role_info->dbcc_chg, + RTW89_H2C_CXROLE_V101_DBCC_CHG) | + le32_encode_bits(role_info->dbcc_2g_phy, + RTW89_H2C_CXROLE_V101_DBCC_2G_PHY) | + le32_encode_bits(role_info->link_mode_chg, + RTW89_H2C_CXROLE_V101_DBCC_LINKMODE_CHG) | + le32_encode_bits(role_info->rsvd, + RTW89_H2C_CXROLE_V101_DBCC_RSVD); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ + (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) + +int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *r = &wl->role_info; + struct rtw89_btc_wl_rlink *rl; + struct sk_buff *skb; + u32 rmap = r->role_map; + u32 len; + u8 *cmd, offset; + int ret; + int i; + + len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); + return -ENOMEM; + } + skb_put(skb, len); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); + RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); + RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode); + + RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); + RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); + RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); + RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); + RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); + RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); + RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); + RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); + RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); + + offset = PORT_DATA_OFFSET; + + for (i = 0; i < RTW89_PORT_NUM; i++) { + rl = &r->rlink[i][RTW89_MAC_0]; + RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, rl->connected, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, rl->pid, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, rl->phy, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, rl->noa, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, rl->rf_band, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, rl->client_ps, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, rl->bw, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, rl->role, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, rl->ch, i, offset); + RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, rl->noa_dur, i, offset); + } + + offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; + RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset); + RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset); + RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; + struct rtw89_h2c_cxrole_v7 *h2c; + struct rtw89_btc_wl_rlink *rl; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + __le32 rm; + int ret; + u8 i; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 7; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + h2c->r.connect_cnt = r->connect_cnt; + h2c->r.link_mode = r->link_mode; + h2c->r.link_mode_chg = r->link_mode_chg; + h2c->r.p2p_2g = r->p2p_2g; + + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { + rl = &r->rlink[i][RTW89_MAC_0]; + h2c->r.active_role[i].connected = rl->connected; + h2c->r.active_role[i].pid = rl->pid; + h2c->r.active_role[i].phy = rl->phy; + h2c->r.active_role[i].noa = rl->noa; + + h2c->r.active_role[i].band = rl->rf_band; + h2c->r.active_role[i].client_ps = rl->client_ps; + h2c->r.active_role[i].bw = rl->bw; + h2c->r.active_role[i].role = rl->role; + + h2c->r.active_role[i].ch = rl->ch; + h2c->r.active_role[i].noa_dur = rl->noa_dur; + h2c->r.active_role[i].client_cnt = rl->client_cnt; + } + + rm = cpu_to_le32(r->role_map); + memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); + h2c->r.mrole_type = cpu_to_le32(r->mrole_type); + h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration); + h2c->r.dbcc_en = cpu_to_le32((u32)r->dbcc_en); + h2c->r.dbcc_chg = cpu_to_le32(r->dbcc_chg); + h2c->r.dbcc_2g_phy = cpu_to_le32(r->dbcc_2g_phy); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; + struct rtw89_h2c_cxrole_v8 *h2c; + struct rtw89_btc_wl_rlink *rl; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + __le32 rm; + int ret; + u8 i, j; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 8; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + h2c->r.connect_cnt = r->connect_cnt; + h2c->r.link_mode = r->link_mode; + h2c->r.link_mode_chg = r->link_mode_chg; + h2c->r.p2p_2g = r->p2p_2g; + h2c->r.pta_req_band = r->pta_req_band; + h2c->r.dbcc_en = r->dbcc_en; + h2c->r.dbcc_chg = r->dbcc_chg; + h2c->r.dbcc_2g_phy = r->dbcc_2g_phy; + + for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { + rl = &r->rlink[i][j]; + h2c->r.rlink[i][j].connected = rl->connected; + h2c->r.rlink[i][j].pid = rl->pid; + h2c->r.rlink[i][j].phy = rl->phy; + h2c->r.rlink[i][j].noa = rl->noa; + + h2c->r.rlink[i][j].rf_band = rl->rf_band; + h2c->r.rlink[i][j].active = rl->active; + h2c->r.rlink[i][j].bw = rl->bw; + h2c->r.rlink[i][j].role = rl->role; + + h2c->r.rlink[i][j].ch = rl->ch; + h2c->r.rlink[i][j].noa_dur = rl->noa_dur; + h2c->r.rlink[i][j].client_cnt = rl->client_cnt; + h2c->r.rlink[i][j].mode = rl->mode; + } + } + + rm = cpu_to_le32(r->role_map); + memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); + h2c->r.mrole_type = cpu_to_le32(r->mrole_type); + h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; + struct rtw89_h2c_cxrole_v10 *h2c; + struct rtw89_btc_wl_rlink *rl; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + __le32 rm; + int ret; + u8 i, j; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxrole_v10 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 10; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { + rl = &r->rlink[i][j]; + h2c->r.rlink[i][j].connected = rl->connected; + h2c->r.rlink[i][j].pid = rl->pid; + h2c->r.rlink[i][j].phy = rl->phy; + h2c->r.rlink[i][j].noa = rl->noa; + + h2c->r.rlink[i][j].rf_band = rl->rf_band; + h2c->r.rlink[i][j].active = rl->active; + h2c->r.rlink[i][j].bw = rl->bw; + h2c->r.rlink[i][j].role = rl->role; + + h2c->r.rlink[i][j].ch = rl->ch; + h2c->r.rlink[i][j].noa_dur = rl->noa_dur; + h2c->r.rlink[i][j].client_cnt = rl->client_cnt; + h2c->r.rlink[i][j].mode = rl->mode; + h2c->r.rlink[i][j].mac_id = rl->mac_id; + } + } + + h2c->r.link_mode = r->link_mode; + h2c->r.link_mode_hb1 = r->link_mode_hb1; + h2c->r.p2p_exist = r->p2p_exist; + h2c->r.p2p_exist_hb1 = r->p2p_exist_hb1; + + h2c->r.pta_req_band = r->pta_req_band; + h2c->r.dbcc_en = r->dbcc_en; + h2c->r.dbcc_2g_phy = r->dbcc_2g_phy; + + rm = cpu_to_le32(r->role_map); + memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); + rm = cpu_to_le32(r->role_map_hb1); + memcpy(&h2c->r.role_map_hb1, &rm, sizeof(h2c->r.role_map_hb1)); + h2c->r.mrole_type = cpu_to_le32(r->mrole_type); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_mlo_v2(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc_wl_mlo_info *mlo = &rtwdev->btc.cx.wl.mlo_info; + struct rtw89_h2c_cxmlo_v2 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_mlo_v2\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxmlo_v2 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 2; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + memcpy(h2c->mlo.wmode, mlo->wmode, + sizeof(h2c->mlo.wmode)); + memcpy(h2c->mlo.ch_type, mlo->ch_type, + sizeof(h2c->mlo.ch_type)); + memcpy(h2c->mlo.hwb_rf_band, mlo->hwb_rf_band, + sizeof(h2c->mlo.hwb_rf_band)); + memcpy(h2c->mlo.path_rf_band, mlo->path_rf_band, + sizeof(h2c->mlo.path_rf_band)); + + h2c->mlo.wtype = mlo->wtype; + h2c->mlo.mrcx_mode = mlo->mrcx_mode; + h2c->mlo.mrcx_act_hwb_map = mlo->mrcx_act_hwb_map; + h2c->mlo.mrcx_bt_slot_rsp = mlo->mrcx_bt_slot_rsp; + + h2c->mlo.rf_combination = mlo->rf_combination; + h2c->mlo.mlo_en = mlo->mlo_en; + h2c->mlo.mlo_adie = mlo->mlo_adie; + h2c->mlo.dual_hw_band_en = mlo->dual_hw_band_en; + h2c->mlo.link_status = cpu_to_le32(mlo->link_status); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; + struct rtw89_h2c_cxosi *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + u8 i, j; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxosi *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = btc->ver->fcxosi; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band)); + memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx)); + memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx)); + + for (i = 0; i < BTC_RF_NUM; i++) { + h2c->osi.gnt_set[i] = osi->gnt_set[i]; + h2c->osi.wlact_set[i] = osi->wlact_set[i]; + } + + h2c->osi.pta_req_hw_band = osi->pta_req_hw_band; + h2c->osi.rf_gbt_source = osi->rf_gbt_source; + h2c->osi.bt_enable_state = osi->bt_enable_state; + h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg; + + memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en)); + + for (i = 0; i < RTW89_MAC_NUM; i++) { + h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]); + for (j = 0; j < BTC_RF_NUM; j++) + h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]); + } + + for (i = 0; i < RTW89_MAC_NUM; i++) { + for (j = 0; j < BTC_ALL_BT; j++) + h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_osi_info_v6(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; + struct rtw89_h2c_cxosi_v6 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + u8 i, j; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi_v6\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxosi_v6 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = btc->ver->fcxosi; + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; + + memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band)); + memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx)); + memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx)); + memcpy(h2c->osi.gnt_set, osi->gnt_set, sizeof(osi->gnt_set)); + memcpy(h2c->osi.wlact_set, osi->wlact_set, sizeof(osi->wlact_set)); + + h2c->osi.pta_req_hw_band = osi->pta_req_hw_band; + h2c->osi.rf_gbt_source = osi->rf_gbt_source; + h2c->osi.bt_enable_state = osi->bt_enable_state; + h2c->osi.bt_plut_type = osi->bt_plut_type; + h2c->osi.wl_tx_limit_en = osi->wl_tx_limit_en; + h2c->osi.fc_exec = osi->fc_exec; + h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg; + h2c->osi.rsvd = osi->rsvd; + + memcpy(h2c->osi.bb_path_sel_bt, osi->bb_path_sel_bt, sizeof(osi->bb_path_sel_bt)); + memcpy(h2c->osi.bb_phy_sel_bt, osi->bb_phy_sel_bt, sizeof(osi->bb_phy_sel_bt)); + memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en)); + + for (i = 0; i < RTW89_MAC_NUM; i++) { + h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]); + for (j = 0; j < BTC_RF_NUM; j++) + h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]); + } + + for (i = 0; i < RTW89_MAC_NUM; i++) { + for (j = 0; j < BTC_ALL_BT_EZL; j++) + h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]); + } + + h2c->osi.wl_tx_limit_time = cpu_to_le32(osi->wl_tx_limit_time); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) +int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_ctrl *ctrl = &btc->ctrl; + struct sk_buff *skb; + u8 *cmd; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); + RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); + RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); + RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); + if (ver->fcxctrl == 0) + RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + H2C_LEN_CXDRVINFO_CTRL); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_ctrl *ctrl = &btc->ctrl; + struct rtw89_h2c_cxctrl_v7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxctrl_v7 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = btc->ver->fcxctrl; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + + h2c->ctrl.manual = ctrl->manual; + h2c->ctrl.igno_bt = ctrl->igno_bt; + h2c->ctrl.always_freerun = ctrl->always_freerun; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_ctrl *ctrl = &btc->ctrl; + struct rtw89_fbtc_wl_ctrl_info_v9 *cinfo; + struct rtw89_h2c_cxctrl_v9 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxctrl_v9 *)skb->data; + cinfo = &h2c->ctrl.wl_ctrl_info; + + h2c->hdr.type = type; + h2c->hdr.ver = btc->ver->fcxctrl; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + + h2c->ctrl.manual = ctrl->manual; + h2c->ctrl.always_freerun = ctrl->always_freerun; + h2c->ctrl.wl_only = ctrl->wl_only; + h2c->ctrl.bt_only = ctrl->bt_only; + h2c->ctrl.ntfy_type = ctrl->ntfy_type; + memcpy(cinfo->rf_band_map, ctrl->wl_ctrl_info.rf_band_map, + sizeof(cinfo->rf_band_map)); + memcpy(cinfo->rf_ch, ctrl->wl_ctrl_info.rf_ch, sizeof(cinfo->rf_ch)); + cinfo->client_pstdma_on = ctrl->wl_ctrl_info.client_pstdma_on; + cinfo->fw_scan = ctrl->wl_ctrl_info.fw_scan; + cinfo->rfk_state = ctrl->wl_ctrl_info.rfk_state; + cinfo->rfk_type = ctrl->wl_ctrl_info.rfk_type; + cinfo->smap_val = cpu_to_le32(ctrl->wl_ctrl_info.smap_val); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +static void rtw89_btc_load_trx_para(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_rf_trx_para_v9 rf_para = btc->dm.rf_trx_para; + struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + u8 i; + + for (i = 0; i < RTW89_PHY_NUM; i++) { + trx->wl_tx_power[i] = u32_get_bits(rf_para.wl_tx_power[i], + RTW89_BTC_WL_DEF_TX_PWR); + trx->wl_rx_gain[i] = u32_get_bits(rf_para.wl_rx_gain[i], + RTW89_BTC_WL_DEF_TX_PWR); + if (btc->ver->fcxtrx == 107) + break; + } + + for (i = 0; i < BTC_ALL_BT; i++) { + trx->bt_tx_power[i] = u32_get_bits(rf_para.bt_tx_power[i], + RTW89_BTC_WL_DEF_TX_PWR); + trx->bt_rx_gain[i] = u32_get_bits(rf_para.bt_rx_gain[i], + RTW89_BTC_WL_DEF_TX_PWR); + if (btc->ver->fcxtrx == 107) + break; + + trx->zb_tx_power[i] = u32_get_bits(rf_para.zb_tx_power[i], + RTW89_BTC_WL_DEF_TX_PWR); + trx->zb_rx_gain[i] = u32_get_bits(rf_para.zb_rx_gain[i], + RTW89_BTC_WL_DEF_TX_PWR); + } + + trx->cn = wl->cn_report; + trx->nhm = wl->nhm.pwr; +} + +int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; + struct rtw89_h2c_cxtrx_v7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + rtw89_btc_load_trx_para(rtwdev); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxtrx_v7 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 7; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + + h2c->v7_u8.tx_lvl = trx->tx_lvl; + h2c->v7_u8.rx_lvl = trx->rx_lvl; + h2c->v7_u8.wl_rssi = trx->wl_rssi; + h2c->v7_u8.bt_rssi = trx->bt_rssi; + h2c->v7_u8.wl_tx_power = trx->wl_tx_power[RTW89_PHY_0]; + h2c->v7_u8.wl_rx_gain = trx->wl_rx_gain[RTW89_PHY_0]; + h2c->v7_u8.bt_tx_power = trx->bt_tx_power[BTC_BT_1ST]; + h2c->v7_u8.bt_rx_gain = trx->bt_rx_gain[BTC_BT_1ST]; + h2c->v7_u8.zb_tx_power = trx->zb_tx_power[BTC_BT_1ST]; + h2c->v7_u8.zb_rx_gain = trx->zb_rx_gain[BTC_BT_1ST]; + h2c->v7_u8.cn = trx->cn; + h2c->v7_u8.nhm = trx->nhm; + h2c->v7_u8.bt_profile = trx->bt_profile; + h2c->v7_u8.rsvd2 = trx->rsvd2; + h2c->v7_le.tx_rate = cpu_to_le16(trx->tx_rate); + h2c->v7_le.rx_rate = cpu_to_le16(trx->rx_rate); + h2c->v7_le.tx_tp = cpu_to_le32(trx->tx_tp); + h2c->v7_le.rx_tp = cpu_to_le32(trx->rx_tp); + h2c->v7_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; + struct rtw89_h2c_cxtrx_v9 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + u8 i; + + rtw89_btc_load_trx_para(rtwdev); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxtrx_v9 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 9; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + + h2c->v9_u8.tx_lvl = trx->tx_lvl; + h2c->v9_u8.rx_lvl = trx->rx_lvl; + h2c->v9_u8.wl_rssi = trx->wl_rssi; + h2c->v9_u8.bt_rssi = trx->bt_rssi; + + for (i = 0; i < RTW89_PHY_NUM; i++) { + h2c->v9_u8.wl_tx_power[i] = trx->wl_tx_power[i]; + h2c->v9_u8.wl_rx_gain[i] = trx->wl_rx_gain[i]; + } + + for (i = 0; i < BTC_ALL_BT; i++) { + h2c->v9_u8.bt_tx_power[i] = trx->bt_tx_power[i]; + h2c->v9_u8.bt_rx_gain[i] = trx->bt_rx_gain[i]; + h2c->v9_u8.zb_tx_power[i] = trx->zb_tx_power[i]; + h2c->v9_u8.zb_rx_gain[i] = trx->zb_rx_gain[i]; + } + h2c->v9_u8.cn = trx->cn; + h2c->v9_u8.nhm = trx->nhm; + h2c->v9_u8.bt_profile = trx->bt_profile; + h2c->v9_u8.rsvd2 = trx->rsvd2; + h2c->v9_le.tx_rate = cpu_to_le16(trx->tx_rate); + h2c->v9_le.rx_rate = cpu_to_le16(trx->rx_rate); + h2c->v9_le.tx_tp = cpu_to_le32(trx->tx_tp); + h2c->v9_le.rx_tp = cpu_to_le32(trx->rx_tp); + h2c->v9_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxdrv_trx_v107(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; + struct rtw89_h2c_cxtrx_v107 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + rtw89_btc_load_trx_para(rtwdev); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v107\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxtrx_v107 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 7; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + + h2c->v107_u8.tx_lvl = trx->tx_lvl; + h2c->v107_u8.rx_lvl = trx->rx_lvl; + h2c->v107_u8.wl_rssi = trx->wl_rssi; + h2c->v107_u8.bt_rssi = trx->bt_rssi; + h2c->v107_u8.wl_tx_power = trx->bt_tx_power[RTW89_PHY_0]; + h2c->v107_u8.wl_rx_gain = trx->wl_rx_gain[RTW89_PHY_0]; + h2c->v107_u8.bt_tx_power = trx->bt_tx_power[BTC_BT_1ST]; + h2c->v107_u8.bt_rx_gain = trx->bt_rx_gain[BTC_BT_1ST]; + h2c->v107_u8.cn = trx->cn; + h2c->v107_u8.nhm = trx->nhm; + h2c->v107_u8.bt_profile = trx->bt_profile; + h2c->v107_u8.rsvd2 = trx->rsvd2; + h2c->v7_le.tx_rate = cpu_to_le16(trx->tx_rate); + h2c->v7_le.rx_rate = cpu_to_le16(trx->rx_rate); + h2c->v7_le.tx_tp = cpu_to_le32(trx->tx_tp); + h2c->v7_le.rx_tp = cpu_to_le32(trx->rx_tp); + h2c->v7_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) +int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; + struct sk_buff *skb; + u8 *cmd; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, H2C_LEN_CXDRVINFO_RFK); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); + RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); + RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); + RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); + RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); + RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, + H2C_LEN_CXDRVINFO_RFK); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxtxpwr_v7(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para; + struct rtw89_h2c_cxtxpwr_v7 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxtxpwr_v7 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 7; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cxtxpwr_v9(struct rtw89_dev *rtwdev, u8 type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para; + struct rtw89_h2c_cxtxpwr_v9 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cxtxpwr_v9 *)skb->data; + + h2c->hdr.type = type; + h2c->hdr.ver = 9; + h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; + if (dm->wl_tx_pwr_phy_map == BIT(RTW89_PHY_1)) + h2c->pwr = rp.wl_tx_power[RTW89_PHY_1] & 0xff; + else + h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff; + h2c->band = dm->wl_tx_pwr_phy_map; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_LEN_PKT_OFLD 4 +int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct sk_buff *skb; + unsigned int cond; + u8 *cmd; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); + return -ENOMEM; + } + skb_put(skb, H2C_LEN_PKT_OFLD); + cmd = skb->data; + + RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id); + RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_PACKET_OFLD, 1, 1, + H2C_LEN_PKT_OFLD); + + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret < 0) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "failed to del pkt ofld: id %d, ret %d\n", + id, ret); + return ret; + } + + rtw89_core_release_bit_map(rtwdev->pkt_offload, id); + return 0; +} + +static int __rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, + struct sk_buff *skb_ofld) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct sk_buff *skb; + unsigned int cond; + u8 *cmd; + u8 alloc_id; + int ret; + + alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload, + RTW89_MAX_PKT_OFLD_NUM); + if (alloc_id == RTW89_MAX_PKT_OFLD_NUM) + return -ENOSPC; + + *id = alloc_id; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); + rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); + return -ENOMEM; + } + skb_put(skb, H2C_LEN_PKT_OFLD); + cmd = skb->data; + + RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id); + RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD); + RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len); + skb_put_data(skb, skb_ofld->data, skb_ofld->len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_PACKET_OFLD, 1, 1, + H2C_LEN_PKT_OFLD + skb_ofld->len); + + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret < 0) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "failed to add pkt ofld: id %d, ret %d\n", + alloc_id, ret); + /* + * Firmware may consider that it has added this entry + * successfully even though the H2C return timeout. + * Send a delete H2C command to drop it, and thus the + * next add on the same id won't be rejected as duplicate. + */ + rtw89_fw_h2c_del_pkt_offload(rtwdev, alloc_id); + rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); + + return -EAGAIN; + } + + return 0; +} + +int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, + struct sk_buff *skb_ofld) +{ + int ret; + + ret = __rtw89_fw_h2c_add_pkt_offload(rtwdev, id, skb_ofld); + if (ret == -EAGAIN) + ret = __rtw89_fw_h2c_add_pkt_offload(rtwdev, id, skb_ofld); + + return ret; +} + +static +int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num, + struct list_head *chan_list) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct rtw89_h2c_chinfo_elem *elem; + struct rtw89_mac_chinfo_ax *ch_info; + struct rtw89_h2c_chinfo *h2c; + struct sk_buff *skb; + unsigned int cond; + int skb_len; + int ret; + + static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE); + + skb_len = struct_size(h2c, elem, ch_num); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); + return -ENOMEM; + } + skb_put(skb, sizeof(*h2c)); + h2c = (struct rtw89_h2c_chinfo *)skb->data; + + h2c->ch_num = ch_num; + h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ + + list_for_each_entry(ch_info, chan_list, list) { + elem = (struct rtw89_h2c_chinfo_elem *)skb_put(skb, sizeof(*elem)); + + elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_W0_PERIOD) | + le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_W0_DWELL) | + le32_encode_bits(ch_info->central_ch, RTW89_H2C_CHINFO_W0_CENTER_CH) | + le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_W0_PRI_CH); + + elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_W1_BW) | + le32_encode_bits(ch_info->notify_action, RTW89_H2C_CHINFO_W1_ACTION) | + le32_encode_bits(ch_info->num_pkt, RTW89_H2C_CHINFO_W1_NUM_PKT) | + le32_encode_bits(ch_info->tx_pkt, RTW89_H2C_CHINFO_W1_TX) | + le32_encode_bits(ch_info->pause_data, RTW89_H2C_CHINFO_W1_PAUSE_DATA) | + le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_W1_BAND) | + le32_encode_bits(ch_info->probe_id, RTW89_H2C_CHINFO_W1_PKT_ID) | + le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) | + le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) | + le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM); + + if (scan_info->extra_op.set) + elem->w1 |= le32_encode_bits(ch_info->macid_tx, + RTW89_H2C_CHINFO_W1_MACID_TX); + + elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) | + le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) | + le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) | + le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_W2_PKT3); + + elem->w3 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_W3_PKT4) | + le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_W3_PKT5) | + le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_W3_PKT6) | + le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_W3_PKT7); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); + + cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); + return ret; + } + + return 0; +} + +static +int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, + struct list_head *chan_list, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct rtw89_h2c_chinfo_elem_be *elem; + struct rtw89_mac_chinfo_be *ch_info; + struct rtw89_h2c_chinfo_be *h2c; + bool wildcard_by_drv; + struct sk_buff *skb; + unsigned int cond; + u8 ver = U8_MAX; + int skb_len; + int ret; + + static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE); + + skb_len = struct_size(h2c, elem, ch_num); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); + return -ENOMEM; + } + + if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) + ver = 0; + + wildcard_by_drv = !(RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw) || + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw) || + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw)); + + skb_put(skb, sizeof(*h2c)); + h2c = (struct rtw89_h2c_chinfo_be *)skb->data; + + h2c->ch_num = ch_num; + h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ + h2c->arg = u8_encode_bits(rtwvif_link->mac_idx, + RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK); + + list_for_each_entry(ch_info, chan_list, list) { + bool with_probe_id = ch_info->probe_id != RTW89_SCANOFLD_PKT_NONE; + + elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem)); + + elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) | + le32_encode_bits(ch_info->central_ch, + RTW89_H2C_CHINFO_BE_W0_CENTER_CH) | + le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH); + + elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_BE_W1_BW) | + le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_BE_W1_CH_BAND) | + le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_BE_W1_DFS) | + le32_encode_bits(ch_info->pause_data, + RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA) | + le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_BE_W1_TX_NULL) | + le32_encode_bits(ch_info->rand_seq_num, + RTW89_H2C_CHINFO_BE_W1_RANDOM) | + le32_encode_bits(ch_info->notify_action, + RTW89_H2C_CHINFO_BE_W1_NOTIFY) | + le32_encode_bits(wildcard_by_drv || with_probe_id, + RTW89_H2C_CHINFO_BE_W1_PROBE) | + le32_encode_bits(ch_info->leave_crit, + RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) | + le32_encode_bits(ch_info->chkpt_timer, + RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER); + + elem->w2 = le32_encode_bits(ch_info->leave_time, + RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME) | + le32_encode_bits(ch_info->leave_th, + RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH) | + le32_encode_bits(ch_info->tx_pkt_ctrl, + RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL); + + elem->w3 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_BE_W3_PKT0) | + le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_BE_W3_PKT1) | + le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_BE_W3_PKT2) | + le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_BE_W3_PKT3); + + elem->w4 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_BE_W4_PKT4) | + le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_BE_W4_PKT5) | + le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_BE_W4_PKT6) | + le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_BE_W4_PKT7); + + elem->w5 = le32_encode_bits(ch_info->sw_def, RTW89_H2C_CHINFO_BE_W5_SW_DEF) | + le32_encode_bits(ch_info->fw_probe0_ssids, + RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS); + + elem->w6 = le32_encode_bits(ch_info->fw_probe0_shortssids, + RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) | + le32_encode_bits(ch_info->fw_probe0_bssids, + RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS); + if (ver == 0) + elem->w0 |= + le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD); + else + elem->w7 = le32_encode_bits(ch_info->period, + RTW89_H2C_CHINFO_BE_W7_PERIOD_V1); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); + + cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); + return ret; + } + + return 0; +} + +int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *option, + struct rtw89_vif_link *rtwvif_link, + bool wowlan) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct rtw89_chan *op = &rtwdev->scan_info.op_chan; + enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE; + struct rtw89_h2c_scanofld *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + unsigned int cond; + u64 tsf = 0; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_scanofld *)skb->data; + + if (option->delay) { + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); + if (ret) { + rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret); + scan_mode = RTW89_SCAN_IMMEDIATE; + } else { + scan_mode = RTW89_SCAN_DELAY; + tsf += (u64)option->delay * 1000; + } + } + + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) | + le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); + + h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | + le32_encode_bits(option->target_ch_mode, + RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) | + le32_encode_bits(scan_mode, RTW89_H2C_SCANOFLD_W1_START_MODE) | + le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE); + + h2c->w2 = le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_W2_NORM_PD) | + le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_W2_SLOW_PD); + + if (option->target_ch_mode) { + h2c->w1 |= le32_encode_bits(op->band_width, + RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) | + le32_encode_bits(op->primary_channel, + RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) | + le32_encode_bits(op->channel, + RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH); + h2c->w0 |= le32_encode_bits(op->band_type, + RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND); + } + + h2c->tsf_high = le32_encode_bits(upper_32_bits(tsf), + RTW89_H2C_SCANOFLD_W3_TSF_HIGH); + h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf), + RTW89_H2C_SCANOFLD_W4_TSF_LOW); + + if (scan_info->extra_op.set) + h2c->w6 = le32_encode_bits(scan_info->extra_op.macid, + RTW89_H2C_SCANOFLD_W6_SECOND_MACID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_SCANOFLD, 1, 1, + len); + + if (option->enable) + cond = RTW89_SCANOFLD_WAIT_COND_START; + else + cond = RTW89_SCANOFLD_WAIT_COND_STOP; + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); + return ret; + } + + return 0; +} + +static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *option) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + u8 i, idx; + + sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ]; + if (!sband) { + option->prohib_chan = U64_MAX; + return; + } + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; + if (chan->flags & IEEE80211_CHAN_DISABLED) { + idx = (chan->hw_value - 1) / 4; + option->prohib_chan |= BIT(idx); + } + } +} + +void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool wowlan) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + struct cfg80211_ssid *s; + u16 sum = 0, n_ssids; + int i, num = 0; + + nd_config = rtw_wow->nd_config; + n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; + + for (i = 0; i < n_ssids; i++) { + s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; + if (s->ssid_len == 0) + continue; + + num++; + sum += s->ssid_len + 1; + } + + scan_info->n_ssids = num; + scan_info->ssid_total_len = sum; +} + +int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *option, + struct rtw89_vif_link *rtwvif_link, + bool wowlan) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_h2c_scanofld_be_macc_role *macc_role; + struct rtw89_hw_scan_extra_op scan_op[2] = {}; + struct rtw89_chan *op = &scan_info->op_chan; + struct rtw89_h2c_scanofld_be_opch *opch; + struct rtw89_h2c_scanofld_be *h2c; + struct ieee80211_vif *vif; + struct sk_buff *skb; + u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role; + u8 opch_size = sizeof(*opch) * option->num_opch; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + u8 *probe_id = scan_info->wildcard_pkt_id; + enum rtw89_scan_be_opmode opmode; + u8 scan_offload_ver = U8_MAX; + u8 cfg_len = sizeof(*h2c); + struct cfg80211_ssid *s; + unsigned int cond; + u8 ver = U8_MAX; + u8 n_ssids = 0; + u8 policy_val; + void *ptr; + u8 txnull; + u8 txbcn; + int ret; + u32 len; + u8 i; + + if (option->num_opch > RTW89_MAX_OP_NUM_BE) { + rtw89_err(rtwdev, "num of scan OP chan %d over limit\n", option->num_opch); + return -ENOENT; + } + + rtw89_scan_get_6g_disabled_chan(rtwdev, option); + + if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) { + cfg_len = offsetofend(typeof(*h2c), w8); + scan_offload_ver = 0; + } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw)) { + cfg_len = offsetofend(typeof(*h2c), w9); + scan_offload_ver = 1; + } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw)) { + scan_offload_ver = 2; + } + + len = cfg_len + macc_role_size + opch_size; + if (scan_offload_ver > 2) + len += scan_info->ssid_total_len; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_scanofld_be *)skb->data; + ptr = skb->data; + + if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) + ver = 0; + + h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) | + le32_encode_bits(option->scan_mode, + RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) | + le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) | + le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) | + le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) | + le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND); + + h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) | + le32_encode_bits(option->num_opch, RTW89_H2C_SCANOFLD_BE_W1_NUM_OP) | + le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_BE_W1_NORM_PD); + + h2c->w2 = le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD) | + le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) | + le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END); + + if (scan_offload_ver > 2) + n_ssids = scan_info->n_ssids; + + h2c->w3 = le32_encode_bits(n_ssids, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) | + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) | + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) | + le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID); + + h2c->w4 = le32_encode_bits(probe_id[NL80211_BAND_5GHZ], + RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) | + le32_encode_bits(probe_id[NL80211_BAND_6GHZ], + RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) | + le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START); + + h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE); + + h2c->w6 = le32_encode_bits(option->prohib_chan, + RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW); + h2c->w7 = le32_encode_bits(option->prohib_chan >> 32, + RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH); + if (!wowlan && req->no_cck) { + h2c->w0 |= le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE); + h2c->w8 = le32_encode_bits(RTW89_HW_RATE_OFDM6, + RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ) | + le32_encode_bits(RTW89_HW_RATE_OFDM6, + RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ) | + le32_encode_bits(RTW89_HW_RATE_OFDM6, + RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ); + } + + if (scan_offload_ver == 0) + goto flex_member; + + h2c->w9 = le32_encode_bits(cfg_len / sizeof(h2c->w0), + RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) | + le32_encode_bits(sizeof(*macc_role) / sizeof(macc_role->w0), + RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC) | + le32_encode_bits(sizeof(*opch) / sizeof(opch->w0), + RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP); + +flex_member: + ptr += cfg_len; + + for (i = 0; i < option->num_macc_role; i++) { + macc_role = ptr; + macc_role->w0 = + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) | + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) | + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID) | + le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END); + ptr += sizeof(*macc_role); + } + + for (i = 0; i < option->num_opch; i++) { + struct rtw89_vif_link *rtwvif_link_op; + bool is_ap; + + switch (i) { + case 0: + scan_op[0].macid = rtwvif_link->mac_id; + scan_op[0].port = rtwvif_link->port; + scan_op[0].chan = *op; + rtwvif_link_op = rtwvif_link; + break; + case 1: + scan_op[1] = *ext; + rtwvif_link_op = ext->rtwvif_link; + break; + } + + vif = rtwvif_to_vif(rtwvif_link_op->rtwvif); + is_ap = vif->type == NL80211_IFTYPE_AP; + txnull = !is_zero_ether_addr(rtwvif_link_op->bssid) && + vif->type != NL80211_IFTYPE_AP; + opmode = is_ap ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV; + policy_val = is_ap ? 2 : RTW89_OFF_CHAN_TIME / 10; + txbcn = is_ap ? 1 : 0; + + opch = ptr; + opch->w0 = le32_encode_bits(scan_op[i].macid, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) | + le32_encode_bits(option->band, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) | + le32_encode_bits(scan_op[i].port, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) | + le32_encode_bits(opmode, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) | + le32_encode_bits(txnull, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) | + le32_encode_bits(policy_val, + RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL); + + opch->w1 = le32_encode_bits(scan_op[i].chan.band_type, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) | + le32_encode_bits(scan_op[i].chan.band_width, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) | + le32_encode_bits(0x3, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) | + le32_encode_bits(scan_op[i].chan.primary_channel, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) | + le32_encode_bits(scan_op[i].chan.channel, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH); + + opch->w2 = le32_encode_bits(0, + RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) | + le32_encode_bits(0, + RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) | + le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2, + RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS) | + le32_encode_bits(txbcn, + RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN); + + opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, + RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) | + le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, + RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1) | + le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, + RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) | + le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, + RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3); + + if (ver == 0) + opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME, + RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION); + else + opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME, + RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1); + ptr += sizeof(*opch); + } + + if (scan_offload_ver <= 2) + goto set_hdr; + + nd_config = rtw_wow->nd_config; + n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; + + for (i = 0; i < n_ssids; i++) { + s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; + if (s->ssid_len == 0) + continue; + + memcpy(ptr, &s->ssid_len, 1); + ptr++; + memcpy(ptr, s->ssid, s->ssid_len); + ptr += s->ssid_len; + } + +set_hdr: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_SCANOFLD_BE, 1, 1, + len); + + if (option->enable) + cond = RTW89_SCANOFLD_BE_WAIT_COND_START; + else + cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP; + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan be ofld\n"); + return ret; + } + + return 0; +} + +int rtw89_fw_h2c_trx_protect(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool enable) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_trx_protect *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c trx protect\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_trx_protect *)skb->data; + + h2c->c0 = le32_encode_bits(BIT(phy_idx), RTW89_H2C_TRX_PROTECT_C0_BAND_BITMAP) | + le32_encode_bits(0, RTW89_H2C_TRX_PROTECT_C0_OP_MODE); + h2c->c1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_RX_IN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_PPDU_STS) | + le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_RX_IN) | + le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_PPDU_STS); + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_HI) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_UL) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); + h2c->m0 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_HI | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN | + RTW89_H2C_TRX_PROTECT_W0_TXEN_UL | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); + h2c->w1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_DFS_EN); + h2c->m1 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN | + RTW89_H2C_TRX_PROTECT_W1_DFS_EN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_TRX_PROTECT, 0, 1, len); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, + RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to trx protect\n"); + return ret; + } + + return 0; +} + +int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, + struct rtw89_fw_h2c_rf_reg_info *info, + u16 len, u8 page) +{ + struct sk_buff *skb; + u8 class = info->rf_path == RF_PATH_A ? + H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); + return -ENOMEM; + } + skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, class, page, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0; + struct rtw89_fw_h2c_rf_get_mccch *mccch; + u32 len = sizeof(*mccch); + struct sk_buff *skb; + u8 ver = U8_MAX; + int ret; + u8 idx; + + if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) { + len = sizeof(*mccch_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, len); + + idx = rfk_mcc->table_idx; + if (ver == 0) { + mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data; + mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); + mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); + mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]); + mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]); + mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]); + mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); + } else { + mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; + mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]); + mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]); + mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]); + mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]); + mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, + H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); + +int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx chanctx_idx, + u8 mcc_role_idx, u8 pd_val, bool en) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + struct rtw89_h2c_mcc_dig *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c mcc_dig\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_mcc_dig *)skb->data; + + h2c->w0 = le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_REG_CNT) | + le32_encode_bits(en, RTW89_H2C_MCC_DIG_W0_DM_EN) | + le32_encode_bits(mcc_role_idx, RTW89_H2C_MCC_DIG_W0_IDX) | + le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_SET) | + le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_PHY0_EN) | + le32_encode_bits(chan->channel, RTW89_H2C_MCC_DIG_W0_CENTER_CH) | + le32_encode_bits(chan->band_type, RTW89_H2C_MCC_DIG_W0_BAND_TYPE); + h2c->w1 = le32_encode_bits(dig_regs->seg0_pd_reg, + RTW89_H2C_MCC_DIG_W1_ADDR_LSB) | + le32_encode_bits(dig_regs->seg0_pd_reg >> 8, + RTW89_H2C_MCC_DIG_W1_ADDR_MSB) | + le32_encode_bits(dig_regs->pd_lower_bound_mask, + RTW89_H2C_MCC_DIG_W1_BMASK_LSB) | + le32_encode_bits(dig_regs->pd_lower_bound_mask >> 8, + RTW89_H2C_MCC_DIG_W1_BMASK_MSB); + h2c->w2 = le32_encode_bits(pd_val, RTW89_H2C_MCC_DIG_W2_VAL_LSB); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, + H2C_FUNC_FW_MCC_DIG, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_h2c_rf_ps_info *h2c; + const struct rtw89_chan *chan; + u32 len = sizeof(*h2c); + unsigned int link_id; + struct sk_buff *skb; + int ret; + u8 path; + u32 val; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_ps_info *)skb->data; + h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx); + val = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + if (path >= chip->rf_path_num || path >= NUM_OF_RTW89_FW_RFK_PATH) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", path); + ret = -ENOENT; + goto fail; + } + + h2c->rf18[path] = cpu_to_le32(val); + h2c->pri_ch[path] = chan->primary_channel; + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, + H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0, + sizeof(*h2c)); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info); + +int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_fw_h2c_rfk_pre_info_common *common; + struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0; + struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1; + struct rtw89_fw_h2c_rfk_pre_info_v2 *h2c_v2; + struct rtw89_fw_h2c_rfk_pre_info *h2c; + u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH]; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + u8 tbl, path; + u32 val32; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V3, &rtwdev->fw)) { + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) { + len = sizeof(*h2c_v2); + ver = 2; + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) { + len = sizeof(*h2c_v1); + ver = 1; + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n"); + return -ENOMEM; + } + skb_put(skb, len); + + if (ver <= 2) + goto old_format; + + h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data; + + h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c->phy_idx = cpu_to_le32(phy_idx); + h2c->mlo_1_1 = cpu_to_le32(rtw89_is_mlo_1_1(rtwdev)); + + goto done; + +old_format: + h2c_v2 = (struct rtw89_fw_h2c_rfk_pre_info_v2 *)skb->data; + common = &h2c_v2->base_v1.common; + + common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + + BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); + BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH); + + for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + common->dbcc.ch[path][tbl] = + cpu_to_le32(rfk_mcc->data[path].ch[tbl]); + common->dbcc.band[path][tbl] = + cpu_to_le32(rfk_mcc->data[path].band[tbl]); + } + } + + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + tbl_sel[path] = rfk_mcc->data[path].table_idx; + + common->tbl.cur_ch[path] = + cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]); + common->tbl.cur_band[path] = + cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]); + + if (ver <= 1) + continue; + + h2c_v2->cur_bandwidth[path] = + cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]); + } + + common->phy_idx = cpu_to_le32(phy_idx); + + if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */ + h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data; + + h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]); + h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]); + h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]); + + val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1); + h2c_v0->ktbl_sel0 = cpu_to_le32(val32); + val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1); + h2c_v0->ktbl_sel1 = cpu_to_le32(val32); + val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + h2c_v0->rfmod0 = cpu_to_le32(val32); + val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK); + h2c_v0->rfmod1 = cpu_to_le32(val32); + + if (rtw89_is_mlo_1_1(rtwdev)) + h2c_v0->mlo_1_1 = cpu_to_le32(1); + + h2c_v0->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type); + + goto done; + } + + if (rtw89_is_mlo_1_1(rtwdev)) { + h2c_v1 = &h2c_v2->base_v1; + h2c_v1->mlo_1_1 = cpu_to_le32(1); + } +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_PRE_NOTIFY, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_mcc_info *rfk_mcc_v0 = &rtwdev->rfk_mcc; + struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *h2c_v0; + struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *h2c_v1; + struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c; + struct rtw89_hal *hal = &rtwdev->hal; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + u8 tbl, path; + u8 tbl_sel; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V2, &rtwdev->fw)) { + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) { + len = sizeof(*h2c_v1); + ver = 1; + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V0, &rtwdev->fw)) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n"); + return -ENOMEM; + } + skb_put(skb, len); + + if (ver != 0) + goto v1; + + h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *)skb->data; + for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + h2c_v0->tbl_18[tbl][path] = + cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl]); + tbl_sel = rfk_mcc_v0->data[path].table_idx; + h2c_v0->cur_18[path] = + cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl_sel]); + } + } + + h2c_v0->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + goto done; + +v1: + h2c_v1 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *)skb->data; + + BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); + + for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) + h2c_v1->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]); + + BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH); + + /* shared table array, but tbl_sel can be independent by path */ + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + tbl = rfk_mcc[path].table_idx; + h2c_v1->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]); + + if (path == phy_idx) + h2c_v1->tbl_idx = tbl; + } + + h2c_v1->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c_v1->phy_idx = phy_idx; + + if (rtw89_is_mlo_1_1(rtwdev)) + h2c_v1->mlo_1_1 = cpu_to_le32(1); + + if (ver == 1) + goto done; + + h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data; + + h2c->aid = cpu_to_le32(hal->aid); + h2c->acv = hal->acv; + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, + H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_h2c_rf_tssi *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF TSSI\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_tssi *)skb->data; + + h2c->len = cpu_to_le16(len); + h2c->phy = phy_idx; + h2c->ch = chan->channel; + h2c->bw = chan->band_width; + h2c->band = chan->band_type; + h2c->cv = hal->cv; + h2c->tssi_mode = tssi_mode; + h2c->rfe_type = efuse->rfe_type; + + if (chip->chip_id == RTL8922A) + h2c->hwtx_en = true; + else + h2c->hwtx_en = false; + + rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c); + rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_TSSI_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_h2c_rf_iqk_v0 *h2c_v0; + struct rtw89_h2c_rf_iqk *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_IQK_V0, &rtwdev->fw)) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n"); + return -ENOMEM; + } + skb_put(skb, len); + + if (ver == 0) { + h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data; + + h2c_v0->phy_idx = cpu_to_le32(phy_idx); + h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en); + + goto done; + } + + h2c = (struct rtw89_h2c_rf_iqk *)skb->data; + + h2c->len = sizeof(*h2c); + h2c->ktype = 0; + h2c->phy = phy_idx; + h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx); + h2c->band = chan->band_type; + h2c->bw = chan->band_width; + h2c->ch = chan->channel; + h2c->cv = hal->cv; + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_h2c_rf_dpk *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_dpk *)skb->data; + + h2c->len = len; + h2c->phy = phy_idx; + h2c->dpk_enable = true; + h2c->kpath = RF_AB; + h2c->cur_band = chan->band_type; + h2c->cur_bw = chan->band_width; + h2c->cur_ch = chan->channel; + h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_h2c_rf_txgapk *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_txgapk *)skb->data; + + h2c->len = len; + h2c->ktype = 2; + h2c->phy = phy_idx; + h2c->kpath = RF_AB; + h2c->band = chan->band_type; + h2c->bw = chan->band_width; + h2c->ch = chan->channel; + h2c->cv = hal->cv; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_h2c_rf_dack *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_dack *)skb->data; + + h2c->len = len; + h2c->phy = phy_idx; + h2c->type = 0; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, bool is_chl_k) +{ + struct rtw89_h2c_rf_rxdck_v0 *v0; + struct rtw89_h2c_rf_rxdck *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ver = -1; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) { + len = sizeof(*v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n"); + return -ENOMEM; + } + skb_put(skb, len); + v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data; + + v0->len = len; + v0->phy = phy_idx; + v0->is_afe = false; + v0->kpath = RF_AB; + v0->cur_band = chan->band_type; + v0->cur_bw = chan->band_width; + v0->cur_ch = chan->channel; + v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); + + if (ver == 0) + goto hdr; + + h2c = (struct rtw89_h2c_rf_rxdck *)skb->data; + h2c->is_chl_k = is_chl_k; + +hdr: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_tas_trigger(struct rtw89_dev *rtwdev, bool enable) +{ + struct rtw89_h2c_rf_tas *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF TAS\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_tas *)skb->data; + + h2c->enable = cpu_to_le32(enable); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_TAS_OFFLOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_txiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_h2c_rf_txiqk_v0 *h2c_v0; + struct rtw89_h2c_rf_txiqk *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_TXIQK_V0, &rtwdev->fw)) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXIQK\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c_v0 = (struct rtw89_h2c_rf_txiqk_v0 *)skb->data; + + h2c_v0->len = len; + h2c_v0->phy = phy_idx; + h2c_v0->txiqk_enable = true; + h2c_v0->is_wb_txiqk = true; + h2c_v0->kpath = RF_AB; + h2c_v0->cur_band = chan->band_type; + h2c_v0->cur_bw = chan->band_width; + h2c_v0->cur_ch = chan->channel; + h2c_v0->txiqk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); + + if (ver == 0) + goto hdr; + + h2c = (struct rtw89_h2c_rf_txiqk *)skb->data; + h2c->is_ther_rek = false; + +hdr: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_TXIQK_OFFOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_rf_cim3k(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + struct rtw89_h2c_rf_cim3k *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c RF CIM3K\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_rf_cim3k *)skb->data; + + h2c->len = len; + h2c->phy = phy_idx; + h2c->kpath = RF_AB; + h2c->cur_band = chan->band_type; + h2c->cur_bw = chan->band_width; + h2c->cur_ch = chan->channel; + h2c->cim3k_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, + H2C_FUNC_RFK_CIM3K_OFFOAD, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, + u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, + bool rack, bool dack) +{ + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); + return -ENOMEM; + } + skb_put_data(skb, buf, len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) +{ + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); + return -ENOMEM; + } + skb_put_data(skb, buf, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) +{ + struct rtw89_early_h2c *early_h2c; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { + rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); + } +} + +void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) +{ + struct rtw89_early_h2c *early_h2c, *tmp; + + list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { + list_del(&early_h2c->list); + kfree(early_h2c->h2c); + kfree(early_h2c); + } +} + +void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + __rtw89_fw_free_all_early_h2c(rtwdev); +} + +void rtw89_fw_c2h_dummy_handler(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); + u8 category = attr->category; + u8 class = attr->class; + u8 func = attr->func; + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "C2H cate=%u cls=%u func=%u is dummy\n", category, class, func); +} + +static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) +{ + const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data; + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); + + attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY); + attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS); + attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC); + attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN); +} + +static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, + struct sk_buff *c2h) +{ + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); + u8 category = attr->category; + u8 class = attr->class; + u8 func = attr->func; + + switch (category) { + default: + return false; + case RTW89_C2H_CAT_MAC: + return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func); + case RTW89_C2H_CAT_OUTSRC: + return rtw89_phy_c2h_chk_atomic(rtwdev, class, func); + } +} + +void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) +{ + rtw89_fw_c2h_parse_attr(c2h); + if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) + goto enqueue; + + rtw89_fw_c2h_cmd_handle(rtwdev, c2h); + dev_kfree_skb_any(c2h); + return; + +enqueue: + skb_queue_tail(&rtwdev->c2h_queue, c2h); + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work); +} + +static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); + u8 category = attr->category; + u8 class = attr->class; + u8 func = attr->func; + u16 len = attr->len; + bool dump = true; + + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) + return; + + switch (category) { + case RTW89_C2H_CAT_TEST: + break; + case RTW89_C2H_CAT_MAC: + rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); + if (class == RTW89_MAC_C2H_CLASS_INFO && + func == RTW89_MAC_C2H_FUNC_C2H_LOG) + dump = false; + break; + case RTW89_C2H_CAT_OUTSRC: + if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && + class <= RTW89_PHY_C2H_CLASS_BTC_MAX) + rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); + else + rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); + break; + } + + if (dump) + rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); +} + +void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + c2h_work); + struct sk_buff *skb, *tmp; + struct sk_buff_head c2hq; + unsigned long flags; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + __skb_queue_head_init(&c2hq); + + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); + skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); + + skb_queue_walk_safe(&c2hq, skb, tmp) { + rtw89_fw_c2h_cmd_handle(rtwdev, skb); + dev_kfree_skb_any(skb); + } +} + +void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct sk_buff *skb, *tmp; + struct sk_buff_head c2hq; + unsigned long flags; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + __skb_queue_head_init(&c2hq); + + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); + skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); + + skb_queue_walk_safe(&c2hq, skb, tmp) { + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); + + if (!attr->is_scan_event || attr->scan_seq == scan_info->seq) + continue; + + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "purge obsoleted scan event with seq=%d (cur=%d)\n", + attr->scan_seq, scan_info->seq); + + __skb_unlink(skb, &c2hq); + dev_kfree_skb_any(skb); + } + + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); + skb_queue_splice(&c2hq, &rtwdev->c2h_queue); + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); +} + +static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, + struct rtw89_mac_h2c_info *info) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const u32 *h2c_reg = chip->h2c_regs; + u8 i, val, len; + int ret; + + ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, + rtwdev, chip->h2c_ctrl_reg); + if (ret) { + rtw89_warn(rtwdev, "FW does not process h2c registers\n"); + return ret; + } + + len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, + sizeof(info->u.h2creg[0])); + + u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK); + u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK); + + for (i = 0; i < RTW89_H2CREG_MAX; i++) + rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]); + + fw_info->h2c_counter++; + rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, + chip->h2c_counter_reg.mask, fw_info->h2c_counter); + rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); + + return 0; +} + +static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, + struct rtw89_mac_c2h_info *info) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const u32 *c2h_reg = chip->c2h_regs; + u32 timeout; + u8 i, val; + int ret; + + info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + timeout = RTW89_C2H_TIMEOUT_USB; + else + timeout = RTW89_C2H_TIMEOUT; + + if (info->timeout) + timeout = info->timeout; + + ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, + timeout, false, rtwdev, + chip->c2h_ctrl_reg); + if (ret) { + rtw89_warn(rtwdev, "c2h reg timeout\n"); + return ret; + } + + for (i = 0; i < RTW89_C2HREG_MAX; i++) + info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); + + rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); + + info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK); + info->content_len = + (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) - + RTW89_C2HREG_HDR_LEN; + + fw_info->c2h_counter++; + rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, + chip->c2h_counter_reg.mask, fw_info->c2h_counter); + + return 0; +} + +int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, + struct rtw89_mac_h2c_info *h2c_info, + struct rtw89_mac_c2h_info *c2h_info) +{ + int ret; + + if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (!h2c_info && !c2h_info) + return -EINVAL; + + if (!h2c_info) + goto recv_c2h; + + ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); + if (ret) + return ret; + +recv_c2h: + if (!c2h_info) + return 0; + + ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); + if (ret) + return ret; + + return 0; +} + +void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { + rtw89_err(rtwdev, "[ERR]pwr is off\n"); + return; + } + + rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); + rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); + rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); + rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); + rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", + rtw89_read32(rtwdev, R_AX_HALT_C2H)); + rtw89_info(rtwdev, "R_AX_HALT_C2H_CTRL = 0x%x\n", + rtw89_read32(rtwdev, R_AX_HALT_C2H_CTRL)); + rtw89_info(rtwdev, "R_AX_HALT_H2C = 0x%x\n", + rtw89_read32(rtwdev, R_AX_HALT_H2C)); + rtw89_info(rtwdev, "R_AX_HALT_H2C_CTRL = 0x%x\n", + rtw89_read32(rtwdev, R_AX_HALT_H2C_CTRL)); + rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", + rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); + + rtw89_fw_prog_cnt_dump(rtwdev); +} + +static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; + struct rtw89_pktofld_info *info, *tmp; + u8 idx, wildcard_pkt_id; + + for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { + if (!(rtwdev->chip->support_bands & BIT(idx))) + continue; + + wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; + if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) + rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); + + list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { + if (test_bit(info->id, rtwdev->pkt_offload)) + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + list_del(&info->list); + kfree(info); + } + } +} + +static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + + mac->free_chan_list(rtwdev); + rtw89_hw_scan_release_pkt_list(rtwdev); + + rtwvif->scan_req = NULL; + rtwvif->scan_ies = NULL; + scan_info->scanning_vif = NULL; + scan_info->abort = false; + scan_info->connected = false; + scan_info->delay = 0; +} + +static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, + struct cfg80211_scan_request *req, + struct rtw89_pktofld_info *info, + enum nl80211_band band, u8 ssid_idx) +{ + if (band != NL80211_BAND_6GHZ) + return false; + + if (req->ssids[ssid_idx].ssid_len) { + memcpy(info->ssid, req->ssids[ssid_idx].ssid, + req->ssids[ssid_idx].ssid_len); + info->ssid_len = req->ssids[ssid_idx].ssid_len; + return false; + } else { + info->wildcard_6ghz = true; + return true; + } +} + +static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct sk_buff *skb, u8 ssid_idx) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_pktofld_info *info; + struct sk_buff *new; + int ret = 0; + u8 band; + + for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { + if (!(rtwdev->chip->support_bands & BIT(band))) + continue; + + new = skb_copy(skb, GFP_KERNEL); + if (!new) { + ret = -ENOMEM; + goto out; + } + skb_put_data(new, ies->ies[band], ies->len[band]); + skb_put_data(new, ies->common_ies, ies->common_ie_len); + + info = kzalloc_obj(*info); + if (!info) { + ret = -ENOMEM; + kfree_skb(new); + goto out; + } + + rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx); + + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); + if (ret) { + kfree_skb(new); + kfree(info); + goto out; + } + + list_add_tail(&info->list, &scan_info->pkt_list[band]); + kfree_skb(new); + } +out: + return ret; +} + +int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool wowlan) +{ + static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08, 0x0c, 0x12, + 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + enum nl80211_band band; + struct sk_buff *skb; + int ret; + u8 id; + + for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { + if (!(rtwdev->chip->support_bands & BIT(band))) + continue; + + if (wowlan) { + nd_config = rtw_wow->nd_config; + + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, NULL, 0, + nd_config->ie_len + + sizeof(basic_rate_ie)); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); + skb_put_data(skb, nd_config->ie, nd_config->ie_len); + } else { + skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, + NULL, 0, req->ie_len); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, ies->ies[band], ies->len[band]); + skb_put_data(skb, ies->common_ies, ies->common_ie_len); + } + + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &id, skb); + kfree_skb(skb); + + if (ret) + return ret; + + scan_info->wildcard_pkt_id[band] = id; + } + + return 0; +} + +static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + u8 num = req->n_ssids, i; + struct sk_buff *skb; + int ret; + + ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, mac_addr, false); + if (ret) + return ret; + + for (i = 0; i < num; i++) { + skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, + req->ssids[i].ssid, + req->ssids[i].ssid_len, + req->ie_len); + if (!skb) + return -ENOMEM; + + ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i); + kfree_skb(skb); + + if (ret) + return ret; + } + + return 0; +} + +static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev, + struct ieee80211_scan_ies *ies, + struct cfg80211_scan_request *req, + struct rtw89_mac_chinfo_ax *ch_info) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; + struct cfg80211_scan_6ghz_params *params; + struct rtw89_pktofld_info *info, *tmp; + struct ieee80211_hdr *hdr; + struct sk_buff *skb; + bool found; + int ret = 0; + u32 i; + + if (!req->n_6ghz_params) + return 0; + + for (i = 0; i < req->n_6ghz_params; i++) { + params = &req->scan_6ghz_params[i]; + + if (req->channels[params->channel_idx]->hw_value != + ch_info->pri_ch) + continue; + + found = false; + list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { + if (ether_addr_equal(tmp->bssid, params->bssid)) { + found = true; + break; + } + } + if (found) + continue; + + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, + NULL, 0, req->ie_len); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); + skb_put_data(skb, ies->common_ies, ies->common_ie_len); + hdr = (struct ieee80211_hdr *)skb->data; + ether_addr_copy(hdr->addr3, params->bssid); + + info = kzalloc_obj(*info); + if (!info) { + ret = -ENOMEM; + kfree_skb(skb); + goto out; + } + + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); + if (ret) { + kfree_skb(skb); + kfree(info); + goto out; + } + + ether_addr_copy(info->bssid, params->bssid); + info->channel_6ghz = req->channels[params->channel_idx]->hw_value; + list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); + + ch_info->tx_pkt = true; + ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; + + kfree_skb(skb); + } + +out: + return ret; +} + +static void rtw89_pno_scan_add_chan_ax(struct rtw89_dev *rtwdev, + int chan_type, int ssid_num, + struct rtw89_mac_chinfo_ax *ch_info) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_pktofld_info *info; + u8 probe_count = 0; + + ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; + ch_info->bw = RTW89_SCAN_WIDTH; + ch_info->tx_pkt = true; + ch_info->cfg_tx_pwr = false; + ch_info->tx_pwr_idx = 0; + ch_info->tx_null = false; + ch_info->pause_data = false; + ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + + if (ssid_num) { + list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { + if (info->channel_6ghz && + ch_info->pri_ch != info->channel_6ghz) + continue; + else if (info->channel_6ghz && probe_count != 0) + ch_info->period += RTW89_CHANNEL_TIME_6G; + + if (info->wildcard_6ghz) + continue; + + ch_info->pkt_id[probe_count++] = info->id; + if (probe_count >= RTW89_SCANOFLD_MAX_SSID) + break; + } + ch_info->num_pkt = probe_count; + } + + switch (chan_type) { + case RTW89_CHAN_DFS: + if (ch_info->ch_band != RTW89_BAND_6G) + ch_info->period = max_t(u8, ch_info->period, + RTW89_DFS_CHAN_TIME); + ch_info->dwell_time = RTW89_DWELL_TIME; + break; + case RTW89_CHAN_ACTIVE: + break; + default: + rtw89_err(rtwdev, "Channel type out of bound\n"); + } +} + +static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, + int ssid_num, + struct rtw89_mac_chinfo_ax *ch_info) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_chan *op = &rtwdev->scan_info.op_chan; + struct rtw89_pktofld_info *info; + struct ieee80211_vif *vif; + u8 band, probe_count = 0; + int ret; + + ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; + ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; + ch_info->bw = RTW89_SCAN_WIDTH; + ch_info->tx_pkt = true; + ch_info->cfg_tx_pwr = false; + ch_info->tx_pwr_idx = 0; + ch_info->tx_null = false; + ch_info->pause_data = false; + ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + + if (ch_info->ch_band == RTW89_BAND_6G) { + if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || + !ch_info->is_psc) { + ch_info->tx_pkt = false; + if (!req->duration_mandatory) + ch_info->period -= RTW89_DWELL_TIME_6G; + } + } + + ret = rtw89_update_6ghz_rnr_chan_ax(rtwdev, ies, req, ch_info); + if (ret) + rtw89_warn(rtwdev, "RNR fails: %d\n", ret); + + if (ssid_num) { + band = rtw89_hw_to_nl80211_band(ch_info->ch_band); + + list_for_each_entry(info, &scan_info->pkt_list[band], list) { + if (info->channel_6ghz && + ch_info->pri_ch != info->channel_6ghz) + continue; + else if (info->channel_6ghz && probe_count != 0) + ch_info->period += RTW89_CHANNEL_TIME_6G; + + if (info->wildcard_6ghz) + continue; + + ch_info->pkt_id[probe_count++] = info->id; + if (probe_count >= RTW89_SCANOFLD_MAX_SSID) + break; + } + ch_info->num_pkt = probe_count; + } + + switch (chan_type) { + case RTW89_CHAN_OPERATE: + ch_info->central_ch = op->channel; + ch_info->pri_ch = op->primary_channel; + ch_info->ch_band = op->band_type; + ch_info->bw = op->band_width; + vif = rtwvif_link_to_vif(rtwvif_link); + ch_info->tx_null = !is_zero_ether_addr(rtwvif_link->bssid) && + vif->type != NL80211_IFTYPE_AP; + ch_info->num_pkt = 0; + break; + case RTW89_CHAN_DFS: + if (ch_info->ch_band != RTW89_BAND_6G) + ch_info->period = max_t(u8, ch_info->period, + RTW89_DFS_CHAN_TIME); + ch_info->dwell_time = RTW89_DWELL_TIME; + ch_info->pause_data = true; + break; + case RTW89_CHAN_ACTIVE: + ch_info->pause_data = true; + break; + case RTW89_CHAN_EXTRA_OP: + ch_info->central_ch = ext->chan.channel; + ch_info->pri_ch = ext->chan.primary_channel; + ch_info->ch_band = ext->chan.band_type; + ch_info->bw = ext->chan.band_width; + vif = rtwvif_link_to_vif(ext->rtwvif_link); + ch_info->tx_null = !is_zero_ether_addr(ext->rtwvif_link->bssid) && + vif->type != NL80211_IFTYPE_AP; + ch_info->num_pkt = 0; + ch_info->macid_tx = true; + break; + default: + rtw89_err(rtwdev, "Channel type out of bound\n"); + } +} + +static void rtw89_pno_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, + int ssid_num, + struct rtw89_mac_chinfo_be *ch_info) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_pktofld_info *info; + u8 probe_count = 0, i; + + ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; + ch_info->bw = RTW89_SCAN_WIDTH; + ch_info->tx_null = false; + ch_info->pause_data = false; + ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + + if (ssid_num) { + list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { + ch_info->pkt_id[probe_count++] = info->id; + if (probe_count >= RTW89_SCANOFLD_MAX_SSID) + break; + } + } + + for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) + ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; + + switch (chan_type) { + case RTW89_CHAN_DFS: + ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); + ch_info->dwell_time = RTW89_DWELL_TIME; + break; + case RTW89_CHAN_ACTIVE: + break; + default: + rtw89_warn(rtwdev, "Channel type out of bound\n"); + break; + } +} + +static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, + int ssid_num, + struct rtw89_mac_chinfo_be *ch_info) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_pktofld_info *info; + u8 band, probe_count = 0, i; + + ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; + ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; + ch_info->bw = RTW89_SCAN_WIDTH; + ch_info->tx_null = false; + ch_info->pause_data = false; + ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + + if (ssid_num) { + band = rtw89_hw_to_nl80211_band(ch_info->ch_band); + + list_for_each_entry(info, &scan_info->pkt_list[band], list) { + if (info->channel_6ghz && + ch_info->pri_ch != info->channel_6ghz) + continue; + + if (info->wildcard_6ghz) + continue; + + ch_info->pkt_id[probe_count++] = info->id; + if (probe_count >= RTW89_SCANOFLD_MAX_SSID) + break; + } + + if (scan_info->n_ssids) + ch_info->fw_probe0_ssids = GENMASK(scan_info->n_ssids - 1, 0); + } + + if (ch_info->ch_band == RTW89_BAND_6G) { + if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || + !ch_info->is_psc) { + ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + if (!req->duration_mandatory) + ch_info->period -= RTW89_DWELL_TIME_6G; + } + } + + for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) + ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; + + switch (chan_type) { + case RTW89_CHAN_DFS: + if (ch_info->ch_band != RTW89_BAND_6G) + ch_info->period = + max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); + ch_info->dwell_time = RTW89_DWELL_TIME; + ch_info->pause_data = true; + break; + case RTW89_CHAN_ACTIVE: + ch_info->pause_data = true; + break; + default: + rtw89_warn(rtwdev, "Channel type out of bound\n"); + break; + } +} + +int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; + struct rtw89_mac_chinfo_ax *ch_info, *tmp; + struct ieee80211_channel *channel; + struct list_head chan_list; + int list_len; + enum rtw89_chan_type type; + int ret = 0; + u32 idx; + + INIT_LIST_HEAD(&chan_list); + for (idx = 0, list_len = 0; + idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX; + idx++, list_len++) { + channel = nd_config->channels[idx]; + ch_info = kzalloc_obj(*ch_info); + if (!ch_info) { + ret = -ENOMEM; + goto out; + } + + ch_info->period = RTW89_CHANNEL_TIME; + ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); + ch_info->central_ch = channel->hw_value; + ch_info->pri_ch = channel->hw_value; + ch_info->is_psc = cfg80211_channel_is_psc(channel); + + if (channel->flags & + (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) + type = RTW89_CHAN_DFS; + else + type = RTW89_CHAN_ACTIVE; + + rtw89_pno_scan_add_chan_ax(rtwdev, type, nd_config->n_match_sets, ch_info); + list_add_tail(&ch_info->list, &chan_list); + } + ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list); + +out: + list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev, + enum rtw89_chan_type type, + struct list_head *chan_list, + struct cfg80211_scan_request *req, + int *off_chan_time) +{ + struct rtw89_mac_chinfo_ax *tmp; + + tmp = kzalloc_obj(*tmp); + if (!tmp) + return -ENOMEM; + + switch (type) { + case RTW89_CHAN_OPERATE: + tmp->period = req->duration_mandatory ? + req->duration : RTW89_CHANNEL_TIME; + *off_chan_time = 0; + break; + case RTW89_CHAN_EXTRA_OP: + tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP; + /* still calc @off_chan_time for scan op */ + *off_chan_time += tmp->period; + break; + default: + kfree(tmp); + return -EINVAL; + } + + rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp); + list_add_tail(&tmp->list, chan_list); + + return 0; +} + +int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_mac_chinfo_ax *ch_info, *tmp; + struct ieee80211_channel *channel; + struct list_head chan_list; + bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; + enum rtw89_chan_type type; + int off_chan_time = 0; + int ret; + u32 idx; + + INIT_LIST_HEAD(&chan_list); + + for (idx = 0; idx < req->n_channels; idx++) { + channel = req->channels[idx]; + ch_info = kzalloc_obj(*ch_info); + if (!ch_info) { + ret = -ENOMEM; + goto out; + } + + if (req->duration) + ch_info->period = req->duration; + else if (channel->band == NL80211_BAND_6GHZ) + ch_info->period = RTW89_CHANNEL_TIME_6G + + RTW89_DWELL_TIME_6G; + else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + ch_info->period = RTW89_P2P_CHAN_TIME; + else + ch_info->period = RTW89_CHANNEL_TIME; + + ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); + ch_info->central_ch = channel->hw_value; + ch_info->pri_ch = channel->hw_value; + ch_info->rand_seq_num = random_seq; + ch_info->is_psc = cfg80211_channel_is_psc(channel); + + if (channel->flags & + (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) + type = RTW89_CHAN_DFS; + else + type = RTW89_CHAN_ACTIVE; + rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info); + + if (!(scan_info->connected && + off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME)) + goto next; + + ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE, + &chan_list, req, &off_chan_time); + if (ret) { + kfree(ch_info); + goto out; + } + + if (!ext->set) + goto next; + + ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP, + &chan_list, req, &off_chan_time); + if (ret) { + kfree(ch_info); + goto out; + } + +next: + list_add_tail(&ch_info->list, &chan_list); + off_chan_time += ch_info->period; + } + + list_splice_tail(&chan_list, &scan_info->chan_list); + return 0; + +out: + list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_mac_chinfo_ax *ch_info, *tmp; + + list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } +} + +int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_mac_chinfo_ax *ch_info, *tmp; + unsigned int list_len = 0; + struct list_head list; + int ret; + + INIT_LIST_HEAD(&list); + + list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { + /* The operating channel (tx_null == true) should + * not be last in the list, to avoid breaking + * RTL8851BU and RTL8832BU. + */ + if (list_len + 1 == RTW89_SCAN_LIST_LIMIT_AX && ch_info->tx_null) + break; + + list_move_tail(&ch_info->list, &list); + + list_len++; + if (list_len == RTW89_SCAN_LIST_LIMIT_AX) + break; + } + + ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list); + + list_for_each_entry_safe(ch_info, tmp, &list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; + struct rtw89_mac_chinfo_be *ch_info, *tmp; + struct ieee80211_channel *channel; + struct list_head chan_list; + enum rtw89_chan_type type; + int list_len, ret; + u32 idx; + + INIT_LIST_HEAD(&chan_list); + + for (idx = 0, list_len = 0; + idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE; + idx++, list_len++) { + channel = nd_config->channels[idx]; + ch_info = kzalloc_obj(*ch_info); + if (!ch_info) { + ret = -ENOMEM; + goto out; + } + + ch_info->period = RTW89_CHANNEL_TIME; + ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); + ch_info->central_ch = channel->hw_value; + ch_info->pri_ch = channel->hw_value; + ch_info->is_psc = cfg80211_channel_is_psc(channel); + + if (channel->flags & + (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) + type = RTW89_CHAN_DFS; + else + type = RTW89_CHAN_ACTIVE; + + rtw89_pno_scan_add_chan_be(rtwdev, type, + nd_config->n_match_sets, ch_info); + list_add_tail(&ch_info->list, &chan_list); + } + + ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list, + rtwvif_link); + +out: + list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_mac_chinfo_be *ch_info, *tmp; + struct ieee80211_channel *channel; + struct list_head chan_list; + enum rtw89_chan_type type; + bool chan_by_rnr; + bool random_seq; + int ret; + u32 idx; + + random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN); + chan_by_rnr = rtwdev->chip->support_rnr && + (req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ); + INIT_LIST_HEAD(&chan_list); + + for (idx = 0; idx < req->n_channels; idx++) { + channel = req->channels[idx]; + + if (channel->band == NL80211_BAND_6GHZ && + !cfg80211_channel_is_psc(channel) && chan_by_rnr) + continue; + + ch_info = kzalloc_obj(*ch_info); + if (!ch_info) { + ret = -ENOMEM; + goto out; + } + + if (req->duration) + ch_info->period = req->duration; + else if (channel->band == NL80211_BAND_6GHZ) + ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; + else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + ch_info->period = RTW89_P2P_CHAN_TIME; + else + ch_info->period = RTW89_CHANNEL_TIME; + + ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); + ch_info->central_ch = channel->hw_value; + ch_info->pri_ch = channel->hw_value; + ch_info->rand_seq_num = random_seq; + ch_info->is_psc = cfg80211_channel_is_psc(channel); + + if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) + type = RTW89_CHAN_DFS; + else + type = RTW89_CHAN_ACTIVE; + rtw89_hw_scan_add_chan_be(rtwdev, type, req->n_ssids, ch_info); + + list_add_tail(&ch_info->list, &chan_list); + } + + list_splice_tail(&chan_list, &scan_info->chan_list); + return 0; + +out: + list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_mac_chinfo_be *ch_info, *tmp; + + list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } +} + +int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_mac_chinfo_be *ch_info, *tmp; + unsigned int list_len = 0; + struct list_head list; + int ret; + + INIT_LIST_HEAD(&list); + + list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { + list_move_tail(&ch_info->list, &list); + + list_len++; + if (list_len == RTW89_SCAN_LIST_LIMIT_BE) + break; + } + + ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list, + rtwvif_link); + + list_for_each_entry_safe(ch_info, tmp, &list, list) { + list_del(&ch_info->list); + kfree(ch_info); + } + + return ret; +} + +static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + int ret; + + ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr); + if (ret) { + rtw89_err(rtwdev, "Update probe request failed\n"); + goto out; + } + ret = mac->prep_chan_list(rtwdev, rtwvif_link); +out: + return ret; +} + +static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 tu, bool scan) +{ + struct ieee80211_p2p_noa_desc noa_desc = {}; + struct ieee80211_bss_conf *bss_conf; + u16 beacon_int; + u64 tsf; + int ret; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + beacon_int = bss_conf->beacon_int; + + rcu_read_unlock(); + + tu += beacon_int * 3; + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000; + + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); + if (ret) { + rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__); + return; + } + + noa_desc.start_time = cpu_to_le32(tsf); + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) { + noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu)); + noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu)); + noa_desc.count = 1; + } else { + noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(20000)); + noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(20000)); + noa_desc.count = 255; + } + + rtw89_p2p_noa_renew(rtwvif_link); + if (scan) + rtw89_p2p_noa_append(rtwvif_link, &noa_desc); + + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); +} + +static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev, bool scan) +{ + const struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_mac_chinfo_ax *chinfo_ax; + struct rtw89_mac_chinfo_be *chinfo_be; + struct rtw89_vif_link *rtwvif_link; + struct list_head *pos, *tmp; + struct ieee80211_vif *vif; + struct rtw89_vif *rtwvif; + u16 tu = 0; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (!scan) + goto update; + + list_for_each_safe(pos, tmp, &scan_info->chan_list) { + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + chinfo_ax = list_entry(pos, typeof(*chinfo_ax), list); + tu += chinfo_ax->period; + break; + case RTW89_CHIP_BE: + chinfo_be = list_entry(pos, typeof(*chinfo_be), list); + tu += chinfo_be->period; + break; + default: + rtw89_warn(rtwdev, "%s: invalid chip gen %d\n", + __func__, chip->chip_gen); + return; + } + } + + if (unlikely(tu == 0)) { + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "%s: cannot estimate needed TU\n", __func__); + return; + } + +update: + list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) { + unsigned int link_id; + + vif = rtwvif_to_vif(rtwvif); + if (vif->type != NL80211_IFTYPE_AP || !vif->p2p) + continue; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link, + tu, scan); + } +} + +static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev, + struct rtw89_vif *scan_rtwvif, + const struct rtw89_chan *scan_op) +{ + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; + struct rtw89_vif *tmp; + + ext->set = false; + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw)) + return; + + list_for_each_entry(tmp, &mgnt->active_list, mgnt_entry) { + const struct rtw89_chan *tmp_chan; + struct rtw89_vif_link *tmp_link; + + if (tmp == scan_rtwvif) + continue; + + tmp_link = rtw89_get_designated_link(tmp); + if (unlikely(!tmp_link)) + continue; + + tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx); + *ext = (struct rtw89_hw_scan_extra_op){ + .set = true, + .macid = tmp_link->mac_id, + .port = tmp_link->port, + .chan = *tmp_chan, + .rtwvif_link = tmp_link, + }; + + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "hw scan: extra op: center %d primary %d\n", + ext->chan.channel, ext->chan.primary_channel); + break; + } +} + +int rtw89_hw_scan_start(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_scan_request *scan_req) +{ + enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); + struct cfg80211_scan_request *req = &scan_req->req; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_chanctx_pause_parm pause_parm = { + .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, + .trigger = rtwvif_link, + }; + u32 rx_fltr = rtwdev->hal.rx_fltr; + u8 mac_addr[ETH_ALEN]; + int ret; + + /* clone op and keep it during scan */ + rtwdev->scan_info.op_chan = *chan; + + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "hw scan: op: center %d primary %d\n", + chan->channel, chan->primary_channel); + + rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan); + + rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); + rtwdev->scan_info.scanning_vif = rtwvif_link; + rtwdev->scan_info.abort = false; + rtwdev->scan_info.delay = 0; + rtwvif->scan_ies = &scan_req->ies; + rtwvif->scan_req = req; + rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link, false); + + memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE, + sizeof(rtwdev->scan_info.wildcard_pkt_id)); + + if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) + get_random_mask_addr(mac_addr, req->mac_addr, + req->mac_addr_mask); + else if (ieee80211_vif_is_mld(vif)) + ether_addr_copy(mac_addr, vif->addr); + else + ether_addr_copy(mac_addr, rtwvif_link->mac_addr); + + ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr); + if (ret) { + rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); + return ret; + } + + ieee80211_stop_queues(rtwdev->hw); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false); + + rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true); + + rx_fltr &= ~B_AX_A_BCN_CHK_EN; + rx_fltr &= ~B_AX_A_BC; + rx_fltr &= ~B_AX_A_A1_MATCH; + + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rx_fltr); + + rtw89_chanctx_pause(rtwdev, &pause_parm); + rtw89_phy_dig_suspend(rtwdev); + + if (mode == RTW89_ENTITY_MODE_MCC) + rtw89_hw_scan_update_beacon_noa(rtwdev, true); + + return 0; +} + +struct rtw89_hw_scan_complete_cb_data { + struct rtw89_vif_link *rtwvif_link; + bool aborted; +}; + +static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data) +{ + enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); + struct rtw89_hw_scan_complete_cb_data *cb_data = data; + struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link; + struct cfg80211_scan_info info = { + .aborted = cb_data->aborted, + }; + + if (!rtwvif_link) + return -EINVAL; + + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr); + + rtw89_core_scan_complete(rtwdev, rtwvif_link, true); + ieee80211_scan_completed(rtwdev->hw, &info); + ieee80211_wake_queues(rtwdev->hw); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true); + rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); + rtw89_phy_dig_resume(rtwdev, true); + + rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); + + if (mode == RTW89_ENTITY_MODE_MCC) + rtw89_hw_scan_update_beacon_noa(rtwdev, false); + + return 0; +} + +void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool aborted) +{ + struct rtw89_hw_scan_complete_cb_data cb_data = { + .rtwvif_link = rtwvif_link, + .aborted = aborted, + }; + const struct rtw89_chanctx_cb_parm cb_parm = { + .cb = rtw89_hw_scan_complete_cb, + .data = &cb_data, + .caller = __func__, + }; + + /* The things here needs to be done after setting channel (for coex) + * and before proceeding entity mode (for MCC). So, pass a callback + * of them for the right sequence rather than doing them directly. + */ + rtw89_chanctx_proceed(rtwdev, &cb_parm); +} + +void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + int ret; + + scan_info->abort = true; + + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false); + if (ret) + rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret); + + /* Indicate ieee80211_scan_completed() before returning, which is safe + * because scan abort command always waits for completion of + * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan + * work properly. + */ + rtw89_hw_scan_complete(rtwdev, rtwvif_link, true); +} + +static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + /* This variable implies connected or during attempt to connect */ + if (!is_zero_ether_addr(rtwvif_link->bssid)) + return true; + } + } + + return false; +} + +int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; + struct rtw89_scan_option opt = {0}; + bool connected; + int ret = 0; + + if (!rtwvif_link) + return -EINVAL; + + connected = rtwdev->scan_info.connected; + opt.enable = enable; + opt.target_ch_mode = connected; + opt.delay = rtwdev->scan_info.delay; + if (enable) { + ret = mac->add_chan_list(rtwdev, rtwvif_link); + if (ret) + goto out; + } + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { + opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; + opt.scan_mode = RTW89_SCAN_MODE_SA; + opt.band = rtwvif_link->mac_idx; + opt.num_macc_role = 0; + opt.mlo_mode = rtwdev->mlo_dbcc_mode; + opt.num_opch = connected ? 1 : 0; + if (connected && ext->set) + opt.num_opch++; + + opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID; + } + + ret = rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, false); + +out: + return ret; +} + +#define H2C_FW_CPU_EXCEPTION_TYPE_0 0x5566 +#define H2C_FW_CPU_EXCEPTION_TYPE_1 0x0 +int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) +{ + struct rtw89_h2c_trig_cpu_except *h2c; + u32 cpu_exception_type_def; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_1, &rtwdev->fw)) + cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_1; + else if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_0, &rtwdev->fw)) + cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_0; + else + return -EOPNOTSUPP; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for fw cpu exception\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_trig_cpu_except *)skb->data; + + h2c->w0 = le32_encode_bits(cpu_exception_type_def, + RTW89_H2C_CPU_EXCEPTION_TYPE); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_TEST, + H2C_CL_FW_STATUS_TEST, + H2C_FUNC_CPU_EXCEPTION, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return ret; + } + + return 0; +} + +#define H2C_PKT_DROP_LEN 24 +int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, + const struct rtw89_pkt_drop_params *params) +{ + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for packet drop\n"); + return -ENOMEM; + } + + switch (params->sel) { + case RTW89_PKT_DROP_SEL_MACID_BE_ONCE: + case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: + case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: + case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: + case RTW89_PKT_DROP_SEL_BAND_ONCE: + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_FW, + "H2C of pkt drop might not fully support sel: %d yet\n", + params->sel); + break; + } + + skb_put(skb, H2C_PKT_DROP_LEN); + RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel); + RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid); + RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band); + RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); + RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); + RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); + RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, + params->macid_band_sel[0]); + RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, + params->macid_band_sel[1]); + RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, + params->macid_band_sel[2]); + RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, + params->macid_band_sel[3]); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FW_OFLD, + H2C_FUNC_PKT_DROP, 0, 0, + H2C_PKT_DROP_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + return ret; +} + +#define H2C_KEEP_ALIVE_LEN 4 +int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct sk_buff *skb; + u8 pkt_id = 0; + int ret; + + if (enable) { + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_ARP_RSP, + &pkt_id); + if (ret) + return -EPERM; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_KEEP_ALIVE_LEN); + + RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); + RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); + RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); + RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_KEEP_ALIVE, 0, 1, + H2C_KEEP_ALIVE_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_h2c_arp_offload *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 pkt_id = 0; + int ret; + + if (enable) { + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_ARP_RSP, + &pkt_id); + if (ret) + return ret; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for arp offload\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_arp_offload *)skb->data; + + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) | + le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) | + le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_ARP_OFLD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +#define H2C_DISCONNECT_DETECT_LEN 8 +int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct sk_buff *skb; + u8 macid = rtwvif_link->mac_id; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_DISCONNECT_DETECT_LEN); + + if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { + RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); + RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); + RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); + RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); + RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_DISCONNECT_DETECT, 0, 1, + H2C_DISCONNECT_DETECT_LEN); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; + struct rtw89_h2c_cfg_nlo *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret, i; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for nlo\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_cfg_nlo *)skb->data; + + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) | + le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID); + + if (enable) { + h2c->nlo_cnt = nd_config->n_match_sets; + for (i = 0 ; i < nd_config->n_match_sets; i++) { + h2c->ssid_len[i] = nd_config->match_sets[i].ssid.ssid_len; + memcpy(h2c->ssid[i], nd_config->match_sets[i].ssid.ssid, + nd_config->match_sets[i].ssid.ssid_len); + } + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_NLO, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + return ret; +} + +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_h2c_wow_global *h2c; + u8 macid = rtwvif_link->mac_id; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for wow global\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_global *)skb->data; + + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) | + le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) | + le32_encode_bits(rtw_wow->ptk_alg, + RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) | + le32_encode_bits(rtw_wow->gtk_alg, + RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO); + h2c->key_info = rtw_wow->key_info; + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_WOW_GLOBAL, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_h2c_wow_wakeup_ctrl *h2c; + struct sk_buff *skb; + u32 len = sizeof(*h2c); + u8 macid = rtwvif_link->mac_id; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_wakeup_ctrl *)skb->data; + + if (rtw_wow->pattern_cnt) + h2c->w0 |= le32_encode_bits(enable, + RTW89_H2C_WOW_WAKEUP_CTRL_W0_PATTERN_MATCH_ENABLE); + if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) { + h2c->w0 |= le32_encode_bits(enable, + RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_ENABLE); + if (ieee80211_vif_is_mld(vif)) + h2c->w0 |= le32_encode_bits(enable, + RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_MLD_ENABLE); + } + + if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) + h2c->w0 |= le32_encode_bits(enable, + RTW89_H2C_WOW_WAKEUP_CTRL_W0_DEAUTH_ENABLE); + + h2c->w0 |= le32_encode_bits(macid, RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_WAKEUP_CTRL, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) +{ + struct rtw89_h2c_wow_cam_update *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for wow cam update\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_cam_update *)skb->data; + + h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_CAM_UPD_W0_R_W) | + le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_CAM_UPD_W0_IDX); + + if (!cam_info->valid) + goto fill_valid; + + h2c->wkfm0 = cam_info->mask[0]; + h2c->wkfm1 = cam_info->mask[1]; + h2c->wkfm2 = cam_info->mask[2]; + h2c->wkfm3 = cam_info->mask[3]; + h2c->w5 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_CAM_UPD_W5_CRC) | + le32_encode_bits(cam_info->negative_pattern_match, + RTW89_H2C_WOW_CAM_UPD_W5_NEGATIVE_PATTERN_MATCH) | + le32_encode_bits(cam_info->skip_mac_hdr, + RTW89_H2C_WOW_CAM_UPD_W5_SKIP_MAC_HDR) | + le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_CAM_UPD_W5_UC) | + le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_CAM_UPD_W5_MC) | + le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_CAM_UPD_W5_BC); +fill_valid: + h2c->w5 |= le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_CAM_UPD_W5_VALID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_WOW_CAM_UPD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update); + +int rtw89_fw_h2c_wow_cam_update_v1(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) +{ + struct rtw89_h2c_wow_payload_cam_update *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for wow payload cam update\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_payload_cam_update *)skb->data; + + h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_PLD_CAM_UPD_W0_R_W) | + le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_PLD_CAM_UPD_W0_IDX); + h2c->w8 = le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_PLD_CAM_UPD_W8_VALID) | + le32_encode_bits(1, RTW89_H2C_WOW_PLD_CAM_UPD_W8_WOW_PTR); + + if (!cam_info->valid) + goto done; + + h2c->wkfm0 = cam_info->mask[0]; + h2c->wkfm1 = cam_info->mask[1]; + h2c->wkfm2 = cam_info->mask[2]; + h2c->wkfm3 = cam_info->mask[3]; + h2c->w5 = le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_UC) | + le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_MC) | + le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_BC) | + le32_encode_bits(cam_info->skip_mac_hdr, + RTW89_H2C_WOW_PLD_CAM_UPD_W5_SKIP_MAC_HDR); + h2c->w6 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_PLD_CAM_UPD_W6_CRC); + h2c->w7 = le32_encode_bits(cam_info->negative_pattern_match, + RTW89_H2C_WOW_PLD_CAM_UPD_W7_NEGATIVE_PATTERN_MATCH); + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_WOW_PLD_CAM_UPD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update_v1); + +int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; + struct rtw89_h2c_wow_gtk_ofld *h2c; + u8 macid = rtwvif_link->mac_id; + u32 len = sizeof(*h2c); + u8 pkt_id_sa_query = 0; + struct sk_buff *skb; + u8 pkt_id_eapol = 0; + int ret; + + if (!rtw_wow->gtk_alg) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data; + + if (!enable) + goto hdr; + + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_EAPOL_KEY, + &pkt_id_eapol); + if (ret) + goto fail; + + if (gtk_info->igtk_keyid) { + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, + RTW89_PKT_OFLD_TYPE_SA_QUERY, + &pkt_id_sa_query); + if (ret) + goto fail; + } + + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) | + le32_encode_bits(!!memchr_inv(gtk_info->txmickey, 0, + sizeof(gtk_info->txmickey)), + RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) | + le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0, + RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) | + le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) | + le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID); + h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0, + RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) | + le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT); + h2c->gtk_info = rtw_wow->gtk_info; + +hdr: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_GTK_OFLD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + +int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait; + struct rtw89_h2c_fwips *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw ips\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_fwips *)skb->data; + + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) | + le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_PS, + H2C_FUNC_IPS_CFG, 0, 1, + len); + + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_PS_WAIT_COND_IPS_CFG); +} + +int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev) +{ + struct rtw89_wait_info *wait = &rtwdev->wow.wait; + struct rtw89_h2c_wow_aoac *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for aoac\n"); + return -ENOMEM; + } + + skb_put(skb, len); + + /* This H2C only nofity firmware to generate AOAC report C2H, + * no need any parameter. + */ + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_AOAC_REPORT_REQ, 1, 0, + len); + + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_WOW_WAIT_COND_AOAC); +} + +/* Return < 0, if failures happen during waiting for the condition. + * Return 0, when waiting for the condition succeeds. + * Return > 0, if the wait is considered unreachable due to driver/FW design, + * where 1 means during SER. + */ +static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, + struct rtw89_wait_info *wait, unsigned int cond) +{ + struct rtw89_wait_response *prep; + int ret = 0; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + prep = rtw89_wait_for_cond_prep(wait, cond); + if (IS_ERR(prep)) + goto out; + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + ret = -EBUSY; + goto out; + } + + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) { + ret = 1; + goto out; + } + +out: + return rtw89_wait_for_cond_eval(wait, prep, ret); +} + +#define H2C_ADD_MCC_LEN 16 +int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_add_req *p) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for add mcc\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_ADD_MCC_LEN); + RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); + RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); + RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); + RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); + RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); + RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); + RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); + RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); + RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); + RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); + RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); + RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); + RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); + RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); + RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); + RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); + RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); + RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); + RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); + RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_ADD_MCC, 0, 0, + H2C_ADD_MCC_LEN); + + cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_START_MCC_LEN 12 +int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_start_req *p) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for start mcc\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_START_MCC_LEN); + RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); + RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); + RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); + RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); + RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); + RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); + RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); + RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); + RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_START_MCC, 0, 0, + H2C_START_MCC_LEN); + + cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_STOP_MCC_LEN 4 +int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, + bool prev_groups) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for stop mcc\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_STOP_MCC_LEN); + RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); + RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); + RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_STOP_MCC, 0, 0, + H2C_STOP_MCC_LEN); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_DEL_MCC_GROUP_LEN 4 +int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, + bool prev_groups) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for del mcc group\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_DEL_MCC_GROUP_LEN); + RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); + RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_DEL_MCC_GROUP, 0, 0, + H2C_DEL_MCC_GROUP_LEN); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_RESET_MCC_GROUP_LEN 4 +int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for reset mcc group\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_RESET_MCC_GROUP_LEN); + RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_RESET_MCC_GROUP, 0, 0, + H2C_RESET_MCC_GROUP_LEN); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_MCC_REQ_TSF_LEN 4 +int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_tsf_req *req, + struct rtw89_mac_mcc_tsf_rpt *rpt) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct rtw89_mac_mcc_tsf_rpt *tmp; + struct sk_buff *skb; + unsigned int cond; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for mcc req tsf\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_MCC_REQ_TSF_LEN); + RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); + RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); + RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_MCC_REQ_TSF, 0, 0, + H2C_MCC_REQ_TSF_LEN); + + cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) + return ret; + + tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; + *rpt = *tmp; + + return 0; +} + +#define H2C_MCC_MACID_BITMAP_DSC_LEN 4 +int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid, + u8 *bitmap) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + u8 map_len; + u8 h2c_len; + + BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); + map_len = RTW89_MAX_MAC_ID_NUM / 8; + h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for mcc macid bitmap\n"); + return -ENOMEM; + } + + skb_put(skb, h2c_len); + RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); + RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); + RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); + RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_MCC_MACID_BITMAP, 0, 0, + h2c_len); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_MCC_SYNC_LEN 4 +int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, + u8 target, u8 offset) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for mcc sync\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_MCC_SYNC_LEN); + RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); + RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); + RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); + RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_MCC_SYNC, 0, 0, + H2C_MCC_SYNC_LEN); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +#define H2C_MCC_SET_DURATION_LEN 20 +int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_duration *p) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for mcc set duration\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_MCC_SET_DURATION_LEN); + RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); + RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); + RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); + RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); + RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); + RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, + p->start_tsf_low); + RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, + p->start_tsf_high); + RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); + RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MCC, + H2C_FUNC_MCC_SET_DURATION, 0, 0, + H2C_MCC_SET_DURATION_LEN); + + cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +static +u32 rtw89_fw_h2c_mrc_add_slot(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_add_slot_arg *slot_arg, + struct rtw89_h2c_mrc_add_slot *slot_h2c) +{ + bool fill_h2c = !!slot_h2c; + unsigned int i; + + if (!fill_h2c) + goto calc_len; + + slot_h2c->w0 = le32_encode_bits(slot_arg->duration, + RTW89_H2C_MRC_ADD_SLOT_W0_DURATION) | + le32_encode_bits(slot_arg->courtesy_en, + RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN) | + le32_encode_bits(slot_arg->role_num, + RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM); + slot_h2c->w1 = le32_encode_bits(slot_arg->courtesy_period, + RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD) | + le32_encode_bits(slot_arg->courtesy_target, + RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET); + + for (i = 0; i < slot_arg->role_num; i++) { + slot_h2c->roles[i].w0 = + le32_encode_bits(slot_arg->roles[i].macid, + RTW89_H2C_MRC_ADD_ROLE_W0_MACID) | + le32_encode_bits(slot_arg->roles[i].role_type, + RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE) | + le32_encode_bits(slot_arg->roles[i].is_master, + RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER) | + le32_encode_bits(slot_arg->roles[i].en_tx_null, + RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN) | + le32_encode_bits(false, + RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE) | + le32_encode_bits(false, + RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN); + slot_h2c->roles[i].w1 = + le32_encode_bits(slot_arg->roles[i].central_ch, + RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG) | + le32_encode_bits(slot_arg->roles[i].primary_ch, + RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH) | + le32_encode_bits(slot_arg->roles[i].bw, + RTW89_H2C_MRC_ADD_ROLE_W1_BW) | + le32_encode_bits(slot_arg->roles[i].band, + RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE) | + le32_encode_bits(slot_arg->roles[i].null_early, + RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY) | + le32_encode_bits(false, + RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS) | + le32_encode_bits(true, + RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC); + slot_h2c->roles[i].macid_main_bitmap = + cpu_to_le32(slot_arg->roles[i].macid_main_bitmap); + slot_h2c->roles[i].macid_paired_bitmap = + cpu_to_le32(slot_arg->roles[i].macid_paired_bitmap); + } + +calc_len: + return struct_size(slot_h2c, roles, slot_arg->role_num); +} + +int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_add_arg *arg) +{ + struct rtw89_h2c_mrc_add *h2c_head; + struct sk_buff *skb; + unsigned int i; + void *tmp; + u32 len; + int ret; + + len = sizeof(*h2c_head); + for (i = 0; i < arg->slot_num; i++) + len += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], NULL); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc add\n"); + return -ENOMEM; + } + + skb_put(skb, len); + tmp = skb->data; + + h2c_head = tmp; + h2c_head->w0 = le32_encode_bits(arg->sch_idx, + RTW89_H2C_MRC_ADD_W0_SCH_IDX) | + le32_encode_bits(arg->sch_type, + RTW89_H2C_MRC_ADD_W0_SCH_TYPE) | + le32_encode_bits(arg->slot_num, + RTW89_H2C_MRC_ADD_W0_SLOT_NUM) | + le32_encode_bits(arg->btc_in_sch, + RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH); + + tmp += sizeof(*h2c_head); + for (i = 0; i < arg->slot_num; i++) + tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], tmp); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_ADD_MRC, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return -EBUSY; + } + + return 0; +} + +int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_start_arg *arg) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct rtw89_h2c_mrc_start *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc start\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_start *)skb->data; + + h2c->w0 = le32_encode_bits(arg->sch_idx, + RTW89_H2C_MRC_START_W0_SCH_IDX) | + le32_encode_bits(arg->old_sch_idx, + RTW89_H2C_MRC_START_W0_OLD_SCH_IDX) | + le32_encode_bits(arg->action, + RTW89_H2C_MRC_START_W0_ACTION); + + h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); + h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_START_MRC, 0, 0, + len); + + cond = RTW89_MRC_WAIT_COND(arg->sch_idx, H2C_FUNC_START_MRC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct rtw89_h2c_mrc_del *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + unsigned int cond; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc del\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_del *)skb->data; + + h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX) | + le32_encode_bits(slot_idx, RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_DEL_MRC, 0, 0, + len); + + cond = RTW89_MRC_WAIT_COND(sch_idx, H2C_FUNC_DEL_MRC); + return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); +} + +int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_req_tsf_arg *arg, + struct rtw89_mac_mrc_tsf_rpt *rpt) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + struct rtw89_h2c_mrc_req_tsf *h2c; + struct rtw89_mac_mrc_tsf_rpt *tmp; + struct sk_buff *skb; + unsigned int i; + u32 len; + int ret; + + len = struct_size(h2c, infos, arg->num); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc req tsf\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_req_tsf *)skb->data; + + h2c->req_tsf_num = arg->num; + for (i = 0; i < arg->num; i++) + h2c->infos[i] = + u8_encode_bits(arg->infos[i].band, + RTW89_H2C_MRC_REQ_TSF_INFO_BAND) | + u8_encode_bits(arg->infos[i].port, + RTW89_H2C_MRC_REQ_TSF_INFO_PORT); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_MRC_REQ_TSF, 0, 0, + len); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_MRC_WAIT_COND_REQ_TSF); + if (ret) + return ret; + + tmp = (struct rtw89_mac_mrc_tsf_rpt *)wait->data.buf; + *rpt = *tmp; + + return 0; +} + +int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_upd_bitmap_arg *arg) +{ + struct rtw89_h2c_mrc_upd_bitmap *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc upd bitmap\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_upd_bitmap *)skb->data; + + h2c->w0 = le32_encode_bits(arg->sch_idx, + RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX) | + le32_encode_bits(arg->action, + RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION) | + le32_encode_bits(arg->macid, + RTW89_H2C_MRC_UPD_BITMAP_W0_MACID); + h2c->w1 = le32_encode_bits(arg->client_macid, + RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_MRC_UPD_BITMAP, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return -EBUSY; + } + + return 0; +} + +int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_sync_arg *arg) +{ + struct rtw89_h2c_mrc_sync *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc sync\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_sync *)skb->data; + + h2c->w0 = le32_encode_bits(true, RTW89_H2C_MRC_SYNC_W0_SYNC_EN) | + le32_encode_bits(arg->src.port, + RTW89_H2C_MRC_SYNC_W0_SRC_PORT) | + le32_encode_bits(arg->src.band, + RTW89_H2C_MRC_SYNC_W0_SRC_BAND) | + le32_encode_bits(arg->dest.port, + RTW89_H2C_MRC_SYNC_W0_DEST_PORT) | + le32_encode_bits(arg->dest.band, + RTW89_H2C_MRC_SYNC_W0_DEST_BAND); + h2c->w1 = le32_encode_bits(arg->offset, RTW89_H2C_MRC_SYNC_W1_OFFSET); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_MRC_SYNC, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return -EBUSY; + } + + return 0; +} + +int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_upd_duration_arg *arg) +{ + struct rtw89_h2c_mrc_upd_duration *h2c; + struct sk_buff *skb; + unsigned int i; + u32 len; + int ret; + + len = struct_size(h2c, slots, arg->slot_num); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mrc upd duration\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mrc_upd_duration *)skb->data; + + h2c->w0 = le32_encode_bits(arg->sch_idx, + RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX) | + le32_encode_bits(arg->slot_num, + RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM) | + le32_encode_bits(false, + RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH); + + h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); + h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); + + for (i = 0; i < arg->slot_num; i++) { + h2c->slots[i] = + le32_encode_bits(arg->slots[i].slot_idx, + RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX) | + le32_encode_bits(arg->slots[i].duration, + RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MRC, + H2C_FUNC_MRC_UPD_DURATION, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return -EBUSY; + } + + return 0; +} + +static int rtw89_fw_h2c_ap_info(struct rtw89_dev *rtwdev, bool en) +{ + struct rtw89_h2c_ap_info *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for ap info\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_ap_info *)skb->data; + + h2c->w0 = le32_encode_bits(en, RTW89_H2C_AP_INFO_W0_PWR_INT_EN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_AP, + H2C_FUNC_AP_INFO, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + dev_kfree_skb_any(skb); + return -EBUSY; + } + + return 0; +} + +int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en) +{ + int ret; + + if (en) { + if (refcount_inc_not_zero(&rtwdev->refcount_ap_info)) + return 0; + } else { + if (!refcount_dec_and_test(&rtwdev->refcount_ap_info)) + return 0; + } + + ret = rtw89_fw_h2c_ap_info(rtwdev, en); + if (ret) { + if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + return ret; + + /* During recovery, neither driver nor stack has full error + * handling, so show a warning, but return 0 with refcount + * increased normally. It can avoid underflow when calling + * with @en == false later. + */ + rtw89_warn(rtwdev, "h2c ap_info failed during SER\n"); + } + + if (en) + refcount_set(&rtwdev->refcount_ap_info, 1); + + return 0; +} + +int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable) +{ + struct rtw89_wait_info *wait = &rtwdev->mlo.wait; + struct rtw89_h2c_mlo_link_cfg *h2c; + u8 mac_id = rtwvif_link->mac_id; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + unsigned int cond; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data; + + h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) | + le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MLO, + H2C_FUNC_MLO_LINK_CFG, 0, 0, + len); + + cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); + if (ret) { + rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n", + str_enable_disable(enable), rtwvif_link->link_id, ret); + return ret; + } + + return 0; +} + +static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len) +{ + static const u8 zeros[U8_MAX] = {}; + + return memcmp(ext_ptr, zeros, ext_len) == 0; +} + +#define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \ +({ \ + u8 __var_sz = sizeof(*(e)); \ + bool __accept; \ + if (__var_sz >= (ent_sz)) \ + __accept = true; \ + else \ + __accept = __fw_txpwr_entry_zero_ext((cursor) + __var_sz,\ + (ent_sz) - __var_sz);\ + __accept; \ +}) + +static bool +fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->band >= RTW89_BAND_NUM || e->bw >= RTW89_BYR_BW_NUM) + return false; + + switch (e->rs) { + case RTW89_RS_CCK: + if (e->shf + e->len > RTW89_RATE_CCK_NUM) + return false; + break; + case RTW89_RS_OFDM: + if (e->shf + e->len > RTW89_RATE_OFDM_NUM) + return false; + break; + case RTW89_RS_MCS: + if (e->shf + e->len > __RTW89_RATE_MCS_NUM || + e->nss >= RTW89_NSS_NUM || + e->ofdma >= RTW89_OFDMA_NUM) + return false; + break; + case RTW89_RS_HEDCM: + if (e->shf + e->len > RTW89_RATE_HEDCM_NUM || + e->nss >= RTW89_NSS_HEDCM_NUM || + e->ofdma >= RTW89_OFDMA_NUM) + return false; + break; + case RTW89_RS_OFFSET: + if (e->shf + e->len > __RTW89_RATE_OFFSET_NUM) + return false; + break; + default: + return false; + } + + return true; +} + +static +void rtw89_fw_load_txpwr_byrate(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl) +{ + const struct rtw89_txpwr_conf *conf = tbl->data; + struct rtw89_fw_txpwr_byrate_entry entry = {}; + struct rtw89_txpwr_byrate *byr_head; + struct rtw89_rate_desc desc = {}; + const void *cursor; + u32 data; + s8 *byr; + int i; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_byrate_entry_valid(&entry, cursor, conf)) + continue; + + byr_head = &rtwdev->byr[entry.band][entry.bw]; + data = le32_to_cpu(entry.data); + desc.ofdma = entry.ofdma; + desc.nss = entry.nss; + desc.rs = entry.rs; + + for (i = 0; i < entry.len; i++, data >>= 8) { + desc.idx = entry.shf + i; + byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc); + *byr = data & 0xff; + } + } +} + +static bool +fw_txpwr_lmt_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_2ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->bw >= RTW89_2G_BW_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->rs >= RTW89_RS_LMT_NUM) + return false; + if (e->bf >= RTW89_BF_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->ch_idx >= RTW89_2G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_2ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_2ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] + [entry.ch_idx] = entry.v; + } +} + +static bool +fw_txpwr_lmt_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_5ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->bw >= RTW89_5G_BW_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->rs >= RTW89_RS_LMT_NUM) + return false; + if (e->bf >= RTW89_BF_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->ch_idx >= RTW89_5G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_5ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_5ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] + [entry.ch_idx] = entry.v; + } +} + +static bool +fw_txpwr_lmt_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_6ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->bw >= RTW89_6G_BW_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->rs >= RTW89_RS_LMT_NUM) + return false; + if (e->bf >= RTW89_BF_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) + return false; + if (e->ch_idx >= RTW89_6G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_6ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_6ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] + [entry.reg_6ghz_power][entry.ch_idx] = entry.v; + } +} + +static bool +fw_txpwr_lmt_ru_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_2ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->ru >= RTW89_RU_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->ch_idx >= RTW89_2G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_ru_2ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_ru_2ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; + } +} + +static bool +fw_txpwr_lmt_ru_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_5ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->ru >= RTW89_RU_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->ch_idx >= RTW89_5G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_ru_5ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_ru_5ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; + } +} + +static bool +fw_txpwr_lmt_ru_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_6ghz_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->ru >= RTW89_RU_NUM) + return false; + if (e->nt >= RTW89_NTX_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) + return false; + if (e->ch_idx >= RTW89_6G_CH_NUM) + return false; + + return true; +} + +static +void rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_txpwr_lmt_ru_6ghz_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_txpwr_lmt_ru_6ghz_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.ru][entry.nt][entry.regd][entry.reg_6ghz_power] + [entry.ch_idx] = entry.v; + } +} + +static bool +fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->band >= RTW89_BAND_NUM) + return false; + if (e->tx_shape_rs >= RTW89_RS_TX_SHAPE_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + + /* ensure compatibility work with 2/5 GHz */ + static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0); + + if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER) + return false; + + return true; +} + +static +void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_tx_shape_lmt_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.band][entry.tx_shape_rs][entry.regd][entry.reg6_pwr] = entry.v; + } +} + +static bool +fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e, + const void *cursor, + const struct rtw89_txpwr_conf *conf) +{ + if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) + return false; + + if (e->band >= RTW89_BAND_NUM) + return false; + if (e->regd >= RTW89_REGD_NUM) + return false; + + /* ensure compatibility work with 2/5 GHz */ + static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0); + + if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER) + return false; + + return true; +} + +static +void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data) +{ + const struct rtw89_txpwr_conf *conf = &data->conf; + struct rtw89_fw_tx_shape_lmt_ru_entry entry = {}; + const void *cursor; + + rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { + if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf)) + continue; + + data->v[entry.band][entry.regd][entry.reg6_pwr] = entry.v; + } +} + +static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev, + const struct rtw89_rfe_parms *parms) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->support_bands & BIT(NL80211_BAND_2GHZ) && + !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru)) + return false; + + if (chip->support_bands & BIT(NL80211_BAND_5GHZ) && + !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru)) + return false; + + if (chip->support_bands & BIT(NL80211_BAND_6GHZ) && + !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru)) + return false; + + return true; +} + +const struct rtw89_rfe_parms * +rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev, + const struct rtw89_rfe_parms *init) +{ + struct rtw89_rfe_data *rfe_data = rtwdev->rfe_data; + struct rtw89_rfe_parms *parms; + + if (!rfe_data) + return init; + + parms = &rfe_data->rfe_parms; + if (init) + *parms = *init; + + if (rtw89_txpwr_conf_valid(&rfe_data->byrate.conf)) { + rfe_data->byrate.tbl.data = &rfe_data->byrate.conf; + rfe_data->byrate.tbl.size = 0; /* don't care here */ + rfe_data->byrate.tbl.load = rtw89_fw_load_txpwr_byrate; + parms->byr_tbl = &rfe_data->byrate.tbl; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_2ghz.conf)) { + rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->lmt_2ghz); + parms->rule_2ghz.lmt = &rfe_data->lmt_2ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_5ghz.conf)) { + rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->lmt_5ghz); + parms->rule_5ghz.lmt = &rfe_data->lmt_5ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_6ghz.conf)) { + rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->lmt_6ghz); + parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_2ghz.conf)) { + rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->da_lmt_2ghz); + parms->rule_da_2ghz.lmt = &rfe_data->da_lmt_2ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_5ghz.conf)) { + rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->da_lmt_5ghz); + parms->rule_da_5ghz.lmt = &rfe_data->da_lmt_5ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_6ghz.conf)) { + rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->da_lmt_6ghz); + parms->rule_da_6ghz.lmt = &rfe_data->da_lmt_6ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz); + parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_5ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->lmt_ru_5ghz); + parms->rule_5ghz.lmt_ru = &rfe_data->lmt_ru_5ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_6ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->lmt_ru_6ghz); + parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_2ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->da_lmt_ru_2ghz); + parms->rule_da_2ghz.lmt_ru = &rfe_data->da_lmt_ru_2ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_5ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->da_lmt_ru_5ghz); + parms->rule_da_5ghz.lmt_ru = &rfe_data->da_lmt_ru_5ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_6ghz.conf)) { + rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->da_lmt_ru_6ghz); + parms->rule_da_6ghz.lmt_ru = &rfe_data->da_lmt_ru_6ghz.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) { + rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt); + parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v; + } + + if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt_ru.conf)) { + rtw89_fw_load_tx_shape_lmt_ru(&rfe_data->tx_shape_lmt_ru); + parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v; + } + + parms->has_da = rtw89_fw_has_da_txpwr_table(rtwdev, parms); + + return parms; +} + +static int rtw89_fw_cmd_ofld_pack(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + info->pack_level++; + + return 0; +} + +static void rtw89_fw_cmd_ofld_flush(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + struct sk_buff *skb; + int ret; + u32 len; + + len = info->cnt * sizeof(info->cmds[0]); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "alloc skb fail\n"); + return; + } + + skb_put_data(skb, info->cmds, len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FW_OFLD, + H2C_FUNC_CMD_OFLD_PKT, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send cmd ofld\n"); + dev_kfree_skb_any(skb); + return; + } + + if (info->accu_delay) + fsleep(info->accu_delay); + + info->cnt = 0; + info->accu_delay = 0; +} + +static int rtw89_fw_cmd_ofld_unpack(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (info->pack_level == 0) + return -EFAULT; + + if (--info->pack_level != 0) + return 0; + + if (info->cnt == 0) + return 0; + + rtw89_fw_cmd_ofld_flush(rtwdev); + + return 0; +} + +static int rtw89_fw_cmd_ofld_enqueue(struct rtw89_dev *rtwdev, + const struct rtw89_fw_cmd_ofld_arg *cmd) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + struct rtw89_h2c_cmd_ofld *h2c; + u32 base_off; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (info->pack_level == 0) + return 1; + + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + if (cmd->type != RTW89_FW_CMD_OFLD_DELAY && + cmd->src != RTW89_FW_CMD_OFLD_SRC_RF && + cmd->src != RTW89_FW_CMD_OFLD_SRC_RF_DDIE && + !IS_ALIGNED(cmd->offset, 4)) + return -EFAULT; + + if (info->cnt >= ARRAY_SIZE(info->cmds)) + rtw89_fw_cmd_ofld_flush(rtwdev); + + h2c = &info->cmds[info->cnt++]; + + h2c->w0 = le32_encode_bits(cmd->src, RTW89_H2C_CMD_OFLD_W0_SRC) | + le32_encode_bits(cmd->type, RTW89_H2C_CMD_OFLD_W0_TYPE) | + le32_encode_bits(cmd->rf_path, RTW89_H2C_CMD_OFLD_W0_PATH) | + le32_encode_bits(info->cnt, RTW89_H2C_CMD_OFLD_W0_CMD_NUM) | + le32_encode_bits(cmd->offset, RTW89_H2C_CMD_OFLD_W0_OFFSET); + + if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF_DDIE) + base_off = 1; + else if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF) + base_off = 0; + else + base_off = cmd->offset >> 16; + + h2c->w1 = le32_encode_bits(cmd->id, RTW89_H2C_CMD_OFLD_W1_ID) | + le32_encode_bits(base_off, RTW89_H2C_CMD_OFLD_W1_BASE_OFFSET); + h2c->w2 = le32_encode_bits(cmd->value, RTW89_H2C_CMD_OFLD_W2_VALUE); + h2c->w3 = le32_encode_bits(cmd->mask, RTW89_H2C_CMD_OFLD_W3_MASK); + + if (cmd->type == RTW89_FW_CMD_OFLD_DELAY) + info->accu_delay += cmd->value; + + return 0; +} + +static const struct rtw89_io_ops rtw89_raw_io = { + .pack = NULL, + .unpack = NULL, + .write8 = rtw89_raw_write8, + .write16 = rtw89_raw_write16, + .write32 = rtw89_raw_write32, + .phy_write8 = rtw89_raw_phy_write8, + .phy_write16 = rtw89_raw_phy_write16, + .phy_write32 = rtw89_raw_phy_write32, + .write_rf = rtw89_raw_write_rf, +}; + +static +void rtw89_fw_cmd_ofld_phy_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 4), + .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write8(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_phy_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 2), + .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write16(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_phy_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = addr, + .mask = MASKDWORD, + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write32(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 4), + .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write8(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 2), + .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write16(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = addr, + .mask = MASKDWORD, + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write32(rtwdev, addr, data); +} + +static void rtw89_fw_cmd_ofld_write_rf_ddv(struct rtw89_dev *rtwdev, + struct rtw89_fw_cmd_ofld_arg *cmd, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + *cmd = (typeof(*cmd)){ + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .rf_path = 0, /* Set rf_path to zero in rf_ddv */ + .offset = chip->rf_base_addr[rf_path] + ((addr & 0xff) << 2), + .mask = mask, + .value = data, + }; +} + +static void rtw89_fw_cmd_ofld_write_rf_dav(struct rtw89_dev *rtwdev, + struct rtw89_fw_cmd_ofld_arg *cmd, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + *cmd = (typeof(*cmd)){ + .src = RTW89_FW_CMD_OFLD_SRC_RF, + .type = RTW89_FW_CMD_OFLD_WRITE, + .rf_path = rf_path, + .offset = addr, + .mask = mask, + .value = data, + }; +} + +static void rtw89_fw_cmd_ofld_write_rf(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + struct rtw89_fw_cmd_ofld_arg cmd; + int ret; + + if (unlikely(rf_path >= chip->rf_path_num)) { + rtw89_warn(rtwdev, "unsupported rf path (%d) in fw offload\n", rf_path); + return; + } + + if (ad_sel) + rtw89_fw_cmd_ofld_write_rf_ddv(rtwdev, &cmd, rf_path, addr, mask, data); + else + rtw89_fw_cmd_ofld_write_rf_dav(rtwdev, &cmd, rf_path, addr, mask, data); + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write_rf(rtwdev, rf_path, addr, mask, data); +} + +static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_DELAY, + .value = us, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + udelay(us); +} + +static void rtw89_fw_cmd_ofld_mdelay(struct rtw89_dev *rtwdev, u32 ms) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_DELAY, + .value = ms * 1000, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + mdelay(ms); +} + +static const struct rtw89_io_ops rtw89_fw_cmd_ofld_io = { + .pack = rtw89_fw_cmd_ofld_pack, + .unpack = rtw89_fw_cmd_ofld_unpack, + .do_udelay = rtw89_fw_cmd_ofld_udelay, + .do_mdelay = rtw89_fw_cmd_ofld_mdelay, + .write8 = rtw89_fw_cmd_ofld_write8, + .write16 = rtw89_fw_cmd_ofld_write16, + .write32 = rtw89_fw_cmd_ofld_write32, + .phy_write8 = rtw89_fw_cmd_ofld_phy_write8, + .phy_write16 = rtw89_fw_cmd_ofld_phy_write16, + .phy_write32 = rtw89_fw_cmd_ofld_phy_write32, + .write_rf = rtw89_fw_cmd_ofld_write_rf, +}; + +const struct rtw89_io_ops * +rtw89_fw_cmd_ofld_alloc_and_get_io_ops(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_cmd_ofld_info *info; + + if (!(rtwdev->hci.type == RTW89_HCI_TYPE_USB && chip->support_fw_cmd_ofld)) + return &rtw89_raw_io; + + info = devm_kzalloc(rtwdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return &rtw89_raw_io; + + rtwdev->fw_cmd_ofld_info = info; + + return &rtw89_fw_cmd_ofld_io; +} diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h new file mode 100644 index 000000000..375ca0a24 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -0,0 +1,5935 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_FW_H__ +#define __RTW89_FW_H__ + +#include "core.h" + +enum rtw89_fw_dl_status { + RTW89_FWDL_INITIAL_STATE = 0, + RTW89_FWDL_FWDL_ONGOING = 1, + RTW89_FWDL_CHECKSUM_FAIL = 2, + RTW89_FWDL_SECURITY_FAIL = 3, + RTW89_FWDL_CV_NOT_MATCH = 4, + RTW89_FWDL_RSVD0 = 5, + RTW89_FWDL_WCPU_FWDL_RDY = 6, + RTW89_FWDL_WCPU_FW_INIT_RDY = 7 +}; + +struct rtw89_c2hreg_hdr { + u32 w0; +}; + +#define RTW89_C2HREG_HDR_FUNC_MASK GENMASK(6, 0) +#define RTW89_C2HREG_HDR_ACK BIT(7) +#define RTW89_C2HREG_HDR_LEN_MASK GENMASK(11, 8) +#define RTW89_C2HREG_HDR_SEQ_MASK GENMASK(15, 12) + +struct rtw89_c2hreg_phycap { + u32 w0; + u32 w1; + u32 w2; + u32 w3; +} __packed; + +#define RTW89_C2HREG_PHYCAP_W0_FUNC GENMASK(6, 0) +#define RTW89_C2HREG_PHYCAP_W0_ACK BIT(7) +#define RTW89_C2HREG_PHYCAP_W0_LEN GENMASK(11, 8) +#define RTW89_C2HREG_PHYCAP_W0_SEQ GENMASK(15, 12) +#define RTW89_C2HREG_PHYCAP_W0_RX_NSS GENMASK(23, 16) +#define RTW89_C2HREG_PHYCAP_W0_BW GENMASK(31, 24) +#define RTW89_C2HREG_PHYCAP_W1_TX_NSS GENMASK(7, 0) +#define RTW89_C2HREG_PHYCAP_W1_PROT GENMASK(15, 8) +#define RTW89_C2HREG_PHYCAP_W1_PROT_11N 1 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11AC 2 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11AX 3 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11BE 4 +#define RTW89_C2HREG_PHYCAP_W1_NIC GENMASK(23, 16) +#define RTW89_C2HREG_PHYCAP_W1_WL_FUNC GENMASK(31, 24) +#define RTW89_C2HREG_PHYCAP_W2_HW_TYPE GENMASK(7, 0) +#define RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM GENMASK(15, 8) +#define RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM GENMASK(23, 16) +#define RTW89_C2HREG_PHYCAP_W3_BAND_SEL GENMASK(31, 24) + +#define RTW89_C2HREG_PHYCAP_P1_W0_B1_RX_NSS GENMASK(23, 16) +#define RTW89_C2HREG_PHYCAP_P1_W0_B1_BW GENMASK(31, 24) +#define RTW89_C2HREG_PHYCAP_P1_W1_B1_TX_NSS GENMASK(7, 0) +#define RTW89_C2HREG_PHYCAP_P1_W1_B1_ANT_TX_NUM GENMASK(15, 8) +#define RTW89_C2HREG_PHYCAP_P1_W1_B1_ANT_RX_NUM GENMASK(23, 16) +#define RTW89_C2HREG_PHYCAP_P1_W1_B1_BAND_SEL GENMASK(31, 24) +#define RTW89_C2HREG_PHYCAP_P1_W2_QAM GENMASK(7, 0) +#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_256 0x1 +#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024 0x2 +#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096 0x3 +#define RTW89_C2HREG_PHYCAP_P1_W2_B1_QAM GENMASK(15, 8) + +#define RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_0 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_1 GENMASK(15, 8) +#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_2 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_3 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_4 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_5 GENMASK(15, 8) +#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_6 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_7 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1 GENMASK(15, 8) +#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7 GENMASK(15, 8) +#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3 GENMASK(15, 8) +#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4 GENMASK(23, 16) +#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5 GENMASK(31, 24) +#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6 GENMASK(7, 0) +#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7 GENMASK(15, 8) + +#define RTW89_C2HREG_PS_LEAVE_ACK_RET GENMASK(7, 0) +#define RTW89_C2HREG_PS_LEAVE_ACK_MACID GENMASK(31, 16) + +struct rtw89_h2creg_hdr { + u32 w0; +}; + +#define RTW89_H2CREG_HDR_FUNC_MASK GENMASK(6, 0) +#define RTW89_H2CREG_HDR_LEN_MASK GENMASK(11, 8) + +struct rtw89_h2creg_sch_tx_en { + u32 w0; + u32 w1; +} __packed; + +#define RTW89_H2CREG_SCH_TX_EN_W0_EN GENMASK(31, 16) +#define RTW89_H2CREG_SCH_TX_EN_W1_MASK GENMASK(15, 0) +#define RTW89_H2CREG_SCH_TX_EN_W1_BAND BIT(16) + +#define RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN GENMASK(23, 16) + +#define RTW89_H2CREG_GET_FEATURE_PART_NUM GENMASK(23, 16) + +#define RTW89_H2CREG_MAX 4 +#define RTW89_C2HREG_MAX 4 +#define RTW89_C2HREG_HDR_LEN 2 +#define RTW89_H2CREG_HDR_LEN 2 +#define RTW89_C2H_TIMEOUT 1000000 +#define RTW89_C2H_TIMEOUT_USB 4000 + +struct rtw89_mac_c2h_info { + u8 id; + u8 content_len; + u32 timeout; + union { + u32 c2hreg[RTW89_C2HREG_MAX]; + struct rtw89_c2hreg_hdr hdr; + struct rtw89_c2hreg_phycap phycap; + } u; +}; + +struct rtw89_mac_h2c_info { + u8 id; + u8 content_len; + union { + u32 h2creg[RTW89_H2CREG_MAX]; + struct rtw89_h2creg_hdr hdr; + struct rtw89_h2creg_sch_tx_en sch_tx_en; + } u; +}; + +enum rtw89_mac_h2c_type { + RTW89_FWCMD_H2CREG_FUNC_H2CREG_LB = 0, + RTW89_FWCMD_H2CREG_FUNC_CNSL_CMD, + RTW89_FWCMD_H2CREG_FUNC_FWERR, + RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE, + RTW89_FWCMD_H2CREG_FUNC_GETPKT_INFORM, + RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN, + RTW89_FWCMD_H2CREG_FUNC_WOW_TRX_STOP, + RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1, + RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2, + RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_3_REQ, + RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL, +}; + +enum rtw89_mac_c2h_type { + RTW89_FWCMD_C2HREG_FUNC_C2HREG_LB = 0, + RTW89_FWCMD_C2HREG_FUNC_ERR_RPT, + RTW89_FWCMD_C2HREG_FUNC_ERR_MSG, + RTW89_FWCMD_C2HREG_FUNC_PHY_CAP, + RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT, + RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK = 0xA, + RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1 = 0xC, + RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK = 0xD, + RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF, +}; + +enum rtw89_fw_c2h_category { + RTW89_C2H_CAT_TEST, + RTW89_C2H_CAT_MAC, + RTW89_C2H_CAT_OUTSRC, +}; + +enum rtw89_fw_log_level { + RTW89_FW_LOG_LEVEL_OFF, + RTW89_FW_LOG_LEVEL_CRT, + RTW89_FW_LOG_LEVEL_SER, + RTW89_FW_LOG_LEVEL_WARN, + RTW89_FW_LOG_LEVEL_LOUD, + RTW89_FW_LOG_LEVEL_TR, +}; + +enum rtw89_fw_log_path { + RTW89_FW_LOG_LEVEL_UART, + RTW89_FW_LOG_LEVEL_C2H, + RTW89_FW_LOG_LEVEL_SNI, +}; + +enum rtw89_fw_log_comp { + RTW89_FW_LOG_COMP_VER, + RTW89_FW_LOG_COMP_INIT, + RTW89_FW_LOG_COMP_TASK, + RTW89_FW_LOG_COMP_CNS, + RTW89_FW_LOG_COMP_H2C, + RTW89_FW_LOG_COMP_C2H, + RTW89_FW_LOG_COMP_TX, + RTW89_FW_LOG_COMP_RX, + RTW89_FW_LOG_COMP_IPSEC, + RTW89_FW_LOG_COMP_TIMER, + RTW89_FW_LOG_COMP_DBGPKT, + RTW89_FW_LOG_COMP_PS, + RTW89_FW_LOG_COMP_ERROR, + RTW89_FW_LOG_COMP_WOWLAN, + RTW89_FW_LOG_COMP_SECURE_BOOT, + RTW89_FW_LOG_COMP_BTC, + RTW89_FW_LOG_COMP_BB, + RTW89_FW_LOG_COMP_TWT, + RTW89_FW_LOG_COMP_RF, + RTW89_FW_LOG_COMP_MCC = 20, + RTW89_FW_LOG_COMP_MLO = 26, + RTW89_FW_LOG_COMP_SCAN = 28, +}; + +enum rtw89_pkt_offload_op { + RTW89_PKT_OFLD_OP_ADD, + RTW89_PKT_OFLD_OP_DEL, + RTW89_PKT_OFLD_OP_READ, + + NUM_OF_RTW89_PKT_OFFLOAD_OP, +}; + +#define RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op) \ + ((pkt_id) * NUM_OF_RTW89_PKT_OFFLOAD_OP + (pkt_op)) + +enum rtw89_scanofld_notify_reason { + RTW89_SCAN_DWELL_NOTIFY, + RTW89_SCAN_PRE_TX_NOTIFY, + RTW89_SCAN_POST_TX_NOTIFY, + RTW89_SCAN_ENTER_CH_NOTIFY, + RTW89_SCAN_LEAVE_CH_NOTIFY, + RTW89_SCAN_END_SCAN_NOTIFY, + RTW89_SCAN_REPORT_NOTIFY, + RTW89_SCAN_CHKPT_NOTIFY, + RTW89_SCAN_ENTER_OP_NOTIFY, + RTW89_SCAN_LEAVE_OP_NOTIFY, +}; + +enum rtw89_scanofld_status { + RTW89_SCAN_STATUS_NOTIFY, + RTW89_SCAN_STATUS_SUCCESS, + RTW89_SCAN_STATUS_FAIL, +}; + +enum rtw89_chan_type { + RTW89_CHAN_OPERATE = 0, + RTW89_CHAN_ACTIVE, + RTW89_CHAN_DFS, + RTW89_CHAN_EXTRA_OP, +}; + +enum rtw89_p2pps_action { + RTW89_P2P_ACT_INIT = 0, + RTW89_P2P_ACT_UPDATE = 1, + RTW89_P2P_ACT_REMOVE = 2, + RTW89_P2P_ACT_TERMINATE = 3, +}; + +#define RTW89_DEFAULT_CQM_HYST 4 +#define RTW89_DEFAULT_CQM_THOLD -70 + +enum rtw89_bcn_fltr_offload_mode { + RTW89_BCN_FLTR_OFFLOAD_MODE_0 = 0, + RTW89_BCN_FLTR_OFFLOAD_MODE_1, + RTW89_BCN_FLTR_OFFLOAD_MODE_2, + RTW89_BCN_FLTR_OFFLOAD_MODE_3, + + RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT = RTW89_BCN_FLTR_OFFLOAD_MODE_0, +}; + +enum rtw89_bcn_fltr_type { + RTW89_BCN_FLTR_BEACON_LOSS, + RTW89_BCN_FLTR_RSSI, + RTW89_BCN_FLTR_NOTIFY, +}; + +enum rtw89_bcn_fltr_rssi_event { + RTW89_BCN_FLTR_RSSI_NOT_CHANGED, + RTW89_BCN_FLTR_RSSI_HIGH, + RTW89_BCN_FLTR_RSSI_LOW, +}; + +#define FWDL_SECTION_MAX_NUM 10 +#define FWDL_SECTION_CHKSUM_LEN 8 +#define FWDL_SECTION_PER_PKT_LEN 2020 + +struct rtw89_fw_hdr_section_info { + u8 redl; + const u8 *addr; + u32 len; + u32 len_override; + u32 dladdr; + u32 mssc; + u8 type; + bool ignore; + const u8 *key_addr; + u32 key_len; + u32 key_idx; +}; + +struct rtw89_fw_bin_info { + u8 section_num; + u32 part_size; + u32 hdr_len; + bool dynamic_hdr_en; + u32 dynamic_hdr_len; + u8 idmem_share_mode; + bool dsp_checksum; + bool secure_section_exist; + struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM]; +}; + +struct rtw89_fw_macid_pause_grp { + __le32 pause_grp[4]; + __le32 mask_grp[4]; +} __packed; + +struct rtw89_fw_macid_pause_sleep_grp { + struct { + __le32 pause_grp[4]; + __le32 pause_mask_grp[4]; + __le32 sleep_grp[4]; + __le32 sleep_mask_grp[4]; + } __packed n[4]; +} __packed; + +#define RTW89_H2C_MAX_SIZE 2048 +#define RTW89_CHANNEL_TIME 45 +#define RTW89_CHANNEL_TIME_6G 20 +#define RTW89_CHANNEL_TIME_EXTRA_OP 30 +#define RTW89_DFS_CHAN_TIME 105 +#define RTW89_OFF_CHAN_TIME 100 +#define RTW89_P2P_CHAN_TIME 105 +#define RTW89_DWELL_TIME 20 +#define RTW89_DWELL_TIME_6G 10 +#define RTW89_SCAN_WIDTH 0 +#define RTW89_SCANOFLD_MAX_SSID 8 +#define RTW89_SCANOFLD_MAX_IE_LEN 512 +#define RTW89_SCANOFLD_PKT_NONE 0xFF +#define RTW89_SCANOFLD_DEBUG_MASK 0x1F +#define RTW89_CHAN_INVALID 0xFF +#define RTW89_MAC_CHINFO_SIZE 28 +#define RTW89_MAC_CHINFO_SIZE_BE 32 +#define RTW89_SCAN_LIST_GUARD 4 +#define RTW89_SCAN_LIST_LIMIT(size) \ + ((RTW89_H2C_MAX_SIZE / (size)) - RTW89_SCAN_LIST_GUARD) +#define RTW89_SCAN_LIST_LIMIT_AX RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE) +#define RTW89_SCAN_LIST_LIMIT_BE RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE_BE) + +#define RTW89_BCN_LOSS_CNT 60 + +struct rtw89_mac_chinfo_ax { + u8 period; + u8 dwell_time; + u8 central_ch; + u8 pri_ch; + u8 bw:3; + u8 notify_action:5; + u8 num_pkt:4; + u8 tx_pkt:1; + u8 pause_data:1; + u8 ch_band:2; + u8 probe_id; + u8 dfs_ch:1; + u8 tx_null:1; + u8 rand_seq_num:1; + u8 cfg_tx_pwr:1; + u8 macid_tx: 1; + u8 rsvd0: 3; + u8 pkt_id[RTW89_SCANOFLD_MAX_SSID]; + u16 tx_pwr_idx; + u8 rsvd1; + struct list_head list; + bool is_psc; +}; + +struct rtw89_mac_chinfo_be { + u8 period; + u8 dwell_time; + u8 central_ch; + u8 pri_ch; + u8 bw:3; + u8 ch_band:2; + u8 dfs_ch:1; + u8 pause_data:1; + u8 tx_null:1; + u8 rand_seq_num:1; + u8 notify_action:5; + u8 probe_id; + u8 leave_crit; + u8 chkpt_timer; + u8 leave_time; + u8 leave_th; + u16 tx_pkt_ctrl; + u8 pkt_id[RTW89_SCANOFLD_MAX_SSID]; + u8 sw_def; + u16 fw_probe0_ssids; + u16 fw_probe0_shortssids; + u16 fw_probe0_bssids; + + struct list_head list; + bool is_psc; +}; + +struct rtw89_pktofld_info { + struct list_head list; + u8 id; + bool wildcard_6ghz; + + /* Below fields are for WiFi 6 chips 6 GHz RNR use only */ + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + u8 bssid[ETH_ALEN]; + u16 channel_6ghz; + bool cancel; +}; + +struct rtw89_h2c_ra { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_H2C_RA_W0_IS_DIS BIT(0) +#define RTW89_H2C_RA_W0_MODE GENMASK(5, 1) +#define RTW89_H2C_RA_W0_BW_CAP GENMASK(7, 6) +#define RTW89_H2C_RA_W0_MACID GENMASK(15, 8) +#define RTW89_H2C_RA_W0_DCM BIT(16) +#define RTW89_H2C_RA_W0_ER BIT(17) +#define RTW89_H2C_RA_W0_INIT_RATE_LV GENMASK(19, 18) +#define RTW89_H2C_RA_W0_UPD_ALL BIT(20) +#define RTW89_H2C_RA_W0_SGI BIT(21) +#define RTW89_H2C_RA_W0_LDPC BIT(22) +#define RTW89_H2C_RA_W0_STBC BIT(23) +#define RTW89_H2C_RA_W0_SS_NUM GENMASK(26, 24) +#define RTW89_H2C_RA_W0_GILTF GENMASK(29, 27) +#define RTW89_H2C_RA_W0_UPD_BW_NSS_MASK BIT(30) +#define RTW89_H2C_RA_W0_UPD_MASK BIT(31) +#define RTW89_H2C_RA_W1_RAMASK_LO32 GENMASK(31, 0) +#define RTW89_H2C_RA_W2_RAMASK_HI32 GENMASK(30, 0) +#define RTW89_H2C_RA_W2_BFEE_CSI_CTL BIT(31) +#define RTW89_H2C_RA_W3_BAND_NUM GENMASK(7, 0) +#define RTW89_H2C_RA_W3_RA_CSI_RATE_EN BIT(8) +#define RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN BIT(9) +#define RTW89_H2C_RA_W3_CR_TBL_SEL BIT(10) +#define RTW89_H2C_RA_W3_FIX_GILTF_EN BIT(11) +#define RTW89_H2C_RA_W3_FIX_GILTF GENMASK(14, 12) +#define RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX GENMASK(23, 16) +#define RTW89_H2C_RA_W3_FIXED_CSI_MODE GENMASK(25, 24) +#define RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF GENMASK(28, 26) +#define RTW89_H2C_RA_W3_FIXED_CSI_BW GENMASK(31, 29) +#define RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER BIT(15) +#define RTW89_H2C_RA_V1_W3_FIXED_CSI_RATE_L GENMASK(23, 16) +#define RTW89_H2C_RA_V1_W3_IS_NOISY BIT(24) +#define RTW89_H2C_RA_V1_W3_PSRA_EN BIT(25) +#define RTW89_H2C_RA_V1_W3_MACID_MSB GENMASK(28, 27) +#define RTW89_H2C_RA_V1_W3_BAND GENMASK(30, 29) +#define RTW89_H2C_RA_V1_W3_NEW_DBGREG BIT(31) + +struct rtw89_h2c_ra_v1 { + struct rtw89_h2c_ra v0; + __le32 w4; + __le32 w5; +} __packed; + +#define RTW89_H2C_RA_V1_W4_MODE_EHT GENMASK(6, 0) +#define RTW89_H2C_RA_V1_W4_BW_EHT GENMASK(10, 8) +#define RTW89_H2C_RA_V1_W4_RAMASK_UHL16 GENMASK(31, 16) +#define RTW89_H2C_RA_V1_W5_RAMASK_UHH16 GENMASK(15, 0) + +struct rtw89_h2c_ra_tx_history { + __le32 w0; +} __packed; + +#define RTW89_H2C_RA_TX_HISTORY_W0_MACID GENMASK(15, 0) +#define RTW89_H2C_RA_TX_HISTORY_W0_PER_PPDU GENMASK(23, 16) + +struct rtw89_h2c_ra_phy_ch_rpt { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_H2C_RA_PHY_CH_RPT_W1_RPT_TX_COUNT BIT(10) + +struct rtw89_h2c_ra_drv_ctrl_fw { + __le32 w0; +} __packed; + +#define RTW89_H2C_RA_DRV_CTRL_FW_W0_RPT_TX_COUNT BIT(13) + +static inline void RTW89_SET_FWCMD_SEC_IDX(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_SEC_OFFSET(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_SEC_LEN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_SEC_TYPE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(3, 0)); +} + +static inline void RTW89_SET_FWCMD_SEC_EXT_KEY(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(4)); +} + +static inline void RTW89_SET_FWCMD_SEC_SPP_MODE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(5)); +} + +static inline void RTW89_SET_FWCMD_SEC_KEY0(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_SEC_KEY1(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_SEC_KEY2(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x04, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_SEC_KEY3(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x05, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_EDCA_SEL(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_EDCA_BAND(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(3)); +} + +static inline void RTW89_SET_EDCA_WMM(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(4)); +} + +static inline void RTW89_SET_EDCA_AC(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(6, 5)); +} + +static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 0)); +} +#define FW_EDCA_PARAM_TXOPLMT_MSK GENMASK(26, 16) +#define FW_EDCA_PARAM_CWMAX_MSK GENMASK(15, 12) +#define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8) +#define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0) + +#define FWDL_SECURITY_SECTION_TYPE 9 +#define FWDL_SECURITY_SIGLEN 512 +#define FWDL_SECURITY_CHKSUM_LEN 8 + +struct rtw89_fw_dynhdr_sec { + __le32 w0; + u8 content[]; +} __packed; + +struct rtw89_fw_dynhdr_hdr { + __le32 hdr_len; + __le32 setcion_count; + /* struct rtw89_fw_dynhdr_sec (nested flexible structures) */ +} __packed; + +struct rtw89_fw_hdr_section { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define FWSECTION_HDR_W0_DL_ADDR GENMASK(31, 0) +#define FWSECTION_HDR_W1_METADATA GENMASK(31, 24) +#define FWSECTION_HDR_W1_SECTIONTYPE GENMASK(27, 24) +#define FWSECTION_HDR_W1_SEC_SIZE GENMASK(23, 0) +#define FWSECTION_HDR_W1_CHECKSUM BIT(28) +#define FWSECTION_HDR_W1_REDL BIT(29) +#define FWSECTION_HDR_W2_MSSC GENMASK(31, 0) + +struct rtw89_fw_hdr { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + struct rtw89_fw_hdr_section sections[]; + /* struct rtw89_fw_dynhdr_hdr (optional) */ +} __packed; + +#define FW_HDR_W1_MAJOR_VERSION GENMASK(7, 0) +#define FW_HDR_W1_MINOR_VERSION GENMASK(15, 8) +#define FW_HDR_W1_SUBVERSION GENMASK(23, 16) +#define FW_HDR_W1_SUBINDEX GENMASK(31, 24) +#define FW_HDR_W2_COMMITID GENMASK(31, 0) +#define FW_HDR_W3_LEN GENMASK(23, 16) +#define FW_HDR_W3_HDR_VER GENMASK(31, 24) +#define FW_HDR_W4_MONTH GENMASK(7, 0) +#define FW_HDR_W4_DATE GENMASK(15, 8) +#define FW_HDR_W4_HOUR GENMASK(23, 16) +#define FW_HDR_W4_MIN GENMASK(31, 24) +#define FW_HDR_W5_YEAR GENMASK(31, 0) +#define FW_HDR_W6_SEC_NUM GENMASK(15, 8) +#define FW_HDR_W7_PART_SIZE GENMASK(15, 0) +#define FW_HDR_W7_DYN_HDR BIT(16) +#define FW_HDR_W7_IDMEM_SHARE_MODE GENMASK(21, 18) +#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24) + +struct rtw89_fw_hdr_section_v1 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define FWSECTION_HDR_V1_W0_DL_ADDR GENMASK(31, 0) +#define FWSECTION_HDR_V1_W1_METADATA GENMASK(31, 24) +#define FWSECTION_HDR_V1_W1_SECTIONTYPE GENMASK(27, 24) +#define FWSECTION_HDR_V1_W1_SEC_SIZE GENMASK(23, 0) +#define FWSECTION_HDR_V1_W1_CHECKSUM BIT(28) +#define FWSECTION_HDR_V1_W1_REDL BIT(29) +#define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0) +#define FORMATTED_MSSC 0xFF +#define FORMATTED_MSSC_MASK GENMASK(7, 0) +#define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24) + +struct rtw89_fw_hdr_v1 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + struct rtw89_fw_hdr_section_v1 sections[]; +} __packed; + +#define FW_HDR_V1_W1_MAJOR_VERSION GENMASK(7, 0) +#define FW_HDR_V1_W1_MINOR_VERSION GENMASK(15, 8) +#define FW_HDR_V1_W1_SUBVERSION GENMASK(23, 16) +#define FW_HDR_V1_W1_SUBINDEX GENMASK(31, 24) +#define FW_HDR_V1_W2_COMMITID GENMASK(31, 0) +#define FW_HDR_V1_W3_CMD_VERSERION GENMASK(23, 16) +#define FW_HDR_V1_W3_HDR_VER GENMASK(31, 24) +#define FW_HDR_V1_W4_MONTH GENMASK(7, 0) +#define FW_HDR_V1_W4_DATE GENMASK(15, 8) +#define FW_HDR_V1_W4_HOUR GENMASK(23, 16) +#define FW_HDR_V1_W4_MIN GENMASK(31, 24) +#define FW_HDR_V1_W5_YEAR GENMASK(15, 0) +#define FW_HDR_V1_W5_HDR_SIZE GENMASK(31, 16) +#define FW_HDR_V1_W6_SEC_NUM GENMASK(15, 8) +#define FW_HDR_V1_W6_DSP_CHKSUM BIT(24) +#define FW_HDR_V1_W7_PART_SIZE GENMASK(15, 0) +#define FW_HDR_V1_W7_DYN_HDR BIT(16) +#define FW_HDR_V1_W7_IDMEM_SHARE_MODE GENMASK(21, 18) + +enum rtw89_fw_mss_pool_rmp_tbl_type { + MSS_POOL_RMP_TBL_BITMASK = 0x0, + MSS_POOL_RMP_TBL_RECORD = 0x1, +}; + +#define FWDL_MSS_POOL_DEFKEYSETS_SIZE 8 + +struct rtw89_fw_mss_pool_hdr { + u8 signature[8]; /* equal to mss_signature[] */ + __le32 rmp_tbl_offset; + __le32 key_raw_offset; + u8 defen; + u8 rsvd[3]; + u8 rmpfmt; /* enum rtw89_fw_mss_pool_rmp_tbl_type */ + u8 mssdev_max; + __le16 keypair_num; + __le16 msscust_max; + __le16 msskey_num_max; + __le32 rsvd3; + u8 rmp_tbl[]; +} __packed; + +union rtw89_fw_section_mssc_content { + struct { + u8 pad[0x20]; + u8 bit_in_chip_list; + u8 ver; + } __packed blacklist; + struct { + u8 pad[58]; + __le32 v; + } __packed sb_sel_ver; + struct { + u8 pad[60]; + __le16 v; + } __packed key_sign_len; +} __packed; + +struct rtw89_fw_blacklist { + u8 ver; + u8 list[32]; +}; + +extern const struct rtw89_fw_blacklist rtw89_fw_blacklist_default; + +static inline void SET_CTRL_INFO_MACID(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)); +} + +static inline void SET_CTRL_INFO_OPERATION(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7)); +} +#define SET_CMC_TBL_MASK_DATARATE GENMASK(8, 0) +static inline void SET_CMC_TBL_DATARATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(8, 0)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATARATE, + GENMASK(8, 0)); +} +#define SET_CMC_TBL_MASK_FORCE_TXOP BIT(0) +static inline void SET_CMC_TBL_FORCE_TXOP(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(9)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_FORCE_TXOP, + BIT(9)); +} +#define SET_CMC_TBL_MASK_DATA_BW GENMASK(1, 0) +static inline void SET_CMC_TBL_DATA_BW(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(11, 10)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_BW, + GENMASK(11, 10)); +} +#define SET_CMC_TBL_MASK_DATA_GI_LTF GENMASK(2, 0) +static inline void SET_CMC_TBL_DATA_GI_LTF(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 12)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_GI_LTF, + GENMASK(14, 12)); +} +#define SET_CMC_TBL_MASK_DARF_TC_INDEX BIT(0) +static inline void SET_CMC_TBL_DARF_TC_INDEX(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DARF_TC_INDEX, + BIT(15)); +} +#define SET_CMC_TBL_MASK_ARFR_CTRL GENMASK(3, 0) +static inline void SET_CMC_TBL_ARFR_CTRL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(19, 16)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ARFR_CTRL, + GENMASK(19, 16)); +} +#define SET_CMC_TBL_MASK_ACQ_RPT_EN BIT(0) +static inline void SET_CMC_TBL_ACQ_RPT_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(20)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ACQ_RPT_EN, + BIT(20)); +} +#define SET_CMC_TBL_MASK_MGQ_RPT_EN BIT(0) +static inline void SET_CMC_TBL_MGQ_RPT_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(21)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_MGQ_RPT_EN, + BIT(21)); +} +#define SET_CMC_TBL_MASK_ULQ_RPT_EN BIT(0) +static inline void SET_CMC_TBL_ULQ_RPT_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(22)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ULQ_RPT_EN, + BIT(22)); +} +#define SET_CMC_TBL_MASK_TWTQ_RPT_EN BIT(0) +static inline void SET_CMC_TBL_TWTQ_RPT_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(23)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TWTQ_RPT_EN, + BIT(23)); +} +#define SET_CMC_TBL_MASK_DISRTSFB BIT(0) +static inline void SET_CMC_TBL_DISRTSFB(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(25)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISRTSFB, + BIT(25)); +} +#define SET_CMC_TBL_MASK_DISDATAFB BIT(0) +static inline void SET_CMC_TBL_DISDATAFB(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(26)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISDATAFB, + BIT(26)); +} +#define SET_CMC_TBL_MASK_TRYRATE BIT(0) +static inline void SET_CMC_TBL_TRYRATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(27)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TRYRATE, + BIT(27)); +} +#define SET_CMC_TBL_MASK_AMPDU_DENSITY GENMASK(3, 0) +static inline void SET_CMC_TBL_AMPDU_DENSITY(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 28)); + le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_AMPDU_DENSITY, + GENMASK(31, 28)); +} +#define SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE GENMASK(8, 0) +static inline void SET_CMC_TBL_DATA_RTY_LOWEST_RATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(8, 0)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE, + GENMASK(8, 0)); +} +#define SET_CMC_TBL_MASK_AMPDU_TIME_SEL BIT(0) +static inline void SET_CMC_TBL_AMPDU_TIME_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, BIT(9)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_TIME_SEL, + BIT(9)); +} +#define SET_CMC_TBL_MASK_AMPDU_LEN_SEL BIT(0) +static inline void SET_CMC_TBL_AMPDU_LEN_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, BIT(10)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_LEN_SEL, + BIT(10)); +} +#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL BIT(0) +static inline void SET_CMC_TBL_RTS_TXCNT_LMT_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, BIT(11)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL, + BIT(11)); +} +#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT GENMASK(3, 0) +static inline void SET_CMC_TBL_RTS_TXCNT_LMT(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(15, 12)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT, + GENMASK(15, 12)); +} +#define SET_CMC_TBL_MASK_RTSRATE GENMASK(8, 0) +static inline void SET_CMC_TBL_RTSRATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(24, 16)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTSRATE, + GENMASK(24, 16)); +} +#define SET_CMC_TBL_MASK_VCS_STBC BIT(0) +static inline void SET_CMC_TBL_VCS_STBC(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, BIT(27)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_VCS_STBC, + BIT(27)); +} +#define SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE GENMASK(3, 0) +static inline void SET_CMC_TBL_RTS_RTY_LOWEST_RATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 28)); + le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE, + GENMASK(31, 28)); +} +#define SET_CMC_TBL_MASK_DATA_TX_CNT_LMT GENMASK(5, 0) +static inline void SET_CMC_TBL_DATA_TX_CNT_LMT(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(5, 0)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TX_CNT_LMT, + GENMASK(5, 0)); +} +#define SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL BIT(0) +static inline void SET_CMC_TBL_DATA_TXCNT_LMT_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(6)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL, + BIT(6)); +} +#define SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL BIT(0) +static inline void SET_CMC_TBL_MAX_AGG_NUM_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(7)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL, + BIT(7)); +} +#define SET_CMC_TBL_MASK_RTS_EN BIT(0) +static inline void SET_CMC_TBL_RTS_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(8)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_EN, + BIT(8)); +} +#define SET_CMC_TBL_MASK_CTS2SELF_EN BIT(0) +static inline void SET_CMC_TBL_CTS2SELF_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(9)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CTS2SELF_EN, + BIT(9)); +} +#define SET_CMC_TBL_MASK_CCA_RTS GENMASK(1, 0) +static inline void SET_CMC_TBL_CCA_RTS(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 10)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CCA_RTS, + GENMASK(11, 10)); +} +#define SET_CMC_TBL_MASK_HW_RTS_EN BIT(0) +static inline void SET_CMC_TBL_HW_RTS_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(12)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_HW_RTS_EN, + BIT(12)); +} +#define SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE GENMASK(1, 0) +static inline void SET_CMC_TBL_RTS_DROP_DATA_MODE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(14, 13)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE, + GENMASK(14, 13)); +} +#define SET_CMC_TBL_MASK_AMPDU_MAX_LEN GENMASK(10, 0) +static inline void SET_CMC_TBL_AMPDU_MAX_LEN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 16)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_LEN, + GENMASK(26, 16)); +} +#define SET_CMC_TBL_MASK_UL_MU_DIS BIT(0) +static inline void SET_CMC_TBL_UL_MU_DIS(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_UL_MU_DIS, + BIT(27)); +} +#define SET_CMC_TBL_MASK_AMPDU_MAX_TIME GENMASK(3, 0) +static inline void SET_CMC_TBL_AMPDU_MAX_TIME(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(31, 28)); + le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_TIME, + GENMASK(31, 28)); +} +#define SET_CMC_TBL_MASK_MAX_AGG_NUM GENMASK(7, 0) +static inline void SET_CMC_TBL_MAX_AGG_NUM(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(7, 0)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_MAX_AGG_NUM, + GENMASK(7, 0)); +} +#define SET_CMC_TBL_MASK_BA_BMAP GENMASK(1, 0) +static inline void SET_CMC_TBL_BA_BMAP(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(9, 8)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BA_BMAP, + GENMASK(9, 8)); +} +#define SET_CMC_TBL_MASK_VO_LFTIME_SEL GENMASK(2, 0) +static inline void SET_CMC_TBL_VO_LFTIME_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(18, 16)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VO_LFTIME_SEL, + GENMASK(18, 16)); +} +#define SET_CMC_TBL_MASK_VI_LFTIME_SEL GENMASK(2, 0) +static inline void SET_CMC_TBL_VI_LFTIME_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(21, 19)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VI_LFTIME_SEL, + GENMASK(21, 19)); +} +#define SET_CMC_TBL_MASK_BE_LFTIME_SEL GENMASK(2, 0) +static inline void SET_CMC_TBL_BE_LFTIME_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(24, 22)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BE_LFTIME_SEL, + GENMASK(24, 22)); +} +#define SET_CMC_TBL_MASK_BK_LFTIME_SEL GENMASK(2, 0) +static inline void SET_CMC_TBL_BK_LFTIME_SEL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 25)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BK_LFTIME_SEL, + GENMASK(27, 25)); +} +#define SET_CMC_TBL_MASK_SECTYPE GENMASK(3, 0) +static inline void SET_CMC_TBL_SECTYPE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 28)); + le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_SECTYPE, + GENMASK(31, 28)); +} +#define SET_CMC_TBL_MASK_MULTI_PORT_ID GENMASK(2, 0) +static inline void SET_CMC_TBL_MULTI_PORT_ID(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(2, 0)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MULTI_PORT_ID, + GENMASK(2, 0)); +} +#define SET_CMC_TBL_MASK_BMC BIT(0) +static inline void SET_CMC_TBL_BMC(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(3)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_BMC, + BIT(3)); +} +#define SET_CMC_TBL_MASK_MBSSID GENMASK(3, 0) +static inline void SET_CMC_TBL_MBSSID(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 4)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MBSSID, + GENMASK(7, 4)); +} +#define SET_CMC_TBL_MASK_NAVUSEHDR BIT(0) +static inline void SET_CMC_TBL_NAVUSEHDR(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_NAVUSEHDR, + BIT(8)); +} +#define SET_CMC_TBL_MASK_TXPWR_MODE GENMASK(2, 0) +static inline void SET_CMC_TBL_TXPWR_MODE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(11, 9)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_TXPWR_MODE, + GENMASK(11, 9)); +} +#define SET_CMC_TBL_MASK_DATA_DCM BIT(0) +static inline void SET_CMC_TBL_DATA_DCM(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(12)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_DCM, + BIT(12)); +} +#define SET_CMC_TBL_MASK_DATA_ER BIT(0) +static inline void SET_CMC_TBL_DATA_ER(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(13)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_ER, + BIT(13)); +} +#define SET_CMC_TBL_MASK_DATA_LDPC BIT(0) +static inline void SET_CMC_TBL_DATA_LDPC(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(14)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_LDPC, + BIT(14)); +} +#define SET_CMC_TBL_MASK_DATA_STBC BIT(0) +static inline void SET_CMC_TBL_DATA_STBC(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_STBC, + BIT(15)); +} +#define SET_CMC_TBL_MASK_A_CTRL_BQR BIT(0) +static inline void SET_CMC_TBL_A_CTRL_BQR(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(16)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BQR, + BIT(16)); +} +#define SET_CMC_TBL_MASK_A_CTRL_UPH BIT(0) +static inline void SET_CMC_TBL_A_CTRL_UPH(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(17)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_UPH, + BIT(17)); +} +#define SET_CMC_TBL_MASK_A_CTRL_BSR BIT(0) +static inline void SET_CMC_TBL_A_CTRL_BSR(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(18)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BSR, + BIT(18)); +} +#define SET_CMC_TBL_MASK_A_CTRL_CAS BIT(0) +static inline void SET_CMC_TBL_A_CTRL_CAS(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(19)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_CAS, + BIT(19)); +} +#define SET_CMC_TBL_MASK_DATA_BW_ER BIT(0) +static inline void SET_CMC_TBL_DATA_BW_ER(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(20)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_BW_ER, + BIT(20)); +} +#define SET_CMC_TBL_MASK_LSIG_TXOP_EN BIT(0) +static inline void SET_CMC_TBL_LSIG_TXOP_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(21)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_LSIG_TXOP_EN, + BIT(21)); +} +#define SET_CMC_TBL_MASK_CTRL_CNT_VLD BIT(0) +static inline void SET_CMC_TBL_CTRL_CNT_VLD(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(27)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT_VLD, + BIT(27)); +} +#define SET_CMC_TBL_MASK_CTRL_CNT GENMASK(3, 0) +static inline void SET_CMC_TBL_CTRL_CNT(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 28)); + le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT, + GENMASK(31, 28)); +} +#define SET_CMC_TBL_MASK_RESP_REF_RATE GENMASK(8, 0) +static inline void SET_CMC_TBL_RESP_REF_RATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(8, 0)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_RESP_REF_RATE, + GENMASK(8, 0)); +} +#define SET_CMC_TBL_MASK_ALL_ACK_SUPPORT BIT(0) +static inline void SET_CMC_TBL_ALL_ACK_SUPPORT(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(12)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ALL_ACK_SUPPORT, + BIT(12)); +} +#define SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT BIT(0) +static inline void SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(13)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT, + BIT(13)); +} +#define SET_CMC_TBL_MASK_NTX_PATH_EN GENMASK(3, 0) +static inline void SET_CMC_TBL_NTX_PATH_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(19, 16)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_NTX_PATH_EN, + GENMASK(19, 16)); +} +#define SET_CMC_TBL_MASK_PATH_MAP_A GENMASK(1, 0) +static inline void SET_CMC_TBL_PATH_MAP_A(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(21, 20)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_A, + GENMASK(21, 20)); +} +#define SET_CMC_TBL_MASK_PATH_MAP_B GENMASK(1, 0) +static inline void SET_CMC_TBL_PATH_MAP_B(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 22)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_B, + GENMASK(23, 22)); +} +#define SET_CMC_TBL_MASK_PATH_MAP_C GENMASK(1, 0) +static inline void SET_CMC_TBL_PATH_MAP_C(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(25, 24)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_C, + GENMASK(25, 24)); +} +#define SET_CMC_TBL_MASK_PATH_MAP_D GENMASK(1, 0) +static inline void SET_CMC_TBL_PATH_MAP_D(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(27, 26)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_D, + GENMASK(27, 26)); +} +#define SET_CMC_TBL_MASK_ANTSEL_A BIT(0) +static inline void SET_CMC_TBL_ANTSEL_A(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(28)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_A, + BIT(28)); +} +#define SET_CMC_TBL_MASK_ANTSEL_B BIT(0) +static inline void SET_CMC_TBL_ANTSEL_B(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(29)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_B, + BIT(29)); +} +#define SET_CMC_TBL_MASK_ANTSEL_C BIT(0) +static inline void SET_CMC_TBL_ANTSEL_C(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(30)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_C, + BIT(30)); +} +#define SET_CMC_TBL_MASK_ANTSEL_D BIT(0) +static inline void SET_CMC_TBL_ANTSEL_D(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, BIT(31)); + le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_D, + BIT(31)); +} + +#define SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING GENMASK(1, 0) +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(1, 0)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(1, 0)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(3, 2)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(3, 2)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(5, 4)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(5, 4)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 6)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(7, 6)); +} + +#define SET_CMC_TBL_MASK_ADDR_CAM_INDEX GENMASK(7, 0) +static inline void SET_CMC_TBL_ADDR_CAM_INDEX(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ADDR_CAM_INDEX, + GENMASK(7, 0)); +} +#define SET_CMC_TBL_MASK_PAID GENMASK(8, 0) +static inline void SET_CMC_TBL_PAID(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(16, 8)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_PAID, + GENMASK(16, 8)); +} +#define SET_CMC_TBL_MASK_ULDL BIT(0) +static inline void SET_CMC_TBL_ULDL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, BIT(17)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ULDL, + BIT(17)); +} +#define SET_CMC_TBL_MASK_DOPPLER_CTRL GENMASK(1, 0) +static inline void SET_CMC_TBL_DOPPLER_CTRL(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(19, 18)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_DOPPLER_CTRL, + GENMASK(19, 18)); +} +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(21, 20)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(21, 20)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING40(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 22)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(23, 22)); +} +#define SET_CMC_TBL_MASK_TXPWR_TOLERENCE GENMASK(3, 0) +static inline void SET_CMC_TBL_TXPWR_TOLERENCE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(27, 24)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_TXPWR_TOLERENCE, + GENMASK(27, 24)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING80(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 30)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(31, 30)); +} +#define SET_CMC_TBL_MASK_NC GENMASK(2, 0) +static inline void SET_CMC_TBL_NC(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(2, 0)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NC, + GENMASK(2, 0)); +} +#define SET_CMC_TBL_MASK_NR GENMASK(2, 0) +static inline void SET_CMC_TBL_NR(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(5, 3)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NR, + GENMASK(5, 3)); +} +#define SET_CMC_TBL_MASK_NG GENMASK(1, 0) +static inline void SET_CMC_TBL_NG(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(7, 6)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NG, + GENMASK(7, 6)); +} +#define SET_CMC_TBL_MASK_CB GENMASK(1, 0) +static inline void SET_CMC_TBL_CB(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(9, 8)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CB, + GENMASK(9, 8)); +} +#define SET_CMC_TBL_MASK_CS GENMASK(1, 0) +static inline void SET_CMC_TBL_CS(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(11, 10)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CS, + GENMASK(11, 10)); +} +#define SET_CMC_TBL_MASK_CSI_TXBF_EN BIT(0) +static inline void SET_CMC_TBL_CSI_TXBF_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, BIT(12)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_TXBF_EN, + BIT(12)); +} +#define SET_CMC_TBL_MASK_CSI_STBC_EN BIT(0) +static inline void SET_CMC_TBL_CSI_STBC_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, BIT(13)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_STBC_EN, + BIT(13)); +} +#define SET_CMC_TBL_MASK_CSI_LDPC_EN BIT(0) +static inline void SET_CMC_TBL_CSI_LDPC_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, BIT(14)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_LDPC_EN, + BIT(14)); +} +#define SET_CMC_TBL_MASK_CSI_PARA_EN BIT(0) +static inline void SET_CMC_TBL_CSI_PARA_EN(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, BIT(15)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_PARA_EN, + BIT(15)); +} +#define SET_CMC_TBL_MASK_CSI_FIX_RATE GENMASK(8, 0) +static inline void SET_CMC_TBL_CSI_FIX_RATE(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(24, 16)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_FIX_RATE, + GENMASK(24, 16)); +} +#define SET_CMC_TBL_MASK_CSI_GI_LTF GENMASK(2, 0) +static inline void SET_CMC_TBL_CSI_GI_LTF(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(27, 25)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GI_LTF, + GENMASK(27, 25)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING160(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(29, 28)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(29, 28)); +} + +#define SET_CMC_TBL_MASK_CSI_BW GENMASK(1, 0) +static inline void SET_CMC_TBL_CSI_BW(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(31, 30)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_BW, + GENMASK(31, 30)); +} + +struct rtw89_h2c_cctlinfo_ud_g7 { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define CCTLINFO_G7_C0_MACID GENMASK(6, 0) +#define CCTLINFO_G7_C0_OP BIT(7) + +#define CCTLINFO_G7_W0_DATARATE GENMASK(11, 0) +#define CCTLINFO_G7_W0_DATA_GI_LTF GENMASK(14, 12) +#define CCTLINFO_G7_W0_TRYRATE BIT(15) +#define CCTLINFO_G7_W0_ARFR_CTRL GENMASK(17, 16) +#define CCTLINFO_G7_W0_DIS_HE1SS_STBC BIT(18) +#define CCTLINFO_G7_W0_ACQ_RPT_EN BIT(20) +#define CCTLINFO_G7_W0_MGQ_RPT_EN BIT(21) +#define CCTLINFO_G7_W0_ULQ_RPT_EN BIT(22) +#define CCTLINFO_G7_W0_TWTQ_RPT_EN BIT(23) +#define CCTLINFO_G7_W0_FORCE_TXOP BIT(24) +#define CCTLINFO_G7_W0_DISRTSFB BIT(25) +#define CCTLINFO_G7_W0_DISDATAFB BIT(26) +#define CCTLINFO_G7_W0_NSTR_EN BIT(27) +#define CCTLINFO_G7_W0_AMPDU_DENSITY GENMASK(31, 28) +#define CCTLINFO_G7_W0_ALL (GENMASK(31, 20) | GENMASK(18, 0)) +#define CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE GENMASK(11, 0) +#define CCTLINFO_G7_W1_RTS_TXCNT_LMT GENMASK(15, 12) +#define CCTLINFO_G7_W1_RTSRATE GENMASK(27, 16) +#define CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE GENMASK(31, 28) +#define CCTLINFO_G7_W1_ALL GENMASK(31, 0) +#define CCTLINFO_G7_W2_DATA_TX_CNT_LMT GENMASK(5, 0) +#define CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL BIT(6) +#define CCTLINFO_G7_W2_MAX_AGG_NUM_SEL BIT(7) +#define CCTLINFO_G7_W2_RTS_EN BIT(8) +#define CCTLINFO_G7_W2_CTS2SELF_EN BIT(9) +#define CCTLINFO_G7_W2_CCA_RTS GENMASK(11, 10) +#define CCTLINFO_G7_W2_HW_RTS_EN BIT(12) +#define CCTLINFO_G7_W2_RTS_DROP_DATA_MODE GENMASK(14, 13) +#define CCTLINFO_G7_W2_PRELD_EN BIT(15) +#define CCTLINFO_G7_W2_AMPDU_MAX_LEN GENMASK(26, 16) +#define CCTLINFO_G7_W2_UL_MU_DIS BIT(27) +#define CCTLINFO_G7_W2_AMPDU_MAX_TIME GENMASK(31, 28) +#define CCTLINFO_G7_W2_ALL GENMASK(31, 0) +#define CCTLINFO_G7_W3_MAX_AGG_NUM GENMASK(7, 0) +#define CCTLINFO_G7_W3_DATA_BW GENMASK(10, 8) +#define CCTLINFO_G7_W3_DATA_BW_ER BIT(11) +#define CCTLINFO_G7_W3_BA_BMAP GENMASK(14, 12) +#define CCTLINFO_G7_W3_VCS_STBC BIT(15) +#define CCTLINFO_G7_W3_VO_LFTIME_SEL GENMASK(18, 16) +#define CCTLINFO_G7_W3_VI_LFTIME_SEL GENMASK(21, 19) +#define CCTLINFO_G7_W3_BE_LFTIME_SEL GENMASK(24, 22) +#define CCTLINFO_G7_W3_BK_LFTIME_SEL GENMASK(27, 25) +#define CCTLINFO_G7_W3_AMPDU_TIME_SEL BIT(28) +#define CCTLINFO_G7_W3_AMPDU_LEN_SEL BIT(29) +#define CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL BIT(30) +#define CCTLINFO_G7_W3_LSIG_TXOP_EN BIT(31) +#define CCTLINFO_G7_W3_ALL GENMASK(31, 0) +#define CCTLINFO_G7_W4_MULTI_PORT_ID GENMASK(2, 0) +#define CCTLINFO_G7_W4_BYPASS_PUNC BIT(3) +#define CCTLINFO_G7_W4_MBSSID GENMASK(7, 4) +#define CCTLINFO_G7_W4_DATA_DCM BIT(8) +#define CCTLINFO_G7_W4_DATA_ER BIT(9) +#define CCTLINFO_G7_W4_DATA_LDPC BIT(10) +#define CCTLINFO_G7_W4_DATA_STBC BIT(11) +#define CCTLINFO_G7_W4_A_CTRL_BQR BIT(12) +#define CCTLINFO_G7_W4_A_CTRL_BSR BIT(14) +#define CCTLINFO_G7_W4_A_CTRL_CAS BIT(15) +#define CCTLINFO_G7_W4_ACT_SUBCH_CBW GENMASK(31, 16) +#define CCTLINFO_G7_W4_ALL (GENMASK(31, 14) | GENMASK(12, 0)) +#define CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 GENMASK(1, 0) +#define CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 GENMASK(3, 2) +#define CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 GENMASK(5, 4) +#define CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 GENMASK(7, 6) +#define CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4 GENMASK(9, 8) +#define CCTLINFO_G7_W5_SR_RATE GENMASK(14, 10) +#define CCTLINFO_G7_W5_TID_DISABLE GENMASK(23, 16) +#define CCTLINFO_G7_W5_ADDR_CAM_INDEX GENMASK(31, 24) +#define CCTLINFO_G7_W5_ALL (GENMASK(31, 16) | GENMASK(14, 0)) +#define CCTLINFO_G7_W6_AID12_PAID GENMASK(11, 0) +#define CCTLINFO_G7_W6_RESP_REF_RATE GENMASK(23, 12) +#define CCTLINFO_G7_W6_ULDL BIT(31) +#define CCTLINFO_G7_W6_ALL (BIT(31) | GENMASK(23, 0)) +#define CCTLINFO_G7_W7_NC GENMASK(2, 0) +#define CCTLINFO_G7_W7_NR GENMASK(5, 3) +#define CCTLINFO_G7_W7_NG GENMASK(7, 6) +#define CCTLINFO_G7_W7_CB GENMASK(9, 8) +#define CCTLINFO_G7_W7_CS GENMASK(11, 10) +#define CCTLINFO_G7_W7_CSI_STBC_EN BIT(13) +#define CCTLINFO_G7_W7_CSI_LDPC_EN BIT(14) +#define CCTLINFO_G7_W7_CSI_PARA_EN BIT(15) +#define CCTLINFO_G7_W7_CSI_FIX_RATE GENMASK(27, 16) +#define CCTLINFO_G7_W7_CSI_BW GENMASK(31, 29) +#define CCTLINFO_G7_W7_ALL (GENMASK(31, 29) | GENMASK(27, 13) | GENMASK(11, 0)) +#define CCTLINFO_G7_W8_ALL_ACK_SUPPORT BIT(0) +#define CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT BIT(1) +#define CCTLINFO_G7_W8_BSR_OM_UPD_EN BIT(2) +#define CCTLINFO_G7_W8_MACID_FWD_IDC BIT(3) +#define CCTLINFO_G7_W8_AZ_SEC_EN BIT(4) +#define CCTLINFO_G7_W8_CSI_SEC_EN BIT(5) +#define CCTLINFO_G7_W8_FIX_UL_ADDRCAM_IDX BIT(6) +#define CCTLINFO_G7_W8_CTRL_CNT_VLD BIT(7) +#define CCTLINFO_G7_W8_CTRL_CNT GENMASK(11, 8) +#define CCTLINFO_G7_W8_RESP_SEC_TYPE GENMASK(15, 12) +#define CCTLINFO_G7_W8_ALL GENMASK(15, 0) +/* W9~13 are reserved */ +#define CCTLINFO_G7_W14_VO_CURR_RATE GENMASK(11, 0) +#define CCTLINFO_G7_W14_VI_CURR_RATE GENMASK(23, 12) +#define CCTLINFO_G7_W14_BE_CURR_RATE_L GENMASK(31, 24) +#define CCTLINFO_G7_W14_ALL GENMASK(31, 0) +#define CCTLINFO_G7_W15_BE_CURR_RATE_H GENMASK(3, 0) +#define CCTLINFO_G7_W15_BK_CURR_RATE GENMASK(15, 4) +#define CCTLINFO_G7_W15_MGNT_CURR_RATE GENMASK(27, 16) +#define CCTLINFO_G7_W15_ALL GENMASK(27, 0) + +struct rtw89_h2c_cctlinfo_ud_be { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define BE_CCTL_INFO_C0_V1_MACID GENMASK(9, 0) +#define BE_CCTL_INFO_C0_V1_OP BIT(10) + +#define BE_CCTL_INFO_W0_DATARATE GENMASK(11, 0) +#define BE_CCTL_INFO_W0_DATA_GI_LTF GENMASK(14, 12) +#define BE_CCTL_INFO_W0_TRYRATE BIT(15) +#define BE_CCTL_INFO_W0_ARFR_CTRL GENMASK(17, 16) +#define BE_CCTL_INFO_W0_DIS_HE1SS_STBC BIT(18) +#define BE_CCTL_INFO_W0_ACQ_RPT_EN BIT(20) +#define BE_CCTL_INFO_W0_MGQ_RPT_EN BIT(21) +#define BE_CCTL_INFO_W0_ULQ_RPT_EN BIT(22) +#define BE_CCTL_INFO_W0_TWTQ_RPT_EN BIT(23) +#define BE_CCTL_INFO_W0_FORCE_TXOP BIT(24) +#define BE_CCTL_INFO_W0_DISRTSFB BIT(25) +#define BE_CCTL_INFO_W0_DISDATAFB BIT(26) +#define BE_CCTL_INFO_W0_NSTR_EN BIT(27) +#define BE_CCTL_INFO_W0_AMPDU_DENSITY GENMASK(31, 28) +#define BE_CCTL_INFO_W0_ALL (GENMASK(31, 20) | GENMASK(18, 0)) +#define BE_CCTL_INFO_W1_DATA_RTY_LOWEST_RATE GENMASK(11, 0) +#define BE_CCTL_INFO_W1_RTS_TXCNT_LMT GENMASK(15, 12) +#define BE_CCTL_INFO_W1_RTSRATE GENMASK(27, 16) +#define BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE GENMASK(31, 28) +#define BE_CCTL_INFO_W1_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W2_DATA_TX_CNT_LMT GENMASK(5, 0) +#define BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL BIT(6) +#define BE_CCTL_INFO_W2_MAX_AGG_NUM_SEL BIT(7) +#define BE_CCTL_INFO_W2_RTS_EN BIT(8) +#define BE_CCTL_INFO_W2_CTS2SELF_EN BIT(9) +#define BE_CCTL_INFO_W2_CCA_RTS GENMASK(11, 10) +#define BE_CCTL_INFO_W2_HW_RTS_EN BIT(12) +#define BE_CCTL_INFO_W2_RTS_DROP_DATA_MODE GENMASK(14, 13) +#define BE_CCTL_INFO_W2_PRELOAD_ENABLE BIT(15) +#define BE_CCTL_INFO_W2_AMPDU_MAX_LEN GENMASK(26, 16) +#define BE_CCTL_INFO_W2_UL_MU_DIS BIT(27) +#define BE_CCTL_INFO_W2_AMPDU_MAX_TIME GENMASK(31, 28) +#define BE_CCTL_INFO_W2_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W3_MAX_AGG_NUM GENMASK(7, 0) +#define BE_CCTL_INFO_W3_DATA_BW GENMASK(10, 8) +#define BE_CCTL_INFO_W3_DATA_BW_ER BIT(11) +#define BE_CCTL_INFO_W3_BA_BMAP GENMASK(14, 12) +#define BE_CCTL_INFO_W3_VCS_STBC BIT(15) +#define BE_CCTL_INFO_W3_VO_LFTIME_SEL GENMASK(18, 16) +#define BE_CCTL_INFO_W3_VI_LFTIME_SEL GENMASK(21, 19) +#define BE_CCTL_INFO_W3_BE_LFTIME_SEL GENMASK(24, 22) +#define BE_CCTL_INFO_W3_BK_LFTIME_SEL GENMASK(27, 25) +#define BE_CCTL_INFO_W3_AMPDU_TIME_SEL BIT(28) +#define BE_CCTL_INFO_W3_AMPDU_LEN_SEL BIT(29) +#define BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL BIT(30) +#define BE_CCTL_INFO_W3_LSIG_TXOP_EN BIT(31) +#define BE_CCTL_INFO_W3_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W4_MULTI_PORT_ID GENMASK(2, 0) +#define BE_CCTL_INFO_W4_BYPASS_PUNC BIT(3) +#define BE_CCTL_INFO_W4_MBSSID GENMASK(7, 4) +#define BE_CCTL_INFO_W4_TID_DISABLE_V1 GENMASK(15, 8) +#define BE_CCTL_INFO_W4_ACT_SUBCH_CBW GENMASK(31, 16) +#define BE_CCTL_INFO_W4_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W5_ADDR_CAM_INDEX_V1 GENMASK(9, 0) +#define BE_CCTL_INFO_W5_SR_MCS_SU GENMASK(14, 10) +#define BE_CCTL_INFO_W5_A_CTRL_BQR_V1 BIT(15) +#define BE_CCTL_INFO_W5_A_CTRL_BSR_V1 BIT(16) +#define BE_CCTL_INFO_W5_A_CTRL_CAS_V1 BIT(17) +#define BE_CCTL_INFO_W5_DATA_ER_V1 BIT(18) +#define BE_CCTL_INFO_W5_DATA_DCM_V1 BIT(19) +#define BE_CCTL_INFO_W5_DATA_LDPC_V1 BIT(20) +#define BE_CCTL_INFO_W5_DATA_STBC_V1 BIT(21) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1 GENMASK(23, 22) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1 GENMASK(25, 24) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1 GENMASK(27, 26) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1 GENMASK(29, 28) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1 GENMASK(31, 30) +#define BE_CCTL_INFO_W5_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W6_AID12_PAID GENMASK(11, 0) +#define BE_CCTL_INFO_W6_RESP_REF_RATE GENMASK(23, 12) +#define BE_CCTL_INFO_W6_ULDL BIT(31) +#define BE_CCTL_INFO_W6_ALL (BIT(31) | GENMASK(23, 0)) +#define BE_CCTL_INFO_W7_NC GENMASK(2, 0) +#define BE_CCTL_INFO_W7_NR GENMASK(5, 3) +#define BE_CCTL_INFO_W7_NG GENMASK(7, 6) +#define BE_CCTL_INFO_W7_CB GENMASK(9, 8) +#define BE_CCTL_INFO_W7_CS GENMASK(11, 10) +#define BE_CCTL_INFO_W7_CSI_STBC_EN BIT(13) +#define BE_CCTL_INFO_W7_CSI_LDPC_EN BIT(14) +#define BE_CCTL_INFO_W7_CSI_PARA_EN BIT(15) +#define BE_CCTL_INFO_W7_CSI_FIX_RATE GENMASK(27, 16) +#define BE_CCTL_INFO_W7_CSI_BW GENMASK(31, 29) +#define BE_CCTL_INFO_W7_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W8_ALL_ACK_SUPPORT_V1 BIT(0) +#define BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1 BIT(1) +#define BE_CCTL_INFO_W8_BSR_OM_UPD_EN_V1 BIT(2) +#define BE_CCTL_INFO_W8_MACID_FWD_IDC_V1 BIT(3) +#define BE_CCTL_INFO_W8_AZ_SEC_EN BIT(4) +#define BE_CCTL_INFO_W8_BF_SEC_EN BIT(5) +#define BE_CCTL_INFO_W8_FIX_UL_ADDRCAM_IDX_V1 BIT(6) +#define BE_CCTL_INFO_W8_CTRL_CNT_VLD_V1 BIT(7) +#define BE_CCTL_INFO_W8_CTRL_CNT_V1 GENMASK(11, 8) +#define BE_CCTL_INFO_W8_RESP_SEC_TYPE GENMASK(15, 12) +#define BE_CCTL_INFO_W8_ALL GENMASK(15, 0) +#define BE_CCTL_INFO_W9_EMLSR_TRANS_DLY GENMASK(2, 0) +#define BE_CCTL_INFO_W9_ALL GENMASK(2, 0) +#define BE_CCTL_INFO_W10_SW_EHT_NLTF GENMASK(1, 0) +#define BE_CCTL_INFO_W10_TB_MLO_MODE BIT(2) +#define BE_CCTL_INFO_W10_ALL GENMASK(2, 0) +#define BE_CCTL_INFO_W14_VO_CURR_RATE GENMASK(11, 0) +#define BE_CCTL_INFO_W14_VI_CURR_RATE GENMASK(23, 12) +#define BE_CCTL_INFO_W14_BE_CURR_RATE_L GENMASK(31, 24) +#define BE_CCTL_INFO_W14_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W15_BE_CURR_RATE_H GENMASK(3, 0) +#define BE_CCTL_INFO_W15_BK_CURR_RATE GENMASK(15, 4) +#define BE_CCTL_INFO_W15_MGNT_CURR_RATE GENMASK(27, 16) +#define BE_CCTL_INFO_W15_ALL GENMASK(27, 0) + +struct rtw89_h2c_bcn_upd { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_H2C_BCN_UPD_W0_PORT GENMASK(7, 0) +#define RTW89_H2C_BCN_UPD_W0_MBSSID GENMASK(15, 8) +#define RTW89_H2C_BCN_UPD_W0_BAND GENMASK(23, 16) +#define RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST GENMASK(31, 24) +#define RTW89_H2C_BCN_UPD_W1_MACID GENMASK(7, 0) +#define RTW89_H2C_BCN_UPD_W1_SSN_SEL GENMASK(9, 8) +#define RTW89_H2C_BCN_UPD_W1_SSN_MODE GENMASK(11, 10) +#define RTW89_H2C_BCN_UPD_W1_RATE GENMASK(20, 12) +#define RTW89_H2C_BCN_UPD_W1_TXPWR GENMASK(23, 21) +#define RTW89_H2C_BCN_UPD_W2_TXINFO_CTRL_EN BIT(0) +#define RTW89_H2C_BCN_UPD_W2_NTX_PATH_EN GENMASK(4, 1) +#define RTW89_H2C_BCN_UPD_W2_PATH_MAP_A GENMASK(6, 5) +#define RTW89_H2C_BCN_UPD_W2_PATH_MAP_B GENMASK(8, 7) +#define RTW89_H2C_BCN_UPD_W2_PATH_MAP_C GENMASK(10, 9) +#define RTW89_H2C_BCN_UPD_W2_PATH_MAP_D GENMASK(12, 11) +#define RTW89_H2C_BCN_UPD_W2_PATH_ANTSEL_A BIT(13) +#define RTW89_H2C_BCN_UPD_W2_PATH_ANTSEL_B BIT(14) +#define RTW89_H2C_BCN_UPD_W2_PATH_ANTSEL_C BIT(15) +#define RTW89_H2C_BCN_UPD_W2_PATH_ANTSEL_D BIT(16) +#define RTW89_H2C_BCN_UPD_W2_CSA_OFST GENMASK(31, 17) + +struct rtw89_h2c_bcn_upd_be { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 w16; + __le32 w17; + __le32 w18; + __le32 w19; + __le32 w20; + __le32 w21; + __le32 w22; + __le32 w23; + __le32 w24; + __le32 w25; + __le32 w26; + __le32 w27; + __le32 w28; + __le32 w29; +} __packed; + +#define RTW89_H2C_BCN_UPD_BE_W0_PORT GENMASK(7, 0) +#define RTW89_H2C_BCN_UPD_BE_W0_MBSSID GENMASK(15, 8) +#define RTW89_H2C_BCN_UPD_BE_W0_BAND GENMASK(23, 16) +#define RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST GENMASK(31, 24) +#define RTW89_H2C_BCN_UPD_BE_W1_MACID GENMASK(7, 0) +#define RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL GENMASK(9, 8) +#define RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE GENMASK(11, 10) +#define RTW89_H2C_BCN_UPD_BE_W1_RATE GENMASK(20, 12) +#define RTW89_H2C_BCN_UPD_BE_W1_TXPWR GENMASK(23, 21) +#define RTW89_H2C_BCN_UPD_BE_W1_MACID_EXT GENMASK(31, 24) +#define RTW89_H2C_BCN_UPD_BE_W2_TXINFO_CTRL_EN BIT(0) +#define RTW89_H2C_BCN_UPD_BE_W2_NTX_PATH_EN GENMASK(4, 1) +#define RTW89_H2C_BCN_UPD_BE_W2_PATH_MAP_A GENMASK(6, 5) +#define RTW89_H2C_BCN_UPD_BE_W2_PATH_MAP_B GENMASK(8, 7) +#define RTW89_H2C_BCN_UPD_BE_W2_PATH_MAP_C GENMASK(10, 9) +#define RTW89_H2C_BCN_UPD_BE_W2_PATH_MAP_D GENMASK(12, 11) +#define RTW89_H2C_BCN_UPD_BE_W2_ANTSEL_A BIT(13) +#define RTW89_H2C_BCN_UPD_BE_W2_ANTSEL_B BIT(14) +#define RTW89_H2C_BCN_UPD_BE_W2_ANTSEL_C BIT(15) +#define RTW89_H2C_BCN_UPD_BE_W2_ANTSEL_D BIT(16) +#define RTW89_H2C_BCN_UPD_BE_W2_CSA_OFST GENMASK(31, 17) +#define RTW89_H2C_BCN_UPD_BE_W3_MLIE_CSA_OFST GENMASK(15, 0) +#define RTW89_H2C_BCN_UPD_BE_W3_CRITICAL_UPD_FLAG_OFST GENMASK(31, 16) +#define RTW89_H2C_BCN_UPD_BE_W4_VAP1_DTIM_CNT_OFST GENMASK(15, 0) +#define RTW89_H2C_BCN_UPD_BE_W4_VAP2_DTIM_CNT_OFST GENMASK(31, 16) +#define RTW89_H2C_BCN_UPD_BE_W5_VAP3_DTIM_CNT_OFST GENMASK(15, 0) +#define RTW89_H2C_BCN_UPD_BE_W5_VAP4_DTIM_CNT_OFST GENMASK(31, 16) +#define RTW89_H2C_BCN_UPD_BE_W6_VAP5_DTIM_CNT_OFST GENMASK(15, 0) +#define RTW89_H2C_BCN_UPD_BE_W6_VAP6_DTIM_CNT_OFST GENMASK(31, 16) +#define RTW89_H2C_BCN_UPD_BE_W7_VAP7_DTIM_CNT_OFST GENMASK(15, 0) +#define RTW89_H2C_BCN_UPD_BE_W7_ECSA_OFST GENMASK(30, 16) +#define RTW89_H2C_BCN_UPD_BE_W7_PROTECTION_KEY_ID BIT(31) + +struct rtw89_h2c_tbtt_tuning { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_TBTT_TUNING_W0_BAND GENMASK(3, 0) +#define RTW89_H2C_TBTT_TUNING_W0_PORT GENMASK(7, 4) +#define RTW89_H2C_TBTT_TUNING_W1_SHIFT GENMASK(31, 0) + +struct rtw89_h2c_pwr_lvl { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_PWR_LVL_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_PWR_LVL_W0_BCN_TO_VAL GENMASK(15, 8) +#define RTW89_H2C_PWR_LVL_W0_PS_LVL GENMASK(19, 16) +#define RTW89_H2C_PWR_LVL_W0_TRX_LVL GENMASK(23, 20) +#define RTW89_H2C_PWR_LVL_W0_BCN_TO_LVL GENMASK(27, 24) +#define RTW89_H2C_PWR_LVL_W0_DTIM_TO_VAL GENMASK(31, 28) +#define RTW89_H2C_PWR_LVL_W1_MACID_EXT GENMASK(7, 0) + +struct rtw89_h2c_role_maintain { + __le32 w0; +}; + +#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE GENMASK(9, 8) +#define RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE GENMASK(12, 10) +#define RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE GENMASK(16, 13) +#define RTW89_H2C_ROLE_MAINTAIN_W0_BAND GENMASK(18, 17) +#define RTW89_H2C_ROLE_MAINTAIN_W0_PORT GENMASK(21, 19) +#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID_EXT GENMASK(31, 24) + +enum rtw89_fw_sta_type { /* value of RTW89_H2C_JOININFO_W1_STA_TYPE */ + RTW89_FW_N_AC_STA = 0, + RTW89_FW_AX_STA = 1, + RTW89_FW_BE_STA = 2, +}; + +struct rtw89_h2c_join { + __le32 w0; +} __packed; + +struct rtw89_h2c_join_v1 { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_H2C_JOININFO_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_JOININFO_W0_OP BIT(8) +#define RTW89_H2C_JOININFO_W0_BAND BIT(9) +#define RTW89_H2C_JOININFO_W0_WMM GENMASK(11, 10) +#define RTW89_H2C_JOININFO_W0_TGR BIT(12) +#define RTW89_H2C_JOININFO_W0_ISHESTA BIT(13) +#define RTW89_H2C_JOININFO_W0_DLBW GENMASK(15, 14) +#define RTW89_H2C_JOININFO_W0_TF_MAC_PAD GENMASK(17, 16) +#define RTW89_H2C_JOININFO_W0_DL_T_PE GENMASK(20, 18) +#define RTW89_H2C_JOININFO_W0_PORT_ID GENMASK(23, 21) +#define RTW89_H2C_JOININFO_W0_NET_TYPE GENMASK(25, 24) +#define RTW89_H2C_JOININFO_W0_WIFI_ROLE GENMASK(29, 26) +#define RTW89_H2C_JOININFO_W0_SELF_ROLE GENMASK(31, 30) +#define RTW89_H2C_JOININFO_W1_STA_TYPE GENMASK(2, 0) +#define RTW89_H2C_JOININFO_W1_IS_MLD BIT(3) +#define RTW89_H2C_JOININFO_W1_MAIN_MACID GENMASK(11, 4) +#define RTW89_H2C_JOININFO_W1_MLO_MODE BIT(12) +#define RTW89_H2C_JOININFO_MLO_MODE_MLMR 0 +#define RTW89_H2C_JOININFO_MLO_MODE_MLSR 1 +#define RTW89_H2C_JOININFO_W1_EMLSR_CAB BIT(13) +#define RTW89_H2C_JOININFO_W1_NSTR_EN BIT(14) +#define RTW89_H2C_JOININFO_W1_INIT_PWR_STATE BIT(15) +#define RTW89_H2C_JOININFO_W1_EMLSR_PADDING GENMASK(18, 16) +#define RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY GENMASK(21, 19) +#define RTW89_H2C_JOININFO_W2_MACID_EXT GENMASK(7, 0) +#define RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT GENMASK(15, 8) + +struct rtw89_h2c_notify_dbcc { + __le32 w0; +} __packed; + +#define RTW89_H2C_NOTIFY_DBCC_EN BIT(0) + +static inline void SET_GENERAL_PKT_MACID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)); +} + +static inline void SET_GENERAL_PKT_PROBRSP_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); +} + +static inline void SET_GENERAL_PKT_PSPOLL_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)); +} + +static inline void SET_GENERAL_PKT_NULL_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); +} + +static inline void SET_GENERAL_PKT_QOS_NULL_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0)); +} + +static inline void SET_GENERAL_PKT_CTS2SELF_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)); +} + +static inline void SET_LOG_CFG_LEVEL(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)); +} + +static inline void SET_LOG_CFG_PATH(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); +} + +static inline void SET_LOG_CFG_COMP(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0)); +} + +static inline void SET_LOG_CFG_COMP_EXT(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 2, val, GENMASK(31, 0)); +} + +struct rtw89_h2c_ba_cam { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_BA_CAM_W0_VALID BIT(0) +#define RTW89_H2C_BA_CAM_W0_INIT_REQ BIT(1) +#define RTW89_H2C_BA_CAM_W0_ENTRY_IDX GENMASK(3, 2) +#define RTW89_H2C_BA_CAM_W0_TID GENMASK(7, 4) +#define RTW89_H2C_BA_CAM_W0_MACID GENMASK(15, 8) +#define RTW89_H2C_BA_CAM_W0_BMAP_SIZE GENMASK(19, 16) +#define RTW89_H2C_BA_CAM_W0_SSN GENMASK(31, 20) +#define RTW89_H2C_BA_CAM_W1_UID GENMASK(7, 0) +#define RTW89_H2C_BA_CAM_W1_STD_EN BIT(8) +#define RTW89_H2C_BA_CAM_W1_BAND BIT(9) +#define RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1 GENMASK(31, 28) + +struct rtw89_h2c_ba_cam_v1 { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_BA_CAM_V1_W0_VALID BIT(0) +#define RTW89_H2C_BA_CAM_V1_W0_INIT_REQ BIT(1) +#define RTW89_H2C_BA_CAM_V1_W0_TID_MASK GENMASK(7, 4) +#define RTW89_H2C_BA_CAM_V1_W0_MACID_MASK GENMASK(15, 8) +#define RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK GENMASK(19, 16) +#define RTW89_H2C_BA_CAM_V1_W0_SSN_MASK GENMASK(31, 20) +#define RTW89_H2C_BA_CAM_V1_W1_UID_VALUE_MASK GENMASK(7, 0) +#define RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN BIT(8) +#define RTW89_H2C_BA_CAM_V1_W1_BAND_SEL BIT(9) +#define RTW89_H2C_BA_CAM_V1_W1_MLD_EN BIT(10) +#define RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK GENMASK(31, 24) + +struct rtw89_h2c_ba_cam_init { + __le32 w0; +} __packed; + +#define RTW89_H2C_BA_CAM_INIT_USERS_MASK GENMASK(7, 0) +#define RTW89_H2C_BA_CAM_INIT_OFFSET_MASK GENMASK(19, 12) +#define RTW89_H2C_BA_CAM_INIT_BAND_SEL BIT(24) + +static inline void SET_LPS_PARM_MACID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)); +} + +static inline void SET_LPS_PARM_PSMODE(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); +} + +static inline void SET_LPS_PARM_RLBM(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(19, 16)); +} + +static inline void SET_LPS_PARM_SMARTPS(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 20)); +} + +static inline void SET_LPS_PARM_AWAKEINTERVAL(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); +} + +static inline void SET_LPS_PARM_VOUAPSD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(0)); +} + +static inline void SET_LPS_PARM_VIUAPSD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(1)); +} + +static inline void SET_LPS_PARM_BEUAPSD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(2)); +} + +static inline void SET_LPS_PARM_BKUAPSD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(3)); +} + +static inline void SET_LPS_PARM_LASTRPWM(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)); +} + +struct rtw89_h2c_lps_ch_info { + struct { + u8 pri_ch; + u8 central_ch; + u8 bw; + u8 band; + } __packed info[2]; + + __le32 mlo_dbcc_mode_lps; +} __packed; + +struct rtw89_h2c_lps_ml_cmn_info { + u8 fmt_id; + u8 rfe_type; + u8 rsvd0[2]; + __le32 mlo_dbcc_mode; + u8 central_ch[RTW89_PHY_NUM]; + u8 pri_ch[RTW89_PHY_NUM]; + u8 bw[RTW89_PHY_NUM]; + u8 band[RTW89_PHY_NUM]; + u8 bcn_rate_type[RTW89_PHY_NUM]; + u8 rsvd1[2]; + __le16 tia_gain[RTW89_PHY_NUM][TIA_GAIN_NUM]; + u8 lna_gain[RTW89_PHY_NUM][LNA_GAIN_NUM]; + u8 rsvd2[2]; + u8 tia_lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM + 1]; + u8 lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM]; + u8 dup_bcn_ofst[RTW89_PHY_NUM]; +} __packed; + +#define BB_RX_GAIN_TB_RSSI_COMP_NUM 3 +#define BB_RX_GAIN_CCK_RPL_BIAS_COMP_NUM 2 +#define BB_GT2_GS_IDX_NUM 11 +#define BB_GT2_WB_GIDX_ELNA_NUM 16 +#define BB_GT2_G_ELNA_NUM 2 + +enum rtw89_bb_link_rx_gain_table_type { + RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_A = 0x00, + RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_B = 0x01, + RTW89_BB_PS_LINK_RX_GAIN_TAB_NOR_PATH_A = 0x02, + RTW89_BB_PS_LINK_RX_GAIN_TAB_NOR_PATH_B = 0x03, + RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX, +}; + +#define RTW89_BB_PS_LINK_ID_SKIP 0xfe + +enum rtw89_bb_ps_link_buf_id { + RTW89_BB_PS_LINK_BUF_0 = 0x00, + RTW89_BB_PS_LINK_BUF_1 = 0x01, + RTW89_BB_PS_LINK_BUF_2 = 0x02, + RTW89_BB_PS_LINK_BUF_MAX, +}; + +struct rtw89_bb_link_info_rx_gain { + u8 gain_ofst[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; + __le16 rpl_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; + u8 tb_rssi_m_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX] + [BB_RX_GAIN_TB_RSSI_COMP_NUM]; + u8 cck_gain_ofst[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; + u8 cck_rpl_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX] + [BB_RX_GAIN_CCK_RPL_BIAS_COMP_NUM]; + u8 gain_err_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; + __le16 gain_err_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][TIA_GAIN_NUM]; + u8 op1db_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; + u8 op1db_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][TIA_LNA_OP1DB_NUM]; + struct { + u8 _20M[RTW89_BW20_SC_20M]; + u8 _40M[RTW89_BW20_SC_40M]; + u8 _80M[RTW89_BW20_SC_80M]; + u8 _160M[RTW89_BW20_SC_160M]; + } rpl_bias_comp_bw[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; + u8 wb_gs[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_GS_IDX_NUM]; + u8 bypass_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; + u8 wb_lna_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_WB_GIDX_ELNA_NUM]; + u8 wb_g_elna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_G_ELNA_NUM]; +} __packed; + +struct rtw89_h2c_lps_ml_cmn_info_v1 { + u8 fmt_id; + u8 rfe_type; + u8 rssi_main; + u8 rsvd0; + __le32 mlo_dbcc_mode; + u8 link_id[RTW89_BB_PS_LINK_BUF_MAX]; + u8 central_ch[RTW89_BB_PS_LINK_BUF_MAX]; + u8 pri_ch[RTW89_BB_PS_LINK_BUF_MAX]; + u8 bw[RTW89_BB_PS_LINK_BUF_MAX]; + u8 band[RTW89_BB_PS_LINK_BUF_MAX]; + u8 dup_bcn_ofst[RTW89_BB_PS_LINK_BUF_MAX]; + struct rtw89_bb_link_info_rx_gain rx_gain[RTW89_BB_PS_LINK_BUF_MAX]; +} __packed; + +struct rtw89_h2c_trig_cpu_except { + __le32 w0; +} __packed; + +#define RTW89_H2C_CPU_EXCEPTION_TYPE GENMASK(31, 0) + +static inline void RTW89_SET_FWCMD_PKT_DROP_SEL(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_BAND(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_PORT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MBSSID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 4, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 5, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_KEEP_ALIVE_ENABLE(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_KEEP_ALIVE_PERIOD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(24, 16)); +} + +static inline void RTW89_SET_KEEP_ALIVE_MACID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_ENABLE(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, BIT(0)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_EN(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, BIT(1)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_DISCONNECT(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, BIT(2)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_MAC_ID(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); +} + +static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_LIMIT(void *h2c, u32 val) +{ + le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0)); +} + +struct rtw89_h2c_wow_global { + __le32 w0; + struct rtw89_wow_key_info key_info; +} __packed; + +#define RTW89_H2C_WOW_GLOBAL_W0_ENABLE BIT(0) +#define RTW89_H2C_WOW_GLOBAL_W0_DROP_ALL_PKT BIT(1) +#define RTW89_H2C_WOW_GLOBAL_W0_RX_PARSE_AFTER_WAKE BIT(2) +#define RTW89_H2C_WOW_GLOBAL_W0_WAKE_BAR_PULLED BIT(3) +#define RTW89_H2C_WOW_GLOBAL_W0_MAC_ID GENMASK(15, 8) +#define RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO GENMASK(23, 16) +#define RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO GENMASK(31, 24) + +#define RTW89_MAX_SUPPORT_NL_NUM 16 +struct rtw89_h2c_cfg_nlo { + __le32 w0; + u8 nlo_cnt; + u8 rsvd[3]; + __le32 patterncheck; + __le32 rsvd1; + __le32 rsvd2; + u8 ssid_len[RTW89_MAX_SUPPORT_NL_NUM]; + u8 chiper[RTW89_MAX_SUPPORT_NL_NUM]; + u8 rsvd3[24]; + u8 ssid[RTW89_MAX_SUPPORT_NL_NUM][IEEE80211_MAX_SSID_LEN]; +} __packed; + +#define RTW89_H2C_NLO_W0_ENABLE BIT(0) +#define RTW89_H2C_NLO_W0_IGNORE_CIPHER BIT(2) +#define RTW89_H2C_NLO_W0_MACID GENMASK(31, 24) + +struct rtw89_h2c_wow_wakeup_ctrl { + __le32 w0; +} __packed; + +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_PATTERN_MATCH_ENABLE BIT(0) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_ENABLE BIT(1) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_HW_UNICAST_ENABLE BIT(2) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_FW_UNICAST_ENABLE BIT(3) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_DEAUTH_ENABLE BIT(4) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_REKEYP_ENABLE BIT(5) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_EAP_ENABLE BIT(6) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_ALL_DATA_ENABLE BIT(7) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_MLD_ENABLE BIT(8) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID_EXT GENMASK(23, 16) +#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID GENMASK(31, 24) + +struct rtw89_h2c_wow_cam_update { + __le32 w0; + __le32 wkfm0; + __le32 wkfm1; + __le32 wkfm2; + __le32 wkfm3; + __le32 w5; +} __packed; + +#define RTW89_H2C_WOW_CAM_UPD_W0_R_W BIT(0) +#define RTW89_H2C_WOW_CAM_UPD_W0_IDX GENMASK(7, 1) +#define RTW89_H2C_WOW_CAM_UPD_WKFM0 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM1 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM2 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM3 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_W5_CRC GENMASK(15, 0) +#define RTW89_H2C_WOW_CAM_UPD_W5_NEGATIVE_PATTERN_MATCH BIT(22) +#define RTW89_H2C_WOW_CAM_UPD_W5_SKIP_MAC_HDR BIT(23) +#define RTW89_H2C_WOW_CAM_UPD_W5_UC BIT(24) +#define RTW89_H2C_WOW_CAM_UPD_W5_MC BIT(25) +#define RTW89_H2C_WOW_CAM_UPD_W5_BC BIT(26) +#define RTW89_H2C_WOW_CAM_UPD_W5_VALID BIT(31) + +struct rtw89_h2c_wow_payload_cam_update { + __le32 w0; + __le32 wkfm0; + __le32 wkfm1; + __le32 wkfm2; + __le32 wkfm3; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; +} __packed; + +#define RTW89_H2C_WOW_PLD_CAM_UPD_W0_R_W BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W0_IDX GENMASK(7, 1) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM0 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM1 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM2 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM3 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_UC BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_MC BIT(1) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_BC BIT(2) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_SKIP_MAC_HDR BIT(7) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W6_CRC GENMASK(15, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W7_NEGATIVE_PATTERN_MATCH BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W8_VALID BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W8_WOW_PTR BIT(1) + +struct rtw89_h2c_wow_gtk_ofld { + __le32 w0; + __le32 w1; + struct rtw89_wow_gtk_info gtk_info; +} __packed; + +#define RTW89_H2C_WOW_GTK_OFLD_W0_EN BIT(0) +#define RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN BIT(1) +#define RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN BIT(2) +#define RTW89_H2C_WOW_GTK_OFLD_W0_PAIRWISE_WAKEUP BIT(3) +#define RTW89_H2C_WOW_GTK_OFLD_W0_NOREKEY_WAKEUP BIT(4) +#define RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID GENMASK(23, 16) +#define RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID GENMASK(31, 24) +#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID GENMASK(7, 0) +#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_BIP_SEC_ALGO GENMASK(9, 8) +#define RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT GENMASK(17, 10) + +struct rtw89_h2c_arp_offload { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_ARP_OFFLOAD_W0_ENABLE BIT(0) +#define RTW89_H2C_ARP_OFFLOAD_W0_ACTION BIT(1) +#define RTW89_H2C_ARP_OFFLOAD_W0_MACID GENMASK(23, 16) +#define RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID GENMASK(31, 24) +#define RTW89_H2C_ARP_OFFLOAD_W1_CONTENT GENMASK(31, 0) + +#define BT_H2C_FUNC_BT2ND 0x80 +#define BT_C2H_FUNC_BT2ND 0x80 + +enum rtw89_btc_btf_h2c_class { + BTFC_SET = 0x10, + BTFC_GET = 0x11, + BTFC_FW_EVENT = 0x12, +}; + +enum rtw89_btc_btf_set { + SET_REPORT_EN = 0x0, + SET_SLOT_TABLE, + SET_MREG_TABLE, + SET_CX_POLICY, + SET_GPIO_DBG, + SET_DRV_INFO, + SET_DRV_EVENT, + SET_BT_WREG_ADDR, + SET_BT_WREG_VAL, + SET_BT_RREG_ADDR, + SET_BT_WL_CH_INFO, + SET_BT_INFO_REPORT, + SET_BT_IGNORE_WLAN_ACT, + SET_BT_TX_PWR, + SET_BT_LNA_CONSTRAIN, + SET_BT_QUERY_DEV_LIST, + SET_BT_QUERY_DEV_INFO, + SET_BT_PSD_REPORT, + SET_H2C_TEST, + SET_IOFLD_RF, + SET_IOFLD_BB, + SET_IOFLD_MAC, + SET_IOFLD_SCBD, + SET_H2C_MACRO, + SET_MAX1, +}; + +enum rtw89_btc_cxdrvinfo { + CXDRVINFO_INIT = 0, + CXDRVINFO_ROLE, + CXDRVINFO_DBCC, + CXDRVINFO_SMAP, + CXDRVINFO_RFK, + CXDRVINFO_RUN, + CXDRVINFO_CTRL, + CXDRVINFO_SCAN, + CXDRVINFO_TRX, /* WL traffic to WL fw */ + CXDRVINFO_TXPWR, + CXDRVINFO_FDDT, + CXDRVINFO_MLO, + CXDRVINFO_OSI, + CXDRVINFO_MAX, +}; + +enum rtw89_fbtc_gpio_type { + CXDGPIO_EN_MAP = 0x0, + CXDGPIO_MUX_MAP = 0x1, + CXDGPIO_EXT_HPTA = 0x2, + CXDGPIO_EXT_HMBX = 0x3, + CXDGPIO_EXT_SWOUT = 0x4, + CXDGPIO_EXT_SWIN = 0x5, + CXDGPIO_MAX, +}; + +enum rtw89_scan_mode { + RTW89_SCAN_IMMEDIATE, + RTW89_SCAN_DELAY, +}; + +enum rtw89_scan_type { + RTW89_SCAN_ONCE, + RTW89_SCAN_NORMAL, + RTW89_SCAN_NORMAL_SLOW, + RTW89_SCAN_SEAMLESS, + RTW89_SCAN_MAX, +}; + +static inline void RTW89_SET_FWCMD_CXHDR_TYPE(void *cmd, u8 val) +{ + u8p_replace_bits((u8 *)(cmd) + 0, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXHDR_LEN(void *cmd, u8 val) +{ + u8p_replace_bits((u8 *)(cmd) + 1, val, GENMASK(7, 0)); +} + +struct rtw89_h2c_cxhdr { + u8 type; + u8 len; +} __packed; + +struct rtw89_h2c_cxhdr_v7 { + u8 type; + u8 ver; + u8 len; +} __packed; + +struct rtw89_h2c_cxctrl_v7 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_ctrl_v7 ctrl; +} __packed; + +struct rtw89_h2c_cxctrl_v9 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_ctrl_v9 ctrl; +} __packed; + +#define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr) +#define H2C_LEN_CXDRVHDR_V7 sizeof(struct rtw89_h2c_cxhdr_v7) + +struct rtw89_h2c_cxrole_v7 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_wl_role_info_v7 r; +} __packed; + +struct rtw89_h2c_cxrole_v8 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_wl_role_info_v8 r; +} __packed; + +struct rtw89_h2c_cxrole_v10 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_wl_role_info_v10 r; +} __packed; + +struct rtw89_h2c_cxmlo_v2 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_wl_mlo_info_v2 mlo; +} __packed; + +struct rtw89_h2c_cxosi { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_fbtc_outsrc_set_info_v1 osi; +} __packed; + +struct rtw89_h2c_cxosi_v6 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_fbtc_outsrc_set_info_v6 osi; +} __packed; + +struct rtw89_h2c_cxinit { + struct rtw89_h2c_cxhdr hdr; + u8 ant_type; + u8 ant_num; + u8 ant_iso; + u8 ant_info; + u8 mod_rfe; + u8 mod_cv; + u8 mod_info; + u8 mod_adie_kt; + u8 wl_gch; + u8 info; + u8 rsvd; + u8 rsvd1; +} __packed; + +struct rtw89_btc_trx_info_u8 { + u8 tx_lvl; + u8 rx_lvl; + u8 wl_rssi; + u8 bt_rssi; + + s8 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 0xff-> no BTC control */ + s8 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */ + s8 bt_tx_power[BTC_ALL_BT]; /* decrease Tx power (dB) */ + s8 bt_rx_gain[BTC_ALL_BT]; /* LNA constrain level */ + s8 zb_tx_power[BTC_ALL_BT]; + s8 zb_rx_gain[BTC_ALL_BT]; + + u8 cn; /* condition_num */ + s8 nhm; + u8 bt_profile; + u8 rsvd2; +} __packed; + +struct rtw89_btc_trx_info_v7_u8 { + u8 tx_lvl; + u8 rx_lvl; + u8 wl_rssi; + u8 bt_rssi; + + s8 wl_tx_power; + s8 wl_rx_gain; + s8 bt_tx_power; + s8 bt_rx_gain; + s8 zb_tx_power; + s8 zb_rx_gain; + + u8 cn; + s8 nhm; + u8 bt_profile; + u8 rsvd2; +} __packed; + +struct rtw89_btc_trx_info_v107_u8 { + u8 tx_lvl; + u8 rx_lvl; + u8 wl_rssi; + u8 bt_rssi; + + s8 wl_tx_power; + s8 wl_rx_gain; + s8 bt_tx_power; + s8 bt_rx_gain; + + u8 cn; + s8 nhm; + u8 bt_profile; + u8 rsvd2; +} __packed; + +struct rtw89_btc_trx_info_le { + __le16 tx_rate; + __le16 rx_rate; + + __le32 tx_tp; + __le32 rx_tp; + __le32 rx_err_ratio; +} __packed; + +struct rtw89_h2c_cxtrx_v9 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_trx_info_u8 v9_u8; + struct rtw89_btc_trx_info_le v9_le; +} __packed; + +struct rtw89_h2c_cxtrx_v7 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_trx_info_v7_u8 v7_u8; + struct rtw89_btc_trx_info_le v7_le; +} __packed; + +struct rtw89_h2c_cxtrx_v107 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_trx_info_v107_u8 v107_u8; + struct rtw89_btc_trx_info_le v7_le; +} __packed; + +struct rtw89_h2c_cxtxpwr_v7 { + struct rtw89_h2c_cxhdr_v7 hdr; + u8 pwr; +} __packed; + +struct rtw89_h2c_cxtxpwr_v9 { + struct rtw89_h2c_cxhdr_v7 hdr; + u8 pwr; + u8 band; +} __packed; + +#define RTW89_H2C_CXINIT_ANT_INFO_POS BIT(0) +#define RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY BIT(1) +#define RTW89_H2C_CXINIT_ANT_INFO_BTG_POS GENMASK(3, 2) +#define RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT GENMASK(7, 4) + +#define RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO BIT(0) +#define RTW89_H2C_CXINIT_MOD_INFO_BT_POS BIT(1) +#define RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE BIT(2) +#define RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE GENMASK(5, 3) + +#define RTW89_H2C_CXINIT_INFO_WL_ONLY BIT(0) +#define RTW89_H2C_CXINIT_INFO_WL_INITOK BIT(1) +#define RTW89_H2C_CXINIT_INFO_DBCC_EN BIT(2) +#define RTW89_H2C_CXINIT_INFO_CX_OTHER BIT(3) +#define RTW89_H2C_CXINIT_INFO_BT_ONLY BIT(4) + +struct rtw89_h2c_cxinit_v7 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_init_info_v7 init; +} __packed; + +struct rtw89_h2c_cxinit_v107 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_init_info_v107 init; +} __packed; + +struct rtw89_h2c_cxinit_v10 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_init_info_v10 init; +} __packed; + +struct rtw89_h2c_cxinit_v11 { + struct rtw89_h2c_cxhdr_v7 hdr; + struct rtw89_btc_init_info_v11 init; +} __packed; + +#define RTW89_H2C_CXROLE_V101_ROLE_STAT_CONNTECTED BIT(0) +#define RTW89_H2C_CXROLE_V101_ROLE_STAT_PID GENMASK(3, 1) +#define RTW89_H2C_CXROLE_V101_ROLE_STAT_PHY BIT(4) +#define RTW89_H2C_CXROLE_V101_ROLE_STAT_NOA BIT(5) +#define RTW89_H2C_CXROLE_V101_ROLE_STAT_BADN GENMASK(7, 6) + +#define RTW89_H2C_CXROLE_V101_CLIPS_BW_CLIENTPS BIT(0) +#define RTW89_H2C_CXROLE_V101_CLIPS_BW_BW GENMASK(7, 1) + +#define RTW89_H2C_CXROLE_V101_DBCC_EN BIT(0) +#define RTW89_H2C_CXROLE_V101_DBCC_CHG BIT(1) +#define RTW89_H2C_CXROLE_V101_DBCC_2G_PHY GENMASK(3, 2) +#define RTW89_H2C_CXROLE_V101_DBCC_LINKMODE_CHG BIT(4) +#define RTW89_H2C_CXROLE_V101_DBCC_RSVD GENMASK(31, 5) + +struct rtw89_btc_wl_active_role_v101 { + u8 map_role_status; + u8 map_clips_bw; + u8 role; + u8 ch; + __le32 noa_duration; +} __packed; + +struct rtw89_h2c_cxrole_v101 { + struct rtw89_h2c_cxhdr hdr; + u8 connect_cnt; + u8 link_mode; + __le16 role_map; + struct rtw89_btc_wl_active_role_v101 act_role[RTW89_PORT_NUM]; + __le32 mrole_type; + __le32 mrole_noa_duration; + __le32 map_dbcc_linkmode_chg; +} __packed; + +static inline void RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(void *cmd, u8 val) +{ + u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_LINK_MODE(void *cmd, u8 val) +{ + u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_NONE(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_STA(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_AP(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(2)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_VAP(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(3)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(4)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(5)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_MESH(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(6)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(7)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(8)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(9)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(10)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ROLE_NAN(void *cmd, u16 val) +{ + le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(11)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_PID(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(3, 1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_PHY(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(4)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(5)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_BAND(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(7, 6)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_BW(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, GENMASK(7, 1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_ROLE(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (8 + (12 + offset) * n), val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CH(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (9 + (12 + offset) * n), val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(void *cmd, u16 val, int n, u8 offset) +{ + le16p_replace_bits((__le16 *)((u8 *)cmd + (10 + (12 + offset) * n)), val, GENMASK(15, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(void *cmd, u16 val, int n, u8 offset) +{ + le16p_replace_bits((__le16 *)((u8 *)cmd + (12 + (12 + offset) * n)), val, GENMASK(15, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(void *cmd, u16 val, int n, u8 offset) +{ + le16p_replace_bits((__le16 *)((u8 *)cmd + (14 + (12 + offset) * n)), val, GENMASK(15, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(void *cmd, u16 val, int n, u8 offset) +{ + le16p_replace_bits((__le16 *)((u8 *)cmd + (16 + (12 + offset) * n)), val, GENMASK(15, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(void *cmd, u32 val, int n, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + (20 + (12 + offset) * n)), val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(3, 1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(4)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(5)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(7, 6)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, GENMASK(7, 1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (8 + (12 + offset) * n), val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(void *cmd, u8 val, int n, u8 offset) +{ + u8p_replace_bits((u8 *)cmd + (9 + (12 + offset) * n), val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(void *cmd, u32 val, int n, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + (10 + (12 + offset) * n)), val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset), val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_MROLE_NOA(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 4), val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_DBCC_EN(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_DBCC_CHG(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(1)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, GENMASK(3, 2)); +} + +static inline void RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(void *cmd, u32 val, u8 offset) +{ + le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(4)); +} + +static inline void RTW89_SET_FWCMD_CXCTRL_MANUAL(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(1)); +} + +static inline void RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(2)); +} + +static inline void RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(18, 3)); +} + +static inline void RTW89_SET_FWCMD_CXRFK_STATE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_CXRFK_PATH_MAP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(5, 2)); +} + +static inline void RTW89_SET_FWCMD_CXRFK_PHY_MAP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(7, 6)); +} + +static inline void RTW89_SET_FWCMD_CXRFK_BAND(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(9, 8)); +} + +static inline void RTW89_SET_FWCMD_CXRFK_TYPE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(17, 10)); +} + +static inline void RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(10, 8)); +} + +static inline void RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(31, 16)); +} + +struct rtw89_h2c_chinfo_elem { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; +} __packed; + +#define RTW89_H2C_CHINFO_W0_PERIOD GENMASK(7, 0) +#define RTW89_H2C_CHINFO_W0_DWELL GENMASK(15, 8) +#define RTW89_H2C_CHINFO_W0_CENTER_CH GENMASK(23, 16) +#define RTW89_H2C_CHINFO_W0_PRI_CH GENMASK(31, 24) +#define RTW89_H2C_CHINFO_W1_BW GENMASK(2, 0) +#define RTW89_H2C_CHINFO_W1_ACTION GENMASK(7, 3) +#define RTW89_H2C_CHINFO_W1_NUM_PKT GENMASK(11, 8) +#define RTW89_H2C_CHINFO_W1_TX BIT(12) +#define RTW89_H2C_CHINFO_W1_PAUSE_DATA BIT(13) +#define RTW89_H2C_CHINFO_W1_BAND GENMASK(15, 14) +#define RTW89_H2C_CHINFO_W1_PKT_ID GENMASK(23, 16) +#define RTW89_H2C_CHINFO_W1_DFS BIT(24) +#define RTW89_H2C_CHINFO_W1_TX_NULL BIT(25) +#define RTW89_H2C_CHINFO_W1_RANDOM BIT(26) +#define RTW89_H2C_CHINFO_W1_CFG_TX BIT(27) +#define RTW89_H2C_CHINFO_W1_MACID_TX BIT(29) +#define RTW89_H2C_CHINFO_W2_PKT0 GENMASK(7, 0) +#define RTW89_H2C_CHINFO_W2_PKT1 GENMASK(15, 8) +#define RTW89_H2C_CHINFO_W2_PKT2 GENMASK(23, 16) +#define RTW89_H2C_CHINFO_W2_PKT3 GENMASK(31, 24) +#define RTW89_H2C_CHINFO_W3_PKT4 GENMASK(7, 0) +#define RTW89_H2C_CHINFO_W3_PKT5 GENMASK(15, 8) +#define RTW89_H2C_CHINFO_W3_PKT6 GENMASK(23, 16) +#define RTW89_H2C_CHINFO_W3_PKT7 GENMASK(31, 24) +#define RTW89_H2C_CHINFO_W4_POWER_IDX GENMASK(15, 0) + +struct rtw89_h2c_chinfo_elem_be { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; +} __packed; + +#define RTW89_H2C_CHINFO_BE_W0_PERIOD GENMASK(7, 0) +#define RTW89_H2C_CHINFO_BE_W0_DWELL GENMASK(15, 8) +#define RTW89_H2C_CHINFO_BE_W0_CENTER_CH GENMASK(23, 16) +#define RTW89_H2C_CHINFO_BE_W0_PRI_CH GENMASK(31, 24) +#define RTW89_H2C_CHINFO_BE_W1_BW GENMASK(2, 0) +#define RTW89_H2C_CHINFO_BE_W1_CH_BAND GENMASK(4, 3) +#define RTW89_H2C_CHINFO_BE_W1_DFS BIT(5) +#define RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA BIT(6) +#define RTW89_H2C_CHINFO_BE_W1_TX_NULL BIT(7) +#define RTW89_H2C_CHINFO_BE_W1_RANDOM BIT(8) +#define RTW89_H2C_CHINFO_BE_W1_NOTIFY GENMASK(13, 9) +#define RTW89_H2C_CHINFO_BE_W1_PROBE BIT(14) +#define RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT GENMASK(17, 15) +#define RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER GENMASK(31, 24) +#define RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME GENMASK(7, 0) +#define RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH GENMASK(15, 8) +#define RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL GENMASK(31, 16) +#define RTW89_H2C_CHINFO_BE_W3_PKT0 GENMASK(7, 0) +#define RTW89_H2C_CHINFO_BE_W3_PKT1 GENMASK(15, 8) +#define RTW89_H2C_CHINFO_BE_W3_PKT2 GENMASK(23, 16) +#define RTW89_H2C_CHINFO_BE_W3_PKT3 GENMASK(31, 24) +#define RTW89_H2C_CHINFO_BE_W4_PKT4 GENMASK(7, 0) +#define RTW89_H2C_CHINFO_BE_W4_PKT5 GENMASK(15, 8) +#define RTW89_H2C_CHINFO_BE_W4_PKT6 GENMASK(23, 16) +#define RTW89_H2C_CHINFO_BE_W4_PKT7 GENMASK(31, 24) +#define RTW89_H2C_CHINFO_BE_W5_SW_DEF GENMASK(7, 0) +#define RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS GENMASK(31, 16) +#define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS GENMASK(15, 0) +#define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS GENMASK(31, 16) +#define RTW89_H2C_CHINFO_BE_W7_PERIOD_V1 GENMASK(15, 0) + +struct rtw89_h2c_chinfo { + u8 ch_num; + u8 elem_size; + u8 arg; + u8 rsvd0; + struct rtw89_h2c_chinfo_elem elem[] __counted_by(ch_num); +} __packed; + +struct rtw89_h2c_chinfo_be { + u8 ch_num; + u8 elem_size; + u8 arg; + u8 rsvd0; + struct rtw89_h2c_chinfo_elem_be elem[] __counted_by(ch_num); +} __packed; + +#define RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK BIT(0) +#define RTW89_H2C_CHINFO_ARG_APPEND_MASK BIT(1) + +struct rtw89_h2c_scanofld { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 tsf_high; + __le32 tsf_low; + __le32 w5; + __le32 w6; +} __packed; + +#define RTW89_H2C_SCANOFLD_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_W0_NORM_CY GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_W0_PORT_ID GENMASK(18, 16) +#define RTW89_H2C_SCANOFLD_W0_BAND BIT(19) +#define RTW89_H2C_SCANOFLD_W0_OPERATION GENMASK(21, 20) +#define RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND GENMASK(23, 22) +#define RTW89_H2C_SCANOFLD_W1_NOTIFY_END BIT(0) +#define RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE BIT(1) +#define RTW89_H2C_SCANOFLD_W1_START_MODE BIT(2) +#define RTW89_H2C_SCANOFLD_W1_SCAN_TYPE GENMASK(4, 3) +#define RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW GENMASK(7, 5) +#define RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_W1_PROBE_REQ_PKT_ID GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_W2_NORM_PD GENMASK(15, 0) +#define RTW89_H2C_SCANOFLD_W2_SLOW_PD GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_W3_TSF_HIGH GENMASK(31, 0) +#define RTW89_H2C_SCANOFLD_W4_TSF_LOW GENMASK(31, 0) +#define RTW89_H2C_SCANOFLD_W6_SECOND_MACID GENMASK(31, 24) + +struct rtw89_h2c_scanofld_be_macc_role { + __le32 w0; +} __packed; + +#define RTW89_MAX_OP_NUM_BE 2 +#define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND GENMASK(1, 0) +#define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT GENMASK(4, 2) +#define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID GENMASK(23, 8) +#define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END GENMASK(31, 24) + +struct rtw89_h2c_scanofld_be_opch { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; +} __packed; + +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID GENMASK(15, 0) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND GENMASK(17, 16) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT GENMASK(20, 18) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY GENMASK(22, 21) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL BIT(23) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND GENMASK(9, 8) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW GENMASK(12, 10) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY GENMASK(14, 13) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS GENMASK(18, 16) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN BIT(19) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0 GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1 GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2 GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3 GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1 GENMASK(15, 0) + +struct rtw89_h2c_scanofld_be { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; /* Added after SCAN_OFFLOAD_BE_V1 */ + __le32 w10; /* Added after SCAN_OFFLOAD_BE_V2 */ + __le32 w11; /* Added after SCAN_OFFLOAD_BE_V2 */ + /* struct rtw89_h2c_scanofld_be_macc_role (flexible number) */ + /* struct rtw89_h2c_scanofld_be_opch (flexible number) */ + /* probe SSID list (flexible number); Added after SCAN_OFFLOAD_BE_V3 */ +} __packed; + +#define RTW89_H2C_SCANOFLD_BE_W0_OP GENMASK(1, 0) +#define RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE GENMASK(3, 2) +#define RTW89_H2C_SCANOFLD_BE_W0_REPEAT GENMASK(5, 4) +#define RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END BIT(6) +#define RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH BIT(7) +#define RTW89_H2C_SCANOFLD_BE_W0_MACID GENMASK(23, 8) +#define RTW89_H2C_SCANOFLD_BE_W0_PORT GENMASK(26, 24) +#define RTW89_H2C_SCANOFLD_BE_W0_BAND GENMASK(28, 27) +#define RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE BIT(29) +#define RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_W1_NUM_OP GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_W1_NORM_PD GENMASK(31, 16) +#define RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD GENMASK(15, 0) +#define RTW89_H2C_SCANOFLD_BE_W2_NORM_CY GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_BE_W2_OPCH_END GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_BE_W3_PROBEID GENMASK(31, 24) +#define RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_W4_DELAY_START GENMASK(31, 16) +#define RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE GENMASK(31, 0) +#define RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW GENMASK(31, 0) +#define RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH GENMASK(31, 0) +#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ GENMASK(23, 16) +#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG GENMASK(7, 0) +#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC GENMASK(15, 8) +#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP GENMASK(23, 16) + +struct rtw89_h2c_trx_protect { + __le32 c0; + __le32 c1; + __le32 w0; + __le32 m0; + __le32 w1; + __le32 m1; +} __packed; + +#define RTW89_H2C_TRX_PROTECT_C0_BAND_BITMAP GENMASK(2, 0) +#define RTW89_H2C_TRX_PROTECT_C0_OP_MODE GENMASK(4, 3) +#define RTW89_H2C_TRX_PROTECT_C1_RX_IN BIT(0) +#define RTW89_H2C_TRX_PROTECT_C1_PPDU_STS BIT(4) +#define RTW89_H2C_TRX_PROTECT_C1_MSK_RX_IN BIT(16) +#define RTW89_H2C_TRX_PROTECT_C1_MSK_PPDU_STS BIT(20) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0 BIT(0) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0 BIT(1) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0 BIT(2) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0 BIT(3) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1 BIT(4) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1 BIT(5) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1 BIT(6) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1 BIT(7) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0 BIT(8) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1 BIT(9) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2 BIT(10) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_HI BIT(11) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN BIT(12) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_UL BIT(13) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0 BIT(14) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1 BIT(15) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2 BIT(16) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3 BIT(17) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0 BIT(18) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1 BIT(19) +#define RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN BIT(0) +#define RTW89_H2C_TRX_PROTECT_W1_DFS_EN BIT(1) + +enum rtw89_fw_cmd_ofld_arg_src { + RTW89_FW_CMD_OFLD_SRC_BB, + RTW89_FW_CMD_OFLD_SRC_RF, + RTW89_FW_CMD_OFLD_SRC_MAC, + RTW89_FW_CMD_OFLD_SRC_RF_DDIE, +}; + +enum rtw89_fw_cmd_ofld_arg_type { + RTW89_FW_CMD_OFLD_WRITE, + RTW89_FW_CMD_OFLD_COMPARE, + RTW89_FW_CMD_OFLD_DELAY, + RTW89_FW_CMD_OFLD_MOVE, +}; + +struct rtw89_fw_cmd_ofld_arg { + enum rtw89_fw_cmd_ofld_arg_src src; + enum rtw89_fw_cmd_ofld_arg_type type; + enum rtw89_rf_path rf_path; + u32 value; + u32 mask; + u32 offset; + u16 id; +}; + +struct rtw89_h2c_cmd_ofld { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_H2C_CMD_OFLD_W0_SRC GENMASK(1, 0) +#define RTW89_H2C_CMD_OFLD_W0_TYPE GENMASK(3, 2) +#define RTW89_H2C_CMD_OFLD_W0_LC BIT(4) +#define RTW89_H2C_CMD_OFLD_W0_PATH GENMASK(6, 5) +#define RTW89_H2C_CMD_OFLD_W0_CMD_NUM GENMASK(14, 8) +#define RTW89_H2C_CMD_OFLD_W0_OFFSET GENMASK(31, 16) +#define RTW89_H2C_CMD_OFLD_W1_ID GENMASK(15, 0) +#define RTW89_H2C_CMD_OFLD_W1_BASE_OFFSET GENMASK(31, 16) +#define RTW89_H2C_CMD_OFLD_W2_VALUE GENMASK(31, 0) +#define RTW89_H2C_CMD_OFLD_W3_MASK GENMASK(31, 0) +#define RTW89_W8_MASK_OF_ALIGNED_ADDR(offset) (0xff << (((offset) & 0x3) << 3)) +#define RTW89_W16_MASK_OF_ALIGNED_ADDR(offset) (0xffff << (((offset) & 0x2) * 8)) + +#define RTW89_FW_CMD_OFLD_NR 125 +struct rtw89_fw_cmd_ofld_info { + unsigned int pack_level; + u32 cnt; + u32 accu_delay; + struct rtw89_h2c_cmd_ofld cmds[RTW89_FW_CMD_OFLD_NR]; +}; + +struct rtw89_h2c_fwips { + __le32 w0; +} __packed; + +#define RTW89_H2C_FW_IPS_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_FW_IPS_W0_ENABLE BIT(8) + +struct rtw89_h2c_mlo_link_cfg { + __le32 w0; +}; + +#define RTW89_H2C_MLO_LINK_CFG_W0_MACID GENMASK(15, 0) +#define RTW89_H2C_MLO_LINK_CFG_W0_OPTION GENMASK(19, 16) + +static inline void RTW89_SET_FWCMD_P2P_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_P2P_P2PID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(11, 8)); +} + +static inline void RTW89_SET_FWCMD_P2P_NOAID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 12)); +} + +static inline void RTW89_SET_FWCMD_P2P_ACT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(19, 16)); +} + +static inline void RTW89_SET_FWCMD_P2P_TYPE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(20)); +} + +static inline void RTW89_SET_FWCMD_P2P_ALL_SLEP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(21)); +} + +static inline void RTW89_SET_FWCMD_NOA_START_TIME(void *cmd, __le32 val) +{ + *((__le32 *)cmd + 1) = val; +} + +static inline void RTW89_SET_FWCMD_NOA_INTERVAL(void *cmd, __le32 val) +{ + *((__le32 *)cmd + 2) = val; +} + +static inline void RTW89_SET_FWCMD_NOA_DURATION(void *cmd, __le32 val) +{ + *((__le32 *)cmd + 3) = val; +} + +static inline void RTW89_SET_FWCMD_NOA_COUNT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)(cmd) + 4, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_NOA_CTWINDOW(void *cmd, u32 val) +{ + u8 ctwnd; + + if (!(val & IEEE80211_P2P_OPPPS_ENABLE_BIT)) + return; + ctwnd = FIELD_GET(IEEE80211_P2P_OPPPS_CTWINDOW_MASK, val); + le32p_replace_bits((__le32 *)(cmd) + 4, ctwnd, GENMASK(23, 8)); +} + +static inline void RTW89_SET_FWCMD_TSF32_TOGL_BAND(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_TSF32_TOGL_EN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(1)); +} + +static inline void RTW89_SET_FWCMD_TSF32_TOGL_PORT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(4, 2)); +} + +static inline void RTW89_SET_FWCMD_TSF32_TOGL_EARLY(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 16)); +} + +enum rtw89_fw_mcc_c2h_rpt_cfg { + RTW89_FW_MCC_C2H_RPT_OFF = 0, + RTW89_FW_MCC_C2H_RPT_FAIL_ONLY = 1, + RTW89_FW_MCC_C2H_RPT_ALL = 2, +}; + +struct rtw89_fw_mcc_add_req { + u8 macid; + u8 central_ch_seg0; + u8 central_ch_seg1; + u8 primary_ch; + enum rtw89_bandwidth bandwidth: 4; + u32 group: 2; + u32 c2h_rpt: 2; + u32 dis_tx_null: 1; + u32 dis_sw_retry: 1; + u32 in_curr_ch: 1; + u32 sw_retry_count: 3; + u32 tx_null_early: 4; + u32 btc_in_2g: 1; + u32 pta_en: 1; + u32 rfk_by_pass: 1; + u32 ch_band_type: 2; + u32 rsvd0: 9; + u32 duration; + u8 courtesy_en; + u8 courtesy_num; + u8 courtesy_target; + u8 rsvd1; +}; + +static inline void RTW89_SET_FWCMD_ADD_MCC_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(3, 0)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(5, 4)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(7, 6)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(8)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(9)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(10)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(13, 11)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(17, 14)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(18)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_PTA_EN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(19)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, BIT(20)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(22, 21)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_DURATION(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 3, val, BIT(0)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(23, 16)); +} + +enum rtw89_fw_mcc_old_group_actions { + RTW89_FW_MCC_OLD_GROUP_ACT_NONE = 0, + RTW89_FW_MCC_OLD_GROUP_ACT_REPLACE = 1, +}; + +struct rtw89_fw_mcc_start_req { + u32 group: 2; + u32 btc_in_group: 1; + u32 old_group_action: 2; + u32 old_group: 2; + u32 rsvd0: 9; + u32 notify_cnt: 3; + u32 rsvd1: 2; + u32 notify_rxdbg_en: 1; + u32 rsvd2: 2; + u32 macid: 8; + u32 tsf_low; + u32 tsf_high; +}; + +static inline void RTW89_SET_FWCMD_START_MCC_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(2)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(4, 3)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_OLD_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(6, 5)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(18, 16)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(21)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_TSF_LOW(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_START_MCC_TSF_HIGH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); +} + +static inline void RTW89_SET_FWCMD_STOP_MCC_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); +} + +static inline void RTW89_SET_FWCMD_STOP_MCC_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(9, 8)); +} + +static inline void RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(10)); +} + +static inline void RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(2)); +} + +static inline void RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +struct rtw89_fw_mcc_tsf_req { + u8 group: 2; + u8 rsvd0: 6; + u8 macid_x; + u8 macid_y; + u8 rsvd1; +}; + +static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(void *cmd, + u8 *bitmap, u8 len) +{ + memcpy((__le32 *)cmd + 1, bitmap, len); +} + +static inline void RTW89_SET_FWCMD_MCC_SYNC_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static inline void RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); +} + +struct rtw89_fw_mcc_duration { + u32 group: 2; + u32 btc_in_group: 1; + u32 rsvd0: 5; + u32 start_macid: 8; + u32 macid_x: 8; + u32 macid_y: 8; + u32 start_tsf_low; + u32 start_tsf_high; + u32 duration_x; + u32 duration_y; +}; + +static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, BIT(2)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); +} + +static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); +} + +static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(31, 0)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(31, 0)); +} + +static +inline void RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd + 4, val, GENMASK(31, 0)); +} + +enum rtw89_h2c_mrc_sch_types { + RTW89_H2C_MRC_SCH_BAND0_ONLY = 0, + RTW89_H2C_MRC_SCH_BAND1_ONLY = 1, + RTW89_H2C_MRC_SCH_DUAL_BAND = 2, +}; + +enum rtw89_h2c_mrc_role_types { + RTW89_H2C_MRC_ROLE_WIFI = 0, + RTW89_H2C_MRC_ROLE_BT = 1, + RTW89_H2C_MRC_ROLE_EMPTY = 2, +}; + +#define RTW89_MAC_MRC_MAX_ADD_SLOT_NUM 3 +#define RTW89_MAC_MRC_MAX_ADD_ROLE_NUM_PER_SLOT 1 /* before MLO */ + +struct rtw89_fw_mrc_add_slot_arg { + u16 duration; /* unit: TU */ + bool courtesy_en; + u8 courtesy_period; + u8 courtesy_target; /* slot idx */ + + unsigned int role_num; + struct { + enum rtw89_h2c_mrc_role_types role_type; + bool is_master; + bool en_tx_null; + enum rtw89_band band; + enum rtw89_bandwidth bw; + u8 macid; + u8 central_ch; + u8 primary_ch; + u8 null_early; /* unit: TU */ + + /* if MLD, for macid: [0, chip::support_mld_num) + * otherwise, for macid: [0, 32) + */ + u32 macid_main_bitmap; + /* for MLD, bit X maps to macid: X + chip::support_mld_num */ + u32 macid_paired_bitmap; + } roles[RTW89_MAC_MRC_MAX_ADD_ROLE_NUM_PER_SLOT]; +}; + +struct rtw89_fw_mrc_add_arg { + u8 sch_idx; + enum rtw89_h2c_mrc_sch_types sch_type; + bool btc_in_sch; + + unsigned int slot_num; + struct rtw89_fw_mrc_add_slot_arg slots[RTW89_MAC_MRC_MAX_ADD_SLOT_NUM]; +}; + +struct rtw89_h2c_mrc_add_role { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 macid_main_bitmap; + __le32 macid_paired_bitmap; +} __packed; + +#define RTW89_H2C_MRC_ADD_ROLE_W0_MACID GENMASK(15, 0) +#define RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE GENMASK(23, 16) +#define RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER BIT(24) +#define RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE BIT(25) +#define RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN BIT(26) +#define RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN BIT(27) +#define RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG GENMASK(7, 0) +#define RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH GENMASK(15, 8) +#define RTW89_H2C_MRC_ADD_ROLE_W1_BW GENMASK(19, 16) +#define RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE GENMASK(21, 20) +#define RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS BIT(22) +#define RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC BIT(23) +#define RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY GENMASK(31, 24) +#define RTW89_H2C_MRC_ADD_ROLE_W2_ALT_PERIOD GENMASK(7, 0) +#define RTW89_H2C_MRC_ADD_ROLE_W2_ALT_ROLE_TYPE GENMASK(15, 8) +#define RTW89_H2C_MRC_ADD_ROLE_W2_ALT_ROLE_MACID GENMASK(23, 16) + +struct rtw89_h2c_mrc_add_slot { + __le32 w0; + __le32 w1; + struct rtw89_h2c_mrc_add_role roles[]; +} __packed; + +#define RTW89_H2C_MRC_ADD_SLOT_W0_DURATION GENMASK(15, 0) +#define RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN BIT(17) +#define RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM GENMASK(31, 24) +#define RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD GENMASK(7, 0) +#define RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET GENMASK(15, 8) + +struct rtw89_h2c_mrc_add { + __le32 w0; + /* Logically append flexible struct rtw89_h2c_mrc_add_slot, but there + * are other flexible array inside it. We cannot access them correctly + * through this struct. So, in case misusing, we don't really declare + * it here. + */ +} __packed; + +#define RTW89_H2C_MRC_ADD_W0_SCH_IDX GENMASK(3, 0) +#define RTW89_H2C_MRC_ADD_W0_SCH_TYPE GENMASK(7, 4) +#define RTW89_H2C_MRC_ADD_W0_SLOT_NUM GENMASK(15, 8) +#define RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH BIT(16) + +enum rtw89_h2c_mrc_start_actions { + RTW89_H2C_MRC_START_ACTION_START_NEW = 0, + RTW89_H2C_MRC_START_ACTION_REPLACE_OLD = 1, +}; + +struct rtw89_fw_mrc_start_arg { + u8 sch_idx; + u8 old_sch_idx; + u64 start_tsf; + enum rtw89_h2c_mrc_start_actions action; +}; + +struct rtw89_h2c_mrc_start { + __le32 w0; + __le32 start_tsf_low; + __le32 start_tsf_high; +} __packed; + +#define RTW89_H2C_MRC_START_W0_SCH_IDX GENMASK(3, 0) +#define RTW89_H2C_MRC_START_W0_OLD_SCH_IDX GENMASK(7, 4) +#define RTW89_H2C_MRC_START_W0_ACTION GENMASK(15, 8) + +struct rtw89_h2c_mrc_del { + __le32 w0; +} __packed; + +#define RTW89_H2C_MRC_DEL_W0_SCH_IDX GENMASK(3, 0) +#define RTW89_H2C_MRC_DEL_W0_DEL_ALL BIT(4) +#define RTW89_H2C_MRC_DEL_W0_STOP_ONLY BIT(5) +#define RTW89_H2C_MRC_DEL_W0_SPECIFIC_ROLE_EN BIT(6) +#define RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX GENMASK(15, 8) +#define RTW89_H2C_MRC_DEL_W0_SPECIFIC_ROLE_MACID GENMASK(31, 16) + +#define RTW89_MAC_MRC_MAX_REQ_TSF_NUM 2 + +struct rtw89_fw_mrc_req_tsf_arg { + unsigned int num; + struct { + u8 band; + u8 port; + } infos[RTW89_MAC_MRC_MAX_REQ_TSF_NUM]; +}; + +struct rtw89_h2c_mrc_req_tsf { + u8 req_tsf_num; + u8 infos[] __counted_by(req_tsf_num); +} __packed; + +#define RTW89_H2C_MRC_REQ_TSF_INFO_BAND GENMASK(3, 0) +#define RTW89_H2C_MRC_REQ_TSF_INFO_PORT GENMASK(7, 4) + +enum rtw89_h2c_mrc_upd_bitmap_actions { + RTW89_H2C_MRC_UPD_BITMAP_ACTION_DEL = 0, + RTW89_H2C_MRC_UPD_BITMAP_ACTION_ADD = 1, +}; + +struct rtw89_fw_mrc_upd_bitmap_arg { + u8 sch_idx; + u8 macid; + u8 client_macid; + enum rtw89_h2c_mrc_upd_bitmap_actions action; +}; + +struct rtw89_h2c_mrc_upd_bitmap { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX GENMASK(3, 0) +#define RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION BIT(4) +#define RTW89_H2C_MRC_UPD_BITMAP_W0_MACID GENMASK(31, 16) +#define RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID GENMASK(15, 0) + +struct rtw89_fw_mrc_sync_arg { + u8 offset; /* unit: TU */ + struct { + u8 band; + u8 port; + } src, dest; +}; + +struct rtw89_h2c_mrc_sync { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_MRC_SYNC_W0_SYNC_EN BIT(0) +#define RTW89_H2C_MRC_SYNC_W0_SRC_PORT GENMASK(11, 8) +#define RTW89_H2C_MRC_SYNC_W0_SRC_BAND GENMASK(15, 12) +#define RTW89_H2C_MRC_SYNC_W0_DEST_PORT GENMASK(19, 16) +#define RTW89_H2C_MRC_SYNC_W0_DEST_BAND GENMASK(23, 20) +#define RTW89_H2C_MRC_SYNC_W1_OFFSET GENMASK(15, 0) + +struct rtw89_fw_mrc_upd_duration_arg { + u8 sch_idx; + u64 start_tsf; + + unsigned int slot_num; + struct { + u8 slot_idx; + u16 duration; /* unit: TU */ + } slots[RTW89_MAC_MRC_MAX_ADD_SLOT_NUM]; +}; + +struct rtw89_h2c_mrc_upd_duration { + __le32 w0; + __le32 start_tsf_low; + __le32 start_tsf_high; + __le32 slots[]; +} __packed; + +#define RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX GENMASK(3, 0) +#define RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM GENMASK(15, 8) +#define RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH BIT(16) +#define RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX GENMASK(7, 0) +#define RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION GENMASK(31, 16) + +struct rtw89_h2c_wow_aoac { + __le32 w0; +} __packed; + +struct rtw89_h2c_ap_info { + __le32 w0; +} __packed; + +#define RTW89_H2C_AP_INFO_W0_PWR_INT_EN BIT(0) + +#define RTW89_C2H_HEADER_LEN 8 + +struct rtw89_c2h_hdr { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_C2H_HDR_W0_CATEGORY GENMASK(1, 0) +#define RTW89_C2H_HDR_W0_CLASS GENMASK(7, 2) +#define RTW89_C2H_HDR_W0_FUNC GENMASK(15, 8) +#define RTW89_C2H_HDR_W1_LEN GENMASK(13, 0) + +struct rtw89_fw_c2h_attr { + u8 category; + u8 class; + u8 func; + u16 len; + u8 is_scan_event: 1; + u8 scan_seq: 2; +}; + +static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) +{ + static_assert(sizeof(skb->cb) >= sizeof(struct rtw89_fw_c2h_attr)); + + return (struct rtw89_fw_c2h_attr *)skb->cb; +} + +struct rtw89_c2h_done_ack { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_DONE_ACK_W2_CAT GENMASK(1, 0) +#define RTW89_C2H_DONE_ACK_W2_CLASS GENMASK(7, 2) +#define RTW89_C2H_DONE_ACK_W2_FUNC GENMASK(15, 8) +#define RTW89_C2H_DONE_ACK_W2_H2C_RETURN GENMASK(23, 16) +#define RTW89_C2H_SCAN_DONE_ACK_RETURN GENMASK(5, 0) +#define RTW89_C2H_DONE_ACK_W2_H2C_SEQ GENMASK(31, 24) + +struct rtw89_c2h_rev_ack { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_REV_ACK_W2_CAT GENMASK(1, 0) +#define RTW89_C2H_REV_ACK_W2_CLASS GENMASK(7, 2) +#define RTW89_C2H_REV_ACK_W2_FUNC GENMASK(15, 8) +#define RTW89_C2H_REV_ACK_W2_H2C_SEQ GENMASK(23, 16) + +struct rtw89_fw_c2h_log_fmt { + __le16 signature; + u8 feature; + u8 syntax; + __le32 fmt_id; + u8 file_num; + __le16 line_num; + u8 argc; + union { + DECLARE_FLEX_ARRAY(u8, raw); + DECLARE_FLEX_ARRAY(__le32, argv); + } __packed u; +} __packed; + +#define RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN 11 +#define RTW89_C2H_FW_LOG_FEATURE_PARA_INT BIT(2) +#define RTW89_C2H_FW_LOG_MAX_PARA_NUM 16 +#define RTW89_C2H_FW_LOG_SIGNATURE 0xA5A5 +#define RTW89_C2H_FW_LOG_STR_BUF_SIZE 512 + +struct rtw89_c2h_bcn_upd_done { + struct rtw89_c2h_hdr hdr; + __le32 w2; +} __packed; + +#define RTW89_C2H_BCN_UPD_DONE_W2_PORT GENMASK(2, 0) +#define RTW89_C2H_BCN_UPD_DONE_W2_MBSSID GENMASK(6, 3) +#define RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX BIT(7) + +struct rtw89_c2h_mac_bcnfltr_rpt { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID GENMASK(7, 0) +#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE GENMASK(9, 8) +#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT GENMASK(11, 10) +#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA GENMASK(23, 16) + +struct rtw89_c2h_ra_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_C2H_RA_RPT_W2_MACID GENMASK(15, 0) +#define RTW89_C2H_RA_RPT_W2_RETRY_RATIO GENMASK(23, 16) +#define RTW89_C2H_RA_RPT_W2_MCSNSS_B7 BIT(31) +#define RTW89_C2H_RA_RPT_W3_MCSNSS GENMASK(6, 0) +#define RTW89_C2H_RA_RPT_W3_MD_SEL GENMASK(9, 8) +#define RTW89_C2H_RA_RPT_W3_GILTF GENMASK(12, 10) +#define RTW89_C2H_RA_RPT_W3_BW GENMASK(14, 13) +#define RTW89_C2H_RA_RPT_W3_MD_SEL_B2 BIT(15) +#define RTW89_C2H_RA_RPT_W3_BW_B2 BIT(16) + +struct rtw89_c2h_lps_rpt { + struct rtw89_c2h_hdr hdr; + u8 type; + u8 cnt_bbcr; + u8 cnt_bbmcucr; + u8 cnt_rfcr; + u8 data[]; + /* + * The layout of data: + * u8 info[][4], size = total_len - size of below fields + * __le16 bbcr_addr[], size = cnt_bbcr + * __le32 bbcr_data[], size = cnt_bbcr + * __le16 bbmcucr_addr[], size = cnt_bbmcucr + * __le32 bbmcucr_data[], size = cnt_bbmcucr + * __le16 rfcr_addr[], size = cnt_rfcr + * __le32 rfcr_data_a[], size = cnt_rfcr + * __le32 rfcr_data_b[], size = cnt_rfcr + */ +} __packed; + +struct rtw89_c2h_ra_tx_history { + struct rtw89_c2h_hdr hdr; + __le32 ra_tbtt_cnt; + __le32 tx_rate_tot_cnt_hist[RTW89_TX_RATE_NR]; + __le32 tx_cat_cnt[3]; +} __packed; + +struct rtw89_c2h_fw_scan_rpt { + struct rtw89_c2h_hdr hdr; + u8 phy_idx; + u8 band; + u8 center_ch; + u8 ofdm_pd_idx; /* in unit of 2 dBm */ +#define PD_LOWER_BOUND_BASE 102 + s8 cck_pd_idx; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; +} __packed; + +/* For WiFi 6 chips: + * VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS + * HT-new: [6:5]: NA, [4:0]: MCS + * For WiFi 7 chips (V1): + * HT, VHT, HE, EHT: [7:5]: NSS, [4:0]: MCS + */ +#define RTW89_RA_RATE_MASK_NSS GENMASK(6, 4) +#define RTW89_RA_RATE_MASK_MCS GENMASK(3, 0) +#define RTW89_RA_RATE_MASK_NSS_V1 GENMASK(7, 5) +#define RTW89_RA_RATE_MASK_MCS_V1 GENMASK(4, 0) +#define RTW89_RA_RATE_MASK_HT_MCS GENMASK(4, 0) +#define RTW89_MK_HT_RATE(nss, mcs) (FIELD_PREP(GENMASK(4, 3), nss) | \ + FIELD_PREP(GENMASK(2, 0), mcs)) + +#define RTW89_GET_MAC_C2H_PKTOFLD_ID(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 0)) +#define RTW89_GET_MAC_C2H_PKTOFLD_OP(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(10, 8)) +#define RTW89_GET_MAC_C2H_PKTOFLD_LEN(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 16)) + +struct rtw89_c2h_scanofld { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; +} __packed; + +#define RTW89_C2H_SCANOFLD_W2_PRI_CH GENMASK(7, 0) +#define RTW89_C2H_SCANOFLD_W2_RSN GENMASK(19, 16) +#define RTW89_C2H_SCANOFLD_W2_STATUS GENMASK(23, 20) +#define RTW89_C2H_SCANOFLD_W2_PERIOD GENMASK(31, 24) +#define RTW89_C2H_SCANOFLD_W5_TX_FAIL GENMASK(3, 0) +#define RTW89_C2H_SCANOFLD_W5_AIR_DENSITY GENMASK(7, 4) +#define RTW89_C2H_SCANOFLD_W5_BAND GENMASK(25, 24) +#define RTW89_C2H_SCANOFLD_W5_MAC_IDX BIT(26) +#define RTW89_C2H_SCANOFLD_W6_SW_DEF GENMASK(7, 0) +#define RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD GENMASK(15, 8) +#define RTW89_C2H_SCANOFLD_W6_FW_DEF GENMASK(23, 16) +#define RTW89_C2H_SCANOFLD_W7_REPORT_TSF GENMASK(31, 0) +#define RTW89_C2H_SCANOFLD_W8_PERIOD_V1 GENMASK(15, 0) +#define RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1 GENMASK(31, 16) + +#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) +#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) + +#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) +#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) +#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) + +struct rtw89_c2h_mac_tx_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; +} __packed; + +#define RTW89_C2H_MAC_TX_RPT_W2_TX_STATE GENMASK(7, 6) +#define RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE GENMASK(11, 8) +#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT GENMASK(13, 8) +#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1 GENMASK(15, 10) + +struct rtw89_c2h_mac_tx_rpt_v2 { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 w16; + __le32 w17; + __le32 w18; + __le32 w19; +} __packed; + +#define RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2 GENMASK(9, 8) +#define RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2 GENMASK(15, 12) +#define RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2 GENMASK(15, 10) + +struct rtw89_mac_mcc_tsf_rpt { + u32 macid_x; + u32 macid_y; + u32 tsf_x_low; + u32 tsf_x_high; + u32 tsf_y_low; + u32 tsf_y_high; +}; + +static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE); + +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 0)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(17, 16)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(31, 0)) +#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 6), GENMASK(31, 0)) + +#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(5, 0)) +#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 6)) +#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) +#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) +#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) + +struct rtw89_c2h_mlo_link_cfg_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; +} __packed; + +#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID GENMASK(15, 0) +#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS GENMASK(19, 16) + +enum rtw89_c2h_mlo_link_status { + RTW89_C2H_MLO_LINK_CFG_IDLE = 0, + RTW89_C2H_MLO_LINK_CFG_DONE = 1, + RTW89_C2H_MLO_LINK_CFG_ISSUE_NULL_FAIL = 2, + RTW89_C2H_MLO_LINK_CFG_TX_NULL_FAIL = 3, + RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST = 4, + RTW89_C2H_MLO_LINK_CFG_NULL_1_TIMEOUT = 5, + RTW89_C2H_MLO_LINK_CFG_NULL_0_TIMEOUT = 6, + RTW89_C2H_MLO_LINK_CFG_RUNNING = 0xff, +}; + +struct rtw89_mac_mrc_tsf_rpt { + unsigned int num; + u64 tsfs[RTW89_MAC_MRC_MAX_REQ_TSF_NUM]; +}; + +static_assert(sizeof(struct rtw89_mac_mrc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE); + +struct rtw89_c2h_mrc_tsf_rpt_info { + __le32 tsf_low; + __le32 tsf_high; +} __packed; + +struct rtw89_c2h_mrc_tsf_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; + struct rtw89_c2h_mrc_tsf_rpt_info infos[]; +} __packed; + +#define RTW89_C2H_MRC_TSF_RPT_W2_REQ_TSF_NUM GENMASK(7, 0) + +struct rtw89_c2h_mrc_status_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 tsf_low; + __le32 tsf_high; +} __packed; + +#define RTW89_C2H_MRC_STATUS_RPT_W2_STATUS GENMASK(5, 0) +#define RTW89_C2H_MRC_STATUS_RPT_W2_SCH_IDX GENMASK(7, 6) + +struct rtw89_c2h_pkt_ofld_rsp { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID GENMASK(7, 0) +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8) +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16) + +struct rtw89_c2h_tx_duty_rpt { + struct rtw89_c2h_hdr c2h_hdr; + __le32 w2; +} __packed; + +#define RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR GENMASK(2, 0) + +struct rtw89_c2h_wow_aoac_report { + struct rtw89_c2h_hdr c2h_hdr; + u8 rpt_ver; + u8 sec_type; + u8 key_idx; + u8 pattern_idx; + u8 rekey_ok; + u8 rsvd1[3]; + u8 ptk_tx_iv[8]; + u8 eapol_key_replay_count[8]; + u8 gtk[32]; + u8 ptk_rx_iv[8]; + u8 gtk_rx_iv[4][8]; + __le64 igtk_key_id; + __le64 igtk_ipn; + u8 igtk[32]; + u8 csa_pri_ch; + u8 csa_bw_ch_offset; + u8 csa_ch_band_chsw_failed; + u8 csa_rsvd1; +} __packed; + +#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0) + +struct rtw89_c2h_pwr_int_notify { + struct rtw89_c2h_hdr hdr; + __le32 w2; +} __packed; + +#define RTW89_C2H_PWR_INT_NOTIFY_W2_MACID GENMASK(15, 0) +#define RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS BIT(16) + +struct rtw89_h2c_tx_duty { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK GENMASK(15, 0) +#define RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK GENMASK(31, 16) +#define RTW89_H2C_TX_DUTY_W1_STOP BIT(0) + +struct rtw89_h2c_bcnfltr { + __le32 w0; +} __packed; + +#define RTW89_H2C_BCNFLTR_W0_MON_RSSI BIT(0) +#define RTW89_H2C_BCNFLTR_W0_MON_BCN BIT(1) +#define RTW89_H2C_BCNFLTR_W0_MON_EN BIT(2) +#define RTW89_H2C_BCNFLTR_W0_MODE GENMASK(4, 3) +#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3 GENMASK(7, 5) +#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4 GENMASK(11, 8) +#define RTW89_H2C_BCNFLTR_W0_RSSI_HYST GENMASK(15, 12) +#define RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD GENMASK(23, 16) +#define RTW89_H2C_BCNFLTR_W0_MAC_ID GENMASK(31, 24) + +struct rtw89_h2c_ofld_rssi { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_H2C_OFLD_RSSI_W0_MACID GENMASK(7, 0) +#define RTW89_H2C_OFLD_RSSI_W0_NUM GENMASK(15, 8) +#define RTW89_H2C_OFLD_RSSI_W1_VAL GENMASK(7, 0) + +struct rtw89_h2c_ofld { + __le32 w0; +} __packed; + +#define RTW89_H2C_OFLD_W0_MAC_ID GENMASK(7, 0) +#define RTW89_H2C_OFLD_W0_TX_TP GENMASK(17, 8) +#define RTW89_H2C_OFLD_W0_RX_TP GENMASK(27, 18) + +#define RTW89_MFW_SIG 0xFF + +struct rtw89_mfw_info { + u8 cv; + u8 type; /* enum rtw89_fw_type */ + u8 mp; + u8 rsvd; + __le32 shift; + __le32 size; + u8 rsvd2[4]; +} __packed; + +struct rtw89_mfw_hdr { + u8 sig; /* RTW89_MFW_SIG */ + u8 fw_nr; + u8 rsvd0[2]; + struct { + u8 major; + u8 minor; + u8 sub; + u8 idx; + } ver; + u8 rsvd1[8]; + struct rtw89_mfw_info info[]; +} __packed; + +struct rtw89_fw_logsuit_hdr { + __le32 rsvd; + __le32 count; + __le32 ids[]; +} __packed; + +#define RTW89_FW_ELEMENT_ALIGN 16 + +enum rtw89_fw_element_id { + RTW89_FW_ELEMENT_ID_BBMCU0 = 0, + RTW89_FW_ELEMENT_ID_BBMCU1 = 1, + RTW89_FW_ELEMENT_ID_BB_REG = 2, + RTW89_FW_ELEMENT_ID_BB_GAIN = 3, + RTW89_FW_ELEMENT_ID_RADIO_A = 4, + RTW89_FW_ELEMENT_ID_RADIO_B = 5, + RTW89_FW_ELEMENT_ID_RADIO_C = 6, + RTW89_FW_ELEMENT_ID_RADIO_D = 7, + RTW89_FW_ELEMENT_ID_RF_NCTL = 8, + RTW89_FW_ELEMENT_ID_TXPWR_BYRATE = 9, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ = 10, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ = 11, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ = 12, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ = 13, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ = 14, + RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ = 15, + RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT = 16, + RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17, + RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18, + RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19, + RTW89_FW_ELEMENT_ID_REGD = 20, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ = 21, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ = 22, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ = 23, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ = 24, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ = 25, + RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ = 26, + RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ = 27, + RTW89_FW_ELEMENT_ID_DIAG_MAC = 28, + RTW89_FW_ELEMENT_ID_TX_COMP = 29, + + __RTW89_FW_ELEMENT_ID_INTL_TRANSITION, + RTW89_FW_ELEMENT_ID_NUM, +}; + +#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS_TX_SHAPE \ + (BIT(RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT) | \ + BIT(RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU)) + +#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ \ + (BIT(RTW89_FW_ELEMENT_ID_TXPWR_BYRATE) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ) | \ + BITS_OF_RTW89_TXPWR_FW_ELEMENTS_TX_SHAPE) + +#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS \ + (BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ)) + +#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_BASE \ + (BIT(RTW89_FW_ELEMENT_ID_BB_REG) | \ + BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \ + BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \ + BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK)) + +#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ \ + (RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_BASE | \ + BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ) + +#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS \ + (RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_BASE | \ + BITS_OF_RTW89_TXPWR_FW_ELEMENTS) + +#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_RTL8852A \ + (RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ & \ + ~BITS_OF_RTW89_TXPWR_FW_ELEMENTS_TX_SHAPE) + +#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_RTL8851B \ + (RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ & \ + ~BIT(RTW89_FW_ELEMENT_ID_RADIO_B)) + +#define RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_BASE \ + (BIT(RTW89_FW_ELEMENT_ID_BB_REG) | \ + BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \ + BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \ + BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \ + BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK) | \ + BITS_OF_RTW89_TXPWR_FW_ELEMENTS) + +#define RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS \ + (RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_BASE | \ + BIT(RTW89_FW_ELEMENT_ID_BBMCU0)) + +#define RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_V1 \ + (RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_BASE | \ + BIT(RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ) | \ + BIT(RTW89_FW_ELEMENT_ID_TX_COMP)) + +struct __rtw89_fw_txpwr_element { + u8 rsvd0; + u8 rsvd1; + u8 rfe_type; + u8 ent_sz; + __le32 num_ents; + u8 content[]; +} __packed; + +struct __rtw89_fw_regd_element { + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + u8 ent_sz; + __le32 num_ents; + u8 content[]; +} __packed; + +enum rtw89_fw_txpwr_trk_type { + __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0, + RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0, + RTW89_FW_TXPWR_TRK_TYPE_6GB_P = 1, + RTW89_FW_TXPWR_TRK_TYPE_6GA_N = 2, + RTW89_FW_TXPWR_TRK_TYPE_6GA_P = 3, + __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX = 3, + + __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START = 4, + RTW89_FW_TXPWR_TRK_TYPE_5GB_N = 4, + RTW89_FW_TXPWR_TRK_TYPE_5GB_P = 5, + RTW89_FW_TXPWR_TRK_TYPE_5GA_N = 6, + RTW89_FW_TXPWR_TRK_TYPE_5GA_P = 7, + __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX = 7, + + __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START = 8, + RTW89_FW_TXPWR_TRK_TYPE_2GB_N = 8, + RTW89_FW_TXPWR_TRK_TYPE_2GB_P = 9, + RTW89_FW_TXPWR_TRK_TYPE_2GA_N = 10, + RTW89_FW_TXPWR_TRK_TYPE_2GA_P = 11, + RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N = 12, + RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P = 13, + RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N = 14, + RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P = 15, + __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX = 15, + + RTW89_FW_TXPWR_TRK_TYPE_NR, +}; + +struct rtw89_fw_txpwr_track_cfg { + const s8 (*delta[RTW89_FW_TXPWR_TRK_TYPE_NR])[DELTA_SWINGIDX_SIZE]; +}; + +#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ \ + (BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_P) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_P)) +#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ \ + (BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_P) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_P)) +#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ \ + (BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_P) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_P) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N) | \ + BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P)) + +enum rtw89_fw_afe_action { + RTW89_FW_AFE_ACTION_WRITE = 0, + RTW89_FW_AFE_ACTION_DELAY = 1, + RTW89_FW_AFE_ACTION_POLL = 2, +}; + +enum rtw89_fw_afe_cat { + RTW89_FW_AFE_CAT_BB = 0, + RTW89_FW_AFE_CAT_BB1 = 1, + RTW89_FW_AFE_CAT_MAC = 2, + RTW89_FW_AFE_CAT_MAC1 = 3, + RTW89_FW_AFE_CAT_AFEDIG = 4, + RTW89_FW_AFE_CAT_AFEDIG1 = 5, +}; + +enum rtw89_fw_afe_class { + RTW89_FW_AFE_CLASS_P0 = 0, + RTW89_FW_AFE_CLASS_P1 = 1, + RTW89_FW_AFE_CLASS_P2 = 2, + RTW89_FW_AFE_CLASS_P3 = 3, + RTW89_FW_AFE_CLASS_P4 = 4, + RTW89_FW_AFE_CLASS_CMN = 5, +}; + +struct rtw89_fw_element_hdr { + __le32 id; /* enum rtw89_fw_element_id */ + __le32 size; /* exclude header size */ + u8 ver[4]; + __le16 aid; /* should match rtw89_hal::aid */ + __le16 rsvd0; + __le32 rsvd1; + __le32 rsvd2; + union { + struct { + u8 priv[8]; + u8 contents[]; + } __packed common; + struct { + u8 idx; + u8 rsvd[7]; + struct { + __le32 addr; + __le32 data; + } __packed regs[]; + } __packed reg2; + struct { + u8 cv; + u8 priv[7]; + u8 contents[]; + } __packed bbmcu; + struct { + __le32 bitmap; /* bitmap of enum rtw89_fw_txpwr_trk_type */ + __le32 rsvd; + s8 contents[][DELTA_SWINGIDX_SIZE]; + } __packed txpwr_trk; + struct { + u8 nr; + u8 rsvd[3]; + u8 rfk_id; /* enum rtw89_phy_c2h_rfk_log_func */ + u8 rsvd1[3]; + __le16 offset[]; + } __packed rfk_log_fmt; + struct { + u8 rsvd[8]; + struct rtw89_phy_afe_info { + __le32 action; /* enum rtw89_fw_afe_action */ + __le32 cat; /* enum rtw89_fw_afe_cat */ + __le32 class; /* enum rtw89_fw_afe_class */ + __le32 addr; + __le32 mask; + __le32 val; + } __packed infos[]; + } __packed afe; + struct { + __le32 rule_size; + u8 rsvd[4]; + u8 rules_and_msgs[]; + } __packed diag_mac; + struct { + u8 rfe_type; + u8 priv[7]; + u8 contents[]; + } __packed tx_comp; + struct __rtw89_fw_txpwr_element txpwr; + struct __rtw89_fw_regd_element regd; + } __packed u; +} __packed; + +struct fwcmd_hdr { + __le32 hdr0; + __le32 hdr1; +}; + +union rtw89_compat_fw_hdr { + struct rtw89_mfw_hdr mfw_hdr; + struct rtw89_fw_hdr fw_hdr; +}; + +static inline u32 rtw89_compat_fw_hdr_ver_code(const void *fw_buf) +{ + const union rtw89_compat_fw_hdr *compat = (typeof(compat))fw_buf; + + if (compat->mfw_hdr.sig == RTW89_MFW_SIG) + return RTW89_MFW_HDR_VER_CODE(&compat->mfw_hdr); + else + return RTW89_FW_HDR_VER_CODE(&compat->fw_hdr); +} + +static inline void rtw89_fw_get_filename(char *buf, size_t size, + const char *fw_basename, int fw_format) +{ + if (fw_format <= 0) + snprintf(buf, size, "%s.bin", fw_basename); + else + snprintf(buf, size, "%s-%d.bin", fw_basename, fw_format); +} + +#define RTW89_H2C_RF_PAGE_SIZE 500 +#define RTW89_H2C_RF_PAGE_NUM 3 +struct rtw89_fw_h2c_rf_reg_info { + enum rtw89_rf_path rf_path; + __le32 rtw89_phy_config_rf_h2c[RTW89_H2C_RF_PAGE_NUM][RTW89_H2C_RF_PAGE_SIZE]; + u16 curr_idx; +}; + +#define H2C_SEC_CAM_LEN 24 + +#define H2C_HEADER_LEN 8 +#define H2C_HDR_CAT GENMASK(1, 0) +#define H2C_HDR_CLASS GENMASK(7, 2) +#define H2C_HDR_FUNC GENMASK(15, 8) +#define H2C_HDR_DEL_TYPE GENMASK(19, 16) +#define H2C_HDR_H2C_SEQ GENMASK(31, 24) +#define H2C_HDR_TOTAL_LEN GENMASK(13, 0) +#define H2C_HDR_REC_ACK BIT(14) +#define H2C_HDR_DONE_ACK BIT(15) + +#define FWCMD_TYPE_H2C 0 + +#define H2C_CAT_TEST 0x0 + +/* CLASS 5 - FW STATUS TEST */ +#define H2C_CL_FW_STATUS_TEST 0x5 +#define H2C_FUNC_CPU_EXCEPTION 0x1 + +#define H2C_CAT_MAC 0x1 + +/* CLASS 0 - FW INFO */ +#define H2C_CL_FW_INFO 0x0 +#define H2C_FUNC_LOG_CFG 0x0 +#define H2C_FUNC_MAC_GENERAL_PKT 0x1 + +/* CLASS 1 - WOW */ +#define H2C_CL_MAC_WOW 0x1 +enum rtw89_wow_h2c_func { + H2C_FUNC_KEEP_ALIVE = 0x0, + H2C_FUNC_DISCONNECT_DETECT = 0x1, + H2C_FUNC_WOW_GLOBAL = 0x2, + H2C_FUNC_GTK_OFLD = 0x3, + H2C_FUNC_ARP_OFLD = 0x4, + H2C_FUNC_NLO = 0x7, + H2C_FUNC_WAKEUP_CTRL = 0x8, + H2C_FUNC_WOW_CAM_UPD = 0xC, + H2C_FUNC_AOAC_REPORT_REQ = 0xD, + H2C_FUNC_WOW_PLD_CAM_UPD = 0x12, + + NUM_OF_RTW89_WOW_H2C_FUNC, +}; + +#define RTW89_WOW_WAIT_COND(tag, func) \ + ((tag) * NUM_OF_RTW89_WOW_H2C_FUNC + (func)) + +#define RTW89_WOW_WAIT_COND_AOAC \ + RTW89_WOW_WAIT_COND(0 /* don't care */, H2C_FUNC_AOAC_REPORT_REQ) + +/* CLASS 2 - PS */ +#define H2C_CL_MAC_PS 0x2 +enum rtw89_ps_h2c_func { + H2C_FUNC_MAC_LPS_PARM = 0x0, + H2C_FUNC_P2P_ACT = 0x1, + H2C_FUNC_IPS_CFG = 0x3, + H2C_FUNC_PS_POWER_LEVEL = 0x7, + H2C_FUNC_TBTT_TUNING = 0xA, + + NUM_OF_RTW89_PS_H2C_FUNC, +}; + +#define RTW89_PS_WAIT_COND(tag, func) \ + ((tag) * NUM_OF_RTW89_PS_H2C_FUNC + (func)) + +#define RTW89_PS_WAIT_COND_IPS_CFG \ + RTW89_PS_WAIT_COND(0 /* don't care */, H2C_FUNC_IPS_CFG) + +/* CLASS 3 - FW download */ +#define H2C_CL_MAC_FWDL 0x3 +#define H2C_FUNC_MAC_FWHDR_DL 0x0 + +/* CLASS 5 - Frame Exchange */ +#define H2C_CL_MAC_FR_EXCHG 0x5 +#define H2C_FUNC_MAC_CCTLINFO_UD 0x2 +#define H2C_FUNC_MAC_BCN_UPD 0x5 +#define H2C_FUNC_MAC_DCTLINFO_UD_V1 0x9 +#define H2C_FUNC_MAC_CCTLINFO_UD_V1 0xa +#define H2C_FUNC_MAC_DCTLINFO_UD_V2 0xc +#define H2C_FUNC_MAC_BCN_UPD_BE 0xd +#define H2C_FUNC_MAC_DCTLINFO_UD_V3 0x10 +#define H2C_FUNC_MAC_CCTLINFO_UD_G7 0x11 + +/* CLASS 6 - Address CAM */ +#define H2C_CL_MAC_ADDR_CAM_UPDATE 0x6 +#define H2C_FUNC_MAC_ADDR_CAM_UPD 0x0 + +/* CLASS 8 - Media Status Report */ +#define H2C_CL_MAC_MEDIA_RPT 0x8 +#define H2C_FUNC_MAC_JOININFO 0x0 +#define H2C_FUNC_MAC_FWROLE_MAINTAIN 0x4 +#define H2C_FUNC_NOTIFY_DBCC 0x5 + +/* CLASS 9 - FW offload */ +#define H2C_CL_MAC_FW_OFLD 0x9 +enum rtw89_fw_ofld_h2c_func { + H2C_FUNC_PACKET_OFLD = 0x1, + H2C_FUNC_MAC_MACID_PAUSE = 0x8, + H2C_FUNC_USR_EDCA = 0xF, + H2C_FUNC_TSF32_TOGL = 0x10, + H2C_FUNC_CMD_OFLD_PKT = 0x13, + H2C_FUNC_OFLD_CFG = 0x14, + H2C_FUNC_ADD_SCANOFLD_CH = 0x16, + H2C_FUNC_SCANOFLD = 0x17, + H2C_FUNC_TX_DUTY = 0x18, + H2C_FUNC_PKT_DROP = 0x1b, + H2C_FUNC_CFG_BCNFLTR = 0x1e, + H2C_FUNC_OFLD_RSSI = 0x1f, + H2C_FUNC_OFLD_TP = 0x20, + H2C_FUNC_MAC_MACID_PAUSE_SLEEP = 0x28, + H2C_FUNC_SCANOFLD_BE = 0x2c, + H2C_FUNC_TRX_PROTECT = 0x34, + + NUM_OF_RTW89_FW_OFLD_H2C_FUNC, +}; + +#define RTW89_FW_OFLD_WAIT_COND(tag, func) \ + ((tag) * NUM_OF_RTW89_FW_OFLD_H2C_FUNC + (func)) + +#define RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op) \ + RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \ + H2C_FUNC_PACKET_OFLD) +#define RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_TRX_PROTECT) + +#define RTW89_SCANOFLD_WAIT_COND_ADD_CH RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH) + +#define RTW89_SCANOFLD_WAIT_COND_START RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD) +#define RTW89_SCANOFLD_WAIT_COND_STOP RTW89_FW_OFLD_WAIT_COND(1, H2C_FUNC_SCANOFLD) +#define RTW89_SCANOFLD_BE_WAIT_COND_START RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD_BE) +#define RTW89_SCANOFLD_BE_WAIT_COND_STOP RTW89_FW_OFLD_WAIT_COND(1, H2C_FUNC_SCANOFLD_BE) + + +/* CLASS 10 - Security CAM */ +#define H2C_CL_MAC_SEC_CAM 0xa +#define H2C_FUNC_MAC_SEC_UPD 0x1 + +/* CLASS 12 - BA CAM */ +#define H2C_CL_BA_CAM 0xc +#define H2C_FUNC_MAC_BA_CAM 0x0 +#define H2C_FUNC_MAC_BA_CAM_V1 0x1 +#define H2C_FUNC_MAC_BA_CAM_INIT 0x2 + +/* CLASS 14 - MCC */ +#define H2C_CL_MCC 0xe +enum rtw89_mcc_h2c_func { + H2C_FUNC_ADD_MCC = 0x0, + H2C_FUNC_START_MCC = 0x1, + H2C_FUNC_STOP_MCC = 0x2, + H2C_FUNC_DEL_MCC_GROUP = 0x3, + H2C_FUNC_RESET_MCC_GROUP = 0x4, + H2C_FUNC_MCC_REQ_TSF = 0x5, + H2C_FUNC_MCC_MACID_BITMAP = 0x6, + H2C_FUNC_MCC_SYNC = 0x7, + H2C_FUNC_MCC_SET_DURATION = 0x8, + + NUM_OF_RTW89_MCC_H2C_FUNC, +}; + +#define RTW89_MCC_WAIT_COND(group, func) \ + ((group) * NUM_OF_RTW89_MCC_H2C_FUNC + (func)) + +/* CLASS 20 - MLO */ +#define H2C_CL_MLO 0x14 +enum rtw89_mlo_h2c_func { + H2C_FUNC_MLO_TBL_CFG = 0x0, + H2C_FUNC_MLO_STA_CFG = 0x1, + H2C_FUNC_MLO_TTLM = 0x2, + H2C_FUNC_MLO_DM_CFG = 0x3, + H2C_FUNC_MLO_EMLSR_STA_CFG = 0x4, + H2C_FUNC_MLO_MCMLO_RELINK_DROP = 0x5, + H2C_FUNC_MLO_MCMLO_SN_SYNC = 0x6, + H2C_FUNC_MLO_RELINK = 0x7, + H2C_FUNC_MLO_LINK_CFG = 0x8, + H2C_FUNC_MLO_DM_DBG = 0x9, + + NUM_OF_RTW89_MLO_H2C_FUNC, +}; + +#define RTW89_MLO_WAIT_COND(macid, func) \ + ((macid) * NUM_OF_RTW89_MLO_H2C_FUNC + (func)) + +/* CLASS 24 - MRC */ +#define H2C_CL_MRC 0x18 +enum rtw89_mrc_h2c_func { + H2C_FUNC_MRC_REQ_TSF = 0x0, + H2C_FUNC_ADD_MRC = 0x1, + H2C_FUNC_START_MRC = 0x2, + H2C_FUNC_DEL_MRC = 0x3, + H2C_FUNC_MRC_SYNC = 0x4, + H2C_FUNC_MRC_UPD_DURATION = 0x5, + H2C_FUNC_MRC_UPD_BITMAP = 0x6, + + NUM_OF_RTW89_MRC_H2C_FUNC, +}; + +/* can consider MRC's sch_idx as MCC's group */ +#define RTW89_MRC_WAIT_COND(sch_idx, func) \ + ((sch_idx) * NUM_OF_RTW89_MRC_H2C_FUNC + (func)) + +#define RTW89_MRC_WAIT_COND_REQ_TSF \ + RTW89_MRC_WAIT_COND(0 /* don't care */, H2C_FUNC_MRC_REQ_TSF) + +/* CLASS 36 - AP */ +#define H2C_CL_AP 0x24 +#define H2C_FUNC_AP_INFO 0x0 + +#define H2C_CAT_OUTSRC 0x2 + +#define H2C_CL_OUTSRC_RA 0x1 +#define H2C_FUNC_OUTSRC_RA_MACIDCFG 0x0 +#define H2C_FUNC_OUTSRC_RA_TX_HISTORY 0x9 +#define H2C_FUNC_OUTSRC_RA_PHY_CH_RPT 0xe +#define H2C_FUNC_OUTSRC_RA_DRV_CTRL_FW 0xf + +#define H2C_CL_OUTSRC_DM 0x2 +#define H2C_FUNC_FW_MCC_DIG 0x6 +#define H2C_FUNC_FW_LPS_CH_INFO 0xb +#define H2C_FUNC_FW_LPS_ML_CMN_INFO 0xe + +#define H2C_CL_OUTSRC_RF_REG_A 0x8 +#define H2C_CL_OUTSRC_RF_REG_B 0x9 +#define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa +#define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2 +#define H2C_FUNC_OUTSRC_RF_MCC_INFO 0xf +#define H2C_FUNC_OUTSRC_RF_PS_INFO 0x10 +#define H2C_CL_OUTSRC_RF_FW_RFK 0xb + +enum rtw89_rfk_offload_h2c_func { + H2C_FUNC_RFK_TSSI_OFFLOAD = 0x0, + H2C_FUNC_RFK_IQK_OFFLOAD = 0x1, + H2C_FUNC_RFK_DPK_OFFLOAD = 0x3, + H2C_FUNC_RFK_TXGAPK_OFFLOAD = 0x4, + H2C_FUNC_RFK_DACK_OFFLOAD = 0x5, + H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6, + H2C_FUNC_RFK_PRE_NOTIFY = 0x8, + H2C_FUNC_RFK_TAS_OFFLOAD = 0x9, + H2C_FUNC_RFK_TXIQK_OFFOAD = 0xc, + H2C_FUNC_RFK_CIM3K_OFFOAD = 0xe, +}; + +struct rtw89_fw_h2c_rf_get_mccch { + __le32 ch_0_0; + __le32 ch_0_1; + __le32 ch_1_0; + __le32 ch_1_1; + __le32 current_channel; +} __packed; + +struct rtw89_fw_h2c_rf_get_mccch_v0 { + __le32 ch_0; + __le32 ch_1; + __le32 band_0; + __le32 band_1; + __le32 current_channel; + __le32 current_band_type; +} __packed; + +struct rtw89_h2c_mcc_dig { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_H2C_MCC_DIG_W0_REG_CNT GENMASK(7, 0) +#define RTW89_H2C_MCC_DIG_W0_DM_EN BIT(8) +#define RTW89_H2C_MCC_DIG_W0_IDX GENMASK(10, 9) +#define RTW89_H2C_MCC_DIG_W0_SET BIT(11) +#define RTW89_H2C_MCC_DIG_W0_PHY0_EN BIT(12) +#define RTW89_H2C_MCC_DIG_W0_PHY1_EN BIT(13) +#define RTW89_H2C_MCC_DIG_W0_CENTER_CH GENMASK(23, 16) +#define RTW89_H2C_MCC_DIG_W0_BAND_TYPE GENMASK(31, 24) +#define RTW89_H2C_MCC_DIG_W1_ADDR_LSB GENMASK(7, 0) +#define RTW89_H2C_MCC_DIG_W1_ADDR_MSB GENMASK(15, 8) +#define RTW89_H2C_MCC_DIG_W1_BMASK_LSB GENMASK(23, 16) +#define RTW89_H2C_MCC_DIG_W1_BMASK_MSB GENMASK(31, 24) +#define RTW89_H2C_MCC_DIG_W2_VAL_LSB GENMASK(7, 0) +#define RTW89_H2C_MCC_DIG_W2_VAL_MSB GENMASK(15, 8) + +#define NUM_OF_RTW89_FW_RFK_PATH 2 +#define NUM_OF_RTW89_FW_RFK_TBL 3 + +struct rtw89_h2c_rf_ps_info { + __le32 rf18[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 mlo_mode; + u8 pri_ch[NUM_OF_RTW89_FW_RFK_PATH]; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_common { + struct { + __le32 ch[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL]; + __le32 band[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL]; + } __packed dbcc; + + __le32 mlo_mode; + struct { + __le32 cur_ch[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 cur_band[NUM_OF_RTW89_FW_RFK_PATH]; + } __packed tbl; + + __le32 phy_idx; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_v0 { + struct rtw89_fw_h2c_rfk_pre_info_common common; + + __le32 cur_band; + __le32 cur_bw; + __le32 cur_center_ch; + + __le32 ktbl_sel0; + __le32 ktbl_sel1; + __le32 rfmod0; + __le32 rfmod1; + + __le32 mlo_1_1; + __le32 rfe_type; + __le32 drv_mode; + + struct { + __le32 ch[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 band[NUM_OF_RTW89_FW_RFK_PATH]; + } __packed mlo; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_v1 { + struct rtw89_fw_h2c_rfk_pre_info_common common; + __le32 mlo_1_1; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_v2 { + struct rtw89_fw_h2c_rfk_pre_info_v1 base_v1; + __le32 cur_bandwidth[NUM_OF_RTW89_FW_RFK_PATH]; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info { + __le32 mlo_mode; + __le32 phy_idx; + __le32 mlo_1_1; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 { + __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL][NUM_OF_RTW89_FW_RFK_PATH]; + __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 mlo_mode; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 { + __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL]; + __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 mlo_mode; + __le32 mlo_1_1; + u8 phy_idx; + u8 tbl_idx; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc { + struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 base; + u8 rsvd[2]; + __le32 aid; + u8 acv; + u8 rsvd2[3]; +} __packed; + +struct rtw89_h2c_rf_tssi { + __le16 len; + u8 phy; + u8 ch; + u8 bw; + u8 band; + u8 hwtx_en; + u8 cv; + s8 curr_tssi_cck_de[2]; + s8 curr_tssi_cck_de_20m[2]; + s8 curr_tssi_cck_de_40m[2]; + s8 curr_tssi_efuse_cck_de[2]; + s8 curr_tssi_ofdm_de[2]; + s8 curr_tssi_ofdm_de_20m[2]; + s8 curr_tssi_ofdm_de_40m[2]; + s8 curr_tssi_ofdm_de_80m[2]; + s8 curr_tssi_ofdm_de_160m[2]; + s8 curr_tssi_ofdm_de_320m[2]; + s8 curr_tssi_efuse_ofdm_de[2]; + s8 curr_tssi_ofdm_de_diff_20m[2]; + s8 curr_tssi_ofdm_de_diff_80m[2]; + s8 curr_tssi_ofdm_de_diff_160m[2]; + s8 curr_tssi_ofdm_de_diff_320m[2]; + s8 curr_tssi_trim_de[2]; + u8 pg_thermal[2]; + u8 ftable[2][128]; + u8 tssi_mode; + u8 rfe_type; +} __packed; + +struct rtw89_h2c_rf_iqk_v0 { + __le32 phy_idx; + __le32 dbcc; +} __packed; + +struct rtw89_h2c_rf_iqk { + u8 len; + u8 ktype; + u8 phy; + u8 kpath; + u8 band; + u8 bw; + u8 ch; + u8 cv; +} __packed; + +struct rtw89_h2c_rf_dpk { + u8 len; + u8 phy; + u8 dpk_enable; + u8 kpath; + u8 cur_band; + u8 cur_bw; + u8 cur_ch; + u8 dpk_dbg_en; +} __packed; + +struct rtw89_h2c_rf_txgapk { + u8 len; + u8 ktype; + u8 phy; + u8 kpath; + u8 band; + u8 bw; + u8 ch; + u8 cv; +} __packed; + +struct rtw89_h2c_rf_dack { + u8 len; + u8 phy; + u8 type; +} __packed; + +struct rtw89_h2c_rf_rxdck_v0 { + u8 len; + u8 phy; + u8 is_afe; + u8 kpath; + u8 cur_band; + u8 cur_bw; + u8 cur_ch; + u8 rxdck_dbg_en; +} __packed; + +struct rtw89_h2c_rf_tas { + __le32 enable; +} __packed; + +struct rtw89_h2c_rf_rxdck { + struct rtw89_h2c_rf_rxdck_v0 v0; + u8 is_chl_k; +} __packed; + +struct rtw89_h2c_rf_txiqk_v0 { + u8 len; + u8 phy; + u8 txiqk_enable; + u8 is_wb_txiqk; + u8 kpath; + u8 cur_band; + u8 cur_bw; + u8 cur_ch; + u8 txiqk_dbg_en; +} __packed; + +struct rtw89_h2c_rf_txiqk { + struct rtw89_h2c_rf_txiqk_v0 v0; + u8 is_ther_rek; +} __packed; + +struct rtw89_h2c_rf_cim3k { + u8 len; + u8 phy; + u8 su_cim3k_enable[2]; + u8 ru_cim3k_enable[2]; + u8 kpath; + u8 cur_band; + u8 cur_bw; + u8 cur_ch; + u8 cim3k_dbg_en; +} __packed; + +enum rtw89_rf_log_type { + RTW89_RF_RUN_LOG = 0, + RTW89_RF_RPT_LOG = 1, +}; + +struct rtw89_c2h_rf_log_hdr { + u8 type; /* enum rtw89_rf_log_type */ + __le16 len; + u8 content[]; +} __packed; + +struct rtw89_c2h_rf_run_log { + __le32 fmt_idx; + __le32 arg[4]; +} __packed; + +struct rtw89_c2h_rf_iqk_rpt_log { + bool iqk_tx_fail[2]; + bool iqk_rx_fail[2]; + bool is_iqk_init; + bool is_reload; + bool is_wb_txiqk[2]; + bool is_wb_rxiqk[2]; + bool is_nbiqk; + bool txiqk_en; + bool rxiqk_en; + bool lok_en; + bool iqk_xym_en; + bool iqk_sram_en; + bool iqk_fft_en; + bool is_fw_iqk; + bool is_iqk_enable; + bool iqk_cfir_en; + bool thermal_rek_en; + u8 iqk_band[2]; + u8 iqk_ch[2]; + u8 iqk_bw[2]; + u8 iqk_times; + u8 version; + u8 phy; + u8 fwk_status; + u8 rsvd; + __le32 reload_cnt; + __le32 iqk_fail_cnt; + __le32 rf_0x18[2]; + __le32 lok_idac[2]; + __le32 lok_vbuf[2]; + __le32 rftxgain[2][6]; + __le32 rfrxgain[2][6]; + __le32 tx_xym[2][6]; + __le32 rx_xym[2][6]; + __le32 rx_wb_xym[2][32]; + bool is_radar; + u8 rsvd1[3]; +} __packed; + +struct rtw89_c2h_rf_dpk_rpt_log { + u8 ver; + u8 idx[2]; + u8 band[2]; + u8 bw[2]; + u8 ch[2]; + u8 path_ok[2]; + u8 txagc[2]; + u8 ther[2]; + u8 gs[2]; + u8 dc_i[4]; + u8 dc_q[4]; + u8 corr_val[2]; + u8 corr_idx[2]; + u8 is_timeout[2]; + u8 rxbb_ov[2]; + u8 rsvd; +} __packed; + +struct rtw89_c2h_rf_dack_rpt_log { + u8 fwdack_ver; + u8 fwdack_info_ver; + u8 msbk_d[2][2][16]; + u8 dadck_d[2][2]; + u8 cdack_d[2][2][2]; + u8 addck2_hd[2][2][2]; + u8 addck2_ld[2][2][2]; + u8 adgaink_d[2][2]; + u8 biask_hd[2][2]; + u8 biask_ld[2][2]; + u8 addck_timeout; + u8 cdack_timeout; + u8 dadck_timeout; + u8 msbk_timeout; + u8 adgaink_timeout; + u8 wbadcdck_timeout; + u8 drck_timeout; + u8 dack_fail; + u8 wbdck_d[2]; + u8 rck_d; + u8 adgaink_ex_d; +} __packed; + +struct rtw89_c2h_rf_rxdck_rpt_log { + u8 ver; + u8 band[2]; + u8 bw[2]; + u8 ch[2]; + u8 timeout[2]; +} __packed; + +struct rtw89_c2h_rf_tssi_rpt_log { + s8 alignment_power[2][2][4]; + u8 alignment_power_cw_h[2][2][4]; + u8 alignment_power_cw_l[2][2][4]; + u8 tssi_alimk_state[2][2]; + u8 default_txagc_offset[2][2]; +} __packed; + +struct rtw89_c2h_rf_txgapk_rpt_log { + __le32 r0x8010[2]; + __le32 chk_cnt; + u8 track_d[2][17]; + u8 power_d[2][17]; + u8 is_txgapk_ok; + u8 chk_id; + u8 ver; + u8 d_bnd_ok; + __le32 stage[2]; + __le16 failcode[2]; + u8 rsvd[4]; +} __packed; + +struct rtw89_c2h_rf_txiqk_rpt_log { + u8 fw_txiqk_ver; + u8 iqk_band[2]; + u8 iqk_ch[2]; + u8 iqk_bw[2]; + bool tx_iqk_fail[2]; + bool is_iqk_init; + bool txiqk_en; + bool lok_en; + bool lok_fail[2]; + u8 rsvd[2]; + __le32 iqk_times; + bool txiqk_nctldone[2]; + u8 rsvd2[2]; + __le32 txgain[2][6]; + __le32 tx_iqc[2][6]; + __le32 tx_xym[2][6][14]; + __le32 kidx[2]; +} __packed; + +struct rtw89_c2h_rf_cim3k_rpt_log { + u8 cim3k_band[2]; + u8 cim3k_ch[2]; + u8 cim3k_bw[2]; + u8 su_path_ok[2]; + u8 ru_path_ok[2]; + u8 txagc_cim3k[2]; + u8 ther_cim3k[2]; + u8 cim3k_gs[2]; + __le16 cim3k_pwsf[2]; + bool cim3k_nctldone[2]; + u8 rsvd[2]; + __le32 cim3k_rxiqc[2]; + __le32 cim3k_su_coef[2][3]; + __le16 dc_i[2]; + __le16 dc_q[2]; + u8 corr_val[2]; + u8 corr_idx[2]; + u8 rxbb_ov[2]; + u8 cim3k_txiqc[2]; + u8 kidx[2]; + u8 fw_cim3k_ver; + bool su_cim3k_en[2]; + bool ru_cim3k_en[2]; + u8 rsvd1; +} __packed; + +struct rtw89_c2h_rfk_report { + struct rtw89_c2h_hdr hdr; + u8 state; /* enum rtw89_rfk_report_state */ + u8 version; +} __packed; + +struct rtw89_c2h_rf_tas_rpt_log { + __le32 cur_idx; + __le16 txpwr_history[20]; +} __packed; + +struct rtw89_c2h_rf_tas_info { + struct rtw89_c2h_hdr hdr; + struct rtw89_c2h_rf_tas_rpt_log content; +} __packed; + +#define RTW89_FW_RSVD_PLE_SIZE 0x800 + +#define RTW89_FW_BACKTRACE_INFO_SIZE 8 +#define RTW89_VALID_FW_BACKTRACE_SIZE(_size) \ + ((_size) % RTW89_FW_BACKTRACE_INFO_SIZE == 0) + +#define RTW89_FW_BACKTRACE_MAX_SIZE 512 /* 8 * 64 (entries) */ +#define RTW89_FW_BACKTRACE_KEY 0xBACEBACE + +#define FWDL_WAIT_CNT 400000 +#define FWDL_WAIT_CNT_USB 3200 + +int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type); +int rtw89_fw_recognize(struct rtw89_dev *rtwdev); +int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev); +const struct firmware * +rtw89_early_fw_feature_recognize(struct device *device, + const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant, + struct rtw89_fw_info *early_fw, + int *used_fw_format); +int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + bool include_bb); +void rtw89_load_firmware_work(struct work_struct *work); +void rtw89_unload_firmware(struct rtw89_dev *rtwdev); +int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev); +int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev); +void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len); +void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u8 type, u8 cat, u8 class, u8 func, + bool rack, bool dack, u32 len); +int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_dmac_tbl_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_assoc_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_ampdu_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_txtime_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured); +int rtw89_fw_h2c_punctured_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured); +int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_tbtt_tuning(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u32 offset); +int rtw89_fw_h2c_pwr_lvl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif, + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, + enum rtw89_upd_mode upd_mode); +int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_dctl_sec_cam_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); +void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev); +void rtw89_fw_c2h_dummy_handler(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len); +int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + enum rtw89_upd_mode upd_mode); +int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool dis_conn); +int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en); +int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, + bool pause); +int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u8 ac, u32 val); +int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv); +int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool connect); +int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu); +int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); +int rtw89_fw_h2c_phy_ch_rpt(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_tx_history(struct rtw89_dev *rtwdev, u16 mac_id); +int rtw89_fw_h2c_drv_ctrl_fw(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_init_v10(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v101(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_init_v11(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_mlo_v2(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_osi_info_v6(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_trx_v107(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxtxpwr_v7(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_cxtxpwr_v9(struct rtw89_dev *rtwdev, u8 type); +int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id); +int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, + struct sk_buff *skb_ofld); +int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *opt, + struct rtw89_vif_link *vif, + bool wowlan); +int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *opt, + struct rtw89_vif_link *vif, + bool wowlan); +int rtw89_fw_h2c_trx_protect(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool enable); +int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, + struct rtw89_fw_h2c_rf_reg_info *info, + u16 len, u8 page); +int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); +int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx chanctx_idx, + u8 mcc_role_idx, u8 pd_val, bool en); +int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode); +int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, bool is_chl_k); +int rtw89_fw_h2c_rf_tas_trigger(struct rtw89_dev *rtwdev, bool enable); +int rtw89_fw_h2c_rf_txiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_rf_cim3k(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan); +int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, + u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, + bool rack, bool dack); +int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); +void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); +void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); +void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u8 macid); +void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool notify_fw); +void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + bool valid, struct ieee80211_ampdu_params *params); +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + bool valid, struct ieee80211_ampdu_params *params); +void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, + u8 offset, u8 mac_idx); + +int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, + struct rtw89_lps_parm *lps_param); +int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif); +void rtw89_bb_lps_cmn_info_rx_gain_fill(struct rtw89_dev *rtwdev, + struct rtw89_bb_link_info_rx_gain *h2c_gain, + const struct rtw89_chan *chan, u8 phy_idx); +int rtw89_fw_h2c_lps_ml_cmn_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif); +int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); +struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len); +struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len); +int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, + struct rtw89_mac_h2c_info *h2c_info, + struct rtw89_mac_c2h_info *c2h_info); +int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); +void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); +int rtw89_hw_scan_start(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_scan_request *scan_req); +void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool aborted); +int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool enable); +void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev); +int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev); +int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool wowlan); +void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool wowlan); +int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, + const struct rtw89_pkt_drop_params *params); +int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_p2p_noa_desc *desc, + u8 act, u8 noa_id, u8 ctwindow_oppps); +int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool en); +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); +int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); +int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); +int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); +int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); +int rtw89_fw_h2c_wow_cam_update_v1(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); +int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool enable); +int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_add_req *p); +int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_start_req *p); +int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, + bool prev_groups); +int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, + bool prev_groups); +int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group); +int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_tsf_req *req, + struct rtw89_mac_mcc_tsf_rpt *rpt); +int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid, + u8 *bitmap); +int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, + u8 target, u8 offset); +int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mcc_duration *p); +int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_add_arg *arg); +int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_start_arg *arg); +int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx); +int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_req_tsf_arg *arg, + struct rtw89_mac_mrc_tsf_rpt *rpt); +int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_upd_bitmap_arg *arg); +int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_sync_arg *arg); +int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev, + const struct rtw89_fw_mrc_upd_duration_arg *arg); +int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en); +int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool enable); + +static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->bacam_ver == RTW89_BACAM_V0_EXT) + rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(rtwdev); +} + +static inline void rtw89_fw_h2c_init_trx_protect(struct rtw89_dev *rtwdev) +{ + u8 active_bands = rtw89_get_active_phy_bitmap(rtwdev); + int i; + + for (i = 0; i < RTW89_PHY_NUM; i++) + rtw89_fw_h2c_trx_protect(rtwdev, i, active_bands & BIT(i)); +} + +static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); +} + +static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->h2c_default_dmac_tbl) + return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + + return 0; +} + +static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_update_beacon(rtwdev, rtwvif_link); +} + +static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); +} + +static inline +int rtw89_chip_h2c_ampdu_link_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->h2c_ampdu_cmac_tbl) + return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, rtwvif_link, + rtwsta_link); + + return 0; +} + +static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_chip_h2c_ampdu_link_cmac_tbl(rtwdev, rtwvif_link, + rtwsta_link); + if (ret) + return ret; + } + + return 0; +} + +static inline +int rtw89_chip_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); +} + +static inline +int rtw89_chip_h2c_punctured_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->h2c_punctured_cmac_tbl) + return 0; + + return chip->ops->h2c_punctured_cmac_tbl(rtwdev, rtwvif_link, punctured); +} + +static inline +int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, + bool valid, struct ieee80211_ampdu_params *params) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = chip->ops->h2c_ba_cam(rtwdev, rtwvif_link, rtwsta_link, + valid, params); + if (ret) + return ret; + } + + return 0; +} + +static inline +int rtw89_chip_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_wow_cam_update(rtwdev, cam_info); +} + +/* Must consider compatibility; don't insert new in the mid. + * Fill each field's default value in rtw89_regd_entcpy(). + */ +struct rtw89_fw_regd_entry { + u8 alpha2_0; + u8 alpha2_1; + u8 rule_2ghz; + u8 rule_5ghz; + u8 rule_6ghz; + __le32 fmap; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_byrate_entry { + u8 band; + u8 nss; + u8 rs; + u8 shf; + u8 len; + __le32 data; + u8 bw; + u8 ofdma; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_2ghz_entry { + u8 bw; + u8 nt; + u8 rs; + u8 bf; + u8 regd; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_5ghz_entry { + u8 bw; + u8 nt; + u8 rs; + u8 bf; + u8 regd; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_6ghz_entry { + u8 bw; + u8 nt; + u8 rs; + u8 bf; + u8 regd; + u8 reg_6ghz_power; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_ru_2ghz_entry { + u8 ru; + u8 nt; + u8 regd; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_ru_5ghz_entry { + u8 ru; + u8 nt; + u8 regd; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_txpwr_lmt_ru_6ghz_entry { + u8 ru; + u8 nt; + u8 regd; + u8 reg_6ghz_power; + u8 ch_idx; + s8 v; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_tx_shape_lmt_entry { + u8 band; + u8 tx_shape_rs; + u8 regd; + u8 v; + u8 reg6_pwr; +} __packed; + +/* must consider compatibility; don't insert new in the mid */ +struct rtw89_fw_tx_shape_lmt_ru_entry { + u8 band; + u8 regd; + u8 v; + u8 reg6_pwr; +} __packed; + +const struct rtw89_rfe_parms * +rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev, + const struct rtw89_rfe_parms *init); + +enum rtw89_wow_wakeup_ver { + RTW89_WOW_REASON_V0, + RTW89_WOW_REASON_V1, + RTW89_WOW_REASON_NUM, +}; + +const struct rtw89_io_ops * +rtw89_fw_cmd_ofld_alloc_and_get_io_ops(struct rtw89_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/led.c b/drivers/net/wireless/realtek/rtw89/led.c new file mode 100644 index 000000000..ae74b7075 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/led.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include "core.h" +#include "debug.h" +#include "led.h" +#include "reg.h" + +static const struct rtw89_led_gpio_entry rtw89_common_led_gpios[] = {{ + .pin = 8, + .pinmux = {.addr = R_AX_GPIO8_15_FUNC_SEL, .mask = GENMASK(3, 0), .data = 0xf}, + .mode = {.addr = R_AX_GPIO_EXT_CTRL + 2, .data = BIT(0) | BIT(8)}, + .out = {.addr = R_AX_GPIO_EXT_CTRL + 1, .data = BIT(0)}, +}}; + +static const struct rtw89_led_desc rtw89_common_led_desc = { + .gpios = rtw89_common_led_gpios, + .n_gpio = ARRAY_SIZE(rtw89_common_led_gpios), +}; + +void rtw89_led_gpio_config(struct rtw89_dev *rtwdev, + const struct rtw89_led_gpio_entry *e) +{ + rtw89_write32_mask(rtwdev, e->pinmux.addr, e->pinmux.mask, e->pinmux.data); + rtw89_write16_clr(rtwdev, e->mode.addr, e->mode.data); +} + +void rtw89_led_gpio_set(struct rtw89_dev *rtwdev, + const struct rtw89_led_gpio_entry *e, + enum led_brightness brightness) +{ + if (brightness == LED_OFF) { + rtw89_write16_clr(rtwdev, e->mode.addr, e->mode.data); + } else { + rtw89_write16_set(rtwdev, e->mode.addr, e->mode.data); + rtw89_write8_clr(rtwdev, e->out.addr, e->out.data); + } +} + +static int rtw89_led_set(struct led_classdev *led, enum led_brightness brightness) +{ + struct rtw89_led *rtw_led = container_of(led, struct rtw89_led, led); + struct rtw89_dev *rtwdev = container_of(rtw_led, struct rtw89_dev, led); + const struct rtw89_led_desc *desc = rtw_led->desc; + const struct rtw89_led_gpio_entry *e = &desc->gpios[0]; + + if (rtw_led->brightness_cache[0] == brightness) { + rtw89_debug(rtwdev, RTW89_DBG_LED, "led_set: pin=%u skip (no change)\n", + e->pin); + return 0; + } + + wiphy_lock(rtwdev->hw->wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_LED, "led_set: pin=%u brightness=%u\n", + e->pin, brightness); + rtw89_led_gpio_set(rtwdev, e, brightness); + rtw_led->brightness_cache[0] = brightness; + + wiphy_unlock(rtwdev->hw->wiphy); + + return 0; +} + +static int rtw89_led_sc_init(struct rtw89_dev *rtwdev, const struct rtw89_led_desc *desc) +{ + struct rtw89_led *rtw_led = &rtwdev->led; + int ret; + + snprintf(rtw_led->name, sizeof(rtw_led->name), "rtw89-%s", + wiphy_name(rtwdev->hw->wiphy)); + rtw_led->led.name = rtw_led->name; + rtw_led->led.brightness_set_blocking = rtw89_led_set; + rtw_led->led.max_brightness = LED_ON; + rtw_led->led.default_trigger = ieee80211_get_assoc_led_name(rtwdev->hw); + + ret = led_classdev_register(rtwdev->dev, &rtw_led->led); + if (ret) { + rtw89_warn(rtwdev, "failed to register LED, ret=%d\n", ret); + return ret; + } + + rtw89_led_gpio_config(rtwdev, &desc->gpios[0]); + + return 0; +} + +static void rtw89_led_sc_deinit(struct rtw89_dev *rtwdev) +{ + struct rtw89_led *rtw_led = &rtwdev->led; + + led_classdev_unregister(&rtw_led->led); +} + +void rtw89_led_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_led_desc *desc = &rtw89_common_led_desc; + struct rtw89_led *rtw_led = &rtwdev->led; + const struct rtw89_board_variant *board = rtwdev->board; + int ret; + int i; + + /* single-GPIO monochrome LED is the only supported layout */ + BUILD_BUG_ON(ARRAY_SIZE(rtw89_common_led_gpios) != 1); + + if (board) + desc = board->led_desc; + if (!desc->n_gpio || desc->n_gpio > RTW89_LED_MAX_NUM) + return; + + rtw_led->desc = desc; + for (i = 0; i < ARRAY_SIZE(rtw_led->brightness_cache); i++) + rtw_led->brightness_cache[i] = LED_OFF; + + if (desc->n_gpio == 1) + ret = rtw89_led_sc_init(rtwdev, desc); + else + ret = rtw89_led_mc_init(rtwdev, desc); + + if (ret) + return; + + rtw_led->registered = true; +} + +void rtw89_led_deinit(struct rtw89_dev *rtwdev) +{ + struct rtw89_led *rtw_led = &rtwdev->led; + const struct rtw89_led_desc *desc = rtw_led->desc; + + if (!rtw_led->registered) + return; + + if (desc->n_gpio == 1) + rtw89_led_sc_deinit(rtwdev); + else + rtw89_led_mc_deinit(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw89/led.h b/drivers/net/wireless/realtek/rtw89/led.h new file mode 100644 index 000000000..f5ccfe1d1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/led.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2026 Realtek Corporation + */ + +#ifndef __RTW89_LED_H__ +#define __RTW89_LED_H__ + +#include "core.h" + +void rtw89_led_gpio_config(struct rtw89_dev *rtwdev, + const struct rtw89_led_gpio_entry *e); +void rtw89_led_gpio_set(struct rtw89_dev *rtwdev, + const struct rtw89_led_gpio_entry *e, + enum led_brightness brightness); + +#ifdef CONFIG_RTW89_LEDS +void rtw89_led_init(struct rtw89_dev *rtwdev); +void rtw89_led_deinit(struct rtw89_dev *rtwdev); +#else +static inline void rtw89_led_init(struct rtw89_dev *rtwdev) {} +static inline void rtw89_led_deinit(struct rtw89_dev *rtwdev) {} +#endif + +#ifdef CONFIG_RTW89_LEDS_MC +int rtw89_led_mc_init(struct rtw89_dev *rtwdev, const struct rtw89_led_desc *desc); +void rtw89_led_mc_deinit(struct rtw89_dev *rtwdev); +#else +static inline int rtw89_led_mc_init(struct rtw89_dev *rtwdev, + const struct rtw89_led_desc *desc) +{ + return -EOPNOTSUPP; +} + +static inline void rtw89_led_mc_deinit(struct rtw89_dev *rtwdev) {} +#endif + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/led_mc.c b/drivers/net/wireless/realtek/rtw89/led_mc.c new file mode 100644 index 000000000..7e9243bae --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/led_mc.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include "core.h" +#include "debug.h" +#include "led.h" + +static int rtw89_led_mc_brightness_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct led_classdev_mc *mcdev = lcdev_to_mccdev(led); + struct rtw89_led *rtw_led = container_of(mcdev, struct rtw89_led, led_mc); + struct rtw89_dev *rtwdev = container_of(rtw_led, struct rtw89_dev, led); + const struct rtw89_led_desc *desc = rtw_led->desc; + const struct rtw89_led_gpio_entry *e; + unsigned int i; + + led_mc_calc_color_components(mcdev, brightness); + + wiphy_lock(rtwdev->hw->wiphy); + + for (i = 0; i < mcdev->num_colors; i++) { + e = &desc->gpios[i]; + if (rtw_led->brightness_cache[i] == mcdev->subled_info[i].brightness) { + rtw89_debug(rtwdev, RTW89_DBG_LED, + "led_mc_set: pin=%u skip (no change)\n", e->pin); + continue; + } + + rtw89_debug(rtwdev, RTW89_DBG_LED, "led_mc_set: pin=%u brightness=%u\n", + e->pin, mcdev->subled_info[i].brightness); + rtw89_led_gpio_set(rtwdev, e, mcdev->subled_info[i].brightness); + rtw_led->brightness_cache[i] = mcdev->subled_info[i].brightness; + } + + wiphy_unlock(rtwdev->hw->wiphy); + + return 0; +} + +int rtw89_led_mc_init(struct rtw89_dev *rtwdev, const struct rtw89_led_desc *desc) +{ + struct rtw89_led *rtw_led = &rtwdev->led; + struct led_classdev_mc *led_mc = &rtw_led->led_mc; + int i, ret; + + led_mc->num_colors = desc->n_gpio; + led_mc->subled_info = rtw_led->subled; + + for (i = 0; i < desc->n_gpio; i++) { + const struct rtw89_led_gpio_entry *e = &desc->gpios[i]; + + rtw_led->subled[i].color_index = e->color; + rtw_led->subled[i].intensity = e->intensity; + rtw_led->subled[i].brightness = 0; + rtw_led->subled[i].channel = i; + + rtw89_led_gpio_config(rtwdev, e); + } + + snprintf(rtw_led->name, sizeof(rtw_led->name), "rtw89-%s-multicolor", + wiphy_name(rtwdev->hw->wiphy)); + led_mc->led_cdev.name = rtw_led->name; + led_mc->led_cdev.brightness_set_blocking = rtw89_led_mc_brightness_set; + led_mc->led_cdev.max_brightness = LED_ON; + led_mc->led_cdev.default_trigger = ieee80211_get_assoc_led_name(rtwdev->hw); + + ret = led_classdev_multicolor_register(rtwdev->dev, led_mc); + if (ret) + rtw89_warn(rtwdev, "failed to register multicolor LED, ret=%d\n", ret); + + return ret; +} + +void rtw89_led_mc_deinit(struct rtw89_dev *rtwdev) +{ + struct rtw89_led *rtw_led = &rtwdev->led; + + led_classdev_multicolor_unregister(&rtw_led->led_mc); +} diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c new file mode 100644 index 000000000..df396fbfc --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -0,0 +1,7550 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "cam.h" +#include "chan.h" +#include "debug.h" +#include "efuse.h" +#include "fw.h" +#include "mac.h" +#include "pci.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "ser.h" +#include "util.h" + +static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = { + [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR, + [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, + [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, + [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR, + [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR, + [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR, + [RTW89_MAC_MEM_SECURITY_CAM] = SECURITY_CAM_BASE_ADDR, + [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR, + [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR, + [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR, + [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR, + [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR, + [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR, + [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR, + [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR, + [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR, + [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR, + [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR, + [RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR, + [RTW89_MAC_MEM_TXD_FIFO_0_V1] = TXD_FIFO_0_BASE_ADDR_V1, + [RTW89_MAC_MEM_TXD_FIFO_1_V1] = TXD_FIFO_1_BASE_ADDR_V1, +}; + +static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset, + u32 val, enum rtw89_mac_mem_sel sel) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 addr = rtw89_mac_mem_base_addrs(rtwdev, sel) + offset; + + rtw89_write32(rtwdev, mac->filter_model_addr, addr); + rtw89_write32(rtwdev, mac->indir_access_addr, val); +} + +static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset, + enum rtw89_mac_mem_sel sel) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 addr = rtw89_mac_mem_base_addrs(rtwdev, sel) + offset; + + rtw89_write32(rtwdev, mac->filter_model_addr, addr); + return rtw89_read32(rtwdev, mac->indir_access_addr); +} + +static int rtw89_mac_check_mac_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_mac_hwmod_sel sel) +{ + u32 val, r_val; + + if (sel == RTW89_DMAC_SEL) { + r_val = rtw89_read32(rtwdev, R_AX_DMAC_FUNC_EN); + val = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN); + } else if (sel == RTW89_CMAC_SEL && mac_idx == 0) { + r_val = rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN); + val = B_AX_CMAC_EN; + } else if (sel == RTW89_CMAC_SEL && mac_idx == 1) { + r_val = rtw89_read32(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND); + val = B_AX_CMAC1_FEN; + } else { + return -EINVAL; + } + if (r_val == RTW89_R32_EA || r_val == RTW89_R32_DEAD || + (val & r_val) != val) + return -EFAULT; + + return 0; +} + +int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val) +{ + u8 lte_ctrl; + int ret; + + ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, + 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); + if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); + + rtw89_write32(rtwdev, R_AX_LTE_WDATA, val); + rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0xC00F0000 | offset); + + return ret; +} + +int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val) +{ + u8 lte_ctrl; + int ret; + + ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, + 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); + if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); + + rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset); + *val = rtw89_read32(rtwdev, R_AX_LTE_RDATA); + + return ret; +} + +int rtw89_mac_dle_dfi_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl) +{ + u32 ctrl_reg, data_reg, ctrl_data; + u32 val; + int ret; + + switch (ctrl->type) { + case DLE_CTRL_TYPE_WDE: + ctrl_reg = R_AX_WDE_DBG_FUN_INTF_CTL; + data_reg = R_AX_WDE_DBG_FUN_INTF_DATA; + ctrl_data = FIELD_PREP(B_AX_WDE_DFI_TRGSEL_MASK, ctrl->target) | + FIELD_PREP(B_AX_WDE_DFI_ADDR_MASK, ctrl->addr) | + B_AX_WDE_DFI_ACTIVE; + break; + case DLE_CTRL_TYPE_PLE: + ctrl_reg = R_AX_PLE_DBG_FUN_INTF_CTL; + data_reg = R_AX_PLE_DBG_FUN_INTF_DATA; + ctrl_data = FIELD_PREP(B_AX_PLE_DFI_TRGSEL_MASK, ctrl->target) | + FIELD_PREP(B_AX_PLE_DFI_ADDR_MASK, ctrl->addr) | + B_AX_PLE_DFI_ACTIVE; + break; + default: + rtw89_warn(rtwdev, "[ERR] dfi ctrl type %d\n", ctrl->type); + return -EINVAL; + } + + rtw89_write32(rtwdev, ctrl_reg, ctrl_data); + + ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_WDE_DFI_ACTIVE), + 1, 1000, false, rtwdev, ctrl_reg); + if (ret) { + rtw89_warn(rtwdev, "[ERR] dle dfi ctrl 0x%X set 0x%X timeout\n", + ctrl_reg, ctrl_data); + return ret; + } + + ctrl->out_data = rtw89_read32(rtwdev, data_reg); + return 0; +} + +int rtw89_mac_dle_dfi_quota_cfg(struct rtw89_dev *rtwdev, + struct rtw89_mac_dle_dfi_quota *quota) +{ + struct rtw89_mac_dle_dfi_ctrl ctrl; + int ret; + + ctrl.type = quota->dle_type; + ctrl.target = DLE_DFI_TYPE_QUOTA; + ctrl.addr = quota->qtaid; + ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl); + if (ret) { + rtw89_warn(rtwdev, "[ERR] dle dfi quota %d\n", ret); + return ret; + } + + quota->rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, ctrl.out_data); + quota->use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, ctrl.out_data); + return 0; +} + +int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev, + struct rtw89_mac_dle_dfi_qempty *qempty) +{ + struct rtw89_mac_dle_dfi_ctrl ctrl; + int ret; + + ctrl.type = qempty->dle_type; + ctrl.target = DLE_DFI_TYPE_QEMPTY; + ctrl.addr = qempty->grpsel; + ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl); + if (ret) { + rtw89_warn(rtwdev, "[ERR] dle dfi qempty %d\n", ret); + return ret; + } + + qempty->qempty = FIELD_GET(B_AX_DLE_QEMPTY_GRP, ctrl.out_data); + return 0; +} + +static void dump_err_status_dispatcher_ax(struct rtw89_dev *rtwdev) +{ + rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_IMR=0x%08x ", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_IMR=0x%08x ", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); +} + +static void rtw89_mac_dump_qta_lost_ax(struct rtw89_dev *rtwdev) +{ + struct rtw89_mac_dle_dfi_qempty qempty; + struct rtw89_mac_dle_dfi_quota quota; + struct rtw89_mac_dle_dfi_ctrl ctrl; + u32 val, not_empty, i; + int ret; + + qempty.dle_type = DLE_CTRL_TYPE_PLE; + qempty.grpsel = 0; + qempty.qempty = ~(u32)0; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty); + + for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) { + if (!(not_empty & BIT(0))) + continue; + ctrl.type = DLE_CTRL_TYPE_PLE; + ctrl.target = DLE_DFI_TYPE_QLNKTBL; + ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) | + u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK); + ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i, + u32_get_bits(ctrl.out_data, + QLNKTBL_DATA_SEL1_PKT_CNT_MASK)); + } + + quota.dle_type = DLE_CTRL_TYPE_PLE; + quota.qtaid = 6; + ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, "a); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n", + quota.rsv_pgnum, quota.use_pgnum); + + val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n", + u32_get_bits(val, B_AX_PLE_Q6_MIN_SIZE_MASK)); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n", + u32_get_bits(val, B_AX_PLE_Q6_MAX_SIZE_MASK)); + val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n", + u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK)); + rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG)); + rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0)); + rtw89_info(rtwdev, "R_AX_CCA_CONTROL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CCA_CONTROL)); + + if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) { + quota.dle_type = DLE_CTRL_TYPE_PLE; + quota.qtaid = 7; + ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, "a); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n", + quota.rsv_pgnum, quota.use_pgnum); + + val = rtw89_read32(rtwdev, R_AX_PLE_QTA7_CFG); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n", + u32_get_bits(val, B_AX_PLE_Q7_MIN_SIZE_MASK)); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n", + u32_get_bits(val, B_AX_PLE_Q7_MAX_SIZE_MASK)); + val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT_C1); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n", + u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK)); + rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG_C1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG_C1)); + rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0_C1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0_C1)); + rtw89_info(rtwdev, "R_AX_CCA_CONTROL_C1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CCA_CONTROL_C1)); + } + + rtw89_info(rtwdev, "R_AX_DLE_EMPTY0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DLE_EMPTY0)); + rtw89_info(rtwdev, "R_AX_DLE_EMPTY1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DLE_EMPTY1)); + + dump_err_status_dispatcher_ax(rtwdev); +} + +void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, + enum mac_ax_err_info err) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 dbg, event; + + dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO); + event = u32_get_bits(dbg, B_AX_L0_TO_L1_EVENT_MASK); + + switch (event) { + case MAC_AX_L0_TO_L1_RX_QTA_LOST: + rtw89_info(rtwdev, "quota lost!\n"); + mac->dump_qta_lost(rtwdev); + break; + default: + break; + } +} + +void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 dmac_err; + int i, ret; + + ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); + if (ret) { + rtw89_warn(rtwdev, "[DMAC] : DMAC not enabled\n"); + return; + } + + dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); + rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); + rtw89_info(rtwdev, "R_AX_DMAC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); + + if (dmac_err) { + rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); + rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); + rtw89_info(rtwdev, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); + rtw89_info(rtwdev, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); + rtw89_info(rtwdev, "R_AX_PLE_DBGERR_STS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); + } + } + + if (dmac_err & B_AX_WDRLS_ERR_FLAG) { + rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); + if (chip->chip_id == RTL8852C) + rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); + else + rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); + } + + if (dmac_err & B_AX_WSEC_ERR_FLAG) { + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); + rtw89_info(rtwdev, "R_AX_SEC_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); + rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + rtw89_info(rtwdev, "R_AX_SEC_DEBUG1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); + rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + + rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, + B_AX_DBG_SEL0, 0x8B); + rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, + B_AX_DBG_SEL1, 0x8B); + rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, + B_AX_SEL_0XC0_MASK, 1); + for (i = 0; i < 0x10; i++) { + rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL, + B_AX_SEC_DBG_PORT_FIELD_MASK, i); + rtw89_info(rtwdev, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", + i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); + } + } else if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_SEC_ERROR_FLAG=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_ERROR_FLAG)); + rtw89_info(rtwdev, "R_BE_SEC_ERROR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_ERROR_IMR)); + rtw89_info(rtwdev, "R_BE_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_ENG_CTRL)); + rtw89_info(rtwdev, "R_BE_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_MPDU_PROC)); + rtw89_info(rtwdev, "R_BE_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_CAM_ACCESS)); + rtw89_info(rtwdev, "R_BE_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_CAM_RDATA)); + rtw89_info(rtwdev, "R_BE_SEC_DEBUG2=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SEC_DEBUG2)); + } else { + rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); + rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + rtw89_info(rtwdev, "R_AX_SEC_CAM_WDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); + rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + rtw89_info(rtwdev, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); + rtw89_info(rtwdev, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); + } + } + + if (dmac_err & B_AX_MPDU_ERR_FLAG) { + rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); + } + + if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { + if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_INTERRUPT_MASK_REG=0x%08x\n", + rtw89_read32(rtwdev, R_BE_INTERRUPT_MASK_REG)); + rtw89_info(rtwdev, "R_BE_INTERRUPT_STS_REG=0x%08x\n", + rtw89_read32(rtwdev, R_BE_INTERRUPT_STS_REG)); + } else { + rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); + } + } + + if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { + rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + } + + if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { + if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); + rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); + rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); + rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); + } else { + rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); + rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); + } + } + + if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { + rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); + rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); + rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); + rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); + rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); + rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); + if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_3=0x%08x\n", + rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_3)); + rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_STATUS)); + rtw89_info(rtwdev, "R_BE_PLE_CPUQ_OP_3=0x%08x\n", + rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_3)); + rtw89_info(rtwdev, "R_BE_PL_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_STATUS)); + } else { + rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); + rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL0)); + rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL1)); + rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL2)); + } else { + rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); + rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); + rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); + } + } + } + + if (dmac_err & B_AX_PKTIN_ERR_FLAG) { + rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); + } + + if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { + if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1)); + rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2)); + rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0)); + } else { + rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); + } + } + + if (dmac_err & B_AX_BBRPT_ERR_FLAG) { + if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + } else { + rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); + rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + } + if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_IMR)); + rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_ISR)); + } + } + + if (dmac_err & B_AX_HAXIDMA_ERR_FLAG) { + if (chip->chip_id == RTL8922A) { + rtw89_info(rtwdev, "R_BE_HAXI_IDCT_MSK=0x%08x\n", + rtw89_read32(rtwdev, R_BE_HAXI_IDCT_MSK)); + rtw89_info(rtwdev, "R_BE_HAXI_IDCT=0x%08x\n", + rtw89_read32(rtwdev, R_BE_HAXI_IDCT)); + } else if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); + rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); + } + } + + if (dmac_err & B_BE_P_AXIDMA_ERR_INT) { + rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT_MSK=0x%08x\n", + rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT_MSK, + RTW89_MAC_MEM_AXIDMA)); + rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT=0x%08x\n", + rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT, + RTW89_MAC_MEM_AXIDMA)); + } + + if (dmac_err & B_BE_MLO_ERR_INT) { + rtw89_info(rtwdev, "R_BE_MLO_ERR_IDCT_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_IMR)); + rtw89_info(rtwdev, "R_BE_PKTIN_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_ISR)); + } + + if (dmac_err & B_BE_PLRLS_ERR_INT) { + rtw89_info(rtwdev, "R_BE_PLRLS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_PLRLS_ERR_IMR)); + rtw89_info(rtwdev, "R_BE_PLRLS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_BE_PLRLS_ERR_ISR)); + } +} + +static void rtw89_mac_dump_cmac_err_status_ax(struct rtw89_dev *rtwdev, + u8 band) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 offset = 0; + u32 cmac_err; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); + if (ret) { + if (band) + rtw89_warn(rtwdev, "[CMAC] : CMAC1 not enabled\n"); + else + rtw89_warn(rtwdev, "[CMAC] : CMAC0 not enabled\n"); + return; + } + + if (band) + offset = RTW89_MAC_AX_BAND_REG_OFFSET; + + cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); + rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); + rtw89_info(rtwdev, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); + rtw89_info(rtwdev, "R_AX_CK_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CK_EN + offset)); + + if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { + rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); + rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); + } + + if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { + rtw89_info(rtwdev, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); + rtw89_info(rtwdev, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); + } + + if (cmac_err & B_AX_DMA_TOP_ERR_IND) { + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); + rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); + } else { + rtw89_info(rtwdev, "R_AX_DLE_CTRL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); + } + } + + if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) { + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); + rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + } else { + rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + } + } + + if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { + rtw89_info(rtwdev, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); + rtw89_info(rtwdev, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); + } + + if (cmac_err & B_AX_WMAC_TX_ERR_IND) { + if (chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); + rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); + } else { + rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); + } + rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); + } + + rtw89_info(rtwdev, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); +} + +static void rtw89_mac_dump_err_status_ax(struct rtw89_dev *rtwdev, + enum mac_ax_err_info err) +{ + if (err != MAC_AX_ERR_L1_ERR_DMAC && + err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && + err != MAC_AX_ERR_L0_ERR_CMAC0 && + err != MAC_AX_ERR_L0_ERR_CMAC1 && + err != MAC_AX_ERR_RXI300) + return; + + rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); + rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", + rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); + rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", + rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); + rtw89_info(rtwdev, "DBG Counter 1 (R_AX_DRV_FW_HSK_4)=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_4)); + rtw89_info(rtwdev, "DBG Counter 2 (R_AX_DRV_FW_HSK_5)=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_5)); + + rtw89_mac_dump_dmac_err_status(rtwdev); + rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_0); + rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_1); + + rtwdev->hci.ops->dump_err_status(rtwdev); + + if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) + rtw89_mac_dump_l0_to_l1(rtwdev, err); + + rtw89_info(rtwdev, "<---\n"); +} + +static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err) +{ + struct rtw89_ser *ser = &rtwdev->ser; + u32 dmac_err, imr, isr; + int ret; + + if (rtwdev->chip->chip_id == RTL8852C) { + ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); + if (ret) + return true; + + if (err == MAC_AX_ERR_L1_ERR_DMAC) { + dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); + imr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR); + isr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR); + + if ((dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) && + ((isr & imr) & B_AX_B0_ISR_ERR_CMDPSR_FRZTO)) { + set_bit(RTW89_SER_SUPPRESS_LOG, ser->flags); + return true; + } + } else if (err == MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE) { + if (test_bit(RTW89_SER_SUPPRESS_LOG, ser->flags)) + return true; + } else if (err == MAC_AX_ERR_L1_RESET_RECOVERY_DONE) { + if (test_and_clear_bit(RTW89_SER_SUPPRESS_LOG, ser->flags)) + return true; + } + } + + return false; +} + +u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 err, err_scnr; + int ret; + + ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000, + false, rtwdev, R_AX_HALT_C2H_CTRL); + if (ret) { + rtw89_warn(rtwdev, "Polling FW err status fail\n"); + return ret; + } + + err = rtw89_read32(rtwdev, R_AX_HALT_C2H); + + if (!RTW89_CHK_FW_FEATURE(SER_POST_RECOVER_DMAC, &rtwdev->fw)) + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + + err_scnr = RTW89_ERROR_SCENARIO(err); + if (err_scnr == RTW89_WCPU_CPU_EXCEPTION) + err = MAC_AX_ERR_CPU_EXCEPTION; + else if (err_scnr == RTW89_WCPU_ASSERTION) + err = MAC_AX_ERR_ASSERTION; + else if (err_scnr == RTW89_RXI300_ERROR) + err = MAC_AX_ERR_RXI300; + + if (rtw89_mac_suppress_log(rtwdev, err)) + goto bottom; + + rtw89_fw_st_dbg_dump(rtwdev); + mac->dump_err_status(rtwdev, err); + +bottom: + if (chip->chip_gen != RTW89_CHIP_AX) + rtw89_write32(rtwdev, R_AX_HALT_C2H, 0); + + if (RTW89_CHK_FW_FEATURE(SER_POST_RECOVER_DMAC, &rtwdev->fw)) + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + + return err; +} +EXPORT_SYMBOL(rtw89_mac_get_err_status); + +int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) +{ + struct rtw89_ser *ser = &rtwdev->ser; + bool ser_l1_hdl = false; + u32 halt; + int ret = 0; + + if (err > MAC_AX_SET_ERR_MAX) { + rtw89_err(rtwdev, "Bad set-err-status value 0x%08x\n", err); + return -EINVAL; + } + + if (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN) + ser_l1_hdl = true; + + if (RTW89_CHK_FW_FEATURE(SER_L1_BY_EVENT, &rtwdev->fw) && ser_l1_hdl) + goto set; + + ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000, + 100000, false, rtwdev, R_AX_HALT_H2C_CTRL); + if (ret) { + rtw89_err(rtwdev, "FW doesn't receive previous msg\n"); + return -EFAULT; + } + +set: + rtw89_write32(rtwdev, R_AX_HALT_H2C, err); + + if (ser->prehandle_l1 && ser_l1_hdl) + return 0; + + rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_set_err_status); + +static int hfc_reset_param(struct rtw89_dev *rtwdev) +{ + const struct rtw89_qta_def *qta_def = rtw89_chip_get_qta_def(rtwdev); + const struct rtw89_hfc_param_ini *param_ini, *param_inis; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + u8 qta_mode = rtwdev->mac.dle_info.qta_mode; + + param_inis = qta_def->hfc_param_ini[rtwdev->hci.dle_type]; + if (!param_inis) + return -EINVAL; + + param_ini = ¶m_inis[qta_mode]; + + param->en = 0; + + if (param_ini->pub_cfg) + param->pub_cfg = *param_ini->pub_cfg; + + if (param_ini->prec_cfg) + param->prec_cfg = *param_ini->prec_cfg; + + if (param_ini->ch_cfg) + param->ch_cfg = param_ini->ch_cfg; + + memset(¶m->ch_info, 0, sizeof(param->ch_info)); + memset(¶m->pub_info, 0, sizeof(param->pub_info)); + param->mode = param_ini->mode; + + return 0; +} + +static int hfc_ch_cfg_chk(struct rtw89_dev *rtwdev, u8 ch) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_ch_cfg *ch_cfg = param->ch_cfg; + const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + + if (ch >= RTW89_DMA_CH_NUM) + return -EINVAL; + + if ((ch_cfg[ch].min && ch_cfg[ch].min < prec_cfg->ch011_prec) || + ch_cfg[ch].max > pub_cfg->pub_max) + return -EINVAL; + if (ch_cfg[ch].grp >= grp_num) + return -EINVAL; + + return 0; +} + +static int hfc_pub_info_chk(struct rtw89_dev *rtwdev) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_pub_cfg *cfg = ¶m->pub_cfg; + struct rtw89_hfc_pub_info *info = ¶m->pub_info; + + if (info->g0_used + info->g1_used + info->pub_aval != cfg->pub_max) { + if (rtwdev->chip->chip_id == RTL8852A) + return 0; + else + return -EFAULT; + } + + return 0; +} + +static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + + if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max) + return -EFAULT; + + return 0; +} + +static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; + int ret = 0; + u32 val = 0; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + ret = hfc_ch_cfg_chk(rtwdev, ch); + if (ret) + return ret; + + if (ch > RTW89_DMA_B1HI) + return -EINVAL; + + val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) | + u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) | + (cfg[ch].grp ? B_AX_GRP : 0); + rtw89_write32(rtwdev, regs->ach_page_ctrl + ch * 4, val); + + return 0; +} + +static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + struct rtw89_hfc_ch_info *info = param->ch_info; + const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; + u32 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + if (ch > RTW89_DMA_H2C) + return -EINVAL; + + val = rtw89_read32(rtwdev, regs->ach_page_info + ch * 4); + info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK); + if (ch < RTW89_DMA_H2C) + info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK); + else + info[ch].used = cfg[ch].min - info[ch].aval; + + return 0; +} + +static int hfc_pub_ctrl(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg; + u32 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + ret = hfc_pub_cfg_chk(rtwdev); + if (ret) + return ret; + + val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) | + u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK); + rtw89_write32(rtwdev, regs->pub_page_ctrl1, val); + + val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK); + rtw89_write32(rtwdev, regs->wp_page_ctrl2, val); + + return 0; +} + +static void hfc_get_mix_info_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + struct rtw89_hfc_pub_info *info = ¶m->pub_info; + u32 val; + + val = rtw89_read32(rtwdev, regs->pub_page_info1); + info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK); + info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK); + val = rtw89_read32(rtwdev, regs->pub_page_info3); + info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK); + info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK); + info->pub_aval = + u32_get_bits(rtw89_read32(rtwdev, regs->pub_page_info2), + B_AX_PUB_AVAL_PG_MASK); + info->wp_aval = + u32_get_bits(rtw89_read32(rtwdev, regs->wp_page_info1), + B_AX_WP_AVAL_PG_MASK); + + val = rtw89_read32(rtwdev, regs->hci_fc_ctrl); + param->en = val & B_AX_HCI_FC_EN ? 1 : 0; + param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0; + param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK); + prec_cfg->ch011_full_cond = + u32_get_bits(val, B_AX_HCI_FC_WD_FULL_COND_MASK); + prec_cfg->h2c_full_cond = + u32_get_bits(val, B_AX_HCI_FC_CH12_FULL_COND_MASK); + prec_cfg->wp_ch07_full_cond = + u32_get_bits(val, B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); + prec_cfg->wp_ch811_full_cond = + u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); + + val = rtw89_read32(rtwdev, regs->ch_page_ctrl); + prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK); + prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK); + + val = rtw89_read32(rtwdev, regs->pub_page_ctrl2); + pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK); + + val = rtw89_read32(rtwdev, regs->wp_page_ctrl1); + prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK); + prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK); + + val = rtw89_read32(rtwdev, regs->wp_page_ctrl2); + pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK); + + val = rtw89_read32(rtwdev, regs->pub_page_ctrl1); + pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK); + pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK); +} + +static int hfc_upd_mix_info(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + mac->hfc_get_mix_info(rtwdev); + + ret = hfc_pub_info_chk(rtwdev); + if (param->en && ret) + return ret; + + return 0; +} + +static void hfc_h2c_cfg_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + u32 val; + + val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); + rtw89_write32(rtwdev, regs->ch_page_ctrl, val); + + rtw89_write32_mask(rtwdev, regs->hci_fc_ctrl, + B_AX_HCI_FC_CH12_FULL_COND_MASK, + prec_cfg->h2c_full_cond); +} + +static void hfc_mix_cfg_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + u32 val; + + val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) | + u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); + rtw89_write32(rtwdev, regs->ch_page_ctrl, val); + + val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK); + rtw89_write32(rtwdev, regs->pub_page_ctrl2, val); + + val = u32_encode_bits(prec_cfg->wp_ch07_prec, + B_AX_PREC_PAGE_WP_CH07_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_prec, + B_AX_PREC_PAGE_WP_CH811_MASK); + rtw89_write32(rtwdev, regs->wp_page_ctrl1, val); + + val = u32_replace_bits(rtw89_read32(rtwdev, regs->hci_fc_ctrl), + param->mode, B_AX_HCI_FC_MODE_MASK); + val = u32_replace_bits(val, prec_cfg->ch011_full_cond, + B_AX_HCI_FC_WD_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->h2c_full_cond, + B_AX_HCI_FC_CH12_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond, + B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond, + B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); + rtw89_write32(rtwdev, regs->hci_fc_ctrl, val); +} + +static void hfc_func_en_ax(struct rtw89_dev *rtwdev, bool en, bool h2c_en) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_page_regs *regs = chip->page_regs; + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + u32 val; + + val = rtw89_read32(rtwdev, regs->hci_fc_ctrl); + param->en = en; + param->h2c_en = h2c_en; + val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN); + val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) : + (val & ~B_AX_HCI_FC_CH12_EN); + rtw89_write32(rtwdev, regs->hci_fc_ctrl, val); +} + +int rtw89_mac_hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 dma_ch_mask = chip->dma_ch_mask; + int ret = 0; + u8 ch; + + if (reset) + ret = hfc_reset_param(rtwdev); + if (ret) + return ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + mac->hfc_func_en(rtwdev, false, false); + + if (!en && h2c_en) { + mac->hfc_h2c_cfg(rtwdev); + mac->hfc_func_en(rtwdev, en, h2c_en); + return 0; + } + + for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { + if (dma_ch_mask & BIT(ch)) + continue; + ret = hfc_ch_ctrl(rtwdev, ch); + if (ret) + return ret; + } + + ret = hfc_pub_ctrl(rtwdev); + if (ret) + return ret; + + mac->hfc_mix_cfg(rtwdev); + if (en || h2c_en) { + mac->hfc_func_en(rtwdev, en, h2c_en); + udelay(10); + } + for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { + if (dma_ch_mask & BIT(ch)) + continue; + ret = hfc_upd_ch_info(rtwdev, ch); + if (ret) + return ret; + } + ret = hfc_upd_mix_info(rtwdev); + + return ret; +} + +#define PWR_POLL_CNT 2000 +static int pwr_cmd_poll(struct rtw89_dev *rtwdev, + const struct rtw89_pwr_cfg *cfg) +{ + u8 val = 0; + int ret; + u32 addr = cfg->base == PWR_INTF_MSK_SDIO ? + cfg->addr | SDIO_LOCAL_BASE_ADDR : cfg->addr; + + ret = read_poll_timeout(rtw89_read8, val, !((val ^ cfg->val) & cfg->msk), + 1000, 1000 * PWR_POLL_CNT, false, rtwdev, addr); + + if (!ret) + return 0; + + rtw89_warn(rtwdev, "[ERR] Polling timeout\n"); + rtw89_warn(rtwdev, "[ERR] addr: %X, %X\n", addr, cfg->addr); + rtw89_warn(rtwdev, "[ERR] val: %X, %X\n", val, cfg->val); + + return -EBUSY; +} + +static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk, + u8 intf_msk, const struct rtw89_pwr_cfg *cfg) +{ + const struct rtw89_pwr_cfg *cur_cfg; + u32 addr; + u8 val; + + for (cur_cfg = cfg; cur_cfg->cmd != PWR_CMD_END; cur_cfg++) { + if (!(cur_cfg->intf_msk & intf_msk) || + !(cur_cfg->cv_msk & cv_msk)) + continue; + + switch (cur_cfg->cmd) { + case PWR_CMD_WRITE: + addr = cur_cfg->addr; + + if (cur_cfg->base == PWR_BASE_SDIO) + addr |= SDIO_LOCAL_BASE_ADDR; + + val = rtw89_read8(rtwdev, addr); + val &= ~(cur_cfg->msk); + val |= (cur_cfg->val & cur_cfg->msk); + + rtw89_write8(rtwdev, addr, val); + break; + case PWR_CMD_POLL: + if (pwr_cmd_poll(rtwdev, cur_cfg)) + return -EBUSY; + break; + case PWR_CMD_DELAY: + if (cur_cfg->val == PWR_DELAY_US) + udelay(cur_cfg->addr); + else + fsleep(cur_cfg->addr * 1000); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev, + const struct rtw89_pwr_cfg * const *cfg_seq) +{ + u8 intf_msk; + int ret; + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + intf_msk = PWR_INTF_MSK_PCIE; + break; + case RTW89_HCI_TYPE_USB: + intf_msk = PWR_INTF_MSK_USB; + break; + case RTW89_HCI_TYPE_SDIO: + intf_msk = PWR_INTF_MSK_SDIO; + break; + default: + return -EOPNOTSUPP; + } + + for (; *cfg_seq; cfg_seq++) { + ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv), + intf_msk, *cfg_seq); + if (ret) + return -EBUSY; + } + + return 0; +} + +static enum rtw89_rpwm_req_pwr_state +rtw89_mac_get_req_pwr_state(struct rtw89_dev *rtwdev) +{ + enum rtw89_rpwm_req_pwr_state state; + + switch (rtwdev->ps_mode) { + case RTW89_PS_MODE_RFOFF: + state = RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF; + break; + case RTW89_PS_MODE_CLK_GATED: + state = RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED; + break; + case RTW89_PS_MODE_PWR_GATED: + state = RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED; + break; + default: + state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; + break; + } + return state; +} + +static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev, + enum rtw89_rpwm_req_pwr_state req_pwr_state, + bool notify_wake) +{ + u16 request; + + spin_lock_bh(&rtwdev->rpwm_lock); + + request = rtw89_read16(rtwdev, R_AX_RPWM); + request ^= request | PS_RPWM_TOGGLE; + request |= req_pwr_state; + + if (notify_wake) { + request |= PS_RPWM_NOTIFY_WAKE; + } else { + rtwdev->mac.rpwm_seq_num = (rtwdev->mac.rpwm_seq_num + 1) & + RPWM_SEQ_NUM_MAX; + request |= FIELD_PREP(PS_RPWM_SEQ_NUM, + rtwdev->mac.rpwm_seq_num); + + if (req_pwr_state < RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) + request |= PS_RPWM_ACK; + } + rtw89_write16(rtwdev, rtwdev->hci.rpwm_addr, request); + + spin_unlock_bh(&rtwdev->rpwm_lock); +} + +static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev, + enum rtw89_rpwm_req_pwr_state req_pwr_state) +{ + bool request_deep_mode; + bool in_deep_mode; + u8 rpwm_req_num; + u8 cpwm_rsp_seq; + u8 cpwm_seq; + u8 cpwm_status; + + if (req_pwr_state >= RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) + request_deep_mode = true; + else + request_deep_mode = false; + + if (rtw89_read32_mask(rtwdev, R_AX_LDM, B_AX_EN_32K)) + in_deep_mode = true; + else + in_deep_mode = false; + + if (request_deep_mode != in_deep_mode) + return -EPERM; + + if (request_deep_mode) + return 0; + + rpwm_req_num = rtwdev->mac.rpwm_seq_num; + cpwm_rsp_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, + PS_CPWM_RSP_SEQ_NUM); + + if (rpwm_req_num != cpwm_rsp_seq) + return -EPERM; + + rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) & + CPWM_SEQ_NUM_MAX; + + cpwm_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_SEQ_NUM); + if (cpwm_seq != rtwdev->mac.cpwm_seq_num) + return -EPERM; + + cpwm_status = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_STATE); + if (cpwm_status != req_pwr_state) + return -EPERM; + + return 0; +} + +void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter) +{ + enum rtw89_rpwm_req_pwr_state state; + unsigned long delay = enter ? 10 : 150; + int ret; + int i; + + if (enter) + state = rtw89_mac_get_req_pwr_state(rtwdev); + else + state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; + + for (i = 0; i < RPWM_TRY_CNT; i++) { + rtw89_mac_send_rpwm(rtwdev, state, false); + ret = read_poll_timeout_atomic(rtw89_mac_check_cpwm_state, ret, + !ret, delay, 15000, false, + rtwdev, state); + if (!ret) + break; + + if (i == RPWM_TRY_CNT - 1) { + rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n", + enter ? "entering" : "leaving"); + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); + } else { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "%d time firmware failed to ack for %s ps mode\n", + i + 1, enter ? "entering" : "leaving"); + } + } +} + +void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev) +{ + enum rtw89_rpwm_req_pwr_state state; + + state = rtw89_mac_get_req_pwr_state(rtwdev); + rtw89_mac_send_rpwm(rtwdev, state, true); +} + +static void rtw89_mac_power_switch_boot_mode(struct rtw89_dev *rtwdev) +{ + u32 boot_mode; + + if (rtwdev->hci.type != RTW89_HCI_TYPE_USB) + return; + + boot_mode = rtw89_read32_mask(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE); + if (!boot_mode) + return; + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); + rtw89_write32_clr(rtwdev, R_AX_SYS_STATUS1, B_AX_AUTO_WLPON); + rtw89_write32_clr(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE); + rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); +} + +static int rtw89_mac_pwr_off_func_for_unplugged(struct rtw89_dev *rtwdev) +{ + /* + * Avoid accessing IO for unplugged power-off to prevent warnings, + * especially XTAL SI. + */ + return 0; +} + +static void rtw89_mac_update_scoreboard(struct rtw89_dev *rtwdev, u8 val) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(chip->btc_sb.n); i++) { + reg = chip->btc_sb.n[i].cfg; + if (!reg) + continue; + + rtw89_write8(rtwdev, reg + 3, val); + } +} + +static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_pwr_cfg * const *cfg_seq; + int (*cfg_func)(struct rtw89_dev *rtwdev); + int ret; + + rtw89_mac_power_switch_boot_mode(rtwdev); + + if (on) { + cfg_seq = chip->pwr_on_seq; + cfg_func = chip->ops->pwr_on_func; + } else { + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) { + cfg_seq = NULL; + cfg_func = rtw89_mac_pwr_off_func_for_unplugged; + } else { + cfg_seq = chip->pwr_off_seq; + cfg_func = chip->ops->pwr_off_func; + } + } + + if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + __rtw89_leave_ps_mode(rtwdev); + + if (on) { + ret = mac->reset_pwr_state(rtwdev); + if (ret) + return ret; + } + + ret = cfg_func ? cfg_func(rtwdev) : rtw89_mac_pwr_seq(rtwdev, cfg_seq); + if (ret) + return ret; + + if (on) { + if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags)) { + rtw89_mac_efuse_read_ecv(rtwdev); + mac->efuse_read_fw_secure(rtwdev); + rtw89_mac_efuse_read_thermal_k(rtwdev); + rtw89_mac_efuse_read_pwr_data(rtwdev); + } + + set_bit(RTW89_FLAG_POWERON, rtwdev->flags); + set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); + set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); + + rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_TP_MAJOR); + rtw89_mac_clr_aon_intr(rtwdev); + } else { + clear_bit(RTW89_FLAG_POWERON, rtwdev->flags); + clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); + clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); + + rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_PWR_MAJOR); + rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false); + rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false); + } + + return 0; +} + +int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_mac_power_switch(rtwdev, true); + if (ret) { + rtw89_mac_power_switch(rtwdev, false); + ret = rtw89_mac_power_switch(rtwdev, true); + if (ret) + return ret; + } + + return 0; +} + +void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev) +{ + rtw89_mac_set_vcore_reset(rtwdev); + + rtw89_mac_power_switch(rtwdev, false); +} + +static int cmac_func_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) +{ + u32 func_en = 0; + u32 ck_en = 0; + u32 c1pc_en = 0; + u32 addrl_func_en[] = {R_AX_CMAC_FUNC_EN, R_AX_CMAC_FUNC_EN_C1}; + u32 addrl_ck_en[] = {R_AX_CK_EN, R_AX_CK_EN_C1}; + + func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | + B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | + B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN | + B_AX_CMAC_CRPRT; + ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN | + B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN | + B_AX_RMAC_CKEN; + c1pc_en = B_AX_R_SYM_WLCMAC1_PC_EN | + B_AX_R_SYM_WLCMAC1_P1_PC_EN | + B_AX_R_SYM_WLCMAC1_P2_PC_EN | + B_AX_R_SYM_WLCMAC1_P3_PC_EN | + B_AX_R_SYM_WLCMAC1_P4_PC_EN; + + if (en) { + if (mac_idx == RTW89_MAC_1) { + rtw89_write32_set(rtwdev, R_AX_AFE_CTRL1, c1pc_en); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_R_SYM_ISO_CMAC12PP); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_CMAC1_FEN); + } + rtw89_write32_set(rtwdev, addrl_ck_en[mac_idx], ck_en); + rtw89_write32_set(rtwdev, addrl_func_en[mac_idx], func_en); + } else { + rtw89_write32_clr(rtwdev, addrl_func_en[mac_idx], func_en); + rtw89_write32_clr(rtwdev, addrl_ck_en[mac_idx], ck_en); + if (mac_idx == RTW89_MAC_1) { + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_CMAC1_FEN); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_R_SYM_ISO_CMAC12PP); + rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, c1pc_en); + } + } + + return 0; +} + +static int dmac_func_en_ax(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val32; + + if (chip_id == RTL8852C) + val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | + B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN | + B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN | + B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN | + B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN | + B_AX_DMAC_CRPRT | B_AX_H_AXIDMA_EN); + else + val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | + B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN | + B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN | + B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN | + B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN | + B_AX_DMAC_CRPRT); + rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val32); + + val32 = (B_AX_MAC_SEC_CLK_EN | B_AX_DISPATCHER_CLK_EN | + B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN | + B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN | + B_AX_WD_RLS_CLK_EN | B_AX_BBRPT_CLK_EN); + if (chip_id == RTL8852BT) + val32 |= B_AX_AXIDMA_CLK_EN; + rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32); + + return 0; +} + +static int chip_func_en_ax(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + rtw89_write32_set(rtwdev, R_AX_SPS_DIG_ON_CTRL0, + B_AX_OCP_L1_MASK); + + return 0; +} + +static int sys_init_ax(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = dmac_func_en_ax(rtwdev); + if (ret) + return ret; + + ret = cmac_func_en_ax(rtwdev, 0, true); + if (ret) + return ret; + + return chip_func_en_ax(rtwdev); +} + +const struct rtw89_mac_size_set rtw89_mac_size = { + .hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0}, + .hfc_prec_cfg_c0 = {2, 32, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0}, + .hfc_prec_cfg_c2 = {0, 256, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0}, + .hfc_prec_cfg_c3 = {18, 32, 148, 148, 1, 1, 1, 1}, + .hfc_prec_cfg_c5 = {18, 32, 148, 148, 1, 1, 0, 1}, + .hfc_prec_cfg_c6 = {8, 32, 148, 148, 1, 1, 0, 1}, + /* PCIE 64 */ + .wde_size0 = {RTW89_WDE_PG_64, 4095, 1,}, + .wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,}, + /* 8852A USB */ + .wde_size1 = {RTW89_WDE_PG_64, 768, 0,}, + /* DLFW */ + .wde_size3_v1 = {RTW89_WDE_PG_64, 0, 3328, 0,}, + .wde_size4 = {RTW89_WDE_PG_64, 0, 4096,}, + /* 8922A USB3.0 */ + .wde_size4_v1 = {RTW89_WDE_PG_64, 892, 4, 0,}, + .wde_size5_v1 = {RTW89_WDE_PG_64, 864, 32, 0,}, + /* PCIE 64 */ + .wde_size6 = {RTW89_WDE_PG_64, 512, 0,}, + /* 8852B PCIE SCC */ + .wde_size7 = {RTW89_WDE_PG_64, 510, 2,}, + /* 8922A USB2.0 */ + .wde_size7_v1 = {RTW89_WDE_PG_64, 508, 4,}, + .wde_size8_v1 = {RTW89_WDE_PG_64, 634, 6,}, + /* DLFW */ + .wde_size9 = {RTW89_WDE_PG_64, 0, 1024,}, + .wde_size16_v1 = {RTW89_WDE_PG_64, 639, 1, 0,}, + /* 8852C USB3.0 */ + .wde_size17 = {RTW89_WDE_PG_64, 354, 30,}, + /* 8852C DLFW */ + .wde_size18 = {RTW89_WDE_PG_64, 0, 2048,}, + .wde_size18_v1 = {RTW89_WDE_PG_64, 0, 640, 0,}, + /* 8852C PCIE SCC */ + .wde_size19 = {RTW89_WDE_PG_64, 3328, 0,}, + .wde_size22_v1 = {RTW89_WDE_PG_128, 384, 0, 0,}, + .wde_size23 = {RTW89_WDE_PG_64, 1022, 2,}, + /* 8852B USB2.0/USB3.0 SCC turbo */ + .wde_size30 = {RTW89_WDE_PG_64, 220, 36,}, + /* 8852C USB2.0 */ + .wde_size31 = {RTW89_WDE_PG_64, 384, 0,}, + /* PCIE */ + .ple_size0 = {RTW89_PLE_PG_128, 1520, 16,}, + .ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,}, + /* 8852A USB */ + .ple_size1 = {RTW89_PLE_PG_128, 3184, 16,}, + .ple_size3_v1 = {RTW89_PLE_PG_128, 2928, 0, 212992,}, + /* DLFW */ + .ple_size4 = {RTW89_PLE_PG_128, 64, 1472,}, + /* 8922A USB3.0 */ + .ple_size4_v1 = {RTW89_PLE_PG_256, 1963, 109, 57344,}, + /* PCIE 64 */ + .ple_size6 = {RTW89_PLE_PG_128, 496, 16,}, + /* 8922A USB2.0 */ + .ple_size6_v1 = {RTW89_PLE_PG_256, 2059, 109, 32768,}, + .ple_size7_v1 = {RTW89_PLE_PG_256, 2027, 109, 40960,}, + /* DLFW */ + .ple_size8 = {RTW89_PLE_PG_128, 64, 960,}, + .ple_size9 = {RTW89_PLE_PG_128, 2288, 16,}, + /* 8852C USB */ + .ple_size17 = {RTW89_PLE_PG_128, 3368, 24,}, + /* 8852C DLFW */ + .ple_size18 = {RTW89_PLE_PG_128, 2544, 16,}, + /* 8852C PCIE SCC */ + .ple_size19 = {RTW89_PLE_PG_128, 1904, 16,}, + .ple_size20_v1 = {RTW89_PLE_PG_128, 2554, 182, 40960,}, + .ple_size22_v1 = {RTW89_PLE_PG_128, 2736, 0, 40960,}, + /* 8851B USB2.0 SCC turbo */ + .ple_size27 = {RTW89_PLE_PG_128, 1396, 12,}, + .ple_size29_v1 = {RTW89_PLE_PG_128, 1895, 182, 49152,}, + /* 8852B USB3.0 SCC turbo */ + .ple_size31 = {RTW89_PLE_PG_128, 1392, 16,}, + /* 8852C USB2.0 */ + .ple_size34 = {RTW89_PLE_PG_128, 3374, 18,}, + /* PCIE 64 */ + .wde_qt0 = {3792, 196, 0, 107,}, + .wde_qt0_v1 = {3302, 6, 0, 20,}, + /* 8852A USB */ + .wde_qt1 = {512, 196, 0, 60,}, + .wde_qt3 = {0, 0, 0, 0,}, + /* DLFW */ + .wde_qt4 = {0, 0, 0, 0,}, + /* 8922A USB3.0 */ + .wde_qt4_v1 = {876, 6, 0, 10,}, + .wde_qt5_v1 = {838, 6, 0, 20,}, + /* PCIE 64 */ + .wde_qt6 = {448, 48, 0, 16,}, + /* 8852B PCIE SCC */ + .wde_qt7 = {446, 48, 0, 16,}, + /* 8922A USB2.0 */ + .wde_qt7_v1 = {492, 6, 0, 10,}, + .wde_qt8_v1 = {608, 6, 0, 20,}, + /* 8852C USB3.0 */ + .wde_qt16 = {344, 2, 0, 8,}, + /* 8852C DLFW */ + .wde_qt17 = {0, 0, 0, 0,}, + /* 8852C PCIE SCC */ + .wde_qt18 = {3228, 60, 0, 40,}, + .wde_qt19_v1 = {613, 6, 0, 20,}, + .wde_qt23 = {958, 48, 0, 16,}, + .wde_qt23_v1 = {371, 3, 0, 10,}, + /* 8852B USB2.0/USB3.0 SCC turbo */ + .wde_qt30 = {210, 2, 0, 8,}, + /* 8852C USB2.0 */ + .wde_qt31 = {338, 6, 0, 40,}, + .ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,}, + .ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,}, + /* PCIE SCC */ + .ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,}, + /* PCIE SCC */ + .ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,}, + .ple_qt5_v2 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,}, + /* 8922A USB3.0 */ + .ple_qt6_v1 = {1806, 0, 16, 24, 7, 14, 57, 0, 12, 9, 1, 4, 0,}, + .ple_qt7_v1 = {1806, 0, 16, 24, 20, 27, 70, 0, 25, 9, 1, 17, 0,}, + .ple_qt8_v1 = {1638, 0, 16, 24, 7, 14, 99, 99, 24, 9, 1, 4, 0,}, + /* PCIE SCC */ + .ple_qt9 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0,}, + /* 8922A USB3.0 */ + .ple_qt9_v1 = {1638, 0, 16, 24, 35, 42, 127, 127, 52, 9, 1, 32, 0,}, + /* 8922A USB2.0 */ + .ple_qt12_v1 = {463, 0, 16, 24, 7, 14, 57, 0, 12, 9, 1, 4, 0,}, + /* DLFW */ + .ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,}, + /* 8922A USB2.0 */ + .ple_qt13_v1 = {463, 0, 16, 24, 1459, 1466, 1509, 0, 1464, 9, 1, 1456, 0,}, + .ple_qt14_v1 = {939, 0, 16, 24, 7, 14, 57, 57, 24, 9, 1, 4, 0,}, + .ple_qt15_v1 = {939, 0, 16, 24, 882, 889, 932, 932, 899, 9, 1, 879, 0,}, + /* PCIE 64 */ + .ple_qt18 = {147, 0, 16, 20, 17, 13, 89, 0, 32, 14, 8, 0,}, + /* 8852A USB SCC */ + .ple_qt25 = {1536, 0, 16, 48, 13, 13, 360, 0, 32, 40, 8, 0,}, + .ple_qt26 = {2654, 0, 1134, 48, 64, 13, 1478, 0, 64, 128, 120, 0,}, + /* 8852B USB3.0 SCC turbo */ + .ple_qt27 = {1040, 0, 16, 48, 13, 13, 178, 0, 32, 14, 8, 0,}, + .ple_qt28 = {1040, 0, 32, 48, 43, 13, 208, 0, 62, 14, 24, 0,}, + /* USB 52C USB3.0 */ + .ple_qt42 = {1068, 0, 16, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, + /* USB 52C USB3.0 */ + .ple_qt43 = {3068, 0, 32, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, + /* DLFW 52C */ + .ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ple_qt44_v2 = {91, 91, 32, 16, 19, 13, 91, 91, 44, 18, 1, 4, 0, 0,}, + /* DLFW 52C */ + .ple_qt45 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ple_qt45_v2 = {645, 645, 32, 2055, 2058, 2052, 2132, 2132, 2083, 2057, 1, 2043, 0, 0,}, + /* 8852C PCIE SCC */ + .ple_qt46 = {525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,}, + /* 8852C PCIE SCC */ + .ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,}, + .ple_qt47_v2 = {0, 0, 32, 2703, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,}, + .ple_qt57 = {147, 0, 16, 20, 13, 13, 178, 0, 32, 14, 8, 0,}, + /* PCIE 64 */ + .ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,}, + .ple_qt59 = {147, 0, 32, 20, 1860, 13, 2025, 0, 1879, 14, 24, 0,}, + /* 8851B USB2.0 SCC turbo */ + .ple_qt61 = {858, 0, 16, 48, 4, 13, 370, 0, 32, 14, 8, 0, 0,}, + .ple_qt62 = {858, 0, 32, 48, 37, 13, 403, 0, 65, 14, 24, 0, 0,}, + .ple_qt64_v2 = {91, 91, 32, 16, 19, 13, 93, 93, 44, 34, 1, 4, 0, 0,}, + .ple_qt65_v2 = {645, 645, 32, 1380, 1383, 1377, 1457, 1457, 1408, 1398, 1, 1368,}, + /* USB2.0 52C */ + .ple_qt78 = {1560, 0, 16, 48, 13, 13, 390, 0, 32, 38, 8, 16, 0,}, + /* USB2.0 52C */ + .ple_qt79 = {1560, 0, 32, 48, 1253, 13, 1630, 0, 1272, 38, 120, 1256, 0,}, + /* 8852A PCIE WOW */ + .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, + /* 8852B PCIE WOW */ + .ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, + /* 8852BT PCIE WOW */ + .ple_qt_52bt_wow = {147, 0, 32, 20, 1860, 13, 1929, 0, 1879, 14, 24, 0,}, + /* 8851B PCIE WOW */ + .ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, + .ple_rsvd_qt0 = {2, 107, 107, 6, 6, 6, 6, 0, 0, 0,}, + .ple_rsvd_qt1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ple_rsvd_qt2 = {1, 56, 28, 6, 6, 6, 6, 0, 0, 0,}, + .ple_rsvd_qt9 = {1, 44, 44, 6, 6, 6, 6, 69, 0, 0,}, + .rsvd0_size0 = {212992, 0,}, + .rsvd0_size3 = {57344, 0,}, + .rsvd0_size5 = {32768, 0,}, + .rsvd0_size6 = {40960, 0,}, + .rsvd0_size17 = {49152, 0,}, + .rsvd1_size0 = {587776, 2048,}, + .rsvd1_size2 = {391168, 2048,}, + .rsvd1_size3 = {315008, 78208,}, + .dle_input3 = {0, 0, 0, 16384, 0, 2048, 0, 0, 0,}, + .dle_input20 = {128, 128, 11454, 2048, 0, 2048, 1024, 24, 24,}, + .dle_input28 = {128, 128, 11454, 2048, 0, 2048, 2048, 24, 24,}, +}; +EXPORT_SYMBOL(rtw89_mac_size); + +static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, + enum rtw89_qta_mode mode) +{ + const struct rtw89_qta_def *qta_def = rtw89_chip_get_qta_def(rtwdev); + struct rtw89_mac_info *mac = &rtwdev->mac; + const struct rtw89_dle_mem *cfg, *cfgs; + + cfgs = qta_def->dle_mem[rtwdev->hci.dle_type]; + if (!cfgs) + return NULL; + + cfg = &cfgs[mode]; + if (cfg->mode != mode) { + rtw89_warn(rtwdev, "qta mode unmatch!\n"); + return NULL; + } + + mac->dle_info.rsvd_qt = cfg->rsvd_qt; + mac->dle_info.dle_input = cfg->dle_input; + mac->dle_info.ple_pg_size = cfg->ple_size->pge_size; + mac->dle_info.ple_free_pg = cfg->ple_size->lnk_pge_num; + mac->dle_info.qta_mode = mode; + mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma; + mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma; + + return cfg; +} + +int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_dle_rsvd_qt_type type, + struct rtw89_mac_dle_rsvd_qt_cfg *cfg) +{ + struct rtw89_dle_info *dle_info = &rtwdev->mac.dle_info; + const struct rtw89_rsvd_quota *rsvd_qt = dle_info->rsvd_qt; + + switch (type) { + case DLE_RSVD_QT_MPDU_INFO: + cfg->pktid = dle_info->ple_free_pg; + cfg->pg_num = rsvd_qt->mpdu_info_tbl; + break; + case DLE_RSVD_QT_B0_CSI: + cfg->pktid = dle_info->ple_free_pg + rsvd_qt->mpdu_info_tbl; + cfg->pg_num = rsvd_qt->b0_csi; + break; + case DLE_RSVD_QT_B1_CSI: + cfg->pktid = dle_info->ple_free_pg + + rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi; + cfg->pg_num = rsvd_qt->b1_csi; + break; + case DLE_RSVD_QT_B0_LMR: + cfg->pktid = dle_info->ple_free_pg + + rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi; + cfg->pg_num = rsvd_qt->b0_lmr; + break; + case DLE_RSVD_QT_B1_LMR: + cfg->pktid = dle_info->ple_free_pg + + rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi + + rsvd_qt->b0_lmr; + cfg->pg_num = rsvd_qt->b1_lmr; + break; + case DLE_RSVD_QT_B0_FTM: + cfg->pktid = dle_info->ple_free_pg + + rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi + + rsvd_qt->b0_lmr + rsvd_qt->b1_lmr; + cfg->pg_num = rsvd_qt->b0_ftm; + break; + case DLE_RSVD_QT_B1_FTM: + cfg->pktid = dle_info->ple_free_pg + + rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi + + rsvd_qt->b0_lmr + rsvd_qt->b1_lmr + rsvd_qt->b0_ftm; + cfg->pg_num = rsvd_qt->b1_ftm; + break; + default: + return -EINVAL; + } + + cfg->size = (u32)cfg->pg_num * dle_info->ple_pg_size; + + return 0; +} + +static bool mac_is_txq_empty_ax(struct rtw89_dev *rtwdev) +{ + struct rtw89_mac_dle_dfi_qempty qempty; + u32 grpnum, qtmp, val32, msk32; + int i, j, ret; + + grpnum = rtwdev->chip->wde_qempty_acq_grpnum; + qempty.dle_type = DLE_CTRL_TYPE_WDE; + + for (i = 0; i < grpnum; i++) { + qempty.grpsel = i; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) { + rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret); + return false; + } + qtmp = qempty.qempty; + for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) { + val32 = u32_get_bits(qtmp, QEMP_ACQ_GRP_QSEL_MASK); + if (val32 != QEMP_ACQ_GRP_QSEL_MASK) + return false; + qtmp >>= QEMP_ACQ_GRP_QSEL_SH; + } + } + + qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) { + rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret); + return false; + } + msk32 = B_CMAC0_MGQ_NORMAL | B_CMAC0_MGQ_NO_PWRSAV | B_CMAC0_CPUMGQ; + if ((qempty.qempty & msk32) != msk32) + return false; + + if (rtwdev->dbcc_en) { + msk32 |= B_CMAC1_MGQ_NORMAL | B_CMAC1_MGQ_NO_PWRSAV | B_CMAC1_CPUMGQ; + if ((qempty.qempty & msk32) != msk32) + return false; + } + + msk32 = B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU | + B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_PLE_EMPTY_QTA_DMAC_H2C | + B_AX_WDE_EMPTY_QUE_OTHERS | B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | + B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | B_AX_PLE_EMPTY_QTA_DMAC_CPUIO | + B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_HIF | + B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | + B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL | + B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX; + val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0); + + return (val32 & msk32) == msk32; +} + +static inline u32 dle_used_size(const struct rtw89_dle_mem *cfg) +{ + const struct rtw89_dle_size *wde = cfg->wde_size; + const struct rtw89_dle_size *ple = cfg->ple_size; + u32 used; + + used = wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) + + ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num); + + if (cfg->rsvd0_size && cfg->rsvd1_size) { + used += cfg->rsvd0_size->size; + used += cfg->rsvd1_size->size; + } + + return used; +} + +static u32 dle_expected_used_size(struct rtw89_dev *rtwdev, + enum rtw89_qta_mode mode) +{ + u32 size = rtwdev->chip->fifo_size; + + if (mode == RTW89_QTA_SCC && rtwdev->hci.type != RTW89_HCI_TYPE_USB) + size -= rtwdev->chip->dle_scc_rsvd_size; + + return size; +} + +static void dle_func_en_ax(struct rtw89_dev *rtwdev, bool enable) +{ + if (enable) + rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); + else + rtw89_write32_clr(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); +} + +static void dle_clk_en_ax(struct rtw89_dev *rtwdev, bool enable) +{ + u32 val = B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN; + + if (enable) { + if (rtwdev->chip->chip_id == RTL8851B) + val |= B_AX_AXIDMA_CLK_EN; + rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, val); + } else { + rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, val); + } +} + +static int dle_mix_cfg_ax(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg) +{ + const struct rtw89_dle_size *size_cfg; + u32 val; + u8 bound = 0; + + val = rtw89_read32(rtwdev, R_AX_WDE_PKTBUF_CFG); + size_cfg = cfg->wde_size; + + switch (size_cfg->pge_size) { + default: + case RTW89_WDE_PG_64: + val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64, + B_AX_WDE_PAGE_SEL_MASK); + break; + case RTW89_WDE_PG_128: + val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128, + B_AX_WDE_PAGE_SEL_MASK); + break; + case RTW89_WDE_PG_256: + rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n"); + return -EINVAL; + } + + val = u32_replace_bits(val, bound, B_AX_WDE_START_BOUND_MASK); + val = u32_replace_bits(val, size_cfg->lnk_pge_num, + B_AX_WDE_FREE_PAGE_NUM_MASK); + rtw89_write32(rtwdev, R_AX_WDE_PKTBUF_CFG, val); + + val = rtw89_read32(rtwdev, R_AX_PLE_PKTBUF_CFG); + bound = (size_cfg->lnk_pge_num + size_cfg->unlnk_pge_num) + * size_cfg->pge_size / DLE_BOUND_UNIT; + size_cfg = cfg->ple_size; + + switch (size_cfg->pge_size) { + default: + case RTW89_PLE_PG_64: + rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n"); + return -EINVAL; + case RTW89_PLE_PG_128: + val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128, + B_AX_PLE_PAGE_SEL_MASK); + break; + case RTW89_PLE_PG_256: + val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256, + B_AX_PLE_PAGE_SEL_MASK); + break; + } + + val = u32_replace_bits(val, bound, B_AX_PLE_START_BOUND_MASK); + val = u32_replace_bits(val, size_cfg->lnk_pge_num, + B_AX_PLE_FREE_PAGE_NUM_MASK); + rtw89_write32(rtwdev, R_AX_PLE_PKTBUF_CFG, val); + + return 0; +} + +static int chk_dle_rdy_ax(struct rtw89_dev *rtwdev, bool wde_or_ple) +{ + u32 reg, mask; + u32 ini; + + if (wde_or_ple) { + reg = R_AX_WDE_INI_STATUS; + mask = WDE_MGN_INI_RDY; + } else { + reg = R_AX_PLE_INI_STATUS; + mask = PLE_MGN_INI_RDY; + } + + return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1, + 2000, false, rtwdev, reg); +} + +#define INVALID_QT_WCPU U16_MAX +#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \ + do { \ + val = u32_encode_bits(_min_x, B_AX_ ## _module ## _MIN_SIZE_MASK) | \ + u32_encode_bits(_max_x, B_AX_ ## _module ## _MAX_SIZE_MASK); \ + rtw89_write32(rtwdev, \ + R_AX_ ## _module ## _QTA ## _idx ## _CFG, \ + val); \ + } while (0) +#define SET_QUOTA(_x, _module, _idx) \ + SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx) + +static void wde_quota_cfg_ax(struct rtw89_dev *rtwdev, + const struct rtw89_wde_quota *min_cfg, + const struct rtw89_wde_quota *max_cfg, + u16 ext_wde_min_qt_wcpu) +{ + u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ? + ext_wde_min_qt_wcpu : min_cfg->wcpu; + u32 val; + + SET_QUOTA(hif, WDE, 0); + SET_QUOTA_VAL(min_qt_wcpu, max_cfg->wcpu, WDE, 1); + SET_QUOTA(pkt_in, WDE, 3); + SET_QUOTA(cpu_io, WDE, 4); +} + +static void ple_quota_cfg_ax(struct rtw89_dev *rtwdev, + const struct rtw89_ple_quota *min_cfg, + const struct rtw89_ple_quota *max_cfg) +{ + u32 val; + + SET_QUOTA(cma0_tx, PLE, 0); + SET_QUOTA(cma1_tx, PLE, 1); + SET_QUOTA(c2h, PLE, 2); + SET_QUOTA(h2c, PLE, 3); + SET_QUOTA(wcpu, PLE, 4); + SET_QUOTA(mpdu_proc, PLE, 5); + SET_QUOTA(cma0_dma, PLE, 6); + SET_QUOTA(cma1_dma, PLE, 7); + SET_QUOTA(bb_rpt, PLE, 8); + SET_QUOTA(wd_rel, PLE, 9); + SET_QUOTA(cpu_io, PLE, 10); + if (rtwdev->chip->chip_id == RTL8852C) + SET_QUOTA(tx_rpt, PLE, 11); +} + +int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow) +{ + const struct rtw89_ple_quota *min_cfg, *max_cfg; + const struct rtw89_dle_mem *cfg; + u32 val; + + if (rtwdev->chip->chip_id == RTL8852C) + return 0; + + if (rtwdev->mac.qta_mode != RTW89_QTA_SCC) { + rtw89_err(rtwdev, "[ERR]support SCC mode only\n"); + return -EINVAL; + } + + if (wow) + cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_WOW); + else + cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_SCC); + if (!cfg) { + rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); + return -EINVAL; + } + + min_cfg = cfg->ple_min_qt; + max_cfg = cfg->ple_max_qt; + SET_QUOTA(cma0_dma, PLE, 6); + SET_QUOTA(cma1_dma, PLE, 7); + + return 0; +} +#undef SET_QUOTA + +void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) + return; + + /* 8852C enable B_AX_UC_MGNT_DEC by default */ + if (chip->chip_id == RTL8852C) + msk32 = B_AX_BMC_MGNT_DEC; + + if (enable) + rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32); + else + rtw89_write32_clr(rtwdev, R_AX_SEC_ENG_CTRL, msk32); +} + +static void dle_quota_cfg(struct rtw89_dev *rtwdev, + const struct rtw89_dle_mem *cfg, + u16 ext_wde_min_qt_wcpu) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + mac->wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu); + mac->ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt); +} + +int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, + enum rtw89_qta_mode ext_mode) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_dle_mem *cfg, *ext_cfg; + u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + cfg = get_dle_mem_cfg(rtwdev, mode); + if (!cfg) { + rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); + ret = -EINVAL; + goto error; + } + + if (mode == RTW89_QTA_DLFW) { + ext_cfg = get_dle_mem_cfg(rtwdev, ext_mode); + if (!ext_cfg) { + rtw89_err(rtwdev, "[ERR]get_dle_ext_mem_cfg %d\n", + ext_mode); + ret = -EINVAL; + goto error; + } + ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu; + } + + if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) { + rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); + ret = -EINVAL; + goto error; + } + + mac->dle_func_en(rtwdev, false); + mac->dle_clk_en(rtwdev, true); + + ret = mac->dle_mix_cfg(rtwdev, cfg); + if (ret) { + rtw89_err(rtwdev, "[ERR] dle mix cfg\n"); + goto error; + } + dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu); + + mac->dle_func_en(rtwdev, true); + + ret = mac->chk_dle_rdy(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]WDE cfg ready\n"); + return ret; + } + + ret = mac->chk_dle_rdy(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]PLE cfg ready\n"); + return ret; + } + + return 0; +error: + mac->dle_func_en(rtwdev, false); + rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n", + rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS)); + rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n", + rtw89_read32(rtwdev, R_AX_PLE_INI_STATUS)); + + return ret; +} + +static int preload_init_set_ax(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_qta_mode mode) +{ + u32 reg, max_preld_size, min_rsvd_size; + + rtw89_io_pack(rtwdev); + + max_preld_size = (mac_idx == RTW89_MAC_0 ? + PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM) * PRELD_AMSDU_SIZE; + reg = mac_idx == RTW89_MAC_0 ? + R_AX_TXPKTCTL_B0_PRELD_CFG0 : R_AX_TXPKTCTL_B1_PRELD_CFG0; + rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_USEMAXSZ_MASK, max_preld_size); + rtw89_write32_set(rtwdev, reg, B_AX_B0_PRELD_FEN); + + min_rsvd_size = PRELD_AMSDU_SIZE; + reg = mac_idx == RTW89_MAC_0 ? + R_AX_TXPKTCTL_B0_PRELD_CFG1 : R_AX_TXPKTCTL_B1_PRELD_CFG1; + rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_TXENDWIN_MASK, PRELD_NEXT_WND); + rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_RSVMINSZ_MASK, min_rsvd_size); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static bool is_qta_poh(struct rtw89_dev *rtwdev) +{ + return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE; +} + +int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, + enum rtw89_qta_mode mode) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev) || + !is_qta_poh(rtwdev)) + return 0; + + return mac->preload_init(rtwdev, mac_idx, mode); +} + +static bool dle_is_txq_empty(struct rtw89_dev *rtwdev) +{ + u32 msk32; + u32 val32; + + msk32 = B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC | B_AX_WDE_EMPTY_QUE_CMAC0_MBH | + B_AX_WDE_EMPTY_QUE_CMAC1_MBH | B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 | + B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 | B_AX_WDE_EMPTY_QUE_OTHERS | + B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | B_AX_PLE_EMPTY_QTA_DMAC_H2C | + B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | + B_AX_WDE_EMPTY_QTA_DMAC_HIF | B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | + B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | + B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | + B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL | + B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX | + B_AX_PLE_EMPTY_QTA_DMAC_CPUIO | + B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU | + B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU; + val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0); + + if ((val32 & msk32) == msk32) + return true; + + return false; +} + +static void _patch_ss2f_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + return; + + rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK, + SS2F_PATH_WLCPU); +} + +static int sta_sch_init_ax(struct rtw89_dev *rtwdev) +{ + u32 p_val; + u8 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + val = rtw89_read8(rtwdev, R_AX_SS_CTRL); + val |= B_AX_SS_EN; + rtw89_write8(rtwdev, R_AX_SS_CTRL, val); + + ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_AX_SS_INIT_DONE_1, + 1, TRXCFG_WAIT_CNT, false, rtwdev, R_AX_SS_CTRL); + if (ret) { + rtw89_err(rtwdev, "[ERR]STA scheduler init\n"); + return ret; + } + + rtw89_io_pack(rtwdev); + + rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG); + rtw89_write32_clr(rtwdev, R_AX_SS_CTRL, B_AX_SS_NONEMPTY_SS2FINFO_EN); + + _patch_ss2f_path(rtwdev); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int mpdu_proc_init_ax(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD); + rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD); + rtw89_write32_set(rtwdev, R_AX_MPDU_PROC, + B_AX_APPEND_FCS | B_AX_A_ICV_ERR); + rtw89_write32(rtwdev, R_AX_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int sec_eng_init_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val = 0; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + val = rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL); + /* init clock */ + val |= (B_AX_CLK_EN_CGCMP | B_AX_CLK_EN_WAPI | B_AX_CLK_EN_WEP_TKIP); + /* init TX encryption */ + val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC); + val |= (B_AX_MC_DEC | B_AX_BC_DEC); + if (chip->chip_id == RTL8852C) + val |= B_AX_UC_MGNT_DEC; + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || + chip->chip_id == RTL8851B || + (chip->chip_id == RTL8852C && rtwdev->hci.type == RTW89_HCI_TYPE_USB)) + val &= ~B_AX_TX_PARTIAL_MODE; + rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); + + /* init MIC ICV append */ + val = rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC); + val |= (B_AX_APPEND_ICV | B_AX_APPEND_MIC); + + /* option init */ + rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val); + + if (chip->chip_id == RTL8852C) + rtw89_write32_mask(rtwdev, R_AX_SEC_DEBUG1, + B_AX_TX_TIMEOUT_SEL_MASK, AX_TX_TO_VAL); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int dmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + + ret = rtw89_mac_dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret); + return ret; + } + + ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode); + if (ret) { + rtw89_err(rtwdev, "[ERR]preload init %d\n", ret); + return ret; + } + + ret = rtw89_mac_hfc_init(rtwdev, true, true, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret); + return ret; + } + + ret = sta_sch_init_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret); + return ret; + } + + ret = mpdu_proc_init_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret); + return ret; + } + + ret = sec_eng_init_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret); + return ret; + } + + return ret; +} + +static int addr_cam_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val, reg; + u16 p_val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_ADDR_CAM_CTRL, mac_idx); + + val = rtw89_read32(rtwdev, reg); + val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) | + B_AX_ADDR_CAM_CLR | B_AX_ADDR_CAM_EN; + rtw89_write32(rtwdev, reg, val); + + ret = read_poll_timeout(rtw89_read16, p_val, !(p_val & B_AX_ADDR_CAM_CLR), + 1, TRXCFG_WAIT_CNT, false, rtwdev, reg); + if (ret) { + rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n"); + return ret; + } + + return 0; +} + +static int scheduler_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + u32 reg; + u32 val; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_1, mac_idx); + if (rtwdev->chip->chip_id == RTL8852C) + rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK, + SIFS_MACTXEN_T1_V1); + else + rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK, + SIFS_MACTXEN_T1); + + if (rtw89_is_rtl885xb(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCH_EXT_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CFG_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_BTCCA_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_0, mac_idx); + if (rtwdev->chip->chip_id == RTL8852C) { + val = rtw89_read32_mask(rtwdev, R_AX_SEC_ENG_CTRL, + B_AX_TX_PARTIAL_MODE); + if (!val) + rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK, + SCH_PREBKF_24US); + } else { + rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK, + SCH_PREBKF_24US); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int rtw89_mac_typ_fltr_opt_ax(struct rtw89_dev *rtwdev, + enum rtw89_machdr_frame_type type, + enum rtw89_mac_fwd_target fwd_target, + u8 mac_idx) +{ + u32 reg; + u32 val; + + switch (fwd_target) { + case RTW89_FWD_DONT_CARE: + val = RX_FLTR_FRAME_DROP; + break; + case RTW89_FWD_TO_HOST: + val = RX_FLTR_FRAME_TO_HOST; + break; + case RTW89_FWD_TO_WLAN_CPU: + val = RX_FLTR_FRAME_TO_WLCPU; + break; + default: + rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n"); + return -EINVAL; + } + + switch (type) { + case RTW89_MGNT: + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MGNT_FLTR, mac_idx); + break; + case RTW89_CTRL: + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTRL_FLTR, mac_idx); + break; + case RTW89_DATA: + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DATA_FLTR, mac_idx); + break; + default: + rtw89_err(rtwdev, "[ERR]set rx filter type err\n"); + return -EINVAL; + } + rtw89_write32(rtwdev, reg, val); + + return 0; +} + +void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 reg; + u32 val; + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, mac_idx); + + val = rtw89_read32(rtwdev, reg); + /* B_AX_RX_FLTR_CFG_MASK is not a consecutive bit mask */ + val = (val & ~B_AX_RX_FLTR_CFG_MASK) | (rx_fltr & B_AX_RX_FLTR_CFG_MASK); + rtw89_write32(rtwdev, reg, val); +} + +static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret, i; + u32 mac_ftlr, plcp_ftlr; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + for (i = RTW89_MGNT; i <= RTW89_DATA; i++) { + ret = rtw89_mac_typ_fltr_opt_ax(rtwdev, i, RTW89_FWD_TO_HOST, + mac_idx); + if (ret) + return ret; + } + mac_ftlr = rtwdev->hal.rx_fltr; + plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK | + B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK | + B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK | + B_AX_HE_SIGB_CRC_CHK; + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx), + mac_ftlr); + rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx), + plcp_ftlr); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg, val32; + u32 b_rsp_chk_nav, b_rsp_chk_cca; + + b_rsp_chk_nav = B_AX_RSP_CHK_TXNAV | B_AX_RSP_CHK_INTRA_NAV | + B_AX_RSP_CHK_BASIC_NAV; + b_rsp_chk_cca = B_AX_RSP_CHK_SEC_CCA_80 | B_AX_RSP_CHK_SEC_CCA_40 | + B_AX_RSP_CHK_SEC_CCA_20 | B_AX_RSP_CHK_BTCCA | + B_AX_RSP_CHK_EDCCA | B_AX_RSP_CHK_CCA; + + switch (rtwdev->chip->chip_id) { + case RTL8852A: + case RTL8852B: + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx); + val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx); + val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca; + rtw89_write32(rtwdev, reg, val32); + break; + default: + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx); + val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx); + val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca; + rtw89_write32(rtwdev, reg, val32); + break; + } +} + +static int cca_ctrl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val, reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CONTROL, mac_idx); + val = rtw89_read32(rtwdev, reg); + val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA | + B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 | + B_AX_SIFS_CHK_BTCCA | B_AX_SIFS_CHK_CCA_P20 | + B_AX_CTN_CHK_INTRA_NAV | + B_AX_CTN_CHK_BASIC_NAV | B_AX_CTN_CHK_BTCCA | + B_AX_CTN_CHK_EDCCA | B_AX_CTN_CHK_CCA_S80 | + B_AX_CTN_CHK_CCA_S40 | B_AX_CTN_CHK_CCA_S20 | + B_AX_CTN_CHK_CCA_P20); + val &= ~(B_AX_TB_CHK_TX_NAV | B_AX_TB_CHK_CCA_S80 | + B_AX_TB_CHK_CCA_S40 | B_AX_TB_CHK_CCA_S20 | + B_AX_SIFS_CHK_CCA_S80 | B_AX_SIFS_CHK_CCA_S40 | + B_AX_SIFS_CHK_CCA_S20 | B_AX_CTN_CHK_TXNAV | + B_AX_SIFS_CHK_EDCCA); + + rtw89_write32(rtwdev, reg, val); + + _patch_dis_resp_chk(rtwdev, mac_idx); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int nav_ctrl_init_ax(struct rtw89_dev *rtwdev) +{ + rtw89_io_pack(rtwdev); + + rtw89_write32_set(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_PLCP_UP_NAV_EN | + B_AX_WMAC_TF_UP_NAV_EN | + B_AX_WMAC_NAV_UPPER_EN); + rtw89_write32_mask(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_NAV_UPPER_MASK, NAV_25MS); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int spatial_reuse_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_SR_CTRL, mac_idx); + rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BSSID_SRC_CTRL, mac_idx); + rtw89_write8_set(rtwdev, reg, B_AX_PLCP_SRC_EN); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int tmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MAC_LOOPBACK, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TCR0, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_TCR_UDF_THSD_MASK, TCR_UDF_THSD); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXD_FIFO_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_HIGH_MCS_THRE_MASK, TXDFIFO_HIGH_MCS_THRE); + rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_LOW_MCS_THRE_MASK, TXDFIFO_LOW_MCS_THRE); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int trxptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs; + u32 reg, val, sifs; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx); + val = rtw89_read32(rtwdev, reg); + val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK; + val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK); + + switch (rtwdev->chip->chip_id) { + case RTL8852A: + sifs = WMAC_SPEC_SIFS_OFDM_52A; + break; + case RTL8851B: + case RTL8852B: + case RTL8852BT: + sifs = WMAC_SPEC_SIFS_OFDM_52B; + break; + default: + sifs = WMAC_SPEC_SIFS_OFDM_52C; + break; + } + val &= ~B_AX_WMAC_SPEC_SIFS_OFDM_MASK; + val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs); + rtw89_write32(rtwdev, reg, val); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXTRIG_TEST_USER_2, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->ref_rate.addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data); + reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->rsc.addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, rrsr->rsc.mask, rrsr->rsc.data); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static void rst_bacam(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + rtw89_write32_mask(rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK, + S_AX_BACAM_RST_ALL); + + ret = read_poll_timeout_atomic(rtw89_read32_mask, val32, val32 == 0, + 1, 1000, false, + rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK); + if (ret) + rtw89_warn(rtwdev, "failed to reset BA CAM\n"); +} + +static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ +#define TRXCFG_RMAC_CCA_TO 32 +#define TRXCFG_RMAC_DATA_TO 15 +#define RX_MAX_LEN_UNIT 512 +#define PLD_RLS_MAX_PG 127 +#define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT) + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + int ret; + u32 reg, rx_max_len, rx_qta; + u16 val; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + if (mac_idx == RTW89_MAC_0) + rst_bacam(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RESPBA_CAM_CTRL, mac_idx); + rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx); + val = rtw89_read16(rtwdev, reg); + val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO, + B_AX_RX_DLK_DATA_TIME_MASK); + val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO, + B_AX_RX_DLK_CCA_TIME_MASK); + if (chip_id == RTL8852BT) + val |= B_AX_RX_DLK_RST_EN; + rtw89_write16(rtwdev, reg, val); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx); + rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx); + if (mac_idx == RTW89_MAC_0) + rx_qta = rtwdev->mac.dle_info.c0_rx_qta; + else + rx_qta = rtwdev->mac.dle_info.c1_rx_qta; + rx_qta = min_t(u32, rx_qta, PLD_RLS_MAX_PG); + rx_max_len = rx_qta * rtwdev->mac.dle_info.ple_pg_size; + rx_max_len = min_t(u32, rx_max_len, RX_SPEC_MAX_LEN); + rx_max_len /= RX_MAX_LEN_UNIT; + rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len); + + if (chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) { + rtw89_write16_mask(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx), + B_AX_RX_DLK_CCA_TIME_MASK, 0); + rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx), + BIT(12)); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx); + rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK); + + rtw89_io_unpack(rtwdev); + + return ret; +} + +static int cmac_com_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val, reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx); + val = rtw89_read32(rtwdev, reg); + val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK); + val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK); + val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK); + rtw89_write32(rtwdev, reg, val); + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_RRSR1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_RRSR_RATE_EN_MASK, RRSR_OFDM_CCK_EN); + } + + return 0; +} + +bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) +{ + const struct rtw89_dle_mem *cfg; + + cfg = get_dle_mem_cfg(rtwdev, mode); + if (!cfg) { + rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); + return false; + } + + return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma); +} + +static int ptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val, reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SIFS_SETTING, mac_idx); + val = rtw89_read32(rtwdev, reg); + val = u32_replace_bits(val, S_AX_CTS2S_TH_1K, + B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK); + val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B, + B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); + val |= B_AX_HW_CTS2SELF_EN; + rtw89_write32(rtwdev, reg, val); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_FSM_MON, mac_idx); + val = rtw89_read32(rtwdev, reg); + val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK); + val &= ~B_AX_PTCL_TX_ARB_TO_MODE; + rtw89_write32(rtwdev, reg, val); + } + + if (mac_idx == RTW89_MAC_0) { + rtw89_write8_set(rtwdev, R_AX_PTCL_COMMON_SETTING_0, + B_AX_CMAC_TX_MODE_0 | B_AX_CMAC_TX_MODE_1); + rtw89_write8_clr(rtwdev, R_AX_PTCL_COMMON_SETTING_0, + B_AX_PTCL_TRIGGER_SS_EN_0 | + B_AX_PTCL_TRIGGER_SS_EN_1 | + B_AX_PTCL_TRIGGER_SS_EN_UL); + rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL, + B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU); + } else if (mac_idx == RTW89_MAC_1) { + rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL_C1, + B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU); + } + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AGG_LEN_VHT_0, mac_idx); + rtw89_write32_mask(rtwdev, reg, + B_AX_AMPDU_MAX_LEN_VHT_MASK, 0x3FF80); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int cmac_dma_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + int ret; + + if (!rtw89_is_rtl885xb(rtwdev)) + return 0; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXDMA_CTRL_0, mac_idx); + rtw89_write8_clr(rtwdev, reg, RX_FULL_MODE); + + return 0; +} + +static int cmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + + ret = scheduler_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret); + return ret; + } + + ret = addr_cam_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx, + ret); + return ret; + } + + ret = rx_fltr_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx, + ret); + return ret; + } + + ret = cca_ctrl_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx, + ret); + return ret; + } + + ret = nav_ctrl_init_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx, + ret); + return ret; + } + + ret = spatial_reuse_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n", + mac_idx, ret); + return ret; + } + + ret = tmac_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret); + return ret; + } + + ret = trxptcl_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret); + return ret; + } + + ret = rmac_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret); + return ret; + } + + ret = cmac_com_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret); + return ret; + } + + ret = ptcl_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret); + return ret; + } + + ret = cmac_dma_init_ax(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret); + return ret; + } + + return ret; +} + +static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev, + struct rtw89_mac_c2h_info *c2h_info, u8 part_num) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_mac_h2c_info h2c_info = {}; + enum rtw89_mac_c2h_type c2h_type; + u8 content_len; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX) + content_len = 0; + else + content_len = 2; + + switch (part_num) { + case 0: + c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP; + break; + case 1: + c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1; + break; + default: + return -EINVAL; + } + + mac->cnv_efuse_state(rtwdev, false); + + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE; + h2c_info.content_len = content_len; + h2c_info.u.hdr.w0 = u32_encode_bits(part_num, RTW89_H2CREG_GET_FEATURE_PART_NUM); + + ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info); + if (ret) + goto out; + + if (c2h_info->id != c2h_type) + ret = -EINVAL; + +out: + mac->cnv_efuse_state(rtwdev, true); + + return ret; +} + +static int rtw89_mac_setup_phycap_part0(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_c2hreg_phycap *phycap; + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_mac_c2h_info c2h_info = {}; + struct rtw89_hal *hal = &rtwdev->hal; + u8 protocol; + u8 tx_nss; + u8 rx_nss; + u8 tx_ant; + u8 rx_ant; + int ret; + + ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 0); + if (ret) + return ret; + + phycap = &c2h_info.u.phycap; + + tx_nss = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_TX_NSS); + rx_nss = u32_get_bits(phycap->w0, RTW89_C2HREG_PHYCAP_W0_RX_NSS); + tx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM); + rx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM); + + hal->tx_nss = tx_nss ? min_t(u8, tx_nss, chip->tx_nss) : chip->tx_nss; + hal->rx_nss = rx_nss ? min_t(u8, rx_nss, chip->rx_nss) : chip->rx_nss; + + if (tx_ant == 1) + hal->antenna_tx = RF_B; + if (rx_ant == 1) + hal->antenna_rx = RF_B; + + if (tx_nss == 1 && tx_ant == 2 && rx_ant == 2) { + hal->antenna_tx = RF_B; + hal->tx_path_diversity = true; + } + + if (chip->rf_path_num == 1) { + hal->antenna_tx = RF_A; + hal->antenna_rx = RF_A; + if ((efuse->rfe_type % 3) == 2) + hal->ant_diversity = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n", + hal->tx_nss, tx_nss, chip->tx_nss, + hal->rx_nss, rx_nss, chip->rx_nss); + rtw89_debug(rtwdev, RTW89_DBG_FW, + "ant num/bitmap: tx=%d/0x%x rx=%d/0x%x\n", + tx_ant, hal->antenna_tx, rx_ant, hal->antenna_rx); + rtw89_debug(rtwdev, RTW89_DBG_FW, "TX path diversity=%d\n", hal->tx_path_diversity); + rtw89_debug(rtwdev, RTW89_DBG_FW, "Antenna diversity=%d\n", hal->ant_diversity); + + protocol = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_PROT); + if (protocol < RTW89_C2HREG_PHYCAP_W1_PROT_11BE) + hal->no_eht = true; + + return 0; +} + +static int rtw89_mac_setup_phycap_part1(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_variant *variant = rtwdev->variant; + const struct rtw89_c2hreg_phycap *phycap; + struct rtw89_mac_c2h_info c2h_info = {}; + struct rtw89_hal *hal = &rtwdev->hal; + u8 qam_raw, qam; + int ret; + + ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 1); + if (ret) + return ret; + + phycap = &c2h_info.u.phycap; + + qam_raw = u32_get_bits(phycap->w2, RTW89_C2HREG_PHYCAP_P1_W2_QAM); + + switch (qam_raw) { + case RTW89_C2HREG_PHYCAP_P1_W2_QAM_256: + case RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024: + case RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096: + qam = qam_raw; + break; + default: + qam = RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096; + break; + } + + if ((variant && variant->no_mcs_12_13) || + qam <= RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024) + hal->no_mcs_12_13 = true; + + rtw89_debug(rtwdev, RTW89_DBG_FW, "phycap qam=%d/%d no_mcs_12_13=%d\n", + qam_raw, qam, hal->no_mcs_12_13); + + return 0; +} + +int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + int ret; + + ret = rtw89_mac_setup_phycap_part0(rtwdev); + if (ret) + return ret; + + if (chip->chip_gen == RTW89_CHIP_AX || + RTW89_CHK_FW_FEATURE(NO_PHYCAP_P1, &rtwdev->fw)) + return 0; + + return rtw89_mac_setup_phycap_part1(rtwdev); +} + +static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band, + u16 tx_en_u16, u16 mask_u16) +{ + struct rtw89_mac_c2h_info c2h_info = {0}; + struct rtw89_mac_h2c_info h2c_info = {0}; + struct rtw89_h2creg_sch_tx_en *sch_tx_en = &h2c_info.u.sch_tx_en; + int ret; + + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN; + h2c_info.content_len = sizeof(*sch_tx_en) - RTW89_H2CREG_HDR_LEN; + + u32p_replace_bits(&sch_tx_en->w0, tx_en_u16, RTW89_H2CREG_SCH_TX_EN_W0_EN); + u32p_replace_bits(&sch_tx_en->w1, mask_u16, RTW89_H2CREG_SCH_TX_EN_W1_MASK); + u32p_replace_bits(&sch_tx_en->w1, band, RTW89_H2CREG_SCH_TX_EN_W1_BAND); + + ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); + if (ret) + return ret; + + if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT) + return -EINVAL; + + return 0; +} + +static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx, + u16 tx_en, u16 tx_en_mask) +{ + u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx); + u16 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return rtw89_hw_sch_tx_en_h2c(rtwdev, mac_idx, + tx_en, tx_en_mask); + + val = rtw89_read16(rtwdev, reg); + val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); + rtw89_write16(rtwdev, reg, val); + + return 0; +} + +static int rtw89_set_hw_sch_tx_en_v1(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 tx_en, u32 tx_en_mask) +{ + u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx); + u32 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + val = rtw89_read32(rtwdev, reg); + val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); + rtw89_write32(rtwdev, reg, val); + + return 0; +} + +int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel) +{ + int ret; + + *tx_en = rtw89_read16(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx)); + + switch (sel) { + case RTW89_SCH_TX_SEL_ALL: + ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, + B_AX_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_HIQ: + ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, + 0, B_AX_CTN_TXEN_HGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MG0: + ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, + 0, B_AX_CTN_TXEN_MGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MACID: + ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, + B_AX_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + break; + default: + return 0; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_stop_sch_tx); + +int rtw89_mac_stop_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel) +{ + int ret; + + *tx_en = rtw89_read32(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx)); + + switch (sel) { + case RTW89_SCH_TX_SEL_ALL: + ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0, + B_AX_CTN_TXEN_ALL_MASK_V1); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_HIQ: + ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, + 0, B_AX_CTN_TXEN_HGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MG0: + ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, + 0, B_AX_CTN_TXEN_MGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MACID: + ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0, + B_AX_CTN_TXEN_ALL_MASK_V1); + if (ret) + return ret; + break; + default: + return 0; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v1); + +int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) +{ + int ret; + + ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, tx_en, B_AX_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_resume_sch_tx); + +int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) +{ + int ret; + + ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, tx_en, + B_AX_CTN_TXEN_ALL_MASK_V1); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v1); + +static int dle_buf_req_ax(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id) +{ + u32 val, reg; + int ret; + + reg = wd ? R_AX_WD_BUF_REQ : R_AX_PL_BUF_REQ; + val = buf_len; + val |= B_AX_WD_BUF_REQ_EXEC; + rtw89_write32(rtwdev, reg, val); + + reg = wd ? R_AX_WD_BUF_STATUS : R_AX_PL_BUF_STATUS; + + ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE, + 1, 2000, false, rtwdev, reg); + if (ret) + return ret; + + *pkt_id = FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val); + if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID) + return -ENOENT; + + return 0; +} + +static int set_cpuio_ax(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd) +{ + u32 val, cmd_type, reg; + int ret; + + cmd_type = ctrl_para->cmd_type; + + reg = wd ? R_AX_WD_CPUQ_OP_2 : R_AX_PL_CPUQ_OP_2; + val = 0; + val = u32_replace_bits(val, ctrl_para->start_pktid, + B_AX_WD_CPUQ_OP_STRT_PKTID_MASK); + val = u32_replace_bits(val, ctrl_para->end_pktid, + B_AX_WD_CPUQ_OP_END_PKTID_MASK); + rtw89_write32(rtwdev, reg, val); + + reg = wd ? R_AX_WD_CPUQ_OP_1 : R_AX_PL_CPUQ_OP_1; + val = 0; + val = u32_replace_bits(val, ctrl_para->src_pid, + B_AX_CPUQ_OP_SRC_PID_MASK); + val = u32_replace_bits(val, ctrl_para->src_qid, + B_AX_CPUQ_OP_SRC_QID_MASK); + val = u32_replace_bits(val, ctrl_para->dst_pid, + B_AX_CPUQ_OP_DST_PID_MASK); + val = u32_replace_bits(val, ctrl_para->dst_qid, + B_AX_CPUQ_OP_DST_QID_MASK); + rtw89_write32(rtwdev, reg, val); + + reg = wd ? R_AX_WD_CPUQ_OP_0 : R_AX_PL_CPUQ_OP_0; + val = 0; + val = u32_replace_bits(val, cmd_type, + B_AX_CPUQ_OP_CMD_TYPE_MASK); + val = u32_replace_bits(val, ctrl_para->macid, + B_AX_CPUQ_OP_MACID_MASK); + val = u32_replace_bits(val, ctrl_para->pkt_num, + B_AX_CPUQ_OP_PKTNUM_MASK); + val |= B_AX_WD_CPUQ_OP_EXEC; + rtw89_write32(rtwdev, reg, val); + + reg = wd ? R_AX_WD_CPUQ_OP_STATUS : R_AX_PL_CPUQ_OP_STATUS; + + ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_CPUQ_OP_STAT_DONE, + 1, 2000, false, rtwdev, reg); + if (ret) + return ret; + + if (cmd_type == CPUIO_OP_CMD_GET_1ST_PID || + cmd_type == CPUIO_OP_CMD_GET_NEXT_PID) + ctrl_para->pktid = FIELD_GET(B_AX_WD_CPUQ_OP_PKTID_MASK, val); + + return 0; +} + +int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, + bool band1_en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_dle_mem *cfg; + + cfg = get_dle_mem_cfg(rtwdev, mode); + if (!cfg) { + rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); + return -EINVAL; + } + + if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) { + rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); + return -EINVAL; + } + + dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU); + + return mac->dle_quota_change(rtwdev, band1_en); +} + +static int dle_quota_change_ax(struct rtw89_dev *rtwdev, bool band1_en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_cpuio_ctrl ctrl_para = {0}; + u16 pkt_id; + int ret; + + ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id); + if (ret) { + rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n"); + return ret; + } + + ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; + ctrl_para.start_pktid = pkt_id; + ctrl_para.end_pktid = pkt_id; + ctrl_para.pkt_num = 0; + ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS; + ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT; + ret = mac->set_cpuio(rtwdev, &ctrl_para, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n"); + return -EFAULT; + } + + ret = mac->dle_buf_req(rtwdev, 0x20, false, &pkt_id); + if (ret) { + rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n"); + return ret; + } + + ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; + ctrl_para.start_pktid = pkt_id; + ctrl_para.end_pktid = pkt_id; + ctrl_para.pkt_num = 0; + ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS; + ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT; + ret = mac->set_cpuio(rtwdev, &ctrl_para, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n"); + return -EFAULT; + } + + return 0; +} + +static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + u32 reg; + u8 val; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_TX_CTN_SEL, mac_idx); + + ret = read_poll_timeout(rtw89_read8, val, + (val & B_AX_PTCL_TX_ON_STAT) == 0, + SW_CVR_DUR_US, + SW_CVR_DUR_US * PTCL_IDLE_POLL_CNT, + false, rtwdev, reg); + if (ret) + return ret; + + return 0; +} + +static int band1_enable_ax(struct rtw89_dev *rtwdev) +{ + int ret, i; + u32 sleep_bak[4] = {0}; + u32 pause_bak[4] = {0}; + u32 tx_en; + + ret = rtw89_chip_stop_sch_tx(rtwdev, 0, &tx_en, RTW89_SCH_TX_SEL_ALL); + if (ret) { + rtw89_err(rtwdev, "[ERR]stop sch tx %d\n", ret); + return ret; + } + + for (i = 0; i < 4; i++) { + sleep_bak[i] = rtw89_read32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4); + pause_bak[i] = rtw89_read32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4); + rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, U32_MAX); + rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, U32_MAX); + } + + ret = band_idle_ck_b(rtwdev, 0); + if (ret) { + rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret); + return ret; + } + + ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); + return ret; + } + + for (i = 0; i < 4; i++) { + rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, sleep_bak[i]); + rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, pause_bak[i]); + } + + ret = rtw89_chip_resume_sch_tx(rtwdev, 0, tx_en); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC1 resume sch tx %d\n", ret); + return ret; + } + + ret = cmac_func_en_ax(rtwdev, 1, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret); + return ret; + } + + ret = cmac_init_ax(rtwdev, 1); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret); + return ret; + } + + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_R_SYM_FEN_WLBBFUN_1 | B_AX_R_SYM_FEN_WLBBGLB_1); + + return 0; +} + +static void rtw89_wdrls_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, B_AX_WDRLS_IMR_EN_CLR); + rtw89_write32_set(rtwdev, R_AX_WDRLS_ERR_IMR, imr->wdrls_imr_set); +} + +static void rtw89_wsec_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_set(rtwdev, imr->wsec_imr_reg, imr->wsec_imr_set); +} + +static void rtw89_mpdu_trx_imr_enable(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR, + B_AX_TX_GET_ERRPKTID_INT_EN | + B_AX_TX_NXT_ERRPKTID_INT_EN | + B_AX_TX_MPDU_SIZE_ZERO_INT_EN | + B_AX_TX_OFFSET_ERR_INT_EN | + B_AX_TX_HDR3_SIZE_ERR_INT_EN); + if (chip_id == RTL8852C) + rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR, + B_AX_TX_ETH_TYPE_ERR_EN | + B_AX_TX_LLC_PRE_ERR_EN | + B_AX_TX_NW_TYPE_ERR_EN | + B_AX_TX_KSRCH_ERR_EN); + rtw89_write32_set(rtwdev, R_AX_MPDU_TX_ERR_IMR, + imr->mpdu_tx_imr_set); + + rtw89_write32_clr(rtwdev, R_AX_MPDU_RX_ERR_IMR, + B_AX_GETPKTID_ERR_INT_EN | + B_AX_MHDRLEN_ERR_INT_EN | + B_AX_RPT_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_MPDU_RX_ERR_IMR, + imr->mpdu_rx_imr_set); +} + +static void rtw89_sta_sch_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR, + B_AX_SEARCH_HANG_TIMEOUT_INT_EN | + B_AX_RPT_HANG_TIMEOUT_INT_EN | + B_AX_PLE_B_PKTID_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR, + imr->sta_sch_imr_set); +} + +static void rtw89_txpktctl_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b0_reg, + imr->txpktctl_imr_b0_clr); + rtw89_write32_set(rtwdev, imr->txpktctl_imr_b0_reg, + imr->txpktctl_imr_b0_set); + rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b1_reg, + imr->txpktctl_imr_b1_clr); + rtw89_write32_set(rtwdev, imr->txpktctl_imr_b1_reg, + imr->txpktctl_imr_b1_set); +} + +static void rtw89_wde_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_clr); + rtw89_write32_set(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_set); +} + +static void rtw89_ple_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_clr); + rtw89_write32_set(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_set); +} + +static void rtw89_pktin_imr_enable(struct rtw89_dev *rtwdev) +{ + rtw89_write32_set(rtwdev, R_AX_PKTIN_ERR_IMR, + B_AX_PKTIN_GETPKTID_ERR_INT_EN); +} + +static void rtw89_dispatcher_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, + imr->host_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, + imr->host_disp_imr_set); + rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, + imr->cpu_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, + imr->cpu_disp_imr_set); + rtw89_write32_clr(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR, + imr->other_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR, + imr->other_disp_imr_set); +} + +static void rtw89_cpuio_imr_enable(struct rtw89_dev *rtwdev) +{ + rtw89_write32_clr(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_CLR); + rtw89_write32_set(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_SET); +} + +static void rtw89_bbrpt_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_set(rtwdev, imr->bbrpt_com_err_imr_reg, + B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN); + rtw89_write32_clr(rtwdev, imr->bbrpt_chinfo_err_imr_reg, + B_AX_BBRPT_CHINFO_IMR_CLR); + rtw89_write32_set(rtwdev, imr->bbrpt_chinfo_err_imr_reg, + imr->bbrpt_err_imr_set); + rtw89_write32_set(rtwdev, imr->bbrpt_dfs_err_imr_reg, + B_AX_BBRPT_DFS_TO_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_LA_ERRFLAG, B_AX_LA_IMR_DATA_LOSS_ERR); +} + +static void rtw89_scheduler_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCHEDULE_ERR_IMR, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_SORT_NON_IDLE_ERR_INT_EN | + B_AX_FSM_TIMEOUT_ERR_INT_EN); + rtw89_write32_set(rtwdev, reg, B_AX_FSM_TIMEOUT_ERR_INT_EN); +} + +static void rtw89_ptcl_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_IMR0, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->ptcl_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->ptcl_imr_set); +} + +static void rtw89_cdma_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_0_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_0_clr); + rtw89_write32_set(rtwdev, reg, imr->cdma_imr_0_set); + + if (chip_id == RTL8852C) { + reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_1_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_1_clr); + rtw89_write32_set(rtwdev, reg, imr->cdma_imr_1_set); + } +} + +static void rtw89_phy_intf_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, imr->phy_intf_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->phy_intf_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->phy_intf_imr_set); +} + +static void rtw89_rmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, imr->rmac_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->rmac_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->rmac_imr_set); +} + +static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, imr->tmac_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->tmac_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set); +} + +static int enable_imr_ax(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_mac_hwmod_sel sel) +{ + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel); + if (ret) { + rtw89_err(rtwdev, "MAC%d mac_idx%d is not ready\n", + sel, mac_idx); + return ret; + } + + if (sel == RTW89_DMAC_SEL) { + rtw89_wdrls_imr_enable(rtwdev); + rtw89_wsec_imr_enable(rtwdev); + rtw89_mpdu_trx_imr_enable(rtwdev); + rtw89_sta_sch_imr_enable(rtwdev); + rtw89_txpktctl_imr_enable(rtwdev); + rtw89_wde_imr_enable(rtwdev); + rtw89_ple_imr_enable(rtwdev); + rtw89_pktin_imr_enable(rtwdev); + rtw89_dispatcher_imr_enable(rtwdev); + rtw89_cpuio_imr_enable(rtwdev); + rtw89_bbrpt_imr_enable(rtwdev); + } else if (sel == RTW89_CMAC_SEL) { + rtw89_scheduler_imr_enable(rtwdev, mac_idx); + rtw89_ptcl_imr_enable(rtwdev, mac_idx); + rtw89_cdma_imr_enable(rtwdev, mac_idx); + rtw89_phy_intf_imr_enable(rtwdev, mac_idx); + rtw89_rmac_imr_enable(rtwdev, mac_idx); + rtw89_tmac_imr_enable(rtwdev, mac_idx); + } else { + return -EINVAL; + } + + return 0; +} + +static void err_imr_ctrl_ax(struct rtw89_dev *rtwdev, bool en) +{ + rtw89_write32(rtwdev, R_AX_DMAC_ERR_IMR, + en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS); + rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR, + en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS); + if (!rtw89_is_rtl885xb(rtwdev) && rtwdev->mac.dle_info.c1_rx_qta) + rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR_C1, + en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS); +} + +static int dbcc_enable_ax(struct rtw89_dev *rtwdev, bool enable) +{ + int ret = 0; + + if (enable) { + ret = band1_enable_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret); + return ret; + } + + ret = enable_imr_ax(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret); + return ret; + } + } else { + rtw89_err(rtwdev, "[ERR] disable dbcc is not implemented not\n"); + return -EINVAL; + } + + return 0; +} + +static int set_host_rpr_ax(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, + B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_POH); + rtw89_write32_set(rtwdev, R_AX_RLSRPT0_CFG0, + B_AX_RLSRPT0_FLTR_MAP_MASK); + } else { + rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, + B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_STF); + rtw89_write32_clr(rtwdev, R_AX_RLSRPT0_CFG0, + B_AX_RLSRPT0_FLTR_MAP_MASK); + } + + rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_AGGNUM_MASK, 30); + rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_TO_MASK, 255); + + return 0; +} + +static int trx_init_ax(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode; + int ret; + + ret = dmac_init_ax(rtwdev, 0); + if (ret) { + rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret); + return ret; + } + + ret = cmac_init_ax(rtwdev, 0); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret); + return ret; + } + + if (rtw89_mac_is_qta_dbcc(rtwdev, qta_mode)) { + ret = dbcc_enable_ax(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret); + return ret; + } + } + + ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret); + return ret; + } + + ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret); + return ret; + } + + err_imr_ctrl_ax(rtwdev, true); + + ret = set_host_rpr_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret); + return ret; + } + + if (chip_id == RTL8852C) + rtw89_write32_clr(rtwdev, R_AX_RSP_CHK_SIG, + B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN); + + return 0; +} + +static int rtw89_mac_feat_init(struct rtw89_dev *rtwdev) +{ +#define BACAM_1024BMP_OCC_ENTRY 4 +#define BACAM_MAX_RU_SUPPORT_B0_STA 1 +#define BACAM_MAX_RU_SUPPORT_B1_STA 1 + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 users, offset; + + if (chip->bacam_ver != RTW89_BACAM_V1) + return 0; + + offset = 0; + users = BACAM_MAX_RU_SUPPORT_B0_STA; + rtw89_fw_h2c_init_ba_cam_users(rtwdev, users, offset, RTW89_MAC_0); + + offset += users * BACAM_1024BMP_OCC_ENTRY; + users = BACAM_MAX_RU_SUPPORT_B1_STA; + rtw89_fw_h2c_init_ba_cam_users(rtwdev, users, offset, RTW89_MAC_1); + + return 0; +} + +static int rtw89_mac_reset_pwr_state_ax(struct rtw89_dev *rtwdev) +{ + u8 val; + + val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK); + if (val == MAC_AX_MAC_ON) { + /* + * A USB adapter might play as USB mass storage with driver and + * then switch to WiFi adapter, causing it stays on power-on + * state when doing WiFi USB probe. Return EAGAIN to caller to + * power-off and power-on again to reset the state. + */ + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB && + !test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags)) + return -EAGAIN; + + rtw89_err(rtwdev, "MAC has already powered on\n"); + return -EBUSY; + } + + return 0; +} + +static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev) +{ + u32 val32; + + if (rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN); + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN); + return; + } + + rtw89_mac_mem_write(rtwdev, R_AX_WDT_CTRL, + WDT_CTRL_ALL_DIS, RTW89_MAC_MEM_CPU_LOCAL); + + val32 = rtw89_mac_mem_read(rtwdev, R_AX_WDT_STATUS, RTW89_MAC_MEM_CPU_LOCAL); + val32 |= B_AX_FS_WDT_INT; + val32 &= ~B_AX_FS_WDT_INT_MSK; + rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL); +} + +static void rtw89_mac_disable_cpu_ax(struct rtw89_dev *rtwdev) +{ + clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); + + rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); + rtw89_write32_clr(rtwdev, R_AX_WCPU_FW_CTRL, B_AX_WCPU_FWDL_EN | + B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY); + rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); + + rtw89_disable_fw_watchdog(rtwdev); + + rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); +} + +static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason, + bool dlfw, bool include_bb) +{ + u32 val; + int ret; + + if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN) + return -EFAULT; + + rtw89_write32(rtwdev, R_AX_UDM1, 0); + rtw89_write32(rtwdev, R_AX_UDM2, 0); + rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + rtw89_write32(rtwdev, R_AX_HALT_H2C, 0); + rtw89_write32(rtwdev, R_AX_HALT_C2H, 0); + + rtw89_write32_set(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); + + val = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); + val &= ~(B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY); + val = u32_replace_bits(val, RTW89_FWDL_INITIAL_STATE, + B_AX_WCPU_FWDL_STS_MASK); + + if (dlfw) + val |= B_AX_WCPU_FWDL_EN; + + rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); + + if (rtw89_is_rtl885xb(rtwdev)) + rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL, + B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2); + + rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK, + boot_reason); + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); + + if (!dlfw) { + mdelay(5); + + ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); + if (ret) + return ret; + } + + return 0; +} + +static void rtw89_mac_hci_func_en_ax(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val; + + if (chip_id == RTL8852C) + val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | + B_AX_PKT_BUF_EN | B_AX_H_AXIDMA_EN; + else + val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | + B_AX_PKT_BUF_EN; + rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val); +} + +static void rtw89_mac_dmac_func_pre_en_ax(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val; + + if (chip_id == RTL8851B || chip_id == RTL8852BT) + val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN; + else + val = B_AX_DISPATCHER_CLK_EN; + rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val); + + if (chip_id != RTL8852C) + return; + + val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1); + val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST); + val |= B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B); + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_USB); + else + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_SDIO); + + rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val); + + rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1, + B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | B_AX_STOP_ACH3 | + B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | B_AX_STOP_ACH6 | + B_AX_STOP_ACH7 | B_AX_STOP_CH8 | B_AX_STOP_CH9 | + B_AX_STOP_CH12 | B_AX_STOP_ACH2); + rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP2, B_AX_STOP_CH10 | B_AX_STOP_CH11); + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_AXIDMA_EN); +} + +static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + int ret; + + mac->hci_func_en(rtwdev); + mac->dmac_func_pre_en(rtwdev); + + ret = rtw89_mac_dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret); + return ret; + } + + ret = rtw89_mac_hfc_init(rtwdev, true, false, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret); + return ret; + } + + return ret; +} + +int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, + B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | + B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); + rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_enable_bb_rf); + +int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, + B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | + B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); + rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_disable_bb_rf); + +int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb, + bool bb_preinit) +{ + int ret; + + rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); + + if (include_bb || bb_preinit) { + /* Only call BB preinit including configuration of BB MCU for + * the chips which need to download BB MCU firmware. Otherwise, + * calling preinit later to prevent touching registers affecting + * download firmware. + */ + rtw89_chip_bb_preinit(rtwdev); + } + + ret = rtw89_mac_dmac_pre_init(rtwdev); + if (ret) + return ret; + + if (rtwdev->hci.ops->mac_pre_init) { + ret = rtwdev->hci.ops->mac_pre_init(rtwdev); + if (ret) + return ret; + } + + rtw89_mac_fwdl_preconfig(rtwdev); + + ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL, include_bb); + if (ret) + return ret; + + return 0; +} + +int rtw89_mac_preinit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + int ret; + + ret = rtw89_mac_pwr_on(rtwdev); + if (ret) + return ret; + + if (mac->mac_func_en) { + ret = mac->mac_func_en(rtwdev); + if (ret) + return ret; + } + + return 0; +} + +int rtw89_mac_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + bool include_bb = !!chip->bbmcu_nr; + int ret; + + ret = rtw89_mac_partial_init(rtwdev, include_bb, include_bb); + if (ret) + goto fail; + + ret = rtw89_chip_enable_bb_rf(rtwdev); + if (ret) + goto fail; + + ret = mac->sys_init(rtwdev); + if (ret) + goto fail; + + ret = mac->trx_init(rtwdev); + if (ret) + goto fail; + + ret = rtw89_mac_feat_init(rtwdev); + if (ret) + goto fail; + + if (rtwdev->hci.ops->mac_post_init) { + ret = rtwdev->hci.ops->mac_post_init(rtwdev); + if (ret) + goto fail; + } + + rtw89_fw_send_all_early_h2c(rtwdev); + rtw89_fw_h2c_set_ofld_cfg(rtwdev); + + return ret; +fail: + rtw89_mac_pwr_off(rtwdev); + + return ret; +} + +static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + u8 i; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot) + return; + + for (i = 0; i < 4; i++) { + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, + DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2)); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0); + } +} + +static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot) + return; + + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, + CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 12, 0); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 16, 0); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 20, 0xE43000B); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 24, 0); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109); +} + +int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause) +{ + u8 sh = FIELD_GET(GENMASK(4, 0), macid); + u8 grp = macid >> 5; + int ret; + + /* If this is called by change_interface() in the case of P2P, it could + * be power-off, so ignore this operation. + */ + if (test_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags) && + !test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return 0; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_fw_h2c_macid_pause(rtwdev, sh, grp, pause); + + return 0; +} + +static const struct rtw89_port_reg rtw89_port_base_ax = { + .port_cfg = R_AX_PORT_CFG_P0, + .tbtt_prohib = R_AX_TBTT_PROHIB_P0, + .bcn_area = R_AX_BCN_AREA_P0, + .bcn_early = R_AX_BCNERLYINT_CFG_P0, + .tbtt_early = R_AX_TBTTERLYINT_CFG_P0, + .tbtt_agg = R_AX_TBTT_AGG_P0, + .bcn_space = R_AX_BCN_SPACE_CFG_P0, + .bcn_forcetx = R_AX_BCN_FORCETX_P0, + .bcn_err_cnt = R_AX_BCN_ERR_CNT_P0, + .bcn_err_flag = R_AX_BCN_ERR_FLAG_P0, + .dtim_ctrl = R_AX_DTIM_CTRL_P0, + .tbtt_shift = R_AX_TBTT_SHIFT_P0, + .bcn_cnt_tmr = R_AX_BCN_CNT_TMR_P0, + .tsftr_l = R_AX_TSFTR_LOW_P0, + .tsftr_h = R_AX_TSFTR_HIGH_P0, + .md_tsft = R_AX_MD_TSFT_STMP_CTL, + .bss_color = R_AX_PTCL_BSS_COLOR_0, + .mbssid = R_AX_MBSSID_CTRL, + .mbssid_drop = R_AX_MBSSID_DROP_0, + .tsf_sync = R_AX_PORT0_TSF_SYNC, + .ptcl_dbg = R_AX_PTCL_DBG, + .ptcl_dbg_info = R_AX_PTCL_DBG_INFO, + .bcn_drop_all = R_AX_BCN_DROP_ALL0, + .bcn_psr_rpt = R_AX_BCN_PSR_RPT_P0, + .hiq_win = {R_AX_P0MB_HGQ_WINDOW_CFG_0, R_AX_PORT_HGQ_WINDOW_CFG, + R_AX_PORT_HGQ_WINDOW_CFG + 1, R_AX_PORT_HGQ_WINDOW_CFG + 2, + R_AX_PORT_HGQ_WINDOW_CFG + 3}, +}; + +static const struct rtw89_mac_mu_gid_addr rtw89_mac_mu_gid_addr_ax = { + .position_en = {R_AX_GID_POSITION_EN0, R_AX_GID_POSITION_EN1}, + .position = {R_AX_GID_POSITION0, R_AX_GID_POSITION1, + R_AX_GID_POSITION2, R_AX_GID_POSITION3}, +}; + +static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u8 type) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif_link->port); + u32 reg_info, reg_ctrl; + u32 val; + int ret; + + reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif_link->mac_idx); + reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif_link->mac_idx); + + rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type); + rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN); + fsleep(100); + + ret = read_poll_timeout(rtw89_read32_mask, val, val == 0, 1000, 100000, + true, rtwdev, reg_info, mask); + if (ret) + rtw89_warn(rtwdev, "Polling beacon packet empty fail\n"); +} + +static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port)); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, + 1); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, + 0); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, + 0); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, 2); + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early, + B_AX_TBTTERLY_MASK, 1); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, + B_AX_BCN_SPACE_MASK, 1); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); + + rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM0); + if (rtwvif_link->port == RTW89_PORT_0) + rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM1); + + rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port)); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TBTT_PROHIB_EN); + fsleep(2000); +} + +#define BCN_INTERVAL 100 +#define BCN_ERLY_DEF 160 +#define BCN_SETUP_DEF 2 +#define BCN_HOLD_DEF 200 +#define BCN_MASK_DEF 0 +#define TBTT_ERLY_DEF 5 +#define TBTT_AGG_DEF 1 +#define BCN_SET_UNIT 32 +#define BCN_ERLY_SET_DLY (10 * 2) + +static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_bss_conf *bss_conf; + bool need_backup = false; + u32 backup_val; + u16 beacon_int; + + if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN)) + return; + + if (chip->chip_id == RTL8852A && rtwvif_link->port != RTW89_PORT_0) { + need_backup = true; + backup_val = rtw89_read32_port(rtwdev, rtwvif_link, p->tbtt_prohib); + } + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + rtw89_mac_bcn_drop(rtwdev, rtwvif_link); + + if (chip->chip_id == RTL8852A) { + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_SETUP_MASK); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_HOLD_MASK, 1); + rtw89_write16_port_clr(rtwdev, rtwvif_link, p->tbtt_early, + B_AX_TBTTERLY_MASK); + rtw89_write16_port_clr(rtwdev, rtwvif_link, p->bcn_early, + B_AX_BCNERLY_MASK); + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + beacon_int = bss_conf->beacon_int; + + rcu_read_unlock(); + + msleep(beacon_int + 1); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN | + B_AX_BRK_SETUP); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST); + rtw89_write32_port(rtwdev, rtwvif_link, p->bcn_cnt_tmr, 0); + + if (need_backup) + rtw89_write32_port(rtwdev, rtwvif_link, p->tbtt_prohib, backup_val); +} + +static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, + B_AX_TXBCN_RPT_EN); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, + B_AX_TXBCN_RPT_EN); +} + +static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, + B_AX_RXBCN_RPT_EN); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, + B_AX_RXBCN_RPT_EN); +} + +static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_NET_TYPE_MASK, + rtwvif_link->net_type); +} + +static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + bool en = rtwvif_link->net_type != RTW89_NET_TYPE_NO_LINK; + u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bits); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bits); +} + +static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; + u32 bit = B_AX_RX_BSSID_FIT_EN; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bit); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bit); +} + +void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN); +} + +static void rtw89_mac_port_cfg_rx_sync_by_nettype(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; + + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, en); +} + +static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); +} + +static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; + + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); +} + +static void rtw89_mac_enable_ap_bcn_by_chan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct rtw89_chan *to_match, + bool en) +{ + const struct rtw89_chan *chan; + + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) + return; + + if (!to_match) + goto doit; + + /* @to_match may not be in the same domain as return of calling + * rtw89_chan_get(). So, cannot compare their addresses directly. + */ + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->channel != to_match->channel) + return; + +doit: + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); +} + +static void rtw89_mac_enable_aps_bcn_by_chan(struct rtw89_dev *rtwdev, + const struct rtw89_chan *to_match, + bool en) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_enable_ap_bcn_by_chan(rtwdev, rtwvif_link, + to_match, en); +} + +void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) +{ + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, NULL, en); +} + +static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + struct ieee80211_bss_conf *bss_conf; + u16 bcn_int; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (bss_conf->beacon_int) + bcn_int = bss_conf->beacon_int; + else + bcn_int = BCN_INTERVAL; + + rcu_read_unlock(); + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK, + bcn_int); +} + +static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + u8 win = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0; + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u8 port = rtwvif_link->port; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif_link->mac_idx); + rtw89_write8(rtwdev, reg, win); +} + +static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + struct ieee80211_bss_conf *bss_conf; + u8 dtim_period; + u32 addr; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + dtim_period = bss_conf->dtim_period; + + rcu_read_unlock(); + + addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx); + rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE); + + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK, + dtim_period); +} + +static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF); +} + +static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF); +} + +static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, + B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF); +} + +static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early, + B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF); +} + +static void rtw89_mac_port_cfg_tbtt_agg(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_agg, + B_AX_TBTT_AGG_NUM_MASK, TBTT_AGG_DEF); +} + +static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + static const u32 masks[RTW89_PORT_NUM] = { + B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK, + B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK, + B_AX_BSS_COLOB_AX_PORT_4_MASK, + }; + struct ieee80211_bss_conf *bss_conf; + u8 port = rtwvif_link->port; + u32 reg_base; + u32 reg; + u8 bss_color; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + bss_color = bss_conf->he_bss_color.color; + + rcu_read_unlock(); + + reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color; + reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, masks[port], bss_color); +} + +static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u8 port = rtwvif_link->port; + u32 reg; + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + return; + + if (port == 0) { + reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif_link->mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK); + } +} + +static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u8 port = rtwvif_link->port; + u32 reg; + u32 val; + + reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif_link->mac_idx); + val = rtw89_read32(rtwdev, reg); + val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port)); + if (port == 0) + val &= ~BIT(0); + rtw89_write32(rtwdev, reg, val); +} + +static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + if (enable) + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, + B_AX_PORT_FUNC_EN); + else + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, + B_AX_PORT_FUNC_EN); +} + +static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, + BCN_ERLY_DEF); +} + +static void rtw89_mac_port_cfg_bcn_psr_rpt(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + struct ieee80211_bss_conf *bss_conf; + u8 bssid_index; + u32 reg; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (bss_conf->nontransmitted) + bssid_index = bss_conf->bssid_index; + else + bssid_index = 0; + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, p->bcn_psr_rpt + rtwvif_link->port * 4, + rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_BCAID_P0_MASK, bssid_index); +} + +void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, + u16 offset_tu) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u32 val, reg; + + val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu); + reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif_link->port * 4, + rtwvif_link->mac_idx); + + rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); + rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); + rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); +} + +static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, + u8 offset, int *n_offset) +{ + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif_link == rtwvif_src) + return; + + if (rtwvif_link->rand_tsf_done) + goto out; + + /* adjust offset randomly to avoid beacon conflict */ + offset = offset - offset / 4 + get_random_u32() % (offset / 2); + rtw89_mac_port_tsf_sync(rtwdev, rtwvif_link, rtwvif_src, + (*n_offset) * offset); + + rtwvif_link->rand_tsf_done = true; + +out: + (*n_offset)++; +} + +static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *src = NULL, *tmp; + u8 offset = 100, vif_aps = 0; + struct rtw89_vif *rtwvif; + unsigned int link_id; + int n_offset = 1; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, tmp, link_id) { + if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA) + src = tmp; + if (tmp->net_type == RTW89_NET_TYPE_AP_MODE) + vif_aps++; + } + } + + if (vif_aps == 0) + return; + + offset /= (vif_aps + 1); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, tmp, link_id) + rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, + &n_offset); +} + +int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + int ret; + + ret = rtw89_mac_port_update(rtwdev, rtwvif_link); + if (ret) + return ret; + + rtw89_mac_dmac_tbl_init(rtwdev, rtwvif_link->mac_id); + rtw89_mac_cmac_tbl_init(rtwdev, rtwvif_link->mac_id); + + ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif_link->mac_id, false); + if (ret) + return ret; + + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_CREATE); + if (ret) + return ret; + + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); + if (ret) + return ret; + + ret = rtw89_cam_init(rtwdev, rtwvif_link); + if (ret) + return ret; + + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_CREATE); + if (ret) + return ret; + + ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, NULL); + if (ret) + return ret; + + ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, NULL); + if (ret) + return ret; + + return 0; +} + +int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + int ret; + + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_REMOVE); + if (ret) + return ret; + + rtw89_cam_deinit(rtwdev, rtwvif_link); + + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_REMOVE); + if (ret) + return ret; + + return 0; +} + +int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + u8 port = rtwvif_link->port; + + if (port >= RTW89_PORT_NUM) + return -EINVAL; + + rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif_link, false); + rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif_link, false); + rtw89_mac_port_cfg_net_type(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tbtt_agg(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true); + rtw89_mac_port_tsf_resync_all(rtwdev); + fsleep(BCN_ERLY_SET_DLY); + rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_psr_rpt(rtwdev, rtwvif_link); + + return 0; +} + +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u64 *tsf) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + u32 tsf_low, tsf_high; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, rtwvif_link->mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + tsf_low = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_l); + tsf_high = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_h); + *tsf = (u64)tsf_high << 32 | tsf_low; + + return 0; +} + +static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, + struct cfg80211_bss *bss, + void *data) +{ + const struct cfg80211_bss_ies *ies; + const struct element *elem; + bool *tolerated = data; + + rcu_read_lock(); + ies = rcu_dereference(bss->ies); + elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data, + ies->len); + + if (!elem || elem->datalen < 11 || + !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) + *tolerated = false; + rcu_read_unlock(); +} + +void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_bss_conf *bss_conf; + struct cfg80211_chan_def oper; + bool tolerated = true; + u32 reg; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) { + rcu_read_unlock(); + return; + } + + oper = bss_conf->chanreq.oper; + if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) { + rcu_read_unlock(); + return; + } + + rcu_read_unlock(); + + cfg80211_bss_iter(hw->wiphy, &oper, + rtw89_mac_check_he_obss_narrow_bw_ru_iter, + &tolerated); + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->narrow_bw_ru_dis.addr, + rtwvif_link->mac_idx); + if (tolerated) + rtw89_write32_clr(rtwdev, reg, mac->narrow_bw_ru_dis.mask); + else + rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask); +} + +void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_bss_conf *bss_conf; + bool set; + u32 reg; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_BE) + return; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + set = bss_conf->he_support && !bss_conf->eht_support; + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CLIENT_OM_CTRL, + rtwvif_link->mac_idx); + + if (set) + rtw89_write32_set(rtwdev, reg, B_BE_TRIG_DIS_EHTTB); + else + rtw89_write32_clr(rtwdev, reg, B_BE_TRIG_DIS_EHTTB); +} + +void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link); + + rtwvif_link->rand_tsf_done = false; +} + +int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + return rtw89_mac_vif_init(rtwdev, rtwvif_link); +} + +int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + return rtw89_mac_vif_deinit(rtwdev, rtwvif_link); +} + +static void +rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ +} + +static const struct rtw89_chan * +rtw89_hw_scan_search_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + const struct rtw89_chan *op = &rtwdev->scan_info.op_chan; + + if (band == op->band_type && channel == op->primary_channel) + return op; + + if (scan_info->extra_op.set) { + op = &scan_info->extra_op.chan; + if (band == op->band_type && channel == op->primary_channel) + return op; + } + + return NULL; +} + +static void +rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len) +{ + const struct rtw89_c2h_scanofld *c2h = + (const struct rtw89_c2h_scanofld *)skb->data; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + const struct rtw89_chan *op_chan; + struct rtw89_vif *rtwvif; + struct rtw89_chan new; + u16 actual_period, expect_period; + u8 reason, status, tx_fail, band; + u8 mac_idx, sw_def, fw_def; + u8 ver = U8_MAX; + u32 report_tsf; + u16 chan; + int ret; + + if (!rtwvif_link) + return; + + rtwvif = rtwvif_link->rtwvif; + + if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) + ver = 0; + + tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL); + status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS); + chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH); + reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN); + band = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_BAND); + actual_period = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PERIOD); + mac_idx = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_MAC_IDX); + + + if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ))) + band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { + sw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_SW_DEF); + fw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_FW_DEF); + report_tsf = le32_get_bits(c2h->w7, RTW89_C2H_SCANOFLD_W7_REPORT_TSF); + if (ver == 0) { + expect_period = + le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD); + } else { + actual_period = le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_PERIOD_V1); + expect_period = + le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1); + } + + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "sw_def: %d, fw_def: %d, tsf: %x, expect: %d\n", + sw_def, fw_def, report_tsf, expect_period); + } + + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n", + mac_idx, band, chan, reason, status, tx_fail, actual_period); + + switch (reason) { + case RTW89_SCAN_LEAVE_OP_NOTIFY: + case RTW89_SCAN_LEAVE_CH_NOTIFY: + op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan); + if (op_chan) { + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, false); + ieee80211_stop_queues(rtwdev->hw); + } else { + rtw89_phy_nhm_get_result(rtwdev, band, chan); + } + return; + case RTW89_SCAN_END_SCAN_NOTIFY: + if (rtwdev->scan_info.abort) + return; + + if (rtwvif_link && rtwvif->scan_req && + !list_empty(&rtwdev->scan_info.chan_list)) { + rtwdev->scan_info.delay = 0; + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_hw_scan_abort(rtwdev, rtwvif_link); + rtw89_warn(rtwdev, "HW scan failed: %d\n", ret); + } + } else { + rtw89_hw_scan_complete(rtwdev, rtwvif_link, false); + } + break; + case RTW89_SCAN_ENTER_OP_NOTIFY: + case RTW89_SCAN_ENTER_CH_NOTIFY: + op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan); + if (op_chan) { + rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, op_chan); + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, true); + ieee80211_wake_queues(rtwdev->hw); + } else { + rtw89_chan_create(&new, chan, chan, band, + RTW89_CHANNEL_WIDTH_20); + rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, + &new); + rtw89_phy_nhm_trigger(rtwdev); + } + break; + default: + return; + } +} + +static void +rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + struct sk_buff *skb) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + enum nl80211_cqm_rssi_threshold_event nl_event; + const struct rtw89_c2h_mac_bcnfltr_rpt *c2h = + (const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data; + u8 type, event, mac_id; + bool start_detect; + s8 sig; + + type = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE); + sig = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA) - MAX_RSSI; + event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT); + mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID); + + if (mac_id != rtwvif_link->mac_id) + return; + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "C2H bcnfltr rpt macid: %d, type: %d, ma: %d, event: %d\n", + mac_id, type, sig, event); + + switch (type) { + case RTW89_BCN_FLTR_BEACON_LOSS: + if (!rtwdev->scanning && !rtwvif->offchan && + !rtwvif_link->noa_once.in_duration) { + start_detect = rtw89_mcc_detect_go_bcn(rtwdev, rtwvif_link); + if (start_detect) + return; + + ieee80211_beacon_loss(vif); + } + + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + return; + case RTW89_BCN_FLTR_NOTIFY: + nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + break; + case RTW89_BCN_FLTR_RSSI: + if (event == RTW89_BCN_FLTR_RSSI_LOW) + nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + else if (event == RTW89_BCN_FLTR_RSSI_HIGH) + nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + else + return; + break; + default: + return; + } + + ieee80211_cqm_rssi_notify(vif, nl_event, sig, GFP_KERNEL); +} + +static void +rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u32 len) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h); +} + +static void +rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) +{ + /* N.B. This will run in interrupt context. */ + const struct rtw89_c2h_rev_ack *c2h = (const void *)skb_c2h->data; + + u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_REV_ACK_W2_CAT); + u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_REV_ACK_W2_CLASS); + u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_REV_ACK_W2_FUNC); + u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_REV_ACK_W2_H2C_SEQ); + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n", + h2c_cat, h2c_class, h2c_func, h2c_seq); + + if (h2c_cat != H2C_CAT_MAC) + return; + + switch (h2c_class) { + default: + return; + case H2C_CL_MAC_FW_OFLD: + switch (h2c_func) { + default: + return; + case H2C_FUNC_SCANOFLD: + case H2C_FUNC_SCANOFLD_BE: + scan_info->seq++; + break; + } + + return; + } +} + +static void +rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) +{ + /* N.B. This will run in interrupt context. */ + struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait; + struct rtw89_wait_info *ps_wait = &rtwdev->mac.ps_wait; + const struct rtw89_c2h_done_ack *c2h = + (const struct rtw89_c2h_done_ack *)skb_c2h->data; + u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT); + u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CLASS); + u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_FUNC); + u8 h2c_return = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_RETURN); + u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_SEQ); + struct rtw89_completion_data data = {}; + unsigned int cond; + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", + h2c_cat, h2c_class, h2c_func, h2c_return, h2c_seq); + + if (h2c_cat != H2C_CAT_MAC) + return; + + switch (h2c_class) { + default: + return; + case H2C_CL_MAC_PS: + switch (h2c_func) { + default: + return; + case H2C_FUNC_IPS_CFG: + cond = RTW89_PS_WAIT_COND_IPS_CFG; + break; + } + + data.err = !!h2c_return; + rtw89_complete_cond(ps_wait, cond, &data); + return; + case H2C_CL_MAC_FW_OFLD: + switch (h2c_func) { + default: + return; + case H2C_FUNC_ADD_SCANOFLD_CH: + cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; + h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN; + break; + case H2C_FUNC_SCANOFLD: + cond = RTW89_SCANOFLD_WAIT_COND_START; + break; + case H2C_FUNC_SCANOFLD_BE: + cond = RTW89_SCANOFLD_BE_WAIT_COND_START; + h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN; + break; + case H2C_FUNC_TRX_PROTECT: + cond = RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT; + break; + } + + data.err = !!h2c_return; + rtw89_complete_cond(fw_ofld_wait, cond, &data); + return; + } +} + +static void +rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_fw_log_dump(rtwdev, c2h->data, len); +} + +static void +rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ +} + +static void +rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) +{ + const struct rtw89_c2h_bcn_upd_done *c2h = + (const struct rtw89_c2h_bcn_upd_done *)skb_c2h->data; + u8 band, port, mbssid; + + port = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_PORT); + mbssid = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_MBSSID); + band = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX); + + rtw89_debug(rtwdev, RTW89_DBG_FW, + "BCN update done on port:%d mbssid:%d band:%d\n", + port, mbssid, band); +} + +static void +rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, + u32 len) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + const struct rtw89_c2h_pkt_ofld_rsp *c2h = + (const struct rtw89_c2h_pkt_ofld_rsp *)skb_c2h->data; + u16 pkt_len = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN); + u8 pkt_id = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID); + u8 pkt_op = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP); + struct rtw89_completion_data data = {}; + unsigned int cond; + + rtw89_debug(rtwdev, RTW89_DBG_FW, "pkt ofld rsp: id %d op %d len %d\n", + pkt_id, pkt_op, pkt_len); + + data.err = !pkt_len; + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op); + + rtw89_complete_cond(wait, cond, &data); +} + +static void +rtw89_mac_c2h_bcn_resend(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ +} + +static void +rtw89_mac_c2h_tx_duty_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) +{ + struct rtw89_c2h_tx_duty_rpt *c2h = + (struct rtw89_c2h_tx_duty_rpt *)skb_c2h->data; + u8 err; + + err = le32_get_bits(c2h->w2, RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "C2H TX duty rpt with err=%d\n", err); +} + +static void +rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u32 len) +{ + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_TSF32_TOGGLE_CHANGE); +} + +static void +rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + u8 group = RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h->data); + u8 func = RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h->data); + + switch (func) { + case H2C_FUNC_ADD_MCC: + case H2C_FUNC_START_MCC: + case H2C_FUNC_STOP_MCC: + case H2C_FUNC_DEL_MCC_GROUP: + case H2C_FUNC_RESET_MCC_GROUP: + case H2C_FUNC_MCC_REQ_TSF: + case H2C_FUNC_MCC_MACID_BITMAP: + case H2C_FUNC_MCC_SYNC: + case H2C_FUNC_MCC_SET_DURATION: + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H RCV ACK: func %d\n", func); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H RCV ACK: group %d, func %d\n", group, func); +} + +static void +rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + u8 group = RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h->data); + u8 func = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h->data); + u8 retcode = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h->data); + struct rtw89_completion_data data = {}; + unsigned int cond; + bool next = false; + + switch (func) { + case H2C_FUNC_MCC_REQ_TSF: + next = true; + break; + case H2C_FUNC_MCC_MACID_BITMAP: + case H2C_FUNC_MCC_SYNC: + case H2C_FUNC_MCC_SET_DURATION: + break; + case H2C_FUNC_ADD_MCC: + case H2C_FUNC_START_MCC: + case H2C_FUNC_STOP_MCC: + case H2C_FUNC_DEL_MCC_GROUP: + case H2C_FUNC_RESET_MCC_GROUP: + default: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H REQ ACK: func %d\n", func); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H REQ ACK: group %d, func %d, return code %d\n", + group, func, retcode); + + if (!retcode && next) + return; + + data.err = !!retcode; + cond = RTW89_MCC_WAIT_COND(group, func); + rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); +} + +static void +rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + u8 group = RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h->data); + struct rtw89_completion_data data = {}; + struct rtw89_mac_mcc_tsf_rpt *rpt; + unsigned int cond; + + rpt = (struct rtw89_mac_mcc_tsf_rpt *)data.buf; + rpt->macid_x = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h->data); + rpt->macid_y = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h->data); + rpt->tsf_x_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h->data); + rpt->tsf_x_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h->data); + rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data); + rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data); + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H TSF RPT: macid %d> %llu, macid %d> %llu\n", + rpt->macid_x, (u64)rpt->tsf_x_high << 32 | rpt->tsf_x_low, + rpt->macid_y, (u64)rpt->tsf_y_high << 32 | rpt->tsf_y_low); + + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF); + rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); +} + +static void +rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + u8 group = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h->data); + u8 macid = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h->data); + u8 status = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h->data); + u32 tsf_low = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h->data); + u32 tsf_high = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h->data); + struct rtw89_completion_data data = {}; + unsigned int cond; + bool rsp = true; + bool err; + u8 func; + + switch (status) { + case RTW89_MAC_MCC_ADD_ROLE_OK: + case RTW89_MAC_MCC_ADD_ROLE_FAIL: + func = H2C_FUNC_ADD_MCC; + err = status == RTW89_MAC_MCC_ADD_ROLE_FAIL; + break; + case RTW89_MAC_MCC_START_GROUP_OK: + case RTW89_MAC_MCC_START_GROUP_FAIL: + func = H2C_FUNC_START_MCC; + err = status == RTW89_MAC_MCC_START_GROUP_FAIL; + break; + case RTW89_MAC_MCC_STOP_GROUP_OK: + case RTW89_MAC_MCC_STOP_GROUP_FAIL: + func = H2C_FUNC_STOP_MCC; + err = status == RTW89_MAC_MCC_STOP_GROUP_FAIL; + break; + case RTW89_MAC_MCC_DEL_GROUP_OK: + case RTW89_MAC_MCC_DEL_GROUP_FAIL: + func = H2C_FUNC_DEL_MCC_GROUP; + err = status == RTW89_MAC_MCC_DEL_GROUP_FAIL; + break; + case RTW89_MAC_MCC_RESET_GROUP_OK: + case RTW89_MAC_MCC_RESET_GROUP_FAIL: + func = H2C_FUNC_RESET_MCC_GROUP; + err = status == RTW89_MAC_MCC_RESET_GROUP_FAIL; + break; + case RTW89_MAC_MCC_SWITCH_CH_OK: + case RTW89_MAC_MCC_SWITCH_CH_FAIL: + case RTW89_MAC_MCC_TXNULL0_OK: + case RTW89_MAC_MCC_TXNULL0_FAIL: + case RTW89_MAC_MCC_TXNULL1_OK: + case RTW89_MAC_MCC_TXNULL1_FAIL: + case RTW89_MAC_MCC_SWITCH_EARLY: + case RTW89_MAC_MCC_TBTT: + case RTW89_MAC_MCC_DURATION_START: + case RTW89_MAC_MCC_DURATION_END: + rsp = false; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H STS RPT: status %d\n", status); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H STS RPT: group %d, macid %d, status %d, tsf %llu\n", + group, macid, status, (u64)tsf_high << 32 | tsf_low); + + if (!rsp) + return; + + data.err = err; + cond = RTW89_MCC_WAIT_COND(group, func); + rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); +} + +static void +rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; + struct rtw89_tx_skb_data *skb_data; + u8 sw_define, tx_status, txcnt; + struct sk_buff *skb; + + if (rtwdev->chip->chip_id == RTL8922A) { + const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2; + + rpt_v2 = (const struct rtw89_c2h_mac_tx_rpt_v2 *)c2h->data; + sw_define = le32_get_bits(rpt_v2->w12, + RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2); + tx_status = le32_get_bits(rpt_v2->w12, + RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2); + txcnt = le32_get_bits(rpt_v2->w14, + RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2); + } else { + const struct rtw89_c2h_mac_tx_rpt *rpt; + + rpt = (const struct rtw89_c2h_mac_tx_rpt *)c2h->data; + sw_define = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE); + tx_status = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_TX_STATE); + if (rtwdev->chip->chip_id == RTL8852C) + txcnt = le32_get_bits(rpt->w5, + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1); + else + txcnt = le32_get_bits(rpt->w5, + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT); + } + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "C2H TX RPT: sn %d, tx_status %d, txcnt %d\n", + sw_define, tx_status, txcnt); + + /* claim sw_define is not over size of tx_rpt->skbs[] */ + static_assert(hweight32(RTW89_MAX_TX_RPTS_MASK) == + hweight32(RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2) && + hweight32(RTW89_MAX_TX_RPTS_MASK) == + hweight32(RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE)); + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + skb = tx_rpt->skbs[sw_define]; + + /* skip if no skb (normally shouldn't happen) */ + if (!skb) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "C2H TX RPT: no skb found in queue\n"); + return; + } + + skb_data = RTW89_TX_SKB_CB(skb); + + /* skip if TX attempt has failed and retry limit has not been + * reached yet + */ + if (tx_status != RTW89_TX_DONE && + txcnt != skb_data->tx_pkt_cnt_lmt) + return; + + tx_rpt->skbs[sw_define] = NULL; + rtw89_tx_rpt_tx_status(rtwdev, skb, tx_status); + } +} + +static void +rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + const struct rtw89_c2h_mrc_tsf_rpt *c2h_rpt; + struct rtw89_completion_data data = {}; + struct rtw89_mac_mrc_tsf_rpt *rpt; + unsigned int i; + + c2h_rpt = (const struct rtw89_c2h_mrc_tsf_rpt *)c2h->data; + rpt = (struct rtw89_mac_mrc_tsf_rpt *)data.buf; + rpt->num = min_t(u8, RTW89_MAC_MRC_MAX_REQ_TSF_NUM, + le32_get_bits(c2h_rpt->w2, + RTW89_C2H_MRC_TSF_RPT_W2_REQ_TSF_NUM)); + + for (i = 0; i < rpt->num; i++) { + u32 tsf_high = le32_to_cpu(c2h_rpt->infos[i].tsf_high); + u32 tsf_low = le32_to_cpu(c2h_rpt->infos[i].tsf_low); + + rpt->tsfs[i] = (u64)tsf_high << 32 | tsf_low; + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H TSF RPT: index %u> %llu\n", + i, rpt->tsfs[i]); + } + + rtw89_complete_cond(wait, RTW89_MRC_WAIT_COND_REQ_TSF, &data); +} + +static void +rtw89_mac_c2h_wow_aoac_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct rtw89_wait_info *wait = &rtw_wow->wait; + const struct rtw89_c2h_wow_aoac_report *c2h = + (const struct rtw89_c2h_wow_aoac_report *)skb->data; + struct rtw89_completion_data data = {}; + + aoac_rpt->rpt_ver = c2h->rpt_ver; + aoac_rpt->sec_type = c2h->sec_type; + aoac_rpt->key_idx = c2h->key_idx; + aoac_rpt->pattern_idx = c2h->pattern_idx; + aoac_rpt->rekey_ok = u8_get_bits(c2h->rekey_ok, + RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX); + memcpy(aoac_rpt->ptk_tx_iv, c2h->ptk_tx_iv, sizeof(aoac_rpt->ptk_tx_iv)); + memcpy(aoac_rpt->eapol_key_replay_count, c2h->eapol_key_replay_count, + sizeof(aoac_rpt->eapol_key_replay_count)); + memcpy(aoac_rpt->gtk, c2h->gtk, sizeof(aoac_rpt->gtk)); + memcpy(aoac_rpt->ptk_rx_iv, c2h->ptk_rx_iv, sizeof(aoac_rpt->ptk_rx_iv)); + memcpy(aoac_rpt->gtk_rx_iv, c2h->gtk_rx_iv, sizeof(aoac_rpt->gtk_rx_iv)); + aoac_rpt->igtk_key_id = le64_to_cpu(c2h->igtk_key_id); + aoac_rpt->igtk_ipn = le64_to_cpu(c2h->igtk_ipn); + memcpy(aoac_rpt->igtk, c2h->igtk, sizeof(aoac_rpt->igtk)); + + rtw89_complete_cond(wait, RTW89_WOW_WAIT_COND_AOAC, &data); +} + +static void +rtw89_mac_c2h_mlo_link_cfg_stat(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_mlo_link_cfg_rpt *c2h_rpt; + struct rtw89_wait_info *wait = &rtwdev->mlo.wait; + struct rtw89_completion_data data = {}; + unsigned int cond; + u16 mac_id; + u8 status; + + c2h_rpt = (const struct rtw89_c2h_mlo_link_cfg_rpt *)c2h->data; + + mac_id = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID); + status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS); + + data.err = status == RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST || + status == RTW89_C2H_MLO_LINK_CFG_RUNNING; + cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG); + rtw89_complete_cond(wait, cond, &data); +} + +static void +rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + struct rtw89_wait_info *wait = &rtwdev->mcc.wait; + const struct rtw89_c2h_mrc_status_rpt *c2h_rpt; + struct rtw89_completion_data data = {}; + enum rtw89_mac_mrc_status status; + unsigned int cond; + bool next = false; + u32 tsf_high; + u32 tsf_low; + u8 sch_idx; + u8 func; + + c2h_rpt = (const struct rtw89_c2h_mrc_status_rpt *)c2h->data; + sch_idx = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MRC_STATUS_RPT_W2_SCH_IDX); + status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MRC_STATUS_RPT_W2_STATUS); + tsf_high = le32_to_cpu(c2h_rpt->tsf_high); + tsf_low = le32_to_cpu(c2h_rpt->tsf_low); + + switch (status) { + case RTW89_MAC_MRC_START_SCH_OK: + func = H2C_FUNC_START_MRC; + break; + case RTW89_MAC_MRC_STOP_SCH_OK: + /* H2C_FUNC_DEL_MRC without STOP_ONLY, so wait for DEL_SCH_OK */ + func = H2C_FUNC_DEL_MRC; + next = true; + break; + case RTW89_MAC_MRC_DEL_SCH_OK: + func = H2C_FUNC_DEL_MRC; + break; + case RTW89_MAC_MRC_EMPTY_SCH_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: empty sch fail\n"); + return; + case RTW89_MAC_MRC_ROLE_NOT_EXIST_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: role not exist fail\n"); + return; + case RTW89_MAC_MRC_DATA_NOT_FOUND_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: data not found fail\n"); + return; + case RTW89_MAC_MRC_GET_NEXT_SLOT_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: get next slot fail\n"); + return; + case RTW89_MAC_MRC_ALT_ROLE_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: alt role fail\n"); + return; + case RTW89_MAC_MRC_ADD_PSTIMER_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: add ps timer fail\n"); + return; + case RTW89_MAC_MRC_MALLOC_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: malloc fail\n"); + return; + case RTW89_MAC_MRC_SWITCH_CH_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: switch ch fail\n"); + return; + case RTW89_MAC_MRC_TXNULL0_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: tx null-0 fail\n"); + return; + case RTW89_MAC_MRC_PORT_FUNC_EN_FAIL: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: port func en fail\n"); + return; + default: + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MRC C2H STS RPT: status %d\n", status); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MRC C2H STS RPT: sch_idx %d, status %d, tsf %llu\n", + sch_idx, status, (u64)tsf_high << 32 | tsf_low); + + if (next) + return; + + cond = RTW89_MRC_WAIT_COND(sch_idx, func); + rtw89_complete_cond(wait, cond, &data); +} + +static void +rtw89_mac_c2h_pwr_int_notify(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len) +{ + const struct rtw89_c2h_pwr_int_notify *c2h; + struct rtw89_sta_link *rtwsta_link; + struct ieee80211_sta *sta; + struct rtw89_sta *rtwsta; + u16 macid; + bool ps; + + c2h = (const struct rtw89_c2h_pwr_int_notify *)skb->data; + macid = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_MACID); + ps = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS); + + rcu_read_lock(); + + rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, macid); + if (unlikely(!rtwsta_link)) + goto out; + + rtwsta = rtwsta_link->rtwsta; + if (ps) + set_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags); + else + clear_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags); + + sta = rtwsta_to_sta(rtwsta); + ieee80211_sta_ps_transition(sta, ps); + +out: + rcu_read_unlock(); +} + +static +void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL, + [RTW89_MAC_C2H_FUNC_READ_RSP] = NULL, + [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = rtw89_mac_c2h_pkt_ofld_rsp, + [RTW89_MAC_C2H_FUNC_BCN_RESEND] = rtw89_mac_c2h_bcn_resend, + [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, + [RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp, + [RTW89_MAC_C2H_FUNC_TX_DUTY_RPT] = rtw89_mac_c2h_tx_duty_rpt, + [RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt, + [RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt, +}; + +static +void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack, + [RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack, + [RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log, + [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, + [RTW89_MAC_C2H_FUNC_BCN_UPD_DONE] = rtw89_mac_c2h_bcn_upd_done, +}; + +static +void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_MCC_RCV_ACK] = rtw89_mac_c2h_mcc_rcv_ack, + [RTW89_MAC_C2H_FUNC_MCC_REQ_ACK] = rtw89_mac_c2h_mcc_req_ack, + [RTW89_MAC_C2H_FUNC_MCC_TSF_RPT] = rtw89_mac_c2h_mcc_tsf_rpt, + [RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt, +}; + +static +void (* const rtw89_mac_c2h_misc_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_TX_REPORT] = rtw89_mac_c2h_tx_rpt, +}; + +static +void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_MLO_GET_TBL] = NULL, + [RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE] = NULL, + [RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE] = NULL, + [RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT] = NULL, + [RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT] = NULL, + [RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT] = rtw89_mac_c2h_mlo_link_cfg_stat, + [RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP] = NULL, +}; + +static +void (* const rtw89_mac_c2h_mrc_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_MRC_TSF_RPT] = rtw89_mac_c2h_mrc_tsf_rpt, + [RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT] = rtw89_mac_c2h_mrc_status_rpt, +}; + +static +void (* const rtw89_mac_c2h_wow_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_AOAC_REPORT] = rtw89_mac_c2h_wow_aoac_rpt, +}; + +static +void (* const rtw89_mac_c2h_ap_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY] = rtw89_mac_c2h_pwr_int_notify, +}; + +static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + const struct rtw89_c2h_scanofld *c2h = + (const struct rtw89_c2h_scanofld *)skb->data; + struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait; + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); + struct rtw89_completion_data data = {}; + unsigned int cond; + u8 status, reason; + + attr->is_scan_event = 1; + attr->scan_seq = scan_info->seq; + + status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS); + reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN); + data.err = status != RTW89_SCAN_STATUS_SUCCESS; + + if (reason == RTW89_SCAN_END_SCAN_NOTIFY) { + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP; + else + cond = RTW89_SCANOFLD_WAIT_COND_STOP; + + rtw89_complete_cond(fw_ofld_wait, cond, &data); + } +} + +bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u8 class, u8 func) +{ + switch (class) { + default: + return false; + case RTW89_MAC_C2H_CLASS_INFO: + switch (func) { + default: + return false; + case RTW89_MAC_C2H_FUNC_REC_ACK: + case RTW89_MAC_C2H_FUNC_DONE_ACK: + return true; + } + case RTW89_MAC_C2H_CLASS_OFLD: + switch (func) { + default: + return false; + case RTW89_MAC_C2H_FUNC_SCANOFLD_RSP: + rtw89_mac_c2h_scanofld_rsp_atomic(rtwdev, c2h); + return false; + case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP: + return true; + } + case RTW89_MAC_C2H_CLASS_MCC: + return true; + case RTW89_MAC_C2H_CLASS_MISC: + return true; + case RTW89_MAC_C2H_CLASS_MLO: + return true; + case RTW89_MAC_C2H_CLASS_MRC: + return true; + case RTW89_MAC_C2H_CLASS_WOW: + return true; + case RTW89_MAC_C2H_CLASS_AP: + switch (func) { + default: + return false; + case RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY: + return true; + } + } +} + +void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func) +{ + void (*handler)(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = NULL; + + switch (class) { + case RTW89_MAC_C2H_CLASS_INFO: + if (func < RTW89_MAC_C2H_FUNC_INFO_MAX) + handler = rtw89_mac_c2h_info_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_OFLD: + if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX) + handler = rtw89_mac_c2h_ofld_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_MCC: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC) + handler = rtw89_mac_c2h_mcc_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_MISC: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MISC) + handler = rtw89_mac_c2h_misc_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_MLO: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO) + handler = rtw89_mac_c2h_mlo_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_MRC: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MRC) + handler = rtw89_mac_c2h_mrc_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_WOW: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_WOW) + handler = rtw89_mac_c2h_wow_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_AP: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_AP) + handler = rtw89_mac_c2h_ap_handler[func]; + break; + case RTW89_MAC_C2H_CLASS_FWDBG: + case RTW89_MAC_C2H_CLASS_ROLE: + return; + default: + break; + } + if (!handler) { + rtw89_info_once(rtwdev, "MAC c2h class %d func %d not support\n", + class, func); + return; + } + handler(rtwdev, skb, len); +} + +static +bool rtw89_mac_get_txpwr_cr_ax(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 *cr) +{ + enum rtw89_qta_mode mode = rtwdev->mac.qta_mode; + u32 addr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx); + + if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR_AX) { + rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n", + addr); + goto error; + } + + if (addr >= CMAC1_START_ADDR_AX && addr <= CMAC1_END_ADDR_AX) + if (mode == RTW89_QTA_SCC) { + rtw89_err(rtwdev, + "[TXPWR] addr=0x%x but hw not enable\n", + addr); + goto error; + } + + *cr = addr; + return true; + +error: + rtw89_err(rtwdev, "[TXPWR] check txpwr cr 0x%x(phy%d) fail\n", + addr, phy_idx); + + return false; +} + +static +int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) +{ + u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PPDU_STAT, mac_idx); + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + if (!enable) { + rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); + return 0; + } + + rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | + B_AX_APP_MAC_INFO_RPT | + B_AX_APP_PLCP_HDR_RPT | + B_AX_PPDU_STAT_RPT_CRC32); + rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, + RTW89_PRPT_DEST_HOST); + + return 0; +} + +static +void __rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) +{ +#define MAC_AX_TIME_TH_SH 5 +#define MAC_AX_LEN_TH_SH 4 +#define MAC_AX_TIME_TH_MAX 255 +#define MAC_AX_LEN_TH_MAX 255 +#define MAC_AX_TIME_TH_DEF 88 +#define MAC_AX_LEN_TH_DEF 4080 + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct ieee80211_hw *hw = rtwdev->hw; + u32 rts_threshold = hw->wiphy->rts_threshold; + u32 time_th, len_th; + u32 reg; + + if (rts_threshold == (u32)-1) { + time_th = MAC_AX_TIME_TH_DEF; + len_th = MAC_AX_LEN_TH_DEF; + } else { + time_th = MAC_AX_TIME_TH_MAX << MAC_AX_TIME_TH_SH; + len_th = rts_threshold; + } + + time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX); + len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX); + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_len_ht, mac_idx); + rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th); + rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th); +} + +void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev) +{ + __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); + if (rtwdev->dbcc_en) + __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_1); +} + +void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop) +{ + bool empty; + int ret; + + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return; + + ret = read_poll_timeout(dle_is_txq_empty, empty, empty, + 10000, 200000, false, rtwdev); + if (ret && !drop && (rtwdev->total_sta_assoc || rtwdev->scanning)) + rtw89_info(rtwdev, "timed out to flush queues\n"); +} + +int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u8 val; + u16 val16; + u32 val32; + int ret; + + rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT); + if (chip_id != RTL8851B && chip_id != RTL8852BT) + rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN); + rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8); + rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK); + rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16); + if (chip_id != RTL8851B && chip_id != RTL8852BT) + rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24); + + val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0); + val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN; + rtw89_write16(rtwdev, R_AX_CCA_CFG_0, val16); + + ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32); + if (ret) { + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n"); + return ret; + } + val32 = val32 & B_AX_WL_RX_CTRL; + ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32); + if (ret) { + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n"); + return ret; + } + + switch (coex->pta_mode) { + case RTW89_MAC_AX_COEX_RTK_MODE: + val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); + val &= ~B_AX_BTMODE_MASK; + val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_0_3); + rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); + + val = rtw89_read8(rtwdev, R_AX_TDMA_MODE); + rtw89_write8(rtwdev, R_AX_TDMA_MODE, val | B_AX_RTK_BT_ENABLE); + + val = rtw89_read8(rtwdev, R_AX_BT_COEX_CFG_5); + val &= ~B_AX_BT_RPT_SAMPLE_RATE_MASK; + val |= FIELD_PREP(B_AX_BT_RPT_SAMPLE_RATE_MASK, MAC_AX_RTK_RATE); + rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_5, val); + break; + case RTW89_MAC_AX_COEX_CSR_MODE: + val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); + val &= ~B_AX_BTMODE_MASK; + val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_2); + rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); + + val16 = rtw89_read16(rtwdev, R_AX_CSR_MODE); + val16 &= ~B_AX_BT_PRI_DETECT_TO_MASK; + val16 |= FIELD_PREP(B_AX_BT_PRI_DETECT_TO_MASK, MAC_AX_CSR_PRI_TO); + val16 &= ~B_AX_BT_TRX_INIT_DETECT_MASK; + val16 |= FIELD_PREP(B_AX_BT_TRX_INIT_DETECT_MASK, MAC_AX_CSR_TRX_TO); + val16 &= ~B_AX_BT_STAT_DELAY_MASK; + val16 |= FIELD_PREP(B_AX_BT_STAT_DELAY_MASK, MAC_AX_CSR_DELAY); + val16 |= B_AX_ENHANCED_BT; + rtw89_write16(rtwdev, R_AX_CSR_MODE, val16); + + rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_2, MAC_AX_CSR_RATE); + break; + default: + return -EINVAL; + } + + switch (coex->direction) { + case RTW89_MAC_AX_COEX_INNER: + val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); + val = (val & ~BIT(2)) | BIT(1); + rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); + break; + case RTW89_MAC_AX_COEX_OUTPUT: + val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); + val = val | BIT(1) | BIT(0); + rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); + break; + case RTW89_MAC_AX_COEX_INPUT: + val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); + val = val & ~(BIT(2) | BIT(1)); + rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_coex_init); + +int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex *coex) +{ + rtw89_write32_set(rtwdev, R_AX_BTC_CFG, + B_AX_BTC_EN | B_AX_BTG_LNA1_GAIN_SEL); + rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN); + rtw89_write16_set(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_EN); + rtw89_write16_clr(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_BRK_TXOP_EN); + + switch (coex->pta_mode) { + case RTW89_MAC_AX_COEX_RTK_MODE: + rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK, + MAC_AX_RTK_MODE); + rtw89_write32_mask(rtwdev, R_AX_RTK_MODE_CFG_V1, + B_AX_SAMPLE_CLK_MASK, MAC_AX_RTK_RATE); + break; + case RTW89_MAC_AX_COEX_CSR_MODE: + rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK, + MAC_AX_CSR_MODE); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_coex_init_v1); + +int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + u32 val = 0, ret; + + if (gnt_cfg->band[0].gnt_bt) + val |= B_AX_GNT_BT_RFC_S0_SW_VAL | B_AX_GNT_BT_BB_S0_SW_VAL; + + if (gnt_cfg->band[0].gnt_bt_sw_en) + val |= B_AX_GNT_BT_RFC_S0_SW_CTRL | B_AX_GNT_BT_BB_S0_SW_CTRL; + + if (gnt_cfg->band[0].gnt_wl) + val |= B_AX_GNT_WL_RFC_S0_SW_VAL | B_AX_GNT_WL_BB_S0_SW_VAL; + + if (gnt_cfg->band[0].gnt_wl_sw_en) + val |= B_AX_GNT_WL_RFC_S0_SW_CTRL | B_AX_GNT_WL_BB_S0_SW_CTRL; + + if (gnt_cfg->band[1].gnt_bt) + val |= B_AX_GNT_BT_RFC_S1_SW_VAL | B_AX_GNT_BT_BB_S1_SW_VAL; + + if (gnt_cfg->band[1].gnt_bt_sw_en) + val |= B_AX_GNT_BT_RFC_S1_SW_CTRL | B_AX_GNT_BT_BB_S1_SW_CTRL; + + if (gnt_cfg->band[1].gnt_wl) + val |= B_AX_GNT_WL_RFC_S1_SW_VAL | B_AX_GNT_WL_BB_S1_SW_VAL; + + if (gnt_cfg->band[1].gnt_wl_sw_en) + val |= B_AX_GNT_WL_RFC_S1_SW_CTRL | B_AX_GNT_WL_BB_S1_SW_CTRL; + + ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val); + if (ret) { + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "Write LTE fail!\n"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_gnt); + +int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + u32 val = 0; + + if (gnt_cfg->band[0].gnt_bt) + val |= B_AX_GNT_BT_RFC_S0_VAL | B_AX_GNT_BT_RX_VAL | + B_AX_GNT_BT_TX_VAL; + + if (gnt_cfg->band[0].gnt_bt_sw_en) + val |= B_AX_GNT_BT_RFC_S0_SWCTRL | B_AX_GNT_BT_RX_SWCTRL | + B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL; + + if (gnt_cfg->band[0].gnt_wl) + val |= B_AX_GNT_WL_RFC_S0_VAL | B_AX_GNT_WL_RX_VAL | + B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL; + + if (gnt_cfg->band[0].gnt_wl_sw_en) + val |= B_AX_GNT_WL_RFC_S0_SWCTRL | B_AX_GNT_WL_RX_SWCTRL | + B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL; + + if (gnt_cfg->band[1].gnt_bt) + val |= B_AX_GNT_BT_RFC_S1_VAL | B_AX_GNT_BT_RX_VAL | + B_AX_GNT_BT_TX_VAL; + + if (gnt_cfg->band[1].gnt_bt_sw_en) + val |= B_AX_GNT_BT_RFC_S1_SWCTRL | B_AX_GNT_BT_RX_SWCTRL | + B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL; + + if (gnt_cfg->band[1].gnt_wl) + val |= B_AX_GNT_WL_RFC_S1_VAL | B_AX_GNT_WL_RX_VAL | + B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL; + + if (gnt_cfg->band[1].gnt_wl_sw_en) + val |= B_AX_GNT_WL_RFC_S1_SWCTRL | B_AX_GNT_WL_RX_SWCTRL | + B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL; + + if (gnt_cfg->bt[0].wlan_act_en) + val |= B_AX_WL_ACT_SWCTRL; + if (gnt_cfg->bt[0].wlan_act) + val |= B_AX_WL_ACT_VAL; + if (gnt_cfg->bt[1].wlan_act_en) + val |= B_AX_WL_ACT2_SWCTRL; + if (gnt_cfg->bt[1].wlan_act) + val |= B_AX_WL_ACT2_VAL; + + rtw89_write32(rtwdev, R_AX_GNT_SW_CTRL, val); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v1); + +static +int rtw89_mac_cfg_plt_ax(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) +{ + u32 reg; + u16 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, plt->band); + val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_TX_PLT_GNT_WL : 0) | + (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_RX_PLT_GNT_LTE_RX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_RX_PLT_GNT_BT_TX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_RX_PLT_GNT_BT_RX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_RX_PLT_GNT_WL : 0) | + B_AX_PLT_EN; + rtw89_write16(rtwdev, reg, val); + + return 0; +} + +void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg = chip->btc_sb.n[0].cfg; + u32 fw_sb; + + fw_sb = rtw89_read32(rtwdev, reg); + fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb); + fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY; + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + fw_sb = fw_sb | MAC_AX_NOTIFY_PWR_MAJOR; + else + fw_sb = fw_sb | MAC_AX_NOTIFY_TP_MAJOR; + val = FIELD_GET(B_MAC_AX_SB_DRV_MASK, val); + val = B_AX_TOGGLE | + FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) | + FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb); + rtw89_write32(rtwdev, reg, val); + fsleep(1000); /* avoid BT FW loss information */ +} + +u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg = chip->btc_sb.n[0].get; + + return rtw89_read32(rtwdev, reg); +} + +int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl) +{ + u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); + + val = wl ? val | BIT(2) : val & ~BIT(2); + rtw89_write8(rtwdev, R_AX_SYS_SDIO_CTRL + 3, val); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path); + +int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl) +{ + struct rtw89_mac_ax_coex_gnt gnt = {}; + int i; + + if (wl) + return 0; + + for (i = 0; i < RTW89_PHY_NUM; i++) { + gnt.band[i].gnt_bt_sw_en = 1; + gnt.band[i].gnt_bt = 1; + gnt.band[i].gnt_wl_sw_en = 1; + gnt.band[i].gnt_wl = 0; + } + + return rtw89_mac_cfg_gnt_v1(rtwdev, &gnt); +} +EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1); + +bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 val = 0; + + if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) + return false; + else if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3, + B_AX_LTE_MUX_CTRL_PATH >> 24); + + return !!val; +} + +static u16 rtw89_mac_get_plt_cnt_ax(struct rtw89_dev *rtwdev, u8 band) +{ + u32 reg; + u16 cnt; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, band); + cnt = rtw89_read32_mask(rtwdev, reg, B_AX_BT_PLT_PKT_CNT_MASK); + rtw89_write16_set(rtwdev, reg, B_AX_BT_PLT_RST); + + return cnt; +} + +static void rtw89_mac_bfee_standby_timer(struct rtw89_dev *rtwdev, u8 mac_idx, + bool keep) +{ + u32 reg; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) + return; + + rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee standby_timer to %d\n", keep); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx); + if (keep) { + set_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); + rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, + BFRP_RX_STANDBY_TIMER_KEEP); + } else { + clear_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); + rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, + BFRP_RX_STANDBY_TIMER_RELEASE); + } +} + +void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 reg; + u32 mask = mac->bfee_ctrl.mask; + + rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en); + reg = rtw89_mac_reg_by_idx(rtwdev, mac->bfee_ctrl.addr, mac_idx); + if (en) { + set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); + rtw89_write32_set(rtwdev, reg, mask); + } else { + clear_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); + rtw89_write32_clr(rtwdev, reg, mask); + } +} + +static int rtw89_mac_init_bfee_ax(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + u32 val32; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + /* AP mode set tx gid to 63 */ + /* STA mode set tx gid to 0(default) */ + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMER_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx); + rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx); + val32 = FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER); + rtw89_write32(rtwdev, reg, val32); + rtw89_mac_bfee_standby_timer(rtwdev, mac_idx, true); + rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL | + B_AX_BFMEE_USE_NSTS | + B_AX_BFMEE_CSI_GID_SEL | + B_AX_BFMEE_CSI_FORCE_RETE_EN); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx); + rtw89_write32(rtwdev, reg, + u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) | + u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) | + u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK)); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CSIRPT_OPTION, mac_idx); + rtw89_write32_set(rtwdev, reg, + B_AX_CSIPRT_VHTSU_AID_EN | B_AX_CSIPRT_HESU_AID_EN); + + return 0; +} + +static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; + struct ieee80211_link_sta *link_sta; + u8 mac_idx = rtwvif_link->mac_idx; + u8 port_sel = rtwvif_link->port; + u8 sound_dim = 3, t; + u8 *phy_cap; + u32 reg; + u16 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; + + if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || + (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { + ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); + stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ); + t = FIELD_GET(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, + phy_cap[5]); + sound_dim = min(sound_dim, t); + } + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); + t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, + link_sta->vht_cap.cap); + sound_dim = min(sound_dim, t); + } + nc = min(nc, sound_dim); + nr = min(nr, sound_dim); + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); + + val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_NR_MASK, nr) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_NG_MASK, ng) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_CB_MASK, cb) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_CS_MASK, cs) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_LDPC_EN, ldpc_en) | + FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en); + + if (port_sel == 0) + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + else + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx); + + rtw89_write16(rtwdev, reg, val); + + return 0; +} + +static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); + struct ieee80211_link_sta *link_sta; + u8 mac_idx = rtwvif_link->mac_idx; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->he_cap.has_he) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | + BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | + BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); + } + if (link_sta->vht_cap.vht_supported) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | + BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | + BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); + } + if (link_sta->ht_cap.ht_supported) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | + BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | + BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); + } + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); + rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN); + rtw89_write32(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx), + rrsc); + + return 0; +} + +static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_link_sta *link_sta; + bool has_beamformer_cap; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta); + + rcu_read_unlock(); + + if (has_beamformer_cap) { + rtw89_debug(rtwdev, RTW89_DBG_BF, + "initialize bfee for new association\n"); + rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx); + rtw89_mac_set_csi_para_reg_ax(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_csi_rrsc_ax(rtwdev, rtwvif_link, rtwsta_link); + } +} + +void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false); +} + +void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_mac_mu_gid_addr *addr = mac->mu_gid; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + u8 mac_idx; + __le32 *p; + + rtwvif_link = rtwvif->links[conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, conf->link_id); + return; + } + + mac_idx = rtwvif_link->mac_idx; + + rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n"); + + p = (__le32 *)conf->mu_group.membership; + rtw89_write32(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, addr->position_en[0], mac_idx), + le32_to_cpu(p[0])); + rtw89_write32(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, addr->position_en[1], mac_idx), + le32_to_cpu(p[1])); + + p = (__le32 *)conf->mu_group.position; + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[0], mac_idx), + le32_to_cpu(p[0])); + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[1], mac_idx), + le32_to_cpu(p[1])); + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[2], mac_idx), + le32_to_cpu(p[2])); + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[3], mac_idx), + le32_to_cpu(p[3])); +} + +struct rtw89_mac_bf_monitor_iter_data { + struct rtw89_dev *rtwdev; + struct rtw89_sta_link *down_rtwsta_link; + int count; +}; + +static +void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_mac_bf_monitor_iter_data *iter_data = + (struct rtw89_mac_bf_monitor_iter_data *)data; + struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct ieee80211_link_sta *link_sta; + struct rtw89_sta_link *rtwsta_link; + bool has_beamformer_cap = false; + int *count = &iter_data->count; + unsigned int link_id; + + rcu_read_lock(); + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + if (rtwsta_link == down_rtwsta_link) + continue; + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (rtw89_sta_has_beamformer_cap(link_sta)) { + has_beamformer_cap = true; + break; + } + } + + if (has_beamformer_cap) + (*count)++; + + rcu_read_unlock(); +} + +void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + bool disconnect) +{ + struct rtw89_mac_bf_monitor_iter_data data; + + data.rtwdev = rtwdev; + data.down_rtwsta_link = disconnect ? rtwsta_link : NULL; + data.count = 0; + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_mac_bf_monitor_calc_iter, + &data); + + rtw89_debug(rtwdev, RTW89_DBG_BF, "bfee STA count=%d\n", data.count); + if (data.count) + set_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); + else + clear_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); +} + +void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_traffic_stats *stats = &rtwdev->stats; + struct rtw89_vif_link *rtwvif_link; + bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv; + bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); + struct rtw89_vif *rtwvif; + bool keep_timer = true; + unsigned int link_id; + bool old_keep_timer; + + old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); + + if (stats->tx_tfc_lv <= RTW89_TFC_LOW && stats->rx_tfc_lv <= RTW89_TFC_LOW) + keep_timer = false; + + if (keep_timer != old_keep_timer) { + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx, + keep_timer); + } + + if (en == old) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en); +} + +static int +__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + u32 tx_time) +{ +#define MAC_AX_DFLT_TX_TIME 5280 + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; + u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + u32 reg; + int ret = 0; + + if (chip->txtime_limit_2ghz) { + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[mac_idx]; + + if (chan->band_type == RTW89_BAND_2G) + max_tx_time = min_t(u32, max_tx_time, + chip->txtime_limit_2ghz); + } + + if (rtwsta_link->cctl_tx_time) { + rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9; + ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); + } else { + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) { + rtw89_warn(rtwdev, "failed to check cmac in set txtime\n"); + return ret; + } + + if (chip->chip_gen == RTW89_CHIP_AX) + max_tx_time >>= 5; + else + max_tx_time = max_tx_time * 1000 >> 15; + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask, max_tx_time); + } + + return ret; +} + +int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + bool resume, u32 tx_time) +{ + int ret = 0; + + if (!resume) { + rtwsta_link->cctl_tx_time = true; + ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time); + } else { + ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time); + rtwsta_link->cctl_tx_time = false; + } + + return ret; +} + +int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + u32 *tx_time) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; + u32 reg; + int ret = 0; + + if (rtwsta_link->cctl_tx_time) { + *tx_time = (rtwsta_link->ampdu_max_time + 1) << 9; + } else { + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) { + rtw89_warn(rtwdev, "failed to check cmac in tx_time\n"); + return ret; + } + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx); + *tx_time = rtw89_read32_mask(rtwdev, reg, mac->agg_limit.mask) << 5; + } + + return ret; +} + +int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + bool resume, u8 tx_retry) +{ + int ret = 0; + + rtwsta_link->data_tx_cnt_lmt = tx_retry; + + if (!resume) { + rtwsta_link->cctl_tx_retry_limit = true; + ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); + } else { + ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); + rtwsta_link->cctl_tx_retry_limit = false; + } + + return ret; +} + +int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 *tx_retry) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; + u32 reg; + int ret = 0; + + if (rtwsta_link->cctl_tx_retry_limit) { + *tx_retry = rtwsta_link->data_tx_cnt_lmt; + } else { + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) { + rtw89_warn(rtwdev, "failed to check cmac in rty_lmt\n"); + return ret; + } + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->txcnt_limit.addr, mac_idx); + *tx_retry = rtw89_read32_mask(rtwdev, reg, mac->txcnt_limit.mask); + } + + return ret; +} + +int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u8 mac_idx = rtwvif_link->mac_idx; + u16 set = mac->muedca_ctrl.mask; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->muedca_ctrl.addr, mac_idx); + if (en) + rtw89_write16_set(rtwdev, reg, set); + else + rtw89_write16_clr(rtwdev, reg, set); + + return 0; +} + +static +int rtw89_mac_write_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask) +{ + u32 val32; + int ret; + + val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) | + FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, val) | + FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, mask) | + FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_WRITE) | + FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1); + rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL), + 50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL); + if (ret) { + rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n", + offset, val, mask); + return ret; + } + + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + (u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset || + u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK) != val)) + rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n", + offset, val, val32); + + return 0; +} + +static +int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val) +{ + u32 val32; + int ret; + + val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) | + FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, 0x00) | + FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, 0x00) | + FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_READ) | + FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1); + rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL), + 50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL); + if (ret) { + rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset); + return ret; + } + + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset) + rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n", + offset, val32); + + *val = u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK); + + return 0; +} + +static +void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + static const enum rtw89_pkt_drop_sel sels[] = { + RTW89_PKT_DROP_SEL_MACID_BE_ONCE, + RTW89_PKT_DROP_SEL_MACID_BK_ONCE, + RTW89_PKT_DROP_SEL_MACID_VI_ONCE, + RTW89_PKT_DROP_SEL_MACID_VO_ONCE, + }; + struct rtw89_pkt_drop_params params = {0}; + int i; + + params.mac_band = rtwvif_link->mac_idx; + params.macid = rtwsta_link->mac_id; + params.port = rtwvif_link->port; + params.mbssid = 0; + params.tf_trs = rtwvif_link->trigger; + + for (i = 0; i < ARRAY_SIZE(sels); i++) { + params.sel = sels[i]; + rtw89_fw_h2c_pkt_drop(rtwdev, ¶ms); + } +} + +static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + struct rtw89_vif *target = data; + unsigned int link_id; + + if (rtwvif != target) + return; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + rtw89_mac_pkt_drop_sta(rtwdev, rtwvif_link, rtwsta_link); + } +} + +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_mac_pkt_drop_vif_iter, + rtwvif); +} + +int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx band) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_pkt_drop_params params = {0}; + bool empty; + int i, ret = 0, try_cnt = 3; + + params.mac_band = band; + params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE; + + for (i = 0; i < try_cnt; i++) { + ret = read_poll_timeout(mac->is_txq_empty, empty, empty, 50, + 50000, false, rtwdev); + if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) + rtw89_fw_h2c_pkt_drop(rtwdev, ¶ms); + else + return 0; + } + return ret; +} + +static int _rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable) +{ + struct rtw89_mac_h2c_info h2c_info = {}; + struct rtw89_mac_c2h_info c2h_info = {}; + int ret; + + if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw)) + return 0; + + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL; + h2c_info.content_len = sizeof(h2c_info.u.hdr); + h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN); + + ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); + if (ret) + return ret; + + if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK) + ret = -EINVAL; + + return ret; +} + +int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable) +{ + int i, ret; + + for (i = 0; i < CPU_IO_RX_RETRY_CNT; i++) { + ret = _rtw89_mac_cpu_io_rx(rtwdev, wow_enable); + if (!ret) + return 0; + } + + return ret; +} + +static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + int ret; + + if (enable_wow) { + ret = rtw89_mac_resize_ple_rx_quota(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret); + return ret; + } + + rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP); + rtw89_mac_cpu_io_rx(rtwdev, enable_wow); + rtw89_write32_clr(rtwdev, mac->rx_fltr, B_AX_SNIFFER_MODE); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0); + rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0); + rtw89_write32(rtwdev, R_AX_TF_FWD, 0); + rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0); + + if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw)) + return 0; + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY); + else + rtw89_write32_set(rtwdev, R_AX_DBG_WOW, + B_AX_DBG_WOW_CPU_IO_RX_EN); + } else { + ret = rtw89_mac_resize_ple_rx_quota(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret); + return ret; + } + + rtw89_mac_cpu_io_rx(rtwdev, enable_wow); + rtw89_write32_clr(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD); + rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD); + } + + return 0; +} + +static u8 rtw89_fw_get_rdy_ax(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) +{ + u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL); + + return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val); +} + +static +int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev, + bool h2c_or_fwdl) +{ + u8 check = h2c_or_fwdl ? B_AX_H2C_PATH_RDY : B_AX_FWDL_PATH_RDY; + u32 timeout; + u8 val; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + timeout = FWDL_WAIT_CNT_USB; + else + timeout = FWDL_WAIT_CNT; + + return read_poll_timeout_atomic(rtw89_read8, val, val & check, + 1, timeout, false, + rtwdev, R_AX_WCPU_FW_CTRL); +} + +static +void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode) +{ + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; + + if (!sec->secure_boot) + return; + + rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL, + B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode); + rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL, + B_AX_IDMEM_SHARE_MODE_RECORD_VALID); +} + +const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { + .band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET, + .filter_model_addr = R_AX_FILTER_MODEL_ADDR, + .indir_access_addr = R_AX_INDIR_ACCESS_ENTRY, + .mem_base_addrs = rtw89_mac_mem_base_addrs_ax, + .mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_AX, + .rx_fltr = R_AX_RX_FLTR_OPT, + .default_rx_fltr = DEFAULT_AX_RX_FLTR, + .port_base = &rtw89_port_base_ax, + .agg_len_ht = R_AX_AGG_LEN_HT_0, + .ps_status = R_AX_PPWRBIT_SETTING, + .mu_gid = &rtw89_mac_mu_gid_addr_ax, + .boot_dbg = R_AX_BOOT_DBG, + + .muedca_ctrl = { + .addr = R_AX_MUEDCA_EN, + .mask = B_AX_MUEDCA_EN_0 | B_AX_SET_MUEDCATIMER_TF_0, + }, + .bfee_ctrl = { + .addr = R_AX_BFMEE_RESP_OPTION, + .mask = B_AX_BFMEE_HT_NDPA_EN | B_AX_BFMEE_VHT_NDPA_EN | + B_AX_BFMEE_HE_NDPA_EN, + }, + .narrow_bw_ru_dis = { + .addr = R_AX_RXTRIG_TEST_USER_2, + .mask = B_AX_RXTRIG_RU26_DIS, + }, + .wow_ctrl = {.addr = R_AX_WOW_CTRL, .mask = B_AX_WOW_WOWEN,}, + .agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, .mask = B_AX_AMPDU_MAX_TIME_MASK,}, + .ra_agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, + .mask = B_AX_RA_TRY_RATE_AGG_LMT_MASK,}, + .txcnt_limit = {.addr = R_AX_TXCNT, .mask = B_AX_L_TXCNT_LMT_MASK,}, + + .check_mac_en = rtw89_mac_check_mac_en_ax, + .sys_init = sys_init_ax, + .trx_init = trx_init_ax, + .preload_init = preload_init_set_ax, + .clr_aon_intr = NULL, + .err_imr_ctrl = err_imr_ctrl_ax, + .mac_func_en = NULL, + .hci_func_en = rtw89_mac_hci_func_en_ax, + .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_ax, + .dle_func_en = dle_func_en_ax, + .dle_clk_en = dle_clk_en_ax, + .bf_assoc = rtw89_mac_bf_assoc_ax, + + .typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax, + .cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_ax, + .cfg_phy_rpt = NULL, + .set_edcca_mode = NULL, + .set_vcore_cfg = NULL, + + .dle_mix_cfg = dle_mix_cfg_ax, + .chk_dle_rdy = chk_dle_rdy_ax, + .dle_buf_req = dle_buf_req_ax, + .hfc_func_en = hfc_func_en_ax, + .hfc_h2c_cfg = hfc_h2c_cfg_ax, + .hfc_mix_cfg = hfc_mix_cfg_ax, + .hfc_get_mix_info = hfc_get_mix_info_ax, + .wde_quota_cfg = wde_quota_cfg_ax, + .ple_quota_cfg = ple_quota_cfg_ax, + .set_cpuio = set_cpuio_ax, + .dle_quota_change = dle_quota_change_ax, + + .reset_pwr_state = rtw89_mac_reset_pwr_state_ax, + .disable_cpu = rtw89_mac_disable_cpu_ax, + .fwdl_preconfig = NULL, + .fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax, + .fwdl_get_status = rtw89_fw_get_rdy_ax, + .fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax, + .fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax, + .parse_efuse_map = rtw89_parse_efuse_map_ax, + .parse_phycap_map = rtw89_parse_phycap_map_ax, + .cnv_efuse_state = rtw89_cnv_efuse_state_ax, + .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax, + .efuse_read_ecv = NULL, + .efuse_read_thermal_k = NULL, + .efuse_read_pwr_data = NULL, + + .cfg_plt = rtw89_mac_cfg_plt_ax, + .get_plt_cnt = rtw89_mac_get_plt_cnt_ax, + + .get_txpwr_cr = rtw89_mac_get_txpwr_cr_ax, + + .write_xtal_si = rtw89_mac_write_xtal_si_ax, + .read_xtal_si = rtw89_mac_read_xtal_si_ax, + + .dump_qta_lost = rtw89_mac_dump_qta_lost_ax, + .dump_err_status = rtw89_mac_dump_err_status_ax, + + .is_txq_empty = mac_is_txq_empty_ax, + + .prep_chan_list = rtw89_hw_scan_prep_chan_list_ax, + .free_chan_list = rtw89_hw_scan_free_chan_list_ax, + .add_chan_list = rtw89_hw_scan_add_chan_list_ax, + .add_chan_list_pno = rtw89_pno_scan_add_chan_list_ax, + .scan_offload = rtw89_fw_h2c_scan_offload_ax, + + .wow_config_mac = rtw89_wow_config_mac_ax, +}; +EXPORT_SYMBOL(rtw89_mac_gen_ax); diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h new file mode 100644 index 000000000..8419bcd39 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -0,0 +1,1932 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_MAC_H__ +#define __RTW89_MAC_H__ + +#include "core.h" +#include "fw.h" +#include "reg.h" + +#define MAC_MEM_DUMP_PAGE_SIZE_AX 0x40000 +#define MAC_MEM_DUMP_PAGE_SIZE_BE 0x80000 + +#define ADDR_CAM_ENT_SIZE 0x40 +#define ADDR_CAM_ENT_SHORT_SIZE 0x20 +#define BSSID_CAM_ENT_SIZE 0x08 +#define HFC_PAGE_UNIT 64 +#define RPWM_TRY_CNT 3 +#define CPU_IO_RX_RETRY_CNT 3 + +enum rtw89_mac_hwmod_sel { + RTW89_DMAC_SEL = 0, + RTW89_CMAC_SEL = 1, + + RTW89_MAC_INVALID, +}; + +enum rtw89_mac_fwd_target { + RTW89_FWD_DONT_CARE = 0, + RTW89_FWD_TO_HOST = 1, + RTW89_FWD_TO_WLAN_CPU = 2 +}; + +enum rtw89_mac_wd_dma_intvl { + RTW89_MAC_WD_DMA_INTVL_0S, + RTW89_MAC_WD_DMA_INTVL_256NS, + RTW89_MAC_WD_DMA_INTVL_512NS, + RTW89_MAC_WD_DMA_INTVL_768NS, + RTW89_MAC_WD_DMA_INTVL_1US, + RTW89_MAC_WD_DMA_INTVL_1_5US, + RTW89_MAC_WD_DMA_INTVL_2US, + RTW89_MAC_WD_DMA_INTVL_4US, + RTW89_MAC_WD_DMA_INTVL_8US, + RTW89_MAC_WD_DMA_INTVL_16US, + RTW89_MAC_WD_DMA_INTVL_DEF = 0xFE +}; + +enum rtw89_mac_multi_tag_num { + RTW89_MAC_TAG_NUM_1, + RTW89_MAC_TAG_NUM_2, + RTW89_MAC_TAG_NUM_3, + RTW89_MAC_TAG_NUM_4, + RTW89_MAC_TAG_NUM_5, + RTW89_MAC_TAG_NUM_6, + RTW89_MAC_TAG_NUM_7, + RTW89_MAC_TAG_NUM_8, + RTW89_MAC_TAG_NUM_DEF = 0xFE +}; + +enum rtw89_mac_lbc_tmr { + RTW89_MAC_LBC_TMR_8US = 0, + RTW89_MAC_LBC_TMR_16US, + RTW89_MAC_LBC_TMR_32US, + RTW89_MAC_LBC_TMR_64US, + RTW89_MAC_LBC_TMR_128US, + RTW89_MAC_LBC_TMR_256US, + RTW89_MAC_LBC_TMR_512US, + RTW89_MAC_LBC_TMR_1MS, + RTW89_MAC_LBC_TMR_2MS, + RTW89_MAC_LBC_TMR_4MS, + RTW89_MAC_LBC_TMR_8MS, + RTW89_MAC_LBC_TMR_DEF = 0xFE +}; + +enum rtw89_mac_cpuio_op_cmd_type { + CPUIO_OP_CMD_GET_1ST_PID = 0, + CPUIO_OP_CMD_GET_NEXT_PID = 1, + CPUIO_OP_CMD_ENQ_TO_TAIL = 4, + CPUIO_OP_CMD_ENQ_TO_HEAD = 5, + CPUIO_OP_CMD_DEQ = 8, + CPUIO_OP_CMD_DEQ_ENQ_ALL = 9, + CPUIO_OP_CMD_DEQ_ENQ_TO_TAIL = 12 +}; + +enum rtw89_mac_wde_dle_port_id { + WDE_DLE_PORT_ID_DISPATCH = 0, + WDE_DLE_PORT_ID_PKTIN = 1, + WDE_DLE_PORT_ID_CMAC0 = 3, + WDE_DLE_PORT_ID_CMAC1 = 4, + WDE_DLE_PORT_ID_CPU_IO = 6, + WDE_DLE_PORT_ID_WDRLS = 7, + WDE_DLE_PORT_ID_END = 8 +}; + +enum rtw89_mac_wde_dle_queid_wdrls { + WDE_DLE_QUEID_TXOK = 0, + WDE_DLE_QUEID_DROP_RETRY_LIMIT = 1, + WDE_DLE_QUEID_DROP_LIFETIME_TO = 2, + WDE_DLE_QUEID_DROP_MACID_DROP = 3, + WDE_DLE_QUEID_NO_REPORT = 4 +}; + +enum rtw89_mac_ple_dle_port_id { + PLE_DLE_PORT_ID_DISPATCH = 0, + PLE_DLE_PORT_ID_MPDU = 1, + PLE_DLE_PORT_ID_SEC = 2, + PLE_DLE_PORT_ID_CMAC0 = 3, + PLE_DLE_PORT_ID_CMAC1 = 4, + PLE_DLE_PORT_ID_WDRLS = 5, + PLE_DLE_PORT_ID_CPU_IO = 6, + PLE_DLE_PORT_ID_PLRLS = 7, + PLE_DLE_PORT_ID_END = 8 +}; + +enum rtw89_mac_ple_dle_queid_plrls { + PLE_DLE_QUEID_NO_REPORT = 0x0 +}; + +enum rtw89_machdr_frame_type { + RTW89_MGNT = 0, + RTW89_CTRL = 1, + RTW89_DATA = 2, +}; + +enum rtw89_mac_dle_dfi_type { + DLE_DFI_TYPE_FREEPG = 0, + DLE_DFI_TYPE_QUOTA = 1, + DLE_DFI_TYPE_PAGELLT = 2, + DLE_DFI_TYPE_PKTINFO = 3, + DLE_DFI_TYPE_PREPKTLLT = 4, + DLE_DFI_TYPE_NXTPKTLLT = 5, + DLE_DFI_TYPE_QLNKTBL = 6, + DLE_DFI_TYPE_QEMPTY = 7, +}; + +enum rtw89_mac_dle_wde_quota_id { + WDE_QTAID_HOST_IF = 0, + WDE_QTAID_WLAN_CPU = 1, + WDE_QTAID_DATA_CPU = 2, + WDE_QTAID_PKTIN = 3, + WDE_QTAID_CPUIO = 4, +}; + +enum rtw89_mac_dle_ple_quota_id { + PLE_QTAID_B0_TXPL = 0, + PLE_QTAID_B1_TXPL = 1, + PLE_QTAID_C2H = 2, + PLE_QTAID_H2C = 3, + PLE_QTAID_WLAN_CPU = 4, + PLE_QTAID_MPDU = 5, + PLE_QTAID_CMAC0_RX = 6, + PLE_QTAID_CMAC1_RX = 7, + PLE_QTAID_CMAC1_BBRPT = 8, + PLE_QTAID_WDRLS = 9, + PLE_QTAID_CPUIO = 10, +}; + +enum rtw89_mac_dle_ctrl_type { + DLE_CTRL_TYPE_WDE = 0, + DLE_CTRL_TYPE_PLE = 1, + DLE_CTRL_TYPE_NUM = 2, +}; + +enum rtw89_mac_ax_l0_to_l1_event { + MAC_AX_L0_TO_L1_CHIF_IDLE = 0, + MAC_AX_L0_TO_L1_CMAC_DMA_IDLE = 1, + MAC_AX_L0_TO_L1_RLS_PKID = 2, + MAC_AX_L0_TO_L1_PTCL_IDLE = 3, + MAC_AX_L0_TO_L1_RX_QTA_LOST = 4, + MAC_AX_L0_TO_L1_DLE_STAT_HANG = 5, + MAC_AX_L0_TO_L1_PCIE_STUCK = 6, + MAC_AX_L0_TO_L1_EVENT_MAX = 15, +}; + +enum rtw89_mac_phy_rpt_size { + MAC_AX_PHY_RPT_SIZE_0 = 0, + MAC_AX_PHY_RPT_SIZE_8 = 1, + MAC_AX_PHY_RPT_SIZE_16 = 2, + MAC_AX_PHY_RPT_SIZE_24 = 3, +}; + +enum rtw89_mac_hdr_cnv_size { + MAC_AX_HDR_CNV_SIZE_0 = 0, + MAC_AX_HDR_CNV_SIZE_32 = 1, + MAC_AX_HDR_CNV_SIZE_64 = 2, + MAC_AX_HDR_CNV_SIZE_96 = 3, +}; + +enum rtw89_mac_wow_fw_status { + WOWLAN_NOT_READY = 0x00, + WOWLAN_SLEEP_READY = 0x01, + WOWLAN_RESUME_READY = 0x02, +}; + +#define RTW89_PORT_OFFSET_TU_TO_32US(shift_tu) ((shift_tu) * 1024 / 32) + +enum rtw89_mac_dbg_port_sel { + /* CMAC 0 related */ + RTW89_DBG_PORT_SEL_PTCL_C0 = 0, + RTW89_DBG_PORT_SEL_SCH_C0, + RTW89_DBG_PORT_SEL_TMAC_C0, + RTW89_DBG_PORT_SEL_RMAC_C0, + RTW89_DBG_PORT_SEL_RMACST_C0, + RTW89_DBG_PORT_SEL_RMAC_PLCP_C0, + RTW89_DBG_PORT_SEL_TRXPTCL_C0, + RTW89_DBG_PORT_SEL_TX_INFOL_C0, + RTW89_DBG_PORT_SEL_TX_INFOH_C0, + RTW89_DBG_PORT_SEL_TXTF_INFOL_C0, + RTW89_DBG_PORT_SEL_TXTF_INFOH_C0, + /* CMAC 1 related */ + RTW89_DBG_PORT_SEL_PTCL_C1, + RTW89_DBG_PORT_SEL_SCH_C1, + RTW89_DBG_PORT_SEL_TMAC_C1, + RTW89_DBG_PORT_SEL_RMAC_C1, + RTW89_DBG_PORT_SEL_RMACST_C1, + RTW89_DBG_PORT_SEL_RMAC_PLCP_C1, + RTW89_DBG_PORT_SEL_TRXPTCL_C1, + RTW89_DBG_PORT_SEL_TX_INFOL_C1, + RTW89_DBG_PORT_SEL_TX_INFOH_C1, + RTW89_DBG_PORT_SEL_TXTF_INFOL_C1, + RTW89_DBG_PORT_SEL_TXTF_INFOH_C1, + /* DLE related */ + RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG, + RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA, + RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT, + RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO, + RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT, + RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT, + RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL, + RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY, + RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG, + RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA, + RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT, + RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO, + RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT, + RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT, + RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL, + RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY, + RTW89_DBG_PORT_SEL_PKTINFO, + /* DISPATCHER related */ + RTW89_DBG_PORT_SEL_DSPT_HDT_TX0, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX1, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX2, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX3, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX4, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX5, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX6, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX7, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX8, + RTW89_DBG_PORT_SEL_DSPT_HDT_TX9, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXA, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXB, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXC, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXD, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXE, + RTW89_DBG_PORT_SEL_DSPT_HDT_TXF, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX0, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX1, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX3, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX4, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX5, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX6, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX7, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX8, + RTW89_DBG_PORT_SEL_DSPT_CDT_TX9, + RTW89_DBG_PORT_SEL_DSPT_CDT_TXA, + RTW89_DBG_PORT_SEL_DSPT_CDT_TXB, + RTW89_DBG_PORT_SEL_DSPT_CDT_TXC, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX0, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX1, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX2, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX3, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX4, + RTW89_DBG_PORT_SEL_DSPT_HDT_RX5, + RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0, + RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0, + RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1, + RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2, + RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1, + RTW89_DBG_PORT_SEL_DSPT_STF_CTRL, + RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL, + RTW89_DBG_PORT_SEL_DSPT_WDE_INTF, + RTW89_DBG_PORT_SEL_DSPT_PLE_INTF, + RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL, + /* PCIE related */ + RTW89_DBG_PORT_SEL_PCIE_TXDMA, + RTW89_DBG_PORT_SEL_PCIE_RXDMA, + RTW89_DBG_PORT_SEL_PCIE_CVT, + RTW89_DBG_PORT_SEL_PCIE_CXPL, + RTW89_DBG_PORT_SEL_PCIE_IO, + RTW89_DBG_PORT_SEL_PCIE_MISC, + RTW89_DBG_PORT_SEL_PCIE_MISC2, + + /* keep last */ + RTW89_DBG_PORT_SEL_LAST, + RTW89_DBG_PORT_SEL_MAX = RTW89_DBG_PORT_SEL_LAST, + RTW89_DBG_PORT_SEL_INVALID = RTW89_DBG_PORT_SEL_LAST, +}; + +/* SRAM mem dump */ +#define R_AX_INDIR_ACCESS_ENTRY 0x40000 +#define R_BE_INDIR_ACCESS_ENTRY 0x80000 + +#define AXIDMA_BASE_ADDR 0x18006000 +#define STA_SCHED_BASE_ADDR 0x18808000 +#define RXPLD_FLTR_CAM_BASE_ADDR 0x18813000 +#define SECURITY_CAM_BASE_ADDR 0x18814000 +#define WOW_CAM_BASE_ADDR 0x18815000 +#define CMAC_TBL_BASE_ADDR 0x18840000 +#define ADDR_CAM_BASE_ADDR 0x18850000 +#define BSSID_CAM_BASE_ADDR 0x18853000 +#define BA_CAM_BASE_ADDR 0x18854000 +#define BCN_IE_CAM0_BASE_ADDR 0x18855000 +#define SHARED_BUF_BASE_ADDR 0x18700000 +#define DMAC_TBL_BASE_ADDR 0x18800000 +#define SHCUT_MACHDR_BASE_ADDR 0x18800800 +#define BCN_IE_CAM1_BASE_ADDR 0x188A0000 +#define TXD_FIFO_0_BASE_ADDR 0x18856200 +#define TXD_FIFO_1_BASE_ADDR 0x188A1080 +#define TXD_FIFO_0_BASE_ADDR_V1 0x18856400 /* for 8852C */ +#define TXD_FIFO_1_BASE_ADDR_V1 0x188A1080 /* for 8852C */ +#define TXDATA_FIFO_0_BASE_ADDR 0x18856000 +#define TXDATA_FIFO_1_BASE_ADDR 0x188A1000 +#define CPU_LOCAL_BASE_ADDR 0x18003000 + +#define WD_PAGE_BASE_ADDR_BE 0x0 +#define CPU_LOCAL_BASE_ADDR_BE 0x18003000 +#define AXIDMA_BASE_ADDR_BE 0x18006000 +#define SHARED_BUF_BASE_ADDR_BE 0x18700000 +#define DMAC_TBL_BASE_ADDR_BE 0x18800000 +#define SHCUT_MACHDR_BASE_ADDR_BE 0x18800800 +#define STA_SCHED_BASE_ADDR_BE 0x18818000 +#define NAT25_CAM_BASE_ADDR_BE 0x18820000 +#define RXPLD_FLTR_CAM_BASE_ADDR_BE 0x18823000 +#define SEC_CAM_BASE_ADDR_BE 0x18824000 +#define SEC_CAM_BASE_ADDR_BE_8922D 0x1882C000 +#define WOW_CAM_BASE_ADDR_BE 0x18828000 +#define MLD_TBL_BASE_ADDR_BE 0x18829000 +#define RX_CLSF_CAM_BASE_ADDR_BE 0x1882A000 +#define CMAC_TBL_BASE_ADDR_BE 0x18840000 +#define ADDR_CAM_BASE_ADDR_BE 0x18850000 +#define BSSID_CAM_BASE_ADDR_BE 0x18858000 +#define BA_CAM_BASE_ADDR_BE 0x18859000 +#define BCN_IE_CAM0_BASE_ADDR_BE 0x18860000 +#define TXDATA_FIFO_0_BASE_ADDR_BE 0x18861000 +#define TXD_FIFO_0_BASE_ADDR_BE 0x18862000 +#define BCN_IE_CAM1_BASE_ADDR_BE 0x18880000 +#define TXDATA_FIFO_1_BASE_ADDR_BE 0x18881000 +#define TXD_FIFO_1_BASE_ADDR_BE 0x18881800 +#define DCPU_LOCAL_BASE_ADDR_BE 0x19C02000 + +#define CCTL_INFO_SIZE 32 + +enum rtw89_mac_mem_sel { + RTW89_MAC_MEM_AXIDMA, + RTW89_MAC_MEM_SHARED_BUF, + RTW89_MAC_MEM_DMAC_TBL, + RTW89_MAC_MEM_SHCUT_MACHDR, + RTW89_MAC_MEM_STA_SCHED, + RTW89_MAC_MEM_RXPLD_FLTR_CAM, + RTW89_MAC_MEM_SECURITY_CAM, + RTW89_MAC_MEM_WOW_CAM, + RTW89_MAC_MEM_CMAC_TBL, + RTW89_MAC_MEM_ADDR_CAM, + RTW89_MAC_MEM_BA_CAM, + RTW89_MAC_MEM_BCN_IE_CAM0, + RTW89_MAC_MEM_BCN_IE_CAM1, + RTW89_MAC_MEM_TXD_FIFO_0, + RTW89_MAC_MEM_TXD_FIFO_1, + RTW89_MAC_MEM_TXDATA_FIFO_0, + RTW89_MAC_MEM_TXDATA_FIFO_1, + RTW89_MAC_MEM_CPU_LOCAL, + RTW89_MAC_MEM_BSSID_CAM, + RTW89_MAC_MEM_TXD_FIFO_0_V1, + RTW89_MAC_MEM_TXD_FIFO_1_V1, + RTW89_MAC_MEM_WD_PAGE, + RTW89_MAC_MEM_MLD_TBL, + + /* keep last */ + RTW89_MAC_MEM_NUM, +}; + +enum rtw89_rpwm_req_pwr_state { + RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0, + RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1, + RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFON = 2, + RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF = 3, + RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFOFF = 4, + RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED = 5, + RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED = 6, + RTW89_MAC_RPWM_REQ_PWR_STATE_HIOE_PWR_GATED = 7, + RTW89_MAC_RPWM_REQ_PWR_STATE_MAX, +}; + +struct rtw89_pwr_cfg { + u16 addr; + u8 cv_msk; + u8 intf_msk; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 val; +}; + +enum rtw89_mac_c2h_ofld_func { + RTW89_MAC_C2H_FUNC_EFUSE_DUMP, + RTW89_MAC_C2H_FUNC_READ_RSP, + RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP, + RTW89_MAC_C2H_FUNC_BCN_RESEND, + RTW89_MAC_C2H_FUNC_MACID_PAUSE, + RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6, + RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9, + RTW89_MAC_C2H_FUNC_TX_DUTY_RPT = 0xa, + RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd, + RTW89_MAC_C2H_FUNC_OFLD_MAX, +}; + +enum rtw89_mac_c2h_info_func { + RTW89_MAC_C2H_FUNC_REC_ACK, + RTW89_MAC_C2H_FUNC_DONE_ACK, + RTW89_MAC_C2H_FUNC_C2H_LOG, + RTW89_MAC_C2H_FUNC_BCN_CNT, + RTW89_MAC_C2H_FUNC_BCN_UPD_DONE = 0x06, + RTW89_MAC_C2H_FUNC_INFO_MAX, +}; + +enum rtw89_mac_c2h_mcc_func { + RTW89_MAC_C2H_FUNC_MCC_RCV_ACK = 0, + RTW89_MAC_C2H_FUNC_MCC_REQ_ACK = 1, + RTW89_MAC_C2H_FUNC_MCC_TSF_RPT = 2, + RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT = 3, + + NUM_OF_RTW89_MAC_C2H_FUNC_MCC, +}; + +enum rtw89_mac_c2h_misc_func { + RTW89_MAC_C2H_FUNC_TX_REPORT = 1, + + NUM_OF_RTW89_MAC_C2H_FUNC_MISC, +}; + +enum rtw89_mac_c2h_mlo_func { + RTW89_MAC_C2H_FUNC_MLO_GET_TBL = 0x0, + RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE = 0x1, + RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE = 0x2, + RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT = 0x3, + RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT = 0x4, + RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT = 0x5, + RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP = 0x6, + + NUM_OF_RTW89_MAC_C2H_FUNC_MLO, +}; + +enum rtw89_mac_c2h_mrc_func { + RTW89_MAC_C2H_FUNC_MRC_TSF_RPT = 0, + RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT = 1, + + NUM_OF_RTW89_MAC_C2H_FUNC_MRC, +}; + +enum rtw89_mac_c2h_wow_func { + RTW89_MAC_C2H_FUNC_AOAC_REPORT, + + NUM_OF_RTW89_MAC_C2H_FUNC_WOW, +}; + +enum rtw89_mac_c2h_ap_func { + RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY = 0, + + NUM_OF_RTW89_MAC_C2H_FUNC_AP, +}; + +enum rtw89_mac_c2h_class { + RTW89_MAC_C2H_CLASS_INFO = 0x0, + RTW89_MAC_C2H_CLASS_OFLD = 0x1, + RTW89_MAC_C2H_CLASS_TWT = 0x2, + RTW89_MAC_C2H_CLASS_WOW = 0x3, + RTW89_MAC_C2H_CLASS_MCC = 0x4, + RTW89_MAC_C2H_CLASS_FWDBG = 0x5, + RTW89_MAC_C2H_CLASS_MISC = 0x9, + RTW89_MAC_C2H_CLASS_MLO = 0xc, + RTW89_MAC_C2H_CLASS_MRC = 0xe, + RTW89_MAC_C2H_CLASS_AP = 0x18, + RTW89_MAC_C2H_CLASS_ROLE = 0x1b, + RTW89_MAC_C2H_CLASS_MAX, +}; + +enum rtw89_mac_mcc_status { + RTW89_MAC_MCC_ADD_ROLE_OK = 0, + RTW89_MAC_MCC_START_GROUP_OK = 1, + RTW89_MAC_MCC_STOP_GROUP_OK = 2, + RTW89_MAC_MCC_DEL_GROUP_OK = 3, + RTW89_MAC_MCC_RESET_GROUP_OK = 4, + RTW89_MAC_MCC_SWITCH_CH_OK = 5, + RTW89_MAC_MCC_TXNULL0_OK = 6, + RTW89_MAC_MCC_TXNULL1_OK = 7, + + RTW89_MAC_MCC_SWITCH_EARLY = 10, + RTW89_MAC_MCC_TBTT = 11, + RTW89_MAC_MCC_DURATION_START = 12, + RTW89_MAC_MCC_DURATION_END = 13, + + RTW89_MAC_MCC_ADD_ROLE_FAIL = 20, + RTW89_MAC_MCC_START_GROUP_FAIL = 21, + RTW89_MAC_MCC_STOP_GROUP_FAIL = 22, + RTW89_MAC_MCC_DEL_GROUP_FAIL = 23, + RTW89_MAC_MCC_RESET_GROUP_FAIL = 24, + RTW89_MAC_MCC_SWITCH_CH_FAIL = 25, + RTW89_MAC_MCC_TXNULL0_FAIL = 26, + RTW89_MAC_MCC_TXNULL1_FAIL = 27, +}; + +enum rtw89_mac_mrc_status { + RTW89_MAC_MRC_START_SCH_OK = 0, + RTW89_MAC_MRC_STOP_SCH_OK = 1, + RTW89_MAC_MRC_DEL_SCH_OK = 2, + RTW89_MAC_MRC_EMPTY_SCH_FAIL = 16, + RTW89_MAC_MRC_ROLE_NOT_EXIST_FAIL = 17, + RTW89_MAC_MRC_DATA_NOT_FOUND_FAIL = 18, + RTW89_MAC_MRC_GET_NEXT_SLOT_FAIL = 19, + RTW89_MAC_MRC_ALT_ROLE_FAIL = 20, + RTW89_MAC_MRC_ADD_PSTIMER_FAIL = 21, + RTW89_MAC_MRC_MALLOC_FAIL = 22, + RTW89_MAC_MRC_SWITCH_CH_FAIL = 23, + RTW89_MAC_MRC_TXNULL0_FAIL = 24, + RTW89_MAC_MRC_PORT_FUNC_EN_FAIL = 25, +}; + +struct rtw89_mac_ax_coex { +#define RTW89_MAC_AX_COEX_RTK_MODE 0 +#define RTW89_MAC_AX_COEX_CSR_MODE 1 + u8 pta_mode; +#define RTW89_MAC_AX_COEX_INNER 0 +#define RTW89_MAC_AX_COEX_OUTPUT 1 +#define RTW89_MAC_AX_COEX_INPUT 2 + u8 direction; +}; + +struct rtw89_mac_ax_plt { +#define RTW89_MAC_AX_PLT_LTE_RX BIT(0) +#define RTW89_MAC_AX_PLT_GNT_BT_TX BIT(1) +#define RTW89_MAC_AX_PLT_GNT_BT_RX BIT(2) +#define RTW89_MAC_AX_PLT_GNT_WL BIT(3) + u8 band; + u8 tx; + u8 rx; +}; + +enum rtw89_mac_bf_rrsc_rate { + RTW89_MAC_BF_RRSC_6M = 0, + RTW89_MAC_BF_RRSC_9M = 1, + RTW89_MAC_BF_RRSC_12M, + RTW89_MAC_BF_RRSC_18M, + RTW89_MAC_BF_RRSC_24M, + RTW89_MAC_BF_RRSC_36M, + RTW89_MAC_BF_RRSC_48M, + RTW89_MAC_BF_RRSC_54M, + RTW89_MAC_BF_RRSC_HT_MSC0, + RTW89_MAC_BF_RRSC_HT_MSC1, + RTW89_MAC_BF_RRSC_HT_MSC2, + RTW89_MAC_BF_RRSC_HT_MSC3, + RTW89_MAC_BF_RRSC_HT_MSC4, + RTW89_MAC_BF_RRSC_HT_MSC5, + RTW89_MAC_BF_RRSC_HT_MSC6, + RTW89_MAC_BF_RRSC_HT_MSC7, + RTW89_MAC_BF_RRSC_VHT_MSC0, + RTW89_MAC_BF_RRSC_VHT_MSC1, + RTW89_MAC_BF_RRSC_VHT_MSC2, + RTW89_MAC_BF_RRSC_VHT_MSC3, + RTW89_MAC_BF_RRSC_VHT_MSC4, + RTW89_MAC_BF_RRSC_VHT_MSC5, + RTW89_MAC_BF_RRSC_VHT_MSC6, + RTW89_MAC_BF_RRSC_VHT_MSC7, + RTW89_MAC_BF_RRSC_HE_MSC0, + RTW89_MAC_BF_RRSC_HE_MSC1, + RTW89_MAC_BF_RRSC_HE_MSC2, + RTW89_MAC_BF_RRSC_HE_MSC3, + RTW89_MAC_BF_RRSC_HE_MSC4, + RTW89_MAC_BF_RRSC_HE_MSC5, + RTW89_MAC_BF_RRSC_HE_MSC6, + RTW89_MAC_BF_RRSC_HE_MSC7 = 31, + RTW89_MAC_BF_RRSC_MAX = 32 +}; + +#define MAC_REG_POOL_COUNT 10 +#define ACCESS_CMAC(_addr) \ + ({typeof(_addr) __addr = (_addr); \ + __addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; }) +#define RTW89_MAC_AX_BAND_REG_OFFSET 0x2000 +#define RTW89_MAC_BE_BAND_REG_OFFSET 0x4000 + +#define PTCL_IDLE_POLL_CNT 10000 +#define SW_CVR_DUR_US 8 +#define SW_CVR_CNT 8 + +#define DLE_BOUND_UNIT (8 * 1024) +#define DLE_WAIT_CNT 2000 +#define TRXCFG_WAIT_CNT 2000 + +#define RTW89_WDE_PG_64 64 +#define RTW89_WDE_PG_128 128 +#define RTW89_WDE_PG_256 256 + +#define S_AX_WDE_PAGE_SEL_64 0 +#define S_AX_WDE_PAGE_SEL_128 1 +#define S_AX_WDE_PAGE_SEL_256 2 + +#define RTW89_PLE_PG_64 64 +#define RTW89_PLE_PG_128 128 +#define RTW89_PLE_PG_256 256 + +#define S_AX_PLE_PAGE_SEL_64 0 +#define S_AX_PLE_PAGE_SEL_128 1 +#define S_AX_PLE_PAGE_SEL_256 2 + +#define B_CMAC0_MGQ_NORMAL BIT(2) +#define B_CMAC0_MGQ_NO_PWRSAV BIT(3) +#define B_CMAC0_CPUMGQ BIT(4) +#define B_CMAC1_MGQ_NORMAL BIT(10) +#define B_CMAC1_MGQ_NO_PWRSAV BIT(11) +#define B_CMAC1_CPUMGQ BIT(12) + +#define B_CMAC0_MGQ_NORMAL_BE BIT(2) +#define B_CMAC1_MGQ_NORMAL_BE BIT(30) + +#define QEMP_ACQ_GRP_MACID_NUM 8 +#define QEMP_ACQ_GRP_QSEL_SH 4 +#define QEMP_ACQ_GRP_QSEL_MASK 0xF + +#define SDIO_LOCAL_BASE_ADDR 0x80000000 + +#define PWR_CMD_WRITE 0 +#define PWR_CMD_POLL 1 +#define PWR_CMD_DELAY 2 +#define PWR_CMD_END 3 + +#define PWR_INTF_MSK_SDIO BIT(0) +#define PWR_INTF_MSK_USB BIT(1) +#define PWR_INTF_MSK_PCIE BIT(2) +#define PWR_INTF_MSK_ALL 0x7 + +#define PWR_BASE_MAC 0 +#define PWR_BASE_USB 1 +#define PWR_BASE_PCIE 2 +#define PWR_BASE_SDIO 3 + +#define PWR_CV_MSK_A BIT(0) +#define PWR_CV_MSK_B BIT(1) +#define PWR_CV_MSK_C BIT(2) +#define PWR_CV_MSK_D BIT(3) +#define PWR_CV_MSK_E BIT(4) +#define PWR_CV_MSK_F BIT(5) +#define PWR_CV_MSK_G BIT(6) +#define PWR_CV_MSK_TEST BIT(7) +#define PWR_CV_MSK_ALL 0xFF + +#define PWR_DELAY_US 0 +#define PWR_DELAY_MS 1 + +/* STA scheduler */ +#define SS_MACID_SH 8 +#define SS_TX_LEN_MSK 0x1FFFFF +#define SS_CTRL1_R_TX_LEN 5 +#define SS_CTRL1_R_NEXT_LINK 20 +#define SS_LINK_SIZE 256 + +/* MAC debug port */ +#define TMAC_DBG_SEL_C0 0xA5 +#define RMAC_DBG_SEL_C0 0xA6 +#define TRXPTCL_DBG_SEL_C0 0xA7 +#define TMAC_DBG_SEL_C1 0xB5 +#define RMAC_DBG_SEL_C1 0xB6 +#define TRXPTCL_DBG_SEL_C1 0xB7 +#define FW_PROG_CNTR_DBG_SEL 0xF2 +#define PCIE_TXDMA_DBG_SEL 0x30 +#define PCIE_RXDMA_DBG_SEL 0x31 +#define PCIE_CVT_DBG_SEL 0x32 +#define PCIE_CXPL_DBG_SEL 0x33 +#define PCIE_IO_DBG_SEL 0x37 +#define PCIE_MISC_DBG_SEL 0x38 +#define PCIE_MISC2_DBG_SEL 0x00 +#define MAC_DBG_SEL 1 +#define RMAC_CMAC_DBG_SEL 1 + +/* TRXPTCL dbg port sel */ +#define TRXPTRL_DBG_SEL_TMAC 0 +#define TRXPTRL_DBG_SEL_RMAC 1 + +struct rtw89_cpuio_ctrl { + u16 pkt_num; + u16 start_pktid; + u16 end_pktid; + u8 cmd_type; + u8 macid; + u8 src_pid; + u8 src_qid; + u8 dst_pid; + u8 dst_qid; + u16 pktid; +}; + +struct rtw89_mac_dbg_port_info { + u32 sel_addr; + u8 sel_byte; + u32 sel_msk; + u32 srt; + u32 end; + u32 rd_addr; + u8 rd_byte; + u32 rd_msk; +}; + +#define QLNKTBL_ADDR_INFO_SEL BIT(0) +#define QLNKTBL_ADDR_INFO_SEL_0 0 +#define QLNKTBL_ADDR_INFO_SEL_1 1 +#define QLNKTBL_ADDR_TBL_IDX_MASK GENMASK(10, 1) +#define QLNKTBL_DATA_SEL1_PKT_CNT_MASK GENMASK(11, 0) + +struct rtw89_mac_dle_dfi_ctrl { + enum rtw89_mac_dle_ctrl_type type; + u32 target; + u32 addr; + u32 out_data; +}; + +struct rtw89_mac_dle_dfi_quota { + enum rtw89_mac_dle_ctrl_type dle_type; + u32 qtaid; + u16 rsv_pgnum; + u16 use_pgnum; +}; + +struct rtw89_mac_dle_dfi_qempty { + enum rtw89_mac_dle_ctrl_type dle_type; + u32 grpsel; + u32 qempty; +}; + +enum rtw89_mac_dle_rsvd_qt_type { + DLE_RSVD_QT_MPDU_INFO, + DLE_RSVD_QT_B0_CSI, + DLE_RSVD_QT_B1_CSI, + DLE_RSVD_QT_B0_LMR, + DLE_RSVD_QT_B1_LMR, + DLE_RSVD_QT_B0_FTM, + DLE_RSVD_QT_B1_FTM, +}; + +struct rtw89_mac_dle_rsvd_qt_cfg { + u16 pktid; + u16 pg_num; + u32 size; +}; + +enum rtw89_mac_error_scenario { + RTW89_RXI300_ERROR = 1, + RTW89_WCPU_CPU_EXCEPTION = 2, + RTW89_WCPU_ASSERTION = 3, +}; + +#define RTW89_ERROR_SCENARIO(__err) ((__err) >> 28) + +/* Define DBG and recovery enum */ +enum mac_ax_err_info { + /* Get error info */ + + /* L0 */ + MAC_AX_ERR_L0_ERR_CMAC0 = 0x0001, + MAC_AX_ERR_L0_ERR_CMAC1 = 0x0002, + MAC_AX_ERR_L0_RESET_DONE = 0x0003, + MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010, + + /* L1 */ + MAC_AX_ERR_L1_PREERR_DMAC = 0x999, + MAC_AX_ERR_L1_ERR_DMAC = 0x1000, + MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001, + MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002, + MAC_AX_ERR_L1_PROMOTE_TO_L2 = 0x1010, + MAC_AX_ERR_L1_RCVY_STOP_DONE = 0x1011, + + /* L2 */ + /* address hole (master) */ + MAC_AX_ERR_L2_ERR_AH_DMA = 0x2000, + MAC_AX_ERR_L2_ERR_AH_HCI = 0x2010, + MAC_AX_ERR_L2_ERR_AH_RLX4081 = 0x2020, + MAC_AX_ERR_L2_ERR_AH_IDDMA = 0x2030, + MAC_AX_ERR_L2_ERR_AH_HIOE = 0x2040, + MAC_AX_ERR_L2_ERR_AH_IPSEC = 0x2050, + MAC_AX_ERR_L2_ERR_AH_RX4281 = 0x2060, + MAC_AX_ERR_L2_ERR_AH_OTHERS = 0x2070, + + /* AHB bridge timeout (master) */ + MAC_AX_ERR_L2_ERR_AHB_TO_DMA = 0x2100, + MAC_AX_ERR_L2_ERR_AHB_TO_HCI = 0x2110, + MAC_AX_ERR_L2_ERR_AHB_TO_RLX4081 = 0x2120, + MAC_AX_ERR_L2_ERR_AHB_TO_IDDMA = 0x2130, + MAC_AX_ERR_L2_ERR_AHB_TO_HIOE = 0x2140, + MAC_AX_ERR_L2_ERR_AHB_TO_IPSEC = 0x2150, + MAC_AX_ERR_L2_ERR_AHB_TO_RX4281 = 0x2160, + MAC_AX_ERR_L2_ERR_AHB_TO_OTHERS = 0x2170, + + /* APB_SA bridge timeout (master + slave) */ + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WVA = 0x2200, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_UART = 0x2201, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_CPULOCAL = 0x2202, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_AXIDMA = 0x2203, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_HIOE = 0x2204, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IDDMA = 0x2205, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IPSEC = 0x2206, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WON = 0x2207, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WDMAC = 0x2208, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WCMAC = 0x2209, + MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_OTHERS = 0x220A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WVA = 0x2210, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_UART = 0x2211, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_CPULOCAL = 0x2212, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_AXIDMA = 0x2213, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_HIOE = 0x2214, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IDDMA = 0x2215, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IPSEC = 0x2216, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WDMAC = 0x2218, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WCMAC = 0x2219, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_OTHERS = 0x221A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WVA = 0x2220, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_UART = 0x2221, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_CPULOCAL = 0x2222, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_AXIDMA = 0x2223, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_HIOE = 0x2224, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IDDMA = 0x2225, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IPSEC = 0x2226, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WON = 0x2227, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WDMAC = 0x2228, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WCMAC = 0x2229, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_OTHERS = 0x222A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WVA = 0x2230, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_UART = 0x2231, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_CPULOCAL = 0x2232, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_AXIDMA = 0x2233, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_HIOE = 0x2234, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IDDMA = 0x2235, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IPSEC = 0x2236, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WON = 0x2237, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WDMAC = 0x2238, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WCMAC = 0x2239, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_OTHERS = 0x223A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WVA = 0x2240, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_UART = 0x2241, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_CPULOCAL = 0x2242, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_AXIDMA = 0x2243, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_HIOE = 0x2244, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IDDMA = 0x2245, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IPSEC = 0x2246, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WON = 0x2247, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WDMAC = 0x2248, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WCMAC = 0x2249, + MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_OTHERS = 0x224A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WVA = 0x2250, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_UART = 0x2251, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_CPULOCAL = 0x2252, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_AXIDMA = 0x2253, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_HIOE = 0x2254, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IDDMA = 0x2255, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IPSEC = 0x2256, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WON = 0x2257, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WDMAC = 0x2258, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WCMAC = 0x2259, + MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_OTHERS = 0x225A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WVA = 0x2260, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_UART = 0x2261, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_CPULOCAL = 0x2262, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_AXIDMA = 0x2263, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_HIOE = 0x2264, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IDDMA = 0x2265, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IPSEC = 0x2266, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WON = 0x2267, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WDMAC = 0x2268, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WCMAC = 0x2269, + MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_OTHERS = 0x226A, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WVA = 0x2270, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_UART = 0x2271, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_CPULOCAL = 0x2272, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_AXIDMA = 0x2273, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_HIOE = 0x2274, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IDDMA = 0x2275, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IPSEC = 0x2276, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WON = 0x2277, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WDMAC = 0x2278, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WCMAC = 0x2279, + MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_OTHERS = 0x227A, + + /* APB_BBRF bridge timeout (master) */ + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_DMA = 0x2300, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HCI = 0x2310, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RLX4081 = 0x2320, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IDDMA = 0x2330, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HIOE = 0x2340, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IPSEC = 0x2350, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RX4281 = 0x2360, + MAC_AX_ERR_L2_ERR_APB_BBRF_TO_OTHERS = 0x2370, + MAC_AX_ERR_L2_RESET_DONE = 0x2400, + MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT = 0x2599, + MAC_AX_ERR_CPU_EXCEPTION = 0x3000, + MAC_AX_ERR_ASSERTION = 0x4000, + MAC_AX_ERR_RXI300 = 0x5000, + MAC_AX_GET_ERR_MAX, + MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, + + /* set error info */ + MAC_AX_ERR_L1_DISABLE_EN = 0x0001, + MAC_AX_ERR_L1_RCVY_EN = 0x0002, + MAC_AX_ERR_L1_RCVY_STOP_REQ = 0x0003, + MAC_AX_ERR_L1_RCVY_START_REQ = 0x0004, + MAC_AX_ERR_L1_RESET_START_DMAC = 0x000A, + MAC_AX_ERR_L0_CFG_NOTIFY = 0x0010, + MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011, + MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012, + MAC_AX_ERR_L0_RCVY_EN = 0x0013, + MAC_AX_ERR_L0_RESET_FORCE = 0x0020, + MAC_AX_ERR_L0_RESET_FORCE_C1 = 0x0021, + MAC_AX_ERR_L1_RESET_FORCE = 0x0022, + MAC_AX_SET_ERR_MAX, +}; + +struct rtw89_mac_size_set { + const struct rtw89_hfc_prec_cfg hfc_preccfg_pcie; + const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0; + const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c2; + const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c3; + const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c5; + const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c6; + const struct rtw89_dle_size wde_size0; + const struct rtw89_dle_size wde_size1; + const struct rtw89_dle_size wde_size0_v1; + const struct rtw89_dle_size wde_size3_v1; + const struct rtw89_dle_size wde_size4; + const struct rtw89_dle_size wde_size4_v1; + const struct rtw89_dle_size wde_size5_v1; + const struct rtw89_dle_size wde_size6; + const struct rtw89_dle_size wde_size7; + const struct rtw89_dle_size wde_size7_v1; + const struct rtw89_dle_size wde_size8_v1; + const struct rtw89_dle_size wde_size9; + const struct rtw89_dle_size wde_size16_v1; + const struct rtw89_dle_size wde_size17; + const struct rtw89_dle_size wde_size18; + const struct rtw89_dle_size wde_size18_v1; + const struct rtw89_dle_size wde_size19; + const struct rtw89_dle_size wde_size22_v1; + const struct rtw89_dle_size wde_size23; + const struct rtw89_dle_size wde_size30; + const struct rtw89_dle_size wde_size31; + const struct rtw89_dle_size ple_size0; + const struct rtw89_dle_size ple_size1; + const struct rtw89_dle_size ple_size0_v1; + const struct rtw89_dle_size ple_size3_v1; + const struct rtw89_dle_size ple_size4_v1; + const struct rtw89_dle_size ple_size4; + const struct rtw89_dle_size ple_size6; + const struct rtw89_dle_size ple_size6_v1; + const struct rtw89_dle_size ple_size7_v1; + const struct rtw89_dle_size ple_size8; + const struct rtw89_dle_size ple_size9; + const struct rtw89_dle_size ple_size17; + const struct rtw89_dle_size ple_size18; + const struct rtw89_dle_size ple_size19; + const struct rtw89_dle_size ple_size20_v1; + const struct rtw89_dle_size ple_size22_v1; + const struct rtw89_dle_size ple_size27; + const struct rtw89_dle_size ple_size29_v1; + const struct rtw89_dle_size ple_size31; + const struct rtw89_dle_size ple_size34; + const struct rtw89_wde_quota wde_qt0; + const struct rtw89_wde_quota wde_qt1; + const struct rtw89_wde_quota wde_qt0_v1; + const struct rtw89_wde_quota wde_qt3; + const struct rtw89_wde_quota wde_qt4; + const struct rtw89_wde_quota wde_qt4_v1; + const struct rtw89_wde_quota wde_qt5_v1; + const struct rtw89_wde_quota wde_qt6; + const struct rtw89_wde_quota wde_qt7; + const struct rtw89_wde_quota wde_qt7_v1; + const struct rtw89_wde_quota wde_qt8_v1; + const struct rtw89_wde_quota wde_qt16; + const struct rtw89_wde_quota wde_qt17; + const struct rtw89_wde_quota wde_qt18; + const struct rtw89_wde_quota wde_qt19_v1; + const struct rtw89_wde_quota wde_qt23; + const struct rtw89_wde_quota wde_qt23_v1; + const struct rtw89_wde_quota wde_qt30; + const struct rtw89_wde_quota wde_qt31; + const struct rtw89_ple_quota ple_qt0; + const struct rtw89_ple_quota ple_qt1; + const struct rtw89_ple_quota ple_qt4; + const struct rtw89_ple_quota ple_qt5; + const struct rtw89_ple_quota ple_qt5_v2; + const struct rtw89_ple_quota ple_qt6_v1; + const struct rtw89_ple_quota ple_qt7_v1; + const struct rtw89_ple_quota ple_qt8_v1; + const struct rtw89_ple_quota ple_qt9; + const struct rtw89_ple_quota ple_qt9_v1; + const struct rtw89_ple_quota ple_qt12_v1; + const struct rtw89_ple_quota ple_qt13; + const struct rtw89_ple_quota ple_qt13_v1; + const struct rtw89_ple_quota ple_qt14_v1; + const struct rtw89_ple_quota ple_qt15_v1; + const struct rtw89_ple_quota ple_qt18; + const struct rtw89_ple_quota ple_qt25; + const struct rtw89_ple_quota ple_qt26; + const struct rtw89_ple_quota ple_qt27; + const struct rtw89_ple_quota ple_qt28; + const struct rtw89_ple_quota ple_qt42; + const struct rtw89_ple_quota ple_qt43; + const struct rtw89_ple_quota ple_qt44; + const struct rtw89_ple_quota ple_qt44_v2; + const struct rtw89_ple_quota ple_qt45; + const struct rtw89_ple_quota ple_qt45_v2; + const struct rtw89_ple_quota ple_qt46; + const struct rtw89_ple_quota ple_qt47; + const struct rtw89_ple_quota ple_qt47_v2; + const struct rtw89_ple_quota ple_qt57; + const struct rtw89_ple_quota ple_qt58; + const struct rtw89_ple_quota ple_qt59; + const struct rtw89_ple_quota ple_qt61; + const struct rtw89_ple_quota ple_qt62; + const struct rtw89_ple_quota ple_qt64_v2; + const struct rtw89_ple_quota ple_qt65_v2; + const struct rtw89_ple_quota ple_qt78; + const struct rtw89_ple_quota ple_qt79; + const struct rtw89_ple_quota ple_qt_52a_wow; + const struct rtw89_ple_quota ple_qt_52b_wow; + const struct rtw89_ple_quota ple_qt_52bt_wow; + const struct rtw89_ple_quota ple_qt_51b_wow; + const struct rtw89_rsvd_quota ple_rsvd_qt0; + const struct rtw89_rsvd_quota ple_rsvd_qt1; + const struct rtw89_rsvd_quota ple_rsvd_qt1_v1; + const struct rtw89_rsvd_quota ple_rsvd_qt2; + const struct rtw89_rsvd_quota ple_rsvd_qt9; + const struct rtw89_dle_rsvd_size rsvd0_size0; + const struct rtw89_dle_rsvd_size rsvd0_size3; + const struct rtw89_dle_rsvd_size rsvd0_size5; + const struct rtw89_dle_rsvd_size rsvd0_size6; + const struct rtw89_dle_rsvd_size rsvd0_size17; + const struct rtw89_dle_rsvd_size rsvd1_size0; + const struct rtw89_dle_rsvd_size rsvd1_size2; + const struct rtw89_dle_rsvd_size rsvd1_size3; + const struct rtw89_dle_input dle_input3; + const struct rtw89_dle_input dle_input20; + const struct rtw89_dle_input dle_input28; +}; + +extern const struct rtw89_mac_size_set rtw89_mac_size; + +struct rtw89_mac_mu_gid_addr { + u32 position_en[2]; + u32 position[4]; +}; + +struct rtw89_mac_gen_def { + u32 band1_offset; + u32 filter_model_addr; + u32 indir_access_addr; + const u32 *mem_base_addrs; + u32 mem_page_size; + u32 rx_fltr; + u32 default_rx_fltr; + const struct rtw89_port_reg *port_base; + u32 agg_len_ht; + u32 ps_status; + const struct rtw89_mac_mu_gid_addr *mu_gid; + u32 boot_dbg; + + struct rtw89_reg_def muedca_ctrl; + struct rtw89_reg_def bfee_ctrl; + struct rtw89_reg_def narrow_bw_ru_dis; + struct rtw89_reg_def wow_ctrl; + struct rtw89_reg_def agg_limit; + struct rtw89_reg_def ra_agg_limit; + struct rtw89_reg_def txcnt_limit; + + int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band, + enum rtw89_mac_hwmod_sel sel); + int (*sys_init)(struct rtw89_dev *rtwdev); + int (*trx_init)(struct rtw89_dev *rtwdev); + int (*preload_init)(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_qta_mode mode); + void (*clr_aon_intr)(struct rtw89_dev *rtwdev); + void (*err_imr_ctrl)(struct rtw89_dev *rtwdev, bool en); + int (*mac_func_en)(struct rtw89_dev *rtwdev); + void (*hci_func_en)(struct rtw89_dev *rtwdev); + void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev); + void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable); + void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable); + void (*bf_assoc)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); + + int (*typ_fltr_opt)(struct rtw89_dev *rtwdev, + enum rtw89_machdr_frame_type type, + enum rtw89_mac_fwd_target fwd_target, + u8 mac_idx); + int (*cfg_ppdu_status)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable); + void (*cfg_phy_rpt)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable); + void (*set_edcca_mode)(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal); + void (*set_vcore_cfg)(struct rtw89_dev *rtwdev, u8 vlv); + + int (*dle_mix_cfg)(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg); + int (*chk_dle_rdy)(struct rtw89_dev *rtwdev, bool wde_or_ple); + int (*dle_buf_req)(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id); + void (*hfc_func_en)(struct rtw89_dev *rtwdev, bool en, bool h2c_en); + void (*hfc_h2c_cfg)(struct rtw89_dev *rtwdev); + void (*hfc_mix_cfg)(struct rtw89_dev *rtwdev); + void (*hfc_get_mix_info)(struct rtw89_dev *rtwdev); + void (*wde_quota_cfg)(struct rtw89_dev *rtwdev, + const struct rtw89_wde_quota *min_cfg, + const struct rtw89_wde_quota *max_cfg, + u16 ext_wde_min_qt_wcpu); + void (*ple_quota_cfg)(struct rtw89_dev *rtwdev, + const struct rtw89_ple_quota *min_cfg, + const struct rtw89_ple_quota *max_cfg); + int (*set_cpuio)(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd); + int (*dle_quota_change)(struct rtw89_dev *rtwdev, bool band1_en); + + int (*reset_pwr_state)(struct rtw89_dev *rtwdev); + void (*disable_cpu)(struct rtw89_dev *rtwdev); + void (*fwdl_preconfig)(struct rtw89_dev *rtwdev); + int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev, u8 boot_reason, + bool dlfw, bool include_bb); + u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type); + int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev, bool h2c_or_fwdl); + void (*fwdl_secure_idmem_share_mode)(struct rtw89_dev *rtwdev, u8 mode); + int (*parse_efuse_map)(struct rtw89_dev *rtwdev); + int (*parse_phycap_map)(struct rtw89_dev *rtwdev); + int (*cnv_efuse_state)(struct rtw89_dev *rtwdev, bool idle); + int (*efuse_read_fw_secure)(struct rtw89_dev *rtwdev); + int (*efuse_read_ecv)(struct rtw89_dev *rtwdev); + int (*efuse_read_thermal_k)(struct rtw89_dev *rtwdev); + int (*efuse_read_pwr_data)(struct rtw89_dev *rtwdev); + + int (*cfg_plt)(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt); + u16 (*get_plt_cnt)(struct rtw89_dev *rtwdev, u8 band); + + bool (*get_txpwr_cr)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 *cr); + + int (*write_xtal_si)(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask); + int (*read_xtal_si)(struct rtw89_dev *rtwdev, u8 offset, u8 *val); + + void (*dump_qta_lost)(struct rtw89_dev *rtwdev); + void (*dump_err_status)(struct rtw89_dev *rtwdev, + enum mac_ax_err_info err); + + bool (*is_txq_empty)(struct rtw89_dev *rtwdev); + + int (*prep_chan_list)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); + void (*free_chan_list)(struct rtw89_dev *rtwdev); + int (*add_chan_list)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); + int (*add_chan_list_pno)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); + int (*scan_offload)(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *option, + struct rtw89_vif_link *rtwvif_link, + bool wowlan); + + int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow); +}; + +extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax; +extern const struct rtw89_mac_gen_def rtw89_mac_gen_be; + +static inline +u32 rtw89_mac_mem_base_addrs(struct rtw89_dev *rtwdev, u8 sel) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (rtwdev->chip->chip_id == RTL8922D && + sel == RTW89_MAC_MEM_SECURITY_CAM) + return SEC_CAM_BASE_ADDR_BE_8922D; + + return mac->mem_base_addrs[sel]; +} + +static inline +u32 rtw89_mac_reg_by_idx(struct rtw89_dev *rtwdev, u32 reg_base, u8 band) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return band == 0 ? reg_base : (reg_base + mac->band1_offset); +} + +static inline void +rtw89_write16_idx(struct rtw89_dev *rtwdev, u32 addr, u16 data, u8 band) +{ + addr = rtw89_mac_reg_by_idx(rtwdev, addr, band); + + rtw89_write16(rtwdev, addr, data); +} + +static inline void +rtw89_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data, u8 band) +{ + addr = rtw89_mac_reg_by_idx(rtwdev, addr, band); + + rtw89_write32_mask(rtwdev, addr, mask, data); +} + +static inline +u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_idx) +{ + return rtw89_mac_reg_by_idx(rtwdev, base + port * 0x40, mac_idx); +} + +static inline u32 +rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + return rtw89_read32(rtwdev, reg); +} + +static inline u32 +rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u32 mask) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + return rtw89_read32_mask(rtwdev, reg, mask); +} + +static inline void +rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, + u32 data) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write32(rtwdev, reg, data); +} + +static inline void +rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u32 mask, u32 data) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, mask, data); +} + +static inline void +rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u32 mask, u16 data) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write16_mask(rtwdev, reg, mask, data); +} + +static inline void +rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u32 bit) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write32_clr(rtwdev, reg, bit); +} + +static inline void +rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u16 bit) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write16_clr(rtwdev, reg, bit); +} + +static inline void +rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u32 base, u32 bit) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); + rtw89_write32_set(rtwdev, reg, bit); +} + +int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev); +void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev); +int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb, + bool bb_preinit); +int rtw89_mac_preinit(struct rtw89_dev *rtwdev); +int rtw89_mac_init(struct rtw89_dev *rtwdev); +int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, + enum rtw89_qta_mode ext_mode); +int rtw89_mac_hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en); +int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, + enum rtw89_qta_mode mode); +bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode); +static inline +int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band, + enum rtw89_mac_hwmod_sel sel) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->check_mac_en(rtwdev, band, sel); +} + +static inline void rtw89_mac_clr_aon_intr(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (mac->clr_aon_intr) + mac->clr_aon_intr(rtwdev); +} + +int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val); +int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); +int rtw89_mac_dle_dfi_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl); +int rtw89_mac_dle_dfi_quota_cfg(struct rtw89_dev *rtwdev, + struct rtw89_mac_dle_dfi_quota *quota); +void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev); +int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev, + struct rtw89_mac_dle_dfi_qempty *qempty); +void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, + enum mac_ax_err_info err); +int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); +int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, + u16 offset_tu); +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + u64 *tsf); +void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en); +void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); +int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); +int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); +int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); + +static inline int rtw89_chip_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->enable_bb_rf(rtwdev); +} + +static inline int rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->disable_bb_rf(rtwdev); +} + +static inline int rtw89_chip_reset_bb_rf(struct rtw89_dev *rtwdev) +{ + int ret; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) + return 0; + + ret = rtw89_chip_disable_bb_rf(rtwdev); + if (ret) + return ret; + ret = rtw89_chip_enable_bb_rf(rtwdev); + if (ret) + return ret; + + return 0; +} + +u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev); +int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err); +bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u8 class, u8 func); +void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func); +int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev); +int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel); +int rtw89_mac_stop_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel); +int rtw89_mac_stop_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel); +int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); +int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); +int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); +void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable); + +static inline +void rtw89_mac_cfg_phy_rpt(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (mac->cfg_phy_rpt) + mac->cfg_phy_rpt(rtwdev, mac_idx, enable); +} + +static inline +void rtw89_mac_cfg_phy_rpt_bands(struct rtw89_dev *rtwdev, bool enable) +{ + rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_0, enable); + + if (!rtwdev->dbcc_en) + return; + + rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_1, enable); +} + +static inline +int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->cfg_ppdu_status(rtwdev, mac_idx, enable); +} + +static inline +int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable) +{ + int ret; + + ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, enable); + if (ret) + return ret; + + if (!rtwdev->dbcc_en) + return 0; + + return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable); +} + +static inline +void rtw89_mac_set_edcca_mode(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->set_edcca_mode) + return; + + mac->set_edcca_mode(rtwdev, mac_idx, normal); +} + +static inline +void rtw89_mac_set_vcore_cfg(struct rtw89_dev *rtwdev, u8 vlv) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->set_vcore_cfg) + return; + + mac->set_vcore_cfg(rtwdev, vlv); +} + +static inline +void rtw89_mac_set_vcore_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + if (hal->thermal_prot_vlv == 0) + return; + + hal->thermal_prot_vlv = 0; + rtw89_mac_set_vcore_cfg(rtwdev, 0); +} + +static inline +void rtw89_mac_set_edcca_mode_bands(struct rtw89_dev *rtwdev, bool normal) +{ + rtw89_mac_set_edcca_mode(rtwdev, RTW89_MAC_0, normal); + rtw89_mac_set_edcca_mode(rtwdev, RTW89_MAC_1, normal); +} + +void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr); +void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev); +void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); +int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); +int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex *coex); +int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); +int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); +int rtw89_mac_cfg_gnt_v2(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); +int rtw89_mac_cfg_gnt_v3(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); + +static inline +int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->cfg_plt(rtwdev, plt); +} + +static inline +u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->get_plt_cnt(rtwdev, band); +} + +void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val); +u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev); +bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev); +int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl); +int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl); +int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl); +void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter); +void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev); + +static inline +void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (mac->bf_assoc) + mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link); +} + +void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); +void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + bool disconnect); +void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev); +void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en); +int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en); +int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause); + +static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) + return; + + if (!test_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags)) + return; + + _rtw89_mac_bf_monitor_track(rtwdev); +} + +static inline int rtw89_mac_txpwr_read32(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 *val) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 cr; + + if (!mac->get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) + return -EINVAL; + + *val = rtw89_read32(rtwdev, cr); + return 0; +} + +static inline int rtw89_mac_txpwr_write32(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 val) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 cr; + + if (!mac->get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) + return -EINVAL; + + rtw89_write32(rtwdev, cr, val); + return 0; +} + +static inline int rtw89_mac_txpwr_write32_mask(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 mask, u32 val) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 cr; + + if (!mac->get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) + return -EINVAL; + + rtw89_write32_mask(rtwdev, cr, mask, val); + return 0; +} + +static inline void rtw89_mac_ctrl_hci_dma_tx(struct rtw89_dev *rtwdev, + bool enable) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (enable) + rtw89_write32_set(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_TXDMA_EN); + else + rtw89_write32_clr(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_TXDMA_EN); +} + +static inline void rtw89_mac_ctrl_hci_dma_rx(struct rtw89_dev *rtwdev, + bool enable) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (enable) + rtw89_write32_set(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_RXDMA_EN); + else + rtw89_write32_clr(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_RXDMA_EN); +} + +static inline void rtw89_mac_ctrl_hci_dma_trx(struct rtw89_dev *rtwdev, + bool enable) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (enable) + rtw89_write32_set(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); + else + rtw89_write32_clr(rtwdev, chip->hci_func_en_addr, + B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); +} + +static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev) +{ + u32 val; + + val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, + B_AX_WLMAC_PWR_STE_MASK); + + return !!val; +} + +int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + bool resume, u32 tx_time); +int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + u32 *tx_time); +int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + bool resume, u8 tx_retry); +int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, u8 *tx_retry); + +enum rtw89_mac_xtal_si_offset { + XTAL0 = 0x0, + XTAL3 = 0x3, + XTAL_SI_XTAL_SC_XI = 0x04, +#define XTAL_SC_XI_MASK GENMASK(7, 0) + XTAL_SI_XTAL_SC_XO = 0x05, +#define XTAL_SC_XO_MASK GENMASK(7, 0) + XTAL_SI_XREF_MODE = 0x0B, + XTAL_SI_PWR_CUT = 0x10, +#define XTAL_SI_SMALL_PWR_CUT BIT(0) +#define XTAL_SI_BIG_PWR_CUT BIT(1) + XTAL_SI_AONLDO_CTRL = 0x10, + XTAL_SI_XTAL_DRV = 0x15, +#define XTAL_SI_DRV_LATCH BIT(4) + XTAL_SI_XTAL_PLL = 0x16, + XTAL_SI_XTAL_XMD_2 = 0x24, +#define XTAL_SI_LDO_LPS GENMASK(6, 4) + XTAL_SI_XTAL_XMD_4 = 0x26, +#define XTAL_SI_LPS_CAP GENMASK(3, 0) + XTAL_SI_XREF_RF1 = 0x2D, + XTAL_SI_XREF_RF2 = 0x2E, + XTAL_SI_CV = 0x41, +#define XTAL_SI_ACV_MASK GENMASK(3, 0) + XTAL_SI_LOW_ADDR = 0x62, +#define XTAL_SI_LOW_ADDR_MASK GENMASK(7, 0) + XTAL_SI_CTRL = 0x63, +#define XTAL_SI_MODE_SEL_MASK GENMASK(7, 6) +#define XTAL_SI_RDY BIT(5) +#define XTAL_SI_HIGH_ADDR_MASK GENMASK(2, 0) + XTAL_SI_READ_VAL = 0x7A, + XTAL_SI_WL_RFC_S0 = 0x80, +#define XTAL_SI_RF00S_EN GENMASK(2, 0) +#define XTAL_SI_RF00 BIT(0) + XTAL_SI_WL_RFC_S1 = 0x81, +#define XTAL_SI_RF10S_EN GENMASK(2, 0) +#define XTAL_SI_RF10 BIT(0) + XTAL_SI_ANAPAR_WL = 0x90, +#define XTAL_SI_SRAM2RFC BIT(7) +#define XTAL_SI_GND_SHDN_WL BIT(6) +#define XTAL_SI_SHDN_WL BIT(5) +#define XTAL_SI_RFC2RF BIT(4) +#define XTAL_SI_OFF_EI BIT(3) +#define XTAL_SI_OFF_WEI BIT(2) +#define XTAL_SI_PON_EI BIT(1) +#define XTAL_SI_PON_WEI BIT(0) + XTAL_SI_SRAM_CTRL = 0xA1, +#define XTAL_SI_SRAM_DIS BIT(1) +#define FULL_BIT_MASK GENMASK(7, 0) + XTAL_SI_APBT = 0xD1, + XTAL_SI_PLL = 0xE0, + XTAL_SI_PLL_1 = 0xE1, + XTAL_SI_CHIP_ID_L = 0xFD, + XTAL_SI_CHIP_ID_H = 0xFE, +}; + +static inline +int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->write_xtal_si(rtwdev, offset, val, mask); +} + +static inline +int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->read_xtal_si(rtwdev, offset, val); +} + +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); +int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx band); +void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool wow); +int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, + bool band1_en); +int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_dle_rsvd_qt_type type, + struct rtw89_mac_dle_rsvd_qt_cfg *cfg); +int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable); + +static inline int rtw89_mac_efuse_read_ecv(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->efuse_read_ecv) + return -ENOENT; + + return mac->efuse_read_ecv(rtwdev); +} + +static inline int rtw89_mac_efuse_read_thermal_k(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->efuse_read_thermal_k) + return -ENOENT; + + return mac->efuse_read_thermal_k(rtwdev); +} + +static inline int rtw89_mac_efuse_read_pwr_data(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->efuse_read_pwr_data) + return -ENOENT; + + return mac->efuse_read_pwr_data(rtwdev); +} + +static inline +void rtw89_mac_fwdl_preconfig(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->fwdl_preconfig) + return; + + mac->fwdl_preconfig(rtwdev); +} + +static inline +void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->fwdl_secure_idmem_share_mode) + return; + + mac->fwdl_secure_idmem_share_mode(rtwdev, mode); +} + +static inline +int rtw89_mac_scan_offload(struct rtw89_dev *rtwdev, + struct rtw89_scan_option *option, + struct rtw89_vif_link *rtwvif_link, + bool wowlan) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + int ret; + + ret = mac->scan_offload(rtwdev, option, rtwvif_link, wowlan); + + if (option->enable) { + /* + * At this point, new scan request is acknowledged by firmware, + * so scan events of previous scan request become obsoleted. + * Purge the queued scan events to prevent interference to + * current new request. + */ + rtw89_fw_c2h_purge_obsoleted_scan_events(rtwdev); + } + + return ret; +} + +static inline +void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; + + if (!rtwdev->hci.tx_rpt_enabled) + return; + + tx_req->desc_info.report = true; + /* firmware maintains a 4-bit sequence number */ + tx_req->desc_info.sn = atomic_inc_return(&tx_rpt->sn) & + RTW89_MAX_TX_RPTS_MASK; + tx_req->desc_info.tx_cnt_lmt_en = true; + tx_req->desc_info.tx_cnt_lmt = 8; +} + +static inline +bool rtw89_is_tx_rpt_skb(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + return rtw89_core_is_tx_wait(rtwdev, skb_data) || + (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); +} + +static inline +void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u8 tx_status) +{ + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); + struct ieee80211_tx_info *info; + + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) + return; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (tx_status == RTW89_TX_DONE) + info->flags |= IEEE80211_TX_STAT_ACK; + else + info->flags &= ~IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(rtwdev->hw, skb); +} + +static inline +void rtw89_tx_rpt_skb_add(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; + struct rtw89_tx_skb_data *skb_data; + u8 idx; + + skb_data = RTW89_TX_SKB_CB(skb); + idx = skb_data->tx_rpt_sn; + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + /* if skb having the similar seq number is still in the queue, + * this means the queue is overflowed - it isn't normal and + * should indicate firmware doesn't provide TX reports in time; + * report the old skb as dropped, we can't do much more here + */ + if (tx_rpt->skbs[idx]) + rtw89_tx_rpt_tx_status(rtwdev, tx_rpt->skbs[idx], + RTW89_TX_MACID_DROP); + tx_rpt->skbs[idx] = skb; + } +} + +static inline +void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev) +{ + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + memcpy(skbs, tx_rpt->skbs, sizeof(tx_rpt->skbs)); + memset(tx_rpt->skbs, 0, sizeof(tx_rpt->skbs)); + } + + for (int i = 0; i < ARRAY_SIZE(skbs); i++) + if (skbs[i]) + rtw89_tx_rpt_tx_status(rtwdev, skbs[i], + RTW89_TX_MACID_DROP); +} + +static inline bool rtw89_mac_chk_preload_allow(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return false; + + /* The RTL8922DE will re-enable pre-load function after verification. */ + + return false; +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c new file mode 100644 index 000000000..c1be69a3c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -0,0 +1,2068 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "cam.h" +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "sar.h" +#include "ser.h" +#include "util.h" +#include "wow.h" + +static void rtw89_ops_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = info->control.vif; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct ieee80211_sta *sta = control->sta; + u32 flags = IEEE80211_SKB_CB(skb)->flags; + int ret, qsel; + + if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n"); + skb_queue_tail(&rtwsta->roc_queue, skb); + return; + } + + ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); + if (ret) { + rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret); + ieee80211_free_txskb(hw, skb); + return; + } + rtw89_core_tx_kick_off(rtwdev, qsel); +} + +static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct rtw89_dev *rtwdev = hw->priv; + + ieee80211_schedule_txq(hw, txq); + queue_work(rtwdev->txq_wq, &rtwdev->txq_work); +} + +static int rtw89_ops_start(struct ieee80211_hw *hw) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + return rtw89_core_start(rtwdev); +} + +static void rtw89_ops_stop(struct ieee80211_hw *hw, bool suspend) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_core_stop(rtwdev); +} + +static int rtw89_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + /* let previous ips work finish to ensure we don't leave ips twice */ + wiphy_work_cancel(hw->wiphy, &rtwdev->ips_work); + + rtw89_leave_ps_mode(rtwdev); + + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + !(hw->conf.flags & IEEE80211_CONF_IDLE)) + rtw89_leave_ips(rtwdev); + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, + &hw->conf.chandef); + rtw89_set_channel(rtwdev); + } + + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (hw->conf.flags & IEEE80211_CONF_IDLE) && + !rtwdev->scanning) + rtw89_enter_ips(rtwdev); + + if (changed & IEEE80211_CONF_CHANGE_MONITOR) + rtw89_physts_parsing_init(rtwdev); + + return 0; +} + +static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_bss_conf *bss_conf; + int ret; + + rtw89_leave_ps_mode(rtwdev); + + rtw89_vif_type_mapping(rtwvif_link, false); + + wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); + wiphy_delayed_work_init(&rtwvif_link->csa_beacon_work, rtw89_core_csa_beacon_work); + wiphy_delayed_work_init(&rtwvif_link->mcc_gc_detect_beacon_work, + rtw89_mcc_gc_detect_beacon_work); + + INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); + + rtw89_p2p_noa_once_init(rtwvif_link); + + rtwvif_link->hit_rule = 0; + rtwvif_link->bcn_hit_cond = 0; + rtwvif_link->chanctx_assigned = false; + rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + rtwvif_link->rand_tsf_done = false; + rtwvif_link->detect_bcn_count = 0; + rtwvif_link->last_sync_bcn_tsf = 0; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); + + rcu_read_unlock(); + + ret = rtw89_mac_add_vif(rtwdev, rtwvif_link); + if (ret) + return ret; + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START); + return 0; +} + +static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->csa_beacon_work); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, + &rtwvif_link->mcc_gc_detect_beacon_work); + + rtw89_p2p_noa_once_deinit(rtwvif_link); + + rtw89_leave_ps_mode(rtwdev); + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP); + + rtw89_mac_remove_vif(rtwdev, rtwvif_link); +} + +static int rtw89_ops_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + u8 mac_id, port; + int ret = 0; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", + vif->addr, vif->type, vif->p2p); + + rtw89_leave_ips_by_hwflags(rtwdev); + + if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + + mac_id = rtw89_acquire_mac_id(rtwdev); + if (mac_id == RTW89_MAX_MAC_ID_NUM) + return -ENOSPC; + + port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM); + if (port == RTW89_PORT_NUM) { + ret = -ENOSPC; + goto release_macid; + } + + rtw89_init_vif(rtwdev, rtwvif, mac_id, port); + + rtw89_core_txq_init(rtwdev, vif->txq); + + if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) { + list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); + INIT_LIST_HEAD(&rtwvif->mgnt_entry); + INIT_LIST_HEAD(&rtwvif->dlink_pool); + } + + ether_addr_copy(rtwvif->mac_addr, vif->addr); + + rtwvif->offchan = false; + rtwvif->roc.state = RTW89_ROC_IDLE; + wiphy_delayed_work_init(&rtwvif->roc.roc_work, rtw89_roc_work); + + rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); + + rtwvif_link = rtw89_vif_set_link(rtwvif, RTW89_VIF_IDLE_LINK_ID); + if (!rtwvif_link) { + ret = -EINVAL; + goto release_port; + } + + ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link); + if (ret) + goto unset_link; + + rtwdev->pure_monitor_mode_vif = vif->type == NL80211_IFTYPE_MONITOR ? + rtwvif : NULL; + rtw89_recalc_lps(rtwdev); + return 0; + +unset_link: + rtw89_vif_unset_link(rtwvif, RTW89_VIF_IDLE_LINK_ID); +release_port: + list_del_init(&rtwvif->list); + rtw89_core_release_bit_map(rtwdev->hw_port, port); +release_macid: + rtw89_release_mac_id(rtwdev, mac_id); + + return ret; +} + +static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + u8 macid = rtw89_vif_get_main_macid(rtwvif); + u8 port = rtw89_vif_get_main_port(rtwvif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", + vif->addr, vif->type, vif->p2p); + + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); + + rtwvif_link = rtwvif->links[RTW89_VIF_IDLE_LINK_ID]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, RTW89_VIF_IDLE_LINK_ID); + goto bottom; + } + + __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link); + + rtw89_vif_unset_link(rtwvif, RTW89_VIF_IDLE_LINK_ID); + +bottom: + list_del_init(&rtwvif->list); + rtw89_core_release_bit_map(rtwdev->hw_port, port); + rtw89_release_mac_id(rtwdev, macid); + + rtwdev->pure_monitor_mode_vif = NULL; + + rtw89_recalc_lps(rtwdev); + rtw89_enter_ips_by_hwflags(rtwdev); +} + +static int rtw89_ops_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype type, bool p2p) +{ + struct rtw89_dev *rtwdev = hw->priv; + int ret; + + set_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", + vif->addr, vif->type, type, vif->p2p, p2p); + + rtw89_ops_remove_interface(hw, vif); + + vif->type = type; + vif->p2p = p2p; + + ret = rtw89_ops_add_interface(hw, vif); + if (ret) + rtw89_warn(rtwdev, "failed to change interface %d\n", ret); + + clear_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags); + + return ret; +} + +static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct rtw89_dev *rtwdev = hw->priv; + u32 rx_fltr; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | + FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ; + + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) + rtwdev->hal.rx_fltr &= ~B_AX_A_MC; + else + rtwdev->hal.rx_fltr |= B_AX_A_MC; + } + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) + rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR; + else + rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR; + } + if (changed_flags & FIF_OTHER_BSS) { + if (*new_flags & FIF_OTHER_BSS) + rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; + else + rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; + } + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { + rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN; + rtwdev->hal.rx_fltr &= ~B_AX_A_BC; + rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; + } else { + rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN; + rtwdev->hal.rx_fltr |= B_AX_A_BC; + rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; + } + } + if (changed_flags & FIF_PROBE_REQ) { + if (*new_flags & FIF_PROBE_REQ) { + rtwdev->hal.rx_fltr &= ~B_AX_A_BC_CAM_MATCH; + rtwdev->hal.rx_fltr &= ~B_AX_A_UC_CAM_MATCH; + } else { + rtwdev->hal.rx_fltr |= B_AX_A_BC_CAM_MATCH; + rtwdev->hal.rx_fltr |= B_AX_A_UC_CAM_MATCH; + } + } + + if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) + rtwdev->hal.rx_fltr |= B_AX_SNIFFER_MODE; + else + rtwdev->hal.rx_fltr &= ~B_AX_SNIFFER_MODE; + + rx_fltr = rtwdev->hal.rx_fltr; + + /* mac80211 doesn't configure filter when HW scan, driver need to + * set by itself. However, during P2P scan might have configure + * filter to overwrite filter that HW scan needed, so we need to + * check scan and append related filter + */ + if (rtwdev->scanning) { + rx_fltr &= ~B_AX_A_BCN_CHK_EN; + rx_fltr &= ~B_AX_A_BC; + rx_fltr &= ~B_AX_A_A1_MATCH; + } + + rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_0, rx_fltr); + if (!rtwdev->dbcc_en) + return; + rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_1, rx_fltr); +} + +static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { + [IEEE80211_AC_VO] = 3, + [IEEE80211_AC_VI] = 2, + [IEEE80211_AC_BE] = 0, + [IEEE80211_AC_BK] = 1, +}; + +static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u8 aifsn) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct ieee80211_bss_conf *bss_conf; + u8 slot_time; + u8 sifs; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + slot_time = bss_conf->use_short_slot ? 9 : 20; + + rcu_read_unlock(); + + sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16; + + return aifsn * slot_time + sifs; +} + +static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u16 ac) +{ + struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac]; + u32 val; + u8 ecw_max, ecw_min; + u8 aifs; + + /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ + ecw_max = ilog2(params->cw_max + 1); + ecw_min = ilog2(params->cw_min + 1); + aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, params->aifs); + val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) | + FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) | + FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) | + FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs); + rtw89_fw_h2c_set_edca(rtwdev, rtwvif_link, ac_to_fw_idx[ac], val); +} + +#define R_MUEDCA_ACS_PARAM(acs) {R_AX_MUEDCA_ ## acs ## _PARAM_0, \ + R_BE_MUEDCA_ ## acs ## _PARAM_0} + +static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS][RTW89_CHIP_GEN_NUM] = { + [IEEE80211_AC_VO] = R_MUEDCA_ACS_PARAM(VO), + [IEEE80211_AC_VI] = R_MUEDCA_ACS_PARAM(VI), + [IEEE80211_AC_BE] = R_MUEDCA_ACS_PARAM(BE), + [IEEE80211_AC_BK] = R_MUEDCA_ACS_PARAM(BK), +}; + +static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u16 ac) +{ + struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac]; + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca; + int gen = rtwdev->chip->chip_gen; + u8 aifs, aifsn; + u16 timer_32us; + u32 reg; + u32 val; + + if (!params->mu_edca) + return; + + mu_edca = ¶ms->mu_edca_param_rec; + aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn); + aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, aifsn) : 0; + timer_32us = mu_edca->mu_edca_timer << 8; + + val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) | + FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) | + FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs); + reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], + rtwvif_link->mac_idx); + rtw89_write32(rtwdev, reg, val); + + rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif_link, true); +} + +static void __rtw89_conf_tx(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, u16 ac) +{ + ____rtw89_conf_tx_edca(rtwdev, rtwvif_link, ac); + ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif_link, ac); +} + +static void rtw89_conf_tx(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + u16 ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + __rtw89_conf_tx(rtwdev, rtwvif_link, ac); +} + +static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + bool acquire_macid = false; + u8 macid; + int ret; + int i; + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; + + /* for station mode, assign the mac_id from itself */ + macid = rtw89_vif_get_main_macid(rtwvif); + } else { + macid = rtw89_acquire_mac_id(rtwdev); + if (macid == RTW89_MAX_MAC_ID_NUM) + return -ENOSPC; + + acquire_macid = true; + } + + rtw89_init_sta(rtwdev, rtwvif, rtwsta, macid); + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw89_core_txq_init(rtwdev, sta->txq[i]); + + INIT_LIST_HEAD(&rtwsta->dlink_pool); + + skb_queue_head_init(&rtwsta->roc_queue); + bitmap_zero(rtwsta->pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM); + + rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id); + if (!rtwsta_link) { + ret = -EINVAL; + goto err; + } + + rtwvif_link = rtwsta_link->rtwvif_link; + + ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + goto unset_link; + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); + + rtw89_fw_h2c_init_trx_protect(rtwdev); + + return 0; + +unset_link: + rtw89_sta_unset_link(rtwsta, sta->deflink.link_id); +err: + if (acquire_macid) + rtw89_release_mac_id(rtwdev, macid); + + return ret; +} + +static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + bool station_mode) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + + if (station_mode) + rtw89_vif_type_mapping(rtwvif_link, true); + + ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } + + rtwdev->total_sta_assoc++; + if (sta->tdls) + rtwvif->tdls_peer++; + + return 0; +} + +static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } + + rtwsta->disassoc = true; + + rtwdev->total_sta_assoc--; + if (sta->tdls) + rtwvif->tdls_peer--; + + return 0; +} + +static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_core_free_sta_pending_ba(rtwdev, sta); + rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); + rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } + + return 0; +} + +static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + u8 macid = rtw89_sta_get_main_macid(rtwsta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + rtw89_sta_unset_link(rtwsta, link_id); + } + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + rtw89_release_mac_id(rtwdev, macid); + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); + } + + return 0; +} + +static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif) +{ + struct ieee80211_sta *sta; + + if (vif->type != NL80211_IFTYPE_STATION) + return; + + sta = ieee80211_find_sta(vif, vif->cfg.ap_addr); + if (!sta) { + rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n"); + return; + } + + __rtw89_ops_sta_assoc(rtwdev, vif, sta, true); +} + +static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); + rtw89_mac_port_update(rtwdev, rtwvif_link); + rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link); + rtw89_mac_set_he_tb(rtwdev, rtwvif_link); +} + +static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); +} + +static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u64 changed) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + if (changed & BSS_CHANGED_ASSOC) { + if (vif->cfg.assoc) { + rtw89_station_mode_sta_assoc(rtwdev, vif); + __rtw89_ops_bss_assoc(rtwdev, vif); + + rtw89_queue_chanctx_work(rtwdev); + } else { + /* Abort ongoing scan if cancel_scan isn't issued + * when disconnected by peer + */ + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + } + } + + if (changed & BSS_CHANGED_PS) + rtw89_recalc_lps(rtwdev); + + if (changed & BSS_CHANGED_ARP_FILTER) + rtwvif->ip_addr = vif->cfg.arp_addr_list[0]; + + if (changed & BSS_CHANGED_MLD_VALID_LINKS) { + struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif); + u16 mac_id; + + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) + rtw89_chip_rfk_channel(rtwdev, cur); + + if (hweight16(vif->active_links) == 1) { + mac_id = cur->mac_id; + rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; + } else { + /* Specify for all MAC ID */ + mac_id = 0xffff; + rtwvif->mlo_mode = RTW89_MLO_MODE_EMLSR; + } + + rtw89_fw_h2c_tx_history(rtwdev, mac_id); + } +} + +static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf, + u64 changed) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + rtwvif_link = rtwvif->links[conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, conf->link_id); + return; + } + + if (changed & BSS_CHANGED_BSSID) { + ether_addr_copy(rtwvif_link->bssid, conf->bssid); + rtw89_cam_bssid_changed(rtwdev, rtwvif_link); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_INFO_CHANGE); + WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0); + } + + if (changed & BSS_CHANGED_BEACON) + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); + + if (changed & BSS_CHANGED_ERP_SLOT) + rtw89_conf_tx(rtwdev, rtwvif_link); + + if (changed & BSS_CHANGED_HE_BSS_COLOR) + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); + + if (changed & BSS_CHANGED_MU_GROUPS) + rtw89_mac_bf_set_gid_table(rtwdev, vif, conf); + + if (changed & BSS_CHANGED_P2P_PS) + rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf); + + if (changed & BSS_CHANGED_CQM) + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + + if (changed & BSS_CHANGED_TPE) + rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); +} + +static int rtw89_ops_start_ap(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + const struct rtw89_chan *chan; + int ret = 0; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return -ENOLINK; + } + + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->band_type == RTW89_BAND_6G) + return -EOPNOTSUPP; + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + ether_addr_copy(rtwvif_link->bssid, link_conf->bssid); + rtw89_cam_bssid_changed(rtwdev, rtwvif_link); + ret = rtw89_mac_port_update(rtwdev, rtwvif_link); + if (ret) { + rtw89_warn(rtwdev, "failed to update mac port\n"); + return ret; + } + + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); + return ret; + } + + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c role info\n"); + return ret; + } + + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c join info\n"); + return ret; + } + + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_TYPE_CHANGE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cam\n"); + return ret; + } + + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); + + if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) { + ret = rtw89_fw_h2c_ap_info_refcount(rtwdev, true); + if (ret) + return ret; + } + + rtw89_queue_chanctx_work(rtwdev); + + return 0; +} + +static +void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return; + } + + if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) + rtw89_fw_h2c_ap_info_refcount(rtwdev, false); + + rtw89_mac_stop_ap(rtwdev, rtwvif_link); + rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); + rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); +} + +static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + wiphy_work_queue(hw->wiphy, &rtwvif_link->update_beacon_work); + + return 0; +} + +static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + rtwvif_link = rtwvif->links[link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_id); + return -ENOLINK; + } + + rtwvif_link->tx_params[ac] = *params; + __rtw89_conf_tx(rtwdev, rtwvif_link, ac); + + return 0; +} + +static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct rtw89_dev *rtwdev = hw->priv; + + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + return __rtw89_ops_sta_add(rtwdev, vif, sta); + + if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) { + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) + return 0; /* defer to bss_info_changed to have vif info */ + return __rtw89_ops_sta_assoc(rtwdev, vif, sta, false); + } + + if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) + return __rtw89_ops_sta_disassoc(rtwdev, vif, sta); + + if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_NONE) + return __rtw89_ops_sta_disconnect(rtwdev, vif, sta); + + if (old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) + return __rtw89_ops_sta_remove(rtwdev, vif, sta); + + return 0; +} + +static int rtw89_ops_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + return __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state); +} + +static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct rtw89_dev *rtwdev = hw->priv; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + + switch (cmd) { + case SET_KEY: + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END); + ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key); + if (ret && ret != -EOPNOTSUPP) { + rtw89_err(rtwdev, "failed to add key to sec cam\n"); + return ret; + } + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + rtw89_core_tid_rx_stats_reset(rtwdev); + break; + case DISABLE_KEY: + flush_work(&rtwdev->txq_work); + rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, + false); + rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false); + ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true); + if (ret) { + rtw89_err(rtwdev, "failed to remove key from sec cam\n"); + return ret; + } + break; + } + + return ret; +} + +static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct ieee80211_sta *sta = params->sta; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + u16 tid = params->tid; + struct ieee80211_txq *txq = sta->txq[tid]; + struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + switch (params->action) { + case IEEE80211_AMPDU_TX_START: + return IEEE80211_AMPDU_TX_START_IMMEDIATE; + case IEEE80211_AMPDU_TX_STOP_CONT: + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); + clear_bit(tid, rtwsta->ampdu_map); + rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + rtw89_leave_ps_mode(rtwdev); + rtw89_phy_ra_recalc_agg_limit(rtwdev); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); + rtwsta->ampdu_params[tid].agg_num = params->buf_size; + rtwsta->ampdu_params[tid].amsdu = params->amsdu; + set_bit(tid, rtwsta->ampdu_map); + rtw89_leave_ps_mode(rtwdev); + rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); + rtw89_phy_ra_recalc_agg_limit(rtwdev); + break; + case IEEE80211_AMPDU_RX_START: + rtw89_core_tid_rx_stats_ctrl(rtwdev, rtwsta, params, true); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params); + break; + case IEEE80211_AMPDU_RX_STOP: + rtw89_core_tid_rx_stats_ctrl(rtwdev, rtwsta, params, false); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params); + break; + default: + WARN_ON(1); + return -ENOTSUPP; + } + + return 0; +} + +static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, + u32 value) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_ps_mode(rtwdev); + if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + rtw89_mac_update_rts_threshold(rtwdev); + + return 0; +} + +static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + + rtwsta_link = rtw89_get_designated_link(rtwsta); + if (unlikely(!rtwsta_link)) + return; + + sinfo->txrate = rtwsta_link->ra_report.txrate; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +} + +static +void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +{ + struct rtw89_vif *rtwvif; + + if (vif) { + rtwvif = vif_to_rtwvif(vif); + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); + } else { + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); + } +} + +static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_leave_lps(rtwdev); + rtw89_hci_flush_queues(rtwdev, queues, drop); + + if (drop && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) + __rtw89_drop_packets(rtwdev, vif); + else + rtw89_mac_flush_txq(rtwdev, queues, drop); +} + +struct rtw89_iter_bitrate_mask_data { + struct rtw89_dev *rtwdev; + struct ieee80211_vif *vif; + const struct cfg80211_bitrate_mask *mask; +}; + +static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_iter_bitrate_mask_data *br_data = data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + if (vif != br_data->vif || vif->p2p) + return; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwsta_link->use_cfg_mask = true; + rtwsta_link->mask = *br_data->mask; + } + + rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED); +} + +static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev, + .vif = vif, + .mask = mask}; + + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter, + &br_data); +} + +static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_phy_rate_pattern_vif(rtwdev, vif, mask); + rtw89_ra_mask_info_update(rtwdev, vif, mask); + + return 0; +} + +static +int rtw89_ops_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, u32 rx_ant) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_hal *hal = &rtwdev->hal; + const struct rtw89_chip_info *chip; + + lockdep_assert_wiphy(hw->wiphy); + + chip = rtwdev->chip; + + if (hal->ant_diversity) { + if (tx_ant != rx_ant || hweight32(tx_ant) != 1) + return -EINVAL; + } else if (chip->ops->cfg_txrx_path) { + /* With cfg_txrx_path ops, chips can configure rx_ant */ + } else if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) { + return -EINVAL; + } + + hal->antenna_tx = tx_ant; + hal->antenna_rx = rx_ant; + hal->tx_path_diversity = false; + hal->ant_diversity_fixed = true; + + return 0; +} + +static +int rtw89_ops_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, + u32 *rx_ant) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_hal *hal = &rtwdev->hal; + + *tx_ant = hal->antenna_tx; + *rx_ant = hal->antenna_rx; + + return 0; +} + +static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "sw scan start: find no designated link\n"); + return; + } + + rtw89_leave_lps(rtwdev); + + rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false); +} + +static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "sw scan complete: find no designated link\n"); + return; + } + + rtw89_core_scan_complete(rtwdev, rtwvif_link, false); +} + +static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) +{ + struct rtw89_dev *rtwdev = hw->priv; + + if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART) + rtw89_ser_recfg_done(rtwdev); +} + +static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *req) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_hal *hal = &rtwdev->hal; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) + return 1; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_HW_SCAN)) { + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, + "reject hw scan due to disabled_dm\n"); + return -EBUSY; + } + + if (rtwdev->scanning || rtwvif->offchan) + return -EBUSY; + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "hw scan: find no designated link\n"); + return -ENOLINK; + } + + rtw89_leave_lps(rtwdev); + rtw89_leave_ips_by_hwflags(rtwdev); + + ret = rtw89_hw_scan_start(rtwdev, rtwvif_link, req); + if (ret) + return ret; + + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_hw_scan_abort(rtwdev, rtwvif_link); + rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret); + } + + return ret; +} + +static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) + return; + + if (!rtwdev->scanning) + return; + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "cancel hw scan: find no designated link\n"); + return; + } + + rtw89_hw_scan_abort(rtwdev, rtwvif_link); +} + +static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(link_sta->sta); + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_sta_link *rtwsta_link; + + rtwsta_link = rtwsta->links[link_sta->link_id]; + if (unlikely(!rtwsta_link)) + return; + + rtw89_phy_ra_update_sta_link(rtwdev, rtwsta_link, changed); +} + +static int rtw89_ops_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + return rtw89_chanctx_ops_add(rtwdev, ctx); +} + +static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_chanctx_ops_remove(rtwdev, ctx); +} + +static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_chanctx_ops_change(rtwdev, ctx, changed); +} + +static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return -ENOLINK; + } + + return rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx); +} + +static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + + lockdep_assert_wiphy(hw->wiphy); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return; + } + + rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx); +} + +static +int rtw89_ops_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode) +{ + struct rtw89_dev *rtwdev = hw->priv; + bool replace; + int ret; + int i; + + lockdep_assert_wiphy(hw->wiphy); + + switch (mode) { + case CHANCTX_SWMODE_REASSIGN_VIF: + replace = false; + break; + case CHANCTX_SWMODE_SWAP_CONTEXTS: + replace = true; + break; + default: + return -EOPNOTSUPP; + } + + for (i = 0; i < n_vifs; i++) { + struct ieee80211_vif_chanctx_switch *p = &vifs[i]; + struct ieee80211_bss_conf *link_conf = p->link_conf; + struct rtw89_vif *rtwvif = vif_to_rtwvif(p->vif); + struct rtw89_vif_link *rtwvif_link; + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return -ENOLINK; + } + + ret = rtw89_chanctx_ops_reassign_vif(rtwdev, rtwvif_link, + p->old_ctx, p->new_ctx, + replace); + if (ret) + return ret; + } + + return 0; +} + +static void rtw89_ops_channel_switch_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_chan_def *chandef) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif_link *rtwvif_link; + + BUILD_BUG_ON(RTW89_MLD_NON_STA_LINK_NUM != 1); + + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "chsw bcn: find no designated link\n"); + return; + } + + wiphy_delayed_work_queue(hw->wiphy, &rtwvif_link->csa_beacon_work, 0); +} + +static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel *chan, + int duration, + enum ieee80211_roc_type type) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_roc *roc = &rtwvif->roc; + + lockdep_assert_wiphy(hw->wiphy); + + if (!rtwvif) + return -EINVAL; + + if (roc->state != RTW89_ROC_IDLE) { + return -EBUSY; + } + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + if (type == IEEE80211_ROC_TYPE_MGMT_TX) + roc->state = RTW89_ROC_MGMT; + else + roc->state = RTW89_ROC_NORMAL; + + roc->duration = duration; + roc->chan = *chan; + roc->type = type; + + rtw89_roc_start(rtwdev, rtwvif); + + return 0; +} + +static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + + lockdep_assert_wiphy(hw->wiphy); + + if (!rtwvif) + return -EINVAL; + + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); + + rtw89_roc_end(rtwdev, rtwvif); + + return 0; +} + +static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta) +{ + struct cfg80211_tid_config *tid_config = data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + + rtw89_core_set_tid_config(rtwdev, sta, tid_config); +} + +static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct cfg80211_tid_config *tid_config) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + if (sta) + rtw89_core_set_tid_config(rtwdev, sta, tid_config); + else + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_set_tid_config_iter, + tid_config); + + return 0; +} + +static bool rtw89_can_work_on_links(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, u16 links) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + u8 w = hweight16(links); + + if (vif->type != NL80211_IFTYPE_STATION && + w > RTW89_MLD_NON_STA_LINK_NUM) + return false; + + return w <= rtwvif->links_inst_valid_num; +} + +static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 active_links) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + u16 current_links = vif->active_links; + struct rtw89_vif_ml_trans trans = { + .mediate_links = current_links | active_links, + .links_to_del = current_links & ~active_links, + .links_to_add = active_links & ~current_links, + }; + + lockdep_assert_wiphy(hw->wiphy); + + if (!rtw89_can_work_on_links(rtwdev, vif, active_links)) + return false; + + /* + * Leave LPS at the beginning of ieee80211_set_active_links(). + * Because the entire process takes the same lock as our track + * work, LPS will not enter during ieee80211_set_active_links(). + */ + rtw89_leave_lps(rtwdev); + + rtwvif->ml_trans = trans; + + return true; +} + +static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + unsigned long clr_links) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + for_each_set_bit(link_id, &clr_links, IEEE80211_MLD_MAX_NUM_LINKS) { + rtwvif_link = rtwvif->links[link_id]; + if (unlikely(!rtwvif_link)) + continue; + + rtw89_fw_h2c_trx_protect(rtwdev, rtwvif_link->phy_idx, false); + + __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link); + + rtw89_vif_unset_link(rtwvif, link_id); + } +} + +static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + unsigned long set_links) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + int ret; + + for_each_set_bit(link_id, &set_links, IEEE80211_MLD_MAX_NUM_LINKS) { + rtwvif_link = rtw89_vif_set_link(rtwvif, link_id); + if (!rtwvif_link) + return -EINVAL; + + ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link); + if (ret) { + rtw89_err(rtwdev, "%s: failed to add iface (link id %u)\n", + __func__, link_id); + return ret; + } + rtw89_fw_h2c_trx_protect(rtwdev, rtwvif_link->phy_idx, true); + } + + return 0; +} + +static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + u16 current_links, bool en) +{ + struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + unsigned long links; + + /* Do follow-up when all updating links exist. */ + if (current_links != trans->mediate_links) + return; + + if (en) + links = trans->links_to_add; + else + links = trans->links_to_del; + + for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { + rtwvif_link = rtwvif->links[link_id]; + if (unlikely(!rtwvif_link)) + continue; + + rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, en); + } +} + +static +int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + unsigned long clr_links = old_links & ~new_links; + unsigned long set_links = new_links & ~old_links; + bool removing_links = !old_links || clr_links; + struct rtw89_link_conf_container *snap; + int ret = 0; + int i; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, + "%s: old_links (0x%08x) -> new_links (0x%08x)\n", + __func__, old_links, new_links); + + if (!rtw89_can_work_on_links(rtwdev, vif, new_links)) + return -EOPNOTSUPP; + + if (removing_links) { + snap = kzalloc_obj(*snap); + if (!snap) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(snap->link_conf); i++) + snap->link_conf[i] = old[i]; + + rcu_assign_pointer(rtwvif->snap_link_confs, snap); + } + + /* might depend on @snap; don't change order */ + rtw89_leave_ips_by_hwflags(rtwdev); + + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + + rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links, true); + + if (!old_links) + __rtw89_ops_clr_vif_links(rtwdev, rtwvif, + BIT(RTW89_VIF_IDLE_LINK_ID)); + else if (clr_links) + __rtw89_ops_clr_vif_links(rtwdev, rtwvif, clr_links); + + if (removing_links) { + /* @snap is required if and only if during removing links. + * However, it's done here. So, cleanup @snap immediately. + */ + rcu_assign_pointer(rtwvif->snap_link_confs, NULL); + + /* The pointers in @old will free after this function return, + * so synchronously wait for all readers of snap to be done. + */ + synchronize_rcu(); + kfree(snap); + } + + if (set_links) { + ret = __rtw89_ops_set_vif_links(rtwdev, rtwvif, set_links); + if (ret) + __rtw89_ops_clr_vif_links(rtwdev, rtwvif, set_links); + } else if (!new_links) { + ret = __rtw89_ops_set_vif_links(rtwdev, rtwvif, + BIT(RTW89_VIF_IDLE_LINK_ID)); + if (ret) + __rtw89_ops_clr_vif_links(rtwdev, rtwvif, + BIT(RTW89_VIF_IDLE_LINK_ID)); + } + + if (!ret) + rtw89_vif_update_fw_links(rtwdev, rtwvif, new_links, false); + + rtw89_enter_ips_by_hwflags(rtwdev); + return ret; +} + +static void __rtw89_ops_clr_sta_links(struct rtw89_dev *rtwdev, + struct rtw89_sta *rtwsta, + unsigned long clr_links) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + for_each_set_bit(link_id, &clr_links, IEEE80211_MLD_MAX_NUM_LINKS) { + rtwsta_link = rtwsta->links[link_id]; + if (unlikely(!rtwsta_link)) + continue; + + rtwvif_link = rtwsta_link->rtwvif_link; + + rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link); + rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link); + rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link); + + rtw89_sta_unset_link(rtwsta, link_id); + } +} + +static int __rtw89_ops_set_sta_links(struct rtw89_dev *rtwdev, + struct rtw89_sta *rtwsta, + unsigned long set_links) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + u8 sec_cam_idx; + int ret; + + for_each_set_bit(link_id, &set_links, IEEE80211_MLD_MAX_NUM_LINKS) { + rtwsta_link = rtw89_sta_set_link(rtwsta, link_id); + if (!rtwsta_link) + return -EINVAL; + + rtwvif_link = rtwsta_link->rtwvif_link; + + ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_err(rtwdev, "%s: failed to add sta (link id %u)\n", + __func__, link_id); + return ret; + } + + rtw89_vif_type_mapping(rtwvif_link, true); + + ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_err(rtwdev, "%s: failed to assoc sta (link id %u)\n", + __func__, link_id); + return ret; + } + + __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); + + for_each_set_bit(sec_cam_idx, rtwsta->pairwise_sec_cam_map, + RTW89_MAX_SEC_CAM_NUM) { + ret = rtw89_cam_attach_link_sec_cam(rtwdev, + rtwvif_link, + rtwsta_link, + sec_cam_idx); + if (ret) { + rtw89_err(rtwdev, + "%s: failed to apply pairwise key (link id %u)\n", + __func__, link_id); + return ret; + } + } + } + + return 0; +} + +static +int rtw89_ops_change_sta_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + unsigned long clr_links = old_links & ~new_links; + unsigned long set_links = new_links & ~old_links; + int ret = 0; + + lockdep_assert_wiphy(hw->wiphy); + + rtw89_debug(rtwdev, RTW89_DBG_STATE, + "%s: old_links (0x%08x) -> new_links (0x%08x)\n", + __func__, old_links, new_links); + + if (!rtw89_can_work_on_links(rtwdev, vif, new_links)) + return -EOPNOTSUPP; + + rtw89_leave_ps_mode(rtwdev); + + if (clr_links) + __rtw89_ops_clr_sta_links(rtwdev, rtwsta, clr_links); + + if (set_links) { + ret = __rtw89_ops_set_sta_links(rtwdev, rtwsta, set_links); + if (ret) + __rtw89_ops_clr_sta_links(rtwdev, rtwsta, set_links); + } + + return ret; +} + +#ifdef CONFIG_PM +static int rtw89_ops_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) +{ + struct rtw89_dev *rtwdev = hw->priv; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); + wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work); + wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_ps_work); + + ret = rtw89_wow_suspend(rtwdev, wowlan); + if (ret) { + rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret); + clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); + return 1; + } + + return 0; +} + +static int rtw89_ops_resume(struct ieee80211_hw *hw) +{ + struct rtw89_dev *rtwdev = hw->priv; + int ret; + + lockdep_assert_wiphy(hw->wiphy); + + ret = rtw89_wow_resume(rtwdev); + if (ret) + rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret); + + clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); + wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_ps_work, + RTW89_TRACK_PS_WORK_PERIOD); + + return ret ? 1 : 0; +} + +static void rtw89_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct rtw89_dev *rtwdev = hw->priv; + + device_set_wakeup_enable(rtwdev->dev, enabled); +} + +static void rtw89_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; + + lockdep_assert_wiphy(hw->wiphy); + + if (data->kek_len > sizeof(gtk_info->kek) || + data->kck_len > sizeof(gtk_info->kck)) { + rtw89_warn(rtwdev, "kek or kck length over fw limit\n"); + return; + } + + memcpy(gtk_info->kek, data->kek, data->kek_len); + memcpy(gtk_info->kck, data->kck, data->kck_len); +} +#endif + +static int rtw89_ops_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ieee80211_conf *conf = &hw->conf; + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_bb_ctx *bb; + + if (idx == 0) { + survey->channel = conf->chandef.chan; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = RTW89_NOISE_DEFAULT; + + return 0; + } + + rtw89_for_each_active_bb(rtwdev, bb) { + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_nhm_report *rpt; + + rpt = list_first_entry_or_null(&env->nhm_rpt_list, typeof(*rpt), list); + if (!rpt) + continue; + + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = rpt->noise - MAX_RSSI; + survey->channel = rpt->channel; + list_del_init(&rpt->list); + + return 0; + } + + return -EINVAL; +} + +static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw) +{ + struct rtw89_dev *rtwdev = hw->priv; + + lockdep_assert_wiphy(hw->wiphy); + + /* wl_disable GPIO get floating when entering LPS */ + if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags) || + test_bit(RTW89_FLAG_SHUTDOWN, rtwdev->flags)) + return; + + rtw89_core_rfkill_poll(rtwdev, false); +} + +const struct ieee80211_ops rtw89_ops = { + .tx = rtw89_ops_tx, + .wake_tx_queue = rtw89_ops_wake_tx_queue, + .start = rtw89_ops_start, + .stop = rtw89_ops_stop, + .config = rtw89_ops_config, + .add_interface = rtw89_ops_add_interface, + .change_interface = rtw89_ops_change_interface, + .remove_interface = rtw89_ops_remove_interface, + .configure_filter = rtw89_ops_configure_filter, + .vif_cfg_changed = rtw89_ops_vif_cfg_changed, + .link_info_changed = rtw89_ops_link_info_changed, + .start_ap = rtw89_ops_start_ap, + .stop_ap = rtw89_ops_stop_ap, + .set_tim = rtw89_ops_set_tim, + .conf_tx = rtw89_ops_conf_tx, + .sta_state = rtw89_ops_sta_state, + .set_key = rtw89_ops_set_key, + .ampdu_action = rtw89_ops_ampdu_action, + .get_survey = rtw89_ops_get_survey, + .set_rts_threshold = rtw89_ops_set_rts_threshold, + .sta_statistics = rtw89_ops_sta_statistics, + .flush = rtw89_ops_flush, + .set_bitrate_mask = rtw89_ops_set_bitrate_mask, + .set_antenna = rtw89_ops_set_antenna, + .get_antenna = rtw89_ops_get_antenna, + .sw_scan_start = rtw89_ops_sw_scan_start, + .sw_scan_complete = rtw89_ops_sw_scan_complete, + .reconfig_complete = rtw89_ops_reconfig_complete, + .hw_scan = rtw89_ops_hw_scan, + .cancel_hw_scan = rtw89_ops_cancel_hw_scan, + .add_chanctx = rtw89_ops_add_chanctx, + .remove_chanctx = rtw89_ops_remove_chanctx, + .change_chanctx = rtw89_ops_change_chanctx, + .assign_vif_chanctx = rtw89_ops_assign_vif_chanctx, + .unassign_vif_chanctx = rtw89_ops_unassign_vif_chanctx, + .switch_vif_chanctx = rtw89_ops_switch_vif_chanctx, + .channel_switch_beacon = rtw89_ops_channel_switch_beacon, + .remain_on_channel = rtw89_ops_remain_on_channel, + .cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel, + .set_sar_specs = rtw89_ops_set_sar_specs, + .link_sta_rc_update = rtw89_ops_sta_rc_update, + .set_tid_config = rtw89_ops_set_tid_config, + .can_activate_links = rtw89_ops_can_activate_links, + .change_vif_links = rtw89_ops_change_vif_links, + .change_sta_links = rtw89_ops_change_sta_links, +#ifdef CONFIG_PM + .suspend = rtw89_ops_suspend, + .resume = rtw89_ops_resume, + .set_wakeup = rtw89_ops_set_wakeup, + .set_rekey_data = rtw89_set_rekey_data, +#endif + .rfkill_poll = rtw89_ops_rfkill_poll, +}; +EXPORT_SYMBOL(rtw89_ops); diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c new file mode 100644 index 000000000..c8f343c8d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -0,0 +1,3368 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "debug.h" +#include "efuse.h" +#include "fw.h" +#include "mac.h" +#include "reg.h" + +static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = { + [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR_BE, + [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR_BE, + [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR_BE, + [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR_BE, + [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR_BE, + [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_SECURITY_CAM] = SEC_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR_BE, + [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR_BE, + [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR_BE, + [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR_BE, + [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR_BE, + [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR_BE, + [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR_BE, + [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR_BE, + [RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR_BE, + [RTW89_MAC_MEM_WD_PAGE] = WD_PAGE_BASE_ADDR_BE, + [RTW89_MAC_MEM_MLD_TBL] = MLD_TBL_BASE_ADDR_BE, +}; + +static const struct rtw89_port_reg rtw89_port_base_be = { + .port_cfg = R_BE_PORT_CFG_P0, + .tbtt_prohib = R_BE_TBTT_PROHIB_P0, + .bcn_area = R_BE_BCN_AREA_P0, + .bcn_early = R_BE_BCNERLYINT_CFG_P0, + .tbtt_early = R_BE_TBTTERLYINT_CFG_P0, + .tbtt_agg = R_BE_TBTT_AGG_P0, + .bcn_space = R_BE_BCN_SPACE_CFG_P0, + .bcn_forcetx = R_BE_BCN_FORCETX_P0, + .bcn_err_cnt = R_BE_BCN_ERR_CNT_P0, + .bcn_err_flag = R_BE_BCN_ERR_FLAG_P0, + .dtim_ctrl = R_BE_DTIM_CTRL_P0, + .tbtt_shift = R_BE_TBTT_SHIFT_P0, + .bcn_cnt_tmr = R_BE_BCN_CNT_TMR_P0, + .tsftr_l = R_BE_TSFTR_LOW_P0, + .tsftr_h = R_BE_TSFTR_HIGH_P0, + .md_tsft = R_BE_WMTX_MOREDATA_TSFT_STMP_CTL, + .bss_color = R_BE_PTCL_BSS_COLOR_0, + .mbssid = R_BE_MBSSID_CTRL, + .mbssid_drop = R_BE_MBSSID_DROP_0, + .tsf_sync = R_BE_PORT_0_TSF_SYNC, + .ptcl_dbg = R_BE_PTCL_DBG, + .ptcl_dbg_info = R_BE_PTCL_DBG_INFO, + .bcn_drop_all = R_BE_BCN_DROP_ALL0, + .bcn_psr_rpt = R_BE_BCN_PSR_RPT_P0, + .hiq_win = {R_BE_P0MB_HGQ_WINDOW_CFG_0, R_BE_PORT_HGQ_WINDOW_CFG, + R_BE_PORT_HGQ_WINDOW_CFG + 1, R_BE_PORT_HGQ_WINDOW_CFG + 2, + R_BE_PORT_HGQ_WINDOW_CFG + 3}, +}; + +static const struct rtw89_mac_mu_gid_addr rtw89_mac_mu_gid_addr_be = { + .position_en = {R_BE_GID_POSITION_EN0, R_BE_GID_POSITION_EN1}, + .position = {R_BE_GID_POSITION0, R_BE_GID_POSITION1, + R_BE_GID_POSITION2, R_BE_GID_POSITION3}, +}; + +static int rtw89_mac_check_mac_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_mac_hwmod_sel sel) +{ + if (sel == RTW89_DMAC_SEL && + test_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags)) + return 0; + if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_0 && + test_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags)) + return 0; + if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_1 && + test_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags)) + return 0; + + return -EFAULT; +} + +static bool is_qta_poh(struct rtw89_dev *rtwdev) +{ + return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE; +} + +static void hfc_get_mix_info_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + struct rtw89_hfc_pub_info *info = ¶m->pub_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val; + + val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO1); + info->g0_used = u32_get_bits(val, B_BE_G0_USE_PG_MASK); + info->g1_used = u32_get_bits(val, B_BE_G1_USE_PG_MASK); + + val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO3); + info->g0_aval = u32_get_bits(val, B_BE_G0_AVAL_PG_MASK); + info->g1_aval = u32_get_bits(val, B_BE_G1_AVAL_PG_MASK); + info->pub_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO2), + B_BE_PUB_AVAL_PG_MASK); + info->wp_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_WP_PAGE_INFO1), + B_BE_WP_AVAL_PG_MASK); + + val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL); + param->en = !!(val & B_BE_HCI_FC_EN); + param->h2c_en = !!(val & B_BE_HCI_FC_CH12_EN); + param->mode = u32_get_bits(val, B_BE_HCI_FC_MODE_MASK); + prec_cfg->ch011_full_cond = u32_get_bits(val, B_BE_HCI_FC_WD_FULL_COND_MASK); + prec_cfg->h2c_full_cond = u32_get_bits(val, B_BE_HCI_FC_CH12_FULL_COND_MASK); + prec_cfg->wp_ch07_full_cond = + u32_get_bits(val, B_BE_HCI_FC_WP_CH07_FULL_COND_MASK); + prec_cfg->wp_ch811_full_cond = + u32_get_bits(val, B_BE_HCI_FC_WP_CH811_FULL_COND_MASK); + + val = rtw89_read32(rtwdev, R_BE_CH_PAGE_CTRL); + prec_cfg->ch011_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH011_V1_MASK); + if (chip->chip_id == RTL8922D) + prec_cfg->ch011_full_page = u32_get_bits(val, B_BE_FULL_WD_PG_MASK); + prec_cfg->h2c_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH12_V1_MASK); + + val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL2); + pub_cfg->pub_max = u32_get_bits(val, B_BE_PUBPG_ALL_MASK); + + val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL1); + if (chip->chip_id == RTL8922D) { + prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_V1_MASK); + prec_cfg->wp_ch07_full_page = u32_get_bits(val, B_BE_FULL_PAGE_WP_CH07_MASK); + prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_V1_MASK); + prec_cfg->wp_ch811_full_page = u32_get_bits(val, B_BE_FULL_PAGE_WP_CH811_MASK); + } else { + prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_MASK); + prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_MASK); + } + + val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL2); + pub_cfg->wp_thrd = u32_get_bits(val, B_BE_WP_THRD_MASK); + + val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL1); + pub_cfg->grp0 = u32_get_bits(val, B_BE_PUBPG_G0_MASK); + pub_cfg->grp1 = u32_get_bits(val, B_BE_PUBPG_G1_MASK); +} + +static void hfc_h2c_cfg_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + u32 val; + + val = u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK); + rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val); +} + +static void hfc_mix_cfg_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; + const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val; + + val = u32_encode_bits(prec_cfg->ch011_prec, B_BE_PREC_PAGE_CH011_V1_MASK) | + u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK); + if (chip->chip_id == RTL8922D) + val = u32_replace_bits(val, prec_cfg->ch011_full_page, B_BE_FULL_WD_PG_MASK); + rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val); + + val = u32_encode_bits(pub_cfg->pub_max, B_BE_PUBPG_ALL_MASK); + rtw89_write32(rtwdev, R_BE_PUB_PAGE_CTRL2, val); + + if (chip->chip_id == RTL8922D) + val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_V1_MASK) | + u32_encode_bits(prec_cfg->wp_ch07_full_page, B_BE_FULL_PAGE_WP_CH07_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_V1_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_full_page, B_BE_FULL_PAGE_WP_CH811_MASK); + else + val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK); + rtw89_write32(rtwdev, R_BE_WP_PAGE_CTRL1, val); + + val = u32_replace_bits(rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL), + param->mode, B_BE_HCI_FC_MODE_MASK); + val = u32_replace_bits(val, prec_cfg->ch011_full_cond, + B_BE_HCI_FC_WD_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->h2c_full_cond, + B_BE_HCI_FC_CH12_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond, + B_BE_HCI_FC_WP_CH07_FULL_COND_MASK); + val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond, + B_BE_HCI_FC_WP_CH811_FULL_COND_MASK); + rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val); +} + +static void hfc_func_en_be(struct rtw89_dev *rtwdev, bool en, bool h2c_en) +{ + struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; + u32 val; + + val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL); + param->en = en; + param->h2c_en = h2c_en; + val = en ? (val | B_BE_HCI_FC_EN) : (val & ~B_BE_HCI_FC_EN); + val = h2c_en ? (val | B_BE_HCI_FC_CH12_EN) : + (val & ~B_BE_HCI_FC_CH12_EN); + rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val); +} + +static void dle_func_en_be(struct rtw89_dev *rtwdev, bool enable) +{ + if (enable) + rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN, + B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN); + else + rtw89_write32_clr(rtwdev, R_BE_DMAC_FUNC_EN, + B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN); +} + +static void dle_clk_en_be(struct rtw89_dev *rtwdev, bool enable) +{ + if (rtwdev->chip->chip_id != RTL8922A) + return; + + if (enable) + rtw89_write32_set(rtwdev, R_BE_DMAC_CLK_EN, + B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN); + else + rtw89_write32_clr(rtwdev, R_BE_DMAC_CLK_EN, + B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN); +} + +static int dle_mix_cfg_be(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg) +{ + const struct rtw89_dle_size *wde_size_cfg, *ple_size_cfg; + u32 bound; + u32 val; + + wde_size_cfg = cfg->wde_size; + ple_size_cfg = cfg->ple_size; + + val = rtw89_read32(rtwdev, R_BE_WDE_PKTBUF_CFG); + + switch (wde_size_cfg->pge_size) { + default: + case RTW89_WDE_PG_64: + val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64, + B_BE_WDE_PAGE_SEL_MASK); + break; + case RTW89_WDE_PG_128: + val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128, + B_BE_WDE_PAGE_SEL_MASK); + break; + case RTW89_WDE_PG_256: + rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n"); + return -EINVAL; + } + + bound = wde_size_cfg->srt_ofst / DLE_BOUND_UNIT; + val = u32_replace_bits(val, bound, B_BE_WDE_START_BOUND_MASK); + val = u32_replace_bits(val, wde_size_cfg->lnk_pge_num, + B_BE_WDE_FREE_PAGE_NUM_MASK); + rtw89_write32(rtwdev, R_BE_WDE_PKTBUF_CFG, val); + + val = rtw89_read32(rtwdev, R_BE_PLE_PKTBUF_CFG); + + switch (ple_size_cfg->pge_size) { + default: + case RTW89_PLE_PG_64: + rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n"); + return -EINVAL; + case RTW89_PLE_PG_128: + val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128, + B_BE_PLE_PAGE_SEL_MASK); + break; + case RTW89_PLE_PG_256: + val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256, + B_BE_PLE_PAGE_SEL_MASK); + break; + } + + bound = ple_size_cfg->srt_ofst / DLE_BOUND_UNIT; + val = u32_replace_bits(val, bound, B_BE_PLE_START_BOUND_MASK); + val = u32_replace_bits(val, ple_size_cfg->lnk_pge_num, + B_BE_PLE_FREE_PAGE_NUM_MASK); + rtw89_write32(rtwdev, R_BE_PLE_PKTBUF_CFG, val); + + return 0; +} + +static int chk_dle_rdy_be(struct rtw89_dev *rtwdev, bool wde_or_ple) +{ + u32 reg, mask; + u32 ini; + + if (wde_or_ple) { + reg = R_AX_WDE_INI_STATUS; + mask = WDE_MGN_INI_RDY; + } else { + reg = R_AX_PLE_INI_STATUS; + mask = PLE_MGN_INI_RDY; + } + + return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1, + 2000, false, rtwdev, reg); +} + +#define INVALID_QT_WCPU U16_MAX +#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \ + do { \ + val = u32_encode_bits(_min_x, B_BE_ ## _module ## _Q ## _idx ## _MIN_SIZE_MASK) | \ + u32_encode_bits(_max_x, B_BE_ ## _module ## _Q ## _idx ## _MAX_SIZE_MASK); \ + rtw89_write32(rtwdev, \ + R_BE_ ## _module ## _QTA ## _idx ## _CFG, \ + val); \ + } while (0) +#define SET_QUOTA(_x, _module, _idx) \ + SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx) + +static void wde_quota_cfg_be(struct rtw89_dev *rtwdev, + const struct rtw89_wde_quota *min_cfg, + const struct rtw89_wde_quota *max_cfg, + u16 ext_wde_min_qt_wcpu) +{ + u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ? + ext_wde_min_qt_wcpu : min_cfg->wcpu; + u16 max_qt_wcpu = max(max_cfg->wcpu, min_qt_wcpu); + u32 val; + + SET_QUOTA(hif, WDE, 0); + SET_QUOTA_VAL(min_qt_wcpu, max_qt_wcpu, WDE, 1); + SET_QUOTA_VAL(0, 0, WDE, 2); + SET_QUOTA(pkt_in, WDE, 3); + SET_QUOTA(cpu_io, WDE, 4); +} + +static void ple_quota_cfg_be(struct rtw89_dev *rtwdev, + const struct rtw89_ple_quota *min_cfg, + const struct rtw89_ple_quota *max_cfg) +{ + u32 val; + + SET_QUOTA(cma0_tx, PLE, 0); + SET_QUOTA(cma1_tx, PLE, 1); + SET_QUOTA(c2h, PLE, 2); + SET_QUOTA(h2c, PLE, 3); + SET_QUOTA(wcpu, PLE, 4); + SET_QUOTA(mpdu_proc, PLE, 5); + SET_QUOTA(cma0_dma, PLE, 6); + SET_QUOTA(cma1_dma, PLE, 7); + SET_QUOTA(bb_rpt, PLE, 8); + SET_QUOTA(wd_rel, PLE, 9); + SET_QUOTA(cpu_io, PLE, 10); + SET_QUOTA(tx_rpt, PLE, 11); + SET_QUOTA(h2d, PLE, 12); + + if (rtwdev->chip->chip_id == RTL8922A) + return; + + SET_QUOTA(snrpt, PLE, 13); +} + +static void rtw89_mac_hci_func_en_be(struct rtw89_dev *rtwdev) +{ + rtw89_write32_set(rtwdev, R_BE_HCI_FUNC_EN, B_BE_HCI_TXDMA_EN | + B_BE_HCI_RXDMA_EN); +} + +static void rtw89_mac_dmac_func_pre_en_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 mask; + u32 val; + + val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1); + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + val = u32_replace_bits(val, S_BE_DMA_MOD_PCIE_NO_DATA_CPU, + B_BE_DMA_MODE_MASK); + break; + case RTW89_HCI_TYPE_USB: + val = u32_replace_bits(val, S_BE_DMA_MOD_USB, B_BE_DMA_MODE_MASK); + val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN; + break; + case RTW89_HCI_TYPE_SDIO: + val = u32_replace_bits(val, S_BE_DMA_MOD_SDIO, B_BE_DMA_MODE_MASK); + val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN; + break; + default: + return; + } + + rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val); + + if (chip->chip_id == RTL8922A) + mask = B_BE_TX_STOP1_MASK; + else + mask = B_BE_TX_STOP1_MASK_V1; + + rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, mask); + + rtw89_write32_set(rtwdev, R_BE_DMAC_TABLE_CTRL, B_BE_DMAC_ADDR_MODE); +} + +static +int rtw89_mac_write_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask) +{ + u32 val32; + int ret; + + val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) | + u32_encode_bits(val, B_BE_WL_XTAL_SI_DATA_MASK) | + u32_encode_bits(mask, B_BE_WL_XTAL_SI_BITMASK_MASK) | + u32_encode_bits(XTAL_SI_NORMAL_WRITE, B_BE_WL_XTAL_SI_MODE_MASK) | + u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) | + B_BE_WL_XTAL_SI_CMD_POLL; + rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL), + 50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL); + if (ret) { + rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n", + offset, val, mask); + return ret; + } + + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + (u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset || + u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK) != val)) + rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n", + offset, val, val32); + + return 0; +} + +static +int rtw89_mac_read_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 *val) +{ + u32 val32; + int ret; + + val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) | + u32_encode_bits(0x0, B_BE_WL_XTAL_SI_DATA_MASK) | + u32_encode_bits(0x0, B_BE_WL_XTAL_SI_BITMASK_MASK) | + u32_encode_bits(XTAL_SI_NORMAL_READ, B_BE_WL_XTAL_SI_MODE_MASK) | + u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) | + B_BE_WL_XTAL_SI_CMD_POLL; + rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL), + 50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL); + if (ret) { + rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset); + return ret; + } + + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset) + rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n", + offset, val32); + + *val = u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK); + + return 0; +} + +static int rtw89_mac_reset_pwr_state_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + val32 = rtw89_read32(rtwdev, R_BE_SYSON_FSM_MON); + val32 &= WLAN_FSM_MASK; + val32 |= WLAN_FSM_SET; + rtw89_write32(rtwdev, R_BE_SYSON_FSM_MON, val32); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == WLAN_FSM_IDLE, + 1000, 2000000, false, + rtwdev, R_BE_SYSON_FSM_MON, WLAN_FSM_STATE_MASK); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN PMC timeout= %X\n", val32); + return ret; + } + + val32 = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK); + if (val32 == MAC_AX_MAC_OFF) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } else if (val32 == MAC_AX_MAC_ON) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_OFF, + 1000, 2000000, false, + rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC state timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } else if (val32 == MAC_AX_MAC_LPS) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_FORCE_LEAVE_LPS); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_ON, + 1000, 2000000, false, + rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC STS timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_OFF, + 1000, 2000000, false, + rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC state timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_WLLPS_CTRL, B_BE_FORCE_LEAVE_LPS); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } + + return 0; +} + +static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + + clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); + + rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); + rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET); + rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); + + val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL); + val32 &= B_BE_RUN_ENV_MASK; + rtw89_write32(rtwdev, R_BE_WCPU_FW_CTRL, val32); + + if (rtwdev->chip->chip_id == RTL8922A) + rtw89_write32_set(rtwdev, R_BE_DCPU_PLATFORM_ENABLE, B_BE_DCPU_PLATFORM_EN); + + rtw89_write32(rtwdev, R_BE_UDM0, 0); + rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); + rtw89_write32(rtwdev, R_BE_UDM2, 0); +} + +static void rtw89_mac_fwdl_preconfig_be(struct rtw89_dev *rtwdev) +{ + rtw89_write32_clr(rtwdev, R_BE_FW_AUTO_CAL_DELAY, B_BE_WCPU_FW_DELAY_COUNT_VALID); + rtw89_write32_mask(rtwdev, R_BE_FW_AUTO_CAL_DELAY, B_BE_WCPU_FW_DELAY_COUNT_MASK, 0); +} + +static void set_cpu_en(struct rtw89_dev *rtwdev, bool include_bb) +{ + u32 set = B_BE_WLANCPU_FWDL_EN; + + if (include_bb) + set |= B_BE_BBMCU0_FWDL_EN; + + rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, set); +} + +static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + int ret; + + val32 = rtw89_read32(rtwdev, R_BE_HALT_C2H); + if (val32) { + rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n"); + rtw89_warn(rtwdev, "[SER] %s: R_BE_HALT_C2H = 0x%x\n", __func__, val32); + } + val32 = rtw89_read32(rtwdev, R_BE_UDM1); + if (val32) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "[SER] AON L2 Debug register not empty before Boot.\n"); + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "[SER] %s: R_BE_UDM1 = 0x%x\n", __func__, val32); + } + val32 = rtw89_read32(rtwdev, R_BE_UDM2); + if (val32) { + rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n"); + rtw89_warn(rtwdev, "[SER] %s: R_BE_UDM2 = 0x%x\n", __func__, val32); + } + + rtw89_write32(rtwdev, R_BE_UDM1, 0); + rtw89_write32(rtwdev, R_BE_UDM2, 0); + rtw89_write32(rtwdev, R_BE_BOOT_DBG, 0x0); + rtw89_write32(rtwdev, R_BE_HALT_H2C, 0); + rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); + rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0); + rtw89_write32(rtwdev, R_BE_HALT_C2H_CTRL, 0); + + val32 = rtw89_read32(rtwdev, R_BE_HISR0); + rtw89_write32(rtwdev, R_BE_HISR0, B_BE_HALT_C2H_INT); + rtw89_debug(rtwdev, RTW89_DBG_SER, "HISR0=0x%x\n", val32); + + rtw89_write32_set(rtwdev, R_BE_SYS_CLK_CTRL, B_BE_CPU_CLK_EN); + rtw89_write32_clr(rtwdev, R_BE_SYS_CFG5, + B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN); + rtw89_write32_clr(rtwdev, R_BE_WCPU_FW_CTRL, + B_BE_WDT_PLT_RST_EN | B_BE_WCPU_ROM_CUT_GET); + rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0); + rtw89_write32_clr(rtwdev, R_BE_GPIO_MUXCFG, B_BE_BOOT_MODE); + + if (chip->chip_id != RTL8922A) + rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, B_BE_HOST_EXIST); + + rtw89_write32_mask(rtwdev, R_BE_WCPU_FW_CTRL, + B_BE_WCPU_ROM_CUT_VAL_MASK, hal->cv + 1); + rtw89_write16_mask(rtwdev, R_BE_BOOT_REASON, B_BE_BOOT_REASON_MASK, boot_reason); + rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); + rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET); + rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); + + if (!dlfw) { + ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); + if (ret) + return ret; + } + + return 0; +} + +static int rtw89_mac_fwdl_enable_wcpu_be(struct rtw89_dev *rtwdev, + u8 boot_reason, bool dlfw, + bool include_bb) +{ + set_cpu_en(rtwdev, include_bb); + + return wcpu_on(rtwdev, boot_reason, dlfw); +} + +static const u8 fwdl_status_map[] = { + [0] = RTW89_FWDL_INITIAL_STATE, + [1] = RTW89_FWDL_FWDL_ONGOING, + [4] = RTW89_FWDL_CHECKSUM_FAIL, + [5] = RTW89_FWDL_SECURITY_FAIL, + [6] = RTW89_FWDL_SECURITY_FAIL, + [7] = RTW89_FWDL_CV_NOT_MATCH, + [8] = RTW89_FWDL_RSVD0, + [2] = RTW89_FWDL_WCPU_FWDL_RDY, + [3] = RTW89_FWDL_WCPU_FW_INIT_RDY, + [9] = RTW89_FWDL_RSVD0, +}; + +static u8 fwdl_get_status_be(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) +{ + bool check_pass = false; + u32 val32; + u8 st; + + val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL); + + switch (type) { + case RTW89_FWDL_CHECK_WCPU_FWDL_DONE: + check_pass = !(val32 & B_BE_WLANCPU_FWDL_EN); + break; + case RTW89_FWDL_CHECK_DCPU_FWDL_DONE: + check_pass = !(val32 & B_BE_DATACPU_FWDL_EN); + break; + case RTW89_FWDL_CHECK_BB0_FWDL_DONE: + check_pass = !(val32 & B_BE_BBMCU0_FWDL_EN); + break; + case RTW89_FWDL_CHECK_BB1_FWDL_DONE: + check_pass = !(val32 & B_BE_BBMCU1_FWDL_EN); + break; + default: + break; + } + + if (check_pass) + return RTW89_FWDL_WCPU_FW_INIT_RDY; + + st = u32_get_bits(val32, B_BE_WCPU_FWDL_STATUS_MASK); + if (st < ARRAY_SIZE(fwdl_status_map)) + return fwdl_status_map[st]; + + return st; +} + +static int rtw89_fwdl_check_path_ready_be(struct rtw89_dev *rtwdev, + bool h2c_or_fwdl) +{ + u32 check = h2c_or_fwdl ? B_BE_H2C_PATH_RDY : B_BE_DLFW_PATH_RDY; + u32 val; + + return read_poll_timeout_atomic(rtw89_read32, val, val & check, + 1, 1000000, false, + rtwdev, R_BE_WCPU_FW_CTRL); +} + +static int dmac_func_en_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8922A) + return 0; + + rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN, + B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | + B_BE_MPDU_PROC_EN | B_BE_WD_RLS_EN | + B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN | + B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | + B_BE_PKT_BUF_EN | B_BE_DMAC_TBL_EN | + B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN | + B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | + B_BE_MAC_SEC_EN | B_BE_H_AXIDMA_EN | + B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN | + B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN); + + return 0; +} + +static int cmac_share_func_en_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8922A) + return 0; + + rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN, + B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | + B_BE_ADDRSRCH_EN | B_BE_BTCOEX_EN); + + return 0; +} + +static int cmac_pwr_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) +{ + if (mac_idx > RTW89_MAC_1) + return -EINVAL; + + if (mac_idx == RTW89_MAC_0) { + if (en == test_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags)) + return 0; + + if (en) { + rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC0_ALL_EN); + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC02PP); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC0_FEN); + + set_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + } else { + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC0_FEN); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC02PP); + rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC0_ALL_EN); + + clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + } + } else { + if (en == test_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags)) + return 0; + + if (en) { + rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC1_ALL_EN); + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC12PP); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC1_FEN); + + set_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); + } else { + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC1_FEN); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC12PP); + rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC1_ALL_EN); + + clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); + } + } + + return 0; +} + +static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) +{ + enum rtw89_flags pwr_flag, func_flag; + u32 reg; + + if (mac_idx > RTW89_MAC_1) + return -EINVAL; + + if (mac_idx == RTW89_MAC_0) { + pwr_flag = RTW89_FLAG_CMAC0_PWR; + func_flag = RTW89_FLAG_CMAC0_FUNC; + } else { + pwr_flag = RTW89_FLAG_CMAC1_PWR; + func_flag = RTW89_FLAG_CMAC1_FUNC; + } + + if (!test_bit(pwr_flag, rtwdev->flags)) { + rtw89_warn(rtwdev, "CMAC %u power cut did not release\n", mac_idx); + return 0; + } + + if (en) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_CK_EN_SET); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET); + + set_bit(func_flag, rtwdev->flags); + } else { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_CK_EN_SET); + + clear_bit(func_flag, rtwdev->flags); + } + + return 0; +} + +static int chip_func_en_be(struct rtw89_dev *rtwdev) +{ + return 0; +} + +static int sys_init_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = dmac_func_en_be(rtwdev); + if (ret) + return ret; + + ret = cmac_share_func_en_be(rtwdev); + if (ret) + return ret; + + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + + return chip_func_en_be(rtwdev); +} + +static int mac_func_en_be(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + ret = dmac_func_en_be(rtwdev); + if (ret) + return ret; + + ret = cmac_share_func_en_be(rtwdev); + if (ret) + return ret; + + val = rtw89_read32(rtwdev, R_BE_FEN_RST_ENABLE); + if (val & B_BE_CMAC0_FEN) { + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + } + + if (val & B_BE_CMAC1_FEN) { + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) + return ret; + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) + return ret; + } + + return 0; +} + +static int sta_sch_init_be(struct rtw89_dev *rtwdev) +{ + u32 p_val; + int ret; + + if (rtwdev->chip->chip_id == RTL8922D) { + rtw89_write32_set(rtwdev, R_BE_SS_LITE_TXL_MACID, B_BE_RPT_OTHER_BAND_EN); + return 0; + } + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_BE_SS_CTRL, B_BE_SS_EN); + + ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_BE_SS_INIT_DONE, + 1, TRXCFG_WAIT_CNT, false, rtwdev, R_BE_SS_CTRL); + if (ret) { + rtw89_err(rtwdev, "[ERR]STA scheduler init\n"); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SS_CTRL, B_BE_WARM_INIT); + rtw89_write32_clr(rtwdev, R_BE_SS_CTRL, B_BE_BAND_TRIG_EN | B_BE_BAND1_TRIG_EN); + + return 0; +} + +static int mpdu_proc_init_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + rtw89_write32_set(rtwdev, R_BE_MPDU_PROC, B_BE_APPEND_FCS); + rtw89_write32(rtwdev, R_BE_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL | + B_BE_CA_CHK_ADDRCAM_EN); + + val32 = rtw89_read32(rtwdev, R_BE_HDR_SHCUT_SETTING); + val32 |= (B_BE_TX_HW_SEQ_EN | B_BE_TX_HW_ACK_POLICY_EN | B_BE_TX_MAC_MPDU_PROC_EN); + val32 &= ~B_BE_TX_ADDR_MLD_TO_LIK; + rtw89_write32_set(rtwdev, R_BE_HDR_SHCUT_SETTING, val32); + + rtw89_write32(rtwdev, R_BE_RX_HDRTRNS, TRXCFG_MPDU_PROC_RX_HDR_CONV | + B_BE_HC_ADDR_HIT_EN); + + val32 = rtw89_read32(rtwdev, R_BE_DISP_FWD_WLAN_0); + val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_DATA_MASK); + val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_MNG_MASK); + val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_CTL_MASK); + val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_1_MASK); + rtw89_write32(rtwdev, R_BE_DISP_FWD_WLAN_0, val32); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int sec_eng_init_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + val32 = rtw89_read32(rtwdev, R_BE_SEC_ENG_CTRL); + val32 |= B_BE_CLK_EN_CGCMP | B_BE_CLK_EN_WAPI | B_BE_CLK_EN_WEP_TKIP | + B_BE_SEC_TX_ENC | B_BE_SEC_RX_DEC | + B_BE_MC_DEC | B_BE_BC_DEC | + B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC | + B_BE_SEC_PRE_ENQUE_TX; + rtw89_write32(rtwdev, R_BE_SEC_ENG_CTRL, val32); + + rtw89_write32_set(rtwdev, R_BE_SEC_MPDU_PROC, B_BE_APPEND_ICV | B_BE_APPEND_MIC); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int txpktctrl_init_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_mac_info *mac = &rtwdev->mac; + struct rtw89_mac_dle_rsvd_qt_cfg qt_cfg; + const struct rtw89_dle_input *dle_input; + u32 mpdu_info_b1_ofst; + u32 val32; + int ret; + + ret = rtw89_mac_get_dle_rsvd_qt_cfg(rtwdev, DLE_RSVD_QT_MPDU_INFO, &qt_cfg); + if (ret) { + rtw89_err(rtwdev, "get dle rsvd qt %d cfg fail %d\n", + DLE_RSVD_QT_MPDU_INFO, ret); + return ret; + } + + dle_input = mac->dle_info.dle_input; + if (dle_input) + mpdu_info_b1_ofst = DIV_ROUND_UP(dle_input->mpdu_info_tbl_b0, + BIT(MPDU_INFO_TBL_FACTOR)); + else + mpdu_info_b1_ofst = MPDU_INFO_B1_OFST; + + val32 = rtw89_read32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG); + val32 = u32_replace_bits(val32, qt_cfg.pktid, B_BE_MPDUINFO_PKTID_MASK); + val32 = u32_replace_bits(val32, mpdu_info_b1_ofst, B_BE_MPDUINFO_B1_BADDR_MASK); + val32 |= B_BE_MPDUINFO_FEN; + rtw89_write32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG, val32); + + return 0; +} + +static int mlo_init_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val32; + u32 reg; + int ret; + + rtw89_io_pack(rtwdev); + + val32 = rtw89_read32(rtwdev, R_BE_MLO_INIT_CTL); + val32 |= B_BE_MLO_TABLE_REINIT; + rtw89_write32(rtwdev, R_BE_MLO_INIT_CTL, val32); + val32 &= ~B_BE_MLO_TABLE_REINIT; + rtw89_write32(rtwdev, R_BE_MLO_INIT_CTL, val32); + + rtw89_io_unpack(rtwdev); + + ret = read_poll_timeout_atomic(rtw89_read32, val32, + val32 & B_BE_MLO_TABLE_INIT_DONE, + 1, 1000, false, rtwdev, R_BE_MLO_INIT_CTL); + if (ret) + rtw89_err(rtwdev, "[MLO]%s: MLO init polling timeout\n", __func__); + + if (chip->chip_id == RTL8922A) + reg = R_BE_SS_CTRL; + else + reg = R_BE_SS_CTRL_V1; + + rtw89_io_pack(rtwdev); + + rtw89_write32_set(rtwdev, reg, B_BE_MLO_HW_CHGLINK_EN); + rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_ACQCHK_CFG_0, B_BE_R_MACID_ACQ_CHK_EN); + + rtw89_io_unpack(rtwdev); + + return ret; +} + +static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + + ret = rtw89_mac_dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret); + return ret; + } + + ret = rtw89_mac_preload_init(rtwdev, mac_idx, rtwdev->mac.qta_mode); + if (ret) { + rtw89_err(rtwdev, "[ERR]preload init %d\n", ret); + return ret; + } + + ret = rtw89_mac_hfc_init(rtwdev, true, true, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret); + return ret; + } + + ret = sta_sch_init_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret); + return ret; + } + + ret = mpdu_proc_init_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret); + return ret; + } + + ret = sec_eng_init_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret); + return ret; + } + + ret = txpktctrl_init_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]TX pkt ctrl init %d\n", ret); + return ret; + } + + ret = mlo_init_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]MLO init %d\n", ret); + return ret; + } + + return ret; +} + +static int scheduler_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val32; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MISC_1, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_EN_TX_FINISH_PRD_RESP); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SCH_EXT_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_CWCNT_PLUS_MODE); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_CTN_CHK_CCA_NAV, mac_idx); + val32 = B_BE_HE_CTN_CHK_CCA_P20 | B_BE_HE_CTN_CHK_EDCCA_P20 | + B_BE_HE_CTN_CHK_CCA_BITMAP | B_BE_HE_CTN_CHK_EDCCA_BITMAP | + B_BE_HE_CTN_CHK_NO_GNT_WL | B_BE_HE_CTN_CHK_BASIC_NAV | + B_BE_HE_CTN_CHK_INTRA_NAV | B_BE_HE_CTN_CHK_TX_NAV; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_SIFS_CHK_CCA_NAV, mac_idx); + val32 = B_BE_HE_SIFS_CHK_EDCCA_P20 | B_BE_HE_SIFS_CHK_EDCCA_BITMAP | + B_BE_HE_SIFS_CHK_NO_GNT_WL; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_CHK_CCA_NAV, mac_idx); + val32 = B_BE_TB_CHK_EDCCA_BITMAP | B_BE_TB_CHK_NO_GNT_WL | B_BE_TB_CHK_BASIC_NAV; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CCA_CFG_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_NO_GNT_WL_EN); + + if (is_qta_poh(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_0, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_PREBKF_TIME_MASK, + SCH_PREBKF_24US); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_CFG_0, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_PREBKF_TIME_NONAC_MASK, + SCH_PREBKF_24US); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_EDCA_BCNQ_PARAM, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_CW_MASK, 0x32); + rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_AIFS_MASK, BCN_IFS_25US); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SCH_EDCA_RST_CFG, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_TX_NAV_RST_EDCA_EN); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int addr_cam_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val32; + u16 val16; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, ADDR_CAM_SERCH_RANGE, B_BE_ADDR_CAM_RANGE_MASK); + val32 |= B_BE_ADDR_CAM_EN; + if (mac_idx == RTW89_MAC_0) + val32 |= B_BE_ADDR_CAM_CLR; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, mac_idx); + ret = read_poll_timeout_atomic(rtw89_read16, val16, !(val16 & B_BE_ADDR_CAM_CLR), + 1, TRXCFG_WAIT_CNT, false, rtwdev, reg); + if (ret) + rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n"); + + return ret; +} + +static int rtw89_mac_typ_fltr_opt_be(struct rtw89_dev *rtwdev, + enum rtw89_machdr_frame_type type, + enum rtw89_mac_fwd_target fwd_target, + u8 mac_idx) +{ + u32 reg; + u32 val; + + switch (fwd_target) { + case RTW89_FWD_DONT_CARE: + val = RX_FLTR_FRAME_DROP_BE; + break; + case RTW89_FWD_TO_HOST: + case RTW89_FWD_TO_WLAN_CPU: + val = RX_FLTR_FRAME_ACCEPT_BE; + break; + default: + rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n"); + return -EINVAL; + } + + switch (type) { + case RTW89_MGNT: + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MGNT_FLTR, mac_idx); + break; + case RTW89_CTRL: + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTRL_FLTR, mac_idx); + break; + case RTW89_DATA: + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DATA_FLTR, mac_idx); + break; + default: + rtw89_err(rtwdev, "[ERR]set rx filter type err\n"); + return -EINVAL; + } + rtw89_write32(rtwdev, reg, val); + + return 0; +} + +static int rx_fltr_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + u32 val; + + rtw89_io_pack(rtwdev); + + rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_MGNT, RTW89_FWD_TO_HOST, mac_idx); + rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_CTRL, RTW89_FWD_TO_HOST, mac_idx); + rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_DATA, RTW89_FWD_TO_HOST, mac_idx); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx); + rtw89_write32(rtwdev, reg, rtwdev->hal.rx_fltr); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx); + val = B_BE_HE_SIGB_CRC_CHK | B_BE_VHT_MU_SIGB_CRC_CHK | + B_BE_VHT_SU_SIGB_CRC_CHK | B_BE_SIGA_CRC_CHK | + B_BE_LSIG_PARITY_CHK_EN | B_BE_CCK_SIG_CHK | B_BE_CCK_CRC_CHK; + rtw89_write16(rtwdev, reg, val); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int cca_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + return 0; +} + +static int nav_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val32; + u32 reg; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_NAV_CTL, mac_idx); + + val32 = rtw89_read32(rtwdev, reg); + val32 &= ~B_BE_WMAC_PLCP_UP_NAV_EN; + val32 |= B_BE_WMAC_TF_UP_NAV_EN | B_BE_WMAC_NAV_UPPER_EN; + val32 = u32_replace_bits(val32, NAV_25MS, B_BE_WMAC_NAV_UPPER_MASK); + + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SPECIAL_TX_SETTING, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_BMC_NAV_PROTECT); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_WMAC_MBA_DUR_FORCE); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int spatial_reuse_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_SR_CTRL, mac_idx); + rtw89_write8_clr(rtwdev, reg, B_BE_SR_EN | B_BE_SR_CTRL_PLCP_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BSSID_SRC_CTRL, mac_idx); + rtw89_write8_set(rtwdev, reg, B_BE_PLCP_SRC_EN); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int tmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + u32 reg; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_PPDU_CTRL, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_QOSNULL_UPD_MUEDCA_EN); + + if (chip->chip_id == RTL8922A) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMTX_TCR_BE_4, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK, 0x12); + rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, 0xe); + } + + if (chip->chip_id == RTL8922D && hal->cid != RTL8922D_CID7090) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_COMMON_PHYINTF_CTRL_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, CLEAR_DTOP_DIS); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int trxptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs; + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MAC_LOOPBACK, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, S_BE_MACLBK_PLCP_DLY_DEF, + B_BE_MACLBK_PLCP_DLY_MASK); + val32 &= ~B_BE_MACLBK_EN; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PHYINTF_EN); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_2, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PLCP_PHASE_B_CRC_CHK_EN | + B_BE_PLCP_PHASE_A_CRC_CHK_EN); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, WMAC_SPEC_SIFS_CCK, + B_BE_WMAC_SPEC_SIFS_CCK_MASK); + val32 = u32_replace_bits(val32, WMAC_SPEC_SIFS_OFDM_1115E, + B_BE_WMAC_SPEC_SIFS_OFDM_MASK); + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_RESP_LEGACY_CHK_EDCCA); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_RESP_HE_CHK_EDCCA); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_EHT_LEG_PUNC_CHK_EDCCA); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RXTRIG_TEST_USER_2, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_RXTRIG_FCSCHK_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_1, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 &= B_BE_FTM_RRSR_RATE_EN_MASK | B_BE_WMAC_RESP_DOPPLEB_BE_EN | + B_BE_WMAC_RESP_DCM_EN | B_BE_WMAC_RESP_REF_RATE_MASK; + rtw89_write32(rtwdev, reg, val32); + rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 &= B_BE_RRSR_RATE_EN_MASK | B_BE_RRSR_CCK_MASK | B_BE_RSC_MASK; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR0, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 &= B_BE_RRSR_OFDM_MASK | B_BE_RRSR_HT_MASK | B_BE_RRSR_VHT_MASK | + B_BE_RRSR_HE_MASK; + rtw89_write32(rtwdev, reg, val32); + + if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_RSC_MASK, 1); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int rst_bacam_be(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + rtw89_write32_mask(rtwdev, R_BE_RESPBA_CAM_CTRL, B_BE_BACAM_RST_MASK, + S_BE_BACAM_RST_ALL); + + ret = read_poll_timeout_atomic(rtw89_read32_mask, val, val == S_BE_BACAM_RST_DONE, + 1, 1000, false, + rtwdev, R_BE_RESPBA_CAM_CTRL, B_BE_BACAM_RST_MASK); + if (ret) + rtw89_err(rtwdev, "[ERR]bacam rst timeout\n"); + + return ret; +} + +#define PLD_RLS_MAX_PG 127 +#define RX_MAX_LEN_UNIT 512 +#define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT) + +static int rmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 rx_min_qta, rx_max_len, rx_max_pg; + u16 val16; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + if (mac_idx == RTW89_MAC_0) { + ret = rst_bacam_be(rtwdev); + if (ret) + return ret; + } + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DLK_PROTECT_CTL, mac_idx); + val16 = rtw89_read16(rtwdev, reg); + val16 = u16_replace_bits(val16, TRXCFG_RMAC_DATA_TO, B_BE_RX_DLK_DATA_TIME_MASK); + val16 = u16_replace_bits(val16, TRXCFG_RMAC_CCA_TO, B_BE_RX_DLK_CCA_TIME_MASK); + val16 |= B_BE_RX_DLK_RST_EN; + rtw89_write16(rtwdev, reg, val16); + + if (mac_idx == RTW89_MAC_0) + rx_min_qta = rtwdev->mac.dle_info.c0_rx_qta; + else + rx_min_qta = rtwdev->mac.dle_info.c1_rx_qta; + rx_max_pg = min_t(u32, rx_min_qta, PLD_RLS_MAX_PG); + rx_max_len = rx_max_pg * rtwdev->mac.dle_info.ple_pg_size; + rx_max_len = min_t(u32, rx_max_len, RX_SPEC_MAX_LEN); + rx_max_len /= RX_MAX_LEN_UNIT; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_RX_MPDU_MAX_LEN_MASK, rx_max_len); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx); + rtw89_write8_clr(rtwdev, reg, B_BE_VHT_SU_SIGB_CRC_CHK); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RCR, mac_idx); + rtw89_write16_set(rtwdev, reg, B_BE_BUSY_CHKSN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_1, mac_idx); + rtw89_write16_set(rtwdev, reg, B_BE_PLCP_SU_PSDU_LEN_SRC); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BSR_UPD_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_QSIZE_RULE); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RXGCK_CTRL, mac_idx); + rtw89_write16_mask(rtwdev, reg, B_BE_RXGCK_GCK_RATE_LIMIT_MASK, RX_GCK_LEGACY); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_DIS_CHK_MIN_LEN); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int resp_pktctl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + struct rtw89_mac_dle_rsvd_qt_cfg qt_cfg; + enum rtw89_mac_dle_rsvd_qt_type type; + u32 reg; + int ret; + + if (mac_idx == RTW89_MAC_1) + type = DLE_RSVD_QT_B1_CSI; + else + type = DLE_RSVD_QT_B0_CSI; + + ret = rtw89_mac_get_dle_rsvd_qt_cfg(rtwdev, type, &qt_cfg); + if (ret) { + rtw89_err(rtwdev, "get dle rsvd qt %d cfg fail %d\n", type, ret); + return ret; + } + + rtw89_io_pack(rtwdev); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RESP_CSI_RESERVED_PAGE, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_START_PAGE_MASK, qt_cfg.pktid); + rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_PAGE_NUM_MASK, qt_cfg.pg_num + 1); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int cmac_com_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val32; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + if (mac_idx == RTW89_MAC_0) { + val32 = rtw89_read32(rtwdev, R_BE_TX_SUB_BAND_VALUE); + val32 = u32_replace_bits(val32, S_BE_TXSB_20M_8, B_BE_TXSB_20M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_40M_4, B_BE_TXSB_40M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_80M_2, B_BE_TXSB_80M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_160M_1, B_BE_TXSB_160M_MASK); + rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE, val32); + } else { + val32 = rtw89_read32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1); + val32 = u32_replace_bits(val32, S_BE_TXSB_20M_2, B_BE_TXSB_20M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_40M_1, B_BE_TXSB_40M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_80M_0, B_BE_TXSB_80M_MASK); + val32 = u32_replace_bits(val32, S_BE_TXSB_160M_0, B_BE_TXSB_160M_MASK); + rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1, val32); + } + + return 0; +} + +static int ptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val32; + u8 val8; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_io_pack(rtwdev); + + if (is_qta_poh(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SIFS_SETTING, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_1K, + B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK); + if (chip->chip_id == RTL8922A) + val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_SEC_256B, + B_BE_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); + val32 |= B_BE_HW_CTS2SELF_EN; + rtw89_write32(rtwdev, reg, val32); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_FSM_MON, mac_idx); + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, S_AX_PTCL_TO_2MS, + B_BE_PTCL_TX_ARB_TO_THR_MASK); + val32 &= ~B_BE_PTCL_TX_ARB_TO_MODE; + rtw89_write32(rtwdev, reg, val32); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_COMMON_SETTING_0, mac_idx); + val8 = rtw89_read8(rtwdev, reg); + val8 |= B_BE_CMAC_TX_MODE_0 | B_BE_CMAC_TX_MODE_1; + val8 &= ~(B_BE_PTCL_TRIGGER_SS_EN_0 | + B_BE_PTCL_TRIGGER_SS_EN_1 | + B_BE_PTCL_TRIGGER_SS_EN_UL); + rtw89_write8(rtwdev, reg, val8); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx); + if (chip->chip_id == RTL8922A) + val32 = AMPDU_MAX_TIME; + else + val32 = AMPDU_MAX_TIME_V1; + rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, val32); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AGG_BK_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_WDBK_CFG | B_BE_EN_RTY_BK | + B_BE_EN_RTY_BK_COD); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_MAX_AGG_NUM_MASK, + MAX_TX_AMPDU_NUM_V1 - 1); + } + + if (rtw89_mac_chk_preload_allow(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AGG_BK_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PRELD_MGQ0_EN | + B_BE_PRELD_HIQ_P4_EN | + B_BE_PRELD_HIQ_P3_EN | + B_BE_PRELD_HIQ_P2_EN | + B_BE_PRELD_HIQ_P1_EN | + B_BE_PRELD_HIQ_P0MB15_EN | + B_BE_PRELD_HIQ_P0MB14_EN | + B_BE_PRELD_HIQ_P0MB13_EN | + B_BE_PRELD_HIQ_P0MB12_EN | + B_BE_PRELD_HIQ_P0MB11_EN | + B_BE_PRELD_HIQ_P0MB10_EN | + B_BE_PRELD_HIQ_P0MB9_EN | + B_BE_PRELD_HIQ_P0MB8_EN | + B_BE_PRELD_HIQ_P0MB7_EN | + B_BE_PRELD_HIQ_P0MB6_EN | + B_BE_PRELD_HIQ_P0MB5_EN | + B_BE_PRELD_HIQ_P0MB4_EN | + B_BE_PRELD_HIQ_P0MB3_EN | + B_BE_PRELD_HIQ_P0MB2_EN | + B_BE_PRELD_HIQ_P0MB1_EN | + B_BE_PRELD_HIQ_P0_EN); + } + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static int cmac_dma_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 val32; + u32 reg; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_CTRL_1, mac_idx); + + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, WLCPU_RXCH2_QID, + B_BE_RXDMA_TXRPT_QUEUE_ID_SW_MASK); + val32 = u32_replace_bits(val32, WLCPU_RXCH2_QID, + B_BE_RXDMA_F2PCMDRPT_QUEUE_ID_SW_MASK); + rtw89_write32(rtwdev, reg, val32); + + return 0; +} + +static int cmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + int ret; + + ret = scheduler_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret); + return ret; + } + + ret = addr_cam_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx, + ret); + return ret; + } + + ret = rx_fltr_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx, + ret); + return ret; + } + + ret = cca_ctrl_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx, + ret); + return ret; + } + + ret = nav_ctrl_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx, + ret); + return ret; + } + + ret = spatial_reuse_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n", + mac_idx, ret); + return ret; + } + + ret = tmac_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret); + return ret; + } + + ret = trxptcl_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret); + return ret; + } + + ret = rmac_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret); + return ret; + } + + ret = resp_pktctl_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d resp pktctl init %d\n", mac_idx, ret); + return ret; + } + + ret = cmac_com_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret); + return ret; + } + + ret = ptcl_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret); + return ret; + } + + ret = cmac_dma_init_be(rtwdev, mac_idx); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret); + return ret; + } + + return ret; +} + +static int tx_idle_poll_band_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + u8 val8; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_TX_CTN_SEL, mac_idx); + + ret = read_poll_timeout_atomic(rtw89_read8, val8, !(val8 & B_BE_PTCL_BUSY), + 30, 66000, false, rtwdev, reg); + + return ret; +} + +static int dle_buf_req_be(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id) +{ + u32 val, reg; + int ret; + + reg = wd ? R_BE_WD_BUF_REQ : R_BE_PL_BUF_REQ; + val = buf_len; + val |= B_BE_WD_BUF_REQ_EXEC; + rtw89_write32(rtwdev, reg, val); + + reg = wd ? R_BE_WD_BUF_STATUS : R_BE_PL_BUF_STATUS; + + ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_BUF_STAT_DONE, + 1, 2000, false, rtwdev, reg); + if (ret) + return ret; + + *pkt_id = u32_get_bits(val, B_BE_WD_BUF_STAT_PKTID_MASK); + if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID) + return -ENOENT; + + return 0; +} + +static int set_cpuio_be(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd) +{ + u32 val_op0, val_op1, val_op2, val_op3; + u32 val, cmd_type, reg; + int ret; + + cmd_type = ctrl_para->cmd_type; + + reg = wd ? R_BE_WD_CPUQ_OP_3 : R_BE_PL_CPUQ_OP_3; + val_op3 = u32_replace_bits(0, ctrl_para->start_pktid, + B_BE_WD_CPUQ_OP_STRT_PKTID_MASK); + val_op3 = u32_replace_bits(val_op3, ctrl_para->end_pktid, + B_BE_WD_CPUQ_OP_END_PKTID_MASK); + rtw89_write32(rtwdev, reg, val_op3); + + reg = wd ? R_BE_WD_CPUQ_OP_1 : R_BE_PL_CPUQ_OP_1; + val_op1 = u32_replace_bits(0, ctrl_para->src_pid, + B_BE_WD_CPUQ_OP_SRC_PID_MASK); + val_op1 = u32_replace_bits(val_op1, ctrl_para->src_qid, + B_BE_WD_CPUQ_OP_SRC_QID_MASK); + val_op1 = u32_replace_bits(val_op1, ctrl_para->macid, + B_BE_WD_CPUQ_OP_SRC_MACID_MASK); + rtw89_write32(rtwdev, reg, val_op1); + + reg = wd ? R_BE_WD_CPUQ_OP_2 : R_BE_PL_CPUQ_OP_2; + val_op2 = u32_replace_bits(0, ctrl_para->dst_pid, + B_BE_WD_CPUQ_OP_DST_PID_MASK); + val_op2 = u32_replace_bits(val_op2, ctrl_para->dst_qid, + B_BE_WD_CPUQ_OP_DST_QID_MASK); + val_op2 = u32_replace_bits(val_op2, ctrl_para->macid, + B_BE_WD_CPUQ_OP_DST_MACID_MASK); + rtw89_write32(rtwdev, reg, val_op2); + + reg = wd ? R_BE_WD_CPUQ_OP_0 : R_BE_PL_CPUQ_OP_0; + val_op0 = u32_replace_bits(0, cmd_type, + B_BE_WD_CPUQ_OP_CMD_TYPE_MASK); + val_op0 = u32_replace_bits(val_op0, ctrl_para->pkt_num, + B_BE_WD_CPUQ_OP_PKTNUM_MASK); + val_op0 |= B_BE_WD_CPUQ_OP_EXEC; + rtw89_write32(rtwdev, reg, val_op0); + + reg = wd ? R_BE_WD_CPUQ_OP_STATUS : R_BE_PL_CPUQ_OP_STATUS; + + ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_CPUQ_OP_STAT_DONE, + 1, 2000, false, rtwdev, reg); + if (ret) { + rtw89_err(rtwdev, "[ERR]set cpuio wd timeout\n"); + rtw89_err(rtwdev, "[ERR]op_0=0x%X, op_1=0x%X, op_2=0x%X\n", + val_op0, val_op1, val_op2); + return ret; + } + + if (cmd_type == CPUIO_OP_CMD_GET_NEXT_PID || + cmd_type == CPUIO_OP_CMD_GET_1ST_PID) + ctrl_para->pktid = u32_get_bits(val, B_BE_WD_CPUQ_OP_PKTID_MASK); + + return 0; +} + +static int dle_upd_qta_aval_page_be(struct rtw89_dev *rtwdev, + enum rtw89_mac_dle_ctrl_type type, + enum rtw89_mac_dle_ple_quota_id quota_id) +{ + u32 val; + + if (type == DLE_CTRL_TYPE_WDE) { + rtw89_write32_mask(rtwdev, R_BE_WDE_BUFMGN_CTL, + B_BE_WDE_AVAL_UPD_QTAID_MASK, quota_id); + rtw89_write32_set(rtwdev, R_BE_WDE_BUFMGN_CTL, B_BE_WDE_AVAL_UPD_REQ); + + return read_poll_timeout(rtw89_read32, val, + !(val & B_BE_WDE_AVAL_UPD_REQ), + 1, 2000, false, rtwdev, R_BE_WDE_BUFMGN_CTL); + } else if (type == DLE_CTRL_TYPE_PLE) { + rtw89_write32_mask(rtwdev, R_BE_PLE_BUFMGN_CTL, + B_BE_PLE_AVAL_UPD_QTAID_MASK, quota_id); + rtw89_write32_set(rtwdev, R_BE_PLE_BUFMGN_CTL, B_BE_PLE_AVAL_UPD_REQ); + + return read_poll_timeout(rtw89_read32, val, + !(val & B_BE_PLE_AVAL_UPD_REQ), + 1, 2000, false, rtwdev, R_BE_PLE_BUFMGN_CTL); + } + + rtw89_warn(rtwdev, "%s wrong type %d\n", __func__, type); + return -EINVAL; +} + +static int dle_quota_change_be(struct rtw89_dev *rtwdev, bool band1_en) +{ + int ret; + + if (band1_en) { + ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE, + PLE_QTAID_B0_TXPL); + if (ret) { + rtw89_err(rtwdev, "update PLE B0 TX avail page fail %d\n", ret); + return ret; + } + + ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE, + PLE_QTAID_CMAC0_RX); + if (ret) { + rtw89_err(rtwdev, "update PLE CMAC0 RX avail page fail %d\n", ret); + return ret; + } + } else { + ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE, + PLE_QTAID_B1_TXPL); + if (ret) { + rtw89_err(rtwdev, "update PLE B1 TX avail page fail %d\n", ret); + return ret; + } + + ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE, + PLE_QTAID_CMAC1_RX); + if (ret) { + rtw89_err(rtwdev, "update PLE CMAC1 RX avail page fail %d\n", ret); + return ret; + } + } + + return 0; +} + +static int preload_init_be(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_qta_mode mode) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 max_preld_size, min_rsvd_size; + u8 preld_acq, preld_miscq; + u32 val32; + u32 reg; + + if (!(chip->chip_id == RTL8922A || rtw89_mac_chk_preload_allow(rtwdev))) + return 0; + + rtw89_io_pack(rtwdev); + + max_preld_size = mac_idx == RTW89_MAC_0 ? + PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM; + if (chip->chip_id == RTL8922D) + max_preld_size = PRELD_B01_ENT_NUM_8922D; + max_preld_size *= PRELD_AMSDU_SIZE; + min_rsvd_size = PRELD_NEXT_MIN_SIZE; + + reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG1 : + R_BE_TXPKTCTL_B1_PRELD_CFG1; + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, PRELD_NEXT_WND, B_BE_B0_PRELD_NXT_TXENDWIN_MASK); + val32 = u32_replace_bits(val32, min_rsvd_size, B_BE_B0_PRELD_NXT_RSVMINSZ_MASK); + rtw89_write32(rtwdev, reg, val32); + + reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG0 : + R_BE_TXPKTCTL_B1_PRELD_CFG0; + if (chip->chip_id == RTL8922D) { + preld_acq = PRELD_ACQ_ENT_NUM_8922D; + preld_miscq = PRELD_MISCQ_ENT_NUM_8922D; + } else { + preld_acq = mac_idx == RTW89_MAC_0 ? PRELD_B0_ACQ_ENT_NUM_8922A : + PRELD_B1_ACQ_ENT_NUM_8922A; + preld_miscq = PRELD_MISCQ_ENT_NUM_8922A; + } + + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, preld_acq, B_BE_B0_PRELD_CAM_G0ENTNUM_MASK); + val32 = u32_replace_bits(val32, preld_miscq, B_BE_B0_PRELD_CAM_G1ENTNUM_MASK); + val32 = u32_replace_bits(val32, max_preld_size, B_BE_B0_PRELD_USEMAXSZ_MASK); + val32 |= B_BE_B0_PRELD_FEN; + rtw89_write32(rtwdev, reg, val32); + + rtw89_io_unpack(rtwdev); + + return 0; +} + +static void clr_aon_intr_be(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return; + + rtw89_write32_clr(rtwdev, R_BE_FWS0IMR, B_BE_FS_GPIOA_INT_EN); + rtw89_write32_set(rtwdev, R_BE_FWS0ISR, B_BE_FS_GPIOA_INT); +} + +static int dbcc_bb_ctrl_be(struct rtw89_dev *rtwdev, bool bb1_en) +{ + u32 set = B_BE_FEN_BB1PLAT_RSTB | B_BE_FEN_BB1_IP_RSTN; + + if (bb1_en) + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, set); + else + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, set); + + return 0; +} + +static int enable_imr_be(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_mac_hwmod_sel sel) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_imr_table *table; + const struct rtw89_reg_imr *reg; + u32 addr; + u32 val; + int i; + + if (sel == RTW89_DMAC_SEL) + table = chip->imr_dmac_table; + else if (sel == RTW89_CMAC_SEL) + table = chip->imr_cmac_table; + else + return -EINVAL; + + if (chip->chip_id == RTL8922D) + rtw89_write32_mask(rtwdev, R_BE_NO_RX_ERR_CFG, + B_BE_NO_RX_ERR_TO_MASK, 0); + + for (i = 0; i < table->n_regs; i++) { + reg = &table->regs[i]; + addr = rtw89_mac_reg_by_idx(rtwdev, reg->addr, mac_idx); + + val = rtw89_read32(rtwdev, addr); + val &= ~reg->clr; + val |= reg->set; + rtw89_write32(rtwdev, addr, val); + } + + return 0; +} + +static void err_imr_ctrl_be(struct rtw89_dev *rtwdev, bool en) +{ + u32 v32_dmac = en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS; + u32 v32_cmac0 = en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS; + u32 v32_cmac1 = en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS; + + v32_dmac &= ~B_BE_DMAC_NOTX_ERR_INT_EN; + + rtw89_write32(rtwdev, R_BE_DMAC_ERR_IMR, v32_dmac); + rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR, v32_cmac0); + + if (rtwdev->dbcc_en) + rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR_C1, v32_cmac1); +} + +static int band1_enable_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = tx_idle_poll_band_be(rtwdev, RTW89_MAC_0); + if (ret) { + rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret); + return ret; + } + + ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); + return ret; + } + + ret = preload_init_be(rtwdev, RTW89_MAC_1, rtwdev->mac.qta_mode); + if (ret) { + rtw89_err(rtwdev, "[ERR]preload init B1 %d\n", ret); + return ret; + } + + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d pwr en %d\n", RTW89_MAC_1, ret); + return ret; + } + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d func en %d\n", RTW89_MAC_1, ret); + return ret; + } + + ret = cmac_init_be(rtwdev, RTW89_MAC_1); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", RTW89_MAC_1, ret); + return ret; + } + + ret = dbcc_bb_ctrl_be(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]enable bb 1 %d\n", ret); + return ret; + } + + ret = enable_imr_be(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret); + return ret; + } + + return 0; +} + +static int band1_disable_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = dbcc_bb_ctrl_be(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]disable bb 1 %d\n", ret); + return ret; + } + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d func dis %d\n", RTW89_MAC_1, ret); + return ret; + } + + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d pwr dis %d\n", RTW89_MAC_1, ret); + return ret; + } + + ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); + return ret; + } + + return 0; +} + +static int dbcc_enable_be(struct rtw89_dev *rtwdev, bool enable) +{ + int ret; + + if (enable) { + ret = band1_enable_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret); + return ret; + } + + if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) { + ret = rtw89_fw_h2c_notify_dbcc(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "%s:[ERR] notify dbcc1 fail %d\n", + __func__, ret); + return ret; + } + } + } else { + if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) { + ret = rtw89_fw_h2c_notify_dbcc(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "%s:[ERR] notify dbcc1 fail %d\n", + __func__, ret); + return ret; + } + } + + ret = band1_disable_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] band1_disable %d\n", ret); + return ret; + } + } + + return 0; +} + +static int set_host_rpr_be(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val32; + u32 mode; + u32 fltr; + u32 qid; + bool poh; + + poh = is_qta_poh(rtwdev); + + if (poh) { + mode = RTW89_RPR_MODE_POH; + qid = WDRLS_DEST_QID_POH; + } else { + mode = RTW89_RPR_MODE_STF; + fltr = 0; + qid = WDRLS_DEST_QID_STF; + } + + if (chip_id == RTL8922A) { + fltr = S_BE_WDRLS_FLTR_TXOK | S_BE_WDRLS_FLTR_RTYLMT | + S_BE_WDRLS_FLTR_LIFTIM | S_BE_WDRLS_FLTR_MACID; + } else { + fltr = S_BE_WDRLS_FLTR_TXOK_V1 | S_BE_WDRLS_FLTR_RTYLMT_V1 | + S_BE_WDRLS_FLTR_LIFTIM_V1 | S_BE_WDRLS_FLTR_MACID_V1; + } + + rtw89_write32_mask(rtwdev, R_BE_WDRLS_CFG, B_BE_WDRLS_MODE_MASK, mode); + rtw89_write32_mask(rtwdev, R_BE_RLSRPT0_CFG0, B_BE_RLSRPT0_QID_MASK, qid); + + val32 = rtw89_read32(rtwdev, R_BE_RLSRPT0_CFG1); + if (chip_id == RTL8922A) + val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_MASK); + else + val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_V1_MASK); + val32 = u32_replace_bits(val32, 30, B_BE_RLSRPT0_AGGNUM_MASK); + val32 = u32_replace_bits(val32, 255, B_BE_RLSRPT0_TO_MASK); + rtw89_write32(rtwdev, R_BE_RLSRPT0_CFG1, val32); + + return 0; +} + +static int trx_init_be(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode; + int ret; + + ret = dmac_init_be(rtwdev, 0); + if (ret) { + rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret); + return ret; + } + + ret = cmac_init_be(rtwdev, 0); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret); + return ret; + } + + if (rtw89_mac_is_qta_dbcc(rtwdev, qta_mode)) { + ret = dbcc_enable_be(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret); + return ret; + } + } + + ret = enable_imr_be(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret); + return ret; + } + + ret = enable_imr_be(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); + if (ret) { + rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret); + return ret; + } + + err_imr_ctrl_be(rtwdev, true); + + ret = set_host_rpr_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret); + return ret; + } + + if (chip_id == RTL8922A) + rtw89_write32_clr(rtwdev, R_BE_RSP_CHK_SIG, + B_BE_RSP_STATIC_RTS_CHK_SERV_BW_EN); + + return 0; +} + +int rtw89_mac_cfg_gnt_v2(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + u32 val = 0; + + if (gnt_cfg->band[0].gnt_bt) + val |= B_BE_GNT_BT_BB0_VAL | B_BE_GNT_BT_RX_BB0_VAL | + B_BE_GNT_BT_TX_BB0_VAL; + + if (gnt_cfg->band[0].gnt_bt_sw_en) + val |= B_BE_GNT_BT_BB0_SWCTRL | B_BE_GNT_BT_RX_BB0_SWCTRL | + B_BE_GNT_BT_TX_BB0_SWCTRL; + + if (gnt_cfg->band[0].gnt_wl) + val |= B_BE_GNT_WL_BB0_VAL | B_BE_GNT_WL_RX_VAL | + B_BE_GNT_WL_TX_VAL | B_BE_GNT_WL_BB_PWR_VAL; + + if (gnt_cfg->band[0].gnt_wl_sw_en) + val |= B_BE_GNT_WL_BB0_SWCTRL | B_BE_GNT_WL_RX_SWCTRL | + B_BE_GNT_WL_TX_SWCTRL | B_BE_GNT_WL_BB_PWR_SWCTRL; + + if (gnt_cfg->band[1].gnt_bt) + val |= B_BE_GNT_BT_BB1_VAL | B_BE_GNT_BT_RX_BB1_VAL | + B_BE_GNT_BT_TX_BB1_VAL; + + if (gnt_cfg->band[1].gnt_bt_sw_en) + val |= B_BE_GNT_BT_BB1_SWCTRL | B_BE_GNT_BT_RX_BB1_SWCTRL | + B_BE_GNT_BT_TX_BB1_SWCTRL; + + if (gnt_cfg->band[1].gnt_wl) + val |= B_BE_GNT_WL_BB1_VAL | B_BE_GNT_WL_RX_VAL | + B_BE_GNT_WL_TX_VAL | B_BE_GNT_WL_BB_PWR_VAL; + + if (gnt_cfg->band[1].gnt_wl_sw_en) + val |= B_BE_GNT_WL_BB1_SWCTRL | B_BE_GNT_WL_RX_SWCTRL | + B_BE_GNT_WL_TX_SWCTRL | B_BE_GNT_WL_BB_PWR_SWCTRL; + + if (gnt_cfg->bt[0].wlan_act_en) + val |= B_BE_WL_ACT_SWCTRL; + if (gnt_cfg->bt[0].wlan_act) + val |= B_BE_WL_ACT_VAL; + if (gnt_cfg->bt[1].wlan_act_en) + val |= B_BE_WL_ACT2_SWCTRL; + if (gnt_cfg->bt[1].wlan_act) + val |= B_BE_WL_ACT2_VAL; + + rtw89_write32(rtwdev, R_BE_GNT_SW_CTRL, val); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v2); + +int rtw89_mac_cfg_gnt_v3(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + u32 val = 0; + + if (gnt_cfg->band[0].gnt_bt) + val |= B_BE_PTA_GNT_BT0_BB_VAL | B_BE_PTA_GNT_BT0_RX_BB0_VAL | + B_BE_PTA_GNT_BT0_TX_BB0_VAL; + + if (gnt_cfg->band[0].gnt_bt_sw_en) + val |= B_BE_PTA_GNT_BT0_BB_SWCTRL | B_BE_PTA_GNT_BT0_RX_BB0_SWCTRL | + B_BE_PTA_GNT_BT0_TX_BB0_SWCTRL; + + if (gnt_cfg->band[0].gnt_wl) + val |= B_BE_PTA_GNT_WL_BB0_VAL; + + if (gnt_cfg->band[0].gnt_wl_sw_en) + val |= B_BE_PTA_GNT_WL_BB0_SWCTRL; + + if (gnt_cfg->band[1].gnt_bt) + val |= B_BE_PTA_GNT_BT0_BB_VAL | B_BE_PTA_GNT_BT0_RX_BB1_VAL | + B_BE_PTA_GNT_BT0_TX_BB1_VAL; + + if (gnt_cfg->band[1].gnt_bt_sw_en) + val |= B_BE_PTA_GNT_BT0_BB_SWCTRL | B_BE_PTA_GNT_BT0_RX_BB1_SWCTRL | + B_BE_PTA_GNT_BT0_TX_BB1_SWCTRL; + + if (gnt_cfg->band[1].gnt_wl) + val |= B_BE_PTA_GNT_WL_BB1_VAL; + + if (gnt_cfg->band[1].gnt_wl_sw_en) + val |= B_BE_PTA_GNT_WL_BB1_SWCTRL; + + if (gnt_cfg->bt[0].wlan_act_en) + val |= B_BE_PTA_WL_ACT0_SWCTRL | B_BE_PTA_WL_ACT_RX_BT0_SWCTRL | + B_BE_PTA_WL_ACT_TX_BT0_SWCTRL; + if (gnt_cfg->bt[0].wlan_act) + val |= B_BE_PTA_WL_ACT0_VAL | B_BE_PTA_WL_ACT_RX_BT0_VAL | + B_BE_PTA_WL_ACT_TX_BT0_VAL; + if (gnt_cfg->bt[1].wlan_act_en) + val |= B_BE_PTA_WL_ACT1_SWCTRL | B_BE_PTA_WL_ACT_RX_BT1_SWCTRL | + B_BE_PTA_WL_ACT_TX_BT1_SWCTRL; + if (gnt_cfg->bt[1].wlan_act) + val |= B_BE_PTA_WL_ACT1_VAL | B_BE_PTA_WL_ACT_RX_BT1_VAL | + B_BE_PTA_WL_ACT_TX_BT1_VAL; + + rtw89_write32(rtwdev, R_BE_PTA_GNT_SW_CTRL, val); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v3); + +int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_mac_ax_coex_gnt gnt = {}; + int i; + + if (wl) + return 0; + + for (i = 0; i < RTW89_PHY_NUM; i++) { + gnt.band[i].gnt_bt_sw_en = 1; + gnt.band[i].gnt_bt = 1; + gnt.band[i].gnt_wl_sw_en = 1; + gnt.band[i].gnt_wl = 0; + gnt.bt[i].wlan_act = 1; + gnt.bt[i].wlan_act_en = 0; + } + + if (chip->chip_id == RTL8922A) + return rtw89_mac_cfg_gnt_v2(rtwdev, &gnt); + else + return rtw89_mac_cfg_gnt_v3(rtwdev, &gnt); + +} +EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v2); + +static +int rtw89_mac_cfg_plt_be(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) +{ + u32 reg; + u16 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL); + if (ret) + return ret; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BT_PLT, plt->band); + val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_BE_TX_PLT_GNT_LTE_RX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_BE_TX_PLT_GNT_BT_TX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_BE_TX_PLT_GNT_BT_RX : 0) | + (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_BE_TX_PLT_GNT_WL : 0) | + (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_BE_RX_PLT_GNT_LTE_RX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_BE_RX_PLT_GNT_BT_TX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_BE_RX_PLT_GNT_BT_RX : 0) | + (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_BE_RX_PLT_GNT_WL : 0) | + B_BE_PLT_EN; + rtw89_write16(rtwdev, reg, val); + + return 0; +} + +static u16 rtw89_mac_get_plt_cnt_be(struct rtw89_dev *rtwdev, u8 band) +{ + u32 reg; + u16 cnt; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BT_PLT, band); + cnt = rtw89_read32_mask(rtwdev, reg, B_BE_BT_PLT_PKT_CNT_MASK); + rtw89_write16_set(rtwdev, reg, B_BE_BT_PLT_RST); + + return cnt; +} + +static int rtw89_set_hw_sch_tx_en_v2(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 tx_en, u32 tx_en_mask) +{ + u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_DRV_TXEN, mac_idx); + u32 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + val = rtw89_read32(rtwdev, reg); + val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); + rtw89_write32(rtwdev, reg, val); + + return 0; +} + +int rtw89_mac_stop_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, + u32 *tx_en, enum rtw89_sch_tx_sel sel) +{ + int ret; + + *tx_en = rtw89_read32(rtwdev, + rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_DRV_TXEN, mac_idx)); + + switch (sel) { + case RTW89_SCH_TX_SEL_ALL: + ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, 0, + B_BE_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_HIQ: + ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, + 0, B_BE_CTN_TXEN_HGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MG0: + ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, + 0, B_BE_CTN_TXEN_MGQ); + if (ret) + return ret; + break; + case RTW89_SCH_TX_SEL_MACID: + ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, 0, + B_BE_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + break; + default: + return 0; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v2); + +int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) +{ + int ret; + + ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, tx_en, + B_BE_CTN_TXEN_ALL_MASK); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v2); + +void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) +{ + u32 reg, val; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RCR, mac_idx); + val = enable ? MAC_AX_PHY_RPT_SIZE_8 : MAC_AX_PHY_RPT_SIZE_0; + rtw89_write32_mask(rtwdev, reg, B_BE_PHY_RPT_SZ_MASK, val); + rtw89_write32_mask(rtwdev, reg, B_BE_HDR_CNV_SZ_MASK, MAC_AX_HDR_CNV_SIZE_0); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DRV_INFO_OPTION, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_DRV_INFO_PHYRPT_EN, enable); +} +EXPORT_SYMBOL(rtw89_mac_cfg_phy_rpt_be); + +static +void rtw89_mac_set_edcca_mode_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal) +{ + u16 resp_ack, resp_rts, resp_rts_punc, resp_normal, resp_normal_punc; + + if (rtwdev->chip->chip_id == RTL8922A) + return; + + resp_ack = RESP_ACK_CFG_BE; + resp_rts = RESP_RTS_CFG_BE; + resp_rts_punc = RESP_RTS_PUNC_CFG_BE; + resp_normal = RESP_NORMAL_CFG_BE; + resp_normal_punc = RESP_NORMAL_PUNC_CFG_BE; + + if (normal) { + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY, + resp_rts, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC, + resp_rts_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + } else { + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY, + resp_rts, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC, + resp_rts_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + } +} + +static +void rtw89_mac_set_vcore_cfg_be(struct rtw89_dev *rtwdev, u8 vlv) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + u8 target; + u8 vpwm; + int i; + + if (rtwdev->chip->chip_id != RTL8922D) + return; + + target = clamp(hal->thermal_prot_vmax - vlv, + hal->thermal_prot_vmin, hal->thermal_prot_vmax); + + val32 = rtw89_read32(rtwdev, R_BE_SPS_DIG_ON_CTRL0); + vpwm = u32_get_bits(val32, B_BE_PWMTUNE_MASK); + val32 &= ~B_BE_PWMTUNE_MASK; + + if (vpwm == target) + return; + + for (i = 0; i < RTW89_THERMAL_PROT_VLV_MAX; i++) { + if (vpwm > target) + vpwm--; + else + vpwm++; + + rtw89_write32(rtwdev, R_BE_SPS_DIG_ON_CTRL0, val32 | vpwm); + + if (vpwm == target) + break; + + mdelay(50); + } +} + +static +int rtw89_mac_cfg_ppdu_status_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) +{ + u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PPDU_STAT, mac_idx); + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + if (!enable) { + rtw89_write32_clr(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN); + return 0; + } + + rtw89_write32_mask(rtwdev, R_BE_HW_PPDU_STATUS, B_BE_FWD_PPDU_STAT_MASK, 3); + rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN | + B_BE_APP_RX_CNT_RPT | B_BE_APP_PLCP_HDR_RPT | + B_BE_PPDU_STAT_RPT_CRC32 | B_BE_PPDU_STAT_RPT_DMA); + + return 0; +} + +static bool rtw89_mac_get_txpwr_cr_be(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + u32 reg_base, u32 *cr) +{ + enum rtw89_qta_mode mode = rtwdev->mac.qta_mode; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, (enum rtw89_mac_idx)phy_idx, + RTW89_CMAC_SEL); + if (ret) { + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + return false; + + rtw89_err(rtwdev, "[TXPWR] check mac enable failed\n"); + return false; + } + + if (reg_base < R_BE_PWR_MODULE || reg_base > R_BE_CMAC_FUNC_EN_C1) { + rtw89_err(rtwdev, "[TXPWR] reg_base=0x%x exceed txpwr cr\n", + reg_base); + return false; + } + + *cr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx); + + if (*cr >= CMAC1_START_ADDR_BE && *cr <= CMAC1_END_ADDR_BE) { + if (mode == RTW89_QTA_SCC) { + rtw89_err(rtwdev, + "[TXPWR] addr=0x%x but hw not enable\n", + *cr); + return false; + } + } + + return true; +} + +static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + u32 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL | + B_BE_BFMEE_USE_NSTS | + B_BE_BFMEE_CSI_GID_SEL | + B_BE_BFMEE_CSI_FORCE_RETE_EN); + rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_CSI_RSC_MASK, CSI_RX_BW_CFG); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CSIRPT_OPTION, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_CSIPRT_VHTSU_AID_EN | + B_BE_CSIPRT_HESU_AID_EN | + B_BE_CSIPRT_EHTSU_AID_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx); + rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP_BE); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_BE_CSI_RRSC_BITMAP_MASK, + CSI_RRSC_BITMAP_CFG); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RATE, mac_idx); + val = u32_encode_bits(CSI_INIT_RATE_HT, B_BE_BFMEE_HT_CSI_RATE_MASK) | + u32_encode_bits(CSI_INIT_RATE_VHT, B_BE_BFMEE_VHT_CSI_RATE_MASK) | + u32_encode_bits(CSI_INIT_RATE_HE, B_BE_BFMEE_HE_CSI_RATE_MASK) | + u32_encode_bits(CSI_INIT_RATE_EHT, B_BE_BFMEE_EHT_CSI_RATE_MASK); + + rtw89_write32(rtwdev, reg, val); + + return 0; +} + +static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; + struct ieee80211_link_sta *link_sta; + u8 mac_idx = rtwvif_link->mac_idx; + u8 port_sel = rtwvif_link->port; + u8 sound_dim = 3, t; + u8 *phy_cap; + u32 reg; + u16 val; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; + + if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || + (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { + ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); + stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ); + t = u8_get_bits(phy_cap[5], + IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK); + sound_dim = min(sound_dim, t); + } + + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); + t = u32_get_bits(link_sta->vht_cap.cap, + IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); + sound_dim = min(sound_dim, t); + } + + /* Disable stbc_en in VHT 160MHz to avoid IOT issues with certain APs */ + if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) + stbc_en = 0; + + nc = min(nc, sound_dim); + nr = min(nr, sound_dim); + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); + + val = u16_encode_bits(nc, B_BE_BFMEE_CSIINFO0_NC_MASK) | + u16_encode_bits(nr, B_BE_BFMEE_CSIINFO0_NR_MASK) | + u16_encode_bits(ng, B_BE_BFMEE_CSIINFO0_NG_MASK) | + u16_encode_bits(cb, B_BE_BFMEE_CSIINFO0_CB_MASK) | + u16_encode_bits(cs, B_BE_BFMEE_CSIINFO0_CS_MASK) | + u16_encode_bits(ldpc_en, B_BE_BFMEE_CSIINFO0_LDPC_EN) | + u16_encode_bits(stbc_en, B_BE_BFMEE_CSIINFO0_STBC_EN); + + if (port_sel == 0) + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, + mac_idx); + else + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, + mac_idx); + + rtw89_write16(rtwdev, reg, val); + + return 0; +} + +static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); + struct ieee80211_link_sta *link_sta; + u8 mac_idx = rtwvif_link->mac_idx; + int ret; + u32 reg; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->he_cap.has_he) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | + BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | + BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); + } + if (link_sta->vht_cap.vht_supported) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | + BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | + BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); + } + if (link_sta->ht_cap.ht_supported) { + rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | + BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | + BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); + } + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); + rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx); + rtw89_write32(rtwdev, reg, rrsc); + + return 0; +} + +static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_link_sta *link_sta; + bool has_beamformer_cap; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta); + + rcu_read_unlock(); + + if (has_beamformer_cap) { + rtw89_debug(rtwdev, RTW89_DBG_BF, + "initialize bfee for new association\n"); + rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx); + rtw89_mac_set_csi_para_reg_be(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_csi_rrsc_be(rtwdev, rtwvif_link, rtwsta_link); + } +} + +static void dump_err_status_dispatcher_be(struct rtw89_dev *rtwdev) +{ + rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x ", + rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1)); + rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x ", + rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2)); + rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x ", + rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR)); + rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0)); +} + +static void rtw89_mac_dump_qta_lost_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_mac_dle_dfi_qempty qempty; + struct rtw89_mac_dle_dfi_quota quota; + struct rtw89_mac_dle_dfi_ctrl ctrl; + u32 val, not_empty, i; + int ret; + + qempty.dle_type = DLE_CTRL_TYPE_PLE; + qempty.grpsel = 0; + qempty.qempty = ~(u32)0; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty); + + for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) { + if (!(not_empty & BIT(0))) + continue; + ctrl.type = DLE_CTRL_TYPE_PLE; + ctrl.target = DLE_DFI_TYPE_QLNKTBL; + ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) | + u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK); + ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i, + u32_get_bits(ctrl.out_data, + QLNKTBL_DATA_SEL1_PKT_CNT_MASK)); + } + + quota.dle_type = DLE_CTRL_TYPE_PLE; + quota.qtaid = 6; + ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, "a); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n", + quota.rsv_pgnum, quota.use_pgnum); + + val = rtw89_read32(rtwdev, R_BE_PLE_QTA6_CFG); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n", + u32_get_bits(val, B_BE_PLE_Q6_MIN_SIZE_MASK)); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n", + u32_get_bits(val, B_BE_PLE_Q6_MAX_SIZE_MASK)); + val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT); + rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n", + u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK)); + rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG=0x%08x\n", + rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG)); + rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0=0x%08x\n", + rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0)); + + if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) { + quota.dle_type = DLE_CTRL_TYPE_PLE; + quota.qtaid = 7; + ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, "a); + if (ret) + rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); + else + rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n", + quota.rsv_pgnum, quota.use_pgnum); + + val = rtw89_read32(rtwdev, R_BE_PLE_QTA7_CFG); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n", + u32_get_bits(val, B_BE_PLE_Q7_MIN_SIZE_MASK)); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n", + u32_get_bits(val, B_BE_PLE_Q7_MAX_SIZE_MASK)); + val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT_C1); + rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n", + u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK)); + rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG_C1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG_C1)); + rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0_C1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0_C1)); + } + + rtw89_info(rtwdev, "R_BE_DLE_EMPTY0=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DLE_EMPTY0)); + rtw89_info(rtwdev, "R_BE_DLE_EMPTY1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_DLE_EMPTY1)); + + dump_err_status_dispatcher_be(rtwdev); +} + +static int rtw89_wow_config_mac_be(struct rtw89_dev *rtwdev, bool enable_wow) +{ + if (enable_wow) { + rtw89_write32_set(rtwdev, R_BE_RX_STOP, B_BE_HOST_RX_STOP); + rtw89_write32_clr(rtwdev, R_BE_RX_FLTR_OPT, B_BE_SNIFFER_MODE); + rtw89_mac_cpu_io_rx(rtwdev, enable_wow); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw89_write32(rtwdev, R_BE_FWD_ERR, 0); + rtw89_write32(rtwdev, R_BE_FWD_ACTN0, 0); + rtw89_write32(rtwdev, R_BE_FWD_ACTN1, 0); + rtw89_write32(rtwdev, R_BE_FWD_ACTN2, 0); + rtw89_write32(rtwdev, R_BE_FWD_TF0, 0); + rtw89_write32(rtwdev, R_BE_FWD_TF1, 0); + rtw89_write32(rtwdev, R_BE_FWD_ERR, 0); + rtw89_write32(rtwdev, R_BE_HW_PPDU_STATUS, 0); + rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY); + } else { + rtw89_mac_cpu_io_rx(rtwdev, enable_wow); + rtw89_write32_clr(rtwdev, R_BE_RX_STOP, B_BE_HOST_RX_STOP); + rtw89_write32_set(rtwdev, R_BE_RX_FLTR_OPT, R_BE_RX_FLTR_OPT); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + } + + return 0; +} + +static void rtw89_mac_dump_cmac_err_status_be(struct rtw89_dev *rtwdev, + u8 band) +{ + u32 offset = 0; + u32 cmac_err; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); + if (ret) { + rtw89_info(rtwdev, "[CMAC] : CMAC%d not enabled\n", band); + return; + } + + if (band) + offset = RTW89_MAC_BE_BAND_REG_OFFSET; + + cmac_err = rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset); + rtw89_info(rtwdev, "R_BE_CMAC_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset)); + rtw89_info(rtwdev, "R_BE_CMAC_FUNC_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_CMAC_FUNC_EN + offset)); + rtw89_info(rtwdev, "R_BE_CK_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_CK_EN + offset)); + + if (cmac_err & B_BE_SCHEDULE_TOP_ERR_IND) { + rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_IMR + offset)); + rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_ISR + offset)); + } + + if (cmac_err & B_BE_PTCL_TOP_ERR_IND) { + rtw89_info(rtwdev, "R_BE_PTCL_IMR0 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PTCL_IMR0 + offset)); + rtw89_info(rtwdev, "R_BE_PTCL_ISR0 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PTCL_ISR0 + offset)); + rtw89_info(rtwdev, "R_BE_PTCL_IMR1 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PTCL_IMR1 + offset)); + rtw89_info(rtwdev, "R_BE_PTCL_ISR1 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PTCL_ISR1 + offset)); + } + + if (cmac_err & B_BE_DMA_TOP_ERR_IND) { + rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR + offset)); + rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG + offset)); + rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG_IMR + offset)); + rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG + offset)); + rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR_1 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR_1 + offset)); + rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_1 [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_1 + offset)); + } + + if (cmac_err & B_BE_PHYINTF_ERR_IND) { + rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_IMR_V1 + offset)); + rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_ISR + offset)); + } + + if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { + rtw89_info(rtwdev, "R_BE_TXPWR_ERR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TXPWR_ERR_FLAG + offset)); + rtw89_info(rtwdev, "R_BE_TXPWR_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TXPWR_ERR_IMR + offset)); + } + + if (cmac_err & (B_BE_WMAC_RX_ERR_IND | B_BE_WMAC_TX_ERR_IND | + B_BE_WMAC_RX_IDLETO_IDCT | B_BE_PTCL_TX_IDLETO_IDCT)) { + rtw89_info(rtwdev, "R_BE_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_DBGSEL_TRXPTCL + offset)); + rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA_MASK + offset)); + rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA + offset)); + rtw89_info(rtwdev, "R_BE_RX_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERR_IMR + offset)); + rtw89_info(rtwdev, "R_BE_RX_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_RX_ERR_ISR + offset)); + } + + rtw89_info(rtwdev, "R_BE_CMAC_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_BE_CMAC_ERR_IMR + offset)); +} + +static void rtw89_mac_dump_err_status_be(struct rtw89_dev *rtwdev, + enum mac_ax_err_info err) +{ + if (err != MAC_AX_ERR_L1_ERR_DMAC && + err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && + err != MAC_AX_ERR_L0_ERR_CMAC0 && + err != MAC_AX_ERR_L0_ERR_CMAC1 && + err != MAC_AX_ERR_RXI300) + return; + + rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); + rtw89_info(rtwdev, "R_BE_SER_DBG_INFO=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_DBG_INFO)); + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT)); + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1)); + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT2=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT2)); + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT3=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT3)); + if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) { + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT_C1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT_C1)); + rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1_C1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1_C1)); + } + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_0=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_0)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_1=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_1)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_2=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_2)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_3=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_3)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_4=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_4)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_5=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_5)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_6=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_6)); + rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_7=0x%08x\n", + rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_7)); + + rtw89_mac_dump_dmac_err_status(rtwdev); + rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_0); + rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_1); + + rtwdev->hci.ops->dump_err_status(rtwdev); + + if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) + rtw89_mac_dump_l0_to_l1(rtwdev, err); + + rtw89_info(rtwdev, "<---\n"); +} + +static bool mac_is_txq_empty_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_mac_dle_dfi_qempty qempty; + u32 val32, msk32; + u32 grpnum; + int ret; + int i; + + grpnum = rtwdev->chip->wde_qempty_acq_grpnum; + qempty.dle_type = DLE_CTRL_TYPE_WDE; + + for (i = 0; i < grpnum; i++) { + qempty.grpsel = i; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) { + rtw89_warn(rtwdev, + "%s: failed to dle dfi acq empty: %d\n", + __func__, ret); + return false; + } + + /* Each acq group contains 32 queues (8 macid * 4 acq), + * but here, we can simply check if all bits are set. + */ + if (qempty.qempty != MASKDWORD) + return false; + } + + qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel; + ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty); + if (ret) { + rtw89_warn(rtwdev, "%s: failed to dle dfi mgq empty: %d\n", + __func__, ret); + return false; + } + + msk32 = B_CMAC0_MGQ_NORMAL_BE | B_CMAC1_MGQ_NORMAL_BE; + if ((qempty.qempty & msk32) != msk32) + return false; + + msk32 = B_BE_WDE_EMPTY_QUE_OTHERS; + val32 = rtw89_read32(rtwdev, R_BE_DLE_EMPTY0); + return (val32 & msk32) == msk32; +} + +const struct rtw89_mac_gen_def rtw89_mac_gen_be = { + .band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET, + .filter_model_addr = R_BE_FILTER_MODEL_ADDR, + .indir_access_addr = R_BE_INDIR_ACCESS_ENTRY, + .mem_base_addrs = rtw89_mac_mem_base_addrs_be, + .mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_BE, + .rx_fltr = R_BE_RX_FLTR_OPT, + .default_rx_fltr = DEFAULT_BE_RX_FLTR, + .port_base = &rtw89_port_base_be, + .agg_len_ht = R_BE_AGG_LEN_HT_0, + .ps_status = R_BE_WMTX_POWER_BE_BIT_CTL, + .mu_gid = &rtw89_mac_mu_gid_addr_be, + .boot_dbg = R_BE_BOOT_DBG, + + .muedca_ctrl = { + .addr = R_BE_MUEDCA_EN, + .mask = B_BE_MUEDCA_EN_0 | B_BE_SET_MUEDCATIMER_TF_0, + }, + .bfee_ctrl = { + .addr = R_BE_BFMEE_RESP_OPTION, + .mask = B_BE_BFMEE_HT_NDPA_EN | B_BE_BFMEE_VHT_NDPA_EN | + B_BE_BFMEE_HE_NDPA_EN | B_BE_BFMEE_EHT_NDPA_EN, + }, + .narrow_bw_ru_dis = { + .addr = R_BE_RXTRIG_TEST_USER_2, + .mask = B_BE_RXTRIG_RU26_DIS, + }, + .wow_ctrl = {.addr = R_BE_WOW_CTRL, .mask = B_BE_WOW_WOWEN,}, + .agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT, .mask = B_BE_AMPDU_MAX_TIME_MASK,}, + .ra_agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT, + .mask = B_BE_RA_TRY_RATE_AGG_LMT_MASK,}, + .txcnt_limit = {.addr = R_BE_TXCNT, .mask = B_BE_L_TXCNT_LMT_MASK,}, + + .check_mac_en = rtw89_mac_check_mac_en_be, + .sys_init = sys_init_be, + .trx_init = trx_init_be, + .preload_init = preload_init_be, + .clr_aon_intr = clr_aon_intr_be, + .err_imr_ctrl = err_imr_ctrl_be, + .mac_func_en = mac_func_en_be, + .hci_func_en = rtw89_mac_hci_func_en_be, + .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_be, + .dle_func_en = dle_func_en_be, + .dle_clk_en = dle_clk_en_be, + .bf_assoc = rtw89_mac_bf_assoc_be, + + .typ_fltr_opt = rtw89_mac_typ_fltr_opt_be, + .cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_be, + .cfg_phy_rpt = rtw89_mac_cfg_phy_rpt_be, + .set_edcca_mode = rtw89_mac_set_edcca_mode_be, + .set_vcore_cfg = rtw89_mac_set_vcore_cfg_be, + + .dle_mix_cfg = dle_mix_cfg_be, + .chk_dle_rdy = chk_dle_rdy_be, + .dle_buf_req = dle_buf_req_be, + .hfc_func_en = hfc_func_en_be, + .hfc_h2c_cfg = hfc_h2c_cfg_be, + .hfc_mix_cfg = hfc_mix_cfg_be, + .hfc_get_mix_info = hfc_get_mix_info_be, + .wde_quota_cfg = wde_quota_cfg_be, + .ple_quota_cfg = ple_quota_cfg_be, + .set_cpuio = set_cpuio_be, + .dle_quota_change = dle_quota_change_be, + + .reset_pwr_state = rtw89_mac_reset_pwr_state_be, + .disable_cpu = rtw89_mac_disable_cpu_be, + .fwdl_preconfig = rtw89_mac_fwdl_preconfig_be, + .fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be, + .fwdl_get_status = fwdl_get_status_be, + .fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be, + .fwdl_secure_idmem_share_mode = NULL, + .parse_efuse_map = rtw89_parse_efuse_map_be, + .parse_phycap_map = rtw89_parse_phycap_map_be, + .cnv_efuse_state = rtw89_cnv_efuse_state_be, + .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_be, + .efuse_read_ecv = rtw89_efuse_read_ecv_be, + .efuse_read_thermal_k = rtw89_efuse_read_thermal_k_be, + .efuse_read_pwr_data = rtw89_efuse_read_pwr_data_be, + + .cfg_plt = rtw89_mac_cfg_plt_be, + .get_plt_cnt = rtw89_mac_get_plt_cnt_be, + + .get_txpwr_cr = rtw89_mac_get_txpwr_cr_be, + + .write_xtal_si = rtw89_mac_write_xtal_si_be, + .read_xtal_si = rtw89_mac_read_xtal_si_be, + + .dump_qta_lost = rtw89_mac_dump_qta_lost_be, + .dump_err_status = rtw89_mac_dump_err_status_be, + + .is_txq_empty = mac_is_txq_empty_be, + + .prep_chan_list = rtw89_hw_scan_prep_chan_list_be, + .free_chan_list = rtw89_hw_scan_free_chan_list_be, + .add_chan_list = rtw89_hw_scan_add_chan_list_be, + .add_chan_list_pno = rtw89_pno_scan_add_chan_list_be, + .scan_offload = rtw89_fw_h2c_scan_offload_be, + + .wow_config_mac = rtw89_wow_config_mac_be, +}; +EXPORT_SYMBOL(rtw89_mac_gen_be); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c new file mode 100644 index 000000000..8c3f4eb52 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -0,0 +1,4896 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2020 Realtek Corporation + */ + +#include + +#include "mac.h" +#include "pci.h" +#include "reg.h" +#include "ser.h" + +static bool rtw89_pci_disable_clkreq; +static bool rtw89_pci_disable_aspm_l1; +static bool rtw89_pci_disable_l1ss; +module_param_named(disable_clkreq, rtw89_pci_disable_clkreq, bool, 0644); +module_param_named(disable_aspm_l1, rtw89_pci_disable_aspm_l1, bool, 0644); +module_param_named(disable_aspm_l1ss, rtw89_pci_disable_l1ss, bool, 0644); +MODULE_PARM_DESC(disable_clkreq, "Set Y to disable PCI clkreq support"); +MODULE_PARM_DESC(disable_aspm_l1, "Set Y to disable PCI ASPM L1 support"); +MODULE_PARM_DESC(disable_aspm_l1ss, "Set Y to disable PCI L1SS support"); + +static int rtw89_pci_get_phy_offset_by_link_speed(struct rtw89_dev *rtwdev, + u32 *phy_offset) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u32 val; + int ret; + + ret = pci_read_config_dword(pdev, RTW89_PCIE_L1_STS_V1, &val); + if (ret) + return ret; + + val = u32_get_bits(val, RTW89_BCFG_LINK_SPEED_MASK); + if (val == RTW89_PCIE_GEN1_SPEED) { + *phy_offset = R_RAC_DIRECT_OFFSET_G1; + } else if (val == RTW89_PCIE_GEN2_SPEED) { + *phy_offset = R_RAC_DIRECT_OFFSET_G2; + } else { + rtw89_warn(rtwdev, "Unknown PCI link speed %d\n", val); + return -EFAULT; + } + + return 0; +} + +static int rtw89_pci_rst_bdram_ax(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RST_BDRAM); + + ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_RST_BDRAM), + 1, RTW89_PCI_POLL_BDRAM_RST_CNT, false, + rtwdev, R_AX_PCIE_INIT_CFG1); + + return ret; +} + +static u32 rtw89_pci_dma_recalc(struct rtw89_dev *rtwdev, + struct rtw89_pci_dma_ring *bd_ring, + u32 cur_idx, bool tx) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 cnt, cur_rp, wp, rp, len; + + rp = bd_ring->rp; + wp = bd_ring->wp; + len = bd_ring->len; + + cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); + if (tx) { + cnt = cur_rp >= rp ? cur_rp - rp : len - (rp - cur_rp); + } else { + if (info->rx_ring_eq_is_full) + wp += 1; + + cnt = cur_rp >= wp ? cur_rp - wp : len - (wp - cur_rp); + } + + bd_ring->rp = cur_rp; + + return cnt; +} + +static u32 rtw89_pci_txbd_recalc(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; + u32 addr_idx = bd_ring->addr.idx; + u32 cnt, idx; + + idx = rtw89_read32(rtwdev, addr_idx); + cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, true); + + return cnt; +} + +static void rtw89_pci_release_fwcmd(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + u32 cnt, bool release_all) +{ + struct rtw89_pci_tx_data *tx_data; + struct sk_buff *skb; + u32 qlen; + + while (cnt--) { + skb = skb_dequeue(&rtwpci->h2c_queue); + if (!skb) { + rtw89_err(rtwdev, "failed to pre-release fwcmd\n"); + return; + } + skb_queue_tail(&rtwpci->h2c_release_queue, skb); + } + + qlen = skb_queue_len(&rtwpci->h2c_release_queue); + if (!release_all) + qlen = qlen > RTW89_PCI_MULTITAG ? qlen - RTW89_PCI_MULTITAG : 0; + + while (qlen--) { + skb = skb_dequeue(&rtwpci->h2c_release_queue); + if (!skb) { + rtw89_err(rtwdev, "failed to release fwcmd\n"); + return; + } + tx_data = RTW89_PCI_TX_SKB_CB(skb); + dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, + DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + } +} + +static void rtw89_pci_reclaim_tx_fwcmd(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci) +{ + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[RTW89_TXCH_CH12]; + u32 cnt; + + cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); + if (!cnt) + return; + rtw89_pci_release_fwcmd(rtwdev, rtwpci, cnt, false); +} + +static u32 rtw89_pci_rxbd_recalc(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + u32 addr_idx = bd_ring->addr.idx; + u32 cnt, idx; + + idx = rtw89_read32(rtwdev, addr_idx); + cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, false); + + return cnt; +} + +static void rtw89_pci_sync_skb_for_cpu(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw89_pci_rx_info *rx_info; + dma_addr_t dma; + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + dma = rx_info->dma; + dma_sync_single_for_cpu(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, + DMA_FROM_DEVICE); +} + +static void rtw89_pci_sync_skb_for_device(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw89_pci_rx_info *rx_info; + dma_addr_t dma; + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + dma = rx_info->dma; + dma_sync_single_for_device(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, + DMA_FROM_DEVICE); +} + +static void rtw89_pci_rxbd_info_update(struct rtw89_dev *rtwdev, + struct sk_buff *skb) +{ + struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb); + struct rtw89_pci_rxbd_info *rxbd_info; + __le32 info; + + rxbd_info = (struct rtw89_pci_rxbd_info *)skb->data; + info = rxbd_info->dword; + + rx_info->fs = le32_get_bits(info, RTW89_PCI_RXBD_FS); + rx_info->ls = le32_get_bits(info, RTW89_PCI_RXBD_LS); + rx_info->len = le32_get_bits(info, RTW89_PCI_RXBD_WRITE_SIZE); + rx_info->tag = le32_get_bits(info, RTW89_PCI_RXBD_TAG); +} + +static int rtw89_pci_validate_rx_tag(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring, + struct sk_buff *skb) +{ + struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb); + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 target_rx_tag; + + if (!info->check_rx_tag) + return 0; + + /* valid range is 1 ~ 0x1FFF */ + if (rx_ring->target_rx_tag == 0) + target_rx_tag = 1; + else + target_rx_tag = rx_ring->target_rx_tag; + + if (rx_info->tag != target_rx_tag) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "mismatch RX tag 0x%x 0x%x\n", + rx_info->tag, target_rx_tag); + return -EAGAIN; + } + + return 0; +} + +static +int rtw89_pci_sync_skb_for_device_and_validate_rx_info(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring, + struct sk_buff *skb) +{ + struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb); + int rx_tag_retry = 1000; + int ret; + + do { + rtw89_pci_sync_skb_for_cpu(rtwdev, skb); + rtw89_pci_rxbd_info_update(rtwdev, skb); + + ret = rtw89_pci_validate_rx_tag(rtwdev, rx_ring, skb); + if (ret != -EAGAIN) + break; + } while (rx_tag_retry--); + + /* update target rx_tag for next RX */ + rx_ring->target_rx_tag = rx_info->tag + 1; + + return ret; +} + +static void rtw89_pci_ctrl_txdma_ch_ax(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_reg_def *dma_stop1 = &info->dma_stop1; + const struct rtw89_reg_def *dma_stop2 = &info->dma_stop2; + + if (enable) { + rtw89_write32_clr(rtwdev, dma_stop1->addr, dma_stop1->mask); + if (dma_stop2->addr) + rtw89_write32_clr(rtwdev, dma_stop2->addr, dma_stop2->mask); + } else { + rtw89_write32_set(rtwdev, dma_stop1->addr, dma_stop1->mask); + if (dma_stop2->addr) + rtw89_write32_set(rtwdev, dma_stop2->addr, dma_stop2->mask); + } +} + +static void rtw89_pci_ctrl_txdma_fw_ch_ax(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_reg_def *dma_stop1 = &info->dma_stop1; + + if (enable) + rtw89_write32_clr(rtwdev, dma_stop1->addr, B_AX_STOP_CH12); + else + rtw89_write32_set(rtwdev, dma_stop1->addr, B_AX_STOP_CH12); +} + +static bool +rtw89_skb_put_rx_data(struct rtw89_dev *rtwdev, bool fs, bool ls, + struct sk_buff *new, + const struct sk_buff *skb, u32 offset, + const struct rtw89_pci_rx_info *rx_info, + const struct rtw89_rx_desc_info *desc_info) +{ + u32 copy_len = rx_info->len - offset; + + if (unlikely(skb_tailroom(new) < copy_len)) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "invalid rx data length bd_len=%d desc_len=%d offset=%d (fs=%d ls=%d)\n", + rx_info->len, desc_info->pkt_size, offset, fs, ls); + rtw89_hex_dump(rtwdev, RTW89_DBG_TXRX, "rx_data: ", + skb->data, rx_info->len); + /* length of a single segment skb is desc_info->pkt_size */ + if (fs && ls) { + copy_len = desc_info->pkt_size; + } else { + rtw89_info(rtwdev, "drop rx data due to invalid length\n"); + return false; + } + } + + skb_put_data(new, skb->data + offset, copy_len); + + return true; +} + +static u32 rtw89_pci_get_rx_skb_idx(struct rtw89_dev *rtwdev, + struct rtw89_pci_dma_ring *bd_ring) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 wp = bd_ring->wp; + + if (!info->rx_ring_eq_is_full) + return wp; + + if (++wp >= bd_ring->len) + wp = 0; + + return wp; +} + +static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring) +{ + struct rtw89_rx_desc_info *desc_info = &rx_ring->diliver_desc; + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct sk_buff *new = rx_ring->diliver_skb; + struct rtw89_pci_rx_info *rx_info; + struct sk_buff *skb; + u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); + u32 skb_idx; + u32 offset; + u32 cnt = 1; + bool fs, ls; + int ret; + + skb_idx = rtw89_pci_get_rx_skb_idx(rtwdev, bd_ring); + skb = rx_ring->buf[skb_idx]; + + ret = rtw89_pci_sync_skb_for_device_and_validate_rx_info(rtwdev, rx_ring, skb); + if (ret) { + rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", + bd_ring->wp, ret); + goto err_sync_device; + } + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + fs = info->no_rxbd_fs ? !new : rx_info->fs; + ls = rx_info->ls; + + if (unlikely(!fs || !ls)) + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "unexpected fs/ls=%d/%d tag=%u len=%u new->len=%u\n", + fs, ls, rx_info->tag, rx_info->len, new ? new->len : 0); + + if (fs) { + if (new) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "skb should not be ready before first segment start\n"); + goto err_sync_device; + } + if (desc_info->ready) { + rtw89_warn(rtwdev, "desc info should not be ready before first segment start\n"); + goto err_sync_device; + } + + rtw89_chip_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); + + new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size); + if (!new) + goto err_sync_device; + + rx_ring->diliver_skb = new; + + /* first segment has RX desc */ + offset = desc_info->offset + desc_info->rxd_len; + } else { + offset = sizeof(struct rtw89_pci_rxbd_info); + if (!new) { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "no last skb\n"); + goto err_sync_device; + } + } + if (!rtw89_skb_put_rx_data(rtwdev, fs, ls, new, skb, offset, rx_info, desc_info)) + goto err_sync_device; + rtw89_pci_sync_skb_for_device(rtwdev, skb); + rtw89_pci_rxbd_increase(rx_ring, 1); + + if (!desc_info->ready) { + rtw89_warn(rtwdev, "no rx desc information\n"); + goto err_free_resource; + } + if (ls) { + rtw89_core_rx(rtwdev, desc_info, new); + rx_ring->diliver_skb = NULL; + desc_info->ready = false; + } + + return cnt; + +err_sync_device: + rtw89_pci_sync_skb_for_device(rtwdev, skb); + rtw89_pci_rxbd_increase(rx_ring, 1); +err_free_resource: + if (new) + dev_kfree_skb_any(new); + rx_ring->diliver_skb = NULL; + desc_info->ready = false; + + return cnt; +} + +static void rtw89_pci_rxbd_deliver(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring, + u32 cnt) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + u32 rx_cnt; + + while (cnt && rtwdev->napi_budget_countdown > 0) { + rx_cnt = rtw89_pci_rxbd_deliver_skbs(rtwdev, rx_ring); + if (!rx_cnt) { + rtw89_err(rtwdev, "failed to deliver RXBD skb\n"); + + /* skip the rest RXBD bufs */ + rtw89_pci_rxbd_increase(rx_ring, cnt); + break; + } + + cnt -= rx_cnt; + } + + rtw89_write16(rtwdev, bd_ring->addr.idx, bd_ring->wp); +} + +static int rtw89_pci_poll_rxq_dma(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, int budget) +{ + struct rtw89_pci_rx_ring *rx_ring; + int countdown = rtwdev->napi_budget_countdown; + u32 cnt; + + rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RXQ]; + + cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); + if (!cnt) + return 0; + + cnt = min_t(u32, budget, cnt); + + rtw89_pci_rxbd_deliver(rtwdev, rx_ring, cnt); + + /* In case of flushing pending SKBs, the countdown may exceed. */ + if (rtwdev->napi_budget_countdown <= 0) + return budget; + + return budget - countdown; +} + +static void rtw89_pci_tx_status(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring, + struct sk_buff *skb, u8 tx_status) +{ + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); + struct ieee80211_tx_info *info; + + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) + return; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + if (tx_status == RTW89_TX_DONE) { + info->flags |= IEEE80211_TX_STAT_ACK; + tx_ring->tx_acked++; + } else { + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) + rtw89_debug(rtwdev, RTW89_DBG_FW, + "failed to TX of status %x\n", tx_status); + switch (tx_status) { + case RTW89_TX_RETRY_LIMIT: + tx_ring->tx_retry_lmt++; + break; + case RTW89_TX_LIFE_TIME: + tx_ring->tx_life_time++; + break; + case RTW89_TX_MACID_DROP: + tx_ring->tx_mac_id_drop++; + break; + default: + rtw89_warn(rtwdev, "invalid TX status %x\n", tx_status); + break; + } + } + + ieee80211_tx_status_ni(rtwdev->hw, skb); +} + +static void rtw89_pci_reclaim_txbd(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_tx_wd *txwd; + u32 cnt; + + cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); + while (cnt--) { + txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); + if (!txwd) { + rtw89_warn(rtwdev, "No busy txwd pages available\n"); + break; + } + + list_del_init(&txwd->list); + + /* this skb has been freed by RPP */ + if (skb_queue_len(&txwd->queue) == 0) + rtw89_pci_enqueue_txwd(tx_ring, txwd); + } +} + +static void rtw89_pci_release_busy_txwd(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + struct rtw89_pci_tx_wd *txwd; + int i; + + for (i = 0; i < wd_ring->page_num; i++) { + txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); + if (!txwd) + break; + + list_del_init(&txwd->list); + } +} + +static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring, + struct rtw89_pci_tx_wd *txwd, u16 seq, + u8 tx_status) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_data *tx_data; + struct sk_buff *skb, *tmp; + u8 txch = tx_ring->txch; + + if (!list_empty(&txwd->list)) { + rtw89_pci_reclaim_txbd(rtwdev, tx_ring); + /* In low power mode, RPP can receive before updating of TX BD. + * In normal mode, it should not happen so give it a warning. + */ + if (!rtwpci->low_power && !list_empty(&txwd->list)) + rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", + txch, seq); + } + + skb_queue_walk_safe(&txwd->queue, skb, tmp) { + skb_unlink(skb, &txwd->queue); + + tx_data = RTW89_PCI_TX_SKB_CB(skb); + dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, + DMA_TO_DEVICE); + + rtw89_pci_tx_status(rtwdev, tx_ring, skb, tx_status); + } + + if (list_empty(&txwd->list)) + rtw89_pci_enqueue_txwd(tx_ring, txwd); +} + +void rtw89_pci_parse_rpp(struct rtw89_dev *rtwdev, void *_rpp, + struct rtw89_pci_rpp_info *rpp_info) +{ + const struct rtw89_pci_rpp_fmt *rpp = _rpp; + + rpp_info->seq = le32_get_bits(rpp->dword, RTW89_PCI_RPP_SEQ); + rpp_info->qsel = le32_get_bits(rpp->dword, RTW89_PCI_RPP_QSEL); + rpp_info->tx_status = le32_get_bits(rpp->dword, RTW89_PCI_RPP_TX_STATUS); + rpp_info->txch = rtw89_chip_get_ch_dma(rtwdev, rpp_info->qsel); +} +EXPORT_SYMBOL(rtw89_pci_parse_rpp); + +void rtw89_pci_parse_rpp_v1(struct rtw89_dev *rtwdev, void *_rpp, + struct rtw89_pci_rpp_info *rpp_info) +{ + const struct rtw89_pci_rpp_fmt_v1 *rpp = _rpp; + + rpp_info->seq = le32_get_bits(rpp->w0, RTW89_PCI_RPP_W0_PCIE_SEQ_V1_MASK); + rpp_info->qsel = le32_get_bits(rpp->w1, RTW89_PCI_RPP_W1_QSEL_V1_MASK); + rpp_info->tx_status = le32_get_bits(rpp->w0, RTW89_PCI_RPP_W0_TX_STATUS_V1_MASK); + rpp_info->txch = le32_get_bits(rpp->w0, RTW89_PCI_RPP_W0_DMA_CH_MASK); +} +EXPORT_SYMBOL(rtw89_pci_parse_rpp_v1); + +static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, void *rpp) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct rtw89_pci_rpp_info rpp_info = {}; + struct rtw89_pci_tx_wd_ring *wd_ring; + struct rtw89_pci_tx_ring *tx_ring; + struct rtw89_pci_tx_wd *txwd; + + info->parse_rpp(rtwdev, rpp, &rpp_info); + + if (unlikely(rpp_info.txch >= RTW89_TXCH_NUM || + info->tx_dma_ch_mask & BIT(rpp_info.txch))) { + rtw89_warn(rtwdev, "should no release report on txch %d\n", + rpp_info.txch); + return; + } + + if (unlikely(rpp_info.seq >= RTW89_PCI_TXWD_NUM_MAX)) { + rtw89_warn(rtwdev, "invalid seq %d\n", rpp_info.seq); + return; + } + + tx_ring = &rtwpci->tx.rings[rpp_info.txch]; + wd_ring = &tx_ring->wd_ring; + txwd = &wd_ring->pages[rpp_info.seq]; + + rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, rpp_info.seq, + rpp_info.tx_status); +} + +static void rtw89_pci_release_pending_txwd_skb(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + struct rtw89_pci_tx_wd *txwd; + int i; + + for (i = 0; i < wd_ring->page_num; i++) { + txwd = &wd_ring->pages[i]; + + if (!list_empty(&txwd->list)) + continue; + + rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, i, RTW89_TX_MACID_DROP); + } +} + +static u32 rtw89_pci_release_tx_skbs(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring, + u32 max_cnt) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct rtw89_rx_desc_info desc_info = {}; + struct rtw89_pci_rx_info *rx_info; + struct sk_buff *skb; + void *rpp; + u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); + u32 rpp_size = info->rpp_fmt_size; + u32 cnt = 0; + u32 skb_idx; + u32 offset; + int ret; + + skb_idx = rtw89_pci_get_rx_skb_idx(rtwdev, bd_ring); + skb = rx_ring->buf[skb_idx]; + + ret = rtw89_pci_sync_skb_for_device_and_validate_rx_info(rtwdev, rx_ring, skb); + if (ret) { + rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", + bd_ring->wp, ret); + goto err_sync_device; + } + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + if (!rx_info->fs || !rx_info->ls) { + rtw89_err(rtwdev, "cannot process RP frame not set FS/LS\n"); + return cnt; + } + + rtw89_chip_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size); + + /* first segment has RX desc */ + offset = desc_info.offset + desc_info.rxd_len; + for (; offset + rpp_size <= rx_info->len; offset += rpp_size) { + rpp = skb->data + offset; + rtw89_pci_release_rpp(rtwdev, rpp); + } + + rtw89_pci_sync_skb_for_device(rtwdev, skb); + rtw89_pci_rxbd_increase(rx_ring, 1); + cnt++; + + return cnt; + +err_sync_device: + rtw89_pci_sync_skb_for_device(rtwdev, skb); + return 0; +} + +static void rtw89_pci_release_tx(struct rtw89_dev *rtwdev, + struct rtw89_pci_rx_ring *rx_ring, + u32 cnt) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + u32 release_cnt; + + while (cnt) { + release_cnt = rtw89_pci_release_tx_skbs(rtwdev, rx_ring, cnt); + if (!release_cnt) { + rtw89_err(rtwdev, "failed to release TX skbs\n"); + + /* skip the rest RXBD bufs */ + rtw89_pci_rxbd_increase(rx_ring, cnt); + break; + } + + cnt -= release_cnt; + } + + rtw89_write16(rtwdev, bd_ring->addr.idx, bd_ring->wp); +} + +static int rtw89_pci_poll_rpq_dma(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, int budget) +{ + struct rtw89_pci_rx_ring *rx_ring; + u32 cnt; + int work_done; + + rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RPQ]; + + spin_lock_bh(&rtwpci->trx_lock); + + cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); + if (cnt == 0) + goto out_unlock; + + rtw89_pci_release_tx(rtwdev, rx_ring, cnt); + +out_unlock: + spin_unlock_bh(&rtwpci->trx_lock); + + /* always release all RPQ */ + work_done = min_t(int, cnt, budget); + rtwdev->napi_budget_countdown -= work_done; + + return work_done; +} + +static void rtw89_pci_isr_rxd_unavail(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci) +{ + struct rtw89_pci_rx_ring *rx_ring; + struct rtw89_pci_dma_ring *bd_ring; + u32 reg_idx; + u16 hw_idx, hw_idx_next, host_idx; + int i; + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx.rings[i]; + bd_ring = &rx_ring->bd_ring; + + reg_idx = rtw89_read32(rtwdev, bd_ring->addr.idx); + hw_idx = FIELD_GET(TXBD_HW_IDX_MASK, reg_idx); + host_idx = FIELD_GET(TXBD_HOST_IDX_MASK, reg_idx); + hw_idx_next = (hw_idx + 1) % bd_ring->len; + + if (hw_idx_next == host_idx) + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "%d RXD unavailable\n", i); + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "%d RXD unavailable, idx=0x%08x, len=%d\n", + i, reg_idx, bd_ring->len); + } +} + +void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + isrs->halt_c2h_isrs = rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs; + isrs->isrs[0] = rtw89_read32(rtwdev, R_AX_PCIE_HISR00) & rtwpci->intrs[0]; + isrs->isrs[1] = rtw89_read32(rtwdev, R_AX_PCIE_HISR10) & rtwpci->intrs[1]; + + rtw89_write32(rtwdev, R_AX_HISR0, isrs->halt_c2h_isrs); + rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isrs->isrs[0]); + rtw89_write32(rtwdev, R_AX_PCIE_HISR10, isrs->isrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_recognize_intrs); + +void rtw89_pci_recognize_intrs_v1(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + isrs->ind_isrs = rtw89_read32(rtwdev, R_AX_PCIE_HISR00_V1) & rtwpci->ind_intrs; + isrs->halt_c2h_isrs = isrs->ind_isrs & B_AX_HS0ISR_IND_INT_EN ? + rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs : 0; + isrs->isrs[0] = isrs->ind_isrs & B_AX_HCI_AXIDMA_INT_EN ? + rtw89_read32(rtwdev, R_AX_HAXI_HISR00) & rtwpci->intrs[0] : 0; + isrs->isrs[1] = isrs->ind_isrs & B_AX_HS1ISR_IND_INT_EN ? + rtw89_read32(rtwdev, R_AX_HISR1) & rtwpci->intrs[1] : 0; + + if (isrs->halt_c2h_isrs) + rtw89_write32(rtwdev, R_AX_HISR0, isrs->halt_c2h_isrs); + if (isrs->isrs[0]) + rtw89_write32(rtwdev, R_AX_HAXI_HISR00, isrs->isrs[0]); + if (isrs->isrs[1]) + rtw89_write32(rtwdev, R_AX_HISR1, isrs->isrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_recognize_intrs_v1); + +void rtw89_pci_recognize_intrs_v2(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + isrs->ind_isrs = rtw89_read32(rtwdev, R_BE_PCIE_HISR) & rtwpci->ind_intrs; + isrs->halt_c2h_isrs = isrs->ind_isrs & B_BE_HS0ISR_IND_INT ? + rtw89_read32(rtwdev, R_BE_HISR0) & rtwpci->halt_c2h_intrs : 0; + isrs->isrs[0] = isrs->ind_isrs & B_BE_HCI_AXIDMA_INT ? + rtw89_read32(rtwdev, R_BE_HAXI_HISR00) & rtwpci->intrs[0] : 0; + isrs->isrs[1] = rtw89_read32(rtwdev, R_BE_PCIE_DMA_ISR) & rtwpci->intrs[1]; + + if (isrs->halt_c2h_isrs) + rtw89_write32(rtwdev, R_BE_HISR0, isrs->halt_c2h_isrs); + if (isrs->isrs[0]) + rtw89_write32(rtwdev, R_BE_HAXI_HISR00, isrs->isrs[0]); + if (isrs->isrs[1]) + rtw89_write32(rtwdev, R_BE_PCIE_DMA_ISR, isrs->isrs[1]); + rtw89_write32(rtwdev, R_BE_PCIE_HISR, isrs->ind_isrs); +} +EXPORT_SYMBOL(rtw89_pci_recognize_intrs_v2); + +void rtw89_pci_recognize_intrs_v3(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + isrs->ind_isrs = rtw89_read32(rtwdev, R_BE_PCIE_HISR) & rtwpci->ind_intrs; + isrs->halt_c2h_isrs = isrs->ind_isrs & B_BE_HS0ISR_IND_INT ? + rtw89_read32(rtwdev, R_BE_HISR0) & rtwpci->halt_c2h_intrs : 0; + isrs->isrs[1] = rtw89_read32(rtwdev, R_BE_PCIE_DMA_ISR) & rtwpci->intrs[1]; + + /* isrs[0] is not used, so borrow to store RDU status to share common + * flow in rtw89_pci_interrupt_threadfn(). + */ + isrs->isrs[0] = isrs->isrs[1] & (B_BE_PCIE_RDU_CH1_INT | + B_BE_PCIE_RDU_CH0_INT); + + if (isrs->halt_c2h_isrs) + rtw89_write32(rtwdev, R_BE_HISR0, isrs->halt_c2h_isrs); + if (isrs->isrs[1]) + rtw89_write32(rtwdev, R_BE_PCIE_DMA_ISR, isrs->isrs[1]); + rtw89_write32(rtwdev, R_BE_PCIE_HISR, isrs->ind_isrs); +} +EXPORT_SYMBOL(rtw89_pci_recognize_intrs_v3); + +void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, rtwpci->intrs[0]); + rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, rtwpci->intrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_enable_intr); + +void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_HIMR0, 0); + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); + rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); +} +EXPORT_SYMBOL(rtw89_pci_disable_intr); + +void rtw89_pci_enable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00_V1, rtwpci->ind_intrs); + rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); + rtw89_write32(rtwdev, R_AX_HAXI_HIMR00, rtwpci->intrs[0]); + rtw89_write32(rtwdev, R_AX_HIMR1, rtwpci->intrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_enable_intr_v1); + +void rtw89_pci_disable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00_V1, 0); +} +EXPORT_SYMBOL(rtw89_pci_disable_intr_v1); + +void rtw89_pci_enable_intr_v2(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_BE_HIMR0, rtwpci->halt_c2h_intrs); + rtw89_write32(rtwdev, R_BE_HAXI_HIMR00, rtwpci->intrs[0]); + rtw89_write32(rtwdev, R_BE_PCIE_DMA_IMR_0_V1, rtwpci->intrs[1]); + rtw89_write32(rtwdev, R_BE_PCIE_HIMR0, rtwpci->ind_intrs); +} +EXPORT_SYMBOL(rtw89_pci_enable_intr_v2); + +void rtw89_pci_disable_intr_v2(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_BE_PCIE_HIMR0, 0); + rtw89_write32(rtwdev, R_BE_PCIE_DMA_IMR_0_V1, 0); +} +EXPORT_SYMBOL(rtw89_pci_disable_intr_v2); + +void rtw89_pci_enable_intr_v3(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_BE_HIMR0, rtwpci->halt_c2h_intrs); + rtw89_write32(rtwdev, R_BE_PCIE_DMA_IMR_0_V1, rtwpci->intrs[1]); + rtw89_write32(rtwdev, R_BE_PCIE_HIMR0, rtwpci->ind_intrs); +} +EXPORT_SYMBOL(rtw89_pci_enable_intr_v3); + +void rtw89_pci_disable_intr_v3(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_BE_PCIE_HIMR0, 0); + rtw89_write32(rtwdev, R_BE_PCIE_DMA_IMR_0_V1, 0); +} +EXPORT_SYMBOL(rtw89_pci_disable_intr_v3); + +static void rtw89_pci_ops_recovery_start(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtw89_chip_disable_intr(rtwdev, rtwpci); + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RECOVERY_START); + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static void rtw89_pci_ops_recovery_complete(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtw89_chip_disable_intr(rtwdev, rtwpci); + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE); + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static void rtw89_pci_low_power_interrupt_handler(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + int budget = NAPI_POLL_WEIGHT; + + /* To prevent RXQ get stuck due to run out of budget. */ + rtwdev->napi_budget_countdown = budget; + + rtw89_pci_poll_rpq_dma(rtwdev, rtwpci, budget); + rtw89_pci_poll_rxq_dma(rtwdev, rtwpci, budget); +} + +static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) +{ + struct rtw89_dev *rtwdev = dev; + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_isr_def *isr_def = info->isr_def; + struct rtw89_pci_isrs isrs; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtw89_chip_recognize_intrs(rtwdev, rtwpci, &isrs); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + + if (unlikely(isrs.isrs[0] & isr_def->isr_rdu)) + rtw89_pci_isr_rxd_unavail(rtwdev, rtwpci); + + if (unlikely(isrs.halt_c2h_isrs & isr_def->isr_halt_c2h)) + rtw89_ser_notify(rtwdev, rtw89_mac_get_err_status(rtwdev)); + + if (unlikely(isrs.halt_c2h_isrs & isr_def->isr_wdt_timeout)) + rtw89_ser_notify(rtwdev, MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT); + + if (unlikely(isrs.halt_c2h_isrs & isr_def->isr_sps_ocp)) + rtw89_warn(rtwdev, "SPS OCP alarm 0x%x\n", isrs.halt_c2h_isrs); + + if (unlikely(rtwpci->under_recovery)) + goto enable_intr; + + if (unlikely(rtwpci->low_power)) { + rtw89_pci_low_power_interrupt_handler(rtwdev); + goto enable_intr; + } + + if (likely(rtwpci->running)) { + local_bh_disable(); + napi_schedule(&rtwdev->napi); + local_bh_enable(); + } + + return IRQ_HANDLED; + +enable_intr: + spin_lock_irqsave(&rtwpci->irq_lock, flags); + if (likely(rtwpci->running)) + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + return IRQ_HANDLED; +} + +static irqreturn_t rtw89_pci_interrupt_handler(int irq, void *dev) +{ + struct rtw89_dev *rtwdev = dev; + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + irqreturn_t irqret = IRQ_WAKE_THREAD; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + + /* If interrupt event is on the road, it is still trigger interrupt + * even we have done pci_stop() to turn off IMR. + */ + if (unlikely(!rtwpci->running)) { + irqret = IRQ_HANDLED; + goto exit; + } + + rtw89_chip_disable_intr(rtwdev, rtwpci); +exit: + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + + return irqret; +} + +#define DEF_TXCHADDRS_TYPE3(gen, ch_idx, txch, v...) \ + [RTW89_TXCH_##ch_idx] = { \ + .num = R_##gen##_##txch##_TXBD_CFG, \ + .idx = R_##gen##_##txch##_TXBD_IDX ##v, \ + .bdram = 0, \ + .desa_l = 0, \ + .desa_h = 0, \ + } + +#define DEF_TXCHADDRS_TYPE3_GRP_BASE(gen, ch_idx, txch, grp, v...) \ + [RTW89_TXCH_##ch_idx] = { \ + .num = R_##gen##_##txch##_TXBD_CFG, \ + .idx = R_##gen##_##txch##_TXBD_IDX ##v, \ + .bdram = 0, \ + .desa_l = R_##gen##_##grp##_TXBD_DESA_L, \ + .desa_h = R_##gen##_##grp##_TXBD_DESA_H, \ + } + +#define DEF_TXCHADDRS_TYPE2(gen, ch_idx, txch, v...) \ + [RTW89_TXCH_##ch_idx] = { \ + .num = R_##gen##_##txch##_TXBD_NUM ##v, \ + .idx = R_##gen##_##txch##_TXBD_IDX ##v, \ + .bdram = 0, \ + .desa_l = R_##gen##_##txch##_TXBD_DESA_L ##v, \ + .desa_h = R_##gen##_##txch##_TXBD_DESA_H ##v, \ + } + +#define DEF_TXCHADDRS_TYPE1(info, txch, v...) \ + [RTW89_TXCH_##txch] = { \ + .num = R_AX_##txch##_TXBD_NUM ##v, \ + .idx = R_AX_##txch##_TXBD_IDX ##v, \ + .bdram = R_AX_##txch##_BDRAM_CTRL ##v, \ + .desa_l = R_AX_##txch##_TXBD_DESA_L ##v, \ + .desa_h = R_AX_##txch##_TXBD_DESA_H ##v, \ + } + +#define DEF_TXCHADDRS(info, txch, v...) \ + [RTW89_TXCH_##txch] = { \ + .num = R_AX_##txch##_TXBD_NUM, \ + .idx = R_AX_##txch##_TXBD_IDX, \ + .bdram = R_AX_##txch##_BDRAM_CTRL ##v, \ + .desa_l = R_AX_##txch##_TXBD_DESA_L ##v, \ + .desa_h = R_AX_##txch##_TXBD_DESA_H ##v, \ + } + +#define DEF_RXCHADDRS_TYPE3(gen, ch_idx, rxch, v...) \ + [RTW89_RXCH_##ch_idx] = { \ + .num = R_##gen##_RX_##rxch##_RXBD_CONFIG, \ + .idx = R_##gen##_##ch_idx##0_RXBD_IDX ##v, \ + .desa_l = 0, \ + .desa_h = 0, \ + } + +#define DEF_RXCHADDRS_TYPE3_GRP_BASE(gen, ch_idx, rxch, grp, v...) \ + [RTW89_RXCH_##ch_idx] = { \ + .num = R_##gen##_RX_##rxch##_RXBD_CONFIG, \ + .idx = R_##gen##_##ch_idx##0_RXBD_IDX ##v, \ + .desa_l = R_##gen##_##grp##_RXBD_DESA_L, \ + .desa_h = R_##gen##_##grp##_RXBD_DESA_H, \ + } + +#define DEF_RXCHADDRS(gen, ch_idx, rxch, v...) \ + [RTW89_RXCH_##ch_idx] = { \ + .num = R_##gen##_##rxch##_RXBD_NUM ##v, \ + .idx = R_##gen##_##rxch##_RXBD_IDX ##v, \ + .desa_l = R_##gen##_##rxch##_RXBD_DESA_L ##v, \ + .desa_h = R_##gen##_##rxch##_RXBD_DESA_H ##v, \ + } + +const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set = { + .tx = { + DEF_TXCHADDRS(info, ACH0), + DEF_TXCHADDRS(info, ACH1), + DEF_TXCHADDRS(info, ACH2), + DEF_TXCHADDRS(info, ACH3), + DEF_TXCHADDRS(info, ACH4), + DEF_TXCHADDRS(info, ACH5), + DEF_TXCHADDRS(info, ACH6), + DEF_TXCHADDRS(info, ACH7), + DEF_TXCHADDRS(info, CH8), + DEF_TXCHADDRS(info, CH9), + DEF_TXCHADDRS_TYPE1(info, CH10), + DEF_TXCHADDRS_TYPE1(info, CH11), + DEF_TXCHADDRS(info, CH12), + }, + .rx = { + DEF_RXCHADDRS(AX, RXQ, RXQ), + DEF_RXCHADDRS(AX, RPQ, RPQ), + }, +}; +EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set); + +const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1 = { + .tx = { + DEF_TXCHADDRS(info, ACH0, _V1), + DEF_TXCHADDRS(info, ACH1, _V1), + DEF_TXCHADDRS(info, ACH2, _V1), + DEF_TXCHADDRS(info, ACH3, _V1), + DEF_TXCHADDRS(info, ACH4, _V1), + DEF_TXCHADDRS(info, ACH5, _V1), + DEF_TXCHADDRS(info, ACH6, _V1), + DEF_TXCHADDRS(info, ACH7, _V1), + DEF_TXCHADDRS(info, CH8, _V1), + DEF_TXCHADDRS(info, CH9, _V1), + DEF_TXCHADDRS_TYPE1(info, CH10, _V1), + DEF_TXCHADDRS_TYPE1(info, CH11, _V1), + DEF_TXCHADDRS(info, CH12, _V1), + }, + .rx = { + DEF_RXCHADDRS(AX, RXQ, RXQ, _V1), + DEF_RXCHADDRS(AX, RPQ, RPQ, _V1), + }, +}; +EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_v1); + +const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be = { + .tx = { + DEF_TXCHADDRS_TYPE2(BE, ACH0, CH0, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH1, CH1, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH2, CH2, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH3, CH3, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH4, CH4, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH5, CH5, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH6, CH6, _V1), + DEF_TXCHADDRS_TYPE2(BE, ACH7, CH7, _V1), + DEF_TXCHADDRS_TYPE2(BE, CH8, CH8, _V1), + DEF_TXCHADDRS_TYPE2(BE, CH9, CH9, _V1), + DEF_TXCHADDRS_TYPE2(BE, CH10, CH10, _V1), + DEF_TXCHADDRS_TYPE2(BE, CH11, CH11, _V1), + DEF_TXCHADDRS_TYPE2(BE, CH12, CH12, _V1), + }, + .rx = { + DEF_RXCHADDRS(BE, RXQ, RXQ0, _V1), + DEF_RXCHADDRS(BE, RPQ, RPQ0, _V1), + }, +}; +EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_be); + +const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be_v1 = { + .tx = { + DEF_TXCHADDRS_TYPE3_GRP_BASE(BE, ACH0, CH0, ACQ, _V1), + /* no CH1 */ + DEF_TXCHADDRS_TYPE3(BE, ACH2, CH2, _V1), + /* no CH3 */ + DEF_TXCHADDRS_TYPE3(BE, ACH4, CH4, _V1), + /* no CH5 */ + DEF_TXCHADDRS_TYPE3(BE, ACH6, CH6, _V1), + /* no CH7 */ + DEF_TXCHADDRS_TYPE3_GRP_BASE(BE, CH8, CH8, NACQ, _V1), + /* no CH9 */ + DEF_TXCHADDRS_TYPE3(BE, CH10, CH10, _V1), + /* no CH11 */ + DEF_TXCHADDRS_TYPE3(BE, CH12, CH12, _V1), + }, + .rx = { + DEF_RXCHADDRS_TYPE3_GRP_BASE(BE, RXQ, CH0, HOST0, _V1), + DEF_RXCHADDRS_TYPE3(BE, RPQ, CH1, _V1), + }, +}; +EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_be_v1); + +#undef DEF_TXCHADDRS_TYPE3 +#undef DEF_TXCHADDRS_TYPE3_GRP_BASE +#undef DEF_TXCHADDRS_TYPE2 +#undef DEF_TXCHADDRS_TYPE1 +#undef DEF_TXCHADDRS +#undef DEF_RXCHADDRS_TYPE3 +#undef DEF_RXCHADDRS_TYPE3_GRP_BASE +#undef DEF_RXCHADDRS + +static int rtw89_pci_get_txch_addrs(struct rtw89_dev *rtwdev, + enum rtw89_tx_channel txch, + const struct rtw89_pci_ch_dma_addr **addr) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + if (txch >= RTW89_TXCH_NUM) + return -EINVAL; + + *addr = &info->dma_addr_set->tx[txch]; + + return 0; +} + +static int rtw89_pci_get_rxch_addrs(struct rtw89_dev *rtwdev, + enum rtw89_rx_channel rxch, + const struct rtw89_pci_ch_dma_addr **addr) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + if (rxch >= RTW89_RXCH_NUM) + return -EINVAL; + + *addr = &info->dma_addr_set->rx[rxch]; + + return 0; +} + +static u32 rtw89_pci_get_avail_txbd_num(struct rtw89_pci_tx_ring *ring) +{ + struct rtw89_pci_dma_ring *bd_ring = &ring->bd_ring; + + /* reserved 1 desc check ring is full or not */ + if (bd_ring->rp > bd_ring->wp) + return bd_ring->rp - bd_ring->wp - 1; + + return bd_ring->len - (bd_ring->wp - bd_ring->rp) - 1; +} + +static +u32 __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[RTW89_TXCH_CH12]; + u32 cnt; + + spin_lock_bh(&rtwpci->trx_lock); + rtw89_pci_reclaim_tx_fwcmd(rtwdev, rtwpci); + cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + spin_unlock_bh(&rtwpci->trx_lock); + + return cnt; +} + +static +u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev, + u8 txch) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[txch]; + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + u32 cnt; + + spin_lock_bh(&rtwpci->trx_lock); + cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + if (txch != RTW89_TXCH_CH12) + cnt = min(cnt, wd_ring->curr_num); + spin_unlock_bh(&rtwpci->trx_lock); + + return cnt; +} + +static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, + u8 txch) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[txch]; + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 bd_cnt, wd_cnt, min_cnt = 0; + struct rtw89_pci_rx_ring *rx_ring; + enum rtw89_debug_mask debug_mask; + u32 cnt; + + rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RPQ]; + + spin_lock_bh(&rtwpci->trx_lock); + bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + wd_cnt = wd_ring->curr_num; + + if (wd_cnt == 0 || bd_cnt == 0) { + cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); + if (cnt) + rtw89_pci_release_tx(rtwdev, rx_ring, cnt); + else if (wd_cnt == 0) + goto out_unlock; + + bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + if (bd_cnt == 0) + rtw89_pci_reclaim_txbd(rtwdev, tx_ring); + } + + bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + wd_cnt = wd_ring->curr_num; + min_cnt = min(bd_cnt, wd_cnt); + if (min_cnt == 0) { + /* This message can be frequently shown in low power mode or + * high traffic with small FIFO chips, and we have recognized it as normal + * behavior, so print with mask RTW89_DBG_TXRX in these situations. + */ + if (rtwpci->low_power || chip->small_fifo_size) + debug_mask = RTW89_DBG_TXRX; + else + debug_mask = RTW89_DBG_UNEXP; + + rtw89_debug(rtwdev, debug_mask, + "still no tx resource after reclaim: wd_cnt=%d bd_cnt=%d\n", + wd_cnt, bd_cnt); + } + +out_unlock: + spin_unlock_bh(&rtwpci->trx_lock); + + return min_cnt; +} + +static u32 rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, + u8 txch) +{ + if (rtwdev->hci.paused) + return __rtw89_pci_check_and_reclaim_tx_resource_noio(rtwdev, txch); + + if (txch == RTW89_TXCH_CH12) + return __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(rtwdev); + + return __rtw89_pci_check_and_reclaim_tx_resource(rtwdev, txch); +} + +static void __rtw89_pci_tx_kick_off(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; + u32 host_idx, addr; + + spin_lock_bh(&rtwpci->trx_lock); + + addr = bd_ring->addr.idx; + host_idx = bd_ring->wp; + rtw89_write16(rtwdev, addr, host_idx); + + spin_unlock_bh(&rtwpci->trx_lock); +} + +static void rtw89_pci_tx_bd_ring_update(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring, + int n_txbd) +{ + struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; + u32 host_idx, len; + + len = bd_ring->len; + host_idx = bd_ring->wp + n_txbd; + host_idx = host_idx < len ? host_idx : host_idx - len; + + bd_ring->wp = host_idx; +} + +static void rtw89_pci_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[txch]; + + if (rtwdev->hci.paused) { + set_bit(txch, rtwpci->kick_map); + return; + } + + __rtw89_pci_tx_kick_off(rtwdev, tx_ring); +} + +static void rtw89_pci_tx_kick_off_pending(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring; + int txch; + + for (txch = 0; txch < RTW89_TXCH_NUM; txch++) { + if (!test_and_clear_bit(txch, rtwpci->kick_map)) + continue; + + tx_ring = &rtwpci->tx.rings[txch]; + __rtw89_pci_tx_kick_off(rtwdev, tx_ring); + } +} + +static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx.rings[txch]; + struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; + u32 cur_idx, cur_rp; + u8 i; + + /* Because the time taked by the I/O is a bit dynamic, it's hard to + * define a reasonable fixed total timeout to use read_poll_timeout* + * helper. Instead, we can ensure a reasonable polling times, so we + * just use for loop with udelay here. + */ + for (i = 0; i < 60; i++) { + cur_idx = rtw89_read32(rtwdev, bd_ring->addr.idx); + cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); + if (cur_rp == bd_ring->wp) + return; + + udelay(1); + } + + if (!drop) + rtw89_info(rtwdev, "timed out to flush pci txch: %d\n", txch); +} + +static void __rtw89_pci_ops_flush_txchs(struct rtw89_dev *rtwdev, u32 txchs, + bool drop) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u8 i; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + /* It may be unnecessary to flush FWCMD queue. */ + if (i == RTW89_TXCH_CH12) + continue; + if (info->tx_dma_ch_mask & BIT(i)) + continue; + + if (txchs & BIT(i)) + __pci_flush_txch(rtwdev, i, drop); + } +} + +static void rtw89_pci_ops_flush_queues(struct rtw89_dev *rtwdev, u32 queues, + bool drop) +{ + __rtw89_pci_ops_flush_txchs(rtwdev, BIT(RTW89_TXCH_NUM) - 1, drop); +} + +u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + struct rtw89_pci_tx_addr_info_32 *txaddr_info = txaddr_info_addr; + __le16 option; + + txaddr_info->length = cpu_to_le16(total_len); + option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | RTW89_PCI_ADDR_NUM(1)); + option |= le16_encode_bits(upper_32_bits(dma), RTW89_PCI_ADDR_HIGH_MASK); + txaddr_info->option = option; + txaddr_info->dma = cpu_to_le32(dma); + + *add_info_nr = 1; + + return sizeof(*txaddr_info); +} +EXPORT_SYMBOL(rtw89_pci_fill_txaddr_info); + +u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + struct rtw89_pci_tx_addr_info_32_v1 *txaddr_info = txaddr_info_addr; + u32 remain = total_len; + u32 len; + u16 length_option; + int n; + + for (n = 0; n < RTW89_TXADDR_INFO_NR_V1 && remain; n++) { + len = remain >= TXADDR_INFO_LENTHG_V1_MAX ? + TXADDR_INFO_LENTHG_V1_MAX : remain; + remain -= len; + + length_option = FIELD_PREP(B_PCIADDR_LEN_V1_MASK, len) | + FIELD_PREP(B_PCIADDR_HIGH_SEL_V1_MASK, 0) | + FIELD_PREP(B_PCIADDR_LS_V1_MASK, remain == 0); + length_option |= u16_encode_bits(upper_32_bits(dma), + B_PCIADDR_HIGH_SEL_V1_MASK); + txaddr_info->length_opt = cpu_to_le16(length_option); + txaddr_info->dma_low_lsb = cpu_to_le16(FIELD_GET(GENMASK(15, 0), dma)); + txaddr_info->dma_low_msb = cpu_to_le16(FIELD_GET(GENMASK(31, 16), dma)); + + dma += len; + txaddr_info++; + } + + WARN_ONCE(remain, "length overflow remain=%u total_len=%u", + remain, total_len); + + *add_info_nr = n; + + return n * sizeof(*txaddr_info); +} +EXPORT_SYMBOL(rtw89_pci_fill_txaddr_info_v1); + +static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring, + struct rtw89_pci_tx_wd *txwd, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_pci_tx_wp_info *txwp_info; + void *txaddr_info_addr; + struct pci_dev *pdev = rtwpci->pdev; + struct sk_buff *skb = tx_req->skb; + struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); + bool en_wd_info = desc_info->en_wd_info; + u32 txwd_len; + u32 txwp_len; + u32 txaddr_info_len; + dma_addr_t dma; + int ret; + + dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&pdev->dev, dma)) { + rtw89_err(rtwdev, "failed to map skb dma data\n"); + ret = -EBUSY; + goto err; + } + + tx_data->dma = dma; + + txwp_len = sizeof(*txwp_info); + txwd_len = chip->txwd_body_size; + txwd_len += en_wd_info ? chip->txwd_info_size : 0; + + txwp_info = txwd->vaddr + txwd_len; + txwp_info->seq0 = cpu_to_le16(txwd->seq | RTW89_PCI_TXWP_VALID); + txwp_info->seq1 = 0; + txwp_info->seq2 = 0; + txwp_info->seq3 = 0; + + tx_ring->tx_cnt++; + txaddr_info_addr = txwd->vaddr + txwd_len + txwp_len; + txaddr_info_len = + rtw89_chip_fill_txaddr_info(rtwdev, txaddr_info_addr, skb->len, + dma, &desc_info->addr_info_nr); + + txwd->len = txwd_len + txwp_len + txaddr_info_len; + + rtw89_chip_fill_txdesc(rtwdev, desc_info, txwd->vaddr); + + skb_queue_tail(&txwd->queue, skb); + + return 0; + +err: + return ret; +} + +static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring, + struct rtw89_pci_tx_bd_32 *txbd, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + void *txdesc; + int txdesc_size = chip->h2c_desc_size; + struct pci_dev *pdev = rtwpci->pdev; + struct sk_buff *skb = tx_req->skb; + struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); + dma_addr_t dma; + __le16 opt; + + txdesc = skb_push(skb, txdesc_size); + memset(txdesc, 0, txdesc_size); + rtw89_chip_fill_txdesc_fwcmd(rtwdev, desc_info, txdesc); + + dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&pdev->dev, dma)) { + rtw89_err(rtwdev, "failed to map fwcmd dma data\n"); + return -EBUSY; + } + + tx_data->dma = dma; + opt = cpu_to_le16(RTW89_PCI_TXBD_OPT_LS); + opt |= le16_encode_bits(upper_32_bits(dma), RTW89_PCI_TXBD_OPT_DMA_HI); + txbd->opt = opt; + txbd->length = cpu_to_le16(skb->len); + txbd->dma = cpu_to_le32(tx_data->dma); + skb_queue_tail(&rtwpci->h2c_queue, skb); + + rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); + + return 0; +} + +static int rtw89_pci_txbd_submit(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring, + struct rtw89_pci_tx_bd_32 *txbd, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_pci_tx_wd *txwd; + __le16 opt; + int ret; + + /* FWCMD queue doesn't have wd pages. Instead, it submits the CMD + * buffer with WD BODY only. So here we don't need to check the free + * pages of the wd ring. + */ + if (tx_ring->txch == RTW89_TXCH_CH12) + return rtw89_pci_fwcmd_submit(rtwdev, tx_ring, txbd, tx_req); + + txwd = rtw89_pci_dequeue_txwd(tx_ring); + if (!txwd) { + rtw89_err(rtwdev, "no available TXWD\n"); + ret = -ENOSPC; + goto err; + } + + ret = rtw89_pci_txwd_submit(rtwdev, tx_ring, txwd, tx_req); + if (ret) { + rtw89_err(rtwdev, "failed to submit TXWD %d\n", txwd->seq); + goto err_enqueue_wd; + } + + list_add_tail(&txwd->list, &tx_ring->busy_pages); + + opt = cpu_to_le16(RTW89_PCI_TXBD_OPT_LS); + opt |= le16_encode_bits(upper_32_bits(txwd->paddr), RTW89_PCI_TXBD_OPT_DMA_HI); + txbd->opt = opt; + txbd->length = cpu_to_le16(txwd->len); + txbd->dma = cpu_to_le32(txwd->paddr); + + rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); + + return 0; + +err_enqueue_wd: + rtw89_pci_enqueue_txwd(tx_ring, txwd); +err: + return ret; +} + +static int rtw89_pci_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req, + u8 txch) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring; + struct rtw89_pci_tx_bd_32 *txbd; + u32 n_avail_txbd; + int ret = 0; + + /* check the tx type and dma channel for fw cmd queue */ + if ((txch == RTW89_TXCH_CH12 || + tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD) && + (txch != RTW89_TXCH_CH12 || + tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD)) { + rtw89_err(rtwdev, "only fw cmd uses dma channel 12\n"); + return -EINVAL; + } + + tx_ring = &rtwpci->tx.rings[txch]; + spin_lock_bh(&rtwpci->trx_lock); + + n_avail_txbd = rtw89_pci_get_avail_txbd_num(tx_ring); + if (n_avail_txbd == 0) { + rtw89_err(rtwdev, "no available TXBD\n"); + ret = -ENOSPC; + goto err_unlock; + } + + txbd = rtw89_pci_get_next_txbd(tx_ring); + ret = rtw89_pci_txbd_submit(rtwdev, tx_ring, txbd, tx_req); + if (ret) { + rtw89_err(rtwdev, "failed to submit TXBD\n"); + goto err_unlock; + } + + spin_unlock_bh(&rtwpci->trx_lock); + return 0; + +err_unlock: + spin_unlock_bh(&rtwpci->trx_lock); + return ret; +} + +static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + int ret; + + ret = rtw89_pci_tx_write(rtwdev, tx_req, desc_info->ch_dma); + if (ret) { + rtw89_err(rtwdev, "failed to TX Queue %d\n", desc_info->ch_dma); + return ret; + } + + return 0; +} + +const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM] = { + [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH4] = {.start_idx = 20, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH5] = {.start_idx = 25, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH6] = {.start_idx = 30, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH7] = {.start_idx = 35, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_CH8] = {.start_idx = 40, .max_num = 5, .min_num = 1}, + [RTW89_TXCH_CH9] = {.start_idx = 45, .max_num = 5, .min_num = 1}, + [RTW89_TXCH_CH10] = {.start_idx = 50, .max_num = 5, .min_num = 1}, + [RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1}, + [RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1}, +}; +EXPORT_SYMBOL(rtw89_bd_ram_table_dual); + +const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM] = { + [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2}, + [RTW89_TXCH_CH8] = {.start_idx = 20, .max_num = 4, .min_num = 1}, + [RTW89_TXCH_CH9] = {.start_idx = 24, .max_num = 4, .min_num = 1}, + [RTW89_TXCH_CH12] = {.start_idx = 28, .max_num = 4, .min_num = 1}, +}; +EXPORT_SYMBOL(rtw89_bd_ram_table_single); + +static void rtw89_pci_init_wp_16sel(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 addr = info->wp_sel_addr; + u32 val; + int i; + + if (!info->wp_sel_addr) + return; + + for (i = 0; i < 16; i += 4) { + val = u32_encode_bits(i + 0, MASKBYTE0) | + u32_encode_bits(i + 1, MASKBYTE1) | + u32_encode_bits(i + 2, MASKBYTE2) | + u32_encode_bits(i + 3, MASKBYTE3); + rtw89_write32(rtwdev, addr + i, val); + } +} + +static u16 rtw89_pci_enc_bd_cfg(struct rtw89_dev *rtwdev, u16 bd_num, + u32 dma_offset) +{ + u16 dma_offset_sel; + u16 num_sel; + + /* B_BE_TX_NUM_SEL_MASK, B_BE_RX_NUM_SEL_MASK: + * 0 -> 0 + * 1 -> 64 = 2^6 + * 2 -> 128 = 2^7 + * ... + * 7 -> 4096 = 2^12 + */ + num_sel = ilog2(bd_num) - 5; + + if (hweight16(bd_num) != 1) + rtw89_warn(rtwdev, "bd_num %u is not power of 2\n", bd_num); + + /* B_BE_TX_START_OFFSET_MASK, B_BE_RX_START_OFFSET_MASK: + * 0 -> 0 = 0 * 2^9 + * 1 -> 512 = 1 * 2^9 + * 2 -> 1024 = 2 * 2^9 + * 3 -> 1536 = 3 * 2^9 + * ... + * 255 -> 130560 = 255 * 2^9 + */ + dma_offset_sel = dma_offset >> 9; + + if (dma_offset % 512) + rtw89_warn(rtwdev, "offset %u is not multiple of 512\n", dma_offset); + + return u16_encode_bits(num_sel, B_BE_TX_NUM_SEL_MASK) | + u16_encode_bits(dma_offset_sel, B_BE_TX_START_OFFSET_MASK); +} + +static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_bd_ram *bd_ram_table = *info->bd_ram_table; + struct rtw89_pci_tx_ring *tx_ring; + struct rtw89_pci_rx_ring *rx_ring; + struct rtw89_pci_dma_ring *bd_ring; + const struct rtw89_pci_bd_ram *bd_ram; + dma_addr_t group_dma_base = 0; + u16 num_or_offset; + u32 addr_desa_l; + u32 addr_bdram; + u32 addr_num; + u32 addr_idx; + u32 val32; + int i; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + if (info->tx_dma_ch_mask & BIT(i)) + continue; + + tx_ring = &rtwpci->tx.rings[i]; + bd_ring = &tx_ring->bd_ring; + bd_ram = bd_ram_table ? &bd_ram_table[i] : NULL; + addr_num = bd_ring->addr.num; + addr_bdram = bd_ring->addr.bdram; + addr_desa_l = bd_ring->addr.desa_l; + bd_ring->wp = 0; + bd_ring->rp = 0; + + if (info->group_bd_addr) { + if (addr_desa_l) + group_dma_base = bd_ring->dma; + + num_or_offset = + rtw89_pci_enc_bd_cfg(rtwdev, bd_ring->len, + bd_ring->dma - group_dma_base); + } else { + num_or_offset = bd_ring->len; + } + rtw89_write16(rtwdev, addr_num, num_or_offset); + + if (addr_bdram && bd_ram) { + val32 = FIELD_PREP(BDRAM_SIDX_MASK, bd_ram->start_idx) | + FIELD_PREP(BDRAM_MAX_MASK, bd_ram->max_num) | + FIELD_PREP(BDRAM_MIN_MASK, bd_ram->min_num); + + rtw89_write32(rtwdev, addr_bdram, val32); + } + if (addr_desa_l) { + rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); + rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma)); + } + } + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx.rings[i]; + bd_ring = &rx_ring->bd_ring; + addr_num = bd_ring->addr.num; + addr_idx = bd_ring->addr.idx; + addr_desa_l = bd_ring->addr.desa_l; + if (info->rx_ring_eq_is_full) + bd_ring->wp = bd_ring->len - 1; + else + bd_ring->wp = 0; + bd_ring->rp = 0; + rx_ring->diliver_skb = NULL; + rx_ring->diliver_desc.ready = false; + rx_ring->target_rx_tag = 0; + + if (info->group_bd_addr) { + if (addr_desa_l) + group_dma_base = bd_ring->dma; + + num_or_offset = + rtw89_pci_enc_bd_cfg(rtwdev, bd_ring->len, + bd_ring->dma - group_dma_base); + } else { + num_or_offset = bd_ring->len; + } + rtw89_write16(rtwdev, addr_num, num_or_offset); + + if (addr_desa_l) { + rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); + rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma)); + } + + if (info->rx_ring_eq_is_full) + rtw89_write16(rtwdev, addr_idx, bd_ring->wp); + } + + rtw89_pci_init_wp_16sel(rtwdev); +} + +static void rtw89_pci_release_tx_ring(struct rtw89_dev *rtwdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + rtw89_pci_release_busy_txwd(rtwdev, tx_ring); + rtw89_pci_release_pending_txwd_skb(rtwdev, tx_ring); +} + +void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + int txch; + + rtw89_pci_reset_trx_rings(rtwdev); + + spin_lock_bh(&rtwpci->trx_lock); + for (txch = 0; txch < RTW89_TXCH_NUM; txch++) { + if (info->tx_dma_ch_mask & BIT(txch)) + continue; + if (txch == RTW89_TXCH_CH12) { + rtw89_pci_release_fwcmd(rtwdev, rtwpci, + skb_queue_len(&rtwpci->h2c_queue), true); + continue; + } + rtw89_pci_release_tx_ring(rtwdev, &rtwpci->tx.rings[txch]); + } + spin_unlock_bh(&rtwpci->trx_lock); +} + +static void rtw89_pci_enable_intr_lock(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtwpci->running = true; + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static void rtw89_pci_disable_intr_lock(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtwpci->running = false; + rtw89_chip_disable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static int rtw89_pci_ops_start(struct rtw89_dev *rtwdev) +{ + rtw89_core_napi_start(rtwdev); + rtw89_pci_enable_intr_lock(rtwdev); + + return 0; +} + +static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + rtw89_pci_disable_intr_lock(rtwdev); + synchronize_irq(pdev->irq); + rtw89_core_napi_stop(rtwdev); +} + +static void rtw89_pci_ops_pause(struct rtw89_dev *rtwdev, bool pause) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + if (pause) { + rtw89_pci_disable_intr_lock(rtwdev); + synchronize_irq(pdev->irq); + if (test_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) + napi_synchronize(&rtwdev->napi); + } else { + rtw89_pci_enable_intr_lock(rtwdev); + rtw89_pci_tx_kick_off_pending(rtwdev); + } +} + +static +void rtw89_pci_switch_bd_idx_addr(struct rtw89_dev *rtwdev, bool low_power) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_bd_idx_addr *bd_idx_addr = info->bd_idx_addr_low_power; + const struct rtw89_pci_ch_dma_addr_set *dma_addr_set = info->dma_addr_set; + struct rtw89_pci_tx_ring *tx_ring; + struct rtw89_pci_rx_ring *rx_ring; + int i; + + if (WARN(!bd_idx_addr, "only HCI with low power mode needs this\n")) + return; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + tx_ring = &rtwpci->tx.rings[i]; + tx_ring->bd_ring.addr.idx = low_power ? + bd_idx_addr->tx_bd_addrs[i] : + dma_addr_set->tx[i].idx; + } + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx.rings[i]; + rx_ring->bd_ring.addr.idx = low_power ? + bd_idx_addr->rx_bd_addrs[i] : + dma_addr_set->rx[i].idx; + } +} + +static void rtw89_pci_ops_switch_mode(struct rtw89_dev *rtwdev, bool low_power) +{ + enum rtw89_pci_intr_mask_cfg cfg; + + WARN(!rtwdev->hci.paused, "HCI isn't paused\n"); + + cfg = low_power ? RTW89_PCI_INTR_MASK_LOW_POWER : RTW89_PCI_INTR_MASK_NORMAL; + rtw89_chip_config_intr_mask(rtwdev, cfg); + rtw89_pci_switch_bd_idx_addr(rtwdev, low_power); +} + +static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data); + +static u32 rtw89_pci_ops_read32_cmac(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + u32 val = readl(rtwpci->mmap + addr); + int count; + + for (count = 0; ; count++) { + if (val != RTW89_R32_DEAD) + return val; + if (count >= MAC_REG_POOL_COUNT) { + rtw89_warn(rtwdev, "addr %#x = %#x\n", addr, val); + return RTW89_R32_DEAD; + } + rtw89_pci_ops_write32(rtwdev, R_AX_CK_EN, B_AX_CMAC_ALLCKEN); + val = readl(rtwpci->mmap + addr); + } + + return val; +} + +static u8 rtw89_pci_ops_read8(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + u32 addr32, val32, shift; + + if (!ACCESS_CMAC(addr)) + return readb(rtwpci->mmap + addr); + + addr32 = addr & ~0x3; + shift = (addr & 0x3) * 8; + val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); + return val32 >> shift; +} + +static u16 rtw89_pci_ops_read16(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + u32 addr32, val32, shift; + + if (!ACCESS_CMAC(addr)) + return readw(rtwpci->mmap + addr); + + addr32 = addr & ~0x3; + shift = (addr & 0x3) * 8; + val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); + return val32 >> shift; +} + +static u32 rtw89_pci_ops_read32(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (!ACCESS_CMAC(addr)) + return readl(rtwpci->mmap + addr); + + return rtw89_pci_ops_read32_cmac(rtwdev, addr); +} + +static void rtw89_pci_ops_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + writeb(data, rtwpci->mmap + addr); +} + +static void rtw89_pci_ops_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + writew(data, rtwpci->mmap + addr); +} + +static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + writel(data, rtwpci->mmap + addr); +} + +static u32 rtw89_pci_ops_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u32 value; + int ret; + + ret = pci_read_config_dword(pdev, addr, &value); + if (ret) + return RTW89_R32_EA; + + return value; +} + +static void rtw89_pci_ctrl_dma_trx(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + if (enable) + rtw89_write32_set(rtwdev, info->init_cfg_reg, + info->rxhci_en_bit | info->txhci_en_bit); + else + rtw89_write32_clr(rtwdev, info->init_cfg_reg, + info->rxhci_en_bit | info->txhci_en_bit); +} + +static void rtw89_pci_ctrl_dma_io(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_reg_def *reg = &info->dma_io_stop; + + if (enable) + rtw89_write32_clr(rtwdev, reg->addr, reg->mask); + else + rtw89_write32_set(rtwdev, reg->addr, reg->mask); +} + +void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable) +{ + rtw89_pci_ctrl_dma_io(rtwdev, enable); + rtw89_pci_ctrl_dma_trx(rtwdev, enable); +} + +static int rtw89_pci_check_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 rw_bit) +{ + u16 val; + + rtw89_write8(rtwdev, R_AX_MDIO_CFG, addr & 0x1F); + + val = rtw89_read16(rtwdev, R_AX_MDIO_CFG); + switch (speed) { + case PCIE_PHY_GEN1: + if (addr < 0x20) + val = u16_replace_bits(val, MDIO_PG0_G1, B_AX_MDIO_PHY_ADDR_MASK); + else + val = u16_replace_bits(val, MDIO_PG1_G1, B_AX_MDIO_PHY_ADDR_MASK); + break; + case PCIE_PHY_GEN2: + if (addr < 0x20) + val = u16_replace_bits(val, MDIO_PG0_G2, B_AX_MDIO_PHY_ADDR_MASK); + else + val = u16_replace_bits(val, MDIO_PG1_G2, B_AX_MDIO_PHY_ADDR_MASK); + break; + default: + rtw89_err(rtwdev, "[ERR]Error Speed %d!\n", speed); + return -EINVAL; + } + rtw89_write16(rtwdev, R_AX_MDIO_CFG, val); + rtw89_write16_set(rtwdev, R_AX_MDIO_CFG, rw_bit); + + return read_poll_timeout(rtw89_read16, val, !(val & rw_bit), 10, 2000, + false, rtwdev, R_AX_MDIO_CFG); +} + +static int +rtw89_read16_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 *val) +{ + int ret; + + ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_RFLAG); + if (ret) { + rtw89_err(rtwdev, "[ERR]MDIO R16 0x%X fail ret=%d!\n", addr, ret); + return ret; + } + *val = rtw89_read16(rtwdev, R_AX_MDIO_RDATA); + + return 0; +} + +static int +rtw89_write16_mdio(struct rtw89_dev *rtwdev, u8 addr, u16 data, u8 speed) +{ + int ret; + + rtw89_write16(rtwdev, R_AX_MDIO_WDATA, data); + ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_WFLAG); + if (ret) { + rtw89_err(rtwdev, "[ERR]MDIO W16 0x%X = %x fail ret=%d!\n", addr, data, ret); + return ret; + } + + return 0; +} + +static int +rtw89_write16_mdio_mask(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u16 data, u8 speed) +{ + u32 shift; + int ret; + u16 val; + + ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); + if (ret) + return ret; + + shift = __ffs(mask); + val &= ~mask; + val |= ((data << shift) & mask); + + ret = rtw89_write16_mdio(rtwdev, addr, val, speed); + if (ret) + return ret; + + return 0; +} + +static int rtw89_write16_mdio_set(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) +{ + int ret; + u16 val; + + ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); + if (ret) + return ret; + ret = rtw89_write16_mdio(rtwdev, addr, val | mask, speed); + if (ret) + return ret; + + return 0; +} + +static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) +{ + int ret; + u16 val; + + ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); + if (ret) + return ret; + ret = rtw89_write16_mdio(rtwdev, addr, val & ~mask, speed); + if (ret) + return ret; + + return 0; +} + +static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data) +{ + u16 addr_2lsb = addr & B_AX_DBI_2LSB; + u16 write_addr; + u8 flag; + int ret; + + write_addr = addr & B_AX_DBI_ADDR_MSK; + write_addr |= u16_encode_bits(BIT(addr_2lsb), B_AX_DBI_WREN_MSK); + rtw89_write8(rtwdev, R_AX_DBI_WDATA + addr_2lsb, data); + rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr); + rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16); + + ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, + 10 * RTW89_PCI_WR_RETRY_CNT, false, + rtwdev, R_AX_DBI_FLAG + 2); + if (ret) + rtw89_err(rtwdev, "failed to write DBI register, addr=0x%X\n", + addr); + + return ret; +} + +static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value) +{ + u16 read_addr = addr & B_AX_DBI_ADDR_MSK; + u8 flag; + int ret; + + rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr); + rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16); + + ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, + 10 * RTW89_PCI_WR_RETRY_CNT, false, + rtwdev, R_AX_DBI_FLAG + 2); + if (ret) { + rtw89_err(rtwdev, "failed to read DBI register, addr=0x%X\n", + addr); + return ret; + } + + read_addr = R_AX_DBI_RDATA + (addr & 3); + *value = rtw89_read8(rtwdev, read_addr); + + return 0; +} + +static int rtw89_pci_write_config_byte(struct rtw89_dev *rtwdev, u16 addr, + u8 data) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct pci_dev *pdev = rtwpci->pdev; + int ret; + + ret = pci_write_config_byte(pdev, addr, data); + if (!ret) + return 0; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + ret = rtw89_dbi_write8(rtwdev, addr, data); + + return ret; +} + +static int rtw89_pci_read_config_byte(struct rtw89_dev *rtwdev, u16 addr, + u8 *value) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct pci_dev *pdev = rtwpci->pdev; + int ret; + + ret = pci_read_config_byte(pdev, addr, value); + if (!ret) + return 0; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + ret = rtw89_dbi_read8(rtwdev, addr, value); + + return ret; +} + +static int rtw89_pci_config_byte_set(struct rtw89_dev *rtwdev, u16 addr, + u8 bit) +{ + u8 value; + int ret; + + ret = rtw89_pci_read_config_byte(rtwdev, addr, &value); + if (ret) + return ret; + + value |= bit; + ret = rtw89_pci_write_config_byte(rtwdev, addr, value); + + return ret; +} + +static int rtw89_pci_config_byte_clr(struct rtw89_dev *rtwdev, u16 addr, + u8 bit) +{ + u8 value; + int ret; + + ret = rtw89_pci_read_config_byte(rtwdev, addr, &value); + if (ret) + return ret; + + value &= ~bit; + ret = rtw89_pci_write_config_byte(rtwdev, addr, value); + + return ret; +} + +static int +__get_target(struct rtw89_dev *rtwdev, u16 *target, enum rtw89_pcie_phy phy_rate) +{ + u16 val, tar; + int ret; + + /* Enable counter */ + ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val); + if (ret) + return ret; + ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, + phy_rate); + if (ret) + return ret; + ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val | B_AX_CLK_CALIB_EN, + phy_rate); + if (ret) + return ret; + + fsleep(300); + + ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &tar); + if (ret) + return ret; + ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, + phy_rate); + if (ret) + return ret; + + tar = tar & 0x0FFF; + if (tar == 0 || tar == 0x0FFF) { + rtw89_err(rtwdev, "[ERR]Get target failed.\n"); + return -EINVAL; + } + + *target = tar; + + return 0; +} + +static int rtw89_pci_autok_x(struct rtw89_dev *rtwdev) +{ + int ret; + + if (!rtw89_is_rtl885xb(rtwdev)) + return 0; + + ret = rtw89_write16_mdio_mask(rtwdev, RAC_REG_FLD_0, BAC_AUTOK_N_MASK, + PCIE_AUTOK_4, PCIE_PHY_GEN1); + return ret; +} + +static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) +{ + enum rtw89_pcie_phy phy_rate; + u16 val16, mgn_set, div_set, tar; + u8 val8, bdr_ori; + bool l1_flag = false; + int ret = 0; + + if (!rtw89_is_rtl885xb(rtwdev)) + return 0; + + ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_PHY_RATE, &val8); + if (ret) { + rtw89_err(rtwdev, "[ERR]pci config read %X\n", + RTW89_PCIE_PHY_RATE); + return ret; + } + + if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x1) { + phy_rate = PCIE_PHY_GEN1; + } else if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x2) { + phy_rate = PCIE_PHY_GEN2; + } else { + rtw89_err(rtwdev, "[ERR]PCIe PHY rate %#x not support\n", val8); + return -EOPNOTSUPP; + } + /* Disable L1BD */ + ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_L1_CTRL, &bdr_ori); + if (ret) { + rtw89_err(rtwdev, "[ERR]pci config read %X\n", RTW89_PCIE_L1_CTRL); + return ret; + } + + if (bdr_ori & RTW89_PCIE_BIT_L1) { + ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_L1_CTRL, + bdr_ori & ~RTW89_PCIE_BIT_L1); + if (ret) { + rtw89_err(rtwdev, "[ERR]pci config write %X\n", + RTW89_PCIE_L1_CTRL); + return ret; + } + l1_flag = true; + } + + ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + + if (val16 & B_AX_CALIB_EN) { + ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, + val16 & ~B_AX_CALIB_EN, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + } + + if (!autook_en) + goto end; + /* Set div */ + ret = rtw89_write16_mdio_clr(rtwdev, RAC_CTRL_PPR_V1, B_AX_DIV, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + + /* Obtain div and margin */ + ret = __get_target(rtwdev, &tar, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]1st get target fail %d\n", ret); + goto end; + } + + mgn_set = tar * INTF_INTGRA_HOSTREF_V1 / INTF_INTGRA_MINREF_V1 - tar; + + if (mgn_set >= 128) { + div_set = 0x0003; + mgn_set = 0x000F; + } else if (mgn_set >= 64) { + div_set = 0x0003; + mgn_set >>= 3; + } else if (mgn_set >= 32) { + div_set = 0x0002; + mgn_set >>= 2; + } else if (mgn_set >= 16) { + div_set = 0x0001; + mgn_set >>= 1; + } else if (mgn_set == 0) { + rtw89_err(rtwdev, "[ERR]cal mgn is 0,tar = %d\n", tar); + goto end; + } else { + div_set = 0x0000; + } + + ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + + val16 |= u16_encode_bits(div_set, B_AX_DIV); + + ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val16, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + + ret = __get_target(rtwdev, &tar, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]2nd get target fail %d\n", ret); + goto end; + } + + rtw89_debug(rtwdev, RTW89_DBG_HCI, "[TRACE]target = 0x%X, div = 0x%X, margin = 0x%X\n", + tar, div_set, mgn_set); + ret = rtw89_write16_mdio(rtwdev, RAC_SET_PPR_V1, + (tar & 0x0FFF) | (mgn_set << 12), phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_SET_PPR_V1); + goto end; + } + + /* Enable function */ + ret = rtw89_write16_mdio_set(rtwdev, RAC_CTRL_PPR_V1, B_AX_CALIB_EN, phy_rate); + if (ret) { + rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); + goto end; + } + + /* CLK delay = 0 */ + ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_CLK_CTRL, + PCIE_CLKDLY_HW_0); + +end: + /* Set L1BD to ori */ + if (l1_flag) { + ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_L1_CTRL, + bdr_ori); + if (ret) { + rtw89_err(rtwdev, "[ERR]pci config write %X\n", + RTW89_PCIE_L1_CTRL); + return ret; + } + } + + return ret; +} + +static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + int ret; + + if (chip_id == RTL8852A) { + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, + PCIE_PHY_GEN1); + if (ret) + return ret; + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, + PCIE_PHY_GEN2); + if (ret) + return ret; + } else if (chip_id == RTL8852C) { + rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA24 * 2, + B_AX_DEGLITCH); + rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA24 * 2, + B_AX_DEGLITCH); + } + + return 0; +} + +static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev) +{ + u16 g1_oobs, g2_oobs; + u32 backup_aspm; + u32 phy_offset; + u16 offset_cal; + u16 oobs_val; + int ret; + u8 gen; + + if (rtwdev->chip->chip_id != RTL8852C) + return; + + g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G2 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + if (g1_oobs && g2_oobs) + return; + + backup_aspm = rtw89_read32(rtwdev, R_AX_PCIE_MIX_CFG_V1); + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, B_AX_ASPM_CTRL_MASK); + + ret = rtw89_pci_get_phy_offset_by_link_speed(rtwdev, &phy_offset); + if (ret) + goto out; + + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, BAC_RX_TEST_EN); + rtw89_write16(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, ADDR_SEL_PINOUT_DIS_VAL); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, B_PCIE_BIT_RD_SEL); + + oobs_val = rtw89_read16_mask(rtwdev, phy_offset + RAC_ANA1F * RAC_MULT, + OOBS_LEVEL_MASK); + + rtw89_write16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA03 * RAC_MULT, + OOBS_SEN_MASK, oobs_val); + rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA09 * RAC_MULT, + BAC_OOBS_SEL); + + rtw89_write16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA03 * RAC_MULT, + OOBS_SEN_MASK, oobs_val); + rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA09 * RAC_MULT, + BAC_OOBS_SEL); + + /* offset K */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 : + R_RAC_DIRECT_OFFSET_G2; + + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 + + RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 : + R_RAC_DIRECT_OFFSET_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT, + MANUAL_LVL_MASK, offset_cal); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + OFFSET_CAL_MODE); + } + +out: + rtw89_write32(rtwdev, R_AX_PCIE_MIX_CFG_V1, backup_aspm); +} + +static void rtw89_pci_ber(struct rtw89_dev *rtwdev) +{ + u32 phy_offset; + + if (!test_bit(RTW89_QUIRK_PCI_BER, rtwdev->quirks)) + return; + + phy_offset = R_RAC_DIRECT_OFFSET_G1; + rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G1_VAL); + rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL); + + phy_offset = R_RAC_DIRECT_OFFSET_G2; + rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G2_VAL); + rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL); +} + +static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852A) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_DIS_RXDMA_PRE); +} + +static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + if (chip_id != RTL8852A && !rtw89_is_rtl885xb(rtwdev)) + return; + + rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN); +} + +static u32 rtw89_pci_l2_rxen_lat(struct rtw89_dev *rtwdev) +{ + int ret; + + if (rtwdev->chip->chip_id != RTL8852A) + return 0; + + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, + PCIE_PHY_GEN1); + if (ret) + return ret; + + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, + PCIE_PHY_GEN2); + if (ret) + return ret; + + return 0; +} + +static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + if (chip_id != RTL8852A && !rtw89_is_rtl885xb(rtwdev)) + return; + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN); +} + +static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_WLSUS_AFT_PDN); + } else if (rtwdev->chip->chip_id == RTL8852C) { + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + } +} + +static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev) +{ + if (!rtw89_is_rtl885xb(rtwdev)) + return 0; + + return rtw89_write16_mdio_mask(rtwdev, RAC_REG_REV2, BAC_CMU_EN_DLY_MASK, + PCIE_DPHY_DLY_25US, PCIE_PHY_GEN1); +} + +static void rtw89_pci_power_wake_ax(struct rtw89_dev *rtwdev, bool pwr_up) +{ + if (pwr_up) + rtw89_write32_set(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL); + else + rtw89_write32_clr(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL); +} + +static void rtw89_pci_autoload_hang(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_BG_CLR, B_AX_BG_CLR_ASYNC_M3); + rtw89_write32_clr(rtwdev, R_AX_PCIE_BG_CLR, B_AX_BG_CLR_ASYNC_M3); +} + +static void rtw89_pci_l12_vmain(struct rtw89_dev *rtwdev) +{ + if (!(rtwdev->chip->chip_id == RTL8852C && rtwdev->hal.cv == CHIP_CAV)) + return; + + rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_FORCE_PWR_NGAT); +} + +static void rtw89_pci_gen2_force_ib(struct rtw89_dev *rtwdev) +{ + if (!(rtwdev->chip->chip_id == RTL8852C && rtwdev->hal.cv == CHIP_CAV)) + return; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, + B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_HCI_BG_CTRL, B_AX_BG_CLR_ASYNC_M3); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, + B_AX_SYSON_DIS_PMCR_AX_WRMSK); +} + +static void rtw89_pci_l1_ent_lat(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL_V1, B_AX_SEL_REQ_ENTR_L1); +} + +static void rtw89_pci_wd_exit_l1(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_PS_CTRL_V1, B_AX_DMAC0_EXIT_L1_EN); +} + +static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id == RTL8852C) + return; + + rtw89_write32_clr(rtwdev, R_AX_PCIE_EXP_CTRL, + B_AX_SIC_EN_FORCE_CLKREQ); +} + +static void rtw89_pci_set_lbc(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 lbc; + + if (rtwdev->chip->chip_id == RTL8852C) + return; + + lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); + if (info->lbc_en == MAC_AX_PCIE_ENABLE) { + lbc = u32_replace_bits(lbc, info->lbc_tmr, B_AX_LBC_TIMER); + lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; + rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); + } else { + lbc &= ~B_AX_LBC_EN; + } + rtw89_write32_set(rtwdev, R_AX_LBC_WATCHDOG, lbc); +} + +static void rtw89_pci_set_io_rcy(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 val32; + + if (rtwdev->chip->chip_id != RTL8852C) + return; + + if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) { + val32 = FIELD_PREP(B_AX_PCIE_WDT_TIMER_M1_MASK, + info->io_rcy_tmr); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_M1, val32); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_M2, val32); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_E0, val32); + + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_M1, B_AX_PCIE_IO_RCY_WDT_MODE_M1); + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_M2, B_AX_PCIE_IO_RCY_WDT_MODE_M2); + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_E0, B_AX_PCIE_IO_RCY_WDT_MODE_E0); + } else { + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_M1, B_AX_PCIE_IO_RCY_WDT_MODE_M1); + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_M2, B_AX_PCIE_IO_RCY_WDT_MODE_M2); + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_E0, B_AX_PCIE_IO_RCY_WDT_MODE_E0); + } + + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_S1, B_AX_PCIE_IO_RCY_WDT_MODE_S1); +} + +static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id == RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_DBG_CTRL, + B_AX_ASFF_FULL_NO_STK | B_AX_EN_STUCK_DBG); + + rtw89_write32_mask(rtwdev, R_AX_PCIE_EXP_CTRL, + B_AX_EN_STUCK_DBG | B_AX_ASFF_FULL_NO_STK, + B_AX_EN_STUCK_DBG); + + if (rtwdev->chip->chip_id == RTL8852A) + rtw89_write32_set(rtwdev, R_AX_PCIE_EXP_CTRL, + B_AX_EN_CHKDSC_NO_RX_STUCK); +} + +static void rtw89_pci_set_keep_reg(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id == RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); +} + +static void rtw89_pci_clr_idx_all_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val = B_AX_CLR_ACH0_IDX | B_AX_CLR_ACH1_IDX | B_AX_CLR_ACH2_IDX | + B_AX_CLR_ACH3_IDX | B_AX_CLR_CH8_IDX | B_AX_CLR_CH9_IDX | + B_AX_CLR_CH12_IDX; + u32 rxbd_rwptr_clr = info->rxbd_rwptr_clr_reg; + u32 txbd_rwptr_clr2 = info->txbd_rwptr_clr2_reg; + + if (chip_id == RTL8852A || chip_id == RTL8852C) + val |= B_AX_CLR_ACH4_IDX | B_AX_CLR_ACH5_IDX | + B_AX_CLR_ACH6_IDX | B_AX_CLR_ACH7_IDX; + /* clear DMA indexes */ + rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR1, val); + if (chip_id == RTL8852A || chip_id == RTL8852C) + rtw89_write32_set(rtwdev, txbd_rwptr_clr2, + B_AX_CLR_CH10_IDX | B_AX_CLR_CH11_IDX); + rtw89_write32_set(rtwdev, rxbd_rwptr_clr, + B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); +} + +static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 dma_busy1 = info->dma_busy1.addr; + u32 dma_busy2 = info->dma_busy2_reg; + u32 check, dma_busy; + int ret; + + check = info->dma_busy1.mask; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy1); + if (ret) + return ret; + + if (!dma_busy2) + return 0; + + check = B_AX_CH10_BUSY | B_AX_CH11_BUSY; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy2); + if (ret) + return ret; + + return 0; +} + +static int rtw89_pci_poll_rxdma_ch_idle_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 dma_busy3 = info->dma_busy3_reg; + u32 check, dma_busy; + int ret; + + check = B_AX_RXQ_BUSY | B_AX_RPQ_BUSY; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy3); + if (ret) + return ret; + + return 0; +} + +static int rtw89_pci_poll_dma_all_idle(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_pci_poll_txdma_ch_idle_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "txdma ch busy\n"); + return ret; + } + + ret = rtw89_pci_poll_rxdma_ch_idle_ax(rtwdev); + if (ret) { + rtw89_err(rtwdev, "rxdma ch busy\n"); + return ret; + } + + return 0; +} + +static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + enum mac_ax_bd_trunc_mode txbd_trunc_mode = info->txbd_trunc_mode; + enum mac_ax_bd_trunc_mode rxbd_trunc_mode = info->rxbd_trunc_mode; + enum mac_ax_rxbd_mode rxbd_mode = info->rxbd_mode; + enum mac_ax_tag_mode tag_mode = info->tag_mode; + enum mac_ax_wd_dma_intvl wd_dma_idle_intvl = info->wd_dma_idle_intvl; + enum mac_ax_wd_dma_intvl wd_dma_act_intvl = info->wd_dma_act_intvl; + enum mac_ax_tx_burst tx_burst = info->tx_burst; + enum mac_ax_rx_burst rx_burst = info->rx_burst; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u8 cv = rtwdev->hal.cv; + u32 val32; + + if (txbd_trunc_mode == MAC_AX_BD_TRUNC) { + if (chip_id == RTL8852A && cv == CHIP_CBV) + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE); + } else if (txbd_trunc_mode == MAC_AX_BD_NORM) { + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE); + } + + if (rxbd_trunc_mode == MAC_AX_BD_TRUNC) { + if (chip_id == RTL8852A && cv == CHIP_CBV) + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RX_TRUNC_MODE); + } else if (rxbd_trunc_mode == MAC_AX_BD_NORM) { + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RX_TRUNC_MODE); + } + + if (rxbd_mode == MAC_AX_RXBD_PKT) { + rtw89_write32_clr(rtwdev, info->init_cfg_reg, info->rxbd_mode_bit); + } else if (rxbd_mode == MAC_AX_RXBD_SEP) { + rtw89_write32_set(rtwdev, info->init_cfg_reg, info->rxbd_mode_bit); + + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, + B_AX_PCIE_RX_APPLEN_MASK, 0); + } + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, tx_burst); + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, rx_burst); + } else if (chip_id == RTL8852C) { + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_HAXI_MAX_TXDMA_MASK, tx_burst); + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_HAXI_MAX_RXDMA_MASK, rx_burst); + } + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + if (tag_mode == MAC_AX_TAG_SGL) { + val32 = rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) & + ~B_AX_LATENCY_CONTROL; + rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, val32); + } else if (tag_mode == MAC_AX_TAG_MULTI) { + val32 = rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) | + B_AX_LATENCY_CONTROL; + rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, val32); + } + } + + rtw89_write32_mask(rtwdev, info->exp_ctrl_reg, info->max_tag_num_mask, + info->multi_tag_num); + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE, + wd_dma_idle_intvl); + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT, + wd_dma_act_intvl); + } else if (chip_id == RTL8852C) { + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_WD_ITVL_IDLE_V1_MASK, + wd_dma_idle_intvl); + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_WD_ITVL_ACT_V1_MASK, + wd_dma_act_intvl); + } + + if (txbd_trunc_mode == MAC_AX_BD_TRUNC) { + rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } else if (txbd_trunc_mode == MAC_AX_BD_NORM) { + rtw89_write32_clr(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_set(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } + + return 0; +} + +static bool rtw89_pci_dev_ltr_enabled(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u16 cap; + + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &cap); + + return !!(cap & PCI_EXP_DEVCTL2_LTR_EN); +} + +static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + rtw89_pci_power_wake(rtwdev, false); + + if (rtwdev->chip->chip_id == RTL8852A) { + /* ltr sw trigger */ + rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE); + } + info->ltr_set(rtwdev, false); + rtw89_pci_ctrl_dma_all(rtwdev, false); + rtw89_pci_clr_idx_all(rtwdev); + + return 0; +} + +static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + int ret; + + rtw89_pci_ber(rtwdev); + rtw89_pci_rxdma_prefth(rtwdev); + rtw89_pci_l1off_pwroff(rtwdev); + rtw89_pci_deglitch_setting(rtwdev); + ret = rtw89_pci_l2_rxen_lat(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] pcie l2 rxen lat %d\n", ret); + return ret; + } + + rtw89_pci_aphy_pwrcut(rtwdev); + rtw89_pci_hci_ldo(rtwdev); + rtw89_pci_dphy_delay(rtwdev); + + ret = rtw89_pci_autok_x(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] pcie autok_x fail %d\n", ret); + return ret; + } + + ret = rtw89_pci_auto_refclk_cal(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "[ERR] pcie autok fail %d\n", ret); + return ret; + } + + rtw89_pci_power_wake_ax(rtwdev, true); + rtw89_pci_autoload_hang(rtwdev); + rtw89_pci_l12_vmain(rtwdev); + rtw89_pci_gen2_force_ib(rtwdev); + rtw89_pci_l1_ent_lat(rtwdev); + rtw89_pci_wd_exit_l1(rtwdev); + rtw89_pci_set_sic(rtwdev); + rtw89_pci_set_lbc(rtwdev); + rtw89_pci_set_io_rcy(rtwdev); + rtw89_pci_set_dbg(rtwdev); + rtw89_pci_set_keep_reg(rtwdev); + + rtw89_write32_set(rtwdev, info->dma_stop1.addr, B_AX_STOP_WPDMA); + + /* stop DMA activities */ + rtw89_pci_ctrl_dma_all(rtwdev, false); + + ret = rtw89_pci_poll_dma_all_idle(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n"); + return ret; + } + + rtw89_pci_clr_idx_all(rtwdev); + rtw89_pci_mode_op(rtwdev); + + /* fill TRX BD indexes */ + rtw89_pci_ops_reset(rtwdev); + + ret = rtw89_pci_rst_bdram_ax(rtwdev); + if (ret) { + rtw89_warn(rtwdev, "reset bdram busy\n"); + return ret; + } + + /* disable all channels except to FW CMD channel to download firmware */ + rtw89_pci_ctrl_txdma_ch_ax(rtwdev, false); + rtw89_pci_ctrl_txdma_fw_ch_ax(rtwdev, true); + + /* start DMA activities */ + rtw89_pci_ctrl_dma_all(rtwdev, true); + + return 0; +} + +static int rtw89_pci_ops_mac_pre_deinit_ax(struct rtw89_dev *rtwdev) +{ + rtw89_pci_power_wake_ax(rtwdev, false); + + return 0; +} + +int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en) +{ + u32 val; + + if (!en || !rtw89_pci_dev_ltr_enabled(rtwdev)) + return 0; + + val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); + if (rtw89_pci_ltr_is_err_reg_val(val)) + return -EINVAL; + val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_1); + if (rtw89_pci_ltr_is_err_reg_val(val)) + return -EINVAL; + val = rtw89_read32(rtwdev, R_AX_LTR_IDLE_LATENCY); + if (rtw89_pci_ltr_is_err_reg_val(val)) + return -EINVAL; + val = rtw89_read32(rtwdev, R_AX_LTR_ACTIVE_LATENCY); + if (rtw89_pci_ltr_is_err_reg_val(val)) + return -EINVAL; + + rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_HW_EN | B_AX_LTR_EN | + B_AX_LTR_WD_NOEMP_CHK); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_SPACE_IDX_MASK, + PCI_LTR_SPC_500US); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK, + PCI_LTR_IDLE_TIMER_3_2MS); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28); + rtw89_write32(rtwdev, R_AX_LTR_IDLE_LATENCY, 0x90039003); + rtw89_write32(rtwdev, R_AX_LTR_ACTIVE_LATENCY, 0x880b880b); + + return 0; +} +EXPORT_SYMBOL(rtw89_pci_ltr_set); + +int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en) +{ + u32 dec_ctrl; + u32 val32; + + if (!rtw89_pci_dev_ltr_enabled(rtwdev)) + return 0; + + val32 = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_CTRL_1); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + dec_ctrl = rtw89_read32(rtwdev, R_AX_LTR_DEC_CTRL); + if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_LATENCY_IDX3); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_LATENCY_IDX0); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + + if (!en) { + dec_ctrl &= ~(LTR_EN_BITS | B_AX_LTR_IDX_DRV_MASK | B_AX_LTR_HW_DEC_EN); + dec_ctrl |= FIELD_PREP(B_AX_LTR_IDX_DRV_MASK, PCIE_LTR_IDX_IDLE) | + B_AX_LTR_REQ_DRV; + } else { + dec_ctrl |= B_AX_LTR_HW_DEC_EN; + } + + dec_ctrl &= ~B_AX_LTR_SPACE_IDX_V1_MASK; + dec_ctrl |= FIELD_PREP(B_AX_LTR_SPACE_IDX_V1_MASK, PCI_LTR_SPC_500US); + + if (en) + rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, + B_AX_LTR_WD_NOEMP_CHK_V1 | B_AX_LTR_HW_EN); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK, + PCI_LTR_IDLE_TIMER_3_2MS); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28); + rtw89_write32(rtwdev, R_AX_LTR_DEC_CTRL, dec_ctrl); + rtw89_write32(rtwdev, R_AX_LTR_LATENCY_IDX3, 0x90039003); + rtw89_write32(rtwdev, R_AX_LTR_LATENCY_IDX0, 0x880b880b); + + return 0; +} +EXPORT_SYMBOL(rtw89_pci_ltr_set_v1); + +static int rtw89_pci_ops_mac_post_init_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + int ret; + + ret = info->ltr_set(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "pci ltr set fail\n"); + return ret; + } + if (chip_id == RTL8852A) { + /* ltr sw trigger */ + rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_ACT); + } + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + /* ADDR info 8-byte mode */ + rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } + + /* enable DMA for all queues */ + rtw89_pci_ctrl_txdma_ch_ax(rtwdev, true); + + /* Release PCI IO */ + rtw89_write32_clr(rtwdev, info->dma_stop1.addr, + B_AX_STOP_WPDMA | B_AX_STOP_PCIEIO); + + return 0; +} + +static int rtw89_pci_claim_device(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + int ret; + + ret = pci_enable_device(pdev); + if (ret) { + rtw89_err(rtwdev, "failed to enable pci device\n"); + return ret; + } + + pci_set_master(pdev); + pci_set_drvdata(pdev, rtwdev->hw); + + rtwpci->pdev = pdev; + + return 0; +} + +static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + pci_disable_device(pdev); +} + +static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + switch (chip->chip_id) { + case RTL8852A: + case RTL8852B: + case RTL8851B: + case RTL8852BT: + return true; + default: + return false; + } +} + +static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev); + + if (!rtw89_pci_chip_is_manual_dac(rtwdev)) + return true; + + if (!bridge) + return false; + + switch (bridge->vendor) { + case PCI_VENDOR_ID_INTEL: + return true; + case PCI_VENDOR_ID_ASMEDIA: + if (bridge->device == 0x2806) + return true; + break; + case PCI_VENDOR_ID_SPACEMIT: + if (bridge->device == PCI_DEVICE_ID_SPACEMIT_K3) + return true; + break; + } + + return false; +} + +static int rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev, bool force) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + int ret; + u8 val; + + if (!rtwpci->enable_dac && !force) + return 0; + + if (!rtw89_pci_chip_is_manual_dac(rtwdev)) + return 0; + + /* Configure DAC only via PCI config API, not DBI interfaces */ + ret = pci_read_config_byte(pdev, RTW89_PCIE_L1_CTRL, &val); + if (ret) + return ret; + + val |= RTW89_PCIE_BIT_EN_64BITS; + return pci_write_config_byte(pdev, RTW89_PCIE_L1_CTRL, val); +} + +static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long resource_len; + u8 bar_id = 2; + int ret; + + ret = pci_request_regions(pdev, KBUILD_MODNAME); + if (ret) { + rtw89_err(rtwdev, "failed to request pci regions\n"); + goto err; + } + + if (!rtw89_pci_is_dac_compatible_bridge(rtwdev)) + goto try_dac_done; + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); + if (!ret) { + ret = rtw89_pci_cfg_dac(rtwdev, true); + if (!ret) { + rtwpci->enable_dac = true; + goto try_dac_done; + } + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + rtw89_err(rtwdev, + "failed to set dma and consistent mask to 32/36-bit\n"); + goto err_release_regions; + } + } +try_dac_done: + + resource_len = pci_resource_len(pdev, bar_id); + rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len); + if (!rtwpci->mmap) { + rtw89_err(rtwdev, "failed to map pci io\n"); + ret = -EIO; + goto err_release_regions; + } + + return 0; + +err_release_regions: + pci_release_regions(pdev); +err: + return ret; +} + +static void rtw89_pci_clear_mapping(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (rtwpci->mmap) { + pci_iounmap(pdev, rtwpci->mmap); + pci_release_regions(pdev); + } +} + +static void rtw89_pci_free_tx_wd_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + u8 *head = wd_ring->head; + dma_addr_t dma = wd_ring->dma; + u32 page_size = wd_ring->page_size; + u32 page_num = wd_ring->page_num; + u32 ring_sz = page_size * page_num; + + dma_free_coherent(&pdev->dev, ring_sz, head, dma); + wd_ring->head = NULL; +} + +static void rtw89_pci_free_tx_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_tx_ring *tx_ring) +{ + tx_ring->bd_ring.head = NULL; +} + +static void rtw89_pci_free_tx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_dma_pool *bd_pool = &rtwpci->tx.bd_pool; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct rtw89_pci_tx_ring *tx_ring; + int i; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + if (info->tx_dma_ch_mask & BIT(i)) + continue; + tx_ring = &rtwpci->tx.rings[i]; + rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); + rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); + } + + dma_free_coherent(&pdev->dev, bd_pool->size, bd_pool->head, bd_pool->dma); +} + +static void rtw89_pci_free_rx_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_rx_ring *rx_ring) +{ + struct rtw89_pci_rx_info *rx_info; + struct sk_buff *skb; + dma_addr_t dma; + u32 buf_sz; + int i; + + buf_sz = rx_ring->buf_sz; + for (i = 0; i < rx_ring->bd_ring.len; i++) { + skb = rx_ring->buf[i]; + if (!skb) + continue; + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + dma = rx_info->dma; + dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb(skb); + rx_ring->buf[i] = NULL; + } + + rx_ring->bd_ring.head = NULL; +} + +static void rtw89_pci_free_rx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_dma_pool *bd_pool = &rtwpci->rx.bd_pool; + struct rtw89_pci_rx_ring *rx_ring; + int i; + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx.rings[i]; + rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); + } + + dma_free_coherent(&pdev->dev, bd_pool->size, bd_pool->head, bd_pool->dma); +} + +static void rtw89_pci_free_trx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + rtw89_pci_free_rx_rings(rtwdev, pdev); + rtw89_pci_free_tx_rings(rtwdev, pdev); +} + +static int rtw89_pci_init_rx_bd(struct rtw89_dev *rtwdev, struct pci_dev *pdev, + struct rtw89_pci_rx_ring *rx_ring, + struct sk_buff *skb, int buf_sz, u32 idx) +{ + struct rtw89_pci_rx_info *rx_info; + struct rtw89_pci_rx_bd_32 *rx_bd; + dma_addr_t dma; + + if (!skb) + return -EINVAL; + + dma = dma_map_single(&pdev->dev, skb->data, buf_sz, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, dma)) + return -EBUSY; + + rx_info = RTW89_PCI_RX_SKB_CB(skb); + rx_bd = RTW89_PCI_RX_BD(rx_ring, idx); + + memset(rx_bd, 0, sizeof(*rx_bd)); + rx_bd->buf_size = cpu_to_le16(buf_sz); + rx_bd->dma = cpu_to_le32(dma); + rx_bd->opt = le16_encode_bits(upper_32_bits(dma), RTW89_PCI_RXBD_OPT_DMA_HI); + rx_info->dma = dma; + + return 0; +} + +static int rtw89_pci_alloc_tx_wd_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_tx_ring *tx_ring, + enum rtw89_tx_channel txch) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + struct rtw89_pci_tx_wd *txwd; + dma_addr_t dma; + dma_addr_t cur_paddr; + u8 *head; + u8 *cur_vaddr; + u32 page_size = RTW89_PCI_TXWD_PAGE_SIZE; + u32 page_num = RTW89_PCI_TXWD_NUM_MAX; + u32 ring_sz = page_size * page_num; + u32 page_offset; + int i; + + /* FWCMD queue doesn't use txwd as pages */ + if (txch == RTW89_TXCH_CH12) + return 0; + + head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); + if (!head) + return -ENOMEM; + + INIT_LIST_HEAD(&wd_ring->free_pages); + wd_ring->head = head; + wd_ring->dma = dma; + wd_ring->page_size = page_size; + wd_ring->page_num = page_num; + + page_offset = 0; + for (i = 0; i < page_num; i++) { + txwd = &wd_ring->pages[i]; + cur_paddr = dma + page_offset; + cur_vaddr = head + page_offset; + + skb_queue_head_init(&txwd->queue); + INIT_LIST_HEAD(&txwd->list); + txwd->paddr = cur_paddr; + txwd->vaddr = cur_vaddr; + txwd->len = page_size; + txwd->seq = i; + rtw89_pci_enqueue_txwd(tx_ring, txwd); + + page_offset += page_size; + } + + return 0; +} + +static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_tx_ring *tx_ring, + u32 desc_size, u32 len, + enum rtw89_tx_channel txch, + void *head, dma_addr_t dma) +{ + const struct rtw89_pci_ch_dma_addr *txch_addr; + int ret; + + ret = rtw89_pci_alloc_tx_wd_ring(rtwdev, pdev, tx_ring, txch); + if (ret) { + rtw89_err(rtwdev, "failed to alloc txwd ring of txch %d\n", txch); + goto err; + } + + ret = rtw89_pci_get_txch_addrs(rtwdev, txch, &txch_addr); + if (ret) { + rtw89_err(rtwdev, "failed to get address of txch %d", txch); + goto err_free_wd_ring; + } + + INIT_LIST_HEAD(&tx_ring->busy_pages); + tx_ring->bd_ring.head = head; + tx_ring->bd_ring.dma = dma; + tx_ring->bd_ring.len = len; + tx_ring->bd_ring.desc_size = desc_size; + tx_ring->bd_ring.addr = *txch_addr; + tx_ring->bd_ring.wp = 0; + tx_ring->bd_ring.rp = 0; + tx_ring->txch = txch; + + return 0; + +err_free_wd_ring: + rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); +err: + return ret; +} + +static int rtw89_pci_alloc_tx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_dma_pool *bd_pool = &rtwpci->tx.bd_pool; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct rtw89_pci_tx_ring *tx_ring; + u32 i, tx_allocated; + dma_addr_t dma; + u32 desc_size; + u32 ring_sz; + u32 pool_sz; + u32 ch_num; + void *head; + u32 len; + int ret; + + BUILD_BUG_ON(RTW89_PCI_TXBD_NUM_MAX % 16); + + desc_size = sizeof(struct rtw89_pci_tx_bd_32); + len = RTW89_PCI_TXBD_NUM_MAX; + ch_num = RTW89_TXCH_NUM - hweight32(info->tx_dma_ch_mask); + ring_sz = desc_size * len; + pool_sz = ring_sz * ch_num; + + head = dma_alloc_coherent(&pdev->dev, pool_sz, &dma, GFP_KERNEL); + if (!head) + return -ENOMEM; + + bd_pool->head = head; + bd_pool->dma = dma; + bd_pool->size = pool_sz; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + if (info->tx_dma_ch_mask & BIT(i)) + continue; + tx_ring = &rtwpci->tx.rings[i]; + ret = rtw89_pci_alloc_tx_ring(rtwdev, pdev, tx_ring, + desc_size, len, i, head, dma); + if (ret) { + rtw89_err(rtwdev, "failed to alloc tx ring %d\n", i); + goto err_free; + } + + head += ring_sz; + dma += ring_sz; + } + + return 0; + +err_free: + tx_allocated = i; + for (i = 0; i < tx_allocated; i++) { + tx_ring = &rtwpci->tx.rings[i]; + rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); + } + + dma_free_coherent(&pdev->dev, bd_pool->size, bd_pool->head, bd_pool->dma); + + return ret; +} + +static int rtw89_pci_alloc_rx_ring(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + struct rtw89_pci_rx_ring *rx_ring, + u32 desc_size, u32 len, u32 rxch, + void *head, dma_addr_t dma) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_ch_dma_addr *rxch_addr; + struct sk_buff *skb; + int buf_sz = RTW89_PCI_RX_BUF_SIZE; + int i, allocated; + int ret; + + ret = rtw89_pci_get_rxch_addrs(rtwdev, rxch, &rxch_addr); + if (ret) { + rtw89_err(rtwdev, "failed to get address of rxch %d", rxch); + return ret; + } + + rx_ring->bd_ring.head = head; + rx_ring->bd_ring.dma = dma; + rx_ring->bd_ring.len = len; + rx_ring->bd_ring.desc_size = desc_size; + rx_ring->bd_ring.addr = *rxch_addr; + if (info->rx_ring_eq_is_full) + rx_ring->bd_ring.wp = len - 1; + else + rx_ring->bd_ring.wp = 0; + rx_ring->bd_ring.rp = 0; + rx_ring->buf_sz = buf_sz; + rx_ring->diliver_skb = NULL; + rx_ring->diliver_desc.ready = false; + rx_ring->target_rx_tag = 0; + + for (i = 0; i < len; i++) { + skb = dev_alloc_skb(buf_sz); + if (!skb) { + ret = -ENOMEM; + goto err_free; + } + + memset(skb->data, 0, buf_sz); + rx_ring->buf[i] = skb; + ret = rtw89_pci_init_rx_bd(rtwdev, pdev, rx_ring, skb, + buf_sz, i); + if (ret) { + rtw89_err(rtwdev, "failed to init rx buf %d\n", i); + dev_kfree_skb_any(skb); + rx_ring->buf[i] = NULL; + goto err_free; + } + } + + return 0; + +err_free: + allocated = i; + for (i = 0; i < allocated; i++) { + skb = rx_ring->buf[i]; + if (!skb) + continue; + dma = *((dma_addr_t *)skb->cb); + dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb(skb); + rx_ring->buf[i] = NULL; + } + + rx_ring->bd_ring.head = NULL; + + return ret; +} + +static int rtw89_pci_alloc_rx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_dma_pool *bd_pool = &rtwpci->rx.bd_pool; + struct rtw89_pci_rx_ring *rx_ring; + int i, rx_allocated; + dma_addr_t dma; + u32 desc_size; + u32 ring_sz; + u32 pool_sz; + void *head; + u32 len; + int ret; + + desc_size = sizeof(struct rtw89_pci_rx_bd_32); + len = RTW89_PCI_RXBD_NUM_MAX; + ring_sz = desc_size * len; + pool_sz = ring_sz * RTW89_RXCH_NUM; + + head = dma_alloc_coherent(&pdev->dev, pool_sz, &dma, GFP_KERNEL); + if (!head) + return -ENOMEM; + + bd_pool->head = head; + bd_pool->dma = dma; + bd_pool->size = pool_sz; + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx.rings[i]; + + ret = rtw89_pci_alloc_rx_ring(rtwdev, pdev, rx_ring, + desc_size, len, i, + head, dma); + if (ret) { + rtw89_err(rtwdev, "failed to alloc rx ring %d\n", i); + goto err_free; + } + + head += ring_sz; + dma += ring_sz; + } + + return 0; + +err_free: + rx_allocated = i; + for (i = 0; i < rx_allocated; i++) { + rx_ring = &rtwpci->rx.rings[i]; + rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); + } + + dma_free_coherent(&pdev->dev, bd_pool->size, bd_pool->head, bd_pool->dma); + + return ret; +} + +static int rtw89_pci_alloc_trx_rings(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + int ret; + + ret = rtw89_pci_alloc_tx_rings(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to alloc dma tx rings\n"); + goto err; + } + + ret = rtw89_pci_alloc_rx_rings(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to alloc dma rx rings\n"); + goto err_free_tx_rings; + } + + return 0; + +err_free_tx_rings: + rtw89_pci_free_tx_rings(rtwdev, pdev); +err: + return ret; +} + +static void rtw89_pci_h2c_init(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci) +{ + skb_queue_head_init(&rtwpci->h2c_queue); + skb_queue_head_init(&rtwpci->h2c_release_queue); +} + +static int rtw89_pci_setup_resource(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + int ret; + + ret = rtw89_pci_setup_mapping(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to setup pci mapping\n"); + goto err; + } + + ret = rtw89_pci_alloc_trx_rings(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to alloc pci trx rings\n"); + goto err_pci_unmap; + } + + rtw89_pci_h2c_init(rtwdev, rtwpci); + + spin_lock_init(&rtwpci->irq_lock); + spin_lock_init(&rtwpci->trx_lock); + + return 0; + +err_pci_unmap: + rtw89_pci_clear_mapping(rtwdev, pdev); +err: + return ret; +} + +static void rtw89_pci_clear_resource(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtw89_pci_free_trx_rings(rtwdev, pdev); + rtw89_pci_clear_mapping(rtwdev, pdev); + rtw89_pci_release_fwcmd(rtwdev, rtwpci, + skb_queue_len(&rtwpci->h2c_queue), true); +} + +void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN; + + if (chip->chip_id == RTL8851B) + hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN_WKARND; + + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0; + + if (rtwpci->under_recovery) { + rtwpci->intrs[0] = hs0isr_ind_int_en; + rtwpci->intrs[1] = 0; + } else { + rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | + B_AX_RXDMA_INT_EN | + B_AX_RXP1DMA_INT_EN | + B_AX_RPQDMA_INT_EN | + B_AX_RXDMA_STUCK_INT_EN | + B_AX_RDU_INT_EN | + B_AX_RPQBD_FULL_INT_EN | + hs0isr_ind_int_en; + + rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; + } +} +EXPORT_SYMBOL(rtw89_pci_config_intr_mask); + +static void rtw89_pci_recovery_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | B_AX_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = 0; +} + +static void rtw89_pci_default_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HCI_AXIDMA_INT_EN | + B_AX_HS1ISR_IND_INT_EN | + B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | B_AX_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | + B_AX_RXDMA_INT_EN | + B_AX_RXP1DMA_INT_EN | + B_AX_RPQDMA_INT_EN | + B_AX_RXDMA_STUCK_INT_EN | + B_AX_RDU_INT_EN | + B_AX_RPQBD_FULL_INT_EN; + rtwpci->intrs[1] = B_AX_GPIO18_INT_EN; +} + +static void rtw89_pci_low_power_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HS1ISR_IND_INT_EN | + B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | B_AX_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = B_AX_GPIO18_INT_EN; +} + +void rtw89_pci_config_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (rtwpci->under_recovery) + rtw89_pci_recovery_intr_mask_v1(rtwdev); + else if (rtwpci->low_power) + rtw89_pci_low_power_intr_mask_v1(rtwdev); + else + rtw89_pci_default_intr_mask_v1(rtwdev); +} +EXPORT_SYMBOL(rtw89_pci_config_intr_mask_v1); + +static void rtw89_pci_recovery_intr_mask_v2(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0; + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = 0; +} + +static void rtw89_pci_default_intr_mask_v2(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_BE_HCI_AXIDMA_INT_EN0 | + B_BE_HS0_IND_INT_EN0; + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = B_BE_RDU_CH1_INT_IMR_V1 | + B_BE_RDU_CH0_INT_IMR_V1; + rtwpci->intrs[1] = B_BE_PCIE_RX_RX0P2_IMR0_V1 | + B_BE_PCIE_RX_RPQ0_IMR0_V1; +} + +static void rtw89_pci_low_power_intr_mask_v2(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0 | + B_BE_HS1_IND_INT_EN0; + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = B_BE_PCIE_RX_RX0P2_IMR0_V1 | + B_BE_PCIE_RX_RPQ0_IMR0_V1; +} + +void rtw89_pci_config_intr_mask_v2(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (rtwpci->under_recovery) + rtw89_pci_recovery_intr_mask_v2(rtwdev); + else if (rtwpci->low_power) + rtw89_pci_low_power_intr_mask_v2(rtwdev); + else + rtw89_pci_default_intr_mask_v2(rtwdev); +} +EXPORT_SYMBOL(rtw89_pci_config_intr_mask_v2); + +static void rtw89_pci_recovery_intr_mask_v3(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0; + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN | + B_BE_SPSANA_OCP_INT_EN | B_BE_SPS_OCP_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = 0; +} + +static void rtw89_pci_default_intr_mask_v3(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0; + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN | + B_BE_SPSANA_OCP_INT_EN | B_BE_SPS_OCP_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = B_BE_PCIE_RDU_CH1_IMR | + B_BE_PCIE_RDU_CH0_IMR | + B_BE_PCIE_RX_RX0P2_IMR0_V1 | + B_BE_PCIE_RX_RPQ0_IMR0_V1; +} + +void rtw89_pci_config_intr_mask_v3(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (rtwpci->under_recovery) + rtw89_pci_recovery_intr_mask_v3(rtwdev); + else + rtw89_pci_default_intr_mask_v3(rtwdev); +} +EXPORT_SYMBOL(rtw89_pci_config_intr_mask_v3); + +static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + unsigned long flags = 0; + int ret; + + flags |= PCI_IRQ_INTX | PCI_IRQ_MSI; + ret = pci_alloc_irq_vectors(pdev, 1, 1, flags); + if (ret < 0) { + rtw89_err(rtwdev, "failed to alloc irq vectors, ret %d\n", ret); + goto err; + } + + ret = devm_request_threaded_irq(rtwdev->dev, pdev->irq, + rtw89_pci_interrupt_handler, + rtw89_pci_interrupt_threadfn, + IRQF_SHARED, KBUILD_MODNAME, rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to request threaded irq\n"); + goto err_free_vector; + } + + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RESET); + + return 0; + +err_free_vector: + pci_free_irq_vectors(pdev); +err: + return ret; +} + +static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev, + struct pci_dev *pdev) +{ + devm_free_irq(rtwdev->dev, pdev->irq, rtwdev); + pci_free_irq_vectors(pdev); +} + +static u16 gray_code_to_bin(u16 gray_code) +{ + u16 binary = gray_code; + + while (gray_code) { + gray_code >>= 1; + binary ^= gray_code; + } + + return binary; +} + +static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u16 val16, filter_out_val; + u32 val, phy_offset; + int ret; + + if (rtwdev->chip->chip_id != RTL8852C) + return 0; + + val = rtw89_read32_mask(rtwdev, R_AX_PCIE_MIX_CFG_V1, B_AX_ASPM_CTRL_MASK); + if (val == B_AX_ASPM_CTRL_L1) + return 0; + + ret = pci_read_config_dword(pdev, RTW89_PCIE_L1_STS_V1, &val); + if (ret) + return ret; + + val = FIELD_GET(RTW89_BCFG_LINK_SPEED_MASK, val); + if (val == RTW89_PCIE_GEN1_SPEED) { + phy_offset = R_RAC_DIRECT_OFFSET_G1; + } else if (val == RTW89_PCIE_GEN2_SPEED) { + phy_offset = R_RAC_DIRECT_OFFSET_G2; + val16 = rtw89_read16(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, + val16 | B_PCIE_BIT_PINOUT_DIS); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + val16 & ~B_PCIE_BIT_RD_SEL); + + val16 = rtw89_read16_mask(rtwdev, + phy_offset + RAC_ANA1F * RAC_MULT, + FILTER_OUT_EQ_MASK); + val16 = gray_code_to_bin(val16); + filter_out_val = rtw89_read16(rtwdev, phy_offset + RAC_ANA24 * + RAC_MULT); + filter_out_val &= ~REG_FILTER_OUT_MASK; + filter_out_val |= FIELD_PREP(REG_FILTER_OUT_MASK, val16); + + rtw89_write16(rtwdev, phy_offset + RAC_ANA24 * RAC_MULT, + filter_out_val); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0A * RAC_MULT, + B_BAC_EQ_SEL); + rtw89_write16_set(rtwdev, + R_RAC_DIRECT_OFFSET_G1 + RAC_ANA0C * RAC_MULT, + B_PCIE_BIT_PSAVE); + } else { + return -EOPNOTSUPP; + } + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0C * RAC_MULT, + B_PCIE_BIT_PSAVE); + + return 0; +} + +static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + if (rtw89_pci_disable_clkreq) + return; + + gen_def->clkreq_set(rtwdev, enable); +} + +static void rtw89_pci_clkreq_set_ax(struct rtw89_dev *rtwdev, bool enable) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + int ret; + + ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_CLK_CTRL, + PCIE_CLKDLY_HW_30US); + if (ret) + rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_CLK); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_CLK); + if (ret) + rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d", + enable ? "set" : "unset", ret); + } else if (chip_id == RTL8852C) { + rtw89_write32_set(rtwdev, R_AX_PCIE_LAT_CTRL, + B_AX_CLK_REQ_SEL_OPT | B_AX_CLK_REQ_SEL); + if (enable) + rtw89_write32_set(rtwdev, R_AX_L1_CLK_CTRL, + B_AX_CLK_REQ_N); + else + rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL, + B_AX_CLK_REQ_N); + } +} + +static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + if (rtw89_pci_disable_aspm_l1) + return; + + gen_def->aspm_set(rtwdev, enable); +} + +static void rtw89_pci_aspm_set_ax(struct rtw89_dev *rtwdev, bool enable) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u8 value = 0; + int ret; + + ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_ASPM_CTRL, &value); + if (ret) + rtw89_warn(rtwdev, "failed to read ASPM Delay\n"); + + u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK); + u8p_replace_bits(&value, PCIE_L0SDLY_4US, RTW89_L0DLY_MASK); + + ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_ASPM_CTRL, value); + if (ret) + rtw89_warn(rtwdev, "failed to read ASPM Delay\n"); + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_L1); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_L1); + } else if (chip_id == RTL8852C) { + if (enable) + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_ASPM_CTRL_L1); + else + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_ASPM_CTRL_L1); + } + if (ret) + rtw89_err(rtwdev, "failed to %s ASPM L1, ret=%d", + enable ? "set" : "unset", ret); +} + +static void rtw89_pci_recalc_int_mit(struct rtw89_dev *rtwdev) +{ + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + const struct rtw89_pci_info *info = rtwdev->pci_info; + struct rtw89_traffic_stats *stats = &rtwdev->stats; + enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; + enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; + u32 val = 0; + + if (rtwdev->scanning || + (tx_tfc_lv < RTW89_TFC_HIGH && rx_tfc_lv < RTW89_TFC_HIGH)) + goto out; + + if (chip_gen == RTW89_CHIP_BE) + val = B_BE_PCIE_MIT_RX0P2_EN | B_BE_PCIE_MIT_RX0P1_EN; + else + val = B_AX_RXMIT_RXP2_SEL | B_AX_RXMIT_RXP1_SEL | + FIELD_PREP(B_AX_RXCOUNTER_MATCH_MASK, RTW89_PCI_RXBD_NUM_MAX / 2) | + FIELD_PREP(B_AX_RXTIMER_UNIT_MASK, AX_RXTIMER_UNIT_64US) | + FIELD_PREP(B_AX_RXTIMER_MATCH_MASK, 2048 / 64); + +out: + rtw89_write32(rtwdev, info->mit_addr, val); +} + +static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u16 link_ctrl; + int ret; + + /* Though there is standard PCIE configuration space to set the + * link control register, but by Realtek's design, driver should + * check if host supports CLKREQ/ASPM to enable the HW module. + * + * These functions are implemented by two HW modules associated, + * one is responsible to access PCIE configuration space to + * follow the host settings, and another is in charge of doing + * CLKREQ/ASPM mechanisms, it is default disabled. Because sometimes + * the host does not support it, and due to some reasons or wrong + * settings (ex. CLKREQ# not Bi-Direction), it could lead to device + * loss if HW misbehaves on the link. + * + * Hence it's designed that driver should first check the PCIE + * configuration space is sync'ed and enabled, then driver can turn + * on the other module that is actually working on the mechanism. + */ + ret = pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &link_ctrl); + if (ret) { + rtw89_err(rtwdev, "failed to read PCI cap, ret=%d\n", ret); + return; + } + + if (link_ctrl & PCI_EXP_LNKCTL_CLKREQ_EN) + rtw89_pci_clkreq_set(rtwdev, true); + + if (link_ctrl & PCI_EXP_LNKCTL_ASPM_L1) + rtw89_pci_aspm_set(rtwdev, true); +} + +static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + if (rtw89_pci_disable_l1ss) + return; + + gen_def->l1ss_set(rtwdev, enable); +} + +static void rtw89_pci_l1ss_set_ax(struct rtw89_dev *rtwdev, bool enable) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + int ret; + + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_TIMER_CTRL, + RTW89_PCIE_BIT_L1SUB); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_TIMER_CTRL, + RTW89_PCIE_BIT_L1SUB); + if (ret) + rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", + enable ? "set" : "unset", ret); + } else if (chip_id == RTL8852C) { + ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1SS_STS_V1, + RTW89_PCIE_BIT_ASPM_L11 | + RTW89_PCIE_BIT_PCI_L11); + if (ret) + rtw89_warn(rtwdev, "failed to unset ASPM L1.1, ret=%d", ret); + if (enable) + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_L1SUB_DISABLE); + else + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_L1SUB_DISABLE); + } +} + +static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u32 l1ss_cap_ptr, l1ss_ctrl; + + if (rtw89_pci_disable_l1ss) + return; + + l1ss_cap_ptr = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); + if (!l1ss_cap_ptr) + return; + + pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); + + if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) + rtw89_pci_l1ss_set(rtwdev, true); +} + +static void rtw89_pci_cpl_timeout_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + struct pci_dev *pdev = rtwpci->pdev; + bool dis = true; + + if (chip_id == RTL8922D && hal->cid == RTL8922D_CID7090) + dis = false; + + if (dis) + pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); + else + pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); +} + +static int rtw89_pci_poll_io_idle_ax(struct rtw89_dev *rtwdev) +{ + int ret = 0; + u32 sts; + u32 busy = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; + + ret = read_poll_timeout_atomic(rtw89_read32, sts, (sts & busy) == 0x0, + 10, 1000, false, rtwdev, + R_AX_PCIE_DMA_BUSY1); + if (ret) { + rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", + rtw89_read32(rtwdev, R_AX_PCIE_DMA_BUSY1)); + return -EINVAL; + } + return ret; +} + +static int rtw89_pci_lv1rst_stop_dma_ax(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + if (rtwdev->chip->chip_id == RTL8852C) + return 0; + + rtw89_pci_ctrl_dma_all(rtwdev, false); + ret = rtw89_pci_poll_io_idle_ax(rtwdev); + if (ret) { + val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "[PCIe] poll_io_idle fail, before 0x%08x: 0x%08x\n", + R_AX_DBG_ERR_FLAG, val); + if (val & B_AX_TX_STUCK || val & B_AX_PCIE_TXBD_LEN0) + rtw89_mac_ctrl_hci_dma_tx(rtwdev, false); + if (val & B_AX_RX_STUCK) + rtw89_mac_ctrl_hci_dma_rx(rtwdev, false); + rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); + ret = rtw89_pci_poll_io_idle_ax(rtwdev); + val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "[PCIe] poll_io_idle fail, after 0x%08x: 0x%08x\n", + R_AX_DBG_ERR_FLAG, val); + } + + return ret; +} + +static int rtw89_pci_lv1rst_start_dma_ax(struct rtw89_dev *rtwdev) +{ + int ret; + + if (rtwdev->chip->chip_id == RTL8852C) + return 0; + + rtw89_mac_ctrl_hci_dma_trx(rtwdev, false); + rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); + rtw89_pci_clr_idx_all(rtwdev); + + ret = rtw89_pci_rst_bdram_ax(rtwdev); + if (ret) + return ret; + + rtw89_pci_ctrl_dma_all(rtwdev, true); + return 0; +} + +static int rtw89_pci_ops_mac_lv1_recovery(struct rtw89_dev *rtwdev, + enum rtw89_lv1_rcvy_step step) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + int ret; + + switch (step) { + case RTW89_LV1_RCVY_STEP_1: + ret = gen_def->lv1rst_stop_dma(rtwdev); + if (ret) + rtw89_err(rtwdev, "lv1 rcvy pci stop dma fail\n"); + + break; + + case RTW89_LV1_RCVY_STEP_2: + ret = gen_def->lv1rst_start_dma(rtwdev); + if (ret) + rtw89_err(rtwdev, "lv1 rcvy pci start dma fail\n"); + break; + + default: + return -EINVAL; + } + + return ret; +} + +static void rtw89_pci_ops_dump_err_status(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + return; + + if (rtwdev->chip->chip_id == RTL8852C) { + rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG_V1)); + rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG_V1)); + } else { + rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX =0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); + rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG)); + rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG)); + } +} + +static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget) +{ + struct rtw89_dev *rtwdev = container_of(napi, struct rtw89_dev, napi); + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_isr_def *isr_def = info->isr_def; + unsigned long flags; + int work_done; + + rtwdev->napi_budget_countdown = budget; + + rtw89_write32(rtwdev, isr_def->isr_clear_rpq.addr, isr_def->isr_clear_rpq.data); + work_done = rtw89_pci_poll_rpq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); + if (work_done == budget) + return budget; + + rtw89_write32(rtwdev, isr_def->isr_clear_rxq.addr, isr_def->isr_clear_rxq.data); + work_done += rtw89_pci_poll_rxq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); + if (work_done < budget && napi_complete_done(napi, work_done)) { + spin_lock_irqsave(&rtwpci->irq_lock, flags); + if (likely(rtwpci->running)) + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + } + + return work_done; +} + +static +void rtw89_check_pci_ssid_quirks(struct rtw89_dev *rtwdev, + struct pci_dev *pdev, + const struct rtw89_pci_ssid_quirk *ssid_quirks) +{ + int i; + + if (!ssid_quirks) + return; + + for (i = 0; i < 200; i++, ssid_quirks++) { + if (ssid_quirks->vendor == 0 && ssid_quirks->device == 0) + break; + + if (ssid_quirks->vendor != pdev->vendor || + ssid_quirks->device != pdev->device || + ssid_quirks->subsystem_vendor != pdev->subsystem_vendor || + ssid_quirks->subsystem_device != pdev->subsystem_device) + continue; + + bitmap_or(rtwdev->quirks, rtwdev->quirks, &ssid_quirks->bitmap, + NUM_OF_RTW89_QUIRKS); + rtwdev->custid = ssid_quirks->custid; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_HCI, "quirks=%*ph custid=%d\n", + (int)sizeof(rtwdev->quirks), rtwdev->quirks, rtwdev->custid); +} + +static int __maybe_unused rtw89_pci_suspend(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw89_dev *rtwdev = hw->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); + rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); + rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); + } else { + rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL_V1, + B_AX_CMAC_EXIT_L1_EN | B_AX_DMAC0_EXIT_L1_EN); + } + + return 0; +} + +static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id == RTL8852C) + return; + + /* Hardware need write the reg twice to ensure the setting work */ + rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_RST_MSTATE, + RTW89_PCIE_BIT_CFG_RST_MSTATE); + rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_RST_MSTATE, + RTW89_PCIE_BIT_CFG_RST_MSTATE); +} + +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume) +{ + if (resume) + rtw89_pci_cfg_dac(rtwdev, false); + + rtw89_pci_disable_eq(rtwdev); + rtw89_pci_filter_out(rtwdev); + rtw89_pci_cpl_timeout_cfg(rtwdev); + rtw89_pci_link_cfg(rtwdev); + rtw89_pci_l1ss_cfg(rtwdev); +} + +static int __maybe_unused rtw89_pci_resume(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw89_dev *rtwdev = hw->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); + rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); + rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); + if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) { + rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); + } else { + rtw89_write32_set(rtwdev, R_AX_PCIE_PS_CTRL_V1, + B_AX_CMAC_EXIT_L1_EN | B_AX_DMAC0_EXIT_L1_EN); + rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL_V1, + B_AX_SEL_REQ_ENTR_L1); + } + rtw89_pci_hci_ldo(rtwdev); + rtw89_pci_l2_hci_ldo(rtwdev); + + rtw89_pci_basic_cfg(rtwdev, true); + + return 0; +} + +SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume); +EXPORT_SYMBOL(rtw89_pm_ops); + +static pci_ers_result_t rtw89_pci_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + + ieee80211_stop_queues(hw); + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t rtw89_pci_io_slot_reset(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw89_dev *rtwdev = hw->priv; + + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void rtw89_pci_io_resume(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, PCI_D0, 0); + + ieee80211_wake_queues(hw); +} + +const struct pci_error_handlers rtw89_pci_err_handler = { + .error_detected = rtw89_pci_io_error_detected, + .slot_reset = rtw89_pci_io_slot_reset, + .resume = rtw89_pci_io_resume, +}; +EXPORT_SYMBOL(rtw89_pci_err_handler); + +const struct rtw89_pci_isr_def rtw89_pci_isr_ax = { + .isr_rdu = B_AX_RDU_INT, + .isr_halt_c2h = B_AX_HALT_C2H_INT_EN, + .isr_wdt_timeout = B_AX_WDT_TIMEOUT_INT_EN, + .isr_sps_ocp = 0, + .isr_clear_rpq = {R_AX_PCIE_HISR00, B_AX_RPQDMA_INT | B_AX_RPQBD_FULL_INT}, + .isr_clear_rxq = {R_AX_PCIE_HISR00, B_AX_RXP1DMA_INT | B_AX_RXDMA_INT | + B_AX_RDU_INT}, +}; +EXPORT_SYMBOL(rtw89_pci_isr_ax); + +const struct rtw89_pci_gen_def rtw89_pci_gen_ax = { + .mac_pre_init = rtw89_pci_ops_mac_pre_init_ax, + .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_ax, + .mac_post_init = rtw89_pci_ops_mac_post_init_ax, + + .clr_idx_all = rtw89_pci_clr_idx_all_ax, + .rst_bdram = rtw89_pci_rst_bdram_ax, + + .lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_ax, + .lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_ax, + + .ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_ax, + .ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_ax, + .poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle_ax, + + .aspm_set = rtw89_pci_aspm_set_ax, + .clkreq_set = rtw89_pci_clkreq_set_ax, + .l1ss_set = rtw89_pci_l1ss_set_ax, + + .disable_eq = rtw89_pci_disable_eq_ax, + .power_wake = rtw89_pci_power_wake_ax, +}; +EXPORT_SYMBOL(rtw89_pci_gen_ax); + +static const struct rtw89_hci_ops rtw89_pci_ops = { + .tx_write = rtw89_pci_ops_tx_write, + .tx_kick_off = rtw89_pci_ops_tx_kick_off, + .flush_queues = rtw89_pci_ops_flush_queues, + .reset = rtw89_pci_ops_reset, + .start = rtw89_pci_ops_start, + .stop = rtw89_pci_ops_stop, + .pause = rtw89_pci_ops_pause, + .switch_mode = rtw89_pci_ops_switch_mode, + .recalc_int_mit = rtw89_pci_recalc_int_mit, + + .read8 = rtw89_pci_ops_read8, + .read16 = rtw89_pci_ops_read16, + .read32 = rtw89_pci_ops_read32, + .write8 = rtw89_pci_ops_write8, + .write16 = rtw89_pci_ops_write16, + .write32 = rtw89_pci_ops_write32, + + .read32_pci_cfg = rtw89_pci_ops_read32_pci_cfg, + + .mac_pre_init = rtw89_pci_ops_mac_pre_init, + .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit, + .mac_post_init = rtw89_pci_ops_mac_post_init, + .deinit = rtw89_pci_ops_deinit, + + .check_and_reclaim_tx_resource = rtw89_pci_check_and_reclaim_tx_resource, + .mac_lv1_rcvy = rtw89_pci_ops_mac_lv1_recovery, + .dump_err_status = rtw89_pci_ops_dump_err_status, + .napi_poll = rtw89_pci_napi_poll, + + .recovery_start = rtw89_pci_ops_recovery_start, + .recovery_complete = rtw89_pci_ops_recovery_complete, + + .ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch, + .ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch, + .ctrl_trxhci = rtw89_pci_ctrl_dma_trx, + .poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle, + + .clr_idx_all = rtw89_pci_clr_idx_all, + .clear = rtw89_pci_clear_resource, + .disable_intr = rtw89_pci_disable_intr_lock, + .enable_intr = rtw89_pci_enable_intr_lock, + .rst_bdram = rtw89_pci_reset_bdram, +}; + +int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct rtw89_dev *rtwdev; + const struct rtw89_driver_info *info; + const struct rtw89_pci_info *pci_info; + int ret; + + info = (const struct rtw89_driver_info *)id->driver_data; + + rtwdev = rtw89_alloc_ieee80211_hw(&pdev->dev, + sizeof(struct rtw89_pci), info); + if (!rtwdev) { + dev_err(&pdev->dev, "failed to allocate hw\n"); + return -ENOMEM; + } + + pci_info = info->bus.pci; + + rtwdev->pci_info = info->bus.pci; + rtwdev->hci.ops = &rtw89_pci_ops; + rtwdev->hci.type = RTW89_HCI_TYPE_PCIE; + rtwdev->hci.dle_type = RTW89_HCI_DLE_TYPE_PCIE; + rtwdev->hci.rpwm_addr = pci_info->rpwm_addr; + rtwdev->hci.cpwm_addr = pci_info->cpwm_addr; + + rtw89_check_quirks(rtwdev, info->quirks); + rtw89_check_pci_ssid_quirks(rtwdev, pdev, pci_info->ssid_quirks); + + SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); + + ret = rtw89_core_init(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to initialise core\n"); + goto err_release_hw; + } + + ret = rtw89_pci_claim_device(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to claim pci device\n"); + goto err_core_deinit; + } + + ret = rtw89_pci_setup_resource(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to setup pci resource\n"); + goto err_declaim_pci; + } + + ret = rtw89_chip_info_setup(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to setup chip information\n"); + goto err_clear_resource; + } + + rtw89_pci_basic_cfg(rtwdev, false); + + ret = rtw89_core_napi_init(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to init napi\n"); + goto err_clear_resource; + } + + ret = rtw89_pci_request_irq(rtwdev, pdev); + if (ret) { + rtw89_err(rtwdev, "failed to request pci irq\n"); + goto err_deinit_napi; + } + + ret = rtw89_core_register(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to register core\n"); + goto err_free_irq; + } + + set_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags); + + return 0; + +err_free_irq: + rtw89_pci_free_irq(rtwdev, pdev); +err_deinit_napi: + rtw89_core_napi_deinit(rtwdev); +err_clear_resource: + rtw89_pci_clear_resource(rtwdev, pdev); +err_declaim_pci: + rtw89_pci_declaim_device(rtwdev, pdev); +err_core_deinit: + rtw89_core_deinit(rtwdev); +err_release_hw: + rtw89_free_ieee80211_hw(rtwdev); + + return ret; +} +EXPORT_SYMBOL(rtw89_pci_probe); + +void rtw89_pci_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw89_dev *rtwdev; + + rtwdev = hw->priv; + + rtw89_pci_free_irq(rtwdev, pdev); + rtw89_core_napi_deinit(rtwdev); + rtw89_core_unregister(rtwdev); + rtw89_pci_clear_resource(rtwdev, pdev); + rtw89_pci_declaim_device(rtwdev, pdev); + rtw89_core_deinit(rtwdev); + rtw89_free_ieee80211_hw(rtwdev); +} +EXPORT_SYMBOL(rtw89_pci_remove); + +void rtw89_pci_shutdown(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw89_dev *rtwdev; + + if (!hw) + return; + + rtwdev = hw->priv; + set_bit(RTW89_FLAG_SHUTDOWN, rtwdev->flags); +} +EXPORT_SYMBOL(rtw89_pci_shutdown); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek PCI 802.11ax wireless driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h new file mode 100644 index 000000000..cba52584e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -0,0 +1,1950 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2020 Realtek Corporation + */ + +#ifndef __RTW89_PCI_H__ +#define __RTW89_PCI_H__ + +#include "txrx.h" + +#define MDIO_PG0_G1 0 +#define MDIO_PG1_G1 1 +#define MDIO_PG0_G2 2 +#define MDIO_PG1_G2 3 +#define RAC_CTRL_PPR 0x00 +#define RAC_ANA03 0x03 +#define OOBS_SEN_MASK GENMASK(5, 1) +#define RAC_ANA09 0x09 +#define BAC_OOBS_SEL BIT(4) +#define RAC_ANA0A 0x0A +#define B_BAC_EQ_SEL BIT(5) +#define RAC_ANA0B 0x0B +#define MANUAL_LVL_MASK GENMASK(8, 5) +#define RAC_ANA0C 0x0C +#define B_PCIE_BIT_PSAVE BIT(15) +#define RAC_ANA0D 0x0D +#define OFFSET_CAL_MODE BIT(13) +#define BAC_RX_TEST_EN BIT(6) +#define RAC_ANA10 0x10 +#define ADDR_SEL_MASK GENMASK(9, 4) +#define ADDR_SEL_VAL 0x3C +#define ADDR_SEL_PINOUT_DIS_VAL 0x3C4 +#define B_PCIE_BIT_PINOUT_DIS BIT(3) +#define RAC_REG_REV2 0x1B +#define BAC_CMU_EN_DLY_MASK GENMASK(15, 12) +#define PCIE_DPHY_DLY_25US 0x1 +#define RAC_ANA14 0x14 +#define EIEOS_L1SS_WAIT_CLKRDY BIT(2) +#define RAC_ANA19 0x19 +#define B_PCIE_BIT_RD_SEL BIT(2) +#define RAC_REG_FLD_0 0x1D +#define BAC_AUTOK_N_MASK GENMASK(3, 2) +#define PCIE_AUTOK_4 0x3 +#define RAC_ANA1E 0x1E +#define RAC_ANA1E_G1_VAL 0x66EA +#define RAC_ANA1E_G2_VAL 0x6EEA +#define RAC_ANA1F 0x1F +#define OOBS_LEVEL_MASK GENMASK(12, 8) +#define OFFSET_CAL_MASK GENMASK(7, 4) +#define RAC_ANA24 0x24 +#define B_AX_DEGLITCH GENMASK(11, 8) +#define RAC_ANA26 0x26 +#define B_AX_RXEN GENMASK(15, 14) +#define RAC_ANA2E 0x2E +#define RAC_ANA2E_VAL 0xFFFE +#define RAC_CTRL_PPR_V1 0x30 +#define B_AX_CLK_CALIB_EN BIT(12) +#define B_AX_CALIB_EN BIT(13) +#define B_AX_DIV GENMASK(15, 14) +#define RAC_SET_PPR_V1 0x31 +#define RAC_ANA40 0x40 +#define PHY_ERR_IMR_DIS (BIT(9) | BIT(2) | BIT(1) | BIT(0)) +#define RAC_ANA41 0x41 +#define PHY_ERR_FLAG_EN BIT(6) + +#define R_AX_DBI_FLAG 0x1090 +#define B_AX_DBI_RFLAG BIT(17) +#define B_AX_DBI_WFLAG BIT(16) +#define B_AX_DBI_WREN_MSK GENMASK(15, 12) +#define B_AX_DBI_ADDR_MSK GENMASK(11, 2) +#define B_AX_DBI_2LSB GENMASK(1, 0) +#define R_AX_DBI_WDATA 0x1094 +#define R_AX_DBI_RDATA 0x1098 + +#define R_AX_MDIO_WDATA 0x10A4 +#define R_AX_MDIO_RDATA 0x10A6 + +#define R_AX_PCIE_PS_CTRL_V1 0x3008 +#define B_AX_CMAC_EXIT_L1_EN BIT(7) +#define B_AX_DMAC0_EXIT_L1_EN BIT(6) +#define B_AX_SEL_XFER_PENDING BIT(3) +#define B_AX_SEL_REQ_ENTR_L1 BIT(2) +#define B_AX_SEL_REQ_EXIT_L1 BIT(0) + +#define R_AX_PCIE_MIX_CFG_V1 0x300C +#define B_AX_ASPM_CTRL_L1 BIT(17) +#define B_AX_ASPM_CTRL_L0 BIT(16) +#define B_AX_ASPM_CTRL_MASK GENMASK(17, 16) +#define B_AX_XFER_PENDING_FW BIT(11) +#define B_AX_XFER_PENDING BIT(10) +#define B_AX_REQ_EXIT_L1 BIT(9) +#define B_AX_REQ_ENTR_L1 BIT(8) +#define B_AX_L1SUB_DISABLE BIT(0) + +#define R_AX_L1_CLK_CTRL 0x3010 +#define B_AX_CLK_REQ_N BIT(1) + +#define R_AX_PCIE_BG_CLR 0x303C +#define B_AX_BG_CLR_ASYNC_M3 BIT(4) + +#define R_AX_PCIE_LAT_CTRL 0x3044 +#define B_AX_CLK_REQ_SEL_OPT BIT(1) +#define B_AX_CLK_REQ_SEL BIT(0) + +#define R_AX_PCIE_IO_RCY_M1 0x3100 +#define B_AX_PCIE_IO_RCY_P_M1 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_M1 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_M1 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_M1 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_M1 0x3104 +#define B_AX_PCIE_WDT_TIMER_M1_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_M2 0x310C +#define B_AX_PCIE_IO_RCY_P_M2 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_M2 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_M2 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_M2 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_M2 0x3110 +#define B_AX_PCIE_WDT_TIMER_M2_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_E0 0x3118 +#define B_AX_PCIE_IO_RCY_P_E0 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_E0 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_E0 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_E0 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_E0 0x311C +#define B_AX_PCIE_WDT_TIMER_E0_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_S1 0x3124 +#define B_AX_PCIE_IO_RCY_RP_S1 BIT(7) +#define B_AX_PCIE_IO_RCY_WP_S1 BIT(6) +#define B_AX_PCIE_IO_RCY_WDT_RP_S1 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_WP_S1 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_S1 BIT(3) +#define B_AX_PCIE_IO_RCY_RTRIG_S1 BIT(1) +#define B_AX_PCIE_IO_RCY_WTRIG_S1 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_S1 0x3128 +#define B_AX_PCIE_WDT_TIMER_S1_MASK GENMASK(31, 0) + +#define R_RAC_DIRECT_OFFSET_G1 0x3800 +#define FILTER_OUT_EQ_MASK GENMASK(14, 10) +#define R_RAC_DIRECT_OFFSET_G2 0x3880 +#define REG_FILTER_OUT_MASK GENMASK(6, 2) +#define RAC_MULT 2 + +#define R_RAC_DIRECT_OFFSET_BE_LANE0_G1 0x3800 +#define R_RAC_DIRECT_OFFSET_BE_LANE1_G1 0x3880 +#define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900 +#define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980 + +#define RAC_DIRECT_OFFESET_L0_G1 0x3800 +#define RAC_DIRECT_OFFESET_L1_G1 0x3900 +#define RAC_DIRECT_OFFESET_L0_G2 0x3A00 +#define RAC_DIRECT_OFFESET_L1_G2 0x3B00 + +#define RTW89_PCI_WR_RETRY_CNT 20 + +/* Interrupts */ +#define R_AX_HIMR0 0x01A0 +#define B_AX_WDT_TIMEOUT_INT_EN BIT(22) +#define B_AX_HALT_C2H_INT_EN BIT(21) +#define R_AX_HISR0 0x01A4 + +#define R_AX_HIMR1 0x01A8 +#define B_AX_GPIO18_INT_EN BIT(2) +#define B_AX_GPIO17_INT_EN BIT(1) +#define B_AX_GPIO16_INT_EN BIT(0) + +#define R_AX_HISR1 0x01AC +#define B_AX_GPIO18_INT BIT(2) +#define B_AX_GPIO17_INT BIT(1) +#define B_AX_GPIO16_INT BIT(0) + +#define R_AX_MDIO_CFG 0x10A0 +#define B_AX_MDIO_PHY_ADDR_MASK GENMASK(13, 12) +#define B_AX_MDIO_RFLAG BIT(9) +#define B_AX_MDIO_WFLAG BIT(8) +#define B_AX_MDIO_ADDR_MASK GENMASK(4, 0) + +#define R_AX_PCIE_HIMR00 0x10B0 +#define R_AX_HAXI_HIMR00 0x10B0 +#define B_AX_HC00ISR_IND_INT_EN BIT(27) +#define B_AX_HD1ISR_IND_INT_EN BIT(26) +#define B_AX_HD0ISR_IND_INT_EN BIT(25) +#define B_AX_HS0ISR_IND_INT_EN BIT(24) +#define B_AX_HS0ISR_IND_INT_EN_WKARND BIT(23) +#define B_AX_RETRAIN_INT_EN BIT(21) +#define B_AX_RPQBD_FULL_INT_EN BIT(20) +#define B_AX_RDU_INT_EN BIT(19) +#define B_AX_RXDMA_STUCK_INT_EN BIT(18) +#define B_AX_TXDMA_STUCK_INT_EN BIT(17) +#define B_AX_PCIE_HOTRST_INT_EN BIT(16) +#define B_AX_PCIE_FLR_INT_EN BIT(15) +#define B_AX_PCIE_PERST_INT_EN BIT(14) +#define B_AX_TXDMA_CH12_INT_EN BIT(13) +#define B_AX_TXDMA_CH9_INT_EN BIT(12) +#define B_AX_TXDMA_CH8_INT_EN BIT(11) +#define B_AX_TXDMA_ACH7_INT_EN BIT(10) +#define B_AX_TXDMA_ACH6_INT_EN BIT(9) +#define B_AX_TXDMA_ACH5_INT_EN BIT(8) +#define B_AX_TXDMA_ACH4_INT_EN BIT(7) +#define B_AX_TXDMA_ACH3_INT_EN BIT(6) +#define B_AX_TXDMA_ACH2_INT_EN BIT(5) +#define B_AX_TXDMA_ACH1_INT_EN BIT(4) +#define B_AX_TXDMA_ACH0_INT_EN BIT(3) +#define B_AX_RPQDMA_INT_EN BIT(2) +#define B_AX_RXP1DMA_INT_EN BIT(1) +#define B_AX_RXDMA_INT_EN BIT(0) + +#define R_AX_PCIE_HISR00 0x10B4 +#define R_AX_HAXI_HISR00 0x10B4 +#define B_AX_HC00ISR_IND_INT BIT(27) +#define B_AX_HD1ISR_IND_INT BIT(26) +#define B_AX_HD0ISR_IND_INT BIT(25) +#define B_AX_HS0ISR_IND_INT BIT(24) +#define B_AX_RETRAIN_INT BIT(21) +#define B_AX_RPQBD_FULL_INT BIT(20) +#define B_AX_RDU_INT BIT(19) +#define B_AX_RXDMA_STUCK_INT BIT(18) +#define B_AX_TXDMA_STUCK_INT BIT(17) +#define B_AX_PCIE_HOTRST_INT BIT(16) +#define B_AX_PCIE_FLR_INT BIT(15) +#define B_AX_PCIE_PERST_INT BIT(14) +#define B_AX_TXDMA_CH12_INT BIT(13) +#define B_AX_TXDMA_CH9_INT BIT(12) +#define B_AX_TXDMA_CH8_INT BIT(11) +#define B_AX_TXDMA_ACH7_INT BIT(10) +#define B_AX_TXDMA_ACH6_INT BIT(9) +#define B_AX_TXDMA_ACH5_INT BIT(8) +#define B_AX_TXDMA_ACH4_INT BIT(7) +#define B_AX_TXDMA_ACH3_INT BIT(6) +#define B_AX_TXDMA_ACH2_INT BIT(5) +#define B_AX_TXDMA_ACH1_INT BIT(4) +#define B_AX_TXDMA_ACH0_INT BIT(3) +#define B_AX_RPQDMA_INT BIT(2) +#define B_AX_RXP1DMA_INT BIT(1) +#define B_AX_RXDMA_INT BIT(0) + +#define R_AX_HAXI_IDCT_MSK 0x10B8 +#define B_AX_TXBD_LEN0_ERR_IDCT_MSK BIT(3) +#define B_AX_TXBD_4KBOUND_ERR_IDCT_MSK BIT(2) +#define B_AX_RXMDA_STUCK_IDCT_MSK BIT(1) +#define B_AX_TXMDA_STUCK_IDCT_MSK BIT(0) + +#define R_AX_HAXI_IDCT 0x10BC +#define B_AX_TXBD_LEN0_ERR_IDCT BIT(3) +#define B_AX_TXBD_4KBOUND_ERR_IDCT BIT(2) +#define B_AX_RXMDA_STUCK_IDCT BIT(1) +#define B_AX_TXMDA_STUCK_IDCT BIT(0) + +#define R_AX_HAXI_HIMR10 0x11E0 +#define B_AX_TXDMA_CH11_INT_EN_V1 BIT(1) +#define B_AX_TXDMA_CH10_INT_EN_V1 BIT(0) + +#define R_AX_PCIE_HIMR10 0x13B0 +#define B_AX_HC10ISR_IND_INT_EN BIT(28) +#define B_AX_TXDMA_CH11_INT_EN BIT(12) +#define B_AX_TXDMA_CH10_INT_EN BIT(11) + +#define R_AX_PCIE_HISR10 0x13B4 +#define B_AX_HC10ISR_IND_INT BIT(28) +#define B_AX_TXDMA_CH11_INT BIT(12) +#define B_AX_TXDMA_CH10_INT BIT(11) + +#define R_AX_PCIE_HIMR00_V1 0x30B0 +#define B_AX_HCI_AXIDMA_INT_EN BIT(29) +#define B_AX_HC00ISR_IND_INT_EN_V1 BIT(28) +#define B_AX_HD1ISR_IND_INT_EN_V1 BIT(27) +#define B_AX_HD0ISR_IND_INT_EN_V1 BIT(26) +#define B_AX_HS1ISR_IND_INT_EN BIT(25) +#define B_AX_PCIE_DBG_STE_INT_EN BIT(13) + +#define R_AX_PCIE_HISR00_V1 0x30B4 +#define B_AX_HCI_AXIDMA_INT BIT(29) +#define B_AX_HC00ISR_IND_INT_V1 BIT(28) +#define B_AX_HD1ISR_IND_INT_V1 BIT(27) +#define B_AX_HD0ISR_IND_INT_V1 BIT(26) +#define B_AX_HS1ISR_IND_INT BIT(25) +#define B_AX_PCIE_DBG_STE_INT BIT(13) + +#define R_BE_PCIE_FRZ_CLK 0x3004 +#define B_BE_PCIE_FRZ_MAC_HW_RST BIT(31) +#define B_BE_PCIE_FRZ_CFG_SPC_RST BIT(30) +#define B_BE_PCIE_FRZ_ELBI_RST BIT(29) +#define B_BE_PCIE_MAC_IS_ACTIVE BIT(28) +#define B_BE_PCIE_FRZ_RTK_HW_RST BIT(27) +#define B_BE_PCIE_FRZ_REG_RST BIT(26) +#define B_BE_PCIE_FRZ_ANA_RST BIT(25) +#define B_BE_PCIE_FRZ_WLAN_RST BIT(24) +#define B_BE_PCIE_FRZ_FLR_RST BIT(23) +#define B_BE_PCIE_FRZ_RET_NON_STKY_RST BIT(22) +#define B_BE_PCIE_FRZ_RET_STKY_RST BIT(21) +#define B_BE_PCIE_FRZ_NON_STKY_RST BIT(20) +#define B_BE_PCIE_FRZ_STKY_RST BIT(19) +#define B_BE_PCIE_FRZ_RET_CORE_RST BIT(18) +#define B_BE_PCIE_FRZ_PWR_RST BIT(17) +#define B_BE_PCIE_FRZ_PERST_RST BIT(16) +#define B_BE_PCIE_FRZ_PHY_ALOAD BIT(15) +#define B_BE_PCIE_FRZ_PHY_HW_RST BIT(14) +#define B_BE_PCIE_DBG_CLK BIT(4) +#define B_BE_PCIE_EN_CLK BIT(3) +#define B_BE_PCIE_DBI_ACLK_ACT BIT(2) +#define B_BE_PCIE_S1_ACLK_ACT BIT(1) +#define B_BE_PCIE_EN_AUX_CLK BIT(0) + +#define R_BE_PCIE_PS_CTRL 0x3008 +#define B_BE_ASPM_L11_EN BIT(19) +#define B_BE_ASPM_L12_EN BIT(18) +#define B_BE_PCIPM_L11_EN BIT(17) +#define B_BE_PCIPM_L12_EN BIT(16) +#define B_BE_RSM_L0S_EN BIT(8) +#define B_BE_CMAC_EXIT_L1_EN BIT(7) +#define B_BE_DMAC0_EXIT_L1_EN BIT(6) +#define B_BE_FORCE_L0 BIT(5) +#define B_BE_DBI_RO_WR_DISABLE BIT(4) +#define B_BE_SEL_XFER_PENDING BIT(3) +#define B_BE_SEL_REQ_ENTR_L1 BIT(2) +#define B_BE_PCIE_EN_SWENT_L23 BIT(1) +#define B_BE_SEL_REQ_EXIT_L1 BIT(0) + +#define R_BE_PCIE_MIX_CFG 0x300C +#define B_BE_L1SS_TIMEOUT_CTRL BIT(18) +#define B_BE_ASPM_CTRL_L1 BIT(17) +#define B_BE_ASPM_CTRL_L0 BIT(16) +#define B_BE_RTK_ASPM_CTRL_MASK GENMASK(17, 16) +#define B_BE_XFER_PENDING_FW BIT(11) +#define B_BE_XFER_PENDING BIT(10) +#define B_BE_REQ_EXIT_L1 BIT(9) +#define B_BE_REQ_ENTR_L1 BIT(8) +#define B_BE_L1SUB_ENABLE BIT(0) + +#define R_BE_L1_CLK_CTRL 0x3010 +#define B_BE_RAS_SD_HOLD_LTSSM BIT(12) +#define B_BE_CLK_REQ_N BIT(1) +#define B_BE_CLK_PM_EN BIT(0) + +#define R_BE_PCIE_LAT_CTRL 0x3044 +#define B_BE_ELBI_PHY_REMAP_MASK GENMASK(29, 24) +#define B_BE_SYS_SUS_L12_EN BIT(17) +#define B_BE_MDIO_S_EN BIT(16) +#define B_BE_SYM_AUX_CLK_SEL BIT(15) +#define B_BE_RTK_LDO_POWER_LATENCY_MASK GENMASK(11, 10) +#define B_BE_RTK_LDO_BIAS_LATENCY_MASK GENMASK(9, 8) +#define B_BE_CLK_REQ_LAT_MASK GENMASK(7, 4) +#define B_BE_RTK_PM_SEL_OPT BIT(1) +#define B_BE_CLK_REQ_SEL BIT(0) + +#define R_BE_PCIE_HIMR0 0x30B0 +#define B_BE_PCIE_HB1_IND_INTA_IMR BIT(31) +#define B_BE_PCIE_HB0_IND_INTA_IMR BIT(30) +#define B_BE_HCI_AXIDMA_INTA_IMR BIT(29) +#define B_BE_HC0_IND_INTA_IMR BIT(28) +#define B_BE_HD1_IND_INTA_IMR BIT(27) +#define B_BE_HD0_IND_INTA_IMR BIT(26) +#define B_BE_HS1_IND_INTA_IMR BIT(25) +#define B_BE_HS0_IND_INTA_IMR BIT(24) +#define B_BE_PCIE_HOTRST_INT_EN BIT(16) +#define B_BE_PCIE_FLR_INT_EN BIT(15) +#define B_BE_PCIE_PERST_INT_EN BIT(14) +#define B_BE_PCIE_DBG_STE_INT_EN BIT(13) +#define B_BE_HB1_IND_INT_EN0 BIT(9) +#define B_BE_HB0_IND_INT_EN0 BIT(8) +#define B_BE_HC1_IND_INT_EN0 BIT(7) +#define B_BE_HCI_AXIDMA_INT_EN0 BIT(5) +#define B_BE_HC0_IND_INT_EN0 BIT(4) +#define B_BE_HD1_IND_INT_EN0 BIT(3) +#define B_BE_HD0_IND_INT_EN0 BIT(2) +#define B_BE_HS1_IND_INT_EN0 BIT(1) +#define B_BE_HS0_IND_INT_EN0 BIT(0) + +#define R_BE_PCIE_HISR 0x30B4 +#define B_BE_PCIE_HOTRST_INT BIT(16) +#define B_BE_PCIE_FLR_INT BIT(15) +#define B_BE_PCIE_PERST_INT BIT(14) +#define B_BE_PCIE_DBG_STE_INT BIT(13) +#define B_BE_HB1IMR_IND BIT(9) +#define B_BE_HB0IMR_IND BIT(8) +#define B_BE_HC1ISR_IND_INT BIT(7) +#define B_BE_HCI_AXIDMA_INT BIT(5) +#define B_BE_HC0ISR_IND_INT BIT(4) +#define B_BE_HD1ISR_IND_INT BIT(3) +#define B_BE_HD0ISR_IND_INT BIT(2) +#define B_BE_HS1ISR_IND_INT BIT(1) +#define B_BE_HS0ISR_IND_INT BIT(0) + +#define R_BE_PCIE_DMA_IMR_0_V1 0x30B8 +#define B_BE_PCIE_RDU_CH7_IMR BIT(31) +#define B_BE_PCIE_RDU_CH6_IMR BIT(30) +#define B_BE_PCIE_RDU_CH5_IMR BIT(29) +#define B_BE_PCIE_RDU_CH4_IMR BIT(28) +#define B_BE_PCIE_RDU_CH3_IMR BIT(27) +#define B_BE_PCIE_RDU_CH2_IMR BIT(26) +#define B_BE_PCIE_RDU_CH1_IMR BIT(25) +#define B_BE_PCIE_RDU_CH0_IMR BIT(24) +#define B_BE_PCIE_RX_RX1P1_IMR0_V1 BIT(23) +#define B_BE_PCIE_RX_RX0P1_IMR0_V1 BIT(22) +#define B_BE_PCIE_RX_ROQ1_IMR0_V1 BIT(21) +#define B_BE_PCIE_RX_RPQ1_IMR0_V1 BIT(20) +#define B_BE_PCIE_RX_RX1P2_IMR0_V1 BIT(19) +#define B_BE_PCIE_RX_ROQ0_IMR0_V1 BIT(18) +#define B_BE_PCIE_RX_RPQ0_IMR0_V1 BIT(17) +#define B_BE_PCIE_RX_RX0P2_IMR0_V1 BIT(16) +#define B_BE_PCIE_TX_CH14_IMR0 BIT(14) +#define B_BE_PCIE_TX_CH13_IMR0 BIT(13) +#define B_BE_PCIE_TX_CH12_IMR0 BIT(12) +#define B_BE_PCIE_TX_CH11_IMR0 BIT(11) +#define B_BE_PCIE_TX_CH10_IMR0 BIT(10) +#define B_BE_PCIE_TX_CH9_IMR0 BIT(9) +#define B_BE_PCIE_TX_CH8_IMR0 BIT(8) +#define B_BE_PCIE_TX_CH7_IMR0 BIT(7) +#define B_BE_PCIE_TX_CH6_IMR0 BIT(6) +#define B_BE_PCIE_TX_CH5_IMR0 BIT(5) +#define B_BE_PCIE_TX_CH4_IMR0 BIT(4) +#define B_BE_PCIE_TX_CH3_IMR0 BIT(3) +#define B_BE_PCIE_TX_CH2_IMR0 BIT(2) +#define B_BE_PCIE_TX_CH1_IMR0 BIT(1) +#define B_BE_PCIE_TX_CH0_IMR0 BIT(0) + +#define R_BE_PCIE_DMA_ISR 0x30BC +#define B_BE_PCIE_RDU_CH7_INT BIT(31) +#define B_BE_PCIE_RDU_CH6_INT BIT(30) +#define B_BE_PCIE_RDU_CH5_INT BIT(29) +#define B_BE_PCIE_RDU_CH4_INT BIT(28) +#define B_BE_PCIE_RDU_CH3_INT BIT(27) +#define B_BE_PCIE_RDU_CH2_INT BIT(26) +#define B_BE_PCIE_RDU_CH1_INT BIT(25) +#define B_BE_PCIE_RDU_CH0_INT BIT(24) +#define B_BE_PCIE_RX_RX1P1_ISR_V1 BIT(23) +#define B_BE_PCIE_RX_RX0P1_ISR_V1 BIT(22) +#define B_BE_PCIE_RX_ROQ1_ISR_V1 BIT(21) +#define B_BE_PCIE_RX_RPQ1_ISR_V1 BIT(20) +#define B_BE_PCIE_RX_RX1P2_ISR_V1 BIT(19) +#define B_BE_PCIE_RX_ROQ0_ISR_V1 BIT(18) +#define B_BE_PCIE_RX_RPQ0_ISR_V1 BIT(17) +#define B_BE_PCIE_RX_RX0P2_ISR_V1 BIT(16) +#define B_BE_PCIE_TX_CH14_ISR BIT(14) +#define B_BE_PCIE_TX_CH13_ISR BIT(13) +#define B_BE_PCIE_TX_CH12_ISR BIT(12) +#define B_BE_PCIE_TX_CH11_ISR BIT(11) +#define B_BE_PCIE_TX_CH10_ISR BIT(10) +#define B_BE_PCIE_TX_CH9_ISR BIT(9) +#define B_BE_PCIE_TX_CH8_ISR BIT(8) +#define B_BE_PCIE_TX_CH7_ISR BIT(7) +#define B_BE_PCIE_TX_CH6_ISR BIT(6) +#define B_BE_PCIE_TX_CH5_ISR BIT(5) +#define B_BE_PCIE_TX_CH4_ISR BIT(4) +#define B_BE_PCIE_TX_CH3_ISR BIT(3) +#define B_BE_PCIE_TX_CH2_ISR BIT(2) +#define B_BE_PCIE_TX_CH1_ISR BIT(1) +#define B_BE_PCIE_TX_CH0_ISR BIT(0) + +#define R_BE_HAXI_HIMR00 0xB0B0 +#define B_BE_RDU_CH5_INT_IMR_V1 BIT(30) +#define B_BE_RDU_CH4_INT_IMR_V1 BIT(29) +#define B_BE_RDU_CH3_INT_IMR_V1 BIT(28) +#define B_BE_RDU_CH2_INT_IMR_V1 BIT(27) +#define B_BE_RDU_CH1_INT_EN_V2 BIT(27) +#define B_BE_RDU_CH1_INT_IMR_V1 BIT(26) +#define B_BE_RDU_CH0_INT_EN_V2 BIT(26) +#define B_BE_RDU_CH0_INT_IMR_V1 BIT(25) +#define B_BE_RXDMA_STUCK_INT_EN_V2 BIT(25) +#define B_BE_RXDMA_STUCK_INT_EN_V1 BIT(24) +#define B_BE_TXDMA_STUCK_INT_EN_V2 BIT(24) +#define B_BE_TXDMA_STUCK_INT_EN_V1 BIT(23) +#define B_BE_TXDMA_CH14_INT_EN_V1 BIT(22) +#define B_BE_TXDMA_CH13_INT_EN_V1 BIT(21) +#define B_BE_TXDMA_CH12_INT_EN_V1 BIT(20) +#define B_BE_TXDMA_CH11_INT_EN_V1 BIT(19) +#define B_BE_TXDMA_CH10_INT_EN_V1 BIT(18) +#define B_BE_TXDMA_CH9_INT_EN_V1 BIT(17) +#define B_BE_TXDMA_CH8_INT_EN_V1 BIT(16) +#define B_BE_TXDMA_CH7_INT_EN_V1 BIT(15) +#define B_BE_TXDMA_CH6_INT_EN_V1 BIT(14) +#define B_BE_TXDMA_CH5_INT_EN_V1 BIT(13) +#define B_BE_TXDMA_CH4_INT_EN_V1 BIT(12) +#define B_BE_TXDMA_CH3_INT_EN_V1 BIT(11) +#define B_BE_TXDMA_CH2_INT_EN_V1 BIT(10) +#define B_BE_TXDMA_CH1_INT_EN_V1 BIT(9) +#define B_BE_TXDMA_CH0_INT_EN_V1 BIT(8) +#define B_BE_RX1P1DMA_INT_EN_V1 BIT(7) +#define B_BE_RX0P1DMA_INT_EN_V1 BIT(6) +#define B_BE_RO1DMA_INT_EN BIT(5) +#define B_BE_RP1DMA_INT_EN BIT(4) +#define B_BE_RX1DMA_INT_EN BIT(3) +#define B_BE_RO0DMA_INT_EN BIT(2) +#define B_BE_RP0DMA_INT_EN BIT(1) +#define B_BE_RX0DMA_INT_EN BIT(0) + +#define R_BE_HAXI_HISR00 0xB0B4 +#define B_BE_RDU_CH5_INT_V1 BIT(30) +#define B_BE_RDU_CH4_INT_V1 BIT(29) +#define B_BE_RDU_CH3_INT_V1 BIT(28) +#define B_BE_RDU_CH2_INT_V1 BIT(27) +#define B_BE_RDU_CH1_INT_V2 BIT(27) +#define B_BE_RDU_CH1_INT_V1 BIT(26) +#define B_BE_RDU_CH0_INT_V2 BIT(26) +#define B_BE_RDU_CH0_INT_V1 BIT(25) +#define B_BE_RXDMA_STUCK_INT_V2 BIT(25) +#define B_BE_RXDMA_STUCK_INT_V1 BIT(24) +#define B_BE_TXDMA_STUCK_INT_V2 BIT(24) +#define B_BE_TXDMA_STUCK_INT_V1 BIT(23) +#define B_BE_TXDMA_CH14_INT_V1 BIT(22) +#define B_BE_TXDMA_CH13_INT_V1 BIT(21) +#define B_BE_TXDMA_CH12_INT_V1 BIT(20) +#define B_BE_TXDMA_CH11_INT_V1 BIT(19) +#define B_BE_TXDMA_CH10_INT_V1 BIT(18) +#define B_BE_TXDMA_CH9_INT_V1 BIT(17) +#define B_BE_TXDMA_CH8_INT_V1 BIT(16) +#define B_BE_TXDMA_CH7_INT_V1 BIT(15) +#define B_BE_TXDMA_CH6_INT_V1 BIT(14) +#define B_BE_TXDMA_CH5_INT_V1 BIT(13) +#define B_BE_TXDMA_CH4_INT_V1 BIT(12) +#define B_BE_TXDMA_CH3_INT_V1 BIT(11) +#define B_BE_TXDMA_CH2_INT_V1 BIT(10) +#define B_BE_TXDMA_CH1_INT_V1 BIT(9) +#define B_BE_TXDMA_CH0_INT_V1 BIT(8) +#define B_BE_RX1P1DMA_INT_V1 BIT(7) +#define B_BE_RX0P1DMA_INT_V1 BIT(6) +#define B_BE_RO1DMA_INT BIT(5) +#define B_BE_RP1DMA_INT BIT(4) +#define B_BE_RX1DMA_INT BIT(3) +#define B_BE_RO0DMA_INT BIT(2) +#define B_BE_RP0DMA_INT BIT(1) +#define B_BE_RX0DMA_INT BIT(0) + +/* TX/RX */ +#define R_AX_DRV_FW_HSK_0 0x01B0 +#define R_AX_DRV_FW_HSK_1 0x01B4 +#define R_AX_DRV_FW_HSK_2 0x01B8 +#define R_AX_DRV_FW_HSK_3 0x01BC +#define R_AX_DRV_FW_HSK_4 0x01C0 +#define R_AX_DRV_FW_HSK_5 0x01C4 +#define R_AX_DRV_FW_HSK_6 0x01C8 +#define R_AX_DRV_FW_HSK_7 0x01CC + +#define R_AX_RXQ_RXBD_IDX 0x1050 +#define R_AX_RPQ_RXBD_IDX 0x1054 +#define R_AX_ACH0_TXBD_IDX 0x1058 +#define R_AX_ACH1_TXBD_IDX 0x105C +#define R_AX_ACH2_TXBD_IDX 0x1060 +#define R_AX_ACH3_TXBD_IDX 0x1064 +#define R_AX_ACH4_TXBD_IDX 0x1068 +#define R_AX_ACH5_TXBD_IDX 0x106C +#define R_AX_ACH6_TXBD_IDX 0x1070 +#define R_AX_ACH7_TXBD_IDX 0x1074 +#define R_AX_CH8_TXBD_IDX 0x1078 /* Management Queue band 0 */ +#define R_AX_CH9_TXBD_IDX 0x107C /* HI Queue band 0 */ +#define R_AX_CH10_TXBD_IDX 0x137C /* Management Queue band 1 */ +#define R_AX_CH11_TXBD_IDX 0x1380 /* HI Queue band 1 */ +#define R_AX_CH12_TXBD_IDX 0x1080 /* FWCMD Queue */ +#define R_AX_CH10_TXBD_IDX_V1 0x11D0 +#define R_AX_CH11_TXBD_IDX_V1 0x11D4 +#define R_AX_RXQ_RXBD_IDX_V1 0x1218 +#define R_AX_RPQ_RXBD_IDX_V1 0x121C +#define TXBD_HW_IDX_MASK GENMASK(27, 16) +#define TXBD_HOST_IDX_MASK GENMASK(11, 0) + +#define R_AX_ACH0_TXBD_DESA_L 0x1110 +#define R_AX_ACH0_TXBD_DESA_H 0x1114 +#define R_AX_ACH1_TXBD_DESA_L 0x1118 +#define R_AX_ACH1_TXBD_DESA_H 0x111C +#define R_AX_ACH2_TXBD_DESA_L 0x1120 +#define R_AX_ACH2_TXBD_DESA_H 0x1124 +#define R_AX_ACH3_TXBD_DESA_L 0x1128 +#define R_AX_ACH3_TXBD_DESA_H 0x112C +#define R_AX_ACH4_TXBD_DESA_L 0x1130 +#define R_AX_ACH4_TXBD_DESA_H 0x1134 +#define R_AX_ACH5_TXBD_DESA_L 0x1138 +#define R_AX_ACH5_TXBD_DESA_H 0x113C +#define R_AX_ACH6_TXBD_DESA_L 0x1140 +#define R_AX_ACH6_TXBD_DESA_H 0x1144 +#define R_AX_ACH7_TXBD_DESA_L 0x1148 +#define R_AX_ACH7_TXBD_DESA_H 0x114C +#define R_AX_CH8_TXBD_DESA_L 0x1150 +#define R_AX_CH8_TXBD_DESA_H 0x1154 +#define R_AX_CH9_TXBD_DESA_L 0x1158 +#define R_AX_CH9_TXBD_DESA_H 0x115C +#define R_AX_CH10_TXBD_DESA_L 0x1358 +#define R_AX_CH10_TXBD_DESA_H 0x135C +#define R_AX_CH11_TXBD_DESA_L 0x1360 +#define R_AX_CH11_TXBD_DESA_H 0x1364 +#define R_AX_CH12_TXBD_DESA_L 0x1160 +#define R_AX_CH12_TXBD_DESA_H 0x1164 +#define R_AX_RXQ_RXBD_DESA_L 0x1100 +#define R_AX_RXQ_RXBD_DESA_H 0x1104 +#define R_AX_RPQ_RXBD_DESA_L 0x1108 +#define R_AX_RPQ_RXBD_DESA_H 0x110C +#define R_AX_RXQ_RXBD_DESA_L_V1 0x1220 +#define R_AX_RXQ_RXBD_DESA_H_V1 0x1224 +#define R_AX_RPQ_RXBD_DESA_L_V1 0x1228 +#define R_AX_RPQ_RXBD_DESA_H_V1 0x122C +#define R_AX_ACH0_TXBD_DESA_L_V1 0x1230 +#define R_AX_ACH0_TXBD_DESA_H_V1 0x1234 +#define R_AX_ACH1_TXBD_DESA_L_V1 0x1238 +#define R_AX_ACH1_TXBD_DESA_H_V1 0x123C +#define R_AX_ACH2_TXBD_DESA_L_V1 0x1240 +#define R_AX_ACH2_TXBD_DESA_H_V1 0x1244 +#define R_AX_ACH3_TXBD_DESA_L_V1 0x1248 +#define R_AX_ACH3_TXBD_DESA_H_V1 0x124C +#define R_AX_ACH4_TXBD_DESA_L_V1 0x1250 +#define R_AX_ACH4_TXBD_DESA_H_V1 0x1254 +#define R_AX_ACH5_TXBD_DESA_L_V1 0x1258 +#define R_AX_ACH5_TXBD_DESA_H_V1 0x125C +#define R_AX_ACH6_TXBD_DESA_L_V1 0x1260 +#define R_AX_ACH6_TXBD_DESA_H_V1 0x1264 +#define R_AX_ACH7_TXBD_DESA_L_V1 0x1268 +#define R_AX_ACH7_TXBD_DESA_H_V1 0x126C +#define R_AX_CH8_TXBD_DESA_L_V1 0x1270 +#define R_AX_CH8_TXBD_DESA_H_V1 0x1274 +#define R_AX_CH9_TXBD_DESA_L_V1 0x1278 +#define R_AX_CH9_TXBD_DESA_H_V1 0x127C +#define R_AX_CH12_TXBD_DESA_L_V1 0x1280 +#define R_AX_CH12_TXBD_DESA_H_V1 0x1284 +#define R_AX_CH10_TXBD_DESA_L_V1 0x1458 +#define R_AX_CH10_TXBD_DESA_H_V1 0x145C +#define R_AX_CH11_TXBD_DESA_L_V1 0x1460 +#define R_AX_CH11_TXBD_DESA_H_V1 0x1464 +#define B_AX_DESC_NUM_MSK GENMASK(11, 0) + +#define R_AX_RXQ_RXBD_NUM 0x1020 +#define R_AX_RPQ_RXBD_NUM 0x1022 +#define R_AX_ACH0_TXBD_NUM 0x1024 +#define R_AX_ACH1_TXBD_NUM 0x1026 +#define R_AX_ACH2_TXBD_NUM 0x1028 +#define R_AX_ACH3_TXBD_NUM 0x102A +#define R_AX_ACH4_TXBD_NUM 0x102C +#define R_AX_ACH5_TXBD_NUM 0x102E +#define R_AX_ACH6_TXBD_NUM 0x1030 +#define R_AX_ACH7_TXBD_NUM 0x1032 +#define R_AX_CH8_TXBD_NUM 0x1034 +#define R_AX_CH9_TXBD_NUM 0x1036 +#define R_AX_CH10_TXBD_NUM 0x1338 +#define R_AX_CH11_TXBD_NUM 0x133A +#define R_AX_CH12_TXBD_NUM 0x1038 +#define R_AX_RXQ_RXBD_NUM_V1 0x1210 +#define R_AX_RPQ_RXBD_NUM_V1 0x1212 +#define R_AX_CH10_TXBD_NUM_V1 0x1438 +#define R_AX_CH11_TXBD_NUM_V1 0x143A + +#define R_AX_ACH0_BDRAM_CTRL 0x1200 +#define R_AX_ACH1_BDRAM_CTRL 0x1204 +#define R_AX_ACH2_BDRAM_CTRL 0x1208 +#define R_AX_ACH3_BDRAM_CTRL 0x120C +#define R_AX_ACH4_BDRAM_CTRL 0x1210 +#define R_AX_ACH5_BDRAM_CTRL 0x1214 +#define R_AX_ACH6_BDRAM_CTRL 0x1218 +#define R_AX_ACH7_BDRAM_CTRL 0x121C +#define R_AX_CH8_BDRAM_CTRL 0x1220 +#define R_AX_CH9_BDRAM_CTRL 0x1224 +#define R_AX_CH10_BDRAM_CTRL 0x1320 +#define R_AX_CH11_BDRAM_CTRL 0x1324 +#define R_AX_CH12_BDRAM_CTRL 0x1228 +#define R_AX_ACH0_BDRAM_CTRL_V1 0x1300 +#define R_AX_ACH1_BDRAM_CTRL_V1 0x1304 +#define R_AX_ACH2_BDRAM_CTRL_V1 0x1308 +#define R_AX_ACH3_BDRAM_CTRL_V1 0x130C +#define R_AX_ACH4_BDRAM_CTRL_V1 0x1310 +#define R_AX_ACH5_BDRAM_CTRL_V1 0x1314 +#define R_AX_ACH6_BDRAM_CTRL_V1 0x1318 +#define R_AX_ACH7_BDRAM_CTRL_V1 0x131C +#define R_AX_CH8_BDRAM_CTRL_V1 0x1320 +#define R_AX_CH9_BDRAM_CTRL_V1 0x1324 +#define R_AX_CH12_BDRAM_CTRL_V1 0x1328 +#define R_AX_CH10_BDRAM_CTRL_V1 0x1420 +#define R_AX_CH11_BDRAM_CTRL_V1 0x1424 +#define BDRAM_SIDX_MASK GENMASK(7, 0) +#define BDRAM_MAX_MASK GENMASK(15, 8) +#define BDRAM_MIN_MASK GENMASK(23, 16) + +#define R_AX_PCIE_INIT_CFG1 0x1000 +#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) +#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) +#define B_AX_PCIE_PERST_KEEP_REG BIT(21) +#define B_AX_PCIE_FLR_KEEP_REG BIT(20) +#define B_AX_PCIE_TRAIN_KEEP_REG BIT(19) +#define B_AX_RXBD_MODE BIT(18) +#define B_AX_PCIE_MAX_RXDMA_MASK GENMASK(16, 14) +#define B_AX_RXHCI_EN BIT(13) +#define B_AX_LATENCY_CONTROL BIT(12) +#define B_AX_TXHCI_EN BIT(11) +#define B_AX_PCIE_MAX_TXDMA_MASK GENMASK(10, 8) +#define B_AX_TX_TRUNC_MODE BIT(5) +#define B_AX_RX_TRUNC_MODE BIT(4) +#define B_AX_RST_BDRAM BIT(3) +#define B_AX_DIS_RXDMA_PRE BIT(2) + +#define R_AX_TXDMA_ADDR_H 0x10F0 +#define R_AX_RXDMA_ADDR_H 0x10F4 + +#define R_AX_PCIE_DMA_STOP1 0x1010 +#define B_AX_STOP_PCIEIO BIT(20) +#define B_AX_STOP_WPDMA BIT(19) +#define B_AX_STOP_CH12 BIT(18) +#define B_AX_STOP_CH9 BIT(17) +#define B_AX_STOP_CH8 BIT(16) +#define B_AX_STOP_ACH7 BIT(15) +#define B_AX_STOP_ACH6 BIT(14) +#define B_AX_STOP_ACH5 BIT(13) +#define B_AX_STOP_ACH4 BIT(12) +#define B_AX_STOP_ACH3 BIT(11) +#define B_AX_STOP_ACH2 BIT(10) +#define B_AX_STOP_ACH1 BIT(9) +#define B_AX_STOP_ACH0 BIT(8) +#define B_AX_STOP_RPQ BIT(1) +#define B_AX_STOP_RXQ BIT(0) +#define B_AX_TX_STOP1_ALL GENMASK(18, 8) +#define B_AX_TX_STOP1_MASK (B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | \ + B_AX_STOP_ACH2 | B_AX_STOP_ACH3 | \ + B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | \ + B_AX_STOP_ACH6 | B_AX_STOP_ACH7 | \ + B_AX_STOP_CH8 | B_AX_STOP_CH9 | \ + B_AX_STOP_CH12) +#define B_AX_TX_STOP1_MASK_V1 (B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | \ + B_AX_STOP_ACH2 | B_AX_STOP_ACH3 | \ + B_AX_STOP_CH8 | B_AX_STOP_CH9 | \ + B_AX_STOP_CH12) + +#define R_AX_PCIE_DMA_STOP2 0x1310 +#define B_AX_STOP_CH11 BIT(1) +#define B_AX_STOP_CH10 BIT(0) +#define B_AX_TX_STOP2_ALL GENMASK(1, 0) + +#define R_AX_TXBD_RWPTR_CLR1 0x1014 +#define B_AX_CLR_CH12_IDX BIT(10) +#define B_AX_CLR_CH9_IDX BIT(9) +#define B_AX_CLR_CH8_IDX BIT(8) +#define B_AX_CLR_ACH7_IDX BIT(7) +#define B_AX_CLR_ACH6_IDX BIT(6) +#define B_AX_CLR_ACH5_IDX BIT(5) +#define B_AX_CLR_ACH4_IDX BIT(4) +#define B_AX_CLR_ACH3_IDX BIT(3) +#define B_AX_CLR_ACH2_IDX BIT(2) +#define B_AX_CLR_ACH1_IDX BIT(1) +#define B_AX_CLR_ACH0_IDX BIT(0) +#define B_AX_TXBD_CLR1_ALL GENMASK(10, 0) + +#define R_AX_RXBD_RWPTR_CLR 0x1018 +#define B_AX_CLR_RPQ_IDX BIT(1) +#define B_AX_CLR_RXQ_IDX BIT(0) +#define B_AX_RXBD_CLR_ALL GENMASK(1, 0) + +#define R_AX_TXBD_RWPTR_CLR2 0x1314 +#define B_AX_CLR_CH11_IDX BIT(1) +#define B_AX_CLR_CH10_IDX BIT(0) +#define B_AX_TXBD_CLR2_ALL GENMASK(1, 0) + +#define R_AX_PCIE_DMA_BUSY1 0x101C +#define B_AX_PCIEIO_RX_BUSY BIT(22) +#define B_AX_PCIEIO_TX_BUSY BIT(21) +#define B_AX_PCIEIO_BUSY BIT(20) +#define B_AX_WPDMA_BUSY BIT(19) +#define B_AX_CH12_BUSY BIT(18) +#define B_AX_CH9_BUSY BIT(17) +#define B_AX_CH8_BUSY BIT(16) +#define B_AX_ACH7_BUSY BIT(15) +#define B_AX_ACH6_BUSY BIT(14) +#define B_AX_ACH5_BUSY BIT(13) +#define B_AX_ACH4_BUSY BIT(12) +#define B_AX_ACH3_BUSY BIT(11) +#define B_AX_ACH2_BUSY BIT(10) +#define B_AX_ACH1_BUSY BIT(9) +#define B_AX_ACH0_BUSY BIT(8) +#define B_AX_RPQ_BUSY BIT(1) +#define B_AX_RXQ_BUSY BIT(0) +#define DMA_BUSY1_CHECK (B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY | \ + B_AX_ACH3_BUSY | B_AX_ACH4_BUSY | B_AX_ACH5_BUSY | \ + B_AX_ACH6_BUSY | B_AX_ACH7_BUSY | B_AX_CH8_BUSY | \ + B_AX_CH9_BUSY | B_AX_CH12_BUSY) +#define DMA_BUSY1_CHECK_V1 (B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY | \ + B_AX_ACH3_BUSY | B_AX_CH8_BUSY | B_AX_CH9_BUSY | \ + B_AX_CH12_BUSY) + +#define R_AX_PCIE_DMA_BUSY2 0x131C +#define B_AX_CH11_BUSY BIT(1) +#define B_AX_CH10_BUSY BIT(0) + +#define R_AX_WP_ADDR_H_SEL0_3 0x1334 +#define R_AX_WP_ADDR_H_SEL4_7 0x1338 +#define R_AX_WP_ADDR_H_SEL8_11 0x133C +#define R_AX_WP_ADDR_H_SEL12_15 0x1340 + +#define R_BE_CH0_TXBD_NUM_V1 0xB030 +#define R_BE_CH1_TXBD_NUM_V1 0xB032 +#define R_BE_CH2_TXBD_NUM_V1 0xB034 +#define R_BE_CH3_TXBD_NUM_V1 0xB036 +#define R_BE_CH4_TXBD_NUM_V1 0xB038 +#define R_BE_CH5_TXBD_NUM_V1 0xB03A +#define R_BE_CH6_TXBD_NUM_V1 0xB03C +#define R_BE_CH7_TXBD_NUM_V1 0xB03E +#define R_BE_CH8_TXBD_NUM_V1 0xB040 +#define R_BE_CH9_TXBD_NUM_V1 0xB042 +#define R_BE_CH10_TXBD_NUM_V1 0xB044 +#define R_BE_CH11_TXBD_NUM_V1 0xB046 +#define R_BE_CH12_TXBD_NUM_V1 0xB048 +#define R_BE_CH13_TXBD_NUM_V1 0xB04C +#define R_BE_CH14_TXBD_NUM_V1 0xB04E + +#define R_BE_CH0_TXBD_CFG 0xB030 +#define R_BE_CH2_TXBD_CFG 0xB034 +#define R_BE_CH4_TXBD_CFG 0xB038 +#define R_BE_CH6_TXBD_CFG 0xB03C +#define R_BE_CH8_TXBD_CFG 0xB040 +#define R_BE_CH10_TXBD_CFG 0xB044 +#define R_BE_CH12_TXBD_CFG 0xB048 +#define B_BE_TX_FLAG BIT(14) +#define B_BE_TX_START_OFFSET_MASK GENMASK(12, 4) +#define B_BE_TX_NUM_SEL_MASK GENMASK(2, 0) + +#define R_BE_RXQ0_RXBD_NUM_V1 0xB050 +#define R_BE_RPQ0_RXBD_NUM_V1 0xB052 + +#define R_BE_RX_CH0_RXBD_CONFIG 0xB050 +#define R_BE_RX_CH1_RXBD_CONFIG 0xB052 +#define B_BE_RX_START_OFFSET_MASK GENMASK(11, 4) +#define B_BE_RX_NUM_SEL_MASK GENMASK(2, 0) + +#define R_BE_CH0_TXBD_IDX_V1 0xB100 +#define R_BE_CH1_TXBD_IDX_V1 0xB104 +#define R_BE_CH2_TXBD_IDX_V1 0xB108 +#define R_BE_CH3_TXBD_IDX_V1 0xB10C +#define R_BE_CH4_TXBD_IDX_V1 0xB110 +#define R_BE_CH5_TXBD_IDX_V1 0xB114 +#define R_BE_CH6_TXBD_IDX_V1 0xB118 +#define R_BE_CH7_TXBD_IDX_V1 0xB11C +#define R_BE_CH8_TXBD_IDX_V1 0xB120 +#define R_BE_CH9_TXBD_IDX_V1 0xB124 +#define R_BE_CH10_TXBD_IDX_V1 0xB128 +#define R_BE_CH11_TXBD_IDX_V1 0xB12C +#define R_BE_CH12_TXBD_IDX_V1 0xB130 +#define R_BE_CH13_TXBD_IDX_V1 0xB134 +#define R_BE_CH14_TXBD_IDX_V1 0xB138 + +#define R_BE_RXQ0_RXBD_IDX_V1 0xB160 +#define R_BE_RPQ0_RXBD_IDX_V1 0xB164 + +#define R_BE_CH0_TXBD_DESA_L_V1 0xB200 +#define R_BE_CH0_TXBD_DESA_H_V1 0xB204 +#define R_BE_CH1_TXBD_DESA_L_V1 0xB208 +#define R_BE_CH1_TXBD_DESA_H_V1 0xB20C +#define R_BE_CH2_TXBD_DESA_L_V1 0xB210 +#define R_BE_CH2_TXBD_DESA_H_V1 0xB214 +#define R_BE_CH3_TXBD_DESA_L_V1 0xB218 +#define R_BE_CH3_TXBD_DESA_H_V1 0xB21C +#define R_BE_CH4_TXBD_DESA_L_V1 0xB220 +#define R_BE_CH4_TXBD_DESA_H_V1 0xB224 +#define R_BE_CH5_TXBD_DESA_L_V1 0xB228 +#define R_BE_CH5_TXBD_DESA_H_V1 0xB22C +#define R_BE_CH6_TXBD_DESA_L_V1 0xB230 +#define R_BE_CH6_TXBD_DESA_H_V1 0xB234 +#define R_BE_CH7_TXBD_DESA_L_V1 0xB238 +#define R_BE_CH7_TXBD_DESA_H_V1 0xB23C +#define R_BE_CH8_TXBD_DESA_L_V1 0xB240 +#define R_BE_CH8_TXBD_DESA_H_V1 0xB244 +#define R_BE_CH9_TXBD_DESA_L_V1 0xB248 +#define R_BE_CH9_TXBD_DESA_H_V1 0xB24C +#define R_BE_CH10_TXBD_DESA_L_V1 0xB250 +#define R_BE_CH10_TXBD_DESA_H_V1 0xB254 +#define R_BE_CH11_TXBD_DESA_L_V1 0xB258 +#define R_BE_CH11_TXBD_DESA_H_V1 0xB25C +#define R_BE_CH12_TXBD_DESA_L_V1 0xB260 +#define R_BE_CH12_TXBD_DESA_H_V1 0xB264 +#define R_BE_CH13_TXBD_DESA_L_V1 0xB268 +#define R_BE_CH13_TXBD_DESA_H_V1 0xB26C +#define R_BE_CH14_TXBD_DESA_L_V1 0xB270 +#define R_BE_CH14_TXBD_DESA_H_V1 0xB274 + +#define R_BE_ACQ_TXBD_DESA_L 0xB200 +#define B_BE_TX_ACQ_DESA_L_MASK GENMASK(31, 3) +#define R_BE_ACQ_TXBD_DESA_H 0xB204 +#define B_BE_TX_ACQ_DESA_H_MASK GENMASK(7, 0) +#define R_BE_NACQ_TXBD_DESA_L 0xB240 +#define B_BE_TX_NACQ_DESA_L_MASK GENMASK(31, 3) +#define R_BE_NACQ_TXBD_DESA_H 0xB244 +#define B_BE_TX_NACQ_DESA_H_MASK GENMASK(7, 0) + +#define R_BE_RXQ0_RXBD_DESA_L_V1 0xB300 +#define R_BE_RXQ0_RXBD_DESA_H_V1 0xB304 +#define R_BE_RPQ0_RXBD_DESA_L_V1 0xB308 +#define R_BE_RPQ0_RXBD_DESA_H_V1 0xB30C + +#define R_BE_HOST0_RXBD_DESA_L 0xB300 +#define B_BE_RX_HOST0_DESA_L_MASK GENMASK(31, 3) +#define R_BE_HOST0_RXBD_DESA_H 0xB304 +#define B_BE_RX_HOST0_DESA_H_MASK GENMASK(7, 0) + +#define R_BE_WP_ADDR_H_SEL0_3_V1 0xB420 +#define R_BE_WP_ADDR_H_SEL4_7_V1 0xB424 +#define R_BE_WP_ADDR_H_SEL8_11_V1 0xB428 +#define R_BE_WP_ADDR_H_SEL12_15_V1 0xB42C + +/* Configure */ +#define R_AX_PCIE_INIT_CFG2 0x1004 +#define B_AX_WD_ITVL_IDLE GENMASK(27, 24) +#define B_AX_WD_ITVL_ACT GENMASK(19, 16) +#define B_AX_PCIE_RX_APPLEN_MASK GENMASK(13, 0) + +#define R_AX_PCIE_PS_CTRL 0x1008 +#define B_AX_L1OFF_PWR_OFF_EN BIT(5) + +#define R_AX_INT_MIT_RX 0x10D4 +#define B_AX_RXMIT_RXP2_SEL BIT(19) +#define B_AX_RXMIT_RXP1_SEL BIT(18) +#define B_AX_RXTIMER_UNIT_MASK GENMASK(17, 16) +#define AX_RXTIMER_UNIT_64US 0 +#define AX_RXTIMER_UNIT_128US 1 +#define AX_RXTIMER_UNIT_256US 2 +#define AX_RXTIMER_UNIT_512US 3 +#define B_AX_RXCOUNTER_MATCH_MASK GENMASK(15, 8) +#define B_AX_RXTIMER_MATCH_MASK GENMASK(7, 0) + +#define R_AX_DBG_ERR_FLAG_V1 0x1104 + +#define R_AX_INT_MIT_RX_V1 0x1184 +#define B_AX_RXMIT_RXP2_SEL_V1 BIT(19) +#define B_AX_RXMIT_RXP1_SEL_V1 BIT(18) +#define B_AX_MIT_RXTIMER_UNIT_MASK GENMASK(17, 16) +#define B_AX_MIT_RXCOUNTER_MATCH_MASK GENMASK(15, 8) +#define B_AX_MIT_RXTIMER_MATCH_MASK GENMASK(7, 0) + +#define R_AX_DBG_ERR_FLAG 0x11C4 +#define B_AX_PCIE_RPQ_FULL BIT(29) +#define B_AX_PCIE_RXQ_FULL BIT(28) +#define B_AX_CPL_STATUS_MASK GENMASK(27, 25) +#define B_AX_RX_STUCK BIT(22) +#define B_AX_TX_STUCK BIT(21) +#define B_AX_PCIEDBG_TXERR0 BIT(16) +#define B_AX_PCIE_RXP1_ERR0 BIT(4) +#define B_AX_PCIE_TXBD_LEN0 BIT(1) +#define B_AX_PCIE_TXBD_4KBOUD_LENERR BIT(0) + +#define R_AX_TXBD_RWPTR_CLR2_V1 0x11C4 +#define B_AX_CLR_CH11_IDX BIT(1) +#define B_AX_CLR_CH10_IDX BIT(0) + +#define R_AX_LBC_WATCHDOG 0x11D8 +#define B_AX_LBC_TIMER GENMASK(7, 4) +#define B_AX_LBC_FLAG BIT(1) +#define B_AX_LBC_EN BIT(0) + +#define R_AX_RXBD_RWPTR_CLR_V1 0x1200 +#define B_AX_CLR_RPQ_IDX BIT(1) +#define B_AX_CLR_RXQ_IDX BIT(0) + +#define R_AX_HAXI_EXP_CTRL 0x1204 +#define B_AX_MAX_TAG_NUM_V1_MASK GENMASK(2, 0) + +#define R_AX_PCIE_EXP_CTRL 0x13F0 +#define B_AX_EN_CHKDSC_NO_RX_STUCK BIT(20) +#define B_AX_MAX_TAG_NUM GENMASK(18, 16) +#define B_AX_SIC_EN_FORCE_CLKREQ BIT(4) + +#define R_AX_PCIE_RX_PREF_ADV 0x13F4 +#define B_AX_RXDMA_PREF_ADV_EN BIT(0) + +#define R_AX_PCIE_HRPWM_V1 0x30C0 +#define R_AX_PCIE_CRPWM 0x30C4 + +#define R_AX_LBC_WATCHDOG_V1 0x30D8 + +#define R_BE_PCIE_HRPWM 0x30C0 +#define R_BE_PCIE_CRPWM 0x30C4 + +#define R_BE_PCIE_HCI2FW_ISR 0x30CC + +#define R_BE_L1_2_CTRL_HCILDO 0x3110 +#define B_BE_PM_CLKREQ_EXT_RB BIT(11) +#define B_BE_PCIE_DIS_RTK_PRST_N_L1_2 BIT(10) +#define B_BE_PCIE_PRST_IN_L1_2_RB BIT(9) +#define B_BE_PCIE_PRST_SEL_RB_V1 BIT(8) +#define B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB BIT(7) +#define B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB BIT(6) +#define B_BE_PCIE_DIS_L1_2_CTRL_HCILDO BIT(0) + +#define R_BE_PL1_DBG_INFO 0x3120 +#define B_BE_END_PL1_CNT_MASK GENMASK(23, 16) +#define B_BE_START_PL1_CNT_MASK GENMASK(7, 0) + +#define R_BE_PCIE_MIT0_TMR 0x3330 +#define B_BE_PCIE_MIT0_RX_TMR_MASK GENMASK(5, 4) +#define BE_MIT0_TMR_UNIT_1MS 0 +#define BE_MIT0_TMR_UNIT_2MS 1 +#define BE_MIT0_TMR_UNIT_4MS 2 +#define BE_MIT0_TMR_UNIT_8MS 3 +#define B_BE_PCIE_MIT0_TX_TMR_MASK GENMASK(1, 0) + +#define R_BE_PCIE_MIT0_CNT 0x3334 +#define B_BE_PCIE_RX_MIT0_CNT_MASK GENMASK(31, 24) +#define B_BE_PCIE_TX_MIT0_CNT_MASK GENMASK(23, 16) +#define B_BE_PCIE_RX_MIT0_TMR_CNT_MASK GENMASK(15, 8) +#define B_BE_PCIE_TX_MIT0_TMR_CNT_MASK GENMASK(7, 0) + +#define R_BE_PCIE_MIT_CH_EN 0x3338 +#define B_BE_PCIE_MIT_RX1P1_EN BIT(23) +#define B_BE_PCIE_MIT_RX0P1_EN BIT(22) +#define B_BE_PCIE_MIT_ROQ1_EN BIT(21) +#define B_BE_PCIE_MIT_RPQ1_EN BIT(20) +#define B_BE_PCIE_MIT_RX1P2_EN BIT(19) +#define B_BE_PCIE_MIT_ROQ0_EN BIT(18) +#define B_BE_PCIE_MIT_RPQ0_EN BIT(17) +#define B_BE_PCIE_MIT_RX0P2_EN BIT(16) +#define B_BE_PCIE_MIT_TXCH14_EN BIT(14) +#define B_BE_PCIE_MIT_TXCH13_EN BIT(13) +#define B_BE_PCIE_MIT_TXCH12_EN BIT(12) +#define B_BE_PCIE_MIT_TXCH11_EN BIT(11) +#define B_BE_PCIE_MIT_TXCH10_EN BIT(10) +#define B_BE_PCIE_MIT_TXCH9_EN BIT(9) +#define B_BE_PCIE_MIT_TXCH8_EN BIT(8) +#define B_BE_PCIE_MIT_TXCH7_EN BIT(7) +#define B_BE_PCIE_MIT_TXCH6_EN BIT(6) +#define B_BE_PCIE_MIT_TXCH5_EN BIT(5) +#define B_BE_PCIE_MIT_TXCH4_EN BIT(4) +#define B_BE_PCIE_MIT_TXCH3_EN BIT(3) +#define B_BE_PCIE_MIT_TXCH2_EN BIT(2) +#define B_BE_PCIE_MIT_TXCH1_EN BIT(1) +#define B_BE_PCIE_MIT_TXCH0_EN BIT(0) + +#define R_BE_SER_PL1_CTRL 0x34A8 +#define B_BE_PL1_SER_PL1_EN BIT(31) +#define B_BE_PL1_IGNORE_HOT_RST BIT(30) +#define B_BE_PL1_TIMER_UNIT_MASK GENMASK(19, 17) +#define PCIE_SER_TIMER_UNIT 0x2 +#define PCIE_SER_WOW_TIMER_UNIT 0x7 +#define B_BE_PL1_TIMER_CLEAR BIT(0) + +#define R_BE_REG_PL1_MASK 0x34B0 +#define B_BE_SER_LTSSM_UNSTABLE_MASK BIT(6) +#define B_BE_SER_PCLKREQ_ACK_MASK BIT(5) +#define B_BE_SER_PM_CLK_MASK BIT(4) +#define B_BE_SER_LTSSM_IMR BIT(3) +#define B_BE_SER_PM_MASTER_IMR BIT(2) +#define B_BE_SER_L1SUB_IMR BIT(1) +#define B_BE_SER_PMU_IMR BIT(0) + +#define R_BE_REG_PL1_ISR 0x34B4 +#define B_PCIE_SER_ALL_ISR 0x7F + +#define R_BE_RX_APPEND_MODE 0x8920 +#define B_BE_APPEND_OFFSET_MASK GENMASK(23, 16) +#define B_BE_APPEND_LEN_MASK GENMASK(15, 0) + +#define R_BE_TXBD_RWPTR_CLR1 0xB014 +#define B_BE_CLR_CH14_IDX BIT(14) +#define B_BE_CLR_CH13_IDX BIT(13) +#define B_BE_CLR_CH12_IDX BIT(12) +#define B_BE_CLR_CH11_IDX BIT(11) +#define B_BE_CLR_CH10_IDX BIT(10) +#define B_BE_CLR_CH9_IDX BIT(9) +#define B_BE_CLR_CH8_IDX BIT(8) +#define B_BE_CLR_CH7_IDX BIT(7) +#define B_BE_CLR_CH6_IDX BIT(6) +#define B_BE_CLR_CH5_IDX BIT(5) +#define B_BE_CLR_CH4_IDX BIT(4) +#define B_BE_CLR_CH3_IDX BIT(3) +#define B_BE_CLR_CH2_IDX BIT(2) +#define B_BE_CLR_CH1_IDX BIT(1) +#define B_BE_CLR_CH0_IDX BIT(0) +#define B_BE_CLR_ALL_IDX_MASK (B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | \ + B_BE_CLR_CH2_IDX | B_BE_CLR_CH3_IDX | \ + B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX | \ + B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | \ + B_BE_CLR_CH8_IDX | B_BE_CLR_CH9_IDX | \ + B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX | \ + B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | \ + B_BE_CLR_CH14_IDX) +#define B_BE_CLR_ALL_IDX_MASK_V1 (B_BE_CLR_CH0_IDX | B_BE_CLR_CH2_IDX | \ + B_BE_CLR_CH4_IDX | B_BE_CLR_CH6_IDX | \ + B_BE_CLR_CH8_IDX | B_BE_CLR_CH10_IDX | \ + B_BE_CLR_CH12_IDX) + +#define R_BE_RXBD_RWPTR_CLR1_V1 0xB018 +#define B_BE_CLR_ROQ1_IDX_V1 BIT(5) +#define B_BE_CLR_RPQ1_IDX_V1 BIT(4) +#define B_BE_CLR_RXQ1_IDX_V1 BIT(3) +#define B_BE_CLR_ROQ0_IDX BIT(2) +#define B_BE_CLR_RPQ0_IDX BIT(1) +#define B_BE_CLR_RXQ0_IDX BIT(0) + +#define R_BE_HAXI_DMA_BUSY1 0xB01C +#define B_BE_HAXI_MST_BUSY BIT(31) +#define B_BE_HAXI_RX_IDLE BIT(25) +#define B_BE_HAXI_TX_IDLE BIT(24) +#define B_BE_ROQ1_BUSY_V1 BIT(21) +#define B_BE_RPQ1_BUSY_V1 BIT(20) +#define B_BE_RXQ1_BUSY_V1 BIT(19) +#define B_BE_ROQ0_BUSY_V1 BIT(18) +#define B_BE_RPQ0_BUSY_V1 BIT(17) +#define B_BE_RXQ0_BUSY_V1 BIT(16) +#define B_BE_WPDMA_BUSY BIT(15) +#define B_BE_CH14_BUSY BIT(14) +#define B_BE_CH13_BUSY BIT(13) +#define B_BE_CH12_BUSY BIT(12) +#define B_BE_CH11_BUSY BIT(11) +#define B_BE_CH10_BUSY BIT(10) +#define B_BE_CH9_BUSY BIT(9) +#define B_BE_CH8_BUSY BIT(8) +#define B_BE_CH7_BUSY BIT(7) +#define B_BE_CH6_BUSY BIT(6) +#define B_BE_CH5_BUSY BIT(5) +#define B_BE_CH4_BUSY BIT(4) +#define B_BE_CH3_BUSY BIT(3) +#define B_BE_CH2_BUSY BIT(2) +#define B_BE_CH1_BUSY BIT(1) +#define B_BE_CH0_BUSY BIT(0) +#define DMA_BUSY1_CHECK_BE (B_BE_CH0_BUSY | B_BE_CH1_BUSY | B_BE_CH2_BUSY | \ + B_BE_CH3_BUSY | B_BE_CH4_BUSY | B_BE_CH5_BUSY | \ + B_BE_CH6_BUSY | B_BE_CH7_BUSY | B_BE_CH8_BUSY | \ + B_BE_CH9_BUSY | B_BE_CH10_BUSY | B_BE_CH11_BUSY | \ + B_BE_CH12_BUSY | B_BE_CH13_BUSY | B_BE_CH14_BUSY) +#define DMA_BUSY1_CHECK_BE_V1 (B_BE_CH0_BUSY | B_BE_CH2_BUSY | B_BE_CH4_BUSY | \ + B_BE_CH6_BUSY | B_BE_CH8_BUSY | B_BE_CH10_BUSY | \ + B_BE_CH12_BUSY) + +#define R_BE_HAXI_EXP_CTRL_V1 0xB020 +#define B_BE_R_NO_SEC_ACCESS BIT(31) +#define B_BE_FORCE_EN_DMA_RX_GCLK BIT(5) +#define B_BE_FORCE_EN_DMA_TX_GCLK BIT(4) +#define B_BE_MAX_TAG_NUM_MASK GENMASK(3, 0) + +#define RTW89_PCI_TXBD_NUM_MAX 256 +#define RTW89_PCI_RXBD_NUM_MAX 256 +#define RTW89_PCI_TXWD_NUM_MAX 512 +#define RTW89_PCI_TXWD_PAGE_SIZE 128 +#define RTW89_PCI_ADDRINFO_MAX 4 +/* +40 for rtw89_rxdesc_long_v2; +4 for rtw89_pci_rxbd_info */ +#define RTW89_PCI_RX_BUF_SIZE (11454 + 40 + 4) + +#define RTW89_PCI_POLL_BDRAM_RST_CNT 100 +#define RTW89_PCI_MULTITAG 8 + +/* PCIE CFG register */ +#define RTW89_PCIE_CAPABILITY_SPEED 0x7C +#define RTW89_PCIE_SUPPORT_GEN_MASK GENMASK(3, 0) +#define RTW89_PCIE_L1_STS_V1 0x80 +#define RTW89_BCFG_LINK_SPEED_MASK GENMASK(19, 16) +#define RTW89_PCIE_GEN1_SPEED 0x01 +#define RTW89_PCIE_GEN2_SPEED 0x02 +#define RTW89_PCIE_PHY_RATE 0x82 +#define RTW89_PCIE_EXTENDED_SYNCH BIT(7) +#define RTW89_PCIE_PHY_RATE_MASK GENMASK(1, 0) +#define RTW89_PCIE_LINK_CHANGE_SPEED 0xA0 +#define RTW89_PCIE_L1SS_STS_V1 0x0168 +#define RTW89_PCIE_BIT_ASPM_L11 BIT(3) +#define RTW89_PCIE_BIT_ASPM_L12 BIT(2) +#define RTW89_PCIE_BIT_PCI_L11 BIT(1) +#define RTW89_PCIE_BIT_PCI_L12 BIT(0) +#define RTW89_PCIE_ASPM_CTRL 0x070F +#define RTW89_L1DLY_MASK GENMASK(5, 3) +#define RTW89_L0DLY_MASK GENMASK(2, 0) +#define RTW89_PCIE_TIMER_CTRL 0x0718 +#define RTW89_PCIE_BIT_L1SUB BIT(5) +#define RTW89_PCIE_L1_CTRL 0x0719 +#define RTW89_PCIE_BIT_EN_64BITS BIT(5) +#define RTW89_PCIE_BIT_CLK BIT(4) +#define RTW89_PCIE_BIT_L1 BIT(3) +#define RTW89_PCIE_CLK_CTRL 0x0725 +#define RTW89_PCIE_FTS 0x080C +#define RTW89_PCIE_POLLING_BIT BIT(17) +#define RTW89_PCIE_RST_MSTATE 0x0B48 +#define RTW89_PCIE_BIT_CFG_RST_MSTATE BIT(0) + +#define INTF_INTGRA_MINREF_V1 90 +#define INTF_INTGRA_HOSTREF_V1 100 + +enum rtw89_pcie_phy { + PCIE_PHY_GEN1, + PCIE_PHY_GEN2, + PCIE_PHY_GEN1_UNDEFINE = 0x7F, +}; + +enum rtw89_pcie_l0sdly { + PCIE_L0SDLY_1US = 0, + PCIE_L0SDLY_2US = 1, + PCIE_L0SDLY_3US = 2, + PCIE_L0SDLY_4US = 3, + PCIE_L0SDLY_5US = 4, + PCIE_L0SDLY_6US = 5, + PCIE_L0SDLY_7US = 6, +}; + +enum rtw89_pcie_l1dly { + PCIE_L1DLY_16US = 4, + PCIE_L1DLY_32US = 5, + PCIE_L1DLY_64US = 6, + PCIE_L1DLY_HW_INFI = 7, +}; + +enum rtw89_pcie_clkdly_hw { + PCIE_CLKDLY_HW_0 = 0, + PCIE_CLKDLY_HW_30US = 0x1, + PCIE_CLKDLY_HW_50US = 0x2, + PCIE_CLKDLY_HW_100US = 0x3, + PCIE_CLKDLY_HW_150US = 0x4, + PCIE_CLKDLY_HW_200US = 0x5, +}; + +enum rtw89_pcie_clkdly_hw_v1 { + PCIE_CLKDLY_HW_V1_0 = 0, + PCIE_CLKDLY_HW_V1_16US = 0x1, + PCIE_CLKDLY_HW_V1_32US = 0x2, + PCIE_CLKDLY_HW_V1_64US = 0x3, + PCIE_CLKDLY_HW_V1_80US = 0x4, + PCIE_CLKDLY_HW_V1_96US = 0x5, +}; + +enum mac_ax_bd_trunc_mode { + MAC_AX_BD_NORM, + MAC_AX_BD_TRUNC, + MAC_AX_BD_DEF = 0xFE +}; + +enum mac_ax_rxbd_mode { + MAC_AX_RXBD_PKT, + MAC_AX_RXBD_SEP, + MAC_AX_RXBD_DEF = 0xFE +}; + +enum mac_ax_tag_mode { + MAC_AX_TAG_SGL, + MAC_AX_TAG_MULTI, + MAC_AX_TAG_DEF = 0xFE +}; + +enum mac_ax_tx_burst { + MAC_AX_TX_BURST_16B = 0, + MAC_AX_TX_BURST_32B = 1, + MAC_AX_TX_BURST_64B = 2, + MAC_AX_TX_BURST_V1_64B = 0, + MAC_AX_TX_BURST_128B = 3, + MAC_AX_TX_BURST_V1_128B = 1, + MAC_AX_TX_BURST_256B = 4, + MAC_AX_TX_BURST_V1_256B = 2, + MAC_AX_TX_BURST_512B = 5, + MAC_AX_TX_BURST_1024B = 6, + MAC_AX_TX_BURST_2048B = 7, + MAC_AX_TX_BURST_DEF = 0xFE +}; + +enum mac_ax_rx_burst { + MAC_AX_RX_BURST_16B = 0, + MAC_AX_RX_BURST_32B = 1, + MAC_AX_RX_BURST_64B = 2, + MAC_AX_RX_BURST_V1_64B = 0, + MAC_AX_RX_BURST_128B = 3, + MAC_AX_RX_BURST_V1_128B = 1, + MAC_AX_RX_BURST_V1_256B = 0, + MAC_AX_RX_BURST_DEF = 0xFE +}; + +enum mac_ax_wd_dma_intvl { + MAC_AX_WD_DMA_INTVL_0S, + MAC_AX_WD_DMA_INTVL_256NS, + MAC_AX_WD_DMA_INTVL_512NS, + MAC_AX_WD_DMA_INTVL_768NS, + MAC_AX_WD_DMA_INTVL_1US, + MAC_AX_WD_DMA_INTVL_1_5US, + MAC_AX_WD_DMA_INTVL_2US, + MAC_AX_WD_DMA_INTVL_4US, + MAC_AX_WD_DMA_INTVL_8US, + MAC_AX_WD_DMA_INTVL_16US, + MAC_AX_WD_DMA_INTVL_DEF = 0xFE +}; + +enum mac_ax_multi_tag_num { + MAC_AX_TAG_NUM_1, + MAC_AX_TAG_NUM_2, + MAC_AX_TAG_NUM_3, + MAC_AX_TAG_NUM_4, + MAC_AX_TAG_NUM_5, + MAC_AX_TAG_NUM_6, + MAC_AX_TAG_NUM_7, + MAC_AX_TAG_NUM_8, + MAC_AX_TAG_NUM_DEF = 0xFE +}; + +enum mac_ax_lbc_tmr { + MAC_AX_LBC_TMR_8US = 0, + MAC_AX_LBC_TMR_16US, + MAC_AX_LBC_TMR_32US, + MAC_AX_LBC_TMR_64US, + MAC_AX_LBC_TMR_128US, + MAC_AX_LBC_TMR_256US, + MAC_AX_LBC_TMR_512US, + MAC_AX_LBC_TMR_1MS, + MAC_AX_LBC_TMR_2MS, + MAC_AX_LBC_TMR_4MS, + MAC_AX_LBC_TMR_8MS, + MAC_AX_LBC_TMR_DEF = 0xFE +}; + +enum mac_ax_pcie_func_ctrl { + MAC_AX_PCIE_DISABLE = 0, + MAC_AX_PCIE_ENABLE = 1, + MAC_AX_PCIE_DEFAULT = 0xFE, + MAC_AX_PCIE_IGNORE = 0xFF +}; + +enum mac_ax_io_rcy_tmr { + MAC_AX_IO_RCY_ANA_TMR_2MS = 24000, + MAC_AX_IO_RCY_ANA_TMR_4MS = 48000, + MAC_AX_IO_RCY_ANA_TMR_6MS = 72000, + MAC_AX_IO_RCY_ANA_TMR_DEF = 0xFE +}; + +enum rtw89_pci_intr_mask_cfg { + RTW89_PCI_INTR_MASK_RESET, + RTW89_PCI_INTR_MASK_NORMAL, + RTW89_PCI_INTR_MASK_LOW_POWER, + RTW89_PCI_INTR_MASK_RECOVERY_START, + RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE, +}; + +struct rtw89_pci_isrs; +struct rtw89_pci; + +struct rtw89_pci_bd_idx_addr { + u32 tx_bd_addrs[RTW89_TXCH_NUM]; + u32 rx_bd_addrs[RTW89_RXCH_NUM]; +}; + +struct rtw89_pci_ch_dma_addr { + u32 num; /* also `offset` addr for group_bd_addr design */ + u32 idx; + u32 bdram; + u32 desa_l; + u32 desa_h; +}; + +struct rtw89_pci_ch_dma_addr_set { + struct rtw89_pci_ch_dma_addr tx[RTW89_TXCH_NUM]; + struct rtw89_pci_ch_dma_addr rx[RTW89_RXCH_NUM]; +}; + +struct rtw89_pci_bd_ram { + u8 start_idx; + u8 max_num; + u8 min_num; +}; + +struct rtw89_pci_isr_def { + u32 isr_rdu; + u32 isr_halt_c2h; + u32 isr_wdt_timeout; + u32 isr_sps_ocp; + struct rtw89_reg2_def isr_clear_rpq; + struct rtw89_reg2_def isr_clear_rxq; +}; + +struct rtw89_pci_gen_def { + int (*mac_pre_init)(struct rtw89_dev *rtwdev); + int (*mac_pre_deinit)(struct rtw89_dev *rtwdev); + int (*mac_post_init)(struct rtw89_dev *rtwdev); + + void (*clr_idx_all)(struct rtw89_dev *rtwdev); + int (*rst_bdram)(struct rtw89_dev *rtwdev); + + int (*lv1rst_stop_dma)(struct rtw89_dev *rtwdev); + int (*lv1rst_start_dma)(struct rtw89_dev *rtwdev); + + void (*ctrl_txdma_ch)(struct rtw89_dev *rtwdev, bool enable); + void (*ctrl_txdma_fw_ch)(struct rtw89_dev *rtwdev, bool enable); + int (*poll_txdma_ch_idle)(struct rtw89_dev *rtwdev); + + void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable); + void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable); + void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable); + + void (*disable_eq)(struct rtw89_dev *rtwdev); + void (*power_wake)(struct rtw89_dev *rtwdev, bool pwr_up); +}; + +#define RTW89_PCI_SSID(v, d, ssv, ssd, cust) \ + .vendor = v, .device = d, .subsystem_vendor = ssv, .subsystem_device = ssd, \ + .custid = RTW89_CUSTID_ ##cust + +struct rtw89_pci_ssid_quirk { + unsigned short vendor; + unsigned short device; + unsigned short subsystem_vendor; + unsigned short subsystem_device; + enum rtw89_custid custid; + unsigned long bitmap; /* bitmap of rtw89_quirks */ +}; + +struct rtw89_pci_rpp_info { + u16 seq; + u8 qsel; + u8 tx_status; + u8 txch; +}; + +struct rtw89_pci_info { + const struct rtw89_pci_gen_def *gen_def; + const struct rtw89_pci_isr_def *isr_def; + enum mac_ax_bd_trunc_mode txbd_trunc_mode; + enum mac_ax_bd_trunc_mode rxbd_trunc_mode; + enum mac_ax_rxbd_mode rxbd_mode; + enum mac_ax_tag_mode tag_mode; + enum mac_ax_tx_burst tx_burst; + enum mac_ax_rx_burst rx_burst; + enum mac_ax_wd_dma_intvl wd_dma_idle_intvl; + enum mac_ax_wd_dma_intvl wd_dma_act_intvl; + enum mac_ax_multi_tag_num multi_tag_num; + enum mac_ax_pcie_func_ctrl lbc_en; + enum mac_ax_lbc_tmr lbc_tmr; + enum mac_ax_pcie_func_ctrl autok_en; + enum mac_ax_pcie_func_ctrl io_rcy_en; + enum mac_ax_io_rcy_tmr io_rcy_tmr; + bool rx_ring_eq_is_full; + bool check_rx_tag; + bool no_rxbd_fs; + bool group_bd_addr; + u32 rpp_fmt_size; + + u32 init_cfg_reg; + u32 txhci_en_bit; + u32 rxhci_en_bit; + u32 rxbd_mode_bit; + u32 exp_ctrl_reg; + u32 max_tag_num_mask; + u32 rxbd_rwptr_clr_reg; + u32 txbd_rwptr_clr2_reg; + struct rtw89_reg_def dma_io_stop; + struct rtw89_reg_def dma_stop1; + struct rtw89_reg_def dma_stop2; + struct rtw89_reg_def dma_busy1; + u32 dma_busy2_reg; + u32 dma_busy3_reg; + + u32 rpwm_addr; + u32 cpwm_addr; + u32 mit_addr; + u32 wp_sel_addr; + u32 tx_dma_ch_mask; + const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power; + const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; + const struct rtw89_pci_bd_ram (*bd_ram_table)[RTW89_TXCH_NUM]; + + int (*ltr_set)(struct rtw89_dev *rtwdev, bool en); + u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); + void (*parse_rpp)(struct rtw89_dev *rtwdev, void *rpp, + struct rtw89_pci_rpp_info *rpp_info); + void (*config_intr_mask)(struct rtw89_dev *rtwdev); + void (*enable_intr)(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); + void (*disable_intr)(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); + void (*recognize_intrs)(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); + + const struct rtw89_pci_ssid_quirk *ssid_quirks; +}; + +struct rtw89_pci_tx_data { + dma_addr_t dma; +}; + +struct rtw89_pci_rx_info { + dma_addr_t dma; + u32 fs:1, ls:1, tag:13, len:14; +}; + +struct rtw89_pci_tx_bd_32 { + __le16 length; + __le16 opt; +#define RTW89_PCI_TXBD_OPT_LS BIT(14) +#define RTW89_PCI_TXBD_OPT_DMA_HI GENMASK(13, 6) + __le32 dma; +} __packed; + +#define RTW89_PCI_TXWP_VALID BIT(15) + +struct rtw89_pci_tx_wp_info { + __le16 seq0; + __le16 seq1; + __le16 seq2; + __le16 seq3; +} __packed; + +#define RTW89_PCI_ADDR_MSDU_LS BIT(15) +#define RTW89_PCI_ADDR_LS BIT(14) +#define RTW89_PCI_ADDR_HIGH_MASK GENMASK(13, 6) +#define RTW89_PCI_ADDR_NUM(x) ((x) & GENMASK(5, 0)) + +struct rtw89_pci_tx_addr_info_32 { + __le16 length; + __le16 option; + __le32 dma; +} __packed; + +#define RTW89_TXADDR_INFO_NR_V1 10 + +struct rtw89_pci_tx_addr_info_32_v1 { + __le16 length_opt; +#define B_PCIADDR_LEN_V1_MASK GENMASK(10, 0) +#define B_PCIADDR_HIGH_SEL_V1_MASK GENMASK(14, 11) +#define B_PCIADDR_LS_V1_MASK BIT(15) +#define TXADDR_INFO_LENTHG_V1_MAX ALIGN_DOWN(BIT(11) - 1, 4) + __le16 dma_low_lsb; + __le16 dma_low_msb; +} __packed; + +#define RTW89_PCI_RPP_POLLUTED BIT(31) +#define RTW89_PCI_RPP_SEQ GENMASK(30, 16) +#define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) +#define RTW89_PCI_RPP_QSEL GENMASK(12, 8) +#define RTW89_PCI_RPP_MACID GENMASK(7, 0) + +struct rtw89_pci_rpp_fmt { + __le32 dword; +} __packed; + +#define RTW89_PCI_RPP_W0_MACID_V1_MASK GENMASK(9, 0) +#define RTW89_PCI_RPP_W0_DMA_CH_MASK GENMASK(13, 10) +#define RTW89_PCI_RPP_W0_TX_STATUS_V1_MASK GENMASK(16, 14) +#define RTW89_PCI_RPP_W0_PCIE_SEQ_V1_MASK GENMASK(31, 17) +#define RTW89_PCI_RPP_W1_QSEL_V1_MASK GENMASK(5, 0) +#define RTW89_PCI_RPP_W1_TID_IND BIT(6) +#define RTW89_PCI_RPP_W1_CHANGE_LINK BIT(7) + +struct rtw89_pci_rpp_fmt_v1 { + __le32 w0; + __le32 w1; +} __packed; + +struct rtw89_pci_rx_bd_32 { + __le16 buf_size; + __le16 opt; +#define RTW89_PCI_RXBD_OPT_DMA_HI GENMASK(13, 6) + __le32 dma; +} __packed; + +#define RTW89_PCI_RXBD_FS BIT(15) +#define RTW89_PCI_RXBD_LS BIT(14) +#define RTW89_PCI_RXBD_WRITE_SIZE GENMASK(13, 0) +#define RTW89_PCI_RXBD_TAG GENMASK(28, 16) + +struct rtw89_pci_rxbd_info { + __le32 dword; +}; + +struct rtw89_pci_tx_wd { + struct list_head list; + struct sk_buff_head queue; + + void *vaddr; + dma_addr_t paddr; + u32 len; + u32 seq; +}; + +struct rtw89_pci_dma_ring { + void *head; + u8 desc_size; + dma_addr_t dma; + + struct rtw89_pci_ch_dma_addr addr; + + u32 len; + u32 wp; /* host idx */ + u32 rp; /* hw idx */ +}; + +struct rtw89_pci_dma_pool { + void *head; + dma_addr_t dma; + u32 size; +}; + +struct rtw89_pci_tx_wd_ring { + void *head; + dma_addr_t dma; + + struct rtw89_pci_tx_wd pages[RTW89_PCI_TXWD_NUM_MAX]; + struct list_head free_pages; + + u32 page_size; + u32 page_num; + u32 curr_num; +}; + +#define RTW89_RX_TAG_MAX 0x1fff + +struct rtw89_pci_tx_ring { + struct rtw89_pci_tx_wd_ring wd_ring; + struct rtw89_pci_dma_ring bd_ring; + struct list_head busy_pages; + u8 txch; + bool dma_enabled; + u16 tag; /* range from 0x0001 ~ 0x1fff */ + + u64 tx_cnt; + u64 tx_acked; + u64 tx_retry_lmt; + u64 tx_life_time; + u64 tx_mac_id_drop; +}; + +struct rtw89_pci_tx_rings { + struct rtw89_pci_tx_ring rings[RTW89_TXCH_NUM]; + struct rtw89_pci_dma_pool bd_pool; +}; + +struct rtw89_pci_rx_ring { + struct rtw89_pci_dma_ring bd_ring; + struct sk_buff *buf[RTW89_PCI_RXBD_NUM_MAX]; + u32 buf_sz; + struct sk_buff *diliver_skb; + struct rtw89_rx_desc_info diliver_desc; + u32 target_rx_tag:13; +}; + +struct rtw89_pci_rx_rings { + struct rtw89_pci_rx_ring rings[RTW89_RXCH_NUM]; + struct rtw89_pci_dma_pool bd_pool; +}; + +struct rtw89_pci_isrs { + u32 ind_isrs; + u32 halt_c2h_isrs; + u32 isrs[2]; +}; + +struct rtw89_pci { + struct pci_dev *pdev; + + /* protect HW irq related registers */ + spinlock_t irq_lock; + /* protect TRX resources (exclude RXQ) */ + spinlock_t trx_lock; + bool running; + bool low_power; + bool under_recovery; + bool enable_dac; + struct rtw89_pci_tx_rings tx; + struct rtw89_pci_rx_rings rx; + struct sk_buff_head h2c_queue; + struct sk_buff_head h2c_release_queue; + DECLARE_BITMAP(kick_map, RTW89_TXCH_NUM); + + u32 ind_intrs; + u32 halt_c2h_intrs; + u32 intrs[2]; + void __iomem *mmap; +}; + +static inline struct rtw89_pci_rx_info *RTW89_PCI_RX_SKB_CB(struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct rtw89_pci_rx_info) > sizeof(skb->cb)); + + return (struct rtw89_pci_rx_info *)skb->cb; +} + +static inline struct rtw89_pci_rx_bd_32 * +RTW89_PCI_RX_BD(struct rtw89_pci_rx_ring *rx_ring, u32 idx) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + u8 *head = bd_ring->head; + u32 desc_size = bd_ring->desc_size; + u32 offset = idx * desc_size; + + return (struct rtw89_pci_rx_bd_32 *)(head + offset); +} + +static inline void +rtw89_pci_rxbd_increase(struct rtw89_pci_rx_ring *rx_ring, u32 cnt) +{ + struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; + + bd_ring->wp += cnt; + + if (bd_ring->wp >= bd_ring->len) + bd_ring->wp -= bd_ring->len; +} + +static inline struct rtw89_pci_tx_data *RTW89_PCI_TX_SKB_CB(struct sk_buff *skb) +{ + struct rtw89_tx_skb_data *data = RTW89_TX_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct rtw89_tx_skb_data) + + sizeof(struct rtw89_pci_tx_data) > + sizeof_field(struct ieee80211_tx_info, driver_data)); + + return (struct rtw89_pci_tx_data *)data->hci_priv; +} + +static inline struct rtw89_pci_tx_bd_32 * +rtw89_pci_get_next_txbd(struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; + struct rtw89_pci_tx_bd_32 *tx_bd, *head; + + head = bd_ring->head; + tx_bd = head + bd_ring->wp; + + return tx_bd; +} + +static inline struct rtw89_pci_tx_wd * +rtw89_pci_dequeue_txwd(struct rtw89_pci_tx_ring *tx_ring) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + struct rtw89_pci_tx_wd *txwd; + + txwd = list_first_entry_or_null(&wd_ring->free_pages, + struct rtw89_pci_tx_wd, list); + if (!txwd) + return NULL; + + list_del_init(&txwd->list); + txwd->len = 0; + wd_ring->curr_num--; + + return txwd; +} + +static inline void +rtw89_pci_enqueue_txwd(struct rtw89_pci_tx_ring *tx_ring, + struct rtw89_pci_tx_wd *txwd) +{ + struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; + + memset(txwd->vaddr, 0, wd_ring->page_size); + list_add_tail(&txwd->list, &wd_ring->free_pages); + wd_ring->curr_num++; +} + +static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val) +{ + return val == 0xffffffff || val == 0xeaeaeaea; +} + +extern const struct dev_pm_ops rtw89_pm_ops; +extern const struct dev_pm_ops rtw89_pm_ops_be; +extern const struct pci_error_handlers rtw89_pci_err_handler; +extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set; +extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1; +extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be; +extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be_v1; +extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM]; +extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM]; +extern const struct rtw89_pci_isr_def rtw89_pci_isr_ax; +extern const struct rtw89_pci_isr_def rtw89_pci_isr_be; +extern const struct rtw89_pci_isr_def rtw89_pci_isr_be_v1; +extern const struct rtw89_pci_gen_def rtw89_pci_gen_ax; +extern const struct rtw89_pci_gen_def rtw89_pci_gen_be; + +struct pci_device_id; + +int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); +void rtw89_pci_remove(struct pci_dev *pdev); +void rtw89_pci_shutdown(struct pci_dev *pdev); +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume); +void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev); +int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en); +int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en); +int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en); +u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); +u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); +void rtw89_pci_parse_rpp(struct rtw89_dev *rtwdev, void *_rpp, + struct rtw89_pci_rpp_info *rpp_info); +void rtw89_pci_parse_rpp_v1(struct rtw89_dev *rtwdev, void *_rpp, + struct rtw89_pci_rpp_info *rpp_info); +void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable); +void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev); +void rtw89_pci_config_intr_mask_v1(struct rtw89_dev *rtwdev); +void rtw89_pci_config_intr_mask_v2(struct rtw89_dev *rtwdev); +void rtw89_pci_config_intr_mask_v3(struct rtw89_dev *rtwdev); +void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_enable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_enable_intr_v2(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr_v2(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_enable_intr_v3(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr_v3(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); +void rtw89_pci_recognize_intrs_v1(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); +void rtw89_pci_recognize_intrs_v2(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); +void rtw89_pci_recognize_intrs_v3(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); + +static inline +u32 rtw89_chip_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + return info->fill_txaddr_info(rtwdev, txaddr_info_addr, total_len, + dma, add_info_nr); +} + +static inline void rtw89_chip_config_intr_mask(struct rtw89_dev *rtwdev, + enum rtw89_pci_intr_mask_cfg cfg) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + + switch (cfg) { + default: + case RTW89_PCI_INTR_MASK_RESET: + rtwpci->low_power = false; + rtwpci->under_recovery = false; + break; + case RTW89_PCI_INTR_MASK_NORMAL: + rtwpci->low_power = false; + break; + case RTW89_PCI_INTR_MASK_LOW_POWER: + rtwpci->low_power = true; + break; + case RTW89_PCI_INTR_MASK_RECOVERY_START: + rtwpci->under_recovery = true; + break; + case RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE: + rtwpci->under_recovery = false; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "Configure PCI interrupt mask mode low_power=%d under_recovery=%d\n", + rtwpci->low_power, rtwpci->under_recovery); + + info->config_intr_mask(rtwdev); +} + +static inline +void rtw89_chip_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->enable_intr(rtwdev, rtwpci); +} + +static inline +void rtw89_chip_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->disable_intr(rtwdev, rtwpci); +} + +static inline +void rtw89_chip_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->recognize_intrs(rtwdev, rtwpci, isrs); +} + +static inline int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->mac_pre_init(rtwdev); +} + +static inline int rtw89_pci_ops_mac_pre_deinit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + if (!gen_def->mac_pre_deinit) + return 0; + + return gen_def->mac_pre_deinit(rtwdev); +} + +static inline int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->mac_post_init(rtwdev); +} + +static inline void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + gen_def->clr_idx_all(rtwdev); +} + +static inline int rtw89_pci_reset_bdram(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->rst_bdram(rtwdev); +} + +static inline void rtw89_pci_ctrl_txdma_ch(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->ctrl_txdma_ch(rtwdev, enable); +} + +static inline void rtw89_pci_ctrl_txdma_fw_ch(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->ctrl_txdma_fw_ch(rtwdev, enable); +} + +static inline int rtw89_pci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + return gen_def->poll_txdma_ch_idle(rtwdev); +} + +static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + gen_def->disable_eq(rtwdev); +} + +static inline void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + gen_def->power_wake(rtwdev, pwr_up); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c new file mode 100644 index 000000000..d338bf633 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/pci_be.c @@ -0,0 +1,910 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include + +#include "mac.h" +#include "pci.h" +#include "reg.h" + +enum pcie_rxbd_mode { + PCIE_RXBD_NORM = 0, + PCIE_RXBD_SEP, + PCIE_RXBD_EXT, +}; + +#define PL0_TMR_SCALE_ASIC 1 +#define PL0_TMR_ANA_172US 0x800 +#define PL0_TMR_MAC_1MS 0x27100 +#define PL0_TMR_AUX_1MS 0x1E848 + +static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u8 value = 0; + int ret; + + ret = pci_read_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, &value); + if (ret) + rtw89_warn(rtwdev, "failed to read ASPM Delay\n"); + + u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK); + + ret = pci_write_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, value); + if (ret) + rtw89_warn(rtwdev, "failed to write ASPM Delay\n"); + + if (enable) + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_BE_ASPM_CTRL_L1); + else + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_BE_ASPM_CTRL_L1); +} + +static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + + if (enable && chip_id == RTL8922D && hal->cid == RTL8922D_CID7090) + rtw89_write32_set(rtwdev, R_BE_PCIE_PS_CTRL, + B_BE_ASPM_L11_EN | B_BE_ASPM_L12_EN | + B_BE_PCIPM_L11_EN | B_BE_PCIPM_L12_EN); + + if (enable) + rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG, + B_BE_L1SUB_ENABLE); + else + rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, + B_BE_L1SUB_ENABLE); +} + +static void rtw89_pci_clkreq_set_be(struct rtw89_dev *rtwdev, bool enable) +{ + rtw89_write32_mask(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_CLK_REQ_LAT_MASK, + PCIE_CLKDLY_HW_V1_0); + + if (enable) + rtw89_write32_set(rtwdev, R_BE_L1_CLK_CTRL, + B_BE_CLK_PM_EN); + else + rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL, + B_BE_CLK_PM_EN); +} + +static void _patch_pcie_power_wake_be(struct rtw89_dev *rtwdev, bool power_up) +{ + if (power_up) + rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1); + else + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1); +} + +static void _patch_pre_init_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_hal *hal = &rtwdev->hal; + struct pci_dev *pdev = rtwpci->pdev; + + if (rtwdev->chip->chip_id != RTL8922D) + return; + + if (hal->cid != RTL8922D_CID7090) + goto set_ts1; + + rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 + + RAC_ANA14 * RAC_MULT, EIEOS_L1SS_WAIT_CLKRDY); + +set_ts1: + pci_clear_and_set_config_dword(pdev, RTW89_PCIE_L1_STS_V1, + 0, RTW89_PCIE_EXTENDED_SYNCH); +} + +static void rtw89_pci_set_io_rcy_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 scale = PL0_TMR_SCALE_ASIC; + u32 val32; + + if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) { + val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ? + PL0_TMR_ANA_172US : info->io_rcy_tmr; + val32 /= scale; + + rtw89_write32(rtwdev, R_BE_AON_WDT_TMR, val32); + rtw89_write32(rtwdev, R_BE_MDIO_WDT_TMR, val32); + rtw89_write32(rtwdev, R_BE_LA_MODE_WDT_TMR, val32); + rtw89_write32(rtwdev, R_BE_WDT_AR_TMR, val32); + rtw89_write32(rtwdev, R_BE_WDT_AW_TMR, val32); + rtw89_write32(rtwdev, R_BE_WDT_W_TMR, val32); + rtw89_write32(rtwdev, R_BE_WDT_B_TMR, val32); + rtw89_write32(rtwdev, R_BE_WDT_R_TMR, val32); + + val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ? + PL0_TMR_MAC_1MS : info->io_rcy_tmr; + val32 /= scale; + rtw89_write32(rtwdev, R_BE_WLAN_WDT_TMR, val32); + rtw89_write32(rtwdev, R_BE_AXIDMA_WDT_TMR, val32); + + val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ? + PL0_TMR_AUX_1MS : info->io_rcy_tmr; + val32 /= scale; + rtw89_write32(rtwdev, R_BE_LOCAL_WDT_TMR, val32); + } else { + rtw89_write32_clr(rtwdev, R_BE_WLAN_WDT, B_BE_WLAN_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_AXIDMA_WDT, B_BE_AXIDMA_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_AON_WDT, B_BE_AON_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_LOCAL_WDT, B_BE_LOCAL_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_MDIO_WDT, B_BE_MDIO_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_LA_MODE_WDT, B_BE_LA_MODE_WDT_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_WDT_AR, B_BE_WDT_AR_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_WDT_AW, B_BE_WDT_AW_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_WDT_W, B_BE_WDT_W_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_WDT_B, B_BE_WDT_B_ENABLE); + rtw89_write32_clr(rtwdev, R_BE_WDT_R, B_BE_WDT_R_ENABLE); + } +} + +static void rtw89_pci_ctrl_wpdma_pcie_be(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA); + else + rtw89_write32_set(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA); +} + +static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev, + enum mac_ax_pcie_func_ctrl tx_en, + enum mac_ax_pcie_func_ctrl rx_en, + enum mac_ax_pcie_func_ctrl io_en) +{ + u32 val; + + val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1); + + if (tx_en == MAC_AX_PCIE_ENABLE) + val |= B_BE_TXDMA_EN; + else if (tx_en == MAC_AX_PCIE_DISABLE) + val &= ~B_BE_TXDMA_EN; + + if (rx_en == MAC_AX_PCIE_ENABLE) + val |= B_BE_RXDMA_EN; + else if (rx_en == MAC_AX_PCIE_DISABLE) + val &= ~B_BE_RXDMA_EN; + + if (io_en == MAC_AX_PCIE_ENABLE) + val &= ~B_BE_STOP_AXI_MST; + else if (io_en == MAC_AX_PCIE_DISABLE) + val |= B_BE_STOP_AXI_MST; + + rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val); + + if (io_en == MAC_AX_PCIE_ENABLE && rtwdev->chip->chip_id == RTL8922A) + rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1, + B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4); +} + +static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_pci_rx_ring *rx_ring; + u32 val; + + if (chip->chip_id == RTL8922A) + val = B_BE_CLR_ALL_IDX_MASK; + else + val = B_BE_CLR_ALL_IDX_MASK_V1; + + rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val); + + rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1, + B_BE_CLR_RXQ0_IDX | B_BE_CLR_RPQ0_IDX); + + rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RXQ]; + rtw89_write16(rtwdev, R_BE_RXQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1); + + rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RPQ]; + rtw89_write16(rtwdev, R_BE_RPQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1); +} + +static int rtw89_pci_poll_txdma_ch_idle_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 dma_busy1 = info->dma_busy1.addr; + u32 check = info->dma_busy1.mask; + u32 val; + + return read_poll_timeout(rtw89_read32, val, (val & check) == 0, + 10, 1000, false, rtwdev, dma_busy1); +} + +static int rtw89_pci_poll_rxdma_ch_idle_be(struct rtw89_dev *rtwdev) +{ + u32 check; + u32 val; + + check = B_BE_RXQ0_BUSY_V1 | B_BE_RPQ0_BUSY_V1; + + return read_poll_timeout(rtw89_read32, val, (val & check) == 0, + 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1); +} + +static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_pci_poll_txdma_ch_idle_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "txdma ch busy\n"); + return ret; + } + + ret = rtw89_pci_poll_rxdma_ch_idle_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "rxdma ch busy\n"); + return ret; + } + + return 0; +} + +static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val32_init1, val32_rxapp, val32_exp; + + val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1); + if (chip->chip_id == RTL8922A) + val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE); + val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1); + + if (chip->chip_id == RTL8922A) { + if (info->rxbd_mode == MAC_AX_RXBD_PKT) { + val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM, + B_BE_RXQ_RXBD_MODE_MASK); + } else if (info->rxbd_mode == MAC_AX_RXBD_SEP) { + val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP, + B_BE_RXQ_RXBD_MODE_MASK); + val32_rxapp = u32_replace_bits(val32_rxapp, 0, + B_BE_APPEND_LEN_MASK); + } + } + + val32_init1 = u32_replace_bits(val32_init1, info->tx_burst, + B_BE_MAX_TXDMA_MASK); + val32_init1 = u32_replace_bits(val32_init1, info->rx_burst, + B_BE_MAX_RXDMA_MASK); + val32_exp = u32_replace_bits(val32_exp, info->multi_tag_num, + B_BE_MAX_TAG_NUM_MASK); + val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_idle_intvl, + B_BE_CFG_WD_PERIOD_IDLE_MASK); + val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_act_intvl, + B_BE_CFG_WD_PERIOD_ACTIVE_MASK); + + rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1); + if (chip->chip_id == RTL8922A) + rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp); + rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp); +} + +static int rtw89_pci_rst_bdram_be(struct rtw89_dev *rtwdev) +{ + u32 val; + + rtw89_write32_set(rtwdev, R_BE_HAXI_INIT_CFG1, B_BE_SET_BDRAM_BOUND); + + return read_poll_timeout(rtw89_read32, val, !(val & B_BE_SET_BDRAM_BOUND), + 50, 500000, false, rtwdev, R_BE_HAXI_INIT_CFG1); +} + +static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + + val32 = rtw89_read32(rtwdev, R_BE_SYS_PAGE_CLK_GATED); + val32 = u32_replace_bits(val32, 0, B_BE_PCIE_PRST_DEBUNC_PERIOD_MASK); + val32 |= B_BE_SYM_PRST_DEBUNC_SEL; + rtw89_write32(rtwdev, R_BE_SYS_PAGE_CLK_GATED, val32); +} + +static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + u32 clr; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN); + rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED, + B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP | + B_BE_CPHY_POWER_READY_CHK); + rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN | + B_BE_PCIE_DIS_L2_RTK_PERST | + B_BE_PCIE_DIS_L2__CTRL_LDO_HCI); + + if (chip_id == RTL8922D && hal->cid == RTL8922D_CID7090) + clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO | + B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB | + B_BE_PCIE_DIS_RTK_PRST_N_L1_2 | + B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB; + else + clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO; + + rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, clr); +} + +static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; + + rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_EN_AUX_CLK); + rtw89_write32_clr(rtwdev, R_BE_PCIE_PS_CTRL, B_BE_CMAC_EXIT_L1_EN); + + if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) + return; + + rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL); + rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL); + + if (chip->chip_id != RTL8922D) + return; + + rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_SYM_PRST_CPHY_RST); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_USUS_OFFCAPC_EN); + rtw89_write32(rtwdev, R_BE_PCIE_HCI2FW_ISR, 0xFFFFFFFF); +} + +static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + int ret; + + if (chip_id == RTL8922D) + goto be2_chips; + else if (chip_id != RTL8922A) + return; + + rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0); + + switch (hal->cv) { + case CHIP_CAV: + case CHIP_CBV: + rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, + B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT); + + val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK); + val32 &= ~(B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | + B_BE_SER_PM_MASTER_IMR | B_BE_SER_LTSSM_IMR | + B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK); + rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32); + break; + case CHIP_CCV: + default: + rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + + ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32, + 1, 1000, false, rtwdev, R_BE_REG_PL1_ISR); + if (ret) + rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n"); + + rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, + B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT); + rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + + val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK); + val32 |= (B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR | + B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | + B_BE_SER_PCLKREQ_ACK_MASK); + val32 &= ~B_BE_SER_L1SUB_IMR; + rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32); + break; + } + + return; + +be2_chips: + rtw89_write32_clr(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB); + rtw89_write32_set(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB); + + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS); + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS); + + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + + val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL); + val32 &= ~B_BE_PL1_SER_PL1_EN; + rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32); + rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR); + + ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32, + 1, 1000, false, rtwdev, R_BE_REG_PL1_ISR); + if (ret) + rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n"); + + val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK); + val32 |= B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR | + B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK | + B_BE_SER_LTSSM_UNSTABLE_MASK; + val32 &= ~B_BE_SER_L1SUB_IMR; + rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32); + + rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK, + PCIE_SER_TIMER_UNIT); + rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + + if (hal->cid == RTL8922D_CID7090) + rtw89_write32_set(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_SER_DETECT_EN); +} + +static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 mask_all; + u32 val; + + mask_all = B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 | + B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 | + B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 | + B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11; + + /* mask out unsupported channels for certains chips */ + mask_all &= info->dma_stop1.mask; + + val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1); + val |= B_BE_STOP_CH13 | B_BE_STOP_CH14; + + if (enable) + val &= ~mask_all; + else + val |= mask_all; + + rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val); +} + +static void rtw89_pci_ctrl_txdma_fw_ch_be(struct rtw89_dev *rtwdev, bool enable) +{ + u32 val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1); + + if (enable) + val &= ~B_BE_STOP_CH12; + else + val |= B_BE_STOP_CH12; + + rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val); +} + +static int rtw89_pci_ops_mac_pre_init_be(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_pci_set_io_rcy_be(rtwdev); + _patch_pcie_power_wake_be(rtwdev, true); + _patch_pre_init_be(rtwdev); + rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, false); + rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE, + MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE); + rtw89_pci_clr_idx_all_be(rtwdev); + + ret = rtw89_pci_poll_dma_all_idle_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n"); + return ret; + } + + rtw89_pci_mode_op_be(rtwdev); + rtw89_pci_ops_reset(rtwdev); + + ret = rtw89_pci_rst_bdram_be(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]pcie rst bdram\n"); + return ret; + } + + rtw89_pci_debounce_be(rtwdev); + rtw89_pci_ldo_low_pwr_be(rtwdev); + rtw89_pci_pcie_setting_be(rtwdev); + rtw89_pci_ser_setting_be(rtwdev); + + rtw89_pci_ctrl_txdma_ch_be(rtwdev, false); + rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true); + rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_ENABLE, + MAC_AX_PCIE_ENABLE, MAC_AX_PCIE_ENABLE); + + return 0; +} + +static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev) +{ + u32 val; + + _patch_pcie_power_wake_be(rtwdev, false); + + val = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK); + if (val == 0) + return 0; + + rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE, + MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE); + rtw89_pci_clr_idx_all_be(rtwdev); + + return 0; +} + +int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en) +{ + u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy; + u32 ltr_idle_lat_ctrl, ltr_act_lat_ctrl; + + ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0); + if (rtw89_pci_ltr_is_err_reg_val(ctrl0)) + return -EINVAL; + cfg0 = rtw89_read32(rtwdev, R_BE_LTR_CFG_0); + if (rtw89_pci_ltr_is_err_reg_val(cfg0)) + return -EINVAL; + cfg1 = rtw89_read32(rtwdev, R_BE_LTR_CFG_1); + if (rtw89_pci_ltr_is_err_reg_val(cfg1)) + return -EINVAL; + dec_ctrl = rtw89_read32(rtwdev, R_BE_LTR_DECISION_CTRL_V1); + if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl)) + return -EINVAL; + idle_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1); + if (rtw89_pci_ltr_is_err_reg_val(idle_ltcy)) + return -EINVAL; + act_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1); + if (rtw89_pci_ltr_is_err_reg_val(act_ltcy)) + return -EINVAL; + dis_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1); + if (rtw89_pci_ltr_is_err_reg_val(dis_ltcy)) + return -EINVAL; + + if (en) { + dec_ctrl |= B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1; + ctrl0 |= B_BE_LTR_HW_EN; + } else { + dec_ctrl &= ~(B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1 | + B_BE_LTR_EN_PORT_V1_MASK); + ctrl0 &= ~B_BE_LTR_HW_EN; + } + + dec_ctrl = u32_replace_bits(dec_ctrl, PCI_LTR_SPC_500US, + B_BE_LTR_SPACE_IDX_MASK); + cfg0 = u32_replace_bits(cfg0, PCI_LTR_IDLE_TIMER_3_2MS, + B_BE_LTR_IDLE_TIMER_IDX_MASK); + cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK); + cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK); + cfg0 = u32_replace_bits(cfg0, 1, B_BE_LTR_IDX_ACTIVE_MASK); + cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK); + dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK); + + if (rtwdev->chip->chip_id == RTL8922A) { + ltr_idle_lat_ctrl = 0x90039003; + ltr_act_lat_ctrl = 0x880b880b; + } else { + ltr_idle_lat_ctrl = 0x90019001; + ltr_act_lat_ctrl = 0x88018801; + } + + rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, ltr_idle_lat_ctrl); + rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, ltr_act_lat_ctrl); + rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0); + rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl); + rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0); + rtw89_write32(rtwdev, R_BE_LTR_CFG_1, cfg1); + rtw89_write32(rtwdev, R_BE_LTR_CTRL_0, ctrl0); + + return 0; +} +EXPORT_SYMBOL(rtw89_pci_ltr_set_v2); + +static void rtw89_pci_configure_mit_be(struct rtw89_dev *rtwdev) +{ + u32 cnt; + u32 val; + + rtw89_write32_mask(rtwdev, R_BE_PCIE_MIT0_TMR, + B_BE_PCIE_MIT0_RX_TMR_MASK, BE_MIT0_TMR_UNIT_1MS); + + val = rtw89_read32(rtwdev, R_BE_PCIE_MIT0_CNT); + cnt = min_t(u32, U8_MAX, RTW89_PCI_RXBD_NUM_MAX / 2); + val = u32_replace_bits(val, cnt, B_BE_PCIE_RX_MIT0_CNT_MASK); + val = u32_replace_bits(val, 2, B_BE_PCIE_RX_MIT0_TMR_CNT_MASK); + rtw89_write32(rtwdev, R_BE_PCIE_MIT0_CNT, val); +} + +static int rtw89_pci_ops_mac_post_init_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + int ret; + + ret = info->ltr_set(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "pci ltr set fail\n"); + return ret; + } + + rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_IGNORE, + MAC_AX_PCIE_IGNORE, MAC_AX_PCIE_ENABLE); + rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, true); + rtw89_pci_ctrl_txdma_ch_be(rtwdev, true); + rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true); + rtw89_pci_configure_mit_be(rtwdev); + + return 0; +} + +static int rtw89_pci_poll_io_idle_be(struct rtw89_dev *rtwdev) +{ + u32 sts; + int ret; + + ret = read_poll_timeout_atomic(rtw89_read32, sts, + !(sts & B_BE_HAXI_MST_BUSY), + 10, 1000, false, rtwdev, + R_BE_HAXI_DMA_BUSY1); + if (ret) { + rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", sts); + return ret; + } + + return 0; +} + +static int rtw89_pci_lv1rst_stop_dma_be(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_pci_ctrl_dma_all(rtwdev, false); + ret = rtw89_pci_poll_io_idle_be(rtwdev); + if (!ret) + return 0; + + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "[PCIe] poll_io_idle fail; reset hci dma trx\n"); + + rtw89_mac_ctrl_hci_dma_trx(rtwdev, false); + rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); + + return rtw89_pci_poll_io_idle_be(rtwdev); +} + +static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_mac_ctrl_hci_dma_trx(rtwdev, false); + rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); + rtw89_pci_clr_idx_all(rtwdev); + + ret = rtw89_pci_rst_bdram_be(rtwdev); + if (ret) + return ret; + + rtw89_pci_ctrl_dma_all(rtwdev, true); + return 0; +} + +static void rtw89_pci_disable_eq_be(struct rtw89_dev *rtwdev) +{ + u32 backup_aspm, phy_offset; + u16 oobs_val, offset_cal; + u16 g1_oobs, g2_oobs; + u8 gen; + + if (rtwdev->chip->chip_id != RTL8922A) + return; + + g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + if (g1_oobs && g2_oobs) + return; + + backup_aspm = rtw89_read32(rtwdev, R_BE_PCIE_MIX_CFG); + rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_RTK_ASPM_CTRL_MASK); + + /* offset K */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT, + MANUAL_LVL_MASK, offset_cal); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + OFFSET_CAL_MODE); + } + + /* OOBS */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + BAC_RX_TEST_EN); + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, + ADDR_SEL_MASK, ADDR_SEL_VAL); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, + B_PCIE_BIT_PINOUT_DIS); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + oobs_val = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA1F * RAC_MULT, OOBS_LEVEL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA03 * RAC_MULT, + OOBS_SEN_MASK, oobs_val); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA09 * RAC_MULT, + BAC_OOBS_SEL); + } + + rtw89_write32(rtwdev, R_BE_PCIE_MIX_CFG, backup_aspm); +} + +static int __maybe_unused rtw89_pci_suspend_be(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw89_dev *rtwdev = hw->priv; + u32 val32; + + rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6); + rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST); + rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6); + rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST); + + val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL); + if (val32 & B_BE_PL1_SER_PL1_EN) { + val32 = u32_replace_bits(val32, PCIE_SER_WOW_TIMER_UNIT, + B_BE_PL1_TIMER_UNIT_MASK); + rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32); + + if (rtwdev->chip->chip_id == RTL8922A) + rtw89_write32_clr(rtwdev, R_BE_REG_PL1_MASK, + B_BE_SER_PM_MASTER_IMR); + } + + return 0; +} + +static int __maybe_unused rtw89_pci_resume_be(struct device *dev) +{ + struct ieee80211_hw *hw = dev_get_drvdata(dev); + struct rtw89_dev *rtwdev = hw->priv; + u32 polling; + u32 val32; + u16 val16; + int ret; + + rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6); + rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST); + rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6); + rtw89_write32_clr(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST); + + val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL); + if (!(val32 & B_BE_PL1_SER_PL1_EN)) + goto clear_phy_isr; + + rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + if (rtwdev->chip->chip_id == RTL8922D) + rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR); + + ret = read_poll_timeout_atomic(rtw89_read32, polling, !polling, 1, 1000, + false, rtwdev, R_BE_REG_PL1_ISR); + if (ret) + rtw89_warn(rtwdev, "[ERR] PCIE SER clear polling fail\n"); + + if (rtwdev->chip->chip_id == RTL8922A) + rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, + B_BE_SER_PM_MASTER_IMR | B_BE_SER_PCLKREQ_ACK_MASK); + + val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL); + val32 = u32_replace_bits(val32, PCIE_SER_TIMER_UNIT, B_BE_PL1_TIMER_UNIT_MASK); + val32 |= B_BE_PL1_SER_PL1_EN; + rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32); + +clear_phy_isr: + if (rtwdev->chip->chip_id == RTL8922D) { + val16 = rtw89_read16(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT); + if (val16 & PHY_ERR_FLAG_EN) { + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + } + + val16 = rtw89_read16(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT); + if (val16 & PHY_ERR_FLAG_EN) { + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + } + + rtw89_write32(rtwdev, R_BE_PCIE_HCI2FW_ISR, 0xFFFFFFFF); + } + + rtw89_pci_basic_cfg(rtwdev, true); + + return 0; +} + +SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be); +EXPORT_SYMBOL(rtw89_pm_ops_be); + +const struct rtw89_pci_isr_def rtw89_pci_isr_be = { + .isr_rdu = B_BE_RDU_CH1_INT_V1 | B_BE_RDU_CH0_INT_V1, + .isr_halt_c2h = B_BE_HALT_C2H_INT, + .isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT, + .isr_sps_ocp = 0, + .isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1}, + .isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1}, +}; +EXPORT_SYMBOL(rtw89_pci_isr_be); + +const struct rtw89_pci_isr_def rtw89_pci_isr_be_v1 = { + .isr_rdu = B_BE_PCIE_RDU_CH1_INT | B_BE_PCIE_RDU_CH0_INT, + .isr_halt_c2h = B_BE_HALT_C2H_INT, + .isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT, + .isr_sps_ocp = B_BE_SPS_OCP_INT | B_BE_SPSANA_OCP_INT, + .isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1}, + .isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1}, +}; +EXPORT_SYMBOL(rtw89_pci_isr_be_v1); + +const struct rtw89_pci_gen_def rtw89_pci_gen_be = { + .mac_pre_init = rtw89_pci_ops_mac_pre_init_be, + .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_be, + .mac_post_init = rtw89_pci_ops_mac_post_init_be, + + .clr_idx_all = rtw89_pci_clr_idx_all_be, + .rst_bdram = rtw89_pci_rst_bdram_be, + + .lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be, + .lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be, + + .ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_be, + .ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_be, + .poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle_be, + + .aspm_set = rtw89_pci_aspm_set_be, + .clkreq_set = rtw89_pci_clkreq_set_be, + .l1ss_set = rtw89_pci_l1ss_set_be, + + .disable_eq = rtw89_pci_disable_eq_be, + .power_wake = _patch_pcie_power_wake_be, +}; +EXPORT_SYMBOL(rtw89_pci_gen_be); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c new file mode 100644 index 000000000..c78107e92 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -0,0 +1,9065 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "acpi.h" +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "sar.h" +#include "txrx.h" +#include "util.h" + +static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + return phy->phy0_phy1_offset(rtwdev, addr); +} + +static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, + const struct rtw89_ra_report *report) +{ + u32 bit_rate = report->bit_rate; + + /* lower than ofdm, do not aggregate */ + if (bit_rate < 550) + return 1; + + /* avoid AMSDU for legacy rate */ + if (report->might_fallback_legacy) + return 1; + + /* lower than 20M vht 2ss mcs8, make it small */ + if (bit_rate < 1800) + return 1200; + + /* lower than 40M vht 2ss mcs9, make it medium */ + if (bit_rate < 4000) + return 2600; + + /* not yet 80M vht 2ss mcs8/9, make it twice regular packet size */ + if (bit_rate < 7000) + return 3500; + + return rtwdev->chip->max_amsdu_limit; +} + +static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap) +{ + u64 ra_mask = 0; + u8 mcs_cap; + int i, nss; + + for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 12) { + mcs_cap = mcs_map & 0x3; + switch (mcs_cap) { + case 2: + ra_mask |= GENMASK_ULL(highest_mcs, 0) << nss; + break; + case 1: + ra_mask |= GENMASK_ULL(highest_mcs - gap, 0) << nss; + break; + case 0: + ra_mask |= GENMASK_ULL(highest_mcs - gap * 2, 0) << nss; + break; + default: + break; + } + } + + return ra_mask; +} + +static u64 get_he_ra_mask(struct ieee80211_link_sta *link_sta) +{ + struct ieee80211_sta_he_cap cap = link_sta->he_cap; + u16 mcs_map; + + switch (link_sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + if (cap.he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) + mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80p80); + else + mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_160); + break; + default: + mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80); + } + + /* MCS11, MCS9, MCS7 */ + return get_mcs_ra_mask(mcs_map, 11, 2); +} + +static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss) +{ + u64 nss_mcs_shift; + u64 nss_mcs_val; + u64 mask = 0; + int i, j; + u8 nss; + + for (i = 0; i < n_nss; i++) { + nss = u8_get_bits(max_nss[i], IEEE80211_EHT_MCS_NSS_RX); + if (!nss) + continue; + + nss_mcs_val = GENMASK_ULL(start_mcs + i * 2, 0); + + for (j = 0, nss_mcs_shift = 12; j < nss; j++, nss_mcs_shift += 16) + mask |= nss_mcs_val << nss_mcs_shift; + } + + return mask; +} + +static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link, + struct ieee80211_link_sta *link_sta) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz; + struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap; + struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss; + u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; + + switch (link_sta->bandwidth) { + case IEEE80211_STA_RX_BW_320: + mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._320; + /* MCS 9, 11, 13 */ + return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); + case IEEE80211_STA_RX_BW_160: + mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._160; + /* MCS 9, 11, 13 */ + return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); + case IEEE80211_STA_RX_BW_20: + if (vif->type == NL80211_IFTYPE_AP && + !(he_phy_cap[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { + mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz; + /* MCS 7, 9, 11, 13 */ + return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4); + } + fallthrough; + case IEEE80211_STA_RX_BW_80: + default: + mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._80; + /* MCS 9, 11, 13 */ + return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); + } +} + +#define RA_FLOOR_TABLE_SIZE 7 +#define RA_FLOOR_UP_GAP 3 +static u64 rtw89_phy_ra_mask_rssi(struct rtw89_dev *rtwdev, u8 rssi, + u8 ratr_state) +{ + u8 rssi_lv_t[RA_FLOOR_TABLE_SIZE] = {30, 44, 48, 52, 56, 60, 100}; + u8 rssi_lv = 0; + u8 i; + + rssi >>= 1; + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (i >= ratr_state) + rssi_lv_t[i] += RA_FLOOR_UP_GAP; + if (rssi < rssi_lv_t[i]) { + rssi_lv = i; + break; + } + } + if (rssi_lv == 0) + return 0xffffffffffffffffULL; + else if (rssi_lv == 1) + return 0xfffffffffffffff0ULL; + else if (rssi_lv == 2) + return 0xffffffffffffefe0ULL; + else if (rssi_lv == 3) + return 0xffffffffffffcfc0ULL; + else if (rssi_lv == 4) + return 0xffffffffffff8f80ULL; + else if (rssi_lv >= 5) + return 0xffffffffffff0f00ULL; + + return 0xffffffffffffffffULL; +} + +static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak) +{ + if ((ra_mask & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)) == 0) + ra_mask |= (ra_mask_bak & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); + + if (ra_mask == 0) + ra_mask |= (ra_mask_bak & (RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); + + return ra_mask; +} + +static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + const struct rtw89_chan *chan) +{ + struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; + enum nl80211_band band; + u64 cfg_mask; + + if (!rtwsta_link->use_cfg_mask) + return -1; + + switch (chan->band_type) { + case RTW89_BAND_2G: + band = NL80211_BAND_2GHZ; + cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy, + RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES); + break; + case RTW89_BAND_5G: + band = NL80211_BAND_5GHZ; + cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_5GHZ].legacy, + RA_MASK_OFDM_RATES); + break; + case RTW89_BAND_6G: + band = NL80211_BAND_6GHZ; + cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_6GHZ].legacy, + RA_MASK_OFDM_RATES); + break; + default: + rtw89_warn(rtwdev, "unhandled band type %d\n", chan->band_type); + return -1; + } + + if (link_sta->eht_cap.has_eht) { + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0], + RA_MASK_EHT_1SS_RATES); + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1], + RA_MASK_EHT_2SS_RATES); + } else if (link_sta->he_cap.has_he) { + cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], + RA_MASK_HE_1SS_RATES); + cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], + RA_MASK_HE_2SS_RATES); + } else if (link_sta->vht_cap.vht_supported) { + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], + RA_MASK_VHT_1SS_RATES); + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], + RA_MASK_VHT_2SS_RATES); + } else if (link_sta->ht_cap.ht_supported) { + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], + RA_MASK_HT_1SS_RATES); + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], + RA_MASK_HT_2SS_RATES); + } + + return cfg_mask; +} + +static const u64 +rtw89_ra_mask_ht_rates[4] = {RA_MASK_HT_1SS_RATES, RA_MASK_HT_2SS_RATES, + RA_MASK_HT_3SS_RATES, RA_MASK_HT_4SS_RATES}; +static const u64 +rtw89_ra_mask_vht_rates[4] = {RA_MASK_VHT_1SS_RATES, RA_MASK_VHT_2SS_RATES, + RA_MASK_VHT_3SS_RATES, RA_MASK_VHT_4SS_RATES}; +static const u64 +rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES, + RA_MASK_HE_3SS_RATES, RA_MASK_HE_4SS_RATES}; +static const u64 +rtw89_ra_mask_eht_rates[4] = {RA_MASK_EHT_1SS_RATES, RA_MASK_EHT_2SS_RATES, + RA_MASK_EHT_3SS_RATES, RA_MASK_EHT_4SS_RATES}; +static const u64 +rtw89_ra_mask_eht_mcs0_11[4] = {RA_MASK_EHT_1SS_MCS0_11, RA_MASK_EHT_2SS_MCS0_11, + RA_MASK_EHT_3SS_MCS0_11, RA_MASK_EHT_4SS_MCS0_11}; + +static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + const struct rtw89_chan *chan, + bool *fix_giltf_en, u8 *fix_giltf) +{ + struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; + u8 band = chan->band_type; + enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); + u8 ltf, gi; + + *fix_giltf_en = true; + + if (rtwdev->chip->chip_id == RTL8852C && + chan->band_width == RTW89_CHANNEL_WIDTH_160 && + rtw89_sta_link_has_su_mu_4xhe08(link_sta)) + *fix_giltf = RTW89_GILTF_SGI_4XHE08; + else + *fix_giltf = RTW89_GILTF_2XHE08; + + if (!rtwsta_link->use_cfg_mask) + return; + + if (link_sta->eht_cap.has_eht) { + ltf = mask->control[nl_band].eht_ltf; + gi = mask->control[nl_band].eht_gi; + } else if (link_sta->he_cap.has_he) { + ltf = mask->control[nl_band].he_ltf; + gi = mask->control[nl_band].he_gi; + } else { + return; + } + + if (ltf == 2 && gi == 2) + *fix_giltf = RTW89_GILTF_LGI_4XHE32; + else if (ltf == 2 && gi == 0) + *fix_giltf = RTW89_GILTF_SGI_4XHE08; + else if (ltf == 1 && gi == 1) + *fix_giltf = RTW89_GILTF_2XHE16; + else if (ltf == 1 && gi == 0) + *fix_giltf = RTW89_GILTF_2XHE08; + else if (ltf == 0 && gi == 1) + *fix_giltf = RTW89_GILTF_1XHE16; + else if (ltf == 0 && gi == 0) + *fix_giltf = RTW89_GILTF_1XHE08; +} + +static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + bool p2p, bool csi) +{ + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; + struct rtw89_ra_info *ra = &rtwsta_link->ra; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; + u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); + u64 ra_mask = 0; + u64 ra_mask_bak; + u8 mode = 0; + u8 csi_mode = RTW89_RA_RPT_MODE_LEGACY; + u8 bw_mode = 0; + u8 stbc_en = 0; + u8 ldpc_en = 0; + u8 fix_giltf = 0; + u8 i; + bool sgi = false; + bool fix_giltf_en = false; + + memset(ra, 0, sizeof(*ra)); + /* Set the ra mask from sta's capability */ + if (link_sta->eht_cap.has_eht) { + mode |= RTW89_RA_MODE_EHT; + ra_mask |= get_eht_ra_mask(rtwvif_link, link_sta); + + if (rtwdev->hal.no_mcs_12_13) + high_rate_masks = rtw89_ra_mask_eht_mcs0_11; + else + high_rate_masks = rtw89_ra_mask_eht_rates; + + rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta, + chan, &fix_giltf_en, &fix_giltf); + } else if (link_sta->he_cap.has_he) { + mode |= RTW89_RA_MODE_HE; + csi_mode = RTW89_RA_RPT_MODE_HE; + ra_mask |= get_he_ra_mask(link_sta); + high_rate_masks = rtw89_ra_mask_he_rates; + if (link_sta->he_cap.he_cap_elem.phy_cap_info[2] & + IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) + stbc_en = 1; + if (link_sta->he_cap.he_cap_elem.phy_cap_info[1] & + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) + ldpc_en = 1; + rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta, + chan, &fix_giltf_en, &fix_giltf); + } else if (link_sta->vht_cap.vht_supported) { + u16 mcs_map = le16_to_cpu(link_sta->vht_cap.vht_mcs.rx_mcs_map); + + mode |= RTW89_RA_MODE_VHT; + csi_mode = RTW89_RA_RPT_MODE_VHT; + /* MCS9 (non-20MHz), MCS8, MCS7 */ + if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20) + ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1); + else + ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1); + high_rate_masks = rtw89_ra_mask_vht_rates; + if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + stbc_en = 1; + if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + ldpc_en = 1; + } else if (link_sta->ht_cap.ht_supported) { + mode |= RTW89_RA_MODE_HT; + csi_mode = RTW89_RA_RPT_MODE_HT; + ra_mask |= ((u64)link_sta->ht_cap.mcs.rx_mask[3] << 48) | + ((u64)link_sta->ht_cap.mcs.rx_mask[2] << 36) | + ((u64)link_sta->ht_cap.mcs.rx_mask[1] << 24) | + ((u64)link_sta->ht_cap.mcs.rx_mask[0] << 12); + high_rate_masks = rtw89_ra_mask_ht_rates; + if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + stbc_en = 1; + if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) + ldpc_en = 1; + } + + switch (chan->band_type) { + case RTW89_BAND_2G: + ra_mask |= link_sta->supp_rates[NL80211_BAND_2GHZ]; + if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xf) + mode |= RTW89_RA_MODE_CCK; + if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xff0) + mode |= RTW89_RA_MODE_OFDM; + break; + case RTW89_BAND_5G: + ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_5GHZ] << 4; + mode |= RTW89_RA_MODE_OFDM; + break; + case RTW89_BAND_6G: + ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_6GHZ] << 4; + mode |= RTW89_RA_MODE_OFDM; + break; + default: + rtw89_err(rtwdev, "Unknown band type\n"); + break; + } + + ra_mask_bak = ra_mask; + + if (mode >= RTW89_RA_MODE_HT) { + u64 mask = 0; + for (i = 0; i < rtwdev->hal.tx_nss; i++) + mask |= high_rate_masks[i]; + if (mode & RTW89_RA_MODE_OFDM) + mask |= RA_MASK_SUBOFDM_RATES; + if (mode & RTW89_RA_MODE_CCK) + mask |= RA_MASK_SUBCCK_RATES; + ra_mask &= mask; + } else if (mode & RTW89_RA_MODE_OFDM) { + ra_mask &= (RA_MASK_OFDM_RATES | RA_MASK_SUBCCK_RATES); + } + + if (mode != RTW89_RA_MODE_CCK) + ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0); + + ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak); + ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan); + + switch (link_sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + bw_mode = RTW89_CHANNEL_WIDTH_160; + sgi = link_sta->vht_cap.vht_supported && + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); + break; + case IEEE80211_STA_RX_BW_80: + bw_mode = RTW89_CHANNEL_WIDTH_80; + sgi = link_sta->vht_cap.vht_supported && + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + break; + case IEEE80211_STA_RX_BW_40: + bw_mode = RTW89_CHANNEL_WIDTH_40; + sgi = link_sta->ht_cap.ht_supported && + (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + break; + default: + bw_mode = RTW89_CHANNEL_WIDTH_20; + sgi = link_sta->ht_cap.ht_supported && + (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + break; + } + + if (link_sta->he_cap.he_cap_elem.phy_cap_info[3] & + IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM) + ra->dcm_cap = 1; + + if (rate_pattern->enable && !p2p) { + ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan); + ra_mask &= rate_pattern->ra_mask; + mode = rate_pattern->ra_mode; + } + + ra->bw_cap = bw_mode; + ra->er_cap = rtwsta_link->er_cap; + ra->mode_ctrl = mode; + ra->macid = rtwsta_link->mac_id; + ra->stbc_cap = stbc_en; + ra->ldpc_cap = ldpc_en; + ra->ss_num = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; + ra->en_sgi = sgi; + ra->ra_mask = ra_mask; + ra->fix_giltf_en = fix_giltf_en; + ra->fix_giltf = fix_giltf; + ra->partial_bw_er = link_sta->he_cap.has_he ? + !!(link_sta->he_cap.he_cap_elem.phy_cap_info[6] & + IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) : 0; + ra->band = chan->band_type; + + if (!csi) + return; + + ra->fixed_csi_rate_en = false; + ra->ra_csi_rate_en = true; + ra->cr_tbl_sel = false; + ra->band_num = rtwvif_link->phy_idx; + ra->csi_bw = bw_mode; + ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32; + ra->csi_mcs_ss_idx = 5; + ra->csi_mode = csi_mode; +} + +void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + u32 changed) +{ + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_ra_info *ra = &rtwsta_link->ra; + struct ieee80211_link_sta *link_sta; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link, + link_sta, vif->p2p, false); + + rcu_read_unlock(); + + if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) + ra->upd_mask = 1; + if (changed & (IEEE80211_RC_BW_CHANGED | IEEE80211_RC_NSS_CHANGED)) + ra->upd_bw_nss_mask = 1; + + rtw89_debug(rtwdev, RTW89_DBG_RA, + "ra updat: macid = %d, bw = %d, nss = %d, gi = %d %d", + ra->macid, + ra->bw_cap, + ra->ss_num, + ra->en_sgi, + ra->giltf); + + rtw89_fw_h2c_ra(rtwdev, ra, false); +} + +void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, + u32 changed) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + rtw89_phy_ra_update_sta_link(rtwdev, rtwsta_link, changed); +} + +static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, + u16 rate_base, u64 ra_mask, u8 ra_mode, + u32 rate_ctrl, u32 ctrl_skip, bool force) +{ + u8 n, c; + + if (rate_ctrl == ctrl_skip) + return true; + + n = hweight32(rate_ctrl); + if (n == 0) + return true; + + if (force && n != 1) + return false; + + if (next->enable) + return false; + + c = __fls(rate_ctrl); + next->rate = rate_base + c; + next->ra_mode = ra_mode; + next->ra_mask = ra_mask; + next->enable = true; + + return true; +} + +enum __rtw89_hw_rate_invalid_bases { + /* no EHT rate for ax chip */ + RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL, +}; + +#define RTW89_HW_RATE_BY_CHIP_GEN(rate) \ + { \ + [RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \ + [RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \ + } + +static +void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_bitrate_mask *mask) +{ + struct ieee80211_supported_band *sband; + struct rtw89_phy_rate_pattern next_pattern = {0}; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = { + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0), + }; + static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = { + RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS3_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS4_MCS0), + }; + static const u16 hw_rate_vht[][RTW89_CHIP_GEN_NUM] = { + RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS1_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS2_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS3_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS4_MCS0), + }; + static const u16 hw_rate_ht[][RTW89_CHIP_GEN_NUM] = { + RTW89_HW_RATE_BY_CHIP_GEN(MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(MCS8), + RTW89_HW_RATE_BY_CHIP_GEN(MCS16), + RTW89_HW_RATE_BY_CHIP_GEN(MCS24), + }; + u8 band = chan->band_type; + enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + u8 tx_nss = rtwdev->hal.tx_nss; + u8 i; + + if (chip_gen == RTW89_CHIP_AX) + goto rs_11ax; + + for (i = 0; i < tx_nss; i++) + if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen], + RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT, + mask->control[nl_band].eht_mcs[i], + 0, true)) + goto out; + +rs_11ax: + for (i = 0; i < tx_nss; i++) + if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen], + RA_MASK_HE_RATES, RTW89_RA_MODE_HE, + mask->control[nl_band].he_mcs[i], + 0, true)) + goto out; + + for (i = 0; i < tx_nss; i++) + if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i][chip_gen], + RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT, + mask->control[nl_band].vht_mcs[i], + 0, true)) + goto out; + + for (i = 0; i < tx_nss; i++) + if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i][chip_gen], + RA_MASK_HT_RATES, RTW89_RA_MODE_HT, + mask->control[nl_band].ht_mcs[i], + 0, true)) + goto out; + + /* lagacy cannot be empty for nl80211_parse_tx_bitrate_mask, and + * require at least one basic rate for ieee80211_set_bitrate_mask, + * so the decision just depends on if all bitrates are set or not. + */ + sband = rtwdev->hw->wiphy->bands[nl_band]; + if (band == RTW89_BAND_2G) { + if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_CCK1, + RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES, + RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM, + mask->control[nl_band].legacy, + BIT(sband->n_bitrates) - 1, false)) + goto out; + } else { + if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_OFDM6, + RA_MASK_OFDM_RATES, RTW89_RA_MODE_OFDM, + mask->control[nl_band].legacy, + BIT(sband->n_bitrates) - 1, false)) + goto out; + } + + if (!next_pattern.enable) + goto out; + + if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) { + rtw89_debug(rtwdev, RTW89_DBG_RA, + "pattern invalid target: chip_gen %d, mode 0x%x\n", + chip_gen, next_pattern.ra_mode); + goto out; + } + + rtwvif_link->rate_pattern = next_pattern; + rtw89_debug(rtwdev, RTW89_DBG_RA, + "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n", + next_pattern.rate, + next_pattern.ra_mask, + next_pattern.ra_mode); + return; + +out: + rtwvif_link->rate_pattern.enable = false; + rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n"); +} + +void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + __rtw89_phy_rate_pattern_vif(rtwdev, rtwvif_link, mask); +} + +static void rtw89_phy_ra_update_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; + + rtw89_phy_ra_update_sta(rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED); +} + +void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) +{ + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_phy_ra_update_sta_iter, + rtwdev); +} + +void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_ra_info *ra = &rtwsta_link->ra; + u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; + struct ieee80211_link_sta *link_sta; + bool csi; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + csi = rtw89_sta_has_beamformer_cap(link_sta); + + rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link, + link_sta, vif->p2p, csi); + + rcu_read_unlock(); + + if (rssi > 40) + ra->init_rate_lv = 1; + else if (rssi > 20) + ra->init_rate_lv = 2; + else if (rssi > 1) + ra->init_rate_lv = 3; + else + ra->init_rate_lv = 0; + ra->upd_all = 1; + rtw89_debug(rtwdev, RTW89_DBG_RA, + "ra assoc: macid = %d, mode = %d, bw = %d, nss = %d, lv = %d", + ra->macid, + ra->mode_ctrl, + ra->bw_cap, + ra->ss_num, + ra->init_rate_lv); + rtw89_debug(rtwdev, RTW89_DBG_RA, + "ra assoc: dcm = %d, er = %d, ldpc = %d, stbc = %d, gi = %d %d", + ra->dcm_cap, + ra->er_cap, + ra->ldpc_cap, + ra->stbc_cap, + ra->en_sgi, + ra->giltf); + + rtw89_fw_h2c_ra(rtwdev, ra, csi); +} + +void rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_reg_def *ra_limit = &mac->ra_agg_limit; + struct ieee80211_sta *sta; + struct rtw89_sta *rtwsta; + u16 agg_num = U16_MAX; + u8 tid; + + for_each_station(sta, rtwdev->hw) { + rtwsta = sta_to_rtwsta(sta); + + for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) + agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); + } + + if (agg_num == U16_MAX) + agg_num = 0x3F; + else + agg_num = clamp(agg_num, 1, 256) - 1; + + rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_0); + if (!rtwdev->dbcc_en) + return; + rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_1); +} + +u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_bandwidth dbw) +{ + enum rtw89_bandwidth cbw = chan->band_width; + u8 pri_ch = chan->primary_channel; + u8 central_ch = chan->channel; + u8 txsc_idx = 0; + u8 tmp = 0; + + if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20) + return txsc_idx; + + switch (cbw) { + case RTW89_CHANNEL_WIDTH_40: + txsc_idx = pri_ch > central_ch ? 1 : 2; + break; + case RTW89_CHANNEL_WIDTH_80: + if (dbw == RTW89_CHANNEL_WIDTH_20) { + if (pri_ch > central_ch) + txsc_idx = (pri_ch - central_ch) >> 1; + else + txsc_idx = ((central_ch - pri_ch) >> 1) + 1; + } else { + txsc_idx = pri_ch > central_ch ? 9 : 10; + } + break; + case RTW89_CHANNEL_WIDTH_160: + if (pri_ch > central_ch) + tmp = (pri_ch - central_ch) >> 1; + else + tmp = ((central_ch - pri_ch) >> 1) + 1; + + if (dbw == RTW89_CHANNEL_WIDTH_20) { + txsc_idx = tmp; + } else if (dbw == RTW89_CHANNEL_WIDTH_40) { + if (tmp == 1 || tmp == 3) + txsc_idx = 9; + else if (tmp == 5 || tmp == 7) + txsc_idx = 11; + else if (tmp == 2 || tmp == 4) + txsc_idx = 10; + else if (tmp == 6 || tmp == 8) + txsc_idx = 12; + else + return 0xff; + } else { + txsc_idx = pri_ch > central_ch ? 13 : 14; + } + break; + case RTW89_CHANNEL_WIDTH_80_80: + if (dbw == RTW89_CHANNEL_WIDTH_20) { + if (pri_ch > central_ch) + txsc_idx = (10 - (pri_ch - central_ch)) >> 1; + else + txsc_idx = ((central_ch - pri_ch) >> 1) + 5; + } else if (dbw == RTW89_CHANNEL_WIDTH_40) { + txsc_idx = pri_ch > central_ch ? 10 : 12; + } else { + txsc_idx = 14; + } + break; + default: + break; + } + + return txsc_idx; +} +EXPORT_SYMBOL(rtw89_phy_get_txsc); + +u8 rtw89_phy_get_txsb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_bandwidth dbw) +{ + enum rtw89_bandwidth cbw = chan->band_width; + u8 pri_ch = chan->primary_channel; + u8 central_ch = chan->channel; + u8 txsb_idx = 0; + + if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20) + return txsb_idx; + + switch (cbw) { + case RTW89_CHANNEL_WIDTH_40: + txsb_idx = pri_ch > central_ch ? 1 : 0; + break; + case RTW89_CHANNEL_WIDTH_80: + if (dbw == RTW89_CHANNEL_WIDTH_20) + txsb_idx = (pri_ch - central_ch + 6) / 4; + else + txsb_idx = pri_ch > central_ch ? 1 : 0; + break; + case RTW89_CHANNEL_WIDTH_160: + if (dbw == RTW89_CHANNEL_WIDTH_20) + txsb_idx = (pri_ch - central_ch + 14) / 4; + else if (dbw == RTW89_CHANNEL_WIDTH_40) + txsb_idx = (pri_ch - central_ch + 12) / 8; + else + txsb_idx = pri_ch > central_ch ? 1 : 0; + break; + case RTW89_CHANNEL_WIDTH_320: + if (dbw == RTW89_CHANNEL_WIDTH_20) + txsb_idx = (pri_ch - central_ch + 30) / 4; + else if (dbw == RTW89_CHANNEL_WIDTH_40) + txsb_idx = (pri_ch - central_ch + 28) / 8; + else if (dbw == RTW89_CHANNEL_WIDTH_80) + txsb_idx = (pri_ch - central_ch + 24) / 16; + else + txsb_idx = pri_ch > central_ch ? 1 : 0; + break; + default: + break; + } + + return txsb_idx; +} +EXPORT_SYMBOL(rtw89_phy_get_txsb); + +static bool rtw89_phy_check_swsi_busy(struct rtw89_dev *rtwdev) +{ + return !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_W_BUSY_V1) || + !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_R_BUSY_V1); +} + +u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const u32 *base_addr = chip->rf_base_addr; + u32 val, direct_addr; + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + addr &= 0xff; + direct_addr = base_addr[rf_path] + (addr << 2); + mask &= RFREG_MASK; + + val = rtw89_phy_read32_mask(rtwdev, direct_addr, mask); + + return val; +} +EXPORT_SYMBOL(rtw89_phy_read_rf); + +static u32 rtw89_phy_read_rf_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask) +{ + bool busy; + bool done; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy, + 1, 30, false, rtwdev); + if (ret) { + rtw89_err(rtwdev, "read rf busy swsi\n"); + return INV_RF_DATA; + } + + mask &= RFREG_MASK; + + val = FIELD_PREP(B_SWSI_READ_ADDR_PATH_V1, rf_path) | + FIELD_PREP(B_SWSI_READ_ADDR_ADDR_V1, addr); + rtw89_phy_write32_mask(rtwdev, R_SWSI_READ_ADDR_V1, B_SWSI_READ_ADDR_V1, val); + udelay(2); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, 1, + 30, false, rtwdev, R_SWSI_V1, + B_SWSI_R_DATA_DONE_V1); + if (ret) { + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + rtw89_err(rtwdev, "read swsi busy\n"); + return INV_RF_DATA; + } + + return rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, mask); +} + +u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask) +{ + bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (ad_sel) + return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask); + else + return rtw89_phy_read_rf_a(rtwdev, rf_path, addr, mask); +} +EXPORT_SYMBOL(rtw89_phy_read_rf_v1); + +static u32 rtw89_phy_read_full_rf_v2_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr) +{ + static const u16 r_addr_ofst[2] = {0x2C24, 0x2D24}; + static const u16 addr_ofst[2] = {0x2ADC, 0x2BDC}; + bool busy, done; + int ret; + u32 val; + + rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_CTL_MASK, 0x1); + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, + 1, 3800, false, + rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_BUSY); + if (ret) { + rtw89_warn(rtwdev, "poll HWSI is busy\n"); + return INV_RF_DATA; + } + + rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_MASK, addr); + rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_RD, 0x1); + udelay(2); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, + 1, 3800, false, + rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_RDONE); + if (ret) { + rtw89_warn(rtwdev, "read HWSI is busy\n"); + val = INV_RF_DATA; + goto out; + } + + val = rtw89_phy_read32_mask(rtwdev, r_addr_ofst[rf_path], RFREG_MASK); +out: + rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_POLL_MASK, 0); + + return val; +} + +static u32 rtw89_phy_read_rf_v2_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask) +{ + u32 val; + + val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr); + + return (val & mask) >> __ffs(mask); +} + +u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask) +{ + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (ad_sel) + return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask); + else + return rtw89_phy_read_rf_v2_a(rtwdev, rf_path, addr, mask); +} +EXPORT_SYMBOL(rtw89_phy_read_rf_v2); + +static u32 rtw89_phy_read_full_rf_v3_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr) +{ + bool done; + u32 busy; + int ret; + u32 val; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, + 1, 30, false, + rtwdev, R_SW_SI_DATA_BE4, + B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4); + if (ret) { + rtw89_warn(rtwdev, "poll HWSI is busy\n"); + return INV_RF_DATA; + } + + val = u32_encode_bits(rf_path, GENMASK(10, 8)) | + u32_encode_bits(addr, GENMASK(7, 0)); + + rtw89_phy_write32_mask(rtwdev, R_SW_SI_READ_ADDR_BE4, B_SW_SI_READ_ADDR_BE4, val); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, + 1, 30, false, + rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_DONE_BE4); + if (ret) { + rtw89_warn(rtwdev, "read HWSI is busy\n"); + return INV_RF_DATA; + } + + val = rtw89_phy_read32_mask(rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_BE4); + + return val; +} + +static u32 rtw89_phy_read_rf_v3_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask) +{ + u32 val; + + val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr); + + return (val & mask) >> __ffs(mask); +} + +u32 rtw89_phy_read_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask) +{ + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (ad_sel) + return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask); + else + return rtw89_phy_read_rf_v3_a(rtwdev, rf_path, addr, mask); +} +EXPORT_SYMBOL(rtw89_phy_read_rf_v3); + +bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const u32 *base_addr = chip->rf_base_addr; + u32 direct_addr; + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return false; + } + + addr &= 0xff; + direct_addr = base_addr[rf_path] + (addr << 2); + mask &= RFREG_MASK; + + rtw89_phy_write32_mask(rtwdev, direct_addr, mask, data); + + /* delay to ensure writing properly */ + udelay(1); + + return true; +} +EXPORT_SYMBOL(rtw89_phy_write_rf); + +static bool rtw89_phy_write_rf_a(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + u8 bit_shift; + u32 val; + bool busy, b_msk_en = false; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy, + 1, 30, false, rtwdev); + if (ret) { + rtw89_err(rtwdev, "write rf busy swsi\n"); + return false; + } + + data &= RFREG_MASK; + mask &= RFREG_MASK; + + if (mask != RFREG_MASK) { + b_msk_en = true; + rtw89_phy_write32_mask(rtwdev, R_SWSI_BIT_MASK_V1, RFREG_MASK, + mask); + bit_shift = __ffs(mask); + data = (data << bit_shift) & RFREG_MASK; + } + + val = FIELD_PREP(B_SWSI_DATA_BIT_MASK_EN_V1, b_msk_en) | + FIELD_PREP(B_SWSI_DATA_PATH_V1, rf_path) | + FIELD_PREP(B_SWSI_DATA_ADDR_V1, addr) | + FIELD_PREP(B_SWSI_DATA_VAL_V1, data); + + rtw89_phy_write32_mask(rtwdev, R_SWSI_DATA_V1, MASKDWORD, val); + + return true; +} + +bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return false; + } + + if (ad_sel) + return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data); + else + return rtw89_phy_write_rf_a(rtwdev, rf_path, addr, mask, data); +} +EXPORT_SYMBOL(rtw89_phy_write_rf_v1); + +static +bool rtw89_phy_write_full_rf_v2_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 data) +{ + static const u32 addr_is_idle[2] = {0x2C24, 0x2D24}; + static const u32 addr_ofst[2] = {0x2AE0, 0x2BE0}; + bool busy; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, + 1, 3800, false, + rtwdev, addr_is_idle[rf_path], BIT(29)); + if (ret) { + rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__); + return false; + } + + val = u32_encode_bits(addr, B_HWSI_DATA_ADDR) | + u32_encode_bits(data, B_HWSI_DATA_VAL); + + rtw89_phy_write32(rtwdev, addr_ofst[rf_path], val); + + return true; +} + +static +bool rtw89_phy_write_rf_a_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + u32 val; + + if (mask == RFREG_MASK) { + val = data; + } else { + val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr); + val &= ~mask; + val |= (data << __ffs(mask)) & mask; + } + + return rtw89_phy_write_full_rf_v2_a(rtwdev, rf_path, addr, val); +} + +bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (ad_sel) + return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data); + else + return rtw89_phy_write_rf_a_v2(rtwdev, rf_path, addr, mask, data); +} +EXPORT_SYMBOL(rtw89_phy_write_rf_v2); + +static +bool rtw89_phy_write_full_rf_v3_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 data) +{ + u32 busy; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, + 1, 30, false, + rtwdev, R_SW_SI_DATA_BE4, + B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4); + if (ret) { + rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__); + return false; + } + + val = u32_encode_bits(rf_path, B_SW_SI_DATA_PATH_BE4) | + u32_encode_bits(addr, B_SW_SI_DATA_ADR_BE4) | + u32_encode_bits(data, B_SW_SI_DATA_DAT_BE4); + + rtw89_phy_write32(rtwdev, R_SW_SI_WDATA_BE4, val); + + return true; +} + +static +bool rtw89_phy_write_rf_a_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + u32 val; + + if (mask == RFREG_MASK) { + val = data; + } else { + val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr); + val &= ~mask; + val |= (data << __ffs(mask)) & mask; + } + + return rtw89_phy_write_full_rf_v3_a(rtwdev, rf_path, addr, val); +} + +bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + + if (rf_path >= rtwdev->chip->rf_path_num) { + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (ad_sel) + return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data); + else + return rtw89_phy_write_rf_a_v3(rtwdev, rf_path, addr, mask, data); +} +EXPORT_SYMBOL(rtw89_phy_write_rf_v3); + +static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev) +{ + return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1; +} + +static void __rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->bb_reset(rtwdev, phy_idx); +} + +static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev) +{ + __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_1); +} + +static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + u32 addr; + + if (reg->addr == 0xfe) { + rtw89_io_mdelay(rtwdev, 50); + } else if (reg->addr == 0xfd) { + rtw89_io_mdelay(rtwdev, 5); + } else if (reg->addr == 0xfc) { + rtw89_io_mdelay(rtwdev, 1); + } else if (reg->addr == 0xfb) { + rtw89_io_udelay(rtwdev, 50); + } else if (reg->addr == 0xfa) { + rtw89_io_udelay(rtwdev, 5); + } else if (reg->addr == 0xf9) { + rtw89_io_udelay(rtwdev, 1); + } else if (reg->data == BYPASS_CR_DATA) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Bypass CR 0x%x\n", reg->addr); + } else { + addr = reg->addr; + + if ((uintptr_t)extra_data == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, reg->addr); + + rtw89_phy_write32(rtwdev, addr, reg->data); + } +} + +union rtw89_phy_bb_gain_arg { + u32 addr; + struct { + union { + u8 type; + struct { + u8 rxsc_start:4; + u8 bw:4; + }; + }; + u8 path; + u8 gain_band; + u8 cfg_type; + }; +} __packed; + +static void +rtw89_phy_cfg_bb_gain_error(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_gain[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_gain[gband][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 2; i++, data >>= 8) + gain->tia_gain[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain error {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +enum rtw89_phy_bb_rxsc_start_idx { + RTW89_BB_RXSC_START_IDX_FULL = 0, + RTW89_BB_RXSC_START_IDX_20 = 1, + RTW89_BB_RXSC_START_IDX_20_1 = 5, + RTW89_BB_RXSC_START_IDX_40 = 9, + RTW89_BB_RXSC_START_IDX_80 = 13, +}; + +static void +rtw89_phy_cfg_bb_rpl_ofst(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 rxsc_start = arg.rxsc_start; + u8 bw = arg.bw; + u8 path = arg.path; + u8 gband = arg.gain_band; + u8 rxsc; + s8 ofst; + int i; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + gain->rpl_ofst_20[gband][path] = (s8)data; + break; + case RTW89_CHANNEL_WIDTH_40: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_40[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_40[gband][path][rxsc] = ofst; + } + } + break; + case RTW89_CHANNEL_WIDTH_80: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_80[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_80[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_40 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_80[gband][path][rxsc] = ofst; + } + } + break; + case RTW89_CHANNEL_WIDTH_160: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_160[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20_1) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20_1 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_40 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_80) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_80 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } + break; + default: + rtw89_warn(rtwdev, + "bb rpl ofst {0x%x:0x%x} with unknown bw: %d\n", + arg.addr, data, bw); + break; + } +} + +static void +rtw89_phy_cfg_bb_gain_bypass(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_gain_bypass[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_gain_bypass[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain bypass {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void +rtw89_phy_cfg_bb_gain_op1db(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_op1db[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_op1db[gband][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 4; i++, data >>= 8) + gain->tia_lna_op1db[gband][path][i] = data & 0xff; + break; + case 3: + for (i = 4; i < 8; i++, data >>= 8) + gain->tia_lna_op1db[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain op1db {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void rtw89_phy_config_bb_gain_ax(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + union rtw89_phy_bb_gain_arg arg = { .addr = reg->addr }; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR) + return; + + if (arg.path >= chip->rf_path_num) + return; + + if (arg.addr >= 0xf9 && arg.addr <= 0xfe) { + rtw89_warn(rtwdev, "bb gain table with flow ctrl\n"); + return; + } + + switch (arg.cfg_type) { + case 0: + rtw89_phy_cfg_bb_gain_error(rtwdev, arg, reg->data); + break; + case 1: + rtw89_phy_cfg_bb_rpl_ofst(rtwdev, arg, reg->data); + break; + case 2: + rtw89_phy_cfg_bb_gain_bypass(rtwdev, arg, reg->data); + break; + case 3: + rtw89_phy_cfg_bb_gain_op1db(rtwdev, arg, reg->data); + break; + case 4: + /* This cfg_type is only used by rfe_type >= 50 with eFEM */ + if (efuse->rfe_type < 50) + break; + fallthrough; + default: + rtw89_warn(rtwdev, + "bb gain {0x%x:0x%x} with unknown cfg type: %d\n", + arg.addr, reg->data, arg.cfg_type); + break; + } +} + +static void +rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + struct rtw89_fw_h2c_rf_reg_info *info) +{ + u16 idx = info->curr_idx % RTW89_H2C_RF_PAGE_SIZE; + u8 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE; + + if (page >= RTW89_H2C_RF_PAGE_NUM) { + rtw89_warn(rtwdev, "RF parameters exceed size. path=%d, idx=%d", + rf_path, info->curr_idx); + return; + } + + info->rtw89_phy_config_rf_h2c[page][idx] = + cpu_to_le32((reg->addr << 20) | reg->data); + info->curr_idx++; +} + +static int rtw89_phy_config_rf_reg_fw(struct rtw89_dev *rtwdev, + struct rtw89_fw_h2c_rf_reg_info *info) +{ + u16 remain = info->curr_idx; + u16 len = 0; + u8 i; + int ret = 0; + + if (remain > RTW89_H2C_RF_PAGE_NUM * RTW89_H2C_RF_PAGE_SIZE) { + rtw89_warn(rtwdev, + "rf reg h2c total len %d larger than %d\n", + remain, RTW89_H2C_RF_PAGE_NUM * RTW89_H2C_RF_PAGE_SIZE); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < RTW89_H2C_RF_PAGE_NUM && remain; i++, remain -= len) { + len = remain > RTW89_H2C_RF_PAGE_SIZE ? RTW89_H2C_RF_PAGE_SIZE : remain; + ret = rtw89_fw_h2c_rf_reg(rtwdev, info, len * 4, i); + if (ret) + goto out; + } +out: + info->curr_idx = 0; + + return ret; +} + +static void rtw89_phy_config_rf_reg_noio(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + u32 addr = reg->addr; + + if (addr == 0xfe || addr == 0xfd || addr == 0xfc || addr == 0xfb || + addr == 0xfa || addr == 0xf9) + return; + + if (rtw89_chip_rf_v1(rtwdev) && addr < 0x100) + return; + + rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, + (struct rtw89_fw_h2c_rf_reg_info *)extra_data); +} + +void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + if (reg->addr == 0xfe) { + rtw89_io_mdelay(rtwdev, 50); + } else if (reg->addr == 0xfd) { + rtw89_io_mdelay(rtwdev, 5); + } else if (reg->addr == 0xfc) { + rtw89_io_mdelay(rtwdev, 1); + } else if (reg->addr == 0xfb) { + rtw89_io_udelay(rtwdev, 50); + } else if (reg->addr == 0xfa) { + rtw89_io_udelay(rtwdev, 5); + } else if (reg->addr == 0xf9) { + rtw89_io_udelay(rtwdev, 1); + } else { + rtw89_write_rf(rtwdev, rf_path, reg->addr, 0xfffff, reg->data); + rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, + (struct rtw89_fw_h2c_rf_reg_info *)extra_data); + } +} + +void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + if (reg->addr == 0xfe) { + rtw89_io_mdelay(rtwdev, 50); + return; + } + + rtw89_write_rf(rtwdev, rf_path, reg->addr, RFREG_MASK, reg->data); + + if (reg->addr < 0x100) + return; + + rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, + (struct rtw89_fw_h2c_rf_reg_info *)extra_data); +} +EXPORT_SYMBOL(rtw89_phy_config_rf_reg_v1); + +static int rtw89_phy_sel_headline(struct rtw89_dev *rtwdev, + const struct rtw89_phy_table *table, + u32 *headline_size, u32 *headline_idx, + u8 rfe, u8 cv) +{ + const struct rtw89_reg2_def *reg; + u32 headline; + u32 compare, target; + u8 rfe_para, cv_para; + u8 cv_max = 0; + bool case_matched = false; + u32 i; + + for (i = 0; i < table->n_regs; i++) { + reg = &table->regs[i]; + headline = get_phy_headline(reg->addr); + if (headline != PHY_HEADLINE_VALID) + break; + } + *headline_size = i; + if (*headline_size == 0) + return 0; + + /* case 1: RFE match, CV match */ + compare = get_phy_compare(rfe, cv); + for (i = 0; i < *headline_size; i++) { + reg = &table->regs[i]; + target = get_phy_target(reg->addr); + if (target == compare) { + *headline_idx = i; + return 0; + } + } + + /* case 2: RFE match, CV don't care */ + compare = get_phy_compare(rfe, PHY_COND_DONT_CARE); + for (i = 0; i < *headline_size; i++) { + reg = &table->regs[i]; + target = get_phy_target(reg->addr); + if (target == compare) { + *headline_idx = i; + return 0; + } + } + + /* case 3: RFE match, CV max in table */ + for (i = 0; i < *headline_size; i++) { + reg = &table->regs[i]; + rfe_para = get_phy_cond_rfe(reg->addr); + cv_para = get_phy_cond_cv(reg->addr); + if (rfe_para == rfe) { + if (cv_para >= cv_max) { + cv_max = cv_para; + *headline_idx = i; + case_matched = true; + } + } + } + + if (case_matched) + return 0; + + /* case 4: RFE don't care, CV max in table */ + for (i = 0; i < *headline_size; i++) { + reg = &table->regs[i]; + rfe_para = get_phy_cond_rfe(reg->addr); + cv_para = get_phy_cond_cv(reg->addr); + if (rfe_para == PHY_COND_DONT_CARE) { + if (cv_para >= cv_max) { + cv_max = cv_para; + *headline_idx = i; + case_matched = true; + } + } + } + + if (case_matched) + return 0; + + return -EINVAL; +} + +static void rtw89_phy_init_reg(struct rtw89_dev *rtwdev, + const struct rtw89_phy_table *table, bool by_acv, + void (*config)(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *data), + void *extra_data) +{ + const struct rtw89_reg2_def *reg; + enum rtw89_rf_path rf_path = table->rf_path; + u8 cv = by_acv ? rtwdev->hal.acv : rtwdev->hal.cv; + u8 rfe = rtwdev->efuse.rfe_type; + u32 i; + u32 headline_size = 0, headline_idx = 0; + u32 target = 0, cfg_target; + u8 cond; + bool is_matched = true; + bool target_found = false; + int ret; + + ret = rtw89_phy_sel_headline(rtwdev, table, &headline_size, + &headline_idx, rfe, cv); + if (ret) { + rtw89_err(rtwdev, "invalid PHY package: %d/%d\n", rfe, cv); + return; + } + + cfg_target = get_phy_target(table->regs[headline_idx].addr); + for (i = headline_size; i < table->n_regs; i++) { + reg = &table->regs[i]; + cond = get_phy_cond(reg->addr); + switch (cond) { + case PHY_COND_BRANCH_IF: + case PHY_COND_BRANCH_ELIF: + target = get_phy_target(reg->addr); + break; + case PHY_COND_BRANCH_ELSE: + is_matched = false; + if (!target_found) { + rtw89_warn(rtwdev, "failed to load CR %x/%x\n", + reg->addr, reg->data); + return; + } + break; + case PHY_COND_BRANCH_END: + is_matched = true; + target_found = false; + break; + case PHY_COND_CHECK: + if (target_found) { + is_matched = false; + break; + } + + if (target == cfg_target) { + is_matched = true; + target_found = true; + } else { + is_matched = false; + target_found = false; + } + break; + default: + if (is_matched) + config(rtwdev, reg, rf_path, extra_data); + break; + } + } +} + +void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_phy_table *bb_table; + const struct rtw89_phy_table *bb_gain_table; + + bb_table = elm_info->bb_tbl ? elm_info->bb_tbl : chip->bb_table; + + rtw89_io_pack(rtwdev); + + rtw89_phy_init_reg(rtwdev, bb_table, false, rtw89_phy_config_bb_reg, NULL); + if (rtwdev->dbcc_en) + rtw89_phy_init_reg(rtwdev, bb_table, false, rtw89_phy_config_bb_reg, + (void *)RTW89_PHY_1); + + rtw89_io_unpack(rtwdev); + + rtw89_chip_init_txpwr_unit(rtwdev); + + bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table; + if (bb_gain_table) + rtw89_phy_init_reg(rtwdev, bb_gain_table, false, + chip->phy_def->config_bb_gain, NULL); + + rtw89_phy_bb_reset(rtwdev); +} + +void rtw89_phy_init_bb_afe(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_fw_element_hdr *afe_elm = elm_info->afe; + const struct rtw89_phy_afe_info *info; + u32 action, cat, class; + u32 addr, mask, val; + u32 poll, rpt; + u32 n, i; + + if (!afe_elm) + return; + + n = le32_to_cpu(afe_elm->size) / sizeof(*info); + + for (i = 0; i < n; i++) { + info = &afe_elm->u.afe.infos[i]; + + class = le32_to_cpu(info->class); + switch (class) { + case RTW89_FW_AFE_CLASS_P0: + case RTW89_FW_AFE_CLASS_P1: + case RTW89_FW_AFE_CLASS_CMN: + /* Currently support two paths */ + break; + case RTW89_FW_AFE_CLASS_P2: + case RTW89_FW_AFE_CLASS_P3: + case RTW89_FW_AFE_CLASS_P4: + default: + rtw89_warn(rtwdev, "unexpected AFE class %u\n", class); + continue; + } + + addr = le32_to_cpu(info->addr); + mask = le32_to_cpu(info->mask); + val = le32_to_cpu(info->val); + cat = le32_to_cpu(info->cat); + action = le32_to_cpu(info->action); + + switch (action) { + case RTW89_FW_AFE_ACTION_WRITE: + switch (cat) { + case RTW89_FW_AFE_CAT_MAC: + case RTW89_FW_AFE_CAT_MAC1: + rtw89_write32_mask(rtwdev, addr, mask, val); + break; + case RTW89_FW_AFE_CAT_AFEDIG: + case RTW89_FW_AFE_CAT_AFEDIG1: + rtw89_write32_mask(rtwdev, addr, mask, val); + break; + case RTW89_FW_AFE_CAT_BB: + rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0); + break; + case RTW89_FW_AFE_CAT_BB1: + rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1); + break; + default: + rtw89_warn(rtwdev, + "unexpected AFE writing action %u\n", action); + break; + } + break; + case RTW89_FW_AFE_ACTION_POLL: + for (poll = 0; poll <= 10; poll++) { + /* + * For CAT_BB, AFE reads register with mcu_offset 0, + * so both CAT_MAC and CAT_BB use the same method. + */ + rpt = rtw89_read32_mask(rtwdev, addr, mask); + if (rpt == val) + goto poll_done; + + fsleep(1); + } + rtw89_warn(rtwdev, "failed to poll AFE cat=%u addr=0x%x mask=0x%x\n", + cat, addr, mask); +poll_done: + break; + case RTW89_FW_AFE_ACTION_DELAY: + fsleep(addr); + break; + } + } +} + +static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32(rtwdev, 0x8080, 0x4); + udelay(1); + return rtw89_phy_read32(rtwdev, 0x8080); +} + +void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio) +{ + void (*config)(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, void *data); + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_phy_table *rf_table; + struct rtw89_fw_h2c_rf_reg_info *rf_reg_info; + bool by_acv = chip->chip_id == RTL8922D; + u8 path; + + rf_reg_info = kzalloc_obj(*rf_reg_info); + if (!rf_reg_info) + return; + + for (path = RF_PATH_A; path < chip->rf_path_num; path++) { + rf_table = elm_info->rf_radio[path] ? + elm_info->rf_radio[path] : chip->rf_table[path]; + rf_reg_info->rf_path = rf_table->rf_path; + if (noio) + config = rtw89_phy_config_rf_reg_noio; + else + config = rf_table->config ? rf_table->config : + rtw89_phy_config_rf_reg; + + rtw89_io_pack(rtwdev); + rtw89_phy_init_reg(rtwdev, rf_table, by_acv, config, (void *)rf_reg_info); + rtw89_io_unpack(rtwdev); + + if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info)) + rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n", + rf_reg_info->rf_path); + } + kfree(rf_reg_info); +} + +static void rtw89_phy_preinit_rf_nctl_ax(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val; + int ret; + + /* IQK/DPK clock & reset */ + rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x3); + rtw89_phy_write32_set(rtwdev, R_GNT_BT_WGT_EN, 0x1); + rtw89_phy_write32_set(rtwdev, R_P0_PATH_RST, 0x8000000); + if (chip->chip_id != RTL8851B) + rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000); + if (chip->chip_id == RTL8852B || chip->chip_id == RTL8852BT) + rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2); + + /* check 0x8080 */ + rtw89_phy_write32(rtwdev, R_NCTL_CFG, 0x8); + + ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10, + 1000, false, rtwdev); + if (ret) + rtw89_err(rtwdev, "failed to poll nctl block\n"); +} + +static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_phy_table *nctl_table; + + rtw89_phy_preinit_rf_nctl(rtwdev); + + nctl_table = elm_info->rf_nctl ? elm_info->rf_nctl : chip->nctl_table; + rtw89_phy_init_reg(rtwdev, nctl_table, false, rtw89_phy_config_bb_reg, NULL); + + if (chip->nctl_post_table) + rtw89_rfk_parser(rtwdev, chip->nctl_post_table); +} + +static u32 rtw89_phy0_phy1_offset_ax(struct rtw89_dev *rtwdev, u32 addr) +{ + u32 phy_page = addr >> 8; + u32 ofst = 0; + + switch (phy_page) { + case 0x6: + case 0x7: + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0x19: + case 0x1a: + case 0x1b: + ofst = 0x2000; + break; + default: + /* warning case */ + ofst = 0; + break; + } + + if (phy_page >= 0x40 && phy_page <= 0x4f) + ofst = 0x2000; + + return ofst; +} + +void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + u32 data, enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + rtw89_phy_write32_mask(rtwdev, addr, mask, data); +} +EXPORT_SYMBOL(rtw89_phy_write32_idx); + +void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + rtw89_phy_write32_set(rtwdev, addr, bits); +} +EXPORT_SYMBOL(rtw89_phy_write32_idx_set); + +void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + rtw89_phy_write32_clr(rtwdev, addr, bits); +} +EXPORT_SYMBOL(rtw89_phy_write32_idx_clr); + +u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + return rtw89_phy_read32_mask(rtwdev, addr, mask); +} +EXPORT_SYMBOL(rtw89_phy_read32_idx); + +void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + u32 val) +{ + rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0); + + if (!rtwdev->dbcc_en) + return; + + rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1); +} +EXPORT_SYMBOL(rtw89_phy_set_phy_regs); + +void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_phy_reg3_tbl *tbl) +{ + const struct rtw89_reg3_def *reg3; + int i; + + for (i = 0; i < tbl->size; i++) { + reg3 = &tbl->reg3[i]; + rtw89_phy_write32_mask(rtwdev, reg3->addr, reg3->mask, reg3->data); + } +} +EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl); + +static u8 rtw89_phy_ant_gain_domain_to_regd(struct rtw89_dev *rtwdev, u8 ant_gain_regd) +{ + switch (ant_gain_regd) { + case RTW89_ANT_GAIN_ETSI: + return RTW89_ETSI; + default: + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "unknown antenna gain domain: %d\n", + ant_gain_regd); + return RTW89_REGD_NUM; + } +} + +/* antenna gain in unit of 0.25 dbm */ +#define RTW89_ANT_GAIN_2GHZ_MIN -8 +#define RTW89_ANT_GAIN_2GHZ_MAX 14 +#define RTW89_ANT_GAIN_5GHZ_MIN -8 +#define RTW89_ANT_GAIN_5GHZ_MAX 20 +#define RTW89_ANT_GAIN_6GHZ_MIN -8 +#define RTW89_ANT_GAIN_6GHZ_MAX 20 + +#define RTW89_ANT_GAIN_REF_2GHZ 14 +#define RTW89_ANT_GAIN_REF_5GHZ 20 +#define RTW89_ANT_GAIN_REF_6GHZ 20 + +void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_acpi_rtag_result res = {}; + u32 domain; + int ret; + u8 i, j; + u8 regd; + u8 val; + + if (!chip->support_ant_gain) + return; + + ret = rtw89_acpi_evaluate_rtag(rtwdev, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "acpi: cannot eval rtag: %d\n", ret); + return; + } + + if (res.revision != 0) { + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "unknown rtag revision: %d\n", res.revision); + return; + } + + domain = get_unaligned_le32(&res.domain); + + for (i = 0; i < RTW89_ANT_GAIN_DOMAIN_NUM; i++) { + if (!(domain & BIT(i))) + continue; + + regd = rtw89_phy_ant_gain_domain_to_regd(rtwdev, i); + if (regd >= RTW89_REGD_NUM) + continue; + ant_gain->regd_enabled |= BIT(regd); + } + + for (i = 0; i < RTW89_ANT_GAIN_CHAIN_NUM; i++) { + for (j = 0; j < RTW89_ANT_GAIN_SUBBAND_NR; j++) { + val = res.ant_gain_table[i][j]; + switch (j) { + default: + case RTW89_ANT_GAIN_2GHZ_SUBBAND: + val = RTW89_ANT_GAIN_REF_2GHZ - + clamp_t(s8, val, + RTW89_ANT_GAIN_2GHZ_MIN, + RTW89_ANT_GAIN_2GHZ_MAX); + break; + case RTW89_ANT_GAIN_5GHZ_SUBBAND_1: + case RTW89_ANT_GAIN_5GHZ_SUBBAND_2: + case RTW89_ANT_GAIN_5GHZ_SUBBAND_2E: + case RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4: + val = RTW89_ANT_GAIN_REF_5GHZ - + clamp_t(s8, val, + RTW89_ANT_GAIN_5GHZ_MIN, + RTW89_ANT_GAIN_5GHZ_MAX); + break; + case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L: + case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H: + case RTW89_ANT_GAIN_6GHZ_SUBBAND_6: + case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L: + case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H: + case RTW89_ANT_GAIN_6GHZ_SUBBAND_8: + val = RTW89_ANT_GAIN_REF_6GHZ - + clamp_t(s8, val, + RTW89_ANT_GAIN_6GHZ_MIN, + RTW89_ANT_GAIN_6GHZ_MAX); + } + ant_gain->offset[i][j] = val; + } + } +} + +static +enum rtw89_ant_gain_subband rtw89_phy_ant_gain_get_subband(struct rtw89_dev *rtwdev, + u32 center_freq) +{ + switch (center_freq) { + default: + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "center freq: %u to antenna gain subband is unhandled\n", + center_freq); + fallthrough; + case 2412 ... 2484: + return RTW89_ANT_GAIN_2GHZ_SUBBAND; + case 5180 ... 5240: + return RTW89_ANT_GAIN_5GHZ_SUBBAND_1; + case 5250 ... 5320: + return RTW89_ANT_GAIN_5GHZ_SUBBAND_2; + case 5500 ... 5720: + return RTW89_ANT_GAIN_5GHZ_SUBBAND_2E; + case 5745 ... 5885: + return RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4; + case 5955 ... 6155: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L; + case 6175 ... 6415: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H; + case 6435 ... 6515: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_6; + case 6535 ... 6695: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L; + case 6715 ... 6855: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H; + + /* freq 6875 (ch 185, 20MHz) spans RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H + * and RTW89_ANT_GAIN_6GHZ_SUBBAND_8, so directly describe it with + * struct rtw89_6ghz_span. + */ + + case 6895 ... 7115: + return RTW89_ANT_GAIN_6GHZ_SUBBAND_8; + } +} + +static s8 rtw89_phy_ant_gain_query(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u32 center_freq) +{ + struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + enum rtw89_ant_gain_subband subband_l, subband_h; + const struct rtw89_6ghz_span *span; + + span = rtw89_get_6ghz_span(rtwdev, center_freq); + + if (span && RTW89_ANT_GAIN_SPAN_VALID(span)) { + subband_l = span->ant_gain_subband_low; + subband_h = span->ant_gain_subband_high; + } else { + subband_l = rtw89_phy_ant_gain_get_subband(rtwdev, center_freq); + subband_h = subband_l; + } + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "center_freq %u: antenna gain subband {%u, %u}\n", + center_freq, subband_l, subband_h); + + return min(ant_gain->offset[path][subband_l], + ant_gain->offset[path][subband_h]); +} + +static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u32 center_freq) +{ + s8 offset_patha, offset_pathb; + + offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq); + offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, center_freq); + + if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw)) + return min(offset_patha, offset_pathb); + + return max(offset_patha, offset_pathb); +} + +static bool rtw89_can_apply_ant_gain(struct rtw89_dev *rtwdev, u8 band) +{ + const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; + struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 regd = rtw89_regd_get(rtwdev, band); + + if (!chip->support_ant_gain) + return false; + + if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd))) + return false; + + if (!rfe_parms->has_da) + return false; + + return true; +} + +s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + s8 offset_patha, offset_pathb; + + if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type)) + return 0; + + if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw)) + return 0; + + offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq); + offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq); + + return rtw89_phy_txpwr_rf_to_bb(rtwdev, offset_patha - offset_pathb); +} +EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset); + +int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan) +{ + char *p = buf, *end = buf + bufsz; + s8 offset_patha, offset_pathb; + + if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type)) { + p += scnprintf(p, end - p, "no DAG is applied\n"); + goto out; + } + + offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq); + offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq); + + p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha); + p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb); + +out: + return p - buf; +} + +static const u8 rtw89_rs_idx_num_ax[] = { + [RTW89_RS_CCK] = RTW89_RATE_CCK_NUM, + [RTW89_RS_OFDM] = RTW89_RATE_OFDM_NUM, + [RTW89_RS_MCS] = RTW89_RATE_MCS_NUM_AX, + [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_NUM, + [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_NUM_AX, +}; + +static const u8 rtw89_rs_nss_num_ax[] = { + [RTW89_RS_CCK] = 1, + [RTW89_RS_OFDM] = 1, + [RTW89_RS_MCS] = RTW89_NSS_NUM, + [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_NUM, + [RTW89_RS_OFFSET] = 1, +}; + +s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_byrate *head, + const struct rtw89_rate_desc *desc) +{ + switch (desc->rs) { + case RTW89_RS_CCK: + return &head->cck[desc->idx]; + case RTW89_RS_OFDM: + return &head->ofdm[desc->idx]; + case RTW89_RS_MCS: + return &head->mcs[desc->ofdma][desc->nss][desc->idx]; + case RTW89_RS_HEDCM: + return &head->hedcm[desc->ofdma][desc->nss][desc->idx]; + case RTW89_RS_OFFSET: + return &head->offset[desc->idx]; + default: + rtw89_warn(rtwdev, "unrecognized byr rs: %d\n", desc->rs); + return &head->trap; + } +} + +void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl) +{ + const struct rtw89_txpwr_byrate_cfg *cfg = tbl->data; + const struct rtw89_txpwr_byrate_cfg *end = cfg + tbl->size; + struct rtw89_txpwr_byrate *byr_head; + struct rtw89_rate_desc desc = {}; + s8 *byr; + u32 data; + u8 i; + + for (; cfg < end; cfg++) { + byr_head = &rtwdev->byr[cfg->band][0]; + desc.rs = cfg->rs; + desc.nss = cfg->nss; + data = cfg->data; + + for (i = 0; i < cfg->len; i++, data >>= 8) { + desc.idx = cfg->shf + i; + byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc); + *byr = data & 0xff; + } + } +} +EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate); + +static s8 rtw89_phy_txpwr_dbm_without_tolerance(s8 dbm) +{ + const u8 tssi_deviation_point = 0; + const u8 tssi_max_deviation = 2; + + if (dbm <= tssi_deviation_point) + dbm -= tssi_max_deviation; + + return dbm; +} + +static s8 rtw89_phy_get_tpe_constraint(struct rtw89_dev *rtwdev, u8 band) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_reg_6ghz_tpe *tpe = ®ulatory->reg_6ghz_tpe; + s8 cstr = S8_MAX; + + if (band == RTW89_BAND_6G && tpe->valid) + cstr = rtw89_phy_txpwr_dbm_without_tolerance(tpe->constraint); + + return rtw89_phy_txpwr_dbm_to_mac(rtwdev, cstr); +} + +s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw, + const struct rtw89_rate_desc *rate_desc) +{ + struct rtw89_txpwr_byrate *byr_head; + s8 *byr; + + if (rate_desc->rs == RTW89_RS_CCK) + band = RTW89_BAND_2G; + + byr_head = &rtwdev->byr[band][bw]; + byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, rate_desc); + + return rtw89_phy_txpwr_rf_to_mac(rtwdev, *byr); +} + +static u8 rtw89_channel_6g_to_idx(struct rtw89_dev *rtwdev, u8 channel_6g) +{ + switch (channel_6g) { + case 1 ... 29: + return (channel_6g - 1) / 2; + case 33 ... 61: + return (channel_6g - 3) / 2; + case 65 ... 93: + return (channel_6g - 5) / 2; + case 97 ... 125: + return (channel_6g - 7) / 2; + case 129 ... 157: + return (channel_6g - 9) / 2; + case 161 ... 189: + return (channel_6g - 11) / 2; + case 193 ... 221: + return (channel_6g - 13) / 2; + case 225 ... 253: + return (channel_6g - 15) / 2; + default: + rtw89_warn(rtwdev, "unknown 6g channel: %d\n", channel_6g); + return 0; + } +} + +static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel) +{ + if (band == RTW89_BAND_6G) + return rtw89_channel_6g_to_idx(rtwdev, channel); + + switch (channel) { + case 1 ... 14: + return channel - 1; + case 36 ... 64: + return (channel - 36) / 2; + case 100 ... 144: + return ((channel - 100) / 2) + 15; + case 149 ... 177: + return ((channel - 149) / 2) + 38; + default: + rtw89_warn(rtwdev, "unknown channel: %d\n", channel); + return 0; + } +} + +static bool rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev *rtwdev, + u8 band, u8 bw) +{ + switch (band) { + case RTW89_BAND_2G: + return bw < RTW89_2G_BW_NUM; + case RTW89_BAND_5G: + return bw < RTW89_5G_BW_NUM; + case RTW89_BAND_6G: + return bw < RTW89_6G_BW_NUM; + default: + return false; + } +} + +s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, + u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) +{ + const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; + const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz; + const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz; + const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz; + const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; + const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; + const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); + bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band); + u32 freq = ieee80211_channel_to_frequency(ch, nl_band); + u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); + s8 lmt = 0, da_lmt = S8_MAX, sar, offset = 0; + u8 regd = rtw89_regd_get(rtwdev, band); + u8 reg6 = regulatory->reg_6ghz_power; + struct rtw89_sar_parm sar_parm = { + .center_freq = freq, + .ntx = ntx, + }; + s8 cstr; + + if (!rtw89_phy_validate_txpwr_limit_bw(rtwdev, band, bw)) { + rtw89_warn(rtwdev, "invalid band %u bandwidth %u\n", band, bw); + return 0; + } + + switch (band) { + case RTW89_BAND_2G: + if (has_ant_gain) + da_lmt = (*rule_da_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; + + lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; + if (lmt) + break; + + lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; + break; + case RTW89_BAND_5G: + if (has_ant_gain) + da_lmt = (*rule_da_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; + + lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; + if (lmt) + break; + + lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; + break; + case RTW89_BAND_6G: + if (has_ant_gain) + da_lmt = (*rule_da_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx]; + + lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx]; + if (lmt) + break; + + lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][RTW89_WW] + [RTW89_REG_6GHZ_POWER_DFLT] + [ch_idx]; + break; + default: + rtw89_warn(rtwdev, "unknown band type: %d\n", band); + return 0; + } + + da_lmt = da_lmt ?: S8_MAX; + if (da_lmt != S8_MAX) + offset = rtw89_phy_ant_gain_offset(rtwdev, freq); + + lmt = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt + offset, da_lmt)); + sar = rtw89_query_sar(rtwdev, &sar_parm); + cstr = rtw89_phy_get_tpe_constraint(rtwdev, band); + + return min3(lmt, sar, cstr); +} +EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit); + +#define __fill_txpwr_limit_nonbf_bf(ptr, band, bw, ntx, rs, ch) \ + do { \ + u8 __i; \ + for (__i = 0; __i < RTW89_BF_NUM; __i++) \ + ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev, \ + band, \ + bw, ntx, \ + rs, __i, \ + (ch)); \ + } while (0) + +static void rtw89_phy_fill_txpwr_limit_20m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ax *lmt, + u8 band, u8 ntx, u8 ch) +{ + __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_CCK, ch); + __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_CCK, ch); + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_OFDM, ch); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch); +} + +static void rtw89_phy_fill_txpwr_limit_40m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ax *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_CCK, ch - 2); + __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_CCK, ch); + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_OFDM, pri_ch); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch); +} + +static void rtw89_phy_fill_txpwr_limit_80m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ax *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + s8 val_0p5_n[RTW89_BF_NUM]; + s8 val_0p5_p[RTW89_BF_NUM]; + u8 i; + + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_OFDM, pri_ch); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 6); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 6); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 4); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 4); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, + ntx, RTW89_RS_MCS, ch); + + __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 4); + __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 4); + + for (i = 0; i < RTW89_BF_NUM; i++) + lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]); +} + +static void rtw89_phy_fill_txpwr_limit_160m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ax *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + s8 val_0p5_n[RTW89_BF_NUM]; + s8 val_0p5_p[RTW89_BF_NUM]; + s8 val_2p5_n[RTW89_BF_NUM]; + s8 val_2p5_p[RTW89_BF_NUM]; + u8 i; + + /* fill ofdm section */ + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_OFDM, pri_ch); + + /* fill mcs 20m section */ + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 14); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 10); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 6); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch - 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 2); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 6); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 10); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], band, + RTW89_CHANNEL_WIDTH_20, + ntx, RTW89_RS_MCS, ch + 14); + + /* fill mcs 40m section */ + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 12); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 4); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 4); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], band, + RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 12); + + /* fill mcs 80m section */ + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, + ntx, RTW89_RS_MCS, ch - 8); + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], band, + RTW89_CHANNEL_WIDTH_80, + ntx, RTW89_RS_MCS, ch + 8); + + /* fill mcs 160m section */ + __fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, band, + RTW89_CHANNEL_WIDTH_160, + ntx, RTW89_RS_MCS, ch); + + /* fill mcs 40m 0p5 section */ + __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 4); + __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 4); + + for (i = 0; i < RTW89_BF_NUM; i++) + lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]); + + /* fill mcs 40m 2p5 section */ + __fill_txpwr_limit_nonbf_bf(val_2p5_n, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch - 8); + __fill_txpwr_limit_nonbf_bf(val_2p5_p, band, RTW89_CHANNEL_WIDTH_40, + ntx, RTW89_RS_MCS, ch + 8); + + for (i = 0; i < RTW89_BF_NUM; i++) + lmt->mcs_40m_2p5[i] = min_t(s8, val_2p5_n[i], val_2p5_p[i]); +} + +static +void rtw89_phy_fill_txpwr_limit_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_ax *lmt, + u8 ntx) +{ + u8 band = chan->band_type; + u8 pri_ch = chan->primary_channel; + u8 ch = chan->channel; + u8 bw = chan->band_width; + + memset(lmt, 0, sizeof(*lmt)); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_fill_txpwr_limit_20m_ax(rtwdev, lmt, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_fill_txpwr_limit_40m_ax(rtwdev, lmt, band, ntx, ch, + pri_ch); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_fill_txpwr_limit_80m_ax(rtwdev, lmt, band, ntx, ch, + pri_ch); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_fill_txpwr_limit_160m_ax(rtwdev, lmt, band, ntx, ch, + pri_ch); + break; + } +} + +s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, + u8 ru, u8 ntx, u8 ch) +{ + const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; + const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz; + const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz; + const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz; + const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; + const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; + const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); + bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band); + u32 freq = ieee80211_channel_to_frequency(ch, nl_band); + u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); + s8 lmt_ru = 0, da_lmt_ru = S8_MAX, sar, offset = 0; + u8 regd = rtw89_regd_get(rtwdev, band); + u8 reg6 = regulatory->reg_6ghz_power; + struct rtw89_sar_parm sar_parm = { + .center_freq = freq, + .ntx = ntx, + }; + s8 cstr; + + switch (band) { + case RTW89_BAND_2G: + if (has_ant_gain) + da_lmt_ru = (*rule_da_2ghz->lmt_ru)[ru][ntx][regd][ch_idx]; + + lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][regd][ch_idx]; + if (lmt_ru) + break; + + lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; + break; + case RTW89_BAND_5G: + if (has_ant_gain) + da_lmt_ru = (*rule_da_5ghz->lmt_ru)[ru][ntx][regd][ch_idx]; + + lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][regd][ch_idx]; + if (lmt_ru) + break; + + lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; + break; + case RTW89_BAND_6G: + if (has_ant_gain) + da_lmt_ru = (*rule_da_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx]; + + lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx]; + if (lmt_ru) + break; + + lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][RTW89_WW] + [RTW89_REG_6GHZ_POWER_DFLT] + [ch_idx]; + break; + default: + rtw89_warn(rtwdev, "unknown band type: %d\n", band); + return 0; + } + + da_lmt_ru = da_lmt_ru ?: S8_MAX; + if (da_lmt_ru != S8_MAX) + offset = rtw89_phy_ant_gain_offset(rtwdev, freq); + + lmt_ru = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt_ru + offset, da_lmt_ru)); + sar = rtw89_query_sar(rtwdev, &sar_parm); + cstr = rtw89_phy_get_tpe_constraint(rtwdev, band); + + return min3(lmt_ru, sar, cstr); +} + +static void +rtw89_phy_fill_txpwr_limit_ru_20m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_ax *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch); + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch); + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch); +} + +static void +rtw89_phy_fill_txpwr_limit_ru_40m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_ax *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch - 2); + lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch + 2); + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch - 2); + lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch + 2); + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch - 2); + lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch + 2); +} + +static void +rtw89_phy_fill_txpwr_limit_ru_80m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_ax *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch - 6); + lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch - 2); + lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch + 2); + lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, ch + 6); + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch - 6); + lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch - 2); + lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch + 2); + lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, ch + 6); + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch - 6); + lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch - 2); + lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch + 2); + lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, ch + 6); +} + +static void +rtw89_phy_fill_txpwr_limit_ru_160m_ax(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_ax *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + static const int ofst[] = { -14, -10, -6, -2, 2, 6, 10, 14 }; + int i; + + static_assert(ARRAY_SIZE(ofst) == RTW89_RU_SEC_NUM_AX); + for (i = 0; i < RTW89_RU_SEC_NUM_AX; i++) { + lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, + ntx, + ch + ofst[i]); + lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, + ntx, + ch + ofst[i]); + lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, + ntx, + ch + ofst[i]); + } +} + +static +void rtw89_phy_fill_txpwr_limit_ru_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_ru_ax *lmt_ru, + u8 ntx) +{ + u8 band = chan->band_type; + u8 ch = chan->channel; + u8 bw = chan->band_width; + + memset(lmt_ru, 0, sizeof(*lmt_ru)); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_fill_txpwr_limit_ru_20m_ax(rtwdev, lmt_ru, band, ntx, + ch); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_fill_txpwr_limit_ru_40m_ax(rtwdev, lmt_ru, band, ntx, + ch); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_fill_txpwr_limit_ru_80m_ax(rtwdev, lmt_ru, band, ntx, + ch); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_fill_txpwr_limit_ru_160m_ax(rtwdev, lmt_ru, band, ntx, + ch); + break; + } +} + +static void rtw89_phy_set_txpwr_byrate_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 max_nss_num = rtwdev->chip->rf_path_num; + static const u8 rs[] = { + RTW89_RS_CCK, + RTW89_RS_OFDM, + RTW89_RS_MCS, + RTW89_RS_HEDCM, + }; + struct rtw89_rate_desc cur = {}; + u8 band = chan->band_type; + u8 ch = chan->channel; + u32 addr, val; + s8 v[4] = {}; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr byrate with ch=%d\n", ch); + + BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_CCK] % 4); + BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_OFDM] % 4); + BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_MCS] % 4); + BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_HEDCM] % 4); + + addr = R_AX_PWR_BY_RATE; + for (cur.nss = 0; cur.nss < max_nss_num; cur.nss++) { + for (i = 0; i < ARRAY_SIZE(rs); i++) { + if (cur.nss >= rtw89_rs_nss_num_ax[rs[i]]) + continue; + + cur.rs = rs[i]; + for (cur.idx = 0; cur.idx < rtw89_rs_idx_num_ax[rs[i]]; + cur.idx++) { + v[cur.idx % 4] = + rtw89_phy_read_txpwr_byrate(rtwdev, + band, 0, + &cur); + + if ((cur.idx + 1) % 4) + continue; + + val = FIELD_PREP(GENMASK(7, 0), v[0]) | + FIELD_PREP(GENMASK(15, 8), v[1]) | + FIELD_PREP(GENMASK(23, 16), v[2]) | + FIELD_PREP(GENMASK(31, 24), v[3]); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, + val); + addr += 4; + } + } + } +} + +static +void rtw89_phy_set_txpwr_offset_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rate_desc desc = { + .nss = RTW89_NSS_1, + .rs = RTW89_RS_OFFSET, + }; + u8 band = chan->band_type; + s8 v[RTW89_RATE_OFFSET_NUM_AX] = {}; + u32 val; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); + + for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_NUM_AX; desc.idx++) + v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, 0, &desc); + + BUILD_BUG_ON(RTW89_RATE_OFFSET_NUM_AX != 5); + val = FIELD_PREP(GENMASK(3, 0), v[0]) | + FIELD_PREP(GENMASK(7, 4), v[1]) | + FIELD_PREP(GENMASK(11, 8), v[2]) | + FIELD_PREP(GENMASK(15, 12), v[3]) | + FIELD_PREP(GENMASK(19, 16), v[4]); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, + GENMASK(19, 0), val); +} + +static void rtw89_phy_set_txpwr_limit_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 max_ntx_num = rtwdev->chip->rf_path_num; + struct rtw89_txpwr_limit_ax lmt; + u8 ch = chan->channel; + u8 bw = chan->band_width; + const s8 *ptr; + u32 addr, val; + u8 i, j; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); + + BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ax) != + RTW89_TXPWR_LMT_PAGE_SIZE_AX); + + addr = R_AX_PWR_LMT; + for (i = 0; i < max_ntx_num; i++) { + rtw89_phy_fill_txpwr_limit_ax(rtwdev, chan, &lmt, i); + + ptr = (s8 *)&lmt; + for (j = 0; j < RTW89_TXPWR_LMT_PAGE_SIZE_AX; + j += 4, addr += 4, ptr += 4) { + val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | + FIELD_PREP(GENMASK(15, 8), ptr[1]) | + FIELD_PREP(GENMASK(23, 16), ptr[2]) | + FIELD_PREP(GENMASK(31, 24), ptr[3]); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } +} + +static void rtw89_phy_set_txpwr_limit_ru_ax(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 max_ntx_num = rtwdev->chip->rf_path_num; + struct rtw89_txpwr_limit_ru_ax lmt_ru; + u8 ch = chan->channel; + u8 bw = chan->band_width; + const s8 *ptr; + u32 addr, val; + u8 i, j; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); + + BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ru_ax) != + RTW89_TXPWR_LMT_RU_PAGE_SIZE_AX); + + addr = R_AX_PWR_RU_LMT; + for (i = 0; i < max_ntx_num; i++) { + rtw89_phy_fill_txpwr_limit_ru_ax(rtwdev, chan, &lmt_ru, i); + + ptr = (s8 *)&lmt_ru; + for (j = 0; j < RTW89_TXPWR_LMT_RU_PAGE_SIZE_AX; + j += 4, addr += 4, ptr += 4) { + val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | + FIELD_PREP(GENMASK(15, 8), ptr[1]) | + FIELD_PREP(GENMASK(23, 16), ptr[2]) | + FIELD_PREP(GENMASK(31, 24), ptr[3]); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } +} + +struct rtw89_phy_iter_ra_data { + struct rtw89_dev *rtwdev; + struct sk_buff *c2h; +}; + +static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + struct rtw89_phy_iter_ra_data *ra_data, + bool *changed) +{ + struct rtw89_dev *rtwdev = ra_data->rtwdev; + const struct rtw89_c2h_ra_rpt *c2h = + (const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data; + struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report; + const struct rtw89_chip_info *chip = rtwdev->chip; + bool format_v1 = chip->chip_gen == RTW89_CHIP_BE; + u8 mode, rate, bw, giltf, mac_id; + u16 legacy_bitrate, amsdu_len; + u8 retry_ratio = 0; + bool valid; + u8 mcs = 0; + u8 t; + + mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID); + if (mac_id != rtwsta_link->mac_id) + return; + + rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS); + bw = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW); + giltf = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_GILTF); + mode = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL); + + if (format_v1) { + t = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MCSNSS_B7); + rate |= u8_encode_bits(t, BIT(7)); + t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW_B2); + bw |= u8_encode_bits(t, BIT(2)); + t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL_B2); + mode |= u8_encode_bits(t, BIT(2)); + retry_ratio = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_RETRY_RATIO); + } + + if (mode == RTW89_RA_RPT_MODE_LEGACY) { + valid = rtw89_legacy_rate_to_bitrate(rtwdev, rate, &legacy_bitrate); + if (!valid) + return; + } + + memset(&ra_report->txrate, 0, sizeof(ra_report->txrate)); + + switch (mode) { + case RTW89_RA_RPT_MODE_LEGACY: + ra_report->txrate.legacy = legacy_bitrate; + break; + case RTW89_RA_RPT_MODE_HT: + ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (RTW89_CHK_FW_FEATURE(OLD_HT_RA_FORMAT, &rtwdev->fw)) + rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate), + FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate)); + else + rate = FIELD_GET(RTW89_RA_RATE_MASK_HT_MCS, rate); + ra_report->txrate.mcs = rate; + if (giltf) + ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + mcs = ra_report->txrate.mcs & 0x07; + break; + case RTW89_RA_RPT_MODE_VHT: + ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + ra_report->txrate.mcs = format_v1 ? + u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) : + u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS); + ra_report->txrate.nss = format_v1 ? + u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 : + u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1; + if (giltf) + ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + mcs = ra_report->txrate.mcs; + break; + case RTW89_RA_RPT_MODE_HE: + ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS; + ra_report->txrate.mcs = format_v1 ? + u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) : + u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS); + ra_report->txrate.nss = format_v1 ? + u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 : + u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1; + if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08) + ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_0_8; + else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16) + ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_1_6; + else + ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2; + mcs = ra_report->txrate.mcs; + break; + case RTW89_RA_RPT_MODE_EHT: + ra_report->txrate.flags |= RATE_INFO_FLAGS_EHT_MCS; + ra_report->txrate.mcs = u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1); + ra_report->txrate.nss = u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1; + if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08) + ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_0_8; + else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16) + ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_1_6; + else + ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_3_2; + mcs = ra_report->txrate.mcs; + break; + } + + ra_report->txrate.bw = rtw89_hw_to_rate_info_bw(bw); + ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate); + ra_report->hw_rate = format_v1 ? + u16_encode_bits(mode, RTW89_HW_RATE_V1_MASK_MOD) | + u16_encode_bits(rate, RTW89_HW_RATE_V1_MASK_VAL) : + u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) | + u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL); + ra_report->retry_ratio = retry_ratio; + ra_report->might_fallback_legacy = mcs <= 2; + + amsdu_len = get_max_amsdu_len(rtwdev, ra_report); + if (link_sta->agg.max_rc_amsdu_len != amsdu_len) { + link_sta->agg.max_rc_amsdu_len = amsdu_len; + *changed = true; + } + + rtwsta_link->max_agg_wait = link_sta->agg.max_rc_amsdu_len / 1500 - 1; +} + +static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + struct ieee80211_link_sta *link_sta; + unsigned int link_id; + bool changed = false; + + rcu_read_lock(); + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data, &changed); + } + + if (changed) + ieee80211_sta_recalc_aggregates(sta); + + rcu_read_unlock(); +} + +static void +rtw89_phy_c2h_ra_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + struct rtw89_phy_iter_ra_data ra_data; + + ra_data.rtwdev = rtwdev; + ra_data.c2h = c2h; + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_phy_c2h_ra_rpt_iter, + &ra_data); +} + +static void +rtw89_phy_c2h_tx_history(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_ra_tx_history *history = (const void *)c2h->data; + u32 *tx_rate_cnt = rtwdev->phystat.tx_rate_cnt; + u32 i; + + for (i = 0; i < RTW89_TX_RATE_NR; i++) + tx_rate_cnt[i] = le32_to_cpu(history->tx_rate_tot_cnt_hist[i]); +} + +static +void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_PHY_C2H_FUNC_STS_RPT] = rtw89_phy_c2h_ra_rpt, + [RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT] = NULL, + [RTW89_PHY_C2H_FUNC_TXSTS] = NULL, + [RTW89_PHY_C2H_FUNC_TX_HISTORY] = rtw89_phy_c2h_tx_history, + [RTW89_PHY_C2H_FUNC_ACCELERATE_EN] = rtw89_fw_c2h_dummy_handler, +}; + +static void +rtw89_phy_c2h_lowrt_rty(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ +} + +static void +rtw89_phy_c2h_lps_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_lps_rpt *c2h_rpt = (const void *)c2h->data; + const __le32 *data_a, *data_b; + u16 len_info, cr_len, idx; + const __le16 *addr; + const u8 *info; + + /* elements size of BBCR/BBMCUCR/RFCR are 6/6/10 bytes respectively */ + cr_len = c2h_rpt->cnt_bbcr * 6 + + c2h_rpt->cnt_bbmcucr * 6 + + c2h_rpt->cnt_rfcr * 10; + len_info = len - (sizeof(*c2h_rpt) + cr_len); + + if (len < sizeof(*c2h_rpt) + cr_len || len_info % 4 != 0) { + rtw89_debug(rtwdev, RTW89_DBG_PS, + "Invalid LPS RPT len(%d) TYPE(%d) CRCNT: BB(%d) MCU(%d) RF(%d)\n", + len, c2h_rpt->type, c2h_rpt->cnt_bbcr, + c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_PS, + "LPS RPT TYPE(%d), CRCNT: BB(%d) MCU(%d) RF(%d)\n", + c2h_rpt->type, c2h_rpt->cnt_bbcr, + c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr); + + info = &c2h_rpt->data[0]; + for (idx = 0; idx < len_info; idx += 4, info += 4) + rtw89_debug(rtwdev, RTW89_DBG_PS, + "BB LPS INFO (%02d) - 0x%02x,0x%02x,0x%02x,0x%02x\n", + idx, info[3], info[2], info[1], info[0]); + + addr = (const void *)(info); + data_a = (const void *)(addr + c2h_rpt->cnt_bbcr); + for (idx = 0; idx < c2h_rpt->cnt_bbcr; idx++, addr++, data_a++) + rtw89_debug(rtwdev, RTW89_DBG_PS, + "LPS BB CR - 0x%04x=0x%08x\n", + le16_to_cpu(*addr), le32_to_cpu(*data_a)); + + addr = (const void *)data_a; + data_a = (const void *)(addr + c2h_rpt->cnt_bbmcucr); + for (idx = 0; idx < c2h_rpt->cnt_bbmcucr; idx++, addr++, data_a++) + rtw89_debug(rtwdev, RTW89_DBG_PS, + "LPS BBMCU - 0x%04x=0x%08x\n", + le16_to_cpu(*addr), le32_to_cpu(*data_a)); + + addr = (const void *)data_a; + data_a = (const void *)(addr + c2h_rpt->cnt_rfcr); + data_b = (const void *)(data_a + c2h_rpt->cnt_rfcr); + for (idx = 0; idx < c2h_rpt->cnt_rfcr; idx++, addr++, data_a++, data_b++) + rtw89_debug(rtwdev, RTW89_DBG_PS, + "LPS RFCR - 0x%04x=0x%05x,0x%05x\n", + le16_to_cpu(*addr), le32_to_cpu(*data_a), + le32_to_cpu(*data_b)); +} + +static void +rtw89_phy_c2h_fw_scan_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_fw_scan_rpt *c2h_rpt = + (const struct rtw89_c2h_fw_scan_rpt *)c2h->data; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "%s: band: %u, op_chan: %u, PD_low_bd(ofdm, cck): (-%d, %d), phy_idx: %u\n", + __func__, c2h_rpt->band, c2h_rpt->center_ch, + PD_LOWER_BOUND_BASE - (c2h_rpt->ofdm_pd_idx << 1), + c2h_rpt->cck_pd_idx, c2h_rpt->phy_idx); +} + +static +void (* const rtw89_phy_c2h_dm_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_PHY_C2H_DM_FUNC_FW_TEST] = NULL, + [RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT] = NULL, + [RTW89_PHY_C2H_DM_FUNC_SIGB] = NULL, + [RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY] = rtw89_phy_c2h_lowrt_rty, + [RTW89_PHY_C2H_DM_FUNC_MCC_DIG] = NULL, + [RTW89_PHY_C2H_DM_FUNC_LPS] = rtw89_phy_c2h_lps_rpt, + [RTW89_PHY_C2H_DM_FUNC_ENV_MNTR] = rtw89_fw_c2h_dummy_handler, + [RTW89_PHY_C2H_DM_FUNC_FW_SCAN] = rtw89_phy_c2h_fw_scan_rpt, +}; + +static +void rtw89_phy_c2h_rfk_tas_pwr(struct rtw89_dev *rtwdev, + const struct rtw89_c2h_rf_tas_rpt_log *content) +{ + const enum rtw89_sar_sources src = rtwdev->sar.src; + struct rtw89_tas_info *tas = &rtwdev->tas; + u64 linear = 0; + u32 i, cur_idx; + s16 txpwr; + + if (!tas->enable || src == RTW89_SAR_SOURCE_NONE) + return; + + cur_idx = le32_to_cpu(content->cur_idx); + for (i = 0; i < cur_idx; i++) { + txpwr = le16_to_cpu(content->txpwr_history[i]); + linear += rtw89_db_quarter_to_linear(txpwr); + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: index: %u, txpwr: %d\n", i, txpwr); + } + + if (cur_idx == 0) + tas->instant_txpwr = rtw89_db_to_linear(0); + else + tas->instant_txpwr = DIV_ROUND_DOWN_ULL(linear, cur_idx); +} + +static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, + enum rtw89_phy_c2h_rfk_log_func func, + void *content, u16 len) +{ + struct rtw89_c2h_rf_txgapk_rpt_log *txgapk; + struct rtw89_c2h_rf_rxdck_rpt_log *rxdck; + struct rtw89_c2h_rf_txiqk_rpt_log *txiqk; + struct rtw89_c2h_rf_cim3k_rpt_log *cim3k; + struct rtw89_c2h_rf_dack_rpt_log *dack; + struct rtw89_c2h_rf_tssi_rpt_log *tssi; + struct rtw89_c2h_rf_dpk_rpt_log *dpk; + struct rtw89_c2h_rf_iqk_rpt_log *iqk; + int i, j, k; + + switch (func) { + case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK: + if (len != sizeof(*iqk)) + goto out; + + iqk = content; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_iqk_init = %x\n", iqk->is_iqk_init); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_reload = %x\n", iqk->is_reload); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_nbiqk = %x\n", iqk->is_nbiqk); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->txiqk_en = %x\n", iqk->txiqk_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rxiqk_en = %x\n", iqk->rxiqk_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->lok_en = %x\n", iqk->lok_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_xym_en = %x\n", iqk->iqk_xym_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_sram_en = %x\n", iqk->iqk_sram_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_fft_en = %x\n", iqk->iqk_fft_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_fw_iqk = %x\n", iqk->is_fw_iqk); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_iqk_enable = %x\n", iqk->is_iqk_enable); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_cfir_en = %x\n", iqk->iqk_cfir_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->thermal_rek_en = %x\n", iqk->thermal_rek_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->version = %x\n", iqk->version); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->phy = %x\n", iqk->phy); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status); + + for (i = 0; i < 2; i++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] ======== Path %x ========\n", i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n", + i, iqk->iqk_band[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_ch[%d] = %x\n", + i, iqk->iqk_ch[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n", + i, iqk->iqk_bw[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->rf_0x18[%d] = %x\n", + i, le32_to_cpu(iqk->rf_0x18[i])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n", + i, le32_to_cpu(iqk->lok_idac[i])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n", + i, le32_to_cpu(iqk->lok_vbuf[i])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_tx_fail[%d] = %x\n", + i, iqk->iqk_tx_fail[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n", + i, iqk->iqk_rx_fail[i]); + for (j = 0; j < 6; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rftxgain[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rftxgain[i][j])); + for (j = 0; j < 6; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->tx_xym[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->tx_xym[i][j])); + for (j = 0; j < 6; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rfrxgain[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rfrxgain[i][j])); + for (j = 0; j < 6; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rx_xym[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rx_xym[i][j])); + + if (!iqk->iqk_xym_en) + continue; + + for (j = 0; j < 32; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rx_wb_xym[%d][%d] = %x\n", + i, j, iqk->rx_wb_xym[i][j]); + } + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK: + if (len != sizeof(*dpk)) + goto out; + + dpk = content; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "DPK ver:%d idx:%2ph band:%2ph bw:%2ph ch:%2ph path:%2ph\n", + dpk->ver, dpk->idx, dpk->band, dpk->bw, dpk->ch, dpk->path_ok); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "DPK txagc:%2ph ther:%2ph gs:%2ph dc_i:%4ph dc_q:%4ph\n", + dpk->txagc, dpk->ther, dpk->gs, dpk->dc_i, dpk->dc_q); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "DPK corr_v:%2ph corr_i:%2ph to:%2ph ov:%2ph\n", + dpk->corr_val, dpk->corr_idx, dpk->is_timeout, dpk->rxbb_ov); + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK: + if (len != sizeof(*dack)) + goto out; + + dack = content; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]FWDACK SUMMARY!!!!!\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]FWDACK ver = 0x%x, FWDACK rpt_ver = 0x%x, driver rpt_ver = 0x%x\n", + dack->fwdack_ver, dack->fwdack_info_ver, 0x2); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]timeout code = [0x%x 0x%x 0x%x 0x%x 0x%x]\n", + dack->addck_timeout, dack->cdack_timeout, dack->dadck_timeout, + dack->adgaink_timeout, dack->msbk_timeout); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]DACK fail = 0x%x\n", dack->dack_fail); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 WBADCK = [0x%x]\n", dack->wbdck_d[0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 WBADCK = [0x%x]\n", dack->wbdck_d[1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]DRCK = [0x%x]\n", dack->rck_d); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n", + dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n", + dack->cdack_d[0][1][0], dack->cdack_d[0][1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK ic = [0x%x, 0x%x]\n", + dack->cdack_d[1][0][0], dack->cdack_d[1][0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK qc = [0x%x, 0x%x]\n", + dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n", + ((u32)dack->addck2_hd[0][0][0] << 8) | dack->addck2_ld[0][0][0], + ((u32)dack->addck2_hd[0][0][1] << 8) | dack->addck2_ld[0][0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n", + ((u32)dack->addck2_hd[0][1][0] << 8) | dack->addck2_ld[0][1][0], + ((u32)dack->addck2_hd[0][1][1] << 8) | dack->addck2_ld[0][1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n", + ((u32)dack->addck2_hd[1][0][0] << 8) | dack->addck2_ld[1][0][0], + ((u32)dack->addck2_hd[1][0][1] << 8) | dack->addck2_ld[1][0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n", + ((u32)dack->addck2_hd[1][1][0] << 8) | dack->addck2_ld[1][1][0], + ((u32)dack->addck2_hd[1][1][1] << 8) | dack->addck2_ld[1][1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n", + dack->adgaink_d[0][0], dack->adgaink_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_GAINK ic = 0x%x, qc = 0x%x\n", + dack->adgaink_d[1][0], dack->adgaink_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n", + ((u32)dack->biask_hd[0][0] << 8) | dack->biask_ld[0][0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n", + ((u32)dack->biask_hd[1][0] << 8) | dack->biask_ld[1][0]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[0][0][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[0][1][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[1][0][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[1][1][i]); + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK: + if (len != sizeof(*rxdck)) + goto out; + + rxdck = content; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "RXDCK ver:%d band:%2ph bw:%2ph ch:%2ph to:%2ph\n", + rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch, + rxdck->timeout); + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI: + if (len != sizeof(*tssi)) + goto out; + + tssi = content; + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 4; k++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw_h[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power_cw_h[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw_l[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power_cw_l[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw[%d][%d][%d]=%d\n", + i, j, k, + (tssi->alignment_power_cw_h[i][j][k] << 8) + + tssi->alignment_power_cw_l[i][j][k]); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] tssi_alimk_state[%d][%d]=%d\n", + i, j, tssi->tssi_alimk_state[i][j]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] default_txagc_offset[%d]=%d\n", + j, tssi->default_txagc_offset[0][j]); + } + } + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK: + if (len != sizeof(*txgapk)) + goto out; + + txgapk = content; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TXGAPK]rpt r0x8010[0]=0x%x, r0x8010[1]=0x%x\n", + le32_to_cpu(txgapk->r0x8010[0]), + le32_to_cpu(txgapk->r0x8010[1])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_id = %d\n", + txgapk->chk_id); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_cnt = %d\n", + le32_to_cpu(txgapk->chk_cnt)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt ver = 0x%x\n", + txgapk->ver); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt d_bnd_ok = %d\n", + txgapk->d_bnd_ok); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[0] = 0x%x\n", + le32_to_cpu(txgapk->stage[0])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[1] = 0x%x\n", + le32_to_cpu(txgapk->stage[1])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[0] = 0x%x\n", + le16_to_cpu(txgapk->failcode[0])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[1] = 0x%x\n", + le16_to_cpu(txgapk->failcode[1])); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[0] = %*ph\n", + (int)sizeof(txgapk->track_d[0]), txgapk->track_d[0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[0] = %*ph\n", + (int)sizeof(txgapk->power_d[0]), txgapk->power_d[0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[1] = %*ph\n", + (int)sizeof(txgapk->track_d[1]), txgapk->track_d[1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[1] = %*ph\n", + (int)sizeof(txgapk->power_d[1]), txgapk->power_d[1]); + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR: + if (len != sizeof(struct rtw89_c2h_rf_tas_rpt_log)) + goto out; + + rtw89_phy_c2h_rfk_tas_pwr(rtwdev, content); + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK: + if (len != sizeof(*txiqk)) + goto out; + return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K: + if (len != sizeof(*cim3k)) + goto out; + return; + default: + break; + } + +out: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "unexpected RFK func %d report log with length %d\n", func, len); +} + +static bool rtw89_phy_c2h_rfk_run_log(struct rtw89_dev *rtwdev, + enum rtw89_phy_c2h_rfk_log_func func, + void *content, u16 len) +{ + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_c2h_rf_run_log *log = content; + const struct rtw89_fw_element_hdr *elm; + u32 fmt_idx; + u16 offset; + + if (sizeof(*log) != len) + return false; + + if (!elm_info->rfk_log_fmt) + return false; + + elm = elm_info->rfk_log_fmt->elm[func]; + fmt_idx = le32_to_cpu(log->fmt_idx); + if (!elm || fmt_idx >= elm->u.rfk_log_fmt.nr) + return false; + + offset = le16_to_cpu(elm->u.rfk_log_fmt.offset[fmt_idx]); + if (offset == 0) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, &elm->u.common.contents[offset], + le32_to_cpu(log->arg[0]), le32_to_cpu(log->arg[1]), + le32_to_cpu(log->arg[2]), le32_to_cpu(log->arg[3])); + + return true; +} + +static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u32 len, enum rtw89_phy_c2h_rfk_log_func func, + const char *rfk_name) +{ + struct rtw89_c2h_hdr *c2h_hdr = (struct rtw89_c2h_hdr *)c2h->data; + struct rtw89_c2h_rf_log_hdr *log_hdr; + void *log_ptr = c2h_hdr; + u16 content_len; + u16 chunk_len; + bool handled; + + log_ptr += sizeof(*c2h_hdr); + len -= sizeof(*c2h_hdr); + + while (len > sizeof(*log_hdr)) { + log_hdr = log_ptr; + content_len = le16_to_cpu(log_hdr->len); + chunk_len = content_len + sizeof(*log_hdr); + + if (chunk_len > len) + break; + + switch (log_hdr->type) { + case RTW89_RF_RUN_LOG: + handled = rtw89_phy_c2h_rfk_run_log(rtwdev, func, + log_hdr->content, content_len); + if (handled) + break; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s run: %*ph\n", + rfk_name, content_len, log_hdr->content); + break; + case RTW89_RF_RPT_LOG: + rtw89_phy_c2h_rfk_rpt_log(rtwdev, func, + log_hdr->content, content_len); + break; + default: + return; + } + + log_ptr += chunk_len; + len -= chunk_len; + } +} + +static void +rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_IQK, "IQK"); +} + +static void +rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_DPK, "DPK"); +} + +static void +rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_DACK, "DACK"); +} + +static void +rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK, "RX_DCK"); +} + +static void +rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI, "TSSI"); +} + +static void +rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK, "TXGAPK"); +} + +static void +rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR, "TAS"); +} + +static void +rtw89_phy_c2h_rfk_log_txiqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK, "TXIQK"); +} + +static void +rtw89_phy_c2h_rfk_log_cim3k(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, + RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K, "CIM3K"); +} + +static +void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_PHY_C2H_RFK_LOG_FUNC_IQK] = rtw89_phy_c2h_rfk_log_iqk, + [RTW89_PHY_C2H_RFK_LOG_FUNC_DPK] = rtw89_phy_c2h_rfk_log_dpk, + [RTW89_PHY_C2H_RFK_LOG_FUNC_DACK] = rtw89_phy_c2h_rfk_log_dack, + [RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK] = rtw89_phy_c2h_rfk_log_rxdck, + [RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI] = rtw89_phy_c2h_rfk_log_tssi, + [RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk, + [RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR] = rtw89_phy_c2h_rfk_log_tas_pwr, + [RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK] = rtw89_phy_c2h_rfk_log_txiqk, + [RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K] = rtw89_phy_c2h_rfk_log_cim3k, +}; + +#define NAME_RTW89_RFK_REPORT(type) \ + [RTW89_RFK_REPORT_ ## type] = #type + +const char * const rtw89_rfk_report_names[] = { + NAME_RTW89_RFK_REPORT(PRE_NTFY), + NAME_RTW89_RFK_REPORT(TSSI), + NAME_RTW89_RFK_REPORT(IQK), + NAME_RTW89_RFK_REPORT(DPK), + NAME_RTW89_RFK_REPORT(TXGAPK), + NAME_RTW89_RFK_REPORT(DACK), + NAME_RTW89_RFK_REPORT(RX_DCK), + NAME_RTW89_RFK_REPORT(TX_IQK), + NAME_RTW89_RFK_REPORT(CIM3k), +}; + +static_assert(ARRAY_SIZE(rtw89_rfk_report_names) == NUM_OF_RTW89_RFK_REPORT_TYPES); + +static +void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait; + + wait->state = RTW89_RFK_STATE_START; + wait->start_time = ktime_get(); + reinit_completion(&wait->completion); +} + +static +int ____rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name, + unsigned int ms) +{ + struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait; + unsigned long time_left; + + /* + * USB transport adds latency to H2C/C2H round-trips, so RF + * calibrations take longer than on PCIe. Apply a 4x multiplier + * to avoid spurious timeouts. + */ + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + ms *= 4; + + /* Since we can't receive C2H event during SER, use a fixed delay. */ + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) { + fsleep(1000 * ms / 2); + goto out; + } + + time_left = wait_for_completion_timeout(&wait->completion, + msecs_to_jiffies(ms)); + if (time_left == 0) { + rtw89_warn(rtwdev, "failed to wait RF %s\n", rfk_name); + return -ETIMEDOUT; + } else if (wait->state != RTW89_RFK_STATE_OK) { + rtw89_warn(rtwdev, "failed to do RF %s result from state %d\n", + rfk_name, wait->state); + return -EFAULT; + } + +out: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "RF %s takes %lld ms to complete\n", + rfk_name, ktime_ms_delta(ktime_get(), wait->start_time)); + + return 0; +} + +static +int __rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, + enum rtw89_rfk_report_types rfk_type, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + const char *rfk_name = rtw89_rfk_report_names[rfk_type]; + struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait; + struct rtw89_rfk_record *record = wait->record_ptr; + int ret; + + ret = ____rtw89_phy_rfk_report_wait(rtwdev, rfk_name, ms); + + if (record) + record->states[rfk_type] = wait->state; + + return ret; +} + +#define rtw89_phy_rfk_report_wait(rtwdev, type, phy_idx, chan, ms) \ + __rtw89_phy_rfk_report_wait(rtwdev, RTW89_RFK_REPORT_ ## type, phy_idx, chan, ms) + +static void +rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_rfk_report *report = + (const struct rtw89_c2h_rfk_report *)c2h->data; + struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait; + + wait->state = report->state; + wait->version = report->version; + + complete(&wait->completion); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "RFK report state %d with version %d (%*ph)\n", + wait->state, wait->version, + (int)(len - sizeof(report->hdr)), &report->state); +} + +static void +rtw89_phy_c2h_rfk_report_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +{ + const struct rtw89_c2h_rf_tas_info *report = + (const struct rtw89_c2h_rf_tas_info *)c2h->data; + + rtw89_phy_c2h_rfk_tas_pwr(rtwdev, &report->content); +} + +static +void (* const rtw89_phy_c2h_rfk_report_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { + [RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE] = rtw89_phy_c2h_rfk_report_state, + [RTW89_PHY_C2H_RFK_REPORT_FUNC_TAS_PWR] = rtw89_phy_c2h_rfk_report_tas_pwr, +}; + +bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) +{ + switch (class) { + case RTW89_PHY_C2H_RFK_LOG: + switch (func) { + case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK: + case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK: + case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK: + case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK: + case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI: + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK: + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK: + return true; + default: + return false; + } + case RTW89_PHY_C2H_RFK_REPORT: + switch (func) { + case RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE: + return true; + default: + return false; + } + default: + return false; + } +} + +void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func) +{ + void (*handler)(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = NULL; + + switch (class) { + case RTW89_PHY_C2H_CLASS_RA: + if (func < ARRAY_SIZE(rtw89_phy_c2h_ra_handler)) + handler = rtw89_phy_c2h_ra_handler[func]; + break; + case RTW89_PHY_C2H_RFK_LOG: + if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_log_handler)) + handler = rtw89_phy_c2h_rfk_log_handler[func]; + break; + case RTW89_PHY_C2H_RFK_REPORT: + if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_report_handler)) + handler = rtw89_phy_c2h_rfk_report_handler[func]; + break; + case RTW89_PHY_C2H_CLASS_DM: + if (func < ARRAY_SIZE(rtw89_phy_c2h_dm_handler)) + handler = rtw89_phy_c2h_dm_handler[func]; + break; + default: + break; + } + if (!handler) { + rtw89_info_once(rtwdev, "PHY c2h class %d func %d not support\n", + class, func); + return; + } + handler(rtwdev, skb, len); +} + +int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + unsigned int ms) +{ + int ret; + + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) { + rtw89_phy_rfk_report_prep(rtwdev); + rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx); + ret = rtw89_phy_rfk_report_wait(rtwdev, PRE_NTFY, phy_idx, NULL, ms); + if (ret) + return ret; + } + + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, &rtwdev->fw)) { + ret = rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx); + if (ret) + return ret; + } + + return 0; + +} +EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait); + +int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + enum rtw89_tssi_mode tssi_mode, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_tssi(rtwdev, phy_idx, chan, tssi_mode); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, TSSI, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_tssi_and_wait); + +int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_iqk(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, IQK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_iqk_and_wait); + +int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_dpk(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, DPK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_dpk_and_wait); + +int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_txgapk(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, TXGAPK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_txgapk_and_wait); + +int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_dack(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, DACK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait); + +int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + bool is_chl_k, unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan, is_chl_k); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, RX_DCK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_rxdck_and_wait); + +int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_txiqk(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, TX_IQK, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_txiqk_and_wait); + +int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms) +{ + int ret; + + rtw89_phy_rfk_report_prep(rtwdev); + + ret = rtw89_fw_h2c_rf_cim3k(rtwdev, phy_idx, chan); + if (ret) + return ret; + + return rtw89_phy_rfk_report_wait(rtwdev, CIM3k, phy_idx, chan, ms); +} +EXPORT_SYMBOL(rtw89_phy_rfk_cim3k_and_wait); + +static u32 phy_tssi_get_cck_group(u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define PHY_TSSI_EXTRA_GROUP_BIT BIT(31) +#define PHY_TSSI_EXTRA_GROUP(idx) (PHY_TSSI_EXTRA_GROUP_BIT | (idx)) +#define PHY_IS_TSSI_EXTRA_GROUP(group) ((group) & PHY_TSSI_EXTRA_GROUP_BIT) +#define PHY_TSSI_EXTRA_GET_GROUP_IDX1(group) \ + ((group) & ~PHY_TSSI_EXTRA_GROUP_BIT) +#define PHY_TSSI_EXTRA_GET_GROUP_IDX2(group) \ + (PHY_TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 phy_tssi_get_ofdm_group(u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return PHY_TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return PHY_TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return PHY_TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return PHY_TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return PHY_TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return PHY_TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return PHY_TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return PHY_TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return PHY_TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return PHY_TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return PHY_TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 phy_tssi_get_6g_ofdm_group(u8 ch) +{ + switch (ch) { + case 1 ... 5: + return 0; + case 6 ... 8: + return PHY_TSSI_EXTRA_GROUP(0); + case 9 ... 13: + return 1; + case 14 ... 16: + return PHY_TSSI_EXTRA_GROUP(1); + case 17 ... 21: + return 2; + case 22 ... 24: + return PHY_TSSI_EXTRA_GROUP(2); + case 25 ... 29: + return 3; + case 33 ... 37: + return 4; + case 38 ... 40: + return PHY_TSSI_EXTRA_GROUP(4); + case 41 ... 45: + return 5; + case 46 ... 48: + return PHY_TSSI_EXTRA_GROUP(5); + case 49 ... 53: + return 6; + case 54 ... 56: + return PHY_TSSI_EXTRA_GROUP(6); + case 57 ... 61: + return 7; + case 65 ... 69: + return 8; + case 70 ... 72: + return PHY_TSSI_EXTRA_GROUP(8); + case 73 ... 77: + return 9; + case 78 ... 80: + return PHY_TSSI_EXTRA_GROUP(9); + case 81 ... 85: + return 10; + case 86 ... 88: + return PHY_TSSI_EXTRA_GROUP(10); + case 89 ... 93: + return 11; + case 97 ... 101: + return 12; + case 102 ... 104: + return PHY_TSSI_EXTRA_GROUP(12); + case 105 ... 109: + return 13; + case 110 ... 112: + return PHY_TSSI_EXTRA_GROUP(13); + case 113 ... 117: + return 14; + case 118 ... 120: + return PHY_TSSI_EXTRA_GROUP(14); + case 121 ... 125: + return 15; + case 129 ... 133: + return 16; + case 134 ... 136: + return PHY_TSSI_EXTRA_GROUP(16); + case 137 ... 141: + return 17; + case 142 ... 144: + return PHY_TSSI_EXTRA_GROUP(17); + case 145 ... 149: + return 18; + case 150 ... 152: + return PHY_TSSI_EXTRA_GROUP(18); + case 153 ... 157: + return 19; + case 161 ... 165: + return 20; + case 166 ... 168: + return PHY_TSSI_EXTRA_GROUP(20); + case 169 ... 173: + return 21; + case 174 ... 176: + return PHY_TSSI_EXTRA_GROUP(21); + case 177 ... 181: + return 22; + case 182 ... 184: + return PHY_TSSI_EXTRA_GROUP(22); + case 185 ... 189: + return 23; + case 193 ... 197: + return 24; + case 198 ... 200: + return PHY_TSSI_EXTRA_GROUP(24); + case 201 ... 205: + return 25; + case 206 ... 208: + return PHY_TSSI_EXTRA_GROUP(25); + case 209 ... 213: + return 26; + case 214 ... 216: + return PHY_TSSI_EXTRA_GROUP(26); + case 217 ... 221: + return 27; + case 225 ... 229: + return 28; + case 230 ... 232: + return PHY_TSSI_EXTRA_GROUP(28); + case 233 ... 237: + return 29; + case 238 ... 240: + return PHY_TSSI_EXTRA_GROUP(29); + case 241 ... 245: + return 30; + case 246 ... 248: + return PHY_TSSI_EXTRA_GROUP(30); + case 249 ... 253: + return 31; + } + + return 0; +} + +static u32 phy_tssi_get_trim_group(u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 49 ... 51: + return PHY_TSSI_EXTRA_GROUP(2); + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 113 ... 115: + return PHY_TSSI_EXTRA_GROUP(4); + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static u32 phy_tssi_get_6g_trim_group(u8 ch) +{ + switch (ch) { + case 1 ... 13: + return 0; + case 14 ... 16: + return PHY_TSSI_EXTRA_GROUP(0); + case 17 ... 29: + return 1; + case 33 ... 45: + return 2; + case 46 ... 48: + return PHY_TSSI_EXTRA_GROUP(2); + case 49 ... 61: + return 3; + case 65 ... 77: + return 4; + case 78 ... 80: + return PHY_TSSI_EXTRA_GROUP(4); + case 81 ... 93: + return 5; + case 97 ... 109: + return 6; + case 110 ... 112: + return PHY_TSSI_EXTRA_GROUP(6); + case 113 ... 125: + return 7; + case 129 ... 141: + return 8; + case 142 ... 144: + return PHY_TSSI_EXTRA_GROUP(8); + case 145 ... 157: + return 9; + case 161 ... 173: + return 10; + case 174 ... 176: + return PHY_TSSI_EXTRA_GROUP(10); + case 177 ... 189: + return 11; + case 193 ... 205: + return 12; + case 206 ... 208: + return PHY_TSSI_EXTRA_GROUP(12); + case 209 ... 221: + return 13; + case 225 ... 237: + return 14; + case 238 ... 240: + return PHY_TSSI_EXTRA_GROUP(14); + case 241 ... 253: + return 15; + } + + return 0; +} + +static s8 phy_tssi_get_ofdm_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = chan->band_type; + u8 ch = chan->channel; + u32 gidx_1st; + u32 gidx_2nd; + s8 de_1st; + s8 de_2nd; + u32 gidx; + s8 val; + + if (band == RTW89_BAND_6G) + goto calc_6g; + + gidx = phy_tssi_get_ofdm_group(ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (PHY_IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; + +calc_6g: + gidx = phy_tssi_get_6g_ofdm_group(ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (PHY_IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_6g_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_6g_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_6g_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; +} + +static s8 phy_tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = chan->band_type; + u8 ch = chan->channel; + u32 tgidx_1st; + u32 tgidx_2nd; + s8 tde_1st; + s8 tde_2nd; + u32 tgidx; + s8 val; + + if (band == RTW89_BAND_6G) + goto calc_6g; + + tgidx = phy_tssi_get_trim_group(ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (PHY_IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; + +calc_6g: + tgidx = phy_tssi_get_6g_trim_group(ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (PHY_IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim_6g[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim_6g[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim_6g[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; +} + +void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + struct rtw89_h2c_rf_tssi *h2c) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + s8 trim_de; + s8 ofdm_de; + s8 cck_de; + u8 gidx; + s8 val; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + for (i = RF_PATH_A; i <= RF_PATH_B; i++) { + trim_de = phy_tssi_get_ofdm_trim_de(rtwdev, phy, chan, i); + h2c->curr_tssi_trim_de[i] = trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d trim_de=0x%x\n", i, trim_de); + + gidx = phy_tssi_get_cck_group(ch); + cck_de = tssi_info->tssi_cck[i][gidx]; + val = u32_get_bits(cck_de + trim_de, 0xff); + + if (chip->chip_id == RTL8922A) { + h2c->curr_tssi_cck_de[i] = 0x0; + h2c->curr_tssi_cck_de_20m[i] = val; + h2c->curr_tssi_cck_de_40m[i] = val; + } else { + h2c->curr_tssi_cck_de[i] = val; + } + + h2c->curr_tssi_efuse_cck_de[i] = cck_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck_de=0x%x\n", i, cck_de); + + ofdm_de = phy_tssi_get_ofdm_de(rtwdev, phy, chan, i); + val = u32_get_bits(ofdm_de + trim_de, 0xff); + + if (chip->chip_id == RTL8922A) { + h2c->curr_tssi_ofdm_de[i] = 0x0; + h2c->curr_tssi_ofdm_de_20m[i] = val; + h2c->curr_tssi_ofdm_de_40m[i] = val; + h2c->curr_tssi_ofdm_de_80m[i] = val; + h2c->curr_tssi_ofdm_de_160m[i] = val; + h2c->curr_tssi_ofdm_de_320m[i] = val; + } else { + h2c->curr_tssi_ofdm_de[i] = val; + } + + h2c->curr_tssi_efuse_ofdm_de[i] = ofdm_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d ofdm_de=0x%x\n", i, ofdm_de); + } +} + +void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + struct rtw89_h2c_rf_tssi *h2c) +{ + struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + const struct rtw89_chip_info *chip = rtwdev->chip; + const s8 *thm_up[RF_PATH_B + 1] = {}; + const s8 *thm_down[RF_PATH_B + 1] = {}; + u8 subband = chan->subband_type; + s8 thm_ofst[128] = {}; + int multiplier; + u8 thermal; + u8 path; + u8 i, j; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2]; + break; + case RTW89_CH_6G_BAND_IDX0: + case RTW89_CH_6G_BAND_IDX1: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][0]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][0]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][0]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][0]; + break; + case RTW89_CH_6G_BAND_IDX2: + case RTW89_CH_6G_BAND_IDX3: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][1]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][1]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][1]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][1]; + break; + case RTW89_CH_6G_BAND_IDX4: + case RTW89_CH_6G_BAND_IDX5: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][2]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][2]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][2]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][2]; + break; + case RTW89_CH_6G_BAND_IDX6: + case RTW89_CH_6G_BAND_IDX7: + thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][3]; + thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][3]; + thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][3]; + thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][3]; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] tmeter tbl on subband: %u\n", subband); + + if (chip->chip_id == RTL8922A) + multiplier = 1; + else + multiplier = -1; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + thermal = tssi_info->thermal[path]; + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "path: %u, pg thermal: 0x%x\n", path, thermal); + + if (thermal == 0xff) { + h2c->pg_thermal[path] = 0x38; + memset(h2c->ftable[path], 0, sizeof(h2c->ftable[path])); + continue; + } + + h2c->pg_thermal[path] = thermal; + + i = 0; + for (j = 0; j < 64; j++) { + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up[path][i++] : + thm_up[path][DELTA_SWINGIDX_SIZE - 1]; + thm_ofst[j] *= multiplier; + } + + i = 1; + for (j = 127; j >= 64; j--) { + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down[path][i++] : + -thm_down[path][DELTA_SWINGIDX_SIZE - 1]; + thm_ofst[j] *= multiplier; + } + + for (i = 0; i < 128; i += 4) { + h2c->ftable[path][i + 0] = thm_ofst[i + 3]; + h2c->ftable[path][i + 1] = thm_ofst[i + 2]; + h2c->ftable[path][i + 2] = thm_ofst[i + 1]; + h2c->ftable[path][i + 3] = thm_ofst[i + 0]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "thm ofst [%x]: %02x %02x %02x %02x\n", + i, thm_ofst[i], thm_ofst[i + 1], + thm_ofst[i + 2], thm_ofst[i + 3]); + } + } +} + +static u8 rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo) +{ + const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info; + u32 reg_mask; + + if (sc_xo) + reg_mask = xtal->sc_xo_mask; + else + reg_mask = xtal->sc_xi_mask; + + return (u8)rtw89_read32_mask(rtwdev, xtal->xcap_reg, reg_mask); +} + +static void rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo, + u8 val) +{ + const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info; + u32 reg_mask; + + if (sc_xo) + reg_mask = xtal->sc_xo_mask; + else + reg_mask = xtal->sc_xi_mask; + + rtw89_write32_mask(rtwdev, xtal->xcap_reg, reg_mask, val); +} + +static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev, + u8 crystal_cap, bool force) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 sc_xi_val = 0, sc_xo_val = 0; + + if (!force && cfo->crystal_cap == crystal_cap) + return; + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) { + rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); + rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); + sc_xo_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, true); + sc_xi_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, false); + } else { + rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XO, + crystal_cap, XTAL_SC_XO_MASK); + rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XI, + crystal_cap, XTAL_SC_XI_MASK); + rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XO, &sc_xo_val); + rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XI, &sc_xi_val); + } + cfo->crystal_cap = sc_xi_val; + cfo->x_cap_ofst = (s8)((int)cfo->crystal_cap - cfo->def_x_cap); + + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xi=0x%x\n", sc_xi_val); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xo=0x%x\n", sc_xo_val); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Get xcap_ofst=%d\n", + cfo->x_cap_ofst); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set xcap OK\n"); +} + +static void rtw89_phy_cfo_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + u8 cap; + + cfo->def_x_cap = cfo->crystal_cap_default & B_AX_XTAL_SC_MASK; + cfo->is_adjust = false; + if (cfo->crystal_cap == cfo->def_x_cap) + return; + cap = cfo->crystal_cap; + cap += (cap > cfo->def_x_cap ? -1 : 1); + rtw89_phy_cfo_set_crystal_cap(rtwdev, cap, false); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "(0x%x) approach to dflt_val=(0x%x)\n", cfo->crystal_cap, + cfo->def_x_cap); +} + +static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo) +{ + const struct rtw89_reg_def *dcfo_comp = rtwdev->chip->dcfo_comp; + bool is_linked = rtwdev->total_sta_assoc > 0; + s32 cfo_avg_312; + s32 dcfo_comp_val; + int sign; + + if (!dcfo_comp) + return; + + if (!is_linked) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: is_linked=%d\n", + is_linked); + return; + } + rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: curr_cfo=%d\n", curr_cfo); + if (curr_cfo == 0) + return; + dcfo_comp_val = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO); + sign = curr_cfo > 0 ? 1 : -1; + cfo_avg_312 = curr_cfo / 625 + sign * dcfo_comp_val; + rtw89_debug(rtwdev, RTW89_DBG_CFO, "avg_cfo_312=%d step\n", cfo_avg_312); + if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) + cfo_avg_312 = -cfo_avg_312; + rtw89_phy_set_phy_regs(rtwdev, dcfo_comp->addr, dcfo_comp->mask, + cfo_avg_312); +} + +static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_cfo_regs *cfo = phy->cfo; + + rtw89_phy_set_phy_regs(rtwdev, cfo->comp_seg0, cfo->valid_0_mask, 1); + rtw89_phy_set_phy_regs(rtwdev, cfo->comp, cfo->weighting_mask, 8); + + if (chip->chip_gen == RTW89_CHIP_AX) { + if (chip->cfo_hw_comp) { + rtw89_write32_mask(rtwdev, R_AX_PWR_UL_CTRL2, + B_AX_PWR_UL_CFO_MASK, 0x6); + } else { + rtw89_phy_set_phy_regs(rtwdev, R_DCFO, B_DCFO, 1); + rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, + B_AX_PWR_UL_CFO_MASK); + } + } +} + +static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + cfo->crystal_cap_default = efuse->xtal_cap & B_AX_XTAL_SC_MASK; + cfo->crystal_cap = cfo->crystal_cap_default; + cfo->def_x_cap = cfo->crystal_cap; + cfo->x_cap_ub = min_t(int, cfo->def_x_cap + CFO_BOUND, 0x7f); + cfo->x_cap_lb = max_t(int, cfo->def_x_cap - CFO_BOUND, 0x1); + cfo->is_adjust = false; + cfo->divergence_lock_en = false; + cfo->x_cap_ofst = 0; + cfo->lock_cnt = 0; + cfo->rtw89_multi_cfo_mode = RTW89_TP_BASED_AVG_MODE; + cfo->apply_compensation = false; + cfo->residual_cfo_acc = 0; + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Default xcap=%0x\n", + cfo->crystal_cap_default); + rtw89_phy_cfo_set_crystal_cap(rtwdev, cfo->crystal_cap_default, true); + rtw89_dcfo_comp_init(rtwdev); + cfo->cfo_timer_ms = 2000; + cfo->cfo_trig_by_timer_en = false; + cfo->phy_cfo_trk_cnt = 0; + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; + cfo->cfo_ul_ofdma_acc_mode = RTW89_CFO_UL_OFDMA_ACC_ENABLE; +} + +static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, + s32 curr_cfo) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + int crystal_cap = cfo->crystal_cap; + s32 cfo_abs = abs(curr_cfo); + int sign; + + if (curr_cfo == 0) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "curr_cfo=0\n"); + return; + } + if (!cfo->is_adjust) { + if (cfo_abs > CFO_TRK_ENABLE_TH) + cfo->is_adjust = true; + } else { + if (cfo_abs <= CFO_TRK_STOP_TH) + cfo->is_adjust = false; + } + if (!cfo->is_adjust) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Stop CFO tracking\n"); + return; + } + sign = curr_cfo > 0 ? 1 : -1; + if (cfo_abs > CFO_TRK_STOP_TH_4) + crystal_cap += 3 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_3) + crystal_cap += 3 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_2) + crystal_cap += 1 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_1) + crystal_cap += 1 * sign; + else + return; + + crystal_cap = clamp(crystal_cap, 0, 127); + rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "X_cap{Curr,Default}={0x%x,0x%x}\n", + cfo->crystal_cap, cfo->def_x_cap); +} + +static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + s32 cfo_khz_all = 0; + s32 cfo_cnt_all = 0; + s32 cfo_all_avg = 0; + u8 i; + + if (rtwdev->total_sta_assoc != 1) + return 0; + rtw89_debug(rtwdev, RTW89_DBG_CFO, "one_entry_only\n"); + for (i = 0; i < CFO_TRACK_MAX_USER; i++) { + if (cfo->cfo_cnt[i] == 0) + continue; + cfo_khz_all += cfo->cfo_tail[i]; + cfo_cnt_all += cfo->cfo_cnt[i]; + cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all); + cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; + cfo->dcfo_avg = phy_div(cfo_khz_all << chip->dcfo_comp_sft, + cfo_cnt_all); + } + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "CFO track for macid = %d\n", i); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "Total cfo=%dK, pkt_cnt=%d, avg_cfo=%dK\n", + cfo_khz_all, cfo_cnt_all, cfo_all_avg); + return cfo_all_avg; +} + +static s32 rtw89_phy_multi_sta_cfo_calc(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + struct rtw89_traffic_stats *stats = &rtwdev->stats; + s32 target_cfo = 0; + s32 cfo_khz_all = 0; + s32 cfo_khz_all_tp_wgt = 0; + s32 cfo_avg = 0; + s32 max_cfo_lb = BIT(31); + s32 min_cfo_ub = GENMASK(30, 0); + u16 cfo_cnt_all = 0; + u8 active_entry_cnt = 0; + u8 sta_cnt = 0; + u32 tp_all = 0; + u8 i; + u8 cfo_tol = 0; + + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Multi entry cfo_trk\n"); + if (cfo->rtw89_multi_cfo_mode == RTW89_PKT_BASED_AVG_MODE) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt based avg mode\n"); + for (i = 0; i < CFO_TRACK_MAX_USER; i++) { + if (cfo->cfo_cnt[i] == 0) + continue; + cfo_khz_all += cfo->cfo_tail[i]; + cfo_cnt_all += cfo->cfo_cnt[i]; + cfo_avg = phy_div(cfo_khz_all, (s32)cfo_cnt_all); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "Msta cfo=%d, pkt_cnt=%d, avg_cfo=%d\n", + cfo_khz_all, cfo_cnt_all, cfo_avg); + target_cfo = cfo_avg; + } + } else if (cfo->rtw89_multi_cfo_mode == RTW89_ENTRY_BASED_AVG_MODE) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Entry based avg mode\n"); + for (i = 0; i < CFO_TRACK_MAX_USER; i++) { + if (cfo->cfo_cnt[i] == 0) + continue; + cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], + (s32)cfo->cfo_cnt[i]); + cfo_khz_all += cfo->cfo_avg[i]; + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "Macid=%d, cfo_avg=%d\n", i, + cfo->cfo_avg[i]); + } + sta_cnt = rtwdev->total_sta_assoc; + cfo_avg = phy_div(cfo_khz_all, (s32)sta_cnt); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "Msta cfo_acc=%d, ent_cnt=%d, avg_cfo=%d\n", + cfo_khz_all, sta_cnt, cfo_avg); + target_cfo = cfo_avg; + } else if (cfo->rtw89_multi_cfo_mode == RTW89_TP_BASED_AVG_MODE) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "TP based avg mode\n"); + cfo_tol = cfo->sta_cfo_tolerance; + for (i = 0; i < CFO_TRACK_MAX_USER; i++) { + sta_cnt++; + if (cfo->cfo_cnt[i] != 0) { + cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], + (s32)cfo->cfo_cnt[i]); + active_entry_cnt++; + } else { + cfo->cfo_avg[i] = cfo->pre_cfo_avg[i]; + } + max_cfo_lb = max(cfo->cfo_avg[i] - cfo_tol, max_cfo_lb); + min_cfo_ub = min(cfo->cfo_avg[i] + cfo_tol, min_cfo_ub); + cfo_khz_all += cfo->cfo_avg[i]; + /* need tp for each entry */ + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "[%d] cfo_avg=%d, tp=tbd\n", + i, cfo->cfo_avg[i]); + if (sta_cnt >= rtwdev->total_sta_assoc) + break; + } + tp_all = stats->rx_throughput; /* need tp for each entry */ + cfo_avg = phy_div(cfo_khz_all_tp_wgt, (s32)tp_all); + + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Assoc sta cnt=%d\n", + sta_cnt); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Active sta cnt=%d\n", + active_entry_cnt); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "Msta cfo with tp_wgt=%d, avg_cfo=%d\n", + cfo_khz_all_tp_wgt, cfo_avg); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "cfo_lb=%d,cfo_ub=%d\n", + max_cfo_lb, min_cfo_ub); + if (max_cfo_lb <= min_cfo_ub) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "cfo win_size=%d\n", + min_cfo_ub - max_cfo_lb); + target_cfo = clamp(cfo_avg, max_cfo_lb, min_cfo_ub); + } else { + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "No intersection of cfo tolerance windows\n"); + target_cfo = phy_div(cfo_khz_all, (s32)sta_cnt); + } + for (i = 0; i < CFO_TRACK_MAX_USER; i++) + cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; + } + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Target cfo=%d\n", target_cfo); + return target_cfo; +} + +static void rtw89_phy_cfo_statistics_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + + memset(&cfo->cfo_tail, 0, sizeof(cfo->cfo_tail)); + memset(&cfo->cfo_cnt, 0, sizeof(cfo->cfo_cnt)); + cfo->packet_count = 0; + cfo->packet_count_pre = 0; + cfo->cfo_avg_pre = 0; +} + +static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + s32 new_cfo = 0; + bool x_cap_update = false; + u8 pre_x_cap = cfo->crystal_cap; + u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft; + + cfo->dcfo_avg = 0; + rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n", + rtwdev->total_sta_assoc); + if (rtwdev->total_sta_assoc == 0 || rtw89_is_mlo_1_1(rtwdev)) { + rtw89_phy_cfo_reset(rtwdev); + return; + } + if (cfo->packet_count == 0) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt = 0\n"); + return; + } + if (cfo->packet_count == cfo->packet_count_pre) { + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt doesn't change\n"); + return; + } + if (rtwdev->total_sta_assoc == 1) + new_cfo = rtw89_phy_average_cfo_calc(rtwdev); + else + new_cfo = rtw89_phy_multi_sta_cfo_calc(rtwdev); + if (cfo->divergence_lock_en) { + cfo->lock_cnt++; + if (cfo->lock_cnt > CFO_PERIOD_CNT) { + cfo->divergence_lock_en = false; + cfo->lock_cnt = 0; + } else { + rtw89_phy_cfo_reset(rtwdev); + } + return; + } + if (cfo->crystal_cap >= cfo->x_cap_ub || + cfo->crystal_cap <= cfo->x_cap_lb) { + cfo->divergence_lock_en = true; + rtw89_phy_cfo_reset(rtwdev); + return; + } + + rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo); + cfo->cfo_avg_pre = new_cfo; + cfo->dcfo_avg_pre = cfo->dcfo_avg; + x_cap_update = cfo->crystal_cap != pre_x_cap; + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update); + rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n", + cfo->def_x_cap, pre_x_cap, cfo->crystal_cap, + cfo->x_cap_ofst); + if (x_cap_update) { + if (cfo->dcfo_avg > 0) + cfo->dcfo_avg -= CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft; + else + cfo->dcfo_avg += CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft; + } + rtw89_dcfo_comp(rtwdev, cfo->dcfo_avg); + rtw89_phy_cfo_statistics_reset(rtwdev); +} + +void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + cfo_track_work.work); + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + + lockdep_assert_wiphy(wiphy); + + if (!cfo->cfo_trig_by_timer_en) + return; + rtw89_leave_ps_mode(rtwdev); + rtw89_phy_cfo_dm(rtwdev); + wiphy_delayed_work_queue(wiphy, &rtwdev->cfo_track_work, + msecs_to_jiffies(cfo->cfo_timer_ms)); +} + +static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->cfo_track_work, + msecs_to_jiffies(cfo->cfo_timer_ms)); +} + +void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + struct rtw89_traffic_stats *stats = &rtwdev->stats; + bool is_ul_ofdma = false, ofdma_acc_en = false; + + if (stats->rx_tf_periodic > CFO_TF_CNT_TH) + is_ul_ofdma = true; + if (cfo->cfo_ul_ofdma_acc_mode == RTW89_CFO_UL_OFDMA_ACC_ENABLE && + is_ul_ofdma) + ofdma_acc_en = true; + + switch (cfo->phy_cfo_status) { + case RTW89_PHY_DCFO_STATE_NORMAL: + if (stats->tx_throughput >= CFO_TP_UPPER) { + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_ENHANCE; + cfo->cfo_trig_by_timer_en = true; + cfo->cfo_timer_ms = CFO_COMP_PERIOD; + rtw89_phy_cfo_start_work(rtwdev); + } + break; + case RTW89_PHY_DCFO_STATE_ENHANCE: + if (stats->tx_throughput <= CFO_TP_LOWER) + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; + else if (ofdma_acc_en && + cfo->phy_cfo_trk_cnt >= CFO_PERIOD_CNT) + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_HOLD; + else + cfo->phy_cfo_trk_cnt++; + + if (cfo->phy_cfo_status == RTW89_PHY_DCFO_STATE_NORMAL) { + cfo->phy_cfo_trk_cnt = 0; + cfo->cfo_trig_by_timer_en = false; + } + break; + case RTW89_PHY_DCFO_STATE_HOLD: + if (stats->tx_throughput <= CFO_TP_LOWER) { + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; + cfo->phy_cfo_trk_cnt = 0; + cfo->cfo_trig_by_timer_en = false; + } else { + cfo->phy_cfo_trk_cnt++; + } + break; + default: + cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; + cfo->phy_cfo_trk_cnt = 0; + break; + } + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "[CFO]WatchDog tp=%d,state=%d,timer_en=%d,trk_cnt=%d,thermal=%ld\n", + stats->tx_throughput, cfo->phy_cfo_status, + cfo->cfo_trig_by_timer_en, cfo->phy_cfo_trk_cnt, + ewma_thermal_read(&rtwdev->phystat.avg_thermal[0])); + if (cfo->cfo_trig_by_timer_en) + return; + rtw89_phy_cfo_dm(rtwdev); +} + +void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; + u8 macid = phy_ppdu->mac_id; + + if (macid >= CFO_TRACK_MAX_USER) { + rtw89_warn(rtwdev, "mac_id %d is out of range\n", macid); + return; + } + + cfo->cfo_tail[macid] += cfo_val; + cfo->cfo_cnt[macid]++; + cfo->packet_count++; +} + +void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; + + if (!chip->ul_tb_waveform_ctrl) + return; + + rtwvif_link->def_tri_idx = + rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG); + + if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV) + rtwvif_link->dyn_tb_bedge_en = false; + else if (chan->band_type >= RTW89_BAND_5G && + chan->band_width >= RTW89_CHANNEL_WIDTH_40) + rtwvif_link->dyn_tb_bedge_en = true; + else + rtwvif_link->dyn_tb_bedge_en = false; + + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n", + ul_tb_info->def_if_bandedge, rtwvif_link->def_tri_idx); + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n", + rtwvif_link->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en); +} + +struct rtw89_phy_ul_tb_check_data { + bool valid; + bool high_tf_client; + bool low_tf_client; + bool dyn_tb_bedge_en; + u8 def_tri_idx; +}; + +struct rtw89_phy_power_diff { + u32 q_00; + u32 q_11; + u32 q_matrix_en; + u32 ultb_1t_norm_160; + u32 ultb_2t_norm_160; + u32 com1_norm_1sts; + u32 com2_resp_1sts_path; +}; + +static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + static const struct rtw89_phy_power_diff table[2] = { + {0x0, 0x0, 0x0, 0x0, 0xf4, 0x3, 0x3}, + {0xb50, 0xb50, 0x1, 0xc, 0x0, 0x1, 0x1}, + }; + const struct rtw89_phy_power_diff *param; + u32 reg; + + if (!rtwdev->chip->ul_tb_pwr_diff) + return; + + if (rtwvif_link->pwr_diff_en == rtwvif_link->pre_pwr_diff_en) { + rtwvif_link->pwr_diff_en = false; + return; + } + + rtwvif_link->pre_pwr_diff_en = rtwvif_link->pwr_diff_en; + param = &table[rtwvif_link->pwr_diff_en]; + + rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_00, B_Q_MATRIX_00_REAL, + param->q_00); + rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_11, B_Q_MATRIX_11_REAL, + param->q_11); + rtw89_phy_write32_mask(rtwdev, R_CUSTOMIZE_Q_MATRIX, + B_CUSTOMIZE_Q_MATRIX_EN, param->q_matrix_en); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_NORM_BW160, + param->ultb_1t_norm_160); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_NORM_BW160, + param->ultb_2t_norm_160); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM1_NORM_1STS, + param->com1_norm_1sts); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM2_RESP_1STS_PATH, + param->com2_resp_1sts_path); +} + +static +void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_phy_ul_tb_check_data *ul_tb_data) +{ + struct rtw89_traffic_stats *stats = &rtwdev->stats; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) + return; + + if (!vif->cfg.assoc) + return; + + if (rtwdev->chip->ul_tb_waveform_ctrl) { + if (stats->rx_tf_periodic > UL_TB_TF_CNT_L2H_TH) + ul_tb_data->high_tf_client = true; + else if (stats->rx_tf_periodic < UL_TB_TF_CNT_H2L_TH) + ul_tb_data->low_tf_client = true; + + ul_tb_data->valid = true; + ul_tb_data->def_tri_idx = rtwvif_link->def_tri_idx; + ul_tb_data->dyn_tb_bedge_en = rtwvif_link->dyn_tb_bedge_en; + } + + rtw89_phy_ofdma_power_diff(rtwdev, rtwvif_link); +} + +static void rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_phy_ul_tb_check_data *ul_tb_data) +{ + struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; + + if (!rtwdev->chip->ul_tb_waveform_ctrl) + return; + + if (ul_tb_data->dyn_tb_bedge_en) { + if (ul_tb_data->high_tf_client) { + rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0); + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] Turn off if_bandedge\n"); + } else if (ul_tb_data->low_tf_client) { + rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, + ul_tb_info->def_if_bandedge); + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] Set to default if_bandedge = %d\n", + ul_tb_info->def_if_bandedge); + } + } + + if (ul_tb_info->dyn_tb_tri_en) { + if (ul_tb_data->high_tf_client) { + rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, + B_TXSHAPE_TRIANGULAR_CFG, 0); + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] Turn off Tx triangle\n"); + } else if (ul_tb_data->low_tf_client) { + rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, + B_TXSHAPE_TRIANGULAR_CFG, + ul_tb_data->def_tri_idx); + rtw89_debug(rtwdev, RTW89_DBG_UL_TB, + "[ULTB] Set to default tx_shap_idx = %d\n", + ul_tb_data->def_tri_idx); + } + } +} + +void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_phy_ul_tb_check_data ul_tb_data = {}; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff) + return; + + if (rtwdev->total_sta_assoc != 1) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data); + + if (!ul_tb_data.valid) + return; + + rtw89_phy_ul_tb_waveform_ctrl(rtwdev, &ul_tb_data); +} + +static void rtw89_phy_ul_tb_info_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; + + if (!chip->ul_tb_waveform_ctrl) + return; + + ul_tb_info->dyn_tb_tri_en = true; + ul_tb_info->def_if_bandedge = + rtw89_phy_read32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN); +} + +static +void rtw89_phy_antdiv_sts_instance_reset(struct rtw89_antdiv_stats *antdiv_sts) +{ + ewma_rssi_init(&antdiv_sts->cck_rssi_avg); + ewma_rssi_init(&antdiv_sts->ofdm_rssi_avg); + ewma_rssi_init(&antdiv_sts->non_legacy_rssi_avg); + antdiv_sts->pkt_cnt_cck = 0; + antdiv_sts->pkt_cnt_ofdm = 0; + antdiv_sts->pkt_cnt_non_legacy = 0; + antdiv_sts->evm = 0; +} + +static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct rtw89_antdiv_stats *stats) +{ + if (rtw89_get_data_rate_mode(rtwdev, phy_ppdu->rate) == DATA_RATE_MODE_NON_HT) { + if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) { + ewma_rssi_add(&stats->cck_rssi_avg, phy_ppdu->rssi_avg); + stats->pkt_cnt_cck++; + } else { + ewma_rssi_add(&stats->ofdm_rssi_avg, phy_ppdu->rssi_avg); + stats->pkt_cnt_ofdm++; + stats->evm += phy_ppdu->ofdm.evm_min; + } + } else { + ewma_rssi_add(&stats->non_legacy_rssi_avg, phy_ppdu->rssi_avg); + stats->pkt_cnt_non_legacy++; + stats->evm += phy_ppdu->ofdm.evm_min; + } +} + +static u8 rtw89_phy_antdiv_sts_instance_get_rssi(struct rtw89_antdiv_stats *stats) +{ + if (stats->pkt_cnt_non_legacy >= stats->pkt_cnt_cck && + stats->pkt_cnt_non_legacy >= stats->pkt_cnt_ofdm) + return ewma_rssi_read(&stats->non_legacy_rssi_avg); + else if (stats->pkt_cnt_ofdm >= stats->pkt_cnt_cck && + stats->pkt_cnt_ofdm >= stats->pkt_cnt_non_legacy) + return ewma_rssi_read(&stats->ofdm_rssi_avg); + else + return ewma_rssi_read(&stats->cck_rssi_avg); +} + +static u8 rtw89_phy_antdiv_sts_instance_get_evm(struct rtw89_antdiv_stats *stats) +{ + return phy_div(stats->evm, stats->pkt_cnt_non_legacy + stats->pkt_cnt_ofdm); +} + +void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + struct rtw89_hal *hal = &rtwdev->hal; + + if (!hal->ant_diversity || hal->ant_diversity_fixed) + return; + + rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->target_stats); + + if (!antdiv->get_stats) + return; + + if (hal->antenna_rx == RF_A) + rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->main_stats); + else if (hal->antenna_rx == RF_B) + rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->aux_stats); +} + +static void rtw89_phy_antdiv_reg_init(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_ANT_TRAIN_EN, + 0x0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_TX_ANT_SEL, + 0x0, RTW89_PHY_0); + + rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_TRSW_TX_EXTEND, + 0x0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_HW_ANTSW_DIS_BY_GNT_BT, + 0x0, RTW89_PHY_0); + + rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_BT_FORCE_ANTIDX_EN, + 0x0, RTW89_PHY_0); + + rtw89_phy_write32_idx(rtwdev, R_RFSW_CTRL_ANT0_BASE, B_RFSW_CTRL_ANT_MAPPING, + 0x0100, RTW89_PHY_0); + + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_BTG_TRX, + 0x1, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_HW_CTRL, + 0x0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_2G, + 0x0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_5G, + 0x0, RTW89_PHY_0); +} + +static void rtw89_phy_antdiv_sts_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + + rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats); + rtw89_phy_antdiv_sts_instance_reset(&antdiv->main_stats); + rtw89_phy_antdiv_sts_instance_reset(&antdiv->aux_stats); +} + +static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + struct rtw89_hal *hal = &rtwdev->hal; + + if (!hal->ant_diversity) + return; + + antdiv->get_stats = false; + antdiv->rssi_pre = 0; + rtw89_phy_antdiv_sts_reset(rtwdev); + rtw89_phy_antdiv_reg_init(rtwdev); +} + +static void rtw89_phy_thermal_protect_vcore(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_stat *phystat = &rtwdev->phystat; + struct rtw89_hal *hal = &rtwdev->hal; + bool vcore_enabled = !!hal->thermal_prot_vmax; + u8 th_max = phystat->last_thermal_max; + u8 vlv = hal->thermal_prot_vlv; + u8 prot_th; + + if (!vcore_enabled || (hal->disabled_dm_bitmap & BIT(RTW89_DM_VCORE))) + return; + + prot_th = hal->thermal_prot_th - RTW89_THERMAL_PROT_VLV_TH_OFFSET; + if (th_max > prot_th && vlv < RTW89_THERMAL_PROT_VLV_MAX) + vlv++; + else if (th_max < prot_th - 2 && vlv > 0) + vlv--; + else + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection vlv=%d\n", vlv); + + hal->thermal_prot_vlv = vlv; + rtw89_mac_set_vcore_cfg(rtwdev, vlv); +} + +static void rtw89_phy_thermal_protect(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_stat *phystat = &rtwdev->phystat; + struct rtw89_hal *hal = &rtwdev->hal; + u8 th_max = phystat->last_thermal_max; + u8 lv = hal->thermal_prot_lv; + + if (!hal->thermal_prot_th || + (hal->disabled_dm_bitmap & BIT(RTW89_DM_THERMAL_PROTECT))) + return; + + if (th_max > hal->thermal_prot_th && lv < RTW89_THERMAL_PROT_LV_MAX) + lv++; + else if (th_max < hal->thermal_prot_th - 2 && lv > 0) + lv--; + else + return; + + hal->thermal_prot_lv = lv; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection lv=%d\n", lv); + + rtw89_fw_h2c_tx_duty(rtwdev, hal->thermal_prot_lv); +} + +static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_stat *phystat = &rtwdev->phystat; + u8 th, th_max = 0; + int i; + + for (i = 0; i < rtwdev->chip->rf_path_num; i++) { + th = rtw89_chip_get_thermal(rtwdev, i); + if (th) + ewma_thermal_add(&phystat->avg_thermal[i], th); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "path(%d) thermal cur=%u avg=%ld", i, th, + ewma_thermal_read(&phystat->avg_thermal[i])); + + th_max = max(th_max, th); + } + + phystat->last_thermal_max = th_max; +} + +struct rtw89_phy_iter_rssi_data { + struct rtw89_dev *rtwdev; + bool rssi_changed; +}; + +static +void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link, + struct rtw89_phy_iter_rssi_data *rssi_data) +{ + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct rtw89_dev *rtwdev = rssi_data->rtwdev; + struct rtw89_phy_ch_info *ch_info; + struct rtw89_bb_ctx *bb; + unsigned long rssi_curr; + + rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi); + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + ch_info = &bb->ch_info; + + if (rssi_curr < ch_info->rssi_min) { + ch_info->rssi_min = rssi_curr; + ch_info->rssi_min_macid = rtwsta_link->mac_id; + } + + if (rtwsta_link->prev_rssi == 0) { + rtwsta_link->prev_rssi = rssi_curr; + } else if (abs((int)rtwsta_link->prev_rssi - (int)rssi_curr) > + (3 << RSSI_FACTOR)) { + rtwsta_link->prev_rssi = rssi_curr; + rssi_data->rssi_changed = true; + } +} + +static void rtw89_phy_stat_rssi_update_iter(void *data, + struct ieee80211_sta *sta) +{ + struct rtw89_phy_iter_rssi_data *rssi_data = + (struct rtw89_phy_iter_rssi_data *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + __rtw89_phy_stat_rssi_update_iter(rtwsta_link, rssi_data); +} + +static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_iter_rssi_data rssi_data = {}; + struct rtw89_bb_ctx *bb; + + rssi_data.rtwdev = rtwdev; + rtw89_for_each_active_bb(rtwdev, bb) + bb->ch_info.rssi_min = U8_MAX; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_phy_stat_rssi_update_iter, + &rssi_data); + if (rssi_data.rssi_changed) + rtw89_btc_ntfy_wl_sta(rtwdev); +} + +static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_stat *phystat = &rtwdev->phystat; + struct rtw89_bb_ctx *bb; + int i; + + for (i = 0; i < rtwdev->chip->rf_path_num; i++) + ewma_thermal_init(&phystat->avg_thermal[i]); + + rtw89_phy_stat_thermal_update(rtwdev); + + rtw89_for_each_capab_bb(rtwdev, bb) { + memset(&bb->cur_pkt_stat, 0, sizeof(bb->cur_pkt_stat)); + memset(&bb->last_pkt_stat, 0, sizeof(bb->last_pkt_stat)); + + ewma_rssi_init(&bb->bcn_rssi); + bb->path_diff.raw = 0; + ewma_path_diff_init(&bb->path_diff.avg); + bb->path_diff.bf_smo_en = false; + } + + rtwdev->hal.thermal_prot_lv = 0; +} + +static void rtw89_phy_pmac_diag(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ +#define RTW89_DIAG_BB_FA_RATIO_TH 80 +#define RTW89_DIAG_BB_NO_RX_TH 5 +#define RTW89_DIAG_BB_HANG_TH 30 + struct rtw89_pmac_stat_info *pmac_stat = &bb->pmac_stat; + bool is_linked = rtwdev->total_sta_assoc > 0; + struct rtw89_diag_bb *diag = &bb->diag; + u8 fa_ratio = 0; + + if (!(pmac_stat->cck_mac_txen || pmac_stat->ofdm_mac_txen)) + diag->consecutive_no_tx_cnt++; + else + diag->consecutive_no_tx_cnt = 0; + + if (!pmac_stat->cnt_cca_all) + diag->consecutive_no_rx_cnt++; + else + diag->consecutive_no_rx_cnt = 0; + + if (pmac_stat->cnt_cca_all) + fa_ratio = pmac_stat->cnt_fail_all * PERCENT / pmac_stat->cnt_cca_all; + + diag->diag_bb_bitmap &= ~(BIT(RTW89_DIAG_BB_NO_RX) | + BIT(RTW89_DIAG_BB_HANG) | + BIT(RTW89_DIAG_BB_FA)); + + if (diag->consecutive_no_rx_cnt >= RTW89_DIAG_BB_NO_RX_TH && is_linked) { + diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_NO_RX); + diag->diag_bb_cnt[RTW89_DIAG_BB_NO_RX]++; + } + + if (fa_ratio >= RTW89_DIAG_BB_FA_RATIO_TH && is_linked) { + diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_FA); + diag->diag_bb_cnt[RTW89_DIAG_BB_FA]++; + } + + if (diag->consecutive_no_tx_cnt > RTW89_DIAG_BB_HANG_TH && + diag->consecutive_no_rx_cnt > RTW89_DIAG_BB_HANG_TH) { + diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_HANG); + diag->diag_bb_cnt[RTW89_DIAG_BB_HANG]++; + } +} + +static void rtw89_phy_pmac_stat_reset(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool cck) +{ + const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs; + + if (cck) { + rtw89_phy_write32_clr(rtwdev, regs->r1b_rx_rpt_rst.addr, + regs->r1b_rx_rpt_rst.mask); + rtw89_phy_write32_set(rtwdev, regs->r1b_rx_rpt_rst.addr, + regs->r1b_rx_rpt_rst.mask); + } + + rtw89_phy_write32_idx_set(rtwdev, regs->enable_all_cnt.addr, + regs->enable_all_cnt.mask, bb->phy_idx); + rtw89_phy_write32_idx_set(rtwdev, regs->rst_all_cnt.addr, + regs->rst_all_cnt.mask, bb->phy_idx); + rtw89_phy_write32_idx_clr(rtwdev, regs->rst_all_cnt.addr, + regs->rst_all_cnt.mask, bb->phy_idx); +} + +static void rtw89_phy_pmac_stat_cck(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs; + struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val; + + pmac->cck_phy_txon = + rtw89_phy_read32_mask(rtwdev, regs->cck_txon.addr, regs->cck_txon.mask); + pmac->cck_mac_txen = + rtw89_phy_read32_mask(rtwdev, regs->cck_txen.addr, regs->cck_txen.mask); + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + rtw89_phy_write32_mask(rtwdev, regs->r1b_rr_sel.addr, + regs->r1b_rr_sel.mask, 0x2); + + if (bb->phy_idx == RTW89_PHY_1) + pmac->cnt_cck_cca = + rtw89_phy_read32_mask(rtwdev, regs->cck_cca.addr + 8, + regs->cck_cca.mask); + else + pmac->cnt_cck_cca = + rtw89_phy_read32_mask(rtwdev, regs->cck_cca.addr, + regs->cck_cca.mask); + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + rtw89_phy_write32_mask(rtwdev, regs->r1b_rr_sel.addr, + regs->r1b_rr_sel.mask, 0x1); + + if (bb->phy_idx == RTW89_PHY_1) + val = rtw89_phy_read32(rtwdev, regs->cck_crc32 + 8); + else + val = rtw89_phy_read32(rtwdev, regs->cck_crc32); + pmac->cnt_cck_crc32_ok = field_get(regs->cck_crc32_ok_mask, val); + pmac->cnt_cck_crc32_error = field_get(regs->cck_crc32_fail_mask, val); + + pmac->cnt_sfd_gg = + rtw89_phy_read32_idx(rtwdev, regs->cck_sfd_gg.addr, + regs->cck_sfd_gg.mask, bb->phy_idx); + pmac->cnt_sig_gg = + rtw89_phy_read32_idx(rtwdev, regs->cck_sig_gg.addr, + regs->cck_sig_gg.mask, bb->phy_idx); + pmac->cnt_cck_spoofing = + rtw89_phy_read32_idx(rtwdev, regs->cck_spoofing.addr, + regs->cck_spoofing.mask, bb->phy_idx); + + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) + pmac->cnt_cck_fail = + pmac->cnt_cck_cca - pmac->cnt_cck_crc32_ok - + pmac->cnt_cck_crc32_error - pmac->cnt_cck_spoofing; + else + pmac->cnt_cck_fail = + rtw89_phy_read32_idx(rtwdev, regs->cck_brk.addr, + regs->cck_brk.mask, bb->phy_idx); +} + +static void rtw89_phy_pmac_stat_ofdm(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs; + struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 val; + + val = rtw89_phy_read32_idx(rtwdev, regs->ofdm_txon, MASKDWORD, bb->phy_idx); + pmac->ofdm_phy_txon = field_get(regs->ofdm_txon_mask, val); + pmac->ofdm_mac_txen = field_get(regs->ofdm_txen_mask, val); + + val = rtw89_phy_read32_idx(rtwdev, regs->l_crc, MASKDWORD, bb->phy_idx); + pmac->cnt_ofdm_crc32_ok = field_get(regs->l_crc_ok_mask, val); + pmac->cnt_ofdm_crc32_error = field_get(regs->l_crc_err_mask, val); + + val = rtw89_phy_read32_idx(rtwdev, regs->ht_crc, MASKDWORD, bb->phy_idx); + pmac->cnt_ht_crc32_ok = field_get(regs->ht_crc_ok_mask, val); + pmac->cnt_ht_crc32_error = field_get(regs->ht_crc_err_mask, val); + + val = rtw89_phy_read32_idx(rtwdev, regs->vht_crc, MASKDWORD, bb->phy_idx); + pmac->cnt_vht_crc32_ok = field_get(regs->vht_crc_ok_mask, val); + pmac->cnt_vht_crc32_error = field_get(regs->vht_crc_err_mask, val); + + val = rtw89_phy_read32_idx(rtwdev, regs->he_crc, MASKDWORD, bb->phy_idx); + pmac->cnt_he_crc32_ok = field_get(regs->he_crc_ok_mask, val); + pmac->cnt_he_crc32_error = field_get(regs->he_crc_err_mask, val); + + if (chip->chip_gen == RTW89_CHIP_BE) { + val = rtw89_phy_read32_idx(rtwdev, regs->eht_crc, + MASKDWORD, bb->phy_idx); + pmac->cnt_eht_crc32_ok = field_get(regs->eht_crc_ok_mask, val); + pmac->cnt_eht_crc32_error = field_get(regs->eht_crc_err_mask, val); + } + + val = rtw89_phy_read32_idx(rtwdev, regs->ampdu_crc, MASKDWORD, bb->phy_idx); + pmac->cnt_ampdu_crc_ok = field_get(regs->ampdu_crc_ok_mask, val); + pmac->cnt_ampdu_crc_error = field_get(regs->ampdu_crc_err_mask, val); + + val = rtw89_phy_read32_idx(rtwdev, regs->brk.addr, regs->brk.mask, bb->phy_idx); + if (chip->chip_id == RTL8852C && + rtw89_phy_read32_idx(rtwdev, regs->brk_option.addr, + regs->brk_option.mask, bb->phy_idx) == 1) { + u32 tmp = pmac->ofdm_phy_txon + pmac->cck_phy_txon; + + val = (val > tmp) ? (val - tmp) : 0; + } + pmac->cnt_ofdm_fail = val; + + pmac->cnt_sb_search_fail = + rtw89_phy_read32_idx(rtwdev, regs->search_fail.addr, + regs->search_fail.mask, bb->phy_idx); + pmac->cnt_lsig_brk_s_th = + rtw89_phy_read32_idx(rtwdev, regs->lsig_brk_s_th.addr, + regs->lsig_brk_s_th.mask, bb->phy_idx); + pmac->cnt_lsig_brk_l_th = + rtw89_phy_read32_idx(rtwdev, regs->lsig_brk_l_th.addr, + regs->lsig_brk_l_th.mask, bb->phy_idx); + pmac->cnt_parity_fail = + rtw89_phy_read32_idx(rtwdev, regs->rxl_err_parity.addr, + regs->rxl_err_parity.mask, bb->phy_idx); + pmac->cnt_rate_illegal = + rtw89_phy_read32_idx(rtwdev, regs->rxl_err_rate.addr, + regs->rxl_err_rate.mask, bb->phy_idx); + pmac->cnt_ofdm_cca = + rtw89_phy_read32_idx(rtwdev, regs->ofdm_cca.addr, + regs->ofdm_cca.mask, bb->phy_idx); + pmac->cnt_ofdm_spoofing = + rtw89_phy_read32_idx(rtwdev, regs->cca_spoofing.addr, + regs->cca_spoofing.mask, bb->phy_idx); + pmac->cnt_ampdu_miss = + rtw89_phy_read32_idx(rtwdev, regs->ampdu_miss.addr, + regs->ampdu_miss.mask, bb->phy_idx); +} + +static void rtw89_phy_pmac_stat_update(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + bool cck; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[bb->phy_idx]; + cck = chan->band_type == RTW89_BAND_2G; + + if (cck) + rtw89_phy_pmac_stat_cck(rtwdev, bb); + + rtw89_phy_pmac_stat_ofdm(rtwdev, bb); + + pmac->cnt_fail_all = pmac->cnt_ofdm_fail; + pmac->cnt_cca_all = pmac->cnt_ofdm_cca; + + if (cck) { + pmac->cnt_fail_all += pmac->cnt_cck_fail; + pmac->cnt_cca_all += pmac->cnt_cck_cca; + } + + pmac->cnt_crc32_error_all = pmac->cnt_he_crc32_error + + pmac->cnt_vht_crc32_error + + pmac->cnt_ht_crc32_error + + pmac->cnt_ofdm_crc32_error + + pmac->cnt_cck_crc32_error; + + pmac->cnt_crc32_ok_all = pmac->cnt_he_crc32_ok + + pmac->cnt_vht_crc32_ok + + pmac->cnt_ht_crc32_ok + + pmac->cnt_ofdm_crc32_ok + + pmac->cnt_cck_crc32_ok; + + if (chip->chip_gen == RTW89_CHIP_BE) { + pmac->cnt_crc32_error_all += pmac->cnt_eht_crc32_error; + pmac->cnt_crc32_ok_all += pmac->cnt_eht_crc32_ok; + } + + rtw89_phy_pmac_diag(rtwdev, bb); + rtw89_phy_pmac_stat_reset(rtwdev, bb, cck); +} + +static void rtw89_phy_tx_stat_update(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_physts_regs *physts = phy->physts; + struct rtw89_tx_stat_info *tx_stat = &bb->tx_stat; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg_nr; + u32 val; + u32 i; + + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF && + bb->phy_idx != RTW89_PHY_0) + val = 1; + else + val = 0; + + rtw89_phy_write32_mask(rtwdev, physts->mac_phy_intf_sel.addr, + physts->mac_phy_intf_sel.mask, val); + + reg_nr = min(physts->tx_info.reg_nr, ARRAY_SIZE(tx_stat->info)); + for (i = 0; i < reg_nr; i++) + tx_stat->info[i] = rtw89_phy_read32(rtwdev, physts->tx_info.regs[i]); + + reg_nr = min(physts->tx_common_ctrl.reg_nr, ARRAY_SIZE(tx_stat->common_ctrl)); + for (i = 0; i < reg_nr; i++) + tx_stat->common_ctrl[i] = + rtw89_phy_read32(rtwdev, physts->tx_common_ctrl.regs[i]); + + reg_nr = min(chip->rf_path_num, ARRAY_SIZE(tx_stat->txpwr)); + for (i = 0; i < reg_nr; i++) + tx_stat->txpwr[i] = rtw89_phy_read32_mask(rtwdev, physts->txpwr[i].addr, + physts->txpwr[i].mask); + + tx_stat->type = u32_get_bits(tx_stat->info[0], TX_STATUS_TYPE); + + if (chip->chip_gen == RTW89_CHIP_AX) { + tx_stat->tx_path_en = u32_get_bits(tx_stat->info[0], TX_STATUS_TX_PATH_EN); + tx_stat->path_map = u32_get_bits(tx_stat->info[0], TX_STATUS_PATH_MAP); + tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD); + tx_stat->txsc = u32_get_bits(tx_stat->info[1], TX_STATUS_TXSC); + tx_stat->bw = u32_get_bits(tx_stat->info[1], TX_STATUS_BW); + tx_stat->tmac_txpwr = u32_get_bits(tx_stat->info[1], TX_STATUS_TMAC_TXPWR); + + if (!(chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))) + tx_stat->max_mcs = u32_get_bits(tx_stat->info[3], TX_STATUS_MAX_MCS); + } else { + tx_stat->type = u32_get_bits(tx_stat->info[0], TX_STATUS_TYPE); + tx_stat->subtype = u32_get_bits(tx_stat->info[0], TX_STATUS_SUBTYPE); + + if (chip->chip_id == RTL8922A) + tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD_V1); + else + tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD_V2); + + tx_stat->txsc = u32_get_bits(tx_stat->info[0], TX_STATUS_TXSC_V1); + tx_stat->bw = u32_get_bits(tx_stat->info[1], TX_STATUS_BW_V1); + tx_stat->tmac_txpwr = u32_get_bits(tx_stat->info[1], TX_STATUS_TMAC_TXPWR_V1); + tx_stat->tx_path_en = u32_get_bits(tx_stat->info[2], TX_STATUS_TX_PATH_EN_V1); + tx_stat->path_map = u32_get_bits(tx_stat->info[2], TX_STATUS_PATH_MAP_V1); + tx_stat->max_mcs = u32_get_bits(tx_stat->info[4], TX_STATUS_MAX_MCS_V1); + } + + tx_stat->stbc = !!(tx_stat->common_ctrl[0] & TX_STATUS_STBC); +} + +static void rtw89_phy_trigger_tx_count(struct rtw89_dev *rtwdev) +{ + if (RTW89_CHK_FW_FEATURE(TX_HISTORY_V1, &rtwdev->fw)) + rtw89_fw_h2c_phy_ch_rpt(rtwdev); + else + rtw89_fw_h2c_drv_ctrl_fw(rtwdev); +} + +static void rtw89_phy_stat_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + if (!rtwdev->phy_info.bb_stat_cfg.enable) + return; + + rtw89_phy_trigger_tx_count(rtwdev); + + rtw89_for_each_active_bb(rtwdev, bb) { + rtw89_phy_pmac_stat_update(rtwdev, bb); + rtw89_phy_tx_stat_update(rtwdev, bb); + } +} + +void rtw89_phy_stat_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_phy_stat_thermal_update(rtwdev); + rtw89_phy_thermal_protect_vcore(rtwdev); + rtw89_phy_thermal_protect(rtwdev); + rtw89_phy_stat_rssi_update(rtwdev); + rtw89_phy_stat_update(rtwdev); + + rtw89_for_each_active_bb(rtwdev, bb) { + bb->last_pkt_stat = bb->cur_pkt_stat; + memset(&bb->cur_pkt_stat, 0, sizeof(bb->cur_pkt_stat)); + + rtw89_chip_path_diff_update(rtwdev, bb); + } +} + +static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u32 time_us) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + + return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); +} + +static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u16 idx) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + + return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); +} + +static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + + env->ccx_manual_ctrl = false; + env->ccx_ongoing = false; + env->ccx_rac_lv = RTW89_RAC_RELEASE; + env->ccx_period = 0; + env->ccx_unit_idx = RTW89_CCX_32_US; + + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->en_mask, 1, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask, + RTW89_CCX_EDCCA_BW20_0, bb->phy_idx); +} + +static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + u16 report, u16 score) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + u32 numer = 0; + u16 ret = 0; + + numer = report * score + (env->ccx_period >> 1); + if (env->ccx_period) + ret = numer / env->ccx_period; + + return ret >= score ? score - 1 : ret; +} + +static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev, + u16 time_ms, u32 *period, + u32 *unit_idx) +{ + u32 idx; + u8 quotient; + + if (time_ms >= CCX_MAX_PERIOD) + time_ms = CCX_MAX_PERIOD; + + quotient = CCX_MAX_PERIOD_UNIT * time_ms / CCX_MAX_PERIOD; + + if (quotient < 4) + idx = RTW89_CCX_4_US; + else if (quotient < 8) + idx = RTW89_CCX_8_US; + else if (quotient < 16) + idx = RTW89_CCX_16_US; + else + idx = RTW89_CCX_32_US; + + *unit_idx = idx; + *period = (time_ms * MS_TO_4US_RATIO) >> idx; + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[Trigger Time] period:%d, unit_idx:%d\n", + *period, *unit_idx); +} + +static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "lv:(%d)->(0)\n", env->ccx_rac_lv); + + env->ccx_ongoing = false; + env->ccx_rac_lv = RTW89_RAC_RELEASE; + env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; +} + +static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + struct rtw89_ccx_para_info *para) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + bool is_update = env->ifs_clm_app != para->ifs_clm_app; + u8 i = 0; + u16 *ifs_th_l = env->ifs_clm_th_l; + u16 *ifs_th_h = env->ifs_clm_th_h; + u32 ifs_th0_us = 0, ifs_th_times = 0; + u32 ifs_th_h_us[RTW89_IFS_CLM_NUM] = {0}; + + if (!is_update) + goto ifs_update_finished; + + switch (para->ifs_clm_app) { + case RTW89_IFS_CLM_INIT: + case RTW89_IFS_CLM_BACKGROUND: + case RTW89_IFS_CLM_ACS: + case RTW89_IFS_CLM_DBG: + case RTW89_IFS_CLM_DIG: + case RTW89_IFS_CLM_TDMA_DIG: + ifs_th0_us = IFS_CLM_TH0_UPPER; + ifs_th_times = IFS_CLM_TH_MUL; + break; + case RTW89_IFS_CLM_DBG_MANUAL: + ifs_th0_us = para->ifs_clm_manual_th0; + ifs_th_times = para->ifs_clm_manual_th_times; + break; + default: + break; + } + + /* Set sampling threshold for 4 different regions, unit in idx_cnt. + * low[i] = high[i-1] + 1 + * high[i] = high[i-1] * ifs_th_times + */ + ifs_th_l[IFS_CLM_TH_START_IDX] = 0; + ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us; + ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, + ifs_th0_us); + for (i = 1; i < RTW89_IFS_CLM_NUM; i++) { + ifs_th_l[i] = ifs_th_h[i - 1] + 1; + ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times; + ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, ifs_th_h_us[i]); + } + +ifs_update_finished: + if (!is_update) + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "No need to update IFS_TH\n"); + + return is_update; +} + +static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + u8 i = 0; + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask, + env->ifs_clm_th_l[0], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask, + env->ifs_clm_th_l[1], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask, + env->ifs_clm_th_l[2], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask, + env->ifs_clm_th_l[3], bb->phy_idx); + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask, + env->ifs_clm_th_h[0], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask, + env->ifs_clm_th_h[1], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask, + env->ifs_clm_th_h[2], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask, + env->ifs_clm_th_h[3], bb->phy_idx); + + for (i = 0; i < RTW89_IFS_CLM_NUM; i++) + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "Update IFS_T%d_th{low, high} : {%d, %d}\n", + i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]); +} + +static void __rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + + env->nhm_include_cca = false; + env->nhm_mntr_time = 0; + env->nhm_sum = 0; + + rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config, ccx->nhm_en_mask, bb->phy_idx); + rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_method, ccx->nhm_pwr_method_msk, + bb->phy_idx); +} + +void rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_bb_ctx *bb; + + if (!chip->support_noise) + return; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_nhm_setting_init(rtwdev, bb); +} + +static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + struct rtw89_ccx_para_info para = {}; + + env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; + env->ifs_clm_mntr_time = 0; + + para.ifs_clm_app = RTW89_IFS_CLM_INIT; + if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, ¶)) + rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb); + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true, + bb->phy_idx); +} + +static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + enum rtw89_env_racing_lv level) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + int ret = 0; + + if (level >= RTW89_RAC_MAX_NUM) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[WARNING] Wrong LV=%d\n", level); + return -EINVAL; + } + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "ccx_ongoing=%d, level:(%d)->(%d)\n", env->ccx_ongoing, + env->ccx_rac_lv, level); + + if (env->ccx_ongoing) { + if (level <= env->ccx_rac_lv) + ret = -EINVAL; + else + env->ccx_ongoing = false; + } + + if (ret == 0) + env->ccx_rac_lv = level; + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "ccx racing success=%d\n", + !ret); + + return ret; +} + +static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 sel) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0, + bb->phy_idx); + if (sel & RTW89_PHY_ENV_MON_NHM) + rtw89_phy_write32_idx_clr(rtwdev, ccx->nhm_config, + ccx->nhm_en_mask, bb->phy_idx); + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1, + bb->phy_idx); + if (sel & RTW89_PHY_ENV_MON_NHM) + rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config, + ccx->nhm_en_mask, bb->phy_idx); + + env->ccx_ongoing = true; +} + +static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + u8 i = 0; + u32 res = 0; + + env->ifs_clm_tx_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_tx, PERCENT); + env->ifs_clm_edcca_excl_cca_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_edcca_excl_cca, + PERCENT); + env->ifs_clm_cck_fa_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERCENT); + env->ifs_clm_ofdm_fa_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERCENT); + env->ifs_clm_cck_cca_excl_fa_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckcca_excl_fa, + PERCENT); + env->ifs_clm_ofdm_cca_excl_fa_ratio = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmcca_excl_fa, + PERCENT); + env->ifs_clm_cck_fa_permil = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERMIL); + env->ifs_clm_ofdm_fa_permil = + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERMIL); + + for (i = 0; i < RTW89_IFS_CLM_NUM; i++) { + if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) { + env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD; + } else { + env->ifs_clm_ifs_avg[i] = + rtw89_phy_ccx_idx_to_us(rtwdev, bb, + env->ifs_clm_avg[i]); + } + + res = rtw89_phy_ccx_idx_to_us(rtwdev, bb, env->ifs_clm_cca[i]); + res += env->ifs_clm_his[i] >> 1; + if (env->ifs_clm_his[i]) + res /= env->ifs_clm_his[i]; + else + res = 0; + env->ifs_clm_cca_avg[i] = res; + } + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM ratio {Tx, EDCCA_exclu_cca} = {%d, %d}\n", + env->ifs_clm_tx_ratio, env->ifs_clm_edcca_excl_cca_ratio); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM FA ratio {CCK, OFDM} = {%d, %d}\n", + env->ifs_clm_cck_fa_ratio, env->ifs_clm_ofdm_fa_ratio); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM FA permil {CCK, OFDM} = {%d, %d}\n", + env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM CCA_exclu_FA ratio {CCK, OFDM} = {%d, %d}\n", + env->ifs_clm_cck_cca_excl_fa_ratio, + env->ifs_clm_ofdm_cca_excl_fa_ratio); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "Time:[his, ifs_avg(us), cca_avg(us)]\n"); + for (i = 0; i < RTW89_IFS_CLM_NUM; i++) + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "T%d:[%d, %d, %d]\n", + i + 1, env->ifs_clm_his[i], env->ifs_clm_ifs_avg[i], + env->ifs_clm_cca_avg[i]); +} + +static u8 rtw89_nhm_weighted_avg(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + u8 nhm_weight[RTW89_NHM_RPT_NUM]; + u32 nhm_weighted_sum = 0; + u8 weight_zero; + u8 i; + + if (env->nhm_sum == 0) + return 0; + + weight_zero = clamp_t(u16, env->nhm_th[0] - RTW89_NHM_WEIGHT_OFFSET, 0, U8_MAX); + + for (i = 0; i < RTW89_NHM_RPT_NUM; i++) { + if (i == 0) + nhm_weight[i] = weight_zero; + else if (i == (RTW89_NHM_RPT_NUM - 1)) + nhm_weight[i] = env->nhm_th[i - 1] + RTW89_NHM_WEIGHT_OFFSET; + else + nhm_weight[i] = (env->nhm_th[i - 1] + env->nhm_th[i]) / 2; + } + + if (rtwdev->chip->chip_id == RTL8852A || rtwdev->chip->chip_id == RTL8852B || + rtwdev->chip->chip_id == RTL8852C) { + if (env->nhm_th[RTW89_NHM_TH_NUM - 1] == RTW89_NHM_WA_TH) { + nhm_weight[RTW89_NHM_RPT_NUM - 1] = + env->nhm_th[RTW89_NHM_TH_NUM - 2] + + RTW89_NHM_WEIGHT_OFFSET; + nhm_weight[RTW89_NHM_RPT_NUM - 2] = + nhm_weight[RTW89_NHM_RPT_NUM - 1]; + } + + env->nhm_result[0] += env->nhm_result[RTW89_NHM_RPT_NUM - 1]; + env->nhm_result[RTW89_NHM_RPT_NUM - 1] = 0; + } + + for (i = 0; i < RTW89_NHM_RPT_NUM; i++) + nhm_weighted_sum += env->nhm_result[i] * nhm_weight[i]; + + return (nhm_weighted_sum / env->nhm_sum) >> RTW89_NHM_TH_FACTOR; +} + +static void __rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, enum rtw89_band hw_band, + u16 ch_hw_value) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_ccx_regs *ccx = phy->ccx; + struct ieee80211_supported_band *sband; + const struct rtw89_reg_def *nhm_rpt; + enum nl80211_band band; + u32 sum = 0; + u8 chan_idx; + u8 nhm_pwr; + u8 i; + + if (!rtw89_phy_read32_idx(rtwdev, ccx->nhm, ccx->nhm_ready, bb->phy_idx)) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "[NHM] Get NHM report Fail\n"); + return; + } + + for (i = 0; i < RTW89_NHM_RPT_NUM; i++) { + nhm_rpt = &(*chip->nhm_report)[i]; + + env->nhm_result[i] = + rtw89_phy_read32_idx(rtwdev, nhm_rpt->addr, + nhm_rpt->mask, bb->phy_idx); + sum += env->nhm_result[i]; + } + env->nhm_sum = sum; + nhm_pwr = rtw89_nhm_weighted_avg(rtwdev, bb); + + if (!ch_hw_value) + return; + + band = rtw89_hw_to_nl80211_band(hw_band); + sband = rtwdev->hw->wiphy->bands[band]; + if (!sband) + return; + + for (chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) { + struct ieee80211_channel *channel; + struct rtw89_nhm_report *rpt; + struct list_head *nhm_list; + + channel = &sband->channels[chan_idx]; + if (channel->hw_value != ch_hw_value) + continue; + + rpt = &env->nhm_his[hw_band][chan_idx]; + nhm_list = &env->nhm_rpt_list; + + rpt->channel = channel; + rpt->noise = nhm_pwr; + + if (list_empty(&rpt->list)) + list_add_tail(&rpt->list, nhm_list); + + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "[NHM] channel not found\n"); +} + +void rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, enum rtw89_band hw_band, + u16 ch_hw_value) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_bb_ctx *bb; + + if (!chip->support_noise) + return; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_nhm_get_result(rtwdev, bb, hw_band, ch_hw_value); +} + +static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + u8 i = 0; + + if (rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr, + ccx->ifs_cnt_done_mask, bb->phy_idx) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "Get IFS_CLM report Fail\n"); + return false; + } + + env->ifs_clm_tx = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr, + ccx->ifs_clm_tx_cnt_msk, bb->phy_idx); + env->ifs_clm_edcca_excl_cca = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr, + ccx->ifs_clm_edcca_excl_cca_fa_mask, bb->phy_idx); + env->ifs_clm_cckcca_excl_fa = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr, + ccx->ifs_clm_cckcca_excl_fa_mask, bb->phy_idx); + env->ifs_clm_ofdmcca_excl_fa = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr, + ccx->ifs_clm_ofdmcca_excl_fa_mask, bb->phy_idx); + env->ifs_clm_cckfa = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr, + ccx->ifs_clm_cck_fa_mask, bb->phy_idx); + env->ifs_clm_ofdmfa = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr, + ccx->ifs_clm_ofdm_fa_mask, bb->phy_idx); + + env->ifs_clm_his[0] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t1_his_mask, bb->phy_idx); + env->ifs_clm_his[1] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t2_his_mask, bb->phy_idx); + + env->ifs_clm_his[2] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2, + ccx->ifs_t3_his_mask, bb->phy_idx); + env->ifs_clm_his[3] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2, + ccx->ifs_t4_his_mask, bb->phy_idx); + + env->ifs_clm_avg[0] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr, + ccx->ifs_t1_avg_mask, bb->phy_idx); + env->ifs_clm_avg[1] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr, + ccx->ifs_t2_avg_mask, bb->phy_idx); + env->ifs_clm_avg[2] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr, + ccx->ifs_t3_avg_mask, bb->phy_idx); + env->ifs_clm_avg[3] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr, + ccx->ifs_t4_avg_mask, bb->phy_idx); + + env->ifs_clm_cca[0] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr, + ccx->ifs_t1_cca_mask, bb->phy_idx); + env->ifs_clm_cca[1] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr, + ccx->ifs_t2_cca_mask, bb->phy_idx); + env->ifs_clm_cca[2] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr, + ccx->ifs_t3_cca_mask, bb->phy_idx); + env->ifs_clm_cca[3] = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr, + ccx->ifs_t4_cca_mask, bb->phy_idx); + + env->ifs_clm_total_ifs = + rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr, + ccx->ifs_total_mask, bb->phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n", + env->ifs_clm_total_ifs); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "{Tx, EDCCA_exclu_cca} = {%d, %d}\n", + env->ifs_clm_tx, env->ifs_clm_edcca_excl_cca); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM FA{CCK, OFDM} = {%d, %d}\n", + env->ifs_clm_cckfa, env->ifs_clm_ofdmfa); + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "IFS-CLM CCA_exclu_FA{CCK, OFDM} = {%d, %d}\n", + env->ifs_clm_cckcca_excl_fa, env->ifs_clm_ofdmcca_excl_fa); + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Time:[his, avg, cca]\n"); + for (i = 0; i < RTW89_IFS_CLM_NUM; i++) + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i], + env->ifs_clm_avg[i], env->ifs_clm_cca[i]); + + rtw89_phy_ifs_clm_get_utility(rtwdev, bb); + + return true; +} + +static bool rtw89_phy_edcca_clm_get_result(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + u32 val; + + val = rtw89_phy_read32_idx(rtwdev, ccx->edcca_clm_rdy, + ccx->edcca_clm_rdy_mask, bb->phy_idx); + if (!val) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "Get EDCCA_CLM report Fail\n"); + return false; + } + + val = rtw89_phy_read32_idx(rtwdev, ccx->edcca_clm_cnt, + ccx->edcca_clm_cnt_mask, bb->phy_idx); + env->edcca_clm_ratio = rtw89_phy_ccx_get_report(rtwdev, bb, val, PERCENT); + + return true; +} + +static void rtw89_phy_nhm_th_update(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + static const u8 nhm_th_11k[RTW89_NHM_RPT_NUM] = { + 18, 21, 24, 27, 30, 35, 40, 45, 50, 55, 60, 0 + }; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_reg_def *nhm_th; + u8 i; + + for (i = 0; i < RTW89_NHM_RPT_NUM; i++) + env->nhm_th[i] = nhm_th_11k[i] << RTW89_NHM_TH_FACTOR; + + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || + chip->chip_id == RTL8852C) + env->nhm_th[RTW89_NHM_TH_NUM - 1] = RTW89_NHM_WA_TH; + + for (i = 0; i < RTW89_NHM_TH_NUM; i++) { + nhm_th = &(*chip->nhm_th)[i]; + + rtw89_phy_write32_idx(rtwdev, nhm_th->addr, nhm_th->mask, + env->nhm_th[i], bb->phy_idx); + } +} + +static int rtw89_phy_nhm_set(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + struct rtw89_ccx_para_info *para) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + u32 unit_idx = 0; + u32 period = 0; + + if (para->mntr_time == 0) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[NHM] MNTR_TIME is 0\n"); + return -EINVAL; + } + + if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv)) + return -EINVAL; + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[NHM]nhm_incld_cca=%d, mntr_time=%d ms\n", + para->nhm_incld_cca, para->mntr_time); + + if (para->mntr_time != env->nhm_mntr_time) { + rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time, + &period, &unit_idx); + rtw89_phy_write32_idx(rtwdev, ccx->nhm_config, + ccx->nhm_period_mask, period, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->nhm_config, + ccx->nhm_unit_mask, period, bb->phy_idx); + + env->nhm_mntr_time = para->mntr_time; + env->ccx_period = period; + env->ccx_unit_idx = unit_idx; + } + + if (para->nhm_incld_cca != env->nhm_include_cca) { + rtw89_phy_write32_idx(rtwdev, ccx->nhm_config, + ccx->nhm_include_cca_mask, para->nhm_incld_cca, + bb->phy_idx); + + env->nhm_include_cca = para->nhm_incld_cca; + } + + rtw89_phy_nhm_th_update(rtwdev, bb); + + return 0; +} + +static void __rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_ccx_para_info para = { + .mntr_time = RTW89_NHM_MNTR_TIME, + .rac_lv = RTW89_RAC_LV_1, + .nhm_incld_cca = true, + }; + + rtw89_phy_ccx_racing_release(rtwdev, bb); + + rtw89_phy_nhm_set(rtwdev, bb, ¶); + rtw89_phy_ccx_trigger(rtwdev, bb, RTW89_PHY_ENV_MON_NHM); +} + +void rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_bb_ctx *bb; + + if (!chip->support_noise) + return; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_nhm_trigger(rtwdev, bb); +} + +static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + struct rtw89_ccx_para_info *para) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_ccx_regs *ccx = phy->ccx; + u32 period = 0; + u32 unit_idx = 0; + + if (para->mntr_time == 0) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[WARN] MNTR_TIME is 0\n"); + return -EINVAL; + } + + if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv)) + return -EINVAL; + + if (para->mntr_time != env->ifs_clm_mntr_time) { + rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time, + &period, &unit_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, + ccx->ifs_clm_period_mask, period, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, + ccx->ifs_clm_cnt_unit_mask, + unit_idx, bb->phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "Update IFS-CLM time ((%d)) -> ((%d))\n", + env->ifs_clm_mntr_time, para->mntr_time); + + env->ifs_clm_mntr_time = para->mntr_time; + env->ccx_period = (u16)period; + env->ccx_unit_idx = (u8)unit_idx; + } + + if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, para)) { + env->ifs_clm_app = para->ifs_clm_app; + rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb); + } + + return 0; +} + +static void __rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_ccx_para_info para = {}; + u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL; + + env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL; + if (env->ccx_manual_ctrl) { + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "CCX in manual ctrl\n"); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "BB-%d env_monitor track\n", bb->phy_idx); + + /* only ifs_clm for now */ + if (rtw89_phy_ifs_clm_get_result(rtwdev, bb)) + env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM; + + if (rtw89_phy_edcca_clm_get_result(rtwdev, bb)) + env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_EDCCA_CLM; + + rtw89_phy_ccx_racing_release(rtwdev, bb); + para.mntr_time = 1900; + para.rac_lv = RTW89_RAC_LV_1; + para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; + + if (rtw89_phy_ifs_clm_set(rtwdev, bb, ¶) == 0) + chk_result |= RTW89_PHY_ENV_MON_IFS_CLM; + if (chk_result) + rtw89_phy_ccx_trigger(rtwdev, bb, chk_result); + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "get_result=0x%x, chk_result:0x%x\n", + env->ccx_watchdog_result, chk_result); +} + +void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_env_monitor_track(rtwdev, bb); +} + +static bool rtw89_physts_ie_page_valid(struct rtw89_dev *rtwdev, + enum rtw89_phy_status_bitmap *ie_page) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM || + *ie_page == RTW89_RSVD_9) + return false; + else if (*ie_page > RTW89_RSVD_9 && *ie_page < RTW89_EHT_PKT) + *ie_page -= 1; + + if (*ie_page == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX) + return false; + + return true; +} + +static u32 rtw89_phy_get_ie_bitmap_addr(struct rtw89_dev *rtwdev, + enum rtw89_phy_status_bitmap ie_page) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + static const u8 ie_page_shift = 2; + + if (ie_page == RTW89_EHT_PKT) + return phy->physt_bmp_eht; + + return phy->physt_bmp_start + (ie_page << ie_page_shift); +} + +static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev, + enum rtw89_phy_status_bitmap ie_page, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page)) + return 0; + + addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page); + + return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx); +} + +static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev, + enum rtw89_phy_status_bitmap ie_page, + u32 val, enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 addr; + + if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page)) + return; + + if (chip->chip_id == RTL8852A) + val &= B_PHY_STS_BITMAP_MSK_52A; + + addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page); + rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); +} + +static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev, + bool enable, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_physts_regs *physts = phy->physts; + + if (enable) { + rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr, + physts->dis_trigger_fail_mask, phy_idx); + rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr, + physts->dis_trigger_brk_mask, phy_idx); + } else { + rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr, + physts->dis_trigger_fail_mask, phy_idx); + rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr, + physts->dis_trigger_brk_mask, phy_idx); + } +} + +static void rtw89_physts_enable_hdr_2(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_gen == RTW89_CHIP_AX || chip->chip_id == RTL8922A) + return; + + rtw89_phy_write32_idx_set(rtwdev, R_STS_HDR2_PARSING_BE4, + B_STS_HDR2_PARSING_BE4, phy_idx); +} + +static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 monitor_mode_mu_ies = 0; + u32 monitor_mode_su_ies = 0; + u32 val; + u8 i; + + if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) { + monitor_mode_mu_ies = BIT(RTW89_PHYSTS_IE09_FTR_0); + if (phy->physt_gen < 2) + monitor_mode_mu_ies |= BIT(RTW89_PHYSTS_IE10_FTR_PLCP_EXT); + + monitor_mode_su_ies = BIT(RTW89_PHYSTS_IE09_FTR_0); + } + + rtw89_physts_enable_fail_report(rtwdev, false, phy_idx); + + /* enable hdr_2 for 8922D (PHYSTS_BE_GEN2 above) */ + rtw89_physts_enable_hdr_2(rtwdev, phy_idx); + + for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) { + if (i == RTW89_RSVD_9 || + (i == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX)) + continue; + + val = rtw89_physts_get_ie_bitmap(rtwdev, i, phy_idx); + if (i == RTW89_HE_MU || i == RTW89_VHT_MU) { + val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF); + val |= monitor_mode_mu_ies; + } else if (i == RTW89_TRIG_BASE_PPDU) { + val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF) | + BIT(RTW89_PHYSTS_IE01_CMN_OFDM); + } else if (i >= RTW89_CCK_PKT) { + val &= ~(GENMASK(RTW89_PHYSTS_IE07_CMN_EXT_PATH_D, + RTW89_PHYSTS_IE04_CMN_EXT_PATH_A)); + + if (i == RTW89_CCK_PKT) + val |= BIT(RTW89_PHYSTS_IE01_CMN_OFDM); + else if (i >= RTW89_HT_PKT) + val |= BIT(RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0); + } + + if (i == RTW89_HE_PKT || i == RTW89_VHT_PKT) + val |= monitor_mode_su_ies; + + rtw89_physts_set_ie_bitmap(rtwdev, i, val, phy_idx); + } +} + +void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev) +{ + __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1); +} + +static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, int type) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_phy_dig_gain_cfg *cfg; + struct rtw89_dig_info *dig = &bb->dig; + const char *msg; + u8 i; + s8 gain_base; + s8 *gain_arr; + u32 tmp; + + switch (type) { + case RTW89_DIG_GAIN_LNA_G: + gain_arr = dig->lna_gain_g; + gain_base = LNA0_GAIN; + cfg = chip->dig_table->cfg_lna_g; + msg = "lna_gain_g"; + break; + case RTW89_DIG_GAIN_TIA_G: + gain_arr = dig->tia_gain_g; + gain_base = TIA0_GAIN_G; + cfg = chip->dig_table->cfg_tia_g; + msg = "tia_gain_g"; + break; + case RTW89_DIG_GAIN_LNA_A: + gain_arr = dig->lna_gain_a; + gain_base = LNA0_GAIN; + cfg = chip->dig_table->cfg_lna_a; + msg = "lna_gain_a"; + break; + case RTW89_DIG_GAIN_TIA_A: + gain_arr = dig->tia_gain_a; + gain_base = TIA0_GAIN_A; + cfg = chip->dig_table->cfg_tia_a; + msg = "tia_gain_a"; + break; + default: + return; + } + + for (i = 0; i < cfg->size; i++) { + tmp = rtw89_phy_read32_idx(rtwdev, cfg->table[i].addr, + cfg->table[i].mask, bb->phy_idx); + tmp >>= DIG_GAIN_SHIFT; + gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base; + gain_base += DIG_GAIN; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s[%d]=%d\n", + msg, i, gain_arr[i]); + } +} + +static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + u32 tmp; + u8 i; + + if (!rtwdev->hal.support_igi) + return; + + tmp = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PKPW, + B_PATH0_IB_PKPW_MSK, bb->phy_idx); + dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT); + dig->ib_pbk = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PBK, + B_PATH0_IB_PBK_MSK, bb->phy_idx); + rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n", + dig->ib_pkpwr, dig->ib_pbk); + + for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++) + rtw89_phy_dig_read_gain_table(rtwdev, bb, i); +} + +static const u8 rssi_nolink = 22; +static const u8 igi_rssi_th[IGI_RSSI_TH_NUM] = {68, 84, 90, 98, 104}; +static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88}; +static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16}; +static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528}; + +static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_phy_ch_info *ch_info = &bb->ch_info; + struct rtw89_dig_info *dig = &bb->dig; + bool is_linked = rtwdev->total_sta_assoc > 0; + + if (is_linked) { + dig->igi_rssi = ch_info->rssi_min >> 1; + } else { + rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n"); + dig->igi_rssi = rssi_nolink; + } +} + +static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + bool is_linked = rtwdev->total_sta_assoc > 0; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + const u16 *fa_th_src = NULL; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[bb->phy_idx]; + + switch (chan->band_type) { + case RTW89_BAND_2G: + dig->lna_gain = dig->lna_gain_g; + dig->tia_gain = dig->tia_gain_g; + fa_th_src = is_linked ? fa_th_2g : fa_th_nolink; + dig->force_gaincode_idx_en = false; + dig->dyn_pd_th_en = true; + break; + case RTW89_BAND_5G: + default: + dig->lna_gain = dig->lna_gain_a; + dig->tia_gain = dig->tia_gain_a; + fa_th_src = is_linked ? fa_th_5g : fa_th_nolink; + dig->force_gaincode_idx_en = true; + dig->dyn_pd_th_en = true; + break; + } + memcpy(dig->fa_th, fa_th_src, sizeof(dig->fa_th)); + memcpy(dig->igi_rssi_th, igi_rssi_th, sizeof(dig->igi_rssi_th)); +} + +static const u8 pd_low_th_offset = 16, dynamic_igi_min = 0x20; +static const u8 igi_max_performance_mode = 0x5a; +static const u8 dynamic_pd_threshold_max; + +static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + + dig->cur_gaincode.lna_idx = LNA_IDX_MAX; + dig->cur_gaincode.tia_idx = TIA_IDX_MAX; + dig->cur_gaincode.rxb_idx = RXB_IDX_MAX; + dig->force_gaincode.lna_idx = LNA_IDX_MAX; + dig->force_gaincode.tia_idx = TIA_IDX_MAX; + dig->force_gaincode.rxb_idx = RXB_IDX_MAX; + + dig->dyn_igi_max = igi_max_performance_mode; + dig->dyn_igi_min = dynamic_igi_min; + dig->dyn_pd_th_max = dynamic_pd_threshold_max; + dig->dyn_pd_max_cnt = 0; + dig->pd_low_th_ofst = pd_low_th_offset; + dig->is_linked_pre = false; +} + +static void __rtw89_phy_dig_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig_init\n", bb->phy_idx); + + rtw89_phy_dig_update_gain_para(rtwdev, bb); + rtw89_phy_dig_reset(rtwdev, bb); +} + +static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_dig_init(rtwdev, bb); +} + +static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi) +{ + struct rtw89_dig_info *dig = &bb->dig; + u8 lna_idx; + + if (rssi < dig->igi_rssi_th[0]) + lna_idx = RTW89_DIG_GAIN_LNA_IDX6; + else if (rssi < dig->igi_rssi_th[1]) + lna_idx = RTW89_DIG_GAIN_LNA_IDX5; + else if (rssi < dig->igi_rssi_th[2]) + lna_idx = RTW89_DIG_GAIN_LNA_IDX4; + else if (rssi < dig->igi_rssi_th[3]) + lna_idx = RTW89_DIG_GAIN_LNA_IDX3; + else if (rssi < dig->igi_rssi_th[4]) + lna_idx = RTW89_DIG_GAIN_LNA_IDX2; + else + lna_idx = RTW89_DIG_GAIN_LNA_IDX1; + + return lna_idx; +} + +static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi) +{ + struct rtw89_dig_info *dig = &bb->dig; + u8 tia_idx; + + if (rssi < dig->igi_rssi_th[0]) + tia_idx = RTW89_DIG_GAIN_TIA_IDX1; + else + tia_idx = RTW89_DIG_GAIN_TIA_IDX0; + + return tia_idx; +} + +#define IB_PBK_BASE 110 +#define WB_RSSI_BASE 10 +static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi, + struct rtw89_agc_gaincode_set *set) +{ + struct rtw89_dig_info *dig = &bb->dig; + s8 lna_gain = dig->lna_gain[set->lna_idx]; + s8 tia_gain = dig->tia_gain[set->tia_idx]; + s32 wb_rssi = rssi + lna_gain + tia_gain; + s32 rxb_idx_tmp = IB_PBK_BASE + WB_RSSI_BASE; + u8 rxb_idx; + + rxb_idx_tmp += dig->ib_pkpwr - dig->ib_pbk - wb_rssi; + rxb_idx = clamp_t(s32, rxb_idx_tmp, RXB_IDX_MIN, RXB_IDX_MAX); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "wb_rssi=%03d, rxb_idx_tmp=%03d\n", + wb_rssi, rxb_idx_tmp); + + return rxb_idx; +} + +static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi, + struct rtw89_agc_gaincode_set *set) +{ + set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, bb, rssi); + set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, bb, rssi); + set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, bb, rssi, set); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n", + rssi, set->lna_idx, set->tia_idx, set->rxb_idx); +} + +#define IGI_OFFSET_MAX 25 +#define IGI_OFFSET_MUL 2 +static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + enum rtw89_dig_noisy_level noisy_lv; + u8 igi_offset = dig->fa_rssi_ofst; + u16 fa_ratio = 0; + + fa_ratio = env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil; + + if (fa_ratio < dig->fa_th[0]) + noisy_lv = RTW89_DIG_NOISY_LEVEL0; + else if (fa_ratio < dig->fa_th[1]) + noisy_lv = RTW89_DIG_NOISY_LEVEL1; + else if (fa_ratio < dig->fa_th[2]) + noisy_lv = RTW89_DIG_NOISY_LEVEL2; + else if (fa_ratio < dig->fa_th[3]) + noisy_lv = RTW89_DIG_NOISY_LEVEL3; + else + noisy_lv = RTW89_DIG_NOISY_LEVEL_MAX; + + if (noisy_lv == RTW89_DIG_NOISY_LEVEL0 && igi_offset < 2) + igi_offset = 0; + else + igi_offset += noisy_lv * IGI_OFFSET_MUL; + + igi_offset = min_t(u8, igi_offset, IGI_OFFSET_MAX); + dig->fa_rssi_ofst = igi_offset; + dig->noisy_lv = noisy_lv; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "fa_th: [+6 (%d) +4 (%d) +2 (%d) 0 (%d) -2 ]\n", + dig->fa_th[3], dig->fa_th[2], dig->fa_th[1], dig->fa_th[0]); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "fa(CCK,OFDM,ALL)=(%d,%d,%d)%%, noisy_lv=%d, ofst=%d\n", + env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil, + env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil, + noisy_lv, igi_offset); +} + +static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 lna_idx) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_lna_init.addr, + dig_regs->p0_lna_init.mask, lna_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_lna_init.addr, + dig_regs->p1_lna_init.mask, lna_idx, bb->phy_idx); +} + +static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 tia_idx) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_tia_init.addr, + dig_regs->p0_tia_init.mask, tia_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_tia_init.addr, + dig_regs->p1_tia_init.mask, tia_idx, bb->phy_idx); +} + +static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rxb_idx) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_rxb_init.addr, + dig_regs->p0_rxb_init.mask, rxb_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_rxb_init.addr, + dig_regs->p1_rxb_init.mask, rxb_idx, bb->phy_idx); +} + +static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + const struct rtw89_agc_gaincode_set set) +{ + if (!rtwdev->hal.support_igi) + return; + + rtw89_phy_dig_set_lna_idx(rtwdev, bb, set.lna_idx); + rtw89_phy_dig_set_tia_idx(rtwdev, bb, set.tia_idx); + rtw89_phy_dig_set_rxb_idx(rtwdev, bb, set.rxb_idx); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n", + set.lna_idx, set.tia_idx, set.rxb_idx); +} + +static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + bool enable) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) + return; + + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_p20_pagcugc_en.addr, + dig_regs->p0_p20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_s20_pagcugc_en.addr, + dig_regs->p0_s20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_p20_pagcugc_en.addr, + dig_regs->p1_p20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_s20_pagcugc_en.addr, + dig_regs->p1_s20_pagcugc_en.mask, enable, bb->phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable); +} + +static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + + if (!rtwdev->hal.support_igi) + return; + + if (dig->force_gaincode_idx_en) { + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode); + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "Force gaincode index enabled.\n"); + } else { + rtw89_phy_dig_gaincode_by_rssi(rtwdev, bb, dig->igi_fa_rssi, + &dig->cur_gaincode); + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->cur_gaincode); + } +} + +static u8 rtw89_phy_dig_cal_under_region(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + const struct rtw89_chan *chan) +{ + enum rtw89_bandwidth cbw = chan->band_width; + struct rtw89_dig_info *dig = &bb->dig; + u8 under_region = dig->pd_low_th_ofst; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + under_region += PD_TH_SB_FLTR_CMP_VAL; + + switch (cbw) { + case RTW89_CHANNEL_WIDTH_40: + under_region += PD_TH_BW40_CMP_VAL; + break; + case RTW89_CHANNEL_WIDTH_80: + under_region += PD_TH_BW80_CMP_VAL; + break; + case RTW89_CHANNEL_WIDTH_160: + under_region += PD_TH_BW160_CMP_VAL; + break; + case RTW89_CHANNEL_WIDTH_20: + fallthrough; + default: + under_region += PD_TH_BW20_CMP_VAL; + break; + } + + return under_region; +} + +static u32 __rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + u8 rssi, bool enable, + const struct rtw89_chan *chan) +{ + struct rtw89_dig_info *dig = &bb->dig; + u8 ofdm_cca_th, under_region; + u8 final_rssi; + u32 pd_val; + + under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan); + dig->dyn_pd_th_max = dig->igi_rssi; + + final_rssi = min_t(u8, rssi, dig->igi_rssi); + ofdm_cca_th = clamp_t(u8, final_rssi, PD_TH_MIN_RSSI + under_region, + PD_TH_MAX_RSSI + under_region); + + if (enable) { + pd_val = (ofdm_cca_th - under_region - PD_TH_MIN_RSSI) >> 1; + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "igi=%d, ofdm_ccaTH=%d, backoff=%d, PD_low=%d\n", + final_rssi, ofdm_cca_th, under_region, pd_val); + } else { + pd_val = 0; + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "Dynamic PD th disabled, Set PD_low_bd=0\n"); + } + + return pd_val; +} + +static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + u8 rssi, bool enable) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + struct rtw89_dig_info *dig = &bb->dig; + struct rtw89_hal *hal = &rtwdev->hal; + u8 final_rssi, under_region = dig->pd_low_th_ofst; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + s8 cck_cca_th; + u32 pd_val; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[bb->phy_idx]; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) { + pd_val = hal->fixed_dig_pd_th; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "Fixed DIG: PD_low=%d\n", pd_val); + } else { + pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan); + } + dig->bak_dig = pd_val; + + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_spatial_reuse_en, enable, bb->phy_idx); + + if (!hal->support_cckpd) + return; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) { + pd_val = hal->fixed_dig_cck_pd_th; + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "Fixed DIG: cck_PD_low=((%d))dB\n", pd_val); + } else { + final_rssi = min_t(u8, rssi, dig->igi_rssi); + under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan); + cck_cca_th = max_t(s8, final_rssi - under_region, CCKPD_TH_MIN_RSSI); + pd_val = (u32)(cck_cca_th - IGI_RSSI_MAX); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n", + final_rssi, cck_cca_th, under_region, pd_val); + } + + rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_reg, + dig_regs->bmode_cca_rssi_limit_en, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_lower_bound_reg, + dig_regs->bmode_rssi_nocca_low_th_mask, pd_val, bb->phy_idx); +} + +void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + + dig->bypass_dig = false; + rtw89_phy_dig_para_reset(rtwdev, bb); + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode); + rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi_nolink, false); + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false); + rtw89_phy_dig_update_para(rtwdev, bb); +} + +static void rtw89_phy_dig_diag(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool is_linked) +{ +#define RTW89_DIAG_BB_PD_MAX_PERIOD 5 + struct rtw89_diag_bb *diag = &bb->diag; + struct rtw89_dig_info *dig = &bb->dig; + + diag->diag_bb_bitmap &= ~BIT(RTW89_DIAG_BB_PD); + + if (dig->dyn_igi_max != dig->igi_fa_rssi || + dig->noisy_lv < RTW89_DIG_NOISY_LEVEL_MAX) { + dig->dyn_pd_max_cnt = 0; + return; + } + + if (++dig->dyn_pd_max_cnt < RTW89_DIAG_BB_PD_MAX_PERIOD || !is_linked) + return; + + diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_PD); + diag->diag_bb_cnt[RTW89_DIAG_BB_PD]++; +} + +#define IGI_RSSI_MIN 10 +#define ABS_IGI_MIN 0xc +static +void rtw89_phy_cal_igi_fa_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool is_linked) +{ + struct rtw89_dig_info *dig = &bb->dig; + u8 igi_min; + + rtw89_phy_dig_igi_offset_by_env(rtwdev, bb); + + igi_min = max_t(int, dig->igi_rssi - IGI_RSSI_MIN, 0); + dig->dyn_igi_max = min(igi_min + IGI_OFFSET_MAX, igi_max_performance_mode); + dig->dyn_igi_min = max(igi_min, ABS_IGI_MIN); + + if (dig->dyn_igi_max >= dig->dyn_igi_min) { + dig->igi_fa_rssi += dig->fa_rssi_ofst; + dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min, + dig->dyn_igi_max); + } else { + dig->igi_fa_rssi = dig->dyn_igi_max; + } + + rtw89_phy_dig_diag(rtwdev, bb, is_linked); +} + +struct rtw89_phy_iter_mcc_dig { + struct rtw89_vif_link *rtwvif_link; + bool has_sta; + u8 rssi_min; +}; + +static void rtw89_phy_set_mcc_dig(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_bb_ctx *bb, + u8 rssi_min, u8 mcc_role_idx, + bool is_linked) +{ + struct rtw89_dig_info *dig = &bb->dig; + const struct rtw89_chan *chan; + u8 pd_val; + + if (is_linked) { + dig->igi_rssi = rssi_min >> 1; + dig->igi_fa_rssi = dig->igi_rssi; + } else { + rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n"); + dig->igi_rssi = rssi_nolink; + dig->igi_fa_rssi = dig->igi_rssi; + } + + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + rtw89_phy_cal_igi_fa_rssi(rtwdev, bb, is_linked); + pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi, + is_linked, chan); + rtw89_fw_h2c_mcc_dig(rtwdev, rtwvif_link->chanctx_idx, + mcc_role_idx, pd_val, true); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "MCC chanctx_idx %d chan %d rssi %d pd_val %d", + rtwvif_link->chanctx_idx, chan->primary_channel, + dig->igi_rssi, pd_val); +} + +static void rtw89_phy_set_mcc_dig_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_phy_iter_mcc_dig *mcc_dig = (struct rtw89_phy_iter_mcc_dig *)data; + unsigned int link_id = mcc_dig->rtwvif_link->link_id; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + + if (rtwsta->rtwvif != mcc_dig->rtwvif_link->rtwvif) + return; + + rtwsta_link = rtwsta->links[link_id]; + if (!rtwsta_link) + return; + + mcc_dig->has_sta = true; + if (ewma_rssi_read(&rtwsta_link->avg_rssi) < mcc_dig->rssi_min) + mcc_dig->rssi_min = ewma_rssi_read(&rtwsta_link->avg_rssi); +} + +static void rtw89_phy_dig_mcc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_phy_iter_mcc_dig mcc_dig; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_mcc_links_info info; + int i; + + rtw89_mcc_get_links(rtwdev, &info); + for (i = 0; i < ARRAY_SIZE(info.links); i++) { + rtwvif_link = info.links[i]; + if (!rtwvif_link) + continue; + + memset(&mcc_dig, 0, sizeof(mcc_dig)); + mcc_dig.rtwvif_link = rtwvif_link; + mcc_dig.has_sta = false; + mcc_dig.rssi_min = U8_MAX; + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_phy_set_mcc_dig_iter, + &mcc_dig); + + rtw89_phy_set_mcc_dig(rtwdev, rtwvif_link, bb, + mcc_dig.rssi_min, i, mcc_dig.has_sta); + } +} + +static void rtw89_phy_dig_ctrl(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb, + bool pause_dig, bool restore) +{ + const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; + struct rtw89_dig_info *dig = &bb->dig; + struct rtw89_hal *hal = &rtwdev->hal; + bool en_dig; + u32 pd_val; + + if (dig->pause_dig == pause_dig) + return; + + if (pause_dig) { + en_dig = false; + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) + pd_val = hal->fixed_dig_pd_th; + else + pd_val = 0; + } else { + en_dig = rtwdev->total_sta_assoc > 0; + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) + pd_val = hal->fixed_dig_pd_th; + else + pd_val = restore ? dig->bak_dig : 0; + } + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s <%s> PD_low=%d", __func__, + pause_dig ? "suspend" : "resume", pd_val); + + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_spatial_reuse_en, en_dig, bb->phy_idx); + + dig->pause_dig = pause_dig; +} + +void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + rtw89_phy_dig_ctrl(rtwdev, bb, true, false); +} + +void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + rtw89_phy_dig_ctrl(rtwdev, bb, false, restore); +} + +static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_dig_info *dig = &bb->dig; + bool is_linked = rtwdev->total_sta_assoc > 0; + enum rtw89_entity_mode mode; + + if (unlikely(dig->bypass_dig)) { + dig->bypass_dig = false; + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx); + + rtw89_phy_dig_update_rssi_info(rtwdev, bb); + + mode = rtw89_get_entity_mode(rtwdev); + if (mode == RTW89_ENTITY_MODE_MCC) { + rtw89_phy_dig_mcc(rtwdev, bb); + return; + } + + if (unlikely(dig->pause_dig)) + return; + + if (!dig->is_linked_pre && is_linked) { + rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n"); + rtw89_phy_dig_update_para(rtwdev, bb); + dig->igi_fa_rssi = dig->igi_rssi; + } else if (dig->is_linked_pre && !is_linked) { + rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n"); + rtw89_phy_dig_update_para(rtwdev, bb); + dig->igi_fa_rssi = dig->igi_rssi; + } + dig->is_linked_pre = is_linked; + + rtw89_phy_cal_igi_fa_rssi(rtwdev, bb, is_linked); + + rtw89_debug(rtwdev, RTW89_DBG_DIG, + "rssi=%03d, dyn_joint(max,min)=(%d,%d), final_rssi=%d\n", + dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, + dig->igi_fa_rssi); + + rtw89_phy_dig_config_igi(rtwdev, bb); + + rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi, dig->dyn_pd_th_en); + + if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max) + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, true); + else + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false); +} + +void rtw89_phy_dig(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_dig(rtwdev, bb); +} + +static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u8 rssi_a, rssi_b; + u32 candidate; + + rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]); + rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]); + + if (rssi_a > rssi_b + RTW89_TX_DIV_RSSI_RAW_TH) + candidate = RF_A; + else if (rssi_b > rssi_a + RTW89_TX_DIV_RSSI_RAW_TH) + candidate = RF_B; + else + return; + + if (hal->antenna_tx == candidate) + return; + + hal->antenna_tx = candidate; + rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta_link); + + if (hal->antenna_tx == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x12); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, B_P1_RFMODE_MUX, 0x11); + } else if (hal->antenna_tx == RF_B) { + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x11); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, B_P1_RFMODE_MUX, 0x12); + } +} + +static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + bool *done = data; + + if (WARN(ieee80211_vif_is_mld(vif), "MLD mix path_div\n")) + return; + + if (sta->tdls) + return; + + if (*done) + return; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) + continue; + + *done = true; + __rtw89_phy_tx_path_div_sta_iter(rtwdev, rtwsta_link); + return; + } +} + +void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + bool done = false; + + if (!hal->tx_path_diversity) + return; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + rtw89_phy_tx_path_div_sta_iter, + &done); +} + +#define ANTDIV_MAIN 0 +#define ANTDIV_AUX 1 + +static void rtw89_phy_antdiv_set_ant(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u8 default_ant, optional_ant; + + if (!hal->ant_diversity || hal->antenna_tx == 0) + return; + + if (hal->antenna_tx == RF_B) { + default_ant = ANTDIV_AUX; + optional_ant = ANTDIV_MAIN; + } else { + default_ant = ANTDIV_MAIN; + optional_ant = ANTDIV_AUX; + } + + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_CGCS_CTRL, + default_ant, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ORI, + default_ant, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ALT, + optional_ant, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_TX_ORI, + default_ant, RTW89_PHY_0); +} + +static void rtw89_phy_swap_hal_antenna(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + hal->antenna_rx = hal->antenna_rx == RF_A ? RF_B : RF_A; + hal->antenna_tx = hal->antenna_rx; +} + +static void rtw89_phy_antdiv_decision_state(struct rtw89_dev *rtwdev) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + struct rtw89_hal *hal = &rtwdev->hal; + bool no_change = false; + u8 main_rssi, aux_rssi; + u8 main_evm, aux_evm; + u32 candidate; + + antdiv->get_stats = false; + antdiv->training_count = 0; + + main_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->main_stats); + main_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->main_stats); + aux_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->aux_stats); + aux_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->aux_stats); + + if (main_evm > aux_evm + ANTDIV_EVM_DIFF_TH) + candidate = RF_A; + else if (aux_evm > main_evm + ANTDIV_EVM_DIFF_TH) + candidate = RF_B; + else if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH) + candidate = RF_A; + else if (aux_rssi > main_rssi + RTW89_TX_DIV_RSSI_RAW_TH) + candidate = RF_B; + else + no_change = true; + + if (no_change) { + /* swap back from training antenna to original */ + rtw89_phy_swap_hal_antenna(rtwdev); + return; + } + + hal->antenna_tx = candidate; + hal->antenna_rx = candidate; +} + +static void rtw89_phy_antdiv_training_state(struct rtw89_dev *rtwdev) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + u64 state_period; + + if (antdiv->training_count % 2 == 0) { + if (antdiv->training_count == 0) + rtw89_phy_antdiv_sts_reset(rtwdev); + + antdiv->get_stats = true; + state_period = msecs_to_jiffies(ANTDIV_TRAINNING_INTVL); + } else { + antdiv->get_stats = false; + state_period = msecs_to_jiffies(ANTDIV_DELAY); + + rtw89_phy_swap_hal_antenna(rtwdev); + rtw89_phy_antdiv_set_ant(rtwdev); + } + + antdiv->training_count++; + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, + state_period); +} + +void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + antdiv_work.work); + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + + lockdep_assert_wiphy(wiphy); + + if (antdiv->training_count <= ANTDIV_TRAINNING_CNT) { + rtw89_phy_antdiv_training_state(rtwdev); + } else { + rtw89_phy_antdiv_decision_state(rtwdev); + rtw89_phy_antdiv_set_ant(rtwdev); + } +} + +void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; + struct rtw89_hal *hal = &rtwdev->hal; + u8 rssi, rssi_pre; + + if (!hal->ant_diversity || hal->ant_diversity_fixed) + return; + + rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->target_stats); + rssi_pre = antdiv->rssi_pre; + antdiv->rssi_pre = rssi; + rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats); + + if (abs((int)rssi - (int)rssi_pre) < ANTDIV_RSSI_DIFF_TH) + return; + + antdiv->training_count = 0; + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, 0); +} + +static void __rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "BB-%d env_monitor init\n", bb->phy_idx); + + rtw89_phy_ccx_top_setting_init(rtwdev, bb); + rtw89_phy_ifs_clm_setting_init(rtwdev, bb); +} + +static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_env_monitor_init(rtwdev, bb); +} + +static void rtw89_phy_diag_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + memset(&bb->diag, 0, sizeof(bb->diag)); +} + +static void __rtw89_phy_edcca_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca init\n", bb->phy_idx); + + memset(edcca_bak, 0, sizeof(*edcca_bak)); + + if (rtwdev->chip->chip_id == RTL8922A && rtwdev->hal.cv == CHIP_CAV) { + rtw89_phy_set_phy_regs(rtwdev, R_TXGATING, B_TXGATING_EN, 0); + rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_VAL, 2); + rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_ON, 1); + rtw89_phy_set_phy_regs(rtwdev, R_SPOOF_CG, B_SPOOF_CG_EN, 0); + rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_CG_EN, 0); + rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 0); + rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 0); + rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 1); + rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 1); + } + + rtw89_phy_write32_idx(rtwdev, edcca_regs->tx_collision_t2r_st, + edcca_regs->tx_collision_t2r_st_mask, 0x29, bb->phy_idx); +} + +static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_edcca_init(rtwdev, bb); +} + +void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) +{ + rtw89_phy_stat_init(rtwdev); + + rtw89_chip_bb_sethw(rtwdev); + + rtw89_phy_diag_init(rtwdev); + rtw89_phy_env_monitor_init(rtwdev); + rtw89_phy_nhm_setting_init(rtwdev); + rtw89_physts_parsing_init(rtwdev); + rtw89_phy_dig_init(rtwdev); + rtw89_phy_cfo_init(rtwdev); + rtw89_phy_bb_wrap_init(rtwdev); + rtw89_phy_edcca_init(rtwdev); + rtw89_phy_ch_info_init(rtwdev); + rtw89_phy_ul_tb_info_init(rtwdev); + rtw89_phy_antdiv_init(rtwdev); + rtw89_chip_rfe_gpio(rtwdev); + rtw89_phy_antdiv_set_ant(rtwdev); + + rtw89_chip_rfk_hw_init(rtwdev); + rtw89_phy_init_rf_nctl(rtwdev); + rtw89_chip_rfk_init(rtwdev); + rtw89_chip_set_txpwr_ctrl(rtwdev); + rtw89_chip_power_trim(rtwdev); + rtw89_chip_cfg_txrx_path(rtwdev); +} + +void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev) +{ + rtw89_phy_env_monitor_init(rtwdev); + rtw89_physts_parsing_init(rtwdev); +} + +static void __rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + struct rtw89_env_monitor_info *env = &bb->env_monitor; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_supported_band *sband; + enum rtw89_band hw_band; + enum nl80211_band band; + u8 idx; + + if (!chip->support_noise) + return; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + sband = rtwdev->hw->wiphy->bands[band]; + if (!sband) + continue; + + hw_band = rtw89_nl80211_to_hw_band(band); + env->nhm_his[hw_band] = + devm_kcalloc(rtwdev->dev, sband->n_channels, + sizeof(*env->nhm_his[0]), GFP_KERNEL); + + for (idx = 0; idx < sband->n_channels; idx++) + INIT_LIST_HEAD(&env->nhm_his[hw_band][idx].list); + + INIT_LIST_HEAD(&env->nhm_rpt_list); + } +} + +void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_dm_init_data(rtwdev, bb); +} + +void __rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, u8 bss_color, u16 aid, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld; + + rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_TGT, + bss_color, phy_idx); + rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_STAID, + aid, phy_idx); +} + +void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + struct ieee80211_bss_conf *bss_conf; + u8 bss_color; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->he_support || !vif->cfg.assoc) { + rcu_read_unlock(); + return; + } + + bss_color = bss_conf->he_bss_color.color; + + rcu_read_unlock(); + + __rtw89_phy_set_bss_color(rtwdev, bss_color, vif->cfg.aid, phy_idx); +} + +static bool rfk_chan_validate_desc(const struct rtw89_rfk_chan_desc *desc) +{ + return desc->ch != 0; +} + +static bool rfk_chan_is_equivalent(const struct rtw89_rfk_chan_desc *desc, + const struct rtw89_chan *chan) +{ + if (!rfk_chan_validate_desc(desc)) + return false; + + if (desc->ch != chan->channel) + return false; + + if (desc->has_band && desc->band != chan->band_type) + return false; + + if (desc->has_bw && desc->bw != chan->band_width) + return false; + + return true; +} + +struct rfk_chan_iter_data { + const struct rtw89_rfk_chan_desc desc; + unsigned int found; +}; + +static int rfk_chan_iter_search(const struct rtw89_chan *chan, void *data) +{ + struct rfk_chan_iter_data *iter_data = data; + + if (rfk_chan_is_equivalent(&iter_data->desc, chan)) + iter_data->found++; + + return 0; +} + +u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev, + const struct rtw89_rfk_chan_desc *desc, u8 desc_nr, + const struct rtw89_chan *target_chan) +{ + int sel = -1; + u8 i; + + for (i = 0; i < desc_nr; i++) { + struct rfk_chan_iter_data iter_data = { + .desc = desc[i], + }; + + if (rfk_chan_is_equivalent(&desc[i], target_chan)) + return i; + + rtw89_iterate_entity_chan(rtwdev, rfk_chan_iter_search, &iter_data); + if (!iter_data.found && sel == -1) + sel = i; + } + + if (sel == -1) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "no idle rfk entry; force replace the first\n"); + sel = 0; + } + + return sel; +} +EXPORT_SYMBOL(rtw89_rfk_chan_lookup); + +static void +_rfk_write_rf(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) +{ + rtw89_write_rf(rtwdev, def->path, def->addr, def->mask, def->data); +} + +static void +_rfk_write32_mask(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) +{ + rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); +} + +static void +_rfk_write32_set(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) +{ + rtw89_phy_write32_set(rtwdev, def->addr, def->mask); +} + +static void +_rfk_write32_clr(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) +{ + rtw89_phy_write32_clr(rtwdev, def->addr, def->mask); +} + +static void +_rfk_delay(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) +{ + udelay(def->data); +} + +static void +(*_rfk_handler[])(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) = { + [RTW89_RFK_F_WRF] = _rfk_write_rf, + [RTW89_RFK_F_WM] = _rfk_write32_mask, + [RTW89_RFK_F_WS] = _rfk_write32_set, + [RTW89_RFK_F_WC] = _rfk_write32_clr, + [RTW89_RFK_F_DELAY] = _rfk_delay, +}; + +static_assert(ARRAY_SIZE(_rfk_handler) == RTW89_RFK_F_NUM); + +void +rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl) +{ + const struct rtw89_reg5_def *p = tbl->defs; + const struct rtw89_reg5_def *end = tbl->defs + tbl->size; + + for (; p < end; p++) + _rfk_handler[p->flag](rtwdev, p); +} +EXPORT_SYMBOL(rtw89_rfk_parser); + +#define RTW89_TSSI_FAST_MODE_NUM 4 + +static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_flat[RTW89_TSSI_FAST_MODE_NUM] = { + {0xD934, 0xff0000}, + {0xD934, 0xff000000}, + {0xD938, 0xff}, + {0xD934, 0xff00}, +}; + +static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_level[RTW89_TSSI_FAST_MODE_NUM] = { + {0xD930, 0xff0000}, + {0xD930, 0xff000000}, + {0xD934, 0xff}, + {0xD930, 0xff00}, +}; + +static +void rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg, + u32 val) +{ + const struct rtw89_reg_def *regs; + u32 reg; + int i; + + if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT) + regs = rtw89_tssi_fastmode_regs_flat; + else + regs = rtw89_tssi_fastmode_regs_level; + + for (i = 0; i < RTW89_TSSI_FAST_MODE_NUM; i++) { + reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, regs[i].mask, val); + } +} + +static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_flat[RTW89_TSSI_SBW_NUM] = { + {0xD91C, 0xff000000}, + {0xD920, 0xff}, + {0xD920, 0xff00}, + {0xD920, 0xff0000}, + {0xD920, 0xff000000}, + {0xD924, 0xff}, + {0xD924, 0xff00}, + {0xD914, 0xff000000}, + {0xD918, 0xff}, + {0xD918, 0xff00}, + {0xD918, 0xff0000}, + {0xD918, 0xff000000}, + {0xD91C, 0xff}, + {0xD91C, 0xff00}, + {0xD91C, 0xff0000}, +}; + +static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_level[RTW89_TSSI_SBW_NUM] = { + {0xD910, 0xff}, + {0xD910, 0xff00}, + {0xD910, 0xff0000}, + {0xD910, 0xff000000}, + {0xD914, 0xff}, + {0xD914, 0xff00}, + {0xD914, 0xff0000}, + {0xD908, 0xff}, + {0xD908, 0xff00}, + {0xD908, 0xff0000}, + {0xD908, 0xff000000}, + {0xD90C, 0xff}, + {0xD90C, 0xff00}, + {0xD90C, 0xff0000}, + {0xD90C, 0xff000000}, +}; + +void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_reg_def *regs; + const u32 *data; + u32 reg; + int i; + + if (bandedge_cfg >= RTW89_TSSI_CFG_NUM) + return; + + if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT) + regs = rtw89_tssi_bandedge_regs_flat; + else + regs = rtw89_tssi_bandedge_regs_level; + + data = chip->tssi_dbw_table->data[bandedge_cfg]; + + for (i = 0; i < RTW89_TSSI_SBW_NUM; i++) { + reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, regs[i].mask, data[i]); + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BANDEDGE_CFG, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_BANDEDGE_CFG_IDX_MASK, bandedge_cfg); + + rtw89_phy_tssi_ctrl_set_fast_mode_cfg(rtwdev, mac_idx, bandedge_cfg, + data[RTW89_TSSI_SBW20]); +} +EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg); + +static +const u8 rtw89_ch_base_table[16] = {1, 0xff, + 36, 100, 132, 149, 0xff, + 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; +#define RTW89_CH_BASE_IDX_2G 0 +#define RTW89_CH_BASE_IDX_5G_FIRST 2 +#define RTW89_CH_BASE_IDX_5G_LAST 5 +#define RTW89_CH_BASE_IDX_6G_FIRST 7 +#define RTW89_CH_BASE_IDX_6G_LAST 14 + +#define RTW89_CH_BASE_IDX_MASK GENMASK(7, 4) +#define RTW89_CH_OFFSET_MASK GENMASK(3, 0) + +u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) +{ + u8 chan_idx; + u8 last, first; + u8 idx; + + switch (band) { + case RTW89_BAND_2G: + chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, RTW89_CH_BASE_IDX_2G) | + FIELD_PREP(RTW89_CH_OFFSET_MASK, central_ch); + return chan_idx; + case RTW89_BAND_5G: + first = RTW89_CH_BASE_IDX_5G_FIRST; + last = RTW89_CH_BASE_IDX_5G_LAST; + break; + case RTW89_BAND_6G: + first = RTW89_CH_BASE_IDX_6G_FIRST; + last = RTW89_CH_BASE_IDX_6G_LAST; + break; + default: + rtw89_warn(rtwdev, "Unsupported band %d\n", band); + return 0; + } + + for (idx = last; idx >= first; idx--) + if (central_ch >= rtw89_ch_base_table[idx]) + break; + + if (idx < first) { + rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); + return 0; + } + + chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, idx) | + FIELD_PREP(RTW89_CH_OFFSET_MASK, + (central_ch - rtw89_ch_base_table[idx]) >> 1); + return chan_idx; +} +EXPORT_SYMBOL(rtw89_encode_chan_idx); + +void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, + u8 *ch, enum nl80211_band *band) +{ + u8 idx, offset; + + idx = FIELD_GET(RTW89_CH_BASE_IDX_MASK, chan_idx); + offset = FIELD_GET(RTW89_CH_OFFSET_MASK, chan_idx); + + if (idx == RTW89_CH_BASE_IDX_2G) { + *band = NL80211_BAND_2GHZ; + *ch = offset; + return; + } + + *band = idx <= RTW89_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; + *ch = rtw89_ch_base_table[idx] + (offset << 1); +} +EXPORT_SYMBOL(rtw89_decode_chan_idx); + +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool scan) +{ + const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; + + if (scan) { + edcca_bak->a = + rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, bb->phy_idx); + edcca_bak->p = + rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, bb->phy_idx); + edcca_bak->ppdu = + rtw89_phy_read32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, bb->phy_idx); + + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, EDCCA_MAX, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, EDCCA_MAX, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, EDCCA_MAX, bb->phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, + edcca_bak->a, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, + edcca_bak->p, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, + edcca_bak->ppdu, bb->phy_idx); + } +} + +static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; + const struct rtw89_edcca_p_regs *edcca_p_regs; + bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80; + s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80; + u8 path, per20_bitmap = 0; + u8 pwdb_sel = 5; + u8 pwdb[8]; + u32 tmp; + + if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_EDCCA)) + return; + + if (bb->phy_idx == RTW89_PHY_1) + edcca_p_regs = &edcca_regs->p[RTW89_PHY_1]; + else + edcca_p_regs = &edcca_regs->p[RTW89_PHY_0]; + + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 0); + if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) { + rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, + edcca_regs->rpt_sel_be_mask, 0); + per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, + MASKBYTE0); + } + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); + path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK); + flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80); + flag_s40 = u32_get_bits(tmp, B_EDCCA_RPT_B_S40); + flag_s20 = u32_get_bits(tmp, B_EDCCA_RPT_B_S20); + flag_p20 = u32_get_bits(tmp, B_EDCCA_RPT_B_P20); + flag_fb = u32_get_bits(tmp, B_EDCCA_RPT_B_FB); + pwdb_s20 = u32_get_bits(tmp, MASKBYTE1); + pwdb_p20 = u32_get_bits(tmp, MASKBYTE2); + pwdb_fb = u32_get_bits(tmp, MASKBYTE3); + + if (rtwdev->chip->chip_id == RTL8922D) + pwdb_sel = 2; + + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, pwdb_sel); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); + pwdb_s80 = u32_get_bits(tmp, MASKBYTE1); + pwdb_s40 = u32_get_bits(tmp, MASKBYTE2); + + if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) { + rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, + edcca_regs->rpt_sel_be_mask, 4); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); + pwdb[0] = u32_get_bits(tmp, MASKBYTE3); + pwdb[1] = u32_get_bits(tmp, MASKBYTE2); + pwdb[2] = u32_get_bits(tmp, MASKBYTE1); + pwdb[3] = u32_get_bits(tmp, MASKBYTE0); + + rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, + edcca_regs->rpt_sel_be_mask, 5); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); + pwdb[4] = u32_get_bits(tmp, MASKBYTE3); + pwdb[5] = u32_get_bits(tmp, MASKBYTE2); + pwdb[6] = u32_get_bits(tmp, MASKBYTE1); + pwdb[7] = u32_get_bits(tmp, MASKBYTE0); + } else { + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 0); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); + pwdb[0] = u32_get_bits(tmp, MASKBYTE3); + pwdb[1] = u32_get_bits(tmp, MASKBYTE2); + + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 5); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); + pwdb[2] = u32_get_bits(tmp, MASKBYTE3); + pwdb[3] = u32_get_bits(tmp, MASKBYTE2); + + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 2); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); + pwdb[4] = u32_get_bits(tmp, MASKBYTE3); + pwdb[5] = u32_get_bits(tmp, MASKBYTE2); + + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 3); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); + pwdb[6] = u32_get_bits(tmp, MASKBYTE3); + pwdb[7] = u32_get_bits(tmp, MASKBYTE2); + } + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, + "[EDCCA]: edcca_bitmap = %04x\n", per20_bitmap); + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, + "[EDCCA]: pwdb per20{0,1,2,3,4,5,6,7} = {%d,%d,%d,%d,%d,%d,%d,%d}(dBm)\n", + pwdb[0], pwdb[1], pwdb[2], pwdb[3], pwdb[4], pwdb[5], + pwdb[6], pwdb[7]); + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, + "[EDCCA]: path=%d, flag {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}\n", + path, flag_fb, flag_p20, flag_s20, flag_s40, flag_s80); + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, + "[EDCCA]: pwdb {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}(dBm)\n", + pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80); +} + +static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + struct rtw89_phy_ch_info *ch_info = &bb->ch_info; + bool is_linked = rtwdev->total_sta_assoc > 0; + u8 rssi_min = ch_info->rssi_min >> 1; + u8 edcca_thre; + + if (!is_linked) { + edcca_thre = EDCCA_MAX; + } else { + edcca_thre = rssi_min - RSSI_UNIT_CONVER + EDCCA_UNIT_CONVER - + EDCCA_TH_REF; + edcca_thre = max_t(u8, edcca_thre, EDCCA_TH_L2H_LB); + } + + return edcca_thre; +} + +void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; + u8 th; + + th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev, bb); + if (th == edcca_bak->th_old) + return; + + edcca_bak->th_old = th; + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, + "[EDCCA]: Normal Mode, EDCCA_th = %d\n", th); + + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, th, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, th, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, th, bb->phy_idx); +} + +static void rtw89_phy_edcca_diag(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ +#define RTW89_DIAG_BB_EDCCA_RATIO_TH 50 +#define RTW89_DIAG_BB_EDCCA_TX_TH 10 + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_traffic_stats *stats = &rtwdev->stats; + struct rtw89_diag_bb *diag = &bb->diag; + + diag->diag_bb_bitmap &= ~BIT(RTW89_DIAG_BB_EDCCA); + + if (stats->tx_throughput <= RTW89_DIAG_BB_EDCCA_TX_TH || + env->edcca_clm_ratio <= RTW89_DIAG_BB_EDCCA_RATIO_TH) + return; + + diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_EDCCA); + diag->diag_bb_cnt[RTW89_DIAG_BB_EDCCA]++; +} + +static +void __rtw89_phy_edcca_track(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca track\n", bb->phy_idx); + + rtw89_phy_edcca_thre_calc(rtwdev, bb); + rtw89_phy_edcca_log(rtwdev, bb); + rtw89_phy_edcca_diag(rtwdev, bb); +} + +void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_bb_ctx *bb; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DYNAMIC_EDCCA)) + return; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_edcca_track(rtwdev, bb); +} + +enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] kpath dbcc_en: 0x%x, mode=0x%x, PHY%d\n", + rtwdev->dbcc_en, rtwdev->mlo_dbcc_mode, phy_idx); + + switch (rtwdev->mlo_dbcc_mode) { + case MLO_1_PLUS_1_1RF: + if (phy_idx == RTW89_PHY_0) + return RF_A; + else + return RF_B; + case MLO_1_PLUS_1_2RF: + if (phy_idx == RTW89_PHY_0) + return RF_A; + else + return RF_D; + case MLO_0_PLUS_2_1RF: + case MLO_2_PLUS_0_1RF: + /* for both PHY 0/1 */ + return RF_AB; + case MLO_0_PLUS_2_2RF: + case MLO_2_PLUS_0_2RF: + case MLO_2_PLUS_2_2RF: + default: + if (phy_idx == RTW89_PHY_0) + return RF_AB; + else + return RF_CD; + } +} +EXPORT_SYMBOL(rtw89_phy_get_kpath); + +enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] kpath dbcc_en: 0x%x, mode=0x%x, PHY%d\n", + rtwdev->dbcc_en, rtwdev->mlo_dbcc_mode, phy_idx); + + switch (rtwdev->mlo_dbcc_mode) { + case MLO_1_PLUS_1_1RF: + if (phy_idx == RTW89_PHY_0) + return RF_PATH_A; + else + return RF_PATH_B; + case MLO_1_PLUS_1_2RF: + if (phy_idx == RTW89_PHY_0) + return RF_PATH_A; + else + return RF_PATH_D; + case MLO_0_PLUS_2_1RF: + case MLO_2_PLUS_0_1RF: + if (phy_idx == RTW89_PHY_0) + return RF_PATH_A; + else + return RF_PATH_B; + case MLO_0_PLUS_2_2RF: + case MLO_2_PLUS_0_2RF: + case MLO_2_PLUS_2_2RF: + default: + if (phy_idx == RTW89_PHY_0) + return RF_PATH_A; + else + return RF_PATH_C; + } +} +EXPORT_SYMBOL(rtw89_phy_get_syn_sel); + +static const struct rtw89_ccx_regs rtw89_ccx_regs_ax = { + .setting_addr = R_CCX, + .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK, + .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK, + .trig_opt_mask = B_CCX_TRIG_OPT_MSK, + .en_mask = B_CCX_EN_MSK, + .ifs_cnt_addr = R_IFS_COUNTER, + .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK, + .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK, + .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK, + .ifs_collect_en_mask = B_IFS_COLLECT_EN, + .ifs_t1_addr = R_IFS_T1, + .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK, + .ifs_t1_en_mask = B_IFS_T1_EN_MSK, + .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK, + .ifs_t2_addr = R_IFS_T2, + .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK, + .ifs_t2_en_mask = B_IFS_T2_EN_MSK, + .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK, + .ifs_t3_addr = R_IFS_T3, + .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK, + .ifs_t3_en_mask = B_IFS_T3_EN_MSK, + .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK, + .ifs_t4_addr = R_IFS_T4, + .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK, + .ifs_t4_en_mask = B_IFS_T4_EN_MSK, + .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK, + .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT, + .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK, + .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK, + .ifs_clm_cca_addr = R_IFS_CLM_CCA, + .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK, + .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK, + .ifs_clm_fa_addr = R_IFS_CLM_FA, + .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, + .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, + .ifs_his_addr = R_IFS_HIS, + .ifs_his_addr2 = R_IFS_HIS, + .ifs_t4_his_mask = B_IFS_T4_HIS_MSK, + .ifs_t3_his_mask = B_IFS_T3_HIS_MSK, + .ifs_t2_his_mask = B_IFS_T2_HIS_MSK, + .ifs_t1_his_mask = B_IFS_T1_HIS_MSK, + .ifs_avg_l_addr = R_IFS_AVG_L, + .ifs_t2_avg_mask = B_IFS_T2_AVG_MSK, + .ifs_t1_avg_mask = B_IFS_T1_AVG_MSK, + .ifs_avg_h_addr = R_IFS_AVG_H, + .ifs_t4_avg_mask = B_IFS_T4_AVG_MSK, + .ifs_t3_avg_mask = B_IFS_T3_AVG_MSK, + .ifs_cca_l_addr = R_IFS_CCA_L, + .ifs_t2_cca_mask = B_IFS_T2_CCA_MSK, + .ifs_t1_cca_mask = B_IFS_T1_CCA_MSK, + .ifs_cca_h_addr = R_IFS_CCA_H, + .ifs_t4_cca_mask = B_IFS_T4_CCA_MSK, + .ifs_t3_cca_mask = B_IFS_T3_CCA_MSK, + .ifs_total_addr = R_IFSCNT, + .ifs_cnt_done_mask = B_IFSCNT_DONE_MSK, + .ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK, + .nhm = R_NHM_AX, + .nhm_ready = B_NHM_READY_MSK, + .nhm_config = R_NHM_CFG, + .nhm_period_mask = B_NHM_PERIOD_MSK, + .nhm_unit_mask = B_NHM_COUNTER_MSK, + .nhm_include_cca_mask = B_NHM_INCLUDE_CCA_MSK, + .nhm_en_mask = B_NHM_EN_MSK, + .nhm_method = R_NHM_TH9, + .nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK, + .edcca_clm_rdy = R_CLM_EDCCA_RDY, + .edcca_clm_rdy_mask = B_CLM_EDCCA_RDY, + .edcca_clm_cnt = R_CLM_EDCCA_RESULT, + .edcca_clm_cnt_mask = B_CLM_EDCCA_RESULT, +}; + +static const u32 rtw89_txinfo_reg_ax[] = { + R_TX_INFO_0_0_COMB, + R_TX_INFO_0_1_COMB, + R_TX_INFO_1_0_COMB, + R_TX_INFO_1_1_COMB +}; + +static const u32 rtw89_tx_common_ctrl_reg_ax[] = { + R_TX_COMMON_CTRL_0_0_COMB, + R_TX_COMMON_CTRL_0_1_COMB +}; + +static const struct rtw89_reg_def rtw89_txpwr_ax[] = { + {.addr = R_PATH0_TXPWR, .mask = B_PATH0_TXPWR}, + {.addr = R_PATH1_TXPWR, .mask = B_PATH1_TXPWR} +}; + +static const struct rtw89_physts_regs rtw89_physts_regs_ax = { + .setting_addr = R_PLCP_HISTOGRAM, + .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL, + .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK, + .mac_phy_intf_sel = {R_INTF_R_INTF_RPT_SEL, B_INTF_R_INTF_RPT_SEL}, + .txpwr = rtw89_txpwr_ax, + .tx_info = RTW89_REGS_DEF(rtw89_txinfo_reg_ax), + .tx_common_ctrl = RTW89_REGS_DEF(rtw89_tx_common_ctrl_reg_ax), +}; + +static const struct rtw89_cfo_regs rtw89_cfo_regs_ax = { + .comp = R_DCFO_WEIGHT, + .weighting_mask = B_DCFO_WEIGHT_MSK, + .comp_seg0 = R_DCFO_OPT, + .valid_0_mask = B_DCFO_OPT_EN, +}; + +const struct rtw89_phy_gen_def rtw89_phy_gen_ax = { + .cr_base = 0x10000, + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START, + .physt_bmp_eht = 0xfc, + .physt_ie_len = {16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, + VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, + VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32}, + .physt_gen = 0, + .ccx = &rtw89_ccx_regs_ax, + .physts = &rtw89_physts_regs_ax, + .cfo = &rtw89_cfo_regs_ax, + .bb_wrap = NULL, + .nctl = NULL, + .phy0_phy1_offset = rtw89_phy0_phy1_offset_ax, + .config_bb_gain = rtw89_phy_config_bb_gain_ax, + .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_ax, + .bb_wrap_init = NULL, + .ch_info_init = NULL, + + .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_ax, + .set_txpwr_offset = rtw89_phy_set_txpwr_offset_ax, + .set_txpwr_limit = rtw89_phy_set_txpwr_limit_ax, + .set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_ax, +}; +EXPORT_SYMBOL(rtw89_phy_gen_ax); diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h new file mode 100644 index 000000000..0963cdfb1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -0,0 +1,1245 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_PHY_H__ +#define __RTW89_PHY_H__ + +#include "core.h" + +#define RTW89_BBMCU_ADDR_OFFSET 0x30000 +#define RTW89_RF_ADDR_ADSEL_MASK BIT(16) + +#define get_phy_headline(addr) FIELD_GET(GENMASK(31, 28), addr) +#define PHY_HEADLINE_VALID 0xf +#define get_phy_target(addr) FIELD_GET(GENMASK(27, 0), addr) +#define get_phy_compare(rfe, cv) (FIELD_PREP(GENMASK(23, 16), rfe) | \ + FIELD_PREP(GENMASK(7, 0), cv)) + +#define get_phy_cond(addr) FIELD_GET(GENMASK(31, 28), addr) +#define get_phy_cond_rfe(addr) FIELD_GET(GENMASK(23, 16), addr) +#define get_phy_cond_pkg(addr) FIELD_GET(GENMASK(15, 8), addr) +#define get_phy_cond_cv(addr) FIELD_GET(GENMASK(7, 0), addr) +#define phy_div(a, b) ({typeof(b) _b = (b); (_b) ? ((a) / (_b)) : 0; }) +#define PHY_COND_BRANCH_IF 0x8 +#define PHY_COND_BRANCH_ELIF 0x9 +#define PHY_COND_BRANCH_ELSE 0xa +#define PHY_COND_BRANCH_END 0xb +#define PHY_COND_CHECK 0x4 +#define PHY_COND_DONT_CARE 0xff + +#define RA_MASK_CCK_RATES GENMASK_ULL(3, 0) +#define RA_MASK_OFDM_RATES GENMASK_ULL(11, 4) +#define RA_MASK_SUBCCK_RATES 0x5ULL +#define RA_MASK_SUBOFDM_RATES 0x10ULL +#define RA_MASK_HT_1SS_RATES GENMASK_ULL(19, 12) +#define RA_MASK_HT_2SS_RATES GENMASK_ULL(31, 24) +#define RA_MASK_HT_3SS_RATES GENMASK_ULL(43, 36) +#define RA_MASK_HT_4SS_RATES GENMASK_ULL(55, 48) +#define RA_MASK_HT_RATES GENMASK_ULL(55, 12) +#define RA_MASK_VHT_1SS_RATES GENMASK_ULL(21, 12) +#define RA_MASK_VHT_2SS_RATES GENMASK_ULL(33, 24) +#define RA_MASK_VHT_3SS_RATES GENMASK_ULL(45, 36) +#define RA_MASK_VHT_4SS_RATES GENMASK_ULL(57, 48) +#define RA_MASK_VHT_RATES GENMASK_ULL(57, 12) +#define RA_MASK_HE_1SS_RATES GENMASK_ULL(23, 12) +#define RA_MASK_HE_2SS_RATES GENMASK_ULL(35, 24) +#define RA_MASK_HE_3SS_RATES GENMASK_ULL(47, 36) +#define RA_MASK_HE_4SS_RATES GENMASK_ULL(59, 48) +#define RA_MASK_HE_RATES GENMASK_ULL(59, 12) +#define RA_MASK_EHT_1SS_RATES GENMASK_ULL(27, 12) +#define RA_MASK_EHT_2SS_RATES GENMASK_ULL(43, 28) +#define RA_MASK_EHT_3SS_RATES GENMASK_ULL(59, 44) +#define RA_MASK_EHT_4SS_RATES GENMASK_ULL(62, 60) +#define RA_MASK_EHT_1SS_MCS0_11 GENMASK_ULL(23, 12) +#define RA_MASK_EHT_2SS_MCS0_11 GENMASK_ULL(39, 28) +#define RA_MASK_EHT_3SS_MCS0_11 GENMASK_ULL(55, 44) +#define RA_MASK_EHT_4SS_MCS0_11 GENMASK_ULL(62, 60) +#define RA_MASK_EHT_RATES GENMASK_ULL(62, 12) + +#define TX_STATUS_TYPE GENMASK(3, 0) +#define TX_STATUS_SUBTYPE GENMASK(7, 4) +#define TX_STATUS_TXCMD GENMASK(29, 24) +#define TX_STATUS_TXCMD_V1 GENMASK(13, 8) +#define TX_STATUS_TXCMD_V2 GENMASK(15, 8) +#define TX_STATUS_TXSC GENMASK(7, 4) +#define TX_STATUS_TXSC_V1 GENMASK(27, 24) +#define TX_STATUS_BW GENMASK(17, 16) +#define TX_STATUS_BW_V1 GENMASK(6, 4) +#define TX_STATUS_TMAC_TXPWR GENMASK(26, 18) +#define TX_STATUS_TMAC_TXPWR_V1 GENMASK(16, 8) +#define TX_STATUS_TX_PATH_EN GENMASK(15, 12) +#define TX_STATUS_TX_PATH_EN_V1 GENMASK(7, 4) +#define TX_STATUS_PATH_MAP GENMASK(23, 16) +#define TX_STATUS_PATH_MAP_V1 GENMASK(15, 8) +#define TX_STATUS_MAX_MCS GENMASK(7, 4) +#define TX_STATUS_MAX_MCS_V1 GENMASK(3, 0) +#define TX_STATUS_STBC BIT(0) + +#define CFO_TRK_ENABLE_TH (2 << 2) +#define CFO_TRK_STOP_TH_4 (30 << 2) +#define CFO_TRK_STOP_TH_3 (20 << 2) +#define CFO_TRK_STOP_TH_2 (10 << 2) +#define CFO_TRK_STOP_TH_1 (03 << 2) +#define CFO_TRK_STOP_TH (2 << 2) +#define CFO_SW_COMP_FINE_TUNE (2 << 2) +#define CFO_PERIOD_CNT 15 +#define CFO_BOUND 64 +#define CFO_TP_UPPER 100 +#define CFO_TP_LOWER 50 +#define CFO_COMP_PERIOD 250 +#define CFO_COMP_WEIGHT 8 +#define MAX_CFO_TOLERANCE 30 +#define CFO_TF_CNT_TH 300 + +#define UL_TB_TF_CNT_L2H_TH 100 +#define UL_TB_TF_CNT_H2L_TH 70 + +#define ANTDIV_TRAINNING_CNT 2 +#define ANTDIV_TRAINNING_INTVL 30 +#define ANTDIV_DELAY 110 +#define ANTDIV_TP_DIFF_TH_HIGH 100 +#define ANTDIV_TP_DIFF_TH_LOW 5 +#define ANTDIV_EVM_DIFF_TH 8 +#define ANTDIV_RSSI_DIFF_TH 3 + +#define CCX_MAX_PERIOD 2097 +#define CCX_MAX_PERIOD_UNIT 32 +#define MS_TO_4US_RATIO 250 +#define ENV_MNTR_FAIL_DWORD 0xffffffff +#define ENV_MNTR_IFSCLM_HIS_MAX 127 +#define PERMIL 1000 +#define PERCENT 100 +#define IFS_CLM_TH0_UPPER 64 +#define IFS_CLM_TH_MUL 4 +#define IFS_CLM_TH_START_IDX 0 + +#define TIA0_GAIN_A 12 +#define TIA0_GAIN_G 16 +#define LNA0_GAIN (-24) +#define U4_MAX_BIT 3 +#define U8_MAX_BIT 7 +#define DIG_GAIN_SHIFT 2 +#define DIG_GAIN 8 + +#define LNA_IDX_MAX 6 +#define LNA_IDX_MIN 0 +#define TIA_IDX_MAX 1 +#define TIA_IDX_MIN 0 +#define RXB_IDX_MAX 31 +#define RXB_IDX_MIN 0 + +#define IGI_RSSI_MAX 110 +#define PD_TH_MAX_RSSI 70 +#define PD_TH_MIN_RSSI 8 +#define CCKPD_TH_MIN_RSSI (-18) +#define PD_TH_BW160_CMP_VAL 9 +#define PD_TH_BW80_CMP_VAL 6 +#define PD_TH_BW40_CMP_VAL 3 +#define PD_TH_BW20_CMP_VAL 0 +#define PD_TH_CMP_VAL 3 +#define PD_TH_SB_FLTR_CMP_VAL 7 + +#define PHYSTS_MGNT BIT(RTW89_RX_TYPE_MGNT) +#define PHYSTS_CTRL BIT(RTW89_RX_TYPE_CTRL) +#define PHYSTS_DATA BIT(RTW89_RX_TYPE_DATA) +#define PHYSTS_RSVD BIT(RTW89_RX_TYPE_RSVD) +#define PPDU_FILTER_BITMAP (PHYSTS_MGNT | PHYSTS_DATA) + +#define EDCCA_MAX 249 +#define EDCCA_TH_L2H_LB 66 +#define EDCCA_TH_REF 3 +#define EDCCA_HL_DIFF_NORMAL 8 +#define RSSI_UNIT_CONVER 110 +#define EDCCA_UNIT_CONVER 128 +#define EDCCA_PWROFST_DEFAULT 18 + +#define VAR_LEN 0xff +#define VAR_LEN_UNIT 8 + +enum rtw89_phy_c2h_ra_func { + RTW89_PHY_C2H_FUNC_STS_RPT, + RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT, + RTW89_PHY_C2H_FUNC_TXSTS, + RTW89_PHY_C2H_FUNC_TX_HISTORY = 0x4, + RTW89_PHY_C2H_FUNC_ACCELERATE_EN = 0x7, + + RTW89_PHY_C2H_FUNC_RA_NUM, +}; + +enum rtw89_phy_c2h_rfk_log_func { + RTW89_PHY_C2H_RFK_LOG_FUNC_IQK = 0, + RTW89_PHY_C2H_RFK_LOG_FUNC_DPK = 1, + RTW89_PHY_C2H_RFK_LOG_FUNC_DACK = 2, + RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK = 3, + RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI = 4, + RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK = 5, + RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR = 9, + RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK = 0xc, + RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K = 0xe, + + RTW89_PHY_C2H_RFK_LOG_FUNC_NUM, +}; + +enum rtw89_phy_c2h_rfk_report_func { + RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE = 0, + RTW89_PHY_C2H_RFK_REPORT_FUNC_TAS_PWR = 6, +}; + +enum rtw89_phy_c2h_dm_func { + RTW89_PHY_C2H_DM_FUNC_FW_TEST, + RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT, + RTW89_PHY_C2H_DM_FUNC_SIGB, + RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY, + RTW89_PHY_C2H_DM_FUNC_MCC_DIG, + RTW89_PHY_C2H_DM_FUNC_LPS = 0x9, + RTW89_PHY_C2H_DM_FUNC_ENV_MNTR = 0xa, + RTW89_PHY_C2H_DM_FUNC_FW_SCAN = 0xc, + RTW89_PHY_C2H_DM_FUNC_NUM, +}; + +enum rtw89_phy_c2h_class { + RTW89_PHY_C2H_CLASS_RUA, + RTW89_PHY_C2H_CLASS_RA, + RTW89_PHY_C2H_CLASS_DM, + RTW89_PHY_C2H_RFK_LOG = 0x8, + RTW89_PHY_C2H_RFK_REPORT = 0x9, + RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10, + RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17, + RTW89_PHY_C2H_CLASS_MAX, +}; + +enum rtw89_env_monitor_result_level { + RTW89_PHY_ENV_MON_CCX_FAIL = 0, + RTW89_PHY_ENV_MON_NHM = BIT(0), + RTW89_PHY_ENV_MON_CLM = BIT(1), + RTW89_PHY_ENV_MON_FAHM = BIT(2), + RTW89_PHY_ENV_MON_IFS_CLM = BIT(3), + RTW89_PHY_ENV_MON_EDCCA_CLM = BIT(4), +}; + +#define RTW89_NHM_WEIGHT_OFFSET 2 +#define RTW89_NHM_WA_TH (109 << 1) +#define RTW89_NOISE_DEFAULT -96 +#define RTW89_NHM_MNTR_TIME 40 +#define RTW89_NHM_TH_FACTOR 1 + +#define CCX_US_BASE_RATIO 4 +enum rtw89_ccx_unit { + RTW89_CCX_4_US = 0, + RTW89_CCX_8_US = 1, + RTW89_CCX_16_US = 2, + RTW89_CCX_32_US = 3 +}; + +enum rtw89_phy_status_ie_type { + RTW89_PHYSTS_IE00_CMN_CCK = 0, + RTW89_PHYSTS_IE01_CMN_OFDM = 1, + RTW89_PHYSTS_IE02_CMN_EXT_AX = 2, + RTW89_PHYSTS_IE03_CMN_EXT_SEG_1 = 3, + RTW89_PHYSTS_IE04_CMN_EXT_PATH_A = 4, + RTW89_PHYSTS_IE05_CMN_EXT_PATH_B = 5, + RTW89_PHYSTS_IE06_CMN_EXT_PATH_C = 6, + RTW89_PHYSTS_IE07_CMN_EXT_PATH_D = 7, + RTW89_PHYSTS_IE08_FTR_CH = 8, + RTW89_PHYSTS_IE09_FTR_0 = 9, + RTW89_PHYSTS_IE10_FTR_PLCP_EXT = 10, + RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM = 11, + RTW89_PHYSTS_IE12_MU_EIGEN_INFO = 12, + RTW89_PHYSTS_IE13_DL_MU_DEF = 13, + RTW89_PHYSTS_IE14_TB_UL_CQI = 14, + RTW89_PHYSTS_IE15_TB_UL_DEF = 15, + RTW89_PHYSTS_IE16_RSVD16 = 16, + RTW89_PHYSTS_IE17_TB_UL_CTRL = 17, + RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN = 18, + RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN = 19, + RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0 = 20, + RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1 = 21, + RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC = 22, + RTW89_PHYSTS_IE23_RSVD23 = 23, + RTW89_PHYSTS_IE24_OFDM_TD_PATH_A = 24, + RTW89_PHYSTS_IE25_OFDM_TD_PATH_B = 25, + RTW89_PHYSTS_IE26_OFDM_TD_PATH_C = 26, + RTW89_PHYSTS_IE27_OFDM_TD_PATH_D = 27, + RTW89_PHYSTS_IE28_DBG_CCK_PATH_A = 28, + RTW89_PHYSTS_IE29_DBG_CCK_PATH_B = 29, + RTW89_PHYSTS_IE30_DBG_CCK_PATH_C = 30, + RTW89_PHYSTS_IE31_DBG_CCK_PATH_D = 31, + + /* keep last */ + RTW89_PHYSTS_IE_NUM, + RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1 +}; + +enum rtw89_phy_status_bitmap { + RTW89_TD_SEARCH_FAIL = 0, + RTW89_BRK_BY_TX_PKT = 1, + RTW89_CCA_SPOOF = 2, + RTW89_OFDM_BRK = 3, + RTW89_CCK_BRK = 4, + RTW89_DL_MU_SPOOFING = 5, + RTW89_HE_MU = 6, + RTW89_VHT_MU = 7, + RTW89_UL_TB_SPOOFING = 8, + RTW89_RSVD_9 = 9, + RTW89_TRIG_BASE_PPDU = 10, + RTW89_CCK_PKT = 11, + RTW89_LEGACY_OFDM_PKT = 12, + RTW89_HT_PKT = 13, + RTW89_VHT_PKT = 14, + RTW89_HE_PKT = 15, + RTW89_EHT_PKT = 16, + + RTW89_PHYSTS_BITMAP_NUM +}; + +enum rtw89_dig_gain_type { + RTW89_DIG_GAIN_LNA_G = 0, + RTW89_DIG_GAIN_TIA_G = 1, + RTW89_DIG_GAIN_LNA_A = 2, + RTW89_DIG_GAIN_TIA_A = 3, + RTW89_DIG_GAIN_MAX = 4 +}; + +enum rtw89_dig_gain_lna_idx { + RTW89_DIG_GAIN_LNA_IDX1 = 1, + RTW89_DIG_GAIN_LNA_IDX2 = 2, + RTW89_DIG_GAIN_LNA_IDX3 = 3, + RTW89_DIG_GAIN_LNA_IDX4 = 4, + RTW89_DIG_GAIN_LNA_IDX5 = 5, + RTW89_DIG_GAIN_LNA_IDX6 = 6 +}; + +enum rtw89_dig_gain_tia_idx { + RTW89_DIG_GAIN_TIA_IDX0 = 0, + RTW89_DIG_GAIN_TIA_IDX1 = 1 +}; + +enum rtw89_tssi_bandedge_cfg { + RTW89_TSSI_BANDEDGE_FLAT, + RTW89_TSSI_BANDEDGE_LOW, + RTW89_TSSI_BANDEDGE_MID, + RTW89_TSSI_BANDEDGE_HIGH, + + RTW89_TSSI_CFG_NUM, +}; + +enum rtw89_tssi_sbw_idx { + RTW89_TSSI_SBW20, + RTW89_TSSI_SBW40_0, + RTW89_TSSI_SBW40_1, + RTW89_TSSI_SBW80_0, + RTW89_TSSI_SBW80_1, + RTW89_TSSI_SBW80_2, + RTW89_TSSI_SBW80_3, + RTW89_TSSI_SBW160_0, + RTW89_TSSI_SBW160_1, + RTW89_TSSI_SBW160_2, + RTW89_TSSI_SBW160_3, + RTW89_TSSI_SBW160_4, + RTW89_TSSI_SBW160_5, + RTW89_TSSI_SBW160_6, + RTW89_TSSI_SBW160_7, + + RTW89_TSSI_SBW_NUM, +}; + +struct rtw89_txpwr_byrate_cfg { + enum rtw89_band band; + enum rtw89_nss nss; + enum rtw89_rate_section rs; + u8 shf; + u8 len; + u32 data; +}; + +struct rtw89_phy_dig_gain_cfg { + const struct rtw89_reg_def *table; + u8 size; +}; + +struct rtw89_phy_dig_gain_table { + const struct rtw89_phy_dig_gain_cfg *cfg_lna_g; + const struct rtw89_phy_dig_gain_cfg *cfg_tia_g; + const struct rtw89_phy_dig_gain_cfg *cfg_lna_a; + const struct rtw89_phy_dig_gain_cfg *cfg_tia_a; +}; + +struct rtw89_phy_tssi_dbw_table { + u32 data[RTW89_TSSI_CFG_NUM][RTW89_TSSI_SBW_NUM]; +}; + +struct rtw89_phy_reg3_tbl { + const struct rtw89_reg3_def *reg3; + int size; +}; + +#define DECLARE_PHY_REG3_TBL(_name) \ +const struct rtw89_phy_reg3_tbl _name ## _tbl = { \ + .reg3 = _name, \ + .size = ARRAY_SIZE(_name), \ +} + +struct rtw89_nbi_reg_def { + struct rtw89_reg_def notch1_idx; + struct rtw89_reg_def notch1_frac_idx; + struct rtw89_reg_def notch1_en; + struct rtw89_reg_def notch2_idx; + struct rtw89_reg_def notch2_frac_idx; + struct rtw89_reg_def notch2_en; +}; + +struct rtw89_ccx_regs { + u32 setting_addr; + u32 edcca_opt_mask; + u32 measurement_trig_mask; + u32 trig_opt_mask; + u32 en_mask; + u32 ifs_cnt_addr; + u32 ifs_clm_period_mask; + u32 ifs_clm_cnt_unit_mask; + u32 ifs_clm_cnt_clear_mask; + u32 ifs_collect_en_mask; + u32 ifs_t1_addr; + u32 ifs_t1_th_h_mask; + u32 ifs_t1_en_mask; + u32 ifs_t1_th_l_mask; + u32 ifs_t2_addr; + u32 ifs_t2_th_h_mask; + u32 ifs_t2_en_mask; + u32 ifs_t2_th_l_mask; + u32 ifs_t3_addr; + u32 ifs_t3_th_h_mask; + u32 ifs_t3_en_mask; + u32 ifs_t3_th_l_mask; + u32 ifs_t4_addr; + u32 ifs_t4_th_h_mask; + u32 ifs_t4_en_mask; + u32 ifs_t4_th_l_mask; + u32 ifs_clm_tx_cnt_addr; + u32 ifs_clm_edcca_excl_cca_fa_mask; + u32 ifs_clm_tx_cnt_msk; + u32 ifs_clm_cca_addr; + u32 ifs_clm_ofdmcca_excl_fa_mask; + u32 ifs_clm_cckcca_excl_fa_mask; + u32 ifs_clm_fa_addr; + u32 ifs_clm_ofdm_fa_mask; + u32 ifs_clm_cck_fa_mask; + u32 ifs_his_addr; + u32 ifs_his_addr2; + u32 ifs_t4_his_mask; + u32 ifs_t3_his_mask; + u32 ifs_t2_his_mask; + u32 ifs_t1_his_mask; + u32 ifs_avg_l_addr; + u32 ifs_t2_avg_mask; + u32 ifs_t1_avg_mask; + u32 ifs_avg_h_addr; + u32 ifs_t4_avg_mask; + u32 ifs_t3_avg_mask; + u32 ifs_cca_l_addr; + u32 ifs_t2_cca_mask; + u32 ifs_t1_cca_mask; + u32 ifs_cca_h_addr; + u32 ifs_t4_cca_mask; + u32 ifs_t3_cca_mask; + u32 ifs_total_addr; + u32 ifs_cnt_done_mask; + u32 ifs_total_mask; + u32 nhm; + u32 nhm_ready; + u32 nhm_config; + u32 nhm_period_mask; + u32 nhm_unit_mask; + u32 nhm_include_cca_mask; + u32 nhm_en_mask; + u32 nhm_method; + u32 nhm_pwr_method_msk; + u32 edcca_clm_rdy; + u32 edcca_clm_rdy_mask; + u32 edcca_clm_cnt; + u32 edcca_clm_cnt_mask; +}; + +struct rtw89_physts_regs { + u32 setting_addr; + u32 dis_trigger_fail_mask; + u32 dis_trigger_brk_mask; + struct rtw89_reg_def mac_phy_intf_sel; + const struct rtw89_reg_def *txpwr; + struct rtw89_regs_def tx_info; + struct rtw89_regs_def tx_common_ctrl; +}; + +struct rtw89_cfo_regs { + u32 comp; + u32 weighting_mask; + u32 comp_seg0; + u32 valid_0_mask; +}; + +struct rtw89_bb_wrap_regs { + u32 pwr_macid_lmt; + u32 pwr_macid_path; +}; + +struct rtw89_nctl_regs { + u32 cfg; + u32 rw; +}; + +enum rtw89_bandwidth_section_num_ax { + RTW89_BW20_SEC_NUM_AX = 8, + RTW89_BW40_SEC_NUM_AX = 4, + RTW89_BW80_SEC_NUM_AX = 2, +}; + +enum rtw89_bandwidth_section_num_be { + RTW89_BW20_SEC_NUM_BE = 16, + RTW89_BW40_SEC_NUM_BE = 8, + RTW89_BW80_SEC_NUM_BE = 4, + RTW89_BW160_SEC_NUM_BE = 2, +}; + +#define RTW89_TXPWR_LMT_PAGE_SIZE_AX 40 + +struct rtw89_txpwr_limit_ax { + s8 cck_20m[RTW89_BF_NUM]; + s8 cck_40m[RTW89_BF_NUM]; + s8 ofdm[RTW89_BF_NUM]; + s8 mcs_20m[RTW89_BW20_SEC_NUM_AX][RTW89_BF_NUM]; + s8 mcs_40m[RTW89_BW40_SEC_NUM_AX][RTW89_BF_NUM]; + s8 mcs_80m[RTW89_BW80_SEC_NUM_AX][RTW89_BF_NUM]; + s8 mcs_160m[RTW89_BF_NUM]; + s8 mcs_40m_0p5[RTW89_BF_NUM]; + s8 mcs_40m_2p5[RTW89_BF_NUM]; +}; + +#define RTW89_TXPWR_LMT_PAGE_SIZE_BE 76 + +struct rtw89_txpwr_limit_be { + s8 cck_20m[RTW89_BF_NUM]; + s8 cck_40m[RTW89_BF_NUM]; + s8 ofdm[RTW89_BF_NUM]; + s8 mcs_20m[RTW89_BW20_SEC_NUM_BE][RTW89_BF_NUM]; + s8 mcs_40m[RTW89_BW40_SEC_NUM_BE][RTW89_BF_NUM]; + s8 mcs_80m[RTW89_BW80_SEC_NUM_BE][RTW89_BF_NUM]; + s8 mcs_160m[RTW89_BW160_SEC_NUM_BE][RTW89_BF_NUM]; + s8 mcs_320m[RTW89_BF_NUM]; + s8 mcs_40m_0p5[RTW89_BF_NUM]; + s8 mcs_40m_2p5[RTW89_BF_NUM]; + s8 mcs_40m_4p5[RTW89_BF_NUM]; + s8 mcs_40m_6p5[RTW89_BF_NUM]; +}; + +#define RTW89_RU_SEC_NUM_AX 8 + +#define RTW89_TXPWR_LMT_RU_PAGE_SIZE_AX 24 + +struct rtw89_txpwr_limit_ru_ax { + s8 ru26[RTW89_RU_SEC_NUM_AX]; + s8 ru52[RTW89_RU_SEC_NUM_AX]; + s8 ru106[RTW89_RU_SEC_NUM_AX]; +}; + +#define RTW89_RU_SEC_NUM_BE 16 + +#define RTW89_TXPWR_LMT_RU_PAGE_SIZE_BE 80 + +struct rtw89_txpwr_limit_ru_be { + s8 ru26[RTW89_RU_SEC_NUM_BE]; + s8 ru52[RTW89_RU_SEC_NUM_BE]; + s8 ru106[RTW89_RU_SEC_NUM_BE]; + s8 ru52_26[RTW89_RU_SEC_NUM_BE]; + s8 ru106_26[RTW89_RU_SEC_NUM_BE]; +}; + +#define RTW89_RU484_242_SEC_NUM_BE 4 +#define RTW89_RU996_484_SEC_NUM_BE 2 +#define RTW89_RU996_484_242_SEC_NUM_BE 2 + +struct rtw89_txpwr_limit_large_mru_be { + s8 ru484_242[RTW89_NSS_NUM][RTW89_RU484_242_SEC_NUM_BE]; + s8 ru996_484[RTW89_NSS_NUM][RTW89_RU996_484_SEC_NUM_BE]; + s8 ru996_484_242[RTW89_NSS_NUM][RTW89_RU996_484_242_SEC_NUM_BE]; +}; + +struct rtw89_phy_rfk_log_fmt { + const struct rtw89_fw_element_hdr *elm[RTW89_PHY_C2H_RFK_LOG_FUNC_NUM]; +}; + +enum rtw89_mdpd_onoff { + MDPD_ON = 0, + MDPD_OFF = 1, +}; + +enum rtw89_oob_dpd_onoff { + OOB_DPD_OFF = 0, + OOB_DPD_ON = 1, +}; + +enum rtw89_cim3k_onoff { + CIM3K_ON = 1, + CIM3K_OFF = 0, +}; + +enum rtw89_cim3k_en_dis { + CIM3K_ENABLE = 1, + CIM3K_DISABLE = 0, +}; + +enum rtw89_rfsi_ctrl_modulation { + RFSI_BPSK = 0, + RFSI_QPSK = 1, + RFSI_16QAM = 2, + RFSI_64QAM = 3, + RFSI_256QAM = 4, + RFSI_1024QAM = 5, + RFSI_4096QAM = 6, + RFSI_MAX, +}; + +enum rtw89_cfir_onoff { + CFIR_ON = 1, + CFIR_OFF = 0, +}; + +enum rtw89_filter_onoff { + FILTER_A_ON = 1, + FILTER_A_OFF = 0, +}; + +#define MAX_TX_RFSI_CTRL_OPT 10 + +#define _8nibble(n0, n1, n2, n3, n4, n5, n6, n7) \ + ((n0) << 0 | (n1) << 4 | (n2) << 8 | (n3) << 12 | \ + (n4) << 16 | (n5) << 20 | (n6) << 24 | (n7) << 28) + +#define _qam_comp_code(c) ((((c) & (BIT(15) | BIT(14))) >> 11) | \ + (((c) & BIT(12)) >> 10) | \ + (((c) & (BIT(9) | BIT(8))) >> 8)) + +#define _10qam_comp_code(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \ + _qam_comp_code(c0), _qam_comp_code(c1), _qam_comp_code(c2), _qam_comp_code(c3), \ + _qam_comp_code(c4), _qam_comp_code(c5), _qam_comp_code(c6), _qam_comp_code(c7), \ + _qam_comp_code(c8), _qam_comp_code(c9) + +struct rtw89_bb_wrap_common_data { + struct { + struct rtw89_bb_wrap_data_cim3k { + u8 th, ow, non_bandedge, bandedge; + } cim3k; + u32 rfsi_ct_opt[2]; + u8 pb_tb; + } bands[RFSI_CTRL_BAND_NUM]; + u8 qam_th[6]; +}; + +struct rtw89_bb_wrap_common_data_gen3 { + struct { + u8 qam_th[6]; + } bands[RFSI_CTRL_BAND_NUM]; + u8 cck_val[2]; +}; + +struct rtw89_bb_wrap_data { + const struct rtw89_bb_wrap_common_data *common; + const struct rtw89_bb_wrap_common_data_gen3 *common_gen3; + struct { + u16 qam_comp_th0[MAX_TX_RFSI_CTRL_OPT]; + u16 qam_comp_th1[MAX_TX_RFSI_CTRL_OPT]; /* encoded */ + u16 qam_comp_th2[MAX_TX_RFSI_CTRL_OPT]; /* encoded */ + u16 qam_comp_ow[MAX_TX_RFSI_CTRL_OPT]; + u8 oob_dpd_by_cbw[8]; + } bands[RFSI_CTRL_BAND_NUM]; + u8 mdpd_by_dbw[4]; +}; + +struct rtw89_phy_gen_def { + u32 cr_base; + u32 physt_bmp_start; + u32 physt_bmp_eht; + u8 physt_ie_len[32]; + u8 physt_gen; + const struct rtw89_ccx_regs *ccx; + const struct rtw89_physts_regs *physts; + const struct rtw89_cfo_regs *cfo; + const struct rtw89_bb_wrap_regs *bb_wrap; + const struct rtw89_nctl_regs *nctl; + u32 (*phy0_phy1_offset)(struct rtw89_dev *rtwdev, u32 addr); + void (*config_bb_gain)(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data); + void (*preinit_rf_nctl)(struct rtw89_dev *rtwdev); + void (*bb_wrap_init)(struct rtw89_dev *rtwdev); + void (*ch_info_init)(struct rtw89_dev *rtwdev); + + void (*set_txpwr_byrate)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*set_txpwr_offset)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*set_txpwr_limit)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*set_txpwr_limit_ru)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +}; + +extern const struct rtw89_phy_gen_def rtw89_phy_gen_ax; +extern const struct rtw89_phy_gen_def rtw89_phy_gen_be; +extern const struct rtw89_phy_gen_def rtw89_phy_gen_be_v1; + +static inline void rtw89_raw_phy_write8(struct rtw89_dev *rtwdev, + u32 addr, u8 data) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write8(rtwdev, addr + phy->cr_base, data); +} + +static inline void rtw89_raw_phy_write16(struct rtw89_dev *rtwdev, + u32 addr, u16 data) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write16(rtwdev, addr + phy->cr_base, data); +} + +static inline void rtw89_raw_phy_write32(struct rtw89_dev *rtwdev, + u32 addr, u32 data) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write32(rtwdev, addr + phy->cr_base, data); +} + +static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, + u32 addr, u8 data) +{ + rtwdev->io->phy_write8(rtwdev, addr, data); +} + +static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev, + u32 addr, u16 data) +{ + rtwdev->io->phy_write16(rtwdev, addr, data); +} + +static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev, + u32 addr, u32 data) +{ + rtwdev->io->phy_write32(rtwdev, addr, data); +} + +static inline void rtw89_phy_write32_set(struct rtw89_dev *rtwdev, + u32 addr, u32 bits) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write32_set(rtwdev, addr + phy->cr_base, bits); +} + +static inline void rtw89_phy_write32_clr(struct rtw89_dev *rtwdev, + u32 addr, u32 bits) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write32_clr(rtwdev, addr + phy->cr_base, bits); +} + +static inline void rtw89_phy_write32_mask(struct rtw89_dev *rtwdev, + u32 addr, u32 mask, u32 data) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + rtw89_write32_mask(rtwdev, addr + phy->cr_base, mask, data); +} + +static inline u8 rtw89_phy_read8(struct rtw89_dev *rtwdev, u32 addr) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + return rtw89_read8(rtwdev, addr + phy->cr_base); +} + +static inline u16 rtw89_phy_read16(struct rtw89_dev *rtwdev, u32 addr) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + return rtw89_read16(rtwdev, addr + phy->cr_base); +} + +static inline u32 rtw89_phy_read32(struct rtw89_dev *rtwdev, u32 addr) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + return rtw89_read32(rtwdev, addr + phy->cr_base); +} + +static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev, + u32 addr, u32 mask) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + return rtw89_read32_mask(rtwdev, addr + phy->cr_base, mask); +} + +static inline void rtw89_bbmcu_write32(struct rtw89_dev *rtwdev, + u32 addr, u32 data, enum rtw89_phy_idx phy_idx) +{ + if (phy_idx && addr < 0x10000) + addr += 0x20000; + + rtw89_write32(rtwdev, addr + RTW89_BBMCU_ADDR_OFFSET, data); +} + +static inline +enum rtw89_gain_offset rtw89_subband_to_gain_offset_band_of_ofdm(enum rtw89_subband subband) +{ + switch (subband) { + default: + case RTW89_CH_2G: + return RTW89_GAIN_OFFSET_2G_OFDM; + case RTW89_CH_5G_BAND_1: + return RTW89_GAIN_OFFSET_5G_LOW; + case RTW89_CH_5G_BAND_3: + return RTW89_GAIN_OFFSET_5G_MID; + case RTW89_CH_5G_BAND_4: + return RTW89_GAIN_OFFSET_5G_HIGH; + case RTW89_CH_6G_BAND_IDX0: + return RTW89_GAIN_OFFSET_6G_L0; + case RTW89_CH_6G_BAND_IDX1: + return RTW89_GAIN_OFFSET_6G_L1; + case RTW89_CH_6G_BAND_IDX2: + return RTW89_GAIN_OFFSET_6G_M0; + case RTW89_CH_6G_BAND_IDX3: + return RTW89_GAIN_OFFSET_6G_M1; + case RTW89_CH_6G_BAND_IDX4: + return RTW89_GAIN_OFFSET_6G_H0; + case RTW89_CH_6G_BAND_IDX5: + return RTW89_GAIN_OFFSET_6G_H1; + case RTW89_CH_6G_BAND_IDX6: + return RTW89_GAIN_OFFSET_6G_UH0; + case RTW89_CH_6G_BAND_IDX7: + return RTW89_GAIN_OFFSET_6G_UH1; + } +} + +static inline +enum rtw89_phy_bb_gain_band rtw89_subband_to_bb_gain_band(enum rtw89_subband subband) +{ + switch (subband) { + default: + case RTW89_CH_2G: + return RTW89_BB_GAIN_BAND_2G; + case RTW89_CH_5G_BAND_1: + return RTW89_BB_GAIN_BAND_5G_L; + case RTW89_CH_5G_BAND_3: + return RTW89_BB_GAIN_BAND_5G_M; + case RTW89_CH_5G_BAND_4: + return RTW89_BB_GAIN_BAND_5G_H; + case RTW89_CH_6G_BAND_IDX0: + case RTW89_CH_6G_BAND_IDX1: + return RTW89_BB_GAIN_BAND_6G_L; + case RTW89_CH_6G_BAND_IDX2: + case RTW89_CH_6G_BAND_IDX3: + return RTW89_BB_GAIN_BAND_6G_M; + case RTW89_CH_6G_BAND_IDX4: + case RTW89_CH_6G_BAND_IDX5: + return RTW89_BB_GAIN_BAND_6G_H; + case RTW89_CH_6G_BAND_IDX6: + case RTW89_CH_6G_BAND_IDX7: + return RTW89_BB_GAIN_BAND_6G_UH; + } +} + +static inline +enum rtw89_phy_gain_band_be rtw89_subband_to_gain_band_be(enum rtw89_subband subband) +{ + switch (subband) { + default: + case RTW89_CH_2G: + return RTW89_BB_GAIN_BAND_2G_BE; + case RTW89_CH_5G_BAND_1: + return RTW89_BB_GAIN_BAND_5G_L_BE; + case RTW89_CH_5G_BAND_3: + return RTW89_BB_GAIN_BAND_5G_M_BE; + case RTW89_CH_5G_BAND_4: + return RTW89_BB_GAIN_BAND_5G_H_BE; + case RTW89_CH_6G_BAND_IDX0: + return RTW89_BB_GAIN_BAND_6G_L0_BE; + case RTW89_CH_6G_BAND_IDX1: + return RTW89_BB_GAIN_BAND_6G_L1_BE; + case RTW89_CH_6G_BAND_IDX2: + return RTW89_BB_GAIN_BAND_6G_M0_BE; + case RTW89_CH_6G_BAND_IDX3: + return RTW89_BB_GAIN_BAND_6G_M1_BE; + case RTW89_CH_6G_BAND_IDX4: + return RTW89_BB_GAIN_BAND_6G_H0_BE; + case RTW89_CH_6G_BAND_IDX5: + return RTW89_BB_GAIN_BAND_6G_H1_BE; + case RTW89_CH_6G_BAND_IDX6: + return RTW89_BB_GAIN_BAND_6G_UH0_BE; + case RTW89_CH_6G_BAND_IDX7: + return RTW89_BB_GAIN_BAND_6G_UH1_BE; + } +} + +struct rtw89_rfk_chan_desc { + /* desc is valid iff ch is non-zero */ + u8 ch; + + /* To avoid us from extending old chip code every time, each new + * field must be defined along with a bool flag in positivte way. + */ + bool has_band; + u8 band; + bool has_bw; + u8 bw; +}; + +enum rtw89_rfk_flag { + RTW89_RFK_F_WRF = 0, + RTW89_RFK_F_WM = 1, + RTW89_RFK_F_WS = 2, + RTW89_RFK_F_WC = 3, + RTW89_RFK_F_DELAY = 4, + RTW89_RFK_F_NUM, +}; + +struct rtw89_rfk_tbl { + const struct rtw89_reg5_def *defs; + u32 size; +}; + +#define RTW89_DECLARE_RFK_TBL(_name) \ +const struct rtw89_rfk_tbl _name ## _tbl = { \ + .defs = _name, \ + .size = ARRAY_SIZE(_name), \ +} + +#define RTW89_DECL_RFK_WRF(_path, _addr, _mask, _data) \ + {.flag = RTW89_RFK_F_WRF, \ + .path = _path, \ + .addr = _addr, \ + .mask = _mask, \ + .data = _data,} + +#define RTW89_DECL_RFK_WM(_addr, _mask, _data) \ + {.flag = RTW89_RFK_F_WM, \ + .addr = _addr, \ + .mask = _mask, \ + .data = _data,} + +#define RTW89_DECL_RFK_WS(_addr, _mask) \ + {.flag = RTW89_RFK_F_WS, \ + .addr = _addr, \ + .mask = _mask,} + +#define RTW89_DECL_RFK_WC(_addr, _mask) \ + {.flag = RTW89_RFK_F_WC, \ + .addr = _addr, \ + .mask = _mask,} + +#define RTW89_DECL_RFK_DELAY(_data) \ + {.flag = RTW89_RFK_F_DELAY, \ + .data = _data,} + +void +rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl); + +#define rtw89_rfk_parser_by_cond(dev, cond, tbl_t, tbl_f) \ + do { \ + typeof(dev) __dev = (dev); \ + if (cond) \ + rtw89_rfk_parser(__dev, (tbl_t)); \ + else \ + rtw89_rfk_parser(__dev, (tbl_f)); \ + } while (0) + +void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_phy_reg3_tbl *tbl); +u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_bandwidth dbw); +u8 rtw89_phy_get_txsb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_bandwidth dbw); +u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask); +u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask); +u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask); +u32 rtw89_phy_read_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask); +bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); +void rtw89_phy_init_bb_afe(struct rtw89_dev *rtwdev); +void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio); +void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data); +void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data); +void rtw89_phy_dm_init(struct rtw89_dev *rtwdev); +void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev); +void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev); +void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev); +void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + u32 data, enum rtw89_phy_idx phy_idx); +void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx); +void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx); +u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + enum rtw89_phy_idx phy_idx); +s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_byrate *head, + const struct rtw89_rate_desc *desc); +s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw, + const struct rtw89_rate_desc *rate_desc); +void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev); +s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan); +int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan); +void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl); +s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, + u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch); +s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, + u8 ru, u8 ntx, u8 ch); + +static inline void rtw89_phy_preinit_rf_nctl(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + phy->preinit_rf_nctl(rtwdev); +} + +static inline void rtw89_phy_bb_wrap_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + if (phy->bb_wrap_init) + phy->bb_wrap_init(rtwdev); +} + +void rtw89_phy_bb_wrap_set_rfsi_ct_opt(struct rtw89_dev *rtwdev, + enum rtw89_rfsi_ctrl_band ctrl_band, + enum rtw89_phy_idx phy_idx); +void rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + +static inline void rtw89_phy_ch_info_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + if (phy->ch_info_init) + phy->ch_info_init(rtwdev); +} + +static inline +void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + phy->set_txpwr_byrate(rtwdev, chan, phy_idx); +} + +static inline +void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + phy->set_txpwr_offset(rtwdev, chan, phy_idx); +} + +static inline +void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + phy->set_txpwr_limit(rtwdev, chan, phy_idx); +} + +static inline +void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + + phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx); +} + +static inline s8 rtw89_phy_txpwr_rf_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_rf) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_rf << (chip->txpwr_factor_bb - chip->txpwr_factor_rf); +} + +static inline s8 rtw89_phy_txpwr_bb_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_bb) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_bb >> (chip->txpwr_factor_bb - chip->txpwr_factor_rf); +} + +static inline s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_rf >> (chip->txpwr_factor_rf - chip->txpwr_factor_mac); +} + +static inline s8 rtw89_phy_txpwr_dbm_to_mac(struct rtw89_dev *rtwdev, s8 dbm) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return clamp_t(s16, dbm << chip->txpwr_factor_mac, -64, 63); +} + +static inline s16 rtw89_phy_txpwr_mac_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_mac) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_mac << (chip->txpwr_factor_rf - chip->txpwr_factor_mac); +} + +static inline s16 rtw89_phy_txpwr_mac_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_mac) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_mac << (chip->txpwr_factor_bb - chip->txpwr_factor_mac); +} + +void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); +void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); +void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, + u32 changed); +void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, + u32 changed); +void rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev *rtwdev); +void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask); +bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func); +void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func); + +extern const char * const rtw89_rfk_report_names[]; + +int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + unsigned int ms); +int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + enum rtw89_tssi_mode tssi_mode, + unsigned int ms); +int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + bool is_chl_k, unsigned int ms); +int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + unsigned int ms); +void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + struct rtw89_h2c_rf_tssi *h2c); +void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + const struct rtw89_chan *chan, + struct rtw89_h2c_rf_tssi *h2c); +void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev); +void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, + struct rtw89_rx_phy_ppdu *phy_ppdu); +void rtw89_phy_stat_track(struct rtw89_dev *rtwdev); +void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev); +void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + u32 val); +void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb); +void rtw89_phy_dig(struct rtw89_dev *rtwdev); +void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev); +void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore); +void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev); +void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu); +void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev); +void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); +void __rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, u8 bss_color, u16 aid, + enum rtw89_phy_idx phy_idx); +void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg); +void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); +u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); +void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, + u8 *ch, enum nl80211_band *band); +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool scan); +void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev); +void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb); +enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); +enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); +u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev, + const struct rtw89_rfk_chan_desc *desc, u8 desc_nr, + const struct rtw89_chan *target_chan); +void rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev); +void rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, enum rtw89_band hw_band, + u16 ch_hw_value); +void rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/phy_be.c b/drivers/net/wireless/realtek/rtw89/phy_be.c new file mode 100644 index 000000000..c06927d1d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/phy_be.c @@ -0,0 +1,1991 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include "chan.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" + +static const struct rtw89_ccx_regs rtw89_ccx_regs_be = { + .setting_addr = R_CCX, + .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK_V1, + .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK, + .trig_opt_mask = B_CCX_TRIG_OPT_MSK, + .en_mask = B_CCX_EN_MSK, + .ifs_cnt_addr = R_IFS_COUNTER, + .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK, + .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK, + .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK, + .ifs_collect_en_mask = B_IFS_COLLECT_EN, + .ifs_t1_addr = R_IFS_T1, + .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK, + .ifs_t1_en_mask = B_IFS_T1_EN_MSK, + .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK, + .ifs_t2_addr = R_IFS_T2, + .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK, + .ifs_t2_en_mask = B_IFS_T2_EN_MSK, + .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK, + .ifs_t3_addr = R_IFS_T3, + .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK, + .ifs_t3_en_mask = B_IFS_T3_EN_MSK, + .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK, + .ifs_t4_addr = R_IFS_T4, + .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK, + .ifs_t4_en_mask = B_IFS_T4_EN_MSK, + .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK, + .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT_V1, + .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK, + .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK, + .ifs_clm_cca_addr = R_IFS_CLM_CCA_V1, + .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK, + .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK, + .ifs_clm_fa_addr = R_IFS_CLM_FA_V1, + .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, + .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, + .ifs_his_addr = R_IFS_HIS_V1, + .ifs_his_addr2 = R_IFS_HIS_V1, + .ifs_t4_his_mask = B_IFS_T4_HIS_MSK, + .ifs_t3_his_mask = B_IFS_T3_HIS_MSK, + .ifs_t2_his_mask = B_IFS_T2_HIS_MSK, + .ifs_t1_his_mask = B_IFS_T1_HIS_MSK, + .ifs_avg_l_addr = R_IFS_AVG_L_V1, + .ifs_t2_avg_mask = B_IFS_T2_AVG_MSK, + .ifs_t1_avg_mask = B_IFS_T1_AVG_MSK, + .ifs_avg_h_addr = R_IFS_AVG_H_V1, + .ifs_t4_avg_mask = B_IFS_T4_AVG_MSK, + .ifs_t3_avg_mask = B_IFS_T3_AVG_MSK, + .ifs_cca_l_addr = R_IFS_CCA_L_V1, + .ifs_t2_cca_mask = B_IFS_T2_CCA_MSK, + .ifs_t1_cca_mask = B_IFS_T1_CCA_MSK, + .ifs_cca_h_addr = R_IFS_CCA_H_V1, + .ifs_t4_cca_mask = B_IFS_T4_CCA_MSK, + .ifs_t3_cca_mask = B_IFS_T3_CCA_MSK, + .ifs_total_addr = R_IFSCNT_V1, + .ifs_cnt_done_mask = B_IFSCNT_DONE_MSK, + .ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK, + .nhm = R_NHM_BE, + .nhm_ready = B_NHM_READY_BE_MSK, + .nhm_config = R_NHM_CFG, + .nhm_period_mask = B_NHM_PERIOD_MSK, + .nhm_unit_mask = B_NHM_COUNTER_MSK, + .nhm_include_cca_mask = B_NHM_INCLUDE_CCA_MSK, + .nhm_en_mask = B_NHM_EN_MSK, + .nhm_method = R_NHM_TH9, + .nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK, + .edcca_clm_rdy = R_CLM_EDCCA_RDY_V1, + .edcca_clm_rdy_mask = B_CLM_EDCCA_RDY, + .edcca_clm_cnt = R_CLM_EDCCA_RESULT_V1, + .edcca_clm_cnt_mask = B_CLM_EDCCA_RESULT, +}; + +static const struct rtw89_ccx_regs rtw89_ccx_regs_be_v1 = { + .setting_addr = R_CCX_BE4, + .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK_V1, + .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK, + .trig_opt_mask = B_CCX_TRIG_OPT_MSK, + .en_mask = B_CCX_EN_MSK, + .ifs_cnt_addr = R_IFS_COUNTER_BE4, + .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK, + .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK, + .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK, + .ifs_collect_en_mask = B_IFS_COLLECT_EN, + .ifs_t1_addr = R_IFS_T1_BE4, + .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK, + .ifs_t1_en_mask = B_IFS_T1_EN_MSK, + .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK, + .ifs_t2_addr = R_IFS_T2_BE4, + .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK, + .ifs_t2_en_mask = B_IFS_T2_EN_MSK, + .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK, + .ifs_t3_addr = R_IFS_T3_BE4, + .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK, + .ifs_t3_en_mask = B_IFS_T3_EN_MSK, + .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK, + .ifs_t4_addr = R_IFS_T4_BE4, + .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK, + .ifs_t4_en_mask = B_IFS_T4_EN_MSK, + .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK, + .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT_BE4, + .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK, + .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK, + .ifs_clm_cca_addr = R_IFS_CLM_CCA_BE4, + .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK, + .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK, + .ifs_clm_fa_addr = R_IFS_CLM_FA_BE4, + .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, + .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, + .ifs_his_addr = R_IFS_T1_HIS_BE4, + .ifs_his_addr2 = R_IFS_T3_HIS_BE4, /* for 3/4 */ + .ifs_t4_his_mask = B_IFS_T4_HIS_BE4, + .ifs_t3_his_mask = B_IFS_T3_HIS_BE4, + .ifs_t2_his_mask = B_IFS_T2_HIS_BE4, + .ifs_t1_his_mask = B_IFS_T1_HIS_BE4, + .ifs_avg_l_addr = R_IFS_T1_AVG_BE4, + .ifs_t2_avg_mask = B_IFS_T2_AVG_BE4, + .ifs_t1_avg_mask = B_IFS_T1_AVG_BE4, + .ifs_avg_h_addr = R_IFS_T3_AVG_BE4, + .ifs_t4_avg_mask = B_IFS_T4_AVG_BE4, + .ifs_t3_avg_mask = B_IFS_T3_AVG_BE4, + .ifs_cca_l_addr = R_IFS_T1_CLM_BE4, + .ifs_t2_cca_mask = B_IFS_T2_CLM_BE4, + .ifs_t1_cca_mask = B_IFS_T1_CLM_BE4, + .ifs_cca_h_addr = R_IFS_T3_CLM_BE4, + .ifs_t4_cca_mask = B_IFS_T4_CLM_BE4, + .ifs_t3_cca_mask = B_IFS_T3_CLM_BE4, + .ifs_total_addr = R_IFS_TOTAL_BE4, + .ifs_cnt_done_mask = B_IFS_CNT_DONE_BE4, + .ifs_total_mask = B_IFS_TOTAL_BE4, + .edcca_clm_rdy = R_CLM_EDCCA_RDY_BE4, + .edcca_clm_rdy_mask = B_CLM_EDCCA_RDY, + .edcca_clm_cnt = R_CLM_EDCCA_RESULT_BE4, + .edcca_clm_cnt_mask = B_CLM_EDCCA_RESULT, +}; + +static const u32 rtw89_tx_info_reg_be[] = { + R_TX_INFO_0_0_COMB_V1, + R_TX_INFO_0_1_COMB_V1, + R_TX_INFO_1_0_COMB_V1, + R_TX_INFO_1_1_COMB_V1, + R_TX_INFO_2_0_COMB_V1, + R_TX_INFO_2_1_COMB_V1 +}; + +static const u32 rtw89_tx_common_ctrl_reg_be[] = { + R_TX_COMMON_CTRL_0_0_COMB_V1, + R_TX_COMMON_CTRL_0_1_COMB_V1 +}; + +static const struct rtw89_reg_def rtw89_txpwr_be[] = { + {.addr = R_PATH0_TXPWR_V1, .mask = B_PATH0_TXPWR}, + {.addr = R_PATH1_TXPWR_V1, .mask = B_PATH1_TXPWR} +}; + +static const struct rtw89_physts_regs rtw89_physts_regs_be = { + .setting_addr = R_PLCP_HISTOGRAM, + .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL, + .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK, + .mac_phy_intf_sel = {R_INTF_R_INTF_RPT_SEL, B_INTF_R_INTF_RPT_SEL}, + .txpwr = rtw89_txpwr_be, + .tx_info = RTW89_REGS_DEF(rtw89_tx_info_reg_be), + .tx_common_ctrl = RTW89_REGS_DEF(rtw89_tx_common_ctrl_reg_be), +}; + +static const u32 rtw89_tx_info_reg_be_v1[] = { + R_TX_INFO_0_0_COMB_BE4, + R_TX_INFO_0_1_COMB_BE4, + R_TX_INFO_1_0_COMB_BE4, + R_TX_INFO_1_1_COMB_BE4, + R_TX_INFO_2_0_COMB_BE4, + R_TX_INFO_2_1_COMB_BE4 +}; + +static const u32 rtw89_tx_common_ctrl_reg_be_v1[] = { + R_TX_COMMON_CTRL_0_0_COMB_BE4, + R_TX_COMMON_CTRL_0_1_COMB_BE4 +}; + +static const struct rtw89_reg_def rtw89_txpwr_be_v1[] = { + {.addr = R_PATH0_TXPWR_BE4, .mask = B_PATH0_TXPWR}, + {.addr = R_PATH1_TXPWR_BE4, .mask = B_PATH1_TXPWR} +}; + +static const struct rtw89_physts_regs rtw89_physts_regs_be_v1 = { + .setting_addr = R_PLCP_HISTOGRAM_BE_V1, + .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL, + .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK, + .mac_phy_intf_sel = {R_INTF_R_INTF_RPT_SEL_BE4, B_INTF_R_INTF_RPT_SEL}, + .txpwr = rtw89_txpwr_be_v1, + .tx_info = RTW89_REGS_DEF(rtw89_tx_info_reg_be_v1), + .tx_common_ctrl = RTW89_REGS_DEF(rtw89_tx_common_ctrl_reg_be_v1), +}; + +static const struct rtw89_cfo_regs rtw89_cfo_regs_be = { + .comp = R_DCFO_WEIGHT_BE, + .weighting_mask = B_DCFO_WEIGHT_MSK_BE, + .comp_seg0 = R_DCFO_OPT_BE, + .valid_0_mask = B_DCFO_OPT_EN_BE, +}; + +static const struct rtw89_cfo_regs rtw89_cfo_regs_be_v1 = { + .comp = R_DCFO_WEIGHT_BE_V1, + .weighting_mask = B_DCFO_WEIGHT_MSK_BE, + .comp_seg0 = R_DCFO_OPT_BE_V1, + .valid_0_mask = B_DCFO_OPT_EN_BE, +}; + +static const struct rtw89_bb_wrap_regs rtw89_bb_wrap_regs_be = { + .pwr_macid_lmt = R_BE_PWR_MACID_LMT_BASE, + .pwr_macid_path = R_BE_PWR_MACID_PATH_BASE, +}; + +static const struct rtw89_bb_wrap_regs rtw89_bb_wrap_regs_be_v1 = { + .pwr_macid_lmt = R_BE_PWR_MACID_LMT_BASE_V1, + .pwr_macid_path = R_BE_PWR_MACID_PATH_BASE_V1, +}; + +static const struct rtw89_nctl_regs rtw89_nctl_regs_be = { + .cfg = R_NCTL_CFG, + .rw = R_NCTL_RW, +}; + +static const struct rtw89_nctl_regs rtw89_nctl_regs_be_v1 = { + .cfg = R_NCTL_CFG_BE4, + .rw = R_NCTL_RW_BE4, +}; + +static u32 rtw89_phy0_phy1_offset_be(struct rtw89_dev *rtwdev, u32 addr) +{ + u32 phy_page = addr >> 8; + u32 ofst = 0; + + if ((phy_page >= 0x4 && phy_page <= 0xF) || + (phy_page >= 0x20 && phy_page <= 0x2B) || + (phy_page >= 0x40 && phy_page <= 0x4f) || + (phy_page >= 0x60 && phy_page <= 0x6f) || + (phy_page >= 0xE4 && phy_page <= 0xE5) || + (phy_page >= 0xE8 && phy_page <= 0xED)) + ofst = 0x1000; + else + ofst = 0x0; + + return ofst; +} + +static u32 rtw89_phy0_phy1_offset_be_v1(struct rtw89_dev *rtwdev, u32 addr) +{ + u32 phy_page = addr >> 8; + u32 ofst = 0; + + if ((phy_page >= 0x204 && phy_page <= 0x20F) || + (phy_page >= 0x220 && phy_page <= 0x22F) || + (phy_page >= 0x240 && phy_page <= 0x24f) || + (phy_page >= 0x260 && phy_page <= 0x26f) || + (phy_page >= 0x2C0 && phy_page <= 0x2C9) || + (phy_page >= 0x2E0 && phy_page <= 0x2E8) || + phy_page == 0x2EE) + ofst = 0x1000; + else + ofst = 0x0; + + return ofst; +} + +union rtw89_phy_bb_gain_arg_be { + u32 addr; + struct { + u8 type; +#define BB_GAIN_TYPE_SUB0_BE GENMASK(3, 0) +#define BB_GAIN_TYPE_SUB1_BE GENMASK(7, 4) + u8 path_bw; +#define BB_GAIN_PATH_BE GENMASK(3, 0) +#define BB_GAIN_BW_BE GENMASK(7, 4) + u8 gain_band; + u8 cfg_type; + } __packed; +} __packed; + +static void +rtw89_phy_cfg_bb_gain_error_be(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg_be arg, u32 data) +{ + struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 bw_type = u8_get_bits(arg.path_bw, BB_GAIN_BW_BE); + u8 path = u8_get_bits(arg.path_bw, BB_GAIN_PATH_BE); + u8 gband = arg.gain_band; + u8 type = arg.type; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_gain[gband][bw_type][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_gain[gband][bw_type][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 2; i++, data >>= 8) + gain->tia_gain[gband][bw_type][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain error {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void +rtw89_phy_cfg_bb_rpl_ofst_be(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg_be arg, u32 data) +{ + struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 type_sub0 = u8_get_bits(arg.type, BB_GAIN_TYPE_SUB0_BE); + u8 type_sub1 = u8_get_bits(arg.type, BB_GAIN_TYPE_SUB1_BE); + u8 path = u8_get_bits(arg.path_bw, BB_GAIN_PATH_BE); + u8 gband = arg.gain_band; + u8 ofst = 0; + int i; + + switch (type_sub1) { + case RTW89_CMAC_BW_20M: + gain->rpl_ofst_20[gband][path][0] = (s8)data; + break; + case RTW89_CMAC_BW_40M: + for (i = 0; i < RTW89_BW20_SC_40M; i++, data >>= 8) + gain->rpl_ofst_40[gband][path][i] = data & 0xff; + break; + case RTW89_CMAC_BW_80M: + for (i = 0; i < RTW89_BW20_SC_80M; i++, data >>= 8) + gain->rpl_ofst_80[gband][path][i] = data & 0xff; + break; + case RTW89_CMAC_BW_160M: + if (type_sub0 == 0) + ofst = 0; + else + ofst = RTW89_BW20_SC_80M; + + for (i = 0; i < RTW89_BW20_SC_80M; i++, data >>= 8) + gain->rpl_ofst_160[gband][path][i + ofst] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb rpl ofst {0x%x:0x%x} with unknown type_sub1: %d\n", + arg.addr, data, type_sub1); + break; + } +} + +static void +rtw89_phy_cfg_bb_gain_op1db_be(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg_be arg, u32 data) +{ + struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 bw_type = u8_get_bits(arg.path_bw, BB_GAIN_BW_BE); + u8 path = u8_get_bits(arg.path_bw, BB_GAIN_PATH_BE); + u8 gband = arg.gain_band; + u8 type = arg.type; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_op1db[gband][bw_type][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_op1db[gband][bw_type][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 4; i++, data >>= 8) + gain->tia_lna_op1db[gband][bw_type][path][i] = data & 0xff; + break; + case 3: + for (i = 4; i < 8; i++, data >>= 8) + gain->tia_lna_op1db[gband][bw_type][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain op1db {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void rtw89_phy_config_bb_gain_be(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + union rtw89_phy_bb_gain_arg_be arg = { .addr = reg->addr }; + struct rtw89_efuse *efuse = &rtwdev->efuse; + u8 bw_type = u8_get_bits(arg.path_bw, BB_GAIN_BW_BE); + u8 path = u8_get_bits(arg.path_bw, BB_GAIN_PATH_BE); + + if (bw_type >= RTW89_BB_BW_NR_BE) + return; + + if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR_BE) + return; + + if (path >= chip->rf_path_num) + return; + + if (arg.addr >= 0xf9 && arg.addr <= 0xfe) { + rtw89_warn(rtwdev, "bb gain table with flow ctrl\n"); + return; + } + + switch (arg.cfg_type) { + case 0: + rtw89_phy_cfg_bb_gain_error_be(rtwdev, arg, reg->data); + break; + case 1: + rtw89_phy_cfg_bb_rpl_ofst_be(rtwdev, arg, reg->data); + break; + case 2: + /* ignore BB gain bypass */ + break; + case 3: + rtw89_phy_cfg_bb_gain_op1db_be(rtwdev, arg, reg->data); + break; + case 15: + rtw89_phy_write32_idx(rtwdev, reg->addr & 0xFFFFF, MASKHWORD, + reg->data, RTW89_PHY_0); + break; + case 4: + /* This cfg_type is only used by rfe_type >= 50 with eFEM */ + if (efuse->rfe_type < 50) + break; + fallthrough; + default: + rtw89_warn(rtwdev, + "bb gain {0x%x:0x%x} with unknown cfg type: %d\n", + arg.addr, reg->data, arg.cfg_type); + break; + } +} + +static void rtw89_phy_preinit_rf_nctl_check_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_nctl_regs *nctl = phy->nctl; + int poll; + u32 val; + + rtw89_phy_write32(rtwdev, nctl->cfg, B_NCTL_CHK_EN); + + for (poll = 0; poll < 10000; poll++) { + rtw89_phy_write32(rtwdev, nctl->rw, B_NCTL_CHECK); + + fsleep(10); + + val = rtw89_phy_read32(rtwdev, nctl->rw); + if (val == B_NCTL_CHECK) + return; + } + + rtw89_warn(rtwdev, "NCTL INIT check 0x%x[2]TIMEOUT!\n", nctl->rw); +} + +static void rtw89_phy_preinit_rf_nctl_be(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C0, B_GOTX_IQKDPK, 0x3); + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C1, B_GOTX_IQKDPK, 0x3); + rtw89_phy_write32_mask(rtwdev, R_IQKDPK_HC, B_IQKDPK_HC, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CLK_GCK, B_CLK_GCK, 0x00fffff); + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_CLKEN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST, B_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST, B_IQK_DPK_PRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST_C1, B_IQK_DPK_PRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TXRFC, B_TXRFC_RST, 0x1); + + if (rtwdev->dbcc_en) { + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST_C1, B_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TXRFC_C1, B_TXRFC_RST, 0x1); + } + + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_RX_CFIR_PATH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_RX_CFIR_PATH, 0x3); + + rtw89_phy_preinit_rf_nctl_check_be(rtwdev); +} + +static void rtw89_phy_preinit_rf_nctl_be_v1(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C0_BE4, B_GOTX_IQKDPK, 0x3); + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C1_BE4, B_GOTX_IQKDPK, 0x3); + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK_BE4, B_IOQ_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST_BE4, B_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST_BE4, B_IQK_DPK_PRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST_C1_BE4, B_IQK_DPK_PRST, 0x1); + + rtw89_phy_preinit_rf_nctl_check_be(rtwdev); +} + +static u32 rtw89_phy_bb_wrap_flush_addr(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) + return 0; + + if (rtwdev->chip->chip_id == RTL8922D && hal->cid == RTL8922D_CID7025) { + if (addr >= R_BE_PWR_MACID_PATH_BASE_V1 && + addr <= R_BE_PWR_MACID_PATH_BASE_V1 + 0xFF) + return addr + 0x800; + + if (addr >= R_BE_PWR_MACID_LMT_BASE_V1 && + addr <= R_BE_PWR_MACID_LMT_BASE_V1 + 0xFF) + return addr - 0x800; + } + + return 0; +} + +static +void rtw89_write_bb_wrap_flush(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + /* To write registers of pwr_macid_lmt and pwr_macid_path with flush */ + u32 flush_addr; + u32 val32; + + flush_addr = rtw89_phy_bb_wrap_flush_addr(rtwdev, addr); + if (flush_addr) { + val32 = rtw89_read32(rtwdev, flush_addr); + rtw89_write32(rtwdev, flush_addr, val32); + } + + rtw89_write32(rtwdev, addr, data); +} + +static +void rtw89_phy_bb_wrap_pwr_by_macid_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_bb_wrap_regs *bb_wrap = phy->bb_wrap; + u32 max_macid = rtwdev->chip->support_macid_num; + u32 macid_idx, cr, base_macid_lmt; + + base_macid_lmt = bb_wrap->pwr_macid_lmt; + + for (macid_idx = 0; macid_idx < 4 * max_macid; macid_idx += 4) { + cr = base_macid_lmt + macid_idx; + rtw89_write_bb_wrap_flush(rtwdev, cr, 0); + } +} + +static +void rtw89_phy_bb_wrap_tx_path_by_macid_init(struct rtw89_dev *rtwdev) +{ + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; + const struct rtw89_bb_wrap_regs *bb_wrap = phy->bb_wrap; + u32 max_macid = rtwdev->chip->support_macid_num; + u32 cr = bb_wrap->pwr_macid_path; + int i; + + for (i = 0; i < max_macid; i++, cr += 4) + rtw89_write_bb_wrap_flush(rtwdev, cr, 0); +} + +static void rtw89_phy_bb_wrap_tpu_set_all(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + u32 addr, t; + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FTM_SS, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_BY_RATE_DBW_ON, 0x3); + + for (addr = R_BE_PWR_BY_RATE; addr <= R_BE_PWR_BY_RATE_END; addr += 4) { + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); + rtw89_write32(rtwdev, t, 0); + } + for (addr = R_BE_PWR_RULMT_START; addr <= R_BE_PWR_RULMT_END; addr += 4) { + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); + rtw89_write32(rtwdev, t, 0); + } + for (addr = R_BE_PWR_RATE_OFST_CTRL; addr <= R_BE_PWR_RATE_OFST_END; addr += 4) { + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); + rtw89_write32(rtwdev, t, 0); + } + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_REF_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_LMT_DB, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_OFST_LMTBF, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_LMTBF_DB, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_RATE_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_BYRATE_DB, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_OFST_RULMT, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_RULMT_DB, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_OFST_SW, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_SW_DB, 0); +} + +static +void rtw89_phy_bb_wrap_listen_path_en_init(struct rtw89_dev *rtwdev) +{ + u32 addr; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL); + if (ret) + return; + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_LISTEN_PATH, RTW89_MAC_1); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_LISTEN_PATH_EN, 0x2); +} + +static void rtw89_phy_bb_wrap_force_cr_init(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + u32 addr; + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FORCE_LMT, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_LMT_ON, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_RATE_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_FORCE_PWR_BY_RATE_EN, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_OFST_RULMT, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_RU_ENON, 0); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_RU_ON, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FORCE_MACID, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_MACID_ALL, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_COEX_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_COEX_ON, 0); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, mac_idx); + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_RATE_ON, 0); +} + +static void rtw89_phy_bb_wrap_ftm_init(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + u32 addr; + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FTM, mac_idx); + rtw89_write32(rtwdev, addr, 0xE4E431); + + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FTM_SS, mac_idx); + rtw89_write32_mask(rtwdev, addr, 0x7, 0); +} + +static u32 rtw89_phy_bb_wrap_be_bandedge_decision(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u8 pri_ch = chan->primary_channel; + u32 val = 0; + + switch (chan->band_type) { + default: + case RTW89_BAND_2G: + if (pri_ch == 1 || pri_ch == 13) + val = BIT(1) | BIT(0); + else if (pri_ch == 5 || pri_ch == 9) + val = BIT(1); + break; + case RTW89_BAND_5G: + if (pri_ch == 36 || pri_ch == 64 || pri_ch == 100) + val = BIT(3) | BIT(2) | BIT(1) | BIT(0); + else if (pri_ch == 40 || pri_ch == 60 || pri_ch == 104) + val = BIT(3) | BIT(2) | BIT(1); + else if ((pri_ch > 40 && pri_ch < 60) || pri_ch == 108 || pri_ch == 112) + val = BIT(3) | BIT(2); + else if (pri_ch > 112 && pri_ch < 132) + val = BIT(3); + break; + case RTW89_BAND_6G: + break; + } + + return val; +} + +void rtw89_phy_bb_wrap_set_rfsi_ct_opt(struct rtw89_dev *rtwdev, + enum rtw89_rfsi_ctrl_band rfsi_band, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + const u32 *val; + u32 reg; + + if (!d || !d->common) + return; + + val = d->common->bands[rfsi_band].rfsi_ct_opt; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_RFSI_CT_OPT_0_BE4, phy_idx); + rtw89_write32(rtwdev, reg, val[0]); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_RFSI_CT_OPT_8_BE4, phy_idx); + rtw89_write32(rtwdev, reg, val[1]); +} +EXPORT_SYMBOL(rtw89_phy_bb_wrap_set_rfsi_ct_opt); + +void rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + bool cfr_manual_en = false; + u32 reg; + u32 val; + + val = rtw89_phy_bb_wrap_be_bandedge_decision(rtwdev, chan); + + if (chan->band_type == RTW89_BAND_2G && + ((chan->primary_channel == 13 && chan->band_width == RTW89_CHANNEL_WIDTH_20) || + (chan->primary_channel == 11 && chan->band_width == RTW89_CHANNEL_WIDTH_40))) + cfr_manual_en = true; + + rtw89_phy_write32_idx(rtwdev, R_TX_CFR_MANUAL_EN_BE4, B_TX_CFR_MANUAL_EN_BE4_M, + cfr_manual_en, phy_idx); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW20_BE4, val & BIT(0)); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW40_BE4, (val & BIT(1)) >> 1); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW80_BE4, (val & BIT(2)) >> 2); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWY_BE4, phy_idx); + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW160_BE4, (val & BIT(3)) >> 3); +} +EXPORT_SYMBOL(rtw89_phy_bb_wrap_set_rfsi_bandedge_ch); + +static void rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_init(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + u8 th0, th1, th2; + + if (!d || !d->common) + return; + + th0 = d->common->qam_th[0]; + th1 = d->common->qam_th[1]; + th2 = d->common->qam_th[2]; + + /* TH0 */ + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_0_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_3_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_1_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_4_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_7_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_0_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_3_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_6_BE4, th0, mac_idx); + /* TH1 */ + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_1_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_4_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_2_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_5_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_8_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_1_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_4_BE4, th1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_7_BE4, th1, mac_idx); + /* TH2 */ + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_2_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_0_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_3_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_6_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_9_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_2_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_5_BE4, th2, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_8_BE4, th2, mac_idx); + /* DPD 160M */ + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_0_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_1_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_2_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_3_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_4_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_5_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_6_BE4, th0, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_7_BE4, th0, mac_idx); + /* DPD 20M */ + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_0_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_1_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_2_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_3_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_4_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_5_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_6_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH1_7_BE4, 0x2, mac_idx); + /* DPD 40M */ + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_0_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_1_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_2_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_3_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_4_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_3_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_4_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_5_BE4, 0x2, mac_idx); + /* DPD 80M */ + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW80_TH1_0_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_1_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_2_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_3_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_4_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_5_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_6_BE4, 0x2, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_7_BE4, 0x2, mac_idx); + /* CIM3K */ + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_TH2_BE4, 0x2, mac_idx); +} + +static void rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_gen3_init(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + const struct rtw89_bb_wrap_common_data_gen3 *common_gen3; + const u8 *ths; + + if (!d || !d->common_gen3) + return; + + common_gen3 = d->common_gen3; + ths = common_gen3->bands[chan->rfsi_band].qam_th; + + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_0_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_1_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_2_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_3_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_4_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_5_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_6_BE4, ths[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH0_7_BE4, ths[0], mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH1_0_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH0_BE4, B_QAM3_TH1_1_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_2_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_3_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_4_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_5_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_6_BE4, ths[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH1_7_BE4, ths[1], mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH2_0_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH2_1_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH2_2_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH1_BE4, B_QAM3_TH2_3_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH2_4_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH2_5_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH2_6_BE4, ths[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH2_7_BE4, ths[2], mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_0_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_1_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_2_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_3_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_4_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH2_BE4, B_QAM3_TH3_5_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH3_6_BE4, ths[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH3_7_BE4, ths[3], mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_0_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_1_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_2_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_3_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_4_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_5_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_6_BE4, ths[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_TH4_7_BE4, ths[4], mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_0_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_1_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_2_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_3_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_4_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_5_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_6_BE4, ths[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH3_BE4, B_QAM3_TH5_7_BE4, ths[5], mac_idx); +} + +static void rtw89_phy_bb_wrap_tx_rfsi_scenario_def(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + u8 pb_tb = 0; + + if (d && d->common) + pb_tb = d->common->bands[0].pb_tb; + + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_ER_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_SUBF_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_FTM_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_SENS_BE4, 0x0, mac_idx); + + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DEF_BE, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_PB_BE4, pb_tb, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DL_WO_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DL_BF_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_MUMIMO_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_FTM_BE4, 0x0, mac_idx); + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_SENS_BE4, 0x0, mac_idx); +} + +static void rtw89_phy_bb_wrap_tx_rfsi_qam_comp_val(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + const u16 *th; + + if (!d || !d->common) + return; + + th = d->bands[0].qam_comp_th0; + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKLWORD, th[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKHWORD, th[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKLWORD, th[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKHWORD, th[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKLWORD, th[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKHWORD, th[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKLWORD, th[6], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKHWORD, th[7], mac_idx); + + th = d->bands[0].qam_comp_th1; + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_L, th[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_M, th[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_H, th[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_L, th[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_M, th[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_H, th[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_L, th[6], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_M, th[7], mac_idx); + + th = d->bands[0].qam_comp_th2; + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2L, th[0], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2M, th[1], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2H, th[2], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2L, th[3], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2M, th[4], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2H, th[5], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_2L, th[6], mac_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_2M, th[7], mac_idx); + + th = d->bands[0].qam_comp_ow; + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKLWORD, th[0], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKHWORD, th[1], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKLWORD, th[2], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKHWORD, th[3], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKLWORD, th[4], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKHWORD, th[5], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKLWORD, th[6], mac_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKHWORD, th[7], mac_idx); +} + +static void rtw89_phy_bb_set_oob_dpd_qam_comp_val(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + u8 th; + + if (!d) + return; + + th = d->bands[0].oob_dpd_by_cbw[0]; + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[1]; + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[2]; + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[3]; + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[4]; + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[5]; + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[6]; + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW7_BE4, th, mac_idx); + + th = d->bands[0].oob_dpd_by_cbw[7]; + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW7_BE4, th, mac_idx); +} + +static void rtw89_phy_bb_set_mdpd_qam_comp_val(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + u8 th; + + if (!d) + return; + + th = d->mdpd_by_dbw[0]; + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH7_BE4, th, mac_idx); + + th = d->mdpd_by_dbw[2]; + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW0_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW1_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW2_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW3_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW4_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW5_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW6_BE4, th, mac_idx); + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW7_BE4, th, mac_idx); +} + +static void rtw89_phy_bb_set_cim3k_val(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + const struct rtw89_bb_wrap_data_cim3k *p; + + if (!d || !d->common) + return; + + p = &d->common->bands[0].cim3k; + + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_TH_BE4, p->th, mac_idx); + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_OW_BE4, p->ow, mac_idx); + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_NONBE_BE4, + p->non_bandedge, mac_idx); + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_BANDEDGE_BE4, + p->bandedge, mac_idx); + + if (rtwdev->chip->chip_id != RTL8922D) + return; + + rtw89_write32_idx(rtwdev, R_CIM3K_SU_FORCE, B_CIM3K_SU_FORCE_EN, 1, mac_idx); + rtw89_write32_idx(rtwdev, R_CIM3K_SU_FORCE, B_CIM3K_SU_FORCE_VAL, 0, mac_idx); +} + +static void rtw89_phy_bb_set_cck_cfir_filter_val_gen3(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + const struct rtw89_bb_wrap_common_data_gen3 *common_gen3; + u8 cck0, cck1; + + if (!d || !d->common_gen3) + return; + + common_gen3 = d->common_gen3; + cck0 = common_gen3->cck_val[0]; + cck1 = common_gen3->cck_val[1]; + + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR0_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR1_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR2_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR3_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR4_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR5_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR6_BE4, cck0, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_TH4_BE4, B_QAM3_CFIR7_BE4, cck0, mac_idx); + + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR0_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR1_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR2_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR3_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR4_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR5_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR6_BE4, cck1, mac_idx); + rtw89_write32_idx(rtwdev, R_QAM3_FLTR_BE4, B_QAM3_FLTR7_BE4, cck1, mac_idx); +} + +static void rtw89_phy_bb_wrap_tx_rfsi_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + enum rtw89_phy_idx phy_idx = mac_idx != RTW89_MAC_0 ? RTW89_PHY_1 : RTW89_PHY_0; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + + if (chip_id != RTL8922D) + return; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[phy_idx]; + + rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_init(rtwdev, mac_idx); + rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_gen3_init(rtwdev, chan, mac_idx); + rtw89_phy_bb_wrap_tx_rfsi_scenario_def(rtwdev, mac_idx); + rtw89_phy_bb_wrap_tx_rfsi_qam_comp_val(rtwdev, mac_idx); + rtw89_phy_bb_set_oob_dpd_qam_comp_val(rtwdev, mac_idx); + rtw89_phy_bb_set_mdpd_qam_comp_val(rtwdev, mac_idx); + rtw89_phy_bb_set_cim3k_val(rtwdev, mac_idx); + rtw89_phy_bb_set_cck_cfir_filter_val_gen3(rtwdev, mac_idx); + rtw89_phy_bb_wrap_set_rfsi_ct_opt(rtwdev, 0, phy_idx); + rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(rtwdev, chan, phy_idx); +} + +static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u8 mac_idx; + u32 addr; + + if (chip_id != RTL8922A) + return; + + for (mac_idx = 0; mac_idx < RTW89_MAC_NUM; mac_idx++) { + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_RSSI_TARGET_LMT, mac_idx); + rtw89_write32(rtwdev, addr, 0x0201FE00); + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_TH, mac_idx); + rtw89_write32(rtwdev, addr, 0x00FFEC7E); + } +} + +static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) +{ + rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev); + rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev); + rtw89_phy_bb_wrap_tpu_set_all(rtwdev, mac_idx); + rtw89_phy_bb_wrap_tx_rfsi_ctrl_init(rtwdev, mac_idx); + rtw89_phy_bb_wrap_force_cr_init(rtwdev, mac_idx); + rtw89_phy_bb_wrap_ftm_init(rtwdev, mac_idx); + rtw89_phy_bb_wrap_listen_path_en_init(rtwdev); + rtw89_phy_bb_wrap_ul_pwr(rtwdev); +} + +static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev) +{ + __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_0); + if (rtwdev->dbcc_en) + __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_1); +} + +static void rtw89_phy_ch_info_init_be(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG, B_CHINFO_SEG_LEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG, B_CHINFO_SEG, 0xf); + rtw89_phy_write32_mask(rtwdev, R_CHINFO_DATA, B_CHINFO_DATA_BITMAP, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_ELM_SRC, B_CHINFO_ELM_BITMAP, 0x40303); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_ELM_SRC, B_CHINFO_SRC, 0x0); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_TYPE_SCAL, B_CHINFO_TYPE, 0x3); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_TYPE_SCAL, B_CHINFO_SCAL, 0x0); +} + +static void rtw89_phy_ch_info_init_be_v1(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG_BE4, B_CHINFO_SEG_LEN_BE4, 0); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_OPT_BE4, B_CHINFO_OPT_BE4, 0x3); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_NX_BE4, B_CHINFO_NX_BE4, 0x669); + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_ALG_BE4, B_CHINFO_ALG_BE4, 0); +} + +struct rtw89_byr_spec_ent_be { + struct rtw89_rate_desc init; + u8 num_of_idx; + bool no_over_bw40; + bool no_multi_nss; +}; + +static const struct rtw89_byr_spec_ent_be rtw89_byr_spec_be[] = { + { + .init = { .rs = RTW89_RS_CCK }, + .num_of_idx = RTW89_RATE_CCK_NUM, + .no_over_bw40 = true, + .no_multi_nss = true, + }, + { + .init = { .rs = RTW89_RS_OFDM }, + .num_of_idx = RTW89_RATE_OFDM_NUM, + .no_multi_nss = true, + }, + { + .init = { .rs = RTW89_RS_MCS, .idx = 14, .ofdma = RTW89_NON_OFDMA }, + .num_of_idx = 2, + .no_multi_nss = true, + }, + { + .init = { .rs = RTW89_RS_MCS, .idx = 14, .ofdma = RTW89_OFDMA }, + .num_of_idx = 2, + .no_multi_nss = true, + }, + { + .init = { .rs = RTW89_RS_MCS, .ofdma = RTW89_NON_OFDMA }, + .num_of_idx = 14, + }, + { + .init = { .rs = RTW89_RS_HEDCM, .ofdma = RTW89_NON_OFDMA }, + .num_of_idx = RTW89_RATE_HEDCM_NUM, + }, + { + .init = { .rs = RTW89_RS_MCS, .ofdma = RTW89_OFDMA }, + .num_of_idx = 14, + }, + { + .init = { .rs = RTW89_RS_HEDCM, .ofdma = RTW89_OFDMA }, + .num_of_idx = RTW89_RATE_HEDCM_NUM, + }, +}; + +static +void __phy_set_txpwr_byrate_be(struct rtw89_dev *rtwdev, u8 band, u8 bw, + u8 nss, u32 *addr, enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_byr_spec_ent_be *ent; + struct rtw89_rate_desc desc; + int pos = 0; + int i, j; + u32 val; + s8 v[4]; + + for (i = 0; i < ARRAY_SIZE(rtw89_byr_spec_be); i++) { + ent = &rtw89_byr_spec_be[i]; + + if (bw > RTW89_CHANNEL_WIDTH_40 && ent->no_over_bw40) + continue; + if (nss > RTW89_NSS_1 && ent->no_multi_nss) + continue; + + desc = ent->init; + desc.nss = nss; + for (j = 0; j < ent->num_of_idx; j++, desc.idx++) { + v[pos] = rtw89_phy_read_txpwr_byrate(rtwdev, band, bw, + &desc); + pos = (pos + 1) % 4; + if (pos) + continue; + + val = u32_encode_bits(v[0], GENMASK(7, 0)) | + u32_encode_bits(v[1], GENMASK(15, 8)) | + u32_encode_bits(v[2], GENMASK(23, 16)) | + u32_encode_bits(v[3], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, *addr, val); + *addr += 4; + } + } +} + +static void rtw89_phy_set_txpwr_byrate_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u32 addr = R_BE_PWR_BY_RATE; + u8 band = chan->band_type; + u8 bw, nss; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr byrate on band %d\n", band); + + for (bw = 0; bw <= RTW89_CHANNEL_WIDTH_320; bw++) + for (nss = 0; nss <= RTW89_NSS_2; nss++) + __phy_set_txpwr_byrate_be(rtwdev, band, bw, nss, + &addr, phy_idx); +} + +static void rtw89_phy_set_txpwr_offset_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rate_desc desc = { + .nss = RTW89_NSS_1, + .rs = RTW89_RS_OFFSET, + }; + u8 band = chan->band_type; + s8 v[RTW89_RATE_OFFSET_NUM_BE] = {}; + u32 val; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr offset on band %d\n", band); + + for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_NUM_BE; desc.idx++) + v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, 0, &desc); + + val = u32_encode_bits(v[RTW89_RATE_OFFSET_CCK], GENMASK(3, 0)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_OFDM], GENMASK(7, 4)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_HT], GENMASK(11, 8)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_VHT], GENMASK(15, 12)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_HE], GENMASK(19, 16)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_EHT], GENMASK(23, 20)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_DLRU_HE], GENMASK(27, 24)) | + u32_encode_bits(v[RTW89_RATE_OFFSET_DLRU_EHT], GENMASK(31, 28)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_BE_PWR_RATE_OFST_CTRL, val); +} + +static void +fill_limit_nonbf_bf(struct rtw89_dev *rtwdev, s8 (*ptr)[RTW89_BF_NUM], + u8 band, u8 bw, u8 ntx, u8 rs, u8 ch) +{ + int bf; + + for (bf = 0; bf < RTW89_BF_NUM; bf++) + (*ptr)[bf] = rtw89_phy_read_txpwr_limit(rtwdev, band, bw, ntx, + rs, bf, ch); +} + +static void +fill_limit_nonbf_bf_min(struct rtw89_dev *rtwdev, s8 (*ptr)[RTW89_BF_NUM], + u8 band, u8 bw, u8 ntx, u8 rs, u8 ch1, u8 ch2) +{ + s8 v1[RTW89_BF_NUM]; + s8 v2[RTW89_BF_NUM]; + int bf; + + fill_limit_nonbf_bf(rtwdev, &v1, band, bw, ntx, rs, ch1); + fill_limit_nonbf_bf(rtwdev, &v2, band, bw, ntx, rs, ch2); + + for (bf = 0; bf < RTW89_BF_NUM; bf++) + (*ptr)[bf] = min(v1[bf], v2[bf]); +} + +static void phy_fill_limit_20m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_be *lmt, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_nonbf_bf(rtwdev, &lmt->cck_20m, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_CCK, ch); + fill_limit_nonbf_bf(rtwdev, &lmt->cck_40m, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_CCK, ch); + fill_limit_nonbf_bf(rtwdev, &lmt->ofdm, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, ch); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch); +} + +static void phy_fill_limit_40m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_be *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + fill_limit_nonbf_bf(rtwdev, &lmt->cck_20m, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_CCK, ch - 2); + fill_limit_nonbf_bf(rtwdev, &lmt->cck_40m, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_CCK, ch); + + fill_limit_nonbf_bf(rtwdev, &lmt->ofdm, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch); +} + +static void phy_fill_limit_80m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_be *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + fill_limit_nonbf_bf(rtwdev, &lmt->ofdm, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch); + + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_0p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch - 4, ch + 4); +} + +static void phy_fill_limit_160m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_be *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + fill_limit_nonbf_bf(rtwdev, &lmt->ofdm, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 14); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 10); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[4], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[5], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[6], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 10); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[7], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 14); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 12); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[2], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[3], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 12); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch - 8); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[1], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch + 8); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_160m[0], band, + RTW89_CHANNEL_WIDTH_160, ntx, RTW89_RS_MCS, ch); + + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_0p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch - 12, ch - 4); + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_2p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch + 4, ch + 12); +} + +static void phy_fill_limit_320m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_be *lmt, + u8 band, u8 ntx, u8 ch, u8 pri_ch) +{ + fill_limit_nonbf_bf(rtwdev, &lmt->ofdm, band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 30); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 26); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 22); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 18); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[4], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 14); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[5], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 10); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[6], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[7], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[8], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[9], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 6); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[10], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 10); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[11], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 14); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[12], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 18); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[13], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 22); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[14], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 26); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_20m[15], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 30); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 28); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 20); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[2], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 12); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[3], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[4], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[5], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 12); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[6], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 20); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_40m[7], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 28); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch - 24); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[1], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch - 8); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[2], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch + 8); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_80m[3], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch + 24); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_160m[0], band, + RTW89_CHANNEL_WIDTH_160, ntx, RTW89_RS_MCS, ch - 16); + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_160m[1], band, + RTW89_CHANNEL_WIDTH_160, ntx, RTW89_RS_MCS, ch + 16); + + fill_limit_nonbf_bf(rtwdev, &lmt->mcs_320m, band, + RTW89_CHANNEL_WIDTH_320, ntx, RTW89_RS_MCS, ch); + + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_0p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch - 28, ch - 20); + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_2p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch - 12, ch - 4); + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_4p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch + 4, ch + 12); + fill_limit_nonbf_bf_min(rtwdev, &lmt->mcs_40m_6p5, band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, + ch + 20, ch + 28); +} + +static void rtw89_phy_fill_limit_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_be *lmt, + u8 ntx) +{ + u8 band = chan->band_type; + u8 pri_ch = chan->primary_channel; + u8 ch = chan->channel; + u8 bw = chan->band_width; + + memset(lmt, 0, sizeof(*lmt)); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + phy_fill_limit_20m_be(rtwdev, lmt, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_40: + phy_fill_limit_40m_be(rtwdev, lmt, band, ntx, ch, pri_ch); + break; + case RTW89_CHANNEL_WIDTH_80: + phy_fill_limit_80m_be(rtwdev, lmt, band, ntx, ch, pri_ch); + break; + case RTW89_CHANNEL_WIDTH_160: + phy_fill_limit_160m_be(rtwdev, lmt, band, ntx, ch, pri_ch); + break; + case RTW89_CHANNEL_WIDTH_320: + phy_fill_limit_320m_be(rtwdev, lmt, band, ntx, ch, pri_ch); + break; + } +} + +static void rtw89_phy_set_txpwr_limit_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_txpwr_limit_be lmt; + const s8 *ptr; + u32 addr, val; + u8 i, j; + + BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_be) != + RTW89_TXPWR_LMT_PAGE_SIZE_BE); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit on band %d bw %d\n", + chan->band_type, chan->band_width); + + addr = R_BE_PWR_LMT; + for (i = 0; i <= RTW89_NSS_2; i++) { + rtw89_phy_fill_limit_be(rtwdev, chan, &lmt, i); + + ptr = (s8 *)&lmt; + for (j = 0; j < RTW89_TXPWR_LMT_PAGE_SIZE_BE; + j += 4, addr += 4, ptr += 4) { + val = u32_encode_bits(ptr[0], GENMASK(7, 0)) | + u32_encode_bits(ptr[1], GENMASK(15, 8)) | + u32_encode_bits(ptr[2], GENMASK(23, 16)) | + u32_encode_bits(ptr[3], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } +} + +static void fill_limit_ru_each(struct rtw89_dev *rtwdev, u8 index, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + lmt_ru->ru26[index] = + rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU26, ntx, ch); + lmt_ru->ru52[index] = + rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU52, ntx, ch); + lmt_ru->ru106[index] = + rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU106, ntx, ch); + lmt_ru->ru52_26[index] = + rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU52_26, ntx, ch); + lmt_ru->ru106_26[index] = + rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU106_26, ntx, ch); +} + +static void phy_fill_limit_ru_20m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_ru_each(rtwdev, 0, lmt_ru, band, ntx, ch); +} + +static void phy_fill_limit_ru_40m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_ru_each(rtwdev, 0, lmt_ru, band, ntx, ch - 2); + fill_limit_ru_each(rtwdev, 1, lmt_ru, band, ntx, ch + 2); +} + +static void phy_fill_limit_ru_80m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_ru_each(rtwdev, 0, lmt_ru, band, ntx, ch - 6); + fill_limit_ru_each(rtwdev, 1, lmt_ru, band, ntx, ch - 2); + fill_limit_ru_each(rtwdev, 2, lmt_ru, band, ntx, ch + 2); + fill_limit_ru_each(rtwdev, 3, lmt_ru, band, ntx, ch + 6); +} + +static void phy_fill_limit_ru_160m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_ru_each(rtwdev, 0, lmt_ru, band, ntx, ch - 14); + fill_limit_ru_each(rtwdev, 1, lmt_ru, band, ntx, ch - 10); + fill_limit_ru_each(rtwdev, 2, lmt_ru, band, ntx, ch - 6); + fill_limit_ru_each(rtwdev, 3, lmt_ru, band, ntx, ch - 2); + fill_limit_ru_each(rtwdev, 4, lmt_ru, band, ntx, ch + 2); + fill_limit_ru_each(rtwdev, 5, lmt_ru, band, ntx, ch + 6); + fill_limit_ru_each(rtwdev, 6, lmt_ru, band, ntx, ch + 10); + fill_limit_ru_each(rtwdev, 7, lmt_ru, band, ntx, ch + 14); +} + +static void phy_fill_limit_ru_320m_be(struct rtw89_dev *rtwdev, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 band, u8 ntx, u8 ch) +{ + fill_limit_ru_each(rtwdev, 0, lmt_ru, band, ntx, ch - 30); + fill_limit_ru_each(rtwdev, 1, lmt_ru, band, ntx, ch - 26); + fill_limit_ru_each(rtwdev, 2, lmt_ru, band, ntx, ch - 22); + fill_limit_ru_each(rtwdev, 3, lmt_ru, band, ntx, ch - 18); + fill_limit_ru_each(rtwdev, 4, lmt_ru, band, ntx, ch - 14); + fill_limit_ru_each(rtwdev, 5, lmt_ru, band, ntx, ch - 10); + fill_limit_ru_each(rtwdev, 6, lmt_ru, band, ntx, ch - 6); + fill_limit_ru_each(rtwdev, 7, lmt_ru, band, ntx, ch - 2); + fill_limit_ru_each(rtwdev, 8, lmt_ru, band, ntx, ch + 2); + fill_limit_ru_each(rtwdev, 9, lmt_ru, band, ntx, ch + 6); + fill_limit_ru_each(rtwdev, 10, lmt_ru, band, ntx, ch + 10); + fill_limit_ru_each(rtwdev, 11, lmt_ru, band, ntx, ch + 14); + fill_limit_ru_each(rtwdev, 12, lmt_ru, band, ntx, ch + 18); + fill_limit_ru_each(rtwdev, 13, lmt_ru, band, ntx, ch + 22); + fill_limit_ru_each(rtwdev, 14, lmt_ru, band, ntx, ch + 26); + fill_limit_ru_each(rtwdev, 15, lmt_ru, band, ntx, ch + 30); +} + +static void rtw89_phy_fill_limit_ru_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_ru_be *lmt_ru, + u8 ntx) +{ + u8 band = chan->band_type; + u8 ch = chan->channel; + u8 bw = chan->band_width; + + memset(lmt_ru, 0, sizeof(*lmt_ru)); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + phy_fill_limit_ru_20m_be(rtwdev, lmt_ru, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_40: + phy_fill_limit_ru_40m_be(rtwdev, lmt_ru, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_80: + phy_fill_limit_ru_80m_be(rtwdev, lmt_ru, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_160: + phy_fill_limit_ru_160m_be(rtwdev, lmt_ru, band, ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_320: + phy_fill_limit_ru_320m_be(rtwdev, lmt_ru, band, ntx, ch); + break; + } +} + +static +void rtw89_phy_fill_limit_ru484_242_be(struct rtw89_dev *rtwdev, + s8 (*lmt)[RTW89_RU484_242_SEC_NUM_BE], + u8 ntx, u8 band, u8 ch, u8 bw) +{ + switch (bw) { + case RTW89_CHANNEL_WIDTH_80: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_160: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch - 8); + (*lmt)[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch + 8); + break; + case RTW89_CHANNEL_WIDTH_320: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch - 24); + (*lmt)[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch - 8); + (*lmt)[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch + 8); + (*lmt)[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU484_242, + ntx, ch + 24); + break; + } +} + +static +void rtw89_phy_fill_limit_ru996_484_be(struct rtw89_dev *rtwdev, + s8 (*lmt)[RTW89_RU996_484_SEC_NUM_BE], + u8 ntx, u8 band, u8 ch, u8 bw) +{ + switch (bw) { + case RTW89_CHANNEL_WIDTH_160: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484, + ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_320: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484, + ntx, ch - 16); + (*lmt)[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484, + ntx, ch + 16); + break; + } +} + +static +void rtw89_phy_fill_limit_ru996_484_242_be(struct rtw89_dev *rtwdev, + s8 (*lmt)[RTW89_RU996_484_242_SEC_NUM_BE], + u8 ntx, u8 band, u8 ch, u8 bw) +{ + switch (bw) { + case RTW89_CHANNEL_WIDTH_160: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484_242, + ntx, ch); + break; + case RTW89_CHANNEL_WIDTH_320: + (*lmt)[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484_242, + ntx, ch - 16); + (*lmt)[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU996_484_242, + ntx, ch + 16); + break; + } +} + +static +void rtw89_phy_fill_limit_large_mru_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_large_mru_be *lmt, + bool has_bf) +{ + u8 band = chan->band_type; + u8 ch = chan->channel; + u8 bw = chan->band_width; + int i; + + memset(lmt, 0, sizeof(*lmt)); + + if (has_bf) + return; + + for (i = 0; i <= RTW89_NSS_2; i++) { + rtw89_phy_fill_limit_ru484_242_be(rtwdev, &lmt->ru484_242[i], + i, band, ch, bw); + rtw89_phy_fill_limit_ru996_484_be(rtwdev, &lmt->ru996_484[i], + i, band, ch, bw); + rtw89_phy_fill_limit_ru996_484_242_be(rtwdev, &lmt->ru996_484_242[i], + i, band, ch, bw); + } +} + +static +void rtw89_phy_conf_limit_large_mru_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx, + bool has_bf) +{ + struct rtw89_txpwr_limit_large_mru_be lmt_lmru; + u32 addr, val; + + rtw89_phy_fill_limit_large_mru_be(rtwdev, chan, &lmt_lmru, has_bf); + + addr = has_bf ? R_BE_TXAGC_MAX_1TX_BF_RU484_242_0 : + R_BE_TXAGC_MAX_1TX_RU484_242_0; + + val = u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_1][0], GENMASK(7, 0)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_1][1], GENMASK(15, 8)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_1][2], GENMASK(23, 16)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_1][3], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + + val = u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_2][0], GENMASK(7, 0)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_2][1], GENMASK(15, 8)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_2][2], GENMASK(23, 16)) | + u32_encode_bits(lmt_lmru.ru484_242[RTW89_NSS_2][3], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr + 4, val); + + addr = has_bf ? R_BE_TXAGC_MAX_1TX_BF_RU996_484_0 : + R_BE_TXAGC_MAX_1TX_RU996_484_0; + + val = u32_encode_bits(lmt_lmru.ru996_484[RTW89_NSS_1][0], GENMASK(7, 0)) | + u32_encode_bits(lmt_lmru.ru996_484[RTW89_NSS_1][1], GENMASK(15, 8)) | + u32_encode_bits(lmt_lmru.ru996_484[RTW89_NSS_2][0], GENMASK(23, 16)) | + u32_encode_bits(lmt_lmru.ru996_484[RTW89_NSS_2][1], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + + addr = has_bf ? R_BE_TXAGC_MAX_1TX_BF_RU996_484_242_0 : + R_BE_TXAGC_MAX_1TX_RU996_484_242_0; + + val = u32_encode_bits(lmt_lmru.ru996_484_242[RTW89_NSS_1][0], GENMASK(7, 0)) | + u32_encode_bits(lmt_lmru.ru996_484_242[RTW89_NSS_1][1], GENMASK(15, 8)) | + u32_encode_bits(lmt_lmru.ru996_484_242[RTW89_NSS_2][0], GENMASK(23, 16)) | + u32_encode_bits(lmt_lmru.ru996_484_242[RTW89_NSS_2][1], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); +} + +static void rtw89_phy_set_txpwr_limit_ru_be(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_txpwr_limit_ru_be lmt_ru; + struct rtw89_hal *hal = &rtwdev->hal; + const s8 *ptr; + u32 addr, val; + u8 i, j; + + BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ru_be) != + RTW89_TXPWR_LMT_RU_PAGE_SIZE_BE); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit ru on band %d bw %d\n", + chan->band_type, chan->band_width); + + addr = R_BE_PWR_RU_LMT; + for (i = 0; i <= RTW89_NSS_2; i++) { + rtw89_phy_fill_limit_ru_be(rtwdev, chan, &lmt_ru, i); + + ptr = (s8 *)&lmt_ru; + for (j = 0; j < RTW89_TXPWR_LMT_RU_PAGE_SIZE_BE; + j += 4, addr += 4, ptr += 4) { + val = u32_encode_bits(ptr[0], GENMASK(7, 0)) | + u32_encode_bits(ptr[1], GENMASK(15, 8)) | + u32_encode_bits(ptr[2], GENMASK(23, 16)) | + u32_encode_bits(ptr[3], GENMASK(31, 24)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } + + if (!(chip->chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)) + return; + + rtw89_phy_conf_limit_large_mru_be(rtwdev, chan, phy_idx, false); + rtw89_phy_conf_limit_large_mru_be(rtwdev, chan, phy_idx, true); +} + +const struct rtw89_phy_gen_def rtw89_phy_gen_be = { + .cr_base = 0x20000, + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START, + .physt_bmp_eht = R_PHY_STS_BITMAP_EHT, + .physt_ie_len = {32, 40, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, + VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 88, 56, VAR_LEN, + VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32}, + .physt_gen = 1, + .ccx = &rtw89_ccx_regs_be, + .physts = &rtw89_physts_regs_be, + .cfo = &rtw89_cfo_regs_be, + .bb_wrap = &rtw89_bb_wrap_regs_be, + .nctl = &rtw89_nctl_regs_be, + .phy0_phy1_offset = rtw89_phy0_phy1_offset_be, + .config_bb_gain = rtw89_phy_config_bb_gain_be, + .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_be, + .bb_wrap_init = rtw89_phy_bb_wrap_init_be, + .ch_info_init = rtw89_phy_ch_info_init_be, + + .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_be, + .set_txpwr_offset = rtw89_phy_set_txpwr_offset_be, + .set_txpwr_limit = rtw89_phy_set_txpwr_limit_be, + .set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_be, +}; +EXPORT_SYMBOL(rtw89_phy_gen_be); + +const struct rtw89_phy_gen_def rtw89_phy_gen_be_v1 = { + .cr_base = 0x0, + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START_BE4, + .physt_bmp_eht = R_PHY_STS_BITMAP_EHT_BE4, + .physt_ie_len = {32, 40, 24, 24, 16, 16, 16, 16, VAR_LEN, VAR_LEN, VAR_LEN, 168, + VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 32, 56, + 96, VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32}, + .physt_gen = 2, + .ccx = &rtw89_ccx_regs_be_v1, + .physts = &rtw89_physts_regs_be_v1, + .cfo = &rtw89_cfo_regs_be_v1, + .bb_wrap = &rtw89_bb_wrap_regs_be_v1, + .nctl = &rtw89_nctl_regs_be_v1, + .phy0_phy1_offset = rtw89_phy0_phy1_offset_be_v1, + .config_bb_gain = rtw89_phy_config_bb_gain_be, + .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_be_v1, + .bb_wrap_init = rtw89_phy_bb_wrap_init_be, + .ch_info_init = rtw89_phy_ch_info_init_be_v1, + + .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_be, + .set_txpwr_offset = rtw89_phy_set_txpwr_offset_be, + .set_txpwr_limit = rtw89_phy_set_txpwr_limit_be, + .set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_be, +}; +EXPORT_SYMBOL(rtw89_phy_gen_be_v1); diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c new file mode 100644 index 000000000..31bb5dcd2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "core.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "ser.h" +#include "util.h" + +static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid) +{ + struct rtw89_mac_c2h_info c2h_info = {.timeout = 5000}; + u16 c2hreg_macid; + u32 c2hreg_ret; + int ret; + + if (!RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw)) + return 0; + + c2h_info.id = RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK; + ret = rtw89_fw_msg_reg(rtwdev, NULL, &c2h_info); + if (ret) + goto fw_fail; + + c2hreg_macid = u32_get_bits(c2h_info.u.c2hreg[0], + RTW89_C2HREG_PS_LEAVE_ACK_MACID); + c2hreg_ret = u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_PS_LEAVE_ACK_RET); + + if (macid != c2hreg_macid || c2hreg_ret) { + rtw89_warn(rtwdev, "rtw89: check lps h2c received by firmware fail\n"); + ret = -EINVAL; + goto fw_fail; + } + rtwdev->ps_hang_cnt = 0; + + return 0; + +fw_fail: + rtwdev->ps_hang_cnt++; + if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT) + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); + + return ret; +} + +static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 pwr_en_bit = 0xE; + u32 chk_msk = pwr_en_bit << (4 * macid); + u32 polling; + int ret; + + ret = read_poll_timeout_atomic(rtw89_read32_mask, polling, !polling, + 1000, 50000, false, rtwdev, + mac->ps_status, chk_msk); + if (ret) { + rtw89_info(rtwdev, "rtw89: failed to leave lps state\n"); + + rtwdev->ps_hang_cnt++; + if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT) + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); + + return -EBUSY; + } + + rtwdev->ps_hang_cnt = 0; + + return 0; +} + +static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev, + bool enter) +{ + ieee80211_stop_queues(rtwdev->hw); + rtwdev->hci.paused = true; + flush_work(&rtwdev->txq_work); + ieee80211_wake_queues(rtwdev->hw); + + rtw89_hci_pause(rtwdev, true); + rtw89_mac_power_mode_change(rtwdev, enter); + rtw89_hci_switch_mode(rtwdev, enter); + rtw89_hci_pause(rtwdev, false); + + rtwdev->hci.paused = false; + + if (!enter) { + local_bh_disable(); + napi_schedule(&rtwdev->napi); + local_bh_enable(); + } +} + +static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter) +{ + if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) && + !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) + rtw89_ps_power_mode_change_with_hci(rtwdev, enter); + else + rtw89_mac_power_mode_change(rtwdev, enter); +} + +void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev) +{ + if (!rtwdev->ps_mode) + return; + + if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) + return; + + rtw89_ps_power_mode_change(rtwdev, true); +} + +void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) +{ + if (!rtwdev->ps_mode) + return; + + if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) + rtw89_ps_power_mode_change(rtwdev, false); +} + +static void __rtw89_enter_lps_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_lps_parm lps_param = { + .macid = rtwvif_link->mac_id, + .psmode = RTW89_MAC_AX_PS_MODE_LEGACY, + .lastrpwm = RTW89_LAST_RPWM_PS, + }; + + rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL); + rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); + + if (RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw)) + rtw89_fw_h2c_pwr_lvl(rtwdev, rtwvif_link); +} + +static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_lps_parm lps_param = { + .macid = rtwvif_link->mac_id, + .psmode = RTW89_MAC_AX_PS_MODE_ACTIVE, + .lastrpwm = RTW89_LAST_RPWM_ACTIVE, + }; + + rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); + rtw89_fw_receive_lps_h2c_check(rtwdev, rtwvif_link->mac_id); + rtw89_fw_leave_lps_check(rtwdev, rtwvif_link->mac_id); + rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); + rtw89_chip_digital_pwr_comp(rtwdev, rtwvif_link->phy_idx); +} + +void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + __rtw89_leave_ps_mode(rtwdev); +} + +void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + bool ps_mode) +{ + struct rtw89_vif_link *rtwvif_link; + bool can_ps_mode = true; + unsigned int link_id; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) + return; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + __rtw89_enter_lps_link(rtwdev, rtwvif_link); + + if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + can_ps_mode = false; + } + + rtw89_fw_h2c_rf_ps_info(rtwdev, rtwvif); + + if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw)) + rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif); + else if (RTW89_CHK_FW_FEATURE(LPS_ML_INFO_V1, &rtwdev->fw)) + rtw89_fw_h2c_lps_ml_cmn_info_v1(rtwdev, rtwvif); + else + rtw89_fw_h2c_lps_ml_cmn_info(rtwdev, rtwvif); + + if (ps_mode && can_ps_mode) + __rtw89_enter_ps_mode(rtwdev); +} + +static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) + return; + + __rtw89_leave_lps(rtwdev, rtwvif_link); +} + +void rtw89_leave_lps(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) + return; + + __rtw89_leave_ps_mode(rtwdev); + + rtw89_phy_dm_reinit(rtwdev); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_leave_lps_vif(rtwdev, rtwvif_link); + + rtw89_fw_h2c_init_trx_protect(rtwdev); +} + +void rtw89_enter_ips(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + struct rtw89_hal *hal = &rtwdev->hal; + unsigned int link_id; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_INACTIVE_PS)) { + rtw89_debug(rtwdev, RTW89_DBG_PS, "skip enter IPS due to disabled_dm\n"); + return; + } + + set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); + + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_vif_deinit(rtwdev, rtwvif_link); + + rtw89_core_stop(rtwdev); +} + +void rtw89_leave_ips(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + int ret; + + if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return; + + ret = rtw89_core_start(rtwdev); + if (ret) + rtw89_err(rtwdev, "failed to leave idle state\n"); + + rtw89_set_channel(rtwdev); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_vif_init(rtwdev, rtwvif_link); + + clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); +} + +void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl) +{ + if (btc_ctrl) + rtw89_leave_lps(rtwdev); +} + +static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + enum rtw89_p2pps_action act) +{ + if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE) + return; + + if (act == RTW89_P2P_ACT_INIT) + rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, true); + else if (act == RTW89_P2P_ACT_TERMINATE) + rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false); +} + +void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) +{ + enum rtw89_p2pps_action act; + u8 oppps_ctwindow; + u8 noa_id; + + rcu_read_lock(); + + if (!bss_conf) + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + oppps_ctwindow = bss_conf->p2p_noa_attr.oppps_ctwindow; + + rcu_read_unlock(); + + if (rtwvif_link->last_noa_nr == 0) + return; + + for (noa_id = 0; noa_id < rtwvif_link->last_noa_nr; noa_id++) { + if (noa_id == rtwvif_link->last_noa_nr - 1) + act = RTW89_P2P_ACT_TERMINATE; + else + act = RTW89_P2P_ACT_REMOVE; + rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, NULL, + act, noa_id, oppps_ctwindow); + } +} + +static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) +{ + struct ieee80211_p2p_noa_desc *desc; + enum rtw89_p2pps_action act; + u8 noa_id; + + for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) { + desc = &bss_conf->p2p_noa_attr.desc[noa_id]; + if (!desc->count || !desc->duration) + break; + + if (noa_id == 0) + act = RTW89_P2P_ACT_INIT; + else + act = RTW89_P2P_ACT_UPDATE; + rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, desc, act, noa_id, + bss_conf->p2p_noa_attr.oppps_ctwindow); + } + rtwvif_link->last_noa_nr = noa_id; +} + +void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) +{ + rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf); + rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf); +} + +void rtw89_recalc_lps(struct rtw89_dev *rtwdev) +{ + struct ieee80211_vif *vif, *found_vif = NULL; + struct rtw89_vif *rtwvif; + enum rtw89_entity_mode mode; + int count = 0; + + mode = rtw89_get_entity_mode(rtwdev); + if (mode == RTW89_ENTITY_MODE_MCC) + goto disable_lps; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + vif = rtwvif_to_vif(rtwvif); + + if (vif->type != NL80211_IFTYPE_STATION) { + count = 0; + break; + } + + count++; + found_vif = vif; + } + + if (count == 1 && found_vif->cfg.ps) { + rtwdev->lps_enabled = true; + return; + } + +disable_lps: + rtw89_leave_lps(rtwdev); + rtwdev->lps_enabled = false; +} + +void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; + struct rtw89_p2p_noa_ie *ie = &setter->ie; + struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head; + struct rtw89_noa_attr_head *noa_head = &ie->noa_head; + + if (setter->noa_count) { + setter->noa_index++; + setter->noa_count = 0; + } + + memset(ie, 0, sizeof(*ie)); + + p2p_head->eid = WLAN_EID_VENDOR_SPECIFIC; + p2p_head->ie_len = 4 + sizeof(*noa_head); + p2p_head->oui[0] = (WLAN_OUI_WFA >> 16) & 0xff; + p2p_head->oui[1] = (WLAN_OUI_WFA >> 8) & 0xff; + p2p_head->oui[2] = (WLAN_OUI_WFA >> 0) & 0xff; + p2p_head->oui_type = WLAN_OUI_TYPE_WFA_P2P; + + noa_head->attr_type = IEEE80211_P2P_ATTR_ABSENCE_NOTICE; + noa_head->attr_len = cpu_to_le16(2); + noa_head->index = setter->noa_index; + noa_head->oppps_ctwindow = 0; +} + +void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link, + const struct ieee80211_p2p_noa_desc *desc) +{ + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; + struct rtw89_p2p_noa_ie *ie = &setter->ie; + struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head; + struct rtw89_noa_attr_head *noa_head = &ie->noa_head; + + if (!desc->count || !desc->duration) + return; + + if (setter->noa_count >= RTW89_P2P_MAX_NOA_NUM) + return; + + p2p_head->ie_len += sizeof(*desc); + le16_add_cpu(&noa_head->attr_len, sizeof(*desc)); + + ie->noa_desc[setter->noa_count++] = *desc; +} + +u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data) +{ + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; + struct rtw89_p2p_noa_ie *ie = &setter->ie; + void *tail; + + if (!setter->noa_count) + return 0; + + *data = ie; + tail = ie->noa_desc + setter->noa_count; + return tail - *data; +} + +static void rtw89_ps_noa_once_set_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_ps_noa_once_handler *noa_once = + container_of(work, struct rtw89_ps_noa_once_handler, set_work.work); + + lockdep_assert_wiphy(wiphy); + + noa_once->in_duration = true; +} + +static void rtw89_ps_noa_once_clr_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct rtw89_ps_noa_once_handler *noa_once = + container_of(work, struct rtw89_ps_noa_once_handler, clr_work.work); + struct rtw89_vif_link *rtwvif_link = + container_of(noa_once, struct rtw89_vif_link, noa_once); + struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev; + + lockdep_assert_wiphy(wiphy); + + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + noa_once->in_duration = false; +} + +void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once; + + noa_once->in_duration = false; + noa_once->tsf_begin = 0; + noa_once->tsf_end = 0; + + wiphy_delayed_work_init(&noa_once->set_work, rtw89_ps_noa_once_set_work); + wiphy_delayed_work_init(&noa_once->clr_work, rtw89_ps_noa_once_clr_work); +} + +static void rtw89_p2p_noa_once_cancel(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once; + struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev; + struct wiphy *wiphy = rtwdev->hw->wiphy; + + wiphy_delayed_work_cancel(wiphy, &noa_once->set_work); + wiphy_delayed_work_cancel(wiphy, &noa_once->clr_work); +} + +void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link) +{ + rtw89_p2p_noa_once_cancel(rtwvif_link); + rtw89_p2p_noa_once_init(rtwvif_link); +} + +void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once; + struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev; + const struct ieee80211_p2p_noa_desc *noa_desc; + struct wiphy *wiphy = rtwdev->hw->wiphy; + struct ieee80211_bss_conf *bss_conf; + u64 tsf_begin = U64_MAX, tsf_end; + u64 set_delay_us = 0; + u64 clr_delay_us = 0; + u32 start_time; + u32 interval; + u32 duration; + u64 tsf; + int ret; + int i; + + lockdep_assert_wiphy(wiphy); + + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); + if (ret) { + rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__); + return; + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + for (i = 0; i < ARRAY_SIZE(bss_conf->p2p_noa_attr.desc); i++) { + bool first = tsf_begin == U64_MAX; + u64 tmp; + + noa_desc = &bss_conf->p2p_noa_attr.desc[i]; + if (noa_desc->count == 0 || noa_desc->count == 255) + continue; + + start_time = le32_to_cpu(noa_desc->start_time); + interval = le32_to_cpu(noa_desc->interval); + duration = le32_to_cpu(noa_desc->duration); + + if (unlikely(duration == 0 || + (noa_desc->count > 1 && interval == 0))) + continue; + + tmp = start_time + interval * (noa_desc->count - 1) + duration; + tmp = (tsf & GENMASK_ULL(63, 32)) + tmp; + if (unlikely(tmp <= tsf)) + continue; + tsf_end = first ? tmp : max(tsf_end, tmp); + + tmp = (tsf & GENMASK_ULL(63, 32)) | start_time; + tsf_begin = first ? tmp : min(tsf_begin, tmp); + } + + rcu_read_unlock(); + + if (tsf_begin == U64_MAX) + return; + + rtw89_p2p_noa_once_cancel(rtwvif_link); + + if (noa_once->tsf_end > tsf) { + tsf_begin = min(tsf_begin, noa_once->tsf_begin); + tsf_end = max(tsf_end, noa_once->tsf_end); + } + + clr_delay_us = min_t(u64, tsf_end - tsf, UINT_MAX); + + if (tsf_begin <= tsf) { + noa_once->in_duration = true; + goto out; + } + + set_delay_us = tsf_begin - tsf; + if (unlikely(set_delay_us > UINT_MAX)) { + rtw89_warn(rtwdev, "%s: unhandled begin\n", __func__); + set_delay_us = 0; + clr_delay_us = 0; + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + noa_once->in_duration = false; + } + +out: + if (set_delay_us) + wiphy_delayed_work_queue(wiphy, &noa_once->set_work, + usecs_to_jiffies(set_delay_us)); + if (clr_delay_us) + wiphy_delayed_work_queue(wiphy, &noa_once->clr_work, + usecs_to_jiffies(clr_delay_us)); + + noa_once->tsf_begin = tsf_begin; + noa_once->tsf_end = tsf_end; +} diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h new file mode 100644 index 000000000..729477153 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/ps.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_PS_H_ +#define __RTW89_PS_H_ + +void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + bool ps_mode); +void rtw89_leave_lps(struct rtw89_dev *rtwdev); +void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); +void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev); +void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); +void rtw89_enter_ips(struct rtw89_dev *rtwdev); +void rtw89_leave_ips(struct rtw89_dev *rtwdev); +void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); +void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf); +void rtw89_recalc_lps(struct rtw89_dev *rtwdev); +void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link); +void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link, + const struct ieee80211_p2p_noa_desc *desc); +u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data); +void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link); +void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link); +void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link); +void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf); + +static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev) +{ + struct ieee80211_hw *hw = rtwdev->hw; + + if (hw->conf.flags & IEEE80211_CONF_IDLE) + rtw89_leave_ips(rtwdev); +} + +static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev) +{ + struct ieee80211_hw *hw = rtwdev->hw; + + /* prevent entering IPS after ROC, but it is scanning */ + if (rtwdev->scanning) + return; + + if (hw->conf.flags & IEEE80211_CONF_IDLE) + rtw89_enter_ips(rtwdev); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h new file mode 100644 index 000000000..abeeb6100 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -0,0 +1,11104 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_REG_H__ +#define __RTW89_REG_H__ + +#define R_AX_SYS_WL_EFUSE_CTRL 0x000A +#define B_AX_AUTOLOAD_SUS BIT(5) + +#define R_AX_SYS_ISO_CTRL 0x0000 +#define B_AX_PWC_EV2EF_MASK GENMASK(15, 14) +#define B_AX_PWC_EV2EF_B15 BIT(15) +#define B_AX_PWC_EV2EF_B14 BIT(14) +#define B_AX_ISO_EB2CORE BIT(8) + +#define R_AX_SYS_FUNC_EN 0x0002 +#define B_AX_FEN_BB_GLB_RSTN BIT(1) +#define B_AX_FEN_BBRSTB BIT(0) + +#define R_AX_SYS_PW_CTRL 0x0004 +#define B_AX_SOP_ASWRM BIT(31) +#define B_AX_SOP_PWMM_DSWR BIT(29) +#define B_AX_SOP_EDSWR BIT(28) +#define B_AX_XTAL_OFF_A_DIE BIT(22) +#define B_AX_DIS_WLBT_PDNSUSEN_SOPC BIT(18) +#define B_AX_RDY_SYSPWR BIT(17) +#define B_AX_EN_WLON BIT(16) +#define B_AX_APDM_HPDN BIT(15) +#define B_AX_PSUS_OFF_CAPC_EN BIT(14) +#define B_AX_AFSM_PCIE_SUS_EN BIT(12) +#define B_AX_AFSM_WLSUS_EN BIT(11) +#define B_AX_APFM_SWLPS BIT(10) +#define B_AX_APFM_OFFMAC BIT(9) +#define B_AX_APFN_ONMAC BIT(8) + +#define R_AX_SYS_CLK_CTRL 0x0008 +#define B_AX_CPU_CLK_EN BIT(14) + +#define R_AX_SYS_SWR_CTRL1 0x0010 +#define B_AX_SYM_CTRL_SPS_PWMFREQ BIT(10) + +#define R_AX_SYS_ADIE_PAD_PWR_CTRL 0x0018 +#define B_AX_SYM_PADPDN_WL_PTA_1P3 BIT(6) +#define B_AX_SYM_PADPDN_WL_RFC_1P3 BIT(5) + +#define R_AX_RSV_CTRL 0x001C +#define B_AX_R_DIS_PRST BIT(6) +#define B_AX_WLOCK_1C_BIT6 BIT(5) + +#define R_AX_AFE_LDO_CTRL 0x0020 +#define B_AX_AON_OFF_PC_EN BIT(23) + +#define R_AX_EFUSE_CTRL_1 0x0038 +#define B_AX_EF_PGPD_MASK GENMASK(30, 28) +#define B_AX_EF_RDT BIT(27) +#define B_AX_EF_VDDQST_MASK GENMASK(26, 24) +#define B_AX_EF_PGTS_MASK GENMASK(23, 20) +#define B_AX_EF_PD_DIS BIT(11) +#define B_AX_EF_POR BIT(10) +#define B_AX_EF_CELL_SEL_MASK GENMASK(9, 8) + +#define R_AX_EFUSE_CTRL 0x0030 +#define B_AX_EF_MODE_SEL_MASK GENMASK(31, 30) +#define B_AX_EF_RDY BIT(29) +#define B_AX_EF_COMP_RESULT BIT(28) +#define B_AX_EF_ADDR_MASK GENMASK(26, 16) +#define B_AX_EF_DATA_MASK GENMASK(15, 0) + +#define R_AX_EFUSE_CTRL_1_V1 0x0038 +#define B_AX_EF_ENT BIT(31) +#define B_AX_EF_BURST BIT(19) +#define B_AX_EF_TEST_SEL_MASK GENMASK(18, 16) +#define B_AX_EF_TROW_EN BIT(15) +#define B_AX_EF_ERR_FLAG BIT(14) +#define B_AX_EF_DSB_EN BIT(11) +#define B_AX_PCIE_CALIB_EN_V1 BIT(12) +#define B_AX_WDT_WAKE_PCIE_EN BIT(10) +#define B_AX_WDT_WAKE_USB_EN BIT(9) + +#define R_AX_GPIO_MUXCFG 0x0040 +#define B_AX_BOOT_MODE BIT(19) +#define B_AX_WL_EECS_EXT_32K_SEL BIT(18) +#define B_AX_WL_SEC_BONDING_OPT_STS BIT(17) +#define B_AX_SECSIC_SEL BIT(16) +#define B_AX_ENHTP BIT(14) +#define B_AX_BT_AOD_GPIO3 BIT(13) +#define B_AX_ENSIC BIT(12) +#define B_AX_SIC_SWRST BIT(11) +#define B_AX_PO_WIFI_PTA_PINS BIT(10) +#define B_AX_PO_BT_PTA_PINS BIT(9) +#define B_AX_ENUARTTX BIT(8) +#define B_AX_BTMODE_MASK GENMASK(7, 6) +#define MAC_AX_BT_MODE_0_3 0 +#define MAC_AX_BT_MODE_2 2 +#define MAC_AX_RTK_MODE 0 +#define MAC_AX_CSR_MODE 1 +#define B_AX_ENBT BIT(5) +#define B_AX_EROM_EN BIT(4) +#define B_AX_ENUARTRX BIT(2) +#define B_AX_GPIOSEL_MASK GENMASK(1, 0) + +#define R_AX_DBG_CTRL 0x0058 +#define B_AX_DBG_SEL1_4BIT GENMASK(31, 30) +#define B_AX_DBG_SEL1_16BIT BIT(27) +#define B_AX_DBG_SEL1 GENMASK(23, 16) +#define B_AX_DBG_SEL0_4BIT GENMASK(15, 14) +#define B_AX_DBG_SEL0_16BIT BIT(11) +#define B_AX_DBG_SEL0 GENMASK(7, 0) + +#define R_AX_GPIO_EXT_CTRL 0x0060 +#define B_AX_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24) +#define B_AX_GPIO_MOD_9 BIT(25) +#define B_AX_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16) +#define B_AX_GPIO_IO_SEL_9 BIT(17) +#define B_AX_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8) +#define B_AX_GPIO_IN_15_TO_8_MASK GENMASK(7, 0) +#define B_AX_GPIO_IN_9 BIT(1) + +#define R_AX_SYS_SDIO_CTRL 0x0070 +#define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15) +#define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14) +#define B_AX_PCIE_FORCE_PWR_NGAT BIT(13) +#define B_AX_PCIE_CALIB_EN_V1 BIT(12) +#define B_AX_PCIE_AUXCLK_GATE BIT(11) +#define B_AX_LTE_MUX_CTRL_PATH BIT(26) + +#define R_AX_HCI_OPT_CTRL 0x0074 +#define BIT_WAKE_CTRL_V1 BIT(23) +#define BIT_WAKE_CTRL BIT(5) + +#define R_AX_HCI_BG_CTRL 0x0078 +#define B_AX_IBX_EN_VALUE BIT(15) +#define B_AX_IB_EN_VALUE BIT(14) +#define B_AX_FORCED_IB_EN BIT(4) +#define B_AX_EN_REGBG BIT(3) +#define B_AX_R_AX_BG_LPF BIT(2) +#define B_AX_R_AX_BG GENMASK(1, 0) + +#define R_AX_HCI_LDO_CTRL 0x007A +#define B_AX_R_AX_VADJ_MASK GENMASK(3, 0) + +#define R_AX_PLATFORM_ENABLE 0x0088 +#define B_AX_AXIDMA_EN BIT(3) +#define B_AX_APB_WRAP_EN BIT(2) +#define B_AX_WCPU_EN BIT(1) +#define B_AX_PLATFORM_EN BIT(0) + +#define R_AX_WLLPS_CTRL 0x0090 +#define B_AX_LPSOP_ASWRM BIT(17) +#define B_AX_LPSOP_DSWRM BIT(9) +#define B_AX_FORCE_LEAVE_LPS BIT(3) +#define B_AX_DIS_WLBT_LPSEN_LOPC BIT(1) +#define SW_LPS_OPTION 0x0001A0B2 + +#define R_AX_SCOREBOARD 0x00AC +#define B_AX_TOGGLE BIT(31) +#define B_MAC_AX_SB_FW_MASK GENMASK(30, 24) +#define B_MAC_AX_SB_DRV_MASK GENMASK(23, 0) +#define B_MAC_AX_BTGS1_NOTIFY BIT(0) +#define MAC_AX_NOTIFY_TP_MAJOR 0x81 +#define MAC_AX_NOTIFY_PWR_MAJOR 0x80 + +#define R_AX_DBG_PORT_SEL 0x00C0 +#define B_AX_DEBUG_ST_MASK GENMASK(31, 0) + +#define R_AX_PAD_CTRL2 0x00C4 +#define B_AX_FORCE_U3_CK BIT(23) +#define B_AX_USB2_FORCE BIT(22) +#define B_AX_USB3_FORCE BIT(21) +#define B_AX_USB3_USB2_TRANSITION BIT(20) +#define B_AX_USB23_SW_MODE_V1 GENMASK(19, 18) +#define USB_MODE_U2 0x1 +#define USB_MODE_U3 0x2 +#define B_AX_NO_PDN_CHIPOFF_V1 BIT(17) +#define B_AX_RSM_EN_V1 BIT(16) +#define B_AX_MATCH_CNT GENMASK(15, 8) +#define USB_SWITCH_DELAY 0xF + +#define R_AX_PMC_DBG_CTRL2 0x00CC +#define B_AX_SYSON_DIS_PMCR_AX_WRMSK BIT(2) + +#define R_AX_PCIE_MIO_INTF 0x00E4 +#define B_AX_PCIE_MIO_ADDR_PAGE_V1_MASK GENMASK(20, 16) +#define B_AX_PCIE_MIO_BYIOREG BIT(13) +#define B_AX_PCIE_MIO_RE BIT(12) +#define B_AX_PCIE_MIO_WE_MASK GENMASK(11, 8) +#define MIO_WRITE_BYTE_ALL 0xF +#define B_AX_PCIE_MIO_ADDR_MASK GENMASK(7, 0) +#define MIO_ADDR_PAGE_MASK GENMASK(12, 8) + +#define R_AX_PCIE_MIO_INTD 0x00E8 +#define B_AX_PCIE_MIO_DATA_MASK GENMASK(31, 0) + +#define R_AX_SYS_CFG1 0x00F0 +#define B_AX_CHIP_VER_MASK GENMASK(15, 12) + +#define R_AX_SYS_STATUS1 0x00F4 +#define B_AX_SEL_0XC0_MASK GENMASK(17, 16) +#define B_AX_AUTO_WLPON BIT(10) +#define B_AX_PAD_HCI_SEL_V2_MASK GENMASK(5, 3) +#define MAC_AX_HCI_SEL_SDIO_UART 0 +#define MAC_AX_HCI_SEL_MULTI_USB 1 +#define MAC_AX_HCI_SEL_PCIE_UART 2 +#define MAC_AX_HCI_SEL_PCIE_USB 3 +#define MAC_AX_HCI_SEL_MULTI_SDIO 4 + +#define R_AX_GPIO_16_TO_18_EXT_CTRL 0x0150 + +#define R_AX_HALT_H2C_CTRL 0x0160 +#define R_AX_HALT_H2C 0x0168 +#define B_AX_HALT_H2C_TRIGGER BIT(0) +#define R_AX_HALT_C2H_CTRL 0x0164 +#define R_AX_HALT_C2H 0x016C + +#define R_AX_WCPU_FW_CTRL 0x01E0 +#define B_AX_IDMEM_SHARE_MODE_RECORD_MASK GENMASK(27, 24) +#define B_AX_IDMEM_SHARE_MODE_RECORD_VALID BIT(23) +#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5) +#define B_AX_FWDL_PATH_RDY BIT(2) +#define B_AX_H2C_PATH_RDY BIT(1) +#define B_AX_WCPU_FWDL_EN BIT(0) + +#define R_AX_RPWM 0x01E4 +#define R_AX_PCIE_HRPWM 0x10C0 +#define PS_RPWM_TOGGLE BIT(15) +#define PS_RPWM_ACK BIT(14) +#define PS_RPWM_SEQ_NUM GENMASK(13, 12) +#define PS_RPWM_NOTIFY_WAKE BIT(8) +#define PS_RPWM_STATE 0x7 +#define RPWM_SEQ_NUM_MAX 3 +#define PS_CPWM_SEQ_NUM GENMASK(13, 12) +#define PS_CPWM_RSP_SEQ_NUM GENMASK(9, 8) +#define PS_CPWM_STATE GENMASK(2, 0) +#define CPWM_SEQ_NUM_MAX 3 + +#define R_AX_BOOT_REASON 0x01E6 +#define B_AX_BOOT_REASON_MASK GENMASK(2, 0) + +#define R_AX_LDM 0x01E8 +#define B_AX_EN_32K BIT(31) + +#define R_AX_UDM0 0x01F0 +#define R_AX_UDM1 0x01F4 +#define B_AX_UDM1_MASK GENMASK(31, 16) +#define B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK GENMASK(15, 12) +#define B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK GENMASK(11, 8) +#define B_AX_UDM1_WCPU_C2H_ENQ_CNT_MASK GENMASK(7, 4) +#define B_AX_UDM1_WCPU_H2C_DEQ_CNT_MASK GENMASK(3, 0) +#define R_AX_UDM2 0x01F8 +#define R_AX_UDM3 0x01FC + +#define R_AX_SPS_DIG_ON_CTRL0 0x0200 +#define B_AX_VREFPFM_L_MASK GENMASK(25, 22) +#define B_AX_REG_ZCDC_H_MASK GENMASK(18, 17) +#define B_AX_OCP_L1_MASK GENMASK(15, 13) +#define B_AX_VOL_L1_MASK GENMASK(3, 0) + +#define R_AX_SPSLDO_ON_CTRL1 0x0204 +#define B_AX_FPWMDELAY BIT(3) + +#define R_AX_LDO_AON_CTRL0 0x0218 +#define B_AX_PD_REGU_L BIT(16) + +#define R_AX_SPSANA_ON_CTRL1 0x0224 + +#define R_AX_SPS_ANA_ON_CTRL2 0x0228 +#define RTL8852B_RFE_05_SPS_ANA 0x4A82 + +#define R_AX_WLAN_XTAL_SI_CTRL 0x0270 +#define B_AX_WL_XTAL_SI_CMD_POLL BIT(31) +#define B_AX_BT_XTAL_SI_ERR_FLAG BIT(30) +#define B_AX_WL_XTAL_GNT BIT(29) +#define B_AX_BT_XTAL_GNT BIT(28) +#define B_AX_WL_XTAL_SI_MODE_MASK GENMASK(25, 24) +#define XTAL_SI_NORMAL_WRITE 0x00 +#define XTAL_SI_NORMAL_READ 0x01 +#define B_AX_WL_XTAL_SI_BITMASK_MASK GENMASK(23, 16) +#define B_AX_WL_XTAL_SI_DATA_MASK GENMASK(15, 8) +#define B_AX_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0) + +#define R_AX_WLAN_XTAL_SI_CONFIG 0x0274 +#define B_AX_XTAL_SI_ADDR_NOT_CHK BIT(0) + +#define R_AX_XTAL_ON_CTRL0 0x0280 +#define B_AX_XTAL_SC_LPS BIT(31) +#define B_AX_XTAL_SC_XO_MASK GENMASK(23, 17) +#define B_AX_XTAL_SC_XI_MASK GENMASK(16, 10) +#define B_AX_XTAL_SC_MASK GENMASK(6, 0) + +#define R_AX_XTAL_ON_CTRL3 0x028C +#define B_AX_XTAL_SC_INIT_A_BLOCK_MASK GENMASK(30, 24) +#define B_AX_XTAL_SC_LPS_A_BLOCK_MASK GENMASK(22, 16) +#define B_AX_XTAL_SC_XO_A_BLOCK_MASK GENMASK(14, 8) +#define B_AX_XTAL_SC_XI_A_BLOCK_MASK GENMASK(6, 0) + +#define R_AX_GPIO0_7_FUNC_SEL 0x02D0 + +#define R_AX_GPIO8_15_FUNC_SEL 0x02D4 +#define B_AX_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4) + +#define R_AX_EECS_EESK_FUNC_SEL 0x02D8 +#define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4) + +#define R_AX_GPIO16_23_FUNC_SEL 0x02D8 +#define B_AX_PINMUX_GPIO17_FUNC_SEL_MASK GENMASK(7, 4) +#define B_AX_PINMUX_GPIO16_FUNC_SEL_MASK GENMASK(3, 0) + +#define R_AX_LED1_FUNC_SEL 0x02DC +#define B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK GENMASK(27, 24) +#define PINMUX_EESK_FUNC_SEL_BT_LOG 0x1 + +#define R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN 0x02E4 +#define B_AX_LED1_PULL_LOW_EN BIT(18) +#define B_AX_EESK_PULL_LOW_EN BIT(17) +#define B_AX_EECS_PULL_LOW_EN BIT(16) + +#define R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN 0x02E4 +#define B_AX_GPIO16_PULL_LOW_EN_V1 BIT(19) +#define B_AX_GPIO10_PULL_LOW_EN BIT(10) + +#define R_AX_WLRF_CTRL 0x02F0 +#define B_AX_AFC_AFEDIG BIT(17) +#define B_AX_WLRF1_CTRL_7 BIT(15) +#define B_AX_WLRF1_CTRL_1 BIT(9) +#define B_AX_WLRF_CTRL_7 BIT(7) +#define B_AX_WLRF_CTRL_1 BIT(1) + +#define R_AX_IC_PWR_STATE 0x03F0 +#define B_AX_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) +#define B_AX_WLMAC_PWR_STE_MASK GENMASK(9, 8) +#define MAC_AX_MAC_OFF 0 +#define MAC_AX_MAC_ON 1 +#define MAC_AX_MAC_LPS 2 +#define B_AX_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6) +#define B_AX_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4) +#define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) +#define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) + +#define R_AX_SPS_DIG_OFF_CTRL0 0x0400 +#define B_AX_R1_L1_MASK GENMASK(7, 6) +#define B_AX_C3_L1_MASK GENMASK(5, 4) +#define B_AX_C2_L1_MASK GENMASK(3, 2) +#define B_AX_C1_L1_MASK GENMASK(1, 0) + +#define R_AX_AFE_OFF_CTRL1 0x0444 +#define B_AX_S1_LDO_VSEL_F_MASK GENMASK(25, 24) +#define B_AX_S1_LDO2PWRCUT_F BIT(23) +#define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21) + +#define R_AX_DBG_WOW 0x0504 +#define B_AX_DBG_WOW_CPU_IO_RX_EN BIT(8) + +#define R_AX_SEC_CTRL 0x0C00 +#define B_AX_SEC_IDMEM_SIZE_CONFIG_MASK GENMASK(17, 16) + +#define R_AX_FILTER_MODEL_ADDR 0x0C04 + +#define R_AX_HAXI_INIT_CFG1 0x1000 +#define B_AX_WD_ITVL_IDLE_V1_MASK GENMASK(31, 28) +#define B_AX_WD_ITVL_ACT_V1_MASK GENMASK(27, 24) +#define B_AX_DMA_MODE_MASK GENMASK(19, 18) +#define DMA_MOD_PCIE_1B 0x0 +#define DMA_MOD_PCIE_4B 0x1 +#define DMA_MOD_USB 0x2 +#define DMA_MOD_SDIO 0x3 +#define B_AX_STOP_AXI_MST BIT(17) +#define B_AX_HAXI_RST_KEEP_REG BIT(16) +#define B_AX_RXHCI_EN_V1 BIT(15) +#define B_AX_RXBD_MODE_V1 BIT(14) +#define B_AX_HAXI_MAX_RXDMA_MASK GENMASK(9, 8) +#define B_AX_TXHCI_EN_V1 BIT(7) +#define B_AX_FLUSH_AXI_MST BIT(4) +#define B_AX_RST_BDRAM BIT(3) +#define B_AX_HAXI_MAX_TXDMA_MASK GENMASK(1, 0) + +#define R_AX_HAXI_DMA_STOP1 0x1010 +#define B_AX_STOP_WPDMA BIT(19) +#define B_AX_STOP_CH12 BIT(18) +#define B_AX_STOP_CH9 BIT(17) +#define B_AX_STOP_CH8 BIT(16) +#define B_AX_STOP_ACH7 BIT(15) +#define B_AX_STOP_ACH6 BIT(14) +#define B_AX_STOP_ACH5 BIT(13) +#define B_AX_STOP_ACH4 BIT(12) +#define B_AX_STOP_ACH3 BIT(11) +#define B_AX_STOP_ACH2 BIT(10) +#define B_AX_STOP_ACH1 BIT(9) +#define B_AX_STOP_ACH0 BIT(8) + +#define R_AX_HAXI_DMA_BUSY1 0x101C +#define B_AX_HAXIIO_BUSY BIT(20) +#define B_AX_WPDMA_BUSY BIT(19) +#define B_AX_CH12_BUSY BIT(18) +#define B_AX_CH9_BUSY BIT(17) +#define B_AX_CH8_BUSY BIT(16) +#define B_AX_ACH7_BUSY BIT(15) +#define B_AX_ACH6_BUSY BIT(14) +#define B_AX_ACH5_BUSY BIT(13) +#define B_AX_ACH4_BUSY BIT(12) +#define B_AX_ACH3_BUSY BIT(11) +#define B_AX_ACH2_BUSY BIT(10) +#define B_AX_ACH1_BUSY BIT(9) +#define B_AX_ACH0_BUSY BIT(8) + +#define R_AX_USB_ENDPOINT_0 0x1060 +#define B_AX_EP_IDX GENMASK(3, 0) +#define R_AX_USB_ENDPOINT_2 0x1068 +#define NUMP 0x1 +#define R_AX_USB_HOST_REQUEST_2 0x1078 +#define B_AX_R_USBIO_MODE BIT(4) +#define R_AX_USB3_MAC_NPI_CONFIG_INTF_0 0x1114 +#define B_AX_SSPHY_LFPS_FILTER BIT(31) +#define R_AX_USB_WLAN0_1 0x1174 +#define B_AX_USBRX_RST BIT(9) +#define B_AX_USBTX_RST BIT(8) + +#define R_AX_PCIE_DBG_CTRL 0x11C0 +#define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) +#define B_AX_PCIE_DBG_SEL_MASK GENMASK(15, 13) +#define B_AX_MRD_TIMEOUT_EN BIT(10) +#define B_AX_ASFF_FULL_NO_STK BIT(1) +#define B_AX_EN_STUCK_DBG BIT(0) + +#define R_AX_HAXI_DMA_STOP2 0x11C0 +#define B_AX_STOP_CH11 BIT(1) +#define B_AX_STOP_CH10 BIT(0) + +#define R_AX_HAXI_DMA_BUSY2 0x11C8 +#define B_AX_CH11_BUSY BIT(1) +#define B_AX_CH10_BUSY BIT(0) + +#define R_AX_HAXI_DMA_BUSY3 0x1208 +#define B_AX_RPQ_BUSY BIT(1) +#define B_AX_RXQ_BUSY BIT(0) + +#define R_AX_LTR_DEC_CTRL 0x1600 +#define B_AX_LTR_IDX_DRV_VLD BIT(16) +#define B_AX_LTR_CURR_IDX_DRV_MASK GENMASK(15, 14) +#define B_AX_LTR_IDX_FW_VLD BIT(13) +#define B_AX_LTR_CURR_IDX_FW_MASK GENMASK(12, 11) +#define B_AX_LTR_IDX_HW_VLD BIT(10) +#define B_AX_LTR_CURR_IDX_HW_MASK GENMASK(9, 8) +#define B_AX_LTR_REQ_DRV BIT(7) +#define B_AX_LTR_IDX_DRV_MASK GENMASK(6, 5) +#define PCIE_LTR_IDX_IDLE 3 +#define B_AX_LTR_DRV_DEC_EN BIT(4) +#define B_AX_LTR_FW_DEC_EN BIT(3) +#define B_AX_LTR_HW_DEC_EN BIT(2) +#define B_AX_LTR_SPACE_IDX_V1_MASK GENMASK(1, 0) +#define LTR_EN_BITS (B_AX_LTR_HW_DEC_EN | B_AX_LTR_FW_DEC_EN | B_AX_LTR_DRV_DEC_EN) + +#define R_AX_LTR_LATENCY_IDX0 0x1604 +#define R_AX_LTR_LATENCY_IDX1 0x1608 +#define R_AX_LTR_LATENCY_IDX2 0x160C +#define R_AX_LTR_LATENCY_IDX3 0x1610 + +#define R_AX_HCI_FC_CTRL_V1 0x1700 +#define R_AX_CH_PAGE_CTRL_V1 0x1704 + +#define R_AX_ACH0_PAGE_CTRL_V1 0x1710 +#define R_AX_ACH1_PAGE_CTRL_V1 0x1714 +#define R_AX_ACH2_PAGE_CTRL_V1 0x1718 +#define R_AX_ACH3_PAGE_CTRL_V1 0x171C +#define R_AX_ACH4_PAGE_CTRL_V1 0x1720 +#define R_AX_ACH5_PAGE_CTRL_V1 0x1724 +#define R_AX_ACH6_PAGE_CTRL_V1 0x1728 +#define R_AX_ACH7_PAGE_CTRL_V1 0x172C +#define R_AX_CH8_PAGE_CTRL_V1 0x1730 +#define R_AX_CH9_PAGE_CTRL_V1 0x1734 +#define R_AX_CH10_PAGE_CTRL_V1 0x1738 +#define R_AX_CH11_PAGE_CTRL_V1 0x173C + +#define R_AX_ACH0_PAGE_INFO_V1 0x1750 +#define R_AX_ACH1_PAGE_INFO_V1 0x1754 +#define R_AX_ACH2_PAGE_INFO_V1 0x1758 +#define R_AX_ACH3_PAGE_INFO_V1 0x175C +#define R_AX_ACH4_PAGE_INFO_V1 0x1760 +#define R_AX_ACH5_PAGE_INFO_V1 0x1764 +#define R_AX_ACH6_PAGE_INFO_V1 0x1768 +#define R_AX_ACH7_PAGE_INFO_V1 0x176C +#define R_AX_CH8_PAGE_INFO_V1 0x1770 +#define R_AX_CH9_PAGE_INFO_V1 0x1774 +#define R_AX_CH10_PAGE_INFO_V1 0x1778 +#define R_AX_CH11_PAGE_INFO_V1 0x177C +#define R_AX_CH12_PAGE_INFO_V1 0x1780 + +#define R_AX_PUB_PAGE_INFO3_V1 0x178C +#define R_AX_PUB_PAGE_CTRL1_V1 0x1790 +#define R_AX_PUB_PAGE_CTRL2_V1 0x1794 +#define R_AX_PUB_PAGE_INFO1_V1 0x1798 +#define R_AX_PUB_PAGE_INFO2_V1 0x179C +#define R_AX_WP_PAGE_CTRL1_V1 0x17A0 +#define R_AX_WP_PAGE_CTRL2_V1 0x17A4 +#define R_AX_WP_PAGE_INFO1_V1 0x17A8 + +#define R_AX_USB_ENDPOINT_0_V1 0x5060 +#define B_AX_EP_IDX_V1 GENMASK(3, 0) +#define R_AX_USB_ENDPOINT_2_V1 0x5068 +#define R_AX_USB_HOST_REQUEST_2_V1 0x5078 +#define B_AX_R_USBIO_MODE_V1 BIT(4) +#define R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1 0x5114 +#define B_AX_SSPHY_LFPS_FILTER_V1 BIT(31) +#define R_AX_USB_WLAN0_1_V1 0x5174 +#define B_AX_USBRX_RST_V1 BIT(9) +#define B_AX_USBTX_RST_V1 BIT(8) + +#define R_AX_H2CREG_DATA0_V1 0x7140 +#define R_AX_H2CREG_DATA1_V1 0x7144 +#define R_AX_H2CREG_DATA2_V1 0x7148 +#define R_AX_H2CREG_DATA3_V1 0x714C +#define R_AX_C2HREG_DATA0_V1 0x7150 +#define R_AX_C2HREG_DATA1_V1 0x7154 +#define R_AX_C2HREG_DATA2_V1 0x7158 +#define R_AX_C2HREG_DATA3_V1 0x715C +#define R_AX_H2CREG_CTRL_V1 0x7160 +#define R_AX_C2HREG_CTRL_V1 0x7164 + +#define R_AX_HCI_FUNC_EN_V1 0x7880 + +#define R_AX_PHYREG_SET 0x8040 +#define PHYREG_SET_ALL_CYCLE 0x8 +#define PHYREG_SET_XYN_CYCLE 0xE + +#define R_AX_HD0IMR 0x8110 +#define B_AX_WDT_PTFM_INT_EN BIT(5) +#define B_AX_CPWM_INT_EN BIT(2) +#define B_AX_GT3_INT_EN BIT(1) +#define B_AX_C2H_INT_EN BIT(0) +#define R_AX_HD0ISR 0x8114 +#define B_AX_C2H_INT BIT(0) + +#define R_AX_H2CREG_DATA0 0x8140 +#define R_AX_H2CREG_DATA1 0x8144 +#define R_AX_H2CREG_DATA2 0x8148 +#define R_AX_H2CREG_DATA3 0x814C +#define R_AX_C2HREG_DATA0 0x8150 +#define R_AX_C2HREG_DATA1 0x8154 +#define R_AX_C2HREG_DATA2 0x8158 +#define R_AX_C2HREG_DATA3 0x815C +#define R_AX_H2CREG_CTRL 0x8160 +#define B_AX_H2CREG_TRIGGER BIT(0) +#define R_AX_C2HREG_CTRL 0x8164 +#define B_AX_C2HREG_TRIGGER BIT(0) +#define R_AX_CPWM 0x8170 + +#define R_AX_HCI_FUNC_EN 0x8380 +#define B_AX_HCI_RXDMA_EN BIT(1) +#define B_AX_HCI_TXDMA_EN BIT(0) + +#define R_AX_BOOT_DBG 0x83F0 + +#define R_AX_DMAC_FUNC_EN 0x8400 +#define B_AX_DMAC_CRPRT BIT(31) +#define B_AX_MAC_FUNC_EN BIT(30) +#define B_AX_DMAC_FUNC_EN BIT(29) +#define B_AX_MPDU_PROC_EN BIT(28) +#define B_AX_WD_RLS_EN BIT(27) +#define B_AX_DLE_WDE_EN BIT(26) +#define B_AX_TXPKT_CTRL_EN BIT(25) +#define B_AX_STA_SCH_EN BIT(24) +#define B_AX_DLE_PLE_EN BIT(23) +#define B_AX_PKT_BUF_EN BIT(22) +#define B_AX_DMAC_TBL_EN BIT(21) +#define B_AX_PKT_IN_EN BIT(20) +#define B_AX_DLE_CPUIO_EN BIT(19) +#define B_AX_DISPATCHER_EN BIT(18) +#define B_AX_BBRPT_EN BIT(17) +#define B_AX_MAC_SEC_EN BIT(16) +#define B_AX_DMACREG_GCKEN BIT(15) +#define B_AX_MAC_UN_EN BIT(15) +#define B_AX_H_AXIDMA_EN BIT(14) + +#define R_AX_DMAC_CLK_EN 0x8404 +#define B_AX_WD_RLS_CLK_EN BIT(27) +#define B_AX_DLE_WDE_CLK_EN BIT(26) +#define B_AX_TXPKT_CTRL_CLK_EN BIT(25) +#define B_AX_STA_SCH_CLK_EN BIT(24) +#define B_AX_DLE_PLE_CLK_EN BIT(23) +#define B_AX_PKT_IN_CLK_EN BIT(20) +#define B_AX_DLE_CPUIO_CLK_EN BIT(19) +#define B_AX_DISPATCHER_CLK_EN BIT(18) +#define B_AX_BBRPT_CLK_EN BIT(17) +#define B_AX_MAC_SEC_CLK_EN BIT(16) +#define B_AX_AXIDMA_CLK_EN BIT(9) + +#define PCI_LTR_IDLE_TIMER_1US 0 +#define PCI_LTR_IDLE_TIMER_10US 1 +#define PCI_LTR_IDLE_TIMER_100US 2 +#define PCI_LTR_IDLE_TIMER_200US 3 +#define PCI_LTR_IDLE_TIMER_400US 4 +#define PCI_LTR_IDLE_TIMER_800US 5 +#define PCI_LTR_IDLE_TIMER_1_6MS 6 +#define PCI_LTR_IDLE_TIMER_3_2MS 7 +#define PCI_LTR_IDLE_TIMER_R_ERR 0xFD +#define PCI_LTR_IDLE_TIMER_DEF 0xFE +#define PCI_LTR_IDLE_TIMER_IGNORE 0xFF + +#define PCI_LTR_SPC_10US 0 +#define PCI_LTR_SPC_100US 1 +#define PCI_LTR_SPC_500US 2 +#define PCI_LTR_SPC_1MS 3 +#define PCI_LTR_SPC_R_ERR 0xFD +#define PCI_LTR_SPC_DEF 0xFE +#define PCI_LTR_SPC_IGNORE 0xFF + +#define R_AX_LTR_CTRL_0 0x8410 +#define B_AX_LTR_SPACE_IDX_MASK GENMASK(13, 12) +#define B_AX_LTR_IDLE_TIMER_IDX_MASK GENMASK(10, 8) +#define B_AX_LTR_WD_NOEMP_CHK BIT(6) +#define B_AX_APP_LTR_ACT BIT(5) +#define B_AX_APP_LTR_IDLE BIT(4) +#define B_AX_LTR_EN BIT(1) +#define B_AX_LTR_WD_NOEMP_CHK_V1 BIT(1) +#define B_AX_LTR_HW_EN BIT(0) + +#define R_AX_LTR_CTRL_1 0x8414 +#define B_AX_LTR_RX1_TH_MASK GENMASK(27, 16) +#define B_AX_LTR_RX0_TH_MASK GENMASK(11, 0) + +#define R_AX_LTR_IDLE_LATENCY 0x8418 + +#define R_AX_LTR_ACTIVE_LATENCY 0x841C + +#define R_AX_SER_DBG_INFO 0x8424 +#define B_AX_L0_TO_L1_EVENT_MASK GENMASK(31, 28) +#define B_AX_SER_L1_COUNTER_MASK GENMASK(27, 24) +#define B_AX_RMAC_PPDU_HANG_CNT_MASK GENMASK(23, 16) +#define B_AX_SER_L0_COUNTER_MASK GENMASK(7, 0) + +#define R_AX_DLE_EMPTY0 0x8430 +#define B_AX_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26) +#define B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25) +#define B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24) +#define B_AX_PLE_EMPTY_QTA_DMAC_H2C BIT(23) +#define B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22) +#define B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21) +#define B_AX_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20) +#define B_AX_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19) +#define B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18) +#define B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17) +#define B_AX_WDE_EMPTY_QTA_DMAC_HIF BIT(16) +#define B_AX_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10) +#define B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9) +#define B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8) +#define B_AX_WDE_EMPTY_QUE_OTHERS BIT(7) +#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4) +#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3) +#define B_AX_WDE_EMPTY_QUE_CMAC1_MBH BIT(2) +#define B_AX_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) +#define B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) + +#define R_AX_DLE_EMPTY1 0x8434 +#define B_AX_PLE_EMPTY_QTA_DMAC_WDRLS BIT(20) +#define B_AX_PLE_EMPTY_QTA_CMAC1_DMA_BBRPT BIT(19) +#define B_AX_PLE_EMPTY_QTA_CMAC1_DMA_RX BIT(18) +#define B_AX_PLE_EMPTY_QTA_CMAC0_DMA_RX BIT(17) +#define B_AX_PLE_EMPTY_QTA_DMAC_C2H BIT(16) +#define B_AX_PLE_EMPTY_QUE_DMAC_PLRLS BIT(5) +#define B_AX_PLE_EMPTY_QUE_DMAC_CPUIO BIT(4) +#define B_AX_PLE_EMPTY_QUE_DMAC_SEC_RX BIT(3) +#define B_AX_PLE_EMPTY_QUE_DMAC_MPDU_RX BIT(2) +#define B_AX_PLE_EMPTY_QUE_DMAC_HDP BIT(1) +#define B_AX_WDE_EMPTY_QUE_DMAC_WDRLS BIT(0) + +#define R_AX_DMAC_ERR_IMR 0x8520 +#define B_AX_DLE_CPUIO_ERR_INT_EN BIT(10) +#define B_AX_APB_BRIDGE_ERR_INT_EN BIT(9) +#define B_AX_DISPATCH_ERR_INT_EN BIT(8) +#define B_AX_PKTIN_ERR_INT_EN BIT(7) +#define B_AX_PLE_DLE_ERR_INT_EN BIT(6) +#define B_AX_TXPKTCTRL_ERR_INT_EN BIT(5) +#define B_AX_WDE_DLE_ERR_INT_EN BIT(4) +#define B_AX_STA_SCHEDULER_ERR_INT_EN BIT(3) +#define B_AX_MPDU_ERR_INT_EN BIT(2) +#define B_AX_WSEC_ERR_INT_EN BIT(1) +#define B_AX_WDRLS_ERR_INT_EN BIT(0) +#define DMAC_ERR_IMR_EN GENMASK(31, 0) +#define DMAC_ERR_IMR_DIS 0 + +#define R_AX_DMAC_ERR_ISR 0x8524 +#define B_AX_HAXIDMA_ERR_FLAG BIT(14) +#define B_AX_PAXIDMA_ERR_FLAG BIT(13) +#define B_AX_HCI_BUF_ERR_FLAG BIT(12) +#define B_AX_BBRPT_ERR_FLAG BIT(11) +#define B_AX_DLE_CPUIO_ERR_FLAG BIT(10) +#define B_AX_APB_BRIDGE_ERR_FLAG BIT(9) +#define B_AX_DISPATCH_ERR_FLAG BIT(8) +#define B_AX_PKTIN_ERR_FLAG BIT(7) +#define B_AX_PLE_DLE_ERR_FLAG BIT(6) +#define B_AX_TXPKTCTRL_ERR_FLAG BIT(5) +#define B_AX_WDE_DLE_ERR_FLAG BIT(4) +#define B_AX_STA_SCHEDULER_ERR_FLAG BIT(3) +#define B_AX_MPDU_ERR_FLAG BIT(2) +#define B_AX_WSEC_ERR_FLAG BIT(1) +#define B_AX_WDRLS_ERR_FLAG BIT(0) + +#define R_AX_DISPATCHER_GLOBAL_SETTING_0 0x8800 +#define B_AX_PL_PAGE_128B_SEL BIT(9) +#define B_AX_WD_PAGE_64B_SEL BIT(8) +#define R_AX_OTHER_DISPATCHER_ERR_ISR 0x8804 +#define R_AX_HOST_DISPATCHER_ERR_ISR 0x8808 +#define R_AX_CPU_DISPATCHER_ERR_ISR 0x880C +#define R_AX_TX_ADDRESS_INFO_MODE_SETTING 0x8810 +#define B_AX_HOST_ADDR_INFO_8B_SEL BIT(0) + +#define R_AX_HOST_DISPATCHER_ERR_IMR 0x8850 +#define B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN BIT(31) +#define B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN BIT(30) +#define B_AX_HDT_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_HDT_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_HDT_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_HDT_TOTAL_LEN_ERR_INT_EN BIT(26) +#define B_AX_HDT_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_HDT_RXAGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_HDT_OUTPUT_ERR_INT_EN BIT(21) +#define B_AX_HDT_RES_ERR_INT_EN BIT(20) +#define B_AX_HDT_BURST_NUM_ERR_INT_EN BIT(19) +#define B_AX_HDT_NULLPKT_ERR_INT_EN BIT(18) +#define B_AX_HDT_FLOW_CTRL_ERR_INT_EN BIT(17) +#define B_AX_HDT_PLD_CMD_UNDERFLOW_INT_EN BIT(16) +#define B_AX_HDT_PLD_CMD_OVERLOW_INT_EN BIT(15) +#define B_AX_HDT_TX_WRITE_UNDERFLOW_INT_EN BIT(14) +#define B_AX_HDT_TX_WRITE_OVERFLOW_INT_EN BIT(13) +#define B_AX_HDT_TCP_CHK_ERR_INT_EN BIT(12) +#define B_AX_HDT_TXPKTSIZE_ERR_INT_EN BIT(11) +#define B_AX_HDT_PRE_COST_ERR_INT_EN BIT(10) +#define B_AX_HDT_WD_CHK_ERR_INT_EN BIT(9) +#define B_AX_HDT_CHANNEL_DMA_ERR_INT_EN BIT(8) +#define B_AX_HDT_OFFSET_UNMATCH_INT_EN BIT(7) +#define B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN BIT(6) +#define B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN BIT(5) +#define B_AX_HDT_PERMU_UNDERFLOW_INT_EN BIT(4) +#define B_AX_HDT_PERMU_OVERFLOW_INT_EN BIT(3) +#define B_AX_HDT_PKT_FAIL_DBG_INT_EN BIT(2) +#define B_AX_HDT_CHANNEL_ID_ERR_INT_EN BIT(1) +#define B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN BIT(0) +#define B_AX_HOST_DISP_IMR_CLR (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_HDT_CHANNEL_ID_ERR_INT_EN | \ + B_AX_HDT_PKT_FAIL_DBG_INT_EN | \ + B_AX_HDT_PERMU_OVERFLOW_INT_EN | \ + B_AX_HDT_PERMU_UNDERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_HDT_OFFSET_UNMATCH_INT_EN | \ + B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HDT_WD_CHK_ERR_INT_EN | \ + B_AX_HDT_PRE_COST_ERR_INT_EN | \ + B_AX_HDT_TXPKTSIZE_ERR_INT_EN | \ + B_AX_HDT_TCP_CHK_ERR_INT_EN | \ + B_AX_HDT_TX_WRITE_OVERFLOW_INT_EN | \ + B_AX_HDT_TX_WRITE_UNDERFLOW_INT_EN | \ + B_AX_HDT_PLD_CMD_OVERLOW_INT_EN | \ + B_AX_HDT_PLD_CMD_UNDERFLOW_INT_EN | \ + B_AX_HDT_FLOW_CTRL_ERR_INT_EN | \ + B_AX_HDT_NULLPKT_ERR_INT_EN | \ + B_AX_HDT_BURST_NUM_ERR_INT_EN | \ + B_AX_HDT_RXAGG_CFG_ERR_INT_EN | \ + B_AX_HDT_SHIFT_EN_ERR_INT_EN | \ + B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \ + B_AX_HDT_DMA_PROCESS_ERR_INT_EN | \ + B_AX_HDT_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_HDT_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN | \ + B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN) +#define B_AX_HOST_DISP_IMR_SET (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \ + B_AX_HDT_DMA_PROCESS_ERR_INT_EN) +#define B_AX_HOST_DISP_IMR_SET_V01 (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \ + B_AX_HDT_DMA_PROCESS_ERR_INT_EN | \ + B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN | \ + B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN) + +#define B_AX_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31) +#define B_AX_HR_WRFF_OVERFLOW_ERR_INT_EN BIT(30) +#define B_AX_HR_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_HR_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_HR_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(26) +#define B_AX_HR_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_HR_AGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_HR_DMA_RD_CNT_DEQ_ERR_INT_EN BIT(23) +#define B_AX_HR_PLD_LEN_ZERO_ERR_INT_EN BIT(22) +#define B_AX_HT_ILL_CH_ERR_INT_EN BIT(20) +#define B_AX_HT_ADDR_INFO_LEN_ERR_INT_EN BIT(18) +#define B_AX_HT_WD_LEN_OVER_ERR_INT_EN BIT(17) +#define B_AX_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(16) +#define B_AX_HT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(15) +#define B_AX_HT_WRFF_UNDERFLOW_ERR_INT_EN BIT(14) +#define B_AX_HT_WRFF_OVERFLOW_ERR_INT_EN BIT(13) +#define B_AX_HT_CHKSUM_FSM_ERR_INT_EN BIT(12) +#define B_AX_HT_TXPKTSIZE_ERR_INT_EN BIT(11) +#define B_AX_HT_PRE_SUB_ERR_INT_EN BIT(10) +#define B_AX_HT_WD_CHKSUM_ERR_INT_EN BIT(9) +#define B_AX_HT_CHANNEL_DMA_ERR_INT_EN BIT(8) +#define B_AX_HT_OFFSET_UNMATCH_ERR_INT_EN BIT(7) +#define B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_AX_HT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_AX_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_AX_HT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_AX_HT_PKT_FAIL_ERR_INT_EN BIT(2) +#define B_AX_HT_CH_ID_ERR_INT_EN BIT(1) +#define B_AX_HT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_AX_HOST_DISP_IMR_CLR_V1 (B_AX_HT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_HT_CH_ID_ERR_INT_EN | \ + B_AX_HT_PKT_FAIL_ERR_INT_EN | \ + B_AX_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_HT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_AX_HT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HT_WD_CHKSUM_ERR_INT_EN | \ + B_AX_HT_PRE_SUB_ERR_INT_EN | \ + B_AX_HT_TXPKTSIZE_ERR_INT_EN | \ + B_AX_HT_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HT_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_WD_LEN_OVER_ERR_INT_EN | \ + B_AX_HT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_HT_ILL_CH_ERR_INT_EN | \ + B_AX_HR_PLD_LEN_ZERO_ERR_INT_EN | \ + B_AX_HR_DMA_RD_CNT_DEQ_ERR_INT_EN | \ + B_AX_HR_AGG_CFG_ERR_INT_EN | \ + B_AX_HR_SHIFT_EN_ERR_INT_EN | \ + B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_HR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_HR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_HR_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_HR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_AX_HOST_DISP_IMR_SET_V1 (B_AX_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_HT_ILL_CH_ERR_INT_EN | \ + B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_HR_DMA_PROCESS_ERR_INT_EN) + +#define R_AX_CPU_DISPATCHER_ERR_IMR 0x8854 +#define B_AX_CPU_RX_WRITE_UNDERFLOW_INT_EN BIT(31) +#define B_AX_CPU_RX_WRITE_OVERFLOW_INT_EN BIT(30) +#define B_AX_CPU_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_CPU_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_CPU_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_CPU_TOTAL_LEN_ERR_INT_EN BIT(26) +#define B_AX_CPU_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_CPU_RXAGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_CPU_OUTPUT_ERR_INT_EN BIT(20) +#define B_AX_CPU_RESP_ERR_INT_EN BIT(19) +#define B_AX_CPU_BURST_NUM_ERR_INT_EN BIT(18) +#define B_AX_CPU_NULLPKT_ERR_INT_EN BIT(17) +#define B_AX_CPU_FLOW_CTRL_ERR_INT_EN BIT(16) +#define B_AX_CPU_F2P_SEQ_ERR_INT_EN BIT(15) +#define B_AX_CPU_F2P_QSEL_ERR_INT_EN BIT(14) +#define B_AX_CPU_PLD_CMD_UNDERFLOW_INT_EN BIT(13) +#define B_AX_CPU_PLD_CMD_OVERLOW_INT_EN BIT(12) +#define B_AX_CPU_PRE_COST_ERR_INT_EN BIT(11) +#define B_AX_CPU_WD_CHK_ERR_INT_EN BIT(10) +#define B_AX_CPU_CHANNEL_DMA_ERR_INT_EN BIT(9) +#define B_AX_CPU_OFFSET_UNMATCH_INT_EN BIT(8) +#define B_AX_CPU_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7) +#define B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN BIT(6) +#define B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN BIT(5) +#define B_AX_CPU_PERMU_UNDERFLOW_INT_EN BIT(4) +#define B_AX_CPU_PERMU_OVERFLOW_INT_EN BIT(3) +#define B_AX_CPU_CHANNEL_ID_ERR_INT_EN BIT(2) +#define B_AX_CPU_PKT_FAIL_DBG_INT_EN BIT(1) +#define B_AX_CPU_CHANNEL_DIFF_ERR_INT_EN BIT(0) +#define B_AX_CPU_DISP_IMR_CLR (B_AX_CPU_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_CPU_PKT_FAIL_DBG_INT_EN | \ + B_AX_CPU_CHANNEL_ID_ERR_INT_EN | \ + B_AX_CPU_PERMU_OVERFLOW_INT_EN | \ + B_AX_CPU_PERMU_UNDERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_CHKSUM_ERR_INT_EN | \ + B_AX_CPU_OFFSET_UNMATCH_INT_EN | \ + B_AX_CPU_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_CPU_WD_CHK_ERR_INT_EN | \ + B_AX_CPU_PRE_COST_ERR_INT_EN | \ + B_AX_CPU_PLD_CMD_OVERLOW_INT_EN | \ + B_AX_CPU_PLD_CMD_UNDERFLOW_INT_EN | \ + B_AX_CPU_F2P_QSEL_ERR_INT_EN | \ + B_AX_CPU_F2P_SEQ_ERR_INT_EN | \ + B_AX_CPU_FLOW_CTRL_ERR_INT_EN | \ + B_AX_CPU_NULLPKT_ERR_INT_EN | \ + B_AX_CPU_BURST_NUM_ERR_INT_EN | \ + B_AX_CPU_RXAGG_CFG_ERR_INT_EN | \ + B_AX_CPU_SHIFT_EN_ERR_INT_EN | \ + B_AX_CPU_TOTAL_LEN_ERR_INT_EN | \ + B_AX_CPU_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CPU_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_CPU_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_CPU_RX_WRITE_OVERFLOW_INT_EN | \ + B_AX_CPU_RX_WRITE_UNDERFLOW_INT_EN) +#define B_AX_CPU_DISP_IMR_SET (B_AX_CPU_PKT_FAIL_DBG_INT_EN | \ + B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_CPU_TOTAL_LEN_ERR_INT_EN) + +#define B_AX_CR_PLD_LEN_ERR_INT_EN BIT(30) +#define B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN BIT(28) +#define B_AX_CR_SHIFT_DMA_CFG_ERR_INT_EN BIT(27) +#define B_AX_CR_DMA_PROCESS_ERR_INT_EN BIT(26) +#define B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(25) +#define B_AX_CR_SHIFT_EN_ERR_INT_EN BIT(24) +#define B_AX_REUSE_FIFO_B_UNDER_ERR_INT_EN BIT(22) +#define B_AX_REUSE_FIFO_B_OVER_ERR_INT_EN BIT(21) +#define B_AX_REUSE_FIFO_A_UNDER_ERR_INT_EN BIT(20) +#define B_AX_REUSE_FIFO_A_OVER_ERR_INT_EN BIT(19) +#define B_AX_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN BIT(17) +#define B_AX_CT_WD_LEN_OVER_ERR_INT_EN BIT(16) +#define B_AX_CT_F2P_SEQ_ERR_INT_EN BIT(15) +#define B_AX_CT_F2P_QSEL_ERR_INT_EN BIT(14) +#define B_AX_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(13) +#define B_AX_CT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(12) +#define B_AX_CT_PRE_SUB_ERR_INT_EN BIT(11) +#define B_AX_CT_WD_CHKSUM_ERR_INT_EN BIT(10) +#define B_AX_CT_CHANNEL_DMA_ERR_INT_EN BIT(9) +#define B_AX_CT_OFFSET_UNMATCH_ERR_INT_EN BIT(8) +#define B_AX_CT_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7) +#define B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_AX_CT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_AX_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_AX_CT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_AX_CT_CH_ID_ERR_INT_EN BIT(2) +#define B_AX_CT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_AX_CPU_DISP_IMR_CLR_V1 (B_AX_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_CT_CH_ID_ERR_INT_EN | \ + B_AX_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_AX_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_CHKSUM_ERR_INT_EN | \ + B_AX_CT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_AX_CT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_CT_WD_CHKSUM_ERR_INT_EN | \ + B_AX_CT_PRE_SUB_ERR_INT_EN | \ + B_AX_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_CT_F2P_QSEL_ERR_INT_EN | \ + B_AX_CT_F2P_SEQ_ERR_INT_EN | \ + B_AX_CT_WD_LEN_OVER_ERR_INT_EN | \ + B_AX_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN | \ + B_AX_REUSE_FIFO_A_OVER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_A_UNDER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_B_OVER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_B_UNDER_ERR_INT_EN | \ + B_AX_CR_SHIFT_EN_ERR_INT_EN | \ + B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_CR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_CR_PLD_LEN_ERR_INT_EN) +#define B_AX_CPU_DISP_IMR_SET_V1 (B_AX_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_CR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN) + +#define R_AX_OTHER_DISPATCHER_ERR_IMR 0x8858 +#define B_AX_OTHER_STF_WROQT_UNDERFLOW_INT_EN BIT(29) +#define B_AX_OTHER_STF_WROQT_OVERFLOW_INT_EN BIT(28) +#define B_AX_OTHER_STF_WRFF_UNDERFLOW_INT_EN BIT(27) +#define B_AX_OTHER_STF_WRFF_OVERFLOW_INT_EN BIT(26) +#define B_AX_OTHER_STF_CMD_UNDERFLOW_INT_EN BIT(25) +#define B_AX_OTHER_STF_CMD_OVERFLOW_INT_EN BIT(24) +#define B_AX_HOST_ADDR_INFO_LEN_ZERO_ERR_INT_EN BIT(17) +#define B_AX_CPU_ADDR_INFO_LEN_ZERO_ERR_INT_EN BIT(16) +#define B_AX_PLE_OUTPUT_ERR_INT_EN BIT(12) +#define B_AX_PLE_RESP_ERR_INT_EN BIT(11) +#define B_AX_PLE_BURST_NUM_ERR_INT_EN BIT(10) +#define B_AX_PLE_NULL_PKT_ERR_INT_EN BIT(9) +#define B_AX_PLE_FLOW_CTRL_ERR_INT_EN BIT(8) +#define B_AX_WDE_OUTPUT_ERR_INT_EN BIT(4) +#define B_AX_WDE_RESP_ERR_INT_EN BIT(3) +#define B_AX_WDE_BURST_NUM_ERR_INT_EN BIT(2) +#define B_AX_WDE_NULL_PKT_ERR_INT_EN BIT(1) +#define B_AX_WDE_FLOW_CTRL_ERR_INT_EN BIT(0) +#define B_AX_OTHER_DISP_IMR_CLR (B_AX_OTHER_STF_WROQT_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_WROQT_OVERFLOW_INT_EN | \ + B_AX_OTHER_STF_WRFF_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_WRFF_OVERFLOW_INT_EN | \ + B_AX_OTHER_STF_CMD_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_CMD_OVERFLOW_INT_EN | \ + B_AX_HOST_ADDR_INFO_LEN_ZERO_ERR_INT_EN | \ + B_AX_CPU_ADDR_INFO_LEN_ZERO_ERR_INT_EN | \ + B_AX_PLE_OUTPUT_ERR_INT_EN | \ + B_AX_PLE_RESP_ERR_INT_EN | \ + B_AX_PLE_BURST_NUM_ERR_INT_EN | \ + B_AX_PLE_NULL_PKT_ERR_INT_EN | \ + B_AX_PLE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_WDE_OUTPUT_ERR_INT_EN | \ + B_AX_WDE_RESP_ERR_INT_EN | \ + B_AX_WDE_BURST_NUM_ERR_INT_EN | \ + B_AX_WDE_NULL_PKT_ERR_INT_EN | \ + B_AX_WDE_FLOW_CTRL_ERR_INT_EN) + +#define B_AX_REUSE_SIZE_ERR_INT_EN BIT(31) +#define B_AX_REUSE_EN_ERR_INT_EN BIT(30) +#define B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_AX_STF_OQT_OVERFLOW_ERR_INT_EN BIT(28) +#define B_AX_STF_WRFF_UNDERFLOW_ERR_INT_EN BIT(27) +#define B_AX_STF_WRFF_OVERFLOW_ERR_INT_EN BIT(26) +#define B_AX_STF_CMD_UNDERFLOW_ERR_INT_EN BIT(25) +#define B_AX_STF_CMD_OVERFLOW_ERR_INT_EN BIT(24) +#define B_AX_REUSE_SIZE_ZERO_ERR_INT_EN BIT(23) +#define B_AX_REUSE_PKT_CNT_ERR_INT_EN BIT(22) +#define B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN BIT(21) +#define B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN BIT(20) +#define B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN BIT(19) +#define B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN BIT(18) +#define B_AX_CDT_ADDR_INFO_LEN_ERR_INT_EN BIT(17) +#define B_AX_HDT_ADDR_INFO_LEN_ERR_INT_EN BIT(16) +#define B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN BIT(15) +#define B_AX_CDR_RX_TIMEOUT_ERR_INT_EN BIT(14) +#define B_AX_PLE_RESPOSE_ERR_INT_EN BIT(11) +#define B_AX_HDR_DMA_TIMEOUT_ERR_INT_EN BIT(7) +#define B_AX_HDR_RX_TIMEOUT_ERR_INT_EN BIT(6) +#define B_AX_WDE_RESPONSE_ERR_INT_EN BIT(3) +#define B_AX_OTHER_DISP_IMR_CLR_V1 (B_AX_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_WDE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_WDE_NULL_PKT_ERR_INT_EN | \ + B_AX_WDE_BURST_NUM_ERR_INT_EN | \ + B_AX_WDE_RESPONSE_ERR_INT_EN | \ + B_AX_WDE_OUTPUT_ERR_INT_EN | \ + B_AX_HDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_HDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_PLE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_PLE_NULL_PKT_ERR_INT_EN | \ + B_AX_PLE_BURST_NUM_ERR_INT_EN | \ + B_AX_PLE_RESPOSE_ERR_INT_EN | \ + B_AX_PLE_OUTPUT_ERR_INT_EN | \ + B_AX_CDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_CDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_REUSE_PKT_CNT_ERR_INT_EN | \ + B_AX_REUSE_SIZE_ZERO_ERR_INT_EN | \ + B_AX_STF_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_STF_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN | \ + B_AX_REUSE_EN_ERR_INT_EN | \ + B_AX_REUSE_SIZE_ERR_INT_EN) +#define B_AX_OTHER_DISP_IMR_SET_V1 (B_AX_CDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN) + +#define R_AX_DISPATCHER_DBG_PORT 0x8860 +#define B_AX_DISPATCHER_DBG_SEL_MASK GENMASK(11, 8) +#define B_AX_DISPATCHER_INTN_SEL_MASK GENMASK(7, 4) +#define B_AX_DISPATCHER_CH_SEL_MASK GENMASK(3, 0) + +#define R_AX_RXDMA_SETTING 0x8908 +#define B_AX_BULK_SIZE GENMASK(1, 0) +#define USB11_BULKSIZE 0x2 +#define USB2_BULKSIZE 0x1 +#define USB3_BULKSIZE 0x0 + +#define R_AX_RX_FUNCTION_STOP 0x8920 +#define B_AX_HDR_RX_STOP BIT(0) + +#define R_AX_HCI_FC_CTRL 0x8A00 +#define B_AX_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) +#define B_AX_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8) +#define B_AX_HCI_FC_WP_CH07_FULL_COND_MASK GENMASK(7, 6) +#define B_AX_HCI_FC_WD_FULL_COND_MASK GENMASK(5, 4) +#define B_AX_HCI_FC_CH12_EN BIT(3) +#define B_AX_HCI_FC_MODE_MASK GENMASK(2, 1) +#define B_AX_HCI_FC_EN BIT(0) + +#define R_AX_CH_PAGE_CTRL 0x8A04 +#define B_AX_PREC_PAGE_CH12_MASK GENMASK(24, 16) +#define B_AX_PREC_PAGE_CH011_MASK GENMASK(8, 0) + +#define B_AX_MAX_PG_MASK GENMASK(28, 16) +#define B_AX_MIN_PG_MASK GENMASK(12, 0) +#define B_AX_GRP BIT(31) +#define R_AX_ACH0_PAGE_CTRL 0x8A10 +#define R_AX_ACH1_PAGE_CTRL 0x8A14 +#define R_AX_ACH2_PAGE_CTRL 0x8A18 +#define R_AX_ACH3_PAGE_CTRL 0x8A1C +#define R_AX_ACH4_PAGE_CTRL 0x8A20 +#define R_AX_ACH5_PAGE_CTRL 0x8A24 +#define R_AX_ACH6_PAGE_CTRL 0x8A28 +#define R_AX_ACH7_PAGE_CTRL 0x8A2C +#define R_AX_CH8_PAGE_CTRL 0x8A30 +#define R_AX_CH9_PAGE_CTRL 0x8A34 +#define R_AX_CH10_PAGE_CTRL 0x8A38 +#define R_AX_CH11_PAGE_CTRL 0x8A3C + +#define B_AX_AVAL_PG_MASK GENMASK(27, 16) +#define B_AX_USE_PG_MASK GENMASK(12, 0) +#define R_AX_ACH0_PAGE_INFO 0x8A50 +#define R_AX_ACH1_PAGE_INFO 0x8A54 +#define R_AX_ACH2_PAGE_INFO 0x8A58 +#define R_AX_ACH3_PAGE_INFO 0x8A5C +#define R_AX_ACH4_PAGE_INFO 0x8A60 +#define R_AX_ACH5_PAGE_INFO 0x8A64 +#define R_AX_ACH6_PAGE_INFO 0x8A68 +#define R_AX_ACH7_PAGE_INFO 0x8A6C +#define R_AX_CH8_PAGE_INFO 0x8A70 +#define R_AX_CH9_PAGE_INFO 0x8A74 +#define R_AX_CH10_PAGE_INFO 0x8A78 +#define R_AX_CH11_PAGE_INFO 0x8A7C +#define R_AX_CH12_PAGE_INFO 0x8A80 + +#define R_AX_PUB_PAGE_INFO3 0x8A8C +#define B_AX_G1_AVAL_PG_MASK GENMASK(28, 16) +#define B_AX_G0_AVAL_PG_MASK GENMASK(12, 0) + +#define R_AX_PUB_PAGE_CTRL1 0x8A90 +#define B_AX_PUBPG_G1_MASK GENMASK(28, 16) +#define B_AX_PUBPG_G0_MASK GENMASK(12, 0) + +#define R_AX_PUB_PAGE_CTRL2 0x8A94 +#define B_AX_PUBPG_ALL_MASK GENMASK(12, 0) + +#define R_AX_PUB_PAGE_INFO1 0x8A98 +#define B_AX_G1_USE_PG_MASK GENMASK(28, 16) +#define B_AX_G0_USE_PG_MASK GENMASK(12, 0) + +#define R_AX_PUB_PAGE_INFO2 0x8A9C +#define B_AX_PUB_AVAL_PG_MASK GENMASK(12, 0) + +#define R_AX_WP_PAGE_CTRL1 0x8AA0 +#define B_AX_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16) +#define B_AX_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0) + +#define R_AX_WP_PAGE_CTRL2 0x8AA4 +#define B_AX_WP_THRD_MASK GENMASK(12, 0) + +#define R_AX_WP_PAGE_INFO1 0x8AA8 +#define B_AX_WP_AVAL_PG_MASK GENMASK(28, 16) + +#define R_AX_WDE_PKTBUF_CFG 0x8C08 +#define B_AX_WDE_START_BOUND_MASK GENMASK(13, 8) +#define B_AX_WDE_PAGE_SEL_MASK GENMASK(1, 0) +#define B_AX_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16) + +#define R_AX_WDE_ERRFLAG_MSG 0x8C30 +#define B_AX_WDE_ERR_FLAG_MSG_MASK GENMASK(31, 0) + +#define R_AX_WDE_ERR_FLAG_CFG_NUM1 0x8C34 +#define B_AX_WDE_ERR_FLAG_NUM1_VLD BIT(31) +#define B_AX_WDE_ERR_FLAG_NUM1_MSTIDX_MASK GENMASK(27, 24) +#define B_AX_WDE_ERR_FLAG_NUM1_ISRIDX_MASK GENMASK(20, 16) +#define B_AX_WDE_DATCHN_FRZTMR_MODE BIT(2) +#define B_AX_WDE_QUEMGN_FRZTMR_MODE BIT(1) +#define B_AX_WDE_BUFMGN_FRZTMR_MODE BIT(0) + +#define R_AX_WDE_ERR_IMR 0x8C38 +#define B_AX_WDE_DATCHN_UAPG_ERR_INT_EN BIT(30) +#define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN BIT(13) +#define B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN BIT(12) +#define B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN BIT(7) +#define B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN BIT(6) +#define B_AX_WDE_GETNPG_STRPG_ERR_INT_EN BIT(5) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(4) +#define B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN BIT(3) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(2) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN BIT(1) +#define B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_AX_WDE_IMR_CLR (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN) +#define B_AX_WDE_IMR_CLR_V01 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN | \ + B_AX_WDE_DATCHN_UAPG_ERR_INT_EN) +#define B_AX_WDE_IMR_SET (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN) +#define B_AX_WDE_IMR_SET_V01 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) + +#define B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) +#define B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) +#define B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) +#define B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) +#define B_AX_WDE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_AX_WDE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_AX_WDE_IMR_CLR_V1 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SIZE0_INT_EN | \ + B_AX_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_AX_WDE_IMR_SET_V1 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SIZE0_INT_EN | \ + B_AX_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) + +#define R_AX_WDE_ERR_ISR 0x8C3C +#define B_AX_WDE_DATCHN_RRDY_ERR BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR BIT(14) +#define B_AX_WDE_QUE_DSTQUEID_ERR BIT(13) +#define B_AX_WDE_QUE_CMDTYPE_ERR BIT(12) +#define B_AX_WDE_BUFMGN_FRZTO_ERR BIT(7) +#define B_AX_WDE_GETNPG_PGOFST_ERR BIT(6) +#define B_AX_WDE_GETNPG_STRPG_ERR BIT(5) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR BIT(4) +#define B_AX_WDE_BUFRTN_SIZE_ERR BIT(3) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR BIT(2) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR BIT(1) +#define B_AX_WDE_BUFREQ_QTAID_ERR BIT(0) + +#define B_AX_WDE_MAX_SIZE_MASK GENMASK(27, 16) +#define B_AX_WDE_MIN_SIZE_MASK GENMASK(11, 0) +#define R_AX_WDE_QTA0_CFG 0x8C40 +#define R_AX_WDE_QTA1_CFG 0x8C44 +#define R_AX_WDE_QTA2_CFG 0x8C48 +#define R_AX_WDE_QTA3_CFG 0x8C4C +#define R_AX_WDE_QTA4_CFG 0x8C50 + +#define B_AX_DLE_PUB_PGNUM GENMASK(12, 0) +#define B_AX_DLE_FREE_HEADPG GENMASK(11, 0) +#define B_AX_DLE_FREE_TAILPG GENMASK(27, 16) +#define B_AX_DLE_USE_PGNUM GENMASK(27, 16) +#define B_AX_DLE_RSV_PGNUM GENMASK(11, 0) +#define B_AX_DLE_QEMPTY_GRP GENMASK(31, 0) + +#define R_AX_WDE_INI_STATUS 0x8D00 +#define B_AX_WDE_Q_MGN_INI_RDY BIT(1) +#define B_AX_WDE_BUF_MGN_INI_RDY BIT(0) +#define WDE_MGN_INI_RDY (B_AX_WDE_Q_MGN_INI_RDY | B_AX_WDE_BUF_MGN_INI_RDY) +#define R_AX_WDE_DBG_FUN_INTF_CTL 0x8D10 +#define B_AX_WDE_DFI_ACTIVE BIT(31) +#define B_AX_WDE_DFI_TRGSEL_MASK GENMASK(19, 16) +#define B_AX_WDE_DFI_ADDR_MASK GENMASK(15, 0) +#define R_AX_WDE_DBG_FUN_INTF_DATA 0x8D14 +#define B_AX_WDE_DFI_DATA_MASK GENMASK(31, 0) + +#define R_AX_PLE_PKTBUF_CFG 0x9008 +#define B_AX_PLE_START_BOUND_MASK GENMASK(13, 8) +#define B_AX_PLE_PAGE_SEL_MASK GENMASK(1, 0) +#define B_AX_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16) + +#define R_AX_PLE_DBGERR_LOCKEN 0x9020 +#define B_AX_PLE_LOCKEN_DLEPIF07 BIT(7) +#define B_AX_PLE_LOCKEN_DLEPIF06 BIT(6) +#define B_AX_PLE_LOCKEN_DLEPIF05 BIT(5) +#define B_AX_PLE_LOCKEN_DLEPIF04 BIT(4) +#define B_AX_PLE_LOCKEN_DLEPIF03 BIT(3) +#define B_AX_PLE_LOCKEN_DLEPIF02 BIT(2) +#define B_AX_PLE_LOCKEN_DLEPIF01 BIT(1) +#define B_AX_PLE_LOCKEN_DLEPIF00 BIT(0) + +#define R_AX_PLE_DBGERR_STS 0x9024 +#define B_AX_PLE_LOCKON_DLEPIF07 BIT(7) +#define B_AX_PLE_LOCKON_DLEPIF06 BIT(6) +#define B_AX_PLE_LOCKON_DLEPIF05 BIT(5) +#define B_AX_PLE_LOCKON_DLEPIF04 BIT(4) +#define B_AX_PLE_LOCKON_DLEPIF03 BIT(3) +#define B_AX_PLE_LOCKON_DLEPIF02 BIT(2) +#define B_AX_PLE_LOCKON_DLEPIF01 BIT(1) +#define B_AX_PLE_LOCKON_DLEPIF00 BIT(0) + +#define R_AX_PLE_ERR_FLAG_CFG_NUM1 0x9034 +#define B_AX_PLE_ERR_FLAG_NUM1_VLD BIT(31) +#define B_AX_PLE_ERR_FLAG_NUM1_MSTIDX_MASK GENMASK(27, 24) +#define B_AX_PLE_ERR_FLAG_NUM1_ISRIDX_MASK GENMASK(20, 16) +#define B_AX_PLE_DATCHN_FRZTMR_MODE BIT(2) +#define B_AX_PLE_QUEMGN_FRZTMR_MODE BIT(1) +#define B_AX_PLE_BUFMGN_FRZTMR_MODE BIT(0) + +#define R_AX_PLE_ERRFLAG_MSG 0x9030 +#define B_AX_PLE_ERR_FLAG_MSG_MASK GENMASK(31, 0) +#define B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) +#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) +#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) +#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) +#define B_AX_PLE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_AX_PLE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_AX_PLE_DATCHN_CAMREQ_ERR BIT(29) +#define B_AX_PLE_DATCHN_ADRERR_ERR BIT(28) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_V1 BIT(9) +#define B_AX_PLE_GETNPG_PGOFST_ERR_V1 BIT(8) +#define B_AX_PLE_GETNPG_STRPG_ERR_V1 BIT(7) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_V1 BIT(6) +#define B_AX_PLE_BUFRTN_SIZE_ERR_V1 BIT(5) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_V1 BIT(4) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_V1 BIT(3) +#define B_AX_PLE_BUFREQ_SIZELMT_ERR BIT(2) +#define B_AX_PLE_BUFREQ_SIZE0_ERR BIT(1) + +#define R_AX_PLE_ERR_IMR 0x9038 +#define B_AX_PLE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_PLE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN BIT(13) +#define B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN BIT(12) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN BIT(7) +#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN BIT(6) +#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN BIT(5) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(4) +#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN BIT(3) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(2) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN BIT(1) +#define B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_AX_PLE_IMR_CLR (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN) +#define B_AX_PLE_IMR_SET (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN) + +#define B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) +#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) +#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) +#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) +#define B_AX_PLE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_AX_PLE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_AX_PLE_IMR_CLR_V1 (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SIZE0_INT_EN | \ + B_AX_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_AX_PLE_IMR_SET_V1 (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SIZE0_INT_EN | \ + B_AX_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN) + +#define R_AX_PLE_ERR_FLAG_ISR 0x903C +#define B_AX_PLE_MAX_SIZE_MASK GENMASK(27, 16) +#define B_AX_PLE_MIN_SIZE_MASK GENMASK(11, 0) +#define R_AX_PLE_QTA0_CFG 0x9040 +#define R_AX_PLE_QTA1_CFG 0x9044 +#define R_AX_PLE_QTA2_CFG 0x9048 +#define R_AX_PLE_QTA3_CFG 0x904C +#define R_AX_PLE_QTA4_CFG 0x9050 +#define R_AX_PLE_QTA5_CFG 0x9054 +#define R_AX_PLE_QTA6_CFG 0x9058 +#define B_AX_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16) +#define B_AX_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0) +#define R_AX_PLE_QTA7_CFG 0x905C +#define B_AX_PLE_Q7_MAX_SIZE_MASK GENMASK(27, 16) +#define B_AX_PLE_Q7_MIN_SIZE_MASK GENMASK(11, 0) +#define R_AX_PLE_QTA8_CFG 0x9060 +#define R_AX_PLE_QTA9_CFG 0x9064 +#define R_AX_PLE_QTA10_CFG 0x9068 +#define R_AX_PLE_QTA11_CFG 0x906C + +#define R_AX_PLE_INI_STATUS 0x9100 +#define B_AX_PLE_Q_MGN_INI_RDY BIT(1) +#define B_AX_PLE_BUF_MGN_INI_RDY BIT(0) +#define PLE_MGN_INI_RDY (B_AX_PLE_Q_MGN_INI_RDY | B_AX_PLE_BUF_MGN_INI_RDY) +#define R_AX_PLE_DBG_FUN_INTF_CTL 0x9110 +#define B_AX_PLE_DFI_ACTIVE BIT(31) +#define B_AX_PLE_DFI_TRGSEL_MASK GENMASK(19, 16) +#define B_AX_PLE_DFI_ADDR_MASK GENMASK(15, 0) +#define R_AX_PLE_DBG_FUN_INTF_DATA 0x9114 +#define B_AX_PLE_DFI_DATA_MASK GENMASK(31, 0) + +#define R_AX_WDRLS_CFG 0x9408 +#define B_AX_RLSRPT_BUFREQ_TO_MASK GENMASK(15, 8) +#define B_AX_WDRLS_MODE_MASK GENMASK(1, 0) + +#define R_AX_RLSRPT0_CFG0 0x9410 +#define B_AX_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24) +#define B_AX_RLSRPT0_PKTTYPE_MASK GENMASK(19, 16) +#define B_AX_RLSRPT0_PID_MASK GENMASK(10, 8) +#define B_AX_RLSRPT0_QID_MASK GENMASK(5, 0) + +#define R_AX_RLSRPT0_CFG1 0x9414 +#define B_AX_RLSRPT0_TO_MASK GENMASK(23, 16) +#define B_AX_RLSRPT0_AGGNUM_MASK GENMASK(7, 0) + +#define R_AX_WDRLS_ERR_IMR 0x9430 +#define B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN BIT(13) +#define B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN BIT(12) +#define B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN BIT(9) +#define B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN BIT(8) +#define B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN BIT(5) +#define B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN BIT(4) +#define B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2) +#define B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1) +#define B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0) +#define B_AX_WDRLS_IMR_EN_CLR (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define B_AX_WDRLS_IMR_SET (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define B_AX_WDRLS_IMR_SET_V1 (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) + +#define R_AX_WDRLS_ERR_ISR 0x9434 + +#define R_AX_BBRPT_COM_ERR_IMR 0x9608 +#define B_AX_BBRPT_COM_HANG_EN BIT(1) +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN BIT(0) + +#define R_AX_BBRPT_COM_ERR_IMR_ISR 0x960C +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR BIT(16) +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN BIT(0) + +#define R_AX_BBRPT_COM_ERR_ISR 0x960C +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_V1 BIT(0) + +#define R_AX_BBRPT_CHINFO_ERR_ISR 0x962C +#define B_AX_BBPRT_CHIF_TO_ERR_V1 BIT(7) +#define B_AX_BBPRT_CHIF_NULL_ERR_V1 BIT(6) +#define B_AX_BBPRT_CHIF_LEFT2_ERR_V1 BIT(5) +#define B_AX_BBPRT_CHIF_LEFT1_ERR_V1 BIT(4) +#define B_AX_BBPRT_CHIF_HDRL_ERR_V1 BIT(3) +#define B_AX_BBPRT_CHIF_BOVF_ERR_V1 BIT(2) +#define B_AX_BBPRT_CHIF_OVF_ERR_V1 BIT(1) +#define B_AX_BBPRT_CHIF_BB_TO_ERR_V1 BIT(0) + +#define R_AX_BBRPT_CHINFO_ERR_IMR 0x9628 +#define B_AX_BBPRT_CHIF_TO_ERR_INT_EN BIT(7) +#define B_AX_BBPRT_CHIF_NULL_ERR_INT_EN BIT(6) +#define B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN BIT(5) +#define B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN BIT(4) +#define B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN BIT(3) +#define B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN BIT(2) +#define B_AX_BBPRT_CHIF_OVF_ERR_INT_EN BIT(1) +#define B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN BIT(0) +#define R_AX_BBRPT_CHINFO_IMR_SET_V1 (B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_OVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_NULL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_TO_ERR_INT_EN) + +#define R_AX_BBRPT_CHINFO_ERR_IMR_ISR 0x962C +#define B_AX_BBPRT_CHIF_TO_ERR BIT(23) +#define B_AX_BBPRT_CHIF_NULL_ERR BIT(22) +#define B_AX_BBPRT_CHIF_LEFT2_ERR BIT(21) +#define B_AX_BBPRT_CHIF_LEFT1_ERR BIT(20) +#define B_AX_BBPRT_CHIF_HDRL_ERR BIT(19) +#define B_AX_BBPRT_CHIF_BOVF_ERR BIT(18) +#define B_AX_BBPRT_CHIF_OVF_ERR BIT(17) +#define B_AX_BBPRT_CHIF_BB_TO_ERR BIT(16) +#define B_AX_BBPRT_CHIF_TO_ERR_INT_EN BIT(7) +#define B_AX_BBPRT_CHIF_NULL_ERR_INT_EN BIT(6) +#define B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN BIT(5) +#define B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN BIT(4) +#define B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN BIT(3) +#define B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN BIT(2) +#define B_AX_BBPRT_CHIF_OVF_ERR_INT_EN BIT(1) +#define B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN BIT(0) +#define B_AX_BBRPT_CHINFO_IMR_CLR (B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_OVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_NULL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_TO_ERR_INT_EN) + +#define R_AX_BBRPT_DFS_ERR_IMR 0x9638 +#define B_AX_BBRPT_DFS_TO_ERR_INT_EN BIT(0) + +#define R_AX_BBRPT_DFS_ERR_IMR_ISR 0x963C +#define B_AX_BBRPT_DFS_TO_ERR BIT(16) +#define B_AX_BBRPT_DFS_TO_ERR_INT_EN BIT(0) + +#define R_AX_BBRPT_DFS_ERR_ISR 0x963C +#define B_AX_BBRPT_DFS_TO_ERR_V1 BIT(0) + +#define R_AX_LA_ERRFLAG 0x966C +#define B_AX_LA_ISR_DATA_LOSS_ERR BIT(16) +#define B_AX_LA_IMR_DATA_LOSS_ERR BIT(0) + +#define R_AX_WD_BUF_REQ 0x9800 +#define R_AX_PL_BUF_REQ 0x9820 +#define B_AX_WD_BUF_REQ_EXEC BIT(31) +#define B_AX_WD_BUF_REQ_QUOTA_ID_MASK GENMASK(23, 16) +#define B_AX_WD_BUF_REQ_LEN_MASK GENMASK(15, 0) + +#define R_AX_WD_BUF_STATUS 0x9804 +#define R_AX_PL_BUF_STATUS 0x9824 +#define B_AX_WD_BUF_STAT_DONE BIT(31) +#define B_AX_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0) +#define S_WD_BUF_STAT_PKTID_INVALID GENMASK(11, 0) + +#define R_AX_WD_CPUQ_OP_0 0x9810 +#define R_AX_PL_CPUQ_OP_0 0x9830 +#define B_AX_WD_CPUQ_OP_EXEC BIT(31) +#define B_AX_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24) +#define B_AX_CPUQ_OP_MACID_MASK GENMASK(23, 16) +#define B_AX_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0) + +#define R_AX_WD_CPUQ_OP_1 0x9814 +#define R_AX_PL_CPUQ_OP_1 0x9834 +#define B_AX_CPUQ_OP_SRC_PID_MASK GENMASK(24, 22) +#define B_AX_CPUQ_OP_SRC_QID_MASK GENMASK(21, 16) +#define B_AX_CPUQ_OP_DST_PID_MASK GENMASK(8, 6) +#define B_AX_CPUQ_OP_DST_QID_MASK GENMASK(5, 0) + +#define R_AX_WD_CPUQ_OP_2 0x9818 +#define R_AX_PL_CPUQ_OP_2 0x9838 +#define B_AX_WD_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16) +#define B_AX_WD_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0) + +#define R_AX_WD_CPUQ_OP_STATUS 0x981C +#define R_AX_PL_CPUQ_OP_STATUS 0x983C +#define B_AX_WD_CPUQ_OP_STAT_DONE BIT(31) +#define B_AX_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0) + +#define R_AX_CPUIO_ERR_IMR 0x9840 +#define B_AX_PLEQUE_OP_ERR_INT_EN BIT(12) +#define B_AX_PLEBUF_OP_ERR_INT_EN BIT(8) +#define B_AX_WDEQUE_OP_ERR_INT_EN BIT(4) +#define B_AX_WDEBUF_OP_ERR_INT_EN BIT(0) +#define B_AX_CPUIO_IMR_CLR (B_AX_WDEBUF_OP_ERR_INT_EN | \ + B_AX_WDEQUE_OP_ERR_INT_EN | \ + B_AX_PLEBUF_OP_ERR_INT_EN | \ + B_AX_PLEQUE_OP_ERR_INT_EN) +#define B_AX_CPUIO_IMR_SET (B_AX_WDEBUF_OP_ERR_INT_EN | \ + B_AX_WDEQUE_OP_ERR_INT_EN | \ + B_AX_PLEBUF_OP_ERR_INT_EN | \ + B_AX_PLEQUE_OP_ERR_INT_EN) + +#define R_AX_CPUIO_ERR_ISR 0x9844 + +#define R_AX_SEC_ERR_IMR_ISR 0x991C + +#define R_AX_PKTIN_SETTING 0x9A00 +#define B_AX_WD_ADDR_INFO_LENGTH BIT(1) + +#define R_AX_PKTIN_ERR_IMR 0x9A20 +#define B_AX_PKTIN_GETPKTID_ERR_INT_EN BIT(0) + +#define R_AX_PKTIN_ERR_ISR 0x9A24 + +#define R_AX_MPDU_TX_ERR_ISR 0x9BF0 +#define R_AX_MPDU_TX_ERR_IMR 0x9BF4 +#define B_AX_TX_KSRCH_ERR_EN BIT(9) +#define B_AX_TX_NW_TYPE_ERR_EN BIT(8) +#define B_AX_TX_LLC_PRE_ERR_EN BIT(7) +#define B_AX_TX_ETH_TYPE_ERR_EN BIT(6) +#define B_AX_TX_HDR3_SIZE_ERR_INT_EN BIT(5) +#define B_AX_TX_OFFSET_ERR_INT_EN BIT(4) +#define B_AX_TX_MPDU_SIZE_ZERO_INT_EN BIT(3) +#define B_AX_TX_NXT_ERRPKTID_INT_EN BIT(2) +#define B_AX_TX_GET_ERRPKTID_INT_EN BIT(1) +#define B_AX_MPDU_TX_IMR_SET_V1 (B_AX_TX_GET_ERRPKTID_INT_EN | \ + B_AX_TX_NXT_ERRPKTID_INT_EN | \ + B_AX_TX_MPDU_SIZE_ZERO_INT_EN | \ + B_AX_TX_HDR3_SIZE_ERR_INT_EN | \ + B_AX_TX_ETH_TYPE_ERR_EN | \ + B_AX_TX_NW_TYPE_ERR_EN | \ + B_AX_TX_KSRCH_ERR_EN) + +#define R_AX_MPDU_PROC 0x9C00 +#define B_AX_A_ICV_ERR BIT(1) +#define B_AX_APPEND_FCS BIT(0) + +#define R_AX_ACTION_FWD0 0x9C04 +#define TRXCFG_MPDU_PROC_ACT_FRWD 0x02A95A95 + +#define R_AX_ACTION_FWD1 0x9C08 + +#define R_AX_TF_FWD 0x9C14 +#define TRXCFG_MPDU_PROC_TF_FRWD 0x0000AA55 + +#define R_AX_HW_RPT_FWD 0x9C18 +#define B_AX_FWD_PPDU_STAT_MASK GENMASK(1, 0) +#define RTW89_PRPT_DEST_HOST 1 +#define RTW89_PRPT_DEST_WLCPU 2 + +#define R_AX_CUT_AMSDU_CTRL 0x9C40 +#define TRXCFG_MPDU_PROC_CUT_CTRL 0x010E05F0 + +#define R_AX_WOW_CTRL 0x9C50 +#define B_AX_WOW_WOWEN BIT(1) + +#define R_AX_MPDU_RX_ERR_ISR 0x9CF0 +#define R_AX_MPDU_RX_ERR_IMR 0x9CF4 +#define B_AX_RPT_ERR_INT_EN BIT(3) +#define B_AX_MHDRLEN_ERR_INT_EN BIT(1) +#define B_AX_GETPKTID_ERR_INT_EN BIT(0) +#define B_AX_MPDU_RX_IMR_SET_V1 B_AX_RPT_ERR_INT_EN + +#define R_AX_SEC_ENG_CTRL 0x9D00 +#define B_AX_SEC_DBG_PORT_FIELD_MASK GENMASK(19, 16) +#define B_AX_TX_PARTIAL_MODE BIT(11) +#define B_AX_CLK_EN_CGCMP BIT(10) +#define B_AX_CLK_EN_WAPI BIT(9) +#define B_AX_CLK_EN_WEP_TKIP BIT(8) +#define B_AX_BMC_MGNT_DEC BIT(5) +#define B_AX_UC_MGNT_DEC BIT(4) +#define B_AX_MC_DEC BIT(3) +#define B_AX_BC_DEC BIT(2) +#define B_AX_SEC_RX_DEC BIT(1) +#define B_AX_SEC_TX_ENC BIT(0) + +#define R_AX_SEC_MPDU_PROC 0x9D04 +#define B_AX_APPEND_ICV BIT(1) +#define B_AX_APPEND_MIC BIT(0) + +#define R_AX_SEC_CAM_ACCESS 0x9D10 +#define R_AX_SEC_CAM_RDATA 0x9D14 +#define R_AX_SEC_CAM_WDATA 0x9D18 + +#define R_AX_SEC_DEBUG 0x9D1C +#define B_AX_IMR_ERROR BIT(3) + +#define R_AX_SEC_DEBUG1 0x9D1C +#define B_AX_TX_TIMEOUT_SEL_MASK GENMASK(31, 30) +#define AX_TX_TO_VAL 0x2 + +#define R_AX_SEC_TX_DEBUG 0x9D20 +#define R_AX_SEC_RX_DEBUG 0x9D24 +#define R_AX_SEC_TRX_PKT_CNT 0x9D28 + +#define R_AX_SEC_DEBUG2 0x9D28 +#define B_AX_DBG_READ_SH 2 +#define B_AX_DBG_READ_MSK 0x3fffffff + +#define R_AX_SEC_TRX_BLK_CNT 0x9D2C + +#define R_AX_SEC_ERROR_FLAG_IMR 0x9D2C +#define B_AX_RX_HANG_IMR BIT(1) +#define B_AX_TX_HANG_IMR BIT(0) + +#define R_AX_SEC_ERROR_FLAG 0x9D30 +#define B_AX_RX_HANG_ERROR_V1 BIT(1) +#define B_AX_TX_HANG_ERROR_V1 BIT(0) + +#define R_AX_SS_CTRL 0x9E10 +#define B_AX_SS_INIT_DONE_1 BIT(31) +#define B_AX_SS_WARM_INIT_FLG BIT(29) +#define B_AX_SS_NONEMPTY_SS2FINFO_EN BIT(28) +#define B_AX_SS_EN BIT(0) + +#define R_AX_SS2FINFO_PATH 0x9E50 +#define B_AX_SS_UL_REL BIT(31) +#define B_AX_SS_REL_QUEUE_MASK GENMASK(29, 24) +#define B_AX_SS_REL_PORT_MASK GENMASK(18, 16) +#define B_AX_SS_DEST_QUEUE_MASK GENMASK(13, 8) +#define SS2F_PATH_WLCPU 0x0A +#define B_AX_SS_DEST_PORT_MASK GENMASK(2, 0) + +#define R_AX_SS_MACID_PAUSE_0 0x9EB0 +#define B_AX_SS_MACID31_0_PAUSE_SH 0 +#define B_AX_SS_MACID31_0_PAUSE_MASK GENMASK(31, 0) + +#define R_AX_SS_MACID_PAUSE_1 0x9EB4 +#define B_AX_SS_MACID63_32_PAUSE_SH 0 +#define B_AX_SS_MACID63_32_PAUSE_MASK GENMASK(31, 0) + +#define R_AX_SS_MACID_PAUSE_2 0x9EB8 +#define B_AX_SS_MACID95_64_PAUSE_SH 0 +#define B_AX_SS_MACID95_64_PAUSE_MASK GENMASK(31, 0) + +#define R_AX_SS_MACID_PAUSE_3 0x9EBC +#define B_AX_SS_MACID127_96_PAUSE_SH 0 +#define B_AX_SS_MACID127_96_PAUSE_MASK GENMASK(31, 0) + +#define R_AX_STA_SCHEDULER_ERR_IMR 0x9EF0 +#define B_AX_PLE_B_PKTID_ERR_INT_EN BIT(2) +#define B_AX_RPT_HANG_TIMEOUT_INT_EN BIT(1) +#define B_AX_SEARCH_HANG_TIMEOUT_INT_EN BIT(0) +#define B_AX_STA_SCHEDULER_IMR_SET (B_AX_SEARCH_HANG_TIMEOUT_INT_EN | \ + B_AX_RPT_HANG_TIMEOUT_INT_EN | \ + B_AX_PLE_B_PKTID_ERR_INT_EN) + +#define R_AX_STA_SCHEDULER_ERR_ISR 0x9EF4 + +#define R_AX_TXPKTCTL_ERR_IMR_ISR 0x9F1C +#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR BIT(25) +#define B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR BIT(24) +#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR BIT(19) +#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR BIT(18) +#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR BIT(17) +#define B_AX_TXPKTCTL_USRCTL_REINIT_ERR BIT(16) +#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) +#define B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN BIT(8) +#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) +#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN BIT(2) +#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN BIT(1) +#define B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN BIT(0) +#define B_AX_TXPKTCTL_IMR_B0_CLR (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B1_CLR (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B0_SET (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B1_SET (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) + +#define R_AX_TXPKTCTL_ERR_IMR_ISR_B1 0x9F2C +#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) +#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) +#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN BIT(2) +#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN BIT(1) + +#define R_AX_DBG_FUN_INTF_CTL 0x9F30 +#define B_AX_DFI_ACTIVE BIT(31) +#define B_AX_DFI_TRGSEL_MASK GENMASK(19, 16) +#define B_AX_DFI_ADDR_MASK GENMASK(15, 0) +#define R_AX_DBG_FUN_INTF_DATA 0x9F34 +#define B_AX_DFI_DATA_MASK GENMASK(31, 0) + +#define R_AX_TXPKTCTL_B0_PRELD_CFG0 0x9F48 +#define B_AX_B0_PRELD_FEN BIT(31) +#define B_AX_B0_PRELD_USEMAXSZ_MASK GENMASK(25, 16) +#define PRELD_B0_ENT_NUM 10 +#define PRELD_B01_ENT_NUM_8922D 2 +#define PRELD_AMSDU_SIZE 52 +#define PRELD_NEXT_MIN_SIZE 255 +#define B_AX_B0_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) +#define B_AX_B0_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) + +#define R_AX_TXPKTCTL_B0_PRELD_CFG1 0x9F4C +#define B_AX_B0_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) +#define PRELD_NEXT_WND 1 +#define B_AX_B0_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) + +#define R_AX_TXPKTCTL_B0_ERRFLAG_IMR 0x9F78 +#define B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B0_IMR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B0_IMR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B0_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B0_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B0_IMR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B0_IMR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B0_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B0_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_AX_TXPKTCTL_IMR_B0_CLR_V1 (B_AX_B0_IMR_ERR_USRCTL_REINIT | \ + B_AX_B0_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B0_IMR_ERR_USRCTL_RDNRLSCMD | \ + B_AX_B0_IMR_ERR_USRCTL_RLSBMPLEN | \ + B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B0_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B0_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B0_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG) +#define B_AX_TXPKTCTL_IMR_B0_SET_V1 (B_AX_B0_IMR_ERR_USRCTL_REINIT | \ + B_AX_B0_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B0_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B0_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG) + +#define R_AX_TXPKTCTL_B0_ERRFLAG_ISR 0x9F7C +#define B_AX_B0_ISR_ERR_PRELD_EVT3 BIT(23) +#define B_AX_B0_ISR_ERR_PRELD_EVT2 BIT(22) +#define B_AX_B0_ISR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B0_ISR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B0_ISR_ERR_MPDUIF_ERR1 BIT(19) +#define B_AX_B0_ISR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B0_ISR_ERR_MPDUINFO_ERR1 BIT(17) +#define B_AX_B0_ISR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B0_ISR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B0_ISR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B0_ISR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B0_ISR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B0_ISR_ERR_USRCTL_EVT7 BIT(7) +#define B_AX_B0_ISR_ERR_USRCTL_EVT6 BIT(6) +#define B_AX_B0_ISR_ERR_USRCTL_EVT5 BIT(5) +#define B_AX_B0_ISR_ERR_USRCTL_EVT4 BIT(4) +#define B_AX_B0_ISR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B0_ISR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B0_ISR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B0_ISR_ERR_USRCTL_REINIT BIT(0) + +#define R_AX_TXPKTCTL_B1_PRELD_CFG0 0x9F88 +#define B_AX_B1_PRELD_FEN BIT(31) +#define B_AX_B1_PRELD_USEMAXSZ_MASK GENMASK(25, 16) +#define PRELD_B1_ENT_NUM 4 +#define B_AX_B1_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) +#define B_AX_B1_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) + +#define R_AX_TXPKTCTL_B1_PRELD_CFG1 0x9F8C +#define B_AX_B1_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) +#define B_AX_B1_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) + +#define R_AX_TXPKTCTL_B1_ERRFLAG_IMR 0x9FB8 +#define B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B1_IMR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B1_IMR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B1_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B1_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B1_IMR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B1_IMR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B1_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B1_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_AX_TXPKTCTL_IMR_B1_CLR_V1 (B_AX_B1_IMR_ERR_USRCTL_REINIT | \ + B_AX_B1_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B1_IMR_ERR_USRCTL_RDNRLSCMD | \ + B_AX_B1_IMR_ERR_USRCTL_RLSBMPLEN | \ + B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B1_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B1_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG) +#define B_AX_TXPKTCTL_IMR_B1_SET_V1 (B_AX_B1_IMR_ERR_USRCTL_REINIT | \ + B_AX_B1_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B1_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B1_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG) + +#define R_AX_TXPKTCTL_B1_ERRFLAG_ISR 0x9FBC +#define B_AX_B1_ISR_ERR_PRELD_EVT3 BIT(23) +#define B_AX_B1_ISR_ERR_PRELD_EVT2 BIT(22) +#define B_AX_B1_ISR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B1_ISR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B1_ISR_ERR_MPDUIF_ERR1 BIT(19) +#define B_AX_B1_ISR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B1_ISR_ERR_MPDUINFO_ERR1 BIT(17) +#define B_AX_B1_ISR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B1_ISR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B1_ISR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B1_ISR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B1_ISR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B1_ISR_ERR_USRCTL_EVT7 BIT(7) +#define B_AX_B1_ISR_ERR_USRCTL_EVT6 BIT(6) +#define B_AX_B1_ISR_ERR_USRCTL_EVT5 BIT(5) +#define B_AX_B1_ISR_ERR_USRCTL_EVT4 BIT(4) +#define B_AX_B1_ISR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B1_ISR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B1_ISR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B1_ISR_ERR_USRCTL_REINIT BIT(0) + +#define R_AX_AFE_CTRL1 0x0024 +#define B_AX_CMAC_CLK_SEL BIT(21) + +#define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) +#define B_AX_R_SYM_WLCMAC1_P3_PC_EN BIT(3) +#define B_AX_R_SYM_WLCMAC1_P2_PC_EN BIT(2) +#define B_AX_R_SYM_WLCMAC1_P1_PC_EN BIT(1) +#define B_AX_R_SYM_WLCMAC1_PC_EN BIT(0) + +#define R_AX_SYS_ISO_CTRL_EXTEND 0x0080 +#define B_AX_CMAC1_FEN BIT(30) +#define B_AX_R_SYM_FEN_WLBBGLB_1 BIT(17) +#define B_AX_R_SYM_FEN_WLBBFUN_1 BIT(16) +#define B_AX_R_SYM_ISO_CMAC12PP BIT(5) + +#define R_AX_SYSON_FSM_MON 0x00A0 +#define B_AX_FSM_MON_SEL_MASK GENMASK(26, 24) +#define B_AX_DOP_ELDO BIT(23) +#define B_AX_FSM_MON_UPD BIT(15) +#define B_AX_FSM_PAR_MASK GENMASK(14, 0) + +#define R_AX_CMAC_REG_START 0xC000 + +#define R_AX_CMAC_FUNC_EN 0xC000 +#define R_AX_CMAC_FUNC_EN_C1 0xE000 +#define B_AX_CMAC_CRPRT BIT(31) +#define B_AX_CMAC_EN BIT(30) +#define B_AX_CMAC_TXEN BIT(29) +#define B_AX_CMAC_RXEN BIT(28) +#define B_AX_FORCE_CMACREG_GCKEN BIT(15) +#define B_AX_PHYINTF_EN BIT(5) +#define B_AX_CMAC_DMA_EN BIT(4) +#define B_AX_PTCLTOP_EN BIT(3) +#define B_AX_SCHEDULER_EN BIT(2) +#define B_AX_TMAC_EN BIT(1) +#define B_AX_RMAC_EN BIT(0) + +#define R_AX_CK_EN 0xC004 +#define R_AX_CK_EN_C1 0xE004 +#define B_AX_CMAC_ALLCKEN GENMASK(31, 0) +#define B_AX_CMAC_CKEN BIT(30) +#define B_AX_PHYINTF_CKEN BIT(5) +#define B_AX_CMAC_DMA_CKEN BIT(4) +#define B_AX_PTCLTOP_CKEN BIT(3) +#define B_AX_SCHEDULER_CKEN BIT(2) +#define B_AX_TMAC_CKEN BIT(1) +#define B_AX_RMAC_CKEN BIT(0) + +#define R_AX_WMAC_RFMOD 0xC010 +#define R_AX_WMAC_RFMOD_C1 0xE010 +#define B_AX_WMAC_RFMOD_MASK GENMASK(1, 0) +#define AX_WMAC_RFMOD_20M 0 +#define AX_WMAC_RFMOD_40M 1 +#define AX_WMAC_RFMOD_80M 2 +#define AX_WMAC_RFMOD_160M 3 + +#define R_AX_GID_POSITION0 0xC070 +#define R_AX_GID_POSITION0_C1 0xE070 +#define R_AX_GID_POSITION1 0xC074 +#define R_AX_GID_POSITION1_C1 0xE074 +#define R_AX_GID_POSITION2 0xC078 +#define R_AX_GID_POSITION2_C1 0xE078 +#define R_AX_GID_POSITION3 0xC07C +#define R_AX_GID_POSITION3_C1 0xE07C +#define R_AX_GID_POSITION_EN0 0xC080 +#define R_AX_GID_POSITION_EN0_C1 0xE080 +#define R_AX_GID_POSITION_EN1 0xC084 +#define R_AX_GID_POSITION_EN1_C1 0xE084 + +#define R_AX_TX_SUB_CARRIER_VALUE 0xC088 +#define R_AX_TX_SUB_CARRIER_VALUE_C1 0xE088 +#define B_AX_TXSC_80M_MASK GENMASK(11, 8) +#define B_AX_TXSC_40M_MASK GENMASK(7, 4) +#define B_AX_TXSC_20M_MASK GENMASK(3, 0) + +#define R_AX_PTCL_RRSR1 0xC090 +#define R_AX_PTCL_RRSR1_C1 0xE090 +#define B_AX_RRSR_RATE_EN_MASK GENMASK(11, 8) +#define RRSR_OFDM_CCK_EN 3 +#define B_AX_RSC_MASK GENMASK(7, 6) +#define B_AX_RRSR_CCK_MASK GENMASK(3, 0) + +#define R_AX_CMAC_ERR_IMR 0xC160 +#define R_AX_CMAC_ERR_IMR_C1 0xE160 +#define B_AX_WMAC_TX_ERR_IND_EN BIT(7) +#define B_AX_WMAC_RX_ERR_IND_EN BIT(6) +#define B_AX_TXPWR_CTRL_ERR_IND_EN BIT(5) +#define B_AX_PHYINTF_ERR_IND_EN BIT(4) +#define B_AX_DMA_TOP_ERR_IND_EN BIT(3) +#define B_AX_PTCL_TOP_ERR_IND_EN BIT(1) +#define B_AX_SCHEDULE_TOP_ERR_IND_EN BIT(0) +#define CMAC0_ERR_IMR_EN GENMASK(31, 0) +#define CMAC1_ERR_IMR_EN GENMASK(31, 0) +#define CMAC0_ERR_IMR_DIS 0 +#define CMAC1_ERR_IMR_DIS 0 + +#define R_AX_CMAC_ERR_ISR 0xC164 +#define R_AX_CMAC_ERR_ISR_C1 0xE164 +#define B_AX_WMAC_TX_ERR_IND BIT(7) +#define B_AX_WMAC_RX_ERR_IND BIT(6) +#define B_AX_TXPWR_CTRL_ERR_IND BIT(5) +#define B_AX_PHYINTF_ERR_IND BIT(4) +#define B_AX_DMA_TOP_ERR_IND BIT(3) +#define B_AX_PTCL_TOP_ERR_IND BIT(1) +#define B_AX_SCHEDULE_TOP_ERR_IND BIT(0) + +#define R_AX_PORT0_TSF_SYNC 0xC2A0 +#define R_AX_PORT0_TSF_SYNC_C1 0xE2A0 +#define R_AX_PORT1_TSF_SYNC 0xC2A4 +#define R_AX_PORT1_TSF_SYNC_C1 0xE2A4 +#define R_AX_PORT2_TSF_SYNC 0xC2A8 +#define R_AX_PORT2_TSF_SYNC_C1 0xE2A8 +#define R_AX_PORT3_TSF_SYNC 0xC2AC +#define R_AX_PORT3_TSF_SYNC_C1 0xE2AC +#define R_AX_PORT4_TSF_SYNC 0xC2B0 +#define R_AX_PORT4_TSF_SYNC_C1 0xE2B0 +#define B_AX_SYNC_NOW BIT(30) +#define B_AX_SYNC_ONCE BIT(29) +#define B_AX_SYNC_AUTO BIT(28) +#define B_AX_SYNC_PORT_SRC GENMASK(26, 24) +#define B_AX_SYNC_PORT_OFFSET_SIGN BIT(18) +#define B_AX_SYNC_PORT_OFFSET_VAL GENMASK(17, 0) + +#define R_AX_MACID_SLEEP_0 0xC2C0 +#define R_AX_MACID_SLEEP_0_C1 0xE2C0 +#define B_AX_MACID31_0_SLEEP_SH 0 +#define B_AX_MACID31_0_SLEEP_MASK GENMASK(31, 0) + +#define R_AX_MACID_SLEEP_1 0xC2C4 +#define R_AX_MACID_SLEEP_1_C1 0xE2C4 +#define B_AX_MACID63_32_SLEEP_SH 0 +#define B_AX_MACID63_32_SLEEP_MASK GENMASK(31, 0) + +#define R_AX_MACID_SLEEP_2 0xC2C8 +#define R_AX_MACID_SLEEP_2_C1 0xE2C8 +#define B_AX_MACID95_64_SLEEP_SH 0 +#define B_AX_MACID95_64_SLEEP_MASK GENMASK(31, 0) + +#define R_AX_MACID_SLEEP_3 0xC2CC +#define R_AX_MACID_SLEEP_3_C1 0xE2CC +#define B_AX_MACID127_96_SLEEP_SH 0 +#define B_AX_MACID127_96_SLEEP_MASK GENMASK(31, 0) + +#define SCH_PREBKF_24US 0x18 +#define R_AX_PREBKF_CFG_0 0xC338 +#define R_AX_PREBKF_CFG_0_C1 0xE338 +#define B_AX_PREBKF_TIME_MASK GENMASK(4, 0) + +#define R_AX_PREBKF_CFG_1 0xC33C +#define R_AX_PREBKF_CFG_1_C1 0xE33C +#define B_AX_SIFS_TIMEOUT_TB_AGGR_MASK GENMASK(30, 24) +#define B_AX_SIFS_PREBKF_MASK GENMASK(23, 16) +#define B_AX_SIFS_TIMEOUT_T2_MASK GENMASK(14, 8) +#define B_AX_SIFS_MACTXEN_T1_MASK GENMASK(6, 0) +#define SIFS_MACTXEN_T1 0x47 +#define SIFS_MACTXEN_T1_V1 0x41 + +#define R_AX_CCA_CFG_0 0xC340 +#define R_AX_CCA_CFG_0_C1 0xE340 +#define B_AX_BTCCA_BRK_TXOP_EN BIT(9) +#define B_AX_BTCCA_EN BIT(5) +#define B_AX_EDCCA_EN BIT(4) +#define B_AX_SEC80_EN BIT(3) +#define B_AX_SEC40_EN BIT(2) +#define B_AX_SEC20_EN BIT(1) +#define B_AX_CCA_EN BIT(0) + +#define R_AX_CTN_TXEN 0xC348 +#define R_AX_CTN_TXEN_C1 0xE348 +#define B_AX_CTN_TXEN_TWT_1 BIT(15) +#define B_AX_CTN_TXEN_TWT_0 BIT(14) +#define B_AX_CTN_TXEN_ULQ BIT(13) +#define B_AX_CTN_TXEN_BCNQ BIT(12) +#define B_AX_CTN_TXEN_HGQ BIT(11) +#define B_AX_CTN_TXEN_CPUMGQ BIT(10) +#define B_AX_CTN_TXEN_MGQ1 BIT(9) +#define B_AX_CTN_TXEN_MGQ BIT(8) +#define B_AX_CTN_TXEN_VO_1 BIT(7) +#define B_AX_CTN_TXEN_VI_1 BIT(6) +#define B_AX_CTN_TXEN_BK_1 BIT(5) +#define B_AX_CTN_TXEN_BE_1 BIT(4) +#define B_AX_CTN_TXEN_VO_0 BIT(3) +#define B_AX_CTN_TXEN_VI_0 BIT(2) +#define B_AX_CTN_TXEN_BK_0 BIT(1) +#define B_AX_CTN_TXEN_BE_0 BIT(0) +#define B_AX_CTN_TXEN_ALL_MASK GENMASK(15, 0) + +#define R_AX_MUEDCA_BE_PARAM_0 0xC350 +#define R_AX_MUEDCA_BE_PARAM_0_C1 0xE350 +#define B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK GENMASK(31, 16) +#define B_AX_MUEDCA_BE_PARAM_0_CW_MASK GENMASK(15, 8) +#define B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK GENMASK(7, 0) + +#define R_AX_MUEDCA_BK_PARAM_0 0xC354 +#define R_AX_MUEDCA_BK_PARAM_0_C1 0xE354 +#define R_AX_MUEDCA_VI_PARAM_0 0xC358 +#define R_AX_MUEDCA_VI_PARAM_0_C1 0xE358 +#define R_AX_MUEDCA_VO_PARAM_0 0xC35C +#define R_AX_MUEDCA_VO_PARAM_0_C1 0xE35C + +#define R_AX_MUEDCA_EN 0xC370 +#define R_AX_MUEDCA_EN_C1 0xE370 +#define B_AX_MUEDCA_WMM_SEL BIT(8) +#define B_AX_SET_MUEDCATIMER_TF_0 BIT(4) +#define B_AX_MUEDCA_EN_0 BIT(0) + +#define R_AX_CCA_CONTROL 0xC390 +#define R_AX_CCA_CONTROL_C1 0xE390 +#define B_AX_TB_CHK_TX_NAV BIT(31) +#define B_AX_TB_CHK_BASIC_NAV BIT(30) +#define B_AX_TB_CHK_BTCCA BIT(29) +#define B_AX_TB_CHK_EDCCA BIT(28) +#define B_AX_TB_CHK_CCA_S80 BIT(27) +#define B_AX_TB_CHK_CCA_S40 BIT(26) +#define B_AX_TB_CHK_CCA_S20 BIT(25) +#define B_AX_TB_CHK_CCA_P20 BIT(24) +#define B_AX_SIFS_CHK_BTCCA BIT(21) +#define B_AX_SIFS_CHK_EDCCA BIT(20) +#define B_AX_SIFS_CHK_CCA_S80 BIT(19) +#define B_AX_SIFS_CHK_CCA_S40 BIT(18) +#define B_AX_SIFS_CHK_CCA_S20 BIT(17) +#define B_AX_SIFS_CHK_CCA_P20 BIT(16) +#define B_AX_CTN_CHK_TXNAV BIT(8) +#define B_AX_CTN_CHK_INTRA_NAV BIT(7) +#define B_AX_CTN_CHK_BASIC_NAV BIT(6) +#define B_AX_CTN_CHK_BTCCA BIT(5) +#define B_AX_CTN_CHK_EDCCA BIT(4) +#define B_AX_CTN_CHK_CCA_S80 BIT(3) +#define B_AX_CTN_CHK_CCA_S40 BIT(2) +#define B_AX_CTN_CHK_CCA_S20 BIT(1) +#define B_AX_CTN_CHK_CCA_P20 BIT(0) + +#define R_AX_CTN_DRV_TXEN 0xC398 +#define R_AX_CTN_DRV_TXEN_C1 0xE398 +#define B_AX_CTN_TXEN_TWT_3 BIT(17) +#define B_AX_CTN_TXEN_TWT_2 BIT(16) +#define B_AX_CTN_TXEN_ALL_MASK_V1 GENMASK(17, 0) + +#define R_AX_SCHEDULE_ERR_IMR 0xC3E8 +#define R_AX_SCHEDULE_ERR_IMR_C1 0xE3E8 +#define B_AX_SORT_NON_IDLE_ERR_INT_EN BIT(1) + +#define R_AX_SCHEDULE_ERR_ISR 0xC3EC +#define R_AX_SCHEDULE_ERR_ISR_C1 0xE3EC + +#define R_AX_SCH_DBG_SEL 0xC3F4 +#define R_AX_SCH_DBG_SEL_C1 0xE3F4 +#define B_AX_SCH_DBG_EN BIT(16) +#define B_AX_SCH_CFG_CMD_SEL GENMASK(15, 8) +#define B_AX_SCH_DBG_SEL_MASK GENMASK(7, 0) + +#define R_AX_SCH_DBG 0xC3F8 +#define R_AX_SCH_DBG_C1 0xE3F8 +#define B_AX_SCHEDULER_DBG_MASK GENMASK(31, 0) + +#define R_AX_SCH_EXT_CTRL 0xC3FC +#define R_AX_SCH_EXT_CTRL_C1 0xE3FC +#define B_AX_PORT_RST_TSF_ADV BIT(1) + +#define R_AX_PORT_CFG_P0 0xC400 +#define R_AX_PORT_CFG_P1 0xC440 +#define R_AX_PORT_CFG_P2 0xC480 +#define R_AX_PORT_CFG_P3 0xC4C0 +#define R_AX_PORT_CFG_P4 0xC500 +#define B_AX_BRK_SETUP BIT(16) +#define B_AX_TBTT_UPD_SHIFT_SEL BIT(15) +#define B_AX_BCN_DROP_ALLOW BIT(14) +#define B_AX_TBTT_PROHIB_EN BIT(13) +#define B_AX_BCNTX_EN BIT(12) +#define B_AX_NET_TYPE_MASK GENMASK(11, 10) +#define B_AX_BCN_FORCETX_EN BIT(9) +#define B_AX_TXBCN_BTCCA_EN BIT(8) +#define B_AX_BCNERR_CNT_EN BIT(7) +#define B_AX_BCN_AGRES BIT(6) +#define B_AX_TSFTR_RST BIT(5) +#define B_AX_RX_BSSID_FIT_EN BIT(4) +#define B_AX_TSF_UDT_EN BIT(3) +#define B_AX_PORT_FUNC_EN BIT(2) +#define B_AX_TXBCN_RPT_EN BIT(1) +#define B_AX_RXBCN_RPT_EN BIT(0) + +#define R_AX_TBTT_PROHIB_P0 0xC404 +#define R_AX_TBTT_PROHIB_P1 0xC444 +#define R_AX_TBTT_PROHIB_P2 0xC484 +#define R_AX_TBTT_PROHIB_P3 0xC4C4 +#define R_AX_TBTT_PROHIB_P4 0xC504 +#define B_AX_TBTT_HOLD_MASK GENMASK(27, 16) +#define B_AX_TBTT_SETUP_MASK GENMASK(7, 0) + +#define R_AX_BCN_AREA_P0 0xC408 +#define R_AX_BCN_AREA_P1 0xC448 +#define R_AX_BCN_AREA_P2 0xC488 +#define R_AX_BCN_AREA_P3 0xC4C8 +#define R_AX_BCN_AREA_P4 0xC508 +#define B_AX_BCN_MSK_AREA_MASK GENMASK(27, 16) +#define B_AX_BCN_CTN_AREA_MASK GENMASK(11, 0) + +#define R_AX_BCNERLYINT_CFG_P0 0xC40C +#define R_AX_BCNERLYINT_CFG_P1 0xC44C +#define R_AX_BCNERLYINT_CFG_P2 0xC48C +#define R_AX_BCNERLYINT_CFG_P3 0xC4CC +#define R_AX_BCNERLYINT_CFG_P4 0xC50C +#define B_AX_BCNERLY_MASK GENMASK(11, 0) + +#define R_AX_TBTTERLYINT_CFG_P0 0xC40E +#define R_AX_TBTTERLYINT_CFG_P1 0xC44E +#define R_AX_TBTTERLYINT_CFG_P2 0xC48E +#define R_AX_TBTTERLYINT_CFG_P3 0xC4CE +#define R_AX_TBTTERLYINT_CFG_P4 0xC50E +#define B_AX_TBTTERLY_MASK GENMASK(11, 0) + +#define R_AX_TBTT_AGG_P0 0xC412 +#define R_AX_TBTT_AGG_P1 0xC452 +#define R_AX_TBTT_AGG_P2 0xC492 +#define R_AX_TBTT_AGG_P3 0xC4D2 +#define R_AX_TBTT_AGG_P4 0xC512 +#define B_AX_TBTT_AGG_NUM_MASK GENMASK(15, 8) + +#define R_AX_BCN_SPACE_CFG_P0 0xC414 +#define R_AX_BCN_SPACE_CFG_P1 0xC454 +#define R_AX_BCN_SPACE_CFG_P2 0xC494 +#define R_AX_BCN_SPACE_CFG_P3 0xC4D4 +#define R_AX_BCN_SPACE_CFG_P4 0xC514 +#define B_AX_SUB_BCN_SPACE_MASK GENMASK(23, 16) +#define B_AX_BCN_SPACE_MASK GENMASK(15, 0) + +#define R_AX_BCN_FORCETX_P0 0xC418 +#define R_AX_BCN_FORCETX_P1 0xC458 +#define R_AX_BCN_FORCETX_P2 0xC498 +#define R_AX_BCN_FORCETX_P3 0xC4D8 +#define R_AX_BCN_FORCETX_P4 0xC518 +#define B_AX_FORCE_BCN_CURRCNT_MASK GENMASK(23, 16) +#define B_AX_FORCE_BCN_NUM_MASK GENMASK(15, 0) +#define B_AX_BCN_MAX_ERR_MASK GENMASK(7, 0) + +#define R_AX_BCN_ERR_CNT_P0 0xC420 +#define R_AX_BCN_ERR_CNT_P1 0xC460 +#define R_AX_BCN_ERR_CNT_P2 0xC4A0 +#define R_AX_BCN_ERR_CNT_P3 0xC4E0 +#define R_AX_BCN_ERR_CNT_P4 0xC520 +#define B_AX_BCN_ERR_CNT_SUM_MASK GENMASK(31, 24) +#define B_AX_BCN_ERR_CNT_NAV_MASK GENMASK(23, 16) +#define B_AX_BCN_ERR_CNT_EDCCA_MASK GENMASK(15, 0) +#define B_AX_BCN_ERR_CNT_CCA_MASK GENMASK(7, 0) + +#define R_AX_BCN_ERR_FLAG_P0 0xC424 +#define R_AX_BCN_ERR_FLAG_P1 0xC464 +#define R_AX_BCN_ERR_FLAG_P2 0xC4A4 +#define R_AX_BCN_ERR_FLAG_P3 0xC4E4 +#define R_AX_BCN_ERR_FLAG_P4 0xC524 +#define B_AX_BCN_ERR_FLAG_OTHERS BIT(6) +#define B_AX_BCN_ERR_FLAG_MAC BIT(5) +#define B_AX_BCN_ERR_FLAG_TXON BIT(4) +#define B_AX_BCN_ERR_FLAG_SRCHEND BIT(3) +#define B_AX_BCN_ERR_FLAG_INVALID BIT(2) +#define B_AX_BCN_ERR_FLAG_CMP BIT(1) +#define B_AX_BCN_ERR_FLAG_LOCK BIT(0) + +#define R_AX_DTIM_CTRL_P0 0xC426 +#define R_AX_DTIM_CTRL_P1 0xC466 +#define R_AX_DTIM_CTRL_P2 0xC4A6 +#define R_AX_DTIM_CTRL_P3 0xC4E6 +#define R_AX_DTIM_CTRL_P4 0xC526 +#define B_AX_DTIM_NUM_MASK GENMASK(15, 8) +#define B_AX_DTIM_CURRCNT_MASK GENMASK(7, 0) + +#define R_AX_TBTT_SHIFT_P0 0xC428 +#define R_AX_TBTT_SHIFT_P1 0xC468 +#define R_AX_TBTT_SHIFT_P2 0xC4A8 +#define R_AX_TBTT_SHIFT_P3 0xC4E8 +#define R_AX_TBTT_SHIFT_P4 0xC528 +#define B_AX_TBTT_SHIFT_OFST_MASK GENMASK(11, 0) +#define B_AX_TBTT_SHIFT_OFST_SIGN BIT(11) +#define B_AX_TBTT_SHIFT_OFST_MAG GENMASK(10, 0) + +#define R_AX_BCN_CNT_TMR_P0 0xC434 +#define R_AX_BCN_CNT_TMR_P1 0xC474 +#define R_AX_BCN_CNT_TMR_P2 0xC4B4 +#define R_AX_BCN_CNT_TMR_P3 0xC4F4 +#define R_AX_BCN_CNT_TMR_P4 0xC534 +#define B_AX_BCN_CNT_TMR_MASK GENMASK(31, 0) + +#define R_AX_TSFTR_LOW_P0 0xC438 +#define R_AX_TSFTR_LOW_P1 0xC478 +#define R_AX_TSFTR_LOW_P2 0xC4B8 +#define R_AX_TSFTR_LOW_P3 0xC4F8 +#define R_AX_TSFTR_LOW_P4 0xC538 +#define B_AX_TSFTR_LOW_MASK GENMASK(31, 0) + +#define R_AX_TSFTR_HIGH_P0 0xC43C +#define R_AX_TSFTR_HIGH_P1 0xC47C +#define R_AX_TSFTR_HIGH_P2 0xC4BC +#define R_AX_TSFTR_HIGH_P3 0xC4FC +#define R_AX_TSFTR_HIGH_P4 0xC53C +#define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0) + +#define R_AX_BCN_DROP_ALL0 0xC560 +#define R_AX_BCN_DROP_ALL0_C1 0xE560 +#define B_AX_BCN_DROP_ALL_P4 BIT(4) +#define B_AX_BCN_DROP_ALL_P3 BIT(3) +#define B_AX_BCN_DROP_ALL_P2 BIT(2) +#define B_AX_BCN_DROP_ALL_P1 BIT(1) +#define B_AX_BCN_DROP_ALL_P0 BIT(0) + +#define R_AX_MBSSID_CTRL 0xC568 +#define R_AX_MBSSID_CTRL_C1 0xE568 +#define B_AX_P0MB_ALL_MASK GENMASK(23, 1) +#define B_AX_P0MB_NUM_MASK GENMASK(19, 16) +#define B_AX_P0MB15_EN BIT(15) +#define B_AX_P0MB14_EN BIT(14) +#define B_AX_P0MB13_EN BIT(13) +#define B_AX_P0MB12_EN BIT(12) +#define B_AX_P0MB11_EN BIT(11) +#define B_AX_P0MB10_EN BIT(10) +#define B_AX_P0MB9_EN BIT(9) +#define B_AX_P0MB8_EN BIT(8) +#define B_AX_P0MB7_EN BIT(7) +#define B_AX_P0MB6_EN BIT(6) +#define B_AX_P0MB5_EN BIT(5) +#define B_AX_P0MB4_EN BIT(4) +#define B_AX_P0MB3_EN BIT(3) +#define B_AX_P0MB2_EN BIT(2) +#define B_AX_P0MB1_EN BIT(1) + +#define R_AX_P0MB_HGQ_WINDOW_CFG_0 0xC590 +#define R_AX_P0MB_HGQ_WINDOW_CFG_0_C1 0xE590 +#define R_AX_PORT_HGQ_WINDOW_CFG 0xC5A0 +#define R_AX_PORT_HGQ_WINDOW_CFG_C1 0xE5A0 + +#define R_AX_PTCL_COMMON_SETTING_0 0xC600 +#define R_AX_PTCL_COMMON_SETTING_0_C1 0xE600 +#define B_AX_PCIE_MODE_MASK GENMASK(15, 14) +#define B_AX_CPUMGQ_LIFETIME_EN BIT(8) +#define B_AX_MGQ_LIFETIME_EN BIT(7) +#define B_AX_LIFETIME_EN BIT(6) +#define B_AX_PTCL_TRIGGER_SS_EN_UL BIT(4) +#define B_AX_PTCL_TRIGGER_SS_EN_1 BIT(3) +#define B_AX_PTCL_TRIGGER_SS_EN_0 BIT(2) +#define B_AX_CMAC_TX_MODE_1 BIT(1) +#define B_AX_CMAC_TX_MODE_0 BIT(0) + +#define R_AX_AMPDU_AGG_LIMIT 0xC610 +#define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24) +#define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) +#define B_AX_RTS_MAX_AGG_NUM_MASK GENMASK(15, 8) +#define B_AX_MAX_AGG_NUM_MASK GENMASK(7, 0) + +#define R_AX_AGG_LEN_HT_0 0xC614 +#define R_AX_AGG_LEN_HT_0_C1 0xE614 +#define B_AX_AMPDU_MAX_LEN_HT_MASK GENMASK(31, 16) +#define B_AX_RTS_TXTIME_TH_MASK GENMASK(15, 8) +#define B_AX_RTS_LEN_TH_MASK GENMASK(7, 0) + +#define R_AX_AGG_LEN_VHT_0 0xC618 +#define R_AX_AGG_LEN_VHT_0_C1 0xE618 +#define B_AX_AMPDU_MAX_LEN_VHT_MASK GENMASK(19, 0) + +#define S_AX_CTS2S_TH_SEC_256B 1 +#define R_AX_SIFS_SETTING 0xC624 +#define R_AX_SIFS_SETTING_C1 0xE624 +#define B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK GENMASK(31, 24) +#define B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK GENMASK(23, 18) +#define B_AX_HW_CTS2SELF_EN BIT(16) +#define B_AX_SPEC_SIFS_OFDM_PTCL_SH 8 +#define B_AX_SPEC_SIFS_OFDM_PTCL_MASK GENMASK(15, 8) +#define B_AX_SPEC_SIFS_CCK_PTCL_MASK GENMASK(7, 0) +#define S_AX_CTS2S_TH_1K 4 + +#define R_AX_TXRATE_CHK 0xC628 +#define R_AX_TXRATE_CHK_C1 0xE628 +#define B_AX_DEFT_RATE_MASK GENMASK(15, 7) +#define B_AX_BAND_MODE BIT(4) +#define B_AX_MAX_TXNSS_MASK GENMASK(3, 2) +#define B_AX_RTS_LIMIT_IN_OFDM6 BIT(1) +#define B_AX_CHECK_CCK_EN BIT(0) + +#define R_AX_TXCNT 0xC62C +#define R_AX_TXCNT_C1 0xE62C +#define B_AX_ADD_TXCNT_BY BIT(31) +#define B_AX_S_TXCNT_LMT_MASK GENMASK(29, 24) +#define B_AX_L_TXCNT_LMT_MASK GENMASK(21, 16) + +#define R_AX_MBSSID_DROP_0 0xC63C +#define R_AX_MBSSID_DROP_0_C1 0xE63C +#define B_AX_GI_LTF_FB_SEL BIT(30) +#define B_AX_RATE_SEL_MASK GENMASK(29, 24) +#define B_AX_PORT_DROP_4_0_MASK GENMASK(20, 16) +#define B_AX_MBSSID_DROP_15_0_MASK GENMASK(15, 0) + +#define R_AX_PTCLRPT_FULL_HDL 0xC660 +#define R_AX_PTCLRPT_FULL_HDL_C1 0xE660 +#define B_AX_RPT_LATCH_PHY_TIME_MASK GENMASK(15, 12) +#define B_AX_F2PCMD_FWWD_RLS_MODE BIT(9) +#define B_AX_F2PCMD_RPT_EN BIT(8) +#define B_AX_BCN_RPT_PATH_MASK GENMASK(7, 6) +#define B_AX_SPE_RPT_PATH_MASK GENMASK(5, 4) +#define FWD_TO_WLCPU 1 +#define B_AX_TX_RPT_PATH_MASK GENMASK(3, 2) +#define B_AX_F2PCMDRPT_FULL_DROP BIT(1) +#define B_AX_NON_F2PCMDRPT_FULL_DROP BIT(0) + +#define R_AX_BT_PLT 0xC67C +#define R_AX_BT_PLT_C1 0xE67C +#define B_AX_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) +#define B_AX_BT_PLT_RST BIT(9) +#define B_AX_PLT_EN BIT(8) +#define B_AX_RX_PLT_GNT_LTE_RX BIT(7) +#define B_AX_RX_PLT_GNT_BT_RX BIT(6) +#define B_AX_RX_PLT_GNT_BT_TX BIT(5) +#define B_AX_RX_PLT_GNT_WL BIT(4) +#define B_AX_TX_PLT_GNT_LTE_RX BIT(3) +#define B_AX_TX_PLT_GNT_BT_RX BIT(2) +#define B_AX_TX_PLT_GNT_BT_TX BIT(1) +#define B_AX_TX_PLT_GNT_WL BIT(0) + +#define R_AX_PTCL_BSS_COLOR_0 0xC6A0 +#define R_AX_PTCL_BSS_COLOR_0_C1 0xE6A0 +#define B_AX_BSS_COLOB_AX_PORT_3_MASK GENMASK(29, 24) +#define B_AX_BSS_COLOB_AX_PORT_2_MASK GENMASK(21, 16) +#define B_AX_BSS_COLOB_AX_PORT_1_MASK GENMASK(13, 8) +#define B_AX_BSS_COLOB_AX_PORT_0_MASK GENMASK(5, 0) + +#define R_AX_PTCL_BSS_COLOR_1 0xC6A4 +#define R_AX_PTCL_BSS_COLOR_1_C1 0xE6A4 +#define B_AX_BSS_COLOB_AX_PORT_4_MASK GENMASK(5, 0) + +#define R_AX_PTCL_IMR0 0xC6C0 +#define R_AX_PTCL_IMR0_C1 0xE6C0 +#define B_AX_F2PCMD_PKTID_ERR_INT_EN BIT(31) +#define B_AX_F2PCMD_RD_PKTID_ERR_INT_EN BIT(30) +#define B_AX_F2PCMD_ASSIGN_PKTID_ERR_INT_EN BIT(29) +#define B_AX_F2PCMD_USER_ALLC_ERR_INT_EN BIT(28) +#define B_AX_RX_SPF_U0_PKTID_ERR_INT_EN BIT(27) +#define B_AX_TX_SPF_U1_PKTID_ERR_INT_EN BIT(26) +#define B_AX_TX_SPF_U2_PKTID_ERR_INT_EN BIT(25) +#define B_AX_TX_SPF_U3_PKTID_ERR_INT_EN BIT(24) +#define B_AX_TX_RECORD_PKTID_ERR_INT_EN BIT(23) +#define B_AX_F2PCMD_EMPTY_ERR_INT_EN BIT(15) +#define B_AX_TWTSP_QSEL_ERR_INT_EN BIT(14) +#define B_AX_BCNQ_ORDER_ERR_INT_EN BIT(12) +#define B_AX_Q_PKTID_ERR_INT_EN BIT(11) +#define B_AX_D_PKTID_ERR_INT_EN BIT(10) +#define B_AX_TXPRT_FULL_DROP_ERR_INT_EN BIT(9) +#define B_AX_F2PCMDRPT_FULL_DROP_ERR_INT_EN BIT(8) +#define B_AX_FSM1_TIMEOUT_ERR_INT_EN BIT(1) +#define B_AX_FSM_TIMEOUT_ERR_INT_EN BIT(0) +#define B_AX_PTCL_IMR_CLR_ALL GENMASK(31, 0) +#define B_AX_PTCL_IMR_CLR (B_AX_FSM_TIMEOUT_ERR_INT_EN | \ + B_AX_F2PCMDRPT_FULL_DROP_ERR_INT_EN | \ + B_AX_TXPRT_FULL_DROP_ERR_INT_EN | \ + B_AX_D_PKTID_ERR_INT_EN | \ + B_AX_Q_PKTID_ERR_INT_EN | \ + B_AX_BCNQ_ORDER_ERR_INT_EN | \ + B_AX_TWTSP_QSEL_ERR_INT_EN | \ + B_AX_F2PCMD_EMPTY_ERR_INT_EN | \ + B_AX_TX_RECORD_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U3_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U2_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U1_PKTID_ERR_INT_EN | \ + B_AX_RX_SPF_U0_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_USER_ALLC_ERR_INT_EN | \ + B_AX_F2PCMD_ASSIGN_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_RD_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_PKTID_ERR_INT_EN) +#define B_AX_PTCL_IMR_SET (B_AX_FSM_TIMEOUT_ERR_INT_EN | \ + B_AX_TX_RECORD_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_USER_ALLC_ERR_INT_EN) +#define B_AX_PTCL_IMR_CLR_V1 (B_AX_FSM1_TIMEOUT_ERR_INT_EN | \ + B_AX_FSM_TIMEOUT_ERR_INT_EN) +#define B_AX_PTCL_IMR_SET_V1 (B_AX_FSM1_TIMEOUT_ERR_INT_EN | \ + B_AX_FSM_TIMEOUT_ERR_INT_EN) + +#define R_AX_PTCL_ISR0 0xC6C4 +#define R_AX_PTCL_ISR0_C1 0xE6C4 + +#define S_AX_PTCL_TO_2MS 0x3F +#define R_AX_PTCL_FSM_MON 0xC6E8 +#define R_AX_PTCL_FSM_MON_C1 0xE6E8 +#define B_AX_PTCL_TX_ARB_TO_MODE BIT(6) +#define B_AX_PTCL_TX_ARB_TO_THR_MASK GENMASK(5, 0) + +#define R_AX_PTCL_TX_CTN_SEL 0xC6EC +#define R_AX_PTCL_TX_CTN_SEL_C1 0xE6EC +#define B_AX_PTCL_TX_ON_STAT BIT(7) + +#define R_AX_PTCL_DBG_INFO 0xC6F0 +#define R_AX_PTCL_DBG_INFO_C1 0xE6F0 +#define B_AX_PTCL_DBG_INFO_MASK_BY_PORT(port) \ +({\ + typeof(port) _port = (port); \ + GENMASK((_port) * 2 + 1, (_port) * 2); \ +}) + +#define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0) +#define R_AX_PTCL_DBG 0xC6F4 +#define R_AX_PTCL_DBG_C1 0xE6F4 +#define B_AX_PTCL_DBG_EN BIT(8) +#define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0) +#define AX_PTCL_DBG_BCNQ_NUM0 8 +#define AX_PTCL_DBG_BCNQ_NUM1 9 + + +#define R_AX_DLE_CTRL 0xC800 +#define R_AX_DLE_CTRL_C1 0xE800 +#define B_AX_NO_RESERVE_PAGE_ERR_IMR BIT(23) +#define B_AX_RXDATA_FSM_HANG_ERROR_IMR BIT(15) +#define B_AX_RXSTS_FSM_HANG_ERROR_IMR BIT(14) +#define B_AX_DLE_IMR_CLR (B_AX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_AX_RXDATA_FSM_HANG_ERROR_IMR | \ + B_AX_NO_RESERVE_PAGE_ERR_IMR) +#define B_AX_DLE_IMR_SET (B_AX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_AX_RXDATA_FSM_HANG_ERROR_IMR) + +#define R_AX_RX_ERR_FLAG 0xC800 +#define R_AX_RX_ERR_FLAG_C1 0xE800 +#define B_AX_RX_GET_NO_PAGE_ERR BIT(31) +#define B_AX_RX_GET_NULL_PKT_ERR BIT(30) +#define B_AX_RX_RU0_FSM_HANG_ERR BIT(29) +#define B_AX_RX_RU1_FSM_HANG_ERR BIT(28) +#define B_AX_RX_RU2_FSM_HANG_ERR BIT(27) +#define B_AX_RX_RU3_FSM_HANG_ERR BIT(26) +#define B_AX_RX_RU4_FSM_HANG_ERR BIT(25) +#define B_AX_RX_RU5_FSM_HANG_ERR BIT(24) +#define B_AX_RX_RU6_FSM_HANG_ERR BIT(23) +#define B_AX_RX_RU7_FSM_HANG_ERR BIT(22) +#define B_AX_RX_RXSTS_FSM_HANG_ERR BIT(21) +#define B_AX_RX_CSI_FSM_HANG_ERR BIT(20) +#define B_AX_RX_TXRPT_FSM_HANG_ERR BIT(19) +#define B_AX_RX_F2PCMD_FSM_HANG_ERR BIT(18) +#define B_AX_RX_RU0_ZERO_LEN_ERR BIT(17) +#define B_AX_RX_RU1_ZERO_LEN_ERR BIT(16) +#define B_AX_RX_RU2_ZERO_LEN_ERR BIT(15) +#define B_AX_RX_RU3_ZERO_LEN_ERR BIT(14) +#define B_AX_RX_RU4_ZERO_LEN_ERR BIT(13) +#define B_AX_RX_RU5_ZERO_LEN_ERR BIT(12) +#define B_AX_RX_RU6_ZERO_LEN_ERR BIT(11) +#define B_AX_RX_RU7_ZERO_LEN_ERR BIT(10) +#define B_AX_RX_RXSTS_ZERO_LEN_ERR BIT(9) +#define B_AX_RX_CSI_ZERO_LEN_ERR BIT(8) +#define B_AX_PLE_DATA_OPT_FSM_HANG BIT(7) +#define B_AX_PLE_RXDATA_REQ_BUF_FSM_HANG BIT(6) +#define B_AX_PLE_TXRPT_REQ_BUF_FSM_HANG BIT(5) +#define B_AX_PLE_WD_OPT_FSM_HANG BIT(4) +#define B_AX_PLE_ENQ_FSM_HANG BIT(3) +#define B_AX_RXDATA_ENQUE_ORDER_ERR BIT(2) +#define B_AX_RXSTS_ENQUE_ORDER_ERR BIT(1) +#define B_AX_RX_CSI_PKT_NUM_ERR BIT(0) + +#define R_AX_RXDMA_CTRL_0 0xC804 +#define R_AX_RXDMA_CTRL_0_C1 0xE804 +#define B_AX_RXDMA_DBGOUT_EN BIT(31) +#define B_AX_RXDMA_DBG_SEL_MASK GENMASK(30, 29) +#define B_AX_RXDMA_FIFO_DBG_SEL_MASK GENMASK(28, 25) +#define B_AX_RXDMA_DEFAULT_PAGE_MASK GENMASK(22, 21) +#define B_AX_RXDMA_BUFF_REQ_PRI_MASK GENMASK(20, 19) +#define B_AX_RXDMA_TGT_QUEID_MASK GENMASK(18, 13) +#define B_AX_RXDMA_TGT_PRID_MASK GENMASK(12, 10) +#define B_AX_RXDMA_DIS_CSI_RELEASE BIT(9) +#define B_AX_RXDMA_DIS_RXSTS_WAIT_PTR_CLR BIT(7) +#define B_AX_RXDMA_DIS_CSI_WAIT_PTR_CLR BIT(6) +#define B_AX_RXSTS_PTR_FULL_MODE BIT(5) +#define B_AX_CSI_PTR_FULL_MODE BIT(4) +#define B_AX_RU3_PTR_FULL_MODE BIT(3) +#define B_AX_RU2_PTR_FULL_MODE BIT(2) +#define B_AX_RU1_PTR_FULL_MODE BIT(1) +#define B_AX_RU0_PTR_FULL_MODE BIT(0) +#define RX_FULL_MODE (B_AX_RU0_PTR_FULL_MODE | B_AX_RU1_PTR_FULL_MODE | \ + B_AX_RU2_PTR_FULL_MODE | B_AX_RU3_PTR_FULL_MODE | \ + B_AX_CSI_PTR_FULL_MODE | B_AX_RXSTS_PTR_FULL_MODE) + +#define R_AX_RX_CTRL0 0xC808 +#define R_AX_RX_CTRL0_C1 0xE808 +#define B_AX_DLE_CLOCK_FORCE_V1 BIT(31) +#define B_AX_TXDMA_CLOCK_FORCE_V1 BIT(30) +#define B_AX_RXDMA_CLOCK_FORCE_V1 BIT(29) +#define B_AX_RXDMA_DEFAULT_PAGE_V1_MASK GENMASK(28, 24) +#define B_AX_RXDMA_CSI_TGT_QUEID_MASK GENMASK(23, 18) +#define B_AX_RXDMA_CSI_TGT_PRID_MASK GENMASK(17, 15) +#define B_AX_RXDMA_DIS_CSI_RELEASE_V1 BIT(14) +#define B_AX_CSI_PTR_FULL_MODE_V1 BIT(13) +#define B_AX_RXDATA_PTR_FULL_MODE BIT(12) +#define B_AX_RXSTS_PTR_FULL_MODE_V1 BIT(11) +#define B_AX_TXRPT_FULL_RSV_DEPTH_V1_MASK GENMASK(10, 8) +#define B_AX_RXDATA_FULL_RSV_DEPTH_MASK GENMASK(7, 5) +#define B_AX_RXSTS_FULL_RSV_DEPTH_V1_MASK GENMASK(4, 2) +#define B_AX_ORDER_FIFO_MASK GENMASK(1, 0) + +#define R_AX_RX_CTRL1 0xC80C +#define R_AX_RX_CTRL1_C1 0xE80C +#define B_AX_RXDMA_TXRPT_QUEUE_ID_SW_EN BIT(31) +#define B_AX_RXDMA_TXRPT_QUEUE_ID_SW_V1_MASK GENMASK(30, 25) +#define B_AX_RXDMA_F2PCMD_QUEUE_ID_SW_EN BIT(24) +#define B_AX_RXDMA_F2PCMD_QUEUE_ID_SW_V1_MASK GENMASK(23, 18) +#define B_AX_RXDMA_TXRPT_QUEUE_ID_TGT_SW_EN BIT(17) +#define B_AX_RXDMA_TXRPT_QUEUE_ID_TGT_SW_1_MASK GENMASK(16, 11) +#define B_AX_RXDMA_F2PCMD_QUEUE_ID_TGT_SW_EN BIT(10) +#define B_AX_RXDMA_F2PCMD_QUEUE_ID_TGT_SW_1_MASK GENMASK(9, 4) +#define B_AX_ORDER_FIFO_OUT BIT(3) +#define B_AX_ORDER_FIFO_EMPTY BIT(2) +#define B_AX_DBG_SEL_MASK GENMASK(1, 0) + +#define R_AX_RX_CTRL2 0xC810 +#define R_AX_RX_CTRL2_C1 0xE810 +#define B_AX_DLE_WDE_STATE_V1_MASK GENMASK(31, 30) +#define B_AX_DLE_PLE_STATE_V1_MASK GENMASK(29, 28) +#define B_AX_DLE_REQ_BUF_STATE_MASK GENMASK(27, 26) +#define B_AX_DLE_ENQ_STATE_V1 BIT(25) +#define B_AX_RX_DBG_SEL_MASK GENMASK(24, 19) +#define B_AX_MACRX_CS_MASK GENMASK(18, 14) +#define B_AX_RXSTS_CS_MASK GENMASK(13, 9) +#define B_AX_ERR_INDICATOR BIT(5) +#define B_AX_TXRPT_CS_MASK GENMASK(4, 0) + +#define R_AX_RXDMA_PKT_INFO_0 0xC814 +#define R_AX_RXDMA_PKT_INFO_1 0xC818 +#define R_AX_RXDMA_PKT_INFO_2 0xC81C + +#define R_AX_RX_ERR_FLAG_IMR 0xC804 +#define R_AX_RX_ERR_FLAG_IMR_C1 0xE804 +#define B_AX_RX_GET_NULL_PKT_ERR_MSK BIT(30) +#define B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK BIT(29) +#define B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK BIT(28) +#define B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK BIT(27) +#define B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK BIT(26) +#define B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK BIT(25) +#define B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK BIT(24) +#define B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK BIT(23) +#define B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK BIT(22) +#define B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK BIT(21) +#define B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK BIT(20) +#define B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK BIT(19) +#define B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK BIT(18) +#define B_AX_RX_RU0_ZERO_LEN_ERR_MSK BIT(17) +#define B_AX_RX_RU1_ZERO_LEN_ERR_MSK BIT(16) +#define B_AX_RX_RU2_ZERO_LEN_ERR_MSK BIT(15) +#define B_AX_RX_RU3_ZERO_LEN_ERR_MSK BIT(14) +#define B_AX_RX_RU4_ZERO_LEN_ERR_MSK BIT(13) +#define B_AX_RX_RU5_ZERO_LEN_ERR_MSK BIT(12) +#define B_AX_RX_RU6_ZERO_LEN_ERR_MSK BIT(11) +#define B_AX_RX_RU7_ZERO_LEN_ERR_MSK BIT(10) +#define B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK BIT(9) +#define B_AX_RX_CSI_ZERO_LEN_ERR_MSK BIT(8) +#define B_AX_PLE_DATA_OPT_FSM_HANG_MSK BIT(7) +#define B_AX_PLE_RXDATA_REQ_BUF_FSM_HANG_MSK BIT(6) +#define B_AX_PLE_TXRPT_REQ_BUF_FSM_HANG_MSK BIT(5) +#define B_AX_PLE_WD_OPT_FSM_HANG_MSK BIT(4) +#define B_AX_PLE_ENQ_FSM_HANG_MSK BIT(3) +#define B_AX_RXDATA_ENQUE_ORDER_ERR_MSK BIT(2) +#define B_AX_RXSTS_ENQUE_ORDER_ERR_MSK BIT(1) +#define B_AX_RX_CSI_PKT_NUM_ERR_MSK BIT(0) +#define B_AX_RX_ERR_IMR_CLR_V1 (B_AX_RXSTS_ENQUE_ORDER_ERR_MSK | \ + B_AX_RXDATA_ENQUE_ORDER_ERR_MSK | \ + B_AX_RX_CSI_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU7_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU6_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU5_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU4_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU3_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU2_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU1_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU0_ZERO_LEN_ERR_MSK | \ + B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_GET_NULL_PKT_ERR_MSK) +#define B_AX_RX_ERR_IMR_SET_V1 (B_AX_RXSTS_ENQUE_ORDER_ERR_MSK | \ + B_AX_RXDATA_ENQUE_ORDER_ERR_MSK | \ + B_AX_RX_CSI_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU7_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU6_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU5_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU4_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU3_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU2_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU1_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU0_ZERO_LEN_ERR_MSK | \ + B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_GET_NULL_PKT_ERR_MSK) + +#define R_AX_TX_ERR_FLAG_IMR 0xC870 +#define R_AX_TX_ERR_FLAG_IMR_C1 0xE870 +#define B_AX_TX_RU0_FSM_HANG_ERR_MSK BIT(31) +#define B_AX_TX_RU1_FSM_HANG_ERR_MSK BIT(30) +#define B_AX_TX_RU2_FSM_HANG_ERR_MSK BIT(29) +#define B_AX_TX_RU3_FSM_HANG_ERR_MSK BIT(28) +#define B_AX_TX_RU4_FSM_HANG_ERR_MSK BIT(27) +#define B_AX_TX_RU5_FSM_HANG_ERR_MSK BIT(26) +#define B_AX_TX_RU6_FSM_HANG_ERR_MSK BIT(25) +#define B_AX_TX_RU7_FSM_HANG_ERR_MSK BIT(24) +#define B_AX_TX_RU8_FSM_HANG_ERR_MSK BIT(23) +#define B_AX_TX_RU9_FSM_HANG_ERR_MSK BIT(22) +#define B_AX_TX_RU10_FSM_HANG_ERR_MSK BIT(21) +#define B_AX_TX_RU11_FSM_HANG_ERR_MSK BIT(20) +#define B_AX_TX_RU12_FSM_HANG_ERR_MSK BIT(19) +#define B_AX_TX_RU13_FSM_HANG_ERR_MSK BIT(18) +#define B_AX_TX_RU14_FSM_HANG_ERR_MSK BIT(17) +#define B_AX_TX_RU15_FSM_HANG_ERR_MSK BIT(16) +#define B_AX_TX_CSI_FSM_HANG_ERR_MSK BIT(15) +#define B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK BIT(14) +#define B_AX_TX_ERR_IMR_CLR_V1 (B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK | \ + B_AX_TX_CSI_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU7_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU6_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU5_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU4_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU3_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU2_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU1_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU0_FSM_HANG_ERR_MSK) +#define B_AX_TX_ERR_IMR_SET_V1 (B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK | \ + B_AX_TX_CSI_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU7_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU6_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU5_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU4_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU3_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU2_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU1_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU0_FSM_HANG_ERR_MSK) + +#define R_AX_TCR0 0xCA00 +#define R_AX_TCR0_C1 0xEA00 +#define B_AX_TCR_ZLD_NUM_MASK GENMASK(31, 24) +#define B_AX_TCR_UDF_EN BIT(23) +#define B_AX_TCR_UDF_THSD_MASK GENMASK(22, 16) +#define TCR_UDF_THSD 0x6 +#define B_AX_TCR_ERRSTEN_MASK GENMASK(15, 10) +#define B_AX_TCR_VHTSIGA1_TXPS BIT(9) +#define B_AX_TCR_PLCP_ERRHDL_EN BIT(8) +#define B_AX_TCR_PADSEL BIT(7) +#define B_AX_TCR_MASK_SIGBCRC BIT(6) +#define B_AX_TCR_SR_VAL15_ALLOW BIT(5) +#define B_AX_TCR_EN_EOF BIT(4) +#define B_AX_TCR_EN_SCRAM_INC BIT(3) +#define B_AX_TCR_EN_20MST BIT(2) +#define B_AX_TCR_CRC BIT(1) +#define B_AX_TCR_DISGCLK BIT(0) + +#define R_AX_TCR1 0xCA04 +#define R_AX_TCR1_C1 0xEA04 +#define B_AX_TXDFIFO_THRESHOLD GENMASK(31, 28) +#define B_AX_TCR_CCK_LOCK_CLK BIT(27) +#define B_AX_TCR_FORCE_READ_TXDFIFO BIT(26) +#define B_AX_TCR_USTIME GENMASK(23, 16) +#define B_AX_TCR_SMOOTH_VAL BIT(15) +#define B_AX_TCR_SMOOTH_CTRL BIT(14) +#define B_AX_CS_REQ_VAL BIT(13) +#define B_AX_CS_REQ_SEL BIT(12) +#define B_AX_TCR_ZLD_USTIME_AFTERPHYTXON GENMASK(11, 8) +#define B_AX_TCR_TXTIMEOUT GENMASK(7, 0) + +#define R_AX_MD_TSFT_STMP_CTL 0xCA08 +#define R_AX_MD_TSFT_STMP_CTL_C1 0xEA08 +#define B_AX_TSFT_OFS_MASK GENMASK(31, 16) +#define B_AX_STMP_THSD_MASK GENMASK(15, 8) +#define B_AX_UPD_HGQMD BIT(1) +#define B_AX_UPD_TIMIE BIT(0) + +#define R_AX_PPWRBIT_SETTING 0xCA0C +#define R_AX_PPWRBIT_SETTING_C1 0xEA0C + +#define R_AX_TXD_FIFO_CTRL 0xCA1C +#define R_AX_TXD_FIFO_CTRL_C1 0xEA1C +#define B_AX_NON_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(28, 24) +#define B_AX_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(20, 16) +#define B_AX_TXDFIFO_HIGH_MCS_THRE_MASK GENMASK(15, 12) +#define TXDFIFO_HIGH_MCS_THRE 0x7 +#define B_AX_TXDFIFO_LOW_MCS_THRE_MASK GENMASK(11, 8) +#define TXDFIFO_LOW_MCS_THRE 0x7 +#define B_AX_HIGH_MCS_PHY_RATE_MASK GENMASK(7, 4) +#define B_AX_BW_PHY_RATE_MASK GENMASK(1, 0) + +#define R_AX_MACTX_DBG_SEL_CNT 0xCA20 +#define R_AX_MACTX_DBG_SEL_CNT_C1 0xEA20 +#define B_AX_MACTX_MPDU_CNT GENMASK(31, 24) +#define B_AX_MACTX_DMA_CNT GENMASK(23, 16) +#define B_AX_LENGTH_ERR_FLAG_U3 BIT(11) +#define B_AX_LENGTH_ERR_FLAG_U2 BIT(10) +#define B_AX_LENGTH_ERR_FLAG_U1 BIT(9) +#define B_AX_LENGTH_ERR_FLAG_U0 BIT(8) +#define B_AX_DBGSEL_MACTX_MASK GENMASK(5, 0) + +#define R_AX_WMAC_TX_CTRL_DEBUG 0xCAE4 +#define R_AX_WMAC_TX_CTRL_DEBUG_C1 0xEAE4 +#define B_AX_TX_CTRL_DEBUG_SEL_MASK GENMASK(3, 0) + +#define R_AX_WMAC_TX_INFO0_DEBUG 0xCAE8 +#define R_AX_WMAC_TX_INFO0_DEBUG_C1 0xEAE8 +#define B_AX_TX_CTRL_INFO_P0_MASK GENMASK(31, 0) + +#define R_AX_WMAC_TX_INFO1_DEBUG 0xCAEC +#define R_AX_WMAC_TX_INFO1_DEBUG_C1 0xEAEC +#define B_AX_TX_CTRL_INFO_P1_MASK GENMASK(31, 0) + +#define R_AX_RSP_CHK_SIG 0xCC00 +#define R_AX_RSP_CHK_SIG_C1 0xEC00 +#define B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN BIT(30) +#define B_AX_RSP_TBPPDU_CHK_PWR BIT(29) +#define B_AX_RSP_CHK_BASIC_NAV BIT(21) +#define B_AX_RSP_CHK_INTRA_NAV BIT(20) +#define B_AX_RSP_CHK_TXNAV BIT(19) +#define B_AX_TXDATA_END_PS_OPT BIT(18) +#define B_AX_CHECK_SOUNDING_SEQ BIT(17) +#define B_AX_RXBA_IGNOREA2 BIT(16) +#define B_AX_ACKTO_CCK_MASK GENMASK(15, 8) +#define B_AX_ACKTO_MASK GENMASK(7, 0) + +#define R_AX_TRXPTCL_RESP_0 0xCC04 +#define R_AX_TRXPTCL_RESP_0_C1 0xEC04 +#define B_AX_WMAC_RESP_STBC_EN BIT(31) +#define B_AX_WMAC_RXFTM_TXACK_SC BIT(30) +#define B_AX_WMAC_RXFTM_TXACKBWEQ BIT(29) +#define B_AX_RSP_CHK_SEC_CCA_80 BIT(28) +#define B_AX_RSP_CHK_SEC_CCA_40 BIT(27) +#define B_AX_RSP_CHK_SEC_CCA_20 BIT(26) +#define B_AX_RSP_CHK_BTCCA BIT(25) +#define B_AX_RSP_CHK_EDCCA BIT(24) +#define B_AX_RSP_CHK_CCA BIT(23) +#define B_AX_WMAC_LDPC_EN BIT(22) +#define B_AX_WMAC_SGIEN BIT(21) +#define B_AX_WMAC_SPLCPEN BIT(20) +#define B_AX_WMAC_BESP_EARLY_TXBA BIT(17) +#define B_AX_WMAC_SPEC_SIFS_OFDM_MASK GENMASK(15, 8) +#define B_AX_WMAC_SPEC_SIFS_CCK_MASK GENMASK(7, 0) +#define WMAC_SPEC_SIFS_OFDM_52A 0x15 +#define WMAC_SPEC_SIFS_OFDM_52B 0x11 +#define WMAC_SPEC_SIFS_OFDM_52C 0x11 +#define WMAC_SPEC_SIFS_CCK 0xA + +#define R_AX_TRXPTCL_RRSR_CTL_0 0xCC08 +#define R_AX_TRXPTCL_RRSR_CTL_0_C1 0xEC08 +#define B_AX_RESP_TX_MACID_CCA_TH_EN BIT(31) +#define B_AX_RESP_TX_PWRMODE_MASK GENMASK(30, 28) +#define B_AX_FTM_RRSR_RATE_EN_MASK GENMASK(27, 24) +#define B_AX_NESS_MASK GENMASK(23, 22) +#define B_AX_WMAC_RESP_DOPPLEB_AX_EN BIT(21) +#define B_AX_WMAC_RESP_DCM_EN BIT(20) +#define B_AX_WMAC_RRSB_AX_CCK_MASK GENMASK(19, 16) +#define B_AX_WMAC_RESP_RATE_EN_MASK GENMASK(15, 12) +#define B_AX_WMAC_RESP_RSC_MASK GENMASK(11, 10) +#define B_AX_WMAC_RESP_REF_RATE_SEL BIT(9) +#define B_AX_WMAC_RESP_REF_RATE_MASK GENMASK(8, 0) + +#define R_AX_MAC_LOOPBACK 0xCC20 +#define R_AX_MAC_LOOPBACK_C1 0xEC20 +#define B_AX_MACLBK_EN BIT(0) + +#define R_AX_WMAC_NAV_CTL 0xCC80 +#define R_AX_WMAC_NAV_CTL_C1 0xEC80 +#define B_AX_WMAC_NAV_UPPER_EN BIT(26) +#define B_AX_WMAC_0P125US_TIMER_MASK GENMASK(25, 18) +#define B_AX_WMAC_PLCP_UP_NAV_EN BIT(17) +#define B_AX_WMAC_TF_UP_NAV_EN BIT(16) +#define B_AX_WMAC_NAV_UPPER_MASK GENMASK(15, 8) +#define NAV_12MS 0xBC +#define NAV_25MS 0xC4 +#define B_AX_WMAC_RTS_RST_DUR_MASK GENMASK(7, 0) + +#define R_AX_RXTRIG_TEST_USER_2 0xCCB0 +#define R_AX_RXTRIG_TEST_USER_2_C1 0xECB0 +#define B_AX_RXTRIG_MACID_MASK GENMASK(31, 24) +#define B_AX_RXTRIG_RU26_DIS BIT(21) +#define B_AX_RXTRIG_FCSCHK_EN BIT(20) +#define B_AX_RXTRIG_PORT_SEL_MASK GENMASK(19, 17) +#define B_AX_RXTRIG_EN BIT(16) +#define B_AX_RXTRIG_USERINFO_2_MASK GENMASK(15, 0) + +#define R_AX_TRXPTCL_ERROR_INDICA_MASK 0xCCBC +#define R_AX_TRXPTCL_ERROR_INDICA_MASK_C1 0xECBC +#define B_AX_WMAC_MODE BIT(22) +#define B_AX_WMAC_TIMETOUT_THR_MASK GENMASK(21, 16) +#define B_AX_RMAC_FTM BIT(8) +#define B_AX_RMAC_CSI BIT(7) +#define B_AX_TMAC_MIMO_CTRL BIT(6) +#define B_AX_TMAC_RXTB BIT(5) +#define B_AX_TMAC_HWSIGB_GEN BIT(4) +#define B_AX_TMAC_TXPLCP BIT(3) +#define B_AX_TMAC_RESP BIT(2) +#define B_AX_TMAC_TXCTL BIT(1) +#define B_AX_TMAC_MACTX BIT(0) +#define B_AX_TMAC_IMR_CLR_V1 (B_AX_TMAC_MACTX | \ + B_AX_TMAC_TXCTL | \ + B_AX_TMAC_RESP | \ + B_AX_TMAC_TXPLCP | \ + B_AX_TMAC_HWSIGB_GEN | \ + B_AX_TMAC_RXTB | \ + B_AX_TMAC_MIMO_CTRL | \ + B_AX_RMAC_CSI | \ + B_AX_RMAC_FTM) +#define B_AX_TMAC_IMR_SET_V1 (B_AX_TMAC_MACTX | \ + B_AX_TMAC_TXCTL | \ + B_AX_TMAC_RESP | \ + B_AX_TMAC_TXPLCP | \ + B_AX_TMAC_HWSIGB_GEN | \ + B_AX_TMAC_RXTB | \ + B_AX_TMAC_MIMO_CTRL | \ + B_AX_RMAC_FTM) + +#define R_AX_TRXPTCL_ERROR_INDICA 0xCCC0 +#define R_AX_TRXPTCL_ERROR_INDICA_C1 0xECC0 +#define B_AX_FTM_ERROR_FLAG_CLR BIT(8) +#define B_AX_CSI_ERROR_FLAG_CLR BIT(7) +#define B_AX_MIMOCTRL_ERROR_FLAG_CLR BIT(6) +#define B_AX_RXTB_ERROR_FLAG_CLR BIT(5) +#define B_AX_HWSIGB_GEN_ERROR_FLAG_CLR BIT(4) +#define B_AX_TXPLCP_ERROR_FLAG_CLR BIT(3) +#define B_AX_RESP_ERROR_FLAG_CLR BIT(2) +#define B_AX_TXCTL_ERROR_FLAG_CLR BIT(1) +#define B_AX_MACTX_ERROR_FLAG_CLR BIT(0) + +#define R_AX_WMAC_TX_TF_INFO_0 0xCCD0 +#define R_AX_WMAC_TX_TF_INFO_0_C1 0xECD0 +#define B_AX_WMAC_TX_TF_INFO_SEL_MASK GENMASK(2, 0) + +#define R_AX_WMAC_TX_TF_INFO_1 0xCCD4 +#define R_AX_WMAC_TX_TF_INFO_1_C1 0xECD4 +#define B_AX_WMAC_TX_TF_INFO_P0_MASK GENMASK(31, 0) + +#define R_AX_WMAC_TX_TF_INFO_2 0xCCD8 +#define R_AX_WMAC_TX_TF_INFO_2_C1 0xECD8 +#define B_AX_WMAC_TX_TF_INFO_P1_MASK GENMASK(31, 0) + +#define R_AX_TMAC_ERR_IMR_ISR 0xCCEC +#define R_AX_TMAC_ERR_IMR_ISR_C1 0xECEC +#define B_AX_TMAC_TXPLCP_ERR_CLR BIT(19) +#define B_AX_TMAC_RESP_ERR_CLR BIT(18) +#define B_AX_TMAC_TXCTL_ERR_CLR BIT(17) +#define B_AX_TMAC_MACTX_ERR_CLR BIT(16) +#define B_AX_TMAC_TXPLCP_ERR BIT(14) +#define B_AX_TMAC_RESP_ERR BIT(13) +#define B_AX_TMAC_TXCTL_ERR BIT(12) +#define B_AX_TMAC_MACTX_ERR BIT(11) +#define B_AX_TMAC_TXPLCP_INT_EN BIT(10) +#define B_AX_TMAC_RESP_INT_EN BIT(9) +#define B_AX_TMAC_TXCTL_INT_EN BIT(8) +#define B_AX_TMAC_MACTX_INT_EN BIT(7) +#define B_AX_WMAC_INT_MODE BIT(6) +#define B_AX_TMAC_TIMETOUT_THR_MASK GENMASK(5, 0) +#define B_AX_TMAC_IMR_CLR (B_AX_TMAC_MACTX_INT_EN | \ + B_AX_TMAC_TXCTL_INT_EN | \ + B_AX_TMAC_RESP_INT_EN | \ + B_AX_TMAC_TXPLCP_INT_EN) +#define B_AX_TMAC_IMR_SET (B_AX_TMAC_MACTX_INT_EN | \ + B_AX_TMAC_TXCTL_INT_EN | \ + B_AX_TMAC_RESP_INT_EN | \ + B_AX_TMAC_TXPLCP_INT_EN) + +#define R_AX_DBGSEL_TRXPTCL 0xCCF4 +#define R_AX_DBGSEL_TRXPTCL_C1 0xECF4 +#define B_AX_DBGSEL_TRXPTCL_MASK GENMASK(7, 0) + +#define R_AX_PHYINFO_ERR_IMR_V1 0xCCF8 +#define R_AX_PHYINFO_ERR_IMR_V1_C1 0xECF8 +#define B_AX_PHYINTF_TIMEOUT_THR_MSAK_V1 GENMASK(21, 16) +#define B_AX_CSI_ON_TIMEOUT_EN BIT(5) +#define B_AX_STS_ON_TIMEOUT_EN BIT(4) +#define B_AX_DATA_ON_TIMEOUT_EN BIT(3) +#define B_AX_OFDM_CCA_TIMEOUT_EN BIT(2) +#define B_AX_CCK_CCA_TIMEOUT_EN BIT(1) +#define B_AX_PHY_TXON_TIMEOUT_EN BIT(0) +#define B_AX_PHYINFO_IMR_CLR_V1 (B_AX_PHY_TXON_TIMEOUT_EN | \ + B_AX_CCK_CCA_TIMEOUT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_EN | \ + B_AX_DATA_ON_TIMEOUT_EN | \ + B_AX_STS_ON_TIMEOUT_EN | \ + B_AX_CSI_ON_TIMEOUT_EN) +#define B_AX_PHYINFO_IMR_SET_V1 (B_AX_PHY_TXON_TIMEOUT_EN | \ + B_AX_CCK_CCA_TIMEOUT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_EN | \ + B_AX_DATA_ON_TIMEOUT_EN | \ + B_AX_STS_ON_TIMEOUT_EN | \ + B_AX_CSI_ON_TIMEOUT_EN) + +#define R_AX_PHYINFO_ERR_IMR 0xCCFC +#define R_AX_PHYINFO_ERR_IMR_C1 0xECFC +#define B_AX_CSI_ON_TIMEOUT BIT(29) +#define B_AX_STS_ON_TIMEOUT BIT(28) +#define B_AX_DATA_ON_TIMEOUT BIT(27) +#define B_AX_OFDM_CCA_TIMEOUT BIT(26) +#define B_AX_CCK_CCA_TIMEOUT BIT(25) +#define B_AXC_PHY_TXON_TIMEOUT BIT(24) +#define B_AX_CSI_ON_TIMEOUT_INT_EN BIT(21) +#define B_AX_STS_ON_TIMEOUT_INT_EN BIT(20) +#define B_AX_DATA_ON_TIMEOUT_INT_EN BIT(19) +#define B_AX_OFDM_CCA_TIMEOUT_INT_EN BIT(18) +#define B_AX_CCK_CCA_TIMEOUT_INT_EN BIT(17) +#define B_AX_PHY_TXON_TIMEOUT_INT_EN BIT(16) +#define B_AX_PHYINTF_TIMEOUT_THR_MSAK GENMASK(5, 0) +#define B_AX_PHYINFO_IMR_EN_ALL (B_AX_PHY_TXON_TIMEOUT_INT_EN | \ + B_AX_CCK_CCA_TIMEOUT_INT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_INT_EN | \ + B_AX_DATA_ON_TIMEOUT_INT_EN | \ + B_AX_STS_ON_TIMEOUT_INT_EN | \ + B_AX_CSI_ON_TIMEOUT_INT_EN | \ + B_AX_PHYINTF_TIMEOUT_THR_MSAK) +#define B_AX_PHYINFO_IMR_SET (B_AX_PHY_TXON_TIMEOUT_INT_EN | 0x7) + +#define R_AX_PHYINFO_ERR_ISR 0xCCFC +#define R_AX_PHYINFO_ERR_ISR_C1 0xECFC + +#define R_AX_BFMER_CTRL_0 0xCD78 +#define R_AX_BFMER_CTRL_0_C1 0xED78 +#define B_AX_BFMER_HE_CSI_OFFSET_MASK GENMASK(31, 24) +#define B_AX_BFMER_VHT_CSI_OFFSET_MASK GENMASK(23, 16) +#define B_AX_BFMER_HT_CSI_OFFSET_MASK GENMASK(15, 8) +#define B_AX_BFMER_NDP_BFEN BIT(2) +#define B_AX_BFMER_VHT_BFPRT_CHK BIT(0) + +#define R_AX_BFMEE_RESP_OPTION 0xCD80 +#define R_AX_BFMEE_RESP_OPTION_C1 0xED80 +#define B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK GENMASK(31, 24) +#define B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK GENMASK(23, 20) +#define BFRP_RX_STANDBY_TIMER_KEEP 0x0 +#define BFRP_RX_STANDBY_TIMER_RELEASE 0x1 +#define B_AX_MU_BFRPTSEG_SEL_MASK GENMASK(18, 17) +#define B_AX_BFMEE_NDP_RXSTDBY_SEL BIT(16) +#define BFRP_RX_STANDBY_TIMER 0x0 +#define NDP_RX_STANDBY_TIMER 0xFF +#define B_AX_BFMEE_HE_NDPA_EN BIT(2) +#define B_AX_BFMEE_VHT_NDPA_EN BIT(1) +#define B_AX_BFMEE_HT_NDPA_EN BIT(0) + +#define R_AX_TRXPTCL_RESP_CSI_CTRL_0 0xCD88 +#define R_AX_TRXPTCL_RESP_CSI_CTRL_0_C1 0xED88 +#define R_AX_TRXPTCL_RESP_CSI_CTRL_1 0xCD94 +#define R_AX_TRXPTCL_RESP_CSI_CTRL_1_C1 0xED94 +#define B_AX_BFMEE_CSISEQ_SEL BIT(29) +#define B_AX_BFMEE_BFPARAM_SEL BIT(28) +#define B_AX_BFMEE_OFDM_LEN_TH_MASK GENMASK(27, 24) +#define B_AX_BFMEE_BF_PORT_SEL BIT(23) +#define B_AX_BFMEE_USE_NSTS BIT(22) +#define B_AX_BFMEE_CSI_RATE_FB_EN BIT(21) +#define B_AX_BFMEE_CSI_GID_SEL BIT(20) +#define B_AX_BFMEE_CSI_RSC_MASK GENMASK(19, 18) +#define B_AX_BFMEE_CSI_FORCE_RETE_EN BIT(17) +#define B_AX_BFMEE_CSI_USE_NDPARATE BIT(16) +#define B_AX_BFMEE_CSI_WITHHTC_EN BIT(15) +#define B_AX_BFMEE_CSIINFO0_BF_EN BIT(14) +#define B_AX_BFMEE_CSIINFO0_STBC_EN BIT(13) +#define B_AX_BFMEE_CSIINFO0_LDPC_EN BIT(12) +#define B_AX_BFMEE_CSIINFO0_CS_MASK GENMASK(11, 10) +#define B_AX_BFMEE_CSIINFO0_CB_MASK GENMASK(9, 8) +#define B_AX_BFMEE_CSIINFO0_NG_MASK GENMASK(7, 6) +#define B_AX_BFMEE_CSIINFO0_NR_MASK GENMASK(5, 3) +#define B_AX_BFMEE_CSIINFO0_NC_MASK GENMASK(2, 0) + +#define R_AX_TRXPTCL_RESP_CSI_RRSC 0xCD8C +#define R_AX_TRXPTCL_RESP_CSI_RRSC_C1 0xED8C +#define CSI_RRSC_BMAP 0x29292911 + +#define R_AX_TRXPTCL_RESP_CSI_RATE 0xCD90 +#define R_AX_TRXPTCL_RESP_CSI_RATE_C1 0xED90 +#define B_AX_BFMEE_HE_CSI_RATE_MASK GENMASK(22, 16) +#define B_AX_BFMEE_VHT_CSI_RATE_MASK GENMASK(14, 8) +#define B_AX_BFMEE_HT_CSI_RATE_MASK GENMASK(6, 0) +#define CSI_INIT_RATE_HE 0x3 +#define CSI_INIT_RATE_VHT 0x3 +#define CSI_INIT_RATE_HT 0x3 + +#define R_AX_RCR 0xCE00 +#define R_AX_RCR_C1 0xEE00 +#define B_AX_STOP_RX_IN BIT(11) +#define B_AX_DRV_INFO_SIZE_MASK GENMASK(10, 8) +#define B_AX_CH_EN_MASK GENMASK(3, 0) + +#define R_AX_DLK_PROTECT_CTL 0xCE02 +#define R_AX_DLK_PROTECT_CTL_C1 0xEE02 +#define B_AX_RX_DLK_CCA_TIME_MASK GENMASK(15, 8) +#define B_AX_RX_DLK_DATA_TIME_MASK GENMASK(7, 4) +#define B_AX_RX_DLK_RST_EN BIT(1) +#define B_AX_RX_DLK_INT_EN BIT(0) + +#define R_AX_PLCP_HDR_FLTR 0xCE04 +#define R_AX_PLCP_HDR_FLTR_C1 0xEE04 +#define B_AX_DIS_CHK_MIN_LEN BIT(8) +#define B_AX_HE_SIGB_CRC_CHK BIT(6) +#define B_AX_VHT_MU_SIGB_CRC_CHK BIT(5) +#define B_AX_VHT_SU_SIGB_CRC_CHK BIT(4) +#define B_AX_SIGA_CRC_CHK BIT(3) +#define B_AX_LSIG_PARITY_CHK_EN BIT(2) +#define B_AX_CCK_SIG_CHK BIT(1) +#define B_AX_CCK_CRC_CHK BIT(0) + +#define R_AX_RX_FLTR_OPT 0xCE20 +#define R_AX_RX_FLTR_OPT_C1 0xEE20 +#define B_AX_UID_FILTER_MASK GENMASK(31, 24) +#define B_AX_UNSPT_FILTER_SH 22 +#define B_AX_UNSPT_FILTER_MASK GENMASK(23, 22) +#define B_AX_RX_MPDU_MAX_LEN_MASK GENMASK(21, 16) +#define B_AX_RX_MPDU_MAX_LEN_SIZE 0x3f +#define B_AX_A_FTM_REQ BIT(14) +#define B_AX_A_ERR_PKT BIT(13) +#define B_AX_A_UNSUP_PKT BIT(12) +#define B_AX_A_CRC32_ERR BIT(11) +#define B_AX_A_PWR_MGNT BIT(10) +#define B_AX_A_BCN_CHK_RULE_MASK GENMASK(9, 8) +#define B_AX_A_BCN_CHK_EN BIT(7) +#define B_AX_A_MC_LIST_CAM_MATCH BIT(6) +#define B_AX_A_BC_CAM_MATCH BIT(5) +#define B_AX_A_UC_CAM_MATCH BIT(4) +#define B_AX_A_MC BIT(3) +#define B_AX_A_BC BIT(2) +#define B_AX_A_A1_MATCH BIT(1) +#define B_AX_SNIFFER_MODE BIT(0) +#define DEFAULT_AX_RX_FLTR (B_AX_A_A1_MATCH | B_AX_A_BC | B_AX_A_MC | \ + B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH | \ + B_AX_A_PWR_MGNT | B_AX_A_FTM_REQ | \ + FIELD_PREP_CONST(B_AX_UID_FILTER_MASK, 3) | \ + B_AX_A_BCN_CHK_EN) +#define B_AX_RX_FLTR_CFG_MASK ((u32)~B_AX_RX_MPDU_MAX_LEN_MASK) + +#define R_AX_CTRL_FLTR 0xCE24 +#define R_AX_CTRL_FLTR_C1 0xEE24 +#define R_AX_MGNT_FLTR 0xCE28 +#define R_AX_MGNT_FLTR_C1 0xEE28 +#define R_AX_DATA_FLTR 0xCE2C +#define R_AX_DATA_FLTR_C1 0xEE2C +#define RX_FLTR_FRAME_DROP 0x00000000 +#define RX_FLTR_FRAME_TO_HOST 0x55555555 +#define RX_FLTR_FRAME_TO_WLCPU 0xAAAAAAAA + +#define R_AX_ADDR_CAM_CTRL 0xCE34 +#define R_AX_ADDR_CAM_CTRL_C1 0xEE34 +#define B_AX_ADDR_CAM_RANGE_MASK GENMASK(23, 16) +#define B_AX_ADDR_CAM_CMPLIMT_MASK GENMASK(15, 12) +#define B_AX_ADDR_CAM_CLR BIT(8) +#define B_AX_ADDR_CAM_A2_B0_CHK BIT(2) +#define B_AX_ADDR_CAM_SRCH_PERPKT BIT(1) +#define B_AX_ADDR_CAM_EN BIT(0) + +#define R_AX_RESPBA_CAM_CTRL 0xCE3C +#define R_AX_RESPBA_CAM_CTRL_C1 0xEE3C +#define B_AX_SSN_SEL BIT(2) +#define B_AX_BACAM_RST_MASK GENMASK(1, 0) +#define S_AX_BACAM_RST_ALL 2 + +#define R_AX_PPDU_STAT 0xCE40 +#define R_AX_PPDU_STAT_C1 0xEE40 +#define B_AX_PPDU_STAT_RPT_TRIG BIT(8) +#define B_AX_PPDU_STAT_RPT_CRC32 BIT(5) +#define B_AX_PPDU_STAT_RPT_A1M BIT(4) +#define B_AX_APP_PLCP_HDR_RPT BIT(3) +#define B_AX_APP_RX_CNT_RPT BIT(2) +#define B_AX_APP_MAC_INFO_RPT BIT(1) +#define B_AX_PPDU_STAT_RPT_EN BIT(0) + +#define R_AX_RX_SR_CTRL 0xCE4A +#define R_AX_RX_SR_CTRL_C1 0xEE4A +#define B_AX_SR_EN BIT(0) + +#define R_AX_BSSID_SRC_CTRL 0xCE4B +#define R_AX_BSSID_SRC_CTRL_C1 0xEE4B +#define B_AX_BSSID_MATCH BIT(3) +#define B_AX_PARTIAL_AID_MATCH BIT(2) +#define B_AX_BSSCOLOR_MATCH BIT(1) +#define B_AX_PLCP_SRC_EN BIT(0) + +#define R_AX_CSIRPT_OPTION 0xCE64 +#define R_AX_CSIRPT_OPTION_C1 0xEE64 +#define B_AX_CSIPRT_HESU_AID_EN BIT(25) +#define B_AX_CSIPRT_VHTSU_AID_EN BIT(24) + +#define R_AX_BCN_PSR_RPT_P0 0xCE84 +#define R_AX_BCN_PSR_RPT_P0_C1 0xEE84 +#define B_AX_BCAID_P0_MASK GENMASK(10, 0) + +#define R_AX_RX_STATE_MONITOR 0xCEF0 +#define R_AX_RX_STATE_MONITOR_C1 0xEEF0 +#define B_AX_RX_STATE_MONITOR_MASK GENMASK(31, 0) +#define B_AX_STATE_CUR_MASK GENMASK(31, 16) +#define B_AX_STATE_NXT_MASK GENMASK(13, 8) +#define B_AX_STATE_UPD BIT(7) +#define B_AX_STATE_SEL_MASK GENMASK(4, 0) + +#define R_AX_RMAC_ERR_ISR 0xCEF4 +#define R_AX_RMAC_ERR_ISR_C1 0xEEF4 +#define B_AX_RXERR_INTPS_EN BIT(31) +#define B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN BIT(19) +#define B_AX_RMAC_RX_TIMEOUT_INT_EN BIT(18) +#define B_AX_RMAC_CSI_TIMEOUT_INT_EN BIT(17) +#define B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN BIT(16) +#define B_AX_RMAC_CCA_TIMEOUT_INT_EN BIT(15) +#define B_AX_RMAC_DMA_TIMEOUT_INT_EN BIT(14) +#define B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN BIT(13) +#define B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN BIT(12) +#define B_AX_RMAC_RX_CSI_TIMEOUT_FLAG BIT(7) +#define B_AX_RMAC_RX_TIMEOUT_FLAG BIT(6) +#define B_AX_BMAC_CSI_TIMEOUT_FLAG BIT(5) +#define B_AX_BMAC_DATA_ON_TIMEOUT_FLAG BIT(4) +#define B_AX_BMAC_CCA_TIMEOUT_FLAG BIT(3) +#define B_AX_BMAC_DMA_TIMEOUT_FLAG BIT(2) +#define B_AX_BMAC_DATA_ON_TO_IDLE_TIMEOUT_FLAG BIT(1) +#define B_AX_BMAC_CCA_TO_IDLE_TIMEOUT_FLAG BIT(0) +#define B_AX_RMAC_IMR_CLR (B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN | \ + B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN | \ + B_AX_RMAC_DMA_TIMEOUT_INT_EN | \ + B_AX_RMAC_CCA_TIMEOUT_INT_EN | \ + B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN | \ + B_AX_RMAC_CSI_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN) +#define B_AX_RMAC_IMR_SET (B_AX_RMAC_DMA_TIMEOUT_INT_EN | \ + B_AX_RMAC_CSI_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN) + +#define R_AX_RX_ERR_IMR 0xCEF8 +#define R_AX_RX_ERR_IMR_C1 0xEEF8 +#define B_AX_RX_ERR_TRIG_ACT_TO_MSK BIT(9) +#define B_AX_RX_ERR_STS_ACT_TO_MSK BIT(8) +#define B_AX_RX_ERR_CSI_ACT_TO_MSK BIT(7) +#define B_AX_RX_ERR_ACT_TO_MSK BIT(6) +#define B_AX_CSI_DATAON_ASSERT_TO_MSK BIT(5) +#define B_AX_DATAON_ASSERT_TO_MSK BIT(4) +#define B_AX_CCA_ASSERT_TO_MSK BIT(3) +#define B_AX_RX_ERR_DMA_TO_MSK BIT(2) +#define B_AX_RX_ERR_DATA_TO_MSK BIT(1) +#define B_AX_RX_ERR_CCA_TO_MSK BIT(0) +#define B_AX_RMAC_IMR_CLR_V1 (B_AX_RX_ERR_CCA_TO_MSK | \ + B_AX_RX_ERR_DATA_TO_MSK | \ + B_AX_RX_ERR_DMA_TO_MSK | \ + B_AX_CCA_ASSERT_TO_MSK | \ + B_AX_DATAON_ASSERT_TO_MSK | \ + B_AX_CSI_DATAON_ASSERT_TO_MSK | \ + B_AX_RX_ERR_ACT_TO_MSK | \ + B_AX_RX_ERR_CSI_ACT_TO_MSK | \ + B_AX_RX_ERR_STS_ACT_TO_MSK | \ + B_AX_RX_ERR_TRIG_ACT_TO_MSK) +#define B_AX_RMAC_IMR_SET_V1 (B_AX_RX_ERR_CCA_TO_MSK | \ + B_AX_RX_ERR_DATA_TO_MSK | \ + B_AX_RX_ERR_DMA_TO_MSK | \ + B_AX_CCA_ASSERT_TO_MSK | \ + B_AX_DATAON_ASSERT_TO_MSK | \ + B_AX_CSI_DATAON_ASSERT_TO_MSK | \ + B_AX_RX_ERR_ACT_TO_MSK | \ + B_AX_RX_ERR_CSI_ACT_TO_MSK | \ + B_AX_RX_ERR_STS_ACT_TO_MSK | \ + B_AX_RX_ERR_TRIG_ACT_TO_MSK) + +#define R_AX_RMAC_PLCP_MON 0xCEF8 +#define R_AX_RMAC_PLCP_MON_C1 0xEEF8 +#define B_AX_RMAC_PLCP_MON_MASK GENMASK(31, 0) +#define B_AX_PCLP_MON_SEL_MASK GENMASK(31, 28) +#define B_AX_PCLP_MON_CONT_MASK GENMASK(27, 0) + +#define R_AX_RX_DEBUG_SELECT 0xCEFC +#define R_AX_RX_DEBUG_SELECT_C1 0xEEFC +#define B_AX_DEBUG_SEL_MASK GENMASK(7, 0) + +#define R_AX_PWR_RATE_CTRL 0xD200 +#define R_AX_PWR_RATE_CTRL_C1 0xF200 +#define B_AX_PWR_REF GENMASK(27, 10) +#define B_AX_FORCE_PWR_BY_RATE_EN BIT(9) +#define B_AX_FORCE_PWR_BY_RATE_VALUE_MASK GENMASK(8, 0) + +#define R_AX_PWR_RATE_OFST_CTRL 0xD204 +#define R_AX_PWR_COEXT_CTRL 0xD220 +#define B_AX_TXAGC_BT_EN BIT(1) +#define B_AX_TXAGC_BT_MASK GENMASK(11, 3) + +#define R_AX_PWR_SWING_OTHER_CTRL0 0xD230 +#define R_AX_PWR_SWING_OTHER_CTRL0_C1 0xF230 +#define B_AX_CFIR_BY_RATE_OFF_MASK GENMASK(17, 0) + +#define R_AX_PWR_UL_CTRL0 0xD240 +#define R_AX_PWR_UL_CTRL2 0xD248 +#define B_AX_PWR_UL_CFO_MASK GENMASK(2, 0) +#define B_AX_PWR_UL_CTRL2_MASK 0x07700007 + +#define R_AX_PWR_NORM_FORCE1 0xD260 +#define R_AX_PWR_NORM_FORCE1_C1 0xF260 +#define B_AX_TXAGC_BF_PWR_BOOST_FORCE_VAL_EN BIT(29) +#define B_AX_TXAGC_BF_PWR_BOOST_FORCE_VAL_MASK GENMASK(28, 24) +#define B_AX_FORCE_HE_ER_SU_EN_EN BIT(23) +#define B_AX_FORCE_HE_ER_SU_EN_VALUE BIT(22) +#define B_AX_FORCE_MACID_CCA_TH_EN_EN BIT(21) +#define B_AX_FORCE_MACID_CCA_TH_EN_VALUE BIT(20) +#define B_AX_FORCE_BT_GRANT_EN BIT(19) +#define B_AX_FORCE_BT_GRANT_VALUE BIT(18) +#define B_AX_FORCE_RX_LTE_EN BIT(17) +#define B_AX_FORCE_RX_LTE_VALUE BIT(16) +#define B_AX_FORCE_TXBF_EN_EN BIT(15) +#define B_AX_FORCE_TXBF_EN_VALUE BIT(14) +#define B_AX_FORCE_TXSC_EN BIT(13) +#define B_AX_FORCE_TXSC_VALUE_MASK GENMASK(12, 9) +#define B_AX_FORCE_NTX_EN BIT(6) +#define B_AX_FORCE_NTX_VALUE BIT(5) +#define B_AX_FORCE_PWR_MODE_EN BIT(3) +#define B_AX_FORCE_PWR_MODE_VALUE_MASK GENMASK(2, 0) + +#define R_AX_PWR_UL_TB_CTRL 0xD288 +#define B_AX_PWR_UL_TB_CTRL_EN BIT(31) +#define R_AX_PWR_UL_TB_1T 0xD28C +#define B_AX_PWR_UL_TB_1T_MASK GENMASK(4, 0) +#define B_AX_PWR_UL_TB_1T_V1_MASK GENMASK(7, 0) +#define B_AX_PWR_UL_TB_1T_NORM_BW160 GENMASK(31, 24) +#define R_AX_PWR_UL_TB_2T 0xD290 +#define B_AX_PWR_UL_TB_2T_MASK GENMASK(4, 0) +#define B_AX_PWR_UL_TB_2T_V1_MASK GENMASK(7, 0) +#define B_AX_PWR_UL_TB_2T_NORM_BW160 GENMASK(31, 24) +#define R_AX_PWR_BY_RATE_TABLE0 0xD2C0 +#define R_AX_PWR_BY_RATE_TABLE6 0xD2D8 +#define R_AX_PWR_BY_RATE_TABLE10 0xD2E8 +#define R_AX_PWR_BY_RATE R_AX_PWR_BY_RATE_TABLE0 +#define R_AX_PWR_BY_RATE_1SS_MAX R_AX_PWR_BY_RATE_TABLE6 +#define R_AX_PWR_BY_RATE_MAX R_AX_PWR_BY_RATE_TABLE10 +#define R_AX_PWR_LMT_TABLE0 0xD2EC +#define R_AX_PWR_LMT_TABLE9 0xD310 +#define R_AX_PWR_LMT_TABLE19 0xD338 +#define R_AX_PWR_LMT R_AX_PWR_LMT_TABLE0 +#define R_AX_PWR_LMT_1SS_MAX R_AX_PWR_LMT_TABLE9 +#define R_AX_PWR_LMT_MAX R_AX_PWR_LMT_TABLE19 +#define R_AX_PWR_RU_LMT_TABLE0 0xD33C +#define R_AX_PWR_RU_LMT_TABLE5 0xD350 +#define R_AX_PWR_RU_LMT_TABLE11 0xD368 +#define R_AX_PWR_RU_LMT R_AX_PWR_RU_LMT_TABLE0 +#define R_AX_PWR_RU_LMT_1SS_MAX R_AX_PWR_RU_LMT_TABLE5 +#define R_AX_PWR_RU_LMT_MAX R_AX_PWR_RU_LMT_TABLE11 +#define R_AX_PWR_MACID_LMT_TABLE0 0xD36C +#define R_AX_PWR_MACID_LMT_TABLE127 0xD568 + +#define R_AX_PATH_COM0 0xD800 +#define AX_PATH_COM0_DFVAL 0x00000000 +#define AX_PATH_COM0_PATHA 0x08889880 +#define AX_PATH_COM0_PATHB 0x11111900 +#define AX_PATH_COM0_PATHAB 0x19999980 +#define R_AX_PATH_COM1 0xD804 +#define B_AX_PATH_COM1_NORM_1STS GENMASK(31, 28) +#define AX_PATH_COM1_DFVAL 0x00000000 +#define AX_PATH_COM1_PATHA 0x13111111 +#define AX_PATH_COM1_PATHB 0x23222222 +#define AX_PATH_COM1_PATHAB 0x33333333 +#define R_AX_PATH_COM2 0xD808 +#define B_AX_PATH_COM2_RESP_1STS_PATH GENMASK(7, 4) +#define AX_PATH_COM2_DFVAL 0x00000000 +#define AX_PATH_COM2_PATHA 0x01209313 +#define AX_PATH_COM2_PATHB 0x01209323 +#define AX_PATH_COM2_PATHAB 0x01209333 +#define R_AX_PATH_COM3 0xD80C +#define AX_PATH_COM3_DFVAL 0x49249249 +#define R_AX_PATH_COM4 0xD810 +#define AX_PATH_COM4_DFVAL 0x1C9C9C49 +#define R_AX_PATH_COM5 0xD814 +#define AX_PATH_COM5_DFVAL 0x39393939 +#define R_AX_PATH_COM6 0xD818 +#define AX_PATH_COM6_DFVAL 0x39393939 +#define R_AX_PATH_COM7 0xD81C +#define AX_PATH_COM7_DFVAL 0x39393939 +#define AX_PATH_COM7_PATHA 0x39393939 +#define AX_PATH_COM7_PATHB 0x39383939 +#define AX_PATH_COM7_PATHAB 0x39393939 +#define R_AX_PATH_COM8 0xD820 +#define AX_PATH_COM8_DFVAL 0x00000000 +#define AX_PATH_COM8_PATHA 0x00003939 +#define AX_PATH_COM8_PATHB 0x00003938 +#define AX_PATH_COM8_PATHAB 0x00003939 +#define R_AX_PATH_COM9 0xD824 +#define AX_PATH_COM9_DFVAL 0x000007C0 +#define R_AX_PATH_COM10 0xD828 +#define AX_PATH_COM10_DFVAL 0xE0000000 +#define R_AX_PATH_COM11 0xD82C +#define AX_PATH_COM11_DFVAL 0x00000000 +#define R_P80_AT_HIGH_FREQ_BB_WRP 0xD848 +#define B_P80_AT_HIGH_FREQ_BB_WRP BIT(28) +#define R_AX_TSSI_CTRL_HEAD 0xD908 +#define R_AX_BANDEDGE_CFG 0xD94C +#define B_AX_BANDEDGE_CFG_IDX_MASK GENMASK(31, 30) +#define R_AX_TSSI_CTRL_TAIL 0xD95C + +#define R_AX_TXPWR_IMR 0xD9E0 +#define R_AX_TXPWR_IMR_C1 0xF9E0 +#define R_AX_TXPWR_ISR 0xD9E4 +#define R_AX_TXPWR_ISR_C1 0xF9E4 + +#define R_AX_BTC_CFG 0xDA00 +#define B_AX_BTC_EN BIT(31) +#define B_AX_EN_EXT_BT_PINMUX BIT(29) +#define B_AX_BTC_RST BIT(28) +#define B_AX_BTC_DBG_SRC_SEL BIT(27) +#define B_AX_BTC_MODE_MASK GENMASK(25, 24) +#define B_AX_INV_WL_ACT2 BIT(17) +#define B_AX_BTG_LNA1_GAIN_SEL BIT(16) +#define B_AX_COEX_DLY_CLK_MASK GENMASK(15, 8) +#define B_AX_IGN_GNT_BT2_RX BIT(7) +#define B_AX_IGN_GNT_BT2_TX BIT(6) +#define B_AX_IGN_GNT_BT2 BIT(5) +#define B_AX_BTC_DBG_SEL_MASK GENMASK(4, 3) +#define B_AX_DIS_BTC_CLK_G BIT(2) +#define B_AX_GNT_WL_RX_CTRL BIT(1) +#define B_AX_WL_SRC BIT(0) + +#define R_AX_RTK_MODE_CFG_V1 0xDA04 +#define R_AX_RTK_MODE_CFG_V1_C1 0xFA04 +#define B_AX_BT_BLE_EN_V1 BIT(24) +#define B_AX_BT_ULTRA_EN BIT(16) +#define B_AX_BT_L_RX_ULTRA_MASK GENMASK(15, 14) +#define B_AX_BT_L_TX_ULTRA_MASK GENMASK(13, 12) +#define B_AX_BT_H_RX_ULTRA_MASK GENMASK(11, 10) +#define B_AX_BT_H_TX_ULTRA_MASK GENMASK(9, 8) +#define B_AX_SAMPLE_CLK_MASK GENMASK(7, 0) + +#define R_AX_WL_PRI_MSK 0xDA10 +#define B_AX_PTA_WL_PRI_MASK_BCNQ BIT(8) + +#define R_AX_BT_CNT_CFG 0xDA10 +#define R_AX_BT_CNT_CFG_C1 0xFA10 +#define B_AX_BT_CNT_RST_V1 BIT(1) +#define B_AX_BT_CNT_EN BIT(0) + +#define R_BTC_BT_CNT_HIGH 0xDA14 +#define R_BTC_BT_CNT_LOW 0xDA18 + +#define R_AX_BTC_FUNC_EN 0xDA20 +#define R_AX_BTC_FUNC_EN_C1 0xFA20 +#define B_AX_PTA_WL_TX_EN BIT(1) +#define B_AX_PTA_EDCCA_EN BIT(0) + +#define R_BTC_COEX_WL_REQ 0xDA24 +#define R_BTC_COEX_WL_REQ_BE 0xE324 +#define B_BTC_TX_NULL_HI BIT(23) +#define B_BTC_TX_BCN_HI BIT(22) +#define B_BTC_TX_TRI_HI BIT(17) +#define B_BTC_RSP_ACK_HI BIT(10) +#define B_BTC_PRI_MASK_TX_TIME GENMASK(4, 3) +#define B_BTC_PRI_MASK_RX_TIME_V1 GENMASK(2, 1) + +#define R_BTC_BREAK_TABLE 0xDA2C +#define BTC_BREAK_PARAM 0xf0ffffff + +#define R_BTC_BT_COEX_MSK_TABLE 0xDA30 +#define B_BTC_PRI_MASK_RXCCK_V1 BIT(28) +#define B_BTC_PRI_MASK_TX_RESP_V1 BIT(3) + +#define R_AX_BT_COEX_CFG_2 0xDA34 +#define R_AX_BT_COEX_CFG_2_C1 0xFA34 +#define B_AX_GNT_BT_BYPASS_PRIORITY BIT(12) +#define B_AX_GNT_BT_POLARITY BIT(8) +#define B_AX_TIMER_MASK GENMASK(7, 0) +#define MAC_AX_CSR_RATE 80 + +#define R_AX_CSR_MODE 0xDA40 +#define R_AX_CSR_MODE_C1 0xFA40 +#define B_AX_BT_CNT_RST BIT(16) +#define B_AX_BT_STAT_DELAY_MASK GENMASK(15, 12) +#define MAC_AX_CSR_DELAY 0 +#define B_AX_BT_TRX_INIT_DETECT_MASK GENMASK(11, 8) +#define MAC_AX_CSR_TRX_TO 4 +#define B_AX_BT_PRI_DETECT_TO_MASK GENMASK(7, 4) +#define MAC_AX_CSR_PRI_TO 5 +#define B_AX_WL_ACT_MSK BIT(3) +#define B_AX_STATIS_BT_EN BIT(2) +#define B_AX_WL_ACT_MASK_ENABLE BIT(1) +#define B_AX_ENHANCED_BT BIT(0) + +#define R_AX_BT_BREAK_TABLE 0xDA44 + +#define R_AX_BT_STAST_HIGH 0xDA44 +#define B_AX_STATIS_BT_HI_RX_MASK GENMASK(31, 16) +#define B_AX_STATIS_BT_HI_TX_MASK GENMASK(15, 0) +#define R_AX_BT_STAST_LOW 0xDA48 +#define B_AX_STATIS_BT_LO_TX_1_MASK GENMASK(15, 0) +#define B_AX_STATIS_BT_LO_RX_1_MASK GENMASK(31, 16) + +#define R_AX_GNT_SW_CTRL 0xDA48 +#define R_AX_GNT_SW_CTRL_C1 0xFA48 +#define B_AX_WL_ACT2_VAL BIT(21) +#define B_AX_WL_ACT2_SWCTRL BIT(20) +#define B_AX_WL_ACT_VAL BIT(19) +#define B_AX_WL_ACT_SWCTRL BIT(18) +#define B_AX_GNT_BT_RX_VAL BIT(17) +#define B_AX_GNT_BT_RX_SWCTRL BIT(16) +#define B_AX_GNT_BT_TX_VAL BIT(15) +#define B_AX_GNT_BT_TX_SWCTRL BIT(14) +#define B_AX_GNT_WL_RX_VAL BIT(13) +#define B_AX_GNT_WL_RX_SWCTRL BIT(12) +#define B_AX_GNT_WL_TX_VAL BIT(11) +#define B_AX_GNT_WL_TX_SWCTRL BIT(10) +#define B_AX_GNT_BT_RFC_S1_VAL BIT(9) +#define B_AX_GNT_BT_RFC_S1_SWCTRL BIT(8) +#define B_AX_GNT_WL_RFC_S1_VAL BIT(7) +#define B_AX_GNT_WL_RFC_S1_SWCTRL BIT(6) +#define B_AX_GNT_BT_RFC_S0_VAL BIT(5) +#define B_AX_GNT_BT_RFC_S0_SWCTRL BIT(4) +#define B_AX_GNT_WL_RFC_S0_VAL BIT(3) +#define B_AX_GNT_WL_RFC_S0_SWCTRL BIT(2) +#define B_AX_GNT_WL_BB_VAL BIT(1) +#define B_AX_GNT_WL_BB_SWCTRL BIT(0) + +#define R_AX_GNT_VAL 0x0054 +#define B_AX_GNT_BT_RFC_S1_STA BIT(5) +#define B_AX_GNT_WL_RFC_S1_STA BIT(4) +#define B_AX_GNT_BT_RFC_S0_STA BIT(3) +#define B_AX_GNT_WL_RFC_S0_STA BIT(2) + +#define R_AX_GNT_VAL_V1 0xDA4C +#define B_AX_GNT_BT_RFC_S1 BIT(4) +#define B_AX_GNT_BT_RFC_S0 BIT(3) +#define B_AX_GNT_WL_RFC_S1 BIT(2) +#define B_AX_GNT_WL_RFC_S0 BIT(1) + +#define R_AX_TDMA_MODE 0xDA4C +#define R_AX_TDMA_MODE_C1 0xFA4C +#define B_AX_R_BT_CMD_RPT_MASK GENMASK(31, 16) +#define B_AX_R_RPT_FROM_BT_MASK GENMASK(15, 8) +#define B_AX_BT_HID_ISR_SET_MASK GENMASK(7, 6) +#define B_AX_TDMA_BT_START_NOTIFY BIT(5) +#define B_AX_ENABLE_TDMA_FW_MODE BIT(4) +#define B_AX_ENABLE_PTA_TDMA_MODE BIT(3) +#define B_AX_ENABLE_COEXIST_TAB_IN_TDMA BIT(2) +#define B_AX_GPIO2_GPIO3_EXANGE_OR_NO_BT_CCA BIT(1) +#define B_AX_RTK_BT_ENABLE BIT(0) + +#define R_AX_BT_COEX_CFG_5 0xDA6C +#define R_AX_BT_COEX_CFG_5_C1 0xFA6C +#define B_AX_BT_TIME_MASK GENMASK(31, 6) +#define B_AX_BT_RPT_SAMPLE_RATE_MASK GENMASK(5, 0) +#define MAC_AX_RTK_RATE 5 + +#define R_AX_LTE_CTRL 0xDAF0 +#define R_AX_LTE_WDATA 0xDAF4 +#define R_AX_LTE_RDATA 0xDAF8 + +#define R_AX_MACID_ANT_TABLE 0xDC00 +#define R_AX_MACID_ANT_TABLE_LAST 0xDDFC + +#define CMAC1_START_ADDR_AX 0xE000 +#define CMAC1_END_ADDR_AX 0xFFFF +#define R_AX_CMAC_REG_END 0xFFFF + +#define R_AX_LTE_SW_CFG_1 0x0038 +#define R_AX_LTE_SW_CFG_1_C1 0x2038 +#define B_AX_GNT_BT_RFC_S1_SW_VAL BIT(31) +#define B_AX_GNT_BT_RFC_S1_SW_CTRL BIT(30) +#define B_AX_GNT_WL_RFC_S1_SW_VAL BIT(29) +#define B_AX_GNT_WL_RFC_S1_SW_CTRL BIT(28) +#define B_AX_GNT_BT_BB_S1_SW_VAL BIT(27) +#define B_AX_GNT_BT_BB_S1_SW_CTRL BIT(26) +#define B_AX_GNT_WL_BB_S1_SW_VAL BIT(25) +#define B_AX_GNT_WL_BB_S1_SW_CTRL BIT(24) +#define B_AX_BT_SW_CTRL_WL_PRIORITY BIT(19) +#define B_AX_WL_SW_CTRL_WL_PRIORITY BIT(18) +#define B_AX_LTE_PATTERN_2_EN BIT(17) +#define B_AX_LTE_PATTERN_1_EN BIT(16) +#define B_AX_GNT_BT_RFC_S0_SW_VAL BIT(15) +#define B_AX_GNT_BT_RFC_S0_SW_CTRL BIT(14) +#define B_AX_GNT_WL_RFC_S0_SW_VAL BIT(13) +#define B_AX_GNT_WL_RFC_S0_SW_CTRL BIT(12) +#define B_AX_GNT_BT_BB_S0_SW_VAL BIT(11) +#define B_AX_GNT_BT_BB_S0_SW_CTRL BIT(10) +#define B_AX_GNT_WL_BB_S0_SW_VAL BIT(9) +#define B_AX_GNT_WL_BB_S0_SW_CTRL BIT(8) +#define B_AX_LTECOEX_FUN_EN BIT(7) +#define B_AX_LTECOEX_3WIRE_CTRL_MUX BIT(6) +#define B_AX_LTECOEX_OP_MODE_SEL_MASK GENMASK(5, 4) +#define B_AX_LTECOEX_UART_MUX BIT(3) +#define B_AX_LTECOEX_UART_MODE_SEL_MASK GENMASK(2, 0) + +#define R_AX_LTE_SW_CFG_2 0x003C +#define R_AX_LTE_SW_CFG_2_C1 0x203C +#define B_AX_WL_RX_CTRL BIT(8) +#define B_AX_GNT_WL_RX_SW_VAL BIT(7) +#define B_AX_GNT_WL_RX_SW_CTRL BIT(6) +#define B_AX_GNT_WL_TX_SW_VAL BIT(5) +#define B_AX_GNT_WL_TX_SW_CTRL BIT(4) +#define B_AX_GNT_BT_RX_SW_VAL BIT(3) +#define B_AX_GNT_BT_RX_SW_CTRL BIT(2) +#define B_AX_GNT_BT_TX_SW_VAL BIT(1) +#define B_AX_GNT_BT_TX_SW_CTRL BIT(0) + +#define R_BE_SYS_ISO_CTRL 0x0000 +#define B_BE_PWC_EV2EF_B BIT(15) +#define B_BE_PWC_EV2EF_S BIT(14) +#define B_BE_PA33V_EN BIT(13) +#define B_BE_PA12V_EN BIT(12) +#define B_BE_PAOOBS33V_EN BIT(11) +#define B_BE_PAOOBS12V_EN BIT(10) +#define B_BE_ISO_RFDIO BIT(9) +#define B_BE_ISO_EB2CORE BIT(8) +#define B_BE_ISO_DIOE BIT(7) +#define B_BE_ISO_WLPON2PP BIT(6) +#define B_BE_ISO_IP2MAC_WA02PP BIT(5) +#define B_BE_ISO_PD2CORE BIT(4) +#define B_BE_ISO_PA2PCIE BIT(3) +#define B_BE_ISO_PAOOBS2PCIE BIT(1) +#define B_BE_ISO_WD2PP BIT(0) + +#define R_BE_SYS_PW_CTRL 0x0004 +#define B_BE_SOP_ASWRM BIT(31) +#define B_BE_SOP_EASWR BIT(30) +#define B_BE_SOP_PWMM_DSWR BIT(29) +#define B_BE_SOP_EDSWR BIT(28) +#define B_BE_SOP_ACKF BIT(27) +#define B_BE_SOP_ERCK BIT(26) +#define B_BE_SOP_ANA_CLK_DIVISION_2 BIT(25) +#define B_BE_SOP_EXTL BIT(24) +#define B_BE_SOP_OFF_CAPC_EN BIT(23) +#define B_BE_XTAL_OFF_A_DIE BIT(22) +#define B_BE_ROP_SWPR BIT(21) +#define B_BE_DIS_HW_LPLDM BIT(20) +#define B_BE_DIS_HW_LPURLDO BIT(19) +#define B_BE_DIS_WLBT_PDNSUSEN_SOPC BIT(18) +#define B_BE_RDY_SYSPWR BIT(17) +#define B_BE_EN_WLON BIT(16) +#define B_BE_APDM_HPDN BIT(15) +#define B_BE_PSUS_OFF_CAPC_EN BIT(14) +#define B_BE_USUS_OFFCAPC_EN BIT(13) +#define B_BE_AFSM_PCIE_SUS_EN BIT(12) +#define B_BE_AFSM_WLSUS_EN BIT(11) +#define B_BE_APFM_SWLPS BIT(10) +#define B_BE_APFM_OFFMAC BIT(9) +#define B_BE_APFN_ONMAC BIT(8) +#define B_BE_CHIP_PDN_EN BIT(7) +#define B_BE_RDY_MACDIS BIT(6) + +#define R_BE_SYS_CLK_CTRL 0x0008 +#define B_BE_CPU_CLK_EN BIT(14) +#define B_BE_SYMR_BE_CLK_EN BIT(13) +#define B_BE_MAC_CLK_EN BIT(11) +#define B_BE_EXT_32K_EN BIT(8) +#define B_BE_WL_CLK_TEST BIT(7) +#define B_BE_LOADER_CLK_EN BIT(5) +#define B_BE_ANA_CLK_DIVISION_2 BIT(1) +#define B_BE_CNTD16V_EN BIT(0) + +#define R_BE_SYS_WL_EFUSE_CTRL 0x000A +#define B_BE_OTP_B_PWC_RPT BIT(15) +#define B_BE_OTP_S_PWC_RPT BIT(14) +#define B_BE_OTP_ISO_RPT BIT(13) +#define B_BE_OTP_BURST_RPT BIT(12) +#define B_BE_OTP_AUTOLOAD_RPT BIT(11) +#define B_BE_AUTOLOAD_DIS_A_DIE BIT(6) +#define B_BE_AUTOLOAD_SUS BIT(5) +#define B_BE_AUTOLOAD_DIS BIT(4) + +#define R_BE_SYS_PAGE_CLK_GATED 0x000C +#define B_BE_USB_APHY_PC_DLP_OP BIT(27) +#define B_BE_PCIE_APHY_PC_DLP_OP BIT(26) +#define B_BE_UPHY_POWER_READY_CHK BIT(25) +#define B_BE_CPHY_POWER_READY_CHK BIT(24) +#define B_BE_PCIE_PRST_DEBUNC_PERIOD_MASK GENMASK(23, 22) +#define B_BE_SYM_PRST_DEBUNC_SEL BIT(21) +#define B_BE_CPHY_AUXCLK_OP BIT(20) +#define B_BE_SOP_OFFUA_PC BIT(19) +#define B_BE_SOP_OFFPOOBS_PC BIT(18) +#define B_BE_PCIE_LAN1_MASK BIT(17) +#define B_BE_PCIE_LAN0_MASK BIT(16) +#define B_BE_DIS_CLK_REGF_GATE BIT(15) +#define B_BE_DIS_CLK_REGE_GATE BIT(14) +#define B_BE_DIS_CLK_REGD_GATE BIT(13) +#define B_BE_DIS_CLK_REGC_GATE BIT(12) +#define B_BE_DIS_CLK_REGB_GATE BIT(11) +#define B_BE_DIS_CLK_REGA_GATE BIT(10) +#define B_BE_DIS_CLK_REG9_GATE BIT(9) +#define B_BE_DIS_CLK_REG8_GATE BIT(8) +#define B_BE_DIS_CLK_REG7_GATE BIT(7) +#define B_BE_DIS_CLK_REG6_GATE BIT(6) +#define B_BE_DIS_CLK_REG5_GATE BIT(5) +#define B_BE_DIS_CLK_REG4_GATE BIT(4) +#define B_BE_DIS_CLK_REG3_GATE BIT(3) +#define B_BE_DIS_CLK_REG2_GATE BIT(2) +#define B_BE_DIS_CLK_REG1_GATE BIT(1) +#define B_BE_DIS_CLK_REG0_GATE BIT(0) + +#define R_BE_ANAPAR_POW_MAC 0x0016 +#define B_BE_POW_PC_LDO_PORT1 BIT(3) +#define B_BE_POW_PC_LDO_PORT0 BIT(2) +#define B_BE_POW_PLL_V1 BIT(1) +#define B_BE_POW_POWER_CUT_POW_LDO BIT(0) + +#define R_BE_SYS_ADIE_PAD_PWR_CTRL 0x0018 +#define B_BE_SYM_PADPDN_WL_RFC1_1P3 BIT(6) +#define B_BE_SYM_PADPDN_WL_RFC0_1P3 BIT(5) + +#define R_BE_RSV_CTRL 0x001C +#define B_BE_R_SYM_PRST_CPHY_RST BIT(25) +#define B_BE_R_SYM_PRST_PDN_EN BIT(24) +#define B_BE_HR_BE_DBG GENMASK(23, 12) +#define B_BE_R_SYM_DIS_PCIE_FLR BIT(9) +#define B_BE_R_EN_HRST_PWRON BIT(8) +#define B_BE_LOCK_ALL_EN BIT(7) +#define B_BE_R_DIS_PRST BIT(6) +#define B_BE_WLOCK_1C_BIT6 BIT(5) +#define B_BE_WLOCK_40 BIT(4) +#define B_BE_WLOCK_08 BIT(3) +#define B_BE_WLOCK_04 BIT(2) +#define B_BE_WLOCK_00 BIT(1) +#define B_BE_WLOCK_ALL BIT(0) + +#define R_BE_AFE_LDO_CTRL 0x0020 +#define B_BE_FORCE_MACBBBT_PWR_ON BIT(31) +#define B_BE_R_SYM_WLPOFF_P4_PC_EN BIT(28) +#define B_BE_R_SYM_WLPOFF_P3_PC_EN BIT(27) +#define B_BE_R_SYM_WLPOFF_P2_PC_EN BIT(26) +#define B_BE_R_SYM_WLPOFF_P1_PC_EN BIT(25) +#define B_BE_R_SYM_WLPOFF_PC_EN BIT(24) +#define B_BE_AON_OFF_PC_EN BIT(23) +#define B_BE_R_SYM_WLPON_P3_PC_EN BIT(21) +#define B_BE_R_SYM_WLPON_P2_PC_EN BIT(20) +#define B_BE_R_SYM_WLPON_P1_PC_EN BIT(19) +#define B_BE_R_SYM_WLPON_PC_EN BIT(18) +#define B_BE_R_SYM_WLBBPON1_P1_PC_EN BIT(15) +#define B_BE_R_SYM_WLBBPON1_PC_EN BIT(14) +#define B_BE_R_SYM_WLBBPON_P1_PC_EN BIT(13) +#define B_BE_R_SYM_WLBBPON_PC_EN BIT(12) +#define B_BE_R_SYM_DIS_WPHYBBOFF_PC BIT(10) +#define B_BE_R_SYM_WLBBOFF1_P4_PC_EN BIT(9) +#define B_BE_R_SYM_WLBBOFF1_P3_PC_EN BIT(8) +#define B_BE_R_SYM_WLBBOFF1_P2_PC_EN BIT(7) +#define B_BE_R_SYM_WLBBOFF1_P1_PC_EN BIT(6) +#define B_BE_R_SYM_WLBBOFF1_PC_EN BIT(5) +#define B_BE_R_SYM_WLBBOFF_P4_PC_EN BIT(4) +#define B_BE_R_SYM_WLBBOFF_P3_PC_EN BIT(3) +#define B_BE_R_SYM_WLBBOFF_P2_PC_EN BIT(2) +#define B_BE_R_SYM_WLBBOFF_P1_PC_EN BIT(1) +#define B_BE_R_SYM_WLBBOFF_PC_EN BIT(0) + +#define R_BE_AFE_CTRL1 0x0024 +#define B_BE_R_SYM_WLCMAC0_P4_PC_EN BIT(28) +#define B_BE_R_SYM_WLCMAC0_P3_PC_EN BIT(27) +#define B_BE_R_SYM_WLCMAC0_P2_PC_EN BIT(26) +#define B_BE_R_SYM_WLCMAC0_P1_PC_EN BIT(25) +#define B_BE_R_SYM_WLCMAC0_PC_EN BIT(24) +#define B_BE_R_SYM_WLCMAC0_ALL_EN (B_BE_R_SYM_WLCMAC0_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P1_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P2_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P3_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P4_PC_EN) +#define B_BE_DATAMEM_PC3_EN BIT(23) +#define B_BE_DATAMEM_PC2_EN BIT(22) +#define B_BE_DATAMEM_PC1_EN BIT(21) +#define B_BE_DATAMEM_PC_EN BIT(20) +#define B_BE_DMEM7_PC_EN BIT(19) +#define B_BE_DMEM6_PC_EN BIT(18) +#define B_BE_DMEM5_PC_EN BIT(17) +#define B_BE_DMEM4_PC_EN BIT(16) +#define B_BE_DMEM3_PC_EN BIT(15) +#define B_BE_DMEM2_PC_EN BIT(14) +#define B_BE_DMEM1_PC_EN BIT(13) +#define B_BE_IMEM4_PC_EN BIT(12) +#define B_BE_IMEM3_PC_EN BIT(11) +#define B_BE_IMEM2_PC_EN BIT(10) +#define B_BE_IMEM1_PC_EN BIT(9) +#define B_BE_IMEM0_PC_EN BIT(8) +#define B_BE_R_SYM_WLCMAC1_P4_PC_EN BIT(4) +#define B_BE_R_SYM_WLCMAC1_P3_PC_EN BIT(3) +#define B_BE_R_SYM_WLCMAC1_P2_PC_EN BIT(2) +#define B_BE_R_SYM_WLCMAC1_P1_PC_EN BIT(1) +#define B_BE_R_SYM_WLCMAC1_PC_EN BIT(0) +#define B_BE_R_SYM_WLCMAC1_ALL_EN (B_BE_R_SYM_WLCMAC1_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P1_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P2_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P3_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P4_PC_EN) + +#define R_BE_EFUSE_CTRL 0x0030 +#define B_BE_EF_MODE_SEL_MASK GENMASK(31, 30) +#define B_BE_EF_RDY BIT(29) +#define B_BE_EF_COMP_RESULT BIT(28) +#define B_BE_EF_ADDR_MASK GENMASK(15, 0) + +#define R_BE_EFUSE_CTRL_1_V1 0x0034 +#define B_BE_EF_DATA_MASK GENMASK(31, 0) + +#define R_BE_GPIO_MUXCFG 0x0040 +#define B_BE_WCPU_AUTO_EN BIT(26) +#define B_BE_WCPU_JTAG_EN BIT(24) +#define B_BE_WCPU_DBG_EN BIT(23) +#define B_BE_JTAG_CHAIN_EN BIT(20) +#define B_BE_BOOT_MODE BIT(19) +#define B_BE_WL_EECS_EXT_32K_SEL BIT(18) +#define B_BE_WL_SEC_BONDING_OPT_STS BIT(17) +#define B_BE_SECSIC_SEL BIT(16) +#define B_BE_ENHTP BIT(14) +#define B_BE_ENSIC BIT(12) +#define B_BE_SIC_SWRST BIT(11) +#define B_BE_PINMUX_PTA_EN BIT(10) +#define B_BE_WL_BT_PTA_SEC BIT(9) +#define B_BE_ENUARTTX BIT(8) +#define B_BE_DBG_GNT_BT_S1_POLARITY BIT(4) +#define B_BE_ENUARTRX BIT(2) + +#define R_BE_GPIO_EXT_CTRL 0x0060 +#define B_BE_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24) +#define B_BE_GPIO_MOD_9 BIT(25) +#define B_BE_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16) +#define B_BE_GPIO_IO_SEL_9 BIT(17) +#define B_BE_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8) +#define B_BE_GPIO_IN_15_TO_8_MASK GENMASK(7, 0) +#define B_BE_GPIO_IN_9 BIT(1) + +#define R_BE_WL_BT_PWR_CTRL 0x0068 +#define B_BE_ISO_BD2PP BIT(31) +#define B_BE_LDOV12B_EN BIT(30) +#define B_BE_CKEN_BT BIT(29) +#define B_BE_FEN_BT BIT(28) +#define B_BE_BTCPU_BOOTSEL BIT(27) +#define B_BE_SPI_SPEEDUP BIT(26) +#define B_BE_BT_LDO_MODE BIT(25) +#define B_BE_ISO_BTPON2PP BIT(22) +#define B_BE_BT_FUNC_EN BIT(18) +#define B_BE_BT_HWPDN_SL BIT(17) +#define B_BE_BT_DISN_EN BIT(16) +#define B_BE_SDM_SRC_SEL BIT(12) +#define B_BE_ISO_BA2PP BIT(11) +#define B_BE_BT_AFE_LDO_EN BIT(10) +#define B_BE_BT_AFE_PLL_EN BIT(9) +#define B_BE_WLAN_32K_SEL BIT(6) +#define B_BE_WL_DRV_EXIST_IDX BIT(5) +#define B_BE_DOP_EHPAD BIT(4) +#define B_BE_WL_FUNC_EN BIT(2) +#define B_BE_WL_HWPDN_SL BIT(1) +#define B_BE_WL_HWPDN_EN BIT(0) + +#define R_BE_SYS_SDIO_CTRL 0x0070 +#define B_BE_MCM_FLASH_EN BIT(28) +#define B_BE_SER_DETECT_EN BIT(26) +#define B_BE_PCIE_SEC_LOAD BIT(26) +#define B_BE_PCIE_SER_RSTB BIT(25) +#define B_BE_PCIE_SEC_LOAD_CLR BIT(24) +#define B_BE_SDIO_CMD_SW_RST BIT(20) +#define B_BE_SDIO_INT_POLARITY BIT(19) +#define B_BE_SDIO_OFF_EN BIT(17) +#define B_BE_SDIO_ON_EN BIT(16) +#define B_BE_PCIE_DIS_L2__CTRL_LDO_HCI BIT(15) +#define B_BE_PCIE_DIS_L2_RTK_PERST BIT(14) +#define B_BE_PCIE_FORCE_PWR_NGAT BIT(13) +#define B_BE_PCIE_FORCE_IBX_EN BIT(12) +#define B_BE_PCIE_AUXCLK_GATE BIT(11) +#define B_BE_PCIE_WAIT_TIMEOUT_EVENT BIT(10) +#define B_BE_PCIE_WAIT_TIME BIT(9) +#define B_BE_L1OFF_TO_L0_RESUME_EVT BIT(8) +#define B_BE_USBA_FORCE_PWR_NGAT BIT(7) +#define B_BE_USBD_FORCE_PWR_NGAT BIT(6) +#define B_BE_BT_CTRL_USB_PWR BIT(5) +#define B_BE_USB_D_STATE_HOLD BIT(4) +#define B_BE_R_BE_FORCE_DP BIT(3) +#define B_BE_R_BE_DP_MODE BIT(2) +#define B_BE_RES_USB_MASS_STORAGE_DESC BIT(1) +#define B_BE_USB_WAIT_TIME BIT(0) + +#define R_BE_HCI_OPT_CTRL 0x0074 +#define B_BE_HCI_WLAN_IO_ST BIT(31) +#define B_BE_HCI_WLAN_IO_EN BIT(28) +#define B_BE_HAXIDMA_IO_ST BIT(27) +#define B_BE_HAXIDMA_BACKUP_RESTORE_ST BIT(26) +#define B_BE_HAXIDMA_IO_EN BIT(24) +#define B_BE_EN_PCIE_WAKE BIT(23) +#define B_BE_SDIO_PAD_H3L1 BIT(22) +#define B_BE_USBMAC_ANACLK_SW BIT(21) +#define B_BE_PCIE_CPHY_CCK_XTAL_SEL BIT(20) +#define B_BE_SDIO_DATA_PAD_SMT BIT(19) +#define B_BE_SDIO_PAD_E5 BIT(18) +#define B_BE_FORCE_PCIE_AUXCLK BIT(17) +#define B_BE_HCI_LA_ADDR_MAP BIT(16) +#define B_BE_HCI_LA_GLO_RST BIT(15) +#define B_BE_USB3_SUS_DIS BIT(14) +#define B_BE_NOPWR_CTRL_SEL BIT(13) +#define B_BE_USB_HOST_PWR_OFF_EN BIT(12) +#define B_BE_SYM_LPS_BLOCK_EN BIT(11) +#define B_BE_USB_LPM_ACT_EN BIT(10) +#define B_BE_USB_LPM_NY BIT(9) +#define B_BE_USB2_SUS_DIS BIT(8) +#define B_BE_SDIO_PAD_E_MASK GENMASK(7, 5) +#define B_BE_USB_LPPLL_EN BIT(4) +#define B_BE_USB1_1_USB2_0_DECISION BIT(3) +#define B_BE_ROP_SW15 BIT(2) +#define B_BE_PCI_CKRDY_OPT BIT(1) +#define B_BE_PCI_VAUX_EN BIT(0) + +#define R_BE_SYS_ISO_CTRL_EXTEND 0x0080 +#define B_BE_R_SYM_ISO_DMEM62PP BIT(29) +#define B_BE_R_SYM_ISO_DMEM52PP BIT(28) +#define B_BE_R_SYM_ISO_DMEM42PP BIT(27) +#define B_BE_R_SYM_ISO_DMEM32PP BIT(26) +#define B_BE_R_SYM_ISO_DMEM22PP BIT(25) +#define B_BE_R_SYM_ISO_DMEM12PP BIT(24) +#define B_BE_R_SYM_ISO_IMEM42PP BIT(22) +#define B_BE_R_SYM_ISO_IMEM32PP BIT(21) +#define B_BE_R_SYM_ISO_IMEM22PP BIT(20) +#define B_BE_R_SYM_ISO_IMEM12PP BIT(19) +#define B_BE_R_SYM_ISO_IMEM02PP BIT(18) +#define B_BE_R_SYM_ISO_AON_OFF2PP BIT(15) +#define B_BE_R_SYM_PWC_HCILA BIT(13) +#define B_BE_R_SYM_PWC_PD12V BIT(12) +#define B_BE_R_SYM_PWC_UD12V BIT(11) +#define B_BE_R_SYM_PWC_BTBRG BIT(10) +#define B_BE_R_SYM_LDOBTSDIO_EN BIT(9) +#define B_BE_R_SYM_LDOSPDIO_EN BIT(8) +#define B_BE_R_SYM_ISO_HCILA BIT(4) +#define B_BE_R_SYM_ISO_BTBRG2PP BIT(2) +#define B_BE_R_SYM_ISO_BTSDIO2PP BIT(1) +#define B_BE_R_SYM_ISO_SPDIO2PP BIT(0) + +#define R_BE_FEN_RST_ENABLE 0x0084 +#define B_BE_R_SYM_FEN_WLMACOFF BIT(31) +#define B_BE_R_SYM_ISO_WA12PP BIT(28) +#define B_BE_R_SYM_ISO_CMAC12PP BIT(25) +#define B_BE_R_SYM_ISO_CMAC02PP BIT(24) +#define B_BE_R_SYM_ISO_ADDA_P32PP BIT(23) +#define B_BE_R_SYM_ISO_ADDA_P22PP BIT(22) +#define B_BE_R_SYM_ISO_ADDA_P12PP BIT(21) +#define B_BE_R_SYM_ISO_ADDA_P02PP BIT(20) +#define B_BE_CMAC1_FEN BIT(17) +#define B_BE_CMAC0_FEN BIT(16) +#define B_BE_SYM_ISO_BBPON12PP BIT(13) +#define B_BE_SYM_ISO_BB12PP BIT(12) +#define B_BE_BOOT_RDY1 BIT(10) +#define B_BE_FEN_BB1_IP_RSTN BIT(9) +#define B_BE_FEN_BB1PLAT_RSTB BIT(8) +#define B_BE_SYM_ISO_BBPON02PP BIT(5) +#define B_BE_SYM_ISO_BB02PP BIT(4) +#define B_BE_BOOT_RDY0 BIT(2) +#define B_BE_FEN_BB_IP_RSTN BIT(1) +#define B_BE_FEN_BBPLAT_RSTB BIT(0) + +#define R_BE_PLATFORM_ENABLE 0x0088 +#define B_BE_HOLD_AFTER_RESET BIT(11) +#define B_BE_SYM_WLPLT_MEM_MUX_EN BIT(10) +#define B_BE_WCPU_WARM_EN BIT(9) +#define B_BE_SPIC_EN BIT(8) +#define B_BE_UART_EN BIT(7) +#define B_BE_IDDMA_EN BIT(6) +#define B_BE_IPSEC_EN BIT(5) +#define B_BE_HIOE_EN BIT(4) +#define B_BE_APB_WRAP_EN BIT(2) +#define B_BE_WCPU_EN BIT(1) +#define B_BE_PLATFORM_EN BIT(0) + +#define R_BE_WLLPS_CTRL 0x0090 +#define B_BE_LPSOP_BBMEMDS BIT(30) +#define B_BE_LPSOP_BBOFF BIT(29) +#define B_BE_LPSOP_MACOFF BIT(28) +#define B_BE_LPSOP_OFF_CAPC_EN BIT(27) +#define B_BE_LPSOP_MEM_DS BIT(26) +#define B_BE_LPSOP_XTALM_LPS BIT(23) +#define B_BE_LPSOP_XTAL BIT(22) +#define B_BE_LPSOP_ACLK_DIV_2 BIT(21) +#define B_BE_LPSOP_ACLK_SEL BIT(20) +#define B_BE_LPSOP_ASWRM BIT(17) +#define B_BE_LPSOP_ASWR BIT(16) +#define B_BE_LPSOP_DSWR_ADJ_MASK GENMASK(15, 12) +#define B_BE_LPSOP_DSWRSD BIT(10) +#define B_BE_LPSOP_DSWRM BIT(9) +#define B_BE_LPSOP_DSWR BIT(8) +#define B_BE_LPSOP_OLD_ADJ_MASK GENMASK(7, 4) +#define B_BE_FORCE_LEAVE_LPS BIT(3) +#define B_BE_LPSOP_OLDSD BIT(2) +#define B_BE_DIS_WLBT_LPSEN_LOPC BIT(1) +#define B_BE_WL_LPS_EN BIT(0) + +#define R_BE_WLRESUME_CTRL 0x0094 +#define B_BE_LPSROP_DMEM5_RSU_EN BIT(31) +#define B_BE_LPSROP_DMEM4_RSU_EN BIT(30) +#define B_BE_LPSROP_DMEM3_RSU_EN BIT(29) +#define B_BE_LPSROP_DMEM2_RSU_EN BIT(28) +#define B_BE_LPSROP_DMEM1_RSU_EN BIT(27) +#define B_BE_LPSROP_DMEM0_RSU_EN BIT(26) +#define B_BE_LPSROP_IMEM5_RSU_EN BIT(25) +#define B_BE_LPSROP_IMEM4_RSU_EN BIT(24) +#define B_BE_LPSROP_IMEM3_RSU_EN BIT(23) +#define B_BE_LPSROP_IMEM2_RSU_EN BIT(22) +#define B_BE_LPSROP_IMEM1_RSU_EN BIT(21) +#define B_BE_LPSROP_IMEM0_RSU_EN BIT(20) +#define B_BE_LPSROP_BB1_W_BB0 BIT(14) +#define B_BE_LPSROP_CMAC1 BIT(13) +#define B_BE_LPSROP_CMAC0 BIT(12) +#define B_BE_LPSROP_XTALM BIT(11) +#define B_BE_LPSROP_PLLM BIT(10) +#define B_BE_LPSROP_HIOE BIT(9) +#define B_BE_LPSROP_CPU BIT(8) +#define B_BE_LPSROP_LOWPWRPLL BIT(7) +#define B_BE_LPSROP_DSWRSD_SEL_MASK GENMASK(5, 4) + +#define R_BE_SYSON_FSM_MON 0x00A0 +#define B_BE_FSM_MON_SEL_MASK GENMASK(26, 24) +#define B_BE_DOP_ELDO BIT(23) +#define B_BE_AFE_PLL_BYPASS BIT(22) +#define B_BE_PON_SWR_BYPASS BIT(21) +#define B_BE_PON_ADIE_BYPASS BIT(20) +#define B_BE_AFE_LS_BYPASS BIT(19) +#define B_BE_BTPMC_XTAL_SI_BYPASS BIT(17) +#define B_BE_WLPMC_XTAL_SI_BYPASS BIT(16) +#define B_BE_FSM_MON_UPD BIT(15) +#define B_BE_FSM_PAR_MASK GENMASK(14, 0) +#define WLAN_FSM_MASK 0xFFFFFF +#define WLAN_FSM_SET 0x4000000 +#define WLAN_FSM_STATE_MASK 0x1FF +#define WLAN_FSM_IDLE 0 + +#define R_BE_EFUSE_CTRL_2_V1 0x00A4 +#define B_BE_EF_ENT BIT(31) +#define B_BE_EF_TCOLUMN_EN BIT(29) +#define B_BE_BT_OTP_PWC_DIS BIT(28) +#define B_BE_EF_RDT BIT(27) +#define B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL BIT(24) +#define B_BE_EF_PGTS_MASK GENMASK(23, 20) +#define B_BE_EF_BURST BIT(19) +#define B_BE_EF_TEST_SEL_MASK GENMASK(18, 16) +#define B_BE_EF_TROW_EN BIT(15) +#define B_BE_EF_ERR_FLAG BIT(14) +#define B_BE_EF_FBURST_DIS BIT(13) +#define B_BE_EF_HT_SEL BIT(12) +#define B_BE_EF_DSB_EN BIT(11) +#define B_BE_EF_DLY_SEL_MASK GENMASK(3, 0) + +#define R_BE_SCOREBOARD 0x00AC +#define B_BE_TOGGLE BIT(31) +#define B_BE_DATA_LINE_MASK GENMASK(30, 0) + +#define R_BE_PAD_CTRL2 0x00C4 +#define B_BE_USB23_SW_MODE BIT(31) +#define B_BE_USB3_GEN_MODE BIT(30) +#define B_BE_USB3_LANE_MODE BIT(29) +#define B_BE_USB_AUTO_INSTALL_MASK BIT(28) +#define B_BE_FORCE_CLK_U2 BIT(25) +#define B_BE_FORCE_U2_CK BIT(24) +#define B_BE_FORCE_U3_CK BIT(23) +#define B_BE_USB2_FORCE BIT(22) +#define B_BE_USB3_FORCE BIT(21) +#define B_BE_NO_PDN_CHIPOFF_V1 BIT(17) +#define B_BE_RSM_EN_V1 BIT(16) +#define B_BE_MATCH_CNT GENMASK(15, 8) + +#define R_BE_PMC_DBG_CTRL2 0x00CC +#define B_BE_EFUSE_BURN_GNT_MASK GENMASK(31, 24) +#define B_BE_DIS_IOWRAP_TIMEOUT BIT(16) +#define B_BE_STOP_WL_PMC BIT(9) +#define B_BE_STOP_SYM_PMC BIT(8) +#define B_BE_SYM_REG_PCIE_WRMSK BIT(7) +#define B_BE_BT_ACCESS_WL_PAGE0 BIT(6) +#define B_BE_R_BE_RST_WLPMC BIT(5) +#define B_BE_R_BE_RST_PD12N BIT(4) +#define B_BE_SYSON_DIS_WLR_BE_WRMSK BIT(3) +#define B_BE_SYSON_DIS_PMCR_BE_WRMSK BIT(2) +#define B_BE_SYSON_R_BE_ARB_MASK GENMASK(1, 0) + +#define R_BE_MEM_PWR_CTRL 0x00D0 +#define B_BE_DMEM5_WLMCU_DS BIT(31) +#define B_BE_DMEM4_WLMCU_DS BIT(30) +#define B_BE_DMEM3_WLMCU_DS BIT(29) +#define B_BE_DMEM2_WLMCU_DS BIT(28) +#define B_BE_DMEM1_WLMCU_DS BIT(27) +#define B_BE_DMEM0_WLMCU_DS BIT(26) +#define B_BE_IMEM5_WLMCU_DS BIT(25) +#define B_BE_IMEM4_WLMCU_DS BIT(24) +#define B_BE_IMEM3_WLMCU_DS BIT(23) +#define B_BE_IMEM2_WLMCU_DS BIT(22) +#define B_BE_IMEM1_WLMCU_DS BIT(21) +#define B_BE_IMEM0_WLMCU_DS BIT(20) +#define B_BE_MEM_BBMCU1_DS BIT(19) +#define B_BE_MEM_BBMCU0_DS_V1 BIT(17) +#define B_BE_MEM_BT_DS BIT(10) +#define B_BE_MEM_SDIO_LS BIT(9) +#define B_BE_MEM_SDIO_DS BIT(8) +#define B_BE_MEM_USB_LS BIT(7) +#define B_BE_MEM_USB_DS BIT(6) +#define B_BE_MEM_PCI_LS BIT(5) +#define B_BE_MEM_PCI_DS BIT(4) +#define B_BE_MEM_WLMAC_LS BIT(3) + +#define R_BE_PCIE_MIO_INTF 0x00E4 +#define B_BE_AON_MIO_EPHY_1K_SEL_MASK GENMASK(29, 24) +#define B_BE_PCIE_MIO_ADDR_PAGE_V1_MASK GENMASK(20, 16) +#define B_BE_PCIE_MIO_ASIF BIT(15) +#define B_BE_PCIE_MIO_BYIOREG BIT(13) +#define B_BE_PCIE_MIO_RE BIT(12) +#define B_BE_PCIE_MIO_WE_MASK GENMASK(11, 8) +#define B_BE_PCIE_MIO_ADDR_MASK GENMASK(7, 0) + +#define R_BE_PCIE_MIO_INTD 0x00E8 +#define B_BE_PCIE_MIO_DATA_MASK GENMASK(31, 0) + +#define R_BE_SYS_CHIPINFO 0x00FC +#define B_BE_USB2_SEL BIT(31) +#define B_BE_U3PHY_RST_V1 BIT(30) +#define B_BE_U3_TERM_DETECT BIT(29) +#define B_BE_VERIFY_ENV_MASK GENMASK(9, 8) +#define B_BE_HW_ID_MASK GENMASK(7, 0) + +#define R_BE_SCOREBOARD_0 0x0110 +#define B_BE_SB0_TOGGLE BIT(31) +#define B_BE_SB0_WL_DATA_LINE_MASK GENMASK(30, 0) + +#define R_BE_SCOREBOARD_0_BT_DATA 0x0114 +#define B_BE_SB0_BT_DATA_LINE_MASK GENMASK(30, 0) + +#define R_BE_SCOREBOARD_1 0x0118 +#define B_BE_SB1_TOGGLE BIT(31) +#define B_BE_SB1_WL_DATA_LINE_MASK GENMASK(30, 0) + +#define R_BE_SCOREBOARD_1_BT_DATA 0x011C +#define B_BE_SB1_BT_DATA_LINE_MASK GENMASK(30, 0) + +#define R_BE_HALT_H2C_CTRL 0x0160 +#define B_BE_HALT_H2C_TRIGGER BIT(0) + +#define R_BE_HALT_C2H_CTRL 0x0164 +#define B_BE_HALT_C2H_TRIGGER BIT(0) + +#define R_BE_HALT_H2C 0x0168 +#define B_BE_HALT_H2C_MASK GENMASK(31, 0) + +#define R_BE_HALT_C2H 0x016C +#define B_BE_HALT_C2H_ERROR_SENARIO_MASK GENMASK(31, 28) +#define B_BE_ERROR_CODE_MASK GENMASK(15, 0) + +#define R_BE_SYS_CFG5 0x0170 +#define B_BE_WDT_DATACPU_WAKE_PCIE_EN BIT(12) +#define B_BE_WDT_DATACPU_WAKE_USB_EN BIT(11) +#define B_BE_WDT_WAKE_PCIE_EN BIT(10) +#define B_BE_WDT_WAKE_USB_EN BIT(9) +#define B_BE_SYM_DIS_HC_ACCESS_MAC BIT(8) +#define B_BE_LPS_STATUS BIT(3) +#define B_BE_HCI_TXDMA_BUSY BIT(2) + +#define R_BE_SECURE_BOOT_MALLOC_INFO 0x0184 + +#define R_BE_FW_AUTO_CAL_DELAY 0x0188 +#define B_BE_WCPU_FW_DELAY_COUNT_VALID BIT(15) +#define B_BE_WCPU_FW_DELAY_COUNT_MASK GENMASK(14, 0) + +#define R_BE_FWS0IMR 0x0190 +#define B_BE_FS_HALT_H2C_INT_EN BIT(31) +#define B_BE_FS_FSM_HIOE_TO_EVENT_INT_EN BIT(30) +#define B_BE_FS_HCI_SUS_INT_EN BIT(29) +#define B_BE_FS_HCI_RES_INT_EN BIT(28) +#define B_BE_FS_HCI_RESET_INT_EN BIT(27) +#define B_BE_FS_BT_SB1_INT_EN BIT(26) +#define B_BE_FS_ACT2RECOVERY_INT_EN BIT(25) +#define B_BE_FS_GEN1GEN2_SWITCH_INT_EN BIT(24) +#define B_BE_FS_USB_LPMRSM_INT_EN BIT(22) +#define B_BE_FS_USB_LPMINT_INT_EN BIT(21) +#define B_BE_FS_PWMERR_INT_EN BIT(20) +#define B_BE_FS_PDNINT_EN BIT(19) +#define B_BE_FS_SPSA_OCP_INT_EN BIT(18) +#define B_BE_FS_SPSD_OCP_INT_EN BIT(17) +#define B_BE_FS_BT_SB0_INT_EN BIT(16) +#define B_BE_FS_GPIOF_INT_EN BIT(15) +#define B_BE_FS_GPIOE_INT_EN BIT(14) +#define B_BE_FS_GPIOD_INT_EN BIT(13) +#define B_BE_FS_GPIOC_INT_EN BIT(12) +#define B_BE_FS_GPIOB_INT_EN BIT(11) +#define B_BE_FS_GPIOA_INT_EN BIT(10) +#define B_BE_FS_GPIO9_INT_EN BIT(9) +#define B_BE_FS_GPIO8_INT_EN BIT(8) +#define B_BE_FS_GPIO7_INT_EN BIT(7) +#define B_BE_FS_GPIO6_INT_EN BIT(6) +#define B_BE_FS_GPIO5_INT_EN BIT(5) +#define B_BE_FS_GPIO4_INT_EN BIT(4) +#define B_BE_FS_GPIO3_INT_EN BIT(3) +#define B_BE_FS_GPIO2_INT_EN BIT(2) +#define B_BE_FS_GPIO1_INT_EN BIT(1) +#define B_BE_FS_GPIO0_INT_EN BIT(0) + +#define R_BE_FWS0ISR 0x0194 +#define B_BE_FS_HALT_H2C_INT BIT(31) +#define B_BE_FS_FSM_HIOE_TO_EVENT_INT BIT(30) +#define B_BE_FS_HCI_SUS_INT BIT(29) +#define B_BE_FS_HCI_RES_INT BIT(28) +#define B_BE_FS_HCI_RESET_INT BIT(27) +#define B_BE_FS_BT_SB1_INT BIT(26) +#define B_BE_FS_ACT2RECOVERY_INT BIT(25) +#define B_BE_FS_GEN1GEN2_SWITCH_INT BIT(24) +#define B_BE_FS_USB_LPMRSM_INT BIT(22) +#define B_BE_FS_USB_LPMINT_INT BIT(21) +#define B_BE_FS_PWMERR_INT BIT(20) +#define B_BE_FS_PDNINT BIT(19) +#define B_BE_FS_SPSA_OCP_INT BIT(18) +#define B_BE_FS_SPSD_OCP_INT BIT(17) +#define B_BE_FS_BT_SB0_INT BIT(16) +#define B_BE_FS_GPIOF_INT BIT(15) +#define B_BE_FS_GPIOE_INT BIT(14) +#define B_BE_FS_GPIOD_INT BIT(13) +#define B_BE_FS_GPIOC_INT BIT(12) +#define B_BE_FS_GPIOB_INT BIT(11) +#define B_BE_FS_GPIOA_INT BIT(10) +#define B_BE_FS_GPIO9_INT BIT(9) +#define B_BE_FS_GPIO8_INT BIT(8) +#define B_BE_FS_GPIO7_INT BIT(7) +#define B_BE_FS_GPIO6_INT BIT(6) +#define B_BE_FS_GPIO5_INT BIT(5) +#define B_BE_FS_GPIO4_INT BIT(4) +#define B_BE_FS_GPIO3_INT BIT(3) +#define B_BE_FS_GPIO2_INT BIT(2) +#define B_BE_FS_GPIO1_INT BIT(1) +#define B_BE_FS_GPIO0_INT BIT(0) + +#define R_BE_FWS1IMR 0x0198 +#define B_BE_FS_RPWM_INT_EN_V1 BIT(24) +#define B_BE_PCIE_HOTRST_EN BIT(22) +#define B_BE_PCIE_SER_TIMEOUT_INDIC_EN BIT(21) +#define B_BE_PCIE_RXI300_SLVTOUT_INDIC_EN BIT(20) +#define B_BE_AON_PCIE_FLR_INT_EN BIT(19) +#define B_BE_PCIE_ERR_INDIC_INT_EN BIT(18) +#define B_BE_SDIO_ERR_INDIC_INT_EN BIT(17) +#define B_BE_USB_ERR_INDIC_INT_EN BIT(16) +#define B_BE_FS_GPIO27_INT_EN BIT(11) +#define B_BE_FS_GPIO26_INT_EN BIT(10) +#define B_BE_FS_GPIO25_INT_EN BIT(9) +#define B_BE_FS_GPIO24_INT_EN BIT(8) +#define B_BE_FS_GPIO23_INT_EN BIT(7) +#define B_BE_FS_GPIO22_INT_EN BIT(6) +#define B_BE_FS_GPIO21_INT_EN BIT(5) +#define B_BE_FS_GPIO20_INT_EN BIT(4) +#define B_BE_FS_GPIO19_INT_EN BIT(3) +#define B_BE_FS_GPIO18_INT_EN BIT(2) +#define B_BE_FS_GPIO17_INT_EN BIT(1) +#define B_BE_FS_GPIO16_INT_EN BIT(0) + +#define R_BE_FWS1ISR 0x019C +#define B_BE_FS_WL_HW_RADIO_OFF_INT BIT(28) +#define B_BE_SWRD_BOD_INT BIT(27) +#define B_BE_HCIDBG_INT BIT(25) +#define B_BE_FS_RPWM_INT_V1 BIT(24) +#define B_BE_PCIE_HOTRST BIT(22) +#define B_BE_PCIE_SER_TIMEOUT_INDIC BIT(21) +#define B_BE_PCIE_RXI300_SLVTOUT_INDIC BIT(20) +#define B_BE_AON_PCIE_FLR_INT BIT(19) +#define B_BE_PCIE_ERR_INDIC BIT(18) +#define B_BE_SDIO_ERR_INDIC BIT(17) +#define B_BE_USB_ERR_INDIC BIT(16) +#define B_BE_FS_GPIO27_INT BIT(11) +#define B_BE_FS_GPIO26_INT BIT(10) +#define B_BE_FS_GPIO25_INT BIT(9) +#define B_BE_FS_GPIO24_INT BIT(8) +#define B_BE_FS_GPIO23_INT BIT(7) +#define B_BE_FS_GPIO22_INT BIT(6) +#define B_BE_FS_GPIO21_INT BIT(5) +#define B_BE_FS_GPIO20_INT BIT(4) +#define B_BE_FS_GPIO19_INT BIT(3) +#define B_BE_FS_GPIO18_INT BIT(2) +#define B_BE_FS_GPIO17_INT BIT(1) +#define B_BE_FS_GPIO16_INT BIT(0) + +#define R_BE_HIMR0 0x01A0 +#define B_BE_WDT_DATACPU_TIMEOUT_INT_EN BIT(25) +#define B_BE_HALT_D2H_INT_EN BIT(24) +#define B_BE_WDT_TIMEOUT_INT_EN BIT(22) +#define B_BE_HALT_C2H_INT_EN BIT(21) +#define B_BE_RON_INT_EN BIT(20) +#define B_BE_PDNINT_EN BIT(19) +#define B_BE_SPSANA_OCP_INT_EN BIT(18) +#define B_BE_SPS_OCP_INT_EN BIT(17) +#define B_BE_BTON_STS_UPDATE_INT_EN BIT(16) +#define B_BE_GPIOF_INT_EN BIT(15) +#define B_BE_GPIOE_INT_EN BIT(14) +#define B_BE_GPIOD_INT_EN BIT(13) +#define B_BE_GPIOC_INT_EN BIT(12) +#define B_BE_GPIOB_INT_EN BIT(11) +#define B_BE_GPIOA_INT_EN BIT(10) +#define B_BE_GPIO9_INT_EN BIT(9) +#define B_BE_GPIO8_INT_EN BIT(8) +#define B_BE_GPIO7_INT_EN BIT(7) +#define B_BE_GPIO6_INT_EN BIT(6) +#define B_BE_GPIO5_INT_EN BIT(5) +#define B_BE_GPIO4_INT_EN BIT(4) +#define B_BE_GPIO3_INT_EN BIT(3) +#define B_BE_GPIO2_INT_EN BIT(2) +#define B_BE_GPIO1_INT_EN BIT(1) +#define B_BE_GPIO0_INT_EN BIT(0) + +#define R_BE_HISR0 0x01A4 +#define B_BE_WDT_DATACPU_TIMEOUT_INT BIT(25) +#define B_BE_HALT_D2H_INT BIT(24) +#define B_BE_WDT_TIMEOUT_INT BIT(22) +#define B_BE_HALT_C2H_INT BIT(21) +#define B_BE_RON_INT BIT(20) +#define B_BE_PDNINT BIT(19) +#define B_BE_SPSANA_OCP_INT BIT(18) +#define B_BE_SPS_OCP_INT BIT(17) +#define B_BE_BTON_STS_UPDATE_INT BIT(16) +#define B_BE_GPIOF_INT BIT(15) +#define B_BE_GPIOE_INT BIT(14) +#define B_BE_GPIOD_INT BIT(13) +#define B_BE_GPIOC_INT BIT(12) +#define B_BE_GPIOB_INT BIT(11) +#define B_BE_GPIOA_INT BIT(10) +#define B_BE_GPIO9_INT BIT(9) +#define B_BE_GPIO8_INT BIT(8) +#define B_BE_GPIO7_INT BIT(7) +#define B_BE_GPIO6_INT BIT(6) +#define B_BE_GPIO5_INT BIT(5) +#define B_BE_GPIO4_INT BIT(4) +#define B_BE_GPIO3_INT BIT(3) +#define B_BE_GPIO2_INT BIT(2) +#define B_BE_GPIO1_INT BIT(1) +#define B_BE_GPIO0_INT BIT(0) + +#define R_BE_WCPU_FW_CTRL 0x01E0 +#define B_BE_RUN_ENV_MASK GENMASK(31, 30) +#define B_BE_WCPU_FWDL_STATUS_MASK GENMASK(29, 26) +#define B_BE_WDT_PLT_RST_EN BIT(17) +#define B_BE_HOST_EXIST BIT(16) +#define B_BE_FW_SEC_AUTH_DONE BIT(14) +#define B_BE_FW_CPU_UTIL_STS_EN BIT(13) +#define B_BE_BBMCU1_FWDL_EN BIT(12) +#define B_BE_BBMCU0_FWDL_EN BIT(11) +#define B_BE_DATACPU_FWDL_EN BIT(10) +#define B_BE_WLANCPU_FWDL_EN BIT(9) +#define B_BE_WCPU_ROM_CUT_GET BIT(8) +#define B_BE_WCPU_ROM_CUT_VAL_MASK GENMASK(7, 4) +#define B_BE_FW_BOOT_MODE_MASK GENMASK(3, 2) +#define B_BE_H2C_PATH_RDY BIT(1) +#define B_BE_DLFW_PATH_RDY BIT(0) + +#define R_BE_BOOT_REASON 0x01E6 +#define B_BE_BOOT_REASON_MASK GENMASK(2, 0) + +#define R_BE_LDM 0x01E8 +#define B_BE_EN_32K BIT(31) +#define B_BE_LDM_MASK GENMASK(30, 0) + +#define R_BE_UDM0 0x01F0 +#define B_BE_UDM0_SEND2RA_CNT_MASK GENMASK(31, 28) +#define B_BE_UDM0_TX_RPT_CNT_MASK GENMASK(27, 24) +#define B_BE_UDM0_FS_CODE_MASK GENMASK(23, 8) +#define B_BE_NULL_POINTER_INDC BIT(7) +#define B_BE_ROM_ASSERT_INDC BIT(6) +#define B_BE_RAM_ASSERT_INDC BIT(5) +#define B_BE_FW_IMAGE_TYPE BIT(4) +#define B_BE_UDM0_TRAP_LOOP_CTRL BIT(2) +#define B_BE_UDM0_SEND_HALTC2H_CTRL BIT(1) +#define B_BE_UDM0_DBG_MODE_CTRL BIT(0) + +#define R_BE_UDM1 0x01F4 +#define B_BE_UDM1_ERROR_ADDR_MASK GENMASK(31, 16) +#define B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK GENMASK(15, 12) +#define B_BE_UDM1_HALMAC_H2C_DEQ_CNT_MASK GENMASK(11, 8) +#define B_BE_UDM1_WCPU_C2H_ENQ_CNT_MASK GENMASK(7, 4) +#define B_BE_UDM1_WCPU_H2C_DEQ_CNT_MASK GENMASK(3, 0) + +#define R_BE_UDM2 0x01F8 +#define B_BE_UDM2_EPC_RA_MASK GENMASK(31, 0) + +#define R_BE_SPS_DIG_ON_CTRL0 0x0200 +#define B_BE_PFMCMP_IQ BIT(31) +#define B_BE_FREQ_MASK GENMASK(30, 27) +#define B_BE_OFF_END_SEL BIT(26) +#define B_BE_POW_MINOFF_L BIT(25) +#define B_BE_REG_BYPASS_L BIT(24) +#define B_BE_VREFPFM_L_MASK GENMASK(23, 19) +#define B_BE_REG_ZCDC_H_MASK GENMASK(18, 17) +#define B_BE_FORCE_ZCD_BIAS BIT(16) +#define B_BE_ZCD_SDZ_L_MASK GENMASK(15, 14) +#define B_BE_ISAW_MASK GENMASK(13, 10) +#define B_BE_SS_DIVSEL_MASK GENMASK(9, 8) +#define B_BE_REG_BG_H BIT(7) +#define B_BE_FPWM_L1 BIT(6) +#define B_BE_POW_ZCD_L BIT(5) +#define B_BE_PWMTUNE_MASK GENMASK(4, 0) + +#define R_BE_SPS_DIG_ON_CTRL1 0x0204 +#define B_BE_SN_N_L_MASK GENMASK(31, 28) +#define B_BE_SP_N_L_MASK GENMASK(27, 24) +#define B_BE_SN_P_L_MASK GENMASK(23, 20) +#define B_BE_SP_P_L_MASK GENMASK(19, 16) +#define B_BE_VO_DISCHG_PWM_H BIT(15) +#define B_BE_REG_MODE_PREDRIVER BIT(14) +#define B_BE_VREFOCP_MASK GENMASK(13, 10) +#define B_BE_POWOCP_L1 BIT(9) +#define B_BE_PWM_FORCE BIT(8) +#define B_BE_PFM_PD_RST BIT(7) +#define B_BE_VC_PFM_RSTB BIT(6) +#define B_BE_PFM_IN_SEL BIT(5) +#define B_BE_VC_RSTB BIT(4) +#define B_BE_FPWMDELAY BIT(3) +#define B_BE_ENFPWMDELAY_H BIT(2) +#define B_BE_REG_MOS_HALF_L BIT(1) +#define B_BE_CURRENT_SENSE_MOS BIT(0) + +#define R_BE_SPS_ANA_ON_CTRL1 0x0224 +#define B_BE_SN_N_L_ANA_MASK GENMASK(31, 28) +#define B_BE_SP_N_L_ANA_MASK GENMASK(27, 24) +#define B_BE_SN_P_L_ANA_MASK GENMASK(23, 20) +#define B_BE_SP_P_L_ANA_MASK GENMASK(19, 16) +#define B_BE_VO_DISCHG_PWM_H_ANA BIT(15) +#define B_BE_REG_MODE_PREDRIVER_ANA BIT(14) +#define B_BE_VREFOCP_ANA_MASK GENMASK(13, 10) +#define B_BE_POWOCP_L1_ANA BIT(9) +#define B_BE_PWM_FORCE_ANA BIT(8) +#define B_BE_PFM_PD_RST_ANA BIT(7) +#define B_BE_VC_PFM_RSTB_ANA BIT(6) +#define B_BE_PFM_IN_SEL_ANA BIT(5) +#define B_BE_VC_RSTB_ANA BIT(4) +#define B_BE_FPWMDELAY_ANA BIT(3) +#define B_BE_ENFPWMDELAY_H_ANA BIT(2) +#define B_BE_REG_MOS_HALF_L_ANA BIT(1) +#define B_BE_CURRENT_SENSE_MOS_ANA BIT(0) + +#define R_BE_AFE_ON_CTRL0 0x0240 +#define B_BE_REG_LPF_R3_3_0_MASK GENMASK(31, 29) +#define B_BE_REG_LPF_R2_MASK GENMASK(28, 24) +#define B_BE_REG_LPF_C3_MASK GENMASK(23, 21) +#define B_BE_REG_LPF_C2_MASK GENMASK(20, 18) +#define B_BE_REG_LPF_C1_MASK GENMASK(17, 15) +#define B_BE_REG_CP_ICPX2 BIT(14) +#define B_BE_REG_CP_ICP_SEL_FAST_MASK GENMASK(13, 10) +#define B_BE_REG_CP_ICP_SEL_MASK GENMASK(9, 6) +#define B_BE_REG_IB_PI_MASK GENMASK(5, 4) +#define B_BE_REG_CK_DEBUG_BT BIT(3) +#define B_BE_EN_PC_LDO BIT(2) +#define B_BE_LDO_VSEL_MASK GENMASK(1, 0) + +#define R_BE_AFE_ON_CTRL1 0x0244 +#define B_BE_REG_CK_MON_SEL_MASK GENMASK(31, 29) +#define B_BE_REG_CK_MON_CK960M_EN BIT(28) +#define B_BE_REG_XTAL_FREQ_SEL BIT(27) +#define B_BE_REG_XTAL_EDGE_SEL BIT(26) +#define B_BE_REG_VCO_KVCO BIT(25) +#define B_BE_REG_SDM_EDGE_SEL BIT(24) +#define B_BE_REG_SDM_CK_SEL BIT(23) +#define B_BE_REG_SDM_CK_GATED BIT(22) +#define B_BE_REG_PFD_RESET_GATED BIT(21) +#define B_BE_REG_LPF_R3_FAST_MASK GENMASK(20, 16) +#define B_BE_REG_LPF_R2_FAST_MASK GENMASK(15, 11) +#define B_BE_REG_LPF_C3_FAST_MASK GENMASK(10, 8) +#define B_BE_REG_LPF_C2_FAST_MASK GENMASK(7, 5) +#define B_BE_REG_LPF_C1_FAST_MASK GENMASK(4, 2) +#define B_BE_REG_LPF_R3_4_MASK GENMASK(1, 0) + +#define R_BE_AFE_ON_CTRL3 0x024C +#define B_BE_LDO_VSEL_DA_1_MASK GENMASK(31, 30) +#define B_BE_LDO_VSEL_DA_0_MASK GENMASK(29, 28) +#define B_BE_LDO_VSEL_D2S_1_MASK GENMASK(27, 26) +#define B_BE_LDO_VSEL_D2S_0_MASK GENMASK(25, 24) +#define B_BE_LDO_VSEL_BUF_MASK GENMASK(23, 22) +#define B_BE_REG_R2_L_MASK GENMASK(21, 19) +#define B_BE_REG_R1_L_MASK GENMASK(18, 16) +#define B_BE_REG_CK_DEBUG_BT_MON BIT(15) +#define B_BE_REG_BT_CLK_BUF_POWER BIT(14) +#define B_BE_REG_BG_OUT_BTADC_V1 BIT(13) +#define B_BE_REG_SEL_V18 BIT(11) +#define B_BE_REG_FRAC_EN BIT(10) +#define B_BE_REG_CK1920M_EN BIT(9) +#define B_BE_REG_CK1280M_EN BIT(8) +#define B_BE_REG_12LDO_SEL_MASK GENMASK(7, 6) +#define B_BE_REG_09LDO_SEL_MASK GENMASK(5, 4) +#define B_BE_REG_VC_TH BIT(3) +#define B_BE_REG_VC_TL BIT(2) +#define B_BE_REG_CK40M_EN BIT(1) +#define B_BE_REG_CK640M_EN BIT(0) + +#define R_BE_GPIO8_15_FUNC_SEL 0x02D4 +#define B_BE_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4) + +#define R_BE_WLAN_XTAL_SI_CTRL 0x0270 +#define B_BE_WL_XTAL_SI_CMD_POLL BIT(31) +#define B_BE_WL_XTAL_SI_CHIPID_MASK GENMASK(30, 28) +#define B_BE_WL_XTAL_SI_MODE_MASK GENMASK(25, 24) +#define B_BE_WL_XTAL_SI_BITMASK_MASK GENMASK(23, 16) +#define B_BE_WL_XTAL_SI_DATA_MASK GENMASK(15, 8) +#define B_BE_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0) + +#define R_BE_PCIE_SER_DBG 0x02FC +#define B_BE_PCIE_SER_DBG_MASK GENMASK(31, 10) +#define B_BE_PCIE_SER_PHY_PROTECT BIT(9) +#define B_BE_PCIE_SER_MAC_PROTECT BIT(8) +#define B_BE_PCIE_SER_FLUSH_RSTB BIT(4) +#define B_BE_PCIE_AXI_BRG_FLUSH_EN BIT(3) +#define B_BE_PCIE_SER_AUXCLK_RDY BIT(2) +#define B_BE_PCIE_SER_FRZ_REG_RST BIT(1) +#define B_BE_PCIE_SER_FRZ_CFG_SPC_RST BIT(0) + +#define R_BE_IC_PWR_STATE 0x03F0 +#define B_BE_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) +#define MAC_AX_SYS_ACT 0x220 +#define B_BE_WLMAC_PWR_STE_MASK GENMASK(9, 8) +#define B_BE_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6) +#define B_BE_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4) +#define B_BE_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) +#define B_BE_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) + +#define R_BE_WLCPU_PORT_PC 0x03FC + +#define R_BE_DBG_WOW 0x0504 + +#define R_BE_DCPU_PLATFORM_ENABLE 0x0888 +#define B_BE_DCPU_SYM_DPLT_MEM_MUX_EN BIT(10) +#define B_BE_DCPU_WARM_EN BIT(9) +#define B_BE_DCPU_UART_EN BIT(7) +#define B_BE_DCPU_IDDMA_EN BIT(6) +#define B_BE_DCPU_APB_WRAP_EN BIT(2) +#define B_BE_DCPU_EN BIT(1) +#define B_BE_DCPU_PLATFORM_EN BIT(0) + +#define R_BE_PL_AXIDMA_IDCT_MSK 0x0910 +#define B_BE_PL_AXIDMA_RRESP_ERR_MASK BIT(6) +#define B_BE_PL_AXIDMA_BRESP_ERR_MASK BIT(5) +#define B_BE_PL_AXIDMA_FC_ERR_MASK BIT(4) +#define B_BE_PL_AXIDMA_TXBD_LEN0_MASK BIT(3) +#define B_BE_PL_AXIDMA_TXBD_4KBOUD_LENERR_MASK BIT(2) +#define B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK BIT(1) +#define B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK BIT(0) +#define B_BE_PL_AXIDMA_IDCT_MSK_CLR (B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK | \ + B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK | \ + B_BE_PL_AXIDMA_TXBD_LEN0_MASK | \ + B_BE_PL_AXIDMA_FC_ERR_MASK | \ + B_BE_PL_AXIDMA_BRESP_ERR_MASK | \ + B_BE_PL_AXIDMA_RRESP_ERR_MASK) +#define B_BE_PL_AXIDMA_IDCT_MSK_SET (B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK | \ + B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK | \ + B_BE_PL_AXIDMA_TXBD_LEN0_MASK | \ + B_BE_PL_AXIDMA_FC_ERR_MASK) + +#define R_BE_PL_AXIDMA_IDCT 0x0914 +#define B_BE_PL_AXIDMA_RRESP_ERR BIT(6) +#define B_BE_PL_AXIDMA_BRESP_ERR BIT(5) +#define B_BE_PL_AXIDMA_FC_ERR BIT(4) +#define B_BE_PL_AXIDMA_TXBD_LEN0 BIT(3) +#define B_BE_PL_AXIDMA_TXBD_4KBOUD_LENERR BIT(2) +#define B_BE_PL_AXIDMA_TXBD_RX_STUCK BIT(1) +#define B_BE_PL_AXIDMA_TXBD_TX_STUCK BIT(0) + +#define R_BE_FILTER_MODEL_ADDR 0x0C04 + +#define R_BE_WLAN_WDT 0x3050 +#define B_BE_WLAN_WDT_TIMEOUT BIT(31) +#define B_BE_WLAN_WDT_TIMER_CLEAR BIT(4) +#define B_BE_WLAN_WDT_BYPASS BIT(1) +#define B_BE_WLAN_WDT_ENABLE BIT(0) + +#define R_BE_AXIDMA_WDT 0x305C +#define B_BE_AXIDMA_WDT_TIMEOUT BIT(31) +#define B_BE_AXIDMA_WDT_TIMER_CLEAR BIT(4) +#define B_BE_AXIDMA_WDT_BYPASS BIT(1) +#define B_BE_AXIDMA_WDT_ENABLE BIT(0) + +#define R_BE_AON_WDT 0x3068 +#define B_BE_AON_WDT_TIMEOUT BIT(31) +#define B_BE_AON_WDT_TIMER_CLEAR BIT(4) +#define B_BE_AON_WDT_BYPASS BIT(1) +#define B_BE_AON_WDT_ENABLE BIT(0) + +#define R_BE_AON_WDT_TMR 0x306C +#define R_BE_MDIO_WDT_TMR 0x3090 +#define R_BE_LA_MODE_WDT_TMR 0x309C +#define R_BE_WDT_AR_TMR 0x3144 +#define R_BE_WDT_AW_TMR 0x3150 +#define R_BE_WLAN_WDT_TMR 0x3054 +#define R_BE_WDT_W_TMR 0x315C +#define R_BE_AXIDMA_WDT_TMR 0x3060 +#define R_BE_WDT_B_TMR 0x3164 +#define R_BE_WDT_R_TMR 0x316C +#define R_BE_LOCAL_WDT_TMR 0x3084 + +#define R_BE_LOCAL_WDT 0x3080 +#define B_BE_LOCAL_WDT_TIMEOUT BIT(31) +#define B_BE_LOCAL_WDT_TIMER_CLEAR BIT(4) +#define B_BE_LOCAL_WDT_BYPASS BIT(1) +#define B_BE_LOCAL_WDT_ENABLE BIT(0) + +#define R_BE_MDIO_WDT 0x308C +#define B_BE_MDIO_WDT_TIMEOUT BIT(31) +#define B_BE_MDIO_WDT_TIMER_CLEAR BIT(4) +#define B_BE_MDIO_WDT_BYPASS BIT(1) +#define B_BE_MDIO_WDT_ENABLE BIT(0) + +#define R_BE_LA_MODE_WDT 0x3098 +#define B_BE_LA_MODE_WDT_TIMEOUT BIT(31) +#define B_BE_LA_MODE_WDT_TIMER_CLEAR BIT(4) +#define B_BE_LA_MODE_WDT_BYPASS BIT(1) +#define B_BE_LA_MODE_WDT_ENABLE BIT(0) + +#define R_BE_WDT_AR 0x3140 +#define B_BE_WDT_AR_TIMEOUT BIT(31) +#define B_BE_WDT_AR_TIMER_CLEAR BIT(4) +#define B_BE_WDT_AR_BYPASS BIT(1) +#define B_BE_WDT_AR_ENABLE BIT(0) + +#define R_BE_WDT_AW 0x314C +#define B_BE_WDT_AW_TIMEOUT BIT(31) +#define B_BE_WDT_AW_TIMER_CLEAR BIT(4) +#define B_BE_WDT_AW_BYPASS BIT(1) +#define B_BE_WDT_AW_ENABLE BIT(0) + +#define R_BE_WDT_W 0x3158 +#define B_BE_WDT_W_TIMEOUT BIT(31) +#define B_BE_WDT_W_TIMER_CLEAR BIT(4) +#define B_BE_WDT_W_BYPASS BIT(1) +#define B_BE_WDT_W_ENABLE BIT(0) + +#define R_BE_WDT_B 0x3160 +#define B_BE_WDT_B_TIMEOUT BIT(31) +#define B_BE_WDT_B_TIMER_CLEAR BIT(4) +#define B_BE_WDT_B_BYPASS BIT(1) +#define B_BE_WDT_B_ENABLE BIT(0) + +#define R_BE_WDT_R 0x3168 +#define B_BE_WDT_R_TIMEOUT BIT(31) +#define B_BE_WDT_R_TIMER_CLEAR BIT(4) +#define B_BE_WDT_R_BYPASS BIT(1) +#define B_BE_WDT_R_ENABLE BIT(0) + +#define R_BE_LTR_DECISION_CTRL_V1 0x3610 +#define B_BE_ENABLE_LTR_CTL_DECISION BIT(31) +#define B_BE_LAT_LTR_IDX_DRV_VLD_V1 BIT(24) +#define B_BE_LAT_LTR_IDX_DRV_V1_MASK GENMASK(23, 22) +#define B_BE_LAT_LTR_IDX_FW_VLD_V1 BIT(21) +#define B_BE_LAT_LTR_IDX_FW_V1_MASK GENMASK(20, 19) +#define B_BE_LAT_LTR_IDX_HW_VLD_V1 BIT(18) +#define B_BE_LAT_LTR_IDX_HW_V1_MASK GENMASK(17, 16) +#define B_BE_LTR_IDX_DRV_V1_MASK GENMASK(15, 14) +#define B_BE_LTR_REQ_DRV_V1 BIT(13) +#define B_BE_LTR_IDX_DISABLE_V1_MASK GENMASK(9, 8) +#define B_BE_LTR_EN_PORT_V1_MASK GENMASK(6, 4) +#define B_BE_LTR_DRV_DEC_EN_V1 BIT(6) +#define B_BE_LTR_FW_DEC_EN_V1 BIT(5) +#define B_BE_LTR_HW_DEC_EN_V1 BIT(4) +#define B_BE_LTR_SPACE_IDX_MASK GENMASK(1, 0) + +#define R_BE_LTR_LATENCY_IDX0_V1 0x3614 +#define R_BE_LTR_LATENCY_IDX1_V1 0x3618 +#define R_BE_LTR_LATENCY_IDX2_V1 0x361C +#define R_BE_LTR_LATENCY_IDX3_V1 0x3620 + +#define R_BE_USB2_WLAN_TRX_OPT_PAR2 0x41BC +#define B_BE_USB2_USBRX_RST BIT(1) +#define B_BE_USB2_USBTX_RST BIT(0) + +#define R_BE_HCI_BUF_IMR 0x6018 +#define B_BE_HCI_BUF_IMR_CLR 0xC0000303 +#define B_BE_HCI_BUF_IMR_SET 0xC0000301 + +#define R_BE_H2CREG_DATA0 0x7140 +#define R_BE_H2CREG_DATA1 0x7144 +#define R_BE_H2CREG_DATA2 0x7148 +#define R_BE_H2CREG_DATA3 0x714C +#define R_BE_C2HREG_DATA0 0x7150 +#define R_BE_C2HREG_DATA1 0x7154 +#define R_BE_C2HREG_DATA2 0x7158 +#define R_BE_C2HREG_DATA3 0x715C +#define R_BE_H2CREG_CTRL 0x7160 +#define B_BE_H2CREG_TRIGGER BIT(0) +#define R_BE_C2HREG_CTRL 0x7164 +#define B_BE_C2HREG_TRIGGER BIT(0) + +#define R_BE_HCI_FUNC_EN 0x7880 +#define B_BE_HCI_CR_PROTECT BIT(31) +#define B_BE_HCI_TRXBUF_EN BIT(2) +#define B_BE_HCI_RXDMA_EN BIT(1) +#define B_BE_HCI_TXDMA_EN BIT(0) + +#define R_BE_BOOT_DBG 0x78F0 +#define B_BE_BOOT_STATUS_MASK GENMASK(31, 16) +#define B_BE_SECUREBOOT_STATUS_MASK GENMASK(15, 0) + +#define R_BE_DBG_WOW_READY 0x815E +#define B_BE_DBG_WOW_READY GENMASK(7, 0) + +#define R_BE_DMAC_FUNC_EN 0x8400 +#define B_BE_DMAC_CRPRT BIT(31) +#define B_BE_MAC_FUNC_EN BIT(30) +#define B_BE_DMAC_FUNC_EN BIT(29) +#define B_BE_MPDU_PROC_EN BIT(28) +#define B_BE_WD_RLS_EN BIT(27) +#define B_BE_DLE_WDE_EN BIT(26) +#define B_BE_TXPKT_CTRL_EN BIT(25) +#define B_BE_STA_SCH_EN BIT(24) +#define B_BE_DLE_PLE_EN BIT(23) +#define B_BE_PKT_BUF_EN BIT(22) +#define B_BE_DMAC_TBL_EN BIT(21) +#define B_BE_PKT_IN_EN BIT(20) +#define B_BE_DLE_CPUIO_EN BIT(19) +#define B_BE_DISPATCHER_EN BIT(18) +#define B_BE_BBRPT_EN BIT(17) +#define B_BE_MAC_SEC_EN BIT(16) +#define B_BE_DMACREG_GCKEN BIT(15) +#define B_BE_H_AXIDMA_EN BIT(14) +#define B_BE_DMAC_MLO_EN BIT(11) +#define B_BE_PLRLS_EN BIT(10) +#define B_BE_P_AXIDMA_EN BIT(9) +#define B_BE_DLE_DATACPUIO_EN BIT(8) +#define B_BE_LTR_CTL_EN BIT(7) + +#define R_BE_DMAC_CLK_EN 0x8404 +#define B_BE_MAC_CKEN BIT(30) +#define B_BE_DMAC_CKEN BIT(29) +#define B_BE_MPDU_CKEN BIT(28) +#define B_BE_WD_RLS_CLK_EN BIT(27) +#define B_BE_DLE_WDE_CLK_EN BIT(26) +#define B_BE_TXPKT_CTRL_CLK_EN BIT(25) +#define B_BE_STA_SCH_CLK_EN BIT(24) +#define B_BE_DLE_PLE_CLK_EN BIT(23) +#define B_BE_PKTBUF_CKEN BIT(22) +#define B_BE_DMAC_TABLE_CLK_EN BIT(21) +#define B_BE_PKT_IN_CLK_EN BIT(20) +#define B_BE_DLE_CPUIO_CLK_EN BIT(19) +#define B_BE_DISPATCHER_CLK_EN BIT(18) +#define B_BE_BBRPT_CLK_EN BIT(17) +#define B_BE_MAC_SEC_CLK_EN BIT(16) +#define B_BE_H_AXIDMA_CKEN BIT(14) +#define B_BE_DMAC_MLO_CKEN BIT(11) +#define B_BE_PLRLS_CKEN BIT(10) +#define B_BE_P_AXIDMA_CKEN BIT(9) +#define B_BE_DLE_DATACPUIO_CKEN BIT(8) + +#define R_BE_LTR_CTRL_0 0x8410 +#define B_BE_LTR_REQ_FW BIT(18) +#define B_BE_LTR_IDX_FW_MASK GENMASK(17, 16) +#define B_BE_LTR_IDLE_TIMER_IDX_MASK GENMASK(10, 8) +#define B_BE_LTR_WD_NOEMP_CHK BIT(1) +#define B_BE_LTR_HW_EN BIT(0) + +#define R_BE_LTR_CFG_0 0x8414 +#define B_BE_LTR_IDX_DISABLE_MASK GENMASK(17, 16) +#define B_BE_LTR_IDX_IDLE_MASK GENMASK(15, 14) +#define B_BE_LTR_IDX_ACTIVE_MASK GENMASK(13, 12) +#define B_BE_LTR_IDLE_TIMER_IDX_MASK GENMASK(10, 8) +#define B_BE_EN_LTR_CMAC_RX_USE_PG_CHK BIT(3) +#define B_BE_EN_LTR_WD_NON_EMPTY_CHK BIT(2) +#define B_BE_EN_LTR_HAXIDMA_TX_IDLE_CHK BIT(1) +#define B_BE_EN_LTR_HAXIDMA_RX_IDLE_CHK BIT(0) + +#define R_BE_LTR_CFG_1 0x8418 +#define B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK GENMASK(27, 16) +#define B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK GENMASK(11, 0) + +#define R_BE_NO_RX_ERR_CFG 0x841C +#define B_BE_NO_RX_ERR_TO_MASK GENMASK(31, 29) + +#define R_BE_DMAC_TABLE_CTRL 0x8420 +#define B_BE_HWAMSDU_PADDING_MODE BIT(31) +#define B_BE_MACID_MPDU_PROCESSOR_OFFSET_MASK GENMASK(26, 16) +#define B_BE_DMAC_ADDR_MODE BIT(12) +#define B_BE_DMAC_CTRL_INFO_SER_IO BIT(11) +#define B_BE_DMAC_CTRL_INFO_OFFSET_MASK GENMASK(10, 0) + +#define R_BE_SER_DBG_INFO 0x8424 +#define B_BE_SER_L0_PROMOTE_L1_EVENT_MASK GENMASK(31, 28) +#define B_BE_SER_L1_COUNTER_MASK GENMASK(27, 24) +#define B_BE_RMAC_PPDU_HANG_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L0_COUNTER_MASK GENMASK(7, 0) + +#define R_BE_DMAC_SYS_CR32B 0x842C +#define B_BE_DMAC_BB_PHY1_MASK GENMASK(31, 16) +#define B_BE_DMAC_BB_PHY0_MASK GENMASK(15, 0) +#define B_BE_DMAC_BB_CTRL_39 BIT(31) +#define B_BE_DMAC_BB_CTRL_38 BIT(30) +#define B_BE_DMAC_BB_CTRL_37 BIT(29) +#define B_BE_DMAC_BB_CTRL_36 BIT(28) +#define B_BE_DMAC_BB_CTRL_35 BIT(27) +#define B_BE_DMAC_BB_CTRL_34 BIT(26) +#define B_BE_DMAC_BB_CTRL_33 BIT(25) +#define B_BE_DMAC_BB_CTRL_32 BIT(24) +#define B_BE_DMAC_BB_CTRL_31 BIT(23) +#define B_BE_DMAC_BB_CTRL_30 BIT(22) +#define B_BE_DMAC_BB_CTRL_29 BIT(21) +#define B_BE_DMAC_BB_CTRL_28 BIT(20) +#define B_BE_DMAC_BB_CTRL_27 BIT(19) +#define B_BE_DMAC_BB_CTRL_26 BIT(18) +#define B_BE_DMAC_BB_CTRL_25 BIT(17) +#define B_BE_DMAC_BB_CTRL_24 BIT(16) +#define B_BE_DMAC_BB_CTRL_23 BIT(15) +#define B_BE_DMAC_BB_CTRL_22 BIT(14) +#define B_BE_DMAC_BB_CTRL_21 BIT(13) +#define B_BE_DMAC_BB_CTRL_20 BIT(12) +#define B_BE_DMAC_BB_CTRL_19 BIT(11) +#define B_BE_DMAC_BB_CTRL_18 BIT(10) +#define B_BE_DMAC_BB_CTRL_17 BIT(9) +#define B_BE_DMAC_BB_CTRL_16 BIT(8) +#define B_BE_DMAC_BB_CTRL_15 BIT(7) +#define B_BE_DMAC_BB_CTRL_14 BIT(6) +#define B_BE_DMAC_BB_CTRL_13 BIT(5) +#define B_BE_DMAC_BB_CTRL_12 BIT(4) +#define B_BE_DMAC_BB_CTRL_11 BIT(3) +#define B_BE_DMAC_BB_CTRL_10 BIT(2) +#define B_BE_DMAC_BB_CTRL_9 BIT(1) +#define B_BE_DMAC_BB_CTRL_8 BIT(0) + +#define R_BE_DLE_EMPTY0 0x8430 +#define B_BE_PLE_EMPTY_QTA_DMAC_H2D BIT(27) +#define B_BE_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26) +#define B_BE_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25) +#define B_BE_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24) +#define B_BE_PLE_EMPTY_QTA_DMAC_H2C BIT(23) +#define B_BE_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22) +#define B_BE_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21) +#define B_BE_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20) +#define B_BE_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19) +#define B_BE_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18) +#define B_BE_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17) +#define B_BE_WDE_EMPTY_QTA_DMAC_HIF BIT(16) +#define B_BE_WDE_EMPTY_QUE_CMAC_B1_HIQ BIT(15) +#define B_BE_WDE_EMPTY_QUE_CMAC_B1_MBH BIT(14) +#define B_BE_WDE_EMPTY_QUE_CMAC_B0_OTHERS BIT(13) +#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_ACQ BIT(12) +#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_MISC BIT(11) +#define B_BE_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10) +#define B_BE_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9) +#define B_BE_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8) +#define B_BE_WDE_EMPTY_QUE_OTHERS BIT(7) +#define B_BE_WDE_EMPTY_QUE_CMAC_WMM3 BIT(6) +#define B_BE_WDE_EMPTY_QUE_CMAC_WMM2 BIT(5) +#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4) +#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3) +#define B_BE_WDE_EMPTY_QUE_CMAC1_MBH BIT(2) +#define B_BE_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) +#define B_BE_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) + +#define R_BE_DLE_EMPTY1 0x8434 +#define B_BE_PLE_EMPTY_QTA_CMAC_DMA_TXRPT BIT(21) +#define B_BE_PLE_EMPTY_QTA_DMAC_WDRLS BIT(20) +#define B_BE_PLE_EMPTY_QTA_CMAC1_DMA_BBRPT BIT(19) +#define B_BE_PLE_EMPTY_QTA_CMAC1_DMA_RX BIT(18) +#define B_BE_PLE_EMPTY_QTA_CMAC0_DMA_RX BIT(17) +#define B_BE_PLE_EMPTY_QTA_DMAC_C2H BIT(16) +#define B_BE_PLE_EMPTY_QUE_DMAC_PLRLS BIT(5) +#define B_BE_PLE_EMPTY_QUE_DMAC_CPUIO BIT(4) +#define B_BE_PLE_EMPTY_QUE_DMAC_SEC_RX BIT(3) +#define B_BE_PLE_EMPTY_QUE_DMAC_MPDU_RX BIT(2) +#define B_BE_PLE_EMPTY_QUE_DMAC_HDP BIT(1) +#define B_BE_WDE_EMPTY_QUE_DMAC_WDRLS BIT(0) + +#define R_BE_SER_L1_DBG_CNT_0 0x8440 +#define B_BE_SER_L1_WDRLS_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L1_SEC_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L1_MPDU_CNT_MASK GENMASK(15, 8) +#define B_BE_SER_L1_STA_SCH_CNT_MASK GENMASK(7, 0) + +#define R_BE_SER_L1_DBG_CNT_1 0x8444 +#define B_BE_SER_L1_WDE_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L1_TXPKTCTRL_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L1_PLE_CNT_MASK GENMASK(15, 8) +#define B_BE_SER_L1_PKTIN_CNT_MASK GENMASK(7, 0) + +#define R_BE_SER_L1_DBG_CNT_2 0x8448 +#define B_BE_SER_L1_DISP_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L1_APB_BRIDGE_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L1_DLE_W_CPUIO_CNT_MASK GENMASK(15, 8) +#define B_BE_SER_L1_BBRPT_CNT_MASK GENMASK(7, 0) + +#define R_BE_SER_L1_DBG_CNT_3 0x844C +#define B_BE_SER_L1_HCI_BUF_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L1_P_AXIDMA_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L1_H_AXIDMA_CNT_MASK GENMASK(15, 8) +#define B_BE_SER_L1_MLO_ERR_CNT_MASK GENMASK(7, 0) + +#define R_BE_SER_L1_DBG_CNT_4 0x8450 +#define B_BE_SER_L1_PLDRLS_ERR_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L1_DLE_D_CPUIO_CNT_MASK GENMASK(23, 16) + +#define R_BE_SER_L1_DBG_CNT_5 0x8454 +#define B_BE_SER_L1_DBG_0_MASK GENMASK(31, 0) + +#define R_BE_SER_L1_DBG_CNT_6 0x8458 +#define B_BE_SER_L1_DBG_1_MASK GENMASK(31, 0) + +#define R_BE_SER_L1_DBG_CNT_7 0x845C +#define B_BE_SER_L1_DBG_2_MASK GENMASK(31, 0) + +#define R_BE_FW_TRIGGER_IDCT_ISR 0x8508 +#define B_BE_DMAC_FW_ERR_IDCT_IMR BIT(31) +#define B_BE_DMAC_FW_TRIG_IDCT BIT(0) + +#define R_BE_DMAC_ERR_IMR 0x8520 +#define B_BE_DMAC_NOTX_ERR_INT_EN BIT(21) +#define B_BE_DMAC_NORX_ERR_INT_EN BIT(20) +#define B_BE_DLE_DATACPUIO_ERR_INT_EN BIT(19) +#define B_BE_PLRSL_ERR_INT_EN BIT(18) +#define B_BE_MLO_ERR_INT_EN BIT(17) +#define B_BE_DMAC_FW_ERR_INT_EN BIT(16) +#define B_BE_H_AXIDMA_ERR_INT_EN BIT(14) +#define B_BE_P_AXIDMA_ERR_INT_EN BIT(13) +#define B_BE_HCI_BUF_ERR_INT_EN BIT(12) +#define B_BE_BBRPT_ERR_INT_EN BIT(11) +#define B_BE_DLE_CPUIO_ERR_INT_EN BIT(10) +#define B_BE_APB_BRIDGE_ERR_INT_EN BIT(9) +#define B_BE_DISPATCH_ERR_INT_EN BIT(8) +#define B_BE_PKTIN_ERR_INT_EN BIT(7) +#define B_BE_PLE_DLE_ERR_INT_EN BIT(6) +#define B_BE_TXPKTCTRL_ERR_INT_EN BIT(5) +#define B_BE_WDE_DLE_ERR_INT_EN BIT(4) +#define B_BE_STA_SCHEDULER_ERR_INT_EN BIT(3) +#define B_BE_MPDU_ERR_INT_EN BIT(2) +#define B_BE_WSEC_ERR_INT_EN BIT(1) +#define B_BE_WDRLS_ERR_INT_EN BIT(0) + +#define R_BE_DMAC_ERR_ISR 0x8524 +#define B_BE_DLE_DATACPUIO_ERR_INT BIT(19) +#define B_BE_PLRLS_ERR_INT BIT(18) +#define B_BE_MLO_ERR_INT BIT(17) +#define B_BE_DMAC_FW_ERR_IDCT BIT(16) +#define B_BE_H_AXIDMA_ERR_INT BIT(14) +#define B_BE_P_AXIDMA_ERR_INT BIT(13) +#define B_BE_HCI_BUF_ERR_FLAG BIT(12) +#define B_BE_BBRPT_ERR_FLAG BIT(11) +#define B_BE_DLE_CPUIO_ERR_FLAG BIT(10) +#define B_BE_APB_BRIDGE_ERR_FLAG BIT(9) +#define B_BE_DISPATCH_ERR_FLAG BIT(8) +#define B_BE_PKTIN_ERR_FLAG BIT(7) +#define B_BE_PLE_DLE_ERR_FLAG BIT(6) +#define B_BE_TXPKTCTRL_ERR_FLAG BIT(5) +#define B_BE_WDE_DLE_ERR_FLAG BIT(4) +#define B_BE_STA_SCHEDULER_ERR_FLAG BIT(3) +#define B_BE_MPDU_ERR_FLAG BIT(2) +#define B_BE_WSEC_ERR_FLAG BIT(1) +#define B_BE_WDRLS_ERR_FLAG BIT(0) + +#define R_BE_DISP_ERROR_ISR0 0x8804 +#define B_BE_REUSE_SIZE_ERR BIT(31) +#define B_BE_REUSE_EN_ERR BIT(30) +#define B_BE_STF_OQT_UNDERFLOW_ERR BIT(29) +#define B_BE_STF_OQT_OVERFLOW_ERR BIT(28) +#define B_BE_STF_WRFF_UNDERFLOW_ERR BIT(27) +#define B_BE_STF_WRFF_OVERFLOW_ERR BIT(26) +#define B_BE_STF_CMD_UNDERFLOW_ERR BIT(25) +#define B_BE_STF_CMD_OVERFLOW_ERR BIT(24) +#define B_BE_REUSE_SIZE_ZERO_ERR BIT(23) +#define B_BE_REUSE_PKT_CNT_ERR BIT(22) +#define B_BE_CDT_PTR_TIMEOUT_ERR BIT(21) +#define B_BE_CDT_HCI_TIMEOUT_ERR BIT(20) +#define B_BE_HDT_PTR_TIMEOUT_ERR BIT(19) +#define B_BE_HDT_HCI_TIMEOUT_ERR BIT(18) +#define B_BE_CDT_ADDR_INFO_LEN_ERR BIT(17) +#define B_BE_HDT_ADDR_INFO_LEN_ERR BIT(16) +#define B_BE_CDR_DMA_TIMEOUT_ERR BIT(15) +#define B_BE_CDR_RX_TIMEOUT_ERR BIT(14) +#define B_BE_PLE_OUTPUT_ERR BIT(12) +#define B_BE_PLE_RESPOSE_ERR BIT(11) +#define B_BE_PLE_BURST_NUM_ERR BIT(10) +#define B_BE_PLE_NULL_PKT_ERR BIT(9) +#define B_BE_PLE_FLOW_CTRL_ERR BIT(8) +#define B_BE_HDR_DMA_TIMEOUT_ERR BIT(7) +#define B_BE_HDR_RX_TIMEOUT_ERR BIT(6) +#define B_BE_WDE_OUTPUT_ERR BIT(4) +#define B_BE_WDE_RESPONSE_ERR BIT(3) +#define B_BE_WDE_BURST_NUM_ERR BIT(2) +#define B_BE_WDE_NULL_PKT_ERR BIT(1) +#define B_BE_WDE_FLOW_CTRL_ERR BIT(0) + +#define R_BE_DISP_ERROR_ISR1 0x8808 +#define B_BE_HR_WRFF_UNDERFLOW_ERR BIT(31) +#define B_BE_HR_WRFF_OVERFLOW_ERR BIT(30) +#define B_BE_HR_CHKSUM_FSM_ERR BIT(29) +#define B_BE_HR_SHIFT_DMA_CFG_ERR BIT(28) +#define B_BE_HR_DMA_PROCESS_ERR BIT(27) +#define B_BE_HR_TOTAL_LEN_UNDER_ERR BIT(26) +#define B_BE_HR_SHIFT_EN_ERR BIT(25) +#define B_BE_HR_AGG_CFG_ERR BIT(24) +#define B_BE_HR_PLD_LEN_ZERO_ERR BIT(22) +#define B_BE_HT_ILL_CH_ERR BIT(20) +#define B_BE_HT_ADDR_INFO_LEN_ERR BIT(18) +#define B_BE_HT_WD_LEN_OVER_ERR BIT(17) +#define B_BE_HT_PLD_CMD_UNDERFLOW_ERR BIT(16) +#define B_BE_HT_PLD_CMD_OVERFLOW_ERR BIT(15) +#define B_BE_HT_WRFF_UNDERFLOW_ERR BIT(14) +#define B_BE_HT_WRFF_OVERFLOW_ERR BIT(13) +#define B_BE_HT_CHKSUM_FSM_ERR BIT(12) +#define B_BE_HT_NON_IDLE_PKT_STR_ERR BIT(11) +#define B_BE_HT_PRE_SUB_BE_ERR BIT(10) +#define B_BE_HT_WD_CHKSUM_ERR BIT(9) +#define B_BE_HT_CHANNEL_DMA_ERR BIT(8) +#define B_BE_HT_OFFSET_UNMATCH_ERR BIT(7) +#define B_BE_HT_PAYLOAD_UNDER_ERR BIT(6) +#define B_BE_HT_PAYLOAD_OVER_ERR BIT(5) +#define B_BE_HT_PERMU_FF_UNDERFLOW_ERR BIT(4) +#define B_BE_HT_PERMU_FF_OVERFLOW_ERR BIT(3) +#define B_BE_HT_PKT_FAIL_ERR BIT(2) +#define B_BE_HT_CH_ID_ERR BIT(1) +#define B_BE_HT_EP_CH_DIFF_ERR BIT(0) + +#define R_BE_DISP_ERROR_ISR2 0x880C +#define B_BE_CR_PLD_LEN_ERR BIT(30) +#define B_BE_CR_WRFF_UNDERFLOW_ERR BIT(29) +#define B_BE_CR_WRFF_OVERFLOW_ERR BIT(28) +#define B_BE_CR_SHIFT_DMA_CFG_ERR BIT(27) +#define B_BE_CR_DMA_PROCESS_ERR BIT(26) +#define B_BE_CR_SHIFT_EN_ERR BIT(24) +#define B_BE_REUSE_FIFO_B_UNDER_ERR BIT(22) +#define B_BE_REUSE_FIFO_B_OVER_ERR BIT(21) +#define B_BE_REUSE_FIFO_A_UNDER_ERR BIT(20) +#define B_BE_REUSE_FIFO_A_OVER_ERR BIT(19) +#define B_BE_CT_ADDR_INFO_LEN_MISS_ERR BIT(17) +#define B_BE_CT_WD_LEN_OVER_ERR BIT(16) +#define B_BE_CT_F2P_SEQ_ERR BIT(15) +#define B_BE_CT_F2P_QSEL_ERR BIT(14) +#define B_BE_CT_PLD_CMD_UNDERFLOW_ERR BIT(13) +#define B_BE_CT_PLD_CMD_OVERFLOW_ERR BIT(12) +#define B_BE_CT_PRE_SUB_ERR BIT(11) +#define B_BE_CT_WD_CHKSUM_ERR BIT(10) +#define B_BE_CT_CHANNEL_DMA_ERR BIT(9) +#define B_BE_CT_OFFSET_UNMATCH_ERR BIT(8) +#define B_BE_F2P_TOTAL_NUM_ERR BIT(7) +#define B_BE_CT_PAYLOAD_UNDER_ERR BIT(6) +#define B_BE_CT_PAYLOAD_OVER_ERR BIT(5) +#define B_BE_CT_PERMU_FF_UNDERFLOW_ERR BIT(4) +#define B_BE_CT_PERMU_FF_OVERFLOW_ERR BIT(3) +#define B_BE_CT_CH_ID_ERR BIT(2) +#define B_BE_CT_EP_CH_DIFF_ERR BIT(0) + +#define R_BE_DISP_OTHER_IMR 0x8870 +#define B_BE_REUSE_SIZE_ERR_INT_EN BIT(31) +#define B_BE_REUSE_EN_ERR_INT_EN BIT(30) +#define B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_BE_STF_OQT_OVERFLOW_ERR_INT_EN BIT(28) +#define B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN BIT(27) +#define B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN BIT(26) +#define B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN BIT(25) +#define B_BE_STF_CMD_OVERFLOW_ERR_INT_EN BIT(24) +#define B_BE_REUSE_SIZE_ZERO_ERR_INT_EN BIT(23) +#define B_BE_REUSE_PKT_CNT_ERR_INT_EN BIT(22) +#define B_BE_CDT_PTR_TIMEOUT_ERR_INT_EN BIT(21) +#define B_BE_CDT_HCI_TIMEOUT_ERR_INT_EN BIT(20) +#define B_BE_HDT_PTR_TIMEOUT_ERR_INT_EN BIT(19) +#define B_BE_HDT_HCI_TIMEOUT_ERR_INT_EN BIT(18) +#define B_BE_CDT_ADDR_INFO_LEN_ERR_INT_EN BIT(17) +#define B_BE_HDT_ADDR_INFO_LEN_ERR_INT_EN BIT(16) +#define B_BE_CDR_DMA_TIMEOUT_ERR_INT_EN BIT(15) +#define B_BE_CDR_RX_TIMEOUT_ERR_INT_EN BIT(14) +#define B_BE_PLE_OUTPUT_ERR_INT_EN BIT(12) +#define B_BE_PLE_RESPOSE_ERR_INT_EN BIT(11) +#define B_BE_PLE_BURST_NUM_ERR_INT_EN BIT(10) +#define B_BE_PLE_NULL_PKT_ERR_INT_EN BIT(9) +#define B_BE_PLE_FLOW_CTRL_ERR_INT_EN BIT(8) +#define B_BE_HDR_DMA_TIMEOUT_ERR_INT_EN BIT(7) +#define B_BE_HDR_RX_TIMEOUT_ERR_INT_EN BIT(6) +#define B_BE_WDE_OUTPUT_ERR_INT_EN BIT(4) +#define B_BE_WDE_RESPONSE_ERR_INT_EN BIT(3) +#define B_BE_WDE_BURST_NUM_ERR_INT_EN BIT(2) +#define B_BE_WDE_NULL_PKT_ERR_INT_EN BIT(1) +#define B_BE_WDE_FLOW_CTRL_ERR_INT_EN BIT(0) +#define B_BE_DISP_OTHER_IMR_CLR (B_BE_WDE_FLOW_CTRL_ERR_INT_EN | \ + B_BE_WDE_NULL_PKT_ERR_INT_EN | \ + B_BE_WDE_BURST_NUM_ERR_INT_EN | \ + B_BE_WDE_RESPONSE_ERR_INT_EN | \ + B_BE_WDE_OUTPUT_ERR_INT_EN | \ + B_BE_HDR_RX_TIMEOUT_ERR_INT_EN | \ + B_BE_HDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_BE_PLE_FLOW_CTRL_ERR_INT_EN | \ + B_BE_PLE_NULL_PKT_ERR_INT_EN | \ + B_BE_PLE_BURST_NUM_ERR_INT_EN | \ + B_BE_PLE_RESPOSE_ERR_INT_EN | \ + B_BE_PLE_OUTPUT_ERR_INT_EN | \ + B_BE_CDR_RX_TIMEOUT_ERR_INT_EN | \ + B_BE_CDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_BE_HDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_BE_CDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_BE_HDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_BE_HDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_BE_CDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_BE_CDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_BE_REUSE_PKT_CNT_ERR_INT_EN | \ + B_BE_REUSE_SIZE_ZERO_ERR_INT_EN | \ + B_BE_STF_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_BE_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN | \ + B_BE_REUSE_EN_ERR_INT_EN | \ + B_BE_REUSE_SIZE_ERR_INT_EN) +#define B_BE_DISP_OTHER_IMR_SET (B_BE_STF_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_BE_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_OTHER_IMR_CLR_V1 0xFFFFFFFF +#define B_BE_DISP_OTHER_IMR_SET_V1 0x3F002000 + +#define R_BE_DISP_HOST_IMR 0x8874 +#define B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31) +#define B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN BIT(30) +#define B_BE_HR_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_BE_HR_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_BE_HR_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(26) +#define B_BE_HR_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_BE_HR_AGG_CFG_ERR_INT_EN BIT(24) +#define B_BE_HR_PLD_LEN_ZERO_ERR_INT_EN BIT(22) +#define B_BE_HT_ILL_CH_ERR_INT_EN BIT(20) +#define B_BE_HT_ADDR_INFO_LEN_ERR_INT_EN BIT(18) +#define B_BE_HT_WD_LEN_OVER_ERR_INT_EN BIT(17) +#define B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(16) +#define B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(15) +#define B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN BIT(14) +#define B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN BIT(13) +#define B_BE_HT_CHKSUM_FSM_ERR_INT_EN BIT(12) +#define B_BE_HT_NON_IDLE_PKT_STR_ERR_EN BIT(11) +#define B_BE_HT_PRE_SUB_ERR_INT_EN BIT(10) +#define B_BE_HT_WD_CHKSUM_ERR_INT_EN BIT(9) +#define B_BE_HT_CHANNEL_DMA_ERR_INT_EN BIT(8) +#define B_BE_HT_OFFSET_UNMATCH_ERR_INT_EN BIT(7) +#define B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_BE_HT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_BE_HT_PKT_FAIL_ERR_INT_EN BIT(2) +#define B_BE_HT_CH_ID_ERR_INT_EN BIT(1) +#define B_BE_HT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_BE_DISP_HOST_IMR_CLR (B_BE_HT_EP_CH_DIFF_ERR_INT_EN | \ + B_BE_HT_CH_ID_ERR_INT_EN | \ + B_BE_HT_PKT_FAIL_ERR_INT_EN | \ + B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_BE_HT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_BE_HT_CHANNEL_DMA_ERR_INT_EN | \ + B_BE_HT_WD_CHKSUM_ERR_INT_EN | \ + B_BE_HT_PRE_SUB_ERR_INT_EN | \ + B_BE_HT_NON_IDLE_PKT_STR_ERR_EN | \ + B_BE_HT_CHKSUM_FSM_ERR_INT_EN | \ + B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_WD_LEN_OVER_ERR_INT_EN | \ + B_BE_HT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_BE_HT_ILL_CH_ERR_INT_EN | \ + B_BE_HR_PLD_LEN_ZERO_ERR_INT_EN | \ + B_BE_HR_AGG_CFG_ERR_INT_EN | \ + B_BE_HR_SHIFT_EN_ERR_INT_EN | \ + B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_BE_HR_DMA_PROCESS_ERR_INT_EN | \ + B_BE_HR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_BE_HR_CHKSUM_FSM_ERR_INT_EN | \ + B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_HOST_IMR_SET (B_BE_HT_EP_CH_DIFF_ERR_INT_EN | \ + B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_BE_HT_CHANNEL_DMA_ERR_INT_EN | \ + B_BE_HT_PRE_SUB_ERR_INT_EN | \ + B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_HT_WD_LEN_OVER_ERR_INT_EN | \ + B_BE_HT_ILL_CH_ERR_INT_EN | \ + B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_BE_HR_DMA_PROCESS_ERR_INT_EN | \ + B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_HOST_IMR_CLR_V1 0xFBFFFFFF +#define B_BE_DISP_HOST_IMR_SET_V1 0xC8B3E579 + +#define R_BE_DISP_CPU_IMR 0x8878 +#define B_BE_CR_PLD_LEN_ERR_INT_EN BIT(30) +#define B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN BIT(28) +#define B_BE_CR_SHIFT_DMA_CFG_ERR_INT_EN BIT(27) +#define B_BE_CR_DMA_PROCESS_ERR_INT_EN BIT(26) +#define B_BE_CR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(25) +#define B_BE_CR_SHIFT_EN_ERR_INT_EN BIT(24) +#define B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN BIT(22) +#define B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN BIT(21) +#define B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN BIT(20) +#define B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN BIT(19) +#define B_BE_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN BIT(17) +#define B_BE_CT_WD_LEN_OVER_ERR_INT_EN BIT(16) +#define B_BE_CT_F2P_SEQ_ERR_INT_EN BIT(15) +#define B_BE_CT_F2P_QSEL_ERR_INT_EN BIT(14) +#define B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(13) +#define B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(12) +#define B_BE_CT_PRE_SUB_ERR_INT_EN BIT(11) +#define B_BE_CT_WD_CHKSUM_ERR_INT_EN BIT(10) +#define B_BE_CT_CHANNEL_DMA_ERR_INT_EN BIT(9) +#define B_BE_CT_OFFSET_UNMATCH_ERR_INT_EN BIT(8) +#define B_BE_CT_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7) +#define B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_BE_CT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_BE_CT_CH_ID_ERR_INT_EN BIT(2) +#define B_BE_CT_PKT_FAIL_ERR_INT_EN BIT(1) +#define B_BE_CT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_BE_DISP_CPU_IMR_CLR (B_BE_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_BE_CT_CH_ID_ERR_INT_EN | \ + B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_BE_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_BE_CT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_BE_CT_CHANNEL_DMA_ERR_INT_EN | \ + B_BE_CT_WD_CHKSUM_ERR_INT_EN | \ + B_BE_CT_PRE_SUB_ERR_INT_EN | \ + B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_CT_F2P_QSEL_ERR_INT_EN | \ + B_BE_CT_F2P_SEQ_ERR_INT_EN | \ + B_BE_CT_WD_LEN_OVER_ERR_INT_EN | \ + B_BE_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN | \ + B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN | \ + B_BE_CR_SHIFT_EN_ERR_INT_EN | \ + B_BE_CR_DMA_PROCESS_ERR_INT_EN | \ + B_BE_CR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_BE_CR_PLD_LEN_ERR_INT_EN) +#define B_BE_DISP_CPU_IMR_SET (B_BE_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_BE_CT_CH_ID_ERR_INT_EN | \ + B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_BE_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_BE_CT_PRE_SUB_ERR_INT_EN | \ + B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_BE_CT_WD_LEN_OVER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN | \ + B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN | \ + B_BE_CR_DMA_PROCESS_ERR_INT_EN | \ + B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_CPU_IMR_CLR_V1 0x7DFFFFFD +#define B_BE_DISP_CPU_IMR_SET_V1 0x34F938FD + +#define R_BE_RX_STOP 0x8914 +#define B_BE_CPU_RX_STOP BIT(17) +#define B_BE_HOST_RX_STOP BIT(16) +#define B_BE_CPU_RX_CH_STOP_MSK GENMASK(15, 8) +#define B_BE_HOST_RX_CH_STOP_MSK GENMASK(5, 0) + +#define R_BE_DISP_FWD_WLAN_0 0x8938 +#define B_BE_FWD_WLAN_CPU_TYPE_13_MASK GENMASK(31, 30) +#define B_BE_FWD_WLAN_CPU_TYPE_12_MASK GENMASK(29, 28) +#define B_BE_FWD_WLAN_CPU_TYPE_11_MASK GENMASK(27, 26) +#define B_BE_FWD_WLAN_CPU_TYPE_10_MASK GENMASK(25, 24) +#define B_BE_FWD_WLAN_CPU_TYPE_9_MASK GENMASK(23, 22) +#define B_BE_FWD_WLAN_CPU_TYPE_8_MASK GENMASK(21, 20) +#define B_BE_FWD_WLAN_CPU_TYPE_7_MASK GENMASK(19, 18) +#define B_BE_FWD_WLAN_CPU_TYPE_6_MASK GENMASK(17, 16) +#define B_BE_FWD_WLAN_CPU_TYPE_5_MASK GENMASK(15, 14) +#define B_BE_FWD_WLAN_CPU_TYPE_4_MASK GENMASK(13, 12) +#define B_BE_FWD_WLAN_CPU_TYPE_3_MASK GENMASK(11, 10) +#define B_BE_FWD_WLAN_CPU_TYPE_2_MASK GENMASK(9, 8) +#define B_BE_FWD_WLAN_CPU_TYPE_1_MASK GENMASK(7, 6) +#define B_BE_FWD_WLAN_CPU_TYPE_0_CTL_MASK GENMASK(5, 4) +#define B_BE_FWD_WLAN_CPU_TYPE_0_MNG_MASK GENMASK(3, 2) +#define B_BE_FWD_WLAN_CPU_TYPE_0_DATA_MASK GENMASK(1, 0) + +#define R_BE_WDE_PKTBUF_CFG 0x8C08 +#define B_BE_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16) +#define B_BE_WDE_START_BOUND_MASK GENMASK(14, 8) +#define B_BE_WDE_PAGE_SEL_MASK GENMASK(1, 0) + +#define R_BE_WDE_BUFMGN_CTL 0x8C10 +#define B_BE_WDE_AVAL_UPD_REQ BIT(29) +#define B_BE_WDE_AVAL_UPD_QTAID_MASK GENMASK(27, 24) +#define B_BE_WDE_BUFMGN_FRZTMR_MODE BIT(0) + +#define R_BE_WDE_ERR_IMR 0x8C38 +#define B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_BE_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_BE_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(23) +#define B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(22) +#define B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(21) +#define B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(20) +#define B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(19) +#define B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(18) +#define B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN BIT(17) +#define B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN BIT(16) +#define B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN BIT(13) +#define B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN BIT(12) +#define B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN BIT(11) +#define B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN BIT(10) +#define B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN BIT(9) +#define B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN BIT(8) +#define B_BE_WDE_GETNPG_STRPG_ERR_INT_EN BIT(7) +#define B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(6) +#define B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN BIT(5) +#define B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(4) +#define B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN BIT(3) +#define B_BE_WDE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_BE_WDE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_BE_WDE_ERR_IMR_CLR (B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_BE_WDE_BUFREQ_SIZE0_INT_EN | \ + B_BE_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_BE_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \ + B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_BE_WDE_ERR_IMR_SET (B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_BE_WDE_BUFREQ_SIZE0_INT_EN | \ + B_BE_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_BE_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN | \ + B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \ + B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_BE_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN) + +#define R_BE_WDE_QTA0_CFG 0x8C40 +#define B_BE_WDE_Q0_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_WDE_Q0_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_WDE_QTA1_CFG 0x8C44 +#define B_BE_WDE_Q1_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_WDE_Q1_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_WDE_QTA2_CFG 0x8C48 +#define B_BE_WDE_Q2_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_WDE_Q2_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_WDE_QTA3_CFG 0x8C4C +#define B_BE_WDE_Q3_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_WDE_Q3_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_WDE_QTA4_CFG 0x8C50 +#define B_BE_WDE_Q4_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_WDE_Q4_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_WDE_ERR1_IMR 0x8CC0 +#define B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN BIT(8) +#define B_BE_WDE_ERR1_IMR_CLR B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN +#define B_BE_WDE_ERR1_IMR_SET B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN + +#define R_BE_PLE_PKTBUF_CFG 0x9008 +#define B_BE_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16) +#define B_BE_PLE_START_BOUND_MASK GENMASK(14, 8) +#define B_BE_PLE_PAGE_SEL_MASK GENMASK(1, 0) + +#define R_BE_PLE_BUFMGN_CTL 0x9010 +#define B_BE_PLE_AVAL_UPD_REQ BIT(29) +#define B_BE_PLE_AVAL_UPD_QTAID_MASK GENMASK(27, 24) +#define B_BE_PLE_BUFMGN_FRZTMR_MODE BIT(0) + +#define R_BE_PLE_ERR_IMR 0x9038 +#define B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_BE_PLE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_BE_PLE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN BIT(23) +#define B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN BIT(22) +#define B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN BIT(21) +#define B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(20) +#define B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(19) +#define B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN BIT(18) +#define B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN BIT(17) +#define B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN BIT(16) +#define B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN BIT(13) +#define B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN BIT(12) +#define B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN BIT(11) +#define B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN BIT(10) +#define B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN BIT(9) +#define B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN BIT(8) +#define B_BE_PLE_GETNPG_STRPG_ERR_INT_EN BIT(7) +#define B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(6) +#define B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN BIT(5) +#define B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(4) +#define B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN BIT(3) +#define B_BE_PLE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_BE_PLE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_BE_PLE_ERR_IMR_CLR (B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_BE_PLE_BUFREQ_SIZE0_INT_EN | \ + B_BE_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_BE_PLE_GETNPG_STRPG_ERR_INT_EN | \ + B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \ + B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_BE_PLE_ERR_IMR_SET (B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_BE_PLE_BUFREQ_SIZE0_INT_EN | \ + B_BE_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_BE_PLE_GETNPG_STRPG_ERR_INT_EN | \ + B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN | \ + B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \ + B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_BE_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN) + +#define R_BE_PLE_QTA0_CFG 0x9040 +#define B_BE_PLE_Q0_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q0_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA1_CFG 0x9044 +#define B_BE_PLE_Q1_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q1_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA2_CFG 0x9048 +#define B_BE_PLE_Q2_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q2_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA3_CFG 0x904C +#define B_BE_PLE_Q3_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q3_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA4_CFG 0x9050 +#define B_BE_PLE_Q4_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q4_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA5_CFG 0x9054 +#define B_BE_PLE_Q5_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q5_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA6_CFG 0x9058 +#define B_BE_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA7_CFG 0x905C +#define B_BE_PLE_Q7_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q7_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA8_CFG 0x9060 +#define B_BE_PLE_Q8_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q8_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA9_CFG 0x9064 +#define B_BE_PLE_Q9_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q9_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA10_CFG 0x9068 +#define B_BE_PLE_Q10_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q10_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA11_CFG 0x906C +#define B_BE_PLE_Q11_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q11_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA12_CFG 0x9070 +#define B_BE_PLE_Q12_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q12_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_QTA13_CFG 0x9074 +#define B_BE_PLE_Q13_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q13_MIN_SIZE_MASK GENMASK(11, 0) + +#define R_BE_PLE_ERRFLAG1_IMR 0x90C0 +#define B_BE_PLE_SRCHPG_PGOFST_IMR BIT(26) +#define B_BE_PLE_SRCHPG_STRPG_IMR BIT(25) +#define B_BE_PLE_SRCHPG_FRZTO_IMR BIT(24) +#define B_BE_PLE_ERRFLAG1_IMR_CLR (B_BE_PLE_SRCHPG_FRZTO_IMR | \ + B_BE_PLE_SRCHPG_STRPG_IMR | \ + B_BE_PLE_SRCHPG_PGOFST_IMR) +#define B_BE_PLE_ERRFLAG1_IMR_SET (B_BE_PLE_SRCHPG_FRZTO_IMR | \ + B_BE_PLE_SRCHPG_STRPG_IMR | \ + B_BE_PLE_SRCHPG_PGOFST_IMR) + +#define R_BE_PLE_DBG_FUN_INTF_CTL 0x9110 +#define B_BE_PLE_DFI_ACTIVE BIT(31) +#define B_BE_PLE_DFI_TRGSEL_MASK GENMASK(19, 16) +#define B_BE_PLE_DFI_ADDR_MASK GENMASK(15, 0) + +#define R_BE_PLE_DBG_FUN_INTF_DATA 0x9114 +#define B_BE_PLE_DFI_DATA_MASK GENMASK(31, 0) + +#define R_BE_WDRLS_CFG 0x9408 +#define B_BE_WDRLS_DIS_AGAC BIT(31) +#define B_BE_RLSRPT_BUFREQ_TO_MASK GENMASK(15, 8) +#define B_BE_RLSRPT_BUFREQ_TO_SEL_MASK GENMASK(7, 6) +#define B_BE_WDRLS_MODE_MASK GENMASK(1, 0) + +#define R_BE_WDRLS_ERR_IMR 0x9430 +#define B_BE_WDRLS_RPT3_FRZTO_ERR_INT_EN BIT(21) +#define B_BE_WDRLS_RPT3_AGGNUM0_ERR_INT_EN BIT(20) +#define B_BE_WDRLS_RPT2_FRZTO_ERR_INT_EN BIT(17) +#define B_BE_WDRLS_RPT2_AGGNUM0_ERR_INT_EN BIT(16) +#define B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN BIT(13) +#define B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN BIT(12) +#define B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN BIT(9) +#define B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN BIT(8) +#define B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN BIT(5) +#define B_BE_WDRLS_PLEBREQ_TO_ERR_INT_EN BIT(4) +#define B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2) +#define B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1) +#define B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0) +#define B_BE_WDRLS_ERR_IMR_CLR (B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_BE_WDRLS_PLEBREQ_TO_ERR_INT_EN | \ + B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define B_BE_WDRLS_ERR_IMR_SET (B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN) + +#define R_BE_RLSRPT0_CFG0 0x9440 +#define B_BE_RLSRPT0_FWRLS BIT(31) +#define B_BE_RLSRPT0_FWD_TRGT_MASK GENMASK(23, 16) +#define B_BE_RLSRPT0_PID_MASK GENMASK(10, 8) +#define B_BE_RLSRPT0_QID_MASK GENMASK(5, 0) +#define WDRLS_DEST_QID_POH 1 +#define WDRLS_DEST_QID_STF 0 + +#define R_BE_RLSRPT0_CFG1 0x9444 +#define B_BE_RLSRPT0_FLTR_MAP_V1_MASK GENMASK(28, 24) +#define S_BE_WDRLS_FLTR_TXOK_V1 BIT(0) +#define S_BE_WDRLS_FLTR_RTYLMT_V1 BIT(1) +#define S_BE_WDRLS_FLTR_LIFTIM_V1 BIT(2) +#define S_BE_WDRLS_FLTR_MACID_V1 BIT(3) +#define S_BE_WDRLS_FLTR_RELINK_V1 BIT(4) +#define B_BE_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24) +#define S_BE_WDRLS_FLTR_TXOK 1 +#define S_BE_WDRLS_FLTR_RTYLMT 2 +#define S_BE_WDRLS_FLTR_LIFTIM 4 +#define S_BE_WDRLS_FLTR_MACID 8 +#define B_BE_RLSRPT0_TO_MASK GENMASK(23, 16) +#define B_BE_RLSRPT0_AGGNUM_MASK GENMASK(7, 0) + +#define R_BE_BBRPT_COM_ERR_IMR 0x9608 +#define B_BE_BBRPT_COM_EVT01_ISR_EN BIT(1) +#define B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN BIT(0) +#define B_BE_BBRPT_COM_ERR_IMR_CLR (B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN | \ + B_BE_BBRPT_COM_EVT01_ISR_EN) +#define B_BE_BBRPT_COM_ERR_IMR_SET B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN + +#define R_BE_BBRPT_CHINFO_ERR_IMR 0x9628 +#define B_BE_ERR_BB_ONETEN_INT_EN BIT(1) +#define B_BE_ERR_GEN_FRZTO_INT_EN BIT(0) +#define B_BE_BBRPT_CHINFO_ERR_IMR_CLR (B_BE_ERR_GEN_FRZTO_INT_EN | \ + B_BE_ERR_BB_ONETEN_INT_EN) +#define B_BE_BBRPT_CHINFO_ERR_IMR_SET (B_BE_ERR_GEN_FRZTO_INT_EN | \ + B_BE_ERR_BB_ONETEN_INT_EN) + +#define R_BE_BBRPT_DFS_ERR_IMR 0x9638 +#define B_BE_BBRPT_DFS_TO_ERR_INT_EN BIT(0) +#define B_BE_BBRPT_DFS_ERR_IMR_CLR B_BE_BBRPT_DFS_TO_ERR_INT_EN +#define B_BE_BBRPT_DFS_ERR_IMR_SET B_BE_BBRPT_DFS_TO_ERR_INT_EN + +#define R_BE_LA_ERRFLAG_IMR 0x9668 +#define B_BE_LA_IMR_DATA_LOSS BIT(0) +#define B_BE_LA_ERRFLAG_IMR_CLR B_BE_LA_IMR_DATA_LOSS +#define B_BE_LA_ERRFLAG_IMR_SET B_BE_LA_IMR_DATA_LOSS + +#define R_BE_LA_ERRFLAG_ISR 0x966C +#define B_BE_LA_ISR_DATA_LOSS BIT(0) + +#define R_BE_CH_INFO_DBGFLAG_IMR 0x9688 +#define B_BE_BCHN_EVT01_ISR_EN BIT(29) +#define B_BE_BCHN_REQTO_ISR_EN BIT(28) +#define B_BE_CHIF_RXDATA_AFACT_ISR_EN BIT(11) +#define B_BE_CHIF_RXDATA_BFACT_ISR_EN BIT(10) +#define B_BE_CHIF_HDR_SEGLEN_ISR_EN BIT(9) +#define B_BE_CHIF_HDR_INVLD_ISR_EN BIT(8) +#define B_BE_CHIF_BBONL_BFACT_ISR_EN BIT(4) +#define B_BE_CHIF_RPT_OVF_ISR_EN BIT(3) +#define B_BE_DBG_CHIF_DATA_LOSS_ISR_EN BIT(2) +#define B_BE_CHIF_DATA_WTOUT_ISR_EN BIT(1) +#define B_BE_CHIF_RPT_WTOUT_ISR_EN BIT(0) +#define B_BE_CH_INFO_DBGFLAG_IMR_CLR (B_BE_CHIF_RPT_WTOUT_ISR_EN | \ + B_BE_CHIF_DATA_WTOUT_ISR_EN | \ + B_BE_DBG_CHIF_DATA_LOSS_ISR_EN | \ + B_BE_CHIF_RPT_OVF_ISR_EN | \ + B_BE_CHIF_HDR_INVLD_ISR_EN | \ + B_BE_CHIF_HDR_SEGLEN_ISR_EN | \ + B_BE_CHIF_RXDATA_BFACT_ISR_EN | \ + B_BE_CHIF_RXDATA_AFACT_ISR_EN) +#define B_BE_CH_INFO_DBGFLAG_IMR_SET 0 + +#define R_BE_WD_BUF_REQ 0x9800 +#define B_BE_WD_BUF_REQ_EXEC BIT(31) +#define B_BE_WD_BUF_REQ_QUOTA_ID_MASK GENMASK(23, 16) +#define B_BE_WD_BUF_REQ_LEN_MASK GENMASK(15, 0) + +#define R_BE_WD_BUF_STATUS 0x9804 +#define B_BE_WD_BUF_STAT_DONE BIT(31) +#define B_BE_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0) + +#define R_BE_WD_CPUQ_OP_0 0x9810 +#define B_BE_WD_CPUQ_OP_EXEC BIT(31) +#define B_BE_WD_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24) +#define B_BE_WD_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0) + +#define R_BE_WD_CPUQ_OP_1 0x9814 +#define B_BE_WD_CPUQ_OP_SRC_MACID_MASK GENMASK(19, 12) +#define B_BE_WD_CPUQ_OP_SRC_QID_MASK GENMASK(9, 4) +#define B_BE_WD_CPUQ_OP_SRC_PID_MASK GENMASK(2, 0) + +#define R_BE_WD_CPUQ_OP_2 0x9818 +#define B_BE_WD_CPUQ_OP_DST_MACID_MASK GENMASK(19, 12) +#define B_BE_WD_CPUQ_OP_DST_QID_MASK GENMASK(9, 4) +#define B_BE_WD_CPUQ_OP_DST_PID_MASK GENMASK(2, 0) + +#define R_BE_WD_CPUQ_OP_3 0x981C +#define B_BE_WD_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16) +#define B_BE_WD_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0) + +#define R_BE_WD_CPUQ_OP_STATUS 0x9820 +#define B_BE_WD_CPUQ_OP_STAT_DONE BIT(31) +#define B_BE_WD_CPUQ_OP_PKTCNT_MASK GENMASK(27, 16) +#define B_BE_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0) + +#define R_BE_PL_BUF_REQ 0x9840 +#define B_BE_PL_BUF_REQ_EXEC BIT(31) +#define B_BE_PL_BUF_REQ_QUOTA_ID_MASK GENMASK(19, 16) +#define B_BE_PL_BUF_REQ_LEN_MASK GENMASK(15, 0) + +#define R_BE_PL_BUF_STATUS 0x9844 +#define B_BE_PL_BUF_STAT_DONE BIT(31) +#define B_BE_PL_BUF_STAT_PKTID_MASK GENMASK(11, 0) + +#define R_BE_PL_CPUQ_OP_0 0x9850 +#define B_BE_PL_CPUQ_OP_EXEC BIT(31) +#define B_BE_PL_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24) +#define B_BE_PL_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0) + +#define R_BE_PL_CPUQ_OP_1 0x9854 +#define B_BE_PL_CPUQ_OP_SRC_MACID_MASK GENMASK(19, 12) +#define B_BE_PL_CPUQ_OP_SRC_QID_MASK GENMASK(9, 4) +#define B_BE_PL_CPUQ_OP_SRC_PID_MASK GENMASK(2, 0) + +#define R_BE_PL_CPUQ_OP_2 0x9858 +#define B_BE_PL_CPUQ_OP_DST_MACID_MASK GENMASK(19, 12) +#define B_BE_PL_CPUQ_OP_DST_QID_MASK GENMASK(9, 4) +#define B_BE_PL_CPUQ_OP_DST_PID_MASK GENMASK(2, 0) + +#define R_BE_PL_CPUQ_OP_3 0x985C +#define B_BE_PL_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16) +#define B_BE_PL_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0) + +#define R_BE_PL_CPUQ_OP_STATUS 0x9860 +#define B_BE_PL_CPUQ_OP_STAT_DONE BIT(31) +#define B_BE_PL_CPUQ_OP_PKTCNT_MASK GENMASK(27, 16) +#define B_BE_PL_CPUQ_OP_PKTID_MASK GENMASK(11, 0) + +#define R_BE_CPUIO_ERR_IMR 0x9888 +#define B_BE_PLEQUE_OP_ERR_INT_EN BIT(12) +#define B_BE_PLEBUF_OP_ERR_INT_EN BIT(8) +#define B_BE_WDEQUE_OP_ERR_INT_EN BIT(4) +#define B_BE_WDEBUF_OP_ERR_INT_EN BIT(0) +#define B_BE_CPUIO_ERR_IMR_CLR (B_BE_WDEBUF_OP_ERR_INT_EN | \ + B_BE_WDEQUE_OP_ERR_INT_EN | \ + B_BE_PLEBUF_OP_ERR_INT_EN | \ + B_BE_PLEQUE_OP_ERR_INT_EN) +#define B_BE_CPUIO_ERR_IMR_SET (B_BE_WDEBUF_OP_ERR_INT_EN | \ + B_BE_WDEQUE_OP_ERR_INT_EN | \ + B_BE_PLEBUF_OP_ERR_INT_EN | \ + B_BE_PLEQUE_OP_ERR_INT_EN) + +#define R_BE_PKTIN_ERR_IMR 0x9A20 +#define B_BE_SW_MERGE_ERR_INT_EN BIT(1) +#define B_BE_GET_NULL_PKTID_ERR_INT_EN BIT(0) +#define B_BE_PKTIN_ERR_IMR_CLR (B_BE_SW_MERGE_ERR_INT_EN | \ + B_BE_GET_NULL_PKTID_ERR_INT_EN) +#define B_BE_PKTIN_ERR_IMR_SET (B_BE_SW_MERGE_ERR_INT_EN | \ + B_BE_GET_NULL_PKTID_ERR_INT_EN) + +#define R_BE_HDR_SHCUT_SETTING 0x9B00 +#define B_BE_TX_ADDR_MLD_TO_LIK BIT(4) +#define B_BE_TX_HW_SEC_HDR_EN BIT(3) +#define B_BE_TX_MAC_MPDU_PROC_EN BIT(2) +#define B_BE_TX_HW_ACK_POLICY_EN BIT(1) +#define B_BE_TX_HW_SEQ_EN BIT(0) + +#define R_BE_MPDU_TX_ERR_IMR 0x9BF4 +#define B_BE_TX_TIMEOUT_ERR_EN BIT(0) +#define B_BE_MPDU_TX_ERR_IMR_CLR B_BE_TX_TIMEOUT_ERR_EN +#define B_BE_MPDU_TX_ERR_IMR_SET 0 + +#define R_BE_MPDU_PROC 0x9C00 +#define B_BE_PORT_SEL BIT(29) +#define B_BE_WPKT_WLANCPU_QSEL_MASK GENMASK(28, 27) +#define B_BE_WPKT_DATACPU_QSEL_MASK GENMASK(26, 25) +#define B_BE_WPKT_FW_RLS BIT(24) +#define B_BE_FWD_RPKT_MASK GENMASK(23, 16) +#define B_BE_FWD_WPKT_MASK GENMASK(15, 8) +#define B_BE_RXFWD_PRIO_MASK GENMASK(5, 4) +#define B_BE_RXFWD_EN BIT(3) +#define B_BE_DROP_NONDMA_PPDU BIT(2) +#define B_BE_APPEND_FCS BIT(0) + +#define R_BE_FWD_ERR 0x9C10 +#define R_BE_FWD_ACTN0 0x9C14 +#define R_BE_FWD_ACTN1 0x9C18 +#define R_BE_FWD_ACTN2 0x9C1C +#define R_BE_FWD_TF0 0x9C20 +#define R_BE_FWD_TF1 0x9C24 + +#define R_BE_HW_PPDU_STATUS 0x9C30 +#define B_BE_FWD_RPKTTYPE_MASK GENMASK(31, 26) +#define B_BE_FWD_PPDU_PRTID_MASK GENMASK(25, 23) +#define B_BE_FWD_PPDU_FW_RLS BIT(22) +#define B_BE_FWD_PPDU_QUEID_MASK GENMASK(21, 16) +#define B_BE_FWD_OTHER_RPKT_MASK GENMASK(15, 8) +#define B_BE_FWD_PPDU_STAT_MASK GENMASK(7, 0) + +#define R_BE_CUT_AMSDU_CTRL 0x9C94 +#define B_BE_EN_CUT_AMSDU BIT(31) +#define B_BE_CUT_AMSDU_CHKLEN_EN BIT(30) +#define B_BE_CA_CHK_ADDRCAM_EN BIT(29) +#define B_BE_MPDU_CUT_CTRL_EN BIT(24) +#define B_BE_CUT_AMSDU_CHKLEN_L_TH_MASK GENMASK(23, 16) +#define B_BE_CUT_AMSDU_CHKLEN_H_TH_MASK GENMASK(15, 0) + +#define R_BE_WOW_CTRL 0x9CB8 +#define B_BE_WOW_HCI BIT(5) +#define B_BE_WOW_DROP BIT(2) +#define B_BE_WOW_WOWEN BIT(1) +#define B_BE_WOW_FORCE_WAKEUP BIT(0) + +#define R_BE_RX_HDRTRNS 0x9CC0 +#define B_BE_RX_MGN_MLD_ADDR_EN BIT(6) +#define B_BE_HDR_INFO_MASK GENMASK(5, 4) +#define B_BE_HC_ADDR_HIT_EN BIT(3) +#define B_BE_RX_ADDR_LINK_TO_MLO BIT(2) +#define B_BE_HDR_CNV BIT(1) +#define B_BE_RX_HDR_CNV_EN BIT(0) +#define TRXCFG_MPDU_PROC_RX_HDR_CONV 0x00000000 + +#define R_BE_MPDU_RX_ERR_IMR 0x9CF4 +#define B_BE_LEN_ERR_IMR BIT(3) +#define B_BE_TIMEOUT_ERR_IMR BIT(1) +#define B_BE_MPDU_RX_ERR_IMR_CLR B_BE_TIMEOUT_ERR_IMR +#define B_BE_MPDU_RX_ERR_IMR_SET 0 + +#define R_BE_SEC_ENG_CTRL 0x9D00 +#define B_BE_SEC_ENG_EN BIT(31) +#define B_BE_CCMP_SPP_MIC BIT(30) +#define B_BE_CCMP_SPP_CTR BIT(29) +#define B_BE_SEC_CAM_ACC BIT(28) +#define B_BE_WMAC_SEC_PN_SEL_MASK GENMASK(27, 26) +#define B_BE_WMAC_SEC_MASKIV BIT(25) +#define B_BE_WAPI_SPEC BIT(24) +#define B_BE_REVERT_TA_RA_MLD_EN BIT(23) +#define B_BE_SEC_DBG_SEL_MASK GENMASK(19, 16) +#define B_BE_CAM_FORCE_CLK BIT(15) +#define B_BE_SEC_FORCE_CLK BIT(14) +#define B_BE_SEC_RX_SHORT_ADD_ICVERR BIT(13) +#define B_BE_SRAM_IO_PROT BIT(12) +#define B_BE_SEC_PRE_ENQUE_TX BIT(11) +#define B_BE_CLK_EN_CGCMP BIT(10) +#define B_BE_CLK_EN_WAPI BIT(9) +#define B_BE_CLK_EN_WEP_TKIP BIT(8) +#define B_BE_BMC_MGNT_DEC BIT(5) +#define B_BE_UC_MGNT_DEC BIT(4) +#define B_BE_MC_DEC BIT(3) +#define B_BE_BC_DEC BIT(2) +#define B_BE_SEC_RX_DEC BIT(1) +#define B_BE_SEC_TX_ENC BIT(0) + +#define R_BE_SEC_MPDU_PROC 0x9D04 +#define B_BE_DBG_ENGINE_SEL BIT(8) +#define B_BE_STOP_RX_PKT_HANDLE BIT(7) +#define B_BE_STOP_TX_PKT_HANDLE BIT(6) +#define B_BE_QUEUE_FOWARD_SEL BIT(5) +#define B_BE_RESP1_PROTECT BIT(4) +#define B_BE_RESP0_PROTECT BIT(3) +#define B_BE_TX_ACTIVE_PROTECT BIT(2) +#define B_BE_APPEND_ICV BIT(1) +#define B_BE_APPEND_MIC BIT(0) + +#define R_BE_SEC_CAM_ACCESS 0x9D10 +#define B_BE_SEC_TIME_OUT_MASK GENMASK(31, 16) +#define B_BE_SEC_CAM_POLL BIT(15) +#define B_BE_SEC_CAM_RW BIT(14) +#define B_BE_SEC_CAM_ACC_FAIL BIT(13) +#define B_BE_SEC_CAM_OFFSET_MASK GENMASK(10, 0) + +#define R_BE_SEC_CAM_RDATA 0x9D14 +#define B_BE_SEC_CAM_RDATA_MASK GENMASK(31, 0) + +#define R_BE_SEC_DEBUG2 0x9D28 +#define B_BE_DBG_READ_MASK GENMASK(31, 0) + +#define R_BE_SEC_ERROR_IMR 0x9D2C +#define B_BE_QUEUE_OPERATION_HANG_IMR BIT(4) +#define B_BE_SEC1_RX_HANG_IMR BIT(3) +#define B_BE_SEC1_TX_HANG_IMR BIT(2) +#define B_BE_RX_HANG_IMR BIT(1) +#define B_BE_TX_HANG_IMR BIT(0) +#define B_BE_SEC_ERROR_IMR_CLR (B_BE_TX_HANG_IMR | \ + B_BE_RX_HANG_IMR | \ + B_BE_SEC1_TX_HANG_IMR | \ + B_BE_SEC1_RX_HANG_IMR | \ + B_BE_QUEUE_OPERATION_HANG_IMR) +#define B_BE_SEC_ERROR_IMR_SET (B_BE_TX_HANG_IMR | \ + B_BE_RX_HANG_IMR | \ + B_BE_SEC1_TX_HANG_IMR | \ + B_BE_SEC1_RX_HANG_IMR | \ + B_BE_QUEUE_OPERATION_HANG_IMR) + +#define R_BE_SEC_ERROR_FLAG 0x9D30 +#define B_BE_TXD_DIFF_KEYCAM_TYPE_ERROR BIT(5) +#define B_BE_QUEUE_OPERATION_HANG_ERROR BIT(4) +#define B_BE_SEC1_RX_HANG_ERROR BIT(3) +#define B_BE_SEC1_TX_HANG_ERROR BIT(2) +#define B_BE_RX_HANG_ERROR BIT(1) +#define B_BE_TX_HANG_ERROR BIT(0) + +#define R_BE_TXPKTCTL_MPDUINFO_CFG 0x9F10 +#define B_BE_MPDUINFO_FEN BIT(31) +#define B_BE_MPDUINFO_PKTID_MASK GENMASK(27, 16) +#define B_BE_MPDUINFO_B1_BADDR_MASK GENMASK(5, 0) +#define MPDU_INFO_B1_OFST 18 +#define MPDU_INFO_TBL_FACTOR 3 + +#define R_BE_TXPKTCTL_B0_PRELD_CFG0 0x9F48 +#define B_BE_B0_PRELD_FEN BIT(31) +#define B_BE_B0_PRELD_USEMAXSZ_MASK GENMASK(25, 16) +#define B_BE_B0_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) +#define PRELD_MISCQ_ENT_NUM_8922A 2 +#define PRELD_MISCQ_ENT_NUM_8922D 1 +#define B_BE_B0_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) +#define PRELD_B0_ACQ_ENT_NUM_8922A 8 +#define PRELD_B1_ACQ_ENT_NUM_8922A 2 +#define PRELD_ACQ_ENT_NUM_8922D 1 + +#define R_BE_TXPKTCTL_B0_PRELD_CFG1 0x9F4C +#define B_BE_B0_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) +#define B_BE_B0_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) + +#define R_BE_TXPKTCTL_B0_ERRFLAG_IMR 0x9F78 +#define B_BE_B0_IMR_DBG_USRCTL_RLSBMPLEN BIT(25) +#define B_BE_B0_IMR_DBG_USRCTL_RDNRLSCMD BIT(24) +#define B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG BIT(17) +#define B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR BIT(16) +#define B_BE_B0_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_BE_B0_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_BE_B0_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_BE_B0_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR (B_BE_B0_IMR_ERR_USRCTL_REINIT | \ + B_BE_B0_IMR_ERR_USRCTL_NOINIT | \ + B_BE_B0_IMR_DBG_USRCTL_RDNRLSCMD | \ + B_BE_B0_IMR_DBG_USRCTL_RLSBMPLEN | \ + B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_BE_B0_IMR_ERR_CMDPSR_FRZTO | \ + B_BE_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG) +#define B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET (B_BE_B0_IMR_ERR_USRCTL_REINIT | \ + B_BE_B0_IMR_ERR_USRCTL_NOINIT | \ + B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_BE_B0_IMR_ERR_CMDPSR_FRZTO | \ + B_BE_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG) + +#define R_BE_TXPKTCTL_B1_PRELD_CFG0 0x9F88 +#define B_BE_B1_PRELD_FEN BIT(31) +#define B_BE_B1_PRELD_USEMAXSZ_MASK GENMASK(25, 16) +#define B_BE_B1_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) +#define B_BE_B1_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) + +#define R_BE_TXPKTCTL_B1_PRELD_CFG1 0x9F8C +#define B_BE_B1_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) +#define B_BE_B1_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) + +#define R_BE_TXPKTCTL_B1_ERRFLAG_IMR 0x9FB8 +#define B_BE_B1_IMR_DBG_USRCTL_RLSBMPLEN BIT(25) +#define B_BE_B1_IMR_DBG_USRCTL_RDNRLSCMD BIT(24) +#define B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG BIT(17) +#define B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR BIT(16) +#define B_BE_B1_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_BE_B1_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_BE_B1_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_BE_B1_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR (B_BE_B1_IMR_ERR_USRCTL_REINIT | \ + B_BE_B1_IMR_ERR_USRCTL_NOINIT | \ + B_BE_B1_IMR_DBG_USRCTL_RDNRLSCMD | \ + B_BE_B1_IMR_DBG_USRCTL_RLSBMPLEN | \ + B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_BE_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_BE_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG) +#define B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET (B_BE_B1_IMR_ERR_USRCTL_REINIT | \ + B_BE_B1_IMR_ERR_USRCTL_NOINIT | \ + B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_BE_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_BE_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG) + +#define R_BE_MLO_INIT_CTL 0xA114 +#define B_BE_MLO_TABLE_INIT_DONE BIT(31) +#define B_BE_MLO_TABLE_CLR_DONE BIT(30) +#define B_BE_MLO_TABLE_REINIT BIT(23) +#define B_BE_MLO_TABLE_HW_FLAG_CLR BIT(22) + +#define R_BE_MLO_ERR_IDCT_IMR 0xA128 +#define B_BE_MLO_ERR_IDCT_IMR_0 BIT(31) +#define B_BE_MLO_ERR_IDCT_IMR_1 BIT(30) +#define B_BE_MLO_ERR_IDCT_IMR_2 BIT(29) +#define B_BE_MLO_ERR_IDCT_IMR_3 BIT(28) +#define B_BE_MLO_ERR_IDCT_IMR_CLR (B_BE_MLO_ERR_IDCT_IMR_2 | \ + B_BE_MLO_ERR_IDCT_IMR_1 | \ + B_BE_MLO_ERR_IDCT_IMR_0) +#define B_BE_MLO_ERR_IDCT_IMR_SET (B_BE_MLO_ERR_IDCT_IMR_2 | \ + B_BE_MLO_ERR_IDCT_IMR_1 | \ + B_BE_MLO_ERR_IDCT_IMR_0) + +#define R_BE_MLO_ERR_IDCT_ISR 0xA12C +#define B_BE_MLO_ISR_IDCT_0 BIT(31) +#define B_BE_MLO_ISR_IDCT_1 BIT(30) +#define B_BE_MLO_ISR_IDCT_2 BIT(29) +#define B_BE_MLO_ISR_IDCT_3 BIT(28) + +#define R_BE_PLRLS_ERR_IMR 0xA218 +#define B_BE_PLRLS_CTL_FRZTO_IMR BIT(0) +#define B_BE_PLRLS_ERR_IMR_CLR B_BE_PLRLS_CTL_FRZTO_IMR +#define B_BE_PLRLS_ERR_IMR_SET B_BE_PLRLS_CTL_FRZTO_IMR + +#define R_BE_PLRLS_ERR_ISR 0xA21C +#define B_BE_PLRLS_CTL_EVT03_ISR BIT(3) +#define B_BE_PLRLS_CTL_EVT02_ISR BIT(2) +#define B_BE_PLRLS_CTL_EVT01_ISR BIT(1) +#define B_BE_PLRLS_CTL_FRZTO_ISR BIT(0) + +#define R_BE_SS_CTRL 0xA310 +#define R_BE_SS_CTRL_V1 0xA610 +#define B_BE_SS_INIT_DONE BIT(31) +#define B_BE_WDE_STA_DIS BIT(30) +#define B_BE_WARM_INIT BIT(29) +#define B_BE_BAND_TRIG_EN BIT(28) +#define B_BE_RMAC_REQ_DIS BIT(27) +#define B_BE_DLYTX_SEL_MASK GENMASK(25, 24) +#define B_BE_WMM3_SWITCH_MASK GENMASK(23, 22) +#define B_BE_WMM2_SWITCH_MASK GENMASK(21, 20) +#define B_BE_WMM1_SWITCH_MASK GENMASK(19, 18) +#define B_BE_WMM0_SWITCH_MASK GENMASK(17, 16) +#define B_BE_STA_OPTION_CR BIT(15) +#define B_BE_EMLSR_STA_EMPTY_EN BIT(11) +#define B_BE_MLO_HW_CHGLINK_EN BIT(10) +#define B_BE_BAND1_TRIG_EN BIT(9) +#define B_BE_RMAC1_REQ_DIS BIT(8) +#define B_BE_MRT_SRAM_EN BIT(7) +#define B_BE_MRT_INIT_EN BIT(6) +#define B_BE_AVG_LENG_EN BIT(5) +#define B_BE_AVG_INIT_EN BIT(4) +#define B_BE_LENG_INIT_EN BIT(2) +#define B_BE_PMPA_INIT_EN BIT(1) +#define B_BE_SS_EN BIT(0) + +#define R_BE_INTERRUPT_MASK_REG 0xA3F0 +#define B_BE_PLE_B_PKTID_ERR_IMR BIT(2) +#define B_BE_RPT_TIMEOUT_IMR BIT(1) +#define B_BE_SEARCH_TIMEOUT_IMR BIT(0) +#define B_BE_INTERRUPT_MASK_REG_CLR (B_BE_SEARCH_TIMEOUT_IMR | \ + B_BE_RPT_TIMEOUT_IMR | \ + B_BE_PLE_B_PKTID_ERR_IMR) +#define B_BE_INTERRUPT_MASK_REG_SET (B_BE_SEARCH_TIMEOUT_IMR | \ + B_BE_RPT_TIMEOUT_IMR | \ + B_BE_PLE_B_PKTID_ERR_IMR) + +#define R_BE_INTERRUPT_STS_REG 0xA3F4 +#define B_BE_PLE_B_PKTID_ERR_ISR BIT(2) +#define B_BE_RPT_TIMEOUT_ISR BIT(1) +#define B_BE_SEARCH_TIMEOUT_ISR BIT(0) + +#define R_BE_PLRLS_ERR_IMR_V1 0xA518 +#define B_BE_PLRLS_DUMMY_ISR6 BIT(7) +#define B_BE_PLRLS_DUMMY_ISR5 BIT(6) +#define B_BE_PLRLS_DUMMY_ISR4 BIT(5) +#define B_BE_PLRLS_DUMMY_ISR3 BIT(4) +#define B_BE_PLRLS_DUMMY_ISR2 BIT(3) +#define B_BE_PLRLS_DUMMY_ISR1 BIT(2) +#define B_BE_PLRLS_DUMMY_ISR0 BIT(1) +#define B_BE_PLRLS_ERR_IMR_V1_CLR 0x1 +#define B_BE_PLRLS_ERR_IMR_V1_SET 0x1 + +#define R_BE_SS_LITE_TXL_MACID 0xA790 +#define B_BE_RPT_OTHER_BAND_EN BIT(31) +#define B_BE_TXL_CMD_EN BIT(30) +#define B_BE_TXL_READ_MACID_MASK GENMASK(29, 20) +#define B_BE_TXL_MACID_1_MASK GENMASK(19, 10) +#define B_BE_TXL_MACID_0_MASK GENMASK(9, 0) + +#define R_BE_HAXI_INIT_CFG1 0xB000 +#define B_BE_CFG_WD_PERIOD_IDLE_MASK GENMASK(31, 28) +#define B_BE_CFG_WD_PERIOD_ACTIVE_MASK GENMASK(27, 24) +#define B_BE_EN_RO_IDX_UPD_BY_IO BIT(19) +#define B_BE_RST_KEEP_REG BIT(18) +#define B_BE_FLUSH_HAXI_MST BIT(17) +#define B_BE_SET_BDRAM_BOUND BIT(16) +#define B_BE_ADDRINFO_ALIGN4B_EN BIT(15) +#define B_BE_RXBD_DONE_MODE_MASK GENMASK(14, 13) +#define B_BE_RXQ_RXBD_MODE_MASK GENMASK(12, 11) +#define B_BE_DMA_MODE_MASK GENMASK(10, 8) +#define S_BE_DMA_MOD_PCIE_NO_DATA_CPU 0x0 +#define S_BE_DMA_MOD_PCIE_DATA_CPU 0x1 +#define S_BE_DMA_MOD_USB 0x4 +#define S_BE_DMA_MOD_SDIO 0x6 +#define B_BE_STOP_AXI_MST BIT(7) +#define B_BE_RXDMA_ALIGN64B_EN BIT(6) +#define B_BE_RXDMA_EN BIT(5) +#define B_BE_TXDMA_EN BIT(4) +#define B_BE_MAX_RXDMA_MASK GENMASK(3, 2) +#define B_BE_MAX_TXDMA_MASK GENMASK(1, 0) + +#define R_BE_HAXI_DMA_STOP1 0xB010 +#define B_BE_STOP_WPDMA BIT(31) +#define B_BE_STOP_CH14 BIT(14) +#define B_BE_STOP_CH13 BIT(13) +#define B_BE_STOP_CH12 BIT(12) +#define B_BE_STOP_CH11 BIT(11) +#define B_BE_STOP_CH10 BIT(10) +#define B_BE_STOP_CH9 BIT(9) +#define B_BE_STOP_CH8 BIT(8) +#define B_BE_STOP_CH7 BIT(7) +#define B_BE_STOP_CH6 BIT(6) +#define B_BE_STOP_CH5 BIT(5) +#define B_BE_STOP_CH4 BIT(4) +#define B_BE_STOP_CH3 BIT(3) +#define B_BE_STOP_CH2 BIT(2) +#define B_BE_STOP_CH1 BIT(1) +#define B_BE_STOP_CH0 BIT(0) +#define B_BE_TX_STOP1_MASK (B_BE_STOP_CH0 | B_BE_STOP_CH1 | \ + B_BE_STOP_CH2 | B_BE_STOP_CH3 | \ + B_BE_STOP_CH4 | B_BE_STOP_CH5 | \ + B_BE_STOP_CH6 | B_BE_STOP_CH7 | \ + B_BE_STOP_CH8 | B_BE_STOP_CH9 | \ + B_BE_STOP_CH10 | B_BE_STOP_CH11 | \ + B_BE_STOP_CH12 | B_BE_STOP_CH13 | \ + B_BE_STOP_CH14) +#define B_BE_TX_STOP1_MASK_V1 (B_BE_STOP_CH0 | B_BE_STOP_CH2 | \ + B_BE_STOP_CH4 | B_BE_STOP_CH6 | \ + B_BE_STOP_CH8 | B_BE_STOP_CH10 | \ + B_BE_STOP_CH12) + +#define R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1 0xB02C +#define B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK GENMASK(4, 0) + +#define R_BE_HAXI_IDCT_MSK 0xB0B8 +#define B_BE_HAXI_RRESP_ERR_IDCT_MSK BIT(7) +#define B_BE_HAXI_BRESP_ERR_IDCT_MSK BIT(6) +#define B_BE_RXDMA_ERR_FLAG_IDCT_MSK BIT(5) +#define B_BE_SET_FC_ERROR_FLAG_IDCT_MSK BIT(4) +#define B_BE_TXBD_LEN0_ERR_IDCT_MSK BIT(3) +#define B_BE_TXBD_4KBOUND_ERR_IDCT_MSK BIT(2) +#define B_BE_RXMDA_STUCK_IDCT_MSK BIT(1) +#define B_BE_TXMDA_STUCK_IDCT_MSK BIT(0) +#define B_BE_HAXI_IDCT_MSK_CLR (B_BE_TXMDA_STUCK_IDCT_MSK | \ + B_BE_RXMDA_STUCK_IDCT_MSK | \ + B_BE_TXBD_LEN0_ERR_IDCT_MSK | \ + B_BE_SET_FC_ERROR_FLAG_IDCT_MSK | \ + B_BE_RXDMA_ERR_FLAG_IDCT_MSK | \ + B_BE_HAXI_BRESP_ERR_IDCT_MSK | \ + B_BE_HAXI_RRESP_ERR_IDCT_MSK) +#define B_BE_HAXI_IDCT_MSK_SET (B_BE_TXMDA_STUCK_IDCT_MSK | \ + B_BE_RXMDA_STUCK_IDCT_MSK | \ + B_BE_TXBD_LEN0_ERR_IDCT_MSK | \ + B_BE_SET_FC_ERROR_FLAG_IDCT_MSK | \ + B_BE_RXDMA_ERR_FLAG_IDCT_MSK | \ + B_BE_HAXI_BRESP_ERR_IDCT_MSK | \ + B_BE_HAXI_RRESP_ERR_IDCT_MSK) + +#define R_BE_HAXI_IDCT 0xB0BC +#define B_BE_HAXI_RRESP_ERR_IDCT BIT(7) +#define B_BE_HAXI_BRESP_ERR_IDCT BIT(6) +#define B_BE_RXDMA_ERR_FLAG_IDCT BIT(5) +#define B_BE_SET_FC_ERROR_FLAG_IDCT BIT(4) +#define B_BE__TXBD_LEN0_ERR_IDCT BIT(3) +#define B_BE__TXBD_4KBOUND_ERR_IDCT BIT(2) +#define B_BE_RXMDA_STUCK_IDCT BIT(1) +#define B_BE_TXMDA_STUCK_IDCT BIT(0) + +#define R_BE_HCI_FC_CTRL 0xB700 +#define B_BE_WD_PAGE_MODE_MASK GENMASK(17, 16) +#define B_BE_HCI_FC_CH14_FULL_COND_MASK GENMASK(15, 14) +#define B_BE_HCI_FC_TWD_FULL_COND_MASK GENMASK(13, 12) +#define B_BE_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) +#define B_BE_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8) +#define B_BE_HCI_FC_WP_CH07_FULL_COND_MASK GENMASK(7, 6) +#define B_BE_HCI_FC_WD_FULL_COND_MASK GENMASK(5, 4) +#define B_BE_HCI_FC_CH12_EN BIT(3) +#define B_BE_HCI_FC_MODE_MASK GENMASK(2, 1) +#define B_BE_HCI_FC_EN BIT(0) + +#define R_BE_CH_PAGE_CTRL 0xB704 +#define B_BE_PREC_PAGE_CH12_V1_MASK GENMASK(21, 16) +#define B_BE_FULL_WD_PG_MASK GENMASK(15, 8) +#define B_BE_PREC_PAGE_CH011_V1_MASK GENMASK(5, 0) + +#define R_BE_CH0_PAGE_CTRL 0xB718 +#define B_BE_CH0_GRP BIT(31) +#define B_BE_CH0_MAX_PG_MASK GENMASK(28, 16) +#define B_BE_CH0_MIN_PG_MASK GENMASK(12, 0) + +#define R_BE_CH0_PAGE_INFO 0xB750 +#define B_BE_CH0_AVAL_PG_MASK GENMASK(28, 16) +#define B_BE_CH0_USE_PG_MASK GENMASK(12, 0) + +#define R_BE_PUB_PAGE_INFO3 0xB78C +#define B_BE_G1_AVAL_PG_MASK GENMASK(28, 16) +#define B_BE_G0_AVAL_PG_MASK GENMASK(12, 0) + +#define R_BE_PUB_PAGE_CTRL1 0xB790 +#define B_BE_PUBPG_G1_MASK GENMASK(28, 16) +#define B_BE_PUBPG_G0_MASK GENMASK(12, 0) + +#define R_BE_PUB_PAGE_CTRL2 0xB794 +#define B_BE_PUBPG_ALL_MASK GENMASK(12, 0) + +#define R_BE_PUB_PAGE_INFO1 0xB79C +#define B_BE_G1_USE_PG_MASK GENMASK(28, 16) +#define B_BE_G0_USE_PG_MASK GENMASK(12, 0) + +#define R_BE_PUB_PAGE_INFO2 0xB7A0 +#define B_BE_PUB_AVAL_PG_MASK GENMASK(12, 0) + +#define R_BE_WP_PAGE_CTRL1 0xB7A4 +#define B_BE_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16) +#define B_BE_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0) +#define B_BE_FULL_PAGE_WP_CH811_MASK GENMASK(31, 24) +#define B_BE_PREC_PAGE_WP_CH811_V1_MASK GENMASK(23, 16) +#define B_BE_FULL_PAGE_WP_CH07_MASK GENMASK(15, 8) +#define B_BE_PREC_PAGE_WP_CH07_V1_MASK GENMASK(7, 0) + +#define R_BE_WP_PAGE_CTRL2 0xB7A8 +#define B_BE_WP_THRD_MASK GENMASK(12, 0) + +#define R_BE_WP_PAGE_INFO1 0xB7AC +#define B_BE_WP_AVAL_PG_MASK GENMASK(28, 16) + +#define R_BE_LTPC_T0_PATH0 0xBA28 +#define R_BE_LTPC_T0_PATH1 0xBB28 + +#define R_BE_CMAC_SHARE_FUNC_EN 0x0E000 +#define B_BE_CMAC_SHARE_CRPRT BIT(31) +#define B_BE_CMAC_SHARE_EN BIT(30) +#define B_BE_FORCE_BTCOEX_REG_GCKEN BIT(24) +#define B_BE_FORCE_CMAC_SHARE_COMMON_REG_GCKEN BIT(16) +#define B_BE_FORCE_CMAC_SHARE_REG_GCKEN BIT(15) +#define B_BE_RESPBA_EN BIT(2) +#define B_BE_ADDRSRCH_EN BIT(1) +#define B_BE_BTCOEX_EN BIT(0) + +#define R_BE_CMAC_SHARE_ACQCHK_CFG_0 0x0E010 +#define B_BE_ACQCHK_ERR_FLAG_MASK GENMASK(31, 24) +#define B_BE_R_ACQCHK_ENTRY_IDX_SEL_MASK GENMASK(7, 4) +#define B_BE_MACID_ACQ_GRP1_CLR_P BIT(3) +#define B_BE_MACID_ACQ_GRP0_CLR_P BIT(2) +#define B_BE_R_MACID_ACQ_CHK_EN BIT(0) + +#define R_BE_BTC_CFG 0x0E300 +#define R_BE_BT_BREAK_TABLE 0x0E344 + +#define R_BE_GNT_SW_CTRL 0x0E348 +#define B_BE_WL_ACT2_VAL BIT(25) +#define B_BE_WL_ACT2_SWCTRL BIT(24) +#define B_BE_WL_ACT_VAL BIT(23) +#define B_BE_WL_ACT_SWCTRL BIT(22) +#define B_BE_GNT_BT_RX_BB1_VAL BIT(21) +#define B_BE_GNT_BT_RX_BB1_SWCTRL BIT(20) +#define B_BE_GNT_BT_TX_BB1_VAL BIT(19) +#define B_BE_GNT_BT_TX_BB1_SWCTRL BIT(18) +#define B_BE_GNT_BT_RX_BB0_VAL BIT(17) +#define B_BE_GNT_BT_RX_BB0_SWCTRL BIT(16) +#define B_BE_GNT_BT_TX_BB0_VAL BIT(15) +#define B_BE_GNT_BT_TX_BB0_SWCTRL BIT(14) +#define B_BE_GNT_WL_RX_VAL BIT(13) +#define B_BE_GNT_WL_RX_SWCTRL BIT(12) +#define B_BE_GNT_WL_TX_VAL BIT(11) +#define B_BE_GNT_WL_TX_SWCTRL BIT(10) +#define B_BE_GNT_BT_BB1_VAL BIT(9) +#define B_BE_GNT_BT_BB1_SWCTRL BIT(8) +#define B_BE_GNT_WL_BB1_VAL BIT(7) +#define B_BE_GNT_WL_BB1_SWCTRL BIT(6) +#define B_BE_GNT_BT_BB0_VAL BIT(5) +#define B_BE_GNT_BT_BB0_SWCTRL BIT(4) +#define B_BE_GNT_WL_BB0_VAL BIT(3) +#define B_BE_GNT_WL_BB0_SWCTRL BIT(2) +#define B_BE_GNT_WL_BB_PWR_VAL BIT(1) +#define B_BE_GNT_WL_BB_PWR_SWCTRL BIT(0) + +#define R_BE_PTA_GNT_SW_CTRL 0x0E348 +#define B_BE_PTA_WL_ACT0_VAL BIT(19) +#define B_BE_PTA_WL_ACT0_SWCTRL BIT(18) +#define B_BE_PTA_GNT_BT0_RX_BB1_VAL BIT(17) +#define B_BE_PTA_GNT_BT0_RX_BB1_SWCTRL BIT(16) +#define B_BE_PTA_GNT_BT0_TX_BB1_VAL BIT(15) +#define B_BE_PTA_GNT_BT0_TX_BB1_SWCTRL BIT(14) +#define B_BE_PTA_GNT_BT0_RX_BB0_VAL BIT(13) +#define B_BE_PTA_GNT_BT0_RX_BB0_SWCTRL BIT(12) +#define B_BE_PTA_GNT_BT0_TX_BB0_VAL BIT(11) +#define B_BE_PTA_GNT_BT0_TX_BB0_SWCTRL BIT(10) +#define B_BE_PTA_GNT_BT0_BB_VAL BIT(9) +#define B_BE_PTA_GNT_BT0_BB_SWCTRL BIT(8) +#define B_BE_PTA_WL_ACT_RX_BT0_VAL BIT(7) +#define B_BE_PTA_WL_ACT_RX_BT0_SWCTRL BIT(6) +#define B_BE_PTA_WL_ACT_TX_BT0_VAL BIT(5) +#define B_BE_PTA_WL_ACT_TX_BT0_SWCTRL BIT(4) +#define B_BE_PTA_GNT_WL_BB1_VAL BIT(3) +#define B_BE_PTA_GNT_WL_BB1_SWCTRL BIT(2) +#define B_BE_PTA_GNT_WL_BB0_VAL BIT(1) +#define B_BE_PTA_GNT_WL_BB0_SWCTRL BIT(0) + +#define R_BE_PTA_GNT_VAL 0x0E34C +#define B_BE_PTA_WL_ACT2 BIT(20) +#define B_BE_PTA_GNT_ZB_TX_BB1 BIT(19) +#define B_BE_PTA_GNT_ZB_TX_BB0 BIT(18) +#define B_BE_PTA_WL_ACT1 BIT(17) +#define B_BE_PTA_GNT_BT1_RX_BB1 BIT(16) +#define B_BE_PTA_GNT_BT1_RX_BB0 BIT(15) +#define B_BE_PTA_GNT_BT1_TX_BB1 BIT(14) +#define B_BE_PTA_GNT_BT1_TX_BB0 BIT(13) +#define B_BE_PTA_WL_ACT_RX_BT1 BIT(12) +#define B_BE_PTA_WL_ACT_TX_BT1 BIT(11) +#define B_BE_PTA_GNT_BT1_BB BIT(10) +#define B_BE_PTA_WL_ACT0 BIT(9) +#define B_BE_PTA_GNT_BT0_RX_BB1 BIT(8) +#define B_BE_PTA_GNT_BT0_TX_BB1 BIT(7) +#define B_BE_PTA_GNT_BT0_RX_BB0 BIT(6) +#define B_BE_PTA_GNT_BT0_TX_BB0 BIT(5) +#define B_BE_PTA_GNT_BT0_BB BIT(4) +#define B_BE_PTA_WL_ACT_RX_BT0 BIT(3) +#define B_BE_PTA_WL_ACT_TX_BT0 BIT(2) +#define B_BE_PTA_GNT_WL_BB1 BIT(1) +#define B_BE_PTA_GNT_WL_BB0 BIT(0) + +#define R_BE_PTA_GNT_ZL_SW_CTRL 0x0E350 +#define B_BE_PTA_WL_ACT2_VAL BIT(21) +#define B_BE_PTA_WL_ACT2_SWCTRL BIT(20) +#define B_BE_PTA_GNT_ZB_TX_BB1_VAL BIT(19) +#define B_BE_PTA_GNT_ZB_TX_BB1_SWCTRL BIT(18) +#define B_BE_PTA_GNT_ZB_TX_BB0_VAL BIT(17) +#define B_BE_PTA_GNT_ZB_TX_BB0_SWCTRL BIT(16) +#define B_BE_PTA_WL_ACT1_VAL BIT(15) +#define B_BE_PTA_WL_ACT1_SWCTRL BIT(14) +#define B_BE_PTA_GNT_BT1_RX_BB1_VAL BIT(13) +#define B_BE_PTA_GNT_BT1_RX_BB1_SWCTRL BIT(12) +#define B_BE_PTA_GNT_BT1_RX_BB0_VAL BIT(11) +#define B_BE_PTA_GNT_BT1_RX_BB0_SWCTRL BIT(10) +#define B_BE_PTA_GNT_BT1_TX_BB1_VAL BIT(9) +#define B_BE_PTA_GNT_BT1_TX_BB1_SWCTRL BIT(8) +#define B_BE_PTA_GNT_BT1_TX_BB0_VAL BIT(7) +#define B_BE_PTA_GNT_BT1_TX_BB0_SWCTRL BIT(6) +#define B_BE_PTA_WL_ACT_RX_BT1_VAL BIT(5) +#define B_BE_PTA_WL_ACT_RX_BT1_SWCTRL BIT(4) +#define B_BE_PTA_WL_ACT_TX_BT1_VAL BIT(3) +#define B_BE_PTA_WL_ACT_TX_BT1_SWCTRL BIT(2) +#define B_BE_PTA_GNT_BT1_BB_VAL BIT(1) +#define B_BE_PTA_GNT_BT1_BB_SWCTRL BIT(0) + +#define R_BE_PWR_MACID_PATH_BASE 0x0E500 +#define R_BE_PWR_MACID_PATH_BASE_V1 0x1C000 +#define R_BE_PWR_MACID_LMT_BASE 0x0ED00 +#define R_BE_PWR_MACID_LMT_BASE_V1 0x1C800 + +#define R_BE_CMAC_FUNC_EN 0x10000 +#define R_BE_CMAC_FUNC_EN_C1 0x14000 +#define B_BE_CMAC_CRPRT BIT(31) +#define B_BE_CMAC_EN BIT(30) +#define B_BE_CMAC_TXEN BIT(29) +#define B_BE_CMAC_RXEN BIT(28) +#define B_BE_FORCE_RESP_PKTCTL_GCKEN BIT(26) +#define B_BE_FORCE_SIGB_REG_GCKEN BIT(25) +#define B_BE_FORCE_POWER_REG_GCKEN BIT(23) +#define B_BE_FORCE_RMAC_REG_GCKEN BIT(22) +#define B_BE_FORCE_TRXPTCL_REG_GCKEN BIT(21) +#define B_BE_FORCE_TMAC_REG_GCKEN BIT(20) +#define B_BE_FORCE_CMAC_DMA_REG_GCKEN BIT(19) +#define B_BE_FORCE_PTCL_REG_GCKEN BIT(18) +#define B_BE_FORCE_SCHEDULER_RREG_GCKEN BIT(17) +#define B_BE_FORCE_CMAC_COMMON_REG_GCKEN BIT(16) +#define B_BE_FORCE_CMACREG_GCKEN BIT(15) +#define B_BE_TXTIME_EN BIT(8) +#define B_BE_RESP_PKTCTL_EN BIT(7) +#define B_BE_SIGB_EN BIT(6) +#define B_BE_PHYINTF_EN BIT(5) +#define B_BE_CMAC_DMA_EN BIT(4) +#define B_BE_PTCLTOP_EN BIT(3) +#define B_BE_SCHEDULER_EN BIT(2) +#define B_BE_TMAC_EN BIT(1) +#define B_BE_RMAC_EN BIT(0) +#define B_BE_CMAC_FUNC_EN_SET (B_BE_CMAC_EN | B_BE_CMAC_TXEN | B_BE_CMAC_RXEN | \ + B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN | B_BE_PTCLTOP_EN | \ + B_BE_SCHEDULER_EN | B_BE_TMAC_EN | B_BE_RMAC_EN | \ + B_BE_CMAC_CRPRT | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN | \ + B_BE_SIGB_EN) + +#define R_BE_CK_EN 0x10004 +#define R_BE_CK_EN_C1 0x14004 +#define B_BE_CMAC_CKEN BIT(30) +#define B_BE_BCN_P1_P4_CKEN BIT(15) +#define B_BE_BCN_P0MB1_15_CKEN BIT(14) +#define B_BE_TXTIME_CKEN BIT(8) +#define B_BE_RESP_PKTCTL_CKEN BIT(7) +#define B_BE_SIGB_CKEN BIT(6) +#define B_BE_PHYINTF_CKEN BIT(5) +#define B_BE_CMAC_DMA_CKEN BIT(4) +#define B_BE_PTCLTOP_CKEN BIT(3) +#define B_BE_SCHEDULER_CKEN BIT(2) +#define B_BE_TMAC_CKEN BIT(1) +#define B_BE_RMAC_CKEN BIT(0) +#define B_BE_CK_EN_SET (B_BE_CMAC_CKEN | B_BE_PHYINTF_CKEN | B_BE_CMAC_DMA_CKEN | \ + B_BE_PTCLTOP_CKEN | B_BE_SCHEDULER_CKEN | B_BE_TMAC_CKEN | \ + B_BE_RMAC_CKEN | B_BE_TXTIME_CKEN | B_BE_RESP_PKTCTL_CKEN | \ + B_BE_SIGB_CKEN) + +#define R_BE_WMAC_RFMOD 0x10010 +#define R_BE_WMAC_RFMOD_C1 0x14010 +#define B_BE_CMAC_ASSERTION BIT(31) +#define B_BE_WMAC_RFMOD_MASK GENMASK(2, 0) +#define BE_WMAC_RFMOD_20M 0 +#define BE_WMAC_RFMOD_40M 1 +#define BE_WMAC_RFMOD_80M 2 +#define BE_WMAC_RFMOD_160M 3 +#define BE_WMAC_RFMOD_320M 4 + +#define R_BE_GID_POSITION0 0x10070 +#define R_BE_GID_POSITION0_C1 0x14070 +#define R_BE_GID_POSITION1 0x10074 +#define R_BE_GID_POSITION1_C1 0x14074 +#define R_BE_GID_POSITION2 0x10078 +#define R_BE_GID_POSITION2_C1 0x14078 +#define R_BE_GID_POSITION3 0x1007C +#define R_BE_GID_POSITION3_C1 0x1407C +#define R_BE_GID_POSITION_EN0 0x10080 +#define R_BE_GID_POSITION_EN0_C1 0x14080 +#define R_BE_GID_POSITION_EN1 0x10084 +#define R_BE_GID_POSITION_EN1_C1 0x14084 + +#define R_BE_TX_SUB_BAND_VALUE 0x10088 +#define R_BE_TX_SUB_BAND_VALUE_C1 0x14088 +#define B_BE_PRI20_BITMAP_MASK GENMASK(31, 16) +#define BE_PRI20_BITMAP_MAX 15 +#define B_BE_TXSB_160M_MASK GENMASK(15, 12) +#define S_BE_TXSB_160M_0 0 +#define S_BE_TXSB_160M_1 1 +#define B_BE_TXSB_80M_MASK GENMASK(11, 8) +#define S_BE_TXSB_80M_0 0 +#define S_BE_TXSB_80M_2 2 +#define S_BE_TXSB_80M_4 4 +#define B_BE_TXSB_40M_MASK GENMASK(7, 4) +#define S_BE_TXSB_40M_0 0 +#define S_BE_TXSB_40M_1 1 +#define S_BE_TXSB_40M_4 4 +#define B_BE_TXSB_20M_MASK GENMASK(3, 0) +#define S_BE_TXSB_20M_8 8 +#define S_BE_TXSB_20M_4 4 +#define S_BE_TXSB_20M_2 2 + +#define R_BE_PTCL_RRSR0 0x1008C +#define R_BE_PTCL_RRSR0_C1 0x1408C +#define B_BE_RRSR_HE_MASK GENMASK(31, 24) +#define B_BE_RRSR_VHT_MASK GENMASK(23, 16) +#define B_BE_RRSR_HT_MASK GENMASK(15, 8) +#define B_BE_RRSR_OFDM_MASK GENMASK(7, 0) + +#define R_BE_PTCL_RRSR1 0x10090 +#define R_BE_PTCL_RRSR1_C1 0x14090 +#define B_BE_RRSR_EHT_MASK GENMASK(23, 16) +#define B_BE_RRSR_RATE_EN_MASK GENMASK(12, 8) +#define B_BE_RSC_MASK GENMASK(7, 6) +#define B_BE_RRSR_CCK_MASK GENMASK(3, 0) + +#define R_BE_COMMON_PHYINTF_CTRL_0 0x100B8 +#define R_BE_COMMON_PHYINTF_CTRL_0_C1 0x140B8 +#define B_BE_SEQ_EN_GUARD_CYE_MASK GENMASK(23, 20) +#define B_BE_PARA_FIFO_CRC_EN BIT(18) +#define B_BE_SEQ_FIFO_TO_EN BIT(17) +#define B_BE_PARA_FIFO_TO_EN BIT(16) +#define B_BE_SEQ_FIFO_CLR_EN BIT(6) +#define B_BE_PARA_FIFO_CLR_EN_V1 BIT(5) +#define B_BE_CSI_FIFO_CLR_EN_V1 BIT(4) +#define B_BE_FTM_FIFO_CLR_EN_V1 BIT(3) +#define B_BE_RXD_FIFO_CLR_EN_V1 BIT(2) +#define B_BE_TXD_FIFO_CLR_EN_V1 BIT(1) +#define B_BE_TXUID_FIFO_CLR_EN_V1 BIT(0) +#define CLEAR_DTOP_DIS (BIT(1) | BIT(5) | BIT(6)) + +#define R_BE_CMAC_ERR_IMR 0x10160 +#define R_BE_CMAC_ERR_IMR_C1 0x14160 +#define B_BE_CMAC_FW_ERR_IDCT_EN BIT(16) +#define B_BE_PTCL_TX_IDLETO_IDCT_EN BIT(9) +#define B_BE_WMAC_RX_IDLETO_IDCT_EN BIT(8) +#define B_BE_WMAC_TX_ERR_IND_EN BIT(7) +#define B_BE_WMAC_RX_ERR_IND_EN BIT(6) +#define B_BE_TXPWR_CTRL_ERR_IND_EN BIT(5) +#define B_BE_PHYINTF_ERR_IND_EN BIT(4) +#define B_BE_DMA_TOP_ERR_IND_EN BIT(3) +#define B_BE_RESP_PKTCTL_ERR_IND_EN BIT(2) +#define B_BE_PTCL_TOP_ERR_IND_EN BIT(1) +#define B_BE_SCHEDULE_TOP_ERR_IND_EN BIT(0) + +#define R_BE_CMAC_ERR_ISR 0x10164 +#define R_BE_CMAC_ERR_ISR_C1 0x14164 +#define B_BE_CMAC_FW_ERR_IDCT BIT(16) +#define B_BE_PTCL_TX_IDLETO_IDCT BIT(9) +#define B_BE_WMAC_RX_IDLETO_IDCT BIT(8) +#define B_BE_WMAC_TX_ERR_IND BIT(7) +#define B_BE_WMAC_RX_ERR_IND BIT(6) +#define B_BE_TXPWR_CTRL_ERR_IND BIT(5) +#define B_BE_PHYINTF_ERR_IND BIT(4) +#define B_BE_DMA_TOP_ERR_IND BIT(3) +#define B_BE_RESP_PKTCTL_ERR_IDCT BIT(2) +#define B_BE_PTCL_TOP_ERR_IND BIT(1) +#define B_BE_SCHEDULE_TOP_ERR_IND BIT(0) + +#define R_BE_CMAC_FW_TRIGGER_IDCT_ISR 0x10168 +#define R_BE_CMAC_FW_TRIGGER_IDCT_ISR_C1 0x14168 +#define B_BE_CMAC_FW_ERR_IDCT_IMR BIT(31) +#define B_BE_CMAC_FW_TRIG_IDCT BIT(0) + +#define R_BE_SER_L0_DBG_CNT 0x10170 +#define R_BE_SER_L0_DBG_CNT_C1 0x14170 +#define B_BE_SER_L0_PHYINTF_CNT_MASK GENMASK(31, 24) +#define B_BE_SER_L0_DMA_CNT_MASK GENMASK(23, 16) +#define B_BE_SER_L0_PTCL_CNT_MASK GENMASK(15, 8) +#define B_BE_SER_L0_SCH_CNT_MASK GENMASK(7, 0) + +#define R_BE_SER_L0_DBG_CNT1 0x10174 +#define R_BE_SER_L0_DBG_CNT1_C1 0x14174 +#define B_BE_SER_L0_TMAC_COUNTER_MASK GENMASK(23, 16) +#define B_BE_SER_L0_RMAC_COUNTER_MASK GENMASK(15, 8) +#define B_BE_SER_L0_TXPWR_COUNTER_MASK GENMASK(7, 0) + +#define R_BE_SER_L0_DBG_CNT2 0x10178 +#define R_BE_SER_L0_DBG_CNT2_C1 0x14178 + +#define R_BE_SER_L0_DBG_CNT3 0x1017C +#define R_BE_SER_L0_DBG_CNT3_C1 0x1417C +#define B_BE_SER_L0_SUBMODULE_BIT31_CNT BIT(31) +#define B_BE_SER_L0_SUBMODULE_BIT30_CNT BIT(30) +#define B_BE_SER_L0_SUBMODULE_BIT29_CNT BIT(29) +#define B_BE_SER_L0_SUBMODULE_BIT28_CNT BIT(28) +#define B_BE_SER_L0_SUBMODULE_BIT27_CNT BIT(27) +#define B_BE_SER_L0_SUBMODULE_BIT26_CNT BIT(26) +#define B_BE_SER_L0_SUBMODULE_BIT25_CNT BIT(25) +#define B_BE_SER_L0_SUBMODULE_BIT24_CNT BIT(24) +#define B_BE_SER_L0_SUBMODULE_BIT23_CNT BIT(23) +#define B_BE_SER_L0_SUBMODULE_BIT22_CNT BIT(22) +#define B_BE_SER_L0_SUBMODULE_BIT21_CNT BIT(21) +#define B_BE_SER_L0_SUBMODULE_BIT20_CNT BIT(20) +#define B_BE_SER_L0_SUBMODULE_BIT19_CNT BIT(19) +#define B_BE_SER_L0_SUBMODULE_BIT18_CNT BIT(18) +#define B_BE_SER_L0_SUBMODULE_BIT17_CNT BIT(17) +#define B_BE_SER_L0_SUBMODULE_BIT16_CNT BIT(16) +#define B_BE_SER_L0_SUBMODULE_BIT15_CNT BIT(15) +#define B_BE_SER_L0_SUBMODULE_BIT14_CNT BIT(14) +#define B_BE_SER_L0_SUBMODULE_BIT13_CNT BIT(13) +#define B_BE_SER_L0_SUBMODULE_BIT12_CNT BIT(12) +#define B_BE_SER_L0_SUBMODULE_BIT11_CNT BIT(11) +#define B_BE_SER_L0_SUBMODULE_BIT10_CNT BIT(10) +#define B_BE_SER_L0_SUBMODULE_BIT9_CNT BIT(9) +#define B_BE_SER_L0_SUBMODULE_BIT8_CNT BIT(8) +#define B_BE_SER_L0_SUBMODULE_BIT7_CNT BIT(7) +#define B_BE_SER_L0_SUBMODULE_BIT6_CNT BIT(6) +#define B_BE_SER_L0_SUBMODULE_BIT5_CNT BIT(5) +#define B_BE_SER_L0_SUBMODULE_BIT4_CNT BIT(4) +#define B_BE_SER_L0_SUBMODULE_BIT3_CNT BIT(3) +#define B_BE_SER_L0_SUBMODULE_BIT2_CNT BIT(2) +#define B_BE_SER_L0_SUBMODULE_BIT1_CNT BIT(1) +#define B_BE_SER_L0_SUBMODULE_BIT0_CNT BIT(0) + +#define R_BE_PORT_0_TSF_SYNC 0x102A0 +#define R_BE_PORT_0_TSF_SYNC_C1 0x142A0 +#define B_BE_P0_SYNC_NOW_P BIT(30) +#define B_BE_P0_SYNC_ONCE_P BIT(29) +#define B_BE_P0_AUTO_SYNC BIT(28) +#define B_BE_P0_SYNC_PORT_SRC_SEL_MASK GENMASK(26, 24) +#define B_BE_P0_TSFTR_SYNC_OFFSET_MASK GENMASK(18, 0) + +#define R_BE_SCH_EDCA_RST_CFG 0x102E4 +#define R_BE_SCH_EDCA_RST_CFG_C1 0x142E4 +#define B_BE_EDCCA_S160_RST_EDCA_EN BIT(23) +#define B_BE_EDCCA_S80_RST_EDCA_EN BIT(22) +#define B_BE_EDCCA_S40_RST_EDCA_EN BIT(21) +#define B_BE_EDCCA_S20_RST_EDCA_EN BIT(20) +#define B_BE_OFDM_CCA_S160_RST_EDCA_EN BIT(19) +#define B_BE_CCA_PEB_BE_BITMAP_RST_EDCA_EN BIT(18) +#define B_BE_RX_INTRA_NAV_RST_EDCA_EN BIT(15) +#define B_BE_RX_BASIC_NAV_RST_EDCA_EN BIT(14) +#define B_BE_EDCCA_PER20_BITMAP_SIFS_RST_EDCA_EN BIT(10) +#define B_BE_TX_NAV_RST_EDCA_EN BIT(7) +#define B_BE_NO_GNT_WL_RST_EDCA_EN BIT(5) +#define B_BE_EDCCA_P20_RST_EDCA_EN BIT(4) +#define B_BE_OFDM_CCA_S80_RST_EDCA_EN BIT(3) +#define B_BE_OFDM_CCA_S40_RST_EDCA_EN BIT(2) +#define B_BE_OFDM_CCA_S20_RST_EDCA_EN BIT(1) +#define B_BE_CCA_P20_RST_EDCA_EN BIT(0) + +#define R_BE_EDCA_BCNQ_PARAM 0x10324 +#define R_BE_EDCA_BCNQ_PARAM_C1 0x14324 +#define B_BE_BCNQ_CW_MASK GENMASK(31, 24) +#define B_BE_BCNQ_AIFS_MASK GENMASK(23, 16) +#define BCN_IFS_25US 0x19 +#define B_BE_PIFS_MASK GENMASK(15, 8) +#define B_BE_FORCE_BCN_IFS_MASK GENMASK(7, 0) + +#define R_BE_PREBKF_CFG_0 0x10338 +#define R_BE_PREBKF_CFG_0_C1 0x14338 +#define B_BE_100NS_TIME_MASK GENMASK(28, 24) +#define B_BE_RX_AIR_END_TIME_MASK GENMASK(22, 16) +#define B_BE_MACTX_LATENCY_MASK GENMASK(10, 8) +#define B_BE_PREBKF_TIME_MASK GENMASK(4, 0) + +#define R_BE_PREBKF_CFG_1 0x1033C +#define R_BE_PREBKF_CFG_1_C1 0x1433C +#define B_BE_SIFS_TIMEOUT_TB_AGGR_MASK GENMASK(31, 24) +#define B_BE_SIFS_PREBKF_MASK GENMASK(23, 16) +#define B_BE_SIFS_TIMEOUT_T2_MASK GENMASK(14, 8) +#define B_BE_SIFS_MACTXEN_T1_MASK GENMASK(6, 0) + +#define R_BE_CCA_CFG_0 0x10340 +#define R_BE_CCA_CFG_0_C1 0x14340 +#define B_BE_R_SIFS_AGGR_TIME_V1_MASK GENMASK(31, 24) +#define B_BE_EDCCA_SEC160_EN BIT(23) +#define B_BE_EDCCA_SEC80_EN BIT(22) +#define B_BE_EDCCA_SEC40_EN BIT(21) +#define B_BE_EDCCA_SEC20_EN BIT(20) +#define B_BE_SEC160_EN BIT(19) +#define B_BE_CCA_BITMAP_EN BIT(18) +#define B_BE_TXPKTCTL_RST_EDCA_EN BIT(17) +#define B_BE_WMAC_RST_EDCA_EN BIT(16) +#define B_BE_TXFAIL_BRK_TXOP_EN BIT(11) +#define B_BE_EDCCA_PER20_BITMAP_SIFS_EN BIT(10) +#define B_BE_NO_GNT_WL_BRK_TXOP_EN BIT(9) +#define B_BE_NAV_BRK_TXOP_EN BIT(8) +#define B_BE_TX_NAV_EN BIT(7) +#define B_BE_BCN_IGNORE_EDCCA BIT(6) +#define B_BE_NO_GNT_WL_EN BIT(5) +#define B_BE_EDCCA_EN BIT(4) +#define B_BE_SEC80_EN BIT(3) +#define B_BE_SEC40_EN BIT(2) +#define B_BE_SEC20_EN BIT(1) +#define B_BE_CCA_EN BIT(0) + +#define R_BE_CTN_CFG_0 0x1034C +#define R_BE_CTN_CFG_0_C1 0x1434C +#define B_BE_OTHER_LINK_BKF_BLK_TX_THD_MASK GENMASK(30, 24) +#define B_BE_CCK_SIFS_COMP_MASK GENMASK(22, 16) +#define B_BE_PIFS_TIMEUNIT_MASK GENMASK(15, 14) +#define B_BE_PREBKF_TIME_NONAC_MASK GENMASK(12, 8) +#define B_BE_SR_TX_EN BIT(2) +#define B_BE_NAV_BLK_MGQ BIT(1) +#define B_BE_NAV_BLK_HGQ BIT(0) + +#define R_BE_MUEDCA_BE_PARAM_0 0x10350 +#define R_BE_MUEDCA_BK_PARAM_0 0x10354 +#define R_BE_MUEDCA_VI_PARAM_0 0x10358 +#define R_BE_MUEDCA_VO_PARAM_0 0x1035C + +#define R_BE_MUEDCA_EN 0x10370 +#define R_BE_MUEDCA_EN_C1 0x14370 +#define B_BE_SIFS_TIMEOUT_TB_T2_MASK GENMASK(30, 24) +#define B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK GENMASK(23, 16) +#define B_BE_SIFS_MACTXEN_TB_T1_MASK GENMASK(22, 16) +#define B_BE_MUEDCA_WMM_SEL BIT(8) +#define B_BE_SET_MUEDCATIMER_TF_MASK GENMASK(5, 4) +#define B_BE_SET_MUEDCATIMER_TF_0 BIT(4) +#define B_BE_MUEDCA_EN_MASK GENMASK(1, 0) +#define B_BE_MUEDCA_EN_0 BIT(0) + +#define R_BE_MISC_1 0x1037C +#define R_BE_MISC_1_C1 0x1437C +#define B_BE_PPS_REMAIN_TIME_MODE BIT(31) +#define B_BE_PPS_IDLE_SORT_EN BIT(30) +#define B_BE_SR_TXOP_USE_SR_PERIOD_EN BIT(29) +#define B_BE_SCH_CCA_PIFS_CLK_GATING_DIS BIT(28) +#define B_BE_SR_TXOP_EN BIT(27) +#define B_BE_SCH_ABORT_CNT_SIFS_EN BIT(26) +#define B_BE_SCH_ABORT_CNT_TB_EN BIT(25) +#define B_BE_SCH_ABORT_CNT_CTN_EN BIT(24) +#define B_BE_SR_CCA_PER20_BITMAP_EN BIT(23) +#define B_BE_SR_CCA_S80_EN BIT(22) +#define B_BE_SR_CCA_S40_EN BIT(21) +#define B_BE_SR_CCA_S20_EN BIT(20) +#define B_BE_EN_TX_FINISH_PRD_RESP BIT(18) +#define B_BE_RESP_TX_ABORT_NON_IDLE BIT(17) +#define B_BE_RESP_TX_ABORT_QUICK_EN BIT(16) +#define B_BE_PREBKF_CHK_LINK_BUSY BIT(15) +#define B_BE_SCH_MSD_PRD_RST_EDCA_EN BIT(14) +#define B_BE_LINK_BUSY_RST_EDCA_EN_MASK GENMASK(13, 12) +#define B_BE_RX_TSFT_SYNC_BYPASS_FCS BIT(11) +#define B_BE_RX_TSFT_DIFF_THD_MASK GENMASK(10, 8) +#define B_BE_CAL_TBTT_OV_EN BIT(5) +#define B_BE_SUBBCN_MS_CNT_MODE BIT(3) +#define B_BE_CAL_ALWAYS_EN BIT(2) +#define B_BE_SIFS_TIMER_AUTO_RST_EN BIT(1) +#define B_BE_CHK_HAS_SIFS_TX_ABORT BIT(0) + +#define R_BE_CTN_DRV_TXEN 0x10398 +#define R_BE_CTN_DRV_TXEN_C1 0x14398 +#define B_BE_CTN_TXEN_TWT_3 BIT(17) +#define B_BE_CTN_TXEN_TWT_2 BIT(16) +#define B_BE_CTN_TXEN_TWT_1 BIT(15) +#define B_BE_CTN_TXEN_TWT_0 BIT(14) +#define B_BE_CTN_TXEN_ULQ BIT(13) +#define B_BE_CTN_TXEN_BCNQ BIT(12) +#define B_BE_CTN_TXEN_HGQ BIT(11) +#define B_BE_CTN_TXEN_CPUMGQ BIT(10) +#define B_BE_CTN_TXEN_MGQ1 BIT(9) +#define B_BE_CTN_TXEN_MGQ BIT(8) +#define B_BE_CTN_TXEN_VO_1 BIT(7) +#define B_BE_CTN_TXEN_VI_1 BIT(6) +#define B_BE_CTN_TXEN_BK_1 BIT(5) +#define B_BE_CTN_TXEN_BE_1 BIT(4) +#define B_BE_CTN_TXEN_VO_0 BIT(3) +#define B_BE_CTN_TXEN_VI_0 BIT(2) +#define B_BE_CTN_TXEN_BK_0 BIT(1) +#define B_BE_CTN_TXEN_BE_0 BIT(0) +#define B_BE_CTN_TXEN_ALL_MASK GENMASK(17, 0) + +#define R_BE_TB_CHK_CCA_NAV 0x103AC +#define R_BE_TB_CHK_CCA_NAV_C1 0x143AC +#define B_BE_TB_CHK_TX_NAV BIT(15) +#define B_BE_TB_CHK_INTRA_NAV BIT(14) +#define B_BE_TB_CHK_BASIC_NAV BIT(13) +#define B_BE_TB_CHK_NO_GNT_WL BIT(12) +#define B_BE_TB_CHK_EDCCA_S160 BIT(11) +#define B_BE_TB_CHK_EDCCA_S80 BIT(10) +#define B_BE_TB_CHK_EDCCA_S40 BIT(9) +#define B_BE_TB_CHK_EDCCA_S20 BIT(8) +#define B_BE_TB_CHK_CCA_S160 BIT(7) +#define B_BE_TB_CHK_CCA_S80 BIT(6) +#define B_BE_TB_CHK_CCA_S40 BIT(5) +#define B_BE_TB_CHK_CCA_S20 BIT(4) +#define B_BE_TB_CHK_EDCCA_BITMAP BIT(3) +#define B_BE_TB_CHK_CCA_BITMAP BIT(2) +#define B_BE_TB_CHK_EDCCA_P20 BIT(1) +#define B_BE_TB_CHK_CCA_P20 BIT(0) + +#define R_BE_HE_SIFS_CHK_CCA_NAV 0x103B4 +#define R_BE_HE_SIFS_CHK_CCA_NAV_C1 0x143B4 +#define B_BE_HE_SIFS_CHK_TX_NAV BIT(15) +#define B_BE_HE_SIFS_CHK_INTRA_NAV BIT(14) +#define B_BE_HE_SIFS_CHK_BASIC_NAV BIT(13) +#define B_BE_HE_SIFS_CHK_NO_GNT_WL BIT(12) +#define B_BE_HE_SIFS_CHK_EDCCA_S160 BIT(11) +#define B_BE_HE_SIFS_CHK_EDCCA_S80 BIT(10) +#define B_BE_HE_SIFS_CHK_EDCCA_S40 BIT(9) +#define B_BE_HE_SIFS_CHK_EDCCA_S20 BIT(8) +#define B_BE_HE_SIFS_CHK_CCA_S160 BIT(7) +#define B_BE_HE_SIFS_CHK_CCA_S80 BIT(6) +#define B_BE_HE_SIFS_CHK_CCA_S40 BIT(5) +#define B_BE_HE_SIFS_CHK_CCA_S20 BIT(4) +#define B_BE_HE_SIFS_CHK_EDCCA_BITMAP BIT(3) +#define B_BE_HE_SIFS_CHK_CCA_BITMAP BIT(2) +#define B_BE_HE_SIFS_CHK_EDCCA_P20 BIT(1) +#define B_BE_HE_SIFS_CHK_CCA_P20 BIT(0) + +#define R_BE_HE_CTN_CHK_CCA_NAV 0x103C4 +#define R_BE_HE_CTN_CHK_CCA_NAV_C1 0x143C4 +#define B_BE_HE_CTN_CHK_TX_NAV BIT(15) +#define B_BE_HE_CTN_CHK_INTRA_NAV BIT(14) +#define B_BE_HE_CTN_CHK_BASIC_NAV BIT(13) +#define B_BE_HE_CTN_CHK_NO_GNT_WL BIT(12) +#define B_BE_HE_CTN_CHK_EDCCA_S160 BIT(11) +#define B_BE_HE_CTN_CHK_EDCCA_S80 BIT(10) +#define B_BE_HE_CTN_CHK_EDCCA_S40 BIT(9) +#define B_BE_HE_CTN_CHK_EDCCA_S20 BIT(8) +#define B_BE_HE_CTN_CHK_CCA_S160 BIT(7) +#define B_BE_HE_CTN_CHK_CCA_S80 BIT(6) +#define B_BE_HE_CTN_CHK_CCA_S40 BIT(5) +#define B_BE_HE_CTN_CHK_CCA_S20 BIT(4) +#define B_BE_HE_CTN_CHK_EDCCA_BITMAP BIT(3) +#define B_BE_HE_CTN_CHK_CCA_BITMAP BIT(2) +#define B_BE_HE_CTN_CHK_EDCCA_P20 BIT(1) +#define B_BE_HE_CTN_CHK_CCA_P20 BIT(0) + +#define R_BE_SCHEDULE_ERR_IMR 0x103E8 +#define R_BE_SCHEDULE_ERR_IMR_C1 0x143E8 +#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0) +#define B_BE_SCHEDULE_ERR_IMR_CLR B_BE_FSM_TIMEOUT_ERR_INT_EN +#define B_BE_SCHEDULE_ERR_IMR_SET B_BE_FSM_TIMEOUT_ERR_INT_EN + +#define R_BE_SCHEDULE_ERR_ISR 0x103EC +#define R_BE_SCHEDULE_ERR_ISR_C1 0x143EC +#define B_BE_SORT_NON_IDLE_ERR_INT BIT(1) +#define B_BE_FSM_TIMEOUT_ERR_INT BIT(0) + +#define R_BE_PORT_CFG_P0 0x10400 +#define R_BE_PORT_CFG_P0_C1 0x14400 +#define B_BE_BCN_ERLY_SORT_EN_P0 BIT(18) +#define B_BE_PROHIB_END_CAL_EN_P0 BIT(17) +#define B_BE_BRK_SETUP_P0 BIT(16) +#define B_BE_TBTT_UPD_SHIFT_SEL_P0 BIT(15) +#define B_BE_BCN_DROP_ALLOW_P0 BIT(14) +#define B_BE_TBTT_PROHIB_EN_P0 BIT(13) +#define B_BE_BCNTX_EN_P0 BIT(12) +#define B_BE_NET_TYPE_P0_MASK GENMASK(11, 10) +#define B_BE_BCN_FORCETX_EN_P0 BIT(9) +#define B_BE_TXBCN_BTCCA_EN_P0 BIT(8) +#define B_BE_BCNERR_CNT_EN_P0 BIT(7) +#define B_BE_BCN_AGRES_P0 BIT(6) +#define B_BE_TSFTR_RST_P0 BIT(5) +#define B_BE_RX_BSSID_FIT_EN_P0 BIT(4) +#define B_BE_TSF_UDT_EN_P0 BIT(3) +#define B_BE_PORT_FUNC_EN_P0 BIT(2) +#define B_BE_TXBCN_RPT_EN_P0 BIT(1) +#define B_BE_RXBCN_RPT_EN_P0 BIT(0) + +#define R_BE_TBTT_PROHIB_P0 0x10404 +#define R_BE_TBTT_PROHIB_P0_C1 0x14404 +#define B_BE_TBTT_HOLD_P0_MASK GENMASK(27, 16) +#define B_BE_TBTT_SETUP_P0_MASK GENMASK(7, 0) + +#define R_BE_BCN_AREA_P0 0x10408 +#define R_BE_BCN_AREA_P0_C1 0x14408 +#define B_BE_BCN_MSK_AREA_P0_MSK 0xfff +#define B_BE_BCN_CTN_AREA_P0_MASK GENMASK(11, 0) + +#define R_BE_BCNERLYINT_CFG_P0 0x1040C +#define R_BE_BCNERLYINT_CFG_P0_C1 0x1440C +#define B_BE_BCNERLY_P0_MASK GENMASK(11, 0) + +#define R_BE_TBTTERLYINT_CFG_P0 0x1040E +#define R_BE_TBTTERLYINT_CFG_P0_C1 0x1440E +#define B_BE_TBTTERLY_P0_MASK GENMASK(11, 0) + +#define R_BE_TBTT_AGG_P0 0x10412 +#define R_BE_TBTT_AGG_P0_C1 0x14412 +#define B_BE_TBTT_AGG_NUM_P0_MASK GENMASK(15, 8) + +#define R_BE_BCN_SPACE_CFG_P0 0x10414 +#define R_BE_BCN_SPACE_CFG_P0_C1 0x14414 +#define B_BE_SUB_BCN_SPACE_P0_MASK GENMASK(23, 16) +#define B_BE_BCN_SPACE_P0_MASK GENMASK(15, 0) + +#define R_BE_BCN_FORCETX_P0 0x10418 +#define R_BE_BCN_FORCETX_P0_C1 0x14418 +#define B_BE_FORCE_BCN_NUM_P0_MASK GENMASK(15, 8) +#define B_BE_BCN_MAX_ERR_P0_MASK GENMASK(7, 0) + +#define R_BE_BCN_ERR_CNT_P0 0x10420 +#define R_BE_BCN_ERR_CNT_P0_C1 0x14420 +#define B_BE_BCN_ERR_CNT_SUM_P0_MASK GENMASK(31, 24) +#define B_BE_BCN_ERR_CNT_NAV_P0_MASK GENMASK(23, 16) +#define B_BE_BCN_ERR_CNT_EDCCA_P0_MASK GENMASK(15, 8) +#define B_BE_BCN_ERR_CNT_CCA_P0_MASK GENMASK(7, 0) + +#define R_BE_BCN_ERR_FLAG_P0 0x10424 +#define R_BE_BCN_ERR_FLAG_P0_C1 0x14424 +#define B_BE_BCN_ERR_FLAG_SRCHEND_P0 BIT(3) +#define B_BE_BCN_ERR_FLAG_INVALID_P0 BIT(2) +#define B_BE_BCN_ERR_FLAG_CMP_P0 BIT(1) +#define B_BE_BCN_ERR_FLAG_LOCK_P0 BIT(0) + +#define R_BE_DTIM_CTRL_P0 0x10426 +#define R_BE_DTIM_CTRL_P0_C1 0x14426 +#define B_BE_DTIM_NUM_P0_MASK GENMASK(15, 8) +#define B_BE_DTIM_CURRCNT_P0_MASK GENMASK(7, 0) + +#define R_BE_TBTT_SHIFT_P0 0x10428 +#define R_BE_TBTT_SHIFT_P0_C1 0x14428 +#define B_BE_TBTT_SHIFT_OFST_P0_SH 0 +#define B_BE_TBTT_SHIFT_OFST_P0_MSK 0xfff + +#define R_BE_BCN_CNT_TMR_P0 0x10434 +#define R_BE_BCN_CNT_TMR_P0_C1 0x14434 +#define B_BE_BCN_CNT_TMR_P0_MASK GENMASK(31, 0) + +#define R_BE_TSFTR_LOW_P0 0x10438 +#define R_BE_TSFTR_LOW_P0_C1 0x14438 +#define B_BE_TSFTR_LOW_P0_MASK GENMASK(31, 0) + +#define R_BE_TSFTR_HIGH_P0 0x1043C +#define R_BE_TSFTR_HIGH_P0_C1 0x1443C +#define B_BE_TSFTR_HIGH_P0_MASK GENMASK(31, 0) + +#define R_BE_BCN_DROP_ALL0 0x10560 + +#define R_BE_MBSSID_CTRL 0x10568 +#define R_BE_MBSSID_CTRL_C1 0x14568 +#define B_BE_MBSSID_MODE_SEL BIT(20) +#define B_BE_P0MB_NUM_MASK GENMASK(19, 16) +#define B_BE_P0MB15_EN BIT(15) +#define B_BE_P0MB14_EN BIT(14) +#define B_BE_P0MB13_EN BIT(13) +#define B_BE_P0MB12_EN BIT(12) +#define B_BE_P0MB11_EN BIT(11) +#define B_BE_P0MB10_EN BIT(10) +#define B_BE_P0MB9_EN BIT(9) +#define B_BE_P0MB8_EN BIT(8) +#define B_BE_P0MB7_EN BIT(7) +#define B_BE_P0MB6_EN BIT(6) +#define B_BE_P0MB5_EN BIT(5) +#define B_BE_P0MB4_EN BIT(4) +#define B_BE_P0MB3_EN BIT(3) +#define B_BE_P0MB2_EN BIT(2) +#define B_BE_P0MB1_EN BIT(1) + +#define R_BE_P0MB_HGQ_WINDOW_CFG_0 0x10590 +#define R_BE_P0MB_HGQ_WINDOW_CFG_0_C1 0x14590 +#define R_BE_PORT_HGQ_WINDOW_CFG 0x105A0 +#define R_BE_PORT_HGQ_WINDOW_CFG_C1 0x145A0 + +#define R_BE_PTCL_COMMON_SETTING_0 0x10800 +#define R_BE_PTCL_COMMON_SETTING_0_C1 0x14800 +#define B_BE_PCIE_MODE_MASK GENMASK(15, 14) +#define B_BE_CPUMGQ_LIFETIME_EN BIT(8) +#define B_BE_MGQ_LIFETIME_EN BIT(7) +#define B_BE_LIFETIME_EN BIT(6) +#define B_BE_DIS_PTCL_CLK_GATING BIT(5) +#define B_BE_PTCL_TRIGGER_SS_EN_UL BIT(4) +#define B_BE_PTCL_TRIGGER_SS_EN_1 BIT(3) +#define B_BE_PTCL_TRIGGER_SS_EN_0 BIT(2) +#define B_BE_CMAC_TX_MODE_1 BIT(1) +#define B_BE_CMAC_TX_MODE_0 BIT(0) + +#define R_BE_AGG_BK_0 0x10804 +#define R_BE_AGG_BK_0_C1 0x14804 +#define B_BE_DIS_SAMPDU_TXIME_SR_CHECK BIT(24) +#define B_BE_TX_PAIR_MACID_LEN_EN BIT(23) +#define B_BE_DIS_SND_STS_CHECK_SU BIT(22) +#define B_BE_MAX_AGG_NUM_FIX_MODE_EN_V1 BIT(21) +#define B_BE_DIS_SIFS_BK_AGG_AMPDU BIT(20) +#define B_BE_EN_MU2SU_CHK_PROTECT_PPDU BIT(19) +#define B_BE_RPT_TXOP_START_PROTECT BIT(18) +#define B_BE_RANDOM_GEN_CMD_ABORT_EN BIT(17) +#define B_BE_PHYTXON_ENDPS_RESP_CHK BIT(16) +#define B_BE_CTN_CHK_SEQ_REQ_EN BIT(15) +#define B_BE_PTCL_RLS_ALLFAIL_EN BIT(14) +#define B_BE_DIS_MURU_PRI_Q_EMPTY_CHK BIT(13) +#define B_BE_DIS_MURU_SEC_Q_EMPTY_CHK BIT(12) +#define B_BE_EN_SAMPDU_TXIME_TWT_CHECK BIT(11) +#define B_BE_DIS_SAMPDU_TXIME_P2P_CHECK BIT(10) +#define B_BE_DIS_SAMPDU_TXIME_BCN_CHECK BIT(9) +#define B_BE_DIS_UL_SEQ_ABORT_CHECK BIT(8) +#define B_BE_DIS_SND_STS_CHECK BIT(7) +#define B_BE_NAV_PAUS_PHB_EN BIT(6) +#define B_BE_TXOP_SHT_PHB_EN BIT(5) +#define B_BE_AGG_BRK_PHB_EN BIT(4) +#define B_BE_DIS_SSN_CHK BIT(3) +#define B_BE_WDBK_CFG BIT(2) +#define B_BE_EN_RTY_BK BIT(1) +#define B_BE_EN_RTY_BK_COD BIT(0) + +#define R_BE_TB_PPDU_CTRL 0x1080C +#define R_BE_TB_PPDU_CTRL_C1 0x1480C +#define B_BE_TB_PPDU_BK_DIS BIT(15) +#define B_BE_TB_PPDU_BE_DIS BIT(14) +#define B_BE_TB_PPDU_VI_DIS BIT(13) +#define B_BE_TB_PPDU_VO_DIS BIT(12) +#define B_BE_QOSNULL_UPD_MUEDCA_EN BIT(3) +#define B_BE_TB_BYPASS_TXPWR BIT(2) +#define B_BE_SW_PREFER_AC_MASK GENMASK(1, 0) + +#define R_BE_AMPDU_AGG_LIMIT 0x10810 +#define R_BE_AMPDU_AGG_LIMIT_C1 0x14810 +#define B_BE_AMPDU_MAX_TIME_MASK GENMASK(31, 24) +#define AMPDU_MAX_TIME 0x9E +#define AMPDU_MAX_TIME_V1 0xA4 +#define B_BE_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) +#define B_BE_RTS_MAX_AGG_NUM_MASK GENMASK(15, 8) +#define B_BE_MAX_AGG_NUM_MASK GENMASK(7, 0) +#define MAX_TX_AMPDU_NUM_V1 128 + +#define R_BE_AGG_LEN_HT_0 0x10814 +#define R_BE_AGG_LEN_HT_0_C1 0x14814 +#define B_BE_AMPDU_MAX_LEN_HT_MASK GENMASK(31, 16) +#define B_BE_RTS_TXTIME_TH_MASK GENMASK(15, 8) +#define B_BE_RTS_LEN_TH_MASK GENMASK(7, 0) + +#define R_BE_SPECIAL_TX_SETTING 0x10820 +#define R_BE_SPECIAL_TX_SETTING_C1 0x14820 +#define B_BE_TRI_PADDING_EXTEND BIT(31) +#define B_BE_TX_SN_BYPASS_EN BIT(30) +#define B_BE_USE_DATA_BW BIT(29) +#define B_BE_BW_SIGTA_MASK GENMASK(28, 27) +#define B_BE_BMC_NAV_PROTECT BIT(26) +#define B_BE_F2P_KEEP_NON_SR_CMD BIT(25) +#define B_BE_F2P_SU_FIXRATE_OVER_WD BIT(24) +#define B_BE_BAR_TXRATE_FOR_NULL_WD_MASK GENMASK(23, 20) +#define B_BE_STBC_CFEND_MASK GENMASK(19, 18) +#define B_BE_STBC_CFEND_RATE_MASK GENMASK(17, 9) +#define B_BE_BASIC_CFEND_RATE_MASK GENMASK(8, 0) + +#define R_BE_SIFS_SETTING 0x10824 +#define R_BE_SIFS_SETTING_C1 0x14824 +#define B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK GENMASK(31, 24) +#define B_BE_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK GENMASK(23, 18) +#define B_BE_HW_CTS2SELF_EN BIT(16) +#define B_BE_SPEC_SIFS_OFDM_PTCL_MASK GENMASK(15, 8) +#define B_BE_SPEC_SIFS_CCK_PTCL_MASK GENMASK(7, 0) + +#define R_BE_TXRATE_CHK 0x10828 +#define R_BE_TXRATE_CHK_C1 0x14828 +#define B_BE_LATENCY_PADDING_PKT_TH_MASK GENMASK(31, 24) +#define B_BE_PLCP_FETCH_BUFF_MASK GENMASK(23, 16) +#define B_BE_OFDM_CCK_ERR_PROC BIT(6) +#define B_BE_PKT_LAST_TX BIT(5) +#define B_BE_BAND_MODE BIT(4) +#define B_BE_MAX_TXNSS_MASK GENMASK(3, 2) +#define B_BE_RTS_LIMIT_IN_OFDM6 BIT(1) +#define B_BE_CHECK_CCK_EN BIT(0) + +#define R_BE_TXCNT 0x1082C +#define R_BE_TXCNT_C1 0x1482C +#define B_BE_ADD_TXCNT_BY BIT(31) +#define B_BE_TOTAL_TC_OPT BIT(30) +#define B_BE_S_TXCNT_LMT_MASK GENMASK(29, 24) +#define B_BE_L_TXCNT_LMT_MASK GENMASK(21, 16) + +#define R_BE_MBSSID_DROP_0 0x1083C +#define R_BE_MBSSID_DROP_0_C1 0x1483C +#define B_BE_GI_LTF_FB_SEL BIT(30) +#define B_BE_RATE_SEL_MASK GENMASK(29, 24) +#define B_BE_PORT_DROP_4_0_MASK GENMASK(20, 16) +#define B_BE_MBSSID_DROP_15_0_MASK GENMASK(15, 0) + +#define R_BE_PTCL_PRELD_CTRL 0x10868 +#define R_BE_PTCL_PRELD_CTRL_C1 0x14868 +#define B_BE_PRELD_MGQ2_EN BIT(22) +#define B_BE_PRELD_MGQ1_EN BIT(21) +#define B_BE_PRELD_MGQ0_EN BIT(20) +#define B_BE_PRELD_HIQ_P4_EN BIT(19) +#define B_BE_PRELD_HIQ_P3_EN BIT(18) +#define B_BE_PRELD_HIQ_P2_EN BIT(17) +#define B_BE_PRELD_HIQ_P1_EN BIT(16) +#define B_BE_PRELD_HIQ_P0MB15_EN BIT(15) +#define B_BE_PRELD_HIQ_P0MB14_EN BIT(14) +#define B_BE_PRELD_HIQ_P0MB13_EN BIT(13) +#define B_BE_PRELD_HIQ_P0MB12_EN BIT(12) +#define B_BE_PRELD_HIQ_P0MB11_EN BIT(11) +#define B_BE_PRELD_HIQ_P0MB10_EN BIT(10) +#define B_BE_PRELD_HIQ_P0MB9_EN BIT(9) +#define B_BE_PRELD_HIQ_P0MB8_EN BIT(8) +#define B_BE_PRELD_HIQ_P0MB7_EN BIT(7) +#define B_BE_PRELD_HIQ_P0MB6_EN BIT(6) +#define B_BE_PRELD_HIQ_P0MB5_EN BIT(5) +#define B_BE_PRELD_HIQ_P0MB4_EN BIT(4) +#define B_BE_PRELD_HIQ_P0MB3_EN BIT(3) +#define B_BE_PRELD_HIQ_P0MB2_EN BIT(2) +#define B_BE_PRELD_HIQ_P0MB1_EN BIT(1) +#define B_BE_PRELD_HIQ_P0_EN BIT(0) +#define B_BE_PRELD_HIQ_ALL_EN (B_BE_PRELD_HIQ_P0_EN | B_BE_PRELD_HIQ_P1_EN | \ + B_BE_PRELD_HIQ_P2_EN | B_BE_PRELD_HIQ_P3_EN | \ + B_BE_PRELD_HIQ_P4_EN) +#define B_BE_PRELD_HIQ_P0MB_ALL_EN \ + (B_BE_PRELD_HIQ_P0_EN | B_BE_PRELD_HIQ_P0MB1_EN | \ + B_BE_PRELD_HIQ_P0MB2_EN | B_BE_PRELD_HIQ_P0MB3_EN | \ + B_BE_PRELD_HIQ_P0MB4_EN | B_BE_PRELD_HIQ_P0MB5_EN | \ + B_BE_PRELD_HIQ_P0MB6_EN | B_BE_PRELD_HIQ_P0MB7_EN | \ + B_BE_PRELD_HIQ_P0MB8_EN | B_BE_PRELD_HIQ_P0MB9_EN | \ + B_BE_PRELD_HIQ_P0MB10_EN | B_BE_PRELD_HIQ_P0MB11_EN | \ + B_BE_PRELD_HIQ_P0MB12_EN | B_BE_PRELD_HIQ_P0MB13_EN | \ + B_BE_PRELD_HIQ_P0MB14_EN | B_BE_PRELD_HIQ_P0MB15_EN) + +#define R_BE_BT_PLT 0x1087C +#define R_BE_BT_PLT_C1 0x1487C +#define B_BE_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) +#define B_BE_BT_PLT_RST BIT(9) +#define B_BE_PLT_EN BIT(8) +#define B_BE_RX_PLT_GNT_LTE_RX BIT(7) +#define B_BE_RX_PLT_GNT_BT_RX BIT(6) +#define B_BE_RX_PLT_GNT_BT_TX BIT(5) +#define B_BE_RX_PLT_GNT_WL BIT(4) +#define B_BE_TX_PLT_GNT_LTE_RX BIT(3) +#define B_BE_TX_PLT_GNT_BT_RX BIT(2) +#define B_BE_TX_PLT_GNT_BT_TX BIT(1) +#define B_BE_TX_PLT_GNT_WL BIT(0) + +#define R_BE_PTCL_BSS_COLOR_0 0x108A0 +#define R_BE_PTCL_BSS_COLOR_0_C1 0x148A0 +#define B_BE_BSS_COLOB_BE_PORT_3_MASK GENMASK(29, 24) +#define B_BE_BSS_COLOB_BE_PORT_2_MASK GENMASK(21, 16) +#define B_BE_BSS_COLOB_BE_PORT_1_MASK GENMASK(13, 8) +#define B_BE_BSS_COLOB_BE_PORT_0_MASK GENMASK(5, 0) + +#define R_BE_PTCL_BSS_COLOR_1 0x108A4 +#define R_BE_PTCL_BSS_COLOR_1_C1 0x148A4 +#define B_BE_BSS_COLOB_BE_PORT_4_MASK GENMASK(5, 0) + +#define R_BE_PTCL_IMR_2 0x108B8 +#define R_BE_PTCL_IMR_2_C1 0x148B8 +#define B_BE_NO_TRX_TIMEOUT_IMR BIT(1) +#define B_BE_TX_IDLE_TIMEOUT_IMR BIT(0) +#define B_BE_PTCL_IMR_2_CLR B_BE_TX_IDLE_TIMEOUT_IMR +#define B_BE_PTCL_IMR_2_SET 0 + +#define R_BE_PTCL_IMR0 0x108C0 +#define R_BE_PTCL_IMR0_C1 0x148C0 +#define B_BE_PTCL_ERROR_FLAG_IMR BIT(31) +#define B_BE_FSM1_TIMEOUT_ERR_INT_EN BIT(1) +#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0) +#define B_BE_PTCL_IMR0_CLR (B_BE_FSM_TIMEOUT_ERR_INT_EN | \ + B_BE_FSM1_TIMEOUT_ERR_INT_EN | \ + B_BE_PTCL_ERROR_FLAG_IMR) +#define B_BE_PTCL_IMR0_SET (B_BE_FSM_TIMEOUT_ERR_INT_EN | \ + B_BE_FSM1_TIMEOUT_ERR_INT_EN | \ + B_BE_PTCL_ERROR_FLAG_IMR) + +#define R_BE_PTCL_ISR0 0x108C4 +#define R_BE_PTCL_ISR0_C1 0x148C4 +#define B_BE_PTCL_ERROR_FLAG_ISR BIT(31) +#define B_BE_FSM1_TIMEOUT_ERR BIT(1) +#define B_BE_FSM_TIMEOUT_ERR BIT(0) + +#define R_BE_PTCL_IMR1 0x108C8 +#define R_BE_PTCL_IMR1_C1 0x148C8 +#define B_BE_F2PCMD_PKTID_IMR BIT(30) +#define B_BE_F2PCMD_RD_PKTID_IMR BIT(29) +#define B_BE_F2PCMD_ASSIGN_PKTID_IMR BIT(28) +#define B_BE_F2PCMD_USER_ALLC_IMR BIT(27) +#define B_BE_RX_SPF_U0_PKTID_IMR BIT(26) +#define B_BE_TX_SPF_U1_PKTID_IMR BIT(25) +#define B_BE_TX_SPF_U2_PKTID_IMR BIT(24) +#define B_BE_TX_SPF_U3_PKTID_IMR BIT(23) +#define B_BE_TX_RECORD_PKTID_IMR BIT(22) +#define B_BE_TWTSP_QSEL_IMR BIT(14) +#define B_BE_F2P_RLS_CTN_SEL_IMR BIT(13) +#define B_BE_BCNQ_ORDER_IMR BIT(12) +#define B_BE_Q_PKTID_IMR BIT(11) +#define B_BE_D_PKTID_IMR BIT(10) +#define B_BE_TXPRT_FULL_DROP_IMR BIT(9) +#define B_BE_F2PCMDRPT_FULL_DROP_IMR BIT(8) +#define B_BE_PTCL_IMR1_CLR (B_BE_F2PCMDRPT_FULL_DROP_IMR | \ + B_BE_TXPRT_FULL_DROP_IMR | \ + B_BE_D_PKTID_IMR | \ + B_BE_Q_PKTID_IMR | \ + B_BE_BCNQ_ORDER_IMR | \ + B_BE_F2P_RLS_CTN_SEL_IMR | \ + B_BE_TWTSP_QSEL_IMR | \ + B_BE_TX_RECORD_PKTID_IMR | \ + B_BE_TX_SPF_U3_PKTID_IMR | \ + B_BE_TX_SPF_U2_PKTID_IMR | \ + B_BE_TX_SPF_U1_PKTID_IMR | \ + B_BE_RX_SPF_U0_PKTID_IMR | \ + B_BE_F2PCMD_USER_ALLC_IMR | \ + B_BE_F2PCMD_ASSIGN_PKTID_IMR | \ + B_BE_F2PCMD_RD_PKTID_IMR | \ + B_BE_F2PCMD_PKTID_IMR) +#define B_BE_PTCL_IMR1_SET B_BE_F2PCMD_USER_ALLC_IMR + +#define R_BE_PTCL_ISR1 0x108CC +#define R_BE_PTCL_ISR1_C1 0x148CC +#define B_BE_F2PCMD_PKTID_ERR BIT(30) +#define B_BE_F2PCMD_RD_PKTID_ERR BIT(29) +#define B_BE_F2PCMD_ASSIGN_PKTID_ERR BIT(28) +#define B_BE_F2PCMD_USER_ALLC_ERR BIT(27) +#define B_BE_RX_SPF_U0_PKTID_ERR BIT(26) +#define B_BE_TX_SPF_U1_PKTID_ERR BIT(25) +#define B_BE_TX_SPF_U2_PKTID_ERR BIT(24) +#define B_BE_TX_SPF_U3_PKTID_ERR BIT(23) +#define B_BE_TX_RECORD_PKTID_ERR BIT(22) +#define B_BE_TWTSP_QSEL_ERR BIT(14) +#define B_BE_F2P_RLS_CTN_SEL_ERR BIT(13) +#define B_BE_BCNQ_ORDER_ERR BIT(12) +#define B_BE_Q_PKTID_ERR BIT(11) +#define B_BE_D_PKTID_ERR BIT(10) +#define B_BE_TXPRT_FULL_DROP_ERR BIT(9) +#define B_BE_F2PCMDRPT_FULL_DROP_ERR BIT(8) + +#define R_BE_PTCL_FSM_MON 0x108E8 +#define R_BE_PTCL_FSM_MON_C1 0x148E8 +#define B_BE_PTCL_FSM2_TO_MODE BIT(30) +#define B_BE_PTCL_FSM2_TO_THR_MASK GENMASK(29, 24) +#define B_BE_PTCL_FSM1_TO_MODE BIT(22) +#define B_BE_PTCL_FSM1_TO_THR_MASK GENMASK(21, 16) +#define B_BE_PTCL_FSM0_TO_MODE BIT(14) +#define B_BE_PTCL_FSM0_TO_THR_MASK GENMASK(13, 8) +#define B_BE_PTCL_TX_ARB_TO_MODE BIT(6) +#define B_BE_PTCL_TX_ARB_TO_THR_MASK GENMASK(5, 0) + +#define R_BE_PTCL_TX_CTN_SEL 0x108EC +#define R_BE_PTCL_TX_CTN_SEL_C1 0x148EC +#define B_BE_PTCL_TXOP_STAT BIT(8) +#define B_BE_PTCL_BUSY BIT(7) +#define B_BE_PTCL_DROP BIT(5) +#define B_BE_PTCL_TX_QUEUE_IDX_MASK GENMASK(4, 0) + +#define R_BE_PTCL_DBG_INFO 0x108F0 + +#define R_BE_PTCL_DBG 0x108F4 + +#define R_BE_RX_ERROR_FLAG 0x10C00 +#define R_BE_RX_ERROR_FLAG_C1 0x14C00 +#define B_BE_RX_CSI_NOT_RELEASE_ERROR BIT(31) +#define B_BE_RX_GET_NULL_PKT_ERROR BIT(30) +#define B_BE_RX_RU0_FSM_HANG_ERROR BIT(29) +#define B_BE_RX_RU1_FSM_HANG_ERROR BIT(28) +#define B_BE_RX_RU2_FSM_HANG_ERROR BIT(27) +#define B_BE_RX_RU3_FSM_HANG_ERROR BIT(26) +#define B_BE_RX_RU4_FSM_HANG_ERROR BIT(25) +#define B_BE_RX_RU5_FSM_HANG_ERROR BIT(24) +#define B_BE_RX_RU6_FSM_HANG_ERROR BIT(23) +#define B_BE_RX_RU7_FSM_HANG_ERROR BIT(22) +#define B_BE_RX_RXSTS_FSM_HANG_ERROR BIT(21) +#define B_BE_RX_CSI_FSM_HANG_ERROR BIT(20) +#define B_BE_RX_TXRPT_FSM_HANG_ERROR BIT(19) +#define B_BE_RX_F2PCMD_FSM_HANG_ERROR BIT(18) +#define B_BE_RX_RU0_ZERO_LENGTH_ERROR BIT(17) +#define B_BE_RX_RU1_ZERO_LENGTH_ERROR BIT(16) +#define B_BE_RX_RU2_ZERO_LENGTH_ERROR BIT(15) +#define B_BE_RX_RU3_ZERO_LENGTH_ERROR BIT(14) +#define B_BE_RX_RU4_ZERO_LENGTH_ERROR BIT(13) +#define B_BE_RX_RU5_ZERO_LENGTH_ERROR BIT(12) +#define B_BE_RX_RU6_ZERO_LENGTH_ERROR BIT(11) +#define B_BE_RX_RU7_ZERO_LENGTH_ERROR BIT(10) +#define B_BE_RX_RXSTS_ZERO_LENGTH_ERROR BIT(9) +#define B_BE_RX_CSI_ZERO_LENGTH_ERROR BIT(8) +#define B_BE_PLE_DATA_OPT_FSM_HANG BIT(7) +#define B_BE_PLE_RXDATA_REQUEST_BUFFER_FSM_HANG BIT(6) +#define B_BE_PLE_TXRPT_REQUEST_BUFFER_FSM_HANG BIT(5) +#define B_BE_PLE_WD_OPT_FSM_HANG BIT(4) +#define B_BE_PLE_ENQ_FSM_HANG BIT(3) +#define B_BE_RXDATA_ENQUE_ORDER_ERROR BIT(2) +#define B_BE_RXSTS_ENQUE_ORDER_ERROR BIT(1) +#define B_BE_RX_CSI_PKT_NUM_ERROR BIT(0) + +#define R_BE_RX_ERROR_FLAG_IMR 0x10C04 +#define R_BE_RX_ERROR_FLAG_IMR_C1 0x14C04 +#define B_BE_RX_CSI_NOT_RELEASE_ERROR_IMR BIT(31) +#define B_BE_RX_GET_NULL_PKT_ERROR_IMR BIT(30) +#define B_BE_RX_RU0_FSM_HANG_ERROR_IMR BIT(29) +#define B_BE_RX_RU1_FSM_HANG_ERROR_IMR BIT(28) +#define B_BE_RX_RU2_FSM_HANG_ERROR_IMR BIT(27) +#define B_BE_RX_RU3_FSM_HANG_ERROR_IMR BIT(26) +#define B_BE_RX_RU4_FSM_HANG_ERROR_IMR BIT(25) +#define B_BE_RX_RU5_FSM_HANG_ERROR_IMR BIT(24) +#define B_BE_RX_RU6_FSM_HANG_ERROR_IMR BIT(23) +#define B_BE_RX_RU7_FSM_HANG_ERROR_IMR BIT(22) +#define B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR BIT(21) +#define B_BE_RX_CSI_FSM_HANG_ERROR_IMR BIT(20) +#define B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR BIT(19) +#define B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR BIT(18) +#define B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR BIT(17) +#define B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR BIT(16) +#define B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR BIT(15) +#define B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR BIT(14) +#define B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR BIT(13) +#define B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR BIT(12) +#define B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR BIT(11) +#define B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR BIT(10) +#define B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR BIT(9) +#define B_BE_RX_CSI_ZERO_LENGTH_ERROR_IMR BIT(8) +#define B_BE_PLE_DATA_OPT_FSM_HANG_IMR BIT(7) +#define B_BE_PLE_RXDATA_REQUEST_BUFFER_FSM_HANG_IMR BIT(6) +#define B_BE_PLE_TXRPT_REQUEST_BUFFER_FSM_HANG_IMR BIT(5) +#define B_BE_PLE_WD_OPT_FSM_HANG_IMR BIT(4) +#define B_BE_PLE_ENQ_FSM_HANG_IMR BIT(3) +#define B_BE_RXDATA_ENQUE_ORDER_ERROR_IMR BIT(2) +#define B_BE_RXSTS_ENQUE_ORDER_ERROR_IMR BIT(1) +#define B_BE_RX_CSI_PKT_NUM_ERROR_IMR BIT(0) +#define B_BE_RX_ERROR_FLAG_IMR_CLR (B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR | \ + B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR | \ + B_BE_RX_CSI_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU7_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU6_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU5_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU4_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU3_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU2_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU1_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU0_FSM_HANG_ERROR_IMR | \ + B_BE_RX_GET_NULL_PKT_ERROR_IMR) +#define B_BE_RX_ERROR_FLAG_IMR_SET (B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR | \ + B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR | \ + B_BE_RX_CSI_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU7_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU6_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU5_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU4_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU3_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU2_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU1_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU0_FSM_HANG_ERROR_IMR | \ + B_BE_RX_GET_NULL_PKT_ERROR_IMR) +#define B_BE_RX_ERROR_FLAG_IMR_CLR_V1 0x7FFFFFF8 +#define B_BE_RX_ERROR_FLAG_IMR_SET_V1 0x7FFFFF38 + +#define R_BE_RX_CTRL_1 0x10C0C +#define R_BE_RX_CTRL_1_C1 0x14C0C +#define B_BE_RXDMA_TXRPT_QUEUE_ID_SW_MASK GENMASK(30, 25) +#define B_BE_RXDMA_F2PCMDRPT_QUEUE_ID_SW_MASK GENMASK(23, 18) +#define B_BE_RXDMA_TXRPT_PORT_ID_SW_MASK GENMASK(17, 14) +#define B_BE_RXDMA_F2PCMDRPT_PORT_ID_SW_MASK GENMASK(13, 10) +#define B_BE_DBG_SEL_MASK GENMASK(1, 0) +#define WLCPU_RXCH2_QID 0xA + +#define R_BE_TX_ERROR_FLAG 0x10C6C +#define R_BE_TX_ERROR_FLAG_C1 0x14C6C +#define B_BE_TX_RU0_FSM_HANG_ERROR BIT(31) +#define B_BE_TX_RU1_FSM_HANG_ERROR BIT(30) +#define B_BE_TX_RU2_FSM_HANG_ERROR BIT(29) +#define B_BE_TX_RU3_FSM_HANG_ERROR BIT(28) +#define B_BE_TX_RU4_FSM_HANG_ERROR BIT(27) +#define B_BE_TX_RU5_FSM_HANG_ERROR BIT(26) +#define B_BE_TX_RU6_FSM_HANG_ERROR BIT(25) +#define B_BE_TX_RU7_FSM_HANG_ERROR BIT(24) +#define B_BE_TX_RU8_FSM_HANG_ERROR BIT(23) +#define B_BE_TX_RU9_FSM_HANG_ERROR BIT(22) +#define B_BE_TX_RU10_FSM_HANG_ERROR BIT(21) +#define B_BE_TX_RU11_FSM_HANG_ERROR BIT(20) +#define B_BE_TX_RU12_FSM_HANG_ERROR BIT(19) +#define B_BE_TX_RU13_FSM_HANG_ERROR BIT(18) +#define B_BE_TX_RU14_FSM_HANG_ERROR BIT(17) +#define B_BE_TX_RU15_FSM_HANG_ERROR BIT(16) +#define B_BE_TX_CSI_FSM_HANG_ERROR BIT(15) +#define B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR BIT(14) + +#define R_BE_TX_ERROR_FLAG_IMR 0x10C70 +#define R_BE_TX_ERROR_FLAG_IMR_C1 0x14C70 +#define B_BE_TX_RU0_FSM_HANG_ERROR_IMR BIT(31) +#define B_BE_TX_RU1_FSM_HANG_ERROR_IMR BIT(30) +#define B_BE_TX_RU2_FSM_HANG_ERROR_IMR BIT(29) +#define B_BE_TX_RU3_FSM_HANG_ERROR_IMR BIT(28) +#define B_BE_TX_RU4_FSM_HANG_ERROR_IMR BIT(27) +#define B_BE_TX_RU5_FSM_HANG_ERROR_IMR BIT(26) +#define B_BE_TX_RU6_FSM_HANG_ERROR_IMR BIT(25) +#define B_BE_TX_RU7_FSM_HANG_ERROR_IMR BIT(24) +#define B_BE_TX_RU8_FSM_HANG_ERROR_IMR BIT(23) +#define B_BE_TX_RU9_FSM_HANG_ERROR_IMR BIT(22) +#define B_BE_TX_RU10_FSM_HANG_ERROR_IMR BIT(21) +#define B_BE_TX_RU11_FSM_HANG_ERROR_IMR BIT(20) +#define B_BE_TX_RU12_FSM_HANG_ERROR_IMR BIT(19) +#define B_BE_TX_RU13_FSM_HANG_ERROR_IMR BIT(18) +#define B_BE_TX_RU14_FSM_HANG_ERROR_IMR BIT(17) +#define B_BE_TX_RU15_FSM_HANG_ERROR_IMR BIT(16) +#define B_BE_TX_CSI_FSM_HANG_ERROR_IMR BIT(15) +#define B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR BIT(14) +#define B_BE_TX_ERROR_FLAG_IMR_CLR (B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR | \ + B_BE_TX_CSI_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU15_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU14_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU13_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU12_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU11_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU10_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU9_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU8_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU7_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU6_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU5_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU4_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU3_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU2_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU1_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU0_FSM_HANG_ERROR_IMR) +#define B_BE_TX_ERROR_FLAG_IMR_SET (B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR | \ + B_BE_TX_CSI_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU15_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU14_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU13_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU12_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU11_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU10_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU9_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU8_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU7_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU6_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU5_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU4_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU3_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU2_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU1_FSM_HANG_ERROR_IMR | \ + B_BE_TX_RU0_FSM_HANG_ERROR_IMR) + +#define R_BE_RX_ERROR_FLAG_1 0x10C84 +#define R_BE_RX_ERROR_FLAG_1_C1 0x14C84 +#define B_BE_RX_RU8_FSM_HANG_ERROR BIT(29) +#define B_BE_RX_RU9_FSM_HANG_ERROR BIT(28) +#define B_BE_RX_RU10_FSM_HANG_ERROR BIT(27) +#define B_BE_RX_RU11_FSM_HANG_ERROR BIT(26) +#define B_BE_RX_RU12_FSM_HANG_ERROR BIT(25) +#define B_BE_RX_RU13_FSM_HANG_ERROR BIT(24) +#define B_BE_RX_RU14_FSM_HANG_ERROR BIT(23) +#define B_BE_RX_RU15_FSM_HANG_ERROR BIT(22) +#define B_BE_RX_RU8_ZERO_LENGTH_ERROR BIT(17) +#define B_BE_RX_RU9_ZERO_LENGTH_ERROR BIT(16) +#define B_BE_RX_RU10_ZERO_LENGTH_ERROR BIT(15) +#define B_BE_RX_RU11_ZERO_LENGTH_ERROR BIT(14) +#define B_BE_RX_RU12_ZERO_LENGTH_ERROR BIT(13) +#define B_BE_RX_RU13_ZERO_LENGTH_ERROR BIT(12) +#define B_BE_RX_RU14_ZERO_LENGTH_ERROR BIT(11) +#define B_BE_RX_RU15_ZERO_LENGTH_ERROR BIT(10) + +#define R_BE_RX_ERROR_FLAG_IMR_1 0x10C88 +#define R_BE_RX_ERROR_FLAG_IMR_1_C1 0x14C88 +#define B_BE_RX_RU8_FSM_HANG_ERROR_IMR BIT(29) +#define B_BE_RX_RU9_FSM_HANG_ERROR_IMR BIT(28) +#define B_BE_RX_RU10_FSM_HANG_ERROR_IMR BIT(27) +#define B_BE_RX_RU11_FSM_HANG_ERROR_IMR BIT(26) +#define B_BE_RX_RU12_FSM_HANG_ERROR_IMR BIT(25) +#define B_BE_RX_RU13_FSM_HANG_ERROR_IMR BIT(24) +#define B_BE_RX_RU14_FSM_HANG_ERROR_IMR BIT(23) +#define B_BE_RX_RU15_FSM_HANG_ERROR_IMR BIT(22) +#define B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR BIT(17) +#define B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR BIT(16) +#define B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR BIT(15) +#define B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR BIT(14) +#define B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR BIT(13) +#define B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR BIT(12) +#define B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR BIT(11) +#define B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR BIT(10) +#define B_BE_TX_ERROR_FLAG_IMR_1_CLR (B_BE_RX_RU8_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU9_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU10_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU11_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU12_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU13_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU14_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU15_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR) +#define B_BE_TX_ERROR_FLAG_IMR_1_SET (B_BE_RX_RU8_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU9_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU10_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU11_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU12_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU13_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU14_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU15_FSM_HANG_ERROR_IMR | \ + B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR | \ + B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR) + +#define R_BE_WMTX_MOREDATA_TSFT_STMP_CTL 0x10E08 +#define R_BE_WMTX_MOREDATA_TSFT_STMP_CTL_C1 0x14E08 +#define B_BE_TSFT_OFS_MASK GENMASK(31, 16) +#define B_BE_STMP_THSD_MASK GENMASK(15, 8) +#define B_BE_UPD_HGQMD BIT(1) +#define B_BE_UPD_TIMIE BIT(0) + +#define R_BE_WMTX_POWER_BE_BIT_CTL 0x10E0C +#define R_BE_WMTX_POWER_BE_BIT_CTL_C1 0x14E0C + +#define R_BE_WMTX_TCR_BE_4 0x10E2C +#define R_BE_WMTX_TCR_BE_4_C1 0x14E2C +#define B_BE_UL_EHT_MUMIMO_LTF_MODE BIT(30) +#define B_BE_UL_HE_MUMIMO_LTF_MODE BIT(29) +#define B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK GENMASK(28, 24) +#define B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK GENMASK(20, 16) +#define B_BE_NON_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(12, 8) +#define B_BE_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(4, 0) + +#define R_BE_RSP_CHK_SIG 0x11000 +#define R_BE_RSP_CHK_SIG_C1 0x15000 +#define B_BE_RSP_STATIC_RTS_CHK_SERV_BW_EN BIT(30) +#define B_BE_RSP_TBPPDU_CHK_PWR BIT(29) +#define B_BE_RESP_PAIR_MACID_LEN_EN BIT(25) +#define B_BE_RESP_TX_ABORT_TEST_EN BIT(24) +#define B_BE_RESP_ER_SU_RU106_EN BIT(23) +#define B_BE_RESP_ER_SU_EN BIT(22) +#define B_BE_TXDATA_END_PS_OPT BIT(18) +#define B_BE_CHECK_SOUNDING_SEQ BIT(17) +#define B_BE_RXBA_IGNOREA2 BIT(16) +#define B_BE_ACKTO_CCK_MASK GENMASK(15, 8) +#define B_BE_ACKTO_MASK GENMASK(8, 0) + +#define R_BE_TRXPTCL_RESP_0 0x11004 +#define R_BE_TRXPTCL_RESP_0_C1 0x15004 +#define B_BE_WMAC_RESP_STBC_EN BIT(31) +#define B_BE_WMAC_RXFTM_TXACK_SB BIT(30) +#define B_BE_WMAC_RXFTM_TXACKBWEQ BIT(29) +#define B_BE_RESP_TB_CHK_TXTIME BIT(24) +#define B_BE_RSP_CHK_CCA BIT(23) +#define B_BE_WMAC_LDPC_EN BIT(22) +#define B_BE_WMAC_SGIEN BIT(21) +#define B_BE_WMAC_SPLCPEN BIT(20) +#define B_BE_RESP_EHT_MCS15_REF BIT(19) +#define B_BE_RESP_EHT_MCS14_REF BIT(18) +#define B_BE_WMAC_BESP_EARLY_TXBA BIT(17) +#define B_BE_WMAC_MBA_DUR_FORCE BIT(16) +#define B_BE_WMAC_SPEC_SIFS_OFDM_MASK GENMASK(15, 8) +#define WMAC_SPEC_SIFS_OFDM_1115E 0x11 +#define B_BE_WMAC_SPEC_SIFS_CCK_MASK GENMASK(7, 0) + +#define R_BE_TRXPTCL_RESP_1 0x11008 +#define R_BE_TRXPTCL_RESP_1_C1 0x15008 +#define B_BE_WMAC_RESP_SR_MODE_EN BIT(31) +#define B_BE_FTM_RRSR_RATE_EN_MASK GENMASK(28, 24) +#define B_BE_NESS_MASK GENMASK(23, 22) +#define B_BE_WMAC_RESP_DOPPLEB_BE_EN BIT(21) +#define B_BE_WMAC_RESP_DCM_EN BIT(20) +#define B_BE_WMAC_CLR_ABORT_RESP_TX_CNT BIT(15) +#define B_BE_WMAC_RESP_REF_RATE_SEL BIT(12) +#define B_BE_WMAC_RESP_REF_RATE_MASK GENMASK(11, 0) + +#define R_BE_MAC_LOOPBACK 0x11020 +#define R_BE_MAC_LOOPBACK_C1 0x15020 +#define B_BE_MACLBK_DIS_GCLK BIT(30) +#define B_BE_MACLBK_STS_EN BIT(29) +#define B_BE_MACLBK_RDY_PERIOD_MASK GENMASK(28, 17) +#define B_BE_MACLBK_PLCP_DLY_MASK GENMASK(16, 8) +#define S_BE_MACLBK_PLCP_DLY_DEF 0x28 +#define B_BE_MACLBK_RDY_NUM_MASK GENMASK(7, 3) +#define B_BE_MACLBK_EN BIT(0) + +#define R_BE_CLIENT_OM_CTRL 0x11040 +#define R_BE_CLIENT_OM_CTRL_C1 0x15040 +#define B_BE_TRIG_DIS_EHTTB BIT(24) + +#define R_BE_WMAC_NAV_CTL 0x11080 +#define R_BE_WMAC_NAV_CTL_C1 0x15080 +#define B_BE_WMAC_NAV_UPPER_EN BIT(26) +#define B_BE_WMAC_0P125US_TIMER_MASK GENMASK(25, 18) +#define B_BE_WMAC_PLCP_UP_NAV_EN BIT(17) +#define B_BE_WMAC_TF_UP_NAV_EN BIT(16) +#define B_BE_WMAC_NAV_UPPER_MASK GENMASK(15, 8) +#define NAV_25MS 0xC4 +#define B_BE_WMAC_RTS_RST_DUR_MASK GENMASK(7, 0) + +#define R_BE_RXTRIG_TEST_USER_2 0x110B0 +#define R_BE_RXTRIG_TEST_USER_2_C1 0x150B0 +#define B_BE_RXTRIG_MACID_MASK GENMASK(31, 24) +#define B_BE_RXTRIG_RU26_DIS BIT(21) +#define B_BE_RXTRIG_FCSCHK_EN BIT(20) +#define B_BE_RXTRIG_PORT_SEL_MASK GENMASK(19, 17) +#define B_BE_RXTRIG_EN BIT(16) +#define B_BE_RXTRIG_USERINFO_2_MASK GENMASK(15, 0) + +#define R_BE_TRXPTCL_ERROR_INDICA_MASK 0x110BC +#define R_BE_TRXPTCL_ERROR_INDICA_MASK_C1 0x150BC +#define B_BE_WMAC_FTM_TIMEOUT_MODE BIT(30) +#define B_BE_WMAC_FTM_TIMEOUT_THR_MASK GENMASK(29, 24) +#define B_BE_WMAC_MODE BIT(22) +#define B_BE_WMAC_TIMETOUT_THR_MASK GENMASK(21, 16) +#define B_BE_RMAC_BFMER BIT(9) +#define B_BE_RMAC_FTM BIT(8) +#define B_BE_RMAC_CSI BIT(7) +#define B_BE_TMAC_MIMO_CTRL BIT(6) +#define B_BE_TMAC_RXTB BIT(5) +#define B_BE_TMAC_HWSIGB_GEN BIT(4) +#define B_BE_TMAC_TXPLCP BIT(3) +#define B_BE_TMAC_RESP BIT(2) +#define B_BE_TMAC_TXCTL BIT(1) +#define B_BE_TMAC_MACTX BIT(0) +#define B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR (B_BE_TMAC_MACTX | \ + B_BE_TMAC_TXCTL | \ + B_BE_TMAC_RESP | \ + B_BE_TMAC_TXPLCP | \ + B_BE_TMAC_HWSIGB_GEN | \ + B_BE_TMAC_RXTB | \ + B_BE_TMAC_MIMO_CTRL | \ + B_BE_RMAC_CSI | \ + B_BE_RMAC_FTM | \ + B_BE_RMAC_BFMER) +#define B_BE_TRXPTCL_ERROR_INDICA_MASK_SET (B_BE_TMAC_MACTX | \ + B_BE_TMAC_TXCTL | \ + B_BE_TMAC_RESP | \ + B_BE_TMAC_TXPLCP | \ + B_BE_TMAC_HWSIGB_GEN | \ + B_BE_TMAC_RXTB | \ + B_BE_TMAC_MIMO_CTRL | \ + B_BE_RMAC_CSI | \ + B_BE_RMAC_FTM | \ + B_BE_RMAC_BFMER) + +#define R_BE_TRXPTCL_ERROR_INDICA 0x110C0 +#define R_BE_TRXPTCL_ERROR_INDICA_C1 0x150C0 +#define B_BE_BFMER_ERR_FLAG BIT(9) +#define B_BE_FTM_ERROR_FLAG_CLR BIT(8) +#define B_BE_CSI_ERROR_FLAG_CLR BIT(7) +#define B_BE_MIMOCTRL_ERROR_FLAG_CLR BIT(6) +#define B_BE_RXTB_ERROR_FLAG_CLR BIT(5) +#define B_BE_HWSIGB_GEN_ERROR_FLAG_CLR BIT(4) +#define B_BE_TXPLCP_ERROR_FLAG_CLR BIT(3) +#define B_BE_RESP_ERROR_FLAG_CLR BIT(2) +#define B_BE_TXCTL_ERROR_FLAG_CLR BIT(1) +#define B_BE_MACTX_ERROR_FLAG_CLR BIT(0) + +#define R_BE_DBGSEL_TRXPTCL 0x110F4 +#define R_BE_DBGSEL_TRXPTCL_C1 0x150F4 +#define B_BE_WMAC_CHNSTS_STATE_MASK GENMASK(19, 16) +#define B_BE_DBGSEL_TRIGCMD_SEL_MASK GENMASK(11, 8) +#define B_BE_DBGSEL_TRXPTCL_MASK GENMASK(7, 0) + +#define R_BE_PHYINFO_ERR_IMR_V1 0x110F8 +#define R_BE_PHYINFO_ERR_IMR_V1_C1 0x150F8 +#define B_BE_PHYINTF_RXTB_WIDTH_MASK GENMASK(31, 30) +#define B_BE_PHYINTF_RXTB_EN_PHASE_MASK GENMASK(29, 28) +#define B_BE_PHYINTF_MIMO_WIDTH_MASK GENMASK(27, 26) +#define B_BE_PHYINTF_MIMO_EN_PHASE_MASK GENMASK(25, 24) +#define B_BE_PHYINTF_TIMEOUT_THR_V1_MASK GENMASK(21, 16) +#define B_BE_CSI_ON_TIMEOUT_EN BIT(5) +#define B_BE_STS_ON_TIMEOUT_EN BIT(4) +#define B_BE_DATA_ON_TIMEOUT_EN BIT(3) +#define B_BE_OFDM_CCA_TIMEOUT_EN BIT(2) +#define B_BE_CCK_CCA_TIMEOUT_EN BIT(1) +#define B_BE_PHY_TXON_TIMEOUT_EN BIT(0) +#define B_BE_PHYINFO_ERR_IMR_V1_CLR (B_BE_PHY_TXON_TIMEOUT_EN | \ + B_BE_CCK_CCA_TIMEOUT_EN | \ + B_BE_OFDM_CCA_TIMEOUT_EN | \ + B_BE_DATA_ON_TIMEOUT_EN | \ + B_BE_STS_ON_TIMEOUT_EN | \ + B_BE_CSI_ON_TIMEOUT_EN) +#define B_BE_PHYINFO_ERR_IMR_V1_SET 0 + +#define R_BE_PHYINFO_ERR_ISR 0x110FC +#define R_BE_PHYINFO_ERR_ISR_C1 0x150FC +#define B_BE_CSI_ON_TIMEOUT_ERR BIT(5) +#define B_BE_STS_ON_TIMEOUT_ERR BIT(4) +#define B_BE_DATA_ON_TIMEOUT_ERR BIT(3) +#define B_BE_OFDM_CCA_TIMEOUT_ERR BIT(2) +#define B_BE_CCK_CCA_TIMEOUT_ERR BIT(1) +#define B_BE_PHY_TXON_TIMEOUT_ERR BIT(0) + +#define R_BE_BFMEE_RESP_OPTION 0x11180 +#define R_BE_BFMEE_RESP_OPTION_C1 0x15180 +#define B_BE_BFMEE_CSI_SEC_TYPE_SH 20 +#define B_BE_BFMEE_CSI_SEC_TYPE_MSK 0xf +#define B_BE_BFMEE_BFRPT_SEG_SIZE_SH 16 +#define B_BE_BFMEE_BFRPT_SEG_SIZE_MSK 0x3 +#define B_BE_BFMEE_MIMO_EN_SEL BIT(8) +#define B_BE_BFMEE_MU_BFEE_DIS BIT(7) +#define B_BE_BFMEE_CHECK_RPTPOLL_MACID_DIS BIT(6) +#define B_BE_BFMEE_NOCHK_BFPOLL_BMP BIT(5) +#define B_BE_BFMEE_VHTBFRPT_CHK BIT(4) +#define B_BE_BFMEE_EHT_NDPA_EN BIT(3) +#define B_BE_BFMEE_HE_NDPA_EN BIT(2) +#define B_BE_BFMEE_VHT_NDPA_EN BIT(1) +#define B_BE_BFMEE_HT_NDPA_EN BIT(0) + +#define R_BE_TRXPTCL_RESP_CSI_CTRL_0 0x11188 +#define R_BE_TRXPTCL_RESP_CSI_CTRL_0_C1 0x15188 +#define B_BE_BFMEE_CSISEQ_SEL BIT(29) +#define B_BE_BFMEE_BFPARAM_SEL BIT(28) +#define B_BE_BFMEE_OFDM_LEN_TH_MASK GENMASK(27, 24) +#define B_BE_BFMEE_BF_PORT_SEL BIT(23) +#define B_BE_BFMEE_USE_NSTS BIT(22) +#define B_BE_BFMEE_CSI_RATE_FB_EN BIT(21) +#define B_BE_BFMEE_CSI_GID_SEL BIT(20) +#define B_BE_BFMEE_CSI_RSC_MASK GENMASK(19, 18) +#define B_BE_BFMEE_CSI_FORCE_RETE_EN BIT(17) +#define B_BE_BFMEE_CSI_USE_NDPARATE BIT(16) +#define B_BE_BFMEE_CSI_WITHHTC_EN BIT(15) +#define B_BE_BFMEE_CSIINFO0_BF_EN BIT(14) +#define B_BE_BFMEE_CSIINFO0_STBC_EN BIT(13) +#define B_BE_BFMEE_CSIINFO0_LDPC_EN BIT(12) +#define B_BE_BFMEE_CSIINFO0_CS_MASK GENMASK(11, 10) +#define B_BE_BFMEE_CSIINFO0_CB_MASK GENMASK(9, 8) +#define B_BE_BFMEE_CSIINFO0_NG_MASK GENMASK(7, 6) +#define B_BE_BFMEE_CSIINFO0_NR_MASK GENMASK(5, 3) +#define B_BE_BFMEE_CSIINFO0_NC_MASK GENMASK(2, 0) +#define CSI_RX_BW_CFG 0x1 +#define R_BE_TRXPTCL_RESP_CSI_CTRL_1 0x11194 +#define R_BE_TRXPTCL_RESP_CSI_CTRL_1_C1 0x15194 +#define B_BE_BFMEE_BE_CSI_RRSC_BITMAP_MASK GENMASK(31, 24) +#define CSI_RRSC_BITMAP_CFG 0x2A + +#define R_BE_TRXPTCL_RESP_CSI_RRSC 0x1118C +#define R_BE_TRXPTCL_RESP_CSI_RRSC_C1 0x1518C +#define CSI_RRSC_BMAP_BE 0x2A2AFF + +#define R_BE_TRXPTCL_RESP_CSI_RATE 0x11190 +#define R_BE_TRXPTCL_RESP_CSI_RATE_C1 0x15190 +#define B_BE_BFMEE_EHT_CSI_RATE_MASK GENMASK(31, 24) +#define B_BE_BFMEE_HE_CSI_RATE_MASK GENMASK(23, 16) +#define B_BE_BFMEE_VHT_CSI_RATE_MASK GENMASK(15, 8) +#define B_BE_BFMEE_HT_CSI_RATE_MASK GENMASK(7, 0) +#define CSI_INIT_RATE_EHT 0x3 + +#define R_BE_WMAC_ACK_BA_RESP_LEGACY 0x11200 +#define R_BE_WMAC_ACK_BA_RESP_LEGACY_C1 0x15200 +#define B_BE_ACK_BA_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_ACK_BA_RESP_LEGACY_CHK_CCA BIT(0) +#define RESP_ACK_CFG_BE (B_BE_ACK_BA_RESP_LEGACY_CHK_BTCCA | \ + B_BE_ACK_BA_RESP_LEGACY_CHK_TX_NAV) + +#define R_BE_WMAC_ACK_BA_RESP_HE 0x11204 +#define R_BE_WMAC_ACK_BA_RESP_HE_C1 0x15204 +#define B_BE_ACK_BA_RESP_HE_CHK_NSTR BIT(16) +#define B_BE_ACK_BA_RESP_HE_CHK_TX_NAV BIT(15) +#define B_BE_ACK_BA_RESP_HE_CHK_INTRA_NAV BIT(14) +#define B_BE_ACK_BA_RESP_HE_CHK_BASIC_NAV BIT(13) +#define B_BE_ACK_BA_RESP_HE_CHK_BTCCA BIT(12) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_ACK_BA_RESP_HE_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_ACK_BA_RESP_HE_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_CCA160 BIT(5) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_CCA80 BIT(4) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_CCA40 BIT(3) +#define B_BE_ACK_BA_RESP_HE_CHK_SEC_CCA20 BIT(2) +#define B_BE_ACK_BA_RESP_HE_CHK_EDCCA BIT(1) +#define B_BE_ACK_BA_RESP_HE_CHK_CCA BIT(0) + +#define R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC 0x11208 +#define R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC_C1 0x15208 +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_NSTR BIT(16) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_BTCCA BIT(12) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_EDCCA BIT(1) +#define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_CCA BIT(0) + +#define R_BE_WMAC_RX_RTS_RESP_LEGACY 0x1120C +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_C1 0x1520C +#define B_BE_RX_RTS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_CCA BIT(0) +#define RESP_RTS_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_RTS_PUNC_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_NORMAL_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_NORMAL_PUNC_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) + +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC 0x11210 +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC_C1 0x15210 +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_NSTR BIT(16) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_BTCCA BIT(12) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_EDCCA BIT(1) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_CCA BIT(0) + +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY 0x11214 +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_C1 0x15214 +#define B_BE_MURTS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_MURTS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_MURTS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_MURTS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_MURTS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_MURTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_MURTS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_MURTS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_MURTS_RESP_LEGACY_CHK_CCA BIT(0) + +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC 0x11218 +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC_C1 0x15218 +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_NSTR BIT(16) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_BTCCA BIT(12) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_EDCCA BIT(1) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_LEGACY 0x1121C +#define R_BE_WMAC_OTHERS_RESP_LEGACY_C1 0x1521C +#define B_BE_OTHERS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_LEGACY_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_HE 0x11220 +#define R_BE_WMAC_OTHERS_RESP_HE_C1 0x15220 +#define B_BE_OTHERS_RESP_HE_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_HE_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_HE_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_HE_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_HE_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_HE_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_HE_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_HE_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_HE_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC 0x11224 +#define R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC_C1 0x15224 +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_CCA BIT(0) + +#define R_BE_RCR 0x11400 +#define R_BE_RCR_C1 0x15400 +#define B_BE_BUSY_CHKSN BIT(15) +#define B_BE_DYN_CHEN BIT(14) +#define B_BE_AUTO_RST BIT(13) +#define B_BE_TIMER_SEL BIT(12) +#define B_BE_STOP_RX_IN BIT(11) +#define B_BE_PSR_RDY_CHKDIS BIT(10) +#define B_BE_DRV_INFO_SZ_MASK GENMASK(9, 8) +#define B_BE_HDR_CNV_SZ_MASK GENMASK(7, 6) +#define B_BE_PHY_RPT_SZ_MASK GENMASK(5, 4) +#define B_BE_CH_EN BIT(0) + +#define R_BE_DLK_PROTECT_CTL 0x11402 +#define R_BE_DLK_PROTECT_CTL_C1 0x15402 +#define B_BE_RX_DLK_CCA_TIME_MASK GENMASK(15, 8) +#define TRXCFG_RMAC_CCA_TO 32 +#define B_BE_RX_DLK_DATA_TIME_MASK GENMASK(7, 4) +#define TRXCFG_RMAC_DATA_TO 15 +#define B_BE_RX_DLK_RST_FSM BIT(3) +#define B_BE_RX_DLK_RST_SKIPDMA BIT(2) +#define B_BE_RX_DLK_RST_EN BIT(1) +#define B_BE_RX_DLK_INT_EN BIT(0) + +#define R_BE_PLCP_HDR_FLTR 0x11404 +#define R_BE_PLCP_HDR_FLTR_C1 0x15404 +#define B_BE_PLCP_RXFA_RESET_TYPE_MASK GENMASK(15, 12) +#define B_BE_PLCP_RXFA_RESET_EN BIT(11) +#define B_BE_DIS_CHK_MIN_LEN BIT(8) +#define B_BE_HE_SIGB_CRC_CHK BIT(6) +#define B_BE_VHT_MU_SIGB_CRC_CHK BIT(5) +#define B_BE_VHT_SU_SIGB_CRC_CHK BIT(4) +#define B_BE_SIGA_CRC_CHK BIT(3) +#define B_BE_LSIG_PARITY_CHK_EN BIT(2) +#define B_BE_CCK_SIG_CHK BIT(1) +#define B_BE_CCK_CRC_CHK BIT(0) + +#define R_BE_RXGCK_CTRL 0x11406 +#define R_BE_RXGCK_CTRL_C1 0x15406 +#define B_BE_RXGCK_BCNPRS_DISGCLK BIT(12) +#define B_BE_RXGCK_GCK_RATE_LIMIT_MASK GENMASK(9, 8) +#define RX_GCK_LEGACY 2 +#define B_BE_RXGCK_DISREG_GCLK BIT(7) +#define B_BE_RXGCK_ENTRY_DELAY_MASK GENMASK(6, 4) +#define B_BE_RXGCK_GCK_CYCLE_MASK GENMASK(3, 2) +#define B_BE_RXGCK_CCA_EN BIT(1) +#define B_BE_DISGCLK BIT(0) + +#define R_BE_RX_FLTR_OPT 0x11420 +#define R_BE_RX_FLTR_OPT_C1 0x15420 +#define B_BE_UID_FILTER_MASK GENMASK(31, 24) +#define B_BE_UNSPT_TYPE BIT(22) +#define B_BE_RX_MPDU_MAX_LEN_MASK GENMASK(21, 16) +#define B_BE_A_FTM_REQ BIT(14) +#define B_BE_A_ERR_PKT BIT(13) +#define B_BE_A_UNSUP_PKT BIT(12) +#define B_BE_A_CRC32_ERR BIT(11) +#define B_BE_A_BCN_CHK_RULE_MASK GENMASK(9, 8) +#define B_BE_A_BCN_CHK_EN BIT(7) +#define B_BE_A_MC_LIST_CAM_MATCH BIT(6) +#define B_BE_A_BC_CAM_MATCH BIT(5) +#define B_BE_A_UC_CAM_MATCH BIT(4) +#define B_BE_A_MC BIT(3) +#define B_BE_A_BC BIT(2) +#define B_BE_A_A1_MATCH BIT(1) +#define B_BE_SNIFFER_MODE BIT(0) +#define DEFAULT_BE_RX_FLTR (B_BE_A_BC_CAM_MATCH | B_BE_A_UC_CAM_MATCH | \ + B_BE_A_MC | B_BE_A_BC | B_BE_A_A1_MATCH | \ + FIELD_PREP_CONST(B_BE_UID_FILTER_MASK, 15) | \ + B_BE_A_FTM_REQ | B_BE_A_BCN_CHK_EN) + +#define R_BE_CTRL_FLTR 0x11424 +#define R_BE_CTRL_FLTR_C1 0x15424 +#define B_BE_CTRL_STYPE_MASK GENMASK(15, 0) +#define RX_FLTR_FRAME_DROP_BE 0x0000 +#define RX_FLTR_FRAME_ACCEPT_BE 0xFFFF + +#define R_BE_MGNT_FLTR 0x11428 +#define R_BE_MGNT_FLTR_C1 0x15428 +#define B_BE_MGNT_STYPE_MASK GENMASK(15, 0) + +#define R_BE_DATA_FLTR 0x1142C +#define R_BE_DATA_FLTR_C1 0x1542C +#define B_BE_DATA_STYPE_MASK GENMASK(15, 0) + +#define R_BE_ADDR_CAM_CTRL 0x11434 +#define R_BE_ADDR_CAM_CTRL_C1 0x15434 +#define B_BE_ADDR_CAM_RANGE_MASK GENMASK(23, 16) +#define ADDR_CAM_SERCH_RANGE 0x7f +#define B_BE_ADDR_CAM_CMPLIMT_MASK GENMASK(15, 12) +#define B_BE_ADDR_CAM_IORST BIT(10) +#define B_BE_DIS_ADDR_CLK_GATED BIT(9) +#define B_BE_ADDR_CAM_CLR BIT(8) +#define B_BE_ADDR_CAM_A2_B0_CHK BIT(2) +#define B_BE_ADDR_CAM_SRCH_PERPKT BIT(1) +#define B_BE_ADDR_CAM_EN BIT(0) + +#define R_BE_RESPBA_CAM_CTRL 0x1143C +#define R_BE_RESPBA_CAM_CTRL_C1 0x1543C +#define B_BE_BACAM_SKIP_ALL_QOSNULL BIT(24) +#define B_BE_BACAM_STD_SSN_SEL BIT(20) +#define B_BE_BACAM_TEMP_SZ_MASK GENMASK(17, 16) +#define B_BE_BACAM_RST_IDX_MASK GENMASK(15, 8) +#define B_BE_BACAM_SHIFT_POLL BIT(7) +#define B_BE_BACAM_IORST BIT(6) +#define B_BE_BACAM_GCK_DIS BIT(5) +#define B_BE_COMPL_VAL BIT(3) +#define B_BE_SSN_SEL BIT(2) +#define B_BE_BACAM_RST_MASK GENMASK(1, 0) +#define S_BE_BACAM_RST_DONE 0 +#define S_BE_BACAM_RST_ENT 1 +#define S_BE_BACAM_RST_ALL 2 + +#define R_BE_PPDU_STAT 0x11440 +#define R_BE_PPDU_STAT_C1 0x15440 +#define B_BE_STAT_IORST BIT(13) +#define B_BE_STAT_GCKDIS BIT(12) +#define B_BE_PPDU_STAT_WR_BW_MASK GENMASK(11, 10) +#define B_BE_PPDU_STAT_RPT_TRIG BIT(8) +#define B_BE_PPDU_STAT_RPT_DMA BIT(6) +#define B_BE_PPDU_STAT_RPT_CRC32 BIT(5) +#define B_BE_PPDU_STAT_RPT_ADDR BIT(4) +#define B_BE_APP_PLCP_HDR_RPT BIT(3) +#define B_BE_APP_RX_CNT_RPT BIT(2) +#define B_BE_PPDU_STAT_RPT_EN BIT(0) + +#define R_BE_RX_SR_CTRL 0x1144A +#define R_BE_RX_SR_CTRL_C1 0x1544A +#define B_BE_SR_OP_MODE_MASK GENMASK(5, 4) +#define B_BE_SRG_CHK_EN BIT(2) +#define B_BE_SR_CTRL_PLCP_EN BIT(1) +#define B_BE_SR_EN BIT(0) + +#define R_BE_BSSID_SRC_CTRL 0x1144B +#define R_BE_BSSID_SRC_CTRL_C1 0x1544B +#define B_BE_BSSID_MATCH BIT(3) +#define B_BE_PARTIAL_AID_MATCH BIT(2) +#define B_BE_BSSCOLOR_MATCH BIT(1) +#define B_BE_PLCP_SRC_EN BIT(0) + +#define R_BE_CSIRPT_OPTION 0x11464 +#define R_BE_CSIRPT_OPTION_C1 0x15464 +#define B_BE_CSIPRT_EHTSU_AID_EN BIT(26) +#define B_BE_CSIPRT_HESU_AID_EN BIT(25) +#define B_BE_CSIPRT_VHTSU_AID_EN BIT(24) + +#define R_BE_BSR_UPD_CTRL 0x11468 +#define R_BE_BSR_UPD_CTRL_C1 0x15468 +#define B_BE_QSIZE_RULE BIT(1) +#define B_BE_QSIZE_UPD BIT(0) + +#define R_BE_DRV_INFO_OPTION 0x11470 +#define R_BE_DRV_INFO_OPTION_C1 0x15470 +#define B_BE_DRV_INFO_PHYRPT_EN BIT(0) + +#define R_BE_BCN_PSR_RPT_P0 0x11484 +#define R_BE_BCN_PSR_RPT_P0_C1 0x15484 +#define B_BE_BCAID_P0_MASK GENMASK(10, 0) + +#define R_BE_RX_ERR_ISR 0x114F4 +#define R_BE_RX_ERR_ISR_C1 0x154F4 +#define B_BE_RX_ERR_TRIG_ACT_TO BIT(9) +#define B_BE_RX_ERR_STS_ACT_TO BIT(8) +#define B_BE_RX_ERR_CSI_ACT_TO BIT(7) +#define B_BE_RX_ERR_ACT_TO BIT(6) +#define B_BE_CSI_DATAON_ASSERT_TO BIT(5) +#define B_BE_DATAON_ASSERT_TO BIT(4) +#define B_BE_CCA_ASSERT_TO BIT(3) +#define B_BE_RX_ERR_DMA_TO BIT(2) +#define B_BE_RX_ERR_DATA_TO BIT(1) +#define B_BE_RX_ERR_CCA_TO BIT(0) + +#define R_BE_RX_ERR_IMR 0x114F8 +#define R_BE_RX_ERR_IMR_C1 0x154F8 +#define B_BE_RX_ERR_TRIG_ACT_TO_MSK BIT(9) +#define B_BE_RX_ERR_STS_ACT_TO_MSK BIT(8) +#define B_BE_RX_ERR_CSI_ACT_TO_MSK BIT(7) +#define B_BE_RX_ERR_ACT_TO_MSK BIT(6) +#define B_BE_CSI_DATAON_ASSERT_TO_MSK BIT(5) +#define B_BE_DATAON_ASSERT_TO_MSK BIT(4) +#define B_BE_CCA_ASSERT_TO_MSK BIT(3) +#define B_BE_RX_ERR_DMA_TO_MSK BIT(2) +#define B_BE_RX_ERR_DATA_TO_MSK BIT(1) +#define B_BE_RX_ERR_CCA_TO_MSK BIT(0) +#define B_BE_RX_ERR_IMR_CLR (B_BE_RX_ERR_CCA_TO_MSK | \ + B_BE_RX_ERR_DATA_TO_MSK | \ + B_BE_RX_ERR_DMA_TO_MSK | \ + B_BE_CCA_ASSERT_TO_MSK | \ + B_BE_DATAON_ASSERT_TO_MSK | \ + B_BE_CSI_DATAON_ASSERT_TO_MSK | \ + B_BE_RX_ERR_ACT_TO_MSK | \ + B_BE_RX_ERR_CSI_ACT_TO_MSK | \ + B_BE_RX_ERR_STS_ACT_TO_MSK | \ + B_BE_RX_ERR_TRIG_ACT_TO_MSK) +#define B_BE_RX_ERR_IMR_SET (B_BE_RX_ERR_ACT_TO_MSK | \ + B_BE_RX_ERR_STS_ACT_TO_MSK | \ + B_BE_RX_ERR_TRIG_ACT_TO_MSK) + +#define R_BE_RX_PLCP_EXT_OPTION_1 0x11514 +#define R_BE_RX_PLCP_EXT_OPTION_1_C1 0x15514 +#define B_BE_PLCP_CLOSE_RX_UNSPUUORT BIT(19) +#define B_BE_PLCP_CLOSE_RX_BB_BRK BIT(18) +#define B_BE_PLCP_CLOSE_RX_PSDU_PRES BIT(17) +#define B_BE_PLCP_CLOSE_RX_NDP BIT(16) +#define B_BE_PLCP_NSS_SRC BIT(11) +#define B_BE_PLCP_DOPPLEB_BE_SRC BIT(10) +#define B_BE_PLCP_STBC_SRC BIT(9) +#define B_BE_PLCP_SU_PSDU_LEN_SRC BIT(8) +#define B_BE_PLCP_RXSB_SRC BIT(7) +#define B_BE_PLCP_BW_SRC_MASK GENMASK(6, 5) +#define B_BE_PLCP_GILTF_SRC BIT(4) +#define B_BE_PLCP_NSTS_SRC BIT(3) +#define B_BE_PLCP_MCS_SRC BIT(2) +#define B_BE_PLCP_CH20_WIDATA_SRC BIT(1) +#define B_BE_PLCP_PPDU_TYPE_SRC BIT(0) + +#define R_BE_RX_PLCP_EXT_OPTION_2 0x11518 +#define R_BE_RX_PLCP_EXT_OPTION_2_C1 0x15518 +#define B_BE_PLCP_PHASE_B_CRC_CHK_EN BIT(17) +#define B_BE_PLCP_PHASE_A_CRC_CHK_EN BIT(16) +#define B_BE_EHTTB_EHTSIG_CRC_CHK_EN BIT(3) +#define B_BE_EHTTB_USIG_CRC_CHK_EN BIT(2) +#define B_BE_EHTMU_EHTSIG_CRC_CHK_EN BIT(1) +#define B_BE_EHTMU_USIG_CRC_CHK_EN BIT(0) + +#define R_BE_RESP_CSI_RESERVED_PAGE 0x11810 +#define R_BE_RESP_CSI_RESERVED_PAGE_C1 0x15810 +#define B_BE_CSI_RESERVED_PAGE_NUM_MASK GENMASK(27, 16) +#define B_BE_CSI_RESERVED_START_PAGE_MASK GENMASK(11, 0) + +#define R_BE_RESP_IMR1 0x11878 +#define R_BE_RESP_IMR1_C1 0x15878 +#define B_BE_RESP_IMR_1_MASK GENMASK(31, 9) +#define B_BE_FSM_TIMEOUT_ERR_IMR BIT(8) +#define B_BE_SEC_DOUBLE_HIT_ERR_IMR BIT(7) +#define B_BE_WRPTR_ERR_IMR BIT(6) +#define B_BE_SMR_TOO_MANY_PLD_ERR_IMR BIT(5) +#define B_BE_LMR_TOO_MANY_PLD_ERR_IMR BIT(4) +#define B_BE_CSI_TOO_MANY_PLD_ERR_IMR BIT(3) +#define B_BE_FTM_LMR_PLDID_READY_ERR_IMR BIT(2) +#define B_BE_SMR_PLDID_READY_ERR_IMR BIT(1) +#define B_BE_CSI_PLDID_READY_ERR_IMR BIT(0) +#define B_BE_RESP_IMR1_CLR 0x1FF +#define B_BE_RESP_IMR1_SET 0xFF + +#define R_BE_RESP_IMR 0x11884 +#define R_BE_RESP_IMR_C1 0x15884 +#define B_BE_RESP_TBL_FLAG_ERR_ISR_EN BIT(17) +#define B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN BIT(16) +#define B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN BIT(15) +#define B_BE_RESP_TOO_MANY_PLD_ERR_ISR_EN BIT(14) +#define B_BE_RESP_TXDMA_READ_DATA_ERR_ISR_EN BIT(13) +#define B_BE_RESP_PLDID_RDY_ERR_ISR_EN BIT(12) +#define B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN BIT(11) +#define B_BE_RESP_RXDMA_WRPTR_INVLD_ERR_ISR_EN BIT(10) +#define B_BE_RESP_RXDMA_REQ_INVLD_ERR_ISR_EN BIT(9) +#define B_BE_RESP_RXDMA_REQ_MACID_ERR_ISR_EN BIT(8) +#define B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN BIT(6) +#define B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN BIT(5) +#define B_BE_RESP_TXCMD_TBL_ERR_ISR_EN BIT(4) +#define B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN BIT(3) +#define B_BE_RESP_INITCMD_RESERVD_PAGE_ABORT_ERR_ISR_EN BIT(2) +#define B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN BIT(1) +#define B_BE_RESP_DMAC_PROC_ERR_ISR_EN BIT(0) +#define B_BE_RESP_IMR_CLR (B_BE_RESP_DMAC_PROC_ERR_ISR_EN | \ + B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_TBL_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_RXDMA_REQ_MACID_ERR_ISR_EN | \ + B_BE_RESP_RXDMA_REQ_INVLD_ERR_ISR_EN | \ + B_BE_RESP_RXDMA_WRPTR_INVLD_ERR_ISR_EN | \ + B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN | \ + B_BE_RESP_PLDID_RDY_ERR_ISR_EN | \ + B_BE_RESP_TXDMA_READ_DATA_ERR_ISR_EN | \ + B_BE_RESP_TOO_MANY_PLD_ERR_ISR_EN | \ + B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN | \ + B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN) +#define B_BE_RESP_IMR_SET (B_BE_RESP_DMAC_PROC_ERR_ISR_EN | \ + B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_TBL_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN | \ + B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN | \ + B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN | \ + B_BE_RESP_PLDID_RDY_ERR_ISR_EN | \ + B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN | \ + B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN) +#define B_BE_RESP_IMR_CLR_V1 0xFFFFFFFF +#define B_BE_RESP_IMR_SET_V1 0xFFFFFFFF + +#define R_BE_PWR_MODULE 0x11900 +#define R_BE_PWR_MODULE_C1 0x15900 +#define R_BE_PWR_LISTEN_PATH 0x11988 +#define B_BE_PWR_LISTEN_PATH_EN GENMASK(31, 28) + +#define R_BE_TXAGC_MAX_1TX_RU484_242_0 0x11990 +#define R_BE_TXAGC_MAX_1TX_RU996_484_0 0x119A4 +#define R_BE_TXAGC_MAX_1TX_RU996_484_242_0 0x119AC +#define R_BE_TXAGC_MAX_1TX_BF_RU484_242_0 0x119DC + +#define R_BE_PWR_REF_CTRL 0x11A20 +#define B_BE_PWR_REF_CTRL_OFDM GENMASK(9, 1) +#define B_BE_PWR_REF_CTRL_CCK GENMASK(18, 10) +#define B_BE_PWR_OFST_LMT_DB GENMASK(27, 19) +#define R_BE_PWR_OFST_LMTBF 0x11A24 +#define B_BE_PWR_OFST_LMTBF_DB GENMASK(8, 0) +#define R_BE_PWR_FORCE_LMT 0x11A28 +#define B_BE_PWR_FORCE_LMT_ON BIT(6) + +#define R_BE_PWR_RATE_CTRL 0x11A2C +#define B_BE_PWR_OFST_BYRATE_DB GENMASK(8, 0) +#define B_BE_FORCE_PWR_BY_RATE_EN BIT(19) +#define B_BE_FORCE_PWR_BY_RATE_VAL GENMASK(28, 20) + +#define R_BE_PWR_RATE_OFST_CTRL 0x11A30 +#define R_BE_PWR_RATE_OFST_END 0x11A38 +#define R_BE_PWR_RULMT_START 0x12048 +#define R_BE_PWR_RULMT_END 0x120e4 + +#define R_BE_PWR_BOOST 0x11A40 +#define B_BE_PWR_CTRL_SEL BIT(16) +#define B_BE_PWR_FORCE_RATE_ON BIT(29) +#define R_BE_PWR_OFST_RULMT 0x11A44 +#define B_BE_PWR_OFST_RULMT_DB GENMASK(17, 9) +#define B_BE_PWR_FORCE_RU_ON BIT(18) +#define B_BE_PWR_FORCE_RU_ENON BIT(28) +#define R_BE_PWR_FORCE_MACID 0x11A48 +#define B_BE_PWR_FORCE_MACID_DBM_ON BIT(9) +#define B_BE_PWR_FORCE_MACID_DBM_VAL GENMASK(17, 10) +#define B_BE_PWR_FORCE_MACID_EN_VAL BIT(18) +#define B_BE_PWR_FORCE_MACID_EN_ON BIT(19) +#define B_BE_PWR_FORCE_MACID_ALL \ + (B_BE_PWR_FORCE_MACID_DBM_ON | \ + B_BE_PWR_FORCE_MACID_DBM_VAL | \ + B_BE_PWR_FORCE_MACID_EN_VAL | \ + B_BE_PWR_FORCE_MACID_EN_ON) + +#define R_BE_TXAGC_MAX_1TX_BF_RU996_484_0 0x11A4C + +#define R_BE_PWR_REG_CTRL 0x11A50 +#define B_BE_PWR_BT_EN BIT(23) + +#define R_BE_PWR_COEX_CTRL 0x11A54 +#define B_BE_PWR_BT_VAL GENMASK(8, 0) +#define B_BE_PWR_FORCE_COEX_ON GENMASK(29, 27) + +#define R_PWR_BOOST_BE4 0x11A64 +#define B_PWR_BOOST_BE4 BIT(8) + +#define R_BE_PWR_TH 0x11A78 +#define R_BE_PWR_RSSI_TARGET_LMT 0x11A84 + +#define R_BE_TXAGC_MAX_1TX_BF_RU996_484_242_0 0x11ADC + +#define R_BE_PWR_OFST_SW 0x11AE8 +#define B_BE_PWR_OFST_SW_DB GENMASK(27, 24) + +#define R_BE_PWR_FTM 0x11B00 +#define R_BE_PWR_FTM_SS 0x11B04 +#define B_BE_PWR_BY_RATE_DBW_ON GENMASK(27, 26) + +#define R_BE_PWR_BY_RATE 0x11E00 +#define R_BE_PWR_BY_RATE_MAX 0x11FA8 +#define R_BE_PWR_LMT 0x11FAC +#define R_BE_PWR_LMT_MAX 0x12040 +#define R_BE_PWR_BY_RATE_END 0x12044 +#define R_BE_PWR_RU_LMT 0x12048 +#define R_BE_PWR_RU_LMT_MAX 0x120E4 + +#define R_BE_C0_TXPWR_IMR 0x128E0 +#define R_BE_C0_TXPWR_IMR_C1 0x168E0 +#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0) +#define B_BE_C0_TXPWR_IMR_CLR B_BE_FSM_TIMEOUT_ERR_INT_EN +#define B_BE_C0_TXPWR_IMR_SET B_BE_FSM_TIMEOUT_ERR_INT_EN + +#define R_BE_TXPWR_ERR_FLAG 0x128E4 +#define R_BE_TXPWR_ERR_IMR 0x128E0 +#define R_BE_TXPWR_ERR_FLAG_C1 0x158E4 +#define R_BE_TXPWR_ERR_IMR_C1 0x158E0 + +#define R_BE_SCH_EXT_CTRL 0x103FC +#define R_BE_SCH_EXT_CTRL_C1 0x143FC +#define B_BE_CWCNT_PLUS_MODE BIT(31) + +#define CMAC1_START_ADDR_BE 0x14000 +#define CMAC1_END_ADDR_BE 0x17FFF + +#define RR_MOD 0x00 +#define RR_MOD_V1 0x10000 +#define RR_MOD_IQK GENMASK(19, 4) +#define RR_MOD_DPK GENMASK(19, 5) +#define RR_MOD_MASK GENMASK(19, 16) +#define RR_MOD_DCK GENMASK(14, 10) +#define RR_MOD_RGM GENMASK(13, 4) +#define RR_MOD_RXB GENMASK(9, 5) +#define RR_MOD_V_DOWN 0x0 +#define RR_MOD_V_STANDBY 0x1 +#define RR_TXAGC 0x10001 +#define RR_MOD_V_TX 0x2 +#define RR_MOD_V_RX 0x3 +#define RR_MOD_V_TXIQK 0x4 +#define RR_MOD_V_DPK 0x5 +#define RR_MOD_V_RXK1 0x6 +#define RR_MOD_V_RXK2 0x7 +#define RR_MOD_NBW GENMASK(15, 14) +#define RR_MOD_M_RXG GENMASK(13, 4) +#define RR_MOD_M_RXBB GENMASK(9, 5) +#define RR_MOD_LO_SEL BIT(1) +#define RR_MODOPT 0x01 +#define RR_MODOPT_V1 0x10001 +#define RR_SW_SEL BIT(19) +#define RR_TXG_SEL GENMASK(19, 17) +#define RR_TBL_SEL_IDX1 GENMASK(9, 8) +#define RR_TBL_SEL_IDX0 GENMASK(7, 6) +#define RR_MODOPT_M_TXPWR GENMASK(5, 0) +#define RR_WLSEL 0x02 +#define RR_WLSEL_AG GENMASK(18, 16) +#define RR_RSV1 0x05 +#define RR_RSV1_RST BIT(0) +#define RR_BBDC 0x10005 +#define RR_BBDC_SEL BIT(0) +#define RR_DTXLOK 0x08 +#define RR_RSV2 0x09 +#define RR_LOKVB 0x0a +#define RR_LOKVB_COI GENMASK(19, 14) +#define RR_LOKVB_COQ GENMASK(9, 4) +#define RR_TXIG 0x11 +#define RR_TXIG_TG GENMASK(16, 12) +#define RR_TXIG_GR1 GENMASK(6, 4) +#define RR_TXIG_GR0 GENMASK(1, 0) +#define RR_CHTR 0x17 +#define RR_CHTR_MOD GENMASK(11, 10) +#define RR_CHTR_TXRX GENMASK(9, 0) +#define RR_CFGCH 0x18 +#define RR_CFGCH_V1 0x10018 +#define RR_CFGCH_BAND1 GENMASK(17, 16) +#define CFGCH_BAND1_2G 0 +#define CFGCH_BAND1_5G 1 +#define CFGCH_BAND1_6G 3 +#define RR_CFGCH_POW_LCK BIT(15) +#define RR_CFGCH_TRX_AH BIT(14) +#define RR_CFGCH_BCN BIT(13) +#define RR_CFGCH_BW2 BIT(12) +#define RR_CFGCH_BAND0 GENMASK(9, 8) +#define CFGCH_BAND0_2G 0 +#define CFGCH_BAND0_5G 1 +#define CFGCH_BAND0_6G 0 +#define RR_CFGCH_BW_V2 GENMASK(12, 10) +#define CFGCH_BW_V2_20M 0 +#define CFGCH_BW_V2_40M 1 +#define CFGCH_BW_V2_80M 2 +#define CFGCH_BW_V2_160M 3 +#define CFGCH_BW_V2_320M 4 +#define RR_CFGCH_BW GENMASK(11, 10) +#define RR_CFGCH_CH GENMASK(7, 0) +#define CFGCH_BW_20M 3 +#define CFGCH_BW_40M 2 +#define CFGCH_BW_80M 1 +#define CFGCH_BW_160M 0 +#define RR_APK 0x19 +#define RR_APK_MOD GENMASK(5, 4) +#define RR_BTC 0x1a +#define RR_BTC_TXBB GENMASK(14, 12) +#define RR_BTC_RXBB GENMASK(11, 10) +#define RR_RCKC 0x1b +#define RR_RCKC_CA GENMASK(14, 10) +#define RR_RCKS 0x1c +#define RR_RCKO 0x1d +#define RR_RCKO_OFF GENMASK(13, 9) +#define RR_RXKPLL 0x1e +#define RR_RXKPLL_OFF GENMASK(5, 0) +#define RR_RXKPLL_POW BIT(19) +#define RR_RSV4 0x1f +#define RR_RSV4_AGH GENMASK(17, 16) +#define RR_RSV4_PLLCH GENMASK(9, 0) +#define RR_RXK 0x20 +#define RR_RXK_SEL2G BIT(8) +#define RR_RXK_SEL5G BIT(7) +#define RR_RXK_PLLEN BIT(5) +#define RR_LUTWA 0x33 +#define RR_LUTWA_MASK GENMASK(9, 0) +#define RR_LUTWA_M1 GENMASK(7, 0) +#define RR_LUTWA_M2 GENMASK(4, 0) +#define RR_LUTWD1 0x3e +#define RR_LUTWD0 0x3f +#define RR_LUTWD0_MB GENMASK(11, 6) +#define RR_LUTWD0_LB GENMASK(5, 0) +#define RR_TM 0x42 +#define RR_TM_TRI BIT(19) +#define RR_TM_TRM GENMASK(17, 11) +#define RR_TM_VAL_V1 GENMASK(7, 0) +#define RR_TM_VAL GENMASK(6, 1) +#define RR_TM2 0x43 +#define RR_TM2_OFF GENMASK(19, 16) +#define RR_TXG1 0x51 +#define RR_TXG1_ATT2 BIT(19) +#define RR_TXG1_ATT1 BIT(11) +#define RR_TXG2 0x52 +#define RR_TXG2_ATT0 BIT(11) +#define RR_BSPAD 0x54 +#define RR_TXGA 0x55 +#define RR_TXGA_TRK_EN BIT(7) +#define RR_TXGA_LOK_EXT GENMASK(4, 0) +#define RR_TXGA_LOK_EN BIT(0) +#define RR_TXGA_V1 0x10055 +#define RR_TXGA_V1_TRK_EN BIT(7) +#define RR_GAINTX 0x56 +#define RR_GAINTX_ALL GENMASK(15, 0) +#define RR_GAINTX_PAD GENMASK(9, 5) +#define RR_GAINTX_BB GENMASK(4, 0) +#define RR_TXMO 0x58 +#define RR_TXMO_COI GENMASK(19, 15) +#define RR_TXMO_COQ GENMASK(14, 10) +#define RR_TXMO_FII GENMASK(9, 6) +#define RR_TXMO_FIQ GENMASK(5, 2) +#define RR_TXA 0x5d +#define RR_TXA_TRK GENMASK(19, 14) +#define RR_TXRSV 0x5c +#define RR_TXRSV_GAPK BIT(19) +#define RR_BIAS 0x5e +#define RR_BIAS_GAPK BIT(19) +#define RR_TXAC 0x5f +#define RR_TXAC_IQG GENMASK(3, 0) +#define RR_BIASA 0x60 +#define RR_BIASA_TXA GENMASK(19, 16) +#define RR_BIASA_TXG GENMASK(15, 12) +#define RR_BIASD_TXA_V1 GENMASK(15, 12) +#define RR_BIASA_TXA_V1 GENMASK(11, 8) +#define RR_BIASD_TXG_V1 GENMASK(7, 4) +#define RR_BIASA_TXG_V1 GENMASK(3, 0) +#define RR_BIASA_A GENMASK(2, 0) +#define RR_BIASA2 0x63 +#define RR_BIASA2_LB GENMASK(4, 2) +#define RR_TXATANK 0x64 +#define RR_TXATANK_LBSW2 GENMASK(17, 15) +#define RR_TXATANK_LBSW GENMASK(16, 15) +#define RR_TXA2 0x65 +#define RR_TXA2_LDO GENMASK(19, 16) +#define RR_TRXIQ 0x66 +#define RR_RSV6 0x6d +#define RR_TXVBUF 0x7c +#define RR_TXVBUF_DACEN BIT(5) +#define RR_TXPOW 0x7f +#define RR_TXPOW_TXA BIT(8) +#define RR_TXPOW_TXAS BIT(7) +#define RR_TXPOW_TXG BIT(1) +#define RR_RXPOW 0x80 +#define RR_RXPOW_IQK GENMASK(17, 16) +#define RR_RXBB 0x83 +#define RR_RXBB_VOBUF GENMASK(15, 12) +#define RR_RXBB_C2G GENMASK(16, 10) +#define RR_RXBB_C2 GENMASK(11, 8) +#define RR_RXBB_C1G GENMASK(9, 8) +#define RR_RXBB_FATT GENMASK(7, 0) +#define RR_RXBB_ATTR GENMASK(7, 4) +#define RR_RXBB_ATTC GENMASK(2, 0) +#define RR_RXG 0x84 +#define RR_RXG_IQKMOD GENMASK(19, 16) +#define RR_XGLNA2 0x85 +#define RR_XGLNA2_SW GENMASK(1, 0) +#define RR_RXAE 0x89 +#define RR_RXAE_IQKMOD GENMASK(3, 0) +#define RR_RXA 0x8a +#define RR_RXA_DPK GENMASK(9, 8) +#define RR_RXA_LNA 0x8b +#define RR_RXA2 0x8c +#define RR_RAA2_SATT GENMASK(15, 13) +#define RR_RAA2_SWATT GENMASK(15, 9) +#define RR_RXA2_C1 GENMASK(12, 10) +#define RR_RXA2_C2 GENMASK(9, 3) +#define RR_RXA2_CC2 GENMASK(8, 7) +#define RR_RXA2_IATT GENMASK(7, 4) +#define RR_RXA2_HATT GENMASK(6, 0) +#define RR_RXA2_ATT GENMASK(3, 0) +#define RR_RXIQGEN 0x8d +#define RR_RXIQGEN_ATTL GENMASK(12, 8) +#define RR_RXIQGEN_ATTH GENMASK(14, 13) +#define RR_RXBB2 0x8f +#define RR_RXBB2_DAC_EN BIT(13) +#define RR_RXBB2_CKT BIT(12) +#define RR_EN_TIA_IDA GENMASK(11, 10) +#define RR_RXBB2_IDAC GENMASK(11, 9) +#define RR_RXBB2_EBW GENMASK(6, 5) +#define RR_XALNA2 0x90 +#define RR_XALNA2_SW2 GENMASK(9, 8) +#define RR_XALNA2_SW GENMASK(1, 0) +#define RR_DCK 0x92 +#define RR_DCK_S1 GENMASK(19, 16) +#define RR_DCK_TIA GENMASK(15, 9) +#define RR_DCK_DONE GENMASK(7, 5) +#define RR_DCK_FINE BIT(1) +#define RR_DCK_LV BIT(0) +#define RR_DCK1 0x93 +#define RR_DCK1_S1 GENMASK(19, 16) +#define RR_DCK1_TIA GENMASK(15, 9) +#define RR_DCK1_DONE BIT(5) +#define RR_DCK1_CLR GENMASK(3, 0) +#define RR_DCK1_SEL BIT(3) +#define RR_DCK2 0x94 +#define RR_DCK2_CYCLE GENMASK(7, 2) +#define RR_DCKC 0x95 +#define RR_DCKC_CHK BIT(3) +#define RR_IQGEN 0x97 +#define RR_IQGEN_BIAS GENMASK(11, 8) +#define RR_TXIQK 0x98 +#define RR_TXIQK_ATT2 GENMASK(15, 12) +#define RR_TXIQK_ATT1 GENMASK(6, 0) +#define RR_TIA 0x9e +#define RR_TIA_N6 BIT(8) +#define RR_MIXER 0x9f +#define RR_MIXER_GN GENMASK(4, 3) +#define RR_POW 0xa0 +#define RR_POW_SYN GENMASK(3, 2) +#define RR_POW_SYN_V1 GENMASK(3, 0) +#define RR_LOGEN 0xa3 +#define RR_LOGEN_RPT GENMASK(19, 16) +#define RR_SX 0xaf +#define RR_IBD 0xc9 +#define RR_IBD_VAL GENMASK(4, 0) +#define RR_LDO 0xb1 +#define RR_LDO_SEL GENMASK(8, 6) +#define RR_VCO 0xb2 +#define RR_VCO_VAL GENMASK(18, 14) +#define RR_VCO_SEL GENMASK(9, 8) +#define RR_VCO_STS GENMASK(7, 0) +#define RR_VCI 0xb3 +#define RR_VCI_ON BIT(7) +#define RR_LPF 0xb7 +#define RR_LPF_BUSY BIT(8) +#define RR_XTALX2 0xb8 +#define RR_MALSEL 0xbe +#define RR_SYNFB 0xc5 +#define RR_SYNFB_LK BIT(15) +#define RR_AACK 0xca +#define RR_LCKST 0xcf +#define RR_LCKST_BIN BIT(0) +#define RR_LCK_TRG 0xd3 +#define RR_LCK_TRGSEL BIT(8) +#define RR_LCK_ST BIT(4) +#define RR_MMD 0xd5 +#define RR_MMD_RST_EN BIT(8) +#define RR_MMD_RST_SYN BIT(6) +#define RR_SMD 0xd6 +#define RR_VCO2 BIT(19) +#define RR_IQKPLL 0xdc +#define RR_IQKPLL_MOD GENMASK(9, 8) +#define RR_SYNLUT 0xdd +#define RR_SYNLUT_MOD BIT(4) +#define RR_RCKD 0xde +#define RR_RCKD_POW GENMASK(19, 13) +#define RR_RCKD_BW BIT(2) +#define RR_TXADBG 0xde +#define RR_LUTDBG 0xdf +#define RR_LUTDBG_TIA BIT(12) +#define RR_LUTDBG_LOK BIT(2) +#define RR_LUTPLL 0xec +#define RR_CAL_RW BIT(19) +#define RR_LUTWE2 0xee +#define RR_LUTWE2_RTXBW BIT(2) +#define RR_LUTWE2_DIS BIT(6) +#define RR_LUTWE 0xef +#define RR_LUTWE_LOK BIT(2) +#define RR_RFC 0xf0 +#define RR_WCAL BIT(16) +#define RR_RFC_CKEN BIT(1) + +#define R_UPD_P0 0x0000 +#define R_BBCLK 0x0000 +#define B_CLK_640M BIT(2) +#define R_RSTB_WATCH_DOG 0x000C +#define B_P0_RSTB_WATCH_DOG BIT(0) +#define B_P1_RSTB_WATCH_DOG BIT(1) +#define B_UPD_P0_EN BIT(31) +#define R_EMLSR 0x0044 +#define B_EMLSR_PARM GENMASK(27, 12) +#define R_CHK_LPS_STAT_BE4 0x3007C +#define R_CHK_LPS_STAT 0x0058 +#define B_CHK_LPS_STAT BIT(0) +#define R_SPOOF_CG 0x00B4 +#define B_SPOOF_CG_EN BIT(17) +#define R_CHINFO_SEG 0x00B4 +#define B_CHINFO_SEG_LEN GENMASK(2, 0) +#define B_CHINFO_SEG GENMASK(16, 7) +#define R_DFS_FFT_CG 0x00B8 +#define B_DFS_CG_EN BIT(1) +#define B_DFS_FFT_EN BIT(0) +#define R_CHINFO_DATA 0x00C0 +#define B_CHINFO_DATA_BITMAP GENMASK(22, 0) +#define R_INTF_R_INTF_RPT_SEL 0x0200 +#define R_INTF_R_INTF_RPT_SEL_BE4 0x20200 +#define B_INTF_R_INTF_RPT_SEL BIT(12) +#define R_ANAPAR_PW15 0x030C +#define B_ANAPAR_PW15 GENMASK(31, 24) +#define B_ANAPAR_PW15_H GENMASK(27, 24) +#define B_ANAPAR_PW15_H2 GENMASK(27, 26) +#define R_ANAPAR 0x032C +#define B_ANAPAR_15 GENMASK(31, 16) +#define B_ANAPAR_EN1 BIT(31) +#define B_ANAPAR_ADCCLK BIT(30) +#define B_ANAPAR_FLTRST BIT(22) +#define B_ANAPAR_CRXBB GENMASK(18, 16) +#define B_ANAPAR_EN BIT(16) +#define B_ANAPAR_14 GENMASK(15, 0) +#define R_RFE_E_A2 0x0334 +#define R_RFE_O_SEL_A2 0x0338 +#define R_RFE_SEL0_A2 0x033C +#define B_RFE_SEL0_MASK GENMASK(1, 0) +#define R_RFE_SEL32_A2 0x0340 +#define R_CIRST 0x035c +#define B_CIRST_SYN GENMASK(11, 10) +#define R_SWSI_DATA_V1 0x0370 +#define B_SWSI_DATA_VAL_V1 GENMASK(19, 0) +#define B_SWSI_DATA_ADDR_V1 GENMASK(27, 20) +#define B_SWSI_DATA_PATH_V1 GENMASK(30, 28) +#define B_SWSI_DATA_BIT_MASK_EN_V1 BIT(31) +#define R_SWSI_BIT_MASK_V1 0x0374 +#define B_SWSI_BIT_MASK_V1 GENMASK(19, 0) +#define R_SWSI_READ_ADDR_V1 0x0378 +#define B_SWSI_READ_ADDR_ADDR_V1 GENMASK(7, 0) +#define B_SWSI_READ_ADDR_PATH_V1 GENMASK(10, 8) +#define B_SWSI_READ_ADDR_V1 GENMASK(10, 0) +#define R_BRK_R 0x0418 +#define B_VHTMCS_LMT GENMASK(22, 21) +#define B_HTMCS_LMT GENMASK(9, 8) +#define R_BRK_EHT 0x0474 +#define B_RXEHT_NSS_MAX GENMASK(4, 2) +#define R_BRK_RXEHT 0x0478 +#define B_RXEHT_N_USER_MAX GENMASK(31, 24) +#define B_RXEHTTB_NSS_MAX GENMASK(16, 14) +#define R_EN_SND_WO_NDP 0x047c +#define R_EN_SND_WO_NDP_C1 0x147c +#define B_EN_SND_WO_NDP BIT(1) +#define R_BRK_HE 0x0480 +#define B_TB_NSS_MAX GENMASK(25, 23) +#define B_NSS_MAX GENMASK(16, 14) +#define B_N_USR_MAX GENMASK(13, 6) +#define R_RXCCA_BE1 0x0520 +#define B_RXCCA_BE1_DIS BIT(0) +#define R_UPD_CLK_ADC 0x0700 +#define B_UPD_GEN_ON BIT(27) +#define B_UPD_CLK_ADC_VAL GENMASK(26, 25) +#define B_UPD_CLK_ADC_ON BIT(24) +#define B_ENABLE_CCK BIT(5) +#define R_RSTB_ASYNC 0x0704 +#define B_RSTB_ASYNC_BW80 GENMASK(9, 8) +#define B_RSTB_ASYNC_ALL BIT(1) +#define R_P0_ANT_SW 0x0728 +#define B_P0_HW_ANTSW_DIS_BY_GNT_BT BIT(12) +#define B_P0_TRSW_TX_EXTEND GENMASK(3, 0) +#define R_RST_ALL_CNT 0x0730 +#define R_RST_ALL_CNT_BE4 0x20730 +#define B_RST_ALL_CNT BIT(0) +#define R_ENABLE_ALL_CNT 0x0730 +#define R_ENABLE_ALL_CNT_BE4 0x20730 +#define B_ENABLE_ALL_CNT BIT(1) +#define R_MAC_PIN_SEL 0x0734 +#define R_MAC_PIN_SEL_BE4 0x20734 +#define B_CH_IDX_SEG0 GENMASK(23, 16) +#define R_PLCP_HISTOGRAM 0x0738 +#define R_PLCP_HISTOGRAM_BE_V1 0x20738 +#define B_STS_PARSING_TIME GENMASK(19, 16) +#define B_STS_DIS_TRIG_BY_FAIL BIT(3) +#define B_STS_DIS_TRIG_BY_BRK BIT(2) +#define R_PHY_STS_BITMAP_ADDR_START R_PHY_STS_BITMAP_SEARCH_FAIL +#define R_PHY_STS_BITMAP_ADDR_START_BE4 0x2073C +#define B_PHY_STS_BITMAP_ADDR_MASK GENMASK(6, 2) +#define R_PHY_STS_BITMAP_SEARCH_FAIL 0x073C +#define B_PHY_STS_BITMAP_MSK_52A 0x337cff3f +#define R_PHY_STS_BITMAP_R2T 0x0740 +#define R_PHY_STS_BITMAP_CCA_SPOOF 0x0744 +#define R_PHY_STS_BITMAP_OFDM_BRK 0x0748 +#define R_PHY_STS_BITMAP_CCK_BRK 0x074C +#define R_PHY_STS_BITMAP_DL_MU_SPOOF 0x0750 +#define R_PHY_STS_BITMAP_HE_MU 0x0754 +#define R_PHY_STS_BITMAP_VHT_MU 0x0758 +#define R_PHY_STS_BITMAP_UL_TB_SPOOF 0x075C +#define R_PHY_STS_BITMAP_TRIGBASE 0x0760 +#define R_PHY_STS_BITMAP_CCK 0x0764 +#define R_PHY_STS_BITMAP_LEGACY 0x0768 +#define R_PHY_STS_BITMAP_HT 0x076C +#define R_PHY_STS_BITMAP_VHT 0x0770 +#define R_PHY_STS_BITMAP_HE 0x0774 +#define R_PHY_STS_BITMAP_EHT 0x0788 +#define R_PHY_STS_BITMAP_EHT_BE4 0x20788 +#define R_EDCCA_RPTREG_SEL_BE 0x078C +#define R_EDCCA_RPTREG_SEL_BE4 0x2078C +#define B_EDCCA_RPTREG_SEL_BE_MSK GENMASK(22, 20) +#define R_PMAC_GNT 0x0980 +#define B_PMAC_GNT_TXEN BIT(0) +#define B_PMAC_GNT_RXEN BIT(16) +#define B_PMAC_GNT_P1 GENMASK(20, 17) +#define B_PMAC_GNT_P2 GENMASK(29, 26) +#define R_PMAC_RX_CFG1 0x0988 +#define B_PMAC_OPT1_MSK GENMASK(11, 0) +#define R_PMAC_RXMOD 0x0994 +#define B_PMAC_RXMOD_MSK GENMASK(7, 4) +#define R_MAC_SEL 0x09A4 +#define B_MAC_SEL_OFDM_TRI_FILTER BIT(31) +#define B_MAC_SEL GENMASK(19, 17) +#define B_MAC_SEL_PWR_EN BIT(16) +#define B_MAC_SEL_DPD_EN BIT(10) +#define B_MAC_SEL_MOD GENMASK(4, 2) +#define R_PMAC_TX_CTRL 0x09C0 +#define B_PMAC_TXEN_DIS BIT(0) +#define R_PMAC_TX_PRD 0x09C4 +#define B_PMAC_TX_PRD_MSK GENMASK(31, 8) +#define B_PMAC_CTX_EN BIT(0) +#define B_PMAC_PTX_EN BIT(4) +#define R_PMAC_TX_CNT 0x09C8 +#define B_PMAC_TX_CNT_MSK GENMASK(31, 0) +#define R_P80_AT_HIGH_FREQ 0x09D8 +#define B_P80_AT_HIGH_FREQ BIT(26) +#define R_DBCC_80P80_SEL_EVM_RPT 0x0A10 +#define B_DBCC_80P80_SEL_EVM_RPT_EN BIT(0) +#define R_CCX 0x0C00 +#define R_CCX_BE4 0x20C00 +#define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4) +#define B_CCX_EDCCA_OPT_MSK_V1 GENMASK(7, 4) +#define B_MEASUREMENT_TRIG_MSK BIT(2) +#define B_CCX_TRIG_OPT_MSK BIT(1) +#define B_CCX_EN_MSK BIT(0) +#define R_NHM_CFG 0x0C08 +#define B_NHM_PERIOD_MSK GENMASK(15, 0) +#define B_NHM_COUNTER_MSK GENMASK(17, 16) +#define B_NHM_EN_MSK BIT(18) +#define B_NHM_INCLUDE_CCA_MSK BIT(19) +#define B_NHM_TH0_MSK GENMASK(31, 24) +#define R_NHM_TH1 0x0C0C +#define B_NHM_TH1_MSK GENMASK(7, 0) +#define B_NHM_TH2_MSK GENMASK(15, 8) +#define B_NHM_TH3_MSK GENMASK(23, 16) +#define B_NHM_TH4_MSK GENMASK(31, 24) +#define R_NHM_TH5 0x0C10 +#define B_NHM_TH5_MSK GENMASK(7, 0) +#define B_NHM_TH6_MSK GENMASK(15, 8) +#define B_NHM_TH7_MSK GENMASK(23, 16) +#define B_NHM_TH8_MSK GENMASK(31, 24) +#define R_NHM_TH9 0x0C14 +#define B_NHM_TH9_MSK GENMASK(7, 0) +#define B_NHM_TH10_MSK GENMASK(15, 8) +#define B_NHM_PWDB_METHOD_MSK GENMASK(17, 16) +#define R_FAHM 0x0C1C +#define B_RXTD_CKEN BIT(2) +#define R_IFS_COUNTER 0x0C28 +#define R_IFS_COUNTER_BE4 0x20C28 +#define B_IFS_CLM_PERIOD_MSK GENMASK(31, 16) +#define B_IFS_CLM_COUNTER_UNIT_MSK GENMASK(15, 14) +#define B_IFS_COUNTER_CLR_MSK BIT(13) +#define B_IFS_COLLECT_EN BIT(12) +#define R_IFS_T1 0x0C2C +#define R_IFS_T1_BE4 0x20C2C +#define B_IFS_T1_TH_HIGH_MSK GENMASK(31, 16) +#define B_IFS_T1_EN_MSK BIT(15) +#define B_IFS_T1_TH_LOW_MSK GENMASK(14, 0) +#define R_IFS_T2 0x0C30 +#define R_IFS_T2_BE4 0x20C30 +#define B_IFS_T2_TH_HIGH_MSK GENMASK(31, 16) +#define B_IFS_T2_EN_MSK BIT(15) +#define B_IFS_T2_TH_LOW_MSK GENMASK(14, 0) +#define R_IFS_T3 0x0C34 +#define R_IFS_T3_BE4 0x20C34 +#define B_IFS_T3_TH_HIGH_MSK GENMASK(31, 16) +#define B_IFS_T3_EN_MSK BIT(15) +#define B_IFS_T3_TH_LOW_MSK GENMASK(14, 0) +#define R_IFS_T4 0x0C38 +#define R_IFS_T4_BE4 0x20C38 +#define B_IFS_T4_TH_HIGH_MSK GENMASK(31, 16) +#define B_IFS_T4_EN_MSK BIT(15) +#define B_IFS_T4_TH_LOW_MSK GENMASK(14, 0) +#define R_PD_CTRL 0x0C3C +#define B_PD_HIT_DIS BIT(9) +#define R_IOQ_IQK_DPK 0x0C60 +#define R_IOQ_IQK_DPK_BE4 0x20C60 +#define B_IOQ_IQK_DPK_CLKEN GENMASK(1, 0) +#define B_IOQ_IQK_DPK_EN BIT(1) +#define B_IOQ_IQK_DPK_RST BIT(0) +#define R_GNT_BT_WGT_EN 0x0C6C +#define B_GNT_BT_WGT_EN BIT(21) +#define R_IQK_DPK_RST 0x0C6C +#define R_IQK_DPK_RST_BE4 0x20C6C +#define R_IQK_DPK_RST_C1 0x1C6C +#define B_IQK_DPK_RST BIT(0) +#define R_TX_COLLISION_T2R_ST 0x0C70 +#define B_TX_COLLISION_T2R_ST_M GENMASK(25, 20) +#define B_RX_CFIR_PATH_EN BIT(9) +#define B_RX_CFIR_PATH GENMASK(6, 5) +#define B_TXRX_FORCE_VAL GENMASK(9, 0) +#define R_TXGATING 0x0C74 +#define B_TXGATING_EN BIT(4) +#define R_TXRFC 0x0C7C +#define R_TXRFC_C1 0x1C7C +#define B_TXRFC_RST GENMASK(23, 21) +#define R_PD_ARBITER_OFF 0x0C80 +#define B_PD_ARBITER_OFF BIT(31) +#define R_SNDCCA_A1 0x0C9C +#define B_SNDCCA_A1_EN GENMASK(19, 12) +#define R_SNDCCA_A2 0x0CA0 +#define B_SNDCCA_A2_VAL GENMASK(19, 12) +#define R_UDP_COEEF 0x0CBC +#define B_UDP_COEEF BIT(19) +#define R_TX_COLLISION_T2R_ST_BE 0x0CC8 +#define R_TX_COLLISION_T2R_ST_BE4 0x20CC8 +#define B_TX_COLLISION_T2R_ST_BE_M GENMASK(13, 8) +#define R_RXHT_MCS_LIMIT 0x0D18 +#define B_RXHT_MCS_LIMIT GENMASK(9, 8) +#define R_RXVHT_MCS_LIMIT 0x0D18 +#define B_RXVHT_MCS_LIMIT GENMASK(22, 21) +#define R_BRK_OPT 0x0D44 +#define B_BRK_OPT BIT(31) +#define R_P0_EN_SOUND_WO_NDP 0x0D7C +#define B_P0_EN_SOUND_WO_NDP BIT(1) +#define R_RXHE 0x0D80 +#define B_RXHETB_MAX_NSS GENMASK(25, 23) +#define B_RXHE_MAX_NSS GENMASK(16, 14) +#define B_RXHE_USER_MAX GENMASK(13, 6) +#define R_SPOOF_ASYNC_RST 0x0D84 +#define B_SPOOF_ASYNC_RST BIT(15) +#define R_NDP_BRK0 0xDA0 +#define R_NDP_BRK1 0xDA4 +#define B_NDP_RU_BRK BIT(0) +#define R_BRK_ASYNC_RST_EN_1 0x0DC0 +#define R_BRK_ASYNC_RST_EN_2 0x0DC4 +#define R_BRK_ASYNC_RST_EN_3 0x0DC8 +#define R_NHM_BE 0x0EA4 +#define B_NHM_READY_BE_MSK BIT(16) +#define R_CTLTOP 0x1008 +#define B_CTLTOP_ON BIT(23) +#define B_CTLTOP_VAL GENMASK(15, 12) +#define R_CLK_GCK 0x1008 +#define B_CLK_GCK GENMASK(24, 0) +#define R_EDCCA_RPT_SEL_BE 0x10CC +#define R_ADC_FIFO_V1 0x10FC +#define B_ADC_FIFO_EN_V1 GENMASK(31, 24) +#define R_S0_HW_SI_DIS 0x1200 +#define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) +#define R_P0_RXCK 0x12A0 +#define B_P0_RXCK_ADJ GENMASK(31, 23) +#define B_P0_RXCK_BW3 BIT(30) +#define B_P0_TXCK_ALL GENMASK(19, 12) +#define B_P0_RXCK_ON BIT(19) +#define B_P0_RXCK_VAL GENMASK(18, 16) +#define B_P0_TXCK_ON BIT(15) +#define B_P0_TXCK_VAL GENMASK(14, 12) +#define R_P0_RFMODE 0x12AC +#define B_P0_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4) +#define B_P0_RFMODE_MUX GENMASK(11, 4) +#define R_P0_RFMODE_ORI_RX 0x12AC +#define B_P0_RFMODE_ORI_RX_ALL GENMASK(23, 12) +#define R_P0_RFMODE_FTM_RX 0x12B0 +#define B_P0_RFMODE_FTM_RX GENMASK(11, 0) +#define R_P0_NRBW 0x12B8 +#define B_P0_NRBW_DBG BIT(30) +#define B_P0_NRBW_RSTB BIT(28) +#define R_S0_RXDC 0x12D4 +#define B_S0_RXDC_I GENMASK(25, 16) +#define B_S0_RXDC_Q GENMASK(31, 26) +#define R_S0_RXDC2 0x12D8 +#define B_S0_RXDC2_SEL GENMASK(9, 8) +#define B_S0_RXDC2_AVG GENMASK(7, 6) +#define B_S0_RXDC2_MEN GENMASK(5, 4) +#define B_S0_RXDC2_Q2 GENMASK(3, 0) +#define R_CFO_COMP_SEG0_L 0x1384 +#define R_CFO_COMP_SEG0_H 0x1388 +#define R_CFO_COMP_SEG0_CTRL 0x138C +#define R_CNT_CCKTXEN 0x1700 +#define R_CNT_CCKTXEN_V1 0x2E00 +#define R_CNT_CCKTXEN_BE4 0x2CF00 +#define B_CNT_CCKTXEN GENMASK(31, 16) +#define R_CNT_CCKTXON 0x1704 +#define R_CNT_CCKTXON_V1 0x2E04 +#define R_CNT_CCKTXON_BE4 0x2CF04 +#define B_CNT_CCKTXON GENMASK(15, 0) +#define R_CNT_CCK_CCA_P0 0x1710 +#define R_CNT_CCK_CCA_P0_V1 0x2E10 +#define B_CNT_CCK_CCA_P0 GENMASK(15, 0) +#define R_CNT_CCK_CRC32_P0 0x1714 +#define R_CNT_CCK_CRC32_P0_V1 0x2E14 +#define B_CNT_CCK_CRC32OK_P0 GENMASK(15, 0) +#define B_CNT_CCK_CRC32FAIL_P0 GENMASK(31, 16) +#define R_DBG32_D 0x1730 +#define R_EDCCA_RPT_A 0x1738 +#define R_EDCCA_RPT_B 0x173c +#define B_EDCCA_RPT_B_FB BIT(7) +#define B_EDCCA_RPT_B_P20 BIT(6) +#define B_EDCCA_RPT_B_S20 BIT(5) +#define B_EDCCA_RPT_B_S40 BIT(4) +#define B_EDCCA_RPT_B_S80 BIT(3) +#define B_EDCCA_RPT_B_PATH_MASK GENMASK(2, 1) +#define R_EDCCA_RPT_P1_A 0x1740 +#define R_EDCCA_RPT_P1_B 0x1744 +#define R_SWSI_V1 0x174C +#define B_SWSI_W_BUSY_V1 BIT(24) +#define B_SWSI_R_BUSY_V1 BIT(25) +#define B_SWSI_R_DATA_DONE_V1 BIT(26) +#define R_TX_INFO_0_0_COMB 0x1800 +#define R_TX_INFO_0_0_COMB_V1 0x3E00 +#define R_TX_INFO_0_1_COMB 0x1804 +#define R_TX_INFO_0_1_COMB_V1 0x3E04 +#define R_TX_INFO_1_0_COMB 0x1808 +#define R_TX_INFO_1_0_COMB_V1 0x3E08 +#define R_TX_INFO_1_1_COMB 0x180C +#define R_TX_INFO_1_1_COMB_V1 0x3E0C +#define R_TX_INFO_2_0_COMB_V1 0x3E10 +#define R_TX_INFO_2_1_COMB_V1 0x3E14 +#define R_TX_COMMON_CTRL_0_0_COMB 0x1810 +#define R_TX_COMMON_CTRL_0_0_COMB_V1 0x3E20 +#define R_TX_COMMON_CTRL_0_1_COMB 0x1814 +#define R_TX_COMMON_CTRL_0_1_COMB_V1 0x3E24 +#define R_CNT_LSIG_BRK_S_TH 0x1A00 +#define R_CNT_LSIG_BRK_S_TH_V1 0x0E00 +#define R_CNT_LSIG_BRK_S_TH_BE4 0x20E00 +#define B_CNT_LSIG_BRK_S_TH GENMASK(31, 16) +#define R_CNT_CCA_SPOOFING 0x1A00 +#define R_CNT_CCA_SPOOFING_V1 0x0E00 +#define R_CNT_CCA_SPOOFING_BE4 0x20E00 +#define B_CNT_CCA_SPOOFING GENMASK(15, 0) +#define R_CNT_LSIG_BRK_L_TH 0x1A04 +#define R_CNT_LSIG_BRK_L_TH_V1 0x0E04 +#define R_CNT_LSIG_BRK_L_TH_BE4 0x20E04 +#define B_CNT_LSIG_BRK_L_TH GENMASK(15, 0) +#define R_CNT_BRK 0x1A08 +#define R_CNT_BRK_V1 0x0E08 +#define R_CNT_BRK_BE4 0x20E08 +#define B_CNT_BRK GENMASK(31, 16) +#define R_CNT_RXL_ERR_PARITY 0x1A0C +#define R_CNT_RXL_ERR_PARITY_V1 0x0E0C +#define R_CNT_RXL_ERR_PARITY_BE4 0x20E0C +#define B_CNT_RXL_ERR_PARITY GENMASK(31, 16) +#define R_CNT_RXL_ERR_RATE 0x1A10 +#define R_CNT_RXL_ERR_RATE_V1 0x0E10 +#define R_CNT_RXL_ERR_RATE_BE4 0x20E10 +#define B_CNT_RXL_ERR_RATE GENMASK(15, 0) +#define R_CNT_SEARCH_FAIL 0x1A20 +#define R_CNT_SEARCH_FAIL_V1 0x0E20 +#define R_CNT_SEARCH_FAIL_BE4 0x20E20 +#define B_CNT_SEARCH_FAIL GENMASK(31, 16) +#define R_CNT_OFDM_CCA 0x1A24 +#define R_CNT_OFDM_CCA_V1 0x0E24 +#define R_CNT_OFDM_CCA_BE4 0x20E24 +#define B_CNT_OFDM_CCA GENMASK(15, 0) +#define R_TX_COUNTER 0x1A40 +#define R_CNT_OFDMTXON 0x1A40 +#define R_CNT_OFDMTXON_V1 0x0E40 +#define R_CNT_OFDMTXON_BE4 0x20E40 +#define B_CNT_OFDMTXON GENMASK(15, 0) +#define B_CNT_OFDMTXEN GENMASK(31, 16) +#define R_CNT_HE_CRC 0x1A58 +#define R_CNT_HE_CRC_V1 0x0E58 +#define R_CNT_HE_CRC_BE4 0x20E58 +#define B_CNT_HE_CRC_OK GENMASK(15, 0) +#define B_CNT_HE_CRC_ERR GENMASK(31, 16) +#define R_CNT_VHT_CRC 0x1A5C +#define R_CNT_VHT_CRC_V1 0x0E5C +#define R_CNT_VHT_CRC_BE4 0x20E5C +#define B_CNT_VHT_CRC_OK GENMASK(15, 0) +#define B_CNT_VHT_CRC_ERR GENMASK(31, 16) +#define R_CNT_HT_CRC 0x1A60 +#define R_CNT_HT_CRC_V1 0x0E60 +#define R_CNT_HT_CRC_BE4 0x20E60 +#define B_CNT_HT_CRC_OK GENMASK(15, 0) +#define B_CNT_HT_CRC_ERR GENMASK(31, 16) +#define R_CNT_L_CRC 0x1A64 +#define R_CNT_L_CRC_V1 0x0E64 +#define R_CNT_L_CRC_BE4 0x20E64 +#define B_CNT_L_CRC_OK GENMASK(15, 0) +#define B_CNT_L_CRC_ERR GENMASK(31, 16) +#define R_CNT_AMPDU_MISS 0x1A7C +#define R_CNT_AMPDU_MISS_V1 0x0E7C +#define R_CNT_AMPDU_MISS_BE4 0x20E7C +#define B_CNT_AMPDU_MISS GENMASK(31, 16) +#define R_CNT_AMPDU_RX_CRC32 0x1A80 +#define R_CNT_AMPDU_RX_CRC32_V1 0x0E80 +#define R_CNT_AMPDU_RX_CRC32_BE4 0x20E80 +#define B_CNT_AMPDU_RX_CRC32_OK GENMASK(15, 0) +#define B_CNT_AMPDU_RX_CRC32_ERR GENMASK(31, 16) +#define R_NHM_CNT0 0x1A88 +#define B_NHM_CNT0_MSK GENMASK(15, 0) +#define B_NHM_CNT1_MSK GENMASK(31, 16) +#define R_NHM_CNT2 0x1A8C +#define B_NHM_CNT2_MSK GENMASK(15, 0) +#define B_NHM_CNT3_MSK GENMASK(31, 16) +#define R_NHM_CNT4 0x1A90 +#define B_NHM_CNT4_MSK GENMASK(15, 0) +#define B_NHM_CNT5_MSK GENMASK(31, 16) +#define R_NHM_CNT6 0x1A94 +#define B_NHM_CNT6_MSK GENMASK(15, 0) +#define B_NHM_CNT7_MSK GENMASK(31, 16) +#define R_NHM_CNT8 0x1A98 +#define B_NHM_CNT8_MSK GENMASK(15, 0) +#define B_NHM_CNT9_MSK GENMASK(31, 16) +#define R_NHM_CNT10 0x1A9C +#define B_NHM_CNT10_MSK GENMASK(15, 0) +#define B_NHM_CNT11_MSK GENMASK(31, 16) +#define R_NHM_AX 0x1AA4 +#define B_NHM_READY_MSK BIT(16) +#define R_CLM_EDCCA_RESULT 0x1AC8 +#define R_CLM_EDCCA_RESULT_V1 0x0EC8 +#define R_CLM_EDCCA_RESULT_BE4 0x20EC8 +#define B_CLM_EDCCA_RESULT GENMASK(15, 0) +#define R_CLM_EDCCA_RDY 0x1AC8 +#define R_CLM_EDCCA_RDY_V1 0x0EC8 +#define R_CLM_EDCCA_RDY_BE4 0x20EC8 +#define B_CLM_EDCCA_RDY BIT(16) +#define R_IFS_CLM_TX_CNT 0x1ACC +#define R_IFS_CLM_TX_CNT_V1 0x0ECC +#define R_IFS_CLM_TX_CNT_BE4 0x20ECC +#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16) +#define B_IFS_CLM_TX_CNT_MSK GENMASK(15, 0) +#define R_IFS_CLM_CCA 0x1AD0 +#define R_IFS_CLM_CCA_V1 0x0ED0 +#define R_IFS_CLM_CCA_BE4 0x20ED0 +#define B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK GENMASK(31, 16) +#define B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK GENMASK(15, 0) +#define R_IFS_CLM_FA 0x1AD4 +#define R_IFS_CLM_FA_V1 0x0ED4 +#define R_IFS_CLM_FA_BE4 0x20ED4 +#define B_IFS_CLM_OFDM_FA_MSK GENMASK(31, 16) +#define B_IFS_CLM_CCK_FA_MSK GENMASK(15, 0) +#define R_IFS_HIS 0x1AD8 +#define R_IFS_HIS_V1 0x0ED8 +#define B_IFS_T4_HIS_MSK GENMASK(31, 24) +#define B_IFS_T3_HIS_MSK GENMASK(23, 16) +#define B_IFS_T2_HIS_MSK GENMASK(15, 8) +#define B_IFS_T1_HIS_MSK GENMASK(7, 0) +#define R_IFS_AVG_L 0x1ADC +#define R_IFS_AVG_L_V1 0x0EDC +#define B_IFS_T2_AVG_MSK GENMASK(31, 16) +#define B_IFS_T1_AVG_MSK GENMASK(15, 0) +#define R_IFS_AVG_H 0x1AE0 +#define R_IFS_AVG_H_V1 0x0EE0 +#define B_IFS_T4_AVG_MSK GENMASK(31, 16) +#define B_IFS_T3_AVG_MSK GENMASK(15, 0) +#define R_IFS_CCA_L 0x1AE4 +#define R_IFS_CCA_L_V1 0x0EE4 +#define B_IFS_T2_CCA_MSK GENMASK(31, 16) +#define B_IFS_T1_CCA_MSK GENMASK(15, 0) +#define R_IFS_CCA_H 0x1AE8 +#define R_IFS_CCA_H_V1 0x0EE8 +#define B_IFS_T4_CCA_MSK GENMASK(31, 16) +#define B_IFS_T3_CCA_MSK GENMASK(15, 0) +#define R_IFSCNT 0x1AEC +#define R_IFSCNT_V1 0x0EEC +#define B_IFSCNT_DONE_MSK BIT(16) +#define B_IFSCNT_TOTAL_CNT_MSK GENMASK(15, 0) +#define R_TXAGC_TP 0x1C04 +#define B_TXAGC_TP GENMASK(2, 0) +#define R_TSSI_THER 0x1C10 +#define B_TSSI_THER GENMASK(29, 24) +#define R_TSSI_CWRPT 0x1C18 +#define B_TSSI_CWRPT_RDY BIT(16) +#define B_TSSI_CWRPT GENMASK(8, 0) +#define R_TXAGC_BTP 0x1CA0 +#define B_TXAGC_BTP GENMASK(31, 24) +#define R_TXAGC_BB 0x1C60 +#define B_TXAGC_BB_OFT GENMASK(31, 16) +#define B_TXAGC_BB GENMASK(31, 24) +#define B_TXAGC_RF GENMASK(5, 0) +#define R_PATH0_TXPWR 0x1C78 +#define R_PATH0_TXPWR_V1 0xEE0C +#define R_PATH0_TXPWR_BE4 0x2F90C +#define B_PATH0_TXPWR GENMASK(8, 0) +#define R_S0_ADDCK 0x1E00 +#define B_S0_ADDCK_I GENMASK(9, 0) +#define B_S0_ADDCK_Q GENMASK(19, 10) +#define R_TXCKEN_FORCE 0x2008 +#define B_TXCKEN_FORCE_ALL GENMASK(24, 0) +#define R_EDCCA_RPT_SEL 0x20CC +#define B_EDCCA_RPT_SEL_MSK GENMASK(2, 0) +#define B_EDCCA_RPT_SEL_P1_MSK GENMASK(5, 3) +#define R_ADC_FIFO 0x20fc +#define B_ADC_FIFO_RST GENMASK(31, 24) +#define B_ADC_FIFO_RXK GENMASK(31, 16) +#define B_ADC_FIFO_A3 BIT(28) +#define B_ADC_FIFO_A2 BIT(24) +#define B_ADC_FIFO_A1 BIT(20) +#define B_ADC_FIFO_A0 BIT(16) +#define R_TXFIR0 0x2300 +#define B_TXFIR_C01 GENMASK(23, 0) +#define R_TXFIR2 0x2304 +#define B_TXFIR_C23 GENMASK(23, 0) +#define R_TXFIR4 0x2308 +#define B_TXFIR_C45 GENMASK(23, 0) +#define R_TXFIR6 0x230c +#define B_TXFIR_C67 GENMASK(23, 0) +#define R_TXFIR8 0x2310 +#define B_TXFIR_C89 GENMASK(23, 0) +#define R_TXFIRA 0x2314 +#define B_TXFIR_CAB GENMASK(23, 0) +#define R_TXFIRC 0x2318 +#define B_TXFIR_CCD GENMASK(23, 0) +#define R_TXFIRE 0x231c +#define B_TXFIR_CEF GENMASK(23, 0) +#define R_11B_RX_V1 0x2320 +#define B_11B_RXCCA_DIS_V1 BIT(0) +#define R_RPL_OFST 0x2340 +#define B_RPL_OFST_MASK GENMASK(14, 8) +#define R_RXCCA 0x2344 +#define B_RXCCA_DIS BIT(31) +#define R_RXCCA_V1 0x2320 +#define B_RXCCA_DIS_V1 BIT(0) +#define R_RXSC 0x237C +#define B_RXSC_EN BIT(0) +#define R_R1B_RR_SEL 0x2388 +#define B_R1B_RR_SEL GENMASK(24, 23) +#define R_R1B_RX_RPT_RST 0x2388 +#define R_R1B_RX_RPT_RST_V1 0x2340 +#define R_R1B_RX_RPT_RST_BE 0x0540 +#define R_R1B_RX_RPT_RST_BE4 0x20540 +#define B_R1B_RX_RPT_RST BIT(15) +#define B_R1B_RX_RPT_RST_V1 BIT(7) +#define R_BRK_CNT 0x239C +#define R_BRK_CNT_V1 0x059C +#define R_BRK_CNT_BE4 0x2059C +#define B_BRK_CNT GENMASK(31, 16) +#define R_RX_RPL_OFST 0x23AC +#define B_RX_RPL_OFST_CCK_MASK GENMASK(6, 0) +#define R_RXSCOBC 0x23B0 +#define B_RXSCOBC_TH GENMASK(18, 0) +#define R_RXSCOCCK 0x23B4 +#define B_RXSCOCCK_TH GENMASK(18, 0) +#define R_SFD_GG_CNT 0x23E0 +#define R_SFD_GG_CNT_V1 0x23A0 +#define R_SFD_GG_CNT_V2 0x05A0 +#define R_SFD_GG_CNT_BE4 0x205A0 +#define B_SFD_GG_CNT GENMASK(15, 0) +#define R_SIG_GG_CNT 0x23E8 +#define R_SIG_GG_CNT_V1 0x23AC +#define R_SIG_GG_CNT_V2 0x05AC +#define R_SIG_GG_CNT_BE4 0x205AC +#define B_SIG_GG_CNT GENMASK(15, 0) +#define B_SIG_GG_CNT_V1 GENMASK(15, 8) +#define R_SPOOF_CNT 0x23EC +#define R_SPOOF_CNT_V1 0x23A8 +#define R_SPOOF_CNT_V2 0x05A8 +#define R_SPOOF_CNT_BE4 0x205A8 +#define B_SPOOF_CNT GENMASK(7, 0) +#define B_SPOOF_CNT_V1 GENMASK(31, 16) +#define R_P80_AT_HIGH_FREQ_RU_ALLOC 0x2410 +#define B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1 BIT(14) +#define B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0 BIT(13) +#define R_DBCC_80P80_SEL_EVM_RPT2 0x2A10 +#define B_DBCC_80P80_SEL_EVM_RPT2_EN BIT(0) +#define R_AFEDAC0 0x2A5C +#define B_AFEDAC0 GENMASK(31, 27) +#define R_AFEDAC1 0x2A60 +#define B_AFEDAC1 GENMASK(2, 0) +#define R_IQKDPK_HC 0x2AB8 +#define B_IQKDPK_HC BIT(28) +#define R_HWSI_ADD0 0x2ADC +#define R_HWSI_ADD1 0x2BDC +#define B_HWSI_ADD_MASK GENMASK(11, 4) +#define B_HWSI_ADD_CTL_MASK GENMASK(2, 0) +#define B_HWSI_ADD_RD BIT(2) +#define B_HWSI_ADD_POLL_MASK GENMASK(1, 0) +#define B_HWSI_ADD_RUN BIT(1) +#define B_HWSI_ADD_BUSY BIT(0) +#define R_HWSI_DATA 0x2AE0 +#define B_HWSI_DATA_VAL GENMASK(27, 8) +#define B_HWSI_DATA_ADDR GENMASK(7, 0) +#define R_HWSI_VAL0 0x2C24 +#define R_HWSI_VAL1 0x2D24 +#define B_HWSI_VAL_RDONE BIT(31) +#define B_HWSI_VAL_BUSY BIT(29) +#define R_P1_EN_SOUND_WO_NDP 0x2D7C +#define B_P1_EN_SOUND_WO_NDP BIT(1) +#define R_EDCCA_RPT_A_BE 0x2E38 +#define R_EDCCA_RPT_A_BE4 0x2EE30 +#define R_EDCCA_RPT_A_BE4_C1 0x2FE30 +#define R_EDCCA_RPT_B_BE 0x2E3C +#define R_EDCCA_RPT_B_BE4 0x2EE34 +#define R_EDCCA_RPT_B_BE4_C1 0x2FE34 +#define R_EDCCA_RPT_P1_A_BE 0x2E40 +#define R_EDCCA_RPT_P1_B_BE 0x2E44 +#define R_CNT_EHT_CRC 0x2F00 +#define R_CNT_EHT_CRC_BE4 0x22F00 +#define B_CNT_EHT_CRC_OK GENMASK(15, 0) +#define B_CNT_EHT_CRC_ERR GENMASK(31, 16) +#define R_S1_HW_SI_DIS 0x3200 +#define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) +#define R_P1_RXCK 0x32A0 +#define B_P1_RXCK_BW3 BIT(30) +#define B_P1_TXCK_ALL GENMASK(19, 12) +#define B_P1_RXCK_ON BIT(19) +#define B_P1_RXCK_VAL GENMASK(18, 16) +#define R_P1_RFMODE 0x32AC +#define B_P1_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4) +#define B_P1_RFMODE_MUX GENMASK(11, 4) +#define R_P1_RFMODE_ORI_RX 0x32AC +#define B_P1_RFMODE_ORI_RX_ALL GENMASK(23, 12) +#define R_P1_RFMODE_FTM_RX 0x32B0 +#define B_P1_RFMODE_FTM_RX GENMASK(11, 0) +#define R_P1_DBGMOD 0x32B8 +#define B_P1_DBGMOD_ON BIT(30) +#define R_S1_RXDC 0x32D4 +#define B_S1_RXDC_I GENMASK(25, 16) +#define B_S1_RXDC_Q GENMASK(31, 26) +#define R_S1_RXDC2 0x32D8 +#define B_S1_RXDC2_EN GENMASK(5, 4) +#define B_S1_RXDC2_SEL GENMASK(9, 8) +#define B_S1_RXDC2_Q2 GENMASK(3, 0) +#define R_TXAGC_BB_S1 0x3C60 +#define B_TXAGC_BB_S1_OFT GENMASK(31, 16) +#define B_TXAGC_BB_S1 GENMASK(31, 24) +#define R_PATH1_TXPWR 0x3C78 +#define R_PATH1_TXPWR_V1 0xEF0C +#define R_PATH1_TXPWR_BE4 0x2FA0C +#define B_PATH1_TXPWR GENMASK(8, 0) +#define R_S1_ADDCK 0x3E00 +#define B_S1_ADDCK_I GENMASK(9, 0) +#define B_S1_ADDCK_Q GENMASK(19, 10) +#define R_OP1DB_A 0x40B0 +#define B_OP1DB_A GENMASK(31, 24) +#define R_OP1DB1_A 0x40BC +#define B_TIA10_A GENMASK(15, 0) +#define B_TIA1_A GENMASK(15, 8) +#define B_TIA0_A GENMASK(7, 0) +#define R_BKOFF_A 0x40E0 +#define B_BKOFF_IBADC_A GENMASK(23, 18) +#define R_BACKOFF_A 0x40E4 +#define B_LNA_IBADC_A GENMASK(29, 18) +#define B_BACKOFF_LNA_A GENMASK(29, 24) +#define B_BACKOFF_IBADC_A GENMASK(23, 18) +#define R_RXBY_WBADC_A 0x40F4 +#define B_RXBY_WBADC_A GENMASK(14, 10) +#define R_MUIC 0x40F8 +#define B_MUIC_EN BIT(0) +#define R_BT_RXBY_WBADC_A 0x4160 +#define B_BT_RXBY_WBADC_A BIT(31) +#define R_BT_SHARE_A 0x4164 +#define B_BT_SHARE_A BIT(0) +#define B_BT_TRK_OFF_A BIT(1) +#define B_BTG_PATH_A BIT(4) +#define R_FORCE_FIR_A 0x418C +#define B_FORCE_FIR_A GENMASK(1, 0) +#define R_DCFO 0x4264 +#define B_DCFO GENMASK(7, 0) +#define R_SEG0CSI 0x42AC +#define R_SEG0CSI_V1 0x42B0 +#define B_SEG0CSI_IDX GENMASK(10, 0) +#define R_SEG0CSI_EN 0x42C4 +#define R_SEG0CSI_EN_V1 0x42C8 +#define B_SEG0CSI_EN BIT(23) +#define R_BSS_CLR_MAP 0x43ac +#define R_BSS_CLR_MAP_V1 0x43B0 +#define R_BSS_CLR_MAP_V2 0x4EB0 +#define B_BSS_CLR_MAP_VLD0 BIT(28) +#define B_BSS_CLR_MAP_TGT GENMASK(27, 22) +#define B_BSS_CLR_MAP_STAID GENMASK(21, 11) +#define R_CFO_TRK0 0x4404 +#define R_CFO_TRK1 0x440C +#define B_CFO_TRK_MSK GENMASK(14, 10) +#define R_T2F_GI_COMB 0x4424 +#define B_T2F_GI_COMB_EN BIT(2) +#define R_BT_DYN_DC_EST_EN 0x441C +#define R_BT_DYN_DC_EST_EN_V1 0x4420 +#define B_BT_DYN_DC_EST_EN_MSK BIT(31) +#define R_ASSIGN_SBD_OPT_V1 0x4440 +#define B_ASSIGN_SBD_OPT_EN_V1 BIT(31) +#define R_ASSIGN_SBD_OPT 0x4450 +#define B_ASSIGN_SBD_OPT_EN BIT(24) +#define R_DCFO_COMP_S0 0x448C +#define B_DCFO_COMP_S0_MSK GENMASK(11, 0) +#define R_DCFO_WEIGHT 0x4490 +#define B_DAC_CLK_IDX BIT(31) +#define B_DCFO_WEIGHT_MSK GENMASK(27, 24) +#define R_DCFO_OPT 0x4494 +#define B_DCFO_OPT_EN BIT(29) +#define B_TXSHAPE_TRIANGULAR_CFG GENMASK(25, 24) +#define R_BANDEDGE 0x4498 +#define B_BANDEDGE_EN BIT(30) +#define R_DPD_BF 0x44a0 +#define B_DPD_BF_OFDM GENMASK(16, 12) +#define B_DPD_BF_SCA GENMASK(6, 0) +#define R_LNA_OP 0x44B0 +#define B_LNA6 GENMASK(31, 24) +#define R_LNA_TIA 0x44BC +#define B_TIA10_B GENMASK(15, 0) +#define B_TIA1_B GENMASK(15, 8) +#define B_TIA0_B GENMASK(7, 0) +#define R_BKOFF_B 0x44E0 +#define B_BKOFF_IBADC_B GENMASK(23, 18) +#define R_BACKOFF_B 0x44E4 +#define B_LNA_IBADC_B GENMASK(29, 18) +#define B_BACKOFF_LNA_B GENMASK(29, 24) +#define B_BACKOFF_IBADC_B GENMASK(23, 18) +#define R_RXBY_WBADC_B 0x44F4 +#define B_RXBY_WBADC_B GENMASK(14, 10) +#define R_BT_RXBY_WBADC_B 0x4560 +#define B_BT_RXBY_WBADC_B BIT(31) +#define R_BT_SHARE_B 0x4564 +#define B_BT_SHARE_B BIT(0) +#define B_BT_TRK_OFF_B BIT(1) +#define B_BTG_PATH_B BIT(4) +#define R_TXPATH_SEL 0x458C +#define B_TXPATH_SEL_MSK GENMASK(31, 28) +#define R_FORCE_FIR_B 0x458C +#define B_FORCE_FIR_B GENMASK(1, 0) +#define R_TXPWR 0x4594 +#define B_TXPWR_MSK GENMASK(30, 22) +#define R_TXNSS_MAP 0x45B4 +#define B_TXNSS_MAP_MSK GENMASK(20, 17) +#define R_PCOEFF0_V1 0x45BC +#define B_PCOEFF01_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF2_V1 0x45CC +#define B_PCOEFF23_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF4_V1 0x45D0 +#define B_PCOEFF45_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF6_V1 0x45D4 +#define B_PCOEFF67_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF8_V1 0x45D8 +#define B_PCOEFF89_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFA_V1 0x45C0 +#define B_PCOEFFAB_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFC_V1 0x45C4 +#define B_PCOEFFCD_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFE_V1 0x45C8 +#define B_PCOEFFEF_MSK_V1 GENMASK(23, 0) +#define R_PATH0_IB_PKPW 0x4628 +#define B_PATH0_IB_PKPW_MSK GENMASK(11, 6) +#define R_PATH0_LNA_ERR1 0x462C +#define B_PATH0_LNA_ERR_G1_A_MSK GENMASK(29, 24) +#define B_PATH0_LNA_ERR_G0_G_MSK GENMASK(17, 12) +#define B_PATH0_LNA_ERR_G0_A_MSK GENMASK(11, 6) +#define R_PATH0_LNA_ERR2 0x4630 +#define B_PATH0_LNA_ERR_G2_G_MSK GENMASK(23, 18) +#define B_PATH0_LNA_ERR_G2_A_MSK GENMASK(17, 12) +#define B_PATH0_LNA_ERR_G1_G_MSK GENMASK(5, 0) +#define R_PATH0_LNA_ERR3 0x4634 +#define B_PATH0_LNA_ERR_G4_G_MSK GENMASK(29, 24) +#define B_PATH0_LNA_ERR_G4_A_MSK GENMASK(23, 18) +#define B_PATH0_LNA_ERR_G3_G_MSK GENMASK(11, 6) +#define B_PATH0_LNA_ERR_G3_A_MSK GENMASK(5, 0) +#define R_PATH0_LNA_ERR4 0x4638 +#define B_PATH0_LNA_ERR_G6_A_MSK GENMASK(29, 24) +#define B_PATH0_LNA_ERR_G5_G_MSK GENMASK(17, 12) +#define B_PATH0_LNA_ERR_G5_A_MSK GENMASK(11, 6) +#define R_PATH0_LNA_ERR5 0x463C +#define B_PATH0_LNA_ERR_G6_G_MSK GENMASK(5, 0) +#define R_PATH0_TIA_ERR_G0 0x4640 +#define B_PATH0_TIA_ERR_G0_G_MSK GENMASK(23, 18) +#define B_PATH0_TIA_ERR_G0_A_MSK GENMASK(17, 12) +#define R_PATH0_TIA_ERR_G1 0x4644 +#define B_PATH0_TIA_ERR_G1_SEL GENMASK(31, 30) +#define B_PATH0_TIA_ERR_G1_G_MSK GENMASK(11, 6) +#define B_PATH0_TIA_ERR_G1_A_MSK GENMASK(5, 0) +#define R_PATH0_IB_PBK 0x4650 +#define B_PATH0_IB_PBK_MSK GENMASK(14, 10) +#define R_PATH0_RXB_INIT 0x4658 +#define B_PATH0_RXB_INIT_IDX_MSK GENMASK(9, 5) +#define R_PATH0_LNA_INIT 0x4668 +#define R_PATH0_LNA_INIT_V1 0x472C +#define B_PATH0_LNA_INIT_IDX_MSK GENMASK(26, 24) +#define R_PATH0_BTG 0x466C +#define B_PATH0_BTG_SHEN GENMASK(18, 17) +#define R_PATH0_TIA_INIT 0x4674 +#define B_PATH0_TIA_INIT_IDX_MSK BIT(17) +#define R_PATH0_P20_FOLLOW_BY_PAGCUGC 0x46A0 +#define R_PATH0_P20_FOLLOW_BY_PAGCUGC_V1 0x4C24 +#define R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2 0x46E8 +#define R_PATH0_P20_FOLLOW_BY_PAGCUGC_V3 0x41C8 +#define R_PATH0_P20_FOLLOW_BY_PAGCUGC_BE4 0x241C8 +#define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4 +#define R_PATH0_S20_FOLLOW_BY_PAGCUGC_V1 0x4C28 +#define R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2 0x46EC +#define R_PATH0_S20_FOLLOW_BY_PAGCUGC_V3 0x41CC +#define R_PATH0_S20_FOLLOW_BY_PAGCUGC_BE4 0x241CC +#define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH0_RXB_INIT_V1 0x46A8 +#define B_PATH0_RXB_INIT_IDX_MSK_V1 GENMASK(14, 10) +#define R_PATH0_G_LNA6_OP1DB_V1 0x4688 +#define B_PATH0_G_LNA6_OP1DB_V1 GENMASK(31, 24) +#define R_PATH0_G_TIA0_LNA6_OP1DB_V1 0x4694 +#define B_PATH0_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) +#define R_PATH0_G_TIA1_LNA6_OP1DB_V1 0x4694 +#define B_PATH0_R_G_OFST_MASK GENMASK(23, 16) +#define B_PATH0_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8) +#define R_CDD_EVM_CHK_EN 0x46C0 +#define B_CDD_EVM_CHK_EN BIT(0) +#define R_PATH0_BAND_SEL_V1 0x4738 +#define B_PATH0_BAND_SEL_MSK_V1 BIT(17) +#define B_PATH0_BAND_NRBW_EN_V1 BIT(16) +#define R_PATH0_BT_SHARE_V1 0x4738 +#define B_PATH0_BT_SHARE_V1 BIT(19) +#define R_PATH0_BTG_PATH_V1 0x4738 +#define B_PATH0_BTG_PATH_V1 BIT(22) +#define R_P0_NBIIDX 0x469C +#define B_P0_NBIIDX_VAL GENMASK(11, 0) +#define B_P0_NBIIDX_NOTCH_EN BIT(12) +#define R_P0_BACKOFF_IBADC_V1 0x469C +#define B_P0_BACKOFF_IBADC_V1 GENMASK(31, 26) +#define B_P0_NBIIDX_NOTCH_EN_V1 BIT(12) +#define R_P1_MODE 0x4718 +#define B_P1_MODE_SEL GENMASK(31, 30) +#define R_P0_AGC_CTL 0x4730 +#define B_P0_AGC_EN BIT(31) +#define R_PATH1_LNA_INIT 0x473C +#define R_PATH1_LNA_INIT_V1 0x4A80 +#define B_PATH1_LNA_INIT_IDX_MSK GENMASK(26, 24) +#define R_PATH0_TIA_INIT_V1 0x473C +#define B_PATH0_TIA_INIT_IDX_MSK_V1 BIT(9) +#define R_PATH1_TIA_INIT 0x4748 +#define B_PATH1_TIA_INIT_IDX_MSK BIT(17) +#define R_PATH1_BTG 0x4740 +#define B_PATH1_BTG_SHEN GENMASK(18, 17) +#define R_PATH1_RXB_INIT 0x472C +#define B_PATH1_RXB_INIT_IDX_MSK GENMASK(9, 5) +#define R_PATH1_G_LNA6_OP1DB_V1 0x476C +#define B_PATH1_G_LNA6_OP1DB_V1 GENMASK(31, 24) +#define R_PATH1_P20_FOLLOW_BY_PAGCUGC 0x4774 +#define R_PATH1_P20_FOLLOW_BY_PAGCUGC_V1 0x4CE8 +#define R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2 0x47A8 +#define R_PATH1_P20_FOLLOW_BY_PAGCUGC_V3 0x45C8 +#define R_PATH1_P20_FOLLOW_BY_PAGCUGC_BE4 0x245C8 +#define B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH1_S20_FOLLOW_BY_PAGCUGC 0x4778 +#define R_PATH1_S20_FOLLOW_BY_PAGCUGC_V1 0x4CEC +#define R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2 0x47AC +#define R_PATH1_S20_FOLLOW_BY_PAGCUGC_V3 0x45CC +#define R_PATH1_S20_FOLLOW_BY_PAGCUGC_BE4 0x245CC +#define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH1_G_TIA0_LNA6_OP1DB_V1 0x4778 +#define B_PATH1_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) +#define R_PATH1_G_TIA1_LNA6_OP1DB_V1 0x4778 +#define B_PATH1_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8) +#define R_PATH1_BAND_SEL_V1 0x4AA4 +#define B_PATH1_BAND_SEL_MSK_V1 BIT(17) +#define B_PATH1_BAND_NRBW_EN_V1 BIT(16) +#define R_PATH1_BT_SHARE_V1 0x4AA4 +#define B_PATH1_BT_SHARE_V1 BIT(19) +#define R_PATH1_BTG_PATH_V1 0x4AA4 +#define B_PATH1_BTG_PATH_V1 BIT(22) +#define R_P1_NBIIDX 0x4770 +#define B_P1_NBIIDX_VAL GENMASK(11, 0) +#define B_P1_NBIIDX_NOTCH_EN BIT(12) +#define R_PKT_CTRL 0x47D4 +#define B_PKT_POP_EN BIT(8) +#define R_SEG0R_PD 0x481C +#define R_SEG0R_PD_V1 0x4860 +#define R_SEG0R_PD_V2 0x6A74 +#define R_SEG0R_PD_BE4 0x26210 +#define R_SEG0R_EDCCA_LVL 0x4840 +#define R_SEG0R_EDCCA_LVL_V1 0x4884 +#define B_EDCCA_LVL_MSK3 GENMASK(31, 24) +#define B_EDCCA_LVL_MSK1 GENMASK(15, 8) +#define B_EDCCA_LVL_MSK0 GENMASK(7, 0) +#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30) +#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29) +#define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6) +#define R_PWOFST 0x488C +#define B_PWOFST GENMASK(21, 17) +#define R_2P4G_BAND 0x4970 +#define B_2P4G_BAND_SEL BIT(1) +#define R_FC0_BW 0x4974 +#define R_FC0_BW_V1 0x49C0 +#define B_FC0_BW_SET GENMASK(31, 30) +#define B_ANT_RX_BT_SEG0 GENMASK(25, 22) +#define B_ANT_RX_1RCCA_SEG1 GENMASK(21, 18) +#define B_ANT_RX_1RCCA_SEG0 GENMASK(17, 14) +#define B_FC0_BW_INV GENMASK(6, 0) +#define R_Q_MATRIX_00 0x497C +#define B_Q_MATRIX_00_IMAGINARY GENMASK(15, 0) +#define B_Q_MATRIX_00_REAL GENMASK(31, 16) +#define R_CHBW_MOD 0x4978 +#define R_CHBW_MOD_V1 0x49C4 +#define B_BT_SHARE BIT(14) +#define B_CHBW_MOD_SBW GENMASK(13, 12) +#define B_CHBW_MOD_PRICH GENMASK(11, 8) +#define B_ANT_RX_SEG0 GENMASK(3, 0) +#define R_Q_MATRIX_11 0x4988 +#define B_Q_MATRIX_11_IMAGINARY GENMASK(15, 0) +#define B_Q_MATRIX_11_REAL GENMASK(31, 16) +#define R_CUSTOMIZE_Q_MATRIX 0x498C +#define B_CUSTOMIZE_Q_MATRIX_EN BIT(0) +#define R_P0_RPL1 0x49B0 +#define B_P0_RPL1_41_MASK GENMASK(31, 24) +#define B_P0_RPL1_40_MASK GENMASK(23, 16) +#define B_P0_RPL1_20_MASK GENMASK(15, 8) +#define B_P0_RPL1_MASK (B_P0_RPL1_41_MASK | B_P0_RPL1_40_MASK | B_P0_RPL1_20_MASK) +#define B_P0_RPL1_SHIFT 8 +#define B_P0_RPL1_BIAS_MASK GENMASK(7, 0) +#define R_P0_RPL2 0x49B4 +#define B_P0_RTL2_8A_MASK GENMASK(31, 24) +#define B_P0_RTL2_81_MASK GENMASK(23, 16) +#define B_P0_RTL2_80_MASK GENMASK(15, 8) +#define B_P0_RTL2_42_MASK GENMASK(7, 0) +#define R_P0_RPL3 0x49B8 +#define B_P0_RTL3_89_MASK GENMASK(31, 24) +#define B_P0_RTL3_84_MASK GENMASK(23, 16) +#define B_P0_RTL3_83_MASK GENMASK(15, 8) +#define B_P0_RTL3_82_MASK GENMASK(7, 0) +#define R_PD_BOOST_EN 0x49E8 +#define B_PD_BOOST_EN BIT(7) +#define R_P1_BACKOFF_IBADC_V1 0x49F0 +#define B_P1_BACKOFF_IBADC_V1 GENMASK(31, 26) +#define R_P1_RPL1 0x4A00 +#define R_P1_RPL2 0x4A04 +#define R_P1_RPL3 0x4A08 +#define R_BK_FC0_INV_V1 0x4A1C +#define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_CCK_FC0_INV_V1 0x4A20 +#define B_CCK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_PATH1_RXB_INIT_V1 0x4A5C +#define B_PATH1_RXB_INIT_IDX_MSK_V1 GENMASK(14, 10) +#define R_P1_AGC_CTL 0x4A9C +#define B_P1_AGC_EN BIT(31) +#define R_PATH1_TIA_INIT_V1 0x4AA8 +#define B_PATH1_TIA_INIT_IDX_MSK_V1 BIT(9) +#define R_P0_AGC_RSVD 0x4ACC +#define R_PATH0_RXBB_V1 0x4AD4 +#define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0) +#define R_P1_AGC_RSVD 0x4AD8 +#define R_PATH1_RXBB_V1 0x4AE0 +#define B_PATH1_RXBB_MSK_V1 GENMASK(31, 0) +#define R_PATH0_BT_BACKOFF_V1 0x4AE4 +#define B_PATH0_BT_BACKOFF_V1 GENMASK(23, 0) +#define R_PATH1_BT_BACKOFF_V1 0x4AEC +#define B_PATH1_BT_BACKOFF_V1 GENMASK(23, 0) +#define R_DCFO_COMP_S0_V2 0x4B20 +#define B_DCFO_COMP_S0_MSK_V2 GENMASK(13, 0) +#define R_PATH0_TX_CFR 0x4B30 +#define B_PATH0_TX_CFR_LGC1 GENMASK(19, 10) +#define B_PATH0_TX_CFR_LGC0 GENMASK(9, 0) +#define R_PATH0_TX_POLAR_CLIPPING 0x4B3C +#define B_PATH0_TX_POLAR_CLIPPING_LGC1 GENMASK(19, 16) +#define B_PATH0_TX_POLAR_CLIPPING_LGC0 GENMASK(15, 12) +#define R_PATH0_FRC_FIR_TYPE_V1 0x4C00 +#define B_PATH0_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0) +#define R_PATH0_NOTCH 0x4C14 +#define B_PATH0_NOTCH_EN BIT(12) +#define B_PATH0_NOTCH_VAL GENMASK(11, 0) +#define R_PATH0_NOTCH2 0x4C20 +#define B_PATH0_NOTCH2_EN BIT(12) +#define B_PATH0_NOTCH2_VAL GENMASK(11, 0) +#define R_PATH0_5MDET 0x4C4C +#define R_PATH0_5MDET_V1 0x46F8 +#define B_PATH0_5MDET_EN BIT(12) +#define B_PATH0_5MDET_SB2 BIT(8) +#define B_PATH0_5MDET_SB0 BIT(6) +#define B_PATH0_5MDET_TH GENMASK(5, 0) +#define R_PATH1_FRC_FIR_TYPE_V1 0x4CC4 +#define B_PATH1_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0) +#define R_PATH1_NOTCH 0x4CD8 +#define B_PATH1_NOTCH_EN BIT(12) +#define B_PATH1_NOTCH_VAL GENMASK(11, 0) +#define R_PATH1_NOTCH2 0x4CE4 +#define B_PATH1_NOTCH2_EN BIT(12) +#define B_PATH1_NOTCH2_VAL GENMASK(11, 0) +#define R_PATH1_5MDET 0x4D10 +#define R_PATH1_5MDET_V1 0x47B8 +#define B_PATH1_5MDET_EN BIT(12) +#define B_PATH1_5MDET_SB2 BIT(8) +#define B_PATH1_5MDET_SB0 BIT(6) +#define B_PATH1_5MDET_TH GENMASK(5, 0) +#define R_S0S1_CSI_WGT 0x4D34 +#define B_S0S1_CSI_WGT_EN BIT(0) +#define B_S0S1_CSI_WGT_TONE_IDX GENMASK(31, 20) +#define R_CHINFO_ELM_SRC 0x4D84 +#define B_CHINFO_ELM_BITMAP GENMASK(22, 0) +#define B_CHINFO_SRC GENMASK(31, 30) +#define R_CHINFO_TYPE_SCAL 0x4D88 +#define B_CHINFO_TYPE GENMASK(2, 1) +#define B_CHINFO_SCAL BIT(8) +#define R_RPL_BIAS_COMP 0x4DF0 +#define B_RPL_BIAS_COMP_MASK GENMASK(7, 0) +#define R_RPL_PATHAB 0x4E0C +#define B_RPL_PATHB_MASK GENMASK(23, 16) +#define B_RPL_PATHA_MASK GENMASK(15, 8) +#define R_RSSI_M_PATHAB 0x4E2C +#define B_RSSI_M_PATHB_MASK GENMASK(15, 8) +#define B_RSSI_M_PATHA_MASK GENMASK(7, 0) +#define R_FC0_V1 0x4E30 +#define B_FC0_MSK_V1 GENMASK(12, 0) +#define R_RX_BW40_2XFFT_EN_V1 0x4E30 +#define B_RX_BW40_2XFFT_EN_MSK_V1 BIT(26) +#define R_DCFO_COMP_S0_V1 0x4A40 +#define B_DCFO_COMP_S0_V1_MSK GENMASK(13, 0) +#define R_BMODE_PDTH_V1 0x4B64 +#define R_BMODE_PDTH_V2 0x6708 +#define R_BMODE_PDTH_BE4 0x26040 +#define B_BMODE_PDTH_LOWER_BOUND_MSK_V1 GENMASK(31, 24) +#define R_BMODE_PDTH_EN_V1 0x4B74 +#define R_BMODE_PDTH_EN_V2 0x6718 +#define R_BMODE_PDTH_EN_BE4 0x26050 +#define B_BMODE_PDTH_LIMIT_EN_MSK_V1 BIT(30) +#define R_BSS_CLR_VLD_V2 0x4EBC +#define B_BSS_CLR_VLD0_V2 BIT(2) +#define R_CFO_COMP_SEG1_L 0x5384 +#define R_CFO_COMP_SEG1_H 0x5388 +#define R_CFO_COMP_SEG1_CTRL 0x538C +#define B_CFO_COMP_VALID_BIT BIT(29) +#define B_CFO_COMP_WEIGHT_MSK GENMASK(27, 24) +#define B_CFO_COMP_VAL_MSK GENMASK(11, 0) +#define R_TSSI_PA_K1 0x5600 +#define R_TSSI_PA_K2 0x5604 +#define R_P0_TSSI_ALIM1 0x5630 +#define B_P0_TSSI_ALIM1 GENMASK(29, 0) +#define B_P0_TSSI_ALIM11 GENMASK(29, 20) +#define B_P0_TSSI_ALIM12 GENMASK(19, 10) +#define B_P0_TSSI_ALIM13 GENMASK(9, 0) +#define R_P0_TSSI_ALIM3 0x5634 +#define B_P0_TSSI_ALIM31 GENMASK(9, 0) +#define R_TSSI_PA_K5 0x5638 +#define R_P0_TSSI_ALIM2 0x563c +#define B_P0_TSSI_ALIM2 GENMASK(29, 0) +#define R_P0_TSSI_ALIM4 0x5640 +#define R_TSSI_PA_K8 0x5644 +#define R_P0_TSSI_ADC_CLK 0x566c +#define B_P0_TSSI_ADC_CLK GENMASK(17, 16) +#define R_UPD_CLK 0x5670 +#define B_DAC_VAL BIT(31) +#define B_ACK_VAL GENMASK(30, 29) +#define B_DPD_DIS BIT(14) +#define B_DPD_GDIS BIT(13) +#define B_IQK_RFC_ON BIT(1) +#define R_TXPWRB 0x56CC +#define R_P1_TXPWRB 0x76CC +#define B_TXPWRB_ON BIT(28) +#define B_TXPWRB_VAL GENMASK(27, 19) +#define B_TXPWRB_MAX GENMASK(8, 0) +#define R_DPD_OFT_EN 0x5800 +#define B_DPD_OFT_EN BIT(28) +#define B_DPD_TSSI_CW GENMASK(26, 18) +#define B_DPD_PWR_CW GENMASK(17, 9) +#define B_DPD_REF GENMASK(8, 0) +#define R_P0_TSSIC 0x5814 +#define B_P0_TSSIC_BYPASS BIT(11) +#define R_DPD_OFT_ADDR 0x5804 +#define B_DPD_OFT_ADDR GENMASK(31, 27) +#define R_TXPWRB_H 0x580c +#define B_TXPWRB_RDY BIT(15) +#define R_P0_TMETER 0x5810 +#define B_P0_TMETER GENMASK(15, 10) +#define B_P0_TMETER_DIS BIT(16) +#define B_P0_TMETER_TRK BIT(24) +#define R_P0_ADCFF_EN 0x58C8 +#define B_P0_ADCFF_EN BIT(24) +#define R_P1_TSSIC 0x7814 +#define B_P1_TSSIC_BYPASS BIT(11) +#define R_P0_TSSI_TRK 0x5818 +#define B_P0_TSSI_TRK_EN BIT(30) +#define B_P0_TSSI_RFC GENMASK(28, 27) +#define B_P0_TSSI_OFT_EN BIT(28) +#define B_P0_TSSI_OFT GENMASK(7, 0) +#define R_P0_TSSI_SLOPE_CAL 0x581c +#define B_P0_TSSI_SLOPE_CAL_EN BIT(20) +#define R_P0_TSSI_AVG 0x5820 +#define B_P0_TSSI_EN BIT(31) +#define B_P0_TSSI_AVG GENMASK(15, 12) +#define R_P0_RFCTM 0x5864 +#define B_P0_CLKG_FORCE GENMASK(31, 30) +#define B_P0_RFCTM_EN BIT(29) +#define B_P0_GOT_TXRX GENMASK(28, 27) +#define B_P0_RFCTM_VAL GENMASK(25, 20) +#define R_P0_RFCTM_RDY BIT(26) +#define R_P0_TRSW 0x5868 +#define B_P0_BT_FORCE_ANTIDX_EN BIT(12) +#define B_P0_TRSW_X BIT(2) +#define B_P0_TRSW_A BIT(1) +#define B_P0_TX_ANT_SEL BIT(1) +#define B_P0_TRSW_B BIT(0) +#define B_P0_ANT_TRAIN_EN BIT(0) +#define B_P0_TRSW_SO_A2 GENMASK(7, 5) +#define R_P0_ANTSEL 0x586C +#define B_P0_ANTSEL_SW_5G BIT(25) +#define B_P0_ANTSEL_SW_2G BIT(23) +#define B_P0_ANTSEL_BTG_TRX BIT(21) +#define B_P0_ANTSEL_CGCS_CTRL BIT(17) +#define B_P0_ANTSEL_HW_CTRL BIT(16) +#define B_P0_ANTSEL_TX_ORI GENMASK(15, 12) +#define B_P0_ANTSEL_RX_ALT GENMASK(11, 8) +#define B_P0_ANTSEL_RX_ORI GENMASK(7, 4) +#define R_RFSW_CTRL_ANT0_BASE 0x5870 +#define B_RFSW_CTRL_ANT_MAPPING GENMASK(15, 0) +#define R_RFE_SEL0_BASE 0x5880 +#define B_RFE_SEL0_SRC_MASK GENMASK(3, 0) +#define R_RFE_SEL32_BASE 0x5884 +#define RFE_SEL0_SRC_ANTSEL_0 8 +#define R_RFE_INV0 0x5890 +#define R_P0_RFM 0x5894 +#define B_P0_RFM_DIS_WL BIT(7) +#define B_P0_RFM_TX_OPT BIT(6) +#define B_P0_RFM_BT_EN BIT(5) +#define B_P0_RFM_OUT GENMASK(4, 0) +#define R_P0_PATH_RST 0x58AC +#define B_P0_PATH_RST BIT(27) +#define R_P0_TXDPD 0x58D4 +#define B_P0_TXDPD GENMASK(31, 28) +#define R_P0_TXPW_RSTB 0x58DC +#define B_P0_TXPW_RSTB_MANON BIT(30) +#define B_P0_TXPW_RSTB_TSSI BIT(31) +#define R_P0_TSSI_MV_AVG 0x58E4 +#define B_P0_TXPW_RSTB GENMASK(28, 27) +#define B_P0_TSSI_MV_MIX GENMASK(19, 11) +#define B_P0_TSSI_MV_AVG GENMASK(13, 11) +#define B_P0_TSSI_MV_CLR BIT(14) +#define R_TXGAIN_SCALE 0x58F0 +#define B_TXGAIN_SCALE_EN BIT(19) +#define B_TXGAIN_SCALE_OFT GENMASK(31, 24) +#define R_P0_DAC_COMP_POST_DPD_EN 0x58F8 +#define B_P0_DAC_COMP_POST_DPD_EN BIT(31) +#define R_P0_TSSI_BASE 0x5C00 +#define R_S0_DACKI 0x5E00 +#define B_S0_DACKI_AR GENMASK(31, 28) +#define B_S0_DACKI_EN BIT(3) +#define R_S0_DACKI2 0x5E30 +#define B_S0_DACKI2_K GENMASK(21, 12) +#define R_S0_DACKI7 0x5E44 +#define B_S0_DACKI7_K GENMASK(15, 8) +#define R_S0_DACKI8 0x5E48 +#define B_S0_DACKI8_K GENMASK(15, 8) +#define R_S0_DACKQ 0x5E50 +#define B_S0_DACKQ_AR GENMASK(31, 28) +#define B_S0_DACKQ_EN BIT(3) +#define R_S0_DACKQ2 0x5E80 +#define B_S0_DACKQ2_K GENMASK(21, 12) +#define R_S0_DACKQ7 0x5E94 +#define B_S0_DACKQ7_K GENMASK(15, 8) +#define R_S0_DACKQ8 0x5E98 +#define B_S0_DACKQ8_K GENMASK(15, 8) +#define R_DCFO_WEIGHT_BE 0x6244 +#define R_DCFO_WEIGHT_BE_V1 0x24808 +#define B_DCFO_WEIGHT_MSK_BE GENMASK(31, 28) +#define R_DAC_CLK 0x625C +#define B_DAC_CLK GENMASK(31, 30) +#define R_DCFO_OPT_BE 0x6260 +#define R_DCFO_OPT_BE_V1 0x24824 +#define B_DCFO_OPT_EN_BE BIT(17) +#define R_TXFCTR 0x627C +#define B_TXFCTR_THD GENMASK(19, 10) +#define R_TXSCALE 0x6284 +#define B_TXFCTR_EN BIT(19) +#define R_PCOEFF01 0x6684 +#define B_PCOEFF01 GENMASK(23, 0) +#define R_PCOEFF23 0x6688 +#define B_PCOEFF23 GENMASK(23, 0) +#define R_PCOEFF45 0x668c +#define B_PCOEFF45 GENMASK(23, 0) +#define R_PCOEFF67 0x6690 +#define B_PCOEFF67 GENMASK(23, 0) +#define R_PCOEFF89 0x6694 +#define B_PCOEFF89 GENMASK(23, 0) +#define R_PCOEFFAB 0x6698 +#define B_PCOEFFAB GENMASK(23, 0) +#define R_PCOEFFCD 0x669c +#define B_PCOEFFCD GENMASK(23, 0) +#define R_PCOEFFEF 0x66a0 +#define B_PCOEFFEF GENMASK(23, 0) +#define R_MGAIN_BIAS 0x672c +#define B_MGAIN_BIAS_BW20 GENMASK(3, 0) +#define B_MGAIN_BIAS_BW40 GENMASK(7, 4) +#define R_CCK_RPL_OFST 0x6750 +#define B_CCK_RPL_OFST GENMASK(7, 0) +#define R_BK_FC0INV 0x6758 +#define B_BK_FC0INV GENMASK(18, 0) +#define R_CCK_FC0INV 0x675c +#define B_CCK_FC0INV GENMASK(18, 0) +#define R_SEG0R_EDCCA_LVL_BE 0x69EC +#define R_SEG0R_EDCCA_LVL_BE4 0x2623C +#define R_SEG0R_PPDU_LVL_BE 0x69F0 +#define R_SEG0R_PPDU_LVL_BE4 0x26240 +#define R_SEGSND 0x6A14 +#define B_SEGSND_EN BIT(31) +#define R_DBCC 0x6B48 +#define B_DBCC_EN BIT(0) +#define R_FC0 0x6B4C +#define B_BW40_2XFFT BIT(31) +#define B_FC0 GENMASK(12, 0) +#define R_FC0INV_SBW 0x6B50 +#define B_SMALLBW GENMASK(31, 30) +#define B_RX_BT_SG0 GENMASK(25, 22) +#define B_RX_1RCCA GENMASK(17, 14) +#define B_FC0_INV GENMASK(6, 0) +#define R_ANT_CHBW 0x6B54 +#define B_ANT_BT_SHARE BIT(16) +#define B_CHBW_BW GENMASK(14, 12) +#define B_CHBW_PRICH GENMASK(11, 8) +#define B_ANT_RX_SG0 GENMASK(3, 0) +#define R_SLOPE 0x6B6C +#define B_EHT_RATE_TH GENMASK(31, 28) +#define B_SLOPE_B GENMASK(27, 14) +#define B_SLOPE_A GENMASK(13, 0) +#define R_SC_CORNER 0x6B70 +#define B_SC_CORNER GENMASK(10, 0) +#define R_MAG_A 0x6BF4 +#define B_MGA_AEND GENMASK(31, 24) +#define R_MAG_AB 0x6BF8 +#define B_BY_SLOPE GENMASK(31, 24) +#define B_MAG_AB GENMASK(23, 0) +#define R_BEDGE 0x6BFC +#define B_EHT_MCS14 BIT(31) +#define B_HE_RATE_TH GENMASK(30, 27) +#define R_BEDGE2 0x6C00 +#define B_EHT_MCS15 BIT(31) +#define B_HT_VHT_TH GENMASK(11, 0) +#define R_BEDGE3 0x6C04 +#define B_TB_EN BIT(23) +#define B_HEMU_EN BIT(21) +#define B_HEERSU_EN BIT(19) +#define B_EHTTB_EN BIT(15) +#define B_BEDGE_CFG GENMASK(1, 0) +#define R_SU_PUNC 0x6C08 +#define B_SU_PUNC_EN BIT(1) +#define R_BEDGE5 0x6C10 +#define B_HWGEN_EN BIT(25) +#define B_PWROFST_COMP BIT(20) +#define R_RPL_BIAS_COMP1 0x6DF0 +#define B_RPL_BIAS_COMP1_MASK GENMASK(7, 0) +#define R_DBCC_FA 0x703C +#define B_DBCC_FA BIT(12) +#define R_P1_TSSI_ALIM1 0x7630 +#define B_P1_TSSI_ALIM1 GENMASK(29, 0) +#define B_P1_TSSI_ALIM11 GENMASK(29, 20) +#define B_P1_TSSI_ALIM12 GENMASK(19, 10) +#define B_P1_TSSI_ALIM13 GENMASK(9, 0) +#define R_P1_TSSI_ALIM3 0x7634 +#define B_P1_TSSI_ALIM31 GENMASK(9, 0) +#define R_P1_TSSI_ALIM2 0x763c +#define B_P1_TSSI_ALIM2 GENMASK(29, 0) +#define R_P1_TSSI_ADC_CLK 0x766c +#define B_P1_TSSI_ADC_CLK GENMASK(17, 16) +#define R_P1_TXAGC_TH 0x7800 +#define B_P1_TXAGC_MAXMIN GENMASK(15, 0) +#define R_P1_TXPW_FORCE 0x780C +#define B_P1_TXPW_RDY BIT(15) +#define R_P1_TSSIC 0x7814 +#define B_P1_TSSIC_BYPASS BIT(11) +#define R_P1_TMETER 0x7810 +#define B_P1_TMETER GENMASK(15, 10) +#define B_P1_TMETER_DIS BIT(16) +#define B_P1_TMETER_TRK BIT(24) +#define R_P1_TSSI_TRK 0x7818 +#define B_P1_TSSI_TRK_EN BIT(30) +#define B_P1_TSSI_RFC GENMASK(28, 27) +#define B_P1_TSSI_OFT_EN BIT(28) +#define B_P1_TSSI_OFT GENMASK(7, 0) +#define R_P1_TSSI_AVG 0x7820 +#define B_P1_TSSI_EN BIT(31) +#define B_P1_TSSI_AVG GENMASK(15, 12) +#define R_P1_RFCTM 0x7864 +#define B_P1_CLKG_FORCE GENMASK(31, 30) +#define B_P1_GOT_TXRX GENMASK(28, 27) +#define R_P1_RFCTM_RDY BIT(26) +#define B_P1_RFCTM_VAL GENMASK(25, 20) +#define B_P1_RFCTM_DEL GENMASK(19, 11) +#define R_P1_PATH_RST 0x78AC +#define B_P1_PATH_RST BIT(27) +#define R_P1_ADCFF_EN 0x78C8 +#define B_P1_ADCFF_EN BIT(24) +#define R_P1_TXPW_RSTB 0x78DC +#define B_P1_TXPW_RSTB_MANON BIT(30) +#define B_P1_TXPW_RSTB_TSSI BIT(31) +#define R_P1_TSSI_MV_AVG 0x78E4 +#define B_P1_TXPW_RSTB GENMASK(28, 27) +#define B_P1_TSSI_MV_MIX GENMASK(19, 11) +#define B_P1_TSSI_MV_AVG GENMASK(13, 11) +#define B_P1_TSSI_MV_CLR BIT(14) +#define R_P1_DAC_COMP_POST_DPD_EN 0x78F8 +#define B_P1_DAC_COMP_POST_DPD_EN BIT(31) +#define R_TSSI_THOF 0x7C00 +#define R_S1_DACKI 0x7E00 +#define B_S1_DACKI_AR GENMASK(31, 28) +#define B_S1_DACKI_EN BIT(3) +#define R_S1_DACKI2 0x7E30 +#define B_S1_DACKI2_K GENMASK(21, 12) +#define R_S1_DACKI7 0x7E44 +#define B_S1_DACKI_K GENMASK(15, 8) +#define R_S1_DACKI8 0x7E48 +#define B_S1_DACKI8_K GENMASK(15, 8) +#define R_S1_DACKQ 0x7E50 +#define B_S1_DACKQ_AR GENMASK(31, 28) +#define B_S1_DACKQ_EN BIT(3) +#define R_S1_DACKQ2 0x7E80 +#define B_S1_DACKQ2_K GENMASK(21, 12) +#define R_S1_DACKQ7 0x7E94 +#define B_S1_DACKQ7_K GENMASK(15, 8) +#define R_S1_DACKQ8 0x7E98 +#define B_S1_DACKQ8_K GENMASK(15, 8) +#define R_NCTL_CFG 0x8000 +#define R_NCTL_CFG_BE4 0x38000 +#define B_NCTL_CFG_BE4_SPAGE GENMASK(25, 24) +#define B_NCTL_CHK_EN BIT(3) +#define B_NCTL_CFG_SPAGE GENMASK(2, 1) +#define R_NCTL_RPT 0x8008 +#define B_NCTL_RPT_FLG BIT(26) +#define R_NCTL_N1 0x8010 +#define B_NCTL_N1_CIP GENMASK(7, 0) +#define R_NCTL_N2 0x8014 +#define R_IQK_COM 0x8018 +#define R_IQK_DIF 0x801C +#define B_IQK_DIF_TRX GENMASK(1, 0) +#define R_IQK_DIF1 0x8020 +#define B_IQK_DIF1_TXPI GENMASK(19, 0) +#define R_IQK_DIF2 0x8024 +#define B_IQK_DIF2_RXPI GENMASK(19, 0) +#define R_IQK_DIF4 0x802C +#define B_IQK_DIF4_RXT GENMASK(27, 16) +#define B_IQK_DIF4_TXT GENMASK(11, 0) +#define IQK_DF4_TXT_8_25MHZ 0x021 +#define R_IQK_CFG 0x8034 +#define B_IQK_CFG_SET GENMASK(5, 4) +#define R_IQK_RXA 0x8044 +#define B_IQK_RXAGC GENMASK(15, 13) +#define R_TPG_SEL 0x8068 +#define R_TPG_MOD 0x806C +#define B_TPG_MOD_F GENMASK(2, 1) +#define R_MDPK_SYNC 0x8070 +#define B_MDPK_SYNC_SEL BIT(31) +#define B_MDPK_SYNC_MAN GENMASK(31, 28) +#define B_MDPK_SYNC_DMAN GENMASK(30, 28) +#define R_MDPK_RX_DCK 0x8074 +#define B_MDPK_RX_DCK_EN BIT(31) +#define R_KIP_MOD 0x8078 +#define B_KIP_MOD GENMASK(19, 0) +#define R_NCTL_RW 0x8080 +#define R_NCTL_RW_BE4 0x38080 +#define B_NCTL_CHECK BIT(2) +#define R_KIP_SYSCFG 0x8088 +#define R_KIP_CLK 0x808C +#define R_DPK_IDL 0x809C +#define B_DPK_IDL_SEL GENMASK(10, 9) +#define B_DPK_IDL BIT(8) +#define R_LDL_NORM 0x80A0 +#define B_LDL_NORM_MA BIT(16) +#define B_LDL_NORM_PN GENMASK(12, 8) +#define B_LDL_NORM_OP GENMASK(1, 0) +#define R_DPK_CTL 0x80B0 +#define B_DPK_CTL_EN BIT(28) +#define R_DPK_CFG 0x80B8 +#define B_DPK_CFG_IDX GENMASK(14, 12) +#define R_DPK_CFG2 0x80BC +#define B_DPK_CFG2_ST BIT(14) +#define R_DPK_CFG3 0x80C0 +#define R_KPATH_CFG 0x80D0 +#define B_KPATH_CFG_ED GENMASK(21, 20) +#define R_KIP_RPT1 0x80D4 +#define B_KIP_RPT1_SEL GENMASK(21, 16) +#define B_KIP_RPT1_SEL_V1 GENMASK(19, 16) +#define R_SRAM_IQRX 0x80D8 +#define R_IDL_MPA 0x80DC +#define B_IDL_DN BIT(31) +#define B_IDL_MD530 BIT(1) +#define B_IDL_MD500 BIT(0) +#define R_GAPK 0x80E0 +#define B_GAPK_ADR BIT(0) +#define R_SRAM_IQRX2 0x80E8 +#define R_DPK_MPA 0x80EC +#define B_DPK_MPA_T0 BIT(10) +#define B_DPK_MPA_T1 BIT(9) +#define B_DPK_MPA_T2 BIT(8) +#define R_DPK_WR 0x80F4 +#define B_DPK_WR_ST BIT(29) +#define R_DPK_TRK 0x80f0 +#define B_DPK_TRK_DIS BIT(31) +#define R_RPT_COM 0x80FC +#define B_PRT_COM_SYNERR BIT(30) +#define B_PRT_COM_DCI GENMASK(27, 16) +#define B_PRT_COM_CORV GENMASK(15, 8) +#define B_RPT_COM_RDY GENMASK(15, 0) +#define B_PRT_COM_DCQ GENMASK(11, 0) +#define B_PRT_COM_RXOV BIT(8) +#define B_PRT_COM_GL GENMASK(7, 4) +#define B_PRT_COM_CORI GENMASK(7, 0) +#define B_PRT_COM_RXBB GENMASK(5, 0) +#define B_PRT_COM_RXBB_V1 GENMASK(4, 0) +#define B_PRT_COM_DONE BIT(0) +#define R_COEF_SEL 0x8104 +#define R_COEF_SEL_C1 0x8204 +#define B_COEF_SEL_IQC BIT(0) +#define B_COEF_SEL_IQC_V1 GENMASK(1, 0) +#define B_COEF_SEL_MDPD BIT(8) +#define B_COEF_SEL_MDPD_V1 GENMASK(9, 8) +#define B_COEF_SEL_EN BIT(31) +#define R_CFIR_COEF 0x810c +#define R_CFIR_SYS 0x8120 +#define R_IQK_RES 0x8124 +#define B_IQK_RES_K BIT(28) +#define B_IQK_RES_TXCFIR GENMASK(11, 8) +#define B_IQK_RES_RXCFIR GENMASK(3, 0) +#define R_TXIQC 0x8138 +#define R_RXIQC 0x813c +#define B_RXIQC_BYPASS BIT(0) +#define B_RXIQC_BYPASS2 BIT(2) +#define B_RXIQC_NEWP GENMASK(19, 8) +#define B_RXIQC_NEWX GENMASK(31, 20) +#define R_KIP 0x8140 +#define B_KIP_DBCC BIT(0) +#define B_KIP_RFGAIN BIT(8) +#define R_RFGAIN 0x8144 +#define B_RFGAIN_PAD GENMASK(4, 0) +#define B_RFGAIN_TXBB GENMASK(12, 8) +#define R_RFGAIN_BND 0x8148 +#define B_RFGAIN_BND GENMASK(4, 0) +#define R_CFIR_MAP 0x8150 +#define R_CFIR_LUT 0x8154 +#define R_CFIR_LUT_C1 0x8254 +#define B_CFIR_LUT_SEL BIT(8) +#define B_CFIR_LUT_SET BIT(4) +#define B_CFIR_LUT_G5 BIT(5) +#define B_CFIR_LUT_G3 BIT(3) +#define B_CFIR_LUT_G2 BIT(2) +#define B_CFIR_LUT_GP_V1 GENMASK(2, 0) +#define B_CFIR_LUT_GP GENMASK(1, 0) +#define R_DPK_GN 0x819C +#define B_DPK_GN_EN GENMASK(17, 16) +#define B_DPK_GN_AG GENMASK(9, 0) +#define R_DPD_V1 0x81a0 +#define B_DPD_LBK BIT(7) +#define R_DPD_CH0 0x81AC +#define R_DPD_BND 0x81B4 +#define B_DPD_BND_1 GENMASK(24, 16) +#define B_DPD_BND_0 GENMASK(8, 0) +#define R_DPD_CH0A 0x81BC +#define B_DPD_MEN GENMASK(31, 28) +#define B_DPD_ORDER GENMASK(26, 24) +#define B_DPD_ORDER_V1 GENMASK(26, 25) +#define B_DPD_CFG GENMASK(22, 0) +#define B_DPD_SEL GENMASK(13, 8) +#define R_TXAGC_RFK 0x81C4 +#define B_TXAGC_RFK_CH0 GENMASK(5, 0) +#define R_DPD_COM 0x81C8 +#define B_DPD_COM_OF BIT(15) +#define R_KIP_IQP 0x81CC +#define B_KIP_IQP_SW GENMASK(13, 12) +#define B_KIP_IQP_IQSW GENMASK(5, 0) +#define R_KIP_RPT 0x81D4 +#define B_KIP_RPT_SEL GENMASK(21, 16) +#define R_W_COEF 0x81D8 +#define R_LOAD_COEF 0x81DC +#define B_LOAD_COEF_MDPD BIT(16) +#define B_LOAD_COEF_CFIR GENMASK(1, 0) +#define B_LOAD_COEF_DI BIT(1) +#define B_LOAD_COEF_AUTO BIT(0) +#define R_DPK_GL 0x81F0 +#define B_DPK_GL_A0 GENMASK(31, 28) +#define B_DPK_GL_A1 GENMASK(17, 0) +#define R_RPT_PER 0x81FC +#define B_RPT_PER_KSET GENMASK(31, 29) +#define B_RPT_PER_TSSI GENMASK(28, 16) +#define B_RPT_PER_OF GENMASK(15, 8) +#define B_RPT_PER_TH GENMASK(5, 0) +#define R_IQRSN 0x8220 +#define B_IQRSN_K1 BIT(28) +#define B_IQRSN_K2 BIT(16) +#define R_DPD_CH0B 0x82BC +#define R_RXCFIR_P0C0 0x8D40 +#define R_RXCFIR_P0C1 0x8D84 +#define R_RXCFIR_P0C2 0x8DC8 +#define R_RXCFIR_P0C3 0x8E0C +#define R_TXCFIR_P0C0 0x8F50 +#define R_TXCFIR_P0C1 0x8F84 +#define R_TXCFIR_P0C2 0x8FB8 +#define R_TXCFIR_P0C3 0x8FEC +#define R_RXCFIR_P1C0 0x9140 +#define R_RXCFIR_P1C1 0x9184 +#define R_RXCFIR_P1C2 0x91C8 +#define R_RXCFIR_P1C3 0x920C +#define R_TXCFIR_P1C0 0x9350 +#define R_TXCFIR_P1C1 0x9384 +#define R_TXCFIR_P1C2 0x93B8 +#define R_TXCFIR_P1C3 0x93EC +#define R_IQKINF 0x9FE0 +#define B_IQKINF_VER GENMASK(31, 24) +#define B_IQKINF_FAIL_RXGRP GENMASK(23, 16) +#define B_IQKINF_FAIL_TXGRP GENMASK(15, 8) +#define B_IQKINF_FAIL GENMASK(3, 0) +#define B_IQKINF_F_RX BIT(3) +#define B_IQKINF_FTX BIT(2) +#define B_IQKINF_FFIN BIT(1) +#define B_IQKINF_FCOR BIT(0) +#define R_IQKCH 0x9FE4 +#define B_IQKCH_CH GENMASK(15, 8) +#define B_IQKCH_BW GENMASK(7, 4) +#define B_IQKCH_BAND GENMASK(3, 0) +#define R_IQKINF2 0x9FE8 +#define B_IQKINF2_FCNT GENMASK(23, 16) +#define B_IQKINF2_KCNT GENMASK(15, 8) +#define B_IQKINF2_NCTLV GENMASK(7, 0) +#define R_TXAGC_REF_DBM_RF1_P0 0xBC04 +#define B_TXAGC_OFDM_REF_DBM_RF1_P0 GENMASK(10, 2) +#define B_TXAGC_CCK_REF_DBM_RF1_P0 GENMASK(19, 11) +#define R_TSSI_K_RF1_P0 0xBC28 +#define B_TSSI_K_OFDM_RF1_P0 GENMASK(9, 0) +#define R_TXAGC_REF_DBM_RF1_P1 0xBD04 +#define B_TXAGC_OFDM_REF_DBM_RF1_P1 GENMASK(10, 2) +#define B_TXAGC_CCK_REF_DBM_RF1_P1 GENMASK(19, 11) +#define R_TSSI_K_RF1_P1 0xBD28 +#define B_TSSI_K_OFDM_RF1_P1 GENMASK(9, 0) +#define R_RFK_ST 0xBFF8 +#define R_DCOF0 0xC000 +#define B_DCOF0_RST BIT(17) +#define B_DCOF0_V GENMASK(4, 1) +#define R_DCOF1 0xC004 +#define B_DCOF1_VAL GENMASK(31, 20) +#define B_DCOF1_RST BIT(17) +#define B_DCOF1_S BIT(0) +#define R_DCOF8 0xC020 +#define B_DCOF8_V GENMASK(4, 1) +#define R_DCOF9 0xC024 +#define B_DCOF9_VAL GENMASK(31, 20) +#define B_DCOF9_RST BIT(17) +#define R_DACK_S0P0 0xC040 +#define B_DACK_S0P0_OK BIT(31) +#define R_DACK_BIAS00 0xc048 +#define B_DACK_BIAS00 GENMASK(11, 2) +#define R_DACK_S0P2 0xC05C +#define B_DACK_S0M0 GENMASK(31, 24) +#define B_DACK_S0P2_OK BIT(2) +#define R_DACK_DADCK00 0xC060 +#define B_DACK_DADCK00 GENMASK(31, 24) +#define R_DACK_S0P1 0xC064 +#define B_DACK_S0P1_OK BIT(31) +#define R_DACK_BIAS01 0xC06C +#define B_DACK_BIAS01 GENMASK(11, 2) +#define R_DACK_S0P3 0xC080 +#define B_DACK_S0M1 GENMASK(31, 24) +#define B_DACK_S0P3_OK BIT(2) +#define R_DACK_DADCK01 0xC084 +#define B_DACK_DADCK01 GENMASK(31, 24) +#define R_DRCK_FH 0xC094 +#define B_DRCK_LAT BIT(9) +#define R_DRCK 0xC0C4 +#define B_DRCK_MUL GENMASK(21, 17) +#define B_DRCK_IDLE BIT(9) +#define B_DRCK_EN BIT(6) +#define B_DRCK_VAL GENMASK(4, 0) +#define R_DRCK_RES 0xC0C8 +#define B_DRCK_RES GENMASK(19, 15) +#define B_DRCK_POL BIT(3) +#define R_DRCK_V1 0xC0CC +#define B_DRCK_V1_SEL BIT(9) +#define B_DRCK_V1_KICK BIT(6) +#define B_DRCK_V1_CV GENMASK(4, 0) +#define R_DRCK_RS 0xC0D0 +#define B_DRCK_RS_LPS GENMASK(19, 15) +#define B_DRCK_RS_DONE BIT(3) +#define R_PATH0_SAMPL_DLY_T_V1 0xC0D4 +#define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) +#define R_P0_CFCH_BW0 0xC0D4 +#define B_P0_CFCH_BW0 GENMASK(27, 26) +#define B_P0_CFCH_EN GENMASK(14, 11) +#define B_P0_CFCH_CTL GENMASK(10, 7) +#define R_P0_CFCH_BW1 0xC0D8 +#define B_P0_CFCH_EX BIT(13) +#define B_P0_CFCH_BW1 GENMASK(8, 5) +#define R_WDADC 0xC0E4 +#define B_WDADC_SEL GENMASK(5, 4) +#define R_ADCMOD 0xC0E8 +#define B_ADCMOD_LP GENMASK(31, 16) +#define B_ADCMOD_AUTO_RST BIT(6) +#define R_DCIM 0xC0EC +#define B_DCIM_RC GENMASK(23, 16) +#define B_DCIM_FR GENMASK(14, 13) +#define R_ADDCK0D 0xC0F0 +#define B_ADDCK0D_VAL2 GENMASK(31, 26) +#define B_ADDCK0D_VAL GENMASK(25, 16) +#define B_ADDCK_DS BIT(16) +#define R_ADDCK0 0xC0F4 +#define B_ADDCK0_TRG BIT(11) +#define B_ADDCK0_IQ BIT(10) +#define B_ADDCK0 GENMASK(9, 8) +#define B_ADDCK0_MAN GENMASK(5, 4) +#define B_ADDCK0_EN BIT(4) +#define B_ADDCK0_VAL GENMASK(3, 0) +#define B_ADDCK0_RST BIT(2) +#define R_ADDCK0_RL 0xC0F8 +#define B_ADDCK0_RLS GENMASK(29, 28) +#define B_ADDCK0_RL1 GENMASK(27, 18) +#define B_ADDCK0_RL0 GENMASK(17, 8) +#define R_ADDCKR0 0xC0FC +#define B_ADDCKR0_A0 GENMASK(19, 10) +#define B_ADDCKR0_DC GENMASK(15, 4) +#define B_ADDCKR0_A1 GENMASK(9, 0) +#define R_DACK10 0xC100 +#define B_DACK10_RST BIT(17) +#define B_DACK10 GENMASK(4, 1) +#define R_DACK1_K 0xc104 +#define B_DACK1_VAL GENMASK(31, 20) +#define B_DACK1_RST BIT(17) +#define B_DACK1_EN BIT(0) +#define R_DACK11 0xC120 +#define B_DACK11 GENMASK(4, 1) +#define R_DACK2_K 0xC124 +#define B_DACK2_VAL GENMASK(31, 20) +#define B_DACK2_RST BIT(17) +#define B_DACK2_EN BIT(0) +#define R_DACK_S1P0 0xC140 +#define B_DACK_S1P0_OK BIT(31) +#define R_DACK_BIAS10 0xC148 +#define B_DACK_BIAS10 GENMASK(11, 2) +#define R_DACK10S 0xC15C +#define B_DACK10S GENMASK(31, 24) +#define R_DACK_S1P2 0xC15C +#define B_DACK_S1P2_OK BIT(2) +#define R_DACK_DADCK10 0xC160 +#define B_DACK_DADCK10 GENMASK(31, 24) +#define R_DACK_S1P1 0xC164 +#define B_DACK_S1P1_OK BIT(31) +#define R_DACK_BIAS11 0xC16C +#define B_DACK_BIAS11 GENMASK(11, 2) +#define R_DACK11S 0xC180 +#define B_DACK11S GENMASK(31, 24) +#define R_DACK_S1P3 0xC180 +#define B_DACK_S1P3_OK BIT(2) +#define R_DACK_DADCK11 0xC184 +#define B_DACK_DADCK11 GENMASK(31, 24) +#define R_PATH1_SAMPL_DLY_T_V1 0xC1D4 +#define B_PATH1_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) +#define R_PATH0_BW_SEL_V1 0xC0D8 +#define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) +#define R_PATH1_BW_SEL_V1 0xC1D8 +#define B_PATH1_BW_SEL_EX BIT(13) +#define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5) +#define R_ADDCK1D 0xC1F0 +#define B_ADDCK1D_VAL2 GENMASK(31, 26) +#define B_ADDCK1D_VAL GENMASK(25, 16) +#define R_ADDCK1 0xC1F4 +#define B_ADDCK1_TRG BIT(11) +#define B_ADDCK1 GENMASK(9, 8) +#define B_ADDCK1_MAN GENMASK(5, 4) +#define B_ADDCK1_EN BIT(4) +#define B_ADDCK1_RST BIT(2) +#define R_ADDCK1_RL 0xC1F8 +#define B_ADDCK1_RLS GENMASK(29, 28) +#define B_ADDCK1_RL1 GENMASK(27, 18) +#define B_ADDCK1_RL0 GENMASK(17, 8) +#define R_ADDCKR1 0xC1fC +#define B_ADDCKR1_A0 GENMASK(19, 10) +#define B_ADDCKR1_A1 GENMASK(9, 0) +#define R_DACKN0_CTL 0xC210 +#define B_DACKN0_EN BIT(0) +#define B_DACKN0_V GENMASK(21, 14) +#define R_DACKN1_CTL 0xC224 +#define B_DACKN1_V GENMASK(21, 14) +#define B_DACKN1_ON BIT(0) +#define R_DACKN2_CTL 0xC238 +#define B_DACKN2_ON BIT(0) +#define R_DACKN3_CTL 0xC24C +#define B_DACKN3_ON BIT(0) +#define R_GAIN_MAP0 0xE44C +#define B_GAIN_MAP0_EN BIT(0) +#define R_GAIN_MAP1 0xE54C +#define B_GAIN_MAP1_EN BIT(0) +#define R_GOTX_IQKDPK_C0 0xE464 +#define R_GOTX_IQKDPK_C0_BE4 0x2E464 +#define R_GOTX_IQKDPK_C1 0xE564 +#define R_GOTX_IQKDPK_C1_BE4 0x2E564 +#define B_GOTX_IQKDPK GENMASK(28, 27) +#define R_IQK_DPK_PRST 0xE4AC +#define R_IQK_DPK_PRST_BE4 0x2E4AC +#define R_IQK_DPK_PRST_C1 0xE5AC +#define R_IQK_DPK_PRST_C1_BE4 0x2E5AC +#define B_IQK_DPK_PRST BIT(27) +#define R_TXPWR_RSTA 0xE60C +#define B_TXPWR_RSTA BIT(16) +#define R_TSSI_PWR_P0 0xE610 +#define R_TSSI_PWR_P1 0xE710 +#define B_TSSI_CONT_EN BIT(3) +#define R_P0_TXPWRB_BE 0xE61C +#define R_P1_TXPWRB_BE 0xE71C +#define R_P0_TXPWRB_BE4 0x2251C +#define R_P1_TXPWRB_BE4 0x2261C +#define B_TXPWRB_MAX_BE GENMASK(20, 12) +#define R_TSSI_MAP_OFST_P0 0xE620 +#define R_TSSI_MAP_OFST_P1 0xE720 +#define B_TSSI_MAP_OFST_OFDM GENMASK(17, 9) +#define B_TSSI_MAP_OFST_CCK GENMASK(26, 18) +#define R_TXAGC_REF_DBM_P0 0xE628 +#define B_TXAGC_OFDM_REF_DBM_P0 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_P0 GENMASK(17, 9) +#define R_TSSI_K_P0 0xE6A0 +#define B_TSSI_K_OFDM_P0 GENMASK(29, 20) +#define R_TXPWR_RSTB 0xE70C +#define B_TXPWR_RSTB BIT(16) +#define R_TXAGC_REF_DBM_P1 0xE728 +#define B_TXAGC_OFDM_REF_DBM_P1 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_P1 GENMASK(17, 9) +#define R_TSSI_K_P1 0xE7A0 +#define B_TSSI_K_OFDM_P1 GENMASK(29, 20) + +#define R_BBWRAP_ELMSR_BE4 0x11974 +#define B_BBWRAP_ELMSR_EN_BE4 GENMASK(29, 28) +#define R_COMP_CIM3K_BE4 0x11998 +#define B_COMP_CIM3K_OW_BE4 BIT(1) +#define B_COMP_CIM3K_TH_BE4 BIT(2) +#define B_COMP_CIM3K_TH2_BE4 GENMASK(5, 3) +#define B_COMP_CIM3K_TXPWR_EN_BE4 BIT(6) +#define B_COMP_CIM3K_NONBE_BE4 BIT(7) +#define B_COMP_CIM3K_BANDEDGE_BE4 BIT(8) +#define R_DPD_CBW160_BE4 0x119B4 +#define B_DPD_CBW160_TH0_BE4 BIT(0) +#define B_DPD_CBW160_TH1_BE4 BIT(1) +#define B_DPD_CBW160_TH2_BE4 BIT(2) +#define B_DPD_CBW160_TH3_BE4 BIT(3) +#define B_DPD_CBW160_TH4_BE4 BIT(4) +#define B_DPD_CBW160_TH5_BE4 BIT(5) +#define B_DPD_CBW160_TH6_BE4 BIT(6) +#define B_DPD_CBW160_TH7_BE4 BIT(7) +#define B_DPD_CBW160_OW0_BE4 BIT(8) +#define B_DPD_CBW160_OW1_BE4 BIT(9) +#define B_DPD_CBW160_OW2_BE4 BIT(10) +#define B_DPD_CBW160_OW3_BE4 BIT(11) +#define B_DPD_CBW160_OW4_BE4 BIT(12) +#define B_DPD_CBW160_OW5_BE4 BIT(13) +#define B_DPD_CBW160_OW6_BE4 BIT(14) +#define B_DPD_CBW160_OW7_BE4 BIT(15) +#define R_OOB_CBW20_BE4 0x119B4 +#define B_OOB_CBW20_CCK0_BE4 BIT(16) +#define B_OOB_CBW20_CCK1_BE4 BIT(17) +#define B_OOB_CBW20_CCK2_BE4 BIT(18) +#define B_OOB_CBW20_CCK3_BE4 BIT(19) +#define B_OOB_CBW20_CCK4_BE4 BIT(20) +#define B_OOB_CBW20_CCK5_BE4 BIT(21) +#define B_OOB_CBW20_CCK6_BE4 BIT(22) +#define B_OOB_CBW20_CCK7_BE4 BIT(23) +#define B_OOB_CBW20_TH0_BE4 BIT(24) +#define B_OOB_CBW20_TH1_BE4 BIT(25) +#define B_OOB_CBW20_TH2_BE4 BIT(26) +#define B_OOB_CBW20_TH3_BE4 BIT(27) +#define B_OOB_CBW20_TH4_BE4 BIT(28) +#define B_OOB_CBW20_TH5_BE4 BIT(29) +#define B_OOB_CBW20_TH6_BE4 BIT(30) +#define B_OOB_CBW20_TH7_BE4 BIT(31) +#define R_OOB_CBW40_BE4 0x119B8 +#define B_OOB_CBW20_OW0_BE4 BIT(0) +#define B_OOB_CBW20_OW1_BE4 BIT(1) +#define B_OOB_CBW20_OW2_BE4 BIT(2) +#define B_OOB_CBW20_OW3_BE4 BIT(3) +#define B_OOB_CBW20_OW4_BE4 BIT(4) +#define B_OOB_CBW20_OW5_BE4 BIT(5) +#define B_OOB_CBW20_OW6_BE4 BIT(6) +#define B_OOB_CBW20_OW7_BE4 BIT(7) +#define B_OOB_CBW40_CCK0_BE4 BIT(8) +#define B_OOB_CBW40_CCK1_BE4 BIT(9) +#define B_OOB_CBW40_CCK2_BE4 BIT(10) +#define B_OOB_CBW40_CCK3_BE4 BIT(11) +#define B_OOB_CBW40_CCK4_BE4 BIT(12) +#define B_OOB_CBW40_CCK5_BE4 BIT(13) +#define B_OOB_CBW40_CCK6_BE4 BIT(14) +#define B_OOB_CBW40_CCK7_BE4 BIT(15) +#define B_OOB_CBW40_TH0_BE4 BIT(16) +#define B_OOB_CBW40_TH1_BE4 BIT(17) +#define B_OOB_CBW40_TH2_BE4 BIT(18) +#define B_OOB_CBW40_TH3_BE4 BIT(19) +#define B_OOB_CBW40_TH4_BE4 BIT(20) +#define B_OOB_CBW40_TH5_BE4 BIT(21) +#define B_OOB_CBW40_TH6_BE4 BIT(22) +#define B_OOB_CBW40_TH7_BE4 BIT(23) +#define B_OOB_CBW40_OW0_BE4 BIT(24) +#define B_OOB_CBW40_OW1_BE4 BIT(25) +#define B_OOB_CBW40_OW2_BE4 BIT(26) +#define B_OOB_CBW40_OW3_BE4 BIT(27) +#define B_OOB_CBW40_OW4_BE4 BIT(28) +#define B_OOB_CBW40_OW5_BE4 BIT(29) +#define B_OOB_CBW40_OW6_BE4 BIT(30) +#define B_OOB_CBW40_OW7_BE4 BIT(31) +#define R_OOB_CBW80_BE4 0x119BC +#define B_OOB_CBW80_TH0_BE4 BIT(0) +#define B_OOB_CBW80_TH1_BE4 BIT(1) +#define B_OOB_CBW80_TH2_BE4 BIT(2) +#define B_OOB_CBW80_TH3_BE4 BIT(3) +#define B_OOB_CBW80_TH4_BE4 BIT(4) +#define B_OOB_CBW80_TH5_BE4 BIT(5) +#define B_OOB_CBW80_TH6_BE4 BIT(6) +#define B_OOB_CBW80_TH7_BE4 BIT(7) +#define B_OOB_CBW80_OW0_BE4 BIT(8) +#define B_OOB_CBW80_OW1_BE4 BIT(9) +#define B_OOB_CBW80_OW2_BE4 BIT(10) +#define B_OOB_CBW80_OW3_BE4 BIT(11) +#define B_OOB_CBW80_OW4_BE4 BIT(12) +#define B_OOB_CBW80_OW5_BE4 BIT(13) +#define B_OOB_CBW80_OW6_BE4 BIT(14) +#define B_OOB_CBW80_OW7_BE4 BIT(15) +#define R_DPD_DBW160_TH0_BE4 0x119BC +#define B_DPD_DBW160_TH0_0_BE4 GENMASK(18, 16) +#define B_DPD_DBW160_TH0_1_BE4 GENMASK(21, 19) +#define B_DPD_DBW160_TH0_2_BE4 GENMASK(24, 22) +#define B_DPD_DBW160_TH0_3_BE4 GENMASK(27, 25) +#define B_DPD_DBW160_TH0_4_BE4 GENMASK(30, 28) +#define R_DPD_DBW160_TH1_BE4 0x119C0 +#define B_DPD_DBW160_TH1_5_BE4 GENMASK(2, 0) +#define B_DPD_DBW160_TH1_6_BE4 GENMASK(5, 3) +#define B_DPD_DBW160_TH1_7_BE4 GENMASK(8, 6) +#define R_DPD_CBW_TH0_BE4 0x119C0 +#define B_DPD_CBW20_TH0_0_BE4 GENMASK(11, 9) +#define B_DPD_CBW20_TH0_1_BE4 GENMASK(14, 12) +#define B_DPD_CBW20_TH0_2_BE4 GENMASK(17, 15) +#define B_DPD_CBW20_TH0_3_BE4 GENMASK(20, 18) +#define B_DPD_CBW20_TH0_4_BE4 GENMASK(23, 21) +#define B_DPD_CBW20_TH0_5_BE4 GENMASK(26, 24) +#define B_DPD_CBW20_TH0_6_BE4 GENMASK(29, 27) +#define R_DPD_CBW_TH1_BE4 0x119C4 +#define B_DPD_CBW20_TH1_7_BE4 GENMASK(2, 0) +#define B_DPD_CBW40_TH1_0_BE4 GENMASK(5, 3) +#define B_DPD_CBW40_TH1_1_BE4 GENMASK(8, 6) +#define B_DPD_CBW40_TH1_2_BE4 GENMASK(11, 9) +#define B_DPD_CBW40_TH1_3_BE4 GENMASK(14, 12) +#define B_DPD_CBW40_TH1_4_BE4 GENMASK(17, 15) +#define B_DPD_CBW40_TH1_5_BE4 GENMASK(20, 18) +#define B_DPD_CBW40_TH1_6_BE4 GENMASK(23, 21) +#define B_DPD_CBW40_TH1_7_BE4 GENMASK(26, 24) +#define B_DPD_CBW80_TH1_0_BE4 GENMASK(29, 27) +#define R_DPD_CBW_TH2_BE4 0x119C8 +#define B_DPD_CBW80_TH2_1_BE4 GENMASK(2, 0) +#define B_DPD_CBW80_TH2_2_BE4 GENMASK(5, 3) +#define B_DPD_CBW80_TH2_3_BE4 GENMASK(8, 6) +#define B_DPD_CBW80_TH2_4_BE4 GENMASK(11, 9) +#define B_DPD_CBW80_TH2_5_BE4 GENMASK(14, 12) +#define B_DPD_CBW80_TH2_6_BE4 GENMASK(17, 15) +#define B_DPD_CBW80_TH2_7_BE4 GENMASK(20, 18) +#define R_QAM_TH0_BE4 0x119E4 +#define B_QAM_TH0_0_BE4 GENMASK(18, 16) +#define B_QAM_TH0_1_BE4 GENMASK(21, 19) +#define B_QAM_TH0_2_BE4 GENMASK(24, 22) +#define B_QAM_TH0_3_BE4 GENMASK(27, 25) +#define B_QAM_TH0_4_BE4 GENMASK(30, 28) +#define R_QAM_TH1_BE4 0x119E8 +#define B_QAM_TH1_0_BE4 GENMASK(2, 0) +#define B_QAM_TH1_1_BE4 GENMASK(5, 3) +#define B_QAM_TH1_2_BE4 GENMASK(8, 6) +#define B_QAM_TH1_3_BE4 GENMASK(11, 9) +#define B_QAM_TH1_4_BE4 GENMASK(14, 12) +#define B_QAM_TH1_5_BE4 GENMASK(17, 15) +#define B_QAM_TH1_6_BE4 GENMASK(20, 18) +#define B_QAM_TH1_7_BE4 GENMASK(23, 21) +#define B_QAM_TH1_8_BE4 GENMASK(26, 24) +#define B_QAM_TH1_9_BE4 GENMASK(29, 27) +#define R_QAM_TH2_BE4 0x119EC +#define B_QAM_TH2_0_BE4 GENMASK(2, 0) +#define B_QAM_TH2_1_BE4 GENMASK(5, 3) +#define B_QAM_TH2_2_BE4 GENMASK(8, 6) +#define B_QAM_TH2_3_BE4 GENMASK(11, 9) +#define B_QAM_TH2_4_BE4 GENMASK(14, 12) +#define B_QAM_TH2_5_BE4 GENMASK(17, 15) +#define B_QAM_TH2_6_BE4 GENMASK(20, 18) +#define B_QAM_TH2_7_BE4 GENMASK(23, 21) +#define B_QAM_TH2_8_BE4 GENMASK(26, 24) +#define R_RFSI_CT_DEF_BE4 0x119F0 +#define B_RFSI_CT_ER_BE4 GENMASK(18, 15) +#define B_RFSI_CT_SUBF_BE4 GENMASK(22, 19) +#define B_RFSI_CT_FTM_BE4 GENMASK(26, 23) +#define B_RFSI_CT_SENS_BE4 GENMASK(30, 27) +#define R_FBTB_CT_DEF_BE4 0x119F4 +#define B_FBTB_CT_DEF_BE GENMASK(3, 0) +#define B_FBTB_CT_PB_BE4 GENMASK(7, 4) +#define B_FBTB_CT_DL_WO_BE4 GENMASK(11, 8) +#define B_FBTB_CT_DL_BF_BE4 GENMASK(15, 12) +#define B_FBTB_CT_MUMIMO_BE4 GENMASK(19, 16) +#define B_FBTB_CT_FTM_BE4 GENMASK(23, 20) +#define B_FBTB_CT_SENS_BE4 GENMASK(27, 24) +#define R_CIM3K_SU_FORCE 0x119F8 +#define B_CIM3K_SU_FORCE_EN BIT(17) +#define B_CIM3K_SU_FORCE_VAL BIT(18) +#define R_QAM3_TH0_BE4 0x119FC +#define B_QAM3_TH0_0_BE4 GENMASK(2, 0) +#define B_QAM3_TH0_1_BE4 GENMASK(5, 3) +#define B_QAM3_TH0_2_BE4 GENMASK(8, 6) +#define B_QAM3_TH0_3_BE4 GENMASK(11, 9) +#define B_QAM3_TH0_4_BE4 GENMASK(14, 12) +#define B_QAM3_TH0_5_BE4 GENMASK(17, 15) +#define B_QAM3_TH0_6_BE4 GENMASK(20, 18) +#define B_QAM3_TH0_7_BE4 GENMASK(23, 21) +#define B_QAM3_TH1_0_BE4 GENMASK(26, 24) +#define B_QAM3_TH1_1_BE4 GENMASK(29, 27) +#define R_RFSI_CT_OPT_0_BE4 0x11A94 +#define R_RFSI_CT_OPT_8_BE4 0x11A98 +#define R_QAM_COMP_TH0_BE4 0x11A9C +#define B_QAM_COMP_TH_TRIANGULAR_L GENMASK(11, 10) +#define B_QAM_COMP_TH_TRIANGULAR_H GENMASK(27, 26) +#define R_QAM_COMP_TH1_BE4 0x11AA0 +#define R_QAM_COMP_TH2_BE4 0x11AA4 +#define R_QAM_COMP_TH3_BE4 0x11AA8 +#define R_QAM_COMP_TH4_BE4 0x11ABC +#define B_QAM_COMP_TH4_L GENMASK(4, 0) +#define B_QAM_COMP_TH4_M GENMASK(14, 10) +#define B_QAM_COMP_TH4_H GENMASK(24, 20) +#define B_QAM_COMP_TH4_2L GENMASK(9, 5) +#define B_QAM_COMP_TH4_2M GENMASK(19, 15) +#define B_QAM_COMP_TH4_2H GENMASK(29, 25) +#define R_QAM_COMP_TH5_BE4 0x11AC0 +#define B_QAM_COMP_TH5_L GENMASK(4, 0) +#define B_QAM_COMP_TH5_M GENMASK(14, 10) +#define B_QAM_COMP_TH5_H GENMASK(24, 20) +#define B_QAM_COMP_TH5_2L GENMASK(9, 5) +#define B_QAM_COMP_TH5_2M GENMASK(19, 15) +#define B_QAM_COMP_TH5_2H GENMASK(29, 25) +#define R_QAM_COMP_TH6_BE4 0x11AC4 +#define B_QAM_COMP_TH6_L GENMASK(4, 0) +#define B_QAM_COMP_TH6_M GENMASK(14, 10) +#define B_QAM_COMP_TH6_2L GENMASK(9, 5) +#define B_QAM_COMP_TH6_2M GENMASK(19, 15) +#define R_OW_VAL_0_BE4 0x11AAC +#define B_OW_VAL_TRIANGULAR_L GENMASK(11, 10) +#define B_OW_VAL_TRIANGULAR_H GENMASK(27, 26) +#define R_OW_VAL_1_BE4 0x11AB0 +#define R_OW_VAL_2_BE4 0x11AB4 +#define R_OW_VAL_3_BE4 0x11AB8 +#define R_BANDEDGE_DBWX_BE4 0x11ACC +#define B_BANDEDGE_DBW20_BE4 BIT(29) +#define B_BANDEDGE_DBW40_BE4 BIT(30) +#define B_BANDEDGE_DBW80_BE4 BIT(31) +#define R_BANDEDGE_DBWY_BE4 0x11AD0 +#define B_BANDEDGE_DBW160_BE4 BIT(0) +#define R_QAM3_TH1_BE4 0x11BE8 +#define B_QAM3_TH1_2_BE4 GENMASK(2, 0) +#define B_QAM3_TH1_3_BE4 GENMASK(5, 3) +#define B_QAM3_TH1_4_BE4 GENMASK(8, 6) +#define B_QAM3_TH1_5_BE4 GENMASK(11, 9) +#define B_QAM3_TH1_6_BE4 GENMASK(14, 12) +#define B_QAM3_TH1_7_BE4 GENMASK(17, 15) +#define B_QAM3_TH2_0_BE4 GENMASK(20, 18) +#define B_QAM3_TH2_1_BE4 GENMASK(23, 21) +#define B_QAM3_TH2_2_BE4 GENMASK(26, 24) +#define B_QAM3_TH2_3_BE4 GENMASK(29, 27) +#define R_QAM3_TH2_BE4 0x11BEC +#define B_QAM3_TH2_4_BE4 GENMASK(2, 0) +#define B_QAM3_TH2_5_BE4 GENMASK(5, 3) +#define B_QAM3_TH2_6_BE4 GENMASK(8, 6) +#define B_QAM3_TH2_7_BE4 GENMASK(11, 9) +#define B_QAM3_TH3_0_BE4 GENMASK(14, 12) +#define B_QAM3_TH3_1_BE4 GENMASK(17, 15) +#define B_QAM3_TH3_2_BE4 GENMASK(20, 18) +#define B_QAM3_TH3_3_BE4 GENMASK(23, 21) +#define B_QAM3_TH3_4_BE4 GENMASK(26, 24) +#define B_QAM3_TH3_5_BE4 GENMASK(29, 27) +#define R_QAM3_TH3_BE4 0x11BF4 +#define B_QAM3_TH3_6_BE4 GENMASK(2, 0) +#define B_QAM3_TH3_7_BE4 GENMASK(5, 3) +#define B_QAM3_TH5_0_BE4 GENMASK(8, 6) +#define B_QAM3_TH5_1_BE4 GENMASK(11, 9) +#define B_QAM3_TH5_2_BE4 GENMASK(14, 12) +#define B_QAM3_TH5_3_BE4 GENMASK(17, 15) +#define B_QAM3_TH5_4_BE4 GENMASK(20, 18) +#define B_QAM3_TH5_5_BE4 GENMASK(23, 21) +#define B_QAM3_TH5_6_BE4 GENMASK(26, 24) +#define B_QAM3_TH5_7_BE4 GENMASK(29, 27) +#define R_QAM3_TH4_BE4 0x11BF8 +#define B_QAM3_TH4_0_BE4 GENMASK(2, 0) +#define B_QAM3_TH4_1_BE4 GENMASK(5, 3) +#define B_QAM3_TH4_2_BE4 GENMASK(8, 6) +#define B_QAM3_TH4_3_BE4 GENMASK(11, 9) +#define B_QAM3_TH4_4_BE4 GENMASK(14, 12) +#define B_QAM3_TH4_5_BE4 GENMASK(17, 15) +#define B_QAM3_TH4_6_BE4 GENMASK(20, 18) +#define B_QAM3_TH4_7_BE4 GENMASK(23, 21) +#define B_QAM3_CFIR0_BE4 BIT(24) +#define B_QAM3_CFIR1_BE4 BIT(25) +#define B_QAM3_CFIR2_BE4 BIT(26) +#define B_QAM3_CFIR3_BE4 BIT(27) +#define B_QAM3_CFIR4_BE4 BIT(28) +#define B_QAM3_CFIR5_BE4 BIT(29) +#define B_QAM3_CFIR6_BE4 BIT(30) +#define B_QAM3_CFIR7_BE4 BIT(31) +#define R_QAM3_FLTR_BE4 0x11BFC +#define B_QAM3_FLTR0_BE4 GENMASK(1, 0) +#define B_QAM3_FLTR1_BE4 GENMASK(3, 2) +#define B_QAM3_FLTR2_BE4 GENMASK(5, 4) +#define B_QAM3_FLTR3_BE4 GENMASK(7, 6) +#define B_QAM3_FLTR4_BE4 GENMASK(9, 8) +#define B_QAM3_FLTR5_BE4 GENMASK(11, 10) +#define B_QAM3_FLTR6_BE4 GENMASK(13, 12) +#define B_QAM3_FLTR7_BE4 GENMASK(15, 14) + +#define R_SYS_DBCC_BE4 0x20000 +#define B_SYS_DBCC_BE4 BIT(0) +#define B_SYS_DBCC_24G_BAND_SEL_BE4 BIT(1) +#define R_EMLSR_SWITCH_BE4 0x20044 +#define B_EMLSR_SWITCH_BE4 GENMASK(27, 12) +#define B_EMLSR_CLR_FORCE_BE4 GENMASK(20, 19) +#define B_EMLSR_BB_CLK_BE4 GENMASK(31, 30) +#define R_CHINFO_SEG_BE4 0x200B4 +#define B_CHINFO_SEG_LEN_BE4 GENMASK(12, 10) +#define R_SEL_GNT_BT_RX_BE4 0x2010C +#define B_SEL_GNT_BT_RX_PATH0_BE4 GENMASK(3, 0) +#define B_SEL_GNT_BT_RX_PATH1_BE4 GENMASK(11, 8) +#define R_SW_SI_WDATA_BE4 0x20370 +#define B_SW_SI_DATA_PATH_BE4 GENMASK(31, 28) +#define B_SW_SI_DATA_ADR_BE4 GENMASK(27, 20) +#define B_SW_SI_DATA_DAT_BE4 GENMASK(19, 0) +#define R_SW_SI_READ_ADDR_BE4 0x20378 +#define B_SW_SI_READ_ADDR_BE4 GENMASK(10, 0) +#define R_RXBW67_BE4 0x2040C +#define B_RXBW6_BE4 GENMASK(22, 20) +#define B_RXBW7_BE4 GENMASK(25, 23) +#define R_RXBW_BE4 0x20410 +#define B_RXBW_BE4 GENMASK(29, 27) +#define R_TXERRCT_EN_BE4 0x20518 +#define B_TXERRCT_EN_BE4 BIT(13) +#define R_TXERRCT1_EN_BE4 0x2051C +#define B_TXERRCT1_EN_BE4 BIT(31) +#define R_ENABLE_CCK0_BE4 0x20700 +#define B_ENABLE_CCK0_BE4 BIT(5) +#define R_RSTB_ASYNC_BE4 0x20704 +#define B_RSTB_ASYNC_BE4 BIT(1) +#define R_STS_HDR2_PARSING_BE4 0x2070C +#define B_STS_HDR2_PARSING_BE4 BIT(10) +#define R_EDCCA_RPT_SEL_BE4 0x20780 +#define R_EDCCA_RPT_SEL_BE4_C1 0x21780 +#define B_EDCCA_RPT_SEL_BE4_MSK 0xE0000 +#define R_SEL_GNT_BT_RXPHY_BE4 0x2079C +#define B_SEL_GNT_BT_RXPHY_BE4 GENMASK(11, 8) +#define R_IMR_TX_ERROR_BE4 0x20920 +#define B_IMR_TX_ERROR_BE4 BIT(30) +#define R_TXINFO_PATH_BE4 0x209A4 +#define B_TXINFO_PATH_EN_BE4 BIT(17) +#define B_TXINFO_PATH_MA_BE4 BIT(18) +#define B_TXINFO_PATH_MB_BE4 BIT(19) +#define R_SHAPER_COEFF_BE4 0x20CBC +#define B_SHAPER_COEFF_BE4 BIT(19) + +#define R_CL_MODE_CNT_BE4 0x20DE0 +#define B_CL_MODE_NDP_CNT_PHY0_BE4 GENMASK(31, 24) +#define B_CL_MODE_NDP_CNT_PHY1_BE4 GENMASK(15, 8) +#define B_CL_MODE_CL_CNT_PHY0_BE4 GENMASK(23, 16) +#define B_CL_MODE_CL_CNT_PHY1_BE4 GENMASK(7, 0) + +#define R_IFS_T1_AVG_BE4 0x20EDC +#define B_IFS_T1_AVG_BE4 GENMASK(15, 0) +#define B_IFS_T2_AVG_BE4 GENMASK(31, 16) +#define R_IFS_T3_AVG_BE4 0x20EE0 +#define B_IFS_T3_AVG_BE4 GENMASK(15, 0) +#define B_IFS_T4_AVG_BE4 GENMASK(31, 16) +#define R_IFS_T1_CLM_BE4 0x20EE4 +#define B_IFS_T1_CLM_BE4 GENMASK(15, 0) +#define B_IFS_T2_CLM_BE4 GENMASK(31, 16) +#define R_IFS_T3_CLM_BE4 0x20EE8 +#define B_IFS_T3_CLM_BE4 GENMASK(15, 0) +#define B_IFS_T4_CLM_BE4 GENMASK(31, 16) +#define R_IFS_TOTAL_BE4 0x20EEC +#define B_IFS_TOTAL_BE4 GENMASK(15, 0) +#define B_IFS_CNT_DONE_BE4 BIT(16) +#define R_IFS_T1_HIS_BE4 0x20F50 +#define B_IFS_T1_HIS_BE4 GENMASK(15, 0) +#define B_IFS_T2_HIS_BE4 GENMASK(31, 16) +#define R_IFS_T3_HIS_BE4 0x20F54 +#define B_IFS_T3_HIS_BE4 GENMASK(15, 0) +#define B_IFS_T4_HIS_BE4 GENMASK(31, 16) +#define R_CNT_CCK_CCA_BE4 0x20FE8 +#define B_CNT_CCK_CCA_BE4 GENMASK(15, 0) +#define R_CNT_CCK_CRC32_BE4 0x20FEC +#define B_CNT_CCK_CRC32OK_BE4 GENMASK(15, 0) +#define B_CNT_CCK_CRC32FAIL_BE4 GENMASK(31, 16) + +#define R_TX_ERROR_SEL_BE4 0x21254 +#define B_TX_ERROR_PSDU_BE4 BIT(11) +#define B_TX_ERROR_NSYM_BE4 BIT(10) +#define B_TX_ERROR_LSIG_BE4 BIT(9) +#define B_TX_ERROR_TXINFO_BE4 BIT(8) + +#define R_TXPWR_RSTB0_BE4 0x2250C +#define B_TXPWR_RSTB0_BE4 BIT(16) +#define R_TSSI_EN_P0_BE4 0x22510 +#define B_TSSI_EN_P0_BE4 GENMASK(3, 0) +#define R_TXAGC_REF_DBM_PATH0_TBL0_BE4 0x22528 +#define B_TXAGC_OFDM_REF_DBM_PATH0_TBL0_BE4 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_PATH0_TBL0_BE4 GENMASK(17, 9) +#define R_USED_TSSI_TRK_ON_P0_BE4 0x22534 +#define B_USED_TSSI_TRK_ON_P0_BE4 BIT(22) +#define R_TSSI_K_OFDM_PATH0_TBL0_BE4 0x225A0 +#define B_TSSI_K_OFDM_PATH0_TBL0_BE4 GENMASK(29, 20) +#define R_TSSI_DCK_MOV_AVG_LEN_P0_BE4 0x225CC +#define B_TSSI_DCK_MOV_AVG_LEN_P0_BE4 GENMASK(8, 6) +#define R_TXPWR_RSTB1_BE4 0x2260C +#define B_TXPWR_RSTB1_BE4 BIT(16) + +#define R_TXAGC_REF_DBM_PATH0_TBL1_BE4 0x23528 +#define B_TXAGC_OFDM_REF_DBM_PATH0_TBL1_BE4 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_PATH0_TBL1_BE4 GENMASK(17, 9) +#define R_TSSI_K_OFDM_PATH0_TBL1_BE4 0x235A0 +#define B_TSSI_K_OFDM_PATH0_TBL1_BE4 GENMASK(29, 20) + +#define R_OFDM_OFST_P0_BE4 0x240C8 +#define B_OFDM_OFST_P0_BE4 GENMASK(31, 24) +#define R_PATH0_RXIDX_INIT_BE4 0x24108 +#define B_PATH0_RXIDX_INIT_BE4 GENMASK(29, 25) +#define R_PATH0_LNA_INIT_BE4 0x24158 +#define B_PATH0_LNA_INIT_IDX_BE4 GENMASK(14, 12) +#define R_BAND_SEL0_BE4 0x24160 +#define B_BAND_SEL0_BE4 BIT(26) +#define R_PATH0_TIA_INIT_BE4 0x24168 +#define B_PATH0_TIA_INIT_IDX_BE4 BIT(18) +#define R_OFDM_RPL_BIAS_P0_BE4 0x2420C +#define B_OFDM_RPL_BIAS_P0_BE4 GENMASK(11, 2) +#define R_OFDM_OFST_P1_BE4 0x244C8 +#define B_OFDM_OFST_P1_BE4 GENMASK(31, 24) +#define R_PATH1_RXIDX_INIT_BE4 0x24508 +#define B_PATH1_RXIDX_INIT_BE4 GENMASK(29, 25) +#define R_PATH1_LNA_INIT_BE4 0x24558 +#define B_PATH1_LNA_INIT_IDX_BE4 GENMASK(14, 12) +#define R_BAND_SEL1_BE4 0x24560 +#define B_BAND_SEL1_BE4 BIT(26) +#define R_PATH1_TIA_INIT_BE4 0x24568 +#define B_PATH1_TIA_INIT_IDX_BE4 BIT(18) +#define R_OFDM_RPL_BIAS_P1_BE4 0x2460C +#define B_OFDM_RPL_BIAS_P1_BE4 GENMASK(11, 2) +#define R_TX_CFR_MANUAL_EN_BE4 0x2483C +#define B_TX_CFR_MANUAL_EN_BE4_M BIT(30) +#define R_PCOEFF0_BE4 0x24880 +#define B_PCOEFF01_BE4 GENMASK(23, 0) +#define R_PCOEFF2_BE4 0x24884 +#define B_PCOEFF23_BE4 GENMASK(23, 0) +#define R_PCOEFF4_BE4 0x24888 +#define B_PCOEFF45_BE4 GENMASK(23, 0) +#define R_PCOEFF6_BE4 0x2488C +#define B_PCOEFF67_BE4 GENMASK(23, 0) +#define R_PCOEFF8_BE4 0x24890 +#define B_PCOEFF89_BE4 GENMASK(23, 0) +#define R_PCOEFF10_BE4 0x24894 +#define B_PCOEFF10_BE4 GENMASK(23, 0) +#define R_PCOEFF12_BE4 0x24898 +#define B_PCOEFF12_BE4 GENMASK(23, 0) +#define R_PCOEFF14_BE4 0x2489C +#define B_PCOEFF14_BE4 GENMASK(23, 0) +#define R_BW_BE4 0x24EE4 +#define B_BW_BE4 GENMASK(6, 4) +#define B_PRISB_BE4 GENMASK(3, 0) +#define R_FC0_BE4 0x24EE8 +#define B_FC0_BE4 GENMASK(12, 0) +#define R_ANT_RX_1RCCA_BE4 0x24EEC +#define B_ANT_RX_1RCCA_BE4 GENMASK(17, 14) +#define R_ANT_RX_BE4 0x24EF0 +#define B_ANT_RX_BE4 GENMASK(3, 0) +#define R_FC0_INV_BE4 0x24EF4 +#define B_FC0_INV_BE4 GENMASK(15, 0) + +#define R_CCK_RPL_OFST_BE4 0x26084 +#define B_CCK_RPL_OFST_BE4 GENMASK(7, 0) +#define R_BK_FC0_INV_BE4 0x2608C +#define B_BK_FC0_INV_BE4 GENMASK(18, 0) +#define R_CCK_FC0_INV_BE4 0x26090 +#define B_CCK_FC0_INV_BE4 GENMASK(18, 0) +#define R_GAIN_BIAS_BE4 0x260A0 +#define B_GAIN_BIAS_BW20_BE4 GENMASK(11, 6) +#define B_GAIN_BIAS_BW40_BE4 GENMASK(17, 12) + +#define R_BF_SMO_PDP_LMT_EHT_BE4 0x26568 +#define B_BF_SMO_PDP_LMT_EHT_BE4 BIT(30) +#define R_BF_SMO_PDP_LMT_HE_BE4 0x26568 +#define B_BF_SMO_PDP_LMT_HE_BE4 BIT(31) +#define R_BF_SMO_PDP_LMT_VHT_BE4 0x2656C +#define B_BF_SMO_PDP_LMT_VHT_BE4 BIT(31) + +#define R_AWGN_DET_BE4 0x2668C +#define B_AWGN_DET_BE4 GENMASK(17, 9) +#define R_CSI_WGT_BE4 0x26770 +#define B_CSI_WGT_EN_BE4 BIT(0) +#define B_CSI_WGT_IDX_BE4 GENMASK(31, 20) +#define R_CHINFO_OPT_BE4 0x267C8 +#define B_CHINFO_OPT_BE4 GENMASK(14, 13) +#define R_CHINFO_NX_BE4 0x267D0 +#define B_CHINFO_NX_BE4 GENMASK(16, 6) +#define R_CHINFO_ALG_BE4 0x267C8 +#define B_CHINFO_ALG_BE4 GENMASK(31, 30) +#define R_RX_AWGN02_BE4 0x2680C +#define B_RX_AWGN11_BE4 GENMASK(23, 18) +#define R_RX_AWGN00_BE4 0x26814 +#define B_RX_AWGN04_BE4 GENMASK(5, 0) +#define B_RX_AWGN07_BE4 GENMASK(23, 18) +#define R_RX_AWGN01_BE4 0x26818 +#define B_RX_AWGN09_BE4 GENMASK(5, 0) +#define R_RXCH_BCC0_BE4 0x26824 +#define B_RXCH_MCS4_BE4 GENMASK(29, 24) +#define R_RXCH_BCC1_BE4 0x26828 +#define B_RXCH_MCS5_BE4 GENMASK(5, 0) +#define B_RXCH_MCS6_BE4 GENMASK(11, 6) +#define B_RXCH_MCS7_BE4 GENMASK(17, 12) +#define B_RXCH_MCS8_BE4 GENMASK(23, 18) +#define B_RXCH_MCS9_BE4 GENMASK(29, 24) +#define R_RX_LDPC02_BE4 0x26834 +#define B_RX_LDPC10_BE4 GENMASK(17, 12) +#define B_RX_LDPC11_BE4 GENMASK(23, 18) +#define B_RX_LDPC12_BE4 GENMASK(29, 24) +#define R_RX_LDPC03_BE4 0x26838 +#define B_RX_LDPC13_BE4 GENMASK(5, 0) +#define B_RX_LDPC02_BE4 GENMASK(23, 18) +#define B_RX_LDPC03_BE4 GENMASK(29, 24) +#define R_RX_LDPC00_BE4 0x2683C +#define B_RX_LDPC04_BE4 GENMASK(5, 0) +#define B_RX_LDPC05_BE4 GENMASK(11, 6) +#define B_RX_LDPC06_BE4 GENMASK(17, 12) +#define B_RX_LDPC07_BE4 GENMASK(23, 18) +#define B_RX_LDPC08_BE4 GENMASK(29, 24) +#define R_RX_LDPC01_BE4 0x26840 +#define B_RX_LDPC09_BE4 GENMASK(5, 0) +#define R_BSS_CLR_MAP_BE4 0x26914 +#define R_BSS_CLR_VLD_BE4 0x26920 +#define B_BSS_CLR_VLD_BE4 BIT(2) + +#define R_CL_MODE_TRIG_BE4 0x26F44 +#define B_CL_MODE_TRIG_BE4 BIT(31) +#define R_SELECTED_TONE_IDX_BE4 0x26F4C +#define B_SELECTED_TONE_IDX_BE4 GENMASK(11, 0) +#define R_OS_TRIG_BY_SW_BE4 0x26F50 +#define B_OS_TRIG_BY_SW_BE4 BIT(30) +#define R_OS_TRIG_SOURCE_BE4 0x26F6C +#define B_OS_TRIG_SOURCE_BE4 BIT(0) + +#define R_SW_SI_DATA_BE4 0x2CF4C +#define B_SW_SI_READ_DATA_BE4 GENMASK(19, 0) +#define B_SW_SI_W_BUSY_BE4 BIT(24) +#define B_SW_SI_R_BUSY_BE4 BIT(25) +#define B_SW_SI_READ_DATA_DONE_BE4 BIT(26) + +#define R_TX_INFO_0_0_COMB_BE4 0x2DF00 +#define R_TX_INFO_0_1_COMB_BE4 0x2DF04 +#define R_TX_INFO_1_0_COMB_BE4 0x2DF08 +#define R_TX_INFO_1_1_COMB_BE4 0x2DF0C +#define R_TX_INFO_2_0_COMB_BE4 0x2DF10 +#define R_TX_INFO_2_1_COMB_BE4 0x2DF14 +#define R_TX_COMMON_CTRL_0_0_COMB_BE4 0x2DF20 +#define R_TX_COMMON_CTRL_0_1_COMB_BE4 0x2DF24 +#define R_RX_PATH0_TBL0_BE4 0x2E028 +#define R_RX_PATH1_TBL0_BE4 0x2E128 + +#define R_KTBL0A_BE4 0x38104 +#define R_KTBL0B_BE4 0x38204 +#define B_KTBL0_IDX0 GENMASK(1, 0) +#define B_KTBL0_IDX1 GENMASK(9, 8) +#define B_KTBL0_MLD_IDX0 GENMASK(25, 24) +#define B_KTBL0_MLD_IDX1 GENMASK(27, 26) +#define B_KTBL0_RST BIT(31) +#define R_CFIR_CTRL_A_BE4 0x38124 +#define R_CFIR_CTRL_B_BE4 0x38224 +#define B_CFIR_CTRL_KIDX0_EN BIT(8) +#define B_CFIR_CTRL_KIDX1_EN BIT(24) +#define R_TX_IQC_A_BE4 0x38138 +#define R_TX_IQC_B_BE4 0x38238 +#define B_TX_IQC_X GENMASK(31, 20) +#define B_TX_IQC_Y GENMASK(19, 8) +#define B_TX_IQC_DPK BIT(3) +#define R_KTBL1A_BE4 0x38154 +#define R_KTBL1B_BE4 0x38254 +#define B_KTBL1_TBL0 BIT(3) +#define B_KTBL1_TBL1 BIT(5) + +#define R_TC_EN_BE4 0x3c200 +#define B_TC_EN_BE4 BIT(0) +#define B_TC_TRIG_BE4 BIT(1) +#define R_TC_VAL_BE4 0x3c208 +#define B_TC_VAL_BE4 GENMASK(7, 0) + +/* WiFi CPU local domain */ +#define R_AX_WDT_CTRL 0x0040 +#define B_AX_WDT_EN BIT(31) +#define B_AX_WDT_OPT_RESET_PLATFORM_EN BIT(29) +#define B_AX_IO_HANG_IMR BIT(27) +#define B_AX_IO_HANG_CMAC_RDATA_EN BIT(26) +#define B_AX_IO_HANG_DMAC_EN BIT(25) +#define B_AX_WDT_CLR BIT(16) +#define B_AX_WDT_COUNT_MASK GENMASK(15, 0) +#define WDT_CTRL_ALL_DIS 0 + +#define R_AX_WDT_STATUS 0x0044 +#define B_AX_FS_WDT_INT BIT(8) +#define B_AX_FS_WDT_INT_MSK BIT(0) + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c new file mode 100644 index 000000000..14fab6b1a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -0,0 +1,1210 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "acpi.h" +#include "debug.h" +#include "ps.h" +#include "util.h" + +static +void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +#define COUNTRY_REGD(_alpha2, _rule_2ghz, _rule_5ghz, _rule_6ghz, _fmap) \ + { \ + .alpha2 = _alpha2, \ + .txpwr_regd[RTW89_BAND_2G] = _rule_2ghz, \ + .txpwr_regd[RTW89_BAND_5G] = _rule_5ghz, \ + .txpwr_regd[RTW89_BAND_6G] = _rule_6ghz, \ + .func_bitmap = { _fmap, }, \ + } + +static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC); + +static const struct rtw89_regd rtw89_ww_regd = + COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0); + +static const struct rtw89_regd rtw89_regd_map[] = { + COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), + COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE, 0x0), + COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), + COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1), + COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK, 0x0), + COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0), + COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE, 0x0), + COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0), + COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1), + COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0), + COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0), + COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), + COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), + COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC, 0x1), + COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK, 0x0), + COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0), + COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0), + COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), +}; + +static const char rtw89_alpha2_list_eu[][3] = { + "AT", + "BE", + "CY", + "CZ", + "DK", + "EE", + "FI", + "FR", + "DE", + "GR", + "HU", + "IS", + "IE", + "IT", + "LV", + "LI", + "LT", + "LU", + "MT", + "MC", + "NL", + "NO", + "PL", + "PT", + "SK", + "SI", + "ES", + "SE", + "CH", + "BG", + "HR", + "RO", +}; + +static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rtwdev, + const char *alpha2) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; + u32 i; + + for (i = 0; i < regd_ctrl->nr; i++) { + if (!memcmp(regd_ctrl->map[i].alpha2, alpha2, 2)) + return ®d_ctrl->map[i]; + } + + return &rtw89_ww_regd; +} + +static bool rtw89_regd_is_ww(const struct rtw89_regd *regd) +{ + return regd == &rtw89_ww_regd; +} + +static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; + + BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM); + + if (rtw89_regd_is_ww(regd)) + return RTW89_REGD_MAX_COUNTRY_NUM; + + return regd - regd_ctrl->map; +} + +static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alpha2) +{ + const struct rtw89_regd *regd; + + regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2); + return rtw89_regd_get_index(rtwdev, regd); +} + +#define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \ +do { \ + typeof(_regd) __r = _regd; \ + rtw89_debug(_dev, RTW89_DBG_REGD, _desc \ + ": %c%c: mapping txregd to {2g: %d, 5g: %d, 6g: %d}\n", \ + ##_argv, __r->alpha2[0], __r->alpha2[1], \ + __r->txpwr_regd[RTW89_BAND_2G], \ + __r->txpwr_regd[RTW89_BAND_5G], \ + __r->txpwr_regd[RTW89_BAND_6G]); \ +} while (0) + +static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev, + struct wiphy *wiphy) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_supported_band *sband; + struct rtw89_acpi_dsm_result res = {}; + bool enable; + u8 index; + int ret; + u8 val; + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + if (!sband) + return; + + if (!chip->support_unii4) { + sband->n_channels -= RTW89_5GHZ_UNII4_CHANNEL_NUM; + return; + } + + if (skip_acpi_dsm) + return; + + bitmap_fill(regulatory->block_unii4, RTW89_REGD_MAX_COUNTRY_NUM); + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_UNII4_SUP, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval unii 4: %d\n", ret); + val = u8_encode_bits(1, RTW89_ACPI_CONF_UNII4_US); + goto bottom; + } + + val = res.u.value; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: eval if allow unii-4: 0x%x\n", val); + +bottom: + index = rtw89_regd_get_index_by_name(rtwdev, "US"); + enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_US); + if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + clear_bit(index, regulatory->block_unii4); + + index = rtw89_regd_get_index_by_name(rtwdev, "CA"); + enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_CA); + if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + clear_bit(index, regulatory->block_unii4); +} + +static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block, + const char *alpha2) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + u8 index; + + index = rtw89_regd_get_index_by_name(rtwdev, alpha2); + if (index == RTW89_REGD_MAX_COUNTRY_NUM) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n", + __func__, alpha2[0], alpha2[1]); + return; + } + + if (block) + set_bit(index, regulatory->block_6ghz); + else + clear_bit(index, regulatory->block_6ghz); +} + +static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_acpi_country_code *country; + const struct rtw89_acpi_policy_6ghz *ptr; + struct rtw89_acpi_dsm_result res = {}; + bool to_block; + int i, j; + int ret; + + if (skip_acpi_dsm) + return; + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_BP, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval policy 6ghz: %d\n", ret); + return; + } + + ptr = res.u.policy_6ghz; + + switch (ptr->policy_mode) { + case RTW89_ACPI_POLICY_BLOCK: + to_block = true; + break; + case RTW89_ACPI_POLICY_ALLOW: + to_block = false; + /* only below list is allowed; block all first */ + bitmap_fill(regulatory->block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "%s: unknown policy mode: %d\n", __func__, + ptr->policy_mode); + goto out; + } + + for (i = 0; i < ptr->country_count; i++) { + country = &ptr->country_list[i]; + if (memcmp("EU", country->alpha2, 2) != 0) { + __rtw89_regd_setup_policy_6ghz(rtwdev, to_block, + country->alpha2); + continue; + } + + for (j = 0; j < ARRAY_SIZE(rtw89_alpha2_list_eu); j++) + __rtw89_regd_setup_policy_6ghz(rtwdev, to_block, + rtw89_alpha2_list_eu[j]); + } + +out: + kfree(ptr); +} + +static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_acpi_policy_6ghz_sp *ptr; + struct rtw89_acpi_dsm_result res = {}; + bool enable; + u8 index; + int ret; + + if (skip_acpi_dsm) + return; + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval policy 6ghz-sp: %d\n", ret); + return; + } + + ptr = res.u.policy_6ghz_sp; + + switch (ptr->override) { + default: + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "%s: unknown override case: %d\n", __func__, + ptr->override); + fallthrough; + case 0: + goto out; + case 1: + break; + } + + bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM); + + index = rtw89_regd_get_index_by_name(rtwdev, "US"); + enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US); + if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + clear_bit(index, regulatory->block_6ghz_sp); + + index = rtw89_regd_get_index_by_name(rtwdev, "CA"); + enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_CA); + if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + clear_bit(index, regulatory->block_6ghz_sp); + +out: + kfree(ptr); +} + +static void rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_acpi_policy_6ghz_vlp *ptr = NULL; + struct rtw89_acpi_dsm_result res = {}; + bool enable; + u8 index; + int ret; + u8 val; + + if (skip_acpi_dsm) + return; + + /* By default, allow 6 GHz VLP on all countries except US and CA. */ + val = ~(RTW89_ACPI_CONF_6GHZ_VLP_US | RTW89_ACPI_CONF_6GHZ_VLP_CA); + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval policy 6ghz-vlp: %d\n", ret); + goto bottom; + } + + ptr = res.u.policy_6ghz_vlp; + + switch (ptr->override) { + default: + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "%s: unknown override case: %d\n", __func__, + ptr->override); + fallthrough; + case 0: + break; + case 1: + val = ptr->conf; + break; + } + +bottom: + index = rtw89_regd_get_index_by_name(rtwdev, "US"); + enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_US); + if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + set_bit(index, regulatory->block_6ghz_vlp); + + index = rtw89_regd_get_index_by_name(rtwdev, "CA"); + enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_CA); + if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM) + set_bit(index, regulatory->block_6ghz_vlp); + + kfree(ptr); +} + +static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ); + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + bool regd_allow_6ghz = chip_support_6ghz; + struct ieee80211_supported_band *sband; + struct rtw89_acpi_dsm_result res = {}; + int ret; + u8 val; + + if (!chip_support_6ghz) + goto bottom; + + if (skip_acpi_dsm) + goto bottom; + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval 6ghz: %d\n", ret); + goto bottom; + } + + val = res.u.value; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: eval if disallow 6ghz: %d\n", val); + + switch (val) { + case 0: + regd_allow_6ghz = true; + break; + case 1: + regd_allow_6ghz = false; + break; + default: + break; + } + +bottom: + rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow 6ghz: %d\n", + regd_allow_6ghz); + + if (regd_allow_6ghz) { + rtw89_regd_setup_policy_6ghz(rtwdev); + rtw89_regd_setup_policy_6ghz_sp(rtwdev); + rtw89_regd_setup_policy_6ghz_vlp(rtwdev); + return; + } + + sband = wiphy->bands[NL80211_BAND_6GHZ]; + if (!sband) + return; + + wiphy->bands[NL80211_BAND_6GHZ] = NULL; + kfree((__force void *)sband->iftype_data); + kfree(sband); +} + +#define RTW89_DEF_REGD_STR(regd) \ + [RTW89_ ## regd] = #regd + +static const char * const rtw89_regd_string[] = { + RTW89_DEF_REGD_STR(WW), + RTW89_DEF_REGD_STR(ETSI), + RTW89_DEF_REGD_STR(FCC), + RTW89_DEF_REGD_STR(MKK), + RTW89_DEF_REGD_STR(NA), + RTW89_DEF_REGD_STR(IC), + RTW89_DEF_REGD_STR(KCC), + RTW89_DEF_REGD_STR(ACMA), + RTW89_DEF_REGD_STR(NCC), + RTW89_DEF_REGD_STR(MEXICO), + RTW89_DEF_REGD_STR(CHILE), + RTW89_DEF_REGD_STR(UKRAINE), + RTW89_DEF_REGD_STR(CN), + RTW89_DEF_REGD_STR(QATAR), + RTW89_DEF_REGD_STR(UK), + RTW89_DEF_REGD_STR(THAILAND), +}; + +static_assert(ARRAY_SIZE(rtw89_regd_string) == RTW89_REGD_NUM); + +const char *rtw89_regd_get_string(enum rtw89_regulation_type regd) +{ + if (regd < 0 || regd >= RTW89_REGD_NUM) + return "(unknown)"; + + return rtw89_regd_string[regd]; +} + +static void rtw89_regd_setup_reg_rules(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_acpi_policy_reg_rules *ptr; + struct rtw89_acpi_dsm_result res = {}; + int ret; + + if (skip_acpi_dsm) + return; + + regulatory->txpwr_uk_follow_etsi = true; + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_REG_RULES_EN, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "acpi: cannot eval policy reg-rules: %d\n", ret); + return; + } + + ptr = res.u.policy_reg_rules; + + regulatory->txpwr_uk_follow_etsi = + !u8_get_bits(ptr->conf, RTW89_ACPI_CONF_REG_RULE_REGD_UK); + + kfree(ptr); +} + +int rtw89_regd_setup(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_regd_data *regd_data = elm_info->regd; + struct wiphy *wiphy = rtwdev->hw->wiphy; + + if (regd_data) { + regulatory->ctrl.nr = regd_data->nr; + regulatory->ctrl.map = regd_data->map; + } else { + regulatory->ctrl.nr = ARRAY_SIZE(rtw89_regd_map); + regulatory->ctrl.map = rtw89_regd_map; + } + + regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + + rtw89_regd_setup_reg_rules(rtwdev); + + if (!wiphy) + return -EINVAL; + + rtw89_regd_setup_unii4(rtwdev, wiphy); + rtw89_regd_setup_6ghz(rtwdev, wiphy); + + wiphy->reg_notifier = rtw89_regd_notifier; + return 0; +} + +int rtw89_regd_init_hint(struct rtw89_dev *rtwdev) +{ + const struct rtw89_regd *chip_regd; + struct wiphy *wiphy = rtwdev->hw->wiphy; + int ret; + + if (!wiphy) + return -EINVAL; + + chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code); + if (!rtw89_regd_is_ww(chip_regd)) { + rtwdev->regulatory.regd = chip_regd; + rtwdev->regulatory.programmed = true; + + /* Ignore country ie if there is a country domain programmed in chip */ + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; + + ret = regulatory_hint(rtwdev->hw->wiphy, + rtwdev->regulatory.regd->alpha2); + if (ret) + rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); + + rtw89_debug_regd(rtwdev, chip_regd, "efuse country code"); + return 0; + } + + rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, + "worldwide roaming chip, follow the setting of stack"); + return 0; +} + +static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev, + struct wiphy *wiphy) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_regd *regd = regulatory->regd; + struct ieee80211_supported_band *sband; + u8 index; + int i; + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + if (!sband) + return; + + if (!chip->support_unii4) + return; + + index = rtw89_regd_get_index(rtwdev, regd); + if (index != RTW89_REGD_MAX_COUNTRY_NUM && + !test_bit(index, regulatory->block_unii4)) + return; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n", + regd->alpha2[0], regd->alpha2[1]); + + for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++) + sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; +} + +static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + u8 index; + + index = rtw89_regd_get_index(rtwdev, regd); + if (index != RTW89_REGD_MAX_COUNTRY_NUM && + !test_bit(index, regulatory->block_6ghz)) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n", + regd->alpha2[0], regd->alpha2[1]); + return true; +} + +static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + + if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n", + regd->alpha2[0], regd->alpha2[1]); + return true; +} + +static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev, + struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + int i; + + if (!regd_is_6ghz_blocked(rtwdev) && + !regd_is_6ghz_not_applicable(rtwdev)) + return; + + sband = wiphy->bands[NL80211_BAND_6GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) + sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; +} + +static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + struct rtw89_tas_info *tas = &rtwdev->tas; + u8 tas_country; + + if (!tas->enable) + return; + + if (memcmp("US", regd->alpha2, 2) == 0) + tas_country = RTW89_ACPI_CONF_TAS_US; + else if (memcmp("CA", regd->alpha2, 2) == 0) + tas_country = RTW89_ACPI_CONF_TAS_CA; + else if (memcmp("KR", regd->alpha2, 2) == 0) + tas_country = RTW89_ACPI_CONF_TAS_KR; + else + tas_country = RTW89_ACPI_CONF_TAS_OTHERS; + + tas->block_regd = !(tas->enabled_countries & tas_country && + test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap)); +} + +static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_regd *regd = regulatory->regd; + + if (!chip->support_ant_gain) + return; + + ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap); +} + +static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, + struct wiphy *wiphy, + struct regulatory_request *request) +{ + rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2); + /* This notification might be set from the system of distros, + * and it does not expect the regulatory will be modified by + * connecting to an AP (i.e. country ie). + */ + if (request->initiator == NL80211_REGDOM_SET_BY_USER && + !rtw89_regd_is_ww(rtwdev->regulatory.regd)) + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; + else + wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; +} + +static +void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw89_dev *rtwdev = hw->priv; + + wiphy_lock(wiphy); + rtw89_leave_ps_mode(rtwdev); + + if (rtwdev->regulatory.programmed) + goto policy; + + rtw89_regd_notifier_apply(rtwdev, wiphy, request); + rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, + "get from initiator %d, alpha2", + request->initiator); + +policy: + rtw89_regd_apply_policy_unii4(rtwdev, wiphy); + rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); + rtw89_regd_apply_policy_tas(rtwdev); + rtw89_regd_apply_policy_ant_gain(rtwdev); + + rtw89_core_set_chip_txpwr(rtwdev); + + wiphy_unlock(wiphy); +} + +/* Maximum Transmit Power field (@raw) can be EIRP or PSD. + * Both units are 0.5 dB-based. Return a constraint in dB. + */ +static s8 tpe_get_constraint(s8 raw) +{ + const u8 hw_deviation = 3; /* unit: 0.5 dB */ + const u8 antenna_gain = 10; /* unit: 0.5 dB */ + const u8 array_gain = 6; /* unit: 0.5 dB */ + const u8 offset = hw_deviation + antenna_gain + array_gain; + + return (raw - offset) / 2; +} + +static void tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe *tpe, s8 cstr) +{ + if (tpe->valid) { + tpe->constraint = min(tpe->constraint, cstr); + return; + } + + tpe->constraint = cstr; + tpe->valid = true; +} + +static void tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe *tpe, + const struct ieee80211_parsed_tpe_eirp *eirp) +{ + unsigned int i; + s8 cstr; + + if (!eirp->valid) + return; + + for (i = 0; i < eirp->count; i++) { + cstr = tpe_get_constraint(eirp->power[i]); + tpe_intersect_constraint(tpe, cstr); + } +} + +static s8 tpe_convert_psd_to_eirp(s8 psd) +{ + static const unsigned int mlog20 = 1301; + + return psd + 10 * mlog20 / 1000; +} + +static void tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe *tpe, + const struct ieee80211_parsed_tpe_psd *psd) +{ + unsigned int i; + s8 cstr_psd; + s8 cstr; + + if (!psd->valid) + return; + + for (i = 0; i < psd->count; i++) { + cstr_psd = tpe_get_constraint(psd->power[i]); + cstr = tpe_convert_psd_to_eirp(cstr_psd); + tpe_intersect_constraint(tpe, cstr); + } +} + +static void rtw89_calculate_tpe(struct rtw89_dev *rtwdev, + struct rtw89_reg_6ghz_tpe *result_tpe, + const struct ieee80211_parsed_tpe *parsed_tpe) +{ + static const u8 category = IEEE80211_TPE_CAT_6GHZ_DEFAULT; + + tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_local[category]); + tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_reg_client[category]); + tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_local[category]); + tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_reg_client[category]); +} + +static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + struct rtw89_reg_6ghz_tpe new = {}; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + bool changed = false; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + const struct rtw89_reg_6ghz_tpe *tmp; + const struct rtw89_chan *chan; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->band_type != RTW89_BAND_6G) + continue; + + tmp = &rtwvif_link->reg_6ghz_tpe; + if (!tmp->valid) + continue; + + tpe_intersect_constraint(&new, tmp->constraint); + } + } + + if (memcmp(®ulatory->reg_6ghz_tpe, &new, + sizeof(regulatory->reg_6ghz_tpe)) != 0) + changed = true; + + if (changed) { + if (new.valid) + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "recalc 6 GHz reg TPE to %d dBm\n", + new.constraint); + else + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "recalc 6 GHz reg TPE to none\n"); + + regulatory->reg_6ghz_tpe = new; + } + + return changed; +} + +static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool active, + unsigned int *changed) +{ + struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe; + struct ieee80211_bss_conf *bss_conf; + + memset(tpe, 0, sizeof(*tpe)); + + if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD) + goto bottom; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe); + + rcu_read_unlock(); + + if (!tpe->valid) + goto bottom; + + if (tpe->constraint < RTW89_MIN_VALID_POWER_CONSTRAINT) { + rtw89_err(rtwdev, + "%s: constraint %d dBm is less than min valid val\n", + __func__, tpe->constraint); + + tpe->valid = false; + return -EINVAL; + } + +bottom: + *changed += __rtw89_reg_6ghz_tpe_recalc(rtwdev); + return 0; +} + +static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + enum rtw89_reg_6ghz_power sel; + const struct rtw89_chan *chan; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; + int count = 0; + u8 index; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->band_type != RTW89_BAND_6G) + continue; + + if (count != 0 && rtwvif_link->reg_6ghz_power == sel) + continue; + + sel = rtwvif_link->reg_6ghz_power; + count++; + } + } + + if (count != 1) + sel = RTW89_REG_6GHZ_POWER_DFLT; + + if (sel == RTW89_REG_6GHZ_POWER_STD) { + index = rtw89_regd_get_index(rtwdev, regd); + if (index == RTW89_REGD_MAX_COUNTRY_NUM || + test_bit(index, regulatory->block_6ghz_sp)) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "%c%c 6 GHz SP is blocked by policy\n", + regd->alpha2[0], regd->alpha2[1]); + sel = RTW89_REG_6GHZ_POWER_DFLT; + } + } + + if (regulatory->reg_6ghz_power == sel) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "recalc 6 GHz reg power type to %d\n", sel); + + regulatory->reg_6ghz_power = sel; + return true; +} + +static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool active, + unsigned int *changed) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + bool blocked[NUM_OF_RTW89_REG_6GHZ_POWER] = {}; + u8 index = rtw89_regd_get_index(rtwdev, regd); + struct ieee80211_bss_conf *bss_conf; + bool dflt = false; + + if (index == RTW89_REGD_MAX_COUNTRY_NUM || + test_bit(index, regulatory->block_6ghz_vlp)) + blocked[RTW89_REG_6GHZ_POWER_VLP] = true; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (active) { + switch (bss_conf->power_type) { + case IEEE80211_REG_VLP_AP: + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; + break; + case IEEE80211_REG_LPI_AP: + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI; + break; + case IEEE80211_REG_SP_AP: + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD; + break; + default: + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + dflt = true; + break; + } + } else { + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + dflt = true; + } + + rcu_read_unlock(); + + if (!dflt && blocked[rtwvif_link->reg_6ghz_power]) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "%c%c 6 GHz power type-%u is blocked by policy\n", + regd->alpha2[0], regd->alpha2[1], + rtwvif_link->reg_6ghz_power); + return -EINVAL; + } + + *changed += __rtw89_reg_6ghz_power_recalc(rtwdev); + return 0; +} + +int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, + bool active) +{ + unsigned int changed = 0; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + /* The result of reg_6ghz_tpe may depend on reg_6ghz_power type, + * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc(). + */ + + ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed); + if (ret) + return ret; + + ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed); + if (ret) + return ret; + + if (changed) + rtw89_core_set_chip_txpwr(rtwdev); + + return 0; +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c new file mode 100644 index 000000000..db37ad665 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -0,0 +1,2740 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#include "coex.h" +#include "efuse.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8851b.h" +#include "rtw8851b_rfk.h" +#include "rtw8851b_rfk_table.h" +#include "rtw8851b_table.h" +#include "txrx.h" +#include "util.h" + +#define RTW8851B_FW_FORMAT_MAX 1 +#define RTW8851B_FW_BASENAME "rtw89/rtw8851b_fw" +#define RTW8851B_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8851B_FW_BASENAME, RTW8851B_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8851b_hfc_chcfg_pcie[] = { + {5, 343, grp_0}, /* ACH 0 */ + {5, 343, grp_0}, /* ACH 1 */ + {5, 343, grp_0}, /* ACH 2 */ + {5, 343, grp_0}, /* ACH 3 */ + {0, 0, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {0, 0, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {4, 344, grp_0}, /* B0MGQ */ + {4, 344, grp_0}, /* B0HIQ */ + {0, 0, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8851b_hfc_pubcfg_pcie = { + 448, /* Group 0 */ + 0, /* Group 1 */ + 448, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8851b_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8851b_hfc_chcfg_pcie, &rtw8851b_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8851b_hfc_chcfg_usb[] = { + {18, 210, grp_0}, /* ACH 0 */ + {18, 210, grp_0}, /* ACH 1 */ + {18, 210, grp_0}, /* ACH 2 */ + {18, 210, grp_0}, /* ACH 3 */ + {0, 0, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {0, 0, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {18, 210, grp_0}, /* B0MGQ */ + {18, 210, grp_0}, /* B0HIQ */ + {0, 0, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8851b_hfc_pubcfg_usb = { + 210, /* Group 0 */ + 0, /* Group 1 */ + 210, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_prec_cfg rtw8851b_hfc_preccfg_usb = { + 9, /* CH 0-11 pre-cost */ + 32, /* H2C pre-cost */ + 64, /* WP CH 0-7 pre-cost */ + 24, /* WP CH 8-11 pre-cost */ + 1, /* CH 0-11 full condition */ + 1, /* H2C full condition */ + 1, /* WP CH 0-7 full condition */ + 1, /* WP CH 8-11 full condition */ +}; + +static const struct rtw89_hfc_param_ini rtw8851b_hfc_param_ini_usb[] = { + [RTW89_QTA_SCC] = {rtw8851b_hfc_chcfg_usb, &rtw8851b_hfc_pubcfg_usb, + &rtw8851b_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, + &rtw8851b_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8851b_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, + &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, + &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, + &rtw89_mac_size.ple_qt58}, + [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size6, + &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, + &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, + &rtw89_mac_size.ple_qt_51b_wow}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, + &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8851b_dle_mem_usb2[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size30, + &rtw89_mac_size.ple_size27, &rtw89_mac_size.wde_qt30, + &rtw89_mac_size.wde_qt30, &rtw89_mac_size.ple_qt61, + &rtw89_mac_size.ple_qt62}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, + &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8851b_dle_mem_usb3[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size30, + &rtw89_mac_size.ple_size31, &rtw89_mac_size.wde_qt30, + &rtw89_mac_size.wde_qt30, &rtw89_mac_size.ple_qt27, + &rtw89_mac_size.ple_qt28}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, + &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_reg3_def rtw8851b_btc_preagc_en_defs[] = { + {0x46D0, GENMASK(1, 0), 0x3}, + {0x4AD4, GENMASK(31, 0), 0xf}, + {0x4688, GENMASK(23, 16), 0x80}, + {0x4688, GENMASK(31, 24), 0x80}, + {0x4694, GENMASK(7, 0), 0x80}, + {0x4694, GENMASK(15, 8), 0x80}, + {0x4AE4, GENMASK(11, 6), 0x34}, + {0x4AE4, GENMASK(17, 12), 0x0}, + {0x469C, GENMASK(31, 26), 0x34}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8851b_btc_preagc_en_defs); + +static const struct rtw89_reg3_def rtw8851b_btc_preagc_dis_defs[] = { + {0x46D0, GENMASK(1, 0), 0x0}, + {0x4AD4, GENMASK(31, 0), 0x60}, + {0x4688, GENMASK(23, 16), 0x10}, + {0x4690, GENMASK(31, 24), 0x2a}, + {0x4694, GENMASK(15, 8), 0x2a}, + {0x4AE4, GENMASK(11, 6), 0x26}, + {0x4AE4, GENMASK(17, 12), 0x1e}, + {0x469C, GENMASK(31, 26), 0x26}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8851b_btc_preagc_dis_defs); + +static const u32 rtw8851b_h2c_regs[RTW89_H2CREG_MAX] = { + R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, + R_AX_H2CREG_DATA3 +}; + +static const u32 rtw8851b_c2h_regs[RTW89_C2HREG_MAX] = { + R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, + R_AX_C2HREG_DATA3 +}; + +static const u32 rtw8851b_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3, +}; + +static const struct rtw89_page_regs rtw8851b_page_regs = { + .hci_fc_ctrl = R_AX_HCI_FC_CTRL, + .ch_page_ctrl = R_AX_CH_PAGE_CTRL, + .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, + .ach_page_info = R_AX_ACH0_PAGE_INFO, + .pub_page_info3 = R_AX_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, + .pub_page_info1 = R_AX_PUB_PAGE_INFO1, + .pub_page_info2 = R_AX_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, + .wp_page_info1 = R_AX_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_def rtw8851b_dcfo_comp = { + R_DCFO_COMP_S0_V2, B_DCFO_COMP_S0_MSK_V2 +}; + +static const struct rtw89_imr_info rtw8851b_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET, + .wsec_imr_reg = R_AX_SEC_DEBUG, + .wsec_imr_set = B_AX_IMR_ERROR, + .mpdu_tx_imr_set = 0, + .mpdu_rx_imr_set = 0, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, + .wde_imr_clr = B_AX_WDE_IMR_CLR, + .wde_imr_set = B_AX_WDE_IMR_SET, + .ple_imr_clr = B_AX_PLE_IMR_CLR, + .ple_imr_set = B_AX_PLE_IMR_SET, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, + .other_disp_imr_set = 0, + .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, + .bbrpt_err_imr_set = 0, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL, + .ptcl_imr_set = B_AX_PTCL_IMR_SET, + .cdma_imr_0_reg = R_AX_DLE_CTRL, + .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, + .cdma_imr_0_set = B_AX_DLE_IMR_SET, + .cdma_imr_1_reg = 0, + .cdma_imr_1_clr = 0, + .cdma_imr_1_set = 0, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, + .phy_intf_imr_clr = 0, + .phy_intf_imr_set = 0, + .rmac_imr_reg = R_AX_RMAC_ERR_ISR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR, + .rmac_imr_set = B_AX_RMAC_IMR_SET, + .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR, + .tmac_imr_set = B_AX_TMAC_IMR_SET, +}; + +static const struct rtw89_xtal_info rtw8851b_xtal_info = { + .xcap_reg = R_AX_XTAL_ON_CTRL3, + .sc_xo_mask = B_AX_XTAL_SC_XO_A_BLOCK_MASK, + .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, +}; + +static const struct rtw89_rrsr_cfgs rtw8851b_rrsr_cfgs = { + .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8851b_rfkill_regs = { + .pinmux = {R_AX_GPIO8_15_FUNC_SEL, + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_AX_GPIO_EXT_CTRL + 2, + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8851b_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD_V1, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, + .bmode_pd_reg = R_BMODE_PDTH_EN_V1, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, + .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, + .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, + .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8851b_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL_V1, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_EDCCA_LVL_V1, + .ppdu_mask = B_EDCCA_LVL_MSK3, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, +}; + +static const struct rtw89_pmac_regs rtw8851b_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT, B_SIG_GG_CNT}, + .cck_spoofing = {R_SPOOF_CNT, B_SPOOF_CNT}, + .cck_brk = {}, + .brk = {R_CNT_BRK, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST, B_R1B_RX_RPT_RST}, + .r1b_rr_sel = {R_R1B_RR_SEL, B_R1B_RR_SEL}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = 0, + .eht_crc_ok_mask = 0, + .eht_crc_err_mask = 0, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8851b_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8851b_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8851b_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4738), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4688), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4694), +}; + +static const u8 rtw89_btc_8851b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; +static const u8 rtw89_btc_8851b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; + +static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + u8 val8; + int ret; + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | + B_AX_AFSM_PCIE_SUS_EN); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, + XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, + XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, + XTAL_SI_PON_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, + XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_DRV, 0, XTAL_SI_DRV_LATCH); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + + fsleep(1000); + + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_set(rtwdev, R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN, + B_AX_GPIO10_PULL_LOW_EN | B_AX_GPIO16_PULL_LOW_EN_V1); + + if (rtwdev->hal.cv == CHIP_CAV) { + ret = rtw89_read_efuse_ver(rtwdev, &val8); + if (!ret) + rtwdev->hal.cv = val8; + } + + rtw89_write32_clr(rtwdev, R_AX_WLAN_XTAL_SI_CONFIG, + B_AX_XTAL_SI_ADDR_NOT_CHK); + if (rtwdev->hal.cv != CHIP_CAV) { + rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL1, B_AX_FPWMDELAY); + rtw89_write32_set(rtwdev, R_AX_SPSANA_ON_CTRL1, B_AX_FPWMDELAY); + } + + rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | + B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | + B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | + B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | + B_AX_DMACREG_GCKEN); + rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, + B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | + B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | + B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN | + B_AX_RMAC_EN); + + rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_MASK, + PINMUX_EESK_FUNC_SEL_BT_LOG); + + return 0; +} + +static void rtw8851b_patch_swr_pfm2pwm(struct rtw89_dev *rtwdev) +{ + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_PWMM_DSWR); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_ASWRM); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_LPSOP_DSWRM); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_LPSOP_ASWRM); +} + +static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, + XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, + XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_WLAN_XTAL_SI_CONFIG, + B_AX_XTAL_SI_ADDR_NOT_CHK); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR); + + if (rtwdev->hal.cv == CHIP_CAV) { + rtw8851b_patch_swr_pfm2pwm(rtwdev); + } else { + rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL1, B_AX_FPWMDELAY); + rtw89_write32_set(rtwdev, R_AX_SPSANA_ON_CTRL1, B_AX_FPWMDELAY); + } + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + } else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) { + val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL); + val32 &= ~B_AX_AFSM_PCIE_SUS_EN; + val32 |= B_AX_AFSM_WLSUS_EN; + rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32); + } + + return 0; +} + +static void rtw8851b_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8851b_efuse *map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + struct rtw8851b_tssi_offset *ofst[] = {&map->path_a_tssi}; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, + sizeof(ofst[i]->cck_tssi)); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + sizeof(ofst[i]->bw40_tssi)); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + } +} + +static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) +{ + if (high) + *high = sign_extend32(u8_get_bits(data, GENMASK(7, 4)), 3); + if (low) + *low = sign_extend32(u8_get_bits(data, GENMASK(3, 0)), 3); + + return data != 0xff; +} + +static void rtw8851b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8851b_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + bool valid = false; + + valid |= _decode_efuse_gain(map->rx_gain_2g_cck, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], + NULL); + valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], + NULL); + valid |= _decode_efuse_gain(map->rx_gain_5g_low, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], + NULL); + valid |= _decode_efuse_gain(map->rx_gain_5g_mid, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], + NULL); + valid |= _decode_efuse_gain(map->rx_gain_5g_high, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], + NULL); + + gain->offset_valid = valid; +} + +static int rtw8851b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw8851b_efuse *map; + + map = (struct rtw8851b_efuse *)log_map; + + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + rtw8851b_efuse_parsing_tssi(rtwdev, map); + rtw8851b_efuse_parsing_gain_offset(rtwdev, map); + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; + case RTW89_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + break; + default: + return -EOPNOTSUPP; + } + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + + return 0; +} + +static void rtw8851b_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + static const u32 tssi_trim_addr[RF_PATH_NUM_8851B] = {0x5D6}; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = false; + u32 ofst; + u8 i, j; + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { + /* addrs are in decreasing order */ + ofst = tssi_trim_addr[i] - addr - j; + tssi->tssi_trim[i][j] = phycap_map[ofst]; + + if (phycap_map[ofst] != 0xff) + pg = true; + } + } + + if (!pg) { + memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM] no PG, set all trim info to 0\n"); + } + + for (i = 0; i < RF_PATH_NUM_8851B; i++) + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", + i, j, tssi->tssi_trim[i][j], + tssi_trim_addr[i] - j); +} + +static void rtw8851b_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 thm_trim_addr[RF_PATH_NUM_8851B] = {0x5DF}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", + i, info->thermal_trim[i]); + + if (info->thermal_trim[i] != 0xff) + info->pg_thermal_trim = true; + } +} + +static void rtw8851b_thermal_trim(struct rtw89_dev *rtwdev) +{ +#define __thm_setting(raw) \ +({ \ + u8 __v = (raw); \ + ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ +}) + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 i, val; + + if (!info->pg_thermal_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + val = __thm_setting(info->thermal_trim[i]); + rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", + i, val); + } +#undef __thm_setting +} + +static void rtw8851b_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 pabias_trim_addr[] = {0x5DE}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + + if (info->pa_bias_trim[i] != 0xff) + info->pg_pa_bias_trim = true; + } +} + +static void rtw8851b_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8851B; i++) { + pabias_2g = u8_get_bits(info->pa_bias_trim[i], GENMASK(3, 0)); + pabias_5g = u8_get_bits(info->pa_bias_trim[i], GENMASK(7, 4)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); + } +} + +static void rtw8851b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = { + {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8}, + }; + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + u32 phycap_addr = rtwdev->chip->phycap_addr; + bool valid = false; + int path, i; + u8 data; + + for (path = 0; path < BB_PATH_NUM_8851B; path++) + for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) { + if (comp_addrs[path][i] == 0) + continue; + + data = phycap_map[comp_addrs[path][i] - phycap_addr]; + valid |= _decode_efuse_gain(data, NULL, + &gain->comp[path][i]); + } + + gain->comp_valid = valid; +} + +static void rtw8851b_phycap_parsing_adc_td(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + u32 phycap_addr = rtwdev->chip->phycap_addr; + struct rtw89_efuse *efuse = &rtwdev->efuse; + const u32 addr_adc_td = 0x5AF; + + efuse->adc_td = phycap_map[addr_adc_td - phycap_addr] & GENMASK(4, 0); +} + +static int rtw8851b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8851b_phycap_parsing_tssi(rtwdev, phycap_map); + rtw8851b_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8851b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + rtw8851b_phycap_parsing_gain_comp(rtwdev, phycap_map); + rtw8851b_phycap_parsing_adc_td(rtwdev, phycap_map); + + return 0; +} + +static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv, + u8 src_sel) +{ + u32 addr, mask; + + if (gpio_idx >= 32) + return; + + /* 2 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 2 bits */ + addr = R_RFE_SEL0_A2 + (gpio_idx / 16) * sizeof(u32); + mask = B_RFE_SEL0_MASK << (gpio_idx % 16) * 2; + + rtw89_phy_write32_mask(rtwdev, addr, mask, RF_PATH_A); + rtw89_phy_write32_mask(rtwdev, R_RFE_INV0, BIT(gpio_idx), inv); + + /* 4 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 4 bits */ + addr = R_RFE_SEL0_BASE + (gpio_idx / 8) * sizeof(u32); + mask = B_RFE_SEL0_SRC_MASK << (gpio_idx % 8) * 4; + + rtw89_phy_write32_mask(rtwdev, addr, mask, src_sel); +} + +static void rtw8851b_set_mac_gpio(struct rtw89_dev *rtwdev, u8 func) +{ + static const struct rtw89_reg3_def func16 = { + R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO16_FUNC_SEL_MASK, BIT(3) + }; + static const struct rtw89_reg3_def func17 = { + R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO17_FUNC_SEL_MASK, BIT(7) >> 4, + }; + const struct rtw89_reg3_def *def; + + switch (func) { + case 16: + def = &func16; + break; + case 17: + def = &func17; + break; + default: + rtw89_warn(rtwdev, "undefined gpio func %d\n", func); + return; + } + + rtw89_write8_mask(rtwdev, def->addr, def->mask, def->data); +} + +static void rtw8851b_rfe_gpio(struct rtw89_dev *rtwdev) +{ + u8 rfe_type = rtwdev->efuse.rfe_type; + + if (rfe_type > 50) + return; + + if (rfe_type % 3 == 2) { + rtw8851b_set_bb_gpio(rtwdev, 16, true, RFE_SEL0_SRC_ANTSEL_0); + rtw8851b_set_bb_gpio(rtwdev, 17, false, RFE_SEL0_SRC_ANTSEL_0); + + rtw8851b_set_mac_gpio(rtwdev, 16); + rtw8851b_set_mac_gpio(rtwdev, 17); + } +} + +static void rtw8851b_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8851b_thermal_trim(rtwdev); + rtw8851b_pa_bias_trim(rtwdev); +} + +static void rtw8851b_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx); + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx); + u8 txsc20 = 0, txsc40 = 0; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); + rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); + rtw89_write32(rtwdev, sub_carr, txsc20); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); + rtw89_write32(rtwdev, sub_carr, 0); + break; + default: + break; + } + + if (chan->channel > 14) { + rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE); + rtw89_write8_set(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); + } else { + rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE); + rtw89_write8_clr(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); + } +} + +static const u32 rtw8851b_sco_barker_threshold[14] = { + 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, + 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 +}; + +static const u32 rtw8851b_sco_cck_threshold[14] = { + 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, + 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed +}; + +static void rtw8851b_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch) +{ + u8 ch_element = primary_ch - 1; + + rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, + rtw8851b_sco_barker_threshold[ch_element]); + rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, + rtw8851b_sco_cck_threshold[ch_element]); +} + +static u8 rtw8851b_sco_mapping(u8 central_ch) +{ + if (central_ch == 1) + return 109; + else if (central_ch >= 2 && central_ch <= 6) + return 108; + else if (central_ch >= 7 && central_ch <= 10) + return 107; + else if (central_ch >= 11 && central_ch <= 14) + return 106; + else if (central_ch == 36 || central_ch == 38) + return 51; + else if (central_ch >= 40 && central_ch <= 58) + return 50; + else if (central_ch >= 60 && central_ch <= 64) + return 49; + else if (central_ch == 100 || central_ch == 102) + return 48; + else if (central_ch >= 104 && central_ch <= 126) + return 47; + else if (central_ch >= 128 && central_ch <= 151) + return 46; + else if (central_ch >= 153 && central_ch <= 177) + return 45; + else + return 0; +} + +struct rtw8851b_bb_gain { + u32 gain_g[BB_PATH_NUM_8851B]; + u32 gain_a[BB_PATH_NUM_8851B]; + u32 gain_mask; +}; + +static const struct rtw8851b_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4678}, .gain_a = {0x45DC}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4678}, .gain_a = {0x45DC}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x467C}, .gain_a = {0x4660}, + .gain_mask = 0x000000ff }, + { .gain_g = {0x467C}, .gain_a = {0x4660}, + .gain_mask = 0x0000ff00 }, + { .gain_g = {0x467C}, .gain_a = {0x4660}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x467C}, .gain_a = {0x4660}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x4680}, .gain_a = {0x4664}, + .gain_mask = 0x000000ff }, +}; + +static const struct rtw8851b_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x4680}, .gain_a = {0x4664}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4680}, .gain_a = {0x4664}, + .gain_mask = 0xff000000 }, +}; + +static void rtw8851b_set_gain_error(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_rf_path path) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 gain_band = rtw89_subband_to_bb_gain_band(subband); + s32 val; + u32 reg; + u32 mask; + int i; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_lna[i].gain_g[path]; + else + reg = bb_gain_lna[i].gain_a[path]; + + mask = bb_gain_lna[i].gain_mask; + val = gain->lna_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_tia[i].gain_g[path]; + else + reg = bb_gain_tia[i].gain_a[path]; + + mask = bb_gain_tia[i].gain_mask; + val = gain->tia_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } +} + +static void rtw8851b_set_gain_offset(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_phy_idx phy_idx) +{ + static const u32 rssi_ofst_addr[] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1}; + static const u32 gain_err_addr[] = {R_P0_AGC_RSVD}; + struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset gain_ofdm_band; + s32 offset_ofdm, offset_cck; + s32 offset_a; + s32 tmp; + u8 path; + + if (!efuse_gain->comp_valid) + goto next; + + for (path = RF_PATH_A; path < BB_PATH_NUM_8851B; path++) { + tmp = efuse_gain->comp[path][subband]; + tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp); + } + +next: + if (!efuse_gain->offset_valid) + return; + + gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband); + + offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; + + tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp); + + offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; + offset_cck = -efuse_gain->offset[RF_PATH_A][0]; + + tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0]; + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); + + tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0]; + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); + + if (subband == RTW89_CH_2G) { + tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1); + tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1); + rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST, + B_RX_RPL_OFST_CCK_MASK, tmp); + } +} + +static +void rtw8851b_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 band = rtw89_subband_to_bb_gain_band(subband); + u32 val; + + val = u32_encode_bits(gain->rpl_ofst_20[band][RF_PATH_A], B_P0_RPL1_20_MASK) | + u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][0], B_P0_RPL1_40_MASK) | + u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][1], B_P0_RPL1_41_MASK); + val >>= B_P0_RPL1_SHIFT; + rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val); + rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val); + + val = u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][2], B_P0_RTL2_42_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][0], B_P0_RTL2_80_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][1], B_P0_RTL2_81_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][10], B_P0_RTL2_8A_MASK); + rtw89_phy_write32(rtwdev, R_P0_RPL2, val); + rtw89_phy_write32(rtwdev, R_P1_RPL2, val); + + val = u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][2], B_P0_RTL3_82_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][3], B_P0_RTL3_83_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][4], B_P0_RTL3_84_MASK) | + u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][9], B_P0_RTL3_89_MASK); + rtw89_phy_write32(rtwdev, R_P0_RPL3, val); + rtw89_phy_write32(rtwdev, R_P1_RPL3, val); +} + +static void rtw8851b_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 subband = chan->subband_type; + u8 central_ch = chan->channel; + bool is_2g = central_ch <= 14; + u8 sco_comp; + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx); + /* SCO compensate FC setting */ + sco_comp = rtw8851b_sco_mapping(central_ch); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx); + + if (chan->band_type == RTW89_BAND_6G) + return; + + /* CCK parameters */ + if (central_ch == 14) { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5); + } + + rtw8851b_set_gain_error(rtwdev, subband, RF_PATH_A); + rtw8851b_set_gain_offset(rtwdev, subband, phy_idx); + rtw8851b_set_rxsc_rpl_comp(rtwdev, subband); +} + +static void rtw8851b_bw_setting(struct rtw89_dev *rtwdev, u8 bw) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + u8 adc_bw_sel; + + switch (efuse->adc_td) { + default: + case 0x19: + adc_bw_sel = 0x4; + break; + case 0x11: + adc_bw_sel = 0x5; + break; + case 0x9: + adc_bw_sel = 0x3; + break; + } + + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, adc_bw_sel); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_MUL, 0xf); + rtw89_phy_write32_mask(rtwdev, R_ADCMOD, B_ADCMOD_LP, 0xa); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_RC, 0x3); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1); + rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1); + rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2); + rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2); + rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + } +} + +static void rtw8851b_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, + pri_ch, phy_idx); + /* CCK primary channel */ + if (pri_ch == RTW89_SC_20_UPPER) + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); + + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, + pri_ch, phy_idx); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, + pri_ch); + } + + rtw8851b_bw_setting(rtwdev, bw); +} + +static void rtw8851b_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en) +{ + if (cck_en) { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); + rtw89_phy_write32_mask(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); + rtw89_phy_write32_mask(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); + } +} + +static u32 rtw8851b_spur_freq(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u8 center_chan = chan->channel; + + switch (chan->band_type) { + case RTW89_BAND_5G: + if (center_chan == 151 || center_chan == 153 || + center_chan == 155 || center_chan == 163) + return 5760; + else if (center_chan == 54 || center_chan == 58) + return 5280; + break; + default: + break; + } + + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8851b_set_csi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u32 spur_freq; + s32 freq_diff, csi_idx, csi_tone_idx; + + spur_freq = rtw8851b_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, + 0, phy_idx); + return; + } + + freq_diff = (spur_freq - chan->freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_V1, B_SEG0CSI_IDX, + csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, 1, phy_idx); +} + +static const struct rtw89_nbi_reg_def rtw8851b_nbi_reg_def = { + .notch1_idx = {0x46E4, 0xFF}, + .notch1_frac_idx = {0x46E4, 0xC00}, + .notch1_en = {0x46E4, 0x1000}, + .notch2_idx = {0x47A4, 0xFF}, + .notch2_frac_idx = {0x47A4, 0xC00}, + .notch2_en = {0x47A4, 0x1000}, +}; + +static void rtw8851b_set_nbi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + const struct rtw89_nbi_reg_def *nbi = &rtw8851b_nbi_reg_def; + s32 nbi_frac_idx, nbi_frac_tone_idx; + s32 nbi_idx, nbi_tone_idx; + bool notch2_chk = false; + u32 spur_freq, fc; + s32 freq_diff; + + spur_freq = rtw8851b_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0); + return; + } + + fc = chan->freq; + if (chan->band_width == RTW89_CHANNEL_WIDTH_160) { + fc = (spur_freq > fc) ? fc + 40 : fc - 40; + if ((fc > spur_freq && + chan->channel < chan->primary_channel) || + (fc < spur_freq && + chan->channel > chan->primary_channel)) + notch2_chk = true; + } + + freq_diff = (spur_freq - fc) * 1000000; + nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, + &nbi_frac_idx); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_20) { + s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); + } else { + u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ? + 128 : 256; + + s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); + } + nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, + CARRIER_SPACING_78_125); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { + rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr, + nbi->notch2_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr, + nbi->notch2_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0); + } else { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr, + nbi->notch1_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr, + nbi->notch1_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0); + } +} + +static void rtw8851b_set_cfr(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) +{ + if (chan->band_type == RTW89_BAND_2G && + chan->band_width == RTW89_CHANNEL_WIDTH_20 && + (chan->channel == 1 || chan->channel == 13)) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, + B_PATH0_TX_CFR_LGC0, 0xf8); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, + B_PATH0_TX_CFR_LGC1, 0x120); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, + B_PATH0_TX_POLAR_CLIPPING_LGC0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, + B_PATH0_TX_POLAR_CLIPPING_LGC1, 0x3); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, + B_PATH0_TX_CFR_LGC0, 0x120); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, + B_PATH0_TX_CFR_LGC1, 0x3ff); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, + B_PATH0_TX_POLAR_CLIPPING_LGC0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, + B_PATH0_TX_POLAR_CLIPPING_LGC1, 0x7); + } +} + +static void rtw8851b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 pri_ch = chan->pri_ch_idx; + bool mask_5m_low; + bool mask_5m_en; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_40: + /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */ + mask_5m_en = true; + mask_5m_low = pri_ch == RTW89_SC_20_LOWER; + break; + case RTW89_CHANNEL_WIDTH_80: + /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ + mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || + pri_ch == RTW89_SC_20_LOWEST; + mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; + break; + default: + mask_5m_en = false; + break; + } + + if (!mask_5m_en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0); + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, + B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx); + return; + } + + if (mask_5m_low) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x5); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x5); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0); + } + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, + B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx); +} + +static void rtw8851b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); +} + +static void rtw8851b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + enum rtw89_phy_idx phy_idx, bool en) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + if (band == RTW89_BAND_2G) + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + } +} + +static void rtw8851b_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x1); + rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw8851b_bb_reset_all(rtwdev, phy_idx); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x3); + rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); +} + +static +void rtw8851b_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 tx_path_en, u8 trsw_tx, + u8 trsw_rx, u8 trsw_a, u8 trsw_b) +{ + u32 mask_ofst = 16; + u32 val; + + if (path != RF_PATH_A) + return; + + mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2; + val = u32_encode_bits(trsw_a, B_P0_TRSW_A) | + u32_encode_bits(trsw_b, B_P0_TRSW_B); + + rtw89_phy_write32_mask(rtwdev, R_P0_TRSW, + (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val); +} + +static void rtw8851b_bb_gpio_init(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_set(rtwdev, R_P0_TRSW, B_P0_TRSW_A); + rtw89_phy_write32_clr(rtwdev, R_P0_TRSW, B_P0_TRSW_X); + rtw89_phy_write32_clr(rtwdev, R_P0_TRSW, B_P0_TRSW_SO_A2); + rtw89_phy_write32(rtwdev, R_RFE_SEL0_BASE, 0x77777777); + rtw89_phy_write32(rtwdev, R_RFE_SEL32_BASE, 0x77777777); + + rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff); + rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0); + + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0); + rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0); +} + +static void rtw8851b_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + for (addr = R_AX_PWR_MACID_LMT_TABLE0; + addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); +} + +static void rtw8851b_bb_sethw(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); + + rtw8851b_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); + rtw8851b_bb_gpio_init(rtwdev); + + rtw89_write32_clr(rtwdev, R_AX_PWR_NORM_FORCE1, B_AX_FORCE_NTX_VALUE); + rtw89_write32_set(rtwdev, R_AX_PWR_NORM_FORCE1, B_AX_FORCE_NTX_EN); + + /* read these registers after loading BB parameters */ + gain->offset_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK); + gain->rssi_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); +} + +static void rtw8851b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 band = chan->band_type, chan_idx; + bool cck_en = chan->channel <= 14; + u8 pri_ch_idx = chan->pri_ch_idx; + + if (cck_en) + rtw8851b_ctrl_sco_cck(rtwdev, chan->primary_channel); + + rtw8851b_ctrl_ch(rtwdev, chan, phy_idx); + rtw8851b_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); + rtw8851b_ctrl_cck_en(rtwdev, cck_en); + rtw8851b_set_nbi_tone_idx(rtwdev, chan); + rtw8851b_set_csi_tone_idx(rtwdev, chan, phy_idx); + + if (chan->band_type == RTW89_BAND_5G) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); + } + + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); + rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx); + rtw8851b_5m_mask(rtwdev, chan, phy_idx); + rtw8851b_set_cfr(rtwdev, chan); + rtw8851b_bb_reset_all(rtwdev, phy_idx); +} + +static void rtw8851b_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8851b_set_channel_mac(rtwdev, chan, mac_idx); + rtw8851b_set_channel_bb(rtwdev, chan, phy_idx); + rtw8851b_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void rtw8851b_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + if (en) { + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN, 0x1); + } +} + +static void rtw8851b_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, + u8 phy_idx) +{ + rtw8851b_tssi_cont_en(rtwdev, en, RF_PATH_A); +} + +static void rtw8851b_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf); +} + +static void rtw8851b_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw8851b_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); + rtw8851b_adc_en(rtwdev, false); + fsleep(40); + rtw8851b_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + rtw8851b_adc_en(rtwdev, true); + rtw8851b_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); + rtw8851b_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); + } +} + +static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev) +{ + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + rtw8851b_lck_init(rtwdev); + + rtw8851b_dpk_init(rtwdev); + rtw8851b_aack(rtwdev); + rtw8851b_rck(rtwdev); + rtw8851b_dack(rtwdev); + rtw8851b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); +} + +static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + + rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx); + rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8851b_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8851b_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); +} + +static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8851b_tssi_scan(rtwdev, phy_idx, chan); +} + +static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); +} + +static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8851b_dpk_track(rtwdev); + rtw8851b_lck_track(rtwdev); +} + +static u32 rtw8851b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) +{ + const u16 tssi_16dbm_cw = 0x12c; + const u8 base_cw_0db = 0x27; + const s8 ofst_int = 0; + s16 pwr_s10_3; + s16 rf_pwr_cw; + u16 bb_pwr_cw; + u32 pwr_cw; + u32 tssi_ofst_cw; + + pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); + bb_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(2, 0)); + rf_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(8, 3)); + rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); + pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; + + tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", + tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); + + return u32_encode_bits(tssi_ofst_cw, B_DPD_TSSI_CW) | + u32_encode_bits(pwr_cw, B_DPD_PWR_CW) | + u32_encode_bits(ref, B_DPD_REF); +} + +static void rtw8851b_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + static const u32 addr[RF_PATH_NUM_8851B] = {0x5800}; + const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF; + const u8 ofst_ofdm = 0x4; + const u8 ofst_cck = 0x8; + const s16 ref_ofdm = 0; + const s16 ref_cck = 0; + u32 val; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, + B_AX_PWR_REF, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); + val = rtw8851b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); + + for (i = 0; i < RF_PATH_NUM_8851B; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, + phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); + val = rtw8851b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); + + for (i = 0; i < RF_PATH_NUM_8851B; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, + phy_idx); +} + +static void rtw8851b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) +{ +#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2)) +#define __DFIR_CFG_MASK 0xffffffff +#define __DFIR_CFG_NR 8 +#define __DECL_DFIR_PARAM(_name, _val...) \ + static const u32 param_ ## _name[] = {_val}; \ + static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR) + + __DECL_DFIR_PARAM(flat, + 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, + 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5); + __DECL_DFIR_PARAM(sharp, + 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090, + 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5); + __DECL_DFIR_PARAM(sharp_14, + 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, + 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); + u8 ch = chan->channel; + const u32 *param; + u32 addr; + int i; + + if (ch > 14) { + rtw89_warn(rtwdev, + "set tx shape dfir by unknown ch: %d on 2G\n", ch); + return; + } + + if (ch == 14) + param = param_sharp_14; + else + param = tx_shape_idx == 0 ? param_flat : param_sharp; + + for (i = 0; i < __DFIR_CFG_NR; i++) { + addr = __DFIR_CFG_ADDR(i); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]); + rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i], + phy_idx); + } + +#undef __DECL_DFIR_PARAM +#undef __DFIR_CFG_NR +#undef __DFIR_CFG_MASK +#undef __DECL_CFG_ADDR +} + +static void rtw8851b_set_tx_shape(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 band = chan->band_type; + u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK); + u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM); + + if (band == RTW89_BAND_2G) + rtw8851b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); + + rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, + tx_shape_ofdm); +} + +static void rtw8851b_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw8851b_set_tx_shape(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); +} + +static void rtw8851b_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8851b_set_txpwr_ref(rtwdev, phy_idx); +} + +static +void rtw8851b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx) +{ + u32 reg; + + if (pw_ofst < -16 || pw_ofst > 15) { + rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst); + return; + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); + + pw_ofst = max_t(s8, pw_ofst - 3, -16); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); +} + +static int +rtw8851b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + int ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); + if (ret) + return ret; + + rtw8851b_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? + RTW89_MAC_1 : RTW89_MAC_0); + + return 0; +} + +static void rtw8851b_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + + rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8851b_btc_preagc_en_defs_tbl : + &rtw8851b_btc_preagc_dis_defs_tbl); + + if (!en) { + if (chan->band_type == RTW89_BAND_2G) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x20); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x30); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a); + } + } +} + +static void rtw8851b_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + + if (en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x20); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x30); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + if (chan->band_type == RTW89_BAND_2G) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a); + } + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); + } +} + +static void rtw8851b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + u32 rst_mask0; + + if (rx_path == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } + + rtw8851b_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0); + + rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; + if (rx_path == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); + } +} + +static void rtw8851b_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + rtw8851b_bb_ctrl_rx_path(rtwdev, RF_A); + + if (rtwdev->hal.rx_nss == 1) { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); +} + +static u8 rtw8851b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + if (rtwdev->is_tssi_mode[rf_path]) { + u32 addr = R_TSSI_THER + (rf_path << 13); + + return rtw89_phy_read32_mask(rtwdev, addr, B_TSSI_THER); + } + + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); +} + +static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->bt_solo = 0; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + md->ant.isolation = 10; + md->kt_ver_adie = rtwdev->hal.acv; + + if (md->rfe_type == 0) + return; + + /* rfe_type 3*n+1: 1-Ant(shared), + * 3*n+2: 2-Ant+Div(non-shared), + * 3*n+3: 2-Ant+no-Div(non-shared) + */ + md->ant.num = (md->rfe_type % 3 == 1) ? 1 : 2; + /* WL-1ss at S0, btg at s0 (On 1 WL RF) */ + md->ant.single_pos = RF_PATH_A; + md->ant.btg_pos = RF_PATH_A; + md->ant.stream_cnt = 1; + + if (md->ant.num == 1) { + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->wa_type = 1; + md->ant.diversity = 0; + } else { /* ant.num == 2 */ + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_EXTERNAL; + md->wa_type = 0; + if (md->rfe_type % 3 == 2) + md->ant.diversity = 1; + } + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +static +void rtw8851b_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + if (group > BTC_BT_SS_GROUP) + group--; /* Tx-group=1, Rx-group=2 */ + + if (rtwdev->btc.ant_type == BTC_ANT_SHARED) /* 1-Ant */ + group += 3; + + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); +} + +static void rtw8851b_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + static const struct rtw89_mac_ax_coex coex_params = { + .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, + .direction = RTW89_MAC_AX_COEX_INNER, + }; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_module *md = &btc->mdinfo; + u8 path, path_min, path_max; + + /* PTA init */ + rtw89_mac_coex_init(rtwdev, &coex_params); + + /* set WL Tx response = Hi-Pri */ + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); + + /* for 1-Ant && 1-ss case: only 1-path */ + if (md->ant.stream_cnt == 1) { + path_min = md->ant.single_pos; + path_max = path_min; + } else { + path_min = RF_PATH_A; + path_max = RF_PATH_B; + } + + for (path = path_min; path <= path_max; path++) { + /* set rf gnt-debug off */ + rtw89_write_rf(rtwdev, path, RR_WLSEL, RFREG_MASK, 0x0); + + /* set DEBUG_LUT_RFMODE_MASK = 1 to start trx-mask-setup */ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, BIT(17)); + + /* if GNT_WL=0 && BT=SS_group --> WL Tx/Rx = THRU */ + rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_SS_GROUP, 0x5ff); + + /* if GNT_WL=0 && BT=Rx_group --> WL-Rx = THRU + WL-Tx = MASK */ + rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_RX_GROUP, 0x5df); + + /* if GNT_WL = 0 && BT = Tx_group --> + * Shared-Ant && BTG-path:WL mask(0x55f), others:WL THRU(0x5ff) + */ + if (btc->ant_type == BTC_ANT_SHARED && btc->btg_pos == path) + rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x55f); + else + rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x5ff); + + /* set DEBUG_LUT_RFMODE_MASK = 0 to stop trx-mask-setup */ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0); + } + + /* set PTA break table */ + rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); + + /* enable BT counter 0xda40[16,2] = 2b'11 */ + rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); +} + +static +void rtw8851b_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + u32 bitmap; + u32 reg; + + switch (map) { + case BTC_PRI_MASK_TX_RESP: + reg = R_BTC_BT_COEX_MSK_TABLE; + bitmap = B_BTC_PRI_MASK_TX_RESP_V1; + break; + case BTC_PRI_MASK_BEACON: + reg = R_AX_WL_PRI_MSK; + bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; + break; + case BTC_PRI_MASK_RX_CCK: + reg = R_BTC_BT_COEX_MSK_TABLE; + bitmap = B_BTC_PRI_MASK_RXCCK_V1; + break; + default: + return; + } + + if (state) + rtw89_write32_set(rtwdev, reg, bitmap); + else + rtw89_write32_clr(rtwdev, reg, bitmap); +} + +union rtw8851b_btc_wl_txpwr_ctrl { + u32 txpwr_val; + struct { + union { + u16 ctrl_all_time; + struct { + s16 data:9; + u16 rsvd:6; + u16 flag:1; + } all_time; + }; + union { + u16 ctrl_gnt_bt; + struct { + s16 data:9; + u16 rsvd:7; + } gnt_bt; + }; + }; +} __packed; + +static void +rtw8851b_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + union rtw8851b_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; + s32 val; + +#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ +do { \ + u32 _wrt = FIELD_PREP(_msk, _val); \ + BUILD_BUG_ON(!!(_msk & _en)); \ + if (_cond) \ + _wrt |= _en; \ + else \ + _wrt &= ~_en; \ + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ + _msk | _en, _wrt); \ +} while (0) + + switch (arg.ctrl_all_time) { + case 0xffff: + val = 0; + break; + default: + val = arg.all_time.data; + break; + } + + __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, + val, B_AX_FORCE_PWR_BY_RATE_EN, + arg.ctrl_all_time != 0xffff); + + switch (arg.ctrl_gnt_bt) { + case 0xffff: + val = 0; + break; + default: + val = arg.gnt_bt.data; + break; + } + + __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, + B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); + +#undef __write_ctrl +} + +static +s8 rtw8851b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + val = clamp_t(s8, val, -100, 0) + 100; + val = min(val + 6, 100); /* compensate offset */ + + return val; +} + +static +void rtw8851b_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + /* Feature move to firmware */ +} + +static void rtw8851b_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWD1, RFREG_MASK, 0x110); + + /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ + if (state) + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWD0, RFREG_MASK, 0x179c); + else + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWD0, RFREG_MASK, 0x208); + + rtw89_write_rf(rtwdev, btc->btg_pos, RR_LUTWE, RFREG_MASK, 0x0); +} + +#define LNA2_51B_MA 0x700 + +static const struct rtw89_reg2_def btc_8851b_rf_0[] = {{0x2, 0x0}}; +static const struct rtw89_reg2_def btc_8851b_rf_1[] = {{0x2, 0x1}}; + +static void rtw8851b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + /* To improve BT ACI in co-rx + * level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB + * level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB + */ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_reg2_def *rf; + u32 n, i, val; + + switch (level) { + case 0: /* original */ + default: + btc->dm.wl_lna2 = 0; + break; + case 1: /* for FDD free-run */ + btc->dm.wl_lna2 = 0; + break; + case 2: /* for BTG Co-Rx*/ + btc->dm.wl_lna2 = 1; + break; + } + + if (btc->dm.wl_lna2 == 0) { + rf = btc_8851b_rf_0; + n = ARRAY_SIZE(btc_8851b_rf_0); + } else { + rf = btc_8851b_rf_1; + n = ARRAY_SIZE(btc_8851b_rf_1); + } + + for (i = 0; i < n; i++, rf++) { + val = rf->data; + /* bit[10] = 1 if non-shared-ant for 8851b */ + if (btc->ant_type == BTC_ANT_DEDICATED) + val |= 0x4; + + rtw89_write_rf(rtwdev, btc->btg_pos, rf->addr, LNA2_51B_MA, val); + } +} + +static void rtw8851b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u16 chan = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan == 0) + return; + + rtw89_decode_chan_idx(rtwdev, chan, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void rtw8851b_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + u8 *rx_power = phy_ppdu->rssi; + + if (!status->signal) + status->signal = RTW89_RSSI_RAW_TO_DBM(rx_power[RF_PATH_A]); + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8851b_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +static int rtw8851b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC7, + FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC7, + FULL_BIT_MASK); + if (ret) + return ret; + + rtw89_write8(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_XYN_CYCLE); + + return 0; +} + +static int rtw8851b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + u8 wl_rfc_s0; + u8 wl_rfc_s1; + int ret; + + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, &wl_rfc_s0); + if (ret) + return ret; + wl_rfc_s0 &= ~XTAL_SI_RF00S_EN; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, wl_rfc_s0, + FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, &wl_rfc_s1); + if (ret) + return ret; + wl_rfc_s1 &= ~XTAL_SI_RF10S_EN; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, wl_rfc_s1, + FULL_BIT_MASK); + return ret; +} + +static const struct rtw89_chip_ops rtw8851b_chip_ops = { + .enable_bb_rf = rtw8851b_mac_enable_bb_rf, + .disable_bb_rf = rtw8851b_mac_disable_bb_rf, + .bb_preinit = NULL, + .bb_postinit = NULL, + .bb_reset = rtw8851b_bb_reset, + .bb_sethw = rtw8851b_bb_sethw, + .read_rf = rtw89_phy_read_rf_v1, + .write_rf = rtw89_phy_write_rf_v1, + .set_channel = rtw8851b_set_channel, + .set_channel_help = rtw8851b_set_channel_help, + .read_efuse = rtw8851b_read_efuse, + .read_phycap = rtw8851b_read_phycap, + .fem_setup = NULL, + .data_setup = NULL, + .rfe_gpio = rtw8851b_rfe_gpio, + .rfk_hw_init = NULL, + .rfk_init = rtw8851b_rfk_init, + .rfk_init_late = NULL, + .rfk_channel = rtw8851b_rfk_channel, + .rfk_band_changed = rtw8851b_rfk_band_changed, + .rfk_scan = rtw8851b_rfk_scan, + .rfk_track = rtw8851b_rfk_track, + .power_trim = rtw8851b_power_trim, + .set_txpwr = rtw8851b_set_txpwr, + .set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8851b_init_txpwr_unit, + .get_thermal = rtw8851b_get_thermal, + .chan_to_rf18_val = NULL, + .ctrl_btg_bt_rx = rtw8851b_ctrl_btg_bt_rx, + .query_ppdu = rtw8851b_query_ppdu, + .convert_rpl_to_rssi = NULL, + .phy_rpt_to_rssi = NULL, + .ctrl_nbtg_bt_tx = rtw8851b_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8851b_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset, + .digital_pwr_comp = NULL, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = rtw8851b_pwr_on_func, + .pwr_off_func = rtw8851b_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc, + .fill_txdesc = rtw89_core_fill_txdesc, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, + .get_ch_dma = {rtw89_core_get_ch_dma, + rtw89_core_get_ch_dma, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, + .mac_cfg_gnt = rtw89_mac_cfg_gnt, + .stop_sch_tx = rtw89_mac_stop_sch_tx, + .resume_sch_tx = rtw89_mac_resume_sch_tx, + .h2c_dctl_sec_cam = NULL, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl, + .h2c_ampdu_cmac_tbl = NULL, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl, + .h2c_punctured_cmac_tbl = NULL, + .h2c_default_dmac_tbl = NULL, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8851b_btc_set_rfe, + .btc_init_cfg = rtw8851b_btc_init_cfg, + .btc_set_wl_pri = rtw8851b_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8851b_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8851b_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8851b_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8851b_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8851b_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8851b = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, +}; +#endif + +const struct rtw89_chip_info rtw8851b_chip_info = { + .chip_id = RTL8851B, + .chip_gen = RTW89_CHIP_AX, + .ops = &rtw8851b_chip_ops, + .mac_def = &rtw89_mac_gen_ax, + .phy_def = &rtw89_phy_gen_ax, + .fw_def = { + .fw_basename = RTW8851B_FW_BASENAME, + .fw_format_max = RTW8851B_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = true, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_RTL8851B | + BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION), + .fw_blacklist = NULL, + .fifo_size = 196608, + .small_fifo_size = true, + .dle_scc_rsvd_size = 98304, + .max_amsdu_limit = 3500, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = true, + .rsvd_ple_ofst = 0x2f800, + .qta_def = { + .hfc_param_ini = {rtw8851b_hfc_param_ini_pcie, + rtw8851b_hfc_param_ini_usb, + rtw8851b_hfc_param_ini_usb, + NULL}, + .dle_mem = {rtw8851b_dle_mem_pcie, + rtw8851b_dle_mem_usb2, + rtw8851b_dle_mem_usb3, + NULL}, + }, + .wde_qempty_acq_grpnum = 4, + .wde_qempty_mgq_grpsel = 4, + .rf_base_addr = {0xe000}, + .thermal_th = {0x32, 0x35}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = &rtw89_8851b_phy_bb_table, + .bb_gain_table = &rtw89_8851b_phy_bb_gain_table, + .rf_table = {&rtw89_8851b_phy_radioa_table,}, + .nctl_table = &rtw89_8851b_phy_nctl_table, + .nctl_post_table = &rtw8851b_nctl_post_defs_tbl, + .dflt_parms = &rtw89_8851b_dflt_parms, + .rfe_parms_conf = rtw89_8851b_rfe_parms_conf, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8851b_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = RTW89_MAX_MAC_ID_NUM, + .support_link_num = 0, + .support_chanctx_num = 0, + .support_rnr = false, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), + .support_unii4 = true, + .support_ant_gain = false, + .support_tas = false, + .support_sar_by_ant = false, + .support_noise = false, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = true, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = true, + .hw_sec_hdr = false, + .hw_mgmt_tx_encrypt = false, + .hw_tkip_crypto = false, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 1, + .tx_nss = 1, + .rx_nss = 1, + .acam_num = 32, + .bcam_num = 20, + .scam_num = 128, + .bacam_num = 2, + .bacam_dynamic_num = 4, + .bacam_ver = RTW89_BACAM_V0, + .addrcam_ver = 0, + .ppdu_max_usr = 4, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, + .limit_efuse_size = 1280, + .dav_phy_efuse_size = 0, + .dav_log_efuse_size = 0, + .efuse_blocks = NULL, + .phycap_addr = 0x580, + .phycap_size = 128, + .para_ver = 0, + .wlcx_desired = 0x06000000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8851b_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8851b_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8851b_mon_reg), + .mon_reg = rtw89_btc_8851b_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8851b_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8851b_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8851b_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8851b_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, + .hci_func_en_addr = R_AX_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_txwd_body), + .txwd_body_size = sizeof(struct rtw89_txwd_body), + .txwd_info_size = sizeof(struct rtw89_txwd_info), + .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8851b_h2c_regs, + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8851b_c2h_regs, + .page_regs = &rtw8851b_page_regs, + .wow_reason_reg = rtw8851b_wow_wakeup_regs, + .cfo_src_fd = true, + .cfo_hw_comp = true, + .dcfo_comp = &rtw8851b_dcfo_comp, + .dcfo_comp_sft = 12, + .nhm_report = NULL, + .nhm_th = NULL, + .imr_info = &rtw8851b_imr_info, + .imr_dmac_table = NULL, + .imr_cmac_table = NULL, + .rrsr_cfgs = &rtw8851b_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0}, + .bss_clr_map_reg = R_BSS_CLR_MAP_V1, + .rfkill_init = &rtw8851b_rfkill_regs, + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, + .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | + BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | + BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), + .edcca_regs = &rtw8851b_edcca_regs, + .pmac_regs = &rtw8851b_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8851b, +#endif + .xtal_info = &rtw8851b_xtal_info, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8851b_chip_info); + +MODULE_FIRMWARE(RTW8851B_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851B driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.h b/drivers/net/wireless/realtek/rtw89/rtw8851b.h new file mode 100644 index 000000000..1a5c52654 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#ifndef __RTW89_8851B_H__ +#define __RTW89_8851B_H__ + +#include "core.h" + +#define RF_PATH_NUM_8851B 1 +#define BB_PATH_NUM_8851B 1 + +struct rtw8851bu_efuse { + u8 rsvd[0x88]; + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8851be_efuse { + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8851b_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; +} __packed; + +struct rtw8851b_efuse { + u8 rsvd[0x210]; + struct rtw8851b_tssi_offset path_a_tssi; + u8 rsvd1[136]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd2; + u8 iqk_lck; + u8 rsvd3[8]; + u8 eeprom_version; + u8 customer_id; + u8 tx_bb_swing_2g; + u8 tx_bb_swing_5g; + u8 tx_cali_pwr_trk_mode; + u8 trx_path_selection; + u8 rfe_type; + u8 country_code[2]; + u8 rsvd4[3]; + u8 path_a_therm; + u8 rsvd5[3]; + u8 rx_gain_2g_ofdm; + u8 rsvd6; + u8 rx_gain_2g_cck; + u8 rsvd7; + u8 rx_gain_5g_low; + u8 rsvd8; + u8 rx_gain_5g_mid; + u8 rsvd9; + u8 rx_gain_5g_high; + u8 rsvd10[35]; + u8 path_a_cck_pwr_idx[6]; + u8 path_a_bw40_1tx_pwr_idx[5]; + u8 path_a_ofdm_1tx_pwr_idx_diff:4; + u8 path_a_bw20_1tx_pwr_idx_diff:4; + u8 path_a_bw20_2tx_pwr_idx_diff:4; + u8 path_a_bw40_2tx_pwr_idx_diff:4; + u8 path_a_cck_2tx_pwr_idx_diff:4; + u8 path_a_ofdm_2tx_pwr_idx_diff:4; + u8 rsvd11[0xf2]; + union { + struct rtw8851bu_efuse u; + struct rtw8851be_efuse e; + }; +} __packed; + +extern const struct rtw89_chip_info rtw8851b_chip_info; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c new file mode 100644 index 000000000..c63f0e636 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c @@ -0,0 +1,3788 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#include "coex.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8851b.h" +#include "rtw8851b_rfk.h" +#include "rtw8851b_rfk_table.h" +#include "rtw8851b_table.h" + +#define DPK_VER_8851B 0x11 +#define DPK_KIP_REG_NUM_8851B 8 +#define DPK_RF_REG_NUM_8851B 4 +#define DPK_KSET_NUM 4 +#define RTW8851B_RXK_GROUP_NR 4 +#define RTW8851B_RXK_GROUP_IDX_NR 4 +#define RTW8851B_A_TXK_GROUP_NR 2 +#define RTW8851B_G_TXK_GROUP_NR 1 +#define RTW8851B_IQK_VER 0x14 +#define RTW8851B_IQK_SS 1 +#define RTW8851B_LOK_GRAM 10 +#define RTW8851B_TSSI_PATH_NR 1 + +#define _TSSI_DE_MASK GENMASK(21, 12) + +enum dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, + DPK_RXAGC = 0x15, + KIP_PRESET = 0x16, + KIP_RESTORE = 0x17, + DPK_TXAGC = 0x19, + D_KIP_PRESET = 0x28, + D_TXAGC = 0x29, + D_RXAGC = 0x2a, + D_SYNC = 0x2b, + D_GAIN_LOSS = 0x2c, + D_MDPK_IDL = 0x2d, + D_MDPK_LDL = 0x2e, + D_GAIN_NORM = 0x2f, + D_KIP_THERMAL = 0x30, + D_KIP_RESTORE = 0x31 +}; + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +enum rtw8851b_iqk_type { + ID_TXAGC = 0x0, + ID_FLOK_COARSE = 0x1, + ID_FLOK_FINE = 0x2, + ID_TXK = 0x3, + ID_RXAGC = 0x4, + ID_RXK = 0x5, + ID_NBTXK = 0x6, + ID_NBRXK = 0x7, + ID_FLOK_VBUFFER = 0x8, + ID_A_FLOK_COARSE = 0x9, + ID_G_FLOK_COARSE = 0xa, + ID_A_FLOK_FINE = 0xb, + ID_G_FLOK_FINE = 0xc, + ID_IQK_RESTORE = 0x10, +}; + +enum rf_mode { + RF_SHUT_DOWN = 0x0, + RF_STANDBY = 0x1, + RF_TX = 0x2, + RF_RX = 0x3, + RF_TXIQK = 0x4, + RF_DPK = 0x5, + RF_RXK1 = 0x6, + RF_RXK2 = 0x7, +}; + +enum adc_ck { + ADC_NA = 0, + ADC_480M = 1, + ADC_960M = 2, + ADC_1920M = 3, +}; + +enum dac_ck { + DAC_40M = 0, + DAC_80M = 1, + DAC_120M = 2, + DAC_160M = 3, + DAC_240M = 4, + DAC_320M = 5, + DAC_480M = 6, + DAC_960M = 7, +}; + +static const u32 _tssi_de_cck_long[RF_PATH_NUM_8851B] = {0x5858}; +static const u32 _tssi_de_cck_short[RF_PATH_NUM_8851B] = {0x5860}; +static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8851B] = {0x5838}; +static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8851B] = {0x5840}; +static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8851B] = {0x5848}; +static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8851B] = {0x5850}; +static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8851B] = {0x5828}; +static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8851B] = {0x5830}; +static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; +static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; +static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; +static const u32 a_idxrxgain[RTW8851B_RXK_GROUP_IDX_NR] = {0x10C, 0x112, 0x28c, 0x292}; +static const u32 a_idxattc2[RTW8851B_RXK_GROUP_IDX_NR] = {0xf, 0xf, 0xf, 0xf}; +static const u32 a_idxrxagc[RTW8851B_RXK_GROUP_IDX_NR] = {0x4, 0x5, 0x6, 0x7}; +static const u32 a_power_range[RTW8851B_A_TXK_GROUP_NR] = {0x0, 0x0}; +static const u32 a_track_range[RTW8851B_A_TXK_GROUP_NR] = {0x7, 0x7}; +static const u32 a_gain_bb[RTW8851B_A_TXK_GROUP_NR] = {0x08, 0x0d}; +static const u32 a_itqt[RTW8851B_A_TXK_GROUP_NR] = {0x12, 0x12}; +static const u32 a_att_smxr[RTW8851B_A_TXK_GROUP_NR] = {0x0, 0x2}; +static const u32 g_power_range[RTW8851B_G_TXK_GROUP_NR] = {0x0}; +static const u32 g_track_range[RTW8851B_G_TXK_GROUP_NR] = {0x6}; +static const u32 g_gain_bb[RTW8851B_G_TXK_GROUP_NR] = {0x10}; +static const u32 g_itqt[RTW8851B_G_TXK_GROUP_NR] = {0x12}; + +static const u32 rtw8851b_backup_bb_regs[] = { + 0xc0d4, 0xc0d8, 0xc0c4, 0xc0ec, 0xc0e8, 0x12a0, 0xc0f0}; +static const u32 rtw8851b_backup_rf_regs[] = { + 0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; + +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8851b_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8851b_backup_rf_regs) + +static const u32 dpk_kip_reg[DPK_KIP_REG_NUM_8851B] = { + 0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8, 0x12a0}; +static const u32 dpk_rf_reg[DPK_RF_REG_NUM_8851B] = {0xde, 0x8f, 0x5, 0x10005}; + +static void _set_ch(struct rtw89_dev *rtwdev, u32 val); + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + return RF_A; +} + +static void _adc_fifo_rst(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); + fsleep(10); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1111); +} + +static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); +} + +static void _txck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool force, enum dac_ck ck) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1); +} + +static void _rxck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool force, enum adc_ck ck) +{ + static const u32 ck960_8851b[] = {0x8, 0x2, 0x2, 0x4, 0xf, 0xa, 0x92}; + static const u32 ck1920_8851b[] = {0x9, 0x0, 0x0, 0x3, 0xf, 0xa, 0x49}; + const u32 *data; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0); + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1); + + switch (ck) { + case ADC_960M: + data = ck960_8851b; + break; + case ADC_1920M: + default: + data = ck1920_8851b; + break; + } + + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, data[0]); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, data[1]); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data[2]); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data[3]); + rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, data[4]); + rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, data[5]); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 8), B_P0_RXCK_ADJ, data[6]); +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u32 rf_mode; + u8 path; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, + rf_mode != 2, 2, 5000, false, + rtwdev, path, 0x00, RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + +static void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x1); +} + +static void _drck(struct rtw89_dev *rtwdev) +{ + u32 rck_d; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); + + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_DRCK_RES, B_DRCK_POL); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); + + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); + + rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, 0x7c00); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, rck_d); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); +} + +static void _addck_backup(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); + + dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); + dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, dack->addck_d[0][1]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); + dack->msbk_d[0][0][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); + + rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); + dack->msbk_d[0][1][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); + } + + dack->biask_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); + dack->biask_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); + dack->dadck_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00) + 24; + dack->dadck_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01) + 24; +} + +static void _dack_reload_by_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 index) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 idx_offset, path_offset; + u32 offset, reg; + u32 tmp; + u8 i; + + if (index == 0) + idx_offset = 0; + else + idx_offset = 0x14; + + if (path == RF_PATH_A) + path_offset = 0; + else + path_offset = 0x28; + + offset = idx_offset + path_offset; + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_RST, 0x1); + + /* msbk_d: 15/14/13/12 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); + reg = 0xc200 + offset; + rtw89_phy_write32(rtwdev, reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, + rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); + + /* msbk_d: 11/10/9/8 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); + reg = 0xc204 + offset; + rtw89_phy_write32(rtwdev, reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, + rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); + + /* msbk_d: 7/6/5/4 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); + reg = 0xc208 + offset; + rtw89_phy_write32(rtwdev, reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, + rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); + + /* msbk_d: 3/2/1/0 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i] << (i * 8); + reg = 0xc20c + offset; + rtw89_phy_write32(rtwdev, reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, + rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); + + /* dadak_d/biask_d */ + tmp = 0x0; + tmp = (dack->biask_d[path][index] << 22) | + (dack->dadck_d[path][index] << 14); + reg = 0xc210 + offset; + rtw89_phy_write32(rtwdev, reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, + rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); + + rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL + offset, B_DACKN0_EN, 0x1); +} + +static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u8 index; + + for (index = 0; index < 2; index++) + _dack_reload_by_path(rtwdev, path, index); +} + +static void _addck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_ADDCKR0, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0); +} + +static void _new_dadck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 i_dc, q_dc, ic, qc; + u32 val; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_setup_defs_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_ADDCKR0, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n"); + dack->addck_timeout[0] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DADCK ret = %d\n", ret); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x0); + i_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x1); + q_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); + + ic = 0x80 - sign_extend32(i_dc, 11) * 6; + qc = 0x80 - sign_extend32(q_dc, 11) * 6; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]before DADCK, i_dc=0x%x, q_dc=0x%x\n", i_dc, q_dc); + + dack->dadck_d[0][0] = ic; + dack->dadck_d[0][1] = qc; + + rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL, B_DACKN0_V, dack->dadck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_DACKN1_CTL, B_DACKN1_V, dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]after DADCK, 0xc210=0x%x, 0xc224=0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DACKN0_CTL, MASKDWORD), + rtw89_phy_read32_mask(rtwdev, R_DACKN1_CTL, MASKDWORD)); + + rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_post_defs_tbl); +} + +static bool _dack_s0_poll(struct rtw89_dev *rtwdev) +{ + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) + return false; + + return true; +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_1_defs_tbl); + _dack_reset(rtwdev, RF_PATH_A); + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); + + ret = read_poll_timeout_atomic(_dack_s0_poll, done, done, + 1, 10000, false, rtwdev); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_2_defs_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); + + _dack_backup_s0(rtwdev); + _dack_reload(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); +} + +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _dack_manual_off(struct rtw89_dev *rtwdev) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_dack_manual_off_defs_tbl); +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 rf0_0; + + dack->dack_done = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x2\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]RF0=0x%x\n", rf0_0); + + _drck(rtwdev); + _dack_manual_off(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); + + _addck(rtwdev); + _addck_backup(rtwdev); + _addck_reload(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); + + _dack(rtwdev); + _new_dadck(rtwdev); + _dack_dump(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); + + dack->dack_done = true; + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + +static void _rx_dck_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, bool is_afe, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ==== S%d RX DCK (%s / CH%d / %s / by %s)====\n", path, + chan->band_type == RTW89_BAND_2G ? "2G" : + chan->band_type == RTW89_BAND_5G ? "5G" : "6G", + chan->channel, + chan->band_width == RTW89_CHANNEL_WIDTH_20 ? "20M" : + chan->band_width == RTW89_CHANNEL_WIDTH_40 ? "40M" : "80M", + is_afe ? "AFE" : "RFC"); +} + +static void _rxbb_ofst_swap(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) +{ + u32 val, val_i, val_q; + + val_i = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_S1); + val_q = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_S1); + + val = val_q << 4 | val_i; + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, rf_mode); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] val_i = 0x%x, val_q = 0x%x, 0x3F = 0x%x\n", + val_i, val_q, val); +} + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) +{ + u32 val; + int ret; + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, + 2, 2000, false, + rtwdev, path, RR_DCK, BIT(8)); + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] S%d RXDCK finish (ret = %d)\n", + path, ret); + + _rxbb_ofst_swap(rtwdev, path, rf_mode); +} + +static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe, + enum rtw89_chanctx_idx chanctx_idx) +{ + u32 rf_reg5; + u8 path; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", + 0x2, rtwdev->hal.cv); + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + _rx_dck_info(rtwdev, phy, path, is_afe, chanctx_idx); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x1); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); + _set_rx_dck(rtwdev, path, RF_RX); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x0); + } +} + +static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) +{ + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); + + for (i = 0; i <= 0x9f; i++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, + 0x00010000 + i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI)); + } + + for (i = 0; i <= 0x9f; i++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, + 0x00010000 + i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ)); + } + + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00000000); +} + +static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) +{ + bool fail1 = false, fail2 = false; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 8200, false, + rtwdev, 0xbff8, MASKBYTE0); + if (ret) { + fail1 = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]NCTL1 IQK timeout!!!\n"); + } + + fsleep(10); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, + 10, 200, false, + rtwdev, R_RPT_COM, B_RPT_COM_RDY); + if (ret) { + fail2 = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]NCTL2 IQK timeout!!!\n"); + } + + fsleep(10); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, ret = %d, notready = %x fail=%d,%d\n", + path, ret, fail1 || fail2, fail1, fail2); + + return fail1 || fail2; +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path, u8 ktype) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool notready; + u32 iqk_cmd; + + switch (ktype) { + case ID_A_FLOK_COARSE: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_A_FLOK_COARSE ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_G_FLOK_COARSE: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_G_FLOK_COARSE ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_A_FLOK_FINE: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_A_FLOK_FINE ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_G_FLOK_FINE: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_G_FLOK_FINE ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_TXK: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_TXK ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_RXAGC: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_RXAGC ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x708 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_RXK ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0xc + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_NBTXK: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_NBTXK ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, + 0x11); + iqk_cmd = 0x408 | (1 << (4 + path)); + break; + case ID_NBRXK: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]============ S%d ID_NBRXK ============\n", path); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, + 0x011); + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + notready = _iqk_check_cal(rtwdev, path); + if (iqk_info->iqk_sram_en && + (ktype == ID_NBRXK || ktype == ID_RXK || ktype == ID_NBTXK)) + _iqk_sram(rtwdev, path); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, ktype= %x, id = %x, notready = %x\n", + path, ktype, iqk_cmd + 1, notready); + + return notready; +} + +static bool _rxk_2g_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u32 rf_0; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + for (gp = 0; gp < RTW8851B_RXK_GROUP_NR; gp++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + fsleep(10); + rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), + rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) + _iqk_sram(rtwdev, path); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, iqk_info->nb_rxcfir[path] | 0x2); + iqk_info->is_wb_txiqk[path] = false; + } else { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, 0x40000000); + iqk_info->is_wb_txiqk[path] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_rxcfir[path]); + return kfail; +} + +static bool _rxk_5g_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u32 rf_0; + u32 val; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x4); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x27); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x0); + + val = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0xc); + + for (gp = 0; gp < RTW8851B_RXK_GROUP_IDX_NR; gp++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + fsleep(100); + rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), + rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) + _iqk_sram(rtwdev, path); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_IQK_RES, B_IQK_RES_RXCFIR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + iqk_info->nb_rxcfir[path] | 0x2); + iqk_info->is_wb_txiqk[path] = false; + } else { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + 0x40000000); + iqk_info->is_wb_txiqk[path] = true; + } + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20, val); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x4); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x37); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x27); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_rxcfir[path]); + return kfail; +} + +static bool _iqk_5g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp = 2; + u32 rf_0; + u32 val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x4); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x27); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x0); + + val = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0xc); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + fsleep(100); + rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), + rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", + path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), 0xf, 0x0); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, 0x40000002); + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->is_wb_rxiqk[path] = false; + } + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, 0x20, val); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x4); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x37); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x27); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_rxcfir[path]); + + return kfail; +} + +static bool _iqk_2g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp = 0x3; + u32 rf_0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + fsleep(10); + rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", + path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), + rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", + path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, 0x40000002); + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->is_wb_rxiqk[path] = false; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_rxcfir[path]); + return kfail; +} + +static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + + if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1); + + _rxck_force(rtwdev, path, true, ADC_960M); + + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_80_defs_tbl); + } else { + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1); + + _rxck_force(rtwdev, path, true, ADC_960M); + + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_others_defs_tbl); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, (2)before RXK IQK\n", path); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[07:10] = 0x%x\n", path, + 0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(10, 7))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[11:14] = 0x%x\n", path, + 0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(14, 11))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[26:27] = 0x%x\n", path, + 0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(27, 26))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[05:08] = 0x%x\n", path, + 0xc0d8, rtw89_phy_read32_mask(rtwdev, 0xc0d8, GENMASK(8, 5))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[17:21] = 0x%x\n", path, + 0xc0c4, rtw89_phy_read32_mask(rtwdev, 0xc0c4, GENMASK(21, 17))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[16:31] = 0x%x\n", path, + 0xc0e8, rtw89_phy_read32_mask(rtwdev, 0xc0e8, GENMASK(31, 16))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[04:05] = 0x%x\n", path, + 0xc0e4, rtw89_phy_read32_mask(rtwdev, 0xc0e4, GENMASK(5, 4))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[23:31] = 0x%x\n", path, + 0x12a0, rtw89_phy_read32_mask(rtwdev, 0x12a0, GENMASK(31, 23))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[13:14] = 0x%x\n", path, + 0xc0ec, rtw89_phy_read32_mask(rtwdev, 0xc0ec, GENMASK(14, 13))); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[16:23] = 0x%x\n", path, + 0xc0ec, rtw89_phy_read32_mask(rtwdev, 0xc0ec, GENMASK(23, 16))); +} + +static bool _txk_5g_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + static const u8 a_idx[RTW8851B_A_TXK_GROUP_NR] = {2, 3}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_COEF, MASKDWORD, 0x33332222); + + for (gp = 0x0; gp < RTW8851B_A_TXK_GROUP_NR; gp++) { + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); + rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, a_att_smxr[gp]); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, a_idx[gp]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x11); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, a_itqt[gp]); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); + iqk_info->is_wb_txiqk[path] = false; + } else { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, 0x40000000); + iqk_info->is_wb_txiqk[path] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_txcfir[path]); + return kfail; +} + +static bool _txk_2g_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_COEF, MASKDWORD, 0x0); + + for (gp = 0x0; gp < RTW8851B_G_TXK_GROUP_NR; gp++) { + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, g_itqt[gp]); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); + iqk_info->is_wb_txiqk[path] = false; + } else { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, 0x40000000); + iqk_info->is_wb_txiqk[path] = true; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_txcfir[path]); + return kfail; +} + +static bool _iqk_5g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + static const u8 a_idx[RTW8851B_A_TXK_GROUP_NR] = {2, 3}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp = 0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); + rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, a_att_smxr[gp]); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, a_idx[gp]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, 0x40000002); + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->is_wb_rxiqk[path] = false; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_txcfir[path]); + return kfail; +} + +static bool _iqk_2g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool notready; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + for (gp = 0x0; gp < RTW8851B_G_TXK_GROUP_NR; gp++) { + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD) | 0x2; + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, 0x40000002); + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->is_wb_rxiqk[path] = false; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, + 1 << path, iqk_info->nb_txcfir[path]); + return kfail; +} + +static bool _iqk_2g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + static const u32 g_txbb[RTW8851B_LOK_GRAM] = { + 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; + static const u32 g_itqt[RTW8851B_LOK_GRAM] = { + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b}; + static const u32 g_wa[RTW8851B_LOK_GRAM] = { + 0x00, 0x04, 0x08, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; + bool fail = false; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x6); + + for (i = 0; i < RTW8851B_LOK_GRAM; i++) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, g_txbb[i]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, g_wa[i]); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000109 | (1 << (4 + path))); + fail |= _iqk_check_cal(rtwdev, path); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000309 | (1 << (4 + path))); + fail |= _iqk_check_cal(rtwdev, path); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x58 = %x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); + } + + return fail; +} + +static bool _iqk_5g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + static const u32 a_txbb[RTW8851B_LOK_GRAM] = { + 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; + static const u32 a_itqt[RTW8851B_LOK_GRAM] = { + 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b, 0x1b, 0x1b, 0x1b}; + static const u32 a_wa[RTW8851B_LOK_GRAM] = { + 0x80, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97}; + bool fail = false; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x7); + + for (i = 0; i < RTW8851B_LOK_GRAM; i++) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, a_txbb[i]); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, a_wa[i]); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000109 | (1 << (4 + path))); + fail |= _iqk_check_cal(rtwdev, path); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000309 | (1 << (4 + path))); + fail |= _iqk_check_cal(rtwdev, path); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S0, i = %x, 0x58 = %x\n", i, + rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); + } + + return fail; +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_2G\n"); + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_2ghz_defs_tbl); + break; + case RTW89_BAND_5G: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_5G\n"); + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_5ghz_defs_tbl); + break; + default: + break; + } +} + +#define IQK_LOK_RETRY 1 + +static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool lok_is_fail; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + for (i = 0; i < IQK_LOK_RETRY; i++) { + _iqk_txk_setting(rtwdev, path); + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + lok_is_fail = _iqk_2g_lok(rtwdev, phy_idx, path); + else + lok_is_fail = _iqk_5g_lok(rtwdev, phy_idx, path); + + if (!lok_is_fail) + break; + } + + if (iqk_info->is_nbiqk) { + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + iqk_info->iqk_tx_fail[0][path] = + _iqk_2g_nbtxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_tx_fail[0][path] = + _iqk_5g_nbtxk(rtwdev, phy_idx, path); + } else { + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + iqk_info->iqk_tx_fail[0][path] = + _txk_2g_group_sel(rtwdev, phy_idx, path); + else + iqk_info->iqk_tx_fail[0][path] = + _txk_5g_group_sel(rtwdev, phy_idx, path); + } + + _iqk_rxclk_setting(rtwdev, path); + _iqk_rxk_setting(rtwdev, path); + _adc_fifo_rst(rtwdev, phy_idx, path); + + if (iqk_info->is_nbiqk) { + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + iqk_info->iqk_rx_fail[0][path] = + _iqk_2g_nbrxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_rx_fail[0][path] = + _iqk_5g_nbrxk(rtwdev, phy_idx, path); + } else { + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + iqk_info->iqk_rx_fail[0][path] = + _rxk_2g_group_sel(rtwdev, phy_idx, path); + else + iqk_info->iqk_rx_fail[0][path] = + _rxk_5g_group_sel(rtwdev, phy_idx, path); + } +} + +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, + u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8851b_backup_bb_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]backup bb reg : %x, value =%x\n", + rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, + u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, + rtw8851b_backup_rf_regs[i], RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path, + rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, + const u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8851b_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore bb reg : %x, value =%x\n", + rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, + const u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8851b_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = 0; + + iqk_info->iqk_band[path] = chan->band_type; + iqk_info->iqk_bw[path] = chan->band_width; + iqk_info->iqk_ch[path] = chan->channel; + iqk_info->iqk_table_idx[path] = idx; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", + path, phy, str_on_off(rtwdev->dbcc_en), + iqk_info->iqk_band[path] == 0 ? "2G" : + iqk_info->iqk_band[path] == 1 ? "5G" : "6G", + iqk_info->iqk_ch[path], + iqk_info->iqk_bw[path] == 0 ? "20M" : + iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", + iqk_info->iqk_times, idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", + path, iqk_info->syn1to2); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + _iqk_by_path(rtwdev, phy_idx, path); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + bool fail; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00001219); + fsleep(10); + fail = _iqk_check_cal(rtwdev, path); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail=%d\n", fail); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_TIA, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_afebb_restore_defs_tbl); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_defs_tbl); + + _txck_force(rtwdev, path, true, DAC_960M); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1); + + _rxck_force(rtwdev, path, true, ADC_1920M); + + rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_bh_defs_tbl); +} + +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx, path; + + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->iqk_times = 0x0; + + for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { + iqk_info->iqk_channel[idx] = 0x0; + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + iqk_info->lok_cor_fail[idx][path] = false; + iqk_info->lok_fin_fail[idx][path] = false; + iqk_info->iqk_tx_fail[idx][path] = false; + iqk_info->iqk_rx_fail[idx][path] = false; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + u32 backup_rf_val[RTW8851B_IQK_SS][BACKUP_RF_REGS_NR]; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, + BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->version = RTW8851B_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + + _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, + BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + bool force, enum rtw89_chanctx_idx chanctx_idx) +{ + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); +} + +static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 *reg, + u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) +{ + u8 i; + + for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { + reg_bkup[path][i] = + rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_bkup_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, + u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) +{ + u8 i; + + for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { + rf_bkup[path][i] = rtw89_read_rf(rtwdev, path, rf_reg[i], RFREG_MASK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup RF S%d 0x%x = %x\n", + path, rf_reg[i], rf_bkup[path][i]); + } +} + +static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 *reg, + u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) +{ + u8 i; + + for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD, + reg_bkup[path][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Reload 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_reload_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, + u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) +{ + u8 i; + + for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { + rtw89_write_rf(rtwdev, path, rf_reg[i], RFREG_MASK, rf_bkup[path][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Reload RF S%d 0x%x = %x\n", path, + rf_reg[i], rf_bkup[path][i]); + } +} + +static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum dpk_id id) +{ + u16 dpk_cmd; + u32 val; + int ret; + + dpk_cmd = ((id << 8) | (0x19 + path * 0x12)); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 20000, false, + rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 1 timeout\n"); + + udelay(1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, + 1, 2000, false, + rtwdev, R_RPT_COM, MASKLWORD); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 2 timeout\n"); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%04x\n", + id == 0x28 ? "KIP_PRESET" : + id == 0x29 ? "DPK_TXAGC" : + id == 0x2a ? "DPK_RXAGC" : + id == 0x2b ? "SYNC" : + id == 0x2c ? "GAIN_LOSS" : + id == 0x2d ? "MDPK_IDL" : + id == 0x2f ? "DPK_GAIN_NORM" : + id == 0x31 ? "KIP_RESTORE" : + id == 0x6 ? "LBK_RXIQK" : "Unknown id", + dpk_cmd); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + u8 off_reverse = off ? 0 : 1; + u8 val; + + val = dpk->is_dpk_enable * off_reverse * dpk->bp[path][kidx].path_ok; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + 0xf0000000, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, str_enable_disable(val)); +} + +static void _dpk_init(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].path_ok = 0; +} + +static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = chan->band_type; + dpk->bp[path][kidx].ch = chan->band_width; + dpk->bp[path][kidx].bw = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + str_on_off(rtwdev->is_tssi_mode[path]), + str_on_off(rtwdev->dbcc_en), + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : + dpk->bp[path][kidx].bw == 2 ? "80M" : "160M"); +} + +static void _dpk_rxagc_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool turn_on) +{ + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, turn_on); + else + rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, turn_on); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d RXAGC is %s\n", path, + turn_on ? "turn_on" : "turn_off"); +} + +static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd); + + _txck_force(rtwdev, path, true, DAC_960M); + _rxck_force(rtwdev, path, true, ADC_1920M); + + rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADCMOD, B_ADCMOD_AUTO_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + udelay(2); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + udelay(2); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); + udelay(10); + + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE setting\n", path); +} + +static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE restore\n", path); +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static +void _dpk_tssi_slope_k_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + bool is_on) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_SLOPE_CAL + (path << 13), + B_P0_TSSI_SLOPE_CAL_EN, is_on); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI slpoe_k %s\n", path, + str_on_off(is_on)); +} + +static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xffe0fa00); + } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xff4009e0); + } else { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xf9f007d0); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool force) +{ + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, force); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", + path, str_on_off(force)); +} + +static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) +{ + if (turn_on) { + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); + } else { + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + rtw89_phy_write32_mask(rtwdev, R_DPK_WR, BIT(18), 0x1); + } +} + +static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool ctrl_by_kip) +{ + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), + B_IQK_RFC_ON, ctrl_by_kip); +} + +static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_SEL, 0x01); + + _dpk_kip_control_rfc(rtwdev, path, true); + _dpk_one_shot(rtwdev, phy, path, D_KIP_PRESET); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + _dpk_one_shot(rtwdev, phy, path, D_KIP_RESTORE); + _dpk_kip_control_rfc(rtwdev, path, false); + _dpk_txpwr_bb_force(rtwdev, path, false); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0x10); + + dpk->cur_k_set = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_KSET) - 1; +} + +static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { + {0x8190, 0x8194, 0x8198, 0x81a4}, + {0x81a8, 0x81c4, 0x81c8, 0x81e8} + }; + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 cur_k_set = dpk->cur_k_set; + u32 para; + + if (cur_k_set >= DPK_KSET_NUM) { + rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); + cur_k_set = 2; + } + + para = rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), + MASKDWORD); + + dpk->bp[path][kidx].txagc_dpk = (para >> 10) & 0x3f; + dpk->bp[path][kidx].ther_dpk = (para >> 26) & 0x3f; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n", + dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, + dpk->bp[path][kidx].txagc_dpk); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 corr_val, corr_idx, rxbb; + u16 dc_i, dc_q; + u8 rxbb_ov; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); + corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); + dpk->corr_idx[path][kidx] = corr_idx; + dpk->corr_val[path][kidx] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n", + path, corr_idx, corr_val, dc_i, dc_q); + + dpk->dc_i[path][kidx] = dc_i; + dpk->dc_q[path][kidx] = dc_q; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x8); + rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x31); + rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n", + path, rxbb, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), + rxbb_ov); + + if (dc_i > 200 || dc_q > 200 || corr_val < 170) + return true; + else + return false; +} + +static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 dbm, + bool set_from_bb) +{ + if (set_from_bb) { + dbm = clamp_t(u8, dbm, 7, 24); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] set S%d txagc to %ddBm\n", path, dbm); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), + B_TXPWRB_VAL, dbm << 2); + } + + _dpk_one_shot(rtwdev, phy, path, D_TXAGC); + _dpk_kset_query(rtwdev, path); +} + +static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_kip_control_rfc(rtwdev, path, false); + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + _dpk_kip_control_rfc(rtwdev, path, true); + + _dpk_one_shot(rtwdev, phy, path, D_RXAGC); + return _dpk_sync_check(rtwdev, path, kidx); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + u32 rf_11, reg_81cc; + u8 cur_rxbb; + + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, false); + + cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); + rf_11 = rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK); + reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_SW); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x3); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0xd); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, 0x1f); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, 0x3); + + _dpk_kip_control_rfc(rtwdev, path, true); + + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, 0x00250025); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); + + _dpk_kip_control_rfc(rtwdev, path, false); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RFREG_MASK, rf_11); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, cur_rxbb); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, reg_81cc); + + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, true); +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50521); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x7); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x50521 | BIT(rtwdev->dbcc_en)); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SATT, 0x3); + } + + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); +} + +static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000002); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Bypass RXIQC\n"); +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); + + return dgain; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + u8 result; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp GL = %d\n", result); + + return result; +} + +static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, D_GAIN_LOSS); + _dpk_kip_set_txagc(rtwdev, phy, path, 0xff, false); + + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, 0xf078); + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, 0x0); + + return _dpk_gainloss_read(rtwdev); +} + +static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, u8 is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u32 val1_sqrt_sum, val2_sqrt_sum; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + + val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; + val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; + + if (val1_sqrt_sum < val2_sqrt_sum) + return 2; + else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) + return 1; + else + return 0; +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + u8 goout = 0, agc_cnt = 0; + bool is_fail = false; + int limit = 200; + u8 tmp_rxbb; + u16 dgain; + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); + + if (is_fail) { + goout = 1; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + + if (dgain > 0x5fc || dgain < 0x556) { + _dpk_one_shot(rtwdev, phy, path, D_SYNC); + _dpk_dgain_read(rtwdev); + } + + if (agc_cnt == 0) { + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + _dpk_bypass_rxiqc(rtwdev, path); + else + _dpk_lbk_rxiqk(rtwdev, phy, path); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + break; + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); + + if (_dpk_pas_read(rtwdev, true) == 2 && tmp_gl_idx > 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true) == 1) || + tmp_gl_idx >= 7) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + break; + + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_dbm <= 7) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_dbm = max_t(u8, tmp_dbm - 3, 7); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_dbm >= 24) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_dbm = min_t(u8, tmp_dbm + 2, 24); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_SET_TX_GAIN: + _dpk_kip_control_rfc(rtwdev, path, false); + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); + tmp_rxbb = min_t(u8, tmp_rxbb + tmp_gl_idx, 0x1f); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, tmp_rxbb); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Adjust RXBB (%+d) = 0x%x\n", + tmp_gl_idx, tmp_rxbb); + _dpk_kip_control_rfc(rtwdev, path, true); + goout = 1; + break; + default: + goout = 1; + break; + } + } while (!goout && agc_cnt < 6 && limit-- > 0); + + return is_fail; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) +{ + switch (order) { + case 0: /* (5,3,1) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); + break; + case 1: /* (5,3,0) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); + break; + case 2: /* (5,0,0) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); + break; + case 3: /* (7,3,1) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x3); + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x3); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Wrong MDPD order!!(0x%x)\n", order); + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", + order == 0x0 ? "(5,3,1)" : + order == 0x1 ? "(5,3,0)" : + order == 0x2 ? "(5,0,0)" : "(7,3,1)"); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD500) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x2); + else if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD530) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x1); + else + _dpk_set_mdpd_para(rtwdev, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, 0x0); + fsleep(1000); + + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); +} + +static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) +{ + u32 order; + u8 val; + + order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); + + switch (order) { + case 0: /* (5,3,1) */ + val = 0x6; + break; + case 1: /* (5,3,0) */ + val = 0x2; + break; + case 2: /* (5,0,0) */ + val = 0x0; + break; + default: + val = 0xff; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); + + return val; +} + +static void _dpk_gain_normalize(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, bool is_execute) +{ + static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { + {0x8190, 0x8194, 0x8198, 0x81a4}, + {0x81a8, 0x81c4, 0x81c8, 0x81e8} + }; + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 cur_k_set = dpk->cur_k_set; + + if (cur_k_set >= DPK_KSET_NUM) { + rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); + cur_k_set = 2; + } + + if (is_execute) { + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), + B_DPK_GN_AG, 0x200); + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), + B_DPK_GN_EN, 0x3); + + _dpk_one_shot(rtwdev, phy, path, D_GAIN_NORM); + } else { + rtw89_phy_write32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), + 0x0000007F, 0x5b); + } + + dpk->bp[path][kidx].gs = + rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), + 0x0000007F); +} + +static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_ORDER, _dpk_order_convert(rtwdev)); + + dpk->bp[path][kidx].path_ok = + dpk->bp[path][kidx].path_ok | BIT(dpk->cur_k_set); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] path_ok = 0x%x\n", + path, kidx, dpk->bp[path][kidx].path_ok); + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_MEN, dpk->bp[path][kidx].path_ok); + + _dpk_gain_normalize(rtwdev, phy, path, kidx, false); +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + u8 init_xdbm = 17; + bool is_fail; + + _dpk_kip_control_rfc(rtwdev, path, false); + _rfk_rf_direct_cntrl(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd); + + _dpk_rf_setting(rtwdev, path, kidx); + _set_rx_dck(rtwdev, path, RF_DPK); + + _dpk_kip_pwr_clk_onoff(rtwdev, true); + _dpk_kip_preset(rtwdev, phy, path, kidx); + _dpk_txpwr_bb_force(rtwdev, path, true); + _dpk_kip_set_txagc(rtwdev, phy, path, init_xdbm, true); + _dpk_tpg_sel(rtwdev, path, kidx); + is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, false); + if (is_fail) + goto _error; + + _dpk_idl_mpa(rtwdev, phy, path, kidx); + _dpk_para_query(rtwdev, path, kidx); + + _dpk_on(rtwdev, phy, path, kidx); +_error: + _dpk_kip_control_rfc(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d]_K%d %s\n", path, kidx, + dpk->cur_k_set, is_fail ? "need Check" : "is Success"); + + return is_fail; +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u32 kip_bkup[RF_PATH_NUM_8851B][DPK_KIP_REG_NUM_8851B] = {}; + u32 rf_bkup[RF_PATH_NUM_8851B][DPK_RF_REG_NUM_8851B] = {}; + bool is_fail; + u8 path; + + for (path = 0; path < RF_PATH_NUM_8851B; path++) + dpk->cur_idx[path] = 0; + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + if (!(kpath & BIT(path))) + continue; + _dpk_bkup_kip(rtwdev, dpk_kip_reg, kip_bkup, path); + _dpk_bkup_rf(rtwdev, dpk_rf_reg, rf_bkup, path); + _dpk_information(rtwdev, phy, path, chanctx_idx); + _dpk_init(rtwdev, path); + + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + } + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + if (!(kpath & BIT(path))) + continue; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", + path, dpk->cur_idx[path]); + + _dpk_tssi_slope_k_onoff(rtwdev, path, false); + _dpk_rxagc_onoff(rtwdev, path, false); + _rfk_drf_direct_cntrl(rtwdev, path, false); + _dpk_bb_afe_setting(rtwdev, path); + + is_fail = _dpk_main(rtwdev, phy, path); + _dpk_onoff(rtwdev, path, is_fail); + } + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + if (!(kpath & BIT(path))) + continue; + + _dpk_kip_restore(rtwdev, phy, path); + _dpk_reload_kip(rtwdev, dpk_kip_reg, kip_bkup, path); + _dpk_reload_rf(rtwdev, dpk_rf_reg, rf_bkup, path); + _dpk_bb_afe_restore(rtwdev, path); + _dpk_rxagc_onoff(rtwdev, path, true); + _dpk_tssi_slope_k_onoff(rtwdev, path, true); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } + + _dpk_kip_pwr_clk_onoff(rtwdev, false); +} + +static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** 8851B DPK Start (Ver: 0x%x, Cv: %d) ******\n", + DPK_VER_8851B, rtwdev->hal.cv); + + _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), chanctx_idx); +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + s8 txagc_bb, txagc_bb_tp, txagc_ofst; + s16 pwsf_tssi_ofst; + s8 delta_ther = 0; + u8 path, kidx; + u8 txagc_rf; + u8 cur_ther; + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + kidx = dpk->cur_idx[path]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + B_TXAGC_RF); + txagc_bb = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + MASKBYTE2); + txagc_bb_tp = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), + B_TXAGC_BTP); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), + B_KIP_RPT_SEL, 0xf); + cur_ther = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), + B_RPT_PER_TH); + txagc_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), + B_RPT_PER_OF); + pwsf_tssi_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), + B_RPT_PER_TSSI); + pwsf_tssi_ofst = sign_extend32(pwsf_tssi_ofst, 12); + + delta_ther = cur_ther - dpk->bp[path][kidx].ther_dpk; + + delta_ther = delta_ther * 2 / 3; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n", + delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n", + txagc_rf - dpk->bp[path][kidx].txagc_dpk, + txagc_rf, dpk->bp[path][kidx].txagc_dpk); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n", + txagc_ofst, pwsf_tssi_ofst); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_DN) == 0x0 && + txagc_rf != 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf = 0x%x\n", 0x78 - delta_ther); + + rtw89_phy_write32_mask(rtwdev, + R_DPD_BND + (path << 8) + (kidx << 2), + 0x07FC0000, 0x78 - delta_ther); + } + } +} + +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5; + u32 rck_val; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, + false, rtwdev, path, RR_RCKS, BIT(3)); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", + rck_val, ret); + + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); +} + +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_sys_defs_tbl); + + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8851b_tssi_sys_a_defs_2g_tbl, + &rtw8851b_tssi_sys_a_defs_5g_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_defs_a_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dck_defs_a_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ +#define RTW8851B_TSSI_GET_VAL(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + const struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 subband = chan->subband_type; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + if (!trk) + trk = &rtw89_8851b_trk_cfg; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + R_P0_TSSI_BASE + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, + thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8851B_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + } +#undef RTW8851B_TSSI_GET_VAL +} + +static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dac_gain_defs_a_tbl); +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8851b_tssi_slope_a_defs_2g_tbl, + &rtw8851b_tssi_slope_a_defs_5g_tbl); +} + +static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, bool all, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8851b_tssi_align_a_2g_defs_tbl, + &rtw8851b_tssi_align_a_5g_defs_tbl); +} + +static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_slope_defs_a_tbl); +} + +static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_track_defs_a_tbl); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_mv_avg_defs_a_tbl); +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + _tssi_set_tssi_track(rtwdev, phy, RF_PATH_A); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXGA_V1, RR_TXGA_V1_TRK_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = true; +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = false; +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u32 gidx, gidx_1st, gidx_2nd; + u8 ch = chan->channel; + s8 de_1st; + s8 de_2nd; + s8 val; + + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u32 tgidx, tgidx_1st, tgidx_2nd; + u8 ch = chan->channel; + s8 tde_1st; + s8 tde_2nd; + s8 val; + + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + for (i = RF_PATH_A; i < RTW8851B_TSSI_PATH_NR; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + _tssi_de_cck_long[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], + _TSSI_DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + _tssi_de_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], + _TSSI_DE_MASK)); + } +} + +static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" + "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", + R_TSSI_PA_K1 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD), + R_TSSI_PA_K2 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM1 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM3 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD), + R_TSSI_PA_K5 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM2 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM4 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD), + R_TSSI_PA_K8 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD)); +} + +static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, enum rtw89_rf_path path, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 channel = chan->channel; + u8 band; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d path=%d\n", __func__, phy, path); + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + if (tssi_info->alignment_done[path][band]) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][0]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][1]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][2]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][3]); + } + + _tssi_alimentk_dump_result(rtwdev, path); +} + +static void rtw8851b_by_rate_dpd(struct rtw89_dev *rtwdev) +{ + rtw89_write32_mask(rtwdev, R_AX_PWR_SWING_OTHER_CTRL0, + B_AX_CFIR_BY_RATE_OFF_MASK, 0x21861); +} + +void rtw8851b_dpk_init(struct rtw89_dev *rtwdev) +{ + rtw8851b_by_rate_dpd(rtwdev); +} + +void rtw8851b_aack(struct rtw89_dev *rtwdev) +{ + u32 tmp05, tmpd3, ib[4]; + u32 tmp; + int ret; + int rek; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO AACK\n"); + + tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); + tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_ST, 0x0); + + for (rek = 0; rek < 4; rek++) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201e); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201f); + fsleep(100); + + ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp, + 1, 1000, false, + rtwdev, RF_PATH_A, 0xd0, BIT(16)); + if (ret) + rtw89_warn(rtwdev, "[LCK]AACK timeout\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x1); + for (i = 0; i < 4; i++) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCO, RR_VCO_SEL, i); + ib[i] = rtw89_read_rf(rtwdev, RF_PATH_A, RR_IBD, RR_IBD_VAL); + } + rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x0); + + if (ib[0] != 0 && ib[1] != 0 && ib[2] != 0 && ib[3] != 0) + break; + } + + if (rek != 0) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]AACK rek = %d\n", rek); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); +} + +static void _lck_keep_thermal(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + + lck->thermal[RF_PATH_A] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d thermal=0x%x", RF_PATH_A, lck->thermal[RF_PATH_A]); +} + +static void rtw8851b_lck(struct rtw89_dev *rtwdev) +{ + u32 tmp05, tmp18, tmpd3; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO LCK\n"); + + tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); + tmp18 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + + _set_ch(rtwdev, tmp18); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); + + _lck_keep_thermal(rtwdev); +} + +#define RTW8851B_LCK_TH 8 + +void rtw8851b_lck_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + u8 cur_thermal; + int delta; + + cur_thermal = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); + delta = abs((int)cur_thermal - lck->thermal[RF_PATH_A]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d current thermal=0x%x delta=0x%x\n", + RF_PATH_A, cur_thermal, delta); + + if (delta >= RTW8851B_LCK_TH) { + rtw8851b_aack(rtwdev); + rtw8851b_lck(rtwdev); + } +} + +void rtw8851b_lck_init(struct rtw89_dev *rtwdev) +{ + _lck_keep_thermal(rtwdev); +} + +void rtw8851b_rck(struct rtw89_dev *rtwdev) +{ + _rck(rtwdev, RF_PATH_A); +} + +void rtw8851b_dack(struct rtw89_dev *rtwdev) +{ + _dac_cal(rtwdev, false); +} + +void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + _iqk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + +void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _rx_dck(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); +} + +void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + rtwdev->dpk.is_dpk_enable = true; + rtwdev->dpk.is_dpk_reload_en = false; + _dpk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8851b_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + +void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_A, chanctx_idx); + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_set_dac_gain_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_alignment_default(rtwdev, phy, i, true, chan); + _tssi_set_tssi_slope(rtwdev, phy, i); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + u8 channel = chan->channel; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d channel=%d\n", __func__, phy, channel); + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_alignment_default(rtwdev, phy, i, true, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 channel = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", + __func__, channel); + + if (enable) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + + _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s SCAN_END\n", __func__); +} + +void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + if (scan_start) + rtw8851b_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx); + else + rtw8851b_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx); +} + +static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) +{ + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + u32 rf_reg18; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + if (rf_reg18 == INV_RF_DATA) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]Invalid RF_0x18 for Path-%d\n", path); + return; + } + rf_reg18 &= ~RR_CFGCH_BW; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); + } + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", + bw, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + _bw_setting(rtwdev, RF_PATH_A, bw, true); + _bw_setting(rtwdev, RF_PATH_A, bw, false); +} + +static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) +{ + u32 bak; + u32 tmp; + int ret; + + bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); + + ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, + false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); + + return !!ret; +} + +static void _lck_check(struct rtw89_dev *rtwdev) +{ + u32 tmp; + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); + } + + udelay(10); + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + } + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); + + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", + rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); + } +} + +static void _set_ch(struct rtw89_dev *rtwdev, u32 val) +{ + bool timeout; + + timeout = _set_s0_arfc18(rtwdev, val); + if (!timeout) + _lck_check(rtwdev); +} + +static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 central_ch, bool dav) +{ + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + bool is_2g_ch = central_ch <= 14; + u32 rf_reg18; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | + RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); + + if (!is_2g_ch) + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | + FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + + if (path == RF_PATH_A && dav) + _set_ch(rtwdev, rf_reg18); + else + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", + central_ch, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) +{ + _ch_setting(rtwdev, RF_PATH_A, central_ch, true); + _ch_setting(rtwdev, RF_PATH_A, central_ch, false); +} + +static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); + + if (bw == RTW89_CHANNEL_WIDTH_20) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); + else if (bw == RTW89_CHANNEL_WIDTH_40) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); + else if (bw == RTW89_CHANNEL_WIDTH_80) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); + else + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path, + rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); +} + +static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + u8 kpath, path; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RF_PATH_NUM_8851B; path++) { + if (!(kpath & BIT(path))) + continue; + + _set_rxbb_bw(rtwdev, bw, path); + } +} + +static void rtw8851b_ctrl_bw_ch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 central_ch, + enum rtw89_band band, enum rtw89_bandwidth bw) +{ + _ctrl_ch(rtwdev, central_ch); + _ctrl_bw(rtwdev, phy, bw); + _rxbb_bw(rtwdev, phy, bw); +} + +void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8851b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, + chan->band_width); +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h new file mode 100644 index 000000000..ea7df6282 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#ifndef __RTW89_8851B_RFK_H__ +#define __RTW89_8851B_RFK_H__ + +#include "core.h" + +void rtw8851b_aack(struct rtw89_dev *rtwdev); +void rtw8851b_lck_init(struct rtw89_dev *rtwdev); +void rtw8851b_lck_track(struct rtw89_dev *rtwdev); +void rtw8851b_rck(struct rtw89_dev *rtwdev); +void rtw8851b_dack(struct rtw89_dev *rtwdev); +void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8851b_dpk_init(struct rtw89_dev *rtwdev); +void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8851b_dpk_track(struct rtw89_dev *rtwdev); +void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx); +void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan); +void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c new file mode 100644 index 000000000..c5f70c045 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#include "rtw8851b_rfk_table.h" + +static const struct rtw89_reg5_def rtw8851b_dadck_setup_defs[] = { + RTW89_DECL_RFK_WM(0xc210, 0x003fc000, 0x80), + RTW89_DECL_RFK_WM(0xc224, 0x003fc000, 0x80), + RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x3), + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0x1f), + RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x0), + RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x0), + RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x1), + RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x0), + RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x1), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x3), + RTW89_DECL_RFK_WM(0xc0f4, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0xc0f4, BIT(4), 0x0), + RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x1), + RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x0), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0xc0f4, 0x300, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_setup_defs); + +static const struct rtw89_reg5_def rtw8851b_dadck_post_defs[] = { + RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x1), + RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x0), + RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0xc), + RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x1), + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_post_defs); + +static const struct rtw89_reg5_def rtw8851b_dack_s0_1_defs[] = { + RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x1), + RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x3), + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_1_defs); + +static const struct rtw89_reg5_def rtw8851b_dack_s0_2_defs[] = { + RTW89_DECL_RFK_WM(0xc004, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x0), + RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x7), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_2_defs); + +static const struct rtw89_reg5_def rtw8851b_dack_manual_off_defs[] = { + RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x0), + RTW89_DECL_RFK_WM(0xc210, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0xc224, BIT(0), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_dack_manual_off_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = { + RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x1), + RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_80_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_others_defs[] = { + RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x0), + RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x2), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_others_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_txk_2ghz_defs[] = { + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x80000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x00800, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x52, 0x00800, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x6), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x10), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_2ghz_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_txk_5ghz_defs[] = { + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x60, 0x00007, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x7), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x7), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_5ghz_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_afebb_restore_defs[] = { + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_afebb_restore_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_macbb_defs[] = { + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0xf801fffd), + RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1), + RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_defs); + +static const struct rtw89_reg5_def rtw8851b_iqk_macbb_bh_defs[] = { + RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f), + RTW89_DECL_RFK_DELAY(10), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_DELAY(10), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f), + RTW89_DECL_RFK_DELAY(10), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_DELAY(2), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_DELAY(10), + RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_bh_defs); + +static const struct rtw89_reg5_def rtw8851b_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), + RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1f19), + RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x1c), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), + RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x2001), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_2g); + +static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_5g); + +static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_defs_a[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x026d000), + RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x5818, 0x00ffffff, 0x2c18e8), + RTW89_DECL_RFK_WM(0x5818, 0x07000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280), + RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x04), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x5898, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x58b0, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x58cc, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800), + RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, MASKDWORD, 0x000000fe), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x3), + RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x5), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_dac_gain_defs_a[] = { + RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000), + RTW89_DECL_RFK_WM(0x5a00, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a04, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a08, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a0c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a10, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a14, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a18, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a1c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a20, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a24, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a28, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a2c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a30, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a34, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a38, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a3c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a40, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a44, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a48, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a4c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a50, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a54, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a58, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a5c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a60, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a64, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a68, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a6c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a70, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a74, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a78, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a7c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a80, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a84, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a88, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a8c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a90, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a94, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a98, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5a9c, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa0, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa4, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa8, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5aac, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab0, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab4, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab8, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5abc, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x5ac0, MASKDWORD, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dac_gain_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0200e08), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x007), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_2g); + +static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0341a08), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201417), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x0e0e0808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080d18), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_5g); + +static const struct rtw89_reg5_def rtw8851b_tssi_align_a_2g_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2400), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3fa), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x02e), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x09c), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x3fb00000), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x02f), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x09c), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_2g_defs); + +static const struct rtw89_reg5_def rtw8851b_tssi_align_a_5g_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x3b2d24), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3cb), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x030), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x73), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0xd4), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_5g_defs); + +static const struct rtw89_reg5_def rtw8851b_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0xf), + RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280), + RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00), + RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00), + RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a), + RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28), + RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76), + RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_track_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff), + RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080), + RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_track_defs_a); + +static const struct rtw89_reg5_def rtw8851b_tssi_mv_avg_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_mv_avg_defs_a); + +static const struct rtw89_reg5_def rtw8851b_nctl_post_defs[] = { + RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x3), + RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x3), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00fffff), + RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3), + RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x1), + RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x0730, 0x00003800, 0x7), + RTW89_DECL_RFK_WM(0x2730, 0x00003800, 0x7), + RTW89_DECL_RFK_WM(0x0c7c, 0x00e00000, 0x1), + RTW89_DECL_RFK_WM(0x58c0, 0x0001ffff, 0x00000), + RTW89_DECL_RFK_WM(0x78c0, 0x0001ffff, 0x00000), + RTW89_DECL_RFK_WM(0x58fc, 0x3f000000, 0x00), + RTW89_DECL_RFK_WM(0x78fc, 0x3f000000, 0x00), +}; + +RTW89_DECLARE_RFK_TBL(rtw8851b_nctl_post_defs); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h new file mode 100644 index 000000000..3f1547f57 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#ifndef __RTW89_8851B_RFK_TABLE_H__ +#define __RTW89_8851B_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8851b_dadck_setup_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_dadck_post_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_1_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_2_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_dack_manual_off_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_80_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_others_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_2ghz_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_5ghz_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_afebb_restore_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_bh_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_dac_gain_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_2g_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_5g_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_track_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_tssi_mv_avg_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8851b_nctl_post_defs_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c new file mode 100644 index 000000000..f875beaec --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c @@ -0,0 +1,14917 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "rtw8851b_table.h" + +static const struct rtw89_reg2_def rtw89_8851b_phy_bb_regs[] = { + {0x704, 0x601E0500}, + {0x4000, 0x00000000}, + {0x4004, 0xCA014000}, + {0x4008, 0xC751D4F0}, + {0x400C, 0x44511475}, + {0x4010, 0x00000000}, + {0x4014, 0x00000000}, + {0x47BC, 0x00000380}, + {0x4018, 0x4F4C084B}, + {0x401C, 0x084A4E52}, + {0x4020, 0x4D504E4B}, + {0x4024, 0x4F4C0849}, + {0x4028, 0x08484C50}, + {0x402C, 0x4C50504C}, + {0x4030, 0x5454084A}, + {0x4034, 0x084B5654}, + {0x4038, 0x6A6C605A}, + {0x403C, 0x4C4C084C}, + {0x4040, 0x084B4E4D}, + {0x4044, 0x4E4C4B4B}, + {0x4048, 0x4B4B084A}, + {0x404C, 0x084A4E4C}, + {0x4050, 0x514F4C4A}, + {0x4054, 0x524E084A}, + {0x4058, 0x084A5154}, + {0x405C, 0x53555554}, + {0x4060, 0x45450845}, + {0x4064, 0x08454144}, + {0x4068, 0x40434445}, + {0x406C, 0x44450845}, + {0x4070, 0x08444043}, + {0x4074, 0x42434444}, + {0x4078, 0x46450844}, + {0x407C, 0x08444843}, + {0x4080, 0x4B4E4A47}, + {0x4084, 0x4F4C084B}, + {0x4088, 0x084A4E52}, + {0x408C, 0x4D504E4B}, + {0x4090, 0x4F4C0849}, + {0x4094, 0x08484C50}, + {0x4098, 0x4C50504C}, + {0x409C, 0x5454084A}, + {0x40A0, 0x084B5654}, + {0x40A4, 0x6A6C605A}, + {0x40A8, 0x4C4C084C}, + {0x40AC, 0x084B4E4D}, + {0x40B0, 0x4E4C4B4B}, + {0x40B4, 0x4B4B084A}, + {0x40B8, 0x084A4E4C}, + {0x40BC, 0x514F4C4A}, + {0x40C0, 0x524E084A}, + {0x40C4, 0x084A5154}, + {0x40C8, 0x53555554}, + {0x40CC, 0x45450845}, + {0x40D0, 0x08454144}, + {0x40D4, 0x40434445}, + {0x40D8, 0x44450845}, + {0x40DC, 0x08444043}, + {0x40E0, 0x42434444}, + {0x40E4, 0x46450844}, + {0x40E8, 0x08444843}, + {0x40EC, 0x4B4E4A47}, + {0x40F0, 0x00000000}, + {0x4A38, 0x00000000}, + {0x40F4, 0x00000006}, + {0x40F8, 0x00000000}, + {0x40FC, 0x8C30C30C}, + {0x4100, 0x4C30C30C}, + {0x4104, 0x0C30C30C}, + {0x4108, 0x0C30C30C}, + {0x410C, 0x0C30C30C}, + {0x4110, 0x0C30C30C}, + {0x4114, 0x28A28A28}, + {0x4118, 0x28A28A28}, + {0x411C, 0x28A28A28}, + {0x4120, 0x28A28A28}, + {0x4124, 0x28A28A28}, + {0x4128, 0x28A28A28}, + {0x412C, 0x06666666}, + {0x4130, 0x33333333}, + {0x4134, 0x33333333}, + {0x4138, 0x33333333}, + {0x413C, 0x00000031}, + {0x4140, 0x5100600A}, + {0x4144, 0x18363113}, + {0x4148, 0x1D976DDC}, + {0x414C, 0x1C072DD7}, + {0x4150, 0x1127CDF4}, + {0x4154, 0x1E37BDF1}, + {0x4158, 0x1FB7F1D6}, + {0x415C, 0x1EA7DDF9}, + {0x4160, 0x1FE445DD}, + {0x4164, 0x1F97F1FE}, + {0x4168, 0x1FF781ED}, + {0x416C, 0x1FA7F5FE}, + {0x4170, 0x1E07B913}, + {0x4174, 0x1FD7FDFF}, + {0x4178, 0x1E17B9FA}, + {0x417C, 0x19A66914}, + {0x4180, 0x10F65598}, + {0x4184, 0x14A5A111}, + {0x4188, 0x1D3765DB}, + {0x418C, 0x17C685CA}, + {0x4190, 0x1107C5F3}, + {0x4194, 0x1B5785EB}, + {0x4198, 0x1F97ED8F}, + {0x419C, 0x1BC7A5F3}, + {0x41A0, 0x1FE43595}, + {0x41A4, 0x1EB7D9FC}, + {0x41A8, 0x1FE65DBE}, + {0x41AC, 0x1EC7D9FC}, + {0x41B0, 0x1976FCFF}, + {0x41B4, 0x1F77F5FF}, + {0x41B8, 0x1976FDEC}, + {0x41BC, 0x198664EF}, + {0x41C0, 0x11062D93}, + {0x41C4, 0x10C4E910}, + {0x41C8, 0x1CA759DB}, + {0x41CC, 0x1335A9B5}, + {0x41D0, 0x1097B9F3}, + {0x41D4, 0x17B72DE1}, + {0x41D8, 0x1F67ED42}, + {0x41DC, 0x18074DE9}, + {0x41E0, 0x1FD40547}, + {0x41E4, 0x1D57ADF9}, + {0x41E8, 0x1FE52182}, + {0x41EC, 0x1D67B1F9}, + {0x41F0, 0x14860CE1}, + {0x41F4, 0x1EC7E9FE}, + {0x41F8, 0x14860DD6}, + {0x41FC, 0x195664C7}, + {0x4200, 0x0005E58A}, + {0x4204, 0x00000000}, + {0x4208, 0x00000000}, + {0x420C, 0x7A000000}, + {0x4210, 0x0F9F3D7A}, + {0x4214, 0x0040817C}, + {0x4218, 0x00E10204}, + {0x421C, 0x227D94CD}, + {0x4220, 0x08028A28}, + {0x4224, 0x00000200}, + {0x4228, 0x04688000}, + {0x47C0, 0x00000001}, + {0x4A48, 0x00000002}, + {0x4B04, 0x00000000}, + {0x4B08, 0x00000000}, + {0x422C, 0x0060B002}, + {0x4230, 0x9A8249A8}, + {0x4234, 0x26A1469E}, + {0x4238, 0x2099A824}, + {0x423C, 0x2359461C}, + {0x4240, 0x1631A675}, + {0x4244, 0x2C6B1D63}, + {0x4248, 0x0000000E}, + {0x424C, 0x00000001}, + {0x4250, 0x00000001}, + {0x4254, 0x00000000}, + {0x4258, 0x00000000}, + {0x425C, 0x00000000}, + {0x4260, 0x0020000C}, + {0x4A30, 0x00000000}, + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, + {0x4270, 0x2B33135C}, + {0x4274, 0x00000002}, + {0x4278, 0x00000000}, + {0x427C, 0x00000000}, + {0x4280, 0x00000000}, + {0x4284, 0x00000000}, + {0x4288, 0x00000000}, + {0x428C, 0x00000000}, + {0x4290, 0x00000000}, + {0x4294, 0x00000000}, + {0x4298, 0x00000000}, + {0x429C, 0x84026000}, + {0x42A0, 0x0051AC20}, + {0x4A24, 0x0010C040}, + {0x42A4, 0x02024008}, + {0x42A8, 0x00000000}, + {0x42AC, 0x00000000}, + {0x42B0, 0x22CE803C}, + {0x42B4, 0xD8000000}, + {0x42B8, 0x596FD67E}, + {0x42BC, 0x7D67D67D}, + {0x42C0, 0x7D67D65B}, + {0x42C4, 0x28029F59}, + {0x42C8, 0x00280280}, + {0x4AF4, 0x00000000}, + {0x42CC, 0x00000000}, + {0x42D0, 0x00000000}, + {0x42D4, 0x00000003}, + {0x4AF8, 0x00280000}, + {0x42D8, 0x00000001}, + {0x42DC, 0x69AEC800}, + {0x42E0, 0x8B4CD3D1}, + {0x42E4, 0xC514534F}, + {0x42E8, 0x85145145}, + {0x42EC, 0x45145145}, + {0x42F0, 0x05145145}, + {0x42F4, 0x05145145}, + {0x42F8, 0x05145145}, + {0x42FC, 0x17659145}, + {0x4300, 0x176DD5D9}, + {0x4304, 0x0F65765B}, + {0x4308, 0x0F3CF3CF}, + {0x430C, 0x0F3CF3CF}, + {0x4310, 0x0F3CF3CF}, + {0x4314, 0x0F3CF3CF}, + {0x4318, 0x0F3CF3CF}, + {0x431C, 0x0F3CF3CF}, + {0x4320, 0x0F3CF3CF}, + {0x4324, 0x0F44F351}, + {0x4328, 0x192D7547}, + {0x432C, 0x0F5CF5CF}, + {0x4330, 0x051593D9}, + {0x4334, 0x05145145}, + {0x4338, 0x05145145}, + {0x433C, 0x05145145}, + {0x4340, 0x05145145}, + {0x4344, 0x05145145}, + {0x4348, 0x19545145}, + {0x434C, 0x1B65B5DB}, + {0x4350, 0x1965965B}, + {0x4354, 0x0F3CF3CF}, + {0x4358, 0x0F3CF3CF}, + {0x435C, 0x0F3CF1CF}, + {0x4360, 0x0F3CF3CF}, + {0x4364, 0x0F3CF3CF}, + {0x4368, 0x0F3CF3CF}, + {0x436C, 0x0F3CF3CF}, + {0x4370, 0x0934D2CF}, + {0x4374, 0x112CB3CF}, + {0x4378, 0x9777A777}, + {0x437C, 0xBB7BAC95}, + {0x4380, 0xB667B889}, + {0x4384, 0x7B9B8899}, + {0x4388, 0x7A5567C8}, + {0x438C, 0x2278CCCC}, + {0x4390, 0x7C222222}, + {0x4394, 0x0000029B}, + {0x4398, 0x001CCCCC}, + {0x4AAC, 0xCCCCC88C}, + {0x4AB0, 0x0000AACC}, + {0x439C, 0x00000000}, + {0x43A0, 0x00000008}, + {0x43A4, 0x00000000}, + {0x43A8, 0x00000000}, + {0x43AC, 0x00000000}, + {0x43B0, 0x10000000}, + {0x43B4, 0x00401001}, + {0x43B8, 0x00061003}, + {0x43BC, 0x000024D8}, + {0x43C0, 0x00000000}, + {0x43C4, 0x10000020}, + {0x43C8, 0x20000200}, + {0x43CC, 0x00000000}, + {0x43D0, 0x04000000}, + {0x43D4, 0x44000100}, + {0x43D8, 0x60804060}, + {0x43DC, 0x44204210}, + {0x43E0, 0x82108082}, + {0x43E4, 0x82108402}, + {0x43E8, 0xC8082108}, + {0x43EC, 0xC8202084}, + {0x43F0, 0x44208208}, + {0x43F4, 0x84108204}, + {0x43F8, 0xD0108104}, + {0x43FC, 0xF8210108}, + {0x4400, 0x6431E930}, + {0x4404, 0x02309468}, + {0x4408, 0x10C61C22}, + {0x440C, 0x02109469}, + {0x4410, 0x10C61C22}, + {0x4414, 0x00041049}, + {0x4A4C, 0x00060581}, + {0x4418, 0x00000000}, + {0x441C, 0x00000000}, + {0x4420, 0xEC000000}, + {0x4424, 0xB0200020}, + {0x4428, 0x00001FF0}, + {0x4AC8, 0x00000001}, + {0x4B0C, 0x00000000}, + {0x4CDC, 0x00000000}, + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, + {0x4438, 0x00000000}, + {0x443C, 0x190642D0}, + {0x4440, 0xA80668A0}, + {0x4444, 0x60900820}, + {0x4448, 0x9F28518C}, + {0x444C, 0x32488A62}, + {0x4450, 0x9C6E36DC}, + {0x4454, 0x0000F52B}, + {0x4A34, 0x00000007}, + {0x4CE0, 0x68120000}, + {0x4CE4, 0x1A0681E0}, + {0x4CE8, 0x94060180}, + {0x4CEC, 0x000603FF}, + {0x4CF0, 0xA0502000}, + {0x4CF4, 0x00001000}, + {0x4D00, 0x00000044}, + {0x4B14, 0x00000000}, + {0x4458, 0x00000000}, + {0x445C, 0x4801442E}, + {0x4460, 0x0051A0FA}, + {0x4B18, 0x0000011F}, + {0x4B1C, 0x0000011F}, + {0x4464, 0x00000000}, + {0x4468, 0x00000000}, + {0x446C, 0x00000000}, + {0x4470, 0x00000000}, + {0x4474, 0x00000000}, + {0x4478, 0x00000000}, + {0x447C, 0x00000000}, + {0x4480, 0x2A0A6040}, + {0x4484, 0x0A0A6829}, + {0x4488, 0x00000004}, + {0x448C, 0x00000000}, + {0x4490, 0x80000000}, + {0x4494, 0x10000000}, + {0x4498, 0xE0000000}, + {0x4A28, 0x000ED877}, + {0x4AB4, 0x00000000}, + {0x4B20, 0x00000000}, + {0x4B24, 0x00000000}, + {0x4B28, 0x00000000}, + {0x4B2C, 0x00000000}, + {0x449C, 0x0000001E}, + {0x44A0, 0x02B2C394}, + {0x44A4, 0x00000400}, + {0x4A2C, 0x0050240E}, + {0x4B30, 0x7FFFFD20}, + {0x4B34, 0x920823FF}, + {0x4B38, 0x7FFFFFFF}, + {0x4B3C, 0x01773773}, + {0x44A8, 0x00000001}, + {0x44AC, 0x000190C0}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4E830171}, + {0x4534, 0x00000870}, + {0x4538, 0x000000FF}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x40000000}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x20000000}, + {0x4570, 0x04F040BB}, + {0x4574, 0x000E53FF}, + {0x4578, 0x000205CB}, + {0x457C, 0x00200000}, + {0x4580, 0x00000040}, + {0x4584, 0x00000000}, + {0x4588, 0x00000017}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x00000000}, + {0x4598, 0x00000001}, + {0x459C, 0x0003FE00}, + {0x45A0, 0x00000086}, + {0x45A4, 0x00000000}, + {0x45A8, 0xC00001C0}, + {0x45AC, 0x78038000}, + {0x45B0, 0x8000004A}, + {0x45B4, 0x04094800}, + {0x45B8, 0x00280002}, + {0x45BC, 0x06748790}, + {0x45C0, 0x80000000}, + {0x45C4, 0x00000000}, + {0x45C8, 0x00000000}, + {0x45CC, 0x00558670}, + {0x45D0, 0x002883F0}, + {0x45D4, 0x00090120}, + {0x45D8, 0x00000000}, + {0x45E0, 0xA3A6D3C4}, + {0x45E4, 0xAB27B126}, + {0x45E8, 0x00006778}, + {0x45F4, 0x000001B5}, + {0x45EC, 0x11110F0A}, + {0x45F0, 0x00000003}, + {0x4A0C, 0x0000000A}, + {0x45F8, 0x0058BC3F}, + {0x45FC, 0x00000003}, + {0x462C, 0x00000020}, + {0x4600, 0x000003D9}, + {0x45F0, 0x00000004}, + {0x4604, 0x002B1CB0}, + {0x4A50, 0xC0000000}, + {0x4A54, 0x00001000}, + {0x4A58, 0x00000000}, + {0x4A18, 0x00000024}, + {0x4608, 0x00000001}, + {0x460C, 0x00000000}, + {0x4A10, 0x00000001}, + {0x4610, 0x00000001}, + {0x4614, 0x16E5298F}, + {0x4618, 0x18C6294A}, + {0x461C, 0x0E06318A}, + {0x4620, 0x0E539CE5}, + {0x4624, 0x00019287}, + {0x4A14, 0x000000BF}, + {0x4628, 0x00000001}, + {0x4630, 0x000001AA}, + {0x4A18, 0x00001900}, + {0x4A1C, 0x000002A6}, + {0x4634, 0x000000A3}, + {0x4A20, 0x00000086}, + {0x4638, 0x00045656}, + {0x49F8, 0x00000000}, + {0x463C, 0x00000000}, + {0x4640, 0x00000000}, + {0x4644, 0x00C8CC00}, + {0x4648, 0xC400B6B6}, + {0x464C, 0xDC400FC0}, + {0x4A44, 0x00000000}, + {0x4A8C, 0x00000110}, + {0x4BC4, 0x00000001}, + {0x4650, 0x08882550}, + {0x4654, 0x08CC2660}, + {0x4658, 0x09102660}, + {0x465C, 0x00000154}, + {0x45DC, 0xC39E38E8}, + {0x4660, 0x452607E6}, + {0x4664, 0x6750DC65}, + {0x4668, 0xF3F0F1ED}, + {0x466C, 0x30141506}, + {0x4670, 0x2C2B2B2B}, + {0x4674, 0x2C2C2C2C}, + {0x4678, 0xDDB738E8}, + {0x467C, 0x543618FB}, + {0x4680, 0x4F31DC6F}, + {0x4684, 0xFBEBDA00}, + {0x4688, 0x1A10FF04}, + {0x468C, 0x282A3000}, + {0x4690, 0x2A29292A}, + {0x4694, 0x04FA2A2A}, + {0x4698, 0xEE0F04D1}, + {0x469C, 0x99E91436}, + {0x46A0, 0x0701E79E}, + {0x46A4, 0x08D77CFF}, + {0x46A8, 0x321AFF14}, + {0x46AC, 0x60313447}, + {0x46B0, 0x63666666}, + {0x46B4, 0x35374425}, + {0x46B8, 0x35883042}, + {0x46BC, 0x5177C252}, + {0x4720, 0x7FFFFD63}, + {0x4724, 0xB58D11FF}, + {0x4728, 0x47FFFFFF}, + {0x472C, 0x0E7893B6}, + {0x4730, 0xE0391201}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0x473C, 0x00000B7F}, + {0x46C0, 0x00000000}, + {0x46C4, 0x00000000}, + {0x46C8, 0x00000219}, + {0x4BDC, 0x00002020}, + {0x46CC, 0x00000000}, + {0x46D0, 0x00000000}, + {0x4A3C, 0x00000002}, + {0x46D4, 0x00000001}, + {0x46D8, 0x00000001}, + {0x46DC, 0x00000000}, + {0x46E0, 0x00000000}, + {0x46E4, 0x00000151}, + {0x46E8, 0x00000498}, + {0x46EC, 0x00000498}, + {0x46F0, 0x00000000}, + {0x46F4, 0x00000000}, + {0x46F8, 0x00001146}, + {0x46FC, 0x00000000}, + {0x4700, 0x00000000}, + {0x4704, 0x00C8CC00}, + {0x4708, 0xC400B6B6}, + {0x470C, 0xDC400FC0}, + {0x4A90, 0x00000110}, + {0x4B10, 0x00000000}, + {0x4BE0, 0x00000001}, + {0x4710, 0x08882550}, + {0x4714, 0x08CC2660}, + {0x4718, 0x09102660}, + {0x471C, 0x00000154}, + {0x4740, 0xC69F38E8}, + {0x4744, 0x462709E9}, + {0x4748, 0x6750DC67}, + {0x474C, 0xF3F0F1ED}, + {0x4750, 0x30141506}, + {0x4754, 0x2C2B2B2B}, + {0x4758, 0x2C2C2C2C}, + {0x475C, 0xE0B738E8}, + {0x4760, 0x52381BFE}, + {0x4764, 0x5031DC6C}, + {0x4768, 0xFBEBDA00}, + {0x476C, 0x1A10FF04}, + {0x4770, 0x282A3000}, + {0x4774, 0x2A29292A}, + {0x4778, 0x04FA2A2A}, + {0x477C, 0xEE0F04D1}, + {0x47C4, 0x00000000}, + {0x47C8, 0xA32103FE}, + {0x47CC, 0xB20A5328}, + {0x47D0, 0xC686314F}, + {0x47D4, 0x000004D7}, + {0x4BFC, 0x00000000}, + {0x4C00, 0x0C442416}, + {0x4C04, 0x00000000}, + {0x47D8, 0x009B902A}, + {0x47DC, 0x009B902A}, + {0x47E0, 0x98682C18}, + {0x47E4, 0x6318C4C1}, + {0x47E8, 0x6248C631}, + {0x47EC, 0x922A8253}, + {0x47F0, 0x00000005}, + {0x47F4, 0x00001759}, + {0x47F8, 0x4BB01800}, + {0x47FC, 0x831408BE}, + {0x4A84, 0x000000E9}, + {0x4C08, 0x0F801404}, + {0x4C0C, 0x00A2B404}, + {0x4800, 0x9ABBCACB}, + {0x4804, 0x56867578}, + {0x4808, 0xBCCBBB13}, + {0x480C, 0x7889989B}, + {0x4810, 0xBBB0F455}, + {0x4814, 0x777BBBBB}, + {0x4818, 0x15277777}, + {0x481C, 0x27039CE9}, + {0x4820, 0x42424432}, + {0x4824, 0x36058342}, + {0x4828, 0x00000006}, + {0x482C, 0x00000005}, + {0x4830, 0x00000005}, + {0x4834, 0xC7013016}, + {0x4838, 0x84413016}, + {0x483C, 0x84413016}, + {0x4840, 0x8C413016}, + {0x4844, 0x8C40B028}, + {0x4848, 0x3140B028}, + {0x484C, 0x2940B028}, + {0x4850, 0x8440B028}, + {0x4854, 0x2318C610}, + {0x4858, 0x45344753}, + {0x485C, 0x236A6A88}, + {0x4860, 0xAC8DF814}, + {0x4864, 0x08877ACB}, + {0x4868, 0x000107AA}, + {0x4A94, 0x00000000}, + {0x486C, 0xBCEB4A14}, + {0x4870, 0x000A3A4A}, + {0x4874, 0xBCEB4A14}, + {0x4878, 0x000A3A4A}, + {0x487C, 0xBCBDBD85}, + {0x4880, 0x0CABB99A}, + {0x4884, 0x38384242}, + {0x4888, 0x0086102E}, + {0x488C, 0xCA24C82A}, + {0x4AFC, 0x00000000}, + {0x4C14, 0x0000349D}, + {0x4CF8, 0x00000007}, + {0x4890, 0x00008A62}, + {0x4894, 0x00000008}, + {0x4958, 0x80040000}, + {0x495C, 0x80040000}, + {0x4960, 0xFE800000}, + {0x4964, 0x834C0000}, + {0x4968, 0x00000000}, + {0x496C, 0x00000000}, + {0x4970, 0x00000000}, + {0x4974, 0x00000000}, + {0x4978, 0x00000000}, + {0x497C, 0x00000000}, + {0x4980, 0x40000000}, + {0x4984, 0x00000000}, + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4990, 0x00000000}, + {0x4994, 0x04065800}, + {0x4998, 0x02004080}, + {0x499C, 0x0E1E3E05}, + {0x49A0, 0x0A163068}, + {0x49A4, 0x00206040}, + {0x49A8, 0x02020202}, + {0x49AC, 0x00002020}, + {0x49B0, 0xF8F8F418}, + {0x49B4, 0xF8E8F8F8}, + {0x49B8, 0xF80808E8}, + {0x4A00, 0xF8F8FA00}, + {0x4A04, 0xFAFAFAF8}, + {0x4A08, 0xFAFAFAFA}, + {0x49BC, 0x00000000}, + {0x49C0, 0x800C562D}, + {0x49C4, 0x00000101}, + {0x49C8, 0x00000000}, + {0x49CC, 0x00000000}, + {0x49D0, 0x00000000}, + {0x49D4, 0x00000000}, + {0x49D8, 0x00000000}, + {0x49DC, 0x00000000}, + {0x49E0, 0x00000000}, + {0x49E4, 0x00000000}, + {0x49E8, 0x00000000}, + {0x49EC, 0x00000000}, + {0x4C28, 0x00000000}, + {0x4C2C, 0x00000000}, + {0x4C30, 0x00000000}, + {0x4C34, 0x00000000}, + {0x4C38, 0x00000000}, + {0x4C3C, 0x00000000}, + {0x4C40, 0x00000000}, + {0x4C44, 0x01C0C832}, + {0x4C48, 0x03207032}, + {0x4C4C, 0x0320701C}, + {0x4C50, 0x03207032}, + {0x4C54, 0x01C0C81C}, + {0x4C58, 0x00A0281C}, + {0x4C5C, 0x0320C80A}, + {0x4C60, 0x00A0C832}, + {0x4C64, 0x01C0C832}, + {0x4C68, 0x03207032}, + {0x4C6C, 0x0320701C}, + {0x4C70, 0x03207032}, + {0x4C74, 0x01C0C81C}, + {0x4C78, 0x00A0281C}, + {0x4C7C, 0x0321A80A}, + {0x4C80, 0x0320C86A}, + {0x4C84, 0x12B02832}, + {0x4C88, 0x12B3292B}, + {0x4C8C, 0x0CA4ACCA}, + {0x4C90, 0x12B4AC6A}, + {0x4C94, 0x0CA4ACCA}, + {0x4C98, 0x06A3292B}, + {0x4C9C, 0x06A0280A}, + {0x4CA0, 0x0CA0286A}, + {0x4CA4, 0x0CA1A8CA}, + {0x4CA8, 0x06A3286A}, + {0x4CAC, 0x0000000A}, + {0x4CB0, 0x01209C27}, + {0x4CB4, 0x02704800}, + {0x4CB8, 0x02704812}, + {0x4CBC, 0x00004827}, + {0x4CC0, 0x01209C12}, + {0x4CC4, 0x00000012}, + {0x4CC8, 0x02718000}, + {0x4CCC, 0x02709C60}, + {0x4CD0, 0x00000027}, + {0x4CD4, 0x00000000}, + {0x4CD8, 0x0000014A}, + {0x994, 0x00000010}, + {0x904, 0x00000005}, + {0x708, 0x00000000}, + {0x884, 0x0043F01D}, + {0x710, 0xEF810000}, + {0x718, 0x1333233F}, + {0x604, 0x041E1E1E}, + {0x714, 0x00010000}, + {0x586C, 0x000000F0}, + {0x586C, 0x000000E0}, + {0x586C, 0x000000D0}, + {0x586C, 0x000000C0}, + {0x586C, 0x000000B0}, + {0x586C, 0x000000A0}, + {0x586C, 0x00000090}, + {0x586C, 0x00000080}, + {0x586C, 0x00000070}, + {0x586C, 0x00000060}, + {0x586C, 0x00000050}, + {0x586C, 0x00000040}, + {0x586C, 0x00000030}, + {0x586C, 0x00000020}, + {0x586C, 0x00000010}, + {0x586C, 0x00000000}, + {0xC0D4, 0xABA41460}, + {0xC0D8, 0xC43A7E87}, + {0xC0DC, 0x30C194B8}, + {0xC0E0, 0x75008138}, + {0xC0E4, 0x0000272B}, + {0xC0E8, 0x000A0C81}, + {0xC0EC, 0x00030003}, + {0xC0F0, 0x00000024}, + {0xC0C4, 0x005E3A00}, + {0xC004, 0x45800000}, + {0xC024, 0x45800000}, + {0x334, 0xFFFFFFFF}, + {0x33C, 0x55000000}, + {0x340, 0x00005555}, + {0x724, 0x00111200}, + {0x5868, 0xA9550000}, + {0x5870, 0x33221100}, + {0x5874, 0x77665544}, + {0x5878, 0xBBAA9988}, + {0x587C, 0xFFEEDDCC}, + {0x5880, 0x76543210}, + {0x5884, 0xFEDCBA98}, + {0x5888, 0x00000000}, + {0x588C, 0x00000000}, + {0x5894, 0x00000008}, + {0x650, 0x00200888}, + {0x710, 0xF3810000}, + {0x020, 0x0000F381}, + {0x024, 0x0000F381}, + {0x000, 0xC580801E}, + {0x980, 0x10002250}, + {0x988, 0x3C3C4107}, + {0x994, 0x00000010}, + {0x000, 0x0580801F}, + {0x240C, 0x00000000}, + {0x640, 0x210A141E}, + {0x640, 0x2114141E}, + {0x640, 0x2114141E}, + {0x644, 0x3414283C}, + {0x644, 0x3425283C}, + {0x644, 0x3426283C}, + {0x2640, 0x140A141E}, + {0x2640, 0x1414141E}, + {0x2640, 0x1414141E}, + {0x2644, 0x3414283C}, + {0x2644, 0x3425283C}, + {0x2644, 0x3425183C}, + {0x2300, 0x02748790}, + {0x2304, 0x00558670}, + {0x2308, 0x002883F0}, + {0x230C, 0x00090120}, + {0x2310, 0x00000000}, + {0x2314, 0x06000000}, + {0x2318, 0x00000000}, + {0x231C, 0x00000000}, + {0x2320, 0x03020100}, + {0x2324, 0x07060504}, + {0x2328, 0x0B0A0908}, + {0x232C, 0x0F0E0D0C}, + {0x2330, 0x13121110}, + {0x2334, 0x17161514}, + {0x2338, 0x0C700022}, + {0x233C, 0x0A0529D0}, + {0x2340, 0x000529D0}, + {0x2344, 0x0006318A}, + {0x2348, 0xB7E6318A}, + {0x234C, 0x80039C00}, + {0x2350, 0x80039C00}, + {0x2354, 0x0005298F}, + {0x2358, 0x0015296E}, + {0x235C, 0x0C07FC31}, + {0x2360, 0x0219AAAE}, + {0x2364, 0xE4F624C3}, + {0x2368, 0x53626F15}, + {0x236C, 0x48000000}, + {0x2370, 0x48000000}, + {0x2374, 0x07540000}, + {0x2378, 0x202401B9}, + {0x237C, 0x00F7000E}, + {0x2380, 0x0F0A1111}, + {0x2384, 0x30D9000F}, + {0x2388, 0x0200EA02}, + {0x238C, 0x003CB061}, + {0x2390, 0x69C00000}, + {0x2394, 0x00000000}, + {0x2398, 0x000000F0}, + {0x239C, 0x0001FFFF}, + {0x23A0, 0x00C80064}, + {0x23A4, 0x0190012C}, + {0x23A8, 0x001917BE}, + {0x23AC, 0x0B30880C}, + {0x23B0, 0x9281CE00}, + {0x23B4, 0x7F027C00}, + {0x704, 0x601E0502}, + {0x5600, 0x00000000}, + {0x5604, 0x802D2721}, + {0x5610, 0x00201020}, + {0x5618, 0x00801008}, + {0x5624, 0x0808081E}, + {0x562C, 0x0000081D}, + {0x5634, 0x3D2EE000}, + {0x5638, 0x0001AC42}, + {0x5640, 0x3D6EF000}, + {0x5644, 0x0001AC3E}, + {0x566C, 0x00210005}, + {0x5680, 0x20500010}, + {0x5684, 0x00020001}, + {0x56A0, 0x0034C000}, + {0x56BC, 0x04000000}, + {0x56C0, 0x00000688}, + {0x56C4, 0x00000010}, + {0x56C8, 0x0E800400}, + {0x56CC, 0x01E400FF}, + {0x5800, 0x003F807F}, + {0x5810, 0x59008400}, + {0x5814, 0x201AF000}, + {0x5818, 0x182C18E8}, + {0x581C, 0x3DD80280}, + {0x5820, 0x80000080}, + {0x5828, 0x023F8121}, + {0x5830, 0x023F8121}, + {0x5838, 0x003F8121}, + {0x5840, 0x023F8121}, + {0x5848, 0x023F8121}, + {0x5850, 0x023F8121}, + {0x5858, 0x003F7121}, + {0x5860, 0x023F7121}, + {0x5864, 0x1A1801FF}, + {0x5868, 0xA9A90002}, + {0x5880, 0x77777777}, + {0x5884, 0x77777777}, + {0x5894, 0x01080604}, + {0x5898, 0x00000000}, + {0x589C, 0x00000000}, + {0x58A0, 0x000000FE}, + {0x58B0, 0x00000800}, + {0x58BC, 0x07A7807F}, + {0x58C0, 0x007E0000}, + {0x58C4, 0x0003FFFF}, + {0x58D4, 0x7401FE00}, + {0x58D8, 0x8008016C}, + {0x58DC, 0xC000807F}, + {0x58E4, 0x3000881F}, + {0x58E8, 0x00000003}, + {0x58F0, 0x400401FF}, + {0x58F4, 0x80000000}, + {0x58F8, 0xC0000000}, + {0x58FC, 0x00000000}, + {0x700, 0x40000030}, + {0x704, 0x601E0502}, + {0x704, 0x601E0500}, + {0x704, 0x601E0502}, + {0x20FC, 0x00000000}, + {0x20F8, 0x00000000}, + {0x20F0, 0x00000000}, + {0x9C0, 0x00000001}, + {0x9C0, 0x00000000}, + {0x9C0, 0x00000001}, + {0x9C0, 0x00000000}, + {0x4AE8, 0x00000744}, + {0x4AD4, 0x00000040}, + {0x4AE4, 0x0079E99E}, + {0x4BC8, 0xFBD5B89F}, + {0x4BCC, 0x99563918}, + {0x4BD0, 0x12EED5B8}, + {0x4BD4, 0x6F7D542F}, + {0x4BD8, 0x0000001D}, + {0x300, 0xF30CE31C}, + {0x304, 0x13EF1F19}, + {0x308, 0x0C0CF3F3}, + {0x30C, 0x0CE30C0C}, + {0x310, 0x80496000}, + {0x314, 0x0041E000}, + {0x318, 0x20022042}, + {0x31C, 0x20448009}, + {0x320, 0x00010031}, + {0x324, 0xE000E000}, + {0x328, 0xE000E000}, + {0x32C, 0xE0008049}, + {0x12BC, 0x10104041}, + {0x12C0, 0x13311111}, + {0x12E4, 0x30D52A68}, + {0x010, 0x0005FFFF}, + {0x028, 0x0000F381}, + {0x02C, 0x0000F381}, + {0x620, 0x00141230}, + {0x70C, 0x00000020}, + {0x720, 0x20000000}, + {0x730, 0x00000002}, + {0x738, 0x004100C0}, + {0x73C, 0x00000002}, + {0x748, 0x01000002}, + {0x74C, 0x00000001}, + {0xA08, 0x00007800}, + {0xC14, 0x25010000}, + {0xC3C, 0x2840E1BF}, + {0xC40, 0x00000000}, + {0xC44, 0x00000007}, + {0xC48, 0x410E4000}, + {0xC54, 0x1EE14368}, + {0xC58, 0x41000000}, + {0xC5C, 0x80558000}, + {0xC60, 0x017FFFF2}, + {0xC64, 0x0010A130}, + {0xC68, 0x90000050}, + {0xC6C, 0x10201021}, + {0xC70, 0x071B0660}, + {0xC74, 0x00000000}, + {0xC78, 0x80000000}, + {0xC7C, 0x0020BFE0}, + {0xC88, 0xC2AC8000}, + {0xC8C, 0x02F2FC08}, + {0xD00, 0x77777777}, + {0xD04, 0xBBBBBBBB}, + {0xD08, 0xBBBBBBBB}, + {0xD0C, 0x000B2070}, + {0xD10, 0x20110FFF}, + {0xD18, 0x50009800}, + {0xD20, 0x01900000}, + {0xD30, 0x03FF8000}, + {0xD40, 0xF64FA0F7}, + {0xD44, 0x0401463F}, + {0xD48, 0x0003FF7F}, + {0xD4C, 0x00000000}, + {0xD50, 0xF64FA0F7}, + {0xD54, 0x04100437}, + {0xD58, 0x0000FF7F}, + {0xD5C, 0x00000000}, + {0xD60, 0x00000000}, + {0xD64, 0x00000000}, + {0xD70, 0x00000015}, + {0xD78, 0x00000001}, + {0xD7C, 0x001D050E}, + {0xD80, 0x00000100}, + {0xD84, 0x00006607}, + {0xD90, 0x000003FF}, + {0xD94, 0x00000000}, + {0xD98, 0x0000003F}, + {0xD9C, 0x00000000}, + {0xDA0, 0x000003FE}, + {0xDA4, 0x00000000}, + {0xDA8, 0x0000003F}, + {0xDAC, 0x00000000}, + {0xDD4, 0x00000000}, + {0x1010, 0x00000000}, + {0x2000, 0x50BBBF04}, + {0x2008, 0x000FFFFF}, + {0x5800, 0x03FF807F}, + {0x5804, 0x04237040}, + {0x5808, 0x04237040}, + {0x5818, 0x082C1800}, + {0x624, 0x0101030A}, + {0x241C, 0x00000001}, + {0xC0F8, 0x00000001}, + {0x35C, 0x000004C4}, + {0x1200, 0x00010142}, + {0x120C, 0x00012233}, + {0x1210, 0x8049E304}, + {0x12A0, 0x49107056}, + {0x12A8, 0x33337025}, + {0x12AC, 0x12333121}, + {0x12B8, 0x30020000}, + {0x0F0, 0x00000001}, + {0x0F4, 0x00000011}, + {0x0F8, 0x20230307}, +}; + +static const struct rtw89_reg2_def rtw89_8851b_phy_bb_reg_gain[] = { + {0xF00100FF, 0x00000000}, + {0xF00200FF, 0x00000001}, + {0xF00300FF, 0x00000002}, + {0xF00400FF, 0x00000003}, + {0xF00500FF, 0x00000004}, + {0xF00600FF, 0x00000005}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x13F6D7B6}, + {0x001, 0x00725132}, + {0x002, 0x00005A38}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x13F6D7B6}, + {0x001, 0x00725132}, + {0x002, 0x00005A38}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x13F6D7B6}, + {0x001, 0x00725132}, + {0x002, 0x00005A38}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x19FADCBC}, + {0x001, 0x007A5A3A}, + {0x002, 0x00005838}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x19FADCBC}, + {0x001, 0x007A5A3A}, + {0x002, 0x00005838}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x000, 0x19FADCBC}, + {0x001, 0x007A5A3A}, + {0x002, 0x00005838}, + {0xA0000000, 0x00000000}, + {0x000, 0x13F6D7B6}, + {0x001, 0x00725132}, + {0x002, 0x00005A38}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0xA0000000, 0x00000000}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x19F8D8C1}, + {0x10001, 0x006F4F31}, + {0x10002, 0x00006F58}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x19F8D8C1}, + {0x10001, 0x006F4F31}, + {0x10002, 0x00006F58}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x19F8D8C1}, + {0x10001, 0x006F4F31}, + {0x10002, 0x00006F58}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x1DF8DAC1}, + {0x10001, 0x00755437}, + {0x10002, 0x00007058}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x1DF8DAC1}, + {0x10001, 0x00755437}, + {0x10002, 0x00007058}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x1DF8DAC1}, + {0x10001, 0x00755437}, + {0x10002, 0x00007058}, + {0xA0000000, 0x00000000}, + {0x10000, 0x19F8D8C1}, + {0x10001, 0x006F4F31}, + {0x10002, 0x00006F58}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0xA0000000, 0x00000000}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1AF0D2B8}, + {0x20001, 0x00755334}, + {0x20002, 0x00006F58}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1AF0D2B8}, + {0x20001, 0x00755334}, + {0x20002, 0x00006F58}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1AF0D2B8}, + {0x20001, 0x00755334}, + {0x20002, 0x00006F58}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1D00E2C8}, + {0x20001, 0x00775336}, + {0x20002, 0x00006D58}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1D00E2C8}, + {0x20001, 0x00775336}, + {0x20002, 0x00006D58}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1D00E2C8}, + {0x20001, 0x00775336}, + {0x20002, 0x00006D58}, + {0xA0000000, 0x00000000}, + {0x20000, 0x1AF0D2B8}, + {0x20001, 0x00755334}, + {0x20002, 0x00006F58}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0xA0000000, 0x00000000}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x15EED2B6}, + {0x30001, 0x006F4D2F}, + {0x30002, 0x00006F58}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x15EED2B6}, + {0x30001, 0x006F4D2F}, + {0x30002, 0x00006F58}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x15EED2B6}, + {0x30001, 0x006F4D2F}, + {0x30002, 0x00006F58}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1F00E2C6}, + {0x30001, 0x00795739}, + {0x30002, 0x00006F58}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1F00E2C6}, + {0x30001, 0x00795739}, + {0x30002, 0x00006F58}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1F00E2C6}, + {0x30001, 0x00795739}, + {0x30002, 0x00006F58}, + {0xA0000000, 0x00000000}, + {0x30000, 0x15EED2B6}, + {0x30001, 0x006F4D2F}, + {0x30002, 0x00006F58}, + {0xB0000000, 0x00000000}, + {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0xA0000000, 0x00000000}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x1000000, 0x000000F4}, + {0x1000010, 0x000000F8}, + {0x1000011, 0x0000F8F8}, + {0x1000100, 0x000000F8}, + {0x1000110, 0x00000000}, + {0x1000111, 0x00000000}, + {0x1010000, 0x000000F4}, + {0x1010010, 0x000000F8}, + {0x1010011, 0x0000F8F8}, + {0x1010020, 0x000000F8}, + {0x1010021, 0x0808E8E8}, + {0x1010029, 0x0000F8F8}, + {0x1010100, 0x000000F4}, + {0x1010110, 0x000000F8}, + {0x1010111, 0x0000F8F8}, + {0x1010120, 0x000000F8}, + {0x1010121, 0x0808E8E8}, + {0x1010129, 0x0000F8F8}, + {0x1020000, 0x000000F4}, + {0x1020010, 0x000000F8}, + {0x1020011, 0x0000F8F8}, + {0x1020020, 0x000000F8}, + {0x1020021, 0x0808E8E8}, + {0x1020029, 0x0000F8F8}, + {0x1020100, 0x000000F4}, + {0x1020110, 0x000000F8}, + {0x1020111, 0x0000F8F8}, + {0x1020120, 0x000000F8}, + {0x1020121, 0x0808E8E8}, + {0x1020129, 0x0000F8F8}, + {0x1030000, 0x000000F4}, + {0x1030010, 0x000000F8}, + {0x1030011, 0x0000F8F8}, + {0x1030020, 0x000000F8}, + {0x1030021, 0x0808E8E8}, + {0x1030029, 0x0000F8F8}, + {0x1030100, 0x000000F4}, + {0x1030110, 0x000000F8}, + {0x1030111, 0x0000F8F8}, + {0x1030120, 0x000000F8}, + {0x1030121, 0x0808E8E8}, + {0x1030129, 0x0000F8F8}, +}; + +static const struct rtw89_reg2_def rtw89_8851b_phy_radioa_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0030000, 0x00000002}, + {0xF0010001, 0x00000003}, + {0xF0020001, 0x00000004}, + {0xF0030001, 0x00000005}, + {0xF0040001, 0x00000006}, + {0xF0050001, 0x00000007}, + {0xF0060001, 0x00000008}, + {0x000, 0x00000000}, + {0x0EF, 0x00080000}, + {0x033, 0x00000003}, + {0x03E, 0x00000150}, + {0x03F, 0x0000D79C}, + {0x0EF, 0x00000000}, + {0x052, 0x000C3338}, + {0x053, 0x000608AF}, + {0x054, 0x00006C04}, + {0x063, 0x000FC082}, + {0x065, 0x00018122}, + {0x000, 0x00010000}, + {0x0FE, 0x0000005A}, + {0x000, 0x00030000}, + {0x018, 0x00013124}, + {0x0EF, 0x00080000}, + {0x033, 0x00000008}, + {0x03E, 0x00000110}, + {0x03F, 0x0000D39C}, + {0x033, 0x0000000C}, + {0x03E, 0x00000110}, + {0x03F, 0x0000F79E}, + {0x0EF, 0x00000000}, + {0x01B, 0x00003A40}, + {0x08F, 0x000C170E}, + {0x08E, 0x00005160}, + {0x002, 0x00000600}, + {0x0EE, 0x00000002}, + {0x033, 0x00000002}, + {0x03F, 0x0000003F}, + {0x033, 0x00000003}, + {0x03F, 0x0000003F}, + {0x033, 0x00000004}, + {0x03F, 0x0000003F}, + {0x033, 0x00000005}, + {0x03F, 0x0000003F}, + {0x033, 0x00000006}, + {0x03F, 0x0000003F}, + {0x033, 0x00000007}, + {0x03F, 0x0000003F}, + {0x033, 0x00000008}, + {0x03F, 0x0000003F}, + {0x033, 0x0000000C}, + {0x03F, 0x0000003F}, + {0x033, 0x0000000D}, + {0x03F, 0x0000003F}, + {0x033, 0x0000000E}, + {0x03F, 0x0000003F}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00004000}, + {0x033, 0x00000007}, + {0x03E, 0x00000000}, + {0x03F, 0x00000707}, + {0x033, 0x00000006}, + {0x03E, 0x00000000}, + {0x03F, 0x00000704}, + {0x033, 0x00000005}, + {0x03E, 0x00000000}, + {0x03F, 0x00020500}, + {0x033, 0x00000004}, + {0x03E, 0x00000000}, + {0x03F, 0x00010404}, + {0x033, 0x00000003}, + {0x03E, 0x00000000}, + {0x03F, 0x00099B04}, + {0x033, 0x00000002}, + {0x03E, 0x00000000}, + {0x03F, 0x00092B04}, + {0x033, 0x00000001}, + {0x03E, 0x00000000}, + {0x03F, 0x000B3204}, + {0x033, 0x00000000}, + {0x03E, 0x00000000}, + {0x03F, 0x00003000}, + {0x033, 0x00000017}, + {0x03E, 0x00000000}, + {0x03F, 0x00000787}, + {0x033, 0x00000016}, + {0x03E, 0x00000000}, + {0x03F, 0x00000784}, + {0x033, 0x00000015}, + {0x03E, 0x00000000}, + {0x03F, 0x00020580}, + {0x033, 0x00000014}, + {0x03E, 0x00000000}, + {0x03F, 0x00010484}, + {0x033, 0x00000013}, + {0x03E, 0x00000000}, + {0x03F, 0x00099B84}, + {0x033, 0x00000012}, + {0x03E, 0x00000000}, + {0x03F, 0x00092B84}, + {0x033, 0x00000011}, + {0x03E, 0x00000000}, + {0x03F, 0x000B3284}, + {0x033, 0x00000010}, + {0x03E, 0x00000000}, + {0x03F, 0x00003080}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000034}, + {0x033, 0x00000001}, + {0x03F, 0x00000037}, + {0x033, 0x00000002}, + {0x03F, 0x00000034}, + {0x033, 0x00000003}, + {0x03F, 0x00000024}, + {0x033, 0x00000004}, + {0x03F, 0x00000037}, + {0x033, 0x00000005}, + {0x03F, 0x00000027}, + {0x0EF, 0x00000000}, + {0x0EC, 0x00000400}, + {0x033, 0x00000001}, + {0x03F, 0x00000022}, + {0x033, 0x00000003}, + {0x03F, 0x00000022}, + {0x033, 0x00000009}, + {0x03F, 0x00000022}, + {0x0EC, 0x00000000}, + {0x0EC, 0x00000004}, + {0x033, 0x00000000}, + {0x03F, 0x000000AE}, + {0x033, 0x00000001}, + {0x03F, 0x0000008C}, + {0x033, 0x00000002}, + {0x03F, 0x0000006A}, + {0x033, 0x00000003}, + {0x03F, 0x00000048}, + {0x033, 0x00000004}, + {0x03F, 0x00000026}, + {0x033, 0x00000005}, + {0x03F, 0x00000004}, + {0x033, 0x00000006}, + {0x03F, 0x00000002}, + {0x033, 0x00000007}, + {0x03F, 0x00000000}, + {0x0EC, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000007}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000006}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000005}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x00000004}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x00000003}, + {0x03E, 0x00000003}, + {0x03F, 0x00001BB0}, + {0x033, 0x00000002}, + {0x03E, 0x00000003}, + {0x03F, 0x00001AB0}, + {0x033, 0x00000001}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D9BC}, + {0x033, 0x00000000}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D4BC}, + {0x033, 0x00000017}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000016}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000015}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x00000014}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x00000013}, + {0x03E, 0x00000003}, + {0x03F, 0x00001BB0}, + {0x033, 0x00000012}, + {0x03E, 0x00000003}, + {0x03F, 0x00001AB0}, + {0x033, 0x00000011}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D9BC}, + {0x033, 0x00000010}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D4BC}, + {0x033, 0x00000027}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000026}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x00000025}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x00000024}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x00000023}, + {0x03E, 0x00000003}, + {0x03F, 0x00001BB0}, + {0x033, 0x00000022}, + {0x03E, 0x00000003}, + {0x03F, 0x00001AB0}, + {0x033, 0x00000021}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D9BC}, + {0x033, 0x00000020}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D4BC}, + {0x033, 0x0000000E}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x0000000D}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x0000000C}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x0000000B}, + {0x03E, 0x00000003}, + {0x03F, 0x00091BB0}, + {0x033, 0x0000000A}, + {0x03E, 0x00000003}, + {0x03F, 0x000A9AB0}, + {0x033, 0x00000009}, + {0x03E, 0x00000003}, + {0x03F, 0x000BD9BC}, + {0x033, 0x00000008}, + {0x03E, 0x00000003}, + {0x03F, 0x0009D4BC}, + {0x033, 0x0000001E}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x0000001D}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x0000001C}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x0000001B}, + {0x03E, 0x00000003}, + {0x03F, 0x00091BB0}, + {0x033, 0x0000001A}, + {0x03E, 0x00000003}, + {0x03F, 0x00099AB0}, + {0x033, 0x00000019}, + {0x03E, 0x00000003}, + {0x03F, 0x000AD9BC}, + {0x033, 0x00000018}, + {0x03E, 0x00000003}, + {0x03F, 0x0009D4BC}, + {0x033, 0x0000002E}, + {0x03E, 0x00000003}, + {0x03F, 0x00001FB0}, + {0x033, 0x0000002D}, + {0x03E, 0x00000003}, + {0x03F, 0x00001DB0}, + {0x033, 0x0000002C}, + {0x03E, 0x00000003}, + {0x03F, 0x00001CB0}, + {0x033, 0x0000002B}, + {0x03E, 0x00000003}, + {0x03F, 0x00001BB0}, + {0x033, 0x0000002A}, + {0x03E, 0x00000003}, + {0x03F, 0x00009AB0}, + {0x033, 0x00000029}, + {0x03E, 0x00000003}, + {0x03F, 0x0009D9BC}, + {0x033, 0x00000028}, + {0x03E, 0x00000003}, + {0x03F, 0x0000D4BC}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00002000}, + {0x033, 0x00000000}, + {0x03F, 0x00000005}, + {0x033, 0x00000001}, + {0x03F, 0x00000004}, + {0x033, 0x00000002}, + {0x03F, 0x00000004}, + {0x033, 0x00000004}, + {0x03F, 0x0000000C}, + {0x033, 0x00000005}, + {0x03F, 0x00000003}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x06C, 0x00038085}, + {0x06D, 0x00000D6B}, + {0x06E, 0x0001FB89}, + {0x06F, 0x00097B99}, + {0x069, 0x00008040}, + {0x0EF, 0x00000200}, + {0x033, 0x00000004}, + {0x03F, 0x000008FF}, + {0x033, 0x00000005}, + {0x03F, 0x000004F2}, + {0x033, 0x00000006}, + {0x03F, 0x00000217}, + {0x033, 0x00000007}, + {0x03F, 0x00000131}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000004}, + {0x03F, 0x000004F7}, + {0x033, 0x00000005}, + {0x03F, 0x000004F7}, + {0x033, 0x00000006}, + {0x03F, 0x000004F2}, + {0x033, 0x00000007}, + {0x03F, 0x00000117}, + {0x0EF, 0x00000000}, + {0x043, 0x00005000}, + {0x036, 0x000147D0}, + {0x0B0, 0x0008677C}, + {0x0B1, 0x00012920}, + {0x0BB, 0x000EF000}, + {0x0CB, 0x000A9594}, + {0x0CC, 0x000C36D2}, + {0x0CD, 0x00024923}, + {0x0CE, 0x00020180}, + {0x0CF, 0x00000000}, + {0x0D5, 0x0006E27A}, + {0x0D8, 0x00000044}, + {0x0D9, 0x00000007}, + {0x0DD, 0x00000020}, + {0x0E3, 0x0000002C}, + {0x0B7, 0x0000000C}, + {0x0E1, 0x000080C0}, + {0x0E4, 0x00000380}, + {0x0ED, 0x00002000}, + {0x033, 0x00000001}, + {0x03D, 0x000A6094}, + {0x03E, 0x00003449}, + {0x03F, 0x00000001}, + {0x033, 0x00000003}, + {0x03D, 0x000AA094}, + {0x03E, 0x00003449}, + {0x03F, 0x00000001}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00000100}, + {0x033, 0x00000000}, + {0x03F, 0x0000007F}, + {0x033, 0x00000001}, + {0x03F, 0x0000007F}, + {0x033, 0x00000002}, + {0x03F, 0x0000007F}, + {0x033, 0x00000003}, + {0x03F, 0x0000007F}, + {0x033, 0x00000004}, + {0x03F, 0x0000007F}, + {0x033, 0x00000005}, + {0x03F, 0x0000007F}, + {0x033, 0x00000007}, + {0x03F, 0x0000007F}, + {0x033, 0x00000008}, + {0x03F, 0x0000007F}, + {0x033, 0x00000009}, + {0x03F, 0x0000007F}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x033, 0x00000010}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x033, 0x00000030}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x033, 0x00000040}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x033, 0x00000050}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x033, 0x00000070}, + {0x03E, 0x000007E1}, + {0x03F, 0x0001F87F}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00000004}, + {0x033, 0x00000000}, + {0x03F, 0x00008420}, + {0x0ED, 0x00000000}, + {0x018, 0x00011108}, + {0x0B9, 0x00000000}, + {0x0B9, 0x00000000}, + {0x0B9, 0x00000200}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0FF, 0x00000000}, + {0x0B9, 0x00000000}, + {0x018, 0x00013124}, + {0x05A, 0x0006808F}, + {0x0ED, 0x00000008}, + {0x033, 0x00000001}, + {0x03F, 0x0000000F}, + {0x0ED, 0x00000000}, + {0x000, 0x00020000}, + {0x018, 0x00010124}, + {0x0EE, 0x00000800}, + {0x033, 0x00000004}, + {0x03F, 0x00000002}, + {0x033, 0x00000005}, + {0x03F, 0x00000003}, + {0x033, 0x00000006}, + {0x03F, 0x00000006}, + {0x033, 0x00000007}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000008}, + {0x03F, 0x00000000}, + {0x033, 0x00000009}, + {0x03F, 0x00000001}, + {0x033, 0x0000000A}, + {0x03F, 0x00000003}, + {0x033, 0x0000000B}, + {0x03F, 0x00000103}, + {0x033, 0x0000000C}, + {0x03F, 0x00000107}, + {0x033, 0x0000000D}, + {0x03F, 0x00000207}, + {0x033, 0x0000000E}, + {0x03F, 0x00000307}, + {0x033, 0x0000000F}, + {0x03F, 0x00000307}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00000200}, + {0x033, 0x00000004}, + {0x03F, 0x00000000}, + {0x033, 0x00000005}, + {0x03F, 0x00000001}, + {0x033, 0x00000006}, + {0x03F, 0x00000002}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x0EE, 0x00000000}, + {0x011, 0x00014062}, + {0x0EF, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x00000DF3}, + {0x033, 0x00000002}, + {0x03F, 0x00000DF3}, + {0x033, 0x00000003}, + {0x03F, 0x00000A83}, + {0x033, 0x00000004}, + {0x03F, 0x00000A83}, + {0x033, 0x00000005}, + {0x03F, 0x00000643}, + {0x033, 0x00000006}, + {0x03F, 0x00000643}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000001}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000002}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000003}, + {0x03F, 0x0001B5A9}, + {0x033, 0x00000004}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000005}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000006}, + {0x03F, 0x0001B589}, + {0x033, 0x00000007}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000008}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000009}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000000A}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000000B}, + {0x03F, 0x0001B5A9}, + {0x033, 0x0000000C}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000000D}, + {0x03F, 0x0001B5A9}, + {0x033, 0x0000000E}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000000F}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000010}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000011}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000012}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000013}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000014}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000015}, + {0x03F, 0x0001B589}, + {0x033, 0x00000016}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000017}, + {0x03F, 0x0001B5A9}, + {0x033, 0x00000018}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000019}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001A}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001B}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001C}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001D}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001E}, + {0x03F, 0x0001B5A8}, + {0x033, 0x0000001F}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000020}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000021}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000022}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000023}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000024}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000025}, + {0x03F, 0x0001B5A8}, + {0x033, 0x00000022}, + {0x03F, 0x0001B5A8}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000001}, + {0x03F, 0x000002C5}, + {0x033, 0x00000002}, + {0x03F, 0x000002C5}, + {0x033, 0x00000003}, + {0x03F, 0x000002C5}, + {0x033, 0x00000004}, + {0x03F, 0x000002C5}, + {0x033, 0x00000005}, + {0x03F, 0x000002C5}, + {0x033, 0x00000006}, + {0x03F, 0x000002C5}, + {0x033, 0x00000007}, + {0x03F, 0x000002C5}, + {0x033, 0x00000008}, + {0x03F, 0x000002C5}, + {0x033, 0x00000009}, + {0x03F, 0x000002C5}, + {0x033, 0x0000000A}, + {0x03F, 0x000002C5}, + {0x033, 0x0000000B}, + {0x03F, 0x000002C5}, + {0x0EF, 0x00000000}, + {0x059, 0x00050033}, + {0x061, 0x0005F48A}, + {0x062, 0x00077435}, + {0x067, 0x00008060}, + {0x07E, 0x0009780B}, + {0x0EE, 0x00000004}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x033, 0x0000000F}, + {0x03F, 0x0000000B}, + {0x033, 0x00000010}, + {0x03F, 0x00000012}, + {0x033, 0x00000011}, + {0x03F, 0x00000019}, + {0x03F, 0x00000000}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000001}, + {0x03F, 0x00000002}, + {0x033, 0x00000002}, + {0x03F, 0x00000003}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00003000}, + {0x033, 0x00000001}, + {0x03F, 0x00000000}, + {0x033, 0x00000002}, + {0x03F, 0x00000001}, + {0x033, 0x00000003}, + {0x03F, 0x00000003}, + {0x033, 0x00000004}, + {0x03F, 0x00000007}, + {0x033, 0x00000005}, + {0x03F, 0x0000000F}, + {0x033, 0x00000006}, + {0x03F, 0x0000010F}, + {0x033, 0x00000007}, + {0x03F, 0x0000030F}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x00000004}, + {0x033, 0x00000001}, + {0x03F, 0x00000005}, + {0x033, 0x00000002}, + {0x03F, 0x00000006}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000004}, + {0x03E, 0x0000001D}, + {0x03F, 0x0001A241}, + {0x033, 0x00000005}, + {0x03E, 0x0000001D}, + {0x03F, 0x0001A241}, + {0x033, 0x00000006}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000007}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000008}, + {0x03E, 0x0000001D}, + {0x03F, 0x0001A241}, + {0x033, 0x00000009}, + {0x03E, 0x0001A241}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000000A}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000000B}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000000C}, + {0x03E, 0x0000001D}, + {0x03F, 0x0001A241}, + {0x033, 0x0000000D}, + {0x03E, 0x0000001D}, + {0x03F, 0x0001A241}, + {0x033, 0x0000000E}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000000F}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000010}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000011}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000012}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000013}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000014}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000015}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000016}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000017}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000018}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000019}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x0000001A}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000001B}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000001C}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x0000001D}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x0000001E}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000001F}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000020}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000021}, + {0x03E, 0x0000001C}, + {0x03F, 0x000199C1}, + {0x033, 0x00000022}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000023}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000024}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000025}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000026}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000027}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000028}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000029}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x0000002A}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000002B}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000002C}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x0000002D}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x0000002E}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000002F}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000030}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000031}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000032}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000033}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000034}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000035}, + {0x03E, 0x0000001C}, + {0x03F, 0x0001E141}, + {0x033, 0x00000036}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000037}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000038}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x00000039}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C1}, + {0x033, 0x0000003A}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x033, 0x0000003B}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x033, 0x0000003C}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x033, 0x0000003D}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x033, 0x0000003E}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x033, 0x0000003F}, + {0x03E, 0x0000001B}, + {0x03F, 0x0001C3C3}, + {0x0EF, 0x00000000}, + {0x051, 0x0003D368}, + {0x058, 0x00084221}, + {0x05B, 0x000EB000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000000F9}, + {0x10030, 0x000004F6}, + {0x10030, 0x000008F3}, + {0x10030, 0x00000CF0}, + {0x10030, 0x000010ED}, + {0x10030, 0x000014EA}, + {0x10030, 0x000018E7}, + {0x10030, 0x00001CE4}, + {0x10030, 0x000020E1}, + {0x10030, 0x000024A4}, + {0x10030, 0x000028A1}, + {0x10030, 0x00002C9E}, + {0x10030, 0x0000309B}, + {0x10030, 0x0000341E}, + {0x10030, 0x0000381B}, + {0x10030, 0x00003C18}, + {0x10030, 0x00004015}, + {0x10030, 0x000200BC}, + {0x10030, 0x000204B9}, + {0x10030, 0x000208B6}, + {0x10030, 0x00020CB3}, + {0x10030, 0x000210B0}, + {0x10030, 0x000214AD}, + {0x10030, 0x0002186C}, + {0x10030, 0x00021C69}, + {0x10030, 0x00022066}, + {0x10030, 0x00022426}, + {0x10030, 0x00022823}, + {0x10030, 0x00022C20}, + {0x10030, 0x0002301D}, + {0x10030, 0x0002341A}, + {0x10030, 0x00023817}, + {0x10030, 0x00023C14}, + {0x10030, 0x00024011}, + {0x10030, 0x000280BC}, + {0x10030, 0x000284B9}, + {0x10030, 0x000288B6}, + {0x10030, 0x00028CB3}, + {0x10030, 0x000290B0}, + {0x10030, 0x000294AD}, + {0x10030, 0x0002986C}, + {0x10030, 0x00029C69}, + {0x10030, 0x0002A066}, + {0x10030, 0x0002A426}, + {0x10030, 0x0002A823}, + {0x10030, 0x0002AC20}, + {0x10030, 0x0002B01D}, + {0x10030, 0x0002B41A}, + {0x10030, 0x0002B817}, + {0x10030, 0x0002BC14}, + {0x10030, 0x0002C011}, + {0x10030, 0x000300BC}, + {0x10030, 0x000304B9}, + {0x10030, 0x000308B6}, + {0x10030, 0x00030CB3}, + {0x10030, 0x000310B0}, + {0x10030, 0x000314AD}, + {0x10030, 0x0003186C}, + {0x10030, 0x00031C69}, + {0x10030, 0x00032066}, + {0x10030, 0x00032426}, + {0x10030, 0x00032823}, + {0x10030, 0x00032C20}, + {0x10030, 0x0003301D}, + {0x10030, 0x0003341A}, + {0x10030, 0x00033817}, + {0x10030, 0x00033C14}, + {0x10030, 0x00034011}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DDD}, + {0x10030, 0x000211D7}, + {0x10030, 0x000215D1}, + {0x10030, 0x00021919}, + {0x10030, 0x00021D13}, + {0x10030, 0x000220D9}, + {0x10030, 0x000224D3}, + {0x10030, 0x00022899}, + {0x10030, 0x00022C93}, + {0x10030, 0x00023059}, + {0x10030, 0x00023453}, + {0x10030, 0x00023819}, + {0x10030, 0x00023C13}, + {0x10030, 0x0002400D}, + {0x10030, 0x00024407}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E9}, + {0x10030, 0x000289E3}, + {0x10030, 0x00028DDD}, + {0x10030, 0x000291D7}, + {0x10030, 0x000295D1}, + {0x10030, 0x00029919}, + {0x10030, 0x00029D13}, + {0x10030, 0x0002A0D9}, + {0x10030, 0x0002A4D3}, + {0x10030, 0x0002A899}, + {0x10030, 0x0002AC93}, + {0x10030, 0x0002B059}, + {0x10030, 0x0002B453}, + {0x10030, 0x0002B819}, + {0x10030, 0x0002BC13}, + {0x10030, 0x0002C00D}, + {0x10030, 0x0002C407}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E9}, + {0x10030, 0x000309E3}, + {0x10030, 0x00030DDD}, + {0x10030, 0x000311D7}, + {0x10030, 0x000315D1}, + {0x10030, 0x00031919}, + {0x10030, 0x00031D13}, + {0x10030, 0x000320D9}, + {0x10030, 0x000324D3}, + {0x10030, 0x00032899}, + {0x10030, 0x00032C93}, + {0x10030, 0x00033059}, + {0x10030, 0x00033453}, + {0x10030, 0x00033819}, + {0x10030, 0x00033C13}, + {0x10030, 0x0003400D}, + {0x10030, 0x00034407}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011A5}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001965}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002125}, + {0x10030, 0x0000251F}, + {0x10030, 0x000028E5}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030A5}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003865}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004025}, + {0x10030, 0x0000441F}, + {0x100EE, 0x00000000}, + {0x0EF, 0x00000008}, + {0x033, 0x00000000}, + {0x03F, 0x00000004}, + {0x0EF, 0x00000000}, + {0x000, 0x00010000}, + {0x0FE, 0x0000005A}, + {0x005, 0x00000001}, + {0x10005, 0x00000001}, + {0x0FE, 0x00000028}, +}; + +static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = { + {0x8000, 0x00000008}, + {0x8008, 0x00000000}, + {0x8004, 0xe8862b66}, + {0x800c, 0x78000000}, + {0x8010, 0x88015000}, + {0x8014, 0x80010100}, + {0x8018, 0x10010100}, + {0x801c, 0xa210bc00}, + {0x8020, 0x000403e0}, + {0x8024, 0x00072160}, + {0x8028, 0x00180e00}, + {0x8030, 0x400000c0}, + {0x8034, 0x11000830}, + {0x8038, 0x40000000}, + {0x803c, 0x00000008}, + {0x8040, 0x00000046}, + {0x8044, 0x0010001f}, + {0x8048, 0x00000003}, + {0x804c, 0x420840e0}, + {0x8050, 0xce08cce0}, + {0x8054, 0x420840e0}, + {0x8058, 0xce08cce0}, + {0x805c, 0x150c0b02}, + {0x8060, 0x150c0b02}, + {0x8064, 0x2aa00047}, + {0x8074, 0x80000000}, + {0x807c, 0x000000ee}, + {0x8088, 0x80000000}, + {0x808c, 0x00000000}, + {0x80b0, 0x00000000}, + {0x80cc, 0x00000000}, + {0x80d0, 0x00000000}, + {0x80ec, 0x00000002}, + {0x8098, 0x0000ff00}, + {0x8070, 0x00e80000}, + {0x80b0, 0xffe00fff}, + {0x809c, 0x0000001f}, + {0x80b8, 0x00002000}, + {0x80bc, 0x00050033}, + {0xa400, 0x00000000}, + {0xa404, 0x00000180}, + {0xa408, 0x000001af}, + {0xa40c, 0x000001e3}, + {0xa410, 0x00000220}, + {0xa414, 0x00000262}, + {0xa418, 0x000002ac}, + {0xa41c, 0x0000035e}, + {0xa420, 0x000003c7}, + {0xa424, 0x0000043d}, + {0xa428, 0x000004c1}, + {0xa42c, 0x00000556}, + {0xa430, 0x000005fc}, + {0xa434, 0x000006b7}, + {0xa438, 0x00000789}, + {0xa43c, 0x00000875}, + {0xa440, 0x0000011f}, + {0x8104, 0x00000000}, + {0x810c, 0x00000000}, + {0x8110, 0x00000000}, + {0x8114, 0x00000000}, + {0x8120, 0x10010000}, + {0x8124, 0x00000000}, + {0x8128, 0x00000200}, + {0x812c, 0x0000c000}, + {0x8130, 0x40000000}, + {0x8138, 0x40000000}, + {0x813c, 0x40000000}, + {0x8140, 0x00000000}, + {0x8144, 0x0b040b03}, + {0x8148, 0x07020a04}, + {0x814c, 0x07020a04}, + {0x8150, 0xe4e40000}, + {0x8158, 0xffffffff}, + {0x815c, 0xffffffff}, + {0x8160, 0xffffffff}, + {0x8164, 0xffffffff}, + {0x8168, 0xffffffff}, + {0x816c, 0x1fffffff}, + {0x81cc, 0x00000000}, + {0x81dc, 0x00000002}, + {0x81e0, 0x00000000}, + {0x81e4, 0x00000001}, + {0x81a0, 0x00000000}, + {0x81ac, 0x3fc20400}, + {0x81b0, 0x3f914100}, + {0x81bc, 0x0000005b}, + {0x81c0, 0x0000005b}, + {0x81b4, 0x01e0f078}, + {0x81b8, 0x01e0f078}, + {0x81f0, 0x0000f078}, + {0x81d8, 0x00000001}, + {0x9500, 0x00000000}, + {0x9504, 0x00000000}, + {0x9508, 0x00000000}, + {0x950c, 0x00000000}, + {0x9510, 0x00000000}, + {0x9514, 0x00000000}, + {0x9518, 0x00000000}, + {0x951c, 0x00000000}, + {0x9520, 0x00000000}, + {0x9524, 0x00000000}, + {0x9528, 0x00000000}, + {0x952c, 0x00000000}, + {0x9530, 0x00000000}, + {0x9534, 0x00000000}, + {0x9538, 0x00000000}, + {0x953c, 0x00000000}, + {0x9540, 0x04000000}, + {0x9544, 0x00000000}, + {0x9548, 0x00000000}, + {0x954c, 0x00000000}, + {0x9550, 0x00000000}, + {0x9554, 0x00000000}, + {0x9558, 0x00000000}, + {0x955c, 0x00000000}, + {0x9560, 0x00000000}, + {0x9564, 0x00000000}, + {0x9568, 0x00000000}, + {0x956c, 0x00000000}, + {0x9570, 0x00000000}, + {0x9574, 0x00000000}, + {0x9578, 0x00000000}, + {0x957c, 0x00000000}, + {0x9580, 0x00000000}, + {0x9584, 0x04000000}, + {0x9588, 0x00000000}, + {0x958c, 0x00000000}, + {0x9590, 0x00000000}, + {0x9594, 0x00000000}, + {0x9598, 0x00000000}, + {0x959c, 0x00000000}, + {0x95a0, 0x00000000}, + {0x95a4, 0x00000000}, + {0x95a8, 0x00000000}, + {0x95ac, 0x00000000}, + {0x95b0, 0x00000000}, + {0x95b4, 0x00000000}, + {0x95b8, 0x00000000}, + {0x95bc, 0x00000000}, + {0x95c0, 0x00000000}, + {0x95c4, 0x00000000}, + {0x95c8, 0x04000000}, + {0x95cc, 0x00000000}, + {0x95d0, 0x00000000}, + {0x95d4, 0x00000000}, + {0x95d8, 0x00000000}, + {0x95dc, 0x00000000}, + {0x95e0, 0x00000000}, + {0x95e4, 0x00000000}, + {0x95e8, 0x00000000}, + {0x95ec, 0x00000000}, + {0x95f0, 0x00000000}, + {0x95f4, 0x00000000}, + {0x95f8, 0x00000000}, + {0x95fc, 0x00000000}, + {0x9600, 0x00000000}, + {0x9604, 0x00000000}, + {0x9608, 0x00000000}, + {0x960c, 0x04000000}, + {0x9610, 0x00000000}, + {0x9614, 0x00000000}, + {0x9618, 0x00000000}, + {0x961c, 0x00000000}, + {0x9620, 0x00000000}, + {0x9624, 0x00000000}, + {0x9628, 0x00000000}, + {0x962c, 0x00000000}, + {0x9630, 0x00000000}, + {0x9634, 0x00000000}, + {0x9638, 0x00000000}, + {0x963c, 0x00000000}, + {0x9640, 0x00000000}, + {0x9644, 0x00000000}, + {0x9648, 0x00000000}, + {0x964c, 0x00000000}, + {0x9650, 0x04000000}, + {0x9654, 0x00000000}, + {0x9658, 0x00000000}, + {0x965c, 0x00000000}, + {0x9660, 0x00000000}, + {0x9664, 0x00000000}, + {0x9668, 0x00000000}, + {0x966c, 0x00000000}, + {0x9670, 0x00000000}, + {0x9674, 0x00000000}, + {0x9678, 0x00000000}, + {0x967c, 0x00000000}, + {0x9680, 0x00000000}, + {0x9684, 0x00000000}, + {0x9688, 0x00000000}, + {0x968c, 0x00000000}, + {0x9690, 0x00000000}, + {0x9694, 0x04000000}, + {0x9698, 0x00000000}, + {0x969c, 0x00000000}, + {0x96a0, 0x00000000}, + {0x96a4, 0x00000000}, + {0x96a8, 0x00000000}, + {0x96ac, 0x00000000}, + {0x96b0, 0x00000000}, + {0x96b4, 0x00000000}, + {0x96b8, 0x00000000}, + {0x96bc, 0x00000000}, + {0x96c0, 0x00000000}, + {0x96c4, 0x00000000}, + {0x96c8, 0x00000000}, + {0x96cc, 0x00000000}, + {0x96d0, 0x00000000}, + {0x96d4, 0x00000000}, + {0x96d8, 0x04000000}, + {0x96dc, 0x00000000}, + {0x96e0, 0x00000000}, + {0x96e4, 0x00000000}, + {0x96e8, 0x00000000}, + {0x96ec, 0x00000000}, + {0x96f0, 0x00000000}, + {0x96f4, 0x00000000}, + {0x96f8, 0x00000000}, + {0x96fc, 0x00000000}, + {0x9700, 0x00000000}, + {0x9704, 0x00000000}, + {0x9708, 0x00000000}, + {0x970c, 0x00000000}, + {0x9710, 0x00000000}, + {0x9714, 0x00000000}, + {0x9718, 0x00000000}, + {0x971c, 0x04000000}, + {0x9720, 0x00000000}, + {0x9724, 0x00000000}, + {0x9728, 0x00000000}, + {0x972c, 0x00000000}, + {0x9730, 0x00000000}, + {0x9734, 0x00000000}, + {0x9738, 0x00000000}, + {0x973c, 0x00000000}, + {0x9740, 0x00000000}, + {0x9744, 0x00000000}, + {0x9748, 0x00000000}, + {0x974c, 0x00000000}, + {0x9750, 0x00000000}, + {0x9754, 0x00000000}, + {0x9758, 0x00000000}, + {0x975c, 0x00000000}, + {0x9760, 0x04000000}, + {0x9764, 0x00000000}, + {0x9768, 0x00000000}, + {0x976c, 0x00000000}, + {0x9770, 0x00000000}, + {0x9774, 0x00000000}, + {0x9778, 0x00000000}, + {0x977c, 0x00000000}, + {0x9780, 0x00000000}, + {0x9784, 0x00000000}, + {0x9788, 0x00000000}, + {0x978c, 0x00000000}, + {0x9790, 0x00000000}, + {0x9794, 0x00000000}, + {0x9798, 0x00000000}, + {0x979c, 0x00000000}, + {0x97a0, 0x00000000}, + {0x97a4, 0x04000000}, + {0x97a8, 0x00000000}, + {0x97ac, 0x00000000}, + {0x97b0, 0x00000000}, + {0x97b4, 0x00000000}, + {0x97b8, 0x00000000}, + {0x97bc, 0x00000000}, + {0x97c0, 0x00000000}, + {0x97c4, 0x00000000}, + {0x97c8, 0x00000000}, + {0x97cc, 0x00000000}, + {0x97d0, 0x00000000}, + {0x97d4, 0x00000000}, + {0x97d8, 0x00000000}, + {0x97dc, 0x00000000}, + {0x97e0, 0x00000000}, + {0x97e4, 0x00000000}, + {0x97e8, 0x04000000}, + {0x97ec, 0x00000000}, + {0x97f0, 0x00000000}, + {0x97f4, 0x00000000}, + {0x97f8, 0x00000000}, + {0x97fc, 0x00000000}, + {0x9800, 0x00000000}, + {0x9804, 0x00000000}, + {0x9808, 0x00000000}, + {0x980c, 0x00000000}, + {0x9810, 0x00000000}, + {0x9814, 0x00000000}, + {0x9818, 0x00000000}, + {0x981c, 0x00000000}, + {0x9820, 0x00000000}, + {0x9824, 0x00000000}, + {0x9828, 0x00000000}, + {0x982c, 0x04000000}, + {0x81d8, 0x00000000}, + {0xb104, 0x2b251f19}, + {0xb108, 0x433d3731}, + {0xb10c, 0x5b554f49}, + {0xb110, 0x736d6761}, + {0xb114, 0x7f7f7f79}, + {0xb118, 0x120f7f7f}, + {0xb11c, 0x1e1b1815}, + {0xb120, 0x2a272421}, + {0xb124, 0x3633302d}, + {0xb128, 0x3f3f3c39}, + {0xb12c, 0x3f3f3f3f}, + {0x8088, 0x00000110}, + {0x8000, 0x00000008}, + {0x8080, 0x00000005}, + {0x8500, 0x80000008}, + {0x8504, 0x43000004}, + {0x8508, 0x4b044a00}, + {0x850c, 0x40098604}, + {0x8510, 0x0004e01f}, + {0x8514, 0x74104b00}, + {0x8518, 0x000021e0}, + {0x851c, 0x74301658}, + {0x8520, 0x43800004}, + {0x8524, 0x4c000007}, + {0x8528, 0x43000004}, + {0x852c, 0x56030007}, + {0x8530, 0x57000004}, + {0x8534, 0x400042fe}, + {0x8538, 0x50554200}, + {0x853c, 0xb4183000}, + {0x8540, 0xe535a50f}, + {0x8544, 0xf12bf02b}, + {0x8548, 0xf32bf22b}, + {0x854c, 0xf62bf42b}, + {0x8550, 0xf82bf72b}, + {0x8554, 0xfa2bf92b}, + {0x8558, 0xfd2bfc2b}, + {0x855c, 0xe535fe2b}, + {0x8560, 0xf12af02a}, + {0x8564, 0xf32af22a}, + {0x8568, 0xf52af42a}, + {0x856c, 0x000bf62a}, + {0x8570, 0xf028a511}, + {0x8574, 0xf228f128}, + {0x8578, 0xf428f328}, + {0x857c, 0xf628f528}, + {0x8580, 0xf828f728}, + {0x8584, 0xfa28f928}, + {0x8588, 0xfc28fb28}, + {0x858c, 0xfe28fd28}, + {0x8590, 0xf028ff28}, + {0x8594, 0xf228f128}, + {0x8598, 0x30750001}, + {0x859c, 0x30753075}, + {0x85a0, 0x30b63097}, + {0x85a4, 0x30be30bb}, + {0x85a8, 0x30d930cc}, + {0x85ac, 0x316d30e6}, + {0x85b0, 0x3189317f}, + {0x85b4, 0x31d23193}, + {0x85b8, 0x31e43210}, + {0x85bc, 0x31e831dd}, + {0x85c0, 0x322831e1}, + {0x85c4, 0x323c3232}, + {0x85c8, 0x32503246}, + {0x85cc, 0x3264325a}, + {0x85d0, 0x3278326e}, + {0x85d4, 0x32983285}, + {0x85d8, 0x32aa32a6}, + {0x85dc, 0x330b32f3}, + {0x85e0, 0x333f330c}, + {0x85e4, 0x334c3341}, + {0x85e8, 0xe35e0001}, + {0x85ec, 0x20887410}, + {0x85f0, 0x140f0200}, + {0x85f4, 0x02002098}, + {0x85f8, 0x7430140f}, + {0x85fc, 0x5b10e39c}, + {0x8600, 0x20807410}, + {0x8604, 0x140f0000}, + {0x8608, 0x56015507}, + {0x860c, 0x7410e382}, + {0x8610, 0x02002088}, + {0x8614, 0x5517140f}, + {0x8618, 0xe34ee382}, + {0x861c, 0x468e7508}, + {0x8620, 0xe0ace38c}, + {0x8624, 0x5500f0e2}, + {0x8628, 0x5501e37e}, + {0x862c, 0x5b10f1de}, + {0x8630, 0x20907410}, + {0x8634, 0x140f0000}, + {0x8638, 0xe3825507}, + {0x863c, 0x20987410}, + {0x8640, 0x140f0200}, + {0x8644, 0xe3825517}, + {0x8648, 0x46967509}, + {0x864c, 0xe0ace38c}, + {0x8650, 0xe37e5500}, + {0x8654, 0x00015501}, + {0x8658, 0x4d000007}, + {0x865c, 0x74200004}, + {0x8660, 0x57005710}, + {0x8664, 0x9700140f}, + {0x8668, 0x00017430}, + {0x866c, 0xe39ce35e}, + {0x8670, 0xe5280bbd}, + {0x8674, 0xe36a0001}, + {0x8678, 0x0001e3c4}, + {0x867c, 0x55005b30}, + {0x8680, 0x46500005}, + {0x8684, 0x74000004}, + {0x8688, 0x1658e37e}, + {0x868c, 0x74305501}, + {0x8690, 0x46100005}, + {0x8694, 0x00010004}, + {0x8698, 0x30f8e35e}, + {0x869c, 0xe5280023}, + {0x86a0, 0x54ed0002}, + {0x86a4, 0x00230baa}, + {0x86a8, 0x0002e528}, + {0x86ac, 0xe356e3e4}, + {0x86b0, 0xe35e0001}, + {0x86b4, 0x002230f3}, + {0x86b8, 0x0002e528}, + {0x86bc, 0x0baa54ec}, + {0x86c0, 0xe5280022}, + {0x86c4, 0xe3e40002}, + {0x86c8, 0x0001e356}, + {0x86cc, 0x0baae35e}, + {0x86d0, 0xe3e430ec}, + {0x86d4, 0x0001e356}, + {0x86d8, 0x6d0f6c67}, + {0x86dc, 0xe528e39c}, + {0x86e0, 0xe39c6c8b}, + {0x86e4, 0x0bace528}, + {0x86e8, 0x6d0f6cb3}, + {0x86ec, 0xe528e39c}, + {0x86f0, 0x6cdb0bad}, + {0x86f4, 0xe39c6d0f}, + {0x86f8, 0x6cf5e528}, + {0x86fc, 0xe39c6d0f}, + {0x8700, 0x6c0be528}, + {0x8704, 0xe39c6d00}, + {0x8708, 0x6c25e528}, + {0x870c, 0xe528e39c}, + {0x8710, 0x6c4df8c6}, + {0x8714, 0xe528e39c}, + {0x8718, 0x6c75f9cf}, + {0x871c, 0xe528e39c}, + {0x8720, 0xe39c6c99}, + {0x8724, 0xfad6e528}, + {0x8728, 0x21e87410}, + {0x872c, 0x6e670009}, + {0x8730, 0xe3c46f0f}, + {0x8734, 0x7410e52d}, + {0x8738, 0x000b21e8}, + {0x873c, 0xe3c46e8b}, + {0x8740, 0x7410e52d}, + {0x8744, 0x000d21e8}, + {0x8748, 0x6f0f6eb3}, + {0x874c, 0xe52de3c4}, + {0x8750, 0xfe07ff08}, + {0x8754, 0x21e87410}, + {0x8758, 0x6ec7000e}, + {0x875c, 0xe52de3c4}, + {0x8760, 0x21e87410}, + {0x8764, 0x6edb000f}, + {0x8768, 0xe3c46f0f}, + {0x876c, 0x7410e52d}, + {0x8770, 0x001021e8}, + {0x8774, 0xe3c46eef}, + {0x8778, 0xff03e52d}, + {0x877c, 0xe52dfe02}, + {0x8780, 0x21e87410}, + {0x8784, 0x6e110013}, + {0x8788, 0xe3c46f00}, + {0x878c, 0xff03e52d}, + {0x8790, 0xe52dfe02}, + {0x8794, 0x21e87410}, + {0x8798, 0x6e250014}, + {0x879c, 0xe52de3c4}, + {0x87a0, 0xff08fc24}, + {0x87a4, 0x7410fe07}, + {0x87a8, 0x001521e8}, + {0x87ac, 0xe3c46e39}, + {0x87b0, 0x7410e52d}, + {0x87b4, 0x001621e8}, + {0x87b8, 0xe3c46e4d}, + {0x87bc, 0xfd27e52d}, + {0x87c0, 0x21e87410}, + {0x87c4, 0x6e750018}, + {0x87c8, 0xe52de3c4}, + {0x87cc, 0x21e87410}, + {0x87d0, 0x6e99001a}, + {0x87d4, 0xe52de3c4}, + {0x87d8, 0xe36afe24}, + {0x87dc, 0x63404380}, + {0x87e0, 0x43006880}, + {0x87e4, 0x31300bac}, + {0x87e8, 0xe52d0022}, + {0x87ec, 0x54ec0002}, + {0x87f0, 0x00220baa}, + {0x87f4, 0x0002e52d}, + {0x87f8, 0xe362e3e4}, + {0x87fc, 0xe36a0001}, + {0x8800, 0x63404380}, + {0x8804, 0x43006881}, + {0x8808, 0x31210baa}, + {0x880c, 0xe362e3e4}, + {0x8810, 0xe36a0001}, + {0x8814, 0x63414380}, + {0x8818, 0x43006882}, + {0x881c, 0x31140baa}, + {0x8820, 0xe362e3e4}, + {0x8824, 0x00040001}, + {0x8828, 0x000742fc}, + {0x882c, 0x00046001}, + {0x8830, 0x00074200}, + {0x8834, 0x62006220}, + {0x8838, 0x55010004}, + {0x883c, 0x66055b40}, + {0x8840, 0x62000007}, + {0x8844, 0xe40c6300}, + {0x8848, 0x09000004}, + {0x884c, 0x0b400a01}, + {0x8850, 0x0e010d00}, + {0x8854, 0x00040032}, + {0x8858, 0x42fb950b}, + {0x885c, 0x4d040007}, + {0x8860, 0x42000004}, + {0x8864, 0x00074380}, + {0x8868, 0x00044d01}, + {0x886c, 0x00074300}, + {0x8870, 0x05a30562}, + {0x8874, 0xe40c961f}, + {0x8878, 0xe37e0004}, + {0x887c, 0x06a20007}, + {0x8880, 0xe40c07a3}, + {0x8884, 0xe37e0004}, + {0x8888, 0x0002e3fc}, + {0x888c, 0x4380e404}, + {0x8890, 0x4d000007}, + {0x8894, 0x43000004}, + {0x8898, 0x000742fe}, + {0x889c, 0x00044d00}, + {0x88a0, 0x00014200}, + {0x88a4, 0x42fc0004}, + {0x88a8, 0x60030007}, + {0x88ac, 0x42000004}, + {0x88b0, 0x00073199}, + {0x88b4, 0x07a306a2}, + {0x88b8, 0xe1eb31c5}, + {0x88bc, 0xe1fee1f9}, + {0x88c0, 0xe1eb0001}, + {0x88c4, 0x0001e1fe}, + {0x88c8, 0xe1f9e1f2}, + {0x88cc, 0x0001e1fe}, + {0x88d0, 0xe1fee1f2}, + {0x88d4, 0x00040001}, + {0x88d8, 0x000742fc}, + {0x88dc, 0x00046003}, + {0x88e0, 0x00014200}, + {0x88e4, 0x42fc0004}, + {0x88e8, 0x60010007}, + {0x88ec, 0x42000004}, + {0x88f0, 0x00070001}, + {0x88f4, 0x62006220}, + {0x88f8, 0x0001e404}, + {0x88fc, 0x63000007}, + {0x8900, 0x09000004}, + {0x8904, 0x0e010a00}, + {0x8908, 0x00070032}, + {0x890c, 0xe40c06a2}, + {0x8910, 0x0002e418}, + {0x8914, 0x000742fe}, + {0x8918, 0x00044d00}, + {0x891c, 0x00014200}, + {0x8920, 0x77000005}, + {0x8924, 0x52000007}, + {0x8928, 0x42fe0004}, + {0x892c, 0x60000007}, + {0x8930, 0x42000004}, + {0x8934, 0x60004380}, + {0x8938, 0x62016100}, + {0x893c, 0x68046310}, + {0x8940, 0x41000005}, + {0x8944, 0x00075500}, + {0x8948, 0x00045c02}, + {0x894c, 0x00014300}, + {0x8950, 0x6c060005}, + {0x8954, 0xe2aae298}, + {0x8958, 0xe428e285}, + {0x895c, 0xe430e2f3}, + {0x8960, 0x0001e30c}, + {0x8964, 0x0005e285}, + {0x8968, 0xe2986c06}, + {0x896c, 0xe428e4a7}, + {0x8970, 0xe430e2f3}, + {0x8974, 0x0001e30c}, + {0x8978, 0x6c000005}, + {0x897c, 0xe2aae298}, + {0x8980, 0xe443e285}, + {0x8984, 0xe44be2f3}, + {0x8988, 0x0001e30c}, + {0x898c, 0x0005e285}, + {0x8990, 0xe2986c00}, + {0x8994, 0xe443e4a7}, + {0x8998, 0xe44be2f3}, + {0x899c, 0x0001e30c}, + {0x89a0, 0x6c040005}, + {0x89a4, 0xe2aae298}, + {0x89a8, 0xe45ee285}, + {0x89ac, 0xe466e2f3}, + {0x89b0, 0x0001e30c}, + {0x89b4, 0x0005e285}, + {0x89b8, 0xe2986c04}, + {0x89bc, 0xe45ee4a7}, + {0x89c0, 0xe466e2f3}, + {0x89c4, 0x0001e30c}, + {0x89c8, 0x6c020005}, + {0x89cc, 0xe2aae298}, + {0x89d0, 0xe479e285}, + {0x89d4, 0xe481e2f3}, + {0x89d8, 0x0001e30c}, + {0x89dc, 0x0005e285}, + {0x89e0, 0xe2986c02}, + {0x89e4, 0xe479e4a7}, + {0x89e8, 0xe481e2f3}, + {0x89ec, 0x0001e30c}, + {0x89f0, 0x43800004}, + {0x89f4, 0x610a6008}, + {0x89f8, 0x63ce6200}, + {0x89fc, 0x60800006}, + {0x8a00, 0x00047f00}, + {0x8a04, 0xe4de4300}, + {0x8a08, 0x00070001}, + {0x8a0c, 0x4d015500}, + {0x8a10, 0x74200004}, + {0x8a14, 0x57107711}, + {0x8a18, 0x140f5700}, + {0x8a1c, 0x00077430}, + {0x8a20, 0x00044d00}, + {0x8a24, 0x00074380}, + {0x8a28, 0x00047200}, + {0x8a2c, 0x00014300}, + {0x8a30, 0x74200004}, + {0x8a34, 0x77000005}, + {0x8a38, 0x73887e06}, + {0x8a3c, 0x8f007380}, + {0x8a40, 0x0004140f}, + {0x8a44, 0x00057430}, + {0x8a48, 0x00017300}, + {0x8a4c, 0x0005e494}, + {0x8a50, 0x00017300}, + {0x8a54, 0x43800004}, + {0x8a58, 0x0006b103}, + {0x8a5c, 0x91037cdb}, + {0x8a60, 0x40db0007}, + {0x8a64, 0x43000004}, + {0x8a68, 0x0005e494}, + {0x8a6c, 0x00067380}, + {0x8a70, 0x60025d01}, + {0x8a74, 0xe4b86200}, + {0x8a78, 0x73000005}, + {0x8a7c, 0x76080007}, + {0x8a80, 0x00047578}, + {0x8a84, 0x00074380}, + {0x8a88, 0x5e005e01}, + {0x8a8c, 0x0006140a}, + {0x8a90, 0x7f006380}, + {0x8a94, 0x00076080}, + {0x8a98, 0x4e204c3f}, + {0x8a9c, 0x73047280}, + {0x8aa0, 0x140a7300}, + {0x8aa4, 0x00044d20}, + {0x8aa8, 0x00064300}, + {0x8aac, 0x00077402}, + {0x8ab0, 0x40004001}, + {0x8ab4, 0x0006ab00}, + {0x8ab8, 0x00077404}, + {0x8abc, 0x40004001}, + {0x8ac0, 0x140aab00}, + {0x8ac4, 0x43800004}, + {0x8ac8, 0x52800007}, + {0x8acc, 0x140a5200}, + {0x8ad0, 0x4d004c00}, + {0x8ad4, 0x00064e00}, + {0x8ad8, 0x63006080}, + {0x8adc, 0x43000004}, + {0x8ae0, 0x76000007}, + {0x8ae4, 0x00040001}, + {0x8ae8, 0xb1034380}, + {0x8aec, 0x7cdb0006}, + {0x8af0, 0x00079103}, + {0x8af4, 0x000440db}, + {0x8af8, 0xe4944300}, + {0x8afc, 0xe4b87e03}, + {0x8b00, 0x43800004}, + {0x8b04, 0x0006b103}, + {0x8b08, 0x91037c5b}, + {0x8b0c, 0x405b0007}, + {0x8b10, 0x43000004}, + {0x8b14, 0x00010001}, + {0x8b18, 0x43800004}, + {0x8b1c, 0x4e200007}, + {0x8b20, 0x63800006}, + {0x8b24, 0x5f807cdb}, + {0x8b28, 0x43000004}, + {0x8b2c, 0x76080007}, + {0x8b30, 0x00057560}, + {0x8b34, 0x00047380}, + {0x8b38, 0x0005420e}, + {0x8b3c, 0x14c86c01}, + {0x8b40, 0x6c001432}, + {0x8b44, 0x42000004}, + {0x8b48, 0x43800004}, + {0x8b4c, 0x5f000006}, + {0x8b50, 0x73010007}, + {0x8b54, 0x00047300}, + {0x8b58, 0x0007420f}, + {0x8b5c, 0x52005280}, + {0x8b60, 0x0004140a}, + {0x8b64, 0x00064200}, + {0x8b68, 0x7c5b6300}, + {0x8b6c, 0x4e000007}, + {0x8b70, 0x43000004}, + {0x8b74, 0x73000005}, + {0x8b78, 0x76000007}, + {0x8b7c, 0xe4c10001}, + {0x8b80, 0x00040001}, + {0x8b84, 0x60004380}, + {0x8b88, 0x62016100}, + {0x8b8c, 0x00066310}, + {0x8b90, 0x00046000}, + {0x8b94, 0x00014300}, + {0x8b98, 0x0001e4de}, + {0x8b9c, 0x4e004f02}, + {0x8ba0, 0x52015302}, + {0x8ba4, 0x140f0001}, + {0x8ba8, 0x00019700}, + {0x8bac, 0x65014380}, + {0x8bb0, 0x79007800}, + {0x8bb4, 0x7b407a00}, + {0x8bb8, 0x00014300}, + {0x8bbc, 0x65004380}, + {0x8bc0, 0x00014300}, + {0x8bc4, 0x64014380}, + {0x8bc8, 0x7d007c00}, + {0x8bcc, 0x7f407e00}, + {0x8bd0, 0x00014300}, + {0x8bd4, 0x64004380}, + {0x8bd8, 0x00014300}, + {0x8bdc, 0x7b004380}, + {0x8be0, 0x79007a04}, + {0x8be4, 0x43007802}, + {0x8be8, 0x33825509}, + {0x8bec, 0x43800001}, + {0x8bf0, 0x7a007b40}, + {0x8bf4, 0x55194300}, + {0x8bf8, 0x00013382}, + {0x8bfc, 0x74007401}, + {0x8c00, 0x00018e00}, + {0x8c04, 0x52300007}, + {0x8c08, 0x74310004}, + {0x8c0c, 0x8e007430}, + {0x8c10, 0x52200007}, + {0x8c14, 0x00010004}, + {0x8c18, 0x57005702}, + {0x8c1c, 0x00018e00}, + {0x8c20, 0x57425740}, + {0x8c24, 0x8e005740}, + {0x8c28, 0x00015700}, + {0x8c2c, 0x561042ef}, + {0x8c30, 0x42005600}, + {0x8c34, 0x00018c00}, + {0x8c38, 0xe3a75b20}, + {0x8c3c, 0x54005480}, + {0x8c40, 0x54005481}, + {0x8c44, 0x54005482}, + {0x8c48, 0xbf1ae3ac}, + {0x8c4c, 0xe36e300b}, + {0x8c50, 0xe390e377}, + {0x8c54, 0x0001e521}, + {0x8c58, 0x54c054bf}, + {0x8c5c, 0x54c154a3}, + {0x8c60, 0x4c1854a4}, + {0x8c64, 0xbf091402}, + {0x8c68, 0x54a454c2}, + {0x8c6c, 0xbf051402}, + {0x8c70, 0x54a354c1}, + {0x8c74, 0xbf011402}, + {0x8c78, 0x54dfe532}, + {0x8c7c, 0x54bf0001}, + {0x8c80, 0x050a54e5}, + {0x8c84, 0x000154df}, + {0x8c88, 0x00071657}, + {0x8c8c, 0x00044c80}, + {0x8c90, 0x43807430}, + {0x8c94, 0x7e007f40}, + {0x8c98, 0x7c027d00}, + {0x8c9c, 0x5b404300}, + {0x8ca0, 0x5c015501}, + {0x8ca4, 0x5480e396}, + {0x8ca8, 0x54815400}, + {0x8cac, 0x54825400}, + {0x8cb0, 0x00075400}, + {0x8cb4, 0x00044c00}, + {0x8cb8, 0xe3ac7410}, + {0x8cbc, 0x300bbfe1}, + {0x8cc0, 0x56005610}, + {0x8cc4, 0x00018c00}, + {0x8cc8, 0x57005704}, + {0x8ccc, 0x33ee8e00}, + {0x8cd0, 0xaf034019}, + {0x8cd4, 0x33ee402b}, + {0x8cd8, 0x33df402b}, + {0x8cdc, 0x57005708}, + {0x8ce0, 0x57818e00}, + {0x8ce4, 0x8e005780}, + {0x8ce8, 0x00074380}, + {0x8cec, 0x5c005c01}, + {0x8cf0, 0x00041403}, + {0x8cf4, 0x00014300}, + {0x8cf8, 0x0007427f}, + {0x8cfc, 0x62006280}, + {0x8d00, 0x00049200}, + {0x8d04, 0x00014200}, + {0x8d08, 0x0007427f}, + {0x8d0c, 0x63146394}, + {0x8d10, 0x00049200}, + {0x8d14, 0x00014200}, + {0x8d18, 0x42fe0004}, + {0x8d1c, 0x4d010007}, + {0x8d20, 0x42000004}, + {0x8d24, 0x140f7420}, + {0x8d28, 0x57005710}, + {0x8d2c, 0x0001141f}, + {0x8d30, 0x42fe0004}, + {0x8d34, 0x4d010007}, + {0x8d38, 0x42000004}, + {0x8d3c, 0x140f7420}, + {0x8d40, 0x000742bf}, + {0x8d44, 0x62006240}, + {0x8d48, 0x0004141f}, + {0x8d4c, 0x00014200}, + {0x8d50, 0x5d060006}, + {0x8d54, 0x61046003}, + {0x8d58, 0x00056200}, + {0x8d5c, 0x00017310}, + {0x8d60, 0x43800004}, + {0x8d64, 0x5e010007}, + {0x8d68, 0x140a5e00}, + {0x8d6c, 0x0006b103}, + {0x8d70, 0x91037f07}, + {0x8d74, 0x43070007}, + {0x8d78, 0x5c000006}, + {0x8d7c, 0x5e035d02}, + {0x8d80, 0x43000004}, + {0x8d84, 0x00060001}, + {0x8d88, 0x60005d04}, + {0x8d8c, 0x62006104}, + {0x8d90, 0x73100005}, + {0x8d94, 0x00040001}, + {0x8d98, 0x00074380}, + {0x8d9c, 0x5e005e01}, + {0x8da0, 0xb103140a}, + {0x8da4, 0x7fc60006}, + {0x8da8, 0x00079103}, + {0x8dac, 0x000643c6}, + {0x8db0, 0x5d025c00}, + {0x8db4, 0x00045e03}, + {0x8db8, 0x00014300}, + {0x8dbc, 0x5d040006}, + {0x8dc0, 0x61046000}, + {0x8dc4, 0x00056200}, + {0x8dc8, 0x00017310}, + {0x8dcc, 0x43800004}, + {0x8dd0, 0x5e010007}, + {0x8dd4, 0x140a5e00}, + {0x8dd8, 0x0006b103}, + {0x8ddc, 0x91037fc6}, + {0x8de0, 0x43c60007}, + {0x8de4, 0x5c000006}, + {0x8de8, 0x5e035d02}, + {0x8dec, 0x43000004}, + {0x8df0, 0x00060001}, + {0x8df4, 0x60025d00}, + {0x8df8, 0x62006100}, + {0x8dfc, 0x73000005}, + {0x8e00, 0x00040001}, + {0x8e04, 0x00074380}, + {0x8e08, 0x5e005e01}, + {0x8e0c, 0xb103140a}, + {0x8e10, 0x7fc00006}, + {0x8e14, 0x00079103}, + {0x8e18, 0x000643c0}, + {0x8e1c, 0x5d025c00}, + {0x8e20, 0x00045e03}, + {0x8e24, 0x00014300}, + {0x8e28, 0x7e020005}, + {0x8e2c, 0x42f70004}, + {0x8e30, 0x6c080005}, + {0x8e34, 0x42700004}, + {0x8e38, 0x73810005}, + {0x8e3c, 0x93007380}, + {0x8e40, 0x42f70004}, + {0x8e44, 0x6c000005}, + {0x8e48, 0x42000004}, + {0x8e4c, 0x00040001}, + {0x8e50, 0x00074380}, + {0x8e54, 0x73007304}, + {0x8e58, 0x72401405}, + {0x8e5c, 0x43000004}, + {0x8e60, 0x74040006}, + {0x8e64, 0x40010007}, + {0x8e68, 0xab004000}, + {0x8e6c, 0x0001140f}, + {0x8e70, 0x140ae515}, + {0x8e74, 0x140ae4c1}, + {0x8e78, 0x0001e51c}, + {0x8e7c, 0xe4c1e515}, + {0x8e80, 0x00040001}, + {0x8e84, 0x00047410}, + {0x8e88, 0x42f04380}, + {0x8e8c, 0x62080007}, + {0x8e90, 0x24206301}, + {0x8e94, 0x14c80000}, + {0x8e98, 0x00002428}, + {0x8e9c, 0x1a4215f4}, + {0x8ea0, 0x6300000b}, + {0x8ea4, 0x42000004}, + {0x8ea8, 0x74304300}, + {0x8eac, 0x4380140f}, + {0x8eb0, 0x73080007}, + {0x8eb4, 0x00047300}, + {0x8eb8, 0x00014300}, + {0x8ebc, 0x4bf00007}, + {0x8ec0, 0x490b4a8f}, + {0x8ec4, 0x4a8e48f1}, + {0x8ec8, 0x48a5490a}, + {0x8ecc, 0x49094a8d}, + {0x8ed0, 0x4a8c487d}, + {0x8ed4, 0x48754908}, + {0x8ed8, 0x49074a8b}, + {0x8edc, 0x4a8a4889}, + {0x8ee0, 0x48b74906}, + {0x8ee4, 0x49054a89}, + {0x8ee8, 0x4a8848fc}, + {0x8eec, 0x48564905}, + {0x8ef0, 0x49044a87}, + {0x8ef4, 0x4a8648c1}, + {0x8ef8, 0x483d4904}, + {0x8efc, 0x49034a85}, + {0x8f00, 0x4a8448c7}, + {0x8f04, 0x485e4903}, + {0x8f08, 0x49024a83}, + {0x8f0c, 0x4a8248ac}, + {0x8f10, 0x48624902}, + {0x8f14, 0x49024a81}, + {0x8f18, 0x4a804820}, + {0x8f1c, 0x48004900}, + {0x8f20, 0x49014a90}, + {0x8f24, 0x4a10481f}, + {0x8f28, 0x00060001}, + {0x8f2c, 0x5f005f80}, + {0x8f30, 0x00059900}, + {0x8f34, 0x00017300}, + {0x8f38, 0x63800006}, + {0x8f3c, 0x98006300}, + {0x8f40, 0x549f0001}, + {0x8f44, 0x5c015400}, + {0x8f48, 0x540054df}, + {0x8f4c, 0x00015c02}, + {0x8f50, 0x07145c01}, + {0x8f54, 0x5c025400}, + {0x8f58, 0x5c020001}, + {0x8f5c, 0x54000714}, + {0x8f60, 0x00015c01}, + {0x8f64, 0x4c184c98}, + {0x8f68, 0x00080001}, + {0x8f6c, 0x5c020004}, + {0x8f70, 0x09017430}, + {0x8f74, 0x0ba60c01}, + {0x8f78, 0x77800005}, + {0x8f7c, 0x52200007}, + {0x8f80, 0x43800004}, + {0x8f84, 0x610a6008}, + {0x8f88, 0x63c26200}, + {0x8f8c, 0x5c000007}, + {0x8f90, 0x43000004}, + {0x8f94, 0x00000001}, + {0x8080, 0x00000004}, + {0x8080, 0x00000000}, + {0x8088, 0x00000000}, +}; + +static const struct rtw89_txpwr_byrate_cfg rtw89_8851b_txpwr_byrate[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x58585858, }, + { 0, 0, 1, 4, 4, 0x484c5054, }, + { 0, 0, 2, 0, 4, 0x54585858, }, + { 0, 0, 2, 4, 4, 0x44484c50, }, + { 0, 0, 2, 8, 4, 0x34383c40, }, + { 0, 0, 3, 0, 4, 0x58585858, }, + { 0, 1, 2, 0, 4, 0x50545858, }, + { 0, 1, 2, 4, 4, 0x4044484c, }, + { 0, 1, 2, 8, 4, 0x3034383c, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x58585858, }, + { 1, 0, 1, 4, 4, 0x484c5054, }, + { 1, 0, 2, 0, 4, 0x54585858, }, + { 1, 0, 2, 4, 4, 0x44484c50, }, + { 1, 0, 2, 8, 4, 0x34383c40, }, + { 1, 0, 3, 0, 4, 0x54585858, }, + { 1, 1, 2, 0, 4, 0x54585858, }, + { 1, 1, 2, 4, 4, 0x44484c50, }, + { 1, 1, 2, 8, 4, 0x34383c40, }, + { 1, 1, 3, 0, 4, 0x48484848, }, + { 1, 0, 4, 0, 4, 0x00000000, }, + { 2, 0, 1, 0, 4, 0x40404040, }, + { 2, 0, 1, 4, 4, 0x383c4040, }, + { 2, 0, 2, 0, 4, 0x40404040, }, + { 2, 0, 2, 4, 4, 0x34383c40, }, + { 2, 0, 2, 8, 4, 0x24282c30, }, + { 2, 0, 3, 0, 4, 0x40404040, }, + { 2, 1, 2, 0, 4, 0x40404040, }, + { 2, 1, 2, 4, 4, 0x34383c40, }, + { 2, 1, 2, 8, 4, 0x24282c30, }, + { 2, 1, 3, 0, 4, 0x40404040, }, + { 2, 0, 4, 0, 4, 0x00000000, }, +}; + +static const struct rtw89_txpwr_byrate_cfg rtw89_8851b_txpwr_byrate_type2[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x54585858, }, + { 0, 0, 1, 4, 4, 0x44484c50, }, + { 0, 0, 2, 0, 4, 0x50545858, }, + { 0, 0, 2, 4, 4, 0x4044484c, }, + { 0, 0, 2, 8, 4, 0x3034383c, }, + { 0, 0, 3, 0, 4, 0x58585858, }, + { 0, 1, 2, 0, 4, 0x50545858, }, + { 0, 1, 2, 4, 4, 0x4044484c, }, + { 0, 1, 2, 8, 4, 0x3034383c, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x58585858, }, + { 1, 0, 1, 4, 4, 0x484c5054, }, + { 1, 0, 2, 0, 4, 0x54585858, }, + { 1, 0, 2, 4, 4, 0x44484c50, }, + { 1, 0, 2, 8, 4, 0x34383c40, }, + { 1, 0, 3, 0, 4, 0x54585858, }, + { 1, 1, 2, 0, 4, 0x54585858, }, + { 1, 1, 2, 4, 4, 0x44484c50, }, + { 1, 1, 2, 8, 4, 0x34383c40, }, + { 1, 1, 3, 0, 4, 0x48484848, }, + { 1, 0, 4, 0, 4, 0x00000000, }, + { 2, 0, 1, 0, 4, 0x40404040, }, + { 2, 0, 1, 4, 4, 0x383c4040, }, + { 2, 0, 2, 0, 4, 0x40404040, }, + { 2, 0, 2, 4, 4, 0x34383c40, }, + { 2, 0, 2, 8, 4, 0x24282c30, }, + { 2, 0, 3, 0, 4, 0x40404040, }, + { 2, 1, 2, 0, 4, 0x40404040, }, + { 2, 1, 2, 4, 4, 0x34383c40, }, + { 2, 1, 2, 8, 4, 0x24282c30, }, + { 2, 1, 3, 0, 4, 0x40404040, }, + { 2, 0, 4, 0, 4, 0x00000000, }, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { + 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, -3, -3, + -4, -4, -4, -4, -4, -5, -5, -5, -5, -5, -5, -6, -6, -6 +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { + 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, -3, -3, + -4, -4, -4, -4, -4, -5, -5, -5, -5, -5, -5, -6, -6, -6 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4 +}; + +static +const u8 rtw89_8851b_tx_shape_lmt[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] + [RTW89_REGD_NUM] = { + [0][0][RTW89_ACMA] = 0, + [0][0][RTW89_CN] = 0, + [0][0][RTW89_ETSI] = 0, + [0][0][RTW89_FCC] = 1, + [0][0][RTW89_IC] = 1, + [0][0][RTW89_KCC] = 0, + [0][0][RTW89_MKK] = 0, + [0][0][RTW89_UK] = 0, + [0][1][RTW89_ACMA] = 0, + [0][1][RTW89_CN] = 0, + [0][1][RTW89_ETSI] = 0, + [0][1][RTW89_FCC] = 3, + [0][1][RTW89_IC] = 3, + [0][1][RTW89_KCC] = 0, + [0][1][RTW89_MKK] = 0, + [0][1][RTW89_UK] = 0, + [1][1][RTW89_ACMA] = 0, + [1][1][RTW89_CN] = 0, + [1][1][RTW89_ETSI] = 0, + [1][1][RTW89_FCC] = 3, + [1][1][RTW89_IC] = 3, + [1][1][RTW89_KCC] = 0, + [1][1][RTW89_MKK] = 0, + [1][1][RTW89_UK] = 0, +}; + +static +const u8 rtw89_8851b_tx_shape_lmt_ru[RTW89_BAND_NUM][RTW89_REGD_NUM] = { + [0][RTW89_ACMA] = 0, + [0][RTW89_CN] = 0, + [0][RTW89_ETSI] = 0, + [0][RTW89_FCC] = 3, + [0][RTW89_IC] = 3, + [0][RTW89_KCC] = 0, + [0][RTW89_MKK] = 0, + [0][RTW89_UK] = 0, + [1][RTW89_ACMA] = 0, + [1][RTW89_CN] = 0, + [1][RTW89_ETSI] = 0, + [1][RTW89_FCC] = 3, + [1][RTW89_IC] = 3, + [1][RTW89_KCC] = 0, + [1][RTW89_MKK] = 0, + [1][RTW89_UK] = 0, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 58, + [0][0][0][0][RTW89_WW][1] = 58, + [0][0][0][0][RTW89_WW][2] = 58, + [0][0][0][0][RTW89_WW][3] = 58, + [0][0][0][0][RTW89_WW][4] = 58, + [0][0][0][0][RTW89_WW][5] = 58, + [0][0][0][0][RTW89_WW][6] = 58, + [0][0][0][0][RTW89_WW][7] = 58, + [0][0][0][0][RTW89_WW][8] = 58, + [0][0][0][0][RTW89_WW][9] = 58, + [0][0][0][0][RTW89_WW][10] = 58, + [0][0][0][0][RTW89_WW][11] = 58, + [0][0][0][0][RTW89_WW][12] = 50, + [0][0][0][0][RTW89_WW][13] = 76, + [0][1][0][0][RTW89_WW][0] = 0, + [0][1][0][0][RTW89_WW][1] = 0, + [0][1][0][0][RTW89_WW][2] = 0, + [0][1][0][0][RTW89_WW][3] = 0, + [0][1][0][0][RTW89_WW][4] = 0, + [0][1][0][0][RTW89_WW][5] = 0, + [0][1][0][0][RTW89_WW][6] = 0, + [0][1][0][0][RTW89_WW][7] = 0, + [0][1][0][0][RTW89_WW][8] = 0, + [0][1][0][0][RTW89_WW][9] = 0, + [0][1][0][0][RTW89_WW][10] = 0, + [0][1][0][0][RTW89_WW][11] = 0, + [0][1][0][0][RTW89_WW][12] = 0, + [0][1][0][0][RTW89_WW][13] = 0, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 58, + [1][0][0][0][RTW89_WW][3] = 58, + [1][0][0][0][RTW89_WW][4] = 58, + [1][0][0][0][RTW89_WW][5] = 58, + [1][0][0][0][RTW89_WW][6] = 58, + [1][0][0][0][RTW89_WW][7] = 58, + [1][0][0][0][RTW89_WW][8] = 58, + [1][0][0][0][RTW89_WW][9] = 58, + [1][0][0][0][RTW89_WW][10] = 50, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 0, + [1][1][0][0][RTW89_WW][3] = 0, + [1][1][0][0][RTW89_WW][4] = 0, + [1][1][0][0][RTW89_WW][5] = 0, + [1][1][0][0][RTW89_WW][6] = 0, + [1][1][0][0][RTW89_WW][7] = 0, + [1][1][0][0][RTW89_WW][8] = 0, + [1][1][0][0][RTW89_WW][9] = 0, + [1][1][0][0][RTW89_WW][10] = 0, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][1] = 60, + [0][0][1][0][RTW89_WW][2] = 60, + [0][0][1][0][RTW89_WW][3] = 60, + [0][0][1][0][RTW89_WW][4] = 60, + [0][0][1][0][RTW89_WW][5] = 60, + [0][0][1][0][RTW89_WW][6] = 60, + [0][0][1][0][RTW89_WW][7] = 60, + [0][0][1][0][RTW89_WW][8] = 60, + [0][0][1][0][RTW89_WW][9] = 60, + [0][0][1][0][RTW89_WW][10] = 60, + [0][0][1][0][RTW89_WW][11] = 60, + [0][0][1][0][RTW89_WW][12] = 40, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 0, + [0][1][1][0][RTW89_WW][1] = 0, + [0][1][1][0][RTW89_WW][2] = 0, + [0][1][1][0][RTW89_WW][3] = 0, + [0][1][1][0][RTW89_WW][4] = 0, + [0][1][1][0][RTW89_WW][5] = 0, + [0][1][1][0][RTW89_WW][6] = 0, + [0][1][1][0][RTW89_WW][7] = 0, + [0][1][1][0][RTW89_WW][8] = 0, + [0][1][1][0][RTW89_WW][9] = 0, + [0][1][1][0][RTW89_WW][10] = 0, + [0][1][1][0][RTW89_WW][11] = 0, + [0][1][1][0][RTW89_WW][12] = 0, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 60, + [0][0][2][0][RTW89_WW][1] = 60, + [0][0][2][0][RTW89_WW][2] = 60, + [0][0][2][0][RTW89_WW][3] = 60, + [0][0][2][0][RTW89_WW][4] = 60, + [0][0][2][0][RTW89_WW][5] = 60, + [0][0][2][0][RTW89_WW][6] = 60, + [0][0][2][0][RTW89_WW][7] = 60, + [0][0][2][0][RTW89_WW][8] = 60, + [0][0][2][0][RTW89_WW][9] = 60, + [0][0][2][0][RTW89_WW][10] = 60, + [0][0][2][0][RTW89_WW][11] = 60, + [0][0][2][0][RTW89_WW][12] = 38, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 0, + [0][1][2][0][RTW89_WW][1] = 0, + [0][1][2][0][RTW89_WW][2] = 0, + [0][1][2][0][RTW89_WW][3] = 0, + [0][1][2][0][RTW89_WW][4] = 0, + [0][1][2][0][RTW89_WW][5] = 0, + [0][1][2][0][RTW89_WW][6] = 0, + [0][1][2][0][RTW89_WW][7] = 0, + [0][1][2][0][RTW89_WW][8] = 0, + [0][1][2][0][RTW89_WW][9] = 0, + [0][1][2][0][RTW89_WW][10] = 0, + [0][1][2][0][RTW89_WW][11] = 0, + [0][1][2][0][RTW89_WW][12] = 0, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 0, + [0][1][2][1][RTW89_WW][1] = 0, + [0][1][2][1][RTW89_WW][2] = 0, + [0][1][2][1][RTW89_WW][3] = 0, + [0][1][2][1][RTW89_WW][4] = 0, + [0][1][2][1][RTW89_WW][5] = 0, + [0][1][2][1][RTW89_WW][6] = 0, + [0][1][2][1][RTW89_WW][7] = 0, + [0][1][2][1][RTW89_WW][8] = 0, + [0][1][2][1][RTW89_WW][9] = 0, + [0][1][2][1][RTW89_WW][10] = 0, + [0][1][2][1][RTW89_WW][11] = 0, + [0][1][2][1][RTW89_WW][12] = 0, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 58, + [1][0][2][0][RTW89_WW][3] = 58, + [1][0][2][0][RTW89_WW][4] = 58, + [1][0][2][0][RTW89_WW][5] = 58, + [1][0][2][0][RTW89_WW][6] = 58, + [1][0][2][0][RTW89_WW][7] = 58, + [1][0][2][0][RTW89_WW][8] = 58, + [1][0][2][0][RTW89_WW][9] = 58, + [1][0][2][0][RTW89_WW][10] = 46, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 0, + [1][1][2][0][RTW89_WW][3] = 0, + [1][1][2][0][RTW89_WW][4] = 0, + [1][1][2][0][RTW89_WW][5] = 0, + [1][1][2][0][RTW89_WW][6] = 0, + [1][1][2][0][RTW89_WW][7] = 0, + [1][1][2][0][RTW89_WW][8] = 0, + [1][1][2][0][RTW89_WW][9] = 0, + [1][1][2][0][RTW89_WW][10] = 0, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 0, + [1][1][2][1][RTW89_WW][3] = 0, + [1][1][2][1][RTW89_WW][4] = 0, + [1][1][2][1][RTW89_WW][5] = 0, + [1][1][2][1][RTW89_WW][6] = 0, + [1][1][2][1][RTW89_WW][7] = 0, + [1][1][2][1][RTW89_WW][8] = 0, + [1][1][2][1][RTW89_WW][9] = 0, + [1][1][2][1][RTW89_WW][10] = 0, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 84, + [0][0][0][0][RTW89_ETSI][0] = 58, + [0][0][0][0][RTW89_MKK][0] = 68, + [0][0][0][0][RTW89_IC][0] = 84, + [0][0][0][0][RTW89_KCC][0] = 68, + [0][0][0][0][RTW89_ACMA][0] = 58, + [0][0][0][0][RTW89_CN][0] = 58, + [0][0][0][0][RTW89_UK][0] = 58, + [0][0][0][0][RTW89_FCC][1] = 84, + [0][0][0][0][RTW89_ETSI][1] = 58, + [0][0][0][0][RTW89_MKK][1] = 68, + [0][0][0][0][RTW89_IC][1] = 84, + [0][0][0][0][RTW89_KCC][1] = 68, + [0][0][0][0][RTW89_ACMA][1] = 58, + [0][0][0][0][RTW89_CN][1] = 58, + [0][0][0][0][RTW89_UK][1] = 58, + [0][0][0][0][RTW89_FCC][2] = 84, + [0][0][0][0][RTW89_ETSI][2] = 58, + [0][0][0][0][RTW89_MKK][2] = 68, + [0][0][0][0][RTW89_IC][2] = 84, + [0][0][0][0][RTW89_KCC][2] = 68, + [0][0][0][0][RTW89_ACMA][2] = 58, + [0][0][0][0][RTW89_CN][2] = 58, + [0][0][0][0][RTW89_UK][2] = 58, + [0][0][0][0][RTW89_FCC][3] = 84, + [0][0][0][0][RTW89_ETSI][3] = 58, + [0][0][0][0][RTW89_MKK][3] = 68, + [0][0][0][0][RTW89_IC][3] = 84, + [0][0][0][0][RTW89_KCC][3] = 68, + [0][0][0][0][RTW89_ACMA][3] = 58, + [0][0][0][0][RTW89_CN][3] = 58, + [0][0][0][0][RTW89_UK][3] = 58, + [0][0][0][0][RTW89_FCC][4] = 84, + [0][0][0][0][RTW89_ETSI][4] = 58, + [0][0][0][0][RTW89_MKK][4] = 68, + [0][0][0][0][RTW89_IC][4] = 84, + [0][0][0][0][RTW89_KCC][4] = 68, + [0][0][0][0][RTW89_ACMA][4] = 58, + [0][0][0][0][RTW89_CN][4] = 58, + [0][0][0][0][RTW89_UK][4] = 58, + [0][0][0][0][RTW89_FCC][5] = 84, + [0][0][0][0][RTW89_ETSI][5] = 58, + [0][0][0][0][RTW89_MKK][5] = 68, + [0][0][0][0][RTW89_IC][5] = 84, + [0][0][0][0][RTW89_KCC][5] = 68, + [0][0][0][0][RTW89_ACMA][5] = 58, + [0][0][0][0][RTW89_CN][5] = 58, + [0][0][0][0][RTW89_UK][5] = 58, + [0][0][0][0][RTW89_FCC][6] = 84, + [0][0][0][0][RTW89_ETSI][6] = 58, + [0][0][0][0][RTW89_MKK][6] = 68, + [0][0][0][0][RTW89_IC][6] = 84, + [0][0][0][0][RTW89_KCC][6] = 68, + [0][0][0][0][RTW89_ACMA][6] = 58, + [0][0][0][0][RTW89_CN][6] = 58, + [0][0][0][0][RTW89_UK][6] = 58, + [0][0][0][0][RTW89_FCC][7] = 84, + [0][0][0][0][RTW89_ETSI][7] = 58, + [0][0][0][0][RTW89_MKK][7] = 68, + [0][0][0][0][RTW89_IC][7] = 84, + [0][0][0][0][RTW89_KCC][7] = 68, + [0][0][0][0][RTW89_ACMA][7] = 58, + [0][0][0][0][RTW89_CN][7] = 58, + [0][0][0][0][RTW89_UK][7] = 58, + [0][0][0][0][RTW89_FCC][8] = 84, + [0][0][0][0][RTW89_ETSI][8] = 58, + [0][0][0][0][RTW89_MKK][8] = 68, + [0][0][0][0][RTW89_IC][8] = 84, + [0][0][0][0][RTW89_KCC][8] = 68, + [0][0][0][0][RTW89_ACMA][8] = 58, + [0][0][0][0][RTW89_CN][8] = 58, + [0][0][0][0][RTW89_UK][8] = 58, + [0][0][0][0][RTW89_FCC][9] = 84, + [0][0][0][0][RTW89_ETSI][9] = 58, + [0][0][0][0][RTW89_MKK][9] = 68, + [0][0][0][0][RTW89_IC][9] = 84, + [0][0][0][0][RTW89_KCC][9] = 68, + [0][0][0][0][RTW89_ACMA][9] = 58, + [0][0][0][0][RTW89_CN][9] = 58, + [0][0][0][0][RTW89_UK][9] = 58, + [0][0][0][0][RTW89_FCC][10] = 82, + [0][0][0][0][RTW89_ETSI][10] = 58, + [0][0][0][0][RTW89_MKK][10] = 68, + [0][0][0][0][RTW89_IC][10] = 82, + [0][0][0][0][RTW89_KCC][10] = 68, + [0][0][0][0][RTW89_ACMA][10] = 58, + [0][0][0][0][RTW89_CN][10] = 58, + [0][0][0][0][RTW89_UK][10] = 58, + [0][0][0][0][RTW89_FCC][11] = 62, + [0][0][0][0][RTW89_ETSI][11] = 58, + [0][0][0][0][RTW89_MKK][11] = 68, + [0][0][0][0][RTW89_IC][11] = 62, + [0][0][0][0][RTW89_KCC][11] = 68, + [0][0][0][0][RTW89_ACMA][11] = 58, + [0][0][0][0][RTW89_CN][11] = 58, + [0][0][0][0][RTW89_UK][11] = 58, + [0][0][0][0][RTW89_FCC][12] = 52, + [0][0][0][0][RTW89_ETSI][12] = 58, + [0][0][0][0][RTW89_MKK][12] = 68, + [0][0][0][0][RTW89_IC][12] = 52, + [0][0][0][0][RTW89_KCC][12] = 68, + [0][0][0][0][RTW89_ACMA][12] = 58, + [0][0][0][0][RTW89_CN][12] = 50, + [0][0][0][0][RTW89_UK][12] = 58, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 76, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_KCC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][0][0][0][RTW89_CN][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 127, + [0][1][0][0][RTW89_ETSI][0] = 127, + [0][1][0][0][RTW89_MKK][0] = 127, + [0][1][0][0][RTW89_IC][0] = 127, + [0][1][0][0][RTW89_KCC][0] = 127, + [0][1][0][0][RTW89_ACMA][0] = 127, + [0][1][0][0][RTW89_CN][0] = 127, + [0][1][0][0][RTW89_UK][0] = 127, + [0][1][0][0][RTW89_FCC][1] = 127, + [0][1][0][0][RTW89_ETSI][1] = 127, + [0][1][0][0][RTW89_MKK][1] = 127, + [0][1][0][0][RTW89_IC][1] = 127, + [0][1][0][0][RTW89_KCC][1] = 127, + [0][1][0][0][RTW89_ACMA][1] = 127, + [0][1][0][0][RTW89_CN][1] = 127, + [0][1][0][0][RTW89_UK][1] = 127, + [0][1][0][0][RTW89_FCC][2] = 127, + [0][1][0][0][RTW89_ETSI][2] = 127, + [0][1][0][0][RTW89_MKK][2] = 127, + [0][1][0][0][RTW89_IC][2] = 127, + [0][1][0][0][RTW89_KCC][2] = 127, + [0][1][0][0][RTW89_ACMA][2] = 127, + [0][1][0][0][RTW89_CN][2] = 127, + [0][1][0][0][RTW89_UK][2] = 127, + [0][1][0][0][RTW89_FCC][3] = 127, + [0][1][0][0][RTW89_ETSI][3] = 127, + [0][1][0][0][RTW89_MKK][3] = 127, + [0][1][0][0][RTW89_IC][3] = 127, + [0][1][0][0][RTW89_KCC][3] = 127, + [0][1][0][0][RTW89_ACMA][3] = 127, + [0][1][0][0][RTW89_CN][3] = 127, + [0][1][0][0][RTW89_UK][3] = 127, + [0][1][0][0][RTW89_FCC][4] = 127, + [0][1][0][0][RTW89_ETSI][4] = 127, + [0][1][0][0][RTW89_MKK][4] = 127, + [0][1][0][0][RTW89_IC][4] = 127, + [0][1][0][0][RTW89_KCC][4] = 127, + [0][1][0][0][RTW89_ACMA][4] = 127, + [0][1][0][0][RTW89_CN][4] = 127, + [0][1][0][0][RTW89_UK][4] = 127, + [0][1][0][0][RTW89_FCC][5] = 127, + [0][1][0][0][RTW89_ETSI][5] = 127, + [0][1][0][0][RTW89_MKK][5] = 127, + [0][1][0][0][RTW89_IC][5] = 127, + [0][1][0][0][RTW89_KCC][5] = 127, + [0][1][0][0][RTW89_ACMA][5] = 127, + [0][1][0][0][RTW89_CN][5] = 127, + [0][1][0][0][RTW89_UK][5] = 127, + [0][1][0][0][RTW89_FCC][6] = 127, + [0][1][0][0][RTW89_ETSI][6] = 127, + [0][1][0][0][RTW89_MKK][6] = 127, + [0][1][0][0][RTW89_IC][6] = 127, + [0][1][0][0][RTW89_KCC][6] = 127, + [0][1][0][0][RTW89_ACMA][6] = 127, + [0][1][0][0][RTW89_CN][6] = 127, + [0][1][0][0][RTW89_UK][6] = 127, + [0][1][0][0][RTW89_FCC][7] = 127, + [0][1][0][0][RTW89_ETSI][7] = 127, + [0][1][0][0][RTW89_MKK][7] = 127, + [0][1][0][0][RTW89_IC][7] = 127, + [0][1][0][0][RTW89_KCC][7] = 127, + [0][1][0][0][RTW89_ACMA][7] = 127, + [0][1][0][0][RTW89_CN][7] = 127, + [0][1][0][0][RTW89_UK][7] = 127, + [0][1][0][0][RTW89_FCC][8] = 127, + [0][1][0][0][RTW89_ETSI][8] = 127, + [0][1][0][0][RTW89_MKK][8] = 127, + [0][1][0][0][RTW89_IC][8] = 127, + [0][1][0][0][RTW89_KCC][8] = 127, + [0][1][0][0][RTW89_ACMA][8] = 127, + [0][1][0][0][RTW89_CN][8] = 127, + [0][1][0][0][RTW89_UK][8] = 127, + [0][1][0][0][RTW89_FCC][9] = 127, + [0][1][0][0][RTW89_ETSI][9] = 127, + [0][1][0][0][RTW89_MKK][9] = 127, + [0][1][0][0][RTW89_IC][9] = 127, + [0][1][0][0][RTW89_KCC][9] = 127, + [0][1][0][0][RTW89_ACMA][9] = 127, + [0][1][0][0][RTW89_CN][9] = 127, + [0][1][0][0][RTW89_UK][9] = 127, + [0][1][0][0][RTW89_FCC][10] = 127, + [0][1][0][0][RTW89_ETSI][10] = 127, + [0][1][0][0][RTW89_MKK][10] = 127, + [0][1][0][0][RTW89_IC][10] = 127, + [0][1][0][0][RTW89_KCC][10] = 127, + [0][1][0][0][RTW89_ACMA][10] = 127, + [0][1][0][0][RTW89_CN][10] = 127, + [0][1][0][0][RTW89_UK][10] = 127, + [0][1][0][0][RTW89_FCC][11] = 127, + [0][1][0][0][RTW89_ETSI][11] = 127, + [0][1][0][0][RTW89_MKK][11] = 127, + [0][1][0][0][RTW89_IC][11] = 127, + [0][1][0][0][RTW89_KCC][11] = 127, + [0][1][0][0][RTW89_ACMA][11] = 127, + [0][1][0][0][RTW89_CN][11] = 127, + [0][1][0][0][RTW89_UK][11] = 127, + [0][1][0][0][RTW89_FCC][12] = 127, + [0][1][0][0][RTW89_ETSI][12] = 127, + [0][1][0][0][RTW89_MKK][12] = 127, + [0][1][0][0][RTW89_IC][12] = 127, + [0][1][0][0][RTW89_KCC][12] = 127, + [0][1][0][0][RTW89_ACMA][12] = 127, + [0][1][0][0][RTW89_CN][12] = 127, + [0][1][0][0][RTW89_UK][12] = 127, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 127, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_KCC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_CN][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_KCC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_CN][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_KCC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_CN][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 127, + [1][0][0][0][RTW89_ETSI][2] = 58, + [1][0][0][0][RTW89_MKK][2] = 70, + [1][0][0][0][RTW89_IC][2] = 127, + [1][0][0][0][RTW89_KCC][2] = 68, + [1][0][0][0][RTW89_ACMA][2] = 58, + [1][0][0][0][RTW89_CN][2] = 58, + [1][0][0][0][RTW89_UK][2] = 58, + [1][0][0][0][RTW89_FCC][3] = 127, + [1][0][0][0][RTW89_ETSI][3] = 58, + [1][0][0][0][RTW89_MKK][3] = 76, + [1][0][0][0][RTW89_IC][3] = 127, + [1][0][0][0][RTW89_KCC][3] = 68, + [1][0][0][0][RTW89_ACMA][3] = 58, + [1][0][0][0][RTW89_CN][3] = 58, + [1][0][0][0][RTW89_UK][3] = 58, + [1][0][0][0][RTW89_FCC][4] = 127, + [1][0][0][0][RTW89_ETSI][4] = 58, + [1][0][0][0][RTW89_MKK][4] = 76, + [1][0][0][0][RTW89_IC][4] = 127, + [1][0][0][0][RTW89_KCC][4] = 68, + [1][0][0][0][RTW89_ACMA][4] = 58, + [1][0][0][0][RTW89_CN][4] = 58, + [1][0][0][0][RTW89_UK][4] = 58, + [1][0][0][0][RTW89_FCC][5] = 127, + [1][0][0][0][RTW89_ETSI][5] = 58, + [1][0][0][0][RTW89_MKK][5] = 76, + [1][0][0][0][RTW89_IC][5] = 127, + [1][0][0][0][RTW89_KCC][5] = 68, + [1][0][0][0][RTW89_ACMA][5] = 58, + [1][0][0][0][RTW89_CN][5] = 58, + [1][0][0][0][RTW89_UK][5] = 58, + [1][0][0][0][RTW89_FCC][6] = 127, + [1][0][0][0][RTW89_ETSI][6] = 58, + [1][0][0][0][RTW89_MKK][6] = 76, + [1][0][0][0][RTW89_IC][6] = 127, + [1][0][0][0][RTW89_KCC][6] = 68, + [1][0][0][0][RTW89_ACMA][6] = 58, + [1][0][0][0][RTW89_CN][6] = 58, + [1][0][0][0][RTW89_UK][6] = 58, + [1][0][0][0][RTW89_FCC][7] = 127, + [1][0][0][0][RTW89_ETSI][7] = 58, + [1][0][0][0][RTW89_MKK][7] = 76, + [1][0][0][0][RTW89_IC][7] = 127, + [1][0][0][0][RTW89_KCC][7] = 68, + [1][0][0][0][RTW89_ACMA][7] = 58, + [1][0][0][0][RTW89_CN][7] = 58, + [1][0][0][0][RTW89_UK][7] = 58, + [1][0][0][0][RTW89_FCC][8] = 127, + [1][0][0][0][RTW89_ETSI][8] = 58, + [1][0][0][0][RTW89_MKK][8] = 76, + [1][0][0][0][RTW89_IC][8] = 127, + [1][0][0][0][RTW89_KCC][8] = 68, + [1][0][0][0][RTW89_ACMA][8] = 58, + [1][0][0][0][RTW89_CN][8] = 58, + [1][0][0][0][RTW89_UK][8] = 58, + [1][0][0][0][RTW89_FCC][9] = 127, + [1][0][0][0][RTW89_ETSI][9] = 58, + [1][0][0][0][RTW89_MKK][9] = 76, + [1][0][0][0][RTW89_IC][9] = 127, + [1][0][0][0][RTW89_KCC][9] = 68, + [1][0][0][0][RTW89_ACMA][9] = 58, + [1][0][0][0][RTW89_CN][9] = 58, + [1][0][0][0][RTW89_UK][9] = 58, + [1][0][0][0][RTW89_FCC][10] = 127, + [1][0][0][0][RTW89_ETSI][10] = 58, + [1][0][0][0][RTW89_MKK][10] = 66, + [1][0][0][0][RTW89_IC][10] = 127, + [1][0][0][0][RTW89_KCC][10] = 68, + [1][0][0][0][RTW89_ACMA][10] = 58, + [1][0][0][0][RTW89_CN][10] = 50, + [1][0][0][0][RTW89_UK][10] = 58, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_KCC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_CN][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_KCC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_CN][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_KCC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_CN][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_KCC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_CN][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_KCC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_CN][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 127, + [1][1][0][0][RTW89_ETSI][2] = 127, + [1][1][0][0][RTW89_MKK][2] = 127, + [1][1][0][0][RTW89_IC][2] = 127, + [1][1][0][0][RTW89_KCC][2] = 127, + [1][1][0][0][RTW89_ACMA][2] = 127, + [1][1][0][0][RTW89_CN][2] = 127, + [1][1][0][0][RTW89_UK][2] = 127, + [1][1][0][0][RTW89_FCC][3] = 127, + [1][1][0][0][RTW89_ETSI][3] = 127, + [1][1][0][0][RTW89_MKK][3] = 127, + [1][1][0][0][RTW89_IC][3] = 127, + [1][1][0][0][RTW89_KCC][3] = 127, + [1][1][0][0][RTW89_ACMA][3] = 127, + [1][1][0][0][RTW89_CN][3] = 127, + [1][1][0][0][RTW89_UK][3] = 127, + [1][1][0][0][RTW89_FCC][4] = 127, + [1][1][0][0][RTW89_ETSI][4] = 127, + [1][1][0][0][RTW89_MKK][4] = 127, + [1][1][0][0][RTW89_IC][4] = 127, + [1][1][0][0][RTW89_KCC][4] = 127, + [1][1][0][0][RTW89_ACMA][4] = 127, + [1][1][0][0][RTW89_CN][4] = 127, + [1][1][0][0][RTW89_UK][4] = 127, + [1][1][0][0][RTW89_FCC][5] = 127, + [1][1][0][0][RTW89_ETSI][5] = 127, + [1][1][0][0][RTW89_MKK][5] = 127, + [1][1][0][0][RTW89_IC][5] = 127, + [1][1][0][0][RTW89_KCC][5] = 127, + [1][1][0][0][RTW89_ACMA][5] = 127, + [1][1][0][0][RTW89_CN][5] = 127, + [1][1][0][0][RTW89_UK][5] = 127, + [1][1][0][0][RTW89_FCC][6] = 127, + [1][1][0][0][RTW89_ETSI][6] = 127, + [1][1][0][0][RTW89_MKK][6] = 127, + [1][1][0][0][RTW89_IC][6] = 127, + [1][1][0][0][RTW89_KCC][6] = 127, + [1][1][0][0][RTW89_ACMA][6] = 127, + [1][1][0][0][RTW89_CN][6] = 127, + [1][1][0][0][RTW89_UK][6] = 127, + [1][1][0][0][RTW89_FCC][7] = 127, + [1][1][0][0][RTW89_ETSI][7] = 127, + [1][1][0][0][RTW89_MKK][7] = 127, + [1][1][0][0][RTW89_IC][7] = 127, + [1][1][0][0][RTW89_KCC][7] = 127, + [1][1][0][0][RTW89_ACMA][7] = 127, + [1][1][0][0][RTW89_CN][7] = 127, + [1][1][0][0][RTW89_UK][7] = 127, + [1][1][0][0][RTW89_FCC][8] = 127, + [1][1][0][0][RTW89_ETSI][8] = 127, + [1][1][0][0][RTW89_MKK][8] = 127, + [1][1][0][0][RTW89_IC][8] = 127, + [1][1][0][0][RTW89_KCC][8] = 127, + [1][1][0][0][RTW89_ACMA][8] = 127, + [1][1][0][0][RTW89_CN][8] = 127, + [1][1][0][0][RTW89_UK][8] = 127, + [1][1][0][0][RTW89_FCC][9] = 127, + [1][1][0][0][RTW89_ETSI][9] = 127, + [1][1][0][0][RTW89_MKK][9] = 127, + [1][1][0][0][RTW89_IC][9] = 127, + [1][1][0][0][RTW89_KCC][9] = 127, + [1][1][0][0][RTW89_ACMA][9] = 127, + [1][1][0][0][RTW89_CN][9] = 127, + [1][1][0][0][RTW89_UK][9] = 127, + [1][1][0][0][RTW89_FCC][10] = 127, + [1][1][0][0][RTW89_ETSI][10] = 127, + [1][1][0][0][RTW89_MKK][10] = 127, + [1][1][0][0][RTW89_IC][10] = 127, + [1][1][0][0][RTW89_KCC][10] = 127, + [1][1][0][0][RTW89_ACMA][10] = 127, + [1][1][0][0][RTW89_CN][10] = 127, + [1][1][0][0][RTW89_UK][10] = 127, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_KCC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_CN][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_KCC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_CN][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_KCC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_CN][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 80, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 72, + [0][0][1][0][RTW89_IC][0] = 80, + [0][0][1][0][RTW89_KCC][0] = 78, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CN][0] = 60, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][1] = 80, + [0][0][1][0][RTW89_ETSI][1] = 60, + [0][0][1][0][RTW89_MKK][1] = 74, + [0][0][1][0][RTW89_IC][1] = 80, + [0][0][1][0][RTW89_KCC][1] = 78, + [0][0][1][0][RTW89_ACMA][1] = 60, + [0][0][1][0][RTW89_CN][1] = 60, + [0][0][1][0][RTW89_UK][1] = 60, + [0][0][1][0][RTW89_FCC][2] = 84, + [0][0][1][0][RTW89_ETSI][2] = 60, + [0][0][1][0][RTW89_MKK][2] = 74, + [0][0][1][0][RTW89_IC][2] = 84, + [0][0][1][0][RTW89_KCC][2] = 78, + [0][0][1][0][RTW89_ACMA][2] = 60, + [0][0][1][0][RTW89_CN][2] = 60, + [0][0][1][0][RTW89_UK][2] = 60, + [0][0][1][0][RTW89_FCC][3] = 84, + [0][0][1][0][RTW89_ETSI][3] = 60, + [0][0][1][0][RTW89_MKK][3] = 74, + [0][0][1][0][RTW89_IC][3] = 84, + [0][0][1][0][RTW89_KCC][3] = 78, + [0][0][1][0][RTW89_ACMA][3] = 60, + [0][0][1][0][RTW89_CN][3] = 60, + [0][0][1][0][RTW89_UK][3] = 60, + [0][0][1][0][RTW89_FCC][4] = 84, + [0][0][1][0][RTW89_ETSI][4] = 60, + [0][0][1][0][RTW89_MKK][4] = 74, + [0][0][1][0][RTW89_IC][4] = 84, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 60, + [0][0][1][0][RTW89_CN][4] = 60, + [0][0][1][0][RTW89_UK][4] = 60, + [0][0][1][0][RTW89_FCC][5] = 84, + [0][0][1][0][RTW89_ETSI][5] = 60, + [0][0][1][0][RTW89_MKK][5] = 74, + [0][0][1][0][RTW89_IC][5] = 84, + [0][0][1][0][RTW89_KCC][5] = 76, + [0][0][1][0][RTW89_ACMA][5] = 60, + [0][0][1][0][RTW89_CN][5] = 60, + [0][0][1][0][RTW89_UK][5] = 60, + [0][0][1][0][RTW89_FCC][6] = 84, + [0][0][1][0][RTW89_ETSI][6] = 60, + [0][0][1][0][RTW89_MKK][6] = 74, + [0][0][1][0][RTW89_IC][6] = 84, + [0][0][1][0][RTW89_KCC][6] = 76, + [0][0][1][0][RTW89_ACMA][6] = 60, + [0][0][1][0][RTW89_CN][6] = 60, + [0][0][1][0][RTW89_UK][6] = 60, + [0][0][1][0][RTW89_FCC][7] = 84, + [0][0][1][0][RTW89_ETSI][7] = 60, + [0][0][1][0][RTW89_MKK][7] = 74, + [0][0][1][0][RTW89_IC][7] = 84, + [0][0][1][0][RTW89_KCC][7] = 76, + [0][0][1][0][RTW89_ACMA][7] = 60, + [0][0][1][0][RTW89_CN][7] = 60, + [0][0][1][0][RTW89_UK][7] = 60, + [0][0][1][0][RTW89_FCC][8] = 80, + [0][0][1][0][RTW89_ETSI][8] = 60, + [0][0][1][0][RTW89_MKK][8] = 74, + [0][0][1][0][RTW89_IC][8] = 80, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 60, + [0][0][1][0][RTW89_CN][8] = 60, + [0][0][1][0][RTW89_UK][8] = 60, + [0][0][1][0][RTW89_FCC][9] = 76, + [0][0][1][0][RTW89_ETSI][9] = 60, + [0][0][1][0][RTW89_MKK][9] = 74, + [0][0][1][0][RTW89_IC][9] = 76, + [0][0][1][0][RTW89_KCC][9] = 74, + [0][0][1][0][RTW89_ACMA][9] = 60, + [0][0][1][0][RTW89_CN][9] = 60, + [0][0][1][0][RTW89_UK][9] = 60, + [0][0][1][0][RTW89_FCC][10] = 76, + [0][0][1][0][RTW89_ETSI][10] = 60, + [0][0][1][0][RTW89_MKK][10] = 74, + [0][0][1][0][RTW89_IC][10] = 76, + [0][0][1][0][RTW89_KCC][10] = 74, + [0][0][1][0][RTW89_ACMA][10] = 60, + [0][0][1][0][RTW89_CN][10] = 60, + [0][0][1][0][RTW89_UK][10] = 60, + [0][0][1][0][RTW89_FCC][11] = 68, + [0][0][1][0][RTW89_ETSI][11] = 60, + [0][0][1][0][RTW89_MKK][11] = 74, + [0][0][1][0][RTW89_IC][11] = 68, + [0][0][1][0][RTW89_KCC][11] = 74, + [0][0][1][0][RTW89_ACMA][11] = 60, + [0][0][1][0][RTW89_CN][11] = 60, + [0][0][1][0][RTW89_UK][11] = 60, + [0][0][1][0][RTW89_FCC][12] = 64, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 70, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 74, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CN][12] = 40, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_KCC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_CN][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 127, + [0][1][1][0][RTW89_ETSI][0] = 127, + [0][1][1][0][RTW89_MKK][0] = 127, + [0][1][1][0][RTW89_IC][0] = 127, + [0][1][1][0][RTW89_KCC][0] = 127, + [0][1][1][0][RTW89_ACMA][0] = 127, + [0][1][1][0][RTW89_CN][0] = 127, + [0][1][1][0][RTW89_UK][0] = 127, + [0][1][1][0][RTW89_FCC][1] = 127, + [0][1][1][0][RTW89_ETSI][1] = 127, + [0][1][1][0][RTW89_MKK][1] = 127, + [0][1][1][0][RTW89_IC][1] = 127, + [0][1][1][0][RTW89_KCC][1] = 127, + [0][1][1][0][RTW89_ACMA][1] = 127, + [0][1][1][0][RTW89_CN][1] = 127, + [0][1][1][0][RTW89_UK][1] = 127, + [0][1][1][0][RTW89_FCC][2] = 127, + [0][1][1][0][RTW89_ETSI][2] = 127, + [0][1][1][0][RTW89_MKK][2] = 127, + [0][1][1][0][RTW89_IC][2] = 127, + [0][1][1][0][RTW89_KCC][2] = 127, + [0][1][1][0][RTW89_ACMA][2] = 127, + [0][1][1][0][RTW89_CN][2] = 127, + [0][1][1][0][RTW89_UK][2] = 127, + [0][1][1][0][RTW89_FCC][3] = 127, + [0][1][1][0][RTW89_ETSI][3] = 127, + [0][1][1][0][RTW89_MKK][3] = 127, + [0][1][1][0][RTW89_IC][3] = 127, + [0][1][1][0][RTW89_KCC][3] = 127, + [0][1][1][0][RTW89_ACMA][3] = 127, + [0][1][1][0][RTW89_CN][3] = 127, + [0][1][1][0][RTW89_UK][3] = 127, + [0][1][1][0][RTW89_FCC][4] = 127, + [0][1][1][0][RTW89_ETSI][4] = 127, + [0][1][1][0][RTW89_MKK][4] = 127, + [0][1][1][0][RTW89_IC][4] = 127, + [0][1][1][0][RTW89_KCC][4] = 127, + [0][1][1][0][RTW89_ACMA][4] = 127, + [0][1][1][0][RTW89_CN][4] = 127, + [0][1][1][0][RTW89_UK][4] = 127, + [0][1][1][0][RTW89_FCC][5] = 127, + [0][1][1][0][RTW89_ETSI][5] = 127, + [0][1][1][0][RTW89_MKK][5] = 127, + [0][1][1][0][RTW89_IC][5] = 127, + [0][1][1][0][RTW89_KCC][5] = 127, + [0][1][1][0][RTW89_ACMA][5] = 127, + [0][1][1][0][RTW89_CN][5] = 127, + [0][1][1][0][RTW89_UK][5] = 127, + [0][1][1][0][RTW89_FCC][6] = 127, + [0][1][1][0][RTW89_ETSI][6] = 127, + [0][1][1][0][RTW89_MKK][6] = 127, + [0][1][1][0][RTW89_IC][6] = 127, + [0][1][1][0][RTW89_KCC][6] = 127, + [0][1][1][0][RTW89_ACMA][6] = 127, + [0][1][1][0][RTW89_CN][6] = 127, + [0][1][1][0][RTW89_UK][6] = 127, + [0][1][1][0][RTW89_FCC][7] = 127, + [0][1][1][0][RTW89_ETSI][7] = 127, + [0][1][1][0][RTW89_MKK][7] = 127, + [0][1][1][0][RTW89_IC][7] = 127, + [0][1][1][0][RTW89_KCC][7] = 127, + [0][1][1][0][RTW89_ACMA][7] = 127, + [0][1][1][0][RTW89_CN][7] = 127, + [0][1][1][0][RTW89_UK][7] = 127, + [0][1][1][0][RTW89_FCC][8] = 127, + [0][1][1][0][RTW89_ETSI][8] = 127, + [0][1][1][0][RTW89_MKK][8] = 127, + [0][1][1][0][RTW89_IC][8] = 127, + [0][1][1][0][RTW89_KCC][8] = 127, + [0][1][1][0][RTW89_ACMA][8] = 127, + [0][1][1][0][RTW89_CN][8] = 127, + [0][1][1][0][RTW89_UK][8] = 127, + [0][1][1][0][RTW89_FCC][9] = 127, + [0][1][1][0][RTW89_ETSI][9] = 127, + [0][1][1][0][RTW89_MKK][9] = 127, + [0][1][1][0][RTW89_IC][9] = 127, + [0][1][1][0][RTW89_KCC][9] = 127, + [0][1][1][0][RTW89_ACMA][9] = 127, + [0][1][1][0][RTW89_CN][9] = 127, + [0][1][1][0][RTW89_UK][9] = 127, + [0][1][1][0][RTW89_FCC][10] = 127, + [0][1][1][0][RTW89_ETSI][10] = 127, + [0][1][1][0][RTW89_MKK][10] = 127, + [0][1][1][0][RTW89_IC][10] = 127, + [0][1][1][0][RTW89_KCC][10] = 127, + [0][1][1][0][RTW89_ACMA][10] = 127, + [0][1][1][0][RTW89_CN][10] = 127, + [0][1][1][0][RTW89_UK][10] = 127, + [0][1][1][0][RTW89_FCC][11] = 127, + [0][1][1][0][RTW89_ETSI][11] = 127, + [0][1][1][0][RTW89_MKK][11] = 127, + [0][1][1][0][RTW89_IC][11] = 127, + [0][1][1][0][RTW89_KCC][11] = 127, + [0][1][1][0][RTW89_ACMA][11] = 127, + [0][1][1][0][RTW89_CN][11] = 127, + [0][1][1][0][RTW89_UK][11] = 127, + [0][1][1][0][RTW89_FCC][12] = 127, + [0][1][1][0][RTW89_ETSI][12] = 127, + [0][1][1][0][RTW89_MKK][12] = 127, + [0][1][1][0][RTW89_IC][12] = 127, + [0][1][1][0][RTW89_KCC][12] = 127, + [0][1][1][0][RTW89_ACMA][12] = 127, + [0][1][1][0][RTW89_CN][12] = 127, + [0][1][1][0][RTW89_UK][12] = 127, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_KCC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_CN][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 78, + [0][0][2][0][RTW89_ETSI][0] = 60, + [0][0][2][0][RTW89_MKK][0] = 72, + [0][0][2][0][RTW89_IC][0] = 78, + [0][0][2][0][RTW89_KCC][0] = 78, + [0][0][2][0][RTW89_ACMA][0] = 60, + [0][0][2][0][RTW89_CN][0] = 60, + [0][0][2][0][RTW89_UK][0] = 60, + [0][0][2][0][RTW89_FCC][1] = 78, + [0][0][2][0][RTW89_ETSI][1] = 60, + [0][0][2][0][RTW89_MKK][1] = 78, + [0][0][2][0][RTW89_IC][1] = 78, + [0][0][2][0][RTW89_KCC][1] = 78, + [0][0][2][0][RTW89_ACMA][1] = 60, + [0][0][2][0][RTW89_CN][1] = 60, + [0][0][2][0][RTW89_UK][1] = 60, + [0][0][2][0][RTW89_FCC][2] = 82, + [0][0][2][0][RTW89_ETSI][2] = 60, + [0][0][2][0][RTW89_MKK][2] = 78, + [0][0][2][0][RTW89_IC][2] = 82, + [0][0][2][0][RTW89_KCC][2] = 78, + [0][0][2][0][RTW89_ACMA][2] = 60, + [0][0][2][0][RTW89_CN][2] = 60, + [0][0][2][0][RTW89_UK][2] = 60, + [0][0][2][0][RTW89_FCC][3] = 82, + [0][0][2][0][RTW89_ETSI][3] = 60, + [0][0][2][0][RTW89_MKK][3] = 78, + [0][0][2][0][RTW89_IC][3] = 82, + [0][0][2][0][RTW89_KCC][3] = 78, + [0][0][2][0][RTW89_ACMA][3] = 60, + [0][0][2][0][RTW89_CN][3] = 60, + [0][0][2][0][RTW89_UK][3] = 60, + [0][0][2][0][RTW89_FCC][4] = 82, + [0][0][2][0][RTW89_ETSI][4] = 60, + [0][0][2][0][RTW89_MKK][4] = 78, + [0][0][2][0][RTW89_IC][4] = 82, + [0][0][2][0][RTW89_KCC][4] = 78, + [0][0][2][0][RTW89_ACMA][4] = 60, + [0][0][2][0][RTW89_CN][4] = 60, + [0][0][2][0][RTW89_UK][4] = 60, + [0][0][2][0][RTW89_FCC][5] = 82, + [0][0][2][0][RTW89_ETSI][5] = 60, + [0][0][2][0][RTW89_MKK][5] = 78, + [0][0][2][0][RTW89_IC][5] = 82, + [0][0][2][0][RTW89_KCC][5] = 78, + [0][0][2][0][RTW89_ACMA][5] = 60, + [0][0][2][0][RTW89_CN][5] = 60, + [0][0][2][0][RTW89_UK][5] = 60, + [0][0][2][0][RTW89_FCC][6] = 82, + [0][0][2][0][RTW89_ETSI][6] = 60, + [0][0][2][0][RTW89_MKK][6] = 78, + [0][0][2][0][RTW89_IC][6] = 82, + [0][0][2][0][RTW89_KCC][6] = 78, + [0][0][2][0][RTW89_ACMA][6] = 60, + [0][0][2][0][RTW89_CN][6] = 60, + [0][0][2][0][RTW89_UK][6] = 60, + [0][0][2][0][RTW89_FCC][7] = 82, + [0][0][2][0][RTW89_ETSI][7] = 60, + [0][0][2][0][RTW89_MKK][7] = 78, + [0][0][2][0][RTW89_IC][7] = 82, + [0][0][2][0][RTW89_KCC][7] = 78, + [0][0][2][0][RTW89_ACMA][7] = 60, + [0][0][2][0][RTW89_CN][7] = 60, + [0][0][2][0][RTW89_UK][7] = 60, + [0][0][2][0][RTW89_FCC][8] = 80, + [0][0][2][0][RTW89_ETSI][8] = 60, + [0][0][2][0][RTW89_MKK][8] = 78, + [0][0][2][0][RTW89_IC][8] = 80, + [0][0][2][0][RTW89_KCC][8] = 78, + [0][0][2][0][RTW89_ACMA][8] = 60, + [0][0][2][0][RTW89_CN][8] = 60, + [0][0][2][0][RTW89_UK][8] = 60, + [0][0][2][0][RTW89_FCC][9] = 76, + [0][0][2][0][RTW89_ETSI][9] = 60, + [0][0][2][0][RTW89_MKK][9] = 78, + [0][0][2][0][RTW89_IC][9] = 76, + [0][0][2][0][RTW89_KCC][9] = 78, + [0][0][2][0][RTW89_ACMA][9] = 60, + [0][0][2][0][RTW89_CN][9] = 60, + [0][0][2][0][RTW89_UK][9] = 60, + [0][0][2][0][RTW89_FCC][10] = 76, + [0][0][2][0][RTW89_ETSI][10] = 60, + [0][0][2][0][RTW89_MKK][10] = 78, + [0][0][2][0][RTW89_IC][10] = 76, + [0][0][2][0][RTW89_KCC][10] = 78, + [0][0][2][0][RTW89_ACMA][10] = 60, + [0][0][2][0][RTW89_CN][10] = 60, + [0][0][2][0][RTW89_UK][10] = 60, + [0][0][2][0][RTW89_FCC][11] = 70, + [0][0][2][0][RTW89_ETSI][11] = 60, + [0][0][2][0][RTW89_MKK][11] = 78, + [0][0][2][0][RTW89_IC][11] = 70, + [0][0][2][0][RTW89_KCC][11] = 78, + [0][0][2][0][RTW89_ACMA][11] = 60, + [0][0][2][0][RTW89_CN][11] = 60, + [0][0][2][0][RTW89_UK][11] = 60, + [0][0][2][0][RTW89_FCC][12] = 70, + [0][0][2][0][RTW89_ETSI][12] = 60, + [0][0][2][0][RTW89_MKK][12] = 70, + [0][0][2][0][RTW89_IC][12] = 70, + [0][0][2][0][RTW89_KCC][12] = 78, + [0][0][2][0][RTW89_ACMA][12] = 60, + [0][0][2][0][RTW89_CN][12] = 38, + [0][0][2][0][RTW89_UK][12] = 60, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_KCC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_CN][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 127, + [0][1][2][0][RTW89_ETSI][0] = 127, + [0][1][2][0][RTW89_MKK][0] = 127, + [0][1][2][0][RTW89_IC][0] = 127, + [0][1][2][0][RTW89_KCC][0] = 127, + [0][1][2][0][RTW89_ACMA][0] = 127, + [0][1][2][0][RTW89_CN][0] = 127, + [0][1][2][0][RTW89_UK][0] = 127, + [0][1][2][0][RTW89_FCC][1] = 127, + [0][1][2][0][RTW89_ETSI][1] = 127, + [0][1][2][0][RTW89_MKK][1] = 127, + [0][1][2][0][RTW89_IC][1] = 127, + [0][1][2][0][RTW89_KCC][1] = 127, + [0][1][2][0][RTW89_ACMA][1] = 127, + [0][1][2][0][RTW89_CN][1] = 127, + [0][1][2][0][RTW89_UK][1] = 127, + [0][1][2][0][RTW89_FCC][2] = 127, + [0][1][2][0][RTW89_ETSI][2] = 127, + [0][1][2][0][RTW89_MKK][2] = 127, + [0][1][2][0][RTW89_IC][2] = 127, + [0][1][2][0][RTW89_KCC][2] = 127, + [0][1][2][0][RTW89_ACMA][2] = 127, + [0][1][2][0][RTW89_CN][2] = 127, + [0][1][2][0][RTW89_UK][2] = 127, + [0][1][2][0][RTW89_FCC][3] = 127, + [0][1][2][0][RTW89_ETSI][3] = 127, + [0][1][2][0][RTW89_MKK][3] = 127, + [0][1][2][0][RTW89_IC][3] = 127, + [0][1][2][0][RTW89_KCC][3] = 127, + [0][1][2][0][RTW89_ACMA][3] = 127, + [0][1][2][0][RTW89_CN][3] = 127, + [0][1][2][0][RTW89_UK][3] = 127, + [0][1][2][0][RTW89_FCC][4] = 127, + [0][1][2][0][RTW89_ETSI][4] = 127, + [0][1][2][0][RTW89_MKK][4] = 127, + [0][1][2][0][RTW89_IC][4] = 127, + [0][1][2][0][RTW89_KCC][4] = 127, + [0][1][2][0][RTW89_ACMA][4] = 127, + [0][1][2][0][RTW89_CN][4] = 127, + [0][1][2][0][RTW89_UK][4] = 127, + [0][1][2][0][RTW89_FCC][5] = 127, + [0][1][2][0][RTW89_ETSI][5] = 127, + [0][1][2][0][RTW89_MKK][5] = 127, + [0][1][2][0][RTW89_IC][5] = 127, + [0][1][2][0][RTW89_KCC][5] = 127, + [0][1][2][0][RTW89_ACMA][5] = 127, + [0][1][2][0][RTW89_CN][5] = 127, + [0][1][2][0][RTW89_UK][5] = 127, + [0][1][2][0][RTW89_FCC][6] = 127, + [0][1][2][0][RTW89_ETSI][6] = 127, + [0][1][2][0][RTW89_MKK][6] = 127, + [0][1][2][0][RTW89_IC][6] = 127, + [0][1][2][0][RTW89_KCC][6] = 127, + [0][1][2][0][RTW89_ACMA][6] = 127, + [0][1][2][0][RTW89_CN][6] = 127, + [0][1][2][0][RTW89_UK][6] = 127, + [0][1][2][0][RTW89_FCC][7] = 127, + [0][1][2][0][RTW89_ETSI][7] = 127, + [0][1][2][0][RTW89_MKK][7] = 127, + [0][1][2][0][RTW89_IC][7] = 127, + [0][1][2][0][RTW89_KCC][7] = 127, + [0][1][2][0][RTW89_ACMA][7] = 127, + [0][1][2][0][RTW89_CN][7] = 127, + [0][1][2][0][RTW89_UK][7] = 127, + [0][1][2][0][RTW89_FCC][8] = 127, + [0][1][2][0][RTW89_ETSI][8] = 127, + [0][1][2][0][RTW89_MKK][8] = 127, + [0][1][2][0][RTW89_IC][8] = 127, + [0][1][2][0][RTW89_KCC][8] = 127, + [0][1][2][0][RTW89_ACMA][8] = 127, + [0][1][2][0][RTW89_CN][8] = 127, + [0][1][2][0][RTW89_UK][8] = 127, + [0][1][2][0][RTW89_FCC][9] = 127, + [0][1][2][0][RTW89_ETSI][9] = 127, + [0][1][2][0][RTW89_MKK][9] = 127, + [0][1][2][0][RTW89_IC][9] = 127, + [0][1][2][0][RTW89_KCC][9] = 127, + [0][1][2][0][RTW89_ACMA][9] = 127, + [0][1][2][0][RTW89_CN][9] = 127, + [0][1][2][0][RTW89_UK][9] = 127, + [0][1][2][0][RTW89_FCC][10] = 127, + [0][1][2][0][RTW89_ETSI][10] = 127, + [0][1][2][0][RTW89_MKK][10] = 127, + [0][1][2][0][RTW89_IC][10] = 127, + [0][1][2][0][RTW89_KCC][10] = 127, + [0][1][2][0][RTW89_ACMA][10] = 127, + [0][1][2][0][RTW89_CN][10] = 127, + [0][1][2][0][RTW89_UK][10] = 127, + [0][1][2][0][RTW89_FCC][11] = 127, + [0][1][2][0][RTW89_ETSI][11] = 127, + [0][1][2][0][RTW89_MKK][11] = 127, + [0][1][2][0][RTW89_IC][11] = 127, + [0][1][2][0][RTW89_KCC][11] = 127, + [0][1][2][0][RTW89_ACMA][11] = 127, + [0][1][2][0][RTW89_CN][11] = 127, + [0][1][2][0][RTW89_UK][11] = 127, + [0][1][2][0][RTW89_FCC][12] = 127, + [0][1][2][0][RTW89_ETSI][12] = 127, + [0][1][2][0][RTW89_MKK][12] = 127, + [0][1][2][0][RTW89_IC][12] = 127, + [0][1][2][0][RTW89_KCC][12] = 127, + [0][1][2][0][RTW89_ACMA][12] = 127, + [0][1][2][0][RTW89_CN][12] = 127, + [0][1][2][0][RTW89_UK][12] = 127, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_KCC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_CN][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 127, + [0][1][2][1][RTW89_ETSI][0] = 127, + [0][1][2][1][RTW89_MKK][0] = 127, + [0][1][2][1][RTW89_IC][0] = 127, + [0][1][2][1][RTW89_KCC][0] = 127, + [0][1][2][1][RTW89_ACMA][0] = 127, + [0][1][2][1][RTW89_CN][0] = 127, + [0][1][2][1][RTW89_UK][0] = 127, + [0][1][2][1][RTW89_FCC][1] = 127, + [0][1][2][1][RTW89_ETSI][1] = 127, + [0][1][2][1][RTW89_MKK][1] = 127, + [0][1][2][1][RTW89_IC][1] = 127, + [0][1][2][1][RTW89_KCC][1] = 127, + [0][1][2][1][RTW89_ACMA][1] = 127, + [0][1][2][1][RTW89_CN][1] = 127, + [0][1][2][1][RTW89_UK][1] = 127, + [0][1][2][1][RTW89_FCC][2] = 127, + [0][1][2][1][RTW89_ETSI][2] = 127, + [0][1][2][1][RTW89_MKK][2] = 127, + [0][1][2][1][RTW89_IC][2] = 127, + [0][1][2][1][RTW89_KCC][2] = 127, + [0][1][2][1][RTW89_ACMA][2] = 127, + [0][1][2][1][RTW89_CN][2] = 127, + [0][1][2][1][RTW89_UK][2] = 127, + [0][1][2][1][RTW89_FCC][3] = 127, + [0][1][2][1][RTW89_ETSI][3] = 127, + [0][1][2][1][RTW89_MKK][3] = 127, + [0][1][2][1][RTW89_IC][3] = 127, + [0][1][2][1][RTW89_KCC][3] = 127, + [0][1][2][1][RTW89_ACMA][3] = 127, + [0][1][2][1][RTW89_CN][3] = 127, + [0][1][2][1][RTW89_UK][3] = 127, + [0][1][2][1][RTW89_FCC][4] = 127, + [0][1][2][1][RTW89_ETSI][4] = 127, + [0][1][2][1][RTW89_MKK][4] = 127, + [0][1][2][1][RTW89_IC][4] = 127, + [0][1][2][1][RTW89_KCC][4] = 127, + [0][1][2][1][RTW89_ACMA][4] = 127, + [0][1][2][1][RTW89_CN][4] = 127, + [0][1][2][1][RTW89_UK][4] = 127, + [0][1][2][1][RTW89_FCC][5] = 127, + [0][1][2][1][RTW89_ETSI][5] = 127, + [0][1][2][1][RTW89_MKK][5] = 127, + [0][1][2][1][RTW89_IC][5] = 127, + [0][1][2][1][RTW89_KCC][5] = 127, + [0][1][2][1][RTW89_ACMA][5] = 127, + [0][1][2][1][RTW89_CN][5] = 127, + [0][1][2][1][RTW89_UK][5] = 127, + [0][1][2][1][RTW89_FCC][6] = 127, + [0][1][2][1][RTW89_ETSI][6] = 127, + [0][1][2][1][RTW89_MKK][6] = 127, + [0][1][2][1][RTW89_IC][6] = 127, + [0][1][2][1][RTW89_KCC][6] = 127, + [0][1][2][1][RTW89_ACMA][6] = 127, + [0][1][2][1][RTW89_CN][6] = 127, + [0][1][2][1][RTW89_UK][6] = 127, + [0][1][2][1][RTW89_FCC][7] = 127, + [0][1][2][1][RTW89_ETSI][7] = 127, + [0][1][2][1][RTW89_MKK][7] = 127, + [0][1][2][1][RTW89_IC][7] = 127, + [0][1][2][1][RTW89_KCC][7] = 127, + [0][1][2][1][RTW89_ACMA][7] = 127, + [0][1][2][1][RTW89_CN][7] = 127, + [0][1][2][1][RTW89_UK][7] = 127, + [0][1][2][1][RTW89_FCC][8] = 127, + [0][1][2][1][RTW89_ETSI][8] = 127, + [0][1][2][1][RTW89_MKK][8] = 127, + [0][1][2][1][RTW89_IC][8] = 127, + [0][1][2][1][RTW89_KCC][8] = 127, + [0][1][2][1][RTW89_ACMA][8] = 127, + [0][1][2][1][RTW89_CN][8] = 127, + [0][1][2][1][RTW89_UK][8] = 127, + [0][1][2][1][RTW89_FCC][9] = 127, + [0][1][2][1][RTW89_ETSI][9] = 127, + [0][1][2][1][RTW89_MKK][9] = 127, + [0][1][2][1][RTW89_IC][9] = 127, + [0][1][2][1][RTW89_KCC][9] = 127, + [0][1][2][1][RTW89_ACMA][9] = 127, + [0][1][2][1][RTW89_CN][9] = 127, + [0][1][2][1][RTW89_UK][9] = 127, + [0][1][2][1][RTW89_FCC][10] = 127, + [0][1][2][1][RTW89_ETSI][10] = 127, + [0][1][2][1][RTW89_MKK][10] = 127, + [0][1][2][1][RTW89_IC][10] = 127, + [0][1][2][1][RTW89_KCC][10] = 127, + [0][1][2][1][RTW89_ACMA][10] = 127, + [0][1][2][1][RTW89_CN][10] = 127, + [0][1][2][1][RTW89_UK][10] = 127, + [0][1][2][1][RTW89_FCC][11] = 127, + [0][1][2][1][RTW89_ETSI][11] = 127, + [0][1][2][1][RTW89_MKK][11] = 127, + [0][1][2][1][RTW89_IC][11] = 127, + [0][1][2][1][RTW89_KCC][11] = 127, + [0][1][2][1][RTW89_ACMA][11] = 127, + [0][1][2][1][RTW89_CN][11] = 127, + [0][1][2][1][RTW89_UK][11] = 127, + [0][1][2][1][RTW89_FCC][12] = 127, + [0][1][2][1][RTW89_ETSI][12] = 127, + [0][1][2][1][RTW89_MKK][12] = 127, + [0][1][2][1][RTW89_IC][12] = 127, + [0][1][2][1][RTW89_KCC][12] = 127, + [0][1][2][1][RTW89_ACMA][12] = 127, + [0][1][2][1][RTW89_CN][12] = 127, + [0][1][2][1][RTW89_UK][12] = 127, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_KCC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_CN][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_KCC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_CN][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_KCC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_CN][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 72, + [1][0][2][0][RTW89_ETSI][2] = 58, + [1][0][2][0][RTW89_MKK][2] = 80, + [1][0][2][0][RTW89_IC][2] = 72, + [1][0][2][0][RTW89_KCC][2] = 80, + [1][0][2][0][RTW89_ACMA][2] = 58, + [1][0][2][0][RTW89_CN][2] = 58, + [1][0][2][0][RTW89_UK][2] = 58, + [1][0][2][0][RTW89_FCC][3] = 72, + [1][0][2][0][RTW89_ETSI][3] = 58, + [1][0][2][0][RTW89_MKK][3] = 80, + [1][0][2][0][RTW89_IC][3] = 72, + [1][0][2][0][RTW89_KCC][3] = 80, + [1][0][2][0][RTW89_ACMA][3] = 58, + [1][0][2][0][RTW89_CN][3] = 58, + [1][0][2][0][RTW89_UK][3] = 58, + [1][0][2][0][RTW89_FCC][4] = 76, + [1][0][2][0][RTW89_ETSI][4] = 58, + [1][0][2][0][RTW89_MKK][4] = 80, + [1][0][2][0][RTW89_IC][4] = 76, + [1][0][2][0][RTW89_KCC][4] = 80, + [1][0][2][0][RTW89_ACMA][4] = 58, + [1][0][2][0][RTW89_CN][4] = 58, + [1][0][2][0][RTW89_UK][4] = 58, + [1][0][2][0][RTW89_FCC][5] = 78, + [1][0][2][0][RTW89_ETSI][5] = 58, + [1][0][2][0][RTW89_MKK][5] = 80, + [1][0][2][0][RTW89_IC][5] = 78, + [1][0][2][0][RTW89_KCC][5] = 80, + [1][0][2][0][RTW89_ACMA][5] = 58, + [1][0][2][0][RTW89_CN][5] = 58, + [1][0][2][0][RTW89_UK][5] = 58, + [1][0][2][0][RTW89_FCC][6] = 78, + [1][0][2][0][RTW89_ETSI][6] = 58, + [1][0][2][0][RTW89_MKK][6] = 78, + [1][0][2][0][RTW89_IC][6] = 78, + [1][0][2][0][RTW89_KCC][6] = 80, + [1][0][2][0][RTW89_ACMA][6] = 58, + [1][0][2][0][RTW89_CN][6] = 58, + [1][0][2][0][RTW89_UK][6] = 58, + [1][0][2][0][RTW89_FCC][7] = 78, + [1][0][2][0][RTW89_ETSI][7] = 58, + [1][0][2][0][RTW89_MKK][7] = 80, + [1][0][2][0][RTW89_IC][7] = 78, + [1][0][2][0][RTW89_KCC][7] = 80, + [1][0][2][0][RTW89_ACMA][7] = 58, + [1][0][2][0][RTW89_CN][7] = 58, + [1][0][2][0][RTW89_UK][7] = 58, + [1][0][2][0][RTW89_FCC][8] = 78, + [1][0][2][0][RTW89_ETSI][8] = 58, + [1][0][2][0][RTW89_MKK][8] = 80, + [1][0][2][0][RTW89_IC][8] = 78, + [1][0][2][0][RTW89_KCC][8] = 78, + [1][0][2][0][RTW89_ACMA][8] = 58, + [1][0][2][0][RTW89_CN][8] = 58, + [1][0][2][0][RTW89_UK][8] = 58, + [1][0][2][0][RTW89_FCC][9] = 76, + [1][0][2][0][RTW89_ETSI][9] = 58, + [1][0][2][0][RTW89_MKK][9] = 80, + [1][0][2][0][RTW89_IC][9] = 76, + [1][0][2][0][RTW89_KCC][9] = 78, + [1][0][2][0][RTW89_ACMA][9] = 58, + [1][0][2][0][RTW89_CN][9] = 58, + [1][0][2][0][RTW89_UK][9] = 58, + [1][0][2][0][RTW89_FCC][10] = 70, + [1][0][2][0][RTW89_ETSI][10] = 58, + [1][0][2][0][RTW89_MKK][10] = 78, + [1][0][2][0][RTW89_IC][10] = 70, + [1][0][2][0][RTW89_KCC][10] = 78, + [1][0][2][0][RTW89_ACMA][10] = 58, + [1][0][2][0][RTW89_CN][10] = 46, + [1][0][2][0][RTW89_UK][10] = 58, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_KCC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_CN][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_KCC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_CN][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_KCC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_CN][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_KCC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_CN][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 127, + [1][1][2][0][RTW89_ETSI][2] = 127, + [1][1][2][0][RTW89_MKK][2] = 127, + [1][1][2][0][RTW89_IC][2] = 127, + [1][1][2][0][RTW89_KCC][2] = 127, + [1][1][2][0][RTW89_ACMA][2] = 127, + [1][1][2][0][RTW89_CN][2] = 127, + [1][1][2][0][RTW89_UK][2] = 127, + [1][1][2][0][RTW89_FCC][3] = 127, + [1][1][2][0][RTW89_ETSI][3] = 127, + [1][1][2][0][RTW89_MKK][3] = 127, + [1][1][2][0][RTW89_IC][3] = 127, + [1][1][2][0][RTW89_KCC][3] = 127, + [1][1][2][0][RTW89_ACMA][3] = 127, + [1][1][2][0][RTW89_CN][3] = 127, + [1][1][2][0][RTW89_UK][3] = 127, + [1][1][2][0][RTW89_FCC][4] = 127, + [1][1][2][0][RTW89_ETSI][4] = 127, + [1][1][2][0][RTW89_MKK][4] = 127, + [1][1][2][0][RTW89_IC][4] = 127, + [1][1][2][0][RTW89_KCC][4] = 127, + [1][1][2][0][RTW89_ACMA][4] = 127, + [1][1][2][0][RTW89_CN][4] = 127, + [1][1][2][0][RTW89_UK][4] = 127, + [1][1][2][0][RTW89_FCC][5] = 127, + [1][1][2][0][RTW89_ETSI][5] = 127, + [1][1][2][0][RTW89_MKK][5] = 127, + [1][1][2][0][RTW89_IC][5] = 127, + [1][1][2][0][RTW89_KCC][5] = 127, + [1][1][2][0][RTW89_ACMA][5] = 127, + [1][1][2][0][RTW89_CN][5] = 127, + [1][1][2][0][RTW89_UK][5] = 127, + [1][1][2][0][RTW89_FCC][6] = 127, + [1][1][2][0][RTW89_ETSI][6] = 127, + [1][1][2][0][RTW89_MKK][6] = 127, + [1][1][2][0][RTW89_IC][6] = 127, + [1][1][2][0][RTW89_KCC][6] = 127, + [1][1][2][0][RTW89_ACMA][6] = 127, + [1][1][2][0][RTW89_CN][6] = 127, + [1][1][2][0][RTW89_UK][6] = 127, + [1][1][2][0][RTW89_FCC][7] = 127, + [1][1][2][0][RTW89_ETSI][7] = 127, + [1][1][2][0][RTW89_MKK][7] = 127, + [1][1][2][0][RTW89_IC][7] = 127, + [1][1][2][0][RTW89_KCC][7] = 127, + [1][1][2][0][RTW89_ACMA][7] = 127, + [1][1][2][0][RTW89_CN][7] = 127, + [1][1][2][0][RTW89_UK][7] = 127, + [1][1][2][0][RTW89_FCC][8] = 127, + [1][1][2][0][RTW89_ETSI][8] = 127, + [1][1][2][0][RTW89_MKK][8] = 127, + [1][1][2][0][RTW89_IC][8] = 127, + [1][1][2][0][RTW89_KCC][8] = 127, + [1][1][2][0][RTW89_ACMA][8] = 127, + [1][1][2][0][RTW89_CN][8] = 127, + [1][1][2][0][RTW89_UK][8] = 127, + [1][1][2][0][RTW89_FCC][9] = 127, + [1][1][2][0][RTW89_ETSI][9] = 127, + [1][1][2][0][RTW89_MKK][9] = 127, + [1][1][2][0][RTW89_IC][9] = 127, + [1][1][2][0][RTW89_KCC][9] = 127, + [1][1][2][0][RTW89_ACMA][9] = 127, + [1][1][2][0][RTW89_CN][9] = 127, + [1][1][2][0][RTW89_UK][9] = 127, + [1][1][2][0][RTW89_FCC][10] = 127, + [1][1][2][0][RTW89_ETSI][10] = 127, + [1][1][2][0][RTW89_MKK][10] = 127, + [1][1][2][0][RTW89_IC][10] = 127, + [1][1][2][0][RTW89_KCC][10] = 127, + [1][1][2][0][RTW89_ACMA][10] = 127, + [1][1][2][0][RTW89_CN][10] = 127, + [1][1][2][0][RTW89_UK][10] = 127, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_KCC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_CN][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_KCC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_CN][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_KCC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_CN][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 127, + [1][1][2][1][RTW89_ETSI][2] = 127, + [1][1][2][1][RTW89_MKK][2] = 127, + [1][1][2][1][RTW89_IC][2] = 127, + [1][1][2][1][RTW89_KCC][2] = 127, + [1][1][2][1][RTW89_ACMA][2] = 127, + [1][1][2][1][RTW89_CN][2] = 127, + [1][1][2][1][RTW89_UK][2] = 127, + [1][1][2][1][RTW89_FCC][3] = 127, + [1][1][2][1][RTW89_ETSI][3] = 127, + [1][1][2][1][RTW89_MKK][3] = 127, + [1][1][2][1][RTW89_IC][3] = 127, + [1][1][2][1][RTW89_KCC][3] = 127, + [1][1][2][1][RTW89_ACMA][3] = 127, + [1][1][2][1][RTW89_CN][3] = 127, + [1][1][2][1][RTW89_UK][3] = 127, + [1][1][2][1][RTW89_FCC][4] = 127, + [1][1][2][1][RTW89_ETSI][4] = 127, + [1][1][2][1][RTW89_MKK][4] = 127, + [1][1][2][1][RTW89_IC][4] = 127, + [1][1][2][1][RTW89_KCC][4] = 127, + [1][1][2][1][RTW89_ACMA][4] = 127, + [1][1][2][1][RTW89_CN][4] = 127, + [1][1][2][1][RTW89_UK][4] = 127, + [1][1][2][1][RTW89_FCC][5] = 127, + [1][1][2][1][RTW89_ETSI][5] = 127, + [1][1][2][1][RTW89_MKK][5] = 127, + [1][1][2][1][RTW89_IC][5] = 127, + [1][1][2][1][RTW89_KCC][5] = 127, + [1][1][2][1][RTW89_ACMA][5] = 127, + [1][1][2][1][RTW89_CN][5] = 127, + [1][1][2][1][RTW89_UK][5] = 127, + [1][1][2][1][RTW89_FCC][6] = 127, + [1][1][2][1][RTW89_ETSI][6] = 127, + [1][1][2][1][RTW89_MKK][6] = 127, + [1][1][2][1][RTW89_IC][6] = 127, + [1][1][2][1][RTW89_KCC][6] = 127, + [1][1][2][1][RTW89_ACMA][6] = 127, + [1][1][2][1][RTW89_CN][6] = 127, + [1][1][2][1][RTW89_UK][6] = 127, + [1][1][2][1][RTW89_FCC][7] = 127, + [1][1][2][1][RTW89_ETSI][7] = 127, + [1][1][2][1][RTW89_MKK][7] = 127, + [1][1][2][1][RTW89_IC][7] = 127, + [1][1][2][1][RTW89_KCC][7] = 127, + [1][1][2][1][RTW89_ACMA][7] = 127, + [1][1][2][1][RTW89_CN][7] = 127, + [1][1][2][1][RTW89_UK][7] = 127, + [1][1][2][1][RTW89_FCC][8] = 127, + [1][1][2][1][RTW89_ETSI][8] = 127, + [1][1][2][1][RTW89_MKK][8] = 127, + [1][1][2][1][RTW89_IC][8] = 127, + [1][1][2][1][RTW89_KCC][8] = 127, + [1][1][2][1][RTW89_ACMA][8] = 127, + [1][1][2][1][RTW89_CN][8] = 127, + [1][1][2][1][RTW89_UK][8] = 127, + [1][1][2][1][RTW89_FCC][9] = 127, + [1][1][2][1][RTW89_ETSI][9] = 127, + [1][1][2][1][RTW89_MKK][9] = 127, + [1][1][2][1][RTW89_IC][9] = 127, + [1][1][2][1][RTW89_KCC][9] = 127, + [1][1][2][1][RTW89_ACMA][9] = 127, + [1][1][2][1][RTW89_CN][9] = 127, + [1][1][2][1][RTW89_UK][9] = 127, + [1][1][2][1][RTW89_FCC][10] = 127, + [1][1][2][1][RTW89_ETSI][10] = 127, + [1][1][2][1][RTW89_MKK][10] = 127, + [1][1][2][1][RTW89_IC][10] = 127, + [1][1][2][1][RTW89_KCC][10] = 127, + [1][1][2][1][RTW89_ACMA][10] = 127, + [1][1][2][1][RTW89_CN][10] = 127, + [1][1][2][1][RTW89_UK][10] = 127, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_KCC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_CN][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_KCC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_CN][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][2] = 58, + [0][0][1][0][RTW89_WW][4] = 58, + [0][0][1][0][RTW89_WW][6] = 50, + [0][0][1][0][RTW89_WW][8] = 58, + [0][0][1][0][RTW89_WW][10] = 58, + [0][0][1][0][RTW89_WW][12] = 58, + [0][0][1][0][RTW89_WW][14] = 58, + [0][0][1][0][RTW89_WW][15] = 58, + [0][0][1][0][RTW89_WW][17] = 60, + [0][0][1][0][RTW89_WW][19] = 60, + [0][0][1][0][RTW89_WW][21] = 60, + [0][0][1][0][RTW89_WW][23] = 60, + [0][0][1][0][RTW89_WW][25] = 60, + [0][0][1][0][RTW89_WW][27] = 60, + [0][0][1][0][RTW89_WW][29] = 60, + [0][0][1][0][RTW89_WW][31] = 60, + [0][0][1][0][RTW89_WW][33] = 60, + [0][0][1][0][RTW89_WW][35] = 60, + [0][0][1][0][RTW89_WW][37] = 74, + [0][0][1][0][RTW89_WW][38] = 30, + [0][0][1][0][RTW89_WW][40] = 30, + [0][0][1][0][RTW89_WW][42] = 30, + [0][0][1][0][RTW89_WW][44] = 30, + [0][0][1][0][RTW89_WW][46] = 30, + [0][0][1][0][RTW89_WW][48] = 72, + [0][0][1][0][RTW89_WW][50] = 72, + [0][0][1][0][RTW89_WW][52] = 72, + [0][1][1][0][RTW89_WW][0] = 0, + [0][1][1][0][RTW89_WW][2] = 0, + [0][1][1][0][RTW89_WW][4] = 0, + [0][1][1][0][RTW89_WW][6] = 0, + [0][1][1][0][RTW89_WW][8] = 0, + [0][1][1][0][RTW89_WW][10] = 0, + [0][1][1][0][RTW89_WW][12] = 0, + [0][1][1][0][RTW89_WW][14] = 0, + [0][1][1][0][RTW89_WW][15] = 0, + [0][1][1][0][RTW89_WW][17] = 0, + [0][1][1][0][RTW89_WW][19] = 0, + [0][1][1][0][RTW89_WW][21] = 0, + [0][1][1][0][RTW89_WW][23] = 0, + [0][1][1][0][RTW89_WW][25] = 0, + [0][1][1][0][RTW89_WW][27] = 0, + [0][1][1][0][RTW89_WW][29] = 0, + [0][1][1][0][RTW89_WW][31] = 0, + [0][1][1][0][RTW89_WW][33] = 0, + [0][1][1][0][RTW89_WW][35] = 0, + [0][1][1][0][RTW89_WW][37] = 0, + [0][1][1][0][RTW89_WW][38] = 0, + [0][1][1][0][RTW89_WW][40] = 0, + [0][1][1][0][RTW89_WW][42] = 0, + [0][1][1][0][RTW89_WW][44] = 0, + [0][1][1][0][RTW89_WW][46] = 0, + [0][1][1][0][RTW89_WW][48] = 0, + [0][1][1][0][RTW89_WW][50] = 0, + [0][1][1][0][RTW89_WW][52] = 0, + [0][0][2][0][RTW89_WW][0] = 60, + [0][0][2][0][RTW89_WW][2] = 60, + [0][0][2][0][RTW89_WW][4] = 60, + [0][0][2][0][RTW89_WW][6] = 54, + [0][0][2][0][RTW89_WW][8] = 60, + [0][0][2][0][RTW89_WW][10] = 60, + [0][0][2][0][RTW89_WW][12] = 60, + [0][0][2][0][RTW89_WW][14] = 60, + [0][0][2][0][RTW89_WW][15] = 60, + [0][0][2][0][RTW89_WW][17] = 62, + [0][0][2][0][RTW89_WW][19] = 62, + [0][0][2][0][RTW89_WW][21] = 62, + [0][0][2][0][RTW89_WW][23] = 62, + [0][0][2][0][RTW89_WW][25] = 62, + [0][0][2][0][RTW89_WW][27] = 62, + [0][0][2][0][RTW89_WW][29] = 62, + [0][0][2][0][RTW89_WW][31] = 62, + [0][0][2][0][RTW89_WW][33] = 62, + [0][0][2][0][RTW89_WW][35] = 62, + [0][0][2][0][RTW89_WW][37] = 76, + [0][0][2][0][RTW89_WW][38] = 30, + [0][0][2][0][RTW89_WW][40] = 30, + [0][0][2][0][RTW89_WW][42] = 30, + [0][0][2][0][RTW89_WW][44] = 30, + [0][0][2][0][RTW89_WW][46] = 30, + [0][0][2][0][RTW89_WW][48] = 74, + [0][0][2][0][RTW89_WW][50] = 76, + [0][0][2][0][RTW89_WW][52] = 76, + [0][1][2][0][RTW89_WW][0] = 0, + [0][1][2][0][RTW89_WW][2] = 0, + [0][1][2][0][RTW89_WW][4] = 0, + [0][1][2][0][RTW89_WW][6] = 0, + [0][1][2][0][RTW89_WW][8] = 0, + [0][1][2][0][RTW89_WW][10] = 0, + [0][1][2][0][RTW89_WW][12] = 0, + [0][1][2][0][RTW89_WW][14] = 0, + [0][1][2][0][RTW89_WW][15] = 0, + [0][1][2][0][RTW89_WW][17] = 0, + [0][1][2][0][RTW89_WW][19] = 0, + [0][1][2][0][RTW89_WW][21] = 0, + [0][1][2][0][RTW89_WW][23] = 0, + [0][1][2][0][RTW89_WW][25] = 0, + [0][1][2][0][RTW89_WW][27] = 0, + [0][1][2][0][RTW89_WW][29] = 0, + [0][1][2][0][RTW89_WW][31] = 0, + [0][1][2][0][RTW89_WW][33] = 0, + [0][1][2][0][RTW89_WW][35] = 0, + [0][1][2][0][RTW89_WW][37] = 0, + [0][1][2][0][RTW89_WW][38] = 0, + [0][1][2][0][RTW89_WW][40] = 0, + [0][1][2][0][RTW89_WW][42] = 0, + [0][1][2][0][RTW89_WW][44] = 0, + [0][1][2][0][RTW89_WW][46] = 0, + [0][1][2][0][RTW89_WW][48] = 0, + [0][1][2][0][RTW89_WW][50] = 0, + [0][1][2][0][RTW89_WW][52] = 0, + [0][1][2][1][RTW89_WW][0] = 0, + [0][1][2][1][RTW89_WW][2] = 0, + [0][1][2][1][RTW89_WW][4] = 0, + [0][1][2][1][RTW89_WW][6] = 0, + [0][1][2][1][RTW89_WW][8] = 0, + [0][1][2][1][RTW89_WW][10] = 0, + [0][1][2][1][RTW89_WW][12] = 0, + [0][1][2][1][RTW89_WW][14] = 0, + [0][1][2][1][RTW89_WW][15] = 0, + [0][1][2][1][RTW89_WW][17] = 0, + [0][1][2][1][RTW89_WW][19] = 0, + [0][1][2][1][RTW89_WW][21] = 0, + [0][1][2][1][RTW89_WW][23] = 0, + [0][1][2][1][RTW89_WW][25] = 0, + [0][1][2][1][RTW89_WW][27] = 0, + [0][1][2][1][RTW89_WW][29] = 0, + [0][1][2][1][RTW89_WW][31] = 0, + [0][1][2][1][RTW89_WW][33] = 0, + [0][1][2][1][RTW89_WW][35] = 0, + [0][1][2][1][RTW89_WW][37] = 0, + [0][1][2][1][RTW89_WW][38] = 0, + [0][1][2][1][RTW89_WW][40] = 0, + [0][1][2][1][RTW89_WW][42] = 0, + [0][1][2][1][RTW89_WW][44] = 0, + [0][1][2][1][RTW89_WW][46] = 0, + [0][1][2][1][RTW89_WW][48] = 0, + [0][1][2][1][RTW89_WW][50] = 0, + [0][1][2][1][RTW89_WW][52] = 0, + [1][0][2][0][RTW89_WW][1] = 62, + [1][0][2][0][RTW89_WW][5] = 62, + [1][0][2][0][RTW89_WW][9] = 62, + [1][0][2][0][RTW89_WW][13] = 62, + [1][0][2][0][RTW89_WW][16] = 66, + [1][0][2][0][RTW89_WW][20] = 66, + [1][0][2][0][RTW89_WW][24] = 66, + [1][0][2][0][RTW89_WW][28] = 66, + [1][0][2][0][RTW89_WW][32] = 66, + [1][0][2][0][RTW89_WW][36] = 76, + [1][0][2][0][RTW89_WW][39] = 30, + [1][0][2][0][RTW89_WW][43] = 30, + [1][0][2][0][RTW89_WW][47] = 84, + [1][0][2][0][RTW89_WW][51] = 84, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][5] = 0, + [1][1][2][0][RTW89_WW][9] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][16] = 0, + [1][1][2][0][RTW89_WW][20] = 0, + [1][1][2][0][RTW89_WW][24] = 0, + [1][1][2][0][RTW89_WW][28] = 0, + [1][1][2][0][RTW89_WW][32] = 0, + [1][1][2][0][RTW89_WW][36] = 0, + [1][1][2][0][RTW89_WW][39] = 0, + [1][1][2][0][RTW89_WW][43] = 0, + [1][1][2][0][RTW89_WW][47] = 0, + [1][1][2][0][RTW89_WW][51] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][5] = 0, + [1][1][2][1][RTW89_WW][9] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][16] = 0, + [1][1][2][1][RTW89_WW][20] = 0, + [1][1][2][1][RTW89_WW][24] = 0, + [1][1][2][1][RTW89_WW][28] = 0, + [1][1][2][1][RTW89_WW][32] = 0, + [1][1][2][1][RTW89_WW][36] = 0, + [1][1][2][1][RTW89_WW][39] = 0, + [1][1][2][1][RTW89_WW][43] = 0, + [1][1][2][1][RTW89_WW][47] = 0, + [1][1][2][1][RTW89_WW][51] = 0, + [2][0][2][0][RTW89_WW][3] = 60, + [2][0][2][0][RTW89_WW][11] = 56, + [2][0][2][0][RTW89_WW][18] = 64, + [2][0][2][0][RTW89_WW][26] = 64, + [2][0][2][0][RTW89_WW][34] = 72, + [2][0][2][0][RTW89_WW][41] = 30, + [2][0][2][0][RTW89_WW][49] = 74, + [2][1][2][0][RTW89_WW][3] = 0, + [2][1][2][0][RTW89_WW][11] = 0, + [2][1][2][0][RTW89_WW][18] = 0, + [2][1][2][0][RTW89_WW][26] = 0, + [2][1][2][0][RTW89_WW][34] = 0, + [2][1][2][0][RTW89_WW][41] = 0, + [2][1][2][0][RTW89_WW][49] = 0, + [2][1][2][1][RTW89_WW][3] = 0, + [2][1][2][1][RTW89_WW][11] = 0, + [2][1][2][1][RTW89_WW][18] = 0, + [2][1][2][1][RTW89_WW][26] = 0, + [2][1][2][1][RTW89_WW][34] = 0, + [2][1][2][1][RTW89_WW][41] = 0, + [2][1][2][1][RTW89_WW][49] = 0, + [3][0][2][0][RTW89_WW][7] = 0, + [3][0][2][0][RTW89_WW][22] = 0, + [3][0][2][0][RTW89_WW][45] = 0, + [3][1][2][0][RTW89_WW][7] = 0, + [3][1][2][0][RTW89_WW][22] = 0, + [3][1][2][0][RTW89_WW][45] = 0, + [3][1][2][1][RTW89_WW][7] = 0, + [3][1][2][1][RTW89_WW][22] = 0, + [3][1][2][1][RTW89_WW][45] = 0, + [0][0][1][0][RTW89_FCC][0] = 80, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 60, + [0][0][1][0][RTW89_IC][0] = 62, + [0][0][1][0][RTW89_KCC][0] = 74, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CN][0] = 60, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][2] = 82, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 60, + [0][0][1][0][RTW89_IC][2] = 62, + [0][0][1][0][RTW89_KCC][2] = 74, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CN][2] = 60, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][4] = 82, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 60, + [0][0][1][0][RTW89_IC][4] = 62, + [0][0][1][0][RTW89_KCC][4] = 74, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CN][4] = 60, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][6] = 82, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 60, + [0][0][1][0][RTW89_IC][6] = 62, + [0][0][1][0][RTW89_KCC][6] = 50, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CN][6] = 60, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][8] = 82, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 60, + [0][0][1][0][RTW89_IC][8] = 64, + [0][0][1][0][RTW89_KCC][8] = 74, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CN][8] = 60, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][10] = 82, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 60, + [0][0][1][0][RTW89_IC][10] = 64, + [0][0][1][0][RTW89_KCC][10] = 74, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CN][10] = 60, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][12] = 82, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 60, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 76, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CN][12] = 60, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][14] = 78, + [0][0][1][0][RTW89_ETSI][14] = 58, + [0][0][1][0][RTW89_MKK][14] = 60, + [0][0][1][0][RTW89_IC][14] = 64, + [0][0][1][0][RTW89_KCC][14] = 76, + [0][0][1][0][RTW89_ACMA][14] = 58, + [0][0][1][0][RTW89_CN][14] = 60, + [0][0][1][0][RTW89_UK][14] = 58, + [0][0][1][0][RTW89_FCC][15] = 78, + [0][0][1][0][RTW89_ETSI][15] = 58, + [0][0][1][0][RTW89_MKK][15] = 78, + [0][0][1][0][RTW89_IC][15] = 78, + [0][0][1][0][RTW89_KCC][15] = 78, + [0][0][1][0][RTW89_ACMA][15] = 58, + [0][0][1][0][RTW89_CN][15] = 127, + [0][0][1][0][RTW89_UK][15] = 58, + [0][0][1][0][RTW89_FCC][17] = 82, + [0][0][1][0][RTW89_ETSI][17] = 60, + [0][0][1][0][RTW89_MKK][17] = 78, + [0][0][1][0][RTW89_IC][17] = 82, + [0][0][1][0][RTW89_KCC][17] = 78, + [0][0][1][0][RTW89_ACMA][17] = 60, + [0][0][1][0][RTW89_CN][17] = 127, + [0][0][1][0][RTW89_UK][17] = 60, + [0][0][1][0][RTW89_FCC][19] = 82, + [0][0][1][0][RTW89_ETSI][19] = 60, + [0][0][1][0][RTW89_MKK][19] = 78, + [0][0][1][0][RTW89_IC][19] = 82, + [0][0][1][0][RTW89_KCC][19] = 78, + [0][0][1][0][RTW89_ACMA][19] = 60, + [0][0][1][0][RTW89_CN][19] = 127, + [0][0][1][0][RTW89_UK][19] = 60, + [0][0][1][0][RTW89_FCC][21] = 82, + [0][0][1][0][RTW89_ETSI][21] = 60, + [0][0][1][0][RTW89_MKK][21] = 78, + [0][0][1][0][RTW89_IC][21] = 82, + [0][0][1][0][RTW89_KCC][21] = 78, + [0][0][1][0][RTW89_ACMA][21] = 60, + [0][0][1][0][RTW89_CN][21] = 127, + [0][0][1][0][RTW89_UK][21] = 60, + [0][0][1][0][RTW89_FCC][23] = 82, + [0][0][1][0][RTW89_ETSI][23] = 60, + [0][0][1][0][RTW89_MKK][23] = 78, + [0][0][1][0][RTW89_IC][23] = 82, + [0][0][1][0][RTW89_KCC][23] = 78, + [0][0][1][0][RTW89_ACMA][23] = 60, + [0][0][1][0][RTW89_CN][23] = 127, + [0][0][1][0][RTW89_UK][23] = 60, + [0][0][1][0][RTW89_FCC][25] = 82, + [0][0][1][0][RTW89_ETSI][25] = 60, + [0][0][1][0][RTW89_MKK][25] = 78, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_KCC][25] = 78, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_CN][25] = 127, + [0][0][1][0][RTW89_UK][25] = 60, + [0][0][1][0][RTW89_FCC][27] = 82, + [0][0][1][0][RTW89_ETSI][27] = 60, + [0][0][1][0][RTW89_MKK][27] = 78, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_KCC][27] = 78, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_CN][27] = 127, + [0][0][1][0][RTW89_UK][27] = 60, + [0][0][1][0][RTW89_FCC][29] = 82, + [0][0][1][0][RTW89_ETSI][29] = 60, + [0][0][1][0][RTW89_MKK][29] = 78, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_KCC][29] = 78, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_CN][29] = 127, + [0][0][1][0][RTW89_UK][29] = 60, + [0][0][1][0][RTW89_FCC][31] = 82, + [0][0][1][0][RTW89_ETSI][31] = 60, + [0][0][1][0][RTW89_MKK][31] = 78, + [0][0][1][0][RTW89_IC][31] = 82, + [0][0][1][0][RTW89_KCC][31] = 74, + [0][0][1][0][RTW89_ACMA][31] = 60, + [0][0][1][0][RTW89_CN][31] = 127, + [0][0][1][0][RTW89_UK][31] = 60, + [0][0][1][0][RTW89_FCC][33] = 82, + [0][0][1][0][RTW89_ETSI][33] = 60, + [0][0][1][0][RTW89_MKK][33] = 78, + [0][0][1][0][RTW89_IC][33] = 82, + [0][0][1][0][RTW89_KCC][33] = 74, + [0][0][1][0][RTW89_ACMA][33] = 60, + [0][0][1][0][RTW89_CN][33] = 127, + [0][0][1][0][RTW89_UK][33] = 60, + [0][0][1][0][RTW89_FCC][35] = 72, + [0][0][1][0][RTW89_ETSI][35] = 60, + [0][0][1][0][RTW89_MKK][35] = 78, + [0][0][1][0][RTW89_IC][35] = 72, + [0][0][1][0][RTW89_KCC][35] = 74, + [0][0][1][0][RTW89_ACMA][35] = 60, + [0][0][1][0][RTW89_CN][35] = 127, + [0][0][1][0][RTW89_UK][35] = 60, + [0][0][1][0][RTW89_FCC][37] = 82, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 78, + [0][0][1][0][RTW89_IC][37] = 82, + [0][0][1][0][RTW89_KCC][37] = 74, + [0][0][1][0][RTW89_ACMA][37] = 78, + [0][0][1][0][RTW89_CN][37] = 127, + [0][0][1][0][RTW89_UK][37] = 78, + [0][0][1][0][RTW89_FCC][38] = 82, + [0][0][1][0][RTW89_ETSI][38] = 30, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 82, + [0][0][1][0][RTW89_KCC][38] = 70, + [0][0][1][0][RTW89_ACMA][38] = 78, + [0][0][1][0][RTW89_CN][38] = 74, + [0][0][1][0][RTW89_UK][38] = 58, + [0][0][1][0][RTW89_FCC][40] = 82, + [0][0][1][0][RTW89_ETSI][40] = 30, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 82, + [0][0][1][0][RTW89_KCC][40] = 76, + [0][0][1][0][RTW89_ACMA][40] = 78, + [0][0][1][0][RTW89_CN][40] = 74, + [0][0][1][0][RTW89_UK][40] = 58, + [0][0][1][0][RTW89_FCC][42] = 82, + [0][0][1][0][RTW89_ETSI][42] = 30, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 82, + [0][0][1][0][RTW89_KCC][42] = 76, + [0][0][1][0][RTW89_ACMA][42] = 78, + [0][0][1][0][RTW89_CN][42] = 74, + [0][0][1][0][RTW89_UK][42] = 58, + [0][0][1][0][RTW89_FCC][44] = 82, + [0][0][1][0][RTW89_ETSI][44] = 30, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 82, + [0][0][1][0][RTW89_KCC][44] = 76, + [0][0][1][0][RTW89_ACMA][44] = 78, + [0][0][1][0][RTW89_CN][44] = 58, + [0][0][1][0][RTW89_UK][44] = 58, + [0][0][1][0][RTW89_FCC][46] = 82, + [0][0][1][0][RTW89_ETSI][46] = 30, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 82, + [0][0][1][0][RTW89_KCC][46] = 76, + [0][0][1][0][RTW89_ACMA][46] = 78, + [0][0][1][0][RTW89_CN][46] = 58, + [0][0][1][0][RTW89_UK][46] = 58, + [0][0][1][0][RTW89_FCC][48] = 72, + [0][0][1][0][RTW89_ETSI][48] = 127, + [0][0][1][0][RTW89_MKK][48] = 127, + [0][0][1][0][RTW89_IC][48] = 72, + [0][0][1][0][RTW89_KCC][48] = 127, + [0][0][1][0][RTW89_ACMA][48] = 127, + [0][0][1][0][RTW89_CN][48] = 127, + [0][0][1][0][RTW89_UK][48] = 127, + [0][0][1][0][RTW89_FCC][50] = 72, + [0][0][1][0][RTW89_ETSI][50] = 127, + [0][0][1][0][RTW89_MKK][50] = 127, + [0][0][1][0][RTW89_IC][50] = 72, + [0][0][1][0][RTW89_KCC][50] = 127, + [0][0][1][0][RTW89_ACMA][50] = 127, + [0][0][1][0][RTW89_CN][50] = 127, + [0][0][1][0][RTW89_UK][50] = 127, + [0][0][1][0][RTW89_FCC][52] = 72, + [0][0][1][0][RTW89_ETSI][52] = 127, + [0][0][1][0][RTW89_MKK][52] = 127, + [0][0][1][0][RTW89_IC][52] = 72, + [0][0][1][0][RTW89_KCC][52] = 127, + [0][0][1][0][RTW89_ACMA][52] = 127, + [0][0][1][0][RTW89_CN][52] = 127, + [0][0][1][0][RTW89_UK][52] = 127, + [0][1][1][0][RTW89_FCC][0] = 127, + [0][1][1][0][RTW89_ETSI][0] = 127, + [0][1][1][0][RTW89_MKK][0] = 127, + [0][1][1][0][RTW89_IC][0] = 127, + [0][1][1][0][RTW89_KCC][0] = 127, + [0][1][1][0][RTW89_ACMA][0] = 127, + [0][1][1][0][RTW89_CN][0] = 127, + [0][1][1][0][RTW89_UK][0] = 127, + [0][1][1][0][RTW89_FCC][2] = 127, + [0][1][1][0][RTW89_ETSI][2] = 127, + [0][1][1][0][RTW89_MKK][2] = 127, + [0][1][1][0][RTW89_IC][2] = 127, + [0][1][1][0][RTW89_KCC][2] = 127, + [0][1][1][0][RTW89_ACMA][2] = 127, + [0][1][1][0][RTW89_CN][2] = 127, + [0][1][1][0][RTW89_UK][2] = 127, + [0][1][1][0][RTW89_FCC][4] = 127, + [0][1][1][0][RTW89_ETSI][4] = 127, + [0][1][1][0][RTW89_MKK][4] = 127, + [0][1][1][0][RTW89_IC][4] = 127, + [0][1][1][0][RTW89_KCC][4] = 127, + [0][1][1][0][RTW89_ACMA][4] = 127, + [0][1][1][0][RTW89_CN][4] = 127, + [0][1][1][0][RTW89_UK][4] = 127, + [0][1][1][0][RTW89_FCC][6] = 127, + [0][1][1][0][RTW89_ETSI][6] = 127, + [0][1][1][0][RTW89_MKK][6] = 127, + [0][1][1][0][RTW89_IC][6] = 127, + [0][1][1][0][RTW89_KCC][6] = 127, + [0][1][1][0][RTW89_ACMA][6] = 127, + [0][1][1][0][RTW89_CN][6] = 127, + [0][1][1][0][RTW89_UK][6] = 127, + [0][1][1][0][RTW89_FCC][8] = 127, + [0][1][1][0][RTW89_ETSI][8] = 127, + [0][1][1][0][RTW89_MKK][8] = 127, + [0][1][1][0][RTW89_IC][8] = 127, + [0][1][1][0][RTW89_KCC][8] = 127, + [0][1][1][0][RTW89_ACMA][8] = 127, + [0][1][1][0][RTW89_CN][8] = 127, + [0][1][1][0][RTW89_UK][8] = 127, + [0][1][1][0][RTW89_FCC][10] = 127, + [0][1][1][0][RTW89_ETSI][10] = 127, + [0][1][1][0][RTW89_MKK][10] = 127, + [0][1][1][0][RTW89_IC][10] = 127, + [0][1][1][0][RTW89_KCC][10] = 127, + [0][1][1][0][RTW89_ACMA][10] = 127, + [0][1][1][0][RTW89_CN][10] = 127, + [0][1][1][0][RTW89_UK][10] = 127, + [0][1][1][0][RTW89_FCC][12] = 127, + [0][1][1][0][RTW89_ETSI][12] = 127, + [0][1][1][0][RTW89_MKK][12] = 127, + [0][1][1][0][RTW89_IC][12] = 127, + [0][1][1][0][RTW89_KCC][12] = 127, + [0][1][1][0][RTW89_ACMA][12] = 127, + [0][1][1][0][RTW89_CN][12] = 127, + [0][1][1][0][RTW89_UK][12] = 127, + [0][1][1][0][RTW89_FCC][14] = 127, + [0][1][1][0][RTW89_ETSI][14] = 127, + [0][1][1][0][RTW89_MKK][14] = 127, + [0][1][1][0][RTW89_IC][14] = 127, + [0][1][1][0][RTW89_KCC][14] = 127, + [0][1][1][0][RTW89_ACMA][14] = 127, + [0][1][1][0][RTW89_CN][14] = 127, + [0][1][1][0][RTW89_UK][14] = 127, + [0][1][1][0][RTW89_FCC][15] = 127, + [0][1][1][0][RTW89_ETSI][15] = 127, + [0][1][1][0][RTW89_MKK][15] = 127, + [0][1][1][0][RTW89_IC][15] = 127, + [0][1][1][0][RTW89_KCC][15] = 127, + [0][1][1][0][RTW89_ACMA][15] = 127, + [0][1][1][0][RTW89_CN][15] = 127, + [0][1][1][0][RTW89_UK][15] = 127, + [0][1][1][0][RTW89_FCC][17] = 127, + [0][1][1][0][RTW89_ETSI][17] = 127, + [0][1][1][0][RTW89_MKK][17] = 127, + [0][1][1][0][RTW89_IC][17] = 127, + [0][1][1][0][RTW89_KCC][17] = 127, + [0][1][1][0][RTW89_ACMA][17] = 127, + [0][1][1][0][RTW89_CN][17] = 127, + [0][1][1][0][RTW89_UK][17] = 127, + [0][1][1][0][RTW89_FCC][19] = 127, + [0][1][1][0][RTW89_ETSI][19] = 127, + [0][1][1][0][RTW89_MKK][19] = 127, + [0][1][1][0][RTW89_IC][19] = 127, + [0][1][1][0][RTW89_KCC][19] = 127, + [0][1][1][0][RTW89_ACMA][19] = 127, + [0][1][1][0][RTW89_CN][19] = 127, + [0][1][1][0][RTW89_UK][19] = 127, + [0][1][1][0][RTW89_FCC][21] = 127, + [0][1][1][0][RTW89_ETSI][21] = 127, + [0][1][1][0][RTW89_MKK][21] = 127, + [0][1][1][0][RTW89_IC][21] = 127, + [0][1][1][0][RTW89_KCC][21] = 127, + [0][1][1][0][RTW89_ACMA][21] = 127, + [0][1][1][0][RTW89_CN][21] = 127, + [0][1][1][0][RTW89_UK][21] = 127, + [0][1][1][0][RTW89_FCC][23] = 127, + [0][1][1][0][RTW89_ETSI][23] = 127, + [0][1][1][0][RTW89_MKK][23] = 127, + [0][1][1][0][RTW89_IC][23] = 127, + [0][1][1][0][RTW89_KCC][23] = 127, + [0][1][1][0][RTW89_ACMA][23] = 127, + [0][1][1][0][RTW89_CN][23] = 127, + [0][1][1][0][RTW89_UK][23] = 127, + [0][1][1][0][RTW89_FCC][25] = 127, + [0][1][1][0][RTW89_ETSI][25] = 127, + [0][1][1][0][RTW89_MKK][25] = 127, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_KCC][25] = 127, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_CN][25] = 127, + [0][1][1][0][RTW89_UK][25] = 127, + [0][1][1][0][RTW89_FCC][27] = 127, + [0][1][1][0][RTW89_ETSI][27] = 127, + [0][1][1][0][RTW89_MKK][27] = 127, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_KCC][27] = 127, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_CN][27] = 127, + [0][1][1][0][RTW89_UK][27] = 127, + [0][1][1][0][RTW89_FCC][29] = 127, + [0][1][1][0][RTW89_ETSI][29] = 127, + [0][1][1][0][RTW89_MKK][29] = 127, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_KCC][29] = 127, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_CN][29] = 127, + [0][1][1][0][RTW89_UK][29] = 127, + [0][1][1][0][RTW89_FCC][31] = 127, + [0][1][1][0][RTW89_ETSI][31] = 127, + [0][1][1][0][RTW89_MKK][31] = 127, + [0][1][1][0][RTW89_IC][31] = 127, + [0][1][1][0][RTW89_KCC][31] = 127, + [0][1][1][0][RTW89_ACMA][31] = 127, + [0][1][1][0][RTW89_CN][31] = 127, + [0][1][1][0][RTW89_UK][31] = 127, + [0][1][1][0][RTW89_FCC][33] = 127, + [0][1][1][0][RTW89_ETSI][33] = 127, + [0][1][1][0][RTW89_MKK][33] = 127, + [0][1][1][0][RTW89_IC][33] = 127, + [0][1][1][0][RTW89_KCC][33] = 127, + [0][1][1][0][RTW89_ACMA][33] = 127, + [0][1][1][0][RTW89_CN][33] = 127, + [0][1][1][0][RTW89_UK][33] = 127, + [0][1][1][0][RTW89_FCC][35] = 127, + [0][1][1][0][RTW89_ETSI][35] = 127, + [0][1][1][0][RTW89_MKK][35] = 127, + [0][1][1][0][RTW89_IC][35] = 127, + [0][1][1][0][RTW89_KCC][35] = 127, + [0][1][1][0][RTW89_ACMA][35] = 127, + [0][1][1][0][RTW89_CN][35] = 127, + [0][1][1][0][RTW89_UK][35] = 127, + [0][1][1][0][RTW89_FCC][37] = 127, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 127, + [0][1][1][0][RTW89_IC][37] = 127, + [0][1][1][0][RTW89_KCC][37] = 127, + [0][1][1][0][RTW89_ACMA][37] = 127, + [0][1][1][0][RTW89_CN][37] = 127, + [0][1][1][0][RTW89_UK][37] = 127, + [0][1][1][0][RTW89_FCC][38] = 127, + [0][1][1][0][RTW89_ETSI][38] = 127, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 127, + [0][1][1][0][RTW89_KCC][38] = 127, + [0][1][1][0][RTW89_ACMA][38] = 127, + [0][1][1][0][RTW89_CN][38] = 127, + [0][1][1][0][RTW89_UK][38] = 127, + [0][1][1][0][RTW89_FCC][40] = 127, + [0][1][1][0][RTW89_ETSI][40] = 127, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 127, + [0][1][1][0][RTW89_KCC][40] = 127, + [0][1][1][0][RTW89_ACMA][40] = 127, + [0][1][1][0][RTW89_CN][40] = 127, + [0][1][1][0][RTW89_UK][40] = 127, + [0][1][1][0][RTW89_FCC][42] = 127, + [0][1][1][0][RTW89_ETSI][42] = 127, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 127, + [0][1][1][0][RTW89_KCC][42] = 127, + [0][1][1][0][RTW89_ACMA][42] = 127, + [0][1][1][0][RTW89_CN][42] = 127, + [0][1][1][0][RTW89_UK][42] = 127, + [0][1][1][0][RTW89_FCC][44] = 127, + [0][1][1][0][RTW89_ETSI][44] = 127, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 127, + [0][1][1][0][RTW89_KCC][44] = 127, + [0][1][1][0][RTW89_ACMA][44] = 127, + [0][1][1][0][RTW89_CN][44] = 127, + [0][1][1][0][RTW89_UK][44] = 127, + [0][1][1][0][RTW89_FCC][46] = 127, + [0][1][1][0][RTW89_ETSI][46] = 127, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 127, + [0][1][1][0][RTW89_KCC][46] = 127, + [0][1][1][0][RTW89_ACMA][46] = 127, + [0][1][1][0][RTW89_CN][46] = 127, + [0][1][1][0][RTW89_UK][46] = 127, + [0][1][1][0][RTW89_FCC][48] = 127, + [0][1][1][0][RTW89_ETSI][48] = 127, + [0][1][1][0][RTW89_MKK][48] = 127, + [0][1][1][0][RTW89_IC][48] = 127, + [0][1][1][0][RTW89_KCC][48] = 127, + [0][1][1][0][RTW89_ACMA][48] = 127, + [0][1][1][0][RTW89_CN][48] = 127, + [0][1][1][0][RTW89_UK][48] = 127, + [0][1][1][0][RTW89_FCC][50] = 127, + [0][1][1][0][RTW89_ETSI][50] = 127, + [0][1][1][0][RTW89_MKK][50] = 127, + [0][1][1][0][RTW89_IC][50] = 127, + [0][1][1][0][RTW89_KCC][50] = 127, + [0][1][1][0][RTW89_ACMA][50] = 127, + [0][1][1][0][RTW89_CN][50] = 127, + [0][1][1][0][RTW89_UK][50] = 127, + [0][1][1][0][RTW89_FCC][52] = 127, + [0][1][1][0][RTW89_ETSI][52] = 127, + [0][1][1][0][RTW89_MKK][52] = 127, + [0][1][1][0][RTW89_IC][52] = 127, + [0][1][1][0][RTW89_KCC][52] = 127, + [0][1][1][0][RTW89_ACMA][52] = 127, + [0][1][1][0][RTW89_CN][52] = 127, + [0][1][1][0][RTW89_UK][52] = 127, + [0][0][2][0][RTW89_FCC][0] = 78, + [0][0][2][0][RTW89_ETSI][0] = 62, + [0][0][2][0][RTW89_MKK][0] = 62, + [0][0][2][0][RTW89_IC][0] = 64, + [0][0][2][0][RTW89_KCC][0] = 76, + [0][0][2][0][RTW89_ACMA][0] = 62, + [0][0][2][0][RTW89_CN][0] = 60, + [0][0][2][0][RTW89_UK][0] = 62, + [0][0][2][0][RTW89_FCC][2] = 82, + [0][0][2][0][RTW89_ETSI][2] = 62, + [0][0][2][0][RTW89_MKK][2] = 62, + [0][0][2][0][RTW89_IC][2] = 64, + [0][0][2][0][RTW89_KCC][2] = 76, + [0][0][2][0][RTW89_ACMA][2] = 62, + [0][0][2][0][RTW89_CN][2] = 60, + [0][0][2][0][RTW89_UK][2] = 62, + [0][0][2][0][RTW89_FCC][4] = 82, + [0][0][2][0][RTW89_ETSI][4] = 62, + [0][0][2][0][RTW89_MKK][4] = 62, + [0][0][2][0][RTW89_IC][4] = 64, + [0][0][2][0][RTW89_KCC][4] = 76, + [0][0][2][0][RTW89_ACMA][4] = 62, + [0][0][2][0][RTW89_CN][4] = 60, + [0][0][2][0][RTW89_UK][4] = 62, + [0][0][2][0][RTW89_FCC][6] = 82, + [0][0][2][0][RTW89_ETSI][6] = 62, + [0][0][2][0][RTW89_MKK][6] = 62, + [0][0][2][0][RTW89_IC][6] = 64, + [0][0][2][0][RTW89_KCC][6] = 54, + [0][0][2][0][RTW89_ACMA][6] = 62, + [0][0][2][0][RTW89_CN][6] = 60, + [0][0][2][0][RTW89_UK][6] = 62, + [0][0][2][0][RTW89_FCC][8] = 82, + [0][0][2][0][RTW89_ETSI][8] = 62, + [0][0][2][0][RTW89_MKK][8] = 62, + [0][0][2][0][RTW89_IC][8] = 64, + [0][0][2][0][RTW89_KCC][8] = 76, + [0][0][2][0][RTW89_ACMA][8] = 62, + [0][0][2][0][RTW89_CN][8] = 60, + [0][0][2][0][RTW89_UK][8] = 62, + [0][0][2][0][RTW89_FCC][10] = 82, + [0][0][2][0][RTW89_ETSI][10] = 62, + [0][0][2][0][RTW89_MKK][10] = 62, + [0][0][2][0][RTW89_IC][10] = 64, + [0][0][2][0][RTW89_KCC][10] = 76, + [0][0][2][0][RTW89_ACMA][10] = 62, + [0][0][2][0][RTW89_CN][10] = 60, + [0][0][2][0][RTW89_UK][10] = 62, + [0][0][2][0][RTW89_FCC][12] = 82, + [0][0][2][0][RTW89_ETSI][12] = 62, + [0][0][2][0][RTW89_MKK][12] = 62, + [0][0][2][0][RTW89_IC][12] = 64, + [0][0][2][0][RTW89_KCC][12] = 78, + [0][0][2][0][RTW89_ACMA][12] = 62, + [0][0][2][0][RTW89_CN][12] = 60, + [0][0][2][0][RTW89_UK][12] = 62, + [0][0][2][0][RTW89_FCC][14] = 76, + [0][0][2][0][RTW89_ETSI][14] = 62, + [0][0][2][0][RTW89_MKK][14] = 62, + [0][0][2][0][RTW89_IC][14] = 64, + [0][0][2][0][RTW89_KCC][14] = 78, + [0][0][2][0][RTW89_ACMA][14] = 62, + [0][0][2][0][RTW89_CN][14] = 60, + [0][0][2][0][RTW89_UK][14] = 62, + [0][0][2][0][RTW89_FCC][15] = 76, + [0][0][2][0][RTW89_ETSI][15] = 60, + [0][0][2][0][RTW89_MKK][15] = 78, + [0][0][2][0][RTW89_IC][15] = 76, + [0][0][2][0][RTW89_KCC][15] = 78, + [0][0][2][0][RTW89_ACMA][15] = 60, + [0][0][2][0][RTW89_CN][15] = 127, + [0][0][2][0][RTW89_UK][15] = 60, + [0][0][2][0][RTW89_FCC][17] = 82, + [0][0][2][0][RTW89_ETSI][17] = 62, + [0][0][2][0][RTW89_MKK][17] = 78, + [0][0][2][0][RTW89_IC][17] = 82, + [0][0][2][0][RTW89_KCC][17] = 78, + [0][0][2][0][RTW89_ACMA][17] = 62, + [0][0][2][0][RTW89_CN][17] = 127, + [0][0][2][0][RTW89_UK][17] = 62, + [0][0][2][0][RTW89_FCC][19] = 82, + [0][0][2][0][RTW89_ETSI][19] = 62, + [0][0][2][0][RTW89_MKK][19] = 78, + [0][0][2][0][RTW89_IC][19] = 82, + [0][0][2][0][RTW89_KCC][19] = 78, + [0][0][2][0][RTW89_ACMA][19] = 62, + [0][0][2][0][RTW89_CN][19] = 127, + [0][0][2][0][RTW89_UK][19] = 62, + [0][0][2][0][RTW89_FCC][21] = 82, + [0][0][2][0][RTW89_ETSI][21] = 62, + [0][0][2][0][RTW89_MKK][21] = 78, + [0][0][2][0][RTW89_IC][21] = 82, + [0][0][2][0][RTW89_KCC][21] = 78, + [0][0][2][0][RTW89_ACMA][21] = 62, + [0][0][2][0][RTW89_CN][21] = 127, + [0][0][2][0][RTW89_UK][21] = 62, + [0][0][2][0][RTW89_FCC][23] = 82, + [0][0][2][0][RTW89_ETSI][23] = 62, + [0][0][2][0][RTW89_MKK][23] = 78, + [0][0][2][0][RTW89_IC][23] = 82, + [0][0][2][0][RTW89_KCC][23] = 78, + [0][0][2][0][RTW89_ACMA][23] = 62, + [0][0][2][0][RTW89_CN][23] = 127, + [0][0][2][0][RTW89_UK][23] = 62, + [0][0][2][0][RTW89_FCC][25] = 82, + [0][0][2][0][RTW89_ETSI][25] = 62, + [0][0][2][0][RTW89_MKK][25] = 78, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_KCC][25] = 78, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_CN][25] = 127, + [0][0][2][0][RTW89_UK][25] = 62, + [0][0][2][0][RTW89_FCC][27] = 82, + [0][0][2][0][RTW89_ETSI][27] = 62, + [0][0][2][0][RTW89_MKK][27] = 78, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_KCC][27] = 78, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_CN][27] = 127, + [0][0][2][0][RTW89_UK][27] = 62, + [0][0][2][0][RTW89_FCC][29] = 82, + [0][0][2][0][RTW89_ETSI][29] = 62, + [0][0][2][0][RTW89_MKK][29] = 78, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_KCC][29] = 78, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_CN][29] = 127, + [0][0][2][0][RTW89_UK][29] = 62, + [0][0][2][0][RTW89_FCC][31] = 82, + [0][0][2][0][RTW89_ETSI][31] = 62, + [0][0][2][0][RTW89_MKK][31] = 78, + [0][0][2][0][RTW89_IC][31] = 82, + [0][0][2][0][RTW89_KCC][31] = 74, + [0][0][2][0][RTW89_ACMA][31] = 62, + [0][0][2][0][RTW89_CN][31] = 127, + [0][0][2][0][RTW89_UK][31] = 62, + [0][0][2][0][RTW89_FCC][33] = 82, + [0][0][2][0][RTW89_ETSI][33] = 62, + [0][0][2][0][RTW89_MKK][33] = 78, + [0][0][2][0][RTW89_IC][33] = 82, + [0][0][2][0][RTW89_KCC][33] = 74, + [0][0][2][0][RTW89_ACMA][33] = 62, + [0][0][2][0][RTW89_CN][33] = 127, + [0][0][2][0][RTW89_UK][33] = 62, + [0][0][2][0][RTW89_FCC][35] = 72, + [0][0][2][0][RTW89_ETSI][35] = 62, + [0][0][2][0][RTW89_MKK][35] = 78, + [0][0][2][0][RTW89_IC][35] = 72, + [0][0][2][0][RTW89_KCC][35] = 74, + [0][0][2][0][RTW89_ACMA][35] = 62, + [0][0][2][0][RTW89_CN][35] = 127, + [0][0][2][0][RTW89_UK][35] = 62, + [0][0][2][0][RTW89_FCC][37] = 82, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 78, + [0][0][2][0][RTW89_IC][37] = 82, + [0][0][2][0][RTW89_KCC][37] = 76, + [0][0][2][0][RTW89_ACMA][37] = 78, + [0][0][2][0][RTW89_CN][37] = 127, + [0][0][2][0][RTW89_UK][37] = 78, + [0][0][2][0][RTW89_FCC][38] = 82, + [0][0][2][0][RTW89_ETSI][38] = 30, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 82, + [0][0][2][0][RTW89_KCC][38] = 66, + [0][0][2][0][RTW89_ACMA][38] = 78, + [0][0][2][0][RTW89_CN][38] = 70, + [0][0][2][0][RTW89_UK][38] = 60, + [0][0][2][0][RTW89_FCC][40] = 82, + [0][0][2][0][RTW89_ETSI][40] = 30, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 82, + [0][0][2][0][RTW89_KCC][40] = 74, + [0][0][2][0][RTW89_ACMA][40] = 78, + [0][0][2][0][RTW89_CN][40] = 70, + [0][0][2][0][RTW89_UK][40] = 60, + [0][0][2][0][RTW89_FCC][42] = 82, + [0][0][2][0][RTW89_ETSI][42] = 30, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 82, + [0][0][2][0][RTW89_KCC][42] = 74, + [0][0][2][0][RTW89_ACMA][42] = 78, + [0][0][2][0][RTW89_CN][42] = 70, + [0][0][2][0][RTW89_UK][42] = 60, + [0][0][2][0][RTW89_FCC][44] = 82, + [0][0][2][0][RTW89_ETSI][44] = 30, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 82, + [0][0][2][0][RTW89_KCC][44] = 74, + [0][0][2][0][RTW89_ACMA][44] = 78, + [0][0][2][0][RTW89_CN][44] = 58, + [0][0][2][0][RTW89_UK][44] = 60, + [0][0][2][0][RTW89_FCC][46] = 82, + [0][0][2][0][RTW89_ETSI][46] = 30, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 82, + [0][0][2][0][RTW89_KCC][46] = 74, + [0][0][2][0][RTW89_ACMA][46] = 78, + [0][0][2][0][RTW89_CN][46] = 58, + [0][0][2][0][RTW89_UK][46] = 60, + [0][0][2][0][RTW89_FCC][48] = 74, + [0][0][2][0][RTW89_ETSI][48] = 127, + [0][0][2][0][RTW89_MKK][48] = 127, + [0][0][2][0][RTW89_IC][48] = 74, + [0][0][2][0][RTW89_KCC][48] = 127, + [0][0][2][0][RTW89_ACMA][48] = 127, + [0][0][2][0][RTW89_CN][48] = 127, + [0][0][2][0][RTW89_UK][48] = 127, + [0][0][2][0][RTW89_FCC][50] = 76, + [0][0][2][0][RTW89_ETSI][50] = 127, + [0][0][2][0][RTW89_MKK][50] = 127, + [0][0][2][0][RTW89_IC][50] = 76, + [0][0][2][0][RTW89_KCC][50] = 127, + [0][0][2][0][RTW89_ACMA][50] = 127, + [0][0][2][0][RTW89_CN][50] = 127, + [0][0][2][0][RTW89_UK][50] = 127, + [0][0][2][0][RTW89_FCC][52] = 76, + [0][0][2][0][RTW89_ETSI][52] = 127, + [0][0][2][0][RTW89_MKK][52] = 127, + [0][0][2][0][RTW89_IC][52] = 76, + [0][0][2][0][RTW89_KCC][52] = 127, + [0][0][2][0][RTW89_ACMA][52] = 127, + [0][0][2][0][RTW89_CN][52] = 127, + [0][0][2][0][RTW89_UK][52] = 127, + [0][1][2][0][RTW89_FCC][0] = 127, + [0][1][2][0][RTW89_ETSI][0] = 127, + [0][1][2][0][RTW89_MKK][0] = 127, + [0][1][2][0][RTW89_IC][0] = 127, + [0][1][2][0][RTW89_KCC][0] = 127, + [0][1][2][0][RTW89_ACMA][0] = 127, + [0][1][2][0][RTW89_CN][0] = 127, + [0][1][2][0][RTW89_UK][0] = 127, + [0][1][2][0][RTW89_FCC][2] = 127, + [0][1][2][0][RTW89_ETSI][2] = 127, + [0][1][2][0][RTW89_MKK][2] = 127, + [0][1][2][0][RTW89_IC][2] = 127, + [0][1][2][0][RTW89_KCC][2] = 127, + [0][1][2][0][RTW89_ACMA][2] = 127, + [0][1][2][0][RTW89_CN][2] = 127, + [0][1][2][0][RTW89_UK][2] = 127, + [0][1][2][0][RTW89_FCC][4] = 127, + [0][1][2][0][RTW89_ETSI][4] = 127, + [0][1][2][0][RTW89_MKK][4] = 127, + [0][1][2][0][RTW89_IC][4] = 127, + [0][1][2][0][RTW89_KCC][4] = 127, + [0][1][2][0][RTW89_ACMA][4] = 127, + [0][1][2][0][RTW89_CN][4] = 127, + [0][1][2][0][RTW89_UK][4] = 127, + [0][1][2][0][RTW89_FCC][6] = 127, + [0][1][2][0][RTW89_ETSI][6] = 127, + [0][1][2][0][RTW89_MKK][6] = 127, + [0][1][2][0][RTW89_IC][6] = 127, + [0][1][2][0][RTW89_KCC][6] = 127, + [0][1][2][0][RTW89_ACMA][6] = 127, + [0][1][2][0][RTW89_CN][6] = 127, + [0][1][2][0][RTW89_UK][6] = 127, + [0][1][2][0][RTW89_FCC][8] = 127, + [0][1][2][0][RTW89_ETSI][8] = 127, + [0][1][2][0][RTW89_MKK][8] = 127, + [0][1][2][0][RTW89_IC][8] = 127, + [0][1][2][0][RTW89_KCC][8] = 127, + [0][1][2][0][RTW89_ACMA][8] = 127, + [0][1][2][0][RTW89_CN][8] = 127, + [0][1][2][0][RTW89_UK][8] = 127, + [0][1][2][0][RTW89_FCC][10] = 127, + [0][1][2][0][RTW89_ETSI][10] = 127, + [0][1][2][0][RTW89_MKK][10] = 127, + [0][1][2][0][RTW89_IC][10] = 127, + [0][1][2][0][RTW89_KCC][10] = 127, + [0][1][2][0][RTW89_ACMA][10] = 127, + [0][1][2][0][RTW89_CN][10] = 127, + [0][1][2][0][RTW89_UK][10] = 127, + [0][1][2][0][RTW89_FCC][12] = 127, + [0][1][2][0][RTW89_ETSI][12] = 127, + [0][1][2][0][RTW89_MKK][12] = 127, + [0][1][2][0][RTW89_IC][12] = 127, + [0][1][2][0][RTW89_KCC][12] = 127, + [0][1][2][0][RTW89_ACMA][12] = 127, + [0][1][2][0][RTW89_CN][12] = 127, + [0][1][2][0][RTW89_UK][12] = 127, + [0][1][2][0][RTW89_FCC][14] = 127, + [0][1][2][0][RTW89_ETSI][14] = 127, + [0][1][2][0][RTW89_MKK][14] = 127, + [0][1][2][0][RTW89_IC][14] = 127, + [0][1][2][0][RTW89_KCC][14] = 127, + [0][1][2][0][RTW89_ACMA][14] = 127, + [0][1][2][0][RTW89_CN][14] = 127, + [0][1][2][0][RTW89_UK][14] = 127, + [0][1][2][0][RTW89_FCC][15] = 127, + [0][1][2][0][RTW89_ETSI][15] = 127, + [0][1][2][0][RTW89_MKK][15] = 127, + [0][1][2][0][RTW89_IC][15] = 127, + [0][1][2][0][RTW89_KCC][15] = 127, + [0][1][2][0][RTW89_ACMA][15] = 127, + [0][1][2][0][RTW89_CN][15] = 127, + [0][1][2][0][RTW89_UK][15] = 127, + [0][1][2][0][RTW89_FCC][17] = 127, + [0][1][2][0][RTW89_ETSI][17] = 127, + [0][1][2][0][RTW89_MKK][17] = 127, + [0][1][2][0][RTW89_IC][17] = 127, + [0][1][2][0][RTW89_KCC][17] = 127, + [0][1][2][0][RTW89_ACMA][17] = 127, + [0][1][2][0][RTW89_CN][17] = 127, + [0][1][2][0][RTW89_UK][17] = 127, + [0][1][2][0][RTW89_FCC][19] = 127, + [0][1][2][0][RTW89_ETSI][19] = 127, + [0][1][2][0][RTW89_MKK][19] = 127, + [0][1][2][0][RTW89_IC][19] = 127, + [0][1][2][0][RTW89_KCC][19] = 127, + [0][1][2][0][RTW89_ACMA][19] = 127, + [0][1][2][0][RTW89_CN][19] = 127, + [0][1][2][0][RTW89_UK][19] = 127, + [0][1][2][0][RTW89_FCC][21] = 127, + [0][1][2][0][RTW89_ETSI][21] = 127, + [0][1][2][0][RTW89_MKK][21] = 127, + [0][1][2][0][RTW89_IC][21] = 127, + [0][1][2][0][RTW89_KCC][21] = 127, + [0][1][2][0][RTW89_ACMA][21] = 127, + [0][1][2][0][RTW89_CN][21] = 127, + [0][1][2][0][RTW89_UK][21] = 127, + [0][1][2][0][RTW89_FCC][23] = 127, + [0][1][2][0][RTW89_ETSI][23] = 127, + [0][1][2][0][RTW89_MKK][23] = 127, + [0][1][2][0][RTW89_IC][23] = 127, + [0][1][2][0][RTW89_KCC][23] = 127, + [0][1][2][0][RTW89_ACMA][23] = 127, + [0][1][2][0][RTW89_CN][23] = 127, + [0][1][2][0][RTW89_UK][23] = 127, + [0][1][2][0][RTW89_FCC][25] = 127, + [0][1][2][0][RTW89_ETSI][25] = 127, + [0][1][2][0][RTW89_MKK][25] = 127, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_KCC][25] = 127, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_CN][25] = 127, + [0][1][2][0][RTW89_UK][25] = 127, + [0][1][2][0][RTW89_FCC][27] = 127, + [0][1][2][0][RTW89_ETSI][27] = 127, + [0][1][2][0][RTW89_MKK][27] = 127, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_KCC][27] = 127, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_CN][27] = 127, + [0][1][2][0][RTW89_UK][27] = 127, + [0][1][2][0][RTW89_FCC][29] = 127, + [0][1][2][0][RTW89_ETSI][29] = 127, + [0][1][2][0][RTW89_MKK][29] = 127, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_KCC][29] = 127, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_CN][29] = 127, + [0][1][2][0][RTW89_UK][29] = 127, + [0][1][2][0][RTW89_FCC][31] = 127, + [0][1][2][0][RTW89_ETSI][31] = 127, + [0][1][2][0][RTW89_MKK][31] = 127, + [0][1][2][0][RTW89_IC][31] = 127, + [0][1][2][0][RTW89_KCC][31] = 127, + [0][1][2][0][RTW89_ACMA][31] = 127, + [0][1][2][0][RTW89_CN][31] = 127, + [0][1][2][0][RTW89_UK][31] = 127, + [0][1][2][0][RTW89_FCC][33] = 127, + [0][1][2][0][RTW89_ETSI][33] = 127, + [0][1][2][0][RTW89_MKK][33] = 127, + [0][1][2][0][RTW89_IC][33] = 127, + [0][1][2][0][RTW89_KCC][33] = 127, + [0][1][2][0][RTW89_ACMA][33] = 127, + [0][1][2][0][RTW89_CN][33] = 127, + [0][1][2][0][RTW89_UK][33] = 127, + [0][1][2][0][RTW89_FCC][35] = 127, + [0][1][2][0][RTW89_ETSI][35] = 127, + [0][1][2][0][RTW89_MKK][35] = 127, + [0][1][2][0][RTW89_IC][35] = 127, + [0][1][2][0][RTW89_KCC][35] = 127, + [0][1][2][0][RTW89_ACMA][35] = 127, + [0][1][2][0][RTW89_CN][35] = 127, + [0][1][2][0][RTW89_UK][35] = 127, + [0][1][2][0][RTW89_FCC][37] = 127, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 127, + [0][1][2][0][RTW89_IC][37] = 127, + [0][1][2][0][RTW89_KCC][37] = 127, + [0][1][2][0][RTW89_ACMA][37] = 127, + [0][1][2][0][RTW89_CN][37] = 127, + [0][1][2][0][RTW89_UK][37] = 127, + [0][1][2][0][RTW89_FCC][38] = 127, + [0][1][2][0][RTW89_ETSI][38] = 127, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 127, + [0][1][2][0][RTW89_KCC][38] = 127, + [0][1][2][0][RTW89_ACMA][38] = 127, + [0][1][2][0][RTW89_CN][38] = 127, + [0][1][2][0][RTW89_UK][38] = 127, + [0][1][2][0][RTW89_FCC][40] = 127, + [0][1][2][0][RTW89_ETSI][40] = 127, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 127, + [0][1][2][0][RTW89_KCC][40] = 127, + [0][1][2][0][RTW89_ACMA][40] = 127, + [0][1][2][0][RTW89_CN][40] = 127, + [0][1][2][0][RTW89_UK][40] = 127, + [0][1][2][0][RTW89_FCC][42] = 127, + [0][1][2][0][RTW89_ETSI][42] = 127, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 127, + [0][1][2][0][RTW89_KCC][42] = 127, + [0][1][2][0][RTW89_ACMA][42] = 127, + [0][1][2][0][RTW89_CN][42] = 127, + [0][1][2][0][RTW89_UK][42] = 127, + [0][1][2][0][RTW89_FCC][44] = 127, + [0][1][2][0][RTW89_ETSI][44] = 127, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 127, + [0][1][2][0][RTW89_KCC][44] = 127, + [0][1][2][0][RTW89_ACMA][44] = 127, + [0][1][2][0][RTW89_CN][44] = 127, + [0][1][2][0][RTW89_UK][44] = 127, + [0][1][2][0][RTW89_FCC][46] = 127, + [0][1][2][0][RTW89_ETSI][46] = 127, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 127, + [0][1][2][0][RTW89_KCC][46] = 127, + [0][1][2][0][RTW89_ACMA][46] = 127, + [0][1][2][0][RTW89_CN][46] = 127, + [0][1][2][0][RTW89_UK][46] = 127, + [0][1][2][0][RTW89_FCC][48] = 127, + [0][1][2][0][RTW89_ETSI][48] = 127, + [0][1][2][0][RTW89_MKK][48] = 127, + [0][1][2][0][RTW89_IC][48] = 127, + [0][1][2][0][RTW89_KCC][48] = 127, + [0][1][2][0][RTW89_ACMA][48] = 127, + [0][1][2][0][RTW89_CN][48] = 127, + [0][1][2][0][RTW89_UK][48] = 127, + [0][1][2][0][RTW89_FCC][50] = 127, + [0][1][2][0][RTW89_ETSI][50] = 127, + [0][1][2][0][RTW89_MKK][50] = 127, + [0][1][2][0][RTW89_IC][50] = 127, + [0][1][2][0][RTW89_KCC][50] = 127, + [0][1][2][0][RTW89_ACMA][50] = 127, + [0][1][2][0][RTW89_CN][50] = 127, + [0][1][2][0][RTW89_UK][50] = 127, + [0][1][2][0][RTW89_FCC][52] = 127, + [0][1][2][0][RTW89_ETSI][52] = 127, + [0][1][2][0][RTW89_MKK][52] = 127, + [0][1][2][0][RTW89_IC][52] = 127, + [0][1][2][0][RTW89_KCC][52] = 127, + [0][1][2][0][RTW89_ACMA][52] = 127, + [0][1][2][0][RTW89_CN][52] = 127, + [0][1][2][0][RTW89_UK][52] = 127, + [0][1][2][1][RTW89_FCC][0] = 127, + [0][1][2][1][RTW89_ETSI][0] = 127, + [0][1][2][1][RTW89_MKK][0] = 127, + [0][1][2][1][RTW89_IC][0] = 127, + [0][1][2][1][RTW89_KCC][0] = 127, + [0][1][2][1][RTW89_ACMA][0] = 127, + [0][1][2][1][RTW89_CN][0] = 127, + [0][1][2][1][RTW89_UK][0] = 127, + [0][1][2][1][RTW89_FCC][2] = 127, + [0][1][2][1][RTW89_ETSI][2] = 127, + [0][1][2][1][RTW89_MKK][2] = 127, + [0][1][2][1][RTW89_IC][2] = 127, + [0][1][2][1][RTW89_KCC][2] = 127, + [0][1][2][1][RTW89_ACMA][2] = 127, + [0][1][2][1][RTW89_CN][2] = 127, + [0][1][2][1][RTW89_UK][2] = 127, + [0][1][2][1][RTW89_FCC][4] = 127, + [0][1][2][1][RTW89_ETSI][4] = 127, + [0][1][2][1][RTW89_MKK][4] = 127, + [0][1][2][1][RTW89_IC][4] = 127, + [0][1][2][1][RTW89_KCC][4] = 127, + [0][1][2][1][RTW89_ACMA][4] = 127, + [0][1][2][1][RTW89_CN][4] = 127, + [0][1][2][1][RTW89_UK][4] = 127, + [0][1][2][1][RTW89_FCC][6] = 127, + [0][1][2][1][RTW89_ETSI][6] = 127, + [0][1][2][1][RTW89_MKK][6] = 127, + [0][1][2][1][RTW89_IC][6] = 127, + [0][1][2][1][RTW89_KCC][6] = 127, + [0][1][2][1][RTW89_ACMA][6] = 127, + [0][1][2][1][RTW89_CN][6] = 127, + [0][1][2][1][RTW89_UK][6] = 127, + [0][1][2][1][RTW89_FCC][8] = 127, + [0][1][2][1][RTW89_ETSI][8] = 127, + [0][1][2][1][RTW89_MKK][8] = 127, + [0][1][2][1][RTW89_IC][8] = 127, + [0][1][2][1][RTW89_KCC][8] = 127, + [0][1][2][1][RTW89_ACMA][8] = 127, + [0][1][2][1][RTW89_CN][8] = 127, + [0][1][2][1][RTW89_UK][8] = 127, + [0][1][2][1][RTW89_FCC][10] = 127, + [0][1][2][1][RTW89_ETSI][10] = 127, + [0][1][2][1][RTW89_MKK][10] = 127, + [0][1][2][1][RTW89_IC][10] = 127, + [0][1][2][1][RTW89_KCC][10] = 127, + [0][1][2][1][RTW89_ACMA][10] = 127, + [0][1][2][1][RTW89_CN][10] = 127, + [0][1][2][1][RTW89_UK][10] = 127, + [0][1][2][1][RTW89_FCC][12] = 127, + [0][1][2][1][RTW89_ETSI][12] = 127, + [0][1][2][1][RTW89_MKK][12] = 127, + [0][1][2][1][RTW89_IC][12] = 127, + [0][1][2][1][RTW89_KCC][12] = 127, + [0][1][2][1][RTW89_ACMA][12] = 127, + [0][1][2][1][RTW89_CN][12] = 127, + [0][1][2][1][RTW89_UK][12] = 127, + [0][1][2][1][RTW89_FCC][14] = 127, + [0][1][2][1][RTW89_ETSI][14] = 127, + [0][1][2][1][RTW89_MKK][14] = 127, + [0][1][2][1][RTW89_IC][14] = 127, + [0][1][2][1][RTW89_KCC][14] = 127, + [0][1][2][1][RTW89_ACMA][14] = 127, + [0][1][2][1][RTW89_CN][14] = 127, + [0][1][2][1][RTW89_UK][14] = 127, + [0][1][2][1][RTW89_FCC][15] = 127, + [0][1][2][1][RTW89_ETSI][15] = 127, + [0][1][2][1][RTW89_MKK][15] = 127, + [0][1][2][1][RTW89_IC][15] = 127, + [0][1][2][1][RTW89_KCC][15] = 127, + [0][1][2][1][RTW89_ACMA][15] = 127, + [0][1][2][1][RTW89_CN][15] = 127, + [0][1][2][1][RTW89_UK][15] = 127, + [0][1][2][1][RTW89_FCC][17] = 127, + [0][1][2][1][RTW89_ETSI][17] = 127, + [0][1][2][1][RTW89_MKK][17] = 127, + [0][1][2][1][RTW89_IC][17] = 127, + [0][1][2][1][RTW89_KCC][17] = 127, + [0][1][2][1][RTW89_ACMA][17] = 127, + [0][1][2][1][RTW89_CN][17] = 127, + [0][1][2][1][RTW89_UK][17] = 127, + [0][1][2][1][RTW89_FCC][19] = 127, + [0][1][2][1][RTW89_ETSI][19] = 127, + [0][1][2][1][RTW89_MKK][19] = 127, + [0][1][2][1][RTW89_IC][19] = 127, + [0][1][2][1][RTW89_KCC][19] = 127, + [0][1][2][1][RTW89_ACMA][19] = 127, + [0][1][2][1][RTW89_CN][19] = 127, + [0][1][2][1][RTW89_UK][19] = 127, + [0][1][2][1][RTW89_FCC][21] = 127, + [0][1][2][1][RTW89_ETSI][21] = 127, + [0][1][2][1][RTW89_MKK][21] = 127, + [0][1][2][1][RTW89_IC][21] = 127, + [0][1][2][1][RTW89_KCC][21] = 127, + [0][1][2][1][RTW89_ACMA][21] = 127, + [0][1][2][1][RTW89_CN][21] = 127, + [0][1][2][1][RTW89_UK][21] = 127, + [0][1][2][1][RTW89_FCC][23] = 127, + [0][1][2][1][RTW89_ETSI][23] = 127, + [0][1][2][1][RTW89_MKK][23] = 127, + [0][1][2][1][RTW89_IC][23] = 127, + [0][1][2][1][RTW89_KCC][23] = 127, + [0][1][2][1][RTW89_ACMA][23] = 127, + [0][1][2][1][RTW89_CN][23] = 127, + [0][1][2][1][RTW89_UK][23] = 127, + [0][1][2][1][RTW89_FCC][25] = 127, + [0][1][2][1][RTW89_ETSI][25] = 127, + [0][1][2][1][RTW89_MKK][25] = 127, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_KCC][25] = 127, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_CN][25] = 127, + [0][1][2][1][RTW89_UK][25] = 127, + [0][1][2][1][RTW89_FCC][27] = 127, + [0][1][2][1][RTW89_ETSI][27] = 127, + [0][1][2][1][RTW89_MKK][27] = 127, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_KCC][27] = 127, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_CN][27] = 127, + [0][1][2][1][RTW89_UK][27] = 127, + [0][1][2][1][RTW89_FCC][29] = 127, + [0][1][2][1][RTW89_ETSI][29] = 127, + [0][1][2][1][RTW89_MKK][29] = 127, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_KCC][29] = 127, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_CN][29] = 127, + [0][1][2][1][RTW89_UK][29] = 127, + [0][1][2][1][RTW89_FCC][31] = 127, + [0][1][2][1][RTW89_ETSI][31] = 127, + [0][1][2][1][RTW89_MKK][31] = 127, + [0][1][2][1][RTW89_IC][31] = 127, + [0][1][2][1][RTW89_KCC][31] = 127, + [0][1][2][1][RTW89_ACMA][31] = 127, + [0][1][2][1][RTW89_CN][31] = 127, + [0][1][2][1][RTW89_UK][31] = 127, + [0][1][2][1][RTW89_FCC][33] = 127, + [0][1][2][1][RTW89_ETSI][33] = 127, + [0][1][2][1][RTW89_MKK][33] = 127, + [0][1][2][1][RTW89_IC][33] = 127, + [0][1][2][1][RTW89_KCC][33] = 127, + [0][1][2][1][RTW89_ACMA][33] = 127, + [0][1][2][1][RTW89_CN][33] = 127, + [0][1][2][1][RTW89_UK][33] = 127, + [0][1][2][1][RTW89_FCC][35] = 127, + [0][1][2][1][RTW89_ETSI][35] = 127, + [0][1][2][1][RTW89_MKK][35] = 127, + [0][1][2][1][RTW89_IC][35] = 127, + [0][1][2][1][RTW89_KCC][35] = 127, + [0][1][2][1][RTW89_ACMA][35] = 127, + [0][1][2][1][RTW89_CN][35] = 127, + [0][1][2][1][RTW89_UK][35] = 127, + [0][1][2][1][RTW89_FCC][37] = 127, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 127, + [0][1][2][1][RTW89_IC][37] = 127, + [0][1][2][1][RTW89_KCC][37] = 127, + [0][1][2][1][RTW89_ACMA][37] = 127, + [0][1][2][1][RTW89_CN][37] = 127, + [0][1][2][1][RTW89_UK][37] = 127, + [0][1][2][1][RTW89_FCC][38] = 127, + [0][1][2][1][RTW89_ETSI][38] = 127, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 127, + [0][1][2][1][RTW89_KCC][38] = 127, + [0][1][2][1][RTW89_ACMA][38] = 127, + [0][1][2][1][RTW89_CN][38] = 127, + [0][1][2][1][RTW89_UK][38] = 127, + [0][1][2][1][RTW89_FCC][40] = 127, + [0][1][2][1][RTW89_ETSI][40] = 127, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 127, + [0][1][2][1][RTW89_KCC][40] = 127, + [0][1][2][1][RTW89_ACMA][40] = 127, + [0][1][2][1][RTW89_CN][40] = 127, + [0][1][2][1][RTW89_UK][40] = 127, + [0][1][2][1][RTW89_FCC][42] = 127, + [0][1][2][1][RTW89_ETSI][42] = 127, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 127, + [0][1][2][1][RTW89_KCC][42] = 127, + [0][1][2][1][RTW89_ACMA][42] = 127, + [0][1][2][1][RTW89_CN][42] = 127, + [0][1][2][1][RTW89_UK][42] = 127, + [0][1][2][1][RTW89_FCC][44] = 127, + [0][1][2][1][RTW89_ETSI][44] = 127, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 127, + [0][1][2][1][RTW89_KCC][44] = 127, + [0][1][2][1][RTW89_ACMA][44] = 127, + [0][1][2][1][RTW89_CN][44] = 127, + [0][1][2][1][RTW89_UK][44] = 127, + [0][1][2][1][RTW89_FCC][46] = 127, + [0][1][2][1][RTW89_ETSI][46] = 127, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 127, + [0][1][2][1][RTW89_KCC][46] = 127, + [0][1][2][1][RTW89_ACMA][46] = 127, + [0][1][2][1][RTW89_CN][46] = 127, + [0][1][2][1][RTW89_UK][46] = 127, + [0][1][2][1][RTW89_FCC][48] = 127, + [0][1][2][1][RTW89_ETSI][48] = 127, + [0][1][2][1][RTW89_MKK][48] = 127, + [0][1][2][1][RTW89_IC][48] = 127, + [0][1][2][1][RTW89_KCC][48] = 127, + [0][1][2][1][RTW89_ACMA][48] = 127, + [0][1][2][1][RTW89_CN][48] = 127, + [0][1][2][1][RTW89_UK][48] = 127, + [0][1][2][1][RTW89_FCC][50] = 127, + [0][1][2][1][RTW89_ETSI][50] = 127, + [0][1][2][1][RTW89_MKK][50] = 127, + [0][1][2][1][RTW89_IC][50] = 127, + [0][1][2][1][RTW89_KCC][50] = 127, + [0][1][2][1][RTW89_ACMA][50] = 127, + [0][1][2][1][RTW89_CN][50] = 127, + [0][1][2][1][RTW89_UK][50] = 127, + [0][1][2][1][RTW89_FCC][52] = 127, + [0][1][2][1][RTW89_ETSI][52] = 127, + [0][1][2][1][RTW89_MKK][52] = 127, + [0][1][2][1][RTW89_IC][52] = 127, + [0][1][2][1][RTW89_KCC][52] = 127, + [0][1][2][1][RTW89_ACMA][52] = 127, + [0][1][2][1][RTW89_CN][52] = 127, + [0][1][2][1][RTW89_UK][52] = 127, + [1][0][2][0][RTW89_FCC][1] = 68, + [1][0][2][0][RTW89_ETSI][1] = 64, + [1][0][2][0][RTW89_MKK][1] = 64, + [1][0][2][0][RTW89_IC][1] = 64, + [1][0][2][0][RTW89_KCC][1] = 74, + [1][0][2][0][RTW89_ACMA][1] = 64, + [1][0][2][0][RTW89_CN][1] = 62, + [1][0][2][0][RTW89_UK][1] = 64, + [1][0][2][0][RTW89_FCC][5] = 82, + [1][0][2][0][RTW89_ETSI][5] = 64, + [1][0][2][0][RTW89_MKK][5] = 62, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 66, + [1][0][2][0][RTW89_ACMA][5] = 64, + [1][0][2][0][RTW89_CN][5] = 62, + [1][0][2][0][RTW89_UK][5] = 64, + [1][0][2][0][RTW89_FCC][9] = 82, + [1][0][2][0][RTW89_ETSI][9] = 64, + [1][0][2][0][RTW89_MKK][9] = 64, + [1][0][2][0][RTW89_IC][9] = 64, + [1][0][2][0][RTW89_KCC][9] = 78, + [1][0][2][0][RTW89_ACMA][9] = 64, + [1][0][2][0][RTW89_CN][9] = 62, + [1][0][2][0][RTW89_UK][9] = 64, + [1][0][2][0][RTW89_FCC][13] = 66, + [1][0][2][0][RTW89_ETSI][13] = 64, + [1][0][2][0][RTW89_MKK][13] = 64, + [1][0][2][0][RTW89_IC][13] = 64, + [1][0][2][0][RTW89_KCC][13] = 72, + [1][0][2][0][RTW89_ACMA][13] = 64, + [1][0][2][0][RTW89_CN][13] = 62, + [1][0][2][0][RTW89_UK][13] = 64, + [1][0][2][0][RTW89_FCC][16] = 66, + [1][0][2][0][RTW89_ETSI][16] = 66, + [1][0][2][0][RTW89_MKK][16] = 80, + [1][0][2][0][RTW89_IC][16] = 66, + [1][0][2][0][RTW89_KCC][16] = 74, + [1][0][2][0][RTW89_ACMA][16] = 66, + [1][0][2][0][RTW89_CN][16] = 127, + [1][0][2][0][RTW89_UK][16] = 66, + [1][0][2][0][RTW89_FCC][20] = 80, + [1][0][2][0][RTW89_ETSI][20] = 66, + [1][0][2][0][RTW89_MKK][20] = 80, + [1][0][2][0][RTW89_IC][20] = 80, + [1][0][2][0][RTW89_KCC][20] = 74, + [1][0][2][0][RTW89_ACMA][20] = 66, + [1][0][2][0][RTW89_CN][20] = 127, + [1][0][2][0][RTW89_UK][20] = 66, + [1][0][2][0][RTW89_FCC][24] = 80, + [1][0][2][0][RTW89_ETSI][24] = 66, + [1][0][2][0][RTW89_MKK][24] = 80, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_KCC][24] = 74, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_CN][24] = 127, + [1][0][2][0][RTW89_UK][24] = 66, + [1][0][2][0][RTW89_FCC][28] = 80, + [1][0][2][0][RTW89_ETSI][28] = 66, + [1][0][2][0][RTW89_MKK][28] = 80, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_KCC][28] = 74, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_CN][28] = 127, + [1][0][2][0][RTW89_UK][28] = 66, + [1][0][2][0][RTW89_FCC][32] = 76, + [1][0][2][0][RTW89_ETSI][32] = 66, + [1][0][2][0][RTW89_MKK][32] = 80, + [1][0][2][0][RTW89_IC][32] = 76, + [1][0][2][0][RTW89_KCC][32] = 78, + [1][0][2][0][RTW89_ACMA][32] = 66, + [1][0][2][0][RTW89_CN][32] = 127, + [1][0][2][0][RTW89_UK][32] = 66, + [1][0][2][0][RTW89_FCC][36] = 80, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 80, + [1][0][2][0][RTW89_IC][36] = 80, + [1][0][2][0][RTW89_KCC][36] = 76, + [1][0][2][0][RTW89_ACMA][36] = 78, + [1][0][2][0][RTW89_CN][36] = 127, + [1][0][2][0][RTW89_UK][36] = 80, + [1][0][2][0][RTW89_FCC][39] = 84, + [1][0][2][0][RTW89_ETSI][39] = 30, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 84, + [1][0][2][0][RTW89_KCC][39] = 68, + [1][0][2][0][RTW89_ACMA][39] = 80, + [1][0][2][0][RTW89_CN][39] = 60, + [1][0][2][0][RTW89_UK][39] = 64, + [1][0][2][0][RTW89_FCC][43] = 84, + [1][0][2][0][RTW89_ETSI][43] = 30, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 84, + [1][0][2][0][RTW89_KCC][43] = 78, + [1][0][2][0][RTW89_ACMA][43] = 80, + [1][0][2][0][RTW89_CN][43] = 62, + [1][0][2][0][RTW89_UK][43] = 64, + [1][0][2][0][RTW89_FCC][47] = 84, + [1][0][2][0][RTW89_ETSI][47] = 127, + [1][0][2][0][RTW89_MKK][47] = 127, + [1][0][2][0][RTW89_IC][47] = 84, + [1][0][2][0][RTW89_KCC][47] = 127, + [1][0][2][0][RTW89_ACMA][47] = 127, + [1][0][2][0][RTW89_CN][47] = 127, + [1][0][2][0][RTW89_UK][47] = 127, + [1][0][2][0][RTW89_FCC][51] = 84, + [1][0][2][0][RTW89_ETSI][51] = 127, + [1][0][2][0][RTW89_MKK][51] = 127, + [1][0][2][0][RTW89_IC][51] = 84, + [1][0][2][0][RTW89_KCC][51] = 127, + [1][0][2][0][RTW89_ACMA][51] = 127, + [1][0][2][0][RTW89_CN][51] = 127, + [1][0][2][0][RTW89_UK][51] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][5] = 127, + [1][1][2][0][RTW89_ETSI][5] = 127, + [1][1][2][0][RTW89_MKK][5] = 127, + [1][1][2][0][RTW89_IC][5] = 127, + [1][1][2][0][RTW89_KCC][5] = 127, + [1][1][2][0][RTW89_ACMA][5] = 127, + [1][1][2][0][RTW89_CN][5] = 127, + [1][1][2][0][RTW89_UK][5] = 127, + [1][1][2][0][RTW89_FCC][9] = 127, + [1][1][2][0][RTW89_ETSI][9] = 127, + [1][1][2][0][RTW89_MKK][9] = 127, + [1][1][2][0][RTW89_IC][9] = 127, + [1][1][2][0][RTW89_KCC][9] = 127, + [1][1][2][0][RTW89_ACMA][9] = 127, + [1][1][2][0][RTW89_CN][9] = 127, + [1][1][2][0][RTW89_UK][9] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][16] = 127, + [1][1][2][0][RTW89_ETSI][16] = 127, + [1][1][2][0][RTW89_MKK][16] = 127, + [1][1][2][0][RTW89_IC][16] = 127, + [1][1][2][0][RTW89_KCC][16] = 127, + [1][1][2][0][RTW89_ACMA][16] = 127, + [1][1][2][0][RTW89_CN][16] = 127, + [1][1][2][0][RTW89_UK][16] = 127, + [1][1][2][0][RTW89_FCC][20] = 127, + [1][1][2][0][RTW89_ETSI][20] = 127, + [1][1][2][0][RTW89_MKK][20] = 127, + [1][1][2][0][RTW89_IC][20] = 127, + [1][1][2][0][RTW89_KCC][20] = 127, + [1][1][2][0][RTW89_ACMA][20] = 127, + [1][1][2][0][RTW89_CN][20] = 127, + [1][1][2][0][RTW89_UK][20] = 127, + [1][1][2][0][RTW89_FCC][24] = 127, + [1][1][2][0][RTW89_ETSI][24] = 127, + [1][1][2][0][RTW89_MKK][24] = 127, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_KCC][24] = 127, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_CN][24] = 127, + [1][1][2][0][RTW89_UK][24] = 127, + [1][1][2][0][RTW89_FCC][28] = 127, + [1][1][2][0][RTW89_ETSI][28] = 127, + [1][1][2][0][RTW89_MKK][28] = 127, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_KCC][28] = 127, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_CN][28] = 127, + [1][1][2][0][RTW89_UK][28] = 127, + [1][1][2][0][RTW89_FCC][32] = 127, + [1][1][2][0][RTW89_ETSI][32] = 127, + [1][1][2][0][RTW89_MKK][32] = 127, + [1][1][2][0][RTW89_IC][32] = 127, + [1][1][2][0][RTW89_KCC][32] = 127, + [1][1][2][0][RTW89_ACMA][32] = 127, + [1][1][2][0][RTW89_CN][32] = 127, + [1][1][2][0][RTW89_UK][32] = 127, + [1][1][2][0][RTW89_FCC][36] = 127, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 127, + [1][1][2][0][RTW89_IC][36] = 127, + [1][1][2][0][RTW89_KCC][36] = 127, + [1][1][2][0][RTW89_ACMA][36] = 127, + [1][1][2][0][RTW89_CN][36] = 127, + [1][1][2][0][RTW89_UK][36] = 127, + [1][1][2][0][RTW89_FCC][39] = 127, + [1][1][2][0][RTW89_ETSI][39] = 127, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 127, + [1][1][2][0][RTW89_KCC][39] = 127, + [1][1][2][0][RTW89_ACMA][39] = 127, + [1][1][2][0][RTW89_CN][39] = 127, + [1][1][2][0][RTW89_UK][39] = 127, + [1][1][2][0][RTW89_FCC][43] = 127, + [1][1][2][0][RTW89_ETSI][43] = 127, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 127, + [1][1][2][0][RTW89_KCC][43] = 127, + [1][1][2][0][RTW89_ACMA][43] = 127, + [1][1][2][0][RTW89_CN][43] = 127, + [1][1][2][0][RTW89_UK][43] = 127, + [1][1][2][0][RTW89_FCC][47] = 127, + [1][1][2][0][RTW89_ETSI][47] = 127, + [1][1][2][0][RTW89_MKK][47] = 127, + [1][1][2][0][RTW89_IC][47] = 127, + [1][1][2][0][RTW89_KCC][47] = 127, + [1][1][2][0][RTW89_ACMA][47] = 127, + [1][1][2][0][RTW89_CN][47] = 127, + [1][1][2][0][RTW89_UK][47] = 127, + [1][1][2][0][RTW89_FCC][51] = 127, + [1][1][2][0][RTW89_ETSI][51] = 127, + [1][1][2][0][RTW89_MKK][51] = 127, + [1][1][2][0][RTW89_IC][51] = 127, + [1][1][2][0][RTW89_KCC][51] = 127, + [1][1][2][0][RTW89_ACMA][51] = 127, + [1][1][2][0][RTW89_CN][51] = 127, + [1][1][2][0][RTW89_UK][51] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][5] = 127, + [1][1][2][1][RTW89_ETSI][5] = 127, + [1][1][2][1][RTW89_MKK][5] = 127, + [1][1][2][1][RTW89_IC][5] = 127, + [1][1][2][1][RTW89_KCC][5] = 127, + [1][1][2][1][RTW89_ACMA][5] = 127, + [1][1][2][1][RTW89_CN][5] = 127, + [1][1][2][1][RTW89_UK][5] = 127, + [1][1][2][1][RTW89_FCC][9] = 127, + [1][1][2][1][RTW89_ETSI][9] = 127, + [1][1][2][1][RTW89_MKK][9] = 127, + [1][1][2][1][RTW89_IC][9] = 127, + [1][1][2][1][RTW89_KCC][9] = 127, + [1][1][2][1][RTW89_ACMA][9] = 127, + [1][1][2][1][RTW89_CN][9] = 127, + [1][1][2][1][RTW89_UK][9] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][16] = 127, + [1][1][2][1][RTW89_ETSI][16] = 127, + [1][1][2][1][RTW89_MKK][16] = 127, + [1][1][2][1][RTW89_IC][16] = 127, + [1][1][2][1][RTW89_KCC][16] = 127, + [1][1][2][1][RTW89_ACMA][16] = 127, + [1][1][2][1][RTW89_CN][16] = 127, + [1][1][2][1][RTW89_UK][16] = 127, + [1][1][2][1][RTW89_FCC][20] = 127, + [1][1][2][1][RTW89_ETSI][20] = 127, + [1][1][2][1][RTW89_MKK][20] = 127, + [1][1][2][1][RTW89_IC][20] = 127, + [1][1][2][1][RTW89_KCC][20] = 127, + [1][1][2][1][RTW89_ACMA][20] = 127, + [1][1][2][1][RTW89_CN][20] = 127, + [1][1][2][1][RTW89_UK][20] = 127, + [1][1][2][1][RTW89_FCC][24] = 127, + [1][1][2][1][RTW89_ETSI][24] = 127, + [1][1][2][1][RTW89_MKK][24] = 127, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_KCC][24] = 127, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_CN][24] = 127, + [1][1][2][1][RTW89_UK][24] = 127, + [1][1][2][1][RTW89_FCC][28] = 127, + [1][1][2][1][RTW89_ETSI][28] = 127, + [1][1][2][1][RTW89_MKK][28] = 127, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_KCC][28] = 127, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_CN][28] = 127, + [1][1][2][1][RTW89_UK][28] = 127, + [1][1][2][1][RTW89_FCC][32] = 127, + [1][1][2][1][RTW89_ETSI][32] = 127, + [1][1][2][1][RTW89_MKK][32] = 127, + [1][1][2][1][RTW89_IC][32] = 127, + [1][1][2][1][RTW89_KCC][32] = 127, + [1][1][2][1][RTW89_ACMA][32] = 127, + [1][1][2][1][RTW89_CN][32] = 127, + [1][1][2][1][RTW89_UK][32] = 127, + [1][1][2][1][RTW89_FCC][36] = 127, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 127, + [1][1][2][1][RTW89_IC][36] = 127, + [1][1][2][1][RTW89_KCC][36] = 127, + [1][1][2][1][RTW89_ACMA][36] = 127, + [1][1][2][1][RTW89_CN][36] = 127, + [1][1][2][1][RTW89_UK][36] = 127, + [1][1][2][1][RTW89_FCC][39] = 127, + [1][1][2][1][RTW89_ETSI][39] = 127, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 127, + [1][1][2][1][RTW89_KCC][39] = 127, + [1][1][2][1][RTW89_ACMA][39] = 127, + [1][1][2][1][RTW89_CN][39] = 127, + [1][1][2][1][RTW89_UK][39] = 127, + [1][1][2][1][RTW89_FCC][43] = 127, + [1][1][2][1][RTW89_ETSI][43] = 127, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 127, + [1][1][2][1][RTW89_KCC][43] = 127, + [1][1][2][1][RTW89_ACMA][43] = 127, + [1][1][2][1][RTW89_CN][43] = 127, + [1][1][2][1][RTW89_UK][43] = 127, + [1][1][2][1][RTW89_FCC][47] = 127, + [1][1][2][1][RTW89_ETSI][47] = 127, + [1][1][2][1][RTW89_MKK][47] = 127, + [1][1][2][1][RTW89_IC][47] = 127, + [1][1][2][1][RTW89_KCC][47] = 127, + [1][1][2][1][RTW89_ACMA][47] = 127, + [1][1][2][1][RTW89_CN][47] = 127, + [1][1][2][1][RTW89_UK][47] = 127, + [1][1][2][1][RTW89_FCC][51] = 127, + [1][1][2][1][RTW89_ETSI][51] = 127, + [1][1][2][1][RTW89_MKK][51] = 127, + [1][1][2][1][RTW89_IC][51] = 127, + [1][1][2][1][RTW89_KCC][51] = 127, + [1][1][2][1][RTW89_ACMA][51] = 127, + [1][1][2][1][RTW89_CN][51] = 127, + [1][1][2][1][RTW89_UK][51] = 127, + [2][0][2][0][RTW89_FCC][3] = 76, + [2][0][2][0][RTW89_ETSI][3] = 64, + [2][0][2][0][RTW89_MKK][3] = 62, + [2][0][2][0][RTW89_IC][3] = 64, + [2][0][2][0][RTW89_KCC][3] = 72, + [2][0][2][0][RTW89_ACMA][3] = 64, + [2][0][2][0][RTW89_CN][3] = 60, + [2][0][2][0][RTW89_UK][3] = 64, + [2][0][2][0][RTW89_FCC][11] = 64, + [2][0][2][0][RTW89_ETSI][11] = 64, + [2][0][2][0][RTW89_MKK][11] = 64, + [2][0][2][0][RTW89_IC][11] = 62, + [2][0][2][0][RTW89_KCC][11] = 72, + [2][0][2][0][RTW89_ACMA][11] = 64, + [2][0][2][0][RTW89_CN][11] = 56, + [2][0][2][0][RTW89_UK][11] = 64, + [2][0][2][0][RTW89_FCC][18] = 66, + [2][0][2][0][RTW89_ETSI][18] = 64, + [2][0][2][0][RTW89_MKK][18] = 72, + [2][0][2][0][RTW89_IC][18] = 66, + [2][0][2][0][RTW89_KCC][18] = 72, + [2][0][2][0][RTW89_ACMA][18] = 64, + [2][0][2][0][RTW89_CN][18] = 127, + [2][0][2][0][RTW89_UK][18] = 64, + [2][0][2][0][RTW89_FCC][26] = 76, + [2][0][2][0][RTW89_ETSI][26] = 64, + [2][0][2][0][RTW89_MKK][26] = 72, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_KCC][26] = 72, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_CN][26] = 127, + [2][0][2][0][RTW89_UK][26] = 64, + [2][0][2][0][RTW89_FCC][34] = 76, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 72, + [2][0][2][0][RTW89_IC][34] = 76, + [2][0][2][0][RTW89_KCC][34] = 72, + [2][0][2][0][RTW89_ACMA][34] = 72, + [2][0][2][0][RTW89_CN][34] = 127, + [2][0][2][0][RTW89_UK][34] = 72, + [2][0][2][0][RTW89_FCC][41] = 76, + [2][0][2][0][RTW89_ETSI][41] = 30, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 76, + [2][0][2][0][RTW89_KCC][41] = 64, + [2][0][2][0][RTW89_ACMA][41] = 72, + [2][0][2][0][RTW89_CN][41] = 40, + [2][0][2][0][RTW89_UK][41] = 64, + [2][0][2][0][RTW89_FCC][49] = 74, + [2][0][2][0][RTW89_ETSI][49] = 127, + [2][0][2][0][RTW89_MKK][49] = 127, + [2][0][2][0][RTW89_IC][49] = 74, + [2][0][2][0][RTW89_KCC][49] = 127, + [2][0][2][0][RTW89_ACMA][49] = 127, + [2][0][2][0][RTW89_CN][49] = 127, + [2][0][2][0][RTW89_UK][49] = 127, + [2][1][2][0][RTW89_FCC][3] = 127, + [2][1][2][0][RTW89_ETSI][3] = 127, + [2][1][2][0][RTW89_MKK][3] = 127, + [2][1][2][0][RTW89_IC][3] = 127, + [2][1][2][0][RTW89_KCC][3] = 127, + [2][1][2][0][RTW89_ACMA][3] = 127, + [2][1][2][0][RTW89_CN][3] = 127, + [2][1][2][0][RTW89_UK][3] = 127, + [2][1][2][0][RTW89_FCC][11] = 127, + [2][1][2][0][RTW89_ETSI][11] = 127, + [2][1][2][0][RTW89_MKK][11] = 127, + [2][1][2][0][RTW89_IC][11] = 127, + [2][1][2][0][RTW89_KCC][11] = 127, + [2][1][2][0][RTW89_ACMA][11] = 127, + [2][1][2][0][RTW89_CN][11] = 127, + [2][1][2][0][RTW89_UK][11] = 127, + [2][1][2][0][RTW89_FCC][18] = 127, + [2][1][2][0][RTW89_ETSI][18] = 127, + [2][1][2][0][RTW89_MKK][18] = 127, + [2][1][2][0][RTW89_IC][18] = 127, + [2][1][2][0][RTW89_KCC][18] = 127, + [2][1][2][0][RTW89_ACMA][18] = 127, + [2][1][2][0][RTW89_CN][18] = 127, + [2][1][2][0][RTW89_UK][18] = 127, + [2][1][2][0][RTW89_FCC][26] = 127, + [2][1][2][0][RTW89_ETSI][26] = 127, + [2][1][2][0][RTW89_MKK][26] = 127, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_KCC][26] = 127, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_CN][26] = 127, + [2][1][2][0][RTW89_UK][26] = 127, + [2][1][2][0][RTW89_FCC][34] = 127, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 127, + [2][1][2][0][RTW89_IC][34] = 127, + [2][1][2][0][RTW89_KCC][34] = 127, + [2][1][2][0][RTW89_ACMA][34] = 127, + [2][1][2][0][RTW89_CN][34] = 127, + [2][1][2][0][RTW89_UK][34] = 127, + [2][1][2][0][RTW89_FCC][41] = 127, + [2][1][2][0][RTW89_ETSI][41] = 127, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 127, + [2][1][2][0][RTW89_KCC][41] = 127, + [2][1][2][0][RTW89_ACMA][41] = 127, + [2][1][2][0][RTW89_CN][41] = 127, + [2][1][2][0][RTW89_UK][41] = 127, + [2][1][2][0][RTW89_FCC][49] = 127, + [2][1][2][0][RTW89_ETSI][49] = 127, + [2][1][2][0][RTW89_MKK][49] = 127, + [2][1][2][0][RTW89_IC][49] = 127, + [2][1][2][0][RTW89_KCC][49] = 127, + [2][1][2][0][RTW89_ACMA][49] = 127, + [2][1][2][0][RTW89_CN][49] = 127, + [2][1][2][0][RTW89_UK][49] = 127, + [2][1][2][1][RTW89_FCC][3] = 127, + [2][1][2][1][RTW89_ETSI][3] = 127, + [2][1][2][1][RTW89_MKK][3] = 127, + [2][1][2][1][RTW89_IC][3] = 127, + [2][1][2][1][RTW89_KCC][3] = 127, + [2][1][2][1][RTW89_ACMA][3] = 127, + [2][1][2][1][RTW89_CN][3] = 127, + [2][1][2][1][RTW89_UK][3] = 127, + [2][1][2][1][RTW89_FCC][11] = 127, + [2][1][2][1][RTW89_ETSI][11] = 127, + [2][1][2][1][RTW89_MKK][11] = 127, + [2][1][2][1][RTW89_IC][11] = 127, + [2][1][2][1][RTW89_KCC][11] = 127, + [2][1][2][1][RTW89_ACMA][11] = 127, + [2][1][2][1][RTW89_CN][11] = 127, + [2][1][2][1][RTW89_UK][11] = 127, + [2][1][2][1][RTW89_FCC][18] = 127, + [2][1][2][1][RTW89_ETSI][18] = 127, + [2][1][2][1][RTW89_MKK][18] = 127, + [2][1][2][1][RTW89_IC][18] = 127, + [2][1][2][1][RTW89_KCC][18] = 127, + [2][1][2][1][RTW89_ACMA][18] = 127, + [2][1][2][1][RTW89_CN][18] = 127, + [2][1][2][1][RTW89_UK][18] = 127, + [2][1][2][1][RTW89_FCC][26] = 127, + [2][1][2][1][RTW89_ETSI][26] = 127, + [2][1][2][1][RTW89_MKK][26] = 127, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_KCC][26] = 127, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_CN][26] = 127, + [2][1][2][1][RTW89_UK][26] = 127, + [2][1][2][1][RTW89_FCC][34] = 127, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 127, + [2][1][2][1][RTW89_IC][34] = 127, + [2][1][2][1][RTW89_KCC][34] = 127, + [2][1][2][1][RTW89_ACMA][34] = 127, + [2][1][2][1][RTW89_CN][34] = 127, + [2][1][2][1][RTW89_UK][34] = 127, + [2][1][2][1][RTW89_FCC][41] = 127, + [2][1][2][1][RTW89_ETSI][41] = 127, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 127, + [2][1][2][1][RTW89_KCC][41] = 127, + [2][1][2][1][RTW89_ACMA][41] = 127, + [2][1][2][1][RTW89_CN][41] = 127, + [2][1][2][1][RTW89_UK][41] = 127, + [2][1][2][1][RTW89_FCC][49] = 127, + [2][1][2][1][RTW89_ETSI][49] = 127, + [2][1][2][1][RTW89_MKK][49] = 127, + [2][1][2][1][RTW89_IC][49] = 127, + [2][1][2][1][RTW89_KCC][49] = 127, + [2][1][2][1][RTW89_ACMA][49] = 127, + [2][1][2][1][RTW89_CN][49] = 127, + [2][1][2][1][RTW89_UK][49] = 127, + [3][0][2][0][RTW89_FCC][7] = 127, + [3][0][2][0][RTW89_ETSI][7] = 127, + [3][0][2][0][RTW89_MKK][7] = 127, + [3][0][2][0][RTW89_IC][7] = 127, + [3][0][2][0][RTW89_KCC][7] = 127, + [3][0][2][0][RTW89_ACMA][7] = 127, + [3][0][2][0][RTW89_CN][7] = 127, + [3][0][2][0][RTW89_UK][7] = 127, + [3][0][2][0][RTW89_FCC][22] = 127, + [3][0][2][0][RTW89_ETSI][22] = 127, + [3][0][2][0][RTW89_MKK][22] = 127, + [3][0][2][0][RTW89_IC][22] = 127, + [3][0][2][0][RTW89_KCC][22] = 127, + [3][0][2][0][RTW89_ACMA][22] = 127, + [3][0][2][0][RTW89_CN][22] = 127, + [3][0][2][0][RTW89_UK][22] = 127, + [3][0][2][0][RTW89_FCC][45] = 127, + [3][0][2][0][RTW89_ETSI][45] = 127, + [3][0][2][0][RTW89_MKK][45] = 127, + [3][0][2][0][RTW89_IC][45] = 127, + [3][0][2][0][RTW89_KCC][45] = 127, + [3][0][2][0][RTW89_ACMA][45] = 127, + [3][0][2][0][RTW89_CN][45] = 127, + [3][0][2][0][RTW89_UK][45] = 127, + [3][1][2][0][RTW89_FCC][7] = 127, + [3][1][2][0][RTW89_ETSI][7] = 127, + [3][1][2][0][RTW89_MKK][7] = 127, + [3][1][2][0][RTW89_IC][7] = 127, + [3][1][2][0][RTW89_KCC][7] = 127, + [3][1][2][0][RTW89_ACMA][7] = 127, + [3][1][2][0][RTW89_CN][7] = 127, + [3][1][2][0][RTW89_UK][7] = 127, + [3][1][2][0][RTW89_FCC][22] = 127, + [3][1][2][0][RTW89_ETSI][22] = 127, + [3][1][2][0][RTW89_MKK][22] = 127, + [3][1][2][0][RTW89_IC][22] = 127, + [3][1][2][0][RTW89_KCC][22] = 127, + [3][1][2][0][RTW89_ACMA][22] = 127, + [3][1][2][0][RTW89_CN][22] = 127, + [3][1][2][0][RTW89_UK][22] = 127, + [3][1][2][0][RTW89_FCC][45] = 127, + [3][1][2][0][RTW89_ETSI][45] = 127, + [3][1][2][0][RTW89_MKK][45] = 127, + [3][1][2][0][RTW89_IC][45] = 127, + [3][1][2][0][RTW89_KCC][45] = 127, + [3][1][2][0][RTW89_ACMA][45] = 127, + [3][1][2][0][RTW89_CN][45] = 127, + [3][1][2][0][RTW89_UK][45] = 127, + [3][1][2][1][RTW89_FCC][7] = 127, + [3][1][2][1][RTW89_ETSI][7] = 127, + [3][1][2][1][RTW89_MKK][7] = 127, + [3][1][2][1][RTW89_IC][7] = 127, + [3][1][2][1][RTW89_KCC][7] = 127, + [3][1][2][1][RTW89_ACMA][7] = 127, + [3][1][2][1][RTW89_CN][7] = 127, + [3][1][2][1][RTW89_UK][7] = 127, + [3][1][2][1][RTW89_FCC][22] = 127, + [3][1][2][1][RTW89_ETSI][22] = 127, + [3][1][2][1][RTW89_MKK][22] = 127, + [3][1][2][1][RTW89_IC][22] = 127, + [3][1][2][1][RTW89_KCC][22] = 127, + [3][1][2][1][RTW89_ACMA][22] = 127, + [3][1][2][1][RTW89_CN][22] = 127, + [3][1][2][1][RTW89_UK][22] = 127, + [3][1][2][1][RTW89_FCC][45] = 127, + [3][1][2][1][RTW89_ETSI][45] = 127, + [3][1][2][1][RTW89_MKK][45] = 127, + [3][1][2][1][RTW89_IC][45] = 127, + [3][1][2][1][RTW89_KCC][45] = 127, + [3][1][2][1][RTW89_ACMA][45] = 127, + [3][1][2][1][RTW89_CN][45] = 127, + [3][1][2][1][RTW89_UK][45] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 30, + [0][0][RTW89_WW][1] = 30, + [0][0][RTW89_WW][2] = 30, + [0][0][RTW89_WW][3] = 30, + [0][0][RTW89_WW][4] = 30, + [0][0][RTW89_WW][5] = 30, + [0][0][RTW89_WW][6] = 30, + [0][0][RTW89_WW][7] = 30, + [0][0][RTW89_WW][8] = 30, + [0][0][RTW89_WW][9] = 30, + [0][0][RTW89_WW][10] = 30, + [0][0][RTW89_WW][11] = 30, + [0][0][RTW89_WW][12] = 30, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 0, + [0][1][RTW89_WW][1] = 0, + [0][1][RTW89_WW][2] = 0, + [0][1][RTW89_WW][3] = 0, + [0][1][RTW89_WW][4] = 0, + [0][1][RTW89_WW][5] = 0, + [0][1][RTW89_WW][6] = 0, + [0][1][RTW89_WW][7] = 0, + [0][1][RTW89_WW][8] = 0, + [0][1][RTW89_WW][9] = 0, + [0][1][RTW89_WW][10] = 0, + [0][1][RTW89_WW][11] = 0, + [0][1][RTW89_WW][12] = 0, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 42, + [1][0][RTW89_WW][2] = 42, + [1][0][RTW89_WW][3] = 42, + [1][0][RTW89_WW][4] = 42, + [1][0][RTW89_WW][5] = 42, + [1][0][RTW89_WW][6] = 42, + [1][0][RTW89_WW][7] = 42, + [1][0][RTW89_WW][8] = 42, + [1][0][RTW89_WW][9] = 42, + [1][0][RTW89_WW][10] = 42, + [1][0][RTW89_WW][11] = 42, + [1][0][RTW89_WW][12] = 34, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 0, + [1][1][RTW89_WW][1] = 0, + [1][1][RTW89_WW][2] = 0, + [1][1][RTW89_WW][3] = 0, + [1][1][RTW89_WW][4] = 0, + [1][1][RTW89_WW][5] = 0, + [1][1][RTW89_WW][6] = 0, + [1][1][RTW89_WW][7] = 0, + [1][1][RTW89_WW][8] = 0, + [1][1][RTW89_WW][9] = 0, + [1][1][RTW89_WW][10] = 0, + [1][1][RTW89_WW][11] = 0, + [1][1][RTW89_WW][12] = 0, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 54, + [2][0][RTW89_WW][1] = 54, + [2][0][RTW89_WW][2] = 54, + [2][0][RTW89_WW][3] = 54, + [2][0][RTW89_WW][4] = 54, + [2][0][RTW89_WW][5] = 54, + [2][0][RTW89_WW][6] = 54, + [2][0][RTW89_WW][7] = 54, + [2][0][RTW89_WW][8] = 54, + [2][0][RTW89_WW][9] = 54, + [2][0][RTW89_WW][10] = 54, + [2][0][RTW89_WW][11] = 54, + [2][0][RTW89_WW][12] = 34, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 0, + [2][1][RTW89_WW][1] = 0, + [2][1][RTW89_WW][2] = 0, + [2][1][RTW89_WW][3] = 0, + [2][1][RTW89_WW][4] = 0, + [2][1][RTW89_WW][5] = 0, + [2][1][RTW89_WW][6] = 0, + [2][1][RTW89_WW][7] = 0, + [2][1][RTW89_WW][8] = 0, + [2][1][RTW89_WW][9] = 0, + [2][1][RTW89_WW][10] = 0, + [2][1][RTW89_WW][11] = 0, + [2][1][RTW89_WW][12] = 0, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 62, + [0][0][RTW89_ETSI][0] = 30, + [0][0][RTW89_MKK][0] = 40, + [0][0][RTW89_IC][0] = 62, + [0][0][RTW89_KCC][0] = 46, + [0][0][RTW89_ACMA][0] = 30, + [0][0][RTW89_CN][0] = 32, + [0][0][RTW89_UK][0] = 30, + [0][0][RTW89_FCC][1] = 62, + [0][0][RTW89_ETSI][1] = 30, + [0][0][RTW89_MKK][1] = 44, + [0][0][RTW89_IC][1] = 62, + [0][0][RTW89_KCC][1] = 46, + [0][0][RTW89_ACMA][1] = 30, + [0][0][RTW89_CN][1] = 32, + [0][0][RTW89_UK][1] = 30, + [0][0][RTW89_FCC][2] = 66, + [0][0][RTW89_ETSI][2] = 30, + [0][0][RTW89_MKK][2] = 44, + [0][0][RTW89_IC][2] = 66, + [0][0][RTW89_KCC][2] = 46, + [0][0][RTW89_ACMA][2] = 30, + [0][0][RTW89_CN][2] = 32, + [0][0][RTW89_UK][2] = 30, + [0][0][RTW89_FCC][3] = 70, + [0][0][RTW89_ETSI][3] = 30, + [0][0][RTW89_MKK][3] = 44, + [0][0][RTW89_IC][3] = 70, + [0][0][RTW89_KCC][3] = 46, + [0][0][RTW89_ACMA][3] = 30, + [0][0][RTW89_CN][3] = 32, + [0][0][RTW89_UK][3] = 30, + [0][0][RTW89_FCC][4] = 70, + [0][0][RTW89_ETSI][4] = 30, + [0][0][RTW89_MKK][4] = 44, + [0][0][RTW89_IC][4] = 70, + [0][0][RTW89_KCC][4] = 48, + [0][0][RTW89_ACMA][4] = 30, + [0][0][RTW89_CN][4] = 32, + [0][0][RTW89_UK][4] = 30, + [0][0][RTW89_FCC][5] = 84, + [0][0][RTW89_ETSI][5] = 30, + [0][0][RTW89_MKK][5] = 44, + [0][0][RTW89_IC][5] = 84, + [0][0][RTW89_KCC][5] = 48, + [0][0][RTW89_ACMA][5] = 30, + [0][0][RTW89_CN][5] = 32, + [0][0][RTW89_UK][5] = 30, + [0][0][RTW89_FCC][6] = 66, + [0][0][RTW89_ETSI][6] = 30, + [0][0][RTW89_MKK][6] = 44, + [0][0][RTW89_IC][6] = 66, + [0][0][RTW89_KCC][6] = 48, + [0][0][RTW89_ACMA][6] = 30, + [0][0][RTW89_CN][6] = 32, + [0][0][RTW89_UK][6] = 30, + [0][0][RTW89_FCC][7] = 66, + [0][0][RTW89_ETSI][7] = 30, + [0][0][RTW89_MKK][7] = 44, + [0][0][RTW89_IC][7] = 66, + [0][0][RTW89_KCC][7] = 48, + [0][0][RTW89_ACMA][7] = 30, + [0][0][RTW89_CN][7] = 32, + [0][0][RTW89_UK][7] = 30, + [0][0][RTW89_FCC][8] = 62, + [0][0][RTW89_ETSI][8] = 30, + [0][0][RTW89_MKK][8] = 44, + [0][0][RTW89_IC][8] = 62, + [0][0][RTW89_KCC][8] = 48, + [0][0][RTW89_ACMA][8] = 30, + [0][0][RTW89_CN][8] = 32, + [0][0][RTW89_UK][8] = 30, + [0][0][RTW89_FCC][9] = 58, + [0][0][RTW89_ETSI][9] = 30, + [0][0][RTW89_MKK][9] = 44, + [0][0][RTW89_IC][9] = 58, + [0][0][RTW89_KCC][9] = 44, + [0][0][RTW89_ACMA][9] = 30, + [0][0][RTW89_CN][9] = 32, + [0][0][RTW89_UK][9] = 30, + [0][0][RTW89_FCC][10] = 58, + [0][0][RTW89_ETSI][10] = 30, + [0][0][RTW89_MKK][10] = 44, + [0][0][RTW89_IC][10] = 58, + [0][0][RTW89_KCC][10] = 44, + [0][0][RTW89_ACMA][10] = 30, + [0][0][RTW89_CN][10] = 32, + [0][0][RTW89_UK][10] = 30, + [0][0][RTW89_FCC][11] = 54, + [0][0][RTW89_ETSI][11] = 30, + [0][0][RTW89_MKK][11] = 44, + [0][0][RTW89_IC][11] = 54, + [0][0][RTW89_KCC][11] = 44, + [0][0][RTW89_ACMA][11] = 30, + [0][0][RTW89_CN][11] = 32, + [0][0][RTW89_UK][11] = 30, + [0][0][RTW89_FCC][12] = 36, + [0][0][RTW89_ETSI][12] = 30, + [0][0][RTW89_MKK][12] = 40, + [0][0][RTW89_IC][12] = 36, + [0][0][RTW89_KCC][12] = 44, + [0][0][RTW89_ACMA][12] = 30, + [0][0][RTW89_CN][12] = 32, + [0][0][RTW89_UK][12] = 30, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_KCC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][0][RTW89_CN][13] = 127, + [0][0][RTW89_UK][13] = 127, + [0][1][RTW89_FCC][0] = 127, + [0][1][RTW89_ETSI][0] = 127, + [0][1][RTW89_MKK][0] = 127, + [0][1][RTW89_IC][0] = 127, + [0][1][RTW89_KCC][0] = 127, + [0][1][RTW89_ACMA][0] = 127, + [0][1][RTW89_CN][0] = 127, + [0][1][RTW89_UK][0] = 127, + [0][1][RTW89_FCC][1] = 127, + [0][1][RTW89_ETSI][1] = 127, + [0][1][RTW89_MKK][1] = 127, + [0][1][RTW89_IC][1] = 127, + [0][1][RTW89_KCC][1] = 127, + [0][1][RTW89_ACMA][1] = 127, + [0][1][RTW89_CN][1] = 127, + [0][1][RTW89_UK][1] = 127, + [0][1][RTW89_FCC][2] = 127, + [0][1][RTW89_ETSI][2] = 127, + [0][1][RTW89_MKK][2] = 127, + [0][1][RTW89_IC][2] = 127, + [0][1][RTW89_KCC][2] = 127, + [0][1][RTW89_ACMA][2] = 127, + [0][1][RTW89_CN][2] = 127, + [0][1][RTW89_UK][2] = 127, + [0][1][RTW89_FCC][3] = 127, + [0][1][RTW89_ETSI][3] = 127, + [0][1][RTW89_MKK][3] = 127, + [0][1][RTW89_IC][3] = 127, + [0][1][RTW89_KCC][3] = 127, + [0][1][RTW89_ACMA][3] = 127, + [0][1][RTW89_CN][3] = 127, + [0][1][RTW89_UK][3] = 127, + [0][1][RTW89_FCC][4] = 127, + [0][1][RTW89_ETSI][4] = 127, + [0][1][RTW89_MKK][4] = 127, + [0][1][RTW89_IC][4] = 127, + [0][1][RTW89_KCC][4] = 127, + [0][1][RTW89_ACMA][4] = 127, + [0][1][RTW89_CN][4] = 127, + [0][1][RTW89_UK][4] = 127, + [0][1][RTW89_FCC][5] = 127, + [0][1][RTW89_ETSI][5] = 127, + [0][1][RTW89_MKK][5] = 127, + [0][1][RTW89_IC][5] = 127, + [0][1][RTW89_KCC][5] = 127, + [0][1][RTW89_ACMA][5] = 127, + [0][1][RTW89_CN][5] = 127, + [0][1][RTW89_UK][5] = 127, + [0][1][RTW89_FCC][6] = 127, + [0][1][RTW89_ETSI][6] = 127, + [0][1][RTW89_MKK][6] = 127, + [0][1][RTW89_IC][6] = 127, + [0][1][RTW89_KCC][6] = 127, + [0][1][RTW89_ACMA][6] = 127, + [0][1][RTW89_CN][6] = 127, + [0][1][RTW89_UK][6] = 127, + [0][1][RTW89_FCC][7] = 127, + [0][1][RTW89_ETSI][7] = 127, + [0][1][RTW89_MKK][7] = 127, + [0][1][RTW89_IC][7] = 127, + [0][1][RTW89_KCC][7] = 127, + [0][1][RTW89_ACMA][7] = 127, + [0][1][RTW89_CN][7] = 127, + [0][1][RTW89_UK][7] = 127, + [0][1][RTW89_FCC][8] = 127, + [0][1][RTW89_ETSI][8] = 127, + [0][1][RTW89_MKK][8] = 127, + [0][1][RTW89_IC][8] = 127, + [0][1][RTW89_KCC][8] = 127, + [0][1][RTW89_ACMA][8] = 127, + [0][1][RTW89_CN][8] = 127, + [0][1][RTW89_UK][8] = 127, + [0][1][RTW89_FCC][9] = 127, + [0][1][RTW89_ETSI][9] = 127, + [0][1][RTW89_MKK][9] = 127, + [0][1][RTW89_IC][9] = 127, + [0][1][RTW89_KCC][9] = 127, + [0][1][RTW89_ACMA][9] = 127, + [0][1][RTW89_CN][9] = 127, + [0][1][RTW89_UK][9] = 127, + [0][1][RTW89_FCC][10] = 127, + [0][1][RTW89_ETSI][10] = 127, + [0][1][RTW89_MKK][10] = 127, + [0][1][RTW89_IC][10] = 127, + [0][1][RTW89_KCC][10] = 127, + [0][1][RTW89_ACMA][10] = 127, + [0][1][RTW89_CN][10] = 127, + [0][1][RTW89_UK][10] = 127, + [0][1][RTW89_FCC][11] = 127, + [0][1][RTW89_ETSI][11] = 127, + [0][1][RTW89_MKK][11] = 127, + [0][1][RTW89_IC][11] = 127, + [0][1][RTW89_KCC][11] = 127, + [0][1][RTW89_ACMA][11] = 127, + [0][1][RTW89_CN][11] = 127, + [0][1][RTW89_UK][11] = 127, + [0][1][RTW89_FCC][12] = 127, + [0][1][RTW89_ETSI][12] = 127, + [0][1][RTW89_MKK][12] = 127, + [0][1][RTW89_IC][12] = 127, + [0][1][RTW89_KCC][12] = 127, + [0][1][RTW89_ACMA][12] = 127, + [0][1][RTW89_CN][12] = 127, + [0][1][RTW89_UK][12] = 127, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_KCC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [0][1][RTW89_CN][13] = 127, + [0][1][RTW89_UK][13] = 127, + [1][0][RTW89_FCC][0] = 70, + [1][0][RTW89_ETSI][0] = 42, + [1][0][RTW89_MKK][0] = 52, + [1][0][RTW89_IC][0] = 70, + [1][0][RTW89_KCC][0] = 56, + [1][0][RTW89_ACMA][0] = 42, + [1][0][RTW89_CN][0] = 42, + [1][0][RTW89_UK][0] = 42, + [1][0][RTW89_FCC][1] = 70, + [1][0][RTW89_ETSI][1] = 42, + [1][0][RTW89_MKK][1] = 52, + [1][0][RTW89_IC][1] = 70, + [1][0][RTW89_KCC][1] = 56, + [1][0][RTW89_ACMA][1] = 42, + [1][0][RTW89_CN][1] = 44, + [1][0][RTW89_UK][1] = 42, + [1][0][RTW89_FCC][2] = 74, + [1][0][RTW89_ETSI][2] = 42, + [1][0][RTW89_MKK][2] = 52, + [1][0][RTW89_IC][2] = 74, + [1][0][RTW89_KCC][2] = 56, + [1][0][RTW89_ACMA][2] = 42, + [1][0][RTW89_CN][2] = 44, + [1][0][RTW89_UK][2] = 42, + [1][0][RTW89_FCC][3] = 76, + [1][0][RTW89_ETSI][3] = 42, + [1][0][RTW89_MKK][3] = 52, + [1][0][RTW89_IC][3] = 76, + [1][0][RTW89_KCC][3] = 56, + [1][0][RTW89_ACMA][3] = 42, + [1][0][RTW89_CN][3] = 44, + [1][0][RTW89_UK][3] = 42, + [1][0][RTW89_FCC][4] = 76, + [1][0][RTW89_ETSI][4] = 42, + [1][0][RTW89_MKK][4] = 52, + [1][0][RTW89_IC][4] = 76, + [1][0][RTW89_KCC][4] = 56, + [1][0][RTW89_ACMA][4] = 42, + [1][0][RTW89_CN][4] = 44, + [1][0][RTW89_UK][4] = 42, + [1][0][RTW89_FCC][5] = 82, + [1][0][RTW89_ETSI][5] = 42, + [1][0][RTW89_MKK][5] = 52, + [1][0][RTW89_IC][5] = 82, + [1][0][RTW89_KCC][5] = 56, + [1][0][RTW89_ACMA][5] = 42, + [1][0][RTW89_CN][5] = 44, + [1][0][RTW89_UK][5] = 42, + [1][0][RTW89_FCC][6] = 74, + [1][0][RTW89_ETSI][6] = 42, + [1][0][RTW89_MKK][6] = 52, + [1][0][RTW89_IC][6] = 74, + [1][0][RTW89_KCC][6] = 56, + [1][0][RTW89_ACMA][6] = 42, + [1][0][RTW89_CN][6] = 44, + [1][0][RTW89_UK][6] = 42, + [1][0][RTW89_FCC][7] = 74, + [1][0][RTW89_ETSI][7] = 42, + [1][0][RTW89_MKK][7] = 52, + [1][0][RTW89_IC][7] = 74, + [1][0][RTW89_KCC][7] = 56, + [1][0][RTW89_ACMA][7] = 42, + [1][0][RTW89_CN][7] = 44, + [1][0][RTW89_UK][7] = 42, + [1][0][RTW89_FCC][8] = 74, + [1][0][RTW89_ETSI][8] = 42, + [1][0][RTW89_MKK][8] = 52, + [1][0][RTW89_IC][8] = 74, + [1][0][RTW89_KCC][8] = 56, + [1][0][RTW89_ACMA][8] = 42, + [1][0][RTW89_CN][8] = 44, + [1][0][RTW89_UK][8] = 42, + [1][0][RTW89_FCC][9] = 70, + [1][0][RTW89_ETSI][9] = 42, + [1][0][RTW89_MKK][9] = 52, + [1][0][RTW89_IC][9] = 70, + [1][0][RTW89_KCC][9] = 58, + [1][0][RTW89_ACMA][9] = 42, + [1][0][RTW89_CN][9] = 44, + [1][0][RTW89_UK][9] = 42, + [1][0][RTW89_FCC][10] = 70, + [1][0][RTW89_ETSI][10] = 42, + [1][0][RTW89_MKK][10] = 52, + [1][0][RTW89_IC][10] = 70, + [1][0][RTW89_KCC][10] = 58, + [1][0][RTW89_ACMA][10] = 42, + [1][0][RTW89_CN][10] = 44, + [1][0][RTW89_UK][10] = 42, + [1][0][RTW89_FCC][11] = 66, + [1][0][RTW89_ETSI][11] = 42, + [1][0][RTW89_MKK][11] = 52, + [1][0][RTW89_IC][11] = 66, + [1][0][RTW89_KCC][11] = 58, + [1][0][RTW89_ACMA][11] = 42, + [1][0][RTW89_CN][11] = 44, + [1][0][RTW89_UK][11] = 42, + [1][0][RTW89_FCC][12] = 34, + [1][0][RTW89_ETSI][12] = 42, + [1][0][RTW89_MKK][12] = 52, + [1][0][RTW89_IC][12] = 34, + [1][0][RTW89_KCC][12] = 58, + [1][0][RTW89_ACMA][12] = 42, + [1][0][RTW89_CN][12] = 42, + [1][0][RTW89_UK][12] = 42, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_KCC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][0][RTW89_CN][13] = 127, + [1][0][RTW89_UK][13] = 127, + [1][1][RTW89_FCC][0] = 127, + [1][1][RTW89_ETSI][0] = 127, + [1][1][RTW89_MKK][0] = 127, + [1][1][RTW89_IC][0] = 127, + [1][1][RTW89_KCC][0] = 127, + [1][1][RTW89_ACMA][0] = 127, + [1][1][RTW89_CN][0] = 127, + [1][1][RTW89_UK][0] = 127, + [1][1][RTW89_FCC][1] = 127, + [1][1][RTW89_ETSI][1] = 127, + [1][1][RTW89_MKK][1] = 127, + [1][1][RTW89_IC][1] = 127, + [1][1][RTW89_KCC][1] = 127, + [1][1][RTW89_ACMA][1] = 127, + [1][1][RTW89_CN][1] = 127, + [1][1][RTW89_UK][1] = 127, + [1][1][RTW89_FCC][2] = 127, + [1][1][RTW89_ETSI][2] = 127, + [1][1][RTW89_MKK][2] = 127, + [1][1][RTW89_IC][2] = 127, + [1][1][RTW89_KCC][2] = 127, + [1][1][RTW89_ACMA][2] = 127, + [1][1][RTW89_CN][2] = 127, + [1][1][RTW89_UK][2] = 127, + [1][1][RTW89_FCC][3] = 127, + [1][1][RTW89_ETSI][3] = 127, + [1][1][RTW89_MKK][3] = 127, + [1][1][RTW89_IC][3] = 127, + [1][1][RTW89_KCC][3] = 127, + [1][1][RTW89_ACMA][3] = 127, + [1][1][RTW89_CN][3] = 127, + [1][1][RTW89_UK][3] = 127, + [1][1][RTW89_FCC][4] = 127, + [1][1][RTW89_ETSI][4] = 127, + [1][1][RTW89_MKK][4] = 127, + [1][1][RTW89_IC][4] = 127, + [1][1][RTW89_KCC][4] = 127, + [1][1][RTW89_ACMA][4] = 127, + [1][1][RTW89_CN][4] = 127, + [1][1][RTW89_UK][4] = 127, + [1][1][RTW89_FCC][5] = 127, + [1][1][RTW89_ETSI][5] = 127, + [1][1][RTW89_MKK][5] = 127, + [1][1][RTW89_IC][5] = 127, + [1][1][RTW89_KCC][5] = 127, + [1][1][RTW89_ACMA][5] = 127, + [1][1][RTW89_CN][5] = 127, + [1][1][RTW89_UK][5] = 127, + [1][1][RTW89_FCC][6] = 127, + [1][1][RTW89_ETSI][6] = 127, + [1][1][RTW89_MKK][6] = 127, + [1][1][RTW89_IC][6] = 127, + [1][1][RTW89_KCC][6] = 127, + [1][1][RTW89_ACMA][6] = 127, + [1][1][RTW89_CN][6] = 127, + [1][1][RTW89_UK][6] = 127, + [1][1][RTW89_FCC][7] = 127, + [1][1][RTW89_ETSI][7] = 127, + [1][1][RTW89_MKK][7] = 127, + [1][1][RTW89_IC][7] = 127, + [1][1][RTW89_KCC][7] = 127, + [1][1][RTW89_ACMA][7] = 127, + [1][1][RTW89_CN][7] = 127, + [1][1][RTW89_UK][7] = 127, + [1][1][RTW89_FCC][8] = 127, + [1][1][RTW89_ETSI][8] = 127, + [1][1][RTW89_MKK][8] = 127, + [1][1][RTW89_IC][8] = 127, + [1][1][RTW89_KCC][8] = 127, + [1][1][RTW89_ACMA][8] = 127, + [1][1][RTW89_CN][8] = 127, + [1][1][RTW89_UK][8] = 127, + [1][1][RTW89_FCC][9] = 127, + [1][1][RTW89_ETSI][9] = 127, + [1][1][RTW89_MKK][9] = 127, + [1][1][RTW89_IC][9] = 127, + [1][1][RTW89_KCC][9] = 127, + [1][1][RTW89_ACMA][9] = 127, + [1][1][RTW89_CN][9] = 127, + [1][1][RTW89_UK][9] = 127, + [1][1][RTW89_FCC][10] = 127, + [1][1][RTW89_ETSI][10] = 127, + [1][1][RTW89_MKK][10] = 127, + [1][1][RTW89_IC][10] = 127, + [1][1][RTW89_KCC][10] = 127, + [1][1][RTW89_ACMA][10] = 127, + [1][1][RTW89_CN][10] = 127, + [1][1][RTW89_UK][10] = 127, + [1][1][RTW89_FCC][11] = 127, + [1][1][RTW89_ETSI][11] = 127, + [1][1][RTW89_MKK][11] = 127, + [1][1][RTW89_IC][11] = 127, + [1][1][RTW89_KCC][11] = 127, + [1][1][RTW89_ACMA][11] = 127, + [1][1][RTW89_CN][11] = 127, + [1][1][RTW89_UK][11] = 127, + [1][1][RTW89_FCC][12] = 127, + [1][1][RTW89_ETSI][12] = 127, + [1][1][RTW89_MKK][12] = 127, + [1][1][RTW89_IC][12] = 127, + [1][1][RTW89_KCC][12] = 127, + [1][1][RTW89_ACMA][12] = 127, + [1][1][RTW89_CN][12] = 127, + [1][1][RTW89_UK][12] = 127, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_KCC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [1][1][RTW89_CN][13] = 127, + [1][1][RTW89_UK][13] = 127, + [2][0][RTW89_FCC][0] = 76, + [2][0][RTW89_ETSI][0] = 54, + [2][0][RTW89_MKK][0] = 64, + [2][0][RTW89_IC][0] = 76, + [2][0][RTW89_KCC][0] = 68, + [2][0][RTW89_ACMA][0] = 54, + [2][0][RTW89_CN][0] = 56, + [2][0][RTW89_UK][0] = 54, + [2][0][RTW89_FCC][1] = 76, + [2][0][RTW89_ETSI][1] = 54, + [2][0][RTW89_MKK][1] = 64, + [2][0][RTW89_IC][1] = 76, + [2][0][RTW89_KCC][1] = 68, + [2][0][RTW89_ACMA][1] = 54, + [2][0][RTW89_CN][1] = 56, + [2][0][RTW89_UK][1] = 54, + [2][0][RTW89_FCC][2] = 78, + [2][0][RTW89_ETSI][2] = 54, + [2][0][RTW89_MKK][2] = 64, + [2][0][RTW89_IC][2] = 78, + [2][0][RTW89_KCC][2] = 68, + [2][0][RTW89_ACMA][2] = 54, + [2][0][RTW89_CN][2] = 56, + [2][0][RTW89_UK][2] = 54, + [2][0][RTW89_FCC][3] = 78, + [2][0][RTW89_ETSI][3] = 54, + [2][0][RTW89_MKK][3] = 64, + [2][0][RTW89_IC][3] = 78, + [2][0][RTW89_KCC][3] = 68, + [2][0][RTW89_ACMA][3] = 54, + [2][0][RTW89_CN][3] = 56, + [2][0][RTW89_UK][3] = 54, + [2][0][RTW89_FCC][4] = 78, + [2][0][RTW89_ETSI][4] = 54, + [2][0][RTW89_MKK][4] = 64, + [2][0][RTW89_IC][4] = 78, + [2][0][RTW89_KCC][4] = 68, + [2][0][RTW89_ACMA][4] = 54, + [2][0][RTW89_CN][4] = 56, + [2][0][RTW89_UK][4] = 54, + [2][0][RTW89_FCC][5] = 82, + [2][0][RTW89_ETSI][5] = 54, + [2][0][RTW89_MKK][5] = 64, + [2][0][RTW89_IC][5] = 82, + [2][0][RTW89_KCC][5] = 68, + [2][0][RTW89_ACMA][5] = 54, + [2][0][RTW89_CN][5] = 56, + [2][0][RTW89_UK][5] = 54, + [2][0][RTW89_FCC][6] = 74, + [2][0][RTW89_ETSI][6] = 54, + [2][0][RTW89_MKK][6] = 64, + [2][0][RTW89_IC][6] = 74, + [2][0][RTW89_KCC][6] = 68, + [2][0][RTW89_ACMA][6] = 54, + [2][0][RTW89_CN][6] = 56, + [2][0][RTW89_UK][6] = 54, + [2][0][RTW89_FCC][7] = 74, + [2][0][RTW89_ETSI][7] = 54, + [2][0][RTW89_MKK][7] = 64, + [2][0][RTW89_IC][7] = 74, + [2][0][RTW89_KCC][7] = 68, + [2][0][RTW89_ACMA][7] = 54, + [2][0][RTW89_CN][7] = 56, + [2][0][RTW89_UK][7] = 54, + [2][0][RTW89_FCC][8] = 74, + [2][0][RTW89_ETSI][8] = 54, + [2][0][RTW89_MKK][8] = 64, + [2][0][RTW89_IC][8] = 74, + [2][0][RTW89_KCC][8] = 68, + [2][0][RTW89_ACMA][8] = 54, + [2][0][RTW89_CN][8] = 56, + [2][0][RTW89_UK][8] = 54, + [2][0][RTW89_FCC][9] = 72, + [2][0][RTW89_ETSI][9] = 54, + [2][0][RTW89_MKK][9] = 64, + [2][0][RTW89_IC][9] = 72, + [2][0][RTW89_KCC][9] = 68, + [2][0][RTW89_ACMA][9] = 54, + [2][0][RTW89_CN][9] = 56, + [2][0][RTW89_UK][9] = 54, + [2][0][RTW89_FCC][10] = 72, + [2][0][RTW89_ETSI][10] = 54, + [2][0][RTW89_MKK][10] = 64, + [2][0][RTW89_IC][10] = 72, + [2][0][RTW89_KCC][10] = 68, + [2][0][RTW89_ACMA][10] = 54, + [2][0][RTW89_CN][10] = 56, + [2][0][RTW89_UK][10] = 54, + [2][0][RTW89_FCC][11] = 64, + [2][0][RTW89_ETSI][11] = 54, + [2][0][RTW89_MKK][11] = 64, + [2][0][RTW89_IC][11] = 64, + [2][0][RTW89_KCC][11] = 68, + [2][0][RTW89_ACMA][11] = 54, + [2][0][RTW89_CN][11] = 56, + [2][0][RTW89_UK][11] = 54, + [2][0][RTW89_FCC][12] = 34, + [2][0][RTW89_ETSI][12] = 54, + [2][0][RTW89_MKK][12] = 64, + [2][0][RTW89_IC][12] = 34, + [2][0][RTW89_KCC][12] = 68, + [2][0][RTW89_ACMA][12] = 54, + [2][0][RTW89_CN][12] = 56, + [2][0][RTW89_UK][12] = 54, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_KCC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][0][RTW89_CN][13] = 127, + [2][0][RTW89_UK][13] = 127, + [2][1][RTW89_FCC][0] = 127, + [2][1][RTW89_ETSI][0] = 127, + [2][1][RTW89_MKK][0] = 127, + [2][1][RTW89_IC][0] = 127, + [2][1][RTW89_KCC][0] = 127, + [2][1][RTW89_ACMA][0] = 127, + [2][1][RTW89_CN][0] = 127, + [2][1][RTW89_UK][0] = 127, + [2][1][RTW89_FCC][1] = 127, + [2][1][RTW89_ETSI][1] = 127, + [2][1][RTW89_MKK][1] = 127, + [2][1][RTW89_IC][1] = 127, + [2][1][RTW89_KCC][1] = 127, + [2][1][RTW89_ACMA][1] = 127, + [2][1][RTW89_CN][1] = 127, + [2][1][RTW89_UK][1] = 127, + [2][1][RTW89_FCC][2] = 127, + [2][1][RTW89_ETSI][2] = 127, + [2][1][RTW89_MKK][2] = 127, + [2][1][RTW89_IC][2] = 127, + [2][1][RTW89_KCC][2] = 127, + [2][1][RTW89_ACMA][2] = 127, + [2][1][RTW89_CN][2] = 127, + [2][1][RTW89_UK][2] = 127, + [2][1][RTW89_FCC][3] = 127, + [2][1][RTW89_ETSI][3] = 127, + [2][1][RTW89_MKK][3] = 127, + [2][1][RTW89_IC][3] = 127, + [2][1][RTW89_KCC][3] = 127, + [2][1][RTW89_ACMA][3] = 127, + [2][1][RTW89_CN][3] = 127, + [2][1][RTW89_UK][3] = 127, + [2][1][RTW89_FCC][4] = 127, + [2][1][RTW89_ETSI][4] = 127, + [2][1][RTW89_MKK][4] = 127, + [2][1][RTW89_IC][4] = 127, + [2][1][RTW89_KCC][4] = 127, + [2][1][RTW89_ACMA][4] = 127, + [2][1][RTW89_CN][4] = 127, + [2][1][RTW89_UK][4] = 127, + [2][1][RTW89_FCC][5] = 127, + [2][1][RTW89_ETSI][5] = 127, + [2][1][RTW89_MKK][5] = 127, + [2][1][RTW89_IC][5] = 127, + [2][1][RTW89_KCC][5] = 127, + [2][1][RTW89_ACMA][5] = 127, + [2][1][RTW89_CN][5] = 127, + [2][1][RTW89_UK][5] = 127, + [2][1][RTW89_FCC][6] = 127, + [2][1][RTW89_ETSI][6] = 127, + [2][1][RTW89_MKK][6] = 127, + [2][1][RTW89_IC][6] = 127, + [2][1][RTW89_KCC][6] = 127, + [2][1][RTW89_ACMA][6] = 127, + [2][1][RTW89_CN][6] = 127, + [2][1][RTW89_UK][6] = 127, + [2][1][RTW89_FCC][7] = 127, + [2][1][RTW89_ETSI][7] = 127, + [2][1][RTW89_MKK][7] = 127, + [2][1][RTW89_IC][7] = 127, + [2][1][RTW89_KCC][7] = 127, + [2][1][RTW89_ACMA][7] = 127, + [2][1][RTW89_CN][7] = 127, + [2][1][RTW89_UK][7] = 127, + [2][1][RTW89_FCC][8] = 127, + [2][1][RTW89_ETSI][8] = 127, + [2][1][RTW89_MKK][8] = 127, + [2][1][RTW89_IC][8] = 127, + [2][1][RTW89_KCC][8] = 127, + [2][1][RTW89_ACMA][8] = 127, + [2][1][RTW89_CN][8] = 127, + [2][1][RTW89_UK][8] = 127, + [2][1][RTW89_FCC][9] = 127, + [2][1][RTW89_ETSI][9] = 127, + [2][1][RTW89_MKK][9] = 127, + [2][1][RTW89_IC][9] = 127, + [2][1][RTW89_KCC][9] = 127, + [2][1][RTW89_ACMA][9] = 127, + [2][1][RTW89_CN][9] = 127, + [2][1][RTW89_UK][9] = 127, + [2][1][RTW89_FCC][10] = 127, + [2][1][RTW89_ETSI][10] = 127, + [2][1][RTW89_MKK][10] = 127, + [2][1][RTW89_IC][10] = 127, + [2][1][RTW89_KCC][10] = 127, + [2][1][RTW89_ACMA][10] = 127, + [2][1][RTW89_CN][10] = 127, + [2][1][RTW89_UK][10] = 127, + [2][1][RTW89_FCC][11] = 127, + [2][1][RTW89_ETSI][11] = 127, + [2][1][RTW89_MKK][11] = 127, + [2][1][RTW89_IC][11] = 127, + [2][1][RTW89_KCC][11] = 127, + [2][1][RTW89_ACMA][11] = 127, + [2][1][RTW89_CN][11] = 127, + [2][1][RTW89_UK][11] = 127, + [2][1][RTW89_FCC][12] = 127, + [2][1][RTW89_ETSI][12] = 127, + [2][1][RTW89_MKK][12] = 127, + [2][1][RTW89_IC][12] = 127, + [2][1][RTW89_KCC][12] = 127, + [2][1][RTW89_ACMA][12] = 127, + [2][1][RTW89_CN][12] = 127, + [2][1][RTW89_UK][12] = 127, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_KCC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, + [2][1][RTW89_CN][13] = 127, + [2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 16, + [0][0][RTW89_WW][2] = 16, + [0][0][RTW89_WW][4] = 16, + [0][0][RTW89_WW][6] = 16, + [0][0][RTW89_WW][8] = 16, + [0][0][RTW89_WW][10] = 16, + [0][0][RTW89_WW][12] = 16, + [0][0][RTW89_WW][14] = 16, + [0][0][RTW89_WW][15] = 24, + [0][0][RTW89_WW][17] = 24, + [0][0][RTW89_WW][19] = 24, + [0][0][RTW89_WW][21] = 24, + [0][0][RTW89_WW][23] = 24, + [0][0][RTW89_WW][25] = 24, + [0][0][RTW89_WW][27] = 24, + [0][0][RTW89_WW][29] = 24, + [0][0][RTW89_WW][31] = 24, + [0][0][RTW89_WW][33] = 24, + [0][0][RTW89_WW][35] = 24, + [0][0][RTW89_WW][37] = 44, + [0][0][RTW89_WW][38] = 24, + [0][0][RTW89_WW][40] = 24, + [0][0][RTW89_WW][42] = 24, + [0][0][RTW89_WW][44] = 24, + [0][0][RTW89_WW][46] = 24, + [0][0][RTW89_WW][48] = 42, + [0][0][RTW89_WW][50] = 42, + [0][0][RTW89_WW][52] = 40, + [0][1][RTW89_WW][0] = 0, + [0][1][RTW89_WW][2] = 0, + [0][1][RTW89_WW][4] = 0, + [0][1][RTW89_WW][6] = 0, + [0][1][RTW89_WW][8] = 0, + [0][1][RTW89_WW][10] = 0, + [0][1][RTW89_WW][12] = 0, + [0][1][RTW89_WW][14] = 0, + [0][1][RTW89_WW][15] = 0, + [0][1][RTW89_WW][17] = 0, + [0][1][RTW89_WW][19] = 0, + [0][1][RTW89_WW][21] = 0, + [0][1][RTW89_WW][23] = 0, + [0][1][RTW89_WW][25] = 0, + [0][1][RTW89_WW][27] = 0, + [0][1][RTW89_WW][29] = 0, + [0][1][RTW89_WW][31] = 0, + [0][1][RTW89_WW][33] = 0, + [0][1][RTW89_WW][35] = 0, + [0][1][RTW89_WW][37] = 0, + [0][1][RTW89_WW][38] = 0, + [0][1][RTW89_WW][40] = 0, + [0][1][RTW89_WW][42] = 0, + [0][1][RTW89_WW][44] = 0, + [0][1][RTW89_WW][46] = 0, + [0][1][RTW89_WW][48] = 0, + [0][1][RTW89_WW][50] = 0, + [0][1][RTW89_WW][52] = 0, + [1][0][RTW89_WW][0] = 26, + [1][0][RTW89_WW][2] = 26, + [1][0][RTW89_WW][4] = 26, + [1][0][RTW89_WW][6] = 26, + [1][0][RTW89_WW][8] = 26, + [1][0][RTW89_WW][10] = 26, + [1][0][RTW89_WW][12] = 26, + [1][0][RTW89_WW][14] = 26, + [1][0][RTW89_WW][15] = 34, + [1][0][RTW89_WW][17] = 34, + [1][0][RTW89_WW][19] = 34, + [1][0][RTW89_WW][21] = 34, + [1][0][RTW89_WW][23] = 34, + [1][0][RTW89_WW][25] = 34, + [1][0][RTW89_WW][27] = 34, + [1][0][RTW89_WW][29] = 34, + [1][0][RTW89_WW][31] = 34, + [1][0][RTW89_WW][33] = 34, + [1][0][RTW89_WW][35] = 34, + [1][0][RTW89_WW][37] = 54, + [1][0][RTW89_WW][38] = 28, + [1][0][RTW89_WW][40] = 28, + [1][0][RTW89_WW][42] = 28, + [1][0][RTW89_WW][44] = 28, + [1][0][RTW89_WW][46] = 28, + [1][0][RTW89_WW][48] = 52, + [1][0][RTW89_WW][50] = 52, + [1][0][RTW89_WW][52] = 52, + [1][1][RTW89_WW][0] = 0, + [1][1][RTW89_WW][2] = 0, + [1][1][RTW89_WW][4] = 0, + [1][1][RTW89_WW][6] = 0, + [1][1][RTW89_WW][8] = 0, + [1][1][RTW89_WW][10] = 0, + [1][1][RTW89_WW][12] = 0, + [1][1][RTW89_WW][14] = 0, + [1][1][RTW89_WW][15] = 0, + [1][1][RTW89_WW][17] = 0, + [1][1][RTW89_WW][19] = 0, + [1][1][RTW89_WW][21] = 0, + [1][1][RTW89_WW][23] = 0, + [1][1][RTW89_WW][25] = 0, + [1][1][RTW89_WW][27] = 0, + [1][1][RTW89_WW][29] = 0, + [1][1][RTW89_WW][31] = 0, + [1][1][RTW89_WW][33] = 0, + [1][1][RTW89_WW][35] = 0, + [1][1][RTW89_WW][37] = 0, + [1][1][RTW89_WW][38] = 0, + [1][1][RTW89_WW][40] = 0, + [1][1][RTW89_WW][42] = 0, + [1][1][RTW89_WW][44] = 0, + [1][1][RTW89_WW][46] = 0, + [1][1][RTW89_WW][48] = 0, + [1][1][RTW89_WW][50] = 0, + [1][1][RTW89_WW][52] = 0, + [2][0][RTW89_WW][0] = 40, + [2][0][RTW89_WW][2] = 40, + [2][0][RTW89_WW][4] = 40, + [2][0][RTW89_WW][6] = 40, + [2][0][RTW89_WW][8] = 40, + [2][0][RTW89_WW][10] = 40, + [2][0][RTW89_WW][12] = 40, + [2][0][RTW89_WW][14] = 40, + [2][0][RTW89_WW][15] = 46, + [2][0][RTW89_WW][17] = 46, + [2][0][RTW89_WW][19] = 46, + [2][0][RTW89_WW][21] = 46, + [2][0][RTW89_WW][23] = 46, + [2][0][RTW89_WW][25] = 46, + [2][0][RTW89_WW][27] = 46, + [2][0][RTW89_WW][29] = 46, + [2][0][RTW89_WW][31] = 46, + [2][0][RTW89_WW][33] = 46, + [2][0][RTW89_WW][35] = 46, + [2][0][RTW89_WW][37] = 66, + [2][0][RTW89_WW][38] = 28, + [2][0][RTW89_WW][40] = 28, + [2][0][RTW89_WW][42] = 28, + [2][0][RTW89_WW][44] = 28, + [2][0][RTW89_WW][46] = 28, + [2][0][RTW89_WW][48] = 64, + [2][0][RTW89_WW][50] = 64, + [2][0][RTW89_WW][52] = 60, + [2][1][RTW89_WW][0] = 0, + [2][1][RTW89_WW][2] = 0, + [2][1][RTW89_WW][4] = 0, + [2][1][RTW89_WW][6] = 0, + [2][1][RTW89_WW][8] = 0, + [2][1][RTW89_WW][10] = 0, + [2][1][RTW89_WW][12] = 0, + [2][1][RTW89_WW][14] = 0, + [2][1][RTW89_WW][15] = 0, + [2][1][RTW89_WW][17] = 0, + [2][1][RTW89_WW][19] = 0, + [2][1][RTW89_WW][21] = 0, + [2][1][RTW89_WW][23] = 0, + [2][1][RTW89_WW][25] = 0, + [2][1][RTW89_WW][27] = 0, + [2][1][RTW89_WW][29] = 0, + [2][1][RTW89_WW][31] = 0, + [2][1][RTW89_WW][33] = 0, + [2][1][RTW89_WW][35] = 0, + [2][1][RTW89_WW][37] = 0, + [2][1][RTW89_WW][38] = 0, + [2][1][RTW89_WW][40] = 0, + [2][1][RTW89_WW][42] = 0, + [2][1][RTW89_WW][44] = 0, + [2][1][RTW89_WW][46] = 0, + [2][1][RTW89_WW][48] = 0, + [2][1][RTW89_WW][50] = 0, + [2][1][RTW89_WW][52] = 0, + [0][0][RTW89_FCC][0] = 52, + [0][0][RTW89_ETSI][0] = 24, + [0][0][RTW89_MKK][0] = 26, + [0][0][RTW89_IC][0] = 28, + [0][0][RTW89_KCC][0] = 42, + [0][0][RTW89_ACMA][0] = 24, + [0][0][RTW89_CN][0] = 16, + [0][0][RTW89_UK][0] = 24, + [0][0][RTW89_FCC][2] = 54, + [0][0][RTW89_ETSI][2] = 24, + [0][0][RTW89_MKK][2] = 26, + [0][0][RTW89_IC][2] = 28, + [0][0][RTW89_KCC][2] = 42, + [0][0][RTW89_ACMA][2] = 24, + [0][0][RTW89_CN][2] = 16, + [0][0][RTW89_UK][2] = 24, + [0][0][RTW89_FCC][4] = 52, + [0][0][RTW89_ETSI][4] = 24, + [0][0][RTW89_MKK][4] = 26, + [0][0][RTW89_IC][4] = 28, + [0][0][RTW89_KCC][4] = 42, + [0][0][RTW89_ACMA][4] = 24, + [0][0][RTW89_CN][4] = 16, + [0][0][RTW89_UK][4] = 24, + [0][0][RTW89_FCC][6] = 52, + [0][0][RTW89_ETSI][6] = 24, + [0][0][RTW89_MKK][6] = 26, + [0][0][RTW89_IC][6] = 28, + [0][0][RTW89_KCC][6] = 18, + [0][0][RTW89_ACMA][6] = 24, + [0][0][RTW89_CN][6] = 16, + [0][0][RTW89_UK][6] = 24, + [0][0][RTW89_FCC][8] = 52, + [0][0][RTW89_ETSI][8] = 24, + [0][0][RTW89_MKK][8] = 26, + [0][0][RTW89_IC][8] = 52, + [0][0][RTW89_KCC][8] = 42, + [0][0][RTW89_ACMA][8] = 24, + [0][0][RTW89_CN][8] = 16, + [0][0][RTW89_UK][8] = 24, + [0][0][RTW89_FCC][10] = 52, + [0][0][RTW89_ETSI][10] = 24, + [0][0][RTW89_MKK][10] = 26, + [0][0][RTW89_IC][10] = 52, + [0][0][RTW89_KCC][10] = 42, + [0][0][RTW89_ACMA][10] = 24, + [0][0][RTW89_CN][10] = 16, + [0][0][RTW89_UK][10] = 24, + [0][0][RTW89_FCC][12] = 56, + [0][0][RTW89_ETSI][12] = 24, + [0][0][RTW89_MKK][12] = 26, + [0][0][RTW89_IC][12] = 56, + [0][0][RTW89_KCC][12] = 44, + [0][0][RTW89_ACMA][12] = 24, + [0][0][RTW89_CN][12] = 16, + [0][0][RTW89_UK][12] = 24, + [0][0][RTW89_FCC][14] = 56, + [0][0][RTW89_ETSI][14] = 24, + [0][0][RTW89_MKK][14] = 26, + [0][0][RTW89_IC][14] = 56, + [0][0][RTW89_KCC][14] = 44, + [0][0][RTW89_ACMA][14] = 24, + [0][0][RTW89_CN][14] = 16, + [0][0][RTW89_UK][14] = 24, + [0][0][RTW89_FCC][15] = 54, + [0][0][RTW89_ETSI][15] = 24, + [0][0][RTW89_MKK][15] = 46, + [0][0][RTW89_IC][15] = 54, + [0][0][RTW89_KCC][15] = 44, + [0][0][RTW89_ACMA][15] = 24, + [0][0][RTW89_CN][15] = 127, + [0][0][RTW89_UK][15] = 24, + [0][0][RTW89_FCC][17] = 54, + [0][0][RTW89_ETSI][17] = 24, + [0][0][RTW89_MKK][17] = 50, + [0][0][RTW89_IC][17] = 54, + [0][0][RTW89_KCC][17] = 44, + [0][0][RTW89_ACMA][17] = 24, + [0][0][RTW89_CN][17] = 127, + [0][0][RTW89_UK][17] = 24, + [0][0][RTW89_FCC][19] = 54, + [0][0][RTW89_ETSI][19] = 24, + [0][0][RTW89_MKK][19] = 50, + [0][0][RTW89_IC][19] = 54, + [0][0][RTW89_KCC][19] = 44, + [0][0][RTW89_ACMA][19] = 24, + [0][0][RTW89_CN][19] = 127, + [0][0][RTW89_UK][19] = 24, + [0][0][RTW89_FCC][21] = 54, + [0][0][RTW89_ETSI][21] = 24, + [0][0][RTW89_MKK][21] = 50, + [0][0][RTW89_IC][21] = 54, + [0][0][RTW89_KCC][21] = 44, + [0][0][RTW89_ACMA][21] = 24, + [0][0][RTW89_CN][21] = 127, + [0][0][RTW89_UK][21] = 24, + [0][0][RTW89_FCC][23] = 54, + [0][0][RTW89_ETSI][23] = 24, + [0][0][RTW89_MKK][23] = 50, + [0][0][RTW89_IC][23] = 54, + [0][0][RTW89_KCC][23] = 44, + [0][0][RTW89_ACMA][23] = 24, + [0][0][RTW89_CN][23] = 127, + [0][0][RTW89_UK][23] = 24, + [0][0][RTW89_FCC][25] = 54, + [0][0][RTW89_ETSI][25] = 24, + [0][0][RTW89_MKK][25] = 50, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_KCC][25] = 44, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_CN][25] = 127, + [0][0][RTW89_UK][25] = 24, + [0][0][RTW89_FCC][27] = 54, + [0][0][RTW89_ETSI][27] = 24, + [0][0][RTW89_MKK][27] = 50, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_KCC][27] = 42, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_CN][27] = 127, + [0][0][RTW89_UK][27] = 24, + [0][0][RTW89_FCC][29] = 54, + [0][0][RTW89_ETSI][29] = 24, + [0][0][RTW89_MKK][29] = 50, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_KCC][29] = 42, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_CN][29] = 127, + [0][0][RTW89_UK][29] = 24, + [0][0][RTW89_FCC][31] = 54, + [0][0][RTW89_ETSI][31] = 24, + [0][0][RTW89_MKK][31] = 50, + [0][0][RTW89_IC][31] = 56, + [0][0][RTW89_KCC][31] = 42, + [0][0][RTW89_ACMA][31] = 24, + [0][0][RTW89_CN][31] = 127, + [0][0][RTW89_UK][31] = 24, + [0][0][RTW89_FCC][33] = 56, + [0][0][RTW89_ETSI][33] = 24, + [0][0][RTW89_MKK][33] = 50, + [0][0][RTW89_IC][33] = 56, + [0][0][RTW89_KCC][33] = 42, + [0][0][RTW89_ACMA][33] = 24, + [0][0][RTW89_CN][33] = 127, + [0][0][RTW89_UK][33] = 24, + [0][0][RTW89_FCC][35] = 56, + [0][0][RTW89_ETSI][35] = 24, + [0][0][RTW89_MKK][35] = 50, + [0][0][RTW89_IC][35] = 56, + [0][0][RTW89_KCC][35] = 42, + [0][0][RTW89_ACMA][35] = 24, + [0][0][RTW89_CN][35] = 127, + [0][0][RTW89_UK][35] = 24, + [0][0][RTW89_FCC][37] = 86, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 46, + [0][0][RTW89_IC][37] = 86, + [0][0][RTW89_KCC][37] = 44, + [0][0][RTW89_ACMA][37] = 50, + [0][0][RTW89_CN][37] = 127, + [0][0][RTW89_UK][37] = 52, + [0][0][RTW89_FCC][38] = 68, + [0][0][RTW89_ETSI][38] = 28, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 68, + [0][0][RTW89_KCC][38] = 44, + [0][0][RTW89_ACMA][38] = 84, + [0][0][RTW89_CN][38] = 54, + [0][0][RTW89_UK][38] = 24, + [0][0][RTW89_FCC][40] = 68, + [0][0][RTW89_ETSI][40] = 28, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 68, + [0][0][RTW89_KCC][40] = 44, + [0][0][RTW89_ACMA][40] = 84, + [0][0][RTW89_CN][40] = 54, + [0][0][RTW89_UK][40] = 24, + [0][0][RTW89_FCC][42] = 70, + [0][0][RTW89_ETSI][42] = 28, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 70, + [0][0][RTW89_KCC][42] = 44, + [0][0][RTW89_ACMA][42] = 84, + [0][0][RTW89_CN][42] = 54, + [0][0][RTW89_UK][42] = 24, + [0][0][RTW89_FCC][44] = 62, + [0][0][RTW89_ETSI][44] = 28, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 62, + [0][0][RTW89_KCC][44] = 44, + [0][0][RTW89_ACMA][44] = 84, + [0][0][RTW89_CN][44] = 54, + [0][0][RTW89_UK][44] = 24, + [0][0][RTW89_FCC][46] = 62, + [0][0][RTW89_ETSI][46] = 28, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 62, + [0][0][RTW89_KCC][46] = 44, + [0][0][RTW89_ACMA][46] = 84, + [0][0][RTW89_CN][46] = 54, + [0][0][RTW89_UK][46] = 24, + [0][0][RTW89_FCC][48] = 42, + [0][0][RTW89_ETSI][48] = 127, + [0][0][RTW89_MKK][48] = 127, + [0][0][RTW89_IC][48] = 42, + [0][0][RTW89_KCC][48] = 127, + [0][0][RTW89_ACMA][48] = 127, + [0][0][RTW89_CN][48] = 127, + [0][0][RTW89_UK][48] = 127, + [0][0][RTW89_FCC][50] = 42, + [0][0][RTW89_ETSI][50] = 127, + [0][0][RTW89_MKK][50] = 127, + [0][0][RTW89_IC][50] = 42, + [0][0][RTW89_KCC][50] = 127, + [0][0][RTW89_ACMA][50] = 127, + [0][0][RTW89_CN][50] = 127, + [0][0][RTW89_UK][50] = 127, + [0][0][RTW89_FCC][52] = 40, + [0][0][RTW89_ETSI][52] = 127, + [0][0][RTW89_MKK][52] = 127, + [0][0][RTW89_IC][52] = 40, + [0][0][RTW89_KCC][52] = 127, + [0][0][RTW89_ACMA][52] = 127, + [0][0][RTW89_CN][52] = 127, + [0][0][RTW89_UK][52] = 127, + [0][1][RTW89_FCC][0] = 127, + [0][1][RTW89_ETSI][0] = 127, + [0][1][RTW89_MKK][0] = 127, + [0][1][RTW89_IC][0] = 127, + [0][1][RTW89_KCC][0] = 127, + [0][1][RTW89_ACMA][0] = 127, + [0][1][RTW89_CN][0] = 127, + [0][1][RTW89_UK][0] = 127, + [0][1][RTW89_FCC][2] = 127, + [0][1][RTW89_ETSI][2] = 127, + [0][1][RTW89_MKK][2] = 127, + [0][1][RTW89_IC][2] = 127, + [0][1][RTW89_KCC][2] = 127, + [0][1][RTW89_ACMA][2] = 127, + [0][1][RTW89_CN][2] = 127, + [0][1][RTW89_UK][2] = 127, + [0][1][RTW89_FCC][4] = 127, + [0][1][RTW89_ETSI][4] = 127, + [0][1][RTW89_MKK][4] = 127, + [0][1][RTW89_IC][4] = 127, + [0][1][RTW89_KCC][4] = 127, + [0][1][RTW89_ACMA][4] = 127, + [0][1][RTW89_CN][4] = 127, + [0][1][RTW89_UK][4] = 127, + [0][1][RTW89_FCC][6] = 127, + [0][1][RTW89_ETSI][6] = 127, + [0][1][RTW89_MKK][6] = 127, + [0][1][RTW89_IC][6] = 127, + [0][1][RTW89_KCC][6] = 127, + [0][1][RTW89_ACMA][6] = 127, + [0][1][RTW89_CN][6] = 127, + [0][1][RTW89_UK][6] = 127, + [0][1][RTW89_FCC][8] = 127, + [0][1][RTW89_ETSI][8] = 127, + [0][1][RTW89_MKK][8] = 127, + [0][1][RTW89_IC][8] = 127, + [0][1][RTW89_KCC][8] = 127, + [0][1][RTW89_ACMA][8] = 127, + [0][1][RTW89_CN][8] = 127, + [0][1][RTW89_UK][8] = 127, + [0][1][RTW89_FCC][10] = 127, + [0][1][RTW89_ETSI][10] = 127, + [0][1][RTW89_MKK][10] = 127, + [0][1][RTW89_IC][10] = 127, + [0][1][RTW89_KCC][10] = 127, + [0][1][RTW89_ACMA][10] = 127, + [0][1][RTW89_CN][10] = 127, + [0][1][RTW89_UK][10] = 127, + [0][1][RTW89_FCC][12] = 127, + [0][1][RTW89_ETSI][12] = 127, + [0][1][RTW89_MKK][12] = 127, + [0][1][RTW89_IC][12] = 127, + [0][1][RTW89_KCC][12] = 127, + [0][1][RTW89_ACMA][12] = 127, + [0][1][RTW89_CN][12] = 127, + [0][1][RTW89_UK][12] = 127, + [0][1][RTW89_FCC][14] = 127, + [0][1][RTW89_ETSI][14] = 127, + [0][1][RTW89_MKK][14] = 127, + [0][1][RTW89_IC][14] = 127, + [0][1][RTW89_KCC][14] = 127, + [0][1][RTW89_ACMA][14] = 127, + [0][1][RTW89_CN][14] = 127, + [0][1][RTW89_UK][14] = 127, + [0][1][RTW89_FCC][15] = 127, + [0][1][RTW89_ETSI][15] = 127, + [0][1][RTW89_MKK][15] = 127, + [0][1][RTW89_IC][15] = 127, + [0][1][RTW89_KCC][15] = 127, + [0][1][RTW89_ACMA][15] = 127, + [0][1][RTW89_CN][15] = 127, + [0][1][RTW89_UK][15] = 127, + [0][1][RTW89_FCC][17] = 127, + [0][1][RTW89_ETSI][17] = 127, + [0][1][RTW89_MKK][17] = 127, + [0][1][RTW89_IC][17] = 127, + [0][1][RTW89_KCC][17] = 127, + [0][1][RTW89_ACMA][17] = 127, + [0][1][RTW89_CN][17] = 127, + [0][1][RTW89_UK][17] = 127, + [0][1][RTW89_FCC][19] = 127, + [0][1][RTW89_ETSI][19] = 127, + [0][1][RTW89_MKK][19] = 127, + [0][1][RTW89_IC][19] = 127, + [0][1][RTW89_KCC][19] = 127, + [0][1][RTW89_ACMA][19] = 127, + [0][1][RTW89_CN][19] = 127, + [0][1][RTW89_UK][19] = 127, + [0][1][RTW89_FCC][21] = 127, + [0][1][RTW89_ETSI][21] = 127, + [0][1][RTW89_MKK][21] = 127, + [0][1][RTW89_IC][21] = 127, + [0][1][RTW89_KCC][21] = 127, + [0][1][RTW89_ACMA][21] = 127, + [0][1][RTW89_CN][21] = 127, + [0][1][RTW89_UK][21] = 127, + [0][1][RTW89_FCC][23] = 127, + [0][1][RTW89_ETSI][23] = 127, + [0][1][RTW89_MKK][23] = 127, + [0][1][RTW89_IC][23] = 127, + [0][1][RTW89_KCC][23] = 127, + [0][1][RTW89_ACMA][23] = 127, + [0][1][RTW89_CN][23] = 127, + [0][1][RTW89_UK][23] = 127, + [0][1][RTW89_FCC][25] = 127, + [0][1][RTW89_ETSI][25] = 127, + [0][1][RTW89_MKK][25] = 127, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_KCC][25] = 127, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_CN][25] = 127, + [0][1][RTW89_UK][25] = 127, + [0][1][RTW89_FCC][27] = 127, + [0][1][RTW89_ETSI][27] = 127, + [0][1][RTW89_MKK][27] = 127, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_KCC][27] = 127, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_CN][27] = 127, + [0][1][RTW89_UK][27] = 127, + [0][1][RTW89_FCC][29] = 127, + [0][1][RTW89_ETSI][29] = 127, + [0][1][RTW89_MKK][29] = 127, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_KCC][29] = 127, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_CN][29] = 127, + [0][1][RTW89_UK][29] = 127, + [0][1][RTW89_FCC][31] = 127, + [0][1][RTW89_ETSI][31] = 127, + [0][1][RTW89_MKK][31] = 127, + [0][1][RTW89_IC][31] = 127, + [0][1][RTW89_KCC][31] = 127, + [0][1][RTW89_ACMA][31] = 127, + [0][1][RTW89_CN][31] = 127, + [0][1][RTW89_UK][31] = 127, + [0][1][RTW89_FCC][33] = 127, + [0][1][RTW89_ETSI][33] = 127, + [0][1][RTW89_MKK][33] = 127, + [0][1][RTW89_IC][33] = 127, + [0][1][RTW89_KCC][33] = 127, + [0][1][RTW89_ACMA][33] = 127, + [0][1][RTW89_CN][33] = 127, + [0][1][RTW89_UK][33] = 127, + [0][1][RTW89_FCC][35] = 127, + [0][1][RTW89_ETSI][35] = 127, + [0][1][RTW89_MKK][35] = 127, + [0][1][RTW89_IC][35] = 127, + [0][1][RTW89_KCC][35] = 127, + [0][1][RTW89_ACMA][35] = 127, + [0][1][RTW89_CN][35] = 127, + [0][1][RTW89_UK][35] = 127, + [0][1][RTW89_FCC][37] = 127, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 127, + [0][1][RTW89_IC][37] = 127, + [0][1][RTW89_KCC][37] = 127, + [0][1][RTW89_ACMA][37] = 127, + [0][1][RTW89_CN][37] = 127, + [0][1][RTW89_UK][37] = 127, + [0][1][RTW89_FCC][38] = 127, + [0][1][RTW89_ETSI][38] = 127, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 127, + [0][1][RTW89_KCC][38] = 127, + [0][1][RTW89_ACMA][38] = 127, + [0][1][RTW89_CN][38] = 127, + [0][1][RTW89_UK][38] = 127, + [0][1][RTW89_FCC][40] = 127, + [0][1][RTW89_ETSI][40] = 127, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 127, + [0][1][RTW89_KCC][40] = 127, + [0][1][RTW89_ACMA][40] = 127, + [0][1][RTW89_CN][40] = 127, + [0][1][RTW89_UK][40] = 127, + [0][1][RTW89_FCC][42] = 127, + [0][1][RTW89_ETSI][42] = 127, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 127, + [0][1][RTW89_KCC][42] = 127, + [0][1][RTW89_ACMA][42] = 127, + [0][1][RTW89_CN][42] = 127, + [0][1][RTW89_UK][42] = 127, + [0][1][RTW89_FCC][44] = 127, + [0][1][RTW89_ETSI][44] = 127, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 127, + [0][1][RTW89_KCC][44] = 127, + [0][1][RTW89_ACMA][44] = 127, + [0][1][RTW89_CN][44] = 127, + [0][1][RTW89_UK][44] = 127, + [0][1][RTW89_FCC][46] = 127, + [0][1][RTW89_ETSI][46] = 127, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 127, + [0][1][RTW89_KCC][46] = 127, + [0][1][RTW89_ACMA][46] = 127, + [0][1][RTW89_CN][46] = 127, + [0][1][RTW89_UK][46] = 127, + [0][1][RTW89_FCC][48] = 127, + [0][1][RTW89_ETSI][48] = 127, + [0][1][RTW89_MKK][48] = 127, + [0][1][RTW89_IC][48] = 127, + [0][1][RTW89_KCC][48] = 127, + [0][1][RTW89_ACMA][48] = 127, + [0][1][RTW89_CN][48] = 127, + [0][1][RTW89_UK][48] = 127, + [0][1][RTW89_FCC][50] = 127, + [0][1][RTW89_ETSI][50] = 127, + [0][1][RTW89_MKK][50] = 127, + [0][1][RTW89_IC][50] = 127, + [0][1][RTW89_KCC][50] = 127, + [0][1][RTW89_ACMA][50] = 127, + [0][1][RTW89_CN][50] = 127, + [0][1][RTW89_UK][50] = 127, + [0][1][RTW89_FCC][52] = 127, + [0][1][RTW89_ETSI][52] = 127, + [0][1][RTW89_MKK][52] = 127, + [0][1][RTW89_IC][52] = 127, + [0][1][RTW89_KCC][52] = 127, + [0][1][RTW89_ACMA][52] = 127, + [0][1][RTW89_CN][52] = 127, + [0][1][RTW89_UK][52] = 127, + [1][0][RTW89_FCC][0] = 64, + [1][0][RTW89_ETSI][0] = 34, + [1][0][RTW89_MKK][0] = 38, + [1][0][RTW89_IC][0] = 38, + [1][0][RTW89_KCC][0] = 52, + [1][0][RTW89_ACMA][0] = 34, + [1][0][RTW89_CN][0] = 26, + [1][0][RTW89_UK][0] = 34, + [1][0][RTW89_FCC][2] = 66, + [1][0][RTW89_ETSI][2] = 34, + [1][0][RTW89_MKK][2] = 38, + [1][0][RTW89_IC][2] = 38, + [1][0][RTW89_KCC][2] = 52, + [1][0][RTW89_ACMA][2] = 34, + [1][0][RTW89_CN][2] = 26, + [1][0][RTW89_UK][2] = 34, + [1][0][RTW89_FCC][4] = 62, + [1][0][RTW89_ETSI][4] = 34, + [1][0][RTW89_MKK][4] = 36, + [1][0][RTW89_IC][4] = 38, + [1][0][RTW89_KCC][4] = 52, + [1][0][RTW89_ACMA][4] = 34, + [1][0][RTW89_CN][4] = 26, + [1][0][RTW89_UK][4] = 34, + [1][0][RTW89_FCC][6] = 62, + [1][0][RTW89_ETSI][6] = 34, + [1][0][RTW89_MKK][6] = 36, + [1][0][RTW89_IC][6] = 38, + [1][0][RTW89_KCC][6] = 32, + [1][0][RTW89_ACMA][6] = 34, + [1][0][RTW89_CN][6] = 26, + [1][0][RTW89_UK][6] = 34, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 34, + [1][0][RTW89_MKK][8] = 38, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_KCC][8] = 52, + [1][0][RTW89_ACMA][8] = 34, + [1][0][RTW89_CN][8] = 26, + [1][0][RTW89_UK][8] = 34, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 34, + [1][0][RTW89_MKK][10] = 38, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_KCC][10] = 52, + [1][0][RTW89_ACMA][10] = 34, + [1][0][RTW89_CN][10] = 26, + [1][0][RTW89_UK][10] = 34, + [1][0][RTW89_FCC][12] = 62, + [1][0][RTW89_ETSI][12] = 34, + [1][0][RTW89_MKK][12] = 38, + [1][0][RTW89_IC][12] = 62, + [1][0][RTW89_KCC][12] = 54, + [1][0][RTW89_ACMA][12] = 34, + [1][0][RTW89_CN][12] = 26, + [1][0][RTW89_UK][12] = 34, + [1][0][RTW89_FCC][14] = 64, + [1][0][RTW89_ETSI][14] = 34, + [1][0][RTW89_MKK][14] = 38, + [1][0][RTW89_IC][14] = 64, + [1][0][RTW89_KCC][14] = 54, + [1][0][RTW89_ACMA][14] = 34, + [1][0][RTW89_CN][14] = 26, + [1][0][RTW89_UK][14] = 34, + [1][0][RTW89_FCC][15] = 62, + [1][0][RTW89_ETSI][15] = 34, + [1][0][RTW89_MKK][15] = 58, + [1][0][RTW89_IC][15] = 62, + [1][0][RTW89_KCC][15] = 54, + [1][0][RTW89_ACMA][15] = 34, + [1][0][RTW89_CN][15] = 127, + [1][0][RTW89_UK][15] = 34, + [1][0][RTW89_FCC][17] = 62, + [1][0][RTW89_ETSI][17] = 34, + [1][0][RTW89_MKK][17] = 58, + [1][0][RTW89_IC][17] = 62, + [1][0][RTW89_KCC][17] = 54, + [1][0][RTW89_ACMA][17] = 34, + [1][0][RTW89_CN][17] = 127, + [1][0][RTW89_UK][17] = 34, + [1][0][RTW89_FCC][19] = 64, + [1][0][RTW89_ETSI][19] = 34, + [1][0][RTW89_MKK][19] = 58, + [1][0][RTW89_IC][19] = 64, + [1][0][RTW89_KCC][19] = 54, + [1][0][RTW89_ACMA][19] = 34, + [1][0][RTW89_CN][19] = 127, + [1][0][RTW89_UK][19] = 34, + [1][0][RTW89_FCC][21] = 64, + [1][0][RTW89_ETSI][21] = 34, + [1][0][RTW89_MKK][21] = 58, + [1][0][RTW89_IC][21] = 64, + [1][0][RTW89_KCC][21] = 54, + [1][0][RTW89_ACMA][21] = 34, + [1][0][RTW89_CN][21] = 127, + [1][0][RTW89_UK][21] = 34, + [1][0][RTW89_FCC][23] = 64, + [1][0][RTW89_ETSI][23] = 34, + [1][0][RTW89_MKK][23] = 58, + [1][0][RTW89_IC][23] = 64, + [1][0][RTW89_KCC][23] = 54, + [1][0][RTW89_ACMA][23] = 34, + [1][0][RTW89_CN][23] = 127, + [1][0][RTW89_UK][23] = 34, + [1][0][RTW89_FCC][25] = 64, + [1][0][RTW89_ETSI][25] = 34, + [1][0][RTW89_MKK][25] = 58, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_KCC][25] = 54, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_CN][25] = 127, + [1][0][RTW89_UK][25] = 34, + [1][0][RTW89_FCC][27] = 64, + [1][0][RTW89_ETSI][27] = 34, + [1][0][RTW89_MKK][27] = 58, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_KCC][27] = 54, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_CN][27] = 127, + [1][0][RTW89_UK][27] = 34, + [1][0][RTW89_FCC][29] = 64, + [1][0][RTW89_ETSI][29] = 34, + [1][0][RTW89_MKK][29] = 58, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_KCC][29] = 54, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_CN][29] = 127, + [1][0][RTW89_UK][29] = 34, + [1][0][RTW89_FCC][31] = 64, + [1][0][RTW89_ETSI][31] = 34, + [1][0][RTW89_MKK][31] = 58, + [1][0][RTW89_IC][31] = 64, + [1][0][RTW89_KCC][31] = 54, + [1][0][RTW89_ACMA][31] = 34, + [1][0][RTW89_CN][31] = 127, + [1][0][RTW89_UK][31] = 34, + [1][0][RTW89_FCC][33] = 64, + [1][0][RTW89_ETSI][33] = 34, + [1][0][RTW89_MKK][33] = 58, + [1][0][RTW89_IC][33] = 64, + [1][0][RTW89_KCC][33] = 54, + [1][0][RTW89_ACMA][33] = 34, + [1][0][RTW89_CN][33] = 127, + [1][0][RTW89_UK][33] = 34, + [1][0][RTW89_FCC][35] = 64, + [1][0][RTW89_ETSI][35] = 34, + [1][0][RTW89_MKK][35] = 58, + [1][0][RTW89_IC][35] = 64, + [1][0][RTW89_KCC][35] = 54, + [1][0][RTW89_ACMA][35] = 34, + [1][0][RTW89_CN][35] = 127, + [1][0][RTW89_UK][35] = 34, + [1][0][RTW89_FCC][37] = 78, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 56, + [1][0][RTW89_IC][37] = 78, + [1][0][RTW89_KCC][37] = 54, + [1][0][RTW89_ACMA][37] = 62, + [1][0][RTW89_CN][37] = 127, + [1][0][RTW89_UK][37] = 62, + [1][0][RTW89_FCC][38] = 82, + [1][0][RTW89_ETSI][38] = 28, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 82, + [1][0][RTW89_KCC][38] = 54, + [1][0][RTW89_ACMA][38] = 84, + [1][0][RTW89_CN][38] = 66, + [1][0][RTW89_UK][38] = 34, + [1][0][RTW89_FCC][40] = 82, + [1][0][RTW89_ETSI][40] = 28, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 82, + [1][0][RTW89_KCC][40] = 54, + [1][0][RTW89_ACMA][40] = 84, + [1][0][RTW89_CN][40] = 66, + [1][0][RTW89_UK][40] = 34, + [1][0][RTW89_FCC][42] = 78, + [1][0][RTW89_ETSI][42] = 28, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 78, + [1][0][RTW89_KCC][42] = 54, + [1][0][RTW89_ACMA][42] = 84, + [1][0][RTW89_CN][42] = 66, + [1][0][RTW89_UK][42] = 34, + [1][0][RTW89_FCC][44] = 82, + [1][0][RTW89_ETSI][44] = 28, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 82, + [1][0][RTW89_KCC][44] = 54, + [1][0][RTW89_ACMA][44] = 84, + [1][0][RTW89_CN][44] = 66, + [1][0][RTW89_UK][44] = 34, + [1][0][RTW89_FCC][46] = 82, + [1][0][RTW89_ETSI][46] = 28, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 82, + [1][0][RTW89_KCC][46] = 54, + [1][0][RTW89_ACMA][46] = 84, + [1][0][RTW89_CN][46] = 66, + [1][0][RTW89_UK][46] = 34, + [1][0][RTW89_FCC][48] = 52, + [1][0][RTW89_ETSI][48] = 127, + [1][0][RTW89_MKK][48] = 127, + [1][0][RTW89_IC][48] = 52, + [1][0][RTW89_KCC][48] = 127, + [1][0][RTW89_ACMA][48] = 127, + [1][0][RTW89_CN][48] = 127, + [1][0][RTW89_UK][48] = 127, + [1][0][RTW89_FCC][50] = 52, + [1][0][RTW89_ETSI][50] = 127, + [1][0][RTW89_MKK][50] = 127, + [1][0][RTW89_IC][50] = 52, + [1][0][RTW89_KCC][50] = 127, + [1][0][RTW89_ACMA][50] = 127, + [1][0][RTW89_CN][50] = 127, + [1][0][RTW89_UK][50] = 127, + [1][0][RTW89_FCC][52] = 52, + [1][0][RTW89_ETSI][52] = 127, + [1][0][RTW89_MKK][52] = 127, + [1][0][RTW89_IC][52] = 52, + [1][0][RTW89_KCC][52] = 127, + [1][0][RTW89_ACMA][52] = 127, + [1][0][RTW89_CN][52] = 127, + [1][0][RTW89_UK][52] = 127, + [1][1][RTW89_FCC][0] = 127, + [1][1][RTW89_ETSI][0] = 127, + [1][1][RTW89_MKK][0] = 127, + [1][1][RTW89_IC][0] = 127, + [1][1][RTW89_KCC][0] = 127, + [1][1][RTW89_ACMA][0] = 127, + [1][1][RTW89_CN][0] = 127, + [1][1][RTW89_UK][0] = 127, + [1][1][RTW89_FCC][2] = 127, + [1][1][RTW89_ETSI][2] = 127, + [1][1][RTW89_MKK][2] = 127, + [1][1][RTW89_IC][2] = 127, + [1][1][RTW89_KCC][2] = 127, + [1][1][RTW89_ACMA][2] = 127, + [1][1][RTW89_CN][2] = 127, + [1][1][RTW89_UK][2] = 127, + [1][1][RTW89_FCC][4] = 127, + [1][1][RTW89_ETSI][4] = 127, + [1][1][RTW89_MKK][4] = 127, + [1][1][RTW89_IC][4] = 127, + [1][1][RTW89_KCC][4] = 127, + [1][1][RTW89_ACMA][4] = 127, + [1][1][RTW89_CN][4] = 127, + [1][1][RTW89_UK][4] = 127, + [1][1][RTW89_FCC][6] = 127, + [1][1][RTW89_ETSI][6] = 127, + [1][1][RTW89_MKK][6] = 127, + [1][1][RTW89_IC][6] = 127, + [1][1][RTW89_KCC][6] = 127, + [1][1][RTW89_ACMA][6] = 127, + [1][1][RTW89_CN][6] = 127, + [1][1][RTW89_UK][6] = 127, + [1][1][RTW89_FCC][8] = 127, + [1][1][RTW89_ETSI][8] = 127, + [1][1][RTW89_MKK][8] = 127, + [1][1][RTW89_IC][8] = 127, + [1][1][RTW89_KCC][8] = 127, + [1][1][RTW89_ACMA][8] = 127, + [1][1][RTW89_CN][8] = 127, + [1][1][RTW89_UK][8] = 127, + [1][1][RTW89_FCC][10] = 127, + [1][1][RTW89_ETSI][10] = 127, + [1][1][RTW89_MKK][10] = 127, + [1][1][RTW89_IC][10] = 127, + [1][1][RTW89_KCC][10] = 127, + [1][1][RTW89_ACMA][10] = 127, + [1][1][RTW89_CN][10] = 127, + [1][1][RTW89_UK][10] = 127, + [1][1][RTW89_FCC][12] = 127, + [1][1][RTW89_ETSI][12] = 127, + [1][1][RTW89_MKK][12] = 127, + [1][1][RTW89_IC][12] = 127, + [1][1][RTW89_KCC][12] = 127, + [1][1][RTW89_ACMA][12] = 127, + [1][1][RTW89_CN][12] = 127, + [1][1][RTW89_UK][12] = 127, + [1][1][RTW89_FCC][14] = 127, + [1][1][RTW89_ETSI][14] = 127, + [1][1][RTW89_MKK][14] = 127, + [1][1][RTW89_IC][14] = 127, + [1][1][RTW89_KCC][14] = 127, + [1][1][RTW89_ACMA][14] = 127, + [1][1][RTW89_CN][14] = 127, + [1][1][RTW89_UK][14] = 127, + [1][1][RTW89_FCC][15] = 127, + [1][1][RTW89_ETSI][15] = 127, + [1][1][RTW89_MKK][15] = 127, + [1][1][RTW89_IC][15] = 127, + [1][1][RTW89_KCC][15] = 127, + [1][1][RTW89_ACMA][15] = 127, + [1][1][RTW89_CN][15] = 127, + [1][1][RTW89_UK][15] = 127, + [1][1][RTW89_FCC][17] = 127, + [1][1][RTW89_ETSI][17] = 127, + [1][1][RTW89_MKK][17] = 127, + [1][1][RTW89_IC][17] = 127, + [1][1][RTW89_KCC][17] = 127, + [1][1][RTW89_ACMA][17] = 127, + [1][1][RTW89_CN][17] = 127, + [1][1][RTW89_UK][17] = 127, + [1][1][RTW89_FCC][19] = 127, + [1][1][RTW89_ETSI][19] = 127, + [1][1][RTW89_MKK][19] = 127, + [1][1][RTW89_IC][19] = 127, + [1][1][RTW89_KCC][19] = 127, + [1][1][RTW89_ACMA][19] = 127, + [1][1][RTW89_CN][19] = 127, + [1][1][RTW89_UK][19] = 127, + [1][1][RTW89_FCC][21] = 127, + [1][1][RTW89_ETSI][21] = 127, + [1][1][RTW89_MKK][21] = 127, + [1][1][RTW89_IC][21] = 127, + [1][1][RTW89_KCC][21] = 127, + [1][1][RTW89_ACMA][21] = 127, + [1][1][RTW89_CN][21] = 127, + [1][1][RTW89_UK][21] = 127, + [1][1][RTW89_FCC][23] = 127, + [1][1][RTW89_ETSI][23] = 127, + [1][1][RTW89_MKK][23] = 127, + [1][1][RTW89_IC][23] = 127, + [1][1][RTW89_KCC][23] = 127, + [1][1][RTW89_ACMA][23] = 127, + [1][1][RTW89_CN][23] = 127, + [1][1][RTW89_UK][23] = 127, + [1][1][RTW89_FCC][25] = 127, + [1][1][RTW89_ETSI][25] = 127, + [1][1][RTW89_MKK][25] = 127, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_KCC][25] = 127, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_CN][25] = 127, + [1][1][RTW89_UK][25] = 127, + [1][1][RTW89_FCC][27] = 127, + [1][1][RTW89_ETSI][27] = 127, + [1][1][RTW89_MKK][27] = 127, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_KCC][27] = 127, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_CN][27] = 127, + [1][1][RTW89_UK][27] = 127, + [1][1][RTW89_FCC][29] = 127, + [1][1][RTW89_ETSI][29] = 127, + [1][1][RTW89_MKK][29] = 127, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_KCC][29] = 127, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_CN][29] = 127, + [1][1][RTW89_UK][29] = 127, + [1][1][RTW89_FCC][31] = 127, + [1][1][RTW89_ETSI][31] = 127, + [1][1][RTW89_MKK][31] = 127, + [1][1][RTW89_IC][31] = 127, + [1][1][RTW89_KCC][31] = 127, + [1][1][RTW89_ACMA][31] = 127, + [1][1][RTW89_CN][31] = 127, + [1][1][RTW89_UK][31] = 127, + [1][1][RTW89_FCC][33] = 127, + [1][1][RTW89_ETSI][33] = 127, + [1][1][RTW89_MKK][33] = 127, + [1][1][RTW89_IC][33] = 127, + [1][1][RTW89_KCC][33] = 127, + [1][1][RTW89_ACMA][33] = 127, + [1][1][RTW89_CN][33] = 127, + [1][1][RTW89_UK][33] = 127, + [1][1][RTW89_FCC][35] = 127, + [1][1][RTW89_ETSI][35] = 127, + [1][1][RTW89_MKK][35] = 127, + [1][1][RTW89_IC][35] = 127, + [1][1][RTW89_KCC][35] = 127, + [1][1][RTW89_ACMA][35] = 127, + [1][1][RTW89_CN][35] = 127, + [1][1][RTW89_UK][35] = 127, + [1][1][RTW89_FCC][37] = 127, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 127, + [1][1][RTW89_IC][37] = 127, + [1][1][RTW89_KCC][37] = 127, + [1][1][RTW89_ACMA][37] = 127, + [1][1][RTW89_CN][37] = 127, + [1][1][RTW89_UK][37] = 127, + [1][1][RTW89_FCC][38] = 127, + [1][1][RTW89_ETSI][38] = 127, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 127, + [1][1][RTW89_KCC][38] = 127, + [1][1][RTW89_ACMA][38] = 127, + [1][1][RTW89_CN][38] = 127, + [1][1][RTW89_UK][38] = 127, + [1][1][RTW89_FCC][40] = 127, + [1][1][RTW89_ETSI][40] = 127, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 127, + [1][1][RTW89_KCC][40] = 127, + [1][1][RTW89_ACMA][40] = 127, + [1][1][RTW89_CN][40] = 127, + [1][1][RTW89_UK][40] = 127, + [1][1][RTW89_FCC][42] = 127, + [1][1][RTW89_ETSI][42] = 127, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 127, + [1][1][RTW89_KCC][42] = 127, + [1][1][RTW89_ACMA][42] = 127, + [1][1][RTW89_CN][42] = 127, + [1][1][RTW89_UK][42] = 127, + [1][1][RTW89_FCC][44] = 127, + [1][1][RTW89_ETSI][44] = 127, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 127, + [1][1][RTW89_KCC][44] = 127, + [1][1][RTW89_ACMA][44] = 127, + [1][1][RTW89_CN][44] = 127, + [1][1][RTW89_UK][44] = 127, + [1][1][RTW89_FCC][46] = 127, + [1][1][RTW89_ETSI][46] = 127, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 127, + [1][1][RTW89_KCC][46] = 127, + [1][1][RTW89_ACMA][46] = 127, + [1][1][RTW89_CN][46] = 127, + [1][1][RTW89_UK][46] = 127, + [1][1][RTW89_FCC][48] = 127, + [1][1][RTW89_ETSI][48] = 127, + [1][1][RTW89_MKK][48] = 127, + [1][1][RTW89_IC][48] = 127, + [1][1][RTW89_KCC][48] = 127, + [1][1][RTW89_ACMA][48] = 127, + [1][1][RTW89_CN][48] = 127, + [1][1][RTW89_UK][48] = 127, + [1][1][RTW89_FCC][50] = 127, + [1][1][RTW89_ETSI][50] = 127, + [1][1][RTW89_MKK][50] = 127, + [1][1][RTW89_IC][50] = 127, + [1][1][RTW89_KCC][50] = 127, + [1][1][RTW89_ACMA][50] = 127, + [1][1][RTW89_CN][50] = 127, + [1][1][RTW89_UK][50] = 127, + [1][1][RTW89_FCC][52] = 127, + [1][1][RTW89_ETSI][52] = 127, + [1][1][RTW89_MKK][52] = 127, + [1][1][RTW89_IC][52] = 127, + [1][1][RTW89_KCC][52] = 127, + [1][1][RTW89_ACMA][52] = 127, + [1][1][RTW89_CN][52] = 127, + [1][1][RTW89_UK][52] = 127, + [2][0][RTW89_FCC][0] = 78, + [2][0][RTW89_ETSI][0] = 46, + [2][0][RTW89_MKK][0] = 48, + [2][0][RTW89_IC][0] = 50, + [2][0][RTW89_KCC][0] = 64, + [2][0][RTW89_ACMA][0] = 46, + [2][0][RTW89_CN][0] = 40, + [2][0][RTW89_UK][0] = 46, + [2][0][RTW89_FCC][2] = 74, + [2][0][RTW89_ETSI][2] = 46, + [2][0][RTW89_MKK][2] = 48, + [2][0][RTW89_IC][2] = 48, + [2][0][RTW89_KCC][2] = 64, + [2][0][RTW89_ACMA][2] = 46, + [2][0][RTW89_CN][2] = 40, + [2][0][RTW89_UK][2] = 46, + [2][0][RTW89_FCC][4] = 74, + [2][0][RTW89_ETSI][4] = 46, + [2][0][RTW89_MKK][4] = 48, + [2][0][RTW89_IC][4] = 48, + [2][0][RTW89_KCC][4] = 64, + [2][0][RTW89_ACMA][4] = 46, + [2][0][RTW89_CN][4] = 40, + [2][0][RTW89_UK][4] = 46, + [2][0][RTW89_FCC][6] = 74, + [2][0][RTW89_ETSI][6] = 46, + [2][0][RTW89_MKK][6] = 48, + [2][0][RTW89_IC][6] = 48, + [2][0][RTW89_KCC][6] = 40, + [2][0][RTW89_ACMA][6] = 46, + [2][0][RTW89_CN][6] = 40, + [2][0][RTW89_UK][6] = 46, + [2][0][RTW89_FCC][8] = 74, + [2][0][RTW89_ETSI][8] = 46, + [2][0][RTW89_MKK][8] = 48, + [2][0][RTW89_IC][8] = 64, + [2][0][RTW89_KCC][8] = 66, + [2][0][RTW89_ACMA][8] = 46, + [2][0][RTW89_CN][8] = 40, + [2][0][RTW89_UK][8] = 46, + [2][0][RTW89_FCC][10] = 74, + [2][0][RTW89_ETSI][10] = 46, + [2][0][RTW89_MKK][10] = 48, + [2][0][RTW89_IC][10] = 64, + [2][0][RTW89_KCC][10] = 66, + [2][0][RTW89_ACMA][10] = 46, + [2][0][RTW89_CN][10] = 40, + [2][0][RTW89_UK][10] = 46, + [2][0][RTW89_FCC][12] = 74, + [2][0][RTW89_ETSI][12] = 46, + [2][0][RTW89_MKK][12] = 48, + [2][0][RTW89_IC][12] = 64, + [2][0][RTW89_KCC][12] = 64, + [2][0][RTW89_ACMA][12] = 46, + [2][0][RTW89_CN][12] = 40, + [2][0][RTW89_UK][12] = 46, + [2][0][RTW89_FCC][14] = 80, + [2][0][RTW89_ETSI][14] = 46, + [2][0][RTW89_MKK][14] = 48, + [2][0][RTW89_IC][14] = 64, + [2][0][RTW89_KCC][14] = 64, + [2][0][RTW89_ACMA][14] = 46, + [2][0][RTW89_CN][14] = 40, + [2][0][RTW89_UK][14] = 46, + [2][0][RTW89_FCC][15] = 72, + [2][0][RTW89_ETSI][15] = 46, + [2][0][RTW89_MKK][15] = 70, + [2][0][RTW89_IC][15] = 72, + [2][0][RTW89_KCC][15] = 66, + [2][0][RTW89_ACMA][15] = 46, + [2][0][RTW89_CN][15] = 127, + [2][0][RTW89_UK][15] = 46, + [2][0][RTW89_FCC][17] = 72, + [2][0][RTW89_ETSI][17] = 46, + [2][0][RTW89_MKK][17] = 70, + [2][0][RTW89_IC][17] = 72, + [2][0][RTW89_KCC][17] = 66, + [2][0][RTW89_ACMA][17] = 46, + [2][0][RTW89_CN][17] = 127, + [2][0][RTW89_UK][17] = 46, + [2][0][RTW89_FCC][19] = 70, + [2][0][RTW89_ETSI][19] = 46, + [2][0][RTW89_MKK][19] = 70, + [2][0][RTW89_IC][19] = 70, + [2][0][RTW89_KCC][19] = 66, + [2][0][RTW89_ACMA][19] = 46, + [2][0][RTW89_CN][19] = 127, + [2][0][RTW89_UK][19] = 46, + [2][0][RTW89_FCC][21] = 70, + [2][0][RTW89_ETSI][21] = 46, + [2][0][RTW89_MKK][21] = 70, + [2][0][RTW89_IC][21] = 70, + [2][0][RTW89_KCC][21] = 66, + [2][0][RTW89_ACMA][21] = 46, + [2][0][RTW89_CN][21] = 127, + [2][0][RTW89_UK][21] = 46, + [2][0][RTW89_FCC][23] = 70, + [2][0][RTW89_ETSI][23] = 46, + [2][0][RTW89_MKK][23] = 70, + [2][0][RTW89_IC][23] = 70, + [2][0][RTW89_KCC][23] = 66, + [2][0][RTW89_ACMA][23] = 46, + [2][0][RTW89_CN][23] = 127, + [2][0][RTW89_UK][23] = 46, + [2][0][RTW89_FCC][25] = 70, + [2][0][RTW89_ETSI][25] = 46, + [2][0][RTW89_MKK][25] = 70, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_KCC][25] = 66, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_CN][25] = 127, + [2][0][RTW89_UK][25] = 46, + [2][0][RTW89_FCC][27] = 70, + [2][0][RTW89_ETSI][27] = 46, + [2][0][RTW89_MKK][27] = 70, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_KCC][27] = 64, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_CN][27] = 127, + [2][0][RTW89_UK][27] = 46, + [2][0][RTW89_FCC][29] = 70, + [2][0][RTW89_ETSI][29] = 46, + [2][0][RTW89_MKK][29] = 70, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_KCC][29] = 64, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_CN][29] = 127, + [2][0][RTW89_UK][29] = 46, + [2][0][RTW89_FCC][31] = 70, + [2][0][RTW89_ETSI][31] = 46, + [2][0][RTW89_MKK][31] = 70, + [2][0][RTW89_IC][31] = 70, + [2][0][RTW89_KCC][31] = 64, + [2][0][RTW89_ACMA][31] = 46, + [2][0][RTW89_CN][31] = 127, + [2][0][RTW89_UK][31] = 46, + [2][0][RTW89_FCC][33] = 70, + [2][0][RTW89_ETSI][33] = 46, + [2][0][RTW89_MKK][33] = 70, + [2][0][RTW89_IC][33] = 70, + [2][0][RTW89_KCC][33] = 64, + [2][0][RTW89_ACMA][33] = 46, + [2][0][RTW89_CN][33] = 127, + [2][0][RTW89_UK][33] = 46, + [2][0][RTW89_FCC][35] = 70, + [2][0][RTW89_ETSI][35] = 46, + [2][0][RTW89_MKK][35] = 70, + [2][0][RTW89_IC][35] = 70, + [2][0][RTW89_KCC][35] = 64, + [2][0][RTW89_ACMA][35] = 46, + [2][0][RTW89_CN][35] = 127, + [2][0][RTW89_UK][35] = 46, + [2][0][RTW89_FCC][37] = 84, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 68, + [2][0][RTW89_IC][37] = 84, + [2][0][RTW89_KCC][37] = 66, + [2][0][RTW89_ACMA][37] = 74, + [2][0][RTW89_CN][37] = 127, + [2][0][RTW89_UK][37] = 74, + [2][0][RTW89_FCC][38] = 84, + [2][0][RTW89_ETSI][38] = 28, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 84, + [2][0][RTW89_KCC][38] = 64, + [2][0][RTW89_ACMA][38] = 84, + [2][0][RTW89_CN][38] = 68, + [2][0][RTW89_UK][38] = 46, + [2][0][RTW89_FCC][40] = 84, + [2][0][RTW89_ETSI][40] = 28, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 84, + [2][0][RTW89_KCC][40] = 64, + [2][0][RTW89_ACMA][40] = 84, + [2][0][RTW89_CN][40] = 68, + [2][0][RTW89_UK][40] = 46, + [2][0][RTW89_FCC][42] = 80, + [2][0][RTW89_ETSI][42] = 28, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 80, + [2][0][RTW89_KCC][42] = 66, + [2][0][RTW89_ACMA][42] = 84, + [2][0][RTW89_CN][42] = 68, + [2][0][RTW89_UK][42] = 46, + [2][0][RTW89_FCC][44] = 82, + [2][0][RTW89_ETSI][44] = 28, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 82, + [2][0][RTW89_KCC][44] = 66, + [2][0][RTW89_ACMA][44] = 84, + [2][0][RTW89_CN][44] = 68, + [2][0][RTW89_UK][44] = 46, + [2][0][RTW89_FCC][46] = 82, + [2][0][RTW89_ETSI][46] = 28, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 82, + [2][0][RTW89_KCC][46] = 66, + [2][0][RTW89_ACMA][46] = 84, + [2][0][RTW89_CN][46] = 68, + [2][0][RTW89_UK][46] = 46, + [2][0][RTW89_FCC][48] = 64, + [2][0][RTW89_ETSI][48] = 127, + [2][0][RTW89_MKK][48] = 127, + [2][0][RTW89_IC][48] = 64, + [2][0][RTW89_KCC][48] = 127, + [2][0][RTW89_ACMA][48] = 127, + [2][0][RTW89_CN][48] = 127, + [2][0][RTW89_UK][48] = 127, + [2][0][RTW89_FCC][50] = 64, + [2][0][RTW89_ETSI][50] = 127, + [2][0][RTW89_MKK][50] = 127, + [2][0][RTW89_IC][50] = 64, + [2][0][RTW89_KCC][50] = 127, + [2][0][RTW89_ACMA][50] = 127, + [2][0][RTW89_CN][50] = 127, + [2][0][RTW89_UK][50] = 127, + [2][0][RTW89_FCC][52] = 60, + [2][0][RTW89_ETSI][52] = 127, + [2][0][RTW89_MKK][52] = 127, + [2][0][RTW89_IC][52] = 60, + [2][0][RTW89_KCC][52] = 127, + [2][0][RTW89_ACMA][52] = 127, + [2][0][RTW89_CN][52] = 127, + [2][0][RTW89_UK][52] = 127, + [2][1][RTW89_FCC][0] = 127, + [2][1][RTW89_ETSI][0] = 127, + [2][1][RTW89_MKK][0] = 127, + [2][1][RTW89_IC][0] = 127, + [2][1][RTW89_KCC][0] = 127, + [2][1][RTW89_ACMA][0] = 127, + [2][1][RTW89_CN][0] = 127, + [2][1][RTW89_UK][0] = 127, + [2][1][RTW89_FCC][2] = 127, + [2][1][RTW89_ETSI][2] = 127, + [2][1][RTW89_MKK][2] = 127, + [2][1][RTW89_IC][2] = 127, + [2][1][RTW89_KCC][2] = 127, + [2][1][RTW89_ACMA][2] = 127, + [2][1][RTW89_CN][2] = 127, + [2][1][RTW89_UK][2] = 127, + [2][1][RTW89_FCC][4] = 127, + [2][1][RTW89_ETSI][4] = 127, + [2][1][RTW89_MKK][4] = 127, + [2][1][RTW89_IC][4] = 127, + [2][1][RTW89_KCC][4] = 127, + [2][1][RTW89_ACMA][4] = 127, + [2][1][RTW89_CN][4] = 127, + [2][1][RTW89_UK][4] = 127, + [2][1][RTW89_FCC][6] = 127, + [2][1][RTW89_ETSI][6] = 127, + [2][1][RTW89_MKK][6] = 127, + [2][1][RTW89_IC][6] = 127, + [2][1][RTW89_KCC][6] = 127, + [2][1][RTW89_ACMA][6] = 127, + [2][1][RTW89_CN][6] = 127, + [2][1][RTW89_UK][6] = 127, + [2][1][RTW89_FCC][8] = 127, + [2][1][RTW89_ETSI][8] = 127, + [2][1][RTW89_MKK][8] = 127, + [2][1][RTW89_IC][8] = 127, + [2][1][RTW89_KCC][8] = 127, + [2][1][RTW89_ACMA][8] = 127, + [2][1][RTW89_CN][8] = 127, + [2][1][RTW89_UK][8] = 127, + [2][1][RTW89_FCC][10] = 127, + [2][1][RTW89_ETSI][10] = 127, + [2][1][RTW89_MKK][10] = 127, + [2][1][RTW89_IC][10] = 127, + [2][1][RTW89_KCC][10] = 127, + [2][1][RTW89_ACMA][10] = 127, + [2][1][RTW89_CN][10] = 127, + [2][1][RTW89_UK][10] = 127, + [2][1][RTW89_FCC][12] = 127, + [2][1][RTW89_ETSI][12] = 127, + [2][1][RTW89_MKK][12] = 127, + [2][1][RTW89_IC][12] = 127, + [2][1][RTW89_KCC][12] = 127, + [2][1][RTW89_ACMA][12] = 127, + [2][1][RTW89_CN][12] = 127, + [2][1][RTW89_UK][12] = 127, + [2][1][RTW89_FCC][14] = 127, + [2][1][RTW89_ETSI][14] = 127, + [2][1][RTW89_MKK][14] = 127, + [2][1][RTW89_IC][14] = 127, + [2][1][RTW89_KCC][14] = 127, + [2][1][RTW89_ACMA][14] = 127, + [2][1][RTW89_CN][14] = 127, + [2][1][RTW89_UK][14] = 127, + [2][1][RTW89_FCC][15] = 127, + [2][1][RTW89_ETSI][15] = 127, + [2][1][RTW89_MKK][15] = 127, + [2][1][RTW89_IC][15] = 127, + [2][1][RTW89_KCC][15] = 127, + [2][1][RTW89_ACMA][15] = 127, + [2][1][RTW89_CN][15] = 127, + [2][1][RTW89_UK][15] = 127, + [2][1][RTW89_FCC][17] = 127, + [2][1][RTW89_ETSI][17] = 127, + [2][1][RTW89_MKK][17] = 127, + [2][1][RTW89_IC][17] = 127, + [2][1][RTW89_KCC][17] = 127, + [2][1][RTW89_ACMA][17] = 127, + [2][1][RTW89_CN][17] = 127, + [2][1][RTW89_UK][17] = 127, + [2][1][RTW89_FCC][19] = 127, + [2][1][RTW89_ETSI][19] = 127, + [2][1][RTW89_MKK][19] = 127, + [2][1][RTW89_IC][19] = 127, + [2][1][RTW89_KCC][19] = 127, + [2][1][RTW89_ACMA][19] = 127, + [2][1][RTW89_CN][19] = 127, + [2][1][RTW89_UK][19] = 127, + [2][1][RTW89_FCC][21] = 127, + [2][1][RTW89_ETSI][21] = 127, + [2][1][RTW89_MKK][21] = 127, + [2][1][RTW89_IC][21] = 127, + [2][1][RTW89_KCC][21] = 127, + [2][1][RTW89_ACMA][21] = 127, + [2][1][RTW89_CN][21] = 127, + [2][1][RTW89_UK][21] = 127, + [2][1][RTW89_FCC][23] = 127, + [2][1][RTW89_ETSI][23] = 127, + [2][1][RTW89_MKK][23] = 127, + [2][1][RTW89_IC][23] = 127, + [2][1][RTW89_KCC][23] = 127, + [2][1][RTW89_ACMA][23] = 127, + [2][1][RTW89_CN][23] = 127, + [2][1][RTW89_UK][23] = 127, + [2][1][RTW89_FCC][25] = 127, + [2][1][RTW89_ETSI][25] = 127, + [2][1][RTW89_MKK][25] = 127, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_KCC][25] = 127, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_CN][25] = 127, + [2][1][RTW89_UK][25] = 127, + [2][1][RTW89_FCC][27] = 127, + [2][1][RTW89_ETSI][27] = 127, + [2][1][RTW89_MKK][27] = 127, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_KCC][27] = 127, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_CN][27] = 127, + [2][1][RTW89_UK][27] = 127, + [2][1][RTW89_FCC][29] = 127, + [2][1][RTW89_ETSI][29] = 127, + [2][1][RTW89_MKK][29] = 127, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_KCC][29] = 127, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_CN][29] = 127, + [2][1][RTW89_UK][29] = 127, + [2][1][RTW89_FCC][31] = 127, + [2][1][RTW89_ETSI][31] = 127, + [2][1][RTW89_MKK][31] = 127, + [2][1][RTW89_IC][31] = 127, + [2][1][RTW89_KCC][31] = 127, + [2][1][RTW89_ACMA][31] = 127, + [2][1][RTW89_CN][31] = 127, + [2][1][RTW89_UK][31] = 127, + [2][1][RTW89_FCC][33] = 127, + [2][1][RTW89_ETSI][33] = 127, + [2][1][RTW89_MKK][33] = 127, + [2][1][RTW89_IC][33] = 127, + [2][1][RTW89_KCC][33] = 127, + [2][1][RTW89_ACMA][33] = 127, + [2][1][RTW89_CN][33] = 127, + [2][1][RTW89_UK][33] = 127, + [2][1][RTW89_FCC][35] = 127, + [2][1][RTW89_ETSI][35] = 127, + [2][1][RTW89_MKK][35] = 127, + [2][1][RTW89_IC][35] = 127, + [2][1][RTW89_KCC][35] = 127, + [2][1][RTW89_ACMA][35] = 127, + [2][1][RTW89_CN][35] = 127, + [2][1][RTW89_UK][35] = 127, + [2][1][RTW89_FCC][37] = 127, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 127, + [2][1][RTW89_IC][37] = 127, + [2][1][RTW89_KCC][37] = 127, + [2][1][RTW89_ACMA][37] = 127, + [2][1][RTW89_CN][37] = 127, + [2][1][RTW89_UK][37] = 127, + [2][1][RTW89_FCC][38] = 127, + [2][1][RTW89_ETSI][38] = 127, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 127, + [2][1][RTW89_KCC][38] = 127, + [2][1][RTW89_ACMA][38] = 127, + [2][1][RTW89_CN][38] = 127, + [2][1][RTW89_UK][38] = 127, + [2][1][RTW89_FCC][40] = 127, + [2][1][RTW89_ETSI][40] = 127, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 127, + [2][1][RTW89_KCC][40] = 127, + [2][1][RTW89_ACMA][40] = 127, + [2][1][RTW89_CN][40] = 127, + [2][1][RTW89_UK][40] = 127, + [2][1][RTW89_FCC][42] = 127, + [2][1][RTW89_ETSI][42] = 127, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 127, + [2][1][RTW89_KCC][42] = 127, + [2][1][RTW89_ACMA][42] = 127, + [2][1][RTW89_CN][42] = 127, + [2][1][RTW89_UK][42] = 127, + [2][1][RTW89_FCC][44] = 127, + [2][1][RTW89_ETSI][44] = 127, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 127, + [2][1][RTW89_KCC][44] = 127, + [2][1][RTW89_ACMA][44] = 127, + [2][1][RTW89_CN][44] = 127, + [2][1][RTW89_UK][44] = 127, + [2][1][RTW89_FCC][46] = 127, + [2][1][RTW89_ETSI][46] = 127, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 127, + [2][1][RTW89_KCC][46] = 127, + [2][1][RTW89_ACMA][46] = 127, + [2][1][RTW89_CN][46] = 127, + [2][1][RTW89_UK][46] = 127, + [2][1][RTW89_FCC][48] = 127, + [2][1][RTW89_ETSI][48] = 127, + [2][1][RTW89_MKK][48] = 127, + [2][1][RTW89_IC][48] = 127, + [2][1][RTW89_KCC][48] = 127, + [2][1][RTW89_ACMA][48] = 127, + [2][1][RTW89_CN][48] = 127, + [2][1][RTW89_UK][48] = 127, + [2][1][RTW89_FCC][50] = 127, + [2][1][RTW89_ETSI][50] = 127, + [2][1][RTW89_MKK][50] = 127, + [2][1][RTW89_IC][50] = 127, + [2][1][RTW89_KCC][50] = 127, + [2][1][RTW89_ACMA][50] = 127, + [2][1][RTW89_CN][50] = 127, + [2][1][RTW89_UK][50] = 127, + [2][1][RTW89_FCC][52] = 127, + [2][1][RTW89_ETSI][52] = 127, + [2][1][RTW89_MKK][52] = 127, + [2][1][RTW89_IC][52] = 127, + [2][1][RTW89_KCC][52] = 127, + [2][1][RTW89_ACMA][52] = 127, + [2][1][RTW89_CN][52] = 127, + [2][1][RTW89_UK][52] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_2g_type2[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 56, + [0][0][0][0][RTW89_WW][1] = 56, + [0][0][0][0][RTW89_WW][2] = 56, + [0][0][0][0][RTW89_WW][3] = 56, + [0][0][0][0][RTW89_WW][4] = 56, + [0][0][0][0][RTW89_WW][5] = 56, + [0][0][0][0][RTW89_WW][6] = 56, + [0][0][0][0][RTW89_WW][7] = 56, + [0][0][0][0][RTW89_WW][8] = 56, + [0][0][0][0][RTW89_WW][9] = 56, + [0][0][0][0][RTW89_WW][10] = 56, + [0][0][0][0][RTW89_WW][11] = 56, + [0][0][0][0][RTW89_WW][12] = 42, + [0][0][0][0][RTW89_WW][13] = 76, + [0][1][0][0][RTW89_WW][0] = 0, + [0][1][0][0][RTW89_WW][1] = 0, + [0][1][0][0][RTW89_WW][2] = 0, + [0][1][0][0][RTW89_WW][3] = 0, + [0][1][0][0][RTW89_WW][4] = 0, + [0][1][0][0][RTW89_WW][5] = 0, + [0][1][0][0][RTW89_WW][6] = 0, + [0][1][0][0][RTW89_WW][7] = 0, + [0][1][0][0][RTW89_WW][8] = 0, + [0][1][0][0][RTW89_WW][9] = 0, + [0][1][0][0][RTW89_WW][10] = 0, + [0][1][0][0][RTW89_WW][11] = 0, + [0][1][0][0][RTW89_WW][12] = 0, + [0][1][0][0][RTW89_WW][13] = 0, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 56, + [1][0][0][0][RTW89_WW][3] = 56, + [1][0][0][0][RTW89_WW][4] = 56, + [1][0][0][0][RTW89_WW][5] = 56, + [1][0][0][0][RTW89_WW][6] = 56, + [1][0][0][0][RTW89_WW][7] = 56, + [1][0][0][0][RTW89_WW][8] = 56, + [1][0][0][0][RTW89_WW][9] = 56, + [1][0][0][0][RTW89_WW][10] = 42, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 0, + [1][1][0][0][RTW89_WW][3] = 0, + [1][1][0][0][RTW89_WW][4] = 0, + [1][1][0][0][RTW89_WW][5] = 0, + [1][1][0][0][RTW89_WW][6] = 0, + [1][1][0][0][RTW89_WW][7] = 0, + [1][1][0][0][RTW89_WW][8] = 0, + [1][1][0][0][RTW89_WW][9] = 0, + [1][1][0][0][RTW89_WW][10] = 0, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][1] = 60, + [0][0][1][0][RTW89_WW][2] = 60, + [0][0][1][0][RTW89_WW][3] = 60, + [0][0][1][0][RTW89_WW][4] = 60, + [0][0][1][0][RTW89_WW][5] = 60, + [0][0][1][0][RTW89_WW][6] = 60, + [0][0][1][0][RTW89_WW][7] = 60, + [0][0][1][0][RTW89_WW][8] = 60, + [0][0][1][0][RTW89_WW][9] = 60, + [0][0][1][0][RTW89_WW][10] = 60, + [0][0][1][0][RTW89_WW][11] = 60, + [0][0][1][0][RTW89_WW][12] = 40, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 0, + [0][1][1][0][RTW89_WW][1] = 0, + [0][1][1][0][RTW89_WW][2] = 0, + [0][1][1][0][RTW89_WW][3] = 0, + [0][1][1][0][RTW89_WW][4] = 0, + [0][1][1][0][RTW89_WW][5] = 0, + [0][1][1][0][RTW89_WW][6] = 0, + [0][1][1][0][RTW89_WW][7] = 0, + [0][1][1][0][RTW89_WW][8] = 0, + [0][1][1][0][RTW89_WW][9] = 0, + [0][1][1][0][RTW89_WW][10] = 0, + [0][1][1][0][RTW89_WW][11] = 0, + [0][1][1][0][RTW89_WW][12] = 0, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 58, + [0][0][2][0][RTW89_WW][1] = 58, + [0][0][2][0][RTW89_WW][2] = 58, + [0][0][2][0][RTW89_WW][3] = 58, + [0][0][2][0][RTW89_WW][4] = 58, + [0][0][2][0][RTW89_WW][5] = 58, + [0][0][2][0][RTW89_WW][6] = 58, + [0][0][2][0][RTW89_WW][7] = 58, + [0][0][2][0][RTW89_WW][8] = 58, + [0][0][2][0][RTW89_WW][9] = 58, + [0][0][2][0][RTW89_WW][10] = 58, + [0][0][2][0][RTW89_WW][11] = 58, + [0][0][2][0][RTW89_WW][12] = 38, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 0, + [0][1][2][0][RTW89_WW][1] = 0, + [0][1][2][0][RTW89_WW][2] = 0, + [0][1][2][0][RTW89_WW][3] = 0, + [0][1][2][0][RTW89_WW][4] = 0, + [0][1][2][0][RTW89_WW][5] = 0, + [0][1][2][0][RTW89_WW][6] = 0, + [0][1][2][0][RTW89_WW][7] = 0, + [0][1][2][0][RTW89_WW][8] = 0, + [0][1][2][0][RTW89_WW][9] = 0, + [0][1][2][0][RTW89_WW][10] = 0, + [0][1][2][0][RTW89_WW][11] = 0, + [0][1][2][0][RTW89_WW][12] = 0, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 0, + [0][1][2][1][RTW89_WW][1] = 0, + [0][1][2][1][RTW89_WW][2] = 0, + [0][1][2][1][RTW89_WW][3] = 0, + [0][1][2][1][RTW89_WW][4] = 0, + [0][1][2][1][RTW89_WW][5] = 0, + [0][1][2][1][RTW89_WW][6] = 0, + [0][1][2][1][RTW89_WW][7] = 0, + [0][1][2][1][RTW89_WW][8] = 0, + [0][1][2][1][RTW89_WW][9] = 0, + [0][1][2][1][RTW89_WW][10] = 0, + [0][1][2][1][RTW89_WW][11] = 0, + [0][1][2][1][RTW89_WW][12] = 0, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 56, + [1][0][2][0][RTW89_WW][3] = 56, + [1][0][2][0][RTW89_WW][4] = 56, + [1][0][2][0][RTW89_WW][5] = 56, + [1][0][2][0][RTW89_WW][6] = 56, + [1][0][2][0][RTW89_WW][7] = 56, + [1][0][2][0][RTW89_WW][8] = 56, + [1][0][2][0][RTW89_WW][9] = 56, + [1][0][2][0][RTW89_WW][10] = 48, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 0, + [1][1][2][0][RTW89_WW][3] = 0, + [1][1][2][0][RTW89_WW][4] = 0, + [1][1][2][0][RTW89_WW][5] = 0, + [1][1][2][0][RTW89_WW][6] = 0, + [1][1][2][0][RTW89_WW][7] = 0, + [1][1][2][0][RTW89_WW][8] = 0, + [1][1][2][0][RTW89_WW][9] = 0, + [1][1][2][0][RTW89_WW][10] = 0, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 0, + [1][1][2][1][RTW89_WW][3] = 0, + [1][1][2][1][RTW89_WW][4] = 0, + [1][1][2][1][RTW89_WW][5] = 0, + [1][1][2][1][RTW89_WW][6] = 0, + [1][1][2][1][RTW89_WW][7] = 0, + [1][1][2][1][RTW89_WW][8] = 0, + [1][1][2][1][RTW89_WW][9] = 0, + [1][1][2][1][RTW89_WW][10] = 0, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 82, + [0][0][0][0][RTW89_ETSI][0] = 58, + [0][0][0][0][RTW89_MKK][0] = 68, + [0][0][0][0][RTW89_IC][0] = 82, + [0][0][0][0][RTW89_KCC][0] = 68, + [0][0][0][0][RTW89_ACMA][0] = 58, + [0][0][0][0][RTW89_CN][0] = 56, + [0][0][0][0][RTW89_UK][0] = 58, + [0][0][0][0][RTW89_FCC][1] = 82, + [0][0][0][0][RTW89_ETSI][1] = 58, + [0][0][0][0][RTW89_MKK][1] = 68, + [0][0][0][0][RTW89_IC][1] = 82, + [0][0][0][0][RTW89_KCC][1] = 68, + [0][0][0][0][RTW89_ACMA][1] = 58, + [0][0][0][0][RTW89_CN][1] = 56, + [0][0][0][0][RTW89_UK][1] = 58, + [0][0][0][0][RTW89_FCC][2] = 82, + [0][0][0][0][RTW89_ETSI][2] = 58, + [0][0][0][0][RTW89_MKK][2] = 68, + [0][0][0][0][RTW89_IC][2] = 82, + [0][0][0][0][RTW89_KCC][2] = 68, + [0][0][0][0][RTW89_ACMA][2] = 58, + [0][0][0][0][RTW89_CN][2] = 56, + [0][0][0][0][RTW89_UK][2] = 58, + [0][0][0][0][RTW89_FCC][3] = 82, + [0][0][0][0][RTW89_ETSI][3] = 58, + [0][0][0][0][RTW89_MKK][3] = 68, + [0][0][0][0][RTW89_IC][3] = 82, + [0][0][0][0][RTW89_KCC][3] = 68, + [0][0][0][0][RTW89_ACMA][3] = 58, + [0][0][0][0][RTW89_CN][3] = 56, + [0][0][0][0][RTW89_UK][3] = 58, + [0][0][0][0][RTW89_FCC][4] = 82, + [0][0][0][0][RTW89_ETSI][4] = 58, + [0][0][0][0][RTW89_MKK][4] = 68, + [0][0][0][0][RTW89_IC][4] = 82, + [0][0][0][0][RTW89_KCC][4] = 68, + [0][0][0][0][RTW89_ACMA][4] = 58, + [0][0][0][0][RTW89_CN][4] = 56, + [0][0][0][0][RTW89_UK][4] = 58, + [0][0][0][0][RTW89_FCC][5] = 82, + [0][0][0][0][RTW89_ETSI][5] = 58, + [0][0][0][0][RTW89_MKK][5] = 68, + [0][0][0][0][RTW89_IC][5] = 82, + [0][0][0][0][RTW89_KCC][5] = 68, + [0][0][0][0][RTW89_ACMA][5] = 58, + [0][0][0][0][RTW89_CN][5] = 56, + [0][0][0][0][RTW89_UK][5] = 58, + [0][0][0][0][RTW89_FCC][6] = 82, + [0][0][0][0][RTW89_ETSI][6] = 58, + [0][0][0][0][RTW89_MKK][6] = 68, + [0][0][0][0][RTW89_IC][6] = 82, + [0][0][0][0][RTW89_KCC][6] = 68, + [0][0][0][0][RTW89_ACMA][6] = 58, + [0][0][0][0][RTW89_CN][6] = 56, + [0][0][0][0][RTW89_UK][6] = 58, + [0][0][0][0][RTW89_FCC][7] = 82, + [0][0][0][0][RTW89_ETSI][7] = 58, + [0][0][0][0][RTW89_MKK][7] = 68, + [0][0][0][0][RTW89_IC][7] = 82, + [0][0][0][0][RTW89_KCC][7] = 68, + [0][0][0][0][RTW89_ACMA][7] = 58, + [0][0][0][0][RTW89_CN][7] = 56, + [0][0][0][0][RTW89_UK][7] = 58, + [0][0][0][0][RTW89_FCC][8] = 82, + [0][0][0][0][RTW89_ETSI][8] = 58, + [0][0][0][0][RTW89_MKK][8] = 68, + [0][0][0][0][RTW89_IC][8] = 82, + [0][0][0][0][RTW89_KCC][8] = 68, + [0][0][0][0][RTW89_ACMA][8] = 58, + [0][0][0][0][RTW89_CN][8] = 56, + [0][0][0][0][RTW89_UK][8] = 58, + [0][0][0][0][RTW89_FCC][9] = 82, + [0][0][0][0][RTW89_ETSI][9] = 58, + [0][0][0][0][RTW89_MKK][9] = 68, + [0][0][0][0][RTW89_IC][9] = 82, + [0][0][0][0][RTW89_KCC][9] = 68, + [0][0][0][0][RTW89_ACMA][9] = 58, + [0][0][0][0][RTW89_CN][9] = 56, + [0][0][0][0][RTW89_UK][9] = 58, + [0][0][0][0][RTW89_FCC][10] = 80, + [0][0][0][0][RTW89_ETSI][10] = 58, + [0][0][0][0][RTW89_MKK][10] = 68, + [0][0][0][0][RTW89_IC][10] = 80, + [0][0][0][0][RTW89_KCC][10] = 68, + [0][0][0][0][RTW89_ACMA][10] = 58, + [0][0][0][0][RTW89_CN][10] = 56, + [0][0][0][0][RTW89_UK][10] = 58, + [0][0][0][0][RTW89_FCC][11] = 60, + [0][0][0][0][RTW89_ETSI][11] = 58, + [0][0][0][0][RTW89_MKK][11] = 68, + [0][0][0][0][RTW89_IC][11] = 60, + [0][0][0][0][RTW89_KCC][11] = 68, + [0][0][0][0][RTW89_ACMA][11] = 58, + [0][0][0][0][RTW89_CN][11] = 56, + [0][0][0][0][RTW89_UK][11] = 58, + [0][0][0][0][RTW89_FCC][12] = 52, + [0][0][0][0][RTW89_ETSI][12] = 58, + [0][0][0][0][RTW89_MKK][12] = 68, + [0][0][0][0][RTW89_IC][12] = 52, + [0][0][0][0][RTW89_KCC][12] = 68, + [0][0][0][0][RTW89_ACMA][12] = 58, + [0][0][0][0][RTW89_CN][12] = 42, + [0][0][0][0][RTW89_UK][12] = 58, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 76, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_KCC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][0][0][0][RTW89_CN][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 127, + [0][1][0][0][RTW89_ETSI][0] = 127, + [0][1][0][0][RTW89_MKK][0] = 127, + [0][1][0][0][RTW89_IC][0] = 127, + [0][1][0][0][RTW89_KCC][0] = 127, + [0][1][0][0][RTW89_ACMA][0] = 127, + [0][1][0][0][RTW89_CN][0] = 127, + [0][1][0][0][RTW89_UK][0] = 127, + [0][1][0][0][RTW89_FCC][1] = 127, + [0][1][0][0][RTW89_ETSI][1] = 127, + [0][1][0][0][RTW89_MKK][1] = 127, + [0][1][0][0][RTW89_IC][1] = 127, + [0][1][0][0][RTW89_KCC][1] = 127, + [0][1][0][0][RTW89_ACMA][1] = 127, + [0][1][0][0][RTW89_CN][1] = 127, + [0][1][0][0][RTW89_UK][1] = 127, + [0][1][0][0][RTW89_FCC][2] = 127, + [0][1][0][0][RTW89_ETSI][2] = 127, + [0][1][0][0][RTW89_MKK][2] = 127, + [0][1][0][0][RTW89_IC][2] = 127, + [0][1][0][0][RTW89_KCC][2] = 127, + [0][1][0][0][RTW89_ACMA][2] = 127, + [0][1][0][0][RTW89_CN][2] = 127, + [0][1][0][0][RTW89_UK][2] = 127, + [0][1][0][0][RTW89_FCC][3] = 127, + [0][1][0][0][RTW89_ETSI][3] = 127, + [0][1][0][0][RTW89_MKK][3] = 127, + [0][1][0][0][RTW89_IC][3] = 127, + [0][1][0][0][RTW89_KCC][3] = 127, + [0][1][0][0][RTW89_ACMA][3] = 127, + [0][1][0][0][RTW89_CN][3] = 127, + [0][1][0][0][RTW89_UK][3] = 127, + [0][1][0][0][RTW89_FCC][4] = 127, + [0][1][0][0][RTW89_ETSI][4] = 127, + [0][1][0][0][RTW89_MKK][4] = 127, + [0][1][0][0][RTW89_IC][4] = 127, + [0][1][0][0][RTW89_KCC][4] = 127, + [0][1][0][0][RTW89_ACMA][4] = 127, + [0][1][0][0][RTW89_CN][4] = 127, + [0][1][0][0][RTW89_UK][4] = 127, + [0][1][0][0][RTW89_FCC][5] = 127, + [0][1][0][0][RTW89_ETSI][5] = 127, + [0][1][0][0][RTW89_MKK][5] = 127, + [0][1][0][0][RTW89_IC][5] = 127, + [0][1][0][0][RTW89_KCC][5] = 127, + [0][1][0][0][RTW89_ACMA][5] = 127, + [0][1][0][0][RTW89_CN][5] = 127, + [0][1][0][0][RTW89_UK][5] = 127, + [0][1][0][0][RTW89_FCC][6] = 127, + [0][1][0][0][RTW89_ETSI][6] = 127, + [0][1][0][0][RTW89_MKK][6] = 127, + [0][1][0][0][RTW89_IC][6] = 127, + [0][1][0][0][RTW89_KCC][6] = 127, + [0][1][0][0][RTW89_ACMA][6] = 127, + [0][1][0][0][RTW89_CN][6] = 127, + [0][1][0][0][RTW89_UK][6] = 127, + [0][1][0][0][RTW89_FCC][7] = 127, + [0][1][0][0][RTW89_ETSI][7] = 127, + [0][1][0][0][RTW89_MKK][7] = 127, + [0][1][0][0][RTW89_IC][7] = 127, + [0][1][0][0][RTW89_KCC][7] = 127, + [0][1][0][0][RTW89_ACMA][7] = 127, + [0][1][0][0][RTW89_CN][7] = 127, + [0][1][0][0][RTW89_UK][7] = 127, + [0][1][0][0][RTW89_FCC][8] = 127, + [0][1][0][0][RTW89_ETSI][8] = 127, + [0][1][0][0][RTW89_MKK][8] = 127, + [0][1][0][0][RTW89_IC][8] = 127, + [0][1][0][0][RTW89_KCC][8] = 127, + [0][1][0][0][RTW89_ACMA][8] = 127, + [0][1][0][0][RTW89_CN][8] = 127, + [0][1][0][0][RTW89_UK][8] = 127, + [0][1][0][0][RTW89_FCC][9] = 127, + [0][1][0][0][RTW89_ETSI][9] = 127, + [0][1][0][0][RTW89_MKK][9] = 127, + [0][1][0][0][RTW89_IC][9] = 127, + [0][1][0][0][RTW89_KCC][9] = 127, + [0][1][0][0][RTW89_ACMA][9] = 127, + [0][1][0][0][RTW89_CN][9] = 127, + [0][1][0][0][RTW89_UK][9] = 127, + [0][1][0][0][RTW89_FCC][10] = 127, + [0][1][0][0][RTW89_ETSI][10] = 127, + [0][1][0][0][RTW89_MKK][10] = 127, + [0][1][0][0][RTW89_IC][10] = 127, + [0][1][0][0][RTW89_KCC][10] = 127, + [0][1][0][0][RTW89_ACMA][10] = 127, + [0][1][0][0][RTW89_CN][10] = 127, + [0][1][0][0][RTW89_UK][10] = 127, + [0][1][0][0][RTW89_FCC][11] = 127, + [0][1][0][0][RTW89_ETSI][11] = 127, + [0][1][0][0][RTW89_MKK][11] = 127, + [0][1][0][0][RTW89_IC][11] = 127, + [0][1][0][0][RTW89_KCC][11] = 127, + [0][1][0][0][RTW89_ACMA][11] = 127, + [0][1][0][0][RTW89_CN][11] = 127, + [0][1][0][0][RTW89_UK][11] = 127, + [0][1][0][0][RTW89_FCC][12] = 127, + [0][1][0][0][RTW89_ETSI][12] = 127, + [0][1][0][0][RTW89_MKK][12] = 127, + [0][1][0][0][RTW89_IC][12] = 127, + [0][1][0][0][RTW89_KCC][12] = 127, + [0][1][0][0][RTW89_ACMA][12] = 127, + [0][1][0][0][RTW89_CN][12] = 127, + [0][1][0][0][RTW89_UK][12] = 127, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 127, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_KCC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_CN][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_KCC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_CN][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_KCC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_CN][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 127, + [1][0][0][0][RTW89_ETSI][2] = 58, + [1][0][0][0][RTW89_MKK][2] = 70, + [1][0][0][0][RTW89_IC][2] = 127, + [1][0][0][0][RTW89_KCC][2] = 68, + [1][0][0][0][RTW89_ACMA][2] = 58, + [1][0][0][0][RTW89_CN][2] = 56, + [1][0][0][0][RTW89_UK][2] = 58, + [1][0][0][0][RTW89_FCC][3] = 127, + [1][0][0][0][RTW89_ETSI][3] = 58, + [1][0][0][0][RTW89_MKK][3] = 76, + [1][0][0][0][RTW89_IC][3] = 127, + [1][0][0][0][RTW89_KCC][3] = 68, + [1][0][0][0][RTW89_ACMA][3] = 58, + [1][0][0][0][RTW89_CN][3] = 56, + [1][0][0][0][RTW89_UK][3] = 58, + [1][0][0][0][RTW89_FCC][4] = 127, + [1][0][0][0][RTW89_ETSI][4] = 58, + [1][0][0][0][RTW89_MKK][4] = 76, + [1][0][0][0][RTW89_IC][4] = 127, + [1][0][0][0][RTW89_KCC][4] = 68, + [1][0][0][0][RTW89_ACMA][4] = 58, + [1][0][0][0][RTW89_CN][4] = 56, + [1][0][0][0][RTW89_UK][4] = 58, + [1][0][0][0][RTW89_FCC][5] = 127, + [1][0][0][0][RTW89_ETSI][5] = 58, + [1][0][0][0][RTW89_MKK][5] = 76, + [1][0][0][0][RTW89_IC][5] = 127, + [1][0][0][0][RTW89_KCC][5] = 68, + [1][0][0][0][RTW89_ACMA][5] = 58, + [1][0][0][0][RTW89_CN][5] = 56, + [1][0][0][0][RTW89_UK][5] = 58, + [1][0][0][0][RTW89_FCC][6] = 127, + [1][0][0][0][RTW89_ETSI][6] = 58, + [1][0][0][0][RTW89_MKK][6] = 76, + [1][0][0][0][RTW89_IC][6] = 127, + [1][0][0][0][RTW89_KCC][6] = 68, + [1][0][0][0][RTW89_ACMA][6] = 58, + [1][0][0][0][RTW89_CN][6] = 56, + [1][0][0][0][RTW89_UK][6] = 58, + [1][0][0][0][RTW89_FCC][7] = 127, + [1][0][0][0][RTW89_ETSI][7] = 58, + [1][0][0][0][RTW89_MKK][7] = 76, + [1][0][0][0][RTW89_IC][7] = 127, + [1][0][0][0][RTW89_KCC][7] = 68, + [1][0][0][0][RTW89_ACMA][7] = 58, + [1][0][0][0][RTW89_CN][7] = 56, + [1][0][0][0][RTW89_UK][7] = 58, + [1][0][0][0][RTW89_FCC][8] = 127, + [1][0][0][0][RTW89_ETSI][8] = 58, + [1][0][0][0][RTW89_MKK][8] = 76, + [1][0][0][0][RTW89_IC][8] = 127, + [1][0][0][0][RTW89_KCC][8] = 68, + [1][0][0][0][RTW89_ACMA][8] = 58, + [1][0][0][0][RTW89_CN][8] = 56, + [1][0][0][0][RTW89_UK][8] = 58, + [1][0][0][0][RTW89_FCC][9] = 127, + [1][0][0][0][RTW89_ETSI][9] = 58, + [1][0][0][0][RTW89_MKK][9] = 76, + [1][0][0][0][RTW89_IC][9] = 127, + [1][0][0][0][RTW89_KCC][9] = 68, + [1][0][0][0][RTW89_ACMA][9] = 58, + [1][0][0][0][RTW89_CN][9] = 56, + [1][0][0][0][RTW89_UK][9] = 58, + [1][0][0][0][RTW89_FCC][10] = 127, + [1][0][0][0][RTW89_ETSI][10] = 58, + [1][0][0][0][RTW89_MKK][10] = 66, + [1][0][0][0][RTW89_IC][10] = 127, + [1][0][0][0][RTW89_KCC][10] = 68, + [1][0][0][0][RTW89_ACMA][10] = 58, + [1][0][0][0][RTW89_CN][10] = 42, + [1][0][0][0][RTW89_UK][10] = 58, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_KCC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_CN][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_KCC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_CN][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_KCC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_CN][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_KCC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_CN][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_KCC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_CN][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 127, + [1][1][0][0][RTW89_ETSI][2] = 127, + [1][1][0][0][RTW89_MKK][2] = 127, + [1][1][0][0][RTW89_IC][2] = 127, + [1][1][0][0][RTW89_KCC][2] = 127, + [1][1][0][0][RTW89_ACMA][2] = 127, + [1][1][0][0][RTW89_CN][2] = 127, + [1][1][0][0][RTW89_UK][2] = 127, + [1][1][0][0][RTW89_FCC][3] = 127, + [1][1][0][0][RTW89_ETSI][3] = 127, + [1][1][0][0][RTW89_MKK][3] = 127, + [1][1][0][0][RTW89_IC][3] = 127, + [1][1][0][0][RTW89_KCC][3] = 127, + [1][1][0][0][RTW89_ACMA][3] = 127, + [1][1][0][0][RTW89_CN][3] = 127, + [1][1][0][0][RTW89_UK][3] = 127, + [1][1][0][0][RTW89_FCC][4] = 127, + [1][1][0][0][RTW89_ETSI][4] = 127, + [1][1][0][0][RTW89_MKK][4] = 127, + [1][1][0][0][RTW89_IC][4] = 127, + [1][1][0][0][RTW89_KCC][4] = 127, + [1][1][0][0][RTW89_ACMA][4] = 127, + [1][1][0][0][RTW89_CN][4] = 127, + [1][1][0][0][RTW89_UK][4] = 127, + [1][1][0][0][RTW89_FCC][5] = 127, + [1][1][0][0][RTW89_ETSI][5] = 127, + [1][1][0][0][RTW89_MKK][5] = 127, + [1][1][0][0][RTW89_IC][5] = 127, + [1][1][0][0][RTW89_KCC][5] = 127, + [1][1][0][0][RTW89_ACMA][5] = 127, + [1][1][0][0][RTW89_CN][5] = 127, + [1][1][0][0][RTW89_UK][5] = 127, + [1][1][0][0][RTW89_FCC][6] = 127, + [1][1][0][0][RTW89_ETSI][6] = 127, + [1][1][0][0][RTW89_MKK][6] = 127, + [1][1][0][0][RTW89_IC][6] = 127, + [1][1][0][0][RTW89_KCC][6] = 127, + [1][1][0][0][RTW89_ACMA][6] = 127, + [1][1][0][0][RTW89_CN][6] = 127, + [1][1][0][0][RTW89_UK][6] = 127, + [1][1][0][0][RTW89_FCC][7] = 127, + [1][1][0][0][RTW89_ETSI][7] = 127, + [1][1][0][0][RTW89_MKK][7] = 127, + [1][1][0][0][RTW89_IC][7] = 127, + [1][1][0][0][RTW89_KCC][7] = 127, + [1][1][0][0][RTW89_ACMA][7] = 127, + [1][1][0][0][RTW89_CN][7] = 127, + [1][1][0][0][RTW89_UK][7] = 127, + [1][1][0][0][RTW89_FCC][8] = 127, + [1][1][0][0][RTW89_ETSI][8] = 127, + [1][1][0][0][RTW89_MKK][8] = 127, + [1][1][0][0][RTW89_IC][8] = 127, + [1][1][0][0][RTW89_KCC][8] = 127, + [1][1][0][0][RTW89_ACMA][8] = 127, + [1][1][0][0][RTW89_CN][8] = 127, + [1][1][0][0][RTW89_UK][8] = 127, + [1][1][0][0][RTW89_FCC][9] = 127, + [1][1][0][0][RTW89_ETSI][9] = 127, + [1][1][0][0][RTW89_MKK][9] = 127, + [1][1][0][0][RTW89_IC][9] = 127, + [1][1][0][0][RTW89_KCC][9] = 127, + [1][1][0][0][RTW89_ACMA][9] = 127, + [1][1][0][0][RTW89_CN][9] = 127, + [1][1][0][0][RTW89_UK][9] = 127, + [1][1][0][0][RTW89_FCC][10] = 127, + [1][1][0][0][RTW89_ETSI][10] = 127, + [1][1][0][0][RTW89_MKK][10] = 127, + [1][1][0][0][RTW89_IC][10] = 127, + [1][1][0][0][RTW89_KCC][10] = 127, + [1][1][0][0][RTW89_ACMA][10] = 127, + [1][1][0][0][RTW89_CN][10] = 127, + [1][1][0][0][RTW89_UK][10] = 127, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_KCC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_CN][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_KCC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_CN][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_KCC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_CN][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 78, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 72, + [0][0][1][0][RTW89_IC][0] = 78, + [0][0][1][0][RTW89_KCC][0] = 76, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CN][0] = 60, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][1] = 78, + [0][0][1][0][RTW89_ETSI][1] = 60, + [0][0][1][0][RTW89_MKK][1] = 74, + [0][0][1][0][RTW89_IC][1] = 78, + [0][0][1][0][RTW89_KCC][1] = 76, + [0][0][1][0][RTW89_ACMA][1] = 60, + [0][0][1][0][RTW89_CN][1] = 60, + [0][0][1][0][RTW89_UK][1] = 60, + [0][0][1][0][RTW89_FCC][2] = 80, + [0][0][1][0][RTW89_ETSI][2] = 60, + [0][0][1][0][RTW89_MKK][2] = 74, + [0][0][1][0][RTW89_IC][2] = 80, + [0][0][1][0][RTW89_KCC][2] = 76, + [0][0][1][0][RTW89_ACMA][2] = 60, + [0][0][1][0][RTW89_CN][2] = 60, + [0][0][1][0][RTW89_UK][2] = 60, + [0][0][1][0][RTW89_FCC][3] = 80, + [0][0][1][0][RTW89_ETSI][3] = 60, + [0][0][1][0][RTW89_MKK][3] = 74, + [0][0][1][0][RTW89_IC][3] = 80, + [0][0][1][0][RTW89_KCC][3] = 76, + [0][0][1][0][RTW89_ACMA][3] = 60, + [0][0][1][0][RTW89_CN][3] = 60, + [0][0][1][0][RTW89_UK][3] = 60, + [0][0][1][0][RTW89_FCC][4] = 80, + [0][0][1][0][RTW89_ETSI][4] = 60, + [0][0][1][0][RTW89_MKK][4] = 74, + [0][0][1][0][RTW89_IC][4] = 80, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 60, + [0][0][1][0][RTW89_CN][4] = 60, + [0][0][1][0][RTW89_UK][4] = 60, + [0][0][1][0][RTW89_FCC][5] = 80, + [0][0][1][0][RTW89_ETSI][5] = 60, + [0][0][1][0][RTW89_MKK][5] = 74, + [0][0][1][0][RTW89_IC][5] = 80, + [0][0][1][0][RTW89_KCC][5] = 76, + [0][0][1][0][RTW89_ACMA][5] = 60, + [0][0][1][0][RTW89_CN][5] = 60, + [0][0][1][0][RTW89_UK][5] = 60, + [0][0][1][0][RTW89_FCC][6] = 80, + [0][0][1][0][RTW89_ETSI][6] = 60, + [0][0][1][0][RTW89_MKK][6] = 74, + [0][0][1][0][RTW89_IC][6] = 80, + [0][0][1][0][RTW89_KCC][6] = 76, + [0][0][1][0][RTW89_ACMA][6] = 60, + [0][0][1][0][RTW89_CN][6] = 60, + [0][0][1][0][RTW89_UK][6] = 60, + [0][0][1][0][RTW89_FCC][7] = 80, + [0][0][1][0][RTW89_ETSI][7] = 60, + [0][0][1][0][RTW89_MKK][7] = 74, + [0][0][1][0][RTW89_IC][7] = 80, + [0][0][1][0][RTW89_KCC][7] = 76, + [0][0][1][0][RTW89_ACMA][7] = 60, + [0][0][1][0][RTW89_CN][7] = 60, + [0][0][1][0][RTW89_UK][7] = 60, + [0][0][1][0][RTW89_FCC][8] = 80, + [0][0][1][0][RTW89_ETSI][8] = 60, + [0][0][1][0][RTW89_MKK][8] = 74, + [0][0][1][0][RTW89_IC][8] = 80, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 60, + [0][0][1][0][RTW89_CN][8] = 60, + [0][0][1][0][RTW89_UK][8] = 60, + [0][0][1][0][RTW89_FCC][9] = 76, + [0][0][1][0][RTW89_ETSI][9] = 60, + [0][0][1][0][RTW89_MKK][9] = 74, + [0][0][1][0][RTW89_IC][9] = 76, + [0][0][1][0][RTW89_KCC][9] = 74, + [0][0][1][0][RTW89_ACMA][9] = 60, + [0][0][1][0][RTW89_CN][9] = 60, + [0][0][1][0][RTW89_UK][9] = 60, + [0][0][1][0][RTW89_FCC][10] = 76, + [0][0][1][0][RTW89_ETSI][10] = 60, + [0][0][1][0][RTW89_MKK][10] = 74, + [0][0][1][0][RTW89_IC][10] = 76, + [0][0][1][0][RTW89_KCC][10] = 74, + [0][0][1][0][RTW89_ACMA][10] = 60, + [0][0][1][0][RTW89_CN][10] = 60, + [0][0][1][0][RTW89_UK][10] = 60, + [0][0][1][0][RTW89_FCC][11] = 68, + [0][0][1][0][RTW89_ETSI][11] = 60, + [0][0][1][0][RTW89_MKK][11] = 74, + [0][0][1][0][RTW89_IC][11] = 68, + [0][0][1][0][RTW89_KCC][11] = 74, + [0][0][1][0][RTW89_ACMA][11] = 60, + [0][0][1][0][RTW89_CN][11] = 60, + [0][0][1][0][RTW89_UK][11] = 60, + [0][0][1][0][RTW89_FCC][12] = 64, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 70, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 74, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CN][12] = 40, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_KCC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_CN][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 127, + [0][1][1][0][RTW89_ETSI][0] = 127, + [0][1][1][0][RTW89_MKK][0] = 127, + [0][1][1][0][RTW89_IC][0] = 127, + [0][1][1][0][RTW89_KCC][0] = 127, + [0][1][1][0][RTW89_ACMA][0] = 127, + [0][1][1][0][RTW89_CN][0] = 127, + [0][1][1][0][RTW89_UK][0] = 127, + [0][1][1][0][RTW89_FCC][1] = 127, + [0][1][1][0][RTW89_ETSI][1] = 127, + [0][1][1][0][RTW89_MKK][1] = 127, + [0][1][1][0][RTW89_IC][1] = 127, + [0][1][1][0][RTW89_KCC][1] = 127, + [0][1][1][0][RTW89_ACMA][1] = 127, + [0][1][1][0][RTW89_CN][1] = 127, + [0][1][1][0][RTW89_UK][1] = 127, + [0][1][1][0][RTW89_FCC][2] = 127, + [0][1][1][0][RTW89_ETSI][2] = 127, + [0][1][1][0][RTW89_MKK][2] = 127, + [0][1][1][0][RTW89_IC][2] = 127, + [0][1][1][0][RTW89_KCC][2] = 127, + [0][1][1][0][RTW89_ACMA][2] = 127, + [0][1][1][0][RTW89_CN][2] = 127, + [0][1][1][0][RTW89_UK][2] = 127, + [0][1][1][0][RTW89_FCC][3] = 127, + [0][1][1][0][RTW89_ETSI][3] = 127, + [0][1][1][0][RTW89_MKK][3] = 127, + [0][1][1][0][RTW89_IC][3] = 127, + [0][1][1][0][RTW89_KCC][3] = 127, + [0][1][1][0][RTW89_ACMA][3] = 127, + [0][1][1][0][RTW89_CN][3] = 127, + [0][1][1][0][RTW89_UK][3] = 127, + [0][1][1][0][RTW89_FCC][4] = 127, + [0][1][1][0][RTW89_ETSI][4] = 127, + [0][1][1][0][RTW89_MKK][4] = 127, + [0][1][1][0][RTW89_IC][4] = 127, + [0][1][1][0][RTW89_KCC][4] = 127, + [0][1][1][0][RTW89_ACMA][4] = 127, + [0][1][1][0][RTW89_CN][4] = 127, + [0][1][1][0][RTW89_UK][4] = 127, + [0][1][1][0][RTW89_FCC][5] = 127, + [0][1][1][0][RTW89_ETSI][5] = 127, + [0][1][1][0][RTW89_MKK][5] = 127, + [0][1][1][0][RTW89_IC][5] = 127, + [0][1][1][0][RTW89_KCC][5] = 127, + [0][1][1][0][RTW89_ACMA][5] = 127, + [0][1][1][0][RTW89_CN][5] = 127, + [0][1][1][0][RTW89_UK][5] = 127, + [0][1][1][0][RTW89_FCC][6] = 127, + [0][1][1][0][RTW89_ETSI][6] = 127, + [0][1][1][0][RTW89_MKK][6] = 127, + [0][1][1][0][RTW89_IC][6] = 127, + [0][1][1][0][RTW89_KCC][6] = 127, + [0][1][1][0][RTW89_ACMA][6] = 127, + [0][1][1][0][RTW89_CN][6] = 127, + [0][1][1][0][RTW89_UK][6] = 127, + [0][1][1][0][RTW89_FCC][7] = 127, + [0][1][1][0][RTW89_ETSI][7] = 127, + [0][1][1][0][RTW89_MKK][7] = 127, + [0][1][1][0][RTW89_IC][7] = 127, + [0][1][1][0][RTW89_KCC][7] = 127, + [0][1][1][0][RTW89_ACMA][7] = 127, + [0][1][1][0][RTW89_CN][7] = 127, + [0][1][1][0][RTW89_UK][7] = 127, + [0][1][1][0][RTW89_FCC][8] = 127, + [0][1][1][0][RTW89_ETSI][8] = 127, + [0][1][1][0][RTW89_MKK][8] = 127, + [0][1][1][0][RTW89_IC][8] = 127, + [0][1][1][0][RTW89_KCC][8] = 127, + [0][1][1][0][RTW89_ACMA][8] = 127, + [0][1][1][0][RTW89_CN][8] = 127, + [0][1][1][0][RTW89_UK][8] = 127, + [0][1][1][0][RTW89_FCC][9] = 127, + [0][1][1][0][RTW89_ETSI][9] = 127, + [0][1][1][0][RTW89_MKK][9] = 127, + [0][1][1][0][RTW89_IC][9] = 127, + [0][1][1][0][RTW89_KCC][9] = 127, + [0][1][1][0][RTW89_ACMA][9] = 127, + [0][1][1][0][RTW89_CN][9] = 127, + [0][1][1][0][RTW89_UK][9] = 127, + [0][1][1][0][RTW89_FCC][10] = 127, + [0][1][1][0][RTW89_ETSI][10] = 127, + [0][1][1][0][RTW89_MKK][10] = 127, + [0][1][1][0][RTW89_IC][10] = 127, + [0][1][1][0][RTW89_KCC][10] = 127, + [0][1][1][0][RTW89_ACMA][10] = 127, + [0][1][1][0][RTW89_CN][10] = 127, + [0][1][1][0][RTW89_UK][10] = 127, + [0][1][1][0][RTW89_FCC][11] = 127, + [0][1][1][0][RTW89_ETSI][11] = 127, + [0][1][1][0][RTW89_MKK][11] = 127, + [0][1][1][0][RTW89_IC][11] = 127, + [0][1][1][0][RTW89_KCC][11] = 127, + [0][1][1][0][RTW89_ACMA][11] = 127, + [0][1][1][0][RTW89_CN][11] = 127, + [0][1][1][0][RTW89_UK][11] = 127, + [0][1][1][0][RTW89_FCC][12] = 127, + [0][1][1][0][RTW89_ETSI][12] = 127, + [0][1][1][0][RTW89_MKK][12] = 127, + [0][1][1][0][RTW89_IC][12] = 127, + [0][1][1][0][RTW89_KCC][12] = 127, + [0][1][1][0][RTW89_ACMA][12] = 127, + [0][1][1][0][RTW89_CN][12] = 127, + [0][1][1][0][RTW89_UK][12] = 127, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_KCC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_CN][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 78, + [0][0][2][0][RTW89_ETSI][0] = 60, + [0][0][2][0][RTW89_MKK][0] = 72, + [0][0][2][0][RTW89_IC][0] = 78, + [0][0][2][0][RTW89_KCC][0] = 76, + [0][0][2][0][RTW89_ACMA][0] = 60, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_UK][0] = 60, + [0][0][2][0][RTW89_FCC][1] = 78, + [0][0][2][0][RTW89_ETSI][1] = 60, + [0][0][2][0][RTW89_MKK][1] = 76, + [0][0][2][0][RTW89_IC][1] = 78, + [0][0][2][0][RTW89_KCC][1] = 76, + [0][0][2][0][RTW89_ACMA][1] = 60, + [0][0][2][0][RTW89_CN][1] = 58, + [0][0][2][0][RTW89_UK][1] = 60, + [0][0][2][0][RTW89_FCC][2] = 80, + [0][0][2][0][RTW89_ETSI][2] = 60, + [0][0][2][0][RTW89_MKK][2] = 76, + [0][0][2][0][RTW89_IC][2] = 80, + [0][0][2][0][RTW89_KCC][2] = 76, + [0][0][2][0][RTW89_ACMA][2] = 60, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_UK][2] = 60, + [0][0][2][0][RTW89_FCC][3] = 80, + [0][0][2][0][RTW89_ETSI][3] = 60, + [0][0][2][0][RTW89_MKK][3] = 76, + [0][0][2][0][RTW89_IC][3] = 80, + [0][0][2][0][RTW89_KCC][3] = 76, + [0][0][2][0][RTW89_ACMA][3] = 60, + [0][0][2][0][RTW89_CN][3] = 58, + [0][0][2][0][RTW89_UK][3] = 60, + [0][0][2][0][RTW89_FCC][4] = 80, + [0][0][2][0][RTW89_ETSI][4] = 60, + [0][0][2][0][RTW89_MKK][4] = 76, + [0][0][2][0][RTW89_IC][4] = 80, + [0][0][2][0][RTW89_KCC][4] = 76, + [0][0][2][0][RTW89_ACMA][4] = 60, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_UK][4] = 60, + [0][0][2][0][RTW89_FCC][5] = 80, + [0][0][2][0][RTW89_ETSI][5] = 60, + [0][0][2][0][RTW89_MKK][5] = 76, + [0][0][2][0][RTW89_IC][5] = 80, + [0][0][2][0][RTW89_KCC][5] = 76, + [0][0][2][0][RTW89_ACMA][5] = 60, + [0][0][2][0][RTW89_CN][5] = 58, + [0][0][2][0][RTW89_UK][5] = 60, + [0][0][2][0][RTW89_FCC][6] = 80, + [0][0][2][0][RTW89_ETSI][6] = 60, + [0][0][2][0][RTW89_MKK][6] = 76, + [0][0][2][0][RTW89_IC][6] = 80, + [0][0][2][0][RTW89_KCC][6] = 76, + [0][0][2][0][RTW89_ACMA][6] = 60, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_UK][6] = 60, + [0][0][2][0][RTW89_FCC][7] = 80, + [0][0][2][0][RTW89_ETSI][7] = 60, + [0][0][2][0][RTW89_MKK][7] = 76, + [0][0][2][0][RTW89_IC][7] = 80, + [0][0][2][0][RTW89_KCC][7] = 76, + [0][0][2][0][RTW89_ACMA][7] = 60, + [0][0][2][0][RTW89_CN][7] = 58, + [0][0][2][0][RTW89_UK][7] = 60, + [0][0][2][0][RTW89_FCC][8] = 78, + [0][0][2][0][RTW89_ETSI][8] = 60, + [0][0][2][0][RTW89_MKK][8] = 76, + [0][0][2][0][RTW89_IC][8] = 78, + [0][0][2][0][RTW89_KCC][8] = 76, + [0][0][2][0][RTW89_ACMA][8] = 60, + [0][0][2][0][RTW89_CN][8] = 58, + [0][0][2][0][RTW89_UK][8] = 60, + [0][0][2][0][RTW89_FCC][9] = 74, + [0][0][2][0][RTW89_ETSI][9] = 60, + [0][0][2][0][RTW89_MKK][9] = 76, + [0][0][2][0][RTW89_IC][9] = 74, + [0][0][2][0][RTW89_KCC][9] = 76, + [0][0][2][0][RTW89_ACMA][9] = 60, + [0][0][2][0][RTW89_CN][9] = 58, + [0][0][2][0][RTW89_UK][9] = 60, + [0][0][2][0][RTW89_FCC][10] = 74, + [0][0][2][0][RTW89_ETSI][10] = 60, + [0][0][2][0][RTW89_MKK][10] = 76, + [0][0][2][0][RTW89_IC][10] = 74, + [0][0][2][0][RTW89_KCC][10] = 76, + [0][0][2][0][RTW89_ACMA][10] = 60, + [0][0][2][0][RTW89_CN][10] = 58, + [0][0][2][0][RTW89_UK][10] = 60, + [0][0][2][0][RTW89_FCC][11] = 68, + [0][0][2][0][RTW89_ETSI][11] = 60, + [0][0][2][0][RTW89_MKK][11] = 76, + [0][0][2][0][RTW89_IC][11] = 68, + [0][0][2][0][RTW89_KCC][11] = 76, + [0][0][2][0][RTW89_ACMA][11] = 60, + [0][0][2][0][RTW89_CN][11] = 58, + [0][0][2][0][RTW89_UK][11] = 60, + [0][0][2][0][RTW89_FCC][12] = 68, + [0][0][2][0][RTW89_ETSI][12] = 60, + [0][0][2][0][RTW89_MKK][12] = 70, + [0][0][2][0][RTW89_IC][12] = 68, + [0][0][2][0][RTW89_KCC][12] = 76, + [0][0][2][0][RTW89_ACMA][12] = 60, + [0][0][2][0][RTW89_CN][12] = 38, + [0][0][2][0][RTW89_UK][12] = 60, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_KCC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_CN][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 127, + [0][1][2][0][RTW89_ETSI][0] = 127, + [0][1][2][0][RTW89_MKK][0] = 127, + [0][1][2][0][RTW89_IC][0] = 127, + [0][1][2][0][RTW89_KCC][0] = 127, + [0][1][2][0][RTW89_ACMA][0] = 127, + [0][1][2][0][RTW89_CN][0] = 127, + [0][1][2][0][RTW89_UK][0] = 127, + [0][1][2][0][RTW89_FCC][1] = 127, + [0][1][2][0][RTW89_ETSI][1] = 127, + [0][1][2][0][RTW89_MKK][1] = 127, + [0][1][2][0][RTW89_IC][1] = 127, + [0][1][2][0][RTW89_KCC][1] = 127, + [0][1][2][0][RTW89_ACMA][1] = 127, + [0][1][2][0][RTW89_CN][1] = 127, + [0][1][2][0][RTW89_UK][1] = 127, + [0][1][2][0][RTW89_FCC][2] = 127, + [0][1][2][0][RTW89_ETSI][2] = 127, + [0][1][2][0][RTW89_MKK][2] = 127, + [0][1][2][0][RTW89_IC][2] = 127, + [0][1][2][0][RTW89_KCC][2] = 127, + [0][1][2][0][RTW89_ACMA][2] = 127, + [0][1][2][0][RTW89_CN][2] = 127, + [0][1][2][0][RTW89_UK][2] = 127, + [0][1][2][0][RTW89_FCC][3] = 127, + [0][1][2][0][RTW89_ETSI][3] = 127, + [0][1][2][0][RTW89_MKK][3] = 127, + [0][1][2][0][RTW89_IC][3] = 127, + [0][1][2][0][RTW89_KCC][3] = 127, + [0][1][2][0][RTW89_ACMA][3] = 127, + [0][1][2][0][RTW89_CN][3] = 127, + [0][1][2][0][RTW89_UK][3] = 127, + [0][1][2][0][RTW89_FCC][4] = 127, + [0][1][2][0][RTW89_ETSI][4] = 127, + [0][1][2][0][RTW89_MKK][4] = 127, + [0][1][2][0][RTW89_IC][4] = 127, + [0][1][2][0][RTW89_KCC][4] = 127, + [0][1][2][0][RTW89_ACMA][4] = 127, + [0][1][2][0][RTW89_CN][4] = 127, + [0][1][2][0][RTW89_UK][4] = 127, + [0][1][2][0][RTW89_FCC][5] = 127, + [0][1][2][0][RTW89_ETSI][5] = 127, + [0][1][2][0][RTW89_MKK][5] = 127, + [0][1][2][0][RTW89_IC][5] = 127, + [0][1][2][0][RTW89_KCC][5] = 127, + [0][1][2][0][RTW89_ACMA][5] = 127, + [0][1][2][0][RTW89_CN][5] = 127, + [0][1][2][0][RTW89_UK][5] = 127, + [0][1][2][0][RTW89_FCC][6] = 127, + [0][1][2][0][RTW89_ETSI][6] = 127, + [0][1][2][0][RTW89_MKK][6] = 127, + [0][1][2][0][RTW89_IC][6] = 127, + [0][1][2][0][RTW89_KCC][6] = 127, + [0][1][2][0][RTW89_ACMA][6] = 127, + [0][1][2][0][RTW89_CN][6] = 127, + [0][1][2][0][RTW89_UK][6] = 127, + [0][1][2][0][RTW89_FCC][7] = 127, + [0][1][2][0][RTW89_ETSI][7] = 127, + [0][1][2][0][RTW89_MKK][7] = 127, + [0][1][2][0][RTW89_IC][7] = 127, + [0][1][2][0][RTW89_KCC][7] = 127, + [0][1][2][0][RTW89_ACMA][7] = 127, + [0][1][2][0][RTW89_CN][7] = 127, + [0][1][2][0][RTW89_UK][7] = 127, + [0][1][2][0][RTW89_FCC][8] = 127, + [0][1][2][0][RTW89_ETSI][8] = 127, + [0][1][2][0][RTW89_MKK][8] = 127, + [0][1][2][0][RTW89_IC][8] = 127, + [0][1][2][0][RTW89_KCC][8] = 127, + [0][1][2][0][RTW89_ACMA][8] = 127, + [0][1][2][0][RTW89_CN][8] = 127, + [0][1][2][0][RTW89_UK][8] = 127, + [0][1][2][0][RTW89_FCC][9] = 127, + [0][1][2][0][RTW89_ETSI][9] = 127, + [0][1][2][0][RTW89_MKK][9] = 127, + [0][1][2][0][RTW89_IC][9] = 127, + [0][1][2][0][RTW89_KCC][9] = 127, + [0][1][2][0][RTW89_ACMA][9] = 127, + [0][1][2][0][RTW89_CN][9] = 127, + [0][1][2][0][RTW89_UK][9] = 127, + [0][1][2][0][RTW89_FCC][10] = 127, + [0][1][2][0][RTW89_ETSI][10] = 127, + [0][1][2][0][RTW89_MKK][10] = 127, + [0][1][2][0][RTW89_IC][10] = 127, + [0][1][2][0][RTW89_KCC][10] = 127, + [0][1][2][0][RTW89_ACMA][10] = 127, + [0][1][2][0][RTW89_CN][10] = 127, + [0][1][2][0][RTW89_UK][10] = 127, + [0][1][2][0][RTW89_FCC][11] = 127, + [0][1][2][0][RTW89_ETSI][11] = 127, + [0][1][2][0][RTW89_MKK][11] = 127, + [0][1][2][0][RTW89_IC][11] = 127, + [0][1][2][0][RTW89_KCC][11] = 127, + [0][1][2][0][RTW89_ACMA][11] = 127, + [0][1][2][0][RTW89_CN][11] = 127, + [0][1][2][0][RTW89_UK][11] = 127, + [0][1][2][0][RTW89_FCC][12] = 127, + [0][1][2][0][RTW89_ETSI][12] = 127, + [0][1][2][0][RTW89_MKK][12] = 127, + [0][1][2][0][RTW89_IC][12] = 127, + [0][1][2][0][RTW89_KCC][12] = 127, + [0][1][2][0][RTW89_ACMA][12] = 127, + [0][1][2][0][RTW89_CN][12] = 127, + [0][1][2][0][RTW89_UK][12] = 127, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_KCC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_CN][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 127, + [0][1][2][1][RTW89_ETSI][0] = 127, + [0][1][2][1][RTW89_MKK][0] = 127, + [0][1][2][1][RTW89_IC][0] = 127, + [0][1][2][1][RTW89_KCC][0] = 127, + [0][1][2][1][RTW89_ACMA][0] = 127, + [0][1][2][1][RTW89_CN][0] = 127, + [0][1][2][1][RTW89_UK][0] = 127, + [0][1][2][1][RTW89_FCC][1] = 127, + [0][1][2][1][RTW89_ETSI][1] = 127, + [0][1][2][1][RTW89_MKK][1] = 127, + [0][1][2][1][RTW89_IC][1] = 127, + [0][1][2][1][RTW89_KCC][1] = 127, + [0][1][2][1][RTW89_ACMA][1] = 127, + [0][1][2][1][RTW89_CN][1] = 127, + [0][1][2][1][RTW89_UK][1] = 127, + [0][1][2][1][RTW89_FCC][2] = 127, + [0][1][2][1][RTW89_ETSI][2] = 127, + [0][1][2][1][RTW89_MKK][2] = 127, + [0][1][2][1][RTW89_IC][2] = 127, + [0][1][2][1][RTW89_KCC][2] = 127, + [0][1][2][1][RTW89_ACMA][2] = 127, + [0][1][2][1][RTW89_CN][2] = 127, + [0][1][2][1][RTW89_UK][2] = 127, + [0][1][2][1][RTW89_FCC][3] = 127, + [0][1][2][1][RTW89_ETSI][3] = 127, + [0][1][2][1][RTW89_MKK][3] = 127, + [0][1][2][1][RTW89_IC][3] = 127, + [0][1][2][1][RTW89_KCC][3] = 127, + [0][1][2][1][RTW89_ACMA][3] = 127, + [0][1][2][1][RTW89_CN][3] = 127, + [0][1][2][1][RTW89_UK][3] = 127, + [0][1][2][1][RTW89_FCC][4] = 127, + [0][1][2][1][RTW89_ETSI][4] = 127, + [0][1][2][1][RTW89_MKK][4] = 127, + [0][1][2][1][RTW89_IC][4] = 127, + [0][1][2][1][RTW89_KCC][4] = 127, + [0][1][2][1][RTW89_ACMA][4] = 127, + [0][1][2][1][RTW89_CN][4] = 127, + [0][1][2][1][RTW89_UK][4] = 127, + [0][1][2][1][RTW89_FCC][5] = 127, + [0][1][2][1][RTW89_ETSI][5] = 127, + [0][1][2][1][RTW89_MKK][5] = 127, + [0][1][2][1][RTW89_IC][5] = 127, + [0][1][2][1][RTW89_KCC][5] = 127, + [0][1][2][1][RTW89_ACMA][5] = 127, + [0][1][2][1][RTW89_CN][5] = 127, + [0][1][2][1][RTW89_UK][5] = 127, + [0][1][2][1][RTW89_FCC][6] = 127, + [0][1][2][1][RTW89_ETSI][6] = 127, + [0][1][2][1][RTW89_MKK][6] = 127, + [0][1][2][1][RTW89_IC][6] = 127, + [0][1][2][1][RTW89_KCC][6] = 127, + [0][1][2][1][RTW89_ACMA][6] = 127, + [0][1][2][1][RTW89_CN][6] = 127, + [0][1][2][1][RTW89_UK][6] = 127, + [0][1][2][1][RTW89_FCC][7] = 127, + [0][1][2][1][RTW89_ETSI][7] = 127, + [0][1][2][1][RTW89_MKK][7] = 127, + [0][1][2][1][RTW89_IC][7] = 127, + [0][1][2][1][RTW89_KCC][7] = 127, + [0][1][2][1][RTW89_ACMA][7] = 127, + [0][1][2][1][RTW89_CN][7] = 127, + [0][1][2][1][RTW89_UK][7] = 127, + [0][1][2][1][RTW89_FCC][8] = 127, + [0][1][2][1][RTW89_ETSI][8] = 127, + [0][1][2][1][RTW89_MKK][8] = 127, + [0][1][2][1][RTW89_IC][8] = 127, + [0][1][2][1][RTW89_KCC][8] = 127, + [0][1][2][1][RTW89_ACMA][8] = 127, + [0][1][2][1][RTW89_CN][8] = 127, + [0][1][2][1][RTW89_UK][8] = 127, + [0][1][2][1][RTW89_FCC][9] = 127, + [0][1][2][1][RTW89_ETSI][9] = 127, + [0][1][2][1][RTW89_MKK][9] = 127, + [0][1][2][1][RTW89_IC][9] = 127, + [0][1][2][1][RTW89_KCC][9] = 127, + [0][1][2][1][RTW89_ACMA][9] = 127, + [0][1][2][1][RTW89_CN][9] = 127, + [0][1][2][1][RTW89_UK][9] = 127, + [0][1][2][1][RTW89_FCC][10] = 127, + [0][1][2][1][RTW89_ETSI][10] = 127, + [0][1][2][1][RTW89_MKK][10] = 127, + [0][1][2][1][RTW89_IC][10] = 127, + [0][1][2][1][RTW89_KCC][10] = 127, + [0][1][2][1][RTW89_ACMA][10] = 127, + [0][1][2][1][RTW89_CN][10] = 127, + [0][1][2][1][RTW89_UK][10] = 127, + [0][1][2][1][RTW89_FCC][11] = 127, + [0][1][2][1][RTW89_ETSI][11] = 127, + [0][1][2][1][RTW89_MKK][11] = 127, + [0][1][2][1][RTW89_IC][11] = 127, + [0][1][2][1][RTW89_KCC][11] = 127, + [0][1][2][1][RTW89_ACMA][11] = 127, + [0][1][2][1][RTW89_CN][11] = 127, + [0][1][2][1][RTW89_UK][11] = 127, + [0][1][2][1][RTW89_FCC][12] = 127, + [0][1][2][1][RTW89_ETSI][12] = 127, + [0][1][2][1][RTW89_MKK][12] = 127, + [0][1][2][1][RTW89_IC][12] = 127, + [0][1][2][1][RTW89_KCC][12] = 127, + [0][1][2][1][RTW89_ACMA][12] = 127, + [0][1][2][1][RTW89_CN][12] = 127, + [0][1][2][1][RTW89_UK][12] = 127, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_KCC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_CN][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_KCC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_CN][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_KCC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_CN][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 70, + [1][0][2][0][RTW89_ETSI][2] = 58, + [1][0][2][0][RTW89_MKK][2] = 76, + [1][0][2][0][RTW89_IC][2] = 70, + [1][0][2][0][RTW89_KCC][2] = 76, + [1][0][2][0][RTW89_ACMA][2] = 58, + [1][0][2][0][RTW89_CN][2] = 56, + [1][0][2][0][RTW89_UK][2] = 58, + [1][0][2][0][RTW89_FCC][3] = 70, + [1][0][2][0][RTW89_ETSI][3] = 58, + [1][0][2][0][RTW89_MKK][3] = 76, + [1][0][2][0][RTW89_IC][3] = 70, + [1][0][2][0][RTW89_KCC][3] = 76, + [1][0][2][0][RTW89_ACMA][3] = 58, + [1][0][2][0][RTW89_CN][3] = 56, + [1][0][2][0][RTW89_UK][3] = 58, + [1][0][2][0][RTW89_FCC][4] = 74, + [1][0][2][0][RTW89_ETSI][4] = 58, + [1][0][2][0][RTW89_MKK][4] = 76, + [1][0][2][0][RTW89_IC][4] = 74, + [1][0][2][0][RTW89_KCC][4] = 76, + [1][0][2][0][RTW89_ACMA][4] = 58, + [1][0][2][0][RTW89_CN][4] = 56, + [1][0][2][0][RTW89_UK][4] = 58, + [1][0][2][0][RTW89_FCC][5] = 76, + [1][0][2][0][RTW89_ETSI][5] = 58, + [1][0][2][0][RTW89_MKK][5] = 76, + [1][0][2][0][RTW89_IC][5] = 76, + [1][0][2][0][RTW89_KCC][5] = 76, + [1][0][2][0][RTW89_ACMA][5] = 58, + [1][0][2][0][RTW89_CN][5] = 56, + [1][0][2][0][RTW89_UK][5] = 58, + [1][0][2][0][RTW89_FCC][6] = 76, + [1][0][2][0][RTW89_ETSI][6] = 58, + [1][0][2][0][RTW89_MKK][6] = 76, + [1][0][2][0][RTW89_IC][6] = 76, + [1][0][2][0][RTW89_KCC][6] = 76, + [1][0][2][0][RTW89_ACMA][6] = 58, + [1][0][2][0][RTW89_CN][6] = 56, + [1][0][2][0][RTW89_UK][6] = 58, + [1][0][2][0][RTW89_FCC][7] = 76, + [1][0][2][0][RTW89_ETSI][7] = 58, + [1][0][2][0][RTW89_MKK][7] = 76, + [1][0][2][0][RTW89_IC][7] = 76, + [1][0][2][0][RTW89_KCC][7] = 76, + [1][0][2][0][RTW89_ACMA][7] = 58, + [1][0][2][0][RTW89_CN][7] = 56, + [1][0][2][0][RTW89_UK][7] = 58, + [1][0][2][0][RTW89_FCC][8] = 78, + [1][0][2][0][RTW89_ETSI][8] = 58, + [1][0][2][0][RTW89_MKK][8] = 76, + [1][0][2][0][RTW89_IC][8] = 78, + [1][0][2][0][RTW89_KCC][8] = 76, + [1][0][2][0][RTW89_ACMA][8] = 58, + [1][0][2][0][RTW89_CN][8] = 56, + [1][0][2][0][RTW89_UK][8] = 58, + [1][0][2][0][RTW89_FCC][9] = 74, + [1][0][2][0][RTW89_ETSI][9] = 58, + [1][0][2][0][RTW89_MKK][9] = 76, + [1][0][2][0][RTW89_IC][9] = 74, + [1][0][2][0][RTW89_KCC][9] = 76, + [1][0][2][0][RTW89_ACMA][9] = 58, + [1][0][2][0][RTW89_CN][9] = 56, + [1][0][2][0][RTW89_UK][9] = 58, + [1][0][2][0][RTW89_FCC][10] = 68, + [1][0][2][0][RTW89_ETSI][10] = 58, + [1][0][2][0][RTW89_MKK][10] = 76, + [1][0][2][0][RTW89_IC][10] = 68, + [1][0][2][0][RTW89_KCC][10] = 76, + [1][0][2][0][RTW89_ACMA][10] = 58, + [1][0][2][0][RTW89_CN][10] = 48, + [1][0][2][0][RTW89_UK][10] = 58, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_KCC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_CN][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_KCC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_CN][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_KCC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_CN][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_KCC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_CN][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 127, + [1][1][2][0][RTW89_ETSI][2] = 127, + [1][1][2][0][RTW89_MKK][2] = 127, + [1][1][2][0][RTW89_IC][2] = 127, + [1][1][2][0][RTW89_KCC][2] = 127, + [1][1][2][0][RTW89_ACMA][2] = 127, + [1][1][2][0][RTW89_CN][2] = 127, + [1][1][2][0][RTW89_UK][2] = 127, + [1][1][2][0][RTW89_FCC][3] = 127, + [1][1][2][0][RTW89_ETSI][3] = 127, + [1][1][2][0][RTW89_MKK][3] = 127, + [1][1][2][0][RTW89_IC][3] = 127, + [1][1][2][0][RTW89_KCC][3] = 127, + [1][1][2][0][RTW89_ACMA][3] = 127, + [1][1][2][0][RTW89_CN][3] = 127, + [1][1][2][0][RTW89_UK][3] = 127, + [1][1][2][0][RTW89_FCC][4] = 127, + [1][1][2][0][RTW89_ETSI][4] = 127, + [1][1][2][0][RTW89_MKK][4] = 127, + [1][1][2][0][RTW89_IC][4] = 127, + [1][1][2][0][RTW89_KCC][4] = 127, + [1][1][2][0][RTW89_ACMA][4] = 127, + [1][1][2][0][RTW89_CN][4] = 127, + [1][1][2][0][RTW89_UK][4] = 127, + [1][1][2][0][RTW89_FCC][5] = 127, + [1][1][2][0][RTW89_ETSI][5] = 127, + [1][1][2][0][RTW89_MKK][5] = 127, + [1][1][2][0][RTW89_IC][5] = 127, + [1][1][2][0][RTW89_KCC][5] = 127, + [1][1][2][0][RTW89_ACMA][5] = 127, + [1][1][2][0][RTW89_CN][5] = 127, + [1][1][2][0][RTW89_UK][5] = 127, + [1][1][2][0][RTW89_FCC][6] = 127, + [1][1][2][0][RTW89_ETSI][6] = 127, + [1][1][2][0][RTW89_MKK][6] = 127, + [1][1][2][0][RTW89_IC][6] = 127, + [1][1][2][0][RTW89_KCC][6] = 127, + [1][1][2][0][RTW89_ACMA][6] = 127, + [1][1][2][0][RTW89_CN][6] = 127, + [1][1][2][0][RTW89_UK][6] = 127, + [1][1][2][0][RTW89_FCC][7] = 127, + [1][1][2][0][RTW89_ETSI][7] = 127, + [1][1][2][0][RTW89_MKK][7] = 127, + [1][1][2][0][RTW89_IC][7] = 127, + [1][1][2][0][RTW89_KCC][7] = 127, + [1][1][2][0][RTW89_ACMA][7] = 127, + [1][1][2][0][RTW89_CN][7] = 127, + [1][1][2][0][RTW89_UK][7] = 127, + [1][1][2][0][RTW89_FCC][8] = 127, + [1][1][2][0][RTW89_ETSI][8] = 127, + [1][1][2][0][RTW89_MKK][8] = 127, + [1][1][2][0][RTW89_IC][8] = 127, + [1][1][2][0][RTW89_KCC][8] = 127, + [1][1][2][0][RTW89_ACMA][8] = 127, + [1][1][2][0][RTW89_CN][8] = 127, + [1][1][2][0][RTW89_UK][8] = 127, + [1][1][2][0][RTW89_FCC][9] = 127, + [1][1][2][0][RTW89_ETSI][9] = 127, + [1][1][2][0][RTW89_MKK][9] = 127, + [1][1][2][0][RTW89_IC][9] = 127, + [1][1][2][0][RTW89_KCC][9] = 127, + [1][1][2][0][RTW89_ACMA][9] = 127, + [1][1][2][0][RTW89_CN][9] = 127, + [1][1][2][0][RTW89_UK][9] = 127, + [1][1][2][0][RTW89_FCC][10] = 127, + [1][1][2][0][RTW89_ETSI][10] = 127, + [1][1][2][0][RTW89_MKK][10] = 127, + [1][1][2][0][RTW89_IC][10] = 127, + [1][1][2][0][RTW89_KCC][10] = 127, + [1][1][2][0][RTW89_ACMA][10] = 127, + [1][1][2][0][RTW89_CN][10] = 127, + [1][1][2][0][RTW89_UK][10] = 127, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_KCC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_CN][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_KCC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_CN][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_KCC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_CN][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 127, + [1][1][2][1][RTW89_ETSI][2] = 127, + [1][1][2][1][RTW89_MKK][2] = 127, + [1][1][2][1][RTW89_IC][2] = 127, + [1][1][2][1][RTW89_KCC][2] = 127, + [1][1][2][1][RTW89_ACMA][2] = 127, + [1][1][2][1][RTW89_CN][2] = 127, + [1][1][2][1][RTW89_UK][2] = 127, + [1][1][2][1][RTW89_FCC][3] = 127, + [1][1][2][1][RTW89_ETSI][3] = 127, + [1][1][2][1][RTW89_MKK][3] = 127, + [1][1][2][1][RTW89_IC][3] = 127, + [1][1][2][1][RTW89_KCC][3] = 127, + [1][1][2][1][RTW89_ACMA][3] = 127, + [1][1][2][1][RTW89_CN][3] = 127, + [1][1][2][1][RTW89_UK][3] = 127, + [1][1][2][1][RTW89_FCC][4] = 127, + [1][1][2][1][RTW89_ETSI][4] = 127, + [1][1][2][1][RTW89_MKK][4] = 127, + [1][1][2][1][RTW89_IC][4] = 127, + [1][1][2][1][RTW89_KCC][4] = 127, + [1][1][2][1][RTW89_ACMA][4] = 127, + [1][1][2][1][RTW89_CN][4] = 127, + [1][1][2][1][RTW89_UK][4] = 127, + [1][1][2][1][RTW89_FCC][5] = 127, + [1][1][2][1][RTW89_ETSI][5] = 127, + [1][1][2][1][RTW89_MKK][5] = 127, + [1][1][2][1][RTW89_IC][5] = 127, + [1][1][2][1][RTW89_KCC][5] = 127, + [1][1][2][1][RTW89_ACMA][5] = 127, + [1][1][2][1][RTW89_CN][5] = 127, + [1][1][2][1][RTW89_UK][5] = 127, + [1][1][2][1][RTW89_FCC][6] = 127, + [1][1][2][1][RTW89_ETSI][6] = 127, + [1][1][2][1][RTW89_MKK][6] = 127, + [1][1][2][1][RTW89_IC][6] = 127, + [1][1][2][1][RTW89_KCC][6] = 127, + [1][1][2][1][RTW89_ACMA][6] = 127, + [1][1][2][1][RTW89_CN][6] = 127, + [1][1][2][1][RTW89_UK][6] = 127, + [1][1][2][1][RTW89_FCC][7] = 127, + [1][1][2][1][RTW89_ETSI][7] = 127, + [1][1][2][1][RTW89_MKK][7] = 127, + [1][1][2][1][RTW89_IC][7] = 127, + [1][1][2][1][RTW89_KCC][7] = 127, + [1][1][2][1][RTW89_ACMA][7] = 127, + [1][1][2][1][RTW89_CN][7] = 127, + [1][1][2][1][RTW89_UK][7] = 127, + [1][1][2][1][RTW89_FCC][8] = 127, + [1][1][2][1][RTW89_ETSI][8] = 127, + [1][1][2][1][RTW89_MKK][8] = 127, + [1][1][2][1][RTW89_IC][8] = 127, + [1][1][2][1][RTW89_KCC][8] = 127, + [1][1][2][1][RTW89_ACMA][8] = 127, + [1][1][2][1][RTW89_CN][8] = 127, + [1][1][2][1][RTW89_UK][8] = 127, + [1][1][2][1][RTW89_FCC][9] = 127, + [1][1][2][1][RTW89_ETSI][9] = 127, + [1][1][2][1][RTW89_MKK][9] = 127, + [1][1][2][1][RTW89_IC][9] = 127, + [1][1][2][1][RTW89_KCC][9] = 127, + [1][1][2][1][RTW89_ACMA][9] = 127, + [1][1][2][1][RTW89_CN][9] = 127, + [1][1][2][1][RTW89_UK][9] = 127, + [1][1][2][1][RTW89_FCC][10] = 127, + [1][1][2][1][RTW89_ETSI][10] = 127, + [1][1][2][1][RTW89_MKK][10] = 127, + [1][1][2][1][RTW89_IC][10] = 127, + [1][1][2][1][RTW89_KCC][10] = 127, + [1][1][2][1][RTW89_ACMA][10] = 127, + [1][1][2][1][RTW89_CN][10] = 127, + [1][1][2][1][RTW89_UK][10] = 127, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_KCC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_CN][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_KCC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_CN][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_5g_type2[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][2] = 58, + [0][0][1][0][RTW89_WW][4] = 58, + [0][0][1][0][RTW89_WW][6] = 50, + [0][0][1][0][RTW89_WW][8] = 58, + [0][0][1][0][RTW89_WW][10] = 58, + [0][0][1][0][RTW89_WW][12] = 58, + [0][0][1][0][RTW89_WW][14] = 58, + [0][0][1][0][RTW89_WW][15] = 58, + [0][0][1][0][RTW89_WW][17] = 60, + [0][0][1][0][RTW89_WW][19] = 60, + [0][0][1][0][RTW89_WW][21] = 60, + [0][0][1][0][RTW89_WW][23] = 60, + [0][0][1][0][RTW89_WW][25] = 60, + [0][0][1][0][RTW89_WW][27] = 60, + [0][0][1][0][RTW89_WW][29] = 60, + [0][0][1][0][RTW89_WW][31] = 60, + [0][0][1][0][RTW89_WW][33] = 60, + [0][0][1][0][RTW89_WW][35] = 60, + [0][0][1][0][RTW89_WW][37] = 74, + [0][0][1][0][RTW89_WW][38] = 30, + [0][0][1][0][RTW89_WW][40] = 30, + [0][0][1][0][RTW89_WW][42] = 30, + [0][0][1][0][RTW89_WW][44] = 30, + [0][0][1][0][RTW89_WW][46] = 30, + [0][0][1][0][RTW89_WW][48] = 72, + [0][0][1][0][RTW89_WW][50] = 72, + [0][0][1][0][RTW89_WW][52] = 72, + [0][1][1][0][RTW89_WW][0] = 0, + [0][1][1][0][RTW89_WW][2] = 0, + [0][1][1][0][RTW89_WW][4] = 0, + [0][1][1][0][RTW89_WW][6] = 0, + [0][1][1][0][RTW89_WW][8] = 0, + [0][1][1][0][RTW89_WW][10] = 0, + [0][1][1][0][RTW89_WW][12] = 0, + [0][1][1][0][RTW89_WW][14] = 0, + [0][1][1][0][RTW89_WW][15] = 0, + [0][1][1][0][RTW89_WW][17] = 0, + [0][1][1][0][RTW89_WW][19] = 0, + [0][1][1][0][RTW89_WW][21] = 0, + [0][1][1][0][RTW89_WW][23] = 0, + [0][1][1][0][RTW89_WW][25] = 0, + [0][1][1][0][RTW89_WW][27] = 0, + [0][1][1][0][RTW89_WW][29] = 0, + [0][1][1][0][RTW89_WW][31] = 0, + [0][1][1][0][RTW89_WW][33] = 0, + [0][1][1][0][RTW89_WW][35] = 0, + [0][1][1][0][RTW89_WW][37] = 0, + [0][1][1][0][RTW89_WW][38] = 0, + [0][1][1][0][RTW89_WW][40] = 0, + [0][1][1][0][RTW89_WW][42] = 0, + [0][1][1][0][RTW89_WW][44] = 0, + [0][1][1][0][RTW89_WW][46] = 0, + [0][1][1][0][RTW89_WW][48] = 0, + [0][1][1][0][RTW89_WW][50] = 0, + [0][1][1][0][RTW89_WW][52] = 0, + [0][0][2][0][RTW89_WW][0] = 60, + [0][0][2][0][RTW89_WW][2] = 60, + [0][0][2][0][RTW89_WW][4] = 60, + [0][0][2][0][RTW89_WW][6] = 54, + [0][0][2][0][RTW89_WW][8] = 60, + [0][0][2][0][RTW89_WW][10] = 60, + [0][0][2][0][RTW89_WW][12] = 60, + [0][0][2][0][RTW89_WW][14] = 60, + [0][0][2][0][RTW89_WW][15] = 60, + [0][0][2][0][RTW89_WW][17] = 62, + [0][0][2][0][RTW89_WW][19] = 62, + [0][0][2][0][RTW89_WW][21] = 62, + [0][0][2][0][RTW89_WW][23] = 62, + [0][0][2][0][RTW89_WW][25] = 62, + [0][0][2][0][RTW89_WW][27] = 62, + [0][0][2][0][RTW89_WW][29] = 62, + [0][0][2][0][RTW89_WW][31] = 62, + [0][0][2][0][RTW89_WW][33] = 62, + [0][0][2][0][RTW89_WW][35] = 62, + [0][0][2][0][RTW89_WW][37] = 74, + [0][0][2][0][RTW89_WW][38] = 30, + [0][0][2][0][RTW89_WW][40] = 30, + [0][0][2][0][RTW89_WW][42] = 30, + [0][0][2][0][RTW89_WW][44] = 30, + [0][0][2][0][RTW89_WW][46] = 30, + [0][0][2][0][RTW89_WW][48] = 74, + [0][0][2][0][RTW89_WW][50] = 74, + [0][0][2][0][RTW89_WW][52] = 74, + [0][1][2][0][RTW89_WW][0] = 0, + [0][1][2][0][RTW89_WW][2] = 0, + [0][1][2][0][RTW89_WW][4] = 0, + [0][1][2][0][RTW89_WW][6] = 0, + [0][1][2][0][RTW89_WW][8] = 0, + [0][1][2][0][RTW89_WW][10] = 0, + [0][1][2][0][RTW89_WW][12] = 0, + [0][1][2][0][RTW89_WW][14] = 0, + [0][1][2][0][RTW89_WW][15] = 0, + [0][1][2][0][RTW89_WW][17] = 0, + [0][1][2][0][RTW89_WW][19] = 0, + [0][1][2][0][RTW89_WW][21] = 0, + [0][1][2][0][RTW89_WW][23] = 0, + [0][1][2][0][RTW89_WW][25] = 0, + [0][1][2][0][RTW89_WW][27] = 0, + [0][1][2][0][RTW89_WW][29] = 0, + [0][1][2][0][RTW89_WW][31] = 0, + [0][1][2][0][RTW89_WW][33] = 0, + [0][1][2][0][RTW89_WW][35] = 0, + [0][1][2][0][RTW89_WW][37] = 0, + [0][1][2][0][RTW89_WW][38] = 0, + [0][1][2][0][RTW89_WW][40] = 0, + [0][1][2][0][RTW89_WW][42] = 0, + [0][1][2][0][RTW89_WW][44] = 0, + [0][1][2][0][RTW89_WW][46] = 0, + [0][1][2][0][RTW89_WW][48] = 0, + [0][1][2][0][RTW89_WW][50] = 0, + [0][1][2][0][RTW89_WW][52] = 0, + [0][1][2][1][RTW89_WW][0] = 0, + [0][1][2][1][RTW89_WW][2] = 0, + [0][1][2][1][RTW89_WW][4] = 0, + [0][1][2][1][RTW89_WW][6] = 0, + [0][1][2][1][RTW89_WW][8] = 0, + [0][1][2][1][RTW89_WW][10] = 0, + [0][1][2][1][RTW89_WW][12] = 0, + [0][1][2][1][RTW89_WW][14] = 0, + [0][1][2][1][RTW89_WW][15] = 0, + [0][1][2][1][RTW89_WW][17] = 0, + [0][1][2][1][RTW89_WW][19] = 0, + [0][1][2][1][RTW89_WW][21] = 0, + [0][1][2][1][RTW89_WW][23] = 0, + [0][1][2][1][RTW89_WW][25] = 0, + [0][1][2][1][RTW89_WW][27] = 0, + [0][1][2][1][RTW89_WW][29] = 0, + [0][1][2][1][RTW89_WW][31] = 0, + [0][1][2][1][RTW89_WW][33] = 0, + [0][1][2][1][RTW89_WW][35] = 0, + [0][1][2][1][RTW89_WW][37] = 0, + [0][1][2][1][RTW89_WW][38] = 0, + [0][1][2][1][RTW89_WW][40] = 0, + [0][1][2][1][RTW89_WW][42] = 0, + [0][1][2][1][RTW89_WW][44] = 0, + [0][1][2][1][RTW89_WW][46] = 0, + [0][1][2][1][RTW89_WW][48] = 0, + [0][1][2][1][RTW89_WW][50] = 0, + [0][1][2][1][RTW89_WW][52] = 0, + [1][0][2][0][RTW89_WW][1] = 64, + [1][0][2][0][RTW89_WW][5] = 62, + [1][0][2][0][RTW89_WW][9] = 58, + [1][0][2][0][RTW89_WW][13] = 58, + [1][0][2][0][RTW89_WW][16] = 66, + [1][0][2][0][RTW89_WW][20] = 66, + [1][0][2][0][RTW89_WW][24] = 66, + [1][0][2][0][RTW89_WW][28] = 66, + [1][0][2][0][RTW89_WW][32] = 66, + [1][0][2][0][RTW89_WW][36] = 76, + [1][0][2][0][RTW89_WW][39] = 30, + [1][0][2][0][RTW89_WW][43] = 30, + [1][0][2][0][RTW89_WW][47] = 80, + [1][0][2][0][RTW89_WW][51] = 80, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][5] = 0, + [1][1][2][0][RTW89_WW][9] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][16] = 0, + [1][1][2][0][RTW89_WW][20] = 0, + [1][1][2][0][RTW89_WW][24] = 0, + [1][1][2][0][RTW89_WW][28] = 0, + [1][1][2][0][RTW89_WW][32] = 0, + [1][1][2][0][RTW89_WW][36] = 0, + [1][1][2][0][RTW89_WW][39] = 0, + [1][1][2][0][RTW89_WW][43] = 0, + [1][1][2][0][RTW89_WW][47] = 0, + [1][1][2][0][RTW89_WW][51] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][5] = 0, + [1][1][2][1][RTW89_WW][9] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][16] = 0, + [1][1][2][1][RTW89_WW][20] = 0, + [1][1][2][1][RTW89_WW][24] = 0, + [1][1][2][1][RTW89_WW][28] = 0, + [1][1][2][1][RTW89_WW][32] = 0, + [1][1][2][1][RTW89_WW][36] = 0, + [1][1][2][1][RTW89_WW][39] = 0, + [1][1][2][1][RTW89_WW][43] = 0, + [1][1][2][1][RTW89_WW][47] = 0, + [1][1][2][1][RTW89_WW][51] = 0, + [2][0][2][0][RTW89_WW][3] = 60, + [2][0][2][0][RTW89_WW][11] = 54, + [2][0][2][0][RTW89_WW][18] = 64, + [2][0][2][0][RTW89_WW][26] = 64, + [2][0][2][0][RTW89_WW][34] = 68, + [2][0][2][0][RTW89_WW][41] = 30, + [2][0][2][0][RTW89_WW][49] = 72, + [2][1][2][0][RTW89_WW][3] = 0, + [2][1][2][0][RTW89_WW][11] = 0, + [2][1][2][0][RTW89_WW][18] = 0, + [2][1][2][0][RTW89_WW][26] = 0, + [2][1][2][0][RTW89_WW][34] = 0, + [2][1][2][0][RTW89_WW][41] = 0, + [2][1][2][0][RTW89_WW][49] = 0, + [2][1][2][1][RTW89_WW][3] = 0, + [2][1][2][1][RTW89_WW][11] = 0, + [2][1][2][1][RTW89_WW][18] = 0, + [2][1][2][1][RTW89_WW][26] = 0, + [2][1][2][1][RTW89_WW][34] = 0, + [2][1][2][1][RTW89_WW][41] = 0, + [2][1][2][1][RTW89_WW][49] = 0, + [3][0][2][0][RTW89_WW][7] = 0, + [3][0][2][0][RTW89_WW][22] = 0, + [3][0][2][0][RTW89_WW][45] = 0, + [3][1][2][0][RTW89_WW][7] = 0, + [3][1][2][0][RTW89_WW][22] = 0, + [3][1][2][0][RTW89_WW][45] = 0, + [3][1][2][1][RTW89_WW][7] = 0, + [3][1][2][1][RTW89_WW][22] = 0, + [3][1][2][1][RTW89_WW][45] = 0, + [0][0][1][0][RTW89_FCC][0] = 78, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 60, + [0][0][1][0][RTW89_IC][0] = 62, + [0][0][1][0][RTW89_KCC][0] = 74, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CN][0] = 60, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][2] = 78, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 60, + [0][0][1][0][RTW89_IC][2] = 62, + [0][0][1][0][RTW89_KCC][2] = 74, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CN][2] = 60, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][4] = 78, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 60, + [0][0][1][0][RTW89_IC][4] = 62, + [0][0][1][0][RTW89_KCC][4] = 74, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CN][4] = 60, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][6] = 78, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 60, + [0][0][1][0][RTW89_IC][6] = 62, + [0][0][1][0][RTW89_KCC][6] = 50, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CN][6] = 60, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][8] = 78, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 60, + [0][0][1][0][RTW89_IC][8] = 62, + [0][0][1][0][RTW89_KCC][8] = 74, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CN][8] = 60, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][10] = 78, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 60, + [0][0][1][0][RTW89_IC][10] = 64, + [0][0][1][0][RTW89_KCC][10] = 74, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CN][10] = 60, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][12] = 78, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 60, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 74, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CN][12] = 60, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][14] = 76, + [0][0][1][0][RTW89_ETSI][14] = 58, + [0][0][1][0][RTW89_MKK][14] = 60, + [0][0][1][0][RTW89_IC][14] = 62, + [0][0][1][0][RTW89_KCC][14] = 74, + [0][0][1][0][RTW89_ACMA][14] = 58, + [0][0][1][0][RTW89_CN][14] = 60, + [0][0][1][0][RTW89_UK][14] = 58, + [0][0][1][0][RTW89_FCC][15] = 76, + [0][0][1][0][RTW89_ETSI][15] = 58, + [0][0][1][0][RTW89_MKK][15] = 74, + [0][0][1][0][RTW89_IC][15] = 76, + [0][0][1][0][RTW89_KCC][15] = 74, + [0][0][1][0][RTW89_ACMA][15] = 58, + [0][0][1][0][RTW89_CN][15] = 127, + [0][0][1][0][RTW89_UK][15] = 58, + [0][0][1][0][RTW89_FCC][17] = 78, + [0][0][1][0][RTW89_ETSI][17] = 60, + [0][0][1][0][RTW89_MKK][17] = 74, + [0][0][1][0][RTW89_IC][17] = 78, + [0][0][1][0][RTW89_KCC][17] = 74, + [0][0][1][0][RTW89_ACMA][17] = 60, + [0][0][1][0][RTW89_CN][17] = 127, + [0][0][1][0][RTW89_UK][17] = 60, + [0][0][1][0][RTW89_FCC][19] = 78, + [0][0][1][0][RTW89_ETSI][19] = 60, + [0][0][1][0][RTW89_MKK][19] = 74, + [0][0][1][0][RTW89_IC][19] = 78, + [0][0][1][0][RTW89_KCC][19] = 74, + [0][0][1][0][RTW89_ACMA][19] = 60, + [0][0][1][0][RTW89_CN][19] = 127, + [0][0][1][0][RTW89_UK][19] = 60, + [0][0][1][0][RTW89_FCC][21] = 78, + [0][0][1][0][RTW89_ETSI][21] = 60, + [0][0][1][0][RTW89_MKK][21] = 74, + [0][0][1][0][RTW89_IC][21] = 78, + [0][0][1][0][RTW89_KCC][21] = 74, + [0][0][1][0][RTW89_ACMA][21] = 60, + [0][0][1][0][RTW89_CN][21] = 127, + [0][0][1][0][RTW89_UK][21] = 60, + [0][0][1][0][RTW89_FCC][23] = 78, + [0][0][1][0][RTW89_ETSI][23] = 60, + [0][0][1][0][RTW89_MKK][23] = 74, + [0][0][1][0][RTW89_IC][23] = 78, + [0][0][1][0][RTW89_KCC][23] = 74, + [0][0][1][0][RTW89_ACMA][23] = 60, + [0][0][1][0][RTW89_CN][23] = 127, + [0][0][1][0][RTW89_UK][23] = 60, + [0][0][1][0][RTW89_FCC][25] = 78, + [0][0][1][0][RTW89_ETSI][25] = 60, + [0][0][1][0][RTW89_MKK][25] = 74, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_KCC][25] = 74, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_CN][25] = 127, + [0][0][1][0][RTW89_UK][25] = 60, + [0][0][1][0][RTW89_FCC][27] = 78, + [0][0][1][0][RTW89_ETSI][27] = 60, + [0][0][1][0][RTW89_MKK][27] = 74, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_KCC][27] = 74, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_CN][27] = 127, + [0][0][1][0][RTW89_UK][27] = 60, + [0][0][1][0][RTW89_FCC][29] = 78, + [0][0][1][0][RTW89_ETSI][29] = 60, + [0][0][1][0][RTW89_MKK][29] = 74, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_KCC][29] = 74, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_CN][29] = 127, + [0][0][1][0][RTW89_UK][29] = 60, + [0][0][1][0][RTW89_FCC][31] = 78, + [0][0][1][0][RTW89_ETSI][31] = 60, + [0][0][1][0][RTW89_MKK][31] = 74, + [0][0][1][0][RTW89_IC][31] = 78, + [0][0][1][0][RTW89_KCC][31] = 74, + [0][0][1][0][RTW89_ACMA][31] = 60, + [0][0][1][0][RTW89_CN][31] = 127, + [0][0][1][0][RTW89_UK][31] = 60, + [0][0][1][0][RTW89_FCC][33] = 78, + [0][0][1][0][RTW89_ETSI][33] = 60, + [0][0][1][0][RTW89_MKK][33] = 74, + [0][0][1][0][RTW89_IC][33] = 78, + [0][0][1][0][RTW89_KCC][33] = 74, + [0][0][1][0][RTW89_ACMA][33] = 60, + [0][0][1][0][RTW89_CN][33] = 127, + [0][0][1][0][RTW89_UK][33] = 60, + [0][0][1][0][RTW89_FCC][35] = 70, + [0][0][1][0][RTW89_ETSI][35] = 60, + [0][0][1][0][RTW89_MKK][35] = 74, + [0][0][1][0][RTW89_IC][35] = 70, + [0][0][1][0][RTW89_KCC][35] = 74, + [0][0][1][0][RTW89_ACMA][35] = 60, + [0][0][1][0][RTW89_CN][35] = 127, + [0][0][1][0][RTW89_UK][35] = 60, + [0][0][1][0][RTW89_FCC][37] = 78, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 74, + [0][0][1][0][RTW89_IC][37] = 78, + [0][0][1][0][RTW89_KCC][37] = 74, + [0][0][1][0][RTW89_ACMA][37] = 74, + [0][0][1][0][RTW89_CN][37] = 127, + [0][0][1][0][RTW89_UK][37] = 74, + [0][0][1][0][RTW89_FCC][38] = 78, + [0][0][1][0][RTW89_ETSI][38] = 30, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 78, + [0][0][1][0][RTW89_KCC][38] = 70, + [0][0][1][0][RTW89_ACMA][38] = 74, + [0][0][1][0][RTW89_CN][38] = 64, + [0][0][1][0][RTW89_UK][38] = 58, + [0][0][1][0][RTW89_FCC][40] = 78, + [0][0][1][0][RTW89_ETSI][40] = 30, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 78, + [0][0][1][0][RTW89_KCC][40] = 74, + [0][0][1][0][RTW89_ACMA][40] = 74, + [0][0][1][0][RTW89_CN][40] = 64, + [0][0][1][0][RTW89_UK][40] = 58, + [0][0][1][0][RTW89_FCC][42] = 78, + [0][0][1][0][RTW89_ETSI][42] = 30, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 78, + [0][0][1][0][RTW89_KCC][42] = 74, + [0][0][1][0][RTW89_ACMA][42] = 74, + [0][0][1][0][RTW89_CN][42] = 64, + [0][0][1][0][RTW89_UK][42] = 58, + [0][0][1][0][RTW89_FCC][44] = 78, + [0][0][1][0][RTW89_ETSI][44] = 30, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 78, + [0][0][1][0][RTW89_KCC][44] = 74, + [0][0][1][0][RTW89_ACMA][44] = 74, + [0][0][1][0][RTW89_CN][44] = 62, + [0][0][1][0][RTW89_UK][44] = 58, + [0][0][1][0][RTW89_FCC][46] = 78, + [0][0][1][0][RTW89_ETSI][46] = 30, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 78, + [0][0][1][0][RTW89_KCC][46] = 74, + [0][0][1][0][RTW89_ACMA][46] = 74, + [0][0][1][0][RTW89_CN][46] = 62, + [0][0][1][0][RTW89_UK][46] = 58, + [0][0][1][0][RTW89_FCC][48] = 72, + [0][0][1][0][RTW89_ETSI][48] = 127, + [0][0][1][0][RTW89_MKK][48] = 127, + [0][0][1][0][RTW89_IC][48] = 72, + [0][0][1][0][RTW89_KCC][48] = 127, + [0][0][1][0][RTW89_ACMA][48] = 127, + [0][0][1][0][RTW89_CN][48] = 127, + [0][0][1][0][RTW89_UK][48] = 127, + [0][0][1][0][RTW89_FCC][50] = 72, + [0][0][1][0][RTW89_ETSI][50] = 127, + [0][0][1][0][RTW89_MKK][50] = 127, + [0][0][1][0][RTW89_IC][50] = 72, + [0][0][1][0][RTW89_KCC][50] = 127, + [0][0][1][0][RTW89_ACMA][50] = 127, + [0][0][1][0][RTW89_CN][50] = 127, + [0][0][1][0][RTW89_UK][50] = 127, + [0][0][1][0][RTW89_FCC][52] = 72, + [0][0][1][0][RTW89_ETSI][52] = 127, + [0][0][1][0][RTW89_MKK][52] = 127, + [0][0][1][0][RTW89_IC][52] = 72, + [0][0][1][0][RTW89_KCC][52] = 127, + [0][0][1][0][RTW89_ACMA][52] = 127, + [0][0][1][0][RTW89_CN][52] = 127, + [0][0][1][0][RTW89_UK][52] = 127, + [0][1][1][0][RTW89_FCC][0] = 127, + [0][1][1][0][RTW89_ETSI][0] = 127, + [0][1][1][0][RTW89_MKK][0] = 127, + [0][1][1][0][RTW89_IC][0] = 127, + [0][1][1][0][RTW89_KCC][0] = 127, + [0][1][1][0][RTW89_ACMA][0] = 127, + [0][1][1][0][RTW89_CN][0] = 127, + [0][1][1][0][RTW89_UK][0] = 127, + [0][1][1][0][RTW89_FCC][2] = 127, + [0][1][1][0][RTW89_ETSI][2] = 127, + [0][1][1][0][RTW89_MKK][2] = 127, + [0][1][1][0][RTW89_IC][2] = 127, + [0][1][1][0][RTW89_KCC][2] = 127, + [0][1][1][0][RTW89_ACMA][2] = 127, + [0][1][1][0][RTW89_CN][2] = 127, + [0][1][1][0][RTW89_UK][2] = 127, + [0][1][1][0][RTW89_FCC][4] = 127, + [0][1][1][0][RTW89_ETSI][4] = 127, + [0][1][1][0][RTW89_MKK][4] = 127, + [0][1][1][0][RTW89_IC][4] = 127, + [0][1][1][0][RTW89_KCC][4] = 127, + [0][1][1][0][RTW89_ACMA][4] = 127, + [0][1][1][0][RTW89_CN][4] = 127, + [0][1][1][0][RTW89_UK][4] = 127, + [0][1][1][0][RTW89_FCC][6] = 127, + [0][1][1][0][RTW89_ETSI][6] = 127, + [0][1][1][0][RTW89_MKK][6] = 127, + [0][1][1][0][RTW89_IC][6] = 127, + [0][1][1][0][RTW89_KCC][6] = 127, + [0][1][1][0][RTW89_ACMA][6] = 127, + [0][1][1][0][RTW89_CN][6] = 127, + [0][1][1][0][RTW89_UK][6] = 127, + [0][1][1][0][RTW89_FCC][8] = 127, + [0][1][1][0][RTW89_ETSI][8] = 127, + [0][1][1][0][RTW89_MKK][8] = 127, + [0][1][1][0][RTW89_IC][8] = 127, + [0][1][1][0][RTW89_KCC][8] = 127, + [0][1][1][0][RTW89_ACMA][8] = 127, + [0][1][1][0][RTW89_CN][8] = 127, + [0][1][1][0][RTW89_UK][8] = 127, + [0][1][1][0][RTW89_FCC][10] = 127, + [0][1][1][0][RTW89_ETSI][10] = 127, + [0][1][1][0][RTW89_MKK][10] = 127, + [0][1][1][0][RTW89_IC][10] = 127, + [0][1][1][0][RTW89_KCC][10] = 127, + [0][1][1][0][RTW89_ACMA][10] = 127, + [0][1][1][0][RTW89_CN][10] = 127, + [0][1][1][0][RTW89_UK][10] = 127, + [0][1][1][0][RTW89_FCC][12] = 127, + [0][1][1][0][RTW89_ETSI][12] = 127, + [0][1][1][0][RTW89_MKK][12] = 127, + [0][1][1][0][RTW89_IC][12] = 127, + [0][1][1][0][RTW89_KCC][12] = 127, + [0][1][1][0][RTW89_ACMA][12] = 127, + [0][1][1][0][RTW89_CN][12] = 127, + [0][1][1][0][RTW89_UK][12] = 127, + [0][1][1][0][RTW89_FCC][14] = 127, + [0][1][1][0][RTW89_ETSI][14] = 127, + [0][1][1][0][RTW89_MKK][14] = 127, + [0][1][1][0][RTW89_IC][14] = 127, + [0][1][1][0][RTW89_KCC][14] = 127, + [0][1][1][0][RTW89_ACMA][14] = 127, + [0][1][1][0][RTW89_CN][14] = 127, + [0][1][1][0][RTW89_UK][14] = 127, + [0][1][1][0][RTW89_FCC][15] = 127, + [0][1][1][0][RTW89_ETSI][15] = 127, + [0][1][1][0][RTW89_MKK][15] = 127, + [0][1][1][0][RTW89_IC][15] = 127, + [0][1][1][0][RTW89_KCC][15] = 127, + [0][1][1][0][RTW89_ACMA][15] = 127, + [0][1][1][0][RTW89_CN][15] = 127, + [0][1][1][0][RTW89_UK][15] = 127, + [0][1][1][0][RTW89_FCC][17] = 127, + [0][1][1][0][RTW89_ETSI][17] = 127, + [0][1][1][0][RTW89_MKK][17] = 127, + [0][1][1][0][RTW89_IC][17] = 127, + [0][1][1][0][RTW89_KCC][17] = 127, + [0][1][1][0][RTW89_ACMA][17] = 127, + [0][1][1][0][RTW89_CN][17] = 127, + [0][1][1][0][RTW89_UK][17] = 127, + [0][1][1][0][RTW89_FCC][19] = 127, + [0][1][1][0][RTW89_ETSI][19] = 127, + [0][1][1][0][RTW89_MKK][19] = 127, + [0][1][1][0][RTW89_IC][19] = 127, + [0][1][1][0][RTW89_KCC][19] = 127, + [0][1][1][0][RTW89_ACMA][19] = 127, + [0][1][1][0][RTW89_CN][19] = 127, + [0][1][1][0][RTW89_UK][19] = 127, + [0][1][1][0][RTW89_FCC][21] = 127, + [0][1][1][0][RTW89_ETSI][21] = 127, + [0][1][1][0][RTW89_MKK][21] = 127, + [0][1][1][0][RTW89_IC][21] = 127, + [0][1][1][0][RTW89_KCC][21] = 127, + [0][1][1][0][RTW89_ACMA][21] = 127, + [0][1][1][0][RTW89_CN][21] = 127, + [0][1][1][0][RTW89_UK][21] = 127, + [0][1][1][0][RTW89_FCC][23] = 127, + [0][1][1][0][RTW89_ETSI][23] = 127, + [0][1][1][0][RTW89_MKK][23] = 127, + [0][1][1][0][RTW89_IC][23] = 127, + [0][1][1][0][RTW89_KCC][23] = 127, + [0][1][1][0][RTW89_ACMA][23] = 127, + [0][1][1][0][RTW89_CN][23] = 127, + [0][1][1][0][RTW89_UK][23] = 127, + [0][1][1][0][RTW89_FCC][25] = 127, + [0][1][1][0][RTW89_ETSI][25] = 127, + [0][1][1][0][RTW89_MKK][25] = 127, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_KCC][25] = 127, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_CN][25] = 127, + [0][1][1][0][RTW89_UK][25] = 127, + [0][1][1][0][RTW89_FCC][27] = 127, + [0][1][1][0][RTW89_ETSI][27] = 127, + [0][1][1][0][RTW89_MKK][27] = 127, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_KCC][27] = 127, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_CN][27] = 127, + [0][1][1][0][RTW89_UK][27] = 127, + [0][1][1][0][RTW89_FCC][29] = 127, + [0][1][1][0][RTW89_ETSI][29] = 127, + [0][1][1][0][RTW89_MKK][29] = 127, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_KCC][29] = 127, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_CN][29] = 127, + [0][1][1][0][RTW89_UK][29] = 127, + [0][1][1][0][RTW89_FCC][31] = 127, + [0][1][1][0][RTW89_ETSI][31] = 127, + [0][1][1][0][RTW89_MKK][31] = 127, + [0][1][1][0][RTW89_IC][31] = 127, + [0][1][1][0][RTW89_KCC][31] = 127, + [0][1][1][0][RTW89_ACMA][31] = 127, + [0][1][1][0][RTW89_CN][31] = 127, + [0][1][1][0][RTW89_UK][31] = 127, + [0][1][1][0][RTW89_FCC][33] = 127, + [0][1][1][0][RTW89_ETSI][33] = 127, + [0][1][1][0][RTW89_MKK][33] = 127, + [0][1][1][0][RTW89_IC][33] = 127, + [0][1][1][0][RTW89_KCC][33] = 127, + [0][1][1][0][RTW89_ACMA][33] = 127, + [0][1][1][0][RTW89_CN][33] = 127, + [0][1][1][0][RTW89_UK][33] = 127, + [0][1][1][0][RTW89_FCC][35] = 127, + [0][1][1][0][RTW89_ETSI][35] = 127, + [0][1][1][0][RTW89_MKK][35] = 127, + [0][1][1][0][RTW89_IC][35] = 127, + [0][1][1][0][RTW89_KCC][35] = 127, + [0][1][1][0][RTW89_ACMA][35] = 127, + [0][1][1][0][RTW89_CN][35] = 127, + [0][1][1][0][RTW89_UK][35] = 127, + [0][1][1][0][RTW89_FCC][37] = 127, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 127, + [0][1][1][0][RTW89_IC][37] = 127, + [0][1][1][0][RTW89_KCC][37] = 127, + [0][1][1][0][RTW89_ACMA][37] = 127, + [0][1][1][0][RTW89_CN][37] = 127, + [0][1][1][0][RTW89_UK][37] = 127, + [0][1][1][0][RTW89_FCC][38] = 127, + [0][1][1][0][RTW89_ETSI][38] = 127, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 127, + [0][1][1][0][RTW89_KCC][38] = 127, + [0][1][1][0][RTW89_ACMA][38] = 127, + [0][1][1][0][RTW89_CN][38] = 127, + [0][1][1][0][RTW89_UK][38] = 127, + [0][1][1][0][RTW89_FCC][40] = 127, + [0][1][1][0][RTW89_ETSI][40] = 127, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 127, + [0][1][1][0][RTW89_KCC][40] = 127, + [0][1][1][0][RTW89_ACMA][40] = 127, + [0][1][1][0][RTW89_CN][40] = 127, + [0][1][1][0][RTW89_UK][40] = 127, + [0][1][1][0][RTW89_FCC][42] = 127, + [0][1][1][0][RTW89_ETSI][42] = 127, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 127, + [0][1][1][0][RTW89_KCC][42] = 127, + [0][1][1][0][RTW89_ACMA][42] = 127, + [0][1][1][0][RTW89_CN][42] = 127, + [0][1][1][0][RTW89_UK][42] = 127, + [0][1][1][0][RTW89_FCC][44] = 127, + [0][1][1][0][RTW89_ETSI][44] = 127, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 127, + [0][1][1][0][RTW89_KCC][44] = 127, + [0][1][1][0][RTW89_ACMA][44] = 127, + [0][1][1][0][RTW89_CN][44] = 127, + [0][1][1][0][RTW89_UK][44] = 127, + [0][1][1][0][RTW89_FCC][46] = 127, + [0][1][1][0][RTW89_ETSI][46] = 127, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 127, + [0][1][1][0][RTW89_KCC][46] = 127, + [0][1][1][0][RTW89_ACMA][46] = 127, + [0][1][1][0][RTW89_CN][46] = 127, + [0][1][1][0][RTW89_UK][46] = 127, + [0][1][1][0][RTW89_FCC][48] = 127, + [0][1][1][0][RTW89_ETSI][48] = 127, + [0][1][1][0][RTW89_MKK][48] = 127, + [0][1][1][0][RTW89_IC][48] = 127, + [0][1][1][0][RTW89_KCC][48] = 127, + [0][1][1][0][RTW89_ACMA][48] = 127, + [0][1][1][0][RTW89_CN][48] = 127, + [0][1][1][0][RTW89_UK][48] = 127, + [0][1][1][0][RTW89_FCC][50] = 127, + [0][1][1][0][RTW89_ETSI][50] = 127, + [0][1][1][0][RTW89_MKK][50] = 127, + [0][1][1][0][RTW89_IC][50] = 127, + [0][1][1][0][RTW89_KCC][50] = 127, + [0][1][1][0][RTW89_ACMA][50] = 127, + [0][1][1][0][RTW89_CN][50] = 127, + [0][1][1][0][RTW89_UK][50] = 127, + [0][1][1][0][RTW89_FCC][52] = 127, + [0][1][1][0][RTW89_ETSI][52] = 127, + [0][1][1][0][RTW89_MKK][52] = 127, + [0][1][1][0][RTW89_IC][52] = 127, + [0][1][1][0][RTW89_KCC][52] = 127, + [0][1][1][0][RTW89_ACMA][52] = 127, + [0][1][1][0][RTW89_CN][52] = 127, + [0][1][1][0][RTW89_UK][52] = 127, + [0][0][2][0][RTW89_FCC][0] = 76, + [0][0][2][0][RTW89_ETSI][0] = 62, + [0][0][2][0][RTW89_MKK][0] = 62, + [0][0][2][0][RTW89_IC][0] = 64, + [0][0][2][0][RTW89_KCC][0] = 74, + [0][0][2][0][RTW89_ACMA][0] = 62, + [0][0][2][0][RTW89_CN][0] = 60, + [0][0][2][0][RTW89_UK][0] = 62, + [0][0][2][0][RTW89_FCC][2] = 78, + [0][0][2][0][RTW89_ETSI][2] = 62, + [0][0][2][0][RTW89_MKK][2] = 62, + [0][0][2][0][RTW89_IC][2] = 64, + [0][0][2][0][RTW89_KCC][2] = 74, + [0][0][2][0][RTW89_ACMA][2] = 62, + [0][0][2][0][RTW89_CN][2] = 60, + [0][0][2][0][RTW89_UK][2] = 62, + [0][0][2][0][RTW89_FCC][4] = 78, + [0][0][2][0][RTW89_ETSI][4] = 62, + [0][0][2][0][RTW89_MKK][4] = 62, + [0][0][2][0][RTW89_IC][4] = 64, + [0][0][2][0][RTW89_KCC][4] = 74, + [0][0][2][0][RTW89_ACMA][4] = 62, + [0][0][2][0][RTW89_CN][4] = 60, + [0][0][2][0][RTW89_UK][4] = 62, + [0][0][2][0][RTW89_FCC][6] = 78, + [0][0][2][0][RTW89_ETSI][6] = 62, + [0][0][2][0][RTW89_MKK][6] = 62, + [0][0][2][0][RTW89_IC][6] = 64, + [0][0][2][0][RTW89_KCC][6] = 54, + [0][0][2][0][RTW89_ACMA][6] = 62, + [0][0][2][0][RTW89_CN][6] = 60, + [0][0][2][0][RTW89_UK][6] = 62, + [0][0][2][0][RTW89_FCC][8] = 78, + [0][0][2][0][RTW89_ETSI][8] = 62, + [0][0][2][0][RTW89_MKK][8] = 62, + [0][0][2][0][RTW89_IC][8] = 64, + [0][0][2][0][RTW89_KCC][8] = 74, + [0][0][2][0][RTW89_ACMA][8] = 62, + [0][0][2][0][RTW89_CN][8] = 60, + [0][0][2][0][RTW89_UK][8] = 62, + [0][0][2][0][RTW89_FCC][10] = 78, + [0][0][2][0][RTW89_ETSI][10] = 62, + [0][0][2][0][RTW89_MKK][10] = 62, + [0][0][2][0][RTW89_IC][10] = 64, + [0][0][2][0][RTW89_KCC][10] = 74, + [0][0][2][0][RTW89_ACMA][10] = 62, + [0][0][2][0][RTW89_CN][10] = 60, + [0][0][2][0][RTW89_UK][10] = 62, + [0][0][2][0][RTW89_FCC][12] = 78, + [0][0][2][0][RTW89_ETSI][12] = 62, + [0][0][2][0][RTW89_MKK][12] = 62, + [0][0][2][0][RTW89_IC][12] = 64, + [0][0][2][0][RTW89_KCC][12] = 74, + [0][0][2][0][RTW89_ACMA][12] = 62, + [0][0][2][0][RTW89_CN][12] = 60, + [0][0][2][0][RTW89_UK][12] = 62, + [0][0][2][0][RTW89_FCC][14] = 74, + [0][0][2][0][RTW89_ETSI][14] = 62, + [0][0][2][0][RTW89_MKK][14] = 62, + [0][0][2][0][RTW89_IC][14] = 64, + [0][0][2][0][RTW89_KCC][14] = 74, + [0][0][2][0][RTW89_ACMA][14] = 62, + [0][0][2][0][RTW89_CN][14] = 60, + [0][0][2][0][RTW89_UK][14] = 62, + [0][0][2][0][RTW89_FCC][15] = 74, + [0][0][2][0][RTW89_ETSI][15] = 60, + [0][0][2][0][RTW89_MKK][15] = 74, + [0][0][2][0][RTW89_IC][15] = 74, + [0][0][2][0][RTW89_KCC][15] = 74, + [0][0][2][0][RTW89_ACMA][15] = 60, + [0][0][2][0][RTW89_CN][15] = 127, + [0][0][2][0][RTW89_UK][15] = 60, + [0][0][2][0][RTW89_FCC][17] = 78, + [0][0][2][0][RTW89_ETSI][17] = 62, + [0][0][2][0][RTW89_MKK][17] = 74, + [0][0][2][0][RTW89_IC][17] = 78, + [0][0][2][0][RTW89_KCC][17] = 74, + [0][0][2][0][RTW89_ACMA][17] = 62, + [0][0][2][0][RTW89_CN][17] = 127, + [0][0][2][0][RTW89_UK][17] = 62, + [0][0][2][0][RTW89_FCC][19] = 78, + [0][0][2][0][RTW89_ETSI][19] = 62, + [0][0][2][0][RTW89_MKK][19] = 74, + [0][0][2][0][RTW89_IC][19] = 78, + [0][0][2][0][RTW89_KCC][19] = 74, + [0][0][2][0][RTW89_ACMA][19] = 62, + [0][0][2][0][RTW89_CN][19] = 127, + [0][0][2][0][RTW89_UK][19] = 62, + [0][0][2][0][RTW89_FCC][21] = 78, + [0][0][2][0][RTW89_ETSI][21] = 62, + [0][0][2][0][RTW89_MKK][21] = 74, + [0][0][2][0][RTW89_IC][21] = 78, + [0][0][2][0][RTW89_KCC][21] = 74, + [0][0][2][0][RTW89_ACMA][21] = 62, + [0][0][2][0][RTW89_CN][21] = 127, + [0][0][2][0][RTW89_UK][21] = 62, + [0][0][2][0][RTW89_FCC][23] = 78, + [0][0][2][0][RTW89_ETSI][23] = 62, + [0][0][2][0][RTW89_MKK][23] = 74, + [0][0][2][0][RTW89_IC][23] = 78, + [0][0][2][0][RTW89_KCC][23] = 74, + [0][0][2][0][RTW89_ACMA][23] = 62, + [0][0][2][0][RTW89_CN][23] = 127, + [0][0][2][0][RTW89_UK][23] = 62, + [0][0][2][0][RTW89_FCC][25] = 78, + [0][0][2][0][RTW89_ETSI][25] = 62, + [0][0][2][0][RTW89_MKK][25] = 74, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_KCC][25] = 74, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_CN][25] = 127, + [0][0][2][0][RTW89_UK][25] = 62, + [0][0][2][0][RTW89_FCC][27] = 78, + [0][0][2][0][RTW89_ETSI][27] = 62, + [0][0][2][0][RTW89_MKK][27] = 74, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_KCC][27] = 74, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_CN][27] = 127, + [0][0][2][0][RTW89_UK][27] = 62, + [0][0][2][0][RTW89_FCC][29] = 78, + [0][0][2][0][RTW89_ETSI][29] = 62, + [0][0][2][0][RTW89_MKK][29] = 74, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_KCC][29] = 74, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_CN][29] = 127, + [0][0][2][0][RTW89_UK][29] = 62, + [0][0][2][0][RTW89_FCC][31] = 78, + [0][0][2][0][RTW89_ETSI][31] = 62, + [0][0][2][0][RTW89_MKK][31] = 74, + [0][0][2][0][RTW89_IC][31] = 78, + [0][0][2][0][RTW89_KCC][31] = 74, + [0][0][2][0][RTW89_ACMA][31] = 62, + [0][0][2][0][RTW89_CN][31] = 127, + [0][0][2][0][RTW89_UK][31] = 62, + [0][0][2][0][RTW89_FCC][33] = 78, + [0][0][2][0][RTW89_ETSI][33] = 62, + [0][0][2][0][RTW89_MKK][33] = 74, + [0][0][2][0][RTW89_IC][33] = 78, + [0][0][2][0][RTW89_KCC][33] = 74, + [0][0][2][0][RTW89_ACMA][33] = 62, + [0][0][2][0][RTW89_CN][33] = 127, + [0][0][2][0][RTW89_UK][33] = 62, + [0][0][2][0][RTW89_FCC][35] = 72, + [0][0][2][0][RTW89_ETSI][35] = 62, + [0][0][2][0][RTW89_MKK][35] = 74, + [0][0][2][0][RTW89_IC][35] = 72, + [0][0][2][0][RTW89_KCC][35] = 74, + [0][0][2][0][RTW89_ACMA][35] = 62, + [0][0][2][0][RTW89_CN][35] = 127, + [0][0][2][0][RTW89_UK][35] = 62, + [0][0][2][0][RTW89_FCC][37] = 78, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 74, + [0][0][2][0][RTW89_IC][37] = 78, + [0][0][2][0][RTW89_KCC][37] = 74, + [0][0][2][0][RTW89_ACMA][37] = 74, + [0][0][2][0][RTW89_CN][37] = 127, + [0][0][2][0][RTW89_UK][37] = 74, + [0][0][2][0][RTW89_FCC][38] = 78, + [0][0][2][0][RTW89_ETSI][38] = 30, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 78, + [0][0][2][0][RTW89_KCC][38] = 66, + [0][0][2][0][RTW89_ACMA][38] = 74, + [0][0][2][0][RTW89_CN][38] = 66, + [0][0][2][0][RTW89_UK][38] = 60, + [0][0][2][0][RTW89_FCC][40] = 78, + [0][0][2][0][RTW89_ETSI][40] = 30, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 78, + [0][0][2][0][RTW89_KCC][40] = 74, + [0][0][2][0][RTW89_ACMA][40] = 74, + [0][0][2][0][RTW89_CN][40] = 66, + [0][0][2][0][RTW89_UK][40] = 60, + [0][0][2][0][RTW89_FCC][42] = 78, + [0][0][2][0][RTW89_ETSI][42] = 30, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 78, + [0][0][2][0][RTW89_KCC][42] = 74, + [0][0][2][0][RTW89_ACMA][42] = 74, + [0][0][2][0][RTW89_CN][42] = 66, + [0][0][2][0][RTW89_UK][42] = 60, + [0][0][2][0][RTW89_FCC][44] = 78, + [0][0][2][0][RTW89_ETSI][44] = 30, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 78, + [0][0][2][0][RTW89_KCC][44] = 74, + [0][0][2][0][RTW89_ACMA][44] = 74, + [0][0][2][0][RTW89_CN][44] = 64, + [0][0][2][0][RTW89_UK][44] = 60, + [0][0][2][0][RTW89_FCC][46] = 78, + [0][0][2][0][RTW89_ETSI][46] = 30, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 78, + [0][0][2][0][RTW89_KCC][46] = 74, + [0][0][2][0][RTW89_ACMA][46] = 74, + [0][0][2][0][RTW89_CN][46] = 64, + [0][0][2][0][RTW89_UK][46] = 60, + [0][0][2][0][RTW89_FCC][48] = 74, + [0][0][2][0][RTW89_ETSI][48] = 127, + [0][0][2][0][RTW89_MKK][48] = 127, + [0][0][2][0][RTW89_IC][48] = 74, + [0][0][2][0][RTW89_KCC][48] = 127, + [0][0][2][0][RTW89_ACMA][48] = 127, + [0][0][2][0][RTW89_CN][48] = 127, + [0][0][2][0][RTW89_UK][48] = 127, + [0][0][2][0][RTW89_FCC][50] = 74, + [0][0][2][0][RTW89_ETSI][50] = 127, + [0][0][2][0][RTW89_MKK][50] = 127, + [0][0][2][0][RTW89_IC][50] = 74, + [0][0][2][0][RTW89_KCC][50] = 127, + [0][0][2][0][RTW89_ACMA][50] = 127, + [0][0][2][0][RTW89_CN][50] = 127, + [0][0][2][0][RTW89_UK][50] = 127, + [0][0][2][0][RTW89_FCC][52] = 74, + [0][0][2][0][RTW89_ETSI][52] = 127, + [0][0][2][0][RTW89_MKK][52] = 127, + [0][0][2][0][RTW89_IC][52] = 74, + [0][0][2][0][RTW89_KCC][52] = 127, + [0][0][2][0][RTW89_ACMA][52] = 127, + [0][0][2][0][RTW89_CN][52] = 127, + [0][0][2][0][RTW89_UK][52] = 127, + [0][1][2][0][RTW89_FCC][0] = 127, + [0][1][2][0][RTW89_ETSI][0] = 127, + [0][1][2][0][RTW89_MKK][0] = 127, + [0][1][2][0][RTW89_IC][0] = 127, + [0][1][2][0][RTW89_KCC][0] = 127, + [0][1][2][0][RTW89_ACMA][0] = 127, + [0][1][2][0][RTW89_CN][0] = 127, + [0][1][2][0][RTW89_UK][0] = 127, + [0][1][2][0][RTW89_FCC][2] = 127, + [0][1][2][0][RTW89_ETSI][2] = 127, + [0][1][2][0][RTW89_MKK][2] = 127, + [0][1][2][0][RTW89_IC][2] = 127, + [0][1][2][0][RTW89_KCC][2] = 127, + [0][1][2][0][RTW89_ACMA][2] = 127, + [0][1][2][0][RTW89_CN][2] = 127, + [0][1][2][0][RTW89_UK][2] = 127, + [0][1][2][0][RTW89_FCC][4] = 127, + [0][1][2][0][RTW89_ETSI][4] = 127, + [0][1][2][0][RTW89_MKK][4] = 127, + [0][1][2][0][RTW89_IC][4] = 127, + [0][1][2][0][RTW89_KCC][4] = 127, + [0][1][2][0][RTW89_ACMA][4] = 127, + [0][1][2][0][RTW89_CN][4] = 127, + [0][1][2][0][RTW89_UK][4] = 127, + [0][1][2][0][RTW89_FCC][6] = 127, + [0][1][2][0][RTW89_ETSI][6] = 127, + [0][1][2][0][RTW89_MKK][6] = 127, + [0][1][2][0][RTW89_IC][6] = 127, + [0][1][2][0][RTW89_KCC][6] = 127, + [0][1][2][0][RTW89_ACMA][6] = 127, + [0][1][2][0][RTW89_CN][6] = 127, + [0][1][2][0][RTW89_UK][6] = 127, + [0][1][2][0][RTW89_FCC][8] = 127, + [0][1][2][0][RTW89_ETSI][8] = 127, + [0][1][2][0][RTW89_MKK][8] = 127, + [0][1][2][0][RTW89_IC][8] = 127, + [0][1][2][0][RTW89_KCC][8] = 127, + [0][1][2][0][RTW89_ACMA][8] = 127, + [0][1][2][0][RTW89_CN][8] = 127, + [0][1][2][0][RTW89_UK][8] = 127, + [0][1][2][0][RTW89_FCC][10] = 127, + [0][1][2][0][RTW89_ETSI][10] = 127, + [0][1][2][0][RTW89_MKK][10] = 127, + [0][1][2][0][RTW89_IC][10] = 127, + [0][1][2][0][RTW89_KCC][10] = 127, + [0][1][2][0][RTW89_ACMA][10] = 127, + [0][1][2][0][RTW89_CN][10] = 127, + [0][1][2][0][RTW89_UK][10] = 127, + [0][1][2][0][RTW89_FCC][12] = 127, + [0][1][2][0][RTW89_ETSI][12] = 127, + [0][1][2][0][RTW89_MKK][12] = 127, + [0][1][2][0][RTW89_IC][12] = 127, + [0][1][2][0][RTW89_KCC][12] = 127, + [0][1][2][0][RTW89_ACMA][12] = 127, + [0][1][2][0][RTW89_CN][12] = 127, + [0][1][2][0][RTW89_UK][12] = 127, + [0][1][2][0][RTW89_FCC][14] = 127, + [0][1][2][0][RTW89_ETSI][14] = 127, + [0][1][2][0][RTW89_MKK][14] = 127, + [0][1][2][0][RTW89_IC][14] = 127, + [0][1][2][0][RTW89_KCC][14] = 127, + [0][1][2][0][RTW89_ACMA][14] = 127, + [0][1][2][0][RTW89_CN][14] = 127, + [0][1][2][0][RTW89_UK][14] = 127, + [0][1][2][0][RTW89_FCC][15] = 127, + [0][1][2][0][RTW89_ETSI][15] = 127, + [0][1][2][0][RTW89_MKK][15] = 127, + [0][1][2][0][RTW89_IC][15] = 127, + [0][1][2][0][RTW89_KCC][15] = 127, + [0][1][2][0][RTW89_ACMA][15] = 127, + [0][1][2][0][RTW89_CN][15] = 127, + [0][1][2][0][RTW89_UK][15] = 127, + [0][1][2][0][RTW89_FCC][17] = 127, + [0][1][2][0][RTW89_ETSI][17] = 127, + [0][1][2][0][RTW89_MKK][17] = 127, + [0][1][2][0][RTW89_IC][17] = 127, + [0][1][2][0][RTW89_KCC][17] = 127, + [0][1][2][0][RTW89_ACMA][17] = 127, + [0][1][2][0][RTW89_CN][17] = 127, + [0][1][2][0][RTW89_UK][17] = 127, + [0][1][2][0][RTW89_FCC][19] = 127, + [0][1][2][0][RTW89_ETSI][19] = 127, + [0][1][2][0][RTW89_MKK][19] = 127, + [0][1][2][0][RTW89_IC][19] = 127, + [0][1][2][0][RTW89_KCC][19] = 127, + [0][1][2][0][RTW89_ACMA][19] = 127, + [0][1][2][0][RTW89_CN][19] = 127, + [0][1][2][0][RTW89_UK][19] = 127, + [0][1][2][0][RTW89_FCC][21] = 127, + [0][1][2][0][RTW89_ETSI][21] = 127, + [0][1][2][0][RTW89_MKK][21] = 127, + [0][1][2][0][RTW89_IC][21] = 127, + [0][1][2][0][RTW89_KCC][21] = 127, + [0][1][2][0][RTW89_ACMA][21] = 127, + [0][1][2][0][RTW89_CN][21] = 127, + [0][1][2][0][RTW89_UK][21] = 127, + [0][1][2][0][RTW89_FCC][23] = 127, + [0][1][2][0][RTW89_ETSI][23] = 127, + [0][1][2][0][RTW89_MKK][23] = 127, + [0][1][2][0][RTW89_IC][23] = 127, + [0][1][2][0][RTW89_KCC][23] = 127, + [0][1][2][0][RTW89_ACMA][23] = 127, + [0][1][2][0][RTW89_CN][23] = 127, + [0][1][2][0][RTW89_UK][23] = 127, + [0][1][2][0][RTW89_FCC][25] = 127, + [0][1][2][0][RTW89_ETSI][25] = 127, + [0][1][2][0][RTW89_MKK][25] = 127, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_KCC][25] = 127, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_CN][25] = 127, + [0][1][2][0][RTW89_UK][25] = 127, + [0][1][2][0][RTW89_FCC][27] = 127, + [0][1][2][0][RTW89_ETSI][27] = 127, + [0][1][2][0][RTW89_MKK][27] = 127, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_KCC][27] = 127, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_CN][27] = 127, + [0][1][2][0][RTW89_UK][27] = 127, + [0][1][2][0][RTW89_FCC][29] = 127, + [0][1][2][0][RTW89_ETSI][29] = 127, + [0][1][2][0][RTW89_MKK][29] = 127, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_KCC][29] = 127, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_CN][29] = 127, + [0][1][2][0][RTW89_UK][29] = 127, + [0][1][2][0][RTW89_FCC][31] = 127, + [0][1][2][0][RTW89_ETSI][31] = 127, + [0][1][2][0][RTW89_MKK][31] = 127, + [0][1][2][0][RTW89_IC][31] = 127, + [0][1][2][0][RTW89_KCC][31] = 127, + [0][1][2][0][RTW89_ACMA][31] = 127, + [0][1][2][0][RTW89_CN][31] = 127, + [0][1][2][0][RTW89_UK][31] = 127, + [0][1][2][0][RTW89_FCC][33] = 127, + [0][1][2][0][RTW89_ETSI][33] = 127, + [0][1][2][0][RTW89_MKK][33] = 127, + [0][1][2][0][RTW89_IC][33] = 127, + [0][1][2][0][RTW89_KCC][33] = 127, + [0][1][2][0][RTW89_ACMA][33] = 127, + [0][1][2][0][RTW89_CN][33] = 127, + [0][1][2][0][RTW89_UK][33] = 127, + [0][1][2][0][RTW89_FCC][35] = 127, + [0][1][2][0][RTW89_ETSI][35] = 127, + [0][1][2][0][RTW89_MKK][35] = 127, + [0][1][2][0][RTW89_IC][35] = 127, + [0][1][2][0][RTW89_KCC][35] = 127, + [0][1][2][0][RTW89_ACMA][35] = 127, + [0][1][2][0][RTW89_CN][35] = 127, + [0][1][2][0][RTW89_UK][35] = 127, + [0][1][2][0][RTW89_FCC][37] = 127, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 127, + [0][1][2][0][RTW89_IC][37] = 127, + [0][1][2][0][RTW89_KCC][37] = 127, + [0][1][2][0][RTW89_ACMA][37] = 127, + [0][1][2][0][RTW89_CN][37] = 127, + [0][1][2][0][RTW89_UK][37] = 127, + [0][1][2][0][RTW89_FCC][38] = 127, + [0][1][2][0][RTW89_ETSI][38] = 127, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 127, + [0][1][2][0][RTW89_KCC][38] = 127, + [0][1][2][0][RTW89_ACMA][38] = 127, + [0][1][2][0][RTW89_CN][38] = 127, + [0][1][2][0][RTW89_UK][38] = 127, + [0][1][2][0][RTW89_FCC][40] = 127, + [0][1][2][0][RTW89_ETSI][40] = 127, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 127, + [0][1][2][0][RTW89_KCC][40] = 127, + [0][1][2][0][RTW89_ACMA][40] = 127, + [0][1][2][0][RTW89_CN][40] = 127, + [0][1][2][0][RTW89_UK][40] = 127, + [0][1][2][0][RTW89_FCC][42] = 127, + [0][1][2][0][RTW89_ETSI][42] = 127, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 127, + [0][1][2][0][RTW89_KCC][42] = 127, + [0][1][2][0][RTW89_ACMA][42] = 127, + [0][1][2][0][RTW89_CN][42] = 127, + [0][1][2][0][RTW89_UK][42] = 127, + [0][1][2][0][RTW89_FCC][44] = 127, + [0][1][2][0][RTW89_ETSI][44] = 127, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 127, + [0][1][2][0][RTW89_KCC][44] = 127, + [0][1][2][0][RTW89_ACMA][44] = 127, + [0][1][2][0][RTW89_CN][44] = 127, + [0][1][2][0][RTW89_UK][44] = 127, + [0][1][2][0][RTW89_FCC][46] = 127, + [0][1][2][0][RTW89_ETSI][46] = 127, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 127, + [0][1][2][0][RTW89_KCC][46] = 127, + [0][1][2][0][RTW89_ACMA][46] = 127, + [0][1][2][0][RTW89_CN][46] = 127, + [0][1][2][0][RTW89_UK][46] = 127, + [0][1][2][0][RTW89_FCC][48] = 127, + [0][1][2][0][RTW89_ETSI][48] = 127, + [0][1][2][0][RTW89_MKK][48] = 127, + [0][1][2][0][RTW89_IC][48] = 127, + [0][1][2][0][RTW89_KCC][48] = 127, + [0][1][2][0][RTW89_ACMA][48] = 127, + [0][1][2][0][RTW89_CN][48] = 127, + [0][1][2][0][RTW89_UK][48] = 127, + [0][1][2][0][RTW89_FCC][50] = 127, + [0][1][2][0][RTW89_ETSI][50] = 127, + [0][1][2][0][RTW89_MKK][50] = 127, + [0][1][2][0][RTW89_IC][50] = 127, + [0][1][2][0][RTW89_KCC][50] = 127, + [0][1][2][0][RTW89_ACMA][50] = 127, + [0][1][2][0][RTW89_CN][50] = 127, + [0][1][2][0][RTW89_UK][50] = 127, + [0][1][2][0][RTW89_FCC][52] = 127, + [0][1][2][0][RTW89_ETSI][52] = 127, + [0][1][2][0][RTW89_MKK][52] = 127, + [0][1][2][0][RTW89_IC][52] = 127, + [0][1][2][0][RTW89_KCC][52] = 127, + [0][1][2][0][RTW89_ACMA][52] = 127, + [0][1][2][0][RTW89_CN][52] = 127, + [0][1][2][0][RTW89_UK][52] = 127, + [0][1][2][1][RTW89_FCC][0] = 127, + [0][1][2][1][RTW89_ETSI][0] = 127, + [0][1][2][1][RTW89_MKK][0] = 127, + [0][1][2][1][RTW89_IC][0] = 127, + [0][1][2][1][RTW89_KCC][0] = 127, + [0][1][2][1][RTW89_ACMA][0] = 127, + [0][1][2][1][RTW89_CN][0] = 127, + [0][1][2][1][RTW89_UK][0] = 127, + [0][1][2][1][RTW89_FCC][2] = 127, + [0][1][2][1][RTW89_ETSI][2] = 127, + [0][1][2][1][RTW89_MKK][2] = 127, + [0][1][2][1][RTW89_IC][2] = 127, + [0][1][2][1][RTW89_KCC][2] = 127, + [0][1][2][1][RTW89_ACMA][2] = 127, + [0][1][2][1][RTW89_CN][2] = 127, + [0][1][2][1][RTW89_UK][2] = 127, + [0][1][2][1][RTW89_FCC][4] = 127, + [0][1][2][1][RTW89_ETSI][4] = 127, + [0][1][2][1][RTW89_MKK][4] = 127, + [0][1][2][1][RTW89_IC][4] = 127, + [0][1][2][1][RTW89_KCC][4] = 127, + [0][1][2][1][RTW89_ACMA][4] = 127, + [0][1][2][1][RTW89_CN][4] = 127, + [0][1][2][1][RTW89_UK][4] = 127, + [0][1][2][1][RTW89_FCC][6] = 127, + [0][1][2][1][RTW89_ETSI][6] = 127, + [0][1][2][1][RTW89_MKK][6] = 127, + [0][1][2][1][RTW89_IC][6] = 127, + [0][1][2][1][RTW89_KCC][6] = 127, + [0][1][2][1][RTW89_ACMA][6] = 127, + [0][1][2][1][RTW89_CN][6] = 127, + [0][1][2][1][RTW89_UK][6] = 127, + [0][1][2][1][RTW89_FCC][8] = 127, + [0][1][2][1][RTW89_ETSI][8] = 127, + [0][1][2][1][RTW89_MKK][8] = 127, + [0][1][2][1][RTW89_IC][8] = 127, + [0][1][2][1][RTW89_KCC][8] = 127, + [0][1][2][1][RTW89_ACMA][8] = 127, + [0][1][2][1][RTW89_CN][8] = 127, + [0][1][2][1][RTW89_UK][8] = 127, + [0][1][2][1][RTW89_FCC][10] = 127, + [0][1][2][1][RTW89_ETSI][10] = 127, + [0][1][2][1][RTW89_MKK][10] = 127, + [0][1][2][1][RTW89_IC][10] = 127, + [0][1][2][1][RTW89_KCC][10] = 127, + [0][1][2][1][RTW89_ACMA][10] = 127, + [0][1][2][1][RTW89_CN][10] = 127, + [0][1][2][1][RTW89_UK][10] = 127, + [0][1][2][1][RTW89_FCC][12] = 127, + [0][1][2][1][RTW89_ETSI][12] = 127, + [0][1][2][1][RTW89_MKK][12] = 127, + [0][1][2][1][RTW89_IC][12] = 127, + [0][1][2][1][RTW89_KCC][12] = 127, + [0][1][2][1][RTW89_ACMA][12] = 127, + [0][1][2][1][RTW89_CN][12] = 127, + [0][1][2][1][RTW89_UK][12] = 127, + [0][1][2][1][RTW89_FCC][14] = 127, + [0][1][2][1][RTW89_ETSI][14] = 127, + [0][1][2][1][RTW89_MKK][14] = 127, + [0][1][2][1][RTW89_IC][14] = 127, + [0][1][2][1][RTW89_KCC][14] = 127, + [0][1][2][1][RTW89_ACMA][14] = 127, + [0][1][2][1][RTW89_CN][14] = 127, + [0][1][2][1][RTW89_UK][14] = 127, + [0][1][2][1][RTW89_FCC][15] = 127, + [0][1][2][1][RTW89_ETSI][15] = 127, + [0][1][2][1][RTW89_MKK][15] = 127, + [0][1][2][1][RTW89_IC][15] = 127, + [0][1][2][1][RTW89_KCC][15] = 127, + [0][1][2][1][RTW89_ACMA][15] = 127, + [0][1][2][1][RTW89_CN][15] = 127, + [0][1][2][1][RTW89_UK][15] = 127, + [0][1][2][1][RTW89_FCC][17] = 127, + [0][1][2][1][RTW89_ETSI][17] = 127, + [0][1][2][1][RTW89_MKK][17] = 127, + [0][1][2][1][RTW89_IC][17] = 127, + [0][1][2][1][RTW89_KCC][17] = 127, + [0][1][2][1][RTW89_ACMA][17] = 127, + [0][1][2][1][RTW89_CN][17] = 127, + [0][1][2][1][RTW89_UK][17] = 127, + [0][1][2][1][RTW89_FCC][19] = 127, + [0][1][2][1][RTW89_ETSI][19] = 127, + [0][1][2][1][RTW89_MKK][19] = 127, + [0][1][2][1][RTW89_IC][19] = 127, + [0][1][2][1][RTW89_KCC][19] = 127, + [0][1][2][1][RTW89_ACMA][19] = 127, + [0][1][2][1][RTW89_CN][19] = 127, + [0][1][2][1][RTW89_UK][19] = 127, + [0][1][2][1][RTW89_FCC][21] = 127, + [0][1][2][1][RTW89_ETSI][21] = 127, + [0][1][2][1][RTW89_MKK][21] = 127, + [0][1][2][1][RTW89_IC][21] = 127, + [0][1][2][1][RTW89_KCC][21] = 127, + [0][1][2][1][RTW89_ACMA][21] = 127, + [0][1][2][1][RTW89_CN][21] = 127, + [0][1][2][1][RTW89_UK][21] = 127, + [0][1][2][1][RTW89_FCC][23] = 127, + [0][1][2][1][RTW89_ETSI][23] = 127, + [0][1][2][1][RTW89_MKK][23] = 127, + [0][1][2][1][RTW89_IC][23] = 127, + [0][1][2][1][RTW89_KCC][23] = 127, + [0][1][2][1][RTW89_ACMA][23] = 127, + [0][1][2][1][RTW89_CN][23] = 127, + [0][1][2][1][RTW89_UK][23] = 127, + [0][1][2][1][RTW89_FCC][25] = 127, + [0][1][2][1][RTW89_ETSI][25] = 127, + [0][1][2][1][RTW89_MKK][25] = 127, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_KCC][25] = 127, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_CN][25] = 127, + [0][1][2][1][RTW89_UK][25] = 127, + [0][1][2][1][RTW89_FCC][27] = 127, + [0][1][2][1][RTW89_ETSI][27] = 127, + [0][1][2][1][RTW89_MKK][27] = 127, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_KCC][27] = 127, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_CN][27] = 127, + [0][1][2][1][RTW89_UK][27] = 127, + [0][1][2][1][RTW89_FCC][29] = 127, + [0][1][2][1][RTW89_ETSI][29] = 127, + [0][1][2][1][RTW89_MKK][29] = 127, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_KCC][29] = 127, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_CN][29] = 127, + [0][1][2][1][RTW89_UK][29] = 127, + [0][1][2][1][RTW89_FCC][31] = 127, + [0][1][2][1][RTW89_ETSI][31] = 127, + [0][1][2][1][RTW89_MKK][31] = 127, + [0][1][2][1][RTW89_IC][31] = 127, + [0][1][2][1][RTW89_KCC][31] = 127, + [0][1][2][1][RTW89_ACMA][31] = 127, + [0][1][2][1][RTW89_CN][31] = 127, + [0][1][2][1][RTW89_UK][31] = 127, + [0][1][2][1][RTW89_FCC][33] = 127, + [0][1][2][1][RTW89_ETSI][33] = 127, + [0][1][2][1][RTW89_MKK][33] = 127, + [0][1][2][1][RTW89_IC][33] = 127, + [0][1][2][1][RTW89_KCC][33] = 127, + [0][1][2][1][RTW89_ACMA][33] = 127, + [0][1][2][1][RTW89_CN][33] = 127, + [0][1][2][1][RTW89_UK][33] = 127, + [0][1][2][1][RTW89_FCC][35] = 127, + [0][1][2][1][RTW89_ETSI][35] = 127, + [0][1][2][1][RTW89_MKK][35] = 127, + [0][1][2][1][RTW89_IC][35] = 127, + [0][1][2][1][RTW89_KCC][35] = 127, + [0][1][2][1][RTW89_ACMA][35] = 127, + [0][1][2][1][RTW89_CN][35] = 127, + [0][1][2][1][RTW89_UK][35] = 127, + [0][1][2][1][RTW89_FCC][37] = 127, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 127, + [0][1][2][1][RTW89_IC][37] = 127, + [0][1][2][1][RTW89_KCC][37] = 127, + [0][1][2][1][RTW89_ACMA][37] = 127, + [0][1][2][1][RTW89_CN][37] = 127, + [0][1][2][1][RTW89_UK][37] = 127, + [0][1][2][1][RTW89_FCC][38] = 127, + [0][1][2][1][RTW89_ETSI][38] = 127, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 127, + [0][1][2][1][RTW89_KCC][38] = 127, + [0][1][2][1][RTW89_ACMA][38] = 127, + [0][1][2][1][RTW89_CN][38] = 127, + [0][1][2][1][RTW89_UK][38] = 127, + [0][1][2][1][RTW89_FCC][40] = 127, + [0][1][2][1][RTW89_ETSI][40] = 127, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 127, + [0][1][2][1][RTW89_KCC][40] = 127, + [0][1][2][1][RTW89_ACMA][40] = 127, + [0][1][2][1][RTW89_CN][40] = 127, + [0][1][2][1][RTW89_UK][40] = 127, + [0][1][2][1][RTW89_FCC][42] = 127, + [0][1][2][1][RTW89_ETSI][42] = 127, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 127, + [0][1][2][1][RTW89_KCC][42] = 127, + [0][1][2][1][RTW89_ACMA][42] = 127, + [0][1][2][1][RTW89_CN][42] = 127, + [0][1][2][1][RTW89_UK][42] = 127, + [0][1][2][1][RTW89_FCC][44] = 127, + [0][1][2][1][RTW89_ETSI][44] = 127, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 127, + [0][1][2][1][RTW89_KCC][44] = 127, + [0][1][2][1][RTW89_ACMA][44] = 127, + [0][1][2][1][RTW89_CN][44] = 127, + [0][1][2][1][RTW89_UK][44] = 127, + [0][1][2][1][RTW89_FCC][46] = 127, + [0][1][2][1][RTW89_ETSI][46] = 127, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 127, + [0][1][2][1][RTW89_KCC][46] = 127, + [0][1][2][1][RTW89_ACMA][46] = 127, + [0][1][2][1][RTW89_CN][46] = 127, + [0][1][2][1][RTW89_UK][46] = 127, + [0][1][2][1][RTW89_FCC][48] = 127, + [0][1][2][1][RTW89_ETSI][48] = 127, + [0][1][2][1][RTW89_MKK][48] = 127, + [0][1][2][1][RTW89_IC][48] = 127, + [0][1][2][1][RTW89_KCC][48] = 127, + [0][1][2][1][RTW89_ACMA][48] = 127, + [0][1][2][1][RTW89_CN][48] = 127, + [0][1][2][1][RTW89_UK][48] = 127, + [0][1][2][1][RTW89_FCC][50] = 127, + [0][1][2][1][RTW89_ETSI][50] = 127, + [0][1][2][1][RTW89_MKK][50] = 127, + [0][1][2][1][RTW89_IC][50] = 127, + [0][1][2][1][RTW89_KCC][50] = 127, + [0][1][2][1][RTW89_ACMA][50] = 127, + [0][1][2][1][RTW89_CN][50] = 127, + [0][1][2][1][RTW89_UK][50] = 127, + [0][1][2][1][RTW89_FCC][52] = 127, + [0][1][2][1][RTW89_ETSI][52] = 127, + [0][1][2][1][RTW89_MKK][52] = 127, + [0][1][2][1][RTW89_IC][52] = 127, + [0][1][2][1][RTW89_KCC][52] = 127, + [0][1][2][1][RTW89_ACMA][52] = 127, + [0][1][2][1][RTW89_CN][52] = 127, + [0][1][2][1][RTW89_UK][52] = 127, + [1][0][2][0][RTW89_FCC][1] = 66, + [1][0][2][0][RTW89_ETSI][1] = 64, + [1][0][2][0][RTW89_MKK][1] = 64, + [1][0][2][0][RTW89_IC][1] = 64, + [1][0][2][0][RTW89_KCC][1] = 74, + [1][0][2][0][RTW89_ACMA][1] = 64, + [1][0][2][0][RTW89_CN][1] = 66, + [1][0][2][0][RTW89_UK][1] = 64, + [1][0][2][0][RTW89_FCC][5] = 80, + [1][0][2][0][RTW89_ETSI][5] = 64, + [1][0][2][0][RTW89_MKK][5] = 62, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 66, + [1][0][2][0][RTW89_ACMA][5] = 64, + [1][0][2][0][RTW89_CN][5] = 66, + [1][0][2][0][RTW89_UK][5] = 64, + [1][0][2][0][RTW89_FCC][9] = 80, + [1][0][2][0][RTW89_ETSI][9] = 64, + [1][0][2][0][RTW89_MKK][9] = 64, + [1][0][2][0][RTW89_IC][9] = 64, + [1][0][2][0][RTW89_KCC][9] = 76, + [1][0][2][0][RTW89_ACMA][9] = 64, + [1][0][2][0][RTW89_CN][9] = 58, + [1][0][2][0][RTW89_UK][9] = 64, + [1][0][2][0][RTW89_FCC][13] = 64, + [1][0][2][0][RTW89_ETSI][13] = 64, + [1][0][2][0][RTW89_MKK][13] = 64, + [1][0][2][0][RTW89_IC][13] = 64, + [1][0][2][0][RTW89_KCC][13] = 72, + [1][0][2][0][RTW89_ACMA][13] = 64, + [1][0][2][0][RTW89_CN][13] = 58, + [1][0][2][0][RTW89_UK][13] = 64, + [1][0][2][0][RTW89_FCC][16] = 66, + [1][0][2][0][RTW89_ETSI][16] = 66, + [1][0][2][0][RTW89_MKK][16] = 76, + [1][0][2][0][RTW89_IC][16] = 66, + [1][0][2][0][RTW89_KCC][16] = 74, + [1][0][2][0][RTW89_ACMA][16] = 66, + [1][0][2][0][RTW89_CN][16] = 127, + [1][0][2][0][RTW89_UK][16] = 66, + [1][0][2][0][RTW89_FCC][20] = 80, + [1][0][2][0][RTW89_ETSI][20] = 66, + [1][0][2][0][RTW89_MKK][20] = 76, + [1][0][2][0][RTW89_IC][20] = 80, + [1][0][2][0][RTW89_KCC][20] = 74, + [1][0][2][0][RTW89_ACMA][20] = 66, + [1][0][2][0][RTW89_CN][20] = 127, + [1][0][2][0][RTW89_UK][20] = 66, + [1][0][2][0][RTW89_FCC][24] = 80, + [1][0][2][0][RTW89_ETSI][24] = 66, + [1][0][2][0][RTW89_MKK][24] = 76, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_KCC][24] = 74, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_CN][24] = 127, + [1][0][2][0][RTW89_UK][24] = 66, + [1][0][2][0][RTW89_FCC][28] = 80, + [1][0][2][0][RTW89_ETSI][28] = 66, + [1][0][2][0][RTW89_MKK][28] = 76, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_KCC][28] = 74, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_CN][28] = 127, + [1][0][2][0][RTW89_UK][28] = 66, + [1][0][2][0][RTW89_FCC][32] = 74, + [1][0][2][0][RTW89_ETSI][32] = 66, + [1][0][2][0][RTW89_MKK][32] = 76, + [1][0][2][0][RTW89_IC][32] = 74, + [1][0][2][0][RTW89_KCC][32] = 76, + [1][0][2][0][RTW89_ACMA][32] = 66, + [1][0][2][0][RTW89_CN][32] = 127, + [1][0][2][0][RTW89_UK][32] = 66, + [1][0][2][0][RTW89_FCC][36] = 78, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 76, + [1][0][2][0][RTW89_IC][36] = 78, + [1][0][2][0][RTW89_KCC][36] = 76, + [1][0][2][0][RTW89_ACMA][36] = 76, + [1][0][2][0][RTW89_CN][36] = 127, + [1][0][2][0][RTW89_UK][36] = 76, + [1][0][2][0][RTW89_FCC][39] = 80, + [1][0][2][0][RTW89_ETSI][39] = 30, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 80, + [1][0][2][0][RTW89_KCC][39] = 68, + [1][0][2][0][RTW89_ACMA][39] = 76, + [1][0][2][0][RTW89_CN][39] = 56, + [1][0][2][0][RTW89_UK][39] = 64, + [1][0][2][0][RTW89_FCC][43] = 80, + [1][0][2][0][RTW89_ETSI][43] = 30, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 80, + [1][0][2][0][RTW89_KCC][43] = 76, + [1][0][2][0][RTW89_ACMA][43] = 76, + [1][0][2][0][RTW89_CN][43] = 64, + [1][0][2][0][RTW89_UK][43] = 64, + [1][0][2][0][RTW89_FCC][47] = 80, + [1][0][2][0][RTW89_ETSI][47] = 127, + [1][0][2][0][RTW89_MKK][47] = 127, + [1][0][2][0][RTW89_IC][47] = 80, + [1][0][2][0][RTW89_KCC][47] = 127, + [1][0][2][0][RTW89_ACMA][47] = 127, + [1][0][2][0][RTW89_CN][47] = 127, + [1][0][2][0][RTW89_UK][47] = 127, + [1][0][2][0][RTW89_FCC][51] = 80, + [1][0][2][0][RTW89_ETSI][51] = 127, + [1][0][2][0][RTW89_MKK][51] = 127, + [1][0][2][0][RTW89_IC][51] = 80, + [1][0][2][0][RTW89_KCC][51] = 127, + [1][0][2][0][RTW89_ACMA][51] = 127, + [1][0][2][0][RTW89_CN][51] = 127, + [1][0][2][0][RTW89_UK][51] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][5] = 127, + [1][1][2][0][RTW89_ETSI][5] = 127, + [1][1][2][0][RTW89_MKK][5] = 127, + [1][1][2][0][RTW89_IC][5] = 127, + [1][1][2][0][RTW89_KCC][5] = 127, + [1][1][2][0][RTW89_ACMA][5] = 127, + [1][1][2][0][RTW89_CN][5] = 127, + [1][1][2][0][RTW89_UK][5] = 127, + [1][1][2][0][RTW89_FCC][9] = 127, + [1][1][2][0][RTW89_ETSI][9] = 127, + [1][1][2][0][RTW89_MKK][9] = 127, + [1][1][2][0][RTW89_IC][9] = 127, + [1][1][2][0][RTW89_KCC][9] = 127, + [1][1][2][0][RTW89_ACMA][9] = 127, + [1][1][2][0][RTW89_CN][9] = 127, + [1][1][2][0][RTW89_UK][9] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][16] = 127, + [1][1][2][0][RTW89_ETSI][16] = 127, + [1][1][2][0][RTW89_MKK][16] = 127, + [1][1][2][0][RTW89_IC][16] = 127, + [1][1][2][0][RTW89_KCC][16] = 127, + [1][1][2][0][RTW89_ACMA][16] = 127, + [1][1][2][0][RTW89_CN][16] = 127, + [1][1][2][0][RTW89_UK][16] = 127, + [1][1][2][0][RTW89_FCC][20] = 127, + [1][1][2][0][RTW89_ETSI][20] = 127, + [1][1][2][0][RTW89_MKK][20] = 127, + [1][1][2][0][RTW89_IC][20] = 127, + [1][1][2][0][RTW89_KCC][20] = 127, + [1][1][2][0][RTW89_ACMA][20] = 127, + [1][1][2][0][RTW89_CN][20] = 127, + [1][1][2][0][RTW89_UK][20] = 127, + [1][1][2][0][RTW89_FCC][24] = 127, + [1][1][2][0][RTW89_ETSI][24] = 127, + [1][1][2][0][RTW89_MKK][24] = 127, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_KCC][24] = 127, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_CN][24] = 127, + [1][1][2][0][RTW89_UK][24] = 127, + [1][1][2][0][RTW89_FCC][28] = 127, + [1][1][2][0][RTW89_ETSI][28] = 127, + [1][1][2][0][RTW89_MKK][28] = 127, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_KCC][28] = 127, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_CN][28] = 127, + [1][1][2][0][RTW89_UK][28] = 127, + [1][1][2][0][RTW89_FCC][32] = 127, + [1][1][2][0][RTW89_ETSI][32] = 127, + [1][1][2][0][RTW89_MKK][32] = 127, + [1][1][2][0][RTW89_IC][32] = 127, + [1][1][2][0][RTW89_KCC][32] = 127, + [1][1][2][0][RTW89_ACMA][32] = 127, + [1][1][2][0][RTW89_CN][32] = 127, + [1][1][2][0][RTW89_UK][32] = 127, + [1][1][2][0][RTW89_FCC][36] = 127, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 127, + [1][1][2][0][RTW89_IC][36] = 127, + [1][1][2][0][RTW89_KCC][36] = 127, + [1][1][2][0][RTW89_ACMA][36] = 127, + [1][1][2][0][RTW89_CN][36] = 127, + [1][1][2][0][RTW89_UK][36] = 127, + [1][1][2][0][RTW89_FCC][39] = 127, + [1][1][2][0][RTW89_ETSI][39] = 127, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 127, + [1][1][2][0][RTW89_KCC][39] = 127, + [1][1][2][0][RTW89_ACMA][39] = 127, + [1][1][2][0][RTW89_CN][39] = 127, + [1][1][2][0][RTW89_UK][39] = 127, + [1][1][2][0][RTW89_FCC][43] = 127, + [1][1][2][0][RTW89_ETSI][43] = 127, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 127, + [1][1][2][0][RTW89_KCC][43] = 127, + [1][1][2][0][RTW89_ACMA][43] = 127, + [1][1][2][0][RTW89_CN][43] = 127, + [1][1][2][0][RTW89_UK][43] = 127, + [1][1][2][0][RTW89_FCC][47] = 127, + [1][1][2][0][RTW89_ETSI][47] = 127, + [1][1][2][0][RTW89_MKK][47] = 127, + [1][1][2][0][RTW89_IC][47] = 127, + [1][1][2][0][RTW89_KCC][47] = 127, + [1][1][2][0][RTW89_ACMA][47] = 127, + [1][1][2][0][RTW89_CN][47] = 127, + [1][1][2][0][RTW89_UK][47] = 127, + [1][1][2][0][RTW89_FCC][51] = 127, + [1][1][2][0][RTW89_ETSI][51] = 127, + [1][1][2][0][RTW89_MKK][51] = 127, + [1][1][2][0][RTW89_IC][51] = 127, + [1][1][2][0][RTW89_KCC][51] = 127, + [1][1][2][0][RTW89_ACMA][51] = 127, + [1][1][2][0][RTW89_CN][51] = 127, + [1][1][2][0][RTW89_UK][51] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][5] = 127, + [1][1][2][1][RTW89_ETSI][5] = 127, + [1][1][2][1][RTW89_MKK][5] = 127, + [1][1][2][1][RTW89_IC][5] = 127, + [1][1][2][1][RTW89_KCC][5] = 127, + [1][1][2][1][RTW89_ACMA][5] = 127, + [1][1][2][1][RTW89_CN][5] = 127, + [1][1][2][1][RTW89_UK][5] = 127, + [1][1][2][1][RTW89_FCC][9] = 127, + [1][1][2][1][RTW89_ETSI][9] = 127, + [1][1][2][1][RTW89_MKK][9] = 127, + [1][1][2][1][RTW89_IC][9] = 127, + [1][1][2][1][RTW89_KCC][9] = 127, + [1][1][2][1][RTW89_ACMA][9] = 127, + [1][1][2][1][RTW89_CN][9] = 127, + [1][1][2][1][RTW89_UK][9] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][16] = 127, + [1][1][2][1][RTW89_ETSI][16] = 127, + [1][1][2][1][RTW89_MKK][16] = 127, + [1][1][2][1][RTW89_IC][16] = 127, + [1][1][2][1][RTW89_KCC][16] = 127, + [1][1][2][1][RTW89_ACMA][16] = 127, + [1][1][2][1][RTW89_CN][16] = 127, + [1][1][2][1][RTW89_UK][16] = 127, + [1][1][2][1][RTW89_FCC][20] = 127, + [1][1][2][1][RTW89_ETSI][20] = 127, + [1][1][2][1][RTW89_MKK][20] = 127, + [1][1][2][1][RTW89_IC][20] = 127, + [1][1][2][1][RTW89_KCC][20] = 127, + [1][1][2][1][RTW89_ACMA][20] = 127, + [1][1][2][1][RTW89_CN][20] = 127, + [1][1][2][1][RTW89_UK][20] = 127, + [1][1][2][1][RTW89_FCC][24] = 127, + [1][1][2][1][RTW89_ETSI][24] = 127, + [1][1][2][1][RTW89_MKK][24] = 127, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_KCC][24] = 127, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_CN][24] = 127, + [1][1][2][1][RTW89_UK][24] = 127, + [1][1][2][1][RTW89_FCC][28] = 127, + [1][1][2][1][RTW89_ETSI][28] = 127, + [1][1][2][1][RTW89_MKK][28] = 127, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_KCC][28] = 127, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_CN][28] = 127, + [1][1][2][1][RTW89_UK][28] = 127, + [1][1][2][1][RTW89_FCC][32] = 127, + [1][1][2][1][RTW89_ETSI][32] = 127, + [1][1][2][1][RTW89_MKK][32] = 127, + [1][1][2][1][RTW89_IC][32] = 127, + [1][1][2][1][RTW89_KCC][32] = 127, + [1][1][2][1][RTW89_ACMA][32] = 127, + [1][1][2][1][RTW89_CN][32] = 127, + [1][1][2][1][RTW89_UK][32] = 127, + [1][1][2][1][RTW89_FCC][36] = 127, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 127, + [1][1][2][1][RTW89_IC][36] = 127, + [1][1][2][1][RTW89_KCC][36] = 127, + [1][1][2][1][RTW89_ACMA][36] = 127, + [1][1][2][1][RTW89_CN][36] = 127, + [1][1][2][1][RTW89_UK][36] = 127, + [1][1][2][1][RTW89_FCC][39] = 127, + [1][1][2][1][RTW89_ETSI][39] = 127, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 127, + [1][1][2][1][RTW89_KCC][39] = 127, + [1][1][2][1][RTW89_ACMA][39] = 127, + [1][1][2][1][RTW89_CN][39] = 127, + [1][1][2][1][RTW89_UK][39] = 127, + [1][1][2][1][RTW89_FCC][43] = 127, + [1][1][2][1][RTW89_ETSI][43] = 127, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 127, + [1][1][2][1][RTW89_KCC][43] = 127, + [1][1][2][1][RTW89_ACMA][43] = 127, + [1][1][2][1][RTW89_CN][43] = 127, + [1][1][2][1][RTW89_UK][43] = 127, + [1][1][2][1][RTW89_FCC][47] = 127, + [1][1][2][1][RTW89_ETSI][47] = 127, + [1][1][2][1][RTW89_MKK][47] = 127, + [1][1][2][1][RTW89_IC][47] = 127, + [1][1][2][1][RTW89_KCC][47] = 127, + [1][1][2][1][RTW89_ACMA][47] = 127, + [1][1][2][1][RTW89_CN][47] = 127, + [1][1][2][1][RTW89_UK][47] = 127, + [1][1][2][1][RTW89_FCC][51] = 127, + [1][1][2][1][RTW89_ETSI][51] = 127, + [1][1][2][1][RTW89_MKK][51] = 127, + [1][1][2][1][RTW89_IC][51] = 127, + [1][1][2][1][RTW89_KCC][51] = 127, + [1][1][2][1][RTW89_ACMA][51] = 127, + [1][1][2][1][RTW89_CN][51] = 127, + [1][1][2][1][RTW89_UK][51] = 127, + [2][0][2][0][RTW89_FCC][3] = 72, + [2][0][2][0][RTW89_ETSI][3] = 64, + [2][0][2][0][RTW89_MKK][3] = 62, + [2][0][2][0][RTW89_IC][3] = 64, + [2][0][2][0][RTW89_KCC][3] = 68, + [2][0][2][0][RTW89_ACMA][3] = 64, + [2][0][2][0][RTW89_CN][3] = 60, + [2][0][2][0][RTW89_UK][3] = 64, + [2][0][2][0][RTW89_FCC][11] = 62, + [2][0][2][0][RTW89_ETSI][11] = 64, + [2][0][2][0][RTW89_MKK][11] = 64, + [2][0][2][0][RTW89_IC][11] = 62, + [2][0][2][0][RTW89_KCC][11] = 68, + [2][0][2][0][RTW89_ACMA][11] = 64, + [2][0][2][0][RTW89_CN][11] = 54, + [2][0][2][0][RTW89_UK][11] = 64, + [2][0][2][0][RTW89_FCC][18] = 66, + [2][0][2][0][RTW89_ETSI][18] = 64, + [2][0][2][0][RTW89_MKK][18] = 68, + [2][0][2][0][RTW89_IC][18] = 66, + [2][0][2][0][RTW89_KCC][18] = 68, + [2][0][2][0][RTW89_ACMA][18] = 64, + [2][0][2][0][RTW89_CN][18] = 127, + [2][0][2][0][RTW89_UK][18] = 64, + [2][0][2][0][RTW89_FCC][26] = 72, + [2][0][2][0][RTW89_ETSI][26] = 64, + [2][0][2][0][RTW89_MKK][26] = 68, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_KCC][26] = 68, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_CN][26] = 127, + [2][0][2][0][RTW89_UK][26] = 64, + [2][0][2][0][RTW89_FCC][34] = 72, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 68, + [2][0][2][0][RTW89_IC][34] = 72, + [2][0][2][0][RTW89_KCC][34] = 68, + [2][0][2][0][RTW89_ACMA][34] = 68, + [2][0][2][0][RTW89_CN][34] = 127, + [2][0][2][0][RTW89_UK][34] = 68, + [2][0][2][0][RTW89_FCC][41] = 72, + [2][0][2][0][RTW89_ETSI][41] = 30, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 72, + [2][0][2][0][RTW89_KCC][41] = 64, + [2][0][2][0][RTW89_ACMA][41] = 68, + [2][0][2][0][RTW89_CN][41] = 38, + [2][0][2][0][RTW89_UK][41] = 64, + [2][0][2][0][RTW89_FCC][49] = 72, + [2][0][2][0][RTW89_ETSI][49] = 127, + [2][0][2][0][RTW89_MKK][49] = 127, + [2][0][2][0][RTW89_IC][49] = 72, + [2][0][2][0][RTW89_KCC][49] = 127, + [2][0][2][0][RTW89_ACMA][49] = 127, + [2][0][2][0][RTW89_CN][49] = 127, + [2][0][2][0][RTW89_UK][49] = 127, + [2][1][2][0][RTW89_FCC][3] = 127, + [2][1][2][0][RTW89_ETSI][3] = 127, + [2][1][2][0][RTW89_MKK][3] = 127, + [2][1][2][0][RTW89_IC][3] = 127, + [2][1][2][0][RTW89_KCC][3] = 127, + [2][1][2][0][RTW89_ACMA][3] = 127, + [2][1][2][0][RTW89_CN][3] = 127, + [2][1][2][0][RTW89_UK][3] = 127, + [2][1][2][0][RTW89_FCC][11] = 127, + [2][1][2][0][RTW89_ETSI][11] = 127, + [2][1][2][0][RTW89_MKK][11] = 127, + [2][1][2][0][RTW89_IC][11] = 127, + [2][1][2][0][RTW89_KCC][11] = 127, + [2][1][2][0][RTW89_ACMA][11] = 127, + [2][1][2][0][RTW89_CN][11] = 127, + [2][1][2][0][RTW89_UK][11] = 127, + [2][1][2][0][RTW89_FCC][18] = 127, + [2][1][2][0][RTW89_ETSI][18] = 127, + [2][1][2][0][RTW89_MKK][18] = 127, + [2][1][2][0][RTW89_IC][18] = 127, + [2][1][2][0][RTW89_KCC][18] = 127, + [2][1][2][0][RTW89_ACMA][18] = 127, + [2][1][2][0][RTW89_CN][18] = 127, + [2][1][2][0][RTW89_UK][18] = 127, + [2][1][2][0][RTW89_FCC][26] = 127, + [2][1][2][0][RTW89_ETSI][26] = 127, + [2][1][2][0][RTW89_MKK][26] = 127, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_KCC][26] = 127, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_CN][26] = 127, + [2][1][2][0][RTW89_UK][26] = 127, + [2][1][2][0][RTW89_FCC][34] = 127, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 127, + [2][1][2][0][RTW89_IC][34] = 127, + [2][1][2][0][RTW89_KCC][34] = 127, + [2][1][2][0][RTW89_ACMA][34] = 127, + [2][1][2][0][RTW89_CN][34] = 127, + [2][1][2][0][RTW89_UK][34] = 127, + [2][1][2][0][RTW89_FCC][41] = 127, + [2][1][2][0][RTW89_ETSI][41] = 127, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 127, + [2][1][2][0][RTW89_KCC][41] = 127, + [2][1][2][0][RTW89_ACMA][41] = 127, + [2][1][2][0][RTW89_CN][41] = 127, + [2][1][2][0][RTW89_UK][41] = 127, + [2][1][2][0][RTW89_FCC][49] = 127, + [2][1][2][0][RTW89_ETSI][49] = 127, + [2][1][2][0][RTW89_MKK][49] = 127, + [2][1][2][0][RTW89_IC][49] = 127, + [2][1][2][0][RTW89_KCC][49] = 127, + [2][1][2][0][RTW89_ACMA][49] = 127, + [2][1][2][0][RTW89_CN][49] = 127, + [2][1][2][0][RTW89_UK][49] = 127, + [2][1][2][1][RTW89_FCC][3] = 127, + [2][1][2][1][RTW89_ETSI][3] = 127, + [2][1][2][1][RTW89_MKK][3] = 127, + [2][1][2][1][RTW89_IC][3] = 127, + [2][1][2][1][RTW89_KCC][3] = 127, + [2][1][2][1][RTW89_ACMA][3] = 127, + [2][1][2][1][RTW89_CN][3] = 127, + [2][1][2][1][RTW89_UK][3] = 127, + [2][1][2][1][RTW89_FCC][11] = 127, + [2][1][2][1][RTW89_ETSI][11] = 127, + [2][1][2][1][RTW89_MKK][11] = 127, + [2][1][2][1][RTW89_IC][11] = 127, + [2][1][2][1][RTW89_KCC][11] = 127, + [2][1][2][1][RTW89_ACMA][11] = 127, + [2][1][2][1][RTW89_CN][11] = 127, + [2][1][2][1][RTW89_UK][11] = 127, + [2][1][2][1][RTW89_FCC][18] = 127, + [2][1][2][1][RTW89_ETSI][18] = 127, + [2][1][2][1][RTW89_MKK][18] = 127, + [2][1][2][1][RTW89_IC][18] = 127, + [2][1][2][1][RTW89_KCC][18] = 127, + [2][1][2][1][RTW89_ACMA][18] = 127, + [2][1][2][1][RTW89_CN][18] = 127, + [2][1][2][1][RTW89_UK][18] = 127, + [2][1][2][1][RTW89_FCC][26] = 127, + [2][1][2][1][RTW89_ETSI][26] = 127, + [2][1][2][1][RTW89_MKK][26] = 127, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_KCC][26] = 127, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_CN][26] = 127, + [2][1][2][1][RTW89_UK][26] = 127, + [2][1][2][1][RTW89_FCC][34] = 127, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 127, + [2][1][2][1][RTW89_IC][34] = 127, + [2][1][2][1][RTW89_KCC][34] = 127, + [2][1][2][1][RTW89_ACMA][34] = 127, + [2][1][2][1][RTW89_CN][34] = 127, + [2][1][2][1][RTW89_UK][34] = 127, + [2][1][2][1][RTW89_FCC][41] = 127, + [2][1][2][1][RTW89_ETSI][41] = 127, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 127, + [2][1][2][1][RTW89_KCC][41] = 127, + [2][1][2][1][RTW89_ACMA][41] = 127, + [2][1][2][1][RTW89_CN][41] = 127, + [2][1][2][1][RTW89_UK][41] = 127, + [2][1][2][1][RTW89_FCC][49] = 127, + [2][1][2][1][RTW89_ETSI][49] = 127, + [2][1][2][1][RTW89_MKK][49] = 127, + [2][1][2][1][RTW89_IC][49] = 127, + [2][1][2][1][RTW89_KCC][49] = 127, + [2][1][2][1][RTW89_ACMA][49] = 127, + [2][1][2][1][RTW89_CN][49] = 127, + [2][1][2][1][RTW89_UK][49] = 127, + [3][0][2][0][RTW89_FCC][7] = 127, + [3][0][2][0][RTW89_ETSI][7] = 127, + [3][0][2][0][RTW89_MKK][7] = 127, + [3][0][2][0][RTW89_IC][7] = 127, + [3][0][2][0][RTW89_KCC][7] = 127, + [3][0][2][0][RTW89_ACMA][7] = 127, + [3][0][2][0][RTW89_CN][7] = 127, + [3][0][2][0][RTW89_UK][7] = 127, + [3][0][2][0][RTW89_FCC][22] = 127, + [3][0][2][0][RTW89_ETSI][22] = 127, + [3][0][2][0][RTW89_MKK][22] = 127, + [3][0][2][0][RTW89_IC][22] = 127, + [3][0][2][0][RTW89_KCC][22] = 127, + [3][0][2][0][RTW89_ACMA][22] = 127, + [3][0][2][0][RTW89_CN][22] = 127, + [3][0][2][0][RTW89_UK][22] = 127, + [3][0][2][0][RTW89_FCC][45] = 127, + [3][0][2][0][RTW89_ETSI][45] = 127, + [3][0][2][0][RTW89_MKK][45] = 127, + [3][0][2][0][RTW89_IC][45] = 127, + [3][0][2][0][RTW89_KCC][45] = 127, + [3][0][2][0][RTW89_ACMA][45] = 127, + [3][0][2][0][RTW89_CN][45] = 127, + [3][0][2][0][RTW89_UK][45] = 127, + [3][1][2][0][RTW89_FCC][7] = 127, + [3][1][2][0][RTW89_ETSI][7] = 127, + [3][1][2][0][RTW89_MKK][7] = 127, + [3][1][2][0][RTW89_IC][7] = 127, + [3][1][2][0][RTW89_KCC][7] = 127, + [3][1][2][0][RTW89_ACMA][7] = 127, + [3][1][2][0][RTW89_CN][7] = 127, + [3][1][2][0][RTW89_UK][7] = 127, + [3][1][2][0][RTW89_FCC][22] = 127, + [3][1][2][0][RTW89_ETSI][22] = 127, + [3][1][2][0][RTW89_MKK][22] = 127, + [3][1][2][0][RTW89_IC][22] = 127, + [3][1][2][0][RTW89_KCC][22] = 127, + [3][1][2][0][RTW89_ACMA][22] = 127, + [3][1][2][0][RTW89_CN][22] = 127, + [3][1][2][0][RTW89_UK][22] = 127, + [3][1][2][0][RTW89_FCC][45] = 127, + [3][1][2][0][RTW89_ETSI][45] = 127, + [3][1][2][0][RTW89_MKK][45] = 127, + [3][1][2][0][RTW89_IC][45] = 127, + [3][1][2][0][RTW89_KCC][45] = 127, + [3][1][2][0][RTW89_ACMA][45] = 127, + [3][1][2][0][RTW89_CN][45] = 127, + [3][1][2][0][RTW89_UK][45] = 127, + [3][1][2][1][RTW89_FCC][7] = 127, + [3][1][2][1][RTW89_ETSI][7] = 127, + [3][1][2][1][RTW89_MKK][7] = 127, + [3][1][2][1][RTW89_IC][7] = 127, + [3][1][2][1][RTW89_KCC][7] = 127, + [3][1][2][1][RTW89_ACMA][7] = 127, + [3][1][2][1][RTW89_CN][7] = 127, + [3][1][2][1][RTW89_UK][7] = 127, + [3][1][2][1][RTW89_FCC][22] = 127, + [3][1][2][1][RTW89_ETSI][22] = 127, + [3][1][2][1][RTW89_MKK][22] = 127, + [3][1][2][1][RTW89_IC][22] = 127, + [3][1][2][1][RTW89_KCC][22] = 127, + [3][1][2][1][RTW89_ACMA][22] = 127, + [3][1][2][1][RTW89_CN][22] = 127, + [3][1][2][1][RTW89_UK][22] = 127, + [3][1][2][1][RTW89_FCC][45] = 127, + [3][1][2][1][RTW89_ETSI][45] = 127, + [3][1][2][1][RTW89_MKK][45] = 127, + [3][1][2][1][RTW89_IC][45] = 127, + [3][1][2][1][RTW89_KCC][45] = 127, + [3][1][2][1][RTW89_ACMA][45] = 127, + [3][1][2][1][RTW89_CN][45] = 127, + [3][1][2][1][RTW89_UK][45] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_ru_2g_type2[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 30, + [0][0][RTW89_WW][1] = 30, + [0][0][RTW89_WW][2] = 30, + [0][0][RTW89_WW][3] = 30, + [0][0][RTW89_WW][4] = 30, + [0][0][RTW89_WW][5] = 30, + [0][0][RTW89_WW][6] = 30, + [0][0][RTW89_WW][7] = 30, + [0][0][RTW89_WW][8] = 30, + [0][0][RTW89_WW][9] = 30, + [0][0][RTW89_WW][10] = 30, + [0][0][RTW89_WW][11] = 30, + [0][0][RTW89_WW][12] = 30, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 0, + [0][1][RTW89_WW][1] = 0, + [0][1][RTW89_WW][2] = 0, + [0][1][RTW89_WW][3] = 0, + [0][1][RTW89_WW][4] = 0, + [0][1][RTW89_WW][5] = 0, + [0][1][RTW89_WW][6] = 0, + [0][1][RTW89_WW][7] = 0, + [0][1][RTW89_WW][8] = 0, + [0][1][RTW89_WW][9] = 0, + [0][1][RTW89_WW][10] = 0, + [0][1][RTW89_WW][11] = 0, + [0][1][RTW89_WW][12] = 0, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 42, + [1][0][RTW89_WW][2] = 42, + [1][0][RTW89_WW][3] = 42, + [1][0][RTW89_WW][4] = 42, + [1][0][RTW89_WW][5] = 42, + [1][0][RTW89_WW][6] = 42, + [1][0][RTW89_WW][7] = 42, + [1][0][RTW89_WW][8] = 42, + [1][0][RTW89_WW][9] = 42, + [1][0][RTW89_WW][10] = 42, + [1][0][RTW89_WW][11] = 42, + [1][0][RTW89_WW][12] = 34, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 0, + [1][1][RTW89_WW][1] = 0, + [1][1][RTW89_WW][2] = 0, + [1][1][RTW89_WW][3] = 0, + [1][1][RTW89_WW][4] = 0, + [1][1][RTW89_WW][5] = 0, + [1][1][RTW89_WW][6] = 0, + [1][1][RTW89_WW][7] = 0, + [1][1][RTW89_WW][8] = 0, + [1][1][RTW89_WW][9] = 0, + [1][1][RTW89_WW][10] = 0, + [1][1][RTW89_WW][11] = 0, + [1][1][RTW89_WW][12] = 0, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 54, + [2][0][RTW89_WW][1] = 54, + [2][0][RTW89_WW][2] = 54, + [2][0][RTW89_WW][3] = 54, + [2][0][RTW89_WW][4] = 54, + [2][0][RTW89_WW][5] = 54, + [2][0][RTW89_WW][6] = 54, + [2][0][RTW89_WW][7] = 54, + [2][0][RTW89_WW][8] = 54, + [2][0][RTW89_WW][9] = 54, + [2][0][RTW89_WW][10] = 54, + [2][0][RTW89_WW][11] = 54, + [2][0][RTW89_WW][12] = 34, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 0, + [2][1][RTW89_WW][1] = 0, + [2][1][RTW89_WW][2] = 0, + [2][1][RTW89_WW][3] = 0, + [2][1][RTW89_WW][4] = 0, + [2][1][RTW89_WW][5] = 0, + [2][1][RTW89_WW][6] = 0, + [2][1][RTW89_WW][7] = 0, + [2][1][RTW89_WW][8] = 0, + [2][1][RTW89_WW][9] = 0, + [2][1][RTW89_WW][10] = 0, + [2][1][RTW89_WW][11] = 0, + [2][1][RTW89_WW][12] = 0, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 60, + [0][0][RTW89_ETSI][0] = 30, + [0][0][RTW89_MKK][0] = 40, + [0][0][RTW89_IC][0] = 60, + [0][0][RTW89_KCC][0] = 46, + [0][0][RTW89_ACMA][0] = 30, + [0][0][RTW89_CN][0] = 32, + [0][0][RTW89_UK][0] = 30, + [0][0][RTW89_FCC][1] = 60, + [0][0][RTW89_ETSI][1] = 30, + [0][0][RTW89_MKK][1] = 44, + [0][0][RTW89_IC][1] = 60, + [0][0][RTW89_KCC][1] = 46, + [0][0][RTW89_ACMA][1] = 30, + [0][0][RTW89_CN][1] = 32, + [0][0][RTW89_UK][1] = 30, + [0][0][RTW89_FCC][2] = 64, + [0][0][RTW89_ETSI][2] = 30, + [0][0][RTW89_MKK][2] = 44, + [0][0][RTW89_IC][2] = 64, + [0][0][RTW89_KCC][2] = 46, + [0][0][RTW89_ACMA][2] = 30, + [0][0][RTW89_CN][2] = 32, + [0][0][RTW89_UK][2] = 30, + [0][0][RTW89_FCC][3] = 68, + [0][0][RTW89_ETSI][3] = 30, + [0][0][RTW89_MKK][3] = 44, + [0][0][RTW89_IC][3] = 68, + [0][0][RTW89_KCC][3] = 46, + [0][0][RTW89_ACMA][3] = 30, + [0][0][RTW89_CN][3] = 32, + [0][0][RTW89_UK][3] = 30, + [0][0][RTW89_FCC][4] = 68, + [0][0][RTW89_ETSI][4] = 30, + [0][0][RTW89_MKK][4] = 44, + [0][0][RTW89_IC][4] = 68, + [0][0][RTW89_KCC][4] = 48, + [0][0][RTW89_ACMA][4] = 30, + [0][0][RTW89_CN][4] = 32, + [0][0][RTW89_UK][4] = 30, + [0][0][RTW89_FCC][5] = 82, + [0][0][RTW89_ETSI][5] = 30, + [0][0][RTW89_MKK][5] = 44, + [0][0][RTW89_IC][5] = 82, + [0][0][RTW89_KCC][5] = 48, + [0][0][RTW89_ACMA][5] = 30, + [0][0][RTW89_CN][5] = 32, + [0][0][RTW89_UK][5] = 30, + [0][0][RTW89_FCC][6] = 64, + [0][0][RTW89_ETSI][6] = 30, + [0][0][RTW89_MKK][6] = 44, + [0][0][RTW89_IC][6] = 64, + [0][0][RTW89_KCC][6] = 48, + [0][0][RTW89_ACMA][6] = 30, + [0][0][RTW89_CN][6] = 32, + [0][0][RTW89_UK][6] = 30, + [0][0][RTW89_FCC][7] = 64, + [0][0][RTW89_ETSI][7] = 30, + [0][0][RTW89_MKK][7] = 44, + [0][0][RTW89_IC][7] = 64, + [0][0][RTW89_KCC][7] = 48, + [0][0][RTW89_ACMA][7] = 30, + [0][0][RTW89_CN][7] = 32, + [0][0][RTW89_UK][7] = 30, + [0][0][RTW89_FCC][8] = 60, + [0][0][RTW89_ETSI][8] = 30, + [0][0][RTW89_MKK][8] = 44, + [0][0][RTW89_IC][8] = 60, + [0][0][RTW89_KCC][8] = 48, + [0][0][RTW89_ACMA][8] = 30, + [0][0][RTW89_CN][8] = 32, + [0][0][RTW89_UK][8] = 30, + [0][0][RTW89_FCC][9] = 56, + [0][0][RTW89_ETSI][9] = 30, + [0][0][RTW89_MKK][9] = 44, + [0][0][RTW89_IC][9] = 56, + [0][0][RTW89_KCC][9] = 44, + [0][0][RTW89_ACMA][9] = 30, + [0][0][RTW89_CN][9] = 32, + [0][0][RTW89_UK][9] = 30, + [0][0][RTW89_FCC][10] = 56, + [0][0][RTW89_ETSI][10] = 30, + [0][0][RTW89_MKK][10] = 44, + [0][0][RTW89_IC][10] = 56, + [0][0][RTW89_KCC][10] = 44, + [0][0][RTW89_ACMA][10] = 30, + [0][0][RTW89_CN][10] = 32, + [0][0][RTW89_UK][10] = 30, + [0][0][RTW89_FCC][11] = 54, + [0][0][RTW89_ETSI][11] = 30, + [0][0][RTW89_MKK][11] = 44, + [0][0][RTW89_IC][11] = 54, + [0][0][RTW89_KCC][11] = 44, + [0][0][RTW89_ACMA][11] = 30, + [0][0][RTW89_CN][11] = 32, + [0][0][RTW89_UK][11] = 30, + [0][0][RTW89_FCC][12] = 34, + [0][0][RTW89_ETSI][12] = 30, + [0][0][RTW89_MKK][12] = 40, + [0][0][RTW89_IC][12] = 34, + [0][0][RTW89_KCC][12] = 44, + [0][0][RTW89_ACMA][12] = 30, + [0][0][RTW89_CN][12] = 32, + [0][0][RTW89_UK][12] = 30, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_KCC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][0][RTW89_CN][13] = 127, + [0][0][RTW89_UK][13] = 127, + [0][1][RTW89_FCC][0] = 127, + [0][1][RTW89_ETSI][0] = 127, + [0][1][RTW89_MKK][0] = 127, + [0][1][RTW89_IC][0] = 127, + [0][1][RTW89_KCC][0] = 127, + [0][1][RTW89_ACMA][0] = 127, + [0][1][RTW89_CN][0] = 127, + [0][1][RTW89_UK][0] = 127, + [0][1][RTW89_FCC][1] = 127, + [0][1][RTW89_ETSI][1] = 127, + [0][1][RTW89_MKK][1] = 127, + [0][1][RTW89_IC][1] = 127, + [0][1][RTW89_KCC][1] = 127, + [0][1][RTW89_ACMA][1] = 127, + [0][1][RTW89_CN][1] = 127, + [0][1][RTW89_UK][1] = 127, + [0][1][RTW89_FCC][2] = 127, + [0][1][RTW89_ETSI][2] = 127, + [0][1][RTW89_MKK][2] = 127, + [0][1][RTW89_IC][2] = 127, + [0][1][RTW89_KCC][2] = 127, + [0][1][RTW89_ACMA][2] = 127, + [0][1][RTW89_CN][2] = 127, + [0][1][RTW89_UK][2] = 127, + [0][1][RTW89_FCC][3] = 127, + [0][1][RTW89_ETSI][3] = 127, + [0][1][RTW89_MKK][3] = 127, + [0][1][RTW89_IC][3] = 127, + [0][1][RTW89_KCC][3] = 127, + [0][1][RTW89_ACMA][3] = 127, + [0][1][RTW89_CN][3] = 127, + [0][1][RTW89_UK][3] = 127, + [0][1][RTW89_FCC][4] = 127, + [0][1][RTW89_ETSI][4] = 127, + [0][1][RTW89_MKK][4] = 127, + [0][1][RTW89_IC][4] = 127, + [0][1][RTW89_KCC][4] = 127, + [0][1][RTW89_ACMA][4] = 127, + [0][1][RTW89_CN][4] = 127, + [0][1][RTW89_UK][4] = 127, + [0][1][RTW89_FCC][5] = 127, + [0][1][RTW89_ETSI][5] = 127, + [0][1][RTW89_MKK][5] = 127, + [0][1][RTW89_IC][5] = 127, + [0][1][RTW89_KCC][5] = 127, + [0][1][RTW89_ACMA][5] = 127, + [0][1][RTW89_CN][5] = 127, + [0][1][RTW89_UK][5] = 127, + [0][1][RTW89_FCC][6] = 127, + [0][1][RTW89_ETSI][6] = 127, + [0][1][RTW89_MKK][6] = 127, + [0][1][RTW89_IC][6] = 127, + [0][1][RTW89_KCC][6] = 127, + [0][1][RTW89_ACMA][6] = 127, + [0][1][RTW89_CN][6] = 127, + [0][1][RTW89_UK][6] = 127, + [0][1][RTW89_FCC][7] = 127, + [0][1][RTW89_ETSI][7] = 127, + [0][1][RTW89_MKK][7] = 127, + [0][1][RTW89_IC][7] = 127, + [0][1][RTW89_KCC][7] = 127, + [0][1][RTW89_ACMA][7] = 127, + [0][1][RTW89_CN][7] = 127, + [0][1][RTW89_UK][7] = 127, + [0][1][RTW89_FCC][8] = 127, + [0][1][RTW89_ETSI][8] = 127, + [0][1][RTW89_MKK][8] = 127, + [0][1][RTW89_IC][8] = 127, + [0][1][RTW89_KCC][8] = 127, + [0][1][RTW89_ACMA][8] = 127, + [0][1][RTW89_CN][8] = 127, + [0][1][RTW89_UK][8] = 127, + [0][1][RTW89_FCC][9] = 127, + [0][1][RTW89_ETSI][9] = 127, + [0][1][RTW89_MKK][9] = 127, + [0][1][RTW89_IC][9] = 127, + [0][1][RTW89_KCC][9] = 127, + [0][1][RTW89_ACMA][9] = 127, + [0][1][RTW89_CN][9] = 127, + [0][1][RTW89_UK][9] = 127, + [0][1][RTW89_FCC][10] = 127, + [0][1][RTW89_ETSI][10] = 127, + [0][1][RTW89_MKK][10] = 127, + [0][1][RTW89_IC][10] = 127, + [0][1][RTW89_KCC][10] = 127, + [0][1][RTW89_ACMA][10] = 127, + [0][1][RTW89_CN][10] = 127, + [0][1][RTW89_UK][10] = 127, + [0][1][RTW89_FCC][11] = 127, + [0][1][RTW89_ETSI][11] = 127, + [0][1][RTW89_MKK][11] = 127, + [0][1][RTW89_IC][11] = 127, + [0][1][RTW89_KCC][11] = 127, + [0][1][RTW89_ACMA][11] = 127, + [0][1][RTW89_CN][11] = 127, + [0][1][RTW89_UK][11] = 127, + [0][1][RTW89_FCC][12] = 127, + [0][1][RTW89_ETSI][12] = 127, + [0][1][RTW89_MKK][12] = 127, + [0][1][RTW89_IC][12] = 127, + [0][1][RTW89_KCC][12] = 127, + [0][1][RTW89_ACMA][12] = 127, + [0][1][RTW89_CN][12] = 127, + [0][1][RTW89_UK][12] = 127, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_KCC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [0][1][RTW89_CN][13] = 127, + [0][1][RTW89_UK][13] = 127, + [1][0][RTW89_FCC][0] = 70, + [1][0][RTW89_ETSI][0] = 42, + [1][0][RTW89_MKK][0] = 52, + [1][0][RTW89_IC][0] = 70, + [1][0][RTW89_KCC][0] = 56, + [1][0][RTW89_ACMA][0] = 42, + [1][0][RTW89_CN][0] = 42, + [1][0][RTW89_UK][0] = 42, + [1][0][RTW89_FCC][1] = 70, + [1][0][RTW89_ETSI][1] = 42, + [1][0][RTW89_MKK][1] = 52, + [1][0][RTW89_IC][1] = 70, + [1][0][RTW89_KCC][1] = 56, + [1][0][RTW89_ACMA][1] = 42, + [1][0][RTW89_CN][1] = 44, + [1][0][RTW89_UK][1] = 42, + [1][0][RTW89_FCC][2] = 74, + [1][0][RTW89_ETSI][2] = 42, + [1][0][RTW89_MKK][2] = 52, + [1][0][RTW89_IC][2] = 74, + [1][0][RTW89_KCC][2] = 56, + [1][0][RTW89_ACMA][2] = 42, + [1][0][RTW89_CN][2] = 44, + [1][0][RTW89_UK][2] = 42, + [1][0][RTW89_FCC][3] = 76, + [1][0][RTW89_ETSI][3] = 42, + [1][0][RTW89_MKK][3] = 52, + [1][0][RTW89_IC][3] = 76, + [1][0][RTW89_KCC][3] = 56, + [1][0][RTW89_ACMA][3] = 42, + [1][0][RTW89_CN][3] = 44, + [1][0][RTW89_UK][3] = 42, + [1][0][RTW89_FCC][4] = 76, + [1][0][RTW89_ETSI][4] = 42, + [1][0][RTW89_MKK][4] = 52, + [1][0][RTW89_IC][4] = 76, + [1][0][RTW89_KCC][4] = 56, + [1][0][RTW89_ACMA][4] = 42, + [1][0][RTW89_CN][4] = 44, + [1][0][RTW89_UK][4] = 42, + [1][0][RTW89_FCC][5] = 82, + [1][0][RTW89_ETSI][5] = 42, + [1][0][RTW89_MKK][5] = 52, + [1][0][RTW89_IC][5] = 82, + [1][0][RTW89_KCC][5] = 56, + [1][0][RTW89_ACMA][5] = 42, + [1][0][RTW89_CN][5] = 44, + [1][0][RTW89_UK][5] = 42, + [1][0][RTW89_FCC][6] = 72, + [1][0][RTW89_ETSI][6] = 42, + [1][0][RTW89_MKK][6] = 52, + [1][0][RTW89_IC][6] = 72, + [1][0][RTW89_KCC][6] = 56, + [1][0][RTW89_ACMA][6] = 42, + [1][0][RTW89_CN][6] = 44, + [1][0][RTW89_UK][6] = 42, + [1][0][RTW89_FCC][7] = 72, + [1][0][RTW89_ETSI][7] = 42, + [1][0][RTW89_MKK][7] = 52, + [1][0][RTW89_IC][7] = 72, + [1][0][RTW89_KCC][7] = 56, + [1][0][RTW89_ACMA][7] = 42, + [1][0][RTW89_CN][7] = 44, + [1][0][RTW89_UK][7] = 42, + [1][0][RTW89_FCC][8] = 72, + [1][0][RTW89_ETSI][8] = 42, + [1][0][RTW89_MKK][8] = 52, + [1][0][RTW89_IC][8] = 72, + [1][0][RTW89_KCC][8] = 56, + [1][0][RTW89_ACMA][8] = 42, + [1][0][RTW89_CN][8] = 44, + [1][0][RTW89_UK][8] = 42, + [1][0][RTW89_FCC][9] = 68, + [1][0][RTW89_ETSI][9] = 42, + [1][0][RTW89_MKK][9] = 52, + [1][0][RTW89_IC][9] = 68, + [1][0][RTW89_KCC][9] = 58, + [1][0][RTW89_ACMA][9] = 42, + [1][0][RTW89_CN][9] = 44, + [1][0][RTW89_UK][9] = 42, + [1][0][RTW89_FCC][10] = 68, + [1][0][RTW89_ETSI][10] = 42, + [1][0][RTW89_MKK][10] = 52, + [1][0][RTW89_IC][10] = 68, + [1][0][RTW89_KCC][10] = 58, + [1][0][RTW89_ACMA][10] = 42, + [1][0][RTW89_CN][10] = 44, + [1][0][RTW89_UK][10] = 42, + [1][0][RTW89_FCC][11] = 66, + [1][0][RTW89_ETSI][11] = 42, + [1][0][RTW89_MKK][11] = 52, + [1][0][RTW89_IC][11] = 66, + [1][0][RTW89_KCC][11] = 58, + [1][0][RTW89_ACMA][11] = 42, + [1][0][RTW89_CN][11] = 44, + [1][0][RTW89_UK][11] = 42, + [1][0][RTW89_FCC][12] = 34, + [1][0][RTW89_ETSI][12] = 42, + [1][0][RTW89_MKK][12] = 52, + [1][0][RTW89_IC][12] = 34, + [1][0][RTW89_KCC][12] = 58, + [1][0][RTW89_ACMA][12] = 42, + [1][0][RTW89_CN][12] = 42, + [1][0][RTW89_UK][12] = 42, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_KCC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][0][RTW89_CN][13] = 127, + [1][0][RTW89_UK][13] = 127, + [1][1][RTW89_FCC][0] = 127, + [1][1][RTW89_ETSI][0] = 127, + [1][1][RTW89_MKK][0] = 127, + [1][1][RTW89_IC][0] = 127, + [1][1][RTW89_KCC][0] = 127, + [1][1][RTW89_ACMA][0] = 127, + [1][1][RTW89_CN][0] = 127, + [1][1][RTW89_UK][0] = 127, + [1][1][RTW89_FCC][1] = 127, + [1][1][RTW89_ETSI][1] = 127, + [1][1][RTW89_MKK][1] = 127, + [1][1][RTW89_IC][1] = 127, + [1][1][RTW89_KCC][1] = 127, + [1][1][RTW89_ACMA][1] = 127, + [1][1][RTW89_CN][1] = 127, + [1][1][RTW89_UK][1] = 127, + [1][1][RTW89_FCC][2] = 127, + [1][1][RTW89_ETSI][2] = 127, + [1][1][RTW89_MKK][2] = 127, + [1][1][RTW89_IC][2] = 127, + [1][1][RTW89_KCC][2] = 127, + [1][1][RTW89_ACMA][2] = 127, + [1][1][RTW89_CN][2] = 127, + [1][1][RTW89_UK][2] = 127, + [1][1][RTW89_FCC][3] = 127, + [1][1][RTW89_ETSI][3] = 127, + [1][1][RTW89_MKK][3] = 127, + [1][1][RTW89_IC][3] = 127, + [1][1][RTW89_KCC][3] = 127, + [1][1][RTW89_ACMA][3] = 127, + [1][1][RTW89_CN][3] = 127, + [1][1][RTW89_UK][3] = 127, + [1][1][RTW89_FCC][4] = 127, + [1][1][RTW89_ETSI][4] = 127, + [1][1][RTW89_MKK][4] = 127, + [1][1][RTW89_IC][4] = 127, + [1][1][RTW89_KCC][4] = 127, + [1][1][RTW89_ACMA][4] = 127, + [1][1][RTW89_CN][4] = 127, + [1][1][RTW89_UK][4] = 127, + [1][1][RTW89_FCC][5] = 127, + [1][1][RTW89_ETSI][5] = 127, + [1][1][RTW89_MKK][5] = 127, + [1][1][RTW89_IC][5] = 127, + [1][1][RTW89_KCC][5] = 127, + [1][1][RTW89_ACMA][5] = 127, + [1][1][RTW89_CN][5] = 127, + [1][1][RTW89_UK][5] = 127, + [1][1][RTW89_FCC][6] = 127, + [1][1][RTW89_ETSI][6] = 127, + [1][1][RTW89_MKK][6] = 127, + [1][1][RTW89_IC][6] = 127, + [1][1][RTW89_KCC][6] = 127, + [1][1][RTW89_ACMA][6] = 127, + [1][1][RTW89_CN][6] = 127, + [1][1][RTW89_UK][6] = 127, + [1][1][RTW89_FCC][7] = 127, + [1][1][RTW89_ETSI][7] = 127, + [1][1][RTW89_MKK][7] = 127, + [1][1][RTW89_IC][7] = 127, + [1][1][RTW89_KCC][7] = 127, + [1][1][RTW89_ACMA][7] = 127, + [1][1][RTW89_CN][7] = 127, + [1][1][RTW89_UK][7] = 127, + [1][1][RTW89_FCC][8] = 127, + [1][1][RTW89_ETSI][8] = 127, + [1][1][RTW89_MKK][8] = 127, + [1][1][RTW89_IC][8] = 127, + [1][1][RTW89_KCC][8] = 127, + [1][1][RTW89_ACMA][8] = 127, + [1][1][RTW89_CN][8] = 127, + [1][1][RTW89_UK][8] = 127, + [1][1][RTW89_FCC][9] = 127, + [1][1][RTW89_ETSI][9] = 127, + [1][1][RTW89_MKK][9] = 127, + [1][1][RTW89_IC][9] = 127, + [1][1][RTW89_KCC][9] = 127, + [1][1][RTW89_ACMA][9] = 127, + [1][1][RTW89_CN][9] = 127, + [1][1][RTW89_UK][9] = 127, + [1][1][RTW89_FCC][10] = 127, + [1][1][RTW89_ETSI][10] = 127, + [1][1][RTW89_MKK][10] = 127, + [1][1][RTW89_IC][10] = 127, + [1][1][RTW89_KCC][10] = 127, + [1][1][RTW89_ACMA][10] = 127, + [1][1][RTW89_CN][10] = 127, + [1][1][RTW89_UK][10] = 127, + [1][1][RTW89_FCC][11] = 127, + [1][1][RTW89_ETSI][11] = 127, + [1][1][RTW89_MKK][11] = 127, + [1][1][RTW89_IC][11] = 127, + [1][1][RTW89_KCC][11] = 127, + [1][1][RTW89_ACMA][11] = 127, + [1][1][RTW89_CN][11] = 127, + [1][1][RTW89_UK][11] = 127, + [1][1][RTW89_FCC][12] = 127, + [1][1][RTW89_ETSI][12] = 127, + [1][1][RTW89_MKK][12] = 127, + [1][1][RTW89_IC][12] = 127, + [1][1][RTW89_KCC][12] = 127, + [1][1][RTW89_ACMA][12] = 127, + [1][1][RTW89_CN][12] = 127, + [1][1][RTW89_UK][12] = 127, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_KCC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [1][1][RTW89_CN][13] = 127, + [1][1][RTW89_UK][13] = 127, + [2][0][RTW89_FCC][0] = 74, + [2][0][RTW89_ETSI][0] = 54, + [2][0][RTW89_MKK][0] = 64, + [2][0][RTW89_IC][0] = 74, + [2][0][RTW89_KCC][0] = 68, + [2][0][RTW89_ACMA][0] = 54, + [2][0][RTW89_CN][0] = 56, + [2][0][RTW89_UK][0] = 54, + [2][0][RTW89_FCC][1] = 74, + [2][0][RTW89_ETSI][1] = 54, + [2][0][RTW89_MKK][1] = 64, + [2][0][RTW89_IC][1] = 74, + [2][0][RTW89_KCC][1] = 68, + [2][0][RTW89_ACMA][1] = 54, + [2][0][RTW89_CN][1] = 56, + [2][0][RTW89_UK][1] = 54, + [2][0][RTW89_FCC][2] = 76, + [2][0][RTW89_ETSI][2] = 54, + [2][0][RTW89_MKK][2] = 64, + [2][0][RTW89_IC][2] = 76, + [2][0][RTW89_KCC][2] = 68, + [2][0][RTW89_ACMA][2] = 54, + [2][0][RTW89_CN][2] = 56, + [2][0][RTW89_UK][2] = 54, + [2][0][RTW89_FCC][3] = 76, + [2][0][RTW89_ETSI][3] = 54, + [2][0][RTW89_MKK][3] = 64, + [2][0][RTW89_IC][3] = 76, + [2][0][RTW89_KCC][3] = 68, + [2][0][RTW89_ACMA][3] = 54, + [2][0][RTW89_CN][3] = 56, + [2][0][RTW89_UK][3] = 54, + [2][0][RTW89_FCC][4] = 76, + [2][0][RTW89_ETSI][4] = 54, + [2][0][RTW89_MKK][4] = 64, + [2][0][RTW89_IC][4] = 76, + [2][0][RTW89_KCC][4] = 68, + [2][0][RTW89_ACMA][4] = 54, + [2][0][RTW89_CN][4] = 56, + [2][0][RTW89_UK][4] = 54, + [2][0][RTW89_FCC][5] = 80, + [2][0][RTW89_ETSI][5] = 54, + [2][0][RTW89_MKK][5] = 64, + [2][0][RTW89_IC][5] = 80, + [2][0][RTW89_KCC][5] = 68, + [2][0][RTW89_ACMA][5] = 54, + [2][0][RTW89_CN][5] = 56, + [2][0][RTW89_UK][5] = 54, + [2][0][RTW89_FCC][6] = 72, + [2][0][RTW89_ETSI][6] = 54, + [2][0][RTW89_MKK][6] = 64, + [2][0][RTW89_IC][6] = 72, + [2][0][RTW89_KCC][6] = 68, + [2][0][RTW89_ACMA][6] = 54, + [2][0][RTW89_CN][6] = 56, + [2][0][RTW89_UK][6] = 54, + [2][0][RTW89_FCC][7] = 72, + [2][0][RTW89_ETSI][7] = 54, + [2][0][RTW89_MKK][7] = 64, + [2][0][RTW89_IC][7] = 72, + [2][0][RTW89_KCC][7] = 68, + [2][0][RTW89_ACMA][7] = 54, + [2][0][RTW89_CN][7] = 56, + [2][0][RTW89_UK][7] = 54, + [2][0][RTW89_FCC][8] = 72, + [2][0][RTW89_ETSI][8] = 54, + [2][0][RTW89_MKK][8] = 64, + [2][0][RTW89_IC][8] = 72, + [2][0][RTW89_KCC][8] = 68, + [2][0][RTW89_ACMA][8] = 54, + [2][0][RTW89_CN][8] = 56, + [2][0][RTW89_UK][8] = 54, + [2][0][RTW89_FCC][9] = 70, + [2][0][RTW89_ETSI][9] = 54, + [2][0][RTW89_MKK][9] = 64, + [2][0][RTW89_IC][9] = 70, + [2][0][RTW89_KCC][9] = 68, + [2][0][RTW89_ACMA][9] = 54, + [2][0][RTW89_CN][9] = 56, + [2][0][RTW89_UK][9] = 54, + [2][0][RTW89_FCC][10] = 70, + [2][0][RTW89_ETSI][10] = 54, + [2][0][RTW89_MKK][10] = 64, + [2][0][RTW89_IC][10] = 70, + [2][0][RTW89_KCC][10] = 68, + [2][0][RTW89_ACMA][10] = 54, + [2][0][RTW89_CN][10] = 56, + [2][0][RTW89_UK][10] = 54, + [2][0][RTW89_FCC][11] = 62, + [2][0][RTW89_ETSI][11] = 54, + [2][0][RTW89_MKK][11] = 64, + [2][0][RTW89_IC][11] = 62, + [2][0][RTW89_KCC][11] = 68, + [2][0][RTW89_ACMA][11] = 54, + [2][0][RTW89_CN][11] = 56, + [2][0][RTW89_UK][11] = 54, + [2][0][RTW89_FCC][12] = 34, + [2][0][RTW89_ETSI][12] = 54, + [2][0][RTW89_MKK][12] = 64, + [2][0][RTW89_IC][12] = 34, + [2][0][RTW89_KCC][12] = 68, + [2][0][RTW89_ACMA][12] = 54, + [2][0][RTW89_CN][12] = 56, + [2][0][RTW89_UK][12] = 54, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_KCC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][0][RTW89_CN][13] = 127, + [2][0][RTW89_UK][13] = 127, + [2][1][RTW89_FCC][0] = 127, + [2][1][RTW89_ETSI][0] = 127, + [2][1][RTW89_MKK][0] = 127, + [2][1][RTW89_IC][0] = 127, + [2][1][RTW89_KCC][0] = 127, + [2][1][RTW89_ACMA][0] = 127, + [2][1][RTW89_CN][0] = 127, + [2][1][RTW89_UK][0] = 127, + [2][1][RTW89_FCC][1] = 127, + [2][1][RTW89_ETSI][1] = 127, + [2][1][RTW89_MKK][1] = 127, + [2][1][RTW89_IC][1] = 127, + [2][1][RTW89_KCC][1] = 127, + [2][1][RTW89_ACMA][1] = 127, + [2][1][RTW89_CN][1] = 127, + [2][1][RTW89_UK][1] = 127, + [2][1][RTW89_FCC][2] = 127, + [2][1][RTW89_ETSI][2] = 127, + [2][1][RTW89_MKK][2] = 127, + [2][1][RTW89_IC][2] = 127, + [2][1][RTW89_KCC][2] = 127, + [2][1][RTW89_ACMA][2] = 127, + [2][1][RTW89_CN][2] = 127, + [2][1][RTW89_UK][2] = 127, + [2][1][RTW89_FCC][3] = 127, + [2][1][RTW89_ETSI][3] = 127, + [2][1][RTW89_MKK][3] = 127, + [2][1][RTW89_IC][3] = 127, + [2][1][RTW89_KCC][3] = 127, + [2][1][RTW89_ACMA][3] = 127, + [2][1][RTW89_CN][3] = 127, + [2][1][RTW89_UK][3] = 127, + [2][1][RTW89_FCC][4] = 127, + [2][1][RTW89_ETSI][4] = 127, + [2][1][RTW89_MKK][4] = 127, + [2][1][RTW89_IC][4] = 127, + [2][1][RTW89_KCC][4] = 127, + [2][1][RTW89_ACMA][4] = 127, + [2][1][RTW89_CN][4] = 127, + [2][1][RTW89_UK][4] = 127, + [2][1][RTW89_FCC][5] = 127, + [2][1][RTW89_ETSI][5] = 127, + [2][1][RTW89_MKK][5] = 127, + [2][1][RTW89_IC][5] = 127, + [2][1][RTW89_KCC][5] = 127, + [2][1][RTW89_ACMA][5] = 127, + [2][1][RTW89_CN][5] = 127, + [2][1][RTW89_UK][5] = 127, + [2][1][RTW89_FCC][6] = 127, + [2][1][RTW89_ETSI][6] = 127, + [2][1][RTW89_MKK][6] = 127, + [2][1][RTW89_IC][6] = 127, + [2][1][RTW89_KCC][6] = 127, + [2][1][RTW89_ACMA][6] = 127, + [2][1][RTW89_CN][6] = 127, + [2][1][RTW89_UK][6] = 127, + [2][1][RTW89_FCC][7] = 127, + [2][1][RTW89_ETSI][7] = 127, + [2][1][RTW89_MKK][7] = 127, + [2][1][RTW89_IC][7] = 127, + [2][1][RTW89_KCC][7] = 127, + [2][1][RTW89_ACMA][7] = 127, + [2][1][RTW89_CN][7] = 127, + [2][1][RTW89_UK][7] = 127, + [2][1][RTW89_FCC][8] = 127, + [2][1][RTW89_ETSI][8] = 127, + [2][1][RTW89_MKK][8] = 127, + [2][1][RTW89_IC][8] = 127, + [2][1][RTW89_KCC][8] = 127, + [2][1][RTW89_ACMA][8] = 127, + [2][1][RTW89_CN][8] = 127, + [2][1][RTW89_UK][8] = 127, + [2][1][RTW89_FCC][9] = 127, + [2][1][RTW89_ETSI][9] = 127, + [2][1][RTW89_MKK][9] = 127, + [2][1][RTW89_IC][9] = 127, + [2][1][RTW89_KCC][9] = 127, + [2][1][RTW89_ACMA][9] = 127, + [2][1][RTW89_CN][9] = 127, + [2][1][RTW89_UK][9] = 127, + [2][1][RTW89_FCC][10] = 127, + [2][1][RTW89_ETSI][10] = 127, + [2][1][RTW89_MKK][10] = 127, + [2][1][RTW89_IC][10] = 127, + [2][1][RTW89_KCC][10] = 127, + [2][1][RTW89_ACMA][10] = 127, + [2][1][RTW89_CN][10] = 127, + [2][1][RTW89_UK][10] = 127, + [2][1][RTW89_FCC][11] = 127, + [2][1][RTW89_ETSI][11] = 127, + [2][1][RTW89_MKK][11] = 127, + [2][1][RTW89_IC][11] = 127, + [2][1][RTW89_KCC][11] = 127, + [2][1][RTW89_ACMA][11] = 127, + [2][1][RTW89_CN][11] = 127, + [2][1][RTW89_UK][11] = 127, + [2][1][RTW89_FCC][12] = 127, + [2][1][RTW89_ETSI][12] = 127, + [2][1][RTW89_MKK][12] = 127, + [2][1][RTW89_IC][12] = 127, + [2][1][RTW89_KCC][12] = 127, + [2][1][RTW89_ACMA][12] = 127, + [2][1][RTW89_CN][12] = 127, + [2][1][RTW89_UK][12] = 127, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_KCC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, + [2][1][RTW89_CN][13] = 127, + [2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8851b_txpwr_lmt_ru_5g_type2[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 16, + [0][0][RTW89_WW][2] = 16, + [0][0][RTW89_WW][4] = 16, + [0][0][RTW89_WW][6] = 16, + [0][0][RTW89_WW][8] = 16, + [0][0][RTW89_WW][10] = 16, + [0][0][RTW89_WW][12] = 16, + [0][0][RTW89_WW][14] = 16, + [0][0][RTW89_WW][15] = 24, + [0][0][RTW89_WW][17] = 24, + [0][0][RTW89_WW][19] = 24, + [0][0][RTW89_WW][21] = 24, + [0][0][RTW89_WW][23] = 24, + [0][0][RTW89_WW][25] = 24, + [0][0][RTW89_WW][27] = 24, + [0][0][RTW89_WW][29] = 24, + [0][0][RTW89_WW][31] = 24, + [0][0][RTW89_WW][33] = 24, + [0][0][RTW89_WW][35] = 24, + [0][0][RTW89_WW][37] = 44, + [0][0][RTW89_WW][38] = 24, + [0][0][RTW89_WW][40] = 24, + [0][0][RTW89_WW][42] = 24, + [0][0][RTW89_WW][44] = 24, + [0][0][RTW89_WW][46] = 24, + [0][0][RTW89_WW][48] = 40, + [0][0][RTW89_WW][50] = 42, + [0][0][RTW89_WW][52] = 38, + [0][1][RTW89_WW][0] = 0, + [0][1][RTW89_WW][2] = 0, + [0][1][RTW89_WW][4] = 0, + [0][1][RTW89_WW][6] = 0, + [0][1][RTW89_WW][8] = 0, + [0][1][RTW89_WW][10] = 0, + [0][1][RTW89_WW][12] = 0, + [0][1][RTW89_WW][14] = 0, + [0][1][RTW89_WW][15] = 0, + [0][1][RTW89_WW][17] = 0, + [0][1][RTW89_WW][19] = 0, + [0][1][RTW89_WW][21] = 0, + [0][1][RTW89_WW][23] = 0, + [0][1][RTW89_WW][25] = 0, + [0][1][RTW89_WW][27] = 0, + [0][1][RTW89_WW][29] = 0, + [0][1][RTW89_WW][31] = 0, + [0][1][RTW89_WW][33] = 0, + [0][1][RTW89_WW][35] = 0, + [0][1][RTW89_WW][37] = 0, + [0][1][RTW89_WW][38] = 0, + [0][1][RTW89_WW][40] = 0, + [0][1][RTW89_WW][42] = 0, + [0][1][RTW89_WW][44] = 0, + [0][1][RTW89_WW][46] = 0, + [0][1][RTW89_WW][48] = 0, + [0][1][RTW89_WW][50] = 0, + [0][1][RTW89_WW][52] = 0, + [1][0][RTW89_WW][0] = 26, + [1][0][RTW89_WW][2] = 26, + [1][0][RTW89_WW][4] = 26, + [1][0][RTW89_WW][6] = 26, + [1][0][RTW89_WW][8] = 26, + [1][0][RTW89_WW][10] = 26, + [1][0][RTW89_WW][12] = 26, + [1][0][RTW89_WW][14] = 26, + [1][0][RTW89_WW][15] = 34, + [1][0][RTW89_WW][17] = 34, + [1][0][RTW89_WW][19] = 34, + [1][0][RTW89_WW][21] = 34, + [1][0][RTW89_WW][23] = 34, + [1][0][RTW89_WW][25] = 34, + [1][0][RTW89_WW][27] = 34, + [1][0][RTW89_WW][29] = 34, + [1][0][RTW89_WW][31] = 34, + [1][0][RTW89_WW][33] = 34, + [1][0][RTW89_WW][35] = 34, + [1][0][RTW89_WW][37] = 54, + [1][0][RTW89_WW][38] = 28, + [1][0][RTW89_WW][40] = 28, + [1][0][RTW89_WW][42] = 28, + [1][0][RTW89_WW][44] = 28, + [1][0][RTW89_WW][46] = 28, + [1][0][RTW89_WW][48] = 52, + [1][0][RTW89_WW][50] = 52, + [1][0][RTW89_WW][52] = 50, + [1][1][RTW89_WW][0] = 0, + [1][1][RTW89_WW][2] = 0, + [1][1][RTW89_WW][4] = 0, + [1][1][RTW89_WW][6] = 0, + [1][1][RTW89_WW][8] = 0, + [1][1][RTW89_WW][10] = 0, + [1][1][RTW89_WW][12] = 0, + [1][1][RTW89_WW][14] = 0, + [1][1][RTW89_WW][15] = 0, + [1][1][RTW89_WW][17] = 0, + [1][1][RTW89_WW][19] = 0, + [1][1][RTW89_WW][21] = 0, + [1][1][RTW89_WW][23] = 0, + [1][1][RTW89_WW][25] = 0, + [1][1][RTW89_WW][27] = 0, + [1][1][RTW89_WW][29] = 0, + [1][1][RTW89_WW][31] = 0, + [1][1][RTW89_WW][33] = 0, + [1][1][RTW89_WW][35] = 0, + [1][1][RTW89_WW][37] = 0, + [1][1][RTW89_WW][38] = 0, + [1][1][RTW89_WW][40] = 0, + [1][1][RTW89_WW][42] = 0, + [1][1][RTW89_WW][44] = 0, + [1][1][RTW89_WW][46] = 0, + [1][1][RTW89_WW][48] = 0, + [1][1][RTW89_WW][50] = 0, + [1][1][RTW89_WW][52] = 0, + [2][0][RTW89_WW][0] = 40, + [2][0][RTW89_WW][2] = 40, + [2][0][RTW89_WW][4] = 40, + [2][0][RTW89_WW][6] = 40, + [2][0][RTW89_WW][8] = 40, + [2][0][RTW89_WW][10] = 40, + [2][0][RTW89_WW][12] = 40, + [2][0][RTW89_WW][14] = 40, + [2][0][RTW89_WW][15] = 46, + [2][0][RTW89_WW][17] = 46, + [2][0][RTW89_WW][19] = 46, + [2][0][RTW89_WW][21] = 46, + [2][0][RTW89_WW][23] = 46, + [2][0][RTW89_WW][25] = 46, + [2][0][RTW89_WW][27] = 46, + [2][0][RTW89_WW][29] = 46, + [2][0][RTW89_WW][31] = 46, + [2][0][RTW89_WW][33] = 46, + [2][0][RTW89_WW][35] = 46, + [2][0][RTW89_WW][37] = 66, + [2][0][RTW89_WW][38] = 28, + [2][0][RTW89_WW][40] = 28, + [2][0][RTW89_WW][42] = 28, + [2][0][RTW89_WW][44] = 28, + [2][0][RTW89_WW][46] = 28, + [2][0][RTW89_WW][48] = 62, + [2][0][RTW89_WW][50] = 62, + [2][0][RTW89_WW][52] = 60, + [2][1][RTW89_WW][0] = 0, + [2][1][RTW89_WW][2] = 0, + [2][1][RTW89_WW][4] = 0, + [2][1][RTW89_WW][6] = 0, + [2][1][RTW89_WW][8] = 0, + [2][1][RTW89_WW][10] = 0, + [2][1][RTW89_WW][12] = 0, + [2][1][RTW89_WW][14] = 0, + [2][1][RTW89_WW][15] = 0, + [2][1][RTW89_WW][17] = 0, + [2][1][RTW89_WW][19] = 0, + [2][1][RTW89_WW][21] = 0, + [2][1][RTW89_WW][23] = 0, + [2][1][RTW89_WW][25] = 0, + [2][1][RTW89_WW][27] = 0, + [2][1][RTW89_WW][29] = 0, + [2][1][RTW89_WW][31] = 0, + [2][1][RTW89_WW][33] = 0, + [2][1][RTW89_WW][35] = 0, + [2][1][RTW89_WW][37] = 0, + [2][1][RTW89_WW][38] = 0, + [2][1][RTW89_WW][40] = 0, + [2][1][RTW89_WW][42] = 0, + [2][1][RTW89_WW][44] = 0, + [2][1][RTW89_WW][46] = 0, + [2][1][RTW89_WW][48] = 0, + [2][1][RTW89_WW][50] = 0, + [2][1][RTW89_WW][52] = 0, + [0][0][RTW89_FCC][0] = 50, + [0][0][RTW89_ETSI][0] = 24, + [0][0][RTW89_MKK][0] = 26, + [0][0][RTW89_IC][0] = 28, + [0][0][RTW89_KCC][0] = 42, + [0][0][RTW89_ACMA][0] = 24, + [0][0][RTW89_CN][0] = 16, + [0][0][RTW89_UK][0] = 24, + [0][0][RTW89_FCC][2] = 54, + [0][0][RTW89_ETSI][2] = 24, + [0][0][RTW89_MKK][2] = 26, + [0][0][RTW89_IC][2] = 28, + [0][0][RTW89_KCC][2] = 42, + [0][0][RTW89_ACMA][2] = 24, + [0][0][RTW89_CN][2] = 16, + [0][0][RTW89_UK][2] = 24, + [0][0][RTW89_FCC][4] = 50, + [0][0][RTW89_ETSI][4] = 24, + [0][0][RTW89_MKK][4] = 26, + [0][0][RTW89_IC][4] = 28, + [0][0][RTW89_KCC][4] = 42, + [0][0][RTW89_ACMA][4] = 24, + [0][0][RTW89_CN][4] = 16, + [0][0][RTW89_UK][4] = 24, + [0][0][RTW89_FCC][6] = 50, + [0][0][RTW89_ETSI][6] = 24, + [0][0][RTW89_MKK][6] = 26, + [0][0][RTW89_IC][6] = 28, + [0][0][RTW89_KCC][6] = 18, + [0][0][RTW89_ACMA][6] = 24, + [0][0][RTW89_CN][6] = 16, + [0][0][RTW89_UK][6] = 24, + [0][0][RTW89_FCC][8] = 52, + [0][0][RTW89_ETSI][8] = 24, + [0][0][RTW89_MKK][8] = 26, + [0][0][RTW89_IC][8] = 52, + [0][0][RTW89_KCC][8] = 42, + [0][0][RTW89_ACMA][8] = 24, + [0][0][RTW89_CN][8] = 16, + [0][0][RTW89_UK][8] = 24, + [0][0][RTW89_FCC][10] = 52, + [0][0][RTW89_ETSI][10] = 24, + [0][0][RTW89_MKK][10] = 26, + [0][0][RTW89_IC][10] = 52, + [0][0][RTW89_KCC][10] = 42, + [0][0][RTW89_ACMA][10] = 24, + [0][0][RTW89_CN][10] = 16, + [0][0][RTW89_UK][10] = 24, + [0][0][RTW89_FCC][12] = 56, + [0][0][RTW89_ETSI][12] = 24, + [0][0][RTW89_MKK][12] = 26, + [0][0][RTW89_IC][12] = 56, + [0][0][RTW89_KCC][12] = 44, + [0][0][RTW89_ACMA][12] = 24, + [0][0][RTW89_CN][12] = 16, + [0][0][RTW89_UK][12] = 24, + [0][0][RTW89_FCC][14] = 56, + [0][0][RTW89_ETSI][14] = 24, + [0][0][RTW89_MKK][14] = 26, + [0][0][RTW89_IC][14] = 56, + [0][0][RTW89_KCC][14] = 44, + [0][0][RTW89_ACMA][14] = 24, + [0][0][RTW89_CN][14] = 16, + [0][0][RTW89_UK][14] = 24, + [0][0][RTW89_FCC][15] = 52, + [0][0][RTW89_ETSI][15] = 24, + [0][0][RTW89_MKK][15] = 46, + [0][0][RTW89_IC][15] = 52, + [0][0][RTW89_KCC][15] = 44, + [0][0][RTW89_ACMA][15] = 24, + [0][0][RTW89_CN][15] = 127, + [0][0][RTW89_UK][15] = 24, + [0][0][RTW89_FCC][17] = 52, + [0][0][RTW89_ETSI][17] = 24, + [0][0][RTW89_MKK][17] = 50, + [0][0][RTW89_IC][17] = 52, + [0][0][RTW89_KCC][17] = 44, + [0][0][RTW89_ACMA][17] = 24, + [0][0][RTW89_CN][17] = 127, + [0][0][RTW89_UK][17] = 24, + [0][0][RTW89_FCC][19] = 52, + [0][0][RTW89_ETSI][19] = 24, + [0][0][RTW89_MKK][19] = 50, + [0][0][RTW89_IC][19] = 52, + [0][0][RTW89_KCC][19] = 44, + [0][0][RTW89_ACMA][19] = 24, + [0][0][RTW89_CN][19] = 127, + [0][0][RTW89_UK][19] = 24, + [0][0][RTW89_FCC][21] = 52, + [0][0][RTW89_ETSI][21] = 24, + [0][0][RTW89_MKK][21] = 50, + [0][0][RTW89_IC][21] = 52, + [0][0][RTW89_KCC][21] = 44, + [0][0][RTW89_ACMA][21] = 24, + [0][0][RTW89_CN][21] = 127, + [0][0][RTW89_UK][21] = 24, + [0][0][RTW89_FCC][23] = 52, + [0][0][RTW89_ETSI][23] = 24, + [0][0][RTW89_MKK][23] = 50, + [0][0][RTW89_IC][23] = 52, + [0][0][RTW89_KCC][23] = 44, + [0][0][RTW89_ACMA][23] = 24, + [0][0][RTW89_CN][23] = 127, + [0][0][RTW89_UK][23] = 24, + [0][0][RTW89_FCC][25] = 52, + [0][0][RTW89_ETSI][25] = 24, + [0][0][RTW89_MKK][25] = 50, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_KCC][25] = 44, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_CN][25] = 127, + [0][0][RTW89_UK][25] = 24, + [0][0][RTW89_FCC][27] = 52, + [0][0][RTW89_ETSI][27] = 24, + [0][0][RTW89_MKK][27] = 50, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_KCC][27] = 42, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_CN][27] = 127, + [0][0][RTW89_UK][27] = 24, + [0][0][RTW89_FCC][29] = 52, + [0][0][RTW89_ETSI][29] = 24, + [0][0][RTW89_MKK][29] = 50, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_KCC][29] = 42, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_CN][29] = 127, + [0][0][RTW89_UK][29] = 24, + [0][0][RTW89_FCC][31] = 52, + [0][0][RTW89_ETSI][31] = 24, + [0][0][RTW89_MKK][31] = 50, + [0][0][RTW89_IC][31] = 56, + [0][0][RTW89_KCC][31] = 42, + [0][0][RTW89_ACMA][31] = 24, + [0][0][RTW89_CN][31] = 127, + [0][0][RTW89_UK][31] = 24, + [0][0][RTW89_FCC][33] = 56, + [0][0][RTW89_ETSI][33] = 24, + [0][0][RTW89_MKK][33] = 50, + [0][0][RTW89_IC][33] = 56, + [0][0][RTW89_KCC][33] = 42, + [0][0][RTW89_ACMA][33] = 24, + [0][0][RTW89_CN][33] = 127, + [0][0][RTW89_UK][33] = 24, + [0][0][RTW89_FCC][35] = 56, + [0][0][RTW89_ETSI][35] = 24, + [0][0][RTW89_MKK][35] = 50, + [0][0][RTW89_IC][35] = 56, + [0][0][RTW89_KCC][35] = 42, + [0][0][RTW89_ACMA][35] = 24, + [0][0][RTW89_CN][35] = 127, + [0][0][RTW89_UK][35] = 24, + [0][0][RTW89_FCC][37] = 84, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 46, + [0][0][RTW89_IC][37] = 84, + [0][0][RTW89_KCC][37] = 44, + [0][0][RTW89_ACMA][37] = 50, + [0][0][RTW89_CN][37] = 127, + [0][0][RTW89_UK][37] = 52, + [0][0][RTW89_FCC][38] = 68, + [0][0][RTW89_ETSI][38] = 28, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 68, + [0][0][RTW89_KCC][38] = 44, + [0][0][RTW89_ACMA][38] = 84, + [0][0][RTW89_CN][38] = 54, + [0][0][RTW89_UK][38] = 24, + [0][0][RTW89_FCC][40] = 68, + [0][0][RTW89_ETSI][40] = 28, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 68, + [0][0][RTW89_KCC][40] = 44, + [0][0][RTW89_ACMA][40] = 84, + [0][0][RTW89_CN][40] = 54, + [0][0][RTW89_UK][40] = 24, + [0][0][RTW89_FCC][42] = 70, + [0][0][RTW89_ETSI][42] = 28, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 70, + [0][0][RTW89_KCC][42] = 44, + [0][0][RTW89_ACMA][42] = 84, + [0][0][RTW89_CN][42] = 54, + [0][0][RTW89_UK][42] = 24, + [0][0][RTW89_FCC][44] = 62, + [0][0][RTW89_ETSI][44] = 28, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 62, + [0][0][RTW89_KCC][44] = 44, + [0][0][RTW89_ACMA][44] = 84, + [0][0][RTW89_CN][44] = 54, + [0][0][RTW89_UK][44] = 24, + [0][0][RTW89_FCC][46] = 62, + [0][0][RTW89_ETSI][46] = 28, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 62, + [0][0][RTW89_KCC][46] = 44, + [0][0][RTW89_ACMA][46] = 84, + [0][0][RTW89_CN][46] = 54, + [0][0][RTW89_UK][46] = 24, + [0][0][RTW89_FCC][48] = 40, + [0][0][RTW89_ETSI][48] = 127, + [0][0][RTW89_MKK][48] = 127, + [0][0][RTW89_IC][48] = 40, + [0][0][RTW89_KCC][48] = 127, + [0][0][RTW89_ACMA][48] = 127, + [0][0][RTW89_CN][48] = 127, + [0][0][RTW89_UK][48] = 127, + [0][0][RTW89_FCC][50] = 42, + [0][0][RTW89_ETSI][50] = 127, + [0][0][RTW89_MKK][50] = 127, + [0][0][RTW89_IC][50] = 42, + [0][0][RTW89_KCC][50] = 127, + [0][0][RTW89_ACMA][50] = 127, + [0][0][RTW89_CN][50] = 127, + [0][0][RTW89_UK][50] = 127, + [0][0][RTW89_FCC][52] = 38, + [0][0][RTW89_ETSI][52] = 127, + [0][0][RTW89_MKK][52] = 127, + [0][0][RTW89_IC][52] = 38, + [0][0][RTW89_KCC][52] = 127, + [0][0][RTW89_ACMA][52] = 127, + [0][0][RTW89_CN][52] = 127, + [0][0][RTW89_UK][52] = 127, + [0][1][RTW89_FCC][0] = 127, + [0][1][RTW89_ETSI][0] = 127, + [0][1][RTW89_MKK][0] = 127, + [0][1][RTW89_IC][0] = 127, + [0][1][RTW89_KCC][0] = 127, + [0][1][RTW89_ACMA][0] = 127, + [0][1][RTW89_CN][0] = 127, + [0][1][RTW89_UK][0] = 127, + [0][1][RTW89_FCC][2] = 127, + [0][1][RTW89_ETSI][2] = 127, + [0][1][RTW89_MKK][2] = 127, + [0][1][RTW89_IC][2] = 127, + [0][1][RTW89_KCC][2] = 127, + [0][1][RTW89_ACMA][2] = 127, + [0][1][RTW89_CN][2] = 127, + [0][1][RTW89_UK][2] = 127, + [0][1][RTW89_FCC][4] = 127, + [0][1][RTW89_ETSI][4] = 127, + [0][1][RTW89_MKK][4] = 127, + [0][1][RTW89_IC][4] = 127, + [0][1][RTW89_KCC][4] = 127, + [0][1][RTW89_ACMA][4] = 127, + [0][1][RTW89_CN][4] = 127, + [0][1][RTW89_UK][4] = 127, + [0][1][RTW89_FCC][6] = 127, + [0][1][RTW89_ETSI][6] = 127, + [0][1][RTW89_MKK][6] = 127, + [0][1][RTW89_IC][6] = 127, + [0][1][RTW89_KCC][6] = 127, + [0][1][RTW89_ACMA][6] = 127, + [0][1][RTW89_CN][6] = 127, + [0][1][RTW89_UK][6] = 127, + [0][1][RTW89_FCC][8] = 127, + [0][1][RTW89_ETSI][8] = 127, + [0][1][RTW89_MKK][8] = 127, + [0][1][RTW89_IC][8] = 127, + [0][1][RTW89_KCC][8] = 127, + [0][1][RTW89_ACMA][8] = 127, + [0][1][RTW89_CN][8] = 127, + [0][1][RTW89_UK][8] = 127, + [0][1][RTW89_FCC][10] = 127, + [0][1][RTW89_ETSI][10] = 127, + [0][1][RTW89_MKK][10] = 127, + [0][1][RTW89_IC][10] = 127, + [0][1][RTW89_KCC][10] = 127, + [0][1][RTW89_ACMA][10] = 127, + [0][1][RTW89_CN][10] = 127, + [0][1][RTW89_UK][10] = 127, + [0][1][RTW89_FCC][12] = 127, + [0][1][RTW89_ETSI][12] = 127, + [0][1][RTW89_MKK][12] = 127, + [0][1][RTW89_IC][12] = 127, + [0][1][RTW89_KCC][12] = 127, + [0][1][RTW89_ACMA][12] = 127, + [0][1][RTW89_CN][12] = 127, + [0][1][RTW89_UK][12] = 127, + [0][1][RTW89_FCC][14] = 127, + [0][1][RTW89_ETSI][14] = 127, + [0][1][RTW89_MKK][14] = 127, + [0][1][RTW89_IC][14] = 127, + [0][1][RTW89_KCC][14] = 127, + [0][1][RTW89_ACMA][14] = 127, + [0][1][RTW89_CN][14] = 127, + [0][1][RTW89_UK][14] = 127, + [0][1][RTW89_FCC][15] = 127, + [0][1][RTW89_ETSI][15] = 127, + [0][1][RTW89_MKK][15] = 127, + [0][1][RTW89_IC][15] = 127, + [0][1][RTW89_KCC][15] = 127, + [0][1][RTW89_ACMA][15] = 127, + [0][1][RTW89_CN][15] = 127, + [0][1][RTW89_UK][15] = 127, + [0][1][RTW89_FCC][17] = 127, + [0][1][RTW89_ETSI][17] = 127, + [0][1][RTW89_MKK][17] = 127, + [0][1][RTW89_IC][17] = 127, + [0][1][RTW89_KCC][17] = 127, + [0][1][RTW89_ACMA][17] = 127, + [0][1][RTW89_CN][17] = 127, + [0][1][RTW89_UK][17] = 127, + [0][1][RTW89_FCC][19] = 127, + [0][1][RTW89_ETSI][19] = 127, + [0][1][RTW89_MKK][19] = 127, + [0][1][RTW89_IC][19] = 127, + [0][1][RTW89_KCC][19] = 127, + [0][1][RTW89_ACMA][19] = 127, + [0][1][RTW89_CN][19] = 127, + [0][1][RTW89_UK][19] = 127, + [0][1][RTW89_FCC][21] = 127, + [0][1][RTW89_ETSI][21] = 127, + [0][1][RTW89_MKK][21] = 127, + [0][1][RTW89_IC][21] = 127, + [0][1][RTW89_KCC][21] = 127, + [0][1][RTW89_ACMA][21] = 127, + [0][1][RTW89_CN][21] = 127, + [0][1][RTW89_UK][21] = 127, + [0][1][RTW89_FCC][23] = 127, + [0][1][RTW89_ETSI][23] = 127, + [0][1][RTW89_MKK][23] = 127, + [0][1][RTW89_IC][23] = 127, + [0][1][RTW89_KCC][23] = 127, + [0][1][RTW89_ACMA][23] = 127, + [0][1][RTW89_CN][23] = 127, + [0][1][RTW89_UK][23] = 127, + [0][1][RTW89_FCC][25] = 127, + [0][1][RTW89_ETSI][25] = 127, + [0][1][RTW89_MKK][25] = 127, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_KCC][25] = 127, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_CN][25] = 127, + [0][1][RTW89_UK][25] = 127, + [0][1][RTW89_FCC][27] = 127, + [0][1][RTW89_ETSI][27] = 127, + [0][1][RTW89_MKK][27] = 127, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_KCC][27] = 127, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_CN][27] = 127, + [0][1][RTW89_UK][27] = 127, + [0][1][RTW89_FCC][29] = 127, + [0][1][RTW89_ETSI][29] = 127, + [0][1][RTW89_MKK][29] = 127, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_KCC][29] = 127, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_CN][29] = 127, + [0][1][RTW89_UK][29] = 127, + [0][1][RTW89_FCC][31] = 127, + [0][1][RTW89_ETSI][31] = 127, + [0][1][RTW89_MKK][31] = 127, + [0][1][RTW89_IC][31] = 127, + [0][1][RTW89_KCC][31] = 127, + [0][1][RTW89_ACMA][31] = 127, + [0][1][RTW89_CN][31] = 127, + [0][1][RTW89_UK][31] = 127, + [0][1][RTW89_FCC][33] = 127, + [0][1][RTW89_ETSI][33] = 127, + [0][1][RTW89_MKK][33] = 127, + [0][1][RTW89_IC][33] = 127, + [0][1][RTW89_KCC][33] = 127, + [0][1][RTW89_ACMA][33] = 127, + [0][1][RTW89_CN][33] = 127, + [0][1][RTW89_UK][33] = 127, + [0][1][RTW89_FCC][35] = 127, + [0][1][RTW89_ETSI][35] = 127, + [0][1][RTW89_MKK][35] = 127, + [0][1][RTW89_IC][35] = 127, + [0][1][RTW89_KCC][35] = 127, + [0][1][RTW89_ACMA][35] = 127, + [0][1][RTW89_CN][35] = 127, + [0][1][RTW89_UK][35] = 127, + [0][1][RTW89_FCC][37] = 127, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 127, + [0][1][RTW89_IC][37] = 127, + [0][1][RTW89_KCC][37] = 127, + [0][1][RTW89_ACMA][37] = 127, + [0][1][RTW89_CN][37] = 127, + [0][1][RTW89_UK][37] = 127, + [0][1][RTW89_FCC][38] = 127, + [0][1][RTW89_ETSI][38] = 127, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 127, + [0][1][RTW89_KCC][38] = 127, + [0][1][RTW89_ACMA][38] = 127, + [0][1][RTW89_CN][38] = 127, + [0][1][RTW89_UK][38] = 127, + [0][1][RTW89_FCC][40] = 127, + [0][1][RTW89_ETSI][40] = 127, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 127, + [0][1][RTW89_KCC][40] = 127, + [0][1][RTW89_ACMA][40] = 127, + [0][1][RTW89_CN][40] = 127, + [0][1][RTW89_UK][40] = 127, + [0][1][RTW89_FCC][42] = 127, + [0][1][RTW89_ETSI][42] = 127, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 127, + [0][1][RTW89_KCC][42] = 127, + [0][1][RTW89_ACMA][42] = 127, + [0][1][RTW89_CN][42] = 127, + [0][1][RTW89_UK][42] = 127, + [0][1][RTW89_FCC][44] = 127, + [0][1][RTW89_ETSI][44] = 127, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 127, + [0][1][RTW89_KCC][44] = 127, + [0][1][RTW89_ACMA][44] = 127, + [0][1][RTW89_CN][44] = 127, + [0][1][RTW89_UK][44] = 127, + [0][1][RTW89_FCC][46] = 127, + [0][1][RTW89_ETSI][46] = 127, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 127, + [0][1][RTW89_KCC][46] = 127, + [0][1][RTW89_ACMA][46] = 127, + [0][1][RTW89_CN][46] = 127, + [0][1][RTW89_UK][46] = 127, + [0][1][RTW89_FCC][48] = 127, + [0][1][RTW89_ETSI][48] = 127, + [0][1][RTW89_MKK][48] = 127, + [0][1][RTW89_IC][48] = 127, + [0][1][RTW89_KCC][48] = 127, + [0][1][RTW89_ACMA][48] = 127, + [0][1][RTW89_CN][48] = 127, + [0][1][RTW89_UK][48] = 127, + [0][1][RTW89_FCC][50] = 127, + [0][1][RTW89_ETSI][50] = 127, + [0][1][RTW89_MKK][50] = 127, + [0][1][RTW89_IC][50] = 127, + [0][1][RTW89_KCC][50] = 127, + [0][1][RTW89_ACMA][50] = 127, + [0][1][RTW89_CN][50] = 127, + [0][1][RTW89_UK][50] = 127, + [0][1][RTW89_FCC][52] = 127, + [0][1][RTW89_ETSI][52] = 127, + [0][1][RTW89_MKK][52] = 127, + [0][1][RTW89_IC][52] = 127, + [0][1][RTW89_KCC][52] = 127, + [0][1][RTW89_ACMA][52] = 127, + [0][1][RTW89_CN][52] = 127, + [0][1][RTW89_UK][52] = 127, + [1][0][RTW89_FCC][0] = 64, + [1][0][RTW89_ETSI][0] = 34, + [1][0][RTW89_MKK][0] = 38, + [1][0][RTW89_IC][0] = 38, + [1][0][RTW89_KCC][0] = 52, + [1][0][RTW89_ACMA][0] = 34, + [1][0][RTW89_CN][0] = 26, + [1][0][RTW89_UK][0] = 34, + [1][0][RTW89_FCC][2] = 66, + [1][0][RTW89_ETSI][2] = 34, + [1][0][RTW89_MKK][2] = 38, + [1][0][RTW89_IC][2] = 38, + [1][0][RTW89_KCC][2] = 52, + [1][0][RTW89_ACMA][2] = 34, + [1][0][RTW89_CN][2] = 26, + [1][0][RTW89_UK][2] = 34, + [1][0][RTW89_FCC][4] = 60, + [1][0][RTW89_ETSI][4] = 34, + [1][0][RTW89_MKK][4] = 36, + [1][0][RTW89_IC][4] = 38, + [1][0][RTW89_KCC][4] = 52, + [1][0][RTW89_ACMA][4] = 34, + [1][0][RTW89_CN][4] = 26, + [1][0][RTW89_UK][4] = 34, + [1][0][RTW89_FCC][6] = 60, + [1][0][RTW89_ETSI][6] = 34, + [1][0][RTW89_MKK][6] = 36, + [1][0][RTW89_IC][6] = 38, + [1][0][RTW89_KCC][6] = 32, + [1][0][RTW89_ACMA][6] = 34, + [1][0][RTW89_CN][6] = 26, + [1][0][RTW89_UK][6] = 34, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 34, + [1][0][RTW89_MKK][8] = 38, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_KCC][8] = 52, + [1][0][RTW89_ACMA][8] = 34, + [1][0][RTW89_CN][8] = 26, + [1][0][RTW89_UK][8] = 34, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 34, + [1][0][RTW89_MKK][10] = 38, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_KCC][10] = 52, + [1][0][RTW89_ACMA][10] = 34, + [1][0][RTW89_CN][10] = 26, + [1][0][RTW89_UK][10] = 34, + [1][0][RTW89_FCC][12] = 62, + [1][0][RTW89_ETSI][12] = 34, + [1][0][RTW89_MKK][12] = 38, + [1][0][RTW89_IC][12] = 62, + [1][0][RTW89_KCC][12] = 54, + [1][0][RTW89_ACMA][12] = 34, + [1][0][RTW89_CN][12] = 26, + [1][0][RTW89_UK][12] = 34, + [1][0][RTW89_FCC][14] = 62, + [1][0][RTW89_ETSI][14] = 34, + [1][0][RTW89_MKK][14] = 38, + [1][0][RTW89_IC][14] = 62, + [1][0][RTW89_KCC][14] = 54, + [1][0][RTW89_ACMA][14] = 34, + [1][0][RTW89_CN][14] = 26, + [1][0][RTW89_UK][14] = 34, + [1][0][RTW89_FCC][15] = 60, + [1][0][RTW89_ETSI][15] = 34, + [1][0][RTW89_MKK][15] = 58, + [1][0][RTW89_IC][15] = 60, + [1][0][RTW89_KCC][15] = 54, + [1][0][RTW89_ACMA][15] = 34, + [1][0][RTW89_CN][15] = 127, + [1][0][RTW89_UK][15] = 34, + [1][0][RTW89_FCC][17] = 60, + [1][0][RTW89_ETSI][17] = 34, + [1][0][RTW89_MKK][17] = 58, + [1][0][RTW89_IC][17] = 60, + [1][0][RTW89_KCC][17] = 54, + [1][0][RTW89_ACMA][17] = 34, + [1][0][RTW89_CN][17] = 127, + [1][0][RTW89_UK][17] = 34, + [1][0][RTW89_FCC][19] = 62, + [1][0][RTW89_ETSI][19] = 34, + [1][0][RTW89_MKK][19] = 58, + [1][0][RTW89_IC][19] = 62, + [1][0][RTW89_KCC][19] = 54, + [1][0][RTW89_ACMA][19] = 34, + [1][0][RTW89_CN][19] = 127, + [1][0][RTW89_UK][19] = 34, + [1][0][RTW89_FCC][21] = 62, + [1][0][RTW89_ETSI][21] = 34, + [1][0][RTW89_MKK][21] = 58, + [1][0][RTW89_IC][21] = 62, + [1][0][RTW89_KCC][21] = 54, + [1][0][RTW89_ACMA][21] = 34, + [1][0][RTW89_CN][21] = 127, + [1][0][RTW89_UK][21] = 34, + [1][0][RTW89_FCC][23] = 62, + [1][0][RTW89_ETSI][23] = 34, + [1][0][RTW89_MKK][23] = 58, + [1][0][RTW89_IC][23] = 62, + [1][0][RTW89_KCC][23] = 54, + [1][0][RTW89_ACMA][23] = 34, + [1][0][RTW89_CN][23] = 127, + [1][0][RTW89_UK][23] = 34, + [1][0][RTW89_FCC][25] = 62, + [1][0][RTW89_ETSI][25] = 34, + [1][0][RTW89_MKK][25] = 58, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_KCC][25] = 54, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_CN][25] = 127, + [1][0][RTW89_UK][25] = 34, + [1][0][RTW89_FCC][27] = 62, + [1][0][RTW89_ETSI][27] = 34, + [1][0][RTW89_MKK][27] = 58, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_KCC][27] = 54, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_CN][27] = 127, + [1][0][RTW89_UK][27] = 34, + [1][0][RTW89_FCC][29] = 62, + [1][0][RTW89_ETSI][29] = 34, + [1][0][RTW89_MKK][29] = 58, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_KCC][29] = 54, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_CN][29] = 127, + [1][0][RTW89_UK][29] = 34, + [1][0][RTW89_FCC][31] = 62, + [1][0][RTW89_ETSI][31] = 34, + [1][0][RTW89_MKK][31] = 58, + [1][0][RTW89_IC][31] = 64, + [1][0][RTW89_KCC][31] = 54, + [1][0][RTW89_ACMA][31] = 34, + [1][0][RTW89_CN][31] = 127, + [1][0][RTW89_UK][31] = 34, + [1][0][RTW89_FCC][33] = 64, + [1][0][RTW89_ETSI][33] = 34, + [1][0][RTW89_MKK][33] = 58, + [1][0][RTW89_IC][33] = 64, + [1][0][RTW89_KCC][33] = 54, + [1][0][RTW89_ACMA][33] = 34, + [1][0][RTW89_CN][33] = 127, + [1][0][RTW89_UK][33] = 34, + [1][0][RTW89_FCC][35] = 64, + [1][0][RTW89_ETSI][35] = 34, + [1][0][RTW89_MKK][35] = 58, + [1][0][RTW89_IC][35] = 64, + [1][0][RTW89_KCC][35] = 54, + [1][0][RTW89_ACMA][35] = 34, + [1][0][RTW89_CN][35] = 127, + [1][0][RTW89_UK][35] = 34, + [1][0][RTW89_FCC][37] = 76, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 56, + [1][0][RTW89_IC][37] = 76, + [1][0][RTW89_KCC][37] = 54, + [1][0][RTW89_ACMA][37] = 62, + [1][0][RTW89_CN][37] = 127, + [1][0][RTW89_UK][37] = 62, + [1][0][RTW89_FCC][38] = 82, + [1][0][RTW89_ETSI][38] = 28, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 82, + [1][0][RTW89_KCC][38] = 54, + [1][0][RTW89_ACMA][38] = 84, + [1][0][RTW89_CN][38] = 66, + [1][0][RTW89_UK][38] = 34, + [1][0][RTW89_FCC][40] = 82, + [1][0][RTW89_ETSI][40] = 28, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 82, + [1][0][RTW89_KCC][40] = 54, + [1][0][RTW89_ACMA][40] = 84, + [1][0][RTW89_CN][40] = 66, + [1][0][RTW89_UK][40] = 34, + [1][0][RTW89_FCC][42] = 78, + [1][0][RTW89_ETSI][42] = 28, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 78, + [1][0][RTW89_KCC][42] = 54, + [1][0][RTW89_ACMA][42] = 84, + [1][0][RTW89_CN][42] = 66, + [1][0][RTW89_UK][42] = 34, + [1][0][RTW89_FCC][44] = 82, + [1][0][RTW89_ETSI][44] = 28, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 82, + [1][0][RTW89_KCC][44] = 54, + [1][0][RTW89_ACMA][44] = 84, + [1][0][RTW89_CN][44] = 66, + [1][0][RTW89_UK][44] = 34, + [1][0][RTW89_FCC][46] = 82, + [1][0][RTW89_ETSI][46] = 28, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 82, + [1][0][RTW89_KCC][46] = 54, + [1][0][RTW89_ACMA][46] = 84, + [1][0][RTW89_CN][46] = 66, + [1][0][RTW89_UK][46] = 34, + [1][0][RTW89_FCC][48] = 52, + [1][0][RTW89_ETSI][48] = 127, + [1][0][RTW89_MKK][48] = 127, + [1][0][RTW89_IC][48] = 52, + [1][0][RTW89_KCC][48] = 127, + [1][0][RTW89_ACMA][48] = 127, + [1][0][RTW89_CN][48] = 127, + [1][0][RTW89_UK][48] = 127, + [1][0][RTW89_FCC][50] = 52, + [1][0][RTW89_ETSI][50] = 127, + [1][0][RTW89_MKK][50] = 127, + [1][0][RTW89_IC][50] = 52, + [1][0][RTW89_KCC][50] = 127, + [1][0][RTW89_ACMA][50] = 127, + [1][0][RTW89_CN][50] = 127, + [1][0][RTW89_UK][50] = 127, + [1][0][RTW89_FCC][52] = 50, + [1][0][RTW89_ETSI][52] = 127, + [1][0][RTW89_MKK][52] = 127, + [1][0][RTW89_IC][52] = 50, + [1][0][RTW89_KCC][52] = 127, + [1][0][RTW89_ACMA][52] = 127, + [1][0][RTW89_CN][52] = 127, + [1][0][RTW89_UK][52] = 127, + [1][1][RTW89_FCC][0] = 127, + [1][1][RTW89_ETSI][0] = 127, + [1][1][RTW89_MKK][0] = 127, + [1][1][RTW89_IC][0] = 127, + [1][1][RTW89_KCC][0] = 127, + [1][1][RTW89_ACMA][0] = 127, + [1][1][RTW89_CN][0] = 127, + [1][1][RTW89_UK][0] = 127, + [1][1][RTW89_FCC][2] = 127, + [1][1][RTW89_ETSI][2] = 127, + [1][1][RTW89_MKK][2] = 127, + [1][1][RTW89_IC][2] = 127, + [1][1][RTW89_KCC][2] = 127, + [1][1][RTW89_ACMA][2] = 127, + [1][1][RTW89_CN][2] = 127, + [1][1][RTW89_UK][2] = 127, + [1][1][RTW89_FCC][4] = 127, + [1][1][RTW89_ETSI][4] = 127, + [1][1][RTW89_MKK][4] = 127, + [1][1][RTW89_IC][4] = 127, + [1][1][RTW89_KCC][4] = 127, + [1][1][RTW89_ACMA][4] = 127, + [1][1][RTW89_CN][4] = 127, + [1][1][RTW89_UK][4] = 127, + [1][1][RTW89_FCC][6] = 127, + [1][1][RTW89_ETSI][6] = 127, + [1][1][RTW89_MKK][6] = 127, + [1][1][RTW89_IC][6] = 127, + [1][1][RTW89_KCC][6] = 127, + [1][1][RTW89_ACMA][6] = 127, + [1][1][RTW89_CN][6] = 127, + [1][1][RTW89_UK][6] = 127, + [1][1][RTW89_FCC][8] = 127, + [1][1][RTW89_ETSI][8] = 127, + [1][1][RTW89_MKK][8] = 127, + [1][1][RTW89_IC][8] = 127, + [1][1][RTW89_KCC][8] = 127, + [1][1][RTW89_ACMA][8] = 127, + [1][1][RTW89_CN][8] = 127, + [1][1][RTW89_UK][8] = 127, + [1][1][RTW89_FCC][10] = 127, + [1][1][RTW89_ETSI][10] = 127, + [1][1][RTW89_MKK][10] = 127, + [1][1][RTW89_IC][10] = 127, + [1][1][RTW89_KCC][10] = 127, + [1][1][RTW89_ACMA][10] = 127, + [1][1][RTW89_CN][10] = 127, + [1][1][RTW89_UK][10] = 127, + [1][1][RTW89_FCC][12] = 127, + [1][1][RTW89_ETSI][12] = 127, + [1][1][RTW89_MKK][12] = 127, + [1][1][RTW89_IC][12] = 127, + [1][1][RTW89_KCC][12] = 127, + [1][1][RTW89_ACMA][12] = 127, + [1][1][RTW89_CN][12] = 127, + [1][1][RTW89_UK][12] = 127, + [1][1][RTW89_FCC][14] = 127, + [1][1][RTW89_ETSI][14] = 127, + [1][1][RTW89_MKK][14] = 127, + [1][1][RTW89_IC][14] = 127, + [1][1][RTW89_KCC][14] = 127, + [1][1][RTW89_ACMA][14] = 127, + [1][1][RTW89_CN][14] = 127, + [1][1][RTW89_UK][14] = 127, + [1][1][RTW89_FCC][15] = 127, + [1][1][RTW89_ETSI][15] = 127, + [1][1][RTW89_MKK][15] = 127, + [1][1][RTW89_IC][15] = 127, + [1][1][RTW89_KCC][15] = 127, + [1][1][RTW89_ACMA][15] = 127, + [1][1][RTW89_CN][15] = 127, + [1][1][RTW89_UK][15] = 127, + [1][1][RTW89_FCC][17] = 127, + [1][1][RTW89_ETSI][17] = 127, + [1][1][RTW89_MKK][17] = 127, + [1][1][RTW89_IC][17] = 127, + [1][1][RTW89_KCC][17] = 127, + [1][1][RTW89_ACMA][17] = 127, + [1][1][RTW89_CN][17] = 127, + [1][1][RTW89_UK][17] = 127, + [1][1][RTW89_FCC][19] = 127, + [1][1][RTW89_ETSI][19] = 127, + [1][1][RTW89_MKK][19] = 127, + [1][1][RTW89_IC][19] = 127, + [1][1][RTW89_KCC][19] = 127, + [1][1][RTW89_ACMA][19] = 127, + [1][1][RTW89_CN][19] = 127, + [1][1][RTW89_UK][19] = 127, + [1][1][RTW89_FCC][21] = 127, + [1][1][RTW89_ETSI][21] = 127, + [1][1][RTW89_MKK][21] = 127, + [1][1][RTW89_IC][21] = 127, + [1][1][RTW89_KCC][21] = 127, + [1][1][RTW89_ACMA][21] = 127, + [1][1][RTW89_CN][21] = 127, + [1][1][RTW89_UK][21] = 127, + [1][1][RTW89_FCC][23] = 127, + [1][1][RTW89_ETSI][23] = 127, + [1][1][RTW89_MKK][23] = 127, + [1][1][RTW89_IC][23] = 127, + [1][1][RTW89_KCC][23] = 127, + [1][1][RTW89_ACMA][23] = 127, + [1][1][RTW89_CN][23] = 127, + [1][1][RTW89_UK][23] = 127, + [1][1][RTW89_FCC][25] = 127, + [1][1][RTW89_ETSI][25] = 127, + [1][1][RTW89_MKK][25] = 127, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_KCC][25] = 127, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_CN][25] = 127, + [1][1][RTW89_UK][25] = 127, + [1][1][RTW89_FCC][27] = 127, + [1][1][RTW89_ETSI][27] = 127, + [1][1][RTW89_MKK][27] = 127, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_KCC][27] = 127, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_CN][27] = 127, + [1][1][RTW89_UK][27] = 127, + [1][1][RTW89_FCC][29] = 127, + [1][1][RTW89_ETSI][29] = 127, + [1][1][RTW89_MKK][29] = 127, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_KCC][29] = 127, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_CN][29] = 127, + [1][1][RTW89_UK][29] = 127, + [1][1][RTW89_FCC][31] = 127, + [1][1][RTW89_ETSI][31] = 127, + [1][1][RTW89_MKK][31] = 127, + [1][1][RTW89_IC][31] = 127, + [1][1][RTW89_KCC][31] = 127, + [1][1][RTW89_ACMA][31] = 127, + [1][1][RTW89_CN][31] = 127, + [1][1][RTW89_UK][31] = 127, + [1][1][RTW89_FCC][33] = 127, + [1][1][RTW89_ETSI][33] = 127, + [1][1][RTW89_MKK][33] = 127, + [1][1][RTW89_IC][33] = 127, + [1][1][RTW89_KCC][33] = 127, + [1][1][RTW89_ACMA][33] = 127, + [1][1][RTW89_CN][33] = 127, + [1][1][RTW89_UK][33] = 127, + [1][1][RTW89_FCC][35] = 127, + [1][1][RTW89_ETSI][35] = 127, + [1][1][RTW89_MKK][35] = 127, + [1][1][RTW89_IC][35] = 127, + [1][1][RTW89_KCC][35] = 127, + [1][1][RTW89_ACMA][35] = 127, + [1][1][RTW89_CN][35] = 127, + [1][1][RTW89_UK][35] = 127, + [1][1][RTW89_FCC][37] = 127, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 127, + [1][1][RTW89_IC][37] = 127, + [1][1][RTW89_KCC][37] = 127, + [1][1][RTW89_ACMA][37] = 127, + [1][1][RTW89_CN][37] = 127, + [1][1][RTW89_UK][37] = 127, + [1][1][RTW89_FCC][38] = 127, + [1][1][RTW89_ETSI][38] = 127, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 127, + [1][1][RTW89_KCC][38] = 127, + [1][1][RTW89_ACMA][38] = 127, + [1][1][RTW89_CN][38] = 127, + [1][1][RTW89_UK][38] = 127, + [1][1][RTW89_FCC][40] = 127, + [1][1][RTW89_ETSI][40] = 127, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 127, + [1][1][RTW89_KCC][40] = 127, + [1][1][RTW89_ACMA][40] = 127, + [1][1][RTW89_CN][40] = 127, + [1][1][RTW89_UK][40] = 127, + [1][1][RTW89_FCC][42] = 127, + [1][1][RTW89_ETSI][42] = 127, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 127, + [1][1][RTW89_KCC][42] = 127, + [1][1][RTW89_ACMA][42] = 127, + [1][1][RTW89_CN][42] = 127, + [1][1][RTW89_UK][42] = 127, + [1][1][RTW89_FCC][44] = 127, + [1][1][RTW89_ETSI][44] = 127, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 127, + [1][1][RTW89_KCC][44] = 127, + [1][1][RTW89_ACMA][44] = 127, + [1][1][RTW89_CN][44] = 127, + [1][1][RTW89_UK][44] = 127, + [1][1][RTW89_FCC][46] = 127, + [1][1][RTW89_ETSI][46] = 127, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 127, + [1][1][RTW89_KCC][46] = 127, + [1][1][RTW89_ACMA][46] = 127, + [1][1][RTW89_CN][46] = 127, + [1][1][RTW89_UK][46] = 127, + [1][1][RTW89_FCC][48] = 127, + [1][1][RTW89_ETSI][48] = 127, + [1][1][RTW89_MKK][48] = 127, + [1][1][RTW89_IC][48] = 127, + [1][1][RTW89_KCC][48] = 127, + [1][1][RTW89_ACMA][48] = 127, + [1][1][RTW89_CN][48] = 127, + [1][1][RTW89_UK][48] = 127, + [1][1][RTW89_FCC][50] = 127, + [1][1][RTW89_ETSI][50] = 127, + [1][1][RTW89_MKK][50] = 127, + [1][1][RTW89_IC][50] = 127, + [1][1][RTW89_KCC][50] = 127, + [1][1][RTW89_ACMA][50] = 127, + [1][1][RTW89_CN][50] = 127, + [1][1][RTW89_UK][50] = 127, + [1][1][RTW89_FCC][52] = 127, + [1][1][RTW89_ETSI][52] = 127, + [1][1][RTW89_MKK][52] = 127, + [1][1][RTW89_IC][52] = 127, + [1][1][RTW89_KCC][52] = 127, + [1][1][RTW89_ACMA][52] = 127, + [1][1][RTW89_CN][52] = 127, + [1][1][RTW89_UK][52] = 127, + [2][0][RTW89_FCC][0] = 76, + [2][0][RTW89_ETSI][0] = 46, + [2][0][RTW89_MKK][0] = 48, + [2][0][RTW89_IC][0] = 50, + [2][0][RTW89_KCC][0] = 64, + [2][0][RTW89_ACMA][0] = 46, + [2][0][RTW89_CN][0] = 40, + [2][0][RTW89_UK][0] = 46, + [2][0][RTW89_FCC][2] = 72, + [2][0][RTW89_ETSI][2] = 46, + [2][0][RTW89_MKK][2] = 48, + [2][0][RTW89_IC][2] = 48, + [2][0][RTW89_KCC][2] = 64, + [2][0][RTW89_ACMA][2] = 46, + [2][0][RTW89_CN][2] = 40, + [2][0][RTW89_UK][2] = 46, + [2][0][RTW89_FCC][4] = 74, + [2][0][RTW89_ETSI][4] = 46, + [2][0][RTW89_MKK][4] = 48, + [2][0][RTW89_IC][4] = 48, + [2][0][RTW89_KCC][4] = 64, + [2][0][RTW89_ACMA][4] = 46, + [2][0][RTW89_CN][4] = 40, + [2][0][RTW89_UK][4] = 46, + [2][0][RTW89_FCC][6] = 74, + [2][0][RTW89_ETSI][6] = 46, + [2][0][RTW89_MKK][6] = 48, + [2][0][RTW89_IC][6] = 48, + [2][0][RTW89_KCC][6] = 40, + [2][0][RTW89_ACMA][6] = 46, + [2][0][RTW89_CN][6] = 40, + [2][0][RTW89_UK][6] = 46, + [2][0][RTW89_FCC][8] = 72, + [2][0][RTW89_ETSI][8] = 46, + [2][0][RTW89_MKK][8] = 48, + [2][0][RTW89_IC][8] = 64, + [2][0][RTW89_KCC][8] = 66, + [2][0][RTW89_ACMA][8] = 46, + [2][0][RTW89_CN][8] = 40, + [2][0][RTW89_UK][8] = 46, + [2][0][RTW89_FCC][10] = 72, + [2][0][RTW89_ETSI][10] = 46, + [2][0][RTW89_MKK][10] = 48, + [2][0][RTW89_IC][10] = 64, + [2][0][RTW89_KCC][10] = 66, + [2][0][RTW89_ACMA][10] = 46, + [2][0][RTW89_CN][10] = 40, + [2][0][RTW89_UK][10] = 46, + [2][0][RTW89_FCC][12] = 74, + [2][0][RTW89_ETSI][12] = 46, + [2][0][RTW89_MKK][12] = 48, + [2][0][RTW89_IC][12] = 64, + [2][0][RTW89_KCC][12] = 64, + [2][0][RTW89_ACMA][12] = 46, + [2][0][RTW89_CN][12] = 40, + [2][0][RTW89_UK][12] = 46, + [2][0][RTW89_FCC][14] = 80, + [2][0][RTW89_ETSI][14] = 46, + [2][0][RTW89_MKK][14] = 48, + [2][0][RTW89_IC][14] = 64, + [2][0][RTW89_KCC][14] = 64, + [2][0][RTW89_ACMA][14] = 46, + [2][0][RTW89_CN][14] = 40, + [2][0][RTW89_UK][14] = 46, + [2][0][RTW89_FCC][15] = 72, + [2][0][RTW89_ETSI][15] = 46, + [2][0][RTW89_MKK][15] = 70, + [2][0][RTW89_IC][15] = 72, + [2][0][RTW89_KCC][15] = 66, + [2][0][RTW89_ACMA][15] = 46, + [2][0][RTW89_CN][15] = 127, + [2][0][RTW89_UK][15] = 46, + [2][0][RTW89_FCC][17] = 72, + [2][0][RTW89_ETSI][17] = 46, + [2][0][RTW89_MKK][17] = 70, + [2][0][RTW89_IC][17] = 72, + [2][0][RTW89_KCC][17] = 66, + [2][0][RTW89_ACMA][17] = 46, + [2][0][RTW89_CN][17] = 127, + [2][0][RTW89_UK][17] = 46, + [2][0][RTW89_FCC][19] = 68, + [2][0][RTW89_ETSI][19] = 46, + [2][0][RTW89_MKK][19] = 70, + [2][0][RTW89_IC][19] = 68, + [2][0][RTW89_KCC][19] = 66, + [2][0][RTW89_ACMA][19] = 46, + [2][0][RTW89_CN][19] = 127, + [2][0][RTW89_UK][19] = 46, + [2][0][RTW89_FCC][21] = 68, + [2][0][RTW89_ETSI][21] = 46, + [2][0][RTW89_MKK][21] = 70, + [2][0][RTW89_IC][21] = 68, + [2][0][RTW89_KCC][21] = 66, + [2][0][RTW89_ACMA][21] = 46, + [2][0][RTW89_CN][21] = 127, + [2][0][RTW89_UK][21] = 46, + [2][0][RTW89_FCC][23] = 68, + [2][0][RTW89_ETSI][23] = 46, + [2][0][RTW89_MKK][23] = 70, + [2][0][RTW89_IC][23] = 68, + [2][0][RTW89_KCC][23] = 66, + [2][0][RTW89_ACMA][23] = 46, + [2][0][RTW89_CN][23] = 127, + [2][0][RTW89_UK][23] = 46, + [2][0][RTW89_FCC][25] = 68, + [2][0][RTW89_ETSI][25] = 46, + [2][0][RTW89_MKK][25] = 70, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_KCC][25] = 66, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_CN][25] = 127, + [2][0][RTW89_UK][25] = 46, + [2][0][RTW89_FCC][27] = 68, + [2][0][RTW89_ETSI][27] = 46, + [2][0][RTW89_MKK][27] = 70, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_KCC][27] = 64, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_CN][27] = 127, + [2][0][RTW89_UK][27] = 46, + [2][0][RTW89_FCC][29] = 68, + [2][0][RTW89_ETSI][29] = 46, + [2][0][RTW89_MKK][29] = 70, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_KCC][29] = 64, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_CN][29] = 127, + [2][0][RTW89_UK][29] = 46, + [2][0][RTW89_FCC][31] = 68, + [2][0][RTW89_ETSI][31] = 46, + [2][0][RTW89_MKK][31] = 70, + [2][0][RTW89_IC][31] = 70, + [2][0][RTW89_KCC][31] = 64, + [2][0][RTW89_ACMA][31] = 46, + [2][0][RTW89_CN][31] = 127, + [2][0][RTW89_UK][31] = 46, + [2][0][RTW89_FCC][33] = 70, + [2][0][RTW89_ETSI][33] = 46, + [2][0][RTW89_MKK][33] = 70, + [2][0][RTW89_IC][33] = 70, + [2][0][RTW89_KCC][33] = 64, + [2][0][RTW89_ACMA][33] = 46, + [2][0][RTW89_CN][33] = 127, + [2][0][RTW89_UK][33] = 46, + [2][0][RTW89_FCC][35] = 70, + [2][0][RTW89_ETSI][35] = 46, + [2][0][RTW89_MKK][35] = 70, + [2][0][RTW89_IC][35] = 70, + [2][0][RTW89_KCC][35] = 64, + [2][0][RTW89_ACMA][35] = 46, + [2][0][RTW89_CN][35] = 127, + [2][0][RTW89_UK][35] = 46, + [2][0][RTW89_FCC][37] = 84, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 68, + [2][0][RTW89_IC][37] = 84, + [2][0][RTW89_KCC][37] = 66, + [2][0][RTW89_ACMA][37] = 74, + [2][0][RTW89_CN][37] = 127, + [2][0][RTW89_UK][37] = 74, + [2][0][RTW89_FCC][38] = 84, + [2][0][RTW89_ETSI][38] = 28, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 84, + [2][0][RTW89_KCC][38] = 64, + [2][0][RTW89_ACMA][38] = 84, + [2][0][RTW89_CN][38] = 68, + [2][0][RTW89_UK][38] = 46, + [2][0][RTW89_FCC][40] = 84, + [2][0][RTW89_ETSI][40] = 28, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 84, + [2][0][RTW89_KCC][40] = 64, + [2][0][RTW89_ACMA][40] = 84, + [2][0][RTW89_CN][40] = 68, + [2][0][RTW89_UK][40] = 46, + [2][0][RTW89_FCC][42] = 78, + [2][0][RTW89_ETSI][42] = 28, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 78, + [2][0][RTW89_KCC][42] = 66, + [2][0][RTW89_ACMA][42] = 84, + [2][0][RTW89_CN][42] = 68, + [2][0][RTW89_UK][42] = 46, + [2][0][RTW89_FCC][44] = 80, + [2][0][RTW89_ETSI][44] = 28, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 80, + [2][0][RTW89_KCC][44] = 66, + [2][0][RTW89_ACMA][44] = 84, + [2][0][RTW89_CN][44] = 68, + [2][0][RTW89_UK][44] = 46, + [2][0][RTW89_FCC][46] = 80, + [2][0][RTW89_ETSI][46] = 28, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 80, + [2][0][RTW89_KCC][46] = 66, + [2][0][RTW89_ACMA][46] = 84, + [2][0][RTW89_CN][46] = 68, + [2][0][RTW89_UK][46] = 46, + [2][0][RTW89_FCC][48] = 62, + [2][0][RTW89_ETSI][48] = 127, + [2][0][RTW89_MKK][48] = 127, + [2][0][RTW89_IC][48] = 62, + [2][0][RTW89_KCC][48] = 127, + [2][0][RTW89_ACMA][48] = 127, + [2][0][RTW89_CN][48] = 127, + [2][0][RTW89_UK][48] = 127, + [2][0][RTW89_FCC][50] = 62, + [2][0][RTW89_ETSI][50] = 127, + [2][0][RTW89_MKK][50] = 127, + [2][0][RTW89_IC][50] = 62, + [2][0][RTW89_KCC][50] = 127, + [2][0][RTW89_ACMA][50] = 127, + [2][0][RTW89_CN][50] = 127, + [2][0][RTW89_UK][50] = 127, + [2][0][RTW89_FCC][52] = 60, + [2][0][RTW89_ETSI][52] = 127, + [2][0][RTW89_MKK][52] = 127, + [2][0][RTW89_IC][52] = 60, + [2][0][RTW89_KCC][52] = 127, + [2][0][RTW89_ACMA][52] = 127, + [2][0][RTW89_CN][52] = 127, + [2][0][RTW89_UK][52] = 127, + [2][1][RTW89_FCC][0] = 127, + [2][1][RTW89_ETSI][0] = 127, + [2][1][RTW89_MKK][0] = 127, + [2][1][RTW89_IC][0] = 127, + [2][1][RTW89_KCC][0] = 127, + [2][1][RTW89_ACMA][0] = 127, + [2][1][RTW89_CN][0] = 127, + [2][1][RTW89_UK][0] = 127, + [2][1][RTW89_FCC][2] = 127, + [2][1][RTW89_ETSI][2] = 127, + [2][1][RTW89_MKK][2] = 127, + [2][1][RTW89_IC][2] = 127, + [2][1][RTW89_KCC][2] = 127, + [2][1][RTW89_ACMA][2] = 127, + [2][1][RTW89_CN][2] = 127, + [2][1][RTW89_UK][2] = 127, + [2][1][RTW89_FCC][4] = 127, + [2][1][RTW89_ETSI][4] = 127, + [2][1][RTW89_MKK][4] = 127, + [2][1][RTW89_IC][4] = 127, + [2][1][RTW89_KCC][4] = 127, + [2][1][RTW89_ACMA][4] = 127, + [2][1][RTW89_CN][4] = 127, + [2][1][RTW89_UK][4] = 127, + [2][1][RTW89_FCC][6] = 127, + [2][1][RTW89_ETSI][6] = 127, + [2][1][RTW89_MKK][6] = 127, + [2][1][RTW89_IC][6] = 127, + [2][1][RTW89_KCC][6] = 127, + [2][1][RTW89_ACMA][6] = 127, + [2][1][RTW89_CN][6] = 127, + [2][1][RTW89_UK][6] = 127, + [2][1][RTW89_FCC][8] = 127, + [2][1][RTW89_ETSI][8] = 127, + [2][1][RTW89_MKK][8] = 127, + [2][1][RTW89_IC][8] = 127, + [2][1][RTW89_KCC][8] = 127, + [2][1][RTW89_ACMA][8] = 127, + [2][1][RTW89_CN][8] = 127, + [2][1][RTW89_UK][8] = 127, + [2][1][RTW89_FCC][10] = 127, + [2][1][RTW89_ETSI][10] = 127, + [2][1][RTW89_MKK][10] = 127, + [2][1][RTW89_IC][10] = 127, + [2][1][RTW89_KCC][10] = 127, + [2][1][RTW89_ACMA][10] = 127, + [2][1][RTW89_CN][10] = 127, + [2][1][RTW89_UK][10] = 127, + [2][1][RTW89_FCC][12] = 127, + [2][1][RTW89_ETSI][12] = 127, + [2][1][RTW89_MKK][12] = 127, + [2][1][RTW89_IC][12] = 127, + [2][1][RTW89_KCC][12] = 127, + [2][1][RTW89_ACMA][12] = 127, + [2][1][RTW89_CN][12] = 127, + [2][1][RTW89_UK][12] = 127, + [2][1][RTW89_FCC][14] = 127, + [2][1][RTW89_ETSI][14] = 127, + [2][1][RTW89_MKK][14] = 127, + [2][1][RTW89_IC][14] = 127, + [2][1][RTW89_KCC][14] = 127, + [2][1][RTW89_ACMA][14] = 127, + [2][1][RTW89_CN][14] = 127, + [2][1][RTW89_UK][14] = 127, + [2][1][RTW89_FCC][15] = 127, + [2][1][RTW89_ETSI][15] = 127, + [2][1][RTW89_MKK][15] = 127, + [2][1][RTW89_IC][15] = 127, + [2][1][RTW89_KCC][15] = 127, + [2][1][RTW89_ACMA][15] = 127, + [2][1][RTW89_CN][15] = 127, + [2][1][RTW89_UK][15] = 127, + [2][1][RTW89_FCC][17] = 127, + [2][1][RTW89_ETSI][17] = 127, + [2][1][RTW89_MKK][17] = 127, + [2][1][RTW89_IC][17] = 127, + [2][1][RTW89_KCC][17] = 127, + [2][1][RTW89_ACMA][17] = 127, + [2][1][RTW89_CN][17] = 127, + [2][1][RTW89_UK][17] = 127, + [2][1][RTW89_FCC][19] = 127, + [2][1][RTW89_ETSI][19] = 127, + [2][1][RTW89_MKK][19] = 127, + [2][1][RTW89_IC][19] = 127, + [2][1][RTW89_KCC][19] = 127, + [2][1][RTW89_ACMA][19] = 127, + [2][1][RTW89_CN][19] = 127, + [2][1][RTW89_UK][19] = 127, + [2][1][RTW89_FCC][21] = 127, + [2][1][RTW89_ETSI][21] = 127, + [2][1][RTW89_MKK][21] = 127, + [2][1][RTW89_IC][21] = 127, + [2][1][RTW89_KCC][21] = 127, + [2][1][RTW89_ACMA][21] = 127, + [2][1][RTW89_CN][21] = 127, + [2][1][RTW89_UK][21] = 127, + [2][1][RTW89_FCC][23] = 127, + [2][1][RTW89_ETSI][23] = 127, + [2][1][RTW89_MKK][23] = 127, + [2][1][RTW89_IC][23] = 127, + [2][1][RTW89_KCC][23] = 127, + [2][1][RTW89_ACMA][23] = 127, + [2][1][RTW89_CN][23] = 127, + [2][1][RTW89_UK][23] = 127, + [2][1][RTW89_FCC][25] = 127, + [2][1][RTW89_ETSI][25] = 127, + [2][1][RTW89_MKK][25] = 127, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_KCC][25] = 127, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_CN][25] = 127, + [2][1][RTW89_UK][25] = 127, + [2][1][RTW89_FCC][27] = 127, + [2][1][RTW89_ETSI][27] = 127, + [2][1][RTW89_MKK][27] = 127, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_KCC][27] = 127, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_CN][27] = 127, + [2][1][RTW89_UK][27] = 127, + [2][1][RTW89_FCC][29] = 127, + [2][1][RTW89_ETSI][29] = 127, + [2][1][RTW89_MKK][29] = 127, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_KCC][29] = 127, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_CN][29] = 127, + [2][1][RTW89_UK][29] = 127, + [2][1][RTW89_FCC][31] = 127, + [2][1][RTW89_ETSI][31] = 127, + [2][1][RTW89_MKK][31] = 127, + [2][1][RTW89_IC][31] = 127, + [2][1][RTW89_KCC][31] = 127, + [2][1][RTW89_ACMA][31] = 127, + [2][1][RTW89_CN][31] = 127, + [2][1][RTW89_UK][31] = 127, + [2][1][RTW89_FCC][33] = 127, + [2][1][RTW89_ETSI][33] = 127, + [2][1][RTW89_MKK][33] = 127, + [2][1][RTW89_IC][33] = 127, + [2][1][RTW89_KCC][33] = 127, + [2][1][RTW89_ACMA][33] = 127, + [2][1][RTW89_CN][33] = 127, + [2][1][RTW89_UK][33] = 127, + [2][1][RTW89_FCC][35] = 127, + [2][1][RTW89_ETSI][35] = 127, + [2][1][RTW89_MKK][35] = 127, + [2][1][RTW89_IC][35] = 127, + [2][1][RTW89_KCC][35] = 127, + [2][1][RTW89_ACMA][35] = 127, + [2][1][RTW89_CN][35] = 127, + [2][1][RTW89_UK][35] = 127, + [2][1][RTW89_FCC][37] = 127, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 127, + [2][1][RTW89_IC][37] = 127, + [2][1][RTW89_KCC][37] = 127, + [2][1][RTW89_ACMA][37] = 127, + [2][1][RTW89_CN][37] = 127, + [2][1][RTW89_UK][37] = 127, + [2][1][RTW89_FCC][38] = 127, + [2][1][RTW89_ETSI][38] = 127, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 127, + [2][1][RTW89_KCC][38] = 127, + [2][1][RTW89_ACMA][38] = 127, + [2][1][RTW89_CN][38] = 127, + [2][1][RTW89_UK][38] = 127, + [2][1][RTW89_FCC][40] = 127, + [2][1][RTW89_ETSI][40] = 127, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 127, + [2][1][RTW89_KCC][40] = 127, + [2][1][RTW89_ACMA][40] = 127, + [2][1][RTW89_CN][40] = 127, + [2][1][RTW89_UK][40] = 127, + [2][1][RTW89_FCC][42] = 127, + [2][1][RTW89_ETSI][42] = 127, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 127, + [2][1][RTW89_KCC][42] = 127, + [2][1][RTW89_ACMA][42] = 127, + [2][1][RTW89_CN][42] = 127, + [2][1][RTW89_UK][42] = 127, + [2][1][RTW89_FCC][44] = 127, + [2][1][RTW89_ETSI][44] = 127, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 127, + [2][1][RTW89_KCC][44] = 127, + [2][1][RTW89_ACMA][44] = 127, + [2][1][RTW89_CN][44] = 127, + [2][1][RTW89_UK][44] = 127, + [2][1][RTW89_FCC][46] = 127, + [2][1][RTW89_ETSI][46] = 127, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 127, + [2][1][RTW89_KCC][46] = 127, + [2][1][RTW89_ACMA][46] = 127, + [2][1][RTW89_CN][46] = 127, + [2][1][RTW89_UK][46] = 127, + [2][1][RTW89_FCC][48] = 127, + [2][1][RTW89_ETSI][48] = 127, + [2][1][RTW89_MKK][48] = 127, + [2][1][RTW89_IC][48] = 127, + [2][1][RTW89_KCC][48] = 127, + [2][1][RTW89_ACMA][48] = 127, + [2][1][RTW89_CN][48] = 127, + [2][1][RTW89_UK][48] = 127, + [2][1][RTW89_FCC][50] = 127, + [2][1][RTW89_ETSI][50] = 127, + [2][1][RTW89_MKK][50] = 127, + [2][1][RTW89_IC][50] = 127, + [2][1][RTW89_KCC][50] = 127, + [2][1][RTW89_ACMA][50] = 127, + [2][1][RTW89_CN][50] = 127, + [2][1][RTW89_UK][50] = 127, + [2][1][RTW89_FCC][52] = 127, + [2][1][RTW89_ETSI][52] = 127, + [2][1][RTW89_MKK][52] = 127, + [2][1][RTW89_IC][52] = 127, + [2][1][RTW89_KCC][52] = 127, + [2][1][RTW89_ACMA][52] = 127, + [2][1][RTW89_CN][52] = 127, + [2][1][RTW89_UK][52] = 127, +}; + +const struct rtw89_phy_table rtw89_8851b_phy_bb_table = { + .regs = rtw89_8851b_phy_bb_regs, + .n_regs = ARRAY_SIZE(rtw89_8851b_phy_bb_regs), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table = { + .regs = rtw89_8851b_phy_bb_reg_gain, + .n_regs = ARRAY_SIZE(rtw89_8851b_phy_bb_reg_gain), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8851b_phy_radioa_table = { + .regs = rtw89_8851b_phy_radioa_regs, + .n_regs = ARRAY_SIZE(rtw89_8851b_phy_radioa_regs), + .rf_path = RF_PATH_A, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8851b_phy_nctl_table = { + .regs = rtw89_8851b_phy_nctl_regs, + .n_regs = ARRAY_SIZE(rtw89_8851b_phy_nctl_regs), + .rf_path = 0, /* don't care */ +}; + +static +const struct rtw89_txpwr_table rtw89_8851b_byr_table = { + .data = rtw89_8851b_txpwr_byrate, + .size = ARRAY_SIZE(rtw89_8851b_txpwr_byrate), + .load = rtw89_phy_load_txpwr_byrate, +}; + +static +const struct rtw89_txpwr_table rtw89_8851b_byr_table_type2 = { + .data = rtw89_8851b_txpwr_byrate_type2, + .size = ARRAY_SIZE(rtw89_8851b_txpwr_byrate_type2), + .load = rtw89_phy_load_txpwr_byrate, +}; + +const struct rtw89_fw_txpwr_track_cfg rtw89_8851b_trk_cfg = { + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N] = _txpwr_track_delta_swingidx_5ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P] = _txpwr_track_delta_swingidx_5ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N] = &_txpwr_track_delta_swingidx_2ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P] = &_txpwr_track_delta_swingidx_2ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N] = &_txpwr_track_delta_swingidx_2g_cck_a_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P] = &_txpwr_track_delta_swingidx_2g_cck_a_p, +}; + +const struct rtw89_rfe_parms rtw89_8851b_dflt_parms = { + .byr_tbl = &rtw89_8851b_byr_table, + .rule_2ghz = { + .lmt = &rtw89_8851b_txpwr_lmt_2g, + .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_2g, + }, + .rule_5ghz = { + .lmt = &rtw89_8851b_txpwr_lmt_5g, + .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g, + }, + .tx_shape = { + .lmt_v0 = &rtw89_8851b_tx_shape_lmt, + .lmt_ru_v0 = &rtw89_8851b_tx_shape_lmt_ru, + }, +}; + +static const struct rtw89_rfe_parms rtw89_8851b_rfe_parms_type2 = { + .byr_tbl = &rtw89_8851b_byr_table_type2, + .rule_2ghz = { + .lmt = &rtw89_8851b_txpwr_lmt_2g_type2, + .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_2g_type2, + }, + .rule_5ghz = { + .lmt = &rtw89_8851b_txpwr_lmt_5g_type2, + .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g_type2, + }, + .tx_shape = { + .lmt_v0 = &rtw89_8851b_tx_shape_lmt, + .lmt_ru_v0 = &rtw89_8851b_tx_shape_lmt_ru, + }, +}; + +const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[] = { + { + .rfe_parms = &rtw89_8851b_rfe_parms_type2, + .rfe_type = 2, + }, + {}, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h new file mode 100644 index 000000000..a73c0a6f0 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#ifndef __RTW89_8851B_TABLE_H__ +#define __RTW89_8851B_TABLE_H__ + +#include "core.h" + +extern const struct rtw89_phy_table rtw89_8851b_phy_bb_table; +extern const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table; +extern const struct rtw89_phy_table rtw89_8851b_phy_radioa_table; +extern const struct rtw89_phy_table rtw89_8851b_phy_nctl_table; +extern const struct rtw89_fw_txpwr_track_cfg rtw89_8851b_trk_cfg; +extern const struct rtw89_rfe_parms rtw89_8851b_dflt_parms; +extern const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[]; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851be.c b/drivers/net/wireless/realtek/rtw89/rtw8851be.c new file mode 100644 index 000000000..81c62296c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2022-2023 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8851b.h" + +static const struct rtw89_pci_info rtw8851b_pci_info = { + .gen_def = &rtw89_pci_gen_ax, + .isr_def = &rtw89_pci_isr_ax, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_2048B, + .rx_burst = MAC_AX_RX_BURST_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_DISABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .rx_ring_eq_is_full = false, + .check_rx_tag = false, + .no_rxbd_fs = false, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN, + .rxhci_en_bit = B_AX_RXHCI_EN, + .rxbd_mode_bit = B_AX_RXBD_MODE, + .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, + .txbd_rwptr_clr2_reg = 0, + .dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO}, + .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1}, + .dma_stop2 = {0}, + .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1}, + .dma_busy2_reg = 0, + .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, + + .rpwm_addr = R_AX_PCIE_HRPWM, + .cpwm_addr = R_AX_CPWM, + .mit_addr = R_AX_INT_MIT_RX, + .wp_sel_addr = 0, + .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) | + BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) | + BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + .bd_ram_table = &rtw89_bd_ram_table_single, + + .ltr_set = rtw89_pci_ltr_set, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask, + .enable_intr = rtw89_pci_enable_intr, + .disable_intr = rtw89_pci_disable_intr, + .recognize_intrs = rtw89_pci_recognize_intrs, + + .ssid_quirks = NULL, +}; + +static const struct rtw89_driver_info rtw89_8851be_info = { + .chip = &rtw8851b_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8851b_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8851be_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb851), + .driver_data = (kernel_ulong_t)&rtw89_8851be_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8851be_id_table); + +static struct pci_driver rtw89_8851be_driver = { + .name = "rtw89_8851be", + .id_table = rtw89_8851be_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8851be_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BE driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851bu.c b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c new file mode 100644 index 000000000..1e827205f --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "rtw8851b.h" +#include "reg.h" +#include "usb.h" + +static const struct rtw89_usb_info rtw8851b_usb_info = { + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, + .usb_wlan0_1 = R_AX_USB_WLAN0_1, + .hci_func_en = R_AX_HCI_FUNC_EN, + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, + .rx_agg_alignment = 8, + .bulkout_id = { + [RTW89_DMA_ACH0] = 3, + [RTW89_DMA_ACH1] = 4, + [RTW89_DMA_ACH2] = 5, + [RTW89_DMA_ACH3] = 6, + [RTW89_DMA_B0MG] = 0, + [RTW89_DMA_B0HI] = 1, + [RTW89_DMA_H2C] = 2, + }, +}; + +static const struct rtw89_driver_info rtw89_8851bu_info = { + .chip = &rtw8851b_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .usb = &rtw8851b_usb_info, + } +}; + +static const struct usb_device_id rtw_8851bu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb831, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb851, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + /* D-Link AX9U rev. A1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + /* Mercusys MA60XNB */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x0128, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + /* TP-Link Archer TX10UB Nano */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + /* Edimax EW-7611UXB */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe611, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8851bu_id_table); + +static struct usb_driver rtw_8851bu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8851bu_id_table, + .probe = rtw89_usb_probe, + .disconnect = rtw89_usb_disconnect, +}; +module_usb_driver(rtw_8851bu_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BU driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c new file mode 100644 index 000000000..5d7b5d1a2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -0,0 +1,2502 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "coex.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852a.h" +#include "rtw8852a_rfk.h" +#include "rtw8852a_table.h" +#include "txrx.h" + +#define RTW8852A_FW_FORMAT_MAX 1 +#define RTW8852A_FW_BASENAME "rtw89/rtw8852a_fw" +#define RTW8852A_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8852A_FW_BASENAME, RTW8852A_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = { + {128, 1896, grp_0}, /* ACH 0 */ + {128, 1896, grp_0}, /* ACH 1 */ + {128, 1896, grp_0}, /* ACH 2 */ + {128, 1896, grp_0}, /* ACH 3 */ + {128, 1896, grp_1}, /* ACH 4 */ + {128, 1896, grp_1}, /* ACH 5 */ + {128, 1896, grp_1}, /* ACH 6 */ + {128, 1896, grp_1}, /* ACH 7 */ + {32, 1896, grp_0}, /* B0MGQ */ + {128, 1896, grp_0}, /* B0HIQ */ + {32, 1896, grp_1}, /* B1MGQ */ + {128, 1896, grp_1}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_pcie = { + 1896, /* Group 0 */ + 1896, /* Group 1 */ + 3792, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_pcie, &rtw8852a_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_usb[] = { + {22, 402, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {22, 402, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {22, 402, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {22, 402, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {22, 402, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {22, 402, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_usb = { + 512, /* Group 0 */ + 0, /* Group 1 */ + 512, /* Public Max */ + 104 /* WP threshold */ +}; + +static const struct rtw89_hfc_prec_cfg rtw8852a_hfc_preccfg_usb = { + 11, /* CH 0-11 pre-cost */ + 32, /* H2C pre-cost */ + 76, /* WP CH 0-7 pre-cost */ + 25, /* WP CH 8-11 pre-cost */ + 1, /* CH 0-11 full condition */ + 1, /* H2C full condition */ + 1, /* WP CH 0-7 full condition */ + 1, /* WP CH 8-11 full condition */ +}; + +static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_usb[] = { + [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_usb, &rtw8852a_hfc_pubcfg_usb, + &rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, + &rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0, + &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, + &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, + &rtw89_mac_size.ple_qt5}, + [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size0, + &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, + &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, + &rtw89_mac_size.ple_qt_52a_wow}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, + &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8852a_dle_mem_usb[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size1, + &rtw89_mac_size.ple_size1, &rtw89_mac_size.wde_qt1, + &rtw89_mac_size.wde_qt1, &rtw89_mac_size.ple_qt25, + &rtw89_mac_size.ple_qt26}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, + &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_reg2_def rtw8852a_pmac_ht20_mcs7_tbl[] = { + {0x44AC, 0x00000000}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4E1F3E81}, + {0x4534, 0x00000000}, + {0x4538, 0x0000005A}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x4060001A}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x00000000}, + {0x4570, 0x04000007}, + {0x4574, 0x0000DC87}, + {0x4578, 0x00000BAB}, + {0x457C, 0x03E00000}, + {0x4580, 0x00000048}, + {0x4584, 0x00000000}, + {0x4588, 0x000003E8}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x10000000}, + {0x4598, 0x00000001}, + {0x459C, 0x00030000}, + {0x45A0, 0x01000000}, + {0x45A4, 0x03000200}, + {0x45A8, 0xC00001C0}, + {0x45AC, 0x78018000}, + {0x45B0, 0x80000000}, + {0x45B4, 0x01C80600}, + {0x45B8, 0x00000002}, + {0x4594, 0x10000000} +}; + +static const struct rtw89_reg3_def rtw8852a_btc_preagc_en_defs[] = { + {0x4624, GENMASK(20, 14), 0x40}, + {0x46f8, GENMASK(20, 14), 0x40}, + {0x4674, GENMASK(20, 19), 0x2}, + {0x4748, GENMASK(20, 19), 0x2}, + {0x4650, GENMASK(14, 10), 0x18}, + {0x4724, GENMASK(14, 10), 0x18}, + {0x4688, GENMASK(1, 0), 0x3}, + {0x475c, GENMASK(1, 0), 0x3}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_en_defs); + +static const struct rtw89_reg3_def rtw8852a_btc_preagc_dis_defs[] = { + {0x4624, GENMASK(20, 14), 0x1a}, + {0x46f8, GENMASK(20, 14), 0x1a}, + {0x4674, GENMASK(20, 19), 0x1}, + {0x4748, GENMASK(20, 19), 0x1}, + {0x4650, GENMASK(14, 10), 0x12}, + {0x4724, GENMASK(14, 10), 0x12}, + {0x4688, GENMASK(1, 0), 0x0}, + {0x475c, GENMASK(1, 0), 0x0}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_dis_defs); + +static const struct rtw89_pwr_cfg rtw8852a_pwron[] = { + {0x00C6, + PWR_CV_MSK_B, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x1086, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), 0}, + {0x1086, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_POLL, BIT(1), BIT(1)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(2), 0}, + {0x0006, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_POLL, BIT(1), BIT(1)}, + {0x0006, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_POLL, BIT(0), 0}, + {0x106D, + PWR_CV_MSK_B | PWR_CV_MSK_C, + PWR_INTF_MSK_USB, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(6), 0}, + {0x0088, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0088, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), 0}, + {0x0088, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0088, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), 0}, + {0x0088, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0083, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(6), 0}, + {0x0080, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0024, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0}, + {0x02A0, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x02A2, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(7) | BIT(6) | BIT(5), 0}, + {0x0071, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4), 0}, + {0x0010, + PWR_CV_MSK_A, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x02A0, + PWR_CV_MSK_A, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, + {0xFFFF, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + 0, + PWR_CMD_END, 0, 0}, +}; + +static const struct rtw89_pwr_cfg rtw8852a_pwroff[] = { + {0x02F0, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, 0xFF, 0}, + {0x02F1, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, 0xFF, 0}, + {0x0006, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0002, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, + {0x0082, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, + {0x106D, + PWR_CV_MSK_B | PWR_CV_MSK_C, + PWR_INTF_MSK_USB, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + PWR_BASE_MAC, + PWR_CMD_POLL, BIT(1), 0}, + {0x0091, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), 0}, + {0x0092, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_PCIE, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0007, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_USB, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4), 0}, + {0x0007, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(6) | BIT(4), 0}, + {0x0005, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, + {0x0005, + PWR_CV_MSK_C | PWR_CV_MSK_D | PWR_CV_MSK_E | PWR_CV_MSK_F | + PWR_CV_MSK_G, + PWR_INTF_MSK_USB, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, + {0x1086, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x1086, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_SDIO, + PWR_BASE_MAC, + PWR_CMD_POLL, BIT(1), 0}, + {0xFFFF, + PWR_CV_MSK_ALL, + PWR_INTF_MSK_ALL, + 0, + PWR_CMD_END, 0, 0}, +}; + +static const struct rtw89_pwr_cfg * const pwr_on_seq_8852a[] = { + rtw8852a_pwron, NULL +}; + +static const struct rtw89_pwr_cfg * const pwr_off_seq_8852a[] = { + rtw8852a_pwroff, NULL +}; + +static const u32 rtw8852a_h2c_regs[RTW89_H2CREG_MAX] = { + R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, + R_AX_H2CREG_DATA3 +}; + +static const u32 rtw8852a_c2h_regs[RTW89_C2HREG_MAX] = { + R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, + R_AX_C2HREG_DATA3 +}; + +static const u32 rtw8852a_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3, +}; + +static const struct rtw89_page_regs rtw8852a_page_regs = { + .hci_fc_ctrl = R_AX_HCI_FC_CTRL, + .ch_page_ctrl = R_AX_CH_PAGE_CTRL, + .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, + .ach_page_info = R_AX_ACH0_PAGE_INFO, + .pub_page_info3 = R_AX_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, + .pub_page_info1 = R_AX_PUB_PAGE_INFO1, + .pub_page_info2 = R_AX_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, + .wp_page_info1 = R_AX_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_def rtw8852a_dcfo_comp = { + R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK +}; + +static const struct rtw89_reg_def rtw8852a_nhm_th[RTW89_NHM_TH_NUM] = { + {R_NHM_CFG, B_NHM_TH0_MSK}, + {R_NHM_TH1, B_NHM_TH1_MSK}, + {R_NHM_TH1, B_NHM_TH2_MSK}, + {R_NHM_TH1, B_NHM_TH3_MSK}, + {R_NHM_TH1, B_NHM_TH4_MSK}, + {R_NHM_TH5, B_NHM_TH5_MSK}, + {R_NHM_TH5, B_NHM_TH6_MSK}, + {R_NHM_TH5, B_NHM_TH7_MSK}, + {R_NHM_TH5, B_NHM_TH8_MSK}, + {R_NHM_TH9, B_NHM_TH9_MSK}, + {R_NHM_TH9, B_NHM_TH10_MSK}, +}; + +static const struct rtw89_reg_def rtw8852a_nhm_rpt[RTW89_NHM_RPT_NUM] = { + {R_NHM_CNT0, B_NHM_CNT0_MSK}, + {R_NHM_CNT0, B_NHM_CNT1_MSK}, + {R_NHM_CNT2, B_NHM_CNT2_MSK}, + {R_NHM_CNT2, B_NHM_CNT3_MSK}, + {R_NHM_CNT4, B_NHM_CNT4_MSK}, + {R_NHM_CNT4, B_NHM_CNT5_MSK}, + {R_NHM_CNT6, B_NHM_CNT6_MSK}, + {R_NHM_CNT6, B_NHM_CNT7_MSK}, + {R_NHM_CNT8, B_NHM_CNT8_MSK}, + {R_NHM_CNT8, B_NHM_CNT9_MSK}, + {R_NHM_CNT10, B_NHM_CNT10_MSK}, + {R_NHM_CNT10, B_NHM_CNT11_MSK}, +}; + +static const struct rtw89_imr_info rtw8852a_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET, + .wsec_imr_reg = R_AX_SEC_DEBUG, + .wsec_imr_set = B_AX_IMR_ERROR, + .mpdu_tx_imr_set = 0, + .mpdu_rx_imr_set = 0, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, + .wde_imr_clr = B_AX_WDE_IMR_CLR, + .wde_imr_set = B_AX_WDE_IMR_SET, + .ple_imr_clr = B_AX_PLE_IMR_CLR, + .ple_imr_set = B_AX_PLE_IMR_SET, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, + .other_disp_imr_set = 0, + .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, + .bbrpt_err_imr_set = 0, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR, + .ptcl_imr_set = B_AX_PTCL_IMR_SET, + .cdma_imr_0_reg = R_AX_DLE_CTRL, + .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, + .cdma_imr_0_set = B_AX_DLE_IMR_SET, + .cdma_imr_1_reg = 0, + .cdma_imr_1_clr = 0, + .cdma_imr_1_set = 0, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, + .phy_intf_imr_clr = 0, + .phy_intf_imr_set = 0, + .rmac_imr_reg = R_AX_RMAC_ERR_ISR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR, + .rmac_imr_set = B_AX_RMAC_IMR_SET, + .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR, + .tmac_imr_set = B_AX_TMAC_IMR_SET, +}; + +static const struct rtw89_xtal_info rtw8852a_xtal_info = { + .xcap_reg = R_AX_XTAL_ON_CTRL0, + .sc_xo_mask = B_AX_XTAL_SC_XO_MASK, + .sc_xi_mask = B_AX_XTAL_SC_XI_MASK, +}; + +static const struct rtw89_rrsr_cfgs rtw8852a_rrsr_cfgs = { + .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8852a_rfkill_regs = { + .pinmux = {R_AX_GPIO8_15_FUNC_SEL, + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_AX_GPIO_EXT_CTRL + 2, + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8852a_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK, + .bmode_pd_reg = R_BMODE_PDTH_EN_V1, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT, B_PATH0_TIA_INIT_IDX_MSK}, + .p1_tia_init = {R_PATH1_TIA_INIT, B_PATH1_TIA_INIT_IDX_MSK}, + .p0_rxb_init = {R_PATH0_RXB_INIT, B_PATH0_RXB_INIT_IDX_MSK}, + .p1_rxb_init = {R_PATH1_RXB_INIT, B_PATH1_RXB_INIT_IDX_MSK}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8852a_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_EDCCA_LVL, + .ppdu_mask = B_EDCCA_LVL_MSK3, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, +}; + +static const struct rtw89_pmac_regs rtw8852a_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT, B_SIG_GG_CNT}, + .cck_spoofing = {R_SPOOF_CNT, B_SPOOF_CNT}, + .cck_brk = {}, + .brk = {R_CNT_BRK, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST, B_R1B_RX_RPT_RST}, + .r1b_rr_sel = {R_R1B_RR_SEL, B_R1B_RR_SEL}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = 0, + .eht_crc_ok_mask = 0, + .eht_crc_err_mask = 0, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static void rtw8852a_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8852a_efuse *map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + struct rtw8852a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + tssi->thermal[RF_PATH_B] = map->path_b_therm; + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, + sizeof(ofst[i]->cck_tssi)); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + sizeof(ofst[i]->bw40_tssi)); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + } +} + +static int rtw8852a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw8852a_efuse *map; + + map = (struct rtw8852a_efuse *)log_map; + + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + rtw8852a_efuse_parsing_tssi(rtwdev, map); + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; + case RTW89_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + break; + default: + return -ENOTSUPP; + } + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + + return 0; +} + +static void rtw8852a_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + static const u32 tssi_trim_addr[RF_PATH_NUM_8852A] = {0x5D6, 0x5AB}; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = false; + u32 ofst; + u8 i, j; + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { + /* addrs are in decreasing order */ + ofst = tssi_trim_addr[i] - addr - j; + tssi->tssi_trim[i][j] = phycap_map[ofst]; + + if (phycap_map[ofst] != 0xff) + pg = true; + } + } + + if (!pg) { + memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM] no PG, set all trim info to 0\n"); + } + + for (i = 0; i < RF_PATH_NUM_8852A; i++) + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", + i, j, tssi->tssi_trim[i][j], + tssi_trim_addr[i] - j); +} + +static void rtw8852a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 thm_trim_addr[RF_PATH_NUM_8852A] = {0x5DF, 0x5DC}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", + i, info->thermal_trim[i]); + + if (info->thermal_trim[i] != 0xff) + info->pg_thermal_trim = true; + } +} + +static void rtw8852a_thermal_trim(struct rtw89_dev *rtwdev) +{ +#define __thm_setting(raw) \ +({ \ + u8 __v = (raw); \ + ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ +}) + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 i, val; + + if (!info->pg_thermal_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + val = __thm_setting(info->thermal_trim[i]); + rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", + i, val); + } +#undef __thm_setting +} + +static void rtw8852a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 pabias_trim_addr[RF_PATH_NUM_8852A] = {0x5DE, 0x5DB}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + + if (info->pa_bias_trim[i] != 0xff) + info->pg_pa_bias_trim = true; + } +} + +static void rtw8852a_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); + pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); + } +} + +static int rtw8852a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8852a_phycap_parsing_tssi(rtwdev, phycap_map); + rtw8852a_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8852a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + + return 0; +} + +static void rtw8852a_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8852a_thermal_trim(rtwdev); + rtw8852a_pa_bias_trim(rtwdev); +} + +static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx); + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx); + u8 txsc20 = 0, txsc40 = 0; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + txsc40 = rtw89_phy_get_txsc(rtwdev, chan, + RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsc20 = rtw89_phy_get_txsc(rtwdev, chan, + RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); + rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); + rtw89_write32(rtwdev, sub_carr, txsc20); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); + rtw89_write32(rtwdev, sub_carr, 0); + break; + default: + break; + } + + if (chan->channel > 14) + rtw89_write8_set(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); + else + rtw89_write8_clr(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); +} + +static const u32 rtw8852a_sco_barker_threshold[14] = { + 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, + 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 +}; + +static const u32 rtw8852a_sco_cck_threshold[14] = { + 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, + 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed +}; + +static int rtw8852a_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch, + u8 primary_ch, enum rtw89_bandwidth bw) +{ + u8 ch_element; + + if (bw == RTW89_CHANNEL_WIDTH_20) { + ch_element = central_ch - 1; + } else if (bw == RTW89_CHANNEL_WIDTH_40) { + if (primary_ch == 1) + ch_element = central_ch - 1 + 2; + else + ch_element = central_ch - 1 - 2; + } else { + rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw); + return -EINVAL; + } + rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, + rtw8852a_sco_barker_threshold[ch_element]); + rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, + rtw8852a_sco_cck_threshold[ch_element]); + + return 0; +} + +static void rtw8852a_ch_setting(struct rtw89_dev *rtwdev, u8 central_ch, + u8 path) +{ + u32 val; + + val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + if (val == INV_RF_DATA) { + rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); + return; + } + val &= ~0x303ff; + val |= central_ch; + if (central_ch > 14) + val |= (BIT(16) | BIT(8)); + rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); +} + +static u8 rtw8852a_sco_mapping(u8 central_ch) +{ + if (central_ch == 1) + return 109; + else if (central_ch >= 2 && central_ch <= 6) + return 108; + else if (central_ch >= 7 && central_ch <= 10) + return 107; + else if (central_ch >= 11 && central_ch <= 14) + return 106; + else if (central_ch == 36 || central_ch == 38) + return 51; + else if (central_ch >= 40 && central_ch <= 58) + return 50; + else if (central_ch >= 60 && central_ch <= 64) + return 49; + else if (central_ch == 100 || central_ch == 102) + return 48; + else if (central_ch >= 104 && central_ch <= 126) + return 47; + else if (central_ch >= 128 && central_ch <= 151) + return 46; + else if (central_ch >= 153 && central_ch <= 177) + return 45; + else + return 0; +} + +static void rtw8852a_ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch, + enum rtw89_phy_idx phy_idx) +{ + u8 sco_comp; + bool is_2g = central_ch <= 14; + + if (phy_idx == RTW89_PHY_0) { + /* Path A */ + rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_A); + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, + B_PATH0_TIA_ERR_G1_SEL, 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, + B_PATH0_TIA_ERR_G1_SEL, 0, + phy_idx); + + /* Path B */ + if (!rtwdev->dbcc_en) { + rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_P1_MODE, + B_P1_MODE_SEL, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_P1_MODE, + B_P1_MODE_SEL, + 0, phy_idx); + } else { + if (is_2g) + rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, + B_2P4G_BAND_SEL); + else + rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, + B_2P4G_BAND_SEL); + } + /* SCO compensate FC setting */ + sco_comp = rtw8852a_sco_mapping(central_ch); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, + sco_comp, phy_idx); + } else { + /* Path B */ + rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_P1_MODE, + B_P1_MODE_SEL, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_P1_MODE, + B_P1_MODE_SEL, + 0, phy_idx); + /* SCO compensate FC setting */ + sco_comp = rtw8852a_sco_mapping(central_ch); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, + sco_comp, phy_idx); + } + + /* Band edge */ + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0, + phy_idx); + + /* CCK parameters */ + if (central_ch == 14) { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, + 0x3b13ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, + 0x1c42de); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, + 0xfdb0ad); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, + 0xf60f6e); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, + 0xfd8f92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, + 0xfff00a); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, + 0x3d23ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, + 0x29b354); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, + 0xfdb053); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, + 0xf86f9a); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, + 0xfaef92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, + 0xfe5fcc); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, + 0xffdff5); + } +} + +static void rtw8852a_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + u32 val = 0; + u32 adc_sel[2] = {0x12d0, 0x32d0}; + u32 wbadc_sel[2] = {0x12ec, 0x32ec}; + + val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + if (val == INV_RF_DATA) { + rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); + return; + } + val &= ~(BIT(11) | BIT(10)); + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); + val |= (BIT(11) | BIT(10)); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); + val |= (BIT(11) | BIT(10)); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + val |= (BIT(11) | BIT(10)); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + val |= BIT(11); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + val |= BIT(10); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + } + + rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); +} + +static void +rtw8852a_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + /* Switch bandwidth */ + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x2, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + if (pri_ch == RTW89_SC_20_UPPER) + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, + pri_ch); + } + + if (phy_idx == RTW89_PHY_0) { + rtw8852a_bw_setting(rtwdev, bw, RF_PATH_A); + if (!rtwdev->dbcc_en) + rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); + } else { + rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); + } +} + +static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) +{ + if (central_ch == 153) { + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, + 0x210); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x210); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x7c0); + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, + B_P0_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, + B_P1_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, + 0x1); + } else if (central_ch == 151) { + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, + 0x210); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x210); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x40); + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, + B_P0_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, + B_P1_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, + 0x1); + } else if (central_ch == 155) { + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, + 0x2d0); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x2d0); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x740); + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, + B_P0_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, + B_P1_NBIIDX_NOTCH_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, + 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, + B_P0_NBIIDX_NOTCH_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, + B_P1_NBIIDX_NOTCH_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, + 0x0); + } +} + +static void rtw8852a_bb_reset_all(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); +} + +static void rtw8852a_bb_reset_en(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool en) +{ + if (en) + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, + 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, + 0, + phy_idx); +} + +static void rtw8852a_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); + rtw8852a_bb_reset_all(rtwdev, phy_idx); + rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); + rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); + rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); +} + +static void rtw8852a_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + for (addr = R_AX_PWR_MACID_LMT_TABLE0; + addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); +} + +static void rtw8852a_bb_sethw(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); + rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP); + + if (rtwdev->hal.cv <= CHIP_CCV) { + rtw89_phy_write32_set(rtwdev, R_RSTB_WATCH_DOG, B_P0_RSTB_WATCH_DOG); + rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_1, 0x864FA000); + rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_2, 0x43F); + rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_3, 0x7FFF); + rtw89_phy_write32_set(rtwdev, R_SPOOF_ASYNC_RST, B_SPOOF_ASYNC_RST); + rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_PLCP_HISTOGRAM, B_STS_PARSING_TIME); + } + rtw89_phy_write32_mask(rtwdev, R_CFO_TRK0, B_CFO_TRK_MSK, 0x1f); + rtw89_phy_write32_mask(rtwdev, R_CFO_TRK1, B_CFO_TRK_MSK, 0x0c); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_1); + rtw89_phy_write32_clr(rtwdev, R_NDP_BRK0, B_NDP_RU_BRK); + rtw89_phy_write32_set(rtwdev, R_NDP_BRK1, B_NDP_RU_BRK); + + rtw8852a_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); +} + +static void rtw8852a_bbrst_for_rfk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); + rtw8852a_bb_reset_all(rtwdev, phy_idx); + rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); + udelay(1); +} + +static void rtw8852a_set_channel_bb(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + bool cck_en = chan->channel <= 14; + u8 pri_ch_idx = chan->pri_ch_idx; + + if (cck_en) + rtw8852a_ctrl_sco_cck(rtwdev, chan->channel, + chan->primary_channel, + chan->band_width); + + rtw8852a_ctrl_ch(rtwdev, chan->channel, phy_idx); + rtw8852a_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); + if (cck_en) { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); + rtw8852a_bbrst_for_rfk(rtwdev, phy_idx); + } + rtw8852a_spur_elimination(rtwdev, chan->channel); + rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, + chan->primary_channel); + rtw8852a_bb_reset_all(rtwdev, phy_idx); +} + +static void rtw8852a_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8852a_set_channel_mac(rtwdev, chan, mac_idx); + rtw8852a_set_channel_bb(rtwdev, chan, phy_idx); +} + +static void rtw8852a_dfs_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0); +} + +static void rtw8852a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + static const u32 tssi_trk[2] = {0x5818, 0x7818}; + static const u32 ctrl_bbrst[2] = {0x58dc, 0x78dc}; + + if (en) { + rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x0); + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x1); + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1); + } +} + +static void rtw8852a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, + u8 phy_idx) +{ + if (!rtwdev->dbcc_en) { + rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); + rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); + } else { + if (phy_idx == RTW89_PHY_0) + rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); + else + rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); + } +} + +static void rtw8852a_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0xf); +} + +static void rtw8852a_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, mac_idx, &p->tx_en, + RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false); + rtw8852a_dfs_en(rtwdev, false); + rtw8852a_tssi_cont_en_phyidx(rtwdev, false, phy_idx); + rtw8852a_adc_en(rtwdev, false); + fsleep(40); + rtw8852a_bb_reset_en(rtwdev, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true); + rtw8852a_adc_en(rtwdev, true); + rtw8852a_dfs_en(rtwdev, true); + rtw8852a_tssi_cont_en_phyidx(rtwdev, true, phy_idx); + rtw8852a_bb_reset_en(rtwdev, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, mac_idx, p->tx_en); + } +} + +static void rtw8852a_fem_setup(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + switch (efuse->rfe_type) { + case 11: + case 12: + case 17: + case 18: + case 51: + case 53: + rtwdev->fem.epa_2g = true; + rtwdev->fem.elna_2g = true; + fallthrough; + case 9: + case 10: + case 15: + case 16: + rtwdev->fem.epa_5g = true; + rtwdev->fem.elna_5g = true; + break; + default: + break; + } +} + +static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev) +{ + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + + rtw8852a_rck(rtwdev); + rtw8852a_dack(rtwdev, RTW89_CHANCTX_0); + rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true, RTW89_CHANCTX_0); +} + +static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + + rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx); + rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852a_tssi(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852a_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); +} + +static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8852a_tssi_scan(rtwdev, phy_idx, chan); +} + +static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx); +} + +static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8852a_dpk_track(rtwdev); + rtw8852a_tssi_track(rtwdev); +} + +static u32 rtw8852a_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) +{ + s8 ofst_int = 0; + u8 base_cw_0db = 0x27; + u16 tssi_16dbm_cw = 0x12c; + s16 pwr_s10_3 = 0; + s16 rf_pwr_cw = 0; + u16 bb_pwr_cw = 0; + u32 pwr_cw = 0; + u32 tssi_ofst_cw = 0; + + pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); + bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); + rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); + rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); + pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; + + tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", + tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); + + return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0)); +} + +static +void rtw8852a_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx) +{ + s8 val_1t = 0; + s8 val_2t = 0; + u32 reg; + + if (pw_ofst < -16 || pw_ofst > 15) { + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Err pwr_offset=%d\n", + pw_ofst); + return; + } + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); + val_1t = pw_ofst; + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, val_1t); + val_2t = max(val_1t - 3, -16); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, val_2t); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Set TB pwr_offset=(%d, %d)\n", + val_1t, val_2t); +} + +static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + static const u32 addr[RF_PATH_NUM_8852A] = {0x5800, 0x7800}; + const u32 mask = 0x7FFFFFF; + const u8 ofst_ofdm = 0x4; + const u8 ofst_cck = 0x8; + s16 ref_ofdm = 0; + s16 ref_cck = 0; + u32 val; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, + GENMASK(27, 10), 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); + val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); + + for (i = 0; i < RF_PATH_NUM_8852A; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, + phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); + val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); + + for (i = 0; i < RF_PATH_NUM_8852A; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, + phy_idx); +} + +static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); +} + +static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852a_set_txpwr_ref(rtwdev, phy_idx); +} + +static int +rtw8852a_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + int ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf004); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); + if (ret) + return ret; + + return 0; +} + +void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev) +{ + u8 i = 0; + u32 addr, val; + + for (i = 0; i < ARRAY_SIZE(rtw8852a_pmac_ht20_mcs7_tbl); i++) { + addr = rtw8852a_pmac_ht20_mcs7_tbl[i].addr; + val = rtw8852a_pmac_ht20_mcs7_tbl[i].data; + rtw89_phy_write32(rtwdev, addr, val); + } +} + +static void rtw8852a_stop_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852a_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx"); + if (tx_info->mode == CONT_TX) + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, + idx); + else if (tx_info->mode == PKTS_TX) + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, + idx); +} + +static void rtw8852a_start_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852a_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx) +{ + enum rtw8852a_pmac_mode mode = tx_info->mode; + u32 pkt_cnt = tx_info->tx_cnt; + u16 period = tx_info->period; + + if (mode == CONT_TX && !tx_info->is_cck) { + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, + idx); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start"); + } else if (mode == PKTS_TX) { + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, + idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, + B_PMAC_TX_PRD_MSK, period, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK, + pkt_cnt, idx); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start"); + } + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx); +} + +void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852a_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan) +{ + if (!tx_info->en_pmac_tx) { + rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx); + if (chan->band_type == RTW89_BAND_2G) + rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS); + return; + } + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable"); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, + idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx); + rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx); + rtw8852a_start_pmac_tx(rtwdev, tx_info, idx); +} + +void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, + u16 tx_cnt, u16 period, u16 tx_time, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan) +{ + struct rtw8852a_bb_pmac_info tx_info = {0}; + + tx_info.en_pmac_tx = enable; + tx_info.is_cck = 0; + tx_info.mode = PKTS_TX; + tx_info.tx_cnt = tx_cnt; + tx_info.period = period; + tx_info.tx_time = tx_time; + rtw8852a_bb_set_pmac_tx(rtwdev, &tx_info, idx, chan); +} + +void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, + enum rtw89_phy_idx idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx); +} + +void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) +{ + u32 rst_mask0 = 0; + u32 rst_mask1 = 0; + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_1); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path); + if (!rtwdev->dbcc_en) { + if (tx_path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, + B_TXPATH_SEL_MSK, 1); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, + B_TXNSS_MAP_MSK, 0); + } else if (tx_path == RF_PATH_B) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, + B_TXPATH_SEL_MSK, 2); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, + B_TXNSS_MAP_MSK, 0); + } else if (tx_path == RF_PATH_AB) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, + B_TXPATH_SEL_MSK, 3); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, + B_TXNSS_MAP_MSK, 4); + } else { + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path"); + } + } else { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, + 1); + rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2, + RTW89_PHY_1); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, + 0); + rtw89_phy_write32_idx(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4, + RTW89_PHY_1); + } + rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; + rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; + if (tx_path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); + } +} + +void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx idx, u8 mode) +{ + if (mode != 0) + return; + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch"); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx); +} + +static void rtw8852a_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8852a_btc_preagc_en_defs_tbl : + &rtw8852a_btc_preagc_dis_defs_tbl); +} + +static u8 rtw8852a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + if (rtwdev->is_tssi_mode[rf_path]) { + u32 addr = 0x1c10 + (rf_path << 13); + + return (u8)rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000); + } + + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + return (u8)rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); +} + +static void rtw8852a_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->bt_solo = 0; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + + if (md->rfe_type > 0) + md->ant.num = (md->rfe_type % 2 ? 2 : 3); + else + md->ant.num = 2; + + md->ant.diversity = 0; + md->ant.isolation = 10; + + if (md->ant.num == 3) { + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + } else { + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + } + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +static +void rtw8852a_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x20000); + rtw89_write_rf(rtwdev, path, RR_LUTWA, 0xfffff, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, 0xfffff, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x0); +} + +static void rtw8852a_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4); + } +} + +static void rtw8852a_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_mac_ax_coex coex_params = { + .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, + .direction = RTW89_MAC_AX_COEX_INNER, + }; + + /* PTA init */ + rtw89_mac_coex_init(rtwdev, &coex_params); + + /* set WL Tx response = Hi-Pri */ + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); + + /* set rf gnt debug off */ + rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, 0xfffff, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, 0xfffff, 0x0); + + /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ + if (btc->ant_type == BTC_ANT_SHARED) { + rtw8852a_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); + rtw8852a_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); + /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */ + rtw8852a_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); + } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ + rtw8852a_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); + rtw8852a_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); + } + + /* set PTA break table */ + rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); + + /* enable BT counter 0xda40[16,2] = 2b'11 */ + rtw89_write32_set(rtwdev, + R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); +} + +static +void rtw8852a_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + u32 bitmap = 0; + u32 reg = 0; + + switch (map) { + case BTC_PRI_MASK_TX_RESP: + reg = R_BTC_BT_COEX_MSK_TABLE; + bitmap = B_BTC_PRI_MASK_TX_RESP_V1; + break; + case BTC_PRI_MASK_BEACON: + reg = R_AX_WL_PRI_MSK; + bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; + break; + default: + return; + } + + if (state) + rtw89_write32_set(rtwdev, reg, bitmap); + else + rtw89_write32_clr(rtwdev, reg, bitmap); +} + +static inline u32 __btc_ctrl_val_all_time(u32 ctrl) +{ + return FIELD_GET(GENMASK(15, 0), ctrl); +} + +static inline u32 __btc_ctrl_rst_all_time(u32 cur) +{ + return cur & ~B_AX_FORCE_PWR_BY_RATE_EN; +} + +static inline u32 __btc_ctrl_gen_all_time(u32 cur, u32 val) +{ + u32 hv = cur & ~B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; + u32 lv = val & B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; + + return hv | lv | B_AX_FORCE_PWR_BY_RATE_EN; +} + +static inline u32 __btc_ctrl_val_gnt_bt(u32 ctrl) +{ + return FIELD_GET(GENMASK(31, 16), ctrl); +} + +static inline u32 __btc_ctrl_rst_gnt_bt(u32 cur) +{ + return cur & ~B_AX_TXAGC_BT_EN; +} + +static inline u32 __btc_ctrl_gen_gnt_bt(u32 cur, u32 val) +{ + u32 ov = cur & ~B_AX_TXAGC_BT_MASK; + u32 iv = FIELD_PREP(B_AX_TXAGC_BT_MASK, val); + + return ov | iv | B_AX_TXAGC_BT_EN; +} + +static void +rtw8852a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + const u32 __btc_cr_all_time = R_AX_PWR_RATE_CTRL; + const u32 __btc_cr_gnt_bt = R_AX_PWR_COEXT_CTRL; + +#define __do_clr(_chk) ((_chk) == GENMASK(15, 0)) +#define __handle(_case) \ + do { \ + const u32 _reg = __btc_cr_ ## _case; \ + u32 _val = __btc_ctrl_val_ ## _case(txpwr_val); \ + u32 _cur, _wrt; \ + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ + "btc ctrl %s: 0x%x\n", #_case, _val); \ + if (rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, _reg, &_cur))\ + break; \ + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ + "btc ctrl ori 0x%x: 0x%x\n", _reg, _cur); \ + _wrt = __do_clr(_val) ? \ + __btc_ctrl_rst_ ## _case(_cur) : \ + __btc_ctrl_gen_ ## _case(_cur, _val); \ + rtw89_mac_txpwr_write32(rtwdev, RTW89_PHY_0, _reg, _wrt);\ + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ + "btc ctrl set 0x%x: 0x%x\n", _reg, _wrt); \ + } while (0) + + __handle(all_time); + __handle(gnt_bt); + +#undef __handle +#undef __do_clr +} + +static +s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + /* +6 for compensate offset */ + return clamp_t(s8, val + 6, -100, 0) + 100; +} + +static struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852a_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852a_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const +u8 rtw89_btc_8852a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; +static const +u8 rtw89_btc_8852a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28}; + +static struct rtw89_btc_fbtc_mreg rtw89_btc_8852a_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178), +}; + +static +void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + struct rtw89_btc_cx *cx = &btc->cx; + u32 val; + + if (ver->fcxbtcrpt != 1) + return; + + val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH); + cx->bt0.bcnt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); + cx->bt0.bcnt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); + + val = rtw89_read32(rtwdev, R_AX_BT_STAST_LOW); + cx->bt0.bcnt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val); + cx->bt0.bcnt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val); + + /* clock-gate off before reset counter*/ + rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); + rtw89_write32_clr(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); + rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); + rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); +} + +static +void rtw8852a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x1); + + /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ + if (state) + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0xa2d7c); + else + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0xa2020); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void rtw8852a_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) +{ + /* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB + * level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB + * To improve BT ACI in co-rx + */ + + switch (level) { + case 0: /* default */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + case 1: /* Fix LNA2=5 */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + } +} + +static void rtw8852a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + switch (level) { + case 0: /* original */ + default: + rtw8852a_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 1: /* for FDD free-run */ + rtw8852a_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 2: /* for BTG Co-Rx*/ + rtw8852a_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 1; + break; + } + + rtw8852a_set_wl_lna2(rtwdev, btc->dm.wl_lna2); +} + +static void rtw8852a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u16 chan = phy_ppdu->chan_idx; + u8 band; + + if (chan == 0) + return; + + band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + status->freq = ieee80211_channel_to_frequency(chan, band); + status->band = band; +} + +static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, phy_ppdu->phy_idx); + u8 *rx_power = phy_ppdu->rssi; + u8 path; + u8 raw; + + if (!status->signal) { + if (phy_ppdu->to_self && ewma_rssi_read(&bb->bcn_rssi)) + raw = ewma_rssi_read(&bb->bcn_rssi); + else + raw = max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]); + + status->signal = RTW89_RSSI_RAW_TO_DBM(raw); + } + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +#define DECLARE_DIG_TABLE(name) \ +static const struct rtw89_phy_dig_gain_cfg name##_table = { \ + .table = name, \ + .size = ARRAY_SIZE(name) \ +} + +static const struct rtw89_reg_def rtw89_8852a_lna_gain_g[] = { + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_G_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G1_G_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_G_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_G_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_G_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_G_MSK}, + {R_PATH0_LNA_ERR5, B_PATH0_LNA_ERR_G6_G_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_g); + +static const struct rtw89_reg_def rtw89_8852a_tia_gain_g[] = { + {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_G_MSK}, + {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_G_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_g); + +static const struct rtw89_reg_def rtw89_8852a_lna_gain_a[] = { + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_A_MSK}, + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G1_A_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_A_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_A_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_A_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_A_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G6_A_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_a); + +static const struct rtw89_reg_def rtw89_8852a_tia_gain_a[] = { + {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_A_MSK}, + {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_A_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_a); + +static const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = { + .cfg_lna_g = &rtw89_8852a_lna_gain_g_table, + .cfg_tia_g = &rtw89_8852a_tia_gain_g_table, + .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, + .cfg_tia_a = &rtw89_8852a_tia_gain_a_table +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, +}; +#endif + +static const struct rtw89_chip_ops rtw8852a_chip_ops = { + .enable_bb_rf = rtw89_mac_enable_bb_rf, + .disable_bb_rf = rtw89_mac_disable_bb_rf, + .bb_preinit = NULL, + .bb_postinit = NULL, + .bb_reset = rtw8852a_bb_reset, + .bb_sethw = rtw8852a_bb_sethw, + .read_rf = rtw89_phy_read_rf, + .write_rf = rtw89_phy_write_rf, + .set_channel = rtw8852a_set_channel, + .set_channel_help = rtw8852a_set_channel_help, + .read_efuse = rtw8852a_read_efuse, + .read_phycap = rtw8852a_read_phycap, + .fem_setup = rtw8852a_fem_setup, + .data_setup = NULL, + .rfe_gpio = NULL, + .rfk_hw_init = NULL, + .rfk_init = rtw8852a_rfk_init, + .rfk_init_late = NULL, + .rfk_channel = rtw8852a_rfk_channel, + .rfk_band_changed = rtw8852a_rfk_band_changed, + .rfk_scan = rtw8852a_rfk_scan, + .rfk_track = rtw8852a_rfk_track, + .power_trim = rtw8852a_power_trim, + .set_txpwr = rtw8852a_set_txpwr, + .set_txpwr_ctrl = rtw8852a_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852a_init_txpwr_unit, + .get_thermal = rtw8852a_get_thermal, + .chan_to_rf18_val = NULL, + .ctrl_btg_bt_rx = rtw8852a_ctrl_btg_bt_rx, + .query_ppdu = rtw8852a_query_ppdu, + .convert_rpl_to_rssi = NULL, + .phy_rpt_to_rssi = NULL, + .ctrl_nbtg_bt_tx = rtw8852a_ctrl_nbtg_bt_tx, + .cfg_txrx_path = NULL, + .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, + .digital_pwr_comp = NULL, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = NULL, + .pwr_off_func = NULL, + .query_rxdesc = rtw89_core_query_rxdesc, + .fill_txdesc = rtw89_core_fill_txdesc, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, + .get_ch_dma = {rtw89_core_get_ch_dma, + rtw89_core_get_ch_dma_v2, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, + .mac_cfg_gnt = rtw89_mac_cfg_gnt, + .stop_sch_tx = rtw89_mac_stop_sch_tx, + .resume_sch_tx = rtw89_mac_resume_sch_tx, + .h2c_dctl_sec_cam = NULL, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl, + .h2c_ampdu_cmac_tbl = NULL, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl, + .h2c_punctured_cmac_tbl = NULL, + .h2c_default_dmac_tbl = NULL, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8852a_btc_set_rfe, + .btc_init_cfg = rtw8852a_btc_init_cfg, + .btc_set_wl_pri = rtw8852a_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8852a_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8852a_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8852a_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852a_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8852a_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy, +}; + +const struct rtw89_chip_info rtw8852a_chip_info = { + .chip_id = RTL8852A, + .chip_gen = RTW89_CHIP_AX, + .ops = &rtw8852a_chip_ops, + .mac_def = &rtw89_mac_gen_ax, + .phy_def = &rtw89_phy_gen_ax, + .fw_def = { + .fw_basename = RTW8852A_FW_BASENAME, + .fw_format_max = RTW8852A_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = false, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_RTL8852A | + BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION), + .fw_blacklist = NULL, + .fifo_size = 458752, + .small_fifo_size = false, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 3500, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = true, + .rsvd_ple_ofst = 0x6f800, + .qta_def = { + .hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, + rtw8852a_hfc_param_ini_usb, + rtw8852a_hfc_param_ini_usb, + NULL}, + .dle_mem = {rtw8852a_dle_mem_pcie, + rtw8852a_dle_mem_usb, + rtw8852a_dle_mem_usb, + NULL}, + }, + .wde_qempty_acq_grpnum = 16, + .wde_qempty_mgq_grpsel = 16, + .rf_base_addr = {0xc000, 0xd000}, + .thermal_th = {0x32, 0x35}, + .pwr_on_seq = pwr_on_seq_8852a, + .pwr_off_seq = pwr_off_seq_8852a, + .bb_table = &rtw89_8852a_phy_bb_table, + .bb_gain_table = NULL, + .rf_table = {&rtw89_8852a_phy_radioa_table, + &rtw89_8852a_phy_radiob_table,}, + .nctl_table = &rtw89_8852a_phy_nctl_table, + .nctl_post_table = NULL, + .dflt_parms = &rtw89_8852a_dflt_parms, + .rfe_parms_conf = NULL, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = &rtw89_8852a_phy_dig_table, + .dig_regs = &rtw8852a_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = RTW89_MAX_MAC_ID_NUM, + .support_link_num = 0, + .support_chanctx_num = 1, + .support_rnr = false, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), + .support_unii4 = false, + .support_ant_gain = false, + .support_tas = false, + .support_sar_by_ant = false, + .support_noise = true, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = false, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = true, + .hw_sec_hdr = false, + .hw_mgmt_tx_encrypt = false, + .hw_tkip_crypto = false, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 10, + .scam_num = 128, + .bacam_num = 2, + .bacam_dynamic_num = 4, + .bacam_ver = RTW89_BACAM_V0, + .addrcam_ver = 0, + .ppdu_max_usr = 4, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 1536, + .limit_efuse_size = 1152, + .dav_phy_efuse_size = 0, + .dav_log_efuse_size = 0, + .efuse_blocks = NULL, + .phycap_addr = 0x580, + .phycap_size = 128, + .para_ver = 0x0, + .wlcx_desired = 0x06000000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8852a_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852a_mon_reg), + .mon_reg = rtw89_btc_8852a_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8852a_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8852a_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852a_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852a_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, + .hci_func_en_addr = R_AX_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_txwd_body), + .txwd_body_size = sizeof(struct rtw89_txwd_body), + .txwd_info_size = sizeof(struct rtw89_txwd_info), + .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8852a_h2c_regs, + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_regs = rtw8852a_c2h_regs, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .page_regs = &rtw8852a_page_regs, + .wow_reason_reg = rtw8852a_wow_wakeup_regs, + .cfo_src_fd = false, + .cfo_hw_comp = false, + .dcfo_comp = &rtw8852a_dcfo_comp, + .dcfo_comp_sft = 10, + .nhm_report = &rtw8852a_nhm_rpt, + .nhm_th = &rtw8852a_nhm_th, + .imr_info = &rtw8852a_imr_info, + .imr_dmac_table = NULL, + .imr_cmac_table = NULL, + .rrsr_cfgs = &rtw8852a_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0}, + .bss_clr_map_reg = R_BSS_CLR_MAP, + .rfkill_init = &rtw8852a_rfkill_regs, + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, + .dma_ch_mask = 0, + .edcca_regs = &rtw8852a_edcca_regs, + .pmac_regs = &rtw8852a_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852a, +#endif + .xtal_info = &rtw8852a_xtal_info, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8852a_chip_info); + +MODULE_FIRMWARE(RTW8852A_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852A driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.h b/drivers/net/wireless/realtek/rtw89/rtw8852a.h new file mode 100644 index 000000000..d6c1acd09 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852A_H__ +#define __RTW89_8852A_H__ + +#include "core.h" + +#define RF_PATH_NUM_8852A 2 + +enum rtw8852a_pmac_mode { + NONE_TEST, + PKTS_TX, + PKTS_RX, + CONT_TX +}; + +struct rtw8852au_efuse { + u8 rsvd[0x38]; + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8852ae_efuse { + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8852a_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; +} __packed; + +struct rtw8852a_efuse { + u8 rsvd[0x210]; + struct rtw8852a_tssi_offset path_a_tssi; + u8 rsvd1[10]; + struct rtw8852a_tssi_offset path_b_tssi; + u8 rsvd2[94]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd3; + u8 iqk_lck; + u8 rsvd4[5]; + u8 reg_setting:2; + u8 tx_diversity:1; + u8 rx_diversity:2; + u8 ac_mode:1; + u8 module_type:2; + u8 rsvd5; + u8 shared_ant:1; + u8 coex_type:3; + u8 ant_iso:1; + u8 radio_on_off:1; + u8 rsvd6:2; + u8 eeprom_version; + u8 customer_id; + u8 tx_bb_swing_2g; + u8 tx_bb_swing_5g; + u8 tx_cali_pwr_trk_mode; + u8 trx_path_selection; + u8 rfe_type; + u8 country_code[2]; + u8 rsvd7[3]; + u8 path_a_therm; + u8 path_b_therm; + u8 rsvd8[46]; + u8 path_a_cck_pwr_idx[6]; + u8 path_a_bw40_1tx_pwr_idx[5]; + u8 path_a_ofdm_1tx_pwr_idx_diff:4; + u8 path_a_bw20_1tx_pwr_idx_diff:4; + u8 path_a_bw20_2tx_pwr_idx_diff:4; + u8 path_a_bw40_2tx_pwr_idx_diff:4; + u8 path_a_cck_2tx_pwr_idx_diff:4; + u8 path_a_ofdm_2tx_pwr_idx_diff:4; + u8 rsvd9[0xf2]; + union { + struct rtw8852au_efuse u; + struct rtw8852ae_efuse e; + }; +} __packed; + +struct rtw8852a_bb_pmac_info { + u8 en_pmac_tx:1; + u8 is_cck:1; + u8 mode:3; + u8 rsvd:3; + u16 tx_cnt; + u16 period; + u16 tx_time; + u8 duty_cycle; +}; + +extern const struct rtw89_chip_info rtw8852a_chip_info; + +void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev); +void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852a_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan); +void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, + u16 tx_cnt, u16 period, u16 tx_time, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan); +void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, + enum rtw89_phy_idx idx); +void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path); +void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx idx, u8 mode); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c new file mode 100644 index 000000000..609cc300f --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c @@ -0,0 +1,3870 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "coex.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852a.h" +#include "rtw8852a_rfk.h" +#include "rtw8852a_rfk_table.h" +#include "rtw8852a_table.h" + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", + rtwdev->dbcc_en, phy_idx); + + if (!rtwdev->dbcc_en) + return RF_AB; + + if (phy_idx == RTW89_PHY_0) + return RF_A; + else + return RF_B; +} + +static const u32 rtw8852a_backup_bb_regs[] = {0x2344, 0x58f0, 0x78f0}; +static const u32 rtw8852a_backup_rf_regs[] = {0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852a_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852a_backup_rf_regs) + +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852a_backup_bb_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup bb reg : %x, value =%x\n", + rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, + rtw8852a_backup_rf_regs[i], RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, + rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, + u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852a_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore bb reg : %x, value =%x\n", + rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, + u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8852a_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u8 path; + u32 rf_mode; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, + 2, 5000, false, rtwdev, path, 0x00, + RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[1][0], dack->addck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[1][0], dack->biask_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _afe_init(struct rtw89_dev *rtwdev) +{ + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_afe_init_defs_tbl); +} + +static void _addck_backup(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_clr(rtwdev, R_S0_RXDC2, B_S0_RXDC2_SEL); + dack->addck_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, + B_S0_ADDCK_Q); + dack->addck_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, + B_S0_ADDCK_I); + + rtw89_phy_write32_clr(rtwdev, R_S1_RXDC2, B_S1_RXDC2_SEL); + dack->addck_d[1][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, + B_S1_ADDCK_Q); + dack->addck_d[1][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, + B_S1_ADDCK_I); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_I, dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2, B_S0_RXDC2_Q2, + (dack->addck_d[0][1] >> 6)); + rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_Q, + (dack->addck_d[0][1] & 0x3f)); + rtw89_phy_write32_set(rtwdev, R_S0_RXDC2, B_S0_RXDC2_MEN); + rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_I, dack->addck_d[1][0]); + rtw89_phy_write32_mask(rtwdev, R_S1_RXDC2, B_S1_RXDC2_Q2, + (dack->addck_d[1][1] >> 6)); + rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_Q, + (dack->addck_d[1][1] & 0x3f)); + rtw89_phy_write32_set(rtwdev, R_S1_RXDC2, B_S1_RXDC2_EN); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_set(rtwdev, R_S0_DACKI, B_S0_DACKI_EN); + rtw89_phy_write32_set(rtwdev, R_S0_DACKQ, B_S0_DACKQ_EN); + rtw89_phy_write32_set(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); + + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_S0_DACKI, B_S0_DACKI_AR, i); + dack->msbk_d[0][0][i] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI7, B_S0_DACKI7_K); + rtw89_phy_write32_mask(rtwdev, R_S0_DACKQ, B_S0_DACKQ_AR, i); + dack->msbk_d[0][1][i] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ7, B_S0_DACKQ7_K); + } + dack->biask_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI2, + B_S0_DACKI2_K); + dack->biask_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ2, + B_S0_DACKQ2_K); + dack->dadck_d[0][0] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI8, + B_S0_DACKI8_K) - 8; + dack->dadck_d[0][1] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ8, + B_S0_DACKQ8_K) - 8; +} + +static void _dack_backup_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_set(rtwdev, R_S1_DACKI, B_S1_DACKI_EN); + rtw89_phy_write32_set(rtwdev, R_S1_DACKQ, B_S1_DACKQ_EN); + rtw89_phy_write32_set(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); + + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_S1_DACKI, B_S1_DACKI_AR, i); + dack->msbk_d[1][0][i] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI7, B_S1_DACKI_K); + rtw89_phy_write32_mask(rtwdev, R_S1_DACKQ, B_S1_DACKQ_AR, i); + dack->msbk_d[1][1][i] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ7, B_S1_DACKQ7_K); + } + dack->biask_d[1][0] = + (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI2, B_S1_DACKI2_K); + dack->biask_d[1][1] = + (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ2, B_S1_DACKQ2_K); + dack->dadck_d[1][0] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI8, B_S1_DACKI8_K) - 8; + dack->dadck_d[1][1] = + (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ8, B_S1_DACKQ8_K) - 8; +} + +static void _dack_reload_by_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 index) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 tmp = 0, tmp_offset, tmp_reg; + u8 i; + u32 idx_offset, path_offset; + + if (index == 0) + idx_offset = 0; + else + idx_offset = 0x50; + + if (path == RF_PATH_A) + path_offset = 0; + else + path_offset = 0x2000; + + tmp_offset = idx_offset + path_offset; + /* msbk_d: 15/14/13/12 */ + tmp = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); + tmp_reg = 0x5e14 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + /* msbk_d: 11/10/9/8 */ + tmp = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); + tmp_reg = 0x5e18 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + /* msbk_d: 7/6/5/4 */ + tmp = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); + tmp_reg = 0x5e1c + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + /* msbk_d: 3/2/1/0 */ + tmp = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + tmp |= dack->msbk_d[path][index][i] << (i * 8); + tmp_reg = 0x5e20 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + /* dadak_d/biask_d */ + tmp = 0x0; + tmp = (dack->biask_d[path][index] << 22) | + (dack->dadck_d[path][index] << 14); + tmp_reg = 0x5e24 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); +} + +static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u8 i; + + for (i = 0; i < 2; i++) + _dack_reload_by_path(rtwdev, path, i); + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_rfk_dack_reload_defs_a_tbl, + &rtw8852a_rfk_dack_reload_defs_b_tbl); +} + +#define ADDC_T_AVG 100 +static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + s32 dc_re = 0, dc_im = 0; + u32 tmp; + u32 i; + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_rfk_check_addc_defs_a_tbl, + &rtw8852a_rfk_check_addc_defs_b_tbl); + + for (i = 0; i < ADDC_T_AVG; i++) { + tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); + dc_re += FIELD_GET_SIGNED(0xfff000, tmp); + dc_im += FIELD_GET_SIGNED(0xfff, tmp); + } + + dc_re /= ADDC_T_AVG; + dc_im /= ADDC_T_AVG; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); +} + +static void _addck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + /* S0 */ + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_a_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_A); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_a_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x1e00, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_A); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_a_tbl); + + /* S1 */ + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_b_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_B); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_b_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x3e00, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); + dack->addck_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_B); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_b_tbl); +} + +static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_rfk_check_dadc_defs_f_a_tbl, + &rtw8852a_rfk_check_dadc_defs_f_b_tbl); + + _check_addc(rtwdev, path); + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_rfk_check_dadc_defs_r_a_tbl, + &rtw8852a_rfk_check_dadc_defs_r_b_tbl); +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_a_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x5e28, BIT(15)); + ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x5e78, BIT(15)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_a_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x5e48, BIT(17)); + ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x5e98, BIT(17)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADACK timeout\n"); + dack->dadck_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_a_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); + _check_dadc(rtwdev, RF_PATH_A); + + _dack_backup_s0(rtwdev); + _dack_reload(rtwdev, RF_PATH_A); + + rtw89_phy_write32_clr(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); +} + +static void _dack_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_b_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x7e28, BIT(15)); + ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x7e78, BIT(15)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); + dack->msbk_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_b_tbl); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x7e48, BIT(17)); + ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, 0x7e98, BIT(17)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); + dack->dadck_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_b_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); + _check_dadc(rtwdev, RF_PATH_B); + + _dack_backup_s1(rtwdev); + _dack_reload(rtwdev, RF_PATH_B); + + rtw89_phy_write32_clr(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); + _dack_s1(rtwdev); +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 rf0_0, rf1_0; + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB, chanctx_idx); + + dack->dack_done = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); + rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); + _afe_init(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x30001); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x30001); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _addck(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + _addck_backup(rtwdev); + _addck_reload(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x40001); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _dack(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + _dack_dump(rtwdev); + dack->dack_done = true; + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + +#define RTW8852A_NCTL_VER 0xd +#define RTW8852A_IQK_VER 0x2a +#define RTW8852A_IQK_SS 2 +#define RTW8852A_IQK_THR_REK 8 +#define RTW8852A_IQK_CFIR_GROUP_NR 4 + +enum rtw8852a_iqk_type { + ID_TXAGC, + ID_FLOK_COARSE, + ID_FLOK_FINE, + ID_TXK, + ID_RXAGC, + ID_RXK, + ID_NBTXK, + ID_NBRXK, +}; + +static void _iqk_read_fft_dbcc0(struct rtw89_dev *rtwdev, u8 path) +{ + u8 i = 0x0; + u32 fft[6] = {0x0}; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00160000); + fft[0] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00170000); + fft[1] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00180000); + fft[2] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00190000); + fft[3] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001a0000); + fft[4] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001b0000); + fft[5] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + for (i = 0; i < 6; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x,fft[%x]= %x\n", + path, i, fft[i]); +} + +static void _iqk_read_xym_dbcc0(struct rtw89_dev *rtwdev, u8 path) +{ + u8 i = 0x0; + u32 tmp = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX, 0x1); + + for (i = 0x0; i < 0x18; i++) { + rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x000000c0 + i); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N2, MASKDWORD); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = %x\n", + path, BIT(path), tmp); + udelay(1); + } + rtw89_phy_write32_clr(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX); + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x80010100); + udelay(1); +} + +static void _iqk_read_txcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, + u8 group) +{ + static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { + {0x8f20, 0x8f54, 0x8f88, 0x8fbc}, + {0x9320, 0x9354, 0x9388, 0x93bc}, + }; + u8 idx = 0x0; + u32 tmp = 0x0; + u32 base_addr; + + if (path >= RTW8852A_IQK_SS) { + rtw89_warn(rtwdev, "cfir path %d out of range\n", path); + return; + } + if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { + rtw89_warn(rtwdev, "cfir group %d out of range\n", group); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); + + base_addr = base_addrs[path][group]; + + for (idx = 0; idx < 0x0d; idx++) { + tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] %x = %x\n", + base_addr + (idx << 2), tmp); + } + + if (path == 0x0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C0, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f50 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C1, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f84 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C2, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fb8 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C3, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fec = %x\n", tmp); + } else { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C0, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9350 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C1, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9384 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C2, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93b8 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C3, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93ec = %x\n", tmp); + } + rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xc); + udelay(1); + tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, + BIT(path), tmp); +} + +static void _iqk_read_rxcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, + u8 group) +{ + static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { + {0x8d00, 0x8d44, 0x8d88, 0x8dcc}, + {0x9100, 0x9144, 0x9188, 0x91cc}, + }; + u8 idx = 0x0; + u32 tmp = 0x0; + u32 base_addr; + + if (path >= RTW8852A_IQK_SS) { + rtw89_warn(rtwdev, "cfir path %d out of range\n", path); + return; + } + if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { + rtw89_warn(rtwdev, "cfir group %d out of range\n", group); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); + + base_addr = base_addrs[path][group]; + for (idx = 0; idx < 0x10; idx++) { + tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]%x = %x\n", + base_addr + (idx << 2), tmp); + } + + if (path == 0x0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C0, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d40 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C1, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d84 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C2, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8dc8 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C3, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8e0c = %x\n", tmp); + } else { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C0, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9140 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C1, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9184 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C2, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x91c8 = %x\n", tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C3, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x920c = %x\n", tmp); + } + rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xd); + tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, + BIT(path), tmp); +} + +static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) +{ + u32 tmp = 0x0; + u32 i = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); + + for (i = 0; i <= 0x9f; i++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); + tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); + } + + for (i = 0; i <= 0x9f; i++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); + tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); + } + rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX2, MASKDWORD); + rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX, MASKDWORD); +} + +static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp = 0x0; + + rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); + rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x5); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); + break; + default: + break; + } + tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); + fsleep(128); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) +{ + u32 tmp; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 1, 8200, + false, rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); + tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); + + return false; +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, u8 ktype, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail = false; + u32 iqk_cmd = 0x0; + u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path, chanctx_idx); + u32 addr_rfc_ctl = 0x0; + + if (path == RF_PATH_A) + addr_rfc_ctl = 0x5864; + else + addr_rfc_ctl = 0x7864; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + switch (ktype) { + case ID_TXAGC: + iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); + break; + case ID_FLOK_COARSE: + rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_FLOK_FINE: + rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); + iqk_cmd = 0x208 | (1 << (4 + path)); + break; + case ID_TXK: + rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_RXAGC: + iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_NBTXK: + rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_NBRXK: + rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); + udelay(1); + fail = _iqk_check_cal(rtwdev, path, ktype); + if (iqk_info->iqk_xym_en) + _iqk_read_xym_dbcc0(rtwdev, path); + if (iqk_info->iqk_fft_en) + _iqk_read_fft_dbcc0(rtwdev, path); + if (iqk_info->iqk_sram_en) + _iqk_sram(rtwdev, path); + if (iqk_info->iqk_cfir_en) { + if (ktype == ID_TXK) { + _iqk_read_txcfir_dbcc0(rtwdev, path, 0x0); + _iqk_read_txcfir_dbcc0(rtwdev, path, 0x1); + _iqk_read_txcfir_dbcc0(rtwdev, path, 0x2); + _iqk_read_txcfir_dbcc0(rtwdev, path, 0x3); + } else { + _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x0); + _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x1); + _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x2); + _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x3); + } + } + + rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); + + return fail; +} + +static bool _rxk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + static const u32 rxgn_a[4] = {0x18C, 0x1A0, 0x28C, 0x2A0}; + static const u32 attc2_a[4] = {0x0, 0x0, 0x07, 0x30}; + static const u32 attc1_a[4] = {0x7, 0x5, 0x1, 0x1}; + static const u32 rxgn_g[4] = {0x1CC, 0x1E0, 0x2CC, 0x2E0}; + static const u32 attc2_g[4] = {0x0, 0x15, 0x3, 0x1a}; + static const u32 attc1_g[4] = {0x1, 0x0, 0x1, 0x0}; + u8 gp = 0x0; + bool fail = false; + u32 rf0 = 0x0; + + for (gp = 0; gp < 0x4; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_g[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, attc2_g[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, attc1_g[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_a[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, attc2_a[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, attc1_a[gp]); + break; + default: + break; + } + rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); + rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, + rf0 | iqk_info->syn1to2); + rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); + rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); + rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN, 0x1); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK, chanctx_idx); + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); + break; + default: + break; + } + iqk_info->nb_rxcfir[path] = 0x40000000; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_RXCFIR, 0x5); + iqk_info->is_wb_rxiqk[path] = true; + return false; +} + +static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 group = 0x0; + u32 rf0 = 0x0, tmp = 0x0; + u32 idxrxgain_a = 0x1a0; + u32 idxattc2_a = 0x00; + u32 idxattc1_a = 0x5; + u32 idxrxgain_g = 0x1E0; + u32 idxattc2_g = 0x15; + u32 idxattc1_g = 0x0; + bool fail = false; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_g); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, idxattc2_g); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, idxattc1_g); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_a); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, idxattc2_a); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, idxattc1_a); + break; + default: + break; + } + rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); + rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, + rf0 | iqk_info->syn1to2); + rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); + rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); + rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP, group); + rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK, chanctx_idx); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); + break; + default: + break; + } + if (!fail) { + tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); + iqk_info->nb_rxcfir[path] = tmp | 0x2; + } else { + iqk_info->nb_rxcfir[path] = 0x40000002; + } + return fail; +} + +static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), + MASKDWORD, 0x4d000a08); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), + B_P0_RXCK_VAL, 0x2); + rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); + rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), + MASKDWORD, 0x44000a08); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), + B_P0_RXCK_VAL, 0x1); + rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); + rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); + rtw89_phy_write32_clr(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL); + } +} + +static bool _txk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + static const u32 a_txgain[4] = {0xE466, 0x646D, 0xE4E2, 0x64ED}; + static const u32 g_txgain[4] = {0x60e8, 0x60f0, 0x61e8, 0x61ED}; + static const u32 a_itqt[4] = {0x12, 0x12, 0x12, 0x1b}; + static const u32 g_itqt[4] = {0x09, 0x12, 0x12, 0x12}; + static const u32 g_attsmxr[4] = {0x0, 0x1, 0x1, 0x1}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail = false; + u8 gp = 0x0; + u32 tmp = 0x0; + + for (gp = 0x0; gp < 0x4; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), + B_RFGAIN_BND, 0x08); + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, + g_txgain[gp]); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, + g_attsmxr[gp]); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, + g_attsmxr[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), + B_RFGAIN_BND, 0x04); + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, + a_txgain[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, a_itqt[gp]); + break; + default: + break; + } + rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP, gp); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK, chanctx_idx); + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(8 + gp + path * 4), fail); + } + + iqk_info->nb_txcfir[path] = 0x40000000; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_TXCFIR, 0x5); + iqk_info->is_wb_txiqk[path] = true; + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, + BIT(path), tmp); + return false; +} + +static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 group = 0x2; + u32 a_mode_txgain = 0x64e2; + u32 g_mode_txgain = 0x61e8; + u32 attsmxr = 0x1; + u32 itqt = 0x12; + u32 tmp = 0x0; + bool fail = false; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), + B_RFGAIN_BND, 0x08); + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, g_mode_txgain); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, attsmxr); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, attsmxr); + break; + case RTW89_BAND_5G: + rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), + B_RFGAIN_BND, 0x04); + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, a_mode_txgain); + break; + default: + break; + } + rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); + rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, group); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK, chanctx_idx); + if (!fail) { + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + iqk_info->nb_txcfir[path] = tmp | 0x2; + } else { + iqk_info->nb_txcfir[path] = 0x40000002; + } + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, + BIT(path), tmp); + return fail; +} + +static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); + else + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); +} + +static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) +{ + bool is_fail = false; + u32 tmp = 0x0; + u32 core_i = 0x0; + u32 core_q = 0x0; + + tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK][FineLOK] S%x, 0x58 = 0x%x\n", + path, tmp); + core_i = FIELD_GET(RR_TXMO_COI, tmp); + core_q = FIELD_GET(RR_TXMO_COQ, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, i = 0x%x\n", path, core_i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, q = 0x%x\n", path, core_q); + + if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) + is_fail = true; + return is_fail; +} + +static bool _iqk_lok(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 rf0 = 0x0; + u8 itqt = 0x12; + bool fail = false; + bool tmp = false; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe5e0); + itqt = 0x09; + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe4e0); + itqt = 0x12; + break; + default: + break; + } + rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); + rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF1, B_IQK_DIF1_TXPI, + rf0 | iqk_info->syn1to2); + rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, 0x0); + rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE, chanctx_idx); + iqk_info->lok_cor_fail[0][path] = tmp; + fsleep(10); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE, chanctx_idx); + iqk_info->lok_fin_fail[0][path] = tmp; + fail = _lok_finetune_check(rtwdev, path); + return fail; +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000); + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00); + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x000); + rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + udelay(1); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); + rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x7); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x100); + rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + udelay(1); + break; + default: + break; + } +} + +static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); +} + +static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp = 0x0; + bool flag = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path, + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, + iqk_info->lok_cor_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, + iqk_info->lok_fin_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, + iqk_info->iqk_tx_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, + iqk_info->iqk_rx_fail[0][path]); + flag = iqk_info->lok_cor_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(0) << (path * 4), flag); + flag = iqk_info->lok_fin_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(1) << (path * 4), flag); + flag = iqk_info->iqk_tx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(2) << (path * 4), flag); + flag = iqk_info->iqk_rx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(3) << (path * 4), flag); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); + iqk_info->bp_iqkenable[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + iqk_info->bp_txkresult[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); + iqk_info->bp_rxkresult[path] = tmp; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, + (u8)iqk_info->iqk_times); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, 0x0000000f << (path * 4)); + if (tmp != 0x0) + iqk_info->iqk_fail_cnt++; + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x00ff0000 << (path * 4), + iqk_info->iqk_fail_cnt); +} + +static +void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool lok_is_fail = false; + u8 ibias = 0x1; + u8 i = 0; + + _iqk_txclk_setting(rtwdev, path); + + for (i = 0; i < 3; i++) { + _lok_res_table(rtwdev, path, ibias++); + _iqk_txk_setting(rtwdev, path); + lok_is_fail = _iqk_lok(rtwdev, phy_idx, path, chanctx_idx); + if (!lok_is_fail) + break; + } + if (iqk_info->is_nbiqk) + iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path, + chanctx_idx); + else + iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path, + chanctx_idx); + + _iqk_rxclk_setting(rtwdev, path); + _iqk_rxk_setting(rtwdev, path); + if (iqk_info->is_nbiqk || rtwdev->dbcc_en || iqk_info->iqk_band[path] == RTW89_BAND_2G) + iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path, + chanctx_idx); + else + iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path, + chanctx_idx); + + _iqk_info_iqk(rtwdev, phy_idx, path); +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u32 reg_rf18 = 0x0, reg_35c = 0x0; + u8 idx = 0; + u8 get_empty_table = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { + if (iqk_info->iqk_mcc_ch[idx][path] == 0) { + get_empty_table = true; + break; + } + } + if (!get_empty_table) { + idx = iqk_info->iqk_table_idx[path] + 1; + if (idx > RTW89_IQK_CHS_NR - 1) + idx = 0; + } + reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18); + reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00); + + iqk_info->iqk_band[path] = chan->band_type; + iqk_info->iqk_bw[path] = chan->band_width; + iqk_info->iqk_ch[path] = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, + iqk_info->iqk_band[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", + path, iqk_info->iqk_bw[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", + path, iqk_info->iqk_ch[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, + str_on_off(rtwdev->dbcc_en), + iqk_info->iqk_band[path] == 0 ? "2G" : + iqk_info->iqk_band[path] == 1 ? "5G" : "6G", + iqk_info->iqk_ch[path], + iqk_info->iqk_bw[path] == 0 ? "20M" : + iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); + if (reg_35c == 0x01) + iqk_info->syn1to2 = 0x1; + else + iqk_info->syn1to2 = 0x0; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852A_IQK_VER); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x000f << (path * 16), + (u8)iqk_info->iqk_band[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x00f0 << (path * 16), + (u8)iqk_info->iqk_bw[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0xff00 << (path * 16), + (u8)iqk_info->iqk_ch[path]); + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x000000ff, RTW8852A_NCTL_VER); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path, enum rtw89_chanctx_idx chanctx_idx) +{ + _iqk_by_path(rtwdev, phy_idx, path, chanctx_idx); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, + iqk_info->nb_txcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + iqk_info->nb_rxcfir[path]); + rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_phy_write32_clr(rtwdev, R_MDPK_RX_DCK, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + rtw89_phy_write32_clr(rtwdev, R_KPATH_CFG, MASKDWORD); + rtw89_phy_write32_clr(rtwdev, R_GAPK, B_GAPK_ADR); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); + rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); + rtw89_phy_write32_mask(rtwdev, R_CFIR_MAP + (path << 8), MASKDWORD, 0xe4e4e4e4); + rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); + rtw89_phy_write32_clr(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD, 0x00000002); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + rtw89_write_rf(rtwdev, path, RR_TXRSV, RR_TXRSV_GAPK, 0x0); + rtw89_write_rf(rtwdev, path, RR_BIAS, RR_BIAS_GAPK, 0x0); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + const struct rtw89_rfk_tbl *tbl; + + switch (_kpath(rtwdev, phy_idx)) { + case RF_A: + tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; + break; + case RF_B: + tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; + break; + default: + tbl = &rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; + break; + } + + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = iqk_info->iqk_table_idx[path]; + + if (rtwdev->dbcc_en) { + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_IQC, path & 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_G2, path & 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_IQC, idx); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_G2, idx); + } + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_clr(rtwdev, R_NCTL_RW, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, MASKDWORD, 0x00200000); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); + rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + const struct rtw89_rfk_tbl *tbl; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); + + switch (_kpath(rtwdev, phy_idx)) { + case RF_A: + tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; + break; + case RF_B: + tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; + break; + default: + tbl = &rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; + break; + } + + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 phy_idx = 0x0; + + iqk_info->iqk_times++; + + if (path == 0x0) + phy_idx = RTW89_PHY_0; + else + phy_idx = RTW89_PHY_1; + + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); +} + +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5, rck_val = 0; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, + false, rtwdev, path, 0x1c, BIT(3)); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + + /* RCK_ADC_OFFSET */ + rtw89_write_rf(rtwdev, path, RR_RCKO, RR_RCKO_OFF, 0x4); + + rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x1); + rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RCK] RF 0x1b / 0x1c / 0x1d = 0x%x / 0x%x / 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RCKO, RFREG_MASK)); +} + +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 ch, path; + + rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->iqk_times = 0x0; + + for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { + iqk_info->iqk_channel[ch] = 0x0; + for (path = 0; path < RTW8852A_IQK_SS; path++) { + iqk_info->lok_cor_fail[ch][path] = false; + iqk_info->lok_fin_fail[ch][path] = false; + iqk_info->iqk_tx_fail[ch][path] = false; + iqk_info->iqk_rx_fail[ch][path] = false; + iqk_info->iqk_mcc_ch[ch][path] = 0x0; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852A_IQK_SS][BACKUP_RF_REGS_NR]; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->version = RTW8852A_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + switch (_kpath(rtwdev, phy_idx)) { + case RF_A: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + break; + case RF_B: + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + case RF_AB: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + default: + break; + } +} + +#define RXDCK_VER_8852A 0xe + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, bool is_afe, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx); + u32 ori_val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ==== S%d RX DCK (by %s)====\n", + path, is_afe ? "AFE" : "RFC"); + + ori_val = rtw89_phy_read32_mask(rtwdev, R_P0_RXCK + (path << 13), MASKDWORD); + + if (is_afe) { + rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); + rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), + B_P0_RXCK_VAL, 0x3); + rtw89_phy_write32_set(rtwdev, R_S0_RXDC2 + (path << 13), B_S0_RXDC2_MEN); + rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2 + (path << 13), + B_S0_RXDC2_AVG, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); + rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK); + rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); + rtw89_phy_write32_set(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_CRXBB, 0x1); + } + + rtw89_write_rf(rtwdev, path, RR_DCK2, RR_DCK2_CYCLE, 0x3f); + rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_SEL, is_afe); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_START); + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + + fsleep(600); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_STOP); + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + + if (is_afe) { + rtw89_phy_write32_clr(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), + MASKDWORD, ori_val); + } +} + +static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool is_afe, enum rtw89_chanctx_idx chanctx_idx) +{ + u8 path, kpath, dck_tune; + u32 rf_reg5; + u32 addr; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", + RXDCK_VER_8852A, rtwdev->hal.cv); + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < 2; path++) { + if (!(kpath & BIT(path))) + continue; + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + dck_tune = (u8)rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); + + if (rtwdev->is_tssi_mode[path]) { + addr = 0x5818 + (path << 13); + /* TSSI pause */ + rtw89_phy_write32_set(rtwdev, addr, BIT(30)); + } + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + _set_rx_dck(rtwdev, phy, path, is_afe, chanctx_idx); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) { + addr = 0x5818 + (path << 13); + /* TSSI resume */ + rtw89_phy_write32_clr(rtwdev, addr, BIT(30)); + } + } +} + +#define RTW8852A_RF_REL_VERSION 34 +#define RTW8852A_DPK_VER 0x10 +#define RTW8852A_DPK_TH_AVG_NUM 4 +#define RTW8852A_DPK_RF_PATH 2 +#define RTW8852A_DPK_KIP_REG_NUM 2 + +enum rtw8852a_dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, +}; + +static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off); + +static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, u32 *reg, + u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], + u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { + reg_bkup[path][i] = rtw89_phy_read32_mask(rtwdev, + reg[i] + (path << 8), + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_reload_kip(struct rtw89_dev *rtwdev, u32 *reg, + u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), + MASKDWORD, reg_bkup[path][i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw8852a_dpk_id id, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx); + u16 dpk_cmd = 0x0; + u32 val; + int ret; + + dpk_cmd = (u16)((id << 8) | (0x19 + (path << 4))); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_START); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); + + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_STOP); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%x (ret=%d)\n", + id == 0x06 ? "LBK_RXIQK" : + id == 0x10 ? "SYNC" : + id == 0x11 ? "MDPK_IDL" : + id == 0x12 ? "MDPK_MPA" : + id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", + dpk_cmd, ret); + + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot over 20ms!!!!\n"); + return 1; + } + + return 0; +} + +static void _dpk_rx_dck(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, + enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); + _set_rx_dck(rtwdev, phy, path, false, chanctx_idx); +} + +static void _dpk_information(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = chan->band_type; + dpk->bp[path][kidx].ch = chan->channel; + dpk->bp[path][kidx].bw = chan->band_width; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + str_on_off(rtwdev->is_tssi_mode[path]), + str_on_off(rtwdev->dbcc_en), + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); +} + +static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + switch (kpath) { + case RF_A: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl); + + if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x0) + rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl); + break; + case RF_B: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl); + + if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x1) + rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl); + break; + case RF_AB: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl); + break; + default: + break; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); +} + +static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + switch (kpath) { + case RF_A: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl); + break; + case RF_B: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl); + break; + case RF_AB: + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl); + break; + default: + break; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static void _dpk_kip_setting(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 kidx) +{ + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x00093f3f); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG, B_DPK_CFG_IDX, 0x2); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); /*subpage_id*/ + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8) + (kidx << 2), + MASKDWORD, 0x003f2e2e); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x005b5b5b); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP setting for S%d[%d]!!\n", + path, kidx); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ + rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); + rtw89_phy_write32_clr(rtwdev, R_KIP_CLK, MASKDWORD); + + if (rtwdev->hal.cv > CHIP_CBV) + rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), BIT(15), 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 cur_rxbb; + + cur_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); + rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x2); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, + rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK)); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); + + fsleep(70); + + rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTL, 0x1f); + + if (cur_rxbb <= 0xa) + rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x3); + else if (cur_rxbb <= 0x10 && cur_rxbb >= 0xb) + rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK, chanctx_idx); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); + + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); /*POW IQKPLL*/ + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_DPK); + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl); +} + +static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, + enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + dpk->bp[path][kidx].ther_dpk = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", + dpk->bp[path][kidx].ther_dpk); +} + +static u8 _dpk_set_tx_pwr(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path) +{ + u8 txagc_ori = 0x38; + + rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc_ori); + + return txagc_ori; +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x280b); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); + rtw89_write_rf(rtwdev, path, RR_MIXER, RR_MIXER_GN, 0x0); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x282e); + rtw89_write_rf(rtwdev, path, RR_BIASA2, RR_BIASA2_LB, 0x7); + rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW, 0x3); + rtw89_write_rf(rtwdev, path, RR_RXA, RR_RXA_DPK, 0x3); + } + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] RF 0x0/0x1/0x1a = 0x%x/ 0x%x/ 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); +} + +static void _dpk_manual_txcfir(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_manual) +{ + u8 tmp_pad, tmp_txbb; + + if (is_manual) { + rtw89_phy_write32_mask(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN, 0x1); + tmp_pad = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_PAD); + rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), + B_RFGAIN_PAD, tmp_pad); + + tmp_txbb = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_BB); + rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), + B_RFGAIN_TXBB, tmp_txbb); + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), + B_LOAD_COEF_CFIR, 0x1); + rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), + B_LOAD_COEF_CFIR); + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), BIT(1), 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] PAD_man / TXBB_man = 0x%x / 0x%x\n", tmp_pad, + tmp_txbb); + } else { + rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] disable manual switch TXCFIR\n"); + } +} + +static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bypass) +{ + if (is_bypass) { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS, 0x1); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD)); + } else { + rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); + rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD)); + } +} + +static +void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) + rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + else + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static void _dpk_table_select(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 kidx, u8 gain) +{ + u8 val; + + val = 0x80 + kidx * 0x20 + gain * 0x10; + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, + gain, val); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ +#define DPK_SYNC_TH_DC_I 200 +#define DPK_SYNC_TH_DC_Q 200 +#define DPK_SYNC_TH_CORR 170 + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u16 dc_i, dc_q; + u8 corr_val, corr_idx; + + rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); + + corr_idx = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); + corr_val = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", path, corr_idx, + corr_val); + + dpk->corr_idx[path][0] = corr_idx; + dpk->corr_val[path][0] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc_i = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + dc_q = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", + path, dc_i, dc_q); + + dpk->dc_i[path][0] = dc_i; + dpk->dc_q[path][0] = dc_q; + + if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || + corr_val < DPK_SYNC_TH_CORR) + return true; + else + return false; +} + +static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, + enum rtw89_chanctx_idx chanctx_idx) +{ + _dpk_tpg_sel(rtwdev, path, kidx); + _dpk_one_shot(rtwdev, phy, path, SYNC, chanctx_idx); + return _dpk_sync_check(rtwdev, path); /*1= fail*/ +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain = 0x0; + + rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); + + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); + + dgain = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, + dgain); + + return dgain; +} + +static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) +{ + s8 offset; + + if (dgain >= 0x783) + offset = 0x6; + else if (dgain <= 0x782 && dgain >= 0x551) + offset = 0x3; + else if (dgain <= 0x550 && dgain >= 0x3c4) + offset = 0x0; + else if (dgain <= 0x3c3 && dgain >= 0x2aa) + offset = -3; + else if (dgain <= 0x2a9 && dgain >= 0x1e3) + offset = -6; + else if (dgain <= 0x1e2 && dgain >= 0x156) + offset = -9; + else if (dgain <= 0x155) + offset = -12; + else + offset = 0x0; + + return offset; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); +} + +static void _dpk_gainloss(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, enum rtw89_rf_path path, + u8 kidx, enum rtw89_chanctx_idx chanctx_idx) +{ + _dpk_table_select(rtwdev, path, kidx, 1); + _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS, chanctx_idx); +} + +#define DPK_TXAGC_LOWER 0x2e +#define DPK_TXAGC_UPPER 0x3f +#define DPK_TXAGC_INVAL 0xff + +static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, s8 gain_offset) +{ + u8 txagc; + + txagc = (u8)rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK); + + if (txagc - gain_offset < DPK_TXAGC_LOWER) + txagc = DPK_TXAGC_LOWER; + else if (txagc - gain_offset > DPK_TXAGC_UPPER) + txagc = DPK_TXAGC_UPPER; + else + txagc = txagc - gain_offset; + + rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", + gain_offset, txagc); + return txagc; +} + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_ADJ, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u8 i; + + rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_pas_read_defs_tbl); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + if ((val1_i * val1_i + val1_q * val1_q) >= + ((val2_i * val2_i + val2_q * val2_q) * 8 / 5)) + return 1; + else + return 0; +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_txagc, + bool loss_only, enum rtw89_chanctx_idx chanctx_idx) +{ +#define DPK_AGC_ADJ_LMT 6 +#define DPK_DGAIN_UPPER 1922 +#define DPK_DGAIN_LOWER 342 +#define DPK_RXBB_UPPER 0x1f +#define DPK_RXBB_LOWER 0 +#define DPK_GL_CRIT 7 + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; + u8 agc_cnt = 0; + bool limited_rxbb = false; + s8 offset = 0; + u16 dgain = 0; + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + bool goout = false; + + tmp_txagc = init_txagc; + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + if (_dpk_sync(rtwdev, phy, path, kidx, chanctx_idx)) { + tmp_txagc = DPK_TXAGC_INVAL; + goout = true; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + + if (loss_only || limited_rxbb) + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + else + step = DPK_AGC_STEP_GAIN_ADJ; + break; + + case DPK_AGC_STEP_GAIN_ADJ: + tmp_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + offset = _dpk_dgain_mapping(rtwdev, dgain); + + if (tmp_rxbb + offset > DPK_RXBB_UPPER) { + tmp_rxbb = DPK_RXBB_UPPER; + limited_rxbb = true; + } else if (tmp_rxbb + offset < DPK_RXBB_LOWER) { + tmp_rxbb = DPK_RXBB_LOWER; + limited_rxbb = true; + } else { + tmp_rxbb = tmp_rxbb + offset; + } + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, + tmp_rxbb); + if (offset != 0 || agc_cnt == 0) { + if (chan->band_width < RTW89_CHANNEL_WIDTH_80) + _dpk_bypass_rxcfir(rtwdev, path, true); + else + _dpk_lbk_rxiqk(rtwdev, phy, path, + chanctx_idx); + } + if (dgain > DPK_DGAIN_UPPER || dgain < DPK_DGAIN_LOWER) + step = DPK_AGC_STEP_SYNC_DGAIN; + else + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + + agc_cnt++; + break; + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + _dpk_gainloss(rtwdev, phy, path, kidx, chanctx_idx); + tmp_gl_idx = _dpk_gainloss_read(rtwdev); + + if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || + tmp_gl_idx > DPK_GL_CRIT) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + break; + + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_txagc == DPK_TXAGC_LOWER) { + goout = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, path, 3); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_txagc == DPK_TXAGC_UPPER) { + goout = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, path, -2); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + + case DPK_AGC_STEP_SET_TX_GAIN: + tmp_txagc = _dpk_set_offset(rtwdev, path, tmp_gl_idx); + goout = true; + agc_cnt++; + break; + + default: + goout = true; + break; + } + } while (!goout && (agc_cnt < DPK_AGC_ADJ_LMT)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, + tmp_rxbb); + + return tmp_txagc; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) +{ + switch (order) { + case 0: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); + break; + case 1: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); + rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); + break; + case 2: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); + rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Wrong MDPD order!!(0x%x)\n", order); + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Set MDPD order to 0x%x for IDL\n", order); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 gain, + enum rtw89_chanctx_idx chanctx_idx) +{ + _dpk_set_mdpd_para(rtwdev, 0x0); + _dpk_table_select(rtwdev, path, kidx, 1); + _dpk_one_shot(rtwdev, phy, path, MDPK_IDL, chanctx_idx); +} + +static void _dpk_fill_result(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 kidx, u8 gain, + u8 txagc) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u16 pwsf = 0x78; + u8 gs = 0x5b; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, + pwsf, gs); + + dpk->bp[path][kidx].txagc_dpk = txagc; + rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), + 0x3F << ((gain << 3) + (kidx << 4)), txagc); + + dpk->bp[path][kidx].pwsf = pwsf; + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x1FF << (gain << 4), pwsf); + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD); + + dpk->bp[path][kidx].gs = gs; + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x065b5b5b); + + rtw89_phy_write32_clr(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD); + + rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL); +} + +static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + bool is_reload = false; + u8 idx, cur_band, cur_ch; + + cur_band = chan->band_type; + cur_ch = chan->channel; + + for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { + if (cur_band != dpk->bp[path][idx].band || + cur_ch != dpk->bp[path][idx].ch) + continue; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, idx); + dpk->cur_idx[path] = idx; + is_reload = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] reload S%d[%d] success\n", path, idx); + } + + return is_reload; +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 gain, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 txagc = 0, kidx = dpk->cur_idx[path]; + bool is_fail = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", path, + kidx); + + _rf_direct_cntrl(rtwdev, path, false); + txagc = _dpk_set_tx_pwr(rtwdev, gain, path); + _dpk_rf_setting(rtwdev, gain, path, kidx); + _dpk_rx_dck(rtwdev, phy, path, chanctx_idx); + + _dpk_kip_setting(rtwdev, path, kidx); + _dpk_manual_txcfir(rtwdev, path, true); + txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx); + if (txagc == DPK_TXAGC_INVAL) + is_fail = true; + _dpk_get_thermal(rtwdev, kidx, path); + + _dpk_idl_mpa(rtwdev, phy, path, kidx, gain, chanctx_idx); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + _dpk_fill_result(rtwdev, path, kidx, gain, txagc); + _dpk_manual_txcfir(rtwdev, path, false); + + if (!is_fail) + dpk->bp[path][kidx].path_ok = true; + else + dpk->bp[path][kidx].path_ok = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, + is_fail ? "Check" : "Success"); + + return is_fail; +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852A_DPK_RF_PATH][BACKUP_RF_REGS_NR]; + u32 kip_bkup[RTW8852A_DPK_RF_PATH][RTW8852A_DPK_KIP_REG_NUM] = {{0}}; + u32 kip_reg[] = {R_RXIQC, R_IQK_RES}; + u8 path; + bool is_fail = true, reloaded[RTW8852A_DPK_RF_PATH] = {false}; + + if (dpk->is_dpk_reload_en) { + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path))) + continue; + + reloaded[path] = _dpk_reload_check(rtwdev, phy, path, + chanctx_idx); + if (!reloaded[path] && dpk->bp[path][0].ch != 0) + dpk->cur_idx[path] = !dpk->cur_idx[path]; + else + _dpk_onoff(rtwdev, path, false); + } + } else { + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) + dpk->cur_idx[path] = 0; + } + + if ((kpath == RF_A && reloaded[RF_PATH_A]) || + (kpath == RF_B && reloaded[RF_PATH_B]) || + (kpath == RF_AB && reloaded[RF_PATH_A] && reloaded[RF_PATH_B])) + return; + + _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); + + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path)) || reloaded[path]) + continue; + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); + _dpk_information(rtwdev, phy, path, chanctx_idx); + } + + _dpk_bb_afe_setting(rtwdev, phy, path, kpath); + + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path)) || reloaded[path]) + continue; + + is_fail = _dpk_main(rtwdev, phy, path, 1, chanctx_idx); + _dpk_onoff(rtwdev, path, is_fail); + } + + _dpk_bb_afe_restore(rtwdev, phy, path, kpath); + _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); + + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path)) || reloaded[path]) + continue; + + _dpk_kip_restore(rtwdev, path); + _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } +} + +static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_fem_info *fem = &rtwdev->fem; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + + if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); + return true; + } + + return false; +} + +static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, kpath; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + if (kpath & BIT(path)) + _dpk_onoff(rtwdev, path, true); + } +} + +static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool force, enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", + RTW8852A_DPK_VER, rtwdev->hal.cv, + RTW8852A_RF_REL_VERSION); + + if (_dpk_bypass_check(rtwdev, phy, chanctx_idx)) + _dpk_force_bypass(rtwdev, phy); + else + _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), + chanctx_idx); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 val, kidx = dpk->cur_idx[path]; + + val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKBYTE3, 0x6 | val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 path, kidx; + u8 trk_idx = 0, txagc_rf = 0; + s8 txagc_bb = 0, txagc_bb_tp = 0, ini_diff = 0, txagc_ofst = 0; + u16 pwsf[2]; + u8 cur_ther; + s8 delta_ther[2] = {0}; + + for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { + kidx = dpk->cur_idx[path]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] thermal now = %d\n", cur_ther); + + if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) + delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + delta_ther[path] = delta_ther[path] * 3 / 2; + else + delta_ther[path] = delta_ther[path] * 5 / 2; + + txagc_rf = (u8)rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + RR_MODOPT_M_TXPWR); + + if (rtwdev->is_tssi_mode[path]) { + trk_idx = (u8)rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", + txagc_rf, trk_idx); + + txagc_bb = + (s8)rtw89_phy_read32_mask(rtwdev, + R_TXAGC_BB + (path << 13), + MASKBYTE2); + txagc_bb_tp = + (u8)rtw89_phy_read32_mask(rtwdev, + R_TXAGC_TP + (path << 13), + B_TXAGC_TP); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + txagc_ofst = + (s8)rtw89_phy_read32_mask(rtwdev, + R_TXAGC_BB + (path << 13), + MASKBYTE3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", + txagc_ofst, delta_ther[path]); + + if (rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), + BIT(15)) == 0x1) + txagc_ofst = 0; + + if (txagc_rf != 0 && cur_ther != 0) + ini_diff = txagc_ofst + delta_ther[path]; + + if (rtw89_phy_read32_mask(rtwdev, R_P0_TXDPD + (path << 13), + B_P0_TXDPD) == 0x0) { + pwsf[0] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - + txagc_bb + ini_diff + + tssi_info->extra_ofst[path]; + pwsf[1] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - + txagc_bb + ini_diff + + tssi_info->extra_ofst[path]; + } else { + pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff + + tssi_info->extra_ofst[path]; + pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff + + tssi_info->extra_ofst[path]; + } + + } else { + pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + } + + if (rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS) == 0x0 && + txagc_rf != 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", + pwsf[0], pwsf[1]); + + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x000001FF, pwsf[0]); + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x01FF0000, pwsf[1]); + } + } +} + +static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (band == RTW89_BAND_2G) + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); +} + +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852a_tssi_sys_defs_2g_tbl, + &rtw8852a_tssi_sys_defs_5g_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl, + &rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl, + &rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, + &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_dck_defs_a_tbl, + &rtw8852a_tssi_dck_defs_b_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ +#define __get_val(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + const struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 subband = chan->subband_type; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + if (!trk) + trk = &rtw89_8852a_trk_cfg; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = __get_val(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + + } else { + thermal = tssi_info->thermal[RF_PATH_B]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_b[i++] : + -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_b[i++] : + thm_up_b[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = __get_val(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); + } +#undef __get_val +} + +static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_dac_gain_tbl_defs_a_tbl, + &rtw8852a_tssi_dac_gain_tbl_defs_b_tbl); +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_slope_cal_org_defs_a_tbl, + &rtw8852a_tssi_slope_cal_org_defs_b_tbl); +} + +static void _tssi_set_rf_gap_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_rf_gap_tbl_defs_a_tbl, + &rtw8852a_tssi_rf_gap_tbl_defs_b_tbl); +} + +static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_slope_defs_a_tbl, + &rtw8852a_tssi_slope_defs_b_tbl); +} + +static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_track_defs_a_tbl, + &rtw8852a_tssi_track_defs_b_tbl); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl, + &rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl); +} + +static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + u8 subband = chan->subband_type; + + switch (subband) { + default: + case RTW89_CH_2G: + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_pak_defs_a_2g_tbl, + &rtw8852a_tssi_pak_defs_b_2g_tbl); + break; + case RTW89_CH_5G_BAND_1: + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_pak_defs_a_5g_1_tbl, + &rtw8852a_tssi_pak_defs_b_5g_1_tbl); + break; + case RTW89_CH_5G_BAND_3: + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_pak_defs_a_5g_3_tbl, + &rtw8852a_tssi_pak_defs_b_5g_3_tbl); + break; + case RTW89_CH_5G_BAND_4: + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852a_tssi_pak_defs_a_5g_4_tbl, + &rtw8852a_tssi_pak_defs_b_5g_4_tbl); + break; + } +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + _tssi_set_track(rtwdev, phy, i); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); + + rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, + &rtw8852a_tssi_enable_defs_a_tbl, + &rtw8852a_tssi_enable_defs_b_tbl); + + tssi_info->base_thermal[i] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); + rtwdev->is_tssi_mode[i] = true; + } +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 gidx, gidx_1st, gidx_2nd; + s8 de_1st = 0; + s8 de_2nd = 0; + s8 val; + + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 tgidx, tgidx_1st, tgidx_2nd; + s8 tde_1st = 0; + s8 tde_2nd = 0; + s8 val; + + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const struct rtw89_chan *chan) +{ +#define __DE_MASK 0x003ff000 + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858}; + static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860}; + static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838}; + static const u32 r_mcs_40m[RF_PATH_NUM_8852A] = {0x5840, 0x7840}; + static const u32 r_mcs_80m[RF_PATH_NUM_8852A] = {0x5848, 0x7848}; + static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850}; + static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828}; + static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830}; + u8 ch = chan->channel; + u8 i, gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + for (i = 0; i < RF_PATH_NUM_8852A; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, r_cck_long[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_cck_short[i], __DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + r_cck_long[i], + rtw89_phy_read32_mask(rtwdev, r_cck_long[i], + __DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, r_mcs_20m[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_mcs_40m[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_mcs_80m[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_mcs_80m_80m[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_mcs_5m[i], __DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, r_mcs_10m[i], __DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + r_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, r_mcs_20m[i], + __DE_MASK)); + } +#undef __DE_MASK +} + +static void _tssi_track(struct rtw89_dev *rtwdev) +{ + static const u32 tx_gain_scale_table[] = { + 0x400, 0x40e, 0x41d, 0x427, 0x43c, 0x44c, 0x45c, 0x46c, + 0x400, 0x39d, 0x3ab, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f1 + }; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 path; + u8 cur_ther; + s32 delta_ther = 0, gain_offset_int, gain_offset_float; + s8 gain_offset; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] %s:\n", + __func__); + + if (!rtwdev->is_tssi_mode[RF_PATH_A]) + return; + if (!rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + for (path = RF_PATH_A; path < RF_PATH_NUM_8852A; path++) { + if (!tssi_info->tssi_tracking_check[path]) { + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] return!!!\n"); + continue; + } + + cur_ther = (u8)rtw89_phy_read32_mask(rtwdev, + R_TSSI_THER + (path << 13), + B_TSSI_THER); + + if (cur_ther == 0 || tssi_info->base_thermal[path] == 0) + continue; + + delta_ther = cur_ther - tssi_info->base_thermal[path]; + + gain_offset = (s8)delta_ther * 15 / 10; + + tssi_info->extra_ofst[path] = gain_offset; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRK] base_thermal=%d gain_offset=0x%x path=%d\n", + tssi_info->base_thermal[path], gain_offset, path); + + gain_offset_int = gain_offset >> 3; + gain_offset_float = gain_offset & 7; + + if (gain_offset_int > 15) + gain_offset_int = 15; + else if (gain_offset_int < -16) + gain_offset_int = -16; + + rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN + (path << 13), + B_DPD_OFT_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), + B_TXGAIN_SCALE_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_ADDR + (path << 13), + B_DPD_OFT_ADDR, gain_offset_int); + + rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), + B_TXGAIN_SCALE_OFT, + tx_gain_scale_table[gain_offset_float]); + } +} + +static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel, ch_tmp; + u8 bw = chan->band_width; + u8 band = chan->band_type; + u8 subband = chan->subband_type; + s8 power; + s32 xdbm; + + if (bw == RTW89_CHANNEL_WIDTH_40) + ch_tmp = ch - 2; + else if (bw == RTW89_CHANNEL_WIDTH_80) + ch_tmp = ch - 6; + else + ch_tmp = ch; + + power = rtw89_phy_read_txpwr_limit(rtwdev, band, bw, RTW89_1TX, + RTW89_RS_MCS, RTW89_NONBF, ch_tmp); + + xdbm = power * 100 / 4; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d xdbm=%d\n", + __func__, phy, xdbm); + + if (xdbm > 1800 && subband == RTW89_CH_2G) { + tssi_info->tssi_tracking_check[RF_PATH_A] = true; + tssi_info->tssi_tracking_check[RF_PATH_B] = true; + } else { + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_tracking_defs_tbl); + tssi_info->extra_ofst[RF_PATH_A] = 0; + tssi_info->extra_ofst[RF_PATH_B] = 0; + tssi_info->tssi_tracking_check[RF_PATH_A] = false; + tssi_info->tssi_tracking_check[RF_PATH_B] = false; + } +} + +static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 path, s16 pwr_dbm, u8 enable, const struct rtw89_chan *chan) +{ + rtw8852a_bb_set_plcp_tx(rtwdev); + rtw8852a_bb_cfg_tx_path(rtwdev, path); + rtw8852a_bb_set_power(rtwdev, pwr_dbm, phy); + rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy, chan); +} + +static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + const struct rtw89_chip_info *mac_reg = rtwdev->chip; + u8 ch = chan->channel, ch_tmp; + u8 bw = chan->band_width; + u8 band = chan->band_type; + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0, chanctx_idx); + s8 power; + s16 xdbm; + u32 i, tx_counter = 0; + + if (bw == RTW89_CHANNEL_WIDTH_40) + ch_tmp = ch - 2; + else if (bw == RTW89_CHANNEL_WIDTH_80) + ch_tmp = ch - 6; + else + ch_tmp = ch; + + power = rtw89_phy_read_txpwr_limit(rtwdev, band, RTW89_CHANNEL_WIDTH_20, + RTW89_1TX, RTW89_RS_OFDM, + RTW89_NONBF, ch_tmp); + + xdbm = (power * 100) >> mac_reg->txpwr_factor_mac; + + if (xdbm > 1800) + xdbm = 68; + else + xdbm = power * 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] %s: phy=%d org_power=%d xdbm=%d\n", + __func__, phy, power, xdbm); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy)); + tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + + _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true, chan); + mdelay(15); + _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false, chan); + + tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD) - + tx_counter; + + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_A] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, + MASKBYTE3); + + if (tssi_info->default_txagc_offset[RF_PATH_A] != 0x0) + break; + } + } + + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_B] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, + MASKBYTE3); + + if (tssi_info->default_txagc_offset[RF_PATH_B] != 0x0) + break; + } + } + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] %s: tx counter=%d\n", + __func__, tx_counter); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Backup R_TXAGC_BB=0x%x R_TXAGC_BB_S1=0x%x\n", + tssi_info->default_txagc_offset[RF_PATH_A], + tssi_info->default_txagc_offset[RF_PATH_B]); + + rtw8852a_bb_tx_mode_switch(rtwdev, phy, 0); + + rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8852a_rck(struct rtw89_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < 2; path++) + _rck(rtwdev, path); +} + +void rtw8852a_dack(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); + _dac_cal(rtwdev, false, chanctx_idx); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); +} + +void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + if (rtwdev->dbcc_en) + _iqk_dbcc(rtwdev, phy_idx, chanctx_idx); + else + _iqk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + +void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + bool is_afe, enum rtw89_chanctx_idx chanctx_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _rx_dck(rtwdev, phy_idx, is_afe, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); +} + +void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + rtwdev->dpk.is_dpk_enable = true; + rtwdev->dpk.is_dpk_reload_en = false; + _dpk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8852a_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + +void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", + __func__, phy); + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, chan); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i, chan); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_set_dac_gain_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i); + _tssi_set_rf_gap_tbl(rtwdev, phy, i); + _tssi_set_slope(rtwdev, phy, i); + _tssi_pak(rtwdev, phy, i, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); + _tssi_high_power(rtwdev, phy, chan); + _tssi_pre_tx(rtwdev, phy, chanctx_idx); +} + +void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", + __func__, phy); + + if (!rtwdev->is_tssi_mode[RF_PATH_A]) + return; + if (!rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, chan); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_pak(rtwdev, phy, i, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +void rtw8852a_tssi_track(struct rtw89_dev *rtwdev) +{ + _tssi_track(rtwdev); +} + +static +void _rtw8852a_tssi_avg_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + /* disable */ + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x0); + + /* enable */ + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); +} + +static +void _rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + /* disable */ + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x4); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x4); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); + + /* enable */ + rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); +} + +static void rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable) +{ + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (enable) { + /* SCAN_START */ + _rtw8852a_tssi_avg_scan(rtwdev, phy); + } else { + /* SCAN_END */ + _rtw8852a_tssi_set_avg(rtwdev, phy); + } +} + +static void rtw8852a_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 i; + + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (enable) { + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_A] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, + B_TXAGC_BB); + if (tssi_info->default_txagc_offset[RF_PATH_A]) + break; + } + } + + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_B] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, + B_TXAGC_BB_S1); + if (tssi_info->default_txagc_offset[RF_PATH_B]) + break; + } + } + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_A]); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_B]); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); + } +} + +void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, + bool scan_start, enum rtw89_phy_idx phy_idx) +{ + if (scan_start) { + rtw8852a_tssi_default_txagc(rtwdev, phy_idx, true); + rtw8852a_tssi_set_avg(rtwdev, phy_idx, true); + } else { + rtw8852a_tssi_default_txagc(rtwdev, phy_idx, false); + rtw8852a_tssi_set_avg(rtwdev, phy_idx, false); + } +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h new file mode 100644 index 000000000..8761f2cc9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852A_RFK_H__ +#define __RTW89_8852A_RFK_H__ + +#include "core.h" + +void rtw8852a_rck(struct rtw89_dev *rtwdev); +void rtw8852a_dack(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + bool is_afe, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852a_dpk_track(struct rtw89_dev *rtwdev); +void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan); +void rtw8852a_tssi_track(struct rtw89_dev *rtwdev); +void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c new file mode 100644 index 000000000..dd2a978b9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c @@ -0,0 +1,1607 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "rtw8852a_rfk_table.h" + +static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12a8, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x12a8, 0x0000000e, 0x00000002), + RTW89_DECL_RFK_WM(0x32a8, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x32a8, 0x0000000e, 0x00000002), + RTW89_DECL_RFK_WM(0x12bc, 0x000000f0, 0x00000005), + RTW89_DECL_RFK_WM(0x12bc, 0x00000f00, 0x00000005), + RTW89_DECL_RFK_WM(0x12bc, 0x000f0000, 0x00000005), + RTW89_DECL_RFK_WM(0x12bc, 0x0000f000, 0x00000005), + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), + RTW89_DECL_RFK_WM(0x32bc, 0x000000f0, 0x00000005), + RTW89_DECL_RFK_WM(0x32bc, 0x00000f00, 0x00000005), + RTW89_DECL_RFK_WM(0x32bc, 0x000f0000, 0x00000005), + RTW89_DECL_RFK_WM(0x32bc, 0x0000f000, 0x00000005), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x00000019), + RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x00000019), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x0000001d), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x00002044), + RTW89_DECL_RFK_WM(0x0318, 0x0000ffff, 0x00002042), + RTW89_DECL_RFK_WM(0x0318, 0xffff0000, 0x00002002), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x00000003), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x00000003), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x0000601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x0000601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x00000004), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x00000004), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x00000000), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_2g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_2g); + +static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_5g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x00000044), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000044), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000044), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x00000044), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_5g); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_a[] = { + RTW89_DECL_RFK_WM(0x5800, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x5800, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x5800, 0x003f0000, 0x0000003f), + RTW89_DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5800, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5800, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x00000040), + RTW89_DECL_RFK_WM(0x580c, 0x00007f00, 0x00000040), + RTW89_DECL_RFK_WM(0x580c, 0x00008000, 0x00000000), + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x0000fc00, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x00010000, 0x00000001), + RTW89_DECL_RFK_WM(0x5810, 0x00fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5810, 0x06000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5810, 0x38000000, 0x00000003), + RTW89_DECL_RFK_WM(0x5810, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5810, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00000c00, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), + RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x01c00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0xe0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x000000ff, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x0001ff00, 0x00000018), + RTW89_DECL_RFK_WM(0x5818, 0x03fe0000, 0x00000016), + RTW89_DECL_RFK_WM(0x5818, 0xfc000000, 0x00000000), + RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), + RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), + RTW89_DECL_RFK_WM(0x581c, 0x01e00000, 0x00000008), + RTW89_DECL_RFK_WM(0x581c, 0x01e00000, 0x0000000e), + RTW89_DECL_RFK_WM(0x581c, 0x1e000000, 0x00000008), + RTW89_DECL_RFK_WM(0x581c, 0x1e000000, 0x0000000e), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), + RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0x0000000f), + RTW89_DECL_RFK_WM(0x5820, 0x001f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5820, 0xffe00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x5864, 0x03f00000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0x04000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a0, 0x000000ff, 0x000000fd), + RTW89_DECL_RFK_WM(0x58a0, 0x0000ff00, 0x000000e5), + RTW89_DECL_RFK_WM(0x58a0, 0x00ff0000, 0x000000cd), + RTW89_DECL_RFK_WM(0x58a0, 0xff000000, 0x000000b5), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x00000016), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x0000001f, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x00000020, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x000001c0, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x0000f000, 0x00000002), + RTW89_DECL_RFK_WM(0x58b4, 0x00ff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), + RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), + RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), + RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58bc, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x58bc, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x58bc, 0x00030000, 0x00000003), + RTW89_DECL_RFK_WM(0x58bc, 0x000c0000, 0x00000001), + RTW89_DECL_RFK_WM(0x58bc, 0x00300000, 0x00000002), + RTW89_DECL_RFK_WM(0x58bc, 0x00c00000, 0x00000002), + RTW89_DECL_RFK_WM(0x58bc, 0x07000000, 0x00000007), + RTW89_DECL_RFK_WM(0x58c0, 0x00fe0000, 0x0000003f), + RTW89_DECL_RFK_WM(0x58c0, 0xff000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58c4, 0x0003ffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58c4, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x00001fff, 0x00000101), + RTW89_DECL_RFK_WM(0x58d0, 0x0001e000, 0x00000004), + RTW89_DECL_RFK_WM(0x58d0, 0x03fe0000, 0x00000100), + RTW89_DECL_RFK_WM(0x58d0, 0x04000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x000000ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x00000100), + RTW89_DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), + RTW89_DECL_RFK_WM(0x58d8, 0x0003fe00, 0x0000005c), + RTW89_DECL_RFK_WM(0x58d8, 0x000c0000, 0x00000002), + RTW89_DECL_RFK_WM(0x58d8, 0xfff00000, 0x00000800), + RTW89_DECL_RFK_WM(0x58dc, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x58dc, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x58dc, 0x00010000, 0x00000000), + RTW89_DECL_RFK_WM(0x58dc, 0x3ff00000, 0x00000000), + RTW89_DECL_RFK_WM(0x58dc, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x58f0, 0x000001ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x58f0, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_b[] = { + RTW89_DECL_RFK_WM(0x7800, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x7800, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x7800, 0x003f0000, 0x0000003f), + RTW89_DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7800, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7800, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), + RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x00000040), + RTW89_DECL_RFK_WM(0x780c, 0x00007f00, 0x00000040), + RTW89_DECL_RFK_WM(0x780c, 0x00008000, 0x00000000), + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x0000fc00, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x00010000, 0x00000001), + RTW89_DECL_RFK_WM(0x7810, 0x00fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7810, 0x06000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7810, 0x38000000, 0x00000003), + RTW89_DECL_RFK_WM(0x7810, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7810, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00000c00, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x7814, 0x00002000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), + RTW89_DECL_RFK_WM(0x7814, 0x003c0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x01c00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0xe0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x000000ff, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x0001ff00, 0x00000018), + RTW89_DECL_RFK_WM(0x7818, 0x03fe0000, 0x00000016), + RTW89_DECL_RFK_WM(0x7818, 0xfc000000, 0x00000000), + RTW89_DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), + RTW89_DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), + RTW89_DECL_RFK_WM(0x781c, 0x01e00000, 0x00000008), + RTW89_DECL_RFK_WM(0x781c, 0x01e00000, 0x0000000e), + RTW89_DECL_RFK_WM(0x781c, 0x1e000000, 0x00000008), + RTW89_DECL_RFK_WM(0x781c, 0x1e000000, 0x0000000e), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), + RTW89_DECL_RFK_WM(0x7820, 0x0000f000, 0x00000000), + RTW89_DECL_RFK_WM(0x7820, 0x001f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7820, 0xffe00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7858, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x7864, 0x03f00000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0x04000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a0, 0x000000ff, 0x000000fd), + RTW89_DECL_RFK_WM(0x78a0, 0x0000ff00, 0x000000e5), + RTW89_DECL_RFK_WM(0x78a0, 0x00ff0000, 0x000000cd), + RTW89_DECL_RFK_WM(0x78a0, 0xff000000, 0x000000b5), + RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x00000016), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x0000001f, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x00000020, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x000001c0, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x0000f000, 0x00000002), + RTW89_DECL_RFK_WM(0x78b4, 0x00ff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), + RTW89_DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), + RTW89_DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), + RTW89_DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78bc, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x78bc, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x78bc, 0x00030000, 0x00000003), + RTW89_DECL_RFK_WM(0x78bc, 0x000c0000, 0x00000001), + RTW89_DECL_RFK_WM(0x78bc, 0x00300000, 0x00000002), + RTW89_DECL_RFK_WM(0x78bc, 0x00c00000, 0x00000002), + RTW89_DECL_RFK_WM(0x78bc, 0x07000000, 0x00000007), + RTW89_DECL_RFK_WM(0x78c0, 0x00fe0000, 0x0000003f), + RTW89_DECL_RFK_WM(0x78c0, 0xff000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78c4, 0x0003ffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78c4, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d0, 0x00001fff, 0x00000101), + RTW89_DECL_RFK_WM(0x78d0, 0x0001e000, 0x00000004), + RTW89_DECL_RFK_WM(0x78d0, 0x03fe0000, 0x00000100), + RTW89_DECL_RFK_WM(0x78d0, 0x04000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x000000ff), + RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x00000100), + RTW89_DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), + RTW89_DECL_RFK_WM(0x78d8, 0x0003fe00, 0x0000005c), + RTW89_DECL_RFK_WM(0x78d8, 0x000c0000, 0x00000002), + RTW89_DECL_RFK_WM(0x78d8, 0xfff00000, 0x00000800), + RTW89_DECL_RFK_WM(0x78dc, 0x000000ff, 0x0000007f), + RTW89_DECL_RFK_WM(0x78dc, 0x0000ff00, 0x00000080), + RTW89_DECL_RFK_WM(0x78dc, 0x00010000, 0x00000000), + RTW89_DECL_RFK_WM(0x78dc, 0x3ff00000, 0x00000000), + RTW89_DECL_RFK_WM(0x78dc, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x78f0, 0x000001ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x78f0, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_2g[] = { + RTW89_DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000013c), + RTW89_DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000013c), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_2g); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_5g[] = { + RTW89_DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), + RTW89_DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_5g); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fc), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x00000020), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = { + RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fc), + RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x00000020), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x00000001), + RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), + RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x00000003), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x7814, 0x00002000, 0x00000001), + RTW89_DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), + RTW89_DECL_RFK_WM(0x7814, 0x003c0000, 0x00000003), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_a[] = { + RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x00000000), + RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x00000001), + RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_b[] = { + RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x00000000), + RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x00000001), + RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_a[] = { + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), + RTW89_DECL_RFK_WM(0x58cc, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x58cc, 0x00000007, 0x00000000), + RTW89_DECL_RFK_WM(0x58cc, 0x00000038, 0x00000001), + RTW89_DECL_RFK_WM(0x58cc, 0x000001c0, 0x00000002), + RTW89_DECL_RFK_WM(0x58cc, 0x00000e00, 0x00000003), + RTW89_DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x5898, 0x000000ff, 0x00000040), + RTW89_DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x5898, 0x0000ff00, 0x00000040), + RTW89_DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x5898, 0x00ff0000, 0x00000040), + RTW89_DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x5898, 0xff000000, 0x00000040), + RTW89_DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x589c, 0x000000ff, 0x00000040), + RTW89_DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x589c, 0x0000ff00, 0x00000040), + RTW89_DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x589c, 0x00ff0000, 0x00000040), + RTW89_DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x589c, 0xff000000, 0x00000040), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_b[] = { + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), + RTW89_DECL_RFK_WM(0x78cc, 0x00001000, 0x00000001), + RTW89_DECL_RFK_WM(0x78cc, 0x00000007, 0x00000000), + RTW89_DECL_RFK_WM(0x78cc, 0x00000038, 0x00000001), + RTW89_DECL_RFK_WM(0x78cc, 0x000001c0, 0x00000002), + RTW89_DECL_RFK_WM(0x78cc, 0x00000e00, 0x00000003), + RTW89_DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x7898, 0x000000ff, 0x00000040), + RTW89_DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x7898, 0x0000ff00, 0x00000040), + RTW89_DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x7898, 0x00ff0000, 0x00000040), + RTW89_DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x7898, 0xff000000, 0x00000040), + RTW89_DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x789c, 0x000000ff, 0x00000040), + RTW89_DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x789c, 0x0000ff00, 0x00000040), + RTW89_DECL_RFK_WM(0x7878, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x789c, 0x00ff0000, 0x00000040), + RTW89_DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000040), + RTW89_DECL_RFK_WM(0x789c, 0xff000000, 0x00000040), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_a[] = { + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_b[] = { + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x00000001), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0x00000001), + RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), + RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), + RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), + RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), + RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x00000001), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7820, 0x0000f000, 0x00000001), + RTW89_DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), + RTW89_DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), + RTW89_DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), + RTW89_DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), + RTW89_DECL_RFK_WM(0x7810, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), + RTW89_DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x18000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x00000000), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), + RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x18000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x00000000), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), + RTW89_DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), + RTW89_DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), + RTW89_DECL_RFK_WM(0x7814, 0x01000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), + RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x00000000), + RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_b[] = { + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), + RTW89_DECL_RFK_WM(0x78e4, 0x00008000, 0x00000000), + RTW89_DECL_RFK_WM(0x78e4, 0x000f0000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_2g[] = { + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d0), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001e8), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x0000000b), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000088), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_2g); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_1[] = { + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d7), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fb), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000005), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x0000007c), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_1); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_3[] = { + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d8), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fc), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000006), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000078), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_3); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_4[] = { + RTW89_DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001e5), + RTW89_DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a8, 0x0003fe00, 0x0000000a), + RTW89_DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000011), + RTW89_DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000075), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_4); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_2g[] = { + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001cc), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001e2), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000005), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000089), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_2g); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_1[] = { + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001d5), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001fc), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000005), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000079), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_1); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_3[] = { + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001dc), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000002), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000000b), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000076), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_3); + +static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_4[] = { + RTW89_DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001f0), + RTW89_DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000016), + RTW89_DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), + RTW89_DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000001f), + RTW89_DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000072), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_4); + +static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_a[] = { + RTW89_DECL_RFK_WRF(0x0, 0x55, 0x00080, 0x00001), + RTW89_DECL_RFK_WM(0x5818, 0x000000ff, 0x000000c0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5818, 0x18000000, 0x00000003), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_a); + +static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_b[] = { + RTW89_DECL_RFK_WRF(0x1, 0x55, 0x00080, 0x00001), + RTW89_DECL_RFK_WM(0x7818, 0x000000ff, 0x000000c0), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7818, 0x18000000, 0x00000003), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_b); + +static const struct rtw89_reg5_def rtw8852a_tssi_disable_defs[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x18000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x18000000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_disable_defs); + +static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_ab[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5818, 0x18000000, 0x3), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7818, 0x18000000, 0x3), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_ab); + +static const struct rtw89_reg5_def rtw8852a_tssi_tracking_defs[] = { + RTW89_DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), + RTW89_DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58f0, 0xfff00000, 0x00000400), + RTW89_DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), + RTW89_DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78f0, 0xfff00000, 0x00000400), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_tssi_tracking_defs); + +static const struct rtw89_reg5_def rtw8852a_rfk_afe_init_defs[] = { + RTW89_DECL_RFK_WC(0x12ec, 0x00008000), + RTW89_DECL_RFK_WS(0x12ec, 0x00008000), + RTW89_DECL_RFK_WC(0x5e00, 0x00000001), + RTW89_DECL_RFK_WS(0x5e00, 0x00000001), + RTW89_DECL_RFK_WC(0x32ec, 0x00008000), + RTW89_DECL_RFK_WS(0x32ec, 0x00008000), + RTW89_DECL_RFK_WC(0x7e00, 0x00000001), + RTW89_DECL_RFK_WS(0x7e00, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_afe_init_defs); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_a[] = { + RTW89_DECL_RFK_WS(0x5e00, 0x00000008), + RTW89_DECL_RFK_WS(0x5e50, 0x00000008), + RTW89_DECL_RFK_WS(0x5e10, 0x80000000), + RTW89_DECL_RFK_WS(0x5e60, 0x80000000), + RTW89_DECL_RFK_WC(0x5e00, 0x00000008), + RTW89_DECL_RFK_WC(0x5e50, 0x00000008), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_b[] = { + RTW89_DECL_RFK_WS(0x7e00, 0x00000008), + RTW89_DECL_RFK_WS(0x7e50, 0x00000008), + RTW89_DECL_RFK_WS(0x7e10, 0x80000000), + RTW89_DECL_RFK_WS(0x7e60, 0x80000000), + RTW89_DECL_RFK_WC(0x7e00, 0x00000008), + RTW89_DECL_RFK_WC(0x7e50, 0x00000008), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_a[] = { + RTW89_DECL_RFK_WC(0x20f4, 0x01000000), + RTW89_DECL_RFK_WS(0x20f8, 0x80000000), + RTW89_DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), + RTW89_DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), + RTW89_DECL_RFK_WC(0x20f0, 0x0000000f), + RTW89_DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000002), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_b[] = { + RTW89_DECL_RFK_WC(0x20f4, 0x01000000), + RTW89_DECL_RFK_WS(0x20f8, 0x80000000), + RTW89_DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), + RTW89_DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), + RTW89_DECL_RFK_WC(0x20f0, 0x0000000f), + RTW89_DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000003), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_a[] = { + RTW89_DECL_RFK_WC(0x12d8, 0x00000030), + RTW89_DECL_RFK_WC(0x32d8, 0x00000030), + RTW89_DECL_RFK_WS(0x12b8, 0x40000000), + RTW89_DECL_RFK_WC(0x032c, 0x40000000), + RTW89_DECL_RFK_WC(0x032c, 0x00400000), + RTW89_DECL_RFK_WS(0x032c, 0x00400000), + RTW89_DECL_RFK_WS(0x030c, 0x0f000000), + RTW89_DECL_RFK_WC(0x032c, 0x00010000), + RTW89_DECL_RFK_WS(0x12dc, 0x00000002), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_a[] = { + RTW89_DECL_RFK_WS(0x12d8, 0x000000c0), + RTW89_DECL_RFK_WS(0x12d8, 0x00000800), + RTW89_DECL_RFK_WC(0x12d8, 0x00000800), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x12d8, 0x00000300, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_a[] = { + RTW89_DECL_RFK_WC(0x12dc, 0x00000002), + RTW89_DECL_RFK_WS(0x032c, 0x00010000), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), + RTW89_DECL_RFK_WS(0x032c, 0x40000000), + RTW89_DECL_RFK_WC(0x12b8, 0x40000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_b[] = { + RTW89_DECL_RFK_WS(0x32b8, 0x40000000), + RTW89_DECL_RFK_WC(0x032c, 0x40000000), + RTW89_DECL_RFK_WC(0x032c, 0x00400000), + RTW89_DECL_RFK_WS(0x032c, 0x00400000), + RTW89_DECL_RFK_WS(0x030c, 0x0f000000), + RTW89_DECL_RFK_WC(0x032c, 0x00010000), + RTW89_DECL_RFK_WS(0x32dc, 0x00000002), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_b[] = { + RTW89_DECL_RFK_WS(0x32d8, 0x000000c0), + RTW89_DECL_RFK_WS(0x32d8, 0x00000800), + RTW89_DECL_RFK_WC(0x32d8, 0x00000800), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x32d8, 0x00000300, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_b[] = { + RTW89_DECL_RFK_WC(0x32dc, 0x00000002), + RTW89_DECL_RFK_WS(0x032c, 0x00010000), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), + RTW89_DECL_RFK_WS(0x032c, 0x40000000), + RTW89_DECL_RFK_WC(0x32b8, 0x40000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_a[] = { + RTW89_DECL_RFK_WC(0x032c, 0x40000000), + RTW89_DECL_RFK_WS(0x030c, 0x0f000000), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), + RTW89_DECL_RFK_WC(0x032c, 0x00010000), + RTW89_DECL_RFK_WS(0x12dc, 0x00000001), + RTW89_DECL_RFK_WS(0x12e8, 0x00000004), + RTW89_DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_b[] = { + RTW89_DECL_RFK_WC(0x032c, 0x40000000), + RTW89_DECL_RFK_WS(0x030c, 0x0f000000), + RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), + RTW89_DECL_RFK_WC(0x032c, 0x00010000), + RTW89_DECL_RFK_WS(0x32dc, 0x00000001), + RTW89_DECL_RFK_WS(0x32e8, 0x00000004), + RTW89_DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_a[] = { + RTW89_DECL_RFK_WC(0x12dc, 0x00000001), + RTW89_DECL_RFK_WC(0x12e8, 0x00000004), + RTW89_DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00000), + RTW89_DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_b[] = { + RTW89_DECL_RFK_WC(0x32dc, 0x00000001), + RTW89_DECL_RFK_WC(0x32e8, 0x00000004), + RTW89_DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00000), + RTW89_DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_a[] = { + RTW89_DECL_RFK_WS(0x5e00, 0x00000008), + RTW89_DECL_RFK_WC(0x5e10, 0x80000000), + RTW89_DECL_RFK_WS(0x5e50, 0x00000008), + RTW89_DECL_RFK_WC(0x5e60, 0x80000000), + RTW89_DECL_RFK_WS(0x12a0, 0x00008000), + RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x00000003), + RTW89_DECL_RFK_WS(0x12b8, 0x40000000), + RTW89_DECL_RFK_WS(0x030c, 0x10000000), + RTW89_DECL_RFK_WC(0x032c, 0x80000000), + RTW89_DECL_RFK_WS(0x12e0, 0x00010000), + RTW89_DECL_RFK_WS(0x12e4, 0x0c000000), + RTW89_DECL_RFK_WM(0x5e00, 0x03ff0000, 0x00000030), + RTW89_DECL_RFK_WM(0x5e50, 0x03ff0000, 0x00000030), + RTW89_DECL_RFK_WC(0x5e00, 0x0c000000), + RTW89_DECL_RFK_WC(0x5e50, 0x0c000000), + RTW89_DECL_RFK_WC(0x5e0c, 0x00000008), + RTW89_DECL_RFK_WC(0x5e5c, 0x00000008), + RTW89_DECL_RFK_WS(0x5e0c, 0x00000001), + RTW89_DECL_RFK_WS(0x5e5c, 0x00000001), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_a[] = { + RTW89_DECL_RFK_WC(0x12e4, 0x0c000000), + RTW89_DECL_RFK_WS(0x5e0c, 0x00000008), + RTW89_DECL_RFK_WS(0x5e5c, 0x00000008), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_a[] = { + RTW89_DECL_RFK_WC(0x5e0c, 0x00000001), + RTW89_DECL_RFK_WC(0x5e5c, 0x00000001), + RTW89_DECL_RFK_WC(0x12e0, 0x00010000), + RTW89_DECL_RFK_WC(0x12a0, 0x00008000), + RTW89_DECL_RFK_WS(0x12a0, 0x00007000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_b[] = { + RTW89_DECL_RFK_WS(0x7e00, 0x00000008), + RTW89_DECL_RFK_WC(0x7e10, 0x80000000), + RTW89_DECL_RFK_WS(0x7e50, 0x00000008), + RTW89_DECL_RFK_WC(0x7e60, 0x80000000), + RTW89_DECL_RFK_WS(0x32a0, 0x00008000), + RTW89_DECL_RFK_WM(0x32a0, 0x00007000, 0x00000003), + RTW89_DECL_RFK_WS(0x32b8, 0x40000000), + RTW89_DECL_RFK_WS(0x030c, 0x10000000), + RTW89_DECL_RFK_WC(0x032c, 0x80000000), + RTW89_DECL_RFK_WS(0x32e0, 0x00010000), + RTW89_DECL_RFK_WS(0x32e4, 0x0c000000), + RTW89_DECL_RFK_WM(0x7e00, 0x03ff0000, 0x00000030), + RTW89_DECL_RFK_WM(0x7e50, 0x03ff0000, 0x00000030), + RTW89_DECL_RFK_WC(0x7e00, 0x0c000000), + RTW89_DECL_RFK_WC(0x7e50, 0x0c000000), + RTW89_DECL_RFK_WC(0x7e0c, 0x00000008), + RTW89_DECL_RFK_WC(0x7e5c, 0x00000008), + RTW89_DECL_RFK_WS(0x7e0c, 0x00000001), + RTW89_DECL_RFK_WS(0x7e5c, 0x00000001), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_b[] = { + RTW89_DECL_RFK_WC(0x32e4, 0x0c000000), + RTW89_DECL_RFK_WM(0x7e0c, 0x00000008, 0x00000001), + RTW89_DECL_RFK_WM(0x7e5c, 0x00000008, 0x00000001), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_b[] = { + RTW89_DECL_RFK_WC(0x7e0c, 0x00000001), + RTW89_DECL_RFK_WC(0x7e5c, 0x00000001), + RTW89_DECL_RFK_WC(0x32e0, 0x00010000), + RTW89_DECL_RFK_WC(0x32a0, 0x00008000), + RTW89_DECL_RFK_WS(0x32a0, 0x00007000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_a[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), + RTW89_DECL_RFK_WS(0x12b8, 0x40000000), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), + RTW89_DECL_RFK_WS(0x12b8, 0x10000000), + RTW89_DECL_RFK_WS(0x58c8, 0x01000000), + RTW89_DECL_RFK_WS(0x5864, 0xc0000000), + RTW89_DECL_RFK_WS(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WS(0x0c1c, 0x00000004), + RTW89_DECL_RFK_WS(0x0700, 0x08000000), + RTW89_DECL_RFK_WS(0x0c70, 0x000003ff), + RTW89_DECL_RFK_WS(0x0c60, 0x00000003), + RTW89_DECL_RFK_WS(0x0c6c, 0x00000001), + RTW89_DECL_RFK_WS(0x58ac, 0x08000000), + RTW89_DECL_RFK_WS(0x0c3c, 0x00000200), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_a[] = { + RTW89_DECL_RFK_WS(0x4490, 0x80000000), + RTW89_DECL_RFK_WS(0x12a0, 0x00007000), + RTW89_DECL_RFK_WS(0x12a0, 0x00008000), + RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WS(0x12a0, 0x00080000), + RTW89_DECL_RFK_WS(0x0700, 0x01000000), + RTW89_DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), + RTW89_DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_b[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), + RTW89_DECL_RFK_WS(0x32b8, 0x40000000), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), + RTW89_DECL_RFK_WS(0x32b8, 0x10000000), + RTW89_DECL_RFK_WS(0x78c8, 0x01000000), + RTW89_DECL_RFK_WS(0x7864, 0xc0000000), + RTW89_DECL_RFK_WS(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WS(0x2c1c, 0x00000004), + RTW89_DECL_RFK_WS(0x2700, 0x08000000), + RTW89_DECL_RFK_WS(0x0c70, 0x000003ff), + RTW89_DECL_RFK_WS(0x0c60, 0x00000003), + RTW89_DECL_RFK_WS(0x0c6c, 0x00000001), + RTW89_DECL_RFK_WS(0x78ac, 0x08000000), + RTW89_DECL_RFK_WS(0x2c3c, 0x00000200), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_b[] = { + RTW89_DECL_RFK_WS(0x6490, 0x80000000), + RTW89_DECL_RFK_WS(0x32a0, 0x00007000), + RTW89_DECL_RFK_WS(0x32a0, 0x00008000), + RTW89_DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WS(0x32a0, 0x00080000), + RTW89_DECL_RFK_WS(0x2700, 0x01000000), + RTW89_DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), + RTW89_DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_s_defs_ab[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), + RTW89_DECL_RFK_WS(0x12b8, 0x40000000), + RTW89_DECL_RFK_WS(0x32b8, 0x40000000), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), + RTW89_DECL_RFK_WS(0x12b8, 0x10000000), + RTW89_DECL_RFK_WS(0x58c8, 0x01000000), + RTW89_DECL_RFK_WS(0x78c8, 0x01000000), + RTW89_DECL_RFK_WS(0x5864, 0xc0000000), + RTW89_DECL_RFK_WS(0x7864, 0xc0000000), + RTW89_DECL_RFK_WS(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WS(0x0c1c, 0x00000004), + RTW89_DECL_RFK_WS(0x0700, 0x08000000), + RTW89_DECL_RFK_WS(0x0c70, 0x000003ff), + RTW89_DECL_RFK_WS(0x0c60, 0x00000003), + RTW89_DECL_RFK_WS(0x0c6c, 0x00000001), + RTW89_DECL_RFK_WS(0x58ac, 0x08000000), + RTW89_DECL_RFK_WS(0x78ac, 0x08000000), + RTW89_DECL_RFK_WS(0x0c3c, 0x00000200), + RTW89_DECL_RFK_WS(0x2344, 0x80000000), + RTW89_DECL_RFK_WS(0x4490, 0x80000000), + RTW89_DECL_RFK_WS(0x12a0, 0x00007000), + RTW89_DECL_RFK_WS(0x12a0, 0x00008000), + RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WS(0x12a0, 0x00080000), + RTW89_DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WS(0x32a0, 0x00080000), + RTW89_DECL_RFK_WS(0x0700, 0x01000000), + RTW89_DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), + RTW89_DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), + RTW89_DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_s_defs_ab); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_a[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), + RTW89_DECL_RFK_WC(0x12b8, 0x40000000), + RTW89_DECL_RFK_WC(0x5864, 0xc0000000), + RTW89_DECL_RFK_WC(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WC(0x0c1c, 0x00000004), + RTW89_DECL_RFK_WC(0x0700, 0x08000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WC(0x12a0, 0x000ff000), + RTW89_DECL_RFK_WC(0x0700, 0x07000000), + RTW89_DECL_RFK_WC(0x5864, 0x20000000), + RTW89_DECL_RFK_WC(0x0c3c, 0x00000200), + RTW89_DECL_RFK_WC(0x20fc, 0xffff0000), + RTW89_DECL_RFK_WC(0x58c8, 0x01000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_a); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_b[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), + RTW89_DECL_RFK_WC(0x32b8, 0x40000000), + RTW89_DECL_RFK_WC(0x7864, 0xc0000000), + RTW89_DECL_RFK_WC(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WC(0x2c1c, 0x00000004), + RTW89_DECL_RFK_WC(0x2700, 0x08000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WC(0x32a0, 0x000ff000), + RTW89_DECL_RFK_WC(0x2700, 0x07000000), + RTW89_DECL_RFK_WC(0x7864, 0x20000000), + RTW89_DECL_RFK_WC(0x2c3c, 0x00000200), + RTW89_DECL_RFK_WC(0x20fc, 0xffff0000), + RTW89_DECL_RFK_WC(0x78c8, 0x01000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_b); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_ab[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), + RTW89_DECL_RFK_WC(0x12b8, 0x40000000), + RTW89_DECL_RFK_WC(0x32b8, 0x40000000), + RTW89_DECL_RFK_WC(0x5864, 0xc0000000), + RTW89_DECL_RFK_WC(0x7864, 0xc0000000), + RTW89_DECL_RFK_WC(0x2008, 0x01ffffff), + RTW89_DECL_RFK_WC(0x0c1c, 0x00000004), + RTW89_DECL_RFK_WC(0x0700, 0x08000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WC(0x12a0, 0x000ff000), + RTW89_DECL_RFK_WC(0x32a0, 0x000ff000), + RTW89_DECL_RFK_WC(0x0700, 0x07000000), + RTW89_DECL_RFK_WC(0x5864, 0x20000000), + RTW89_DECL_RFK_WC(0x7864, 0x20000000), + RTW89_DECL_RFK_WC(0x0c3c, 0x00000200), + RTW89_DECL_RFK_WC(0x20fc, 0xffff0000), + RTW89_DECL_RFK_WC(0x58c8, 0x01000000), + RTW89_DECL_RFK_WC(0x78c8, 0x01000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_ab); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_f[] = { + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0000000f), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000003), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a001), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a041), + RTW89_DECL_RFK_WS(0x8074, 0x80000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_f); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_r[] = { + RTW89_DECL_RFK_WC(0x8074, 0x80000000), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0000001f), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_r); + +static const struct rtw89_reg5_def rtw8852a_rfk_dpk_pas_read_defs[] = { + RTW89_DECL_RFK_WM(0x80d4, 0x00ff0000, 0x00000006), + RTW89_DECL_RFK_WC(0x80bc, 0x00004000), + RTW89_DECL_RFK_WM(0x80c0, 0x00ff0000, 0x00000008), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_dpk_pas_read_defs); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_nondbcc_path01[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), + RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), + RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), + RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), + RTW89_DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), + RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), + RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), + RTW89_DECL_RFK_WM(0x2344, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), + RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), + RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), + RTW89_DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), + RTW89_DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), + RTW89_DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_nondbcc_path01); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path0[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), + RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), + RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), + RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), + RTW89_DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), + RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), + RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), + RTW89_DECL_RFK_WM(0x2320, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), + RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), + RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), + RTW89_DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path0); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path1[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), + RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), + RTW89_DECL_RFK_WM(0x32b8, 0x10000000, 0x00000001), + RTW89_DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), + RTW89_DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000001), + RTW89_DECL_RFK_WM(0x2700, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), + RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), + RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), + RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), + RTW89_DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000001), + RTW89_DECL_RFK_WM(0x6490, 0x80000000, 0x00000001), + RTW89_DECL_RFK_WM(0x32a0, 0x00007000, 0x00000007), + RTW89_DECL_RFK_WM(0x32a0, 0x00008000, 0x00000001), + RTW89_DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), + RTW89_DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), + RTW89_DECL_RFK_WM(0x2700, 0x01000000, 0x00000001), + RTW89_DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), + RTW89_DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path1); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_nondbcc_path01[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), + RTW89_DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x2320, 0x00000001, 0x00000000), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_nondbcc_path01); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path0[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), + RTW89_DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path0); + +static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path1[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), + RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000000), + RTW89_DECL_RFK_WM(0x2700, 0x08000000, 0x00000000), + RTW89_DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), + RTW89_DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), + RTW89_DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), + RTW89_DECL_RFK_WM(0x2700, 0x07000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), + RTW89_DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000000), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), + RTW89_DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path1); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h new file mode 100644 index 000000000..33e6c404e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852A_RFK_TABLE_H__ +#define __RTW89_8852A_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_1_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_3_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_4_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_1_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_3_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_4_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_ab_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_disable_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_tssi_tracking_defs_tbl; + +extern const struct rtw89_rfk_tbl rtw8852a_rfk_afe_init_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_pas_read_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; +extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c new file mode 100644 index 000000000..f1bcef64a --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c @@ -0,0 +1,51012 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852a_table.h" + +static const struct rtw89_reg2_def rtw89_8852a_phy_bb_regs[] = { + {0xF0FF0001, 0x00000000}, + {0xF03300FF, 0x00000001}, + {0xF03500FF, 0x00000002}, + {0xF03200FF, 0x00000003}, + {0xF03400FF, 0x00000004}, + {0xF03600FF, 0x00000005}, + {0x704, 0x601E0100}, + {0x714, 0x00000000}, + {0x718, 0x13332333}, + {0x714, 0x00010000}, + {0x720, 0x20000000}, + {0x980, 0x10002250}, + {0x994, 0x00000010}, + {0x644, 0x2314283C}, + {0x644, 0x3426283C}, + {0x994, 0x00000010}, + {0xC3C, 0x2840E1BF}, + {0xC40, 0x00000000}, + {0xC44, 0x00000007}, + {0xC48, 0x410E4000}, + {0xC54, 0x1001436E}, + {0xC58, 0x41000000}, + {0x730, 0x00000002}, + {0xC60, 0x017FFFF2}, + {0xC64, 0x0010A130}, + {0xC64, 0x0010A130}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x10000068}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x90000068}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x90000068}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x10000068}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x90000068}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0xC68, 0x90000068}, + {0xA0000000, 0x00000000}, + {0xC68, 0x10000068}, + {0xB0000000, 0x00000000}, + {0xC64, 0x0010A130}, + {0xC54, 0x1EE1436E}, + {0xC6C, 0x00000020}, + {0x708, 0x00000000}, + {0xC6C, 0x00000020}, + {0x804, 0x0043F01D}, + {0x12D0, 0x00000000}, + {0x12EC, 0x888CA72B}, + {0x32D0, 0x00000000}, + {0x32EC, 0x888CA72B}, + {0xD40, 0xF64FA0F7}, + {0xD44, 0x0400063F}, + {0xD48, 0x0003FF7F}, + {0xD4C, 0x00000000}, + {0xD50, 0xF64FA0F7}, + {0xD54, 0x04100437}, + {0xD58, 0x0000FF7F}, + {0xD5C, 0x00000000}, + {0xD60, 0x00000000}, + {0xD64, 0x00000000}, + {0xD70, 0x0000001D}, + {0xD90, 0x000003FF}, + {0xD94, 0x00000000}, + {0xD98, 0x0000003F}, + {0xD9C, 0x00000000}, + {0xDA0, 0x000003FF}, + {0xDA4, 0x00000000}, + {0xDA8, 0x0000003F}, + {0xDAC, 0x00000000}, + {0xD00, 0x77777777}, + {0xD04, 0xBBBBBBBB}, + {0xD08, 0xBBBBBBBB}, + {0xD0C, 0x00000070}, + {0xD10, 0x20110900}, + {0xD10, 0x20110FFF}, + {0xD7C, 0x001D050C}, + {0xD84, 0x00006207}, + {0xD18, 0x50209900}, + {0xD80, 0x00804100}, + {0x714, 0x00010000}, + {0x704, 0x601E00FD}, + {0x710, 0xF3810000}, + {0x000, 0x0580801F}, + {0x000, 0x8580801F}, + {0x334, 0xFFFFFFFF}, + {0x33C, 0x55000000}, + {0x340, 0x00005555}, + {0x724, 0x00111200}, + {0x5868, 0xA9550000}, + {0x5870, 0x33221100}, + {0x5874, 0x77665544}, + {0x5878, 0xBBAA9988}, + {0x587C, 0xFFEEDDCC}, + {0x5880, 0x76543210}, + {0x5884, 0xFEDCBA98}, + {0x5888, 0x00000000}, + {0x588C, 0x00000000}, + {0x5894, 0x00000008}, + {0x7868, 0xA9550000}, + {0x7870, 0x33221100}, + {0x7874, 0x77665544}, + {0x7878, 0xBBAA9988}, + {0x787C, 0xFFEEDDCC}, + {0x7880, 0x76543210}, + {0x7884, 0xFEDCBA98}, + {0x7888, 0x00000000}, + {0x788C, 0x00000000}, + {0x7894, 0x00000008}, + {0x240C, 0x00000000}, + {0xC70, 0x00000400}, + {0x700, 0x00000030}, + {0x704, 0x601E00FF}, + {0x704, 0x601E00FD}, + {0x704, 0x601E00FF}, + {0x586C, 0x000000F0}, + {0x586C, 0x000000E0}, + {0x586C, 0x000000D0}, + {0x586C, 0x000000C0}, + {0x586C, 0x000000B0}, + {0x586C, 0x000000A0}, + {0x586C, 0x00000090}, + {0x586C, 0x00000080}, + {0x586C, 0x00000070}, + {0x586C, 0x00000060}, + {0x586C, 0x00000050}, + {0x586C, 0x00000040}, + {0x586C, 0x00000030}, + {0x586C, 0x00000020}, + {0x586C, 0x00000010}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x00000000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x03E00000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x03E00000}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x03E00000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x586C, 0x03E00000}, + {0xA0000000, 0x00000000}, + {0x586C, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x786C, 0x000000F0}, + {0x786C, 0x000000E0}, + {0x786C, 0x000000D0}, + {0x786C, 0x000000C0}, + {0x786C, 0x000000B0}, + {0x786C, 0x000000A0}, + {0x786C, 0x00000090}, + {0x786C, 0x00000080}, + {0x786C, 0x00000070}, + {0x786C, 0x00000060}, + {0x786C, 0x00000050}, + {0x786C, 0x00000040}, + {0x786C, 0x00000030}, + {0x786C, 0x00000020}, + {0x786C, 0x00000010}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x00000000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x03E00000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x03E00000}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x03E00000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x786C, 0x03E00000}, + {0xA0000000, 0x00000000}, + {0x786C, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x5864, 0x080801FF}, + {0x7864, 0x080801FF}, + {0xC60, 0x017FFFF3}, + {0xC6C, 0x00000021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0xC60, 0x017FFFF3}, + {0x2C60, 0x013FFF0A}, + {0xC70, 0x00000600}, + {0xC70, 0x00000660}, + {0xC6C, 0x10001021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x5864, 0x100801FF}, + {0x7864, 0x100801FF}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0x704, 0x601C01FF}, + {0x58D4, 0x0401FE00}, + {0x78D4, 0x0401FE00}, + {0x58F0, 0x000401FF}, + {0x78F0, 0x000401FF}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x12A8, 0x333378A5}, + {0x32A8, 0x333378A5}, + {0x2300, 0x02748790}, + {0x2304, 0x00558670}, + {0x2308, 0x002883F0}, + {0x230C, 0x00090120}, + {0x2310, 0x00000000}, + {0x2314, 0x06000000}, + {0x2318, 0x00000000}, + {0x231C, 0x00000000}, + {0x2320, 0x03020100}, + {0x2324, 0x07060504}, + {0x2328, 0x0B0A0908}, + {0x232C, 0x0F0E0D0C}, + {0x2330, 0x13121110}, + {0x2334, 0x17161514}, + {0x2338, 0x0C700022}, + {0x233C, 0x0A05298F}, + {0x2340, 0x0005298E}, + {0x2344, 0x0006318A}, + {0x2348, 0xB7E6318A}, + {0x234C, 0x80039CE7}, + {0x2350, 0x80039CE7}, + {0x2354, 0x0005298F}, + {0x2358, 0x0015296E}, + {0x235C, 0x0C07FC31}, + {0x2360, 0x0219A6AE}, + {0x2364, 0xE4F624C3}, + {0x2368, 0x53626F15}, + {0x236C, 0x48000000}, + {0x2370, 0x48000000}, + {0x2374, 0x074C0000}, + {0x2378, 0x202401B5}, + {0x237C, 0x00F7000E}, + {0x2380, 0x0F0A1111}, + {0x2384, 0x30D9000F}, + {0x2388, 0x0400EA02}, + {0x238C, 0x003CB061}, + {0x2390, 0x69C00000}, + {0x2394, 0x00000000}, + {0x2398, 0x000000F0}, + {0x239C, 0x0001FFFF}, + {0x23A0, 0x00C80064}, + {0x23A4, 0x0190012C}, + {0x23A8, 0x001917BE}, + {0x23AC, 0x0B308800}, + {0x23B0, 0x0001D5B0}, + {0x23B4, 0x000285D2}, + {0x23B8, 0x00000000}, + {0x23BC, 0x00000000}, + {0x23C0, 0x00000000}, + {0x23C4, 0x00000000}, + {0x23C8, 0x00000000}, + {0x23CC, 0x00000000}, + {0x23D0, 0x00000000}, + {0x23D4, 0x00000000}, + {0x23D8, 0x00000000}, + {0x23DC, 0x00000000}, + {0x23E0, 0x00000000}, + {0x23E4, 0x00000000}, + {0x23E8, 0x00000000}, + {0x23EC, 0x00000000}, + {0x23F0, 0x00000000}, + {0x23F4, 0x00000000}, + {0x23F8, 0x00000000}, + {0x23FC, 0x00000000}, + {0x804, 0x0043F01D}, + {0x300, 0xF30CE31C}, + {0x304, 0x13EF1F19}, + {0x308, 0x0C0CF3F3}, + {0x30C, 0x0C0C0C0C}, + {0x310, 0x80416000}, + {0x314, 0x0041E000}, + {0x318, 0x20022042}, + {0x31C, 0x20448001}, + {0x320, 0x00410040}, + {0x324, 0xE000E000}, + {0x328, 0xE000E000}, + {0x32C, 0xE000E000}, + {0x12BC, 0x10104041}, + {0x12C0, 0x14411111}, + {0x32BC, 0x10104041}, + {0x32C0, 0x14411111}, + {0x010, 0x0005FFFF}, + {0x604, 0x1E1E1E28}, + {0x650, 0x00200888}, + {0x620, 0x00141230}, + {0x35C, 0x000004C4}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04237040}, + {0x7804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7808, 0x04237040}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04231040}, + {0x7804, 0x04231040}, + {0x5808, 0x04231040}, + {0x7808, 0x04231040}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04231040}, + {0x7804, 0x04231040}, + {0x5808, 0x04231040}, + {0x7808, 0x04231040}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04237040}, + {0x7804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7808, 0x04237040}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04231040}, + {0x7804, 0x04231040}, + {0x5808, 0x04231040}, + {0x7808, 0x04231040}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5804, 0x04231040}, + {0x7804, 0x04231040}, + {0x5808, 0x04231040}, + {0x7808, 0x04231040}, + {0xA0000000, 0x00000000}, + {0x5804, 0x04237040}, + {0x7804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7808, 0x04237040}, + {0xB0000000, 0x00000000}, + {0x12A0, 0x24903156}, + {0x32A0, 0x24903156}, + {0x640, 0x1414141E}, + {0x12B8, 0x30020000}, + {0x12AC, 0x02333121}, + {0x9A4, 0x0000001C}, + {0x624, 0x01010301}, + {0x628, 0x00010101}, + {0x5800, 0x03FF807F}, + {0x7800, 0x03FF807F}, + {0x4000, 0x00000000}, + {0x4004, 0xCA014000}, + {0x4008, 0xC751D4F0}, + {0x400C, 0x44511475}, + {0x4010, 0x00000000}, + {0x4014, 0x00000000}, + {0x4018, 0x4F4C084B}, + {0x401C, 0x084A4E52}, + {0x4020, 0x4D504E4B}, + {0x4024, 0x4F4C0849}, + {0x4028, 0x08484C50}, + {0x402C, 0x4C50504C}, + {0x4030, 0x5454084A}, + {0x4034, 0x084B5654}, + {0x4038, 0x6A6C605A}, + {0x403C, 0x4C4C084C}, + {0x4040, 0x084B4E4D}, + {0x4044, 0x4E4C4B4B}, + {0x4048, 0x4B4B084A}, + {0x404C, 0x084A4E4C}, + {0x4050, 0x514F4C4A}, + {0x4054, 0x524E084A}, + {0x4058, 0x084A5154}, + {0x405C, 0x53555554}, + {0x4060, 0x45450845}, + {0x4064, 0x08454144}, + {0x4068, 0x40434445}, + {0x406C, 0x44450845}, + {0x4070, 0x08444043}, + {0x4074, 0x42434444}, + {0x4078, 0x46450844}, + {0x407C, 0x08444843}, + {0x4080, 0x4B4E4A47}, + {0x4084, 0x4F4C084B}, + {0x4088, 0x084A4E52}, + {0x408C, 0x4D504E4B}, + {0x4090, 0x4F4C0849}, + {0x4094, 0x08484C50}, + {0x4098, 0x4C50504C}, + {0x409C, 0x5454084A}, + {0x40A0, 0x084B5654}, + {0x40A4, 0x6A6C605A}, + {0x40A8, 0x4C4C084C}, + {0x40AC, 0x084B4E4D}, + {0x40B0, 0x4E4C4B4B}, + {0x40B4, 0x4B4B084A}, + {0x40B8, 0x084A4E4C}, + {0x40BC, 0x514F4C4A}, + {0x40C0, 0x524E084A}, + {0x40C4, 0x084A5154}, + {0x40C8, 0x53555554}, + {0x40CC, 0x45450845}, + {0x40D0, 0x08454144}, + {0x40D4, 0x40434445}, + {0x40D8, 0x44450845}, + {0x40DC, 0x08444043}, + {0x40E0, 0x42434444}, + {0x40E4, 0x46450844}, + {0x40E8, 0x08444843}, + {0x40EC, 0x4B4E4A47}, + {0x40F0, 0x00000000}, + {0x40F4, 0x00000006}, + {0x40F8, 0x00000001}, + {0x40FC, 0x8C30C30C}, + {0x4100, 0x4C30C30C}, + {0x4104, 0x0C30C30C}, + {0x4108, 0x0C30C30C}, + {0x410C, 0x0C30C30C}, + {0x4110, 0x0C30C30C}, + {0x4114, 0x28A28A28}, + {0x4118, 0x28A28A28}, + {0x411C, 0x28A28A28}, + {0x4120, 0x28A28A28}, + {0x4124, 0x28A28A28}, + {0x4128, 0x28A28A28}, + {0x412C, 0x06666666}, + {0x4130, 0x33333333}, + {0x4134, 0x33333333}, + {0x4138, 0x33333333}, + {0x413C, 0x00000031}, + {0x4140, 0x5100600A}, + {0x4144, 0x18363113}, + {0x4148, 0x1D976DDC}, + {0x414C, 0x1C072DD7}, + {0x4150, 0x1127CDF4}, + {0x4154, 0x1E37BDF1}, + {0x4158, 0x1FB7F1D6}, + {0x415C, 0x1EA7DDF9}, + {0x4160, 0x1FE445DD}, + {0x4164, 0x1F97F1FE}, + {0x4168, 0x1FF781ED}, + {0x416C, 0x1FA7F5FE}, + {0x4170, 0x1E07B913}, + {0x4174, 0x1FD7FDFF}, + {0x4178, 0x1E17B9FA}, + {0x417C, 0x19A66914}, + {0x4180, 0x10F65598}, + {0x4184, 0x14A5A111}, + {0x4188, 0x1D3765DB}, + {0x418C, 0x17C685CA}, + {0x4190, 0x1107C5F3}, + {0x4194, 0x1B5785EB}, + {0x4198, 0x1F97ED8F}, + {0x419C, 0x1BC7A5F3}, + {0x41A0, 0x1FE43595}, + {0x41A4, 0x1EB7D9FC}, + {0x41A8, 0x1FE65DBE}, + {0x41AC, 0x1EC7D9FC}, + {0x41B0, 0x1976FCFF}, + {0x41B4, 0x1F77F5FF}, + {0x41B8, 0x1976FDEC}, + {0x41BC, 0x198664EF}, + {0x41C0, 0x11062D93}, + {0x41C4, 0x10C4E910}, + {0x41C8, 0x1CA759DB}, + {0x41CC, 0x1335A9B5}, + {0x41D0, 0x1097B9F3}, + {0x41D4, 0x17B72DE1}, + {0x41D8, 0x1F67ED42}, + {0x41DC, 0x18074DE9}, + {0x41E0, 0x1FD40547}, + {0x41E4, 0x1D57ADF9}, + {0x41E8, 0x1FE52182}, + {0x41EC, 0x1D67B1F9}, + {0x41F0, 0x14860CE1}, + {0x41F4, 0x1EC7E9FE}, + {0x41F8, 0x14860DD6}, + {0x41FC, 0x195664C7}, + {0x4200, 0x0005E58A}, + {0x4204, 0x00000000}, + {0x4208, 0x00000000}, + {0x420C, 0x7A000000}, + {0x4210, 0x0F9F3D7A}, + {0x4214, 0x0040817C}, + {0x4218, 0x00E10204}, + {0x421C, 0x227D94CD}, + {0x4220, 0x080238E3}, + {0x4224, 0x00000210}, + {0x4228, 0x04688000}, + {0x422C, 0x0060B002}, + {0x4230, 0x9A8249A8}, + {0x4234, 0x26A1469E}, + {0x4238, 0x2099A824}, + {0x423C, 0x2359461C}, + {0x4240, 0x1631A675}, + {0x4244, 0x2C6B1D63}, + {0x4248, 0x0000000E}, + {0x424C, 0x00000001}, + {0x4250, 0x00000001}, + {0x4254, 0x00000000}, + {0x4258, 0x00000000}, + {0x425C, 0x00000000}, + {0x4260, 0x0020000C}, + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, + {0x4270, 0x00D6135C}, + {0x4274, 0x00000000}, + {0x4278, 0x00000000}, + {0x427C, 0x00000000}, + {0x4280, 0x00000000}, + {0x4284, 0x00000000}, + {0x4288, 0x00000000}, + {0x428C, 0x00000000}, + {0x4290, 0x00000000}, + {0x4294, 0x00000000}, + {0x4298, 0x84026000}, + {0x429C, 0x0051AC20}, + {0x42A0, 0x02024008}, + {0x42A4, 0x00000000}, + {0x42A8, 0x00000000}, + {0x42AC, 0x22CE803C}, + {0x42B0, 0x80000000}, + {0x42B4, 0x00E7D03D}, + {0x42B8, 0x3D67D67D}, + {0x42BC, 0x7D67D65B}, + {0x42C0, 0x2802AF59}, + {0x42C4, 0x00280280}, + {0x42C8, 0x00000000}, + {0x42CC, 0x00000000}, + {0x42D0, 0x00000003}, + {0x42D4, 0x00000001}, + {0x42D8, 0x61861800}, + {0x42DC, 0x830C30C3}, + {0x42E0, 0xC30C30C3}, + {0x42E4, 0x830C30C3}, + {0x42E8, 0x451450C3}, + {0x42EC, 0x05145145}, + {0x42F0, 0x05145145}, + {0x42F4, 0x05145145}, + {0x42F8, 0x0F0C3145}, + {0x42FC, 0x030C30CF}, + {0x4300, 0x030C30C3}, + {0x4304, 0x030CF3C3}, + {0x4308, 0x030C30C3}, + {0x430C, 0x0F3CF3C3}, + {0x4310, 0x0F3CF3CF}, + {0x4314, 0x0F3CF3CF}, + {0x4318, 0x0F3CF3CF}, + {0x431C, 0x0F3CF3CF}, + {0x4320, 0x030C10C3}, + {0x4324, 0x051430C3}, + {0x4328, 0x051490CB}, + {0x432C, 0x030CD151}, + {0x4330, 0x050C50C7}, + {0x4334, 0x051492CB}, + {0x4338, 0x05145145}, + {0x433C, 0x05145145}, + {0x4340, 0x05145145}, + {0x4344, 0x05145145}, + {0x4348, 0x090CD3CF}, + {0x434C, 0x071491C5}, + {0x4350, 0x073CF143}, + {0x4354, 0x071431C3}, + {0x4358, 0x0F3CF1C5}, + {0x435C, 0x0F3CF3CF}, + {0x4360, 0x0F3CF3CF}, + {0x4364, 0x0F3CF3CF}, + {0x4368, 0x0F3CF3CF}, + {0x436C, 0x090C91CF}, + {0x4370, 0x11243143}, + {0x4374, 0x9777A777}, + {0x4378, 0xBB7BAC95}, + {0x437C, 0xB667B889}, + {0x4380, 0x7B9B8899}, + {0x4384, 0x7A5567C8}, + {0x4388, 0x2278CCCC}, + {0x438C, 0x7C222222}, + {0x4390, 0x0000069B}, + {0x4394, 0x001CCCCC}, + {0x4398, 0x00000000}, + {0x439C, 0x00000008}, + {0x49A4, 0x00000000}, + {0x43A0, 0x00000000}, + {0x43A4, 0x00000000}, + {0x43A8, 0x00000000}, + {0x43AC, 0x10000800}, + {0x43B0, 0x00401802}, + {0x43B4, 0x00061004}, + {0x43B8, 0x000024D8}, + {0x43BC, 0x00000000}, + {0x43C0, 0x10000020}, + {0x43C4, 0x20000200}, + {0x43C8, 0x00000000}, + {0x43CC, 0x04000000}, + {0x43D0, 0x44000100}, + {0x43D4, 0x60804060}, + {0x43D8, 0x44204210}, + {0x43DC, 0x82108082}, + {0x43E0, 0x82108402}, + {0x43E4, 0xC8082108}, + {0x43E8, 0xC8202084}, + {0x43EC, 0x44208208}, + {0x43F0, 0x84108204}, + {0x43F4, 0xD0108104}, + {0x43F8, 0xF8210108}, + {0x43FC, 0x6431E930}, + {0x4400, 0x02109468}, + {0x4404, 0x10C61C22}, + {0x4408, 0x02109469}, + {0x440C, 0x10C61C22}, + {0x4410, 0x00041049}, + {0x4414, 0x00000000}, + {0x4418, 0x00000000}, + {0x441C, 0x6C000000}, + {0x4420, 0xB0200020}, + {0x4424, 0x00001FF0}, + {0x4428, 0x00000000}, + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, + {0x4438, 0x65F962F8}, + {0x443C, 0x280668A0}, + {0x4440, 0x64100820}, + {0x4444, 0x4A146304}, + {0x4448, 0x0C59008F}, + {0x444C, 0x6E30498A}, + {0x4450, 0x656E371B}, + {0x4454, 0x00000F52}, + {0x4458, 0x00000000}, + {0x445C, 0x4801442E}, + {0x4460, 0x0041A0B8}, + {0x4464, 0x00000000}, + {0x4468, 0x00000000}, + {0x446C, 0x00000000}, + {0x4470, 0x00000000}, + {0x4474, 0x00000000}, + {0x4478, 0x00000000}, + {0x447C, 0x00000000}, + {0x4480, 0x2A0A6040}, + {0x4484, 0x0A0A6829}, + {0x4488, 0x00000004}, + {0x448C, 0x00000000}, + {0x4490, 0x80000000}, + {0x4494, 0x10000000}, + {0x4498, 0xA0000000}, + {0x449C, 0x0000001E}, + {0x44A0, 0x02B29397}, + {0x44A4, 0x00000400}, + {0x44A8, 0x00000001}, + {0x44AC, 0x00000000}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4EA20631}, + {0x4534, 0x000005C8}, + {0x4538, 0x000000FF}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x4060001A}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x20000000}, + {0x4570, 0x04800406}, + {0x4574, 0x00022270}, + {0x4578, 0x0002024B}, + {0x457C, 0x00200000}, + {0x4580, 0x00009B40}, + {0x4584, 0x00000000}, + {0x4588, 0x00000063}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x05000000}, + {0x4598, 0x00000001}, + {0x459C, 0x0003FE00}, + {0x45A0, 0x00000000}, + {0x45A4, 0x00000000}, + {0x45A8, 0xC00001C0}, + {0x45AC, 0x78028000}, + {0x45B0, 0x80000048}, + {0x45B4, 0x01C90800}, + {0x45B8, 0x00000002}, + {0x45BC, 0x06748790}, + {0x45C0, 0x80000000}, + {0x45C4, 0x00000000}, + {0x45C8, 0x00000000}, + {0x45CC, 0x00558670}, + {0x45D0, 0x002883F0}, + {0x45D4, 0x00090120}, + {0x45D8, 0x00000000}, + {0x45DC, 0xA3A6D3C4}, + {0x49A8, 0xAB27B126}, + {0x49AC, 0x00006778}, + {0x49FC, 0x000001B5}, + {0x49B0, 0x11110F0A}, + {0x49B4, 0x00000007}, + {0x49B8, 0x0000000A}, + {0x49BC, 0x0058BC3F}, + {0x49C0, 0x00000003}, + {0x49C4, 0x000003D9}, + {0x49C8, 0x002B1CB0}, + {0x4A00, 0x00000000}, + {0x49CC, 0x00000001}, + {0x49D0, 0x00000010}, + {0x49D4, 0x00000001}, + {0x49D8, 0x85298FBF}, + {0x49DC, 0x18A5296E}, + {0x49E0, 0x18C6298C}, + {0x49E4, 0x0A739CA7}, + {0x49E8, 0x001A50E7}, + {0x49EC, 0x00000001}, + {0x49F0, 0x00005924}, + {0x49F4, 0x0003AAA6}, + {0x49F8, 0x0000C4C3}, + {0x45E0, 0x00000000}, + {0x45E4, 0x00000000}, + {0x45E8, 0x00E2E100}, + {0x45EC, 0xCB00B6B6}, + {0x45F0, 0x59100FCA}, + {0x45F4, 0x08882550}, + {0x45F8, 0x08CC2660}, + {0x45FC, 0x09102660}, + {0x4600, 0x00000154}, + {0x4604, 0x00000800}, + {0x4608, 0x31BF0400}, + {0x460C, 0x00E0C0A0}, + {0x4610, 0x30604020}, + {0x4614, 0x2F346D50}, + {0x4618, 0x2E36B6E2}, + {0x461C, 0x3E7EF86B}, + {0x4620, 0x001FC004}, + {0x4624, 0xA8068010}, + {0x4628, 0x4602CA80}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76067E8C}, + {0x4630, 0x8EA350E8}, + {0x4634, 0xB3B8D8F5}, + {0x4638, 0x6FFF0C06}, + {0x463C, 0xB8FA4435}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76078E8C}, + {0x4630, 0x8EDB50F6}, + {0x4634, 0xB5B8DD75}, + {0x4638, 0x6FFF4C06}, + {0x463C, 0xB8FA4434}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76078E8C}, + {0x4630, 0x8EDB50F6}, + {0x4634, 0xB5B8DD75}, + {0x4638, 0x6FFF4C06}, + {0x463C, 0xB8FA4434}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76067E8C}, + {0x4630, 0x8EA350E8}, + {0x4634, 0xB3B8D8F5}, + {0x4638, 0x6FFF0C06}, + {0x463C, 0xB8FA4435}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76078E8C}, + {0x4630, 0x8EDB50F6}, + {0x4634, 0xB5B8DD75}, + {0x4638, 0x6FFF4C06}, + {0x463C, 0xB8FA4434}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x462C, 0x76078E8C}, + {0x4630, 0x8EDB50F6}, + {0x4634, 0xB5B8DD75}, + {0x4638, 0x6FFF4C06}, + {0x463C, 0xB8FA4434}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0xA0000000, 0x00000000}, + {0x462C, 0x76067E8C}, + {0x4630, 0x8EA350E8}, + {0x4634, 0xB3B8D8F5}, + {0x4638, 0x6FFF0C06}, + {0x463C, 0xB8FA4435}, + {0x4640, 0xB7C4FEF8}, + {0x4644, 0x2A72AD07}, + {0xB0000000, 0x00000000}, + {0x4648, 0x64204FB2}, + {0x464C, 0x4C823404}, + {0x4650, 0x9084C800}, + {0x4654, 0x9889314F}, + {0x4658, 0x5ECC3FF4}, + {0x465C, 0xFEECAECE}, + {0x4660, 0x47806638}, + {0x4664, 0x0F5AF843}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x56452994}, + {0x466C, 0x54D89ADB}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x55452994}, + {0x466C, 0x56D89ADB}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x55452994}, + {0x466C, 0x56D89ADB}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x56452994}, + {0x466C, 0x54D89ADB}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x55452994}, + {0x466C, 0x56D89ADB}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4668, 0x55452994}, + {0x466C, 0x56D89ADB}, + {0xA0000000, 0x00000000}, + {0x4668, 0x56452994}, + {0x466C, 0x54D89ADB}, + {0xB0000000, 0x00000000}, + {0x4670, 0xE8DF38D8}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x002ACC30}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x0028CC30}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x0028CC30}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x002ACC30}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x0028CC30}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4674, 0x0028CC30}, + {0xA0000000, 0x00000000}, + {0x4674, 0x002ACC30}, + {0xB0000000, 0x00000000}, + {0x4678, 0x00000000}, + {0x467C, 0x00000000}, + {0x4680, 0x00000219}, + {0x4684, 0x00000000}, + {0x4688, 0x00000000}, + {0x468C, 0x00000001}, + {0x4690, 0x00000001}, + {0x4694, 0x00000000}, + {0x4698, 0x00000000}, + {0x469C, 0x00000151}, + {0x46A0, 0x00000498}, + {0x46A4, 0x00000498}, + {0x46A8, 0x00000000}, + {0x46AC, 0x00000000}, + {0x46B0, 0x00001146}, + {0x46B4, 0x00000000}, + {0x46B8, 0x00000000}, + {0x46BC, 0x00E2E100}, + {0x46C0, 0xCB00B6B6}, + {0x46C4, 0x59100FCA}, + {0x46C8, 0x08882550}, + {0x46CC, 0x08CC2660}, + {0x46D0, 0x09102660}, + {0x46D4, 0x00000154}, + {0x46D8, 0x00000800}, + {0x46DC, 0x31BF0400}, + {0x46E0, 0x00E0C0A0}, + {0x46E4, 0x30604020}, + {0x46E8, 0x4F346D50}, + {0x46EC, 0x2E36B6E2}, + {0x46F0, 0x3E7EF86B}, + {0x46F4, 0x001FC004}, + {0x46F8, 0xA8068010}, + {0x46FC, 0x4602CA80}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x7806FECC}, + {0x4704, 0x8EC360F1}, + {0x4708, 0xB4C4DA7A}, + {0x470C, 0x72FF2CC6}, + {0x4710, 0xB8FA4439}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x78078ECC}, + {0x4704, 0x8EDB60F6}, + {0x4708, 0xB5C4DD7A}, + {0x470C, 0x72FF4CC6}, + {0x4710, 0xB8FA4434}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x78078ECC}, + {0x4704, 0x8EDB60F6}, + {0x4708, 0xB5C4DD7A}, + {0x470C, 0x72FF4CC6}, + {0x4710, 0xB8FA4434}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x7806FECC}, + {0x4704, 0x8EC360F1}, + {0x4708, 0xB4C4DA7A}, + {0x470C, 0x72FF2CC6}, + {0x4710, 0xB8FA4439}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x78078ECC}, + {0x4704, 0x8EDB60F6}, + {0x4708, 0xB5C4DD7A}, + {0x470C, 0x72FF4CC6}, + {0x4710, 0xB8FA4434}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4700, 0x78078ECC}, + {0x4704, 0x8EDB60F6}, + {0x4708, 0xB5C4DD7A}, + {0x470C, 0x72FF4CC6}, + {0x4710, 0xB8FA4434}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0xA0000000, 0x00000000}, + {0x4700, 0x7806FECC}, + {0x4704, 0x8EC360F1}, + {0x4708, 0xB4C4DA7A}, + {0x470C, 0x72FF2CC6}, + {0x4710, 0xB8FA4439}, + {0x4714, 0xB7C4FEF8}, + {0x4718, 0x2A72AD09}, + {0xB0000000, 0x00000000}, + {0x471C, 0x64204FB2}, + {0x4720, 0x4C823404}, + {0x4724, 0x9084C800}, + {0x4728, 0x9889314F}, + {0x472C, 0x5ECC3FF4}, + {0x4730, 0xFEECAECE}, + {0x4734, 0x47806638}, + {0x4738, 0x0F4A7843}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x56452994}, + {0x4740, 0x54D89ADB}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x55452994}, + {0x4740, 0x56D89ADB}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x55452994}, + {0x4740, 0x56D89ADB}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x56452994}, + {0x4740, 0x54D89ADB}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x55452994}, + {0x4740, 0x56D89ADB}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x473C, 0x55452994}, + {0x4740, 0x56D89ADB}, + {0xA0000000, 0x00000000}, + {0x473C, 0x56452994}, + {0x4740, 0x54D89ADB}, + {0xB0000000, 0x00000000}, + {0x4744, 0xE8DF38D8}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x002ACC30}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x0028CC30}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x0028CC30}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x002ACC30}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x0028CC30}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4748, 0x0028CC30}, + {0xA0000000, 0x00000000}, + {0x4748, 0x002ACC30}, + {0xB0000000, 0x00000000}, + {0x474C, 0x00000000}, + {0x4750, 0x00000000}, + {0x4754, 0x00000219}, + {0x4758, 0x00000000}, + {0x475C, 0x00000000}, + {0x4760, 0x00000001}, + {0x4764, 0x00000001}, + {0x4768, 0x00000000}, + {0x476C, 0x00000000}, + {0x4770, 0x00000151}, + {0x4774, 0x00000498}, + {0x4778, 0x00000498}, + {0x477C, 0x00000000}, + {0x4780, 0x00000000}, + {0x4784, 0x00001147}, + {0x4788, 0x00000000}, + {0x478C, 0xA32103FE}, + {0x4790, 0x320A7B28}, + {0x4794, 0xC6A7B14F}, + {0x4798, 0x000006D7}, + {0x479C, 0x009B902A}, + {0x47A0, 0x009B902A}, + {0x47A4, 0x98682C18}, + {0x47A8, 0x6308C4C1}, + {0x47AC, 0x6248C631}, + {0x47B0, 0x922A8253}, + {0x47B4, 0x00000005}, + {0x47B8, 0x00001759}, + {0x47BC, 0x4B802000}, + {0x47C0, 0x831408BE}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x47CC, 0xBBCCBBB3}, + {0x47D0, 0x57889989}, + {0x47D4, 0x00000F45}, + {0x47D8, 0x27039CE9}, + {0x47DC, 0x31413432}, + {0x47E0, 0x26058342}, + {0x47E4, 0x00000006}, + {0x47E8, 0x00000005}, + {0x47EC, 0x00000005}, + {0x47F0, 0xC7013016}, + {0x47F4, 0x84413016}, + {0x47F8, 0x84413016}, + {0x47FC, 0x8C413016}, + {0x4800, 0x8C40B028}, + {0x4804, 0x3140B028}, + {0x4808, 0x2940B028}, + {0x480C, 0x8440B028}, + {0x4810, 0x2318C610}, + {0x4814, 0x45334753}, + {0x4818, 0x236A6A88}, + {0x481C, 0x576DF814}, + {0x4820, 0xA08877AC}, + {0x4824, 0x0000087A}, + {0x4828, 0xBCEB4A14}, + {0x482C, 0x000A3A4A}, + {0x4830, 0xBCEB4A14}, + {0x4834, 0x000A3A4A}, + {0x4838, 0xBCBDBD85}, + {0x483C, 0x0CABB99A}, + {0x4840, 0x38384242}, + {0x4844, 0x8086102E}, + {0x4848, 0xCA24C82A}, + {0x484C, 0x00008A62}, + {0x4850, 0x00000008}, + {0x4854, 0x009B902A}, + {0x4858, 0x009B902A}, + {0x485C, 0x98682C18}, + {0x4860, 0x6308C4C1}, + {0x4864, 0x6248C631}, + {0x4868, 0x922A8253}, + {0x486C, 0x00000005}, + {0x4870, 0x00001759}, + {0x4874, 0x4B802000}, + {0x4878, 0x831408BE}, + {0x487C, 0x9898A8BB}, + {0x4880, 0x54535368}, + {0x4884, 0x999999B3}, + {0x4888, 0x35555589}, + {0x488C, 0x00000745}, + {0x4890, 0x27039CE9}, + {0x4894, 0x31413432}, + {0x4898, 0x26058342}, + {0x489C, 0x00000006}, + {0x48A0, 0x00000005}, + {0x48A4, 0x00000005}, + {0x48A8, 0xC7013016}, + {0x48AC, 0x84413016}, + {0x48B0, 0x84413016}, + {0x48B4, 0x8C413016}, + {0x48B8, 0x8C40B028}, + {0x48BC, 0x3140B028}, + {0x48C0, 0x2940B028}, + {0x48C4, 0x8440B028}, + {0x48C8, 0x2318C610}, + {0x48CC, 0x45334753}, + {0x48D0, 0x236A6A88}, + {0x48D4, 0x576DF814}, + {0x48D8, 0xA08877AC}, + {0x48DC, 0x0000007A}, + {0x48E0, 0xBCEB4A14}, + {0x48E4, 0x000A3A4A}, + {0x48E8, 0xBCEB4A14}, + {0x48EC, 0x000A3A4A}, + {0x48F0, 0x9A8A8A85}, + {0x48F4, 0x0CA3B99A}, + {0x48F8, 0x38384242}, + {0x48FC, 0x8086102E}, + {0x4900, 0xCA24C82A}, + {0x4904, 0x00008A62}, + {0x4908, 0x00000008}, + {0x490C, 0x80040000}, + {0x4910, 0x80040000}, + {0x4914, 0xFE800000}, + {0x4918, 0x834C0000}, + {0x491C, 0x00000000}, + {0x4920, 0x00000000}, + {0x4924, 0x00000000}, + {0x4928, 0x00000000}, + {0x492C, 0x00000000}, + {0x4930, 0x00000000}, + {0x4934, 0x40000000}, + {0x4938, 0x00000000}, + {0x493C, 0x00000000}, + {0x4940, 0x00000000}, + {0x4944, 0x00000000}, + {0x4948, 0x04065800}, + {0x494C, 0x32004080}, + {0x4950, 0x0E1E3E05}, + {0x4954, 0x0A163068}, + {0x4958, 0x00206040}, + {0x495C, 0x02020202}, + {0x4960, 0x00A16020}, + {0x4964, 0x031F4284}, + {0x4968, 0x00A10285}, + {0x496C, 0x00000005}, + {0x4970, 0x00000000}, + {0x4974, 0x800CD62D}, + {0x4978, 0x00000103}, + {0x497C, 0x00000000}, + {0x4980, 0x00000000}, + {0x4984, 0x00000000}, + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4990, 0x00000000}, + {0x4994, 0x00000000}, + {0x4998, 0x00000000}, + {0x499C, 0x00000000}, + {0x49A0, 0x00000000}, + {0x2404, 0x00000001}, + {0xC7C, 0x0000BFE0}, + {0x020, 0x0000F381}, + {0x024, 0x0000F381}, + {0x028, 0x0000F381}, + {0x02C, 0x0000F381}, + {0xD78, 0x00000005}, + {0x12CC, 0x00000CC1}, + {0x12D0, 0x00000000}, + {0x12D4, 0x00000000}, + {0x12D8, 0x00000040}, + {0x12DC, 0x4486888C}, + {0x12E0, 0xC43A10E1}, + {0x12E4, 0x30D52C68}, + {0x12E8, 0x02024128}, + {0x12EC, 0x888C272B}, + {0x12EC, 0x888CA72B}, + {0x32CC, 0x00000CC1}, + {0x32D0, 0x00000000}, + {0x32D4, 0x00000000}, + {0x32D8, 0x00000040}, + {0x32DC, 0x4486888C}, + {0x32E0, 0xC43A10E1}, + {0x32E4, 0x30D52C68}, + {0x32E8, 0x02024128}, + {0x32EC, 0x888C272B}, + {0x32EC, 0x888CA72B}, + {0x12AC, 0x12333121}, + {0x32AC, 0x12333121}, + {0x738, 0x004100CC}, + {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0x80001080}, + {0x7820, 0x80001080}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0xC0001080}, + {0x7820, 0xC0001080}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0xC0001080}, + {0x7820, 0xC0001080}, + {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0x80001080}, + {0x7820, 0x80001080}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0x80001080}, + {0x7820, 0x80001080}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5820, 0x80001080}, + {0x7820, 0x80001080}, + {0xA0000000, 0x00000000}, + {0x5820, 0x80001080}, + {0x7820, 0x80001080}, + {0xB0000000, 0x00000000}, + {0x2000, 0x18BBBF84}, + {0x0F0, 0x00000002}, + {0x0F4, 0x00000016}, + {0x0F8, 0x20201013}, +}; + +static const struct rtw89_reg2_def rtw89_8852a_phy_radioa_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0010001, 0x00000001}, + {0xF0020001, 0x00000002}, + {0xF0030001, 0x00000003}, + {0xF0250001, 0x00000004}, + {0xF0260001, 0x00000005}, + {0xF0320001, 0x00000006}, + {0xF0330001, 0x00000007}, + {0xF0340001, 0x00000008}, + {0xF0350001, 0x00000009}, + {0xF0360001, 0x0000000A}, + {0xF0010002, 0x0000000B}, + {0xF0020002, 0x0000000C}, + {0xF0030002, 0x0000000D}, + {0xF0250002, 0x0000000E}, + {0xF0260002, 0x0000000F}, + {0xF0320002, 0x00000010}, + {0xF0330002, 0x00000011}, + {0xF0340002, 0x00000012}, + {0xF0350002, 0x00000013}, + {0xF0360002, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x005, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x000, 0x00030000}, + {0x018, 0x00011124}, + {0x000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x055, 0x00080000}, + {0x056, 0x0008FFF0}, + {0x057, 0x0000C485}, + {0x058, 0x000A4164}, + {0x059, 0x00010000}, + {0x05A, 0x00060000}, + {0x05B, 0x0000A000}, + {0x05C, 0x00000000}, + {0x05D, 0x0001C013}, + {0x05E, 0x00000000}, + {0x05F, 0x00001FF0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0xA0000000, 0x00000000}, + {0x060, 0x00011000}, + {0xB0000000, 0x00000000}, + {0x061, 0x0009F338}, + {0x062, 0x0009233A}, + {0x063, 0x000D6002}, + {0x064, 0x000A0CB0}, + {0x065, 0x00030EFE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0xA0000000, 0x00000000}, + {0x066, 0x00020000}, + {0xB0000000, 0x00000000}, + {0x068, 0x00000000}, + {0x069, 0x00030F0A}, + {0x06A, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000AD6A4}, + {0x052, 0x00091345}, + {0x053, 0x00080081}, + {0x054, 0x0009BC24}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0xA0000000, 0x00000000}, + {0x051, 0x000AD6A4}, + {0x052, 0x00091345}, + {0x053, 0x00080081}, + {0x054, 0x0009BC24}, + {0xB0000000, 0x00000000}, + {0x0D3, 0x00000143}, + {0x043, 0x00005000}, + {0x0DD, 0x000003A0}, + {0x0B0, 0x000E6700}, + {0x0AF, 0x0001F82E}, + {0x0B2, 0x000210A7}, + {0x0B1, 0x00065FFF}, + {0x0BB, 0x000F7A00}, + {0x0B3, 0x00013F7A}, + {0x0D4, 0x0000000E}, + {0x0B7, 0x00001E0C}, + {0x0A0, 0x0000004F}, + {0x0B4, 0x0007C03E}, + {0x0B5, 0x0007E301}, + {0x0B6, 0x00080800}, + {0x0CA, 0x00002000}, + {0x0DD, 0x000003A0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x00080000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0xA0000000, 0x00000000}, + {0x0CC, 0x00080000}, + {0xB0000000, 0x00000000}, + {0x0A1, 0x0006F300}, + {0x0A2, 0x00080500}, + {0x0A3, 0x0008050B}, + {0x0A4, 0x0006DB12}, + {0x0A5, 0x00000000}, + {0x0A6, 0x00000000}, + {0x0A7, 0x00000000}, + {0x0A8, 0x00000000}, + {0x0A9, 0x00000000}, + {0x0AA, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x000B0000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0A5, 0x000B0000}, + {0xB0000000, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00008000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0ED, 0x00008000}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000000}, + {0x03E, 0x00008000}, + {0x03F, 0x000E1333}, + {0x033, 0x00000001}, + {0x03E, 0x00008000}, + {0x03F, 0x000E7333}, + {0x033, 0x00000002}, + {0x03E, 0x00008000}, + {0x03F, 0x000FA000}, + {0x033, 0x00000003}, + {0x03E, 0x00004000}, + {0x03F, 0x000FA400}, + {0x033, 0x00000004}, + {0x03E, 0x00004000}, + {0x03F, 0x000F5000}, + {0x033, 0x00000005}, + {0x03E, 0x00004001}, + {0x03F, 0x00029400}, + {0x033, 0x00000006}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x00041999}, + {0x033, 0x00000007}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x00034444}, + {0x033, 0x00000008}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x0004D555}, + {0x033, 0x00000009}, + {0x03E, 0x00005551}, + {0x03F, 0x00046AAA}, + {0x033, 0x0000000A}, + {0x03E, 0x00005551}, + {0x03F, 0x00046AAA}, + {0x033, 0x0000000B}, + {0x03E, 0x00005551}, + {0x03F, 0x0008C555}, + {0x033, 0x0000000C}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00081EB8}, + {0x033, 0x0000000D}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00071EB8}, + {0x033, 0x0000000E}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00090000}, + {0x033, 0x0000000F}, + {0x03E, 0x00006661}, + {0x03F, 0x00088000}, + {0x033, 0x00000010}, + {0x03E, 0x00006661}, + {0x03F, 0x00088000}, + {0x033, 0x00000011}, + {0x03E, 0x00006661}, + {0x03F, 0x000DB999}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00002000}, + {0x033, 0x00000002}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000006}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x0ED, 0x00000000}, + {0x018, 0x00001001}, + {0x002, 0x0000000D}, + {0x0EE, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0xA0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x08F, 0x000D0F7A}, + {0x08C, 0x00084584}, + {0x0EF, 0x00004000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000700}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000700}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000500}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000500}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000400}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008B00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00008B00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00002900}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000000}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000001}, + {0x03F, 0x000BECFC}, + {0x033, 0x00000002}, + {0x03F, 0x0003E4FC}, + {0x033, 0x00000003}, + {0x03F, 0x0001D0FC}, + {0x033, 0x00000004}, + {0x03F, 0x0001C3FC}, + {0x033, 0x00000005}, + {0x03F, 0x000103FC}, + {0x033, 0x00000006}, + {0x03F, 0x0000007C}, + {0x033, 0x00000007}, + {0x03F, 0x0000007C}, + {0x033, 0x00000008}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000009}, + {0x03F, 0x000BECFC}, + {0x033, 0x0000000A}, + {0x03F, 0x0003E4FC}, + {0x033, 0x0000000B}, + {0x03F, 0x0001D0FC}, + {0x033, 0x0000000C}, + {0x03F, 0x0001C3FC}, + {0x033, 0x0000000D}, + {0x03F, 0x000103FC}, + {0x033, 0x0000000E}, + {0x03F, 0x0000007C}, + {0x033, 0x0000000F}, + {0x03F, 0x0000007C}, + {0x033, 0x00000010}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000011}, + {0x03F, 0x000BECFC}, + {0x033, 0x00000012}, + {0x03F, 0x0003E4FC}, + {0x033, 0x00000013}, + {0x03F, 0x0001D0FC}, + {0x033, 0x00000014}, + {0x03F, 0x0001C3FC}, + {0x033, 0x00000015}, + {0x03F, 0x000103FC}, + {0x033, 0x00000016}, + {0x03F, 0x0000007C}, + {0x033, 0x00000017}, + {0x03F, 0x0000007C}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000000}, + {0x03F, 0x00003317}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03F, 0x00003317}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x03F, 0x00003317}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03F, 0x00003338}, + {0x033, 0x0000001A}, + {0x03F, 0x00003338}, + {0x033, 0x0000001B}, + {0x03F, 0x00003338}, + {0x033, 0x0000001C}, + {0x03F, 0x00003338}, + {0x033, 0x0000001D}, + {0x03F, 0x00003338}, + {0x033, 0x0000001E}, + {0x03F, 0x00003338}, + {0x033, 0x0000001F}, + {0x03F, 0x00003338}, + {0x033, 0x00000020}, + {0x03F, 0x00003338}, + {0x033, 0x00000021}, + {0x03F, 0x00003338}, + {0x033, 0x00000022}, + {0x03F, 0x00003338}, + {0x033, 0x00000023}, + {0x03F, 0x00003338}, + {0x033, 0x00000024}, + {0x03F, 0x00003338}, + {0x033, 0x00000025}, + {0x03F, 0x00003338}, + {0x033, 0x00000026}, + {0x03F, 0x00003338}, + {0x033, 0x00000027}, + {0x03F, 0x00003338}, + {0x033, 0x00000028}, + {0x03F, 0x00003338}, + {0x033, 0x00000029}, + {0x03F, 0x00003338}, + {0x033, 0x0000002A}, + {0x03F, 0x00003338}, + {0x033, 0x0000002B}, + {0x03F, 0x00003338}, + {0x033, 0x0000002C}, + {0x03F, 0x00003338}, + {0x033, 0x0000002D}, + {0x03F, 0x00003338}, + {0x033, 0x0000002E}, + {0x03F, 0x00003338}, + {0x033, 0x0000002F}, + {0x03F, 0x00003338}, + {0x033, 0x00000030}, + {0x03F, 0x00003338}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000001}, + {0x03F, 0x000004BA}, + {0x033, 0x00000002}, + {0x03F, 0x000004BA}, + {0x033, 0x00000003}, + {0x03F, 0x000004BA}, + {0x033, 0x00000004}, + {0x03F, 0x000004BA}, + {0x033, 0x00000005}, + {0x03F, 0x000004BA}, + {0x033, 0x00000006}, + {0x03F, 0x000004BA}, + {0x033, 0x00000007}, + {0x03F, 0x000004BA}, + {0x033, 0x00000008}, + {0x03F, 0x000004BA}, + {0x033, 0x00000009}, + {0x03F, 0x000004BA}, + {0x033, 0x0000000A}, + {0x03F, 0x000004BA}, + {0x033, 0x0000000B}, + {0x03F, 0x000004BA}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000002}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000003}, + {0x03F, 0x00000870}, + {0x033, 0x00000004}, + {0x03F, 0x00000870}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000008}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000009}, + {0x03F, 0x00000870}, + {0x033, 0x0000000A}, + {0x03F, 0x00000870}, + {0x033, 0x0000000B}, + {0x03F, 0x00000430}, + {0x033, 0x0000000C}, + {0x03F, 0x00000430}, + {0x033, 0x0000000D}, + {0x03F, 0x00000000}, + {0x033, 0x0000000E}, + {0x03F, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F358}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F358}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00023458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00023858}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002E758}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002E658}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00027758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C758}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000E}, + {0x03F, 0x0002F658}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00002000}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000068}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000040}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000041}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000042}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000043}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000044}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000045}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000046}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000047}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000048}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000049}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000050}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000051}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000052}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000053}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000054}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000055}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000056}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000057}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000058}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000059}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000065}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00004000}, + {0x033, 0x00000000}, + {0x03F, 0x00003BEF}, + {0x033, 0x00000001}, + {0x03F, 0x00003BE9}, + {0x033, 0x00000002}, + {0x03F, 0x00003BE3}, + {0x033, 0x00000003}, + {0x03F, 0x00003BDD}, + {0x033, 0x00000004}, + {0x03F, 0x00003BD7}, + {0x033, 0x00000005}, + {0x03F, 0x00003BD1}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001BD9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000BD9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000859}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000859}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000819}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000819}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x03F, 0x000039EE}, + {0x033, 0x00000013}, + {0x03F, 0x000039E8}, + {0x033, 0x00000014}, + {0x03F, 0x000039E2}, + {0x033, 0x00000015}, + {0x03F, 0x000039DC}, + {0x033, 0x00000016}, + {0x03F, 0x000039D6}, + {0x033, 0x00000017}, + {0x03F, 0x000039D0}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03F, 0x000019D2}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x03F, 0x000009D2}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x03F, 0x000008D3}, + {0x033, 0x0000001E}, + {0x03F, 0x000008CD}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x03F, 0x0000084D}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x03F, 0x0000080D}, + {0x033, 0x00000023}, + {0x03F, 0x00000807}, + {0x033, 0x00000024}, + {0x03F, 0x000039EE}, + {0x033, 0x00000025}, + {0x03F, 0x000039E8}, + {0x033, 0x00000026}, + {0x03F, 0x000039E2}, + {0x033, 0x00000027}, + {0x03F, 0x000039DC}, + {0x033, 0x00000028}, + {0x03F, 0x000039D6}, + {0x033, 0x00000029}, + {0x03F, 0x000039D0}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x03F, 0x000019D2}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x03F, 0x000009D2}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x03F, 0x000008D3}, + {0x033, 0x00000030}, + {0x03F, 0x000008CD}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x03F, 0x0000084D}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x03F, 0x0000080D}, + {0x033, 0x00000035}, + {0x03F, 0x00000807}, + {0x033, 0x00000036}, + {0x03F, 0x000039EE}, + {0x033, 0x00000037}, + {0x03F, 0x000039E8}, + {0x033, 0x00000038}, + {0x03F, 0x000039E2}, + {0x033, 0x00000039}, + {0x03F, 0x000039DC}, + {0x033, 0x0000003A}, + {0x03F, 0x000039D6}, + {0x033, 0x0000003B}, + {0x03F, 0x000039D0}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x03F, 0x000019D2}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x03F, 0x000009D2}, + {0x033, 0x00000040}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000041}, + {0x03F, 0x000008D3}, + {0x033, 0x00000042}, + {0x03F, 0x000008CD}, + {0x033, 0x00000043}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000044}, + {0x03F, 0x0000084D}, + {0x033, 0x00000045}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000046}, + {0x03F, 0x0000080D}, + {0x033, 0x00000047}, + {0x03F, 0x00000807}, + {0x033, 0x00000048}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000049}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000050}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000051}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000052}, + {0x03F, 0x000009CD}, + {0x033, 0x00000053}, + {0x03F, 0x000008D3}, + {0x033, 0x00000054}, + {0x03F, 0x000008CD}, + {0x033, 0x00000055}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000056}, + {0x03F, 0x0000084D}, + {0x033, 0x00000057}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000058}, + {0x03F, 0x0000080D}, + {0x033, 0x00000059}, + {0x03F, 0x00000807}, + {0x033, 0x0000005A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x03F, 0x000009CD}, + {0x033, 0x00000065}, + {0x03F, 0x000008D3}, + {0x033, 0x00000066}, + {0x03F, 0x000008CD}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x03F, 0x0000084D}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x03F, 0x0000080D}, + {0x033, 0x0000006B}, + {0x03F, 0x00000807}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x03F, 0x000009CD}, + {0x033, 0x00000077}, + {0x03F, 0x000008D3}, + {0x033, 0x00000078}, + {0x03F, 0x000008CD}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x03F, 0x0000084D}, + {0x033, 0x0000007B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x03F, 0x0000080D}, + {0x033, 0x0000007D}, + {0x03F, 0x00000807}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000088}, + {0x03F, 0x000009CD}, + {0x033, 0x00000089}, + {0x03F, 0x000008D3}, + {0x033, 0x0000008A}, + {0x03F, 0x000008CD}, + {0x033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000008C}, + {0x03F, 0x0000084D}, + {0x033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000008E}, + {0x03F, 0x0000080D}, + {0x033, 0x0000008F}, + {0x03F, 0x00000807}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00080000}, + {0x033, 0x00000007}, + {0x03E, 0x00000001}, + {0x03F, 0x00020F3C}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00080000}, + {0x033, 0x0000000C}, + {0x03E, 0x00000001}, + {0x03F, 0x000305BC}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0EC, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x03C, 0x00000020}, + {0x03D, 0x00000078}, + {0x03E, 0x00080000}, + {0x03F, 0x00001999}, + {0x0EC, 0x00000000}, + {0x02F, 0x0002260D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0DE, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000002}, + {0x033, 0x00000000}, + {0x03F, 0x00000002}, + {0x033, 0x00000001}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001FF}, + {0x033, 0x00000003}, + {0x03F, 0x000001FF}, + {0x033, 0x00000004}, + {0x03F, 0x000001FF}, + {0x033, 0x00000005}, + {0x03F, 0x000001FF}, + {0x033, 0x00000006}, + {0x03F, 0x000001FF}, + {0x033, 0x00000007}, + {0x03F, 0x000001FF}, + {0x033, 0x00000008}, + {0x03F, 0x000001FF}, + {0x033, 0x00000009}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000A}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000B}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000C}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000D}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000E}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000F}, + {0x03F, 0x000001FF}, + {0x033, 0x00000010}, + {0x03F, 0x000001FF}, + {0x033, 0x00000011}, + {0x03F, 0x000001FF}, + {0x033, 0x00000012}, + {0x03F, 0x000001FF}, + {0x033, 0x00000013}, + {0x03F, 0x000001FF}, + {0x033, 0x00000014}, + {0x03F, 0x000001FF}, + {0x033, 0x00000015}, + {0x03F, 0x000001FF}, + {0x033, 0x00000016}, + {0x03F, 0x000001FF}, + {0x033, 0x00000017}, + {0x03F, 0x000001FF}, + {0x033, 0x00000018}, + {0x03F, 0x000001FF}, + {0x033, 0x00000019}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001A}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001B}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001C}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001D}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001E}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001F}, + {0x03F, 0x000001FF}, + {0x033, 0x00000020}, + {0x03F, 0x000001FF}, + {0x033, 0x00000021}, + {0x03F, 0x000001FF}, + {0x033, 0x00000022}, + {0x03F, 0x000001FF}, + {0x033, 0x00000023}, + {0x03F, 0x000001FF}, + {0x033, 0x00000024}, + {0x03F, 0x000001FF}, + {0x033, 0x00000025}, + {0x03F, 0x000001FF}, + {0x033, 0x00000026}, + {0x03F, 0x000001FF}, + {0x033, 0x00000027}, + {0x03F, 0x000001FF}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0xA0000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0xB0000000, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0xA0000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0xB0000000, 0x00000000}, + {0x06D, 0x00000C31}, + {0x0EF, 0x00020000}, + {0x033, 0x00000000}, + {0x03F, 0x000005FF}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x0EF, 0x00080000}, + {0x033, 0x00000001}, + {0x03E, 0x00000001}, + {0x03F, 0x00022020}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0xA0000000, 0x00000000}, + {0x087, 0x00000427}, + {0xB0000000, 0x00000000}, + {0x002, 0x00000000}, + {0x067, 0x00000056}, +}; + +static const struct rtw89_reg2_def rtw89_8852a_phy_radiob_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0010001, 0x00000001}, + {0xF0020001, 0x00000002}, + {0xF0030001, 0x00000003}, + {0xF0250001, 0x00000004}, + {0xF0260001, 0x00000005}, + {0xF0320001, 0x00000006}, + {0xF0330001, 0x00000007}, + {0xF0340001, 0x00000008}, + {0xF0350001, 0x00000009}, + {0xF0360001, 0x0000000A}, + {0xF0010002, 0x0000000B}, + {0xF0020002, 0x0000000C}, + {0xF0030002, 0x0000000D}, + {0xF0250002, 0x0000000E}, + {0xF0260002, 0x0000000F}, + {0xF0320002, 0x00000010}, + {0xF0330002, 0x00000011}, + {0xF0340002, 0x00000012}, + {0xF0350002, 0x00000013}, + {0xF0360002, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x005, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x005, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x000, 0x00030000}, + {0x018, 0x00011124}, + {0x000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x055, 0x00080000}, + {0x056, 0x0008FFF0}, + {0x057, 0x0000C485}, + {0x058, 0x000A4164}, + {0x059, 0x00010000}, + {0x05A, 0x00060000}, + {0x05B, 0x0000A000}, + {0x05C, 0x00000000}, + {0x05D, 0x0001C013}, + {0x05E, 0x00000000}, + {0x05F, 0x00001FF0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x060, 0x00011008}, + {0xA0000000, 0x00000000}, + {0x060, 0x00011000}, + {0xB0000000, 0x00000000}, + {0x061, 0x0009F338}, + {0x062, 0x0009233A}, + {0x063, 0x000D6002}, + {0x064, 0x000A0CB0}, + {0x065, 0x00030EFE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00010000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x066, 0x00020000}, + {0xA0000000, 0x00000000}, + {0x066, 0x00010000}, + {0xB0000000, 0x00000000}, + {0x068, 0x00000000}, + {0x069, 0x00030F0A}, + {0x06A, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000AD6A4}, + {0x052, 0x00091345}, + {0x053, 0x00080081}, + {0x054, 0x0007BC24}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x051, 0x000BD267}, + {0x052, 0x00091345}, + {0x053, 0x000B0081}, + {0x054, 0x0007BCA4}, + {0xA0000000, 0x00000000}, + {0x051, 0x000AD6A4}, + {0x052, 0x00091345}, + {0x053, 0x00080081}, + {0x054, 0x0007BC24}, + {0xB0000000, 0x00000000}, + {0x0D3, 0x00000143}, + {0x043, 0x00005000}, + {0x0DD, 0x000003A0}, + {0x0B0, 0x000E6700}, + {0x0AF, 0x0001F82E}, + {0x0B2, 0x000210A7}, + {0x0B1, 0x00065FFF}, + {0x0BB, 0x000F7A00}, + {0x0B3, 0x00013F7A}, + {0x0D4, 0x0000000E}, + {0x0B7, 0x00001E0C}, + {0x0A0, 0x0000004F}, + {0x0B4, 0x0007C03E}, + {0x0B5, 0x0007E301}, + {0x0B6, 0x00080800}, + {0x0CA, 0x00002000}, + {0x0DD, 0x000003A0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x00080000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0CC, 0x000E0000}, + {0xA0000000, 0x00000000}, + {0x0CC, 0x00080000}, + {0xB0000000, 0x00000000}, + {0x0A1, 0x0006F300}, + {0x0A2, 0x00080500}, + {0x0A3, 0x0008050B}, + {0x0A4, 0x0006DB12}, + {0x0A5, 0x00000000}, + {0x0A6, 0x00000000}, + {0x0A7, 0x00000000}, + {0x0A8, 0x00000000}, + {0x0A9, 0x00000000}, + {0x0AA, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x000B0000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0A5, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0A5, 0x000B0000}, + {0xB0000000, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00008000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0ED, 0x00008000}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000000}, + {0x03E, 0x00008000}, + {0x03F, 0x000E1333}, + {0x033, 0x00000001}, + {0x03E, 0x00008000}, + {0x03F, 0x000E7333}, + {0x033, 0x00000002}, + {0x03E, 0x00008000}, + {0x03F, 0x000FA000}, + {0x033, 0x00000003}, + {0x03E, 0x00004000}, + {0x03F, 0x000FA400}, + {0x033, 0x00000004}, + {0x03E, 0x00004000}, + {0x03F, 0x000F5000}, + {0x033, 0x00000005}, + {0x03E, 0x00004001}, + {0x03F, 0x00029400}, + {0x033, 0x00000006}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x00041999}, + {0x033, 0x00000007}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x00034444}, + {0x033, 0x00000008}, + {0x03E, 0x0000AAA1}, + {0x03F, 0x0004D555}, + {0x033, 0x00000009}, + {0x03E, 0x00005551}, + {0x03F, 0x00046AAA}, + {0x033, 0x0000000A}, + {0x03E, 0x00005551}, + {0x03F, 0x00046AAA}, + {0x033, 0x0000000B}, + {0x03E, 0x00005551}, + {0x03F, 0x0008C555}, + {0x033, 0x0000000C}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00081EB8}, + {0x033, 0x0000000D}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00071EB8}, + {0x033, 0x0000000E}, + {0x03E, 0x0000CCC1}, + {0x03F, 0x00090000}, + {0x033, 0x0000000F}, + {0x03E, 0x00006661}, + {0x03F, 0x00088000}, + {0x033, 0x00000010}, + {0x03E, 0x00006661}, + {0x03F, 0x00088000}, + {0x033, 0x00000011}, + {0x03E, 0x00006661}, + {0x03F, 0x000DB999}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00002000}, + {0x033, 0x00000002}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000006}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x0ED, 0x00000000}, + {0x018, 0x00001001}, + {0x002, 0x0000000D}, + {0x0EE, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000A}, + {0x033, 0x0000000C}, + {0x03F, 0x00000011}, + {0x033, 0x0000000D}, + {0x03F, 0x00000018}, + {0xA0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x08F, 0x000D0F7A}, + {0x08C, 0x00084584}, + {0x0EF, 0x00004000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000700}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000700}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004700}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000700}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000500}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000B0600}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00094600}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000500}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000400}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4500}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000400}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008B00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00038B00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000D4400}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00008B00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00014B00}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000B00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004A00}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001A00}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00002900}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004900}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00002900}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x033, 0x00000002}, + {0x03F, 0x00000015}, + {0x033, 0x00000003}, + {0x03F, 0x00000017}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000000}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000001}, + {0x03F, 0x000BECFC}, + {0x033, 0x00000002}, + {0x03F, 0x0003E4FC}, + {0x033, 0x00000003}, + {0x03F, 0x0001D0FC}, + {0x033, 0x00000004}, + {0x03F, 0x0001C3FC}, + {0x033, 0x00000005}, + {0x03F, 0x000103FC}, + {0x033, 0x00000006}, + {0x03F, 0x0000007C}, + {0x033, 0x00000007}, + {0x03F, 0x0000007C}, + {0x033, 0x00000008}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000009}, + {0x03F, 0x000BECFC}, + {0x033, 0x0000000A}, + {0x03F, 0x0003E4FC}, + {0x033, 0x0000000B}, + {0x03F, 0x0001D0FC}, + {0x033, 0x0000000C}, + {0x03F, 0x0001C3FC}, + {0x033, 0x0000000D}, + {0x03F, 0x000103FC}, + {0x033, 0x0000000E}, + {0x03F, 0x0000007C}, + {0x033, 0x0000000F}, + {0x03F, 0x0000007C}, + {0x033, 0x00000010}, + {0x03F, 0x000FECFC}, + {0x033, 0x00000011}, + {0x03F, 0x000BECFC}, + {0x033, 0x00000012}, + {0x03F, 0x0003E4FC}, + {0x033, 0x00000013}, + {0x03F, 0x0001D0FC}, + {0x033, 0x00000014}, + {0x03F, 0x0001C3FC}, + {0x033, 0x00000015}, + {0x03F, 0x000103FC}, + {0x033, 0x00000016}, + {0x03F, 0x0000007C}, + {0x033, 0x00000017}, + {0x03F, 0x0000007C}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000000}, + {0x03F, 0x00003317}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03F, 0x00003317}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x03F, 0x00003317}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003336}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003338}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003337}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003356}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03F, 0x00003338}, + {0x033, 0x0000001A}, + {0x03F, 0x00003338}, + {0x033, 0x0000001B}, + {0x03F, 0x00003338}, + {0x033, 0x0000001C}, + {0x03F, 0x00003338}, + {0x033, 0x0000001D}, + {0x03F, 0x00003338}, + {0x033, 0x0000001E}, + {0x03F, 0x00003338}, + {0x033, 0x0000001F}, + {0x03F, 0x00003338}, + {0x033, 0x00000020}, + {0x03F, 0x00003338}, + {0x033, 0x00000021}, + {0x03F, 0x00003338}, + {0x033, 0x00000022}, + {0x03F, 0x00003338}, + {0x033, 0x00000023}, + {0x03F, 0x00003338}, + {0x033, 0x00000024}, + {0x03F, 0x00003338}, + {0x033, 0x00000025}, + {0x03F, 0x00003338}, + {0x033, 0x00000026}, + {0x03F, 0x00003338}, + {0x033, 0x00000027}, + {0x03F, 0x00003338}, + {0x033, 0x00000028}, + {0x03F, 0x00003338}, + {0x033, 0x00000029}, + {0x03F, 0x00003338}, + {0x033, 0x0000002A}, + {0x03F, 0x00003338}, + {0x033, 0x0000002B}, + {0x03F, 0x00003338}, + {0x033, 0x0000002C}, + {0x03F, 0x00003338}, + {0x033, 0x0000002D}, + {0x03F, 0x00003338}, + {0x033, 0x0000002E}, + {0x03F, 0x00003338}, + {0x033, 0x0000002F}, + {0x03F, 0x00003338}, + {0x033, 0x00000030}, + {0x03F, 0x00003338}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000001}, + {0x03F, 0x000004BA}, + {0x033, 0x00000002}, + {0x03F, 0x000004BA}, + {0x033, 0x00000003}, + {0x03F, 0x000004BA}, + {0x033, 0x00000004}, + {0x03F, 0x000004BA}, + {0x033, 0x00000005}, + {0x03F, 0x000004BA}, + {0x033, 0x00000006}, + {0x03F, 0x000004BA}, + {0x033, 0x00000007}, + {0x03F, 0x000004BA}, + {0x033, 0x00000008}, + {0x03F, 0x000004BA}, + {0x033, 0x00000009}, + {0x03F, 0x000004BA}, + {0x033, 0x0000000A}, + {0x03F, 0x000004BA}, + {0x033, 0x0000000B}, + {0x03F, 0x000004BA}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000002}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000003}, + {0x03F, 0x00000870}, + {0x033, 0x00000004}, + {0x03F, 0x00000870}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000730}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000430}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000008}, + {0x03F, 0x00000CB0}, + {0x033, 0x00000009}, + {0x03F, 0x00000870}, + {0x033, 0x0000000A}, + {0x03F, 0x00000870}, + {0x033, 0x0000000B}, + {0x03F, 0x00000430}, + {0x033, 0x0000000C}, + {0x03F, 0x00000430}, + {0x033, 0x0000000D}, + {0x03F, 0x00000000}, + {0x033, 0x0000000E}, + {0x03F, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F258}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F258}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00036458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0003C458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026658}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00026458}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00028558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C358}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0002C558}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F358}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002F358}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F258}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023758}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00023558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00025558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x00024558}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000C}, + {0x03F, 0x0002C558}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xA0000000, 0x00000000}, + {0x03E, 0x0000000B}, + {0x03F, 0x0006F458}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00002000}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000166}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000163}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000068}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F5}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A5}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000053}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000070}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000067}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000064}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000061}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000058}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E5}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000055}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000E2}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000065}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000062}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000062}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000040}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000049}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000041}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000046}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000042}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000043}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000043}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000056}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000040}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000056}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000044}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000045}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000046}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000047}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000048}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000049}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000050}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000051}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000052}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000053}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000054}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000055}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000056}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000057}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000058}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000059}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000065}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000078}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000075}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000072}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001EA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001F0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E4}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001ED}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AC}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001AA}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000E0}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000006C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000069}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000069}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000066}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000066}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000063}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000060}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004E}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000057}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000004B}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000054}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005D}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000048}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000051}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00004000}, + {0x033, 0x00000000}, + {0x03F, 0x00003BEF}, + {0x033, 0x00000001}, + {0x03F, 0x00003BE9}, + {0x033, 0x00000002}, + {0x03F, 0x00003BE3}, + {0x033, 0x00000003}, + {0x03F, 0x00003BDD}, + {0x033, 0x00000004}, + {0x03F, 0x00003BD7}, + {0x033, 0x00000005}, + {0x03F, 0x00003BD1}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003BCB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001BD9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BD1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00001BD3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001BCD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000BD9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BD1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000BD3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000BCD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000859}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000857}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000859}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000851}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000819}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000084D}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000817}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000819}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000811}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x03F, 0x000039EE}, + {0x033, 0x00000013}, + {0x03F, 0x000039E8}, + {0x033, 0x00000014}, + {0x03F, 0x000039E2}, + {0x033, 0x00000015}, + {0x03F, 0x000039DC}, + {0x033, 0x00000016}, + {0x03F, 0x000039D6}, + {0x033, 0x00000017}, + {0x03F, 0x000039D0}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03F, 0x000019D2}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x03F, 0x000009D2}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x03F, 0x000008D3}, + {0x033, 0x0000001E}, + {0x03F, 0x000008CD}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x03F, 0x0000084D}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x03F, 0x0000080D}, + {0x033, 0x00000023}, + {0x03F, 0x00000807}, + {0x033, 0x00000024}, + {0x03F, 0x000039EE}, + {0x033, 0x00000025}, + {0x03F, 0x000039E8}, + {0x033, 0x00000026}, + {0x03F, 0x000039E2}, + {0x033, 0x00000027}, + {0x03F, 0x000039DC}, + {0x033, 0x00000028}, + {0x03F, 0x000039D6}, + {0x033, 0x00000029}, + {0x03F, 0x000039D0}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x03F, 0x000019D2}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x03F, 0x000009D2}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x03F, 0x000008D3}, + {0x033, 0x00000030}, + {0x03F, 0x000008CD}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x03F, 0x0000084D}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x03F, 0x0000080D}, + {0x033, 0x00000035}, + {0x03F, 0x00000807}, + {0x033, 0x00000036}, + {0x03F, 0x000039EE}, + {0x033, 0x00000037}, + {0x03F, 0x000039E8}, + {0x033, 0x00000038}, + {0x03F, 0x000039E2}, + {0x033, 0x00000039}, + {0x03F, 0x000039DC}, + {0x033, 0x0000003A}, + {0x03F, 0x000039D6}, + {0x033, 0x0000003B}, + {0x03F, 0x000039D0}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x03F, 0x000019D2}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x03F, 0x000009D2}, + {0x033, 0x00000040}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CC}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000008D9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000041}, + {0x03F, 0x000008D3}, + {0x033, 0x00000042}, + {0x03F, 0x000008CD}, + {0x033, 0x00000043}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000044}, + {0x03F, 0x0000084D}, + {0x033, 0x00000045}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000046}, + {0x03F, 0x0000080D}, + {0x033, 0x00000047}, + {0x03F, 0x00000807}, + {0x033, 0x00000048}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000049}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000004F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000050}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000051}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000052}, + {0x03F, 0x000009CD}, + {0x033, 0x00000053}, + {0x03F, 0x000008D3}, + {0x033, 0x00000054}, + {0x03F, 0x000008CD}, + {0x033, 0x00000055}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000056}, + {0x03F, 0x0000084D}, + {0x033, 0x00000057}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000058}, + {0x03F, 0x0000080D}, + {0x033, 0x00000059}, + {0x03F, 0x00000807}, + {0x033, 0x0000005A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000005F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x03F, 0x000009CD}, + {0x033, 0x00000065}, + {0x03F, 0x000008D3}, + {0x033, 0x00000066}, + {0x03F, 0x000008CD}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x03F, 0x0000084D}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x03F, 0x0000080D}, + {0x033, 0x0000006B}, + {0x03F, 0x00000807}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x03F, 0x000009CD}, + {0x033, 0x00000077}, + {0x03F, 0x000008D3}, + {0x033, 0x00000078}, + {0x03F, 0x000008CD}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x03F, 0x0000084D}, + {0x033, 0x0000007B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x03F, 0x0000080D}, + {0x033, 0x0000007D}, + {0x03F, 0x00000807}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EE}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039EF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E8}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E9}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039E3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039DD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D6}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D0}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039D1}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CA}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000039CB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CC}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000019CD}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D2}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000009D3}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000088}, + {0x03F, 0x000009CD}, + {0x033, 0x00000089}, + {0x03F, 0x000008D3}, + {0x033, 0x0000008A}, + {0x03F, 0x000008CD}, + {0x033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000008C7}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000853}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000008C}, + {0x03F, 0x0000084D}, + {0x033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000847}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000813}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000008E}, + {0x03F, 0x0000080D}, + {0x033, 0x0000008F}, + {0x03F, 0x00000807}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00080000}, + {0x033, 0x00000007}, + {0x03E, 0x00000001}, + {0x03F, 0x00020F3C}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00080000}, + {0x033, 0x0000000C}, + {0x03E, 0x00000001}, + {0x03F, 0x000305BC}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0EC, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x03C, 0x00000020}, + {0x03D, 0x00000078}, + {0x03E, 0x00080000}, + {0x03F, 0x00001999}, + {0x0EC, 0x00000000}, + {0x02F, 0x0002260D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000001}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x0DE, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0DE, 0x00000001}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000002}, + {0x033, 0x00000000}, + {0x03F, 0x00000002}, + {0x033, 0x00000001}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000017F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000013F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FA}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001FF}, + {0x033, 0x00000003}, + {0x03F, 0x000001FF}, + {0x033, 0x00000004}, + {0x03F, 0x000001FF}, + {0x033, 0x00000005}, + {0x03F, 0x000001FF}, + {0x033, 0x00000006}, + {0x03F, 0x000001FF}, + {0x033, 0x00000007}, + {0x03F, 0x000001FF}, + {0x033, 0x00000008}, + {0x03F, 0x000001FF}, + {0x033, 0x00000009}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000A}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000B}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000C}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000D}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000E}, + {0x03F, 0x000001FF}, + {0x033, 0x0000000F}, + {0x03F, 0x000001FF}, + {0x033, 0x00000010}, + {0x03F, 0x000001FF}, + {0x033, 0x00000011}, + {0x03F, 0x000001FF}, + {0x033, 0x00000012}, + {0x03F, 0x000001FF}, + {0x033, 0x00000013}, + {0x03F, 0x000001FF}, + {0x033, 0x00000014}, + {0x03F, 0x000001FF}, + {0x033, 0x00000015}, + {0x03F, 0x000001FF}, + {0x033, 0x00000016}, + {0x03F, 0x000001FF}, + {0x033, 0x00000017}, + {0x03F, 0x000001FF}, + {0x033, 0x00000018}, + {0x03F, 0x000001FF}, + {0x033, 0x00000019}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001A}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001B}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001C}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001D}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001E}, + {0x03F, 0x000001FF}, + {0x033, 0x0000001F}, + {0x03F, 0x000001FF}, + {0x033, 0x00000020}, + {0x03F, 0x000001FF}, + {0x033, 0x00000021}, + {0x03F, 0x000001FF}, + {0x033, 0x00000022}, + {0x03F, 0x000001FF}, + {0x033, 0x00000023}, + {0x03F, 0x000001FF}, + {0x033, 0x00000024}, + {0x03F, 0x000001FF}, + {0x033, 0x00000025}, + {0x03F, 0x000001FF}, + {0x033, 0x00000026}, + {0x03F, 0x000001FF}, + {0x033, 0x00000027}, + {0x03F, 0x000001FF}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FB}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001FF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003B}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003F}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000EB}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06E, 0x00067A7C}, + {0xA0000000, 0x00000000}, + {0x06E, 0x00077A7C}, + {0xB0000000, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x06F, 0x00067A7C}, + {0xA0000000, 0x00000000}, + {0x06F, 0x00077A7C}, + {0xB0000000, 0x00000000}, + {0x06D, 0x00000C31}, + {0x0EF, 0x00020000}, + {0x033, 0x00000000}, + {0x03F, 0x000005FF}, + {0x0EF, 0x00000000}, + {0x0A0, 0x00000043}, + {0x005, 0x00000001}, + {0x0EF, 0x00080000}, + {0x033, 0x00000001}, + {0x03E, 0x00000001}, + {0x03F, 0x00022020}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x00000427}, + {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, + {0x087, 0x0000042F}, + {0xA0000000, 0x00000000}, + {0x087, 0x00000427}, + {0xB0000000, 0x00000000}, + {0x002, 0x00000000}, + {0x067, 0x00000056}, +}; + +static const struct rtw89_reg2_def rtw89_8852a_phy_nctl_regs[] = { + {0x8000, 0x00000008}, + {0x8008, 0x00000000}, + {0x8004, 0xf0862966}, + {0x800c, 0x78000000}, + {0x8010, 0x88015000}, + {0x8014, 0x80010100}, + {0x8018, 0x10010100}, + {0x801c, 0xa210bc00}, + {0x8020, 0x000403e0}, + {0x8024, 0x00072160}, + {0x8028, 0x00180e00}, + {0x8030, 0x400000c0}, + {0x8034, 0x56000800}, + {0x8038, 0x00000009}, + {0x803c, 0x00000008}, + {0x8040, 0x00000046}, + {0x8044, 0x0010001f}, + {0x8048, 0xf0000003}, + {0x804c, 0x62ac6162}, + {0x8050, 0xf2acf162}, + {0x8054, 0x62ac6162}, + {0x8058, 0xf2acf162}, + {0x805c, 0x150c0b02}, + {0x8060, 0x150c0b02}, + {0x8064, 0x2aa00047}, + {0x8074, 0x80000000}, + {0x807c, 0x000000ee}, + {0x8088, 0x80000000}, + {0x8098, 0x0000ff00}, + {0x809c, 0x0000001f}, + {0x80a0, 0x00010300}, + {0x80b0, 0x00000000}, + {0x80d0, 0x00000000}, + {0x8114, 0x00000000}, + {0x8120, 0x10010000}, + {0x8124, 0x00000000}, + {0x812c, 0x0000c000}, + {0x8138, 0x40000002}, + {0x813c, 0x40000002}, + {0x8140, 0x00000000}, + {0x8144, 0x0b040b03}, + {0x8148, 0x0b040b04}, + {0x814c, 0x0b040b03}, + {0x8150, 0x00000000}, + {0x8158, 0xffffffff}, + {0x815c, 0xffffffff}, + {0x8160, 0xffffffff}, + {0x8164, 0xffffffff}, + {0x8168, 0xffffffff}, + {0x816c, 0x1fffffff}, + {0x81ac, 0x003f1a00}, + {0x81b0, 0x003f1a00}, + {0x81bc, 0x005b5b5b}, + {0x81c0, 0x005b5b5b}, + {0x81b4, 0x00600060}, + {0x81b8, 0x00600060}, + {0x81cc, 0x00000000}, + {0x81dc, 0x00000002}, + {0x8214, 0x00000000}, + {0x8220, 0x10010000}, + {0x8224, 0x00000000}, + {0x822c, 0x0000d000}, + {0x8238, 0x40000002}, + {0x823c, 0x40000002}, + {0x8240, 0x00000000}, + {0x8244, 0x0b040b03}, + {0x8248, 0x0b040b03}, + {0x824c, 0x0b030b03}, + {0x8250, 0x00000000}, + {0x8258, 0xffffffff}, + {0x825c, 0xffffffff}, + {0x8260, 0xffffffff}, + {0x8264, 0xffffffff}, + {0x8268, 0xffffffff}, + {0x826c, 0x1fffffff}, + {0x82ac, 0x003f1a00}, + {0x82b0, 0x003f1a00}, + {0x82bc, 0x005b5b5b}, + {0x82c0, 0x005b5b5b}, + {0x82b4, 0x00600060}, + {0x82b8, 0x00600060}, + {0x82cc, 0x00000000}, + {0x82dc, 0x00000002}, + {0x81d8, 0x00000001}, + {0x82d8, 0x00000001}, + {0x8d00, 0x00000000}, + {0x8d04, 0x00000000}, + {0x8d08, 0x00000000}, + {0x8d0c, 0x00000000}, + {0x8d10, 0x00000000}, + {0x8d14, 0x00000000}, + {0x8d18, 0x00000000}, + {0x8d1c, 0x00000000}, + {0x8d20, 0x00000000}, + {0x8d24, 0x00000000}, + {0x8d28, 0x00000000}, + {0x8d2c, 0x00000000}, + {0x8d30, 0x00000000}, + {0x8d34, 0x00000000}, + {0x8d38, 0x00000000}, + {0x8d3c, 0x00000000}, + {0x8d40, 0x00000000}, + {0x8d44, 0x00000000}, + {0x8d48, 0x00000000}, + {0x8d4c, 0x00000000}, + {0x8d50, 0x00000000}, + {0x8d54, 0x00000000}, + {0x8d58, 0x00000000}, + {0x8d5c, 0x00000000}, + {0x8d60, 0x00000000}, + {0x8d64, 0x00000000}, + {0x8d68, 0x00000000}, + {0x8d6c, 0x00000000}, + {0x8d70, 0x00000000}, + {0x8d74, 0x00000000}, + {0x8d78, 0x00000000}, + {0x8d7c, 0x00000000}, + {0x8d80, 0x00000000}, + {0x8d84, 0x00000000}, + {0x8d88, 0x00000000}, + {0x8d8c, 0x00000000}, + {0x8d90, 0x00000000}, + {0x8d94, 0x00000000}, + {0x8d98, 0x00000000}, + {0x8d9c, 0x00000000}, + {0x8da0, 0x00000000}, + {0x8da4, 0x00000000}, + {0x8da8, 0x00000000}, + {0x8dac, 0x00000000}, + {0x8db0, 0x00000000}, + {0x8db4, 0x00000000}, + {0x8db8, 0x00000000}, + {0x8dbc, 0x00000000}, + {0x8dc0, 0x00000000}, + {0x8dc4, 0x00000000}, + {0x8dc8, 0x00000000}, + {0x8dcc, 0x00000000}, + {0x8dd0, 0x00000000}, + {0x8dd4, 0x00000000}, + {0x8dd8, 0x00000000}, + {0x8ddc, 0x00000000}, + {0x8de0, 0x00000000}, + {0x8de4, 0x00000000}, + {0x8de8, 0x00000000}, + {0x8dec, 0x00000000}, + {0x8df0, 0x00000000}, + {0x8df4, 0x00000000}, + {0x8df8, 0x00000000}, + {0x8dfc, 0x00000000}, + {0x8e00, 0x00000000}, + {0x8e04, 0x00000000}, + {0x8e08, 0x00000000}, + {0x8e0c, 0x00000000}, + {0x8e10, 0x00000000}, + {0x8e14, 0x00000000}, + {0x8e18, 0x00000000}, + {0x8e1c, 0x00000000}, + {0x8e20, 0x00000000}, + {0x8e24, 0x00000000}, + {0x8e28, 0x00000000}, + {0x8e2c, 0x00000000}, + {0x8e30, 0x00000000}, + {0x8e34, 0x00000000}, + {0x8e38, 0x00000000}, + {0x8e3c, 0x00000000}, + {0x8e40, 0x00000000}, + {0x8e44, 0x00000000}, + {0x8e48, 0x00000000}, + {0x8e4c, 0x00000000}, + {0x8e50, 0x00000000}, + {0x8e54, 0x00000000}, + {0x8e58, 0x00000000}, + {0x8e5c, 0x00000000}, + {0x8e60, 0x00000000}, + {0x8e64, 0x00000000}, + {0x8e68, 0x00000000}, + {0x8e6c, 0x00000000}, + {0x8e70, 0x00000000}, + {0x8e74, 0x00000000}, + {0x8e78, 0x00000000}, + {0x8e7c, 0x00000000}, + {0x8e80, 0x00000000}, + {0x8e84, 0x00000000}, + {0x8e88, 0x00000000}, + {0x8e8c, 0x00000000}, + {0x8e90, 0x00000000}, + {0x8e94, 0x00000000}, + {0x8e98, 0x00000000}, + {0x8e9c, 0x00000000}, + {0x8ea0, 0x00000000}, + {0x8ea4, 0x00000000}, + {0x8ea8, 0x00000000}, + {0x8eac, 0x00000000}, + {0x8eb0, 0x00000000}, + {0x8eb4, 0x00000000}, + {0x8eb8, 0x00000000}, + {0x8ebc, 0x00000000}, + {0x8ec0, 0x00000000}, + {0x8ec4, 0x00000000}, + {0x8ec8, 0x00000000}, + {0x8ecc, 0x00000000}, + {0x8ed0, 0x00000000}, + {0x8ed4, 0x00000000}, + {0x8ed8, 0x00000000}, + {0x8edc, 0x00000000}, + {0x8ee0, 0x00000000}, + {0x8ee4, 0x00000000}, + {0x8ee8, 0x00000000}, + {0x8eec, 0x00000000}, + {0x8ef0, 0x00000000}, + {0x8ef4, 0x00000000}, + {0x8ef8, 0x00000000}, + {0x8efc, 0x00000000}, + {0x8f00, 0x00000000}, + {0x8f04, 0x00000000}, + {0x8f08, 0x00000000}, + {0x8f0c, 0x00000000}, + {0x8f10, 0x00000000}, + {0x8f14, 0x00000000}, + {0x8f18, 0x00000000}, + {0x8f1c, 0x00000000}, + {0x8f20, 0x00000000}, + {0x8f24, 0x00000000}, + {0x8f28, 0x00000000}, + {0x8f2c, 0x00000000}, + {0x8f30, 0x00000000}, + {0x8f34, 0x00000000}, + {0x8f38, 0x00000000}, + {0x8f3c, 0x00000000}, + {0x8f40, 0x00000000}, + {0x8f44, 0x00000000}, + {0x8f48, 0x00000000}, + {0x8f4c, 0x00000000}, + {0x8f50, 0x00000000}, + {0x8f54, 0x00000000}, + {0x8f58, 0x00000000}, + {0x8f5c, 0x00000000}, + {0x8f60, 0x00000000}, + {0x8f64, 0x00000000}, + {0x8f68, 0x00000000}, + {0x8f6c, 0x00000000}, + {0x8f70, 0x00000000}, + {0x8f74, 0x00000000}, + {0x8f78, 0x00000000}, + {0x8f7c, 0x00000000}, + {0x8f80, 0x00000000}, + {0x8f84, 0x00000000}, + {0x8f88, 0x00000000}, + {0x8f8c, 0x00000000}, + {0x8f90, 0x00000000}, + {0x8f94, 0x00000000}, + {0x8f98, 0x00000000}, + {0x8f9c, 0x00000000}, + {0x8fa0, 0x00000000}, + {0x8fa4, 0x00000000}, + {0x8fa8, 0x00000000}, + {0x8fac, 0x00000000}, + {0x8fb0, 0x00000000}, + {0x8fb4, 0x00000000}, + {0x8fb8, 0x00000000}, + {0x8fbc, 0x00000000}, + {0x8fc0, 0x00000000}, + {0x8fc4, 0x00000000}, + {0x8fc8, 0x00000000}, + {0x8fcc, 0x00000000}, + {0x8fd0, 0x00000000}, + {0x8fd4, 0x00000000}, + {0x8fd8, 0x00000000}, + {0x8fdc, 0x00000000}, + {0x8fe0, 0x00000000}, + {0x8fe4, 0x00000000}, + {0x8fe8, 0x00000000}, + {0x8fec, 0x00000000}, + {0x8ff0, 0x00000000}, + {0x8ff4, 0x00000000}, + {0x8ff8, 0x00000000}, + {0x8ffc, 0x00000000}, + {0x9000, 0x00000000}, + {0x9004, 0x00000000}, + {0x9008, 0x00000000}, + {0x900c, 0x00000000}, + {0x9010, 0x00000000}, + {0x9014, 0x00000000}, + {0x9018, 0x00000000}, + {0x901c, 0x00000000}, + {0x9020, 0x00000000}, + {0x9024, 0x00000000}, + {0x9028, 0x00000000}, + {0x902c, 0x00000000}, + {0x9030, 0x00000000}, + {0x9034, 0x00000000}, + {0x9038, 0x00000000}, + {0x903c, 0x00000000}, + {0x9040, 0x00000000}, + {0x9044, 0x00000000}, + {0x9048, 0x00000000}, + {0x904c, 0x00000000}, + {0x9050, 0x00000000}, + {0x9054, 0x00000000}, + {0x9058, 0x00000000}, + {0x905c, 0x00000000}, + {0x9060, 0x00000000}, + {0x9064, 0x00000000}, + {0x9068, 0x00000000}, + {0x906c, 0x00000000}, + {0x9070, 0x00000000}, + {0x9074, 0x00000000}, + {0x9078, 0x00000000}, + {0x907c, 0x00000000}, + {0x9080, 0x00000000}, + {0x9084, 0x00000000}, + {0x9088, 0x00000000}, + {0x908c, 0x00000000}, + {0x9090, 0x00000000}, + {0x9094, 0x00000000}, + {0x9098, 0x00000000}, + {0x909c, 0x00000000}, + {0x90a0, 0x00000000}, + {0x90a4, 0x00000000}, + {0x90a8, 0x00000000}, + {0x90ac, 0x00000000}, + {0x90b0, 0x00000000}, + {0x90b4, 0x00000000}, + {0x90b8, 0x00000000}, + {0x90bc, 0x00000000}, + {0x9100, 0x00000000}, + {0x9104, 0x00000000}, + {0x9108, 0x00000000}, + {0x910c, 0x00000000}, + {0x9110, 0x00000000}, + {0x9114, 0x00000000}, + {0x9118, 0x00000000}, + {0x911c, 0x00000000}, + {0x9120, 0x00000000}, + {0x9124, 0x00000000}, + {0x9128, 0x00000000}, + {0x912c, 0x00000000}, + {0x9130, 0x00000000}, + {0x9134, 0x00000000}, + {0x9138, 0x00000000}, + {0x913c, 0x00000000}, + {0x9140, 0x00000000}, + {0x9144, 0x00000000}, + {0x9148, 0x00000000}, + {0x914c, 0x00000000}, + {0x9150, 0x00000000}, + {0x9154, 0x00000000}, + {0x9158, 0x00000000}, + {0x915c, 0x00000000}, + {0x9160, 0x00000000}, + {0x9164, 0x00000000}, + {0x9168, 0x00000000}, + {0x916c, 0x00000000}, + {0x9170, 0x00000000}, + {0x9174, 0x00000000}, + {0x9178, 0x00000000}, + {0x917c, 0x00000000}, + {0x9180, 0x00000000}, + {0x9184, 0x00000000}, + {0x9188, 0x00000000}, + {0x918c, 0x00000000}, + {0x9190, 0x00000000}, + {0x9194, 0x00000000}, + {0x9198, 0x00000000}, + {0x919c, 0x00000000}, + {0x91a0, 0x00000000}, + {0x91a4, 0x00000000}, + {0x91a8, 0x00000000}, + {0x91ac, 0x00000000}, + {0x91b0, 0x00000000}, + {0x91b4, 0x00000000}, + {0x91b8, 0x00000000}, + {0x91bc, 0x00000000}, + {0x91c0, 0x00000000}, + {0x91c4, 0x00000000}, + {0x91c8, 0x00000000}, + {0x91cc, 0x00000000}, + {0x91d0, 0x00000000}, + {0x91d4, 0x00000000}, + {0x91d8, 0x00000000}, + {0x91dc, 0x00000000}, + {0x91e0, 0x00000000}, + {0x91e4, 0x00000000}, + {0x91e8, 0x00000000}, + {0x91ec, 0x00000000}, + {0x91f0, 0x00000000}, + {0x91f4, 0x00000000}, + {0x91f8, 0x00000000}, + {0x91fc, 0x00000000}, + {0x9200, 0x00000000}, + {0x9204, 0x00000000}, + {0x9208, 0x00000000}, + {0x920c, 0x00000000}, + {0x9210, 0x00000000}, + {0x9214, 0x00000000}, + {0x9218, 0x00000000}, + {0x921c, 0x00000000}, + {0x9220, 0x00000000}, + {0x9224, 0x00000000}, + {0x9228, 0x00000000}, + {0x922c, 0x00000000}, + {0x9230, 0x00000000}, + {0x9234, 0x00000000}, + {0x9238, 0x00000000}, + {0x923c, 0x00000000}, + {0x9240, 0x00000000}, + {0x9244, 0x00000000}, + {0x9248, 0x00000000}, + {0x924c, 0x00000000}, + {0x9250, 0x00000000}, + {0x9254, 0x00000000}, + {0x9258, 0x00000000}, + {0x925c, 0x00000000}, + {0x9260, 0x00000000}, + {0x9264, 0x00000000}, + {0x9268, 0x00000000}, + {0x926c, 0x00000000}, + {0x9270, 0x00000000}, + {0x9274, 0x00000000}, + {0x9278, 0x00000000}, + {0x927c, 0x00000000}, + {0x9280, 0x00000000}, + {0x9284, 0x00000000}, + {0x9288, 0x00000000}, + {0x928c, 0x00000000}, + {0x9290, 0x00000000}, + {0x9294, 0x00000000}, + {0x9298, 0x00000000}, + {0x929c, 0x00000000}, + {0x92a0, 0x00000000}, + {0x92a4, 0x00000000}, + {0x92a8, 0x00000000}, + {0x92ac, 0x00000000}, + {0x92b0, 0x00000000}, + {0x92b4, 0x00000000}, + {0x92b8, 0x00000000}, + {0x92bc, 0x00000000}, + {0x92c0, 0x00000000}, + {0x92c4, 0x00000000}, + {0x92c8, 0x00000000}, + {0x92cc, 0x00000000}, + {0x92d0, 0x00000000}, + {0x92d4, 0x00000000}, + {0x92d8, 0x00000000}, + {0x92dc, 0x00000000}, + {0x92e0, 0x00000000}, + {0x92e4, 0x00000000}, + {0x92e8, 0x00000000}, + {0x92ec, 0x00000000}, + {0x92f0, 0x00000000}, + {0x92f4, 0x00000000}, + {0x92f8, 0x00000000}, + {0x92fc, 0x00000000}, + {0x9300, 0x00000000}, + {0x9304, 0x00000000}, + {0x9308, 0x00000000}, + {0x930c, 0x00000000}, + {0x9310, 0x00000000}, + {0x9314, 0x00000000}, + {0x9318, 0x00000000}, + {0x931c, 0x00000000}, + {0x9320, 0x00000000}, + {0x9324, 0x00000000}, + {0x9328, 0x00000000}, + {0x932c, 0x00000000}, + {0x9330, 0x00000000}, + {0x9334, 0x00000000}, + {0x9338, 0x00000000}, + {0x933c, 0x00000000}, + {0x9340, 0x00000000}, + {0x9344, 0x00000000}, + {0x9348, 0x00000000}, + {0x934c, 0x00000000}, + {0x9350, 0x00000000}, + {0x9354, 0x00000000}, + {0x9358, 0x00000000}, + {0x935c, 0x00000000}, + {0x9360, 0x00000000}, + {0x9364, 0x00000000}, + {0x9368, 0x00000000}, + {0x936c, 0x00000000}, + {0x9370, 0x00000000}, + {0x9374, 0x00000000}, + {0x9378, 0x00000000}, + {0x937c, 0x00000000}, + {0x9380, 0x00000000}, + {0x9384, 0x00000000}, + {0x9388, 0x00000000}, + {0x938c, 0x00000000}, + {0x9390, 0x00000000}, + {0x9394, 0x00000000}, + {0x9398, 0x00000000}, + {0x939c, 0x00000000}, + {0x93a0, 0x00000000}, + {0x93a4, 0x00000000}, + {0x93a8, 0x00000000}, + {0x93ac, 0x00000000}, + {0x93b0, 0x00000000}, + {0x93b4, 0x00000000}, + {0x93b8, 0x00000000}, + {0x93bc, 0x00000000}, + {0x93c0, 0x00000000}, + {0x93c4, 0x00000000}, + {0x93c8, 0x00000000}, + {0x93cc, 0x00000000}, + {0x93d0, 0x00000000}, + {0x93d4, 0x00000000}, + {0x93d8, 0x00000000}, + {0x93dc, 0x00000000}, + {0x93e0, 0x00000000}, + {0x93e4, 0x00000000}, + {0x93e8, 0x00000000}, + {0x93ec, 0x00000000}, + {0x93f0, 0x00000000}, + {0x93f4, 0x00000000}, + {0x93f8, 0x00000000}, + {0x93fc, 0x00000000}, + {0x9400, 0x00000000}, + {0x9404, 0x00000000}, + {0x9408, 0x00000000}, + {0x940c, 0x00000000}, + {0x9410, 0x00000000}, + {0x9414, 0x00000000}, + {0x9418, 0x00000000}, + {0x941c, 0x00000000}, + {0x9420, 0x00000000}, + {0x9424, 0x00000000}, + {0x9428, 0x00000000}, + {0x942c, 0x00000000}, + {0x9430, 0x00000000}, + {0x9434, 0x00000000}, + {0x9438, 0x00000000}, + {0x943c, 0x00000000}, + {0x9440, 0x00000000}, + {0x9444, 0x00000000}, + {0x9448, 0x00000000}, + {0x944c, 0x00000000}, + {0x9450, 0x00000000}, + {0x9454, 0x00000000}, + {0x9458, 0x00000000}, + {0x945c, 0x00000000}, + {0x9460, 0x00000000}, + {0x9464, 0x00000000}, + {0x9468, 0x00000000}, + {0x946c, 0x00000000}, + {0x9470, 0x00000000}, + {0x9474, 0x00000000}, + {0x9478, 0x00000000}, + {0x947c, 0x00000000}, + {0x9480, 0x00000000}, + {0x9484, 0x00000000}, + {0x9488, 0x00000000}, + {0x948c, 0x00000000}, + {0x9490, 0x00000000}, + {0x9494, 0x00000000}, + {0x9498, 0x00000000}, + {0x949c, 0x00000000}, + {0x94a0, 0x00000000}, + {0x94a4, 0x00000000}, + {0x94a8, 0x00000000}, + {0x94ac, 0x00000000}, + {0x94b0, 0x00000000}, + {0x94b4, 0x00000000}, + {0x94b8, 0x00000000}, + {0x94bc, 0x00000000}, + {0x81d8, 0x00000000}, + {0x82d8, 0x00000000}, + {0x9f04, 0x2b251f19}, + {0x9f08, 0x433d3731}, + {0x9f0c, 0x5b554f49}, + {0x9f10, 0x736d6761}, + {0x9f14, 0x7f7f7f79}, + {0x9f18, 0x120f7f7f}, + {0x9f1c, 0x1e1b1815}, + {0x9f20, 0x2a272421}, + {0x9f24, 0x3633302d}, + {0x9f28, 0x3f3f3c39}, + {0x9f2c, 0x3f3f3f3f}, + {0x8088, 0x00000110}, + {0x8000, 0x00000008}, + {0x8080, 0x00000005}, + {0x8500, 0x00060009}, + {0x8504, 0x000418b0}, + {0x8508, 0x00089c00}, + {0x850c, 0x43000004}, + {0x8510, 0x4b044a00}, + {0x8514, 0x40098603}, + {0x8518, 0x4b05e01f}, + {0x851c, 0x400b8703}, + {0x8520, 0x4b00e01f}, + {0x8524, 0x43800004}, + {0x8528, 0x4c000007}, + {0x852c, 0x43000004}, + {0x8530, 0x57007430}, + {0x8534, 0x73000006}, + {0x8538, 0x50550004}, + {0x853c, 0xb4163000}, + {0x8540, 0xe37ea510}, + {0x8544, 0xf117f017}, + {0x8548, 0xf317f217}, + {0x854c, 0xf517f417}, + {0x8550, 0xf717f617}, + {0x8554, 0xf917f817}, + {0x8558, 0xfb17fa17}, + {0x855c, 0xfd17fc17}, + {0x8560, 0xf117f017}, + {0x8564, 0xf317f217}, + {0x8568, 0xa503f417}, + {0x856c, 0xf116f016}, + {0x8570, 0x304e0001}, + {0x8574, 0x30873053}, + {0x8578, 0x30ab30a8}, + {0x857c, 0x30b330ae}, + {0x8580, 0x30ba30b6}, + {0x8584, 0x30d430c7}, + {0x8588, 0x310d3100}, + {0x858c, 0x31ed3112}, + {0x8590, 0x320a31f1}, + {0x8594, 0x3243320b}, + {0x8598, 0x31e631b1}, + {0x859c, 0x5b00e283}, + {0x85a0, 0xe2d15500}, + {0x85a4, 0xe2830001}, + {0x85a8, 0x5b10e2e3}, + {0x85ac, 0x20987410}, + {0x85b0, 0xe3750200}, + {0x85b4, 0x00002080}, + {0x85b8, 0x23f0e375}, + {0x85bc, 0xe3750001}, + {0x85c0, 0x000023f0}, + {0x85c4, 0x5507e375}, + {0x85c8, 0xe2d5e2d5}, + {0x85cc, 0x20887410}, + {0x85d0, 0xe3750200}, + {0x85d4, 0x000123f0}, + {0x85d8, 0x23f0e375}, + {0x85dc, 0xe3750000}, + {0x85e0, 0xe2d55517}, + {0x85e4, 0x4e004f02}, + {0x85e8, 0x52015302}, + {0x85ec, 0x7508e2d9}, + {0x85f0, 0x74207900}, + {0x85f4, 0x57005710}, + {0x85f8, 0x75fbe375}, + {0x85fc, 0x23f07410}, + {0x8600, 0xe3750001}, + {0x8604, 0x000023f0}, + {0x8608, 0x7430e375}, + {0x860c, 0x5b100001}, + {0x8610, 0x20907410}, + {0x8614, 0xe3750000}, + {0x8618, 0x000123f0}, + {0x861c, 0x23f0e375}, + {0x8620, 0xe3750000}, + {0x8624, 0xe2d55507}, + {0x8628, 0x7410e2d5}, + {0x862c, 0x02002098}, + {0x8630, 0x23f0e375}, + {0x8634, 0xe3750001}, + {0x8638, 0x000023f0}, + {0x863c, 0x5517e375}, + {0x8640, 0x4f02e2d5}, + {0x8644, 0x53024e00}, + {0x8648, 0xe2d95201}, + {0x864c, 0x30787509}, + {0x8650, 0xe2e3e283}, + {0x8654, 0xe27b0001}, + {0x8658, 0x0001e2e3}, + {0x865c, 0x5b30e28f}, + {0x8660, 0xe2d15500}, + {0x8664, 0xe28f0001}, + {0x8668, 0x0001e312}, + {0x866c, 0x4380e287}, + {0x8670, 0x0001e312}, + {0x8674, 0x30e2e283}, + {0x8678, 0xe3600023}, + {0x867c, 0x54ed0002}, + {0x8680, 0x00230baa}, + {0x8684, 0x0002e360}, + {0x8688, 0xe27be330}, + {0x868c, 0xe2830001}, + {0x8690, 0x002230dd}, + {0x8694, 0x0002e360}, + {0x8698, 0x0baa54ec}, + {0x869c, 0xe3600022}, + {0x86a0, 0xe3300002}, + {0x86a4, 0x0001e27b}, + {0x86a8, 0x0baae283}, + {0x86ac, 0x6d0f6c67}, + {0x86b0, 0xe360e2e3}, + {0x86b4, 0xe2e36c8b}, + {0x86b8, 0x0bace360}, + {0x86bc, 0x6d0f6cb3}, + {0x86c0, 0xe360e2e3}, + {0x86c4, 0x6cdb0bad}, + {0x86c8, 0xe2e36d0f}, + {0x86cc, 0x6cf7e360}, + {0x86d0, 0xe2e36d0f}, + {0x86d4, 0x6c09e360}, + {0x86d8, 0xe2e36d00}, + {0x86dc, 0x6c25e360}, + {0x86e0, 0xe360e2e3}, + {0x86e4, 0x6c4df8ca}, + {0x86e8, 0xe360e2e3}, + {0x86ec, 0x6c75f9d3}, + {0x86f0, 0xe360e2e3}, + {0x86f4, 0xe2e36c99}, + {0x86f8, 0xe330e360}, + {0x86fc, 0x0001e27b}, + {0x8700, 0x314de28f}, + {0x8704, 0xe3650022}, + {0x8708, 0x54ec0002}, + {0x870c, 0x00220baa}, + {0x8710, 0x0002e365}, + {0x8714, 0xe287e330}, + {0x8718, 0xe28f0001}, + {0x871c, 0xe3303139}, + {0x8720, 0x0001e287}, + {0x8724, 0x0ba6e28f}, + {0x8728, 0x21e07410}, + {0x872c, 0x21e80009}, + {0x8730, 0x6e670009}, + {0x8734, 0xe32b6f0f}, + {0x8738, 0xe365e312}, + {0x873c, 0x21e07410}, + {0x8740, 0x21e8000a}, + {0x8744, 0x6e77000a}, + {0x8748, 0xe312e32b}, + {0x874c, 0x7410e365}, + {0x8750, 0x000b21e0}, + {0x8754, 0x000b21e8}, + {0x8758, 0xe32b6e8b}, + {0x875c, 0xe365e312}, + {0x8760, 0x21e07410}, + {0x8764, 0x21e8000c}, + {0x8768, 0x6e9f000c}, + {0x876c, 0xe312e32b}, + {0x8770, 0x0baae365}, + {0x8774, 0x21e07410}, + {0x8778, 0x21e8000d}, + {0x877c, 0x6eb3000d}, + {0x8780, 0xe32b6f0f}, + {0x8784, 0xe365e312}, + {0x8788, 0x21e07410}, + {0x878c, 0x21e8000e}, + {0x8790, 0x6ec7000e}, + {0x8794, 0xe312e32b}, + {0x8798, 0x0bace365}, + {0x879c, 0x21e07410}, + {0x87a0, 0x21e8000f}, + {0x87a4, 0x6edb000f}, + {0x87a8, 0xe32b6f0f}, + {0x87ac, 0xe365e312}, + {0x87b0, 0x21e07410}, + {0x87b4, 0x21e80010}, + {0x87b8, 0x6eef0010}, + {0x87bc, 0xe312e32b}, + {0x87c0, 0xe365e365}, + {0x87c4, 0x21e07410}, + {0x87c8, 0x21e80013}, + {0x87cc, 0x6e110013}, + {0x87d0, 0xe32b6f00}, + {0x87d4, 0xe365e312}, + {0x87d8, 0x7410e365}, + {0x87dc, 0x001421e0}, + {0x87e0, 0x001421e8}, + {0x87e4, 0xe32b6e25}, + {0x87e8, 0xe365e312}, + {0x87ec, 0x7410fb8c}, + {0x87f0, 0x001521e0}, + {0x87f4, 0x001521e8}, + {0x87f8, 0xe32b6e39}, + {0x87fc, 0xe365e312}, + {0x8800, 0x21e07410}, + {0x8804, 0x21e80016}, + {0x8808, 0x6e4d0016}, + {0x880c, 0xe312e32b}, + {0x8810, 0xfc86e365}, + {0x8814, 0x21e07410}, + {0x8818, 0x21e80017}, + {0x881c, 0x6e610017}, + {0x8820, 0xe312e32b}, + {0x8824, 0x7410e365}, + {0x8828, 0x001821e0}, + {0x882c, 0x001821e8}, + {0x8830, 0xe32b6e75}, + {0x8834, 0xe365e312}, + {0x8838, 0x21e07410}, + {0x883c, 0x21e80019}, + {0x8840, 0x6e890019}, + {0x8844, 0xe312e32b}, + {0x8848, 0x7410e365}, + {0x884c, 0x001a21e0}, + {0x8850, 0x001a21e8}, + {0x8854, 0xe32b6e99}, + {0x8858, 0xe365e312}, + {0x885c, 0xe287e330}, + {0x8860, 0x00040001}, + {0x8864, 0x0007775c}, + {0x8868, 0x62006220}, + {0x886c, 0x55010004}, + {0x8870, 0xe2d15b00}, + {0x8874, 0x66055b40}, + {0x8878, 0x62000007}, + {0x887c, 0xe3506300}, + {0x8880, 0xe2d10004}, + {0x8884, 0x0a010900}, + {0x8888, 0x0d000b40}, + {0x888c, 0x00320e01}, + {0x8890, 0x95060004}, + {0x8894, 0x00074380}, + {0x8898, 0x00044d01}, + {0x889c, 0x00074300}, + {0x88a0, 0x05a30562}, + {0x88a4, 0xe3509617}, + {0x88a8, 0xe2d10004}, + {0x88ac, 0x06a20007}, + {0x88b0, 0xe35007a3}, + {0x88b4, 0xe2d10004}, + {0x88b8, 0x0002e340}, + {0x88bc, 0x4380e348}, + {0x88c0, 0x4d000007}, + {0x88c4, 0x43000004}, + {0x88c8, 0x00017900}, + {0x88cc, 0x775e0004}, + {0x88d0, 0x000731b3}, + {0x88d4, 0x07a306a2}, + {0x88d8, 0xe29331dd}, + {0x88dc, 0x73000005}, + {0x88e0, 0xe2930001}, + {0x88e4, 0x5d000006}, + {0x88e8, 0x42f70004}, + {0x88ec, 0x6c000005}, + {0x88f0, 0x42000004}, + {0x88f4, 0x0004e2ab}, + {0x88f8, 0x00074380}, + {0x88fc, 0x4a004e00}, + {0x8900, 0x00064c00}, + {0x8904, 0x60007f00}, + {0x8908, 0x00046f00}, + {0x890c, 0x00054300}, + {0x8910, 0x00017300}, + {0x8914, 0xe2930001}, + {0x8918, 0x5d010006}, + {0x891c, 0x61006002}, + {0x8920, 0x00055601}, + {0x8924, 0xe2ab7710}, + {0x8928, 0x73000005}, + {0x892c, 0x43800004}, + {0x8930, 0x5e010007}, + {0x8934, 0x4d205e00}, + {0x8938, 0x4a084e20}, + {0x893c, 0x4c3f4960}, + {0x8940, 0x00064301}, + {0x8944, 0x63807f01}, + {0x8948, 0x00046010}, + {0x894c, 0x00064300}, + {0x8950, 0x00077402}, + {0x8954, 0x40004001}, + {0x8958, 0x0006ab00}, + {0x895c, 0x00077404}, + {0x8960, 0x40004001}, + {0x8964, 0x0004ab00}, + {0x8968, 0x00074380}, + {0x896c, 0x4e004d00}, + {0x8970, 0x4c004a00}, + {0x8974, 0x00064300}, + {0x8978, 0x63007f00}, + {0x897c, 0x6f006000}, + {0x8980, 0x43000004}, + {0x8984, 0x00040001}, + {0x8988, 0x42bf4380}, + {0x898c, 0x48400007}, + {0x8990, 0x42ef0004}, + {0x8994, 0x4d100007}, + {0x8998, 0x42000004}, + {0x899c, 0x5f800006}, + {0x89a0, 0x5a010007}, + {0x89a4, 0x00044a08}, + {0x89a8, 0x00054300}, + {0x89ac, 0x73807381}, + {0x89b0, 0x003f9300}, + {0x89b4, 0x00000000}, + {0x89b8, 0x00000000}, + {0x89bc, 0x00020000}, + {0x89c0, 0x5f800006}, + {0x89c4, 0x99005f00}, + {0x89c8, 0x43800004}, + {0x89cc, 0x00074280}, + {0x89d0, 0x00044800}, + {0x89d4, 0x000742ef}, + {0x89d8, 0x00044d00}, + {0x89dc, 0x00064200}, + {0x89e0, 0x60005f00}, + {0x89e4, 0x5a000007}, + {0x89e8, 0x48004a00}, + {0x89ec, 0x43000004}, + {0x89f0, 0x73000005}, + {0x89f4, 0x43800001}, + {0x89f8, 0x78006505}, + {0x89fc, 0x7a007900}, + {0x8a00, 0x43007b00}, + {0x8a04, 0x43800001}, + {0x8a08, 0x43006500}, + {0x8a0c, 0x43800001}, + {0x8a10, 0x7c006405}, + {0x8a14, 0x7e007d00}, + {0x8a18, 0x43007f00}, + {0x8a1c, 0x43800001}, + {0x8a20, 0x43006400}, + {0x8a24, 0x00060001}, + {0x8a28, 0x55025601}, + {0x8a2c, 0x00055400}, + {0x8a30, 0x7e127f00}, + {0x8a34, 0x76007710}, + {0x8a38, 0x74007500}, + {0x8a3c, 0x42700004}, + {0x8a40, 0x73810005}, + {0x8a44, 0x00047380}, + {0x8a48, 0x93004200}, + {0x8a4c, 0x77000005}, + {0x8a50, 0x56000006}, + {0x8a54, 0x00060001}, + {0x8a58, 0x5f005f80}, + {0x8a5c, 0x00059900}, + {0x8a60, 0x00067300}, + {0x8a64, 0x63006380}, + {0x8a68, 0x00019800}, + {0x8a6c, 0x7b484380}, + {0x8a70, 0x79007a90}, + {0x8a74, 0x43007802}, + {0x8a78, 0x32cd5503}, + {0x8a7c, 0x7b384380}, + {0x8a80, 0x79007a80}, + {0x8a84, 0x43007802}, + {0x8a88, 0x32cd5513}, + {0x8a8c, 0x7b404380}, + {0x8a90, 0x79007a00}, + {0x8a94, 0x43007802}, + {0x8a98, 0x74315523}, + {0x8a9c, 0x8e007430}, + {0x8aa0, 0x74010001}, + {0x8aa4, 0x8e007400}, + {0x8aa8, 0x74310001}, + {0x8aac, 0x8e007430}, + {0x8ab0, 0x57020001}, + {0x8ab4, 0x97005700}, + {0x8ab8, 0x42ef0001}, + {0x8abc, 0x56005610}, + {0x8ac0, 0x8c004200}, + {0x8ac4, 0x4f780001}, + {0x8ac8, 0x53884e00}, + {0x8acc, 0x5b205201}, + {0x8ad0, 0x5480e2f2}, + {0x8ad4, 0x54815400}, + {0x8ad8, 0x54825400}, + {0x8adc, 0xe2fd5400}, + {0x8ae0, 0x3012bf1d}, + {0x8ae4, 0xe2bee2b6}, + {0x8ae8, 0xe2d9e2c6}, + {0x8aec, 0x5523e359}, + {0x8af0, 0x5525e2cd}, + {0x8af4, 0xe359e2d9}, + {0x8af8, 0x54bf0001}, + {0x8afc, 0x54a354c0}, + {0x8b00, 0x54a454c1}, + {0x8b04, 0xbf074c18}, + {0x8b08, 0x54a454c2}, + {0x8b0c, 0x54c1bf04}, + {0x8b10, 0xbf0154a3}, + {0x8b14, 0x54dfe36a}, + {0x8b18, 0x54bf0001}, + {0x8b1c, 0x050a54e5}, + {0x8b20, 0x000154df}, + {0x8b24, 0x43807b80}, + {0x8b28, 0x7e007f40}, + {0x8b2c, 0x7c027d00}, + {0x8b30, 0x5b404300}, + {0x8b34, 0x5c015501}, + {0x8b38, 0x5480e2dd}, + {0x8b3c, 0x54815400}, + {0x8b40, 0x54825400}, + {0x8b44, 0x7b005400}, + {0x8b48, 0xbfe8e2fd}, + {0x8b4c, 0x56103012}, + {0x8b50, 0x8c005600}, + {0x8b54, 0xe36d0001}, + {0x8b58, 0xe36de36d}, + {0x8b5c, 0x0001e36d}, + {0x8b60, 0x57005704}, + {0x8b64, 0x57089700}, + {0x8b68, 0x97005700}, + {0x8b6c, 0x57805781}, + {0x8b70, 0x43809700}, + {0x8b74, 0x5c010007}, + {0x8b78, 0x00045c00}, + {0x8b7c, 0x00014300}, + {0x8b80, 0x0007427f}, + {0x8b84, 0x62006280}, + {0x8b88, 0x00049200}, + {0x8b8c, 0x00014200}, + {0x8b90, 0x0007427f}, + {0x8b94, 0x63146394}, + {0x8b98, 0x00049100}, + {0x8b9c, 0x00014200}, + {0x8ba0, 0x79010004}, + {0x8ba4, 0xe3757420}, + {0x8ba8, 0x57005710}, + {0x8bac, 0xe375e375}, + {0x8bb0, 0x549f0001}, + {0x8bb4, 0x5c015400}, + {0x8bb8, 0x540054df}, + {0x8bbc, 0x00015c02}, + {0x8bc0, 0x07145c01}, + {0x8bc4, 0x5c025400}, + {0x8bc8, 0x5c020001}, + {0x8bcc, 0x54000714}, + {0x8bd0, 0x00015c01}, + {0x8bd4, 0x4c184c98}, + {0x8bd8, 0x003f0001}, + {0x8bdc, 0x00000000}, + {0x8be0, 0x00000000}, + {0x8be4, 0x00020000}, + {0x8be8, 0x00000001}, + {0x8bec, 0x00000000}, + {0x8bf0, 0x00000000}, + {0x8bf4, 0x00000000}, + {0x8bf8, 0x00010000}, + {0x8bfc, 0x5c020004}, + {0x8c00, 0x66076204}, + {0x8c04, 0x743070c0}, + {0x8c08, 0x0c010901}, + {0x8c0c, 0x00010ba6}, + {0x8080, 0x00000004}, + {0x8080, 0x00000000}, + {0x8088, 0x00000000}, +}; + +static const struct rtw89_txpwr_byrate_cfg rtw89_8852a_txpwr_byrate[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x50505050, }, + { 0, 0, 1, 4, 4, 0x484c5050, }, + { 0, 0, 2, 0, 4, 0x50505050, }, + { 0, 0, 2, 4, 4, 0x44484c50, }, + { 0, 0, 2, 8, 4, 0x34383c40, }, + { 0, 0, 3, 0, 4, 0x50505050, }, + { 0, 1, 2, 0, 4, 0x50505050, }, + { 0, 1, 2, 4, 4, 0x44484c50, }, + { 0, 1, 2, 8, 4, 0x34383c40, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x50505050, }, + { 1, 0, 1, 4, 4, 0x484c5050, }, + { 1, 0, 2, 0, 4, 0x50505050, }, + { 1, 0, 2, 4, 4, 0x44484c50, }, + { 1, 0, 2, 8, 4, 0x34383c40, }, + { 1, 0, 3, 0, 4, 0x50505050, }, + { 1, 1, 2, 0, 4, 0x50505050, }, + { 1, 1, 2, 4, 4, 0x44484c50, }, + { 1, 1, 2, 8, 4, 0x34383c40, }, + { 1, 1, 3, 0, 4, 0x50505050, }, + { 1, 0, 4, 0, 4, 0x00000000, }, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { + 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; + +static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; + +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { + 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, + 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; + +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { + 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { + 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, + 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; + +static +const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 56, + [0][0][0][0][RTW89_WW][1] = 56, + [0][0][0][0][RTW89_WW][2] = 56, + [0][0][0][0][RTW89_WW][3] = 56, + [0][0][0][0][RTW89_WW][4] = 56, + [0][0][0][0][RTW89_WW][5] = 56, + [0][0][0][0][RTW89_WW][6] = 56, + [0][0][0][0][RTW89_WW][7] = 56, + [0][0][0][0][RTW89_WW][8] = 56, + [0][0][0][0][RTW89_WW][9] = 56, + [0][0][0][0][RTW89_WW][10] = 56, + [0][0][0][0][RTW89_WW][11] = 56, + [0][0][0][0][RTW89_WW][12] = 48, + [0][0][0][0][RTW89_WW][13] = 76, + [0][1][0][0][RTW89_WW][0] = 44, + [0][1][0][0][RTW89_WW][1] = 44, + [0][1][0][0][RTW89_WW][2] = 44, + [0][1][0][0][RTW89_WW][3] = 44, + [0][1][0][0][RTW89_WW][4] = 44, + [0][1][0][0][RTW89_WW][5] = 44, + [0][1][0][0][RTW89_WW][6] = 44, + [0][1][0][0][RTW89_WW][7] = 44, + [0][1][0][0][RTW89_WW][8] = 44, + [0][1][0][0][RTW89_WW][9] = 44, + [0][1][0][0][RTW89_WW][10] = 44, + [0][1][0][0][RTW89_WW][11] = 44, + [0][1][0][0][RTW89_WW][12] = 38, + [0][1][0][0][RTW89_WW][13] = 64, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 58, + [1][0][0][0][RTW89_WW][3] = 58, + [1][0][0][0][RTW89_WW][4] = 58, + [1][0][0][0][RTW89_WW][5] = 58, + [1][0][0][0][RTW89_WW][6] = 46, + [1][0][0][0][RTW89_WW][7] = 46, + [1][0][0][0][RTW89_WW][8] = 46, + [1][0][0][0][RTW89_WW][9] = 32, + [1][0][0][0][RTW89_WW][10] = 32, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 46, + [1][1][0][0][RTW89_WW][3] = 46, + [1][1][0][0][RTW89_WW][4] = 46, + [1][1][0][0][RTW89_WW][5] = 46, + [1][1][0][0][RTW89_WW][6] = 46, + [1][1][0][0][RTW89_WW][7] = 46, + [1][1][0][0][RTW89_WW][8] = 46, + [1][1][0][0][RTW89_WW][9] = 24, + [1][1][0][0][RTW89_WW][10] = 24, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][1] = 58, + [0][0][1][0][RTW89_WW][2] = 58, + [0][0][1][0][RTW89_WW][3] = 58, + [0][0][1][0][RTW89_WW][4] = 58, + [0][0][1][0][RTW89_WW][5] = 58, + [0][0][1][0][RTW89_WW][6] = 58, + [0][0][1][0][RTW89_WW][7] = 58, + [0][0][1][0][RTW89_WW][8] = 58, + [0][0][1][0][RTW89_WW][9] = 58, + [0][0][1][0][RTW89_WW][10] = 58, + [0][0][1][0][RTW89_WW][11] = 56, + [0][0][1][0][RTW89_WW][12] = 52, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 46, + [0][1][1][0][RTW89_WW][1] = 46, + [0][1][1][0][RTW89_WW][2] = 46, + [0][1][1][0][RTW89_WW][3] = 46, + [0][1][1][0][RTW89_WW][4] = 46, + [0][1][1][0][RTW89_WW][5] = 46, + [0][1][1][0][RTW89_WW][6] = 46, + [0][1][1][0][RTW89_WW][7] = 46, + [0][1][1][0][RTW89_WW][8] = 46, + [0][1][1][0][RTW89_WW][9] = 46, + [0][1][1][0][RTW89_WW][10] = 46, + [0][1][1][0][RTW89_WW][11] = 42, + [0][1][1][0][RTW89_WW][12] = 40, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 58, + [0][0][2][0][RTW89_WW][1] = 58, + [0][0][2][0][RTW89_WW][2] = 58, + [0][0][2][0][RTW89_WW][3] = 58, + [0][0][2][0][RTW89_WW][4] = 58, + [0][0][2][0][RTW89_WW][5] = 58, + [0][0][2][0][RTW89_WW][6] = 58, + [0][0][2][0][RTW89_WW][7] = 58, + [0][0][2][0][RTW89_WW][8] = 58, + [0][0][2][0][RTW89_WW][9] = 58, + [0][0][2][0][RTW89_WW][10] = 58, + [0][0][2][0][RTW89_WW][11] = 54, + [0][0][2][0][RTW89_WW][12] = 50, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 46, + [0][1][2][0][RTW89_WW][1] = 46, + [0][1][2][0][RTW89_WW][2] = 46, + [0][1][2][0][RTW89_WW][3] = 46, + [0][1][2][0][RTW89_WW][4] = 46, + [0][1][2][0][RTW89_WW][5] = 46, + [0][1][2][0][RTW89_WW][6] = 46, + [0][1][2][0][RTW89_WW][7] = 46, + [0][1][2][0][RTW89_WW][8] = 46, + [0][1][2][0][RTW89_WW][9] = 46, + [0][1][2][0][RTW89_WW][10] = 46, + [0][1][2][0][RTW89_WW][11] = 42, + [0][1][2][0][RTW89_WW][12] = 40, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 34, + [0][1][2][1][RTW89_WW][1] = 34, + [0][1][2][1][RTW89_WW][2] = 34, + [0][1][2][1][RTW89_WW][3] = 34, + [0][1][2][1][RTW89_WW][4] = 34, + [0][1][2][1][RTW89_WW][5] = 34, + [0][1][2][1][RTW89_WW][6] = 34, + [0][1][2][1][RTW89_WW][7] = 34, + [0][1][2][1][RTW89_WW][8] = 34, + [0][1][2][1][RTW89_WW][9] = 34, + [0][1][2][1][RTW89_WW][10] = 34, + [0][1][2][1][RTW89_WW][11] = 34, + [0][1][2][1][RTW89_WW][12] = 34, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 56, + [1][0][2][0][RTW89_WW][3] = 56, + [1][0][2][0][RTW89_WW][4] = 58, + [1][0][2][0][RTW89_WW][5] = 58, + [1][0][2][0][RTW89_WW][6] = 54, + [1][0][2][0][RTW89_WW][7] = 50, + [1][0][2][0][RTW89_WW][8] = 50, + [1][0][2][0][RTW89_WW][9] = 42, + [1][0][2][0][RTW89_WW][10] = 40, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 46, + [1][1][2][0][RTW89_WW][3] = 46, + [1][1][2][0][RTW89_WW][4] = 46, + [1][1][2][0][RTW89_WW][5] = 46, + [1][1][2][0][RTW89_WW][6] = 46, + [1][1][2][0][RTW89_WW][7] = 46, + [1][1][2][0][RTW89_WW][8] = 46, + [1][1][2][0][RTW89_WW][9] = 38, + [1][1][2][0][RTW89_WW][10] = 36, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 34, + [1][1][2][1][RTW89_WW][3] = 34, + [1][1][2][1][RTW89_WW][4] = 34, + [1][1][2][1][RTW89_WW][5] = 34, + [1][1][2][1][RTW89_WW][6] = 34, + [1][1][2][1][RTW89_WW][7] = 34, + [1][1][2][1][RTW89_WW][8] = 34, + [1][1][2][1][RTW89_WW][9] = 34, + [1][1][2][1][RTW89_WW][10] = 34, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 76, + [0][0][0][0][RTW89_ETSI][0] = 56, + [0][0][0][0][RTW89_MKK][0] = 68, + [0][0][0][0][RTW89_IC][0] = 76, + [0][0][0][0][RTW89_KCC][0] = 76, + [0][0][0][0][RTW89_ACMA][0] = 56, + [0][0][0][0][RTW89_CHILE][0] = 60, + [0][0][0][0][RTW89_UKRAINE][0] = 56, + [0][0][0][0][RTW89_MEXICO][0] = 76, + [0][0][0][0][RTW89_CN][0] = 56, + [0][0][0][0][RTW89_QATAR][0] = 56, + [0][0][0][0][RTW89_UK][0] = 56, + [0][0][0][0][RTW89_FCC][1] = 76, + [0][0][0][0][RTW89_ETSI][1] = 56, + [0][0][0][0][RTW89_MKK][1] = 68, + [0][0][0][0][RTW89_IC][1] = 76, + [0][0][0][0][RTW89_KCC][1] = 76, + [0][0][0][0][RTW89_ACMA][1] = 56, + [0][0][0][0][RTW89_CHILE][1] = 60, + [0][0][0][0][RTW89_UKRAINE][1] = 56, + [0][0][0][0][RTW89_MEXICO][1] = 76, + [0][0][0][0][RTW89_CN][1] = 56, + [0][0][0][0][RTW89_QATAR][1] = 56, + [0][0][0][0][RTW89_UK][1] = 56, + [0][0][0][0][RTW89_FCC][2] = 76, + [0][0][0][0][RTW89_ETSI][2] = 56, + [0][0][0][0][RTW89_MKK][2] = 68, + [0][0][0][0][RTW89_IC][2] = 76, + [0][0][0][0][RTW89_KCC][2] = 76, + [0][0][0][0][RTW89_ACMA][2] = 56, + [0][0][0][0][RTW89_CHILE][2] = 60, + [0][0][0][0][RTW89_UKRAINE][2] = 56, + [0][0][0][0][RTW89_MEXICO][2] = 76, + [0][0][0][0][RTW89_CN][2] = 56, + [0][0][0][0][RTW89_QATAR][2] = 56, + [0][0][0][0][RTW89_UK][2] = 56, + [0][0][0][0][RTW89_FCC][3] = 76, + [0][0][0][0][RTW89_ETSI][3] = 56, + [0][0][0][0][RTW89_MKK][3] = 68, + [0][0][0][0][RTW89_IC][3] = 76, + [0][0][0][0][RTW89_KCC][3] = 76, + [0][0][0][0][RTW89_ACMA][3] = 56, + [0][0][0][0][RTW89_CHILE][3] = 60, + [0][0][0][0][RTW89_UKRAINE][3] = 56, + [0][0][0][0][RTW89_MEXICO][3] = 76, + [0][0][0][0][RTW89_CN][3] = 56, + [0][0][0][0][RTW89_QATAR][3] = 56, + [0][0][0][0][RTW89_UK][3] = 56, + [0][0][0][0][RTW89_FCC][4] = 76, + [0][0][0][0][RTW89_ETSI][4] = 56, + [0][0][0][0][RTW89_MKK][4] = 68, + [0][0][0][0][RTW89_IC][4] = 76, + [0][0][0][0][RTW89_KCC][4] = 76, + [0][0][0][0][RTW89_ACMA][4] = 56, + [0][0][0][0][RTW89_CHILE][4] = 60, + [0][0][0][0][RTW89_UKRAINE][4] = 56, + [0][0][0][0][RTW89_MEXICO][4] = 76, + [0][0][0][0][RTW89_CN][4] = 56, + [0][0][0][0][RTW89_QATAR][4] = 56, + [0][0][0][0][RTW89_UK][4] = 56, + [0][0][0][0][RTW89_FCC][5] = 76, + [0][0][0][0][RTW89_ETSI][5] = 56, + [0][0][0][0][RTW89_MKK][5] = 68, + [0][0][0][0][RTW89_IC][5] = 76, + [0][0][0][0][RTW89_KCC][5] = 76, + [0][0][0][0][RTW89_ACMA][5] = 56, + [0][0][0][0][RTW89_CHILE][5] = 60, + [0][0][0][0][RTW89_UKRAINE][5] = 56, + [0][0][0][0][RTW89_MEXICO][5] = 76, + [0][0][0][0][RTW89_CN][5] = 56, + [0][0][0][0][RTW89_QATAR][5] = 56, + [0][0][0][0][RTW89_UK][5] = 56, + [0][0][0][0][RTW89_FCC][6] = 76, + [0][0][0][0][RTW89_ETSI][6] = 56, + [0][0][0][0][RTW89_MKK][6] = 68, + [0][0][0][0][RTW89_IC][6] = 76, + [0][0][0][0][RTW89_KCC][6] = 76, + [0][0][0][0][RTW89_ACMA][6] = 56, + [0][0][0][0][RTW89_CHILE][6] = 60, + [0][0][0][0][RTW89_UKRAINE][6] = 56, + [0][0][0][0][RTW89_MEXICO][6] = 76, + [0][0][0][0][RTW89_CN][6] = 56, + [0][0][0][0][RTW89_QATAR][6] = 56, + [0][0][0][0][RTW89_UK][6] = 56, + [0][0][0][0][RTW89_FCC][7] = 76, + [0][0][0][0][RTW89_ETSI][7] = 56, + [0][0][0][0][RTW89_MKK][7] = 68, + [0][0][0][0][RTW89_IC][7] = 76, + [0][0][0][0][RTW89_KCC][7] = 76, + [0][0][0][0][RTW89_ACMA][7] = 56, + [0][0][0][0][RTW89_CHILE][7] = 60, + [0][0][0][0][RTW89_UKRAINE][7] = 56, + [0][0][0][0][RTW89_MEXICO][7] = 76, + [0][0][0][0][RTW89_CN][7] = 56, + [0][0][0][0][RTW89_QATAR][7] = 56, + [0][0][0][0][RTW89_UK][7] = 56, + [0][0][0][0][RTW89_FCC][8] = 76, + [0][0][0][0][RTW89_ETSI][8] = 56, + [0][0][0][0][RTW89_MKK][8] = 68, + [0][0][0][0][RTW89_IC][8] = 76, + [0][0][0][0][RTW89_KCC][8] = 76, + [0][0][0][0][RTW89_ACMA][8] = 56, + [0][0][0][0][RTW89_CHILE][8] = 60, + [0][0][0][0][RTW89_UKRAINE][8] = 56, + [0][0][0][0][RTW89_MEXICO][8] = 76, + [0][0][0][0][RTW89_CN][8] = 56, + [0][0][0][0][RTW89_QATAR][8] = 56, + [0][0][0][0][RTW89_UK][8] = 56, + [0][0][0][0][RTW89_FCC][9] = 76, + [0][0][0][0][RTW89_ETSI][9] = 56, + [0][0][0][0][RTW89_MKK][9] = 68, + [0][0][0][0][RTW89_IC][9] = 76, + [0][0][0][0][RTW89_KCC][9] = 76, + [0][0][0][0][RTW89_ACMA][9] = 56, + [0][0][0][0][RTW89_CHILE][9] = 60, + [0][0][0][0][RTW89_UKRAINE][9] = 56, + [0][0][0][0][RTW89_MEXICO][9] = 76, + [0][0][0][0][RTW89_CN][9] = 56, + [0][0][0][0][RTW89_QATAR][9] = 56, + [0][0][0][0][RTW89_UK][9] = 56, + [0][0][0][0][RTW89_FCC][10] = 76, + [0][0][0][0][RTW89_ETSI][10] = 56, + [0][0][0][0][RTW89_MKK][10] = 68, + [0][0][0][0][RTW89_IC][10] = 76, + [0][0][0][0][RTW89_KCC][10] = 76, + [0][0][0][0][RTW89_ACMA][10] = 56, + [0][0][0][0][RTW89_CHILE][10] = 60, + [0][0][0][0][RTW89_UKRAINE][10] = 56, + [0][0][0][0][RTW89_MEXICO][10] = 76, + [0][0][0][0][RTW89_CN][10] = 56, + [0][0][0][0][RTW89_QATAR][10] = 56, + [0][0][0][0][RTW89_UK][10] = 56, + [0][0][0][0][RTW89_FCC][11] = 68, + [0][0][0][0][RTW89_ETSI][11] = 56, + [0][0][0][0][RTW89_MKK][11] = 68, + [0][0][0][0][RTW89_IC][11] = 68, + [0][0][0][0][RTW89_KCC][11] = 76, + [0][0][0][0][RTW89_ACMA][11] = 56, + [0][0][0][0][RTW89_CHILE][11] = 60, + [0][0][0][0][RTW89_UKRAINE][11] = 56, + [0][0][0][0][RTW89_MEXICO][11] = 68, + [0][0][0][0][RTW89_CN][11] = 56, + [0][0][0][0][RTW89_QATAR][11] = 56, + [0][0][0][0][RTW89_UK][11] = 56, + [0][0][0][0][RTW89_FCC][12] = 48, + [0][0][0][0][RTW89_ETSI][12] = 56, + [0][0][0][0][RTW89_MKK][12] = 68, + [0][0][0][0][RTW89_IC][12] = 48, + [0][0][0][0][RTW89_KCC][12] = 76, + [0][0][0][0][RTW89_ACMA][12] = 56, + [0][0][0][0][RTW89_CHILE][12] = 48, + [0][0][0][0][RTW89_UKRAINE][12] = 56, + [0][0][0][0][RTW89_MEXICO][12] = 48, + [0][0][0][0][RTW89_CN][12] = 56, + [0][0][0][0][RTW89_QATAR][12] = 56, + [0][0][0][0][RTW89_UK][12] = 56, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 76, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_KCC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][0][0][0][RTW89_CHILE][13] = 127, + [0][0][0][0][RTW89_UKRAINE][13] = 127, + [0][0][0][0][RTW89_MEXICO][13] = 127, + [0][0][0][0][RTW89_CN][13] = 127, + [0][0][0][0][RTW89_QATAR][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 74, + [0][1][0][0][RTW89_ETSI][0] = 44, + [0][1][0][0][RTW89_MKK][0] = 56, + [0][1][0][0][RTW89_IC][0] = 74, + [0][1][0][0][RTW89_KCC][0] = 68, + [0][1][0][0][RTW89_ACMA][0] = 44, + [0][1][0][0][RTW89_CHILE][0] = 48, + [0][1][0][0][RTW89_UKRAINE][0] = 44, + [0][1][0][0][RTW89_MEXICO][0] = 74, + [0][1][0][0][RTW89_CN][0] = 44, + [0][1][0][0][RTW89_QATAR][0] = 44, + [0][1][0][0][RTW89_UK][0] = 44, + [0][1][0][0][RTW89_FCC][1] = 76, + [0][1][0][0][RTW89_ETSI][1] = 44, + [0][1][0][0][RTW89_MKK][1] = 56, + [0][1][0][0][RTW89_IC][1] = 76, + [0][1][0][0][RTW89_KCC][1] = 68, + [0][1][0][0][RTW89_ACMA][1] = 44, + [0][1][0][0][RTW89_CHILE][1] = 48, + [0][1][0][0][RTW89_UKRAINE][1] = 44, + [0][1][0][0][RTW89_MEXICO][1] = 76, + [0][1][0][0][RTW89_CN][1] = 44, + [0][1][0][0][RTW89_QATAR][1] = 44, + [0][1][0][0][RTW89_UK][1] = 44, + [0][1][0][0][RTW89_FCC][2] = 76, + [0][1][0][0][RTW89_ETSI][2] = 44, + [0][1][0][0][RTW89_MKK][2] = 56, + [0][1][0][0][RTW89_IC][2] = 76, + [0][1][0][0][RTW89_KCC][2] = 68, + [0][1][0][0][RTW89_ACMA][2] = 44, + [0][1][0][0][RTW89_CHILE][2] = 48, + [0][1][0][0][RTW89_UKRAINE][2] = 44, + [0][1][0][0][RTW89_MEXICO][2] = 76, + [0][1][0][0][RTW89_CN][2] = 44, + [0][1][0][0][RTW89_QATAR][2] = 44, + [0][1][0][0][RTW89_UK][2] = 44, + [0][1][0][0][RTW89_FCC][3] = 76, + [0][1][0][0][RTW89_ETSI][3] = 44, + [0][1][0][0][RTW89_MKK][3] = 56, + [0][1][0][0][RTW89_IC][3] = 76, + [0][1][0][0][RTW89_KCC][3] = 68, + [0][1][0][0][RTW89_ACMA][3] = 44, + [0][1][0][0][RTW89_CHILE][3] = 48, + [0][1][0][0][RTW89_UKRAINE][3] = 44, + [0][1][0][0][RTW89_MEXICO][3] = 76, + [0][1][0][0][RTW89_CN][3] = 44, + [0][1][0][0][RTW89_QATAR][3] = 44, + [0][1][0][0][RTW89_UK][3] = 44, + [0][1][0][0][RTW89_FCC][4] = 76, + [0][1][0][0][RTW89_ETSI][4] = 44, + [0][1][0][0][RTW89_MKK][4] = 56, + [0][1][0][0][RTW89_IC][4] = 76, + [0][1][0][0][RTW89_KCC][4] = 68, + [0][1][0][0][RTW89_ACMA][4] = 44, + [0][1][0][0][RTW89_CHILE][4] = 48, + [0][1][0][0][RTW89_UKRAINE][4] = 44, + [0][1][0][0][RTW89_MEXICO][4] = 76, + [0][1][0][0][RTW89_CN][4] = 44, + [0][1][0][0][RTW89_QATAR][4] = 44, + [0][1][0][0][RTW89_UK][4] = 44, + [0][1][0][0][RTW89_FCC][5] = 76, + [0][1][0][0][RTW89_ETSI][5] = 44, + [0][1][0][0][RTW89_MKK][5] = 56, + [0][1][0][0][RTW89_IC][5] = 76, + [0][1][0][0][RTW89_KCC][5] = 68, + [0][1][0][0][RTW89_ACMA][5] = 44, + [0][1][0][0][RTW89_CHILE][5] = 48, + [0][1][0][0][RTW89_UKRAINE][5] = 44, + [0][1][0][0][RTW89_MEXICO][5] = 76, + [0][1][0][0][RTW89_CN][5] = 44, + [0][1][0][0][RTW89_QATAR][5] = 44, + [0][1][0][0][RTW89_UK][5] = 44, + [0][1][0][0][RTW89_FCC][6] = 76, + [0][1][0][0][RTW89_ETSI][6] = 44, + [0][1][0][0][RTW89_MKK][6] = 56, + [0][1][0][0][RTW89_IC][6] = 76, + [0][1][0][0][RTW89_KCC][6] = 68, + [0][1][0][0][RTW89_ACMA][6] = 44, + [0][1][0][0][RTW89_CHILE][6] = 48, + [0][1][0][0][RTW89_UKRAINE][6] = 44, + [0][1][0][0][RTW89_MEXICO][6] = 76, + [0][1][0][0][RTW89_CN][6] = 44, + [0][1][0][0][RTW89_QATAR][6] = 44, + [0][1][0][0][RTW89_UK][6] = 44, + [0][1][0][0][RTW89_FCC][7] = 76, + [0][1][0][0][RTW89_ETSI][7] = 44, + [0][1][0][0][RTW89_MKK][7] = 56, + [0][1][0][0][RTW89_IC][7] = 76, + [0][1][0][0][RTW89_KCC][7] = 68, + [0][1][0][0][RTW89_ACMA][7] = 44, + [0][1][0][0][RTW89_CHILE][7] = 48, + [0][1][0][0][RTW89_UKRAINE][7] = 44, + [0][1][0][0][RTW89_MEXICO][7] = 76, + [0][1][0][0][RTW89_CN][7] = 44, + [0][1][0][0][RTW89_QATAR][7] = 44, + [0][1][0][0][RTW89_UK][7] = 44, + [0][1][0][0][RTW89_FCC][8] = 76, + [0][1][0][0][RTW89_ETSI][8] = 44, + [0][1][0][0][RTW89_MKK][8] = 56, + [0][1][0][0][RTW89_IC][8] = 76, + [0][1][0][0][RTW89_KCC][8] = 68, + [0][1][0][0][RTW89_ACMA][8] = 44, + [0][1][0][0][RTW89_CHILE][8] = 48, + [0][1][0][0][RTW89_UKRAINE][8] = 44, + [0][1][0][0][RTW89_MEXICO][8] = 76, + [0][1][0][0][RTW89_CN][8] = 44, + [0][1][0][0][RTW89_QATAR][8] = 44, + [0][1][0][0][RTW89_UK][8] = 44, + [0][1][0][0][RTW89_FCC][9] = 76, + [0][1][0][0][RTW89_ETSI][9] = 44, + [0][1][0][0][RTW89_MKK][9] = 56, + [0][1][0][0][RTW89_IC][9] = 76, + [0][1][0][0][RTW89_KCC][9] = 68, + [0][1][0][0][RTW89_ACMA][9] = 44, + [0][1][0][0][RTW89_CHILE][9] = 48, + [0][1][0][0][RTW89_UKRAINE][9] = 44, + [0][1][0][0][RTW89_MEXICO][9] = 76, + [0][1][0][0][RTW89_CN][9] = 44, + [0][1][0][0][RTW89_QATAR][9] = 44, + [0][1][0][0][RTW89_UK][9] = 44, + [0][1][0][0][RTW89_FCC][10] = 62, + [0][1][0][0][RTW89_ETSI][10] = 44, + [0][1][0][0][RTW89_MKK][10] = 56, + [0][1][0][0][RTW89_IC][10] = 62, + [0][1][0][0][RTW89_KCC][10] = 68, + [0][1][0][0][RTW89_ACMA][10] = 44, + [0][1][0][0][RTW89_CHILE][10] = 48, + [0][1][0][0][RTW89_UKRAINE][10] = 44, + [0][1][0][0][RTW89_MEXICO][10] = 62, + [0][1][0][0][RTW89_CN][10] = 44, + [0][1][0][0][RTW89_QATAR][10] = 44, + [0][1][0][0][RTW89_UK][10] = 44, + [0][1][0][0][RTW89_FCC][11] = 52, + [0][1][0][0][RTW89_ETSI][11] = 44, + [0][1][0][0][RTW89_MKK][11] = 56, + [0][1][0][0][RTW89_IC][11] = 52, + [0][1][0][0][RTW89_KCC][11] = 68, + [0][1][0][0][RTW89_ACMA][11] = 44, + [0][1][0][0][RTW89_CHILE][11] = 48, + [0][1][0][0][RTW89_UKRAINE][11] = 44, + [0][1][0][0][RTW89_MEXICO][11] = 52, + [0][1][0][0][RTW89_CN][11] = 44, + [0][1][0][0][RTW89_QATAR][11] = 44, + [0][1][0][0][RTW89_UK][11] = 44, + [0][1][0][0][RTW89_FCC][12] = 38, + [0][1][0][0][RTW89_ETSI][12] = 44, + [0][1][0][0][RTW89_MKK][12] = 56, + [0][1][0][0][RTW89_IC][12] = 38, + [0][1][0][0][RTW89_KCC][12] = 68, + [0][1][0][0][RTW89_ACMA][12] = 44, + [0][1][0][0][RTW89_CHILE][12] = 38, + [0][1][0][0][RTW89_UKRAINE][12] = 44, + [0][1][0][0][RTW89_MEXICO][12] = 38, + [0][1][0][0][RTW89_CN][12] = 44, + [0][1][0][0][RTW89_QATAR][12] = 44, + [0][1][0][0][RTW89_UK][12] = 44, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 64, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_KCC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_CHILE][13] = 127, + [0][1][0][0][RTW89_UKRAINE][13] = 127, + [0][1][0][0][RTW89_MEXICO][13] = 127, + [0][1][0][0][RTW89_CN][13] = 127, + [0][1][0][0][RTW89_QATAR][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_KCC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_CHILE][0] = 127, + [1][0][0][0][RTW89_UKRAINE][0] = 127, + [1][0][0][0][RTW89_MEXICO][0] = 127, + [1][0][0][0][RTW89_CN][0] = 127, + [1][0][0][0][RTW89_QATAR][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_KCC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_CHILE][1] = 127, + [1][0][0][0][RTW89_UKRAINE][1] = 127, + [1][0][0][0][RTW89_MEXICO][1] = 127, + [1][0][0][0][RTW89_CN][1] = 127, + [1][0][0][0][RTW89_QATAR][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 60, + [1][0][0][0][RTW89_ETSI][2] = 58, + [1][0][0][0][RTW89_MKK][2] = 68, + [1][0][0][0][RTW89_IC][2] = 60, + [1][0][0][0][RTW89_KCC][2] = 70, + [1][0][0][0][RTW89_ACMA][2] = 58, + [1][0][0][0][RTW89_CHILE][2] = 60, + [1][0][0][0][RTW89_UKRAINE][2] = 58, + [1][0][0][0][RTW89_MEXICO][2] = 60, + [1][0][0][0][RTW89_CN][2] = 58, + [1][0][0][0][RTW89_QATAR][2] = 58, + [1][0][0][0][RTW89_UK][2] = 58, + [1][0][0][0][RTW89_FCC][3] = 60, + [1][0][0][0][RTW89_ETSI][3] = 58, + [1][0][0][0][RTW89_MKK][3] = 68, + [1][0][0][0][RTW89_IC][3] = 60, + [1][0][0][0][RTW89_KCC][3] = 70, + [1][0][0][0][RTW89_ACMA][3] = 58, + [1][0][0][0][RTW89_CHILE][3] = 60, + [1][0][0][0][RTW89_UKRAINE][3] = 58, + [1][0][0][0][RTW89_MEXICO][3] = 60, + [1][0][0][0][RTW89_CN][3] = 58, + [1][0][0][0][RTW89_QATAR][3] = 58, + [1][0][0][0][RTW89_UK][3] = 58, + [1][0][0][0][RTW89_FCC][4] = 60, + [1][0][0][0][RTW89_ETSI][4] = 58, + [1][0][0][0][RTW89_MKK][4] = 68, + [1][0][0][0][RTW89_IC][4] = 60, + [1][0][0][0][RTW89_KCC][4] = 70, + [1][0][0][0][RTW89_ACMA][4] = 58, + [1][0][0][0][RTW89_CHILE][4] = 60, + [1][0][0][0][RTW89_UKRAINE][4] = 58, + [1][0][0][0][RTW89_MEXICO][4] = 60, + [1][0][0][0][RTW89_CN][4] = 58, + [1][0][0][0][RTW89_QATAR][4] = 58, + [1][0][0][0][RTW89_UK][4] = 58, + [1][0][0][0][RTW89_FCC][5] = 60, + [1][0][0][0][RTW89_ETSI][5] = 58, + [1][0][0][0][RTW89_MKK][5] = 68, + [1][0][0][0][RTW89_IC][5] = 60, + [1][0][0][0][RTW89_KCC][5] = 70, + [1][0][0][0][RTW89_ACMA][5] = 58, + [1][0][0][0][RTW89_CHILE][5] = 60, + [1][0][0][0][RTW89_UKRAINE][5] = 58, + [1][0][0][0][RTW89_MEXICO][5] = 60, + [1][0][0][0][RTW89_CN][5] = 58, + [1][0][0][0][RTW89_QATAR][5] = 58, + [1][0][0][0][RTW89_UK][5] = 58, + [1][0][0][0][RTW89_FCC][6] = 46, + [1][0][0][0][RTW89_ETSI][6] = 58, + [1][0][0][0][RTW89_MKK][6] = 68, + [1][0][0][0][RTW89_IC][6] = 46, + [1][0][0][0][RTW89_KCC][6] = 70, + [1][0][0][0][RTW89_ACMA][6] = 58, + [1][0][0][0][RTW89_CHILE][6] = 46, + [1][0][0][0][RTW89_UKRAINE][6] = 58, + [1][0][0][0][RTW89_MEXICO][6] = 46, + [1][0][0][0][RTW89_CN][6] = 58, + [1][0][0][0][RTW89_QATAR][6] = 58, + [1][0][0][0][RTW89_UK][6] = 58, + [1][0][0][0][RTW89_FCC][7] = 46, + [1][0][0][0][RTW89_ETSI][7] = 58, + [1][0][0][0][RTW89_MKK][7] = 68, + [1][0][0][0][RTW89_IC][7] = 46, + [1][0][0][0][RTW89_KCC][7] = 70, + [1][0][0][0][RTW89_ACMA][7] = 58, + [1][0][0][0][RTW89_CHILE][7] = 46, + [1][0][0][0][RTW89_UKRAINE][7] = 58, + [1][0][0][0][RTW89_MEXICO][7] = 46, + [1][0][0][0][RTW89_CN][7] = 58, + [1][0][0][0][RTW89_QATAR][7] = 58, + [1][0][0][0][RTW89_UK][7] = 58, + [1][0][0][0][RTW89_FCC][8] = 46, + [1][0][0][0][RTW89_ETSI][8] = 58, + [1][0][0][0][RTW89_MKK][8] = 68, + [1][0][0][0][RTW89_IC][8] = 46, + [1][0][0][0][RTW89_KCC][8] = 70, + [1][0][0][0][RTW89_ACMA][8] = 58, + [1][0][0][0][RTW89_CHILE][8] = 46, + [1][0][0][0][RTW89_UKRAINE][8] = 58, + [1][0][0][0][RTW89_MEXICO][8] = 46, + [1][0][0][0][RTW89_CN][8] = 58, + [1][0][0][0][RTW89_QATAR][8] = 58, + [1][0][0][0][RTW89_UK][8] = 58, + [1][0][0][0][RTW89_FCC][9] = 32, + [1][0][0][0][RTW89_ETSI][9] = 58, + [1][0][0][0][RTW89_MKK][9] = 68, + [1][0][0][0][RTW89_IC][9] = 32, + [1][0][0][0][RTW89_KCC][9] = 70, + [1][0][0][0][RTW89_ACMA][9] = 58, + [1][0][0][0][RTW89_CHILE][9] = 32, + [1][0][0][0][RTW89_UKRAINE][9] = 58, + [1][0][0][0][RTW89_MEXICO][9] = 32, + [1][0][0][0][RTW89_CN][9] = 58, + [1][0][0][0][RTW89_QATAR][9] = 58, + [1][0][0][0][RTW89_UK][9] = 58, + [1][0][0][0][RTW89_FCC][10] = 32, + [1][0][0][0][RTW89_ETSI][10] = 58, + [1][0][0][0][RTW89_MKK][10] = 68, + [1][0][0][0][RTW89_IC][10] = 32, + [1][0][0][0][RTW89_KCC][10] = 70, + [1][0][0][0][RTW89_ACMA][10] = 58, + [1][0][0][0][RTW89_CHILE][10] = 32, + [1][0][0][0][RTW89_UKRAINE][10] = 58, + [1][0][0][0][RTW89_MEXICO][10] = 32, + [1][0][0][0][RTW89_CN][10] = 58, + [1][0][0][0][RTW89_QATAR][10] = 58, + [1][0][0][0][RTW89_UK][10] = 58, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_KCC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_CHILE][11] = 127, + [1][0][0][0][RTW89_UKRAINE][11] = 127, + [1][0][0][0][RTW89_MEXICO][11] = 127, + [1][0][0][0][RTW89_CN][11] = 127, + [1][0][0][0][RTW89_QATAR][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_KCC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_CHILE][12] = 127, + [1][0][0][0][RTW89_UKRAINE][12] = 127, + [1][0][0][0][RTW89_MEXICO][12] = 127, + [1][0][0][0][RTW89_CN][12] = 127, + [1][0][0][0][RTW89_QATAR][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_KCC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_CHILE][13] = 127, + [1][0][0][0][RTW89_UKRAINE][13] = 127, + [1][0][0][0][RTW89_MEXICO][13] = 127, + [1][0][0][0][RTW89_CN][13] = 127, + [1][0][0][0][RTW89_QATAR][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_KCC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_CHILE][0] = 127, + [1][1][0][0][RTW89_UKRAINE][0] = 127, + [1][1][0][0][RTW89_MEXICO][0] = 127, + [1][1][0][0][RTW89_CN][0] = 127, + [1][1][0][0][RTW89_QATAR][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_KCC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_CHILE][1] = 127, + [1][1][0][0][RTW89_UKRAINE][1] = 127, + [1][1][0][0][RTW89_MEXICO][1] = 127, + [1][1][0][0][RTW89_CN][1] = 127, + [1][1][0][0][RTW89_QATAR][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 48, + [1][1][0][0][RTW89_ETSI][2] = 46, + [1][1][0][0][RTW89_MKK][2] = 56, + [1][1][0][0][RTW89_IC][2] = 48, + [1][1][0][0][RTW89_KCC][2] = 58, + [1][1][0][0][RTW89_ACMA][2] = 46, + [1][1][0][0][RTW89_CHILE][2] = 48, + [1][1][0][0][RTW89_UKRAINE][2] = 46, + [1][1][0][0][RTW89_MEXICO][2] = 48, + [1][1][0][0][RTW89_CN][2] = 46, + [1][1][0][0][RTW89_QATAR][2] = 46, + [1][1][0][0][RTW89_UK][2] = 46, + [1][1][0][0][RTW89_FCC][3] = 48, + [1][1][0][0][RTW89_ETSI][3] = 46, + [1][1][0][0][RTW89_MKK][3] = 56, + [1][1][0][0][RTW89_IC][3] = 48, + [1][1][0][0][RTW89_KCC][3] = 58, + [1][1][0][0][RTW89_ACMA][3] = 46, + [1][1][0][0][RTW89_CHILE][3] = 48, + [1][1][0][0][RTW89_UKRAINE][3] = 46, + [1][1][0][0][RTW89_MEXICO][3] = 48, + [1][1][0][0][RTW89_CN][3] = 46, + [1][1][0][0][RTW89_QATAR][3] = 46, + [1][1][0][0][RTW89_UK][3] = 46, + [1][1][0][0][RTW89_FCC][4] = 48, + [1][1][0][0][RTW89_ETSI][4] = 46, + [1][1][0][0][RTW89_MKK][4] = 56, + [1][1][0][0][RTW89_IC][4] = 48, + [1][1][0][0][RTW89_KCC][4] = 58, + [1][1][0][0][RTW89_ACMA][4] = 46, + [1][1][0][0][RTW89_CHILE][4] = 48, + [1][1][0][0][RTW89_UKRAINE][4] = 46, + [1][1][0][0][RTW89_MEXICO][4] = 48, + [1][1][0][0][RTW89_CN][4] = 46, + [1][1][0][0][RTW89_QATAR][4] = 46, + [1][1][0][0][RTW89_UK][4] = 46, + [1][1][0][0][RTW89_FCC][5] = 58, + [1][1][0][0][RTW89_ETSI][5] = 46, + [1][1][0][0][RTW89_MKK][5] = 56, + [1][1][0][0][RTW89_IC][5] = 58, + [1][1][0][0][RTW89_KCC][5] = 58, + [1][1][0][0][RTW89_ACMA][5] = 46, + [1][1][0][0][RTW89_CHILE][5] = 48, + [1][1][0][0][RTW89_UKRAINE][5] = 46, + [1][1][0][0][RTW89_MEXICO][5] = 58, + [1][1][0][0][RTW89_CN][5] = 46, + [1][1][0][0][RTW89_QATAR][5] = 46, + [1][1][0][0][RTW89_UK][5] = 46, + [1][1][0][0][RTW89_FCC][6] = 46, + [1][1][0][0][RTW89_ETSI][6] = 46, + [1][1][0][0][RTW89_MKK][6] = 56, + [1][1][0][0][RTW89_IC][6] = 46, + [1][1][0][0][RTW89_KCC][6] = 58, + [1][1][0][0][RTW89_ACMA][6] = 46, + [1][1][0][0][RTW89_CHILE][6] = 46, + [1][1][0][0][RTW89_UKRAINE][6] = 46, + [1][1][0][0][RTW89_MEXICO][6] = 46, + [1][1][0][0][RTW89_CN][6] = 46, + [1][1][0][0][RTW89_QATAR][6] = 46, + [1][1][0][0][RTW89_UK][6] = 46, + [1][1][0][0][RTW89_FCC][7] = 46, + [1][1][0][0][RTW89_ETSI][7] = 46, + [1][1][0][0][RTW89_MKK][7] = 56, + [1][1][0][0][RTW89_IC][7] = 46, + [1][1][0][0][RTW89_KCC][7] = 58, + [1][1][0][0][RTW89_ACMA][7] = 46, + [1][1][0][0][RTW89_CHILE][7] = 46, + [1][1][0][0][RTW89_UKRAINE][7] = 46, + [1][1][0][0][RTW89_MEXICO][7] = 46, + [1][1][0][0][RTW89_CN][7] = 46, + [1][1][0][0][RTW89_QATAR][7] = 46, + [1][1][0][0][RTW89_UK][7] = 46, + [1][1][0][0][RTW89_FCC][8] = 46, + [1][1][0][0][RTW89_ETSI][8] = 46, + [1][1][0][0][RTW89_MKK][8] = 56, + [1][1][0][0][RTW89_IC][8] = 46, + [1][1][0][0][RTW89_KCC][8] = 58, + [1][1][0][0][RTW89_ACMA][8] = 46, + [1][1][0][0][RTW89_CHILE][8] = 46, + [1][1][0][0][RTW89_UKRAINE][8] = 46, + [1][1][0][0][RTW89_MEXICO][8] = 46, + [1][1][0][0][RTW89_CN][8] = 46, + [1][1][0][0][RTW89_QATAR][8] = 46, + [1][1][0][0][RTW89_UK][8] = 46, + [1][1][0][0][RTW89_FCC][9] = 24, + [1][1][0][0][RTW89_ETSI][9] = 46, + [1][1][0][0][RTW89_MKK][9] = 56, + [1][1][0][0][RTW89_IC][9] = 24, + [1][1][0][0][RTW89_KCC][9] = 58, + [1][1][0][0][RTW89_ACMA][9] = 46, + [1][1][0][0][RTW89_CHILE][9] = 24, + [1][1][0][0][RTW89_UKRAINE][9] = 46, + [1][1][0][0][RTW89_MEXICO][9] = 24, + [1][1][0][0][RTW89_CN][9] = 46, + [1][1][0][0][RTW89_QATAR][9] = 46, + [1][1][0][0][RTW89_UK][9] = 46, + [1][1][0][0][RTW89_FCC][10] = 24, + [1][1][0][0][RTW89_ETSI][10] = 46, + [1][1][0][0][RTW89_MKK][10] = 56, + [1][1][0][0][RTW89_IC][10] = 24, + [1][1][0][0][RTW89_KCC][10] = 58, + [1][1][0][0][RTW89_ACMA][10] = 46, + [1][1][0][0][RTW89_CHILE][10] = 24, + [1][1][0][0][RTW89_UKRAINE][10] = 46, + [1][1][0][0][RTW89_MEXICO][10] = 24, + [1][1][0][0][RTW89_CN][10] = 46, + [1][1][0][0][RTW89_QATAR][10] = 46, + [1][1][0][0][RTW89_UK][10] = 46, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_KCC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_CHILE][11] = 127, + [1][1][0][0][RTW89_UKRAINE][11] = 127, + [1][1][0][0][RTW89_MEXICO][11] = 127, + [1][1][0][0][RTW89_CN][11] = 127, + [1][1][0][0][RTW89_QATAR][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_KCC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_CHILE][12] = 127, + [1][1][0][0][RTW89_UKRAINE][12] = 127, + [1][1][0][0][RTW89_MEXICO][12] = 127, + [1][1][0][0][RTW89_CN][12] = 127, + [1][1][0][0][RTW89_QATAR][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_KCC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_CHILE][13] = 127, + [1][1][0][0][RTW89_UKRAINE][13] = 127, + [1][1][0][0][RTW89_MEXICO][13] = 127, + [1][1][0][0][RTW89_CN][13] = 127, + [1][1][0][0][RTW89_QATAR][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 66, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 76, + [0][0][1][0][RTW89_IC][0] = 66, + [0][0][1][0][RTW89_KCC][0] = 76, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CHILE][0] = 60, + [0][0][1][0][RTW89_UKRAINE][0] = 58, + [0][0][1][0][RTW89_MEXICO][0] = 66, + [0][0][1][0][RTW89_CN][0] = 58, + [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][1] = 66, + [0][0][1][0][RTW89_ETSI][1] = 58, + [0][0][1][0][RTW89_MKK][1] = 76, + [0][0][1][0][RTW89_IC][1] = 66, + [0][0][1][0][RTW89_KCC][1] = 76, + [0][0][1][0][RTW89_ACMA][1] = 58, + [0][0][1][0][RTW89_CHILE][1] = 60, + [0][0][1][0][RTW89_UKRAINE][1] = 58, + [0][0][1][0][RTW89_MEXICO][1] = 66, + [0][0][1][0][RTW89_CN][1] = 58, + [0][0][1][0][RTW89_QATAR][1] = 58, + [0][0][1][0][RTW89_UK][1] = 58, + [0][0][1][0][RTW89_FCC][2] = 70, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 76, + [0][0][1][0][RTW89_IC][2] = 70, + [0][0][1][0][RTW89_KCC][2] = 76, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CHILE][2] = 60, + [0][0][1][0][RTW89_UKRAINE][2] = 58, + [0][0][1][0][RTW89_MEXICO][2] = 70, + [0][0][1][0][RTW89_CN][2] = 58, + [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][3] = 74, + [0][0][1][0][RTW89_ETSI][3] = 58, + [0][0][1][0][RTW89_MKK][3] = 76, + [0][0][1][0][RTW89_IC][3] = 74, + [0][0][1][0][RTW89_KCC][3] = 76, + [0][0][1][0][RTW89_ACMA][3] = 58, + [0][0][1][0][RTW89_CHILE][3] = 60, + [0][0][1][0][RTW89_UKRAINE][3] = 58, + [0][0][1][0][RTW89_MEXICO][3] = 74, + [0][0][1][0][RTW89_CN][3] = 58, + [0][0][1][0][RTW89_QATAR][3] = 58, + [0][0][1][0][RTW89_UK][3] = 58, + [0][0][1][0][RTW89_FCC][4] = 78, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 76, + [0][0][1][0][RTW89_IC][4] = 78, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CHILE][4] = 60, + [0][0][1][0][RTW89_UKRAINE][4] = 58, + [0][0][1][0][RTW89_MEXICO][4] = 78, + [0][0][1][0][RTW89_CN][4] = 58, + [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][5] = 78, + [0][0][1][0][RTW89_ETSI][5] = 58, + [0][0][1][0][RTW89_MKK][5] = 76, + [0][0][1][0][RTW89_IC][5] = 78, + [0][0][1][0][RTW89_KCC][5] = 76, + [0][0][1][0][RTW89_ACMA][5] = 58, + [0][0][1][0][RTW89_CHILE][5] = 60, + [0][0][1][0][RTW89_UKRAINE][5] = 58, + [0][0][1][0][RTW89_MEXICO][5] = 78, + [0][0][1][0][RTW89_CN][5] = 58, + [0][0][1][0][RTW89_QATAR][5] = 58, + [0][0][1][0][RTW89_UK][5] = 58, + [0][0][1][0][RTW89_FCC][6] = 78, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 76, + [0][0][1][0][RTW89_IC][6] = 78, + [0][0][1][0][RTW89_KCC][6] = 76, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CHILE][6] = 60, + [0][0][1][0][RTW89_UKRAINE][6] = 58, + [0][0][1][0][RTW89_MEXICO][6] = 78, + [0][0][1][0][RTW89_CN][6] = 58, + [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][7] = 74, + [0][0][1][0][RTW89_ETSI][7] = 58, + [0][0][1][0][RTW89_MKK][7] = 76, + [0][0][1][0][RTW89_IC][7] = 74, + [0][0][1][0][RTW89_KCC][7] = 76, + [0][0][1][0][RTW89_ACMA][7] = 58, + [0][0][1][0][RTW89_CHILE][7] = 60, + [0][0][1][0][RTW89_UKRAINE][7] = 58, + [0][0][1][0][RTW89_MEXICO][7] = 74, + [0][0][1][0][RTW89_CN][7] = 58, + [0][0][1][0][RTW89_QATAR][7] = 58, + [0][0][1][0][RTW89_UK][7] = 58, + [0][0][1][0][RTW89_FCC][8] = 70, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 76, + [0][0][1][0][RTW89_IC][8] = 70, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CHILE][8] = 60, + [0][0][1][0][RTW89_UKRAINE][8] = 58, + [0][0][1][0][RTW89_MEXICO][8] = 70, + [0][0][1][0][RTW89_CN][8] = 58, + [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][9] = 66, + [0][0][1][0][RTW89_ETSI][9] = 58, + [0][0][1][0][RTW89_MKK][9] = 76, + [0][0][1][0][RTW89_IC][9] = 66, + [0][0][1][0][RTW89_KCC][9] = 76, + [0][0][1][0][RTW89_ACMA][9] = 58, + [0][0][1][0][RTW89_CHILE][9] = 60, + [0][0][1][0][RTW89_UKRAINE][9] = 58, + [0][0][1][0][RTW89_MEXICO][9] = 66, + [0][0][1][0][RTW89_CN][9] = 58, + [0][0][1][0][RTW89_QATAR][9] = 58, + [0][0][1][0][RTW89_UK][9] = 58, + [0][0][1][0][RTW89_FCC][10] = 66, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 76, + [0][0][1][0][RTW89_IC][10] = 66, + [0][0][1][0][RTW89_KCC][10] = 76, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CHILE][10] = 60, + [0][0][1][0][RTW89_UKRAINE][10] = 58, + [0][0][1][0][RTW89_MEXICO][10] = 66, + [0][0][1][0][RTW89_CN][10] = 58, + [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][11] = 56, + [0][0][1][0][RTW89_ETSI][11] = 58, + [0][0][1][0][RTW89_MKK][11] = 76, + [0][0][1][0][RTW89_IC][11] = 56, + [0][0][1][0][RTW89_KCC][11] = 76, + [0][0][1][0][RTW89_ACMA][11] = 58, + [0][0][1][0][RTW89_CHILE][11] = 56, + [0][0][1][0][RTW89_UKRAINE][11] = 58, + [0][0][1][0][RTW89_MEXICO][11] = 56, + [0][0][1][0][RTW89_CN][11] = 58, + [0][0][1][0][RTW89_QATAR][11] = 58, + [0][0][1][0][RTW89_UK][11] = 58, + [0][0][1][0][RTW89_FCC][12] = 52, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 76, + [0][0][1][0][RTW89_IC][12] = 52, + [0][0][1][0][RTW89_KCC][12] = 76, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CHILE][12] = 52, + [0][0][1][0][RTW89_UKRAINE][12] = 58, + [0][0][1][0][RTW89_MEXICO][12] = 52, + [0][0][1][0][RTW89_CN][12] = 58, + [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_KCC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_CHILE][13] = 127, + [0][0][1][0][RTW89_UKRAINE][13] = 127, + [0][0][1][0][RTW89_MEXICO][13] = 127, + [0][0][1][0][RTW89_CN][13] = 127, + [0][0][1][0][RTW89_QATAR][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 62, + [0][1][1][0][RTW89_ETSI][0] = 46, + [0][1][1][0][RTW89_MKK][0] = 64, + [0][1][1][0][RTW89_IC][0] = 62, + [0][1][1][0][RTW89_KCC][0] = 70, + [0][1][1][0][RTW89_ACMA][0] = 46, + [0][1][1][0][RTW89_CHILE][0] = 48, + [0][1][1][0][RTW89_UKRAINE][0] = 46, + [0][1][1][0][RTW89_MEXICO][0] = 62, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, + [0][1][1][0][RTW89_FCC][1] = 62, + [0][1][1][0][RTW89_ETSI][1] = 46, + [0][1][1][0][RTW89_MKK][1] = 64, + [0][1][1][0][RTW89_IC][1] = 62, + [0][1][1][0][RTW89_KCC][1] = 70, + [0][1][1][0][RTW89_ACMA][1] = 46, + [0][1][1][0][RTW89_CHILE][1] = 48, + [0][1][1][0][RTW89_UKRAINE][1] = 46, + [0][1][1][0][RTW89_MEXICO][1] = 62, + [0][1][1][0][RTW89_CN][1] = 46, + [0][1][1][0][RTW89_QATAR][1] = 46, + [0][1][1][0][RTW89_UK][1] = 46, + [0][1][1][0][RTW89_FCC][2] = 66, + [0][1][1][0][RTW89_ETSI][2] = 46, + [0][1][1][0][RTW89_MKK][2] = 64, + [0][1][1][0][RTW89_IC][2] = 66, + [0][1][1][0][RTW89_KCC][2] = 70, + [0][1][1][0][RTW89_ACMA][2] = 46, + [0][1][1][0][RTW89_CHILE][2] = 48, + [0][1][1][0][RTW89_UKRAINE][2] = 46, + [0][1][1][0][RTW89_MEXICO][2] = 66, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, + [0][1][1][0][RTW89_FCC][3] = 70, + [0][1][1][0][RTW89_ETSI][3] = 46, + [0][1][1][0][RTW89_MKK][3] = 64, + [0][1][1][0][RTW89_IC][3] = 70, + [0][1][1][0][RTW89_KCC][3] = 70, + [0][1][1][0][RTW89_ACMA][3] = 46, + [0][1][1][0][RTW89_CHILE][3] = 48, + [0][1][1][0][RTW89_UKRAINE][3] = 46, + [0][1][1][0][RTW89_MEXICO][3] = 70, + [0][1][1][0][RTW89_CN][3] = 46, + [0][1][1][0][RTW89_QATAR][3] = 46, + [0][1][1][0][RTW89_UK][3] = 46, + [0][1][1][0][RTW89_FCC][4] = 78, + [0][1][1][0][RTW89_ETSI][4] = 46, + [0][1][1][0][RTW89_MKK][4] = 64, + [0][1][1][0][RTW89_IC][4] = 78, + [0][1][1][0][RTW89_KCC][4] = 70, + [0][1][1][0][RTW89_ACMA][4] = 46, + [0][1][1][0][RTW89_CHILE][4] = 48, + [0][1][1][0][RTW89_UKRAINE][4] = 46, + [0][1][1][0][RTW89_MEXICO][4] = 78, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, + [0][1][1][0][RTW89_FCC][5] = 78, + [0][1][1][0][RTW89_ETSI][5] = 46, + [0][1][1][0][RTW89_MKK][5] = 64, + [0][1][1][0][RTW89_IC][5] = 78, + [0][1][1][0][RTW89_KCC][5] = 70, + [0][1][1][0][RTW89_ACMA][5] = 46, + [0][1][1][0][RTW89_CHILE][5] = 48, + [0][1][1][0][RTW89_UKRAINE][5] = 46, + [0][1][1][0][RTW89_MEXICO][5] = 78, + [0][1][1][0][RTW89_CN][5] = 46, + [0][1][1][0][RTW89_QATAR][5] = 46, + [0][1][1][0][RTW89_UK][5] = 46, + [0][1][1][0][RTW89_FCC][6] = 78, + [0][1][1][0][RTW89_ETSI][6] = 46, + [0][1][1][0][RTW89_MKK][6] = 64, + [0][1][1][0][RTW89_IC][6] = 78, + [0][1][1][0][RTW89_KCC][6] = 70, + [0][1][1][0][RTW89_ACMA][6] = 46, + [0][1][1][0][RTW89_CHILE][6] = 48, + [0][1][1][0][RTW89_UKRAINE][6] = 46, + [0][1][1][0][RTW89_MEXICO][6] = 78, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, + [0][1][1][0][RTW89_FCC][7] = 70, + [0][1][1][0][RTW89_ETSI][7] = 46, + [0][1][1][0][RTW89_MKK][7] = 64, + [0][1][1][0][RTW89_IC][7] = 70, + [0][1][1][0][RTW89_KCC][7] = 70, + [0][1][1][0][RTW89_ACMA][7] = 46, + [0][1][1][0][RTW89_CHILE][7] = 48, + [0][1][1][0][RTW89_UKRAINE][7] = 46, + [0][1][1][0][RTW89_MEXICO][7] = 70, + [0][1][1][0][RTW89_CN][7] = 46, + [0][1][1][0][RTW89_QATAR][7] = 46, + [0][1][1][0][RTW89_UK][7] = 46, + [0][1][1][0][RTW89_FCC][8] = 66, + [0][1][1][0][RTW89_ETSI][8] = 46, + [0][1][1][0][RTW89_MKK][8] = 64, + [0][1][1][0][RTW89_IC][8] = 66, + [0][1][1][0][RTW89_KCC][8] = 70, + [0][1][1][0][RTW89_ACMA][8] = 46, + [0][1][1][0][RTW89_CHILE][8] = 48, + [0][1][1][0][RTW89_UKRAINE][8] = 46, + [0][1][1][0][RTW89_MEXICO][8] = 66, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, + [0][1][1][0][RTW89_FCC][9] = 62, + [0][1][1][0][RTW89_ETSI][9] = 46, + [0][1][1][0][RTW89_MKK][9] = 64, + [0][1][1][0][RTW89_IC][9] = 62, + [0][1][1][0][RTW89_KCC][9] = 70, + [0][1][1][0][RTW89_ACMA][9] = 46, + [0][1][1][0][RTW89_CHILE][9] = 48, + [0][1][1][0][RTW89_UKRAINE][9] = 46, + [0][1][1][0][RTW89_MEXICO][9] = 62, + [0][1][1][0][RTW89_CN][9] = 46, + [0][1][1][0][RTW89_QATAR][9] = 46, + [0][1][1][0][RTW89_UK][9] = 46, + [0][1][1][0][RTW89_FCC][10] = 62, + [0][1][1][0][RTW89_ETSI][10] = 46, + [0][1][1][0][RTW89_MKK][10] = 64, + [0][1][1][0][RTW89_IC][10] = 62, + [0][1][1][0][RTW89_KCC][10] = 70, + [0][1][1][0][RTW89_ACMA][10] = 46, + [0][1][1][0][RTW89_CHILE][10] = 48, + [0][1][1][0][RTW89_UKRAINE][10] = 46, + [0][1][1][0][RTW89_MEXICO][10] = 62, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, + [0][1][1][0][RTW89_FCC][11] = 42, + [0][1][1][0][RTW89_ETSI][11] = 46, + [0][1][1][0][RTW89_MKK][11] = 64, + [0][1][1][0][RTW89_IC][11] = 42, + [0][1][1][0][RTW89_KCC][11] = 70, + [0][1][1][0][RTW89_ACMA][11] = 46, + [0][1][1][0][RTW89_CHILE][11] = 42, + [0][1][1][0][RTW89_UKRAINE][11] = 46, + [0][1][1][0][RTW89_MEXICO][11] = 42, + [0][1][1][0][RTW89_CN][11] = 46, + [0][1][1][0][RTW89_QATAR][11] = 46, + [0][1][1][0][RTW89_UK][11] = 46, + [0][1][1][0][RTW89_FCC][12] = 40, + [0][1][1][0][RTW89_ETSI][12] = 46, + [0][1][1][0][RTW89_MKK][12] = 64, + [0][1][1][0][RTW89_IC][12] = 40, + [0][1][1][0][RTW89_KCC][12] = 70, + [0][1][1][0][RTW89_ACMA][12] = 46, + [0][1][1][0][RTW89_CHILE][12] = 40, + [0][1][1][0][RTW89_UKRAINE][12] = 46, + [0][1][1][0][RTW89_MEXICO][12] = 40, + [0][1][1][0][RTW89_CN][12] = 46, + [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_KCC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_CHILE][13] = 127, + [0][1][1][0][RTW89_UKRAINE][13] = 127, + [0][1][1][0][RTW89_MEXICO][13] = 127, + [0][1][1][0][RTW89_CN][13] = 127, + [0][1][1][0][RTW89_QATAR][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 66, + [0][0][2][0][RTW89_ETSI][0] = 58, + [0][0][2][0][RTW89_MKK][0] = 76, + [0][0][2][0][RTW89_IC][0] = 66, + [0][0][2][0][RTW89_KCC][0] = 76, + [0][0][2][0][RTW89_ACMA][0] = 58, + [0][0][2][0][RTW89_CHILE][0] = 60, + [0][0][2][0][RTW89_UKRAINE][0] = 58, + [0][0][2][0][RTW89_MEXICO][0] = 66, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_QATAR][0] = 58, + [0][0][2][0][RTW89_UK][0] = 58, + [0][0][2][0][RTW89_FCC][1] = 66, + [0][0][2][0][RTW89_ETSI][1] = 58, + [0][0][2][0][RTW89_MKK][1] = 76, + [0][0][2][0][RTW89_IC][1] = 66, + [0][0][2][0][RTW89_KCC][1] = 76, + [0][0][2][0][RTW89_ACMA][1] = 58, + [0][0][2][0][RTW89_CHILE][1] = 60, + [0][0][2][0][RTW89_UKRAINE][1] = 58, + [0][0][2][0][RTW89_MEXICO][1] = 66, + [0][0][2][0][RTW89_CN][1] = 58, + [0][0][2][0][RTW89_QATAR][1] = 58, + [0][0][2][0][RTW89_UK][1] = 58, + [0][0][2][0][RTW89_FCC][2] = 70, + [0][0][2][0][RTW89_ETSI][2] = 58, + [0][0][2][0][RTW89_MKK][2] = 76, + [0][0][2][0][RTW89_IC][2] = 70, + [0][0][2][0][RTW89_KCC][2] = 76, + [0][0][2][0][RTW89_ACMA][2] = 58, + [0][0][2][0][RTW89_CHILE][2] = 60, + [0][0][2][0][RTW89_UKRAINE][2] = 58, + [0][0][2][0][RTW89_MEXICO][2] = 70, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_QATAR][2] = 58, + [0][0][2][0][RTW89_UK][2] = 58, + [0][0][2][0][RTW89_FCC][3] = 74, + [0][0][2][0][RTW89_ETSI][3] = 58, + [0][0][2][0][RTW89_MKK][3] = 76, + [0][0][2][0][RTW89_IC][3] = 74, + [0][0][2][0][RTW89_KCC][3] = 76, + [0][0][2][0][RTW89_ACMA][3] = 58, + [0][0][2][0][RTW89_CHILE][3] = 60, + [0][0][2][0][RTW89_UKRAINE][3] = 58, + [0][0][2][0][RTW89_MEXICO][3] = 74, + [0][0][2][0][RTW89_CN][3] = 58, + [0][0][2][0][RTW89_QATAR][3] = 58, + [0][0][2][0][RTW89_UK][3] = 58, + [0][0][2][0][RTW89_FCC][4] = 76, + [0][0][2][0][RTW89_ETSI][4] = 58, + [0][0][2][0][RTW89_MKK][4] = 76, + [0][0][2][0][RTW89_IC][4] = 76, + [0][0][2][0][RTW89_KCC][4] = 76, + [0][0][2][0][RTW89_ACMA][4] = 58, + [0][0][2][0][RTW89_CHILE][4] = 60, + [0][0][2][0][RTW89_UKRAINE][4] = 58, + [0][0][2][0][RTW89_MEXICO][4] = 76, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_QATAR][4] = 58, + [0][0][2][0][RTW89_UK][4] = 58, + [0][0][2][0][RTW89_FCC][5] = 76, + [0][0][2][0][RTW89_ETSI][5] = 58, + [0][0][2][0][RTW89_MKK][5] = 76, + [0][0][2][0][RTW89_IC][5] = 76, + [0][0][2][0][RTW89_KCC][5] = 76, + [0][0][2][0][RTW89_ACMA][5] = 58, + [0][0][2][0][RTW89_CHILE][5] = 60, + [0][0][2][0][RTW89_UKRAINE][5] = 58, + [0][0][2][0][RTW89_MEXICO][5] = 76, + [0][0][2][0][RTW89_CN][5] = 58, + [0][0][2][0][RTW89_QATAR][5] = 58, + [0][0][2][0][RTW89_UK][5] = 58, + [0][0][2][0][RTW89_FCC][6] = 76, + [0][0][2][0][RTW89_ETSI][6] = 58, + [0][0][2][0][RTW89_MKK][6] = 76, + [0][0][2][0][RTW89_IC][6] = 76, + [0][0][2][0][RTW89_KCC][6] = 76, + [0][0][2][0][RTW89_ACMA][6] = 58, + [0][0][2][0][RTW89_CHILE][6] = 60, + [0][0][2][0][RTW89_UKRAINE][6] = 58, + [0][0][2][0][RTW89_MEXICO][6] = 76, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_QATAR][6] = 58, + [0][0][2][0][RTW89_UK][6] = 58, + [0][0][2][0][RTW89_FCC][7] = 74, + [0][0][2][0][RTW89_ETSI][7] = 58, + [0][0][2][0][RTW89_MKK][7] = 76, + [0][0][2][0][RTW89_IC][7] = 74, + [0][0][2][0][RTW89_KCC][7] = 76, + [0][0][2][0][RTW89_ACMA][7] = 58, + [0][0][2][0][RTW89_CHILE][7] = 60, + [0][0][2][0][RTW89_UKRAINE][7] = 58, + [0][0][2][0][RTW89_MEXICO][7] = 74, + [0][0][2][0][RTW89_CN][7] = 58, + [0][0][2][0][RTW89_QATAR][7] = 58, + [0][0][2][0][RTW89_UK][7] = 58, + [0][0][2][0][RTW89_FCC][8] = 70, + [0][0][2][0][RTW89_ETSI][8] = 58, + [0][0][2][0][RTW89_MKK][8] = 76, + [0][0][2][0][RTW89_IC][8] = 70, + [0][0][2][0][RTW89_KCC][8] = 76, + [0][0][2][0][RTW89_ACMA][8] = 58, + [0][0][2][0][RTW89_CHILE][8] = 60, + [0][0][2][0][RTW89_UKRAINE][8] = 58, + [0][0][2][0][RTW89_MEXICO][8] = 70, + [0][0][2][0][RTW89_CN][8] = 58, + [0][0][2][0][RTW89_QATAR][8] = 58, + [0][0][2][0][RTW89_UK][8] = 58, + [0][0][2][0][RTW89_FCC][9] = 66, + [0][0][2][0][RTW89_ETSI][9] = 58, + [0][0][2][0][RTW89_MKK][9] = 76, + [0][0][2][0][RTW89_IC][9] = 66, + [0][0][2][0][RTW89_KCC][9] = 76, + [0][0][2][0][RTW89_ACMA][9] = 58, + [0][0][2][0][RTW89_CHILE][9] = 60, + [0][0][2][0][RTW89_UKRAINE][9] = 58, + [0][0][2][0][RTW89_MEXICO][9] = 66, + [0][0][2][0][RTW89_CN][9] = 58, + [0][0][2][0][RTW89_QATAR][9] = 58, + [0][0][2][0][RTW89_UK][9] = 58, + [0][0][2][0][RTW89_FCC][10] = 66, + [0][0][2][0][RTW89_ETSI][10] = 58, + [0][0][2][0][RTW89_MKK][10] = 76, + [0][0][2][0][RTW89_IC][10] = 66, + [0][0][2][0][RTW89_KCC][10] = 76, + [0][0][2][0][RTW89_ACMA][10] = 58, + [0][0][2][0][RTW89_CHILE][10] = 60, + [0][0][2][0][RTW89_UKRAINE][10] = 58, + [0][0][2][0][RTW89_MEXICO][10] = 66, + [0][0][2][0][RTW89_CN][10] = 58, + [0][0][2][0][RTW89_QATAR][10] = 58, + [0][0][2][0][RTW89_UK][10] = 58, + [0][0][2][0][RTW89_FCC][11] = 54, + [0][0][2][0][RTW89_ETSI][11] = 58, + [0][0][2][0][RTW89_MKK][11] = 76, + [0][0][2][0][RTW89_IC][11] = 54, + [0][0][2][0][RTW89_KCC][11] = 76, + [0][0][2][0][RTW89_ACMA][11] = 58, + [0][0][2][0][RTW89_CHILE][11] = 54, + [0][0][2][0][RTW89_UKRAINE][11] = 58, + [0][0][2][0][RTW89_MEXICO][11] = 54, + [0][0][2][0][RTW89_CN][11] = 58, + [0][0][2][0][RTW89_QATAR][11] = 58, + [0][0][2][0][RTW89_UK][11] = 58, + [0][0][2][0][RTW89_FCC][12] = 50, + [0][0][2][0][RTW89_ETSI][12] = 58, + [0][0][2][0][RTW89_MKK][12] = 76, + [0][0][2][0][RTW89_IC][12] = 50, + [0][0][2][0][RTW89_KCC][12] = 74, + [0][0][2][0][RTW89_ACMA][12] = 58, + [0][0][2][0][RTW89_CHILE][12] = 50, + [0][0][2][0][RTW89_UKRAINE][12] = 58, + [0][0][2][0][RTW89_MEXICO][12] = 50, + [0][0][2][0][RTW89_CN][12] = 58, + [0][0][2][0][RTW89_QATAR][12] = 58, + [0][0][2][0][RTW89_UK][12] = 58, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_KCC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_CHILE][13] = 127, + [0][0][2][0][RTW89_UKRAINE][13] = 127, + [0][0][2][0][RTW89_MEXICO][13] = 127, + [0][0][2][0][RTW89_CN][13] = 127, + [0][0][2][0][RTW89_QATAR][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 62, + [0][1][2][0][RTW89_ETSI][0] = 46, + [0][1][2][0][RTW89_MKK][0] = 64, + [0][1][2][0][RTW89_IC][0] = 62, + [0][1][2][0][RTW89_KCC][0] = 68, + [0][1][2][0][RTW89_ACMA][0] = 46, + [0][1][2][0][RTW89_CHILE][0] = 48, + [0][1][2][0][RTW89_UKRAINE][0] = 46, + [0][1][2][0][RTW89_MEXICO][0] = 62, + [0][1][2][0][RTW89_CN][0] = 46, + [0][1][2][0][RTW89_QATAR][0] = 46, + [0][1][2][0][RTW89_UK][0] = 46, + [0][1][2][0][RTW89_FCC][1] = 62, + [0][1][2][0][RTW89_ETSI][1] = 46, + [0][1][2][0][RTW89_MKK][1] = 64, + [0][1][2][0][RTW89_IC][1] = 62, + [0][1][2][0][RTW89_KCC][1] = 70, + [0][1][2][0][RTW89_ACMA][1] = 46, + [0][1][2][0][RTW89_CHILE][1] = 48, + [0][1][2][0][RTW89_UKRAINE][1] = 46, + [0][1][2][0][RTW89_MEXICO][1] = 62, + [0][1][2][0][RTW89_CN][1] = 46, + [0][1][2][0][RTW89_QATAR][1] = 46, + [0][1][2][0][RTW89_UK][1] = 46, + [0][1][2][0][RTW89_FCC][2] = 66, + [0][1][2][0][RTW89_ETSI][2] = 46, + [0][1][2][0][RTW89_MKK][2] = 64, + [0][1][2][0][RTW89_IC][2] = 66, + [0][1][2][0][RTW89_KCC][2] = 70, + [0][1][2][0][RTW89_ACMA][2] = 46, + [0][1][2][0][RTW89_CHILE][2] = 48, + [0][1][2][0][RTW89_UKRAINE][2] = 46, + [0][1][2][0][RTW89_MEXICO][2] = 66, + [0][1][2][0][RTW89_CN][2] = 46, + [0][1][2][0][RTW89_QATAR][2] = 46, + [0][1][2][0][RTW89_UK][2] = 46, + [0][1][2][0][RTW89_FCC][3] = 70, + [0][1][2][0][RTW89_ETSI][3] = 46, + [0][1][2][0][RTW89_MKK][3] = 64, + [0][1][2][0][RTW89_IC][3] = 70, + [0][1][2][0][RTW89_KCC][3] = 70, + [0][1][2][0][RTW89_ACMA][3] = 46, + [0][1][2][0][RTW89_CHILE][3] = 48, + [0][1][2][0][RTW89_UKRAINE][3] = 46, + [0][1][2][0][RTW89_MEXICO][3] = 70, + [0][1][2][0][RTW89_CN][3] = 46, + [0][1][2][0][RTW89_QATAR][3] = 46, + [0][1][2][0][RTW89_UK][3] = 46, + [0][1][2][0][RTW89_FCC][4] = 76, + [0][1][2][0][RTW89_ETSI][4] = 46, + [0][1][2][0][RTW89_MKK][4] = 64, + [0][1][2][0][RTW89_IC][4] = 76, + [0][1][2][0][RTW89_KCC][4] = 70, + [0][1][2][0][RTW89_ACMA][4] = 46, + [0][1][2][0][RTW89_CHILE][4] = 48, + [0][1][2][0][RTW89_UKRAINE][4] = 46, + [0][1][2][0][RTW89_MEXICO][4] = 76, + [0][1][2][0][RTW89_CN][4] = 46, + [0][1][2][0][RTW89_QATAR][4] = 46, + [0][1][2][0][RTW89_UK][4] = 46, + [0][1][2][0][RTW89_FCC][5] = 76, + [0][1][2][0][RTW89_ETSI][5] = 46, + [0][1][2][0][RTW89_MKK][5] = 64, + [0][1][2][0][RTW89_IC][5] = 76, + [0][1][2][0][RTW89_KCC][5] = 70, + [0][1][2][0][RTW89_ACMA][5] = 46, + [0][1][2][0][RTW89_CHILE][5] = 48, + [0][1][2][0][RTW89_UKRAINE][5] = 46, + [0][1][2][0][RTW89_MEXICO][5] = 76, + [0][1][2][0][RTW89_CN][5] = 46, + [0][1][2][0][RTW89_QATAR][5] = 46, + [0][1][2][0][RTW89_UK][5] = 46, + [0][1][2][0][RTW89_FCC][6] = 76, + [0][1][2][0][RTW89_ETSI][6] = 46, + [0][1][2][0][RTW89_MKK][6] = 64, + [0][1][2][0][RTW89_IC][6] = 76, + [0][1][2][0][RTW89_KCC][6] = 70, + [0][1][2][0][RTW89_ACMA][6] = 46, + [0][1][2][0][RTW89_CHILE][6] = 48, + [0][1][2][0][RTW89_UKRAINE][6] = 46, + [0][1][2][0][RTW89_MEXICO][6] = 76, + [0][1][2][0][RTW89_CN][6] = 46, + [0][1][2][0][RTW89_QATAR][6] = 46, + [0][1][2][0][RTW89_UK][6] = 46, + [0][1][2][0][RTW89_FCC][7] = 68, + [0][1][2][0][RTW89_ETSI][7] = 46, + [0][1][2][0][RTW89_MKK][7] = 64, + [0][1][2][0][RTW89_IC][7] = 68, + [0][1][2][0][RTW89_KCC][7] = 70, + [0][1][2][0][RTW89_ACMA][7] = 46, + [0][1][2][0][RTW89_CHILE][7] = 48, + [0][1][2][0][RTW89_UKRAINE][7] = 46, + [0][1][2][0][RTW89_MEXICO][7] = 68, + [0][1][2][0][RTW89_CN][7] = 46, + [0][1][2][0][RTW89_QATAR][7] = 46, + [0][1][2][0][RTW89_UK][7] = 46, + [0][1][2][0][RTW89_FCC][8] = 64, + [0][1][2][0][RTW89_ETSI][8] = 46, + [0][1][2][0][RTW89_MKK][8] = 64, + [0][1][2][0][RTW89_IC][8] = 64, + [0][1][2][0][RTW89_KCC][8] = 70, + [0][1][2][0][RTW89_ACMA][8] = 46, + [0][1][2][0][RTW89_CHILE][8] = 48, + [0][1][2][0][RTW89_UKRAINE][8] = 46, + [0][1][2][0][RTW89_MEXICO][8] = 64, + [0][1][2][0][RTW89_CN][8] = 46, + [0][1][2][0][RTW89_QATAR][8] = 46, + [0][1][2][0][RTW89_UK][8] = 46, + [0][1][2][0][RTW89_FCC][9] = 60, + [0][1][2][0][RTW89_ETSI][9] = 46, + [0][1][2][0][RTW89_MKK][9] = 64, + [0][1][2][0][RTW89_IC][9] = 60, + [0][1][2][0][RTW89_KCC][9] = 70, + [0][1][2][0][RTW89_ACMA][9] = 46, + [0][1][2][0][RTW89_CHILE][9] = 48, + [0][1][2][0][RTW89_UKRAINE][9] = 46, + [0][1][2][0][RTW89_MEXICO][9] = 60, + [0][1][2][0][RTW89_CN][9] = 46, + [0][1][2][0][RTW89_QATAR][9] = 46, + [0][1][2][0][RTW89_UK][9] = 46, + [0][1][2][0][RTW89_FCC][10] = 60, + [0][1][2][0][RTW89_ETSI][10] = 46, + [0][1][2][0][RTW89_MKK][10] = 64, + [0][1][2][0][RTW89_IC][10] = 60, + [0][1][2][0][RTW89_KCC][10] = 70, + [0][1][2][0][RTW89_ACMA][10] = 46, + [0][1][2][0][RTW89_CHILE][10] = 48, + [0][1][2][0][RTW89_UKRAINE][10] = 46, + [0][1][2][0][RTW89_MEXICO][10] = 60, + [0][1][2][0][RTW89_CN][10] = 46, + [0][1][2][0][RTW89_QATAR][10] = 46, + [0][1][2][0][RTW89_UK][10] = 46, + [0][1][2][0][RTW89_FCC][11] = 42, + [0][1][2][0][RTW89_ETSI][11] = 46, + [0][1][2][0][RTW89_MKK][11] = 64, + [0][1][2][0][RTW89_IC][11] = 42, + [0][1][2][0][RTW89_KCC][11] = 70, + [0][1][2][0][RTW89_ACMA][11] = 46, + [0][1][2][0][RTW89_CHILE][11] = 42, + [0][1][2][0][RTW89_UKRAINE][11] = 46, + [0][1][2][0][RTW89_MEXICO][11] = 42, + [0][1][2][0][RTW89_CN][11] = 46, + [0][1][2][0][RTW89_QATAR][11] = 46, + [0][1][2][0][RTW89_UK][11] = 46, + [0][1][2][0][RTW89_FCC][12] = 40, + [0][1][2][0][RTW89_ETSI][12] = 46, + [0][1][2][0][RTW89_MKK][12] = 64, + [0][1][2][0][RTW89_IC][12] = 40, + [0][1][2][0][RTW89_KCC][12] = 68, + [0][1][2][0][RTW89_ACMA][12] = 46, + [0][1][2][0][RTW89_CHILE][12] = 40, + [0][1][2][0][RTW89_UKRAINE][12] = 46, + [0][1][2][0][RTW89_MEXICO][12] = 40, + [0][1][2][0][RTW89_CN][12] = 46, + [0][1][2][0][RTW89_QATAR][12] = 46, + [0][1][2][0][RTW89_UK][12] = 46, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_KCC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_CHILE][13] = 127, + [0][1][2][0][RTW89_UKRAINE][13] = 127, + [0][1][2][0][RTW89_MEXICO][13] = 127, + [0][1][2][0][RTW89_CN][13] = 127, + [0][1][2][0][RTW89_QATAR][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 62, + [0][1][2][1][RTW89_ETSI][0] = 34, + [0][1][2][1][RTW89_MKK][0] = 64, + [0][1][2][1][RTW89_IC][0] = 62, + [0][1][2][1][RTW89_KCC][0] = 68, + [0][1][2][1][RTW89_ACMA][0] = 34, + [0][1][2][1][RTW89_CHILE][0] = 36, + [0][1][2][1][RTW89_UKRAINE][0] = 34, + [0][1][2][1][RTW89_MEXICO][0] = 62, + [0][1][2][1][RTW89_CN][0] = 34, + [0][1][2][1][RTW89_QATAR][0] = 34, + [0][1][2][1][RTW89_UK][0] = 34, + [0][1][2][1][RTW89_FCC][1] = 62, + [0][1][2][1][RTW89_ETSI][1] = 34, + [0][1][2][1][RTW89_MKK][1] = 64, + [0][1][2][1][RTW89_IC][1] = 62, + [0][1][2][1][RTW89_KCC][1] = 70, + [0][1][2][1][RTW89_ACMA][1] = 34, + [0][1][2][1][RTW89_CHILE][1] = 36, + [0][1][2][1][RTW89_UKRAINE][1] = 34, + [0][1][2][1][RTW89_MEXICO][1] = 62, + [0][1][2][1][RTW89_CN][1] = 34, + [0][1][2][1][RTW89_QATAR][1] = 34, + [0][1][2][1][RTW89_UK][1] = 34, + [0][1][2][1][RTW89_FCC][2] = 66, + [0][1][2][1][RTW89_ETSI][2] = 34, + [0][1][2][1][RTW89_MKK][2] = 64, + [0][1][2][1][RTW89_IC][2] = 66, + [0][1][2][1][RTW89_KCC][2] = 70, + [0][1][2][1][RTW89_ACMA][2] = 34, + [0][1][2][1][RTW89_CHILE][2] = 36, + [0][1][2][1][RTW89_UKRAINE][2] = 34, + [0][1][2][1][RTW89_MEXICO][2] = 66, + [0][1][2][1][RTW89_CN][2] = 34, + [0][1][2][1][RTW89_QATAR][2] = 34, + [0][1][2][1][RTW89_UK][2] = 34, + [0][1][2][1][RTW89_FCC][3] = 70, + [0][1][2][1][RTW89_ETSI][3] = 34, + [0][1][2][1][RTW89_MKK][3] = 64, + [0][1][2][1][RTW89_IC][3] = 70, + [0][1][2][1][RTW89_KCC][3] = 70, + [0][1][2][1][RTW89_ACMA][3] = 34, + [0][1][2][1][RTW89_CHILE][3] = 36, + [0][1][2][1][RTW89_UKRAINE][3] = 34, + [0][1][2][1][RTW89_MEXICO][3] = 70, + [0][1][2][1][RTW89_CN][3] = 34, + [0][1][2][1][RTW89_QATAR][3] = 34, + [0][1][2][1][RTW89_UK][3] = 34, + [0][1][2][1][RTW89_FCC][4] = 76, + [0][1][2][1][RTW89_ETSI][4] = 34, + [0][1][2][1][RTW89_MKK][4] = 64, + [0][1][2][1][RTW89_IC][4] = 76, + [0][1][2][1][RTW89_KCC][4] = 70, + [0][1][2][1][RTW89_ACMA][4] = 34, + [0][1][2][1][RTW89_CHILE][4] = 36, + [0][1][2][1][RTW89_UKRAINE][4] = 34, + [0][1][2][1][RTW89_MEXICO][4] = 76, + [0][1][2][1][RTW89_CN][4] = 34, + [0][1][2][1][RTW89_QATAR][4] = 34, + [0][1][2][1][RTW89_UK][4] = 34, + [0][1][2][1][RTW89_FCC][5] = 76, + [0][1][2][1][RTW89_ETSI][5] = 34, + [0][1][2][1][RTW89_MKK][5] = 64, + [0][1][2][1][RTW89_IC][5] = 76, + [0][1][2][1][RTW89_KCC][5] = 70, + [0][1][2][1][RTW89_ACMA][5] = 34, + [0][1][2][1][RTW89_CHILE][5] = 36, + [0][1][2][1][RTW89_UKRAINE][5] = 34, + [0][1][2][1][RTW89_MEXICO][5] = 76, + [0][1][2][1][RTW89_CN][5] = 34, + [0][1][2][1][RTW89_QATAR][5] = 34, + [0][1][2][1][RTW89_UK][5] = 34, + [0][1][2][1][RTW89_FCC][6] = 76, + [0][1][2][1][RTW89_ETSI][6] = 34, + [0][1][2][1][RTW89_MKK][6] = 64, + [0][1][2][1][RTW89_IC][6] = 76, + [0][1][2][1][RTW89_KCC][6] = 70, + [0][1][2][1][RTW89_ACMA][6] = 34, + [0][1][2][1][RTW89_CHILE][6] = 36, + [0][1][2][1][RTW89_UKRAINE][6] = 34, + [0][1][2][1][RTW89_MEXICO][6] = 76, + [0][1][2][1][RTW89_CN][6] = 34, + [0][1][2][1][RTW89_QATAR][6] = 34, + [0][1][2][1][RTW89_UK][6] = 34, + [0][1][2][1][RTW89_FCC][7] = 68, + [0][1][2][1][RTW89_ETSI][7] = 34, + [0][1][2][1][RTW89_MKK][7] = 64, + [0][1][2][1][RTW89_IC][7] = 68, + [0][1][2][1][RTW89_KCC][7] = 70, + [0][1][2][1][RTW89_ACMA][7] = 34, + [0][1][2][1][RTW89_CHILE][7] = 36, + [0][1][2][1][RTW89_UKRAINE][7] = 34, + [0][1][2][1][RTW89_MEXICO][7] = 68, + [0][1][2][1][RTW89_CN][7] = 34, + [0][1][2][1][RTW89_QATAR][7] = 34, + [0][1][2][1][RTW89_UK][7] = 34, + [0][1][2][1][RTW89_FCC][8] = 64, + [0][1][2][1][RTW89_ETSI][8] = 34, + [0][1][2][1][RTW89_MKK][8] = 64, + [0][1][2][1][RTW89_IC][8] = 64, + [0][1][2][1][RTW89_KCC][8] = 70, + [0][1][2][1][RTW89_ACMA][8] = 34, + [0][1][2][1][RTW89_CHILE][8] = 36, + [0][1][2][1][RTW89_UKRAINE][8] = 34, + [0][1][2][1][RTW89_MEXICO][8] = 64, + [0][1][2][1][RTW89_CN][8] = 34, + [0][1][2][1][RTW89_QATAR][8] = 34, + [0][1][2][1][RTW89_UK][8] = 34, + [0][1][2][1][RTW89_FCC][9] = 60, + [0][1][2][1][RTW89_ETSI][9] = 34, + [0][1][2][1][RTW89_MKK][9] = 64, + [0][1][2][1][RTW89_IC][9] = 60, + [0][1][2][1][RTW89_KCC][9] = 70, + [0][1][2][1][RTW89_ACMA][9] = 34, + [0][1][2][1][RTW89_CHILE][9] = 36, + [0][1][2][1][RTW89_UKRAINE][9] = 34, + [0][1][2][1][RTW89_MEXICO][9] = 60, + [0][1][2][1][RTW89_CN][9] = 34, + [0][1][2][1][RTW89_QATAR][9] = 34, + [0][1][2][1][RTW89_UK][9] = 34, + [0][1][2][1][RTW89_FCC][10] = 60, + [0][1][2][1][RTW89_ETSI][10] = 34, + [0][1][2][1][RTW89_MKK][10] = 64, + [0][1][2][1][RTW89_IC][10] = 60, + [0][1][2][1][RTW89_KCC][10] = 70, + [0][1][2][1][RTW89_ACMA][10] = 34, + [0][1][2][1][RTW89_CHILE][10] = 36, + [0][1][2][1][RTW89_UKRAINE][10] = 34, + [0][1][2][1][RTW89_MEXICO][10] = 60, + [0][1][2][1][RTW89_CN][10] = 34, + [0][1][2][1][RTW89_QATAR][10] = 34, + [0][1][2][1][RTW89_UK][10] = 34, + [0][1][2][1][RTW89_FCC][11] = 42, + [0][1][2][1][RTW89_ETSI][11] = 34, + [0][1][2][1][RTW89_MKK][11] = 64, + [0][1][2][1][RTW89_IC][11] = 42, + [0][1][2][1][RTW89_KCC][11] = 70, + [0][1][2][1][RTW89_ACMA][11] = 34, + [0][1][2][1][RTW89_CHILE][11] = 36, + [0][1][2][1][RTW89_UKRAINE][11] = 34, + [0][1][2][1][RTW89_MEXICO][11] = 42, + [0][1][2][1][RTW89_CN][11] = 34, + [0][1][2][1][RTW89_QATAR][11] = 34, + [0][1][2][1][RTW89_UK][11] = 34, + [0][1][2][1][RTW89_FCC][12] = 40, + [0][1][2][1][RTW89_ETSI][12] = 34, + [0][1][2][1][RTW89_MKK][12] = 64, + [0][1][2][1][RTW89_IC][12] = 40, + [0][1][2][1][RTW89_KCC][12] = 68, + [0][1][2][1][RTW89_ACMA][12] = 34, + [0][1][2][1][RTW89_CHILE][12] = 36, + [0][1][2][1][RTW89_UKRAINE][12] = 34, + [0][1][2][1][RTW89_MEXICO][12] = 40, + [0][1][2][1][RTW89_CN][12] = 34, + [0][1][2][1][RTW89_QATAR][12] = 34, + [0][1][2][1][RTW89_UK][12] = 34, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_KCC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_CHILE][13] = 127, + [0][1][2][1][RTW89_UKRAINE][13] = 127, + [0][1][2][1][RTW89_MEXICO][13] = 127, + [0][1][2][1][RTW89_CN][13] = 127, + [0][1][2][1][RTW89_QATAR][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_KCC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_CHILE][0] = 127, + [1][0][2][0][RTW89_UKRAINE][0] = 127, + [1][0][2][0][RTW89_MEXICO][0] = 127, + [1][0][2][0][RTW89_CN][0] = 127, + [1][0][2][0][RTW89_QATAR][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_KCC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_CHILE][1] = 127, + [1][0][2][0][RTW89_UKRAINE][1] = 127, + [1][0][2][0][RTW89_MEXICO][1] = 127, + [1][0][2][0][RTW89_CN][1] = 127, + [1][0][2][0][RTW89_QATAR][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 56, + [1][0][2][0][RTW89_ETSI][2] = 58, + [1][0][2][0][RTW89_MKK][2] = 68, + [1][0][2][0][RTW89_IC][2] = 56, + [1][0][2][0][RTW89_KCC][2] = 68, + [1][0][2][0][RTW89_ACMA][2] = 58, + [1][0][2][0][RTW89_CHILE][2] = 56, + [1][0][2][0][RTW89_UKRAINE][2] = 58, + [1][0][2][0][RTW89_MEXICO][2] = 56, + [1][0][2][0][RTW89_CN][2] = 58, + [1][0][2][0][RTW89_QATAR][2] = 58, + [1][0][2][0][RTW89_UK][2] = 58, + [1][0][2][0][RTW89_FCC][3] = 56, + [1][0][2][0][RTW89_ETSI][3] = 58, + [1][0][2][0][RTW89_MKK][3] = 68, + [1][0][2][0][RTW89_IC][3] = 56, + [1][0][2][0][RTW89_KCC][3] = 68, + [1][0][2][0][RTW89_ACMA][3] = 58, + [1][0][2][0][RTW89_CHILE][3] = 56, + [1][0][2][0][RTW89_UKRAINE][3] = 58, + [1][0][2][0][RTW89_MEXICO][3] = 56, + [1][0][2][0][RTW89_CN][3] = 58, + [1][0][2][0][RTW89_QATAR][3] = 58, + [1][0][2][0][RTW89_UK][3] = 58, + [1][0][2][0][RTW89_FCC][4] = 60, + [1][0][2][0][RTW89_ETSI][4] = 58, + [1][0][2][0][RTW89_MKK][4] = 68, + [1][0][2][0][RTW89_IC][4] = 60, + [1][0][2][0][RTW89_KCC][4] = 68, + [1][0][2][0][RTW89_ACMA][4] = 58, + [1][0][2][0][RTW89_CHILE][4] = 60, + [1][0][2][0][RTW89_UKRAINE][4] = 58, + [1][0][2][0][RTW89_MEXICO][4] = 60, + [1][0][2][0][RTW89_CN][4] = 58, + [1][0][2][0][RTW89_QATAR][4] = 58, + [1][0][2][0][RTW89_UK][4] = 58, + [1][0][2][0][RTW89_FCC][5] = 64, + [1][0][2][0][RTW89_ETSI][5] = 58, + [1][0][2][0][RTW89_MKK][5] = 68, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 68, + [1][0][2][0][RTW89_ACMA][5] = 58, + [1][0][2][0][RTW89_CHILE][5] = 60, + [1][0][2][0][RTW89_UKRAINE][5] = 58, + [1][0][2][0][RTW89_MEXICO][5] = 64, + [1][0][2][0][RTW89_CN][5] = 58, + [1][0][2][0][RTW89_QATAR][5] = 58, + [1][0][2][0][RTW89_UK][5] = 58, + [1][0][2][0][RTW89_FCC][6] = 54, + [1][0][2][0][RTW89_ETSI][6] = 58, + [1][0][2][0][RTW89_MKK][6] = 68, + [1][0][2][0][RTW89_IC][6] = 54, + [1][0][2][0][RTW89_KCC][6] = 68, + [1][0][2][0][RTW89_ACMA][6] = 58, + [1][0][2][0][RTW89_CHILE][6] = 54, + [1][0][2][0][RTW89_UKRAINE][6] = 58, + [1][0][2][0][RTW89_MEXICO][6] = 54, + [1][0][2][0][RTW89_CN][6] = 58, + [1][0][2][0][RTW89_QATAR][6] = 58, + [1][0][2][0][RTW89_UK][6] = 58, + [1][0][2][0][RTW89_FCC][7] = 50, + [1][0][2][0][RTW89_ETSI][7] = 58, + [1][0][2][0][RTW89_MKK][7] = 68, + [1][0][2][0][RTW89_IC][7] = 50, + [1][0][2][0][RTW89_KCC][7] = 68, + [1][0][2][0][RTW89_ACMA][7] = 58, + [1][0][2][0][RTW89_CHILE][7] = 50, + [1][0][2][0][RTW89_UKRAINE][7] = 58, + [1][0][2][0][RTW89_MEXICO][7] = 50, + [1][0][2][0][RTW89_CN][7] = 58, + [1][0][2][0][RTW89_QATAR][7] = 58, + [1][0][2][0][RTW89_UK][7] = 58, + [1][0][2][0][RTW89_FCC][8] = 50, + [1][0][2][0][RTW89_ETSI][8] = 58, + [1][0][2][0][RTW89_MKK][8] = 68, + [1][0][2][0][RTW89_IC][8] = 50, + [1][0][2][0][RTW89_KCC][8] = 68, + [1][0][2][0][RTW89_ACMA][8] = 58, + [1][0][2][0][RTW89_CHILE][8] = 50, + [1][0][2][0][RTW89_UKRAINE][8] = 58, + [1][0][2][0][RTW89_MEXICO][8] = 50, + [1][0][2][0][RTW89_CN][8] = 58, + [1][0][2][0][RTW89_QATAR][8] = 58, + [1][0][2][0][RTW89_UK][8] = 58, + [1][0][2][0][RTW89_FCC][9] = 42, + [1][0][2][0][RTW89_ETSI][9] = 58, + [1][0][2][0][RTW89_MKK][9] = 68, + [1][0][2][0][RTW89_IC][9] = 42, + [1][0][2][0][RTW89_KCC][9] = 68, + [1][0][2][0][RTW89_ACMA][9] = 58, + [1][0][2][0][RTW89_CHILE][9] = 42, + [1][0][2][0][RTW89_UKRAINE][9] = 58, + [1][0][2][0][RTW89_MEXICO][9] = 42, + [1][0][2][0][RTW89_CN][9] = 58, + [1][0][2][0][RTW89_QATAR][9] = 58, + [1][0][2][0][RTW89_UK][9] = 58, + [1][0][2][0][RTW89_FCC][10] = 40, + [1][0][2][0][RTW89_ETSI][10] = 58, + [1][0][2][0][RTW89_MKK][10] = 68, + [1][0][2][0][RTW89_IC][10] = 40, + [1][0][2][0][RTW89_KCC][10] = 68, + [1][0][2][0][RTW89_ACMA][10] = 58, + [1][0][2][0][RTW89_CHILE][10] = 40, + [1][0][2][0][RTW89_UKRAINE][10] = 58, + [1][0][2][0][RTW89_MEXICO][10] = 40, + [1][0][2][0][RTW89_CN][10] = 58, + [1][0][2][0][RTW89_QATAR][10] = 58, + [1][0][2][0][RTW89_UK][10] = 58, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_KCC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_CHILE][11] = 127, + [1][0][2][0][RTW89_UKRAINE][11] = 127, + [1][0][2][0][RTW89_MEXICO][11] = 127, + [1][0][2][0][RTW89_CN][11] = 127, + [1][0][2][0][RTW89_QATAR][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_KCC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_CHILE][12] = 127, + [1][0][2][0][RTW89_UKRAINE][12] = 127, + [1][0][2][0][RTW89_MEXICO][12] = 127, + [1][0][2][0][RTW89_CN][12] = 127, + [1][0][2][0][RTW89_QATAR][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_KCC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_CHILE][13] = 127, + [1][0][2][0][RTW89_UKRAINE][13] = 127, + [1][0][2][0][RTW89_MEXICO][13] = 127, + [1][0][2][0][RTW89_CN][13] = 127, + [1][0][2][0][RTW89_QATAR][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_KCC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_CHILE][0] = 127, + [1][1][2][0][RTW89_UKRAINE][0] = 127, + [1][1][2][0][RTW89_MEXICO][0] = 127, + [1][1][2][0][RTW89_CN][0] = 127, + [1][1][2][0][RTW89_QATAR][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CHILE][1] = 127, + [1][1][2][0][RTW89_UKRAINE][1] = 127, + [1][1][2][0][RTW89_MEXICO][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_QATAR][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 52, + [1][1][2][0][RTW89_ETSI][2] = 46, + [1][1][2][0][RTW89_MKK][2] = 64, + [1][1][2][0][RTW89_IC][2] = 52, + [1][1][2][0][RTW89_KCC][2] = 66, + [1][1][2][0][RTW89_ACMA][2] = 46, + [1][1][2][0][RTW89_CHILE][2] = 48, + [1][1][2][0][RTW89_UKRAINE][2] = 46, + [1][1][2][0][RTW89_MEXICO][2] = 52, + [1][1][2][0][RTW89_CN][2] = 46, + [1][1][2][0][RTW89_QATAR][2] = 46, + [1][1][2][0][RTW89_UK][2] = 46, + [1][1][2][0][RTW89_FCC][3] = 52, + [1][1][2][0][RTW89_ETSI][3] = 46, + [1][1][2][0][RTW89_MKK][3] = 64, + [1][1][2][0][RTW89_IC][3] = 52, + [1][1][2][0][RTW89_KCC][3] = 68, + [1][1][2][0][RTW89_ACMA][3] = 46, + [1][1][2][0][RTW89_CHILE][3] = 48, + [1][1][2][0][RTW89_UKRAINE][3] = 46, + [1][1][2][0][RTW89_MEXICO][3] = 52, + [1][1][2][0][RTW89_CN][3] = 46, + [1][1][2][0][RTW89_QATAR][3] = 46, + [1][1][2][0][RTW89_UK][3] = 46, + [1][1][2][0][RTW89_FCC][4] = 56, + [1][1][2][0][RTW89_ETSI][4] = 46, + [1][1][2][0][RTW89_MKK][4] = 64, + [1][1][2][0][RTW89_IC][4] = 56, + [1][1][2][0][RTW89_KCC][4] = 68, + [1][1][2][0][RTW89_ACMA][4] = 46, + [1][1][2][0][RTW89_CHILE][4] = 48, + [1][1][2][0][RTW89_UKRAINE][4] = 46, + [1][1][2][0][RTW89_MEXICO][4] = 56, + [1][1][2][0][RTW89_CN][4] = 46, + [1][1][2][0][RTW89_QATAR][4] = 46, + [1][1][2][0][RTW89_UK][4] = 46, + [1][1][2][0][RTW89_FCC][5] = 60, + [1][1][2][0][RTW89_ETSI][5] = 46, + [1][1][2][0][RTW89_MKK][5] = 64, + [1][1][2][0][RTW89_IC][5] = 60, + [1][1][2][0][RTW89_KCC][5] = 68, + [1][1][2][0][RTW89_ACMA][5] = 46, + [1][1][2][0][RTW89_CHILE][5] = 48, + [1][1][2][0][RTW89_UKRAINE][5] = 46, + [1][1][2][0][RTW89_MEXICO][5] = 60, + [1][1][2][0][RTW89_CN][5] = 46, + [1][1][2][0][RTW89_QATAR][5] = 46, + [1][1][2][0][RTW89_UK][5] = 46, + [1][1][2][0][RTW89_FCC][6] = 54, + [1][1][2][0][RTW89_ETSI][6] = 46, + [1][1][2][0][RTW89_MKK][6] = 64, + [1][1][2][0][RTW89_IC][6] = 52, + [1][1][2][0][RTW89_KCC][6] = 68, + [1][1][2][0][RTW89_ACMA][6] = 46, + [1][1][2][0][RTW89_CHILE][6] = 48, + [1][1][2][0][RTW89_UKRAINE][6] = 46, + [1][1][2][0][RTW89_MEXICO][6] = 54, + [1][1][2][0][RTW89_CN][6] = 46, + [1][1][2][0][RTW89_QATAR][6] = 46, + [1][1][2][0][RTW89_UK][6] = 46, + [1][1][2][0][RTW89_FCC][7] = 50, + [1][1][2][0][RTW89_ETSI][7] = 46, + [1][1][2][0][RTW89_MKK][7] = 64, + [1][1][2][0][RTW89_IC][7] = 48, + [1][1][2][0][RTW89_KCC][7] = 68, + [1][1][2][0][RTW89_ACMA][7] = 46, + [1][1][2][0][RTW89_CHILE][7] = 48, + [1][1][2][0][RTW89_UKRAINE][7] = 46, + [1][1][2][0][RTW89_MEXICO][7] = 50, + [1][1][2][0][RTW89_CN][7] = 46, + [1][1][2][0][RTW89_QATAR][7] = 46, + [1][1][2][0][RTW89_UK][7] = 46, + [1][1][2][0][RTW89_FCC][8] = 50, + [1][1][2][0][RTW89_ETSI][8] = 46, + [1][1][2][0][RTW89_MKK][8] = 64, + [1][1][2][0][RTW89_IC][8] = 48, + [1][1][2][0][RTW89_KCC][8] = 68, + [1][1][2][0][RTW89_ACMA][8] = 46, + [1][1][2][0][RTW89_CHILE][8] = 48, + [1][1][2][0][RTW89_UKRAINE][8] = 46, + [1][1][2][0][RTW89_MEXICO][8] = 50, + [1][1][2][0][RTW89_CN][8] = 46, + [1][1][2][0][RTW89_QATAR][8] = 46, + [1][1][2][0][RTW89_UK][8] = 46, + [1][1][2][0][RTW89_FCC][9] = 38, + [1][1][2][0][RTW89_ETSI][9] = 46, + [1][1][2][0][RTW89_MKK][9] = 64, + [1][1][2][0][RTW89_IC][9] = 38, + [1][1][2][0][RTW89_KCC][9] = 68, + [1][1][2][0][RTW89_ACMA][9] = 46, + [1][1][2][0][RTW89_CHILE][9] = 38, + [1][1][2][0][RTW89_UKRAINE][9] = 46, + [1][1][2][0][RTW89_MEXICO][9] = 38, + [1][1][2][0][RTW89_CN][9] = 46, + [1][1][2][0][RTW89_QATAR][9] = 46, + [1][1][2][0][RTW89_UK][9] = 46, + [1][1][2][0][RTW89_FCC][10] = 36, + [1][1][2][0][RTW89_ETSI][10] = 46, + [1][1][2][0][RTW89_MKK][10] = 64, + [1][1][2][0][RTW89_IC][10] = 36, + [1][1][2][0][RTW89_KCC][10] = 66, + [1][1][2][0][RTW89_ACMA][10] = 46, + [1][1][2][0][RTW89_CHILE][10] = 36, + [1][1][2][0][RTW89_UKRAINE][10] = 46, + [1][1][2][0][RTW89_MEXICO][10] = 36, + [1][1][2][0][RTW89_CN][10] = 46, + [1][1][2][0][RTW89_QATAR][10] = 46, + [1][1][2][0][RTW89_UK][10] = 46, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_KCC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_CHILE][11] = 127, + [1][1][2][0][RTW89_UKRAINE][11] = 127, + [1][1][2][0][RTW89_MEXICO][11] = 127, + [1][1][2][0][RTW89_CN][11] = 127, + [1][1][2][0][RTW89_QATAR][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_KCC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_CHILE][12] = 127, + [1][1][2][0][RTW89_UKRAINE][12] = 127, + [1][1][2][0][RTW89_MEXICO][12] = 127, + [1][1][2][0][RTW89_CN][12] = 127, + [1][1][2][0][RTW89_QATAR][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CHILE][13] = 127, + [1][1][2][0][RTW89_UKRAINE][13] = 127, + [1][1][2][0][RTW89_MEXICO][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_QATAR][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_KCC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_CHILE][0] = 127, + [1][1][2][1][RTW89_UKRAINE][0] = 127, + [1][1][2][1][RTW89_MEXICO][0] = 127, + [1][1][2][1][RTW89_CN][0] = 127, + [1][1][2][1][RTW89_QATAR][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CHILE][1] = 127, + [1][1][2][1][RTW89_UKRAINE][1] = 127, + [1][1][2][1][RTW89_MEXICO][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_QATAR][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 52, + [1][1][2][1][RTW89_ETSI][2] = 34, + [1][1][2][1][RTW89_MKK][2] = 64, + [1][1][2][1][RTW89_IC][2] = 52, + [1][1][2][1][RTW89_KCC][2] = 66, + [1][1][2][1][RTW89_ACMA][2] = 34, + [1][1][2][1][RTW89_CHILE][2] = 36, + [1][1][2][1][RTW89_UKRAINE][2] = 34, + [1][1][2][1][RTW89_MEXICO][2] = 52, + [1][1][2][1][RTW89_CN][2] = 34, + [1][1][2][1][RTW89_QATAR][2] = 34, + [1][1][2][1][RTW89_UK][2] = 34, + [1][1][2][1][RTW89_FCC][3] = 52, + [1][1][2][1][RTW89_ETSI][3] = 34, + [1][1][2][1][RTW89_MKK][3] = 64, + [1][1][2][1][RTW89_IC][3] = 52, + [1][1][2][1][RTW89_KCC][3] = 68, + [1][1][2][1][RTW89_ACMA][3] = 34, + [1][1][2][1][RTW89_CHILE][3] = 36, + [1][1][2][1][RTW89_UKRAINE][3] = 34, + [1][1][2][1][RTW89_MEXICO][3] = 52, + [1][1][2][1][RTW89_CN][3] = 34, + [1][1][2][1][RTW89_QATAR][3] = 34, + [1][1][2][1][RTW89_UK][3] = 34, + [1][1][2][1][RTW89_FCC][4] = 56, + [1][1][2][1][RTW89_ETSI][4] = 34, + [1][1][2][1][RTW89_MKK][4] = 64, + [1][1][2][1][RTW89_IC][4] = 56, + [1][1][2][1][RTW89_KCC][4] = 68, + [1][1][2][1][RTW89_ACMA][4] = 34, + [1][1][2][1][RTW89_CHILE][4] = 36, + [1][1][2][1][RTW89_UKRAINE][4] = 34, + [1][1][2][1][RTW89_MEXICO][4] = 56, + [1][1][2][1][RTW89_CN][4] = 34, + [1][1][2][1][RTW89_QATAR][4] = 34, + [1][1][2][1][RTW89_UK][4] = 34, + [1][1][2][1][RTW89_FCC][5] = 60, + [1][1][2][1][RTW89_ETSI][5] = 34, + [1][1][2][1][RTW89_MKK][5] = 64, + [1][1][2][1][RTW89_IC][5] = 60, + [1][1][2][1][RTW89_KCC][5] = 68, + [1][1][2][1][RTW89_ACMA][5] = 34, + [1][1][2][1][RTW89_CHILE][5] = 36, + [1][1][2][1][RTW89_UKRAINE][5] = 34, + [1][1][2][1][RTW89_MEXICO][5] = 60, + [1][1][2][1][RTW89_CN][5] = 34, + [1][1][2][1][RTW89_QATAR][5] = 34, + [1][1][2][1][RTW89_UK][5] = 34, + [1][1][2][1][RTW89_FCC][6] = 54, + [1][1][2][1][RTW89_ETSI][6] = 34, + [1][1][2][1][RTW89_MKK][6] = 64, + [1][1][2][1][RTW89_IC][6] = 52, + [1][1][2][1][RTW89_KCC][6] = 68, + [1][1][2][1][RTW89_ACMA][6] = 34, + [1][1][2][1][RTW89_CHILE][6] = 36, + [1][1][2][1][RTW89_UKRAINE][6] = 34, + [1][1][2][1][RTW89_MEXICO][6] = 54, + [1][1][2][1][RTW89_CN][6] = 34, + [1][1][2][1][RTW89_QATAR][6] = 34, + [1][1][2][1][RTW89_UK][6] = 34, + [1][1][2][1][RTW89_FCC][7] = 50, + [1][1][2][1][RTW89_ETSI][7] = 34, + [1][1][2][1][RTW89_MKK][7] = 64, + [1][1][2][1][RTW89_IC][7] = 48, + [1][1][2][1][RTW89_KCC][7] = 68, + [1][1][2][1][RTW89_ACMA][7] = 34, + [1][1][2][1][RTW89_CHILE][7] = 36, + [1][1][2][1][RTW89_UKRAINE][7] = 34, + [1][1][2][1][RTW89_MEXICO][7] = 50, + [1][1][2][1][RTW89_CN][7] = 34, + [1][1][2][1][RTW89_QATAR][7] = 34, + [1][1][2][1][RTW89_UK][7] = 34, + [1][1][2][1][RTW89_FCC][8] = 50, + [1][1][2][1][RTW89_ETSI][8] = 34, + [1][1][2][1][RTW89_MKK][8] = 64, + [1][1][2][1][RTW89_IC][8] = 48, + [1][1][2][1][RTW89_KCC][8] = 68, + [1][1][2][1][RTW89_ACMA][8] = 34, + [1][1][2][1][RTW89_CHILE][8] = 36, + [1][1][2][1][RTW89_UKRAINE][8] = 34, + [1][1][2][1][RTW89_MEXICO][8] = 50, + [1][1][2][1][RTW89_CN][8] = 34, + [1][1][2][1][RTW89_QATAR][8] = 34, + [1][1][2][1][RTW89_UK][8] = 34, + [1][1][2][1][RTW89_FCC][9] = 38, + [1][1][2][1][RTW89_ETSI][9] = 34, + [1][1][2][1][RTW89_MKK][9] = 64, + [1][1][2][1][RTW89_IC][9] = 38, + [1][1][2][1][RTW89_KCC][9] = 68, + [1][1][2][1][RTW89_ACMA][9] = 34, + [1][1][2][1][RTW89_CHILE][9] = 36, + [1][1][2][1][RTW89_UKRAINE][9] = 34, + [1][1][2][1][RTW89_MEXICO][9] = 38, + [1][1][2][1][RTW89_CN][9] = 34, + [1][1][2][1][RTW89_QATAR][9] = 34, + [1][1][2][1][RTW89_UK][9] = 34, + [1][1][2][1][RTW89_FCC][10] = 36, + [1][1][2][1][RTW89_ETSI][10] = 34, + [1][1][2][1][RTW89_MKK][10] = 64, + [1][1][2][1][RTW89_IC][10] = 36, + [1][1][2][1][RTW89_KCC][10] = 66, + [1][1][2][1][RTW89_ACMA][10] = 34, + [1][1][2][1][RTW89_CHILE][10] = 36, + [1][1][2][1][RTW89_UKRAINE][10] = 34, + [1][1][2][1][RTW89_MEXICO][10] = 36, + [1][1][2][1][RTW89_CN][10] = 34, + [1][1][2][1][RTW89_QATAR][10] = 34, + [1][1][2][1][RTW89_UK][10] = 34, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_KCC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_CHILE][11] = 127, + [1][1][2][1][RTW89_UKRAINE][11] = 127, + [1][1][2][1][RTW89_MEXICO][11] = 127, + [1][1][2][1][RTW89_CN][11] = 127, + [1][1][2][1][RTW89_QATAR][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_KCC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_CHILE][12] = 127, + [1][1][2][1][RTW89_UKRAINE][12] = 127, + [1][1][2][1][RTW89_MEXICO][12] = 127, + [1][1][2][1][RTW89_CN][12] = 127, + [1][1][2][1][RTW89_QATAR][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CHILE][13] = 127, + [1][1][2][1][RTW89_UKRAINE][13] = 127, + [1][1][2][1][RTW89_MEXICO][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_QATAR][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 30, + [0][0][1][0][RTW89_WW][2] = 30, + [0][0][1][0][RTW89_WW][4] = 30, + [0][0][1][0][RTW89_WW][6] = 30, + [0][0][1][0][RTW89_WW][8] = 52, + [0][0][1][0][RTW89_WW][10] = 52, + [0][0][1][0][RTW89_WW][12] = 52, + [0][0][1][0][RTW89_WW][14] = 52, + [0][0][1][0][RTW89_WW][15] = 52, + [0][0][1][0][RTW89_WW][17] = 52, + [0][0][1][0][RTW89_WW][19] = 52, + [0][0][1][0][RTW89_WW][21] = 52, + [0][0][1][0][RTW89_WW][23] = 52, + [0][0][1][0][RTW89_WW][25] = 52, + [0][0][1][0][RTW89_WW][27] = 52, + [0][0][1][0][RTW89_WW][29] = 52, + [0][0][1][0][RTW89_WW][31] = 52, + [0][0][1][0][RTW89_WW][33] = 52, + [0][0][1][0][RTW89_WW][35] = 52, + [0][0][1][0][RTW89_WW][37] = 54, + [0][0][1][0][RTW89_WW][38] = 28, + [0][0][1][0][RTW89_WW][40] = 28, + [0][0][1][0][RTW89_WW][42] = 28, + [0][0][1][0][RTW89_WW][44] = 28, + [0][0][1][0][RTW89_WW][46] = 28, + [0][1][1][0][RTW89_WW][0] = 18, + [0][1][1][0][RTW89_WW][2] = 18, + [0][1][1][0][RTW89_WW][4] = 18, + [0][1][1][0][RTW89_WW][6] = 18, + [0][1][1][0][RTW89_WW][8] = 40, + [0][1][1][0][RTW89_WW][10] = 40, + [0][1][1][0][RTW89_WW][12] = 40, + [0][1][1][0][RTW89_WW][14] = 40, + [0][1][1][0][RTW89_WW][15] = 40, + [0][1][1][0][RTW89_WW][17] = 40, + [0][1][1][0][RTW89_WW][19] = 40, + [0][1][1][0][RTW89_WW][21] = 40, + [0][1][1][0][RTW89_WW][23] = 40, + [0][1][1][0][RTW89_WW][25] = 40, + [0][1][1][0][RTW89_WW][27] = 40, + [0][1][1][0][RTW89_WW][29] = 40, + [0][1][1][0][RTW89_WW][31] = 40, + [0][1][1][0][RTW89_WW][33] = 40, + [0][1][1][0][RTW89_WW][35] = 40, + [0][1][1][0][RTW89_WW][37] = 42, + [0][1][1][0][RTW89_WW][38] = 16, + [0][1][1][0][RTW89_WW][40] = 16, + [0][1][1][0][RTW89_WW][42] = 16, + [0][1][1][0][RTW89_WW][44] = 16, + [0][1][1][0][RTW89_WW][46] = 16, + [0][0][2][0][RTW89_WW][0] = 30, + [0][0][2][0][RTW89_WW][2] = 30, + [0][0][2][0][RTW89_WW][4] = 30, + [0][0][2][0][RTW89_WW][6] = 30, + [0][0][2][0][RTW89_WW][8] = 52, + [0][0][2][0][RTW89_WW][10] = 52, + [0][0][2][0][RTW89_WW][12] = 52, + [0][0][2][0][RTW89_WW][14] = 52, + [0][0][2][0][RTW89_WW][15] = 52, + [0][0][2][0][RTW89_WW][17] = 52, + [0][0][2][0][RTW89_WW][19] = 52, + [0][0][2][0][RTW89_WW][21] = 52, + [0][0][2][0][RTW89_WW][23] = 52, + [0][0][2][0][RTW89_WW][25] = 52, + [0][0][2][0][RTW89_WW][27] = 52, + [0][0][2][0][RTW89_WW][29] = 52, + [0][0][2][0][RTW89_WW][31] = 52, + [0][0][2][0][RTW89_WW][33] = 52, + [0][0][2][0][RTW89_WW][35] = 52, + [0][0][2][0][RTW89_WW][37] = 54, + [0][0][2][0][RTW89_WW][38] = 28, + [0][0][2][0][RTW89_WW][40] = 28, + [0][0][2][0][RTW89_WW][42] = 28, + [0][0][2][0][RTW89_WW][44] = 28, + [0][0][2][0][RTW89_WW][46] = 28, + [0][1][2][0][RTW89_WW][0] = 18, + [0][1][2][0][RTW89_WW][2] = 18, + [0][1][2][0][RTW89_WW][4] = 18, + [0][1][2][0][RTW89_WW][6] = 18, + [0][1][2][0][RTW89_WW][8] = 40, + [0][1][2][0][RTW89_WW][10] = 40, + [0][1][2][0][RTW89_WW][12] = 40, + [0][1][2][0][RTW89_WW][14] = 40, + [0][1][2][0][RTW89_WW][15] = 40, + [0][1][2][0][RTW89_WW][17] = 40, + [0][1][2][0][RTW89_WW][19] = 40, + [0][1][2][0][RTW89_WW][21] = 40, + [0][1][2][0][RTW89_WW][23] = 40, + [0][1][2][0][RTW89_WW][25] = 40, + [0][1][2][0][RTW89_WW][27] = 40, + [0][1][2][0][RTW89_WW][29] = 40, + [0][1][2][0][RTW89_WW][31] = 40, + [0][1][2][0][RTW89_WW][33] = 40, + [0][1][2][0][RTW89_WW][35] = 40, + [0][1][2][0][RTW89_WW][37] = 42, + [0][1][2][0][RTW89_WW][38] = 16, + [0][1][2][0][RTW89_WW][40] = 16, + [0][1][2][0][RTW89_WW][42] = 16, + [0][1][2][0][RTW89_WW][44] = 16, + [0][1][2][0][RTW89_WW][46] = 16, + [0][1][2][1][RTW89_WW][0] = 6, + [0][1][2][1][RTW89_WW][2] = 6, + [0][1][2][1][RTW89_WW][4] = 6, + [0][1][2][1][RTW89_WW][6] = 6, + [0][1][2][1][RTW89_WW][8] = 28, + [0][1][2][1][RTW89_WW][10] = 28, + [0][1][2][1][RTW89_WW][12] = 28, + [0][1][2][1][RTW89_WW][14] = 28, + [0][1][2][1][RTW89_WW][15] = 28, + [0][1][2][1][RTW89_WW][17] = 28, + [0][1][2][1][RTW89_WW][19] = 28, + [0][1][2][1][RTW89_WW][21] = 28, + [0][1][2][1][RTW89_WW][23] = 28, + [0][1][2][1][RTW89_WW][25] = 28, + [0][1][2][1][RTW89_WW][27] = 28, + [0][1][2][1][RTW89_WW][29] = 28, + [0][1][2][1][RTW89_WW][31] = 28, + [0][1][2][1][RTW89_WW][33] = 28, + [0][1][2][1][RTW89_WW][35] = 28, + [0][1][2][1][RTW89_WW][37] = 30, + [0][1][2][1][RTW89_WW][38] = 4, + [0][1][2][1][RTW89_WW][40] = 4, + [0][1][2][1][RTW89_WW][42] = 4, + [0][1][2][1][RTW89_WW][44] = 4, + [0][1][2][1][RTW89_WW][46] = 4, + [1][0][2][0][RTW89_WW][1] = 30, + [1][0][2][0][RTW89_WW][5] = 30, + [1][0][2][0][RTW89_WW][9] = 52, + [1][0][2][0][RTW89_WW][13] = 52, + [1][0][2][0][RTW89_WW][16] = 52, + [1][0][2][0][RTW89_WW][20] = 52, + [1][0][2][0][RTW89_WW][24] = 52, + [1][0][2][0][RTW89_WW][28] = 52, + [1][0][2][0][RTW89_WW][32] = 52, + [1][0][2][0][RTW89_WW][36] = 54, + [1][0][2][0][RTW89_WW][39] = 28, + [1][0][2][0][RTW89_WW][43] = 28, + [1][1][2][0][RTW89_WW][1] = 18, + [1][1][2][0][RTW89_WW][5] = 18, + [1][1][2][0][RTW89_WW][9] = 40, + [1][1][2][0][RTW89_WW][13] = 40, + [1][1][2][0][RTW89_WW][16] = 40, + [1][1][2][0][RTW89_WW][20] = 40, + [1][1][2][0][RTW89_WW][24] = 40, + [1][1][2][0][RTW89_WW][28] = 40, + [1][1][2][0][RTW89_WW][32] = 40, + [1][1][2][0][RTW89_WW][36] = 42, + [1][1][2][0][RTW89_WW][39] = 16, + [1][1][2][0][RTW89_WW][43] = 16, + [1][1][2][1][RTW89_WW][1] = 6, + [1][1][2][1][RTW89_WW][5] = 6, + [1][1][2][1][RTW89_WW][9] = 28, + [1][1][2][1][RTW89_WW][13] = 28, + [1][1][2][1][RTW89_WW][16] = 28, + [1][1][2][1][RTW89_WW][20] = 28, + [1][1][2][1][RTW89_WW][24] = 28, + [1][1][2][1][RTW89_WW][28] = 28, + [1][1][2][1][RTW89_WW][32] = 28, + [1][1][2][1][RTW89_WW][36] = 30, + [1][1][2][1][RTW89_WW][39] = 4, + [1][1][2][1][RTW89_WW][43] = 4, + [2][0][2][0][RTW89_WW][3] = 30, + [2][0][2][0][RTW89_WW][11] = 52, + [2][0][2][0][RTW89_WW][18] = 52, + [2][0][2][0][RTW89_WW][26] = 52, + [2][0][2][0][RTW89_WW][34] = 54, + [2][0][2][0][RTW89_WW][41] = 28, + [2][1][2][0][RTW89_WW][3] = 18, + [2][1][2][0][RTW89_WW][11] = 40, + [2][1][2][0][RTW89_WW][18] = 40, + [2][1][2][0][RTW89_WW][26] = 40, + [2][1][2][0][RTW89_WW][34] = 42, + [2][1][2][0][RTW89_WW][41] = 16, + [2][1][2][1][RTW89_WW][3] = 6, + [2][1][2][1][RTW89_WW][11] = 28, + [2][1][2][1][RTW89_WW][18] = 28, + [2][1][2][1][RTW89_WW][26] = 28, + [2][1][2][1][RTW89_WW][34] = 30, + [2][1][2][1][RTW89_WW][41] = 4, + [0][0][1][0][RTW89_FCC][0] = 76, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 62, + [0][0][1][0][RTW89_IC][0] = 62, + [0][0][1][0][RTW89_KCC][0] = 76, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CHILE][0] = 30, + [0][0][1][0][RTW89_UKRAINE][0] = 52, + [0][0][1][0][RTW89_MEXICO][0] = 62, + [0][0][1][0][RTW89_CN][0] = 58, + [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][2] = 76, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 62, + [0][0][1][0][RTW89_IC][2] = 62, + [0][0][1][0][RTW89_KCC][2] = 76, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CHILE][2] = 30, + [0][0][1][0][RTW89_UKRAINE][2] = 52, + [0][0][1][0][RTW89_MEXICO][2] = 62, + [0][0][1][0][RTW89_CN][2] = 58, + [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][4] = 76, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 62, + [0][0][1][0][RTW89_IC][4] = 62, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CHILE][4] = 30, + [0][0][1][0][RTW89_UKRAINE][4] = 52, + [0][0][1][0][RTW89_MEXICO][4] = 62, + [0][0][1][0][RTW89_CN][4] = 58, + [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][6] = 76, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 62, + [0][0][1][0][RTW89_IC][6] = 62, + [0][0][1][0][RTW89_KCC][6] = 58, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CHILE][6] = 30, + [0][0][1][0][RTW89_UKRAINE][6] = 52, + [0][0][1][0][RTW89_MEXICO][6] = 62, + [0][0][1][0][RTW89_CN][6] = 58, + [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][8] = 76, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 62, + [0][0][1][0][RTW89_IC][8] = 64, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CHILE][8] = 54, + [0][0][1][0][RTW89_UKRAINE][8] = 52, + [0][0][1][0][RTW89_MEXICO][8] = 76, + [0][0][1][0][RTW89_CN][8] = 58, + [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][10] = 76, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 62, + [0][0][1][0][RTW89_IC][10] = 64, + [0][0][1][0][RTW89_KCC][10] = 76, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CHILE][10] = 54, + [0][0][1][0][RTW89_UKRAINE][10] = 52, + [0][0][1][0][RTW89_MEXICO][10] = 76, + [0][0][1][0][RTW89_CN][10] = 58, + [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][12] = 76, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 62, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 76, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CHILE][12] = 54, + [0][0][1][0][RTW89_UKRAINE][12] = 52, + [0][0][1][0][RTW89_MEXICO][12] = 76, + [0][0][1][0][RTW89_CN][12] = 58, + [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][14] = 76, + [0][0][1][0][RTW89_ETSI][14] = 58, + [0][0][1][0][RTW89_MKK][14] = 62, + [0][0][1][0][RTW89_IC][14] = 64, + [0][0][1][0][RTW89_KCC][14] = 76, + [0][0][1][0][RTW89_ACMA][14] = 58, + [0][0][1][0][RTW89_CHILE][14] = 54, + [0][0][1][0][RTW89_UKRAINE][14] = 52, + [0][0][1][0][RTW89_MEXICO][14] = 76, + [0][0][1][0][RTW89_CN][14] = 58, + [0][0][1][0][RTW89_QATAR][14] = 58, + [0][0][1][0][RTW89_UK][14] = 58, + [0][0][1][0][RTW89_FCC][15] = 76, + [0][0][1][0][RTW89_ETSI][15] = 58, + [0][0][1][0][RTW89_MKK][15] = 76, + [0][0][1][0][RTW89_IC][15] = 76, + [0][0][1][0][RTW89_KCC][15] = 76, + [0][0][1][0][RTW89_ACMA][15] = 58, + [0][0][1][0][RTW89_CHILE][15] = 54, + [0][0][1][0][RTW89_UKRAINE][15] = 52, + [0][0][1][0][RTW89_MEXICO][15] = 76, + [0][0][1][0][RTW89_CN][15] = 127, + [0][0][1][0][RTW89_QATAR][15] = 52, + [0][0][1][0][RTW89_UK][15] = 58, + [0][0][1][0][RTW89_FCC][17] = 76, + [0][0][1][0][RTW89_ETSI][17] = 58, + [0][0][1][0][RTW89_MKK][17] = 76, + [0][0][1][0][RTW89_IC][17] = 76, + [0][0][1][0][RTW89_KCC][17] = 76, + [0][0][1][0][RTW89_ACMA][17] = 58, + [0][0][1][0][RTW89_CHILE][17] = 54, + [0][0][1][0][RTW89_UKRAINE][17] = 52, + [0][0][1][0][RTW89_MEXICO][17] = 76, + [0][0][1][0][RTW89_CN][17] = 127, + [0][0][1][0][RTW89_QATAR][17] = 52, + [0][0][1][0][RTW89_UK][17] = 58, + [0][0][1][0][RTW89_FCC][19] = 76, + [0][0][1][0][RTW89_ETSI][19] = 58, + [0][0][1][0][RTW89_MKK][19] = 76, + [0][0][1][0][RTW89_IC][19] = 76, + [0][0][1][0][RTW89_KCC][19] = 76, + [0][0][1][0][RTW89_ACMA][19] = 58, + [0][0][1][0][RTW89_CHILE][19] = 54, + [0][0][1][0][RTW89_UKRAINE][19] = 52, + [0][0][1][0][RTW89_MEXICO][19] = 76, + [0][0][1][0][RTW89_CN][19] = 127, + [0][0][1][0][RTW89_QATAR][19] = 52, + [0][0][1][0][RTW89_UK][19] = 58, + [0][0][1][0][RTW89_FCC][21] = 76, + [0][0][1][0][RTW89_ETSI][21] = 58, + [0][0][1][0][RTW89_MKK][21] = 76, + [0][0][1][0][RTW89_IC][21] = 76, + [0][0][1][0][RTW89_KCC][21] = 76, + [0][0][1][0][RTW89_ACMA][21] = 58, + [0][0][1][0][RTW89_CHILE][21] = 54, + [0][0][1][0][RTW89_UKRAINE][21] = 52, + [0][0][1][0][RTW89_MEXICO][21] = 76, + [0][0][1][0][RTW89_CN][21] = 127, + [0][0][1][0][RTW89_QATAR][21] = 52, + [0][0][1][0][RTW89_UK][21] = 58, + [0][0][1][0][RTW89_FCC][23] = 76, + [0][0][1][0][RTW89_ETSI][23] = 58, + [0][0][1][0][RTW89_MKK][23] = 76, + [0][0][1][0][RTW89_IC][23] = 76, + [0][0][1][0][RTW89_KCC][23] = 76, + [0][0][1][0][RTW89_ACMA][23] = 58, + [0][0][1][0][RTW89_CHILE][23] = 54, + [0][0][1][0][RTW89_UKRAINE][23] = 52, + [0][0][1][0][RTW89_MEXICO][23] = 76, + [0][0][1][0][RTW89_CN][23] = 127, + [0][0][1][0][RTW89_QATAR][23] = 52, + [0][0][1][0][RTW89_UK][23] = 58, + [0][0][1][0][RTW89_FCC][25] = 76, + [0][0][1][0][RTW89_ETSI][25] = 58, + [0][0][1][0][RTW89_MKK][25] = 76, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_KCC][25] = 76, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_CHILE][25] = 54, + [0][0][1][0][RTW89_UKRAINE][25] = 52, + [0][0][1][0][RTW89_MEXICO][25] = 76, + [0][0][1][0][RTW89_CN][25] = 127, + [0][0][1][0][RTW89_QATAR][25] = 52, + [0][0][1][0][RTW89_UK][25] = 58, + [0][0][1][0][RTW89_FCC][27] = 76, + [0][0][1][0][RTW89_ETSI][27] = 58, + [0][0][1][0][RTW89_MKK][27] = 76, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_KCC][27] = 76, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_CHILE][27] = 54, + [0][0][1][0][RTW89_UKRAINE][27] = 52, + [0][0][1][0][RTW89_MEXICO][27] = 76, + [0][0][1][0][RTW89_CN][27] = 127, + [0][0][1][0][RTW89_QATAR][27] = 52, + [0][0][1][0][RTW89_UK][27] = 58, + [0][0][1][0][RTW89_FCC][29] = 76, + [0][0][1][0][RTW89_ETSI][29] = 58, + [0][0][1][0][RTW89_MKK][29] = 76, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_KCC][29] = 76, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_CHILE][29] = 54, + [0][0][1][0][RTW89_UKRAINE][29] = 52, + [0][0][1][0][RTW89_MEXICO][29] = 76, + [0][0][1][0][RTW89_CN][29] = 127, + [0][0][1][0][RTW89_QATAR][29] = 52, + [0][0][1][0][RTW89_UK][29] = 58, + [0][0][1][0][RTW89_FCC][31] = 76, + [0][0][1][0][RTW89_ETSI][31] = 58, + [0][0][1][0][RTW89_MKK][31] = 76, + [0][0][1][0][RTW89_IC][31] = 76, + [0][0][1][0][RTW89_KCC][31] = 76, + [0][0][1][0][RTW89_ACMA][31] = 58, + [0][0][1][0][RTW89_CHILE][31] = 54, + [0][0][1][0][RTW89_UKRAINE][31] = 52, + [0][0][1][0][RTW89_MEXICO][31] = 76, + [0][0][1][0][RTW89_CN][31] = 127, + [0][0][1][0][RTW89_QATAR][31] = 52, + [0][0][1][0][RTW89_UK][31] = 58, + [0][0][1][0][RTW89_FCC][33] = 76, + [0][0][1][0][RTW89_ETSI][33] = 58, + [0][0][1][0][RTW89_MKK][33] = 76, + [0][0][1][0][RTW89_IC][33] = 76, + [0][0][1][0][RTW89_KCC][33] = 76, + [0][0][1][0][RTW89_ACMA][33] = 58, + [0][0][1][0][RTW89_CHILE][33] = 54, + [0][0][1][0][RTW89_UKRAINE][33] = 52, + [0][0][1][0][RTW89_MEXICO][33] = 76, + [0][0][1][0][RTW89_CN][33] = 127, + [0][0][1][0][RTW89_QATAR][33] = 52, + [0][0][1][0][RTW89_UK][33] = 58, + [0][0][1][0][RTW89_FCC][35] = 74, + [0][0][1][0][RTW89_ETSI][35] = 58, + [0][0][1][0][RTW89_MKK][35] = 76, + [0][0][1][0][RTW89_IC][35] = 74, + [0][0][1][0][RTW89_KCC][35] = 76, + [0][0][1][0][RTW89_ACMA][35] = 58, + [0][0][1][0][RTW89_CHILE][35] = 54, + [0][0][1][0][RTW89_UKRAINE][35] = 52, + [0][0][1][0][RTW89_MEXICO][35] = 74, + [0][0][1][0][RTW89_CN][35] = 127, + [0][0][1][0][RTW89_QATAR][35] = 52, + [0][0][1][0][RTW89_UK][35] = 58, + [0][0][1][0][RTW89_FCC][37] = 76, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 76, + [0][0][1][0][RTW89_IC][37] = 76, + [0][0][1][0][RTW89_KCC][37] = 76, + [0][0][1][0][RTW89_ACMA][37] = 76, + [0][0][1][0][RTW89_CHILE][37] = 54, + [0][0][1][0][RTW89_UKRAINE][37] = 127, + [0][0][1][0][RTW89_MEXICO][37] = 76, + [0][0][1][0][RTW89_CN][37] = 127, + [0][0][1][0][RTW89_QATAR][37] = 127, + [0][0][1][0][RTW89_UK][37] = 76, + [0][0][1][0][RTW89_FCC][38] = 76, + [0][0][1][0][RTW89_ETSI][38] = 28, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 76, + [0][0][1][0][RTW89_KCC][38] = 76, + [0][0][1][0][RTW89_ACMA][38] = 76, + [0][0][1][0][RTW89_CHILE][38] = 54, + [0][0][1][0][RTW89_UKRAINE][38] = 28, + [0][0][1][0][RTW89_MEXICO][38] = 76, + [0][0][1][0][RTW89_CN][38] = 72, + [0][0][1][0][RTW89_QATAR][38] = 28, + [0][0][1][0][RTW89_UK][38] = 56, + [0][0][1][0][RTW89_FCC][40] = 76, + [0][0][1][0][RTW89_ETSI][40] = 28, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 76, + [0][0][1][0][RTW89_KCC][40] = 76, + [0][0][1][0][RTW89_ACMA][40] = 76, + [0][0][1][0][RTW89_CHILE][40] = 54, + [0][0][1][0][RTW89_UKRAINE][40] = 28, + [0][0][1][0][RTW89_MEXICO][40] = 76, + [0][0][1][0][RTW89_CN][40] = 76, + [0][0][1][0][RTW89_QATAR][40] = 28, + [0][0][1][0][RTW89_UK][40] = 56, + [0][0][1][0][RTW89_FCC][42] = 76, + [0][0][1][0][RTW89_ETSI][42] = 28, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 76, + [0][0][1][0][RTW89_KCC][42] = 76, + [0][0][1][0][RTW89_ACMA][42] = 76, + [0][0][1][0][RTW89_CHILE][42] = 54, + [0][0][1][0][RTW89_UKRAINE][42] = 28, + [0][0][1][0][RTW89_MEXICO][42] = 76, + [0][0][1][0][RTW89_CN][42] = 76, + [0][0][1][0][RTW89_QATAR][42] = 28, + [0][0][1][0][RTW89_UK][42] = 56, + [0][0][1][0][RTW89_FCC][44] = 76, + [0][0][1][0][RTW89_ETSI][44] = 28, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 76, + [0][0][1][0][RTW89_KCC][44] = 76, + [0][0][1][0][RTW89_ACMA][44] = 76, + [0][0][1][0][RTW89_CHILE][44] = 54, + [0][0][1][0][RTW89_UKRAINE][44] = 28, + [0][0][1][0][RTW89_MEXICO][44] = 76, + [0][0][1][0][RTW89_CN][44] = 76, + [0][0][1][0][RTW89_QATAR][44] = 28, + [0][0][1][0][RTW89_UK][44] = 56, + [0][0][1][0][RTW89_FCC][46] = 76, + [0][0][1][0][RTW89_ETSI][46] = 28, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 76, + [0][0][1][0][RTW89_KCC][46] = 76, + [0][0][1][0][RTW89_ACMA][46] = 76, + [0][0][1][0][RTW89_CHILE][46] = 54, + [0][0][1][0][RTW89_UKRAINE][46] = 28, + [0][0][1][0][RTW89_MEXICO][46] = 76, + [0][0][1][0][RTW89_CN][46] = 76, + [0][0][1][0][RTW89_QATAR][46] = 28, + [0][0][1][0][RTW89_UK][46] = 56, + [0][1][1][0][RTW89_FCC][0] = 68, + [0][1][1][0][RTW89_ETSI][0] = 46, + [0][1][1][0][RTW89_MKK][0] = 50, + [0][1][1][0][RTW89_IC][0] = 40, + [0][1][1][0][RTW89_KCC][0] = 72, + [0][1][1][0][RTW89_ACMA][0] = 46, + [0][1][1][0][RTW89_CHILE][0] = 18, + [0][1][1][0][RTW89_UKRAINE][0] = 40, + [0][1][1][0][RTW89_MEXICO][0] = 50, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, + [0][1][1][0][RTW89_FCC][2] = 68, + [0][1][1][0][RTW89_ETSI][2] = 46, + [0][1][1][0][RTW89_MKK][2] = 50, + [0][1][1][0][RTW89_IC][2] = 40, + [0][1][1][0][RTW89_KCC][2] = 72, + [0][1][1][0][RTW89_ACMA][2] = 46, + [0][1][1][0][RTW89_CHILE][2] = 18, + [0][1][1][0][RTW89_UKRAINE][2] = 40, + [0][1][1][0][RTW89_MEXICO][2] = 50, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, + [0][1][1][0][RTW89_FCC][4] = 68, + [0][1][1][0][RTW89_ETSI][4] = 46, + [0][1][1][0][RTW89_MKK][4] = 50, + [0][1][1][0][RTW89_IC][4] = 40, + [0][1][1][0][RTW89_KCC][4] = 72, + [0][1][1][0][RTW89_ACMA][4] = 46, + [0][1][1][0][RTW89_CHILE][4] = 18, + [0][1][1][0][RTW89_UKRAINE][4] = 40, + [0][1][1][0][RTW89_MEXICO][4] = 50, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, + [0][1][1][0][RTW89_FCC][6] = 68, + [0][1][1][0][RTW89_ETSI][6] = 46, + [0][1][1][0][RTW89_MKK][6] = 50, + [0][1][1][0][RTW89_IC][6] = 40, + [0][1][1][0][RTW89_KCC][6] = 44, + [0][1][1][0][RTW89_ACMA][6] = 46, + [0][1][1][0][RTW89_CHILE][6] = 18, + [0][1][1][0][RTW89_UKRAINE][6] = 40, + [0][1][1][0][RTW89_MEXICO][6] = 50, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, + [0][1][1][0][RTW89_FCC][8] = 68, + [0][1][1][0][RTW89_ETSI][8] = 46, + [0][1][1][0][RTW89_MKK][8] = 50, + [0][1][1][0][RTW89_IC][8] = 52, + [0][1][1][0][RTW89_KCC][8] = 72, + [0][1][1][0][RTW89_ACMA][8] = 46, + [0][1][1][0][RTW89_CHILE][8] = 42, + [0][1][1][0][RTW89_UKRAINE][8] = 40, + [0][1][1][0][RTW89_MEXICO][8] = 68, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, + [0][1][1][0][RTW89_FCC][10] = 68, + [0][1][1][0][RTW89_ETSI][10] = 46, + [0][1][1][0][RTW89_MKK][10] = 50, + [0][1][1][0][RTW89_IC][10] = 52, + [0][1][1][0][RTW89_KCC][10] = 72, + [0][1][1][0][RTW89_ACMA][10] = 46, + [0][1][1][0][RTW89_CHILE][10] = 42, + [0][1][1][0][RTW89_UKRAINE][10] = 40, + [0][1][1][0][RTW89_MEXICO][10] = 68, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, + [0][1][1][0][RTW89_FCC][12] = 68, + [0][1][1][0][RTW89_ETSI][12] = 46, + [0][1][1][0][RTW89_MKK][12] = 50, + [0][1][1][0][RTW89_IC][12] = 52, + [0][1][1][0][RTW89_KCC][12] = 72, + [0][1][1][0][RTW89_ACMA][12] = 46, + [0][1][1][0][RTW89_CHILE][12] = 42, + [0][1][1][0][RTW89_UKRAINE][12] = 40, + [0][1][1][0][RTW89_MEXICO][12] = 68, + [0][1][1][0][RTW89_CN][12] = 46, + [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, + [0][1][1][0][RTW89_FCC][14] = 68, + [0][1][1][0][RTW89_ETSI][14] = 46, + [0][1][1][0][RTW89_MKK][14] = 50, + [0][1][1][0][RTW89_IC][14] = 52, + [0][1][1][0][RTW89_KCC][14] = 72, + [0][1][1][0][RTW89_ACMA][14] = 46, + [0][1][1][0][RTW89_CHILE][14] = 42, + [0][1][1][0][RTW89_UKRAINE][14] = 40, + [0][1][1][0][RTW89_MEXICO][14] = 68, + [0][1][1][0][RTW89_CN][14] = 46, + [0][1][1][0][RTW89_QATAR][14] = 46, + [0][1][1][0][RTW89_UK][14] = 46, + [0][1][1][0][RTW89_FCC][15] = 68, + [0][1][1][0][RTW89_ETSI][15] = 46, + [0][1][1][0][RTW89_MKK][15] = 70, + [0][1][1][0][RTW89_IC][15] = 68, + [0][1][1][0][RTW89_KCC][15] = 72, + [0][1][1][0][RTW89_ACMA][15] = 46, + [0][1][1][0][RTW89_CHILE][15] = 42, + [0][1][1][0][RTW89_UKRAINE][15] = 40, + [0][1][1][0][RTW89_MEXICO][15] = 68, + [0][1][1][0][RTW89_CN][15] = 127, + [0][1][1][0][RTW89_QATAR][15] = 40, + [0][1][1][0][RTW89_UK][15] = 46, + [0][1][1][0][RTW89_FCC][17] = 68, + [0][1][1][0][RTW89_ETSI][17] = 46, + [0][1][1][0][RTW89_MKK][17] = 70, + [0][1][1][0][RTW89_IC][17] = 68, + [0][1][1][0][RTW89_KCC][17] = 72, + [0][1][1][0][RTW89_ACMA][17] = 46, + [0][1][1][0][RTW89_CHILE][17] = 42, + [0][1][1][0][RTW89_UKRAINE][17] = 40, + [0][1][1][0][RTW89_MEXICO][17] = 68, + [0][1][1][0][RTW89_CN][17] = 127, + [0][1][1][0][RTW89_QATAR][17] = 40, + [0][1][1][0][RTW89_UK][17] = 46, + [0][1][1][0][RTW89_FCC][19] = 68, + [0][1][1][0][RTW89_ETSI][19] = 46, + [0][1][1][0][RTW89_MKK][19] = 70, + [0][1][1][0][RTW89_IC][19] = 68, + [0][1][1][0][RTW89_KCC][19] = 72, + [0][1][1][0][RTW89_ACMA][19] = 46, + [0][1][1][0][RTW89_CHILE][19] = 42, + [0][1][1][0][RTW89_UKRAINE][19] = 40, + [0][1][1][0][RTW89_MEXICO][19] = 68, + [0][1][1][0][RTW89_CN][19] = 127, + [0][1][1][0][RTW89_QATAR][19] = 40, + [0][1][1][0][RTW89_UK][19] = 46, + [0][1][1][0][RTW89_FCC][21] = 68, + [0][1][1][0][RTW89_ETSI][21] = 46, + [0][1][1][0][RTW89_MKK][21] = 70, + [0][1][1][0][RTW89_IC][21] = 68, + [0][1][1][0][RTW89_KCC][21] = 72, + [0][1][1][0][RTW89_ACMA][21] = 46, + [0][1][1][0][RTW89_CHILE][21] = 42, + [0][1][1][0][RTW89_UKRAINE][21] = 40, + [0][1][1][0][RTW89_MEXICO][21] = 68, + [0][1][1][0][RTW89_CN][21] = 127, + [0][1][1][0][RTW89_QATAR][21] = 40, + [0][1][1][0][RTW89_UK][21] = 46, + [0][1][1][0][RTW89_FCC][23] = 68, + [0][1][1][0][RTW89_ETSI][23] = 46, + [0][1][1][0][RTW89_MKK][23] = 70, + [0][1][1][0][RTW89_IC][23] = 68, + [0][1][1][0][RTW89_KCC][23] = 72, + [0][1][1][0][RTW89_ACMA][23] = 46, + [0][1][1][0][RTW89_CHILE][23] = 42, + [0][1][1][0][RTW89_UKRAINE][23] = 40, + [0][1][1][0][RTW89_MEXICO][23] = 68, + [0][1][1][0][RTW89_CN][23] = 127, + [0][1][1][0][RTW89_QATAR][23] = 40, + [0][1][1][0][RTW89_UK][23] = 46, + [0][1][1][0][RTW89_FCC][25] = 68, + [0][1][1][0][RTW89_ETSI][25] = 46, + [0][1][1][0][RTW89_MKK][25] = 70, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_KCC][25] = 72, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_CHILE][25] = 42, + [0][1][1][0][RTW89_UKRAINE][25] = 40, + [0][1][1][0][RTW89_MEXICO][25] = 68, + [0][1][1][0][RTW89_CN][25] = 127, + [0][1][1][0][RTW89_QATAR][25] = 40, + [0][1][1][0][RTW89_UK][25] = 46, + [0][1][1][0][RTW89_FCC][27] = 68, + [0][1][1][0][RTW89_ETSI][27] = 46, + [0][1][1][0][RTW89_MKK][27] = 70, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_KCC][27] = 72, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_CHILE][27] = 42, + [0][1][1][0][RTW89_UKRAINE][27] = 40, + [0][1][1][0][RTW89_MEXICO][27] = 68, + [0][1][1][0][RTW89_CN][27] = 127, + [0][1][1][0][RTW89_QATAR][27] = 40, + [0][1][1][0][RTW89_UK][27] = 46, + [0][1][1][0][RTW89_FCC][29] = 68, + [0][1][1][0][RTW89_ETSI][29] = 46, + [0][1][1][0][RTW89_MKK][29] = 70, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_KCC][29] = 72, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_CHILE][29] = 42, + [0][1][1][0][RTW89_UKRAINE][29] = 40, + [0][1][1][0][RTW89_MEXICO][29] = 68, + [0][1][1][0][RTW89_CN][29] = 127, + [0][1][1][0][RTW89_QATAR][29] = 40, + [0][1][1][0][RTW89_UK][29] = 46, + [0][1][1][0][RTW89_FCC][31] = 68, + [0][1][1][0][RTW89_ETSI][31] = 46, + [0][1][1][0][RTW89_MKK][31] = 70, + [0][1][1][0][RTW89_IC][31] = 68, + [0][1][1][0][RTW89_KCC][31] = 72, + [0][1][1][0][RTW89_ACMA][31] = 46, + [0][1][1][0][RTW89_CHILE][31] = 42, + [0][1][1][0][RTW89_UKRAINE][31] = 40, + [0][1][1][0][RTW89_MEXICO][31] = 68, + [0][1][1][0][RTW89_CN][31] = 127, + [0][1][1][0][RTW89_QATAR][31] = 40, + [0][1][1][0][RTW89_UK][31] = 46, + [0][1][1][0][RTW89_FCC][33] = 68, + [0][1][1][0][RTW89_ETSI][33] = 46, + [0][1][1][0][RTW89_MKK][33] = 70, + [0][1][1][0][RTW89_IC][33] = 68, + [0][1][1][0][RTW89_KCC][33] = 72, + [0][1][1][0][RTW89_ACMA][33] = 46, + [0][1][1][0][RTW89_CHILE][33] = 42, + [0][1][1][0][RTW89_UKRAINE][33] = 40, + [0][1][1][0][RTW89_MEXICO][33] = 68, + [0][1][1][0][RTW89_CN][33] = 127, + [0][1][1][0][RTW89_QATAR][33] = 40, + [0][1][1][0][RTW89_UK][33] = 46, + [0][1][1][0][RTW89_FCC][35] = 66, + [0][1][1][0][RTW89_ETSI][35] = 46, + [0][1][1][0][RTW89_MKK][35] = 70, + [0][1][1][0][RTW89_IC][35] = 66, + [0][1][1][0][RTW89_KCC][35] = 72, + [0][1][1][0][RTW89_ACMA][35] = 46, + [0][1][1][0][RTW89_CHILE][35] = 42, + [0][1][1][0][RTW89_UKRAINE][35] = 40, + [0][1][1][0][RTW89_MEXICO][35] = 66, + [0][1][1][0][RTW89_CN][35] = 127, + [0][1][1][0][RTW89_QATAR][35] = 40, + [0][1][1][0][RTW89_UK][35] = 46, + [0][1][1][0][RTW89_FCC][37] = 68, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 70, + [0][1][1][0][RTW89_IC][37] = 68, + [0][1][1][0][RTW89_KCC][37] = 72, + [0][1][1][0][RTW89_ACMA][37] = 68, + [0][1][1][0][RTW89_CHILE][37] = 42, + [0][1][1][0][RTW89_UKRAINE][37] = 127, + [0][1][1][0][RTW89_MEXICO][37] = 68, + [0][1][1][0][RTW89_CN][37] = 127, + [0][1][1][0][RTW89_QATAR][37] = 127, + [0][1][1][0][RTW89_UK][37] = 74, + [0][1][1][0][RTW89_FCC][38] = 76, + [0][1][1][0][RTW89_ETSI][38] = 16, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 76, + [0][1][1][0][RTW89_KCC][38] = 72, + [0][1][1][0][RTW89_ACMA][38] = 76, + [0][1][1][0][RTW89_CHILE][38] = 42, + [0][1][1][0][RTW89_UKRAINE][38] = 16, + [0][1][1][0][RTW89_MEXICO][38] = 76, + [0][1][1][0][RTW89_CN][38] = 72, + [0][1][1][0][RTW89_QATAR][38] = 16, + [0][1][1][0][RTW89_UK][38] = 44, + [0][1][1][0][RTW89_FCC][40] = 76, + [0][1][1][0][RTW89_ETSI][40] = 16, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 76, + [0][1][1][0][RTW89_KCC][40] = 72, + [0][1][1][0][RTW89_ACMA][40] = 76, + [0][1][1][0][RTW89_CHILE][40] = 42, + [0][1][1][0][RTW89_UKRAINE][40] = 16, + [0][1][1][0][RTW89_MEXICO][40] = 76, + [0][1][1][0][RTW89_CN][40] = 76, + [0][1][1][0][RTW89_QATAR][40] = 16, + [0][1][1][0][RTW89_UK][40] = 44, + [0][1][1][0][RTW89_FCC][42] = 76, + [0][1][1][0][RTW89_ETSI][42] = 16, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 76, + [0][1][1][0][RTW89_KCC][42] = 72, + [0][1][1][0][RTW89_ACMA][42] = 76, + [0][1][1][0][RTW89_CHILE][42] = 42, + [0][1][1][0][RTW89_UKRAINE][42] = 16, + [0][1][1][0][RTW89_MEXICO][42] = 76, + [0][1][1][0][RTW89_CN][42] = 76, + [0][1][1][0][RTW89_QATAR][42] = 16, + [0][1][1][0][RTW89_UK][42] = 44, + [0][1][1][0][RTW89_FCC][44] = 76, + [0][1][1][0][RTW89_ETSI][44] = 16, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 76, + [0][1][1][0][RTW89_KCC][44] = 72, + [0][1][1][0][RTW89_ACMA][44] = 76, + [0][1][1][0][RTW89_CHILE][44] = 42, + [0][1][1][0][RTW89_UKRAINE][44] = 16, + [0][1][1][0][RTW89_MEXICO][44] = 76, + [0][1][1][0][RTW89_CN][44] = 76, + [0][1][1][0][RTW89_QATAR][44] = 16, + [0][1][1][0][RTW89_UK][44] = 44, + [0][1][1][0][RTW89_FCC][46] = 76, + [0][1][1][0][RTW89_ETSI][46] = 16, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 76, + [0][1][1][0][RTW89_KCC][46] = 72, + [0][1][1][0][RTW89_ACMA][46] = 76, + [0][1][1][0][RTW89_CHILE][46] = 42, + [0][1][1][0][RTW89_UKRAINE][46] = 16, + [0][1][1][0][RTW89_MEXICO][46] = 76, + [0][1][1][0][RTW89_CN][46] = 76, + [0][1][1][0][RTW89_QATAR][46] = 16, + [0][1][1][0][RTW89_UK][46] = 44, + [0][0][2][0][RTW89_FCC][0] = 76, + [0][0][2][0][RTW89_ETSI][0] = 58, + [0][0][2][0][RTW89_MKK][0] = 62, + [0][0][2][0][RTW89_IC][0] = 62, + [0][0][2][0][RTW89_KCC][0] = 76, + [0][0][2][0][RTW89_ACMA][0] = 58, + [0][0][2][0][RTW89_CHILE][0] = 30, + [0][0][2][0][RTW89_UKRAINE][0] = 52, + [0][0][2][0][RTW89_MEXICO][0] = 62, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_QATAR][0] = 58, + [0][0][2][0][RTW89_UK][0] = 58, + [0][0][2][0][RTW89_FCC][2] = 76, + [0][0][2][0][RTW89_ETSI][2] = 58, + [0][0][2][0][RTW89_MKK][2] = 62, + [0][0][2][0][RTW89_IC][2] = 62, + [0][0][2][0][RTW89_KCC][2] = 76, + [0][0][2][0][RTW89_ACMA][2] = 58, + [0][0][2][0][RTW89_CHILE][2] = 30, + [0][0][2][0][RTW89_UKRAINE][2] = 52, + [0][0][2][0][RTW89_MEXICO][2] = 62, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_QATAR][2] = 58, + [0][0][2][0][RTW89_UK][2] = 58, + [0][0][2][0][RTW89_FCC][4] = 76, + [0][0][2][0][RTW89_ETSI][4] = 58, + [0][0][2][0][RTW89_MKK][4] = 62, + [0][0][2][0][RTW89_IC][4] = 62, + [0][0][2][0][RTW89_KCC][4] = 76, + [0][0][2][0][RTW89_ACMA][4] = 58, + [0][0][2][0][RTW89_CHILE][4] = 30, + [0][0][2][0][RTW89_UKRAINE][4] = 52, + [0][0][2][0][RTW89_MEXICO][4] = 62, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_QATAR][4] = 58, + [0][0][2][0][RTW89_UK][4] = 58, + [0][0][2][0][RTW89_FCC][6] = 76, + [0][0][2][0][RTW89_ETSI][6] = 58, + [0][0][2][0][RTW89_MKK][6] = 62, + [0][0][2][0][RTW89_IC][6] = 62, + [0][0][2][0][RTW89_KCC][6] = 58, + [0][0][2][0][RTW89_ACMA][6] = 58, + [0][0][2][0][RTW89_CHILE][6] = 30, + [0][0][2][0][RTW89_UKRAINE][6] = 52, + [0][0][2][0][RTW89_MEXICO][6] = 62, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_QATAR][6] = 58, + [0][0][2][0][RTW89_UK][6] = 58, + [0][0][2][0][RTW89_FCC][8] = 76, + [0][0][2][0][RTW89_ETSI][8] = 58, + [0][0][2][0][RTW89_MKK][8] = 62, + [0][0][2][0][RTW89_IC][8] = 64, + [0][0][2][0][RTW89_KCC][8] = 76, + [0][0][2][0][RTW89_ACMA][8] = 58, + [0][0][2][0][RTW89_CHILE][8] = 54, + [0][0][2][0][RTW89_UKRAINE][8] = 52, + [0][0][2][0][RTW89_MEXICO][8] = 76, + [0][0][2][0][RTW89_CN][8] = 58, + [0][0][2][0][RTW89_QATAR][8] = 58, + [0][0][2][0][RTW89_UK][8] = 58, + [0][0][2][0][RTW89_FCC][10] = 76, + [0][0][2][0][RTW89_ETSI][10] = 58, + [0][0][2][0][RTW89_MKK][10] = 62, + [0][0][2][0][RTW89_IC][10] = 64, + [0][0][2][0][RTW89_KCC][10] = 76, + [0][0][2][0][RTW89_ACMA][10] = 58, + [0][0][2][0][RTW89_CHILE][10] = 54, + [0][0][2][0][RTW89_UKRAINE][10] = 52, + [0][0][2][0][RTW89_MEXICO][10] = 76, + [0][0][2][0][RTW89_CN][10] = 58, + [0][0][2][0][RTW89_QATAR][10] = 58, + [0][0][2][0][RTW89_UK][10] = 58, + [0][0][2][0][RTW89_FCC][12] = 76, + [0][0][2][0][RTW89_ETSI][12] = 58, + [0][0][2][0][RTW89_MKK][12] = 62, + [0][0][2][0][RTW89_IC][12] = 64, + [0][0][2][0][RTW89_KCC][12] = 76, + [0][0][2][0][RTW89_ACMA][12] = 58, + [0][0][2][0][RTW89_CHILE][12] = 54, + [0][0][2][0][RTW89_UKRAINE][12] = 52, + [0][0][2][0][RTW89_MEXICO][12] = 76, + [0][0][2][0][RTW89_CN][12] = 58, + [0][0][2][0][RTW89_QATAR][12] = 58, + [0][0][2][0][RTW89_UK][12] = 58, + [0][0][2][0][RTW89_FCC][14] = 76, + [0][0][2][0][RTW89_ETSI][14] = 58, + [0][0][2][0][RTW89_MKK][14] = 62, + [0][0][2][0][RTW89_IC][14] = 64, + [0][0][2][0][RTW89_KCC][14] = 76, + [0][0][2][0][RTW89_ACMA][14] = 58, + [0][0][2][0][RTW89_CHILE][14] = 54, + [0][0][2][0][RTW89_UKRAINE][14] = 52, + [0][0][2][0][RTW89_MEXICO][14] = 76, + [0][0][2][0][RTW89_CN][14] = 58, + [0][0][2][0][RTW89_QATAR][14] = 58, + [0][0][2][0][RTW89_UK][14] = 58, + [0][0][2][0][RTW89_FCC][15] = 74, + [0][0][2][0][RTW89_ETSI][15] = 58, + [0][0][2][0][RTW89_MKK][15] = 76, + [0][0][2][0][RTW89_IC][15] = 74, + [0][0][2][0][RTW89_KCC][15] = 76, + [0][0][2][0][RTW89_ACMA][15] = 58, + [0][0][2][0][RTW89_CHILE][15] = 54, + [0][0][2][0][RTW89_UKRAINE][15] = 52, + [0][0][2][0][RTW89_MEXICO][15] = 74, + [0][0][2][0][RTW89_CN][15] = 127, + [0][0][2][0][RTW89_QATAR][15] = 52, + [0][0][2][0][RTW89_UK][15] = 58, + [0][0][2][0][RTW89_FCC][17] = 76, + [0][0][2][0][RTW89_ETSI][17] = 58, + [0][0][2][0][RTW89_MKK][17] = 76, + [0][0][2][0][RTW89_IC][17] = 76, + [0][0][2][0][RTW89_KCC][17] = 76, + [0][0][2][0][RTW89_ACMA][17] = 58, + [0][0][2][0][RTW89_CHILE][17] = 54, + [0][0][2][0][RTW89_UKRAINE][17] = 52, + [0][0][2][0][RTW89_MEXICO][17] = 76, + [0][0][2][0][RTW89_CN][17] = 127, + [0][0][2][0][RTW89_QATAR][17] = 52, + [0][0][2][0][RTW89_UK][17] = 58, + [0][0][2][0][RTW89_FCC][19] = 76, + [0][0][2][0][RTW89_ETSI][19] = 58, + [0][0][2][0][RTW89_MKK][19] = 76, + [0][0][2][0][RTW89_IC][19] = 76, + [0][0][2][0][RTW89_KCC][19] = 76, + [0][0][2][0][RTW89_ACMA][19] = 58, + [0][0][2][0][RTW89_CHILE][19] = 54, + [0][0][2][0][RTW89_UKRAINE][19] = 52, + [0][0][2][0][RTW89_MEXICO][19] = 76, + [0][0][2][0][RTW89_CN][19] = 127, + [0][0][2][0][RTW89_QATAR][19] = 52, + [0][0][2][0][RTW89_UK][19] = 58, + [0][0][2][0][RTW89_FCC][21] = 76, + [0][0][2][0][RTW89_ETSI][21] = 58, + [0][0][2][0][RTW89_MKK][21] = 76, + [0][0][2][0][RTW89_IC][21] = 76, + [0][0][2][0][RTW89_KCC][21] = 76, + [0][0][2][0][RTW89_ACMA][21] = 58, + [0][0][2][0][RTW89_CHILE][21] = 54, + [0][0][2][0][RTW89_UKRAINE][21] = 52, + [0][0][2][0][RTW89_MEXICO][21] = 76, + [0][0][2][0][RTW89_CN][21] = 127, + [0][0][2][0][RTW89_QATAR][21] = 52, + [0][0][2][0][RTW89_UK][21] = 58, + [0][0][2][0][RTW89_FCC][23] = 76, + [0][0][2][0][RTW89_ETSI][23] = 58, + [0][0][2][0][RTW89_MKK][23] = 76, + [0][0][2][0][RTW89_IC][23] = 76, + [0][0][2][0][RTW89_KCC][23] = 76, + [0][0][2][0][RTW89_ACMA][23] = 58, + [0][0][2][0][RTW89_CHILE][23] = 54, + [0][0][2][0][RTW89_UKRAINE][23] = 52, + [0][0][2][0][RTW89_MEXICO][23] = 76, + [0][0][2][0][RTW89_CN][23] = 127, + [0][0][2][0][RTW89_QATAR][23] = 52, + [0][0][2][0][RTW89_UK][23] = 58, + [0][0][2][0][RTW89_FCC][25] = 76, + [0][0][2][0][RTW89_ETSI][25] = 58, + [0][0][2][0][RTW89_MKK][25] = 76, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_KCC][25] = 76, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_CHILE][25] = 54, + [0][0][2][0][RTW89_UKRAINE][25] = 52, + [0][0][2][0][RTW89_MEXICO][25] = 76, + [0][0][2][0][RTW89_CN][25] = 127, + [0][0][2][0][RTW89_QATAR][25] = 52, + [0][0][2][0][RTW89_UK][25] = 58, + [0][0][2][0][RTW89_FCC][27] = 76, + [0][0][2][0][RTW89_ETSI][27] = 58, + [0][0][2][0][RTW89_MKK][27] = 76, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_KCC][27] = 76, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_CHILE][27] = 54, + [0][0][2][0][RTW89_UKRAINE][27] = 52, + [0][0][2][0][RTW89_MEXICO][27] = 76, + [0][0][2][0][RTW89_CN][27] = 127, + [0][0][2][0][RTW89_QATAR][27] = 52, + [0][0][2][0][RTW89_UK][27] = 58, + [0][0][2][0][RTW89_FCC][29] = 76, + [0][0][2][0][RTW89_ETSI][29] = 58, + [0][0][2][0][RTW89_MKK][29] = 76, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_KCC][29] = 76, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_CHILE][29] = 54, + [0][0][2][0][RTW89_UKRAINE][29] = 52, + [0][0][2][0][RTW89_MEXICO][29] = 76, + [0][0][2][0][RTW89_CN][29] = 127, + [0][0][2][0][RTW89_QATAR][29] = 52, + [0][0][2][0][RTW89_UK][29] = 58, + [0][0][2][0][RTW89_FCC][31] = 76, + [0][0][2][0][RTW89_ETSI][31] = 58, + [0][0][2][0][RTW89_MKK][31] = 76, + [0][0][2][0][RTW89_IC][31] = 76, + [0][0][2][0][RTW89_KCC][31] = 76, + [0][0][2][0][RTW89_ACMA][31] = 58, + [0][0][2][0][RTW89_CHILE][31] = 54, + [0][0][2][0][RTW89_UKRAINE][31] = 52, + [0][0][2][0][RTW89_MEXICO][31] = 76, + [0][0][2][0][RTW89_CN][31] = 127, + [0][0][2][0][RTW89_QATAR][31] = 52, + [0][0][2][0][RTW89_UK][31] = 58, + [0][0][2][0][RTW89_FCC][33] = 76, + [0][0][2][0][RTW89_ETSI][33] = 58, + [0][0][2][0][RTW89_MKK][33] = 76, + [0][0][2][0][RTW89_IC][33] = 76, + [0][0][2][0][RTW89_KCC][33] = 76, + [0][0][2][0][RTW89_ACMA][33] = 58, + [0][0][2][0][RTW89_CHILE][33] = 54, + [0][0][2][0][RTW89_UKRAINE][33] = 52, + [0][0][2][0][RTW89_MEXICO][33] = 76, + [0][0][2][0][RTW89_CN][33] = 127, + [0][0][2][0][RTW89_QATAR][33] = 52, + [0][0][2][0][RTW89_UK][33] = 58, + [0][0][2][0][RTW89_FCC][35] = 70, + [0][0][2][0][RTW89_ETSI][35] = 58, + [0][0][2][0][RTW89_MKK][35] = 76, + [0][0][2][0][RTW89_IC][35] = 70, + [0][0][2][0][RTW89_KCC][35] = 76, + [0][0][2][0][RTW89_ACMA][35] = 58, + [0][0][2][0][RTW89_CHILE][35] = 54, + [0][0][2][0][RTW89_UKRAINE][35] = 52, + [0][0][2][0][RTW89_MEXICO][35] = 70, + [0][0][2][0][RTW89_CN][35] = 127, + [0][0][2][0][RTW89_QATAR][35] = 52, + [0][0][2][0][RTW89_UK][35] = 58, + [0][0][2][0][RTW89_FCC][37] = 76, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 76, + [0][0][2][0][RTW89_IC][37] = 76, + [0][0][2][0][RTW89_KCC][37] = 76, + [0][0][2][0][RTW89_ACMA][37] = 76, + [0][0][2][0][RTW89_CHILE][37] = 54, + [0][0][2][0][RTW89_UKRAINE][37] = 127, + [0][0][2][0][RTW89_MEXICO][37] = 76, + [0][0][2][0][RTW89_CN][37] = 127, + [0][0][2][0][RTW89_QATAR][37] = 127, + [0][0][2][0][RTW89_UK][37] = 76, + [0][0][2][0][RTW89_FCC][38] = 76, + [0][0][2][0][RTW89_ETSI][38] = 28, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 76, + [0][0][2][0][RTW89_KCC][38] = 76, + [0][0][2][0][RTW89_ACMA][38] = 76, + [0][0][2][0][RTW89_CHILE][38] = 54, + [0][0][2][0][RTW89_UKRAINE][38] = 28, + [0][0][2][0][RTW89_MEXICO][38] = 76, + [0][0][2][0][RTW89_CN][38] = 68, + [0][0][2][0][RTW89_QATAR][38] = 28, + [0][0][2][0][RTW89_UK][38] = 58, + [0][0][2][0][RTW89_FCC][40] = 76, + [0][0][2][0][RTW89_ETSI][40] = 28, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 76, + [0][0][2][0][RTW89_KCC][40] = 76, + [0][0][2][0][RTW89_ACMA][40] = 76, + [0][0][2][0][RTW89_CHILE][40] = 54, + [0][0][2][0][RTW89_UKRAINE][40] = 28, + [0][0][2][0][RTW89_MEXICO][40] = 76, + [0][0][2][0][RTW89_CN][40] = 76, + [0][0][2][0][RTW89_QATAR][40] = 28, + [0][0][2][0][RTW89_UK][40] = 58, + [0][0][2][0][RTW89_FCC][42] = 76, + [0][0][2][0][RTW89_ETSI][42] = 28, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 76, + [0][0][2][0][RTW89_KCC][42] = 76, + [0][0][2][0][RTW89_ACMA][42] = 76, + [0][0][2][0][RTW89_CHILE][42] = 54, + [0][0][2][0][RTW89_UKRAINE][42] = 28, + [0][0][2][0][RTW89_MEXICO][42] = 76, + [0][0][2][0][RTW89_CN][42] = 76, + [0][0][2][0][RTW89_QATAR][42] = 28, + [0][0][2][0][RTW89_UK][42] = 58, + [0][0][2][0][RTW89_FCC][44] = 76, + [0][0][2][0][RTW89_ETSI][44] = 28, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 76, + [0][0][2][0][RTW89_KCC][44] = 76, + [0][0][2][0][RTW89_ACMA][44] = 76, + [0][0][2][0][RTW89_CHILE][44] = 54, + [0][0][2][0][RTW89_UKRAINE][44] = 28, + [0][0][2][0][RTW89_MEXICO][44] = 76, + [0][0][2][0][RTW89_CN][44] = 76, + [0][0][2][0][RTW89_QATAR][44] = 28, + [0][0][2][0][RTW89_UK][44] = 58, + [0][0][2][0][RTW89_FCC][46] = 76, + [0][0][2][0][RTW89_ETSI][46] = 28, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 76, + [0][0][2][0][RTW89_KCC][46] = 76, + [0][0][2][0][RTW89_ACMA][46] = 76, + [0][0][2][0][RTW89_CHILE][46] = 54, + [0][0][2][0][RTW89_UKRAINE][46] = 28, + [0][0][2][0][RTW89_MEXICO][46] = 76, + [0][0][2][0][RTW89_CN][46] = 76, + [0][0][2][0][RTW89_QATAR][46] = 28, + [0][0][2][0][RTW89_UK][46] = 58, + [0][1][2][0][RTW89_FCC][0] = 68, + [0][1][2][0][RTW89_ETSI][0] = 46, + [0][1][2][0][RTW89_MKK][0] = 50, + [0][1][2][0][RTW89_IC][0] = 40, + [0][1][2][0][RTW89_KCC][0] = 68, + [0][1][2][0][RTW89_ACMA][0] = 46, + [0][1][2][0][RTW89_CHILE][0] = 18, + [0][1][2][0][RTW89_UKRAINE][0] = 40, + [0][1][2][0][RTW89_MEXICO][0] = 50, + [0][1][2][0][RTW89_CN][0] = 46, + [0][1][2][0][RTW89_QATAR][0] = 46, + [0][1][2][0][RTW89_UK][0] = 46, + [0][1][2][0][RTW89_FCC][2] = 68, + [0][1][2][0][RTW89_ETSI][2] = 46, + [0][1][2][0][RTW89_MKK][2] = 50, + [0][1][2][0][RTW89_IC][2] = 40, + [0][1][2][0][RTW89_KCC][2] = 68, + [0][1][2][0][RTW89_ACMA][2] = 46, + [0][1][2][0][RTW89_CHILE][2] = 18, + [0][1][2][0][RTW89_UKRAINE][2] = 40, + [0][1][2][0][RTW89_MEXICO][2] = 50, + [0][1][2][0][RTW89_CN][2] = 46, + [0][1][2][0][RTW89_QATAR][2] = 46, + [0][1][2][0][RTW89_UK][2] = 46, + [0][1][2][0][RTW89_FCC][4] = 68, + [0][1][2][0][RTW89_ETSI][4] = 46, + [0][1][2][0][RTW89_MKK][4] = 50, + [0][1][2][0][RTW89_IC][4] = 40, + [0][1][2][0][RTW89_KCC][4] = 68, + [0][1][2][0][RTW89_ACMA][4] = 46, + [0][1][2][0][RTW89_CHILE][4] = 18, + [0][1][2][0][RTW89_UKRAINE][4] = 40, + [0][1][2][0][RTW89_MEXICO][4] = 50, + [0][1][2][0][RTW89_CN][4] = 46, + [0][1][2][0][RTW89_QATAR][4] = 46, + [0][1][2][0][RTW89_UK][4] = 46, + [0][1][2][0][RTW89_FCC][6] = 68, + [0][1][2][0][RTW89_ETSI][6] = 46, + [0][1][2][0][RTW89_MKK][6] = 50, + [0][1][2][0][RTW89_IC][6] = 40, + [0][1][2][0][RTW89_KCC][6] = 38, + [0][1][2][0][RTW89_ACMA][6] = 46, + [0][1][2][0][RTW89_CHILE][6] = 18, + [0][1][2][0][RTW89_UKRAINE][6] = 40, + [0][1][2][0][RTW89_MEXICO][6] = 50, + [0][1][2][0][RTW89_CN][6] = 46, + [0][1][2][0][RTW89_QATAR][6] = 46, + [0][1][2][0][RTW89_UK][6] = 46, + [0][1][2][0][RTW89_FCC][8] = 68, + [0][1][2][0][RTW89_ETSI][8] = 46, + [0][1][2][0][RTW89_MKK][8] = 50, + [0][1][2][0][RTW89_IC][8] = 52, + [0][1][2][0][RTW89_KCC][8] = 68, + [0][1][2][0][RTW89_ACMA][8] = 46, + [0][1][2][0][RTW89_CHILE][8] = 42, + [0][1][2][0][RTW89_UKRAINE][8] = 40, + [0][1][2][0][RTW89_MEXICO][8] = 68, + [0][1][2][0][RTW89_CN][8] = 46, + [0][1][2][0][RTW89_QATAR][8] = 46, + [0][1][2][0][RTW89_UK][8] = 46, + [0][1][2][0][RTW89_FCC][10] = 68, + [0][1][2][0][RTW89_ETSI][10] = 46, + [0][1][2][0][RTW89_MKK][10] = 50, + [0][1][2][0][RTW89_IC][10] = 52, + [0][1][2][0][RTW89_KCC][10] = 68, + [0][1][2][0][RTW89_ACMA][10] = 46, + [0][1][2][0][RTW89_CHILE][10] = 42, + [0][1][2][0][RTW89_UKRAINE][10] = 40, + [0][1][2][0][RTW89_MEXICO][10] = 68, + [0][1][2][0][RTW89_CN][10] = 46, + [0][1][2][0][RTW89_QATAR][10] = 46, + [0][1][2][0][RTW89_UK][10] = 46, + [0][1][2][0][RTW89_FCC][12] = 68, + [0][1][2][0][RTW89_ETSI][12] = 46, + [0][1][2][0][RTW89_MKK][12] = 50, + [0][1][2][0][RTW89_IC][12] = 52, + [0][1][2][0][RTW89_KCC][12] = 68, + [0][1][2][0][RTW89_ACMA][12] = 46, + [0][1][2][0][RTW89_CHILE][12] = 42, + [0][1][2][0][RTW89_UKRAINE][12] = 40, + [0][1][2][0][RTW89_MEXICO][12] = 68, + [0][1][2][0][RTW89_CN][12] = 46, + [0][1][2][0][RTW89_QATAR][12] = 46, + [0][1][2][0][RTW89_UK][12] = 46, + [0][1][2][0][RTW89_FCC][14] = 68, + [0][1][2][0][RTW89_ETSI][14] = 46, + [0][1][2][0][RTW89_MKK][14] = 50, + [0][1][2][0][RTW89_IC][14] = 52, + [0][1][2][0][RTW89_KCC][14] = 68, + [0][1][2][0][RTW89_ACMA][14] = 46, + [0][1][2][0][RTW89_CHILE][14] = 42, + [0][1][2][0][RTW89_UKRAINE][14] = 40, + [0][1][2][0][RTW89_MEXICO][14] = 68, + [0][1][2][0][RTW89_CN][14] = 46, + [0][1][2][0][RTW89_QATAR][14] = 46, + [0][1][2][0][RTW89_UK][14] = 46, + [0][1][2][0][RTW89_FCC][15] = 68, + [0][1][2][0][RTW89_ETSI][15] = 46, + [0][1][2][0][RTW89_MKK][15] = 70, + [0][1][2][0][RTW89_IC][15] = 68, + [0][1][2][0][RTW89_KCC][15] = 66, + [0][1][2][0][RTW89_ACMA][15] = 46, + [0][1][2][0][RTW89_CHILE][15] = 42, + [0][1][2][0][RTW89_UKRAINE][15] = 40, + [0][1][2][0][RTW89_MEXICO][15] = 68, + [0][1][2][0][RTW89_CN][15] = 127, + [0][1][2][0][RTW89_QATAR][15] = 40, + [0][1][2][0][RTW89_UK][15] = 46, + [0][1][2][0][RTW89_FCC][17] = 68, + [0][1][2][0][RTW89_ETSI][17] = 46, + [0][1][2][0][RTW89_MKK][17] = 70, + [0][1][2][0][RTW89_IC][17] = 68, + [0][1][2][0][RTW89_KCC][17] = 66, + [0][1][2][0][RTW89_ACMA][17] = 46, + [0][1][2][0][RTW89_CHILE][17] = 42, + [0][1][2][0][RTW89_UKRAINE][17] = 40, + [0][1][2][0][RTW89_MEXICO][17] = 68, + [0][1][2][0][RTW89_CN][17] = 127, + [0][1][2][0][RTW89_QATAR][17] = 40, + [0][1][2][0][RTW89_UK][17] = 46, + [0][1][2][0][RTW89_FCC][19] = 68, + [0][1][2][0][RTW89_ETSI][19] = 46, + [0][1][2][0][RTW89_MKK][19] = 70, + [0][1][2][0][RTW89_IC][19] = 68, + [0][1][2][0][RTW89_KCC][19] = 66, + [0][1][2][0][RTW89_ACMA][19] = 46, + [0][1][2][0][RTW89_CHILE][19] = 42, + [0][1][2][0][RTW89_UKRAINE][19] = 40, + [0][1][2][0][RTW89_MEXICO][19] = 68, + [0][1][2][0][RTW89_CN][19] = 127, + [0][1][2][0][RTW89_QATAR][19] = 40, + [0][1][2][0][RTW89_UK][19] = 46, + [0][1][2][0][RTW89_FCC][21] = 68, + [0][1][2][0][RTW89_ETSI][21] = 46, + [0][1][2][0][RTW89_MKK][21] = 70, + [0][1][2][0][RTW89_IC][21] = 68, + [0][1][2][0][RTW89_KCC][21] = 66, + [0][1][2][0][RTW89_ACMA][21] = 46, + [0][1][2][0][RTW89_CHILE][21] = 42, + [0][1][2][0][RTW89_UKRAINE][21] = 40, + [0][1][2][0][RTW89_MEXICO][21] = 68, + [0][1][2][0][RTW89_CN][21] = 127, + [0][1][2][0][RTW89_QATAR][21] = 40, + [0][1][2][0][RTW89_UK][21] = 46, + [0][1][2][0][RTW89_FCC][23] = 68, + [0][1][2][0][RTW89_ETSI][23] = 46, + [0][1][2][0][RTW89_MKK][23] = 70, + [0][1][2][0][RTW89_IC][23] = 68, + [0][1][2][0][RTW89_KCC][23] = 66, + [0][1][2][0][RTW89_ACMA][23] = 46, + [0][1][2][0][RTW89_CHILE][23] = 42, + [0][1][2][0][RTW89_UKRAINE][23] = 40, + [0][1][2][0][RTW89_MEXICO][23] = 68, + [0][1][2][0][RTW89_CN][23] = 127, + [0][1][2][0][RTW89_QATAR][23] = 40, + [0][1][2][0][RTW89_UK][23] = 46, + [0][1][2][0][RTW89_FCC][25] = 68, + [0][1][2][0][RTW89_ETSI][25] = 46, + [0][1][2][0][RTW89_MKK][25] = 70, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_KCC][25] = 66, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_CHILE][25] = 42, + [0][1][2][0][RTW89_UKRAINE][25] = 40, + [0][1][2][0][RTW89_MEXICO][25] = 68, + [0][1][2][0][RTW89_CN][25] = 127, + [0][1][2][0][RTW89_QATAR][25] = 40, + [0][1][2][0][RTW89_UK][25] = 46, + [0][1][2][0][RTW89_FCC][27] = 68, + [0][1][2][0][RTW89_ETSI][27] = 46, + [0][1][2][0][RTW89_MKK][27] = 70, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_KCC][27] = 66, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_CHILE][27] = 42, + [0][1][2][0][RTW89_UKRAINE][27] = 40, + [0][1][2][0][RTW89_MEXICO][27] = 68, + [0][1][2][0][RTW89_CN][27] = 127, + [0][1][2][0][RTW89_QATAR][27] = 40, + [0][1][2][0][RTW89_UK][27] = 46, + [0][1][2][0][RTW89_FCC][29] = 68, + [0][1][2][0][RTW89_ETSI][29] = 46, + [0][1][2][0][RTW89_MKK][29] = 70, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_KCC][29] = 66, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_CHILE][29] = 42, + [0][1][2][0][RTW89_UKRAINE][29] = 40, + [0][1][2][0][RTW89_MEXICO][29] = 68, + [0][1][2][0][RTW89_CN][29] = 127, + [0][1][2][0][RTW89_QATAR][29] = 40, + [0][1][2][0][RTW89_UK][29] = 46, + [0][1][2][0][RTW89_FCC][31] = 68, + [0][1][2][0][RTW89_ETSI][31] = 46, + [0][1][2][0][RTW89_MKK][31] = 70, + [0][1][2][0][RTW89_IC][31] = 68, + [0][1][2][0][RTW89_KCC][31] = 66, + [0][1][2][0][RTW89_ACMA][31] = 46, + [0][1][2][0][RTW89_CHILE][31] = 42, + [0][1][2][0][RTW89_UKRAINE][31] = 40, + [0][1][2][0][RTW89_MEXICO][31] = 68, + [0][1][2][0][RTW89_CN][31] = 127, + [0][1][2][0][RTW89_QATAR][31] = 40, + [0][1][2][0][RTW89_UK][31] = 46, + [0][1][2][0][RTW89_FCC][33] = 68, + [0][1][2][0][RTW89_ETSI][33] = 46, + [0][1][2][0][RTW89_MKK][33] = 70, + [0][1][2][0][RTW89_IC][33] = 68, + [0][1][2][0][RTW89_KCC][33] = 66, + [0][1][2][0][RTW89_ACMA][33] = 46, + [0][1][2][0][RTW89_CHILE][33] = 42, + [0][1][2][0][RTW89_UKRAINE][33] = 40, + [0][1][2][0][RTW89_MEXICO][33] = 68, + [0][1][2][0][RTW89_CN][33] = 127, + [0][1][2][0][RTW89_QATAR][33] = 40, + [0][1][2][0][RTW89_UK][33] = 46, + [0][1][2][0][RTW89_FCC][35] = 64, + [0][1][2][0][RTW89_ETSI][35] = 46, + [0][1][2][0][RTW89_MKK][35] = 70, + [0][1][2][0][RTW89_IC][35] = 64, + [0][1][2][0][RTW89_KCC][35] = 66, + [0][1][2][0][RTW89_ACMA][35] = 46, + [0][1][2][0][RTW89_CHILE][35] = 42, + [0][1][2][0][RTW89_UKRAINE][35] = 40, + [0][1][2][0][RTW89_MEXICO][35] = 64, + [0][1][2][0][RTW89_CN][35] = 127, + [0][1][2][0][RTW89_QATAR][35] = 40, + [0][1][2][0][RTW89_UK][35] = 46, + [0][1][2][0][RTW89_FCC][37] = 68, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 70, + [0][1][2][0][RTW89_IC][37] = 68, + [0][1][2][0][RTW89_KCC][37] = 66, + [0][1][2][0][RTW89_ACMA][37] = 68, + [0][1][2][0][RTW89_CHILE][37] = 42, + [0][1][2][0][RTW89_UKRAINE][37] = 127, + [0][1][2][0][RTW89_MEXICO][37] = 68, + [0][1][2][0][RTW89_CN][37] = 127, + [0][1][2][0][RTW89_QATAR][37] = 127, + [0][1][2][0][RTW89_UK][37] = 74, + [0][1][2][0][RTW89_FCC][38] = 76, + [0][1][2][0][RTW89_ETSI][38] = 16, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 76, + [0][1][2][0][RTW89_KCC][38] = 66, + [0][1][2][0][RTW89_ACMA][38] = 76, + [0][1][2][0][RTW89_CHILE][38] = 42, + [0][1][2][0][RTW89_UKRAINE][38] = 16, + [0][1][2][0][RTW89_MEXICO][38] = 76, + [0][1][2][0][RTW89_CN][38] = 68, + [0][1][2][0][RTW89_QATAR][38] = 16, + [0][1][2][0][RTW89_UK][38] = 46, + [0][1][2][0][RTW89_FCC][40] = 76, + [0][1][2][0][RTW89_ETSI][40] = 16, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 76, + [0][1][2][0][RTW89_KCC][40] = 66, + [0][1][2][0][RTW89_ACMA][40] = 76, + [0][1][2][0][RTW89_CHILE][40] = 42, + [0][1][2][0][RTW89_UKRAINE][40] = 16, + [0][1][2][0][RTW89_MEXICO][40] = 76, + [0][1][2][0][RTW89_CN][40] = 76, + [0][1][2][0][RTW89_QATAR][40] = 16, + [0][1][2][0][RTW89_UK][40] = 46, + [0][1][2][0][RTW89_FCC][42] = 76, + [0][1][2][0][RTW89_ETSI][42] = 16, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 76, + [0][1][2][0][RTW89_KCC][42] = 66, + [0][1][2][0][RTW89_ACMA][42] = 76, + [0][1][2][0][RTW89_CHILE][42] = 42, + [0][1][2][0][RTW89_UKRAINE][42] = 16, + [0][1][2][0][RTW89_MEXICO][42] = 76, + [0][1][2][0][RTW89_CN][42] = 76, + [0][1][2][0][RTW89_QATAR][42] = 16, + [0][1][2][0][RTW89_UK][42] = 46, + [0][1][2][0][RTW89_FCC][44] = 76, + [0][1][2][0][RTW89_ETSI][44] = 16, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 76, + [0][1][2][0][RTW89_KCC][44] = 66, + [0][1][2][0][RTW89_ACMA][44] = 76, + [0][1][2][0][RTW89_CHILE][44] = 42, + [0][1][2][0][RTW89_UKRAINE][44] = 16, + [0][1][2][0][RTW89_MEXICO][44] = 76, + [0][1][2][0][RTW89_CN][44] = 76, + [0][1][2][0][RTW89_QATAR][44] = 16, + [0][1][2][0][RTW89_UK][44] = 46, + [0][1][2][0][RTW89_FCC][46] = 76, + [0][1][2][0][RTW89_ETSI][46] = 16, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 76, + [0][1][2][0][RTW89_KCC][46] = 66, + [0][1][2][0][RTW89_ACMA][46] = 76, + [0][1][2][0][RTW89_CHILE][46] = 42, + [0][1][2][0][RTW89_UKRAINE][46] = 16, + [0][1][2][0][RTW89_MEXICO][46] = 76, + [0][1][2][0][RTW89_CN][46] = 76, + [0][1][2][0][RTW89_QATAR][46] = 16, + [0][1][2][0][RTW89_UK][46] = 46, + [0][1][2][1][RTW89_FCC][0] = 68, + [0][1][2][1][RTW89_ETSI][0] = 34, + [0][1][2][1][RTW89_MKK][0] = 50, + [0][1][2][1][RTW89_IC][0] = 38, + [0][1][2][1][RTW89_KCC][0] = 68, + [0][1][2][1][RTW89_ACMA][0] = 34, + [0][1][2][1][RTW89_CHILE][0] = 6, + [0][1][2][1][RTW89_UKRAINE][0] = 28, + [0][1][2][1][RTW89_MEXICO][0] = 50, + [0][1][2][1][RTW89_CN][0] = 34, + [0][1][2][1][RTW89_QATAR][0] = 34, + [0][1][2][1][RTW89_UK][0] = 34, + [0][1][2][1][RTW89_FCC][2] = 68, + [0][1][2][1][RTW89_ETSI][2] = 34, + [0][1][2][1][RTW89_MKK][2] = 50, + [0][1][2][1][RTW89_IC][2] = 38, + [0][1][2][1][RTW89_KCC][2] = 68, + [0][1][2][1][RTW89_ACMA][2] = 34, + [0][1][2][1][RTW89_CHILE][2] = 6, + [0][1][2][1][RTW89_UKRAINE][2] = 28, + [0][1][2][1][RTW89_MEXICO][2] = 50, + [0][1][2][1][RTW89_CN][2] = 34, + [0][1][2][1][RTW89_QATAR][2] = 34, + [0][1][2][1][RTW89_UK][2] = 34, + [0][1][2][1][RTW89_FCC][4] = 68, + [0][1][2][1][RTW89_ETSI][4] = 34, + [0][1][2][1][RTW89_MKK][4] = 50, + [0][1][2][1][RTW89_IC][4] = 38, + [0][1][2][1][RTW89_KCC][4] = 68, + [0][1][2][1][RTW89_ACMA][4] = 34, + [0][1][2][1][RTW89_CHILE][4] = 6, + [0][1][2][1][RTW89_UKRAINE][4] = 28, + [0][1][2][1][RTW89_MEXICO][4] = 50, + [0][1][2][1][RTW89_CN][4] = 34, + [0][1][2][1][RTW89_QATAR][4] = 34, + [0][1][2][1][RTW89_UK][4] = 34, + [0][1][2][1][RTW89_FCC][6] = 68, + [0][1][2][1][RTW89_ETSI][6] = 34, + [0][1][2][1][RTW89_MKK][6] = 50, + [0][1][2][1][RTW89_IC][6] = 38, + [0][1][2][1][RTW89_KCC][6] = 38, + [0][1][2][1][RTW89_ACMA][6] = 34, + [0][1][2][1][RTW89_CHILE][6] = 6, + [0][1][2][1][RTW89_UKRAINE][6] = 28, + [0][1][2][1][RTW89_MEXICO][6] = 50, + [0][1][2][1][RTW89_CN][6] = 34, + [0][1][2][1][RTW89_QATAR][6] = 34, + [0][1][2][1][RTW89_UK][6] = 34, + [0][1][2][1][RTW89_FCC][8] = 68, + [0][1][2][1][RTW89_ETSI][8] = 34, + [0][1][2][1][RTW89_MKK][8] = 50, + [0][1][2][1][RTW89_IC][8] = 38, + [0][1][2][1][RTW89_KCC][8] = 68, + [0][1][2][1][RTW89_ACMA][8] = 34, + [0][1][2][1][RTW89_CHILE][8] = 30, + [0][1][2][1][RTW89_UKRAINE][8] = 28, + [0][1][2][1][RTW89_MEXICO][8] = 68, + [0][1][2][1][RTW89_CN][8] = 34, + [0][1][2][1][RTW89_QATAR][8] = 34, + [0][1][2][1][RTW89_UK][8] = 34, + [0][1][2][1][RTW89_FCC][10] = 68, + [0][1][2][1][RTW89_ETSI][10] = 34, + [0][1][2][1][RTW89_MKK][10] = 50, + [0][1][2][1][RTW89_IC][10] = 38, + [0][1][2][1][RTW89_KCC][10] = 68, + [0][1][2][1][RTW89_ACMA][10] = 34, + [0][1][2][1][RTW89_CHILE][10] = 30, + [0][1][2][1][RTW89_UKRAINE][10] = 28, + [0][1][2][1][RTW89_MEXICO][10] = 68, + [0][1][2][1][RTW89_CN][10] = 34, + [0][1][2][1][RTW89_QATAR][10] = 34, + [0][1][2][1][RTW89_UK][10] = 34, + [0][1][2][1][RTW89_FCC][12] = 68, + [0][1][2][1][RTW89_ETSI][12] = 34, + [0][1][2][1][RTW89_MKK][12] = 50, + [0][1][2][1][RTW89_IC][12] = 38, + [0][1][2][1][RTW89_KCC][12] = 68, + [0][1][2][1][RTW89_ACMA][12] = 34, + [0][1][2][1][RTW89_CHILE][12] = 30, + [0][1][2][1][RTW89_UKRAINE][12] = 28, + [0][1][2][1][RTW89_MEXICO][12] = 68, + [0][1][2][1][RTW89_CN][12] = 34, + [0][1][2][1][RTW89_QATAR][12] = 34, + [0][1][2][1][RTW89_UK][12] = 34, + [0][1][2][1][RTW89_FCC][14] = 68, + [0][1][2][1][RTW89_ETSI][14] = 34, + [0][1][2][1][RTW89_MKK][14] = 50, + [0][1][2][1][RTW89_IC][14] = 38, + [0][1][2][1][RTW89_KCC][14] = 68, + [0][1][2][1][RTW89_ACMA][14] = 34, + [0][1][2][1][RTW89_CHILE][14] = 30, + [0][1][2][1][RTW89_UKRAINE][14] = 28, + [0][1][2][1][RTW89_MEXICO][14] = 68, + [0][1][2][1][RTW89_CN][14] = 34, + [0][1][2][1][RTW89_QATAR][14] = 34, + [0][1][2][1][RTW89_UK][14] = 34, + [0][1][2][1][RTW89_FCC][15] = 68, + [0][1][2][1][RTW89_ETSI][15] = 34, + [0][1][2][1][RTW89_MKK][15] = 70, + [0][1][2][1][RTW89_IC][15] = 62, + [0][1][2][1][RTW89_KCC][15] = 66, + [0][1][2][1][RTW89_ACMA][15] = 34, + [0][1][2][1][RTW89_CHILE][15] = 30, + [0][1][2][1][RTW89_UKRAINE][15] = 28, + [0][1][2][1][RTW89_MEXICO][15] = 68, + [0][1][2][1][RTW89_CN][15] = 127, + [0][1][2][1][RTW89_QATAR][15] = 28, + [0][1][2][1][RTW89_UK][15] = 34, + [0][1][2][1][RTW89_FCC][17] = 68, + [0][1][2][1][RTW89_ETSI][17] = 34, + [0][1][2][1][RTW89_MKK][17] = 70, + [0][1][2][1][RTW89_IC][17] = 62, + [0][1][2][1][RTW89_KCC][17] = 66, + [0][1][2][1][RTW89_ACMA][17] = 34, + [0][1][2][1][RTW89_CHILE][17] = 30, + [0][1][2][1][RTW89_UKRAINE][17] = 28, + [0][1][2][1][RTW89_MEXICO][17] = 68, + [0][1][2][1][RTW89_CN][17] = 127, + [0][1][2][1][RTW89_QATAR][17] = 28, + [0][1][2][1][RTW89_UK][17] = 34, + [0][1][2][1][RTW89_FCC][19] = 68, + [0][1][2][1][RTW89_ETSI][19] = 34, + [0][1][2][1][RTW89_MKK][19] = 70, + [0][1][2][1][RTW89_IC][19] = 62, + [0][1][2][1][RTW89_KCC][19] = 66, + [0][1][2][1][RTW89_ACMA][19] = 34, + [0][1][2][1][RTW89_CHILE][19] = 30, + [0][1][2][1][RTW89_UKRAINE][19] = 28, + [0][1][2][1][RTW89_MEXICO][19] = 68, + [0][1][2][1][RTW89_CN][19] = 127, + [0][1][2][1][RTW89_QATAR][19] = 28, + [0][1][2][1][RTW89_UK][19] = 34, + [0][1][2][1][RTW89_FCC][21] = 68, + [0][1][2][1][RTW89_ETSI][21] = 34, + [0][1][2][1][RTW89_MKK][21] = 70, + [0][1][2][1][RTW89_IC][21] = 62, + [0][1][2][1][RTW89_KCC][21] = 66, + [0][1][2][1][RTW89_ACMA][21] = 34, + [0][1][2][1][RTW89_CHILE][21] = 30, + [0][1][2][1][RTW89_UKRAINE][21] = 28, + [0][1][2][1][RTW89_MEXICO][21] = 68, + [0][1][2][1][RTW89_CN][21] = 127, + [0][1][2][1][RTW89_QATAR][21] = 28, + [0][1][2][1][RTW89_UK][21] = 34, + [0][1][2][1][RTW89_FCC][23] = 68, + [0][1][2][1][RTW89_ETSI][23] = 34, + [0][1][2][1][RTW89_MKK][23] = 70, + [0][1][2][1][RTW89_IC][23] = 62, + [0][1][2][1][RTW89_KCC][23] = 66, + [0][1][2][1][RTW89_ACMA][23] = 34, + [0][1][2][1][RTW89_CHILE][23] = 30, + [0][1][2][1][RTW89_UKRAINE][23] = 28, + [0][1][2][1][RTW89_MEXICO][23] = 68, + [0][1][2][1][RTW89_CN][23] = 127, + [0][1][2][1][RTW89_QATAR][23] = 28, + [0][1][2][1][RTW89_UK][23] = 34, + [0][1][2][1][RTW89_FCC][25] = 68, + [0][1][2][1][RTW89_ETSI][25] = 34, + [0][1][2][1][RTW89_MKK][25] = 70, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_KCC][25] = 66, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_CHILE][25] = 30, + [0][1][2][1][RTW89_UKRAINE][25] = 28, + [0][1][2][1][RTW89_MEXICO][25] = 68, + [0][1][2][1][RTW89_CN][25] = 127, + [0][1][2][1][RTW89_QATAR][25] = 28, + [0][1][2][1][RTW89_UK][25] = 34, + [0][1][2][1][RTW89_FCC][27] = 68, + [0][1][2][1][RTW89_ETSI][27] = 34, + [0][1][2][1][RTW89_MKK][27] = 70, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_KCC][27] = 66, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_CHILE][27] = 30, + [0][1][2][1][RTW89_UKRAINE][27] = 28, + [0][1][2][1][RTW89_MEXICO][27] = 68, + [0][1][2][1][RTW89_CN][27] = 127, + [0][1][2][1][RTW89_QATAR][27] = 28, + [0][1][2][1][RTW89_UK][27] = 34, + [0][1][2][1][RTW89_FCC][29] = 68, + [0][1][2][1][RTW89_ETSI][29] = 34, + [0][1][2][1][RTW89_MKK][29] = 70, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_KCC][29] = 66, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_CHILE][29] = 30, + [0][1][2][1][RTW89_UKRAINE][29] = 28, + [0][1][2][1][RTW89_MEXICO][29] = 68, + [0][1][2][1][RTW89_CN][29] = 127, + [0][1][2][1][RTW89_QATAR][29] = 28, + [0][1][2][1][RTW89_UK][29] = 34, + [0][1][2][1][RTW89_FCC][31] = 68, + [0][1][2][1][RTW89_ETSI][31] = 34, + [0][1][2][1][RTW89_MKK][31] = 70, + [0][1][2][1][RTW89_IC][31] = 62, + [0][1][2][1][RTW89_KCC][31] = 66, + [0][1][2][1][RTW89_ACMA][31] = 34, + [0][1][2][1][RTW89_CHILE][31] = 30, + [0][1][2][1][RTW89_UKRAINE][31] = 28, + [0][1][2][1][RTW89_MEXICO][31] = 68, + [0][1][2][1][RTW89_CN][31] = 127, + [0][1][2][1][RTW89_QATAR][31] = 28, + [0][1][2][1][RTW89_UK][31] = 34, + [0][1][2][1][RTW89_FCC][33] = 68, + [0][1][2][1][RTW89_ETSI][33] = 34, + [0][1][2][1][RTW89_MKK][33] = 70, + [0][1][2][1][RTW89_IC][33] = 62, + [0][1][2][1][RTW89_KCC][33] = 66, + [0][1][2][1][RTW89_ACMA][33] = 34, + [0][1][2][1][RTW89_CHILE][33] = 30, + [0][1][2][1][RTW89_UKRAINE][33] = 28, + [0][1][2][1][RTW89_MEXICO][33] = 68, + [0][1][2][1][RTW89_CN][33] = 127, + [0][1][2][1][RTW89_QATAR][33] = 28, + [0][1][2][1][RTW89_UK][33] = 34, + [0][1][2][1][RTW89_FCC][35] = 64, + [0][1][2][1][RTW89_ETSI][35] = 34, + [0][1][2][1][RTW89_MKK][35] = 70, + [0][1][2][1][RTW89_IC][35] = 62, + [0][1][2][1][RTW89_KCC][35] = 66, + [0][1][2][1][RTW89_ACMA][35] = 34, + [0][1][2][1][RTW89_CHILE][35] = 30, + [0][1][2][1][RTW89_UKRAINE][35] = 28, + [0][1][2][1][RTW89_MEXICO][35] = 64, + [0][1][2][1][RTW89_CN][35] = 127, + [0][1][2][1][RTW89_QATAR][35] = 28, + [0][1][2][1][RTW89_UK][35] = 34, + [0][1][2][1][RTW89_FCC][37] = 68, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 70, + [0][1][2][1][RTW89_IC][37] = 62, + [0][1][2][1][RTW89_KCC][37] = 66, + [0][1][2][1][RTW89_ACMA][37] = 68, + [0][1][2][1][RTW89_CHILE][37] = 30, + [0][1][2][1][RTW89_UKRAINE][37] = 127, + [0][1][2][1][RTW89_MEXICO][37] = 68, + [0][1][2][1][RTW89_CN][37] = 127, + [0][1][2][1][RTW89_QATAR][37] = 127, + [0][1][2][1][RTW89_UK][37] = 62, + [0][1][2][1][RTW89_FCC][38] = 76, + [0][1][2][1][RTW89_ETSI][38] = 4, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 76, + [0][1][2][1][RTW89_KCC][38] = 66, + [0][1][2][1][RTW89_ACMA][38] = 76, + [0][1][2][1][RTW89_CHILE][38] = 30, + [0][1][2][1][RTW89_UKRAINE][38] = 4, + [0][1][2][1][RTW89_MEXICO][38] = 76, + [0][1][2][1][RTW89_CN][38] = 68, + [0][1][2][1][RTW89_QATAR][38] = 4, + [0][1][2][1][RTW89_UK][38] = 34, + [0][1][2][1][RTW89_FCC][40] = 76, + [0][1][2][1][RTW89_ETSI][40] = 4, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 76, + [0][1][2][1][RTW89_KCC][40] = 66, + [0][1][2][1][RTW89_ACMA][40] = 76, + [0][1][2][1][RTW89_CHILE][40] = 30, + [0][1][2][1][RTW89_UKRAINE][40] = 4, + [0][1][2][1][RTW89_MEXICO][40] = 76, + [0][1][2][1][RTW89_CN][40] = 70, + [0][1][2][1][RTW89_QATAR][40] = 4, + [0][1][2][1][RTW89_UK][40] = 34, + [0][1][2][1][RTW89_FCC][42] = 76, + [0][1][2][1][RTW89_ETSI][42] = 4, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 76, + [0][1][2][1][RTW89_KCC][42] = 66, + [0][1][2][1][RTW89_ACMA][42] = 76, + [0][1][2][1][RTW89_CHILE][42] = 30, + [0][1][2][1][RTW89_UKRAINE][42] = 4, + [0][1][2][1][RTW89_MEXICO][42] = 76, + [0][1][2][1][RTW89_CN][42] = 70, + [0][1][2][1][RTW89_QATAR][42] = 4, + [0][1][2][1][RTW89_UK][42] = 34, + [0][1][2][1][RTW89_FCC][44] = 76, + [0][1][2][1][RTW89_ETSI][44] = 4, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 76, + [0][1][2][1][RTW89_KCC][44] = 66, + [0][1][2][1][RTW89_ACMA][44] = 76, + [0][1][2][1][RTW89_CHILE][44] = 30, + [0][1][2][1][RTW89_UKRAINE][44] = 4, + [0][1][2][1][RTW89_MEXICO][44] = 76, + [0][1][2][1][RTW89_CN][44] = 70, + [0][1][2][1][RTW89_QATAR][44] = 4, + [0][1][2][1][RTW89_UK][44] = 34, + [0][1][2][1][RTW89_FCC][46] = 76, + [0][1][2][1][RTW89_ETSI][46] = 4, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 76, + [0][1][2][1][RTW89_KCC][46] = 66, + [0][1][2][1][RTW89_ACMA][46] = 76, + [0][1][2][1][RTW89_CHILE][46] = 30, + [0][1][2][1][RTW89_UKRAINE][46] = 4, + [0][1][2][1][RTW89_MEXICO][46] = 76, + [0][1][2][1][RTW89_CN][46] = 70, + [0][1][2][1][RTW89_QATAR][46] = 4, + [0][1][2][1][RTW89_UK][46] = 34, + [1][0][2][0][RTW89_FCC][1] = 68, + [1][0][2][0][RTW89_ETSI][1] = 64, + [1][0][2][0][RTW89_MKK][1] = 62, + [1][0][2][0][RTW89_IC][1] = 64, + [1][0][2][0][RTW89_KCC][1] = 72, + [1][0][2][0][RTW89_ACMA][1] = 64, + [1][0][2][0][RTW89_CHILE][1] = 30, + [1][0][2][0][RTW89_UKRAINE][1] = 52, + [1][0][2][0][RTW89_MEXICO][1] = 62, + [1][0][2][0][RTW89_CN][1] = 64, + [1][0][2][0][RTW89_QATAR][1] = 64, + [1][0][2][0][RTW89_UK][1] = 64, + [1][0][2][0][RTW89_FCC][5] = 72, + [1][0][2][0][RTW89_ETSI][5] = 64, + [1][0][2][0][RTW89_MKK][5] = 62, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 72, + [1][0][2][0][RTW89_ACMA][5] = 64, + [1][0][2][0][RTW89_CHILE][5] = 30, + [1][0][2][0][RTW89_UKRAINE][5] = 52, + [1][0][2][0][RTW89_MEXICO][5] = 62, + [1][0][2][0][RTW89_CN][5] = 64, + [1][0][2][0][RTW89_QATAR][5] = 64, + [1][0][2][0][RTW89_UK][5] = 64, + [1][0][2][0][RTW89_FCC][9] = 72, + [1][0][2][0][RTW89_ETSI][9] = 64, + [1][0][2][0][RTW89_MKK][9] = 62, + [1][0][2][0][RTW89_IC][9] = 64, + [1][0][2][0][RTW89_KCC][9] = 72, + [1][0][2][0][RTW89_ACMA][9] = 64, + [1][0][2][0][RTW89_CHILE][9] = 54, + [1][0][2][0][RTW89_UKRAINE][9] = 52, + [1][0][2][0][RTW89_MEXICO][9] = 72, + [1][0][2][0][RTW89_CN][9] = 64, + [1][0][2][0][RTW89_QATAR][9] = 64, + [1][0][2][0][RTW89_UK][9] = 64, + [1][0][2][0][RTW89_FCC][13] = 66, + [1][0][2][0][RTW89_ETSI][13] = 64, + [1][0][2][0][RTW89_MKK][13] = 62, + [1][0][2][0][RTW89_IC][13] = 64, + [1][0][2][0][RTW89_KCC][13] = 68, + [1][0][2][0][RTW89_ACMA][13] = 64, + [1][0][2][0][RTW89_CHILE][13] = 54, + [1][0][2][0][RTW89_UKRAINE][13] = 52, + [1][0][2][0][RTW89_MEXICO][13] = 66, + [1][0][2][0][RTW89_CN][13] = 64, + [1][0][2][0][RTW89_QATAR][13] = 64, + [1][0][2][0][RTW89_UK][13] = 64, + [1][0][2][0][RTW89_FCC][16] = 62, + [1][0][2][0][RTW89_ETSI][16] = 64, + [1][0][2][0][RTW89_MKK][16] = 72, + [1][0][2][0][RTW89_IC][16] = 62, + [1][0][2][0][RTW89_KCC][16] = 72, + [1][0][2][0][RTW89_ACMA][16] = 64, + [1][0][2][0][RTW89_CHILE][16] = 54, + [1][0][2][0][RTW89_UKRAINE][16] = 52, + [1][0][2][0][RTW89_MEXICO][16] = 62, + [1][0][2][0][RTW89_CN][16] = 127, + [1][0][2][0][RTW89_QATAR][16] = 52, + [1][0][2][0][RTW89_UK][16] = 64, + [1][0][2][0][RTW89_FCC][20] = 72, + [1][0][2][0][RTW89_ETSI][20] = 64, + [1][0][2][0][RTW89_MKK][20] = 72, + [1][0][2][0][RTW89_IC][20] = 72, + [1][0][2][0][RTW89_KCC][20] = 72, + [1][0][2][0][RTW89_ACMA][20] = 64, + [1][0][2][0][RTW89_CHILE][20] = 54, + [1][0][2][0][RTW89_UKRAINE][20] = 52, + [1][0][2][0][RTW89_MEXICO][20] = 72, + [1][0][2][0][RTW89_CN][20] = 127, + [1][0][2][0][RTW89_QATAR][20] = 52, + [1][0][2][0][RTW89_UK][20] = 64, + [1][0][2][0][RTW89_FCC][24] = 72, + [1][0][2][0][RTW89_ETSI][24] = 64, + [1][0][2][0][RTW89_MKK][24] = 72, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_KCC][24] = 72, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_CHILE][24] = 54, + [1][0][2][0][RTW89_UKRAINE][24] = 52, + [1][0][2][0][RTW89_MEXICO][24] = 72, + [1][0][2][0][RTW89_CN][24] = 127, + [1][0][2][0][RTW89_QATAR][24] = 52, + [1][0][2][0][RTW89_UK][24] = 64, + [1][0][2][0][RTW89_FCC][28] = 72, + [1][0][2][0][RTW89_ETSI][28] = 64, + [1][0][2][0][RTW89_MKK][28] = 72, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_KCC][28] = 72, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_CHILE][28] = 54, + [1][0][2][0][RTW89_UKRAINE][28] = 52, + [1][0][2][0][RTW89_MEXICO][28] = 72, + [1][0][2][0][RTW89_CN][28] = 127, + [1][0][2][0][RTW89_QATAR][28] = 52, + [1][0][2][0][RTW89_UK][28] = 64, + [1][0][2][0][RTW89_FCC][32] = 72, + [1][0][2][0][RTW89_ETSI][32] = 64, + [1][0][2][0][RTW89_MKK][32] = 72, + [1][0][2][0][RTW89_IC][32] = 72, + [1][0][2][0][RTW89_KCC][32] = 72, + [1][0][2][0][RTW89_ACMA][32] = 64, + [1][0][2][0][RTW89_CHILE][32] = 54, + [1][0][2][0][RTW89_UKRAINE][32] = 52, + [1][0][2][0][RTW89_MEXICO][32] = 72, + [1][0][2][0][RTW89_CN][32] = 127, + [1][0][2][0][RTW89_QATAR][32] = 52, + [1][0][2][0][RTW89_UK][32] = 64, + [1][0][2][0][RTW89_FCC][36] = 72, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 72, + [1][0][2][0][RTW89_IC][36] = 72, + [1][0][2][0][RTW89_KCC][36] = 72, + [1][0][2][0][RTW89_ACMA][36] = 72, + [1][0][2][0][RTW89_CHILE][36] = 54, + [1][0][2][0][RTW89_UKRAINE][36] = 127, + [1][0][2][0][RTW89_MEXICO][36] = 72, + [1][0][2][0][RTW89_CN][36] = 127, + [1][0][2][0][RTW89_QATAR][36] = 127, + [1][0][2][0][RTW89_UK][36] = 72, + [1][0][2][0][RTW89_FCC][39] = 72, + [1][0][2][0][RTW89_ETSI][39] = 28, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 72, + [1][0][2][0][RTW89_KCC][39] = 72, + [1][0][2][0][RTW89_ACMA][39] = 72, + [1][0][2][0][RTW89_CHILE][39] = 54, + [1][0][2][0][RTW89_UKRAINE][39] = 28, + [1][0][2][0][RTW89_MEXICO][39] = 72, + [1][0][2][0][RTW89_CN][39] = 68, + [1][0][2][0][RTW89_QATAR][39] = 28, + [1][0][2][0][RTW89_UK][39] = 64, + [1][0][2][0][RTW89_FCC][43] = 72, + [1][0][2][0][RTW89_ETSI][43] = 28, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 72, + [1][0][2][0][RTW89_KCC][43] = 72, + [1][0][2][0][RTW89_ACMA][43] = 72, + [1][0][2][0][RTW89_CHILE][43] = 54, + [1][0][2][0][RTW89_UKRAINE][43] = 28, + [1][0][2][0][RTW89_MEXICO][43] = 72, + [1][0][2][0][RTW89_CN][43] = 72, + [1][0][2][0][RTW89_QATAR][43] = 28, + [1][0][2][0][RTW89_UK][43] = 64, + [1][1][2][0][RTW89_FCC][1] = 58, + [1][1][2][0][RTW89_ETSI][1] = 52, + [1][1][2][0][RTW89_MKK][1] = 50, + [1][1][2][0][RTW89_IC][1] = 52, + [1][1][2][0][RTW89_KCC][1] = 66, + [1][1][2][0][RTW89_ACMA][1] = 52, + [1][1][2][0][RTW89_CHILE][1] = 18, + [1][1][2][0][RTW89_UKRAINE][1] = 40, + [1][1][2][0][RTW89_MEXICO][1] = 50, + [1][1][2][0][RTW89_CN][1] = 52, + [1][1][2][0][RTW89_QATAR][1] = 52, + [1][1][2][0][RTW89_UK][1] = 52, + [1][1][2][0][RTW89_FCC][5] = 72, + [1][1][2][0][RTW89_ETSI][5] = 52, + [1][1][2][0][RTW89_MKK][5] = 50, + [1][1][2][0][RTW89_IC][5] = 52, + [1][1][2][0][RTW89_KCC][5] = 50, + [1][1][2][0][RTW89_ACMA][5] = 52, + [1][1][2][0][RTW89_CHILE][5] = 18, + [1][1][2][0][RTW89_UKRAINE][5] = 40, + [1][1][2][0][RTW89_MEXICO][5] = 50, + [1][1][2][0][RTW89_CN][5] = 52, + [1][1][2][0][RTW89_QATAR][5] = 52, + [1][1][2][0][RTW89_UK][5] = 52, + [1][1][2][0][RTW89_FCC][9] = 72, + [1][1][2][0][RTW89_ETSI][9] = 52, + [1][1][2][0][RTW89_MKK][9] = 50, + [1][1][2][0][RTW89_IC][9] = 52, + [1][1][2][0][RTW89_KCC][9] = 66, + [1][1][2][0][RTW89_ACMA][9] = 52, + [1][1][2][0][RTW89_CHILE][9] = 42, + [1][1][2][0][RTW89_UKRAINE][9] = 40, + [1][1][2][0][RTW89_MEXICO][9] = 72, + [1][1][2][0][RTW89_CN][9] = 52, + [1][1][2][0][RTW89_QATAR][9] = 52, + [1][1][2][0][RTW89_UK][9] = 52, + [1][1][2][0][RTW89_FCC][13] = 58, + [1][1][2][0][RTW89_ETSI][13] = 52, + [1][1][2][0][RTW89_MKK][13] = 50, + [1][1][2][0][RTW89_IC][13] = 52, + [1][1][2][0][RTW89_KCC][13] = 66, + [1][1][2][0][RTW89_ACMA][13] = 52, + [1][1][2][0][RTW89_CHILE][13] = 42, + [1][1][2][0][RTW89_UKRAINE][13] = 40, + [1][1][2][0][RTW89_MEXICO][13] = 58, + [1][1][2][0][RTW89_CN][13] = 52, + [1][1][2][0][RTW89_QATAR][13] = 52, + [1][1][2][0][RTW89_UK][13] = 52, + [1][1][2][0][RTW89_FCC][16] = 56, + [1][1][2][0][RTW89_ETSI][16] = 52, + [1][1][2][0][RTW89_MKK][16] = 72, + [1][1][2][0][RTW89_IC][16] = 56, + [1][1][2][0][RTW89_KCC][16] = 64, + [1][1][2][0][RTW89_ACMA][16] = 52, + [1][1][2][0][RTW89_CHILE][16] = 42, + [1][1][2][0][RTW89_UKRAINE][16] = 40, + [1][1][2][0][RTW89_MEXICO][16] = 56, + [1][1][2][0][RTW89_CN][16] = 127, + [1][1][2][0][RTW89_QATAR][16] = 40, + [1][1][2][0][RTW89_UK][16] = 52, + [1][1][2][0][RTW89_FCC][20] = 72, + [1][1][2][0][RTW89_ETSI][20] = 52, + [1][1][2][0][RTW89_MKK][20] = 72, + [1][1][2][0][RTW89_IC][20] = 72, + [1][1][2][0][RTW89_KCC][20] = 66, + [1][1][2][0][RTW89_ACMA][20] = 52, + [1][1][2][0][RTW89_CHILE][20] = 42, + [1][1][2][0][RTW89_UKRAINE][20] = 40, + [1][1][2][0][RTW89_MEXICO][20] = 72, + [1][1][2][0][RTW89_CN][20] = 127, + [1][1][2][0][RTW89_QATAR][20] = 40, + [1][1][2][0][RTW89_UK][20] = 52, + [1][1][2][0][RTW89_FCC][24] = 72, + [1][1][2][0][RTW89_ETSI][24] = 52, + [1][1][2][0][RTW89_MKK][24] = 72, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_KCC][24] = 66, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_CHILE][24] = 42, + [1][1][2][0][RTW89_UKRAINE][24] = 40, + [1][1][2][0][RTW89_MEXICO][24] = 72, + [1][1][2][0][RTW89_CN][24] = 127, + [1][1][2][0][RTW89_QATAR][24] = 40, + [1][1][2][0][RTW89_UK][24] = 52, + [1][1][2][0][RTW89_FCC][28] = 72, + [1][1][2][0][RTW89_ETSI][28] = 52, + [1][1][2][0][RTW89_MKK][28] = 72, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_KCC][28] = 66, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_CHILE][28] = 42, + [1][1][2][0][RTW89_UKRAINE][28] = 40, + [1][1][2][0][RTW89_MEXICO][28] = 72, + [1][1][2][0][RTW89_CN][28] = 127, + [1][1][2][0][RTW89_QATAR][28] = 40, + [1][1][2][0][RTW89_UK][28] = 52, + [1][1][2][0][RTW89_FCC][32] = 68, + [1][1][2][0][RTW89_ETSI][32] = 52, + [1][1][2][0][RTW89_MKK][32] = 72, + [1][1][2][0][RTW89_IC][32] = 68, + [1][1][2][0][RTW89_KCC][32] = 66, + [1][1][2][0][RTW89_ACMA][32] = 52, + [1][1][2][0][RTW89_CHILE][32] = 42, + [1][1][2][0][RTW89_UKRAINE][32] = 40, + [1][1][2][0][RTW89_MEXICO][32] = 68, + [1][1][2][0][RTW89_CN][32] = 127, + [1][1][2][0][RTW89_QATAR][32] = 40, + [1][1][2][0][RTW89_UK][32] = 52, + [1][1][2][0][RTW89_FCC][36] = 72, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 72, + [1][1][2][0][RTW89_IC][36] = 72, + [1][1][2][0][RTW89_KCC][36] = 66, + [1][1][2][0][RTW89_ACMA][36] = 72, + [1][1][2][0][RTW89_CHILE][36] = 42, + [1][1][2][0][RTW89_UKRAINE][36] = 127, + [1][1][2][0][RTW89_MEXICO][36] = 72, + [1][1][2][0][RTW89_CN][36] = 127, + [1][1][2][0][RTW89_QATAR][36] = 127, + [1][1][2][0][RTW89_UK][36] = 72, + [1][1][2][0][RTW89_FCC][39] = 72, + [1][1][2][0][RTW89_ETSI][39] = 16, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 72, + [1][1][2][0][RTW89_KCC][39] = 66, + [1][1][2][0][RTW89_ACMA][39] = 72, + [1][1][2][0][RTW89_CHILE][39] = 42, + [1][1][2][0][RTW89_UKRAINE][39] = 16, + [1][1][2][0][RTW89_MEXICO][39] = 72, + [1][1][2][0][RTW89_CN][39] = 68, + [1][1][2][0][RTW89_QATAR][39] = 16, + [1][1][2][0][RTW89_UK][39] = 52, + [1][1][2][0][RTW89_FCC][43] = 72, + [1][1][2][0][RTW89_ETSI][43] = 16, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 72, + [1][1][2][0][RTW89_KCC][43] = 66, + [1][1][2][0][RTW89_ACMA][43] = 72, + [1][1][2][0][RTW89_CHILE][43] = 42, + [1][1][2][0][RTW89_UKRAINE][43] = 16, + [1][1][2][0][RTW89_MEXICO][43] = 72, + [1][1][2][0][RTW89_CN][43] = 72, + [1][1][2][0][RTW89_QATAR][43] = 16, + [1][1][2][0][RTW89_UK][43] = 52, + [1][1][2][1][RTW89_FCC][1] = 58, + [1][1][2][1][RTW89_ETSI][1] = 40, + [1][1][2][1][RTW89_MKK][1] = 50, + [1][1][2][1][RTW89_IC][1] = 40, + [1][1][2][1][RTW89_KCC][1] = 66, + [1][1][2][1][RTW89_ACMA][1] = 40, + [1][1][2][1][RTW89_CHILE][1] = 6, + [1][1][2][1][RTW89_UKRAINE][1] = 28, + [1][1][2][1][RTW89_MEXICO][1] = 50, + [1][1][2][1][RTW89_CN][1] = 40, + [1][1][2][1][RTW89_QATAR][1] = 40, + [1][1][2][1][RTW89_UK][1] = 40, + [1][1][2][1][RTW89_FCC][5] = 68, + [1][1][2][1][RTW89_ETSI][5] = 40, + [1][1][2][1][RTW89_MKK][5] = 50, + [1][1][2][1][RTW89_IC][5] = 40, + [1][1][2][1][RTW89_KCC][5] = 50, + [1][1][2][1][RTW89_ACMA][5] = 40, + [1][1][2][1][RTW89_CHILE][5] = 6, + [1][1][2][1][RTW89_UKRAINE][5] = 28, + [1][1][2][1][RTW89_MEXICO][5] = 50, + [1][1][2][1][RTW89_CN][5] = 40, + [1][1][2][1][RTW89_QATAR][5] = 40, + [1][1][2][1][RTW89_UK][5] = 40, + [1][1][2][1][RTW89_FCC][9] = 68, + [1][1][2][1][RTW89_ETSI][9] = 40, + [1][1][2][1][RTW89_MKK][9] = 50, + [1][1][2][1][RTW89_IC][9] = 40, + [1][1][2][1][RTW89_KCC][9] = 66, + [1][1][2][1][RTW89_ACMA][9] = 40, + [1][1][2][1][RTW89_CHILE][9] = 30, + [1][1][2][1][RTW89_UKRAINE][9] = 28, + [1][1][2][1][RTW89_MEXICO][9] = 68, + [1][1][2][1][RTW89_CN][9] = 40, + [1][1][2][1][RTW89_QATAR][9] = 40, + [1][1][2][1][RTW89_UK][9] = 40, + [1][1][2][1][RTW89_FCC][13] = 58, + [1][1][2][1][RTW89_ETSI][13] = 40, + [1][1][2][1][RTW89_MKK][13] = 50, + [1][1][2][1][RTW89_IC][13] = 40, + [1][1][2][1][RTW89_KCC][13] = 66, + [1][1][2][1][RTW89_ACMA][13] = 40, + [1][1][2][1][RTW89_CHILE][13] = 30, + [1][1][2][1][RTW89_UKRAINE][13] = 28, + [1][1][2][1][RTW89_MEXICO][13] = 58, + [1][1][2][1][RTW89_CN][13] = 40, + [1][1][2][1][RTW89_QATAR][13] = 40, + [1][1][2][1][RTW89_UK][13] = 40, + [1][1][2][1][RTW89_FCC][16] = 56, + [1][1][2][1][RTW89_ETSI][16] = 40, + [1][1][2][1][RTW89_MKK][16] = 72, + [1][1][2][1][RTW89_IC][16] = 56, + [1][1][2][1][RTW89_KCC][16] = 64, + [1][1][2][1][RTW89_ACMA][16] = 40, + [1][1][2][1][RTW89_CHILE][16] = 30, + [1][1][2][1][RTW89_UKRAINE][16] = 28, + [1][1][2][1][RTW89_MEXICO][16] = 56, + [1][1][2][1][RTW89_CN][16] = 127, + [1][1][2][1][RTW89_QATAR][16] = 28, + [1][1][2][1][RTW89_UK][16] = 40, + [1][1][2][1][RTW89_FCC][20] = 68, + [1][1][2][1][RTW89_ETSI][20] = 40, + [1][1][2][1][RTW89_MKK][20] = 72, + [1][1][2][1][RTW89_IC][20] = 68, + [1][1][2][1][RTW89_KCC][20] = 66, + [1][1][2][1][RTW89_ACMA][20] = 40, + [1][1][2][1][RTW89_CHILE][20] = 30, + [1][1][2][1][RTW89_UKRAINE][20] = 28, + [1][1][2][1][RTW89_MEXICO][20] = 68, + [1][1][2][1][RTW89_CN][20] = 127, + [1][1][2][1][RTW89_QATAR][20] = 28, + [1][1][2][1][RTW89_UK][20] = 40, + [1][1][2][1][RTW89_FCC][24] = 68, + [1][1][2][1][RTW89_ETSI][24] = 40, + [1][1][2][1][RTW89_MKK][24] = 72, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_KCC][24] = 66, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_CHILE][24] = 30, + [1][1][2][1][RTW89_UKRAINE][24] = 28, + [1][1][2][1][RTW89_MEXICO][24] = 68, + [1][1][2][1][RTW89_CN][24] = 127, + [1][1][2][1][RTW89_QATAR][24] = 28, + [1][1][2][1][RTW89_UK][24] = 40, + [1][1][2][1][RTW89_FCC][28] = 68, + [1][1][2][1][RTW89_ETSI][28] = 40, + [1][1][2][1][RTW89_MKK][28] = 72, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_KCC][28] = 66, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_CHILE][28] = 30, + [1][1][2][1][RTW89_UKRAINE][28] = 28, + [1][1][2][1][RTW89_MEXICO][28] = 68, + [1][1][2][1][RTW89_CN][28] = 127, + [1][1][2][1][RTW89_QATAR][28] = 28, + [1][1][2][1][RTW89_UK][28] = 40, + [1][1][2][1][RTW89_FCC][32] = 68, + [1][1][2][1][RTW89_ETSI][32] = 40, + [1][1][2][1][RTW89_MKK][32] = 72, + [1][1][2][1][RTW89_IC][32] = 68, + [1][1][2][1][RTW89_KCC][32] = 66, + [1][1][2][1][RTW89_ACMA][32] = 40, + [1][1][2][1][RTW89_CHILE][32] = 30, + [1][1][2][1][RTW89_UKRAINE][32] = 28, + [1][1][2][1][RTW89_MEXICO][32] = 68, + [1][1][2][1][RTW89_CN][32] = 127, + [1][1][2][1][RTW89_QATAR][32] = 28, + [1][1][2][1][RTW89_UK][32] = 40, + [1][1][2][1][RTW89_FCC][36] = 68, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 72, + [1][1][2][1][RTW89_IC][36] = 68, + [1][1][2][1][RTW89_KCC][36] = 66, + [1][1][2][1][RTW89_ACMA][36] = 68, + [1][1][2][1][RTW89_CHILE][36] = 30, + [1][1][2][1][RTW89_UKRAINE][36] = 127, + [1][1][2][1][RTW89_MEXICO][36] = 68, + [1][1][2][1][RTW89_CN][36] = 127, + [1][1][2][1][RTW89_QATAR][36] = 127, + [1][1][2][1][RTW89_UK][36] = 66, + [1][1][2][1][RTW89_FCC][39] = 72, + [1][1][2][1][RTW89_ETSI][39] = 4, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 72, + [1][1][2][1][RTW89_KCC][39] = 66, + [1][1][2][1][RTW89_ACMA][39] = 72, + [1][1][2][1][RTW89_CHILE][39] = 30, + [1][1][2][1][RTW89_UKRAINE][39] = 4, + [1][1][2][1][RTW89_MEXICO][39] = 72, + [1][1][2][1][RTW89_CN][39] = 62, + [1][1][2][1][RTW89_QATAR][39] = 4, + [1][1][2][1][RTW89_UK][39] = 40, + [1][1][2][1][RTW89_FCC][43] = 72, + [1][1][2][1][RTW89_ETSI][43] = 4, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 72, + [1][1][2][1][RTW89_KCC][43] = 66, + [1][1][2][1][RTW89_ACMA][43] = 72, + [1][1][2][1][RTW89_CHILE][43] = 30, + [1][1][2][1][RTW89_UKRAINE][43] = 4, + [1][1][2][1][RTW89_MEXICO][43] = 72, + [1][1][2][1][RTW89_CN][43] = 72, + [1][1][2][1][RTW89_QATAR][43] = 4, + [1][1][2][1][RTW89_UK][43] = 40, + [2][0][2][0][RTW89_FCC][3] = 64, + [2][0][2][0][RTW89_ETSI][3] = 64, + [2][0][2][0][RTW89_MKK][3] = 64, + [2][0][2][0][RTW89_IC][3] = 62, + [2][0][2][0][RTW89_KCC][3] = 72, + [2][0][2][0][RTW89_ACMA][3] = 64, + [2][0][2][0][RTW89_CHILE][3] = 30, + [2][0][2][0][RTW89_UKRAINE][3] = 52, + [2][0][2][0][RTW89_MEXICO][3] = 62, + [2][0][2][0][RTW89_CN][3] = 64, + [2][0][2][0][RTW89_QATAR][3] = 64, + [2][0][2][0][RTW89_UK][3] = 64, + [2][0][2][0][RTW89_FCC][11] = 64, + [2][0][2][0][RTW89_ETSI][11] = 64, + [2][0][2][0][RTW89_MKK][11] = 64, + [2][0][2][0][RTW89_IC][11] = 62, + [2][0][2][0][RTW89_KCC][11] = 72, + [2][0][2][0][RTW89_ACMA][11] = 64, + [2][0][2][0][RTW89_CHILE][11] = 54, + [2][0][2][0][RTW89_UKRAINE][11] = 52, + [2][0][2][0][RTW89_MEXICO][11] = 64, + [2][0][2][0][RTW89_CN][11] = 64, + [2][0][2][0][RTW89_QATAR][11] = 64, + [2][0][2][0][RTW89_UK][11] = 64, + [2][0][2][0][RTW89_FCC][18] = 62, + [2][0][2][0][RTW89_ETSI][18] = 64, + [2][0][2][0][RTW89_MKK][18] = 72, + [2][0][2][0][RTW89_IC][18] = 66, + [2][0][2][0][RTW89_KCC][18] = 70, + [2][0][2][0][RTW89_ACMA][18] = 64, + [2][0][2][0][RTW89_CHILE][18] = 54, + [2][0][2][0][RTW89_UKRAINE][18] = 52, + [2][0][2][0][RTW89_MEXICO][18] = 62, + [2][0][2][0][RTW89_CN][18] = 127, + [2][0][2][0][RTW89_QATAR][18] = 52, + [2][0][2][0][RTW89_UK][18] = 64, + [2][0][2][0][RTW89_FCC][26] = 72, + [2][0][2][0][RTW89_ETSI][26] = 64, + [2][0][2][0][RTW89_MKK][26] = 72, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_KCC][26] = 72, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_CHILE][26] = 54, + [2][0][2][0][RTW89_UKRAINE][26] = 52, + [2][0][2][0][RTW89_MEXICO][26] = 72, + [2][0][2][0][RTW89_CN][26] = 127, + [2][0][2][0][RTW89_QATAR][26] = 52, + [2][0][2][0][RTW89_UK][26] = 64, + [2][0][2][0][RTW89_FCC][34] = 72, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 72, + [2][0][2][0][RTW89_IC][34] = 72, + [2][0][2][0][RTW89_KCC][34] = 72, + [2][0][2][0][RTW89_ACMA][34] = 72, + [2][0][2][0][RTW89_CHILE][34] = 54, + [2][0][2][0][RTW89_UKRAINE][34] = 127, + [2][0][2][0][RTW89_MEXICO][34] = 72, + [2][0][2][0][RTW89_CN][34] = 127, + [2][0][2][0][RTW89_QATAR][34] = 127, + [2][0][2][0][RTW89_UK][34] = 72, + [2][0][2][0][RTW89_FCC][41] = 72, + [2][0][2][0][RTW89_ETSI][41] = 28, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 72, + [2][0][2][0][RTW89_KCC][41] = 68, + [2][0][2][0][RTW89_ACMA][41] = 72, + [2][0][2][0][RTW89_CHILE][41] = 54, + [2][0][2][0][RTW89_UKRAINE][41] = 28, + [2][0][2][0][RTW89_MEXICO][41] = 72, + [2][0][2][0][RTW89_CN][41] = 68, + [2][0][2][0][RTW89_QATAR][41] = 28, + [2][0][2][0][RTW89_UK][41] = 64, + [2][1][2][0][RTW89_FCC][3] = 56, + [2][1][2][0][RTW89_ETSI][3] = 52, + [2][1][2][0][RTW89_MKK][3] = 52, + [2][1][2][0][RTW89_IC][3] = 52, + [2][1][2][0][RTW89_KCC][3] = 66, + [2][1][2][0][RTW89_ACMA][3] = 52, + [2][1][2][0][RTW89_CHILE][3] = 18, + [2][1][2][0][RTW89_UKRAINE][3] = 40, + [2][1][2][0][RTW89_MEXICO][3] = 50, + [2][1][2][0][RTW89_CN][3] = 52, + [2][1][2][0][RTW89_QATAR][3] = 52, + [2][1][2][0][RTW89_UK][3] = 52, + [2][1][2][0][RTW89_FCC][11] = 56, + [2][1][2][0][RTW89_ETSI][11] = 52, + [2][1][2][0][RTW89_MKK][11] = 52, + [2][1][2][0][RTW89_IC][11] = 52, + [2][1][2][0][RTW89_KCC][11] = 64, + [2][1][2][0][RTW89_ACMA][11] = 52, + [2][1][2][0][RTW89_CHILE][11] = 42, + [2][1][2][0][RTW89_UKRAINE][11] = 40, + [2][1][2][0][RTW89_MEXICO][11] = 56, + [2][1][2][0][RTW89_CN][11] = 52, + [2][1][2][0][RTW89_QATAR][11] = 52, + [2][1][2][0][RTW89_UK][11] = 52, + [2][1][2][0][RTW89_FCC][18] = 56, + [2][1][2][0][RTW89_ETSI][18] = 52, + [2][1][2][0][RTW89_MKK][18] = 72, + [2][1][2][0][RTW89_IC][18] = 56, + [2][1][2][0][RTW89_KCC][18] = 58, + [2][1][2][0][RTW89_ACMA][18] = 52, + [2][1][2][0][RTW89_CHILE][18] = 42, + [2][1][2][0][RTW89_UKRAINE][18] = 40, + [2][1][2][0][RTW89_MEXICO][18] = 56, + [2][1][2][0][RTW89_CN][18] = 127, + [2][1][2][0][RTW89_QATAR][18] = 40, + [2][1][2][0][RTW89_UK][18] = 52, + [2][1][2][0][RTW89_FCC][26] = 72, + [2][1][2][0][RTW89_ETSI][26] = 52, + [2][1][2][0][RTW89_MKK][26] = 72, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_KCC][26] = 64, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_CHILE][26] = 42, + [2][1][2][0][RTW89_UKRAINE][26] = 40, + [2][1][2][0][RTW89_MEXICO][26] = 72, + [2][1][2][0][RTW89_CN][26] = 127, + [2][1][2][0][RTW89_QATAR][26] = 40, + [2][1][2][0][RTW89_UK][26] = 52, + [2][1][2][0][RTW89_FCC][34] = 72, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 72, + [2][1][2][0][RTW89_IC][34] = 72, + [2][1][2][0][RTW89_KCC][34] = 64, + [2][1][2][0][RTW89_ACMA][34] = 72, + [2][1][2][0][RTW89_CHILE][34] = 42, + [2][1][2][0][RTW89_UKRAINE][34] = 127, + [2][1][2][0][RTW89_MEXICO][34] = 72, + [2][1][2][0][RTW89_CN][34] = 127, + [2][1][2][0][RTW89_QATAR][34] = 127, + [2][1][2][0][RTW89_UK][34] = 72, + [2][1][2][0][RTW89_FCC][41] = 72, + [2][1][2][0][RTW89_ETSI][41] = 16, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 72, + [2][1][2][0][RTW89_KCC][41] = 58, + [2][1][2][0][RTW89_ACMA][41] = 72, + [2][1][2][0][RTW89_CHILE][41] = 42, + [2][1][2][0][RTW89_UKRAINE][41] = 16, + [2][1][2][0][RTW89_MEXICO][41] = 72, + [2][1][2][0][RTW89_CN][41] = 68, + [2][1][2][0][RTW89_QATAR][41] = 16, + [2][1][2][0][RTW89_UK][41] = 52, + [2][1][2][1][RTW89_FCC][3] = 56, + [2][1][2][1][RTW89_ETSI][3] = 40, + [2][1][2][1][RTW89_MKK][3] = 52, + [2][1][2][1][RTW89_IC][3] = 40, + [2][1][2][1][RTW89_KCC][3] = 66, + [2][1][2][1][RTW89_ACMA][3] = 40, + [2][1][2][1][RTW89_CHILE][3] = 6, + [2][1][2][1][RTW89_UKRAINE][3] = 28, + [2][1][2][1][RTW89_MEXICO][3] = 50, + [2][1][2][1][RTW89_CN][3] = 40, + [2][1][2][1][RTW89_QATAR][3] = 40, + [2][1][2][1][RTW89_UK][3] = 40, + [2][1][2][1][RTW89_FCC][11] = 56, + [2][1][2][1][RTW89_ETSI][11] = 40, + [2][1][2][1][RTW89_MKK][11] = 52, + [2][1][2][1][RTW89_IC][11] = 40, + [2][1][2][1][RTW89_KCC][11] = 64, + [2][1][2][1][RTW89_ACMA][11] = 40, + [2][1][2][1][RTW89_CHILE][11] = 30, + [2][1][2][1][RTW89_UKRAINE][11] = 28, + [2][1][2][1][RTW89_MEXICO][11] = 56, + [2][1][2][1][RTW89_CN][11] = 40, + [2][1][2][1][RTW89_QATAR][11] = 40, + [2][1][2][1][RTW89_UK][11] = 40, + [2][1][2][1][RTW89_FCC][18] = 56, + [2][1][2][1][RTW89_ETSI][18] = 40, + [2][1][2][1][RTW89_MKK][18] = 72, + [2][1][2][1][RTW89_IC][18] = 56, + [2][1][2][1][RTW89_KCC][18] = 58, + [2][1][2][1][RTW89_ACMA][18] = 40, + [2][1][2][1][RTW89_CHILE][18] = 30, + [2][1][2][1][RTW89_UKRAINE][18] = 28, + [2][1][2][1][RTW89_MEXICO][18] = 56, + [2][1][2][1][RTW89_CN][18] = 127, + [2][1][2][1][RTW89_QATAR][18] = 28, + [2][1][2][1][RTW89_UK][18] = 40, + [2][1][2][1][RTW89_FCC][26] = 68, + [2][1][2][1][RTW89_ETSI][26] = 40, + [2][1][2][1][RTW89_MKK][26] = 72, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_KCC][26] = 64, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_CHILE][26] = 30, + [2][1][2][1][RTW89_UKRAINE][26] = 28, + [2][1][2][1][RTW89_MEXICO][26] = 68, + [2][1][2][1][RTW89_CN][26] = 127, + [2][1][2][1][RTW89_QATAR][26] = 28, + [2][1][2][1][RTW89_UK][26] = 40, + [2][1][2][1][RTW89_FCC][34] = 68, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 72, + [2][1][2][1][RTW89_IC][34] = 68, + [2][1][2][1][RTW89_KCC][34] = 64, + [2][1][2][1][RTW89_ACMA][34] = 68, + [2][1][2][1][RTW89_CHILE][34] = 30, + [2][1][2][1][RTW89_UKRAINE][34] = 127, + [2][1][2][1][RTW89_MEXICO][34] = 68, + [2][1][2][1][RTW89_CN][34] = 127, + [2][1][2][1][RTW89_QATAR][34] = 127, + [2][1][2][1][RTW89_UK][34] = 66, + [2][1][2][1][RTW89_FCC][41] = 72, + [2][1][2][1][RTW89_ETSI][41] = 4, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 72, + [2][1][2][1][RTW89_KCC][41] = 58, + [2][1][2][1][RTW89_ACMA][41] = 72, + [2][1][2][1][RTW89_CHILE][41] = 30, + [2][1][2][1][RTW89_UKRAINE][41] = 4, + [2][1][2][1][RTW89_MEXICO][41] = 72, + [2][1][2][1][RTW89_CN][41] = 64, + [2][1][2][1][RTW89_QATAR][41] = 4, + [2][1][2][1][RTW89_UK][41] = 40, +}; + +static +const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 32, + [0][0][RTW89_WW][1] = 32, + [0][0][RTW89_WW][2] = 32, + [0][0][RTW89_WW][3] = 32, + [0][0][RTW89_WW][4] = 32, + [0][0][RTW89_WW][5] = 32, + [0][0][RTW89_WW][6] = 32, + [0][0][RTW89_WW][7] = 32, + [0][0][RTW89_WW][8] = 32, + [0][0][RTW89_WW][9] = 32, + [0][0][RTW89_WW][10] = 32, + [0][0][RTW89_WW][11] = 32, + [0][0][RTW89_WW][12] = 32, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 20, + [0][1][RTW89_WW][1] = 20, + [0][1][RTW89_WW][2] = 20, + [0][1][RTW89_WW][3] = 20, + [0][1][RTW89_WW][4] = 20, + [0][1][RTW89_WW][5] = 20, + [0][1][RTW89_WW][6] = 20, + [0][1][RTW89_WW][7] = 20, + [0][1][RTW89_WW][8] = 20, + [0][1][RTW89_WW][9] = 20, + [0][1][RTW89_WW][10] = 20, + [0][1][RTW89_WW][11] = 20, + [0][1][RTW89_WW][12] = 20, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 42, + [1][0][RTW89_WW][2] = 42, + [1][0][RTW89_WW][3] = 42, + [1][0][RTW89_WW][4] = 42, + [1][0][RTW89_WW][5] = 42, + [1][0][RTW89_WW][6] = 42, + [1][0][RTW89_WW][7] = 42, + [1][0][RTW89_WW][8] = 42, + [1][0][RTW89_WW][9] = 42, + [1][0][RTW89_WW][10] = 42, + [1][0][RTW89_WW][11] = 42, + [1][0][RTW89_WW][12] = 36, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 30, + [1][1][RTW89_WW][1] = 30, + [1][1][RTW89_WW][2] = 30, + [1][1][RTW89_WW][3] = 30, + [1][1][RTW89_WW][4] = 30, + [1][1][RTW89_WW][5] = 30, + [1][1][RTW89_WW][6] = 30, + [1][1][RTW89_WW][7] = 30, + [1][1][RTW89_WW][8] = 30, + [1][1][RTW89_WW][9] = 30, + [1][1][RTW89_WW][10] = 30, + [1][1][RTW89_WW][11] = 30, + [1][1][RTW89_WW][12] = 30, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 52, + [2][0][RTW89_WW][1] = 52, + [2][0][RTW89_WW][2] = 52, + [2][0][RTW89_WW][3] = 52, + [2][0][RTW89_WW][4] = 52, + [2][0][RTW89_WW][5] = 52, + [2][0][RTW89_WW][6] = 52, + [2][0][RTW89_WW][7] = 52, + [2][0][RTW89_WW][8] = 52, + [2][0][RTW89_WW][9] = 52, + [2][0][RTW89_WW][10] = 52, + [2][0][RTW89_WW][11] = 52, + [2][0][RTW89_WW][12] = 40, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 40, + [2][1][RTW89_WW][1] = 40, + [2][1][RTW89_WW][2] = 40, + [2][1][RTW89_WW][3] = 40, + [2][1][RTW89_WW][4] = 40, + [2][1][RTW89_WW][5] = 40, + [2][1][RTW89_WW][6] = 40, + [2][1][RTW89_WW][7] = 40, + [2][1][RTW89_WW][8] = 40, + [2][1][RTW89_WW][9] = 40, + [2][1][RTW89_WW][10] = 40, + [2][1][RTW89_WW][11] = 40, + [2][1][RTW89_WW][12] = 26, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 70, + [0][0][RTW89_ETSI][0] = 32, + [0][0][RTW89_MKK][0] = 40, + [0][0][RTW89_IC][0] = 70, + [0][0][RTW89_KCC][0] = 46, + [0][0][RTW89_ACMA][0] = 32, + [0][0][RTW89_CHILE][0] = 60, + [0][0][RTW89_UKRAINE][0] = 32, + [0][0][RTW89_MEXICO][0] = 70, + [0][0][RTW89_CN][0] = 32, + [0][0][RTW89_QATAR][0] = 32, + [0][0][RTW89_UK][0] = 32, + [0][0][RTW89_FCC][1] = 70, + [0][0][RTW89_ETSI][1] = 32, + [0][0][RTW89_MKK][1] = 40, + [0][0][RTW89_IC][1] = 70, + [0][0][RTW89_KCC][1] = 46, + [0][0][RTW89_ACMA][1] = 32, + [0][0][RTW89_CHILE][1] = 60, + [0][0][RTW89_UKRAINE][1] = 32, + [0][0][RTW89_MEXICO][1] = 70, + [0][0][RTW89_CN][1] = 32, + [0][0][RTW89_QATAR][1] = 32, + [0][0][RTW89_UK][1] = 32, + [0][0][RTW89_FCC][2] = 74, + [0][0][RTW89_ETSI][2] = 32, + [0][0][RTW89_MKK][2] = 40, + [0][0][RTW89_IC][2] = 74, + [0][0][RTW89_KCC][2] = 46, + [0][0][RTW89_ACMA][2] = 32, + [0][0][RTW89_CHILE][2] = 60, + [0][0][RTW89_UKRAINE][2] = 32, + [0][0][RTW89_MEXICO][2] = 74, + [0][0][RTW89_CN][2] = 32, + [0][0][RTW89_QATAR][2] = 32, + [0][0][RTW89_UK][2] = 32, + [0][0][RTW89_FCC][3] = 78, + [0][0][RTW89_ETSI][3] = 32, + [0][0][RTW89_MKK][3] = 40, + [0][0][RTW89_IC][3] = 78, + [0][0][RTW89_KCC][3] = 46, + [0][0][RTW89_ACMA][3] = 32, + [0][0][RTW89_CHILE][3] = 60, + [0][0][RTW89_UKRAINE][3] = 32, + [0][0][RTW89_MEXICO][3] = 78, + [0][0][RTW89_CN][3] = 32, + [0][0][RTW89_QATAR][3] = 32, + [0][0][RTW89_UK][3] = 32, + [0][0][RTW89_FCC][4] = 78, + [0][0][RTW89_ETSI][4] = 32, + [0][0][RTW89_MKK][4] = 40, + [0][0][RTW89_IC][4] = 78, + [0][0][RTW89_KCC][4] = 46, + [0][0][RTW89_ACMA][4] = 32, + [0][0][RTW89_CHILE][4] = 60, + [0][0][RTW89_UKRAINE][4] = 32, + [0][0][RTW89_MEXICO][4] = 78, + [0][0][RTW89_CN][4] = 32, + [0][0][RTW89_QATAR][4] = 32, + [0][0][RTW89_UK][4] = 32, + [0][0][RTW89_FCC][5] = 78, + [0][0][RTW89_ETSI][5] = 32, + [0][0][RTW89_MKK][5] = 40, + [0][0][RTW89_IC][5] = 78, + [0][0][RTW89_KCC][5] = 46, + [0][0][RTW89_ACMA][5] = 32, + [0][0][RTW89_CHILE][5] = 60, + [0][0][RTW89_UKRAINE][5] = 32, + [0][0][RTW89_MEXICO][5] = 78, + [0][0][RTW89_CN][5] = 32, + [0][0][RTW89_QATAR][5] = 32, + [0][0][RTW89_UK][5] = 32, + [0][0][RTW89_FCC][6] = 78, + [0][0][RTW89_ETSI][6] = 32, + [0][0][RTW89_MKK][6] = 40, + [0][0][RTW89_IC][6] = 78, + [0][0][RTW89_KCC][6] = 46, + [0][0][RTW89_ACMA][6] = 32, + [0][0][RTW89_CHILE][6] = 60, + [0][0][RTW89_UKRAINE][6] = 32, + [0][0][RTW89_MEXICO][6] = 78, + [0][0][RTW89_CN][6] = 32, + [0][0][RTW89_QATAR][6] = 32, + [0][0][RTW89_UK][6] = 32, + [0][0][RTW89_FCC][7] = 78, + [0][0][RTW89_ETSI][7] = 32, + [0][0][RTW89_MKK][7] = 40, + [0][0][RTW89_IC][7] = 78, + [0][0][RTW89_KCC][7] = 46, + [0][0][RTW89_ACMA][7] = 32, + [0][0][RTW89_CHILE][7] = 60, + [0][0][RTW89_UKRAINE][7] = 32, + [0][0][RTW89_MEXICO][7] = 78, + [0][0][RTW89_CN][7] = 32, + [0][0][RTW89_QATAR][7] = 32, + [0][0][RTW89_UK][7] = 32, + [0][0][RTW89_FCC][8] = 74, + [0][0][RTW89_ETSI][8] = 32, + [0][0][RTW89_MKK][8] = 40, + [0][0][RTW89_IC][8] = 74, + [0][0][RTW89_KCC][8] = 46, + [0][0][RTW89_ACMA][8] = 32, + [0][0][RTW89_CHILE][8] = 60, + [0][0][RTW89_UKRAINE][8] = 32, + [0][0][RTW89_MEXICO][8] = 74, + [0][0][RTW89_CN][8] = 32, + [0][0][RTW89_QATAR][8] = 32, + [0][0][RTW89_UK][8] = 32, + [0][0][RTW89_FCC][9] = 70, + [0][0][RTW89_ETSI][9] = 32, + [0][0][RTW89_MKK][9] = 40, + [0][0][RTW89_IC][9] = 70, + [0][0][RTW89_KCC][9] = 46, + [0][0][RTW89_ACMA][9] = 32, + [0][0][RTW89_CHILE][9] = 60, + [0][0][RTW89_UKRAINE][9] = 32, + [0][0][RTW89_MEXICO][9] = 70, + [0][0][RTW89_CN][9] = 32, + [0][0][RTW89_QATAR][9] = 32, + [0][0][RTW89_UK][9] = 32, + [0][0][RTW89_FCC][10] = 70, + [0][0][RTW89_ETSI][10] = 32, + [0][0][RTW89_MKK][10] = 40, + [0][0][RTW89_IC][10] = 70, + [0][0][RTW89_KCC][10] = 46, + [0][0][RTW89_ACMA][10] = 32, + [0][0][RTW89_CHILE][10] = 60, + [0][0][RTW89_UKRAINE][10] = 32, + [0][0][RTW89_MEXICO][10] = 70, + [0][0][RTW89_CN][10] = 32, + [0][0][RTW89_QATAR][10] = 32, + [0][0][RTW89_UK][10] = 32, + [0][0][RTW89_FCC][11] = 58, + [0][0][RTW89_ETSI][11] = 32, + [0][0][RTW89_MKK][11] = 40, + [0][0][RTW89_IC][11] = 58, + [0][0][RTW89_KCC][11] = 46, + [0][0][RTW89_ACMA][11] = 32, + [0][0][RTW89_CHILE][11] = 58, + [0][0][RTW89_UKRAINE][11] = 32, + [0][0][RTW89_MEXICO][11] = 58, + [0][0][RTW89_CN][11] = 32, + [0][0][RTW89_QATAR][11] = 32, + [0][0][RTW89_UK][11] = 32, + [0][0][RTW89_FCC][12] = 34, + [0][0][RTW89_ETSI][12] = 32, + [0][0][RTW89_MKK][12] = 40, + [0][0][RTW89_IC][12] = 34, + [0][0][RTW89_KCC][12] = 46, + [0][0][RTW89_ACMA][12] = 32, + [0][0][RTW89_CHILE][12] = 34, + [0][0][RTW89_UKRAINE][12] = 32, + [0][0][RTW89_MEXICO][12] = 34, + [0][0][RTW89_CN][12] = 32, + [0][0][RTW89_QATAR][12] = 32, + [0][0][RTW89_UK][12] = 32, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_KCC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][0][RTW89_CHILE][13] = 127, + [0][0][RTW89_UKRAINE][13] = 127, + [0][0][RTW89_MEXICO][13] = 127, + [0][0][RTW89_CN][13] = 127, + [0][0][RTW89_QATAR][13] = 127, + [0][0][RTW89_UK][13] = 127, + [0][1][RTW89_FCC][0] = 64, + [0][1][RTW89_ETSI][0] = 20, + [0][1][RTW89_MKK][0] = 28, + [0][1][RTW89_IC][0] = 64, + [0][1][RTW89_KCC][0] = 32, + [0][1][RTW89_ACMA][0] = 20, + [0][1][RTW89_CHILE][0] = 48, + [0][1][RTW89_UKRAINE][0] = 20, + [0][1][RTW89_MEXICO][0] = 64, + [0][1][RTW89_CN][0] = 20, + [0][1][RTW89_QATAR][0] = 20, + [0][1][RTW89_UK][0] = 20, + [0][1][RTW89_FCC][1] = 64, + [0][1][RTW89_ETSI][1] = 20, + [0][1][RTW89_MKK][1] = 28, + [0][1][RTW89_IC][1] = 64, + [0][1][RTW89_KCC][1] = 32, + [0][1][RTW89_ACMA][1] = 20, + [0][1][RTW89_CHILE][1] = 48, + [0][1][RTW89_UKRAINE][1] = 20, + [0][1][RTW89_MEXICO][1] = 64, + [0][1][RTW89_CN][1] = 20, + [0][1][RTW89_QATAR][1] = 20, + [0][1][RTW89_UK][1] = 20, + [0][1][RTW89_FCC][2] = 68, + [0][1][RTW89_ETSI][2] = 20, + [0][1][RTW89_MKK][2] = 28, + [0][1][RTW89_IC][2] = 68, + [0][1][RTW89_KCC][2] = 32, + [0][1][RTW89_ACMA][2] = 20, + [0][1][RTW89_CHILE][2] = 48, + [0][1][RTW89_UKRAINE][2] = 20, + [0][1][RTW89_MEXICO][2] = 68, + [0][1][RTW89_CN][2] = 20, + [0][1][RTW89_QATAR][2] = 20, + [0][1][RTW89_UK][2] = 20, + [0][1][RTW89_FCC][3] = 72, + [0][1][RTW89_ETSI][3] = 20, + [0][1][RTW89_MKK][3] = 28, + [0][1][RTW89_IC][3] = 72, + [0][1][RTW89_KCC][3] = 32, + [0][1][RTW89_ACMA][3] = 20, + [0][1][RTW89_CHILE][3] = 48, + [0][1][RTW89_UKRAINE][3] = 20, + [0][1][RTW89_MEXICO][3] = 72, + [0][1][RTW89_CN][3] = 20, + [0][1][RTW89_QATAR][3] = 20, + [0][1][RTW89_UK][3] = 20, + [0][1][RTW89_FCC][4] = 76, + [0][1][RTW89_ETSI][4] = 20, + [0][1][RTW89_MKK][4] = 28, + [0][1][RTW89_IC][4] = 76, + [0][1][RTW89_KCC][4] = 32, + [0][1][RTW89_ACMA][4] = 20, + [0][1][RTW89_CHILE][4] = 48, + [0][1][RTW89_UKRAINE][4] = 20, + [0][1][RTW89_MEXICO][4] = 76, + [0][1][RTW89_CN][4] = 20, + [0][1][RTW89_QATAR][4] = 20, + [0][1][RTW89_UK][4] = 20, + [0][1][RTW89_FCC][5] = 78, + [0][1][RTW89_ETSI][5] = 20, + [0][1][RTW89_MKK][5] = 28, + [0][1][RTW89_IC][5] = 78, + [0][1][RTW89_KCC][5] = 32, + [0][1][RTW89_ACMA][5] = 20, + [0][1][RTW89_CHILE][5] = 48, + [0][1][RTW89_UKRAINE][5] = 20, + [0][1][RTW89_MEXICO][5] = 78, + [0][1][RTW89_CN][5] = 20, + [0][1][RTW89_QATAR][5] = 20, + [0][1][RTW89_UK][5] = 20, + [0][1][RTW89_FCC][6] = 76, + [0][1][RTW89_ETSI][6] = 20, + [0][1][RTW89_MKK][6] = 28, + [0][1][RTW89_IC][6] = 76, + [0][1][RTW89_KCC][6] = 32, + [0][1][RTW89_ACMA][6] = 20, + [0][1][RTW89_CHILE][6] = 48, + [0][1][RTW89_UKRAINE][6] = 20, + [0][1][RTW89_MEXICO][6] = 76, + [0][1][RTW89_CN][6] = 20, + [0][1][RTW89_QATAR][6] = 20, + [0][1][RTW89_UK][6] = 20, + [0][1][RTW89_FCC][7] = 72, + [0][1][RTW89_ETSI][7] = 20, + [0][1][RTW89_MKK][7] = 28, + [0][1][RTW89_IC][7] = 72, + [0][1][RTW89_KCC][7] = 32, + [0][1][RTW89_ACMA][7] = 20, + [0][1][RTW89_CHILE][7] = 48, + [0][1][RTW89_UKRAINE][7] = 20, + [0][1][RTW89_MEXICO][7] = 72, + [0][1][RTW89_CN][7] = 20, + [0][1][RTW89_QATAR][7] = 20, + [0][1][RTW89_UK][7] = 20, + [0][1][RTW89_FCC][8] = 68, + [0][1][RTW89_ETSI][8] = 20, + [0][1][RTW89_MKK][8] = 28, + [0][1][RTW89_IC][8] = 68, + [0][1][RTW89_KCC][8] = 32, + [0][1][RTW89_ACMA][8] = 20, + [0][1][RTW89_CHILE][8] = 48, + [0][1][RTW89_UKRAINE][8] = 20, + [0][1][RTW89_MEXICO][8] = 68, + [0][1][RTW89_CN][8] = 20, + [0][1][RTW89_QATAR][8] = 20, + [0][1][RTW89_UK][8] = 20, + [0][1][RTW89_FCC][9] = 64, + [0][1][RTW89_ETSI][9] = 20, + [0][1][RTW89_MKK][9] = 28, + [0][1][RTW89_IC][9] = 64, + [0][1][RTW89_KCC][9] = 32, + [0][1][RTW89_ACMA][9] = 20, + [0][1][RTW89_CHILE][9] = 48, + [0][1][RTW89_UKRAINE][9] = 20, + [0][1][RTW89_MEXICO][9] = 64, + [0][1][RTW89_CN][9] = 20, + [0][1][RTW89_QATAR][9] = 20, + [0][1][RTW89_UK][9] = 20, + [0][1][RTW89_FCC][10] = 64, + [0][1][RTW89_ETSI][10] = 20, + [0][1][RTW89_MKK][10] = 28, + [0][1][RTW89_IC][10] = 64, + [0][1][RTW89_KCC][10] = 32, + [0][1][RTW89_ACMA][10] = 20, + [0][1][RTW89_CHILE][10] = 48, + [0][1][RTW89_UKRAINE][10] = 20, + [0][1][RTW89_MEXICO][10] = 64, + [0][1][RTW89_CN][10] = 20, + [0][1][RTW89_QATAR][10] = 20, + [0][1][RTW89_UK][10] = 20, + [0][1][RTW89_FCC][11] = 54, + [0][1][RTW89_ETSI][11] = 20, + [0][1][RTW89_MKK][11] = 28, + [0][1][RTW89_IC][11] = 54, + [0][1][RTW89_KCC][11] = 32, + [0][1][RTW89_ACMA][11] = 20, + [0][1][RTW89_CHILE][11] = 48, + [0][1][RTW89_UKRAINE][11] = 20, + [0][1][RTW89_MEXICO][11] = 54, + [0][1][RTW89_CN][11] = 20, + [0][1][RTW89_QATAR][11] = 20, + [0][1][RTW89_UK][11] = 20, + [0][1][RTW89_FCC][12] = 32, + [0][1][RTW89_ETSI][12] = 20, + [0][1][RTW89_MKK][12] = 28, + [0][1][RTW89_IC][12] = 32, + [0][1][RTW89_KCC][12] = 32, + [0][1][RTW89_ACMA][12] = 20, + [0][1][RTW89_CHILE][12] = 32, + [0][1][RTW89_UKRAINE][12] = 20, + [0][1][RTW89_MEXICO][12] = 32, + [0][1][RTW89_CN][12] = 20, + [0][1][RTW89_QATAR][12] = 20, + [0][1][RTW89_UK][12] = 20, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_KCC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [0][1][RTW89_CHILE][13] = 127, + [0][1][RTW89_UKRAINE][13] = 127, + [0][1][RTW89_MEXICO][13] = 127, + [0][1][RTW89_CN][13] = 127, + [0][1][RTW89_QATAR][13] = 127, + [0][1][RTW89_UK][13] = 127, + [1][0][RTW89_FCC][0] = 72, + [1][0][RTW89_ETSI][0] = 42, + [1][0][RTW89_MKK][0] = 50, + [1][0][RTW89_IC][0] = 72, + [1][0][RTW89_KCC][0] = 58, + [1][0][RTW89_ACMA][0] = 42, + [1][0][RTW89_CHILE][0] = 60, + [1][0][RTW89_UKRAINE][0] = 42, + [1][0][RTW89_MEXICO][0] = 72, + [1][0][RTW89_CN][0] = 42, + [1][0][RTW89_QATAR][0] = 42, + [1][0][RTW89_UK][0] = 42, + [1][0][RTW89_FCC][1] = 72, + [1][0][RTW89_ETSI][1] = 42, + [1][0][RTW89_MKK][1] = 50, + [1][0][RTW89_IC][1] = 72, + [1][0][RTW89_KCC][1] = 58, + [1][0][RTW89_ACMA][1] = 42, + [1][0][RTW89_CHILE][1] = 60, + [1][0][RTW89_UKRAINE][1] = 42, + [1][0][RTW89_MEXICO][1] = 72, + [1][0][RTW89_CN][1] = 42, + [1][0][RTW89_QATAR][1] = 42, + [1][0][RTW89_UK][1] = 42, + [1][0][RTW89_FCC][2] = 76, + [1][0][RTW89_ETSI][2] = 42, + [1][0][RTW89_MKK][2] = 50, + [1][0][RTW89_IC][2] = 76, + [1][0][RTW89_KCC][2] = 58, + [1][0][RTW89_ACMA][2] = 42, + [1][0][RTW89_CHILE][2] = 60, + [1][0][RTW89_UKRAINE][2] = 42, + [1][0][RTW89_MEXICO][2] = 76, + [1][0][RTW89_CN][2] = 42, + [1][0][RTW89_QATAR][2] = 42, + [1][0][RTW89_UK][2] = 42, + [1][0][RTW89_FCC][3] = 78, + [1][0][RTW89_ETSI][3] = 42, + [1][0][RTW89_MKK][3] = 50, + [1][0][RTW89_IC][3] = 78, + [1][0][RTW89_KCC][3] = 58, + [1][0][RTW89_ACMA][3] = 42, + [1][0][RTW89_CHILE][3] = 60, + [1][0][RTW89_UKRAINE][3] = 42, + [1][0][RTW89_MEXICO][3] = 78, + [1][0][RTW89_CN][3] = 42, + [1][0][RTW89_QATAR][3] = 42, + [1][0][RTW89_UK][3] = 42, + [1][0][RTW89_FCC][4] = 78, + [1][0][RTW89_ETSI][4] = 42, + [1][0][RTW89_MKK][4] = 50, + [1][0][RTW89_IC][4] = 78, + [1][0][RTW89_KCC][4] = 58, + [1][0][RTW89_ACMA][4] = 42, + [1][0][RTW89_CHILE][4] = 60, + [1][0][RTW89_UKRAINE][4] = 42, + [1][0][RTW89_MEXICO][4] = 78, + [1][0][RTW89_CN][4] = 42, + [1][0][RTW89_QATAR][4] = 42, + [1][0][RTW89_UK][4] = 42, + [1][0][RTW89_FCC][5] = 78, + [1][0][RTW89_ETSI][5] = 42, + [1][0][RTW89_MKK][5] = 50, + [1][0][RTW89_IC][5] = 78, + [1][0][RTW89_KCC][5] = 58, + [1][0][RTW89_ACMA][5] = 42, + [1][0][RTW89_CHILE][5] = 60, + [1][0][RTW89_UKRAINE][5] = 42, + [1][0][RTW89_MEXICO][5] = 78, + [1][0][RTW89_CN][5] = 42, + [1][0][RTW89_QATAR][5] = 42, + [1][0][RTW89_UK][5] = 42, + [1][0][RTW89_FCC][6] = 78, + [1][0][RTW89_ETSI][6] = 42, + [1][0][RTW89_MKK][6] = 50, + [1][0][RTW89_IC][6] = 78, + [1][0][RTW89_KCC][6] = 58, + [1][0][RTW89_ACMA][6] = 42, + [1][0][RTW89_CHILE][6] = 60, + [1][0][RTW89_UKRAINE][6] = 42, + [1][0][RTW89_MEXICO][6] = 78, + [1][0][RTW89_CN][6] = 42, + [1][0][RTW89_QATAR][6] = 42, + [1][0][RTW89_UK][6] = 42, + [1][0][RTW89_FCC][7] = 78, + [1][0][RTW89_ETSI][7] = 42, + [1][0][RTW89_MKK][7] = 50, + [1][0][RTW89_IC][7] = 78, + [1][0][RTW89_KCC][7] = 58, + [1][0][RTW89_ACMA][7] = 42, + [1][0][RTW89_CHILE][7] = 60, + [1][0][RTW89_UKRAINE][7] = 42, + [1][0][RTW89_MEXICO][7] = 78, + [1][0][RTW89_CN][7] = 42, + [1][0][RTW89_QATAR][7] = 42, + [1][0][RTW89_UK][7] = 42, + [1][0][RTW89_FCC][8] = 78, + [1][0][RTW89_ETSI][8] = 42, + [1][0][RTW89_MKK][8] = 50, + [1][0][RTW89_IC][8] = 78, + [1][0][RTW89_KCC][8] = 58, + [1][0][RTW89_ACMA][8] = 42, + [1][0][RTW89_CHILE][8] = 60, + [1][0][RTW89_UKRAINE][8] = 42, + [1][0][RTW89_MEXICO][8] = 78, + [1][0][RTW89_CN][8] = 42, + [1][0][RTW89_QATAR][8] = 42, + [1][0][RTW89_UK][8] = 42, + [1][0][RTW89_FCC][9] = 74, + [1][0][RTW89_ETSI][9] = 42, + [1][0][RTW89_MKK][9] = 50, + [1][0][RTW89_IC][9] = 74, + [1][0][RTW89_KCC][9] = 58, + [1][0][RTW89_ACMA][9] = 42, + [1][0][RTW89_CHILE][9] = 60, + [1][0][RTW89_UKRAINE][9] = 42, + [1][0][RTW89_MEXICO][9] = 74, + [1][0][RTW89_CN][9] = 42, + [1][0][RTW89_QATAR][9] = 42, + [1][0][RTW89_UK][9] = 42, + [1][0][RTW89_FCC][10] = 74, + [1][0][RTW89_ETSI][10] = 42, + [1][0][RTW89_MKK][10] = 50, + [1][0][RTW89_IC][10] = 74, + [1][0][RTW89_KCC][10] = 58, + [1][0][RTW89_ACMA][10] = 42, + [1][0][RTW89_CHILE][10] = 60, + [1][0][RTW89_UKRAINE][10] = 42, + [1][0][RTW89_MEXICO][10] = 74, + [1][0][RTW89_CN][10] = 42, + [1][0][RTW89_QATAR][10] = 42, + [1][0][RTW89_UK][10] = 42, + [1][0][RTW89_FCC][11] = 64, + [1][0][RTW89_ETSI][11] = 42, + [1][0][RTW89_MKK][11] = 50, + [1][0][RTW89_IC][11] = 64, + [1][0][RTW89_KCC][11] = 58, + [1][0][RTW89_ACMA][11] = 42, + [1][0][RTW89_CHILE][11] = 60, + [1][0][RTW89_UKRAINE][11] = 42, + [1][0][RTW89_MEXICO][11] = 64, + [1][0][RTW89_CN][11] = 42, + [1][0][RTW89_QATAR][11] = 42, + [1][0][RTW89_UK][11] = 42, + [1][0][RTW89_FCC][12] = 36, + [1][0][RTW89_ETSI][12] = 42, + [1][0][RTW89_MKK][12] = 50, + [1][0][RTW89_IC][12] = 36, + [1][0][RTW89_KCC][12] = 58, + [1][0][RTW89_ACMA][12] = 42, + [1][0][RTW89_CHILE][12] = 36, + [1][0][RTW89_UKRAINE][12] = 42, + [1][0][RTW89_MEXICO][12] = 36, + [1][0][RTW89_CN][12] = 42, + [1][0][RTW89_QATAR][12] = 42, + [1][0][RTW89_UK][12] = 42, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_KCC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][0][RTW89_CHILE][13] = 127, + [1][0][RTW89_UKRAINE][13] = 127, + [1][0][RTW89_MEXICO][13] = 127, + [1][0][RTW89_CN][13] = 127, + [1][0][RTW89_QATAR][13] = 127, + [1][0][RTW89_UK][13] = 127, + [1][1][RTW89_FCC][0] = 66, + [1][1][RTW89_ETSI][0] = 30, + [1][1][RTW89_MKK][0] = 38, + [1][1][RTW89_IC][0] = 66, + [1][1][RTW89_KCC][0] = 44, + [1][1][RTW89_ACMA][0] = 30, + [1][1][RTW89_CHILE][0] = 48, + [1][1][RTW89_UKRAINE][0] = 30, + [1][1][RTW89_MEXICO][0] = 66, + [1][1][RTW89_CN][0] = 30, + [1][1][RTW89_QATAR][0] = 30, + [1][1][RTW89_UK][0] = 30, + [1][1][RTW89_FCC][1] = 66, + [1][1][RTW89_ETSI][1] = 30, + [1][1][RTW89_MKK][1] = 38, + [1][1][RTW89_IC][1] = 66, + [1][1][RTW89_KCC][1] = 44, + [1][1][RTW89_ACMA][1] = 30, + [1][1][RTW89_CHILE][1] = 48, + [1][1][RTW89_UKRAINE][1] = 30, + [1][1][RTW89_MEXICO][1] = 66, + [1][1][RTW89_CN][1] = 30, + [1][1][RTW89_QATAR][1] = 30, + [1][1][RTW89_UK][1] = 30, + [1][1][RTW89_FCC][2] = 70, + [1][1][RTW89_ETSI][2] = 30, + [1][1][RTW89_MKK][2] = 38, + [1][1][RTW89_IC][2] = 70, + [1][1][RTW89_KCC][2] = 44, + [1][1][RTW89_ACMA][2] = 30, + [1][1][RTW89_CHILE][2] = 48, + [1][1][RTW89_UKRAINE][2] = 30, + [1][1][RTW89_MEXICO][2] = 70, + [1][1][RTW89_CN][2] = 30, + [1][1][RTW89_QATAR][2] = 30, + [1][1][RTW89_UK][2] = 30, + [1][1][RTW89_FCC][3] = 74, + [1][1][RTW89_ETSI][3] = 30, + [1][1][RTW89_MKK][3] = 38, + [1][1][RTW89_IC][3] = 74, + [1][1][RTW89_KCC][3] = 44, + [1][1][RTW89_ACMA][3] = 30, + [1][1][RTW89_CHILE][3] = 48, + [1][1][RTW89_UKRAINE][3] = 30, + [1][1][RTW89_MEXICO][3] = 74, + [1][1][RTW89_CN][3] = 30, + [1][1][RTW89_QATAR][3] = 30, + [1][1][RTW89_UK][3] = 30, + [1][1][RTW89_FCC][4] = 78, + [1][1][RTW89_ETSI][4] = 30, + [1][1][RTW89_MKK][4] = 38, + [1][1][RTW89_IC][4] = 78, + [1][1][RTW89_KCC][4] = 44, + [1][1][RTW89_ACMA][4] = 30, + [1][1][RTW89_CHILE][4] = 48, + [1][1][RTW89_UKRAINE][4] = 30, + [1][1][RTW89_MEXICO][4] = 78, + [1][1][RTW89_CN][4] = 30, + [1][1][RTW89_QATAR][4] = 30, + [1][1][RTW89_UK][4] = 30, + [1][1][RTW89_FCC][5] = 78, + [1][1][RTW89_ETSI][5] = 30, + [1][1][RTW89_MKK][5] = 38, + [1][1][RTW89_IC][5] = 78, + [1][1][RTW89_KCC][5] = 44, + [1][1][RTW89_ACMA][5] = 30, + [1][1][RTW89_CHILE][5] = 48, + [1][1][RTW89_UKRAINE][5] = 30, + [1][1][RTW89_MEXICO][5] = 78, + [1][1][RTW89_CN][5] = 30, + [1][1][RTW89_QATAR][5] = 30, + [1][1][RTW89_UK][5] = 30, + [1][1][RTW89_FCC][6] = 78, + [1][1][RTW89_ETSI][6] = 30, + [1][1][RTW89_MKK][6] = 38, + [1][1][RTW89_IC][6] = 78, + [1][1][RTW89_KCC][6] = 44, + [1][1][RTW89_ACMA][6] = 30, + [1][1][RTW89_CHILE][6] = 48, + [1][1][RTW89_UKRAINE][6] = 30, + [1][1][RTW89_MEXICO][6] = 78, + [1][1][RTW89_CN][6] = 30, + [1][1][RTW89_QATAR][6] = 30, + [1][1][RTW89_UK][6] = 30, + [1][1][RTW89_FCC][7] = 74, + [1][1][RTW89_ETSI][7] = 30, + [1][1][RTW89_MKK][7] = 38, + [1][1][RTW89_IC][7] = 74, + [1][1][RTW89_KCC][7] = 44, + [1][1][RTW89_ACMA][7] = 30, + [1][1][RTW89_CHILE][7] = 48, + [1][1][RTW89_UKRAINE][7] = 30, + [1][1][RTW89_MEXICO][7] = 74, + [1][1][RTW89_CN][7] = 30, + [1][1][RTW89_QATAR][7] = 30, + [1][1][RTW89_UK][7] = 30, + [1][1][RTW89_FCC][8] = 70, + [1][1][RTW89_ETSI][8] = 30, + [1][1][RTW89_MKK][8] = 38, + [1][1][RTW89_IC][8] = 70, + [1][1][RTW89_KCC][8] = 44, + [1][1][RTW89_ACMA][8] = 30, + [1][1][RTW89_CHILE][8] = 48, + [1][1][RTW89_UKRAINE][8] = 30, + [1][1][RTW89_MEXICO][8] = 70, + [1][1][RTW89_CN][8] = 30, + [1][1][RTW89_QATAR][8] = 30, + [1][1][RTW89_UK][8] = 30, + [1][1][RTW89_FCC][9] = 66, + [1][1][RTW89_ETSI][9] = 30, + [1][1][RTW89_MKK][9] = 38, + [1][1][RTW89_IC][9] = 66, + [1][1][RTW89_KCC][9] = 44, + [1][1][RTW89_ACMA][9] = 30, + [1][1][RTW89_CHILE][9] = 48, + [1][1][RTW89_UKRAINE][9] = 30, + [1][1][RTW89_MEXICO][9] = 66, + [1][1][RTW89_CN][9] = 30, + [1][1][RTW89_QATAR][9] = 30, + [1][1][RTW89_UK][9] = 30, + [1][1][RTW89_FCC][10] = 66, + [1][1][RTW89_ETSI][10] = 30, + [1][1][RTW89_MKK][10] = 38, + [1][1][RTW89_IC][10] = 66, + [1][1][RTW89_KCC][10] = 44, + [1][1][RTW89_ACMA][10] = 30, + [1][1][RTW89_CHILE][10] = 48, + [1][1][RTW89_UKRAINE][10] = 30, + [1][1][RTW89_MEXICO][10] = 66, + [1][1][RTW89_CN][10] = 30, + [1][1][RTW89_QATAR][10] = 30, + [1][1][RTW89_UK][10] = 30, + [1][1][RTW89_FCC][11] = 60, + [1][1][RTW89_ETSI][11] = 30, + [1][1][RTW89_MKK][11] = 38, + [1][1][RTW89_IC][11] = 60, + [1][1][RTW89_KCC][11] = 44, + [1][1][RTW89_ACMA][11] = 30, + [1][1][RTW89_CHILE][11] = 48, + [1][1][RTW89_UKRAINE][11] = 30, + [1][1][RTW89_MEXICO][11] = 60, + [1][1][RTW89_CN][11] = 30, + [1][1][RTW89_QATAR][11] = 30, + [1][1][RTW89_UK][11] = 30, + [1][1][RTW89_FCC][12] = 32, + [1][1][RTW89_ETSI][12] = 30, + [1][1][RTW89_MKK][12] = 38, + [1][1][RTW89_IC][12] = 32, + [1][1][RTW89_KCC][12] = 44, + [1][1][RTW89_ACMA][12] = 30, + [1][1][RTW89_CHILE][12] = 32, + [1][1][RTW89_UKRAINE][12] = 30, + [1][1][RTW89_MEXICO][12] = 32, + [1][1][RTW89_CN][12] = 30, + [1][1][RTW89_QATAR][12] = 30, + [1][1][RTW89_UK][12] = 30, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_KCC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [1][1][RTW89_CHILE][13] = 127, + [1][1][RTW89_UKRAINE][13] = 127, + [1][1][RTW89_MEXICO][13] = 127, + [1][1][RTW89_CN][13] = 127, + [1][1][RTW89_QATAR][13] = 127, + [1][1][RTW89_UK][13] = 127, + [2][0][RTW89_FCC][0] = 76, + [2][0][RTW89_ETSI][0] = 52, + [2][0][RTW89_MKK][0] = 64, + [2][0][RTW89_IC][0] = 76, + [2][0][RTW89_KCC][0] = 70, + [2][0][RTW89_ACMA][0] = 52, + [2][0][RTW89_CHILE][0] = 60, + [2][0][RTW89_UKRAINE][0] = 52, + [2][0][RTW89_MEXICO][0] = 76, + [2][0][RTW89_CN][0] = 52, + [2][0][RTW89_QATAR][0] = 52, + [2][0][RTW89_UK][0] = 52, + [2][0][RTW89_FCC][1] = 76, + [2][0][RTW89_ETSI][1] = 52, + [2][0][RTW89_MKK][1] = 64, + [2][0][RTW89_IC][1] = 76, + [2][0][RTW89_KCC][1] = 70, + [2][0][RTW89_ACMA][1] = 52, + [2][0][RTW89_CHILE][1] = 60, + [2][0][RTW89_UKRAINE][1] = 52, + [2][0][RTW89_MEXICO][1] = 76, + [2][0][RTW89_CN][1] = 52, + [2][0][RTW89_QATAR][1] = 52, + [2][0][RTW89_UK][1] = 52, + [2][0][RTW89_FCC][2] = 78, + [2][0][RTW89_ETSI][2] = 52, + [2][0][RTW89_MKK][2] = 64, + [2][0][RTW89_IC][2] = 78, + [2][0][RTW89_KCC][2] = 70, + [2][0][RTW89_ACMA][2] = 52, + [2][0][RTW89_CHILE][2] = 60, + [2][0][RTW89_UKRAINE][2] = 52, + [2][0][RTW89_MEXICO][2] = 78, + [2][0][RTW89_CN][2] = 52, + [2][0][RTW89_QATAR][2] = 52, + [2][0][RTW89_UK][2] = 52, + [2][0][RTW89_FCC][3] = 78, + [2][0][RTW89_ETSI][3] = 52, + [2][0][RTW89_MKK][3] = 64, + [2][0][RTW89_IC][3] = 78, + [2][0][RTW89_KCC][3] = 70, + [2][0][RTW89_ACMA][3] = 52, + [2][0][RTW89_CHILE][3] = 60, + [2][0][RTW89_UKRAINE][3] = 52, + [2][0][RTW89_MEXICO][3] = 78, + [2][0][RTW89_CN][3] = 52, + [2][0][RTW89_QATAR][3] = 52, + [2][0][RTW89_UK][3] = 52, + [2][0][RTW89_FCC][4] = 78, + [2][0][RTW89_ETSI][4] = 52, + [2][0][RTW89_MKK][4] = 64, + [2][0][RTW89_IC][4] = 78, + [2][0][RTW89_KCC][4] = 70, + [2][0][RTW89_ACMA][4] = 52, + [2][0][RTW89_CHILE][4] = 60, + [2][0][RTW89_UKRAINE][4] = 52, + [2][0][RTW89_MEXICO][4] = 78, + [2][0][RTW89_CN][4] = 52, + [2][0][RTW89_QATAR][4] = 52, + [2][0][RTW89_UK][4] = 52, + [2][0][RTW89_FCC][5] = 78, + [2][0][RTW89_ETSI][5] = 52, + [2][0][RTW89_MKK][5] = 64, + [2][0][RTW89_IC][5] = 78, + [2][0][RTW89_KCC][5] = 70, + [2][0][RTW89_ACMA][5] = 52, + [2][0][RTW89_CHILE][5] = 60, + [2][0][RTW89_UKRAINE][5] = 52, + [2][0][RTW89_MEXICO][5] = 78, + [2][0][RTW89_CN][5] = 52, + [2][0][RTW89_QATAR][5] = 52, + [2][0][RTW89_UK][5] = 52, + [2][0][RTW89_FCC][6] = 78, + [2][0][RTW89_ETSI][6] = 52, + [2][0][RTW89_MKK][6] = 64, + [2][0][RTW89_IC][6] = 78, + [2][0][RTW89_KCC][6] = 70, + [2][0][RTW89_ACMA][6] = 52, + [2][0][RTW89_CHILE][6] = 60, + [2][0][RTW89_UKRAINE][6] = 52, + [2][0][RTW89_MEXICO][6] = 78, + [2][0][RTW89_CN][6] = 52, + [2][0][RTW89_QATAR][6] = 52, + [2][0][RTW89_UK][6] = 52, + [2][0][RTW89_FCC][7] = 78, + [2][0][RTW89_ETSI][7] = 52, + [2][0][RTW89_MKK][7] = 64, + [2][0][RTW89_IC][7] = 78, + [2][0][RTW89_KCC][7] = 70, + [2][0][RTW89_ACMA][7] = 52, + [2][0][RTW89_CHILE][7] = 60, + [2][0][RTW89_UKRAINE][7] = 52, + [2][0][RTW89_MEXICO][7] = 78, + [2][0][RTW89_CN][7] = 52, + [2][0][RTW89_QATAR][7] = 52, + [2][0][RTW89_UK][7] = 52, + [2][0][RTW89_FCC][8] = 78, + [2][0][RTW89_ETSI][8] = 52, + [2][0][RTW89_MKK][8] = 64, + [2][0][RTW89_IC][8] = 78, + [2][0][RTW89_KCC][8] = 70, + [2][0][RTW89_ACMA][8] = 52, + [2][0][RTW89_CHILE][8] = 60, + [2][0][RTW89_UKRAINE][8] = 52, + [2][0][RTW89_MEXICO][8] = 78, + [2][0][RTW89_CN][8] = 52, + [2][0][RTW89_QATAR][8] = 52, + [2][0][RTW89_UK][8] = 52, + [2][0][RTW89_FCC][9] = 76, + [2][0][RTW89_ETSI][9] = 52, + [2][0][RTW89_MKK][9] = 64, + [2][0][RTW89_IC][9] = 76, + [2][0][RTW89_KCC][9] = 70, + [2][0][RTW89_ACMA][9] = 52, + [2][0][RTW89_CHILE][9] = 60, + [2][0][RTW89_UKRAINE][9] = 52, + [2][0][RTW89_MEXICO][9] = 76, + [2][0][RTW89_CN][9] = 52, + [2][0][RTW89_QATAR][9] = 52, + [2][0][RTW89_UK][9] = 52, + [2][0][RTW89_FCC][10] = 76, + [2][0][RTW89_ETSI][10] = 52, + [2][0][RTW89_MKK][10] = 64, + [2][0][RTW89_IC][10] = 76, + [2][0][RTW89_KCC][10] = 70, + [2][0][RTW89_ACMA][10] = 52, + [2][0][RTW89_CHILE][10] = 60, + [2][0][RTW89_UKRAINE][10] = 52, + [2][0][RTW89_MEXICO][10] = 76, + [2][0][RTW89_CN][10] = 52, + [2][0][RTW89_QATAR][10] = 52, + [2][0][RTW89_UK][10] = 52, + [2][0][RTW89_FCC][11] = 68, + [2][0][RTW89_ETSI][11] = 52, + [2][0][RTW89_MKK][11] = 64, + [2][0][RTW89_IC][11] = 68, + [2][0][RTW89_KCC][11] = 70, + [2][0][RTW89_ACMA][11] = 52, + [2][0][RTW89_CHILE][11] = 60, + [2][0][RTW89_UKRAINE][11] = 52, + [2][0][RTW89_MEXICO][11] = 68, + [2][0][RTW89_CN][11] = 52, + [2][0][RTW89_QATAR][11] = 52, + [2][0][RTW89_UK][11] = 52, + [2][0][RTW89_FCC][12] = 40, + [2][0][RTW89_ETSI][12] = 52, + [2][0][RTW89_MKK][12] = 64, + [2][0][RTW89_IC][12] = 40, + [2][0][RTW89_KCC][12] = 70, + [2][0][RTW89_ACMA][12] = 52, + [2][0][RTW89_CHILE][12] = 40, + [2][0][RTW89_UKRAINE][12] = 52, + [2][0][RTW89_MEXICO][12] = 40, + [2][0][RTW89_CN][12] = 52, + [2][0][RTW89_QATAR][12] = 52, + [2][0][RTW89_UK][12] = 52, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_KCC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][0][RTW89_CHILE][13] = 127, + [2][0][RTW89_UKRAINE][13] = 127, + [2][0][RTW89_MEXICO][13] = 127, + [2][0][RTW89_CN][13] = 127, + [2][0][RTW89_QATAR][13] = 127, + [2][0][RTW89_UK][13] = 127, + [2][1][RTW89_FCC][0] = 68, + [2][1][RTW89_ETSI][0] = 40, + [2][1][RTW89_MKK][0] = 52, + [2][1][RTW89_IC][0] = 68, + [2][1][RTW89_KCC][0] = 56, + [2][1][RTW89_ACMA][0] = 40, + [2][1][RTW89_CHILE][0] = 48, + [2][1][RTW89_UKRAINE][0] = 40, + [2][1][RTW89_MEXICO][0] = 68, + [2][1][RTW89_CN][0] = 40, + [2][1][RTW89_QATAR][0] = 40, + [2][1][RTW89_UK][0] = 40, + [2][1][RTW89_FCC][1] = 68, + [2][1][RTW89_ETSI][1] = 40, + [2][1][RTW89_MKK][1] = 52, + [2][1][RTW89_IC][1] = 68, + [2][1][RTW89_KCC][1] = 56, + [2][1][RTW89_ACMA][1] = 40, + [2][1][RTW89_CHILE][1] = 48, + [2][1][RTW89_UKRAINE][1] = 40, + [2][1][RTW89_MEXICO][1] = 68, + [2][1][RTW89_CN][1] = 40, + [2][1][RTW89_QATAR][1] = 40, + [2][1][RTW89_UK][1] = 40, + [2][1][RTW89_FCC][2] = 72, + [2][1][RTW89_ETSI][2] = 40, + [2][1][RTW89_MKK][2] = 52, + [2][1][RTW89_IC][2] = 72, + [2][1][RTW89_KCC][2] = 56, + [2][1][RTW89_ACMA][2] = 40, + [2][1][RTW89_CHILE][2] = 48, + [2][1][RTW89_UKRAINE][2] = 40, + [2][1][RTW89_MEXICO][2] = 72, + [2][1][RTW89_CN][2] = 40, + [2][1][RTW89_QATAR][2] = 40, + [2][1][RTW89_UK][2] = 40, + [2][1][RTW89_FCC][3] = 76, + [2][1][RTW89_ETSI][3] = 40, + [2][1][RTW89_MKK][3] = 52, + [2][1][RTW89_IC][3] = 76, + [2][1][RTW89_KCC][3] = 56, + [2][1][RTW89_ACMA][3] = 40, + [2][1][RTW89_CHILE][3] = 48, + [2][1][RTW89_UKRAINE][3] = 40, + [2][1][RTW89_MEXICO][3] = 76, + [2][1][RTW89_CN][3] = 40, + [2][1][RTW89_QATAR][3] = 40, + [2][1][RTW89_UK][3] = 40, + [2][1][RTW89_FCC][4] = 78, + [2][1][RTW89_ETSI][4] = 40, + [2][1][RTW89_MKK][4] = 52, + [2][1][RTW89_IC][4] = 78, + [2][1][RTW89_KCC][4] = 56, + [2][1][RTW89_ACMA][4] = 40, + [2][1][RTW89_CHILE][4] = 48, + [2][1][RTW89_UKRAINE][4] = 40, + [2][1][RTW89_MEXICO][4] = 78, + [2][1][RTW89_CN][4] = 40, + [2][1][RTW89_QATAR][4] = 40, + [2][1][RTW89_UK][4] = 40, + [2][1][RTW89_FCC][5] = 78, + [2][1][RTW89_ETSI][5] = 40, + [2][1][RTW89_MKK][5] = 52, + [2][1][RTW89_IC][5] = 78, + [2][1][RTW89_KCC][5] = 56, + [2][1][RTW89_ACMA][5] = 40, + [2][1][RTW89_CHILE][5] = 48, + [2][1][RTW89_UKRAINE][5] = 40, + [2][1][RTW89_MEXICO][5] = 78, + [2][1][RTW89_CN][5] = 40, + [2][1][RTW89_QATAR][5] = 40, + [2][1][RTW89_UK][5] = 40, + [2][1][RTW89_FCC][6] = 78, + [2][1][RTW89_ETSI][6] = 40, + [2][1][RTW89_MKK][6] = 52, + [2][1][RTW89_IC][6] = 78, + [2][1][RTW89_KCC][6] = 56, + [2][1][RTW89_ACMA][6] = 40, + [2][1][RTW89_CHILE][6] = 48, + [2][1][RTW89_UKRAINE][6] = 40, + [2][1][RTW89_MEXICO][6] = 78, + [2][1][RTW89_CN][6] = 40, + [2][1][RTW89_QATAR][6] = 40, + [2][1][RTW89_UK][6] = 40, + [2][1][RTW89_FCC][7] = 78, + [2][1][RTW89_ETSI][7] = 40, + [2][1][RTW89_MKK][7] = 52, + [2][1][RTW89_IC][7] = 78, + [2][1][RTW89_KCC][7] = 56, + [2][1][RTW89_ACMA][7] = 40, + [2][1][RTW89_CHILE][7] = 48, + [2][1][RTW89_UKRAINE][7] = 40, + [2][1][RTW89_MEXICO][7] = 78, + [2][1][RTW89_CN][7] = 40, + [2][1][RTW89_QATAR][7] = 40, + [2][1][RTW89_UK][7] = 40, + [2][1][RTW89_FCC][8] = 74, + [2][1][RTW89_ETSI][8] = 40, + [2][1][RTW89_MKK][8] = 52, + [2][1][RTW89_IC][8] = 74, + [2][1][RTW89_KCC][8] = 56, + [2][1][RTW89_ACMA][8] = 40, + [2][1][RTW89_CHILE][8] = 48, + [2][1][RTW89_UKRAINE][8] = 40, + [2][1][RTW89_MEXICO][8] = 74, + [2][1][RTW89_CN][8] = 40, + [2][1][RTW89_QATAR][8] = 40, + [2][1][RTW89_UK][8] = 40, + [2][1][RTW89_FCC][9] = 70, + [2][1][RTW89_ETSI][9] = 40, + [2][1][RTW89_MKK][9] = 52, + [2][1][RTW89_IC][9] = 70, + [2][1][RTW89_KCC][9] = 56, + [2][1][RTW89_ACMA][9] = 40, + [2][1][RTW89_CHILE][9] = 48, + [2][1][RTW89_UKRAINE][9] = 40, + [2][1][RTW89_MEXICO][9] = 70, + [2][1][RTW89_CN][9] = 40, + [2][1][RTW89_QATAR][9] = 40, + [2][1][RTW89_UK][9] = 40, + [2][1][RTW89_FCC][10] = 70, + [2][1][RTW89_ETSI][10] = 40, + [2][1][RTW89_MKK][10] = 52, + [2][1][RTW89_IC][10] = 70, + [2][1][RTW89_KCC][10] = 56, + [2][1][RTW89_ACMA][10] = 40, + [2][1][RTW89_CHILE][10] = 48, + [2][1][RTW89_UKRAINE][10] = 40, + [2][1][RTW89_MEXICO][10] = 70, + [2][1][RTW89_CN][10] = 40, + [2][1][RTW89_QATAR][10] = 40, + [2][1][RTW89_UK][10] = 40, + [2][1][RTW89_FCC][11] = 48, + [2][1][RTW89_ETSI][11] = 40, + [2][1][RTW89_MKK][11] = 52, + [2][1][RTW89_IC][11] = 48, + [2][1][RTW89_KCC][11] = 56, + [2][1][RTW89_ACMA][11] = 40, + [2][1][RTW89_CHILE][11] = 48, + [2][1][RTW89_UKRAINE][11] = 40, + [2][1][RTW89_MEXICO][11] = 48, + [2][1][RTW89_CN][11] = 40, + [2][1][RTW89_QATAR][11] = 40, + [2][1][RTW89_UK][11] = 40, + [2][1][RTW89_FCC][12] = 26, + [2][1][RTW89_ETSI][12] = 40, + [2][1][RTW89_MKK][12] = 52, + [2][1][RTW89_IC][12] = 26, + [2][1][RTW89_KCC][12] = 56, + [2][1][RTW89_ACMA][12] = 40, + [2][1][RTW89_CHILE][12] = 26, + [2][1][RTW89_UKRAINE][12] = 40, + [2][1][RTW89_MEXICO][12] = 26, + [2][1][RTW89_CN][12] = 40, + [2][1][RTW89_QATAR][12] = 40, + [2][1][RTW89_UK][12] = 40, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_KCC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, + [2][1][RTW89_CHILE][13] = 127, + [2][1][RTW89_UKRAINE][13] = 127, + [2][1][RTW89_MEXICO][13] = 127, + [2][1][RTW89_CN][13] = 127, + [2][1][RTW89_QATAR][13] = 127, + [2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 22, + [0][0][RTW89_WW][2] = 22, + [0][0][RTW89_WW][4] = 22, + [0][0][RTW89_WW][6] = 20, + [0][0][RTW89_WW][8] = 24, + [0][0][RTW89_WW][10] = 24, + [0][0][RTW89_WW][12] = 24, + [0][0][RTW89_WW][14] = 24, + [0][0][RTW89_WW][15] = 24, + [0][0][RTW89_WW][17] = 24, + [0][0][RTW89_WW][19] = 24, + [0][0][RTW89_WW][21] = 24, + [0][0][RTW89_WW][23] = 24, + [0][0][RTW89_WW][25] = 24, + [0][0][RTW89_WW][27] = 24, + [0][0][RTW89_WW][29] = 24, + [0][0][RTW89_WW][31] = 24, + [0][0][RTW89_WW][33] = 24, + [0][0][RTW89_WW][35] = 24, + [0][0][RTW89_WW][37] = 44, + [0][0][RTW89_WW][38] = 28, + [0][0][RTW89_WW][40] = 28, + [0][0][RTW89_WW][42] = 28, + [0][0][RTW89_WW][44] = 28, + [0][0][RTW89_WW][46] = 28, + [0][1][RTW89_WW][0] = 8, + [0][1][RTW89_WW][2] = 8, + [0][1][RTW89_WW][4] = 8, + [0][1][RTW89_WW][6] = 4, + [0][1][RTW89_WW][8] = 12, + [0][1][RTW89_WW][10] = 12, + [0][1][RTW89_WW][12] = 12, + [0][1][RTW89_WW][14] = 12, + [0][1][RTW89_WW][15] = 12, + [0][1][RTW89_WW][17] = 12, + [0][1][RTW89_WW][19] = 12, + [0][1][RTW89_WW][21] = 12, + [0][1][RTW89_WW][23] = 12, + [0][1][RTW89_WW][25] = 12, + [0][1][RTW89_WW][27] = 12, + [0][1][RTW89_WW][29] = 12, + [0][1][RTW89_WW][31] = 12, + [0][1][RTW89_WW][33] = 12, + [0][1][RTW89_WW][35] = 12, + [0][1][RTW89_WW][37] = 32, + [0][1][RTW89_WW][38] = 16, + [0][1][RTW89_WW][40] = 16, + [0][1][RTW89_WW][42] = 16, + [0][1][RTW89_WW][44] = 16, + [0][1][RTW89_WW][46] = 16, + [1][0][RTW89_WW][0] = 30, + [1][0][RTW89_WW][2] = 30, + [1][0][RTW89_WW][4] = 30, + [1][0][RTW89_WW][6] = 30, + [1][0][RTW89_WW][8] = 36, + [1][0][RTW89_WW][10] = 36, + [1][0][RTW89_WW][12] = 36, + [1][0][RTW89_WW][14] = 36, + [1][0][RTW89_WW][15] = 36, + [1][0][RTW89_WW][17] = 36, + [1][0][RTW89_WW][19] = 36, + [1][0][RTW89_WW][21] = 36, + [1][0][RTW89_WW][23] = 36, + [1][0][RTW89_WW][25] = 36, + [1][0][RTW89_WW][27] = 36, + [1][0][RTW89_WW][29] = 36, + [1][0][RTW89_WW][31] = 36, + [1][0][RTW89_WW][33] = 36, + [1][0][RTW89_WW][35] = 36, + [1][0][RTW89_WW][37] = 54, + [1][0][RTW89_WW][38] = 28, + [1][0][RTW89_WW][40] = 28, + [1][0][RTW89_WW][42] = 28, + [1][0][RTW89_WW][44] = 28, + [1][0][RTW89_WW][46] = 28, + [1][1][RTW89_WW][0] = 18, + [1][1][RTW89_WW][2] = 18, + [1][1][RTW89_WW][4] = 18, + [1][1][RTW89_WW][6] = 16, + [1][1][RTW89_WW][8] = 22, + [1][1][RTW89_WW][10] = 22, + [1][1][RTW89_WW][12] = 22, + [1][1][RTW89_WW][14] = 22, + [1][1][RTW89_WW][15] = 22, + [1][1][RTW89_WW][17] = 22, + [1][1][RTW89_WW][19] = 22, + [1][1][RTW89_WW][21] = 22, + [1][1][RTW89_WW][23] = 22, + [1][1][RTW89_WW][25] = 22, + [1][1][RTW89_WW][27] = 22, + [1][1][RTW89_WW][29] = 22, + [1][1][RTW89_WW][31] = 22, + [1][1][RTW89_WW][33] = 22, + [1][1][RTW89_WW][35] = 22, + [1][1][RTW89_WW][37] = 42, + [1][1][RTW89_WW][38] = 16, + [1][1][RTW89_WW][40] = 16, + [1][1][RTW89_WW][42] = 16, + [1][1][RTW89_WW][44] = 16, + [1][1][RTW89_WW][46] = 16, + [2][0][RTW89_WW][0] = 30, + [2][0][RTW89_WW][2] = 30, + [2][0][RTW89_WW][4] = 30, + [2][0][RTW89_WW][6] = 30, + [2][0][RTW89_WW][8] = 46, + [2][0][RTW89_WW][10] = 46, + [2][0][RTW89_WW][12] = 46, + [2][0][RTW89_WW][14] = 46, + [2][0][RTW89_WW][15] = 46, + [2][0][RTW89_WW][17] = 46, + [2][0][RTW89_WW][19] = 46, + [2][0][RTW89_WW][21] = 46, + [2][0][RTW89_WW][23] = 46, + [2][0][RTW89_WW][25] = 46, + [2][0][RTW89_WW][27] = 46, + [2][0][RTW89_WW][29] = 46, + [2][0][RTW89_WW][31] = 46, + [2][0][RTW89_WW][33] = 46, + [2][0][RTW89_WW][35] = 46, + [2][0][RTW89_WW][37] = 54, + [2][0][RTW89_WW][38] = 28, + [2][0][RTW89_WW][40] = 28, + [2][0][RTW89_WW][42] = 28, + [2][0][RTW89_WW][44] = 28, + [2][0][RTW89_WW][46] = 28, + [2][1][RTW89_WW][0] = 18, + [2][1][RTW89_WW][2] = 18, + [2][1][RTW89_WW][4] = 18, + [2][1][RTW89_WW][6] = 18, + [2][1][RTW89_WW][8] = 32, + [2][1][RTW89_WW][10] = 32, + [2][1][RTW89_WW][12] = 32, + [2][1][RTW89_WW][14] = 32, + [2][1][RTW89_WW][15] = 32, + [2][1][RTW89_WW][17] = 32, + [2][1][RTW89_WW][19] = 32, + [2][1][RTW89_WW][21] = 32, + [2][1][RTW89_WW][23] = 32, + [2][1][RTW89_WW][25] = 32, + [2][1][RTW89_WW][27] = 32, + [2][1][RTW89_WW][29] = 32, + [2][1][RTW89_WW][31] = 32, + [2][1][RTW89_WW][33] = 32, + [2][1][RTW89_WW][35] = 32, + [2][1][RTW89_WW][37] = 42, + [2][1][RTW89_WW][38] = 16, + [2][1][RTW89_WW][40] = 16, + [2][1][RTW89_WW][42] = 16, + [2][1][RTW89_WW][44] = 16, + [2][1][RTW89_WW][46] = 16, + [0][0][RTW89_FCC][0] = 48, + [0][0][RTW89_ETSI][0] = 24, + [0][0][RTW89_MKK][0] = 26, + [0][0][RTW89_IC][0] = 22, + [0][0][RTW89_KCC][0] = 46, + [0][0][RTW89_ACMA][0] = 24, + [0][0][RTW89_CHILE][0] = 30, + [0][0][RTW89_UKRAINE][0] = 24, + [0][0][RTW89_MEXICO][0] = 48, + [0][0][RTW89_CN][0] = 24, + [0][0][RTW89_QATAR][0] = 24, + [0][0][RTW89_UK][0] = 24, + [0][0][RTW89_FCC][2] = 48, + [0][0][RTW89_ETSI][2] = 24, + [0][0][RTW89_MKK][2] = 26, + [0][0][RTW89_IC][2] = 22, + [0][0][RTW89_KCC][2] = 46, + [0][0][RTW89_ACMA][2] = 24, + [0][0][RTW89_CHILE][2] = 30, + [0][0][RTW89_UKRAINE][2] = 24, + [0][0][RTW89_MEXICO][2] = 48, + [0][0][RTW89_CN][2] = 24, + [0][0][RTW89_QATAR][2] = 24, + [0][0][RTW89_UK][2] = 24, + [0][0][RTW89_FCC][4] = 48, + [0][0][RTW89_ETSI][4] = 24, + [0][0][RTW89_MKK][4] = 26, + [0][0][RTW89_IC][4] = 22, + [0][0][RTW89_KCC][4] = 46, + [0][0][RTW89_ACMA][4] = 24, + [0][0][RTW89_CHILE][4] = 30, + [0][0][RTW89_UKRAINE][4] = 24, + [0][0][RTW89_MEXICO][4] = 48, + [0][0][RTW89_CN][4] = 24, + [0][0][RTW89_QATAR][4] = 24, + [0][0][RTW89_UK][4] = 24, + [0][0][RTW89_FCC][6] = 48, + [0][0][RTW89_ETSI][6] = 24, + [0][0][RTW89_MKK][6] = 26, + [0][0][RTW89_IC][6] = 22, + [0][0][RTW89_KCC][6] = 20, + [0][0][RTW89_ACMA][6] = 24, + [0][0][RTW89_CHILE][6] = 30, + [0][0][RTW89_UKRAINE][6] = 24, + [0][0][RTW89_MEXICO][6] = 48, + [0][0][RTW89_CN][6] = 24, + [0][0][RTW89_QATAR][6] = 24, + [0][0][RTW89_UK][6] = 24, + [0][0][RTW89_FCC][8] = 48, + [0][0][RTW89_ETSI][8] = 24, + [0][0][RTW89_MKK][8] = 26, + [0][0][RTW89_IC][8] = 48, + [0][0][RTW89_KCC][8] = 46, + [0][0][RTW89_ACMA][8] = 24, + [0][0][RTW89_CHILE][8] = 48, + [0][0][RTW89_UKRAINE][8] = 24, + [0][0][RTW89_MEXICO][8] = 48, + [0][0][RTW89_CN][8] = 24, + [0][0][RTW89_QATAR][8] = 24, + [0][0][RTW89_UK][8] = 24, + [0][0][RTW89_FCC][10] = 48, + [0][0][RTW89_ETSI][10] = 24, + [0][0][RTW89_MKK][10] = 26, + [0][0][RTW89_IC][10] = 48, + [0][0][RTW89_KCC][10] = 46, + [0][0][RTW89_ACMA][10] = 24, + [0][0][RTW89_CHILE][10] = 48, + [0][0][RTW89_UKRAINE][10] = 24, + [0][0][RTW89_MEXICO][10] = 48, + [0][0][RTW89_CN][10] = 24, + [0][0][RTW89_QATAR][10] = 24, + [0][0][RTW89_UK][10] = 24, + [0][0][RTW89_FCC][12] = 48, + [0][0][RTW89_ETSI][12] = 24, + [0][0][RTW89_MKK][12] = 26, + [0][0][RTW89_IC][12] = 48, + [0][0][RTW89_KCC][12] = 46, + [0][0][RTW89_ACMA][12] = 24, + [0][0][RTW89_CHILE][12] = 48, + [0][0][RTW89_UKRAINE][12] = 24, + [0][0][RTW89_MEXICO][12] = 48, + [0][0][RTW89_CN][12] = 24, + [0][0][RTW89_QATAR][12] = 24, + [0][0][RTW89_UK][12] = 24, + [0][0][RTW89_FCC][14] = 48, + [0][0][RTW89_ETSI][14] = 24, + [0][0][RTW89_MKK][14] = 26, + [0][0][RTW89_IC][14] = 48, + [0][0][RTW89_KCC][14] = 46, + [0][0][RTW89_ACMA][14] = 24, + [0][0][RTW89_CHILE][14] = 48, + [0][0][RTW89_UKRAINE][14] = 24, + [0][0][RTW89_MEXICO][14] = 48, + [0][0][RTW89_CN][14] = 24, + [0][0][RTW89_QATAR][14] = 24, + [0][0][RTW89_UK][14] = 24, + [0][0][RTW89_FCC][15] = 48, + [0][0][RTW89_ETSI][15] = 24, + [0][0][RTW89_MKK][15] = 44, + [0][0][RTW89_IC][15] = 48, + [0][0][RTW89_KCC][15] = 46, + [0][0][RTW89_ACMA][15] = 24, + [0][0][RTW89_CHILE][15] = 48, + [0][0][RTW89_UKRAINE][15] = 24, + [0][0][RTW89_MEXICO][15] = 48, + [0][0][RTW89_CN][15] = 127, + [0][0][RTW89_QATAR][15] = 24, + [0][0][RTW89_UK][15] = 24, + [0][0][RTW89_FCC][17] = 48, + [0][0][RTW89_ETSI][17] = 24, + [0][0][RTW89_MKK][17] = 44, + [0][0][RTW89_IC][17] = 48, + [0][0][RTW89_KCC][17] = 46, + [0][0][RTW89_ACMA][17] = 24, + [0][0][RTW89_CHILE][17] = 48, + [0][0][RTW89_UKRAINE][17] = 24, + [0][0][RTW89_MEXICO][17] = 48, + [0][0][RTW89_CN][17] = 127, + [0][0][RTW89_QATAR][17] = 24, + [0][0][RTW89_UK][17] = 24, + [0][0][RTW89_FCC][19] = 48, + [0][0][RTW89_ETSI][19] = 24, + [0][0][RTW89_MKK][19] = 44, + [0][0][RTW89_IC][19] = 48, + [0][0][RTW89_KCC][19] = 46, + [0][0][RTW89_ACMA][19] = 24, + [0][0][RTW89_CHILE][19] = 48, + [0][0][RTW89_UKRAINE][19] = 24, + [0][0][RTW89_MEXICO][19] = 48, + [0][0][RTW89_CN][19] = 127, + [0][0][RTW89_QATAR][19] = 24, + [0][0][RTW89_UK][19] = 24, + [0][0][RTW89_FCC][21] = 48, + [0][0][RTW89_ETSI][21] = 24, + [0][0][RTW89_MKK][21] = 44, + [0][0][RTW89_IC][21] = 48, + [0][0][RTW89_KCC][21] = 46, + [0][0][RTW89_ACMA][21] = 24, + [0][0][RTW89_CHILE][21] = 48, + [0][0][RTW89_UKRAINE][21] = 24, + [0][0][RTW89_MEXICO][21] = 48, + [0][0][RTW89_CN][21] = 127, + [0][0][RTW89_QATAR][21] = 24, + [0][0][RTW89_UK][21] = 24, + [0][0][RTW89_FCC][23] = 48, + [0][0][RTW89_ETSI][23] = 24, + [0][0][RTW89_MKK][23] = 44, + [0][0][RTW89_IC][23] = 48, + [0][0][RTW89_KCC][23] = 46, + [0][0][RTW89_ACMA][23] = 24, + [0][0][RTW89_CHILE][23] = 48, + [0][0][RTW89_UKRAINE][23] = 24, + [0][0][RTW89_MEXICO][23] = 48, + [0][0][RTW89_CN][23] = 127, + [0][0][RTW89_QATAR][23] = 24, + [0][0][RTW89_UK][23] = 24, + [0][0][RTW89_FCC][25] = 48, + [0][0][RTW89_ETSI][25] = 24, + [0][0][RTW89_MKK][25] = 44, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_KCC][25] = 46, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_CHILE][25] = 48, + [0][0][RTW89_UKRAINE][25] = 24, + [0][0][RTW89_MEXICO][25] = 48, + [0][0][RTW89_CN][25] = 127, + [0][0][RTW89_QATAR][25] = 24, + [0][0][RTW89_UK][25] = 24, + [0][0][RTW89_FCC][27] = 48, + [0][0][RTW89_ETSI][27] = 24, + [0][0][RTW89_MKK][27] = 44, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_KCC][27] = 46, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_CHILE][27] = 48, + [0][0][RTW89_UKRAINE][27] = 24, + [0][0][RTW89_MEXICO][27] = 48, + [0][0][RTW89_CN][27] = 127, + [0][0][RTW89_QATAR][27] = 24, + [0][0][RTW89_UK][27] = 24, + [0][0][RTW89_FCC][29] = 48, + [0][0][RTW89_ETSI][29] = 24, + [0][0][RTW89_MKK][29] = 44, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_KCC][29] = 46, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_CHILE][29] = 48, + [0][0][RTW89_UKRAINE][29] = 24, + [0][0][RTW89_MEXICO][29] = 48, + [0][0][RTW89_CN][29] = 127, + [0][0][RTW89_QATAR][29] = 24, + [0][0][RTW89_UK][29] = 24, + [0][0][RTW89_FCC][31] = 48, + [0][0][RTW89_ETSI][31] = 24, + [0][0][RTW89_MKK][31] = 44, + [0][0][RTW89_IC][31] = 48, + [0][0][RTW89_KCC][31] = 46, + [0][0][RTW89_ACMA][31] = 24, + [0][0][RTW89_CHILE][31] = 48, + [0][0][RTW89_UKRAINE][31] = 24, + [0][0][RTW89_MEXICO][31] = 48, + [0][0][RTW89_CN][31] = 127, + [0][0][RTW89_QATAR][31] = 24, + [0][0][RTW89_UK][31] = 24, + [0][0][RTW89_FCC][33] = 48, + [0][0][RTW89_ETSI][33] = 24, + [0][0][RTW89_MKK][33] = 44, + [0][0][RTW89_IC][33] = 48, + [0][0][RTW89_KCC][33] = 46, + [0][0][RTW89_ACMA][33] = 24, + [0][0][RTW89_CHILE][33] = 48, + [0][0][RTW89_UKRAINE][33] = 24, + [0][0][RTW89_MEXICO][33] = 48, + [0][0][RTW89_CN][33] = 127, + [0][0][RTW89_QATAR][33] = 24, + [0][0][RTW89_UK][33] = 24, + [0][0][RTW89_FCC][35] = 48, + [0][0][RTW89_ETSI][35] = 24, + [0][0][RTW89_MKK][35] = 44, + [0][0][RTW89_IC][35] = 48, + [0][0][RTW89_KCC][35] = 46, + [0][0][RTW89_ACMA][35] = 24, + [0][0][RTW89_CHILE][35] = 48, + [0][0][RTW89_UKRAINE][35] = 24, + [0][0][RTW89_MEXICO][35] = 48, + [0][0][RTW89_CN][35] = 127, + [0][0][RTW89_QATAR][35] = 24, + [0][0][RTW89_UK][35] = 24, + [0][0][RTW89_FCC][37] = 48, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 44, + [0][0][RTW89_IC][37] = 48, + [0][0][RTW89_KCC][37] = 46, + [0][0][RTW89_ACMA][37] = 48, + [0][0][RTW89_CHILE][37] = 48, + [0][0][RTW89_UKRAINE][37] = 127, + [0][0][RTW89_MEXICO][37] = 48, + [0][0][RTW89_CN][37] = 127, + [0][0][RTW89_QATAR][37] = 127, + [0][0][RTW89_UK][37] = 58, + [0][0][RTW89_FCC][38] = 76, + [0][0][RTW89_ETSI][38] = 28, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 76, + [0][0][RTW89_KCC][38] = 46, + [0][0][RTW89_ACMA][38] = 76, + [0][0][RTW89_CHILE][38] = 54, + [0][0][RTW89_UKRAINE][38] = 28, + [0][0][RTW89_MEXICO][38] = 76, + [0][0][RTW89_CN][38] = 62, + [0][0][RTW89_QATAR][38] = 28, + [0][0][RTW89_UK][38] = 28, + [0][0][RTW89_FCC][40] = 76, + [0][0][RTW89_ETSI][40] = 28, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 76, + [0][0][RTW89_KCC][40] = 46, + [0][0][RTW89_ACMA][40] = 76, + [0][0][RTW89_CHILE][40] = 54, + [0][0][RTW89_UKRAINE][40] = 28, + [0][0][RTW89_MEXICO][40] = 76, + [0][0][RTW89_CN][40] = 62, + [0][0][RTW89_QATAR][40] = 28, + [0][0][RTW89_UK][40] = 28, + [0][0][RTW89_FCC][42] = 76, + [0][0][RTW89_ETSI][42] = 28, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 76, + [0][0][RTW89_KCC][42] = 46, + [0][0][RTW89_ACMA][42] = 76, + [0][0][RTW89_CHILE][42] = 54, + [0][0][RTW89_UKRAINE][42] = 28, + [0][0][RTW89_MEXICO][42] = 76, + [0][0][RTW89_CN][42] = 62, + [0][0][RTW89_QATAR][42] = 28, + [0][0][RTW89_UK][42] = 28, + [0][0][RTW89_FCC][44] = 76, + [0][0][RTW89_ETSI][44] = 28, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 76, + [0][0][RTW89_KCC][44] = 46, + [0][0][RTW89_ACMA][44] = 76, + [0][0][RTW89_CHILE][44] = 54, + [0][0][RTW89_UKRAINE][44] = 28, + [0][0][RTW89_MEXICO][44] = 76, + [0][0][RTW89_CN][44] = 62, + [0][0][RTW89_QATAR][44] = 28, + [0][0][RTW89_UK][44] = 28, + [0][0][RTW89_FCC][46] = 76, + [0][0][RTW89_ETSI][46] = 28, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 76, + [0][0][RTW89_KCC][46] = 46, + [0][0][RTW89_ACMA][46] = 76, + [0][0][RTW89_CHILE][46] = 54, + [0][0][RTW89_UKRAINE][46] = 28, + [0][0][RTW89_MEXICO][46] = 76, + [0][0][RTW89_CN][46] = 62, + [0][0][RTW89_QATAR][46] = 28, + [0][0][RTW89_UK][46] = 28, + [0][1][RTW89_FCC][0] = 36, + [0][1][RTW89_ETSI][0] = 12, + [0][1][RTW89_MKK][0] = 14, + [0][1][RTW89_IC][0] = 8, + [0][1][RTW89_KCC][0] = 32, + [0][1][RTW89_ACMA][0] = 12, + [0][1][RTW89_CHILE][0] = 18, + [0][1][RTW89_UKRAINE][0] = 12, + [0][1][RTW89_MEXICO][0] = 36, + [0][1][RTW89_CN][0] = 12, + [0][1][RTW89_QATAR][0] = 12, + [0][1][RTW89_UK][0] = 12, + [0][1][RTW89_FCC][2] = 36, + [0][1][RTW89_ETSI][2] = 12, + [0][1][RTW89_MKK][2] = 14, + [0][1][RTW89_IC][2] = 8, + [0][1][RTW89_KCC][2] = 32, + [0][1][RTW89_ACMA][2] = 12, + [0][1][RTW89_CHILE][2] = 18, + [0][1][RTW89_UKRAINE][2] = 12, + [0][1][RTW89_MEXICO][2] = 36, + [0][1][RTW89_CN][2] = 12, + [0][1][RTW89_QATAR][2] = 12, + [0][1][RTW89_UK][2] = 12, + [0][1][RTW89_FCC][4] = 36, + [0][1][RTW89_ETSI][4] = 12, + [0][1][RTW89_MKK][4] = 14, + [0][1][RTW89_IC][4] = 8, + [0][1][RTW89_KCC][4] = 32, + [0][1][RTW89_ACMA][4] = 12, + [0][1][RTW89_CHILE][4] = 18, + [0][1][RTW89_UKRAINE][4] = 12, + [0][1][RTW89_MEXICO][4] = 36, + [0][1][RTW89_CN][4] = 12, + [0][1][RTW89_QATAR][4] = 12, + [0][1][RTW89_UK][4] = 12, + [0][1][RTW89_FCC][6] = 36, + [0][1][RTW89_ETSI][6] = 12, + [0][1][RTW89_MKK][6] = 14, + [0][1][RTW89_IC][6] = 8, + [0][1][RTW89_KCC][6] = 4, + [0][1][RTW89_ACMA][6] = 12, + [0][1][RTW89_CHILE][6] = 18, + [0][1][RTW89_UKRAINE][6] = 12, + [0][1][RTW89_MEXICO][6] = 36, + [0][1][RTW89_CN][6] = 12, + [0][1][RTW89_QATAR][6] = 12, + [0][1][RTW89_UK][6] = 12, + [0][1][RTW89_FCC][8] = 36, + [0][1][RTW89_ETSI][8] = 12, + [0][1][RTW89_MKK][8] = 14, + [0][1][RTW89_IC][8] = 36, + [0][1][RTW89_KCC][8] = 32, + [0][1][RTW89_ACMA][8] = 12, + [0][1][RTW89_CHILE][8] = 36, + [0][1][RTW89_UKRAINE][8] = 12, + [0][1][RTW89_MEXICO][8] = 36, + [0][1][RTW89_CN][8] = 12, + [0][1][RTW89_QATAR][8] = 12, + [0][1][RTW89_UK][8] = 12, + [0][1][RTW89_FCC][10] = 36, + [0][1][RTW89_ETSI][10] = 12, + [0][1][RTW89_MKK][10] = 14, + [0][1][RTW89_IC][10] = 36, + [0][1][RTW89_KCC][10] = 32, + [0][1][RTW89_ACMA][10] = 12, + [0][1][RTW89_CHILE][10] = 36, + [0][1][RTW89_UKRAINE][10] = 12, + [0][1][RTW89_MEXICO][10] = 36, + [0][1][RTW89_CN][10] = 12, + [0][1][RTW89_QATAR][10] = 12, + [0][1][RTW89_UK][10] = 12, + [0][1][RTW89_FCC][12] = 36, + [0][1][RTW89_ETSI][12] = 12, + [0][1][RTW89_MKK][12] = 14, + [0][1][RTW89_IC][12] = 36, + [0][1][RTW89_KCC][12] = 32, + [0][1][RTW89_ACMA][12] = 12, + [0][1][RTW89_CHILE][12] = 36, + [0][1][RTW89_UKRAINE][12] = 12, + [0][1][RTW89_MEXICO][12] = 36, + [0][1][RTW89_CN][12] = 12, + [0][1][RTW89_QATAR][12] = 12, + [0][1][RTW89_UK][12] = 12, + [0][1][RTW89_FCC][14] = 36, + [0][1][RTW89_ETSI][14] = 12, + [0][1][RTW89_MKK][14] = 14, + [0][1][RTW89_IC][14] = 36, + [0][1][RTW89_KCC][14] = 32, + [0][1][RTW89_ACMA][14] = 12, + [0][1][RTW89_CHILE][14] = 36, + [0][1][RTW89_UKRAINE][14] = 12, + [0][1][RTW89_MEXICO][14] = 36, + [0][1][RTW89_CN][14] = 12, + [0][1][RTW89_QATAR][14] = 12, + [0][1][RTW89_UK][14] = 12, + [0][1][RTW89_FCC][15] = 36, + [0][1][RTW89_ETSI][15] = 12, + [0][1][RTW89_MKK][15] = 32, + [0][1][RTW89_IC][15] = 36, + [0][1][RTW89_KCC][15] = 32, + [0][1][RTW89_ACMA][15] = 12, + [0][1][RTW89_CHILE][15] = 36, + [0][1][RTW89_UKRAINE][15] = 12, + [0][1][RTW89_MEXICO][15] = 36, + [0][1][RTW89_CN][15] = 127, + [0][1][RTW89_QATAR][15] = 12, + [0][1][RTW89_UK][15] = 12, + [0][1][RTW89_FCC][17] = 36, + [0][1][RTW89_ETSI][17] = 12, + [0][1][RTW89_MKK][17] = 32, + [0][1][RTW89_IC][17] = 36, + [0][1][RTW89_KCC][17] = 32, + [0][1][RTW89_ACMA][17] = 12, + [0][1][RTW89_CHILE][17] = 36, + [0][1][RTW89_UKRAINE][17] = 12, + [0][1][RTW89_MEXICO][17] = 36, + [0][1][RTW89_CN][17] = 127, + [0][1][RTW89_QATAR][17] = 12, + [0][1][RTW89_UK][17] = 12, + [0][1][RTW89_FCC][19] = 36, + [0][1][RTW89_ETSI][19] = 12, + [0][1][RTW89_MKK][19] = 32, + [0][1][RTW89_IC][19] = 36, + [0][1][RTW89_KCC][19] = 32, + [0][1][RTW89_ACMA][19] = 12, + [0][1][RTW89_CHILE][19] = 36, + [0][1][RTW89_UKRAINE][19] = 12, + [0][1][RTW89_MEXICO][19] = 36, + [0][1][RTW89_CN][19] = 127, + [0][1][RTW89_QATAR][19] = 12, + [0][1][RTW89_UK][19] = 12, + [0][1][RTW89_FCC][21] = 36, + [0][1][RTW89_ETSI][21] = 12, + [0][1][RTW89_MKK][21] = 32, + [0][1][RTW89_IC][21] = 36, + [0][1][RTW89_KCC][21] = 32, + [0][1][RTW89_ACMA][21] = 12, + [0][1][RTW89_CHILE][21] = 36, + [0][1][RTW89_UKRAINE][21] = 12, + [0][1][RTW89_MEXICO][21] = 36, + [0][1][RTW89_CN][21] = 127, + [0][1][RTW89_QATAR][21] = 12, + [0][1][RTW89_UK][21] = 12, + [0][1][RTW89_FCC][23] = 36, + [0][1][RTW89_ETSI][23] = 12, + [0][1][RTW89_MKK][23] = 32, + [0][1][RTW89_IC][23] = 36, + [0][1][RTW89_KCC][23] = 32, + [0][1][RTW89_ACMA][23] = 12, + [0][1][RTW89_CHILE][23] = 36, + [0][1][RTW89_UKRAINE][23] = 12, + [0][1][RTW89_MEXICO][23] = 36, + [0][1][RTW89_CN][23] = 127, + [0][1][RTW89_QATAR][23] = 12, + [0][1][RTW89_UK][23] = 12, + [0][1][RTW89_FCC][25] = 36, + [0][1][RTW89_ETSI][25] = 12, + [0][1][RTW89_MKK][25] = 32, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_KCC][25] = 32, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_CHILE][25] = 36, + [0][1][RTW89_UKRAINE][25] = 12, + [0][1][RTW89_MEXICO][25] = 36, + [0][1][RTW89_CN][25] = 127, + [0][1][RTW89_QATAR][25] = 12, + [0][1][RTW89_UK][25] = 12, + [0][1][RTW89_FCC][27] = 36, + [0][1][RTW89_ETSI][27] = 12, + [0][1][RTW89_MKK][27] = 32, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_KCC][27] = 32, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_CHILE][27] = 36, + [0][1][RTW89_UKRAINE][27] = 12, + [0][1][RTW89_MEXICO][27] = 36, + [0][1][RTW89_CN][27] = 127, + [0][1][RTW89_QATAR][27] = 12, + [0][1][RTW89_UK][27] = 12, + [0][1][RTW89_FCC][29] = 36, + [0][1][RTW89_ETSI][29] = 12, + [0][1][RTW89_MKK][29] = 32, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_KCC][29] = 32, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_CHILE][29] = 36, + [0][1][RTW89_UKRAINE][29] = 12, + [0][1][RTW89_MEXICO][29] = 36, + [0][1][RTW89_CN][29] = 127, + [0][1][RTW89_QATAR][29] = 12, + [0][1][RTW89_UK][29] = 12, + [0][1][RTW89_FCC][31] = 36, + [0][1][RTW89_ETSI][31] = 12, + [0][1][RTW89_MKK][31] = 32, + [0][1][RTW89_IC][31] = 36, + [0][1][RTW89_KCC][31] = 32, + [0][1][RTW89_ACMA][31] = 12, + [0][1][RTW89_CHILE][31] = 36, + [0][1][RTW89_UKRAINE][31] = 12, + [0][1][RTW89_MEXICO][31] = 36, + [0][1][RTW89_CN][31] = 127, + [0][1][RTW89_QATAR][31] = 12, + [0][1][RTW89_UK][31] = 12, + [0][1][RTW89_FCC][33] = 36, + [0][1][RTW89_ETSI][33] = 12, + [0][1][RTW89_MKK][33] = 32, + [0][1][RTW89_IC][33] = 36, + [0][1][RTW89_KCC][33] = 32, + [0][1][RTW89_ACMA][33] = 12, + [0][1][RTW89_CHILE][33] = 36, + [0][1][RTW89_UKRAINE][33] = 12, + [0][1][RTW89_MEXICO][33] = 36, + [0][1][RTW89_CN][33] = 127, + [0][1][RTW89_QATAR][33] = 12, + [0][1][RTW89_UK][33] = 12, + [0][1][RTW89_FCC][35] = 36, + [0][1][RTW89_ETSI][35] = 12, + [0][1][RTW89_MKK][35] = 32, + [0][1][RTW89_IC][35] = 36, + [0][1][RTW89_KCC][35] = 32, + [0][1][RTW89_ACMA][35] = 12, + [0][1][RTW89_CHILE][35] = 36, + [0][1][RTW89_UKRAINE][35] = 12, + [0][1][RTW89_MEXICO][35] = 36, + [0][1][RTW89_CN][35] = 127, + [0][1][RTW89_QATAR][35] = 12, + [0][1][RTW89_UK][35] = 12, + [0][1][RTW89_FCC][37] = 36, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 32, + [0][1][RTW89_IC][37] = 36, + [0][1][RTW89_KCC][37] = 32, + [0][1][RTW89_ACMA][37] = 36, + [0][1][RTW89_CHILE][37] = 36, + [0][1][RTW89_UKRAINE][37] = 127, + [0][1][RTW89_MEXICO][37] = 36, + [0][1][RTW89_CN][37] = 127, + [0][1][RTW89_QATAR][37] = 127, + [0][1][RTW89_UK][37] = 46, + [0][1][RTW89_FCC][38] = 72, + [0][1][RTW89_ETSI][38] = 16, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 72, + [0][1][RTW89_KCC][38] = 32, + [0][1][RTW89_ACMA][38] = 76, + [0][1][RTW89_CHILE][38] = 42, + [0][1][RTW89_UKRAINE][38] = 16, + [0][1][RTW89_MEXICO][38] = 72, + [0][1][RTW89_CN][38] = 50, + [0][1][RTW89_QATAR][38] = 16, + [0][1][RTW89_UK][38] = 16, + [0][1][RTW89_FCC][40] = 76, + [0][1][RTW89_ETSI][40] = 16, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 76, + [0][1][RTW89_KCC][40] = 32, + [0][1][RTW89_ACMA][40] = 76, + [0][1][RTW89_CHILE][40] = 42, + [0][1][RTW89_UKRAINE][40] = 16, + [0][1][RTW89_MEXICO][40] = 76, + [0][1][RTW89_CN][40] = 50, + [0][1][RTW89_QATAR][40] = 16, + [0][1][RTW89_UK][40] = 16, + [0][1][RTW89_FCC][42] = 76, + [0][1][RTW89_ETSI][42] = 16, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 76, + [0][1][RTW89_KCC][42] = 32, + [0][1][RTW89_ACMA][42] = 76, + [0][1][RTW89_CHILE][42] = 42, + [0][1][RTW89_UKRAINE][42] = 16, + [0][1][RTW89_MEXICO][42] = 76, + [0][1][RTW89_CN][42] = 50, + [0][1][RTW89_QATAR][42] = 16, + [0][1][RTW89_UK][42] = 16, + [0][1][RTW89_FCC][44] = 76, + [0][1][RTW89_ETSI][44] = 16, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 76, + [0][1][RTW89_KCC][44] = 32, + [0][1][RTW89_ACMA][44] = 76, + [0][1][RTW89_CHILE][44] = 42, + [0][1][RTW89_UKRAINE][44] = 16, + [0][1][RTW89_MEXICO][44] = 76, + [0][1][RTW89_CN][44] = 50, + [0][1][RTW89_QATAR][44] = 16, + [0][1][RTW89_UK][44] = 16, + [0][1][RTW89_FCC][46] = 76, + [0][1][RTW89_ETSI][46] = 16, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 76, + [0][1][RTW89_KCC][46] = 32, + [0][1][RTW89_ACMA][46] = 76, + [0][1][RTW89_CHILE][46] = 42, + [0][1][RTW89_UKRAINE][46] = 16, + [0][1][RTW89_MEXICO][46] = 76, + [0][1][RTW89_CN][46] = 50, + [0][1][RTW89_QATAR][46] = 16, + [0][1][RTW89_UK][46] = 16, + [1][0][RTW89_FCC][0] = 62, + [1][0][RTW89_ETSI][0] = 36, + [1][0][RTW89_MKK][0] = 36, + [1][0][RTW89_IC][0] = 34, + [1][0][RTW89_KCC][0] = 58, + [1][0][RTW89_ACMA][0] = 36, + [1][0][RTW89_CHILE][0] = 30, + [1][0][RTW89_UKRAINE][0] = 36, + [1][0][RTW89_MEXICO][0] = 62, + [1][0][RTW89_CN][0] = 36, + [1][0][RTW89_QATAR][0] = 36, + [1][0][RTW89_UK][0] = 36, + [1][0][RTW89_FCC][2] = 62, + [1][0][RTW89_ETSI][2] = 36, + [1][0][RTW89_MKK][2] = 36, + [1][0][RTW89_IC][2] = 34, + [1][0][RTW89_KCC][2] = 58, + [1][0][RTW89_ACMA][2] = 36, + [1][0][RTW89_CHILE][2] = 30, + [1][0][RTW89_UKRAINE][2] = 36, + [1][0][RTW89_MEXICO][2] = 62, + [1][0][RTW89_CN][2] = 36, + [1][0][RTW89_QATAR][2] = 36, + [1][0][RTW89_UK][2] = 36, + [1][0][RTW89_FCC][4] = 62, + [1][0][RTW89_ETSI][4] = 36, + [1][0][RTW89_MKK][4] = 36, + [1][0][RTW89_IC][4] = 34, + [1][0][RTW89_KCC][4] = 58, + [1][0][RTW89_ACMA][4] = 36, + [1][0][RTW89_CHILE][4] = 30, + [1][0][RTW89_UKRAINE][4] = 36, + [1][0][RTW89_MEXICO][4] = 62, + [1][0][RTW89_CN][4] = 36, + [1][0][RTW89_QATAR][4] = 36, + [1][0][RTW89_UK][4] = 36, + [1][0][RTW89_FCC][6] = 62, + [1][0][RTW89_ETSI][6] = 36, + [1][0][RTW89_MKK][6] = 36, + [1][0][RTW89_IC][6] = 34, + [1][0][RTW89_KCC][6] = 32, + [1][0][RTW89_ACMA][6] = 36, + [1][0][RTW89_CHILE][6] = 30, + [1][0][RTW89_UKRAINE][6] = 36, + [1][0][RTW89_MEXICO][6] = 62, + [1][0][RTW89_CN][6] = 36, + [1][0][RTW89_QATAR][6] = 36, + [1][0][RTW89_UK][6] = 36, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 36, + [1][0][RTW89_MKK][8] = 36, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_KCC][8] = 58, + [1][0][RTW89_ACMA][8] = 36, + [1][0][RTW89_CHILE][8] = 54, + [1][0][RTW89_UKRAINE][8] = 36, + [1][0][RTW89_MEXICO][8] = 62, + [1][0][RTW89_CN][8] = 36, + [1][0][RTW89_QATAR][8] = 36, + [1][0][RTW89_UK][8] = 36, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 36, + [1][0][RTW89_MKK][10] = 36, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_KCC][10] = 58, + [1][0][RTW89_ACMA][10] = 36, + [1][0][RTW89_CHILE][10] = 54, + [1][0][RTW89_UKRAINE][10] = 36, + [1][0][RTW89_MEXICO][10] = 62, + [1][0][RTW89_CN][10] = 36, + [1][0][RTW89_QATAR][10] = 36, + [1][0][RTW89_UK][10] = 36, + [1][0][RTW89_FCC][12] = 62, + [1][0][RTW89_ETSI][12] = 36, + [1][0][RTW89_MKK][12] = 36, + [1][0][RTW89_IC][12] = 62, + [1][0][RTW89_KCC][12] = 58, + [1][0][RTW89_ACMA][12] = 36, + [1][0][RTW89_CHILE][12] = 54, + [1][0][RTW89_UKRAINE][12] = 36, + [1][0][RTW89_MEXICO][12] = 62, + [1][0][RTW89_CN][12] = 36, + [1][0][RTW89_QATAR][12] = 36, + [1][0][RTW89_UK][12] = 36, + [1][0][RTW89_FCC][14] = 62, + [1][0][RTW89_ETSI][14] = 36, + [1][0][RTW89_MKK][14] = 36, + [1][0][RTW89_IC][14] = 62, + [1][0][RTW89_KCC][14] = 58, + [1][0][RTW89_ACMA][14] = 36, + [1][0][RTW89_CHILE][14] = 54, + [1][0][RTW89_UKRAINE][14] = 36, + [1][0][RTW89_MEXICO][14] = 62, + [1][0][RTW89_CN][14] = 36, + [1][0][RTW89_QATAR][14] = 36, + [1][0][RTW89_UK][14] = 36, + [1][0][RTW89_FCC][15] = 62, + [1][0][RTW89_ETSI][15] = 36, + [1][0][RTW89_MKK][15] = 58, + [1][0][RTW89_IC][15] = 62, + [1][0][RTW89_KCC][15] = 58, + [1][0][RTW89_ACMA][15] = 36, + [1][0][RTW89_CHILE][15] = 54, + [1][0][RTW89_UKRAINE][15] = 36, + [1][0][RTW89_MEXICO][15] = 62, + [1][0][RTW89_CN][15] = 127, + [1][0][RTW89_QATAR][15] = 36, + [1][0][RTW89_UK][15] = 36, + [1][0][RTW89_FCC][17] = 62, + [1][0][RTW89_ETSI][17] = 36, + [1][0][RTW89_MKK][17] = 58, + [1][0][RTW89_IC][17] = 62, + [1][0][RTW89_KCC][17] = 58, + [1][0][RTW89_ACMA][17] = 36, + [1][0][RTW89_CHILE][17] = 54, + [1][0][RTW89_UKRAINE][17] = 36, + [1][0][RTW89_MEXICO][17] = 62, + [1][0][RTW89_CN][17] = 127, + [1][0][RTW89_QATAR][17] = 36, + [1][0][RTW89_UK][17] = 36, + [1][0][RTW89_FCC][19] = 62, + [1][0][RTW89_ETSI][19] = 36, + [1][0][RTW89_MKK][19] = 58, + [1][0][RTW89_IC][19] = 62, + [1][0][RTW89_KCC][19] = 58, + [1][0][RTW89_ACMA][19] = 36, + [1][0][RTW89_CHILE][19] = 54, + [1][0][RTW89_UKRAINE][19] = 36, + [1][0][RTW89_MEXICO][19] = 62, + [1][0][RTW89_CN][19] = 127, + [1][0][RTW89_QATAR][19] = 36, + [1][0][RTW89_UK][19] = 36, + [1][0][RTW89_FCC][21] = 62, + [1][0][RTW89_ETSI][21] = 36, + [1][0][RTW89_MKK][21] = 58, + [1][0][RTW89_IC][21] = 62, + [1][0][RTW89_KCC][21] = 58, + [1][0][RTW89_ACMA][21] = 36, + [1][0][RTW89_CHILE][21] = 54, + [1][0][RTW89_UKRAINE][21] = 36, + [1][0][RTW89_MEXICO][21] = 62, + [1][0][RTW89_CN][21] = 127, + [1][0][RTW89_QATAR][21] = 36, + [1][0][RTW89_UK][21] = 36, + [1][0][RTW89_FCC][23] = 62, + [1][0][RTW89_ETSI][23] = 36, + [1][0][RTW89_MKK][23] = 58, + [1][0][RTW89_IC][23] = 62, + [1][0][RTW89_KCC][23] = 58, + [1][0][RTW89_ACMA][23] = 36, + [1][0][RTW89_CHILE][23] = 54, + [1][0][RTW89_UKRAINE][23] = 36, + [1][0][RTW89_MEXICO][23] = 62, + [1][0][RTW89_CN][23] = 127, + [1][0][RTW89_QATAR][23] = 36, + [1][0][RTW89_UK][23] = 36, + [1][0][RTW89_FCC][25] = 62, + [1][0][RTW89_ETSI][25] = 36, + [1][0][RTW89_MKK][25] = 58, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_KCC][25] = 58, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_CHILE][25] = 54, + [1][0][RTW89_UKRAINE][25] = 36, + [1][0][RTW89_MEXICO][25] = 62, + [1][0][RTW89_CN][25] = 127, + [1][0][RTW89_QATAR][25] = 36, + [1][0][RTW89_UK][25] = 36, + [1][0][RTW89_FCC][27] = 62, + [1][0][RTW89_ETSI][27] = 36, + [1][0][RTW89_MKK][27] = 58, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_KCC][27] = 58, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_CHILE][27] = 54, + [1][0][RTW89_UKRAINE][27] = 36, + [1][0][RTW89_MEXICO][27] = 62, + [1][0][RTW89_CN][27] = 127, + [1][0][RTW89_QATAR][27] = 36, + [1][0][RTW89_UK][27] = 36, + [1][0][RTW89_FCC][29] = 62, + [1][0][RTW89_ETSI][29] = 36, + [1][0][RTW89_MKK][29] = 58, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_KCC][29] = 58, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_CHILE][29] = 54, + [1][0][RTW89_UKRAINE][29] = 36, + [1][0][RTW89_MEXICO][29] = 62, + [1][0][RTW89_CN][29] = 127, + [1][0][RTW89_QATAR][29] = 36, + [1][0][RTW89_UK][29] = 36, + [1][0][RTW89_FCC][31] = 62, + [1][0][RTW89_ETSI][31] = 36, + [1][0][RTW89_MKK][31] = 58, + [1][0][RTW89_IC][31] = 62, + [1][0][RTW89_KCC][31] = 58, + [1][0][RTW89_ACMA][31] = 36, + [1][0][RTW89_CHILE][31] = 54, + [1][0][RTW89_UKRAINE][31] = 36, + [1][0][RTW89_MEXICO][31] = 62, + [1][0][RTW89_CN][31] = 127, + [1][0][RTW89_QATAR][31] = 36, + [1][0][RTW89_UK][31] = 36, + [1][0][RTW89_FCC][33] = 62, + [1][0][RTW89_ETSI][33] = 36, + [1][0][RTW89_MKK][33] = 58, + [1][0][RTW89_IC][33] = 62, + [1][0][RTW89_KCC][33] = 58, + [1][0][RTW89_ACMA][33] = 36, + [1][0][RTW89_CHILE][33] = 54, + [1][0][RTW89_UKRAINE][33] = 36, + [1][0][RTW89_MEXICO][33] = 62, + [1][0][RTW89_CN][33] = 127, + [1][0][RTW89_QATAR][33] = 36, + [1][0][RTW89_UK][33] = 36, + [1][0][RTW89_FCC][35] = 62, + [1][0][RTW89_ETSI][35] = 36, + [1][0][RTW89_MKK][35] = 58, + [1][0][RTW89_IC][35] = 62, + [1][0][RTW89_KCC][35] = 58, + [1][0][RTW89_ACMA][35] = 36, + [1][0][RTW89_CHILE][35] = 54, + [1][0][RTW89_UKRAINE][35] = 36, + [1][0][RTW89_MEXICO][35] = 62, + [1][0][RTW89_CN][35] = 127, + [1][0][RTW89_QATAR][35] = 36, + [1][0][RTW89_UK][35] = 36, + [1][0][RTW89_FCC][37] = 62, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 58, + [1][0][RTW89_IC][37] = 62, + [1][0][RTW89_KCC][37] = 58, + [1][0][RTW89_ACMA][37] = 62, + [1][0][RTW89_CHILE][37] = 54, + [1][0][RTW89_UKRAINE][37] = 127, + [1][0][RTW89_MEXICO][37] = 62, + [1][0][RTW89_CN][37] = 127, + [1][0][RTW89_QATAR][37] = 127, + [1][0][RTW89_UK][37] = 64, + [1][0][RTW89_FCC][38] = 76, + [1][0][RTW89_ETSI][38] = 28, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 76, + [1][0][RTW89_KCC][38] = 58, + [1][0][RTW89_ACMA][38] = 76, + [1][0][RTW89_CHILE][38] = 54, + [1][0][RTW89_UKRAINE][38] = 28, + [1][0][RTW89_MEXICO][38] = 76, + [1][0][RTW89_CN][38] = 74, + [1][0][RTW89_QATAR][38] = 28, + [1][0][RTW89_UK][38] = 34, + [1][0][RTW89_FCC][40] = 76, + [1][0][RTW89_ETSI][40] = 28, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 76, + [1][0][RTW89_KCC][40] = 58, + [1][0][RTW89_ACMA][40] = 76, + [1][0][RTW89_CHILE][40] = 54, + [1][0][RTW89_UKRAINE][40] = 28, + [1][0][RTW89_MEXICO][40] = 76, + [1][0][RTW89_CN][40] = 74, + [1][0][RTW89_QATAR][40] = 28, + [1][0][RTW89_UK][40] = 34, + [1][0][RTW89_FCC][42] = 76, + [1][0][RTW89_ETSI][42] = 28, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 76, + [1][0][RTW89_KCC][42] = 58, + [1][0][RTW89_ACMA][42] = 76, + [1][0][RTW89_CHILE][42] = 54, + [1][0][RTW89_UKRAINE][42] = 28, + [1][0][RTW89_MEXICO][42] = 76, + [1][0][RTW89_CN][42] = 74, + [1][0][RTW89_QATAR][42] = 28, + [1][0][RTW89_UK][42] = 34, + [1][0][RTW89_FCC][44] = 76, + [1][0][RTW89_ETSI][44] = 28, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 76, + [1][0][RTW89_KCC][44] = 58, + [1][0][RTW89_ACMA][44] = 76, + [1][0][RTW89_CHILE][44] = 54, + [1][0][RTW89_UKRAINE][44] = 28, + [1][0][RTW89_MEXICO][44] = 76, + [1][0][RTW89_CN][44] = 74, + [1][0][RTW89_QATAR][44] = 28, + [1][0][RTW89_UK][44] = 34, + [1][0][RTW89_FCC][46] = 76, + [1][0][RTW89_ETSI][46] = 28, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 76, + [1][0][RTW89_KCC][46] = 58, + [1][0][RTW89_ACMA][46] = 76, + [1][0][RTW89_CHILE][46] = 54, + [1][0][RTW89_UKRAINE][46] = 28, + [1][0][RTW89_MEXICO][46] = 76, + [1][0][RTW89_CN][46] = 74, + [1][0][RTW89_QATAR][46] = 28, + [1][0][RTW89_UK][46] = 34, + [1][1][RTW89_FCC][0] = 46, + [1][1][RTW89_ETSI][0] = 22, + [1][1][RTW89_MKK][0] = 24, + [1][1][RTW89_IC][0] = 18, + [1][1][RTW89_KCC][0] = 44, + [1][1][RTW89_ACMA][0] = 22, + [1][1][RTW89_CHILE][0] = 18, + [1][1][RTW89_UKRAINE][0] = 22, + [1][1][RTW89_MEXICO][0] = 46, + [1][1][RTW89_CN][0] = 22, + [1][1][RTW89_QATAR][0] = 22, + [1][1][RTW89_UK][0] = 22, + [1][1][RTW89_FCC][2] = 46, + [1][1][RTW89_ETSI][2] = 22, + [1][1][RTW89_MKK][2] = 24, + [1][1][RTW89_IC][2] = 18, + [1][1][RTW89_KCC][2] = 44, + [1][1][RTW89_ACMA][2] = 22, + [1][1][RTW89_CHILE][2] = 18, + [1][1][RTW89_UKRAINE][2] = 22, + [1][1][RTW89_MEXICO][2] = 46, + [1][1][RTW89_CN][2] = 22, + [1][1][RTW89_QATAR][2] = 22, + [1][1][RTW89_UK][2] = 22, + [1][1][RTW89_FCC][4] = 46, + [1][1][RTW89_ETSI][4] = 22, + [1][1][RTW89_MKK][4] = 24, + [1][1][RTW89_IC][4] = 18, + [1][1][RTW89_KCC][4] = 44, + [1][1][RTW89_ACMA][4] = 22, + [1][1][RTW89_CHILE][4] = 18, + [1][1][RTW89_UKRAINE][4] = 22, + [1][1][RTW89_MEXICO][4] = 46, + [1][1][RTW89_CN][4] = 22, + [1][1][RTW89_QATAR][4] = 22, + [1][1][RTW89_UK][4] = 22, + [1][1][RTW89_FCC][6] = 46, + [1][1][RTW89_ETSI][6] = 22, + [1][1][RTW89_MKK][6] = 24, + [1][1][RTW89_IC][6] = 18, + [1][1][RTW89_KCC][6] = 16, + [1][1][RTW89_ACMA][6] = 22, + [1][1][RTW89_CHILE][6] = 18, + [1][1][RTW89_UKRAINE][6] = 22, + [1][1][RTW89_MEXICO][6] = 46, + [1][1][RTW89_CN][6] = 22, + [1][1][RTW89_QATAR][6] = 22, + [1][1][RTW89_UK][6] = 22, + [1][1][RTW89_FCC][8] = 46, + [1][1][RTW89_ETSI][8] = 22, + [1][1][RTW89_MKK][8] = 24, + [1][1][RTW89_IC][8] = 46, + [1][1][RTW89_KCC][8] = 44, + [1][1][RTW89_ACMA][8] = 22, + [1][1][RTW89_CHILE][8] = 42, + [1][1][RTW89_UKRAINE][8] = 22, + [1][1][RTW89_MEXICO][8] = 46, + [1][1][RTW89_CN][8] = 22, + [1][1][RTW89_QATAR][8] = 22, + [1][1][RTW89_UK][8] = 22, + [1][1][RTW89_FCC][10] = 46, + [1][1][RTW89_ETSI][10] = 22, + [1][1][RTW89_MKK][10] = 24, + [1][1][RTW89_IC][10] = 46, + [1][1][RTW89_KCC][10] = 44, + [1][1][RTW89_ACMA][10] = 22, + [1][1][RTW89_CHILE][10] = 42, + [1][1][RTW89_UKRAINE][10] = 22, + [1][1][RTW89_MEXICO][10] = 46, + [1][1][RTW89_CN][10] = 22, + [1][1][RTW89_QATAR][10] = 22, + [1][1][RTW89_UK][10] = 22, + [1][1][RTW89_FCC][12] = 46, + [1][1][RTW89_ETSI][12] = 22, + [1][1][RTW89_MKK][12] = 24, + [1][1][RTW89_IC][12] = 46, + [1][1][RTW89_KCC][12] = 44, + [1][1][RTW89_ACMA][12] = 22, + [1][1][RTW89_CHILE][12] = 42, + [1][1][RTW89_UKRAINE][12] = 22, + [1][1][RTW89_MEXICO][12] = 46, + [1][1][RTW89_CN][12] = 22, + [1][1][RTW89_QATAR][12] = 22, + [1][1][RTW89_UK][12] = 22, + [1][1][RTW89_FCC][14] = 46, + [1][1][RTW89_ETSI][14] = 22, + [1][1][RTW89_MKK][14] = 24, + [1][1][RTW89_IC][14] = 46, + [1][1][RTW89_KCC][14] = 44, + [1][1][RTW89_ACMA][14] = 22, + [1][1][RTW89_CHILE][14] = 42, + [1][1][RTW89_UKRAINE][14] = 22, + [1][1][RTW89_MEXICO][14] = 46, + [1][1][RTW89_CN][14] = 22, + [1][1][RTW89_QATAR][14] = 22, + [1][1][RTW89_UK][14] = 22, + [1][1][RTW89_FCC][15] = 46, + [1][1][RTW89_ETSI][15] = 22, + [1][1][RTW89_MKK][15] = 46, + [1][1][RTW89_IC][15] = 46, + [1][1][RTW89_KCC][15] = 44, + [1][1][RTW89_ACMA][15] = 22, + [1][1][RTW89_CHILE][15] = 42, + [1][1][RTW89_UKRAINE][15] = 22, + [1][1][RTW89_MEXICO][15] = 46, + [1][1][RTW89_CN][15] = 127, + [1][1][RTW89_QATAR][15] = 22, + [1][1][RTW89_UK][15] = 22, + [1][1][RTW89_FCC][17] = 46, + [1][1][RTW89_ETSI][17] = 22, + [1][1][RTW89_MKK][17] = 46, + [1][1][RTW89_IC][17] = 46, + [1][1][RTW89_KCC][17] = 44, + [1][1][RTW89_ACMA][17] = 22, + [1][1][RTW89_CHILE][17] = 42, + [1][1][RTW89_UKRAINE][17] = 22, + [1][1][RTW89_MEXICO][17] = 46, + [1][1][RTW89_CN][17] = 127, + [1][1][RTW89_QATAR][17] = 22, + [1][1][RTW89_UK][17] = 22, + [1][1][RTW89_FCC][19] = 46, + [1][1][RTW89_ETSI][19] = 22, + [1][1][RTW89_MKK][19] = 46, + [1][1][RTW89_IC][19] = 46, + [1][1][RTW89_KCC][19] = 44, + [1][1][RTW89_ACMA][19] = 22, + [1][1][RTW89_CHILE][19] = 42, + [1][1][RTW89_UKRAINE][19] = 22, + [1][1][RTW89_MEXICO][19] = 46, + [1][1][RTW89_CN][19] = 127, + [1][1][RTW89_QATAR][19] = 22, + [1][1][RTW89_UK][19] = 22, + [1][1][RTW89_FCC][21] = 46, + [1][1][RTW89_ETSI][21] = 22, + [1][1][RTW89_MKK][21] = 46, + [1][1][RTW89_IC][21] = 46, + [1][1][RTW89_KCC][21] = 44, + [1][1][RTW89_ACMA][21] = 22, + [1][1][RTW89_CHILE][21] = 42, + [1][1][RTW89_UKRAINE][21] = 22, + [1][1][RTW89_MEXICO][21] = 46, + [1][1][RTW89_CN][21] = 127, + [1][1][RTW89_QATAR][21] = 22, + [1][1][RTW89_UK][21] = 22, + [1][1][RTW89_FCC][23] = 46, + [1][1][RTW89_ETSI][23] = 22, + [1][1][RTW89_MKK][23] = 46, + [1][1][RTW89_IC][23] = 46, + [1][1][RTW89_KCC][23] = 44, + [1][1][RTW89_ACMA][23] = 22, + [1][1][RTW89_CHILE][23] = 42, + [1][1][RTW89_UKRAINE][23] = 22, + [1][1][RTW89_MEXICO][23] = 46, + [1][1][RTW89_CN][23] = 127, + [1][1][RTW89_QATAR][23] = 22, + [1][1][RTW89_UK][23] = 22, + [1][1][RTW89_FCC][25] = 46, + [1][1][RTW89_ETSI][25] = 22, + [1][1][RTW89_MKK][25] = 46, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_KCC][25] = 44, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_CHILE][25] = 42, + [1][1][RTW89_UKRAINE][25] = 22, + [1][1][RTW89_MEXICO][25] = 46, + [1][1][RTW89_CN][25] = 127, + [1][1][RTW89_QATAR][25] = 22, + [1][1][RTW89_UK][25] = 22, + [1][1][RTW89_FCC][27] = 46, + [1][1][RTW89_ETSI][27] = 22, + [1][1][RTW89_MKK][27] = 46, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_KCC][27] = 44, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_CHILE][27] = 42, + [1][1][RTW89_UKRAINE][27] = 22, + [1][1][RTW89_MEXICO][27] = 46, + [1][1][RTW89_CN][27] = 127, + [1][1][RTW89_QATAR][27] = 22, + [1][1][RTW89_UK][27] = 22, + [1][1][RTW89_FCC][29] = 46, + [1][1][RTW89_ETSI][29] = 22, + [1][1][RTW89_MKK][29] = 46, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_KCC][29] = 44, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_CHILE][29] = 42, + [1][1][RTW89_UKRAINE][29] = 22, + [1][1][RTW89_MEXICO][29] = 46, + [1][1][RTW89_CN][29] = 127, + [1][1][RTW89_QATAR][29] = 22, + [1][1][RTW89_UK][29] = 22, + [1][1][RTW89_FCC][31] = 46, + [1][1][RTW89_ETSI][31] = 22, + [1][1][RTW89_MKK][31] = 46, + [1][1][RTW89_IC][31] = 46, + [1][1][RTW89_KCC][31] = 44, + [1][1][RTW89_ACMA][31] = 22, + [1][1][RTW89_CHILE][31] = 42, + [1][1][RTW89_UKRAINE][31] = 22, + [1][1][RTW89_MEXICO][31] = 46, + [1][1][RTW89_CN][31] = 127, + [1][1][RTW89_QATAR][31] = 22, + [1][1][RTW89_UK][31] = 22, + [1][1][RTW89_FCC][33] = 46, + [1][1][RTW89_ETSI][33] = 22, + [1][1][RTW89_MKK][33] = 46, + [1][1][RTW89_IC][33] = 46, + [1][1][RTW89_KCC][33] = 44, + [1][1][RTW89_ACMA][33] = 22, + [1][1][RTW89_CHILE][33] = 42, + [1][1][RTW89_UKRAINE][33] = 22, + [1][1][RTW89_MEXICO][33] = 46, + [1][1][RTW89_CN][33] = 127, + [1][1][RTW89_QATAR][33] = 22, + [1][1][RTW89_UK][33] = 22, + [1][1][RTW89_FCC][35] = 46, + [1][1][RTW89_ETSI][35] = 22, + [1][1][RTW89_MKK][35] = 46, + [1][1][RTW89_IC][35] = 46, + [1][1][RTW89_KCC][35] = 44, + [1][1][RTW89_ACMA][35] = 22, + [1][1][RTW89_CHILE][35] = 42, + [1][1][RTW89_UKRAINE][35] = 22, + [1][1][RTW89_MEXICO][35] = 46, + [1][1][RTW89_CN][35] = 127, + [1][1][RTW89_QATAR][35] = 22, + [1][1][RTW89_UK][35] = 22, + [1][1][RTW89_FCC][37] = 46, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 46, + [1][1][RTW89_IC][37] = 46, + [1][1][RTW89_KCC][37] = 44, + [1][1][RTW89_ACMA][37] = 50, + [1][1][RTW89_CHILE][37] = 42, + [1][1][RTW89_UKRAINE][37] = 127, + [1][1][RTW89_MEXICO][37] = 46, + [1][1][RTW89_CN][37] = 127, + [1][1][RTW89_QATAR][37] = 127, + [1][1][RTW89_UK][37] = 52, + [1][1][RTW89_FCC][38] = 74, + [1][1][RTW89_ETSI][38] = 16, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 74, + [1][1][RTW89_KCC][38] = 44, + [1][1][RTW89_ACMA][38] = 76, + [1][1][RTW89_CHILE][38] = 42, + [1][1][RTW89_UKRAINE][38] = 16, + [1][1][RTW89_MEXICO][38] = 74, + [1][1][RTW89_CN][38] = 62, + [1][1][RTW89_QATAR][38] = 16, + [1][1][RTW89_UK][38] = 22, + [1][1][RTW89_FCC][40] = 76, + [1][1][RTW89_ETSI][40] = 16, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 76, + [1][1][RTW89_KCC][40] = 44, + [1][1][RTW89_ACMA][40] = 76, + [1][1][RTW89_CHILE][40] = 42, + [1][1][RTW89_UKRAINE][40] = 16, + [1][1][RTW89_MEXICO][40] = 76, + [1][1][RTW89_CN][40] = 62, + [1][1][RTW89_QATAR][40] = 16, + [1][1][RTW89_UK][40] = 22, + [1][1][RTW89_FCC][42] = 76, + [1][1][RTW89_ETSI][42] = 16, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 76, + [1][1][RTW89_KCC][42] = 44, + [1][1][RTW89_ACMA][42] = 76, + [1][1][RTW89_CHILE][42] = 42, + [1][1][RTW89_UKRAINE][42] = 16, + [1][1][RTW89_MEXICO][42] = 76, + [1][1][RTW89_CN][42] = 62, + [1][1][RTW89_QATAR][42] = 16, + [1][1][RTW89_UK][42] = 22, + [1][1][RTW89_FCC][44] = 76, + [1][1][RTW89_ETSI][44] = 16, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 76, + [1][1][RTW89_KCC][44] = 44, + [1][1][RTW89_ACMA][44] = 76, + [1][1][RTW89_CHILE][44] = 42, + [1][1][RTW89_UKRAINE][44] = 16, + [1][1][RTW89_MEXICO][44] = 76, + [1][1][RTW89_CN][44] = 62, + [1][1][RTW89_QATAR][44] = 16, + [1][1][RTW89_UK][44] = 22, + [1][1][RTW89_FCC][46] = 76, + [1][1][RTW89_ETSI][46] = 16, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 76, + [1][1][RTW89_KCC][46] = 44, + [1][1][RTW89_ACMA][46] = 76, + [1][1][RTW89_CHILE][46] = 42, + [1][1][RTW89_UKRAINE][46] = 16, + [1][1][RTW89_MEXICO][46] = 76, + [1][1][RTW89_CN][46] = 62, + [1][1][RTW89_QATAR][46] = 16, + [1][1][RTW89_UK][46] = 22, + [2][0][RTW89_FCC][0] = 74, + [2][0][RTW89_ETSI][0] = 46, + [2][0][RTW89_MKK][0] = 50, + [2][0][RTW89_IC][0] = 46, + [2][0][RTW89_KCC][0] = 70, + [2][0][RTW89_ACMA][0] = 46, + [2][0][RTW89_CHILE][0] = 30, + [2][0][RTW89_UKRAINE][0] = 46, + [2][0][RTW89_MEXICO][0] = 62, + [2][0][RTW89_CN][0] = 46, + [2][0][RTW89_QATAR][0] = 46, + [2][0][RTW89_UK][0] = 46, + [2][0][RTW89_FCC][2] = 74, + [2][0][RTW89_ETSI][2] = 46, + [2][0][RTW89_MKK][2] = 50, + [2][0][RTW89_IC][2] = 46, + [2][0][RTW89_KCC][2] = 70, + [2][0][RTW89_ACMA][2] = 46, + [2][0][RTW89_CHILE][2] = 30, + [2][0][RTW89_UKRAINE][2] = 46, + [2][0][RTW89_MEXICO][2] = 62, + [2][0][RTW89_CN][2] = 46, + [2][0][RTW89_QATAR][2] = 46, + [2][0][RTW89_UK][2] = 46, + [2][0][RTW89_FCC][4] = 74, + [2][0][RTW89_ETSI][4] = 46, + [2][0][RTW89_MKK][4] = 50, + [2][0][RTW89_IC][4] = 46, + [2][0][RTW89_KCC][4] = 70, + [2][0][RTW89_ACMA][4] = 46, + [2][0][RTW89_CHILE][4] = 30, + [2][0][RTW89_UKRAINE][4] = 46, + [2][0][RTW89_MEXICO][4] = 62, + [2][0][RTW89_CN][4] = 46, + [2][0][RTW89_QATAR][4] = 46, + [2][0][RTW89_UK][4] = 46, + [2][0][RTW89_FCC][6] = 74, + [2][0][RTW89_ETSI][6] = 46, + [2][0][RTW89_MKK][6] = 50, + [2][0][RTW89_IC][6] = 46, + [2][0][RTW89_KCC][6] = 44, + [2][0][RTW89_ACMA][6] = 46, + [2][0][RTW89_CHILE][6] = 30, + [2][0][RTW89_UKRAINE][6] = 46, + [2][0][RTW89_MEXICO][6] = 62, + [2][0][RTW89_CN][6] = 46, + [2][0][RTW89_QATAR][6] = 46, + [2][0][RTW89_UK][6] = 46, + [2][0][RTW89_FCC][8] = 74, + [2][0][RTW89_ETSI][8] = 46, + [2][0][RTW89_MKK][8] = 50, + [2][0][RTW89_IC][8] = 66, + [2][0][RTW89_KCC][8] = 70, + [2][0][RTW89_ACMA][8] = 46, + [2][0][RTW89_CHILE][8] = 54, + [2][0][RTW89_UKRAINE][8] = 46, + [2][0][RTW89_MEXICO][8] = 74, + [2][0][RTW89_CN][8] = 46, + [2][0][RTW89_QATAR][8] = 46, + [2][0][RTW89_UK][8] = 46, + [2][0][RTW89_FCC][10] = 74, + [2][0][RTW89_ETSI][10] = 46, + [2][0][RTW89_MKK][10] = 50, + [2][0][RTW89_IC][10] = 66, + [2][0][RTW89_KCC][10] = 70, + [2][0][RTW89_ACMA][10] = 46, + [2][0][RTW89_CHILE][10] = 54, + [2][0][RTW89_UKRAINE][10] = 46, + [2][0][RTW89_MEXICO][10] = 74, + [2][0][RTW89_CN][10] = 46, + [2][0][RTW89_QATAR][10] = 46, + [2][0][RTW89_UK][10] = 46, + [2][0][RTW89_FCC][12] = 74, + [2][0][RTW89_ETSI][12] = 46, + [2][0][RTW89_MKK][12] = 50, + [2][0][RTW89_IC][12] = 66, + [2][0][RTW89_KCC][12] = 70, + [2][0][RTW89_ACMA][12] = 46, + [2][0][RTW89_CHILE][12] = 54, + [2][0][RTW89_UKRAINE][12] = 46, + [2][0][RTW89_MEXICO][12] = 74, + [2][0][RTW89_CN][12] = 46, + [2][0][RTW89_QATAR][12] = 46, + [2][0][RTW89_UK][12] = 46, + [2][0][RTW89_FCC][14] = 74, + [2][0][RTW89_ETSI][14] = 46, + [2][0][RTW89_MKK][14] = 50, + [2][0][RTW89_IC][14] = 66, + [2][0][RTW89_KCC][14] = 70, + [2][0][RTW89_ACMA][14] = 46, + [2][0][RTW89_CHILE][14] = 54, + [2][0][RTW89_UKRAINE][14] = 46, + [2][0][RTW89_MEXICO][14] = 74, + [2][0][RTW89_CN][14] = 46, + [2][0][RTW89_QATAR][14] = 46, + [2][0][RTW89_UK][14] = 46, + [2][0][RTW89_FCC][15] = 74, + [2][0][RTW89_ETSI][15] = 46, + [2][0][RTW89_MKK][15] = 70, + [2][0][RTW89_IC][15] = 74, + [2][0][RTW89_KCC][15] = 70, + [2][0][RTW89_ACMA][15] = 46, + [2][0][RTW89_CHILE][15] = 54, + [2][0][RTW89_UKRAINE][15] = 46, + [2][0][RTW89_MEXICO][15] = 74, + [2][0][RTW89_CN][15] = 127, + [2][0][RTW89_QATAR][15] = 46, + [2][0][RTW89_UK][15] = 46, + [2][0][RTW89_FCC][17] = 74, + [2][0][RTW89_ETSI][17] = 46, + [2][0][RTW89_MKK][17] = 70, + [2][0][RTW89_IC][17] = 74, + [2][0][RTW89_KCC][17] = 70, + [2][0][RTW89_ACMA][17] = 46, + [2][0][RTW89_CHILE][17] = 54, + [2][0][RTW89_UKRAINE][17] = 46, + [2][0][RTW89_MEXICO][17] = 74, + [2][0][RTW89_CN][17] = 127, + [2][0][RTW89_QATAR][17] = 46, + [2][0][RTW89_UK][17] = 46, + [2][0][RTW89_FCC][19] = 74, + [2][0][RTW89_ETSI][19] = 46, + [2][0][RTW89_MKK][19] = 70, + [2][0][RTW89_IC][19] = 74, + [2][0][RTW89_KCC][19] = 70, + [2][0][RTW89_ACMA][19] = 46, + [2][0][RTW89_CHILE][19] = 54, + [2][0][RTW89_UKRAINE][19] = 46, + [2][0][RTW89_MEXICO][19] = 74, + [2][0][RTW89_CN][19] = 127, + [2][0][RTW89_QATAR][19] = 46, + [2][0][RTW89_UK][19] = 46, + [2][0][RTW89_FCC][21] = 74, + [2][0][RTW89_ETSI][21] = 46, + [2][0][RTW89_MKK][21] = 70, + [2][0][RTW89_IC][21] = 74, + [2][0][RTW89_KCC][21] = 70, + [2][0][RTW89_ACMA][21] = 46, + [2][0][RTW89_CHILE][21] = 54, + [2][0][RTW89_UKRAINE][21] = 46, + [2][0][RTW89_MEXICO][21] = 74, + [2][0][RTW89_CN][21] = 127, + [2][0][RTW89_QATAR][21] = 46, + [2][0][RTW89_UK][21] = 46, + [2][0][RTW89_FCC][23] = 74, + [2][0][RTW89_ETSI][23] = 46, + [2][0][RTW89_MKK][23] = 70, + [2][0][RTW89_IC][23] = 74, + [2][0][RTW89_KCC][23] = 70, + [2][0][RTW89_ACMA][23] = 46, + [2][0][RTW89_CHILE][23] = 54, + [2][0][RTW89_UKRAINE][23] = 46, + [2][0][RTW89_MEXICO][23] = 74, + [2][0][RTW89_CN][23] = 127, + [2][0][RTW89_QATAR][23] = 46, + [2][0][RTW89_UK][23] = 46, + [2][0][RTW89_FCC][25] = 74, + [2][0][RTW89_ETSI][25] = 46, + [2][0][RTW89_MKK][25] = 70, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_KCC][25] = 70, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_CHILE][25] = 54, + [2][0][RTW89_UKRAINE][25] = 46, + [2][0][RTW89_MEXICO][25] = 74, + [2][0][RTW89_CN][25] = 127, + [2][0][RTW89_QATAR][25] = 46, + [2][0][RTW89_UK][25] = 46, + [2][0][RTW89_FCC][27] = 74, + [2][0][RTW89_ETSI][27] = 46, + [2][0][RTW89_MKK][27] = 70, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_KCC][27] = 70, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_CHILE][27] = 54, + [2][0][RTW89_UKRAINE][27] = 46, + [2][0][RTW89_MEXICO][27] = 74, + [2][0][RTW89_CN][27] = 127, + [2][0][RTW89_QATAR][27] = 46, + [2][0][RTW89_UK][27] = 46, + [2][0][RTW89_FCC][29] = 74, + [2][0][RTW89_ETSI][29] = 46, + [2][0][RTW89_MKK][29] = 70, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_KCC][29] = 70, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_CHILE][29] = 54, + [2][0][RTW89_UKRAINE][29] = 46, + [2][0][RTW89_MEXICO][29] = 74, + [2][0][RTW89_CN][29] = 127, + [2][0][RTW89_QATAR][29] = 46, + [2][0][RTW89_UK][29] = 46, + [2][0][RTW89_FCC][31] = 74, + [2][0][RTW89_ETSI][31] = 46, + [2][0][RTW89_MKK][31] = 70, + [2][0][RTW89_IC][31] = 74, + [2][0][RTW89_KCC][31] = 70, + [2][0][RTW89_ACMA][31] = 46, + [2][0][RTW89_CHILE][31] = 54, + [2][0][RTW89_UKRAINE][31] = 46, + [2][0][RTW89_MEXICO][31] = 74, + [2][0][RTW89_CN][31] = 127, + [2][0][RTW89_QATAR][31] = 46, + [2][0][RTW89_UK][31] = 46, + [2][0][RTW89_FCC][33] = 74, + [2][0][RTW89_ETSI][33] = 46, + [2][0][RTW89_MKK][33] = 70, + [2][0][RTW89_IC][33] = 74, + [2][0][RTW89_KCC][33] = 70, + [2][0][RTW89_ACMA][33] = 46, + [2][0][RTW89_CHILE][33] = 54, + [2][0][RTW89_UKRAINE][33] = 46, + [2][0][RTW89_MEXICO][33] = 74, + [2][0][RTW89_CN][33] = 127, + [2][0][RTW89_QATAR][33] = 46, + [2][0][RTW89_UK][33] = 46, + [2][0][RTW89_FCC][35] = 74, + [2][0][RTW89_ETSI][35] = 46, + [2][0][RTW89_MKK][35] = 70, + [2][0][RTW89_IC][35] = 74, + [2][0][RTW89_KCC][35] = 70, + [2][0][RTW89_ACMA][35] = 46, + [2][0][RTW89_CHILE][35] = 54, + [2][0][RTW89_UKRAINE][35] = 46, + [2][0][RTW89_MEXICO][35] = 74, + [2][0][RTW89_CN][35] = 127, + [2][0][RTW89_QATAR][35] = 46, + [2][0][RTW89_UK][35] = 46, + [2][0][RTW89_FCC][37] = 74, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 70, + [2][0][RTW89_IC][37] = 74, + [2][0][RTW89_KCC][37] = 70, + [2][0][RTW89_ACMA][37] = 74, + [2][0][RTW89_CHILE][37] = 54, + [2][0][RTW89_UKRAINE][37] = 127, + [2][0][RTW89_MEXICO][37] = 74, + [2][0][RTW89_CN][37] = 127, + [2][0][RTW89_QATAR][37] = 127, + [2][0][RTW89_UK][37] = 74, + [2][0][RTW89_FCC][38] = 76, + [2][0][RTW89_ETSI][38] = 28, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 76, + [2][0][RTW89_KCC][38] = 70, + [2][0][RTW89_ACMA][38] = 76, + [2][0][RTW89_CHILE][38] = 54, + [2][0][RTW89_UKRAINE][38] = 28, + [2][0][RTW89_MEXICO][38] = 76, + [2][0][RTW89_CN][38] = 76, + [2][0][RTW89_QATAR][38] = 28, + [2][0][RTW89_UK][38] = 44, + [2][0][RTW89_FCC][40] = 76, + [2][0][RTW89_ETSI][40] = 28, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 76, + [2][0][RTW89_KCC][40] = 70, + [2][0][RTW89_ACMA][40] = 76, + [2][0][RTW89_CHILE][40] = 54, + [2][0][RTW89_UKRAINE][40] = 28, + [2][0][RTW89_MEXICO][40] = 76, + [2][0][RTW89_CN][40] = 76, + [2][0][RTW89_QATAR][40] = 28, + [2][0][RTW89_UK][40] = 44, + [2][0][RTW89_FCC][42] = 76, + [2][0][RTW89_ETSI][42] = 28, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 76, + [2][0][RTW89_KCC][42] = 70, + [2][0][RTW89_ACMA][42] = 76, + [2][0][RTW89_CHILE][42] = 54, + [2][0][RTW89_UKRAINE][42] = 28, + [2][0][RTW89_MEXICO][42] = 76, + [2][0][RTW89_CN][42] = 76, + [2][0][RTW89_QATAR][42] = 28, + [2][0][RTW89_UK][42] = 44, + [2][0][RTW89_FCC][44] = 76, + [2][0][RTW89_ETSI][44] = 28, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 76, + [2][0][RTW89_KCC][44] = 70, + [2][0][RTW89_ACMA][44] = 76, + [2][0][RTW89_CHILE][44] = 54, + [2][0][RTW89_UKRAINE][44] = 28, + [2][0][RTW89_MEXICO][44] = 76, + [2][0][RTW89_CN][44] = 76, + [2][0][RTW89_QATAR][44] = 28, + [2][0][RTW89_UK][44] = 44, + [2][0][RTW89_FCC][46] = 76, + [2][0][RTW89_ETSI][46] = 28, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 76, + [2][0][RTW89_KCC][46] = 70, + [2][0][RTW89_ACMA][46] = 76, + [2][0][RTW89_CHILE][46] = 54, + [2][0][RTW89_UKRAINE][46] = 28, + [2][0][RTW89_MEXICO][46] = 76, + [2][0][RTW89_CN][46] = 76, + [2][0][RTW89_QATAR][46] = 28, + [2][0][RTW89_UK][46] = 44, + [2][1][RTW89_FCC][0] = 58, + [2][1][RTW89_ETSI][0] = 32, + [2][1][RTW89_MKK][0] = 38, + [2][1][RTW89_IC][0] = 30, + [2][1][RTW89_KCC][0] = 54, + [2][1][RTW89_ACMA][0] = 32, + [2][1][RTW89_CHILE][0] = 18, + [2][1][RTW89_UKRAINE][0] = 32, + [2][1][RTW89_MEXICO][0] = 50, + [2][1][RTW89_CN][0] = 32, + [2][1][RTW89_QATAR][0] = 32, + [2][1][RTW89_UK][0] = 32, + [2][1][RTW89_FCC][2] = 58, + [2][1][RTW89_ETSI][2] = 32, + [2][1][RTW89_MKK][2] = 38, + [2][1][RTW89_IC][2] = 30, + [2][1][RTW89_KCC][2] = 54, + [2][1][RTW89_ACMA][2] = 32, + [2][1][RTW89_CHILE][2] = 18, + [2][1][RTW89_UKRAINE][2] = 32, + [2][1][RTW89_MEXICO][2] = 50, + [2][1][RTW89_CN][2] = 32, + [2][1][RTW89_QATAR][2] = 32, + [2][1][RTW89_UK][2] = 32, + [2][1][RTW89_FCC][4] = 58, + [2][1][RTW89_ETSI][4] = 32, + [2][1][RTW89_MKK][4] = 38, + [2][1][RTW89_IC][4] = 30, + [2][1][RTW89_KCC][4] = 54, + [2][1][RTW89_ACMA][4] = 32, + [2][1][RTW89_CHILE][4] = 18, + [2][1][RTW89_UKRAINE][4] = 32, + [2][1][RTW89_MEXICO][4] = 50, + [2][1][RTW89_CN][4] = 32, + [2][1][RTW89_QATAR][4] = 32, + [2][1][RTW89_UK][4] = 32, + [2][1][RTW89_FCC][6] = 58, + [2][1][RTW89_ETSI][6] = 32, + [2][1][RTW89_MKK][6] = 38, + [2][1][RTW89_IC][6] = 30, + [2][1][RTW89_KCC][6] = 26, + [2][1][RTW89_ACMA][6] = 32, + [2][1][RTW89_CHILE][6] = 18, + [2][1][RTW89_UKRAINE][6] = 32, + [2][1][RTW89_MEXICO][6] = 50, + [2][1][RTW89_CN][6] = 32, + [2][1][RTW89_QATAR][6] = 32, + [2][1][RTW89_UK][6] = 32, + [2][1][RTW89_FCC][8] = 58, + [2][1][RTW89_ETSI][8] = 32, + [2][1][RTW89_MKK][8] = 38, + [2][1][RTW89_IC][8] = 52, + [2][1][RTW89_KCC][8] = 54, + [2][1][RTW89_ACMA][8] = 32, + [2][1][RTW89_CHILE][8] = 42, + [2][1][RTW89_UKRAINE][8] = 32, + [2][1][RTW89_MEXICO][8] = 58, + [2][1][RTW89_CN][8] = 32, + [2][1][RTW89_QATAR][8] = 32, + [2][1][RTW89_UK][8] = 32, + [2][1][RTW89_FCC][10] = 58, + [2][1][RTW89_ETSI][10] = 32, + [2][1][RTW89_MKK][10] = 38, + [2][1][RTW89_IC][10] = 52, + [2][1][RTW89_KCC][10] = 54, + [2][1][RTW89_ACMA][10] = 32, + [2][1][RTW89_CHILE][10] = 42, + [2][1][RTW89_UKRAINE][10] = 32, + [2][1][RTW89_MEXICO][10] = 58, + [2][1][RTW89_CN][10] = 32, + [2][1][RTW89_QATAR][10] = 32, + [2][1][RTW89_UK][10] = 32, + [2][1][RTW89_FCC][12] = 58, + [2][1][RTW89_ETSI][12] = 32, + [2][1][RTW89_MKK][12] = 38, + [2][1][RTW89_IC][12] = 52, + [2][1][RTW89_KCC][12] = 54, + [2][1][RTW89_ACMA][12] = 32, + [2][1][RTW89_CHILE][12] = 42, + [2][1][RTW89_UKRAINE][12] = 32, + [2][1][RTW89_MEXICO][12] = 58, + [2][1][RTW89_CN][12] = 32, + [2][1][RTW89_QATAR][12] = 32, + [2][1][RTW89_UK][12] = 32, + [2][1][RTW89_FCC][14] = 58, + [2][1][RTW89_ETSI][14] = 32, + [2][1][RTW89_MKK][14] = 38, + [2][1][RTW89_IC][14] = 52, + [2][1][RTW89_KCC][14] = 54, + [2][1][RTW89_ACMA][14] = 32, + [2][1][RTW89_CHILE][14] = 42, + [2][1][RTW89_UKRAINE][14] = 32, + [2][1][RTW89_MEXICO][14] = 58, + [2][1][RTW89_CN][14] = 32, + [2][1][RTW89_QATAR][14] = 32, + [2][1][RTW89_UK][14] = 32, + [2][1][RTW89_FCC][15] = 58, + [2][1][RTW89_ETSI][15] = 32, + [2][1][RTW89_MKK][15] = 58, + [2][1][RTW89_IC][15] = 58, + [2][1][RTW89_KCC][15] = 54, + [2][1][RTW89_ACMA][15] = 32, + [2][1][RTW89_CHILE][15] = 42, + [2][1][RTW89_UKRAINE][15] = 32, + [2][1][RTW89_MEXICO][15] = 58, + [2][1][RTW89_CN][15] = 127, + [2][1][RTW89_QATAR][15] = 32, + [2][1][RTW89_UK][15] = 32, + [2][1][RTW89_FCC][17] = 58, + [2][1][RTW89_ETSI][17] = 32, + [2][1][RTW89_MKK][17] = 58, + [2][1][RTW89_IC][17] = 58, + [2][1][RTW89_KCC][17] = 54, + [2][1][RTW89_ACMA][17] = 32, + [2][1][RTW89_CHILE][17] = 42, + [2][1][RTW89_UKRAINE][17] = 32, + [2][1][RTW89_MEXICO][17] = 58, + [2][1][RTW89_CN][17] = 127, + [2][1][RTW89_QATAR][17] = 32, + [2][1][RTW89_UK][17] = 32, + [2][1][RTW89_FCC][19] = 58, + [2][1][RTW89_ETSI][19] = 32, + [2][1][RTW89_MKK][19] = 58, + [2][1][RTW89_IC][19] = 58, + [2][1][RTW89_KCC][19] = 54, + [2][1][RTW89_ACMA][19] = 32, + [2][1][RTW89_CHILE][19] = 42, + [2][1][RTW89_UKRAINE][19] = 32, + [2][1][RTW89_MEXICO][19] = 58, + [2][1][RTW89_CN][19] = 127, + [2][1][RTW89_QATAR][19] = 32, + [2][1][RTW89_UK][19] = 32, + [2][1][RTW89_FCC][21] = 58, + [2][1][RTW89_ETSI][21] = 32, + [2][1][RTW89_MKK][21] = 58, + [2][1][RTW89_IC][21] = 58, + [2][1][RTW89_KCC][21] = 54, + [2][1][RTW89_ACMA][21] = 32, + [2][1][RTW89_CHILE][21] = 42, + [2][1][RTW89_UKRAINE][21] = 32, + [2][1][RTW89_MEXICO][21] = 58, + [2][1][RTW89_CN][21] = 127, + [2][1][RTW89_QATAR][21] = 32, + [2][1][RTW89_UK][21] = 32, + [2][1][RTW89_FCC][23] = 58, + [2][1][RTW89_ETSI][23] = 32, + [2][1][RTW89_MKK][23] = 58, + [2][1][RTW89_IC][23] = 58, + [2][1][RTW89_KCC][23] = 54, + [2][1][RTW89_ACMA][23] = 32, + [2][1][RTW89_CHILE][23] = 42, + [2][1][RTW89_UKRAINE][23] = 32, + [2][1][RTW89_MEXICO][23] = 58, + [2][1][RTW89_CN][23] = 127, + [2][1][RTW89_QATAR][23] = 32, + [2][1][RTW89_UK][23] = 32, + [2][1][RTW89_FCC][25] = 58, + [2][1][RTW89_ETSI][25] = 32, + [2][1][RTW89_MKK][25] = 58, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_KCC][25] = 54, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_CHILE][25] = 42, + [2][1][RTW89_UKRAINE][25] = 32, + [2][1][RTW89_MEXICO][25] = 58, + [2][1][RTW89_CN][25] = 127, + [2][1][RTW89_QATAR][25] = 32, + [2][1][RTW89_UK][25] = 32, + [2][1][RTW89_FCC][27] = 58, + [2][1][RTW89_ETSI][27] = 32, + [2][1][RTW89_MKK][27] = 58, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_KCC][27] = 54, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_CHILE][27] = 42, + [2][1][RTW89_UKRAINE][27] = 32, + [2][1][RTW89_MEXICO][27] = 58, + [2][1][RTW89_CN][27] = 127, + [2][1][RTW89_QATAR][27] = 32, + [2][1][RTW89_UK][27] = 32, + [2][1][RTW89_FCC][29] = 58, + [2][1][RTW89_ETSI][29] = 32, + [2][1][RTW89_MKK][29] = 58, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_KCC][29] = 54, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_CHILE][29] = 42, + [2][1][RTW89_UKRAINE][29] = 32, + [2][1][RTW89_MEXICO][29] = 58, + [2][1][RTW89_CN][29] = 127, + [2][1][RTW89_QATAR][29] = 32, + [2][1][RTW89_UK][29] = 32, + [2][1][RTW89_FCC][31] = 58, + [2][1][RTW89_ETSI][31] = 32, + [2][1][RTW89_MKK][31] = 58, + [2][1][RTW89_IC][31] = 58, + [2][1][RTW89_KCC][31] = 54, + [2][1][RTW89_ACMA][31] = 32, + [2][1][RTW89_CHILE][31] = 42, + [2][1][RTW89_UKRAINE][31] = 32, + [2][1][RTW89_MEXICO][31] = 58, + [2][1][RTW89_CN][31] = 127, + [2][1][RTW89_QATAR][31] = 32, + [2][1][RTW89_UK][31] = 32, + [2][1][RTW89_FCC][33] = 58, + [2][1][RTW89_ETSI][33] = 32, + [2][1][RTW89_MKK][33] = 58, + [2][1][RTW89_IC][33] = 58, + [2][1][RTW89_KCC][33] = 54, + [2][1][RTW89_ACMA][33] = 32, + [2][1][RTW89_CHILE][33] = 42, + [2][1][RTW89_UKRAINE][33] = 32, + [2][1][RTW89_MEXICO][33] = 58, + [2][1][RTW89_CN][33] = 127, + [2][1][RTW89_QATAR][33] = 32, + [2][1][RTW89_UK][33] = 32, + [2][1][RTW89_FCC][35] = 58, + [2][1][RTW89_ETSI][35] = 32, + [2][1][RTW89_MKK][35] = 58, + [2][1][RTW89_IC][35] = 58, + [2][1][RTW89_KCC][35] = 54, + [2][1][RTW89_ACMA][35] = 32, + [2][1][RTW89_CHILE][35] = 42, + [2][1][RTW89_UKRAINE][35] = 32, + [2][1][RTW89_MEXICO][35] = 58, + [2][1][RTW89_CN][35] = 127, + [2][1][RTW89_QATAR][35] = 32, + [2][1][RTW89_UK][35] = 32, + [2][1][RTW89_FCC][37] = 58, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 58, + [2][1][RTW89_IC][37] = 58, + [2][1][RTW89_KCC][37] = 54, + [2][1][RTW89_ACMA][37] = 62, + [2][1][RTW89_CHILE][37] = 42, + [2][1][RTW89_UKRAINE][37] = 127, + [2][1][RTW89_MEXICO][37] = 58, + [2][1][RTW89_CN][37] = 127, + [2][1][RTW89_QATAR][37] = 127, + [2][1][RTW89_UK][37] = 62, + [2][1][RTW89_FCC][38] = 76, + [2][1][RTW89_ETSI][38] = 16, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 76, + [2][1][RTW89_KCC][38] = 54, + [2][1][RTW89_ACMA][38] = 76, + [2][1][RTW89_CHILE][38] = 42, + [2][1][RTW89_UKRAINE][38] = 16, + [2][1][RTW89_MEXICO][38] = 76, + [2][1][RTW89_CN][38] = 64, + [2][1][RTW89_QATAR][38] = 16, + [2][1][RTW89_UK][38] = 32, + [2][1][RTW89_FCC][40] = 76, + [2][1][RTW89_ETSI][40] = 16, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 76, + [2][1][RTW89_KCC][40] = 54, + [2][1][RTW89_ACMA][40] = 76, + [2][1][RTW89_CHILE][40] = 42, + [2][1][RTW89_UKRAINE][40] = 16, + [2][1][RTW89_MEXICO][40] = 76, + [2][1][RTW89_CN][40] = 64, + [2][1][RTW89_QATAR][40] = 16, + [2][1][RTW89_UK][40] = 32, + [2][1][RTW89_FCC][42] = 76, + [2][1][RTW89_ETSI][42] = 16, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 76, + [2][1][RTW89_KCC][42] = 54, + [2][1][RTW89_ACMA][42] = 76, + [2][1][RTW89_CHILE][42] = 42, + [2][1][RTW89_UKRAINE][42] = 16, + [2][1][RTW89_MEXICO][42] = 76, + [2][1][RTW89_CN][42] = 64, + [2][1][RTW89_QATAR][42] = 16, + [2][1][RTW89_UK][42] = 32, + [2][1][RTW89_FCC][44] = 76, + [2][1][RTW89_ETSI][44] = 16, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 76, + [2][1][RTW89_KCC][44] = 54, + [2][1][RTW89_ACMA][44] = 76, + [2][1][RTW89_CHILE][44] = 42, + [2][1][RTW89_UKRAINE][44] = 16, + [2][1][RTW89_MEXICO][44] = 76, + [2][1][RTW89_CN][44] = 64, + [2][1][RTW89_QATAR][44] = 16, + [2][1][RTW89_UK][44] = 32, + [2][1][RTW89_FCC][46] = 76, + [2][1][RTW89_ETSI][46] = 16, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 76, + [2][1][RTW89_KCC][46] = 54, + [2][1][RTW89_ACMA][46] = 76, + [2][1][RTW89_CHILE][46] = 42, + [2][1][RTW89_UKRAINE][46] = 16, + [2][1][RTW89_MEXICO][46] = 76, + [2][1][RTW89_CN][46] = 64, + [2][1][RTW89_QATAR][46] = 16, + [2][1][RTW89_UK][46] = 32, +}; + +const struct rtw89_phy_table rtw89_8852a_phy_bb_table = { + .regs = rtw89_8852a_phy_bb_regs, + .n_regs = ARRAY_SIZE(rtw89_8852a_phy_bb_regs), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852a_phy_radioa_table = { + .regs = rtw89_8852a_phy_radioa_regs, + .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radioa_regs), + .rf_path = RF_PATH_A, +}; + +const struct rtw89_phy_table rtw89_8852a_phy_radiob_table = { + .regs = rtw89_8852a_phy_radiob_regs, + .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radiob_regs), + .rf_path = RF_PATH_B, +}; + +const struct rtw89_phy_table rtw89_8852a_phy_nctl_table = { + .regs = rtw89_8852a_phy_nctl_regs, + .n_regs = ARRAY_SIZE(rtw89_8852a_phy_nctl_regs), + .rf_path = 0, /* don't care */ +}; + +static +const struct rtw89_txpwr_table rtw89_8852a_byr_table = { + .data = rtw89_8852a_txpwr_byrate, + .size = ARRAY_SIZE(rtw89_8852a_txpwr_byrate), + .load = rtw89_phy_load_txpwr_byrate, +}; + +const struct rtw89_fw_txpwr_track_cfg rtw89_8852a_trk_cfg = { + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N] = _txpwr_track_delta_swingidx_5gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P] = _txpwr_track_delta_swingidx_5gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N] = _txpwr_track_delta_swingidx_5ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P] = _txpwr_track_delta_swingidx_5ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N] = &_txpwr_track_delta_swingidx_2gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P] = &_txpwr_track_delta_swingidx_2gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N] = &_txpwr_track_delta_swingidx_2ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P] = &_txpwr_track_delta_swingidx_2ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N] = &_txpwr_track_delta_swingidx_2g_cck_b_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P] = &_txpwr_track_delta_swingidx_2g_cck_b_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N] = &_txpwr_track_delta_swingidx_2g_cck_a_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P] = &_txpwr_track_delta_swingidx_2g_cck_a_p, +}; + +const struct rtw89_rfe_parms rtw89_8852a_dflt_parms = { + .byr_tbl = &rtw89_8852a_byr_table, + .rule_2ghz = { + .lmt = &rtw89_8852a_txpwr_lmt_2g, + .lmt_ru = &rtw89_8852a_txpwr_lmt_ru_2g, + }, + .rule_5ghz = { + .lmt = &rtw89_8852a_txpwr_lmt_5g, + .lmt_ru = &rtw89_8852a_txpwr_lmt_ru_5g, + }, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h new file mode 100644 index 000000000..501a8248d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852A_TABLE_H__ +#define __RTW89_8852A_TABLE_H__ + +#include "core.h" + +extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table; +extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table; +extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table; +extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table; +extern const struct rtw89_fw_txpwr_track_cfg rtw89_8852a_trk_cfg; +extern const struct rtw89_rfe_parms rtw89_8852a_dflt_parms; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c new file mode 100644 index 000000000..3defb0748 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2020-2021 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8852a.h" + +static const struct rtw89_pci_info rtw8852a_pci_info = { + .gen_def = &rtw89_pci_gen_ax, + .isr_def = &rtw89_pci_isr_ax, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_2048B, + .rx_burst = MAC_AX_RX_BURST_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_DISABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .rx_ring_eq_is_full = false, + .check_rx_tag = false, + .no_rxbd_fs = false, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN, + .rxhci_en_bit = B_AX_RXHCI_EN, + .rxbd_mode_bit = B_AX_RXBD_MODE, + .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, + .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2, + .dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO}, + .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK}, + .dma_stop2 = {R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL}, + .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK}, + .dma_busy2_reg = R_AX_PCIE_DMA_BUSY2, + .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, + + .rpwm_addr = R_AX_PCIE_HRPWM, + .cpwm_addr = R_AX_CPWM, + .mit_addr = R_AX_INT_MIT_RX, + .wp_sel_addr = 0, + .tx_dma_ch_mask = 0, + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + .bd_ram_table = &rtw89_bd_ram_table_dual, + + .ltr_set = rtw89_pci_ltr_set, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask, + .enable_intr = rtw89_pci_enable_intr, + .disable_intr = rtw89_pci_disable_intr, + .recognize_intrs = rtw89_pci_recognize_intrs, + + .ssid_quirks = NULL, +}; + +static const struct rtw89_driver_info rtw89_8852ae_info = { + .chip = &rtw8852a_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8852a_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8852ae_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8852), + .driver_data = (kernel_ulong_t)&rtw89_8852ae_info, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xa85a), + .driver_data = (kernel_ulong_t)&rtw89_8852ae_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8852ae_id_table); + +static struct pci_driver rtw89_8852ae_driver = { + .name = "rtw89_8852ae", + .id_table = rtw89_8852ae_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8852ae_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AE driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852au.c b/drivers/net/wireless/realtek/rtw89/rtw8852au.c new file mode 100644 index 000000000..065f4e5b1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852au.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "rtw8852a.h" +#include "reg.h" +#include "usb.h" + +static const struct rtw89_usb_info rtw8852a_usb_info = { + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, + .usb_wlan0_1 = R_AX_USB_WLAN0_1, + .hci_func_en = R_AX_HCI_FUNC_EN, + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, + .rx_agg_alignment = 8, + .bulkout_id = { + [RTW89_DMA_ACH0] = 3, + [RTW89_DMA_ACH2] = 5, + [RTW89_DMA_ACH4] = 4, + [RTW89_DMA_ACH6] = 6, + [RTW89_DMA_B0MG] = 0, + [RTW89_DMA_B0HI] = 0, + [RTW89_DMA_B1MG] = 1, + [RTW89_DMA_B1HI] = 1, + [RTW89_DMA_H2C] = 2, + }, +}; + +static const struct rtw89_driver_info rtw89_8852au_info = { + .chip = &rtw8852a_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .usb = &rtw8852a_usb_info, + } +}; + +static const struct usb_device_id rtw_8852au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0312, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4020, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1997, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8832, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3321, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3323, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0140, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0141, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8852au_id_table); + +static struct usb_driver rtw_8852au_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8852au_id_table, + .probe = rtw89_usb_probe, + .disconnect = rtw89_usb_disconnect, +}; +module_usb_driver(rtw_8852au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AU driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c new file mode 100644 index 000000000..356623341 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -0,0 +1,1100 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "coex.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852b.h" +#include "rtw8852b_common.h" +#include "rtw8852b_rfk.h" +#include "rtw8852b_table.h" +#include "txrx.h" + +#define RTW8852B_FW_FORMAT_MAX 2 +#define RTW8852B_FW_BASENAME "rtw89/rtw8852b_fw" +#define RTW8852B_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8852B_FW_BASENAME, RTW8852B_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = { + {5, 341, grp_0}, /* ACH 0 */ + {5, 341, grp_0}, /* ACH 1 */ + {4, 342, grp_0}, /* ACH 2 */ + {4, 342, grp_0}, /* ACH 3 */ + {0, 0, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {0, 0, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {4, 342, grp_0}, /* B0MGQ */ + {4, 342, grp_0}, /* B0HIQ */ + {0, 0, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_pcie = { + 446, /* Group 0 */ + 0, /* Group 1 */ + 446, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8852b_hfc_chcfg_pcie, &rtw8852b_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_usb[] = { + {18, 210, grp_0}, /* ACH 0 */ + {18, 210, grp_0}, /* ACH 1 */ + {18, 210, grp_0}, /* ACH 2 */ + {18, 210, grp_0}, /* ACH 3 */ + {0, 0, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {0, 0, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {18, 210, grp_0}, /* B0MGQ */ + {18, 210, grp_0}, /* B0HIQ */ + {0, 0, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_usb = { + 210, /* Group 0 */ + 0, /* Group 1 */ + 210, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_prec_cfg rtw8852b_hfc_preccfg_usb = { + 9, /* CH 0-11 pre-cost */ + 32, /* H2C pre-cost */ + 64, /* WP CH 0-7 pre-cost */ + 24, /* WP CH 8-11 pre-cost */ + 1, /* CH 0-11 full condition */ + 1, /* H2C full condition */ + 1, /* WP CH 0-7 full condition */ + 1, /* WP CH 8-11 full condition */ +}; + +static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_usb[] = { + [RTW89_QTA_SCC] = {rtw8852b_hfc_chcfg_usb, &rtw8852b_hfc_pubcfg_usb, + &rtw8852b_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, + &rtw8852b_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size7, + &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7, + &rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18, + &rtw89_mac_size.ple_qt58}, + [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size7, + &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7, + &rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18, + &rtw89_mac_size.ple_qt_52b_wow}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, + &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8852b_dle_mem_usb3[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size30, + &rtw89_mac_size.ple_size31, &rtw89_mac_size.wde_qt30, + &rtw89_mac_size.wde_qt30, &rtw89_mac_size.ple_qt27, + &rtw89_mac_size.ple_qt28}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, + &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const u32 rtw8852b_h2c_regs[RTW89_H2CREG_MAX] = { + R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, + R_AX_H2CREG_DATA3 +}; + +static const u32 rtw8852b_c2h_regs[RTW89_C2HREG_MAX] = { + R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, + R_AX_C2HREG_DATA3 +}; + +static const u32 rtw8852b_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3, +}; + +static const struct rtw89_page_regs rtw8852b_page_regs = { + .hci_fc_ctrl = R_AX_HCI_FC_CTRL, + .ch_page_ctrl = R_AX_CH_PAGE_CTRL, + .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, + .ach_page_info = R_AX_ACH0_PAGE_INFO, + .pub_page_info3 = R_AX_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, + .pub_page_info1 = R_AX_PUB_PAGE_INFO1, + .pub_page_info2 = R_AX_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, + .wp_page_info1 = R_AX_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_def rtw8852b_dcfo_comp = { + R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK +}; + +static const struct rtw89_imr_info rtw8852b_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET, + .wsec_imr_reg = R_AX_SEC_DEBUG, + .wsec_imr_set = B_AX_IMR_ERROR, + .mpdu_tx_imr_set = 0, + .mpdu_rx_imr_set = 0, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, + .wde_imr_clr = B_AX_WDE_IMR_CLR, + .wde_imr_set = B_AX_WDE_IMR_SET, + .ple_imr_clr = B_AX_PLE_IMR_CLR, + .ple_imr_set = B_AX_PLE_IMR_SET, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, + .other_disp_imr_set = 0, + .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, + .bbrpt_err_imr_set = 0, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL, + .ptcl_imr_set = B_AX_PTCL_IMR_SET, + .cdma_imr_0_reg = R_AX_DLE_CTRL, + .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, + .cdma_imr_0_set = B_AX_DLE_IMR_SET, + .cdma_imr_1_reg = 0, + .cdma_imr_1_clr = 0, + .cdma_imr_1_set = 0, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, + .phy_intf_imr_clr = 0, + .phy_intf_imr_set = 0, + .rmac_imr_reg = R_AX_RMAC_ERR_ISR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR, + .rmac_imr_set = B_AX_RMAC_IMR_SET, + .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR, + .tmac_imr_set = B_AX_TMAC_IMR_SET, +}; + +static const struct rtw89_rrsr_cfgs rtw8852b_rrsr_cfgs = { + .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8852b_rfkill_regs = { + .pinmux = {R_AX_GPIO8_15_FUNC_SEL, + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_AX_GPIO_EXT_CTRL + 2, + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8852b_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD_V1, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, + .bmode_pd_reg = R_BMODE_PDTH_EN_V1, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, + .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, + .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, + .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8852b_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL_V1, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_EDCCA_LVL_V1, + .ppdu_mask = B_EDCCA_LVL_MSK3, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, +}; + +static const struct rtw89_pmac_regs rtw8852b_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT, B_SIG_GG_CNT}, + .cck_spoofing = {R_SPOOF_CNT, B_SPOOF_CNT}, + .cck_brk = {}, + .brk = {R_CNT_BRK, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST, B_R1B_RX_RPT_RST}, + .r1b_rr_sel = {R_R1B_RR_SEL, B_R1B_RR_SEL}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = 0, + .eht_crc_ok_mask = 0, + .eht_crc_err_mask = 0, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852b_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852b_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4738), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4688), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4694), +}; + +static const u8 rtw89_btc_8852b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; +static const u8 rtw89_btc_8852b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; + +static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (efuse->rfe_type == 0x5) + rtw89_write16(rtwdev, R_AX_SPS_ANA_ON_CTRL2, RTL8852B_RFE_05_SPS_ANA); +} + +static void rtw8852b_pwr_sps_dig_off(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (efuse->rfe_type == 0x5) { + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C1_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C2_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C3_L1_MASK, 0x2); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_R1_L1_MASK, 0x1); + } else { + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C1_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C3_L1_MASK, 0x3); + } +} + +static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + rtw8852b_pwr_sps_ana(rtwdev); + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | + B_AX_AFSM_PCIE_SUS_EN); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_AFE_LDO_CTRL, B_AX_AON_OFF_PC_EN); + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_AON_OFF_PC_EN, + 1000, 20000, false, rtwdev, R_AX_AFE_LDO_CTRL); + if (ret) + return ret; + + rtw8852b_pwr_sps_dig_off(rtwdev); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); + + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, + XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, + XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, + XTAL_SI_PON_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, + XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + + fsleep(1000); + + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + + if (!rtwdev->efuse.valid || rtwdev->efuse.power_k_valid) + goto func_en; + + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VOL_L1_MASK, 0x9); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VREFPFM_L_MASK, 0xA); + + if (rtwdev->hal.cv == CHIP_CBV && rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write16_mask(rtwdev, R_AX_HCI_LDO_CTRL, B_AX_R_AX_VADJ_MASK, 0xA); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + } + +func_en: + rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | + B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | + B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | + B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | + B_AX_DMACREG_GCKEN); + rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, + B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | + B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | + B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN | + B_AX_RMAC_EN); + + rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_MASK, + PINMUX_EESK_FUNC_SEL_BT_LOG); + + return 0; +} + +static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + rtw8852b_pwr_sps_ana(rtwdev); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, + XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, + XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR); + + rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x3); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + } else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) { + val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL); + val32 &= ~B_AX_AFSM_PCIE_SUS_EN; + val32 |= B_AX_AFSM_WLSUS_EN; + rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32); + } + + return 0; +} + +static void rtw8852b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + enum rtw89_phy_idx phy_idx, bool en) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + if (band == RTW89_BAND_2G) + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + } +} + +static void rtw8852b_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); + rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); + rtw8852bx_bb_reset_all(rtwdev, phy_idx); + rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); + rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); + rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); +} + +static void rtw8852b_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_set_channel_mac(rtwdev, chan, mac_idx); + rtw8852bx_set_channel_bb(rtwdev, chan, phy_idx); + rtw8852b_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void rtw8852b_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + static const u32 tssi_trk[2] = {R_P0_TSSI_TRK, R_P1_TSSI_TRK}; + static const u32 ctrl_bbrst[2] = {R_P0_TXPW_RSTB, R_P1_TXPW_RSTB}; + + if (en) { + rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], B_P0_TXPW_RSTB_MANON, 0x0); + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], B_P0_TXPW_RSTB_MANON, 0x1); + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x1); + } +} + +static void rtw8852b_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, + u8 phy_idx) +{ + if (!rtwdev->dbcc_en) { + rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_A); + rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_B); + } else { + if (phy_idx == RTW89_PHY_0) + rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_A); + else + rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_B); + } +} + +static void rtw8852b_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf); +} + +static void rtw8852b_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw8852b_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); + rtw8852b_adc_en(rtwdev, false); + fsleep(40); + rtw8852b_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + rtw8852b_adc_en(rtwdev, true); + rtw8852b_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); + rtw8852b_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); + } +} + +static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + memset(rfk_mcc, 0, sizeof(*rfk_mcc)); + + rtw8852b_dpk_init(rtwdev); + rtw8852b_rck(rtwdev); + rtw8852b_dack(rtwdev, RTW89_CHANCTX_0); + rtw8852b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); +} + +static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + + rtw8852b_mcc_get_ch_info(rtwdev, phy_idx); + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + + rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx); + rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852b_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); + rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); +} + +static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8852b_tssi_scan(rtwdev, phy_idx, chan); +} + +static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); +} + +static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8852b_dpk_track(rtwdev); +} + +static void rtw8852b_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->bt_solo = 0; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + + if (md->rfe_type > 0) + md->ant.num = (md->rfe_type % 2 ? 2 : 3); + else + md->ant.num = 2; + + md->ant.diversity = 0; + md->ant.isolation = 10; + + if (md->ant.num == 3) { + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + } else { + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + } + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +union rtw8852b_btc_wl_txpwr_ctrl { + u32 txpwr_val; + struct { + union { + u16 ctrl_all_time; + struct { + s16 data:9; + u16 rsvd:6; + u16 flag:1; + } all_time; + }; + union { + u16 ctrl_gnt_bt; + struct { + s16 data:9; + u16 rsvd:7; + } gnt_bt; + }; + }; +} __packed; + +static void +rtw8852b_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + union rtw8852b_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; + s32 val; + +#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ +do { \ + u32 _wrt = FIELD_PREP(_msk, _val); \ + BUILD_BUG_ON(!!(_msk & _en)); \ + if (_cond) \ + _wrt |= _en; \ + else \ + _wrt &= ~_en; \ + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ + _msk | _en, _wrt); \ +} while (0) + + switch (arg.ctrl_all_time) { + case 0xffff: + val = 0; + break; + default: + val = arg.all_time.data; + break; + } + + __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, + val, B_AX_FORCE_PWR_BY_RATE_EN, + arg.ctrl_all_time != 0xffff); + + switch (arg.ctrl_gnt_bt) { + case 0xffff: + val = 0; + break; + default: + val = arg.gnt_bt.data; + break; + } + + __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, + B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); + +#undef __write_ctrl +} + +static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852bx_mac_enable_bb_rf, + .disable_bb_rf = rtw8852bx_mac_disable_bb_rf, + .bb_preinit = NULL, + .bb_postinit = NULL, + .bb_reset = rtw8852b_bb_reset, + .bb_sethw = rtw8852bx_bb_sethw, + .read_rf = rtw89_phy_read_rf_v1, + .write_rf = rtw89_phy_write_rf_v1, + .set_channel = rtw8852b_set_channel, + .set_channel_help = rtw8852b_set_channel_help, + .read_efuse = rtw8852bx_read_efuse, + .read_phycap = rtw8852bx_read_phycap, + .fem_setup = NULL, + .data_setup = NULL, + .rfe_gpio = NULL, + .rfk_hw_init = NULL, + .rfk_init = rtw8852b_rfk_init, + .rfk_init_late = NULL, + .rfk_channel = rtw8852b_rfk_channel, + .rfk_band_changed = rtw8852b_rfk_band_changed, + .rfk_scan = rtw8852b_rfk_scan, + .rfk_track = rtw8852b_rfk_track, + .power_trim = rtw8852bx_power_trim, + .set_txpwr = rtw8852bx_set_txpwr, + .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852bx_init_txpwr_unit, + .get_thermal = rtw8852bx_get_thermal, + .chan_to_rf18_val = NULL, + .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx, + .query_ppdu = rtw8852bx_query_ppdu, + .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi, + .phy_rpt_to_rssi = NULL, + .ctrl_nbtg_bt_tx = rtw8852bx_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset, + .digital_pwr_comp = NULL, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc, + .fill_txdesc = rtw89_core_fill_txdesc, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, + .get_ch_dma = {rtw89_core_get_ch_dma, + rtw89_core_get_ch_dma, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, + .mac_cfg_gnt = rtw89_mac_cfg_gnt, + .stop_sch_tx = rtw89_mac_stop_sch_tx, + .resume_sch_tx = rtw89_mac_resume_sch_tx, + .h2c_dctl_sec_cam = NULL, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl, + .h2c_ampdu_cmac_tbl = NULL, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl, + .h2c_punctured_cmac_tbl = NULL, + .h2c_default_dmac_tbl = NULL, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8852b_btc_set_rfe, + .btc_init_cfg = rtw8852bx_btc_init_cfg, + .btc_set_wl_pri = rtw8852bx_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8852b_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8852bx_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8852bx_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852bx_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8852bx_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +static const struct rtw89_chanctx_listener rtw8852b_chanctx_listener = { + .callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852b_rfk_chanctx_cb, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8852b = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, +}; +#endif + +const struct rtw89_chip_info rtw8852b_chip_info = { + .chip_id = RTL8852B, + .chip_gen = RTW89_CHIP_AX, + .ops = &rtw8852b_chip_ops, + .mac_def = &rtw89_mac_gen_ax, + .phy_def = &rtw89_phy_gen_ax, + .fw_def = { + .fw_basename = RTW8852B_FW_BASENAME, + .fw_format_max = RTW8852B_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = true, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ | + BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION), + .fw_blacklist = &rtw89_fw_blacklist_default, + .fifo_size = 196608, + .small_fifo_size = true, + .dle_scc_rsvd_size = 98304, + .max_amsdu_limit = 5000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = true, + .rsvd_ple_ofst = 0x2f800, + .qta_def = { + .hfc_param_ini = {rtw8852b_hfc_param_ini_pcie, + rtw8852b_hfc_param_ini_usb, + rtw8852b_hfc_param_ini_usb, + NULL}, + .dle_mem = {rtw8852b_dle_mem_pcie, + rtw8852b_dle_mem_usb3, + rtw8852b_dle_mem_usb3, + NULL}, + }, + .wde_qempty_acq_grpnum = 4, + .wde_qempty_mgq_grpsel = 4, + .rf_base_addr = {0xe000, 0xf000}, + .thermal_th = {0x32, 0x35}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = &rtw89_8852b_phy_bb_table, + .bb_gain_table = &rtw89_8852b_phy_bb_gain_table, + .rf_table = {&rtw89_8852b_phy_radioa_table, + &rtw89_8852b_phy_radiob_table,}, + .nctl_table = &rtw89_8852b_phy_nctl_table, + .nctl_post_table = NULL, + .dflt_parms = &rtw89_8852b_dflt_parms, + .rfe_parms_conf = NULL, + .chanctx_listener = &rtw8852b_chanctx_listener, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8852b_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = RTW89_MAX_MAC_ID_NUM, + .support_link_num = 0, + .support_chanctx_num = 2, + .support_rnr = false, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), + .support_unii4 = true, + .support_ant_gain = true, + .support_tas = false, + .support_sar_by_ant = true, + .support_noise = false, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = true, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = true, + .hw_sec_hdr = false, + .hw_mgmt_tx_encrypt = false, + .hw_tkip_crypto = false, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 10, + .scam_num = 128, + .bacam_num = 2, + .bacam_dynamic_num = 4, + .bacam_ver = RTW89_BACAM_V0, + .addrcam_ver = 0, + .ppdu_max_usr = 4, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, + .limit_efuse_size = 1280, + .dav_phy_efuse_size = 96, + .dav_log_efuse_size = 16, + .efuse_blocks = NULL, + .phycap_addr = 0x580, + .phycap_size = 128, + .para_ver = 0, + .wlcx_desired = 0x05050000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852b_mon_reg), + .mon_reg = rtw89_btc_8852b_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8852b_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8852b_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852b_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852b_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, + .hci_func_en_addr = R_AX_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_txwd_body), + .txwd_body_size = sizeof(struct rtw89_txwd_body), + .txwd_info_size = sizeof(struct rtw89_txwd_info), + .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8852b_h2c_regs, + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8852b_c2h_regs, + .page_regs = &rtw8852b_page_regs, + .wow_reason_reg = rtw8852b_wow_wakeup_regs, + .cfo_src_fd = true, + .cfo_hw_comp = true, + .dcfo_comp = &rtw8852b_dcfo_comp, + .dcfo_comp_sft = 10, + .nhm_report = NULL, + .nhm_th = NULL, + .imr_info = &rtw8852b_imr_info, + .imr_dmac_table = NULL, + .imr_cmac_table = NULL, + .rrsr_cfgs = &rtw8852b_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0}, + .bss_clr_map_reg = R_BSS_CLR_MAP_V1, + .rfkill_init = &rtw8852b_rfkill_regs, + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, + .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | + BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | + BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), + .edcca_regs = &rtw8852b_edcca_regs, + .pmac_regs = &rtw8852b_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852b, +#endif + .xtal_info = NULL, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8852b_chip_info); + +MODULE_FIRMWARE(RTW8852B_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852B driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h new file mode 100644 index 000000000..5ec7180fd --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852B_H__ +#define __RTW89_8852B_H__ + +#include "core.h" + +#define RF_PATH_NUM_8852B 2 +#define BB_PATH_NUM_8852B 2 + +extern const struct rtw89_chip_info rtw8852b_chip_info; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c new file mode 100644 index 000000000..7c68260dc --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c @@ -0,0 +1,2101 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "coex.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852b_common.h" +#include "sar.h" +#include "util.h" + +static const struct rtw89_reg3_def rtw8852bx_pmac_ht20_mcs7_tbl[] = { + {0x4580, 0x0000ffff, 0x0}, + {0x4580, 0xffff0000, 0x0}, + {0x4584, 0x0000ffff, 0x0}, + {0x4584, 0xffff0000, 0x0}, + {0x4580, 0x0000ffff, 0x1}, + {0x4578, 0x00ffffff, 0x2018b}, + {0x4570, 0x03ffffff, 0x7}, + {0x4574, 0x03ffffff, 0x32407}, + {0x45b8, 0x00000010, 0x0}, + {0x45b8, 0x00000100, 0x0}, + {0x45b8, 0x00000080, 0x0}, + {0x45b8, 0x00000008, 0x0}, + {0x45a0, 0x0000ff00, 0x0}, + {0x45a0, 0xff000000, 0x1}, + {0x45a4, 0x0000ff00, 0x2}, + {0x45a4, 0xff000000, 0x3}, + {0x45b8, 0x00000020, 0x0}, + {0x4568, 0xe0000000, 0x0}, + {0x45b8, 0x00000002, 0x1}, + {0x456c, 0xe0000000, 0x0}, + {0x45b4, 0x00006000, 0x0}, + {0x45b4, 0x00001800, 0x1}, + {0x45b8, 0x00000040, 0x0}, + {0x45b8, 0x00000004, 0x0}, + {0x45b8, 0x00000200, 0x0}, + {0x4598, 0xf8000000, 0x0}, + {0x45b8, 0x00100000, 0x0}, + {0x45a8, 0x00000fc0, 0x0}, + {0x45b8, 0x00200000, 0x0}, + {0x45b0, 0x00000038, 0x0}, + {0x45b0, 0x000001c0, 0x0}, + {0x45a0, 0x000000ff, 0x0}, + {0x45b8, 0x00400000, 0x0}, + {0x4590, 0x000007ff, 0x0}, + {0x45b0, 0x00000e00, 0x0}, + {0x45ac, 0x0000001f, 0x0}, + {0x45b8, 0x00800000, 0x0}, + {0x45a8, 0x0003f000, 0x0}, + {0x45b8, 0x01000000, 0x0}, + {0x45b0, 0x00007000, 0x0}, + {0x45b0, 0x00038000, 0x0}, + {0x45a0, 0x00ff0000, 0x0}, + {0x45b8, 0x02000000, 0x0}, + {0x4590, 0x003ff800, 0x0}, + {0x45b0, 0x001c0000, 0x0}, + {0x45ac, 0x000003e0, 0x0}, + {0x45b8, 0x04000000, 0x0}, + {0x45a8, 0x00fc0000, 0x0}, + {0x45b8, 0x08000000, 0x0}, + {0x45b0, 0x00e00000, 0x0}, + {0x45b0, 0x07000000, 0x0}, + {0x45a4, 0x000000ff, 0x0}, + {0x45b8, 0x10000000, 0x0}, + {0x4594, 0x000007ff, 0x0}, + {0x45b0, 0x38000000, 0x0}, + {0x45ac, 0x00007c00, 0x0}, + {0x45b8, 0x20000000, 0x0}, + {0x45a8, 0x3f000000, 0x0}, + {0x45b8, 0x40000000, 0x0}, + {0x45b4, 0x00000007, 0x0}, + {0x45b4, 0x00000038, 0x0}, + {0x45a4, 0x00ff0000, 0x0}, + {0x45b8, 0x80000000, 0x0}, + {0x4594, 0x003ff800, 0x0}, + {0x45b4, 0x000001c0, 0x0}, + {0x4598, 0xf8000000, 0x0}, + {0x45b8, 0x00100000, 0x0}, + {0x45a8, 0x00000fc0, 0x7}, + {0x45b8, 0x00200000, 0x0}, + {0x45b0, 0x00000038, 0x0}, + {0x45b0, 0x000001c0, 0x0}, + {0x45a0, 0x000000ff, 0x0}, + {0x45b4, 0x06000000, 0x0}, + {0x45b0, 0x00000007, 0x0}, + {0x45b8, 0x00080000, 0x0}, + {0x45a8, 0x0000003f, 0x0}, + {0x457c, 0xffe00000, 0x1}, + {0x4530, 0xffffffff, 0x0}, + {0x4588, 0x00003fff, 0x0}, + {0x4598, 0x000001ff, 0x0}, + {0x4534, 0xffffffff, 0x0}, + {0x4538, 0xffffffff, 0x0}, + {0x453c, 0xffffffff, 0x0}, + {0x4588, 0x0fffc000, 0x0}, + {0x4598, 0x0003fe00, 0x0}, + {0x4540, 0xffffffff, 0x0}, + {0x4544, 0xffffffff, 0x0}, + {0x4548, 0xffffffff, 0x0}, + {0x458c, 0x00003fff, 0x0}, + {0x4598, 0x07fc0000, 0x0}, + {0x454c, 0xffffffff, 0x0}, + {0x4550, 0xffffffff, 0x0}, + {0x4554, 0xffffffff, 0x0}, + {0x458c, 0x0fffc000, 0x0}, + {0x459c, 0x000001ff, 0x0}, + {0x4558, 0xffffffff, 0x0}, + {0x455c, 0xffffffff, 0x0}, + {0x4530, 0xffffffff, 0x4e790001}, + {0x4588, 0x00003fff, 0x0}, + {0x4598, 0x000001ff, 0x1}, + {0x4534, 0xffffffff, 0x0}, + {0x4538, 0xffffffff, 0x4b}, + {0x45ac, 0x38000000, 0x7}, + {0x4588, 0xf0000000, 0x0}, + {0x459c, 0x7e000000, 0x0}, + {0x45b8, 0x00040000, 0x0}, + {0x45b8, 0x00020000, 0x0}, + {0x4590, 0xffc00000, 0x0}, + {0x45b8, 0x00004000, 0x0}, + {0x4578, 0xff000000, 0x0}, + {0x45b8, 0x00000400, 0x0}, + {0x45b8, 0x00000800, 0x0}, + {0x45b8, 0x00001000, 0x0}, + {0x45b8, 0x00002000, 0x0}, + {0x45b4, 0x00018000, 0x0}, + {0x45ac, 0x07800000, 0x0}, + {0x45b4, 0x00000600, 0x2}, + {0x459c, 0x0001fe00, 0x80}, + {0x45ac, 0x00078000, 0x3}, + {0x459c, 0x01fe0000, 0x1}, +}; + +static const struct rtw89_reg3_def rtw8852bx_btc_preagc_en_defs[] = { + {0x46D0, GENMASK(1, 0), 0x3}, + {0x4790, GENMASK(1, 0), 0x3}, + {0x4AD4, GENMASK(31, 0), 0xf}, + {0x4AE0, GENMASK(31, 0), 0xf}, + {0x4688, GENMASK(31, 24), 0x80}, + {0x476C, GENMASK(31, 24), 0x80}, + {0x4694, GENMASK(7, 0), 0x80}, + {0x4694, GENMASK(15, 8), 0x80}, + {0x4778, GENMASK(7, 0), 0x80}, + {0x4778, GENMASK(15, 8), 0x80}, + {0x4AE4, GENMASK(23, 0), 0x780D1E}, + {0x4AEC, GENMASK(23, 0), 0x780D1E}, + {0x469C, GENMASK(31, 26), 0x34}, + {0x49F0, GENMASK(31, 26), 0x34}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8852bx_btc_preagc_en_defs); + +static const struct rtw89_reg3_def rtw8852bx_btc_preagc_dis_defs[] = { + {0x46D0, GENMASK(1, 0), 0x0}, + {0x4790, GENMASK(1, 0), 0x0}, + {0x4AD4, GENMASK(31, 0), 0x60}, + {0x4AE0, GENMASK(31, 0), 0x60}, + {0x4688, GENMASK(31, 24), 0x1a}, + {0x476C, GENMASK(31, 24), 0x1a}, + {0x4694, GENMASK(7, 0), 0x2a}, + {0x4694, GENMASK(15, 8), 0x2a}, + {0x4778, GENMASK(7, 0), 0x2a}, + {0x4778, GENMASK(15, 8), 0x2a}, + {0x4AE4, GENMASK(23, 0), 0x79E99E}, + {0x4AEC, GENMASK(23, 0), 0x79E99E}, + {0x469C, GENMASK(31, 26), 0x26}, + {0x49F0, GENMASK(31, 26), 0x26}, +}; + +static DECLARE_PHY_REG3_TBL(rtw8852bx_btc_preagc_dis_defs); + +static void rtw8852bx_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8852bx_efuse *map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + struct rtw8852bx_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + tssi->thermal[RF_PATH_B] = map->path_b_therm; + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, + sizeof(ofst[i]->cck_tssi)); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + sizeof(ofst[i]->bw40_tssi)); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + } +} + +static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) +{ + if (high) + *high = FIELD_GET_SIGNED(GENMASK(7, 4), data); + if (low) + *low = FIELD_GET_SIGNED(GENMASK(3, 0), data); + + return data != 0xff; +} + +static void rtw8852bx_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8852bx_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + bool valid = false; + + valid |= _decode_efuse_gain(map->rx_gain_2g_cck, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]); + valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]); + valid |= _decode_efuse_gain(map->rx_gain_5g_low, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]); + valid |= _decode_efuse_gain(map->rx_gain_5g_mid, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]); + valid |= _decode_efuse_gain(map->rx_gain_5g_high, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]); + + gain->offset_valid = valid; +} + +static int __rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw8852bx_efuse *map; + + map = (struct rtw8852bx_efuse *)log_map; + + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + rtw8852bx_efuse_parsing_tssi(rtwdev, map); + rtw8852bx_efuse_parsing_gain_offset(rtwdev, map); + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; + case RTW89_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + break; + default: + return -EOPNOTSUPP; + } + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + + return 0; +} + +static void rtw8852bx_phycap_parsing_power_cal(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ +#define PWR_K_CHK_OFFSET 0x5E9 +#define PWR_K_CHK_VALUE 0xAA + u32 offset = PWR_K_CHK_OFFSET - rtwdev->chip->phycap_addr; + + if (phycap_map[offset] == PWR_K_CHK_VALUE) + rtwdev->efuse.power_k_valid = true; +} + +static void rtw8852bx_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + static const u32 tssi_trim_addr[RF_PATH_NUM_8852BX] = {0x5D6, 0x5AB}; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = false; + u32 ofst; + u8 i, j; + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { + /* addrs are in decreasing order */ + ofst = tssi_trim_addr[i] - addr - j; + tssi->tssi_trim[i][j] = phycap_map[ofst]; + + if (phycap_map[ofst] != 0xff) + pg = true; + } + } + + if (!pg) { + memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM] no PG, set all trim info to 0\n"); + } + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", + i, j, tssi->tssi_trim[i][j], + tssi_trim_addr[i] - j); +} + +static void rtw8852bx_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 thm_trim_addr[RF_PATH_NUM_8852BX] = {0x5DF, 0x5DC}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", + i, info->thermal_trim[i]); + + if (info->thermal_trim[i] != 0xff) + info->pg_thermal_trim = true; + } +} + +static void rtw8852bx_thermal_trim(struct rtw89_dev *rtwdev) +{ +#define __thm_setting(raw) \ +({ \ + u8 __v = (raw); \ + ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ +}) + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 i, val; + + if (!info->pg_thermal_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + val = __thm_setting(info->thermal_trim[i]); + rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", + i, val); + } +#undef __thm_setting +} + +static void rtw8852bx_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 pabias_trim_addr[RF_PATH_NUM_8852BX] = {0x5DE, 0x5DB}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + + if (info->pa_bias_trim[i] != 0xff) + info->pg_pa_bias_trim = true; + } +} + +static void rtw8852bx_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); + pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); + } +} + +static void rtw8852bx_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = { + {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8}, + {0x590, 0x58F, 0, 0x58E, 0x58D}, + }; + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + u32 phycap_addr = rtwdev->chip->phycap_addr; + bool valid = false; + int path, i; + u8 data; + + for (path = 0; path < 2; path++) + for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) { + if (comp_addrs[path][i] == 0) + continue; + + data = phycap_map[comp_addrs[path][i] - phycap_addr]; + valid |= _decode_efuse_gain(data, NULL, + &gain->comp[path][i]); + } + + gain->comp_valid = valid; +} + +static int __rtw8852bx_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8852bx_phycap_parsing_power_cal(rtwdev, phycap_map); + rtw8852bx_phycap_parsing_tssi(rtwdev, phycap_map); + rtw8852bx_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8852bx_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + rtw8852bx_phycap_parsing_gain_comp(rtwdev, phycap_map); + + return 0; +} + +static void __rtw8852bx_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8852bx_thermal_trim(rtwdev); + rtw8852bx_pa_bias_trim(rtwdev); +} + +static void __rtw8852bx_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx); + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx); + u8 txsc20 = 0, txsc40 = 0; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_80: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); + rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); + rtw89_write32(rtwdev, sub_carr, txsc20); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); + rtw89_write32(rtwdev, sub_carr, 0); + break; + default: + break; + } + + if (chan->channel > 14) { + rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE); + rtw89_write8_set(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); + } else { + rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE); + rtw89_write8_clr(rtwdev, chk_rate, + B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); + } +} + +static const u32 rtw8852bx_sco_barker_threshold[14] = { + 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, + 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 +}; + +static const u32 rtw8852bx_sco_cck_threshold[14] = { + 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, + 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed +}; + +static void rtw8852bx_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch) +{ + u8 ch_element = primary_ch - 1; + + rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, + rtw8852bx_sco_barker_threshold[ch_element]); + rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, + rtw8852bx_sco_cck_threshold[ch_element]); +} + +static u8 rtw8852bx_sco_mapping(u8 central_ch) +{ + if (central_ch == 1) + return 109; + else if (central_ch >= 2 && central_ch <= 6) + return 108; + else if (central_ch >= 7 && central_ch <= 10) + return 107; + else if (central_ch >= 11 && central_ch <= 14) + return 106; + else if (central_ch == 36 || central_ch == 38) + return 51; + else if (central_ch >= 40 && central_ch <= 58) + return 50; + else if (central_ch >= 60 && central_ch <= 64) + return 49; + else if (central_ch == 100 || central_ch == 102) + return 48; + else if (central_ch >= 104 && central_ch <= 126) + return 47; + else if (central_ch >= 128 && central_ch <= 151) + return 46; + else if (central_ch >= 153 && central_ch <= 177) + return 45; + else + return 0; +} + +struct rtw8852bx_bb_gain { + u32 gain_g[BB_PATH_NUM_8852BX]; + u32 gain_a[BB_PATH_NUM_8852BX]; + u32 gain_mask; +}; + +static const struct rtw8852bx_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x000000ff }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x0000ff00 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x000000ff }, +}; + +static const struct rtw8852bx_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0xff000000 }, +}; + +static void rtw8852bx_set_gain_error(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_rf_path path) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 gain_band = rtw89_subband_to_bb_gain_band(subband); + s32 val; + u32 reg; + u32 mask; + int i; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_lna[i].gain_g[path]; + else + reg = bb_gain_lna[i].gain_a[path]; + + mask = bb_gain_lna[i].gain_mask; + val = gain->lna_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_tia[i].gain_g[path]; + else + reg = bb_gain_tia[i].gain_a[path]; + + mask = bb_gain_tia[i].gain_mask; + val = gain->tia_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } +} + +static void rtw8852bt_ext_loss_avg_update(struct rtw89_dev *rtwdev, + s8 ext_loss_a, s8 ext_loss_b) +{ + s8 ext_loss_avg; + u64 linear; + u8 pwrofst; + + if (ext_loss_a == ext_loss_b) { + ext_loss_avg = ext_loss_a; + } else { + linear = rtw89_db_to_linear(abs(ext_loss_a - ext_loss_b)) + 1; + linear /= 2; + ext_loss_avg = rtw89_linear_to_db(linear); + ext_loss_avg += min(ext_loss_a, ext_loss_b); + } + + pwrofst = max(DIV_ROUND_CLOSEST(ext_loss_avg, 4) + 16, EDCCA_PWROFST_DEFAULT); + + rtw89_phy_write32_mask(rtwdev, R_PWOFST, B_PWOFST, pwrofst); +} + +static void rtw8852bx_set_gain_offset(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_phy_idx phy_idx) +{ + static const u32 gain_err_addr[2] = {R_P0_AGC_RSVD, R_P1_AGC_RSVD}; + static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1, + R_PATH1_G_TIA1_LNA6_OP1DB_V1}; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset gain_ofdm_band; + s8 ext_loss_a = 0, ext_loss_b = 0; + s32 offset_a, offset_b; + s32 offset_ofdm, offset_cck; + s32 tmp; + u8 path; + + if (!efuse_gain->comp_valid) + goto next; + + for (path = RF_PATH_A; path < BB_PATH_NUM_8852BX; path++) { + tmp = efuse_gain->comp[path][subband]; + tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp); + } + +next: + if (!efuse_gain->offset_valid) + goto ext_loss; + + gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband); + + offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; + offset_b = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band]; + + tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp); + + tmp = -((offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_B], B_PATH0_R_G_OFST_MASK, tmp); + + if (hal->antenna_rx == RF_B) { + offset_ofdm = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band]; + offset_cck = -efuse_gain->offset[RF_PATH_B][0]; + } else { + offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; + offset_cck = -efuse_gain->offset[RF_PATH_A][0]; + } + + tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0]; + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); + + tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0]; + tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); + + if (subband == RTW89_CH_2G) { + tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1); + tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1); + rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST, + B_RX_RPL_OFST_CCK_MASK, tmp); + } + + ext_loss_a = (offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2); + ext_loss_b = (offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2); + +ext_loss: + if (rtwdev->chip->chip_id == RTL8852BT) + rtw8852bt_ext_loss_avg_update(rtwdev, ext_loss_a, ext_loss_b); +} + +static +void rtw8852bx_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 band = rtw89_subband_to_bb_gain_band(subband); + u32 val; + + val = u32_encode_bits((gain->rpl_ofst_20[band][RF_PATH_A] + + gain->rpl_ofst_20[band][RF_PATH_B]) >> 1, B_P0_RPL1_20_MASK) | + u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][0] + + gain->rpl_ofst_40[band][RF_PATH_B][0]) >> 1, B_P0_RPL1_40_MASK) | + u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][1] + + gain->rpl_ofst_40[band][RF_PATH_B][1]) >> 1, B_P0_RPL1_41_MASK); + val >>= B_P0_RPL1_SHIFT; + rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val); + rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val); + + val = u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][2] + + gain->rpl_ofst_40[band][RF_PATH_B][2]) >> 1, B_P0_RTL2_42_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][0] + + gain->rpl_ofst_80[band][RF_PATH_B][0]) >> 1, B_P0_RTL2_80_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][1] + + gain->rpl_ofst_80[band][RF_PATH_B][1]) >> 1, B_P0_RTL2_81_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][10] + + gain->rpl_ofst_80[band][RF_PATH_B][10]) >> 1, B_P0_RTL2_8A_MASK); + rtw89_phy_write32(rtwdev, R_P0_RPL2, val); + rtw89_phy_write32(rtwdev, R_P1_RPL2, val); + + val = u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][2] + + gain->rpl_ofst_80[band][RF_PATH_B][2]) >> 1, B_P0_RTL3_82_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][3] + + gain->rpl_ofst_80[band][RF_PATH_B][3]) >> 1, B_P0_RTL3_83_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][4] + + gain->rpl_ofst_80[band][RF_PATH_B][4]) >> 1, B_P0_RTL3_84_MASK) | + u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][9] + + gain->rpl_ofst_80[band][RF_PATH_B][9]) >> 1, B_P0_RTL3_89_MASK); + rtw89_phy_write32(rtwdev, R_P0_RPL3, val); + rtw89_phy_write32(rtwdev, R_P1_RPL3, val); +} + +static void rtw8852bx_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 central_ch = chan->channel; + u8 subband = chan->subband_type; + u8 sco_comp; + bool is_2g = central_ch <= 14; + + /* Path A */ + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx); + + /* Path B */ + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, 0, phy_idx); + + /* SCO compensate FC setting */ + sco_comp = rtw8852bx_sco_mapping(central_ch); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx); + + if (chan->band_type == RTW89_BAND_6G) + return; + + /* CCK parameters */ + if (central_ch == 14) { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff); + rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354); + rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); + rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053); + rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a); + rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92); + rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc); + rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5); + } + + rtw8852bx_set_gain_error(rtwdev, subband, RF_PATH_A); + rtw8852bx_set_gain_error(rtwdev, subband, RF_PATH_B); + rtw8852bx_set_gain_offset(rtwdev, subband, phy_idx); + rtw8852bx_set_rxsc_rpl_comp(rtwdev, subband); +} + +static void rtw8852b_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + static const u32 adc_sel[2] = {0xC0EC, 0xC1EC}; + static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4}; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + } +} + +static +void rtw8852bt_adc_cfg(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + static const u32 rck_reset_count[2] = {0xC0E8, 0xC1E8}; + static const u32 adc_op5_bw_sel[2] = {0xC0D8, 0xC1D8}; + static const u32 adc_sample_td[2] = {0xC0D4, 0xC1D4}; + static const u32 adc_rst_cycle[2] = {0xC0EC, 0xC1EC}; + static const u32 decim_filter[2] = {0xC0EC, 0xC1EC}; + static const u32 rck_offset[2] = {0xC0C4, 0xC1C4}; + static const u32 rx_adc_clk[2] = {0x12A0, 0x32A0}; + static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4}; + static const u32 idac2_1[2] = {0xC0D4, 0xC1D4}; + static const u32 idac2[2] = {0xC0D4, 0xC1D4}; + static const u32 upd_clk_adc = {0x704}; + + if (rtwdev->chip->chip_id != RTL8852BT) + return; + + rtw89_phy_write32_mask(rtwdev, idac2[path], B_P0_CFCH_CTL, 0x8); + rtw89_phy_write32_mask(rtwdev, rck_reset_count[path], B_ADCMOD_LP, 0x9); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], B_WDADC_SEL, 0x2); + rtw89_phy_write32_mask(rtwdev, rx_adc_clk[path], B_P0_RXCK_ADJ, 0x49); + rtw89_phy_write32_mask(rtwdev, decim_filter[path], B_DCIM_FR, 0x0); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0xf); + rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x0); + /* Tx TSSI ADC update */ + rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 0); + + if (rtwdev->efuse.rfe_type >= 51) + rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x2); + else + rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x2); + rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0x8); + rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x0); + rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3); + /* Tx TSSI ADC update */ + rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 1); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0x4); + rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x6); + rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3); + /* Tx TSSI ADC update */ + rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 2); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + break; + } +} + +static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 rx_path_0; + + rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, phy_idx); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + + /*Set RF mode at 3 */ + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + if (chip_id == RTL8852BT) { + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_NRBW_EN_V1, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_NRBW_EN_V1, 0x0, phy_idx); + } + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + + /*Set RF mode at 3 */ + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + if (chip_id == RTL8852BT) { + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_NRBW_EN_V1, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_NRBW_EN_V1, 0x0, phy_idx); + } + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); + + /*Set RF mode at 3 */ + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + if (chip_id == RTL8852BT) { + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_NRBW_EN_V1, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_NRBW_EN_V1, 0x1, phy_idx); + } + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, + pri_ch, phy_idx); + + /*Set RF mode at 3 */ + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + /*CCK primary channel */ + if (pri_ch == RTW89_SC_20_UPPER) + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); + + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, + pri_ch, phy_idx); + + /*Set RF mode at 3 */ + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, + pri_ch); + } + + if (chip_id == RTL8852B) { + rtw8852b_bw_setting(rtwdev, bw, RF_PATH_A); + rtw8852b_bw_setting(rtwdev, bw, RF_PATH_B); + } else if (chip_id == RTL8852BT) { + rtw8852bt_adc_cfg(rtwdev, bw, RF_PATH_A); + rtw8852bt_adc_cfg(rtwdev, bw, RF_PATH_B); + } + + if (rx_path_0 == 0x1) + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, + B_P1_RFMODE_ORI_RX_ALL, 0x111, phy_idx); + else if (rx_path_0 == 0x2) + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, + B_P0_RFMODE_ORI_RX_ALL, 0x111, phy_idx); +} + +static void rtw8852bx_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en) +{ + if (cck_en) { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); + } else { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); + } +} + +static void rtw8852bx_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 pri_ch = chan->pri_ch_idx; + bool mask_5m_low; + bool mask_5m_en; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_40: + /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */ + mask_5m_en = true; + mask_5m_low = pri_ch == RTW89_SC_20_LOWER; + break; + case RTW89_CHANNEL_WIDTH_80: + /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ + mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || + pri_ch == RTW89_SC_20_LOWEST; + mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; + break; + default: + mask_5m_en = false; + break; + } + + if (!mask_5m_en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x0); + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, + B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx); + return; + } + + if (mask_5m_low) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x0); + } + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, + B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx); +} + +static void __rtw8852bx_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); +} + +static void rtw8852bx_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + for (addr = R_AX_PWR_MACID_LMT_TABLE0; + addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); +} + +static void __rtw8852bx_bb_sethw(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); + rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP); + + rtw8852bx_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); + + /* read these registers after loading BB parameters */ + gain->offset_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK); + gain->rssi_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); +} + +static void rtw8852bx_bb_set_pop(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) + rtw89_phy_write32_clr(rtwdev, R_PKT_CTRL, B_PKT_POP_EN); +} + +static u32 rtw8852bt_spur_freq(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u8 center_chan = chan->channel; + + switch (chan->band_type) { + case RTW89_BAND_5G: + if (center_chan == 151 || center_chan == 153 || + center_chan == 155 || center_chan == 163) + return 5760; + break; + default: + break; + } + + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8852bt_set_csi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s32 freq_diff, csi_idx, csi_tone_idx; + u32 spur_freq; + + spur_freq = rtw8852bt_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, + 0, phy_idx); + return; + } + + freq_diff = (spur_freq - chan->freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_V1, B_SEG0CSI_IDX, + csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, 1, phy_idx); +} + +static +void __rtw8852bx_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + bool cck_en = chan->channel <= 14; + u8 pri_ch_idx = chan->pri_ch_idx; + u8 band = chan->band_type, chan_idx; + + if (cck_en) + rtw8852bx_ctrl_sco_cck(rtwdev, chan->primary_channel); + + rtw8852bx_ctrl_ch(rtwdev, chan, phy_idx); + rtw8852bx_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); + rtw8852bx_ctrl_cck_en(rtwdev, cck_en); + if (chip_id == RTL8852BT) + rtw8852bt_set_csi_tone_idx(rtwdev, chan, phy_idx); + if (chip_id == RTL8852B && chan->band_type == RTW89_BAND_5G) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); + } + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); + rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx); + rtw8852bx_5m_mask(rtwdev, chan, phy_idx); + rtw8852bx_bb_set_pop(rtwdev); + __rtw8852bx_bb_reset_all(rtwdev, phy_idx); +} + +static u32 rtw8852bx_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + s16 ref, u16 pwr_ofst_decrease) +{ + const u16 tssi_16dbm_cw = 0x12c; + const u8 base_cw_0db = 0x27; + s16 pwr_s10_3; + s16 rf_pwr_cw; + u16 bb_pwr_cw; + u32 pwr_cw; + u32 tssi_ofst_cw; + + pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease; + bb_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(2, 0)); + rf_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(8, 3)); + rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); + pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; + + tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) - + pwr_ofst_decrease; + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", + tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); + + return u32_encode_bits(tssi_ofst_cw, B_DPD_TSSI_CW) | + u32_encode_bits(pwr_cw, B_DPD_PWR_CW) | + u32_encode_bits(ref, B_DPD_REF); +} + +/* @pwr_ofst (unit: 1/8 dBm): power of path A minus power of path B */ +static void rtw8852bx_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 pwr_ofst) +{ + static const u32 addr[RF_PATH_NUM_8852BX] = {0x5800, 0x7800}; + const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF; + u16 ofst_dec[RF_PATH_NUM_8852BX]; + const u8 ofst_ofdm = 0x4; + const u8 ofst_cck = 0x8; + const s16 ref_ofdm = 0; + const s16 ref_cck = 0; + u32 val; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, + B_AX_PWR_REF, 0x0); + + ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst); + ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]); + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx); + } + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); + for (i = 0; i < RF_PATH_NUM_8852BX; i++) { + val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]); + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx); + } +} + +static void rtw8852bx_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) +{ +#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2)) +#define __DFIR_CFG_MASK 0xffffffff +#define __DFIR_CFG_NR 8 +#define __DECL_DFIR_PARAM(_name, _val...) \ + static const u32 param_ ## _name[] = {_val}; \ + static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR) + + __DECL_DFIR_PARAM(flat, + 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, + 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5); + __DECL_DFIR_PARAM(sharp, + 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090, + 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5); + __DECL_DFIR_PARAM(sharp_14, + 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, + 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); + u8 ch = chan->channel; + const u32 *param; + u32 addr; + int i; + + if (ch > 14) { + rtw89_warn(rtwdev, + "set tx shape dfir by unknown ch: %d on 2G\n", ch); + return; + } + + if (ch == 14) + param = param_sharp_14; + else + param = tx_shape_idx == 0 ? param_flat : param_sharp; + + for (i = 0; i < __DFIR_CFG_NR; i++) { + addr = __DFIR_CFG_ADDR(i); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]); + rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i], + phy_idx); + } + +#undef __DECL_DFIR_PARAM +#undef __DFIR_CFG_NR +#undef __DFIR_CFG_MASK +#undef __DECL_CFG_ADDR +} + +static void rtw8852bx_set_tx_shape(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 band = chan->band_type; + u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK); + u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM); + + if (band == RTW89_BAND_2G) + rtw8852bx_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); + + rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, + tx_shape_ofdm); +} + +static s16 rtw8852bx_get_txpwr_sar_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + struct rtw89_sar_parm sar_parm = { + .center_freq = chan->freq, + .force_path = true, + }; + s16 sar_bb_a, sar_bb_b; + s8 sar_mac; + + sar_parm.path = RF_PATH_A; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_bb_a = rtw89_phy_txpwr_mac_to_bb(rtwdev, sar_mac); + + sar_parm.path = RF_PATH_B; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_bb_b = rtw89_phy_txpwr_mac_to_bb(rtwdev, sar_mac); + + return sar_bb_a - sar_bb_b; +} + +static void rtw8852bx_set_txpwr_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 pwr_ofst; + + pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan); + pwr_ofst += rtw8852bx_get_txpwr_sar_diff(rtwdev, chan); + rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst); +} + +static void __rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw8852bx_set_tx_shape(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); + rtw8852bx_set_txpwr_diff(rtwdev, chan, phy_idx); +} + +static void __rtw8852bx_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, 0); +} + +static +void __rtw8852bx_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx) +{ + u32 reg; + + if (pw_ofst < -16 || pw_ofst > 15) { + rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst); + return; + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); + + pw_ofst = max_t(s8, pw_ofst - 3, -16); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); +} + +static int +__rtw8852bx_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + int ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); + if (ret) + return ret; + + rtw8852bx_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? + RTW89_MAC_1 : RTW89_MAC_0); + + return 0; +} + +static +void __rtw8852bx_bb_set_plcp_tx(struct rtw89_dev *rtwdev) +{ + const struct rtw89_reg3_def *def = rtw8852bx_pmac_ht20_mcs7_tbl; + u8 i; + + for (i = 0; i < ARRAY_SIZE(rtw8852bx_pmac_ht20_mcs7_tbl); i++, def++) + rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); +} + +static void rtw8852bx_stop_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852bx_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx"); + if (tx_info->mode == CONT_TX) + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, idx); + else if (tx_info->mode == PKTS_TX) + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, idx); +} + +static void rtw8852bx_start_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852bx_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx) +{ + enum rtw8852bx_pmac_mode mode = tx_info->mode; + u32 pkt_cnt = tx_info->tx_cnt; + u16 period = tx_info->period; + + if (mode == CONT_TX && !tx_info->is_cck) { + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, idx); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start"); + } else if (mode == PKTS_TX) { + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, + B_PMAC_TX_PRD_MSK, period, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK, + pkt_cnt, idx); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start"); + } + + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx); +} + +static +void rtw8852bx_bb_set_pmac_tx(struct rtw89_dev *rtwdev, + struct rtw8852bx_bb_pmac_info *tx_info, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan) +{ + if (!tx_info->en_pmac_tx) { + rtw8852bx_stop_pmac_tx(rtwdev, tx_info, idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx); + if (chan->band_type == RTW89_BAND_2G) + rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable"); + + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx); + rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx); + + rtw8852bx_start_pmac_tx(rtwdev, tx_info, idx); +} + +static +void __rtw8852bx_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, + u16 tx_cnt, u16 period, u16 tx_time, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan) +{ + struct rtw8852bx_bb_pmac_info tx_info = {0}; + + tx_info.en_pmac_tx = enable; + tx_info.is_cck = 0; + tx_info.mode = PKTS_TX; + tx_info.tx_cnt = tx_cnt; + tx_info.period = period; + tx_info.tx_time = tx_time; + + rtw8852bx_bb_set_pmac_tx(rtwdev, &tx_info, idx, chan); +} + +static +void __rtw8852bx_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, + enum rtw89_phy_idx idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm); + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx); +} + +static +void __rtw8852bx_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) +{ + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path); + + if (tx_path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 1); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0); + } else if (tx_path == RF_PATH_B) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0); + } else if (tx_path == RF_PATH_AB) { + rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 3); + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4); + } else { + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path"); + } +} + +static +void __rtw8852bx_bb_tx_mode_switch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx idx, u8 mode) +{ + if (mode != 0) + return; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch"); + + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx); +} + +static +void __rtw8852bx_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + struct rtw8852bx_bb_tssi_bak *bak) +{ + s32 tmp; + + bak->tx_path = rtw89_phy_read32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, idx); + bak->rx_path = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, idx); + bak->p0_rfmode = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, idx); + bak->p0_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, idx); + bak->p1_rfmode = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, idx); + bak->p1_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, idx); + tmp = rtw89_phy_read32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, idx); + bak->tx_pwr = sign_extend32(tmp, 8); +} + +static +void __rtw8852bx_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + const struct rtw8852bx_bb_tssi_bak *bak) +{ + rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, bak->tx_path, idx); + if (bak->tx_path == RF_AB) + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x4); + else + rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x0); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, bak->rx_path, idx); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, bak->p0_rfmode, idx); + rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, bak->p0_rfmode_ftm, idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, bak->p1_rfmode, idx); + rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, bak->p1_rfmode_ftm, idx); + rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, bak->tx_pwr, idx); +} + +static void __rtw8852bx_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8852bx_btc_preagc_en_defs_tbl : + &rtw8852bx_btc_preagc_dis_defs_tbl); +} + +static void __rtw8852bx_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x20); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); + } +} + +static +void __rtw8852bx_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path, + const struct rtw89_chan *chan) +{ + u32 rst_mask0; + u32 rst_mask1; + + if (rx_path == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } else if (rx_path == RF_B) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 2); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } else if (rx_path == RF_AB) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 3); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); + } + + rtw8852bx_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0); + + if (chan->band_type == RTW89_BAND_2G && + (rx_path == RF_B || rx_path == RF_AB)) + rtw8852bx_ctrl_btg_bt_rx(rtwdev, true, RTW89_PHY_0); + else + rtw8852bx_ctrl_btg_bt_rx(rtwdev, false, RTW89_PHY_0); + + rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; + rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; + if (rx_path == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); + } +} + +static void rtw8852bx_bb_ctrl_rf_mode_rx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path) +{ + if (rx_path == RF_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, + B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, + B_P0_RFMODE_FTM_RX, 0x333); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, + B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1111111); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, + B_P1_RFMODE_FTM_RX, 0x111); + } else if (rx_path == RF_B) { + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, + B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1111111); + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, + B_P0_RFMODE_FTM_RX, 0x111); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, + B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, + B_P1_RFMODE_FTM_RX, 0x333); + } else if (rx_path == RF_AB) { + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, + B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); + rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, + B_P0_RFMODE_FTM_RX, 0x333); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, + B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); + rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, + B_P1_RFMODE_FTM_RX, 0x333); + } +} + +static void __rtw8852bx_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB; + u8 rx_nss = rtwdev->hal.rx_nss; + + if (rx_path != RF_AB) + rx_nss = 1; + + rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan); + rtw8852bx_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path); + + if (rx_nss == 1) { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); + } + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); +} + +static u8 __rtw8852bx_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + if (rtwdev->is_tssi_mode[rf_path]) { + u32 addr = 0x1c10 + (rf_path << 13); + + return rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000); + } + + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); +} + +static +void rtw8852bx_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void __rtw8852bx_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_mac_ax_coex coex_params = { + .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, + .direction = RTW89_MAC_AX_COEX_INNER, + }; + + /* PTA init */ + rtw89_mac_coex_init(rtwdev, &coex_params); + + /* set WL Tx response = Hi-Pri */ + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); + + /* set rf gnt debug off */ + rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0); + + /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ + if (btc->ant_type == BTC_ANT_SHARED) { + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); + /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */ + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x55f); + } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x5ff); + } + + if (rtwdev->chip->chip_id == RTL8852BT) { + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_RX_GROUP, 0x5df); + rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_RX_GROUP, 0x5df); + } + + /* set PTA break table */ + rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); + + /* enable BT counter 0xda40[16,2] = 2b'11 */ + rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); +} + +static +void __rtw8852bx_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + u32 bitmap; + u32 reg; + + switch (map) { + case BTC_PRI_MASK_TX_RESP: + reg = R_BTC_BT_COEX_MSK_TABLE; + bitmap = B_BTC_PRI_MASK_TX_RESP_V1; + break; + case BTC_PRI_MASK_BEACON: + reg = R_AX_WL_PRI_MSK; + bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; + break; + case BTC_PRI_MASK_RX_CCK: + reg = R_BTC_BT_COEX_MSK_TABLE; + bitmap = B_BTC_PRI_MASK_RXCCK_V1; + break; + default: + return; + } + + if (state) + rtw89_write32_set(rtwdev, reg, bitmap); + else + rtw89_write32_clr(rtwdev, reg, bitmap); +} + +static +s8 __rtw8852bx_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + /* +6 for compensate offset */ + return clamp_t(s8, val + 6, -100, 0) + 100; +} + +static +void __rtw8852bx_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + /* Feature move to firmware */ +} + +static void __rtw8852bx_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x31); + + /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ + if (state) + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x179); + else + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void rtw8852bx_btc_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) +{ + switch (level) { + case 0: /* default */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + case 1: /* Fix LNA2=5 */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + } +} + +static void __rtw8852bx_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + switch (level) { + case 0: /* original */ + default: + rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 1: /* for FDD free-run */ + rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 2: /* for BTG Co-Rx*/ + rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 1; + break; + } + + rtw8852bx_btc_set_wl_lna2(rtwdev, btc->dm.wl_lna2); +} + +static void rtw8852bx_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u16 chan = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan == 0) + return; + + rtw89_decode_chan_idx(rtwdev, chan, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void __rtw8852bx_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + u8 *rx_power = phy_ppdu->rssi; + + if (!status->signal) + status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], + rx_power[RF_PATH_B])); + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8852bx_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +static void __rtw8852bx_convert_rpl_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + u8 delta = phy_ppdu->rpl_avg - phy_ppdu->rssi_avg; + u8 *rssi = phy_ppdu->rssi; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852BX; i++) + rssi[i] += delta; + + phy_ppdu->rssi_avg = phy_ppdu->rpl_avg; +} + +static int __rtw8852bx_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 val32; + int ret; + + rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x1); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + + if (chip_id == RTL8852BT) { + val32 = rtw89_read32(rtwdev, R_AX_AFE_OFF_CTRL1); + val32 = u32_replace_bits(val32, 0x1, B_AX_S0_LDO_VSEL_F_MASK); + val32 = u32_replace_bits(val32, 0x1, B_AX_S1_LDO_VSEL_F_MASK); + rtw89_write32(rtwdev, R_AX_AFE_OFF_CTRL1, val32); + } + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC7, + FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC7, + FULL_BIT_MASK); + if (ret) + return ret; + + rtw89_write8(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_XYN_CYCLE); + + return 0; +} + +static int __rtw8852bx_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + u8 wl_rfc_s0; + u8 wl_rfc_s1; + int ret; + + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, &wl_rfc_s0); + if (ret) + return ret; + wl_rfc_s0 &= ~XTAL_SI_RF00S_EN; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, wl_rfc_s0, + FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, &wl_rfc_s1); + if (ret) + return ret; + wl_rfc_s1 &= ~XTAL_SI_RF10S_EN; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, wl_rfc_s1, + FULL_BIT_MASK); + return ret; +} + +const struct rtw8852bx_info rtw8852bx_info = { + .mac_enable_bb_rf = __rtw8852bx_mac_enable_bb_rf, + .mac_disable_bb_rf = __rtw8852bx_mac_disable_bb_rf, + .bb_sethw = __rtw8852bx_bb_sethw, + .bb_reset_all = __rtw8852bx_bb_reset_all, + .bb_cfg_txrx_path = __rtw8852bx_bb_cfg_txrx_path, + .bb_cfg_tx_path = __rtw8852bx_bb_cfg_tx_path, + .bb_ctrl_rx_path = __rtw8852bx_bb_ctrl_rx_path, + .bb_set_plcp_tx = __rtw8852bx_bb_set_plcp_tx, + .bb_set_power = __rtw8852bx_bb_set_power, + .bb_set_pmac_pkt_tx = __rtw8852bx_bb_set_pmac_pkt_tx, + .bb_backup_tssi = __rtw8852bx_bb_backup_tssi, + .bb_restore_tssi = __rtw8852bx_bb_restore_tssi, + .bb_tx_mode_switch = __rtw8852bx_bb_tx_mode_switch, + .set_channel_mac = __rtw8852bx_set_channel_mac, + .set_channel_bb = __rtw8852bx_set_channel_bb, + .ctrl_nbtg_bt_tx = __rtw8852bx_ctrl_nbtg_bt_tx, + .ctrl_btg_bt_rx = __rtw8852bx_ctrl_btg_bt_rx, + .query_ppdu = __rtw8852bx_query_ppdu, + .convert_rpl_to_rssi = __rtw8852bx_convert_rpl_to_rssi, + .read_efuse = __rtw8852bx_read_efuse, + .read_phycap = __rtw8852bx_read_phycap, + .power_trim = __rtw8852bx_power_trim, + .set_txpwr = __rtw8852bx_set_txpwr, + .set_txpwr_ctrl = __rtw8852bx_set_txpwr_ctrl, + .init_txpwr_unit = __rtw8852bx_init_txpwr_unit, + .set_txpwr_ul_tb_offset = __rtw8852bx_set_txpwr_ul_tb_offset, + .get_thermal = __rtw8852bx_get_thermal, + .adc_cfg = rtw8852bt_adc_cfg, + .btc_init_cfg = __rtw8852bx_btc_init_cfg, + .btc_set_wl_pri = __rtw8852bx_btc_set_wl_pri, + .btc_get_bt_rssi = __rtw8852bx_btc_get_bt_rssi, + .btc_update_bt_cnt = __rtw8852bx_btc_update_bt_cnt, + .btc_wl_s1_standby = __rtw8852bx_btc_wl_s1_standby, + .btc_set_wl_rx_gain = __rtw8852bx_btc_set_wl_rx_gain, +}; +EXPORT_SYMBOL(rtw8852bx_info); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852B common routines"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h new file mode 100644 index 000000000..3dce5422f --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h @@ -0,0 +1,400 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW89_8852BX_H__ +#define __RTW89_8852BX_H__ + +#include "core.h" + +#define RF_PATH_NUM_8852BX 2 +#define BB_PATH_NUM_8852BX 2 + +enum rtw8852bx_pmac_mode { + NONE_TEST, + PKTS_TX, + PKTS_RX, + CONT_TX +}; + +struct rtw8852bx_u_efuse { + u8 rsvd[0x88]; + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8852bx_e_efuse { + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8852bx_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; +} __packed; + +struct rtw8852bx_efuse { + u8 rsvd[0x210]; + struct rtw8852bx_tssi_offset path_a_tssi; + u8 rsvd1[10]; + struct rtw8852bx_tssi_offset path_b_tssi; + u8 rsvd2[94]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd3; + u8 iqk_lck; + u8 rsvd4[5]; + u8 reg_setting:2; + u8 tx_diversity:1; + u8 rx_diversity:2; + u8 ac_mode:1; + u8 module_type:2; + u8 rsvd5; + u8 shared_ant:1; + u8 coex_type:3; + u8 ant_iso:1; + u8 radio_on_off:1; + u8 rsvd6:2; + u8 eeprom_version; + u8 customer_id; + u8 tx_bb_swing_2g; + u8 tx_bb_swing_5g; + u8 tx_cali_pwr_trk_mode; + u8 trx_path_selection; + u8 rfe_type; + u8 country_code[2]; + u8 rsvd7[3]; + u8 path_a_therm; + u8 path_b_therm; + u8 rsvd8[2]; + u8 rx_gain_2g_ofdm; + u8 rsvd9; + u8 rx_gain_2g_cck; + u8 rsvd10; + u8 rx_gain_5g_low; + u8 rsvd11; + u8 rx_gain_5g_mid; + u8 rsvd12; + u8 rx_gain_5g_high; + u8 rsvd13[35]; + u8 path_a_cck_pwr_idx[6]; + u8 path_a_bw40_1tx_pwr_idx[5]; + u8 path_a_ofdm_1tx_pwr_idx_diff:4; + u8 path_a_bw20_1tx_pwr_idx_diff:4; + u8 path_a_bw20_2tx_pwr_idx_diff:4; + u8 path_a_bw40_2tx_pwr_idx_diff:4; + u8 path_a_cck_2tx_pwr_idx_diff:4; + u8 path_a_ofdm_2tx_pwr_idx_diff:4; + u8 rsvd14[0xf2]; + union { + struct rtw8852bx_u_efuse u; + struct rtw8852bx_e_efuse e; + }; +} __packed; + +struct rtw8852bx_bb_pmac_info { + u8 en_pmac_tx:1; + u8 is_cck:1; + u8 mode:3; + u8 rsvd:3; + u16 tx_cnt; + u16 period; + u16 tx_time; + u8 duty_cycle; +}; + +struct rtw8852bx_bb_tssi_bak { + u8 tx_path; + u8 rx_path; + u32 p0_rfmode; + u32 p0_rfmode_ftm; + u32 p1_rfmode; + u32 p1_rfmode_ftm; + s16 tx_pwr; /* S9 */ +}; + +struct rtw8852bx_info { + int (*mac_enable_bb_rf)(struct rtw89_dev *rtwdev); + int (*mac_disable_bb_rf)(struct rtw89_dev *rtwdev); + void (*bb_sethw)(struct rtw89_dev *rtwdev); + void (*bb_reset_all)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void (*bb_cfg_txrx_path)(struct rtw89_dev *rtwdev); + void (*bb_cfg_tx_path)(struct rtw89_dev *rtwdev, u8 tx_path); + void (*bb_ctrl_rx_path)(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path, + const struct rtw89_chan *chan); + void (*bb_set_plcp_tx)(struct rtw89_dev *rtwdev); + void (*bb_set_power)(struct rtw89_dev *rtwdev, s16 pwr_dbm, + enum rtw89_phy_idx idx); + void (*bb_set_pmac_pkt_tx)(struct rtw89_dev *rtwdev, u8 enable, + u16 tx_cnt, u16 period, u16 tx_time, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan); + void (*bb_backup_tssi)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + struct rtw8852bx_bb_tssi_bak *bak); + void (*bb_restore_tssi)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + const struct rtw8852bx_bb_tssi_bak *bak); + void (*bb_tx_mode_switch)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx idx, u8 mode); + void (*set_channel_mac)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 mac_idx); + void (*set_channel_bb)(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*ctrl_nbtg_bt_tx)(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx); + void (*ctrl_btg_bt_rx)(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx); + void (*query_ppdu)(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status); + void (*convert_rpl_to_rssi)(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu); + int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block); + int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); + void (*power_trim)(struct rtw89_dev *rtwdev); + void (*set_txpwr)(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); + void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx); + int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx); + u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); + void (*adc_cfg)(struct rtw89_dev *rtwdev, u8 bw, u8 path); + void (*btc_init_cfg)(struct rtw89_dev *rtwdev); + void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); + s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); + void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); + void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); + void (*btc_set_wl_rx_gain)(struct rtw89_dev *rtwdev, u32 level); +}; + +extern const struct rtw8852bx_info rtw8852bx_info; + +static inline +int rtw8852bx_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + return rtw8852bx_info.mac_enable_bb_rf(rtwdev); +} + +static inline +int rtw8852bx_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + return rtw8852bx_info.mac_disable_bb_rf(rtwdev); +} + +static inline +void rtw8852bx_bb_sethw(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.bb_sethw(rtwdev); +} + +static inline +void rtw8852bx_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.bb_reset_all(rtwdev, phy_idx); +} + +static inline +void rtw8852bx_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.bb_cfg_txrx_path(rtwdev); +} + +static inline +void rtw8852bx_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) +{ + rtw8852bx_info.bb_cfg_tx_path(rtwdev, tx_path); +} + +static inline +void rtw8852bx_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path, + const struct rtw89_chan *chan) +{ + rtw8852bx_info.bb_ctrl_rx_path(rtwdev, rx_path, chan); +} + +static inline +void rtw8852bx_bb_set_plcp_tx(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.bb_set_plcp_tx(rtwdev); +} + +static inline +void rtw8852bx_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, + enum rtw89_phy_idx idx) +{ + rtw8852bx_info.bb_set_power(rtwdev, pwr_dbm, idx); +} + +static inline +void rtw8852bx_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, + u16 tx_cnt, u16 period, u16 tx_time, + enum rtw89_phy_idx idx, const struct rtw89_chan *chan) +{ + rtw8852bx_info.bb_set_pmac_pkt_tx(rtwdev, enable, tx_cnt, period, tx_time, idx, + chan); +} + +static inline +void rtw8852bx_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + struct rtw8852bx_bb_tssi_bak *bak) +{ + rtw8852bx_info.bb_backup_tssi(rtwdev, idx, bak); +} + +static inline +void rtw8852bx_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, + const struct rtw8852bx_bb_tssi_bak *bak) +{ + rtw8852bx_info.bb_restore_tssi(rtwdev, idx, bak); +} + +static inline +void rtw8852bx_bb_tx_mode_switch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx idx, u8 mode) +{ + rtw8852bx_info.bb_tx_mode_switch(rtwdev, idx, mode); +} + +static inline +void rtw8852bx_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 mac_idx) +{ + rtw8852bx_info.set_channel_mac(rtwdev, chan, mac_idx); +} + +static inline +void rtw8852bx_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.set_channel_bb(rtwdev, chan, phy_idx); +} + +static inline +void rtw8852bx_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.ctrl_nbtg_bt_tx(rtwdev, en, phy_idx); +} + +static inline +void rtw8852bx_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.ctrl_btg_bt_rx(rtwdev, en, phy_idx); +} + +static inline +void rtw8852bx_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + rtw8852bx_info.query_ppdu(rtwdev, phy_ppdu, status); +} + +static inline +void rtw8852bx_convert_rpl_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + rtw8852bx_info.convert_rpl_to_rssi(rtwdev, phy_ppdu); +} + +static inline +int rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + return rtw8852bx_info.read_efuse(rtwdev, log_map, block); +} + +static inline +int rtw8852bx_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + return rtw8852bx_info.read_phycap(rtwdev, phycap_map); +} + +static inline +void rtw8852bx_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.power_trim(rtwdev); +} + +static inline +void rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.set_txpwr(rtwdev, chan, phy_idx); +} + +static inline +void rtw8852bx_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_info.set_txpwr_ctrl(rtwdev, phy_idx); +} + +static inline +int rtw8852bx_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + return rtw8852bx_info.init_txpwr_unit(rtwdev, phy_idx); +} + +static inline +void rtw8852bx_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx) +{ + rtw8852bx_info.set_txpwr_ul_tb_offset(rtwdev, pw_ofst, mac_idx); +} + +static inline +u8 rtw8852bx_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + return rtw8852bx_info.get_thermal(rtwdev, rf_path); +} + +static inline +void rtw8852bx_adc_cfg(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + rtw8852bx_info.adc_cfg(rtwdev, bw, path); +} + +static inline +void rtw8852bx_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.btc_init_cfg(rtwdev); +} + +static inline +void rtw8852bx_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + rtw8852bx_info.btc_set_wl_pri(rtwdev, map, state); +} + +static inline +s8 rtw8852bx_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + return rtw8852bx_info.btc_get_bt_rssi(rtwdev, val); +} + +static inline +void rtw8852bx_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + rtw8852bx_info.btc_update_bt_cnt(rtwdev); +} + +static inline +void rtw8852bx_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + rtw8852bx_info.btc_wl_s1_standby(rtwdev, state); +} + +static inline +void rtw8852bx_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + rtw8852bx_info.btc_set_wl_rx_gain(rtwdev, level); +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c new file mode 100644 index 000000000..29a82b1c4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c @@ -0,0 +1,4220 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852b.h" +#include "rtw8852b_common.h" +#include "rtw8852b_rfk.h" +#include "rtw8852b_rfk_table.h" +#include "rtw8852b_table.h" + +#define RTW8852B_RXDCK_VER 0x1 +#define RTW8852B_IQK_VER 0x2a +#define RTW8852B_IQK_SS 2 +#define RTW8852B_RXK_GROUP_NR 4 +#define RTW8852B_TSSI_PATH_NR 2 +#define RTW8852B_RF_REL_VERSION 34 +#define RTW8852B_DPK_VER 0x0d +#define RTW8852B_DPK_RF_PATH 2 +#define RTW8852B_DPK_KIP_REG_NUM 3 + +#define _TSSI_DE_MASK GENMASK(21, 12) +#define ADDC_T_AVG 100 +#define DPK_TXAGC_LOWER 0x2e +#define DPK_TXAGC_UPPER 0x3f +#define DPK_TXAGC_INVAL 0xff +#define RFREG_MASKRXBB 0x003e0 +#define RFREG_MASKMODE 0xf0000 + +enum rtw8852b_dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, + DPK_RXAGC = 0x15, + KIP_PRESET = 0x16, + KIP_RESTORE = 0x17, + DPK_TXAGC = 0x19, + D_KIP_PRESET = 0x28, + D_TXAGC = 0x29, + D_RXAGC = 0x2a, + D_SYNC = 0x2b, + D_GAIN_LOSS = 0x2c, + D_MDPK_IDL = 0x2d, + D_GAIN_NORM = 0x2f, + D_KIP_THERMAL = 0x30, + D_KIP_RESTORE = 0x31 +}; + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_ADJ, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +enum rtw8852b_iqk_type { + ID_TXAGC = 0x0, + ID_FLOK_COARSE = 0x1, + ID_FLOK_FINE = 0x2, + ID_TXK = 0x3, + ID_RXAGC = 0x4, + ID_RXK = 0x5, + ID_NBTXK = 0x6, + ID_NBRXK = 0x7, + ID_FLOK_VBUFFER = 0x8, + ID_A_FLOK_COARSE = 0x9, + ID_G_FLOK_COARSE = 0xa, + ID_A_FLOK_FINE = 0xb, + ID_G_FLOK_FINE = 0xc, + ID_IQK_RESTORE = 0x10, +}; + +static const u32 _tssi_trigger[RTW8852B_TSSI_PATH_NR] = {0x5820, 0x7820}; +static const u32 _tssi_cw_rpt_addr[RTW8852B_TSSI_PATH_NR] = {0x1c18, 0x3c18}; +static const u32 _tssi_cw_default_addr[RTW8852B_TSSI_PATH_NR][4] = { + {0x5634, 0x5630, 0x5630, 0x5630}, + {0x7634, 0x7630, 0x7630, 0x7630} }; +static const u32 _tssi_cw_default_mask[4] = { + 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff}; +static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852B] = {0x5858, 0x7858}; +static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852B] = {0x5860, 0x7860}; +static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852B] = {0x5838, 0x7838}; +static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852B] = {0x5840, 0x7840}; +static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852B] = {0x5848, 0x7848}; +static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852B] = {0x5850, 0x7850}; +static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852B] = {0x5828, 0x7828}; +static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852B] = {0x5830, 0x7830}; +static const u32 _a_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x190, 0x198, 0x350, 0x352}; +static const u32 _a_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x0f, 0x0f, 0x3f, 0x7f}; +static const u32 _a_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x1, 0x0, 0x0}; +static const u32 _g_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x212, 0x21c, 0x350, 0x360}; +static const u32 _g_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x00, 0x00, 0x28, 0x5f}; +static const u32 _g_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x2, 0x1}; +static const u32 _a_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0}; +static const u32 _a_track_range[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x6, 0x6}; +static const u32 _a_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e}; +static const u32 _a_itqt[RTW8852B_RXK_GROUP_NR] = {0x12, 0x12, 0x12, 0x1b}; +static const u32 _g_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0}; +static const u32 _g_track_range[RTW8852B_RXK_GROUP_NR] = {0x4, 0x4, 0x6, 0x6}; +static const u32 _g_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e}; +static const u32 _g_itqt[RTW8852B_RXK_GROUP_NR] = {0x09, 0x12, 0x1b, 0x24}; + +static const u32 rtw8852b_backup_bb_regs[] = {0x2344, 0x5800, 0x7800}; +static const u32 rtw8852b_backup_rf_regs[] = { + 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x1e, 0x0, 0x2, 0x5, 0x10005 +}; + +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852b_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852b_backup_rf_regs) + +static const struct rtw89_reg3_def rtw8852b_set_nondbcc_path01[] = { + {0x20fc, 0xffff0000, 0x0303}, + {0x5864, 0x18000000, 0x3}, + {0x7864, 0x18000000, 0x3}, + {0x12b8, 0x40000000, 0x1}, + {0x32b8, 0x40000000, 0x1}, + {0x030c, 0xff000000, 0x13}, + {0x032c, 0xffff0000, 0x0041}, + {0x12b8, 0x10000000, 0x1}, + {0x58c8, 0x01000000, 0x1}, + {0x78c8, 0x01000000, 0x1}, + {0x5864, 0xc0000000, 0x3}, + {0x7864, 0xc0000000, 0x3}, + {0x2008, 0x01ffffff, 0x1ffffff}, + {0x0c1c, 0x00000004, 0x1}, + {0x0700, 0x08000000, 0x1}, + {0x0c70, 0x000003ff, 0x3ff}, + {0x0c60, 0x00000003, 0x3}, + {0x0c6c, 0x00000001, 0x1}, + {0x58ac, 0x08000000, 0x1}, + {0x78ac, 0x08000000, 0x1}, + {0x0c3c, 0x00000200, 0x1}, + {0x2344, 0x80000000, 0x1}, + {0x4490, 0x80000000, 0x1}, + {0x12a0, 0x00007000, 0x7}, + {0x12a0, 0x00008000, 0x1}, + {0x12a0, 0x00070000, 0x3}, + {0x12a0, 0x00080000, 0x1}, + {0x32a0, 0x00070000, 0x3}, + {0x32a0, 0x00080000, 0x1}, + {0x0700, 0x01000000, 0x1}, + {0x0700, 0x06000000, 0x2}, + {0x20fc, 0xffff0000, 0x3333}, +}; + +static const struct rtw89_reg3_def rtw8852b_restore_nondbcc_path01[] = { + {0x20fc, 0xffff0000, 0x0303}, + {0x12b8, 0x40000000, 0x0}, + {0x32b8, 0x40000000, 0x0}, + {0x5864, 0xc0000000, 0x0}, + {0x7864, 0xc0000000, 0x0}, + {0x2008, 0x01ffffff, 0x0000000}, + {0x0c1c, 0x00000004, 0x0}, + {0x0700, 0x08000000, 0x0}, + {0x0c70, 0x0000001f, 0x03}, + {0x0c70, 0x000003e0, 0x03}, + {0x12a0, 0x000ff000, 0x00}, + {0x32a0, 0x000ff000, 0x00}, + {0x0700, 0x07000000, 0x0}, + {0x20fc, 0xffff0000, 0x0000}, + {0x58c8, 0x01000000, 0x0}, + {0x78c8, 0x01000000, 0x0}, + {0x0c3c, 0x00000200, 0x0}, + {0x2344, 0x80000000, 0x0}, +}; + +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852b_backup_bb_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]backup bb reg : %x, value =%x\n", + rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, + rtw8852b_backup_rf_regs[i], RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path, + rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, + const u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852b_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore bb reg : %x, value =%x\n", + rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, + const u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8852b_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) +{ + bool fail = true; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL1 IQK timeout!!!\n"); + + udelay(200); + + if (!ret) + fail = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); + val = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8008 = 0x%x\n", path, val); + + return fail; +} + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u8 val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n", + rtwdev->dbcc_en, phy_idx); + + if (!rtwdev->dbcc_en) { + val = RF_AB; + } else { + if (phy_idx == RTW89_PHY_0) + val = RF_A; + else + val = RF_B; + } + return val; +} + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + mdelay(1); +} + +static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, dck_tune; + u32 rf_reg5; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n", + RTW8852B_RXDCK_VER, rtwdev->hal.cv); + + for (path = 0; path < RF_PATH_NUM_8852B; path++) { + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x1); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + _set_rx_dck(rtwdev, phy, path); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x0); + } +} + +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5; + u32 rck_val; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, + false, rtwdev, path, RR_RCKS, BIT(3)); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", + rck_val, ret); + + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); +} + +static void _afe_init(struct rtw89_dev *rtwdev) +{ + rtw89_write32(rtwdev, R_AX_PHYREG_SET, 0xf); + + rtw89_rfk_parser(rtwdev, &rtw8852b_afe_init_defs_tbl); +} + +static void _drck(struct rtw89_dev *rtwdev) +{ + u32 rck_d; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); + rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, R_DRCK_RS, B_DRCK_RS_DONE); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); + + rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); + rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RS, B_DRCK_RS_LPS); + rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_CV, rck_d); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0cc = 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DRCK_V1, MASKDWORD)); +} + +static void _addck_backup(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); + dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); + dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0); + dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0); + dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + /* S0 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL, dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_VAL, dack->addck_d[0][1] >> 6); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL2, dack->addck_d[0][1] & 0x3f); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x3); + + /* S1 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL, dack->addck_d[1][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK0_VAL, dack->addck_d[1][1] >> 6); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL2, dack->addck_d[1][1] & 0x3f); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, 0x3); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); + dack->msbk_d[0][0][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); + rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); + dack->msbk_d[0][1][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); + } + + dack->biask_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); + dack->biask_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); + + dack->dadck_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00); + dack->dadck_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01); +} + +static void _dack_backup_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i); + dack->msbk_d[1][0][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S); + rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i); + dack->msbk_d[1][1][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S); + } + + dack->biask_d[1][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10); + dack->biask_d[1][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11); + + dack->dadck_d[1][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10); + dack->dadck_d[1][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11); +} + +static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + s32 dc_re = 0, dc_im = 0; + u32 tmp; + u32 i; + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_check_addc_defs_a_tbl, + &rtw8852b_check_addc_defs_b_tbl); + + for (i = 0; i < ADDC_T_AVG; i++) { + tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); + dc_re += FIELD_GET_SIGNED(0xfff000, tmp); + dc_im += FIELD_GET_SIGNED(0xfff, tmp); + } + + dc_re /= ADDC_T_AVG; + dc_im /= ADDC_T_AVG; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); +} + +static void _addck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + /* S0 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x30, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, R_ADDCKR0, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); + + /* S1 */ + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, + false, rtwdev, R_ADDCKR1, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); + dack->addck_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); + _check_addc(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_check_dadc_en_defs_a_tbl, + &rtw8852b_check_dadc_en_defs_b_tbl); + + _check_addc(rtwdev, path); + + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_check_dadc_dis_defs_a_tbl, + &rtw8852b_check_dadc_dis_defs_b_tbl); +} + +static bool _dack_s0_check_done(struct rtw89_dev *rtwdev, bool part1) +{ + if (part1) { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0) + return false; + } else { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) + return false; + } + + return true; +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_1_defs_tbl); + + ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000, + false, rtwdev, true); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_2_defs_tbl); + + ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000, + false, rtwdev, false); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n"); + dack->dadck_timeout[0] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_3_defs_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); + + _dack_backup_s0(rtwdev); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); +} + +static bool _dack_s1_check_done(struct rtw89_dev *rtwdev, bool part1) +{ + if (part1) { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 && + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0) + return false; + } else { + if (rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK_S1P2_OK) == 0 && + rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK_S1P3_OK) == 0) + return false; + } + + return true; +} + +static void _dack_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_1_defs_tbl); + + ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000, + false, rtwdev, true); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); + dack->msbk_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_2_defs_tbl); + + ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000, + false, rtwdev, false); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); + dack->dadck_timeout[1] = true; + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_3_defs_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); + + _check_dadc(rtwdev, RF_PATH_B); + _dack_backup_s1(rtwdev); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); + _dack_s1(rtwdev); +} + +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[1][0], dack->addck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[1][0], dack->biask_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 rf0_0, rf1_0; + + dack->dack_done = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x1\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + + rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); + rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); + _afe_init(rtwdev); + _drck(rtwdev); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1); + _addck(rtwdev); + _addck_backup(rtwdev); + _addck_reload(rtwdev); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); + _dack(rtwdev); + _dack_dump(rtwdev); + dack->dack_done = true; + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + +static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); + tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); + tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); + break; + default: + break; + } +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path, u8 ktype) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 iqk_cmd; + bool fail; + + switch (ktype) { + case ID_FLOK_COARSE: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_FLOK_FINE: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + iqk_cmd = 0x208 | (1 << (4 + path)); + break; + case ID_FLOK_VBUFFER: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_TXK: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_RXAGC: + iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_NBTXK: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011); + iqk_cmd = 0x408 | (1 << (4 + path)); + break; + case ID_NBRXK: + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + udelay(1); + fail = _iqk_check_cal(rtwdev, path); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + return fail; +} + +static bool _rxk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool fail; + u8 gp; + + for (gp = 0; gp < RTW8852B_RXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, + _g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, + _g_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, + _g_idxattc1[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, + _a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, + _a_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, + _a_idxattc1[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP_V1, gp); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + rtw89_phy_write32_mask(rtwdev, R_IQKINF, + BIT(16 + gp + path * 4), fail); + kfail |= fail; + } + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); + + if (kfail) { + iqk_info->nb_rxcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_RXCFIR, 0x0); + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->nb_rxcfir[path] = 0x40000000; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_RXCFIR, 0x5); + iqk_info->is_wb_rxiqk[path] = true; + } + + return kfail; +} + +static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + const u8 gp = 0x3; + bool kfail = false; + bool fail; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, + _g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, + _g_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, + _g_idxattc1[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, + _a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, + _a_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, + _a_idxattc1[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, gp); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + udelay(1); + + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); + kfail |= fail; + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); + + if (!kfail) + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD) | 0x2; + else + iqk_info->nb_rxcfir[path] = 0x40000002; + + return kfail; +} + +static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x0); + } +} + +static bool _txk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail = false; + bool fail; + u8 gp; + + for (gp = 0x0; gp < RTW8852B_RXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _a_itqt[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP, gp); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + rtw89_phy_write32_mask(rtwdev, R_IQKINF, + BIT(8 + gp + path * 4), fail); + kfail |= fail; + } + + if (kfail) { + iqk_info->nb_txcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_TXCFIR, 0x0); + iqk_info->is_wb_txiqk[path] = false; + } else { + iqk_info->nb_txcfir[path] = 0x40000000; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_TXCFIR, 0x5); + iqk_info->is_wb_txiqk[path] = true; + } + + return kfail; +} + +static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool kfail; + u8 gp = 0x2; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _a_itqt[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + kfail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + + if (!kfail) + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD) | 0x2; + else + iqk_info->nb_txcfir[path] = 0x40000002; + + return kfail; +} + +static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); + + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); + else + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXVBUF, RR_TXVBUF_DACEN, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x7c = %x\n", path, + rtw89_read_rf(rtwdev, path, RR_TXVBUF, RFREG_MASK)); +} + +static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 ch = rfk_mcc->table_idx; + bool is_fail1, is_fail2; + u32 vbuff_i; + u32 vbuff_q; + u32 core_i; + u32 core_q; + u32 tmp; + + tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); + core_i = FIELD_GET(RR_TXMO_COI, tmp); + core_q = FIELD_GET(RR_TXMO_COQ, tmp); + + if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) + is_fail1 = true; + else + is_fail1 = false; + + iqk_info->lok_idac[ch][path] = tmp; + + tmp = rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK); + vbuff_i = FIELD_GET(RR_LOKVB_COI, tmp); + vbuff_q = FIELD_GET(RR_LOKVB_COQ, tmp); + + if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d) + is_fail2 = true; + else + is_fail2 = false; + + iqk_info->lok_vbuf[ch][path] = tmp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, lok_idac[%x][%x] = 0x%x\n", path, ch, path, + iqk_info->lok_idac[ch][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, lok_vbuf[%x][%x] = 0x%x\n", path, ch, path, + iqk_info->lok_vbuf[ch][path]); + + return is_fail1 | is_fail2; +} + +static bool _iqk_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool tmp; + + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x4); + break; + default: + break; + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9); + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE); + iqk_info->lok_cor_fail[0][path] = tmp; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24); + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE); + iqk_info->lok_fin_fail[0][path] = tmp; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24); + _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + + return _lok_finetune_check(rtwdev, path); +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW2, 0x00); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x00); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); + udelay(1); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); + rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x80); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); + udelay(1); + break; + default: + break; + } +} + +static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); +} + +static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp; + bool flag; + + flag = iqk_info->lok_cor_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag); + flag = iqk_info->lok_fin_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), flag); + flag = iqk_info->iqk_tx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), flag); + flag = iqk_info->iqk_rx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), flag); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); + iqk_info->bp_iqkenable[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + iqk_info->bp_txkresult[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); + iqk_info->bp_rxkresult[path] = tmp; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, iqk_info->iqk_times); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4)); + if (tmp) + iqk_info->iqk_fail_cnt++; + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4), + iqk_info->iqk_fail_cnt); +} + +static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool lok_is_fail = false; + const int try = 3; + u8 ibias = 0x1; + u8 i; + + _iqk_txclk_setting(rtwdev, path); + + /* LOK */ + for (i = 0; i < try; i++) { + _lok_res_table(rtwdev, path, ibias++); + _iqk_txk_setting(rtwdev, path); + lok_is_fail = _iqk_lok(rtwdev, phy_idx, path); + if (!lok_is_fail) + break; + } + + if (lok_is_fail) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] LOK (%d) fail\n", path); + + /* TXK */ + if (iqk_info->is_nbiqk) + iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); + + /* RX */ + _iqk_rxclk_setting(rtwdev, path); + _iqk_rxk_setting(rtwdev, path); + if (iqk_info->is_nbiqk) + iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); + + _iqk_info_iqk(rtwdev, phy_idx, path); +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = rfk_mcc->table_idx; + u32 reg_rf18; + u32 reg_35c; + + reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN); + + iqk_info->iqk_band[path] = chan->band_type; + iqk_info->iqk_bw[path] = chan->band_width; + iqk_info->iqk_ch[path] = chan->channel; + iqk_info->iqk_mcc_ch[idx][path] = chan->channel; + iqk_info->iqk_table_idx[path] = idx; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x, idx = %x\n", + path, reg_rf18, idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x\n", + path, reg_rf18); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", + iqk_info->iqk_times, idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n", + idx, path, iqk_info->iqk_mcc_ch[idx][path]); + + if (reg_35c == 0x01) + iqk_info->syn1to2 = 0x1; + else + iqk_info->syn1to2 = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", path, + iqk_info->syn1to2); + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852B_IQK_VER); + /* 2GHz/5GHz/6GHz = 0/1/2 */ + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16), + iqk_info->iqk_band[path]); + /* 20/40/80 = 0/1/2 */ + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16), + iqk_info->iqk_bw[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16), + iqk_info->iqk_ch[path]); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + _iqk_by_path(rtwdev, phy_idx, path); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, + iqk_info->nb_txcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + iqk_info->nb_rxcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000e19 + (path << 4)); + fail = _iqk_check_cal(rtwdev, path); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s result =%x\n", __func__, fail); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS, B_IQK_RES_K, 0x0); + rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0x3); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + const struct rtw89_reg3_def *def; + int size; + u8 kpath; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__); + + kpath = _kpath(rtwdev, phy_idx); + + switch (kpath) { + case RF_A: + case RF_B: + return; + default: + size = ARRAY_SIZE(rtw8852b_restore_nondbcc_path01); + def = rtw8852b_restore_nondbcc_path01; + break; + } + + for (i = 0; i < size; i++, def++) + rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + u8 idx = rfk_mcc->table_idx; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] idx = %x\n", idx); + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x54 = 0x%x\n", path, 1 << path, + rtw89_phy_read32_mask(rtwdev, R_CFIR_LUT + (path << 8), MASKDWORD)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x04 = 0x%x\n", path, 1 << path, + rtw89_phy_read32_mask(rtwdev, R_COEF_SEL + (path << 8), MASKDWORD)); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + const struct rtw89_reg3_def *def; + int size; + u8 kpath; + int i; + + kpath = _kpath(rtwdev, phy_idx); + + switch (kpath) { + case RF_A: + case RF_B: + return; + default: + size = ARRAY_SIZE(rtw8852b_set_nondbcc_path01); + def = rtw8852b_set_nondbcc_path01; + break; + } + + for (i = 0; i < size; i++, def++) + rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); +} + +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx, path; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0); + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->iqk_times = 0x0; + + for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { + iqk_info->iqk_channel[idx] = 0x0; + for (path = 0; path < RTW8852B_IQK_SS; path++) { + iqk_info->lok_cor_fail[idx][path] = false; + iqk_info->lok_fin_fail[idx][path] = false; + iqk_info->iqk_tx_fail[idx][path] = false; + iqk_info->iqk_rx_fail[idx][path] = false; + iqk_info->iqk_mcc_ch[idx][path] = 0x0; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u32 rf_mode; + u8 path; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, + rf_mode != 2, 2, 5000, false, + rtwdev, path, RR_MOD, RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret); + } +} + +static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx, + bool is_pause) +{ + if (!is_pause) + return; + + _wait_rx_mode(rtwdev, _kpath(rtwdev, band_idx)); +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852B_IQK_SS][BACKUP_RF_REGS_NR]; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->version = RTW8852B_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + + _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); + _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 kpath = _kpath(rtwdev, phy_idx); + + switch (kpath) { + case RF_A: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + break; + case RF_B: + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + case RF_AB: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + default: + break; + } +} + +static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[], + u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) { + reg_bkup[path][i] = + rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[], + const u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD, + reg_bkup[path][i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) +{ + u8 order; + u8 val; + + order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); + val = 0x3 >> order; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); + + return val; +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 val, kidx = dpk->cur_idx[path]; + + val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKBYTE3, _dpk_order_convert(rtwdev) << 1 | val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); +} + +static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw8852b_dpk_id id) +{ + u16 dpk_cmd; + u32 val; + int ret; + + dpk_cmd = (id << 8) | (0x19 + (path << 4)); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 1, 20000, false, + rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n"); + + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00030000); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, + 1, 2000, false, + rtwdev, 0x80fc, MASKLWORD); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n"); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%x\n", + id == 0x06 ? "LBK_RXIQK" : + id == 0x10 ? "SYNC" : + id == 0x11 ? "MDPK_IDL" : + id == 0x12 ? "MDPK_MPA" : + id == 0x13 ? "GAIN_LOSS" : + id == 0x14 ? "PWR_CAL" : + id == 0x15 ? "DPK_RXAGC" : + id == 0x16 ? "KIP_PRESET" : + id == 0x17 ? "KIP_RESTORE" : "DPK_TXAGC", + dpk_cmd); +} + +static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); + _set_rx_dck(rtwdev, phy, path); +} + +static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = chan->band_type; + dpk->bp[path][kidx].ch = chan->channel; + dpk->bp[path][kidx].bw = chan->band_width; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + str_on_off(rtwdev->is_tssi_mode[path]), + str_on_off(rtwdev->dbcc_en), + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); +} + +static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_defs_tbl); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x1); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); +} + +static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + + rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_restore_defs_tbl); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x0); + } +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_kip_defs_tbl); + + if (rtwdev->hal.cv > CHIP_CAV) + rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), B_DPD_COM_OF, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + u8 cur_rxbb; + u32 tmp; + + cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB); + + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, 0x0); + + tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0xd); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); + + if (cur_rxbb >= 0x11) + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x13); + else if (cur_rxbb <= 0xa) + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x00); + else + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x05); + + rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80014); + udelay(70); + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x025); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0x5); +} + +static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + + udelay(200); + + dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", + dpk->bp[path][kidx].ther_dpk); +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_FATT, 0xf2); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SWATT, 0x5); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + rtw89_write_rf(rtwdev, path, RR_RXA_LNA, RFREG_MASK, 0x920FC); + rtw89_write_rf(rtwdev, path, RR_XALNA2, RFREG_MASK, 0x002C0); + rtw89_write_rf(rtwdev, path, RR_IQGEN, RFREG_MASK, 0x38800); + } + + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ARF 0x0/0x11/0x1a = 0x%x/ 0x%x/ 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); +} + +static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bypass) +{ + if (is_bypass) { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS, 0x1); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD)); + } else { + rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); + rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD)); + } +} + +static +void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) + rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + else + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static void _dpk_table_select(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 kidx, u8 gain) +{ + u8 val; + + val = 0x80 + kidx * 0x20 + gain * 0x10; + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, + gain, val); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define DPK_SYNC_TH_DC_I 200 +#define DPK_SYNC_TH_DC_Q 200 +#define DPK_SYNC_TH_CORR 170 + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u16 dc_i, dc_q; + u8 corr_val, corr_idx; + + rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); + + corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); + corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", + path, corr_idx, corr_val); + + dpk->corr_idx[path][kidx] = corr_idx; + dpk->corr_val[path][kidx] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", + path, dc_i, dc_q); + + dpk->dc_i[path][kidx] = dc_i; + dpk->dc_q[path][kidx] = dc_q; + + if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || + corr_val < DPK_SYNC_TH_CORR) + return true; + else + return false; +} + +static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, SYNC); + + return _dpk_sync_check(rtwdev, path, kidx); +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); + + return dgain; +} + +static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) +{ + static const u16 bnd[15] = { + 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556, + 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220 + }; + s8 offset; + + if (dgain >= bnd[0]) + offset = 0x6; + else if (bnd[0] > dgain && dgain >= bnd[1]) + offset = 0x6; + else if (bnd[1] > dgain && dgain >= bnd[2]) + offset = 0x5; + else if (bnd[2] > dgain && dgain >= bnd[3]) + offset = 0x4; + else if (bnd[3] > dgain && dgain >= bnd[4]) + offset = 0x3; + else if (bnd[4] > dgain && dgain >= bnd[5]) + offset = 0x2; + else if (bnd[5] > dgain && dgain >= bnd[6]) + offset = 0x1; + else if (bnd[6] > dgain && dgain >= bnd[7]) + offset = 0x0; + else if (bnd[7] > dgain && dgain >= bnd[8]) + offset = 0xff; + else if (bnd[8] > dgain && dgain >= bnd[9]) + offset = 0xfe; + else if (bnd[9] > dgain && dgain >= bnd[10]) + offset = 0xfd; + else if (bnd[10] > dgain && dgain >= bnd[11]) + offset = 0xfc; + else if (bnd[11] > dgain && dgain >= bnd[12]) + offset = 0xfb; + else if (bnd[12] > dgain && dgain >= bnd[13]) + offset = 0xfa; + else if (bnd[13] > dgain && dgain >= bnd[14]) + offset = 0xf9; + else if (bnd[14] > dgain) + offset = 0xf8; + else + offset = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain offset = %d\n", offset); + + return offset; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + + return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); +} + +static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_table_select(rtwdev, path, kidx, 1); + _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS); +} + +static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_tpg_sel(rtwdev, path, kidx); + _dpk_one_shot(rtwdev, phy, path, KIP_PRESET); +} + +static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP Power/CLK on\n"); +} + +static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 txagc) +{ + rtw89_write_rf(rtwdev, path, RR_TXAGC, RFREG_MASK, txagc); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + _dpk_one_shot(rtwdev, phy, path, DPK_TXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set TXAGC = 0x%x\n", txagc); +} + +static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + u32 tmp; + + tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, tmp); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + _dpk_one_shot(rtwdev, phy, path, DPK_RXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL_V1, 0x8); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] set RXBB = 0x%x (RF0x0[9:5] = 0x%x)\n", + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB_V1), + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB)); +} + +static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, s8 gain_offset) +{ + u8 txagc; + + txagc = rtw89_read_rf(rtwdev, path, RR_TXAGC, RFREG_MASK); + + if (txagc - gain_offset < DPK_TXAGC_LOWER) + txagc = DPK_TXAGC_LOWER; + else if (txagc - gain_offset > DPK_TXAGC_UPPER) + txagc = DPK_TXAGC_UPPER; + else + txagc = txagc - gain_offset; + + _dpk_kip_set_txagc(rtwdev, phy, path, txagc); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", + gain_offset, txagc); + return txagc; +} + +static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + + if (val1_i * val1_i + val1_q * val1_q >= + (val2_i * val2_i + val2_q * val2_q) * 8 / 5) + return true; + + return false; +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_txagc, + bool loss_only, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; + u8 goout = 0, agc_cnt = 0, limited_rxbb = 0; + u16 dgain = 0; + s8 offset; + int limit = 200; + + tmp_txagc = init_txagc; + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + if (_dpk_sync(rtwdev, phy, path, kidx)) { + tmp_txagc = 0xff; + goout = 1; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + + if (loss_only == 1 || limited_rxbb == 1) + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + else + step = DPK_AGC_STEP_GAIN_ADJ; + break; + + case DPK_AGC_STEP_GAIN_ADJ: + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, + RFREG_MASKRXBB); + offset = _dpk_dgain_mapping(rtwdev, dgain); + + if (tmp_rxbb + offset > 0x1f) { + tmp_rxbb = 0x1f; + limited_rxbb = 1; + } else if (tmp_rxbb + offset < 0) { + tmp_rxbb = 0; + limited_rxbb = 1; + } else { + tmp_rxbb = tmp_rxbb + offset; + } + + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB, + tmp_rxbb); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb); + if (offset || agc_cnt == 0) { + if (chan->band_width < RTW89_CHANNEL_WIDTH_80) + _dpk_bypass_rxcfir(rtwdev, path, true); + else + _dpk_lbk_rxiqk(rtwdev, phy, path); + } + if (dgain > 1922 || dgain < 342) + step = DPK_AGC_STEP_SYNC_DGAIN; + else + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + + agc_cnt++; + break; + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + _dpk_gainloss(rtwdev, phy, path, kidx); + tmp_gl_idx = _dpk_gainloss_read(rtwdev); + + if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || + tmp_gl_idx >= 7) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + break; + + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_txagc == 0x2e) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0x3); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_txagc == 0x3f) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0xfe); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + case DPK_AGC_STEP_SET_TX_GAIN: + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, tmp_gl_idx); + goout = 1; + agc_cnt++; + break; + + default: + goout = 1; + break; + } + } while (!goout && agc_cnt < 6 && limit-- > 0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, + tmp_rxbb); + + return tmp_txagc; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) +{ + switch (order) { + case 0: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); + break; + case 1: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); + rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); + break; + case 2: + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); + rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Wrong MDPD order!!(0x%x)\n", order); + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Set MDPD order to 0x%x for IDL\n", order); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 gain) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 && + dpk->bp[path][kidx].band == RTW89_BAND_5G) + _dpk_set_mdpd_para(rtwdev, 0x2); + else + _dpk_set_mdpd_para(rtwdev, 0x0); + + _dpk_one_shot(rtwdev, phy, path, MDPK_IDL); +} + +static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + const u16 pwsf = 0x78; + u8 gs = dpk->dpk_gs[phy]; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, kidx); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, + pwsf, gs); + + dpk->bp[path][kidx].txagc_dpk = txagc; + rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), + 0x3F << ((gain << 3) + (kidx << 4)), txagc); + + dpk->bp[path][kidx].pwsf = pwsf; + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x1FF << (gain << 4), pwsf); + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); + + dpk->bp[path][kidx].gs = gs; + if (dpk->dpk_gs[phy] == 0x7f) + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x007f7f7f); + else + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x005b5b5b); + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_ORDER_V1, _dpk_order_convert(rtwdev)); + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, 0x0); +} + +static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + bool is_reload = false; + u8 idx, cur_band, cur_ch; + + cur_band = chan->band_type; + cur_ch = chan->channel; + + for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { + if (cur_band != dpk->bp[path][idx].band || + cur_ch != dpk->bp[path][idx].ch) + continue; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, idx); + dpk->cur_idx[path] = idx; + is_reload = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] reload S%d[%d] success\n", path, idx); + } + + return is_reload; +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 gain, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 txagc = 0x38, kidx = dpk->cur_idx[path]; + bool is_fail = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx); + + _rfk_rf_direct_cntrl(rtwdev, path, false); + _rfk_drf_direct_cntrl(rtwdev, path, false); + + _dpk_kip_pwr_clk_on(rtwdev, path); + _dpk_kip_set_txagc(rtwdev, phy, path, txagc); + _dpk_rf_setting(rtwdev, gain, path, kidx); + _dpk_rx_dck(rtwdev, phy, path); + + _dpk_kip_preset(rtwdev, phy, path, kidx); + _dpk_kip_set_rxagc(rtwdev, phy, path); + _dpk_table_select(rtwdev, path, kidx, gain); + + txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust txagc = 0x%x\n", txagc); + + if (txagc == 0xff) { + is_fail = true; + } else { + _dpk_get_thermal(rtwdev, kidx, path); + + _dpk_idl_mpa(rtwdev, phy, path, kidx, gain); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc); + } + + if (!is_fail) + dpk->bp[path][kidx].path_ok = true; + else + dpk->bp[path][kidx].path_ok = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, + is_fail ? "Check" : "Success"); + + return is_fail; +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120}; + u32 kip_bkup[RTW8852B_DPK_RF_PATH][RTW8852B_DPK_KIP_REG_NUM] = {}; + u32 backup_rf_val[RTW8852B_DPK_RF_PATH][BACKUP_RF_REGS_NR]; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + bool is_fail = true, reloaded[RTW8852B_DPK_RF_PATH] = {}; + u8 path; + + if (dpk->is_dpk_reload_en) { + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { + reloaded[path] = _dpk_reload_check(rtwdev, phy, path, + chanctx_idx); + if (!reloaded[path] && dpk->bp[path][0].ch) + dpk->cur_idx[path] = !dpk->cur_idx[path]; + else + _dpk_onoff(rtwdev, path, false); + } + } else { + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) + dpk->cur_idx[path] = 0; + } + + _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); + + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { + _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); + _dpk_information(rtwdev, phy, path, chanctx_idx); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + } + + _dpk_bb_afe_setting(rtwdev, phy, path, kpath, chanctx_idx); + + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { + is_fail = _dpk_main(rtwdev, phy, path, 1, chanctx_idx); + _dpk_onoff(rtwdev, path, is_fail); + } + + _dpk_bb_afe_restore(rtwdev, phy, path, kpath, chanctx_idx); + _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); + + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { + _dpk_kip_restore(rtwdev, path); + _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } +} + +static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_fem_info *fem = &rtwdev->fem; + + if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 6G_ext_PA exist!!\n"); + return true; + } + + return false; +} + +static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, kpath; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { + if (kpath & BIT(path)) + _dpk_onoff(rtwdev, path, true); + } +} + +static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", + RTW8852B_DPK_VER, rtwdev->hal.cv, + RTW8852B_RF_REL_VERSION); + + if (_dpk_bypass_check(rtwdev, phy, chanctx_idx)) + _dpk_force_bypass(rtwdev, phy); + else + _dpk_cal_select(rtwdev, force, phy, RF_AB, chanctx_idx); +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst; + s8 delta_ther[2] = {}; + u8 trk_idx, txagc_rf; + u8 path, kidx; + u16 pwsf[2]; + u8 cur_ther; + u32 tmp; + + for (path = 0; path < RF_PATH_NUM_8852B; path++) { + kidx = dpk->cur_idx[path]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] thermal now = %d\n", cur_ther); + + if (dpk->bp[path][kidx].ch && cur_ther) + delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + delta_ther[path] = delta_ther[path] * 3 / 2; + else + delta_ther[path] = delta_ther[path] * 5 / 2; + + txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + 0x0000003f); + + if (rtwdev->is_tssi_mode[path]) { + trk_idx = rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", + txagc_rf, trk_idx); + + txagc_bb = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + MASKBYTE2); + txagc_bb_tp = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13), + B_TXAGC_TP); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + txagc_ofst = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + MASKBYTE3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", + txagc_ofst, delta_ther[path]); + tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), + B_DPD_COM_OF); + if (tmp == 0x1) { + txagc_ofst = 0; + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] HW txagc offset mode\n"); + } + + if (txagc_rf && cur_ther) + ini_diff = txagc_ofst + (delta_ther[path]); + + tmp = rtw89_phy_read32_mask(rtwdev, + R_P0_TXDPD + (path << 13), + B_P0_TXDPD); + if (tmp == 0x0) { + pwsf[0] = dpk->bp[path][kidx].pwsf + + txagc_bb_tp - txagc_bb + ini_diff; + pwsf[1] = dpk->bp[path][kidx].pwsf + + txagc_bb_tp - txagc_bb + ini_diff; + } else { + pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff; + pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff; + } + + } else { + pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + } + + tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS); + if (!tmp && txagc_rf) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", + pwsf[0], pwsf[1]); + + rtw89_phy_write32_mask(rtwdev, + R_DPD_BND + (path << 8) + (kidx << 2), + B_DPD_BND_0, pwsf[0]); + rtw89_phy_write32_mask(rtwdev, + R_DPD_BND + (path << 8) + (kidx << 2), + B_DPD_BND_1, pwsf[1]); + } + } +} + +static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 tx_scale, ofdm_bkof, path, kpath; + + kpath = _kpath(rtwdev, phy); + + ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM); + tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA); + + if (ofdm_bkof + tx_scale >= 44) { + /* move dpd backoff to bb, and set dpd backoff to 0 */ + dpk->dpk_gs[phy] = 0x7f; + for (path = 0; path < RF_PATH_NUM_8852B; path++) { + if (!(kpath & BIT(path))) + continue; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8), + B_DPD_CFG, 0x7f7f7f); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Set S%d DPD backoff to 0dB\n", path); + } + } else { + dpk->dpk_gs[phy] = 0x5b; + } +} + +static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (band == RTW89_BAND_2G) + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); +} + +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser(rtwdev, &rtw8852b_tssi_sys_defs_tbl); + + if (path == RF_PATH_A) + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852b_tssi_sys_a_defs_2g_tbl, + &rtw8852b_tssi_sys_a_defs_5g_tbl); + else + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852b_tssi_sys_b_defs_2g_tbl, + &rtw8852b_tssi_sys_b_defs_5g_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_tssi_init_txpwr_defs_a_tbl, + &rtw8852b_tssi_init_txpwr_defs_b_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl, + &rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_tssi_dck_defs_a_tbl, + &rtw8852b_tssi_dck_defs_b_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ +#define RTW8852B_TSSI_GET_VAL(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + const struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 subband = chan->subband_type; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + if (!trk) + trk = &rtw89_8852b_trk_cfg; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + R_P0_TSSI_BASE + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + + } else { + thermal = tssi_info->thermal[RF_PATH_B]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_b[i++] : + -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_b[i++] : + thm_up_b[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); + } +#undef RTW8852B_TSSI_GET_VAL +} + +static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_tssi_dac_gain_defs_a_tbl, + &rtw8852b_tssi_dac_gain_defs_b_tbl); +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (path == RF_PATH_A) + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852b_tssi_slope_a_defs_2g_tbl, + &rtw8852b_tssi_slope_a_defs_5g_tbl); + else + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852b_tssi_slope_b_defs_2g_tbl, + &rtw8852b_tssi_slope_b_defs_5g_tbl); +} + +static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, bool all, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + const struct rtw89_rfk_tbl *tbl = NULL; + u8 ch = chan->channel; + + if (path == RF_PATH_A) { + if (band == RTW89_BAND_2G) { + if (all) + tbl = &rtw8852b_tssi_align_a_2g_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_a_2g_part_defs_tbl; + } else if (ch >= 36 && ch <= 64) { + if (all) + tbl = &rtw8852b_tssi_align_a_5g1_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_a_5g1_part_defs_tbl; + } else if (ch >= 100 && ch <= 144) { + if (all) + tbl = &rtw8852b_tssi_align_a_5g2_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_a_5g2_part_defs_tbl; + } else if (ch >= 149 && ch <= 177) { + if (all) + tbl = &rtw8852b_tssi_align_a_5g3_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_a_5g3_part_defs_tbl; + } + } else { + if (ch >= 1 && ch <= 14) { + if (all) + tbl = &rtw8852b_tssi_align_b_2g_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_b_2g_part_defs_tbl; + } else if (ch >= 36 && ch <= 64) { + if (all) + tbl = &rtw8852b_tssi_align_b_5g1_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_b_5g1_part_defs_tbl; + } else if (ch >= 100 && ch <= 144) { + if (all) + tbl = &rtw8852b_tssi_align_b_5g2_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_b_5g2_part_defs_tbl; + } else if (ch >= 149 && ch <= 177) { + if (all) + tbl = &rtw8852b_tssi_align_b_5g3_all_defs_tbl; + else + tbl = &rtw8852b_tssi_align_b_5g3_part_defs_tbl; + } + } + + if (tbl) + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852b_tssi_slope_defs_a_tbl, + &rtw8852b_tssi_slope_defs_b_tbl); +} + +static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, 0x0); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "======>%s path=%d\n", __func__, + path); + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_MIX, 0x010); + else + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_RFCTM_DEL, 0x010); +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852B; i++) { + _tssi_set_tssi_track(rtwdev, phy, i); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); + + if (i == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, + B_P0_TSSI_MV_CLR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, + B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, + B_P0_TSSI_EN, 0x1); + rtw89_write_rf(rtwdev, i, RR_TXGA_V1, + RR_TXGA_V1_TRK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_RFC, 0x3); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT_EN, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = true; + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, + B_P1_TSSI_MV_CLR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, + B_P1_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, + B_P1_TSSI_EN, 0x1); + rtw89_write_rf(rtwdev, i, RR_TXGA_V1, + RR_TXGA_V1_TRK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_RFC, 0x3); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT_EN, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_B] = true; + } + } +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 gidx, gidx_1st, gidx_2nd; + s8 de_1st; + s8 de_2nd; + s8 val; + + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 tgidx, tgidx_1st, tgidx_2nd; + s8 tde_1st; + s8 tde_2nd; + s8 val; + + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + _tssi_de_cck_long[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], + _TSSI_DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + _tssi_de_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], + _TSSI_DE_MASK)); + } +} + +static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" + "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", + R_TSSI_PA_K1 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD), + R_TSSI_PA_K2 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM1 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM3 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD), + R_TSSI_PA_K5 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM2 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD), + R_P0_TSSI_ALIM4 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD), + R_TSSI_PA_K8 + (path << 13), + rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD)); +} + +static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, enum rtw89_rf_path path, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 channel = chan->channel; + u8 band; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d path=%d\n", __func__, phy, path); + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + if (tssi_info->alignment_done[path][band]) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][0]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][1]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][2]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][3]); + } + + _tssi_alimentk_dump_result(rtwdev, path); +} + +static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm, + u8 enable, const struct rtw89_chan *chan) +{ + enum rtw89_rf_path_bit rx_path; + + if (path == RF_PATH_A) + rx_path = RF_A; + else if (path == RF_PATH_B) + rx_path = RF_B; + else if (path == RF_PATH_AB) + rx_path = RF_AB; + else + rx_path = RF_ABCD; /* don't change path, but still set others */ + + if (enable) { + rtw8852bx_bb_set_plcp_tx(rtwdev); + rtw8852bx_bb_cfg_tx_path(rtwdev, path); + rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan); + rtw8852bx_bb_set_power(rtwdev, pwr_dbm, phy); + } + + rtw8852bx_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy, chan); +} + +static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const u32 reg[], + u32 reg_backup[], u32 reg_num) +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + reg_backup[i] = rtw89_phy_read32_mask(rtwdev, reg[i], MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i], + reg_backup[i]); + } +} + +static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const u32 reg[], + u32 reg_backup[], u32 reg_num) + +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i], MASKDWORD, reg_backup[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i], + reg_backup[i]); + } +} + +static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel) +{ + u8 channel_index; + + if (channel >= 1 && channel <= 14) + channel_index = channel - 1; + else if (channel >= 36 && channel <= 64) + channel_index = (channel - 36) / 2 + 14; + else if (channel >= 100 && channel <= 144) + channel_index = ((channel - 100) / 2) + 15 + 14; + else if (channel >= 149 && channel <= 177) + channel_index = ((channel - 149) / 2) + 38 + 14; + else + channel_index = 0; + + return channel_index; +} + +static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const s16 *power, + u32 *tssi_cw_rpt, const struct rtw89_chan *chan) +{ + u32 tx_counter, tx_counter_tmp; + const int retry = 100; + u32 tmp; + int j, k; + + for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) { + rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x1); + + tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_trigger[path], MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] 0x%x = 0x%08x path=%d\n", + _tssi_trigger[path], tmp, path); + + if (j == 0) + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true, chan); + else + _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true, + chan); + + tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] First HWTXcounter=%d path=%d\n", + tx_counter_tmp, path); + + for (k = 0; k < retry; k++) { + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], + B_TSSI_CWRPT_RDY); + if (tmp) + break; + + udelay(30); + + tx_counter_tmp = + rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n", + k, tx_counter_tmp, path); + } + + if (k >= retry) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n", + k, path); + + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan); + return false; + } + + tssi_cw_rpt[j] = + rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], B_TSSI_CWRPT); + + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan); + + tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] Final HWTXcounter=%d path=%d\n", + tx_counter_tmp, path); + } + + return true; +} + +static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4, + 0x78e4, 0x49c0, 0x0d18, 0x0d80}; + static const s16 power_2g[4] = {48, 20, 4, 4}; + static const s16 power_5g[4] = {48, 20, 4, 4}; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3; + u32 tssi_cw_rpt[RTW8852B_TSSI_PATH_NR] = {0}; + u8 channel = chan->channel; + u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel); + struct rtw8852bx_bb_tssi_bak tssi_bak; + s32 aliment_diff, tssi_cw_default; + u32 bb_reg_backup[8] = {0}; + ktime_t start_time; + const s16 *power; + s64 this_time; + u8 band; + bool ok; + u32 tmp; + u8 j; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s channel=%d path=%d\n", __func__, channel, + path); + + if (tssi_info->check_backup_aligmk[path][ch_idx]) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, + tssi_info->alignment_backup_by_ch[path][ch_idx][0]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, + tssi_info->alignment_backup_by_ch[path][ch_idx][1]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, + tssi_info->alignment_backup_by_ch[path][ch_idx][2]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, + tssi_info->alignment_backup_by_ch[path][ch_idx][3]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s Reload TSSI Alignment !!!\n", __func__); + _tssi_alimentk_dump_result(rtwdev, path); + return; + } + + start_time = ktime_get(); + + if (chan->band_type == RTW89_BAND_2G) + power = power_2g; + else + power = power_5g; + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + rtw8852bx_bb_backup_tssi(rtwdev, phy, &tssi_bak); + _tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup)); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); + + ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt, chan); + if (!ok) + goto out; + + for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j, + power[j], j, tssi_cw_rpt[j]); + } + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][1], + _tssi_cw_default_mask[1]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) - + tssi_cw_rpt[1] + tssi_cw_default; + aliment_diff = tssi_alim_offset_1 - tssi_cw_default; + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][2], + _tssi_cw_default_mask[2]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_2 = tssi_cw_default + aliment_diff; + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][3], + _tssi_cw_default_mask[3]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_3 = tssi_cw_default + aliment_diff; + + if (path == RF_PATH_A) { + tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | + FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | + FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, tmp); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13)); + } else { + tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | + FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | + FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, tmp); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13)); + } + + tssi_info->alignment_done[path][band] = true; + tssi_info->alignment_value[path][band][0] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][1] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][2] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][3] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); + + tssi_info->check_backup_aligmk[path][ch_idx] = true; + tssi_info->alignment_backup_by_ch[path][ch_idx][0] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][1] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][2] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][3] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM1 + (path << 13), + tssi_info->alignment_value[path][band][0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM3 + (path << 13), + tssi_info->alignment_value[path][band][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM2 + (path << 13), + tssi_info->alignment_value[path][band][2]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM4 + (path << 13), + tssi_info->alignment_value[path][band][3]); + +out: + _tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup)); + rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak); + rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0); + + this_time = ktime_us_delta(ktime_get(), start_time); + tssi_info->tssi_alimk_time += this_time; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n", + __func__, this_time, tssi_info->tssi_alimk_time); +} + +void rtw8852b_dpk_init(struct rtw89_dev *rtwdev) +{ + _set_dpd_backoff(rtwdev, RTW89_PHY_0); +} + +void rtw8852b_rck(struct rtw89_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < RF_PATH_NUM_8852B; path++) + _rck(rtwdev, path); +} + +void rtw8852b_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); + _dac_cal(rtwdev, false); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); +} + +void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + _iqk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + +void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _rx_dck(rtwdev, phy_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); +} + +void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + rtwdev->dpk.is_dpk_enable = true; + rtwdev->dpk.is_dpk_reload_en = false; + _dpk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8852b_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + +void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB, chanctx_idx); + u32 tx_en; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_set_dac_gain_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_alignment_default(rtwdev, phy, i, true, chan); + _tssi_set_tssi_slope(rtwdev, phy, i); + + rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); + _tmac_tx_pause(rtwdev, phy, true); + if (hwtx_en) + _tssi_alimentk(rtwdev, phy, i, chan); + _tmac_tx_pause(rtwdev, phy, false); + rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 channel = chan->channel; + u8 band; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d channel=%d\n", __func__, phy, channel); + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RTW8852B_TSSI_PATH_NR; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + + if (tssi_info->alignment_done[i][band]) + _tssi_alimentk_done(rtwdev, phy, i, chan); + else + _tssi_alignment_default(rtwdev, phy, i, true, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 channel = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", + __func__, channel); + + if (enable) { + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + rtw8852b_tssi(rtwdev, phy, true, chanctx_idx); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); + + _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan); + _tssi_alimentk_done(rtwdev, phy, RF_PATH_B, chan); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s SCAN_END\n", __func__); +} + +void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + if (scan_start) + rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx); + else + rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx); +} + +static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) +{ + u32 rf_reg18; + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + if (rf_reg18 == INV_RF_DATA) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]Invalid RF_0x18 for Path-%d\n", path); + return; + } + rf_reg18 &= ~RR_CFGCH_BW; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); + } + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", + bw, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + _bw_setting(rtwdev, RF_PATH_A, bw, true); + _bw_setting(rtwdev, RF_PATH_B, bw, true); + _bw_setting(rtwdev, RF_PATH_A, bw, false); + _bw_setting(rtwdev, RF_PATH_B, bw, false); +} + +static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) +{ + u32 bak; + u32 tmp; + int ret; + + bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); + + ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, + false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); + + return !!ret; +} + +static void _lck_check(struct rtw89_dev *rtwdev) +{ + u32 tmp; + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); + } + + udelay(10); + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + } + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); + + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", + rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); + } +} + +static void _set_ch(struct rtw89_dev *rtwdev, u32 val) +{ + bool timeout; + + timeout = _set_s0_arfc18(rtwdev, val); + if (!timeout) + _lck_check(rtwdev); +} + +static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 central_ch, bool dav) +{ + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + bool is_2g_ch = central_ch <= 14; + u32 rf_reg18; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | + RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); + + if (!is_2g_ch) + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | + FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + + if (path == RF_PATH_A && dav) + _set_ch(rtwdev, rf_reg18); + else + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", + central_ch, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) +{ + _ch_setting(rtwdev, RF_PATH_A, central_ch, true); + _ch_setting(rtwdev, RF_PATH_B, central_ch, true); + _ch_setting(rtwdev, RF_PATH_A, central_ch, false); + _ch_setting(rtwdev, RF_PATH_B, central_ch, false); +} + +static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); + + if (bw == RTW89_CHANNEL_WIDTH_20) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); + else if (bw == RTW89_CHANNEL_WIDTH_40) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); + else if (bw == RTW89_CHANNEL_WIDTH_80) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); + else + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path, + rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); +} + +static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + u8 kpath, path; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RF_PATH_NUM_8852B; path++) { + if (!(kpath & BIT(path))) + continue; + + _set_rxbb_bw(rtwdev, bw, path); + } +} + +static void rtw8852b_ctrl_bw_ch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 central_ch, + enum rtw89_band band, enum rtw89_bandwidth bw) +{ + _ctrl_ch(rtwdev, central_ch); + _ctrl_bw(rtwdev, phy, bw); + _rxbb_bw(rtwdev, phy, bw); +} + +void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8852b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, + chan->band_width); +} + +void rtw8852b_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {}; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + u8 idx; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[0]; + + for (idx = 0; idx < ARRAY_SIZE(desc); idx++) { + struct rtw89_rfk_chan_desc *p = &desc[idx]; + + p->ch = rfk_mcc->ch[idx]; + + p->has_band = true; + p->band = rfk_mcc->band[idx]; + } + + idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[idx] = chan->channel; + rfk_mcc->band[idx] = chan->band_type; + rfk_mcc->table_idx = idx; +} + +void rtw8852b_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 path; + + switch (state) { + case RTW89_CHANCTX_STATE_MCC_START: + dpk->is_dpk_enable = false; + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) + _dpk_onoff(rtwdev, path, false); + break; + case RTW89_CHANCTX_STATE_MCC_STOP: + dpk->is_dpk_enable = true; + for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) + _dpk_onoff(rtwdev, path, false); + rtw8852b_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); + break; + default: + break; + } +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h new file mode 100644 index 000000000..5fae980d5 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852B_RFK_H__ +#define __RTW89_8852B_RFK_H__ + +#include "core.h" + +void rtw8852b_rck(struct rtw89_dev *rtwdev); +void rtw8852b_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_dpk_init(struct rtw89_dev *rtwdev); +void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_dpk_track(struct rtw89_dev *rtwdev); +void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan); +void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +void rtw8852b_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw8852b_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c new file mode 100644 index 000000000..0b8a210bb --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "rtw8852b_rfk_table.h" + +static const struct rtw89_reg5_def rtw8852b_afe_init_defs[] = { + RTW89_DECL_RFK_WM(0xC0D4, 0xffffffff, 0x4486888c), + RTW89_DECL_RFK_WM(0xC0D8, 0xffffffff, 0xc6ba10e0), + RTW89_DECL_RFK_WM(0xc0dc, 0xffffffff, 0x30c52868), + RTW89_DECL_RFK_WM(0xc0e0, 0xffffffff, 0x05008128), + RTW89_DECL_RFK_WM(0xc0e4, 0xffffffff, 0x0000272b), + RTW89_DECL_RFK_WM(0xC1D4, 0xffffffff, 0x4486888c), + RTW89_DECL_RFK_WM(0xC1D8, 0xffffffff, 0xc6ba10e0), + RTW89_DECL_RFK_WM(0xc1dc, 0xffffffff, 0x30c52868), + RTW89_DECL_RFK_WM(0xc1e0, 0xffffffff, 0x05008128), + RTW89_DECL_RFK_WM(0xc1e4, 0xffffffff, 0x0000272b), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_afe_init_defs); + +static const struct rtw89_reg5_def rtw8852b_check_addc_defs_a[] = { + RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0), + RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1), + RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2), + RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0), + RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x2), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_a); + +static const struct rtw89_reg5_def rtw8852b_check_addc_defs_b[] = { + RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0), + RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1), + RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2), + RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0), + RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x3), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_b); + +static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_a[] = { + RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf), + RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3), + RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0), + RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x1), + RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x1), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_a); + +static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_b[] = { + RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf), + RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3), + RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0), + RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x1), + RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x1), + RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_b); + +static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_a[] = { + RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x0), + RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_a); + +static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_b[] = { + RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x0), + RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_b); + +static const struct rtw89_reg5_def rtw8852b_dack_s0_1_defs[] = { + RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x1), + RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x3), + RTW89_DECL_RFK_WM(0x12B8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x1), + RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x3), + RTW89_DECL_RFK_WM(0xC004, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0xc024, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0xC004, 0x3ff00000, 0x30), + RTW89_DECL_RFK_WM(0xC004, 0xc0000000, 0x0), + RTW89_DECL_RFK_WM(0xC004, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x1), + RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x1), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_1_defs); + +static const struct rtw89_reg5_def rtw8852b_dack_s0_2_defs[] = { + RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x0), + RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x1), + RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_2_defs); + +static const struct rtw89_reg5_def rtw8852b_dack_s0_3_defs[] = { + RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x0), + RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x0), + RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x7), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_3_defs); + +static const struct rtw89_reg5_def rtw8852b_dack_s1_1_defs[] = { + RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x1), + RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x3), + RTW89_DECL_RFK_WM(0x32B8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x1), + RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x3), + RTW89_DECL_RFK_WM(0xc104, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0xc124, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0xc104, 0x3ff00000, 0x30), + RTW89_DECL_RFK_WM(0xc104, 0xc0000000, 0x0), + RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x1), + RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x1), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_1_defs); + +static const struct rtw89_reg5_def rtw8852b_dack_s1_2_defs[] = { + RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x0), + RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x1), + RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x1), + RTW89_DECL_RFK_DELAY(1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_2_defs); + +static const struct rtw89_reg5_def rtw8852b_dack_s1_3_defs[] = { + RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x0), + RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x0), + RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x0), + RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x7), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_3_defs); + +static const struct rtw89_reg5_def rtw8852b_dpk_afe_defs[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303), + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), + RTW89_DECL_RFK_WM(0x12b8, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x1), + RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x1), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x3), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x3), + RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x1ffffff), + RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x1), + RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x1), + RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x3ff), + RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3), + RTW89_DECL_RFK_WM(0x0c6c, BIT(0), 0x1), + RTW89_DECL_RFK_WM(0x58ac, BIT(27), 0x1), + RTW89_DECL_RFK_WM(0x78ac, BIT(27), 0x1), + RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x1), + RTW89_DECL_RFK_WM(0x2344, BIT(31), 0x1), + RTW89_DECL_RFK_WM(0x4490, BIT(31), 0x1), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0xbf), + RTW89_DECL_RFK_WM(0x32a0, 0x000f0000, 0xb), + RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x5), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x3333), + RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x1), + RTW89_DECL_RFK_WM(0x5800, 0x0000ffff, 0x0000), + RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x1), + RTW89_DECL_RFK_WM(0x7800, 0x0000ffff, 0x0000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_defs); + +static const struct rtw89_reg5_def rtw8852b_dpk_afe_restore_defs[] = { + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303), + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x0), + RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x0), + RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x0), + RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x0), + RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x0), + RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x0), + RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x63), + RTW89_DECL_RFK_WM(0x12a0, 0x000FF000, 0x00), + RTW89_DECL_RFK_WM(0x32a0, 0x000FF000, 0x00), + RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, BIT(29), 0x0), + RTW89_DECL_RFK_WM(0x7864, BIT(29), 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0000), + RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x0), + RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x0), + RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x0), + RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x0), + RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x2), + RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x0), + RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x1), + RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x2), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_restore_defs); + +static const struct rtw89_reg5_def rtw8852b_dpk_kip_defs[] = { + RTW89_DECL_RFK_WM(0x8008, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x8088, 0xffffffff, 0x80000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_kip_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x5), + RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x5), + RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0x5555), + RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0x5555), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), + RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x19), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_2g); + +static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_5g); + +static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_2g[] = { + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_2g); + +static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_5g[] = { + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_5g); + +static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_a[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x002d000), + RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x1dc80280), + RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00002080), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800), + RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_a); + +static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_b[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x002d000), + RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x1dc80280), + RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00002080), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0x800), + RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_b); + +static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_b[] = { + RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_b); + +static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x0ef), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x0ef), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_b); + +static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_a[] = { + RTW89_DECL_RFK_WM(0x58b0, 0x00000400, 0x1), + RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000), + RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_a); + +static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_b[] = { + RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x000), + RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_b); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0804008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_2g); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e08), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_5g); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_2g[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0804008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_2g); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_5g[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e08), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_5g); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_part_defs[] = { + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_part_defs[] = { + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_part_defs[] = { + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_part_defs[] = { + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_part_defs[] = { + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_part_defs[] = { + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_part_defs[] = { + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_all_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_part_defs[] = { + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_part_defs); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_b); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h new file mode 100644 index 000000000..b4d6e9851 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852B_RFK_TABLE_H__ +#define __RTW89_8852B_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8852b_afe_init_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_1_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_2_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_3_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_1_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_2_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_3_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_restore_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_dpk_kip_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_part_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_b_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c new file mode 100644 index 000000000..1485a8fc4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c @@ -0,0 +1,22928 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852b_table.h" + +static const struct rtw89_reg2_def rtw89_8852b_phy_bb_regs[] = { + {0x704, 0x601E0100}, + {0x4000, 0x00000000}, + {0x4004, 0xCA014000}, + {0x4008, 0xC751D4F0}, + {0x400C, 0x44511475}, + {0x4010, 0x00000000}, + {0x4014, 0x00000000}, + {0x4018, 0x4F4C084B}, + {0x401C, 0x084A4E52}, + {0x4020, 0x4D504E4B}, + {0x4024, 0x4F4C0849}, + {0x4028, 0x08484C50}, + {0x402C, 0x4C50504C}, + {0x4030, 0x5454084A}, + {0x4034, 0x084B5654}, + {0x4038, 0x6A6C605A}, + {0x403C, 0x4C4C084C}, + {0x4040, 0x084B4E4D}, + {0x4044, 0x4E4C4B4B}, + {0x4048, 0x4B4B084A}, + {0x404C, 0x084A4E4C}, + {0x4050, 0x514F4C4A}, + {0x4054, 0x524E084A}, + {0x4058, 0x084A5154}, + {0x405C, 0x53555554}, + {0x4060, 0x45450845}, + {0x4064, 0x08454144}, + {0x4068, 0x40434445}, + {0x406C, 0x44450845}, + {0x4070, 0x08444043}, + {0x4074, 0x42434444}, + {0x4078, 0x46450844}, + {0x407C, 0x08444843}, + {0x4080, 0x4B4E4A47}, + {0x4084, 0x4F4C084B}, + {0x4088, 0x084A4E52}, + {0x408C, 0x4D504E4B}, + {0x4090, 0x4F4C0849}, + {0x4094, 0x08484C50}, + {0x4098, 0x4C50504C}, + {0x409C, 0x5454084A}, + {0x40A0, 0x084B5654}, + {0x40A4, 0x6A6C605A}, + {0x40A8, 0x4C4C084C}, + {0x40AC, 0x084B4E4D}, + {0x40B0, 0x4E4C4B4B}, + {0x40B4, 0x4B4B084A}, + {0x40B8, 0x084A4E4C}, + {0x40BC, 0x514F4C4A}, + {0x40C0, 0x524E084A}, + {0x40C4, 0x084A5154}, + {0x40C8, 0x53555554}, + {0x40CC, 0x45450845}, + {0x40D0, 0x08454144}, + {0x40D4, 0x40434445}, + {0x40D8, 0x44450845}, + {0x40DC, 0x08444043}, + {0x40E0, 0x42434444}, + {0x40E4, 0x46450844}, + {0x40E8, 0x08444843}, + {0x40EC, 0x4B4E4A47}, + {0x40F0, 0x00000000}, + {0x40F4, 0x00000006}, + {0x40F8, 0x00000000}, + {0x40FC, 0x8C30C30C}, + {0x4100, 0x4C30C30C}, + {0x4104, 0x0C30C30C}, + {0x4108, 0x0C30C30C}, + {0x410C, 0x0C30C30C}, + {0x4110, 0x0C30C30C}, + {0x4114, 0x28A28A28}, + {0x4118, 0x28A28A28}, + {0x411C, 0x28A28A28}, + {0x4120, 0x28A28A28}, + {0x4124, 0x28A28A28}, + {0x4128, 0x28A28A28}, + {0x412C, 0x06666666}, + {0x4130, 0x33333333}, + {0x4134, 0x33333333}, + {0x4138, 0x33333333}, + {0x413C, 0x00000031}, + {0x4140, 0x5100600A}, + {0x4144, 0x18363113}, + {0x4148, 0x1D976DDC}, + {0x414C, 0x1C072DD7}, + {0x4150, 0x1127CDF4}, + {0x4154, 0x1E37BDF1}, + {0x4158, 0x1FB7F1D6}, + {0x415C, 0x1EA7DDF9}, + {0x4160, 0x1FE445DD}, + {0x4164, 0x1F97F1FE}, + {0x4168, 0x1FF781ED}, + {0x416C, 0x1FA7F5FE}, + {0x4170, 0x1E07B913}, + {0x4174, 0x1FD7FDFF}, + {0x4178, 0x1E17B9FA}, + {0x417C, 0x19A66914}, + {0x4180, 0x10F65598}, + {0x4184, 0x14A5A111}, + {0x4188, 0x1D3765DB}, + {0x418C, 0x17C685CA}, + {0x4190, 0x1107C5F3}, + {0x4194, 0x1B5785EB}, + {0x4198, 0x1F97ED8F}, + {0x419C, 0x1BC7A5F3}, + {0x41A0, 0x1FE43595}, + {0x41A4, 0x1EB7D9FC}, + {0x41A8, 0x1FE65DBE}, + {0x41AC, 0x1EC7D9FC}, + {0x41B0, 0x1976FCFF}, + {0x41B4, 0x1F77F5FF}, + {0x41B8, 0x1976FDEC}, + {0x41BC, 0x198664EF}, + {0x41C0, 0x11062D93}, + {0x41C4, 0x10C4E910}, + {0x41C8, 0x1CA759DB}, + {0x41CC, 0x1335A9B5}, + {0x41D0, 0x1097B9F3}, + {0x41D4, 0x17B72DE1}, + {0x41D8, 0x1F67ED42}, + {0x41DC, 0x18074DE9}, + {0x41E0, 0x1FD40547}, + {0x41E4, 0x1D57ADF9}, + {0x41E8, 0x1FE52182}, + {0x41EC, 0x1D67B1F9}, + {0x41F0, 0x14860CE1}, + {0x41F4, 0x1EC7E9FE}, + {0x41F8, 0x14860DD6}, + {0x41FC, 0x195664C7}, + {0x4200, 0x0005E58A}, + {0x4204, 0x00000000}, + {0x4208, 0x00000000}, + {0x420C, 0x7A000000}, + {0x4210, 0x0F9F3D7A}, + {0x4214, 0x0040817C}, + {0x4218, 0x00E10204}, + {0x421C, 0x227D94CD}, + {0x4220, 0x08028A28}, + {0x4224, 0x00000210}, + {0x4228, 0x04688000}, + {0x4A48, 0x00000002}, + {0x422C, 0x0060B002}, + {0x4230, 0x9A8249A8}, + {0x4234, 0x26A1469E}, + {0x4238, 0x2099A824}, + {0x423C, 0x2359461C}, + {0x4240, 0x1631A675}, + {0x4244, 0x2C6B1D63}, + {0x4248, 0x0000000E}, + {0x424C, 0x00000001}, + {0x4250, 0x00000001}, + {0x4254, 0x00000000}, + {0x4258, 0x00000000}, + {0x425C, 0x00000000}, + {0x4260, 0x0020000C}, + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, + {0x4270, 0x2B33135C}, + {0x4274, 0x00000002}, + {0x4278, 0x00000000}, + {0x427C, 0x00000000}, + {0x4280, 0x00000000}, + {0x4284, 0x00000000}, + {0x4288, 0x00000000}, + {0x428C, 0x00000000}, + {0x4290, 0x00000000}, + {0x4294, 0x00000000}, + {0x4298, 0x00000000}, + {0x429C, 0x84026000}, + {0x42A0, 0x0051AC20}, + {0x4A24, 0x0010C040}, + {0x42A4, 0x02024008}, + {0x42A8, 0x00000000}, + {0x42AC, 0x00000000}, + {0x42B0, 0x22CE803C}, + {0x42B4, 0x32000000}, + {0x42B8, 0x996FD67D}, + {0x42BC, 0xBD67D67D}, + {0x42C0, 0x7D67D65B}, + {0x42C4, 0x28029F59}, + {0x42C8, 0x00280280}, + {0x42CC, 0x00000000}, + {0x42D0, 0x00000000}, + {0x42D4, 0x00000003}, + {0x42D8, 0x00000001}, + {0x42DC, 0x61861800}, + {0x42E0, 0x830C30C3}, + {0x42E4, 0xC30C30C3}, + {0x42E8, 0x830C30C3}, + {0x42EC, 0x451450C3}, + {0x42F0, 0x05145145}, + {0x42F4, 0x05145145}, + {0x42F8, 0x05145145}, + {0x42FC, 0x0F0C3145}, + {0x4300, 0x030C30CF}, + {0x4304, 0x030C30C3}, + {0x4308, 0x030CF3C3}, + {0x430C, 0x030C30C3}, + {0x4310, 0x0F3CF3C3}, + {0x4314, 0x0F3CF3CF}, + {0x4318, 0x0F3CF3CF}, + {0x431C, 0x0F3CF3CF}, + {0x4320, 0x0F3CF3CF}, + {0x4324, 0x030C10C3}, + {0x4328, 0x051430C3}, + {0x432C, 0x051490CB}, + {0x4330, 0x030CD151}, + {0x4334, 0x050C50C7}, + {0x4338, 0x051492CB}, + {0x433C, 0x05145145}, + {0x4340, 0x05145145}, + {0x4344, 0x05145145}, + {0x4348, 0x05145145}, + {0x434C, 0x090CD3CF}, + {0x4350, 0x071491C5}, + {0x4354, 0x073CF143}, + {0x4358, 0x071431C3}, + {0x435C, 0x0F3CF1C5}, + {0x4360, 0x0F3CF3CF}, + {0x4364, 0x0F3CF3CF}, + {0x4368, 0x0F3CF3CF}, + {0x436C, 0x0F3CF3CF}, + {0x4370, 0x090C91CF}, + {0x4374, 0x11243143}, + {0x4378, 0x9777A777}, + {0x437C, 0xBB7BAC95}, + {0x4380, 0xB667B889}, + {0x4384, 0x7B9B8899}, + {0x4388, 0x7A5567C8}, + {0x438C, 0x2278CCCC}, + {0x4390, 0x7C222222}, + {0x4394, 0x0000069B}, + {0x4398, 0x001CCCCC}, + {0x4AAC, 0xCCCCC88C}, + {0x4AB0, 0x0000AACC}, + {0x439C, 0x00000000}, + {0x43A0, 0x00000008}, + {0x43A4, 0x00000000}, + {0x43A8, 0x00000000}, + {0x43AC, 0x00000000}, + {0x43B0, 0x10000000}, + {0x43B4, 0x00401001}, + {0x43B8, 0x00061003}, + {0x43BC, 0x000024D8}, + {0x43C0, 0x00000000}, + {0x43C4, 0x10000020}, + {0x43C8, 0x20000200}, + {0x43CC, 0x00000000}, + {0x43D0, 0x04000000}, + {0x43D4, 0x44000100}, + {0x43D8, 0x60804060}, + {0x43DC, 0x44204210}, + {0x43E0, 0x82108082}, + {0x43E4, 0x82108402}, + {0x43E8, 0xC8082108}, + {0x43EC, 0xC8202084}, + {0x43F0, 0x44208208}, + {0x43F4, 0x84108204}, + {0x43F8, 0xD0108104}, + {0x43FC, 0xF8210108}, + {0x4400, 0x6431E930}, + {0x4404, 0x02309468}, + {0x4408, 0x10C61C22}, + {0x440C, 0x02109469}, + {0x4410, 0x10C61C22}, + {0x4414, 0x00041049}, + {0x4A4C, 0x00060581}, + {0x4418, 0x00000000}, + {0x441C, 0x00000000}, + {0x4420, 0x6C000000}, + {0x4424, 0xB0200020}, + {0x4428, 0x00001FF0}, + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, + {0x4438, 0x00000000}, + {0x443C, 0x190642D0}, + {0x4440, 0xA80668A0}, + {0x4444, 0x60900820}, + {0x4448, 0x9F28518C}, + {0x444C, 0x32488A62}, + {0x4450, 0x9C6E36DC}, + {0x4454, 0x0000F52B}, + {0x4458, 0x00000000}, + {0x445C, 0x4801442E}, + {0x4460, 0x0051A0B8}, + {0x4464, 0x00000000}, + {0x4468, 0x00000000}, + {0x446C, 0x00000000}, + {0x4470, 0x00000000}, + {0x4474, 0x00000000}, + {0x4478, 0x00000000}, + {0x447C, 0x00000000}, + {0x4480, 0x2A0A6040}, + {0x4484, 0x0A0A6829}, + {0x4488, 0x00000004}, + {0x448C, 0x00000000}, + {0x4490, 0x80000000}, + {0x4494, 0x10000000}, + {0x4498, 0xE0000000}, + {0x4AB4, 0x00000000}, + {0x449C, 0x0000001E}, + {0x44A0, 0x02B2C3A6}, + {0x44A4, 0x00000400}, + {0x44A8, 0x00000001}, + {0x44AC, 0x000190C0}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4E830171}, + {0x4534, 0x00000870}, + {0x4538, 0x000000FF}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x40000000}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x20000000}, + {0x4570, 0x04F040BB}, + {0x4574, 0x000E53FF}, + {0x4578, 0x000205CB}, + {0x457C, 0x00200000}, + {0x4580, 0x00000040}, + {0x4584, 0x00000000}, + {0x4588, 0x00000017}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x00000000}, + {0x4598, 0x00000001}, + {0x459C, 0x0003FE00}, + {0x45A0, 0x00000086}, + {0x45A4, 0x00000000}, + {0x45A8, 0xC00001C0}, + {0x45AC, 0x78038000}, + {0x45B0, 0x8000004A}, + {0x45B4, 0x04094800}, + {0x45B8, 0x00280002}, + {0x45BC, 0x06748790}, + {0x45C0, 0x80000000}, + {0x45C4, 0x00000000}, + {0x45C8, 0x00000000}, + {0x45CC, 0x00558670}, + {0x45D0, 0x002883F0}, + {0x45D4, 0x00090120}, + {0x45D8, 0x00000000}, + {0x45E0, 0xA3A6D3C4}, + {0x45E4, 0xAB27B126}, + {0x45E8, 0x00006778}, + {0x45F4, 0x000001B5}, + {0x45EC, 0x11110F0A}, + {0x45F0, 0x00000003}, + {0x4A0C, 0x0000000A}, + {0x45F8, 0x0058BC3F}, + {0x45FC, 0x00000003}, + {0x462C, 0x00000020}, + {0x4600, 0x000003D9}, + {0x45F0, 0x00000004}, + {0x4604, 0x002B1CB0}, + {0x4A50, 0xC0000000}, + {0x4A54, 0x00001000}, + {0x4A58, 0x00000000}, + {0x4A18, 0x00000024}, + {0x4608, 0x00000001}, + {0x460C, 0x00000000}, + {0x4A10, 0x00000001}, + {0x4610, 0x00000001}, + {0x4614, 0x16E5298F}, + {0x4618, 0x18C6294A}, + {0x461C, 0x0E06318A}, + {0x4620, 0x0E539CE5}, + {0x4624, 0x00019287}, + {0x4A14, 0x000000BF}, + {0x4628, 0x00000001}, + {0x4630, 0x000001AA}, + {0x4A18, 0x00001900}, + {0x4A1C, 0x000002A6}, + {0x4634, 0x000000A3}, + {0x4A20, 0x00000086}, + {0x4638, 0x01986456}, + {0x49F8, 0x00000000}, + {0x463C, 0x00000000}, + {0x4640, 0x00000000}, + {0x4644, 0x00C8CC00}, + {0x4648, 0xC400B6B6}, + {0x464C, 0xDC400FC0}, + {0x4A8C, 0x00000110}, + {0x4650, 0x08882550}, + {0x4654, 0x08CC2660}, + {0x4658, 0x09102660}, + {0x465C, 0x00000154}, + {0x45DC, 0xC39E38E8}, + {0x4660, 0x452607E6}, + {0x4664, 0x6750DC65}, + {0x4668, 0xF3F0F1ED}, + {0x466C, 0x30141506}, + {0x4670, 0x2C2B2B2B}, + {0x4674, 0x2C2C2C2C}, + {0x4678, 0xDDB738E8}, + {0x467C, 0x543618FB}, + {0x4680, 0x4F31DC6F}, + {0x4684, 0xFBEBDA00}, + {0x4688, 0x1A10FF04}, + {0x468C, 0x282A3000}, + {0x4690, 0x2A29292A}, + {0x4694, 0x04FA2A2A}, + {0x4698, 0xEE0F04D1}, + {0x469C, 0x99E91436}, + {0x46A0, 0x0701E79E}, + {0x46A4, 0x08D77CFF}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60322437}, + {0x46B0, 0x63666666}, + {0x46B4, 0x35374425}, + {0x46B8, 0x35883042}, + {0x46BC, 0x5177C252}, + {0x4720, 0x7FFFFD63}, + {0x4724, 0xB58D11FF}, + {0x4728, 0x07FFFFFF}, + {0x472C, 0x0E7893B6}, + {0x4730, 0xE0391201}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0x473C, 0x00000B7F}, + {0x46C0, 0x00000000}, + {0x46C4, 0x00000000}, + {0x46C8, 0x00000219}, + {0x46CC, 0x00000000}, + {0x46D0, 0x00000000}, + {0x46D4, 0x00000001}, + {0x46D8, 0x00000001}, + {0x46DC, 0x00000000}, + {0x46E0, 0x00000000}, + {0x46E4, 0x00000151}, + {0x46E8, 0x00000498}, + {0x46EC, 0x00000498}, + {0x46F0, 0x00000000}, + {0x46F4, 0x00000000}, + {0x46F8, 0x00001146}, + {0x46FC, 0x00000000}, + {0x4700, 0x00000000}, + {0x4704, 0x00C8CC00}, + {0x4708, 0xC400B6B6}, + {0x470C, 0xDC400FC0}, + {0x4A90, 0x00000110}, + {0x4710, 0x08882550}, + {0x4714, 0x08CC2660}, + {0x4718, 0x09102660}, + {0x471C, 0x00000154}, + {0x4740, 0xC69F38E8}, + {0x4744, 0x462709E9}, + {0x4748, 0x6750DC67}, + {0x474C, 0xF3F0F1ED}, + {0x4750, 0x30141506}, + {0x4754, 0x2C2B2B2B}, + {0x4758, 0x2C2C2C2C}, + {0x475C, 0xE0B738E8}, + {0x4760, 0x52381BFE}, + {0x4764, 0x5031DC6C}, + {0x4768, 0xFBEBDA00}, + {0x476C, 0x1A10FF04}, + {0x4770, 0x282A3000}, + {0x4774, 0x2A29292A}, + {0x4778, 0x04FA2A2A}, + {0x477C, 0xEE0F04D1}, + {0x49F0, 0x99E91436}, + {0x49F4, 0x0701E79E}, + {0x49FC, 0x08D77CFF}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60322437}, + {0x4A64, 0x63666666}, + {0x4A68, 0x35374425}, + {0x4A6C, 0x35883042}, + {0x4A70, 0x5177C252}, + {0x4A74, 0x7FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0x4A7C, 0x07FFFFFF}, + {0x4A80, 0x0E7893B6}, + {0x4A9C, 0xE0391201}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0x4AA8, 0x00000B7F}, + {0x4780, 0x00000000}, + {0x4784, 0x00000000}, + {0x4788, 0x00000219}, + {0x478C, 0x00000000}, + {0x4790, 0x00000000}, + {0x4794, 0x00000001}, + {0x4798, 0x00000001}, + {0x479C, 0x00000000}, + {0x47A0, 0x00000000}, + {0x47A4, 0x00000151}, + {0x47A8, 0x00000498}, + {0x47AC, 0x00000498}, + {0x47B0, 0x00000000}, + {0x47B4, 0x00000000}, + {0x47B8, 0x00001146}, + {0x47BC, 0x00000002}, + {0x47C0, 0x00000002}, + {0x47C4, 0x00000000}, + {0x47C8, 0xA32103FE}, + {0x47CC, 0xB20A5328}, + {0x47D0, 0xC686314F}, + {0x47D4, 0x000005D7}, + {0x47D8, 0x009B902A}, + {0x47DC, 0x009B902A}, + {0x47E0, 0x98682C18}, + {0x47E4, 0x6308C4C1}, + {0x47E8, 0x6248C631}, + {0x47EC, 0x922A8253}, + {0x47F0, 0x00000005}, + {0x47F4, 0x00001759}, + {0x47F8, 0x4BB02000}, + {0x47FC, 0x831408BE}, + {0x4A84, 0x000000E9}, + {0x4800, 0x9ABBCACB}, + {0x4804, 0x56767578}, + {0x4808, 0xBCCBBB13}, + {0x480C, 0x7889989B}, + {0x4810, 0xBBB0F455}, + {0x4814, 0x777BBBBB}, + {0x4818, 0x15277777}, + {0x481C, 0x27039CE9}, + {0x4820, 0x42424432}, + {0x4824, 0x36058342}, + {0x4828, 0x00000006}, + {0x482C, 0x00000005}, + {0x4830, 0x00000005}, + {0x4834, 0xC7013016}, + {0x4838, 0x84413016}, + {0x483C, 0x84413016}, + {0x4840, 0x8C413016}, + {0x4844, 0x8C40B028}, + {0x4848, 0x3140B028}, + {0x484C, 0x2940B028}, + {0x4850, 0x8440B028}, + {0x4854, 0x2318C610}, + {0x4858, 0x45344753}, + {0x485C, 0x236A6A88}, + {0x4860, 0xAC8DF814}, + {0x4864, 0x08877ACB}, + {0x4868, 0x000107AA}, + {0x4A94, 0x00000000}, + {0x486C, 0xBCEB4A14}, + {0x4870, 0x000A3A4A}, + {0x4874, 0xBCEB4A14}, + {0x4878, 0x000A3A4A}, + {0x487C, 0xBCBDBD85}, + {0x4880, 0x0CABB99A}, + {0x4884, 0x38384242}, + {0x4888, 0x0086102E}, + {0x488C, 0xCA24C82A}, + {0x4890, 0x00008A62}, + {0x4894, 0x00000008}, + {0x4898, 0x009B902A}, + {0x489C, 0x009B902A}, + {0x48A0, 0x98682C18}, + {0x48A4, 0x6308C4C1}, + {0x48A8, 0x6248C631}, + {0x48AC, 0x922A8253}, + {0x48B0, 0x00000005}, + {0x48B4, 0x00001759}, + {0x48B8, 0x4BA02000}, + {0x48BC, 0x831408BE}, + {0x4A88, 0x000000E9}, + {0x48C0, 0x9898A8BB}, + {0x48C4, 0x54535368}, + {0x48C8, 0x99999B13}, + {0x48CC, 0x55555899}, + {0x48D0, 0xBBB07453}, + {0x48D4, 0x777BBBBB}, + {0x48D8, 0x15277777}, + {0x48DC, 0x27039CE9}, + {0x48E0, 0x31413432}, + {0x48E4, 0x36058342}, + {0x48E8, 0x00000006}, + {0x48EC, 0x00000005}, + {0x48F0, 0x00000005}, + {0x48F4, 0xC7013016}, + {0x48F8, 0x84413016}, + {0x48FC, 0x84413016}, + {0x4900, 0x8C413016}, + {0x4904, 0x8C40B028}, + {0x4908, 0x3140B028}, + {0x490C, 0x2940B028}, + {0x4910, 0x8440B028}, + {0x4914, 0x2318C610}, + {0x4918, 0x45334753}, + {0x491C, 0x236A6A88}, + {0x4920, 0xAC8DF814}, + {0x4924, 0x08877ACB}, + {0x4928, 0x000007AA}, + {0x4A98, 0x00000000}, + {0x492C, 0xBCEB4A14}, + {0x4930, 0x000A3A4A}, + {0x4934, 0xBCEB4A14}, + {0x4938, 0x000A3A4A}, + {0x493C, 0x9A8A8A85}, + {0x4940, 0x0CA3B99A}, + {0x4944, 0x38384242}, + {0x4948, 0x8086102E}, + {0x494C, 0xCA24C82A}, + {0x4950, 0x00008A62}, + {0x4954, 0x00000008}, + {0x4958, 0x80040000}, + {0x495C, 0x80040000}, + {0x4960, 0xFE800000}, + {0x4964, 0x834C0000}, + {0x4968, 0x00000000}, + {0x496C, 0x00000000}, + {0x4970, 0x00000000}, + {0x4974, 0x00000000}, + {0x4978, 0x00000000}, + {0x497C, 0x00000000}, + {0x4980, 0x40000000}, + {0x4984, 0x00000000}, + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4990, 0x00000000}, + {0x4994, 0x04065800}, + {0x4998, 0x02004080}, + {0x499C, 0x0E1E3E05}, + {0x49A0, 0x0A163068}, + {0x49A4, 0x00206040}, + {0x49A8, 0x02020202}, + {0x49AC, 0x00002020}, + {0x49B0, 0xF8F8F418}, + {0x49B4, 0xF8E8F8F8}, + {0x49B8, 0xF80808E8}, + {0x4A00, 0xF8F8FA00}, + {0x4A04, 0xFAFAFAF8}, + {0x4A08, 0xFAFAFAFA}, + {0x4A28, 0xFAFAFAFA}, + {0x4A2C, 0xFAFAFAFA}, + {0x4A30, 0xFAFAFAFA}, + {0x4A34, 0xFAFAFAFA}, + {0x4A38, 0xFAFAFAFA}, + {0x4A3C, 0xFAFAFAFA}, + {0x4A40, 0xFAFAFAFA}, + {0x4A44, 0x0000FAFA}, + {0x49BC, 0x00000000}, + {0x49C0, 0x800CD62D}, + {0x49C4, 0x00000103}, + {0x49C8, 0x00000000}, + {0x49CC, 0x00000000}, + {0x49D0, 0x00000000}, + {0x49D4, 0x00000000}, + {0x49D8, 0x00000000}, + {0x49DC, 0x00000000}, + {0x49E0, 0x00000000}, + {0x49E4, 0x00000000}, + {0x49E8, 0x00000000}, + {0x49EC, 0x00000000}, + {0x994, 0x00000010}, + {0x904, 0x00000005}, + {0xC3C, 0x2840E1BF}, + {0xC40, 0x00000000}, + {0xC44, 0x00000007}, + {0xC48, 0x410E4000}, + {0xC54, 0x1EE14368}, + {0xC58, 0x41000000}, + {0x730, 0x00000002}, + {0xC60, 0x017FFFF2}, + {0xC64, 0x0010A130}, + {0xC68, 0x10000050}, + {0xC6C, 0x10001021}, + {0x708, 0x00000000}, + {0x884, 0x0043F01D}, + {0x704, 0x601E0100}, + {0x710, 0xEF810000}, + {0x704, 0x601E0100}, + {0xD40, 0xF64FA0F7}, + {0xD44, 0x0400063F}, + {0xD48, 0x0003FF7F}, + {0xD4C, 0x00000000}, + {0xD50, 0xF64FA0F7}, + {0xD54, 0x04100437}, + {0xD58, 0x0000FF7F}, + {0xD5C, 0x00000000}, + {0xD60, 0x00000000}, + {0xD64, 0x00000000}, + {0xD70, 0x00000015}, + {0xD90, 0x000003FF}, + {0xD94, 0x00000000}, + {0xD98, 0x0000003F}, + {0xD9C, 0x00000000}, + {0xDA0, 0x000003FE}, + {0xDA4, 0x00000000}, + {0xDA8, 0x0000003F}, + {0xDAC, 0x00000000}, + {0xD00, 0x77777777}, + {0xD04, 0xBBBBBBBB}, + {0xD08, 0xBBBBBBBB}, + {0xD0C, 0x00000070}, + {0xD10, 0x20110900}, + {0xD10, 0x20110FFF}, + {0xD78, 0x00000001}, + {0xD7C, 0x001D050E}, + {0xD84, 0x00004207}, + {0xD18, 0x50209900}, + {0xD80, 0x00804100}, + {0x718, 0x1333233F}, + {0x604, 0x041E1E1E}, + {0x714, 0x00010000}, + {0x586C, 0x000000F0}, + {0x586C, 0x000000E0}, + {0x586C, 0x000000D0}, + {0x586C, 0x000000C0}, + {0x586C, 0x000000B0}, + {0x586C, 0x000000A0}, + {0x586C, 0x00000090}, + {0x586C, 0x00000080}, + {0x586C, 0x00000070}, + {0x586C, 0x00000060}, + {0x586C, 0x00000050}, + {0x586C, 0x00000040}, + {0x586C, 0x00000030}, + {0x586C, 0x00000020}, + {0x586C, 0x00000010}, + {0x586C, 0x00000000}, + {0x786C, 0x000000F0}, + {0x786C, 0x000000E0}, + {0x786C, 0x000000D0}, + {0x786C, 0x000000C0}, + {0x786C, 0x000000B0}, + {0x786C, 0x000000A0}, + {0x786C, 0x00000090}, + {0x786C, 0x00000080}, + {0x786C, 0x00000070}, + {0x786C, 0x00000060}, + {0x786C, 0x00000050}, + {0x786C, 0x00000040}, + {0x786C, 0x00000030}, + {0x786C, 0x00000020}, + {0x786C, 0x00000010}, + {0x786C, 0x00000000}, + {0xC0D4, 0x4486888C}, + {0xC0D8, 0xC6BA10E1}, + {0xC0DC, 0x30C52868}, + {0xC0E0, 0x05008128}, + {0xC0E4, 0x0000A72B}, + {0xC1D4, 0x4486888C}, + {0xC1D8, 0xC6BA10E1}, + {0xC1DC, 0x30C52868}, + {0xC1E0, 0x05008128}, + {0xC1E4, 0x0000A72B}, + {0xC0EC, 0x00000000}, + {0xC0E4, 0x0000272B}, + {0xC1EC, 0x00000000}, + {0xC1E4, 0x0000272B}, + {0x334, 0xFFFFFFFF}, + {0x33C, 0x55000000}, + {0x340, 0x00005555}, + {0x724, 0x00111200}, + {0x5868, 0xA9550000}, + {0x5870, 0x33221100}, + {0x5874, 0x77665544}, + {0x5878, 0xBBAA9988}, + {0x587C, 0xFFEEDDCC}, + {0x5880, 0x76543210}, + {0x5884, 0xFEDCBA98}, + {0x5888, 0x00000000}, + {0x588C, 0x00000000}, + {0x5894, 0x00000008}, + {0x7868, 0xA9550000}, + {0x7870, 0x33221100}, + {0x7874, 0x77665544}, + {0x7878, 0xBBAA9988}, + {0x787C, 0xFFEEDDCC}, + {0x7880, 0x76543210}, + {0x7884, 0xFEDCBA98}, + {0x7888, 0x00000000}, + {0x788C, 0x00000000}, + {0x7894, 0x00000008}, + {0x650, 0x00200888}, + {0x710, 0xF3810000}, + {0x020, 0x0000F381}, + {0x024, 0x0000F381}, + {0x000, 0xC580801E}, + {0xC70, 0x00000400}, + {0x980, 0x10002250}, + {0x988, 0x3C3C4107}, + {0x994, 0x00000010}, + {0x2994, 0x00000010}, + {0x000, 0x0580801F}, + {0x240C, 0x00000000}, + {0x640, 0x140A141E}, + {0x640, 0x1414141E}, + {0x640, 0x1414141E}, + {0x644, 0x3414283C}, + {0x644, 0x3425283C}, + {0x644, 0x3426283C}, + {0x2640, 0x140A141E}, + {0x2640, 0x1414141E}, + {0x2640, 0x1414141E}, + {0x2644, 0x3414283C}, + {0x2644, 0x3425283C}, + {0x2644, 0x3425183C}, + {0x2300, 0x02748790}, + {0x2304, 0x00558670}, + {0x2308, 0x002883F0}, + {0x230C, 0x00090120}, + {0x2310, 0x00000000}, + {0x2314, 0x06000000}, + {0x2318, 0x00000000}, + {0x231C, 0x00000000}, + {0x2320, 0x03020100}, + {0x2324, 0x07060504}, + {0x2328, 0x0B0A0908}, + {0x232C, 0x0F0E0D0C}, + {0x2330, 0x13121110}, + {0x2334, 0x17161514}, + {0x2338, 0x0C700022}, + {0x233C, 0x0A0529D0}, + {0x2340, 0x000529D0}, + {0x2344, 0x0006318A}, + {0x2348, 0xB7E6318A}, + {0x234C, 0x80039C00}, + {0x2350, 0x80039C00}, + {0x2354, 0x0005298F}, + {0x2358, 0x0015296E}, + {0x235C, 0x0C07FC31}, + {0x2360, 0x0219AAAE}, + {0x2364, 0xE4F624C3}, + {0x2368, 0x53626F15}, + {0x236C, 0x48000000}, + {0x2370, 0x48000000}, + {0x2374, 0x07540000}, + {0x2378, 0x202401B9}, + {0x237C, 0x00F7000E}, + {0x2380, 0x0F0A1111}, + {0x2384, 0x30D9000F}, + {0x2388, 0x0200EA02}, + {0x238C, 0x003CB061}, + {0x2390, 0x69C00000}, + {0x2394, 0x00000000}, + {0x2398, 0x000000F0}, + {0x239C, 0x0001FFFF}, + {0x23A0, 0x00C80064}, + {0x23A4, 0x0190012C}, + {0x23A8, 0x001917BE}, + {0x23AC, 0x0B30880C}, + {0x23B0, 0x9281CE00}, + {0x23B4, 0x7F027C00}, + {0x704, 0x601E0102}, + {0x704, 0x601E0102}, + {0x5864, 0x080801FF}, + {0x7864, 0x080801FF}, + {0xC60, 0x017FFFF3}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8088, 0x007F0000}, + {0x81A4, 0x003F3A00}, + {0x81B4, 0x0100007F}, + {0x81C0, 0x0060010B}, + {0x81A0, 0x00000010}, + {0x8138, 0x00000002}, + {0x82A4, 0x003F3A00}, + {0x82B4, 0x0100007F}, + {0x82C0, 0x0060010B}, + {0x82A0, 0x00000010}, + {0x81A0, 0x00000010}, + {0x8238, 0x00000002}, + {0x8088, 0x00000000}, + {0x8020, 0x00000000}, + {0x8120, 0x00000000}, + {0x8220, 0x00000000}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0xC70, 0x00000600}, + {0xC70, 0x00000660}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8120, 0x10000000}, + {0x8120, 0x10030000}, + {0x8124, 0x00000F0F}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8220, 0x10000000}, + {0x8220, 0x10030000}, + {0x704, 0x601E0100}, + {0x5864, 0x100801FF}, + {0x7864, 0x100801FF}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0x58D4, 0x7401FE00}, + {0x78D4, 0x7401FE00}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x704, 0x601E0102}, + {0xC7C, 0x0020BFE0}, + {0x58C0, 0x00FE0000}, + {0x58FC, 0x00000000}, + {0x566C, 0x00000005}, + {0x566C, 0x00001005}, + {0x78C0, 0x00FE0000}, + {0x78FC, 0x00000000}, + {0x700, 0x00000030}, + {0x704, 0x601E0102}, + {0x704, 0x601E0100}, + {0x704, 0x601E0502}, + {0x20FC, 0x00000000}, + {0x20F8, 0x00000000}, + {0x20F0, 0x00000000}, + {0x9C0, 0x00000001}, + {0x9C0, 0x00000000}, + {0x9C0, 0x00000001}, + {0x9C0, 0x00000000}, + {0x4AE8, 0x00000744}, + {0x4AF0, 0x00000744}, + {0x1010, 0x00000010}, + {0x3010, 0x00000010}, + {0x4AD4, 0x00000040}, + {0x4AE0, 0x00000040}, + {0x4AE4, 0x0079E99E}, + {0x4AEC, 0x0079E99E}, + {0x300, 0xF30CE31C}, + {0x304, 0x13EF1F19}, + {0x308, 0x0C0CF3F3}, + {0x30C, 0x0C0C0C0C}, + {0x310, 0x80496000}, + {0x314, 0x0041E000}, + {0x318, 0x20022042}, + {0x31C, 0x20448009}, + {0x320, 0x00010031}, + {0x324, 0xE000E000}, + {0x328, 0xE000E000}, + {0x32C, 0xE000E000}, + {0x12BC, 0x10104041}, + {0x12C0, 0x14411111}, + {0x32BC, 0x10104041}, + {0x32C0, 0x14411111}, + {0x010, 0x0005FFFF}, + {0x028, 0x0000F381}, + {0x02C, 0x0000F381}, + {0x620, 0x00141230}, + {0x704, 0x601C05FF}, + {0x720, 0x20000000}, + {0x738, 0x004100CC}, + {0x12A0, 0x24903056}, + {0x12AC, 0x12333121}, + {0x12B8, 0x30020000}, + {0x12E4, 0x30D52A68}, + {0x2000, 0x50BBBF04}, + {0x32A0, 0x24903056}, + {0x32AC, 0x12333121}, + {0x32B8, 0x30020000}, + {0x32E4, 0x30D52A68}, + {0x5800, 0x03FF807F}, + {0x5804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7800, 0x03FF807F}, + {0x7804, 0x04237040}, + {0x7808, 0x04237040}, + {0x73C, 0x00000002}, + {0x74C, 0x00000001}, + {0x748, 0x00000002}, + {0x5818, 0x082C1800}, + {0x7818, 0x082C1800}, + {0x624, 0x0101030A}, + {0xC14, 0x85010000}, + {0xDD4, 0x00000001}, + {0x241C, 0x00000001}, + {0x1200, 0x00010142}, + {0x3200, 0x00010142}, + {0xC0F8, 0x00000001}, + {0xC1F8, 0x00000001}, + {0x35C, 0x000004C4}, + {0x0F0, 0x00000002}, + {0x0F4, 0x00000028}, + {0x0F8, 0x20220408}, +}; + +static const struct rtw89_reg2_def rtw89_8852b_phy_bb_reg_gain[] = { + {0x000, 0x18FBDDB7}, + {0x001, 0x006F5436}, + {0x002, 0x00004F31}, + {0x100, 0x1BFEE0B7}, + {0x101, 0x006C5238}, + {0x102, 0x00005031}, + {0x10000, 0x07E6C39E}, + {0x10001, 0x00654526}, + {0x10002, 0x00006750}, + {0x10100, 0x09E9C69F}, + {0x10101, 0x00674627}, + {0x10102, 0x00006750}, + {0x20000, 0x06E8C49F}, + {0x20001, 0x00654526}, + {0x20002, 0x00006750}, + {0x20100, 0x07E9C6A0}, + {0x20101, 0x00674728}, + {0x20102, 0x00006850}, + {0x30000, 0x04E5C39D}, + {0x30001, 0x00634325}, + {0x30002, 0x00006750}, + {0x30100, 0x06E9C69F}, + {0x30101, 0x00654527}, + {0x30102, 0x00006750}, + {0x1000000, 0x000000F4}, + {0x1000010, 0x000000F8}, + {0x1000011, 0x0000F8F8}, + {0x1000100, 0x000000F8}, + {0x1000110, 0x00000000}, + {0x1000111, 0x00000000}, + {0x1010000, 0x000000F4}, + {0x1010010, 0x000000F8}, + {0x1010011, 0x0000F8F8}, + {0x1010020, 0x000000F8}, + {0x1010021, 0x0808E8E8}, + {0x1010029, 0x0000F8F8}, + {0x1010100, 0x000000F4}, + {0x1010110, 0x000000F8}, + {0x1010111, 0x0000F8F8}, + {0x1010120, 0x000000F8}, + {0x1010121, 0x0808E8E8}, + {0x1010129, 0x0000F8F8}, + {0x1020000, 0x000000F4}, + {0x1020010, 0x000000F8}, + {0x1020011, 0x0000F8F8}, + {0x1020020, 0x000000F8}, + {0x1020021, 0x0808E8E8}, + {0x1020029, 0x0000F8F8}, + {0x1020100, 0x000000F4}, + {0x1020110, 0x000000F8}, + {0x1020111, 0x0000F8F8}, + {0x1020120, 0x000000F8}, + {0x1020121, 0x0808E8E8}, + {0x1020129, 0x0000F8F8}, + {0x1030000, 0x000000F4}, + {0x1030010, 0x000000F8}, + {0x1030011, 0x0000F8F8}, + {0x1030020, 0x000000F8}, + {0x1030021, 0x0808E8E8}, + {0x1030029, 0x0000F8F8}, + {0x1030100, 0x000000F4}, + {0x1030110, 0x000000F8}, + {0x1030111, 0x0000F8F8}, + {0x1030120, 0x000000F8}, + {0x1030121, 0x0808E8E8}, + {0x1030129, 0x0000F8F8}, +}; + +static const struct rtw89_reg2_def rtw89_8852b_phy_radioa_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0010001, 0x00000002}, + {0xF0020001, 0x00000003}, + {0xF0030001, 0x00000004}, + {0xF0040001, 0x00000005}, + {0xF0050001, 0x00000006}, + {0xF0060001, 0x00000007}, + {0xF0070001, 0x00000008}, + {0xF0080001, 0x00000009}, + {0xF0290001, 0x0000000A}, + {0xF02B0001, 0x0000000B}, + {0x005, 0x00000000}, + {0x000, 0x00030000}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x000, 0x00033C00}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x011, 0x00014073}, + {0x067, 0x00000070}, + {0x059, 0x000A0000}, + {0x066, 0x00000100}, + {0x057, 0x0000D589}, + {0x05A, 0x0007FFFF}, + {0x0A4, 0x0006FF12}, + {0x043, 0x00005000}, + {0x0E1, 0x00000001}, + {0x0DD, 0x000001A0}, + {0x0CA, 0x00002000}, + {0x0D3, 0x00000003}, + {0x0B3, 0x0004EFE0}, + {0x0B4, 0x0007C07E}, + {0x0B5, 0x0003A701}, + {0x0B6, 0x000581E0}, + {0x0B7, 0x00001A0A}, + {0x0BB, 0x000C7000}, + {0x0ED, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x00000543}, + {0x033, 0x00000001}, + {0x03F, 0x00000542}, + {0x033, 0x00000002}, + {0x03F, 0x00000541}, + {0x033, 0x00000003}, + {0x03F, 0x00000521}, + {0x033, 0x00000004}, + {0x03F, 0x00000343}, + {0x033, 0x00000005}, + {0x03F, 0x00000342}, + {0x033, 0x00000006}, + {0x03F, 0x00000341}, + {0x033, 0x00000007}, + {0x03F, 0x00000321}, + {0x033, 0x00000008}, + {0x03F, 0x000005C3}, + {0x033, 0x00000009}, + {0x03F, 0x000005C2}, + {0x033, 0x0000000A}, + {0x03F, 0x000005C1}, + {0x033, 0x0000000B}, + {0x03F, 0x000005A1}, + {0x033, 0x0000000C}, + {0x03F, 0x000002C3}, + {0x033, 0x0000000D}, + {0x03F, 0x000002C2}, + {0x033, 0x0000000E}, + {0x03F, 0x000002C1}, + {0x033, 0x0000000F}, + {0x03F, 0x000002A1}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00002000}, + {0x033, 0x00000002}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000006}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x0ED, 0x00000000}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000004}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x08F, 0x000D0F7A}, + {0x0EF, 0x00080000}, + {0x033, 0x00000008}, + {0x03E, 0x000000C4}, + {0x03F, 0x000034C0}, + {0x033, 0x0000000A}, + {0x03E, 0x000000C4}, + {0x03F, 0x000035D0}, + {0x033, 0x0000000B}, + {0x03E, 0x000000C4}, + {0x03F, 0x000035C8}, + {0x033, 0x0000008A}, + {0x03E, 0x000000C4}, + {0x03F, 0x000035F7}, + {0x0EF, 0x00000000}, + {0x08D, 0x000CC800}, + {0x0EF, 0x00004000}, + {0x033, 0x00000006}, + {0x03F, 0x00000700}, + {0x033, 0x00000005}, + {0x03F, 0x00090600}, + {0x033, 0x00000004}, + {0x03F, 0x000A3500}, + {0x033, 0x00000003}, + {0x03F, 0x000A3400}, + {0x033, 0x00000002}, + {0x03F, 0x00008B00}, + {0x033, 0x00000001}, + {0x03F, 0x00001B00}, + {0x033, 0x00000000}, + {0x03F, 0x00003A00}, + {0x033, 0x0000000F}, + {0x03F, 0x00000700}, + {0x033, 0x0000000E}, + {0x03F, 0x00000700}, + {0x033, 0x0000000D}, + {0x03F, 0x00090600}, + {0x033, 0x0000000C}, + {0x03F, 0x000A3500}, + {0x033, 0x0000000B}, + {0x03F, 0x000A3400}, + {0x033, 0x0000000A}, + {0x03F, 0x00008B00}, + {0x033, 0x00000009}, + {0x03F, 0x00001B00}, + {0x033, 0x00000008}, + {0x03F, 0x00003A00}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000000}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000001}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000002}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000003}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000004}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000005}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000006}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000008}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000009}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x0000000A}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x0000000B}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x0000000C}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x0000000D}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x0000000E}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000010}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000011}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000012}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000013}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000014}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000015}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000016}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000020}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000021}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000022}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000023}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000024}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000025}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000026}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000028}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000029}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x0000002A}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x0000002B}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x0000002C}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x0000002D}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x0000002E}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000030}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000031}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000032}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000033}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000034}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000035}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000036}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x03F, 0x00004376}, + {0x033, 0x00000004}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x03F, 0x00004376}, + {0x033, 0x00000007}, + {0x03F, 0x00004376}, + {0x033, 0x00000008}, + {0x03F, 0x00004376}, + {0x033, 0x00000009}, + {0x03F, 0x00004376}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004396}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004396}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004396}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004396}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004396}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004386}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004396}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x067, 0x00008072}, + {0x0EF, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x00000ED5}, + {0x033, 0x00000002}, + {0x03F, 0x00000FC7}, + {0x033, 0x00000003}, + {0x03F, 0x00000783}, + {0x033, 0x00000004}, + {0x03F, 0x00000973}, + {0x033, 0x00000005}, + {0x03F, 0x00000762}, + {0x033, 0x00000006}, + {0x03F, 0x00000762}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023958}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026858}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026858}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00023A58}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0002C758}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000001}, + {0x03F, 0x00000003}, + {0x033, 0x00000002}, + {0x03F, 0x00000005}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x033, 0x00000004}, + {0x03F, 0x00000001}, + {0x033, 0x00000005}, + {0x03F, 0x00000003}, + {0x033, 0x00000006}, + {0x03F, 0x00000006}, + {0x033, 0x00000007}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00003000}, + {0x033, 0x00000001}, + {0x03F, 0x00003001}, + {0x033, 0x00000002}, + {0x03F, 0x00003003}, + {0x033, 0x00000003}, + {0x03F, 0x00003007}, + {0x033, 0x00000004}, + {0x03F, 0x0000300F}, + {0x033, 0x00000005}, + {0x03F, 0x0000310F}, + {0x033, 0x00000006}, + {0x03F, 0x0000330F}, + {0x033, 0x00000007}, + {0x03F, 0x0000330F}, + {0x033, 0x00000008}, + {0x03F, 0x00003000}, + {0x033, 0x00000009}, + {0x03F, 0x00003001}, + {0x033, 0x0000000A}, + {0x03F, 0x00003003}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003103}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00002307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000001}, + {0x03F, 0x00000003}, + {0x033, 0x00000002}, + {0x03F, 0x00000005}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03D, 0x00000078}, + {0x03E, 0x00080000}, + {0x03F, 0x00000000}, + {0x033, 0x00000005}, + {0x03D, 0x0000007B}, + {0x03E, 0x00020000}, + {0x03F, 0x00000000}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x0000017F}, + {0x033, 0x00000001}, + {0x03F, 0x0000017F}, + {0x033, 0x00000002}, + {0x03F, 0x0000017F}, + {0x033, 0x00000003}, + {0x03F, 0x0000007F}, + {0x033, 0x00000004}, + {0x03F, 0x0000007F}, + {0x033, 0x00000005}, + {0x03F, 0x0000007F}, + {0x033, 0x00000006}, + {0x03F, 0x0000007F}, + {0x033, 0x00000007}, + {0x03F, 0x0000007F}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06F, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x0EF, 0x00020000}, + {0x033, 0x00000000}, + {0x03F, 0x000005FF}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0xA0000000, 0x00000000}, + {0x094, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000088}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000089}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000090}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A2}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A3}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C2}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C3}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10033, 0x00000080}, + {0x1003F, 0x000001A9}, + {0x10033, 0x00000081}, + {0x1003F, 0x000001A3}, + {0x10033, 0x00000082}, + {0x1003F, 0x0000019D}, + {0x10033, 0x00000083}, + {0x1003F, 0x00000197}, + {0x10033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000088}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000089}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000090}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000091}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A0}, + {0x1003F, 0x000001A9}, + {0x10033, 0x000000A1}, + {0x1003F, 0x000001A3}, + {0x10033, 0x000000A2}, + {0x1003F, 0x0000019D}, + {0x10033, 0x000000A3}, + {0x1003F, 0x00000197}, + {0x10033, 0x000000A4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C0}, + {0x1003F, 0x000001A9}, + {0x10033, 0x000000C1}, + {0x1003F, 0x000001A3}, + {0x10033, 0x000000C2}, + {0x1003F, 0x0000019D}, + {0x10033, 0x000000C3}, + {0x1003F, 0x00000197}, + {0x10033, 0x000000C4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10033, 0x00000000}, + {0x1003F, 0x000000F6}, + {0x10033, 0x00000001}, + {0x1003F, 0x000000F3}, + {0x10033, 0x00000002}, + {0x1003F, 0x000000F0}, + {0x10033, 0x00000003}, + {0x1003F, 0x000000ED}, + {0x10033, 0x00000004}, + {0x1003F, 0x000000EA}, + {0x10033, 0x00000005}, + {0x1003F, 0x000000E7}, + {0x10033, 0x00000006}, + {0x1003F, 0x000000A6}, + {0x10033, 0x00000007}, + {0x1003F, 0x000000A3}, + {0x10033, 0x00000008}, + {0x1003F, 0x00000063}, + {0x10033, 0x00000009}, + {0x1003F, 0x00000060}, + {0x10033, 0x0000000A}, + {0x1003F, 0x00000023}, + {0x10033, 0x0000000B}, + {0x1003F, 0x00000020}, + {0x10033, 0x0000000C}, + {0x1003F, 0x0000001D}, + {0x10033, 0x0000000D}, + {0x1003F, 0x0000001A}, + {0x10033, 0x0000000E}, + {0x1003F, 0x00000017}, + {0x10033, 0x0000000F}, + {0x1003F, 0x00000014}, + {0x10033, 0x00000010}, + {0x1003F, 0x00000011}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10033, 0x00000000}, + {0x1003F, 0x000001AF}, + {0x10033, 0x00000001}, + {0x1003F, 0x000001A9}, + {0x10033, 0x00000002}, + {0x1003F, 0x000001A3}, + {0x10033, 0x00000003}, + {0x1003F, 0x0000019D}, + {0x10033, 0x00000004}, + {0x1003F, 0x00000197}, + {0x10033, 0x00000005}, + {0x1003F, 0x0000015F}, + {0x10033, 0x00000006}, + {0x1003F, 0x00000159}, + {0x10033, 0x00000007}, + {0x1003F, 0x0000011F}, + {0x10033, 0x00000008}, + {0x1003F, 0x00000119}, + {0x10033, 0x00000009}, + {0x1003F, 0x000000DF}, + {0x10033, 0x0000000A}, + {0x1003F, 0x000000D9}, + {0x10033, 0x0000000B}, + {0x1003F, 0x0000009F}, + {0x10033, 0x0000000C}, + {0x1003F, 0x00000099}, + {0x10033, 0x0000000D}, + {0x1003F, 0x0000005F}, + {0x10033, 0x0000000E}, + {0x1003F, 0x00000059}, + {0x10033, 0x0000000F}, + {0x1003F, 0x0000001F}, + {0x10033, 0x00000010}, + {0x1003F, 0x00000019}, + {0x10033, 0x00000011}, + {0x1003F, 0x00000013}, + {0x100EE, 0x00000000}, + {0x10005, 0x00000001}, + {0x09F, 0x00000032}, +}; + +static const struct rtw89_reg2_def rtw89_8852b_phy_radiob_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0010001, 0x00000002}, + {0xF0020001, 0x00000003}, + {0xF0030001, 0x00000004}, + {0xF0040001, 0x00000005}, + {0xF0050001, 0x00000006}, + {0xF0060001, 0x00000007}, + {0xF0070001, 0x00000008}, + {0xF0080001, 0x00000009}, + {0xF0290001, 0x0000000A}, + {0xF02B0001, 0x0000000B}, + {0x005, 0x00000000}, + {0x000, 0x00030000}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x000, 0x00033C00}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x011, 0x00014073}, + {0x067, 0x00000070}, + {0x059, 0x000A0000}, + {0x066, 0x00000100}, + {0x05A, 0x0007F000}, + {0x0A4, 0x0006FF12}, + {0x043, 0x00005000}, + {0x0E1, 0x00000001}, + {0x0DD, 0x000001A0}, + {0x0CA, 0x00002000}, + {0x0D3, 0x00000003}, + {0x0B3, 0x0004EFE0}, + {0x0B4, 0x0007C03E}, + {0x0B5, 0x0003A201}, + {0x0BB, 0x000C7000}, + {0x0ED, 0x00002000}, + {0x033, 0x00000002}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000006}, + {0x03D, 0x0004A883}, + {0x03E, 0x00000000}, + {0x03F, 0x00000001}, + {0x0ED, 0x00000000}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000004}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x08F, 0x000D0F7A}, + {0x0EF, 0x00080000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D30}, + {0xA0000000, 0x00000000}, + {0x03E, 0x000000C4}, + {0x03F, 0x000034C0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D74}, + {0xA0000000, 0x00000000}, + {0x03E, 0x000000C4}, + {0x03F, 0x000035D0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D72}, + {0xA0000000, 0x00000000}, + {0x03E, 0x000000C4}, + {0x03F, 0x000035C8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000008A}, + {0x03E, 0x00000031}, + {0x03F, 0x00000D7D}, + {0x0EF, 0x00000000}, + {0x08D, 0x000CC800}, + {0x0EF, 0x00004000}, + {0x033, 0x00000007}, + {0x03F, 0x00000700}, + {0x033, 0x00000006}, + {0x03F, 0x00000700}, + {0x033, 0x00000005}, + {0x03F, 0x00090600}, + {0x033, 0x00000004}, + {0x03F, 0x000A3500}, + {0x033, 0x00000003}, + {0x03F, 0x000A3400}, + {0x033, 0x00000002}, + {0x03F, 0x00008B00}, + {0x033, 0x00000001}, + {0x03F, 0x00001B00}, + {0x033, 0x00000000}, + {0x03F, 0x00003A00}, + {0x033, 0x0000000F}, + {0x03F, 0x00000700}, + {0x033, 0x0000000E}, + {0x03F, 0x00000700}, + {0x033, 0x0000000D}, + {0x03F, 0x00090600}, + {0x033, 0x0000000C}, + {0x03F, 0x000A3500}, + {0x033, 0x0000000B}, + {0x03F, 0x000A3400}, + {0x033, 0x0000000A}, + {0x03F, 0x00008B00}, + {0x033, 0x00000009}, + {0x03F, 0x00001B00}, + {0x033, 0x00000008}, + {0x03F, 0x00003A00}, + {0x033, 0x00000017}, + {0x03F, 0x00000705}, + {0x033, 0x00000016}, + {0x03F, 0x00000705}, + {0x033, 0x00000015}, + {0x03F, 0x00090605}, + {0x033, 0x00000014}, + {0x03F, 0x000A3505}, + {0x033, 0x00000013}, + {0x03F, 0x000A3405}, + {0x033, 0x00000012}, + {0x03F, 0x00008B05}, + {0x033, 0x00000011}, + {0x03F, 0x00001B05}, + {0x033, 0x00000010}, + {0x03F, 0x00003A05}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000005}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000015}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000005}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000007}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000000}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000001}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000002}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000003}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000004}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000005}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000006}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000008}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000009}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x0000000A}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x0000000B}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x0000000C}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x0000000D}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x0000000E}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000010}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000011}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000012}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000013}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000014}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000015}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000016}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000020}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000021}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000022}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000023}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000024}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000025}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000026}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000028}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000029}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x0000002A}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x0000002B}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x0000002C}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x0000002D}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x0000002E}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x033, 0x00000030}, + {0x03E, 0x00004FC0}, + {0x03F, 0x00000087}, + {0x033, 0x00000031}, + {0x03E, 0x000046C0}, + {0x03F, 0x00000087}, + {0x033, 0x00000032}, + {0x03E, 0x00004240}, + {0x03F, 0x00000087}, + {0x033, 0x00000033}, + {0x03E, 0x00008010}, + {0x03F, 0x00000147}, + {0x033, 0x00000034}, + {0x03E, 0x0000A048}, + {0x03F, 0x0000004F}, + {0x033, 0x00000035}, + {0x03E, 0x0000A030}, + {0x03F, 0x0000005F}, + {0x033, 0x00000036}, + {0x03E, 0x0000A000}, + {0x03F, 0x0000009F}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000000}, + {0x03F, 0x00004346}, + {0x033, 0x00000001}, + {0x03F, 0x00004346}, + {0x033, 0x00000002}, + {0x03F, 0x00004346}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03F, 0x00004346}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004317}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004376}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000043A6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004347}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004366}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00004346}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00004366}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x03F, 0x00004386}, + {0x033, 0x00000024}, + {0x03F, 0x00004386}, + {0x033, 0x00000025}, + {0x03F, 0x00004386}, + {0x033, 0x00000026}, + {0x03F, 0x00004386}, + {0x033, 0x00000027}, + {0x03F, 0x00004386}, + {0x0EF, 0x00000000}, + {0x067, 0x00008072}, + {0x0EF, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x00000ED5}, + {0x033, 0x00000002}, + {0x03F, 0x00000FC5}, + {0x033, 0x00000003}, + {0x03F, 0x00000A93}, + {0x033, 0x00000004}, + {0x03F, 0x00000973}, + {0x033, 0x00000005}, + {0x03F, 0x00000761}, + {0x033, 0x00000006}, + {0x03F, 0x00000761}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000001}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000002}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000003}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000005}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000006}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020758}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x03E, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000020}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000023}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000033}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00026458}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022658}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00026458}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00022858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003B}, + {0x03E, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00027558}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00020858}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00027558}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000001}, + {0x03F, 0x00000003}, + {0x033, 0x00000002}, + {0x03F, 0x00000005}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x033, 0x00000004}, + {0x03F, 0x00000001}, + {0x033, 0x00000005}, + {0x03F, 0x00000003}, + {0x033, 0x00000006}, + {0x03F, 0x00000006}, + {0x033, 0x00000007}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00003000}, + {0x033, 0x00000001}, + {0x03F, 0x00003001}, + {0x033, 0x00000002}, + {0x03F, 0x00003003}, + {0x033, 0x00000003}, + {0x03F, 0x00003007}, + {0x033, 0x00000004}, + {0x03F, 0x0000300F}, + {0x033, 0x00000005}, + {0x03F, 0x0000310F}, + {0x033, 0x00000006}, + {0x03F, 0x0000330F}, + {0x033, 0x00000007}, + {0x03F, 0x0000330F}, + {0x033, 0x00000008}, + {0x03F, 0x00003000}, + {0x033, 0x00000009}, + {0x03F, 0x00003001}, + {0x033, 0x0000000A}, + {0x03F, 0x00003003}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003007}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003103}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003107}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00003307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00003307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00002307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00001307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000307}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00000000}, + {0x0EE, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x00000001}, + {0x033, 0x00000001}, + {0x03F, 0x00000003}, + {0x033, 0x00000002}, + {0x03F, 0x00000005}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EC, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x0EC, 0x00000100}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000004}, + {0x03D, 0x00000078}, + {0x03E, 0x00080000}, + {0x03F, 0x00000000}, + {0x033, 0x00000005}, + {0x03D, 0x0000007B}, + {0x03E, 0x00020000}, + {0x03F, 0x00000000}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x0000013F}, + {0x033, 0x00000003}, + {0x03F, 0x000000FB}, + {0x033, 0x00000004}, + {0x03F, 0x000000FB}, + {0x033, 0x00000005}, + {0x03F, 0x000000FB}, + {0x033, 0x00000006}, + {0x03F, 0x000000FB}, + {0x033, 0x00000007}, + {0x03F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x0EF, 0x00000400}, + {0x033, 0x00000000}, + {0x03F, 0x000001FF}, + {0x033, 0x00000001}, + {0x03F, 0x000001FF}, + {0x033, 0x00000002}, + {0x03F, 0x000001F7}, + {0x033, 0x00000003}, + {0x03F, 0x000000FF}, + {0x033, 0x00000004}, + {0x03F, 0x000000FF}, + {0x033, 0x00000005}, + {0x03F, 0x000000FF}, + {0x033, 0x00000006}, + {0x03F, 0x000000FF}, + {0x033, 0x00000007}, + {0x03F, 0x000000FF}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x0000017F}, + {0x033, 0x00000001}, + {0x03F, 0x0000017F}, + {0x033, 0x00000002}, + {0x03F, 0x0000017F}, + {0x033, 0x00000003}, + {0x03F, 0x0000007F}, + {0x033, 0x00000004}, + {0x03F, 0x0000007F}, + {0x033, 0x00000005}, + {0x03F, 0x0000007F}, + {0x033, 0x00000006}, + {0x03F, 0x0000007F}, + {0x033, 0x00000007}, + {0x03F, 0x0000007F}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06F, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x0EF, 0x00020000}, + {0x033, 0x00000000}, + {0x03F, 0x000005FF}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x094, 0x000000FC}, + {0xA0000000, 0x00000000}, + {0x094, 0x000001FC}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10033, 0x00000080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000081}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000082}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000083}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000088}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000089}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000090}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A2}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A3}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000FB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C2}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F5}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000F0}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C3}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000F2}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000ED}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000EA}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000EC}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000E7}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000AB}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A6}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000A8}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000A3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000068}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000063}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000065}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000060}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000002B}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000026}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000028}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000023}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000025}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000022}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000001A}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000017}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000014}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10033, 0x00000080}, + {0x1003F, 0x000001A9}, + {0x10033, 0x00000081}, + {0x1003F, 0x000001A3}, + {0x10033, 0x00000082}, + {0x1003F, 0x0000019D}, + {0x10033, 0x00000083}, + {0x1003F, 0x00000197}, + {0x10033, 0x00000084}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000085}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000086}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000087}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000088}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000089}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x0000008F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000090}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x00000091}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A0}, + {0x1003F, 0x000001A9}, + {0x10033, 0x000000A1}, + {0x1003F, 0x000001A3}, + {0x10033, 0x000000A2}, + {0x1003F, 0x0000019D}, + {0x10033, 0x000000A3}, + {0x1003F, 0x00000197}, + {0x10033, 0x000000A4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000A9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000B1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C0}, + {0x1003F, 0x000001A9}, + {0x10033, 0x000000C1}, + {0x1003F, 0x000001A3}, + {0x10033, 0x000000C2}, + {0x1003F, 0x0000019D}, + {0x10033, 0x000000C3}, + {0x1003F, 0x00000197}, + {0x10033, 0x000000C4}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000158}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000191}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C5}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000011F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000018B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000119}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000014D}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000010B}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C8}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000DF}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000C9}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000009F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D9}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CA}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x000000D3}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CB}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000005F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000099}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000093}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CD}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000059}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000053}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000CF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000019}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D0}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x00000013}, + {0xB0000000, 0x00000000}, + {0x10033, 0x000000D1}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x1003F, 0x00000007}, + {0xA0000000, 0x00000000}, + {0x1003F, 0x0000000D}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10033, 0x00000000}, + {0x1003F, 0x000000F6}, + {0x10033, 0x00000001}, + {0x1003F, 0x000000F3}, + {0x10033, 0x00000002}, + {0x1003F, 0x000000F0}, + {0x10033, 0x00000003}, + {0x1003F, 0x000000ED}, + {0x10033, 0x00000004}, + {0x1003F, 0x000000EA}, + {0x10033, 0x00000005}, + {0x1003F, 0x000000E7}, + {0x10033, 0x00000006}, + {0x1003F, 0x000000A6}, + {0x10033, 0x00000007}, + {0x1003F, 0x000000A3}, + {0x10033, 0x00000008}, + {0x1003F, 0x00000063}, + {0x10033, 0x00000009}, + {0x1003F, 0x00000060}, + {0x10033, 0x0000000A}, + {0x1003F, 0x00000023}, + {0x10033, 0x0000000B}, + {0x1003F, 0x00000020}, + {0x10033, 0x0000000C}, + {0x1003F, 0x0000001D}, + {0x10033, 0x0000000D}, + {0x1003F, 0x0000001A}, + {0x10033, 0x0000000E}, + {0x1003F, 0x00000017}, + {0x10033, 0x0000000F}, + {0x1003F, 0x00000014}, + {0x10033, 0x00000010}, + {0x1003F, 0x00000011}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x10033, 0x00000000}, + {0x1003F, 0x000001AF}, + {0x10033, 0x00000001}, + {0x1003F, 0x000001A9}, + {0x10033, 0x00000002}, + {0x1003F, 0x000001A3}, + {0x10033, 0x00000003}, + {0x1003F, 0x0000019D}, + {0x10033, 0x00000004}, + {0x1003F, 0x00000197}, + {0x10033, 0x00000005}, + {0x1003F, 0x0000015F}, + {0x10033, 0x00000006}, + {0x1003F, 0x00000159}, + {0x10033, 0x00000007}, + {0x1003F, 0x0000011F}, + {0x10033, 0x00000008}, + {0x1003F, 0x00000119}, + {0x10033, 0x00000009}, + {0x1003F, 0x000000DF}, + {0x10033, 0x0000000A}, + {0x1003F, 0x000000D9}, + {0x10033, 0x0000000B}, + {0x1003F, 0x0000009F}, + {0x10033, 0x0000000C}, + {0x1003F, 0x00000099}, + {0x10033, 0x0000000D}, + {0x1003F, 0x0000005F}, + {0x10033, 0x0000000E}, + {0x1003F, 0x00000059}, + {0x10033, 0x0000000F}, + {0x1003F, 0x0000001F}, + {0x10033, 0x00000010}, + {0x1003F, 0x00000019}, + {0x10033, 0x00000011}, + {0x1003F, 0x00000013}, + {0x100EE, 0x00000000}, + {0x10005, 0x00000001}, + {0x09F, 0x00000032}, +}; + +static const struct rtw89_reg2_def rtw89_8852b_phy_nctl_regs[] = { + {0x8000, 0x00000008}, + {0x8008, 0x00000000}, + {0x8004, 0xf0862966}, + {0x800c, 0x78000000}, + {0x8010, 0x88015000}, + {0x8014, 0x80010100}, + {0x8018, 0x10010100}, + {0x801c, 0xa210bc00}, + {0x8020, 0x000403e0}, + {0x8024, 0x00072160}, + {0x8028, 0x00180e00}, + {0x8030, 0x400000c0}, + {0x8034, 0x11000830}, + {0x8038, 0x00000009}, + {0x803c, 0x00000008}, + {0x8040, 0x00000046}, + {0x8044, 0x0010001f}, + {0x8048, 0xf0000003}, + {0x804c, 0x62ac6162}, + {0x8050, 0xf2acf162}, + {0x8054, 0x62ac6162}, + {0x8058, 0xf2acf162}, + {0x805c, 0x150c0b02}, + {0x8060, 0x150c0b02}, + {0x8064, 0x2aa00047}, + {0x8074, 0x80000000}, + {0x807c, 0x000000ee}, + {0x8088, 0x80000000}, + {0x8098, 0x0000ff00}, + {0x809c, 0x0000001f}, + {0x80a0, 0x00010300}, + {0x80b8, 0x00001000}, + {0x80b0, 0x00000000}, + {0x80d0, 0x00000000}, + {0x80ec, 0x00000002}, + {0x810c, 0x33112200}, + {0x8110, 0x33112200}, + {0x8114, 0x00000000}, + {0x8120, 0x10010000}, + {0x8124, 0x00000000}, + {0x812c, 0x0000c000}, + {0x8138, 0x40000000}, + {0x813c, 0x40000000}, + {0x8140, 0x00000000}, + {0x8144, 0x0b040b03}, + {0x8148, 0x0a050b04}, + {0x814c, 0x0a050b04}, + {0x8150, 0xe4e40000}, + {0x8158, 0xffffffff}, + {0x815c, 0xffffffff}, + {0x8160, 0xffffffff}, + {0x8164, 0xffffffff}, + {0x8168, 0xffffffff}, + {0x816c, 0x1fffffff}, + {0x81a0, 0x00000000}, + {0x81ac, 0x003f2e2e}, + {0x81b0, 0x003f2e2e}, + {0x81bc, 0x005b5b5b}, + {0x81c0, 0x005b5b5b}, + {0x81b4, 0x00600060}, + {0x81b8, 0x00600060}, + {0x81cc, 0x00000000}, + {0x81dc, 0x00000002}, + {0x81e0, 0x00000000}, + {0x81e4, 0x00000001}, + {0x820c, 0x33112200}, + {0x8210, 0x33112200}, + {0x8214, 0x00000000}, + {0x8220, 0x10010000}, + {0x8224, 0x00000000}, + {0x822c, 0x0000d000}, + {0x8238, 0x40000000}, + {0x823c, 0x40000000}, + {0x8240, 0x00000000}, + {0x8244, 0x0b040b03}, + {0x8248, 0x0a050b04}, + {0x824c, 0x0a050b04}, + {0x8250, 0xe4e40000}, + {0x8258, 0xffffffff}, + {0x825c, 0xffffffff}, + {0x8260, 0xffffffff}, + {0x8264, 0xffffffff}, + {0x8268, 0xffffffff}, + {0x826c, 0x1fffffff}, + {0x82a0, 0x00000000}, + {0x82ac, 0x003f2e2e}, + {0x82b0, 0x003f2e2e}, + {0x82bc, 0x005b5b5b}, + {0x82c0, 0x005b5b5b}, + {0x82b4, 0x00600060}, + {0x82b8, 0x00600060}, + {0x82cc, 0x00000000}, + {0x82dc, 0x00000002}, + {0x82e0, 0x00100000}, + {0x82e4, 0x00000001}, + {0x81d8, 0x00000001}, + {0x82d8, 0x00000001}, + {0x8d00, 0x00000000}, + {0x8d04, 0x00000000}, + {0x8d08, 0x00000000}, + {0x8d0c, 0x00000000}, + {0x8d10, 0x00000000}, + {0x8d14, 0x00000000}, + {0x8d18, 0x00000000}, + {0x8d1c, 0x00000000}, + {0x8d20, 0x00000000}, + {0x8d24, 0x00000000}, + {0x8d28, 0x00000000}, + {0x8d2c, 0x00000000}, + {0x8d30, 0x00000000}, + {0x8d34, 0x00000000}, + {0x8d38, 0x00000000}, + {0x8d3c, 0x00000000}, + {0x8d40, 0x00000000}, + {0x8d44, 0x00000000}, + {0x8d48, 0x00000000}, + {0x8d4c, 0x00000000}, + {0x8d50, 0x00000000}, + {0x8d54, 0x00000000}, + {0x8d58, 0x00000000}, + {0x8d5c, 0x00000000}, + {0x8d60, 0x00000000}, + {0x8d64, 0x00000000}, + {0x8d68, 0x00000000}, + {0x8d6c, 0x00000000}, + {0x8d70, 0x00000000}, + {0x8d74, 0x00000000}, + {0x8d78, 0x00000000}, + {0x8d7c, 0x00000000}, + {0x8d80, 0x00000000}, + {0x8d84, 0x00000000}, + {0x8d88, 0x00000000}, + {0x8d8c, 0x00000000}, + {0x8d90, 0x00000000}, + {0x8d94, 0x00000000}, + {0x8d98, 0x00000000}, + {0x8d9c, 0x00000000}, + {0x8da0, 0x00000000}, + {0x8da4, 0x00000000}, + {0x8da8, 0x00000000}, + {0x8dac, 0x00000000}, + {0x8db0, 0x00000000}, + {0x8db4, 0x00000000}, + {0x8db8, 0x00000000}, + {0x8dbc, 0x00000000}, + {0x8dc0, 0x00000000}, + {0x8dc4, 0x00000000}, + {0x8dc8, 0x00000000}, + {0x8dcc, 0x00000000}, + {0x8dd0, 0x00000000}, + {0x8dd4, 0x00000000}, + {0x8dd8, 0x00000000}, + {0x8ddc, 0x00000000}, + {0x8de0, 0x00000000}, + {0x8de4, 0x00000000}, + {0x8de8, 0x00000000}, + {0x8dec, 0x00000000}, + {0x8df0, 0x00000000}, + {0x8df4, 0x00000000}, + {0x8df8, 0x00000000}, + {0x8dfc, 0x00000000}, + {0x8e00, 0x00000000}, + {0x8e04, 0x00000000}, + {0x8e08, 0x00000000}, + {0x8e0c, 0x00000000}, + {0x8e10, 0x00000000}, + {0x8e14, 0x00000000}, + {0x8e18, 0x00000000}, + {0x8e1c, 0x00000000}, + {0x8e20, 0x00000000}, + {0x8e24, 0x00000000}, + {0x8e28, 0x00000000}, + {0x8e2c, 0x00000000}, + {0x8e30, 0x00000000}, + {0x8e34, 0x00000000}, + {0x8e38, 0x00000000}, + {0x8e3c, 0x00000000}, + {0x8e40, 0x00000000}, + {0x8e44, 0x00000000}, + {0x8e48, 0x00000000}, + {0x8e4c, 0x00000000}, + {0x8e50, 0x00000000}, + {0x8e54, 0x00000000}, + {0x8e58, 0x00000000}, + {0x8e5c, 0x00000000}, + {0x8e60, 0x00000000}, + {0x8e64, 0x00000000}, + {0x8e68, 0x00000000}, + {0x8e6c, 0x00000000}, + {0x8e70, 0x00000000}, + {0x8e74, 0x00000000}, + {0x8e78, 0x00000000}, + {0x8e7c, 0x00000000}, + {0x8e80, 0x00000000}, + {0x8e84, 0x00000000}, + {0x8e88, 0x00000000}, + {0x8e8c, 0x00000000}, + {0x8e90, 0x00000000}, + {0x8e94, 0x00000000}, + {0x8e98, 0x00000000}, + {0x8e9c, 0x00000000}, + {0x8ea0, 0x00000000}, + {0x8ea4, 0x00000000}, + {0x8ea8, 0x00000000}, + {0x8eac, 0x00000000}, + {0x8eb0, 0x00000000}, + {0x8eb4, 0x00000000}, + {0x8eb8, 0x00000000}, + {0x8ebc, 0x00000000}, + {0x8ec0, 0x00000000}, + {0x8ec4, 0x00000000}, + {0x8ec8, 0x00000000}, + {0x8ecc, 0x00000000}, + {0x8ed0, 0x00000000}, + {0x8ed4, 0x00000000}, + {0x8ed8, 0x00000000}, + {0x8edc, 0x00000000}, + {0x8ee0, 0x00000000}, + {0x8ee4, 0x00000000}, + {0x8ee8, 0x00000000}, + {0x8eec, 0x00000000}, + {0x8ef0, 0x00000000}, + {0x8ef4, 0x00000000}, + {0x8ef8, 0x00000000}, + {0x8efc, 0x00000000}, + {0x8f00, 0x00000000}, + {0x8f04, 0x00000000}, + {0x8f08, 0x00000000}, + {0x8f0c, 0x00000000}, + {0x8f10, 0x00000000}, + {0x8f14, 0x00000000}, + {0x8f18, 0x00000000}, + {0x8f1c, 0x00000000}, + {0x8f20, 0x00000000}, + {0x8f24, 0x00000000}, + {0x8f28, 0x00000000}, + {0x8f2c, 0x00000000}, + {0x8f30, 0x00000000}, + {0x8f34, 0x00000000}, + {0x8f38, 0x00000000}, + {0x8f3c, 0x00000000}, + {0x8f40, 0x00000000}, + {0x8f44, 0x00000000}, + {0x8f48, 0x00000000}, + {0x8f4c, 0x00000000}, + {0x8f50, 0x00000000}, + {0x8f54, 0x00000000}, + {0x8f58, 0x00000000}, + {0x8f5c, 0x00000000}, + {0x8f60, 0x00000000}, + {0x8f64, 0x00000000}, + {0x8f68, 0x00000000}, + {0x8f6c, 0x00000000}, + {0x8f70, 0x00000000}, + {0x8f74, 0x00000000}, + {0x8f78, 0x00000000}, + {0x8f7c, 0x00000000}, + {0x8f80, 0x00000000}, + {0x8f84, 0x00000000}, + {0x8f88, 0x00000000}, + {0x8f8c, 0x00000000}, + {0x8f90, 0x00000000}, + {0x8f94, 0x00000000}, + {0x8f98, 0x00000000}, + {0x8f9c, 0x00000000}, + {0x8fa0, 0x00000000}, + {0x8fa4, 0x00000000}, + {0x8fa8, 0x00000000}, + {0x8fac, 0x00000000}, + {0x8fb0, 0x00000000}, + {0x8fb4, 0x00000000}, + {0x8fb8, 0x00000000}, + {0x8fbc, 0x00000000}, + {0x8fc0, 0x00000000}, + {0x8fc4, 0x00000000}, + {0x8fc8, 0x00000000}, + {0x8fcc, 0x00000000}, + {0x8fd0, 0x00000000}, + {0x8fd4, 0x00000000}, + {0x8fd8, 0x00000000}, + {0x8fdc, 0x00000000}, + {0x8fe0, 0x00000000}, + {0x8fe4, 0x00000000}, + {0x8fe8, 0x00000000}, + {0x8fec, 0x00000000}, + {0x8ff0, 0x00000000}, + {0x8ff4, 0x00000000}, + {0x8ff8, 0x00000000}, + {0x8ffc, 0x00000000}, + {0x9000, 0x00000000}, + {0x9004, 0x00000000}, + {0x9008, 0x00000000}, + {0x900c, 0x00000000}, + {0x9010, 0x00000000}, + {0x9014, 0x00000000}, + {0x9018, 0x00000000}, + {0x901c, 0x00000000}, + {0x9020, 0x00000000}, + {0x9024, 0x00000000}, + {0x9028, 0x00000000}, + {0x902c, 0x00000000}, + {0x9030, 0x00000000}, + {0x9034, 0x00000000}, + {0x9038, 0x00000000}, + {0x903c, 0x00000000}, + {0x9040, 0x00000000}, + {0x9044, 0x00000000}, + {0x9048, 0x00000000}, + {0x904c, 0x00000000}, + {0x9050, 0x00000000}, + {0x9054, 0x00000000}, + {0x9058, 0x00000000}, + {0x905c, 0x00000000}, + {0x9060, 0x00000000}, + {0x9064, 0x00000000}, + {0x9068, 0x00000000}, + {0x906c, 0x00000000}, + {0x9070, 0x00000000}, + {0x9074, 0x00000000}, + {0x9078, 0x00000000}, + {0x907c, 0x00000000}, + {0x9080, 0x00000000}, + {0x9084, 0x00000000}, + {0x9088, 0x00000000}, + {0x908c, 0x00000000}, + {0x9090, 0x00000000}, + {0x9094, 0x00000000}, + {0x9098, 0x00000000}, + {0x909c, 0x00000000}, + {0x90a0, 0x00000000}, + {0x90a4, 0x00000000}, + {0x90a8, 0x00000000}, + {0x90ac, 0x00000000}, + {0x90b0, 0x00000000}, + {0x90b4, 0x00000000}, + {0x90b8, 0x00000000}, + {0x90bc, 0x00000000}, + {0x9100, 0x00000000}, + {0x9104, 0x00000000}, + {0x9108, 0x00000000}, + {0x910c, 0x00000000}, + {0x9110, 0x00000000}, + {0x9114, 0x00000000}, + {0x9118, 0x00000000}, + {0x911c, 0x00000000}, + {0x9120, 0x00000000}, + {0x9124, 0x00000000}, + {0x9128, 0x00000000}, + {0x912c, 0x00000000}, + {0x9130, 0x00000000}, + {0x9134, 0x00000000}, + {0x9138, 0x00000000}, + {0x913c, 0x00000000}, + {0x9140, 0x00000000}, + {0x9144, 0x00000000}, + {0x9148, 0x00000000}, + {0x914c, 0x00000000}, + {0x9150, 0x00000000}, + {0x9154, 0x00000000}, + {0x9158, 0x00000000}, + {0x915c, 0x00000000}, + {0x9160, 0x00000000}, + {0x9164, 0x00000000}, + {0x9168, 0x00000000}, + {0x916c, 0x00000000}, + {0x9170, 0x00000000}, + {0x9174, 0x00000000}, + {0x9178, 0x00000000}, + {0x917c, 0x00000000}, + {0x9180, 0x00000000}, + {0x9184, 0x00000000}, + {0x9188, 0x00000000}, + {0x918c, 0x00000000}, + {0x9190, 0x00000000}, + {0x9194, 0x00000000}, + {0x9198, 0x00000000}, + {0x919c, 0x00000000}, + {0x91a0, 0x00000000}, + {0x91a4, 0x00000000}, + {0x91a8, 0x00000000}, + {0x91ac, 0x00000000}, + {0x91b0, 0x00000000}, + {0x91b4, 0x00000000}, + {0x91b8, 0x00000000}, + {0x91bc, 0x00000000}, + {0x91c0, 0x00000000}, + {0x91c4, 0x00000000}, + {0x91c8, 0x00000000}, + {0x91cc, 0x00000000}, + {0x91d0, 0x00000000}, + {0x91d4, 0x00000000}, + {0x91d8, 0x00000000}, + {0x91dc, 0x00000000}, + {0x91e0, 0x00000000}, + {0x91e4, 0x00000000}, + {0x91e8, 0x00000000}, + {0x91ec, 0x00000000}, + {0x91f0, 0x00000000}, + {0x91f4, 0x00000000}, + {0x91f8, 0x00000000}, + {0x91fc, 0x00000000}, + {0x9200, 0x00000000}, + {0x9204, 0x00000000}, + {0x9208, 0x00000000}, + {0x920c, 0x00000000}, + {0x9210, 0x00000000}, + {0x9214, 0x00000000}, + {0x9218, 0x00000000}, + {0x921c, 0x00000000}, + {0x9220, 0x00000000}, + {0x9224, 0x00000000}, + {0x9228, 0x00000000}, + {0x922c, 0x00000000}, + {0x9230, 0x00000000}, + {0x9234, 0x00000000}, + {0x9238, 0x00000000}, + {0x923c, 0x00000000}, + {0x9240, 0x00000000}, + {0x9244, 0x00000000}, + {0x9248, 0x00000000}, + {0x924c, 0x00000000}, + {0x9250, 0x00000000}, + {0x9254, 0x00000000}, + {0x9258, 0x00000000}, + {0x925c, 0x00000000}, + {0x9260, 0x00000000}, + {0x9264, 0x00000000}, + {0x9268, 0x00000000}, + {0x926c, 0x00000000}, + {0x9270, 0x00000000}, + {0x9274, 0x00000000}, + {0x9278, 0x00000000}, + {0x927c, 0x00000000}, + {0x9280, 0x00000000}, + {0x9284, 0x00000000}, + {0x9288, 0x00000000}, + {0x928c, 0x00000000}, + {0x9290, 0x00000000}, + {0x9294, 0x00000000}, + {0x9298, 0x00000000}, + {0x929c, 0x00000000}, + {0x92a0, 0x00000000}, + {0x92a4, 0x00000000}, + {0x92a8, 0x00000000}, + {0x92ac, 0x00000000}, + {0x92b0, 0x00000000}, + {0x92b4, 0x00000000}, + {0x92b8, 0x00000000}, + {0x92bc, 0x00000000}, + {0x92c0, 0x00000000}, + {0x92c4, 0x00000000}, + {0x92c8, 0x00000000}, + {0x92cc, 0x00000000}, + {0x92d0, 0x00000000}, + {0x92d4, 0x00000000}, + {0x92d8, 0x00000000}, + {0x92dc, 0x00000000}, + {0x92e0, 0x00000000}, + {0x92e4, 0x00000000}, + {0x92e8, 0x00000000}, + {0x92ec, 0x00000000}, + {0x92f0, 0x00000000}, + {0x92f4, 0x00000000}, + {0x92f8, 0x00000000}, + {0x92fc, 0x00000000}, + {0x9300, 0x00000000}, + {0x9304, 0x00000000}, + {0x9308, 0x00000000}, + {0x930c, 0x00000000}, + {0x9310, 0x00000000}, + {0x9314, 0x00000000}, + {0x9318, 0x00000000}, + {0x931c, 0x00000000}, + {0x9320, 0x00000000}, + {0x9324, 0x00000000}, + {0x9328, 0x00000000}, + {0x932c, 0x00000000}, + {0x9330, 0x00000000}, + {0x9334, 0x00000000}, + {0x9338, 0x00000000}, + {0x933c, 0x00000000}, + {0x9340, 0x00000000}, + {0x9344, 0x00000000}, + {0x9348, 0x00000000}, + {0x934c, 0x00000000}, + {0x9350, 0x00000000}, + {0x9354, 0x00000000}, + {0x9358, 0x00000000}, + {0x935c, 0x00000000}, + {0x9360, 0x00000000}, + {0x9364, 0x00000000}, + {0x9368, 0x00000000}, + {0x936c, 0x00000000}, + {0x9370, 0x00000000}, + {0x9374, 0x00000000}, + {0x9378, 0x00000000}, + {0x937c, 0x00000000}, + {0x9380, 0x00000000}, + {0x9384, 0x00000000}, + {0x9388, 0x00000000}, + {0x938c, 0x00000000}, + {0x9390, 0x00000000}, + {0x9394, 0x00000000}, + {0x9398, 0x00000000}, + {0x939c, 0x00000000}, + {0x93a0, 0x00000000}, + {0x93a4, 0x00000000}, + {0x93a8, 0x00000000}, + {0x93ac, 0x00000000}, + {0x93b0, 0x00000000}, + {0x93b4, 0x00000000}, + {0x93b8, 0x00000000}, + {0x93bc, 0x00000000}, + {0x93c0, 0x00000000}, + {0x93c4, 0x00000000}, + {0x93c8, 0x00000000}, + {0x93cc, 0x00000000}, + {0x93d0, 0x00000000}, + {0x93d4, 0x00000000}, + {0x93d8, 0x00000000}, + {0x93dc, 0x00000000}, + {0x93e0, 0x00000000}, + {0x93e4, 0x00000000}, + {0x93e8, 0x00000000}, + {0x93ec, 0x00000000}, + {0x93f0, 0x00000000}, + {0x93f4, 0x00000000}, + {0x93f8, 0x00000000}, + {0x93fc, 0x00000000}, + {0x9400, 0x00000000}, + {0x9404, 0x00000000}, + {0x9408, 0x00000000}, + {0x940c, 0x00000000}, + {0x9410, 0x00000000}, + {0x9414, 0x00000000}, + {0x9418, 0x00000000}, + {0x941c, 0x00000000}, + {0x9420, 0x00000000}, + {0x9424, 0x00000000}, + {0x9428, 0x00000000}, + {0x942c, 0x00000000}, + {0x9430, 0x00000000}, + {0x9434, 0x00000000}, + {0x9438, 0x00000000}, + {0x943c, 0x00000000}, + {0x9440, 0x00000000}, + {0x9444, 0x00000000}, + {0x9448, 0x00000000}, + {0x944c, 0x00000000}, + {0x9450, 0x00000000}, + {0x9454, 0x00000000}, + {0x9458, 0x00000000}, + {0x945c, 0x00000000}, + {0x9460, 0x00000000}, + {0x9464, 0x00000000}, + {0x9468, 0x00000000}, + {0x946c, 0x00000000}, + {0x9470, 0x00000000}, + {0x9474, 0x00000000}, + {0x9478, 0x00000000}, + {0x947c, 0x00000000}, + {0x9480, 0x00000000}, + {0x9484, 0x00000000}, + {0x9488, 0x00000000}, + {0x948c, 0x00000000}, + {0x9490, 0x00000000}, + {0x9494, 0x00000000}, + {0x9498, 0x00000000}, + {0x949c, 0x00000000}, + {0x94a0, 0x00000000}, + {0x94a4, 0x00000000}, + {0x94a8, 0x00000000}, + {0x94ac, 0x00000000}, + {0x94b0, 0x00000000}, + {0x94b4, 0x00000000}, + {0x94b8, 0x00000000}, + {0x94bc, 0x00000000}, + {0xa220, 0x00000000}, + {0xa224, 0x00000000}, + {0xa228, 0x00000000}, + {0xa22c, 0x00000000}, + {0xa230, 0x00000000}, + {0xa234, 0x00000000}, + {0xa238, 0x00000000}, + {0xa23c, 0x00000000}, + {0xa240, 0x00000000}, + {0xa244, 0x00000000}, + {0xa248, 0x00000000}, + {0xa24c, 0x00000000}, + {0xa250, 0x00000000}, + {0xa254, 0x00000000}, + {0xa258, 0x00000000}, + {0xa25c, 0x00000000}, + {0xa260, 0x00000000}, + {0xa264, 0x00000000}, + {0xa268, 0x00000000}, + {0xa26c, 0x00000000}, + {0xa270, 0x00000000}, + {0xa274, 0x00000000}, + {0xa278, 0x00000000}, + {0xa27c, 0x00000000}, + {0xa280, 0x00000000}, + {0xa284, 0x00000000}, + {0xa288, 0x00000000}, + {0xa28c, 0x00000000}, + {0xa290, 0x00000000}, + {0xa294, 0x00000000}, + {0xa298, 0x00000000}, + {0xa29c, 0x00000000}, + {0xa2a0, 0x00000000}, + {0xa2a4, 0x00000000}, + {0xa2a8, 0x00000000}, + {0xa2ac, 0x00000000}, + {0xa2b0, 0x00000000}, + {0xa2b4, 0x00000000}, + {0xa2b8, 0x00000000}, + {0xa2bc, 0x00000000}, + {0xa2c0, 0x00000000}, + {0xa2c4, 0x00000000}, + {0xa2c8, 0x00000000}, + {0xa2cc, 0x00000000}, + {0xa2d0, 0x00000000}, + {0xa2d4, 0x00000000}, + {0xa2d8, 0x00000000}, + {0xa2dc, 0x00000000}, + {0xa2e0, 0x00000000}, + {0xa2e4, 0x00000000}, + {0xa2e8, 0x00000000}, + {0xa2ec, 0x00000000}, + {0xa2f0, 0x00000000}, + {0xa2f4, 0x00000000}, + {0xa2f8, 0x00000000}, + {0xa2fc, 0x00000000}, + {0xa300, 0x00000000}, + {0xa304, 0x00000000}, + {0xa308, 0x00000000}, + {0xa30c, 0x00000000}, + {0xa310, 0x00000000}, + {0xa314, 0x00000000}, + {0xa318, 0x00000000}, + {0xa31c, 0x00000000}, + {0xa320, 0x00000000}, + {0xa324, 0x00000000}, + {0xa328, 0x00000000}, + {0xa32c, 0x00000000}, + {0xa330, 0x00000000}, + {0xa334, 0x00000000}, + {0xa338, 0x00000000}, + {0xa33c, 0x00000000}, + {0xa340, 0x00000000}, + {0xa344, 0x00000000}, + {0xa348, 0x00000000}, + {0xa34c, 0x00000000}, + {0xa350, 0x00000000}, + {0xa354, 0x00000000}, + {0xa358, 0x00000000}, + {0xa35c, 0x00000000}, + {0xa360, 0x00000000}, + {0xa364, 0x00000000}, + {0xa368, 0x00000000}, + {0xa36c, 0x00000000}, + {0xa370, 0x00000000}, + {0xa374, 0x00000000}, + {0xa378, 0x00000000}, + {0xa37c, 0x00000000}, + {0xa380, 0x00000000}, + {0xa384, 0x00000000}, + {0xa388, 0x00000000}, + {0xa38c, 0x00000000}, + {0xa390, 0x00000000}, + {0xa394, 0x00000000}, + {0xa398, 0x00000000}, + {0xa39c, 0x00000000}, + {0xa3a0, 0x00000000}, + {0xa3a4, 0x00000000}, + {0xa3a8, 0x00000000}, + {0xa3ac, 0x00000000}, + {0xa3b0, 0x00000000}, + {0xa3b4, 0x00000000}, + {0xa3b8, 0x00000000}, + {0xa3bc, 0x00000000}, + {0xa620, 0x00000000}, + {0xa624, 0x00000000}, + {0xa628, 0x00000000}, + {0xa62c, 0x00000000}, + {0xa630, 0x00000000}, + {0xa634, 0x00000000}, + {0xa638, 0x00000000}, + {0xa63c, 0x00000000}, + {0xa640, 0x00000000}, + {0xa644, 0x00000000}, + {0xa648, 0x00000000}, + {0xa64c, 0x00000000}, + {0xa650, 0x00000000}, + {0xa654, 0x00000000}, + {0xa658, 0x00000000}, + {0xa65c, 0x00000000}, + {0xa660, 0x00000000}, + {0xa664, 0x00000000}, + {0xa668, 0x00000000}, + {0xa66c, 0x00000000}, + {0xa670, 0x00000000}, + {0xa674, 0x00000000}, + {0xa678, 0x00000000}, + {0xa67c, 0x00000000}, + {0xa680, 0x00000000}, + {0xa684, 0x00000000}, + {0xa688, 0x00000000}, + {0xa68c, 0x00000000}, + {0xa690, 0x00000000}, + {0xa694, 0x00000000}, + {0xa698, 0x00000000}, + {0xa69c, 0x00000000}, + {0xa6a0, 0x00000000}, + {0xa6a4, 0x00000000}, + {0xa6a8, 0x00000000}, + {0xa6ac, 0x00000000}, + {0xa6b0, 0x00000000}, + {0xa6b4, 0x00000000}, + {0xa6b8, 0x00000000}, + {0xa6bc, 0x00000000}, + {0xa6c0, 0x00000000}, + {0xa6c4, 0x00000000}, + {0xa6c8, 0x00000000}, + {0xa6cc, 0x00000000}, + {0xa6d0, 0x00000000}, + {0xa6d4, 0x00000000}, + {0xa6d8, 0x00000000}, + {0xa6dc, 0x00000000}, + {0xa6e0, 0x00000000}, + {0xa6e4, 0x00000000}, + {0xa6e8, 0x00000000}, + {0xa6ec, 0x00000000}, + {0xa6f0, 0x00000000}, + {0xa6f4, 0x00000000}, + {0xa6f8, 0x00000000}, + {0xa6fc, 0x00000000}, + {0xa700, 0x00000000}, + {0xa704, 0x00000000}, + {0xa708, 0x00000000}, + {0xa70c, 0x00000000}, + {0xa710, 0x00000000}, + {0xa714, 0x00000000}, + {0xa718, 0x00000000}, + {0xa71c, 0x00000000}, + {0xa720, 0x00000000}, + {0xa724, 0x00000000}, + {0xa728, 0x00000000}, + {0xa72c, 0x00000000}, + {0xa730, 0x00000000}, + {0xa734, 0x00000000}, + {0xa738, 0x00000000}, + {0xa73c, 0x00000000}, + {0xa740, 0x00000000}, + {0xa744, 0x00000000}, + {0xa748, 0x00000000}, + {0xa74c, 0x00000000}, + {0xa750, 0x00000000}, + {0xa754, 0x00000000}, + {0xa758, 0x00000000}, + {0xa75c, 0x00000000}, + {0xa760, 0x00000000}, + {0xa764, 0x00000000}, + {0xa768, 0x00000000}, + {0xa76c, 0x00000000}, + {0xa770, 0x00000000}, + {0xa774, 0x00000000}, + {0xa778, 0x00000000}, + {0xa77c, 0x00000000}, + {0xa780, 0x00000000}, + {0xa784, 0x00000000}, + {0xa788, 0x00000000}, + {0xa78c, 0x00000000}, + {0xa790, 0x00000000}, + {0xa794, 0x00000000}, + {0xa798, 0x00000000}, + {0xa79c, 0x00000000}, + {0xa7a0, 0x00000000}, + {0xa7a4, 0x00000000}, + {0xa7a8, 0x00000000}, + {0xa7ac, 0x00000000}, + {0xa7b0, 0x00000000}, + {0xa7b4, 0x00000000}, + {0xa7b8, 0x00000000}, + {0xa7bc, 0x00000000}, + {0x81d8, 0x00000000}, + {0x82d8, 0x00000000}, + {0x9f04, 0x2b251f19}, + {0x9f08, 0x433d3731}, + {0x9f0c, 0x5b554f49}, + {0x9f10, 0x736d6761}, + {0x9f14, 0x7f7f7f79}, + {0x9f18, 0x120f7f7f}, + {0x9f1c, 0x1e1b1815}, + {0x9f20, 0x2a272421}, + {0x9f24, 0x3633302d}, + {0x9f28, 0x3f3f3c39}, + {0x9f2c, 0x3f3f3f3f}, + {0x8008, 0x00000080}, + {0x8088, 0x807f030a}, + {0x80c8, 0x708f0bf1}, + {0x80c8, 0x708e0aa5}, + {0x80c8, 0x708d097d}, + {0x80c8, 0x708c0875}, + {0x80c8, 0x708b0789}, + {0x80c8, 0x708a06b7}, + {0x80c8, 0x708905fc}, + {0x80c8, 0x70880556}, + {0x80c8, 0x708704c1}, + {0x80c8, 0x7086043d}, + {0x80c8, 0x708503c7}, + {0x80c8, 0x7084035e}, + {0x80c8, 0x708302ac}, + {0x80c8, 0x70820262}, + {0x80c8, 0x70810220}, + {0x80c8, 0x70800000}, + {0x80c8, 0x7090011f}, + {0x80c8, 0x7010011f}, + {0x8088, 0x80000000}, + {0x8008, 0x00000000}, + {0x8088, 0x00000110}, + {0x8000, 0x00000008}, + {0x8080, 0x00000005}, + {0x8500, 0x80000008}, + {0x8504, 0x43000004}, + {0x8508, 0x4b044a00}, + {0x850c, 0x40098604}, + {0x8510, 0x0004e020}, + {0x8514, 0x87044b05}, + {0x8518, 0xe020400b}, + {0x851c, 0x4b000004}, + {0x8520, 0x21e07410}, + {0x8524, 0x74300000}, + {0x8528, 0x43800004}, + {0x852c, 0x4c000007}, + {0x8530, 0x43000004}, + {0x8534, 0x42fe5700}, + {0x8538, 0x42004000}, + {0x853c, 0x30005055}, + {0x8540, 0xa50fb41a}, + {0x8544, 0xf11ce3c7}, + {0x8548, 0xf31cf21c}, + {0x854c, 0xf61cf41c}, + {0x8550, 0xf91cf81c}, + {0x8554, 0xfb1cfa1c}, + {0x8558, 0xfd1cfc1c}, + {0x855c, 0xff1cfe1c}, + {0x8560, 0xf11cf01c}, + {0x8564, 0xf31cf21c}, + {0x8568, 0xf51cf41c}, + {0x856c, 0xf71cf61c}, + {0x8570, 0xf91cf81c}, + {0x8574, 0xe3c7a504}, + {0x8578, 0xf11af01a}, + {0x857c, 0x30580001}, + {0x8580, 0x30b030c9}, + {0x8584, 0x30ff30fc}, + {0x8588, 0x310f3102}, + {0x858c, 0x3148311c}, + {0x8590, 0x31603158}, + {0x8594, 0x30c7320e}, + {0x8598, 0x32293225}, + {0x859c, 0x32433242}, + {0x85a0, 0x3286327a}, + {0x85a4, 0x329d328a}, + {0x85a8, 0x32aa32a8}, + {0x85ac, 0x320331c5}, + {0x85b0, 0x7410e2c1}, + {0x85b4, 0x020020a8}, + {0x85b8, 0x2098140f}, + {0x85bc, 0x140f0200}, + {0x85c0, 0x02002088}, + {0x85c4, 0x7430140f}, + {0x85c8, 0x5b10e31c}, + {0x85cc, 0x20a87410}, + {0x85d0, 0x140f0201}, + {0x85d4, 0x00002080}, + {0x85d8, 0x5507140f}, + {0x85dc, 0x5c065661}, + {0x85e0, 0x7410e308}, + {0x85e4, 0x02002088}, + {0x85e8, 0x5517140f}, + {0x85ec, 0x7410e308}, + {0x85f0, 0x020020a8}, + {0x85f4, 0x5517140f}, + {0x85f8, 0x5c025641}, + {0x85fc, 0x7410e308}, + {0x8600, 0x00002080}, + {0x8604, 0x1407140f}, + {0x8608, 0xe3085507}, + {0x860c, 0x7508e2b4}, + {0x8610, 0xe312468e}, + {0x8614, 0x5b10e0f4}, + {0x8618, 0x20a87410}, + {0x861c, 0x140f0201}, + {0x8620, 0x00002090}, + {0x8624, 0x5507140f}, + {0x8628, 0x5c065661}, + {0x862c, 0x7410e308}, + {0x8630, 0x02002098}, + {0x8634, 0x5517140f}, + {0x8638, 0x7410e308}, + {0x863c, 0x020020a8}, + {0x8640, 0x5517140f}, + {0x8644, 0x5c025641}, + {0x8648, 0x7410e308}, + {0x864c, 0x00002090}, + {0x8650, 0x5507140f}, + {0x8654, 0x7509e308}, + {0x8658, 0xe3124696}, + {0x865c, 0x0001e0f4}, + {0x8660, 0x74105b10}, + {0x8664, 0x000020a0}, + {0x8668, 0x5507140f}, + {0x866c, 0xe3085601}, + {0x8670, 0x20a87410}, + {0x8674, 0x140f0200}, + {0x8678, 0xe3085517}, + {0x867c, 0x750ae2b4}, + {0x8680, 0xe3124686}, + {0x8684, 0x5500e0f4}, + {0x8688, 0x5501e304}, + {0x868c, 0xe2c10001}, + {0x8690, 0x5b10e31c}, + {0x8694, 0x20807410}, + {0x8698, 0x140f0000}, + {0x869c, 0x02002098}, + {0x86a0, 0xf204140f}, + {0x86a4, 0x020020a8}, + {0x86a8, 0x5507140f}, + {0x86ac, 0xe3085601}, + {0x86b0, 0x20887410}, + {0x86b4, 0x140f0200}, + {0x86b8, 0xe3085517}, + {0x86bc, 0x7508e2b4}, + {0x86c0, 0xe312468e}, + {0x86c4, 0x7410e0f4}, + {0x86c8, 0x00002090}, + {0x86cc, 0x5507140f}, + {0x86d0, 0x7410e308}, + {0x86d4, 0x02002098}, + {0x86d8, 0x5517140f}, + {0x86dc, 0x7509e308}, + {0x86e0, 0xe3124696}, + {0x86e4, 0x0001e0f4}, + {0x86e8, 0x74207900}, + {0x86ec, 0x57005710}, + {0x86f0, 0x9700140f}, + {0x86f4, 0x00017430}, + {0x86f8, 0xe31ce2c1}, + {0x86fc, 0xe2ca0001}, + {0x8700, 0x0001e34b}, + {0x8704, 0x312ae2c1}, + {0x8708, 0xe3ba0023}, + {0x870c, 0x54ed0002}, + {0x8710, 0x00230baa}, + {0x8714, 0x0002e3ba}, + {0x8718, 0xe2b9e367}, + {0x871c, 0xe2c10001}, + {0x8720, 0x00223125}, + {0x8724, 0x0002e3ba}, + {0x8728, 0x0baa54ec}, + {0x872c, 0xe3ba0022}, + {0x8730, 0xe3670002}, + {0x8734, 0x0001e2b9}, + {0x8738, 0x0baae2c1}, + {0x873c, 0x6d0f6c67}, + {0x8740, 0xe3bae31c}, + {0x8744, 0xe31c6c8b}, + {0x8748, 0x0bace3ba}, + {0x874c, 0x6d0f6cb3}, + {0x8750, 0xe3bae31c}, + {0x8754, 0x6cdb0bad}, + {0x8758, 0xe31c6d0f}, + {0x875c, 0x6cf7e3ba}, + {0x8760, 0xe31c6d0f}, + {0x8764, 0x6c09e3ba}, + {0x8768, 0xe31c6d00}, + {0x876c, 0x6c25e3ba}, + {0x8770, 0xe3bae31c}, + {0x8774, 0x6c4df8ca}, + {0x8778, 0xe3bae31c}, + {0x877c, 0x6c75f9d3}, + {0x8780, 0xe3bae31c}, + {0x8784, 0xe31c6c99}, + {0x8788, 0xe367e3ba}, + {0x878c, 0x0001e2b9}, + {0x8790, 0x4380e2ca}, + {0x8794, 0x43006344}, + {0x8798, 0x00223188}, + {0x879c, 0x0002e3bf}, + {0x87a0, 0x0baa54ec}, + {0x87a4, 0xe3bf0022}, + {0x87a8, 0xe3670002}, + {0x87ac, 0x0001e2c5}, + {0x87b0, 0x4380e2ca}, + {0x87b4, 0x43006344}, + {0x87b8, 0xe367317b}, + {0x87bc, 0x0001e2c5}, + {0x87c0, 0x4380e2ca}, + {0x87c4, 0x4300634d}, + {0x87c8, 0x74100ba6}, + {0x87cc, 0x000921e8}, + {0x87d0, 0x6f0f6e67}, + {0x87d4, 0xe3bfe34b}, + {0x87d8, 0x000a21e8}, + {0x87dc, 0xe34b6e77}, + {0x87e0, 0x21e8e3bf}, + {0x87e4, 0x6e8b000b}, + {0x87e8, 0xe3bfe34b}, + {0x87ec, 0x000c21e8}, + {0x87f0, 0xe34b6e9f}, + {0x87f4, 0x0baae3bf}, + {0x87f8, 0x21e87410}, + {0x87fc, 0x6eb3000d}, + {0x8800, 0xe34b6f0f}, + {0x8804, 0x21e8e3bf}, + {0x8808, 0x6ec7000e}, + {0x880c, 0xe3bfe34b}, + {0x8810, 0x74100bac}, + {0x8814, 0x000f21e8}, + {0x8818, 0x6f0f6edb}, + {0x881c, 0xe3bfe34b}, + {0x8820, 0x001021e8}, + {0x8824, 0xe34b6eef}, + {0x8828, 0xe3bfe3bf}, + {0x882c, 0x001321e8}, + {0x8830, 0x6f006e11}, + {0x8834, 0xe3bfe34b}, + {0x8838, 0x21e8e3bf}, + {0x883c, 0x6e250014}, + {0x8840, 0xe3bfe34b}, + {0x8844, 0x21e8fbab}, + {0x8848, 0x6e390015}, + {0x884c, 0xe3bfe34b}, + {0x8850, 0x001621e8}, + {0x8854, 0xe34b6e4d}, + {0x8858, 0xfcb0e3bf}, + {0x885c, 0x001721e8}, + {0x8860, 0xe34b6e61}, + {0x8864, 0x21e8e3bf}, + {0x8868, 0x6e750018}, + {0x886c, 0xe3bfe34b}, + {0x8870, 0x001921e8}, + {0x8874, 0xe34b6e89}, + {0x8878, 0x21e8e3bf}, + {0x887c, 0x6e99001a}, + {0x8880, 0xe3bfe34b}, + {0x8884, 0xe2c5e367}, + {0x8888, 0x00040001}, + {0x888c, 0x42fc0004}, + {0x8890, 0x60010007}, + {0x8894, 0x42000004}, + {0x8898, 0x62200007}, + {0x889c, 0x00046200}, + {0x88a0, 0x5b005501}, + {0x88a4, 0x5b40e304}, + {0x88a8, 0x00076605}, + {0x88ac, 0x63006200}, + {0x88b0, 0x0004e388}, + {0x88b4, 0x0a010900}, + {0x88b8, 0x0d000b40}, + {0x88bc, 0x00320e01}, + {0x88c0, 0x95090004}, + {0x88c4, 0x790442fb}, + {0x88c8, 0x43804200}, + {0x88cc, 0x4d010007}, + {0x88d0, 0x43000004}, + {0x88d4, 0x05620007}, + {0x88d8, 0x961d05a3}, + {0x88dc, 0x0004e388}, + {0x88e0, 0x0007e304}, + {0x88e4, 0x07a306a2}, + {0x88e8, 0x0004e388}, + {0x88ec, 0xe378e304}, + {0x88f0, 0xe3800002}, + {0x88f4, 0x00074380}, + {0x88f8, 0x00044d00}, + {0x88fc, 0x42fe4300}, + {0x8900, 0x42007900}, + {0x8904, 0x00040001}, + {0x8908, 0x000742fc}, + {0x890c, 0x00046003}, + {0x8910, 0x31cc4200}, + {0x8914, 0x06a20007}, + {0x8918, 0x31f807a3}, + {0x891c, 0x77000005}, + {0x8920, 0x52000007}, + {0x8924, 0x42fe0004}, + {0x8928, 0x60000007}, + {0x892c, 0x42000004}, + {0x8930, 0x60004380}, + {0x8934, 0x62016100}, + {0x8938, 0x00056310}, + {0x893c, 0x55004100}, + {0x8940, 0x5c020007}, + {0x8944, 0x43000004}, + {0x8948, 0xe2d70001}, + {0x894c, 0x73000005}, + {0x8950, 0xe2d70001}, + {0x8954, 0x5d000006}, + {0x8958, 0x42f70004}, + {0x895c, 0x6c000005}, + {0x8960, 0x42000004}, + {0x8964, 0x0004e2de}, + {0x8968, 0x00074380}, + {0x896c, 0x4a004e00}, + {0x8970, 0x00064c00}, + {0x8974, 0x60007f00}, + {0x8978, 0x00046f00}, + {0x897c, 0x00054300}, + {0x8980, 0x00017300}, + {0x8984, 0xe2d70001}, + {0x8988, 0x5d010006}, + {0x898c, 0x61006002}, + {0x8990, 0x00055601}, + {0x8994, 0xe2e27710}, + {0x8998, 0x73000005}, + {0x899c, 0x43800004}, + {0x89a0, 0x5e010007}, + {0x89a4, 0x4d205e00}, + {0x89a8, 0x4a084e20}, + {0x89ac, 0x4c3f4960}, + {0x89b0, 0x00064301}, + {0x89b4, 0x63807f01}, + {0x89b8, 0x00046010}, + {0x89bc, 0x00064300}, + {0x89c0, 0x00077402}, + {0x89c4, 0x40004001}, + {0x89c8, 0x0006ab00}, + {0x89cc, 0x00077404}, + {0x89d0, 0x40004001}, + {0x89d4, 0x0004ab00}, + {0x89d8, 0x00074380}, + {0x89dc, 0x4e004d00}, + {0x89e0, 0x4c004a00}, + {0x89e4, 0x00064300}, + {0x89e8, 0x63007f00}, + {0x89ec, 0x00046000}, + {0x89f0, 0x00014300}, + {0x89f4, 0x73800005}, + {0x89f8, 0x42fe0004}, + {0x89fc, 0x6c010005}, + {0x8a00, 0x000514c8}, + {0x8a04, 0x00046c00}, + {0x8a08, 0x00014200}, + {0x8a0c, 0x0005e2ce}, + {0x8a10, 0x00017300}, + {0x8a14, 0x00040006}, + {0x8a18, 0x42fa4380}, + {0x8a1c, 0x42007c05}, + {0x8a20, 0x7c5b0006}, + {0x8a24, 0x7e5b7d5b}, + {0x8a28, 0x00077f00}, + {0x8a2c, 0x415b405b}, + {0x8a30, 0x4300425b}, + {0x8a34, 0x43000004}, + {0x8a38, 0x00040001}, + {0x8a3c, 0x60004380}, + {0x8a40, 0x62016100}, + {0x8a44, 0x42fa6310}, + {0x8a48, 0x42007c00}, + {0x8a4c, 0x00014300}, + {0x8a50, 0x0001e2e5}, + {0x8a54, 0x55000007}, + {0x8a58, 0x74200004}, + {0x8a5c, 0x79017711}, + {0x8a60, 0x57005710}, + {0x8a64, 0x00019700}, + {0x8a68, 0x4e004f02}, + {0x8a6c, 0x52015302}, + {0x8a70, 0x43800001}, + {0x8a74, 0x78006505}, + {0x8a78, 0x7a007900}, + {0x8a7c, 0x43007b00}, + {0x8a80, 0x43800001}, + {0x8a84, 0x43006500}, + {0x8a88, 0x43800001}, + {0x8a8c, 0x7c006405}, + {0x8a90, 0x00014300}, + {0x8a94, 0x64004380}, + {0x8a98, 0x00014300}, + {0x8a9c, 0x74200004}, + {0x8aa0, 0x0005e392}, + {0x8aa4, 0x73807388}, + {0x8aa8, 0xe3a08f00}, + {0x8aac, 0xe3920001}, + {0x8ab0, 0x73810005}, + {0x8ab4, 0x93007380}, + {0x8ab8, 0x0001e3a0}, + {0x8abc, 0xe2e5e3a7}, + {0x8ac0, 0x0001e3ae}, + {0x8ac4, 0xe3aee3a7}, + {0x8ac8, 0x00040001}, + {0x8acc, 0x24207410}, + {0x8ad0, 0x14c80000}, + {0x8ad4, 0x00002428}, + {0x8ad8, 0x1a4215f4}, + {0x8adc, 0x74300008}, + {0x8ae0, 0x43800001}, + {0x8ae4, 0x7a907b48}, + {0x8ae8, 0x78027900}, + {0x8aec, 0x55034300}, + {0x8af0, 0x43803308}, + {0x8af4, 0x7a807b38}, + {0x8af8, 0x55134300}, + {0x8afc, 0x43803308}, + {0x8b00, 0x7a007b40}, + {0x8b04, 0x55234300}, + {0x8b08, 0x74007401}, + {0x8b0c, 0x00018e00}, + {0x8b10, 0x52300007}, + {0x8b14, 0x74310004}, + {0x8b18, 0x8e007430}, + {0x8b1c, 0x52200007}, + {0x8b20, 0x00010004}, + {0x8b24, 0x57005702}, + {0x8b28, 0x00018e00}, + {0x8b2c, 0x561042ef}, + {0x8b30, 0x42005600}, + {0x8b34, 0x00018c00}, + {0x8b38, 0x4e004f78}, + {0x8b3c, 0x52015388}, + {0x8b40, 0xe32b5b20}, + {0x8b44, 0x54005480}, + {0x8b48, 0x54005481}, + {0x8b4c, 0x54005482}, + {0x8b50, 0xbf1de336}, + {0x8b54, 0xe2f13010}, + {0x8b58, 0xe2ffe2f9}, + {0x8b5c, 0xe3b3e312}, + {0x8b60, 0xe3085523}, + {0x8b64, 0xe3125525}, + {0x8b68, 0x0001e3b3}, + {0x8b6c, 0x54c054bf}, + {0x8b70, 0x54c154a3}, + {0x8b74, 0x4c1854a4}, + {0x8b78, 0x54c2bf07}, + {0x8b7c, 0xbf0454a4}, + {0x8b80, 0x54a354c1}, + {0x8b84, 0xe3c4bf01}, + {0x8b88, 0x000154df}, + {0x8b8c, 0x54e554bf}, + {0x8b90, 0x54df050a}, + {0x8b94, 0x16570001}, + {0x8b98, 0x74307b80}, + {0x8b9c, 0x7f404380}, + {0x8ba0, 0x7d007e00}, + {0x8ba4, 0x43007c02}, + {0x8ba8, 0x55015b40}, + {0x8bac, 0xe3165c01}, + {0x8bb0, 0x54005480}, + {0x8bb4, 0x54005481}, + {0x8bb8, 0x54005482}, + {0x8bbc, 0x74107b00}, + {0x8bc0, 0xbfe5e336}, + {0x8bc4, 0x56103010}, + {0x8bc8, 0x8c005600}, + {0x8bcc, 0x57040001}, + {0x8bd0, 0x8e005700}, + {0x8bd4, 0x57005708}, + {0x8bd8, 0x57818e00}, + {0x8bdc, 0x8e005780}, + {0x8be0, 0x00074380}, + {0x8be4, 0x5c005c01}, + {0x8be8, 0x00041403}, + {0x8bec, 0x00014300}, + {0x8bf0, 0x0007427f}, + {0x8bf4, 0x62006280}, + {0x8bf8, 0x00049200}, + {0x8bfc, 0x00014200}, + {0x8c00, 0x0007427f}, + {0x8c04, 0x63146394}, + {0x8c08, 0x00049200}, + {0x8c0c, 0x00014200}, + {0x8c10, 0x42fe0004}, + {0x8c14, 0x42007901}, + {0x8c18, 0x14037420}, + {0x8c1c, 0x57005710}, + {0x8c20, 0x0001140f}, + {0x8c24, 0x56010006}, + {0x8c28, 0x54005502}, + {0x8c2c, 0x7f000005}, + {0x8c30, 0x77107e12}, + {0x8c34, 0x75007600}, + {0x8c38, 0x00047400}, + {0x8c3c, 0x00014270}, + {0x8c40, 0x42000004}, + {0x8c44, 0x77000005}, + {0x8c48, 0x56000006}, + {0x8c4c, 0x00060001}, + {0x8c50, 0x5f005f80}, + {0x8c54, 0x00059900}, + {0x8c58, 0x00017300}, + {0x8c5c, 0x63800006}, + {0x8c60, 0x98006300}, + {0x8c64, 0x549f0001}, + {0x8c68, 0x5c015400}, + {0x8c6c, 0x540054df}, + {0x8c70, 0x00015c02}, + {0x8c74, 0x07145c01}, + {0x8c78, 0x5c025400}, + {0x8c7c, 0x5c020001}, + {0x8c80, 0x54000714}, + {0x8c84, 0x00015c01}, + {0x8c88, 0x4c184c98}, + {0x8c8c, 0x00040001}, + {0x8c90, 0x74305c02}, + {0x8c94, 0x0c010901}, + {0x8c98, 0x00050ba6}, + {0x8c9c, 0x00077780}, + {0x8ca0, 0x00045220}, + {0x8ca4, 0x60084380}, + {0x8ca8, 0x6200610a}, + {0x8cac, 0x000763ce}, + {0x8cb0, 0x00045c00}, + {0x8cb4, 0x00014300}, + {0x8080, 0x00000004}, + {0x8080, 0x00000000}, + {0x8088, 0x00000000}, +}; + +static const struct rtw89_txpwr_byrate_cfg rtw89_8852b_txpwr_byrate[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x50505050, }, + { 0, 0, 1, 4, 4, 0x484c5050, }, + { 0, 0, 2, 0, 4, 0x50505050, }, + { 0, 0, 2, 4, 4, 0x44484c50, }, + { 0, 0, 2, 8, 4, 0x34383c40, }, + { 0, 0, 3, 0, 4, 0x50505050, }, + { 0, 1, 2, 0, 4, 0x50505050, }, + { 0, 1, 2, 4, 4, 0x44484c50, }, + { 0, 1, 2, 8, 4, 0x34383c40, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x50505050, }, + { 1, 0, 1, 4, 4, 0x484c5050, }, + { 1, 0, 2, 0, 4, 0x50505050, }, + { 1, 0, 2, 4, 4, 0x44484c50, }, + { 1, 0, 2, 8, 4, 0x34383c40, }, + { 1, 0, 3, 0, 4, 0x50505050, }, + { 1, 1, 2, 0, 4, 0x50505050, }, + { 1, 1, 2, 4, 4, 0x44484c50, }, + { 1, 1, 2, 8, 4, 0x34383c40, }, + { 1, 1, 3, 0, 4, 0x50505050, }, + { 1, 0, 4, 0, 4, 0x00000000, }, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8}, + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8}, + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8}, + {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8}, + {0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, + {0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, + 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2}; + +static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { + 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6}; + +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { + 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +static +const u8 rtw89_8852b_tx_shape_lmt[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] + [RTW89_REGD_NUM] = { + [0][0][RTW89_ACMA] = 0, + [0][0][RTW89_CHILE] = 0, + [0][0][RTW89_CN] = 0, + [0][0][RTW89_ETSI] = 0, + [0][0][RTW89_FCC] = 1, + [0][0][RTW89_IC] = 1, + [0][0][RTW89_KCC] = 0, + [0][0][RTW89_MEXICO] = 1, + [0][0][RTW89_MKK] = 0, + [0][0][RTW89_QATAR] = 0, + [0][0][RTW89_UK] = 0, + [0][0][RTW89_UKRAINE] = 0, + [0][1][RTW89_ACMA] = 0, + [0][1][RTW89_CHILE] = 0, + [0][1][RTW89_CN] = 0, + [0][1][RTW89_ETSI] = 0, + [0][1][RTW89_FCC] = 3, + [0][1][RTW89_IC] = 3, + [0][1][RTW89_KCC] = 0, + [0][1][RTW89_MEXICO] = 3, + [0][1][RTW89_MKK] = 0, + [0][1][RTW89_QATAR] = 0, + [0][1][RTW89_UK] = 0, + [0][1][RTW89_UKRAINE] = 0, + [1][1][RTW89_ACMA] = 0, + [1][1][RTW89_CHILE] = 0, + [1][1][RTW89_CN] = 0, + [1][1][RTW89_ETSI] = 0, + [1][1][RTW89_FCC] = 3, + [1][1][RTW89_IC] = 3, + [1][1][RTW89_KCC] = 0, + [1][1][RTW89_MEXICO] = 3, + [1][1][RTW89_MKK] = 0, + [1][1][RTW89_QATAR] = 0, + [1][1][RTW89_UK] = 0, + [1][1][RTW89_UKRAINE] = 0, +}; + +static +const u8 rtw89_8852b_tx_shape_lmt_ru[RTW89_BAND_NUM][RTW89_REGD_NUM] = { + [0][RTW89_ACMA] = 0, + [0][RTW89_CHILE] = 0, + [0][RTW89_CN] = 0, + [0][RTW89_ETSI] = 0, + [0][RTW89_FCC] = 3, + [0][RTW89_IC] = 3, + [0][RTW89_KCC] = 0, + [0][RTW89_MEXICO] = 3, + [0][RTW89_MKK] = 0, + [0][RTW89_QATAR] = 0, + [0][RTW89_UK] = 0, + [0][RTW89_UKRAINE] = 0, + [1][RTW89_ACMA] = 0, + [1][RTW89_CHILE] = 0, + [1][RTW89_CN] = 0, + [1][RTW89_ETSI] = 0, + [1][RTW89_FCC] = 3, + [1][RTW89_IC] = 3, + [1][RTW89_KCC] = 0, + [1][RTW89_MEXICO] = 3, + [1][RTW89_MKK] = 0, + [1][RTW89_QATAR] = 0, + [1][RTW89_UK] = 0, + [1][RTW89_UKRAINE] = 0, +}; + +static +const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 56, + [0][0][0][0][RTW89_WW][1] = 56, + [0][0][0][0][RTW89_WW][2] = 56, + [0][0][0][0][RTW89_WW][3] = 56, + [0][0][0][0][RTW89_WW][4] = 56, + [0][0][0][0][RTW89_WW][5] = 56, + [0][0][0][0][RTW89_WW][6] = 56, + [0][0][0][0][RTW89_WW][7] = 56, + [0][0][0][0][RTW89_WW][8] = 56, + [0][0][0][0][RTW89_WW][9] = 56, + [0][0][0][0][RTW89_WW][10] = 56, + [0][0][0][0][RTW89_WW][11] = 56, + [0][0][0][0][RTW89_WW][12] = 56, + [0][0][0][0][RTW89_WW][13] = 76, + [0][1][0][0][RTW89_WW][0] = 44, + [0][1][0][0][RTW89_WW][1] = 44, + [0][1][0][0][RTW89_WW][2] = 44, + [0][1][0][0][RTW89_WW][3] = 44, + [0][1][0][0][RTW89_WW][4] = 44, + [0][1][0][0][RTW89_WW][5] = 44, + [0][1][0][0][RTW89_WW][6] = 44, + [0][1][0][0][RTW89_WW][7] = 44, + [0][1][0][0][RTW89_WW][8] = 44, + [0][1][0][0][RTW89_WW][9] = 44, + [0][1][0][0][RTW89_WW][10] = 44, + [0][1][0][0][RTW89_WW][11] = 44, + [0][1][0][0][RTW89_WW][12] = 42, + [0][1][0][0][RTW89_WW][13] = 64, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 50, + [1][0][0][0][RTW89_WW][3] = 50, + [1][0][0][0][RTW89_WW][4] = 50, + [1][0][0][0][RTW89_WW][5] = 56, + [1][0][0][0][RTW89_WW][6] = 50, + [1][0][0][0][RTW89_WW][7] = 50, + [1][0][0][0][RTW89_WW][8] = 50, + [1][0][0][0][RTW89_WW][9] = 42, + [1][0][0][0][RTW89_WW][10] = 30, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 44, + [1][1][0][0][RTW89_WW][3] = 44, + [1][1][0][0][RTW89_WW][4] = 44, + [1][1][0][0][RTW89_WW][5] = 44, + [1][1][0][0][RTW89_WW][6] = 34, + [1][1][0][0][RTW89_WW][7] = 34, + [1][1][0][0][RTW89_WW][8] = 34, + [1][1][0][0][RTW89_WW][9] = 30, + [1][1][0][0][RTW89_WW][10] = 30, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][1] = 58, + [0][0][1][0][RTW89_WW][2] = 58, + [0][0][1][0][RTW89_WW][3] = 58, + [0][0][1][0][RTW89_WW][4] = 58, + [0][0][1][0][RTW89_WW][5] = 58, + [0][0][1][0][RTW89_WW][6] = 58, + [0][0][1][0][RTW89_WW][7] = 58, + [0][0][1][0][RTW89_WW][8] = 58, + [0][0][1][0][RTW89_WW][9] = 58, + [0][0][1][0][RTW89_WW][10] = 58, + [0][0][1][0][RTW89_WW][11] = 54, + [0][0][1][0][RTW89_WW][12] = 50, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 46, + [0][1][1][0][RTW89_WW][1] = 46, + [0][1][1][0][RTW89_WW][2] = 46, + [0][1][1][0][RTW89_WW][3] = 46, + [0][1][1][0][RTW89_WW][4] = 46, + [0][1][1][0][RTW89_WW][5] = 46, + [0][1][1][0][RTW89_WW][6] = 46, + [0][1][1][0][RTW89_WW][7] = 46, + [0][1][1][0][RTW89_WW][8] = 46, + [0][1][1][0][RTW89_WW][9] = 46, + [0][1][1][0][RTW89_WW][10] = 46, + [0][1][1][0][RTW89_WW][11] = 46, + [0][1][1][0][RTW89_WW][12] = 42, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 58, + [0][0][2][0][RTW89_WW][1] = 58, + [0][0][2][0][RTW89_WW][2] = 58, + [0][0][2][0][RTW89_WW][3] = 58, + [0][0][2][0][RTW89_WW][4] = 58, + [0][0][2][0][RTW89_WW][5] = 58, + [0][0][2][0][RTW89_WW][6] = 58, + [0][0][2][0][RTW89_WW][7] = 58, + [0][0][2][0][RTW89_WW][8] = 58, + [0][0][2][0][RTW89_WW][9] = 58, + [0][0][2][0][RTW89_WW][10] = 58, + [0][0][2][0][RTW89_WW][11] = 54, + [0][0][2][0][RTW89_WW][12] = 50, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 46, + [0][1][2][0][RTW89_WW][1] = 46, + [0][1][2][0][RTW89_WW][2] = 46, + [0][1][2][0][RTW89_WW][3] = 46, + [0][1][2][0][RTW89_WW][4] = 46, + [0][1][2][0][RTW89_WW][5] = 46, + [0][1][2][0][RTW89_WW][6] = 46, + [0][1][2][0][RTW89_WW][7] = 46, + [0][1][2][0][RTW89_WW][8] = 46, + [0][1][2][0][RTW89_WW][9] = 46, + [0][1][2][0][RTW89_WW][10] = 46, + [0][1][2][0][RTW89_WW][11] = 46, + [0][1][2][0][RTW89_WW][12] = 42, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 34, + [0][1][2][1][RTW89_WW][1] = 34, + [0][1][2][1][RTW89_WW][2] = 34, + [0][1][2][1][RTW89_WW][3] = 34, + [0][1][2][1][RTW89_WW][4] = 34, + [0][1][2][1][RTW89_WW][5] = 34, + [0][1][2][1][RTW89_WW][6] = 34, + [0][1][2][1][RTW89_WW][7] = 34, + [0][1][2][1][RTW89_WW][8] = 34, + [0][1][2][1][RTW89_WW][9] = 34, + [0][1][2][1][RTW89_WW][10] = 34, + [0][1][2][1][RTW89_WW][11] = 34, + [0][1][2][1][RTW89_WW][12] = 34, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 58, + [1][0][2][0][RTW89_WW][3] = 58, + [1][0][2][0][RTW89_WW][4] = 58, + [1][0][2][0][RTW89_WW][5] = 58, + [1][0][2][0][RTW89_WW][6] = 58, + [1][0][2][0][RTW89_WW][7] = 58, + [1][0][2][0][RTW89_WW][8] = 58, + [1][0][2][0][RTW89_WW][9] = 58, + [1][0][2][0][RTW89_WW][10] = 40, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 46, + [1][1][2][0][RTW89_WW][3] = 46, + [1][1][2][0][RTW89_WW][4] = 46, + [1][1][2][0][RTW89_WW][5] = 46, + [1][1][2][0][RTW89_WW][6] = 46, + [1][1][2][0][RTW89_WW][7] = 46, + [1][1][2][0][RTW89_WW][8] = 46, + [1][1][2][0][RTW89_WW][9] = 42, + [1][1][2][0][RTW89_WW][10] = 38, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 34, + [1][1][2][1][RTW89_WW][3] = 34, + [1][1][2][1][RTW89_WW][4] = 34, + [1][1][2][1][RTW89_WW][5] = 34, + [1][1][2][1][RTW89_WW][6] = 34, + [1][1][2][1][RTW89_WW][7] = 34, + [1][1][2][1][RTW89_WW][8] = 34, + [1][1][2][1][RTW89_WW][9] = 34, + [1][1][2][1][RTW89_WW][10] = 34, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 78, + [0][0][0][0][RTW89_ETSI][0] = 58, + [0][0][0][0][RTW89_MKK][0] = 68, + [0][0][0][0][RTW89_IC][0] = 78, + [0][0][0][0][RTW89_KCC][0] = 68, + [0][0][0][0][RTW89_ACMA][0] = 58, + [0][0][0][0][RTW89_CHILE][0] = 64, + [0][0][0][0][RTW89_UKRAINE][0] = 58, + [0][0][0][0][RTW89_MEXICO][0] = 78, + [0][0][0][0][RTW89_CN][0] = 56, + [0][0][0][0][RTW89_QATAR][0] = 58, + [0][0][0][0][RTW89_UK][0] = 58, + [0][0][0][0][RTW89_FCC][1] = 78, + [0][0][0][0][RTW89_ETSI][1] = 58, + [0][0][0][0][RTW89_MKK][1] = 68, + [0][0][0][0][RTW89_IC][1] = 78, + [0][0][0][0][RTW89_KCC][1] = 68, + [0][0][0][0][RTW89_ACMA][1] = 58, + [0][0][0][0][RTW89_CHILE][1] = 64, + [0][0][0][0][RTW89_UKRAINE][1] = 58, + [0][0][0][0][RTW89_MEXICO][1] = 78, + [0][0][0][0][RTW89_CN][1] = 56, + [0][0][0][0][RTW89_QATAR][1] = 58, + [0][0][0][0][RTW89_UK][1] = 58, + [0][0][0][0][RTW89_FCC][2] = 78, + [0][0][0][0][RTW89_ETSI][2] = 58, + [0][0][0][0][RTW89_MKK][2] = 68, + [0][0][0][0][RTW89_IC][2] = 78, + [0][0][0][0][RTW89_KCC][2] = 68, + [0][0][0][0][RTW89_ACMA][2] = 58, + [0][0][0][0][RTW89_CHILE][2] = 64, + [0][0][0][0][RTW89_UKRAINE][2] = 58, + [0][0][0][0][RTW89_MEXICO][2] = 78, + [0][0][0][0][RTW89_CN][2] = 56, + [0][0][0][0][RTW89_QATAR][2] = 58, + [0][0][0][0][RTW89_UK][2] = 58, + [0][0][0][0][RTW89_FCC][3] = 78, + [0][0][0][0][RTW89_ETSI][3] = 58, + [0][0][0][0][RTW89_MKK][3] = 68, + [0][0][0][0][RTW89_IC][3] = 78, + [0][0][0][0][RTW89_KCC][3] = 68, + [0][0][0][0][RTW89_ACMA][3] = 58, + [0][0][0][0][RTW89_CHILE][3] = 64, + [0][0][0][0][RTW89_UKRAINE][3] = 58, + [0][0][0][0][RTW89_MEXICO][3] = 78, + [0][0][0][0][RTW89_CN][3] = 56, + [0][0][0][0][RTW89_QATAR][3] = 58, + [0][0][0][0][RTW89_UK][3] = 58, + [0][0][0][0][RTW89_FCC][4] = 78, + [0][0][0][0][RTW89_ETSI][4] = 58, + [0][0][0][0][RTW89_MKK][4] = 68, + [0][0][0][0][RTW89_IC][4] = 78, + [0][0][0][0][RTW89_KCC][4] = 70, + [0][0][0][0][RTW89_ACMA][4] = 58, + [0][0][0][0][RTW89_CHILE][4] = 64, + [0][0][0][0][RTW89_UKRAINE][4] = 58, + [0][0][0][0][RTW89_MEXICO][4] = 78, + [0][0][0][0][RTW89_CN][4] = 56, + [0][0][0][0][RTW89_QATAR][4] = 58, + [0][0][0][0][RTW89_UK][4] = 58, + [0][0][0][0][RTW89_FCC][5] = 78, + [0][0][0][0][RTW89_ETSI][5] = 58, + [0][0][0][0][RTW89_MKK][5] = 68, + [0][0][0][0][RTW89_IC][5] = 78, + [0][0][0][0][RTW89_KCC][5] = 70, + [0][0][0][0][RTW89_ACMA][5] = 58, + [0][0][0][0][RTW89_CHILE][5] = 64, + [0][0][0][0][RTW89_UKRAINE][5] = 58, + [0][0][0][0][RTW89_MEXICO][5] = 78, + [0][0][0][0][RTW89_CN][5] = 56, + [0][0][0][0][RTW89_QATAR][5] = 58, + [0][0][0][0][RTW89_UK][5] = 58, + [0][0][0][0][RTW89_FCC][6] = 78, + [0][0][0][0][RTW89_ETSI][6] = 58, + [0][0][0][0][RTW89_MKK][6] = 68, + [0][0][0][0][RTW89_IC][6] = 78, + [0][0][0][0][RTW89_KCC][6] = 70, + [0][0][0][0][RTW89_ACMA][6] = 58, + [0][0][0][0][RTW89_CHILE][6] = 64, + [0][0][0][0][RTW89_UKRAINE][6] = 58, + [0][0][0][0][RTW89_MEXICO][6] = 78, + [0][0][0][0][RTW89_CN][6] = 56, + [0][0][0][0][RTW89_QATAR][6] = 58, + [0][0][0][0][RTW89_UK][6] = 58, + [0][0][0][0][RTW89_FCC][7] = 78, + [0][0][0][0][RTW89_ETSI][7] = 58, + [0][0][0][0][RTW89_MKK][7] = 68, + [0][0][0][0][RTW89_IC][7] = 78, + [0][0][0][0][RTW89_KCC][7] = 70, + [0][0][0][0][RTW89_ACMA][7] = 58, + [0][0][0][0][RTW89_CHILE][7] = 64, + [0][0][0][0][RTW89_UKRAINE][7] = 58, + [0][0][0][0][RTW89_MEXICO][7] = 78, + [0][0][0][0][RTW89_CN][7] = 56, + [0][0][0][0][RTW89_QATAR][7] = 58, + [0][0][0][0][RTW89_UK][7] = 58, + [0][0][0][0][RTW89_FCC][8] = 78, + [0][0][0][0][RTW89_ETSI][8] = 58, + [0][0][0][0][RTW89_MKK][8] = 68, + [0][0][0][0][RTW89_IC][8] = 78, + [0][0][0][0][RTW89_KCC][8] = 70, + [0][0][0][0][RTW89_ACMA][8] = 58, + [0][0][0][0][RTW89_CHILE][8] = 64, + [0][0][0][0][RTW89_UKRAINE][8] = 58, + [0][0][0][0][RTW89_MEXICO][8] = 78, + [0][0][0][0][RTW89_CN][8] = 56, + [0][0][0][0][RTW89_QATAR][8] = 58, + [0][0][0][0][RTW89_UK][8] = 58, + [0][0][0][0][RTW89_FCC][9] = 78, + [0][0][0][0][RTW89_ETSI][9] = 58, + [0][0][0][0][RTW89_MKK][9] = 68, + [0][0][0][0][RTW89_IC][9] = 78, + [0][0][0][0][RTW89_KCC][9] = 70, + [0][0][0][0][RTW89_ACMA][9] = 58, + [0][0][0][0][RTW89_CHILE][9] = 64, + [0][0][0][0][RTW89_UKRAINE][9] = 58, + [0][0][0][0][RTW89_MEXICO][9] = 78, + [0][0][0][0][RTW89_CN][9] = 56, + [0][0][0][0][RTW89_QATAR][9] = 58, + [0][0][0][0][RTW89_UK][9] = 58, + [0][0][0][0][RTW89_FCC][10] = 78, + [0][0][0][0][RTW89_ETSI][10] = 58, + [0][0][0][0][RTW89_MKK][10] = 68, + [0][0][0][0][RTW89_IC][10] = 78, + [0][0][0][0][RTW89_KCC][10] = 70, + [0][0][0][0][RTW89_ACMA][10] = 58, + [0][0][0][0][RTW89_CHILE][10] = 66, + [0][0][0][0][RTW89_UKRAINE][10] = 58, + [0][0][0][0][RTW89_MEXICO][10] = 78, + [0][0][0][0][RTW89_CN][10] = 56, + [0][0][0][0][RTW89_QATAR][10] = 58, + [0][0][0][0][RTW89_UK][10] = 58, + [0][0][0][0][RTW89_FCC][11] = 70, + [0][0][0][0][RTW89_ETSI][11] = 58, + [0][0][0][0][RTW89_MKK][11] = 68, + [0][0][0][0][RTW89_IC][11] = 70, + [0][0][0][0][RTW89_KCC][11] = 70, + [0][0][0][0][RTW89_ACMA][11] = 58, + [0][0][0][0][RTW89_CHILE][11] = 64, + [0][0][0][0][RTW89_UKRAINE][11] = 58, + [0][0][0][0][RTW89_MEXICO][11] = 70, + [0][0][0][0][RTW89_CN][11] = 56, + [0][0][0][0][RTW89_QATAR][11] = 58, + [0][0][0][0][RTW89_UK][11] = 58, + [0][0][0][0][RTW89_FCC][12] = 56, + [0][0][0][0][RTW89_ETSI][12] = 58, + [0][0][0][0][RTW89_MKK][12] = 68, + [0][0][0][0][RTW89_IC][12] = 56, + [0][0][0][0][RTW89_KCC][12] = 70, + [0][0][0][0][RTW89_ACMA][12] = 58, + [0][0][0][0][RTW89_CHILE][12] = 56, + [0][0][0][0][RTW89_UKRAINE][12] = 58, + [0][0][0][0][RTW89_MEXICO][12] = 56, + [0][0][0][0][RTW89_CN][12] = 56, + [0][0][0][0][RTW89_QATAR][12] = 58, + [0][0][0][0][RTW89_UK][12] = 58, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 76, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_KCC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][0][0][0][RTW89_CHILE][13] = 127, + [0][0][0][0][RTW89_UKRAINE][13] = 127, + [0][0][0][0][RTW89_MEXICO][13] = 127, + [0][0][0][0][RTW89_CN][13] = 127, + [0][0][0][0][RTW89_QATAR][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 74, + [0][1][0][0][RTW89_ETSI][0] = 46, + [0][1][0][0][RTW89_MKK][0] = 56, + [0][1][0][0][RTW89_IC][0] = 74, + [0][1][0][0][RTW89_KCC][0] = 58, + [0][1][0][0][RTW89_ACMA][0] = 46, + [0][1][0][0][RTW89_CHILE][0] = 50, + [0][1][0][0][RTW89_UKRAINE][0] = 46, + [0][1][0][0][RTW89_MEXICO][0] = 74, + [0][1][0][0][RTW89_CN][0] = 44, + [0][1][0][0][RTW89_QATAR][0] = 46, + [0][1][0][0][RTW89_UK][0] = 46, + [0][1][0][0][RTW89_FCC][1] = 74, + [0][1][0][0][RTW89_ETSI][1] = 46, + [0][1][0][0][RTW89_MKK][1] = 56, + [0][1][0][0][RTW89_IC][1] = 74, + [0][1][0][0][RTW89_KCC][1] = 58, + [0][1][0][0][RTW89_ACMA][1] = 46, + [0][1][0][0][RTW89_CHILE][1] = 50, + [0][1][0][0][RTW89_UKRAINE][1] = 46, + [0][1][0][0][RTW89_MEXICO][1] = 74, + [0][1][0][0][RTW89_CN][1] = 44, + [0][1][0][0][RTW89_QATAR][1] = 46, + [0][1][0][0][RTW89_UK][1] = 46, + [0][1][0][0][RTW89_FCC][2] = 74, + [0][1][0][0][RTW89_ETSI][2] = 46, + [0][1][0][0][RTW89_MKK][2] = 56, + [0][1][0][0][RTW89_IC][2] = 74, + [0][1][0][0][RTW89_KCC][2] = 58, + [0][1][0][0][RTW89_ACMA][2] = 46, + [0][1][0][0][RTW89_CHILE][2] = 50, + [0][1][0][0][RTW89_UKRAINE][2] = 46, + [0][1][0][0][RTW89_MEXICO][2] = 74, + [0][1][0][0][RTW89_CN][2] = 44, + [0][1][0][0][RTW89_QATAR][2] = 46, + [0][1][0][0][RTW89_UK][2] = 46, + [0][1][0][0][RTW89_FCC][3] = 74, + [0][1][0][0][RTW89_ETSI][3] = 46, + [0][1][0][0][RTW89_MKK][3] = 56, + [0][1][0][0][RTW89_IC][3] = 74, + [0][1][0][0][RTW89_KCC][3] = 58, + [0][1][0][0][RTW89_ACMA][3] = 46, + [0][1][0][0][RTW89_CHILE][3] = 50, + [0][1][0][0][RTW89_UKRAINE][3] = 46, + [0][1][0][0][RTW89_MEXICO][3] = 74, + [0][1][0][0][RTW89_CN][3] = 44, + [0][1][0][0][RTW89_QATAR][3] = 46, + [0][1][0][0][RTW89_UK][3] = 46, + [0][1][0][0][RTW89_FCC][4] = 74, + [0][1][0][0][RTW89_ETSI][4] = 46, + [0][1][0][0][RTW89_MKK][4] = 56, + [0][1][0][0][RTW89_IC][4] = 74, + [0][1][0][0][RTW89_KCC][4] = 56, + [0][1][0][0][RTW89_ACMA][4] = 46, + [0][1][0][0][RTW89_CHILE][4] = 50, + [0][1][0][0][RTW89_UKRAINE][4] = 46, + [0][1][0][0][RTW89_MEXICO][4] = 74, + [0][1][0][0][RTW89_CN][4] = 44, + [0][1][0][0][RTW89_QATAR][4] = 46, + [0][1][0][0][RTW89_UK][4] = 46, + [0][1][0][0][RTW89_FCC][5] = 74, + [0][1][0][0][RTW89_ETSI][5] = 46, + [0][1][0][0][RTW89_MKK][5] = 56, + [0][1][0][0][RTW89_IC][5] = 74, + [0][1][0][0][RTW89_KCC][5] = 56, + [0][1][0][0][RTW89_ACMA][5] = 46, + [0][1][0][0][RTW89_CHILE][5] = 50, + [0][1][0][0][RTW89_UKRAINE][5] = 46, + [0][1][0][0][RTW89_MEXICO][5] = 74, + [0][1][0][0][RTW89_CN][5] = 44, + [0][1][0][0][RTW89_QATAR][5] = 46, + [0][1][0][0][RTW89_UK][5] = 46, + [0][1][0][0][RTW89_FCC][6] = 74, + [0][1][0][0][RTW89_ETSI][6] = 46, + [0][1][0][0][RTW89_MKK][6] = 56, + [0][1][0][0][RTW89_IC][6] = 74, + [0][1][0][0][RTW89_KCC][6] = 56, + [0][1][0][0][RTW89_ACMA][6] = 46, + [0][1][0][0][RTW89_CHILE][6] = 52, + [0][1][0][0][RTW89_UKRAINE][6] = 46, + [0][1][0][0][RTW89_MEXICO][6] = 74, + [0][1][0][0][RTW89_CN][6] = 44, + [0][1][0][0][RTW89_QATAR][6] = 46, + [0][1][0][0][RTW89_UK][6] = 46, + [0][1][0][0][RTW89_FCC][7] = 74, + [0][1][0][0][RTW89_ETSI][7] = 46, + [0][1][0][0][RTW89_MKK][7] = 56, + [0][1][0][0][RTW89_IC][7] = 74, + [0][1][0][0][RTW89_KCC][7] = 56, + [0][1][0][0][RTW89_ACMA][7] = 46, + [0][1][0][0][RTW89_CHILE][7] = 50, + [0][1][0][0][RTW89_UKRAINE][7] = 46, + [0][1][0][0][RTW89_MEXICO][7] = 74, + [0][1][0][0][RTW89_CN][7] = 44, + [0][1][0][0][RTW89_QATAR][7] = 46, + [0][1][0][0][RTW89_UK][7] = 46, + [0][1][0][0][RTW89_FCC][8] = 74, + [0][1][0][0][RTW89_ETSI][8] = 46, + [0][1][0][0][RTW89_MKK][8] = 56, + [0][1][0][0][RTW89_IC][8] = 74, + [0][1][0][0][RTW89_KCC][8] = 56, + [0][1][0][0][RTW89_ACMA][8] = 46, + [0][1][0][0][RTW89_CHILE][8] = 50, + [0][1][0][0][RTW89_UKRAINE][8] = 46, + [0][1][0][0][RTW89_MEXICO][8] = 74, + [0][1][0][0][RTW89_CN][8] = 44, + [0][1][0][0][RTW89_QATAR][8] = 46, + [0][1][0][0][RTW89_UK][8] = 46, + [0][1][0][0][RTW89_FCC][9] = 74, + [0][1][0][0][RTW89_ETSI][9] = 46, + [0][1][0][0][RTW89_MKK][9] = 56, + [0][1][0][0][RTW89_IC][9] = 74, + [0][1][0][0][RTW89_KCC][9] = 54, + [0][1][0][0][RTW89_ACMA][9] = 46, + [0][1][0][0][RTW89_CHILE][9] = 50, + [0][1][0][0][RTW89_UKRAINE][9] = 46, + [0][1][0][0][RTW89_MEXICO][9] = 74, + [0][1][0][0][RTW89_CN][9] = 44, + [0][1][0][0][RTW89_QATAR][9] = 46, + [0][1][0][0][RTW89_UK][9] = 46, + [0][1][0][0][RTW89_FCC][10] = 74, + [0][1][0][0][RTW89_ETSI][10] = 46, + [0][1][0][0][RTW89_MKK][10] = 56, + [0][1][0][0][RTW89_IC][10] = 74, + [0][1][0][0][RTW89_KCC][10] = 54, + [0][1][0][0][RTW89_ACMA][10] = 46, + [0][1][0][0][RTW89_CHILE][10] = 52, + [0][1][0][0][RTW89_UKRAINE][10] = 46, + [0][1][0][0][RTW89_MEXICO][10] = 74, + [0][1][0][0][RTW89_CN][10] = 44, + [0][1][0][0][RTW89_QATAR][10] = 46, + [0][1][0][0][RTW89_UK][10] = 46, + [0][1][0][0][RTW89_FCC][11] = 54, + [0][1][0][0][RTW89_ETSI][11] = 46, + [0][1][0][0][RTW89_MKK][11] = 56, + [0][1][0][0][RTW89_IC][11] = 54, + [0][1][0][0][RTW89_KCC][11] = 54, + [0][1][0][0][RTW89_ACMA][11] = 46, + [0][1][0][0][RTW89_CHILE][11] = 50, + [0][1][0][0][RTW89_UKRAINE][11] = 46, + [0][1][0][0][RTW89_MEXICO][11] = 54, + [0][1][0][0][RTW89_CN][11] = 44, + [0][1][0][0][RTW89_QATAR][11] = 46, + [0][1][0][0][RTW89_UK][11] = 46, + [0][1][0][0][RTW89_FCC][12] = 42, + [0][1][0][0][RTW89_ETSI][12] = 46, + [0][1][0][0][RTW89_MKK][12] = 56, + [0][1][0][0][RTW89_IC][12] = 42, + [0][1][0][0][RTW89_KCC][12] = 54, + [0][1][0][0][RTW89_ACMA][12] = 46, + [0][1][0][0][RTW89_CHILE][12] = 42, + [0][1][0][0][RTW89_UKRAINE][12] = 46, + [0][1][0][0][RTW89_MEXICO][12] = 42, + [0][1][0][0][RTW89_CN][12] = 44, + [0][1][0][0][RTW89_QATAR][12] = 46, + [0][1][0][0][RTW89_UK][12] = 46, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 64, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_KCC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_CHILE][13] = 127, + [0][1][0][0][RTW89_UKRAINE][13] = 127, + [0][1][0][0][RTW89_MEXICO][13] = 127, + [0][1][0][0][RTW89_CN][13] = 127, + [0][1][0][0][RTW89_QATAR][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_KCC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_CHILE][0] = 127, + [1][0][0][0][RTW89_UKRAINE][0] = 127, + [1][0][0][0][RTW89_MEXICO][0] = 127, + [1][0][0][0][RTW89_CN][0] = 127, + [1][0][0][0][RTW89_QATAR][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_KCC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_CHILE][1] = 127, + [1][0][0][0][RTW89_UKRAINE][1] = 127, + [1][0][0][0][RTW89_MEXICO][1] = 127, + [1][0][0][0][RTW89_CN][1] = 127, + [1][0][0][0][RTW89_QATAR][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 50, + [1][0][0][0][RTW89_ETSI][2] = 58, + [1][0][0][0][RTW89_MKK][2] = 76, + [1][0][0][0][RTW89_IC][2] = 50, + [1][0][0][0][RTW89_KCC][2] = 70, + [1][0][0][0][RTW89_ACMA][2] = 58, + [1][0][0][0][RTW89_CHILE][2] = 62, + [1][0][0][0][RTW89_UKRAINE][2] = 58, + [1][0][0][0][RTW89_MEXICO][2] = 50, + [1][0][0][0][RTW89_CN][2] = 56, + [1][0][0][0][RTW89_QATAR][2] = 58, + [1][0][0][0][RTW89_UK][2] = 58, + [1][0][0][0][RTW89_FCC][3] = 50, + [1][0][0][0][RTW89_ETSI][3] = 58, + [1][0][0][0][RTW89_MKK][3] = 76, + [1][0][0][0][RTW89_IC][3] = 50, + [1][0][0][0][RTW89_KCC][3] = 70, + [1][0][0][0][RTW89_ACMA][3] = 58, + [1][0][0][0][RTW89_CHILE][3] = 62, + [1][0][0][0][RTW89_UKRAINE][3] = 58, + [1][0][0][0][RTW89_MEXICO][3] = 50, + [1][0][0][0][RTW89_CN][3] = 56, + [1][0][0][0][RTW89_QATAR][3] = 58, + [1][0][0][0][RTW89_UK][3] = 58, + [1][0][0][0][RTW89_FCC][4] = 50, + [1][0][0][0][RTW89_ETSI][4] = 58, + [1][0][0][0][RTW89_MKK][4] = 76, + [1][0][0][0][RTW89_IC][4] = 50, + [1][0][0][0][RTW89_KCC][4] = 70, + [1][0][0][0][RTW89_ACMA][4] = 58, + [1][0][0][0][RTW89_CHILE][4] = 62, + [1][0][0][0][RTW89_UKRAINE][4] = 58, + [1][0][0][0][RTW89_MEXICO][4] = 50, + [1][0][0][0][RTW89_CN][4] = 56, + [1][0][0][0][RTW89_QATAR][4] = 58, + [1][0][0][0][RTW89_UK][4] = 58, + [1][0][0][0][RTW89_FCC][5] = 66, + [1][0][0][0][RTW89_ETSI][5] = 58, + [1][0][0][0][RTW89_MKK][5] = 76, + [1][0][0][0][RTW89_IC][5] = 66, + [1][0][0][0][RTW89_KCC][5] = 70, + [1][0][0][0][RTW89_ACMA][5] = 58, + [1][0][0][0][RTW89_CHILE][5] = 62, + [1][0][0][0][RTW89_UKRAINE][5] = 58, + [1][0][0][0][RTW89_MEXICO][5] = 66, + [1][0][0][0][RTW89_CN][5] = 56, + [1][0][0][0][RTW89_QATAR][5] = 58, + [1][0][0][0][RTW89_UK][5] = 58, + [1][0][0][0][RTW89_FCC][6] = 50, + [1][0][0][0][RTW89_ETSI][6] = 58, + [1][0][0][0][RTW89_MKK][6] = 76, + [1][0][0][0][RTW89_IC][6] = 50, + [1][0][0][0][RTW89_KCC][6] = 70, + [1][0][0][0][RTW89_ACMA][6] = 58, + [1][0][0][0][RTW89_CHILE][6] = 62, + [1][0][0][0][RTW89_UKRAINE][6] = 58, + [1][0][0][0][RTW89_MEXICO][6] = 50, + [1][0][0][0][RTW89_CN][6] = 56, + [1][0][0][0][RTW89_QATAR][6] = 58, + [1][0][0][0][RTW89_UK][6] = 58, + [1][0][0][0][RTW89_FCC][7] = 50, + [1][0][0][0][RTW89_ETSI][7] = 58, + [1][0][0][0][RTW89_MKK][7] = 76, + [1][0][0][0][RTW89_IC][7] = 50, + [1][0][0][0][RTW89_KCC][7] = 70, + [1][0][0][0][RTW89_ACMA][7] = 58, + [1][0][0][0][RTW89_CHILE][7] = 62, + [1][0][0][0][RTW89_UKRAINE][7] = 58, + [1][0][0][0][RTW89_MEXICO][7] = 50, + [1][0][0][0][RTW89_CN][7] = 56, + [1][0][0][0][RTW89_QATAR][7] = 58, + [1][0][0][0][RTW89_UK][7] = 58, + [1][0][0][0][RTW89_FCC][8] = 50, + [1][0][0][0][RTW89_ETSI][8] = 58, + [1][0][0][0][RTW89_MKK][8] = 76, + [1][0][0][0][RTW89_IC][8] = 50, + [1][0][0][0][RTW89_KCC][8] = 70, + [1][0][0][0][RTW89_ACMA][8] = 58, + [1][0][0][0][RTW89_CHILE][8] = 62, + [1][0][0][0][RTW89_UKRAINE][8] = 58, + [1][0][0][0][RTW89_MEXICO][8] = 50, + [1][0][0][0][RTW89_CN][8] = 56, + [1][0][0][0][RTW89_QATAR][8] = 58, + [1][0][0][0][RTW89_UK][8] = 58, + [1][0][0][0][RTW89_FCC][9] = 42, + [1][0][0][0][RTW89_ETSI][9] = 58, + [1][0][0][0][RTW89_MKK][9] = 76, + [1][0][0][0][RTW89_IC][9] = 42, + [1][0][0][0][RTW89_KCC][9] = 70, + [1][0][0][0][RTW89_ACMA][9] = 58, + [1][0][0][0][RTW89_CHILE][9] = 42, + [1][0][0][0][RTW89_UKRAINE][9] = 58, + [1][0][0][0][RTW89_MEXICO][9] = 42, + [1][0][0][0][RTW89_CN][9] = 56, + [1][0][0][0][RTW89_QATAR][9] = 58, + [1][0][0][0][RTW89_UK][9] = 58, + [1][0][0][0][RTW89_FCC][10] = 30, + [1][0][0][0][RTW89_ETSI][10] = 58, + [1][0][0][0][RTW89_MKK][10] = 72, + [1][0][0][0][RTW89_IC][10] = 30, + [1][0][0][0][RTW89_KCC][10] = 70, + [1][0][0][0][RTW89_ACMA][10] = 58, + [1][0][0][0][RTW89_CHILE][10] = 30, + [1][0][0][0][RTW89_UKRAINE][10] = 58, + [1][0][0][0][RTW89_MEXICO][10] = 30, + [1][0][0][0][RTW89_CN][10] = 56, + [1][0][0][0][RTW89_QATAR][10] = 58, + [1][0][0][0][RTW89_UK][10] = 58, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_KCC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_CHILE][11] = 127, + [1][0][0][0][RTW89_UKRAINE][11] = 127, + [1][0][0][0][RTW89_MEXICO][11] = 127, + [1][0][0][0][RTW89_CN][11] = 127, + [1][0][0][0][RTW89_QATAR][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_KCC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_CHILE][12] = 127, + [1][0][0][0][RTW89_UKRAINE][12] = 127, + [1][0][0][0][RTW89_MEXICO][12] = 127, + [1][0][0][0][RTW89_CN][12] = 127, + [1][0][0][0][RTW89_QATAR][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_KCC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_CHILE][13] = 127, + [1][0][0][0][RTW89_UKRAINE][13] = 127, + [1][0][0][0][RTW89_MEXICO][13] = 127, + [1][0][0][0][RTW89_CN][13] = 127, + [1][0][0][0][RTW89_QATAR][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_KCC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_CHILE][0] = 127, + [1][1][0][0][RTW89_UKRAINE][0] = 127, + [1][1][0][0][RTW89_MEXICO][0] = 127, + [1][1][0][0][RTW89_CN][0] = 127, + [1][1][0][0][RTW89_QATAR][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_KCC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_CHILE][1] = 127, + [1][1][0][0][RTW89_UKRAINE][1] = 127, + [1][1][0][0][RTW89_MEXICO][1] = 127, + [1][1][0][0][RTW89_CN][1] = 127, + [1][1][0][0][RTW89_QATAR][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 46, + [1][1][0][0][RTW89_ETSI][2] = 46, + [1][1][0][0][RTW89_MKK][2] = 64, + [1][1][0][0][RTW89_IC][2] = 46, + [1][1][0][0][RTW89_KCC][2] = 58, + [1][1][0][0][RTW89_ACMA][2] = 46, + [1][1][0][0][RTW89_CHILE][2] = 50, + [1][1][0][0][RTW89_UKRAINE][2] = 46, + [1][1][0][0][RTW89_MEXICO][2] = 46, + [1][1][0][0][RTW89_CN][2] = 44, + [1][1][0][0][RTW89_QATAR][2] = 46, + [1][1][0][0][RTW89_UK][2] = 46, + [1][1][0][0][RTW89_FCC][3] = 46, + [1][1][0][0][RTW89_ETSI][3] = 46, + [1][1][0][0][RTW89_MKK][3] = 64, + [1][1][0][0][RTW89_IC][3] = 46, + [1][1][0][0][RTW89_KCC][3] = 58, + [1][1][0][0][RTW89_ACMA][3] = 46, + [1][1][0][0][RTW89_CHILE][3] = 50, + [1][1][0][0][RTW89_UKRAINE][3] = 46, + [1][1][0][0][RTW89_MEXICO][3] = 46, + [1][1][0][0][RTW89_CN][3] = 44, + [1][1][0][0][RTW89_QATAR][3] = 46, + [1][1][0][0][RTW89_UK][3] = 46, + [1][1][0][0][RTW89_FCC][4] = 46, + [1][1][0][0][RTW89_ETSI][4] = 46, + [1][1][0][0][RTW89_MKK][4] = 64, + [1][1][0][0][RTW89_IC][4] = 46, + [1][1][0][0][RTW89_KCC][4] = 58, + [1][1][0][0][RTW89_ACMA][4] = 46, + [1][1][0][0][RTW89_CHILE][4] = 50, + [1][1][0][0][RTW89_UKRAINE][4] = 46, + [1][1][0][0][RTW89_MEXICO][4] = 46, + [1][1][0][0][RTW89_CN][4] = 44, + [1][1][0][0][RTW89_QATAR][4] = 46, + [1][1][0][0][RTW89_UK][4] = 46, + [1][1][0][0][RTW89_FCC][5] = 62, + [1][1][0][0][RTW89_ETSI][5] = 46, + [1][1][0][0][RTW89_MKK][5] = 64, + [1][1][0][0][RTW89_IC][5] = 62, + [1][1][0][0][RTW89_KCC][5] = 58, + [1][1][0][0][RTW89_ACMA][5] = 46, + [1][1][0][0][RTW89_CHILE][5] = 50, + [1][1][0][0][RTW89_UKRAINE][5] = 46, + [1][1][0][0][RTW89_MEXICO][5] = 62, + [1][1][0][0][RTW89_CN][5] = 44, + [1][1][0][0][RTW89_QATAR][5] = 46, + [1][1][0][0][RTW89_UK][5] = 46, + [1][1][0][0][RTW89_FCC][6] = 34, + [1][1][0][0][RTW89_ETSI][6] = 46, + [1][1][0][0][RTW89_MKK][6] = 64, + [1][1][0][0][RTW89_IC][6] = 34, + [1][1][0][0][RTW89_KCC][6] = 58, + [1][1][0][0][RTW89_ACMA][6] = 46, + [1][1][0][0][RTW89_CHILE][6] = 50, + [1][1][0][0][RTW89_UKRAINE][6] = 46, + [1][1][0][0][RTW89_MEXICO][6] = 34, + [1][1][0][0][RTW89_CN][6] = 44, + [1][1][0][0][RTW89_QATAR][6] = 46, + [1][1][0][0][RTW89_UK][6] = 46, + [1][1][0][0][RTW89_FCC][7] = 34, + [1][1][0][0][RTW89_ETSI][7] = 46, + [1][1][0][0][RTW89_MKK][7] = 64, + [1][1][0][0][RTW89_IC][7] = 34, + [1][1][0][0][RTW89_KCC][7] = 58, + [1][1][0][0][RTW89_ACMA][7] = 46, + [1][1][0][0][RTW89_CHILE][7] = 50, + [1][1][0][0][RTW89_UKRAINE][7] = 46, + [1][1][0][0][RTW89_MEXICO][7] = 34, + [1][1][0][0][RTW89_CN][7] = 44, + [1][1][0][0][RTW89_QATAR][7] = 46, + [1][1][0][0][RTW89_UK][7] = 46, + [1][1][0][0][RTW89_FCC][8] = 34, + [1][1][0][0][RTW89_ETSI][8] = 46, + [1][1][0][0][RTW89_MKK][8] = 64, + [1][1][0][0][RTW89_IC][8] = 34, + [1][1][0][0][RTW89_KCC][8] = 58, + [1][1][0][0][RTW89_ACMA][8] = 46, + [1][1][0][0][RTW89_CHILE][8] = 50, + [1][1][0][0][RTW89_UKRAINE][8] = 46, + [1][1][0][0][RTW89_MEXICO][8] = 34, + [1][1][0][0][RTW89_CN][8] = 44, + [1][1][0][0][RTW89_QATAR][8] = 46, + [1][1][0][0][RTW89_UK][8] = 46, + [1][1][0][0][RTW89_FCC][9] = 30, + [1][1][0][0][RTW89_ETSI][9] = 46, + [1][1][0][0][RTW89_MKK][9] = 64, + [1][1][0][0][RTW89_IC][9] = 30, + [1][1][0][0][RTW89_KCC][9] = 58, + [1][1][0][0][RTW89_ACMA][9] = 46, + [1][1][0][0][RTW89_CHILE][9] = 30, + [1][1][0][0][RTW89_UKRAINE][9] = 46, + [1][1][0][0][RTW89_MEXICO][9] = 30, + [1][1][0][0][RTW89_CN][9] = 44, + [1][1][0][0][RTW89_QATAR][9] = 46, + [1][1][0][0][RTW89_UK][9] = 46, + [1][1][0][0][RTW89_FCC][10] = 30, + [1][1][0][0][RTW89_ETSI][10] = 46, + [1][1][0][0][RTW89_MKK][10] = 64, + [1][1][0][0][RTW89_IC][10] = 30, + [1][1][0][0][RTW89_KCC][10] = 58, + [1][1][0][0][RTW89_ACMA][10] = 46, + [1][1][0][0][RTW89_CHILE][10] = 30, + [1][1][0][0][RTW89_UKRAINE][10] = 46, + [1][1][0][0][RTW89_MEXICO][10] = 30, + [1][1][0][0][RTW89_CN][10] = 44, + [1][1][0][0][RTW89_QATAR][10] = 46, + [1][1][0][0][RTW89_UK][10] = 46, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_KCC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_CHILE][11] = 127, + [1][1][0][0][RTW89_UKRAINE][11] = 127, + [1][1][0][0][RTW89_MEXICO][11] = 127, + [1][1][0][0][RTW89_CN][11] = 127, + [1][1][0][0][RTW89_QATAR][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_KCC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_CHILE][12] = 127, + [1][1][0][0][RTW89_UKRAINE][12] = 127, + [1][1][0][0][RTW89_MEXICO][12] = 127, + [1][1][0][0][RTW89_CN][12] = 127, + [1][1][0][0][RTW89_QATAR][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_KCC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_CHILE][13] = 127, + [1][1][0][0][RTW89_UKRAINE][13] = 127, + [1][1][0][0][RTW89_MEXICO][13] = 127, + [1][1][0][0][RTW89_CN][13] = 127, + [1][1][0][0][RTW89_QATAR][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 76, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 74, + [0][0][1][0][RTW89_IC][0] = 76, + [0][0][1][0][RTW89_KCC][0] = 76, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CHILE][0] = 66, + [0][0][1][0][RTW89_UKRAINE][0] = 58, + [0][0][1][0][RTW89_MEXICO][0] = 76, + [0][0][1][0][RTW89_CN][0] = 58, + [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][1] = 76, + [0][0][1][0][RTW89_ETSI][1] = 58, + [0][0][1][0][RTW89_MKK][1] = 76, + [0][0][1][0][RTW89_IC][1] = 76, + [0][0][1][0][RTW89_KCC][1] = 76, + [0][0][1][0][RTW89_ACMA][1] = 58, + [0][0][1][0][RTW89_CHILE][1] = 66, + [0][0][1][0][RTW89_UKRAINE][1] = 58, + [0][0][1][0][RTW89_MEXICO][1] = 76, + [0][0][1][0][RTW89_CN][1] = 58, + [0][0][1][0][RTW89_QATAR][1] = 58, + [0][0][1][0][RTW89_UK][1] = 58, + [0][0][1][0][RTW89_FCC][2] = 78, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 76, + [0][0][1][0][RTW89_IC][2] = 78, + [0][0][1][0][RTW89_KCC][2] = 76, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CHILE][2] = 66, + [0][0][1][0][RTW89_UKRAINE][2] = 58, + [0][0][1][0][RTW89_MEXICO][2] = 78, + [0][0][1][0][RTW89_CN][2] = 58, + [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][3] = 78, + [0][0][1][0][RTW89_ETSI][3] = 58, + [0][0][1][0][RTW89_MKK][3] = 76, + [0][0][1][0][RTW89_IC][3] = 78, + [0][0][1][0][RTW89_KCC][3] = 76, + [0][0][1][0][RTW89_ACMA][3] = 58, + [0][0][1][0][RTW89_CHILE][3] = 66, + [0][0][1][0][RTW89_UKRAINE][3] = 58, + [0][0][1][0][RTW89_MEXICO][3] = 78, + [0][0][1][0][RTW89_CN][3] = 58, + [0][0][1][0][RTW89_QATAR][3] = 58, + [0][0][1][0][RTW89_UK][3] = 58, + [0][0][1][0][RTW89_FCC][4] = 78, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 76, + [0][0][1][0][RTW89_IC][4] = 78, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CHILE][4] = 66, + [0][0][1][0][RTW89_UKRAINE][4] = 58, + [0][0][1][0][RTW89_MEXICO][4] = 78, + [0][0][1][0][RTW89_CN][4] = 58, + [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][5] = 78, + [0][0][1][0][RTW89_ETSI][5] = 58, + [0][0][1][0][RTW89_MKK][5] = 76, + [0][0][1][0][RTW89_IC][5] = 78, + [0][0][1][0][RTW89_KCC][5] = 76, + [0][0][1][0][RTW89_ACMA][5] = 58, + [0][0][1][0][RTW89_CHILE][5] = 66, + [0][0][1][0][RTW89_UKRAINE][5] = 58, + [0][0][1][0][RTW89_MEXICO][5] = 78, + [0][0][1][0][RTW89_CN][5] = 58, + [0][0][1][0][RTW89_QATAR][5] = 58, + [0][0][1][0][RTW89_UK][5] = 58, + [0][0][1][0][RTW89_FCC][6] = 78, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 76, + [0][0][1][0][RTW89_IC][6] = 78, + [0][0][1][0][RTW89_KCC][6] = 76, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CHILE][6] = 66, + [0][0][1][0][RTW89_UKRAINE][6] = 58, + [0][0][1][0][RTW89_MEXICO][6] = 78, + [0][0][1][0][RTW89_CN][6] = 58, + [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][7] = 78, + [0][0][1][0][RTW89_ETSI][7] = 58, + [0][0][1][0][RTW89_MKK][7] = 76, + [0][0][1][0][RTW89_IC][7] = 78, + [0][0][1][0][RTW89_KCC][7] = 76, + [0][0][1][0][RTW89_ACMA][7] = 58, + [0][0][1][0][RTW89_CHILE][7] = 66, + [0][0][1][0][RTW89_UKRAINE][7] = 58, + [0][0][1][0][RTW89_MEXICO][7] = 78, + [0][0][1][0][RTW89_CN][7] = 58, + [0][0][1][0][RTW89_QATAR][7] = 58, + [0][0][1][0][RTW89_UK][7] = 58, + [0][0][1][0][RTW89_FCC][8] = 78, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 76, + [0][0][1][0][RTW89_IC][8] = 78, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CHILE][8] = 66, + [0][0][1][0][RTW89_UKRAINE][8] = 58, + [0][0][1][0][RTW89_MEXICO][8] = 78, + [0][0][1][0][RTW89_CN][8] = 58, + [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][9] = 74, + [0][0][1][0][RTW89_ETSI][9] = 58, + [0][0][1][0][RTW89_MKK][9] = 76, + [0][0][1][0][RTW89_IC][9] = 74, + [0][0][1][0][RTW89_KCC][9] = 76, + [0][0][1][0][RTW89_ACMA][9] = 58, + [0][0][1][0][RTW89_CHILE][9] = 66, + [0][0][1][0][RTW89_UKRAINE][9] = 58, + [0][0][1][0][RTW89_MEXICO][9] = 74, + [0][0][1][0][RTW89_CN][9] = 58, + [0][0][1][0][RTW89_QATAR][9] = 58, + [0][0][1][0][RTW89_UK][9] = 58, + [0][0][1][0][RTW89_FCC][10] = 74, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 76, + [0][0][1][0][RTW89_IC][10] = 74, + [0][0][1][0][RTW89_KCC][10] = 76, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CHILE][10] = 66, + [0][0][1][0][RTW89_UKRAINE][10] = 58, + [0][0][1][0][RTW89_MEXICO][10] = 74, + [0][0][1][0][RTW89_CN][10] = 58, + [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][11] = 54, + [0][0][1][0][RTW89_ETSI][11] = 58, + [0][0][1][0][RTW89_MKK][11] = 76, + [0][0][1][0][RTW89_IC][11] = 54, + [0][0][1][0][RTW89_KCC][11] = 76, + [0][0][1][0][RTW89_ACMA][11] = 58, + [0][0][1][0][RTW89_CHILE][11] = 54, + [0][0][1][0][RTW89_UKRAINE][11] = 58, + [0][0][1][0][RTW89_MEXICO][11] = 54, + [0][0][1][0][RTW89_CN][11] = 58, + [0][0][1][0][RTW89_QATAR][11] = 58, + [0][0][1][0][RTW89_UK][11] = 58, + [0][0][1][0][RTW89_FCC][12] = 50, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 76, + [0][0][1][0][RTW89_IC][12] = 50, + [0][0][1][0][RTW89_KCC][12] = 76, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CHILE][12] = 50, + [0][0][1][0][RTW89_UKRAINE][12] = 58, + [0][0][1][0][RTW89_MEXICO][12] = 50, + [0][0][1][0][RTW89_CN][12] = 58, + [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_KCC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_CHILE][13] = 127, + [0][0][1][0][RTW89_UKRAINE][13] = 127, + [0][0][1][0][RTW89_MEXICO][13] = 127, + [0][0][1][0][RTW89_CN][13] = 127, + [0][0][1][0][RTW89_QATAR][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 62, + [0][1][1][0][RTW89_ETSI][0] = 46, + [0][1][1][0][RTW89_MKK][0] = 64, + [0][1][1][0][RTW89_IC][0] = 62, + [0][1][1][0][RTW89_KCC][0] = 66, + [0][1][1][0][RTW89_ACMA][0] = 46, + [0][1][1][0][RTW89_CHILE][0] = 50, + [0][1][1][0][RTW89_UKRAINE][0] = 46, + [0][1][1][0][RTW89_MEXICO][0] = 62, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, + [0][1][1][0][RTW89_FCC][1] = 62, + [0][1][1][0][RTW89_ETSI][1] = 46, + [0][1][1][0][RTW89_MKK][1] = 64, + [0][1][1][0][RTW89_IC][1] = 62, + [0][1][1][0][RTW89_KCC][1] = 66, + [0][1][1][0][RTW89_ACMA][1] = 46, + [0][1][1][0][RTW89_CHILE][1] = 50, + [0][1][1][0][RTW89_UKRAINE][1] = 46, + [0][1][1][0][RTW89_MEXICO][1] = 62, + [0][1][1][0][RTW89_CN][1] = 46, + [0][1][1][0][RTW89_QATAR][1] = 46, + [0][1][1][0][RTW89_UK][1] = 46, + [0][1][1][0][RTW89_FCC][2] = 66, + [0][1][1][0][RTW89_ETSI][2] = 46, + [0][1][1][0][RTW89_MKK][2] = 64, + [0][1][1][0][RTW89_IC][2] = 66, + [0][1][1][0][RTW89_KCC][2] = 66, + [0][1][1][0][RTW89_ACMA][2] = 46, + [0][1][1][0][RTW89_CHILE][2] = 50, + [0][1][1][0][RTW89_UKRAINE][2] = 46, + [0][1][1][0][RTW89_MEXICO][2] = 66, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, + [0][1][1][0][RTW89_FCC][3] = 70, + [0][1][1][0][RTW89_ETSI][3] = 46, + [0][1][1][0][RTW89_MKK][3] = 64, + [0][1][1][0][RTW89_IC][3] = 70, + [0][1][1][0][RTW89_KCC][3] = 66, + [0][1][1][0][RTW89_ACMA][3] = 46, + [0][1][1][0][RTW89_CHILE][3] = 50, + [0][1][1][0][RTW89_UKRAINE][3] = 46, + [0][1][1][0][RTW89_MEXICO][3] = 70, + [0][1][1][0][RTW89_CN][3] = 46, + [0][1][1][0][RTW89_QATAR][3] = 46, + [0][1][1][0][RTW89_UK][3] = 46, + [0][1][1][0][RTW89_FCC][4] = 78, + [0][1][1][0][RTW89_ETSI][4] = 46, + [0][1][1][0][RTW89_MKK][4] = 64, + [0][1][1][0][RTW89_IC][4] = 78, + [0][1][1][0][RTW89_KCC][4] = 64, + [0][1][1][0][RTW89_ACMA][4] = 46, + [0][1][1][0][RTW89_CHILE][4] = 50, + [0][1][1][0][RTW89_UKRAINE][4] = 46, + [0][1][1][0][RTW89_MEXICO][4] = 78, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, + [0][1][1][0][RTW89_FCC][5] = 78, + [0][1][1][0][RTW89_ETSI][5] = 46, + [0][1][1][0][RTW89_MKK][5] = 64, + [0][1][1][0][RTW89_IC][5] = 78, + [0][1][1][0][RTW89_KCC][5] = 64, + [0][1][1][0][RTW89_ACMA][5] = 46, + [0][1][1][0][RTW89_CHILE][5] = 50, + [0][1][1][0][RTW89_UKRAINE][5] = 46, + [0][1][1][0][RTW89_MEXICO][5] = 78, + [0][1][1][0][RTW89_CN][5] = 46, + [0][1][1][0][RTW89_QATAR][5] = 46, + [0][1][1][0][RTW89_UK][5] = 46, + [0][1][1][0][RTW89_FCC][6] = 78, + [0][1][1][0][RTW89_ETSI][6] = 46, + [0][1][1][0][RTW89_MKK][6] = 64, + [0][1][1][0][RTW89_IC][6] = 78, + [0][1][1][0][RTW89_KCC][6] = 64, + [0][1][1][0][RTW89_ACMA][6] = 46, + [0][1][1][0][RTW89_CHILE][6] = 50, + [0][1][1][0][RTW89_UKRAINE][6] = 46, + [0][1][1][0][RTW89_MEXICO][6] = 78, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, + [0][1][1][0][RTW89_FCC][7] = 70, + [0][1][1][0][RTW89_ETSI][7] = 46, + [0][1][1][0][RTW89_MKK][7] = 64, + [0][1][1][0][RTW89_IC][7] = 70, + [0][1][1][0][RTW89_KCC][7] = 64, + [0][1][1][0][RTW89_ACMA][7] = 46, + [0][1][1][0][RTW89_CHILE][7] = 50, + [0][1][1][0][RTW89_UKRAINE][7] = 46, + [0][1][1][0][RTW89_MEXICO][7] = 70, + [0][1][1][0][RTW89_CN][7] = 46, + [0][1][1][0][RTW89_QATAR][7] = 46, + [0][1][1][0][RTW89_UK][7] = 46, + [0][1][1][0][RTW89_FCC][8] = 66, + [0][1][1][0][RTW89_ETSI][8] = 46, + [0][1][1][0][RTW89_MKK][8] = 64, + [0][1][1][0][RTW89_IC][8] = 66, + [0][1][1][0][RTW89_KCC][8] = 64, + [0][1][1][0][RTW89_ACMA][8] = 46, + [0][1][1][0][RTW89_CHILE][8] = 50, + [0][1][1][0][RTW89_UKRAINE][8] = 46, + [0][1][1][0][RTW89_MEXICO][8] = 66, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, + [0][1][1][0][RTW89_FCC][9] = 62, + [0][1][1][0][RTW89_ETSI][9] = 46, + [0][1][1][0][RTW89_MKK][9] = 64, + [0][1][1][0][RTW89_IC][9] = 62, + [0][1][1][0][RTW89_KCC][9] = 64, + [0][1][1][0][RTW89_ACMA][9] = 46, + [0][1][1][0][RTW89_CHILE][9] = 50, + [0][1][1][0][RTW89_UKRAINE][9] = 46, + [0][1][1][0][RTW89_MEXICO][9] = 62, + [0][1][1][0][RTW89_CN][9] = 46, + [0][1][1][0][RTW89_QATAR][9] = 46, + [0][1][1][0][RTW89_UK][9] = 46, + [0][1][1][0][RTW89_FCC][10] = 62, + [0][1][1][0][RTW89_ETSI][10] = 46, + [0][1][1][0][RTW89_MKK][10] = 64, + [0][1][1][0][RTW89_IC][10] = 62, + [0][1][1][0][RTW89_KCC][10] = 64, + [0][1][1][0][RTW89_ACMA][10] = 46, + [0][1][1][0][RTW89_CHILE][10] = 52, + [0][1][1][0][RTW89_UKRAINE][10] = 46, + [0][1][1][0][RTW89_MEXICO][10] = 62, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, + [0][1][1][0][RTW89_FCC][11] = 46, + [0][1][1][0][RTW89_ETSI][11] = 46, + [0][1][1][0][RTW89_MKK][11] = 64, + [0][1][1][0][RTW89_IC][11] = 46, + [0][1][1][0][RTW89_KCC][11] = 64, + [0][1][1][0][RTW89_ACMA][11] = 46, + [0][1][1][0][RTW89_CHILE][11] = 46, + [0][1][1][0][RTW89_UKRAINE][11] = 46, + [0][1][1][0][RTW89_MEXICO][11] = 46, + [0][1][1][0][RTW89_CN][11] = 46, + [0][1][1][0][RTW89_QATAR][11] = 46, + [0][1][1][0][RTW89_UK][11] = 46, + [0][1][1][0][RTW89_FCC][12] = 42, + [0][1][1][0][RTW89_ETSI][12] = 46, + [0][1][1][0][RTW89_MKK][12] = 64, + [0][1][1][0][RTW89_IC][12] = 42, + [0][1][1][0][RTW89_KCC][12] = 64, + [0][1][1][0][RTW89_ACMA][12] = 46, + [0][1][1][0][RTW89_CHILE][12] = 42, + [0][1][1][0][RTW89_UKRAINE][12] = 46, + [0][1][1][0][RTW89_MEXICO][12] = 42, + [0][1][1][0][RTW89_CN][12] = 46, + [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_KCC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_CHILE][13] = 127, + [0][1][1][0][RTW89_UKRAINE][13] = 127, + [0][1][1][0][RTW89_MEXICO][13] = 127, + [0][1][1][0][RTW89_CN][13] = 127, + [0][1][1][0][RTW89_QATAR][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 76, + [0][0][2][0][RTW89_ETSI][0] = 58, + [0][0][2][0][RTW89_MKK][0] = 76, + [0][0][2][0][RTW89_IC][0] = 76, + [0][0][2][0][RTW89_KCC][0] = 76, + [0][0][2][0][RTW89_ACMA][0] = 58, + [0][0][2][0][RTW89_CHILE][0] = 66, + [0][0][2][0][RTW89_UKRAINE][0] = 58, + [0][0][2][0][RTW89_MEXICO][0] = 76, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_QATAR][0] = 58, + [0][0][2][0][RTW89_UK][0] = 58, + [0][0][2][0][RTW89_FCC][1] = 76, + [0][0][2][0][RTW89_ETSI][1] = 58, + [0][0][2][0][RTW89_MKK][1] = 76, + [0][0][2][0][RTW89_IC][1] = 76, + [0][0][2][0][RTW89_KCC][1] = 76, + [0][0][2][0][RTW89_ACMA][1] = 58, + [0][0][2][0][RTW89_CHILE][1] = 66, + [0][0][2][0][RTW89_UKRAINE][1] = 58, + [0][0][2][0][RTW89_MEXICO][1] = 76, + [0][0][2][0][RTW89_CN][1] = 58, + [0][0][2][0][RTW89_QATAR][1] = 58, + [0][0][2][0][RTW89_UK][1] = 58, + [0][0][2][0][RTW89_FCC][2] = 78, + [0][0][2][0][RTW89_ETSI][2] = 58, + [0][0][2][0][RTW89_MKK][2] = 76, + [0][0][2][0][RTW89_IC][2] = 78, + [0][0][2][0][RTW89_KCC][2] = 76, + [0][0][2][0][RTW89_ACMA][2] = 58, + [0][0][2][0][RTW89_CHILE][2] = 66, + [0][0][2][0][RTW89_UKRAINE][2] = 58, + [0][0][2][0][RTW89_MEXICO][2] = 78, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_QATAR][2] = 58, + [0][0][2][0][RTW89_UK][2] = 58, + [0][0][2][0][RTW89_FCC][3] = 78, + [0][0][2][0][RTW89_ETSI][3] = 58, + [0][0][2][0][RTW89_MKK][3] = 76, + [0][0][2][0][RTW89_IC][3] = 78, + [0][0][2][0][RTW89_KCC][3] = 76, + [0][0][2][0][RTW89_ACMA][3] = 58, + [0][0][2][0][RTW89_CHILE][3] = 66, + [0][0][2][0][RTW89_UKRAINE][3] = 58, + [0][0][2][0][RTW89_MEXICO][3] = 78, + [0][0][2][0][RTW89_CN][3] = 58, + [0][0][2][0][RTW89_QATAR][3] = 58, + [0][0][2][0][RTW89_UK][3] = 58, + [0][0][2][0][RTW89_FCC][4] = 78, + [0][0][2][0][RTW89_ETSI][4] = 58, + [0][0][2][0][RTW89_MKK][4] = 76, + [0][0][2][0][RTW89_IC][4] = 78, + [0][0][2][0][RTW89_KCC][4] = 76, + [0][0][2][0][RTW89_ACMA][4] = 58, + [0][0][2][0][RTW89_CHILE][4] = 66, + [0][0][2][0][RTW89_UKRAINE][4] = 58, + [0][0][2][0][RTW89_MEXICO][4] = 78, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_QATAR][4] = 58, + [0][0][2][0][RTW89_UK][4] = 58, + [0][0][2][0][RTW89_FCC][5] = 78, + [0][0][2][0][RTW89_ETSI][5] = 58, + [0][0][2][0][RTW89_MKK][5] = 76, + [0][0][2][0][RTW89_IC][5] = 78, + [0][0][2][0][RTW89_KCC][5] = 76, + [0][0][2][0][RTW89_ACMA][5] = 58, + [0][0][2][0][RTW89_CHILE][5] = 66, + [0][0][2][0][RTW89_UKRAINE][5] = 58, + [0][0][2][0][RTW89_MEXICO][5] = 78, + [0][0][2][0][RTW89_CN][5] = 58, + [0][0][2][0][RTW89_QATAR][5] = 58, + [0][0][2][0][RTW89_UK][5] = 58, + [0][0][2][0][RTW89_FCC][6] = 78, + [0][0][2][0][RTW89_ETSI][6] = 58, + [0][0][2][0][RTW89_MKK][6] = 76, + [0][0][2][0][RTW89_IC][6] = 78, + [0][0][2][0][RTW89_KCC][6] = 76, + [0][0][2][0][RTW89_ACMA][6] = 58, + [0][0][2][0][RTW89_CHILE][6] = 66, + [0][0][2][0][RTW89_UKRAINE][6] = 58, + [0][0][2][0][RTW89_MEXICO][6] = 78, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_QATAR][6] = 58, + [0][0][2][0][RTW89_UK][6] = 58, + [0][0][2][0][RTW89_FCC][7] = 78, + [0][0][2][0][RTW89_ETSI][7] = 58, + [0][0][2][0][RTW89_MKK][7] = 76, + [0][0][2][0][RTW89_IC][7] = 78, + [0][0][2][0][RTW89_KCC][7] = 76, + [0][0][2][0][RTW89_ACMA][7] = 58, + [0][0][2][0][RTW89_CHILE][7] = 66, + [0][0][2][0][RTW89_UKRAINE][7] = 58, + [0][0][2][0][RTW89_MEXICO][7] = 78, + [0][0][2][0][RTW89_CN][7] = 58, + [0][0][2][0][RTW89_QATAR][7] = 58, + [0][0][2][0][RTW89_UK][7] = 58, + [0][0][2][0][RTW89_FCC][8] = 76, + [0][0][2][0][RTW89_ETSI][8] = 58, + [0][0][2][0][RTW89_MKK][8] = 76, + [0][0][2][0][RTW89_IC][8] = 76, + [0][0][2][0][RTW89_KCC][8] = 76, + [0][0][2][0][RTW89_ACMA][8] = 58, + [0][0][2][0][RTW89_CHILE][8] = 66, + [0][0][2][0][RTW89_UKRAINE][8] = 58, + [0][0][2][0][RTW89_MEXICO][8] = 76, + [0][0][2][0][RTW89_CN][8] = 58, + [0][0][2][0][RTW89_QATAR][8] = 58, + [0][0][2][0][RTW89_UK][8] = 58, + [0][0][2][0][RTW89_FCC][9] = 72, + [0][0][2][0][RTW89_ETSI][9] = 58, + [0][0][2][0][RTW89_MKK][9] = 76, + [0][0][2][0][RTW89_IC][9] = 72, + [0][0][2][0][RTW89_KCC][9] = 76, + [0][0][2][0][RTW89_ACMA][9] = 58, + [0][0][2][0][RTW89_CHILE][9] = 66, + [0][0][2][0][RTW89_UKRAINE][9] = 58, + [0][0][2][0][RTW89_MEXICO][9] = 72, + [0][0][2][0][RTW89_CN][9] = 58, + [0][0][2][0][RTW89_QATAR][9] = 58, + [0][0][2][0][RTW89_UK][9] = 58, + [0][0][2][0][RTW89_FCC][10] = 72, + [0][0][2][0][RTW89_ETSI][10] = 58, + [0][0][2][0][RTW89_MKK][10] = 76, + [0][0][2][0][RTW89_IC][10] = 72, + [0][0][2][0][RTW89_KCC][10] = 76, + [0][0][2][0][RTW89_ACMA][10] = 58, + [0][0][2][0][RTW89_CHILE][10] = 66, + [0][0][2][0][RTW89_UKRAINE][10] = 58, + [0][0][2][0][RTW89_MEXICO][10] = 72, + [0][0][2][0][RTW89_CN][10] = 58, + [0][0][2][0][RTW89_QATAR][10] = 58, + [0][0][2][0][RTW89_UK][10] = 58, + [0][0][2][0][RTW89_FCC][11] = 54, + [0][0][2][0][RTW89_ETSI][11] = 58, + [0][0][2][0][RTW89_MKK][11] = 76, + [0][0][2][0][RTW89_IC][11] = 54, + [0][0][2][0][RTW89_KCC][11] = 76, + [0][0][2][0][RTW89_ACMA][11] = 58, + [0][0][2][0][RTW89_CHILE][11] = 54, + [0][0][2][0][RTW89_UKRAINE][11] = 58, + [0][0][2][0][RTW89_MEXICO][11] = 54, + [0][0][2][0][RTW89_CN][11] = 58, + [0][0][2][0][RTW89_QATAR][11] = 58, + [0][0][2][0][RTW89_UK][11] = 58, + [0][0][2][0][RTW89_FCC][12] = 50, + [0][0][2][0][RTW89_ETSI][12] = 58, + [0][0][2][0][RTW89_MKK][12] = 76, + [0][0][2][0][RTW89_IC][12] = 50, + [0][0][2][0][RTW89_KCC][12] = 76, + [0][0][2][0][RTW89_ACMA][12] = 58, + [0][0][2][0][RTW89_CHILE][12] = 50, + [0][0][2][0][RTW89_UKRAINE][12] = 58, + [0][0][2][0][RTW89_MEXICO][12] = 50, + [0][0][2][0][RTW89_CN][12] = 58, + [0][0][2][0][RTW89_QATAR][12] = 58, + [0][0][2][0][RTW89_UK][12] = 58, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_KCC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_CHILE][13] = 127, + [0][0][2][0][RTW89_UKRAINE][13] = 127, + [0][0][2][0][RTW89_MEXICO][13] = 127, + [0][0][2][0][RTW89_CN][13] = 127, + [0][0][2][0][RTW89_QATAR][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 58, + [0][1][2][0][RTW89_ETSI][0] = 46, + [0][1][2][0][RTW89_MKK][0] = 66, + [0][1][2][0][RTW89_IC][0] = 58, + [0][1][2][0][RTW89_KCC][0] = 62, + [0][1][2][0][RTW89_ACMA][0] = 46, + [0][1][2][0][RTW89_CHILE][0] = 50, + [0][1][2][0][RTW89_UKRAINE][0] = 46, + [0][1][2][0][RTW89_MEXICO][0] = 58, + [0][1][2][0][RTW89_CN][0] = 46, + [0][1][2][0][RTW89_QATAR][0] = 46, + [0][1][2][0][RTW89_UK][0] = 46, + [0][1][2][0][RTW89_FCC][1] = 58, + [0][1][2][0][RTW89_ETSI][1] = 46, + [0][1][2][0][RTW89_MKK][1] = 66, + [0][1][2][0][RTW89_IC][1] = 58, + [0][1][2][0][RTW89_KCC][1] = 62, + [0][1][2][0][RTW89_ACMA][1] = 46, + [0][1][2][0][RTW89_CHILE][1] = 50, + [0][1][2][0][RTW89_UKRAINE][1] = 46, + [0][1][2][0][RTW89_MEXICO][1] = 58, + [0][1][2][0][RTW89_CN][1] = 46, + [0][1][2][0][RTW89_QATAR][1] = 46, + [0][1][2][0][RTW89_UK][1] = 46, + [0][1][2][0][RTW89_FCC][2] = 62, + [0][1][2][0][RTW89_ETSI][2] = 46, + [0][1][2][0][RTW89_MKK][2] = 66, + [0][1][2][0][RTW89_IC][2] = 62, + [0][1][2][0][RTW89_KCC][2] = 62, + [0][1][2][0][RTW89_ACMA][2] = 46, + [0][1][2][0][RTW89_CHILE][2] = 50, + [0][1][2][0][RTW89_UKRAINE][2] = 46, + [0][1][2][0][RTW89_MEXICO][2] = 62, + [0][1][2][0][RTW89_CN][2] = 46, + [0][1][2][0][RTW89_QATAR][2] = 46, + [0][1][2][0][RTW89_UK][2] = 46, + [0][1][2][0][RTW89_FCC][3] = 66, + [0][1][2][0][RTW89_ETSI][3] = 46, + [0][1][2][0][RTW89_MKK][3] = 66, + [0][1][2][0][RTW89_IC][3] = 66, + [0][1][2][0][RTW89_KCC][3] = 62, + [0][1][2][0][RTW89_ACMA][3] = 46, + [0][1][2][0][RTW89_CHILE][3] = 50, + [0][1][2][0][RTW89_UKRAINE][3] = 46, + [0][1][2][0][RTW89_MEXICO][3] = 66, + [0][1][2][0][RTW89_CN][3] = 46, + [0][1][2][0][RTW89_QATAR][3] = 46, + [0][1][2][0][RTW89_UK][3] = 46, + [0][1][2][0][RTW89_FCC][4] = 72, + [0][1][2][0][RTW89_ETSI][4] = 46, + [0][1][2][0][RTW89_MKK][4] = 66, + [0][1][2][0][RTW89_IC][4] = 72, + [0][1][2][0][RTW89_KCC][4] = 62, + [0][1][2][0][RTW89_ACMA][4] = 46, + [0][1][2][0][RTW89_CHILE][4] = 50, + [0][1][2][0][RTW89_UKRAINE][4] = 46, + [0][1][2][0][RTW89_MEXICO][4] = 72, + [0][1][2][0][RTW89_CN][4] = 46, + [0][1][2][0][RTW89_QATAR][4] = 46, + [0][1][2][0][RTW89_UK][4] = 46, + [0][1][2][0][RTW89_FCC][5] = 78, + [0][1][2][0][RTW89_ETSI][5] = 46, + [0][1][2][0][RTW89_MKK][5] = 66, + [0][1][2][0][RTW89_IC][5] = 78, + [0][1][2][0][RTW89_KCC][5] = 62, + [0][1][2][0][RTW89_ACMA][5] = 46, + [0][1][2][0][RTW89_CHILE][5] = 50, + [0][1][2][0][RTW89_UKRAINE][5] = 46, + [0][1][2][0][RTW89_MEXICO][5] = 78, + [0][1][2][0][RTW89_CN][5] = 46, + [0][1][2][0][RTW89_QATAR][5] = 46, + [0][1][2][0][RTW89_UK][5] = 46, + [0][1][2][0][RTW89_FCC][6] = 74, + [0][1][2][0][RTW89_ETSI][6] = 46, + [0][1][2][0][RTW89_MKK][6] = 66, + [0][1][2][0][RTW89_IC][6] = 74, + [0][1][2][0][RTW89_KCC][6] = 62, + [0][1][2][0][RTW89_ACMA][6] = 46, + [0][1][2][0][RTW89_CHILE][6] = 50, + [0][1][2][0][RTW89_UKRAINE][6] = 46, + [0][1][2][0][RTW89_MEXICO][6] = 74, + [0][1][2][0][RTW89_CN][6] = 46, + [0][1][2][0][RTW89_QATAR][6] = 46, + [0][1][2][0][RTW89_UK][6] = 46, + [0][1][2][0][RTW89_FCC][7] = 66, + [0][1][2][0][RTW89_ETSI][7] = 46, + [0][1][2][0][RTW89_MKK][7] = 66, + [0][1][2][0][RTW89_IC][7] = 66, + [0][1][2][0][RTW89_KCC][7] = 62, + [0][1][2][0][RTW89_ACMA][7] = 46, + [0][1][2][0][RTW89_CHILE][7] = 50, + [0][1][2][0][RTW89_UKRAINE][7] = 46, + [0][1][2][0][RTW89_MEXICO][7] = 66, + [0][1][2][0][RTW89_CN][7] = 46, + [0][1][2][0][RTW89_QATAR][7] = 46, + [0][1][2][0][RTW89_UK][7] = 46, + [0][1][2][0][RTW89_FCC][8] = 62, + [0][1][2][0][RTW89_ETSI][8] = 46, + [0][1][2][0][RTW89_MKK][8] = 66, + [0][1][2][0][RTW89_IC][8] = 62, + [0][1][2][0][RTW89_KCC][8] = 62, + [0][1][2][0][RTW89_ACMA][8] = 46, + [0][1][2][0][RTW89_CHILE][8] = 50, + [0][1][2][0][RTW89_UKRAINE][8] = 46, + [0][1][2][0][RTW89_MEXICO][8] = 62, + [0][1][2][0][RTW89_CN][8] = 46, + [0][1][2][0][RTW89_QATAR][8] = 46, + [0][1][2][0][RTW89_UK][8] = 46, + [0][1][2][0][RTW89_FCC][9] = 58, + [0][1][2][0][RTW89_ETSI][9] = 46, + [0][1][2][0][RTW89_MKK][9] = 66, + [0][1][2][0][RTW89_IC][9] = 58, + [0][1][2][0][RTW89_KCC][9] = 60, + [0][1][2][0][RTW89_ACMA][9] = 46, + [0][1][2][0][RTW89_CHILE][9] = 50, + [0][1][2][0][RTW89_UKRAINE][9] = 46, + [0][1][2][0][RTW89_MEXICO][9] = 58, + [0][1][2][0][RTW89_CN][9] = 46, + [0][1][2][0][RTW89_QATAR][9] = 46, + [0][1][2][0][RTW89_UK][9] = 46, + [0][1][2][0][RTW89_FCC][10] = 58, + [0][1][2][0][RTW89_ETSI][10] = 46, + [0][1][2][0][RTW89_MKK][10] = 66, + [0][1][2][0][RTW89_IC][10] = 58, + [0][1][2][0][RTW89_KCC][10] = 60, + [0][1][2][0][RTW89_ACMA][10] = 46, + [0][1][2][0][RTW89_CHILE][10] = 50, + [0][1][2][0][RTW89_UKRAINE][10] = 46, + [0][1][2][0][RTW89_MEXICO][10] = 58, + [0][1][2][0][RTW89_CN][10] = 46, + [0][1][2][0][RTW89_QATAR][10] = 46, + [0][1][2][0][RTW89_UK][10] = 46, + [0][1][2][0][RTW89_FCC][11] = 46, + [0][1][2][0][RTW89_ETSI][11] = 46, + [0][1][2][0][RTW89_MKK][11] = 66, + [0][1][2][0][RTW89_IC][11] = 46, + [0][1][2][0][RTW89_KCC][11] = 60, + [0][1][2][0][RTW89_ACMA][11] = 46, + [0][1][2][0][RTW89_CHILE][11] = 46, + [0][1][2][0][RTW89_UKRAINE][11] = 46, + [0][1][2][0][RTW89_MEXICO][11] = 46, + [0][1][2][0][RTW89_CN][11] = 46, + [0][1][2][0][RTW89_QATAR][11] = 46, + [0][1][2][0][RTW89_UK][11] = 46, + [0][1][2][0][RTW89_FCC][12] = 42, + [0][1][2][0][RTW89_ETSI][12] = 46, + [0][1][2][0][RTW89_MKK][12] = 66, + [0][1][2][0][RTW89_IC][12] = 42, + [0][1][2][0][RTW89_KCC][12] = 60, + [0][1][2][0][RTW89_ACMA][12] = 46, + [0][1][2][0][RTW89_CHILE][12] = 42, + [0][1][2][0][RTW89_UKRAINE][12] = 46, + [0][1][2][0][RTW89_MEXICO][12] = 42, + [0][1][2][0][RTW89_CN][12] = 46, + [0][1][2][0][RTW89_QATAR][12] = 46, + [0][1][2][0][RTW89_UK][12] = 46, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_KCC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_CHILE][13] = 127, + [0][1][2][0][RTW89_UKRAINE][13] = 127, + [0][1][2][0][RTW89_MEXICO][13] = 127, + [0][1][2][0][RTW89_CN][13] = 127, + [0][1][2][0][RTW89_QATAR][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 58, + [0][1][2][1][RTW89_ETSI][0] = 34, + [0][1][2][1][RTW89_MKK][0] = 66, + [0][1][2][1][RTW89_IC][0] = 58, + [0][1][2][1][RTW89_KCC][0] = 62, + [0][1][2][1][RTW89_ACMA][0] = 34, + [0][1][2][1][RTW89_CHILE][0] = 42, + [0][1][2][1][RTW89_UKRAINE][0] = 34, + [0][1][2][1][RTW89_MEXICO][0] = 58, + [0][1][2][1][RTW89_CN][0] = 34, + [0][1][2][1][RTW89_QATAR][0] = 34, + [0][1][2][1][RTW89_UK][0] = 34, + [0][1][2][1][RTW89_FCC][1] = 58, + [0][1][2][1][RTW89_ETSI][1] = 34, + [0][1][2][1][RTW89_MKK][1] = 66, + [0][1][2][1][RTW89_IC][1] = 58, + [0][1][2][1][RTW89_KCC][1] = 62, + [0][1][2][1][RTW89_ACMA][1] = 34, + [0][1][2][1][RTW89_CHILE][1] = 40, + [0][1][2][1][RTW89_UKRAINE][1] = 34, + [0][1][2][1][RTW89_MEXICO][1] = 58, + [0][1][2][1][RTW89_CN][1] = 34, + [0][1][2][1][RTW89_QATAR][1] = 34, + [0][1][2][1][RTW89_UK][1] = 34, + [0][1][2][1][RTW89_FCC][2] = 62, + [0][1][2][1][RTW89_ETSI][2] = 34, + [0][1][2][1][RTW89_MKK][2] = 66, + [0][1][2][1][RTW89_IC][2] = 62, + [0][1][2][1][RTW89_KCC][2] = 62, + [0][1][2][1][RTW89_ACMA][2] = 34, + [0][1][2][1][RTW89_CHILE][2] = 40, + [0][1][2][1][RTW89_UKRAINE][2] = 34, + [0][1][2][1][RTW89_MEXICO][2] = 62, + [0][1][2][1][RTW89_CN][2] = 34, + [0][1][2][1][RTW89_QATAR][2] = 34, + [0][1][2][1][RTW89_UK][2] = 34, + [0][1][2][1][RTW89_FCC][3] = 66, + [0][1][2][1][RTW89_ETSI][3] = 34, + [0][1][2][1][RTW89_MKK][3] = 66, + [0][1][2][1][RTW89_IC][3] = 66, + [0][1][2][1][RTW89_KCC][3] = 62, + [0][1][2][1][RTW89_ACMA][3] = 34, + [0][1][2][1][RTW89_CHILE][3] = 40, + [0][1][2][1][RTW89_UKRAINE][3] = 34, + [0][1][2][1][RTW89_MEXICO][3] = 66, + [0][1][2][1][RTW89_CN][3] = 34, + [0][1][2][1][RTW89_QATAR][3] = 34, + [0][1][2][1][RTW89_UK][3] = 34, + [0][1][2][1][RTW89_FCC][4] = 72, + [0][1][2][1][RTW89_ETSI][4] = 34, + [0][1][2][1][RTW89_MKK][4] = 66, + [0][1][2][1][RTW89_IC][4] = 72, + [0][1][2][1][RTW89_KCC][4] = 62, + [0][1][2][1][RTW89_ACMA][4] = 34, + [0][1][2][1][RTW89_CHILE][4] = 40, + [0][1][2][1][RTW89_UKRAINE][4] = 34, + [0][1][2][1][RTW89_MEXICO][4] = 72, + [0][1][2][1][RTW89_CN][4] = 34, + [0][1][2][1][RTW89_QATAR][4] = 34, + [0][1][2][1][RTW89_UK][4] = 34, + [0][1][2][1][RTW89_FCC][5] = 78, + [0][1][2][1][RTW89_ETSI][5] = 34, + [0][1][2][1][RTW89_MKK][5] = 66, + [0][1][2][1][RTW89_IC][5] = 78, + [0][1][2][1][RTW89_KCC][5] = 62, + [0][1][2][1][RTW89_ACMA][5] = 34, + [0][1][2][1][RTW89_CHILE][5] = 42, + [0][1][2][1][RTW89_UKRAINE][5] = 34, + [0][1][2][1][RTW89_MEXICO][5] = 78, + [0][1][2][1][RTW89_CN][5] = 34, + [0][1][2][1][RTW89_QATAR][5] = 34, + [0][1][2][1][RTW89_UK][5] = 34, + [0][1][2][1][RTW89_FCC][6] = 74, + [0][1][2][1][RTW89_ETSI][6] = 34, + [0][1][2][1][RTW89_MKK][6] = 66, + [0][1][2][1][RTW89_IC][6] = 74, + [0][1][2][1][RTW89_KCC][6] = 62, + [0][1][2][1][RTW89_ACMA][6] = 34, + [0][1][2][1][RTW89_CHILE][6] = 40, + [0][1][2][1][RTW89_UKRAINE][6] = 34, + [0][1][2][1][RTW89_MEXICO][6] = 74, + [0][1][2][1][RTW89_CN][6] = 34, + [0][1][2][1][RTW89_QATAR][6] = 34, + [0][1][2][1][RTW89_UK][6] = 34, + [0][1][2][1][RTW89_FCC][7] = 66, + [0][1][2][1][RTW89_ETSI][7] = 34, + [0][1][2][1][RTW89_MKK][7] = 66, + [0][1][2][1][RTW89_IC][7] = 66, + [0][1][2][1][RTW89_KCC][7] = 62, + [0][1][2][1][RTW89_ACMA][7] = 34, + [0][1][2][1][RTW89_CHILE][7] = 40, + [0][1][2][1][RTW89_UKRAINE][7] = 34, + [0][1][2][1][RTW89_MEXICO][7] = 66, + [0][1][2][1][RTW89_CN][7] = 34, + [0][1][2][1][RTW89_QATAR][7] = 34, + [0][1][2][1][RTW89_UK][7] = 34, + [0][1][2][1][RTW89_FCC][8] = 62, + [0][1][2][1][RTW89_ETSI][8] = 34, + [0][1][2][1][RTW89_MKK][8] = 66, + [0][1][2][1][RTW89_IC][8] = 62, + [0][1][2][1][RTW89_KCC][8] = 62, + [0][1][2][1][RTW89_ACMA][8] = 34, + [0][1][2][1][RTW89_CHILE][8] = 40, + [0][1][2][1][RTW89_UKRAINE][8] = 34, + [0][1][2][1][RTW89_MEXICO][8] = 62, + [0][1][2][1][RTW89_CN][8] = 34, + [0][1][2][1][RTW89_QATAR][8] = 34, + [0][1][2][1][RTW89_UK][8] = 34, + [0][1][2][1][RTW89_FCC][9] = 58, + [0][1][2][1][RTW89_ETSI][9] = 34, + [0][1][2][1][RTW89_MKK][9] = 66, + [0][1][2][1][RTW89_IC][9] = 58, + [0][1][2][1][RTW89_KCC][9] = 60, + [0][1][2][1][RTW89_ACMA][9] = 34, + [0][1][2][1][RTW89_CHILE][9] = 40, + [0][1][2][1][RTW89_UKRAINE][9] = 34, + [0][1][2][1][RTW89_MEXICO][9] = 58, + [0][1][2][1][RTW89_CN][9] = 34, + [0][1][2][1][RTW89_QATAR][9] = 34, + [0][1][2][1][RTW89_UK][9] = 34, + [0][1][2][1][RTW89_FCC][10] = 58, + [0][1][2][1][RTW89_ETSI][10] = 34, + [0][1][2][1][RTW89_MKK][10] = 66, + [0][1][2][1][RTW89_IC][10] = 58, + [0][1][2][1][RTW89_KCC][10] = 60, + [0][1][2][1][RTW89_ACMA][10] = 34, + [0][1][2][1][RTW89_CHILE][10] = 40, + [0][1][2][1][RTW89_UKRAINE][10] = 34, + [0][1][2][1][RTW89_MEXICO][10] = 58, + [0][1][2][1][RTW89_CN][10] = 34, + [0][1][2][1][RTW89_QATAR][10] = 34, + [0][1][2][1][RTW89_UK][10] = 34, + [0][1][2][1][RTW89_FCC][11] = 46, + [0][1][2][1][RTW89_ETSI][11] = 34, + [0][1][2][1][RTW89_MKK][11] = 66, + [0][1][2][1][RTW89_IC][11] = 46, + [0][1][2][1][RTW89_KCC][11] = 60, + [0][1][2][1][RTW89_ACMA][11] = 34, + [0][1][2][1][RTW89_CHILE][11] = 40, + [0][1][2][1][RTW89_UKRAINE][11] = 34, + [0][1][2][1][RTW89_MEXICO][11] = 46, + [0][1][2][1][RTW89_CN][11] = 34, + [0][1][2][1][RTW89_QATAR][11] = 34, + [0][1][2][1][RTW89_UK][11] = 34, + [0][1][2][1][RTW89_FCC][12] = 42, + [0][1][2][1][RTW89_ETSI][12] = 34, + [0][1][2][1][RTW89_MKK][12] = 66, + [0][1][2][1][RTW89_IC][12] = 42, + [0][1][2][1][RTW89_KCC][12] = 60, + [0][1][2][1][RTW89_ACMA][12] = 34, + [0][1][2][1][RTW89_CHILE][12] = 40, + [0][1][2][1][RTW89_UKRAINE][12] = 34, + [0][1][2][1][RTW89_MEXICO][12] = 42, + [0][1][2][1][RTW89_CN][12] = 34, + [0][1][2][1][RTW89_QATAR][12] = 34, + [0][1][2][1][RTW89_UK][12] = 34, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_KCC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_CHILE][13] = 127, + [0][1][2][1][RTW89_UKRAINE][13] = 127, + [0][1][2][1][RTW89_MEXICO][13] = 127, + [0][1][2][1][RTW89_CN][13] = 127, + [0][1][2][1][RTW89_QATAR][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_KCC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_CHILE][0] = 127, + [1][0][2][0][RTW89_UKRAINE][0] = 127, + [1][0][2][0][RTW89_MEXICO][0] = 127, + [1][0][2][0][RTW89_CN][0] = 127, + [1][0][2][0][RTW89_QATAR][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_KCC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_CHILE][1] = 127, + [1][0][2][0][RTW89_UKRAINE][1] = 127, + [1][0][2][0][RTW89_MEXICO][1] = 127, + [1][0][2][0][RTW89_CN][1] = 127, + [1][0][2][0][RTW89_QATAR][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 70, + [1][0][2][0][RTW89_ETSI][2] = 58, + [1][0][2][0][RTW89_MKK][2] = 74, + [1][0][2][0][RTW89_IC][2] = 70, + [1][0][2][0][RTW89_KCC][2] = 74, + [1][0][2][0][RTW89_ACMA][2] = 58, + [1][0][2][0][RTW89_CHILE][2] = 66, + [1][0][2][0][RTW89_UKRAINE][2] = 58, + [1][0][2][0][RTW89_MEXICO][2] = 70, + [1][0][2][0][RTW89_CN][2] = 58, + [1][0][2][0][RTW89_QATAR][2] = 58, + [1][0][2][0][RTW89_UK][2] = 58, + [1][0][2][0][RTW89_FCC][3] = 70, + [1][0][2][0][RTW89_ETSI][3] = 58, + [1][0][2][0][RTW89_MKK][3] = 74, + [1][0][2][0][RTW89_IC][3] = 70, + [1][0][2][0][RTW89_KCC][3] = 74, + [1][0][2][0][RTW89_ACMA][3] = 58, + [1][0][2][0][RTW89_CHILE][3] = 66, + [1][0][2][0][RTW89_UKRAINE][3] = 58, + [1][0][2][0][RTW89_MEXICO][3] = 70, + [1][0][2][0][RTW89_CN][3] = 58, + [1][0][2][0][RTW89_QATAR][3] = 58, + [1][0][2][0][RTW89_UK][3] = 58, + [1][0][2][0][RTW89_FCC][4] = 72, + [1][0][2][0][RTW89_ETSI][4] = 58, + [1][0][2][0][RTW89_MKK][4] = 74, + [1][0][2][0][RTW89_IC][4] = 72, + [1][0][2][0][RTW89_KCC][4] = 74, + [1][0][2][0][RTW89_ACMA][4] = 58, + [1][0][2][0][RTW89_CHILE][4] = 66, + [1][0][2][0][RTW89_UKRAINE][4] = 58, + [1][0][2][0][RTW89_MEXICO][4] = 72, + [1][0][2][0][RTW89_CN][4] = 58, + [1][0][2][0][RTW89_QATAR][4] = 58, + [1][0][2][0][RTW89_UK][4] = 58, + [1][0][2][0][RTW89_FCC][5] = 72, + [1][0][2][0][RTW89_ETSI][5] = 58, + [1][0][2][0][RTW89_MKK][5] = 74, + [1][0][2][0][RTW89_IC][5] = 72, + [1][0][2][0][RTW89_KCC][5] = 74, + [1][0][2][0][RTW89_ACMA][5] = 58, + [1][0][2][0][RTW89_CHILE][5] = 66, + [1][0][2][0][RTW89_UKRAINE][5] = 58, + [1][0][2][0][RTW89_MEXICO][5] = 72, + [1][0][2][0][RTW89_CN][5] = 58, + [1][0][2][0][RTW89_QATAR][5] = 58, + [1][0][2][0][RTW89_UK][5] = 58, + [1][0][2][0][RTW89_FCC][6] = 72, + [1][0][2][0][RTW89_ETSI][6] = 58, + [1][0][2][0][RTW89_MKK][6] = 74, + [1][0][2][0][RTW89_IC][6] = 72, + [1][0][2][0][RTW89_KCC][6] = 74, + [1][0][2][0][RTW89_ACMA][6] = 58, + [1][0][2][0][RTW89_CHILE][6] = 66, + [1][0][2][0][RTW89_UKRAINE][6] = 58, + [1][0][2][0][RTW89_MEXICO][6] = 72, + [1][0][2][0][RTW89_CN][6] = 58, + [1][0][2][0][RTW89_QATAR][6] = 58, + [1][0][2][0][RTW89_UK][6] = 58, + [1][0][2][0][RTW89_FCC][7] = 68, + [1][0][2][0][RTW89_ETSI][7] = 58, + [1][0][2][0][RTW89_MKK][7] = 74, + [1][0][2][0][RTW89_IC][7] = 68, + [1][0][2][0][RTW89_KCC][7] = 74, + [1][0][2][0][RTW89_ACMA][7] = 58, + [1][0][2][0][RTW89_CHILE][7] = 66, + [1][0][2][0][RTW89_UKRAINE][7] = 58, + [1][0][2][0][RTW89_MEXICO][7] = 68, + [1][0][2][0][RTW89_CN][7] = 58, + [1][0][2][0][RTW89_QATAR][7] = 58, + [1][0][2][0][RTW89_UK][7] = 58, + [1][0][2][0][RTW89_FCC][8] = 68, + [1][0][2][0][RTW89_ETSI][8] = 58, + [1][0][2][0][RTW89_MKK][8] = 74, + [1][0][2][0][RTW89_IC][8] = 68, + [1][0][2][0][RTW89_KCC][8] = 74, + [1][0][2][0][RTW89_ACMA][8] = 58, + [1][0][2][0][RTW89_CHILE][8] = 66, + [1][0][2][0][RTW89_UKRAINE][8] = 58, + [1][0][2][0][RTW89_MEXICO][8] = 68, + [1][0][2][0][RTW89_CN][8] = 58, + [1][0][2][0][RTW89_QATAR][8] = 58, + [1][0][2][0][RTW89_UK][8] = 58, + [1][0][2][0][RTW89_FCC][9] = 68, + [1][0][2][0][RTW89_ETSI][9] = 58, + [1][0][2][0][RTW89_MKK][9] = 74, + [1][0][2][0][RTW89_IC][9] = 68, + [1][0][2][0][RTW89_KCC][9] = 74, + [1][0][2][0][RTW89_ACMA][9] = 58, + [1][0][2][0][RTW89_CHILE][9] = 66, + [1][0][2][0][RTW89_UKRAINE][9] = 58, + [1][0][2][0][RTW89_MEXICO][9] = 68, + [1][0][2][0][RTW89_CN][9] = 58, + [1][0][2][0][RTW89_QATAR][9] = 58, + [1][0][2][0][RTW89_UK][9] = 58, + [1][0][2][0][RTW89_FCC][10] = 66, + [1][0][2][0][RTW89_ETSI][10] = 58, + [1][0][2][0][RTW89_MKK][10] = 74, + [1][0][2][0][RTW89_IC][10] = 66, + [1][0][2][0][RTW89_KCC][10] = 74, + [1][0][2][0][RTW89_ACMA][10] = 58, + [1][0][2][0][RTW89_CHILE][10] = 66, + [1][0][2][0][RTW89_UKRAINE][10] = 58, + [1][0][2][0][RTW89_MEXICO][10] = 66, + [1][0][2][0][RTW89_CN][10] = 40, + [1][0][2][0][RTW89_QATAR][10] = 58, + [1][0][2][0][RTW89_UK][10] = 58, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_KCC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_CHILE][11] = 127, + [1][0][2][0][RTW89_UKRAINE][11] = 127, + [1][0][2][0][RTW89_MEXICO][11] = 127, + [1][0][2][0][RTW89_CN][11] = 127, + [1][0][2][0][RTW89_QATAR][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_KCC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_CHILE][12] = 127, + [1][0][2][0][RTW89_UKRAINE][12] = 127, + [1][0][2][0][RTW89_MEXICO][12] = 127, + [1][0][2][0][RTW89_CN][12] = 127, + [1][0][2][0][RTW89_QATAR][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_KCC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_CHILE][13] = 127, + [1][0][2][0][RTW89_UKRAINE][13] = 127, + [1][0][2][0][RTW89_MEXICO][13] = 127, + [1][0][2][0][RTW89_CN][13] = 127, + [1][0][2][0][RTW89_QATAR][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_KCC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_CHILE][0] = 127, + [1][1][2][0][RTW89_UKRAINE][0] = 127, + [1][1][2][0][RTW89_MEXICO][0] = 127, + [1][1][2][0][RTW89_CN][0] = 127, + [1][1][2][0][RTW89_QATAR][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CHILE][1] = 127, + [1][1][2][0][RTW89_UKRAINE][1] = 127, + [1][1][2][0][RTW89_MEXICO][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_QATAR][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 54, + [1][1][2][0][RTW89_ETSI][2] = 46, + [1][1][2][0][RTW89_MKK][2] = 66, + [1][1][2][0][RTW89_IC][2] = 54, + [1][1][2][0][RTW89_KCC][2] = 62, + [1][1][2][0][RTW89_ACMA][2] = 46, + [1][1][2][0][RTW89_CHILE][2] = 52, + [1][1][2][0][RTW89_UKRAINE][2] = 46, + [1][1][2][0][RTW89_MEXICO][2] = 54, + [1][1][2][0][RTW89_CN][2] = 46, + [1][1][2][0][RTW89_QATAR][2] = 46, + [1][1][2][0][RTW89_UK][2] = 46, + [1][1][2][0][RTW89_FCC][3] = 54, + [1][1][2][0][RTW89_ETSI][3] = 46, + [1][1][2][0][RTW89_MKK][3] = 66, + [1][1][2][0][RTW89_IC][3] = 54, + [1][1][2][0][RTW89_KCC][3] = 62, + [1][1][2][0][RTW89_ACMA][3] = 46, + [1][1][2][0][RTW89_CHILE][3] = 52, + [1][1][2][0][RTW89_UKRAINE][3] = 46, + [1][1][2][0][RTW89_MEXICO][3] = 54, + [1][1][2][0][RTW89_CN][3] = 46, + [1][1][2][0][RTW89_QATAR][3] = 46, + [1][1][2][0][RTW89_UK][3] = 46, + [1][1][2][0][RTW89_FCC][4] = 58, + [1][1][2][0][RTW89_ETSI][4] = 46, + [1][1][2][0][RTW89_MKK][4] = 66, + [1][1][2][0][RTW89_IC][4] = 58, + [1][1][2][0][RTW89_KCC][4] = 62, + [1][1][2][0][RTW89_ACMA][4] = 46, + [1][1][2][0][RTW89_CHILE][4] = 52, + [1][1][2][0][RTW89_UKRAINE][4] = 46, + [1][1][2][0][RTW89_MEXICO][4] = 58, + [1][1][2][0][RTW89_CN][4] = 46, + [1][1][2][0][RTW89_QATAR][4] = 46, + [1][1][2][0][RTW89_UK][4] = 46, + [1][1][2][0][RTW89_FCC][5] = 66, + [1][1][2][0][RTW89_ETSI][5] = 46, + [1][1][2][0][RTW89_MKK][5] = 66, + [1][1][2][0][RTW89_IC][5] = 66, + [1][1][2][0][RTW89_KCC][5] = 62, + [1][1][2][0][RTW89_ACMA][5] = 46, + [1][1][2][0][RTW89_CHILE][5] = 54, + [1][1][2][0][RTW89_UKRAINE][5] = 46, + [1][1][2][0][RTW89_MEXICO][5] = 66, + [1][1][2][0][RTW89_CN][5] = 46, + [1][1][2][0][RTW89_QATAR][5] = 46, + [1][1][2][0][RTW89_UK][5] = 46, + [1][1][2][0][RTW89_FCC][6] = 58, + [1][1][2][0][RTW89_ETSI][6] = 46, + [1][1][2][0][RTW89_MKK][6] = 66, + [1][1][2][0][RTW89_IC][6] = 58, + [1][1][2][0][RTW89_KCC][6] = 62, + [1][1][2][0][RTW89_ACMA][6] = 46, + [1][1][2][0][RTW89_CHILE][6] = 52, + [1][1][2][0][RTW89_UKRAINE][6] = 46, + [1][1][2][0][RTW89_MEXICO][6] = 58, + [1][1][2][0][RTW89_CN][6] = 46, + [1][1][2][0][RTW89_QATAR][6] = 46, + [1][1][2][0][RTW89_UK][6] = 46, + [1][1][2][0][RTW89_FCC][7] = 54, + [1][1][2][0][RTW89_ETSI][7] = 46, + [1][1][2][0][RTW89_MKK][7] = 66, + [1][1][2][0][RTW89_IC][7] = 54, + [1][1][2][0][RTW89_KCC][7] = 62, + [1][1][2][0][RTW89_ACMA][7] = 46, + [1][1][2][0][RTW89_CHILE][7] = 52, + [1][1][2][0][RTW89_UKRAINE][7] = 46, + [1][1][2][0][RTW89_MEXICO][7] = 54, + [1][1][2][0][RTW89_CN][7] = 46, + [1][1][2][0][RTW89_QATAR][7] = 46, + [1][1][2][0][RTW89_UK][7] = 46, + [1][1][2][0][RTW89_FCC][8] = 54, + [1][1][2][0][RTW89_ETSI][8] = 46, + [1][1][2][0][RTW89_MKK][8] = 66, + [1][1][2][0][RTW89_IC][8] = 54, + [1][1][2][0][RTW89_KCC][8] = 62, + [1][1][2][0][RTW89_ACMA][8] = 46, + [1][1][2][0][RTW89_CHILE][8] = 52, + [1][1][2][0][RTW89_UKRAINE][8] = 46, + [1][1][2][0][RTW89_MEXICO][8] = 54, + [1][1][2][0][RTW89_CN][8] = 46, + [1][1][2][0][RTW89_QATAR][8] = 46, + [1][1][2][0][RTW89_UK][8] = 46, + [1][1][2][0][RTW89_FCC][9] = 42, + [1][1][2][0][RTW89_ETSI][9] = 46, + [1][1][2][0][RTW89_MKK][9] = 66, + [1][1][2][0][RTW89_IC][9] = 42, + [1][1][2][0][RTW89_KCC][9] = 62, + [1][1][2][0][RTW89_ACMA][9] = 46, + [1][1][2][0][RTW89_CHILE][9] = 42, + [1][1][2][0][RTW89_UKRAINE][9] = 46, + [1][1][2][0][RTW89_MEXICO][9] = 42, + [1][1][2][0][RTW89_CN][9] = 46, + [1][1][2][0][RTW89_QATAR][9] = 46, + [1][1][2][0][RTW89_UK][9] = 46, + [1][1][2][0][RTW89_FCC][10] = 38, + [1][1][2][0][RTW89_ETSI][10] = 46, + [1][1][2][0][RTW89_MKK][10] = 66, + [1][1][2][0][RTW89_IC][10] = 38, + [1][1][2][0][RTW89_KCC][10] = 62, + [1][1][2][0][RTW89_ACMA][10] = 46, + [1][1][2][0][RTW89_CHILE][10] = 38, + [1][1][2][0][RTW89_UKRAINE][10] = 46, + [1][1][2][0][RTW89_MEXICO][10] = 38, + [1][1][2][0][RTW89_CN][10] = 40, + [1][1][2][0][RTW89_QATAR][10] = 46, + [1][1][2][0][RTW89_UK][10] = 46, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_KCC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_CHILE][11] = 127, + [1][1][2][0][RTW89_UKRAINE][11] = 127, + [1][1][2][0][RTW89_MEXICO][11] = 127, + [1][1][2][0][RTW89_CN][11] = 127, + [1][1][2][0][RTW89_QATAR][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_KCC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_CHILE][12] = 127, + [1][1][2][0][RTW89_UKRAINE][12] = 127, + [1][1][2][0][RTW89_MEXICO][12] = 127, + [1][1][2][0][RTW89_CN][12] = 127, + [1][1][2][0][RTW89_QATAR][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CHILE][13] = 127, + [1][1][2][0][RTW89_UKRAINE][13] = 127, + [1][1][2][0][RTW89_MEXICO][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_QATAR][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_KCC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_CHILE][0] = 127, + [1][1][2][1][RTW89_UKRAINE][0] = 127, + [1][1][2][1][RTW89_MEXICO][0] = 127, + [1][1][2][1][RTW89_CN][0] = 127, + [1][1][2][1][RTW89_QATAR][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CHILE][1] = 127, + [1][1][2][1][RTW89_UKRAINE][1] = 127, + [1][1][2][1][RTW89_MEXICO][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_QATAR][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 54, + [1][1][2][1][RTW89_ETSI][2] = 34, + [1][1][2][1][RTW89_MKK][2] = 66, + [1][1][2][1][RTW89_IC][2] = 54, + [1][1][2][1][RTW89_KCC][2] = 62, + [1][1][2][1][RTW89_ACMA][2] = 34, + [1][1][2][1][RTW89_CHILE][2] = 42, + [1][1][2][1][RTW89_UKRAINE][2] = 34, + [1][1][2][1][RTW89_MEXICO][2] = 54, + [1][1][2][1][RTW89_CN][2] = 34, + [1][1][2][1][RTW89_QATAR][2] = 34, + [1][1][2][1][RTW89_UK][2] = 34, + [1][1][2][1][RTW89_FCC][3] = 54, + [1][1][2][1][RTW89_ETSI][3] = 34, + [1][1][2][1][RTW89_MKK][3] = 66, + [1][1][2][1][RTW89_IC][3] = 54, + [1][1][2][1][RTW89_KCC][3] = 62, + [1][1][2][1][RTW89_ACMA][3] = 34, + [1][1][2][1][RTW89_CHILE][3] = 42, + [1][1][2][1][RTW89_UKRAINE][3] = 34, + [1][1][2][1][RTW89_MEXICO][3] = 54, + [1][1][2][1][RTW89_CN][3] = 34, + [1][1][2][1][RTW89_QATAR][3] = 34, + [1][1][2][1][RTW89_UK][3] = 34, + [1][1][2][1][RTW89_FCC][4] = 58, + [1][1][2][1][RTW89_ETSI][4] = 34, + [1][1][2][1][RTW89_MKK][4] = 66, + [1][1][2][1][RTW89_IC][4] = 58, + [1][1][2][1][RTW89_KCC][4] = 62, + [1][1][2][1][RTW89_ACMA][4] = 34, + [1][1][2][1][RTW89_CHILE][4] = 42, + [1][1][2][1][RTW89_UKRAINE][4] = 34, + [1][1][2][1][RTW89_MEXICO][4] = 58, + [1][1][2][1][RTW89_CN][4] = 34, + [1][1][2][1][RTW89_QATAR][4] = 34, + [1][1][2][1][RTW89_UK][4] = 34, + [1][1][2][1][RTW89_FCC][5] = 66, + [1][1][2][1][RTW89_ETSI][5] = 34, + [1][1][2][1][RTW89_MKK][5] = 66, + [1][1][2][1][RTW89_IC][5] = 66, + [1][1][2][1][RTW89_KCC][5] = 62, + [1][1][2][1][RTW89_ACMA][5] = 34, + [1][1][2][1][RTW89_CHILE][5] = 42, + [1][1][2][1][RTW89_UKRAINE][5] = 34, + [1][1][2][1][RTW89_MEXICO][5] = 66, + [1][1][2][1][RTW89_CN][5] = 34, + [1][1][2][1][RTW89_QATAR][5] = 34, + [1][1][2][1][RTW89_UK][5] = 34, + [1][1][2][1][RTW89_FCC][6] = 58, + [1][1][2][1][RTW89_ETSI][6] = 34, + [1][1][2][1][RTW89_MKK][6] = 66, + [1][1][2][1][RTW89_IC][6] = 58, + [1][1][2][1][RTW89_KCC][6] = 62, + [1][1][2][1][RTW89_ACMA][6] = 34, + [1][1][2][1][RTW89_CHILE][6] = 42, + [1][1][2][1][RTW89_UKRAINE][6] = 34, + [1][1][2][1][RTW89_MEXICO][6] = 58, + [1][1][2][1][RTW89_CN][6] = 34, + [1][1][2][1][RTW89_QATAR][6] = 34, + [1][1][2][1][RTW89_UK][6] = 34, + [1][1][2][1][RTW89_FCC][7] = 54, + [1][1][2][1][RTW89_ETSI][7] = 34, + [1][1][2][1][RTW89_MKK][7] = 66, + [1][1][2][1][RTW89_IC][7] = 54, + [1][1][2][1][RTW89_KCC][7] = 62, + [1][1][2][1][RTW89_ACMA][7] = 34, + [1][1][2][1][RTW89_CHILE][7] = 42, + [1][1][2][1][RTW89_UKRAINE][7] = 34, + [1][1][2][1][RTW89_MEXICO][7] = 54, + [1][1][2][1][RTW89_CN][7] = 34, + [1][1][2][1][RTW89_QATAR][7] = 34, + [1][1][2][1][RTW89_UK][7] = 34, + [1][1][2][1][RTW89_FCC][8] = 54, + [1][1][2][1][RTW89_ETSI][8] = 34, + [1][1][2][1][RTW89_MKK][8] = 66, + [1][1][2][1][RTW89_IC][8] = 54, + [1][1][2][1][RTW89_KCC][8] = 62, + [1][1][2][1][RTW89_ACMA][8] = 34, + [1][1][2][1][RTW89_CHILE][8] = 42, + [1][1][2][1][RTW89_UKRAINE][8] = 34, + [1][1][2][1][RTW89_MEXICO][8] = 54, + [1][1][2][1][RTW89_CN][8] = 34, + [1][1][2][1][RTW89_QATAR][8] = 34, + [1][1][2][1][RTW89_UK][8] = 34, + [1][1][2][1][RTW89_FCC][9] = 42, + [1][1][2][1][RTW89_ETSI][9] = 34, + [1][1][2][1][RTW89_MKK][9] = 66, + [1][1][2][1][RTW89_IC][9] = 42, + [1][1][2][1][RTW89_KCC][9] = 62, + [1][1][2][1][RTW89_ACMA][9] = 34, + [1][1][2][1][RTW89_CHILE][9] = 42, + [1][1][2][1][RTW89_UKRAINE][9] = 34, + [1][1][2][1][RTW89_MEXICO][9] = 42, + [1][1][2][1][RTW89_CN][9] = 34, + [1][1][2][1][RTW89_QATAR][9] = 34, + [1][1][2][1][RTW89_UK][9] = 34, + [1][1][2][1][RTW89_FCC][10] = 38, + [1][1][2][1][RTW89_ETSI][10] = 34, + [1][1][2][1][RTW89_MKK][10] = 66, + [1][1][2][1][RTW89_IC][10] = 38, + [1][1][2][1][RTW89_KCC][10] = 62, + [1][1][2][1][RTW89_ACMA][10] = 34, + [1][1][2][1][RTW89_CHILE][10] = 38, + [1][1][2][1][RTW89_UKRAINE][10] = 34, + [1][1][2][1][RTW89_MEXICO][10] = 38, + [1][1][2][1][RTW89_CN][10] = 34, + [1][1][2][1][RTW89_QATAR][10] = 34, + [1][1][2][1][RTW89_UK][10] = 34, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_KCC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_CHILE][11] = 127, + [1][1][2][1][RTW89_UKRAINE][11] = 127, + [1][1][2][1][RTW89_MEXICO][11] = 127, + [1][1][2][1][RTW89_CN][11] = 127, + [1][1][2][1][RTW89_QATAR][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_KCC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_CHILE][12] = 127, + [1][1][2][1][RTW89_UKRAINE][12] = 127, + [1][1][2][1][RTW89_MEXICO][12] = 127, + [1][1][2][1][RTW89_CN][12] = 127, + [1][1][2][1][RTW89_QATAR][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CHILE][13] = 127, + [1][1][2][1][RTW89_UKRAINE][13] = 127, + [1][1][2][1][RTW89_MEXICO][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_QATAR][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 42, + [0][0][1][0][RTW89_WW][2] = 42, + [0][0][1][0][RTW89_WW][4] = 42, + [0][0][1][0][RTW89_WW][6] = 42, + [0][0][1][0][RTW89_WW][8] = 52, + [0][0][1][0][RTW89_WW][10] = 52, + [0][0][1][0][RTW89_WW][12] = 52, + [0][0][1][0][RTW89_WW][14] = 52, + [0][0][1][0][RTW89_WW][15] = 52, + [0][0][1][0][RTW89_WW][17] = 52, + [0][0][1][0][RTW89_WW][19] = 52, + [0][0][1][0][RTW89_WW][21] = 52, + [0][0][1][0][RTW89_WW][23] = 52, + [0][0][1][0][RTW89_WW][25] = 52, + [0][0][1][0][RTW89_WW][27] = 52, + [0][0][1][0][RTW89_WW][29] = 52, + [0][0][1][0][RTW89_WW][31] = 52, + [0][0][1][0][RTW89_WW][33] = 52, + [0][0][1][0][RTW89_WW][35] = 52, + [0][0][1][0][RTW89_WW][37] = 68, + [0][0][1][0][RTW89_WW][38] = 28, + [0][0][1][0][RTW89_WW][40] = 28, + [0][0][1][0][RTW89_WW][42] = 28, + [0][0][1][0][RTW89_WW][44] = 28, + [0][0][1][0][RTW89_WW][46] = 28, + [0][0][1][0][RTW89_WW][48] = 76, + [0][0][1][0][RTW89_WW][50] = 76, + [0][0][1][0][RTW89_WW][52] = 76, + [0][1][1][0][RTW89_WW][0] = 30, + [0][1][1][0][RTW89_WW][2] = 32, + [0][1][1][0][RTW89_WW][4] = 30, + [0][1][1][0][RTW89_WW][6] = 30, + [0][1][1][0][RTW89_WW][8] = 40, + [0][1][1][0][RTW89_WW][10] = 40, + [0][1][1][0][RTW89_WW][12] = 40, + [0][1][1][0][RTW89_WW][14] = 40, + [0][1][1][0][RTW89_WW][15] = 40, + [0][1][1][0][RTW89_WW][17] = 40, + [0][1][1][0][RTW89_WW][19] = 40, + [0][1][1][0][RTW89_WW][21] = 40, + [0][1][1][0][RTW89_WW][23] = 40, + [0][1][1][0][RTW89_WW][25] = 40, + [0][1][1][0][RTW89_WW][27] = 40, + [0][1][1][0][RTW89_WW][29] = 40, + [0][1][1][0][RTW89_WW][31] = 40, + [0][1][1][0][RTW89_WW][33] = 40, + [0][1][1][0][RTW89_WW][35] = 40, + [0][1][1][0][RTW89_WW][37] = 50, + [0][1][1][0][RTW89_WW][38] = 16, + [0][1][1][0][RTW89_WW][40] = 16, + [0][1][1][0][RTW89_WW][42] = 16, + [0][1][1][0][RTW89_WW][44] = 16, + [0][1][1][0][RTW89_WW][46] = 16, + [0][1][1][0][RTW89_WW][48] = 50, + [0][1][1][0][RTW89_WW][50] = 50, + [0][1][1][0][RTW89_WW][52] = 50, + [0][0][2][0][RTW89_WW][0] = 42, + [0][0][2][0][RTW89_WW][2] = 42, + [0][0][2][0][RTW89_WW][4] = 42, + [0][0][2][0][RTW89_WW][6] = 42, + [0][0][2][0][RTW89_WW][8] = 52, + [0][0][2][0][RTW89_WW][10] = 52, + [0][0][2][0][RTW89_WW][12] = 52, + [0][0][2][0][RTW89_WW][14] = 52, + [0][0][2][0][RTW89_WW][15] = 52, + [0][0][2][0][RTW89_WW][17] = 52, + [0][0][2][0][RTW89_WW][19] = 52, + [0][0][2][0][RTW89_WW][21] = 52, + [0][0][2][0][RTW89_WW][23] = 52, + [0][0][2][0][RTW89_WW][25] = 52, + [0][0][2][0][RTW89_WW][27] = 52, + [0][0][2][0][RTW89_WW][29] = 52, + [0][0][2][0][RTW89_WW][31] = 52, + [0][0][2][0][RTW89_WW][33] = 52, + [0][0][2][0][RTW89_WW][35] = 52, + [0][0][2][0][RTW89_WW][37] = 64, + [0][0][2][0][RTW89_WW][38] = 28, + [0][0][2][0][RTW89_WW][40] = 28, + [0][0][2][0][RTW89_WW][42] = 28, + [0][0][2][0][RTW89_WW][44] = 28, + [0][0][2][0][RTW89_WW][46] = 28, + [0][0][2][0][RTW89_WW][48] = 78, + [0][0][2][0][RTW89_WW][50] = 78, + [0][0][2][0][RTW89_WW][52] = 78, + [0][1][2][0][RTW89_WW][0] = 30, + [0][1][2][0][RTW89_WW][2] = 30, + [0][1][2][0][RTW89_WW][4] = 30, + [0][1][2][0][RTW89_WW][6] = 30, + [0][1][2][0][RTW89_WW][8] = 40, + [0][1][2][0][RTW89_WW][10] = 40, + [0][1][2][0][RTW89_WW][12] = 40, + [0][1][2][0][RTW89_WW][14] = 40, + [0][1][2][0][RTW89_WW][15] = 40, + [0][1][2][0][RTW89_WW][17] = 40, + [0][1][2][0][RTW89_WW][19] = 40, + [0][1][2][0][RTW89_WW][21] = 40, + [0][1][2][0][RTW89_WW][23] = 40, + [0][1][2][0][RTW89_WW][25] = 40, + [0][1][2][0][RTW89_WW][27] = 40, + [0][1][2][0][RTW89_WW][29] = 40, + [0][1][2][0][RTW89_WW][31] = 40, + [0][1][2][0][RTW89_WW][33] = 40, + [0][1][2][0][RTW89_WW][35] = 40, + [0][1][2][0][RTW89_WW][37] = 50, + [0][1][2][0][RTW89_WW][38] = 16, + [0][1][2][0][RTW89_WW][40] = 16, + [0][1][2][0][RTW89_WW][42] = 16, + [0][1][2][0][RTW89_WW][44] = 16, + [0][1][2][0][RTW89_WW][46] = 16, + [0][1][2][0][RTW89_WW][48] = 50, + [0][1][2][0][RTW89_WW][50] = 52, + [0][1][2][0][RTW89_WW][52] = 52, + [0][1][2][1][RTW89_WW][0] = 14, + [0][1][2][1][RTW89_WW][2] = 14, + [0][1][2][1][RTW89_WW][4] = 14, + [0][1][2][1][RTW89_WW][6] = 14, + [0][1][2][1][RTW89_WW][8] = 28, + [0][1][2][1][RTW89_WW][10] = 28, + [0][1][2][1][RTW89_WW][12] = 28, + [0][1][2][1][RTW89_WW][14] = 28, + [0][1][2][1][RTW89_WW][15] = 28, + [0][1][2][1][RTW89_WW][17] = 28, + [0][1][2][1][RTW89_WW][19] = 28, + [0][1][2][1][RTW89_WW][21] = 28, + [0][1][2][1][RTW89_WW][23] = 28, + [0][1][2][1][RTW89_WW][25] = 28, + [0][1][2][1][RTW89_WW][27] = 28, + [0][1][2][1][RTW89_WW][29] = 28, + [0][1][2][1][RTW89_WW][31] = 28, + [0][1][2][1][RTW89_WW][33] = 28, + [0][1][2][1][RTW89_WW][35] = 28, + [0][1][2][1][RTW89_WW][37] = 36, + [0][1][2][1][RTW89_WW][38] = 4, + [0][1][2][1][RTW89_WW][40] = 4, + [0][1][2][1][RTW89_WW][42] = 4, + [0][1][2][1][RTW89_WW][44] = 4, + [0][1][2][1][RTW89_WW][46] = 4, + [0][1][2][1][RTW89_WW][48] = 50, + [0][1][2][1][RTW89_WW][50] = 52, + [0][1][2][1][RTW89_WW][52] = 52, + [1][0][2][0][RTW89_WW][1] = 42, + [1][0][2][0][RTW89_WW][5] = 42, + [1][0][2][0][RTW89_WW][9] = 52, + [1][0][2][0][RTW89_WW][13] = 52, + [1][0][2][0][RTW89_WW][16] = 52, + [1][0][2][0][RTW89_WW][20] = 52, + [1][0][2][0][RTW89_WW][24] = 52, + [1][0][2][0][RTW89_WW][28] = 52, + [1][0][2][0][RTW89_WW][32] = 52, + [1][0][2][0][RTW89_WW][36] = 64, + [1][0][2][0][RTW89_WW][39] = 28, + [1][0][2][0][RTW89_WW][43] = 28, + [1][0][2][0][RTW89_WW][47] = 78, + [1][0][2][0][RTW89_WW][51] = 70, + [1][1][2][0][RTW89_WW][1] = 30, + [1][1][2][0][RTW89_WW][5] = 30, + [1][1][2][0][RTW89_WW][9] = 40, + [1][1][2][0][RTW89_WW][13] = 40, + [1][1][2][0][RTW89_WW][16] = 40, + [1][1][2][0][RTW89_WW][20] = 40, + [1][1][2][0][RTW89_WW][24] = 40, + [1][1][2][0][RTW89_WW][28] = 40, + [1][1][2][0][RTW89_WW][32] = 40, + [1][1][2][0][RTW89_WW][36] = 50, + [1][1][2][0][RTW89_WW][39] = 16, + [1][1][2][0][RTW89_WW][43] = 16, + [1][1][2][0][RTW89_WW][47] = 62, + [1][1][2][0][RTW89_WW][51] = 62, + [1][1][2][1][RTW89_WW][1] = 16, + [1][1][2][1][RTW89_WW][5] = 16, + [1][1][2][1][RTW89_WW][9] = 28, + [1][1][2][1][RTW89_WW][13] = 28, + [1][1][2][1][RTW89_WW][16] = 28, + [1][1][2][1][RTW89_WW][20] = 28, + [1][1][2][1][RTW89_WW][24] = 28, + [1][1][2][1][RTW89_WW][28] = 28, + [1][1][2][1][RTW89_WW][32] = 28, + [1][1][2][1][RTW89_WW][36] = 36, + [1][1][2][1][RTW89_WW][39] = 4, + [1][1][2][1][RTW89_WW][43] = 4, + [1][1][2][1][RTW89_WW][47] = 62, + [1][1][2][1][RTW89_WW][51] = 62, + [2][0][2][0][RTW89_WW][3] = 42, + [2][0][2][0][RTW89_WW][11] = 52, + [2][0][2][0][RTW89_WW][18] = 52, + [2][0][2][0][RTW89_WW][26] = 52, + [2][0][2][0][RTW89_WW][34] = 64, + [2][0][2][0][RTW89_WW][41] = 28, + [2][0][2][0][RTW89_WW][49] = 64, + [2][1][2][0][RTW89_WW][3] = 28, + [2][1][2][0][RTW89_WW][11] = 40, + [2][1][2][0][RTW89_WW][18] = 40, + [2][1][2][0][RTW89_WW][26] = 40, + [2][1][2][0][RTW89_WW][34] = 50, + [2][1][2][0][RTW89_WW][41] = 16, + [2][1][2][0][RTW89_WW][49] = 58, + [2][1][2][1][RTW89_WW][3] = 16, + [2][1][2][1][RTW89_WW][11] = 28, + [2][1][2][1][RTW89_WW][18] = 28, + [2][1][2][1][RTW89_WW][26] = 28, + [2][1][2][1][RTW89_WW][34] = 34, + [2][1][2][1][RTW89_WW][41] = 4, + [2][1][2][1][RTW89_WW][49] = 58, + [0][0][1][0][RTW89_FCC][0] = 78, + [0][0][1][0][RTW89_ETSI][0] = 58, + [0][0][1][0][RTW89_MKK][0] = 60, + [0][0][1][0][RTW89_IC][0] = 60, + [0][0][1][0][RTW89_KCC][0] = 76, + [0][0][1][0][RTW89_ACMA][0] = 58, + [0][0][1][0][RTW89_CHILE][0] = 42, + [0][0][1][0][RTW89_UKRAINE][0] = 52, + [0][0][1][0][RTW89_MEXICO][0] = 62, + [0][0][1][0][RTW89_CN][0] = 58, + [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, + [0][0][1][0][RTW89_FCC][2] = 78, + [0][0][1][0][RTW89_ETSI][2] = 58, + [0][0][1][0][RTW89_MKK][2] = 60, + [0][0][1][0][RTW89_IC][2] = 60, + [0][0][1][0][RTW89_KCC][2] = 76, + [0][0][1][0][RTW89_ACMA][2] = 58, + [0][0][1][0][RTW89_CHILE][2] = 42, + [0][0][1][0][RTW89_UKRAINE][2] = 52, + [0][0][1][0][RTW89_MEXICO][2] = 62, + [0][0][1][0][RTW89_CN][2] = 58, + [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, + [0][0][1][0][RTW89_FCC][4] = 78, + [0][0][1][0][RTW89_ETSI][4] = 58, + [0][0][1][0][RTW89_MKK][4] = 60, + [0][0][1][0][RTW89_IC][4] = 60, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 58, + [0][0][1][0][RTW89_CHILE][4] = 42, + [0][0][1][0][RTW89_UKRAINE][4] = 52, + [0][0][1][0][RTW89_MEXICO][4] = 62, + [0][0][1][0][RTW89_CN][4] = 58, + [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, + [0][0][1][0][RTW89_FCC][6] = 78, + [0][0][1][0][RTW89_ETSI][6] = 58, + [0][0][1][0][RTW89_MKK][6] = 60, + [0][0][1][0][RTW89_IC][6] = 60, + [0][0][1][0][RTW89_KCC][6] = 50, + [0][0][1][0][RTW89_ACMA][6] = 58, + [0][0][1][0][RTW89_CHILE][6] = 42, + [0][0][1][0][RTW89_UKRAINE][6] = 52, + [0][0][1][0][RTW89_MEXICO][6] = 62, + [0][0][1][0][RTW89_CN][6] = 58, + [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, + [0][0][1][0][RTW89_FCC][8] = 78, + [0][0][1][0][RTW89_ETSI][8] = 58, + [0][0][1][0][RTW89_MKK][8] = 62, + [0][0][1][0][RTW89_IC][8] = 64, + [0][0][1][0][RTW89_KCC][8] = 70, + [0][0][1][0][RTW89_ACMA][8] = 58, + [0][0][1][0][RTW89_CHILE][8] = 66, + [0][0][1][0][RTW89_UKRAINE][8] = 52, + [0][0][1][0][RTW89_MEXICO][8] = 78, + [0][0][1][0][RTW89_CN][8] = 58, + [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, + [0][0][1][0][RTW89_FCC][10] = 78, + [0][0][1][0][RTW89_ETSI][10] = 58, + [0][0][1][0][RTW89_MKK][10] = 62, + [0][0][1][0][RTW89_IC][10] = 64, + [0][0][1][0][RTW89_KCC][10] = 70, + [0][0][1][0][RTW89_ACMA][10] = 58, + [0][0][1][0][RTW89_CHILE][10] = 66, + [0][0][1][0][RTW89_UKRAINE][10] = 52, + [0][0][1][0][RTW89_MEXICO][10] = 78, + [0][0][1][0][RTW89_CN][10] = 58, + [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, + [0][0][1][0][RTW89_FCC][12] = 78, + [0][0][1][0][RTW89_ETSI][12] = 58, + [0][0][1][0][RTW89_MKK][12] = 62, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 74, + [0][0][1][0][RTW89_ACMA][12] = 58, + [0][0][1][0][RTW89_CHILE][12] = 66, + [0][0][1][0][RTW89_UKRAINE][12] = 52, + [0][0][1][0][RTW89_MEXICO][12] = 78, + [0][0][1][0][RTW89_CN][12] = 58, + [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, + [0][0][1][0][RTW89_FCC][14] = 78, + [0][0][1][0][RTW89_ETSI][14] = 58, + [0][0][1][0][RTW89_MKK][14] = 60, + [0][0][1][0][RTW89_IC][14] = 64, + [0][0][1][0][RTW89_KCC][14] = 74, + [0][0][1][0][RTW89_ACMA][14] = 58, + [0][0][1][0][RTW89_CHILE][14] = 66, + [0][0][1][0][RTW89_UKRAINE][14] = 52, + [0][0][1][0][RTW89_MEXICO][14] = 78, + [0][0][1][0][RTW89_CN][14] = 58, + [0][0][1][0][RTW89_QATAR][14] = 58, + [0][0][1][0][RTW89_UK][14] = 58, + [0][0][1][0][RTW89_FCC][15] = 76, + [0][0][1][0][RTW89_ETSI][15] = 58, + [0][0][1][0][RTW89_MKK][15] = 76, + [0][0][1][0][RTW89_IC][15] = 76, + [0][0][1][0][RTW89_KCC][15] = 74, + [0][0][1][0][RTW89_ACMA][15] = 58, + [0][0][1][0][RTW89_CHILE][15] = 66, + [0][0][1][0][RTW89_UKRAINE][15] = 52, + [0][0][1][0][RTW89_MEXICO][15] = 76, + [0][0][1][0][RTW89_CN][15] = 127, + [0][0][1][0][RTW89_QATAR][15] = 58, + [0][0][1][0][RTW89_UK][15] = 58, + [0][0][1][0][RTW89_FCC][17] = 78, + [0][0][1][0][RTW89_ETSI][17] = 58, + [0][0][1][0][RTW89_MKK][17] = 76, + [0][0][1][0][RTW89_IC][17] = 78, + [0][0][1][0][RTW89_KCC][17] = 74, + [0][0][1][0][RTW89_ACMA][17] = 58, + [0][0][1][0][RTW89_CHILE][17] = 66, + [0][0][1][0][RTW89_UKRAINE][17] = 52, + [0][0][1][0][RTW89_MEXICO][17] = 78, + [0][0][1][0][RTW89_CN][17] = 127, + [0][0][1][0][RTW89_QATAR][17] = 58, + [0][0][1][0][RTW89_UK][17] = 58, + [0][0][1][0][RTW89_FCC][19] = 78, + [0][0][1][0][RTW89_ETSI][19] = 58, + [0][0][1][0][RTW89_MKK][19] = 76, + [0][0][1][0][RTW89_IC][19] = 78, + [0][0][1][0][RTW89_KCC][19] = 74, + [0][0][1][0][RTW89_ACMA][19] = 58, + [0][0][1][0][RTW89_CHILE][19] = 66, + [0][0][1][0][RTW89_UKRAINE][19] = 52, + [0][0][1][0][RTW89_MEXICO][19] = 78, + [0][0][1][0][RTW89_CN][19] = 127, + [0][0][1][0][RTW89_QATAR][19] = 58, + [0][0][1][0][RTW89_UK][19] = 58, + [0][0][1][0][RTW89_FCC][21] = 78, + [0][0][1][0][RTW89_ETSI][21] = 58, + [0][0][1][0][RTW89_MKK][21] = 76, + [0][0][1][0][RTW89_IC][21] = 78, + [0][0][1][0][RTW89_KCC][21] = 74, + [0][0][1][0][RTW89_ACMA][21] = 58, + [0][0][1][0][RTW89_CHILE][21] = 68, + [0][0][1][0][RTW89_UKRAINE][21] = 52, + [0][0][1][0][RTW89_MEXICO][21] = 78, + [0][0][1][0][RTW89_CN][21] = 127, + [0][0][1][0][RTW89_QATAR][21] = 58, + [0][0][1][0][RTW89_UK][21] = 58, + [0][0][1][0][RTW89_FCC][23] = 78, + [0][0][1][0][RTW89_ETSI][23] = 58, + [0][0][1][0][RTW89_MKK][23] = 76, + [0][0][1][0][RTW89_IC][23] = 78, + [0][0][1][0][RTW89_KCC][23] = 74, + [0][0][1][0][RTW89_ACMA][23] = 58, + [0][0][1][0][RTW89_CHILE][23] = 68, + [0][0][1][0][RTW89_UKRAINE][23] = 52, + [0][0][1][0][RTW89_MEXICO][23] = 78, + [0][0][1][0][RTW89_CN][23] = 127, + [0][0][1][0][RTW89_QATAR][23] = 58, + [0][0][1][0][RTW89_UK][23] = 58, + [0][0][1][0][RTW89_FCC][25] = 78, + [0][0][1][0][RTW89_ETSI][25] = 58, + [0][0][1][0][RTW89_MKK][25] = 76, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_KCC][25] = 74, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_CHILE][25] = 68, + [0][0][1][0][RTW89_UKRAINE][25] = 52, + [0][0][1][0][RTW89_MEXICO][25] = 78, + [0][0][1][0][RTW89_CN][25] = 127, + [0][0][1][0][RTW89_QATAR][25] = 58, + [0][0][1][0][RTW89_UK][25] = 58, + [0][0][1][0][RTW89_FCC][27] = 78, + [0][0][1][0][RTW89_ETSI][27] = 58, + [0][0][1][0][RTW89_MKK][27] = 76, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_KCC][27] = 74, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_CHILE][27] = 66, + [0][0][1][0][RTW89_UKRAINE][27] = 52, + [0][0][1][0][RTW89_MEXICO][27] = 78, + [0][0][1][0][RTW89_CN][27] = 127, + [0][0][1][0][RTW89_QATAR][27] = 58, + [0][0][1][0][RTW89_UK][27] = 58, + [0][0][1][0][RTW89_FCC][29] = 78, + [0][0][1][0][RTW89_ETSI][29] = 58, + [0][0][1][0][RTW89_MKK][29] = 76, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_KCC][29] = 74, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_CHILE][29] = 66, + [0][0][1][0][RTW89_UKRAINE][29] = 52, + [0][0][1][0][RTW89_MEXICO][29] = 78, + [0][0][1][0][RTW89_CN][29] = 127, + [0][0][1][0][RTW89_QATAR][29] = 58, + [0][0][1][0][RTW89_UK][29] = 58, + [0][0][1][0][RTW89_FCC][31] = 78, + [0][0][1][0][RTW89_ETSI][31] = 58, + [0][0][1][0][RTW89_MKK][31] = 76, + [0][0][1][0][RTW89_IC][31] = 78, + [0][0][1][0][RTW89_KCC][31] = 72, + [0][0][1][0][RTW89_ACMA][31] = 58, + [0][0][1][0][RTW89_CHILE][31] = 66, + [0][0][1][0][RTW89_UKRAINE][31] = 52, + [0][0][1][0][RTW89_MEXICO][31] = 78, + [0][0][1][0][RTW89_CN][31] = 127, + [0][0][1][0][RTW89_QATAR][31] = 58, + [0][0][1][0][RTW89_UK][31] = 58, + [0][0][1][0][RTW89_FCC][33] = 78, + [0][0][1][0][RTW89_ETSI][33] = 58, + [0][0][1][0][RTW89_MKK][33] = 76, + [0][0][1][0][RTW89_IC][33] = 78, + [0][0][1][0][RTW89_KCC][33] = 72, + [0][0][1][0][RTW89_ACMA][33] = 58, + [0][0][1][0][RTW89_CHILE][33] = 66, + [0][0][1][0][RTW89_UKRAINE][33] = 52, + [0][0][1][0][RTW89_MEXICO][33] = 78, + [0][0][1][0][RTW89_CN][33] = 127, + [0][0][1][0][RTW89_QATAR][33] = 58, + [0][0][1][0][RTW89_UK][33] = 58, + [0][0][1][0][RTW89_FCC][35] = 70, + [0][0][1][0][RTW89_ETSI][35] = 58, + [0][0][1][0][RTW89_MKK][35] = 76, + [0][0][1][0][RTW89_IC][35] = 70, + [0][0][1][0][RTW89_KCC][35] = 72, + [0][0][1][0][RTW89_ACMA][35] = 58, + [0][0][1][0][RTW89_CHILE][35] = 66, + [0][0][1][0][RTW89_UKRAINE][35] = 52, + [0][0][1][0][RTW89_MEXICO][35] = 70, + [0][0][1][0][RTW89_CN][35] = 127, + [0][0][1][0][RTW89_QATAR][35] = 58, + [0][0][1][0][RTW89_UK][35] = 58, + [0][0][1][0][RTW89_FCC][37] = 78, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 76, + [0][0][1][0][RTW89_IC][37] = 78, + [0][0][1][0][RTW89_KCC][37] = 72, + [0][0][1][0][RTW89_ACMA][37] = 76, + [0][0][1][0][RTW89_CHILE][37] = 68, + [0][0][1][0][RTW89_UKRAINE][37] = 127, + [0][0][1][0][RTW89_MEXICO][37] = 78, + [0][0][1][0][RTW89_CN][37] = 127, + [0][0][1][0][RTW89_QATAR][37] = 127, + [0][0][1][0][RTW89_UK][37] = 76, + [0][0][1][0][RTW89_FCC][38] = 78, + [0][0][1][0][RTW89_ETSI][38] = 28, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 78, + [0][0][1][0][RTW89_KCC][38] = 74, + [0][0][1][0][RTW89_ACMA][38] = 76, + [0][0][1][0][RTW89_CHILE][38] = 68, + [0][0][1][0][RTW89_UKRAINE][38] = 28, + [0][0][1][0][RTW89_MEXICO][38] = 78, + [0][0][1][0][RTW89_CN][38] = 62, + [0][0][1][0][RTW89_QATAR][38] = 28, + [0][0][1][0][RTW89_UK][38] = 58, + [0][0][1][0][RTW89_FCC][40] = 78, + [0][0][1][0][RTW89_ETSI][40] = 28, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 78, + [0][0][1][0][RTW89_KCC][40] = 74, + [0][0][1][0][RTW89_ACMA][40] = 76, + [0][0][1][0][RTW89_CHILE][40] = 68, + [0][0][1][0][RTW89_UKRAINE][40] = 28, + [0][0][1][0][RTW89_MEXICO][40] = 78, + [0][0][1][0][RTW89_CN][40] = 62, + [0][0][1][0][RTW89_QATAR][40] = 28, + [0][0][1][0][RTW89_UK][40] = 58, + [0][0][1][0][RTW89_FCC][42] = 78, + [0][0][1][0][RTW89_ETSI][42] = 28, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 78, + [0][0][1][0][RTW89_KCC][42] = 74, + [0][0][1][0][RTW89_ACMA][42] = 76, + [0][0][1][0][RTW89_CHILE][42] = 66, + [0][0][1][0][RTW89_UKRAINE][42] = 28, + [0][0][1][0][RTW89_MEXICO][42] = 78, + [0][0][1][0][RTW89_CN][42] = 62, + [0][0][1][0][RTW89_QATAR][42] = 28, + [0][0][1][0][RTW89_UK][42] = 58, + [0][0][1][0][RTW89_FCC][44] = 78, + [0][0][1][0][RTW89_ETSI][44] = 28, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 78, + [0][0][1][0][RTW89_KCC][44] = 74, + [0][0][1][0][RTW89_ACMA][44] = 76, + [0][0][1][0][RTW89_CHILE][44] = 68, + [0][0][1][0][RTW89_UKRAINE][44] = 28, + [0][0][1][0][RTW89_MEXICO][44] = 78, + [0][0][1][0][RTW89_CN][44] = 62, + [0][0][1][0][RTW89_QATAR][44] = 28, + [0][0][1][0][RTW89_UK][44] = 58, + [0][0][1][0][RTW89_FCC][46] = 78, + [0][0][1][0][RTW89_ETSI][46] = 28, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 78, + [0][0][1][0][RTW89_KCC][46] = 74, + [0][0][1][0][RTW89_ACMA][46] = 76, + [0][0][1][0][RTW89_CHILE][46] = 68, + [0][0][1][0][RTW89_UKRAINE][46] = 28, + [0][0][1][0][RTW89_MEXICO][46] = 78, + [0][0][1][0][RTW89_CN][46] = 62, + [0][0][1][0][RTW89_QATAR][46] = 28, + [0][0][1][0][RTW89_UK][46] = 58, + [0][0][1][0][RTW89_FCC][48] = 78, + [0][0][1][0][RTW89_ETSI][48] = 127, + [0][0][1][0][RTW89_MKK][48] = 127, + [0][0][1][0][RTW89_IC][48] = 76, + [0][0][1][0][RTW89_KCC][48] = 127, + [0][0][1][0][RTW89_ACMA][48] = 127, + [0][0][1][0][RTW89_CHILE][48] = 127, + [0][0][1][0][RTW89_UKRAINE][48] = 127, + [0][0][1][0][RTW89_MEXICO][48] = 127, + [0][0][1][0][RTW89_CN][48] = 127, + [0][0][1][0][RTW89_QATAR][48] = 127, + [0][0][1][0][RTW89_UK][48] = 127, + [0][0][1][0][RTW89_FCC][50] = 78, + [0][0][1][0][RTW89_ETSI][50] = 127, + [0][0][1][0][RTW89_MKK][50] = 127, + [0][0][1][0][RTW89_IC][50] = 76, + [0][0][1][0][RTW89_KCC][50] = 127, + [0][0][1][0][RTW89_ACMA][50] = 127, + [0][0][1][0][RTW89_CHILE][50] = 127, + [0][0][1][0][RTW89_UKRAINE][50] = 127, + [0][0][1][0][RTW89_MEXICO][50] = 127, + [0][0][1][0][RTW89_CN][50] = 127, + [0][0][1][0][RTW89_QATAR][50] = 127, + [0][0][1][0][RTW89_UK][50] = 127, + [0][0][1][0][RTW89_FCC][52] = 78, + [0][0][1][0][RTW89_ETSI][52] = 127, + [0][0][1][0][RTW89_MKK][52] = 127, + [0][0][1][0][RTW89_IC][52] = 76, + [0][0][1][0][RTW89_KCC][52] = 127, + [0][0][1][0][RTW89_ACMA][52] = 127, + [0][0][1][0][RTW89_CHILE][52] = 127, + [0][0][1][0][RTW89_UKRAINE][52] = 127, + [0][0][1][0][RTW89_MEXICO][52] = 127, + [0][0][1][0][RTW89_CN][52] = 127, + [0][0][1][0][RTW89_QATAR][52] = 127, + [0][0][1][0][RTW89_UK][52] = 127, + [0][1][1][0][RTW89_FCC][0] = 68, + [0][1][1][0][RTW89_ETSI][0] = 46, + [0][1][1][0][RTW89_MKK][0] = 48, + [0][1][1][0][RTW89_IC][0] = 40, + [0][1][1][0][RTW89_KCC][0] = 64, + [0][1][1][0][RTW89_ACMA][0] = 46, + [0][1][1][0][RTW89_CHILE][0] = 30, + [0][1][1][0][RTW89_UKRAINE][0] = 40, + [0][1][1][0][RTW89_MEXICO][0] = 50, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, + [0][1][1][0][RTW89_FCC][2] = 68, + [0][1][1][0][RTW89_ETSI][2] = 46, + [0][1][1][0][RTW89_MKK][2] = 48, + [0][1][1][0][RTW89_IC][2] = 40, + [0][1][1][0][RTW89_KCC][2] = 64, + [0][1][1][0][RTW89_ACMA][2] = 46, + [0][1][1][0][RTW89_CHILE][2] = 32, + [0][1][1][0][RTW89_UKRAINE][2] = 40, + [0][1][1][0][RTW89_MEXICO][2] = 50, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, + [0][1][1][0][RTW89_FCC][4] = 68, + [0][1][1][0][RTW89_ETSI][4] = 46, + [0][1][1][0][RTW89_MKK][4] = 48, + [0][1][1][0][RTW89_IC][4] = 40, + [0][1][1][0][RTW89_KCC][4] = 64, + [0][1][1][0][RTW89_ACMA][4] = 46, + [0][1][1][0][RTW89_CHILE][4] = 30, + [0][1][1][0][RTW89_UKRAINE][4] = 40, + [0][1][1][0][RTW89_MEXICO][4] = 50, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, + [0][1][1][0][RTW89_FCC][6] = 68, + [0][1][1][0][RTW89_ETSI][6] = 46, + [0][1][1][0][RTW89_MKK][6] = 48, + [0][1][1][0][RTW89_IC][6] = 40, + [0][1][1][0][RTW89_KCC][6] = 38, + [0][1][1][0][RTW89_ACMA][6] = 46, + [0][1][1][0][RTW89_CHILE][6] = 30, + [0][1][1][0][RTW89_UKRAINE][6] = 40, + [0][1][1][0][RTW89_MEXICO][6] = 50, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, + [0][1][1][0][RTW89_FCC][8] = 68, + [0][1][1][0][RTW89_ETSI][8] = 46, + [0][1][1][0][RTW89_MKK][8] = 48, + [0][1][1][0][RTW89_IC][8] = 52, + [0][1][1][0][RTW89_KCC][8] = 64, + [0][1][1][0][RTW89_ACMA][8] = 46, + [0][1][1][0][RTW89_CHILE][8] = 52, + [0][1][1][0][RTW89_UKRAINE][8] = 40, + [0][1][1][0][RTW89_MEXICO][8] = 68, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, + [0][1][1][0][RTW89_FCC][10] = 68, + [0][1][1][0][RTW89_ETSI][10] = 46, + [0][1][1][0][RTW89_MKK][10] = 48, + [0][1][1][0][RTW89_IC][10] = 52, + [0][1][1][0][RTW89_KCC][10] = 64, + [0][1][1][0][RTW89_ACMA][10] = 46, + [0][1][1][0][RTW89_CHILE][10] = 52, + [0][1][1][0][RTW89_UKRAINE][10] = 40, + [0][1][1][0][RTW89_MEXICO][10] = 68, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, + [0][1][1][0][RTW89_FCC][12] = 68, + [0][1][1][0][RTW89_ETSI][12] = 46, + [0][1][1][0][RTW89_MKK][12] = 48, + [0][1][1][0][RTW89_IC][12] = 52, + [0][1][1][0][RTW89_KCC][12] = 64, + [0][1][1][0][RTW89_ACMA][12] = 46, + [0][1][1][0][RTW89_CHILE][12] = 52, + [0][1][1][0][RTW89_UKRAINE][12] = 40, + [0][1][1][0][RTW89_MEXICO][12] = 68, + [0][1][1][0][RTW89_CN][12] = 46, + [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, + [0][1][1][0][RTW89_FCC][14] = 68, + [0][1][1][0][RTW89_ETSI][14] = 46, + [0][1][1][0][RTW89_MKK][14] = 48, + [0][1][1][0][RTW89_IC][14] = 52, + [0][1][1][0][RTW89_KCC][14] = 64, + [0][1][1][0][RTW89_ACMA][14] = 46, + [0][1][1][0][RTW89_CHILE][14] = 52, + [0][1][1][0][RTW89_UKRAINE][14] = 40, + [0][1][1][0][RTW89_MEXICO][14] = 68, + [0][1][1][0][RTW89_CN][14] = 46, + [0][1][1][0][RTW89_QATAR][14] = 46, + [0][1][1][0][RTW89_UK][14] = 46, + [0][1][1][0][RTW89_FCC][15] = 66, + [0][1][1][0][RTW89_ETSI][15] = 46, + [0][1][1][0][RTW89_MKK][15] = 68, + [0][1][1][0][RTW89_IC][15] = 66, + [0][1][1][0][RTW89_KCC][15] = 62, + [0][1][1][0][RTW89_ACMA][15] = 46, + [0][1][1][0][RTW89_CHILE][15] = 48, + [0][1][1][0][RTW89_UKRAINE][15] = 40, + [0][1][1][0][RTW89_MEXICO][15] = 66, + [0][1][1][0][RTW89_CN][15] = 127, + [0][1][1][0][RTW89_QATAR][15] = 46, + [0][1][1][0][RTW89_UK][15] = 46, + [0][1][1][0][RTW89_FCC][17] = 68, + [0][1][1][0][RTW89_ETSI][17] = 46, + [0][1][1][0][RTW89_MKK][17] = 70, + [0][1][1][0][RTW89_IC][17] = 68, + [0][1][1][0][RTW89_KCC][17] = 62, + [0][1][1][0][RTW89_ACMA][17] = 46, + [0][1][1][0][RTW89_CHILE][17] = 48, + [0][1][1][0][RTW89_UKRAINE][17] = 40, + [0][1][1][0][RTW89_MEXICO][17] = 68, + [0][1][1][0][RTW89_CN][17] = 127, + [0][1][1][0][RTW89_QATAR][17] = 46, + [0][1][1][0][RTW89_UK][17] = 46, + [0][1][1][0][RTW89_FCC][19] = 68, + [0][1][1][0][RTW89_ETSI][19] = 46, + [0][1][1][0][RTW89_MKK][19] = 70, + [0][1][1][0][RTW89_IC][19] = 68, + [0][1][1][0][RTW89_KCC][19] = 62, + [0][1][1][0][RTW89_ACMA][19] = 46, + [0][1][1][0][RTW89_CHILE][19] = 48, + [0][1][1][0][RTW89_UKRAINE][19] = 40, + [0][1][1][0][RTW89_MEXICO][19] = 68, + [0][1][1][0][RTW89_CN][19] = 127, + [0][1][1][0][RTW89_QATAR][19] = 46, + [0][1][1][0][RTW89_UK][19] = 46, + [0][1][1][0][RTW89_FCC][21] = 68, + [0][1][1][0][RTW89_ETSI][21] = 46, + [0][1][1][0][RTW89_MKK][21] = 70, + [0][1][1][0][RTW89_IC][21] = 68, + [0][1][1][0][RTW89_KCC][21] = 62, + [0][1][1][0][RTW89_ACMA][21] = 46, + [0][1][1][0][RTW89_CHILE][21] = 48, + [0][1][1][0][RTW89_UKRAINE][21] = 40, + [0][1][1][0][RTW89_MEXICO][21] = 68, + [0][1][1][0][RTW89_CN][21] = 127, + [0][1][1][0][RTW89_QATAR][21] = 46, + [0][1][1][0][RTW89_UK][21] = 46, + [0][1][1][0][RTW89_FCC][23] = 68, + [0][1][1][0][RTW89_ETSI][23] = 46, + [0][1][1][0][RTW89_MKK][23] = 70, + [0][1][1][0][RTW89_IC][23] = 68, + [0][1][1][0][RTW89_KCC][23] = 62, + [0][1][1][0][RTW89_ACMA][23] = 46, + [0][1][1][0][RTW89_CHILE][23] = 48, + [0][1][1][0][RTW89_UKRAINE][23] = 40, + [0][1][1][0][RTW89_MEXICO][23] = 68, + [0][1][1][0][RTW89_CN][23] = 127, + [0][1][1][0][RTW89_QATAR][23] = 46, + [0][1][1][0][RTW89_UK][23] = 46, + [0][1][1][0][RTW89_FCC][25] = 68, + [0][1][1][0][RTW89_ETSI][25] = 46, + [0][1][1][0][RTW89_MKK][25] = 68, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_KCC][25] = 62, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_CHILE][25] = 48, + [0][1][1][0][RTW89_UKRAINE][25] = 40, + [0][1][1][0][RTW89_MEXICO][25] = 68, + [0][1][1][0][RTW89_CN][25] = 127, + [0][1][1][0][RTW89_QATAR][25] = 46, + [0][1][1][0][RTW89_UK][25] = 46, + [0][1][1][0][RTW89_FCC][27] = 68, + [0][1][1][0][RTW89_ETSI][27] = 46, + [0][1][1][0][RTW89_MKK][27] = 70, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_KCC][27] = 62, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_CHILE][27] = 50, + [0][1][1][0][RTW89_UKRAINE][27] = 40, + [0][1][1][0][RTW89_MEXICO][27] = 68, + [0][1][1][0][RTW89_CN][27] = 127, + [0][1][1][0][RTW89_QATAR][27] = 46, + [0][1][1][0][RTW89_UK][27] = 46, + [0][1][1][0][RTW89_FCC][29] = 68, + [0][1][1][0][RTW89_ETSI][29] = 46, + [0][1][1][0][RTW89_MKK][29] = 70, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_KCC][29] = 62, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_CHILE][29] = 50, + [0][1][1][0][RTW89_UKRAINE][29] = 40, + [0][1][1][0][RTW89_MEXICO][29] = 68, + [0][1][1][0][RTW89_CN][29] = 127, + [0][1][1][0][RTW89_QATAR][29] = 46, + [0][1][1][0][RTW89_UK][29] = 46, + [0][1][1][0][RTW89_FCC][31] = 68, + [0][1][1][0][RTW89_ETSI][31] = 46, + [0][1][1][0][RTW89_MKK][31] = 70, + [0][1][1][0][RTW89_IC][31] = 68, + [0][1][1][0][RTW89_KCC][31] = 62, + [0][1][1][0][RTW89_ACMA][31] = 46, + [0][1][1][0][RTW89_CHILE][31] = 50, + [0][1][1][0][RTW89_UKRAINE][31] = 40, + [0][1][1][0][RTW89_MEXICO][31] = 68, + [0][1][1][0][RTW89_CN][31] = 127, + [0][1][1][0][RTW89_QATAR][31] = 46, + [0][1][1][0][RTW89_UK][31] = 46, + [0][1][1][0][RTW89_FCC][33] = 68, + [0][1][1][0][RTW89_ETSI][33] = 46, + [0][1][1][0][RTW89_MKK][33] = 70, + [0][1][1][0][RTW89_IC][33] = 68, + [0][1][1][0][RTW89_KCC][33] = 62, + [0][1][1][0][RTW89_ACMA][33] = 46, + [0][1][1][0][RTW89_CHILE][33] = 50, + [0][1][1][0][RTW89_UKRAINE][33] = 40, + [0][1][1][0][RTW89_MEXICO][33] = 68, + [0][1][1][0][RTW89_CN][33] = 127, + [0][1][1][0][RTW89_QATAR][33] = 46, + [0][1][1][0][RTW89_UK][33] = 46, + [0][1][1][0][RTW89_FCC][35] = 66, + [0][1][1][0][RTW89_ETSI][35] = 46, + [0][1][1][0][RTW89_MKK][35] = 70, + [0][1][1][0][RTW89_IC][35] = 66, + [0][1][1][0][RTW89_KCC][35] = 62, + [0][1][1][0][RTW89_ACMA][35] = 46, + [0][1][1][0][RTW89_CHILE][35] = 50, + [0][1][1][0][RTW89_UKRAINE][35] = 40, + [0][1][1][0][RTW89_MEXICO][35] = 66, + [0][1][1][0][RTW89_CN][35] = 127, + [0][1][1][0][RTW89_QATAR][35] = 46, + [0][1][1][0][RTW89_UK][35] = 46, + [0][1][1][0][RTW89_FCC][37] = 68, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 70, + [0][1][1][0][RTW89_IC][37] = 68, + [0][1][1][0][RTW89_KCC][37] = 62, + [0][1][1][0][RTW89_ACMA][37] = 70, + [0][1][1][0][RTW89_CHILE][37] = 50, + [0][1][1][0][RTW89_UKRAINE][37] = 127, + [0][1][1][0][RTW89_MEXICO][37] = 68, + [0][1][1][0][RTW89_CN][37] = 127, + [0][1][1][0][RTW89_QATAR][37] = 127, + [0][1][1][0][RTW89_UK][37] = 76, + [0][1][1][0][RTW89_FCC][38] = 78, + [0][1][1][0][RTW89_ETSI][38] = 16, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 78, + [0][1][1][0][RTW89_KCC][38] = 60, + [0][1][1][0][RTW89_ACMA][38] = 72, + [0][1][1][0][RTW89_CHILE][38] = 48, + [0][1][1][0][RTW89_UKRAINE][38] = 16, + [0][1][1][0][RTW89_MEXICO][38] = 78, + [0][1][1][0][RTW89_CN][38] = 62, + [0][1][1][0][RTW89_QATAR][38] = 16, + [0][1][1][0][RTW89_UK][38] = 46, + [0][1][1][0][RTW89_FCC][40] = 78, + [0][1][1][0][RTW89_ETSI][40] = 16, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 78, + [0][1][1][0][RTW89_KCC][40] = 60, + [0][1][1][0][RTW89_ACMA][40] = 72, + [0][1][1][0][RTW89_CHILE][40] = 48, + [0][1][1][0][RTW89_UKRAINE][40] = 16, + [0][1][1][0][RTW89_MEXICO][40] = 78, + [0][1][1][0][RTW89_CN][40] = 62, + [0][1][1][0][RTW89_QATAR][40] = 16, + [0][1][1][0][RTW89_UK][40] = 46, + [0][1][1][0][RTW89_FCC][42] = 78, + [0][1][1][0][RTW89_ETSI][42] = 16, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 78, + [0][1][1][0][RTW89_KCC][42] = 60, + [0][1][1][0][RTW89_ACMA][42] = 76, + [0][1][1][0][RTW89_CHILE][42] = 48, + [0][1][1][0][RTW89_UKRAINE][42] = 16, + [0][1][1][0][RTW89_MEXICO][42] = 78, + [0][1][1][0][RTW89_CN][42] = 62, + [0][1][1][0][RTW89_QATAR][42] = 16, + [0][1][1][0][RTW89_UK][42] = 46, + [0][1][1][0][RTW89_FCC][44] = 78, + [0][1][1][0][RTW89_ETSI][44] = 16, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 78, + [0][1][1][0][RTW89_KCC][44] = 60, + [0][1][1][0][RTW89_ACMA][44] = 76, + [0][1][1][0][RTW89_CHILE][44] = 48, + [0][1][1][0][RTW89_UKRAINE][44] = 16, + [0][1][1][0][RTW89_MEXICO][44] = 78, + [0][1][1][0][RTW89_CN][44] = 62, + [0][1][1][0][RTW89_QATAR][44] = 16, + [0][1][1][0][RTW89_UK][44] = 46, + [0][1][1][0][RTW89_FCC][46] = 78, + [0][1][1][0][RTW89_ETSI][46] = 16, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 78, + [0][1][1][0][RTW89_KCC][46] = 60, + [0][1][1][0][RTW89_ACMA][46] = 76, + [0][1][1][0][RTW89_CHILE][46] = 48, + [0][1][1][0][RTW89_UKRAINE][46] = 16, + [0][1][1][0][RTW89_MEXICO][46] = 78, + [0][1][1][0][RTW89_CN][46] = 62, + [0][1][1][0][RTW89_QATAR][46] = 16, + [0][1][1][0][RTW89_UK][46] = 46, + [0][1][1][0][RTW89_FCC][48] = 56, + [0][1][1][0][RTW89_ETSI][48] = 127, + [0][1][1][0][RTW89_MKK][48] = 127, + [0][1][1][0][RTW89_IC][48] = 50, + [0][1][1][0][RTW89_KCC][48] = 127, + [0][1][1][0][RTW89_ACMA][48] = 127, + [0][1][1][0][RTW89_CHILE][48] = 127, + [0][1][1][0][RTW89_UKRAINE][48] = 127, + [0][1][1][0][RTW89_MEXICO][48] = 127, + [0][1][1][0][RTW89_CN][48] = 127, + [0][1][1][0][RTW89_QATAR][48] = 127, + [0][1][1][0][RTW89_UK][48] = 127, + [0][1][1][0][RTW89_FCC][50] = 56, + [0][1][1][0][RTW89_ETSI][50] = 127, + [0][1][1][0][RTW89_MKK][50] = 127, + [0][1][1][0][RTW89_IC][50] = 50, + [0][1][1][0][RTW89_KCC][50] = 127, + [0][1][1][0][RTW89_ACMA][50] = 127, + [0][1][1][0][RTW89_CHILE][50] = 127, + [0][1][1][0][RTW89_UKRAINE][50] = 127, + [0][1][1][0][RTW89_MEXICO][50] = 127, + [0][1][1][0][RTW89_CN][50] = 127, + [0][1][1][0][RTW89_QATAR][50] = 127, + [0][1][1][0][RTW89_UK][50] = 127, + [0][1][1][0][RTW89_FCC][52] = 56, + [0][1][1][0][RTW89_ETSI][52] = 127, + [0][1][1][0][RTW89_MKK][52] = 127, + [0][1][1][0][RTW89_IC][52] = 50, + [0][1][1][0][RTW89_KCC][52] = 127, + [0][1][1][0][RTW89_ACMA][52] = 127, + [0][1][1][0][RTW89_CHILE][52] = 127, + [0][1][1][0][RTW89_UKRAINE][52] = 127, + [0][1][1][0][RTW89_MEXICO][52] = 127, + [0][1][1][0][RTW89_CN][52] = 127, + [0][1][1][0][RTW89_QATAR][52] = 127, + [0][1][1][0][RTW89_UK][52] = 127, + [0][0][2][0][RTW89_FCC][0] = 78, + [0][0][2][0][RTW89_ETSI][0] = 60, + [0][0][2][0][RTW89_MKK][0] = 62, + [0][0][2][0][RTW89_IC][0] = 64, + [0][0][2][0][RTW89_KCC][0] = 74, + [0][0][2][0][RTW89_ACMA][0] = 60, + [0][0][2][0][RTW89_CHILE][0] = 42, + [0][0][2][0][RTW89_UKRAINE][0] = 52, + [0][0][2][0][RTW89_MEXICO][0] = 62, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_QATAR][0] = 60, + [0][0][2][0][RTW89_UK][0] = 60, + [0][0][2][0][RTW89_FCC][2] = 78, + [0][0][2][0][RTW89_ETSI][2] = 60, + [0][0][2][0][RTW89_MKK][2] = 62, + [0][0][2][0][RTW89_IC][2] = 64, + [0][0][2][0][RTW89_KCC][2] = 74, + [0][0][2][0][RTW89_ACMA][2] = 60, + [0][0][2][0][RTW89_CHILE][2] = 42, + [0][0][2][0][RTW89_UKRAINE][2] = 52, + [0][0][2][0][RTW89_MEXICO][2] = 62, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_QATAR][2] = 60, + [0][0][2][0][RTW89_UK][2] = 60, + [0][0][2][0][RTW89_FCC][4] = 78, + [0][0][2][0][RTW89_ETSI][4] = 60, + [0][0][2][0][RTW89_MKK][4] = 62, + [0][0][2][0][RTW89_IC][4] = 64, + [0][0][2][0][RTW89_KCC][4] = 74, + [0][0][2][0][RTW89_ACMA][4] = 60, + [0][0][2][0][RTW89_CHILE][4] = 42, + [0][0][2][0][RTW89_UKRAINE][4] = 52, + [0][0][2][0][RTW89_MEXICO][4] = 62, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_QATAR][4] = 60, + [0][0][2][0][RTW89_UK][4] = 60, + [0][0][2][0][RTW89_FCC][6] = 78, + [0][0][2][0][RTW89_ETSI][6] = 60, + [0][0][2][0][RTW89_MKK][6] = 62, + [0][0][2][0][RTW89_IC][6] = 64, + [0][0][2][0][RTW89_KCC][6] = 50, + [0][0][2][0][RTW89_ACMA][6] = 60, + [0][0][2][0][RTW89_CHILE][6] = 42, + [0][0][2][0][RTW89_UKRAINE][6] = 52, + [0][0][2][0][RTW89_MEXICO][6] = 62, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_QATAR][6] = 60, + [0][0][2][0][RTW89_UK][6] = 60, + [0][0][2][0][RTW89_FCC][8] = 78, + [0][0][2][0][RTW89_ETSI][8] = 60, + [0][0][2][0][RTW89_MKK][8] = 62, + [0][0][2][0][RTW89_IC][8] = 64, + [0][0][2][0][RTW89_KCC][8] = 74, + [0][0][2][0][RTW89_ACMA][8] = 60, + [0][0][2][0][RTW89_CHILE][8] = 66, + [0][0][2][0][RTW89_UKRAINE][8] = 52, + [0][0][2][0][RTW89_MEXICO][8] = 78, + [0][0][2][0][RTW89_CN][8] = 60, + [0][0][2][0][RTW89_QATAR][8] = 60, + [0][0][2][0][RTW89_UK][8] = 60, + [0][0][2][0][RTW89_FCC][10] = 78, + [0][0][2][0][RTW89_ETSI][10] = 60, + [0][0][2][0][RTW89_MKK][10] = 62, + [0][0][2][0][RTW89_IC][10] = 64, + [0][0][2][0][RTW89_KCC][10] = 74, + [0][0][2][0][RTW89_ACMA][10] = 60, + [0][0][2][0][RTW89_CHILE][10] = 66, + [0][0][2][0][RTW89_UKRAINE][10] = 52, + [0][0][2][0][RTW89_MEXICO][10] = 78, + [0][0][2][0][RTW89_CN][10] = 60, + [0][0][2][0][RTW89_QATAR][10] = 60, + [0][0][2][0][RTW89_UK][10] = 60, + [0][0][2][0][RTW89_FCC][12] = 78, + [0][0][2][0][RTW89_ETSI][12] = 60, + [0][0][2][0][RTW89_MKK][12] = 62, + [0][0][2][0][RTW89_IC][12] = 64, + [0][0][2][0][RTW89_KCC][12] = 74, + [0][0][2][0][RTW89_ACMA][12] = 60, + [0][0][2][0][RTW89_CHILE][12] = 66, + [0][0][2][0][RTW89_UKRAINE][12] = 52, + [0][0][2][0][RTW89_MEXICO][12] = 78, + [0][0][2][0][RTW89_CN][12] = 60, + [0][0][2][0][RTW89_QATAR][12] = 60, + [0][0][2][0][RTW89_UK][12] = 60, + [0][0][2][0][RTW89_FCC][14] = 78, + [0][0][2][0][RTW89_ETSI][14] = 60, + [0][0][2][0][RTW89_MKK][14] = 62, + [0][0][2][0][RTW89_IC][14] = 64, + [0][0][2][0][RTW89_KCC][14] = 74, + [0][0][2][0][RTW89_ACMA][14] = 60, + [0][0][2][0][RTW89_CHILE][14] = 66, + [0][0][2][0][RTW89_UKRAINE][14] = 52, + [0][0][2][0][RTW89_MEXICO][14] = 78, + [0][0][2][0][RTW89_CN][14] = 60, + [0][0][2][0][RTW89_QATAR][14] = 60, + [0][0][2][0][RTW89_UK][14] = 60, + [0][0][2][0][RTW89_FCC][15] = 74, + [0][0][2][0][RTW89_ETSI][15] = 60, + [0][0][2][0][RTW89_MKK][15] = 76, + [0][0][2][0][RTW89_IC][15] = 74, + [0][0][2][0][RTW89_KCC][15] = 74, + [0][0][2][0][RTW89_ACMA][15] = 60, + [0][0][2][0][RTW89_CHILE][15] = 64, + [0][0][2][0][RTW89_UKRAINE][15] = 52, + [0][0][2][0][RTW89_MEXICO][15] = 74, + [0][0][2][0][RTW89_CN][15] = 127, + [0][0][2][0][RTW89_QATAR][15] = 60, + [0][0][2][0][RTW89_UK][15] = 60, + [0][0][2][0][RTW89_FCC][17] = 78, + [0][0][2][0][RTW89_ETSI][17] = 60, + [0][0][2][0][RTW89_MKK][17] = 76, + [0][0][2][0][RTW89_IC][17] = 78, + [0][0][2][0][RTW89_KCC][17] = 74, + [0][0][2][0][RTW89_ACMA][17] = 60, + [0][0][2][0][RTW89_CHILE][17] = 64, + [0][0][2][0][RTW89_UKRAINE][17] = 52, + [0][0][2][0][RTW89_MEXICO][17] = 78, + [0][0][2][0][RTW89_CN][17] = 127, + [0][0][2][0][RTW89_QATAR][17] = 60, + [0][0][2][0][RTW89_UK][17] = 60, + [0][0][2][0][RTW89_FCC][19] = 78, + [0][0][2][0][RTW89_ETSI][19] = 60, + [0][0][2][0][RTW89_MKK][19] = 76, + [0][0][2][0][RTW89_IC][19] = 78, + [0][0][2][0][RTW89_KCC][19] = 74, + [0][0][2][0][RTW89_ACMA][19] = 60, + [0][0][2][0][RTW89_CHILE][19] = 64, + [0][0][2][0][RTW89_UKRAINE][19] = 52, + [0][0][2][0][RTW89_MEXICO][19] = 78, + [0][0][2][0][RTW89_CN][19] = 127, + [0][0][2][0][RTW89_QATAR][19] = 60, + [0][0][2][0][RTW89_UK][19] = 60, + [0][0][2][0][RTW89_FCC][21] = 78, + [0][0][2][0][RTW89_ETSI][21] = 60, + [0][0][2][0][RTW89_MKK][21] = 76, + [0][0][2][0][RTW89_IC][21] = 78, + [0][0][2][0][RTW89_KCC][21] = 74, + [0][0][2][0][RTW89_ACMA][21] = 60, + [0][0][2][0][RTW89_CHILE][21] = 66, + [0][0][2][0][RTW89_UKRAINE][21] = 52, + [0][0][2][0][RTW89_MEXICO][21] = 78, + [0][0][2][0][RTW89_CN][21] = 127, + [0][0][2][0][RTW89_QATAR][21] = 60, + [0][0][2][0][RTW89_UK][21] = 60, + [0][0][2][0][RTW89_FCC][23] = 78, + [0][0][2][0][RTW89_ETSI][23] = 60, + [0][0][2][0][RTW89_MKK][23] = 76, + [0][0][2][0][RTW89_IC][23] = 78, + [0][0][2][0][RTW89_KCC][23] = 74, + [0][0][2][0][RTW89_ACMA][23] = 60, + [0][0][2][0][RTW89_CHILE][23] = 66, + [0][0][2][0][RTW89_UKRAINE][23] = 52, + [0][0][2][0][RTW89_MEXICO][23] = 78, + [0][0][2][0][RTW89_CN][23] = 127, + [0][0][2][0][RTW89_QATAR][23] = 60, + [0][0][2][0][RTW89_UK][23] = 60, + [0][0][2][0][RTW89_FCC][25] = 78, + [0][0][2][0][RTW89_ETSI][25] = 60, + [0][0][2][0][RTW89_MKK][25] = 76, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_KCC][25] = 74, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_CHILE][25] = 66, + [0][0][2][0][RTW89_UKRAINE][25] = 52, + [0][0][2][0][RTW89_MEXICO][25] = 78, + [0][0][2][0][RTW89_CN][25] = 127, + [0][0][2][0][RTW89_QATAR][25] = 60, + [0][0][2][0][RTW89_UK][25] = 60, + [0][0][2][0][RTW89_FCC][27] = 78, + [0][0][2][0][RTW89_ETSI][27] = 60, + [0][0][2][0][RTW89_MKK][27] = 76, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_KCC][27] = 74, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_CHILE][27] = 64, + [0][0][2][0][RTW89_UKRAINE][27] = 52, + [0][0][2][0][RTW89_MEXICO][27] = 78, + [0][0][2][0][RTW89_CN][27] = 127, + [0][0][2][0][RTW89_QATAR][27] = 60, + [0][0][2][0][RTW89_UK][27] = 60, + [0][0][2][0][RTW89_FCC][29] = 78, + [0][0][2][0][RTW89_ETSI][29] = 60, + [0][0][2][0][RTW89_MKK][29] = 76, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_KCC][29] = 74, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_CHILE][29] = 64, + [0][0][2][0][RTW89_UKRAINE][29] = 52, + [0][0][2][0][RTW89_MEXICO][29] = 78, + [0][0][2][0][RTW89_CN][29] = 127, + [0][0][2][0][RTW89_QATAR][29] = 60, + [0][0][2][0][RTW89_UK][29] = 60, + [0][0][2][0][RTW89_FCC][31] = 78, + [0][0][2][0][RTW89_ETSI][31] = 60, + [0][0][2][0][RTW89_MKK][31] = 76, + [0][0][2][0][RTW89_IC][31] = 78, + [0][0][2][0][RTW89_KCC][31] = 74, + [0][0][2][0][RTW89_ACMA][31] = 60, + [0][0][2][0][RTW89_CHILE][31] = 64, + [0][0][2][0][RTW89_UKRAINE][31] = 52, + [0][0][2][0][RTW89_MEXICO][31] = 78, + [0][0][2][0][RTW89_CN][31] = 127, + [0][0][2][0][RTW89_QATAR][31] = 60, + [0][0][2][0][RTW89_UK][31] = 60, + [0][0][2][0][RTW89_FCC][33] = 78, + [0][0][2][0][RTW89_ETSI][33] = 60, + [0][0][2][0][RTW89_MKK][33] = 76, + [0][0][2][0][RTW89_IC][33] = 78, + [0][0][2][0][RTW89_KCC][33] = 74, + [0][0][2][0][RTW89_ACMA][33] = 60, + [0][0][2][0][RTW89_CHILE][33] = 64, + [0][0][2][0][RTW89_UKRAINE][33] = 52, + [0][0][2][0][RTW89_MEXICO][33] = 78, + [0][0][2][0][RTW89_CN][33] = 127, + [0][0][2][0][RTW89_QATAR][33] = 60, + [0][0][2][0][RTW89_UK][33] = 60, + [0][0][2][0][RTW89_FCC][35] = 70, + [0][0][2][0][RTW89_ETSI][35] = 60, + [0][0][2][0][RTW89_MKK][35] = 76, + [0][0][2][0][RTW89_IC][35] = 70, + [0][0][2][0][RTW89_KCC][35] = 74, + [0][0][2][0][RTW89_ACMA][35] = 60, + [0][0][2][0][RTW89_CHILE][35] = 64, + [0][0][2][0][RTW89_UKRAINE][35] = 52, + [0][0][2][0][RTW89_MEXICO][35] = 70, + [0][0][2][0][RTW89_CN][35] = 127, + [0][0][2][0][RTW89_QATAR][35] = 60, + [0][0][2][0][RTW89_UK][35] = 60, + [0][0][2][0][RTW89_FCC][37] = 78, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 76, + [0][0][2][0][RTW89_IC][37] = 78, + [0][0][2][0][RTW89_KCC][37] = 74, + [0][0][2][0][RTW89_ACMA][37] = 76, + [0][0][2][0][RTW89_CHILE][37] = 64, + [0][0][2][0][RTW89_UKRAINE][37] = 127, + [0][0][2][0][RTW89_MEXICO][37] = 78, + [0][0][2][0][RTW89_CN][37] = 127, + [0][0][2][0][RTW89_QATAR][37] = 127, + [0][0][2][0][RTW89_UK][37] = 74, + [0][0][2][0][RTW89_FCC][38] = 78, + [0][0][2][0][RTW89_ETSI][38] = 28, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 78, + [0][0][2][0][RTW89_KCC][38] = 72, + [0][0][2][0][RTW89_ACMA][38] = 76, + [0][0][2][0][RTW89_CHILE][38] = 64, + [0][0][2][0][RTW89_UKRAINE][38] = 28, + [0][0][2][0][RTW89_MEXICO][38] = 78, + [0][0][2][0][RTW89_CN][38] = 62, + [0][0][2][0][RTW89_QATAR][38] = 28, + [0][0][2][0][RTW89_UK][38] = 60, + [0][0][2][0][RTW89_FCC][40] = 78, + [0][0][2][0][RTW89_ETSI][40] = 28, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 78, + [0][0][2][0][RTW89_KCC][40] = 72, + [0][0][2][0][RTW89_ACMA][40] = 76, + [0][0][2][0][RTW89_CHILE][40] = 64, + [0][0][2][0][RTW89_UKRAINE][40] = 28, + [0][0][2][0][RTW89_MEXICO][40] = 78, + [0][0][2][0][RTW89_CN][40] = 62, + [0][0][2][0][RTW89_QATAR][40] = 28, + [0][0][2][0][RTW89_UK][40] = 60, + [0][0][2][0][RTW89_FCC][42] = 78, + [0][0][2][0][RTW89_ETSI][42] = 28, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 78, + [0][0][2][0][RTW89_KCC][42] = 72, + [0][0][2][0][RTW89_ACMA][42] = 76, + [0][0][2][0][RTW89_CHILE][42] = 64, + [0][0][2][0][RTW89_UKRAINE][42] = 28, + [0][0][2][0][RTW89_MEXICO][42] = 78, + [0][0][2][0][RTW89_CN][42] = 62, + [0][0][2][0][RTW89_QATAR][42] = 28, + [0][0][2][0][RTW89_UK][42] = 60, + [0][0][2][0][RTW89_FCC][44] = 78, + [0][0][2][0][RTW89_ETSI][44] = 28, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 78, + [0][0][2][0][RTW89_KCC][44] = 72, + [0][0][2][0][RTW89_ACMA][44] = 76, + [0][0][2][0][RTW89_CHILE][44] = 66, + [0][0][2][0][RTW89_UKRAINE][44] = 28, + [0][0][2][0][RTW89_MEXICO][44] = 78, + [0][0][2][0][RTW89_CN][44] = 62, + [0][0][2][0][RTW89_QATAR][44] = 28, + [0][0][2][0][RTW89_UK][44] = 60, + [0][0][2][0][RTW89_FCC][46] = 78, + [0][0][2][0][RTW89_ETSI][46] = 28, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 78, + [0][0][2][0][RTW89_KCC][46] = 72, + [0][0][2][0][RTW89_ACMA][46] = 76, + [0][0][2][0][RTW89_CHILE][46] = 66, + [0][0][2][0][RTW89_UKRAINE][46] = 28, + [0][0][2][0][RTW89_MEXICO][46] = 78, + [0][0][2][0][RTW89_CN][46] = 62, + [0][0][2][0][RTW89_QATAR][46] = 28, + [0][0][2][0][RTW89_UK][46] = 60, + [0][0][2][0][RTW89_FCC][48] = 78, + [0][0][2][0][RTW89_ETSI][48] = 127, + [0][0][2][0][RTW89_MKK][48] = 127, + [0][0][2][0][RTW89_IC][48] = 78, + [0][0][2][0][RTW89_KCC][48] = 127, + [0][0][2][0][RTW89_ACMA][48] = 127, + [0][0][2][0][RTW89_CHILE][48] = 127, + [0][0][2][0][RTW89_UKRAINE][48] = 127, + [0][0][2][0][RTW89_MEXICO][48] = 127, + [0][0][2][0][RTW89_CN][48] = 127, + [0][0][2][0][RTW89_QATAR][48] = 127, + [0][0][2][0][RTW89_UK][48] = 127, + [0][0][2][0][RTW89_FCC][50] = 78, + [0][0][2][0][RTW89_ETSI][50] = 127, + [0][0][2][0][RTW89_MKK][50] = 127, + [0][0][2][0][RTW89_IC][50] = 78, + [0][0][2][0][RTW89_KCC][50] = 127, + [0][0][2][0][RTW89_ACMA][50] = 127, + [0][0][2][0][RTW89_CHILE][50] = 127, + [0][0][2][0][RTW89_UKRAINE][50] = 127, + [0][0][2][0][RTW89_MEXICO][50] = 127, + [0][0][2][0][RTW89_CN][50] = 127, + [0][0][2][0][RTW89_QATAR][50] = 127, + [0][0][2][0][RTW89_UK][50] = 127, + [0][0][2][0][RTW89_FCC][52] = 78, + [0][0][2][0][RTW89_ETSI][52] = 127, + [0][0][2][0][RTW89_MKK][52] = 127, + [0][0][2][0][RTW89_IC][52] = 78, + [0][0][2][0][RTW89_KCC][52] = 127, + [0][0][2][0][RTW89_ACMA][52] = 127, + [0][0][2][0][RTW89_CHILE][52] = 127, + [0][0][2][0][RTW89_UKRAINE][52] = 127, + [0][0][2][0][RTW89_MEXICO][52] = 127, + [0][0][2][0][RTW89_CN][52] = 127, + [0][0][2][0][RTW89_QATAR][52] = 127, + [0][0][2][0][RTW89_UK][52] = 127, + [0][1][2][0][RTW89_FCC][0] = 70, + [0][1][2][0][RTW89_ETSI][0] = 48, + [0][1][2][0][RTW89_MKK][0] = 50, + [0][1][2][0][RTW89_IC][0] = 42, + [0][1][2][0][RTW89_KCC][0] = 62, + [0][1][2][0][RTW89_ACMA][0] = 48, + [0][1][2][0][RTW89_CHILE][0] = 30, + [0][1][2][0][RTW89_UKRAINE][0] = 40, + [0][1][2][0][RTW89_MEXICO][0] = 50, + [0][1][2][0][RTW89_CN][0] = 46, + [0][1][2][0][RTW89_QATAR][0] = 48, + [0][1][2][0][RTW89_UK][0] = 48, + [0][1][2][0][RTW89_FCC][2] = 70, + [0][1][2][0][RTW89_ETSI][2] = 48, + [0][1][2][0][RTW89_MKK][2] = 50, + [0][1][2][0][RTW89_IC][2] = 42, + [0][1][2][0][RTW89_KCC][2] = 62, + [0][1][2][0][RTW89_ACMA][2] = 48, + [0][1][2][0][RTW89_CHILE][2] = 30, + [0][1][2][0][RTW89_UKRAINE][2] = 40, + [0][1][2][0][RTW89_MEXICO][2] = 50, + [0][1][2][0][RTW89_CN][2] = 46, + [0][1][2][0][RTW89_QATAR][2] = 48, + [0][1][2][0][RTW89_UK][2] = 48, + [0][1][2][0][RTW89_FCC][4] = 70, + [0][1][2][0][RTW89_ETSI][4] = 48, + [0][1][2][0][RTW89_MKK][4] = 50, + [0][1][2][0][RTW89_IC][4] = 42, + [0][1][2][0][RTW89_KCC][4] = 62, + [0][1][2][0][RTW89_ACMA][4] = 48, + [0][1][2][0][RTW89_CHILE][4] = 30, + [0][1][2][0][RTW89_UKRAINE][4] = 40, + [0][1][2][0][RTW89_MEXICO][4] = 50, + [0][1][2][0][RTW89_CN][4] = 46, + [0][1][2][0][RTW89_QATAR][4] = 48, + [0][1][2][0][RTW89_UK][4] = 48, + [0][1][2][0][RTW89_FCC][6] = 70, + [0][1][2][0][RTW89_ETSI][6] = 48, + [0][1][2][0][RTW89_MKK][6] = 50, + [0][1][2][0][RTW89_IC][6] = 42, + [0][1][2][0][RTW89_KCC][6] = 34, + [0][1][2][0][RTW89_ACMA][6] = 48, + [0][1][2][0][RTW89_CHILE][6] = 30, + [0][1][2][0][RTW89_UKRAINE][6] = 40, + [0][1][2][0][RTW89_MEXICO][6] = 50, + [0][1][2][0][RTW89_CN][6] = 46, + [0][1][2][0][RTW89_QATAR][6] = 48, + [0][1][2][0][RTW89_UK][6] = 48, + [0][1][2][0][RTW89_FCC][8] = 70, + [0][1][2][0][RTW89_ETSI][8] = 48, + [0][1][2][0][RTW89_MKK][8] = 50, + [0][1][2][0][RTW89_IC][8] = 52, + [0][1][2][0][RTW89_KCC][8] = 62, + [0][1][2][0][RTW89_ACMA][8] = 48, + [0][1][2][0][RTW89_CHILE][8] = 50, + [0][1][2][0][RTW89_UKRAINE][8] = 40, + [0][1][2][0][RTW89_MEXICO][8] = 70, + [0][1][2][0][RTW89_CN][8] = 48, + [0][1][2][0][RTW89_QATAR][8] = 48, + [0][1][2][0][RTW89_UK][8] = 48, + [0][1][2][0][RTW89_FCC][10] = 70, + [0][1][2][0][RTW89_ETSI][10] = 48, + [0][1][2][0][RTW89_MKK][10] = 50, + [0][1][2][0][RTW89_IC][10] = 52, + [0][1][2][0][RTW89_KCC][10] = 62, + [0][1][2][0][RTW89_ACMA][10] = 48, + [0][1][2][0][RTW89_CHILE][10] = 50, + [0][1][2][0][RTW89_UKRAINE][10] = 40, + [0][1][2][0][RTW89_MEXICO][10] = 70, + [0][1][2][0][RTW89_CN][10] = 48, + [0][1][2][0][RTW89_QATAR][10] = 48, + [0][1][2][0][RTW89_UK][10] = 48, + [0][1][2][0][RTW89_FCC][12] = 70, + [0][1][2][0][RTW89_ETSI][12] = 48, + [0][1][2][0][RTW89_MKK][12] = 50, + [0][1][2][0][RTW89_IC][12] = 52, + [0][1][2][0][RTW89_KCC][12] = 62, + [0][1][2][0][RTW89_ACMA][12] = 48, + [0][1][2][0][RTW89_CHILE][12] = 50, + [0][1][2][0][RTW89_UKRAINE][12] = 40, + [0][1][2][0][RTW89_MEXICO][12] = 70, + [0][1][2][0][RTW89_CN][12] = 48, + [0][1][2][0][RTW89_QATAR][12] = 48, + [0][1][2][0][RTW89_UK][12] = 48, + [0][1][2][0][RTW89_FCC][14] = 70, + [0][1][2][0][RTW89_ETSI][14] = 48, + [0][1][2][0][RTW89_MKK][14] = 50, + [0][1][2][0][RTW89_IC][14] = 52, + [0][1][2][0][RTW89_KCC][14] = 62, + [0][1][2][0][RTW89_ACMA][14] = 48, + [0][1][2][0][RTW89_CHILE][14] = 50, + [0][1][2][0][RTW89_UKRAINE][14] = 40, + [0][1][2][0][RTW89_MEXICO][14] = 70, + [0][1][2][0][RTW89_CN][14] = 48, + [0][1][2][0][RTW89_QATAR][14] = 48, + [0][1][2][0][RTW89_UK][14] = 48, + [0][1][2][0][RTW89_FCC][15] = 68, + [0][1][2][0][RTW89_ETSI][15] = 48, + [0][1][2][0][RTW89_MKK][15] = 70, + [0][1][2][0][RTW89_IC][15] = 68, + [0][1][2][0][RTW89_KCC][15] = 62, + [0][1][2][0][RTW89_ACMA][15] = 48, + [0][1][2][0][RTW89_CHILE][15] = 48, + [0][1][2][0][RTW89_UKRAINE][15] = 40, + [0][1][2][0][RTW89_MEXICO][15] = 68, + [0][1][2][0][RTW89_CN][15] = 127, + [0][1][2][0][RTW89_QATAR][15] = 48, + [0][1][2][0][RTW89_UK][15] = 48, + [0][1][2][0][RTW89_FCC][17] = 70, + [0][1][2][0][RTW89_ETSI][17] = 48, + [0][1][2][0][RTW89_MKK][17] = 70, + [0][1][2][0][RTW89_IC][17] = 70, + [0][1][2][0][RTW89_KCC][17] = 62, + [0][1][2][0][RTW89_ACMA][17] = 48, + [0][1][2][0][RTW89_CHILE][17] = 48, + [0][1][2][0][RTW89_UKRAINE][17] = 40, + [0][1][2][0][RTW89_MEXICO][17] = 70, + [0][1][2][0][RTW89_CN][17] = 127, + [0][1][2][0][RTW89_QATAR][17] = 48, + [0][1][2][0][RTW89_UK][17] = 48, + [0][1][2][0][RTW89_FCC][19] = 70, + [0][1][2][0][RTW89_ETSI][19] = 48, + [0][1][2][0][RTW89_MKK][19] = 70, + [0][1][2][0][RTW89_IC][19] = 70, + [0][1][2][0][RTW89_KCC][19] = 62, + [0][1][2][0][RTW89_ACMA][19] = 48, + [0][1][2][0][RTW89_CHILE][19] = 48, + [0][1][2][0][RTW89_UKRAINE][19] = 40, + [0][1][2][0][RTW89_MEXICO][19] = 70, + [0][1][2][0][RTW89_CN][19] = 127, + [0][1][2][0][RTW89_QATAR][19] = 48, + [0][1][2][0][RTW89_UK][19] = 48, + [0][1][2][0][RTW89_FCC][21] = 70, + [0][1][2][0][RTW89_ETSI][21] = 48, + [0][1][2][0][RTW89_MKK][21] = 70, + [0][1][2][0][RTW89_IC][21] = 70, + [0][1][2][0][RTW89_KCC][21] = 62, + [0][1][2][0][RTW89_ACMA][21] = 48, + [0][1][2][0][RTW89_CHILE][21] = 48, + [0][1][2][0][RTW89_UKRAINE][21] = 40, + [0][1][2][0][RTW89_MEXICO][21] = 70, + [0][1][2][0][RTW89_CN][21] = 127, + [0][1][2][0][RTW89_QATAR][21] = 48, + [0][1][2][0][RTW89_UK][21] = 48, + [0][1][2][0][RTW89_FCC][23] = 70, + [0][1][2][0][RTW89_ETSI][23] = 48, + [0][1][2][0][RTW89_MKK][23] = 70, + [0][1][2][0][RTW89_IC][23] = 70, + [0][1][2][0][RTW89_KCC][23] = 62, + [0][1][2][0][RTW89_ACMA][23] = 48, + [0][1][2][0][RTW89_CHILE][23] = 48, + [0][1][2][0][RTW89_UKRAINE][23] = 40, + [0][1][2][0][RTW89_MEXICO][23] = 70, + [0][1][2][0][RTW89_CN][23] = 127, + [0][1][2][0][RTW89_QATAR][23] = 48, + [0][1][2][0][RTW89_UK][23] = 48, + [0][1][2][0][RTW89_FCC][25] = 70, + [0][1][2][0][RTW89_ETSI][25] = 48, + [0][1][2][0][RTW89_MKK][25] = 70, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_KCC][25] = 62, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_CHILE][25] = 48, + [0][1][2][0][RTW89_UKRAINE][25] = 40, + [0][1][2][0][RTW89_MEXICO][25] = 70, + [0][1][2][0][RTW89_CN][25] = 127, + [0][1][2][0][RTW89_QATAR][25] = 48, + [0][1][2][0][RTW89_UK][25] = 48, + [0][1][2][0][RTW89_FCC][27] = 70, + [0][1][2][0][RTW89_ETSI][27] = 48, + [0][1][2][0][RTW89_MKK][27] = 70, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_KCC][27] = 62, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_CHILE][27] = 50, + [0][1][2][0][RTW89_UKRAINE][27] = 40, + [0][1][2][0][RTW89_MEXICO][27] = 70, + [0][1][2][0][RTW89_CN][27] = 127, + [0][1][2][0][RTW89_QATAR][27] = 48, + [0][1][2][0][RTW89_UK][27] = 48, + [0][1][2][0][RTW89_FCC][29] = 70, + [0][1][2][0][RTW89_ETSI][29] = 48, + [0][1][2][0][RTW89_MKK][29] = 70, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_KCC][29] = 62, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_CHILE][29] = 50, + [0][1][2][0][RTW89_UKRAINE][29] = 40, + [0][1][2][0][RTW89_MEXICO][29] = 70, + [0][1][2][0][RTW89_CN][29] = 127, + [0][1][2][0][RTW89_QATAR][29] = 48, + [0][1][2][0][RTW89_UK][29] = 48, + [0][1][2][0][RTW89_FCC][31] = 70, + [0][1][2][0][RTW89_ETSI][31] = 48, + [0][1][2][0][RTW89_MKK][31] = 70, + [0][1][2][0][RTW89_IC][31] = 70, + [0][1][2][0][RTW89_KCC][31] = 62, + [0][1][2][0][RTW89_ACMA][31] = 48, + [0][1][2][0][RTW89_CHILE][31] = 50, + [0][1][2][0][RTW89_UKRAINE][31] = 40, + [0][1][2][0][RTW89_MEXICO][31] = 70, + [0][1][2][0][RTW89_CN][31] = 127, + [0][1][2][0][RTW89_QATAR][31] = 48, + [0][1][2][0][RTW89_UK][31] = 48, + [0][1][2][0][RTW89_FCC][33] = 70, + [0][1][2][0][RTW89_ETSI][33] = 48, + [0][1][2][0][RTW89_MKK][33] = 70, + [0][1][2][0][RTW89_IC][33] = 70, + [0][1][2][0][RTW89_KCC][33] = 62, + [0][1][2][0][RTW89_ACMA][33] = 48, + [0][1][2][0][RTW89_CHILE][33] = 50, + [0][1][2][0][RTW89_UKRAINE][33] = 40, + [0][1][2][0][RTW89_MEXICO][33] = 70, + [0][1][2][0][RTW89_CN][33] = 127, + [0][1][2][0][RTW89_QATAR][33] = 48, + [0][1][2][0][RTW89_UK][33] = 48, + [0][1][2][0][RTW89_FCC][35] = 66, + [0][1][2][0][RTW89_ETSI][35] = 48, + [0][1][2][0][RTW89_MKK][35] = 70, + [0][1][2][0][RTW89_IC][35] = 66, + [0][1][2][0][RTW89_KCC][35] = 62, + [0][1][2][0][RTW89_ACMA][35] = 48, + [0][1][2][0][RTW89_CHILE][35] = 50, + [0][1][2][0][RTW89_UKRAINE][35] = 40, + [0][1][2][0][RTW89_MEXICO][35] = 66, + [0][1][2][0][RTW89_CN][35] = 127, + [0][1][2][0][RTW89_QATAR][35] = 48, + [0][1][2][0][RTW89_UK][35] = 48, + [0][1][2][0][RTW89_FCC][37] = 70, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 70, + [0][1][2][0][RTW89_IC][37] = 70, + [0][1][2][0][RTW89_KCC][37] = 62, + [0][1][2][0][RTW89_ACMA][37] = 70, + [0][1][2][0][RTW89_CHILE][37] = 50, + [0][1][2][0][RTW89_UKRAINE][37] = 127, + [0][1][2][0][RTW89_MEXICO][37] = 70, + [0][1][2][0][RTW89_CN][37] = 127, + [0][1][2][0][RTW89_QATAR][37] = 127, + [0][1][2][0][RTW89_UK][37] = 76, + [0][1][2][0][RTW89_FCC][38] = 78, + [0][1][2][0][RTW89_ETSI][38] = 16, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 78, + [0][1][2][0][RTW89_KCC][38] = 62, + [0][1][2][0][RTW89_ACMA][38] = 74, + [0][1][2][0][RTW89_CHILE][38] = 50, + [0][1][2][0][RTW89_UKRAINE][38] = 16, + [0][1][2][0][RTW89_MEXICO][38] = 78, + [0][1][2][0][RTW89_CN][38] = 62, + [0][1][2][0][RTW89_QATAR][38] = 16, + [0][1][2][0][RTW89_UK][38] = 48, + [0][1][2][0][RTW89_FCC][40] = 78, + [0][1][2][0][RTW89_ETSI][40] = 16, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 78, + [0][1][2][0][RTW89_KCC][40] = 62, + [0][1][2][0][RTW89_ACMA][40] = 74, + [0][1][2][0][RTW89_CHILE][40] = 50, + [0][1][2][0][RTW89_UKRAINE][40] = 16, + [0][1][2][0][RTW89_MEXICO][40] = 78, + [0][1][2][0][RTW89_CN][40] = 62, + [0][1][2][0][RTW89_QATAR][40] = 16, + [0][1][2][0][RTW89_UK][40] = 48, + [0][1][2][0][RTW89_FCC][42] = 78, + [0][1][2][0][RTW89_ETSI][42] = 16, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 78, + [0][1][2][0][RTW89_KCC][42] = 62, + [0][1][2][0][RTW89_ACMA][42] = 76, + [0][1][2][0][RTW89_CHILE][42] = 52, + [0][1][2][0][RTW89_UKRAINE][42] = 16, + [0][1][2][0][RTW89_MEXICO][42] = 78, + [0][1][2][0][RTW89_CN][42] = 62, + [0][1][2][0][RTW89_QATAR][42] = 16, + [0][1][2][0][RTW89_UK][42] = 48, + [0][1][2][0][RTW89_FCC][44] = 78, + [0][1][2][0][RTW89_ETSI][44] = 16, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 78, + [0][1][2][0][RTW89_KCC][44] = 62, + [0][1][2][0][RTW89_ACMA][44] = 76, + [0][1][2][0][RTW89_CHILE][44] = 52, + [0][1][2][0][RTW89_UKRAINE][44] = 16, + [0][1][2][0][RTW89_MEXICO][44] = 78, + [0][1][2][0][RTW89_CN][44] = 62, + [0][1][2][0][RTW89_QATAR][44] = 16, + [0][1][2][0][RTW89_UK][44] = 48, + [0][1][2][0][RTW89_FCC][46] = 78, + [0][1][2][0][RTW89_ETSI][46] = 16, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 78, + [0][1][2][0][RTW89_KCC][46] = 62, + [0][1][2][0][RTW89_ACMA][46] = 76, + [0][1][2][0][RTW89_CHILE][46] = 52, + [0][1][2][0][RTW89_UKRAINE][46] = 16, + [0][1][2][0][RTW89_MEXICO][46] = 78, + [0][1][2][0][RTW89_CN][46] = 62, + [0][1][2][0][RTW89_QATAR][46] = 16, + [0][1][2][0][RTW89_UK][46] = 48, + [0][1][2][0][RTW89_FCC][48] = 58, + [0][1][2][0][RTW89_ETSI][48] = 127, + [0][1][2][0][RTW89_MKK][48] = 127, + [0][1][2][0][RTW89_IC][48] = 50, + [0][1][2][0][RTW89_KCC][48] = 127, + [0][1][2][0][RTW89_ACMA][48] = 127, + [0][1][2][0][RTW89_CHILE][48] = 127, + [0][1][2][0][RTW89_UKRAINE][48] = 127, + [0][1][2][0][RTW89_MEXICO][48] = 127, + [0][1][2][0][RTW89_CN][48] = 127, + [0][1][2][0][RTW89_QATAR][48] = 127, + [0][1][2][0][RTW89_UK][48] = 127, + [0][1][2][0][RTW89_FCC][50] = 58, + [0][1][2][0][RTW89_ETSI][50] = 127, + [0][1][2][0][RTW89_MKK][50] = 127, + [0][1][2][0][RTW89_IC][50] = 52, + [0][1][2][0][RTW89_KCC][50] = 127, + [0][1][2][0][RTW89_ACMA][50] = 127, + [0][1][2][0][RTW89_CHILE][50] = 127, + [0][1][2][0][RTW89_UKRAINE][50] = 127, + [0][1][2][0][RTW89_MEXICO][50] = 127, + [0][1][2][0][RTW89_CN][50] = 127, + [0][1][2][0][RTW89_QATAR][50] = 127, + [0][1][2][0][RTW89_UK][50] = 127, + [0][1][2][0][RTW89_FCC][52] = 58, + [0][1][2][0][RTW89_ETSI][52] = 127, + [0][1][2][0][RTW89_MKK][52] = 127, + [0][1][2][0][RTW89_IC][52] = 52, + [0][1][2][0][RTW89_KCC][52] = 127, + [0][1][2][0][RTW89_ACMA][52] = 127, + [0][1][2][0][RTW89_CHILE][52] = 127, + [0][1][2][0][RTW89_UKRAINE][52] = 127, + [0][1][2][0][RTW89_MEXICO][52] = 127, + [0][1][2][0][RTW89_CN][52] = 127, + [0][1][2][0][RTW89_QATAR][52] = 127, + [0][1][2][0][RTW89_UK][52] = 127, + [0][1][2][1][RTW89_FCC][0] = 68, + [0][1][2][1][RTW89_ETSI][0] = 36, + [0][1][2][1][RTW89_MKK][0] = 50, + [0][1][2][1][RTW89_IC][0] = 40, + [0][1][2][1][RTW89_KCC][0] = 62, + [0][1][2][1][RTW89_ACMA][0] = 36, + [0][1][2][1][RTW89_CHILE][0] = 14, + [0][1][2][1][RTW89_UKRAINE][0] = 28, + [0][1][2][1][RTW89_MEXICO][0] = 50, + [0][1][2][1][RTW89_CN][0] = 34, + [0][1][2][1][RTW89_QATAR][0] = 36, + [0][1][2][1][RTW89_UK][0] = 36, + [0][1][2][1][RTW89_FCC][2] = 68, + [0][1][2][1][RTW89_ETSI][2] = 36, + [0][1][2][1][RTW89_MKK][2] = 50, + [0][1][2][1][RTW89_IC][2] = 40, + [0][1][2][1][RTW89_KCC][2] = 62, + [0][1][2][1][RTW89_ACMA][2] = 36, + [0][1][2][1][RTW89_CHILE][2] = 14, + [0][1][2][1][RTW89_UKRAINE][2] = 28, + [0][1][2][1][RTW89_MEXICO][2] = 50, + [0][1][2][1][RTW89_CN][2] = 34, + [0][1][2][1][RTW89_QATAR][2] = 36, + [0][1][2][1][RTW89_UK][2] = 36, + [0][1][2][1][RTW89_FCC][4] = 68, + [0][1][2][1][RTW89_ETSI][4] = 36, + [0][1][2][1][RTW89_MKK][4] = 50, + [0][1][2][1][RTW89_IC][4] = 40, + [0][1][2][1][RTW89_KCC][4] = 62, + [0][1][2][1][RTW89_ACMA][4] = 36, + [0][1][2][1][RTW89_CHILE][4] = 14, + [0][1][2][1][RTW89_UKRAINE][4] = 28, + [0][1][2][1][RTW89_MEXICO][4] = 50, + [0][1][2][1][RTW89_CN][4] = 34, + [0][1][2][1][RTW89_QATAR][4] = 36, + [0][1][2][1][RTW89_UK][4] = 36, + [0][1][2][1][RTW89_FCC][6] = 68, + [0][1][2][1][RTW89_ETSI][6] = 36, + [0][1][2][1][RTW89_MKK][6] = 50, + [0][1][2][1][RTW89_IC][6] = 40, + [0][1][2][1][RTW89_KCC][6] = 34, + [0][1][2][1][RTW89_ACMA][6] = 36, + [0][1][2][1][RTW89_CHILE][6] = 14, + [0][1][2][1][RTW89_UKRAINE][6] = 28, + [0][1][2][1][RTW89_MEXICO][6] = 50, + [0][1][2][1][RTW89_CN][6] = 34, + [0][1][2][1][RTW89_QATAR][6] = 36, + [0][1][2][1][RTW89_UK][6] = 36, + [0][1][2][1][RTW89_FCC][8] = 68, + [0][1][2][1][RTW89_ETSI][8] = 36, + [0][1][2][1][RTW89_MKK][8] = 50, + [0][1][2][1][RTW89_IC][8] = 40, + [0][1][2][1][RTW89_KCC][8] = 62, + [0][1][2][1][RTW89_ACMA][8] = 36, + [0][1][2][1][RTW89_CHILE][8] = 36, + [0][1][2][1][RTW89_UKRAINE][8] = 28, + [0][1][2][1][RTW89_MEXICO][8] = 68, + [0][1][2][1][RTW89_CN][8] = 36, + [0][1][2][1][RTW89_QATAR][8] = 36, + [0][1][2][1][RTW89_UK][8] = 36, + [0][1][2][1][RTW89_FCC][10] = 68, + [0][1][2][1][RTW89_ETSI][10] = 36, + [0][1][2][1][RTW89_MKK][10] = 50, + [0][1][2][1][RTW89_IC][10] = 40, + [0][1][2][1][RTW89_KCC][10] = 62, + [0][1][2][1][RTW89_ACMA][10] = 36, + [0][1][2][1][RTW89_CHILE][10] = 36, + [0][1][2][1][RTW89_UKRAINE][10] = 28, + [0][1][2][1][RTW89_MEXICO][10] = 68, + [0][1][2][1][RTW89_CN][10] = 36, + [0][1][2][1][RTW89_QATAR][10] = 36, + [0][1][2][1][RTW89_UK][10] = 36, + [0][1][2][1][RTW89_FCC][12] = 68, + [0][1][2][1][RTW89_ETSI][12] = 36, + [0][1][2][1][RTW89_MKK][12] = 50, + [0][1][2][1][RTW89_IC][12] = 40, + [0][1][2][1][RTW89_KCC][12] = 62, + [0][1][2][1][RTW89_ACMA][12] = 36, + [0][1][2][1][RTW89_CHILE][12] = 36, + [0][1][2][1][RTW89_UKRAINE][12] = 28, + [0][1][2][1][RTW89_MEXICO][12] = 68, + [0][1][2][1][RTW89_CN][12] = 36, + [0][1][2][1][RTW89_QATAR][12] = 36, + [0][1][2][1][RTW89_UK][12] = 36, + [0][1][2][1][RTW89_FCC][14] = 68, + [0][1][2][1][RTW89_ETSI][14] = 36, + [0][1][2][1][RTW89_MKK][14] = 50, + [0][1][2][1][RTW89_IC][14] = 40, + [0][1][2][1][RTW89_KCC][14] = 62, + [0][1][2][1][RTW89_ACMA][14] = 36, + [0][1][2][1][RTW89_CHILE][14] = 36, + [0][1][2][1][RTW89_UKRAINE][14] = 28, + [0][1][2][1][RTW89_MEXICO][14] = 68, + [0][1][2][1][RTW89_CN][14] = 36, + [0][1][2][1][RTW89_QATAR][14] = 36, + [0][1][2][1][RTW89_UK][14] = 36, + [0][1][2][1][RTW89_FCC][15] = 68, + [0][1][2][1][RTW89_ETSI][15] = 36, + [0][1][2][1][RTW89_MKK][15] = 70, + [0][1][2][1][RTW89_IC][15] = 68, + [0][1][2][1][RTW89_KCC][15] = 62, + [0][1][2][1][RTW89_ACMA][15] = 36, + [0][1][2][1][RTW89_CHILE][15] = 36, + [0][1][2][1][RTW89_UKRAINE][15] = 28, + [0][1][2][1][RTW89_MEXICO][15] = 68, + [0][1][2][1][RTW89_CN][15] = 127, + [0][1][2][1][RTW89_QATAR][15] = 36, + [0][1][2][1][RTW89_UK][15] = 36, + [0][1][2][1][RTW89_FCC][17] = 68, + [0][1][2][1][RTW89_ETSI][17] = 36, + [0][1][2][1][RTW89_MKK][17] = 70, + [0][1][2][1][RTW89_IC][17] = 68, + [0][1][2][1][RTW89_KCC][17] = 62, + [0][1][2][1][RTW89_ACMA][17] = 36, + [0][1][2][1][RTW89_CHILE][17] = 36, + [0][1][2][1][RTW89_UKRAINE][17] = 28, + [0][1][2][1][RTW89_MEXICO][17] = 68, + [0][1][2][1][RTW89_CN][17] = 127, + [0][1][2][1][RTW89_QATAR][17] = 36, + [0][1][2][1][RTW89_UK][17] = 36, + [0][1][2][1][RTW89_FCC][19] = 68, + [0][1][2][1][RTW89_ETSI][19] = 36, + [0][1][2][1][RTW89_MKK][19] = 70, + [0][1][2][1][RTW89_IC][19] = 68, + [0][1][2][1][RTW89_KCC][19] = 62, + [0][1][2][1][RTW89_ACMA][19] = 36, + [0][1][2][1][RTW89_CHILE][19] = 36, + [0][1][2][1][RTW89_UKRAINE][19] = 28, + [0][1][2][1][RTW89_MEXICO][19] = 68, + [0][1][2][1][RTW89_CN][19] = 127, + [0][1][2][1][RTW89_QATAR][19] = 36, + [0][1][2][1][RTW89_UK][19] = 36, + [0][1][2][1][RTW89_FCC][21] = 68, + [0][1][2][1][RTW89_ETSI][21] = 36, + [0][1][2][1][RTW89_MKK][21] = 70, + [0][1][2][1][RTW89_IC][21] = 68, + [0][1][2][1][RTW89_KCC][21] = 62, + [0][1][2][1][RTW89_ACMA][21] = 36, + [0][1][2][1][RTW89_CHILE][21] = 36, + [0][1][2][1][RTW89_UKRAINE][21] = 28, + [0][1][2][1][RTW89_MEXICO][21] = 68, + [0][1][2][1][RTW89_CN][21] = 127, + [0][1][2][1][RTW89_QATAR][21] = 36, + [0][1][2][1][RTW89_UK][21] = 36, + [0][1][2][1][RTW89_FCC][23] = 68, + [0][1][2][1][RTW89_ETSI][23] = 36, + [0][1][2][1][RTW89_MKK][23] = 70, + [0][1][2][1][RTW89_IC][23] = 68, + [0][1][2][1][RTW89_KCC][23] = 62, + [0][1][2][1][RTW89_ACMA][23] = 36, + [0][1][2][1][RTW89_CHILE][23] = 36, + [0][1][2][1][RTW89_UKRAINE][23] = 28, + [0][1][2][1][RTW89_MEXICO][23] = 68, + [0][1][2][1][RTW89_CN][23] = 127, + [0][1][2][1][RTW89_QATAR][23] = 36, + [0][1][2][1][RTW89_UK][23] = 36, + [0][1][2][1][RTW89_FCC][25] = 66, + [0][1][2][1][RTW89_ETSI][25] = 36, + [0][1][2][1][RTW89_MKK][25] = 70, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_KCC][25] = 62, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_CHILE][25] = 36, + [0][1][2][1][RTW89_UKRAINE][25] = 28, + [0][1][2][1][RTW89_MEXICO][25] = 66, + [0][1][2][1][RTW89_CN][25] = 127, + [0][1][2][1][RTW89_QATAR][25] = 36, + [0][1][2][1][RTW89_UK][25] = 36, + [0][1][2][1][RTW89_FCC][27] = 66, + [0][1][2][1][RTW89_ETSI][27] = 36, + [0][1][2][1][RTW89_MKK][27] = 70, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_KCC][27] = 62, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_CHILE][27] = 36, + [0][1][2][1][RTW89_UKRAINE][27] = 28, + [0][1][2][1][RTW89_MEXICO][27] = 66, + [0][1][2][1][RTW89_CN][27] = 127, + [0][1][2][1][RTW89_QATAR][27] = 36, + [0][1][2][1][RTW89_UK][27] = 36, + [0][1][2][1][RTW89_FCC][29] = 66, + [0][1][2][1][RTW89_ETSI][29] = 36, + [0][1][2][1][RTW89_MKK][29] = 70, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_KCC][29] = 62, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_CHILE][29] = 36, + [0][1][2][1][RTW89_UKRAINE][29] = 28, + [0][1][2][1][RTW89_MEXICO][29] = 66, + [0][1][2][1][RTW89_CN][29] = 127, + [0][1][2][1][RTW89_QATAR][29] = 36, + [0][1][2][1][RTW89_UK][29] = 36, + [0][1][2][1][RTW89_FCC][31] = 66, + [0][1][2][1][RTW89_ETSI][31] = 36, + [0][1][2][1][RTW89_MKK][31] = 70, + [0][1][2][1][RTW89_IC][31] = 66, + [0][1][2][1][RTW89_KCC][31] = 62, + [0][1][2][1][RTW89_ACMA][31] = 36, + [0][1][2][1][RTW89_CHILE][31] = 36, + [0][1][2][1][RTW89_UKRAINE][31] = 28, + [0][1][2][1][RTW89_MEXICO][31] = 66, + [0][1][2][1][RTW89_CN][31] = 127, + [0][1][2][1][RTW89_QATAR][31] = 36, + [0][1][2][1][RTW89_UK][31] = 36, + [0][1][2][1][RTW89_FCC][33] = 66, + [0][1][2][1][RTW89_ETSI][33] = 36, + [0][1][2][1][RTW89_MKK][33] = 70, + [0][1][2][1][RTW89_IC][33] = 66, + [0][1][2][1][RTW89_KCC][33] = 62, + [0][1][2][1][RTW89_ACMA][33] = 36, + [0][1][2][1][RTW89_CHILE][33] = 36, + [0][1][2][1][RTW89_UKRAINE][33] = 28, + [0][1][2][1][RTW89_MEXICO][33] = 66, + [0][1][2][1][RTW89_CN][33] = 127, + [0][1][2][1][RTW89_QATAR][33] = 36, + [0][1][2][1][RTW89_UK][33] = 36, + [0][1][2][1][RTW89_FCC][35] = 66, + [0][1][2][1][RTW89_ETSI][35] = 36, + [0][1][2][1][RTW89_MKK][35] = 70, + [0][1][2][1][RTW89_IC][35] = 66, + [0][1][2][1][RTW89_KCC][35] = 62, + [0][1][2][1][RTW89_ACMA][35] = 36, + [0][1][2][1][RTW89_CHILE][35] = 36, + [0][1][2][1][RTW89_UKRAINE][35] = 28, + [0][1][2][1][RTW89_MEXICO][35] = 66, + [0][1][2][1][RTW89_CN][35] = 127, + [0][1][2][1][RTW89_QATAR][35] = 36, + [0][1][2][1][RTW89_UK][35] = 36, + [0][1][2][1][RTW89_FCC][37] = 68, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 70, + [0][1][2][1][RTW89_IC][37] = 68, + [0][1][2][1][RTW89_KCC][37] = 62, + [0][1][2][1][RTW89_ACMA][37] = 70, + [0][1][2][1][RTW89_CHILE][37] = 36, + [0][1][2][1][RTW89_UKRAINE][37] = 127, + [0][1][2][1][RTW89_MEXICO][37] = 68, + [0][1][2][1][RTW89_CN][37] = 127, + [0][1][2][1][RTW89_QATAR][37] = 127, + [0][1][2][1][RTW89_UK][37] = 62, + [0][1][2][1][RTW89_FCC][38] = 78, + [0][1][2][1][RTW89_ETSI][38] = 4, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 78, + [0][1][2][1][RTW89_KCC][38] = 62, + [0][1][2][1][RTW89_ACMA][38] = 74, + [0][1][2][1][RTW89_CHILE][38] = 36, + [0][1][2][1][RTW89_UKRAINE][38] = 4, + [0][1][2][1][RTW89_MEXICO][38] = 78, + [0][1][2][1][RTW89_CN][38] = 62, + [0][1][2][1][RTW89_QATAR][38] = 4, + [0][1][2][1][RTW89_UK][38] = 36, + [0][1][2][1][RTW89_FCC][40] = 78, + [0][1][2][1][RTW89_ETSI][40] = 4, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 78, + [0][1][2][1][RTW89_KCC][40] = 62, + [0][1][2][1][RTW89_ACMA][40] = 74, + [0][1][2][1][RTW89_CHILE][40] = 36, + [0][1][2][1][RTW89_UKRAINE][40] = 4, + [0][1][2][1][RTW89_MEXICO][40] = 78, + [0][1][2][1][RTW89_CN][40] = 62, + [0][1][2][1][RTW89_QATAR][40] = 4, + [0][1][2][1][RTW89_UK][40] = 36, + [0][1][2][1][RTW89_FCC][42] = 78, + [0][1][2][1][RTW89_ETSI][42] = 4, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 78, + [0][1][2][1][RTW89_KCC][42] = 62, + [0][1][2][1][RTW89_ACMA][42] = 76, + [0][1][2][1][RTW89_CHILE][42] = 36, + [0][1][2][1][RTW89_UKRAINE][42] = 4, + [0][1][2][1][RTW89_MEXICO][42] = 78, + [0][1][2][1][RTW89_CN][42] = 62, + [0][1][2][1][RTW89_QATAR][42] = 4, + [0][1][2][1][RTW89_UK][42] = 36, + [0][1][2][1][RTW89_FCC][44] = 78, + [0][1][2][1][RTW89_ETSI][44] = 4, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 78, + [0][1][2][1][RTW89_KCC][44] = 62, + [0][1][2][1][RTW89_ACMA][44] = 76, + [0][1][2][1][RTW89_CHILE][44] = 36, + [0][1][2][1][RTW89_UKRAINE][44] = 4, + [0][1][2][1][RTW89_MEXICO][44] = 78, + [0][1][2][1][RTW89_CN][44] = 62, + [0][1][2][1][RTW89_QATAR][44] = 4, + [0][1][2][1][RTW89_UK][44] = 36, + [0][1][2][1][RTW89_FCC][46] = 78, + [0][1][2][1][RTW89_ETSI][46] = 4, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 78, + [0][1][2][1][RTW89_KCC][46] = 62, + [0][1][2][1][RTW89_ACMA][46] = 76, + [0][1][2][1][RTW89_CHILE][46] = 36, + [0][1][2][1][RTW89_UKRAINE][46] = 4, + [0][1][2][1][RTW89_MEXICO][46] = 78, + [0][1][2][1][RTW89_CN][46] = 62, + [0][1][2][1][RTW89_QATAR][46] = 4, + [0][1][2][1][RTW89_UK][46] = 36, + [0][1][2][1][RTW89_FCC][48] = 58, + [0][1][2][1][RTW89_ETSI][48] = 127, + [0][1][2][1][RTW89_MKK][48] = 127, + [0][1][2][1][RTW89_IC][48] = 50, + [0][1][2][1][RTW89_KCC][48] = 127, + [0][1][2][1][RTW89_ACMA][48] = 127, + [0][1][2][1][RTW89_CHILE][48] = 127, + [0][1][2][1][RTW89_UKRAINE][48] = 127, + [0][1][2][1][RTW89_MEXICO][48] = 127, + [0][1][2][1][RTW89_CN][48] = 127, + [0][1][2][1][RTW89_QATAR][48] = 127, + [0][1][2][1][RTW89_UK][48] = 127, + [0][1][2][1][RTW89_FCC][50] = 58, + [0][1][2][1][RTW89_ETSI][50] = 127, + [0][1][2][1][RTW89_MKK][50] = 127, + [0][1][2][1][RTW89_IC][50] = 52, + [0][1][2][1][RTW89_KCC][50] = 127, + [0][1][2][1][RTW89_ACMA][50] = 127, + [0][1][2][1][RTW89_CHILE][50] = 127, + [0][1][2][1][RTW89_UKRAINE][50] = 127, + [0][1][2][1][RTW89_MEXICO][50] = 127, + [0][1][2][1][RTW89_CN][50] = 127, + [0][1][2][1][RTW89_QATAR][50] = 127, + [0][1][2][1][RTW89_UK][50] = 127, + [0][1][2][1][RTW89_FCC][52] = 58, + [0][1][2][1][RTW89_ETSI][52] = 127, + [0][1][2][1][RTW89_MKK][52] = 127, + [0][1][2][1][RTW89_IC][52] = 52, + [0][1][2][1][RTW89_KCC][52] = 127, + [0][1][2][1][RTW89_ACMA][52] = 127, + [0][1][2][1][RTW89_CHILE][52] = 127, + [0][1][2][1][RTW89_UKRAINE][52] = 127, + [0][1][2][1][RTW89_MEXICO][52] = 127, + [0][1][2][1][RTW89_CN][52] = 127, + [0][1][2][1][RTW89_QATAR][52] = 127, + [0][1][2][1][RTW89_UK][52] = 127, + [1][0][2][0][RTW89_FCC][1] = 66, + [1][0][2][0][RTW89_ETSI][1] = 64, + [1][0][2][0][RTW89_MKK][1] = 62, + [1][0][2][0][RTW89_IC][1] = 64, + [1][0][2][0][RTW89_KCC][1] = 70, + [1][0][2][0][RTW89_ACMA][1] = 64, + [1][0][2][0][RTW89_CHILE][1] = 42, + [1][0][2][0][RTW89_UKRAINE][1] = 52, + [1][0][2][0][RTW89_MEXICO][1] = 62, + [1][0][2][0][RTW89_CN][1] = 62, + [1][0][2][0][RTW89_QATAR][1] = 64, + [1][0][2][0][RTW89_UK][1] = 64, + [1][0][2][0][RTW89_FCC][5] = 78, + [1][0][2][0][RTW89_ETSI][5] = 64, + [1][0][2][0][RTW89_MKK][5] = 62, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 66, + [1][0][2][0][RTW89_ACMA][5] = 64, + [1][0][2][0][RTW89_CHILE][5] = 42, + [1][0][2][0][RTW89_UKRAINE][5] = 52, + [1][0][2][0][RTW89_MEXICO][5] = 62, + [1][0][2][0][RTW89_CN][5] = 62, + [1][0][2][0][RTW89_QATAR][5] = 64, + [1][0][2][0][RTW89_UK][5] = 64, + [1][0][2][0][RTW89_FCC][9] = 78, + [1][0][2][0][RTW89_ETSI][9] = 64, + [1][0][2][0][RTW89_MKK][9] = 62, + [1][0][2][0][RTW89_IC][9] = 64, + [1][0][2][0][RTW89_KCC][9] = 74, + [1][0][2][0][RTW89_ACMA][9] = 64, + [1][0][2][0][RTW89_CHILE][9] = 66, + [1][0][2][0][RTW89_UKRAINE][9] = 52, + [1][0][2][0][RTW89_MEXICO][9] = 78, + [1][0][2][0][RTW89_CN][9] = 62, + [1][0][2][0][RTW89_QATAR][9] = 64, + [1][0][2][0][RTW89_UK][9] = 64, + [1][0][2][0][RTW89_FCC][13] = 66, + [1][0][2][0][RTW89_ETSI][13] = 64, + [1][0][2][0][RTW89_MKK][13] = 62, + [1][0][2][0][RTW89_IC][13] = 64, + [1][0][2][0][RTW89_KCC][13] = 68, + [1][0][2][0][RTW89_ACMA][13] = 64, + [1][0][2][0][RTW89_CHILE][13] = 66, + [1][0][2][0][RTW89_UKRAINE][13] = 52, + [1][0][2][0][RTW89_MEXICO][13] = 66, + [1][0][2][0][RTW89_CN][13] = 62, + [1][0][2][0][RTW89_QATAR][13] = 64, + [1][0][2][0][RTW89_UK][13] = 64, + [1][0][2][0][RTW89_FCC][16] = 64, + [1][0][2][0][RTW89_ETSI][16] = 64, + [1][0][2][0][RTW89_MKK][16] = 74, + [1][0][2][0][RTW89_IC][16] = 64, + [1][0][2][0][RTW89_KCC][16] = 70, + [1][0][2][0][RTW89_ACMA][16] = 64, + [1][0][2][0][RTW89_CHILE][16] = 64, + [1][0][2][0][RTW89_UKRAINE][16] = 52, + [1][0][2][0][RTW89_MEXICO][16] = 64, + [1][0][2][0][RTW89_CN][16] = 127, + [1][0][2][0][RTW89_QATAR][16] = 64, + [1][0][2][0][RTW89_UK][16] = 64, + [1][0][2][0][RTW89_FCC][20] = 78, + [1][0][2][0][RTW89_ETSI][20] = 64, + [1][0][2][0][RTW89_MKK][20] = 74, + [1][0][2][0][RTW89_IC][20] = 78, + [1][0][2][0][RTW89_KCC][20] = 70, + [1][0][2][0][RTW89_ACMA][20] = 64, + [1][0][2][0][RTW89_CHILE][20] = 62, + [1][0][2][0][RTW89_UKRAINE][20] = 52, + [1][0][2][0][RTW89_MEXICO][20] = 78, + [1][0][2][0][RTW89_CN][20] = 127, + [1][0][2][0][RTW89_QATAR][20] = 64, + [1][0][2][0][RTW89_UK][20] = 64, + [1][0][2][0][RTW89_FCC][24] = 78, + [1][0][2][0][RTW89_ETSI][24] = 64, + [1][0][2][0][RTW89_MKK][24] = 74, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_KCC][24] = 70, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_CHILE][24] = 62, + [1][0][2][0][RTW89_UKRAINE][24] = 52, + [1][0][2][0][RTW89_MEXICO][24] = 78, + [1][0][2][0][RTW89_CN][24] = 127, + [1][0][2][0][RTW89_QATAR][24] = 64, + [1][0][2][0][RTW89_UK][24] = 64, + [1][0][2][0][RTW89_FCC][28] = 78, + [1][0][2][0][RTW89_ETSI][28] = 64, + [1][0][2][0][RTW89_MKK][28] = 74, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_KCC][28] = 74, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_CHILE][28] = 64, + [1][0][2][0][RTW89_UKRAINE][28] = 52, + [1][0][2][0][RTW89_MEXICO][28] = 78, + [1][0][2][0][RTW89_CN][28] = 127, + [1][0][2][0][RTW89_QATAR][28] = 64, + [1][0][2][0][RTW89_UK][28] = 64, + [1][0][2][0][RTW89_FCC][32] = 76, + [1][0][2][0][RTW89_ETSI][32] = 64, + [1][0][2][0][RTW89_MKK][32] = 74, + [1][0][2][0][RTW89_IC][32] = 76, + [1][0][2][0][RTW89_KCC][32] = 74, + [1][0][2][0][RTW89_ACMA][32] = 64, + [1][0][2][0][RTW89_CHILE][32] = 64, + [1][0][2][0][RTW89_UKRAINE][32] = 52, + [1][0][2][0][RTW89_MEXICO][32] = 76, + [1][0][2][0][RTW89_CN][32] = 127, + [1][0][2][0][RTW89_QATAR][32] = 64, + [1][0][2][0][RTW89_UK][32] = 64, + [1][0][2][0][RTW89_FCC][36] = 78, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 74, + [1][0][2][0][RTW89_IC][36] = 78, + [1][0][2][0][RTW89_KCC][36] = 74, + [1][0][2][0][RTW89_ACMA][36] = 74, + [1][0][2][0][RTW89_CHILE][36] = 64, + [1][0][2][0][RTW89_UKRAINE][36] = 127, + [1][0][2][0][RTW89_MEXICO][36] = 78, + [1][0][2][0][RTW89_CN][36] = 127, + [1][0][2][0][RTW89_QATAR][36] = 127, + [1][0][2][0][RTW89_UK][36] = 74, + [1][0][2][0][RTW89_FCC][39] = 78, + [1][0][2][0][RTW89_ETSI][39] = 28, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 78, + [1][0][2][0][RTW89_KCC][39] = 74, + [1][0][2][0][RTW89_ACMA][39] = 74, + [1][0][2][0][RTW89_CHILE][39] = 64, + [1][0][2][0][RTW89_UKRAINE][39] = 28, + [1][0][2][0][RTW89_MEXICO][39] = 78, + [1][0][2][0][RTW89_CN][39] = 56, + [1][0][2][0][RTW89_QATAR][39] = 28, + [1][0][2][0][RTW89_UK][39] = 64, + [1][0][2][0][RTW89_FCC][43] = 78, + [1][0][2][0][RTW89_ETSI][43] = 28, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 78, + [1][0][2][0][RTW89_KCC][43] = 74, + [1][0][2][0][RTW89_ACMA][43] = 74, + [1][0][2][0][RTW89_CHILE][43] = 64, + [1][0][2][0][RTW89_UKRAINE][43] = 28, + [1][0][2][0][RTW89_MEXICO][43] = 78, + [1][0][2][0][RTW89_CN][43] = 62, + [1][0][2][0][RTW89_QATAR][43] = 28, + [1][0][2][0][RTW89_UK][43] = 62, + [1][0][2][0][RTW89_FCC][47] = 78, + [1][0][2][0][RTW89_ETSI][47] = 127, + [1][0][2][0][RTW89_MKK][47] = 127, + [1][0][2][0][RTW89_IC][47] = 78, + [1][0][2][0][RTW89_KCC][47] = 127, + [1][0][2][0][RTW89_ACMA][47] = 127, + [1][0][2][0][RTW89_CHILE][47] = 127, + [1][0][2][0][RTW89_UKRAINE][47] = 127, + [1][0][2][0][RTW89_MEXICO][47] = 127, + [1][0][2][0][RTW89_CN][47] = 127, + [1][0][2][0][RTW89_QATAR][47] = 127, + [1][0][2][0][RTW89_UK][47] = 127, + [1][0][2][0][RTW89_FCC][51] = 70, + [1][0][2][0][RTW89_ETSI][51] = 127, + [1][0][2][0][RTW89_MKK][51] = 127, + [1][0][2][0][RTW89_IC][51] = 78, + [1][0][2][0][RTW89_KCC][51] = 127, + [1][0][2][0][RTW89_ACMA][51] = 127, + [1][0][2][0][RTW89_CHILE][51] = 127, + [1][0][2][0][RTW89_UKRAINE][51] = 127, + [1][0][2][0][RTW89_MEXICO][51] = 127, + [1][0][2][0][RTW89_CN][51] = 127, + [1][0][2][0][RTW89_QATAR][51] = 127, + [1][0][2][0][RTW89_UK][51] = 127, + [1][1][2][0][RTW89_FCC][1] = 62, + [1][1][2][0][RTW89_ETSI][1] = 52, + [1][1][2][0][RTW89_MKK][1] = 50, + [1][1][2][0][RTW89_IC][1] = 52, + [1][1][2][0][RTW89_KCC][1] = 58, + [1][1][2][0][RTW89_ACMA][1] = 52, + [1][1][2][0][RTW89_CHILE][1] = 30, + [1][1][2][0][RTW89_UKRAINE][1] = 40, + [1][1][2][0][RTW89_MEXICO][1] = 50, + [1][1][2][0][RTW89_CN][1] = 50, + [1][1][2][0][RTW89_QATAR][1] = 52, + [1][1][2][0][RTW89_UK][1] = 52, + [1][1][2][0][RTW89_FCC][5] = 76, + [1][1][2][0][RTW89_ETSI][5] = 52, + [1][1][2][0][RTW89_MKK][5] = 50, + [1][1][2][0][RTW89_IC][5] = 52, + [1][1][2][0][RTW89_KCC][5] = 48, + [1][1][2][0][RTW89_ACMA][5] = 52, + [1][1][2][0][RTW89_CHILE][5] = 30, + [1][1][2][0][RTW89_UKRAINE][5] = 40, + [1][1][2][0][RTW89_MEXICO][5] = 50, + [1][1][2][0][RTW89_CN][5] = 50, + [1][1][2][0][RTW89_QATAR][5] = 52, + [1][1][2][0][RTW89_UK][5] = 52, + [1][1][2][0][RTW89_FCC][9] = 76, + [1][1][2][0][RTW89_ETSI][9] = 52, + [1][1][2][0][RTW89_MKK][9] = 50, + [1][1][2][0][RTW89_IC][9] = 52, + [1][1][2][0][RTW89_KCC][9] = 60, + [1][1][2][0][RTW89_ACMA][9] = 52, + [1][1][2][0][RTW89_CHILE][9] = 50, + [1][1][2][0][RTW89_UKRAINE][9] = 40, + [1][1][2][0][RTW89_MEXICO][9] = 76, + [1][1][2][0][RTW89_CN][9] = 50, + [1][1][2][0][RTW89_QATAR][9] = 52, + [1][1][2][0][RTW89_UK][9] = 52, + [1][1][2][0][RTW89_FCC][13] = 62, + [1][1][2][0][RTW89_ETSI][13] = 52, + [1][1][2][0][RTW89_MKK][13] = 50, + [1][1][2][0][RTW89_IC][13] = 52, + [1][1][2][0][RTW89_KCC][13] = 58, + [1][1][2][0][RTW89_ACMA][13] = 52, + [1][1][2][0][RTW89_CHILE][13] = 48, + [1][1][2][0][RTW89_UKRAINE][13] = 40, + [1][1][2][0][RTW89_MEXICO][13] = 62, + [1][1][2][0][RTW89_CN][13] = 50, + [1][1][2][0][RTW89_QATAR][13] = 52, + [1][1][2][0][RTW89_UK][13] = 52, + [1][1][2][0][RTW89_FCC][16] = 56, + [1][1][2][0][RTW89_ETSI][16] = 52, + [1][1][2][0][RTW89_MKK][16] = 70, + [1][1][2][0][RTW89_IC][16] = 56, + [1][1][2][0][RTW89_KCC][16] = 58, + [1][1][2][0][RTW89_ACMA][16] = 52, + [1][1][2][0][RTW89_CHILE][16] = 48, + [1][1][2][0][RTW89_UKRAINE][16] = 40, + [1][1][2][0][RTW89_MEXICO][16] = 56, + [1][1][2][0][RTW89_CN][16] = 127, + [1][1][2][0][RTW89_QATAR][16] = 52, + [1][1][2][0][RTW89_UK][16] = 52, + [1][1][2][0][RTW89_FCC][20] = 76, + [1][1][2][0][RTW89_ETSI][20] = 52, + [1][1][2][0][RTW89_MKK][20] = 70, + [1][1][2][0][RTW89_IC][20] = 76, + [1][1][2][0][RTW89_KCC][20] = 58, + [1][1][2][0][RTW89_ACMA][20] = 52, + [1][1][2][0][RTW89_CHILE][20] = 50, + [1][1][2][0][RTW89_UKRAINE][20] = 40, + [1][1][2][0][RTW89_MEXICO][20] = 76, + [1][1][2][0][RTW89_CN][20] = 127, + [1][1][2][0][RTW89_QATAR][20] = 52, + [1][1][2][0][RTW89_UK][20] = 52, + [1][1][2][0][RTW89_FCC][24] = 76, + [1][1][2][0][RTW89_ETSI][24] = 52, + [1][1][2][0][RTW89_MKK][24] = 70, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_KCC][24] = 58, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_CHILE][24] = 50, + [1][1][2][0][RTW89_UKRAINE][24] = 40, + [1][1][2][0][RTW89_MEXICO][24] = 76, + [1][1][2][0][RTW89_CN][24] = 127, + [1][1][2][0][RTW89_QATAR][24] = 52, + [1][1][2][0][RTW89_UK][24] = 52, + [1][1][2][0][RTW89_FCC][28] = 76, + [1][1][2][0][RTW89_ETSI][28] = 52, + [1][1][2][0][RTW89_MKK][28] = 70, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_KCC][28] = 60, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_CHILE][28] = 48, + [1][1][2][0][RTW89_UKRAINE][28] = 40, + [1][1][2][0][RTW89_MEXICO][28] = 76, + [1][1][2][0][RTW89_CN][28] = 127, + [1][1][2][0][RTW89_QATAR][28] = 52, + [1][1][2][0][RTW89_UK][28] = 52, + [1][1][2][0][RTW89_FCC][32] = 68, + [1][1][2][0][RTW89_ETSI][32] = 52, + [1][1][2][0][RTW89_MKK][32] = 70, + [1][1][2][0][RTW89_IC][32] = 68, + [1][1][2][0][RTW89_KCC][32] = 60, + [1][1][2][0][RTW89_ACMA][32] = 52, + [1][1][2][0][RTW89_CHILE][32] = 48, + [1][1][2][0][RTW89_UKRAINE][32] = 40, + [1][1][2][0][RTW89_MEXICO][32] = 68, + [1][1][2][0][RTW89_CN][32] = 127, + [1][1][2][0][RTW89_QATAR][32] = 52, + [1][1][2][0][RTW89_UK][32] = 52, + [1][1][2][0][RTW89_FCC][36] = 76, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 70, + [1][1][2][0][RTW89_IC][36] = 76, + [1][1][2][0][RTW89_KCC][36] = 60, + [1][1][2][0][RTW89_ACMA][36] = 74, + [1][1][2][0][RTW89_CHILE][36] = 50, + [1][1][2][0][RTW89_UKRAINE][36] = 127, + [1][1][2][0][RTW89_MEXICO][36] = 76, + [1][1][2][0][RTW89_CN][36] = 127, + [1][1][2][0][RTW89_QATAR][36] = 127, + [1][1][2][0][RTW89_UK][36] = 74, + [1][1][2][0][RTW89_FCC][39] = 78, + [1][1][2][0][RTW89_ETSI][39] = 16, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 78, + [1][1][2][0][RTW89_KCC][39] = 58, + [1][1][2][0][RTW89_ACMA][39] = 72, + [1][1][2][0][RTW89_CHILE][39] = 52, + [1][1][2][0][RTW89_UKRAINE][39] = 16, + [1][1][2][0][RTW89_MEXICO][39] = 78, + [1][1][2][0][RTW89_CN][39] = 56, + [1][1][2][0][RTW89_QATAR][39] = 16, + [1][1][2][0][RTW89_UK][39] = 52, + [1][1][2][0][RTW89_FCC][43] = 78, + [1][1][2][0][RTW89_ETSI][43] = 16, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 78, + [1][1][2][0][RTW89_KCC][43] = 58, + [1][1][2][0][RTW89_ACMA][43] = 74, + [1][1][2][0][RTW89_CHILE][43] = 52, + [1][1][2][0][RTW89_UKRAINE][43] = 16, + [1][1][2][0][RTW89_MEXICO][43] = 78, + [1][1][2][0][RTW89_CN][43] = 62, + [1][1][2][0][RTW89_QATAR][43] = 16, + [1][1][2][0][RTW89_UK][43] = 52, + [1][1][2][0][RTW89_FCC][47] = 68, + [1][1][2][0][RTW89_ETSI][47] = 127, + [1][1][2][0][RTW89_MKK][47] = 127, + [1][1][2][0][RTW89_IC][47] = 62, + [1][1][2][0][RTW89_KCC][47] = 127, + [1][1][2][0][RTW89_ACMA][47] = 127, + [1][1][2][0][RTW89_CHILE][47] = 127, + [1][1][2][0][RTW89_UKRAINE][47] = 127, + [1][1][2][0][RTW89_MEXICO][47] = 127, + [1][1][2][0][RTW89_CN][47] = 127, + [1][1][2][0][RTW89_QATAR][47] = 127, + [1][1][2][0][RTW89_UK][47] = 127, + [1][1][2][0][RTW89_FCC][51] = 66, + [1][1][2][0][RTW89_ETSI][51] = 127, + [1][1][2][0][RTW89_MKK][51] = 127, + [1][1][2][0][RTW89_IC][51] = 62, + [1][1][2][0][RTW89_KCC][51] = 127, + [1][1][2][0][RTW89_ACMA][51] = 127, + [1][1][2][0][RTW89_CHILE][51] = 127, + [1][1][2][0][RTW89_UKRAINE][51] = 127, + [1][1][2][0][RTW89_MEXICO][51] = 127, + [1][1][2][0][RTW89_CN][51] = 127, + [1][1][2][0][RTW89_QATAR][51] = 127, + [1][1][2][0][RTW89_UK][51] = 127, + [1][1][2][1][RTW89_FCC][1] = 62, + [1][1][2][1][RTW89_ETSI][1] = 40, + [1][1][2][1][RTW89_MKK][1] = 50, + [1][1][2][1][RTW89_IC][1] = 40, + [1][1][2][1][RTW89_KCC][1] = 58, + [1][1][2][1][RTW89_ACMA][1] = 40, + [1][1][2][1][RTW89_CHILE][1] = 16, + [1][1][2][1][RTW89_UKRAINE][1] = 28, + [1][1][2][1][RTW89_MEXICO][1] = 50, + [1][1][2][1][RTW89_CN][1] = 38, + [1][1][2][1][RTW89_QATAR][1] = 40, + [1][1][2][1][RTW89_UK][1] = 40, + [1][1][2][1][RTW89_FCC][5] = 68, + [1][1][2][1][RTW89_ETSI][5] = 40, + [1][1][2][1][RTW89_MKK][5] = 50, + [1][1][2][1][RTW89_IC][5] = 40, + [1][1][2][1][RTW89_KCC][5] = 48, + [1][1][2][1][RTW89_ACMA][5] = 40, + [1][1][2][1][RTW89_CHILE][5] = 16, + [1][1][2][1][RTW89_UKRAINE][5] = 28, + [1][1][2][1][RTW89_MEXICO][5] = 50, + [1][1][2][1][RTW89_CN][5] = 38, + [1][1][2][1][RTW89_QATAR][5] = 40, + [1][1][2][1][RTW89_UK][5] = 40, + [1][1][2][1][RTW89_FCC][9] = 68, + [1][1][2][1][RTW89_ETSI][9] = 40, + [1][1][2][1][RTW89_MKK][9] = 50, + [1][1][2][1][RTW89_IC][9] = 40, + [1][1][2][1][RTW89_KCC][9] = 60, + [1][1][2][1][RTW89_ACMA][9] = 40, + [1][1][2][1][RTW89_CHILE][9] = 36, + [1][1][2][1][RTW89_UKRAINE][9] = 28, + [1][1][2][1][RTW89_MEXICO][9] = 68, + [1][1][2][1][RTW89_CN][9] = 38, + [1][1][2][1][RTW89_QATAR][9] = 40, + [1][1][2][1][RTW89_UK][9] = 40, + [1][1][2][1][RTW89_FCC][13] = 62, + [1][1][2][1][RTW89_ETSI][13] = 40, + [1][1][2][1][RTW89_MKK][13] = 50, + [1][1][2][1][RTW89_IC][13] = 40, + [1][1][2][1][RTW89_KCC][13] = 58, + [1][1][2][1][RTW89_ACMA][13] = 40, + [1][1][2][1][RTW89_CHILE][13] = 36, + [1][1][2][1][RTW89_UKRAINE][13] = 28, + [1][1][2][1][RTW89_MEXICO][13] = 62, + [1][1][2][1][RTW89_CN][13] = 38, + [1][1][2][1][RTW89_QATAR][13] = 40, + [1][1][2][1][RTW89_UK][13] = 40, + [1][1][2][1][RTW89_FCC][16] = 56, + [1][1][2][1][RTW89_ETSI][16] = 40, + [1][1][2][1][RTW89_MKK][16] = 70, + [1][1][2][1][RTW89_IC][16] = 56, + [1][1][2][1][RTW89_KCC][16] = 58, + [1][1][2][1][RTW89_ACMA][16] = 40, + [1][1][2][1][RTW89_CHILE][16] = 36, + [1][1][2][1][RTW89_UKRAINE][16] = 28, + [1][1][2][1][RTW89_MEXICO][16] = 56, + [1][1][2][1][RTW89_CN][16] = 127, + [1][1][2][1][RTW89_QATAR][16] = 40, + [1][1][2][1][RTW89_UK][16] = 40, + [1][1][2][1][RTW89_FCC][20] = 68, + [1][1][2][1][RTW89_ETSI][20] = 40, + [1][1][2][1][RTW89_MKK][20] = 70, + [1][1][2][1][RTW89_IC][20] = 68, + [1][1][2][1][RTW89_KCC][20] = 58, + [1][1][2][1][RTW89_ACMA][20] = 40, + [1][1][2][1][RTW89_CHILE][20] = 36, + [1][1][2][1][RTW89_UKRAINE][20] = 28, + [1][1][2][1][RTW89_MEXICO][20] = 68, + [1][1][2][1][RTW89_CN][20] = 127, + [1][1][2][1][RTW89_QATAR][20] = 40, + [1][1][2][1][RTW89_UK][20] = 40, + [1][1][2][1][RTW89_FCC][24] = 68, + [1][1][2][1][RTW89_ETSI][24] = 40, + [1][1][2][1][RTW89_MKK][24] = 70, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_KCC][24] = 58, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_CHILE][24] = 36, + [1][1][2][1][RTW89_UKRAINE][24] = 28, + [1][1][2][1][RTW89_MEXICO][24] = 68, + [1][1][2][1][RTW89_CN][24] = 127, + [1][1][2][1][RTW89_QATAR][24] = 40, + [1][1][2][1][RTW89_UK][24] = 40, + [1][1][2][1][RTW89_FCC][28] = 68, + [1][1][2][1][RTW89_ETSI][28] = 40, + [1][1][2][1][RTW89_MKK][28] = 70, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_KCC][28] = 60, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_CHILE][28] = 36, + [1][1][2][1][RTW89_UKRAINE][28] = 28, + [1][1][2][1][RTW89_MEXICO][28] = 68, + [1][1][2][1][RTW89_CN][28] = 127, + [1][1][2][1][RTW89_QATAR][28] = 40, + [1][1][2][1][RTW89_UK][28] = 40, + [1][1][2][1][RTW89_FCC][32] = 68, + [1][1][2][1][RTW89_ETSI][32] = 40, + [1][1][2][1][RTW89_MKK][32] = 70, + [1][1][2][1][RTW89_IC][32] = 68, + [1][1][2][1][RTW89_KCC][32] = 60, + [1][1][2][1][RTW89_ACMA][32] = 40, + [1][1][2][1][RTW89_CHILE][32] = 36, + [1][1][2][1][RTW89_UKRAINE][32] = 28, + [1][1][2][1][RTW89_MEXICO][32] = 68, + [1][1][2][1][RTW89_CN][32] = 127, + [1][1][2][1][RTW89_QATAR][32] = 40, + [1][1][2][1][RTW89_UK][32] = 40, + [1][1][2][1][RTW89_FCC][36] = 68, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 70, + [1][1][2][1][RTW89_IC][36] = 68, + [1][1][2][1][RTW89_KCC][36] = 60, + [1][1][2][1][RTW89_ACMA][36] = 70, + [1][1][2][1][RTW89_CHILE][36] = 36, + [1][1][2][1][RTW89_UKRAINE][36] = 127, + [1][1][2][1][RTW89_MEXICO][36] = 68, + [1][1][2][1][RTW89_CN][36] = 127, + [1][1][2][1][RTW89_QATAR][36] = 127, + [1][1][2][1][RTW89_UK][36] = 62, + [1][1][2][1][RTW89_FCC][39] = 78, + [1][1][2][1][RTW89_ETSI][39] = 4, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 78, + [1][1][2][1][RTW89_KCC][39] = 58, + [1][1][2][1][RTW89_ACMA][39] = 72, + [1][1][2][1][RTW89_CHILE][39] = 36, + [1][1][2][1][RTW89_UKRAINE][39] = 4, + [1][1][2][1][RTW89_MEXICO][39] = 78, + [1][1][2][1][RTW89_CN][39] = 58, + [1][1][2][1][RTW89_QATAR][39] = 4, + [1][1][2][1][RTW89_UK][39] = 40, + [1][1][2][1][RTW89_FCC][43] = 78, + [1][1][2][1][RTW89_ETSI][43] = 4, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 78, + [1][1][2][1][RTW89_KCC][43] = 58, + [1][1][2][1][RTW89_ACMA][43] = 74, + [1][1][2][1][RTW89_CHILE][43] = 36, + [1][1][2][1][RTW89_UKRAINE][43] = 4, + [1][1][2][1][RTW89_MEXICO][43] = 78, + [1][1][2][1][RTW89_CN][43] = 62, + [1][1][2][1][RTW89_QATAR][43] = 4, + [1][1][2][1][RTW89_UK][43] = 40, + [1][1][2][1][RTW89_FCC][47] = 68, + [1][1][2][1][RTW89_ETSI][47] = 127, + [1][1][2][1][RTW89_MKK][47] = 127, + [1][1][2][1][RTW89_IC][47] = 62, + [1][1][2][1][RTW89_KCC][47] = 127, + [1][1][2][1][RTW89_ACMA][47] = 127, + [1][1][2][1][RTW89_CHILE][47] = 127, + [1][1][2][1][RTW89_UKRAINE][47] = 127, + [1][1][2][1][RTW89_MEXICO][47] = 127, + [1][1][2][1][RTW89_CN][47] = 127, + [1][1][2][1][RTW89_QATAR][47] = 127, + [1][1][2][1][RTW89_UK][47] = 127, + [1][1][2][1][RTW89_FCC][51] = 66, + [1][1][2][1][RTW89_ETSI][51] = 127, + [1][1][2][1][RTW89_MKK][51] = 127, + [1][1][2][1][RTW89_IC][51] = 62, + [1][1][2][1][RTW89_KCC][51] = 127, + [1][1][2][1][RTW89_ACMA][51] = 127, + [1][1][2][1][RTW89_CHILE][51] = 127, + [1][1][2][1][RTW89_UKRAINE][51] = 127, + [1][1][2][1][RTW89_MEXICO][51] = 127, + [1][1][2][1][RTW89_CN][51] = 127, + [1][1][2][1][RTW89_QATAR][51] = 127, + [1][1][2][1][RTW89_UK][51] = 127, + [2][0][2][0][RTW89_FCC][3] = 64, + [2][0][2][0][RTW89_ETSI][3] = 64, + [2][0][2][0][RTW89_MKK][3] = 64, + [2][0][2][0][RTW89_IC][3] = 62, + [2][0][2][0][RTW89_KCC][3] = 68, + [2][0][2][0][RTW89_ACMA][3] = 64, + [2][0][2][0][RTW89_CHILE][3] = 42, + [2][0][2][0][RTW89_UKRAINE][3] = 52, + [2][0][2][0][RTW89_MEXICO][3] = 62, + [2][0][2][0][RTW89_CN][3] = 62, + [2][0][2][0][RTW89_QATAR][3] = 64, + [2][0][2][0][RTW89_UK][3] = 64, + [2][0][2][0][RTW89_FCC][11] = 66, + [2][0][2][0][RTW89_ETSI][11] = 64, + [2][0][2][0][RTW89_MKK][11] = 64, + [2][0][2][0][RTW89_IC][11] = 64, + [2][0][2][0][RTW89_KCC][11] = 70, + [2][0][2][0][RTW89_ACMA][11] = 64, + [2][0][2][0][RTW89_CHILE][11] = 66, + [2][0][2][0][RTW89_UKRAINE][11] = 52, + [2][0][2][0][RTW89_MEXICO][11] = 66, + [2][0][2][0][RTW89_CN][11] = 62, + [2][0][2][0][RTW89_QATAR][11] = 64, + [2][0][2][0][RTW89_UK][11] = 64, + [2][0][2][0][RTW89_FCC][18] = 62, + [2][0][2][0][RTW89_ETSI][18] = 64, + [2][0][2][0][RTW89_MKK][18] = 70, + [2][0][2][0][RTW89_IC][18] = 62, + [2][0][2][0][RTW89_KCC][18] = 64, + [2][0][2][0][RTW89_ACMA][18] = 64, + [2][0][2][0][RTW89_CHILE][18] = 64, + [2][0][2][0][RTW89_UKRAINE][18] = 52, + [2][0][2][0][RTW89_MEXICO][18] = 62, + [2][0][2][0][RTW89_CN][18] = 127, + [2][0][2][0][RTW89_QATAR][18] = 64, + [2][0][2][0][RTW89_UK][18] = 64, + [2][0][2][0][RTW89_FCC][26] = 74, + [2][0][2][0][RTW89_ETSI][26] = 64, + [2][0][2][0][RTW89_MKK][26] = 70, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_KCC][26] = 70, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_CHILE][26] = 64, + [2][0][2][0][RTW89_UKRAINE][26] = 52, + [2][0][2][0][RTW89_MEXICO][26] = 74, + [2][0][2][0][RTW89_CN][26] = 127, + [2][0][2][0][RTW89_QATAR][26] = 64, + [2][0][2][0][RTW89_UK][26] = 64, + [2][0][2][0][RTW89_FCC][34] = 74, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 70, + [2][0][2][0][RTW89_IC][34] = 74, + [2][0][2][0][RTW89_KCC][34] = 70, + [2][0][2][0][RTW89_ACMA][34] = 70, + [2][0][2][0][RTW89_CHILE][34] = 64, + [2][0][2][0][RTW89_UKRAINE][34] = 127, + [2][0][2][0][RTW89_MEXICO][34] = 74, + [2][0][2][0][RTW89_CN][34] = 127, + [2][0][2][0][RTW89_QATAR][34] = 127, + [2][0][2][0][RTW89_UK][34] = 70, + [2][0][2][0][RTW89_FCC][41] = 74, + [2][0][2][0][RTW89_ETSI][41] = 28, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 74, + [2][0][2][0][RTW89_KCC][41] = 66, + [2][0][2][0][RTW89_ACMA][41] = 70, + [2][0][2][0][RTW89_CHILE][41] = 64, + [2][0][2][0][RTW89_UKRAINE][41] = 28, + [2][0][2][0][RTW89_MEXICO][41] = 74, + [2][0][2][0][RTW89_CN][41] = 48, + [2][0][2][0][RTW89_QATAR][41] = 28, + [2][0][2][0][RTW89_UK][41] = 64, + [2][0][2][0][RTW89_FCC][49] = 64, + [2][0][2][0][RTW89_ETSI][49] = 127, + [2][0][2][0][RTW89_MKK][49] = 127, + [2][0][2][0][RTW89_IC][49] = 74, + [2][0][2][0][RTW89_KCC][49] = 127, + [2][0][2][0][RTW89_ACMA][49] = 127, + [2][0][2][0][RTW89_CHILE][49] = 127, + [2][0][2][0][RTW89_UKRAINE][49] = 127, + [2][0][2][0][RTW89_MEXICO][49] = 127, + [2][0][2][0][RTW89_CN][49] = 127, + [2][0][2][0][RTW89_QATAR][49] = 127, + [2][0][2][0][RTW89_UK][49] = 127, + [2][1][2][0][RTW89_FCC][3] = 56, + [2][1][2][0][RTW89_ETSI][3] = 52, + [2][1][2][0][RTW89_MKK][3] = 52, + [2][1][2][0][RTW89_IC][3] = 52, + [2][1][2][0][RTW89_KCC][3] = 54, + [2][1][2][0][RTW89_ACMA][3] = 52, + [2][1][2][0][RTW89_CHILE][3] = 28, + [2][1][2][0][RTW89_UKRAINE][3] = 40, + [2][1][2][0][RTW89_MEXICO][3] = 50, + [2][1][2][0][RTW89_CN][3] = 50, + [2][1][2][0][RTW89_QATAR][3] = 52, + [2][1][2][0][RTW89_UK][3] = 52, + [2][1][2][0][RTW89_FCC][11] = 62, + [2][1][2][0][RTW89_ETSI][11] = 52, + [2][1][2][0][RTW89_MKK][11] = 52, + [2][1][2][0][RTW89_IC][11] = 52, + [2][1][2][0][RTW89_KCC][11] = 56, + [2][1][2][0][RTW89_ACMA][11] = 52, + [2][1][2][0][RTW89_CHILE][11] = 52, + [2][1][2][0][RTW89_UKRAINE][11] = 40, + [2][1][2][0][RTW89_MEXICO][11] = 62, + [2][1][2][0][RTW89_CN][11] = 50, + [2][1][2][0][RTW89_QATAR][11] = 52, + [2][1][2][0][RTW89_UK][11] = 52, + [2][1][2][0][RTW89_FCC][18] = 56, + [2][1][2][0][RTW89_ETSI][18] = 52, + [2][1][2][0][RTW89_MKK][18] = 70, + [2][1][2][0][RTW89_IC][18] = 56, + [2][1][2][0][RTW89_KCC][18] = 58, + [2][1][2][0][RTW89_ACMA][18] = 52, + [2][1][2][0][RTW89_CHILE][18] = 48, + [2][1][2][0][RTW89_UKRAINE][18] = 40, + [2][1][2][0][RTW89_MEXICO][18] = 56, + [2][1][2][0][RTW89_CN][18] = 127, + [2][1][2][0][RTW89_QATAR][18] = 52, + [2][1][2][0][RTW89_UK][18] = 52, + [2][1][2][0][RTW89_FCC][26] = 70, + [2][1][2][0][RTW89_ETSI][26] = 52, + [2][1][2][0][RTW89_MKK][26] = 70, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_KCC][26] = 56, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_CHILE][26] = 50, + [2][1][2][0][RTW89_UKRAINE][26] = 40, + [2][1][2][0][RTW89_MEXICO][26] = 70, + [2][1][2][0][RTW89_CN][26] = 127, + [2][1][2][0][RTW89_QATAR][26] = 52, + [2][1][2][0][RTW89_UK][26] = 52, + [2][1][2][0][RTW89_FCC][34] = 74, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 70, + [2][1][2][0][RTW89_IC][34] = 74, + [2][1][2][0][RTW89_KCC][34] = 56, + [2][1][2][0][RTW89_ACMA][34] = 70, + [2][1][2][0][RTW89_CHILE][34] = 50, + [2][1][2][0][RTW89_UKRAINE][34] = 127, + [2][1][2][0][RTW89_MEXICO][34] = 74, + [2][1][2][0][RTW89_CN][34] = 127, + [2][1][2][0][RTW89_QATAR][34] = 127, + [2][1][2][0][RTW89_UK][34] = 68, + [2][1][2][0][RTW89_FCC][41] = 74, + [2][1][2][0][RTW89_ETSI][41] = 16, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 74, + [2][1][2][0][RTW89_KCC][41] = 56, + [2][1][2][0][RTW89_ACMA][41] = 70, + [2][1][2][0][RTW89_CHILE][41] = 50, + [2][1][2][0][RTW89_UKRAINE][41] = 16, + [2][1][2][0][RTW89_MEXICO][41] = 74, + [2][1][2][0][RTW89_CN][41] = 48, + [2][1][2][0][RTW89_QATAR][41] = 16, + [2][1][2][0][RTW89_UK][41] = 52, + [2][1][2][0][RTW89_FCC][49] = 58, + [2][1][2][0][RTW89_ETSI][49] = 127, + [2][1][2][0][RTW89_MKK][49] = 127, + [2][1][2][0][RTW89_IC][49] = 66, + [2][1][2][0][RTW89_KCC][49] = 127, + [2][1][2][0][RTW89_ACMA][49] = 127, + [2][1][2][0][RTW89_CHILE][49] = 127, + [2][1][2][0][RTW89_UKRAINE][49] = 127, + [2][1][2][0][RTW89_MEXICO][49] = 127, + [2][1][2][0][RTW89_CN][49] = 127, + [2][1][2][0][RTW89_QATAR][49] = 127, + [2][1][2][0][RTW89_UK][49] = 127, + [2][1][2][1][RTW89_FCC][3] = 56, + [2][1][2][1][RTW89_ETSI][3] = 40, + [2][1][2][1][RTW89_MKK][3] = 52, + [2][1][2][1][RTW89_IC][3] = 40, + [2][1][2][1][RTW89_KCC][3] = 54, + [2][1][2][1][RTW89_ACMA][3] = 40, + [2][1][2][1][RTW89_CHILE][3] = 16, + [2][1][2][1][RTW89_UKRAINE][3] = 28, + [2][1][2][1][RTW89_MEXICO][3] = 50, + [2][1][2][1][RTW89_CN][3] = 38, + [2][1][2][1][RTW89_QATAR][3] = 40, + [2][1][2][1][RTW89_UK][3] = 40, + [2][1][2][1][RTW89_FCC][11] = 62, + [2][1][2][1][RTW89_ETSI][11] = 40, + [2][1][2][1][RTW89_MKK][11] = 52, + [2][1][2][1][RTW89_IC][11] = 40, + [2][1][2][1][RTW89_KCC][11] = 56, + [2][1][2][1][RTW89_ACMA][11] = 40, + [2][1][2][1][RTW89_CHILE][11] = 34, + [2][1][2][1][RTW89_UKRAINE][11] = 28, + [2][1][2][1][RTW89_MEXICO][11] = 62, + [2][1][2][1][RTW89_CN][11] = 38, + [2][1][2][1][RTW89_QATAR][11] = 40, + [2][1][2][1][RTW89_UK][11] = 40, + [2][1][2][1][RTW89_FCC][18] = 56, + [2][1][2][1][RTW89_ETSI][18] = 40, + [2][1][2][1][RTW89_MKK][18] = 70, + [2][1][2][1][RTW89_IC][18] = 56, + [2][1][2][1][RTW89_KCC][18] = 58, + [2][1][2][1][RTW89_ACMA][18] = 40, + [2][1][2][1][RTW89_CHILE][18] = 34, + [2][1][2][1][RTW89_UKRAINE][18] = 28, + [2][1][2][1][RTW89_MEXICO][18] = 56, + [2][1][2][1][RTW89_CN][18] = 127, + [2][1][2][1][RTW89_QATAR][18] = 40, + [2][1][2][1][RTW89_UK][18] = 40, + [2][1][2][1][RTW89_FCC][26] = 68, + [2][1][2][1][RTW89_ETSI][26] = 40, + [2][1][2][1][RTW89_MKK][26] = 70, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_KCC][26] = 56, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_CHILE][26] = 34, + [2][1][2][1][RTW89_UKRAINE][26] = 28, + [2][1][2][1][RTW89_MEXICO][26] = 68, + [2][1][2][1][RTW89_CN][26] = 127, + [2][1][2][1][RTW89_QATAR][26] = 40, + [2][1][2][1][RTW89_UK][26] = 40, + [2][1][2][1][RTW89_FCC][34] = 68, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 70, + [2][1][2][1][RTW89_IC][34] = 68, + [2][1][2][1][RTW89_KCC][34] = 56, + [2][1][2][1][RTW89_ACMA][34] = 70, + [2][1][2][1][RTW89_CHILE][34] = 34, + [2][1][2][1][RTW89_UKRAINE][34] = 127, + [2][1][2][1][RTW89_MEXICO][34] = 68, + [2][1][2][1][RTW89_CN][34] = 127, + [2][1][2][1][RTW89_QATAR][34] = 127, + [2][1][2][1][RTW89_UK][34] = 56, + [2][1][2][1][RTW89_FCC][41] = 74, + [2][1][2][1][RTW89_ETSI][41] = 4, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 74, + [2][1][2][1][RTW89_KCC][41] = 56, + [2][1][2][1][RTW89_ACMA][41] = 70, + [2][1][2][1][RTW89_CHILE][41] = 36, + [2][1][2][1][RTW89_UKRAINE][41] = 4, + [2][1][2][1][RTW89_MEXICO][41] = 74, + [2][1][2][1][RTW89_CN][41] = 46, + [2][1][2][1][RTW89_QATAR][41] = 4, + [2][1][2][1][RTW89_UK][41] = 38, + [2][1][2][1][RTW89_FCC][49] = 58, + [2][1][2][1][RTW89_ETSI][49] = 127, + [2][1][2][1][RTW89_MKK][49] = 127, + [2][1][2][1][RTW89_IC][49] = 66, + [2][1][2][1][RTW89_KCC][49] = 127, + [2][1][2][1][RTW89_ACMA][49] = 127, + [2][1][2][1][RTW89_CHILE][49] = 127, + [2][1][2][1][RTW89_UKRAINE][49] = 127, + [2][1][2][1][RTW89_MEXICO][49] = 127, + [2][1][2][1][RTW89_CN][49] = 127, + [2][1][2][1][RTW89_QATAR][49] = 127, + [2][1][2][1][RTW89_UK][49] = 127, +}; + +static +const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 32, + [0][0][RTW89_WW][1] = 32, + [0][0][RTW89_WW][2] = 32, + [0][0][RTW89_WW][3] = 32, + [0][0][RTW89_WW][4] = 32, + [0][0][RTW89_WW][5] = 32, + [0][0][RTW89_WW][6] = 32, + [0][0][RTW89_WW][7] = 32, + [0][0][RTW89_WW][8] = 32, + [0][0][RTW89_WW][9] = 32, + [0][0][RTW89_WW][10] = 32, + [0][0][RTW89_WW][11] = 32, + [0][0][RTW89_WW][12] = 32, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 20, + [0][1][RTW89_WW][1] = 22, + [0][1][RTW89_WW][2] = 22, + [0][1][RTW89_WW][3] = 22, + [0][1][RTW89_WW][4] = 22, + [0][1][RTW89_WW][5] = 22, + [0][1][RTW89_WW][6] = 22, + [0][1][RTW89_WW][7] = 22, + [0][1][RTW89_WW][8] = 22, + [0][1][RTW89_WW][9] = 22, + [0][1][RTW89_WW][10] = 22, + [0][1][RTW89_WW][11] = 22, + [0][1][RTW89_WW][12] = 20, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 44, + [1][0][RTW89_WW][2] = 44, + [1][0][RTW89_WW][3] = 44, + [1][0][RTW89_WW][4] = 44, + [1][0][RTW89_WW][5] = 44, + [1][0][RTW89_WW][6] = 44, + [1][0][RTW89_WW][7] = 44, + [1][0][RTW89_WW][8] = 44, + [1][0][RTW89_WW][9] = 44, + [1][0][RTW89_WW][10] = 44, + [1][0][RTW89_WW][11] = 44, + [1][0][RTW89_WW][12] = 38, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 32, + [1][1][RTW89_WW][1] = 32, + [1][1][RTW89_WW][2] = 32, + [1][1][RTW89_WW][3] = 32, + [1][1][RTW89_WW][4] = 32, + [1][1][RTW89_WW][5] = 32, + [1][1][RTW89_WW][6] = 32, + [1][1][RTW89_WW][7] = 32, + [1][1][RTW89_WW][8] = 32, + [1][1][RTW89_WW][9] = 32, + [1][1][RTW89_WW][10] = 32, + [1][1][RTW89_WW][11] = 32, + [1][1][RTW89_WW][12] = 32, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 56, + [2][0][RTW89_WW][1] = 56, + [2][0][RTW89_WW][2] = 56, + [2][0][RTW89_WW][3] = 56, + [2][0][RTW89_WW][4] = 56, + [2][0][RTW89_WW][5] = 56, + [2][0][RTW89_WW][6] = 56, + [2][0][RTW89_WW][7] = 56, + [2][0][RTW89_WW][8] = 56, + [2][0][RTW89_WW][9] = 56, + [2][0][RTW89_WW][10] = 56, + [2][0][RTW89_WW][11] = 50, + [2][0][RTW89_WW][12] = 46, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 44, + [2][1][RTW89_WW][1] = 44, + [2][1][RTW89_WW][2] = 44, + [2][1][RTW89_WW][3] = 44, + [2][1][RTW89_WW][4] = 44, + [2][1][RTW89_WW][5] = 44, + [2][1][RTW89_WW][6] = 44, + [2][1][RTW89_WW][7] = 44, + [2][1][RTW89_WW][8] = 44, + [2][1][RTW89_WW][9] = 44, + [2][1][RTW89_WW][10] = 44, + [2][1][RTW89_WW][11] = 38, + [2][1][RTW89_WW][12] = 34, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 68, + [0][0][RTW89_ETSI][0] = 32, + [0][0][RTW89_MKK][0] = 42, + [0][0][RTW89_IC][0] = 68, + [0][0][RTW89_KCC][0] = 44, + [0][0][RTW89_ACMA][0] = 32, + [0][0][RTW89_CHILE][0] = 66, + [0][0][RTW89_UKRAINE][0] = 32, + [0][0][RTW89_MEXICO][0] = 68, + [0][0][RTW89_CN][0] = 32, + [0][0][RTW89_QATAR][0] = 32, + [0][0][RTW89_UK][0] = 32, + [0][0][RTW89_FCC][1] = 68, + [0][0][RTW89_ETSI][1] = 32, + [0][0][RTW89_MKK][1] = 42, + [0][0][RTW89_IC][1] = 68, + [0][0][RTW89_KCC][1] = 44, + [0][0][RTW89_ACMA][1] = 32, + [0][0][RTW89_CHILE][1] = 64, + [0][0][RTW89_UKRAINE][1] = 32, + [0][0][RTW89_MEXICO][1] = 68, + [0][0][RTW89_CN][1] = 32, + [0][0][RTW89_QATAR][1] = 32, + [0][0][RTW89_UK][1] = 32, + [0][0][RTW89_FCC][2] = 72, + [0][0][RTW89_ETSI][2] = 32, + [0][0][RTW89_MKK][2] = 42, + [0][0][RTW89_IC][2] = 72, + [0][0][RTW89_KCC][2] = 44, + [0][0][RTW89_ACMA][2] = 32, + [0][0][RTW89_CHILE][2] = 64, + [0][0][RTW89_UKRAINE][2] = 32, + [0][0][RTW89_MEXICO][2] = 72, + [0][0][RTW89_CN][2] = 32, + [0][0][RTW89_QATAR][2] = 32, + [0][0][RTW89_UK][2] = 32, + [0][0][RTW89_FCC][3] = 76, + [0][0][RTW89_ETSI][3] = 32, + [0][0][RTW89_MKK][3] = 42, + [0][0][RTW89_IC][3] = 76, + [0][0][RTW89_KCC][3] = 44, + [0][0][RTW89_ACMA][3] = 32, + [0][0][RTW89_CHILE][3] = 64, + [0][0][RTW89_UKRAINE][3] = 32, + [0][0][RTW89_MEXICO][3] = 76, + [0][0][RTW89_CN][3] = 32, + [0][0][RTW89_QATAR][3] = 32, + [0][0][RTW89_UK][3] = 32, + [0][0][RTW89_FCC][4] = 76, + [0][0][RTW89_ETSI][4] = 32, + [0][0][RTW89_MKK][4] = 42, + [0][0][RTW89_IC][4] = 76, + [0][0][RTW89_KCC][4] = 44, + [0][0][RTW89_ACMA][4] = 32, + [0][0][RTW89_CHILE][4] = 64, + [0][0][RTW89_UKRAINE][4] = 32, + [0][0][RTW89_MEXICO][4] = 76, + [0][0][RTW89_CN][4] = 32, + [0][0][RTW89_QATAR][4] = 32, + [0][0][RTW89_UK][4] = 32, + [0][0][RTW89_FCC][5] = 84, + [0][0][RTW89_ETSI][5] = 32, + [0][0][RTW89_MKK][5] = 42, + [0][0][RTW89_IC][5] = 84, + [0][0][RTW89_KCC][5] = 44, + [0][0][RTW89_ACMA][5] = 32, + [0][0][RTW89_CHILE][5] = 64, + [0][0][RTW89_UKRAINE][5] = 32, + [0][0][RTW89_MEXICO][5] = 84, + [0][0][RTW89_CN][5] = 32, + [0][0][RTW89_QATAR][5] = 32, + [0][0][RTW89_UK][5] = 32, + [0][0][RTW89_FCC][6] = 74, + [0][0][RTW89_ETSI][6] = 32, + [0][0][RTW89_MKK][6] = 42, + [0][0][RTW89_IC][6] = 74, + [0][0][RTW89_KCC][6] = 44, + [0][0][RTW89_ACMA][6] = 32, + [0][0][RTW89_CHILE][6] = 64, + [0][0][RTW89_UKRAINE][6] = 32, + [0][0][RTW89_MEXICO][6] = 74, + [0][0][RTW89_CN][6] = 32, + [0][0][RTW89_QATAR][6] = 32, + [0][0][RTW89_UK][6] = 32, + [0][0][RTW89_FCC][7] = 74, + [0][0][RTW89_ETSI][7] = 32, + [0][0][RTW89_MKK][7] = 42, + [0][0][RTW89_IC][7] = 74, + [0][0][RTW89_KCC][7] = 44, + [0][0][RTW89_ACMA][7] = 32, + [0][0][RTW89_CHILE][7] = 64, + [0][0][RTW89_UKRAINE][7] = 32, + [0][0][RTW89_MEXICO][7] = 74, + [0][0][RTW89_CN][7] = 32, + [0][0][RTW89_QATAR][7] = 32, + [0][0][RTW89_UK][7] = 32, + [0][0][RTW89_FCC][8] = 70, + [0][0][RTW89_ETSI][8] = 32, + [0][0][RTW89_MKK][8] = 42, + [0][0][RTW89_IC][8] = 70, + [0][0][RTW89_KCC][8] = 44, + [0][0][RTW89_ACMA][8] = 32, + [0][0][RTW89_CHILE][8] = 64, + [0][0][RTW89_UKRAINE][8] = 32, + [0][0][RTW89_MEXICO][8] = 70, + [0][0][RTW89_CN][8] = 32, + [0][0][RTW89_QATAR][8] = 32, + [0][0][RTW89_UK][8] = 32, + [0][0][RTW89_FCC][9] = 66, + [0][0][RTW89_ETSI][9] = 32, + [0][0][RTW89_MKK][9] = 42, + [0][0][RTW89_IC][9] = 66, + [0][0][RTW89_KCC][9] = 42, + [0][0][RTW89_ACMA][9] = 32, + [0][0][RTW89_CHILE][9] = 64, + [0][0][RTW89_UKRAINE][9] = 32, + [0][0][RTW89_MEXICO][9] = 66, + [0][0][RTW89_CN][9] = 32, + [0][0][RTW89_QATAR][9] = 32, + [0][0][RTW89_UK][9] = 32, + [0][0][RTW89_FCC][10] = 66, + [0][0][RTW89_ETSI][10] = 32, + [0][0][RTW89_MKK][10] = 42, + [0][0][RTW89_IC][10] = 66, + [0][0][RTW89_KCC][10] = 42, + [0][0][RTW89_ACMA][10] = 32, + [0][0][RTW89_CHILE][10] = 66, + [0][0][RTW89_UKRAINE][10] = 32, + [0][0][RTW89_MEXICO][10] = 66, + [0][0][RTW89_CN][10] = 32, + [0][0][RTW89_QATAR][10] = 32, + [0][0][RTW89_UK][10] = 32, + [0][0][RTW89_FCC][11] = 50, + [0][0][RTW89_ETSI][11] = 32, + [0][0][RTW89_MKK][11] = 42, + [0][0][RTW89_IC][11] = 50, + [0][0][RTW89_KCC][11] = 42, + [0][0][RTW89_ACMA][11] = 32, + [0][0][RTW89_CHILE][11] = 64, + [0][0][RTW89_UKRAINE][11] = 32, + [0][0][RTW89_MEXICO][11] = 50, + [0][0][RTW89_CN][11] = 32, + [0][0][RTW89_QATAR][11] = 32, + [0][0][RTW89_UK][11] = 32, + [0][0][RTW89_FCC][12] = 32, + [0][0][RTW89_ETSI][12] = 32, + [0][0][RTW89_MKK][12] = 42, + [0][0][RTW89_IC][12] = 32, + [0][0][RTW89_KCC][12] = 42, + [0][0][RTW89_ACMA][12] = 32, + [0][0][RTW89_CHILE][12] = 64, + [0][0][RTW89_UKRAINE][12] = 32, + [0][0][RTW89_MEXICO][12] = 32, + [0][0][RTW89_CN][12] = 32, + [0][0][RTW89_QATAR][12] = 32, + [0][0][RTW89_UK][12] = 32, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_KCC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][0][RTW89_CHILE][13] = 127, + [0][0][RTW89_UKRAINE][13] = 127, + [0][0][RTW89_MEXICO][13] = 127, + [0][0][RTW89_CN][13] = 127, + [0][0][RTW89_QATAR][13] = 127, + [0][0][RTW89_UK][13] = 127, + [0][1][RTW89_FCC][0] = 54, + [0][1][RTW89_ETSI][0] = 20, + [0][1][RTW89_MKK][0] = 32, + [0][1][RTW89_IC][0] = 54, + [0][1][RTW89_KCC][0] = 32, + [0][1][RTW89_ACMA][0] = 20, + [0][1][RTW89_CHILE][0] = 50, + [0][1][RTW89_UKRAINE][0] = 20, + [0][1][RTW89_MEXICO][0] = 54, + [0][1][RTW89_CN][0] = 20, + [0][1][RTW89_QATAR][0] = 20, + [0][1][RTW89_UK][0] = 20, + [0][1][RTW89_FCC][1] = 54, + [0][1][RTW89_ETSI][1] = 22, + [0][1][RTW89_MKK][1] = 32, + [0][1][RTW89_IC][1] = 54, + [0][1][RTW89_KCC][1] = 32, + [0][1][RTW89_ACMA][1] = 22, + [0][1][RTW89_CHILE][1] = 50, + [0][1][RTW89_UKRAINE][1] = 22, + [0][1][RTW89_MEXICO][1] = 54, + [0][1][RTW89_CN][1] = 22, + [0][1][RTW89_QATAR][1] = 22, + [0][1][RTW89_UK][1] = 22, + [0][1][RTW89_FCC][2] = 58, + [0][1][RTW89_ETSI][2] = 22, + [0][1][RTW89_MKK][2] = 32, + [0][1][RTW89_IC][2] = 58, + [0][1][RTW89_KCC][2] = 32, + [0][1][RTW89_ACMA][2] = 22, + [0][1][RTW89_CHILE][2] = 50, + [0][1][RTW89_UKRAINE][2] = 22, + [0][1][RTW89_MEXICO][2] = 58, + [0][1][RTW89_CN][2] = 22, + [0][1][RTW89_QATAR][2] = 22, + [0][1][RTW89_UK][2] = 22, + [0][1][RTW89_FCC][3] = 62, + [0][1][RTW89_ETSI][3] = 22, + [0][1][RTW89_MKK][3] = 32, + [0][1][RTW89_IC][3] = 62, + [0][1][RTW89_KCC][3] = 32, + [0][1][RTW89_ACMA][3] = 22, + [0][1][RTW89_CHILE][3] = 50, + [0][1][RTW89_UKRAINE][3] = 22, + [0][1][RTW89_MEXICO][3] = 62, + [0][1][RTW89_CN][3] = 22, + [0][1][RTW89_QATAR][3] = 22, + [0][1][RTW89_UK][3] = 22, + [0][1][RTW89_FCC][4] = 66, + [0][1][RTW89_ETSI][4] = 22, + [0][1][RTW89_MKK][4] = 32, + [0][1][RTW89_IC][4] = 66, + [0][1][RTW89_KCC][4] = 30, + [0][1][RTW89_ACMA][4] = 22, + [0][1][RTW89_CHILE][4] = 50, + [0][1][RTW89_UKRAINE][4] = 22, + [0][1][RTW89_MEXICO][4] = 66, + [0][1][RTW89_CN][4] = 22, + [0][1][RTW89_QATAR][4] = 22, + [0][1][RTW89_UK][4] = 22, + [0][1][RTW89_FCC][5] = 74, + [0][1][RTW89_ETSI][5] = 22, + [0][1][RTW89_MKK][5] = 32, + [0][1][RTW89_IC][5] = 74, + [0][1][RTW89_KCC][5] = 30, + [0][1][RTW89_ACMA][5] = 22, + [0][1][RTW89_CHILE][5] = 52, + [0][1][RTW89_UKRAINE][5] = 22, + [0][1][RTW89_MEXICO][5] = 74, + [0][1][RTW89_CN][5] = 22, + [0][1][RTW89_QATAR][5] = 22, + [0][1][RTW89_UK][5] = 22, + [0][1][RTW89_FCC][6] = 66, + [0][1][RTW89_ETSI][6] = 22, + [0][1][RTW89_MKK][6] = 30, + [0][1][RTW89_IC][6] = 66, + [0][1][RTW89_KCC][6] = 30, + [0][1][RTW89_ACMA][6] = 22, + [0][1][RTW89_CHILE][6] = 50, + [0][1][RTW89_UKRAINE][6] = 22, + [0][1][RTW89_MEXICO][6] = 66, + [0][1][RTW89_CN][6] = 22, + [0][1][RTW89_QATAR][6] = 22, + [0][1][RTW89_UK][6] = 22, + [0][1][RTW89_FCC][7] = 62, + [0][1][RTW89_ETSI][7] = 22, + [0][1][RTW89_MKK][7] = 32, + [0][1][RTW89_IC][7] = 62, + [0][1][RTW89_KCC][7] = 30, + [0][1][RTW89_ACMA][7] = 22, + [0][1][RTW89_CHILE][7] = 50, + [0][1][RTW89_UKRAINE][7] = 22, + [0][1][RTW89_MEXICO][7] = 62, + [0][1][RTW89_CN][7] = 22, + [0][1][RTW89_QATAR][7] = 22, + [0][1][RTW89_UK][7] = 22, + [0][1][RTW89_FCC][8] = 58, + [0][1][RTW89_ETSI][8] = 22, + [0][1][RTW89_MKK][8] = 32, + [0][1][RTW89_IC][8] = 58, + [0][1][RTW89_KCC][8] = 30, + [0][1][RTW89_ACMA][8] = 22, + [0][1][RTW89_CHILE][8] = 50, + [0][1][RTW89_UKRAINE][8] = 22, + [0][1][RTW89_MEXICO][8] = 58, + [0][1][RTW89_CN][8] = 22, + [0][1][RTW89_QATAR][8] = 22, + [0][1][RTW89_UK][8] = 22, + [0][1][RTW89_FCC][9] = 54, + [0][1][RTW89_ETSI][9] = 22, + [0][1][RTW89_MKK][9] = 32, + [0][1][RTW89_IC][9] = 54, + [0][1][RTW89_KCC][9] = 30, + [0][1][RTW89_ACMA][9] = 22, + [0][1][RTW89_CHILE][9] = 50, + [0][1][RTW89_UKRAINE][9] = 22, + [0][1][RTW89_MEXICO][9] = 54, + [0][1][RTW89_CN][9] = 22, + [0][1][RTW89_QATAR][9] = 22, + [0][1][RTW89_UK][9] = 22, + [0][1][RTW89_FCC][10] = 54, + [0][1][RTW89_ETSI][10] = 22, + [0][1][RTW89_MKK][10] = 32, + [0][1][RTW89_IC][10] = 54, + [0][1][RTW89_KCC][10] = 30, + [0][1][RTW89_ACMA][10] = 22, + [0][1][RTW89_CHILE][10] = 50, + [0][1][RTW89_UKRAINE][10] = 22, + [0][1][RTW89_MEXICO][10] = 54, + [0][1][RTW89_CN][10] = 22, + [0][1][RTW89_QATAR][10] = 22, + [0][1][RTW89_UK][10] = 22, + [0][1][RTW89_FCC][11] = 38, + [0][1][RTW89_ETSI][11] = 22, + [0][1][RTW89_MKK][11] = 32, + [0][1][RTW89_IC][11] = 38, + [0][1][RTW89_KCC][11] = 30, + [0][1][RTW89_ACMA][11] = 22, + [0][1][RTW89_CHILE][11] = 50, + [0][1][RTW89_UKRAINE][11] = 22, + [0][1][RTW89_MEXICO][11] = 38, + [0][1][RTW89_CN][11] = 22, + [0][1][RTW89_QATAR][11] = 22, + [0][1][RTW89_UK][11] = 22, + [0][1][RTW89_FCC][12] = 30, + [0][1][RTW89_ETSI][12] = 20, + [0][1][RTW89_MKK][12] = 30, + [0][1][RTW89_IC][12] = 30, + [0][1][RTW89_KCC][12] = 30, + [0][1][RTW89_ACMA][12] = 20, + [0][1][RTW89_CHILE][12] = 50, + [0][1][RTW89_UKRAINE][12] = 20, + [0][1][RTW89_MEXICO][12] = 30, + [0][1][RTW89_CN][12] = 20, + [0][1][RTW89_QATAR][12] = 20, + [0][1][RTW89_UK][12] = 20, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_KCC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [0][1][RTW89_CHILE][13] = 127, + [0][1][RTW89_UKRAINE][13] = 127, + [0][1][RTW89_MEXICO][13] = 127, + [0][1][RTW89_CN][13] = 127, + [0][1][RTW89_QATAR][13] = 127, + [0][1][RTW89_UK][13] = 127, + [1][0][RTW89_FCC][0] = 72, + [1][0][RTW89_ETSI][0] = 42, + [1][0][RTW89_MKK][0] = 52, + [1][0][RTW89_IC][0] = 72, + [1][0][RTW89_KCC][0] = 52, + [1][0][RTW89_ACMA][0] = 42, + [1][0][RTW89_CHILE][0] = 68, + [1][0][RTW89_UKRAINE][0] = 42, + [1][0][RTW89_MEXICO][0] = 72, + [1][0][RTW89_CN][0] = 42, + [1][0][RTW89_QATAR][0] = 42, + [1][0][RTW89_UK][0] = 42, + [1][0][RTW89_FCC][1] = 72, + [1][0][RTW89_ETSI][1] = 44, + [1][0][RTW89_MKK][1] = 52, + [1][0][RTW89_IC][1] = 72, + [1][0][RTW89_KCC][1] = 52, + [1][0][RTW89_ACMA][1] = 44, + [1][0][RTW89_CHILE][1] = 68, + [1][0][RTW89_UKRAINE][1] = 44, + [1][0][RTW89_MEXICO][1] = 72, + [1][0][RTW89_CN][1] = 44, + [1][0][RTW89_QATAR][1] = 44, + [1][0][RTW89_UK][1] = 44, + [1][0][RTW89_FCC][2] = 76, + [1][0][RTW89_ETSI][2] = 44, + [1][0][RTW89_MKK][2] = 52, + [1][0][RTW89_IC][2] = 76, + [1][0][RTW89_KCC][2] = 52, + [1][0][RTW89_ACMA][2] = 44, + [1][0][RTW89_CHILE][2] = 68, + [1][0][RTW89_UKRAINE][2] = 44, + [1][0][RTW89_MEXICO][2] = 76, + [1][0][RTW89_CN][2] = 44, + [1][0][RTW89_QATAR][2] = 44, + [1][0][RTW89_UK][2] = 44, + [1][0][RTW89_FCC][3] = 78, + [1][0][RTW89_ETSI][3] = 44, + [1][0][RTW89_MKK][3] = 52, + [1][0][RTW89_IC][3] = 78, + [1][0][RTW89_KCC][3] = 52, + [1][0][RTW89_ACMA][3] = 44, + [1][0][RTW89_CHILE][3] = 68, + [1][0][RTW89_UKRAINE][3] = 44, + [1][0][RTW89_MEXICO][3] = 78, + [1][0][RTW89_CN][3] = 44, + [1][0][RTW89_QATAR][3] = 44, + [1][0][RTW89_UK][3] = 44, + [1][0][RTW89_FCC][4] = 78, + [1][0][RTW89_ETSI][4] = 44, + [1][0][RTW89_MKK][4] = 52, + [1][0][RTW89_IC][4] = 78, + [1][0][RTW89_KCC][4] = 52, + [1][0][RTW89_ACMA][4] = 44, + [1][0][RTW89_CHILE][4] = 68, + [1][0][RTW89_UKRAINE][4] = 44, + [1][0][RTW89_MEXICO][4] = 78, + [1][0][RTW89_CN][4] = 44, + [1][0][RTW89_QATAR][4] = 44, + [1][0][RTW89_UK][4] = 44, + [1][0][RTW89_FCC][5] = 84, + [1][0][RTW89_ETSI][5] = 44, + [1][0][RTW89_MKK][5] = 52, + [1][0][RTW89_IC][5] = 84, + [1][0][RTW89_KCC][5] = 52, + [1][0][RTW89_ACMA][5] = 44, + [1][0][RTW89_CHILE][5] = 68, + [1][0][RTW89_UKRAINE][5] = 44, + [1][0][RTW89_MEXICO][5] = 84, + [1][0][RTW89_CN][5] = 44, + [1][0][RTW89_QATAR][5] = 44, + [1][0][RTW89_UK][5] = 44, + [1][0][RTW89_FCC][6] = 72, + [1][0][RTW89_ETSI][6] = 44, + [1][0][RTW89_MKK][6] = 52, + [1][0][RTW89_IC][6] = 72, + [1][0][RTW89_KCC][6] = 52, + [1][0][RTW89_ACMA][6] = 44, + [1][0][RTW89_CHILE][6] = 68, + [1][0][RTW89_UKRAINE][6] = 44, + [1][0][RTW89_MEXICO][6] = 72, + [1][0][RTW89_CN][6] = 44, + [1][0][RTW89_QATAR][6] = 44, + [1][0][RTW89_UK][6] = 44, + [1][0][RTW89_FCC][7] = 72, + [1][0][RTW89_ETSI][7] = 44, + [1][0][RTW89_MKK][7] = 52, + [1][0][RTW89_IC][7] = 72, + [1][0][RTW89_KCC][7] = 52, + [1][0][RTW89_ACMA][7] = 44, + [1][0][RTW89_CHILE][7] = 68, + [1][0][RTW89_UKRAINE][7] = 44, + [1][0][RTW89_MEXICO][7] = 72, + [1][0][RTW89_CN][7] = 44, + [1][0][RTW89_QATAR][7] = 44, + [1][0][RTW89_UK][7] = 44, + [1][0][RTW89_FCC][8] = 72, + [1][0][RTW89_ETSI][8] = 44, + [1][0][RTW89_MKK][8] = 52, + [1][0][RTW89_IC][8] = 72, + [1][0][RTW89_KCC][8] = 52, + [1][0][RTW89_ACMA][8] = 44, + [1][0][RTW89_CHILE][8] = 68, + [1][0][RTW89_UKRAINE][8] = 44, + [1][0][RTW89_MEXICO][8] = 72, + [1][0][RTW89_CN][8] = 44, + [1][0][RTW89_QATAR][8] = 44, + [1][0][RTW89_UK][8] = 44, + [1][0][RTW89_FCC][9] = 68, + [1][0][RTW89_ETSI][9] = 44, + [1][0][RTW89_MKK][9] = 52, + [1][0][RTW89_IC][9] = 68, + [1][0][RTW89_KCC][9] = 52, + [1][0][RTW89_ACMA][9] = 44, + [1][0][RTW89_CHILE][9] = 68, + [1][0][RTW89_UKRAINE][9] = 44, + [1][0][RTW89_MEXICO][9] = 68, + [1][0][RTW89_CN][9] = 44, + [1][0][RTW89_QATAR][9] = 44, + [1][0][RTW89_UK][9] = 44, + [1][0][RTW89_FCC][10] = 68, + [1][0][RTW89_ETSI][10] = 44, + [1][0][RTW89_MKK][10] = 52, + [1][0][RTW89_IC][10] = 68, + [1][0][RTW89_KCC][10] = 52, + [1][0][RTW89_ACMA][10] = 44, + [1][0][RTW89_CHILE][10] = 70, + [1][0][RTW89_UKRAINE][10] = 44, + [1][0][RTW89_MEXICO][10] = 68, + [1][0][RTW89_CN][10] = 44, + [1][0][RTW89_QATAR][10] = 44, + [1][0][RTW89_UK][10] = 44, + [1][0][RTW89_FCC][11] = 50, + [1][0][RTW89_ETSI][11] = 44, + [1][0][RTW89_MKK][11] = 52, + [1][0][RTW89_IC][11] = 50, + [1][0][RTW89_KCC][11] = 52, + [1][0][RTW89_ACMA][11] = 44, + [1][0][RTW89_CHILE][11] = 68, + [1][0][RTW89_UKRAINE][11] = 44, + [1][0][RTW89_MEXICO][11] = 50, + [1][0][RTW89_CN][11] = 44, + [1][0][RTW89_QATAR][11] = 44, + [1][0][RTW89_UK][11] = 44, + [1][0][RTW89_FCC][12] = 38, + [1][0][RTW89_ETSI][12] = 42, + [1][0][RTW89_MKK][12] = 52, + [1][0][RTW89_IC][12] = 38, + [1][0][RTW89_KCC][12] = 52, + [1][0][RTW89_ACMA][12] = 42, + [1][0][RTW89_CHILE][12] = 68, + [1][0][RTW89_UKRAINE][12] = 42, + [1][0][RTW89_MEXICO][12] = 38, + [1][0][RTW89_CN][12] = 42, + [1][0][RTW89_QATAR][12] = 42, + [1][0][RTW89_UK][12] = 42, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_KCC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][0][RTW89_CHILE][13] = 127, + [1][0][RTW89_UKRAINE][13] = 127, + [1][0][RTW89_MEXICO][13] = 127, + [1][0][RTW89_CN][13] = 127, + [1][0][RTW89_QATAR][13] = 127, + [1][0][RTW89_UK][13] = 127, + [1][1][RTW89_FCC][0] = 54, + [1][1][RTW89_ETSI][0] = 32, + [1][1][RTW89_MKK][0] = 40, + [1][1][RTW89_IC][0] = 54, + [1][1][RTW89_KCC][0] = 40, + [1][1][RTW89_ACMA][0] = 32, + [1][1][RTW89_CHILE][0] = 54, + [1][1][RTW89_UKRAINE][0] = 32, + [1][1][RTW89_MEXICO][0] = 54, + [1][1][RTW89_CN][0] = 32, + [1][1][RTW89_QATAR][0] = 32, + [1][1][RTW89_UK][0] = 32, + [1][1][RTW89_FCC][1] = 54, + [1][1][RTW89_ETSI][1] = 32, + [1][1][RTW89_MKK][1] = 40, + [1][1][RTW89_IC][1] = 54, + [1][1][RTW89_KCC][1] = 40, + [1][1][RTW89_ACMA][1] = 32, + [1][1][RTW89_CHILE][1] = 54, + [1][1][RTW89_UKRAINE][1] = 32, + [1][1][RTW89_MEXICO][1] = 54, + [1][1][RTW89_CN][1] = 32, + [1][1][RTW89_QATAR][1] = 32, + [1][1][RTW89_UK][1] = 32, + [1][1][RTW89_FCC][2] = 58, + [1][1][RTW89_ETSI][2] = 32, + [1][1][RTW89_MKK][2] = 40, + [1][1][RTW89_IC][2] = 58, + [1][1][RTW89_KCC][2] = 40, + [1][1][RTW89_ACMA][2] = 32, + [1][1][RTW89_CHILE][2] = 54, + [1][1][RTW89_UKRAINE][2] = 32, + [1][1][RTW89_MEXICO][2] = 58, + [1][1][RTW89_CN][2] = 32, + [1][1][RTW89_QATAR][2] = 32, + [1][1][RTW89_UK][2] = 32, + [1][1][RTW89_FCC][3] = 62, + [1][1][RTW89_ETSI][3] = 32, + [1][1][RTW89_MKK][3] = 40, + [1][1][RTW89_IC][3] = 62, + [1][1][RTW89_KCC][3] = 40, + [1][1][RTW89_ACMA][3] = 32, + [1][1][RTW89_CHILE][3] = 54, + [1][1][RTW89_UKRAINE][3] = 32, + [1][1][RTW89_MEXICO][3] = 62, + [1][1][RTW89_CN][3] = 32, + [1][1][RTW89_QATAR][3] = 32, + [1][1][RTW89_UK][3] = 32, + [1][1][RTW89_FCC][4] = 66, + [1][1][RTW89_ETSI][4] = 32, + [1][1][RTW89_MKK][4] = 40, + [1][1][RTW89_IC][4] = 66, + [1][1][RTW89_KCC][4] = 40, + [1][1][RTW89_ACMA][4] = 32, + [1][1][RTW89_CHILE][4] = 54, + [1][1][RTW89_UKRAINE][4] = 32, + [1][1][RTW89_MEXICO][4] = 66, + [1][1][RTW89_CN][4] = 32, + [1][1][RTW89_QATAR][4] = 32, + [1][1][RTW89_UK][4] = 32, + [1][1][RTW89_FCC][5] = 74, + [1][1][RTW89_ETSI][5] = 32, + [1][1][RTW89_MKK][5] = 40, + [1][1][RTW89_IC][5] = 74, + [1][1][RTW89_KCC][5] = 40, + [1][1][RTW89_ACMA][5] = 32, + [1][1][RTW89_CHILE][5] = 54, + [1][1][RTW89_UKRAINE][5] = 32, + [1][1][RTW89_MEXICO][5] = 74, + [1][1][RTW89_CN][5] = 32, + [1][1][RTW89_QATAR][5] = 32, + [1][1][RTW89_UK][5] = 32, + [1][1][RTW89_FCC][6] = 66, + [1][1][RTW89_ETSI][6] = 32, + [1][1][RTW89_MKK][6] = 40, + [1][1][RTW89_IC][6] = 66, + [1][1][RTW89_KCC][6] = 40, + [1][1][RTW89_ACMA][6] = 32, + [1][1][RTW89_CHILE][6] = 54, + [1][1][RTW89_UKRAINE][6] = 32, + [1][1][RTW89_MEXICO][6] = 66, + [1][1][RTW89_CN][6] = 32, + [1][1][RTW89_QATAR][6] = 32, + [1][1][RTW89_UK][6] = 32, + [1][1][RTW89_FCC][7] = 62, + [1][1][RTW89_ETSI][7] = 32, + [1][1][RTW89_MKK][7] = 40, + [1][1][RTW89_IC][7] = 62, + [1][1][RTW89_KCC][7] = 40, + [1][1][RTW89_ACMA][7] = 32, + [1][1][RTW89_CHILE][7] = 54, + [1][1][RTW89_UKRAINE][7] = 32, + [1][1][RTW89_MEXICO][7] = 62, + [1][1][RTW89_CN][7] = 32, + [1][1][RTW89_QATAR][7] = 32, + [1][1][RTW89_UK][7] = 32, + [1][1][RTW89_FCC][8] = 58, + [1][1][RTW89_ETSI][8] = 32, + [1][1][RTW89_MKK][8] = 40, + [1][1][RTW89_IC][8] = 58, + [1][1][RTW89_KCC][8] = 40, + [1][1][RTW89_ACMA][8] = 32, + [1][1][RTW89_CHILE][8] = 54, + [1][1][RTW89_UKRAINE][8] = 32, + [1][1][RTW89_MEXICO][8] = 58, + [1][1][RTW89_CN][8] = 32, + [1][1][RTW89_QATAR][8] = 32, + [1][1][RTW89_UK][8] = 32, + [1][1][RTW89_FCC][9] = 54, + [1][1][RTW89_ETSI][9] = 32, + [1][1][RTW89_MKK][9] = 40, + [1][1][RTW89_IC][9] = 54, + [1][1][RTW89_KCC][9] = 40, + [1][1][RTW89_ACMA][9] = 32, + [1][1][RTW89_CHILE][9] = 54, + [1][1][RTW89_UKRAINE][9] = 32, + [1][1][RTW89_MEXICO][9] = 54, + [1][1][RTW89_CN][9] = 32, + [1][1][RTW89_QATAR][9] = 32, + [1][1][RTW89_UK][9] = 32, + [1][1][RTW89_FCC][10] = 54, + [1][1][RTW89_ETSI][10] = 32, + [1][1][RTW89_MKK][10] = 40, + [1][1][RTW89_IC][10] = 54, + [1][1][RTW89_KCC][10] = 40, + [1][1][RTW89_ACMA][10] = 32, + [1][1][RTW89_CHILE][10] = 54, + [1][1][RTW89_UKRAINE][10] = 32, + [1][1][RTW89_MEXICO][10] = 54, + [1][1][RTW89_CN][10] = 32, + [1][1][RTW89_QATAR][10] = 32, + [1][1][RTW89_UK][10] = 32, + [1][1][RTW89_FCC][11] = 38, + [1][1][RTW89_ETSI][11] = 32, + [1][1][RTW89_MKK][11] = 40, + [1][1][RTW89_IC][11] = 38, + [1][1][RTW89_KCC][11] = 40, + [1][1][RTW89_ACMA][11] = 32, + [1][1][RTW89_CHILE][11] = 54, + [1][1][RTW89_UKRAINE][11] = 32, + [1][1][RTW89_MEXICO][11] = 38, + [1][1][RTW89_CN][11] = 32, + [1][1][RTW89_QATAR][11] = 32, + [1][1][RTW89_UK][11] = 32, + [1][1][RTW89_FCC][12] = 32, + [1][1][RTW89_ETSI][12] = 32, + [1][1][RTW89_MKK][12] = 40, + [1][1][RTW89_IC][12] = 32, + [1][1][RTW89_KCC][12] = 40, + [1][1][RTW89_ACMA][12] = 32, + [1][1][RTW89_CHILE][12] = 54, + [1][1][RTW89_UKRAINE][12] = 32, + [1][1][RTW89_MEXICO][12] = 32, + [1][1][RTW89_CN][12] = 32, + [1][1][RTW89_QATAR][12] = 32, + [1][1][RTW89_UK][12] = 32, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_KCC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [1][1][RTW89_CHILE][13] = 127, + [1][1][RTW89_UKRAINE][13] = 127, + [1][1][RTW89_MEXICO][13] = 127, + [1][1][RTW89_CN][13] = 127, + [1][1][RTW89_QATAR][13] = 127, + [1][1][RTW89_UK][13] = 127, + [2][0][RTW89_FCC][0] = 72, + [2][0][RTW89_ETSI][0] = 56, + [2][0][RTW89_MKK][0] = 64, + [2][0][RTW89_IC][0] = 72, + [2][0][RTW89_KCC][0] = 66, + [2][0][RTW89_ACMA][0] = 56, + [2][0][RTW89_CHILE][0] = 68, + [2][0][RTW89_UKRAINE][0] = 56, + [2][0][RTW89_MEXICO][0] = 72, + [2][0][RTW89_CN][0] = 56, + [2][0][RTW89_QATAR][0] = 56, + [2][0][RTW89_UK][0] = 56, + [2][0][RTW89_FCC][1] = 72, + [2][0][RTW89_ETSI][1] = 56, + [2][0][RTW89_MKK][1] = 64, + [2][0][RTW89_IC][1] = 72, + [2][0][RTW89_KCC][1] = 66, + [2][0][RTW89_ACMA][1] = 56, + [2][0][RTW89_CHILE][1] = 68, + [2][0][RTW89_UKRAINE][1] = 56, + [2][0][RTW89_MEXICO][1] = 72, + [2][0][RTW89_CN][1] = 56, + [2][0][RTW89_QATAR][1] = 56, + [2][0][RTW89_UK][1] = 56, + [2][0][RTW89_FCC][2] = 74, + [2][0][RTW89_ETSI][2] = 56, + [2][0][RTW89_MKK][2] = 64, + [2][0][RTW89_IC][2] = 74, + [2][0][RTW89_KCC][2] = 66, + [2][0][RTW89_ACMA][2] = 56, + [2][0][RTW89_CHILE][2] = 68, + [2][0][RTW89_UKRAINE][2] = 56, + [2][0][RTW89_MEXICO][2] = 74, + [2][0][RTW89_CN][2] = 56, + [2][0][RTW89_QATAR][2] = 56, + [2][0][RTW89_UK][2] = 56, + [2][0][RTW89_FCC][3] = 74, + [2][0][RTW89_ETSI][3] = 56, + [2][0][RTW89_MKK][3] = 64, + [2][0][RTW89_IC][3] = 74, + [2][0][RTW89_KCC][3] = 66, + [2][0][RTW89_ACMA][3] = 56, + [2][0][RTW89_CHILE][3] = 68, + [2][0][RTW89_UKRAINE][3] = 56, + [2][0][RTW89_MEXICO][3] = 74, + [2][0][RTW89_CN][3] = 56, + [2][0][RTW89_QATAR][3] = 56, + [2][0][RTW89_UK][3] = 56, + [2][0][RTW89_FCC][4] = 74, + [2][0][RTW89_ETSI][4] = 56, + [2][0][RTW89_MKK][4] = 64, + [2][0][RTW89_IC][4] = 74, + [2][0][RTW89_KCC][4] = 66, + [2][0][RTW89_ACMA][4] = 56, + [2][0][RTW89_CHILE][4] = 68, + [2][0][RTW89_UKRAINE][4] = 56, + [2][0][RTW89_MEXICO][4] = 74, + [2][0][RTW89_CN][4] = 56, + [2][0][RTW89_QATAR][4] = 56, + [2][0][RTW89_UK][4] = 56, + [2][0][RTW89_FCC][5] = 84, + [2][0][RTW89_ETSI][5] = 56, + [2][0][RTW89_MKK][5] = 64, + [2][0][RTW89_IC][5] = 84, + [2][0][RTW89_KCC][5] = 66, + [2][0][RTW89_ACMA][5] = 56, + [2][0][RTW89_CHILE][5] = 70, + [2][0][RTW89_UKRAINE][5] = 56, + [2][0][RTW89_MEXICO][5] = 84, + [2][0][RTW89_CN][5] = 56, + [2][0][RTW89_QATAR][5] = 56, + [2][0][RTW89_UK][5] = 56, + [2][0][RTW89_FCC][6] = 70, + [2][0][RTW89_ETSI][6] = 56, + [2][0][RTW89_MKK][6] = 64, + [2][0][RTW89_IC][6] = 70, + [2][0][RTW89_KCC][6] = 66, + [2][0][RTW89_ACMA][6] = 56, + [2][0][RTW89_CHILE][6] = 68, + [2][0][RTW89_UKRAINE][6] = 56, + [2][0][RTW89_MEXICO][6] = 70, + [2][0][RTW89_CN][6] = 56, + [2][0][RTW89_QATAR][6] = 56, + [2][0][RTW89_UK][6] = 56, + [2][0][RTW89_FCC][7] = 70, + [2][0][RTW89_ETSI][7] = 56, + [2][0][RTW89_MKK][7] = 64, + [2][0][RTW89_IC][7] = 70, + [2][0][RTW89_KCC][7] = 66, + [2][0][RTW89_ACMA][7] = 56, + [2][0][RTW89_CHILE][7] = 68, + [2][0][RTW89_UKRAINE][7] = 56, + [2][0][RTW89_MEXICO][7] = 70, + [2][0][RTW89_CN][7] = 56, + [2][0][RTW89_QATAR][7] = 56, + [2][0][RTW89_UK][7] = 56, + [2][0][RTW89_FCC][8] = 70, + [2][0][RTW89_ETSI][8] = 56, + [2][0][RTW89_MKK][8] = 64, + [2][0][RTW89_IC][8] = 70, + [2][0][RTW89_KCC][8] = 66, + [2][0][RTW89_ACMA][8] = 56, + [2][0][RTW89_CHILE][8] = 68, + [2][0][RTW89_UKRAINE][8] = 56, + [2][0][RTW89_MEXICO][8] = 70, + [2][0][RTW89_CN][8] = 56, + [2][0][RTW89_QATAR][8] = 56, + [2][0][RTW89_UK][8] = 56, + [2][0][RTW89_FCC][9] = 68, + [2][0][RTW89_ETSI][9] = 56, + [2][0][RTW89_MKK][9] = 64, + [2][0][RTW89_IC][9] = 68, + [2][0][RTW89_KCC][9] = 66, + [2][0][RTW89_ACMA][9] = 56, + [2][0][RTW89_CHILE][9] = 68, + [2][0][RTW89_UKRAINE][9] = 56, + [2][0][RTW89_MEXICO][9] = 68, + [2][0][RTW89_CN][9] = 56, + [2][0][RTW89_QATAR][9] = 56, + [2][0][RTW89_UK][9] = 56, + [2][0][RTW89_FCC][10] = 68, + [2][0][RTW89_ETSI][10] = 56, + [2][0][RTW89_MKK][10] = 64, + [2][0][RTW89_IC][10] = 68, + [2][0][RTW89_KCC][10] = 66, + [2][0][RTW89_ACMA][10] = 56, + [2][0][RTW89_CHILE][10] = 68, + [2][0][RTW89_UKRAINE][10] = 56, + [2][0][RTW89_MEXICO][10] = 68, + [2][0][RTW89_CN][10] = 56, + [2][0][RTW89_QATAR][10] = 56, + [2][0][RTW89_UK][10] = 56, + [2][0][RTW89_FCC][11] = 50, + [2][0][RTW89_ETSI][11] = 56, + [2][0][RTW89_MKK][11] = 64, + [2][0][RTW89_IC][11] = 50, + [2][0][RTW89_KCC][11] = 66, + [2][0][RTW89_ACMA][11] = 56, + [2][0][RTW89_CHILE][11] = 68, + [2][0][RTW89_UKRAINE][11] = 56, + [2][0][RTW89_MEXICO][11] = 50, + [2][0][RTW89_CN][11] = 56, + [2][0][RTW89_QATAR][11] = 56, + [2][0][RTW89_UK][11] = 56, + [2][0][RTW89_FCC][12] = 46, + [2][0][RTW89_ETSI][12] = 56, + [2][0][RTW89_MKK][12] = 64, + [2][0][RTW89_IC][12] = 46, + [2][0][RTW89_KCC][12] = 66, + [2][0][RTW89_ACMA][12] = 56, + [2][0][RTW89_CHILE][12] = 68, + [2][0][RTW89_UKRAINE][12] = 56, + [2][0][RTW89_MEXICO][12] = 46, + [2][0][RTW89_CN][12] = 56, + [2][0][RTW89_QATAR][12] = 56, + [2][0][RTW89_UK][12] = 56, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_KCC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][0][RTW89_CHILE][13] = 127, + [2][0][RTW89_UKRAINE][13] = 127, + [2][0][RTW89_MEXICO][13] = 127, + [2][0][RTW89_CN][13] = 127, + [2][0][RTW89_QATAR][13] = 127, + [2][0][RTW89_UK][13] = 127, + [2][1][RTW89_FCC][0] = 54, + [2][1][RTW89_ETSI][0] = 44, + [2][1][RTW89_MKK][0] = 52, + [2][1][RTW89_IC][0] = 54, + [2][1][RTW89_KCC][0] = 54, + [2][1][RTW89_ACMA][0] = 44, + [2][1][RTW89_CHILE][0] = 58, + [2][1][RTW89_UKRAINE][0] = 44, + [2][1][RTW89_MEXICO][0] = 54, + [2][1][RTW89_CN][0] = 44, + [2][1][RTW89_QATAR][0] = 44, + [2][1][RTW89_UK][0] = 44, + [2][1][RTW89_FCC][1] = 54, + [2][1][RTW89_ETSI][1] = 44, + [2][1][RTW89_MKK][1] = 52, + [2][1][RTW89_IC][1] = 54, + [2][1][RTW89_KCC][1] = 54, + [2][1][RTW89_ACMA][1] = 44, + [2][1][RTW89_CHILE][1] = 56, + [2][1][RTW89_UKRAINE][1] = 44, + [2][1][RTW89_MEXICO][1] = 54, + [2][1][RTW89_CN][1] = 44, + [2][1][RTW89_QATAR][1] = 44, + [2][1][RTW89_UK][1] = 44, + [2][1][RTW89_FCC][2] = 58, + [2][1][RTW89_ETSI][2] = 44, + [2][1][RTW89_MKK][2] = 52, + [2][1][RTW89_IC][2] = 58, + [2][1][RTW89_KCC][2] = 54, + [2][1][RTW89_ACMA][2] = 44, + [2][1][RTW89_CHILE][2] = 56, + [2][1][RTW89_UKRAINE][2] = 44, + [2][1][RTW89_MEXICO][2] = 58, + [2][1][RTW89_CN][2] = 44, + [2][1][RTW89_QATAR][2] = 44, + [2][1][RTW89_UK][2] = 44, + [2][1][RTW89_FCC][3] = 62, + [2][1][RTW89_ETSI][3] = 44, + [2][1][RTW89_MKK][3] = 52, + [2][1][RTW89_IC][3] = 62, + [2][1][RTW89_KCC][3] = 54, + [2][1][RTW89_ACMA][3] = 44, + [2][1][RTW89_CHILE][3] = 56, + [2][1][RTW89_UKRAINE][3] = 44, + [2][1][RTW89_MEXICO][3] = 62, + [2][1][RTW89_CN][3] = 44, + [2][1][RTW89_QATAR][3] = 44, + [2][1][RTW89_UK][3] = 44, + [2][1][RTW89_FCC][4] = 64, + [2][1][RTW89_ETSI][4] = 44, + [2][1][RTW89_MKK][4] = 52, + [2][1][RTW89_IC][4] = 64, + [2][1][RTW89_KCC][4] = 52, + [2][1][RTW89_ACMA][4] = 44, + [2][1][RTW89_CHILE][4] = 56, + [2][1][RTW89_UKRAINE][4] = 44, + [2][1][RTW89_MEXICO][4] = 64, + [2][1][RTW89_CN][4] = 44, + [2][1][RTW89_QATAR][4] = 44, + [2][1][RTW89_UK][4] = 44, + [2][1][RTW89_FCC][5] = 80, + [2][1][RTW89_ETSI][5] = 44, + [2][1][RTW89_MKK][5] = 52, + [2][1][RTW89_IC][5] = 80, + [2][1][RTW89_KCC][5] = 52, + [2][1][RTW89_ACMA][5] = 44, + [2][1][RTW89_CHILE][5] = 56, + [2][1][RTW89_UKRAINE][5] = 44, + [2][1][RTW89_MEXICO][5] = 80, + [2][1][RTW89_CN][5] = 44, + [2][1][RTW89_QATAR][5] = 44, + [2][1][RTW89_UK][5] = 44, + [2][1][RTW89_FCC][6] = 62, + [2][1][RTW89_ETSI][6] = 44, + [2][1][RTW89_MKK][6] = 52, + [2][1][RTW89_IC][6] = 62, + [2][1][RTW89_KCC][6] = 52, + [2][1][RTW89_ACMA][6] = 44, + [2][1][RTW89_CHILE][6] = 56, + [2][1][RTW89_UKRAINE][6] = 44, + [2][1][RTW89_MEXICO][6] = 62, + [2][1][RTW89_CN][6] = 44, + [2][1][RTW89_QATAR][6] = 44, + [2][1][RTW89_UK][6] = 44, + [2][1][RTW89_FCC][7] = 62, + [2][1][RTW89_ETSI][7] = 44, + [2][1][RTW89_MKK][7] = 52, + [2][1][RTW89_IC][7] = 62, + [2][1][RTW89_KCC][7] = 52, + [2][1][RTW89_ACMA][7] = 44, + [2][1][RTW89_CHILE][7] = 56, + [2][1][RTW89_UKRAINE][7] = 44, + [2][1][RTW89_MEXICO][7] = 62, + [2][1][RTW89_CN][7] = 44, + [2][1][RTW89_QATAR][7] = 44, + [2][1][RTW89_UK][7] = 44, + [2][1][RTW89_FCC][8] = 58, + [2][1][RTW89_ETSI][8] = 44, + [2][1][RTW89_MKK][8] = 52, + [2][1][RTW89_IC][8] = 58, + [2][1][RTW89_KCC][8] = 52, + [2][1][RTW89_ACMA][8] = 44, + [2][1][RTW89_CHILE][8] = 56, + [2][1][RTW89_UKRAINE][8] = 44, + [2][1][RTW89_MEXICO][8] = 58, + [2][1][RTW89_CN][8] = 44, + [2][1][RTW89_QATAR][8] = 44, + [2][1][RTW89_UK][8] = 44, + [2][1][RTW89_FCC][9] = 54, + [2][1][RTW89_ETSI][9] = 44, + [2][1][RTW89_MKK][9] = 52, + [2][1][RTW89_IC][9] = 54, + [2][1][RTW89_KCC][9] = 54, + [2][1][RTW89_ACMA][9] = 44, + [2][1][RTW89_CHILE][9] = 56, + [2][1][RTW89_UKRAINE][9] = 44, + [2][1][RTW89_MEXICO][9] = 54, + [2][1][RTW89_CN][9] = 44, + [2][1][RTW89_QATAR][9] = 44, + [2][1][RTW89_UK][9] = 44, + [2][1][RTW89_FCC][10] = 54, + [2][1][RTW89_ETSI][10] = 44, + [2][1][RTW89_MKK][10] = 52, + [2][1][RTW89_IC][10] = 54, + [2][1][RTW89_KCC][10] = 54, + [2][1][RTW89_ACMA][10] = 44, + [2][1][RTW89_CHILE][10] = 56, + [2][1][RTW89_UKRAINE][10] = 44, + [2][1][RTW89_MEXICO][10] = 54, + [2][1][RTW89_CN][10] = 44, + [2][1][RTW89_QATAR][10] = 44, + [2][1][RTW89_UK][10] = 44, + [2][1][RTW89_FCC][11] = 38, + [2][1][RTW89_ETSI][11] = 44, + [2][1][RTW89_MKK][11] = 52, + [2][1][RTW89_IC][11] = 38, + [2][1][RTW89_KCC][11] = 54, + [2][1][RTW89_ACMA][11] = 44, + [2][1][RTW89_CHILE][11] = 56, + [2][1][RTW89_UKRAINE][11] = 44, + [2][1][RTW89_MEXICO][11] = 38, + [2][1][RTW89_CN][11] = 44, + [2][1][RTW89_QATAR][11] = 44, + [2][1][RTW89_UK][11] = 44, + [2][1][RTW89_FCC][12] = 34, + [2][1][RTW89_ETSI][12] = 42, + [2][1][RTW89_MKK][12] = 52, + [2][1][RTW89_IC][12] = 34, + [2][1][RTW89_KCC][12] = 54, + [2][1][RTW89_ACMA][12] = 42, + [2][1][RTW89_CHILE][12] = 56, + [2][1][RTW89_UKRAINE][12] = 42, + [2][1][RTW89_MEXICO][12] = 34, + [2][1][RTW89_CN][12] = 42, + [2][1][RTW89_QATAR][12] = 42, + [2][1][RTW89_UK][12] = 42, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_KCC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, + [2][1][RTW89_CHILE][13] = 127, + [2][1][RTW89_UKRAINE][13] = 127, + [2][1][RTW89_MEXICO][13] = 127, + [2][1][RTW89_CN][13] = 127, + [2][1][RTW89_QATAR][13] = 127, + [2][1][RTW89_UK][13] = 127, +}; + +static +const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 24, + [0][0][RTW89_WW][2] = 24, + [0][0][RTW89_WW][4] = 24, + [0][0][RTW89_WW][6] = 12, + [0][0][RTW89_WW][8] = 24, + [0][0][RTW89_WW][10] = 24, + [0][0][RTW89_WW][12] = 24, + [0][0][RTW89_WW][14] = 24, + [0][0][RTW89_WW][15] = 24, + [0][0][RTW89_WW][17] = 24, + [0][0][RTW89_WW][19] = 24, + [0][0][RTW89_WW][21] = 24, + [0][0][RTW89_WW][23] = 24, + [0][0][RTW89_WW][25] = 24, + [0][0][RTW89_WW][27] = 24, + [0][0][RTW89_WW][29] = 24, + [0][0][RTW89_WW][31] = 24, + [0][0][RTW89_WW][33] = 24, + [0][0][RTW89_WW][35] = 24, + [0][0][RTW89_WW][37] = 44, + [0][0][RTW89_WW][38] = 26, + [0][0][RTW89_WW][40] = 26, + [0][0][RTW89_WW][42] = 26, + [0][0][RTW89_WW][44] = 26, + [0][0][RTW89_WW][46] = 26, + [0][0][RTW89_WW][48] = 32, + [0][0][RTW89_WW][50] = 32, + [0][0][RTW89_WW][52] = 32, + [0][1][RTW89_WW][0] = 1, + [0][1][RTW89_WW][2] = 4, + [0][1][RTW89_WW][4] = 1, + [0][1][RTW89_WW][6] = 1, + [0][1][RTW89_WW][8] = 12, + [0][1][RTW89_WW][10] = 12, + [0][1][RTW89_WW][12] = 12, + [0][1][RTW89_WW][14] = 12, + [0][1][RTW89_WW][15] = 12, + [0][1][RTW89_WW][17] = 12, + [0][1][RTW89_WW][19] = 12, + [0][1][RTW89_WW][21] = 12, + [0][1][RTW89_WW][23] = 12, + [0][1][RTW89_WW][25] = 12, + [0][1][RTW89_WW][27] = 12, + [0][1][RTW89_WW][29] = 12, + [0][1][RTW89_WW][31] = 12, + [0][1][RTW89_WW][33] = 12, + [0][1][RTW89_WW][35] = 12, + [0][1][RTW89_WW][37] = 30, + [0][1][RTW89_WW][38] = 14, + [0][1][RTW89_WW][40] = 14, + [0][1][RTW89_WW][42] = 14, + [0][1][RTW89_WW][44] = 14, + [0][1][RTW89_WW][46] = 14, + [0][1][RTW89_WW][48] = 16, + [0][1][RTW89_WW][50] = 16, + [0][1][RTW89_WW][52] = 16, + [1][0][RTW89_WW][0] = 34, + [1][0][RTW89_WW][2] = 34, + [1][0][RTW89_WW][4] = 34, + [1][0][RTW89_WW][6] = 26, + [1][0][RTW89_WW][8] = 34, + [1][0][RTW89_WW][10] = 34, + [1][0][RTW89_WW][12] = 34, + [1][0][RTW89_WW][14] = 34, + [1][0][RTW89_WW][15] = 34, + [1][0][RTW89_WW][17] = 34, + [1][0][RTW89_WW][19] = 34, + [1][0][RTW89_WW][21] = 34, + [1][0][RTW89_WW][23] = 34, + [1][0][RTW89_WW][25] = 34, + [1][0][RTW89_WW][27] = 34, + [1][0][RTW89_WW][29] = 34, + [1][0][RTW89_WW][31] = 34, + [1][0][RTW89_WW][33] = 34, + [1][0][RTW89_WW][35] = 34, + [1][0][RTW89_WW][37] = 52, + [1][0][RTW89_WW][38] = 28, + [1][0][RTW89_WW][40] = 28, + [1][0][RTW89_WW][42] = 28, + [1][0][RTW89_WW][44] = 28, + [1][0][RTW89_WW][46] = 28, + [1][0][RTW89_WW][48] = 44, + [1][0][RTW89_WW][50] = 44, + [1][0][RTW89_WW][52] = 44, + [1][1][RTW89_WW][0] = 10, + [1][1][RTW89_WW][2] = 14, + [1][1][RTW89_WW][4] = 10, + [1][1][RTW89_WW][6] = 10, + [1][1][RTW89_WW][8] = 20, + [1][1][RTW89_WW][10] = 20, + [1][1][RTW89_WW][12] = 22, + [1][1][RTW89_WW][14] = 22, + [1][1][RTW89_WW][15] = 22, + [1][1][RTW89_WW][17] = 22, + [1][1][RTW89_WW][19] = 22, + [1][1][RTW89_WW][21] = 22, + [1][1][RTW89_WW][23] = 22, + [1][1][RTW89_WW][25] = 22, + [1][1][RTW89_WW][27] = 22, + [1][1][RTW89_WW][29] = 22, + [1][1][RTW89_WW][31] = 22, + [1][1][RTW89_WW][33] = 22, + [1][1][RTW89_WW][35] = 22, + [1][1][RTW89_WW][37] = 38, + [1][1][RTW89_WW][38] = 16, + [1][1][RTW89_WW][40] = 16, + [1][1][RTW89_WW][42] = 16, + [1][1][RTW89_WW][44] = 16, + [1][1][RTW89_WW][46] = 16, + [1][1][RTW89_WW][48] = 28, + [1][1][RTW89_WW][50] = 30, + [1][1][RTW89_WW][52] = 30, + [2][0][RTW89_WW][0] = 44, + [2][0][RTW89_WW][2] = 44, + [2][0][RTW89_WW][4] = 44, + [2][0][RTW89_WW][6] = 38, + [2][0][RTW89_WW][8] = 48, + [2][0][RTW89_WW][10] = 48, + [2][0][RTW89_WW][12] = 46, + [2][0][RTW89_WW][14] = 46, + [2][0][RTW89_WW][15] = 48, + [2][0][RTW89_WW][17] = 48, + [2][0][RTW89_WW][19] = 48, + [2][0][RTW89_WW][21] = 48, + [2][0][RTW89_WW][23] = 48, + [2][0][RTW89_WW][25] = 48, + [2][0][RTW89_WW][27] = 48, + [2][0][RTW89_WW][29] = 48, + [2][0][RTW89_WW][31] = 48, + [2][0][RTW89_WW][33] = 48, + [2][0][RTW89_WW][35] = 48, + [2][0][RTW89_WW][37] = 64, + [2][0][RTW89_WW][38] = 28, + [2][0][RTW89_WW][40] = 28, + [2][0][RTW89_WW][42] = 28, + [2][0][RTW89_WW][44] = 28, + [2][0][RTW89_WW][46] = 28, + [2][0][RTW89_WW][48] = 56, + [2][0][RTW89_WW][50] = 56, + [2][0][RTW89_WW][52] = 56, + [2][1][RTW89_WW][0] = 20, + [2][1][RTW89_WW][2] = 18, + [2][1][RTW89_WW][4] = 22, + [2][1][RTW89_WW][6] = 22, + [2][1][RTW89_WW][8] = 34, + [2][1][RTW89_WW][10] = 34, + [2][1][RTW89_WW][12] = 36, + [2][1][RTW89_WW][14] = 36, + [2][1][RTW89_WW][15] = 36, + [2][1][RTW89_WW][17] = 36, + [2][1][RTW89_WW][19] = 36, + [2][1][RTW89_WW][21] = 36, + [2][1][RTW89_WW][23] = 36, + [2][1][RTW89_WW][25] = 36, + [2][1][RTW89_WW][27] = 36, + [2][1][RTW89_WW][29] = 36, + [2][1][RTW89_WW][31] = 36, + [2][1][RTW89_WW][33] = 36, + [2][1][RTW89_WW][35] = 36, + [2][1][RTW89_WW][37] = 48, + [2][1][RTW89_WW][38] = 16, + [2][1][RTW89_WW][40] = 16, + [2][1][RTW89_WW][42] = 16, + [2][1][RTW89_WW][44] = 16, + [2][1][RTW89_WW][46] = 16, + [2][1][RTW89_WW][48] = 40, + [2][1][RTW89_WW][50] = 40, + [2][1][RTW89_WW][52] = 40, + [0][0][RTW89_FCC][0] = 52, + [0][0][RTW89_ETSI][0] = 24, + [0][0][RTW89_MKK][0] = 26, + [0][0][RTW89_IC][0] = 24, + [0][0][RTW89_KCC][0] = 44, + [0][0][RTW89_ACMA][0] = 24, + [0][0][RTW89_CHILE][0] = 40, + [0][0][RTW89_UKRAINE][0] = 24, + [0][0][RTW89_MEXICO][0] = 52, + [0][0][RTW89_CN][0] = 24, + [0][0][RTW89_QATAR][0] = 24, + [0][0][RTW89_UK][0] = 24, + [0][0][RTW89_FCC][2] = 52, + [0][0][RTW89_ETSI][2] = 24, + [0][0][RTW89_MKK][2] = 26, + [0][0][RTW89_IC][2] = 24, + [0][0][RTW89_KCC][2] = 44, + [0][0][RTW89_ACMA][2] = 24, + [0][0][RTW89_CHILE][2] = 38, + [0][0][RTW89_UKRAINE][2] = 24, + [0][0][RTW89_MEXICO][2] = 52, + [0][0][RTW89_CN][2] = 24, + [0][0][RTW89_QATAR][2] = 24, + [0][0][RTW89_UK][2] = 24, + [0][0][RTW89_FCC][4] = 52, + [0][0][RTW89_ETSI][4] = 24, + [0][0][RTW89_MKK][4] = 26, + [0][0][RTW89_IC][4] = 24, + [0][0][RTW89_KCC][4] = 44, + [0][0][RTW89_ACMA][4] = 24, + [0][0][RTW89_CHILE][4] = 38, + [0][0][RTW89_UKRAINE][4] = 24, + [0][0][RTW89_MEXICO][4] = 52, + [0][0][RTW89_CN][4] = 24, + [0][0][RTW89_QATAR][4] = 24, + [0][0][RTW89_UK][4] = 24, + [0][0][RTW89_FCC][6] = 52, + [0][0][RTW89_ETSI][6] = 24, + [0][0][RTW89_MKK][6] = 26, + [0][0][RTW89_IC][6] = 24, + [0][0][RTW89_KCC][6] = 12, + [0][0][RTW89_ACMA][6] = 24, + [0][0][RTW89_CHILE][6] = 40, + [0][0][RTW89_UKRAINE][6] = 24, + [0][0][RTW89_MEXICO][6] = 52, + [0][0][RTW89_CN][6] = 24, + [0][0][RTW89_QATAR][6] = 24, + [0][0][RTW89_UK][6] = 24, + [0][0][RTW89_FCC][8] = 52, + [0][0][RTW89_ETSI][8] = 24, + [0][0][RTW89_MKK][8] = 26, + [0][0][RTW89_IC][8] = 52, + [0][0][RTW89_KCC][8] = 46, + [0][0][RTW89_ACMA][8] = 24, + [0][0][RTW89_CHILE][8] = 64, + [0][0][RTW89_UKRAINE][8] = 24, + [0][0][RTW89_MEXICO][8] = 52, + [0][0][RTW89_CN][8] = 24, + [0][0][RTW89_QATAR][8] = 24, + [0][0][RTW89_UK][8] = 24, + [0][0][RTW89_FCC][10] = 52, + [0][0][RTW89_ETSI][10] = 24, + [0][0][RTW89_MKK][10] = 26, + [0][0][RTW89_IC][10] = 52, + [0][0][RTW89_KCC][10] = 46, + [0][0][RTW89_ACMA][10] = 24, + [0][0][RTW89_CHILE][10] = 64, + [0][0][RTW89_UKRAINE][10] = 24, + [0][0][RTW89_MEXICO][10] = 52, + [0][0][RTW89_CN][10] = 24, + [0][0][RTW89_QATAR][10] = 24, + [0][0][RTW89_UK][10] = 24, + [0][0][RTW89_FCC][12] = 52, + [0][0][RTW89_ETSI][12] = 24, + [0][0][RTW89_MKK][12] = 24, + [0][0][RTW89_IC][12] = 52, + [0][0][RTW89_KCC][12] = 42, + [0][0][RTW89_ACMA][12] = 24, + [0][0][RTW89_CHILE][12] = 64, + [0][0][RTW89_UKRAINE][12] = 24, + [0][0][RTW89_MEXICO][12] = 52, + [0][0][RTW89_CN][12] = 24, + [0][0][RTW89_QATAR][12] = 24, + [0][0][RTW89_UK][12] = 24, + [0][0][RTW89_FCC][14] = 52, + [0][0][RTW89_ETSI][14] = 24, + [0][0][RTW89_MKK][14] = 24, + [0][0][RTW89_IC][14] = 52, + [0][0][RTW89_KCC][14] = 42, + [0][0][RTW89_ACMA][14] = 24, + [0][0][RTW89_CHILE][14] = 64, + [0][0][RTW89_UKRAINE][14] = 24, + [0][0][RTW89_MEXICO][14] = 52, + [0][0][RTW89_CN][14] = 24, + [0][0][RTW89_QATAR][14] = 24, + [0][0][RTW89_UK][14] = 24, + [0][0][RTW89_FCC][15] = 52, + [0][0][RTW89_ETSI][15] = 24, + [0][0][RTW89_MKK][15] = 46, + [0][0][RTW89_IC][15] = 52, + [0][0][RTW89_KCC][15] = 44, + [0][0][RTW89_ACMA][15] = 24, + [0][0][RTW89_CHILE][15] = 60, + [0][0][RTW89_UKRAINE][15] = 24, + [0][0][RTW89_MEXICO][15] = 52, + [0][0][RTW89_CN][15] = 127, + [0][0][RTW89_QATAR][15] = 24, + [0][0][RTW89_UK][15] = 24, + [0][0][RTW89_FCC][17] = 52, + [0][0][RTW89_ETSI][17] = 24, + [0][0][RTW89_MKK][17] = 48, + [0][0][RTW89_IC][17] = 52, + [0][0][RTW89_KCC][17] = 44, + [0][0][RTW89_ACMA][17] = 24, + [0][0][RTW89_CHILE][17] = 60, + [0][0][RTW89_UKRAINE][17] = 24, + [0][0][RTW89_MEXICO][17] = 52, + [0][0][RTW89_CN][17] = 127, + [0][0][RTW89_QATAR][17] = 24, + [0][0][RTW89_UK][17] = 24, + [0][0][RTW89_FCC][19] = 52, + [0][0][RTW89_ETSI][19] = 24, + [0][0][RTW89_MKK][19] = 48, + [0][0][RTW89_IC][19] = 52, + [0][0][RTW89_KCC][19] = 44, + [0][0][RTW89_ACMA][19] = 24, + [0][0][RTW89_CHILE][19] = 60, + [0][0][RTW89_UKRAINE][19] = 24, + [0][0][RTW89_MEXICO][19] = 52, + [0][0][RTW89_CN][19] = 127, + [0][0][RTW89_QATAR][19] = 24, + [0][0][RTW89_UK][19] = 24, + [0][0][RTW89_FCC][21] = 52, + [0][0][RTW89_ETSI][21] = 24, + [0][0][RTW89_MKK][21] = 48, + [0][0][RTW89_IC][21] = 52, + [0][0][RTW89_KCC][21] = 44, + [0][0][RTW89_ACMA][21] = 24, + [0][0][RTW89_CHILE][21] = 62, + [0][0][RTW89_UKRAINE][21] = 24, + [0][0][RTW89_MEXICO][21] = 52, + [0][0][RTW89_CN][21] = 127, + [0][0][RTW89_QATAR][21] = 24, + [0][0][RTW89_UK][21] = 24, + [0][0][RTW89_FCC][23] = 52, + [0][0][RTW89_ETSI][23] = 24, + [0][0][RTW89_MKK][23] = 48, + [0][0][RTW89_IC][23] = 52, + [0][0][RTW89_KCC][23] = 44, + [0][0][RTW89_ACMA][23] = 24, + [0][0][RTW89_CHILE][23] = 62, + [0][0][RTW89_UKRAINE][23] = 24, + [0][0][RTW89_MEXICO][23] = 52, + [0][0][RTW89_CN][23] = 127, + [0][0][RTW89_QATAR][23] = 24, + [0][0][RTW89_UK][23] = 24, + [0][0][RTW89_FCC][25] = 52, + [0][0][RTW89_ETSI][25] = 24, + [0][0][RTW89_MKK][25] = 48, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_KCC][25] = 44, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_CHILE][25] = 62, + [0][0][RTW89_UKRAINE][25] = 24, + [0][0][RTW89_MEXICO][25] = 52, + [0][0][RTW89_CN][25] = 127, + [0][0][RTW89_QATAR][25] = 24, + [0][0][RTW89_UK][25] = 24, + [0][0][RTW89_FCC][27] = 52, + [0][0][RTW89_ETSI][27] = 24, + [0][0][RTW89_MKK][27] = 48, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_KCC][27] = 44, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_CHILE][27] = 62, + [0][0][RTW89_UKRAINE][27] = 24, + [0][0][RTW89_MEXICO][27] = 52, + [0][0][RTW89_CN][27] = 127, + [0][0][RTW89_QATAR][27] = 24, + [0][0][RTW89_UK][27] = 24, + [0][0][RTW89_FCC][29] = 52, + [0][0][RTW89_ETSI][29] = 24, + [0][0][RTW89_MKK][29] = 48, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_KCC][29] = 44, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_CHILE][29] = 60, + [0][0][RTW89_UKRAINE][29] = 24, + [0][0][RTW89_MEXICO][29] = 52, + [0][0][RTW89_CN][29] = 127, + [0][0][RTW89_QATAR][29] = 24, + [0][0][RTW89_UK][29] = 24, + [0][0][RTW89_FCC][31] = 52, + [0][0][RTW89_ETSI][31] = 24, + [0][0][RTW89_MKK][31] = 48, + [0][0][RTW89_IC][31] = 52, + [0][0][RTW89_KCC][31] = 44, + [0][0][RTW89_ACMA][31] = 24, + [0][0][RTW89_CHILE][31] = 60, + [0][0][RTW89_UKRAINE][31] = 24, + [0][0][RTW89_MEXICO][31] = 52, + [0][0][RTW89_CN][31] = 127, + [0][0][RTW89_QATAR][31] = 24, + [0][0][RTW89_UK][31] = 24, + [0][0][RTW89_FCC][33] = 52, + [0][0][RTW89_ETSI][33] = 24, + [0][0][RTW89_MKK][33] = 48, + [0][0][RTW89_IC][33] = 52, + [0][0][RTW89_KCC][33] = 44, + [0][0][RTW89_ACMA][33] = 24, + [0][0][RTW89_CHILE][33] = 60, + [0][0][RTW89_UKRAINE][33] = 24, + [0][0][RTW89_MEXICO][33] = 52, + [0][0][RTW89_CN][33] = 127, + [0][0][RTW89_QATAR][33] = 24, + [0][0][RTW89_UK][33] = 24, + [0][0][RTW89_FCC][35] = 52, + [0][0][RTW89_ETSI][35] = 24, + [0][0][RTW89_MKK][35] = 48, + [0][0][RTW89_IC][35] = 52, + [0][0][RTW89_KCC][35] = 44, + [0][0][RTW89_ACMA][35] = 24, + [0][0][RTW89_CHILE][35] = 60, + [0][0][RTW89_UKRAINE][35] = 24, + [0][0][RTW89_MEXICO][35] = 52, + [0][0][RTW89_CN][35] = 127, + [0][0][RTW89_QATAR][35] = 24, + [0][0][RTW89_UK][35] = 24, + [0][0][RTW89_FCC][37] = 52, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 44, + [0][0][RTW89_IC][37] = 52, + [0][0][RTW89_KCC][37] = 44, + [0][0][RTW89_ACMA][37] = 52, + [0][0][RTW89_CHILE][37] = 62, + [0][0][RTW89_UKRAINE][37] = 127, + [0][0][RTW89_MEXICO][37] = 52, + [0][0][RTW89_CN][37] = 127, + [0][0][RTW89_QATAR][37] = 127, + [0][0][RTW89_UK][37] = 56, + [0][0][RTW89_FCC][38] = 84, + [0][0][RTW89_ETSI][38] = 28, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 84, + [0][0][RTW89_KCC][38] = 44, + [0][0][RTW89_ACMA][38] = 84, + [0][0][RTW89_CHILE][38] = 60, + [0][0][RTW89_UKRAINE][38] = 28, + [0][0][RTW89_MEXICO][38] = 84, + [0][0][RTW89_CN][38] = 62, + [0][0][RTW89_QATAR][38] = 28, + [0][0][RTW89_UK][38] = 26, + [0][0][RTW89_FCC][40] = 84, + [0][0][RTW89_ETSI][40] = 28, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 84, + [0][0][RTW89_KCC][40] = 44, + [0][0][RTW89_ACMA][40] = 84, + [0][0][RTW89_CHILE][40] = 60, + [0][0][RTW89_UKRAINE][40] = 28, + [0][0][RTW89_MEXICO][40] = 84, + [0][0][RTW89_CN][40] = 62, + [0][0][RTW89_QATAR][40] = 28, + [0][0][RTW89_UK][40] = 26, + [0][0][RTW89_FCC][42] = 84, + [0][0][RTW89_ETSI][42] = 28, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 84, + [0][0][RTW89_KCC][42] = 44, + [0][0][RTW89_ACMA][42] = 84, + [0][0][RTW89_CHILE][42] = 64, + [0][0][RTW89_UKRAINE][42] = 28, + [0][0][RTW89_MEXICO][42] = 84, + [0][0][RTW89_CN][42] = 62, + [0][0][RTW89_QATAR][42] = 28, + [0][0][RTW89_UK][42] = 26, + [0][0][RTW89_FCC][44] = 84, + [0][0][RTW89_ETSI][44] = 28, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 84, + [0][0][RTW89_KCC][44] = 44, + [0][0][RTW89_ACMA][44] = 84, + [0][0][RTW89_CHILE][44] = 60, + [0][0][RTW89_UKRAINE][44] = 28, + [0][0][RTW89_MEXICO][44] = 84, + [0][0][RTW89_CN][44] = 62, + [0][0][RTW89_QATAR][44] = 28, + [0][0][RTW89_UK][44] = 26, + [0][0][RTW89_FCC][46] = 84, + [0][0][RTW89_ETSI][46] = 28, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 84, + [0][0][RTW89_KCC][46] = 44, + [0][0][RTW89_ACMA][46] = 84, + [0][0][RTW89_CHILE][46] = 60, + [0][0][RTW89_UKRAINE][46] = 28, + [0][0][RTW89_MEXICO][46] = 84, + [0][0][RTW89_CN][46] = 62, + [0][0][RTW89_QATAR][46] = 28, + [0][0][RTW89_UK][46] = 26, + [0][0][RTW89_FCC][48] = 32, + [0][0][RTW89_ETSI][48] = 127, + [0][0][RTW89_MKK][48] = 127, + [0][0][RTW89_IC][48] = 42, + [0][0][RTW89_KCC][48] = 127, + [0][0][RTW89_ACMA][48] = 127, + [0][0][RTW89_CHILE][48] = 127, + [0][0][RTW89_UKRAINE][48] = 127, + [0][0][RTW89_MEXICO][48] = 127, + [0][0][RTW89_CN][48] = 127, + [0][0][RTW89_QATAR][48] = 127, + [0][0][RTW89_UK][48] = 127, + [0][0][RTW89_FCC][50] = 32, + [0][0][RTW89_ETSI][50] = 127, + [0][0][RTW89_MKK][50] = 127, + [0][0][RTW89_IC][50] = 42, + [0][0][RTW89_KCC][50] = 127, + [0][0][RTW89_ACMA][50] = 127, + [0][0][RTW89_CHILE][50] = 127, + [0][0][RTW89_UKRAINE][50] = 127, + [0][0][RTW89_MEXICO][50] = 127, + [0][0][RTW89_CN][50] = 127, + [0][0][RTW89_QATAR][50] = 127, + [0][0][RTW89_UK][50] = 127, + [0][0][RTW89_FCC][52] = 32, + [0][0][RTW89_ETSI][52] = 127, + [0][0][RTW89_MKK][52] = 127, + [0][0][RTW89_IC][52] = 40, + [0][0][RTW89_KCC][52] = 127, + [0][0][RTW89_ACMA][52] = 127, + [0][0][RTW89_CHILE][52] = 127, + [0][0][RTW89_UKRAINE][52] = 127, + [0][0][RTW89_MEXICO][52] = 127, + [0][0][RTW89_CN][52] = 127, + [0][0][RTW89_QATAR][52] = 127, + [0][0][RTW89_UK][52] = 127, + [0][1][RTW89_FCC][0] = 34, + [0][1][RTW89_ETSI][0] = 12, + [0][1][RTW89_MKK][0] = 12, + [0][1][RTW89_IC][0] = 1, + [0][1][RTW89_KCC][0] = 28, + [0][1][RTW89_ACMA][0] = 12, + [0][1][RTW89_CHILE][0] = 14, + [0][1][RTW89_UKRAINE][0] = 12, + [0][1][RTW89_MEXICO][0] = 34, + [0][1][RTW89_CN][0] = 12, + [0][1][RTW89_QATAR][0] = 12, + [0][1][RTW89_UK][0] = 12, + [0][1][RTW89_FCC][2] = 38, + [0][1][RTW89_ETSI][2] = 12, + [0][1][RTW89_MKK][2] = 12, + [0][1][RTW89_IC][2] = 4, + [0][1][RTW89_KCC][2] = 28, + [0][1][RTW89_ACMA][2] = 12, + [0][1][RTW89_CHILE][2] = 12, + [0][1][RTW89_UKRAINE][2] = 12, + [0][1][RTW89_MEXICO][2] = 38, + [0][1][RTW89_CN][2] = 12, + [0][1][RTW89_QATAR][2] = 12, + [0][1][RTW89_UK][2] = 12, + [0][1][RTW89_FCC][4] = 34, + [0][1][RTW89_ETSI][4] = 12, + [0][1][RTW89_MKK][4] = 14, + [0][1][RTW89_IC][4] = 1, + [0][1][RTW89_KCC][4] = 28, + [0][1][RTW89_ACMA][4] = 12, + [0][1][RTW89_CHILE][4] = 12, + [0][1][RTW89_UKRAINE][4] = 12, + [0][1][RTW89_MEXICO][4] = 34, + [0][1][RTW89_CN][4] = 12, + [0][1][RTW89_QATAR][4] = 12, + [0][1][RTW89_UK][4] = 12, + [0][1][RTW89_FCC][6] = 34, + [0][1][RTW89_ETSI][6] = 12, + [0][1][RTW89_MKK][6] = 14, + [0][1][RTW89_IC][6] = 1, + [0][1][RTW89_KCC][6] = 2, + [0][1][RTW89_ACMA][6] = 12, + [0][1][RTW89_CHILE][6] = 12, + [0][1][RTW89_UKRAINE][6] = 12, + [0][1][RTW89_MEXICO][6] = 34, + [0][1][RTW89_CN][6] = 12, + [0][1][RTW89_QATAR][6] = 12, + [0][1][RTW89_UK][6] = 12, + [0][1][RTW89_FCC][8] = 34, + [0][1][RTW89_ETSI][8] = 12, + [0][1][RTW89_MKK][8] = 14, + [0][1][RTW89_IC][8] = 34, + [0][1][RTW89_KCC][8] = 30, + [0][1][RTW89_ACMA][8] = 12, + [0][1][RTW89_CHILE][8] = 50, + [0][1][RTW89_UKRAINE][8] = 12, + [0][1][RTW89_MEXICO][8] = 34, + [0][1][RTW89_CN][8] = 12, + [0][1][RTW89_QATAR][8] = 12, + [0][1][RTW89_UK][8] = 12, + [0][1][RTW89_FCC][10] = 34, + [0][1][RTW89_ETSI][10] = 12, + [0][1][RTW89_MKK][10] = 14, + [0][1][RTW89_IC][10] = 34, + [0][1][RTW89_KCC][10] = 30, + [0][1][RTW89_ACMA][10] = 12, + [0][1][RTW89_CHILE][10] = 50, + [0][1][RTW89_UKRAINE][10] = 12, + [0][1][RTW89_MEXICO][10] = 34, + [0][1][RTW89_CN][10] = 12, + [0][1][RTW89_QATAR][10] = 12, + [0][1][RTW89_UK][10] = 12, + [0][1][RTW89_FCC][12] = 38, + [0][1][RTW89_ETSI][12] = 12, + [0][1][RTW89_MKK][12] = 12, + [0][1][RTW89_IC][12] = 38, + [0][1][RTW89_KCC][12] = 30, + [0][1][RTW89_ACMA][12] = 12, + [0][1][RTW89_CHILE][12] = 50, + [0][1][RTW89_UKRAINE][12] = 12, + [0][1][RTW89_MEXICO][12] = 38, + [0][1][RTW89_CN][12] = 12, + [0][1][RTW89_QATAR][12] = 12, + [0][1][RTW89_UK][12] = 12, + [0][1][RTW89_FCC][14] = 34, + [0][1][RTW89_ETSI][14] = 12, + [0][1][RTW89_MKK][14] = 12, + [0][1][RTW89_IC][14] = 34, + [0][1][RTW89_KCC][14] = 30, + [0][1][RTW89_ACMA][14] = 12, + [0][1][RTW89_CHILE][14] = 48, + [0][1][RTW89_UKRAINE][14] = 12, + [0][1][RTW89_MEXICO][14] = 34, + [0][1][RTW89_CN][14] = 12, + [0][1][RTW89_QATAR][14] = 12, + [0][1][RTW89_UK][14] = 12, + [0][1][RTW89_FCC][15] = 34, + [0][1][RTW89_ETSI][15] = 12, + [0][1][RTW89_MKK][15] = 32, + [0][1][RTW89_IC][15] = 34, + [0][1][RTW89_KCC][15] = 30, + [0][1][RTW89_ACMA][15] = 12, + [0][1][RTW89_CHILE][15] = 52, + [0][1][RTW89_UKRAINE][15] = 12, + [0][1][RTW89_MEXICO][15] = 34, + [0][1][RTW89_CN][15] = 127, + [0][1][RTW89_QATAR][15] = 12, + [0][1][RTW89_UK][15] = 12, + [0][1][RTW89_FCC][17] = 34, + [0][1][RTW89_ETSI][17] = 12, + [0][1][RTW89_MKK][17] = 34, + [0][1][RTW89_IC][17] = 34, + [0][1][RTW89_KCC][17] = 30, + [0][1][RTW89_ACMA][17] = 12, + [0][1][RTW89_CHILE][17] = 52, + [0][1][RTW89_UKRAINE][17] = 12, + [0][1][RTW89_MEXICO][17] = 34, + [0][1][RTW89_CN][17] = 127, + [0][1][RTW89_QATAR][17] = 12, + [0][1][RTW89_UK][17] = 12, + [0][1][RTW89_FCC][19] = 38, + [0][1][RTW89_ETSI][19] = 12, + [0][1][RTW89_MKK][19] = 34, + [0][1][RTW89_IC][19] = 38, + [0][1][RTW89_KCC][19] = 30, + [0][1][RTW89_ACMA][19] = 12, + [0][1][RTW89_CHILE][19] = 52, + [0][1][RTW89_UKRAINE][19] = 12, + [0][1][RTW89_MEXICO][19] = 38, + [0][1][RTW89_CN][19] = 127, + [0][1][RTW89_QATAR][19] = 12, + [0][1][RTW89_UK][19] = 12, + [0][1][RTW89_FCC][21] = 38, + [0][1][RTW89_ETSI][21] = 12, + [0][1][RTW89_MKK][21] = 34, + [0][1][RTW89_IC][21] = 38, + [0][1][RTW89_KCC][21] = 30, + [0][1][RTW89_ACMA][21] = 12, + [0][1][RTW89_CHILE][21] = 52, + [0][1][RTW89_UKRAINE][21] = 12, + [0][1][RTW89_MEXICO][21] = 38, + [0][1][RTW89_CN][21] = 127, + [0][1][RTW89_QATAR][21] = 12, + [0][1][RTW89_UK][21] = 12, + [0][1][RTW89_FCC][23] = 38, + [0][1][RTW89_ETSI][23] = 12, + [0][1][RTW89_MKK][23] = 34, + [0][1][RTW89_IC][23] = 38, + [0][1][RTW89_KCC][23] = 30, + [0][1][RTW89_ACMA][23] = 12, + [0][1][RTW89_CHILE][23] = 52, + [0][1][RTW89_UKRAINE][23] = 12, + [0][1][RTW89_MEXICO][23] = 38, + [0][1][RTW89_CN][23] = 127, + [0][1][RTW89_QATAR][23] = 12, + [0][1][RTW89_UK][23] = 12, + [0][1][RTW89_FCC][25] = 38, + [0][1][RTW89_ETSI][25] = 12, + [0][1][RTW89_MKK][25] = 34, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_KCC][25] = 30, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_CHILE][25] = 52, + [0][1][RTW89_UKRAINE][25] = 12, + [0][1][RTW89_MEXICO][25] = 38, + [0][1][RTW89_CN][25] = 127, + [0][1][RTW89_QATAR][25] = 12, + [0][1][RTW89_UK][25] = 12, + [0][1][RTW89_FCC][27] = 38, + [0][1][RTW89_ETSI][27] = 12, + [0][1][RTW89_MKK][27] = 34, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_KCC][27] = 30, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_CHILE][27] = 52, + [0][1][RTW89_UKRAINE][27] = 12, + [0][1][RTW89_MEXICO][27] = 38, + [0][1][RTW89_CN][27] = 127, + [0][1][RTW89_QATAR][27] = 12, + [0][1][RTW89_UK][27] = 12, + [0][1][RTW89_FCC][29] = 38, + [0][1][RTW89_ETSI][29] = 12, + [0][1][RTW89_MKK][29] = 34, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_KCC][29] = 30, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_CHILE][29] = 52, + [0][1][RTW89_UKRAINE][29] = 12, + [0][1][RTW89_MEXICO][29] = 38, + [0][1][RTW89_CN][29] = 127, + [0][1][RTW89_QATAR][29] = 12, + [0][1][RTW89_UK][29] = 12, + [0][1][RTW89_FCC][31] = 38, + [0][1][RTW89_ETSI][31] = 12, + [0][1][RTW89_MKK][31] = 34, + [0][1][RTW89_IC][31] = 34, + [0][1][RTW89_KCC][31] = 30, + [0][1][RTW89_ACMA][31] = 12, + [0][1][RTW89_CHILE][31] = 52, + [0][1][RTW89_UKRAINE][31] = 12, + [0][1][RTW89_MEXICO][31] = 38, + [0][1][RTW89_CN][31] = 127, + [0][1][RTW89_QATAR][31] = 12, + [0][1][RTW89_UK][31] = 12, + [0][1][RTW89_FCC][33] = 34, + [0][1][RTW89_ETSI][33] = 12, + [0][1][RTW89_MKK][33] = 34, + [0][1][RTW89_IC][33] = 34, + [0][1][RTW89_KCC][33] = 30, + [0][1][RTW89_ACMA][33] = 12, + [0][1][RTW89_CHILE][33] = 52, + [0][1][RTW89_UKRAINE][33] = 12, + [0][1][RTW89_MEXICO][33] = 34, + [0][1][RTW89_CN][33] = 127, + [0][1][RTW89_QATAR][33] = 12, + [0][1][RTW89_UK][33] = 12, + [0][1][RTW89_FCC][35] = 34, + [0][1][RTW89_ETSI][35] = 12, + [0][1][RTW89_MKK][35] = 34, + [0][1][RTW89_IC][35] = 34, + [0][1][RTW89_KCC][35] = 30, + [0][1][RTW89_ACMA][35] = 12, + [0][1][RTW89_CHILE][35] = 52, + [0][1][RTW89_UKRAINE][35] = 12, + [0][1][RTW89_MEXICO][35] = 34, + [0][1][RTW89_CN][35] = 127, + [0][1][RTW89_QATAR][35] = 12, + [0][1][RTW89_UK][35] = 12, + [0][1][RTW89_FCC][37] = 38, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 34, + [0][1][RTW89_IC][37] = 38, + [0][1][RTW89_KCC][37] = 30, + [0][1][RTW89_ACMA][37] = 38, + [0][1][RTW89_CHILE][37] = 52, + [0][1][RTW89_UKRAINE][37] = 127, + [0][1][RTW89_MEXICO][37] = 38, + [0][1][RTW89_CN][37] = 127, + [0][1][RTW89_QATAR][37] = 127, + [0][1][RTW89_UK][37] = 44, + [0][1][RTW89_FCC][38] = 82, + [0][1][RTW89_ETSI][38] = 16, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 82, + [0][1][RTW89_KCC][38] = 30, + [0][1][RTW89_ACMA][38] = 84, + [0][1][RTW89_CHILE][38] = 52, + [0][1][RTW89_UKRAINE][38] = 16, + [0][1][RTW89_MEXICO][38] = 82, + [0][1][RTW89_CN][38] = 50, + [0][1][RTW89_QATAR][38] = 16, + [0][1][RTW89_UK][38] = 14, + [0][1][RTW89_FCC][40] = 82, + [0][1][RTW89_ETSI][40] = 16, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 82, + [0][1][RTW89_KCC][40] = 30, + [0][1][RTW89_ACMA][40] = 84, + [0][1][RTW89_CHILE][40] = 52, + [0][1][RTW89_UKRAINE][40] = 16, + [0][1][RTW89_MEXICO][40] = 82, + [0][1][RTW89_CN][40] = 50, + [0][1][RTW89_QATAR][40] = 16, + [0][1][RTW89_UK][40] = 14, + [0][1][RTW89_FCC][42] = 82, + [0][1][RTW89_ETSI][42] = 16, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 82, + [0][1][RTW89_KCC][42] = 30, + [0][1][RTW89_ACMA][42] = 84, + [0][1][RTW89_CHILE][42] = 54, + [0][1][RTW89_UKRAINE][42] = 16, + [0][1][RTW89_MEXICO][42] = 82, + [0][1][RTW89_CN][42] = 50, + [0][1][RTW89_QATAR][42] = 16, + [0][1][RTW89_UK][42] = 14, + [0][1][RTW89_FCC][44] = 82, + [0][1][RTW89_ETSI][44] = 16, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 82, + [0][1][RTW89_KCC][44] = 30, + [0][1][RTW89_ACMA][44] = 84, + [0][1][RTW89_CHILE][44] = 54, + [0][1][RTW89_UKRAINE][44] = 16, + [0][1][RTW89_MEXICO][44] = 82, + [0][1][RTW89_CN][44] = 50, + [0][1][RTW89_QATAR][44] = 16, + [0][1][RTW89_UK][44] = 14, + [0][1][RTW89_FCC][46] = 82, + [0][1][RTW89_ETSI][46] = 16, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 82, + [0][1][RTW89_KCC][46] = 30, + [0][1][RTW89_ACMA][46] = 84, + [0][1][RTW89_CHILE][46] = 54, + [0][1][RTW89_UKRAINE][46] = 16, + [0][1][RTW89_MEXICO][46] = 82, + [0][1][RTW89_CN][46] = 50, + [0][1][RTW89_QATAR][46] = 16, + [0][1][RTW89_UK][46] = 14, + [0][1][RTW89_FCC][48] = 20, + [0][1][RTW89_ETSI][48] = 127, + [0][1][RTW89_MKK][48] = 127, + [0][1][RTW89_IC][48] = 16, + [0][1][RTW89_KCC][48] = 127, + [0][1][RTW89_ACMA][48] = 127, + [0][1][RTW89_CHILE][48] = 127, + [0][1][RTW89_UKRAINE][48] = 127, + [0][1][RTW89_MEXICO][48] = 127, + [0][1][RTW89_CN][48] = 127, + [0][1][RTW89_QATAR][48] = 127, + [0][1][RTW89_UK][48] = 127, + [0][1][RTW89_FCC][50] = 20, + [0][1][RTW89_ETSI][50] = 127, + [0][1][RTW89_MKK][50] = 127, + [0][1][RTW89_IC][50] = 16, + [0][1][RTW89_KCC][50] = 127, + [0][1][RTW89_ACMA][50] = 127, + [0][1][RTW89_CHILE][50] = 127, + [0][1][RTW89_UKRAINE][50] = 127, + [0][1][RTW89_MEXICO][50] = 127, + [0][1][RTW89_CN][50] = 127, + [0][1][RTW89_QATAR][50] = 127, + [0][1][RTW89_UK][50] = 127, + [0][1][RTW89_FCC][52] = 20, + [0][1][RTW89_ETSI][52] = 127, + [0][1][RTW89_MKK][52] = 127, + [0][1][RTW89_IC][52] = 16, + [0][1][RTW89_KCC][52] = 127, + [0][1][RTW89_ACMA][52] = 127, + [0][1][RTW89_CHILE][52] = 127, + [0][1][RTW89_UKRAINE][52] = 127, + [0][1][RTW89_MEXICO][52] = 127, + [0][1][RTW89_CN][52] = 127, + [0][1][RTW89_QATAR][52] = 127, + [0][1][RTW89_UK][52] = 127, + [1][0][RTW89_FCC][0] = 62, + [1][0][RTW89_ETSI][0] = 34, + [1][0][RTW89_MKK][0] = 36, + [1][0][RTW89_IC][0] = 36, + [1][0][RTW89_KCC][0] = 52, + [1][0][RTW89_ACMA][0] = 34, + [1][0][RTW89_CHILE][0] = 40, + [1][0][RTW89_UKRAINE][0] = 34, + [1][0][RTW89_MEXICO][0] = 62, + [1][0][RTW89_CN][0] = 34, + [1][0][RTW89_QATAR][0] = 34, + [1][0][RTW89_UK][0] = 34, + [1][0][RTW89_FCC][2] = 62, + [1][0][RTW89_ETSI][2] = 34, + [1][0][RTW89_MKK][2] = 36, + [1][0][RTW89_IC][2] = 36, + [1][0][RTW89_KCC][2] = 52, + [1][0][RTW89_ACMA][2] = 34, + [1][0][RTW89_CHILE][2] = 42, + [1][0][RTW89_UKRAINE][2] = 34, + [1][0][RTW89_MEXICO][2] = 62, + [1][0][RTW89_CN][2] = 34, + [1][0][RTW89_QATAR][2] = 34, + [1][0][RTW89_UK][2] = 34, + [1][0][RTW89_FCC][4] = 62, + [1][0][RTW89_ETSI][4] = 34, + [1][0][RTW89_MKK][4] = 34, + [1][0][RTW89_IC][4] = 36, + [1][0][RTW89_KCC][4] = 52, + [1][0][RTW89_ACMA][4] = 34, + [1][0][RTW89_CHILE][4] = 42, + [1][0][RTW89_UKRAINE][4] = 34, + [1][0][RTW89_MEXICO][4] = 62, + [1][0][RTW89_CN][4] = 34, + [1][0][RTW89_QATAR][4] = 34, + [1][0][RTW89_UK][4] = 34, + [1][0][RTW89_FCC][6] = 62, + [1][0][RTW89_ETSI][6] = 34, + [1][0][RTW89_MKK][6] = 34, + [1][0][RTW89_IC][6] = 36, + [1][0][RTW89_KCC][6] = 26, + [1][0][RTW89_ACMA][6] = 34, + [1][0][RTW89_CHILE][6] = 42, + [1][0][RTW89_UKRAINE][6] = 34, + [1][0][RTW89_MEXICO][6] = 62, + [1][0][RTW89_CN][6] = 34, + [1][0][RTW89_QATAR][6] = 34, + [1][0][RTW89_UK][6] = 34, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 34, + [1][0][RTW89_MKK][8] = 36, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_KCC][8] = 54, + [1][0][RTW89_ACMA][8] = 34, + [1][0][RTW89_CHILE][8] = 64, + [1][0][RTW89_UKRAINE][8] = 34, + [1][0][RTW89_MEXICO][8] = 62, + [1][0][RTW89_CN][8] = 34, + [1][0][RTW89_QATAR][8] = 34, + [1][0][RTW89_UK][8] = 34, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 34, + [1][0][RTW89_MKK][10] = 36, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_KCC][10] = 54, + [1][0][RTW89_ACMA][10] = 34, + [1][0][RTW89_CHILE][10] = 64, + [1][0][RTW89_UKRAINE][10] = 34, + [1][0][RTW89_MEXICO][10] = 62, + [1][0][RTW89_CN][10] = 34, + [1][0][RTW89_QATAR][10] = 34, + [1][0][RTW89_UK][10] = 34, + [1][0][RTW89_FCC][12] = 64, + [1][0][RTW89_ETSI][12] = 34, + [1][0][RTW89_MKK][12] = 36, + [1][0][RTW89_IC][12] = 64, + [1][0][RTW89_KCC][12] = 54, + [1][0][RTW89_ACMA][12] = 34, + [1][0][RTW89_CHILE][12] = 64, + [1][0][RTW89_UKRAINE][12] = 34, + [1][0][RTW89_MEXICO][12] = 64, + [1][0][RTW89_CN][12] = 34, + [1][0][RTW89_QATAR][12] = 34, + [1][0][RTW89_UK][12] = 34, + [1][0][RTW89_FCC][14] = 62, + [1][0][RTW89_ETSI][14] = 34, + [1][0][RTW89_MKK][14] = 36, + [1][0][RTW89_IC][14] = 62, + [1][0][RTW89_KCC][14] = 54, + [1][0][RTW89_ACMA][14] = 34, + [1][0][RTW89_CHILE][14] = 64, + [1][0][RTW89_UKRAINE][14] = 34, + [1][0][RTW89_MEXICO][14] = 62, + [1][0][RTW89_CN][14] = 34, + [1][0][RTW89_QATAR][14] = 34, + [1][0][RTW89_UK][14] = 34, + [1][0][RTW89_FCC][15] = 62, + [1][0][RTW89_ETSI][15] = 34, + [1][0][RTW89_MKK][15] = 54, + [1][0][RTW89_IC][15] = 62, + [1][0][RTW89_KCC][15] = 54, + [1][0][RTW89_ACMA][15] = 34, + [1][0][RTW89_CHILE][15] = 62, + [1][0][RTW89_UKRAINE][15] = 34, + [1][0][RTW89_MEXICO][15] = 62, + [1][0][RTW89_CN][15] = 127, + [1][0][RTW89_QATAR][15] = 34, + [1][0][RTW89_UK][15] = 34, + [1][0][RTW89_FCC][17] = 62, + [1][0][RTW89_ETSI][17] = 34, + [1][0][RTW89_MKK][17] = 58, + [1][0][RTW89_IC][17] = 62, + [1][0][RTW89_KCC][17] = 54, + [1][0][RTW89_ACMA][17] = 34, + [1][0][RTW89_CHILE][17] = 62, + [1][0][RTW89_UKRAINE][17] = 34, + [1][0][RTW89_MEXICO][17] = 62, + [1][0][RTW89_CN][17] = 127, + [1][0][RTW89_QATAR][17] = 34, + [1][0][RTW89_UK][17] = 34, + [1][0][RTW89_FCC][19] = 62, + [1][0][RTW89_ETSI][19] = 34, + [1][0][RTW89_MKK][19] = 58, + [1][0][RTW89_IC][19] = 62, + [1][0][RTW89_KCC][19] = 54, + [1][0][RTW89_ACMA][19] = 34, + [1][0][RTW89_CHILE][19] = 62, + [1][0][RTW89_UKRAINE][19] = 34, + [1][0][RTW89_MEXICO][19] = 62, + [1][0][RTW89_CN][19] = 127, + [1][0][RTW89_QATAR][19] = 34, + [1][0][RTW89_UK][19] = 34, + [1][0][RTW89_FCC][21] = 62, + [1][0][RTW89_ETSI][21] = 34, + [1][0][RTW89_MKK][21] = 58, + [1][0][RTW89_IC][21] = 62, + [1][0][RTW89_KCC][21] = 54, + [1][0][RTW89_ACMA][21] = 34, + [1][0][RTW89_CHILE][21] = 64, + [1][0][RTW89_UKRAINE][21] = 34, + [1][0][RTW89_MEXICO][21] = 62, + [1][0][RTW89_CN][21] = 127, + [1][0][RTW89_QATAR][21] = 34, + [1][0][RTW89_UK][21] = 34, + [1][0][RTW89_FCC][23] = 62, + [1][0][RTW89_ETSI][23] = 34, + [1][0][RTW89_MKK][23] = 58, + [1][0][RTW89_IC][23] = 62, + [1][0][RTW89_KCC][23] = 54, + [1][0][RTW89_ACMA][23] = 34, + [1][0][RTW89_CHILE][23] = 64, + [1][0][RTW89_UKRAINE][23] = 34, + [1][0][RTW89_MEXICO][23] = 62, + [1][0][RTW89_CN][23] = 127, + [1][0][RTW89_QATAR][23] = 34, + [1][0][RTW89_UK][23] = 34, + [1][0][RTW89_FCC][25] = 62, + [1][0][RTW89_ETSI][25] = 34, + [1][0][RTW89_MKK][25] = 58, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_KCC][25] = 54, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_CHILE][25] = 64, + [1][0][RTW89_UKRAINE][25] = 34, + [1][0][RTW89_MEXICO][25] = 62, + [1][0][RTW89_CN][25] = 127, + [1][0][RTW89_QATAR][25] = 34, + [1][0][RTW89_UK][25] = 34, + [1][0][RTW89_FCC][27] = 62, + [1][0][RTW89_ETSI][27] = 34, + [1][0][RTW89_MKK][27] = 58, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_KCC][27] = 54, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_CHILE][27] = 64, + [1][0][RTW89_UKRAINE][27] = 34, + [1][0][RTW89_MEXICO][27] = 62, + [1][0][RTW89_CN][27] = 127, + [1][0][RTW89_QATAR][27] = 34, + [1][0][RTW89_UK][27] = 34, + [1][0][RTW89_FCC][29] = 62, + [1][0][RTW89_ETSI][29] = 34, + [1][0][RTW89_MKK][29] = 58, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_KCC][29] = 54, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_CHILE][29] = 66, + [1][0][RTW89_UKRAINE][29] = 34, + [1][0][RTW89_MEXICO][29] = 62, + [1][0][RTW89_CN][29] = 127, + [1][0][RTW89_QATAR][29] = 34, + [1][0][RTW89_UK][29] = 34, + [1][0][RTW89_FCC][31] = 62, + [1][0][RTW89_ETSI][31] = 34, + [1][0][RTW89_MKK][31] = 58, + [1][0][RTW89_IC][31] = 62, + [1][0][RTW89_KCC][31] = 54, + [1][0][RTW89_ACMA][31] = 34, + [1][0][RTW89_CHILE][31] = 66, + [1][0][RTW89_UKRAINE][31] = 34, + [1][0][RTW89_MEXICO][31] = 62, + [1][0][RTW89_CN][31] = 127, + [1][0][RTW89_QATAR][31] = 34, + [1][0][RTW89_UK][31] = 34, + [1][0][RTW89_FCC][33] = 62, + [1][0][RTW89_ETSI][33] = 34, + [1][0][RTW89_MKK][33] = 58, + [1][0][RTW89_IC][33] = 62, + [1][0][RTW89_KCC][33] = 54, + [1][0][RTW89_ACMA][33] = 34, + [1][0][RTW89_CHILE][33] = 66, + [1][0][RTW89_UKRAINE][33] = 34, + [1][0][RTW89_MEXICO][33] = 62, + [1][0][RTW89_CN][33] = 127, + [1][0][RTW89_QATAR][33] = 34, + [1][0][RTW89_UK][33] = 34, + [1][0][RTW89_FCC][35] = 62, + [1][0][RTW89_ETSI][35] = 34, + [1][0][RTW89_MKK][35] = 58, + [1][0][RTW89_IC][35] = 62, + [1][0][RTW89_KCC][35] = 54, + [1][0][RTW89_ACMA][35] = 34, + [1][0][RTW89_CHILE][35] = 66, + [1][0][RTW89_UKRAINE][35] = 34, + [1][0][RTW89_MEXICO][35] = 62, + [1][0][RTW89_CN][35] = 127, + [1][0][RTW89_QATAR][35] = 34, + [1][0][RTW89_UK][35] = 34, + [1][0][RTW89_FCC][37] = 64, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 52, + [1][0][RTW89_IC][37] = 64, + [1][0][RTW89_KCC][37] = 54, + [1][0][RTW89_ACMA][37] = 64, + [1][0][RTW89_CHILE][37] = 64, + [1][0][RTW89_UKRAINE][37] = 127, + [1][0][RTW89_MEXICO][37] = 64, + [1][0][RTW89_CN][37] = 127, + [1][0][RTW89_QATAR][37] = 127, + [1][0][RTW89_UK][37] = 66, + [1][0][RTW89_FCC][38] = 84, + [1][0][RTW89_ETSI][38] = 28, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 84, + [1][0][RTW89_KCC][38] = 56, + [1][0][RTW89_ACMA][38] = 84, + [1][0][RTW89_CHILE][38] = 64, + [1][0][RTW89_UKRAINE][38] = 28, + [1][0][RTW89_MEXICO][38] = 84, + [1][0][RTW89_CN][38] = 62, + [1][0][RTW89_QATAR][38] = 28, + [1][0][RTW89_UK][38] = 38, + [1][0][RTW89_FCC][40] = 84, + [1][0][RTW89_ETSI][40] = 28, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 84, + [1][0][RTW89_KCC][40] = 56, + [1][0][RTW89_ACMA][40] = 84, + [1][0][RTW89_CHILE][40] = 64, + [1][0][RTW89_UKRAINE][40] = 28, + [1][0][RTW89_MEXICO][40] = 84, + [1][0][RTW89_CN][40] = 62, + [1][0][RTW89_QATAR][40] = 28, + [1][0][RTW89_UK][40] = 38, + [1][0][RTW89_FCC][42] = 84, + [1][0][RTW89_ETSI][42] = 28, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 84, + [1][0][RTW89_KCC][42] = 56, + [1][0][RTW89_ACMA][42] = 84, + [1][0][RTW89_CHILE][42] = 64, + [1][0][RTW89_UKRAINE][42] = 28, + [1][0][RTW89_MEXICO][42] = 84, + [1][0][RTW89_CN][42] = 62, + [1][0][RTW89_QATAR][42] = 28, + [1][0][RTW89_UK][42] = 38, + [1][0][RTW89_FCC][44] = 84, + [1][0][RTW89_ETSI][44] = 28, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 84, + [1][0][RTW89_KCC][44] = 56, + [1][0][RTW89_ACMA][44] = 84, + [1][0][RTW89_CHILE][44] = 64, + [1][0][RTW89_UKRAINE][44] = 28, + [1][0][RTW89_MEXICO][44] = 84, + [1][0][RTW89_CN][44] = 62, + [1][0][RTW89_QATAR][44] = 28, + [1][0][RTW89_UK][44] = 38, + [1][0][RTW89_FCC][46] = 84, + [1][0][RTW89_ETSI][46] = 28, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 84, + [1][0][RTW89_KCC][46] = 56, + [1][0][RTW89_ACMA][46] = 84, + [1][0][RTW89_CHILE][46] = 64, + [1][0][RTW89_UKRAINE][46] = 28, + [1][0][RTW89_MEXICO][46] = 84, + [1][0][RTW89_CN][46] = 62, + [1][0][RTW89_QATAR][46] = 28, + [1][0][RTW89_UK][46] = 38, + [1][0][RTW89_FCC][48] = 44, + [1][0][RTW89_ETSI][48] = 127, + [1][0][RTW89_MKK][48] = 127, + [1][0][RTW89_IC][48] = 54, + [1][0][RTW89_KCC][48] = 127, + [1][0][RTW89_ACMA][48] = 127, + [1][0][RTW89_CHILE][48] = 127, + [1][0][RTW89_UKRAINE][48] = 127, + [1][0][RTW89_MEXICO][48] = 127, + [1][0][RTW89_CN][48] = 127, + [1][0][RTW89_QATAR][48] = 127, + [1][0][RTW89_UK][48] = 127, + [1][0][RTW89_FCC][50] = 44, + [1][0][RTW89_ETSI][50] = 127, + [1][0][RTW89_MKK][50] = 127, + [1][0][RTW89_IC][50] = 54, + [1][0][RTW89_KCC][50] = 127, + [1][0][RTW89_ACMA][50] = 127, + [1][0][RTW89_CHILE][50] = 127, + [1][0][RTW89_UKRAINE][50] = 127, + [1][0][RTW89_MEXICO][50] = 127, + [1][0][RTW89_CN][50] = 127, + [1][0][RTW89_QATAR][50] = 127, + [1][0][RTW89_UK][50] = 127, + [1][0][RTW89_FCC][52] = 44, + [1][0][RTW89_ETSI][52] = 127, + [1][0][RTW89_MKK][52] = 127, + [1][0][RTW89_IC][52] = 52, + [1][0][RTW89_KCC][52] = 127, + [1][0][RTW89_ACMA][52] = 127, + [1][0][RTW89_CHILE][52] = 127, + [1][0][RTW89_UKRAINE][52] = 127, + [1][0][RTW89_MEXICO][52] = 127, + [1][0][RTW89_CN][52] = 127, + [1][0][RTW89_QATAR][52] = 127, + [1][0][RTW89_UK][52] = 127, + [1][1][RTW89_FCC][0] = 42, + [1][1][RTW89_ETSI][0] = 22, + [1][1][RTW89_MKK][0] = 22, + [1][1][RTW89_IC][0] = 10, + [1][1][RTW89_KCC][0] = 36, + [1][1][RTW89_ACMA][0] = 22, + [1][1][RTW89_CHILE][0] = 22, + [1][1][RTW89_UKRAINE][0] = 22, + [1][1][RTW89_MEXICO][0] = 42, + [1][1][RTW89_CN][0] = 22, + [1][1][RTW89_QATAR][0] = 22, + [1][1][RTW89_UK][0] = 22, + [1][1][RTW89_FCC][2] = 44, + [1][1][RTW89_ETSI][2] = 22, + [1][1][RTW89_MKK][2] = 22, + [1][1][RTW89_IC][2] = 14, + [1][1][RTW89_KCC][2] = 36, + [1][1][RTW89_ACMA][2] = 22, + [1][1][RTW89_CHILE][2] = 22, + [1][1][RTW89_UKRAINE][2] = 22, + [1][1][RTW89_MEXICO][2] = 44, + [1][1][RTW89_CN][2] = 22, + [1][1][RTW89_QATAR][2] = 22, + [1][1][RTW89_UK][2] = 22, + [1][1][RTW89_FCC][4] = 42, + [1][1][RTW89_ETSI][4] = 22, + [1][1][RTW89_MKK][4] = 20, + [1][1][RTW89_IC][4] = 10, + [1][1][RTW89_KCC][4] = 36, + [1][1][RTW89_ACMA][4] = 22, + [1][1][RTW89_CHILE][4] = 20, + [1][1][RTW89_UKRAINE][4] = 22, + [1][1][RTW89_MEXICO][4] = 42, + [1][1][RTW89_CN][4] = 22, + [1][1][RTW89_QATAR][4] = 22, + [1][1][RTW89_UK][4] = 22, + [1][1][RTW89_FCC][6] = 42, + [1][1][RTW89_ETSI][6] = 22, + [1][1][RTW89_MKK][6] = 20, + [1][1][RTW89_IC][6] = 10, + [1][1][RTW89_KCC][6] = 10, + [1][1][RTW89_ACMA][6] = 22, + [1][1][RTW89_CHILE][6] = 20, + [1][1][RTW89_UKRAINE][6] = 22, + [1][1][RTW89_MEXICO][6] = 42, + [1][1][RTW89_CN][6] = 22, + [1][1][RTW89_QATAR][6] = 22, + [1][1][RTW89_UK][6] = 22, + [1][1][RTW89_FCC][8] = 44, + [1][1][RTW89_ETSI][8] = 22, + [1][1][RTW89_MKK][8] = 20, + [1][1][RTW89_IC][8] = 44, + [1][1][RTW89_KCC][8] = 36, + [1][1][RTW89_ACMA][8] = 22, + [1][1][RTW89_CHILE][8] = 54, + [1][1][RTW89_UKRAINE][8] = 22, + [1][1][RTW89_MEXICO][8] = 44, + [1][1][RTW89_CN][8] = 22, + [1][1][RTW89_QATAR][8] = 22, + [1][1][RTW89_UK][8] = 22, + [1][1][RTW89_FCC][10] = 44, + [1][1][RTW89_ETSI][10] = 22, + [1][1][RTW89_MKK][10] = 20, + [1][1][RTW89_IC][10] = 44, + [1][1][RTW89_KCC][10] = 36, + [1][1][RTW89_ACMA][10] = 22, + [1][1][RTW89_CHILE][10] = 54, + [1][1][RTW89_UKRAINE][10] = 22, + [1][1][RTW89_MEXICO][10] = 44, + [1][1][RTW89_CN][10] = 22, + [1][1][RTW89_QATAR][10] = 22, + [1][1][RTW89_UK][10] = 22, + [1][1][RTW89_FCC][12] = 46, + [1][1][RTW89_ETSI][12] = 22, + [1][1][RTW89_MKK][12] = 22, + [1][1][RTW89_IC][12] = 46, + [1][1][RTW89_KCC][12] = 40, + [1][1][RTW89_ACMA][12] = 22, + [1][1][RTW89_CHILE][12] = 52, + [1][1][RTW89_UKRAINE][12] = 22, + [1][1][RTW89_MEXICO][12] = 46, + [1][1][RTW89_CN][12] = 22, + [1][1][RTW89_QATAR][12] = 22, + [1][1][RTW89_UK][12] = 22, + [1][1][RTW89_FCC][14] = 42, + [1][1][RTW89_ETSI][14] = 22, + [1][1][RTW89_MKK][14] = 22, + [1][1][RTW89_IC][14] = 40, + [1][1][RTW89_KCC][14] = 40, + [1][1][RTW89_ACMA][14] = 22, + [1][1][RTW89_CHILE][14] = 54, + [1][1][RTW89_UKRAINE][14] = 22, + [1][1][RTW89_MEXICO][14] = 42, + [1][1][RTW89_CN][14] = 22, + [1][1][RTW89_QATAR][14] = 22, + [1][1][RTW89_UK][14] = 22, + [1][1][RTW89_FCC][15] = 42, + [1][1][RTW89_ETSI][15] = 22, + [1][1][RTW89_MKK][15] = 42, + [1][1][RTW89_IC][15] = 42, + [1][1][RTW89_KCC][15] = 38, + [1][1][RTW89_ACMA][15] = 22, + [1][1][RTW89_CHILE][15] = 54, + [1][1][RTW89_UKRAINE][15] = 22, + [1][1][RTW89_MEXICO][15] = 42, + [1][1][RTW89_CN][15] = 127, + [1][1][RTW89_QATAR][15] = 22, + [1][1][RTW89_UK][15] = 22, + [1][1][RTW89_FCC][17] = 42, + [1][1][RTW89_ETSI][17] = 22, + [1][1][RTW89_MKK][17] = 44, + [1][1][RTW89_IC][17] = 42, + [1][1][RTW89_KCC][17] = 38, + [1][1][RTW89_ACMA][17] = 22, + [1][1][RTW89_CHILE][17] = 54, + [1][1][RTW89_UKRAINE][17] = 22, + [1][1][RTW89_MEXICO][17] = 42, + [1][1][RTW89_CN][17] = 127, + [1][1][RTW89_QATAR][17] = 22, + [1][1][RTW89_UK][17] = 22, + [1][1][RTW89_FCC][19] = 42, + [1][1][RTW89_ETSI][19] = 22, + [1][1][RTW89_MKK][19] = 44, + [1][1][RTW89_IC][19] = 42, + [1][1][RTW89_KCC][19] = 38, + [1][1][RTW89_ACMA][19] = 22, + [1][1][RTW89_CHILE][19] = 54, + [1][1][RTW89_UKRAINE][19] = 22, + [1][1][RTW89_MEXICO][19] = 42, + [1][1][RTW89_CN][19] = 127, + [1][1][RTW89_QATAR][19] = 22, + [1][1][RTW89_UK][19] = 22, + [1][1][RTW89_FCC][21] = 42, + [1][1][RTW89_ETSI][21] = 22, + [1][1][RTW89_MKK][21] = 44, + [1][1][RTW89_IC][21] = 42, + [1][1][RTW89_KCC][21] = 38, + [1][1][RTW89_ACMA][21] = 22, + [1][1][RTW89_CHILE][21] = 54, + [1][1][RTW89_UKRAINE][21] = 22, + [1][1][RTW89_MEXICO][21] = 42, + [1][1][RTW89_CN][21] = 127, + [1][1][RTW89_QATAR][21] = 22, + [1][1][RTW89_UK][21] = 22, + [1][1][RTW89_FCC][23] = 42, + [1][1][RTW89_ETSI][23] = 22, + [1][1][RTW89_MKK][23] = 44, + [1][1][RTW89_IC][23] = 42, + [1][1][RTW89_KCC][23] = 38, + [1][1][RTW89_ACMA][23] = 22, + [1][1][RTW89_CHILE][23] = 54, + [1][1][RTW89_UKRAINE][23] = 22, + [1][1][RTW89_MEXICO][23] = 42, + [1][1][RTW89_CN][23] = 127, + [1][1][RTW89_QATAR][23] = 22, + [1][1][RTW89_UK][23] = 22, + [1][1][RTW89_FCC][25] = 42, + [1][1][RTW89_ETSI][25] = 22, + [1][1][RTW89_MKK][25] = 44, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_KCC][25] = 38, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_CHILE][25] = 54, + [1][1][RTW89_UKRAINE][25] = 22, + [1][1][RTW89_MEXICO][25] = 42, + [1][1][RTW89_CN][25] = 127, + [1][1][RTW89_QATAR][25] = 22, + [1][1][RTW89_UK][25] = 22, + [1][1][RTW89_FCC][27] = 42, + [1][1][RTW89_ETSI][27] = 22, + [1][1][RTW89_MKK][27] = 44, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_KCC][27] = 38, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_CHILE][27] = 54, + [1][1][RTW89_UKRAINE][27] = 22, + [1][1][RTW89_MEXICO][27] = 42, + [1][1][RTW89_CN][27] = 127, + [1][1][RTW89_QATAR][27] = 22, + [1][1][RTW89_UK][27] = 22, + [1][1][RTW89_FCC][29] = 42, + [1][1][RTW89_ETSI][29] = 22, + [1][1][RTW89_MKK][29] = 44, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_KCC][29] = 38, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_CHILE][29] = 54, + [1][1][RTW89_UKRAINE][29] = 22, + [1][1][RTW89_MEXICO][29] = 42, + [1][1][RTW89_CN][29] = 127, + [1][1][RTW89_QATAR][29] = 22, + [1][1][RTW89_UK][29] = 22, + [1][1][RTW89_FCC][31] = 42, + [1][1][RTW89_ETSI][31] = 22, + [1][1][RTW89_MKK][31] = 44, + [1][1][RTW89_IC][31] = 38, + [1][1][RTW89_KCC][31] = 38, + [1][1][RTW89_ACMA][31] = 22, + [1][1][RTW89_CHILE][31] = 54, + [1][1][RTW89_UKRAINE][31] = 22, + [1][1][RTW89_MEXICO][31] = 42, + [1][1][RTW89_CN][31] = 127, + [1][1][RTW89_QATAR][31] = 22, + [1][1][RTW89_UK][31] = 22, + [1][1][RTW89_FCC][33] = 40, + [1][1][RTW89_ETSI][33] = 22, + [1][1][RTW89_MKK][33] = 44, + [1][1][RTW89_IC][33] = 38, + [1][1][RTW89_KCC][33] = 38, + [1][1][RTW89_ACMA][33] = 22, + [1][1][RTW89_CHILE][33] = 54, + [1][1][RTW89_UKRAINE][33] = 22, + [1][1][RTW89_MEXICO][33] = 40, + [1][1][RTW89_CN][33] = 127, + [1][1][RTW89_QATAR][33] = 22, + [1][1][RTW89_UK][33] = 22, + [1][1][RTW89_FCC][35] = 40, + [1][1][RTW89_ETSI][35] = 22, + [1][1][RTW89_MKK][35] = 44, + [1][1][RTW89_IC][35] = 38, + [1][1][RTW89_KCC][35] = 38, + [1][1][RTW89_ACMA][35] = 22, + [1][1][RTW89_CHILE][35] = 54, + [1][1][RTW89_UKRAINE][35] = 22, + [1][1][RTW89_MEXICO][35] = 40, + [1][1][RTW89_CN][35] = 127, + [1][1][RTW89_QATAR][35] = 22, + [1][1][RTW89_UK][35] = 22, + [1][1][RTW89_FCC][37] = 48, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 42, + [1][1][RTW89_IC][37] = 48, + [1][1][RTW89_KCC][37] = 38, + [1][1][RTW89_ACMA][37] = 48, + [1][1][RTW89_CHILE][37] = 54, + [1][1][RTW89_UKRAINE][37] = 127, + [1][1][RTW89_MEXICO][37] = 48, + [1][1][RTW89_CN][37] = 127, + [1][1][RTW89_QATAR][37] = 127, + [1][1][RTW89_UK][37] = 54, + [1][1][RTW89_FCC][38] = 84, + [1][1][RTW89_ETSI][38] = 16, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 84, + [1][1][RTW89_KCC][38] = 38, + [1][1][RTW89_ACMA][38] = 82, + [1][1][RTW89_CHILE][38] = 54, + [1][1][RTW89_UKRAINE][38] = 16, + [1][1][RTW89_MEXICO][38] = 84, + [1][1][RTW89_CN][38] = 62, + [1][1][RTW89_QATAR][38] = 16, + [1][1][RTW89_UK][38] = 26, + [1][1][RTW89_FCC][40] = 84, + [1][1][RTW89_ETSI][40] = 16, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 84, + [1][1][RTW89_KCC][40] = 38, + [1][1][RTW89_ACMA][40] = 82, + [1][1][RTW89_CHILE][40] = 54, + [1][1][RTW89_UKRAINE][40] = 16, + [1][1][RTW89_MEXICO][40] = 84, + [1][1][RTW89_CN][40] = 62, + [1][1][RTW89_QATAR][40] = 16, + [1][1][RTW89_UK][40] = 26, + [1][1][RTW89_FCC][42] = 84, + [1][1][RTW89_ETSI][42] = 16, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 84, + [1][1][RTW89_KCC][42] = 38, + [1][1][RTW89_ACMA][42] = 84, + [1][1][RTW89_CHILE][42] = 54, + [1][1][RTW89_UKRAINE][42] = 16, + [1][1][RTW89_MEXICO][42] = 84, + [1][1][RTW89_CN][42] = 62, + [1][1][RTW89_QATAR][42] = 16, + [1][1][RTW89_UK][42] = 26, + [1][1][RTW89_FCC][44] = 84, + [1][1][RTW89_ETSI][44] = 16, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 84, + [1][1][RTW89_KCC][44] = 38, + [1][1][RTW89_ACMA][44] = 84, + [1][1][RTW89_CHILE][44] = 56, + [1][1][RTW89_UKRAINE][44] = 16, + [1][1][RTW89_MEXICO][44] = 84, + [1][1][RTW89_CN][44] = 62, + [1][1][RTW89_QATAR][44] = 16, + [1][1][RTW89_UK][44] = 26, + [1][1][RTW89_FCC][46] = 84, + [1][1][RTW89_ETSI][46] = 16, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 84, + [1][1][RTW89_KCC][46] = 38, + [1][1][RTW89_ACMA][46] = 84, + [1][1][RTW89_CHILE][46] = 56, + [1][1][RTW89_UKRAINE][46] = 16, + [1][1][RTW89_MEXICO][46] = 84, + [1][1][RTW89_CN][46] = 62, + [1][1][RTW89_QATAR][46] = 16, + [1][1][RTW89_UK][46] = 26, + [1][1][RTW89_FCC][48] = 32, + [1][1][RTW89_ETSI][48] = 127, + [1][1][RTW89_MKK][48] = 127, + [1][1][RTW89_IC][48] = 28, + [1][1][RTW89_KCC][48] = 127, + [1][1][RTW89_ACMA][48] = 127, + [1][1][RTW89_CHILE][48] = 127, + [1][1][RTW89_UKRAINE][48] = 127, + [1][1][RTW89_MEXICO][48] = 127, + [1][1][RTW89_CN][48] = 127, + [1][1][RTW89_QATAR][48] = 127, + [1][1][RTW89_UK][48] = 127, + [1][1][RTW89_FCC][50] = 32, + [1][1][RTW89_ETSI][50] = 127, + [1][1][RTW89_MKK][50] = 127, + [1][1][RTW89_IC][50] = 30, + [1][1][RTW89_KCC][50] = 127, + [1][1][RTW89_ACMA][50] = 127, + [1][1][RTW89_CHILE][50] = 127, + [1][1][RTW89_UKRAINE][50] = 127, + [1][1][RTW89_MEXICO][50] = 127, + [1][1][RTW89_CN][50] = 127, + [1][1][RTW89_QATAR][50] = 127, + [1][1][RTW89_UK][50] = 127, + [1][1][RTW89_FCC][52] = 32, + [1][1][RTW89_ETSI][52] = 127, + [1][1][RTW89_MKK][52] = 127, + [1][1][RTW89_IC][52] = 30, + [1][1][RTW89_KCC][52] = 127, + [1][1][RTW89_ACMA][52] = 127, + [1][1][RTW89_CHILE][52] = 127, + [1][1][RTW89_UKRAINE][52] = 127, + [1][1][RTW89_MEXICO][52] = 127, + [1][1][RTW89_CN][52] = 127, + [1][1][RTW89_QATAR][52] = 127, + [1][1][RTW89_UK][52] = 127, + [2][0][RTW89_FCC][0] = 70, + [2][0][RTW89_ETSI][0] = 48, + [2][0][RTW89_MKK][0] = 48, + [2][0][RTW89_IC][0] = 46, + [2][0][RTW89_KCC][0] = 66, + [2][0][RTW89_ACMA][0] = 48, + [2][0][RTW89_CHILE][0] = 44, + [2][0][RTW89_UKRAINE][0] = 48, + [2][0][RTW89_MEXICO][0] = 64, + [2][0][RTW89_CN][0] = 48, + [2][0][RTW89_QATAR][0] = 48, + [2][0][RTW89_UK][0] = 48, + [2][0][RTW89_FCC][2] = 70, + [2][0][RTW89_ETSI][2] = 48, + [2][0][RTW89_MKK][2] = 48, + [2][0][RTW89_IC][2] = 46, + [2][0][RTW89_KCC][2] = 66, + [2][0][RTW89_ACMA][2] = 48, + [2][0][RTW89_CHILE][2] = 44, + [2][0][RTW89_UKRAINE][2] = 48, + [2][0][RTW89_MEXICO][2] = 64, + [2][0][RTW89_CN][2] = 48, + [2][0][RTW89_QATAR][2] = 48, + [2][0][RTW89_UK][2] = 48, + [2][0][RTW89_FCC][4] = 70, + [2][0][RTW89_ETSI][4] = 48, + [2][0][RTW89_MKK][4] = 48, + [2][0][RTW89_IC][4] = 46, + [2][0][RTW89_KCC][4] = 66, + [2][0][RTW89_ACMA][4] = 48, + [2][0][RTW89_CHILE][4] = 44, + [2][0][RTW89_UKRAINE][4] = 48, + [2][0][RTW89_MEXICO][4] = 64, + [2][0][RTW89_CN][4] = 48, + [2][0][RTW89_QATAR][4] = 48, + [2][0][RTW89_UK][4] = 48, + [2][0][RTW89_FCC][6] = 70, + [2][0][RTW89_ETSI][6] = 48, + [2][0][RTW89_MKK][6] = 48, + [2][0][RTW89_IC][6] = 46, + [2][0][RTW89_KCC][6] = 38, + [2][0][RTW89_ACMA][6] = 48, + [2][0][RTW89_CHILE][6] = 44, + [2][0][RTW89_UKRAINE][6] = 48, + [2][0][RTW89_MEXICO][6] = 64, + [2][0][RTW89_CN][6] = 48, + [2][0][RTW89_QATAR][6] = 48, + [2][0][RTW89_UK][6] = 48, + [2][0][RTW89_FCC][8] = 70, + [2][0][RTW89_ETSI][8] = 48, + [2][0][RTW89_MKK][8] = 48, + [2][0][RTW89_IC][8] = 66, + [2][0][RTW89_KCC][8] = 64, + [2][0][RTW89_ACMA][8] = 48, + [2][0][RTW89_CHILE][8] = 66, + [2][0][RTW89_UKRAINE][8] = 48, + [2][0][RTW89_MEXICO][8] = 70, + [2][0][RTW89_CN][8] = 48, + [2][0][RTW89_QATAR][8] = 48, + [2][0][RTW89_UK][8] = 48, + [2][0][RTW89_FCC][10] = 70, + [2][0][RTW89_ETSI][10] = 48, + [2][0][RTW89_MKK][10] = 48, + [2][0][RTW89_IC][10] = 66, + [2][0][RTW89_KCC][10] = 64, + [2][0][RTW89_ACMA][10] = 48, + [2][0][RTW89_CHILE][10] = 66, + [2][0][RTW89_UKRAINE][10] = 48, + [2][0][RTW89_MEXICO][10] = 70, + [2][0][RTW89_CN][10] = 48, + [2][0][RTW89_QATAR][10] = 48, + [2][0][RTW89_UK][10] = 48, + [2][0][RTW89_FCC][12] = 70, + [2][0][RTW89_ETSI][12] = 48, + [2][0][RTW89_MKK][12] = 46, + [2][0][RTW89_IC][12] = 66, + [2][0][RTW89_KCC][12] = 64, + [2][0][RTW89_ACMA][12] = 48, + [2][0][RTW89_CHILE][12] = 66, + [2][0][RTW89_UKRAINE][12] = 48, + [2][0][RTW89_MEXICO][12] = 70, + [2][0][RTW89_CN][12] = 48, + [2][0][RTW89_QATAR][12] = 48, + [2][0][RTW89_UK][12] = 48, + [2][0][RTW89_FCC][14] = 70, + [2][0][RTW89_ETSI][14] = 48, + [2][0][RTW89_MKK][14] = 46, + [2][0][RTW89_IC][14] = 66, + [2][0][RTW89_KCC][14] = 64, + [2][0][RTW89_ACMA][14] = 48, + [2][0][RTW89_CHILE][14] = 66, + [2][0][RTW89_UKRAINE][14] = 48, + [2][0][RTW89_MEXICO][14] = 70, + [2][0][RTW89_CN][14] = 48, + [2][0][RTW89_QATAR][14] = 48, + [2][0][RTW89_UK][14] = 48, + [2][0][RTW89_FCC][15] = 70, + [2][0][RTW89_ETSI][15] = 48, + [2][0][RTW89_MKK][15] = 68, + [2][0][RTW89_IC][15] = 70, + [2][0][RTW89_KCC][15] = 64, + [2][0][RTW89_ACMA][15] = 48, + [2][0][RTW89_CHILE][15] = 62, + [2][0][RTW89_UKRAINE][15] = 48, + [2][0][RTW89_MEXICO][15] = 70, + [2][0][RTW89_CN][15] = 127, + [2][0][RTW89_QATAR][15] = 48, + [2][0][RTW89_UK][15] = 48, + [2][0][RTW89_FCC][17] = 70, + [2][0][RTW89_ETSI][17] = 48, + [2][0][RTW89_MKK][17] = 70, + [2][0][RTW89_IC][17] = 70, + [2][0][RTW89_KCC][17] = 64, + [2][0][RTW89_ACMA][17] = 48, + [2][0][RTW89_CHILE][17] = 62, + [2][0][RTW89_UKRAINE][17] = 48, + [2][0][RTW89_MEXICO][17] = 70, + [2][0][RTW89_CN][17] = 127, + [2][0][RTW89_QATAR][17] = 48, + [2][0][RTW89_UK][17] = 48, + [2][0][RTW89_FCC][19] = 70, + [2][0][RTW89_ETSI][19] = 48, + [2][0][RTW89_MKK][19] = 70, + [2][0][RTW89_IC][19] = 70, + [2][0][RTW89_KCC][19] = 64, + [2][0][RTW89_ACMA][19] = 48, + [2][0][RTW89_CHILE][19] = 62, + [2][0][RTW89_UKRAINE][19] = 48, + [2][0][RTW89_MEXICO][19] = 70, + [2][0][RTW89_CN][19] = 127, + [2][0][RTW89_QATAR][19] = 48, + [2][0][RTW89_UK][19] = 48, + [2][0][RTW89_FCC][21] = 70, + [2][0][RTW89_ETSI][21] = 48, + [2][0][RTW89_MKK][21] = 70, + [2][0][RTW89_IC][21] = 70, + [2][0][RTW89_KCC][21] = 64, + [2][0][RTW89_ACMA][21] = 48, + [2][0][RTW89_CHILE][21] = 64, + [2][0][RTW89_UKRAINE][21] = 48, + [2][0][RTW89_MEXICO][21] = 70, + [2][0][RTW89_CN][21] = 127, + [2][0][RTW89_QATAR][21] = 48, + [2][0][RTW89_UK][21] = 48, + [2][0][RTW89_FCC][23] = 70, + [2][0][RTW89_ETSI][23] = 48, + [2][0][RTW89_MKK][23] = 70, + [2][0][RTW89_IC][23] = 70, + [2][0][RTW89_KCC][23] = 64, + [2][0][RTW89_ACMA][23] = 48, + [2][0][RTW89_CHILE][23] = 64, + [2][0][RTW89_UKRAINE][23] = 48, + [2][0][RTW89_MEXICO][23] = 70, + [2][0][RTW89_CN][23] = 127, + [2][0][RTW89_QATAR][23] = 48, + [2][0][RTW89_UK][23] = 48, + [2][0][RTW89_FCC][25] = 70, + [2][0][RTW89_ETSI][25] = 48, + [2][0][RTW89_MKK][25] = 70, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_KCC][25] = 64, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_CHILE][25] = 64, + [2][0][RTW89_UKRAINE][25] = 48, + [2][0][RTW89_MEXICO][25] = 70, + [2][0][RTW89_CN][25] = 127, + [2][0][RTW89_QATAR][25] = 48, + [2][0][RTW89_UK][25] = 48, + [2][0][RTW89_FCC][27] = 70, + [2][0][RTW89_ETSI][27] = 48, + [2][0][RTW89_MKK][27] = 70, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_KCC][27] = 64, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_CHILE][27] = 64, + [2][0][RTW89_UKRAINE][27] = 48, + [2][0][RTW89_MEXICO][27] = 70, + [2][0][RTW89_CN][27] = 127, + [2][0][RTW89_QATAR][27] = 48, + [2][0][RTW89_UK][27] = 48, + [2][0][RTW89_FCC][29] = 70, + [2][0][RTW89_ETSI][29] = 48, + [2][0][RTW89_MKK][29] = 70, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_KCC][29] = 64, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_CHILE][29] = 66, + [2][0][RTW89_UKRAINE][29] = 48, + [2][0][RTW89_MEXICO][29] = 70, + [2][0][RTW89_CN][29] = 127, + [2][0][RTW89_QATAR][29] = 48, + [2][0][RTW89_UK][29] = 48, + [2][0][RTW89_FCC][31] = 70, + [2][0][RTW89_ETSI][31] = 48, + [2][0][RTW89_MKK][31] = 70, + [2][0][RTW89_IC][31] = 72, + [2][0][RTW89_KCC][31] = 64, + [2][0][RTW89_ACMA][31] = 48, + [2][0][RTW89_CHILE][31] = 66, + [2][0][RTW89_UKRAINE][31] = 48, + [2][0][RTW89_MEXICO][31] = 70, + [2][0][RTW89_CN][31] = 127, + [2][0][RTW89_QATAR][31] = 48, + [2][0][RTW89_UK][31] = 48, + [2][0][RTW89_FCC][33] = 72, + [2][0][RTW89_ETSI][33] = 48, + [2][0][RTW89_MKK][33] = 70, + [2][0][RTW89_IC][33] = 72, + [2][0][RTW89_KCC][33] = 64, + [2][0][RTW89_ACMA][33] = 48, + [2][0][RTW89_CHILE][33] = 66, + [2][0][RTW89_UKRAINE][33] = 48, + [2][0][RTW89_MEXICO][33] = 72, + [2][0][RTW89_CN][33] = 127, + [2][0][RTW89_QATAR][33] = 48, + [2][0][RTW89_UK][33] = 48, + [2][0][RTW89_FCC][35] = 72, + [2][0][RTW89_ETSI][35] = 48, + [2][0][RTW89_MKK][35] = 70, + [2][0][RTW89_IC][35] = 72, + [2][0][RTW89_KCC][35] = 64, + [2][0][RTW89_ACMA][35] = 48, + [2][0][RTW89_CHILE][35] = 66, + [2][0][RTW89_UKRAINE][35] = 48, + [2][0][RTW89_MEXICO][35] = 72, + [2][0][RTW89_CN][35] = 127, + [2][0][RTW89_QATAR][35] = 48, + [2][0][RTW89_UK][35] = 48, + [2][0][RTW89_FCC][37] = 70, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 66, + [2][0][RTW89_IC][37] = 70, + [2][0][RTW89_KCC][37] = 64, + [2][0][RTW89_ACMA][37] = 76, + [2][0][RTW89_CHILE][37] = 66, + [2][0][RTW89_UKRAINE][37] = 127, + [2][0][RTW89_MEXICO][37] = 70, + [2][0][RTW89_CN][37] = 127, + [2][0][RTW89_QATAR][37] = 127, + [2][0][RTW89_UK][37] = 76, + [2][0][RTW89_FCC][38] = 84, + [2][0][RTW89_ETSI][38] = 28, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 84, + [2][0][RTW89_KCC][38] = 66, + [2][0][RTW89_ACMA][38] = 84, + [2][0][RTW89_CHILE][38] = 64, + [2][0][RTW89_UKRAINE][38] = 28, + [2][0][RTW89_MEXICO][38] = 84, + [2][0][RTW89_CN][38] = 62, + [2][0][RTW89_QATAR][38] = 28, + [2][0][RTW89_UK][38] = 50, + [2][0][RTW89_FCC][40] = 84, + [2][0][RTW89_ETSI][40] = 28, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 84, + [2][0][RTW89_KCC][40] = 66, + [2][0][RTW89_ACMA][40] = 84, + [2][0][RTW89_CHILE][40] = 64, + [2][0][RTW89_UKRAINE][40] = 28, + [2][0][RTW89_MEXICO][40] = 84, + [2][0][RTW89_CN][40] = 62, + [2][0][RTW89_QATAR][40] = 28, + [2][0][RTW89_UK][40] = 50, + [2][0][RTW89_FCC][42] = 84, + [2][0][RTW89_ETSI][42] = 28, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 84, + [2][0][RTW89_KCC][42] = 66, + [2][0][RTW89_ACMA][42] = 84, + [2][0][RTW89_CHILE][42] = 66, + [2][0][RTW89_UKRAINE][42] = 28, + [2][0][RTW89_MEXICO][42] = 84, + [2][0][RTW89_CN][42] = 62, + [2][0][RTW89_QATAR][42] = 28, + [2][0][RTW89_UK][42] = 50, + [2][0][RTW89_FCC][44] = 84, + [2][0][RTW89_ETSI][44] = 28, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 84, + [2][0][RTW89_KCC][44] = 66, + [2][0][RTW89_ACMA][44] = 84, + [2][0][RTW89_CHILE][44] = 64, + [2][0][RTW89_UKRAINE][44] = 28, + [2][0][RTW89_MEXICO][44] = 84, + [2][0][RTW89_CN][44] = 62, + [2][0][RTW89_QATAR][44] = 28, + [2][0][RTW89_UK][44] = 50, + [2][0][RTW89_FCC][46] = 84, + [2][0][RTW89_ETSI][46] = 28, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 84, + [2][0][RTW89_KCC][46] = 66, + [2][0][RTW89_ACMA][46] = 84, + [2][0][RTW89_CHILE][46] = 64, + [2][0][RTW89_UKRAINE][46] = 28, + [2][0][RTW89_MEXICO][46] = 84, + [2][0][RTW89_CN][46] = 62, + [2][0][RTW89_QATAR][46] = 28, + [2][0][RTW89_UK][46] = 50, + [2][0][RTW89_FCC][48] = 56, + [2][0][RTW89_ETSI][48] = 127, + [2][0][RTW89_MKK][48] = 127, + [2][0][RTW89_IC][48] = 127, + [2][0][RTW89_KCC][48] = 66, + [2][0][RTW89_ACMA][48] = 127, + [2][0][RTW89_CHILE][48] = 127, + [2][0][RTW89_UKRAINE][48] = 127, + [2][0][RTW89_MEXICO][48] = 127, + [2][0][RTW89_CN][48] = 127, + [2][0][RTW89_QATAR][48] = 127, + [2][0][RTW89_UK][48] = 127, + [2][0][RTW89_FCC][50] = 56, + [2][0][RTW89_ETSI][50] = 127, + [2][0][RTW89_MKK][50] = 127, + [2][0][RTW89_IC][50] = 127, + [2][0][RTW89_KCC][50] = 66, + [2][0][RTW89_ACMA][50] = 127, + [2][0][RTW89_CHILE][50] = 127, + [2][0][RTW89_UKRAINE][50] = 127, + [2][0][RTW89_MEXICO][50] = 127, + [2][0][RTW89_CN][50] = 127, + [2][0][RTW89_QATAR][50] = 127, + [2][0][RTW89_UK][50] = 127, + [2][0][RTW89_FCC][52] = 56, + [2][0][RTW89_ETSI][52] = 127, + [2][0][RTW89_MKK][52] = 127, + [2][0][RTW89_IC][52] = 127, + [2][0][RTW89_KCC][52] = 66, + [2][0][RTW89_ACMA][52] = 127, + [2][0][RTW89_CHILE][52] = 127, + [2][0][RTW89_UKRAINE][52] = 127, + [2][0][RTW89_MEXICO][52] = 127, + [2][0][RTW89_CN][52] = 127, + [2][0][RTW89_QATAR][52] = 127, + [2][0][RTW89_UK][52] = 127, + [2][1][RTW89_FCC][0] = 50, + [2][1][RTW89_ETSI][0] = 36, + [2][1][RTW89_MKK][0] = 36, + [2][1][RTW89_IC][0] = 20, + [2][1][RTW89_KCC][0] = 46, + [2][1][RTW89_ACMA][0] = 36, + [2][1][RTW89_CHILE][0] = 32, + [2][1][RTW89_UKRAINE][0] = 36, + [2][1][RTW89_MEXICO][0] = 52, + [2][1][RTW89_CN][0] = 36, + [2][1][RTW89_QATAR][0] = 36, + [2][1][RTW89_UK][0] = 36, + [2][1][RTW89_FCC][2] = 50, + [2][1][RTW89_ETSI][2] = 36, + [2][1][RTW89_MKK][2] = 36, + [2][1][RTW89_IC][2] = 18, + [2][1][RTW89_KCC][2] = 46, + [2][1][RTW89_ACMA][2] = 36, + [2][1][RTW89_CHILE][2] = 32, + [2][1][RTW89_UKRAINE][2] = 36, + [2][1][RTW89_MEXICO][2] = 52, + [2][1][RTW89_CN][2] = 36, + [2][1][RTW89_QATAR][2] = 36, + [2][1][RTW89_UK][2] = 36, + [2][1][RTW89_FCC][4] = 50, + [2][1][RTW89_ETSI][4] = 36, + [2][1][RTW89_MKK][4] = 36, + [2][1][RTW89_IC][4] = 22, + [2][1][RTW89_KCC][4] = 46, + [2][1][RTW89_ACMA][4] = 36, + [2][1][RTW89_CHILE][4] = 30, + [2][1][RTW89_UKRAINE][4] = 36, + [2][1][RTW89_MEXICO][4] = 52, + [2][1][RTW89_CN][4] = 36, + [2][1][RTW89_QATAR][4] = 36, + [2][1][RTW89_UK][4] = 36, + [2][1][RTW89_FCC][6] = 50, + [2][1][RTW89_ETSI][6] = 36, + [2][1][RTW89_MKK][6] = 36, + [2][1][RTW89_IC][6] = 22, + [2][1][RTW89_KCC][6] = 22, + [2][1][RTW89_ACMA][6] = 36, + [2][1][RTW89_CHILE][6] = 30, + [2][1][RTW89_UKRAINE][6] = 36, + [2][1][RTW89_MEXICO][6] = 52, + [2][1][RTW89_CN][6] = 36, + [2][1][RTW89_QATAR][6] = 36, + [2][1][RTW89_UK][6] = 36, + [2][1][RTW89_FCC][8] = 50, + [2][1][RTW89_ETSI][8] = 36, + [2][1][RTW89_MKK][8] = 34, + [2][1][RTW89_IC][8] = 50, + [2][1][RTW89_KCC][8] = 48, + [2][1][RTW89_ACMA][8] = 36, + [2][1][RTW89_CHILE][8] = 54, + [2][1][RTW89_UKRAINE][8] = 36, + [2][1][RTW89_MEXICO][8] = 50, + [2][1][RTW89_CN][8] = 36, + [2][1][RTW89_QATAR][8] = 36, + [2][1][RTW89_UK][8] = 36, + [2][1][RTW89_FCC][10] = 50, + [2][1][RTW89_ETSI][10] = 36, + [2][1][RTW89_MKK][10] = 34, + [2][1][RTW89_IC][10] = 50, + [2][1][RTW89_KCC][10] = 48, + [2][1][RTW89_ACMA][10] = 36, + [2][1][RTW89_CHILE][10] = 54, + [2][1][RTW89_UKRAINE][10] = 36, + [2][1][RTW89_MEXICO][10] = 50, + [2][1][RTW89_CN][10] = 36, + [2][1][RTW89_QATAR][10] = 36, + [2][1][RTW89_UK][10] = 36, + [2][1][RTW89_FCC][12] = 52, + [2][1][RTW89_ETSI][12] = 36, + [2][1][RTW89_MKK][12] = 36, + [2][1][RTW89_IC][12] = 52, + [2][1][RTW89_KCC][12] = 48, + [2][1][RTW89_ACMA][12] = 36, + [2][1][RTW89_CHILE][12] = 54, + [2][1][RTW89_UKRAINE][12] = 36, + [2][1][RTW89_MEXICO][12] = 52, + [2][1][RTW89_CN][12] = 36, + [2][1][RTW89_QATAR][12] = 36, + [2][1][RTW89_UK][12] = 36, + [2][1][RTW89_FCC][14] = 52, + [2][1][RTW89_ETSI][14] = 36, + [2][1][RTW89_MKK][14] = 36, + [2][1][RTW89_IC][14] = 52, + [2][1][RTW89_KCC][14] = 48, + [2][1][RTW89_ACMA][14] = 36, + [2][1][RTW89_CHILE][14] = 54, + [2][1][RTW89_UKRAINE][14] = 36, + [2][1][RTW89_MEXICO][14] = 52, + [2][1][RTW89_CN][14] = 36, + [2][1][RTW89_QATAR][14] = 36, + [2][1][RTW89_UK][14] = 36, + [2][1][RTW89_FCC][15] = 50, + [2][1][RTW89_ETSI][15] = 36, + [2][1][RTW89_MKK][15] = 54, + [2][1][RTW89_IC][15] = 50, + [2][1][RTW89_KCC][15] = 48, + [2][1][RTW89_ACMA][15] = 36, + [2][1][RTW89_CHILE][15] = 56, + [2][1][RTW89_UKRAINE][15] = 36, + [2][1][RTW89_MEXICO][15] = 50, + [2][1][RTW89_CN][15] = 127, + [2][1][RTW89_QATAR][15] = 36, + [2][1][RTW89_UK][15] = 36, + [2][1][RTW89_FCC][17] = 50, + [2][1][RTW89_ETSI][17] = 36, + [2][1][RTW89_MKK][17] = 56, + [2][1][RTW89_IC][17] = 50, + [2][1][RTW89_KCC][17] = 48, + [2][1][RTW89_ACMA][17] = 36, + [2][1][RTW89_CHILE][17] = 56, + [2][1][RTW89_UKRAINE][17] = 36, + [2][1][RTW89_MEXICO][17] = 50, + [2][1][RTW89_CN][17] = 127, + [2][1][RTW89_QATAR][17] = 36, + [2][1][RTW89_UK][17] = 36, + [2][1][RTW89_FCC][19] = 50, + [2][1][RTW89_ETSI][19] = 36, + [2][1][RTW89_MKK][19] = 56, + [2][1][RTW89_IC][19] = 50, + [2][1][RTW89_KCC][19] = 48, + [2][1][RTW89_ACMA][19] = 36, + [2][1][RTW89_CHILE][19] = 56, + [2][1][RTW89_UKRAINE][19] = 36, + [2][1][RTW89_MEXICO][19] = 50, + [2][1][RTW89_CN][19] = 127, + [2][1][RTW89_QATAR][19] = 36, + [2][1][RTW89_UK][19] = 36, + [2][1][RTW89_FCC][21] = 50, + [2][1][RTW89_ETSI][21] = 36, + [2][1][RTW89_MKK][21] = 56, + [2][1][RTW89_IC][21] = 50, + [2][1][RTW89_KCC][21] = 48, + [2][1][RTW89_ACMA][21] = 36, + [2][1][RTW89_CHILE][21] = 58, + [2][1][RTW89_UKRAINE][21] = 36, + [2][1][RTW89_MEXICO][21] = 50, + [2][1][RTW89_CN][21] = 127, + [2][1][RTW89_QATAR][21] = 36, + [2][1][RTW89_UK][21] = 36, + [2][1][RTW89_FCC][23] = 50, + [2][1][RTW89_ETSI][23] = 36, + [2][1][RTW89_MKK][23] = 56, + [2][1][RTW89_IC][23] = 50, + [2][1][RTW89_KCC][23] = 48, + [2][1][RTW89_ACMA][23] = 36, + [2][1][RTW89_CHILE][23] = 58, + [2][1][RTW89_UKRAINE][23] = 36, + [2][1][RTW89_MEXICO][23] = 50, + [2][1][RTW89_CN][23] = 127, + [2][1][RTW89_QATAR][23] = 36, + [2][1][RTW89_UK][23] = 36, + [2][1][RTW89_FCC][25] = 50, + [2][1][RTW89_ETSI][25] = 36, + [2][1][RTW89_MKK][25] = 56, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_KCC][25] = 48, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_CHILE][25] = 58, + [2][1][RTW89_UKRAINE][25] = 36, + [2][1][RTW89_MEXICO][25] = 50, + [2][1][RTW89_CN][25] = 127, + [2][1][RTW89_QATAR][25] = 36, + [2][1][RTW89_UK][25] = 36, + [2][1][RTW89_FCC][27] = 50, + [2][1][RTW89_ETSI][27] = 36, + [2][1][RTW89_MKK][27] = 56, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_KCC][27] = 48, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_CHILE][27] = 58, + [2][1][RTW89_UKRAINE][27] = 36, + [2][1][RTW89_MEXICO][27] = 50, + [2][1][RTW89_CN][27] = 127, + [2][1][RTW89_QATAR][27] = 36, + [2][1][RTW89_UK][27] = 36, + [2][1][RTW89_FCC][29] = 50, + [2][1][RTW89_ETSI][29] = 36, + [2][1][RTW89_MKK][29] = 56, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_KCC][29] = 48, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_CHILE][29] = 56, + [2][1][RTW89_UKRAINE][29] = 36, + [2][1][RTW89_MEXICO][29] = 50, + [2][1][RTW89_CN][29] = 127, + [2][1][RTW89_QATAR][29] = 36, + [2][1][RTW89_UK][29] = 36, + [2][1][RTW89_FCC][31] = 50, + [2][1][RTW89_ETSI][31] = 36, + [2][1][RTW89_MKK][31] = 56, + [2][1][RTW89_IC][31] = 50, + [2][1][RTW89_KCC][31] = 48, + [2][1][RTW89_ACMA][31] = 36, + [2][1][RTW89_CHILE][31] = 56, + [2][1][RTW89_UKRAINE][31] = 36, + [2][1][RTW89_MEXICO][31] = 50, + [2][1][RTW89_CN][31] = 127, + [2][1][RTW89_QATAR][31] = 36, + [2][1][RTW89_UK][31] = 36, + [2][1][RTW89_FCC][33] = 50, + [2][1][RTW89_ETSI][33] = 36, + [2][1][RTW89_MKK][33] = 56, + [2][1][RTW89_IC][33] = 50, + [2][1][RTW89_KCC][33] = 48, + [2][1][RTW89_ACMA][33] = 36, + [2][1][RTW89_CHILE][33] = 56, + [2][1][RTW89_UKRAINE][33] = 36, + [2][1][RTW89_MEXICO][33] = 50, + [2][1][RTW89_CN][33] = 127, + [2][1][RTW89_QATAR][33] = 36, + [2][1][RTW89_UK][33] = 36, + [2][1][RTW89_FCC][35] = 50, + [2][1][RTW89_ETSI][35] = 36, + [2][1][RTW89_MKK][35] = 56, + [2][1][RTW89_IC][35] = 50, + [2][1][RTW89_KCC][35] = 48, + [2][1][RTW89_ACMA][35] = 36, + [2][1][RTW89_CHILE][35] = 56, + [2][1][RTW89_UKRAINE][35] = 36, + [2][1][RTW89_MEXICO][35] = 50, + [2][1][RTW89_CN][35] = 127, + [2][1][RTW89_QATAR][35] = 36, + [2][1][RTW89_UK][35] = 36, + [2][1][RTW89_FCC][37] = 50, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 54, + [2][1][RTW89_IC][37] = 50, + [2][1][RTW89_KCC][37] = 48, + [2][1][RTW89_ACMA][37] = 60, + [2][1][RTW89_CHILE][37] = 56, + [2][1][RTW89_UKRAINE][37] = 127, + [2][1][RTW89_MEXICO][37] = 50, + [2][1][RTW89_CN][37] = 127, + [2][1][RTW89_QATAR][37] = 127, + [2][1][RTW89_UK][37] = 66, + [2][1][RTW89_FCC][38] = 84, + [2][1][RTW89_ETSI][38] = 16, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 84, + [2][1][RTW89_KCC][38] = 48, + [2][1][RTW89_ACMA][38] = 84, + [2][1][RTW89_CHILE][38] = 58, + [2][1][RTW89_UKRAINE][38] = 16, + [2][1][RTW89_MEXICO][38] = 84, + [2][1][RTW89_CN][38] = 62, + [2][1][RTW89_QATAR][38] = 16, + [2][1][RTW89_UK][38] = 38, + [2][1][RTW89_FCC][40] = 84, + [2][1][RTW89_ETSI][40] = 16, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 84, + [2][1][RTW89_KCC][40] = 48, + [2][1][RTW89_ACMA][40] = 84, + [2][1][RTW89_CHILE][40] = 58, + [2][1][RTW89_UKRAINE][40] = 16, + [2][1][RTW89_MEXICO][40] = 84, + [2][1][RTW89_CN][40] = 62, + [2][1][RTW89_QATAR][40] = 16, + [2][1][RTW89_UK][40] = 38, + [2][1][RTW89_FCC][42] = 84, + [2][1][RTW89_ETSI][42] = 16, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 84, + [2][1][RTW89_KCC][42] = 48, + [2][1][RTW89_ACMA][42] = 84, + [2][1][RTW89_CHILE][42] = 58, + [2][1][RTW89_UKRAINE][42] = 16, + [2][1][RTW89_MEXICO][42] = 84, + [2][1][RTW89_CN][42] = 62, + [2][1][RTW89_QATAR][42] = 16, + [2][1][RTW89_UK][42] = 38, + [2][1][RTW89_FCC][44] = 84, + [2][1][RTW89_ETSI][44] = 16, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 84, + [2][1][RTW89_KCC][44] = 48, + [2][1][RTW89_ACMA][44] = 84, + [2][1][RTW89_CHILE][44] = 58, + [2][1][RTW89_UKRAINE][44] = 16, + [2][1][RTW89_MEXICO][44] = 84, + [2][1][RTW89_CN][44] = 62, + [2][1][RTW89_QATAR][44] = 16, + [2][1][RTW89_UK][44] = 38, + [2][1][RTW89_FCC][46] = 84, + [2][1][RTW89_ETSI][46] = 16, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 84, + [2][1][RTW89_KCC][46] = 48, + [2][1][RTW89_ACMA][46] = 84, + [2][1][RTW89_CHILE][46] = 58, + [2][1][RTW89_UKRAINE][46] = 16, + [2][1][RTW89_MEXICO][46] = 84, + [2][1][RTW89_CN][46] = 62, + [2][1][RTW89_QATAR][46] = 16, + [2][1][RTW89_UK][46] = 38, + [2][1][RTW89_FCC][48] = 44, + [2][1][RTW89_ETSI][48] = 127, + [2][1][RTW89_MKK][48] = 127, + [2][1][RTW89_IC][48] = 40, + [2][1][RTW89_KCC][48] = 127, + [2][1][RTW89_ACMA][48] = 127, + [2][1][RTW89_CHILE][48] = 127, + [2][1][RTW89_UKRAINE][48] = 127, + [2][1][RTW89_MEXICO][48] = 127, + [2][1][RTW89_CN][48] = 127, + [2][1][RTW89_QATAR][48] = 127, + [2][1][RTW89_UK][48] = 127, + [2][1][RTW89_FCC][50] = 44, + [2][1][RTW89_ETSI][50] = 127, + [2][1][RTW89_MKK][50] = 127, + [2][1][RTW89_IC][50] = 40, + [2][1][RTW89_KCC][50] = 127, + [2][1][RTW89_ACMA][50] = 127, + [2][1][RTW89_CHILE][50] = 127, + [2][1][RTW89_UKRAINE][50] = 127, + [2][1][RTW89_MEXICO][50] = 127, + [2][1][RTW89_CN][50] = 127, + [2][1][RTW89_QATAR][50] = 127, + [2][1][RTW89_UK][50] = 127, + [2][1][RTW89_FCC][52] = 44, + [2][1][RTW89_ETSI][52] = 127, + [2][1][RTW89_MKK][52] = 127, + [2][1][RTW89_IC][52] = 40, + [2][1][RTW89_KCC][52] = 127, + [2][1][RTW89_ACMA][52] = 127, + [2][1][RTW89_CHILE][52] = 127, + [2][1][RTW89_UKRAINE][52] = 127, + [2][1][RTW89_MEXICO][52] = 127, + [2][1][RTW89_CN][52] = 127, + [2][1][RTW89_QATAR][52] = 127, + [2][1][RTW89_UK][52] = 127, +}; + +const struct rtw89_phy_table rtw89_8852b_phy_bb_table = { + .regs = rtw89_8852b_phy_bb_regs, + .n_regs = ARRAY_SIZE(rtw89_8852b_phy_bb_regs), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table = { + .regs = rtw89_8852b_phy_bb_reg_gain, + .n_regs = ARRAY_SIZE(rtw89_8852b_phy_bb_reg_gain), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852b_phy_radioa_table = { + .regs = rtw89_8852b_phy_radioa_regs, + .n_regs = ARRAY_SIZE(rtw89_8852b_phy_radioa_regs), + .rf_path = RF_PATH_A, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852b_phy_radiob_table = { + .regs = rtw89_8852b_phy_radiob_regs, + .n_regs = ARRAY_SIZE(rtw89_8852b_phy_radiob_regs), + .rf_path = RF_PATH_B, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852b_phy_nctl_table = { + .regs = rtw89_8852b_phy_nctl_regs, + .n_regs = ARRAY_SIZE(rtw89_8852b_phy_nctl_regs), + .rf_path = 0, /* don't care */ +}; + +static +const struct rtw89_txpwr_table rtw89_8852b_byr_table = { + .data = rtw89_8852b_txpwr_byrate, + .size = ARRAY_SIZE(rtw89_8852b_txpwr_byrate), + .load = rtw89_phy_load_txpwr_byrate, +}; + +const struct rtw89_fw_txpwr_track_cfg rtw89_8852b_trk_cfg = { + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N] = _txpwr_track_delta_swingidx_5gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P] = _txpwr_track_delta_swingidx_5gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N] = _txpwr_track_delta_swingidx_5ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P] = _txpwr_track_delta_swingidx_5ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N] = &_txpwr_track_delta_swingidx_2gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P] = &_txpwr_track_delta_swingidx_2gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N] = &_txpwr_track_delta_swingidx_2ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P] = &_txpwr_track_delta_swingidx_2ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N] = &_txpwr_track_delta_swingidx_2g_cck_b_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P] = &_txpwr_track_delta_swingidx_2g_cck_b_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N] = &_txpwr_track_delta_swingidx_2g_cck_a_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P] = &_txpwr_track_delta_swingidx_2g_cck_a_p, +}; + +const struct rtw89_rfe_parms rtw89_8852b_dflt_parms = { + .byr_tbl = &rtw89_8852b_byr_table, + .rule_2ghz = { + .lmt = &rtw89_8852b_txpwr_lmt_2g, + .lmt_ru = &rtw89_8852b_txpwr_lmt_ru_2g, + }, + .rule_5ghz = { + .lmt = &rtw89_8852b_txpwr_lmt_5g, + .lmt_ru = &rtw89_8852b_txpwr_lmt_ru_5g, + }, + .tx_shape = { + .lmt_v0 = &rtw89_8852b_tx_shape_lmt, + .lmt_ru_v0 = &rtw89_8852b_tx_shape_lmt_ru, + }, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h new file mode 100644 index 000000000..d30a1fb43 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_8852B_TABLE_H__ +#define __RTW89_8852B_TABLE_H__ + +#include "core.h" + +extern const struct rtw89_phy_table rtw89_8852b_phy_bb_table; +extern const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table; +extern const struct rtw89_phy_table rtw89_8852b_phy_radioa_table; +extern const struct rtw89_phy_table rtw89_8852b_phy_radiob_table; +extern const struct rtw89_phy_table rtw89_8852b_phy_nctl_table; +extern const struct rtw89_fw_txpwr_track_cfg rtw89_8852b_trk_cfg; +extern const struct rtw89_rfe_parms rtw89_8852b_dflt_parms; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c new file mode 100644 index 000000000..9b48e70c2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2020-2022 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8852b.h" + +static const struct rtw89_pci_info rtw8852b_pci_info = { + .gen_def = &rtw89_pci_gen_ax, + .isr_def = &rtw89_pci_isr_ax, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_2048B, + .rx_burst = MAC_AX_RX_BURST_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_DISABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .rx_ring_eq_is_full = false, + .check_rx_tag = false, + .no_rxbd_fs = false, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN, + .rxhci_en_bit = B_AX_RXHCI_EN, + .rxbd_mode_bit = B_AX_RXBD_MODE, + .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, + .txbd_rwptr_clr2_reg = 0, + .dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO}, + .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1}, + .dma_stop2 = {0}, + .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1}, + .dma_busy2_reg = 0, + .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, + + .rpwm_addr = R_AX_PCIE_HRPWM, + .cpwm_addr = R_AX_CPWM, + .mit_addr = R_AX_INT_MIT_RX, + .wp_sel_addr = 0, + .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) | + BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) | + BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + .bd_ram_table = &rtw89_bd_ram_table_single, + + .ltr_set = rtw89_pci_ltr_set, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask, + .enable_intr = rtw89_pci_enable_intr, + .disable_intr = rtw89_pci_disable_intr, + .recognize_intrs = rtw89_pci_recognize_intrs, + + .ssid_quirks = NULL, +}; + +static const struct rtw89_driver_info rtw89_8852be_info = { + .chip = &rtw8852b_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8852b_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8852be_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb852), + .driver_data = (kernel_ulong_t)&rtw89_8852be_info, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb85b), + .driver_data = (kernel_ulong_t)&rtw89_8852be_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8852be_id_table); + +static struct pci_driver rtw89_8852be_driver = { + .name = "rtw89_8852be", + .id_table = rtw89_8852be_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8852be_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c new file mode 100644 index 000000000..3d93cee56 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -0,0 +1,957 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "coex.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852bt.h" +#include "rtw8852bt_rfk.h" +#include "rtw8852b_common.h" + +#define RTW8852BT_FW_FORMAT_MAX 0 +#define RTW8852BT_FW_BASENAME "rtw89/rtw8852bt_fw" +#define RTW8852BT_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8852BT_FW_BASENAME, RTW8852BT_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8852bt_hfc_chcfg_pcie[] = { + {16, 742, grp_0}, /* ACH 0 */ + {16, 742, grp_0}, /* ACH 1 */ + {16, 742, grp_0}, /* ACH 2 */ + {16, 742, grp_0}, /* ACH 3 */ + {0, 0, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {0, 0, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {15, 743, grp_0}, /* B0MGQ */ + {15, 743, grp_0}, /* B0HIQ */ + {0, 0, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852bt_hfc_pubcfg_pcie = { + 958, /* Group 0 */ + 0, /* Group 1 */ + 958, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8852bt_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8852bt_hfc_chcfg_pcie, &rtw8852bt_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8852bt_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size23, + &rtw89_mac_size.ple_size9, &rtw89_mac_size.wde_qt23, + &rtw89_mac_size.wde_qt23, &rtw89_mac_size.ple_qt57, + &rtw89_mac_size.ple_qt59}, + [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size23, + &rtw89_mac_size.ple_size9, &rtw89_mac_size.wde_qt23, + &rtw89_mac_size.wde_qt23, &rtw89_mac_size.ple_qt57, + &rtw89_mac_size.ple_qt_52bt_wow}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, + &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const u32 rtw8852bt_h2c_regs[RTW89_H2CREG_MAX] = { + R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, + R_AX_H2CREG_DATA3 +}; + +static const u32 rtw8852bt_c2h_regs[RTW89_C2HREG_MAX] = { + R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, + R_AX_C2HREG_DATA3 +}; + +static const u32 rtw8852bt_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3, +}; + +static const struct rtw89_page_regs rtw8852bt_page_regs = { + .hci_fc_ctrl = R_AX_HCI_FC_CTRL, + .ch_page_ctrl = R_AX_CH_PAGE_CTRL, + .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, + .ach_page_info = R_AX_ACH0_PAGE_INFO, + .pub_page_info3 = R_AX_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, + .pub_page_info1 = R_AX_PUB_PAGE_INFO1, + .pub_page_info2 = R_AX_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, + .wp_page_info1 = R_AX_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_def rtw8852bt_dcfo_comp = { + R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK +}; + +static const struct rtw89_imr_info rtw8852bt_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET, + .wsec_imr_reg = R_AX_SEC_DEBUG, + .wsec_imr_set = B_AX_IMR_ERROR, + .mpdu_tx_imr_set = 0, + .mpdu_rx_imr_set = 0, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, + .wde_imr_clr = B_AX_WDE_IMR_CLR_V01, + .wde_imr_set = B_AX_WDE_IMR_SET_V01, + .ple_imr_clr = B_AX_PLE_IMR_CLR, + .ple_imr_set = B_AX_PLE_IMR_SET, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V01, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, + .other_disp_imr_set = 0, + .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, + .bbrpt_err_imr_set = 0, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL, + .ptcl_imr_set = B_AX_PTCL_IMR_SET, + .cdma_imr_0_reg = R_AX_DLE_CTRL, + .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, + .cdma_imr_0_set = B_AX_DLE_IMR_SET, + .cdma_imr_1_reg = 0, + .cdma_imr_1_clr = 0, + .cdma_imr_1_set = 0, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, + .phy_intf_imr_clr = B_AX_PHYINFO_IMR_EN_ALL, + .phy_intf_imr_set = B_AX_PHYINFO_IMR_SET, + .rmac_imr_reg = R_AX_RMAC_ERR_ISR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR, + .rmac_imr_set = B_AX_RMAC_IMR_SET, + .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR, + .tmac_imr_set = B_AX_TMAC_IMR_SET, +}; + +static const struct rtw89_rrsr_cfgs rtw8852bt_rrsr_cfgs = { + .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8852bt_rfkill_regs = { + .pinmux = {R_AX_GPIO8_15_FUNC_SEL, + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_AX_GPIO_EXT_CTRL + 2, + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8852bt_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD_V1, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, + .bmode_pd_reg = R_BMODE_PDTH_EN_V1, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, + .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, + .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, + .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8852bt_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL_V1, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_EDCCA_LVL_V1, + .ppdu_mask = B_EDCCA_LVL_MSK3, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, +}; + +static const struct rtw89_pmac_regs rtw8852bt_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT, B_SIG_GG_CNT}, + .cck_spoofing = {R_SPOOF_CNT, B_SPOOF_CNT}, + .cck_brk = {}, + .brk = {R_CNT_BRK, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST, B_R1B_RX_RPT_RST}, + .r1b_rr_sel = {R_R1B_RR_SEL, B_R1B_RR_SEL}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = 0, + .eht_crc_ok_mask = 0, + .eht_crc_err_mask = 0, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852bt_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852bt_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852bt_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c), +}; + +static const u8 rtw89_btc_8852bt_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; +static const u8 rtw89_btc_8852bt_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; + +static int rtw8852bt_pwr_on_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | + B_AX_AFSM_PCIE_SUS_EN); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_OCP_L1_MASK, 7); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, + XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, + XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, + XTAL_SI_PON_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, + XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + + fsleep(1000); + + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + + if (!rtwdev->efuse.valid || rtwdev->efuse.power_k_valid) + goto func_en; + + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VOL_L1_MASK, 0x9); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VREFPFM_L_MASK, 0xA); + +func_en: + rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | + B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | + B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | + B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | + B_AX_DMACREG_GCKEN); + rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, + B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | + B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | + B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN | + B_AX_RMAC_EN); + + rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL, + B_AX_PINMUX_EESK_FUNC_SEL_MASK, 0x1); + + return 0; +} + +static int rtw8852bt_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, + XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, + XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); + rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x3); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + + return 0; +} + +static void rtw8852bt_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + enum rtw89_phy_idx phy_idx, bool en) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + if (band == RTW89_BAND_2G) + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + } +} + +static void rtw8852bt_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x1); + rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI, 0x1); + rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); + rtw8852bx_bb_reset_all(rtwdev, phy_idx); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 3); + rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + B_P1_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x3); + rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); +} + +static void rtw8852bt_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bx_set_channel_mac(rtwdev, chan, mac_idx); + rtw8852bx_set_channel_bb(rtwdev, chan, phy_idx); + rtw8852bt_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void rtw8852bt_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + static const u32 tssi_trk[2] = {R_P0_TSSI_TRK, R_P1_TSSI_TRK}; + + if (en) + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x0); + else + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x1); +} + +static void rtw8852bt_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, + u8 phy_idx, const struct rtw89_chan *chan) +{ + if (!rtwdev->dbcc_en) { + rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_A); + rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_B); + rtw8852bt_tssi_scan(rtwdev, phy_idx, chan); + } else { + if (phy_idx == RTW89_PHY_0) + rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_A); + else + rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_B); + } +} + +static void rtw8852bt_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf); +} + +static void rtw8852bt_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw8852bt_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0, chan); + rtw8852bt_adc_en(rtwdev, false); + fsleep(40); + rtw8852bt_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + rtw8852bt_adc_en(rtwdev, true); + rtw8852bt_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0, chan); + rtw8852bt_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); + } +} + +static void rtw8852bt_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + memset(rfk_mcc, 0, sizeof(*rfk_mcc)); + + rtw8852bt_dpk_init(rtwdev); + rtw8852bt_rck(rtwdev); + rtw8852bt_dack(rtwdev, RTW89_CHANCTX_0); + rtw8852bt_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); +} + +static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + + rtw8852bt_mcc_get_ch_info(rtwdev, phy_idx); + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + + rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx); + rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852bt_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852bt_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); + rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); +} + +static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8852bt_tssi_scan(rtwdev, phy_idx, chan); +} + +static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); +} + +static void rtw8852bt_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8852bt_dpk_track(rtwdev); +} + +static void rtw8852bt_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->kt_ver_adie = rtwdev->hal.acv; + md->bt_solo = 0; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + md->wa_type = 0; + + md->ant.type = BTC_ANT_SHARED; + md->ant.num = 2; + md->ant.isolation = 10; + md->ant.diversity = 0; + /* WL 1-stream+1-Ant is located at 0:s0(path-A) or 1:s1(path-B) */ + md->ant.single_pos = RF_PATH_A; + md->ant.btg_pos = RF_PATH_B; + + if (md->rfe_type == 0) { + rtwdev->btc.dm.error.map.rfe_type0 = true; + return; + } + + md->ant.num = (md->rfe_type % 2) ? 2 : 3; + md->ant.stream_cnt = 2; + md->wa_type |= BTC_WA_INIT_SCAN; + + if (md->ant.num == 2) { + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->wa_type |= BTC_WA_HFP_LAG; + } else { + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + } +} + +static void +rtw8852bt_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0)); + u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16)); + + switch (ctrl_all_time) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL, + B_AX_FORCE_PWR_BY_RATE_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL, + B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL, + B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, + ctrl_all_time); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL, + B_AX_FORCE_PWR_BY_RATE_EN, 0x1); + break; + } + + switch (ctrl_gnt_bt) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL, + B_AX_TXAGC_BT_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL, + B_AX_TXAGC_BT_MASK, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL, + B_AX_TXAGC_BT_MASK, ctrl_gnt_bt); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL, + B_AX_TXAGC_BT_EN, 0x1); + break; + } +} + +static const struct rtw89_chip_ops rtw8852bt_chip_ops = { + .enable_bb_rf = rtw8852bx_mac_enable_bb_rf, + .disable_bb_rf = rtw8852bx_mac_disable_bb_rf, + .bb_preinit = NULL, + .bb_postinit = NULL, + .bb_reset = rtw8852bt_bb_reset, + .bb_sethw = rtw8852bx_bb_sethw, + .read_rf = rtw89_phy_read_rf_v1, + .write_rf = rtw89_phy_write_rf_v1, + .set_channel = rtw8852bt_set_channel, + .set_channel_help = rtw8852bt_set_channel_help, + .read_efuse = rtw8852bx_read_efuse, + .read_phycap = rtw8852bx_read_phycap, + .fem_setup = NULL, + .data_setup = NULL, + .rfe_gpio = NULL, + .rfk_hw_init = NULL, + .rfk_init = rtw8852bt_rfk_init, + .rfk_init_late = NULL, + .rfk_channel = rtw8852bt_rfk_channel, + .rfk_band_changed = rtw8852bt_rfk_band_changed, + .rfk_scan = rtw8852bt_rfk_scan, + .rfk_track = rtw8852bt_rfk_track, + .power_trim = rtw8852bx_power_trim, + .set_txpwr = rtw8852bx_set_txpwr, + .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852bx_init_txpwr_unit, + .get_thermal = rtw8852bx_get_thermal, + .chan_to_rf18_val = NULL, + .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx, + .query_ppdu = rtw8852bx_query_ppdu, + .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi, + .phy_rpt_to_rssi = NULL, + .ctrl_nbtg_bt_tx = rtw8852bx_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset, + .digital_pwr_comp = NULL, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = rtw8852bt_pwr_on_func, + .pwr_off_func = rtw8852bt_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc, + .fill_txdesc = rtw89_core_fill_txdesc, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, + .get_ch_dma = {rtw89_core_get_ch_dma, + NULL, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, + .mac_cfg_gnt = rtw89_mac_cfg_gnt, + .stop_sch_tx = rtw89_mac_stop_sch_tx, + .resume_sch_tx = rtw89_mac_resume_sch_tx, + .h2c_dctl_sec_cam = NULL, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl, + .h2c_ampdu_cmac_tbl = NULL, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl, + .h2c_punctured_cmac_tbl = NULL, + .h2c_default_dmac_tbl = NULL, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8852bt_btc_set_rfe, + .btc_init_cfg = rtw8852bx_btc_init_cfg, + .btc_set_wl_pri = rtw8852bx_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8852bt_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8852bx_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8852bx_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852bx_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8852bx_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +static const struct rtw89_chanctx_listener rtw8852bt_chanctx_listener = { + .callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852bt_rfk_chanctx_cb, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8852bt = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, +}; +#endif + +const struct rtw89_chip_info rtw8852bt_chip_info = { + .chip_id = RTL8852BT, + .chip_gen = RTW89_CHIP_AX, + .ops = &rtw8852bt_chip_ops, + .mac_def = &rtw89_mac_gen_ax, + .phy_def = &rtw89_phy_gen_ax, + .fw_def = { + .fw_basename = RTW8852BT_FW_BASENAME, + .fw_format_max = RTW8852BT_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = true, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ, + .fw_blacklist = &rtw89_fw_blacklist_default, + .fifo_size = 458752, + .small_fifo_size = true, + .dle_scc_rsvd_size = 98304, + .max_amsdu_limit = 5000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = true, + .rsvd_ple_ofst = 0x6f800, + .qta_def = { + .hfc_param_ini = {rtw8852bt_hfc_param_ini_pcie, NULL, NULL, NULL}, + .dle_mem = {rtw8852bt_dle_mem_pcie, NULL, NULL, NULL}, + }, + .wde_qempty_acq_grpnum = 4, + .wde_qempty_mgq_grpsel = 4, + .rf_base_addr = {0xe000, 0xf000}, + .thermal_th = {0x32, 0x35}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = NULL, + .bb_gain_table = NULL, + .rf_table = {}, + .nctl_table = NULL, + .nctl_post_table = NULL, + .dflt_parms = NULL, + .rfe_parms_conf = NULL, + .chanctx_listener = &rtw8852bt_chanctx_listener, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8852bt_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = RTW89_MAX_MAC_ID_NUM, + .support_link_num = 0, + .support_chanctx_num = 2, + .support_rnr = false, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), + .support_unii4 = true, + .support_ant_gain = true, + .support_tas = false, + .support_sar_by_ant = true, + .support_noise = false, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = true, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = true, + .hw_sec_hdr = false, + .hw_mgmt_tx_encrypt = false, + .hw_tkip_crypto = true, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 10, + .scam_num = 128, + .bacam_num = 2, + .bacam_dynamic_num = 4, + .bacam_ver = RTW89_BACAM_V0, + .addrcam_ver = 0, + .ppdu_max_usr = 4, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, + .limit_efuse_size = 1280, + .dav_phy_efuse_size = 96, + .dav_log_efuse_size = 16, + .efuse_blocks = NULL, + .phycap_addr = 0x580, + .phycap_size = 128, + .para_ver = 0, + .wlcx_desired = 0x070e0000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8852bt_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8852bt_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852bt_mon_reg), + .mon_reg = rtw89_btc_8852bt_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8852bt_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8852bt_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852bt_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852bt_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, + .hci_func_en_addr = R_AX_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_txwd_body), + .txwd_body_size = sizeof(struct rtw89_txwd_body), + .txwd_info_size = sizeof(struct rtw89_txwd_info), + .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8852bt_h2c_regs, + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8852bt_c2h_regs, + .page_regs = &rtw8852bt_page_regs, + .wow_reason_reg = rtw8852bt_wow_wakeup_regs, + .cfo_src_fd = true, + .cfo_hw_comp = true, + .dcfo_comp = &rtw8852bt_dcfo_comp, + .dcfo_comp_sft = 10, + .imr_info = &rtw8852bt_imr_info, + .imr_dmac_table = NULL, + .imr_cmac_table = NULL, + .rrsr_cfgs = &rtw8852bt_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0}, + .bss_clr_map_reg = R_BSS_CLR_MAP_V1, + .rfkill_init = &rtw8852bt_rfkill_regs, + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, + .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | + BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | + BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), + .edcca_regs = &rtw8852bt_edcca_regs, + .pmac_regs = &rtw8852bt_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852bt, +#endif + .xtal_info = NULL, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8852bt_chip_info); + +MODULE_FIRMWARE(RTW8852BT_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BT driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt.h new file mode 100644 index 000000000..b76b36aaf --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW89_8852BT_H__ +#define __RTW89_8852BT_H__ + +#include "core.h" + +#define RF_PATH_NUM_8852BT 2 +#define BB_PATH_NUM_8852BT 2 + +extern const struct rtw89_chip_info rtw8852bt_chip_info; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c new file mode 100644 index 000000000..433807e71 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c @@ -0,0 +1,4283 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852bt.h" +#include "rtw8852bt_rfk.h" +#include "rtw8852bt_rfk_table.h" +#include "rtw8852b_common.h" + +#define RTW8852BT_RXDCK_VER 0x1 +#define RTW8852BT_IQK_VER 0x2a +#define RTW8852BT_SS 2 +#define RTW8852BT_TSSI_PATH_NR 2 +#define RTW8852BT_DPK_VER 0x06 +#define DPK_RF_PATH_MAX_8852BT 2 + +#define _TSSI_DE_MASK GENMASK(21, 12) +#define DPK_TXAGC_LOWER 0x2e +#define DPK_TXAGC_UPPER 0x3f +#define DPK_TXAGC_INVAL 0xff +#define RFREG_MASKRXBB 0x003e0 +#define RFREG_MASKMODE 0xf0000 + +enum rf_mode { + RF_SHUT_DOWN = 0x0, + RF_STANDBY = 0x1, + RF_TX = 0x2, + RF_RX = 0x3, + RF_TXIQK = 0x4, + RF_DPK = 0x5, + RF_RXK1 = 0x6, + RF_RXK2 = 0x7, +}; + +enum rtw8852bt_dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, + DPK_RXAGC = 0x15, + KIP_PRESET = 0x16, + KIP_RESTORE = 0x17, + DPK_TXAGC = 0x19, + D_KIP_PRESET = 0x28, + D_TXAGC = 0x29, + D_RXAGC = 0x2a, + D_SYNC = 0x2b, + D_GAIN_LOSS = 0x2c, + D_MDPK_IDL = 0x2d, + D_GAIN_NORM = 0x2f, + D_KIP_THERMAL = 0x30, + D_KIP_RESTORE = 0x31 +}; + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_ADJ, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +enum rtw8852bt_iqk_type { + ID_TXAGC = 0x0, + ID_FLOK_COARSE = 0x1, + ID_FLOK_FINE = 0x2, + ID_TXK = 0x3, + ID_RXAGC = 0x4, + ID_RXK = 0x5, + ID_NBTXK = 0x6, + ID_NBRXK = 0x7, + ID_FLOK_VBUFFER = 0x8, + ID_A_FLOK_COARSE = 0x9, + ID_G_FLOK_COARSE = 0xa, + ID_A_FLOK_FINE = 0xb, + ID_G_FLOK_FINE = 0xc, + ID_IQK_RESTORE = 0x10, +}; + +enum adc_ck { + ADC_NA = 0, + ADC_480M = 1, + ADC_960M = 2, + ADC_1920M = 3, +}; + +enum dac_ck { + DAC_40M = 0, + DAC_80M = 1, + DAC_120M = 2, + DAC_160M = 3, + DAC_240M = 4, + DAC_320M = 5, + DAC_480M = 6, + DAC_960M = 7, +}; + +static const u32 _tssi_trigger[RTW8852BT_TSSI_PATH_NR] = {0x5820, 0x7820}; +static const u32 _tssi_cw_rpt_addr[RTW8852BT_TSSI_PATH_NR] = {0x1c18, 0x3c18}; +static const u32 _tssi_cw_default_addr[RTW8852BT_TSSI_PATH_NR][4] = { + {0x5634, 0x5630, 0x5630, 0x5630}, + {0x7634, 0x7630, 0x7630, 0x7630} }; +static const u32 _tssi_cw_default_mask[4] = { + 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff}; +static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852BT] = {0x5858, 0x7858}; +static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852BT] = {0x5860, 0x7860}; +static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852BT] = {0x5838, 0x7838}; +static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852BT] = {0x5840, 0x7840}; +static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852BT] = {0x5848, 0x7848}; +static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852BT] = {0x5850, 0x7850}; +static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852BT] = {0x5828, 0x7828}; +static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852BT] = {0x5830, 0x7830}; + +static const u32 rtw8852bt_backup_bb_regs[] = {0x2344, 0x5800, 0x7800, 0x0704}; +static const u32 rtw8852bt_backup_rf_regs[] = { + 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x5, 0x10005}; +static const u32 rtw8852bt_backup_kip_regs[] = { + 0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0c4, 0xc0ec, + 0x823c, 0x8224, 0x8220, 0xc1d4, 0xc1d8, 0xc1c4, 0xc1ec}; + +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852bt_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852bt_backup_rf_regs) +#define BACKUP_KIP_REGS_NR ARRAY_SIZE(rtw8852bt_backup_kip_regs) + +static void _rfk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + + udelay(200); + + dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", + dpk->bp[path][kidx].ther_dpk); +} + +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852bt_backup_bb_regs[i], MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]backup bb reg : %x, value =%x\n", + rtw8852bt_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_kip_reg(struct rtw89_dev *rtwdev, u32 backup_kip_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_KIP_REGS_NR; i++) { + backup_kip_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852bt_backup_kip_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + rtw8852bt_backup_kip_regs[i], backup_kip_reg_val[i]); + } +} + +static +void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, rtw8852bt_backup_rf_regs[i], + RFREG_MASK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup RF S%d 0x%x = %x\n", + rf_path, rtw8852bt_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_reload_bb_reg(struct rtw89_dev *rtwdev, const u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852bt_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore bb reg : %x, value =%x\n", + rtw8852bt_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_reload_kip_reg(struct rtw89_dev *rtwdev, u32 backup_kip_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_KIP_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852bt_backup_kip_regs[i], + MASKDWORD, backup_kip_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore kip reg : %x, value =%x\n", + rtw8852bt_backup_kip_regs[i], backup_kip_reg_val[i]); + } +} + +static void _rfk_reload_rf_reg(struct rtw89_dev *rtwdev, + const u32 backup_rf_reg_val[], u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8852bt_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8852bt_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u8 val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n", + rtwdev->dbcc_en, phy_idx); + + if (!rtwdev->dbcc_en) { + val = RF_AB; + } else { + if (phy_idx == RTW89_PHY_0) + val = RF_A; + else + val = RF_B; + } + return val; +} + +static +void _txck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool force, + enum dac_ck ck) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1); +} + +static +void _rxck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool force, + enum adc_ck ck) +{ + u32 bw = 0; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1); + + switch (ck) { + case ADC_480M: + bw = RTW89_CHANNEL_WIDTH_40; + break; + case ADC_960M: + bw = RTW89_CHANNEL_WIDTH_80; + break; + case ADC_1920M: + bw = RTW89_CHANNEL_WIDTH_160; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s==>Invalid ck", __func__); + break; + } + + rtw8852bx_adc_cfg(rtwdev, bw, path); +} + +static void _rfk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x3); + rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x1ffffff); + rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x3ff); + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_CLKEN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST, B_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_PATH_RST, B_P0_PATH_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_PATH_RST, B_P1_PATH_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DCFO_WEIGHT, B_DAC_CLK_IDX, 0x1); + + _txck_force(rtwdev, RF_PATH_A, true, DAC_960M); + _txck_force(rtwdev, RF_PATH_B, true, DAC_960M); + _rxck_force(rtwdev, RF_PATH_A, true, ADC_1920M); + _rxck_force(rtwdev, RF_PATH_B, true, ADC_1920M); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x5); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0041); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_RSTB, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x3333); + + rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H, B_TXPWRB_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN, MASKLWORD, 0x0000); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_FORCE, B_P1_TXPW_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXAGC_TH, MASKLWORD, 0x0000); +} + +static void _rfk_bb_afe_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x63); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0000); + rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H, B_TXPWRB_RDY, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TXPW_RSTB, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TXPW_RSTB, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_FORCE, B_P1_TXPW_RDY, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TXPW_RSTB, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TXPW_RSTB, 0x2); +} + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + mdelay(1); +} + +static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, dck_tune; + u32 rf_reg5; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n", + RTW8852BT_RXDCK_VER, rtwdev->hal.cv); + + for (path = 0; path < RF_PATH_NUM_8852BT; path++) { + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x1); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + _set_rx_dck(rtwdev, phy, path); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, + R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x0); + } +} + +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5; + u32 rck_val; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, + false, rtwdev, path, RR_RCKS, BIT(3)); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", + rck_val, ret); + + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); +} + +static void _drck(struct rtw89_dev *rtwdev) +{ + u32 rck_d; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_DRCK_RES, B_DRCK_POL); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); + + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); + + rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, 0x7c00); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, rck_d); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + + for (i = 0; i < 0x10; i++) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); + dack->msbk_d[0][0][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); + + rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); + dack->msbk_d[0][1][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); + } + + dack->biask_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); + dack->biask_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); + + dack->dadck_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00); + dack->dadck_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01); +} + +static void _dack_backup_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + + for (i = 0; i < 0x10; i++) { + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i); + dack->msbk_d[1][0][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S); + + rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i); + dack->msbk_d[1][1][i] = + rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S); + } + + dack->biask_d[1][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10); + dack->biask_d[1][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11); + + dack->dadck_d[1][0] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10); + dack->dadck_d[1][1] = + rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11); +} + +static +void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + if (path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10_RST, 0x1); + } +} + +static +void _dack_reload_by_path(struct rtw89_dev *rtwdev, u8 path, u8 index) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 tmp, tmp_offset, tmp_reg; + u32 idx_offset, path_offset; + u8 i; + + if (index == 0) + idx_offset = 0; + else + idx_offset = 0x14; + + if (path == RF_PATH_A) + path_offset = 0; + else + path_offset = 0x28; + + tmp_offset = idx_offset + path_offset; + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DACK2_K, B_DACK2_RST, 0x1); + + /* msbk_d: 15/14/13/12 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); + tmp_reg = 0xc200 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + + /* msbk_d: 11/10/9/8 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); + tmp_reg = 0xc204 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + + /* msbk_d: 7/6/5/4 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); + tmp_reg = 0xc208 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + + /* msbk_d: 3/2/1/0 */ + tmp = 0x0; + for (i = 0; i < 4; i++) + tmp |= dack->msbk_d[path][index][i] << (i * 8); + tmp_reg = 0xc20c + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + + /* dadak_d/biask_d */ + tmp = (dack->biask_d[path][index] << 22) | + (dack->dadck_d[path][index] << 14); + tmp_reg = 0xc210 + tmp_offset; + rtw89_phy_write32(rtwdev, tmp_reg, tmp); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, + rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); + + /* enable DACK result from reg */ + rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL + tmp_offset, B_DACKN0_EN, 0x1); +} + +static +void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u8 i; + + for (i = 0; i < 2; i++) + _dack_reload_by_path(rtwdev, path, i); +} + +static bool _dack_s0_poll(struct rtw89_dev *rtwdev) +{ + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) + return false; + + return true; +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + _txck_force(rtwdev, RF_PATH_A, true, DAC_160M); + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, BIT(28), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN1, 0x0); + udelay(100); + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_VAL, 0x30); + rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_VAL, 0x30); + + _dack_reset(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); + udelay(1); + + dack->msbk_timeout[0] = false; + + ret = read_poll_timeout_atomic(_dack_s0_poll, done, done, + 1, 20000, false, rtwdev); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x0); + + _txck_force(rtwdev, RF_PATH_A, false, DAC_960M); + _dack_backup_s0(rtwdev); + _dack_reload(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); +} + +static bool _dack_s1_poll(struct rtw89_dev *rtwdev) +{ + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0) + return false; + + return true; +} + +static void _dack_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + _txck_force(rtwdev, RF_PATH_B, true, DAC_160M); + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, BIT(28), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN1, 0x0); + udelay(100); + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_VAL, 0x30); + rtw89_phy_write32_mask(rtwdev, R_DACK2_K, B_DACK2_VAL, 0x30); + + _dack_reset(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x1); + udelay(1); + + dack->msbk_timeout[1] = false; + + ret = read_poll_timeout_atomic(_dack_s1_poll, done, done, + 1, 10000, false, rtwdev); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DACK timeout\n"); + dack->msbk_timeout[1] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x0); + + _txck_force(rtwdev, RF_PATH_B, false, DAC_960M); + _dack_backup_s1(rtwdev); + _dack_reload(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); + _dack_s1(rtwdev); +} + +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[1][0], dack->addck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[1][0], dack->biask_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _addck_ori(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); + udelay(100); + + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(4), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x0); + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); + dack->addck_timeout[0] = false; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_ADDCKR0, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(4), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); + dack->addck_d[0][0] = + rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); + dack->addck_d[0][1] = + rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); + udelay(100); + + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(4), 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x0); + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1); + dack->addck_timeout[1] = false; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, + rtwdev, R_ADDCKR1, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); + dack->addck_timeout[1] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(4), 0x0); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0); + dack->addck_d[1][0] = + rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0); + dack->addck_d[1][1] = + rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1); + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, dack->addck_d[0][1]); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1, dack->addck_d[1][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0, dack->addck_d[1][1]); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x3); +} + +static void _dack_manual_off(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL, B_DACKN0_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DACKN1_CTL, B_DACKN1_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DACKN2_CTL, B_DACKN2_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DACKN3_CTL, B_DACKN3_ON, 0x0); +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + dack->dack_done = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + + _drck(rtwdev); + _dack_manual_off(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1); + _rxck_force(rtwdev, RF_PATH_A, true, ADC_960M); + _rxck_force(rtwdev, RF_PATH_B, true, ADC_960M); + _addck_ori(rtwdev); + + _rxck_force(rtwdev, RF_PATH_A, false, ADC_960M); + _rxck_force(rtwdev, RF_PATH_B, false, ADC_960M); + _addck_reload(rtwdev); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); + + _dack(rtwdev); + _dack_dump(rtwdev); + dack->dack_done = true; + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RFREG_MASK, 0x1); + + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) +{ + bool notready = false; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 8200, false, + rtwdev, R_RFK_ST, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL1 IQK timeout!!!\n"); + + udelay(10); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, + 10, 400, false, + rtwdev, R_RPT_COM, B_RPT_COM_RDY); + if (ret) { + notready = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL2 IQK timeout!!!\n"); + } + + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + + return notready; +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path, u8 ktype) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 iqk_cmd; + bool fail; + + switch (ktype) { + case ID_TXAGC: + iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); + break; + case ID_FLOK_COARSE: + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_FLOK_FINE: + iqk_cmd = 0x208 | (1 << (4 + path)); + break; + case ID_FLOK_VBUFFER: + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_TXK: + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_RXAGC: + iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + iqk_cmd = 0x008 | (1 << (path + 4)) | + (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); + break; + case ID_NBTXK: + iqk_cmd = 0x408 | (1 << (4 + path)); + break; + case ID_NBRXK: + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s, iqk_cmd = %x\n", + __func__, iqk_cmd + 1); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + fail = _iqk_check_cal(rtwdev, path, ktype); + + return fail; +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x00); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x5); + udelay(1); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x80); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x4); + udelay(1); + break; + default: + break; + } +} + +static bool _iqk_2g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000119 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000219 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + return false; +} + +static bool _iqk_5g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000119 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000219 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4)); + + _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + return false; +} + +static bool _iqk_2g_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + static const u32 g_power_range[4] = {0x0, 0x0, 0x0, 0x0}; + static const u32 g_track_range[4] = {0x4, 0x4, 0x6, 0x6}; + static const u32 g_gain_bb[4] = {0x08, 0x0e, 0x08, 0x0e}; + static const u32 g_itqt[4] = {0x09, 0x12, 0x1b, 0x24}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool notready = false; + bool kfail = false; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + for (gp = 0x0; gp < 0x4; gp++) { + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000100, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000010, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000004, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000003, gp); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, + 0x009); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, g_itqt[gp]); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + + if (iqk_info->is_nbiqk) + break; + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, g_itqt[gp]); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, gp = 0x%x, 0x8%x38 = 0x%x\n", + path, gp, 1 << path, iqk_info->nb_txcfir[path]); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + iqk_info->nb_txcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_TXCFIR, 0x0); + } + + return kfail; +} + +static bool _iqk_5g_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + static const u32 a_power_range[4] = {0x0, 0x0, 0x0, 0x0}; + static const u32 a_track_range[4] = {0x3, 0x3, 0x6, 0x6}; + static const u32 a_gain_bb[4] = {0x08, 0x10, 0x08, 0x0e}; + static const u32 a_itqt[4] = {0x09, 0x12, 0x1b, 0x24}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool notready = false; + bool kfail = false; + u8 gp; + + for (gp = 0x0; gp < 0x4; gp++) { + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, a_itqt[gp]); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000100, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000010, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000004, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000003, gp); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, + 0x009); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, a_itqt[gp]); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + + if (iqk_info->is_nbiqk) + break; + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, a_itqt[gp]); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, gp = 0x%x, 0x8%x38 = 0x%x\n", + path, gp, 1 << path, iqk_info->nb_txcfir[path]); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + iqk_info->nb_txcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_TXCFIR, 0x0); + } + + return kfail; +} + +static void _iqk_adc_fifo_rst(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333); +} + +static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + + if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { + _rxck_force(rtwdev, RF_PATH_A, true, ADC_960M); + _rxck_force(rtwdev, RF_PATH_B, true, ADC_960M); + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_VAL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0x8); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0x8); + } else { + _rxck_force(rtwdev, RF_PATH_A, true, ADC_480M); + _rxck_force(rtwdev, RF_PATH_B, true, ADC_480M); + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_VAL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xf); + } + + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, 0x00000780, 0x8); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x00000780, 0x8); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, 0x00007800, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x00007800, 0x2); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_MUL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333); +} + +static bool _iqk_2g_rx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + static const u32 g_idxrxgain[2] = {0x212, 0x310}; + static const u32 g_idxattc2[2] = {0x00, 0x20}; + static const u32 g_idxattc1[2] = {0x3, 0x2}; + static const u32 g_idxrxagc[2] = {0x0, 0x2}; + static const u32 g_idx[2] = {0x0, 0x2}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool notready = false; + bool kfail = false; + u32 rf_18, tmp; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); + rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18); + + for (gp = 0x0; gp < 0x2; gp++) { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, g_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, g_idxattc1[gp]); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000100, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000010, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000007, g_idx[gp]); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + udelay(100); + udelay(100); + + tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, tmp); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, rf rxbb = %x\n", path, + rtw89_read_rf(rtwdev, path, RR_MOD, 0x003c0)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + udelay(100); + udelay(100); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD) | 0x2; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, gp = 0x%x, 0x8%x3c = 0x%x\n", path, + g_idx[gp], 1 << path, iqk_info->nb_rxcfir[path]); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + if (iqk_info->is_nbiqk) + break; + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + iqk_info->nb_txcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_RXCFIR, 0x0); + } + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); + + return kfail; +} + +static bool _iqk_5g_rx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + static const u32 a_idxrxgain[2] = {0x110, 0x290}; + static const u32 a_idxattc2[2] = {0x0f, 0x0f}; + static const u32 a_idxattc1[2] = {0x2, 0x2}; + static const u32 a_idxrxagc[2] = {0x4, 0x6}; + static const u32 a_idx[2] = {0x0, 0x2}; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool notready = false; + bool kfail = false; + u32 rf_18, tmp; + u8 gp; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); + rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18); + + for (gp = 0x0; gp < 0x2; gp++) { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, a_idxattc2[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, a_idxattc1[gp]); + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000100, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000010, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + 0x00000007, a_idx[gp]); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + udelay(100); + udelay(100); + + tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, tmp); + rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); + + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, rf rxbb = %x\n", path, + rtw89_read_rf(rtwdev, path, RR_MOD, 0x003c0)); + + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); + udelay(200); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD) | 0x2; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, gp = 0x%x, 0x8%x3c = 0x%x\n", + path, a_idx[gp], 1 << path, iqk_info->nb_rxcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + if (iqk_info->is_nbiqk) + break; + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + } + + if (!notready) + kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); + + if (kfail) { + iqk_info->nb_txcfir[path] = 0x40000002; + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), + B_IQK_RES_RXCFIR, 0x0); + } + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); + + return kfail; +} + +static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool lok_result = false; + bool txk_result = false; + bool rxk_result = false; + u8 i; + + for (i = 0; i < 3; i++) { + _iqk_txk_setting(rtwdev, path); + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + lok_result = _iqk_2g_lok(rtwdev, phy_idx, path); + else + lok_result = _iqk_5g_lok(rtwdev, phy_idx, path); + + if (!lok_result) + break; + } + + if (lok_result) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]!!!!!!!!!!LOK by Pass !!!!!!!!!!!\n"); + rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); + rtw89_write_rf(rtwdev, path, RR_LOKVB, RFREG_MASK, 0x80200); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x08[00:19] = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x09[00:19] = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RSV2, RFREG_MASK)); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x0a[00:19] = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK)); + + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + txk_result = _iqk_2g_tx(rtwdev, phy_idx, path); + else + txk_result = _iqk_5g_tx(rtwdev, phy_idx, path); + + _iqk_rxclk_setting(rtwdev, path); + _iqk_adc_fifo_rst(rtwdev, phy_idx, path); + + if (iqk_info->iqk_band[path] == RTW89_BAND_2G) + rxk_result = _iqk_2g_rx(rtwdev, phy_idx, path); + else + rxk_result = _iqk_5g_rx(rtwdev, phy_idx, path); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]result : lok_= %x, txk_= %x, rxk_= %x\n", + lok_result, txk_result, rxk_result); +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = rfk_mcc->table_idx; + u32 reg_rf18; + u32 reg_35c; + + reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN); + + iqk_info->iqk_band[path] = chan->band_type; + iqk_info->iqk_bw[path] = chan->band_width; + iqk_info->iqk_ch[path] = chan->channel; + iqk_info->iqk_mcc_ch[idx][path] = chan->channel; + iqk_info->iqk_table_idx[path] = idx; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x, idx = %x\n", + path, reg_rf18, idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x\n", + path, reg_rf18); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x35c= 0x%x\n", + path, reg_35c); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", + iqk_info->iqk_times, idx); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n", + idx, path, iqk_info->iqk_mcc_ch[idx][path]); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + _iqk_by_path(rtwdev, phy_idx, path); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__); + + if (iqk_info->is_nbiqk) { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, iqk_info->nb_txcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, iqk_info->nb_rxcfir[path]); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD, 0x40000000); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD, 0x40000000); + } + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00000e19 + (path << 4)); + + _iqk_check_cal(rtwdev, path, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + + rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), BIT(28), 0x0); + + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0x3); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x0000000); + rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, 0x0000001f, 0x03); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, 0x000003e0, 0x03); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, + B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000); + rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x0); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + u8 idx = rfk_mcc->table_idx; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 0x00000001, idx); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 0x00000008, idx); + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000000); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_GOT_TXRX, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_GOT_TXRX, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P0_CLKG_FORCE, 0x3); + rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x1ffffff); + rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x3ff); + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_CLKEN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST, B_IQK_DPK_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_PATH_RST, B_P0_PATH_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_PATH_RST, B_P1_PATH_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DCFO_WEIGHT, B_DAC_CLK_IDX, 0x1); + + _txck_force(rtwdev, RF_PATH_A, true, DAC_960M); + _txck_force(rtwdev, RF_PATH_B, true, DAC_960M); + _rxck_force(rtwdev, RF_PATH_A, true, ADC_1920M); + _rxck_force(rtwdev, RF_PATH_B, true, ADC_1920M); + + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x2); + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + udelay(10); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_RSTB, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333); +} + +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx, path; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0); + + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->iqk_times = 0x0; + + for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { + iqk_info->iqk_channel[idx] = 0x0; + for (path = 0; path < RTW8852BT_SS; path++) { + iqk_info->lok_cor_fail[idx][path] = false; + iqk_info->lok_fin_fail[idx][path] = false; + iqk_info->iqk_tx_fail[idx][path] = false; + iqk_info->iqk_rx_fail[idx][path] = false; + iqk_info->iqk_mcc_ch[idx][path] = 0x0; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u32 rf_mode; + u8 path; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, + rf_mode != 2, 2, 5000, false, + rtwdev, path, RR_MOD, RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret); + } +} + +static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx, + bool is_pause) +{ + if (!is_pause) + return; + + _wait_rx_mode(rtwdev, _kpath(rtwdev, band_idx)); +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852BT_SS][BACKUP_RF_REGS_NR]; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->version = RTW8852BT_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + + _rfk_backup_bb_reg(rtwdev, backup_bb_val); + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_reload_bb_reg(rtwdev, backup_bb_val); + _rfk_reload_rf_reg(rtwdev, backup_rf_val[path], path); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 kpath = _kpath(rtwdev, phy_idx); + + switch (kpath) { + case RF_A: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + break; + case RF_B: + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + case RF_AB: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + default: + break; + } +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 val, kidx = dpk->cur_idx[path]; + + val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + BIT(24), val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); +} + +static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw8852bt_dpk_id id) +{ + u16 dpk_cmd; + u32 val; + int ret; + + dpk_cmd = (id << 8) | (0x19 + (path << 4)); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 1, 30000, false, + rtwdev, R_RFK_ST, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 1 over 30ms!!!!\n"); + + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00030000); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, + 1, 2000, false, + rtwdev, R_RPT_COM, MASKLWORD); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 2 over 2ms!!!!\n"); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%04x\n", + id == 0x06 ? "LBK_RXIQK" : + id == 0x10 ? "SYNC" : + id == 0x11 ? "MDPK_IDL" : + id == 0x12 ? "MDPK_MPA" : + id == 0x13 ? "GAIN_LOSS" : + id == 0x14 ? "PWR_CAL" : + id == 0x15 ? "DPK_RXAGC" : + id == 0x16 ? "KIP_PRESET" : + id == 0x17 ? "KIP_RESTORE" : + "DPK_TXAGC", dpk_cmd); +} + +static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + + udelay(600); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d RXDCK\n", path); +} + +static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = chan->band_type; + dpk->bp[path][kidx].ch = chan->channel; + dpk->bp[path][kidx].bw = chan->band_width; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + str_on_off(rtwdev->is_tssi_mode[path]), + str_on_off(rtwdev->dbcc_en), + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + + if (rtwdev->hal.cv > CHIP_CAV) + rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), + B_DPD_COM_OF, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 cur_rxbb, u32 rf_18) +{ + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, 0x0); + + rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0xd); + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); + + if (cur_rxbb >= 0x11) + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x13); + else if (cur_rxbb <= 0xa) + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x00); + else + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x05); + + rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80014); + + udelay(100); + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x025); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); + + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0x5); +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_FATT, 0xf2); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SWATT, 0x5); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + rtw89_write_rf(rtwdev, path, RR_RXA_LNA, RFREG_MASK, 0x920FC); + rtw89_write_rf(rtwdev, path, RR_XALNA2, RFREG_MASK, 0x002C0); + rtw89_write_rf(rtwdev, path, RR_IQGEN, RFREG_MASK, 0x38800); + } + + rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); + rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); +} + +static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bypass) +{ + if (is_bypass) { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), + B_RXIQC_BYPASS, 0x0); + } +} + +static +void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + else + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static void _dpk_table_select(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 kidx, u8 gain) +{ + u8 val; + + val = 0x80 + kidx * 0x20 + gain * 0x10; + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, + gain, val); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define DPK_SYNC_TH_DC_I 200 +#define DPK_SYNC_TH_DC_Q 200 +#define DPK_SYNC_TH_CORR 170 + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 corr_val, corr_idx; + u16 dc_i, dc_q; + u32 corr, dc; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + corr = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + corr_idx = u32_get_bits(corr, B_PRT_COM_CORI); + corr_val = u32_get_bits(corr, B_PRT_COM_CORV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", + path, corr_idx, corr_val); + + dpk->corr_idx[path][kidx] = corr_idx; + dpk->corr_val[path][kidx] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + dc_i = u32_get_bits(dc, B_PRT_COM_DCI); + dc_q = u32_get_bits(dc, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", + path, dc_i, dc_q); + + dpk->dc_i[path][kidx] = dc_i; + dpk->dc_q[path][kidx] = dc_q; + + if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || + corr_val < DPK_SYNC_TH_CORR) + return true; + else + return false; +} + +static void _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, SYNC); +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); + + return dgain; +} + +static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) +{ + static const u16 bnd[15] = { + 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556, + 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220 + }; + s8 offset; + + if (dgain >= bnd[0]) + offset = 0x6; + else if (bnd[0] > dgain && dgain >= bnd[1]) + offset = 0x6; + else if (bnd[1] > dgain && dgain >= bnd[2]) + offset = 0x5; + else if (bnd[2] > dgain && dgain >= bnd[3]) + offset = 0x4; + else if (bnd[3] > dgain && dgain >= bnd[4]) + offset = 0x3; + else if (bnd[4] > dgain && dgain >= bnd[5]) + offset = 0x2; + else if (bnd[5] > dgain && dgain >= bnd[6]) + offset = 0x1; + else if (bnd[6] > dgain && dgain >= bnd[7]) + offset = 0x0; + else if (bnd[7] > dgain && dgain >= bnd[8]) + offset = 0xff; + else if (bnd[8] > dgain && dgain >= bnd[9]) + offset = 0xfe; + else if (bnd[9] > dgain && dgain >= bnd[10]) + offset = 0xfd; + else if (bnd[10] > dgain && dgain >= bnd[11]) + offset = 0xfc; + else if (bnd[11] > dgain && dgain >= bnd[12]) + offset = 0xfb; + else if (bnd[12] > dgain && dgain >= bnd[13]) + offset = 0xfa; + else if (bnd[13] > dgain && dgain >= bnd[14]) + offset = 0xf9; + else if (bnd[14] > dgain) + offset = 0xf8; + else + offset = 0x0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain offset = %d\n", offset); + + return offset; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + + return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); +} + +static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); +} + +static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_tpg_sel(rtwdev, path, kidx); + _dpk_one_shot(rtwdev, phy, path, KIP_PRESET); +} + +static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); + rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP Power/CLK on\n"); +} + +static +u8 _dpk_txagc_check_8852bt(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 txagc) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (txagc >= dpk->max_dpk_txagc[path]) + txagc = dpk->max_dpk_txagc[path]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set TxAGC = 0x%x\n", txagc); + + return txagc; +} + +static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 txagc) +{ + u8 val; + + val = _dpk_txagc_check_8852bt(rtwdev, path, txagc); + rtw89_write_rf(rtwdev, path, RR_TXAGC, RFREG_MASK, val); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + _dpk_one_shot(rtwdev, phy, path, DPK_TXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set TXAGC = 0x%x\n", txagc); +} + +static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, 0x50220); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); + _dpk_one_shot(rtwdev, phy, path, DPK_RXAGC); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); +} + +static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 txagc, s8 gain_offset) +{ + txagc = rtw89_read_rf(rtwdev, path, RR_TXAGC, RFREG_MASK); + + if ((txagc - gain_offset) < DPK_TXAGC_LOWER) + txagc = DPK_TXAGC_LOWER; + else if ((txagc - gain_offset) > DPK_TXAGC_UPPER) + txagc = DPK_TXAGC_UPPER; + else + txagc = txagc - gain_offset; + + _dpk_kip_set_txagc(rtwdev, phy, path, txagc); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", + gain_offset, txagc); + return txagc; +} + +static bool _dpk_pas_read(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + + if (val1_i * val1_i + val1_q * val1_q >= + (val2_i * val2_i + val2_q * val2_q) * 8 / 5) + return true; + + return false; +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_txagc, + bool loss_only, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 goout = 0, agc_cnt = 0, limited_rxbb = 0, gl_cnt = 0; + u8 tmp_txagc, tmp_rxbb, tmp_gl_idx = 0; + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + int limit = 200; + s8 offset = 0; + u16 dgain = 0; + u32 rf_18; + + tmp_txagc = init_txagc; + + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB); + rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + _dpk_sync(rtwdev, phy, path, kidx); + if (agc_cnt == 0) { + if (chan->band_width < 2) + _dpk_bypass_rxcfir(rtwdev, path, true); + else + _dpk_lbk_rxiqk(rtwdev, phy, path, + tmp_rxbb, rf_18); + } + + if (_dpk_sync_check(rtwdev, path, kidx) == true) { + tmp_txagc = 0xff; + goout = 1; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + offset = _dpk_dgain_mapping(rtwdev, dgain); + + if (loss_only == 1 || limited_rxbb == 1 || offset == 0) + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + else + step = DPK_AGC_STEP_GAIN_ADJ; + break; + case DPK_AGC_STEP_GAIN_ADJ: + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB); + + if (tmp_rxbb + offset > 0x1f) { + tmp_rxbb = 0x1f; + limited_rxbb = 1; + } else if (tmp_rxbb + offset < 0) { + tmp_rxbb = 0; + limited_rxbb = 1; + } else { + tmp_rxbb = tmp_rxbb + offset; + } + + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB, tmp_rxbb); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_80) + _dpk_lbk_rxiqk(rtwdev, phy, path, tmp_rxbb, rf_18); + if (dgain > 1922 || dgain < 342) + step = DPK_AGC_STEP_SYNC_DGAIN; + else + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + + agc_cnt++; + break; + case DPK_AGC_STEP_GAIN_LOSS_IDX: + _dpk_gainloss(rtwdev, phy, path, kidx); + + tmp_gl_idx = _dpk_gainloss_read(rtwdev); + + if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, path, true)) || + tmp_gl_idx >= 7) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + + gl_cnt++; + break; + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_txagc == 0x2e || + tmp_txagc == dpk->max_dpk_txagc[path]) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, + tmp_txagc, 0x3); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_txagc == 0x3f || tmp_txagc == dpk->max_dpk_txagc[path]) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, + tmp_txagc, 0xfe); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + agc_cnt++; + break; + + case DPK_AGC_STEP_SET_TX_GAIN: + tmp_txagc = _dpk_set_offset(rtwdev, phy, path, tmp_txagc, + tmp_gl_idx); + goout = 1; + agc_cnt++; + break; + + default: + goout = 1; + break; + } + } while (!goout && agc_cnt < 6 && limit-- > 0); + + if (gl_cnt >= 6) + _dpk_pas_read(rtwdev, path, false); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, tmp_rxbb); + + return tmp_txagc; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 order) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + switch (order) { + case 0: /* (5,3,1) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); + dpk->dpk_order[path] = 0x3; + break; + case 1: /* (5,3,0) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x0); + dpk->dpk_order[path] = 0x1; + break; + case 2: /* (5,0,0) */ + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x0); + dpk->dpk_order[path] = 0x0; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Wrong MDPD order!!(0x%x)\n", order); + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", + order == 0x0 ? "(5,3,1)" : + order == 0x1 ? "(5,3,0)" : "(5,0,0)"); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Set MDPD order to 0x%x for IDL\n", order); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 gain) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 && + dpk->bp[path][kidx].band == RTW89_BAND_5G) + _dpk_set_mdpd_para(rtwdev, path, 0x2); + else + _dpk_set_mdpd_para(rtwdev, path, 0x0); + + _dpk_one_shot(rtwdev, phy, path, MDPK_IDL); +} + +static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 gs = dpk->dpk_gs[phy]; + u16 pwsf = 0x78; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), BIT(8), kidx); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", + txagc, pwsf, gs); + + dpk->bp[path][kidx].txagc_dpk = txagc; + rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), + 0x3F << ((gain << 3) + (kidx << 4)), txagc); + + dpk->bp[path][kidx].pwsf = pwsf; + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x1FF << (gain << 4), pwsf); + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); + + dpk->bp[path][kidx].gs = gs; + if (dpk->dpk_gs[phy] == 0x7f) + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x007f7f7f); + else + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + MASKDWORD, 0x005b5b5b); + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_ORDER_V1, dpk->dpk_order[path]); + + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, 0x0); +} + +static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 idx, cur_band, cur_ch; + bool is_reload = false; + + cur_band = chan->band_type; + cur_ch = chan->channel; + + for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { + if (cur_band != dpk->bp[path][idx].band || + cur_ch != dpk->bp[path][idx].ch) + continue; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, idx); + dpk->cur_idx[path] = idx; + is_reload = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] reload S%d[%d] success\n", path, idx); + } + + return is_reload; +} + +static +void _rf_direct_cntrl(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static +void _drf_direct_cntrl(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 gain, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 txagc = 0x38, kidx = dpk->cur_idx[path]; + bool is_fail = false; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx); + + _rf_direct_cntrl(rtwdev, path, false); + _drf_direct_cntrl(rtwdev, path, false); + + _dpk_kip_pwr_clk_on(rtwdev, path); + _dpk_kip_set_txagc(rtwdev, phy, path, txagc); + _dpk_rf_setting(rtwdev, gain, path, kidx); + _dpk_rx_dck(rtwdev, phy, path); + _dpk_kip_preset(rtwdev, phy, path, kidx); + _dpk_kip_set_rxagc(rtwdev, phy, path); + _dpk_table_select(rtwdev, path, kidx, gain); + + txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx); + + _rfk_get_thermal(rtwdev, kidx, path); + + if (txagc == 0xff) { + is_fail = true; + goto _error; + } + + _dpk_idl_mpa(rtwdev, phy, path, kidx, gain); + + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, RF_RX); + _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc); + +_error: + if (!is_fail) + dpk->bp[path][kidx].path_ok = 1; + else + dpk->bp[path][kidx].path_ok = 0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, + is_fail ? "Check" : "Success"); + + _dpk_onoff(rtwdev, path, is_fail); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, + is_fail ? "Check" : "Success"); + + return is_fail; +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u32 backup_kip_val[BACKUP_KIP_REGS_NR]; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852BT_SS][BACKUP_RF_REGS_NR]; + bool reloaded[2] = {false}; + u8 path; + + for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) { + reloaded[path] = _dpk_reload_check(rtwdev, phy, path, chanctx_idx); + if (!reloaded[path] && dpk->bp[path][0].ch != 0) + dpk->cur_idx[path] = !dpk->cur_idx[path]; + else + _dpk_onoff(rtwdev, path, false); + } + + _rfk_backup_bb_reg(rtwdev, backup_bb_val); + _rfk_backup_kip_reg(rtwdev, backup_kip_val); + + for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) { + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _dpk_information(rtwdev, phy, path, chanctx_idx); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + } + + _rfk_bb_afe_setting(rtwdev, phy, path, kpath); + + for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) + _dpk_main(rtwdev, phy, path, 1, chanctx_idx); + + _rfk_bb_afe_restore(rtwdev, phy, path, kpath); + + _dpk_kip_restore(rtwdev, path); + _rfk_reload_bb_reg(rtwdev, backup_bb_val); + _rfk_reload_kip_reg(rtwdev, backup_kip_val); + + for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) { + _rfk_reload_rf_reg(rtwdev, backup_rf_val[path], path); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } +} + +static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_fem_info *fem = &rtwdev->fem; + + if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] Skip DPK due to 6G_ext_PA exist!!\n"); + return true; + } + + return false; +} + +static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, kpath; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RTW8852BT_SS; path++) { + if (kpath & BIT(path)) + _dpk_onoff(rtwdev, path, true); + } +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst; + s8 delta_ther[2] = {}; + u8 trk_idx, txagc_rf; + u8 path, kidx; + u16 pwsf[2]; + u8 cur_ther; + u32 tmp; + + for (path = 0; path < RF_PATH_NUM_8852BT; path++) { + kidx = dpk->cur_idx[path]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] thermal now = %d\n", cur_ther); + + if (dpk->bp[path][kidx].ch && cur_ther) + delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + delta_ther[path] = delta_ther[path] * 3 / 2; + else + delta_ther[path] = delta_ther[path] * 5 / 2; + + txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + B_TXAGC_RF); + + if (rtwdev->is_tssi_mode[path]) { + trk_idx = rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", + txagc_rf, trk_idx); + + txagc_bb = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + MASKBYTE2); + txagc_bb_tp = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13), + B_TXAGC_TP); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + txagc_ofst = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), + MASKBYTE3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", + txagc_ofst, delta_ther[path]); + tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), + B_DPD_COM_OF); + if (tmp == 0x1) { + txagc_ofst = 0; + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] HW txagc offset mode\n"); + } + + if (txagc_rf && cur_ther) + ini_diff = txagc_ofst + (delta_ther[path]); + + tmp = rtw89_phy_read32_mask(rtwdev, + R_P0_TXDPD + (path << 13), + B_P0_TXDPD); + if (tmp == 0x0) { + pwsf[0] = dpk->bp[path][kidx].pwsf + + txagc_bb_tp - txagc_bb + ini_diff; + pwsf[1] = dpk->bp[path][kidx].pwsf + + txagc_bb_tp - txagc_bb + ini_diff; + } else { + pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff; + pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff; + } + } else { + pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; + } + + tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS); + if (!tmp && txagc_rf) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", + pwsf[0], pwsf[1]); + + rtw89_phy_write32_mask(rtwdev, + R_DPD_BND + (path << 8) + (kidx << 2), + B_DPD_BND_0, pwsf[0]); + rtw89_phy_write32_mask(rtwdev, + R_DPD_BND + (path << 8) + (kidx << 2), + B_DPD_BND_1, pwsf[1]); + } + } +} + +static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 tx_scale, ofdm_bkof, path, kpath; + + kpath = _kpath(rtwdev, phy); + + ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM); + tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA); + + if (ofdm_bkof + tx_scale >= 44) { + /* move dpd backoff to bb, and set dpd backoff to 0 */ + dpk->dpk_gs[phy] = 0x7f; + for (path = 0; path < RF_PATH_NUM_8852BT; path++) { + if (!(kpath & BIT(path))) + continue; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8), + B_DPD_CFG, 0x7f7f7f); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Set S%d DPD backoff to 0dB\n", path); + } + } else { + dpk->dpk_gs[phy] = 0x5b; + } +} + +static void _tssi_dpk_off(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A, BIT(24), 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0B, BIT(24), 0x0); +} + +static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (band == RTW89_BAND_2G) + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); +} + +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + rtw89_rfk_parser(rtwdev, &rtw8852bt_tssi_sys_defs_tbl); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_80) + rtw89_phy_write32_mask(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_BW80, 0x1); + else + rtw89_phy_write32_mask(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_BW80, 0x0); + + if (path == RF_PATH_A) + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852bt_tssi_sys_a_defs_2g_tbl, + &rtw8852bt_tssi_sys_a_defs_5g_tbl); + else + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852bt_tssi_sys_b_defs_2g_tbl, + &rtw8852bt_tssi_sys_b_defs_5g_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852bt_tssi_init_txpwr_defs_a_tbl, + &rtw8852bt_tssi_init_txpwr_defs_b_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852bt_tssi_init_txpwr_he_tb_defs_a_tbl, + &rtw8852bt_tssi_init_txpwr_he_tb_defs_b_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852bt_tssi_dck_defs_a_tbl, + &rtw8852bt_tssi_dck_defs_b_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ +#define RTW8852BT_TSSI_GET_VAL(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 subband = chan->subband_type; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + R_P0_TSSI_BASE + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, + thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852BT_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + + } else { + thermal = tssi_info->thermal[RF_PATH_B]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, + thermal); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_b[i++] : + -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_b[i++] : + thm_up_b[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852BT_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); + } +#undef RTW8852BT_TSSI_GET_VAL +} + +static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852bt_tssi_dac_gain_defs_a_tbl, + &rtw8852bt_tssi_dac_gain_defs_b_tbl); +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (path == RF_PATH_A) + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852bt_tssi_slope_a_defs_2g_tbl, + &rtw8852bt_tssi_slope_a_defs_5g_tbl); + else + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852bt_tssi_slope_b_defs_2g_tbl, + &rtw8852bt_tssi_slope_b_defs_5g_tbl); +} + +static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, bool all, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + const struct rtw89_rfk_tbl *tbl = NULL; + u8 ch = chan->channel; + + if (path == RF_PATH_A) { + if (band == RTW89_BAND_2G) + tbl = &rtw8852bt_tssi_align_a_2g_all_defs_tbl; + else if (ch >= 36 && ch <= 64) + tbl = &rtw8852bt_tssi_align_a_5g1_all_defs_tbl; + else if (ch >= 100 && ch <= 144) + tbl = &rtw8852bt_tssi_align_a_5g2_all_defs_tbl; + else if (ch >= 149 && ch <= 177) + tbl = &rtw8852bt_tssi_align_a_5g3_all_defs_tbl; + } else { + if (ch >= 1 && ch <= 14) + tbl = &rtw8852bt_tssi_align_b_2g_all_defs_tbl; + else if (ch >= 36 && ch <= 64) + tbl = &rtw8852bt_tssi_align_b_5g1_all_defs_tbl; + else if (ch >= 100 && ch <= 144) + tbl = &rtw8852bt_tssi_align_b_5g2_all_defs_tbl; + else if (ch >= 149 && ch <= 177) + tbl = &rtw8852bt_tssi_align_b_5g3_all_defs_tbl; + } + + if (tbl) + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852bt_tssi_slope_defs_a_tbl, + &rtw8852bt_tssi_slope_defs_b_tbl); +} + +static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, 0x0); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "======>%s path=%d\n", __func__, + path); + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, + B_P0_TSSI_MV_MIX, 0x010); + else + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, + B_P1_RFCTM_DEL, 0x010); +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852BT; i++) { + _tssi_set_tssi_track(rtwdev, phy, i); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); + + if (i == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, + B_P0_TSSI_MV_CLR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, + B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, + B_P0_TSSI_EN, 0x1); + rtw89_write_rf(rtwdev, i, RR_TXGA_V1, + RR_TXGA_V1_TRK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_RFC, 0x3); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, + B_P0_TSSI_OFT_EN, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = true; + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, + B_P1_TSSI_MV_CLR, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, + B_P1_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, + B_P1_TSSI_EN, 0x1); + rtw89_write_rf(rtwdev, i, RR_TXGA_V1, + RR_TXGA_V1_TRK_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_RFC, 0x3); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, + B_P1_TSSI_OFT_EN, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_B] = true; + } + } +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, 0x1); + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 gidx, gidx_1st, gidx_2nd; + s8 de_1st; + s8 de_2nd; + s8 val; + + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u32 tgidx, tgidx_1st, tgidx_2nd; + s8 tde_1st; + s8 tde_2nd; + s8 val; + + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852BT; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + _tssi_de_cck_long[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], + _TSSI_DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], + _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + _tssi_de_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], + _TSSI_DE_MASK)); + } +} + +static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" + "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", + R_TSSI_PA_K1 + (path << 13), + rtw89_phy_read32(rtwdev, R_TSSI_PA_K1 + (path << 13)), + R_TSSI_PA_K2 + (path << 13), + rtw89_phy_read32(rtwdev, R_TSSI_PA_K2 + (path << 13)), + R_P0_TSSI_ALIM1 + (path << 13), + rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM1 + (path << 13)), + R_P0_TSSI_ALIM3 + (path << 13), + rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM3 + (path << 13)), + R_TSSI_PA_K5 + (path << 13), + rtw89_phy_read32(rtwdev, R_TSSI_PA_K5 + (path << 13)), + R_P0_TSSI_ALIM2 + (path << 13), + rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM2 + (path << 13)), + R_P0_TSSI_ALIM4 + (path << 13), + rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM4 + (path << 13)), + R_TSSI_PA_K8 + (path << 13), + rtw89_phy_read32(rtwdev, R_TSSI_PA_K8 + (path << 13))); +} + +static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, enum rtw89_rf_path path, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 channel = chan->channel; + u8 band; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d path=%d\n", __func__, phy, path); + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + if (tssi_info->alignment_done[path][band]) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][0]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][1]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][2]); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, + tssi_info->alignment_value[path][band][3]); + } + + _tssi_alimentk_dump_result(rtwdev, path); +} + +static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm, + u8 enable, const struct rtw89_chan *chan) +{ + enum rtw89_rf_path_bit rx_path; + + if (path == RF_PATH_A) + rx_path = RF_A; + else if (path == RF_PATH_B) + rx_path = RF_B; + else if (path == RF_PATH_AB) + rx_path = RF_AB; + else + rx_path = RF_ABCD; /* don't change path, but still set others */ + + if (enable) { + rtw8852bx_bb_set_plcp_tx(rtwdev); + rtw8852bx_bb_cfg_tx_path(rtwdev, path); + rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan); + rtw8852bx_bb_set_power(rtwdev, pwr_dbm, phy); + } + + rtw8852bx_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy, chan); +} + +static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const u32 reg[], + u32 reg_backup[], u32 reg_num) +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + reg_backup[i] = rtw89_phy_read32_mask(rtwdev, reg[i], MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i], + reg_backup[i]); + } +} + +static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const u32 reg[], + u32 reg_backup[], u32 reg_num) + +{ + u32 i; + + for (i = 0; i < reg_num; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i], MASKDWORD, reg_backup[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i], + reg_backup[i]); + } +} + +static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel) +{ + u8 channel_index; + + if (channel >= 1 && channel <= 14) + channel_index = channel - 1; + else if (channel >= 36 && channel <= 64) + channel_index = (channel - 36) / 2 + 14; + else if (channel >= 100 && channel <= 144) + channel_index = ((channel - 100) / 2) + 15 + 14; + else if (channel >= 149 && channel <= 177) + channel_index = ((channel - 149) / 2) + 38 + 14; + else + channel_index = 0; + + return channel_index; +} + +static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const s16 *power, + u32 *tssi_cw_rpt, const struct rtw89_chan *chan) +{ + u32 tx_counter, tx_counter_tmp; + const int retry = 100; + u32 tmp; + int j, k; + + for (j = 0; j < RTW8852BT_TSSI_PATH_NR; j++) { + rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x1); + + tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_trigger[path], MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] 0x%x = 0x%08x path=%d\n", + _tssi_trigger[path], tmp, path); + + if (j == 0) + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true, + chan); + else + _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true, + chan); + + tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] First HWTXcounter=%d path=%d\n", + tx_counter_tmp, path); + + for (k = 0; k < retry; k++) { + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], + B_TSSI_CWRPT_RDY); + if (tmp) + break; + + udelay(30); + + tx_counter_tmp = + rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n", + k, tx_counter_tmp, path); + } + + if (k >= retry) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n", + k, path); + + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan); + return false; + } + + tssi_cw_rpt[j] = + rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], + B_TSSI_CWRPT); + + _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan); + + tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); + tx_counter_tmp -= tx_counter; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] Final HWTXcounter=%d path=%d\n", + tx_counter_tmp, path); + } + + return true; +} + +static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4, + 0x78e4, 0x49c0, 0x0d18, 0x0d80}; + static const s16 power_2g[4] = {48, 20, 4, -8}; + static const s16 power_5g[4] = {48, 20, 4, 4}; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3; + u32 tssi_cw_rpt[RTW8852BT_TSSI_PATH_NR] = {}; + u8 channel = chan->channel; + u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel); + struct rtw8852bx_bb_tssi_bak tssi_bak; + s32 aliment_diff, tssi_cw_default; + u32 bb_reg_backup[8] = {}; + ktime_t start_time; + const s16 *power; + s64 this_time; + u8 band; + bool ok; + u32 tmp; + u8 j; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s channel=%d path=%d\n", __func__, channel, + path); + + start_time = ktime_get(); + + if (chan->band_type == RTW89_BAND_2G) + power = power_2g; + else + power = power_5g; + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + rtw8852bx_bb_backup_tssi(rtwdev, phy, &tssi_bak); + _tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, + ARRAY_SIZE(bb_reg_backup)); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x8); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); + + ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt, chan); + if (!ok) + goto out; + + for (j = 0; j < RTW8852BT_TSSI_PATH_NR; j++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j, + power[j], j, tssi_cw_rpt[j]); + } + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][1], + _tssi_cw_default_mask[1]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) - + tssi_cw_rpt[1] + tssi_cw_default; + aliment_diff = tssi_alim_offset_1 - tssi_cw_default; + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][2], + _tssi_cw_default_mask[2]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_2 = tssi_cw_default + aliment_diff; + + tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][3], + _tssi_cw_default_mask[3]); + tssi_cw_default = sign_extend32(tmp, 8); + tssi_alim_offset_3 = tssi_cw_default + aliment_diff; + + if (path == RF_PATH_A) { + tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | + FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | + FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, tmp); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12), + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13)); + } else { + tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | + FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | + FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, tmp); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13)); + } + + tssi_info->alignment_done[path][band] = true; + tssi_info->alignment_value[path][band][0] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][1] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][2] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); + tssi_info->alignment_value[path][band][3] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); + + tssi_info->check_backup_aligmk[path][ch_idx] = true; + tssi_info->alignment_backup_by_ch[path][ch_idx][0] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][1] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][2] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); + tssi_info->alignment_backup_by_ch[path][ch_idx][3] = + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM1 + (path << 13), + tssi_info->alignment_value[path][band][0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM3 + (path << 13), + tssi_info->alignment_value[path][band][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM2 + (path << 13), + tssi_info->alignment_value[path][band][2]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n", + path, band, R_P0_TSSI_ALIM4 + (path << 13), + tssi_info->alignment_value[path][band][3]); + +out: + _tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, + ARRAY_SIZE(bb_reg_backup)); + rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak); + rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0); + + this_time = ktime_us_delta(ktime_get(), start_time); + tssi_info->tssi_alimk_time += this_time; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n", + __func__, this_time, tssi_info->tssi_alimk_time); +} + +void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 path; + + for (path = 0; path < 2; path++) { + dpk->cur_idx[path] = 0; + dpk->max_dpk_txagc[path] = 0x3F; + } + + dpk->is_dpk_enable = true; + dpk->is_dpk_reload_en = false; + _set_dpd_backoff(rtwdev, RTW89_PHY_0); +} + +void rtw8852bt_rck(struct rtw89_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < RF_PATH_NUM_8852BT; path++) + _rck(rtwdev, path); +} + +void rtw8852bt_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); + _dac_cal(rtwdev, false); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); +} + +void rtw8852bt_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + _iqk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + +void rtw8852bt_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _rx_dck(rtwdev, phy_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); +} + +void rtw8852bt_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** DPK Start (Ver: 0x%x) ******\n", RTW8852BT_DPK_VER); + + if (_dpk_bypass_check(rtwdev, phy_idx, chanctx_idx)) + _dpk_force_bypass(rtwdev, phy_idx); + else + _dpk_cal_select(rtwdev, phy_idx, RF_AB, chanctx_idx); +} + +void rtw8852bt_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + +void rtw8852bt_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + static const u32 reg[2] = {R_DPD_CH0A, R_DPD_CH0B}; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB, chanctx_idx); + u32 reg_backup[2] = {}; + u32 tx_en; + u8 i; + + _tssi_backup_bb_registers(rtwdev, phy, reg, reg_backup, 2); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + _tssi_dpk_off(rtwdev, phy); + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RF_PATH_NUM_8852BT; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_set_dac_gain_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_alignment_default(rtwdev, phy, i, true, chan); + _tssi_set_tssi_slope(rtwdev, phy, i); + + rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); + _tmac_tx_pause(rtwdev, phy, true); + if (hwtx_en) + _tssi_alimentk(rtwdev, phy, i, chan); + _tmac_tx_pause(rtwdev, phy, false); + rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); + + _tssi_reload_bb_registers(rtwdev, phy, reg, reg_backup, 2); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +void rtw8852bt_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 channel = chan->channel; + u8 band; + u32 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s phy=%d channel=%d\n", __func__, phy, channel); + + if (channel >= 1 && channel <= 14) + band = TSSI_ALIMK_2G; + else if (channel >= 36 && channel <= 64) + band = TSSI_ALIMK_5GL; + else if (channel >= 100 && channel <= 144) + band = TSSI_ALIMK_5GM; + else if (channel >= 149 && channel <= 177) + band = TSSI_ALIMK_5GH; + else + band = TSSI_ALIMK_2G; + + _tssi_disable(rtwdev, phy); + + for (i = RF_PATH_A; i < RTW8852BT_TSSI_PATH_NR; i++) { + _tssi_rf_setting(rtwdev, phy, i, chan); + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + + if (tssi_info->alignment_done[i][band]) + _tssi_alimentk_done(rtwdev, phy, i, chan); + else + _tssi_alignment_default(rtwdev, phy, i, true, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +static void rtw8852bt_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 channel = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", + __func__, channel); + + if (enable) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 0xc0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); + + _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan); + _tssi_alimentk_done(rtwdev, phy, RF_PATH_B, chan); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", + __func__, + rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), + rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "======> %s SCAN_END\n", __func__); +} + +void rtw8852bt_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + if (scan_start) + rtw8852bt_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx); + else + rtw8852bt_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx); +} + +static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) +{ + u32 rf_reg18; + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + if (rf_reg18 == INV_RF_DATA) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]Invalid RF_0x18 for Path-%d\n", path); + return; + } + rf_reg18 &= ~RR_CFGCH_BW; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); + } + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", + bw, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + _bw_setting(rtwdev, RF_PATH_A, bw, true); + _bw_setting(rtwdev, RF_PATH_B, bw, true); + _bw_setting(rtwdev, RF_PATH_A, bw, false); + _bw_setting(rtwdev, RF_PATH_B, bw, false); +} + +static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) +{ + u32 tmp; + int ret; + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); + + ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, + false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + return !!ret; +} + +static void _lck_check(struct rtw89_dev *rtwdev) +{ + u32 tmp; + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); + } + + udelay(10); + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + } + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); + + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + _set_s0_arfc18(rtwdev, tmp); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", + rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), + rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); + } +} + +static void _set_ch(struct rtw89_dev *rtwdev, u32 val) +{ + bool timeout; + u32 bak; + + bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); + timeout = _set_s0_arfc18(rtwdev, val); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); + if (!timeout) + _lck_check(rtwdev); +} + +static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 central_ch, bool dav) +{ + u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; + bool is_2g_ch = central_ch <= 14; + u32 rf_reg18; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); + rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | + RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); + + if (!is_2g_ch) + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | + FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); + + rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | + RR_CFGCH_BW2) & RFREG_MASK; + rf_reg18 |= RR_CFGCH_BW2; + + if (path == RF_PATH_A && dav) + _set_ch(rtwdev, rf_reg18); + else + rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); + + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); + rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", + central_ch, path, reg18_addr, + rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); +} + +static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) +{ + _ch_setting(rtwdev, RF_PATH_A, central_ch, true); + _ch_setting(rtwdev, RF_PATH_B, central_ch, true); + _ch_setting(rtwdev, RF_PATH_A, central_ch, false); + _ch_setting(rtwdev, RF_PATH_B, central_ch, false); +} + +static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, + enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); + + if (bw == RTW89_CHANNEL_WIDTH_20) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); + else if (bw == RTW89_CHANNEL_WIDTH_40) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); + else if (bw == RTW89_CHANNEL_WIDTH_80) + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); + else + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", + path, rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); +} + +static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + u8 kpath, path; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RF_PATH_NUM_8852BT; path++) { + if (!(kpath & BIT(path))) + continue; + + _set_rxbb_bw(rtwdev, bw, path); + } +} + +static void rtw8852bt_ctrl_bw_ch(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 central_ch, + enum rtw89_band band, enum rtw89_bandwidth bw) +{ + _ctrl_ch(rtwdev, central_ch); + _ctrl_bw(rtwdev, phy, bw); + _rxbb_bw(rtwdev, phy, bw); +} + +void rtw8852bt_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8852bt_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, + chan->band_width); +} + +void rtw8852bt_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {}; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + u8 idx; + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[0]; + + for (idx = 0; idx < ARRAY_SIZE(desc); idx++) { + struct rtw89_rfk_chan_desc *p = &desc[idx]; + + p->ch = rfk_mcc->ch[idx]; + + p->has_band = true; + p->band = rfk_mcc->band[idx]; + } + + idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[idx] = chan->channel; + rfk_mcc->band[idx] = chan->band_type; + rfk_mcc->table_idx = idx; +} + +void rtw8852bt_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 path; + + switch (state) { + case RTW89_CHANCTX_STATE_MCC_START: + dpk->is_dpk_enable = false; + for (path = 0; path < RTW8852BT_SS; path++) + _dpk_onoff(rtwdev, path, false); + break; + case RTW89_CHANCTX_STATE_MCC_STOP: + dpk->is_dpk_enable = true; + for (path = 0; path < RTW8852BT_SS; path++) + _dpk_onoff(rtwdev, path, false); + rtw8852bt_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); + break; + default: + break; + } +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h new file mode 100644 index 000000000..a663bbda4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW89_8852BT_RFK_H__ +#define __RTW89_8852BT_RFK_H__ + +#include "core.h" + +void rtw8852bt_rck(struct rtw89_dev *rtwdev); +void rtw8852bt_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev); +void rtw8852bt_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_dpk_track(struct rtw89_dev *rtwdev); +void rtw8852bt_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan); +void rtw8852bt_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852bt_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +void rtw8852bt_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw8852bt_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c new file mode 100644 index 000000000..782144bb7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "rtw8852bt_rfk_table.h" + +static const struct rtw89_reg5_def rtw8852bt_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x4), + RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x4), + RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0x5555), + RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0x5555), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), + RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x19), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_sys_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_a_defs_2g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_sys_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_a_defs_5g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_sys_b_defs_2g[] = { + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_b_defs_2g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_sys_b_defs_5g[] = { + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_b_defs_5g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_defs_a[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x002d000), + RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x1dc80280), + RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00002080), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0xc00), + RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_defs_a); + +static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_defs_b[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x002d000), + RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x1dc80280), + RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00002080), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0xc00), + RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_defs_b); + +static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_he_tb_defs_b[] = { + RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_he_tb_defs_b); + +static const struct rtw89_reg5_def rtw8852bt_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x0ef), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8852bt_tssi_dck_defs_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x0ef), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dck_defs_b); + +static const struct rtw89_reg5_def rtw8852bt_tssi_dac_gain_defs_a[] = { + RTW89_DECL_RFK_WM(0x58b0, 0x00000400, 0x1), + RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000), + RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dac_gain_defs_a); + +static const struct rtw89_reg5_def rtw8852bt_tssi_dac_gain_defs_b[] = { + RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x000), + RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dac_gain_defs_b); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_a_defs_2g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0804008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_a_defs_2g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_a_defs_5g[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201019), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_a_defs_5g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_b_defs_2g[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0804008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08081e28), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_b_defs_2g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_b_defs_5g[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201019), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081808), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_b_defs_5g); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_2g_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x029f57c0), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000077), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x029f5bc0), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000076), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_2g_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g1_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x007ff3d7), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000068), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g1_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g2_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00a003db), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000065), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g2_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g3_all_defs[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01101be2), + RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000065), + RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g3_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_2g_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x023f3fb9), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000075), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x01df3fb8), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000074), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_2g_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g1_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x010017e0), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g1_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g2_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01201fe2), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000066), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g2_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g3_all_defs[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01602fe5), + RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000068), + RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g3_all_defs); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852bt_tssi_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_defs_b); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h new file mode 100644 index 000000000..beb246237 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW89_8852BT_RFK_TABLE_H__ +#define __RTW89_8852BT_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_b_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_b_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_he_tb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dck_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dac_gain_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dac_gain_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_a_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_a_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_b_defs_2g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_b_defs_5g_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_2g_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g1_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g2_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g3_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_2g_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g1_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g2_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g3_all_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_defs_b_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bte.c b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c new file mode 100644 index 000000000..850ae9cba --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8852bt.h" + +static const struct rtw89_pci_ssid_quirk rtw8852bt_pci_ssid_quirks[] = { + {RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0xB520, 0x103C, 0x88E9, HP), + .bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_110C)}, + {}, +}; + +static const struct rtw89_pci_info rtw8852bt_pci_info = { + .gen_def = &rtw89_pci_gen_ax, + .isr_def = &rtw89_pci_isr_ax, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_2048B, + .rx_burst = MAC_AX_RX_BURST_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_DISABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .rx_ring_eq_is_full = false, + .check_rx_tag = false, + .no_rxbd_fs = false, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN, + .rxhci_en_bit = B_AX_RXHCI_EN, + .rxbd_mode_bit = B_AX_RXBD_MODE, + .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, + .txbd_rwptr_clr2_reg = 0, + .dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO}, + .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1}, + .dma_stop2 = {0}, + .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1}, + .dma_busy2_reg = 0, + .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, + + .rpwm_addr = R_AX_PCIE_HRPWM, + .cpwm_addr = R_AX_CPWM, + .mit_addr = R_AX_INT_MIT_RX, + .wp_sel_addr = 0, + .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) | + BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) | + BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + .bd_ram_table = &rtw89_bd_ram_table_single, + + .ltr_set = rtw89_pci_ltr_set, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask, + .enable_intr = rtw89_pci_enable_intr, + .disable_intr = rtw89_pci_disable_intr, + .recognize_intrs = rtw89_pci_recognize_intrs, + + .ssid_quirks = rtw8852bt_pci_ssid_quirks, +}; + +static const struct rtw89_driver_info rtw89_8852bte_info = { + .chip = &rtw8852bt_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8852bt_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8852bte_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb520), + .driver_data = (kernel_ulong_t)&rtw89_8852bte_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8852bte_id_table); + +static struct pci_driver rtw89_8852bte_driver = { + .name = "rtw89_8852bte", + .id_table = rtw89_8852bte_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8852bte_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE-VT driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c new file mode 100644 index 000000000..de79a19a2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "rtw8852b.h" +#include "reg.h" +#include "usb.h" + +static const struct rtw89_usb_info rtw8852b_usb_info = { + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, + .usb_wlan0_1 = R_AX_USB_WLAN0_1, + .hci_func_en = R_AX_HCI_FUNC_EN, + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, + .rx_agg_alignment = 8, + .bulkout_id = { + [RTW89_DMA_ACH0] = 3, + [RTW89_DMA_ACH1] = 4, + [RTW89_DMA_ACH2] = 5, + [RTW89_DMA_ACH3] = 6, + [RTW89_DMA_B0MG] = 0, + [RTW89_DMA_B0HI] = 1, + [RTW89_DMA_H2C] = 2, + }, +}; + +static const struct rtw89_driver_info rtw89_8852bu_info = { + .chip = &rtw8852b_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .usb = &rtw8852b_usb_info, + } +}; + +static const struct usb_device_id rtw_8852bu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb832, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb83a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb852, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb85a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xa85b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3428, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1a62, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1cb6, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x6931, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0xf0c8, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3327, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6121, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0108, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x6822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8852bu_id_table); + +static struct usb_driver rtw_8852bu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8852bu_id_table, + .probe = rtw89_usb_probe, + .disconnect = rtw89_usb_disconnect, +}; +module_usb_driver(rtw_8852bu_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BU driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c new file mode 100644 index 000000000..c68959b63 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -0,0 +1,3303 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852c.h" +#include "rtw8852c_rfk.h" +#include "rtw8852c_table.h" +#include "sar.h" +#include "util.h" + +#define RTW8852C_FW_FORMAT_MAX 2 +#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw" +#define RTW8852C_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8852C_FW_BASENAME, RTW8852C_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = { + {13, 1614, grp_0}, /* ACH 0 */ + {13, 1614, grp_0}, /* ACH 1 */ + {13, 1614, grp_0}, /* ACH 2 */ + {13, 1614, grp_0}, /* ACH 3 */ + {13, 1614, grp_1}, /* ACH 4 */ + {13, 1614, grp_1}, /* ACH 5 */ + {13, 1614, grp_1}, /* ACH 6 */ + {13, 1614, grp_1}, /* ACH 7 */ + {13, 1614, grp_0}, /* B0MGQ */ + {13, 1614, grp_0}, /* B0HIQ */ + {13, 1614, grp_1}, /* B1MGQ */ + {13, 1614, grp_1}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_pcie = { + 1614, /* Group 0 */ + 1614, /* Group 1 */ + 3228, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_pcie, &rtw8852c_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_usb[] = { + {18, 344, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {18, 344, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {18, 344, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {18, 344, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {18, 344, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {18, 344, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_usb = { + 344, /* Group 0 */ + 0, /* Group 1 */ + 344, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_prec_cfg rtw8852c_hfc_preccfg_usb = { + 9, /* CH 0-11 pre-cost */ + 32, /* H2C pre-cost */ + 146, /* WP CH 0-7 pre-cost */ + 146, /* WP CH 8-11 pre-cost */ + 1, /* CH 0-11 full condition */ + 1, /* H2C full condition */ + 1, /* WP CH 0-7 full condition */ + 1, /* WP CH 8-11 full condition */ +}; + +static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_usb[] = { + [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_usb, &rtw8852c_hfc_pubcfg_usb, + &rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, + &rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19, + &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18, + &rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46, + &rtw89_mac_size.ple_qt47}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, + &rtw89_mac_size.ple_qt45}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8852c_dle_mem_usb2[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size31, + &rtw89_mac_size.ple_size34, &rtw89_mac_size.wde_qt31, + &rtw89_mac_size.wde_qt31, &rtw89_mac_size.ple_qt78, + &rtw89_mac_size.ple_qt79}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, + &rtw89_mac_size.ple_qt45}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8852c_dle_mem_usb3[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size17, + &rtw89_mac_size.ple_size17, &rtw89_mac_size.wde_qt16, + &rtw89_mac_size.wde_qt16, &rtw89_mac_size.ple_qt42, + &rtw89_mac_size.ple_qt43}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, + &rtw89_mac_size.ple_qt45}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = { + R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1, + R_AX_H2CREG_DATA3_V1 +}; + +static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = { + R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1, + R_AX_C2HREG_DATA3_V1 +}; + +static const u32 rtw8852c_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3_V1 + 3, R_AX_DBG_WOW, +}; + +static const struct rtw89_page_regs rtw8852c_page_regs = { + .hci_fc_ctrl = R_AX_HCI_FC_CTRL_V1, + .ch_page_ctrl = R_AX_CH_PAGE_CTRL_V1, + .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL_V1, + .ach_page_info = R_AX_ACH0_PAGE_INFO_V1, + .pub_page_info3 = R_AX_PUB_PAGE_INFO3_V1, + .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1_V1, + .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2_V1, + .pub_page_info1 = R_AX_PUB_PAGE_INFO1_V1, + .pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1, + .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1_V1, + .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2_V1, + .wp_page_info1 = R_AX_WP_PAGE_INFO1_V1, +}; + +static const struct rtw89_reg_def rtw8852c_dcfo_comp = { + R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK +}; + +static const struct rtw89_imr_info rtw8852c_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET_V1, + .wsec_imr_reg = R_AX_SEC_ERROR_FLAG_IMR, + .wsec_imr_set = B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR, + .mpdu_tx_imr_set = B_AX_MPDU_TX_IMR_SET_V1, + .mpdu_rx_imr_set = B_AX_MPDU_RX_IMR_SET_V1, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_B0_ERRFLAG_IMR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR_V1, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET_V1, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_B1_ERRFLAG_IMR, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR_V1, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET_V1, + .wde_imr_clr = B_AX_WDE_IMR_CLR_V1, + .wde_imr_set = B_AX_WDE_IMR_SET_V1, + .ple_imr_clr = B_AX_PLE_IMR_CLR_V1, + .ple_imr_set = B_AX_PLE_IMR_SET_V1, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR_V1, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V1, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR_V1, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET_V1, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR_V1, + .other_disp_imr_set = B_AX_OTHER_DISP_IMR_SET_V1, + .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR, + .bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_V1, + .ptcl_imr_set = B_AX_PTCL_IMR_SET_V1, + .cdma_imr_0_reg = R_AX_RX_ERR_FLAG_IMR, + .cdma_imr_0_clr = B_AX_RX_ERR_IMR_CLR_V1, + .cdma_imr_0_set = B_AX_RX_ERR_IMR_SET_V1, + .cdma_imr_1_reg = R_AX_TX_ERR_FLAG_IMR, + .cdma_imr_1_clr = B_AX_TX_ERR_IMR_CLR_V1, + .cdma_imr_1_set = B_AX_TX_ERR_IMR_SET_V1, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR_V1, + .phy_intf_imr_clr = B_AX_PHYINFO_IMR_CLR_V1, + .phy_intf_imr_set = B_AX_PHYINFO_IMR_SET_V1, + .rmac_imr_reg = R_AX_RX_ERR_IMR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR_V1, + .rmac_imr_set = B_AX_RMAC_IMR_SET_V1, + .tmac_imr_reg = R_AX_TRXPTCL_ERROR_INDICA_MASK, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR_V1, + .tmac_imr_set = B_AX_TMAC_IMR_SET_V1, +}; + +static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = { + .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8852c_rfkill_regs = { + .pinmux = {R_AX_GPIO8_15_FUNC_SEL, + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_AX_GPIO_EXT_CTRL + 2, + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8852c_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK, + .bmode_pd_reg = R_BMODE_PDTH_EN_V1, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, + .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, + .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, + .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V1, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V1, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V1, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V1, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8852c_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_EDCCA_LVL, + .ppdu_mask = B_EDCCA_LVL_MSK3, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, +}; + +static const struct rtw89_pmac_regs rtw8852c_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT_V1, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT_V1, B_SIG_GG_CNT_V1}, + .cck_spoofing = {R_SPOOF_CNT_V1, B_SPOOF_CNT_V1}, + .cck_brk = {R_BRK_CNT, B_BRK_CNT}, + .brk = {R_CNT_BRK, B_CNT_BRK}, + .brk_option = {R_BRK_OPT, B_BRK_OPT}, + .search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST_V1, B_R1B_RX_RPT_RST_V1}, + .r1b_rr_sel = {}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = 0, + .eht_crc_ok_mask = 0, + .eht_crc_err_mask = 0, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx); + +static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path, + enum rtw89_mac_idx mac_idx); + +static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK); + if (val32 == MAC_AX_HCI_SEL_PCIE_USB || + rtwdev->hci.type == RTW89_HCI_TYPE_USB) + rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L); + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | + B_AX_AFSM_PCIE_SUS_EN); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); + rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, + B_AX_OCP_L1_MASK, 0x7); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + + rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); + + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP); + rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN | + B_AX_R_SYM_WLCMAC1_P3_PC_EN | + B_AX_R_SYM_WLCMAC1_P2_PC_EN | + B_AX_R_SYM_WLCMAC1_P1_PC_EN | + B_AX_R_SYM_WLCMAC1_PC_EN); + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, + XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, + XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, + XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, + XTAL_SI_PON_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, + XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0x10, XTAL_SI_LDO_LPS); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); + + fsleep(1000); + + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN, + B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN | + B_AX_LED1_PULL_LOW_EN); + + rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, + B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | + B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | + B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | + B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | + B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | + B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN); + + rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, + B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | + B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | + B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | + B_AX_TMAC_EN | B_AX_RMAC_EN); + + rtw89_write32_mask(rtwdev, R_AX_LED1_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK, + PINMUX_EESK_FUNC_SEL_BT_LOG); + + return 0; +} + +static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, + XTAL_SI_RFC2RF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, + XTAL_SI_SRAM2RFC); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); + rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, + B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1); + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), + 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR); + + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE); + rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, + B_AX_REG_ZCDC_H_MASK, 0x3); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); + } else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) { + val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL); + val32 &= ~B_AX_AFSM_PCIE_SUS_EN; + val32 |= B_AX_AFSM_WLSUS_EN; + rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32); + } + + return 0; +} + +static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8852c_efuse *map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; + u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b}; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + tssi->thermal[RF_PATH_B] = map->path_b_therm; + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, + sizeof(ofst[i]->cck_tssi)); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + sizeof(ofst[i]->bw40_tssi)); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); + memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i], + sizeof(tssi->tssi_6g_mcs[i])); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + } +} + +static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) +{ + if (high) + *high = FIELD_GET_SIGNED(GENMASK(7, 4), data); + if (low) + *low = FIELD_GET_SIGNED(GENMASK(3, 0), data); + + return data != 0xff; +} + +static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8852c_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + bool valid = false; + + valid |= _decode_efuse_gain(map->rx_gain_2g_cck, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]); + valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]); + valid |= _decode_efuse_gain(map->rx_gain_5g_low, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]); + valid |= _decode_efuse_gain(map->rx_gain_5g_mid, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]); + valid |= _decode_efuse_gain(map->rx_gain_5g_high, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]); + valid |= _decode_efuse_gain(map->rx_gain_6g_l0, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0]); + valid |= _decode_efuse_gain(map->rx_gain_6g_l1, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1]); + valid |= _decode_efuse_gain(map->rx_gain_6g_m0, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0]); + valid |= _decode_efuse_gain(map->rx_gain_6g_m1, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1]); + valid |= _decode_efuse_gain(map->rx_gain_6g_h0, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0]); + valid |= _decode_efuse_gain(map->rx_gain_6g_h1, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1]); + valid |= _decode_efuse_gain(map->rx_gain_6g_uh0, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0]); + valid |= _decode_efuse_gain(map->rx_gain_6g_uh1, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1]); + + gain->offset_valid = valid; +} + +static void rtw8852c_efuse_copy_sn_uuid_usb(struct rtw89_dev *rtwdev, + const struct rtw8852c_efuse *map) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + memcpy(efuse->sn, map->u.sn, sizeof(efuse->sn)); + memcpy(efuse->uuid, map->u.uuid, sizeof(efuse->uuid)); +} + +static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw8852c_efuse *map; + + map = (struct rtw8852c_efuse *)log_map; + + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + rtw8852c_efuse_parsing_tssi(rtwdev, map); + rtw8852c_efuse_parsing_gain_offset(rtwdev, map); + + switch (rtwdev->hci.type) { + case RTW89_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; + case RTW89_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + rtw8852c_efuse_copy_sn_uuid_usb(rtwdev, map); + break; + default: + return -ENOTSUPP; + } + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + + return 0; +} + +static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB}; + static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3}; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = false; + u32 ofst; + u8 i, j; + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { + /* addrs are in decreasing order */ + ofst = tssi_trim_addr[i] - addr - j; + tssi->tssi_trim[i][j] = phycap_map[ofst]; + + if (phycap_map[ofst] != 0xff) + pg = true; + } + + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) { + /* addrs are in decreasing order */ + ofst = tssi_trim_addr_6g[i] - addr - j; + tssi->tssi_trim_6g[i][j] = phycap_map[ofst]; + + if (phycap_map[ofst] != 0xff) + pg = true; + } + } + + if (!pg) { + memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); + memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g)); + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM] no PG, set all trim info to 0\n"); + } + + for (i = 0; i < RF_PATH_NUM_8852C; i++) + for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", + i, j, tssi->tssi_trim[i][j], + tssi_trim_addr[i] - j); +} + +static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", + i, info->thermal_trim[i]); + + if (info->thermal_trim[i] != 0xff) + info->pg_thermal_trim = true; + } +} + +#define __THM_MASK_SIGN BIT(0) +#define __THM_MASK_3BITS GENMASK(3, 1) +#define __THM_MASK_VAL8 BIT(4) + +static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev) +{ +#define __thm_setting(raw) \ +({ \ + u8 __v = (raw); \ + ((__v & __THM_MASK_SIGN) << 3) | ((__v & __THM_MASK_3BITS) >> 1); \ +}) + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 i, val; + + if (!info->pg_thermal_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + val = __thm_setting(info->thermal_trim[i]); + rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", + i, val); + } +#undef __thm_setting +} + +static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB}; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + + if (info->pa_bias_trim[i] != 0xff) + info->pg_pa_bias_trim = true; + } +} + +static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); + pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); + } +} + +static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map); + rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + + return 0; +} + +static void rtw8852c_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8852c_thermal_trim(rtwdev); + rtw8852c_pa_bias_trim(rtwdev); +} + +static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx); + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx); + u8 txsc20 = 0, txsc40 = 0, txsc80 = 0; + u8 rf_mod_val = 0, chk_rate_mask = 0; + u32 txsc; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + txsc80 = rtw89_phy_get_txsc(rtwdev, chan, + RTW89_CHANNEL_WIDTH_80); + fallthrough; + case RTW89_CHANNEL_WIDTH_80: + txsc40 = rtw89_phy_get_txsc(rtwdev, chan, + RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsc20 = rtw89_phy_get_txsc(rtwdev, chan, + RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + rf_mod_val = AX_WMAC_RFMOD_160M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) | + FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) | + FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_mod_val = AX_WMAC_RFMOD_80M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) | + FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_mod_val = AX_WMAC_RFMOD_40M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20); + break; + case RTW89_CHANNEL_WIDTH_20: + default: + rf_mod_val = AX_WMAC_RFMOD_20M; + txsc = 0; + break; + } + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val); + rtw89_write32(rtwdev, sub_carr, txsc); + + switch (chan->band_type) { + case RTW89_BAND_2G: + chk_rate_mask = B_AX_BAND_MODE; + break; + case RTW89_BAND_5G: + case RTW89_BAND_6G: + chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6; + break; + default: + rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type); + return; + } + rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN | + B_AX_RTS_LIMIT_IN_OFDM6); + rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask); +} + +static const u32 rtw8852c_sco_barker_threshold[14] = { + 0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6, + 0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a +}; + +static const u32 rtw8852c_sco_cck_threshold[14] = { + 0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db, + 0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e +}; + +static int rtw8852c_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch, + u8 primary_ch, enum rtw89_bandwidth bw) +{ + u8 ch_element; + + if (bw == RTW89_CHANNEL_WIDTH_20) { + ch_element = central_ch - 1; + } else if (bw == RTW89_CHANNEL_WIDTH_40) { + if (primary_ch == 1) + ch_element = central_ch - 1 + 2; + else + ch_element = central_ch - 1 - 2; + } else { + rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw); + return -EINVAL; + } + rtw89_phy_write32_mask(rtwdev, R_BK_FC0_INV_V1, B_BK_FC0_INV_MSK_V1, + rtw8852c_sco_barker_threshold[ch_element]); + rtw89_phy_write32_mask(rtwdev, R_CCK_FC0_INV_V1, B_CCK_FC0_INV_MSK_V1, + rtw8852c_sco_cck_threshold[ch_element]); + + return 0; +} + +struct rtw8852c_bb_gain { + u32 gain_g[BB_PATH_NUM_8852C]; + u32 gain_a[BB_PATH_NUM_8852C]; + u32 gain_mask; +}; + +static const struct rtw8852c_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x000000ff }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x0000ff00 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x000000ff }, +}; + +static const struct rtw8852c_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0xff000000 }, +}; + +struct rtw8852c_bb_gain_bypass { + u32 gain_g[BB_PATH_NUM_8852C]; + u32 gain_a[BB_PATH_NUM_8852C]; + u32 gain_mask_g; + u32 gain_mask_a; +}; + +static +const struct rtw8852c_bb_gain_bypass bb_gain_bypass_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4BB8, 0x4C7C}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff000000, .gain_mask_a = 0xff}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff, .gain_mask_a = 0xff00}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff0000, .gain_mask_a = 0xff000000}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff000000, .gain_mask_a = 0xff}, + { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff, .gain_mask_a = 0xff00}, + { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000}, +}; + +struct rtw8852c_bb_gain_op1db { + struct { + u32 lna[BB_PATH_NUM_8852C]; + u32 tia_lna[BB_PATH_NUM_8852C]; + u32 mask; + } reg[LNA_GAIN_NUM]; + u32 reg_tia0_lna6[BB_PATH_NUM_8852C]; + u32 mask_tia0_lna6; +}; + +static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = { + .reg = { + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff00}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff0000}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff000000}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff00}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff0000}, + }, + .reg_tia0_lna6 = {0x4674, 0x4758}, + .mask_tia0_lna6 = 0xff000000, +}; + +static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_rf_path path) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax; + u8 gain_band = rtw89_subband_to_bb_gain_band(subband); + s32 val; + u32 reg; + u32 mask; + int i; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_lna[i].gain_g[path]; + else + reg = bb_gain_lna[i].gain_a[path]; + + mask = bb_gain_lna[i].gain_mask; + val = gain->lna_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + if (subband == RTW89_CH_2G) { + reg = bb_gain_bypass_lna[i].gain_g[path]; + mask = bb_gain_bypass_lna[i].gain_mask_g; + } else { + reg = bb_gain_bypass_lna[i].gain_a[path]; + mask = bb_gain_bypass_lna[i].gain_mask_a; + } + + val = gain->lna_gain_bypass[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + if (subband != RTW89_CH_2G) { + reg = bb_gain_op1db_a.reg[i].lna[path]; + mask = bb_gain_op1db_a.reg[i].mask; + val = gain->lna_op1db[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + reg = bb_gain_op1db_a.reg[i].tia_lna[path]; + mask = bb_gain_op1db_a.reg[i].mask; + val = gain->tia_lna_op1db[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + } + + if (subband != RTW89_CH_2G) { + reg = bb_gain_op1db_a.reg_tia0_lna6[path]; + mask = bb_gain_op1db_a.mask_tia0_lna6; + val = gain->tia_lna_op1db[gain_band][path][7]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_tia[i].gain_g[path]; + else + reg = bb_gain_tia[i].gain_a[path]; + + mask = bb_gain_tia[i].gain_mask; + val = gain->tia_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } +} + +static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx, + enum rtw89_rf_path path) +{ + static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA0_LNA6_OP1DB_V1, + R_PATH1_G_TIA0_LNA6_OP1DB_V1}; + static const u32 rpl_mask[2] = {B_RPL_PATHA_MASK, B_RPL_PATHB_MASK}; + static const u32 rpl_tb_mask[2] = {B_RSSI_M_PATHA_MASK, B_RSSI_M_PATHB_MASK}; + struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset gain_band; + s32 offset_q0, offset_base_q4; + s32 tmp = 0; + + if (!efuse_gain->offset_valid) + return; + + if (rtwdev->dbcc_en && path == RF_PATH_B) + phy_idx = RTW89_PHY_1; + + if (chan->band_type == RTW89_BAND_2G) { + offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK]; + offset_base_q4 = efuse_gain->offset_base[phy_idx]; + + tmp = clamp_t(s32, (-offset_q0 << 3) + (offset_base_q4 >> 1), + S8_MIN >> 1, S8_MAX >> 1); + rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f); + } + + gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type); + + offset_q0 = -efuse_gain->offset[path][gain_band]; + offset_base_q4 = efuse_gain->offset_base[phy_idx]; + + tmp = (offset_q0 << 2) + (offset_base_q4 >> 2); + tmp = clamp_t(s32, -tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], B_PATH0_R_G_OFST_MASK, tmp & 0xff); + + tmp = clamp_t(s32, offset_q0 << 4, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_RPL_PATHAB, rpl_mask[path], tmp & 0xff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, rpl_tb_mask[path], tmp & 0xff, phy_idx); +} + +static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 sco; + u16 central_freq = chan->freq; + u8 central_ch = chan->channel; + u8 band = chan->band_type; + u8 subband = chan->subband_type; + bool is_2g = band == RTW89_BAND_2G; + u8 chan_idx; + + if (!central_freq) { + rtw89_warn(rtwdev, "Invalid central_freq\n"); + return; + } + + if (phy_idx == RTW89_PHY_0) { + /* Path A */ + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_A); + rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_A); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 0, + phy_idx); + /* Path B */ + if (!rtwdev->dbcc_en) { + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B); + rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, + R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, + R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 0, phy_idx); + rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + } else { + if (is_2g) + rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + else + rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + } + /* SCO compensate FC setting */ + rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1, + central_freq, phy_idx); + /* round_up((1/fc0)*pow(2,18)) */ + sco = DIV_ROUND_CLOSEST(1 << 18, central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco, + phy_idx); + } else { + /* Path B */ + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B); + rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 0, phy_idx); + /* SCO compensate FC setting */ + rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1, + central_freq, phy_idx); + /* round_up((1/fc0)*pow(2,18)) */ + sco = DIV_ROUND_CLOSEST(1 << 18, central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco, + phy_idx); + } + /* CCK parameters */ + if (band == RTW89_BAND_2G) { + if (central_ch == 14) { + rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1, + B_PCOEFF01_MSK_V1, 0x3b13ff); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1, + B_PCOEFF23_MSK_V1, 0x1c42de); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1, + B_PCOEFF45_MSK_V1, 0xfdb0ad); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1, + B_PCOEFF67_MSK_V1, 0xf60f6e); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1, + B_PCOEFF89_MSK_V1, 0xfd8f92); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1, + B_PCOEFFAB_MSK_V1, 0x2d011); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1, + B_PCOEFFCD_MSK_V1, 0x1c02c); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1, + B_PCOEFFEF_MSK_V1, 0xfff00a); + } else { + rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1, + B_PCOEFF01_MSK_V1, 0x3d23ff); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1, + B_PCOEFF23_MSK_V1, 0x29b354); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1, + B_PCOEFF45_MSK_V1, 0xfc1c8); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1, + B_PCOEFF67_MSK_V1, 0xfdb053); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1, + B_PCOEFF89_MSK_V1, 0xf86f9a); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1, + B_PCOEFFAB_MSK_V1, 0xfaef92); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1, + B_PCOEFFCD_MSK_V1, 0xfe5fcc); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1, + B_PCOEFFEF_MSK_V1, 0xffdff5); + } + } + + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); + rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx); +} + +static void rtw8852c_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + static const u32 adc_sel[2] = {0xC0EC, 0xC1EC}; + static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4}; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); + break; + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + case RTW89_CHANNEL_WIDTH_80: + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + } +} + +static void rtw8852c_edcca_per20_bitmap_sifs(struct rtw89_dev *rtwdev, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + if (bw == RTW89_CHANNEL_WIDTH_20) { + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0xff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx); + } +} + +static void +rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + u8 mod_sbw = 0; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + if (bw == RTW89_CHANNEL_WIDTH_5) + mod_sbw = 0x1; + else if (bw == RTW89_CHANNEL_WIDTH_10) + mod_sbw = 0x2; + else if (bw == RTW89_CHANNEL_WIDTH_20) + mod_sbw = 0x0; + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, + mod_sbw, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, 0x0, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xd); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xd); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x3, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xb); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xb); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, + pri_ch); + } + + if (bw == RTW89_CHANNEL_WIDTH_40) { + rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1, + B_RX_BW40_2XFFT_EN_MSK_V1, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 1, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1, + B_RX_BW40_2XFFT_EN_MSK_V1, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 0, phy_idx); + } + + if (phy_idx == RTW89_PHY_0) { + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_A); + if (!rtwdev->dbcc_en) + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B); + } else { + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B); + } + + rtw8852c_edcca_per20_bitmap_sifs(rtwdev, bw, phy_idx); +} + +static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u8 center_chan = chan->channel; + u8 bw = chan->band_width; + + switch (chan->band_type) { + case RTW89_BAND_2G: + if (bw == RTW89_CHANNEL_WIDTH_20) { + if (center_chan >= 5 && center_chan <= 8) + return 2440; + if (center_chan == 13) + return 2480; + } else if (bw == RTW89_CHANNEL_WIDTH_40) { + if (center_chan >= 3 && center_chan <= 10) + return 2440; + } + break; + case RTW89_BAND_5G: + if (center_chan == 151 || center_chan == 153 || + center_chan == 155 || center_chan == 163) + return 5760; + break; + case RTW89_BAND_6G: + if (center_chan == 195 || center_chan == 197 || + center_chan == 199 || center_chan == 207) + return 6920; + break; + default: + break; + } + + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u32 spur_freq; + s32 freq_diff, csi_idx, csi_tone_idx; + + spur_freq = rtw8852c_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 0, phy_idx); + return; + } + + freq_diff = (spur_freq - chan->freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 1, phy_idx); +} + +static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = { + [RF_PATH_A] = { + .notch1_idx = {0x4C14, 0xFF}, + .notch1_frac_idx = {0x4C14, 0xC00}, + .notch1_en = {0x4C14, 0x1000}, + .notch2_idx = {0x4C20, 0xFF}, + .notch2_frac_idx = {0x4C20, 0xC00}, + .notch2_en = {0x4C20, 0x1000}, + }, + [RF_PATH_B] = { + .notch1_idx = {0x4CD8, 0xFF}, + .notch1_frac_idx = {0x4CD8, 0xC00}, + .notch1_en = {0x4CD8, 0x1000}, + .notch2_idx = {0x4CE4, 0xFF}, + .notch2_frac_idx = {0x4CE4, 0xC00}, + .notch2_en = {0x4CE4, 0x1000}, + }, +}; + +static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path]; + u32 spur_freq, fc; + s32 freq_diff; + s32 nbi_idx, nbi_tone_idx; + s32 nbi_frac_idx, nbi_frac_tone_idx; + bool notch2_chk = false; + + spur_freq = rtw8852c_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + return; + } + + fc = chan->freq; + if (chan->band_width == RTW89_CHANNEL_WIDTH_160) { + fc = (spur_freq > fc) ? fc + 40 : fc - 40; + if ((fc > spur_freq && + chan->channel < chan->primary_channel) || + (fc < spur_freq && + chan->channel > chan->primary_channel)) + notch2_chk = true; + } + + freq_diff = (spur_freq - fc) * 1000000; + nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_20) { + s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); + } else { + u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ? + 128 : 256; + + s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); + } + nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { + rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr, + nbi->notch2_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr, + nbi->notch2_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + } else { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr, + nbi->notch1_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr, + nbi->notch1_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0); + } +} + +static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val, + enum rtw89_phy_idx phy_idx) +{ + u32 notch; + u32 notch2; + + if (phy_idx == RTW89_PHY_0) { + notch = R_PATH0_NOTCH; + notch2 = R_PATH0_NOTCH2; + } else { + notch = R_PATH1_NOTCH; + notch2 = R_PATH1_NOTCH2; + } + + rtw89_phy_write32_mask(rtwdev, notch, + B_PATH0_NOTCH_VAL | B_PATH0_NOTCH_EN, val); + rtw89_phy_write32_set(rtwdev, notch, B_PATH0_NOTCH_EN); + rtw89_phy_write32_mask(rtwdev, notch2, + B_PATH0_NOTCH2_VAL | B_PATH0_NOTCH2_EN, val); + rtw89_phy_write32_set(rtwdev, notch2, B_PATH0_NOTCH2_EN); +} + +static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 pri_ch_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_set_csi_tone_idx(rtwdev, chan, phy_idx); + + if (phy_idx == RTW89_PHY_0) { + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && + (pri_ch_idx == RTW89_SC_20_LOWER || + pri_ch_idx == RTW89_SC_20_UP3X)) { + rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_0); + if (!rtwdev->dbcc_en) + rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1); + } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && + (pri_ch_idx == RTW89_SC_20_UPPER || + pri_ch_idx == RTW89_SC_20_LOW3X)) { + rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_0); + if (!rtwdev->dbcc_en) + rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1); + } else { + rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A); + if (!rtwdev->dbcc_en) + rtw8852c_set_nbi_tone_idx(rtwdev, chan, + RF_PATH_B); + } + } else { + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && + (pri_ch_idx == RTW89_SC_20_LOWER || + pri_ch_idx == RTW89_SC_20_UP3X)) { + rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1); + } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && + (pri_ch_idx == RTW89_SC_20_UPPER || + pri_ch_idx == RTW89_SC_20_LOW3X)) { + rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1); + } else { + rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B); + } + } + + if (pri_ch_idx == RTW89_SC_20_UP3X || pri_ch_idx == RTW89_SC_20_LOW3X) + rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 0, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 1, phy_idx); +} + +static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 pri_ch = chan->pri_ch_idx; + bool mask_5m_low; + bool mask_5m_en; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_40: + mask_5m_en = true; + mask_5m_low = pri_ch == RTW89_SC_20_LOWER; + break; + case RTW89_CHANNEL_WIDTH_80: + mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || + pri_ch == RTW89_SC_20_LOWEST; + mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; + break; + default: + mask_5m_en = false; + mask_5m_low = false; + break; + } + + if (!mask_5m_en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x0); + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, + B_ASSIGN_SBD_OPT_EN, 0x0, phy_idx); + } else { + if (mask_5m_low) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x0); + } + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, 0x1, phy_idx); + } +} + +static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + /*HW SI reset*/ + rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, + 0x7); + rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, + 0x7); + + udelay(1); + + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, + phy_idx); + /*HW SI reset*/ + rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, + 0x0); + rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, + 0x0); + + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); +} + +static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + enum rtw89_phy_idx phy_idx, bool en) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); + if (band == RTW89_BAND_2G) + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, + phy_idx); + } +} + +static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_bb_reset_all(rtwdev, phy_idx); +} + +static +void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 tx_path_en, u8 trsw_tx, + u8 trsw_rx, u8 trsw, u8 trsw_b) +{ + static const u32 path_cr_bases[] = {0x5868, 0x7868}; + u32 mask_ofst = 16; + u32 cr; + u32 val; + + if (path >= ARRAY_SIZE(path_cr_bases)) + return; + + cr = path_cr_bases[path]; + + mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2; + val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b); + + rtw89_phy_write32_mask(rtwdev, cr, (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val); +} + +enum rtw8852c_rfe_src { + PAPE_RFM, + TRSW_RFM, + LNAON_RFM, +}; + +static +void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl, + u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val) +{ + static const u32 path_cr_bases[] = {0x5894, 0x7894}; + static const u32 masks[] = {0, 8, 16}; + u32 mask, mask_ofst; + u32 cr; + u32 val; + + if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases)) + return; + + mask_ofst = masks[src]; + cr = path_cr_bases[path]; + + val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) | + FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) | + FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) | + FIELD_PREP(B_P0_RFM_OUT, rfm_output_val); + mask = 0xff << mask_ofst; + + rtw89_phy_write32_mask(rtwdev, cr, mask, val); +} + +static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev) +{ + static const u32 cr_bases[] = {0x5800, 0x7800}; + u32 addr; + u8 i; + + for (i = 0; i < ARRAY_SIZE(cr_bases); i++) { + addr = cr_bases[i]; + rtw89_phy_write32_set(rtwdev, (addr | 0x68), B_P0_TRSW_A); + rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_X); + rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_SO_A2); + rtw89_phy_write32(rtwdev, (addr | 0x80), 0x77777777); + rtw89_phy_write32(rtwdev, (addr | 0x84), 0x77777777); + } + + rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff); + rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0); + + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0); + + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 1, 1, 0); + + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, PAPE_RFM, 0, 0, 0, 0x0); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, TRSW_RFM, 0, 0, 0, 0x4); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, LNAON_RFM, 0, 0, 0, 0x8); + + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, PAPE_RFM, 0, 0, 0, 0x0); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, TRSW_RFM, 0, 0, 0, 0x4); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, LNAON_RFM, 0, 0, 0, 0x8); +} + +static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + for (addr = R_AX_PWR_MACID_LMT_TABLE0; + addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); +} + +static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT, + B_DBCC_80P80_SEL_EVM_RPT_EN); + rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2, + B_DBCC_80P80_SEL_EVM_RPT2_EN); + + rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); + rtw8852c_bb_gpio_init(rtwdev); + + /* read these registers after loading BB parameters */ + gain->offset_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK); + gain->offset_base[RTW89_PHY_1] = + rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK); +} + +static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + static const u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0, + B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1}; + struct rtw89_hal *hal = &rtwdev->hal; + bool cck_en = chan->band_type == RTW89_BAND_2G; + u8 pri_ch_idx = chan->pri_ch_idx; + u32 mask, reg; + u8 ntx_path; + + if (chan->band_type == RTW89_BAND_2G) + rtw8852c_ctrl_sco_cck(rtwdev, chan->channel, + chan->primary_channel, + chan->band_width); + + rtw8852c_ctrl_ch(rtwdev, chan, phy_idx); + rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); + if (cck_en) { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 0x0, phy_idx); + } else { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 1); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 0x1, phy_idx); + } + + rtw8852c_spur_elimination(rtwdev, chan, pri_ch_idx, phy_idx); + rtw8852c_ctrl_btg_bt_rx(rtwdev, chan->band_type == RTW89_BAND_2G, + RTW89_PHY_0); + rtw8852c_5m_mask(rtwdev, chan, phy_idx); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && + rtwdev->hal.cv != CHIP_CAV) { + rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ, + B_P80_AT_HIGH_FREQ, 0x0, phy_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, R_P80_AT_HIGH_FREQ_BB_WRP, phy_idx); + if (chan->primary_channel > chan->channel) { + rtw89_phy_write32_mask(rtwdev, + R_P80_AT_HIGH_FREQ_RU_ALLOC, + ru_alloc_msk[phy_idx], 1); + rtw89_write32_mask(rtwdev, reg, + B_P80_AT_HIGH_FREQ_BB_WRP, 1); + } else { + rtw89_phy_write32_mask(rtwdev, + R_P80_AT_HIGH_FREQ_RU_ALLOC, + ru_alloc_msk[phy_idx], 0); + rtw89_write32_mask(rtwdev, reg, + B_P80_AT_HIGH_FREQ_BB_WRP, 0); + } + } + + if (chan->band_type == RTW89_BAND_6G && + chan->band_width == RTW89_CHANNEL_WIDTH_160) + rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN, + B_CDD_EVM_CHK_EN, 0, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN, + B_CDD_EVM_CHK_EN, 1, phy_idx); + + if (!rtwdev->dbcc_en) { + mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3); + mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3); + } else { + if (phy_idx == RTW89_PHY_0) { + mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3); + } else { + mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3); + } + } + + if (chan->band_type == RTW89_BAND_6G) + rtw89_phy_write32_set(rtwdev, R_MUIC, B_MUIC_EN); + else + rtw89_phy_write32_clr(rtwdev, R_MUIC, B_MUIC_EN); + + if (hal->antenna_tx) + ntx_path = hal->antenna_tx; + else + ntx_path = chan->band_type == RTW89_BAND_6G ? RF_B : RF_AB; + + rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, (enum rtw89_mac_idx)phy_idx); + + rtw8852c_bb_reset_all(rtwdev, phy_idx); +} + +static void rtw8852c_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_set_channel_mac(rtwdev, chan, mac_idx); + rtw8852c_set_channel_bb(rtwdev, chan, phy_idx); + rtw8852c_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0); +} + +static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0xf); +} + +static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, mac_idx, &p->tx_en, + RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false); + rtw8852c_dfs_en(rtwdev, false); + rtw8852c_tssi_cont_en_phyidx(rtwdev, false, phy_idx, chan); + rtw8852c_adc_en(rtwdev, false); + fsleep(40); + rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true); + rtw8852c_adc_en(rtwdev, true); + rtw8852c_dfs_en(rtwdev, true); + rtw8852c_tssi_cont_en_phyidx(rtwdev, true, phy_idx, chan); + rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, mac_idx, p->tx_en); + } +} + +static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + memset(rfk_mcc, 0, sizeof(*rfk_mcc)); + rtw8852c_lck_init(rtwdev); + rtw8852c_dpk_init(rtwdev); + + rtw8852c_rck(rtwdev); + rtw8852c_dack(rtwdev, RTW89_CHANCTX_0); + rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false); +} + +static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + + rtw8852c_mcc_get_ch_info(rtwdev, phy_idx); + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + + rtw8852c_rx_dck(rtwdev, phy_idx, false); + rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); + rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); + rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); +} + +static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8852c_tssi_scan(rtwdev, phy_idx, chan); +} + +static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx); +} + +static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8852c_dpk_track(rtwdev); + rtw8852c_lck_track(rtwdev); + rtw8852c_rx_dck_track(rtwdev); +} + +static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + s16 ref, u16 pwr_ofst_decrease) +{ + u8 base_cw_0db = 0x27; + u16 tssi_16dbm_cw = 0x12c; + s16 pwr_s10_3 = 0; + s16 rf_pwr_cw = 0; + u16 bb_pwr_cw = 0; + u32 pwr_cw = 0; + u32 tssi_ofst_cw = 0; + + pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease; + bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); + rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); + rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); + pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; + + tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) - + pwr_ofst_decrease; + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", + tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); + + return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0)); +} + +static +void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + s8 pw_ofst, enum rtw89_mac_idx mac_idx) +{ + s8 pw_ofst_2tx; + s8 val_1t; + s8 val_2t; + u32 reg; + u8 i; + + if (pw_ofst < -32 || pw_ofst > 31) { + rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst); + return; + } + val_1t = pw_ofst << 2; + pw_ofst_2tx = max(pw_ofst - 3, -32); + val_2t = pw_ofst_2tx << 2; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t); + + for (i = 0; i < 4; i++) { + /* 1TX */ + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx); + rtw89_write32_mask(rtwdev, reg, + B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i), + val_1t); + /* 2TX */ + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx); + rtw89_write32_mask(rtwdev, reg, + B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i), + val_2t); + } +} + +static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 pwr_ofst) +{ + static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800}; + u16 ofst_dec[RF_PATH_NUM_8852C]; + const u32 mask = 0x7FFFFFF; + const u8 ofst_ofdm = 0x4; + const u8 ofst_cck = 0x8; + s16 ref_ofdm = 0; + s16 ref_cck = 0; + u32 val; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, + GENMASK(27, 10), 0x0); + + ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst); + ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]); + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx); + } + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]); + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx); + } +} + +static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) +{ +#define __DFIR_CFG_MASK 0xffffff +#define __DFIR_CFG_NR 8 +#define __DECL_DFIR_VAR(_prefix, _name, _val...) \ + static const u32 _prefix ## _ ## _name[] = {_val}; \ + static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR) +#define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val) +#define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val) + + __DECL_DFIR_PARAM(flat, + 0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, + 0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5); + __DECL_DFIR_PARAM(sharp, + 0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090, + 0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5); + __DECL_DFIR_PARAM(sharp_14, + 0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, + 0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A); + __DECL_DFIR_ADDR(filter, + 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0, + 0x45C4, 0x45C8); + u8 ch = chan->channel; + const u32 *param; + int i; + + if (ch > 14) { + rtw89_warn(rtwdev, + "set tx shape dfir by unknown ch: %d on 2G\n", ch); + return; + } + + if (ch == 14) + param = param_sharp_14; + else + param = tx_shape_idx == 0 ? param_flat : param_sharp; + + for (i = 0; i < __DFIR_CFG_NR; i++) { + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i], + param[i]); + rtw89_phy_write32_idx(rtwdev, addr_filter[i], __DFIR_CFG_MASK, + param[i], phy_idx); + } + +#undef __DECL_DFIR_ADDR +#undef __DECL_DFIR_PARAM +#undef __DECL_DFIR_VAR +#undef __DFIR_CFG_NR +#undef __DFIR_CFG_MASK +} + +static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 band = chan->band_type; + u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK); + u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM); + + if (band == RTW89_BAND_2G) + rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); + + rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, + (enum rtw89_mac_idx)phy_idx, + tx_shape_ofdm); + + rtw89_phy_write32_set(rtwdev, R_P0_DAC_COMP_POST_DPD_EN, + B_P0_DAC_COMP_POST_DPD_EN); + rtw89_phy_write32_set(rtwdev, R_P1_DAC_COMP_POST_DPD_EN, + B_P1_DAC_COMP_POST_DPD_EN); +} + +static void rtw8852c_set_txpwr_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 pwr_ofst; + + pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan); + rtw8852c_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst); +} + +static void rtw8852c_set_txpwr_sar_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_sar_parm sar_parm = { + .center_freq = chan->freq, + .force_path = true, + }; + s16 sar_rf; + s8 sar_mac; + + if (phy_idx != RTW89_PHY_0) + return; + + sar_parm.path = RF_PATH_A; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB, B_TXPWRB_MAX, sar_rf); + + sar_parm.path = RF_PATH_B; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB, B_TXPWRB_MAX, sar_rf); +} + +static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw8852c_set_tx_shape(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); + rtw8852c_set_txpwr_diff(rtwdev, chan, phy_idx); + rtw8852c_set_txpwr_sar_diff(rtwdev, chan, phy_idx); +} + +static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_set_txpwr_ref(rtwdev, phy_idx, 0); +} + +static void +rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + static const struct rtw89_reg2_def ctrl_ini[] = { + {0xD938, 0x00010100}, + {0xD93C, 0x0500D500}, + {0xD940, 0x00000500}, + {0xD944, 0x00000005}, + {0xD94C, 0x00220000}, + {0xD950, 0x00030000}, + }; + u32 addr; + int i; + + for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); + + for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, ctrl_ini[i].addr, + ctrl_ini[i].data); + + rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, + (enum rtw89_mac_idx)phy_idx, + RTW89_TSSI_BANDEDGE_FLAT); +} + +static int +rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + int ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); + if (ret) + return ret; + + rtw8852c_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? + RTW89_MAC_1 : + RTW89_MAC_0); + rtw8852c_init_tssi_ctrl(rtwdev, phy_idx); + + return 0; +} + +static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + u8 band = chan->band_type; + u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; + u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; + + if (rtwdev->dbcc_en) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2, + RTW89_PHY_1); + + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, + 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, + 1); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2, + RTW89_PHY_1); + + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + + rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0, + RTW89_PHY_1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); + } else { + if (rx_path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 3); + } else if (rx_path == RF_PATH_B) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 2); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 3); + } else { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 3); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 1); + rtw8852c_ctrl_btg_bt_rx(rtwdev, band == RTW89_BAND_2G, + RTW89_PHY_0); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 3); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 3); + } + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8); + } +} + +static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path, + enum rtw89_mac_idx mac_idx) +{ + struct rtw89_reg2_def path_com[] = { + {R_AX_PATH_COM0, AX_PATH_COM0_DFVAL}, + {R_AX_PATH_COM1, AX_PATH_COM1_DFVAL}, + {R_AX_PATH_COM2, AX_PATH_COM2_DFVAL}, + {R_AX_PATH_COM3, AX_PATH_COM3_DFVAL}, + {R_AX_PATH_COM4, AX_PATH_COM4_DFVAL}, + {R_AX_PATH_COM5, AX_PATH_COM5_DFVAL}, + {R_AX_PATH_COM6, AX_PATH_COM6_DFVAL}, + {R_AX_PATH_COM7, AX_PATH_COM7_DFVAL}, + {R_AX_PATH_COM8, AX_PATH_COM8_DFVAL}, + {R_AX_PATH_COM9, AX_PATH_COM9_DFVAL}, + {R_AX_PATH_COM10, AX_PATH_COM10_DFVAL}, + {R_AX_PATH_COM11, AX_PATH_COM11_DFVAL}, + }; + u32 addr; + u32 reg; + u8 cr_size = ARRAY_SIZE(path_com); + u8 i = 0; + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1); + + for (addr = R_AX_MACID_ANT_TABLE; + addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) { + reg = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); + rtw89_write32(rtwdev, reg, 0); + } + + if (tx_path == RF_A) { + path_com[0].data = AX_PATH_COM0_PATHA; + path_com[1].data = AX_PATH_COM1_PATHA; + path_com[2].data = AX_PATH_COM2_PATHA; + path_com[7].data = AX_PATH_COM7_PATHA; + path_com[8].data = AX_PATH_COM8_PATHA; + } else if (tx_path == RF_B) { + path_com[0].data = AX_PATH_COM0_PATHB; + path_com[1].data = AX_PATH_COM1_PATHB; + path_com[2].data = AX_PATH_COM2_PATHB; + path_com[7].data = AX_PATH_COM7_PATHB; + path_com[8].data = AX_PATH_COM8_PATHB; + } else if (tx_path == RF_AB) { + path_com[0].data = AX_PATH_COM0_PATHAB; + path_com[1].data = AX_PATH_COM1_PATHAB; + path_com[2].data = AX_PATH_COM2_PATHAB; + path_com[7].data = AX_PATH_COM7_PATHAB; + path_com[8].data = AX_PATH_COM8_PATHAB; + } else { + rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path); + return; + } + + for (i = 0; i < cr_size; i++) { + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n", + path_com[i].addr, path_com[i].data); + reg = rtw89_mac_reg_by_idx(rtwdev, path_com[i].addr, mac_idx); + rtw89_write32(rtwdev, reg, path_com[i].data); + } +} + +static void rtw8852c_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1, + B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1, + B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1, + B_PATH0_RXBB_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1, + B_PATH1_RXBB_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1, + B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1, + B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x80); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1, + B_PATH0_BT_BACKOFF_V1, 0x780D1E); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1, + B_PATH1_BT_BACKOFF_V1, 0x780D1E); + rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1, + B_P0_BACKOFF_IBADC_V1, 0x34); + rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1, + B_P1_BACKOFF_IBADC_V1, 0x34); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1, + B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1, + B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1, + B_PATH0_RXBB_MSK_V1, 0x60); + rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1, + B_PATH1_RXBB_MSK_V1, 0x60); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, + B_PATH0_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, + B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1, + B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1, + B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1, + B_PATH0_BT_BACKOFF_V1, 0x79E99E); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1, + B_PATH1_BT_BACKOFF_V1, 0x79E99E); + rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1, + B_P0_BACKOFF_IBADC_V1, 0x26); + rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1, + B_P1_BACKOFF_IBADC_V1, 0x26); + } +} + +static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u8 nrx_path = RF_PATH_AB; + u8 rx_nss = hal->rx_nss; + + if (hal->antenna_rx == RF_A) + nrx_path = RF_PATH_A; + else if (hal->antenna_rx == RF_B) + nrx_path = RF_PATH_B; + + if (nrx_path != RF_PATH_AB) + rx_nss = 1; + + rtw8852c_bb_cfg_rx_path(rtwdev, nrx_path); + + if (rx_nss == 1) { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); + } +} + +static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + s8 comp = 0; + u8 val; + + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + val = rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); + + if (info->pg_thermal_trim) { + u8 trim = info->thermal_trim[rf_path]; + + if (trim & __THM_MASK_VAL8) + comp = 8 * (trim & __THM_MASK_SIGN ? -1 : 1); + } + + return val + comp; +} + +static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc_module *md = &rtwdev->btc.mdinfo; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->bt_solo = 0; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + + if (md->rfe_type > 0) + md->ant.num = (md->rfe_type % 2 ? 2 : 3); + else + md->ant.num = 2; + + md->ant.diversity = 0; + md->ant.isolation = 10; + + if (md->ant.num == 3) { + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + } else { + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + } + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x20); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN, + B_BT_DYN_DC_EST_EN_MSK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x0); + } +} + +static +void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_mac_ax_coex coex_params = { + .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, + .direction = RTW89_MAC_AX_COEX_INNER, + }; + + /* PTA init */ + rtw89_mac_coex_init_v1(rtwdev, &coex_params); + + /* set WL Tx response = Hi-Pri */ + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); + + /* set rf gnt debug off */ + rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0); + + /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ + if (btc->ant_type == BTC_ANT_SHARED) { + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); + /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */ + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); + } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); + } + + /* set PTA break table */ + rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM); + + /* enable BT counter 0xda10[1:0] = 2b'11 */ + rtw89_write32_set(rtwdev, + R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN | + B_AX_BT_CNT_RST_V1); +} + +static +void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + u32 bitmap = 0; + u32 reg = 0; + + switch (map) { + case BTC_PRI_MASK_TX_RESP: + reg = R_BTC_COEX_WL_REQ; + bitmap = B_BTC_RSP_ACK_HI; + break; + case BTC_PRI_MASK_BEACON: + reg = R_BTC_COEX_WL_REQ; + bitmap = B_BTC_TX_BCN_HI; + break; + default: + return; + } + + if (state) + rtw89_write32_set(rtwdev, reg, bitmap); + else + rtw89_write32_clr(rtwdev, reg, bitmap); +} + +union rtw8852c_btc_wl_txpwr_ctrl { + u32 txpwr_val; + struct { + union { + u16 ctrl_all_time; + struct { + s16 data:9; + u16 rsvd:6; + u16 flag:1; + } all_time; + }; + union { + u16 ctrl_gnt_bt; + struct { + s16 data:9; + u16 rsvd:7; + } gnt_bt; + }; + }; +} __packed; + +static void +rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; + s32 val; + +#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ +do { \ + u32 _wrt = FIELD_PREP(_msk, _val); \ + BUILD_BUG_ON((_msk & _en) != 0); \ + if (_cond) \ + _wrt |= _en; \ + else \ + _wrt &= ~_en; \ + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ + _msk | _en, _wrt); \ +} while (0) + + switch (arg.ctrl_all_time) { + case 0xffff: + val = 0; + break; + default: + val = arg.all_time.data; + break; + } + + __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, + val, B_AX_FORCE_PWR_BY_RATE_EN, + arg.ctrl_all_time != 0xffff); + + switch (arg.ctrl_gnt_bt) { + case 0xffff: + val = 0; + break; + default: + val = arg.gnt_bt.data; + break; + } + + __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, + B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); + +#undef __write_ctrl +} + +static +s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + /* +6 for compensate offset */ + return clamp_t(s8, val + 6, -100, 0) + 100; +} + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852c_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852c_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const u8 rtw89_btc_8852c_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; +static const u8 rtw89_btc_8852c_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda00), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda04), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda38), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda44), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda48), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c), +}; + +static +void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + /* Feature move to firmware */ +} + +static +void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x620); + + /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ + if (state) + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0x179c); + else + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0x208); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void rtw8852c_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) +{ + /* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB + * level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB + * To improve BT ACI in co-rx + */ + + switch (level) { + case 0: /* default */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + case 1: /* Fix LNA2=5 */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + } +} + +static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + struct rtw89_btc *btc = &rtwdev->btc; + + switch (level) { + case 0: /* original */ + default: + rtw8852c_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 1: /* for FDD free-run */ + rtw8852c_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0); + btc->dm.wl_lna2 = 0; + break; + case 2: /* for BTG Co-Rx*/ + rtw8852c_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0); + btc->dm.wl_lna2 = 1; + break; + } + + rtw8852c_set_wl_lna2(rtwdev, btc->dm.wl_lna2); +} + +static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 chan_idx = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan_idx == 0) + return; + + rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + u8 *rx_power = phy_ppdu->rssi; + + if (!status->signal) + status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], + rx_power[RF_PATH_B])); + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + + rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK); + if (ret) + return ret; + + return 0; +} + +static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + + return 0; +} + +static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = { + .callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb, + .callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_NET_DETECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, + .max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID, +}; +#endif + +static const struct rtw89_chip_ops rtw8852c_chip_ops = { + .enable_bb_rf = rtw8852c_mac_enable_bb_rf, + .disable_bb_rf = rtw8852c_mac_disable_bb_rf, + .bb_preinit = NULL, + .bb_postinit = NULL, + .bb_reset = rtw8852c_bb_reset, + .bb_sethw = rtw8852c_bb_sethw, + .read_rf = rtw89_phy_read_rf_v1, + .write_rf = rtw89_phy_write_rf_v1, + .set_channel = rtw8852c_set_channel, + .set_channel_help = rtw8852c_set_channel_help, + .read_efuse = rtw8852c_read_efuse, + .read_phycap = rtw8852c_read_phycap, + .fem_setup = NULL, + .data_setup = NULL, + .rfe_gpio = NULL, + .rfk_hw_init = NULL, + .rfk_init = rtw8852c_rfk_init, + .rfk_init_late = NULL, + .rfk_channel = rtw8852c_rfk_channel, + .rfk_band_changed = rtw8852c_rfk_band_changed, + .rfk_scan = rtw8852c_rfk_scan, + .rfk_track = rtw8852c_rfk_track, + .power_trim = rtw8852c_power_trim, + .set_txpwr = rtw8852c_set_txpwr, + .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852c_init_txpwr_unit, + .get_thermal = rtw8852c_get_thermal, + .chan_to_rf18_val = NULL, + .ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx, + .query_ppdu = rtw8852c_query_ppdu, + .convert_rpl_to_rssi = NULL, + .phy_rpt_to_rssi = NULL, + .ctrl_nbtg_bt_tx = rtw8852c_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8852c_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, + .digital_pwr_comp = NULL, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = rtw8852c_pwr_on_func, + .pwr_off_func = rtw8852c_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc, + .fill_txdesc = rtw89_core_fill_txdesc_v1, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1, + .get_ch_dma = {rtw89_core_get_ch_dma, + rtw89_core_get_ch_dma_v2, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1, + .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, + .stop_sch_tx = rtw89_mac_stop_sch_tx_v1, + .resume_sch_tx = rtw89_mac_resume_sch_tx_v1, + .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v1, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl, + .h2c_ampdu_cmac_tbl = NULL, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl, + .h2c_punctured_cmac_tbl = NULL, + .h2c_default_dmac_tbl = NULL, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8852c_btc_set_rfe, + .btc_init_cfg = rtw8852c_btc_init_cfg, + .btc_set_wl_pri = rtw8852c_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8852c_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +const struct rtw89_chip_info rtw8852c_chip_info = { + .chip_id = RTL8852C, + .chip_gen = RTW89_CHIP_AX, + .ops = &rtw8852c_chip_ops, + .mac_def = &rtw89_mac_gen_ax, + .phy_def = &rtw89_phy_gen_ax, + .fw_def = { + .fw_basename = RTW8852C_FW_BASENAME, + .fw_format_max = RTW8852C_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = false, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS | + BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION), + .fw_blacklist = &rtw89_fw_blacklist_default, + .fifo_size = 458752, + .small_fifo_size = false, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 8000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = false, + .rsvd_ple_ofst = 0x6f800, + .qta_def = { + .hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, + rtw8852c_hfc_param_ini_usb, + rtw8852c_hfc_param_ini_usb, + NULL}, + .dle_mem = {rtw8852c_dle_mem_pcie, + rtw8852c_dle_mem_usb2, + rtw8852c_dle_mem_usb3, + NULL}, + }, + .wde_qempty_acq_grpnum = 16, + .wde_qempty_mgq_grpsel = 16, + .rf_base_addr = {0xe000, 0xf000}, + .thermal_th = {0x32, 0x35}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = &rtw89_8852c_phy_bb_table, + .bb_gain_table = &rtw89_8852c_phy_bb_gain_table, + .rf_table = {&rtw89_8852c_phy_radiob_table, + &rtw89_8852c_phy_radioa_table,}, + .nctl_table = &rtw89_8852c_phy_nctl_table, + .nctl_post_table = NULL, + .dflt_parms = &rtw89_8852c_dflt_parms, + .rfe_parms_conf = NULL, + .chanctx_listener = &rtw8852c_chanctx_listener, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8852c_dig_regs, + .tssi_dbw_table = &rtw89_8852c_tssi_dbw_table, + .support_macid_num = RTW89_MAX_MAC_ID_NUM, + .support_link_num = 0, + .support_chanctx_num = 2, + .support_rnr = false, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ) | + BIT(NL80211_BAND_6GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160), + .support_unii4 = true, + .support_ant_gain = true, + .support_tas = true, + .support_sar_by_ant = true, + .support_noise = false, + .support_fw_cmd_ofld = true, + .ul_tb_waveform_ctrl = false, + .ul_tb_pwr_diff = true, + .rx_freq_from_ie = false, + .hw_sec_hdr = true, + .hw_mgmt_tx_encrypt = true, + .hw_tkip_crypto = true, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 20, + .scam_num = 128, + .bacam_num = 8, + .bacam_dynamic_num = 8, + .bacam_ver = RTW89_BACAM_V0_EXT, + .addrcam_ver = 0, + .ppdu_max_usr = 8, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, + .limit_efuse_size = 1280, + .dav_phy_efuse_size = 96, + .dav_log_efuse_size = 16, + .efuse_blocks = NULL, + .phycap_addr = 0x590, + .phycap_size = 0x60, + .para_ver = 0x1, + .wlcx_desired = 0x06000000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8852c_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852c_mon_reg), + .mon_reg = rtw89_btc_8852c_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8852c_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8852c_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852c_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852c_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1, + .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1, + .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), + .txwd_body_size = sizeof(struct rtw89_txwd_body_v1), + .txwd_info_size = sizeof(struct rtw89_txwd_info), + .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8852c_h2c_regs, + .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8852c_c2h_regs, + .page_regs = &rtw8852c_page_regs, + .wow_reason_reg = rtw8852c_wow_wakeup_regs, + .cfo_src_fd = false, + .cfo_hw_comp = false, + .dcfo_comp = &rtw8852c_dcfo_comp, + .dcfo_comp_sft = 12, + .nhm_report = NULL, + .nhm_th = NULL, + .imr_info = &rtw8852c_imr_info, + .imr_dmac_table = NULL, + .imr_cmac_table = NULL, + .rrsr_cfgs = &rtw8852c_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0}, + .bss_clr_map_reg = R_BSS_CLR_MAP, + .rfkill_init = &rtw8852c_rfkill_regs, + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, + .dma_ch_mask = 0, + .edcca_regs = &rtw8852c_edcca_regs, + .pmac_regs = &rtw8852c_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852c, +#endif + .xtal_info = NULL, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8852c_chip_info); + +MODULE_FIRMWARE(RTW8852C_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h new file mode 100644 index 000000000..b1d7c354c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_H__ +#define __RTW89_8852C_H__ + +#include "core.h" + +#define RF_PATH_NUM_8852C 2 +#define BB_PATH_NUM_8852C 2 + +struct rtw8852c_u_efuse { + u8 rsvd[0x88]; + u8 mac_addr[ETH_ALEN]; + u8 rsvd1[8]; + u8 sn[RTW89_EFUSE_SN_LEN]; + u8 rsvd2[29]; + u8 uuid[RTW89_EFUSE_UUID_LEN]; +} __packed; + +struct rtw8852c_e_efuse { + u8 mac_addr[ETH_ALEN]; +}; + +struct rtw8852c_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; +} __packed; + +struct rtw8852c_efuse { + u8 rsvd[0x210]; + struct rtw8852c_tssi_offset path_a_tssi; + u8 rsvd1[10]; + struct rtw8852c_tssi_offset path_b_tssi; + u8 rsvd2[94]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd3; + u8 iqk_lck; + u8 rsvd4[5]; + u8 reg_setting:2; + u8 tx_diversity:1; + u8 rx_diversity:2; + u8 ac_mode:1; + u8 module_type:2; + u8 rsvd5; + u8 shared_ant:1; + u8 coex_type:3; + u8 ant_iso:1; + u8 radio_on_off:1; + u8 rsvd6:2; + u8 eeprom_version; + u8 customer_id; + u8 tx_bb_swing_2g; + u8 tx_bb_swing_5g; + u8 tx_cali_pwr_trk_mode; + u8 trx_path_selection; + u8 rfe_type; + u8 country_code[2]; + u8 rsvd7[3]; + u8 path_a_therm; + u8 path_b_therm; + u8 rsvd8[2]; + u8 rx_gain_2g_ofdm; + u8 rsvd9; + u8 rx_gain_2g_cck; + u8 rsvd10; + u8 rx_gain_5g_low; + u8 rsvd11; + u8 rx_gain_5g_mid; + u8 rsvd12; + u8 rx_gain_5g_high; + u8 rsvd13[35]; + u8 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd14[10]; + u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd15[94]; + u8 rx_gain_6g_l0; + u8 rsvd16; + u8 rx_gain_6g_l1; + u8 rsvd17; + u8 rx_gain_6g_m0; + u8 rsvd18; + u8 rx_gain_6g_m1; + u8 rsvd19; + u8 rx_gain_6g_h0; + u8 rsvd20; + u8 rx_gain_6g_h1; + u8 rsvd21; + u8 rx_gain_6g_uh0; + u8 rsvd22; + u8 rx_gain_6g_uh1; + u8 rsvd23; + u8 channel_plan_6g; + u8 rsvd24[71]; + union { + struct rtw8852c_u_efuse u; + struct rtw8852c_e_efuse e; + }; +} __packed; + +extern const struct rtw89_chip_info rtw8852c_chip_info; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c new file mode 100644 index 000000000..8d03a4645 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -0,0 +1,4462 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852c.h" +#include "rtw8852c_rfk.h" +#include "rtw8852c_rfk_table.h" +#include "rtw8852c_table.h" + +struct rxck_def { + u32 ctl; + u32 en; + u32 bw0; + u32 bw1; + u32 mul; + u32 lp; +}; + +#define _TSSI_DE_MASK GENMASK(21, 12) +static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858}; +static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860}; +static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852C] = {0x5838, 0x7838}; +static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852C] = {0x5840, 0x7840}; +static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852C] = {0x5848, 0x7848}; +static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852C] = {0x5850, 0x7850}; +static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852C] = {0x5828, 0x7828}; +static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830}; + +static const u32 rtw8852c_backup_bb_regs[] = { + 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x8220, 0xc1d4, 0xc1d8, 0xc1e8 +}; + +static const u32 rtw8852c_backup_rf_regs[] = { + 0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005 +}; + +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852c_backup_rf_regs) + +#define RXK_GROUP_NR 4 +static const u32 _rxk_a6_idxrxgain[RXK_GROUP_NR] = {0x190, 0x196, 0x290, 0x316}; +static const u32 _rxk_a6_idxattc2[RXK_GROUP_NR] = {0x00, 0x0, 0x00, 0x00}; +static const u32 _rxk_a_idxrxgain[RXK_GROUP_NR] = {0x190, 0x198, 0x310, 0x318}; +static const u32 _rxk_a_idxattc2[RXK_GROUP_NR] = {0x00, 0x00, 0x00, 0x00}; +static const u32 _rxk_g_idxrxgain[RXK_GROUP_NR] = {0x252, 0x26c, 0x350, 0x360}; +static const u32 _rxk_g_idxattc2[RXK_GROUP_NR] = {0x00, 0x07, 0x00, 0x3}; + +#define TXK_GROUP_NR 3 +static const u32 _txk_a6_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_a6_track_range[TXK_GROUP_NR] = {0x6, 0x7, 0x7}; +static const u32 _txk_a6_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; +static const u32 _txk_a6_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; +static const u32 _txk_a_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_a_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x7}; +static const u32 _txk_a_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; +static const u32 _txk_a_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; +static const u32 _txk_g_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_g_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x6}; +static const u32 _txk_g_gain_bb[TXK_GROUP_NR] = {0x0e, 0x0a, 0x0e}; +static const u32 _txk_g_itqt[TXK_GROUP_NR] = { 0x12, 0x12, 0x12}; + +static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = { + {0x8190, 0x8194, 0x8198, 0x81a4}, + {0x81a8, 0x81c4, 0x81c8, 0x81e8}, +}; + +static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10}; +static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c}; + +static const struct rxck_def _ck480M = {0x8, 0x2, 0x3, 0xf, 0x0, 0x9}; +static const struct rxck_def _ck960M = {0x8, 0x2, 0x2, 0x8, 0x0, 0x9}; +static const struct rxck_def _ck1920M = {0x8, 0x0, 0x2, 0x4, 0x6, 0x9}; + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", + rtwdev->dbcc_en, phy_idx); + + if (!rtwdev->dbcc_en) + return RF_AB; + + if (phy_idx == RTW89_PHY_0) + return RF_A; + else + return RF_B; +} + +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852c_backup_bb_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup bb reg : %x, value =%x\n", + rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, + rtw8852c_backup_rf_regs[i], RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, + rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852c_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore bb reg : %x, value =%x\n", + rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8852c_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u8 path; + u32 rf_mode; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, + 2, 5000, false, rtwdev, path, 0x00, + RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[1][0], dack->addck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[1][0], dack->biask_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _addck_backup(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); + dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, + B_ADDCKR0_A0); + dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, + B_ADDCKR0_A1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0); + dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, + B_ADDCKR1_A0); + dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, + B_ADDCKR1_A1); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, + dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, + dack->addck_d[0][1]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1, + dack->addck_d[1][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0, + dack->addck_d[1][1]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x3); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); + dack->msbk_d[0][0][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK_S0P2, + B_DACK_S0M0); + rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); + dack->msbk_d[0][1][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK_S0P3, + B_DACK_S0M1); + } + dack->biask_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, + B_DACK_BIAS00); + dack->biask_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, + B_DACK_BIAS01); + dack->dadck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, + B_DACK_DADCK00); + dack->dadck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, + B_DACK_DADCK01); +} + +static void _dack_backup_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i); + dack->msbk_d[1][0][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK10S, + B_DACK10S); + rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i); + dack->msbk_d[1][1][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK11S, + B_DACK11S); + } + dack->biask_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, + B_DACK_BIAS10); + dack->biask_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, + B_DACK_BIAS11); + dack->dadck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, + B_DACK_DADCK10); + dack->dadck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, + B_DACK_DADCK11); +} + +static void _dack_reload_by_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 index) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 idx_offset, path_offset; + u32 val32, offset, addr; + u8 i; + + idx_offset = (index == 0 ? 0 : 0x14); + path_offset = (path == RF_PATH_A ? 0 : 0x28); + offset = idx_offset + path_offset; + + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_reload_defs_tbl); + + /* msbk_d: 15/14/13/12 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 12] << (i * 8); + addr = 0xc200 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 11/10/9/8 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 8] << (i * 8); + addr = 0xc204 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 7/6/5/4 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 4] << (i * 8); + addr = 0xc208 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 3/2/1/0 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i] << (i * 8); + addr = 0xc20c + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* dadak_d/biask_d */ + val32 = (dack->biask_d[path][index] << 22) | + (dack->dadck_d[path][index] << 14); + addr = 0xc210 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_phy_write32_set(rtwdev, addr, BIT(0)); +} + +static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u8 i; + + for (i = 0; i < 2; i++) + _dack_reload_by_path(rtwdev, path, i); +} + +static void _addck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + /* S0 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0); + fsleep(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc0fc, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0); + + /* S1 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc1fc, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x0); +} + +static void _dack_reset(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_dack_reset_defs_a_tbl, + &rtw8852c_dack_reset_defs_b_tbl); +} + +enum adc_ck { + ADC_NA = 0, + ADC_480M = 1, + ADC_960M = 2, + ADC_1920M = 3, +}; + +enum dac_ck { + DAC_40M = 0, + DAC_80M = 1, + DAC_120M = 2, + DAC_160M = 3, + DAC_240M = 4, + DAC_320M = 5, + DAC_480M = 6, + DAC_960M = 7, +}; + +enum rf_mode { + RF_SHUT_DOWN = 0x0, + RF_STANDBY = 0x1, + RF_TX = 0x2, + RF_RX = 0x3, + RF_TXIQK = 0x4, + RF_DPK = 0x5, + RF_RXK1 = 0x6, + RF_RXK2 = 0x7, +}; + +static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + enum dac_ck ck) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1); +} + +static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + enum adc_ck ck) +{ + const struct rxck_def *def; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1); + + switch (ck) { + case ADC_480M: + def = &_ck480M; + break; + case ADC_960M: + def = &_ck960M; + break; + case ADC_1920M: + default: + def = &_ck1920M; + break; + } + + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, def->ctl); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, def->en); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, def->bw0); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, def->bw1); + rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, def->mul); + rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, def->lp); +} + +static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0) +{ + if (s0) { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) + return false; + } else { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0) + return false; + } + + return true; +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw8852c_txck_force(rtwdev, RF_PATH_A, true, DAC_160M); + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s0_tbl); + + _dack_reset(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); + ret = read_poll_timeout_atomic(_check_dack_done, done, done, + 1, 10000, false, rtwdev, true); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x0); + rtw8852c_txck_force(rtwdev, RF_PATH_A, false, DAC_960M); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); + + _dack_backup_s0(rtwdev); + _dack_reload(rtwdev, RF_PATH_A); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); +} + +static void _dack_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw8852c_txck_force(rtwdev, RF_PATH_B, true, DAC_160M); + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s1_tbl); + + _dack_reset(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x1); + ret = read_poll_timeout_atomic(_check_dack_done, done, done, + 1, 10000, false, rtwdev, false); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x0); + rtw8852c_txck_force(rtwdev, RF_PATH_B, false, DAC_960M); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); + + _dack_backup_s1(rtwdev); + _dack_reload(rtwdev, RF_PATH_B); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); + _dack_s1(rtwdev); +} + +static void _drck(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc0c8, BIT(3)); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); + + rtw89_rfk_parser(rtwdev, &rtw8852c_drck_defs_tbl); + + val = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, B_DRCK_RES); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, val); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 rf0_0, rf1_0; + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB, chanctx_idx); + + dack->dack_done = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); + rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); + _drck(rtwdev); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _addck(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + + _addck_backup(rtwdev); + _addck_reload(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _dack(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + + _dack_dump(rtwdev); + dack->dack_done = true; + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + +#define RTW8852C_NCTL_VER 0xd +#define RTW8852C_IQK_VER 0x2a +#define RTW8852C_IQK_SS 2 +#define RTW8852C_IQK_THR_REK 8 +#define RTW8852C_IQK_CFIR_GROUP_NR 4 + +enum rtw8852c_iqk_type { + ID_TXAGC, + ID_G_FLOK_COARSE, + ID_A_FLOK_COARSE, + ID_G_FLOK_FINE, + ID_A_FLOK_FINE, + ID_FLOK_VBUFFER, + ID_TXK, + ID_RXAGC, + ID_RXK, + ID_NBTXK, + ID_NBRXK, +}; + +static void rtw8852c_disable_rxagc(struct rtw89_dev *rtwdev, u8 path, u8 en_rxgac) +{ + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, en_rxgac); + else + rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, en_rxgac); +} + +static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0202); + + switch (iqk_info->iqk_bw[path]) { + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_480M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_960M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x1); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x2); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + default: + break; + } + + rtw89_rfk_parser(rtwdev, &rtw8852c_iqk_rxk_cfg_defs_tbl); + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1101); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x2202); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) +{ + u32 tmp; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); + + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); + tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); + + return false; +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, u8 ktype) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 addr_rfc_ctl = R_UPD_CLK + (path << 13); + u32 iqk_cmd; + bool fail; + + switch (ktype) { + case ID_TXAGC: + iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); + break; + case ID_A_FLOK_COARSE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x008 | (1 << (4 + path)); + break; + case ID_G_FLOK_COARSE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_A_FLOK_FINE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x508 | (1 << (4 + path)); + break; + case ID_G_FLOK_FINE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x208 | (1 << (4 + path)); + break; + case ID_FLOK_VBUFFER: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_TXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + iqk_cmd = 0x008 | (1 << (4 + path)) | ((0x8 + iqk_info->iqk_bw[path]) << 8); + break; + case ID_RXAGC: + iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x008 | (1 << (4 + path)) | ((0xc + iqk_info->iqk_bw[path]) << 8); + break; + case ID_NBTXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + iqk_cmd = 0x408 | (1 << (4 + path)); + break; + case ID_NBRXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + fsleep(15); + fail = _iqk_check_cal(rtwdev, path, ktype); + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + + return fail; +} + +static bool _rxk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u32 tmp; + u32 bkrf0; + u8 gp; + + bkrf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_NBW); + if (path == RF_PATH_B) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, 0x3); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_MOD); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_AGH, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, tmp); + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXG, RR_RXG_IQKMOD, 0x9); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x8); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x9); + break; + } + + fsleep(10); + + for (gp = 0; gp < RXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_VOBUF, + _rxk_g_idxattc2[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, + _rxk_a_idxattc2[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_a6_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, + _rxk_a6_idxattc2[gp]); + break; + } + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP_V1, gp); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + } + + if (path == RF_PATH_B) + rtw89_write_rf(rtwdev, path, RR_IQKPLL, RR_IQKPLL_MOD, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, bkrf0); + + if (fail) { + iqk_info->nb_rxcfir[path] = 0x40000002; + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->nb_rxcfir[path] = 0x40000000; + iqk_info->is_wb_rxiqk[path] = true; + } + + return false; +} + +static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u32 tmp; + u32 bkrf0; + u8 gp = 0x2; + + bkrf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_NBW); + if (path == RF_PATH_B) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, 0x3); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_MOD); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_AGH, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, tmp); + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXG, RR_RXG_IQKMOD, 0x9); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x8); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x9); + break; + } + + fsleep(10); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_VOBUF, _rxk_g_idxattc2[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, _rxk_a_idxattc2[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_a6_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, _rxk_a6_idxattc2[gp]); + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, gp); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + + if (path == RF_PATH_B) + rtw89_write_rf(rtwdev, path, RR_IQKPLL, RR_IQKPLL_MOD, 0x0); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, bkrf0); + + if (fail) + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD) | 0x2; + else + iqk_info->nb_rxcfir[path] = 0x40000002; + + iqk_info->is_wb_rxiqk[path] = false; + return fail; +} + +static bool _txk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u8 gp; + + for (gp = 0; gp < TXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a_itqt[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_a6_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_a6_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_a6_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a6_itqt[gp]); + break; + default: + break; + } + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP, gp + 1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x00b); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + } + + if (fail) { + iqk_info->nb_txcfir[path] = 0x40000002; + iqk_info->is_wb_txiqk[path] = false; + } else { + iqk_info->nb_txcfir[path] = 0x40000000; + iqk_info->is_wb_txiqk[path] = true; + } + + return fail; +} + +static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u8 gp = 0x2; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a_itqt[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_a6_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_a6_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_a6_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a6_itqt[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp + 1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x00b); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + + if (!fail) + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD) | 0x2; + else + iqk_info->nb_txcfir[path] = 0x40000002; + + iqk_info->is_wb_txiqk[path] = false; + + return fail; +} + +static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = rfk_mcc->table_idx; + bool is_fail1, is_fail2; + u32 val; + u32 core_i; + u32 core_q; + u32 vbuff_i; + u32 vbuff_q; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + val = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); + core_i = FIELD_GET(RR_TXMO_COI, val); + core_q = FIELD_GET(RR_TXMO_COQ, val); + + if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) + is_fail1 = true; + else + is_fail1 = false; + + iqk_info->lok_idac[idx][path] = val; + + val = rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK); + vbuff_i = FIELD_GET(RR_LOKVB_COI, val); + vbuff_q = FIELD_GET(RR_LOKVB_COQ, val); + + if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d) + is_fail2 = true; + else + is_fail2 = false; + + iqk_info->lok_vbuf[idx][path] = val; + + return is_fail1 || is_fail2; +} + +static bool _iqk_lok(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 tmp_id = 0x0; + bool fail = false; + bool tmp = false; + + /* Step 0: Init RF gain & tone idx= 8.25Mhz */ + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, IQK_DF4_TXT_8_25MHZ); + + /* Step 1 START: _lok_coarse_fine_wi_swap */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_G_FLOK_COARSE; + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_COARSE; + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_COARSE; + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, tmp_id); + iqk_info->lok_cor_fail[0][path] = tmp; + + /* Step 2 */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + + /* Step 3 */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_G_FLOK_FINE; + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_FINE; + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_FINE; + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, tmp_id); + iqk_info->lok_fin_fail[0][path] = tmp; + + /* Step 4 large rf gain */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + fail = _lok_finetune_check(rtwdev, path); + + return fail; +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXAS, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXAS, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + } +} + +static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp; + bool flag; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path, + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, + iqk_info->lok_cor_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, + iqk_info->lok_fin_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, + iqk_info->iqk_tx_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, + iqk_info->iqk_rx_fail[0][path]); + + flag = iqk_info->lok_cor_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag); + flag = iqk_info->lok_fin_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), flag); + flag = iqk_info->iqk_tx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), flag); + flag = iqk_info->iqk_rx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), flag); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); + iqk_info->bp_iqkenable[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + iqk_info->bp_txkresult[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); + iqk_info->bp_rxkresult[path] = tmp; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, + iqk_info->iqk_times); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4)); + if (tmp != 0x0) + iqk_info->iqk_fail_cnt++; + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4), + iqk_info->iqk_fail_cnt); +} + +static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + _iqk_txk_setting(rtwdev, path); + iqk_info->lok_fail[path] = _iqk_lok(rtwdev, phy_idx, path); + + if (iqk_info->is_nbiqk) + iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); + + _iqk_rxk_setting(rtwdev, path); + if (iqk_info->is_nbiqk) + iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); + + _iqk_info_iqk(rtwdev, phy_idx, path); +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + iqk_info->iqk_band[path] = chan->band_type; + iqk_info->iqk_bw[path] = chan->band_width; + iqk_info->iqk_ch[path] = chan->channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, + iqk_info->iqk_band[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", + path, iqk_info->iqk_bw[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", + path, iqk_info->iqk_ch[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, + str_on_off(rtwdev->dbcc_en), + iqk_info->iqk_band[path] == 0 ? "2G" : + iqk_info->iqk_band[path] == 1 ? "5G" : "6G", + iqk_info->iqk_ch[path], + iqk_info->iqk_bw[path] == 0 ? "20M" : + iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); + if (!rtwdev->dbcc_en) + iqk_info->syn1to2 = 0x1; + else + iqk_info->syn1to2 = 0x3; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852C_IQK_VER); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16), + iqk_info->iqk_band[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16), + iqk_info->iqk_bw[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16), + iqk_info->iqk_ch[path]); + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_NCTLV, RTW8852C_NCTL_VER); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + _iqk_by_path(rtwdev, phy_idx, path); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, + iqk_info->nb_txcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + iqk_info->nb_rxcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00001219 + (path << 4)); + fsleep(200); + fail = _iqk_check_cal(rtwdev, path, 0x12); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail = %x\n", fail); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_iqk_afebb_restore_defs_a_tbl, + &rtw8852c_iqk_afebb_restore_defs_b_tbl); + + rtw8852c_disable_rxagc(rtwdev, path, 0x1); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + u8 idx = 0; + + idx = rfk_mcc->table_idx; + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); + + /* 01_BB_AFE_for DPK_S0_20210820 */ + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + + /* disable rxgac */ + rtw8852c_disable_rxagc(rtwdev, path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), MASKDWORD, 0xf801fffd); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DAC_VAL, 0x1); + + rtw8852c_txck_force(rtwdev, path, true, DAC_960M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_GDIS, 0x1); + + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, 0x2); + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x1); +} + +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5, rck_val = 0; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, + false, rtwdev, path, 0x1c, BIT(3)); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RCK] RF 0x1b / 0x1c = 0x%x / 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK)); +} + +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 ch, path; + + rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->iqk_times = 0x0; + + for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { + iqk_info->iqk_channel[ch] = 0x0; + for (path = 0; path < RTW8852C_IQK_SS; path++) { + iqk_info->lok_cor_fail[ch][path] = false; + iqk_info->lok_fin_fail[ch][path] = false; + iqk_info->iqk_tx_fail[ch][path] = false; + iqk_info->iqk_rx_fail[ch][path] = false; + iqk_info->iqk_mcc_ch[ch][path] = 0x0; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852C_IQK_SS][BACKUP_RF_REGS_NR]; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->version = RTW8852C_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); + _rfk_backup_bb_reg(rtwdev, backup_bb_val); + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_restore_bb_reg(rtwdev, backup_bb_val); + _rfk_restore_rf_reg(rtwdev, backup_rf_val[path], path); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + switch (_kpath(rtwdev, phy_idx)) { + case RF_A: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + break; + case RF_B: + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + case RF_AB: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); + _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); + break; + default: + break; + } +} + +static void _rx_dck_value_rewrite(struct rtw89_dev *rtwdev, u8 path, u8 addr, + u8 val_i, u8 val_q) +{ + u32 ofst_val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] rewrite val_i = 0x%x, val_q = 0x%x\n", val_i, val_q); + + /* val_i and val_q are 7 bits, and target is 6 bits. */ + ofst_val = u32_encode_bits(val_q >> 1, RR_LUTWD0_MB) | + u32_encode_bits(val_i >> 1, RR_LUTWD0_LB); + + rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x1); + rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x1); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, MASKBYTE0, addr); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); + rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] Final val_i = 0x%x, val_q = 0x%x\n", + u32_get_bits(ofst_val, RR_LUTWD0_LB) << 1, + u32_get_bits(ofst_val, RR_LUTWD0_MB) << 1); +} + +static bool _rx_dck_rek_check(struct rtw89_dev *rtwdev, u8 path) +{ + u8 i_even_bs, q_even_bs; + u8 i_odd_bs, q_odd_bs; + u8 i_even, q_even; + u8 i_odd, q_odd; + const u8 th = 10; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]); + i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n", + _dck_addr_bs[i], i_even_bs, q_even_bs); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]); + i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n", + _dck_addr[i], i_even, q_even); + + if (abs(i_even_bs - i_even) > th || abs(q_even_bs - q_even) > th) + return true; + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1); + i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n", + _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1); + i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n", + _dck_addr[i] + 1, i_odd, q_odd); + + if (abs(i_odd_bs - i_odd) > th || abs(q_odd_bs - q_odd) > th) + return true; + } + + return false; +} + +static void _rx_dck_fix_if_need(struct rtw89_dev *rtwdev, u8 path, u8 addr, + u8 val_i_bs, u8 val_q_bs, u8 val_i, u8 val_q) +{ + const u8 th = 10; + + if ((abs(val_i_bs - val_i) < th) && (abs(val_q_bs - val_q) <= th)) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] offset check PASS!!\n"); + return; + } + + if (abs(val_i_bs - val_i) > th) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] val_i over TH (0x%x / 0x%x)\n", val_i_bs, val_i); + val_i = val_i_bs; + } + + if (abs(val_q_bs - val_q) > th) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] val_q over TH (0x%x / 0x%x)\n", val_q_bs, val_q); + val_q = val_q_bs; + } + + _rx_dck_value_rewrite(rtwdev, path, addr, val_i, val_q); +} + +static void _rx_dck_recover(struct rtw89_dev *rtwdev, u8 path) +{ + u8 i_even_bs, q_even_bs; + u8 i_odd_bs, q_odd_bs; + u8 i_even, q_even; + u8 i_odd, q_odd; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] ===> recovery\n"); + + for (i = 0; i < RF_PATH_NUM_8852C; i++) { + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]); + i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1); + i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n", + _dck_addr_bs[i], i_even_bs, q_even_bs); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]); + i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n", + _dck_addr[i], i_even, q_even); + _rx_dck_fix_if_need(rtwdev, path, _dck_addr[i], + i_even_bs, q_even_bs, i_even, q_even); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n", + _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1); + i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); + q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n", + _dck_addr[i] + 1, i_odd, q_odd); + _rx_dck_fix_if_need(rtwdev, path, _dck_addr[i] + 1, + i_odd_bs, q_odd_bs, i_odd, q_odd); + } +} + +static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path) +{ + int ret; + u32 val; + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, + 2, 2000, false, rtwdev, path, + RR_DCK1, RR_DCK1_DONE); + if (ret) + rtw89_warn(rtwdev, "[RX_DCK] S%d RXDCK timeout\n", path); + else + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] S%d RXDCK finish\n", path); + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); +} + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path, + bool is_afe) +{ + u8 res; + + rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0); + + _rx_dck_toggle(rtwdev, path); + if (rtw89_read_rf(rtwdev, path, RR_DCKC, RR_DCKC_CHK) == 0) + return; + res = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_DONE); + if (res > 1) { + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_IDAC, res); + _rx_dck_toggle(rtwdev, path); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_IDAC, 0x1); + } +} + +static +u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) +{ + u8 target_ch = 0; + + if (chan->band_type == RTW89_BAND_5G) { + if (chan->channel >= 36 && chan->channel <= 64) { + target_ch = 100; + } else if (chan->channel >= 100 && chan->channel <= 144) { + target_ch = chan->channel + 32; + if (target_ch > 144) + target_ch = chan->channel + 33; + } else if (chan->channel >= 149 && chan->channel <= 177) { + target_ch = chan->channel - 33; + } + } else if (chan->band_type == RTW89_BAND_6G) { + if (chan->channel > 125) + target_ch = chan->channel - 32; + else + target_ch = chan->channel + 32; + } else { + target_ch = chan->channel; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] cur_ch / target_ch = %d / %d\n", + chan->channel, target_ch); + + return target_ch; +} + +#define RTW8852C_RF_REL_VERSION 34 +#define RTW8852C_DPK_VER 0xf +#define RTW8852C_DPK_TH_AVG_NUM 4 +#define RTW8852C_DPK_RF_PATH 2 +#define RTW8852C_DPK_KIP_REG_NUM 7 +#define RTW8852C_DPK_RXSRAM_DBG 0 + +enum rtw8852c_dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, + DPK_RXAGC = 0x15, + KIP_PRESET = 0x16, + KIP_RESTORE = 0x17, + DPK_TXAGC = 0x19, + D_KIP_PRESET = 0x28, + D_TXAGC = 0x29, + D_RXAGC = 0x2a, + D_SYNC = 0x2b, + D_GAIN_LOSS = 0x2c, + D_MDPK_IDL = 0x2d, + D_GAIN_NORM = 0x2f, + D_KIP_THERMAL = 0x30, + D_KIP_RESTORE = 0x31 +}; + +#define DPK_TXAGC_LOWER 0x2e +#define DPK_TXAGC_UPPER 0x3f +#define DPK_TXAGC_INVAL 0xff + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +enum dpk_pas_result { + DPK_PAS_NOR, + DPK_PAS_GT, + DPK_PAS_LT, +}; + +static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off); + +static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[], + u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { + reg_bkup[path][i] = + rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[], + u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), + MASKDWORD, reg_bkup[path][i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw8852c_dpk_id id) +{ + u16 dpk_cmd; + u32 val; + int ret; + + dpk_cmd = (u16)((id << 8) | (0x19 + path * 0x12)); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); + udelay(10); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%x (ret=%d)\n", + id == 0x06 ? "LBK_RXIQK" : + id == 0x10 ? "SYNC" : + id == 0x11 ? "MDPK_IDL" : + id == 0x12 ? "MDPK_MPA" : + id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", + dpk_cmd, ret); + + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot over 20ms!!!!\n"); + return 1; + } + + return 0; +} + +static void _dpk_information(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = chan->band_type; + dpk->bp[path][kidx].ch = chan->channel; + dpk->bp[path][kidx].bw = chan->band_width; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + str_on_off(rtwdev->is_tssi_mode[path]), + str_on_off(rtwdev->dbcc_en), + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); +} + +static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + /*1. Keep ADC_fifo reset*/ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + + /*2. BB for IQK DBG mode*/ + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd); + + /*3.Set DAC clk*/ + rtw8852c_txck_force(rtwdev, path, true, DAC_960M); + + /*4. Set ADC clk*/ + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), + B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0001); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0041); + + /*5. ADDA fifo rst*/ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE setting\n", path); +} + +static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), + B_P0_NRBW_DBG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE restore\n", path); +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, u8 path, bool ctrl_by_kip) +{ + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_IQK_RFC_ON, ctrl_by_kip); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RFC is controlled by %s\n", + ctrl_by_kip ? "KIP" : "BB"); +} + +static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, u8 path, bool force) +{ + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, force); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", + path, str_on_off(force)); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + _dpk_one_shot(rtwdev, phy, path, D_KIP_RESTORE); + _dpk_kip_control_rfc(rtwdev, path, false); + _dpk_txpwr_bb_force(rtwdev, path, false); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ +#define RX_TONE_IDX 0x00250025 /* Q.2 9.25MHz */ + u8 cur_rxbb; + u32 rf_11, reg_81cc; + + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, false); + + cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + rf_11 = rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK); + reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_SW); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x3); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0xd); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, 0x1f); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, 0x3); + + _dpk_kip_control_rfc(rtwdev, path, true); + + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, RX_TONE_IDX); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); + + _dpk_kip_control_rfc(rtwdev, path, false); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RFREG_MASK, rf_11); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, cur_rxbb); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, reg_81cc); + + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, true); +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x50121 | BIT(rtwdev->dbcc_en)); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x2); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] RF 0x0/0x83/0x9e/0x1a/0xdf/0x1001a = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RXBB, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_TIA, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_LUTDBG, RFREG_MASK), + rtw89_read_rf(rtwdev, path, 0x1001a, RFREG_MASK)); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x50101 | BIT(rtwdev->dbcc_en)); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + + if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161) + rtw89_write_rf(rtwdev, path, RR_IQGEN, RR_IQGEN_BIAS, 0x8); + + rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd); + rtw89_write_rf(rtwdev, path, RR_TXAC, RR_TXAC_IQG, 0x8); + + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_ATT, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT2, 0x3); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); + } +} + +static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x3); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0x0180ff30); + } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xffe0fa00); + } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xff4009e0); + } else { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xf9f007d0); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160 ? "160M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define DPK_SYNC_TH_DC_I 200 +#define DPK_SYNC_TH_DC_Q 200 +#define DPK_SYNC_TH_CORR 170 + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u16 dc_i, dc_q; + u8 corr_val, corr_idx, rxbb; + u8 rxbb_ov; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); + corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); + + dpk->corr_idx[path][kidx] = corr_idx; + dpk->corr_val[path][kidx] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n", + path, corr_idx, corr_val, dc_i, dc_q); + + dpk->dc_i[path][kidx] = dc_i; + dpk->dc_q[path][kidx] = dc_q; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x8); + rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x31); + rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n", + path, rxbb, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), + rxbb_ov); + + if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || + corr_val < DPK_SYNC_TH_CORR) + return true; + else + return false; +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain = 0x0; + + rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); + + dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, dgain); + + return dgain; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + u8 result; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + + result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp GL = %d\n", result); + + return result; +} + +static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0x10); + dpk->cur_k_set = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), 0xE0000000) - 1; +} + +static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 dbm, bool set_from_bb) +{ + if (set_from_bb) { + dbm = clamp_t(u8, dbm, 7, 24); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set S%d txagc to %ddBm\n", path, dbm); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_VAL, dbm << 2); + } + _dpk_one_shot(rtwdev, phy, path, D_TXAGC); + _dpk_kset_query(rtwdev, path); +} + +static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, D_GAIN_LOSS); + _dpk_kip_set_txagc(rtwdev, phy, path, 0xff, false); + + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, 0x0); + + return _dpk_gainloss_read(rtwdev); +} + +static enum dpk_pas_result _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u32 val1_sqrt_sum, val2_sqrt_sum; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + + val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; + val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; + + if (val1_sqrt_sum < val2_sqrt_sum) + return DPK_PAS_LT; + else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) + return DPK_PAS_GT; + else + return DPK_PAS_NOR; +} + +static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_kip_control_rfc(rtwdev, path, false); + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + _dpk_kip_control_rfc(rtwdev, path, true); + + _dpk_one_shot(rtwdev, phy, path, D_RXAGC); + + return _dpk_sync_check(rtwdev, path, kidx); +} + +static void _dpk_read_rxsram(struct rtw89_dev *rtwdev) +{ + u32 addr; + + rtw89_rfk_parser(rtwdev, &rtw8852c_read_rxsram_pre_defs_tbl); + + for (addr = 0; addr < 0x200; addr++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 | addr); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RXSRAM[%03d] = 0x%07x\n", addr, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + + rtw89_rfk_parser(rtwdev, &rtw8852c_read_rxsram_post_defs_tbl); +} + +static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000002); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Bypass RXIQC\n"); +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; + u8 tmp_rxbb; + u8 goout = 0, agc_cnt = 0; + enum dpk_pas_result pas; + u16 dgain = 0; + bool is_fail = false; + int limit = 200; + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); + + if (RTW8852C_DPK_RXSRAM_DBG) + _dpk_read_rxsram(rtwdev); + + if (is_fail) { + goout = 1; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + + if (dgain > 0x5fc || dgain < 0x556) { + _dpk_one_shot(rtwdev, phy, path, D_SYNC); + _dpk_dgain_read(rtwdev); + } + + if (agc_cnt == 0) { + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + _dpk_bypass_rxiqc(rtwdev, path); + else + _dpk_lbk_rxiqk(rtwdev, phy, path); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + break; + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); + pas = _dpk_pas_read(rtwdev, true); + + if (pas == DPK_PAS_LT && tmp_gl_idx > 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else if (pas == DPK_PAS_GT && tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx >= 7) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + break; + + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_dbm <= 7) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_dbm = max_t(u8, tmp_dbm - 3, 7); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_dbm >= 24) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_dbm = min_t(u8, tmp_dbm + 2, 24); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_SET_TX_GAIN: + _dpk_kip_control_rfc(rtwdev, path, false); + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + if (tmp_rxbb + tmp_gl_idx > 0x1f) + tmp_rxbb = 0x1f; + else + tmp_rxbb = tmp_rxbb + tmp_gl_idx; + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust RXBB (%+d) = 0x%x\n", + tmp_gl_idx, tmp_rxbb); + _dpk_kip_control_rfc(rtwdev, path, true); + goout = 1; + break; + default: + goout = 1; + break; + } + } while (!goout && agc_cnt < 6 && --limit > 0); + + if (limit <= 0) + rtw89_warn(rtwdev, "[DPK] exceed loop limit\n"); + + return is_fail; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) +{ + static const struct rtw89_rfk_tbl *order_tbls[] = { + &rtw8852c_dpk_mdpd_order0_defs_tbl, + &rtw8852c_dpk_mdpd_order1_defs_tbl, + &rtw8852c_dpk_mdpd_order2_defs_tbl, + &rtw8852c_dpk_mdpd_order3_defs_tbl, + }; + + if (order >= ARRAY_SIZE(order_tbls)) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Wrong MDPD order!!(0x%x)\n", order); + return; + } + + rtw89_rfk_parser(rtwdev, order_tbls[order]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", + order == 0x0 ? "(5,3,1)" : + order == 0x1 ? "(5,3,0)" : + order == 0x2 ? "(5,0,0)" : "(7,3,1)"); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 cnt; + u8 ov_flag; + u32 dpk_sync; + + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, 0x1); + + if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T2) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x2); + else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T1) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x1); + else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T0) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x0); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_5 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_10 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_20) + _dpk_set_mdpd_para(rtwdev, 0x2); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) + _dpk_set_mdpd_para(rtwdev, 0x1); + else + _dpk_set_mdpd_para(rtwdev, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, 0x0); + fsleep(1000); + + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + dpk_sync = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] dpk_sync = 0x%x\n", dpk_sync); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0xf); + ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); + for (cnt = 0; cnt < 5 && ov_flag == 0x1; cnt++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] ReK due to MDPK ov!!!\n"); + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0xf); + ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); + } + + if (ov_flag) { + _dpk_set_mdpd_para(rtwdev, 0x2); + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + } +} + +static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + bool is_reload = false; + u8 idx, cur_band, cur_ch; + + cur_band = chan->band_type; + cur_ch = chan->channel; + + for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { + if (cur_band != dpk->bp[path][idx].band || + cur_ch != dpk->bp[path][idx].ch) + continue; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, idx); + dpk->cur_idx[path] = idx; + is_reload = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] reload S%d[%d] success\n", path, idx); + } + + return is_reload; +} + +static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) +{ + rtw89_rfk_parser(rtwdev, turn_on ? &rtw8852c_dpk_kip_pwr_clk_on_defs_tbl : + &rtw8852c_dpk_kip_pwr_clk_off_defs_tbl); +} + +static void _dpk_kip_preset_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + if (rtwdev->hal.cv == CHIP_CAV) + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_SEL, 0x01); + else + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_SEL, 0x0c); + + _dpk_kip_control_rfc(rtwdev, path, true); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); + + _dpk_one_shot(rtwdev, phy, path, D_KIP_PRESET); +} + +static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define _DPK_PARA_TXAGC GENMASK(15, 10) +#define _DPK_PARA_THER GENMASK(31, 26) + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u32 para; + + para = rtw89_phy_read32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + MASKDWORD); + + dpk->bp[path][kidx].txagc_dpk = FIELD_GET(_DPK_PARA_TXAGC, para); + dpk->bp[path][kidx].ther_dpk = FIELD_GET(_DPK_PARA_THER, para); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n", + dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, dpk->bp[path][kidx].txagc_dpk); +} + +static void _dpk_gain_normalize_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, bool is_execute) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (is_execute) { + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_AG, 0x200); + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_EN, 0x3); + + _dpk_one_shot(rtwdev, phy, path, D_GAIN_NORM); + } else { + rtw89_phy_write32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + 0x0000007F, 0x5b); + } + dpk->bp[path][kidx].gs = + rtw89_phy_read32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + 0x0000007F); +} + +static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) +{ + u32 val32 = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); + u8 val; + + switch (val32) { + case 0: + val = 0x6; + break; + case 1: + val = 0x2; + break; + case 2: + val = 0x0; + break; + case 3: + val = 0x7; + break; + default: + val = 0xff; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); + + return val; +} + +static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_ORDER, _dpk_order_convert(rtwdev)); + + dpk->bp[path][kidx].mdpd_en = BIT(dpk->cur_k_set); + dpk->bp[path][kidx].path_ok = true; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] path_ok = 0x%x\n", + path, kidx, dpk->bp[path][kidx].mdpd_en); + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_MEN, dpk->bp[path][kidx].mdpd_en); + + _dpk_gain_normalize_8852c(rtwdev, phy, path, kidx, false); +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 gain) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + u8 init_xdbm = 15; + bool is_fail; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx); + _dpk_kip_control_rfc(rtwdev, path, false); + _rf_direct_cntrl(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd); + _dpk_rf_setting(rtwdev, gain, path, kidx); + _set_rx_dck(rtwdev, phy, path, false); + _dpk_kip_pwr_clk_onoff(rtwdev, true); + _dpk_kip_preset_8852c(rtwdev, phy, path, kidx); + _dpk_txpwr_bb_force(rtwdev, path, true); + _dpk_kip_set_txagc(rtwdev, phy, path, init_xdbm, true); + _dpk_tpg_sel(rtwdev, path, kidx); + + is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, false); + if (is_fail) + goto _error; + + _dpk_idl_mpa(rtwdev, phy, path, kidx); + _dpk_para_query(rtwdev, path, kidx); + _dpk_on(rtwdev, phy, path, kidx); + +_error: + _dpk_kip_control_rfc(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d]_K%d %s\n", path, kidx, + dpk->cur_k_set, is_fail ? "need Check" : "is Success"); + + return is_fail; +} + +static void _dpk_init(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].path_ok = false; +} + +static void _dpk_drf_direct_cntrl(struct rtw89_dev *rtwdev, u8 path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8}; + u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR]; + u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {}; + u8 path; + bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false}; + + static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM); + + if (dpk->is_dpk_reload_en) { + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path))) + continue; + + reloaded[path] = _dpk_reload_check(rtwdev, phy, path, + chanctx_idx); + if (!reloaded[path] && dpk->bp[path][0].ch != 0) + dpk->cur_idx[path] = !dpk->cur_idx[path]; + else + _dpk_onoff(rtwdev, path, false); + } + } else { + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) + dpk->cur_idx[path] = 0; + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Init =========\n", + path, dpk->cur_idx[path]); + _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _dpk_information(rtwdev, phy, path, chanctx_idx); + _dpk_init(rtwdev, path); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", + path, dpk->cur_idx[path]); + rtw8852c_disable_rxagc(rtwdev, path, 0x0); + _dpk_drf_direct_cntrl(rtwdev, path, false); + _dpk_bb_afe_setting(rtwdev, phy, path, kpath); + is_fail = _dpk_main(rtwdev, phy, path, 1); + _dpk_onoff(rtwdev, path, is_fail); + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Restore =========\n", + path, dpk->cur_idx[path]); + _dpk_kip_restore(rtwdev, phy, path); + _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_restore_rf_reg(rtwdev, backup_rf_val[path], path); + _dpk_bb_afe_restore(rtwdev, path); + rtw8852c_disable_rxagc(rtwdev, path, 0x1); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } + + _dpk_kip_pwr_clk_onoff(rtwdev, false); +} + +static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + struct rtw89_fem_info *fem = &rtwdev->fem; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u8 band = chan->band_type; + + if (rtwdev->hal.cv == CHIP_CAV && band != RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to CAV & not 2G!!\n"); + return true; + } else if (fem->epa_2g && band == RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_5g && band == RTW89_BAND_5G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_6g && band == RTW89_BAND_6G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 6G_ext_PA exist!!\n"); + return true; + } + + return false; +} + +static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, kpath; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + if (kpath & BIT(path)) + _dpk_onoff(rtwdev, path, true); + } +} + +static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force, + enum rtw89_chanctx_idx chanctx_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", + RTW8852C_DPK_VER, rtwdev->hal.cv, + RTW8852C_RF_REL_VERSION); + + if (_dpk_bypass_check(rtwdev, phy, chanctx_idx)) + _dpk_force_bypass(rtwdev, phy); + else + _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), chanctx_idx); + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_DCKC, RR_DCKC_CHK) == 0x1) + rtw8852c_rx_dck(rtwdev, phy, false); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 val, kidx = dpk->cur_idx[path]; + + val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok ? + dpk->bp[path][kidx].mdpd_en : 0; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_MEN, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 path, kidx; + u8 txagc_rf = 0; + s8 txagc_bb = 0, txagc_bb_tp = 0, txagc_ofst = 0; + u8 cur_ther; + s8 delta_ther = 0; + s16 pwsf_tssi_ofst; + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + kidx = dpk->cur_idx[path]; + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + txagc_rf = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), 0x0000003f); + txagc_bb = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), MASKBYTE2); + txagc_bb_tp = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), B_TXAGC_BTP); + + /* report from KIP */ + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xf); + cur_ther = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TH); + txagc_ofst = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_OF); + pwsf_tssi_ofst = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TSSI); + pwsf_tssi_ofst = sign_extend32(pwsf_tssi_ofst, 12); + + cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] thermal now = %d\n", cur_ther); + + if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) + delta_ther = dpk->bp[path][kidx].ther_dpk - cur_ther; + + delta_ther = delta_ther * 1 / 2; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n", + delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n", + txagc_rf - dpk->bp[path][kidx].txagc_dpk, txagc_rf, + dpk->bp[path][kidx].txagc_dpk); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n", + txagc_ofst, pwsf_tssi_ofst); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + if (rtw89_phy_read32_mask(rtwdev, R_DPK_WR, B_DPK_WR_ST) == 0x0 && + txagc_rf != 0 && rtwdev->hal.cv == CHIP_CAV) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf = 0x%x\n", 0x78 - delta_ther); + + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x07FC0000, 0x78 - delta_ther); + } + } +} + +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_bandwidth bw = chan->band_width; + enum rtw89_band band = chan->band_type; + u32 clk = 0x0; + + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_sys_defs_tbl); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_80: + clk = 0x1; + break; + case RTW89_CHANNEL_WIDTH_80_80: + case RTW89_CHANNEL_WIDTH_160: + clk = 0x2; + break; + default: + break; + } + + if (path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ADC_CLK, + B_P0_TSSI_ADC_CLK, clk); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_sys_defs_2g_a_tbl, + &rtw8852c_tssi_sys_defs_5g_a_tbl); + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ADC_CLK, + B_P1_TSSI_ADC_CLK, clk); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_sys_defs_2g_b_tbl, + &rtw8852c_tssi_sys_defs_5g_b_tbl); + } +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl, + &rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, + &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (path == RF_PATH_A) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_a_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_dck_defs_2g_a_tbl, + &rtw8852c_tssi_dck_defs_5g_a_tbl); + } else { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_b_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_dck_defs_2g_b_tbl, + &rtw8852c_tssi_dck_defs_5g_b_tbl); + } +} + +static void _tssi_set_bbgain_split(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_set_bbgain_split_a_tbl, + &rtw8852c_tssi_set_bbgain_split_b_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ +#define RTW8852C_TSSI_GET_VAL(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + const struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 subband = chan->subband_type; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + if (!trk) + trk = &rtw89_8852c_trk_cfg; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0]; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2]; + break; + case RTW89_CH_6G_BAND_IDX0: + case RTW89_CH_6G_BAND_IDX1: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][0]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][0]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][0]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][0]; + break; + case RTW89_CH_6G_BAND_IDX2: + case RTW89_CH_6G_BAND_IDX3: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][1]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][1]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][1]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][1]; + break; + case RTW89_CH_6G_BAND_IDX4: + case RTW89_CH_6G_BAND_IDX5: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][2]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][2]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][2]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][2]; + break; + case RTW89_CH_6G_BAND_IDX6: + case RTW89_CH_6G_BAND_IDX7: + thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][3]; + thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][3]; + thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][3]; + thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][3]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + + } else { + thermal = tssi_info->thermal[RF_PATH_B]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_b[i++] : + -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_b[i++] : + thm_up_b[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); + } +#undef RTW8852C_TSSI_GET_VAL +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + + if (path == RF_PATH_A) { + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl, + &rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl); + } else { + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl, + &rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl); + } +} + +static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, + const struct rtw89_chan *chan) +{ + enum rtw89_band band = chan->band_type; + const struct rtw89_rfk_tbl *tbl; + + if (path == RF_PATH_A) { + if (band == RTW89_BAND_2G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl; + else if (band == RTW89_BAND_6G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl; + else + tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl; + } else { + if (band == RTW89_BAND_2G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl; + else if (band == RTW89_BAND_6G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl; + else + tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl; + } + + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_slope_defs_a_tbl, + &rtw8852c_tssi_slope_defs_b_tbl); +} + +static void _tssi_run_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_run_slope_defs_a_tbl, + &rtw8852c_tssi_run_slope_defs_b_tbl); +} + +static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_track_defs_a_tbl, + &rtw8852c_tssi_track_defs_b_tbl); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl, + &rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl); +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + _tssi_set_track(rtwdev, phy, i); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); + + rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, + &rtw8852c_tssi_enable_defs_a_tbl, + &rtw8852c_tssi_enable_defs_b_tbl); + + tssi_info->base_thermal[i] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); + rtwdev->is_tssi_mode[i] = true; + } +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + if (i == RF_PATH_A) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_disable_defs_a_tbl); + rtwdev->is_tssi_mode[RF_PATH_A] = false; + } else if (i == RF_PATH_B) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_disable_defs_b_tbl); + rtwdev->is_tssi_mode[RF_PATH_B] = false; + } + } +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_6g_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 5: + return 0; + case 6 ... 8: + return TSSI_EXTRA_GROUP(0); + case 9 ... 13: + return 1; + case 14 ... 16: + return TSSI_EXTRA_GROUP(1); + case 17 ... 21: + return 2; + case 22 ... 24: + return TSSI_EXTRA_GROUP(2); + case 25 ... 29: + return 3; + case 33 ... 37: + return 4; + case 38 ... 40: + return TSSI_EXTRA_GROUP(4); + case 41 ... 45: + return 5; + case 46 ... 48: + return TSSI_EXTRA_GROUP(5); + case 49 ... 53: + return 6; + case 54 ... 56: + return TSSI_EXTRA_GROUP(6); + case 57 ... 61: + return 7; + case 65 ... 69: + return 8; + case 70 ... 72: + return TSSI_EXTRA_GROUP(8); + case 73 ... 77: + return 9; + case 78 ... 80: + return TSSI_EXTRA_GROUP(9); + case 81 ... 85: + return 10; + case 86 ... 88: + return TSSI_EXTRA_GROUP(10); + case 89 ... 93: + return 11; + case 97 ... 101: + return 12; + case 102 ... 104: + return TSSI_EXTRA_GROUP(12); + case 105 ... 109: + return 13; + case 110 ... 112: + return TSSI_EXTRA_GROUP(13); + case 113 ... 117: + return 14; + case 118 ... 120: + return TSSI_EXTRA_GROUP(14); + case 121 ... 125: + return 15; + case 129 ... 133: + return 16; + case 134 ... 136: + return TSSI_EXTRA_GROUP(16); + case 137 ... 141: + return 17; + case 142 ... 144: + return TSSI_EXTRA_GROUP(17); + case 145 ... 149: + return 18; + case 150 ... 152: + return TSSI_EXTRA_GROUP(18); + case 153 ... 157: + return 19; + case 161 ... 165: + return 20; + case 166 ... 168: + return TSSI_EXTRA_GROUP(20); + case 169 ... 173: + return 21; + case 174 ... 176: + return TSSI_EXTRA_GROUP(21); + case 177 ... 181: + return 22; + case 182 ... 184: + return TSSI_EXTRA_GROUP(22); + case 185 ... 189: + return 23; + case 193 ... 197: + return 24; + case 198 ... 200: + return TSSI_EXTRA_GROUP(24); + case 201 ... 205: + return 25; + case 206 ... 208: + return TSSI_EXTRA_GROUP(25); + case 209 ... 213: + return 26; + case 214 ... 216: + return TSSI_EXTRA_GROUP(26); + case 217 ... 221: + return 27; + case 225 ... 229: + return 28; + case 230 ... 232: + return TSSI_EXTRA_GROUP(28); + case 233 ... 237: + return 29; + case 238 ... 240: + return TSSI_EXTRA_GROUP(29); + case 241 ... 245: + return 30; + case 246 ... 248: + return TSSI_EXTRA_GROUP(30); + case 249 ... 253: + return 31; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 49 ... 51: + return TSSI_EXTRA_GROUP(2); + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 113 ... 115: + return TSSI_EXTRA_GROUP(4); + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static u32 _tssi_get_6g_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 13: + return 0; + case 14 ... 16: + return TSSI_EXTRA_GROUP(0); + case 17 ... 29: + return 1; + case 33 ... 45: + return 2; + case 46 ... 48: + return TSSI_EXTRA_GROUP(2); + case 49 ... 61: + return 3; + case 65 ... 77: + return 4; + case 78 ... 80: + return TSSI_EXTRA_GROUP(4); + case 81 ... 93: + return 5; + case 97 ... 109: + return 6; + case 110 ... 112: + return TSSI_EXTRA_GROUP(6); + case 113 ... 125: + return 7; + case 129 ... 141: + return 8; + case 142 ... 144: + return TSSI_EXTRA_GROUP(8); + case 145 ... 157: + return 9; + case 161 ... 173: + return 10; + case 174 ... 176: + return TSSI_EXTRA_GROUP(10); + case 177 ... 189: + return 11; + case 193 ... 205: + return 12; + case 206 ... 208: + return TSSI_EXTRA_GROUP(12); + case 209 ... 221: + return 13; + case 225 ... 237: + return 14; + case 238 ... 240: + return TSSI_EXTRA_GROUP(14); + case 241 ... 253: + return 15; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = chan->band_type; + u8 ch = chan->channel; + u32 gidx, gidx_1st, gidx_2nd; + s8 de_1st; + s8 de_2nd; + s8 val; + + if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + } else { + gidx = _tssi_get_6g_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_6g_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_6g_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_6g_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = chan->band_type; + u8 ch = chan->channel; + u32 tgidx, tgidx_1st, tgidx_2nd; + s8 tde_1st = 0; + s8 tde_2nd = 0; + s8 val; + + if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + } else { + tgidx = _tssi_get_6g_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim_6g[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim_6g[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim_6g[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, const struct rtw89_chan *chan) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = chan->channel; + u8 gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + _tssi_de_cck_long[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], + _TSSI_DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + _tssi_de_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], + _TSSI_DE_MASK)); + } +} + +static void rtw8852c_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path, const struct rtw89_chan *chan) +{ + static const u32 tssi_trk[2] = {0x5818, 0x7818}; + static const u32 tssi_en[2] = {0x5820, 0x7820}; + + if (en) { + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0); + rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x0); + if (rtwdev->dbcc_en && path == RF_PATH_B) + _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_1, chan); + else + _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_0, chan); + } else { + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1); + rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x1); + } +} + +void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx, + const struct rtw89_chan *chan) +{ + if (!rtwdev->dbcc_en) { + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A, chan); + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B, chan); + } else { + if (phy_idx == RTW89_PHY_0) + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A, chan); + else + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B, chan); + } +} + +static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool is_dav) +{ + u32 rf_reg18; + u32 reg_reg18_addr; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (is_dav) + reg_reg18_addr = RR_CFGCH; + else + reg_reg18_addr = RR_CFGCH_V1; + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK); + rf_reg18 &= ~RR_CFGCH_BW; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xd); + break; + case RTW89_CHANNEL_WIDTH_160: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_160M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb); + break; + default: + break; + } + + rtw89_write_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK, rf_reg18); +} + +static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + bool is_dav; + u8 kpath, path; + u32 tmp = 0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < 2; path++) { + if (!(kpath & BIT(path))) + continue; + + is_dav = true; + _bw_setting(rtwdev, path, bw, is_dav); + is_dav = false; + _bw_setting(rtwdev, path, bw, is_dav); + if (rtwdev->dbcc_en) + continue; + + if (path == RF_PATH_B && rtwdev->hal.cv == CHIP_CAV) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_APK, RR_APK_MOD, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK, tmp); + fsleep(100); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + } + } +} + +static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 central_ch, enum rtw89_band band, bool is_dav) +{ + u32 rf_reg18; + u32 reg_reg18_addr; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (is_dav) + reg_reg18_addr = 0x18; + else + reg_reg18_addr = 0x10018; + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK); + rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); + + switch (band) { + case RTW89_BAND_2G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_2G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_2G); + break; + case RTW89_BAND_5G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); + break; + case RTW89_BAND_6G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_6G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_6G); + break; + default: + break; + } + rtw89_write_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK, rf_reg18); + fsleep(100); +} + +static void _ctrl_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 central_ch, enum rtw89_band band) +{ + u8 kpath, path; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (band != RTW89_BAND_6G) { + if ((central_ch > 14 && central_ch < 36) || + (central_ch > 64 && central_ch < 100) || + (central_ch > 144 && central_ch < 149) || central_ch > 177) + return; + } else { + if (central_ch > 253 || central_ch == 2) + return; + } + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < 2; path++) { + if (kpath & BIT(path)) { + _ch_setting(rtwdev, path, central_ch, band, true); + _ch_setting(rtwdev, path, central_ch, band, false); + } + } +} + +static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw) +{ + u32 val; + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa); + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + val = 0x1b; + break; + case RTW89_CHANNEL_WIDTH_40: + val = 0x13; + break; + case RTW89_CHANNEL_WIDTH_80: + val = 0xb; + break; + case RTW89_CHANNEL_WIDTH_160: + default: + val = 0x3; + break; + } + + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); +} + +static void _set_tia_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw) +{ + if (bw == RTW89_CHANNEL_WIDTH_160) + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); + else + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x2); +} + +static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + u8 kpath; + u8 path; + + kpath = _kpath(rtwdev, phy); + for (path = 0; path < 2; path++) { + if (!(kpath & BIT(path))) + continue; + + _set_rxbb_bw(rtwdev, path, bw); + _set_tia_bw(rtwdev, path, bw); + } +} + +static void _lck_keep_thermal(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + lck->thermal[path] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d thermal=0x%x", path, lck->thermal[path]); + } +} + +static void _lck(struct rtw89_dev *rtwdev) +{ + u32 tmp18[2]; + int path = rtwdev->dbcc_en ? 2 : 1; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "[LCK] DO LCK\n"); + + tmp18[0] = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + tmp18[1] = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK); + + for (i = 0; i < path; i++) { + rtw89_write_rf(rtwdev, i, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + rtw89_write_rf(rtwdev, i, RR_CFGCH, RFREG_MASK, tmp18[i]); + rtw89_write_rf(rtwdev, i, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + } + + _lck_keep_thermal(rtwdev); +} + +#define RTW8852C_LCK_TH 8 + +void rtw8852c_lck_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + u8 cur_thermal; + int delta; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + cur_thermal = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + delta = abs((int)cur_thermal - lck->thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d current thermal=0x%x delta=0x%x\n", + path, cur_thermal, delta); + + if (delta >= RTW8852C_LCK_TH) { + _lck(rtwdev); + return; + } + } +} + +void rtw8852c_lck_init(struct rtw89_dev *rtwdev) +{ + _lck_keep_thermal(rtwdev); +} + +static +void rtw8852c_ctrl_bw_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 central_ch, enum rtw89_band band, + enum rtw89_bandwidth bw) +{ + _ctrl_ch(rtwdev, phy, central_ch, band); + _ctrl_bw(rtwdev, phy, bw); + _rxbb_bw(rtwdev, phy, bw); +} + +void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, + chan->band_type, + chan->band_width); +} + +void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {}; + const struct rtw89_chan *chan; + enum rtw89_entity_mode mode; + u8 chan_idx; + u8 idx; + + mode = rtw89_get_entity_mode(rtwdev); + switch (mode) { + case RTW89_ENTITY_MODE_MCC_PREPARE: + chan_idx = RTW89_CHANCTX_1; + break; + default: + chan_idx = RTW89_CHANCTX_0; + break; + } + + chan = rtw89_chan_get(rtwdev, chan_idx); + + for (idx = 0; idx < ARRAY_SIZE(desc); idx++) { + struct rtw89_rfk_chan_desc *p = &desc[idx]; + + p->ch = rfk_mcc->ch[idx]; + + p->has_band = true; + p->band = rfk_mcc->band[idx]; + } + + idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[idx] = chan->channel; + rfk_mcc->band[idx] = chan->band_type; + rfk_mcc->table_idx = idx; +} + +void rtw8852c_rck(struct rtw89_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < 2; path++) + _rck(rtwdev, path); +} + +void rtw8852c_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); + _dac_cal(rtwdev, false, chanctx_idx); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); +} + +void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + _iqk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + +#define RXDCK_VER_8852C 0xe + +static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + bool is_afe, u8 retry_limit) +{ + struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; + u8 path, kpath; + u32 rf_reg5; + bool is_fail; + u8 rek_cnt; + + kpath = _kpath(rtwdev, phy); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", + RXDCK_VER_8852C, rtwdev->hal.cv); + + for (path = 0; path < 2; path++) { + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + if (!(kpath & BIT(path))) + continue; + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x1); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_LO_SEL, rtwdev->dbcc_en); + + for (rek_cnt = 0; rek_cnt < retry_limit; rek_cnt++) { + _set_rx_dck(rtwdev, phy, path, is_afe); + + /* To reduce IO of dck_rek_check(), the last try is seen + * as failure always, and then do recovery procedure. + */ + if (rek_cnt == retry_limit - 1) { + _rx_dck_recover(rtwdev, path); + break; + } + + is_fail = _rx_dck_rek_check(rtwdev, path); + if (!is_fail) + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] rek_cnt[%d]=%d", + path, rek_cnt); + + rx_dck->thermal[path] = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x0); + } +} + +void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) +{ + _rx_dck(rtwdev, phy, is_afe, 1); +} + +#define RTW8852C_RX_DCK_TH 12 + +void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev) +{ + enum rtw89_chanctx_idx chanctx_idx = RTW89_CHANCTX_0; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; + enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + u8 dck_channel; + u8 cur_thermal; + u32 tx_en; + int delta; + int path; + + if (chan->band_type == RTW89_BAND_2G) + return; + + if (rtwdev->scanning) + return; + + for (path = 0; path < RF_PATH_NUM_8852C; path++) { + cur_thermal = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + delta = abs((int)cur_thermal - rx_dck->thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n", + path, cur_thermal, delta); + + if (delta >= RTW8852C_RX_DCK_TH) + goto trigger_rx_dck; + } + + return; + +trigger_rx_dck: + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + + for (path = 0; path < RF_PATH_NUM_8852C; path++) { + dck_channel = _rx_dck_channel_calc(rtwdev, chan); + _ctrl_ch(rtwdev, RTW89_PHY_0, dck_channel, chan->band_type); + } + + _rx_dck(rtwdev, RTW89_PHY_0, false, 20); + + for (path = 0; path < RF_PATH_NUM_8852C; path++) + _ctrl_ch(rtwdev, RTW89_PHY_0, chan->channel, chan->band_type); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); +} + +void rtw8852c_dpk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + dpk->is_dpk_enable = true; + dpk->is_dpk_reload_en = false; +} + +void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _dpk(rtwdev, phy_idx, false, chanctx_idx); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8852c_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + +void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + _tssi_disable(rtwdev, phy); + + for (i = path; i < path_max; i++) { + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i, chan); + _tssi_set_bbgain_split(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_set_aligk_default(rtwdev, phy, i, chan); + _tssi_set_slope(rtwdev, phy, i); + _tssi_run_slope(rtwdev, phy, i); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", + __func__, phy); + + if (!rtwdev->is_tssi_mode[RF_PATH_A]) + return; + if (!rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + _tssi_disable(rtwdev, phy); + + for (i = path; i < path_max; i++) { + _tssi_set_sys(rtwdev, phy, i, chan); + _tssi_set_dck(rtwdev, phy, i, chan); + _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); + _tssi_slope_cal_org(rtwdev, phy, i, chan); + _tssi_set_aligk_default(rtwdev, phy, i, chan); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy, chan); +} + +static void rtw8852c_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 i; + + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (enable) { + /* SCAN_START */ + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_A] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, + B_TXAGC_BB); + if (tssi_info->default_txagc_offset[RF_PATH_A]) + break; + } + } + + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_B] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, + B_TXAGC_BB_S1); + if (tssi_info->default_txagc_offset[RF_PATH_B]) + break; + } + } + } else { + /* SCAN_END */ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_A]); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_B]); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); + } +} + +void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, + bool scan_start, enum rtw89_phy_idx phy_idx) +{ + if (scan_start) + rtw8852c_tssi_default_txagc(rtwdev, phy_idx, true); + else + rtw8852c_tssi_default_txagc(rtwdev, phy_idx, false); +} + +void rtw8852c_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 path; + + switch (state) { + case RTW89_CHANCTX_STATE_MCC_START: + dpk->is_dpk_enable = false; + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) + _dpk_onoff(rtwdev, path, false); + break; + case RTW89_CHANCTX_STATE_MCC_STOP: + dpk->is_dpk_enable = true; + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) + _dpk_onoff(rtwdev, path, false); + rtw8852c_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); + break; + default: + break; + } +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h new file mode 100644 index 000000000..306dd0a0b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_RFK_H__ +#define __RTW89_8852C_RFK_H__ + +#include "core.h" + +void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); +void rtw8852c_rck(struct rtw89_dev *rtwdev); +void rtw8852c_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx); +void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool is_afe); +void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev); +void rtw8852c_dpk_init(struct rtw89_dev *rtwdev); +void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852c_dpk_track(struct rtw89_dev *rtwdev); +void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_chanctx_idx chanctx_idx); +void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan); +void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx, + const struct rtw89_chan *chan); +void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx); +void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +void rtw8852c_lck_init(struct rtw89_dev *rtwdev); +void rtw8852c_lck_track(struct rtw89_dev *rtwdev); +void rtw8852c_rfk_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c new file mode 100644 index 000000000..e5b0c2a68 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c @@ -0,0 +1,781 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "rtw8852c_rfk_table.h" + +static const struct rtw89_reg5_def rtw8852c_dack_reload_defs[] = { + RTW89_DECL_RFK_WM(0xc004, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reload_defs); + +static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_a[] = { + RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x0), + RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_a); + +static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_b[] = { + RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x0), + RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_b); + +static const struct rtw89_reg5_def rtw8852c_dack_defs_s0[] = { + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xc004, 0xfff00000, 0x30), + RTW89_DECL_RFK_WM(0xc024, 0xfff00000, 0x30), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s0); + +static const struct rtw89_reg5_def rtw8852c_dack_defs_s1[] = { + RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xc104, 0xfff00000, 0x30), + RTW89_DECL_RFK_WM(0xc124, 0xfff00000, 0x30), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s1); + +static const struct rtw89_reg5_def rtw8852c_drck_defs[] = { + RTW89_DECL_RFK_WM(0xc0c4, BIT(6), 0x0), + RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x1), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_drck_defs); + +static const struct rtw89_reg5_def rtw8852c_iqk_rxk_cfg_defs[] = { + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_rxk_cfg_defs); + +static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_a[] = { + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_a); + +static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_b[] = { + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00200000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x7670, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x32a0, 0x000ff000, 0x00), + RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_B, 0x10005, 0x00001, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_b); + +static const struct rtw89_reg5_def rtw8852c_read_rxsram_pre_defs[] = { + RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x1), + RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x1), + RTW89_DECL_RFK_WM(0x80d4, MASKDWORD, 0x00020000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_pre_defs); + +static const struct rtw89_reg5_def rtw8852c_read_rxsram_post_defs[] = { + RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x0), + RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_post_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order0_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x0), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x2), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order0_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order1_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x1), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x1), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order1_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order2_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x2), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x0), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order2_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order3_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x3), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x3), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order3_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_on_defs[] = { + RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000080), + RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x807f030a), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_on_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_off_defs[] = { + RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x80000000), + RTW89_DECL_RFK_WM(0x80f4, BIT(18), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_off_defs); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), + RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1313), + RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x13), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x00410041), + RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x0041), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_defs_a[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x026d000), + RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c18e8), + RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280), + RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0xc00), + RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000), + RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_defs_b[] = { + RTW89_DECL_RFK_WM(0x766c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x026d000), + RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c18e8), + RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x3dc80280), + RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00000080), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0xc00), + RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000), + RTW89_DECL_RFK_WM(0x78f8, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = { + RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x0), + RTW89_DECL_RFK_WM(0x58c8, 0x00000fff, 0x0), + RTW89_DECL_RFK_WM(0x58c8, 0x00fff000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_b[] = { + RTW89_DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x0), + RTW89_DECL_RFK_WM(0x78c8, 0x00000fff, 0x0), + RTW89_DECL_RFK_WM(0x78c8, 0x00fff000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x1af), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x1af), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x0003c000, 0xb), + RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x6), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x00001000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x0003c000, 0xb), + RTW89_DECL_RFK_WM(0x7814, 0x00002000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x003c0000, 0x6), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_a[] = { + RTW89_DECL_RFK_WM(0x5818, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x58d4, 0xf0000000, 0x7), + RTW89_DECL_RFK_WM(0x58f0, 0x000c0000, 0x1), + RTW89_DECL_RFK_WM(0x58f0, 0xfff00000, 0x400), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_b[] = { + RTW89_DECL_RFK_WM(0x7818, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x78d4, 0xf0000000, 0x7), + RTW89_DECL_RFK_WM(0x78f0, 0x000c0000, 0x1), + RTW89_DECL_RFK_WM(0x78f0, 0xfff00000, 0x400), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x0808081e), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x081d), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0204020), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x020), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08081e21), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x1d23), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2721), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3b8), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3d2), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x042), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x06b), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x3bc), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3d6), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x03e), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x06b), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x2d2721), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x3c0), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3da), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x002), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x071), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x3c8), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e2), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x00c), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x071), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x07d), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x07d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x07d), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x07d), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x080), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x080), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x080), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x080), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x0f), + RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280), + RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00), + RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00), + RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a), + RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28), + RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76), + RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x0f), + RTW89_DECL_RFK_WM(0x781c, 0x000003ff, 0x280), + RTW89_DECL_RFK_WM(0x781c, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x78b8, 0x007f0000, 0x00), + RTW89_DECL_RFK_WM(0x78b8, 0x7f000000, 0x00), + RTW89_DECL_RFK_WM(0x78b4, 0x7f000000, 0x0a), + RTW89_DECL_RFK_WM(0x78b8, 0x0000007f, 0x28), + RTW89_DECL_RFK_WM(0x78b8, 0x00007f00, 0x76), + RTW89_DECL_RFK_WM(0x7810, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7834, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7838, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7838, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7854, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7854, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7858, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7858, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7824, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7824, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7828, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7828, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x782c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x782c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7830, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7830, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x783c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x783c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7840, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7840, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7844, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7844, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7848, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7848, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x784c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x784c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7850, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7850, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x785c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x785c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7860, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7860, 0x003ff000, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff), + RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080), + RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x0), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x7864, 0x000003ff, 0x1ff), + RTW89_DECL_RFK_WM(0x7864, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x7820, 0x00000fff, 0x080), + RTW89_DECL_RFK_WM(0x7814, 0x01000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_b[] = { + RTW89_DECL_RFK_WM(0x78e4, 0x00003800, 0x1), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x78e4, 0x00008000, 0x1), + RTW89_DECL_RFK_WM(0x78e4, 0x000f0000, 0x0), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1), + RTW89_DECL_RFK_WRF(0x0, 0x10055, 0x00080, 0x1), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_b[] = { + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1), + RTW89_DECL_RFK_WRF(0x1, 0x10055, 0x00080, 0x1), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_b); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h new file mode 100644 index 000000000..953a960ef --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_RFK_TABLE_H__ +#define __RTW89_8852C_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8852c_dack_reload_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s0_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s1_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_drck_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_rxk_cfg_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_pre_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_post_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order0_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order1_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order2_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order3_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_on_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_off_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_b_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c new file mode 100644 index 000000000..c5ede63e7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c @@ -0,0 +1,57160 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852c_table.h" + +static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0xF0FF0000, 0x00000000}, + {0xF03300FF, 0x00000001}, + {0xF03400FF, 0x00000002}, + {0xF03500FF, 0x00000003}, + {0xF03600FF, 0x00000004}, + {0x70C, 0x00000020}, + {0x704, 0x601E0100}, + {0x4000, 0x00000000}, + {0x4004, 0xCA014000}, + {0x4008, 0xC751D4F0}, + {0x400C, 0x44511475}, + {0x4010, 0x00000000}, + {0x4014, 0x00000000}, + {0x44AC, 0x01F60380}, + {0x4018, 0x4F4C4B4B}, + {0x401C, 0x494A4E52}, + {0x4020, 0x4D504E4B}, + {0x4024, 0x4F4C4949}, + {0x4028, 0x49484C50}, + {0x402C, 0x4C50504C}, + {0x4030, 0x54544D4A}, + {0x4034, 0x504B5654}, + {0x4038, 0x6A6C605A}, + {0x403C, 0x48484848}, + {0x4040, 0x48483D47}, + {0x4044, 0x3D474848}, + {0x4048, 0x51484848}, + {0x404C, 0x4A4A404F}, + {0x4050, 0x514F4C4A}, + {0x4054, 0x524E4A4A}, + {0x4058, 0x4A4A5154}, + {0x405C, 0x53555554}, + {0x4060, 0x45454545}, + {0x4064, 0x45454144}, + {0x4068, 0x40434445}, + {0x406C, 0x44454545}, + {0x4070, 0x44444043}, + {0x4074, 0x42434444}, + {0x4078, 0x46454444}, + {0x407C, 0x44444843}, + {0x4080, 0x4B4E4A47}, + {0x4084, 0x514D4A49}, + {0x4088, 0x4A495454}, + {0x408C, 0x5454514D}, + {0x4090, 0x524E4B4A}, + {0x4094, 0x4C4B5455}, + {0x4098, 0x55565550}, + {0x409C, 0x5959504D}, + {0x40A0, 0x544E5D5A}, + {0x40A4, 0x7975665F}, + {0x40A8, 0x48484848}, + {0x40AC, 0x48483D47}, + {0x40B0, 0x3D474848}, + {0x40B4, 0x48484848}, + {0x40B8, 0x48483E48}, + {0x40BC, 0x3E4A4A49}, + {0x40C0, 0x514E4948}, + {0x40C4, 0x4A49404F}, + {0x40C8, 0x42525555}, + {0x40CC, 0x47474747}, + {0x40D0, 0x47474747}, + {0x40D4, 0x47474747}, + {0x40D8, 0x48484848}, + {0x40DC, 0x48474848}, + {0x40E0, 0x4A484848}, + {0x40E4, 0x49484847}, + {0x40E8, 0x4847524D}, + {0x40EC, 0x55544F4B}, + {0x40F0, 0x00000000}, + {0x4604, 0x4C4C4D4E}, + {0x4608, 0x3D3D6A56}, + {0x460C, 0x53515140}, + {0x4610, 0x42404041}, + {0x4614, 0x54544B48}, + {0x4618, 0x795D5554}, + {0x461C, 0x3E3E3D3D}, + {0x4620, 0x47474240}, + {0x4624, 0x55524A48}, + {0x4ED4, 0x00000000}, + {0x40F4, 0x00000006}, + {0x4628, 0x00000000}, + {0x4E9C, 0x26663333}, + {0x4EA0, 0x6EDA4148}, + {0x4EA4, 0x599A0000}, + {0x4EA8, 0x40000000}, + {0x4ED0, 0x00000001}, + {0x40F8, 0x00000000}, + {0x40FC, 0x8C30C30C}, + {0x4100, 0x4C30C30C}, + {0x4104, 0x0C30C30C}, + {0x4108, 0x0C30C30C}, + {0x410C, 0x0C30C30C}, + {0x4110, 0x0C30C30C}, + {0x4114, 0x28A28A28}, + {0x4118, 0x28A28A28}, + {0x411C, 0x28A28A28}, + {0x4120, 0x28A28A28}, + {0x4124, 0x28A28A28}, + {0x4128, 0x28A28A28}, + {0x412C, 0x06666666}, + {0x4130, 0x33333333}, + {0x4134, 0x33333333}, + {0x4138, 0x33333333}, + {0x413C, 0x00000031}, + {0x462C, 0x0C30C30C}, + {0x4630, 0x0C30C30C}, + {0x4634, 0x28A28A28}, + {0x4638, 0x28A28A28}, + {0x463C, 0x33333333}, + {0x4640, 0x00000033}, + {0x4140, 0x5100600A}, + {0x4144, 0x18363113}, + {0x4148, 0x1D976DDC}, + {0x414C, 0x1C072DD7}, + {0x4150, 0x1127CDF4}, + {0x4154, 0x1E37BDF1}, + {0x4158, 0x1FB7F1D6}, + {0x415C, 0x1EA7DDF9}, + {0x4160, 0x1FE445DD}, + {0x4164, 0x1F97F1FE}, + {0x4168, 0x1FF781ED}, + {0x416C, 0x1FA7F5FE}, + {0x4170, 0x1E07B913}, + {0x4174, 0x1FD7FDFF}, + {0x4178, 0x1E17B9FA}, + {0x417C, 0x19A66914}, + {0x4180, 0x10F65598}, + {0x4184, 0x14A5A111}, + {0x4188, 0x1D3765DB}, + {0x418C, 0x17C685CA}, + {0x4190, 0x1107C5F3}, + {0x4194, 0x1B5785EB}, + {0x4198, 0x1F97ED8F}, + {0x419C, 0x1BC7A5F3}, + {0x41A0, 0x1FE43595}, + {0x41A4, 0x1EB7D9FC}, + {0x41A8, 0x1FE65DBE}, + {0x41AC, 0x1EC7D9FC}, + {0x41B0, 0x1976FCFF}, + {0x41B4, 0x1F77F5FF}, + {0x41B8, 0x1976FDEC}, + {0x41BC, 0x198664EF}, + {0x41C0, 0x11062D93}, + {0x41C4, 0x10C4E910}, + {0x41C8, 0x1CA759DB}, + {0x41CC, 0x1335A9B5}, + {0x41D0, 0x1097B9F3}, + {0x41D4, 0x17B72DE1}, + {0x41D8, 0x1F67ED42}, + {0x41DC, 0x18074DE9}, + {0x41E0, 0x1FD40547}, + {0x41E4, 0x1D57ADF9}, + {0x41E8, 0x1FE52182}, + {0x41EC, 0x1D67B1F9}, + {0x41F0, 0x14860CE1}, + {0x41F4, 0x1EC7E9FE}, + {0x41F8, 0x14860DD6}, + {0x41FC, 0x195664C7}, + {0x4200, 0x0005E58A}, + {0x4204, 0x00000000}, + {0x4208, 0x00000000}, + {0x420C, 0x7A000000}, + {0x4210, 0x0F9F3D7A}, + {0x4214, 0x0040817C}, + {0x4218, 0x00E10204}, + {0x421C, 0x257D94CD}, + {0x4220, 0x0802DB6D}, + {0x4224, 0x00000200}, + {0x4228, 0x04688000}, + {0x4644, 0x00000000}, + {0x4648, 0x00000000}, + {0x464C, 0x00000000}, + {0x4650, 0x00000020}, + {0x4ECC, 0x00000001}, + {0x422C, 0x0060B002}, + {0x4230, 0x9A8249A8}, + {0x4234, 0x26A1469E}, + {0x4238, 0x2099A824}, + {0x423C, 0x2359461C}, + {0x4240, 0x1631A675}, + {0x4244, 0x2C6B1D63}, + {0x4248, 0x0000000E}, + {0x424C, 0x00000001}, + {0x4250, 0x00000001}, + {0x4254, 0x00000000}, + {0x4258, 0x00000000}, + {0x425C, 0x00000000}, + {0x4260, 0x01E0000C}, + {0x4654, 0x00000000}, + {0x4658, 0x00000000}, + {0x465C, 0x0000001E}, + {0x4E74, 0x00000000}, + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, + {0x46C0, 0x00000000}, + {0x4270, 0x00D6135C}, + {0x46C4, 0x00000033}, + {0x4274, 0x00000000}, + {0x4278, 0x00000000}, + {0x427C, 0x00000000}, + {0x4280, 0x00000000}, + {0x4284, 0x00000000}, + {0x4288, 0x00000000}, + {0x46D8, 0x00000000}, + {0x46DC, 0x00000000}, + {0x46E0, 0x00000000}, + {0x46E4, 0x00000000}, + {0x46E8, 0x00000000}, + {0x428C, 0x00000000}, + {0x4290, 0x00000000}, + {0x4294, 0x00000000}, + {0x4298, 0x84026000}, + {0x429C, 0x0051AC20}, + {0x46EC, 0x1020C040}, + {0x46F0, 0xB8BEBEB8}, + {0x46F4, 0x021102BE}, + {0x46F8, 0x14221142}, + {0x46FC, 0x18C4098C}, + {0x4700, 0x00021084}, + {0x42A0, 0x02024008}, + {0x42A4, 0x00000000}, + {0x42A8, 0x00000000}, + {0x42AC, 0x22CE803C}, + {0x42B0, 0x32000000}, + {0x42B4, 0x996FD67D}, + {0x42B8, 0xBD67D67D}, + {0x42BC, 0x7D67D65B}, + {0x42C0, 0x28029F59}, + {0x42C4, 0x00280280}, + {0x4704, 0x00000000}, + {0x42C8, 0x00000000}, + {0x42CC, 0x00000000}, + {0x42D0, 0x00000003}, + {0x4708, 0x00280000}, + {0x42D4, 0x00000001}, + {0x42D8, 0x61861800}, + {0x42DC, 0x830C30C3}, + {0x42E0, 0xC30C30C3}, + {0x42E4, 0x830C30C3}, + {0x42E8, 0x451450C3}, + {0x42EC, 0x05145145}, + {0x42F0, 0x05145145}, + {0x42F4, 0x05145145}, + {0x42F8, 0x03207145}, + {0x42FC, 0x041C32C6}, + {0x4300, 0x031C5247}, + {0x4304, 0x030C5143}, + {0x4308, 0x030C30C3}, + {0x430C, 0x0F3CF3C3}, + {0x4310, 0x0F3CF3CF}, + {0x4314, 0x0F3CF3CF}, + {0x4318, 0x0F3CF3CF}, + {0x431C, 0x0F3CF3CF}, + {0x4320, 0x030C10C3}, + {0x4324, 0x051430C3}, + {0x4328, 0x051490CB}, + {0x432C, 0x030C70D1}, + {0x4330, 0x050C50C7}, + {0x4334, 0x051492CB}, + {0x4338, 0x05145145}, + {0x433C, 0x05145145}, + {0x4340, 0x05145145}, + {0x4344, 0x05145145}, + {0x4348, 0x090CD243}, + {0x434C, 0x0918A1C5}, + {0x4350, 0x071C3143}, + {0x4354, 0x071431C3}, + {0x4358, 0x0F3CF1C5}, + {0x435C, 0x0F3CF3CF}, + {0x4360, 0x0F3CF3CF}, + {0x4364, 0x0F3CF3CF}, + {0x4368, 0x0F3CF3CF}, + {0x436C, 0x090C91CF}, + {0x4370, 0x11243143}, + {0x4374, 0x9777A777}, + {0x4378, 0xBB7BAC95}, + {0x437C, 0xB667B889}, + {0x4380, 0x7B9B8899}, + {0x4384, 0x7A5567C8}, + {0x4388, 0x2278CCCC}, + {0x438C, 0x7C222222}, + {0x4390, 0x0000049B}, + {0x470C, 0x00000888}, + {0x4EB4, 0x00000002}, + {0x4394, 0x001CCCCC}, + {0x4710, 0xCCCCCAAC}, + {0x4714, 0x0000AACC}, + {0x4398, 0x00000000}, + {0x439C, 0x00000008}, + {0x49A4, 0x00000000}, + {0x43A0, 0x00000000}, + {0x43A4, 0x00000000}, + {0x43A8, 0x00000000}, + {0x43AC, 0x10000000}, + {0x43B0, 0x00401001}, + {0x43B4, 0x00061003}, + {0x4718, 0x00003000}, + {0x43B8, 0x000024D8}, + {0x43BC, 0x00000000}, + {0x43C0, 0x10000020}, + {0x43C4, 0x20000200}, + {0x43C8, 0x00000000}, + {0x43CC, 0x04000000}, + {0x43D0, 0x44000100}, + {0x43D4, 0x60804060}, + {0x43D8, 0x44204210}, + {0x43DC, 0x82108082}, + {0x43E0, 0x82108402}, + {0x43E4, 0xC8082108}, + {0x43E8, 0xC8202084}, + {0x43EC, 0x44208208}, + {0x43F0, 0x84108204}, + {0x43F4, 0xD0108104}, + {0x43F8, 0xF8210108}, + {0x43FC, 0x6431E930}, + {0x4400, 0x02109468}, + {0x4404, 0x10C61C22}, + {0x4408, 0x02109469}, + {0x440C, 0x10C61C22}, + {0x4410, 0x00041049}, + {0x471C, 0x0B02C080}, + {0x4414, 0x00000000}, + {0x4418, 0x00000000}, + {0x441C, 0x80000000}, + {0x4420, 0xB0200000}, + {0x4424, 0x00001FF0}, + {0x4780, 0xEC000000}, + {0x4784, 0x8C400020}, + {0x4964, 0x51089104}, + {0x4968, 0x88448844}, + {0x496C, 0x07000044}, + {0x4E4C, 0x00000000}, + {0x4428, 0x00000000}, + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, + {0x4438, 0x59096398}, + {0x443C, 0x398668A0}, + {0x4440, 0x6C100808}, + {0x4444, 0x4A145344}, + {0x4448, 0x0C5B008F}, + {0x444C, 0x6E30498A}, + {0x4450, 0x656E371B}, + {0x4454, 0x00000F53}, + {0x49A8, 0x68120000}, + {0x49AC, 0xDA0681E0}, + {0x49BC, 0x14060180}, + {0x49D8, 0x600603FF}, + {0x49DC, 0x3C502000}, + {0x49E0, 0x2C580050}, + {0x49E4, 0x45B055EF}, + {0x49E8, 0x00000290}, + {0x4A0C, 0x00000001}, + {0x4A28, 0x0DAC1B58}, + {0x4A2C, 0x0000001E}, + {0x4E50, 0x16878003}, + {0x4E54, 0x0F00F078}, + {0x4E58, 0x03C1E0B4}, + {0x4E5C, 0x78584830}, + {0x4E60, 0x88C0140C}, + {0x4E64, 0x90302C24}, + {0x4E68, 0x0F84A00A}, + {0x4E6C, 0x00000011}, + {0x4E78, 0x00003039}, + {0x4E7C, 0x0000D431}, + {0x4E80, 0x00008235}, + {0x4E84, 0x00000000}, + {0x4E88, 0x000056CE}, + {0x4E8C, 0x00002B67}, + {0x4E90, 0x00000237}, + {0x4EB8, 0x00004624}, + {0x4A30, 0x00000000}, + {0x4458, 0x00000000}, + {0x445C, 0x4801442E}, + {0x4460, 0x0051A0B8}, + {0x4A34, 0x0000011F}, + {0x4EBC, 0x00000000}, + {0x4A38, 0x0000011F}, + {0x4EC0, 0x00000000}, + {0x4464, 0x00000000}, + {0x4468, 0x00000000}, + {0x446C, 0x00000000}, + {0x4470, 0x00000000}, + {0x4474, 0x00000000}, + {0x4478, 0x00000000}, + {0x447C, 0x00000000}, + {0x4480, 0x2A0AA040}, + {0x4484, 0x0A886926}, + {0x4488, 0x00000004}, + {0x4A3C, 0x00002B1C}, + {0x448C, 0x00000000}, + {0x4490, 0x88000000}, + {0x4494, 0x10000000}, + {0x4498, 0xE0000000}, + {0x4A08, 0x00000FE6}, + {0x4A40, 0x00000000}, + {0x4A44, 0x00000000}, + {0x4A48, 0x00000000}, + {0x4A4C, 0x00000000}, + {0x4A50, 0x00000000}, + {0x4A54, 0x00000000}, + {0x449C, 0x00000019}, + {0x44A0, 0x02B2E394}, + {0x44A4, 0x00000400}, + {0x4A58, 0x14285208}, + {0x4A84, 0x02850A14}, + {0x4A88, 0x048D0A14}, + {0x4A8C, 0x01123401}, + {0x4A90, 0x34011234}, + {0x4A94, 0x23450112}, + {0x4A98, 0x45123451}, + {0x4AAC, 0x12345123}, + {0x4AB0, 0x00000000}, + {0x44A8, 0x00000001}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4ED80C81}, + {0x4534, 0x00001808}, + {0x4538, 0x000000FF}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x40600033}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x20000000}, + {0x4570, 0x04AAA407}, + {0x4574, 0x0001A2B4}, + {0x4578, 0x0002024B}, + {0x457C, 0x00200000}, + {0x4580, 0x00001B40}, + {0x4584, 0x00000000}, + {0x4588, 0x000000C8}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x00000000}, + {0x4598, 0x00000001}, + {0x459C, 0x0003FE00}, + {0x45A0, 0x00000000}, + {0x45A4, 0x00000000}, + {0x45A8, 0xC00002C0}, + {0x45AC, 0x78028000}, + {0x45B0, 0x80000048}, + {0x45B4, 0x00098800}, + {0x45B8, 0x00200002}, + {0x4AB4, 0x00000000}, + {0x4AB8, 0x00000000}, + {0x4ABC, 0x00000000}, + {0x4AC0, 0x00000000}, + {0x4AC4, 0x00000000}, + {0x4AC8, 0x00000000}, + {0x4AF4, 0x00000000}, + {0x4AF8, 0x00000000}, + {0x4AFC, 0x00000000}, + {0x4B00, 0x00000000}, + {0x4B04, 0x00000000}, + {0x4B08, 0x00000000}, + {0x4B0C, 0x00000000}, + {0x4B10, 0x00000000}, + {0x4B14, 0x00000000}, + {0x4B18, 0xB0000000}, + {0x4B1C, 0x00000000}, + {0x4B20, 0x00000000}, + {0x4B24, 0x00000000}, + {0x4B28, 0x00000000}, + {0x4B2C, 0x00000000}, + {0x4B30, 0x00000000}, + {0x4B34, 0x00000000}, + {0x4B38, 0x00000000}, + {0x4B3C, 0x00000000}, + {0x4B40, 0x00000000}, + {0x45BC, 0x06748790}, + {0x45C0, 0x80000000}, + {0x45C4, 0x00000000}, + {0x45C8, 0x00000000}, + {0x45CC, 0x00558670}, + {0x45D0, 0x002883F0}, + {0x45D4, 0x00090120}, + {0x45D8, 0x00000000}, + {0x4B44, 0x00000100}, + {0x4B48, 0xA6DBC4B1}, + {0x4B4C, 0x64F624C3}, + {0x4B50, 0x00D4EF15}, + {0x49B0, 0x11110F0A}, + {0x49B4, 0x00000003}, + {0x49B8, 0x0000000A}, + {0x4B54, 0xBE9007FF}, + {0x4B58, 0x00000001}, + {0x49C0, 0x00000007}, + {0x49C4, 0x000003D9}, + {0x4A10, 0x00000001}, + {0x49C8, 0x002B1CB0}, + {0x4A00, 0xC0000000}, + {0x4A04, 0x00001000}, + {0x4B5C, 0x00000005}, + {0x4A18, 0x00000007}, + {0x4B60, 0x00000024}, + {0x49CC, 0x00000001}, + {0x49D0, 0x00000010}, + {0x49D4, 0x00000001}, + {0x4B64, 0x927FBFBF}, + {0x4B68, 0x1D07BDD0}, + {0x4B6C, 0x318A4DEF}, + {0x4B70, 0x158C5318}, + {0x4B74, 0x18C5318C}, + {0x4B78, 0x4E7394EC}, + {0x4B7C, 0xD9081CE5}, + {0x4B80, 0x00000001}, + {0x49EC, 0x00000001}, + {0x4B84, 0x00000000}, + {0x4B88, 0x00000000}, + {0x4B8C, 0x00000000}, + {0x4B90, 0x00000000}, + {0x4B94, 0x00000000}, + {0x4B98, 0x00000000}, + {0x4B9C, 0x00000000}, + {0x4BA0, 0x00000000}, + {0x4BA4, 0x00EA99A2}, + {0x49F8, 0x0000C4C3}, + {0x4A1C, 0x00020800}, + {0x4A20, 0x0002CC00}, + {0x4BA8, 0x002B6456}, + {0x45E0, 0x00000000}, + {0x45E4, 0x00000000}, + {0x45E8, 0x00C8E1E1}, + {0x45EC, 0xCBCBB6B6}, + {0x45F0, 0x5F900FCA}, + {0x4BAC, 0x12CAB6DE}, + {0x4BB0, 0x00001110}, + {0x45F4, 0x08882550}, + {0x45F8, 0x08CC2660}, + {0x45FC, 0x09102660}, + {0x4600, 0x00000154}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xE1CB38E8}, + {0x4660, 0x4A2E1800}, + {0x4664, 0x6750E462}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xD1B942F4}, + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xD1B942F4}, + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xD1B942F4}, + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xD1B942F4}, + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0xA0000000, 0x00000000}, + {0x45DC, 0xE1CB38E8}, + {0x4660, 0x4A2E1800}, + {0x4664, 0x6750E462}, + {0xB0000000, 0x00000000}, + {0x4668, 0x0E0CFB0A}, + {0x466C, 0x30100F06}, + {0x4670, 0x34333333}, + {0x4674, 0x34343434}, + {0x4678, 0xC39D38E8}, + {0x467C, 0x482800E3}, + {0x4680, 0x5836E46A}, + {0x4684, 0xFBEBDA00}, + {0x4688, 0x1A10FF04}, + {0x468C, 0x282A3000}, + {0x4690, 0x2A29292A}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4694, 0x04FA2A2A}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4694, 0x04FA2A2A}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4694, 0x06FA2A2A}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4694, 0x04FA2A2A}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4694, 0x04FA2A2A}, + {0xA0000000, 0x00000000}, + {0x4694, 0x04FA2A2A}, + {0xB0000000, 0x00000000}, + {0x4698, 0xEE0F04D1}, + {0x469C, 0x89291436}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0xA0000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0xB0000000, 0x00000000}, + {0x46A4, 0x08D07CFF}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x649EFF14}, + {0x46AC, 0xA1B37C4E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x4D1E7F14}, + {0x46AC, 0x60B37C4E}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x649EFF14}, + {0x46AC, 0xA1B37C4E}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x649EFF14}, + {0x46AC, 0xA1B37C4E}, + {0xA0000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0xB0000000, 0x00000000}, + {0x46B0, 0x63666666}, + {0x46B4, 0x35374425}, + {0x46B8, 0x25883043}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x3FFFFD63}, + {0x4724, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x510FC252}, + {0x4720, 0x27795303}, + {0x4724, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x510FC252}, + {0x4720, 0x27795843}, + {0x4724, 0xB58D11F5}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x510FC252}, + {0x4720, 0x27795303}, + {0x4724, 0xB58D11F5}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x510FC252}, + {0x4720, 0x27795303}, + {0x4724, 0xB58D11F5}, + {0xA0000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x3FFFFD63}, + {0x4724, 0xB58D11FF}, + {0xB0000000, 0x00000000}, + {0x4728, 0x07FFFFFF}, + {0x472C, 0x0E7893B6}, + {0x4730, 0xE0399201}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D5420}, + {0x4738, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D4C20}, + {0x4738, 0x8F25C500}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D5420}, + {0x4738, 0x8F25C500}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D5420}, + {0x4738, 0x8F25C500}, + {0xA0000000, 0x00000000}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0xB0000000, 0x00000000}, + {0x473C, 0x00000B7F}, + {0x4ACC, 0x000F7D00}, + {0x4AD0, 0x00000000}, + {0x4AD4, 0x00000040}, + {0x4AE4, 0x5379E99E}, + {0x4AE8, 0x00000744}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0xFBD5B89F}, + {0x4BB8, 0x99563918}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0xA0000000, 0x00000000}, + {0x4BB4, 0xFBD5B89F}, + {0x4BB8, 0x99563918}, + {0xB0000000, 0x00000000}, + {0x4BBC, 0x12EED5B8}, + {0x4BC0, 0x80C4542F}, + {0x4BC4, 0x005A007F}, + {0x4BC8, 0x40000000}, + {0x4BCC, 0x40000000}, + {0x4BD0, 0x00000000}, + {0x4BD4, 0x40000000}, + {0x4BD8, 0xC0000000}, + {0x4BDC, 0x40000000}, + {0x4BE0, 0x80000000}, + {0x4BE4, 0xBAAC8000}, + {0x4BE8, 0x638A88C5}, + {0x4BEC, 0x00900000}, + {0x4EAC, 0x00000000}, + {0x4BF0, 0x00000000}, + {0x4BF4, 0x00000000}, + {0x4BF8, 0x00000219}, + {0x4EC4, 0x00000001}, + {0x4EE8, 0x00002020}, + {0x4BFC, 0x00000000}, + {0x4C00, 0x00000010}, + {0x4C04, 0x00000001}, + {0x4C08, 0x00000001}, + {0x4C0C, 0x00000000}, + {0x4C10, 0x00000000}, + {0x4C14, 0x00000151}, + {0x4C18, 0x00000000}, + {0x4C1C, 0x00000000}, + {0x4C20, 0x00000151}, + {0x4C24, 0x00000498}, + {0x4C28, 0x00000498}, + {0x4C2C, 0x00000498}, + {0x4C30, 0x00000498}, + {0x4C34, 0x00000498}, + {0x4C38, 0x00000498}, + {0x4C3C, 0x00000498}, + {0x4C40, 0x00000498}, + {0x4C44, 0x00000000}, + {0x4C48, 0x00000000}, + {0x4C4C, 0x00001146}, + {0x4C50, 0x00000000}, + {0x4C54, 0x00000000}, + {0x4C58, 0x00001146}, + {0x4C5C, 0x00000000}, + {0x4C60, 0x00000000}, + {0x4C64, 0xC8E1E1DE}, + {0x4C68, 0xB6B600B6}, + {0x4C6C, 0xCACBCBCA}, + {0x4C70, 0x80F9010F}, + {0x4C74, 0x00000B11}, + {0x46C8, 0x08882550}, + {0x46CC, 0x08CC2660}, + {0x46D0, 0x09102660}, + {0x46D4, 0x00000154}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xE4CD38E8}, + {0x4744, 0x4C321B04}, + {0x4748, 0x6750E466}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xC5AD42F4}, + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xC5AD42F4}, + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xC5AD42F4}, + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xC5AD42F4}, + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0xA0000000, 0x00000000}, + {0x4740, 0xE4CD38E8}, + {0x4744, 0x4C321B04}, + {0x4748, 0x6750E466}, + {0xB0000000, 0x00000000}, + {0x474C, 0x0E0CFB0A}, + {0x4750, 0x30100F06}, + {0x4754, 0x34333333}, + {0x4758, 0x34343434}, + {0x475C, 0xC49E38E8}, + {0x4760, 0x482800E2}, + {0x4764, 0x5636E466}, + {0x4768, 0xFBEBDA00}, + {0x476C, 0x1A10FF04}, + {0x4770, 0x282A3000}, + {0x4774, 0x2A29292A}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4778, 0x04FA2A2A}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4778, 0x04FA2A2A}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4778, 0x06FA2A2A}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4778, 0x04FA2A2A}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4778, 0x04FA2A2A}, + {0xA0000000, 0x00000000}, + {0x4778, 0x04FA2A2A}, + {0xB0000000, 0x00000000}, + {0x477C, 0xEE0F04D1}, + {0x49F0, 0x89291436}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0xA0000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0xB0000000, 0x00000000}, + {0x49FC, 0x08D07CFF}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x649EFF14}, + {0x4A60, 0xA1B37C4E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x4D1E7F14}, + {0x4A60, 0x60B37C4E}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x649EFF14}, + {0x4A60, 0xA1B37C4E}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x649EFF14}, + {0x4A60, 0xA1B37C4E}, + {0xA0000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0xB0000000, 0x00000000}, + {0x4A64, 0x63666666}, + {0x4A68, 0x35374425}, + {0x4A6C, 0x25883043}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x3FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x510FC252}, + {0x4A74, 0x27795303}, + {0x4A78, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x510FC252}, + {0x4A74, 0x27795843}, + {0x4A78, 0xB58D11F5}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x510FC252}, + {0x4A74, 0x27795303}, + {0x4A78, 0xB58D11F5}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x510FC252}, + {0x4A74, 0x27795303}, + {0x4A78, 0xB58D11F5}, + {0xA0000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x3FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0xB0000000, 0x00000000}, + {0x4A7C, 0x07FFFFFF}, + {0x4A80, 0x0E7893B6}, + {0x4A9C, 0xE0399201}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D5420}, + {0x4AA4, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D4C20}, + {0x4AA4, 0x8F25C500}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D5420}, + {0x4AA4, 0x8F25C500}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D5420}, + {0x4AA4, 0x8F25C500}, + {0xA0000000, 0x00000000}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0xB0000000, 0x00000000}, + {0x4AA8, 0x00000B7F}, + {0x4AD8, 0x000F7D00}, + {0x4ADC, 0x00000000}, + {0x4AE0, 0x00000040}, + {0x4AEC, 0x5379E99E}, + {0x4AF0, 0x00000744}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0xFBD5B89F}, + {0x4C7C, 0x99563918}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0xA0000000, 0x00000000}, + {0x4C78, 0xFBD5B89F}, + {0x4C7C, 0x99563918}, + {0xB0000000, 0x00000000}, + {0x4C80, 0x12EED5B8}, + {0x4C84, 0x80C4542F}, + {0x4C88, 0x005A007F}, + {0x4C8C, 0x40000000}, + {0x4C90, 0x40000000}, + {0x4C94, 0x00000000}, + {0x4C98, 0x40000000}, + {0x4C9C, 0xC0000000}, + {0x4CA0, 0x40000000}, + {0x4CA4, 0x80000000}, + {0x4CA8, 0xBAAC8000}, + {0x4CAC, 0x638A88C5}, + {0x4CB0, 0x00900000}, + {0x4EB0, 0x00000000}, + {0x4CB4, 0x00000000}, + {0x4CB8, 0x00000000}, + {0x4CBC, 0x00000219}, + {0x4EC8, 0x00000001}, + {0x4EEC, 0x00002020}, + {0x4CC0, 0x00000000}, + {0x4CC4, 0x00000010}, + {0x4CC8, 0x00000001}, + {0x4CCC, 0x00000001}, + {0x4CD0, 0x00000000}, + {0x4CD4, 0x00000000}, + {0x4CD8, 0x00000151}, + {0x4CDC, 0x00000000}, + {0x4CE0, 0x00000000}, + {0x4CE4, 0x00000151}, + {0x4CE8, 0x00000498}, + {0x4CEC, 0x00000498}, + {0x4CF0, 0x00000498}, + {0x4CF4, 0x00000498}, + {0x4CF8, 0x00000498}, + {0x4CFC, 0x00000498}, + {0x4D00, 0x00000498}, + {0x4D04, 0x00000498}, + {0x4D08, 0x00000000}, + {0x4D0C, 0x00000000}, + {0x4D10, 0x00001146}, + {0x4D14, 0x00000000}, + {0x4D18, 0x00000000}, + {0x4D1C, 0x00001146}, + {0x4788, 0x00000000}, + {0x478C, 0xA32103FE}, + {0x4790, 0xB20A7B28}, + {0x4794, 0xC6A7B14F}, + {0x4798, 0x000000D3}, + {0x4D20, 0x00000000}, + {0x4D24, 0x0C442416}, + {0x4D28, 0x00000000}, + {0x479C, 0x009B902A}, + {0x47A0, 0x009B902A}, + {0x47A4, 0x98682C18}, + {0x47A8, 0x6318C4C1}, + {0x47AC, 0x6248C631}, + {0x47B0, 0x922A8253}, + {0x47B4, 0x00000005}, + {0x4D2C, 0x0008C0C1}, + {0x47B8, 0x00001759}, + {0x47BC, 0x4B002402}, + {0x47C0, 0x831508BC}, + {0x4A14, 0x000000E9}, + {0x4D30, 0x00000000}, + {0x4E94, 0x000000FC}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0xA0000000, 0x00000000}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0xB0000000, 0x00000000}, + {0x47CC, 0xBBCCBBB3}, + {0x47D0, 0x57889989}, + {0x47D4, 0x00000F45}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4D34, 0x7BB167AB}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4D34, 0x7BB1579A}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4D34, 0x7BB167AB}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4D34, 0x7BB1579A}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4D34, 0x7BB1579A}, + {0xA0000000, 0x00000000}, + {0x4D34, 0x7BB167AB}, + {0xB0000000, 0x00000000}, + {0x4D38, 0xBBBBBB05}, + {0x4D3C, 0x777777BB}, + {0x4D40, 0x00015277}, + {0x47D8, 0x27039CE9}, + {0x47DC, 0x41414432}, + {0x47E0, 0x36058342}, + {0x47E4, 0x00000006}, + {0x4D44, 0x00000687}, + {0x47E8, 0x00000001}, + {0x47EC, 0x00000001}, + {0x47F0, 0xC7013016}, + {0x47F4, 0x84413016}, + {0x47F8, 0x84413016}, + {0x47FC, 0x8C413016}, + {0x4800, 0x8C40B028}, + {0x4804, 0x3140B028}, + {0x4808, 0x2940B028}, + {0x480C, 0x8440B028}, + {0x4810, 0x6318C610}, + {0x4814, 0x45334753}, + {0x4818, 0x236A6A88}, + {0x4D48, 0x8C413016}, + {0x4D4C, 0xA140B028}, + {0x4D50, 0x00150A31}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x481C, 0x576DF814}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x481C, 0x576DF814}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x481C, 0x576BF814}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x481C, 0x576DF814}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x481C, 0x576DF814}, + {0xA0000000, 0x00000000}, + {0x481C, 0x576DF814}, + {0xB0000000, 0x00000000}, + {0x4820, 0xA08877AC}, + {0x4824, 0x0000007A}, + {0x4D54, 0x00001184}, + {0x4828, 0xBCEB4A14}, + {0x482C, 0x000A3A4A}, + {0x4830, 0xBCEB4A14}, + {0x4834, 0x000A3A4A}, + {0x4D58, 0x2F63DD3A}, + {0x4838, 0xBCBDBD85}, + {0x483C, 0x0CABB99A}, + {0x4D5C, 0x000000BC}, + {0x4840, 0x38384242}, + {0x4844, 0x0086102E}, + {0x4848, 0xCA24C82A}, + {0x4D60, 0x00000000}, + {0x4D64, 0x0000F49D}, + {0x4ED8, 0x00000001}, + {0x4D68, 0x000001C4}, + {0x4D6C, 0x00000000}, + {0x4D70, 0x38384242}, + {0x4D74, 0x030E902E}, + {0x4D78, 0x994C1502}, + {0x4D7C, 0x00017912}, + {0x4EDC, 0x00000001}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x484C, 0x0000CA62}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x484C, 0x00008A62}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x484C, 0x0000CA62}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x484C, 0x00008A62}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x484C, 0x00008A62}, + {0xA0000000, 0x00000000}, + {0x484C, 0x0000CA62}, + {0xB0000000, 0x00000000}, + {0x4D80, 0x00000002}, + {0x4850, 0x00000008}, + {0x4854, 0x009B902A}, + {0x4858, 0x009B902A}, + {0x485C, 0x98682C18}, + {0x4860, 0x6318C4C1}, + {0x4864, 0x6248C631}, + {0x4868, 0x922A8253}, + {0x486C, 0x00000005}, + {0x4D84, 0x0008C0C1}, + {0x4870, 0x00001759}, + {0x4874, 0x4B702400}, + {0x4878, 0x831508BA}, + {0x4A24, 0x000000E9}, + {0x4D88, 0x00000001}, + {0x4E98, 0x000000FC}, + {0x487C, 0x9898A8BB}, + {0x4880, 0x54535368}, + {0x4884, 0x999999B3}, + {0x4888, 0x35555589}, + {0x488C, 0x00000745}, + {0x4D8C, 0x6AB14487}, + {0x4D90, 0xBBBBBB04}, + {0x4D94, 0x777777BB}, + {0x4D98, 0x00015277}, + {0x4890, 0x27039CE9}, + {0x4894, 0x41414432}, + {0x4898, 0x36058342}, + {0x489C, 0x00000006}, + {0x4D9C, 0x00000687}, + {0x48A0, 0x00000001}, + {0x48A4, 0x00000001}, + {0x48A8, 0xC7013016}, + {0x48AC, 0x84413016}, + {0x48B0, 0x84413016}, + {0x48B4, 0x8C413016}, + {0x48B8, 0x8C40B028}, + {0x48BC, 0x3140B028}, + {0x48C0, 0x2940B028}, + {0x48C4, 0x8440B028}, + {0x48C8, 0x6318C610}, + {0x48CC, 0x45334753}, + {0x48D0, 0x236A6A88}, + {0x4DA0, 0x8C413016}, + {0x4DA4, 0xA140B028}, + {0x4DA8, 0x00150A31}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x48D4, 0x576DF814}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x48D4, 0x576BF814}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x48D4, 0x576BF814}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x48D4, 0x576BF814}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x48D4, 0x576BF814}, + {0xA0000000, 0x00000000}, + {0x48D4, 0x576DF814}, + {0xB0000000, 0x00000000}, + {0x48D8, 0xA08877AC}, + {0x48DC, 0x0000007A}, + {0x4DAC, 0x00001184}, + {0x48E0, 0xBCEB4A14}, + {0x48E4, 0x000A3A4A}, + {0x48E8, 0xBCEB4A14}, + {0x48EC, 0x000A3A4A}, + {0x4DB0, 0x2F63DD3A}, + {0x48F0, 0x9A8A8A85}, + {0x48F4, 0x0C9BB99A}, + {0x4DB4, 0x0000009A}, + {0x48F8, 0x38384242}, + {0x48FC, 0x0086102E}, + {0x4900, 0xCA24C82A}, + {0x4DB8, 0x00000000}, + {0x4DBC, 0x0000F49D}, + {0x4EE0, 0x00000001}, + {0x4DC0, 0x000001C4}, + {0x4DC4, 0x00000000}, + {0x4DC8, 0x38384242}, + {0x4DCC, 0x030E902E}, + {0x4DD0, 0x994C1502}, + {0x4DD4, 0x00017912}, + {0x4EE4, 0x00000001}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0xA0000000, 0x00000000}, + {0x4904, 0x0000CA62}, + {0xB0000000, 0x00000000}, + {0x4DD8, 0x00000002}, + {0x4908, 0x00000008}, + {0x490C, 0x80040000}, + {0x4910, 0x80040000}, + {0x4914, 0xFE800000}, + {0x4918, 0x834C0000}, + {0x491C, 0x00000000}, + {0x4920, 0x00000000}, + {0x4924, 0x000003FF}, + {0x4928, 0x00000000}, + {0x492C, 0x00000000}, + {0x4930, 0x00000000}, + {0x4934, 0x40000000}, + {0x4938, 0x00000000}, + {0x493C, 0x00000000}, + {0x4940, 0x00000000}, + {0x4944, 0x00000000}, + {0x4948, 0x04065800}, + {0x494C, 0x02010080}, + {0x4950, 0x0E1E3E05}, + {0x4954, 0x0A163068}, + {0x4958, 0x00206040}, + {0x495C, 0x02020202}, + {0x4960, 0x00002020}, + {0x4DDC, 0x18002000}, + {0x4DE0, 0x00004001}, + {0x4DE4, 0x00040004}, + {0x4DE8, 0x00400040}, + {0x4DEC, 0x04000400}, + {0x4DF0, 0x08080618}, + {0x4DF4, 0x08081616}, + {0x4DF8, 0x08080808}, + {0x4DFC, 0x18180808}, + {0x4E00, 0x01020100}, + {0x4E04, 0x05020502}, + {0x4E08, 0x00020E0F}, + {0x4E0C, 0x00000000}, + {0x4E10, 0x16080806}, + {0x4E14, 0x08080816}, + {0x4E18, 0x08080808}, + {0x4E1C, 0x00181808}, + {0x4E20, 0x02010201}, + {0x4E24, 0x0F050205}, + {0x4E28, 0x0000020E}, + {0x4E2C, 0x00000000}, + {0x4E70, 0x00000001}, + {0x4970, 0x00000000}, + {0x4974, 0xC00CD62D}, + {0x4978, 0x00000103}, + {0x4E30, 0x02E416A8}, + {0x497C, 0x00000000}, + {0x4980, 0x00000000}, + {0x4984, 0x00000000}, + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4E34, 0x00FC0000}, + {0x4E38, 0x00000000}, + {0x4E3C, 0x00000003}, + {0x4990, 0x00000000}, + {0x4994, 0x00000000}, + {0x4998, 0x00000000}, + {0x499C, 0x00000000}, + {0x49A0, 0x00000000}, + {0x4E40, 0x00FC0000}, + {0x4E44, 0x0000F800}, + {0x4E48, 0x00000001}, + {0xC54, 0x10014368}, + {0xC58, 0x61000000}, + {0xC5C, 0x805580F0}, + {0xC64, 0x0010A030}, + {0x189C, 0x000003FF}, + {0xC6C, 0x00060020}, + {0xC3C, 0x2840E1BF}, + {0xC40, 0x00000000}, + {0xC44, 0x00000007}, + {0xC48, 0x410E4000}, + {0xC54, 0x1EE1436A}, + {0xC58, 0x61000000}, + {0x730, 0x00000002}, + {0xC60, 0x017FFFF2}, + {0xC64, 0x0010A170}, + {0xC64, 0x0010A170}, + {0xC68, 0x000000FF}, + {0xC64, 0x0010A130}, + {0xC54, 0x1AE1436A}, + {0xC6C, 0x00060020}, + {0xC58, 0x41000000}, + {0x708, 0x00000000}, + {0xC6C, 0x00061020}, + {0x884, 0x0043F01D}, + {0x704, 0x601E0100}, + {0x710, 0xEF810000}, + {0xC54, 0x1AE1436A}, + {0xC58, 0x41000000}, + {0xC68, 0x90000050}, + {0xC6C, 0x20061020}, + {0x704, 0x601E0100}, + {0xC74, 0x00000000}, + {0x90C, 0x00300000}, + {0xC70, 0x071BFC00}, + {0xC74, 0x3FFFFFFF}, + {0xC78, 0x3FFFFFFF}, + {0xC7C, 0x0000BFFF}, + {0xD40, 0xF64FA0F7}, + {0xD44, 0x0400463F}, + {0xD48, 0x0003FFFF}, + {0xD4C, 0x00000000}, + {0xD50, 0xF64FA0F7}, + {0xD54, 0x04100437}, + {0xD58, 0x0000FF7F}, + {0xD5C, 0x00000000}, + {0xD60, 0x00000000}, + {0xD64, 0x00000000}, + {0xD70, 0x00000015}, + {0xD90, 0x000003FF}, + {0xD94, 0x00000000}, + {0xD98, 0x0000003F}, + {0xD9C, 0x00000000}, + {0xDA0, 0x000003FE}, + {0xDA4, 0x00000000}, + {0xDA8, 0x0000003F}, + {0xDAC, 0x00000000}, + {0xD00, 0x77777777}, + {0xD04, 0xBBBBBBBB}, + {0xD08, 0xBBBBBBBB}, + {0xD0C, 0x00000070}, + {0xD10, 0x20110900}, + {0xD10, 0x20110FFF}, + {0xD78, 0x00000001}, + {0xD7C, 0x001C040A}, + {0xD84, 0x00006007}, + {0xD84, 0x00006607}, + {0xD10, 0x28110FFF}, + {0xD18, 0x50209900}, + {0xD80, 0x00804100}, + {0xD80, 0x00804200}, + {0x718, 0x1333233F}, + {0x604, 0x041E1E1E}, + {0x714, 0x00010000}, + {0x586C, 0x000000F0}, + {0x586C, 0x000000E0}, + {0x586C, 0x000000D0}, + {0x586C, 0x000000C0}, + {0x586C, 0x000000B0}, + {0x586C, 0x000000A0}, + {0x586C, 0x00000090}, + {0x586C, 0x00000080}, + {0x586C, 0x00000070}, + {0x586C, 0x00000060}, + {0x586C, 0x00000050}, + {0x586C, 0x00000040}, + {0x586C, 0x00000030}, + {0x586C, 0x00000020}, + {0x586C, 0x00000010}, + {0x586C, 0x00000000}, + {0x786C, 0x000000F0}, + {0x786C, 0x000000E0}, + {0x786C, 0x000000D0}, + {0x786C, 0x000000C0}, + {0x786C, 0x000000B0}, + {0x786C, 0x000000A0}, + {0x786C, 0x00000090}, + {0x786C, 0x00000080}, + {0x786C, 0x00000070}, + {0x786C, 0x00000060}, + {0x786C, 0x00000050}, + {0x786C, 0x00000040}, + {0x786C, 0x00000030}, + {0x786C, 0x00000020}, + {0x786C, 0x00000010}, + {0x786C, 0x00000000}, + {0x304, 0x0CE31333}, + {0x300, 0xF30CE31C}, + {0x304, 0x13EF1F19}, + {0x308, 0x0C13E3F3}, + {0x30C, 0x130C0C0C}, + {0x310, 0x80496000}, + {0x314, 0x0041E000}, + {0x318, 0x20022042}, + {0x31C, 0x20448009}, + {0x320, 0x00490040}, + {0x324, 0xE0000070}, + {0x328, 0xE000E000}, + {0x32C, 0x0041E000}, + {0x35C, 0x000004C4}, + {0xC0D4, 0xA7441460}, + {0xC0D8, 0xC6BA7F67}, + {0xC0DC, 0x30C52868}, + {0xC0E0, 0x75008128}, + {0xC0E4, 0x0000272B}, + {0xC1D4, 0xA7441460}, + {0xC1D8, 0xC6BA7F67}, + {0xC1DC, 0x30C52868}, + {0xC1E0, 0x75008128}, + {0xC1E4, 0x0000272B}, + {0xC0EC, 0x00030003}, + {0xC1EC, 0x00030003}, + {0xC004, 0x03020000}, + {0xC024, 0x03020000}, + {0xC104, 0x03020000}, + {0xC124, 0x03020000}, + {0xC0E8, 0x000A0C81}, + {0xC0F0, 0x00000024}, + {0xC1E8, 0x000A0C81}, + {0xC1F0, 0x00000024}, + {0x334, 0xFFFFFFFF}, + {0x33C, 0x55000000}, + {0x340, 0x00005555}, + {0x724, 0x00111201}, + {0x5868, 0xA9550000}, + {0x5870, 0x33221100}, + {0x5874, 0x77665544}, + {0x5878, 0xBBAA9988}, + {0x587C, 0xFFEEDDCC}, + {0x5880, 0x76543210}, + {0x5884, 0xFEDCBA98}, + {0x5888, 0x00000000}, + {0x588C, 0x00000000}, + {0x5894, 0x00000008}, + {0x7868, 0xA9550000}, + {0x7870, 0x33221100}, + {0x7874, 0x77665544}, + {0x7878, 0xBBAA9988}, + {0x787C, 0xFFEEDDCC}, + {0x7880, 0x76543210}, + {0x7884, 0xFEDCBA98}, + {0x7888, 0x00000000}, + {0x788C, 0x00000000}, + {0x7894, 0x00000008}, + {0x650, 0x00200888}, + {0x710, 0xF3810000}, + {0x020, 0x0000F381}, + {0x024, 0x0000F381}, + {0xC0A8, 0x00000080}, + {0xC0AC, 0x00000100}, + {0xC0B8, 0x00020000}, + {0xC1A8, 0x00000080}, + {0xC1AC, 0x00000100}, + {0xC1B8, 0x00020000}, + {0x1038, 0x00003100}, + {0x1038, 0x00003100}, + {0x3038, 0x00003100}, + {0x3038, 0x00003100}, + {0xC14, 0xA5000000}, + {0x908, 0x00000001}, + {0xC54, 0x1EE14368}, + {0xC88, 0xC2AC8000}, + {0xC8C, 0x02F2FC08}, + {0xC70, 0x071BFC00}, + {0x980, 0x10002251}, + {0x988, 0x3C3C8107}, + {0x904, 0x00000005}, + {0x994, 0x00000010}, + {0x000, 0x0580801F}, + {0x240C, 0x00000000}, + {0x010, 0x000C01FF}, + {0x010, 0x001C01FF}, + {0x2424, 0x00000008}, + {0x620, 0x00141A30}, + {0x660, 0x00000004}, + {0x2620, 0x00141A30}, + {0x2660, 0x00000000}, + {0x640, 0x180A141E}, + {0x640, 0x1814141E}, + {0x640, 0x1814141E}, + {0x640, 0x14141414}, + {0x644, 0x3C14283C}, + {0x644, 0x3C29283C}, + {0x644, 0x3C29203C}, + {0x644, 0x3C29201A}, + {0x2640, 0x180A141E}, + {0x2640, 0x1814141E}, + {0x2640, 0x1814141E}, + {0x2640, 0x14141414}, + {0x2644, 0x3C14283C}, + {0x2644, 0x3C29283C}, + {0x2644, 0x3C29203C}, + {0x2644, 0x3C29201A}, + {0x620, 0x00141A40}, + {0x64C, 0x1D0A141E}, + {0x64C, 0x1D1D141E}, + {0x64C, 0x1D1D1D1E}, + {0x2620, 0x00141A40}, + {0x264C, 0x1D0A141E}, + {0x264C, 0x1D1D141E}, + {0x264C, 0x1D1D1D1E}, + {0x2300, 0x03020100}, + {0x2304, 0x07060504}, + {0x2308, 0x0B0A0908}, + {0x230C, 0x0F0E0D0C}, + {0x2310, 0x13121110}, + {0x2314, 0x17161514}, + {0x2318, 0x00000018}, + {0x231C, 0x00C00000}, + {0x2320, 0x00000000}, + {0x2324, 0x0005298F}, + {0x2328, 0x0015296E}, + {0x232C, 0x0D3B5200}, + {0x2330, 0x00000000}, + {0x2334, 0x00000000}, + {0x2338, 0x00000000}, + {0x233C, 0x00000402}, + {0x2340, 0x00020080}, + {0x2344, 0x03C00000}, + {0x2348, 0x0001FFFF}, + {0x234C, 0x00C80064}, + {0x2350, 0x0190012C}, + {0x2354, 0x000032FE}, + {0x2358, 0xF0203C28}, + {0x235C, 0xF027C000}, + {0x2360, 0x01210C00}, + {0x2320, 0x00000001}, + {0x2300, 0x0C811B40}, + {0x2304, 0xF3FC4ED8}, + {0x2308, 0x08FF808F}, + {0x230C, 0xFCBC80C8}, + {0x2310, 0xBC80536C}, + {0x2314, 0x0363A0F3}, + {0x2318, 0x000000BB}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x724, 0x00111200}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x724, 0x20111100}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x724, 0x20111100}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x724, 0x01100100}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x724, 0x01100100}, + {0xA0000000, 0x00000000}, + {0x724, 0x00111200}, + {0xB0000000, 0x00000000}, + {0x704, 0x601E0D00}, + {0xC78, 0xBFFFFFFF}, + {0x704, 0x601E0D02}, + {0x704, 0x601E0D02}, + {0x5864, 0x080801FF}, + {0x7864, 0x080801FF}, + {0xC60, 0x017FFFF3}, + {0xC6C, 0x20061021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8088, 0x007F0000}, + {0x81A4, 0x003F3A00}, + {0x81B4, 0x0100007F}, + {0x81C0, 0x0060010B}, + {0x81A0, 0x00000010}, + {0x8138, 0x40000002}, + {0x82A4, 0x003F3A00}, + {0x82B4, 0x0100007F}, + {0x82C0, 0x0060010B}, + {0x82A0, 0x00000010}, + {0x81A0, 0x00000010}, + {0x8238, 0x40000002}, + {0x8088, 0x00000000}, + {0x8020, 0x00000000}, + {0x8120, 0x00000000}, + {0x8220, 0x00000000}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0xC70, 0x071BFE00}, + {0xC70, 0x071BFE60}, + {0xC6C, 0x26061021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8120, 0x10000000}, + {0x8120, 0x10030000}, + {0x8124, 0x00000F0F}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8220, 0x10000000}, + {0x8220, 0x10030000}, + {0x704, 0x601E0D00}, + {0x5864, 0x100801FF}, + {0x7864, 0x100801FF}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0x58D4, 0x7401FE00}, + {0x78D4, 0x7401FE00}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x704, 0x601E0D02}, + {0xC7C, 0x0020BFFF}, + {0x58C0, 0x00FE0000}, + {0x58FC, 0x00000000}, + {0x566C, 0x00010005}, + {0x566C, 0x00011005}, + {0x700, 0x00000030}, + {0x9D0, 0x00001001}, + {0x704, 0x601E0D02}, + {0x704, 0x601E0D00}, + {0x704, 0x601C0502}, + {0x000, 0x0580801F}, + {0x980, 0x10002250}, + {0x010, 0x001C01FF}, + {0xC3C, 0x2840E1BF}, + {0x12A8, 0x33337824}, + {0x32A8, 0x33337824}, + {0x620, 0x00141A40}, + {0x2320, 0x00000000}, + {0x664, 0x0000000C}, + {0xC0F8, 0x00000001}, + {0xC1F8, 0x00000001}, + {0x2D7C, 0x739C040A}, + {0x1010, 0x00000000}, + {0x3010, 0x00000000}, + {0x2C14, 0x80000005}, + {0x5818, 0x082C1800}, + {0x7818, 0x082C1800}, + {0x624, 0x0101030A}, + {0x028, 0x0000F381}, + {0x02C, 0x0000F381}, + {0x720, 0x20000000}, + {0x1200, 0x00010142}, + {0x12A0, 0x24903056}, + {0x12AC, 0x12333121}, + {0x12B8, 0x30020000}, + {0x2000, 0x20BBBF04}, + {0x2C14, 0x85000005}, + {0x3200, 0x00010142}, + {0x32A0, 0x24903056}, + {0x32AC, 0x12333121}, + {0x32B8, 0x30020000}, + {0x5800, 0x03FF807F}, + {0x5804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7800, 0x03FF807F}, + {0x7804, 0x04237040}, + {0x7808, 0x04237040}, + {0x010, 0x001C61FF}, + {0x56C8, 0x0E800400}, + {0x76C8, 0x0E800400}, + {0x984, 0x000000E0}, + {0x2008, 0x000FFFFF}, + {0x1210, 0x8049E304}, + {0x3210, 0x8049E304}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x58B0, 0x00000800}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x58B0, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x58B0, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x58B0, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x58B0, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x58B0, 0x00000800}, + {0xB0000000, 0x00000000}, + {0x5A00, 0x00000000}, + {0x5A04, 0x00000000}, + {0x5A08, 0x00000000}, + {0x5A0C, 0x00000000}, + {0x5A10, 0x00000000}, + {0x5A14, 0x00000000}, + {0x5A18, 0x00000000}, + {0x5A1C, 0x00000000}, + {0x5A20, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A24, 0x00050000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A24, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A24, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A24, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A24, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x5A24, 0x00050000}, + {0xB0000000, 0x00000000}, + {0x5A28, 0x00000000}, + {0x5A2C, 0x00000000}, + {0x5A30, 0x00000000}, + {0x5A34, 0x00000000}, + {0x5A38, 0x00000000}, + {0x5A3C, 0x00000000}, + {0x5A40, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A44, 0x00000005}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A44, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A44, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A44, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A44, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x5A44, 0x00000005}, + {0xB0000000, 0x00000000}, + {0x5A48, 0x00000000}, + {0x5A4C, 0x00000000}, + {0x5A50, 0x00000000}, + {0x5A54, 0x00000000}, + {0x5A58, 0x00000000}, + {0x5A5C, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A60, 0x00050000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A60, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A60, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A60, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5A60, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x5A60, 0x00050000}, + {0xB0000000, 0x00000000}, + {0x5A64, 0x00000000}, + {0x5A68, 0x00000000}, + {0x5A6C, 0x00000000}, + {0x5A70, 0x00000000}, + {0x5A74, 0x00000000}, + {0x5A78, 0x00000000}, + {0x5A7C, 0x00000000}, + {0x5A80, 0x00000000}, + {0x5A84, 0x00000000}, + {0x5A88, 0x00000000}, + {0x5A8C, 0x00000000}, + {0x5A90, 0x00000000}, + {0x5A94, 0x00000000}, + {0x5A98, 0x00000000}, + {0x5A9C, 0x00000000}, + {0x5AA0, 0x00000000}, + {0x5AA4, 0x00000000}, + {0x5AA8, 0x00000000}, + {0x5AAC, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x5AB0, 0x00050005}, + {0x5AB4, 0x00050005}, + {0x5AB8, 0x00050005}, + {0x5ABC, 0x00050005}, + {0x5AC0, 0x00000005}, + {0x78B0, 0x00000800}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5AB0, 0x00000000}, + {0x5AB4, 0x00000000}, + {0x5AB8, 0x00000000}, + {0x5ABC, 0x00000000}, + {0x5AC0, 0x00000000}, + {0x78B0, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5AB0, 0x00000000}, + {0x5AB4, 0x00000000}, + {0x5AB8, 0x00000000}, + {0x5ABC, 0x00000000}, + {0x5AC0, 0x00000000}, + {0x78B0, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5AB0, 0x00000000}, + {0x5AB4, 0x00000000}, + {0x5AB8, 0x00000000}, + {0x5ABC, 0x00000000}, + {0x5AC0, 0x00000000}, + {0x78B0, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x5AB0, 0x00000000}, + {0x5AB4, 0x00000000}, + {0x5AB8, 0x00000000}, + {0x5ABC, 0x00000000}, + {0x5AC0, 0x00000000}, + {0x78B0, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x5AB0, 0x00050005}, + {0x5AB4, 0x00050005}, + {0x5AB8, 0x00050005}, + {0x5ABC, 0x00050005}, + {0x5AC0, 0x00000005}, + {0x78B0, 0x00000800}, + {0xB0000000, 0x00000000}, + {0x7A00, 0x00000000}, + {0x7A04, 0x00000000}, + {0x7A08, 0x00000000}, + {0x7A0C, 0x00000000}, + {0x7A10, 0x00000000}, + {0x7A14, 0x00000000}, + {0x7A18, 0x00000000}, + {0x7A1C, 0x00000000}, + {0x7A20, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A24, 0x00050000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A24, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A24, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A24, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A24, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x7A24, 0x00050000}, + {0xB0000000, 0x00000000}, + {0x7A28, 0x00000000}, + {0x7A2C, 0x00000000}, + {0x7A30, 0x00000000}, + {0x7A34, 0x00000000}, + {0x7A38, 0x00000000}, + {0x7A3C, 0x00000000}, + {0x7A40, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A44, 0x00000005}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A44, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A44, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A44, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A44, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x7A44, 0x00000005}, + {0xB0000000, 0x00000000}, + {0x7A48, 0x00000000}, + {0x7A4C, 0x00000000}, + {0x7A50, 0x00000000}, + {0x7A54, 0x00000000}, + {0x7A58, 0x00000000}, + {0x7A5C, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A60, 0x00050000}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A60, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A60, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A60, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7A60, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x7A60, 0x00050000}, + {0xB0000000, 0x00000000}, + {0x7A64, 0x00000000}, + {0x7A68, 0x00000000}, + {0x7A6C, 0x00000000}, + {0x7A70, 0x00000000}, + {0x7A74, 0x00000000}, + {0x7A78, 0x00000000}, + {0x7A7C, 0x00000000}, + {0x7A80, 0x00000000}, + {0x7A84, 0x00000000}, + {0x7A88, 0x00000000}, + {0x7A8C, 0x00000000}, + {0x7A90, 0x00000000}, + {0x7A94, 0x00000000}, + {0x7A98, 0x00000000}, + {0x7A9C, 0x00000000}, + {0x7AA0, 0x00000000}, + {0x7AA4, 0x00000000}, + {0x7AA8, 0x00000000}, + {0x7AAC, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x7AB0, 0x00050005}, + {0x7AB4, 0x00050005}, + {0x7AB8, 0x00050005}, + {0x7ABC, 0x00050005}, + {0x7AC0, 0x00000005}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7AB0, 0x00000000}, + {0x7AB4, 0x00000000}, + {0x7AB8, 0x00000000}, + {0x7ABC, 0x00000000}, + {0x7AC0, 0x00000000}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7AB0, 0x00000000}, + {0x7AB4, 0x00000000}, + {0x7AB8, 0x00000000}, + {0x7ABC, 0x00000000}, + {0x7AC0, 0x00000000}, + {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7AB0, 0x00000000}, + {0x7AB4, 0x00000000}, + {0x7AB8, 0x00000000}, + {0x7ABC, 0x00000000}, + {0x7AC0, 0x00000000}, + {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x7AB0, 0x00000000}, + {0x7AB4, 0x00000000}, + {0x7AB8, 0x00000000}, + {0x7ABC, 0x00000000}, + {0x7AC0, 0x00000000}, + {0xA0000000, 0x00000000}, + {0x7AB0, 0x00050005}, + {0x7AB4, 0x00050005}, + {0x7AB8, 0x00050005}, + {0x7ABC, 0x00050005}, + {0x7AC0, 0x00000005}, + {0xB0000000, 0x00000000}, + {0x0F0, 0x00010000}, + {0x0F4, 0x00000028}, + {0x0F8, 0x20220610}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { + {0xF0FF0000, 0x00000000}, + {0xF03300FF, 0x00000001}, + {0x000, 0x0EEECAA6}, + {0x001, 0x006C4B2C}, + {0x002, 0x00005636}, + {0x100, 0x0DEFCAA9}, + {0x101, 0x00694B2C}, + {0x102, 0x00005536}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x1A02E1C9}, + {0x10001, 0x00644A30}, + {0x10002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x0BF1CEB6}, + {0x10001, 0x00434328}, + {0x10002, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x10000, 0x1D08E8D0}, + {0x10001, 0x00644C32}, + {0x10002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x1901E1C8}, + {0x10101, 0x0061482D}, + {0x10102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x0BF0CEB8}, + {0x10101, 0x00424227}, + {0x10102, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x10100, 0x1F0AECD5}, + {0x10101, 0x00634B31}, + {0x10102, 0x00006550}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1601E2CA}, + {0x20001, 0x005D452A}, + {0x20002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x0EF5D3BB}, + {0x20001, 0x00454529}, + {0x20002, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x20000, 0x1904E6CE}, + {0x20001, 0x0060482D}, + {0x20002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x1901E1C8}, + {0x20101, 0x0061482D}, + {0x20102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x12F8D7C1}, + {0x20101, 0x004A4A2E}, + {0x20102, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x20100, 0x1F0AECD5}, + {0x20101, 0x0061482D}, + {0x20102, 0x00006550}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1700E1CA}, + {0x30001, 0x005E472B}, + {0x30002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x0DF6D5BE}, + {0x30001, 0x00414126}, + {0x30002, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x30000, 0x14FEE0CA}, + {0x30001, 0x005C4328}, + {0x30002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x14FEE0C9}, + {0x30101, 0x00594428}, + {0x30102, 0x00006650}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x0EF5D5C0}, + {0x30101, 0x0045452A}, + {0x30102, 0x00005050}, + {0xA0000000, 0x00000000}, + {0x30100, 0x1F0AECD8}, + {0x30101, 0x00654C31}, + {0x30102, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x40000, 0x15FEE0CB}, + {0x40001, 0x0060462B}, + {0x40002, 0x00006450}, + {0x40100, 0x1902E5D2}, + {0x40101, 0x0063482E}, + {0x40102, 0x00006450}, + {0x50000, 0x1C04E6D3}, + {0x50001, 0x006B5034}, + {0x50002, 0x00006450}, + {0x50100, 0x2009EDDB}, + {0x50101, 0x006B5035}, + {0x50102, 0x00006450}, + {0x60000, 0x16FEE1CF}, + {0x60001, 0x00634A2E}, + {0x60002, 0x00006550}, + {0x60100, 0x14FDE2D2}, + {0x60101, 0x005E4429}, + {0x60102, 0x00006450}, + {0x70000, 0x0BF3D6C6}, + {0x70001, 0x00573F24}, + {0x70002, 0x00006550}, + {0x70100, 0x08F0D6C7}, + {0x70101, 0x0052391E}, + {0x70102, 0x00006450}, + {0x2000000, 0x02E4C4A0}, + {0x2000001, 0x006A4828}, + {0x2000100, 0x02E4C5A1}, + {0x2000101, 0x00664629}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2010000, 0x05EBC8AF}, + {0x2010001, 0x00543D24}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2010000, 0x08EDCAB2}, + {0x2010001, 0x00434327}, + {0xA0000000, 0x00000000}, + {0x2010000, 0x05EBC8AF}, + {0x2010001, 0x00543D24}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2010100, 0x07ECC9B0}, + {0x2010101, 0x005B4126}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2010100, 0x08ECCBB2}, + {0x2010101, 0x003C3C20}, + {0xA0000000, 0x00000000}, + {0x2010100, 0x07ECC9B0}, + {0x2010101, 0x005B4126}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2020000, 0x05EDCCB2}, + {0x2020001, 0x004D361C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2020000, 0x0CF4D2BA}, + {0x2020001, 0x00404025}, + {0xA0000000, 0x00000000}, + {0x2020000, 0x05EDCCB2}, + {0x2020001, 0x004D361C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2020100, 0x06ECCBB2}, + {0x2020101, 0x00553D22}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2020100, 0x09EECDB8}, + {0x2020101, 0x00444428}, + {0xA0000000, 0x00000000}, + {0x2020100, 0x06ECCBB2}, + {0x2020101, 0x00553D22}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2030000, 0x02ECCCB3}, + {0x2030001, 0x00483118}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2030000, 0x0DF8D6BF}, + {0x2030001, 0x003F3F24}, + {0xA0000000, 0x00000000}, + {0x2030000, 0x02ECCCB3}, + {0x2030001, 0x00483118}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x2030100, 0x04ECCCB2}, + {0x2030101, 0x004F381C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x2030100, 0x08EFCDBA}, + {0x2030101, 0x00414126}, + {0xA0000000, 0x00000000}, + {0x2030100, 0x04ECCCB2}, + {0x2030101, 0x004F381C}, + {0xB0000000, 0x00000000}, + {0x3000000, 0x00000000}, + {0x3000001, 0x00000000}, + {0x3000002, 0x00000000}, + {0x3000003, 0x00000000}, + {0x3000100, 0x00000000}, + {0x3000101, 0x00000000}, + {0x3000102, 0x00000000}, + {0x3000103, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3010000, 0x0E0CFB0A}, + {0x3010001, 0x00100F06}, + {0x3010002, 0x34333333}, + {0x3010003, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3010000, 0x0E0CFB0A}, + {0x3010001, 0x00100F06}, + {0x3010002, 0x34333327}, + {0x3010003, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3010000, 0x0E0CFB0A}, + {0x3010001, 0x00100F06}, + {0x3010002, 0x34333333}, + {0x3010003, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3010100, 0x0E0CFB0A}, + {0x3010101, 0x00100F06}, + {0x3010102, 0x34333333}, + {0x3010103, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3010100, 0x0E0CFB0A}, + {0x3010101, 0x00100F06}, + {0x3010102, 0x34333327}, + {0x3010103, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3010100, 0x0E0CFB0A}, + {0x3010101, 0x00100F06}, + {0x3010102, 0x34333333}, + {0x3010103, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3020000, 0x0E0CFB0A}, + {0x3020001, 0x00100F06}, + {0x3020002, 0x34333333}, + {0x3020003, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3020000, 0x0E0CFB0A}, + {0x3020001, 0x00100F06}, + {0x3020002, 0x34333327}, + {0x3020003, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3020000, 0x0E0CFB0A}, + {0x3020001, 0x00100F06}, + {0x3020002, 0x34333333}, + {0x3020003, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3020100, 0x0E0CFB0A}, + {0x3020101, 0x00100F06}, + {0x3020102, 0x34333333}, + {0x3020103, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3020100, 0x0E0CFB0A}, + {0x3020101, 0x00100F06}, + {0x3020102, 0x34333327}, + {0x3020103, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3020100, 0x0E0CFB0A}, + {0x3020101, 0x00100F06}, + {0x3020102, 0x34333333}, + {0x3020103, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3030000, 0x0E0CFB0A}, + {0x3030001, 0x00100F06}, + {0x3030002, 0x34333333}, + {0x3030003, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3030000, 0x0E0CFB0A}, + {0x3030001, 0x00100F06}, + {0x3030002, 0x34333327}, + {0x3030003, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3030000, 0x0E0CFB0A}, + {0x3030001, 0x00100F06}, + {0x3030002, 0x34333333}, + {0x3030003, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x3030100, 0x0E0CFB0A}, + {0x3030101, 0x00100F06}, + {0x3030102, 0x34333333}, + {0x3030103, 0x3434343C}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x3030100, 0x0E0CFB0A}, + {0x3030101, 0x00100F06}, + {0x3030102, 0x34333327}, + {0x3030103, 0x3434343C}, + {0xA0000000, 0x00000000}, + {0x3030100, 0x0E0CFB0A}, + {0x3030101, 0x00100F06}, + {0x3030102, 0x34333333}, + {0x3030103, 0x3434343C}, + {0xB0000000, 0x00000000}, + {0x3040000, 0x0E0CFB0A}, + {0x3040001, 0x00100F06}, + {0x3040002, 0x343B3333}, + {0x3040003, 0x34343C3C}, + {0x3040100, 0x0E0CFB0A}, + {0x3040101, 0x00100F06}, + {0x3040102, 0x343B3333}, + {0x3040103, 0x34343C3C}, + {0x3050000, 0x0E0CFB0A}, + {0x3050001, 0x00100F06}, + {0x3050002, 0x343B3333}, + {0x3050003, 0x34343C3C}, + {0x3050100, 0x0E0CFB0A}, + {0x3050101, 0x00100F06}, + {0x3050102, 0x343B3333}, + {0x3050103, 0x34343C3C}, + {0x3060000, 0x0E0CFB0A}, + {0x3060001, 0x00100F06}, + {0x3060002, 0x3C3B3333}, + {0x3060003, 0x34343C3C}, + {0x3060100, 0x0E0CFB0A}, + {0x3060101, 0x00100F06}, + {0x3060102, 0x3C3B3333}, + {0x3060103, 0x34343C3C}, + {0x3070000, 0x0E0CFB0A}, + {0x3070001, 0x00100F06}, + {0x3070002, 0x3C3B3333}, + {0x3070003, 0x34343C3C}, + {0x3070100, 0x0E0CFB0A}, + {0x3070101, 0x00100F06}, + {0x3070102, 0x3C3B3333}, + {0x3070103, 0x34343C3C}, + {0x4000000, 0x00000000}, + {0x4000001, 0x76543210}, + {0x4000002, 0x77777777}, + {0x4000003, 0x35374425}, + {0x4000004, 0x00000043}, + {0x4000005, 0x000038E8}, + {0x4000100, 0x00000000}, + {0x4000101, 0x76543210}, + {0x4000102, 0x77777777}, + {0x4000103, 0x35374425}, + {0x4000104, 0x00000043}, + {0x4000105, 0x000038E8}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4010000, 0x00000000}, + {0x4010001, 0x76543210}, + {0x4010002, 0x77777777}, + {0x4010003, 0x35374425}, + {0x4010004, 0x00000042}, + {0x4010005, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4010000, 0x0000FC50}, + {0x4010001, 0x51403210}, + {0x4010002, 0x76543276}, + {0x4010003, 0x3A4DAA3C}, + {0x4010004, 0x00000093}, + {0x4010005, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4010000, 0x00000000}, + {0x4010001, 0x76543210}, + {0x4010002, 0x77777777}, + {0x4010003, 0x35374425}, + {0x4010004, 0x00000042}, + {0x4010005, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4010100, 0x00000000}, + {0x4010101, 0x76543210}, + {0x4010102, 0x77777777}, + {0x4010103, 0x35374425}, + {0x4010104, 0x00000042}, + {0x4010105, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4010100, 0x0000FC50}, + {0x4010101, 0x51403210}, + {0x4010102, 0x76543276}, + {0x4010103, 0x3A4DAA3C}, + {0x4010104, 0x00000093}, + {0x4010105, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4010100, 0x00000000}, + {0x4010101, 0x76543210}, + {0x4010102, 0x77777777}, + {0x4010103, 0x35374425}, + {0x4010104, 0x00000042}, + {0x4010105, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4020000, 0x00000000}, + {0x4020001, 0x76543210}, + {0x4020002, 0x77777777}, + {0x4020003, 0x35374425}, + {0x4020004, 0x00000042}, + {0x4020005, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4020000, 0x0000FC50}, + {0x4020001, 0x51403210}, + {0x4020002, 0x76543276}, + {0x4020003, 0x4B4DAA3C}, + {0x4020004, 0x000000A3}, + {0x4020005, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4020000, 0x00000000}, + {0x4020001, 0x76543210}, + {0x4020002, 0x77777777}, + {0x4020003, 0x35374425}, + {0x4020004, 0x00000042}, + {0x4020005, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4020100, 0x00000000}, + {0x4020101, 0x76543210}, + {0x4020102, 0x77777777}, + {0x4020103, 0x35374425}, + {0x4020104, 0x00000042}, + {0x4020105, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4020100, 0x0000FC50}, + {0x4020101, 0x51403210}, + {0x4020102, 0x76543276}, + {0x4020103, 0x3A4DAA3C}, + {0x4020104, 0x00000093}, + {0x4020105, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4020100, 0x00000000}, + {0x4020101, 0x76543210}, + {0x4020102, 0x77777777}, + {0x4020103, 0x35374425}, + {0x4020104, 0x00000042}, + {0x4020105, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4030000, 0x00000000}, + {0x4030001, 0x76543210}, + {0x4030002, 0x77777777}, + {0x4030003, 0x35374425}, + {0x4030004, 0x00000042}, + {0x4030005, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4030000, 0x0000FC50}, + {0x4030001, 0x51403210}, + {0x4030002, 0x76543276}, + {0x4030003, 0x3A4DAA3C}, + {0x4030004, 0x00000093}, + {0x4030005, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4030000, 0x00000000}, + {0x4030001, 0x76543210}, + {0x4030002, 0x77777777}, + {0x4030003, 0x35374425}, + {0x4030004, 0x00000042}, + {0x4030005, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4030100, 0x00000000}, + {0x4030101, 0x76543210}, + {0x4030102, 0x77777777}, + {0x4030103, 0x35374425}, + {0x4030104, 0x00000042}, + {0x4030105, 0x000038E8}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4030100, 0x0000FC50}, + {0x4030101, 0x51403210}, + {0x4030102, 0x76543276}, + {0x4030103, 0x3A4DAA3C}, + {0x4030104, 0x00000093}, + {0x4030105, 0x000040E4}, + {0xA0000000, 0x00000000}, + {0x4030100, 0x00000000}, + {0x4030101, 0x76543210}, + {0x4030102, 0x77777777}, + {0x4030103, 0x35374425}, + {0x4030104, 0x00000042}, + {0x4030105, 0x000038E8}, + {0xB0000000, 0x00000000}, + {0x1000000, 0x00000008}, + {0x1000010, 0x00000008}, + {0x1000011, 0x00000000}, + {0x1000100, 0x00000004}, + {0x1000110, 0x00000004}, + {0x1000111, 0x00000000}, + {0x1010000, 0x00000004}, + {0x1010010, 0x00000004}, + {0x1010011, 0x00000000}, + {0x1010020, 0x00000004}, + {0x1010021, 0x00000000}, + {0x1010029, 0x00000000}, + {0x1010030, 0x00000000}, + {0x1010031, 0x00000000}, + {0x1010035, 0x00000000}, + {0x1010039, 0x00000000}, + {0x101003D, 0x00000000}, + {0x1010100, 0x00000010}, + {0x1010110, 0x00000010}, + {0x1010111, 0x00000000}, + {0x1010120, 0x00000010}, + {0x1010121, 0x00000000}, + {0x1010129, 0x00000000}, + {0x1010030, 0x00000000}, + {0x1010031, 0x00000000}, + {0x1010035, 0x00000000}, + {0x1010039, 0x00000000}, + {0x101003D, 0x00000000}, + {0x1020000, 0x000000FA}, + {0x1020010, 0x000000FA}, + {0x1020011, 0x00000000}, + {0x1020020, 0x000000FA}, + {0x1020021, 0x00000000}, + {0x1020029, 0x00000000}, + {0x1020030, 0x00000000}, + {0x1020031, 0x00000000}, + {0x1020035, 0x00000000}, + {0x1020039, 0x00000000}, + {0x102003D, 0x00000000}, + {0x1020100, 0x0000000D}, + {0x1020110, 0x0000000D}, + {0x1020111, 0x00000000}, + {0x1020120, 0x0000000D}, + {0x1020121, 0x00000000}, + {0x1020129, 0x00000000}, + {0x1020030, 0x00000000}, + {0x1020031, 0x00000000}, + {0x1020035, 0x00000000}, + {0x1020039, 0x00000000}, + {0x102003D, 0x00000000}, + {0x1030000, 0x000000E4}, + {0x1030010, 0x000000E4}, + {0x1030011, 0x00000000}, + {0x1030020, 0x0000E8E8}, + {0x1030021, 0x00000000}, + {0x1030029, 0x00000000}, + {0x1030030, 0x00000000}, + {0x1030031, 0x00000000}, + {0x1030035, 0x00000000}, + {0x1030039, 0x00000000}, + {0x103003D, 0x00000000}, + {0x1030100, 0x00000018}, + {0x1030110, 0x00000018}, + {0x1030111, 0x00000000}, + {0x1030120, 0x00000018}, + {0x1030121, 0x00000000}, + {0x1030129, 0x00000000}, + {0x1030030, 0x00000000}, + {0x1030031, 0x00000000}, + {0x1030035, 0x00000000}, + {0x1030039, 0x00000000}, + {0x103003D, 0x00000000}, + {0x1040000, 0x000000EE}, + {0x1040010, 0x000000EE}, + {0x1040011, 0x00000000}, + {0x1040020, 0x000000EE}, + {0x1040021, 0x00000000}, + {0x1040029, 0x00000000}, + {0x1040030, 0x000000EE}, + {0x1040031, 0x00000000}, + {0x1040035, 0x00000000}, + {0x1040039, 0x00000000}, + {0x104003D, 0x00000000}, + {0x1040100, 0x00000000}, + {0x1040110, 0x00000005}, + {0x1040111, 0x00000000}, + {0x1040120, 0x00000008}, + {0x1040121, 0x00000000}, + {0x1040129, 0x00000000}, + {0x1040030, 0x00000008}, + {0x1040031, 0x00000000}, + {0x1040035, 0x00000000}, + {0x1040039, 0x00000000}, + {0x104003D, 0x00000000}, + {0x1050000, 0x00000008}, + {0x1050010, 0x0000000B}, + {0x1050011, 0x00000000}, + {0x1050020, 0x00000015}, + {0x1050021, 0x00000000}, + {0x1050029, 0x00000000}, + {0x1050030, 0x00000010}, + {0x1050031, 0x00000000}, + {0x1050035, 0x00000000}, + {0x1050039, 0x00000000}, + {0x105003D, 0x00000000}, + {0x1050100, 0x00000016}, + {0x1050110, 0x00000016}, + {0x1050111, 0x0000F8F8}, + {0x1050120, 0x0000001A}, + {0x1050121, 0x00000000}, + {0x1050129, 0x00000000}, + {0x1050030, 0x0000001A}, + {0x1050031, 0x00000000}, + {0x1050035, 0x00000000}, + {0x1050039, 0x00000000}, + {0x105003D, 0x00000000}, + {0x1060000, 0x000000F8}, + {0x1060010, 0x000000F8}, + {0x1060011, 0x00000000}, + {0x1060020, 0x00000000}, + {0x1060021, 0x00000000}, + {0x1060029, 0x00000000}, + {0x1060030, 0x00000000}, + {0x1060031, 0x00000000}, + {0x1060035, 0x00000000}, + {0x1060039, 0x00000000}, + {0x106003D, 0x00000000}, + {0x1060100, 0x000000F6}, + {0x1060110, 0x000000F6}, + {0x1060111, 0x00000000}, + {0x1060120, 0x000000F6}, + {0x1060121, 0x00000000}, + {0x1060129, 0x00000000}, + {0x1060030, 0x00000000}, + {0x1060031, 0x00000000}, + {0x1060035, 0x00000000}, + {0x1060039, 0x00000000}, + {0x106003D, 0x00000000}, + {0x1070000, 0x000000E8}, + {0x1070010, 0x000000E8}, + {0x1070011, 0x00000000}, + {0x1070020, 0x000000E8}, + {0x1070021, 0x00000000}, + {0x1070029, 0x00000000}, + {0x1070030, 0x000000F0}, + {0x1070031, 0x00000000}, + {0x1070035, 0x00000000}, + {0x1070039, 0x00000000}, + {0x107003D, 0x00000000}, + {0x1070100, 0x000000E4}, + {0x1070110, 0x000000E4}, + {0x1070111, 0x00000000}, + {0x1070120, 0x000000E4}, + {0x1070121, 0x00000000}, + {0x1070129, 0x00000000}, + {0x1070030, 0x000000F0}, + {0x1070031, 0x00000000}, + {0x1070035, 0x00000000}, + {0x1070039, 0x00000000}, + {0x107003D, 0x00000000}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_radioa_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0320000, 0x00000002}, + {0xF0330000, 0x00000003}, + {0xF0340000, 0x00000004}, + {0xF0350000, 0x00000005}, + {0xF0360000, 0x00000006}, + {0xF0010001, 0x00000007}, + {0xF0020001, 0x00000008}, + {0xF0030001, 0x00000009}, + {0xF0040001, 0x0000000A}, + {0xF0050001, 0x0000000B}, + {0xF0070001, 0x0000000C}, + {0xF0150001, 0x0000000D}, + {0xF0160001, 0x0000000E}, + {0xF0320001, 0x0000000F}, + {0xF0330001, 0x00000010}, + {0xF0340001, 0x00000011}, + {0xF0350001, 0x00000012}, + {0xF0360001, 0x00000013}, + {0xF03F0001, 0x00000014}, + {0xF0400001, 0x00000015}, + {0x005, 0x00000000}, + {0x10005, 0x00000000}, + {0x000, 0x00030001}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x0A3, 0x000B9204}, + {0x0AD, 0x00091E0F}, + {0x05D, 0x00001012}, + {0x05C, 0x00061C5C}, + {0x062, 0x00055220}, + {0x0D3, 0x00000103}, + {0x0EF, 0x00080000}, + {0x033, 0x00000001}, + {0x03E, 0x00000620}, + {0x03F, 0x0000020C}, + {0x0EF, 0x00000000}, + {0x05F, 0x00000038}, + {0x097, 0x00043200}, + {0x0A6, 0x00066DB7}, + {0x0EF, 0x00004000}, + {0x033, 0x00000005}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000003}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000002}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x0000000D}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x0000000B}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x0000000A}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x0EF, 0x00000000}, + {0x000, 0x00033C01}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x096, 0x00015200}, + {0x10055, 0x00080080}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0xA0000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0xB0000000, 0x00000000}, + {0x057, 0x0000D589}, + {0x05A, 0x0007FFFF}, + {0x043, 0x00005000}, + {0x0B5, 0x00001720}, + {0x0ED, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x033, 0x00000010}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x033, 0x00000020}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x000000FA}, + {0x033, 0x00000001}, + {0x03F, 0x000000F2}, + {0x033, 0x00000002}, + {0x03F, 0x000000EA}, + {0x033, 0x00000003}, + {0x03F, 0x000000E2}, + {0x033, 0x00000004}, + {0x03F, 0x000000DA}, + {0x033, 0x00000005}, + {0x03F, 0x000000D2}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000090}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000080}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000038}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000030}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000028}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000018}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000010}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000008}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x0B9, 0x00020440}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0xA0000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0xB0000000, 0x00000000}, + {0x0EB, 0x00000000}, + {0x030, 0x000109B0}, + {0x030, 0x000189B0}, + {0x0EB, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x033, 0x00000002}, + {0x03F, 0x00000017}, + {0x033, 0x00000003}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000007}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00060001}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00000001}, + {0x033, 0x00000025}, + {0x03F, 0x00000002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00060001}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00000001}, + {0x033, 0x0000002D}, + {0x03F, 0x00000002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00060001}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00000001}, + {0x033, 0x00000035}, + {0x03F, 0x00000002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00060001}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00000001}, + {0x033, 0x00000065}, + {0x03F, 0x00000002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00060001}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00000001}, + {0x033, 0x0000006D}, + {0x03F, 0x00000002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00060001}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00000001}, + {0x033, 0x00000075}, + {0x03F, 0x00000002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00060001}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00000001}, + {0x033, 0x0000007D}, + {0x03F, 0x00000002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00060001}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00000001}, + {0x033, 0x000000A5}, + {0x03F, 0x00000002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00060001}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00000001}, + {0x033, 0x000000AD}, + {0x03F, 0x00000002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00060001}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00000001}, + {0x033, 0x000000B5}, + {0x03F, 0x00000002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00060001}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00000001}, + {0x033, 0x000000E5}, + {0x03F, 0x00000002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00060001}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00000001}, + {0x033, 0x000000ED}, + {0x03F, 0x00000002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00060001}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00000001}, + {0x033, 0x000000F5}, + {0x03F, 0x00000002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00060001}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00000001}, + {0x033, 0x000000FD}, + {0x03F, 0x00000002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00060001}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00000001}, + {0x033, 0x00000125}, + {0x03F, 0x00000002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00060001}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00000001}, + {0x033, 0x0000012D}, + {0x03F, 0x00000002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00060001}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00000001}, + {0x033, 0x00000135}, + {0x03F, 0x00000002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00060001}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00000001}, + {0x033, 0x00000165}, + {0x03F, 0x00000002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00060001}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00000001}, + {0x033, 0x0000016D}, + {0x03F, 0x00000002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00060001}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00000001}, + {0x033, 0x00000175}, + {0x03F, 0x00000002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00060001}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00000001}, + {0x033, 0x0000017D}, + {0x03F, 0x00000002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00060001}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00000001}, + {0x033, 0x000001A5}, + {0x03F, 0x00000002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00060001}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00000001}, + {0x033, 0x000001AD}, + {0x03F, 0x00000002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00060001}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00000001}, + {0x033, 0x000001B5}, + {0x03F, 0x00000002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00060001}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00000001}, + {0x033, 0x000001E5}, + {0x03F, 0x00000002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00060001}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00000001}, + {0x033, 0x000001ED}, + {0x03F, 0x00000002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00060001}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00000001}, + {0x033, 0x000001F5}, + {0x03F, 0x00000002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00060001}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00000001}, + {0x033, 0x000001FD}, + {0x03F, 0x00000002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000001}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000002}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000003}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000004}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000005}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000006}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000007}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000008}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000009}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000B}, + {0x03F, 0x0000AFFF}, + {0x033, 0x0000000C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000010}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000011}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000012}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000013}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000014}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000017}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000018}, + {0x03F, 0x0000FBFF}, + {0x033, 0x00000019}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000020}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000021}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000022}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000023}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000024}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000025}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000026}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000027}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000028}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000029}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000030}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000031}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000032}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000033}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000034}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000035}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000036}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000037}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000038}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000039}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000003A}, + {0x03F, 0x0000EFFF}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000000}, + {0x03F, 0x00004344}, + {0x033, 0x00000001}, + {0x03F, 0x00004344}, + {0x033, 0x00000002}, + {0x03F, 0x00004344}, + {0x033, 0x00000003}, + {0x03F, 0x00004344}, + {0x033, 0x00000004}, + {0x03F, 0x00004344}, + {0x033, 0x00000005}, + {0x03F, 0x00004344}, + {0x033, 0x00000006}, + {0x03F, 0x00004344}, + {0x033, 0x00000007}, + {0x03F, 0x00004344}, + {0x033, 0x00000008}, + {0x03F, 0x00004344}, + {0x033, 0x00000009}, + {0x03F, 0x00004344}, + {0x033, 0x0000000A}, + {0x03F, 0x00004344}, + {0x033, 0x0000000B}, + {0x03F, 0x00004344}, + {0x033, 0x00000010}, + {0x03F, 0x00004344}, + {0x033, 0x00000011}, + {0x03F, 0x00004344}, + {0x033, 0x00000012}, + {0x03F, 0x00004344}, + {0x033, 0x00000013}, + {0x03F, 0x00004344}, + {0x033, 0x00000014}, + {0x03F, 0x00004344}, + {0x033, 0x00000015}, + {0x03F, 0x00004344}, + {0x033, 0x00000016}, + {0x03F, 0x00004344}, + {0x033, 0x00000017}, + {0x03F, 0x00004344}, + {0x033, 0x00000018}, + {0x03F, 0x00004344}, + {0x033, 0x00000019}, + {0x03F, 0x00004344}, + {0x033, 0x0000001A}, + {0x03F, 0x00004344}, + {0x033, 0x0000001B}, + {0x03F, 0x00004344}, + {0x033, 0x0000001C}, + {0x03F, 0x00004344}, + {0x033, 0x0000001D}, + {0x03F, 0x00004344}, + {0x033, 0x0000001E}, + {0x03F, 0x00004344}, + {0x033, 0x0000001F}, + {0x03F, 0x00004344}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000020}, + {0x033, 0x00000010}, + {0x03F, 0x00000200}, + {0x033, 0x00000011}, + {0x03F, 0x00000200}, + {0x033, 0x00000012}, + {0x03F, 0x00000200}, + {0x033, 0x00000013}, + {0x03F, 0x00000200}, + {0x033, 0x00000020}, + {0x03F, 0x00000200}, + {0x033, 0x00000021}, + {0x03F, 0x00000200}, + {0x033, 0x00000022}, + {0x03F, 0x00000200}, + {0x033, 0x00000023}, + {0x03F, 0x00000200}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0xA0000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0xB0000000, 0x00000000}, + {0x030, 0x00068000}, + {0x030, 0x00070000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000004}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000005}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000006}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x00000007}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000008}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000009}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x0000000B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x0000000C}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000D}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x0000000F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000010}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000011}, + {0x03E, 0x0000001B}, + {0x03F, 0x00023C58}, + {0x033, 0x00000012}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x00000013}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000014}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000015}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x00000016}, + {0x03E, 0x0000001C}, + {0x03F, 0x00021C58}, + {0x033, 0x00000017}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x00000018}, + {0x03E, 0x00000013}, + {0x03F, 0x00025A58}, + {0x033, 0x00000019}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x0000001A}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x0000001B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x0000001C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000001D}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x0000001E}, + {0x03E, 0x00000013}, + {0x03F, 0x00021E58}, + {0x033, 0x0000001F}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000020}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000021}, + {0x03E, 0x0000001C}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000022}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000023}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000024}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000025}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000026}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000027}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000028}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000029}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000002B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x0000002C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000002F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000030}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000031}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000032}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000033}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000034}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000035}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000036}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000037}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000038}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000039}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000003B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x0000003C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000003F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000031}, + {0x033, 0x00000001}, + {0x03F, 0x00000023}, + {0x033, 0x00000002}, + {0x03F, 0x00000015}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EC, 0x00000400}, + {0x033, 0x00000003}, + {0x03F, 0x00000030}, + {0x033, 0x00000004}, + {0x03F, 0x00000021}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x0A7, 0x00080308}, + {0x066, 0x00006000}, + {0x0EF, 0x00000400}, + {0x030, 0x000001FF}, + {0x030, 0x000081FF}, + {0x030, 0x000101FF}, + {0x030, 0x000181FF}, + {0x030, 0x000201FF}, + {0x030, 0x000281FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0xA0000000, 0x00000000}, + {0x030, 0x0003017F}, + {0xB0000000, 0x00000000}, + {0x030, 0x000380FB}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0380}, + {0x06B, 0x00003CA0}, + {0x06F, 0x000C01FC}, + {0x05E, 0x0000001F}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0380}, + {0x06B, 0x00003CA0}, + {0x06F, 0x000C01FC}, + {0x05E, 0x0000001F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0xA0000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000200}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0xA0000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00080000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0000803C}, + {0x030, 0x0001003C}, + {0x030, 0x0001803C}, + {0x030, 0x0002003C}, + {0x030, 0x0002803C}, + {0x030, 0x0003003C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0000803C}, + {0x030, 0x0001003C}, + {0x030, 0x0001803C}, + {0x030, 0x0002003C}, + {0x030, 0x0002803C}, + {0x030, 0x0003003C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0xA0000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0xB0000000, 0x00000000}, + {0x030, 0x0003803C}, + {0x030, 0x0004003C}, + {0x030, 0x0004803C}, + {0x030, 0x0005003C}, + {0x030, 0x0005803C}, + {0x030, 0x0006003C}, + {0x030, 0x0006803C}, + {0x030, 0x0007003C}, + {0x0EB, 0x00000000}, + {0x094, 0x000000FC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0xA0000000, 0x00000000}, + {0x095, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x03F, 0x000002E7}, + {0x033, 0x0000003C}, + {0x03F, 0x000003E7}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000065}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x03F, 0x000002E7}, + {0x033, 0x0000007F}, + {0x03F, 0x000003E7}, + {0x0EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E7}, + {0x10030, 0x000709A7}, + {0x10030, 0x00070D61}, + {0x10030, 0x0007115B}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x000720DF}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728A1}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E3}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B823}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000000FC}, + {0x10030, 0x000004F9}, + {0x10030, 0x000008F6}, + {0x10030, 0x00000CF3}, + {0x10030, 0x000010F0}, + {0x10030, 0x000014ED}, + {0x10030, 0x000018AC}, + {0x10030, 0x00001CA9}, + {0x10030, 0x00002069}, + {0x10030, 0x00002466}, + {0x10030, 0x00002829}, + {0x10030, 0x00002C26}, + {0x10030, 0x00003023}, + {0x10030, 0x00003420}, + {0x10030, 0x0000381D}, + {0x10030, 0x00003C1A}, + {0x10030, 0x00004017}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x0002240D}, + {0x10030, 0x0002280A}, + {0x10030, 0x00022C07}, + {0x10030, 0x00023004}, + {0x10030, 0x00023401}, + {0x10030, 0x00023800}, + {0x10030, 0x00023C00}, + {0x10030, 0x00024000}, + {0x10030, 0x000280ED}, + {0x10030, 0x000284EA}, + {0x10030, 0x000288E7}, + {0x10030, 0x00028CE4}, + {0x10030, 0x000290E1}, + {0x10030, 0x000294DE}, + {0x10030, 0x000298DB}, + {0x10030, 0x00029CD8}, + {0x10030, 0x0002A0D5}, + {0x10030, 0x0002A4D2}, + {0x10030, 0x0002A8CF}, + {0x10030, 0x0002AC0C}, + {0x10030, 0x0002B009}, + {0x10030, 0x0002B406}, + {0x10030, 0x0002B803}, + {0x10030, 0x0002BC00}, + {0x10030, 0x0002C000}, + {0x10030, 0x000300EE}, + {0x10030, 0x000304EB}, + {0x10030, 0x000308E8}, + {0x10030, 0x00030CE5}, + {0x10030, 0x000310E2}, + {0x10030, 0x000314DF}, + {0x10030, 0x000318DC}, + {0x10030, 0x00031CD9}, + {0x10030, 0x000320D6}, + {0x10030, 0x000324D3}, + {0x10030, 0x000328D0}, + {0x10030, 0x00032CCD}, + {0x10030, 0x0003300A}, + {0x10030, 0x00033407}, + {0x10030, 0x00033804}, + {0x10030, 0x00033C01}, + {0x10030, 0x00034000}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x0002240D}, + {0x10030, 0x0002280A}, + {0x10030, 0x00022C07}, + {0x10030, 0x00023004}, + {0x10030, 0x00023401}, + {0x10030, 0x00023800}, + {0x10030, 0x00023C00}, + {0x10030, 0x00024000}, + {0x10030, 0x000280ED}, + {0x10030, 0x000284EA}, + {0x10030, 0x000288E7}, + {0x10030, 0x00028CE4}, + {0x10030, 0x000290E1}, + {0x10030, 0x000294DE}, + {0x10030, 0x000298DB}, + {0x10030, 0x00029CD8}, + {0x10030, 0x0002A0D5}, + {0x10030, 0x0002A4D2}, + {0x10030, 0x0002A8CF}, + {0x10030, 0x0002AC0C}, + {0x10030, 0x0002B009}, + {0x10030, 0x0002B406}, + {0x10030, 0x0002B803}, + {0x10030, 0x0002BC00}, + {0x10030, 0x0002C000}, + {0x10030, 0x000300EE}, + {0x10030, 0x000304EB}, + {0x10030, 0x000308E8}, + {0x10030, 0x00030CE5}, + {0x10030, 0x000310E2}, + {0x10030, 0x000314DF}, + {0x10030, 0x000318DC}, + {0x10030, 0x00031CD9}, + {0x10030, 0x000320D6}, + {0x10030, 0x000324D3}, + {0x10030, 0x000328D0}, + {0x10030, 0x00032CCD}, + {0x10030, 0x0003300A}, + {0x10030, 0x00033407}, + {0x10030, 0x00033804}, + {0x10030, 0x00033C01}, + {0x10030, 0x00034000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0xB0000000, 0x00000000}, + {0x10030, 0x000600F6}, + {0x10030, 0x000604F3}, + {0x10030, 0x000608F0}, + {0x10030, 0x00060CED}, + {0x10030, 0x000610EA}, + {0x10030, 0x000614E7}, + {0x10030, 0x000618E4}, + {0x10030, 0x00061CE1}, + {0x10030, 0x000620DE}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628D8}, + {0x10030, 0x00062CD5}, + {0x10030, 0x000630D2}, + {0x10030, 0x000634CF}, + {0x10030, 0x000638CC}, + {0x10030, 0x00063C09}, + {0x10030, 0x00064006}, + {0x10030, 0x000680F5}, + {0x10030, 0x000684F2}, + {0x10030, 0x000688EF}, + {0x10030, 0x00068CEC}, + {0x10030, 0x000690E9}, + {0x10030, 0x000694E6}, + {0x10030, 0x000698E3}, + {0x10030, 0x00069CE0}, + {0x10030, 0x0006A0DD}, + {0x10030, 0x0006A4DA}, + {0x10030, 0x0006A8D7}, + {0x10030, 0x0006ACD4}, + {0x10030, 0x0006B0D1}, + {0x10030, 0x0006B4CE}, + {0x10030, 0x0006B8CB}, + {0x10030, 0x0006BC08}, + {0x10030, 0x0006C005}, + {0x10030, 0x000700F5}, + {0x10030, 0x000704F2}, + {0x10030, 0x000708EF}, + {0x10030, 0x00070CEC}, + {0x10030, 0x000710E9}, + {0x10030, 0x000714E6}, + {0x10030, 0x000718E3}, + {0x10030, 0x00071CE0}, + {0x10030, 0x000720DD}, + {0x10030, 0x000724DA}, + {0x10030, 0x000728D7}, + {0x10030, 0x00072CD4}, + {0x10030, 0x000730D1}, + {0x10030, 0x000734CE}, + {0x10030, 0x000738CB}, + {0x10030, 0x00073C08}, + {0x10030, 0x00074005}, + {0x10030, 0x000780F4}, + {0x10030, 0x000784F1}, + {0x10030, 0x000788EE}, + {0x10030, 0x00078CEB}, + {0x10030, 0x000790E8}, + {0x10030, 0x000794E5}, + {0x10030, 0x000798E2}, + {0x10030, 0x00079CDF}, + {0x10030, 0x0007A0DC}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D6}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B0D0}, + {0x10030, 0x0007B4CD}, + {0x10030, 0x0007B8CA}, + {0x10030, 0x0007BC07}, + {0x10030, 0x0007C004}, + {0x100EE, 0x00000000}, + {0x0EF, 0x00002000}, + {0x033, 0x00000008}, + {0x03F, 0x00000004}, + {0x033, 0x00000009}, + {0x03F, 0x00000003}, + {0x033, 0x0000000A}, + {0x03F, 0x00000003}, + {0x033, 0x0000000B}, + {0x03F, 0x00000002}, + {0x033, 0x0000000C}, + {0x03F, 0x00000002}, + {0x033, 0x0000000D}, + {0x03F, 0x00000002}, + {0x033, 0x0000000E}, + {0x03F, 0x00000002}, + {0x033, 0x0000000F}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00040000}, + {0x030, 0x000109B7}, + {0x0EB, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00050002}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00008001}, + {0x033, 0x00000025}, + {0x03F, 0x00008002}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x03F, 0x00050002}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00008001}, + {0x033, 0x0000002D}, + {0x03F, 0x00008002}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x03F, 0x00050002}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00008001}, + {0x033, 0x00000035}, + {0x03F, 0x00008002}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x03F, 0x00050002}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00008001}, + {0x033, 0x00000065}, + {0x03F, 0x00008002}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x03F, 0x00050002}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00008001}, + {0x033, 0x0000006D}, + {0x03F, 0x00008002}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x03F, 0x00050002}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00060032}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00008001}, + {0x033, 0x00000075}, + {0x03F, 0x00008002}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x03F, 0x00050002}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00060032}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00060032}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00008001}, + {0x033, 0x0000007D}, + {0x03F, 0x00008002}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A0}, + {0x03F, 0x00050002}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00008001}, + {0x033, 0x000000A5}, + {0x03F, 0x00008002}, + {0x033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A8}, + {0x03F, 0x00050002}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00008001}, + {0x033, 0x000000AD}, + {0x03F, 0x00008002}, + {0x033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000B0}, + {0x03F, 0x00050002}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00008001}, + {0x033, 0x000000B5}, + {0x03F, 0x00008002}, + {0x033, 0x000000B6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000B7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E0}, + {0x03F, 0x00050002}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00008001}, + {0x033, 0x000000E5}, + {0x03F, 0x00008002}, + {0x033, 0x000000E6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E8}, + {0x03F, 0x00050002}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00008001}, + {0x033, 0x000000ED}, + {0x03F, 0x00008002}, + {0x033, 0x000000EE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000EF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F0}, + {0x03F, 0x00050002}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00008001}, + {0x033, 0x000000F5}, + {0x03F, 0x00008002}, + {0x033, 0x000000F6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F8}, + {0x03F, 0x00050002}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00008001}, + {0x033, 0x000000FD}, + {0x03F, 0x00008002}, + {0x033, 0x000000FE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000120}, + {0x03F, 0x00050002}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00008001}, + {0x033, 0x00000125}, + {0x03F, 0x00008002}, + {0x033, 0x00000126}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000127}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000128}, + {0x03F, 0x00050002}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00008001}, + {0x033, 0x0000012D}, + {0x03F, 0x00008002}, + {0x033, 0x0000012E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000012F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000130}, + {0x03F, 0x00050002}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00008001}, + {0x033, 0x00000135}, + {0x03F, 0x00008002}, + {0x033, 0x00000136}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000137}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000160}, + {0x03F, 0x00050002}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00008001}, + {0x033, 0x00000165}, + {0x03F, 0x00008002}, + {0x033, 0x00000166}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000167}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000168}, + {0x03F, 0x00050002}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00008001}, + {0x033, 0x0000016D}, + {0x03F, 0x00008002}, + {0x033, 0x0000016E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000016F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000170}, + {0x03F, 0x00050002}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00008001}, + {0x033, 0x00000175}, + {0x03F, 0x00008002}, + {0x033, 0x00000176}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000177}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000178}, + {0x03F, 0x00050002}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00008001}, + {0x033, 0x0000017D}, + {0x03F, 0x00008002}, + {0x033, 0x0000017E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000017F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A0}, + {0x03F, 0x00050002}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00008001}, + {0x033, 0x000001A5}, + {0x03F, 0x00008002}, + {0x033, 0x000001A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A8}, + {0x03F, 0x00050002}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00008001}, + {0x033, 0x000001AD}, + {0x03F, 0x00008002}, + {0x033, 0x000001AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001B0}, + {0x03F, 0x00050002}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00008001}, + {0x033, 0x000001B5}, + {0x03F, 0x00008002}, + {0x033, 0x000001B6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001B7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E0}, + {0x03F, 0x00050002}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00008001}, + {0x033, 0x000001E5}, + {0x03F, 0x00008002}, + {0x033, 0x000001E6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E8}, + {0x03F, 0x00050002}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00008001}, + {0x033, 0x000001ED}, + {0x03F, 0x00008002}, + {0x033, 0x000001EE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001EF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F0}, + {0x03F, 0x00050002}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00008001}, + {0x033, 0x000001F5}, + {0x03F, 0x00008002}, + {0x033, 0x000001F6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F8}, + {0x03F, 0x00050002}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00008001}, + {0x033, 0x000001FD}, + {0x03F, 0x00008002}, + {0x033, 0x000001FE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x10005, 0x00000001}, + {0x100EE, 0x00000400}, + {0x10030, 0x00000000}, + {0x10030, 0x00001000}, + {0x10030, 0x00002000}, + {0x10030, 0x00003000}, + {0x10030, 0x00004000}, + {0x10030, 0x00005000}, + {0x10030, 0x00006003}, + {0x10030, 0x00007003}, + {0x10030, 0x00008000}, + {0x10030, 0x00009000}, + {0x10030, 0x0000A000}, + {0x10030, 0x0000B000}, + {0x10030, 0x0000C000}, + {0x10030, 0x0000D000}, + {0x10030, 0x0000E003}, + {0x10030, 0x0000F003}, + {0x10030, 0x00010000}, + {0x10030, 0x00011000}, + {0x10030, 0x00012000}, + {0x10030, 0x00013000}, + {0x10030, 0x00014000}, + {0x10030, 0x00015000}, + {0x10030, 0x00016003}, + {0x10030, 0x00017003}, + {0x10030, 0x00018000}, + {0x10030, 0x00019000}, + {0x10030, 0x0001A000}, + {0x10030, 0x0001B000}, + {0x10030, 0x0001C000}, + {0x10030, 0x0001D000}, + {0x10030, 0x0001E003}, + {0x10030, 0x0001F003}, + {0x10030, 0x00020000}, + {0x10030, 0x00021000}, + {0x10030, 0x00022000}, + {0x10030, 0x00023000}, + {0x10030, 0x00024000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00025000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00026003}, + {0x10030, 0x00027003}, + {0x10030, 0x00028000}, + {0x10030, 0x00029000}, + {0x10030, 0x0002A000}, + {0x10030, 0x0002B000}, + {0x10030, 0x0002C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0002E003}, + {0x10030, 0x0002F003}, + {0x10030, 0x00030000}, + {0x10030, 0x00031000}, + {0x10030, 0x00032000}, + {0x10030, 0x00033000}, + {0x10030, 0x00034000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00035000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00036003}, + {0x10030, 0x00037003}, + {0x10030, 0x00038000}, + {0x10030, 0x00039000}, + {0x10030, 0x0003A000}, + {0x10030, 0x0003B000}, + {0x10030, 0x0003C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0003E003}, + {0x10030, 0x0003F003}, + {0x10030, 0x00060000}, + {0x10030, 0x00061000}, + {0x10030, 0x00062000}, + {0x10030, 0x00063000}, + {0x10030, 0x00064000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00067003}, + {0x10030, 0x00068000}, + {0x10030, 0x00069000}, + {0x10030, 0x0006A000}, + {0x10030, 0x0006B000}, + {0x10030, 0x0006C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0006F003}, + {0x10030, 0x00070000}, + {0x10030, 0x00071000}, + {0x10030, 0x00072000}, + {0x10030, 0x00073000}, + {0x10030, 0x00074000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00077003}, + {0x10030, 0x00078000}, + {0x10030, 0x00079000}, + {0x10030, 0x0007A000}, + {0x10030, 0x0007B000}, + {0x10030, 0x0007C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0007F003}, + {0x100EE, 0x00000000}, + {0x0FE, 0x00000063}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_radiob_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0320000, 0x00000002}, + {0xF0330000, 0x00000003}, + {0xF0340000, 0x00000004}, + {0xF0350000, 0x00000005}, + {0xF0360000, 0x00000006}, + {0xF0010001, 0x00000007}, + {0xF0020001, 0x00000008}, + {0xF0030001, 0x00000009}, + {0xF0040001, 0x0000000A}, + {0xF0050001, 0x0000000B}, + {0xF0070001, 0x0000000C}, + {0xF0150001, 0x0000000D}, + {0xF0160001, 0x0000000E}, + {0xF0320001, 0x0000000F}, + {0xF0330001, 0x00000010}, + {0xF0340001, 0x00000011}, + {0xF0350001, 0x00000012}, + {0xF0360001, 0x00000013}, + {0xF03F0001, 0x00000014}, + {0xF0400001, 0x00000015}, + {0x005, 0x00000000}, + {0x10005, 0x00000000}, + {0x0B9, 0x00020440}, + {0x000, 0x00030001}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x0A3, 0x000B9204}, + {0x0AD, 0x00091E0F}, + {0x05D, 0x00001012}, + {0x05C, 0x00079C5C}, + {0x062, 0x00055220}, + {0x0D3, 0x00000103}, + {0x05F, 0x00000038}, + {0x097, 0x00043200}, + {0x0A6, 0x00066DB7}, + {0x0EF, 0x00004000}, + {0x033, 0x00000005}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000004}, + {0x03E, 0x00000000}, + {0x03F, 0x00000400}, + {0x033, 0x00000003}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000002}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x00000001}, + {0x03E, 0x00000000}, + {0x03F, 0x00001A00}, + {0x033, 0x00000000}, + {0x03E, 0x00000000}, + {0x03F, 0x00002900}, + {0x033, 0x0000000D}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x0000000C}, + {0x03E, 0x00000000}, + {0x03F, 0x00000400}, + {0x033, 0x0000000B}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x0000000A}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x00000009}, + {0x03E, 0x00000000}, + {0x03F, 0x00001A00}, + {0x033, 0x00000008}, + {0x03E, 0x00000000}, + {0x03F, 0x00002900}, + {0x033, 0x00000015}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000014}, + {0x03E, 0x00000000}, + {0x03F, 0x00000400}, + {0x033, 0x00000013}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000012}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x00000011}, + {0x03E, 0x00000000}, + {0x03F, 0x00001A00}, + {0x033, 0x00000010}, + {0x03E, 0x00000000}, + {0x03F, 0x00002900}, + {0x0EF, 0x00000000}, + {0x10055, 0x00080080}, + {0x000, 0x00033C01}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x096, 0x00015200}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0xA0000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0xB0000000, 0x00000000}, + {0x057, 0x0000D589}, + {0x05A, 0x0007F0F8}, + {0x043, 0x00005000}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0xA0000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0xB0000000, 0x00000000}, + {0x0EB, 0x00000000}, + {0x030, 0x000109B0}, + {0x030, 0x000189B0}, + {0x0EB, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x033, 0x00000004}, + {0x03F, 0x00000017}, + {0x033, 0x00000005}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000007}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000017}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000007}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00060001}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00000001}, + {0x033, 0x00000025}, + {0x03F, 0x00000002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00060001}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00000001}, + {0x033, 0x0000002D}, + {0x03F, 0x00000002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00060001}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00000001}, + {0x033, 0x00000035}, + {0x03F, 0x00000002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00060001}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00000001}, + {0x033, 0x00000065}, + {0x03F, 0x00000002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00060001}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00000001}, + {0x033, 0x0000006D}, + {0x03F, 0x00000002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00060001}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00000001}, + {0x033, 0x00000075}, + {0x03F, 0x00000002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00060001}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00000001}, + {0x033, 0x0000007D}, + {0x03F, 0x00000002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00060001}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00000001}, + {0x033, 0x000000A5}, + {0x03F, 0x00000002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00060001}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00000001}, + {0x033, 0x000000AD}, + {0x03F, 0x00000002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00060001}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00000001}, + {0x033, 0x000000B5}, + {0x03F, 0x00000002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00060001}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00000001}, + {0x033, 0x000000E5}, + {0x03F, 0x00000002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00060001}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00000001}, + {0x033, 0x000000ED}, + {0x03F, 0x00000002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00060001}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00000001}, + {0x033, 0x000000F5}, + {0x03F, 0x00000002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00060001}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00000001}, + {0x033, 0x000000FD}, + {0x03F, 0x00000002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00060001}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00000001}, + {0x033, 0x00000125}, + {0x03F, 0x00000002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00060001}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00000001}, + {0x033, 0x0000012D}, + {0x03F, 0x00000002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00060001}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00000001}, + {0x033, 0x00000135}, + {0x03F, 0x00000002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00060001}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00000001}, + {0x033, 0x00000165}, + {0x03F, 0x00000002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00060001}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00000001}, + {0x033, 0x0000016D}, + {0x03F, 0x00000002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00060001}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00000001}, + {0x033, 0x00000175}, + {0x03F, 0x00000002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00060001}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00000001}, + {0x033, 0x0000017D}, + {0x03F, 0x00000002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00060001}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00000001}, + {0x033, 0x000001A5}, + {0x03F, 0x00000002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00060001}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00000001}, + {0x033, 0x000001AD}, + {0x03F, 0x00000002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00060001}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00000001}, + {0x033, 0x000001B5}, + {0x03F, 0x00000002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00060001}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00000001}, + {0x033, 0x000001E5}, + {0x03F, 0x00000002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00060001}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00000001}, + {0x033, 0x000001ED}, + {0x03F, 0x00000002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00060001}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00000001}, + {0x033, 0x000001F5}, + {0x03F, 0x00000002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00060001}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00000001}, + {0x033, 0x000001FD}, + {0x03F, 0x00000002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000001}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000002}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000003}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000004}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000005}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000006}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000007}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000008}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000009}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000B}, + {0x03F, 0x0000AFFF}, + {0x033, 0x0000000C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000010}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000011}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000012}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000013}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000014}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000017}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000018}, + {0x03F, 0x0000FBFF}, + {0x033, 0x00000019}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000020}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000021}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000022}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000023}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000024}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000025}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000026}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000027}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000028}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000029}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000030}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000031}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000032}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000033}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000034}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000035}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000036}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000037}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000038}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000039}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000003A}, + {0x03F, 0x0000EFFF}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000000}, + {0x03F, 0x00004344}, + {0x033, 0x00000001}, + {0x03F, 0x00004344}, + {0x033, 0x00000002}, + {0x03F, 0x00004344}, + {0x033, 0x00000003}, + {0x03F, 0x00004344}, + {0x033, 0x00000004}, + {0x03F, 0x00004344}, + {0x033, 0x00000005}, + {0x03F, 0x00004344}, + {0x033, 0x00000006}, + {0x03F, 0x00004344}, + {0x033, 0x00000007}, + {0x03F, 0x00004344}, + {0x033, 0x00000008}, + {0x03F, 0x00004344}, + {0x033, 0x00000009}, + {0x03F, 0x00004344}, + {0x033, 0x0000000A}, + {0x03F, 0x00004344}, + {0x033, 0x0000000B}, + {0x03F, 0x00004344}, + {0x033, 0x00000010}, + {0x03F, 0x00004344}, + {0x033, 0x00000011}, + {0x03F, 0x00004344}, + {0x033, 0x00000012}, + {0x03F, 0x00004344}, + {0x033, 0x00000013}, + {0x03F, 0x00004344}, + {0x033, 0x00000014}, + {0x03F, 0x00004344}, + {0x033, 0x00000015}, + {0x03F, 0x00004344}, + {0x033, 0x00000016}, + {0x03F, 0x00004344}, + {0x033, 0x00000017}, + {0x03F, 0x00004344}, + {0x033, 0x00000018}, + {0x03F, 0x00004344}, + {0x033, 0x00000019}, + {0x03F, 0x00004344}, + {0x033, 0x0000001A}, + {0x03F, 0x00004344}, + {0x033, 0x0000001B}, + {0x03F, 0x00004344}, + {0x033, 0x0000001C}, + {0x03F, 0x00004344}, + {0x033, 0x0000001D}, + {0x03F, 0x00004344}, + {0x033, 0x0000001E}, + {0x03F, 0x00004344}, + {0x033, 0x0000001F}, + {0x03F, 0x00004344}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000020}, + {0x033, 0x00000010}, + {0x03F, 0x00000200}, + {0x033, 0x00000011}, + {0x03F, 0x00000200}, + {0x033, 0x00000012}, + {0x03F, 0x00000200}, + {0x033, 0x00000013}, + {0x03F, 0x00000200}, + {0x033, 0x00000020}, + {0x03F, 0x00000200}, + {0x033, 0x00000021}, + {0x03F, 0x00000200}, + {0x033, 0x00000022}, + {0x03F, 0x00000200}, + {0x033, 0x00000023}, + {0x03F, 0x00000200}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000085ED}, + {0x030, 0x000105CC}, + {0x030, 0x000184AA}, + {0x030, 0x00020388}, + {0x030, 0x00028377}, + {0x030, 0x00030377}, + {0x030, 0x00038255}, + {0x030, 0x00040244}, + {0x030, 0x00048133}, + {0x030, 0x00050112}, + {0x030, 0x00058101}, + {0x030, 0x00060001}, + {0xA0000000, 0x00000000}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0xB0000000, 0x00000000}, + {0x030, 0x00068000}, + {0x030, 0x00070000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000004}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000005}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000006}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x00000007}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000008}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000009}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x0000000B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000000C}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000D}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x0000000F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000010}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000011}, + {0x03E, 0x0000001B}, + {0x03F, 0x00022A58}, + {0x033, 0x00000012}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x00000013}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000014}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000015}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x00000016}, + {0x03E, 0x0000001C}, + {0x03F, 0x00023958}, + {0x033, 0x00000017}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000018}, + {0x03E, 0x00000013}, + {0x03F, 0x00029858}, + {0x033, 0x00000019}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x0000001A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000001D}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x0000001E}, + {0x03E, 0x00000013}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001F}, + {0x03E, 0x00000013}, + {0x03F, 0x00023A58}, + {0x033, 0x00000020}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000021}, + {0x03E, 0x0000001C}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000022}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000023}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000024}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000025}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000026}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000027}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000028}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000029}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000030}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000031}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000032}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000033}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000034}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000035}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000036}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000037}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000038}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000039}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000031}, + {0x033, 0x00000001}, + {0x03F, 0x00000023}, + {0x033, 0x00000002}, + {0x03F, 0x00000015}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EC, 0x00000400}, + {0x033, 0x00000003}, + {0x03F, 0x00000030}, + {0x033, 0x00000004}, + {0x03F, 0x00000021}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x0A7, 0x00080308}, + {0x066, 0x00006000}, + {0x0EF, 0x00000400}, + {0x030, 0x000001FF}, + {0x030, 0x000081FF}, + {0x030, 0x000101FF}, + {0x030, 0x000181FF}, + {0x030, 0x000201FF}, + {0x030, 0x000281FF}, + {0x030, 0x0003017F}, + {0x030, 0x000380FB}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0380}, + {0x06B, 0x00003CA0}, + {0x06F, 0x000C01FC}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0380}, + {0x06B, 0x00003CA0}, + {0x06F, 0x000C01FC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0xA0000000, 0x00000000}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0xB0000000, 0x00000000}, + {0x05E, 0x0000001F}, + {0x0EF, 0x00000200}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x030, 0x0003E207}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0xA0000000, 0x00000000}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00080000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0000803C}, + {0x030, 0x0001003C}, + {0x030, 0x0001803C}, + {0x030, 0x0002003C}, + {0x030, 0x0002803C}, + {0x030, 0x0003003C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0000803C}, + {0x030, 0x0001003C}, + {0x030, 0x0001803C}, + {0x030, 0x0002003C}, + {0x030, 0x0002803C}, + {0x030, 0x0003003C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0xA0000000, 0x00000000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0xB0000000, 0x00000000}, + {0x030, 0x0003803C}, + {0x030, 0x0004003C}, + {0x030, 0x0004803C}, + {0x030, 0x0005003C}, + {0x030, 0x0005803C}, + {0x030, 0x0006003C}, + {0x030, 0x0006803C}, + {0x030, 0x0007003C}, + {0x0EB, 0x00000000}, + {0x094, 0x000000FC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0xA0000000, 0x00000000}, + {0x095, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000020}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000024}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000034}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000038}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000021}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000025}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000029}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000031}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000035}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000039}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000022}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000032}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000003E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000064}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000074}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000061}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000065}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000069}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000071}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000075}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000079}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000062}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000072}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000003E7}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000003E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x03F, 0x000002E7}, + {0x033, 0x0000007F}, + {0x03F, 0x000003E7}, + {0x0EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201EF}, + {0x10030, 0x000205E9}, + {0x10030, 0x000209E3}, + {0x10030, 0x00020DA3}, + {0x10030, 0x00021161}, + {0x10030, 0x0002155B}, + {0x10030, 0x0002191F}, + {0x10030, 0x00021D19}, + {0x10030, 0x000220E1}, + {0x10030, 0x000224DB}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1B}, + {0x10030, 0x00024015}, + {0x10030, 0x0002440F}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285E7}, + {0x10030, 0x000289A7}, + {0x10030, 0x00028D65}, + {0x10030, 0x0002915F}, + {0x10030, 0x00029523}, + {0x10030, 0x0002991D}, + {0x10030, 0x00029CE5}, + {0x10030, 0x0002A0DF}, + {0x10030, 0x0002A4A7}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC67}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B427}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC19}, + {0x10030, 0x0002C013}, + {0x10030, 0x0002C40D}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305E7}, + {0x10030, 0x000309A7}, + {0x10030, 0x00030D65}, + {0x10030, 0x0003115F}, + {0x10030, 0x00031525}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031CE7}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324A9}, + {0x10030, 0x000328A3}, + {0x10030, 0x00032C69}, + {0x10030, 0x00033063}, + {0x10030, 0x00033429}, + {0x10030, 0x00033823}, + {0x10030, 0x00033C1D}, + {0x10030, 0x00034013}, + {0x10030, 0x0003440D}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061525}, + {0x10030, 0x0006191F}, + {0x10030, 0x00061CE7}, + {0x10030, 0x000620E1}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628A3}, + {0x10030, 0x00062C69}, + {0x10030, 0x00063063}, + {0x10030, 0x00063429}, + {0x10030, 0x00063823}, + {0x10030, 0x00063C1D}, + {0x10030, 0x00064013}, + {0x10030, 0x0006440D}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069523}, + {0x10030, 0x0006991D}, + {0x10030, 0x00069CE5}, + {0x10030, 0x0006A0DF}, + {0x10030, 0x0006A4A7}, + {0x10030, 0x0006A8A1}, + {0x10030, 0x0006AC67}, + {0x10030, 0x0006B061}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C40D}, + {0x10030, 0x000701F1}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071523}, + {0x10030, 0x0007191D}, + {0x10030, 0x00071D17}, + {0x10030, 0x00072111}, + {0x10030, 0x000724D9}, + {0x10030, 0x000728D3}, + {0x10030, 0x00072C67}, + {0x10030, 0x00073061}, + {0x10030, 0x00073427}, + {0x10030, 0x00073821}, + {0x10030, 0x00073C1B}, + {0x10030, 0x00074015}, + {0x10030, 0x0007440D}, + {0x10030, 0x000781F1}, + {0x10030, 0x000785EB}, + {0x10030, 0x000789E5}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079923}, + {0x10030, 0x00079D1D}, + {0x10030, 0x0007A117}, + {0x10030, 0x0007A4DD}, + {0x10030, 0x0007A8D7}, + {0x10030, 0x0007AC9D}, + {0x10030, 0x0007B063}, + {0x10030, 0x0007B45D}, + {0x10030, 0x0007B857}, + {0x10030, 0x0007BC1D}, + {0x10030, 0x0007C017}, + {0x10030, 0x0007C40F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201A7}, + {0x10030, 0x000205A1}, + {0x10030, 0x0002099B}, + {0x10030, 0x00020D95}, + {0x10030, 0x0002115B}, + {0x10030, 0x00021555}, + {0x10030, 0x00021921}, + {0x10030, 0x00021D1B}, + {0x10030, 0x000220E3}, + {0x10030, 0x000224DD}, + {0x10030, 0x000228A3}, + {0x10030, 0x00022C9D}, + {0x10030, 0x00023063}, + {0x10030, 0x0002345D}, + {0x10030, 0x00023823}, + {0x10030, 0x00023C1D}, + {0x10030, 0x00024017}, + {0x10030, 0x00024411}, + {0x10030, 0x000281A9}, + {0x10030, 0x000285A3}, + {0x10030, 0x0002899D}, + {0x10030, 0x00028D97}, + {0x10030, 0x0002915D}, + {0x10030, 0x00029557}, + {0x10030, 0x0002991F}, + {0x10030, 0x00029D19}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DB}, + {0x10030, 0x0002A8A1}, + {0x10030, 0x0002AC9B}, + {0x10030, 0x0002B061}, + {0x10030, 0x0002B45B}, + {0x10030, 0x0002B821}, + {0x10030, 0x0002BC1B}, + {0x10030, 0x0002C015}, + {0x10030, 0x0002C40F}, + {0x10030, 0x000301A9}, + {0x10030, 0x000305A3}, + {0x10030, 0x0003099D}, + {0x10030, 0x00030D97}, + {0x10030, 0x0003115D}, + {0x10030, 0x00031557}, + {0x10030, 0x0003191F}, + {0x10030, 0x00031D19}, + {0x10030, 0x000320E1}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328A1}, + {0x10030, 0x00032C9B}, + {0x10030, 0x00033061}, + {0x10030, 0x0003345B}, + {0x10030, 0x00033821}, + {0x10030, 0x00033C1B}, + {0x10030, 0x00034015}, + {0x10030, 0x0003440F}, + {0x10030, 0x000601F1}, + {0x10030, 0x000605E9}, + {0x10030, 0x000609A9}, + {0x10030, 0x00060D65}, + {0x10030, 0x0006115F}, + {0x10030, 0x00061527}, + {0x10030, 0x00061921}, + {0x10030, 0x00061CE9}, + {0x10030, 0x000620E3}, + {0x10030, 0x000624DD}, + {0x10030, 0x000628A5}, + {0x10030, 0x00062C6B}, + {0x10030, 0x00063065}, + {0x10030, 0x0006342B}, + {0x10030, 0x00063825}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681EF}, + {0x10030, 0x000685E7}, + {0x10030, 0x000689A7}, + {0x10030, 0x00068D61}, + {0x10030, 0x0006915B}, + {0x10030, 0x00069525}, + {0x10030, 0x0006991F}, + {0x10030, 0x00069CE7}, + {0x10030, 0x0006A0E1}, + {0x10030, 0x0006A4A9}, + {0x10030, 0x0006A8A3}, + {0x10030, 0x0006AC69}, + {0x10030, 0x0006B063}, + {0x10030, 0x0006B429}, + {0x10030, 0x0006B823}, + {0x10030, 0x0006BC1D}, + {0x10030, 0x0006C017}, + {0x10030, 0x0006C411}, + {0x10030, 0x000701EF}, + {0x10030, 0x000705E9}, + {0x10030, 0x000709A9}, + {0x10030, 0x00070D63}, + {0x10030, 0x0007115D}, + {0x10030, 0x00071525}, + {0x10030, 0x0007191F}, + {0x10030, 0x00071D19}, + {0x10030, 0x000720E1}, + {0x10030, 0x000724DB}, + {0x10030, 0x000728A3}, + {0x10030, 0x00072C69}, + {0x10030, 0x00073063}, + {0x10030, 0x00073429}, + {0x10030, 0x00073823}, + {0x10030, 0x00073C1D}, + {0x10030, 0x00074017}, + {0x10030, 0x00074411}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA1}, + {0x10030, 0x0007915F}, + {0x10030, 0x00079559}, + {0x10030, 0x0007991F}, + {0x10030, 0x00079D19}, + {0x10030, 0x0007A0DF}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D3}, + {0x10030, 0x0007AC99}, + {0x10030, 0x0007B05F}, + {0x10030, 0x0007B459}, + {0x10030, 0x0007B81F}, + {0x10030, 0x0007BC19}, + {0x10030, 0x0007C013}, + {0x10030, 0x0007C40D}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000000FC}, + {0x10030, 0x000004F9}, + {0x10030, 0x000008F6}, + {0x10030, 0x00000CF3}, + {0x10030, 0x000010F0}, + {0x10030, 0x000014ED}, + {0x10030, 0x000018AC}, + {0x10030, 0x00001CA9}, + {0x10030, 0x00002069}, + {0x10030, 0x00002466}, + {0x10030, 0x00002829}, + {0x10030, 0x00002C26}, + {0x10030, 0x00003023}, + {0x10030, 0x00003420}, + {0x10030, 0x0000381D}, + {0x10030, 0x00003C1A}, + {0x10030, 0x00004017}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x0002240D}, + {0x10030, 0x0002280A}, + {0x10030, 0x00022C07}, + {0x10030, 0x00023004}, + {0x10030, 0x00023401}, + {0x10030, 0x00023800}, + {0x10030, 0x00023C00}, + {0x10030, 0x00024000}, + {0x10030, 0x000280E7}, + {0x10030, 0x000284E4}, + {0x10030, 0x000288E1}, + {0x10030, 0x00028CDE}, + {0x10030, 0x000290DB}, + {0x10030, 0x000294D8}, + {0x10030, 0x000298D5}, + {0x10030, 0x00029CD2}, + {0x10030, 0x0002A0CF}, + {0x10030, 0x0002A40C}, + {0x10030, 0x0002A809}, + {0x10030, 0x0002AC06}, + {0x10030, 0x0002B003}, + {0x10030, 0x0002B400}, + {0x10030, 0x0002B800}, + {0x10030, 0x0002BC00}, + {0x10030, 0x0002C000}, + {0x10030, 0x000300E7}, + {0x10030, 0x000304E4}, + {0x10030, 0x000308E1}, + {0x10030, 0x00030CDE}, + {0x10030, 0x000310DB}, + {0x10030, 0x000314D8}, + {0x10030, 0x000318D5}, + {0x10030, 0x00031CD2}, + {0x10030, 0x000320CF}, + {0x10030, 0x000324CC}, + {0x10030, 0x00032809}, + {0x10030, 0x00032C06}, + {0x10030, 0x00033003}, + {0x10030, 0x00033400}, + {0x10030, 0x00033800}, + {0x10030, 0x00033C00}, + {0x10030, 0x00034000}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x0002240D}, + {0x10030, 0x0002280A}, + {0x10030, 0x00022C07}, + {0x10030, 0x00023004}, + {0x10030, 0x00023401}, + {0x10030, 0x00023800}, + {0x10030, 0x00023C00}, + {0x10030, 0x00024000}, + {0x10030, 0x000280E7}, + {0x10030, 0x000284E4}, + {0x10030, 0x000288E1}, + {0x10030, 0x00028CDE}, + {0x10030, 0x000290DB}, + {0x10030, 0x000294D8}, + {0x10030, 0x000298D5}, + {0x10030, 0x00029CD2}, + {0x10030, 0x0002A0CF}, + {0x10030, 0x0002A40C}, + {0x10030, 0x0002A809}, + {0x10030, 0x0002AC06}, + {0x10030, 0x0002B003}, + {0x10030, 0x0002B400}, + {0x10030, 0x0002B800}, + {0x10030, 0x0002BC00}, + {0x10030, 0x0002C000}, + {0x10030, 0x000300E7}, + {0x10030, 0x000304E4}, + {0x10030, 0x000308E1}, + {0x10030, 0x00030CDE}, + {0x10030, 0x000310DB}, + {0x10030, 0x000314D8}, + {0x10030, 0x000318D5}, + {0x10030, 0x00031CD2}, + {0x10030, 0x000320CF}, + {0x10030, 0x000324CC}, + {0x10030, 0x00032809}, + {0x10030, 0x00032C06}, + {0x10030, 0x00033003}, + {0x10030, 0x00033400}, + {0x10030, 0x00033800}, + {0x10030, 0x00033C00}, + {0x10030, 0x00034000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000200E8}, + {0x10030, 0x000204E5}, + {0x10030, 0x000208E2}, + {0x10030, 0x00020CDF}, + {0x10030, 0x000210DC}, + {0x10030, 0x000214D9}, + {0x10030, 0x000218D6}, + {0x10030, 0x00021CD3}, + {0x10030, 0x000220D0}, + {0x10030, 0x000224CD}, + {0x10030, 0x000228CD}, + {0x10030, 0x00022CCD}, + {0x10030, 0x000230CD}, + {0x10030, 0x000234CD}, + {0x10030, 0x000238CD}, + {0x10030, 0x00023CCD}, + {0x10030, 0x000240CD}, + {0x10030, 0x000280E8}, + {0x10030, 0x000284E5}, + {0x10030, 0x000288E2}, + {0x10030, 0x00028CDF}, + {0x10030, 0x000290DC}, + {0x10030, 0x000294D9}, + {0x10030, 0x000298D6}, + {0x10030, 0x00029CD3}, + {0x10030, 0x0002A0D0}, + {0x10030, 0x0002A4CD}, + {0x10030, 0x0002A8CD}, + {0x10030, 0x0002ACCD}, + {0x10030, 0x0002B0CD}, + {0x10030, 0x0002B4CD}, + {0x10030, 0x0002B8CD}, + {0x10030, 0x0002BCCD}, + {0x10030, 0x0002C0CD}, + {0x10030, 0x000300E8}, + {0x10030, 0x000304E5}, + {0x10030, 0x000308E2}, + {0x10030, 0x00030CDF}, + {0x10030, 0x000310DC}, + {0x10030, 0x000314D9}, + {0x10030, 0x000318D6}, + {0x10030, 0x00031CD3}, + {0x10030, 0x000320D0}, + {0x10030, 0x000324CD}, + {0x10030, 0x000328CD}, + {0x10030, 0x00032CCD}, + {0x10030, 0x000330CD}, + {0x10030, 0x000334CD}, + {0x10030, 0x000338CD}, + {0x10030, 0x00033CCD}, + {0x10030, 0x000340CD}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000200FA}, + {0x10030, 0x000204F7}, + {0x10030, 0x000208F4}, + {0x10030, 0x00020CF1}, + {0x10030, 0x000210EE}, + {0x10030, 0x000214EB}, + {0x10030, 0x000218E8}, + {0x10030, 0x00021CE5}, + {0x10030, 0x000220E2}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228DC}, + {0x10030, 0x00022CD9}, + {0x10030, 0x000230D6}, + {0x10030, 0x000234D3}, + {0x10030, 0x000238D0}, + {0x10030, 0x00023C0D}, + {0x10030, 0x0002400A}, + {0x10030, 0x000280F9}, + {0x10030, 0x000284F6}, + {0x10030, 0x000288F3}, + {0x10030, 0x00028CF0}, + {0x10030, 0x000290ED}, + {0x10030, 0x000294EA}, + {0x10030, 0x000298E7}, + {0x10030, 0x00029CE4}, + {0x10030, 0x0002A0E1}, + {0x10030, 0x0002A4DE}, + {0x10030, 0x0002A8DB}, + {0x10030, 0x0002ACD8}, + {0x10030, 0x0002B0D5}, + {0x10030, 0x0002B4D2}, + {0x10030, 0x0002B8CF}, + {0x10030, 0x0002BC0C}, + {0x10030, 0x0002C009}, + {0x10030, 0x000300F6}, + {0x10030, 0x000304F3}, + {0x10030, 0x000308F0}, + {0x10030, 0x00030CED}, + {0x10030, 0x000310EA}, + {0x10030, 0x000314E7}, + {0x10030, 0x000318E4}, + {0x10030, 0x00031CE1}, + {0x10030, 0x000320DE}, + {0x10030, 0x000324DB}, + {0x10030, 0x000328D8}, + {0x10030, 0x00032CD5}, + {0x10030, 0x000330D2}, + {0x10030, 0x000334CF}, + {0x10030, 0x000338CC}, + {0x10030, 0x00033C09}, + {0x10030, 0x00034006}, + {0xB0000000, 0x00000000}, + {0x10030, 0x000600F6}, + {0x10030, 0x000604F3}, + {0x10030, 0x000608F0}, + {0x10030, 0x00060CED}, + {0x10030, 0x000610EA}, + {0x10030, 0x000614E7}, + {0x10030, 0x000618E4}, + {0x10030, 0x00061CE1}, + {0x10030, 0x000620DE}, + {0x10030, 0x000624DB}, + {0x10030, 0x000628D8}, + {0x10030, 0x00062CD5}, + {0x10030, 0x000630D2}, + {0x10030, 0x000634CF}, + {0x10030, 0x000638CC}, + {0x10030, 0x00063C09}, + {0x10030, 0x00064006}, + {0x10030, 0x000680F5}, + {0x10030, 0x000684F2}, + {0x10030, 0x000688EF}, + {0x10030, 0x00068CEC}, + {0x10030, 0x000690E9}, + {0x10030, 0x000694E6}, + {0x10030, 0x000698E3}, + {0x10030, 0x00069CE0}, + {0x10030, 0x0006A0DD}, + {0x10030, 0x0006A4DA}, + {0x10030, 0x0006A8D7}, + {0x10030, 0x0006ACD4}, + {0x10030, 0x0006B0D1}, + {0x10030, 0x0006B4CE}, + {0x10030, 0x0006B8CB}, + {0x10030, 0x0006BC08}, + {0x10030, 0x0006C005}, + {0x10030, 0x000700F5}, + {0x10030, 0x000704F2}, + {0x10030, 0x000708EF}, + {0x10030, 0x00070CEC}, + {0x10030, 0x000710E9}, + {0x10030, 0x000714E6}, + {0x10030, 0x000718E3}, + {0x10030, 0x00071CE0}, + {0x10030, 0x000720DD}, + {0x10030, 0x000724DA}, + {0x10030, 0x000728D7}, + {0x10030, 0x00072CD4}, + {0x10030, 0x000730D1}, + {0x10030, 0x000734CE}, + {0x10030, 0x000738CB}, + {0x10030, 0x00073C08}, + {0x10030, 0x00074005}, + {0x10030, 0x000780F4}, + {0x10030, 0x000784F1}, + {0x10030, 0x000788EE}, + {0x10030, 0x00078CEB}, + {0x10030, 0x000790E8}, + {0x10030, 0x000794E5}, + {0x10030, 0x000798E2}, + {0x10030, 0x00079CDF}, + {0x10030, 0x0007A0DC}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D6}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B0D0}, + {0x10030, 0x0007B4CD}, + {0x10030, 0x0007B8CA}, + {0x10030, 0x0007BC07}, + {0x10030, 0x0007C004}, + {0x100EE, 0x00000000}, + {0x0EF, 0x00002000}, + {0x033, 0x00000008}, + {0x03F, 0x00000004}, + {0x033, 0x00000009}, + {0x03F, 0x00000003}, + {0x033, 0x0000000A}, + {0x03F, 0x00000003}, + {0x033, 0x0000000B}, + {0x03F, 0x00000002}, + {0x033, 0x0000000C}, + {0x03F, 0x00000002}, + {0x033, 0x0000000D}, + {0x03F, 0x00000002}, + {0x033, 0x0000000E}, + {0x03F, 0x00000002}, + {0x033, 0x0000000F}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00040000}, + {0x030, 0x000109B7}, + {0x0EB, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00050002}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00008001}, + {0x033, 0x00000025}, + {0x03F, 0x00008002}, + {0x033, 0x00000026}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000027}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000028}, + {0x03F, 0x00050002}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00008001}, + {0x033, 0x0000002D}, + {0x03F, 0x00008002}, + {0x033, 0x0000002E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000002F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000030}, + {0x03F, 0x00050002}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00008001}, + {0x033, 0x00000035}, + {0x03F, 0x00008002}, + {0x033, 0x00000036}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000037}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000060}, + {0x03F, 0x00050002}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00008001}, + {0x033, 0x00000065}, + {0x03F, 0x00008002}, + {0x033, 0x00000066}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000068}, + {0x03F, 0x00050002}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00008001}, + {0x033, 0x0000006D}, + {0x03F, 0x00008002}, + {0x033, 0x0000006E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000070}, + {0x03F, 0x00050002}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00008001}, + {0x033, 0x00000075}, + {0x03F, 0x00008002}, + {0x033, 0x00000076}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000078}, + {0x03F, 0x00050002}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00008001}, + {0x033, 0x0000007D}, + {0x03F, 0x00008002}, + {0x033, 0x0000007E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A0}, + {0x03F, 0x00050002}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00008001}, + {0x033, 0x000000A5}, + {0x03F, 0x00008002}, + {0x033, 0x000000A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000A8}, + {0x03F, 0x00050002}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00008001}, + {0x033, 0x000000AD}, + {0x03F, 0x00008002}, + {0x033, 0x000000AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000B0}, + {0x03F, 0x00050002}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00008001}, + {0x033, 0x000000B5}, + {0x03F, 0x00008002}, + {0x033, 0x000000B6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000B7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E0}, + {0x03F, 0x00050002}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00008001}, + {0x033, 0x000000E5}, + {0x03F, 0x00008002}, + {0x033, 0x000000E6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000E8}, + {0x03F, 0x00050002}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00008001}, + {0x033, 0x000000ED}, + {0x03F, 0x00008002}, + {0x033, 0x000000EE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000EF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F0}, + {0x03F, 0x00050002}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00008001}, + {0x033, 0x000000F5}, + {0x03F, 0x00008002}, + {0x033, 0x000000F6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000F8}, + {0x03F, 0x00050002}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00008001}, + {0x033, 0x000000FD}, + {0x03F, 0x00008002}, + {0x033, 0x000000FE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000000FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000120}, + {0x03F, 0x00050002}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00008001}, + {0x033, 0x00000125}, + {0x03F, 0x00008002}, + {0x033, 0x00000126}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000127}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000128}, + {0x03F, 0x00050002}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00008001}, + {0x033, 0x0000012D}, + {0x03F, 0x00008002}, + {0x033, 0x0000012E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000012F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000130}, + {0x03F, 0x00050002}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00008001}, + {0x033, 0x00000135}, + {0x03F, 0x00008002}, + {0x033, 0x00000136}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000137}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000160}, + {0x03F, 0x00050002}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00008001}, + {0x033, 0x00000165}, + {0x03F, 0x00008002}, + {0x033, 0x00000166}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000167}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000168}, + {0x03F, 0x00050002}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00008001}, + {0x033, 0x0000016D}, + {0x03F, 0x00008002}, + {0x033, 0x0000016E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000016F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000170}, + {0x03F, 0x00050002}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00008001}, + {0x033, 0x00000175}, + {0x03F, 0x00008002}, + {0x033, 0x00000176}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000177}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000178}, + {0x03F, 0x00050002}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00008001}, + {0x033, 0x0000017D}, + {0x03F, 0x00008002}, + {0x033, 0x0000017E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000017F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A0}, + {0x03F, 0x00050002}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00008001}, + {0x033, 0x000001A5}, + {0x03F, 0x00008002}, + {0x033, 0x000001A6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001A8}, + {0x03F, 0x00050002}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00008001}, + {0x033, 0x000001AD}, + {0x03F, 0x00008002}, + {0x033, 0x000001AE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001AF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001B0}, + {0x03F, 0x00050002}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00008001}, + {0x033, 0x000001B5}, + {0x03F, 0x00008002}, + {0x033, 0x000001B6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001B7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E0}, + {0x03F, 0x00050002}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00008001}, + {0x033, 0x000001E5}, + {0x03F, 0x00008002}, + {0x033, 0x000001E6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001E8}, + {0x03F, 0x00050002}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00008001}, + {0x033, 0x000001ED}, + {0x03F, 0x00008002}, + {0x033, 0x000001EE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001EF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F0}, + {0x03F, 0x00050002}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00008001}, + {0x033, 0x000001F5}, + {0x03F, 0x00008002}, + {0x033, 0x000001F6}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F7}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001F8}, + {0x03F, 0x00050002}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00008001}, + {0x033, 0x000001FD}, + {0x03F, 0x00008002}, + {0x033, 0x000001FE}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x033, 0x000001FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00008002}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000003}, + {0xB0000000, 0x00000000}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x10005, 0x00000001}, + {0x100EE, 0x00000400}, + {0x10030, 0x00000000}, + {0x10030, 0x00001000}, + {0x10030, 0x00002000}, + {0x10030, 0x00003000}, + {0x10030, 0x00004000}, + {0x10030, 0x00005000}, + {0x10030, 0x00006003}, + {0x10030, 0x00007003}, + {0x10030, 0x00008000}, + {0x10030, 0x00009000}, + {0x10030, 0x0000A000}, + {0x10030, 0x0000B000}, + {0x10030, 0x0000C000}, + {0x10030, 0x0000D000}, + {0x10030, 0x0000E003}, + {0x10030, 0x0000F003}, + {0x10030, 0x00010000}, + {0x10030, 0x00011000}, + {0x10030, 0x00012000}, + {0x10030, 0x00013000}, + {0x10030, 0x00014000}, + {0x10030, 0x00015000}, + {0x10030, 0x00016003}, + {0x10030, 0x00017003}, + {0x10030, 0x00018000}, + {0x10030, 0x00019000}, + {0x10030, 0x0001A000}, + {0x10030, 0x0001B000}, + {0x10030, 0x0001C000}, + {0x10030, 0x0001D000}, + {0x10030, 0x0001E003}, + {0x10030, 0x0001F003}, + {0x10030, 0x00020000}, + {0x10030, 0x00021000}, + {0x10030, 0x00022000}, + {0x10030, 0x00023000}, + {0x10030, 0x00024000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00025003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00025000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00026003}, + {0x10030, 0x00027003}, + {0x10030, 0x00028000}, + {0x10030, 0x00029000}, + {0x10030, 0x0002A000}, + {0x10030, 0x0002B000}, + {0x10030, 0x0002C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0002D003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0002D000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0002E003}, + {0x10030, 0x0002F003}, + {0x10030, 0x00030000}, + {0x10030, 0x00031000}, + {0x10030, 0x00032000}, + {0x10030, 0x00033000}, + {0x10030, 0x00034000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00035003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00035000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00036003}, + {0x10030, 0x00037003}, + {0x10030, 0x00038000}, + {0x10030, 0x00039000}, + {0x10030, 0x0003A000}, + {0x10030, 0x0003B000}, + {0x10030, 0x0003C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0003D003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0003D000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0003E003}, + {0x10030, 0x0003F003}, + {0x10030, 0x00060000}, + {0x10030, 0x00061000}, + {0x10030, 0x00062000}, + {0x10030, 0x00063000}, + {0x10030, 0x00064000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00065003}, + {0x10030, 0x00066003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00067003}, + {0x10030, 0x00068000}, + {0x10030, 0x00069000}, + {0x10030, 0x0006A000}, + {0x10030, 0x0006B000}, + {0x10030, 0x0006C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0006D003}, + {0x10030, 0x0006E003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0006F003}, + {0x10030, 0x00070000}, + {0x10030, 0x00071000}, + {0x10030, 0x00072000}, + {0x10030, 0x00073000}, + {0x10030, 0x00074000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x00075003}, + {0x10030, 0x00076003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x00077003}, + {0x10030, 0x00078000}, + {0x10030, 0x00079000}, + {0x10030, 0x0007A000}, + {0x10030, 0x0007B000}, + {0x10030, 0x0007C000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x0007D003}, + {0x10030, 0x0007E003}, + {0xA0000000, 0x00000000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0xB0000000, 0x00000000}, + {0x10030, 0x0007F003}, + {0x0ED, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x0000000A}, + {0x033, 0x00000002}, + {0x03F, 0x0000000A}, + {0x033, 0x00000003}, + {0x03F, 0x0000000A}, + {0x033, 0x00000005}, + {0x03F, 0x0000000A}, + {0x033, 0x00000006}, + {0x03F, 0x0000000A}, + {0x033, 0x00000007}, + {0x03F, 0x0000000A}, + {0x0ED, 0x00000000}, + {0x100EE, 0x00000000}, + {0x0FE, 0x00000063}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_nctl_regs[] = { + {0x8008, 0x00000000}, + {0x8000, 0x00000008}, + {0x8004, 0xf0862966}, + {0x800c, 0x78000000}, + {0x8010, 0x88015000}, + {0x8014, 0x80010100}, + {0x8018, 0x10010100}, + {0x801c, 0xa210bc00}, + {0x8020, 0x000403e0}, + {0x8024, 0x00072160}, + {0x8028, 0x00180e00}, + {0x8030, 0x400000c0}, + {0x8034, 0x11000830}, + {0x8038, 0x00000009}, + {0x803c, 0x00000008}, + {0x8040, 0x00000046}, + {0x8044, 0x0010001f}, + {0x8048, 0xf0000003}, + {0x804c, 0x62ac6162}, + {0x8050, 0xf2acf162}, + {0x8054, 0x62ac6162}, + {0x8058, 0xf2acf162}, + {0x805c, 0x150c0b02}, + {0x8060, 0x150c0b02}, + {0x8064, 0x2aa00047}, + {0x8074, 0x80000000}, + {0x807c, 0x000000ee}, + {0x8088, 0x80000000}, + {0x808c, 0x00000000}, + {0x80b0, 0x00000000}, + {0x80d0, 0x00000000}, + {0x80ec, 0x00000002}, + {0x8098, 0x0000ff00}, + {0x8070, 0x00e80000}, + {0x80b0, 0xffe00fff}, + {0x809c, 0x0000001f}, + {0x80b8, 0x00001000}, + {0x80bc, 0x0005001d}, + {0x810c, 0x33112211}, + {0x8110, 0x33112211}, + {0x8114, 0x00000000}, + {0x8120, 0x10010000}, + {0x8124, 0x00000000}, + {0x8128, 0x00000200}, + {0x812c, 0x0000c000}, + {0x8138, 0x40000000}, + {0x813c, 0x40000000}, + {0x8140, 0x00000000}, + {0x8144, 0x0b040b03}, + {0x8148, 0x0a040b04}, + {0x814c, 0x0a040b04}, + {0x8150, 0xe4e40000}, + {0x8158, 0xffffffff}, + {0x815c, 0xffffffff}, + {0x8160, 0xffffffff}, + {0x8164, 0xffffffff}, + {0x8168, 0xffffffff}, + {0x816c, 0x1fffffff}, + {0x81cc, 0x00000000}, + {0x81dc, 0x00000002}, + {0x81e0, 0x00000000}, + {0x81e4, 0x00000001}, + {0x81a0, 0x00000000}, + {0x81ac, 0x3fc20400}, + {0x81b0, 0x3f914100}, + {0x81bc, 0x0000005b}, + {0x81c0, 0x0000005b}, + {0x81b4, 0x01e0f078}, + {0x81b8, 0x01e0f078}, + {0x81f0, 0x0000f078}, + {0x820c, 0x33112211}, + {0x8210, 0x33112211}, + {0x8214, 0x00000000}, + {0x8220, 0x10010000}, + {0x8224, 0x00000000}, + {0x8228, 0x00000200}, + {0x822c, 0x0000d000}, + {0x8238, 0x40000000}, + {0x823c, 0x40000000}, + {0x8240, 0x00000000}, + {0x8244, 0x0b040b03}, + {0x8248, 0x0a040b04}, + {0x824c, 0x0a040b04}, + {0x8250, 0xe4e40000}, + {0x8258, 0xffffffff}, + {0x825c, 0xffffffff}, + {0x8260, 0xffffffff}, + {0x8264, 0xffffffff}, + {0x8268, 0xffffffff}, + {0x826c, 0x1fffffff}, + {0x82cc, 0x00000000}, + {0x82dc, 0x00000002}, + {0x82e0, 0x00100000}, + {0x82e4, 0x00000001}, + {0x82a0, 0x00000000}, + {0x82ac, 0x3fc20400}, + {0x82b0, 0x3f914100}, + {0x82bc, 0x0000005b}, + {0x82c0, 0x0000005b}, + {0x82b4, 0x01e0f078}, + {0x82b8, 0x01e0f078}, + {0x82f0, 0x0000f078}, + {0x81d8, 0x00000001}, + {0x82d8, 0x00000001}, + {0x9500, 0x00000000}, + {0x9504, 0x00000000}, + {0x9508, 0x00000000}, + {0x950c, 0x00000000}, + {0x9510, 0x00000000}, + {0x9514, 0x00000000}, + {0x9518, 0x00000000}, + {0x951c, 0x00000000}, + {0x9520, 0x00000000}, + {0x9524, 0x00000000}, + {0x9528, 0x00000000}, + {0x952c, 0x00000000}, + {0x9530, 0x00000000}, + {0x9534, 0x00000000}, + {0x9538, 0x00000000}, + {0x953c, 0x00000000}, + {0x9540, 0x04000000}, + {0x9544, 0x00000000}, + {0x9548, 0x00000000}, + {0x954c, 0x00000000}, + {0x9550, 0x00000000}, + {0x9554, 0x00000000}, + {0x9558, 0x00000000}, + {0x955c, 0x00000000}, + {0x9560, 0x00000000}, + {0x9564, 0x00000000}, + {0x9568, 0x00000000}, + {0x956c, 0x00000000}, + {0x9570, 0x00000000}, + {0x9574, 0x00000000}, + {0x9578, 0x00000000}, + {0x957c, 0x00000000}, + {0x9580, 0x00000000}, + {0x9584, 0x04000000}, + {0x9588, 0x00000000}, + {0x958c, 0x00000000}, + {0x9590, 0x00000000}, + {0x9594, 0x00000000}, + {0x9598, 0x00000000}, + {0x959c, 0x00000000}, + {0x95a0, 0x00000000}, + {0x95a4, 0x00000000}, + {0x95a8, 0x00000000}, + {0x95ac, 0x00000000}, + {0x95b0, 0x00000000}, + {0x95b4, 0x00000000}, + {0x95b8, 0x00000000}, + {0x95bc, 0x00000000}, + {0x95c0, 0x00000000}, + {0x95c4, 0x00000000}, + {0x95c8, 0x04000000}, + {0x95cc, 0x00000000}, + {0x95d0, 0x00000000}, + {0x95d4, 0x00000000}, + {0x95d8, 0x00000000}, + {0x95dc, 0x00000000}, + {0x95e0, 0x00000000}, + {0x95e4, 0x00000000}, + {0x95e8, 0x00000000}, + {0x95ec, 0x00000000}, + {0x95f0, 0x00000000}, + {0x95f4, 0x00000000}, + {0x95f8, 0x00000000}, + {0x95fc, 0x00000000}, + {0x9600, 0x00000000}, + {0x9604, 0x00000000}, + {0x9608, 0x00000000}, + {0x960c, 0x04000000}, + {0x9610, 0x00000000}, + {0x9614, 0x00000000}, + {0x9618, 0x00000000}, + {0x961c, 0x00000000}, + {0x9620, 0x00000000}, + {0x9624, 0x00000000}, + {0x9628, 0x00000000}, + {0x962c, 0x00000000}, + {0x9630, 0x00000000}, + {0x9634, 0x00000000}, + {0x9638, 0x00000000}, + {0x963c, 0x00000000}, + {0x9640, 0x00000000}, + {0x9644, 0x00000000}, + {0x9648, 0x00000000}, + {0x964c, 0x00000000}, + {0x9650, 0x04000000}, + {0x9654, 0x00000000}, + {0x9658, 0x00000000}, + {0x965c, 0x00000000}, + {0x9660, 0x00000000}, + {0x9664, 0x00000000}, + {0x9668, 0x00000000}, + {0x966c, 0x00000000}, + {0x9670, 0x00000000}, + {0x9674, 0x00000000}, + {0x9678, 0x00000000}, + {0x967c, 0x00000000}, + {0x9680, 0x00000000}, + {0x9684, 0x00000000}, + {0x9688, 0x00000000}, + {0x968c, 0x00000000}, + {0x9690, 0x00000000}, + {0x9694, 0x04000000}, + {0x9698, 0x00000000}, + {0x969c, 0x00000000}, + {0x96a0, 0x00000000}, + {0x96a4, 0x00000000}, + {0x96a8, 0x00000000}, + {0x96ac, 0x00000000}, + {0x96b0, 0x00000000}, + {0x96b4, 0x00000000}, + {0x96b8, 0x00000000}, + {0x96bc, 0x00000000}, + {0x96c0, 0x00000000}, + {0x96c4, 0x00000000}, + {0x96c8, 0x00000000}, + {0x96cc, 0x00000000}, + {0x96d0, 0x00000000}, + {0x96d4, 0x00000000}, + {0x96d8, 0x04000000}, + {0x96dc, 0x00000000}, + {0x96e0, 0x00000000}, + {0x96e4, 0x00000000}, + {0x96e8, 0x00000000}, + {0x96ec, 0x00000000}, + {0x96f0, 0x00000000}, + {0x96f4, 0x00000000}, + {0x96f8, 0x00000000}, + {0x96fc, 0x00000000}, + {0x9700, 0x00000000}, + {0x9704, 0x00000000}, + {0x9708, 0x00000000}, + {0x970c, 0x00000000}, + {0x9710, 0x00000000}, + {0x9714, 0x00000000}, + {0x9718, 0x00000000}, + {0x971c, 0x04000000}, + {0x9720, 0x00000000}, + {0x9724, 0x00000000}, + {0x9728, 0x00000000}, + {0x972c, 0x00000000}, + {0x9730, 0x00000000}, + {0x9734, 0x00000000}, + {0x9738, 0x00000000}, + {0x973c, 0x00000000}, + {0x9740, 0x00000000}, + {0x9744, 0x00000000}, + {0x9748, 0x00000000}, + {0x974c, 0x00000000}, + {0x9750, 0x00000000}, + {0x9754, 0x00000000}, + {0x9758, 0x00000000}, + {0x975c, 0x00000000}, + {0x9760, 0x04000000}, + {0x9764, 0x00000000}, + {0x9768, 0x00000000}, + {0x976c, 0x00000000}, + {0x9770, 0x00000000}, + {0x9774, 0x00000000}, + {0x9778, 0x00000000}, + {0x977c, 0x00000000}, + {0x9780, 0x00000000}, + {0x9784, 0x00000000}, + {0x9788, 0x00000000}, + {0x978c, 0x00000000}, + {0x9790, 0x00000000}, + {0x9794, 0x00000000}, + {0x9798, 0x00000000}, + {0x979c, 0x00000000}, + {0x97a0, 0x00000000}, + {0x97a4, 0x04000000}, + {0x97a8, 0x00000000}, + {0x97ac, 0x00000000}, + {0x97b0, 0x00000000}, + {0x97b4, 0x00000000}, + {0x97b8, 0x00000000}, + {0x97bc, 0x00000000}, + {0x97c0, 0x00000000}, + {0x97c4, 0x00000000}, + {0x97c8, 0x00000000}, + {0x97cc, 0x00000000}, + {0x97d0, 0x00000000}, + {0x97d4, 0x00000000}, + {0x97d8, 0x00000000}, + {0x97dc, 0x00000000}, + {0x97e0, 0x00000000}, + {0x97e4, 0x00000000}, + {0x97e8, 0x04000000}, + {0x97ec, 0x00000000}, + {0x97f0, 0x00000000}, + {0x97f4, 0x00000000}, + {0x97f8, 0x00000000}, + {0x97fc, 0x00000000}, + {0x9800, 0x00000000}, + {0x9804, 0x00000000}, + {0x9808, 0x00000000}, + {0x980c, 0x00000000}, + {0x9810, 0x00000000}, + {0x9814, 0x00000000}, + {0x9818, 0x00000000}, + {0x981c, 0x00000000}, + {0x9820, 0x00000000}, + {0x9824, 0x00000000}, + {0x9828, 0x00000000}, + {0x982c, 0x04000000}, + {0x9830, 0x00000000}, + {0x9834, 0x00000000}, + {0x9838, 0x00000000}, + {0x983c, 0x00000000}, + {0x9840, 0x00000000}, + {0x9844, 0x00000000}, + {0x9848, 0x00000000}, + {0x984c, 0x00000000}, + {0x9850, 0x00000000}, + {0x9854, 0x00000000}, + {0x9858, 0x00000000}, + {0x985c, 0x00000000}, + {0x9860, 0x00000000}, + {0x9864, 0x00000000}, + {0x9868, 0x00000000}, + {0x986c, 0x00000000}, + {0x9870, 0x04000000}, + {0x9874, 0x00000000}, + {0x9878, 0x00000000}, + {0x987c, 0x00000000}, + {0x9880, 0x00000000}, + {0x9884, 0x00000000}, + {0x9888, 0x00000000}, + {0x988c, 0x00000000}, + {0x9890, 0x00000000}, + {0x9894, 0x00000000}, + {0x9898, 0x00000000}, + {0x989c, 0x00000000}, + {0x98a0, 0x00000000}, + {0x98a4, 0x00000000}, + {0x98a8, 0x00000000}, + {0x98ac, 0x00000000}, + {0x98b0, 0x00000000}, + {0x98b4, 0x04000000}, + {0x98b8, 0x00000000}, + {0x98bc, 0x00000000}, + {0x98c0, 0x00000000}, + {0x98c4, 0x00000000}, + {0x98c8, 0x00000000}, + {0x98cc, 0x00000000}, + {0x98d0, 0x00000000}, + {0x98d4, 0x00000000}, + {0x98d8, 0x00000000}, + {0x98dc, 0x00000000}, + {0x98e0, 0x00000000}, + {0x98e4, 0x00000000}, + {0x98e8, 0x00000000}, + {0x98ec, 0x00000000}, + {0x98f0, 0x00000000}, + {0x98f4, 0x00000000}, + {0x98f8, 0x04000000}, + {0x98fc, 0x00000000}, + {0x9900, 0x00000000}, + {0x9904, 0x00000000}, + {0x9908, 0x00000000}, + {0x990c, 0x00000000}, + {0x9910, 0x00000000}, + {0x9914, 0x00000000}, + {0x9918, 0x00000000}, + {0x991c, 0x00000000}, + {0x9920, 0x00000000}, + {0x9924, 0x00000000}, + {0x9928, 0x00000000}, + {0x992c, 0x00000000}, + {0x9930, 0x00000000}, + {0x9934, 0x00000000}, + {0x9938, 0x00000000}, + {0x993c, 0x04000000}, + {0x9940, 0x00000000}, + {0x9944, 0x00000000}, + {0x9948, 0x00000000}, + {0x994c, 0x00000000}, + {0x9950, 0x00000000}, + {0x9954, 0x00000000}, + {0x9958, 0x00000000}, + {0x995c, 0x00000000}, + {0x9960, 0x00000000}, + {0x9964, 0x00000000}, + {0x9968, 0x00000000}, + {0x996c, 0x00000000}, + {0x9970, 0x00000000}, + {0x9974, 0x00000000}, + {0x9978, 0x00000000}, + {0x997c, 0x00000000}, + {0x9980, 0x04000000}, + {0x9984, 0x00000000}, + {0x9988, 0x00000000}, + {0x998c, 0x00000000}, + {0x9990, 0x00000000}, + {0x9994, 0x00000000}, + {0x9998, 0x00000000}, + {0x999c, 0x00000000}, + {0x99a0, 0x00000000}, + {0x99a4, 0x00000000}, + {0x99a8, 0x00000000}, + {0x99ac, 0x00000000}, + {0x99b0, 0x00000000}, + {0x99b4, 0x00000000}, + {0x99b8, 0x00000000}, + {0x99bc, 0x00000000}, + {0x99c0, 0x00000000}, + {0x99c4, 0x04000000}, + {0x99c8, 0x00000000}, + {0x99cc, 0x00000000}, + {0x99d0, 0x00000000}, + {0x99d4, 0x00000000}, + {0x99d8, 0x00000000}, + {0x99dc, 0x00000000}, + {0x99e0, 0x00000000}, + {0x99e4, 0x00000000}, + {0x99e8, 0x00000000}, + {0x99ec, 0x00000000}, + {0x99f0, 0x00000000}, + {0x99f4, 0x00000000}, + {0x99f8, 0x00000000}, + {0x99fc, 0x00000000}, + {0x9a00, 0x00000000}, + {0x9a04, 0x00000000}, + {0x9a08, 0x04000000}, + {0x9a0c, 0x00000000}, + {0x9a10, 0x00000000}, + {0x9a14, 0x00000000}, + {0x9a18, 0x00000000}, + {0x9a1c, 0x00000000}, + {0x9a20, 0x00000000}, + {0x9a24, 0x00000000}, + {0x9a28, 0x00000000}, + {0x9a2c, 0x00000000}, + {0x9a30, 0x00000000}, + {0x9a34, 0x00000000}, + {0x9a38, 0x00000000}, + {0x9a3c, 0x00000000}, + {0x9a40, 0x00000000}, + {0x9a44, 0x00000000}, + {0x9a48, 0x00000000}, + {0x9a4c, 0x04000000}, + {0x9a50, 0x00000000}, + {0x9a54, 0x00000000}, + {0x9a58, 0x00000000}, + {0x9a5c, 0x00000000}, + {0x9a60, 0x00000000}, + {0x9a64, 0x00000000}, + {0x9a68, 0x00000000}, + {0x9a6c, 0x00000000}, + {0x9a70, 0x00000000}, + {0x9a74, 0x00000000}, + {0x9a78, 0x00000000}, + {0x9a7c, 0x00000000}, + {0x9a80, 0x00000000}, + {0x9a84, 0x00000000}, + {0x9a88, 0x00000000}, + {0x9a8c, 0x00000000}, + {0x9a90, 0x04000000}, + {0x9a94, 0x00000000}, + {0x9a98, 0x00000000}, + {0x9a9c, 0x00000000}, + {0x9aa0, 0x00000000}, + {0x9aa4, 0x00000000}, + {0x9aa8, 0x00000000}, + {0x9aac, 0x00000000}, + {0x9ab0, 0x00000000}, + {0x9ab4, 0x00000000}, + {0x9ab8, 0x00000000}, + {0x9abc, 0x00000000}, + {0x9ac0, 0x00000000}, + {0x9ac4, 0x00000000}, + {0x9ac8, 0x00000000}, + {0x9acc, 0x00000000}, + {0x9ad0, 0x00000000}, + {0x9ad4, 0x04000000}, + {0x9ad8, 0x00000000}, + {0x9adc, 0x00000000}, + {0x9ae0, 0x00000000}, + {0x9ae4, 0x00000000}, + {0x9ae8, 0x00000000}, + {0x9aec, 0x00000000}, + {0x9af0, 0x00000000}, + {0x9af4, 0x00000000}, + {0x9af8, 0x00000000}, + {0x9afc, 0x00000000}, + {0x9b00, 0x00000000}, + {0x9b04, 0x00000000}, + {0x9b08, 0x00000000}, + {0x9b0c, 0x00000000}, + {0x9b10, 0x00000000}, + {0x9b14, 0x00000000}, + {0x9b18, 0x04000000}, + {0x9b1c, 0x00000000}, + {0x9b20, 0x00000000}, + {0x9b24, 0x00000000}, + {0x9b28, 0x00000000}, + {0x9b2c, 0x00000000}, + {0x9b30, 0x00000000}, + {0x9b34, 0x00000000}, + {0x9b38, 0x00000000}, + {0x9b3c, 0x00000000}, + {0x9b40, 0x00000000}, + {0x9b44, 0x00000000}, + {0x9b48, 0x00000000}, + {0x9b4c, 0x00000000}, + {0x9b50, 0x00000000}, + {0x9b54, 0x00000000}, + {0x9b58, 0x00000000}, + {0x9b5c, 0x04000000}, + {0x9d00, 0x00000000}, + {0x9d04, 0x00000000}, + {0x9d08, 0x00000000}, + {0x9d0c, 0x00000000}, + {0x9d10, 0x00000000}, + {0x9d14, 0x00000000}, + {0x9d18, 0x00000000}, + {0x9d1c, 0x00000000}, + {0x9d20, 0x00000000}, + {0x9d24, 0x00000000}, + {0x9d28, 0x00000000}, + {0x9d2c, 0x00000000}, + {0x9d30, 0x00000000}, + {0x9d34, 0x00000000}, + {0x9d38, 0x00000000}, + {0x9d3c, 0x00000000}, + {0x9d40, 0x04000000}, + {0x9d44, 0x00000000}, + {0x9d48, 0x00000000}, + {0x9d4c, 0x00000000}, + {0x9d50, 0x00000000}, + {0x9d54, 0x00000000}, + {0x9d58, 0x00000000}, + {0x9d5c, 0x00000000}, + {0x9d60, 0x00000000}, + {0x9d64, 0x00000000}, + {0x9d68, 0x00000000}, + {0x9d6c, 0x00000000}, + {0x9d70, 0x00000000}, + {0x9d74, 0x00000000}, + {0x9d78, 0x00000000}, + {0x9d7c, 0x00000000}, + {0x9d80, 0x00000000}, + {0x9d84, 0x04000000}, + {0x9d88, 0x00000000}, + {0x9d8c, 0x00000000}, + {0x9d90, 0x00000000}, + {0x9d94, 0x00000000}, + {0x9d98, 0x00000000}, + {0x9d9c, 0x00000000}, + {0x9da0, 0x00000000}, + {0x9da4, 0x00000000}, + {0x9da8, 0x00000000}, + {0x9dac, 0x00000000}, + {0x9db0, 0x00000000}, + {0x9db4, 0x00000000}, + {0x9db8, 0x00000000}, + {0x9dbc, 0x00000000}, + {0x9dc0, 0x00000000}, + {0x9dc4, 0x00000000}, + {0x9dc8, 0x04000000}, + {0x9dcc, 0x00000000}, + {0x9dd0, 0x00000000}, + {0x9dd4, 0x00000000}, + {0x9dd8, 0x00000000}, + {0x9ddc, 0x00000000}, + {0x9de0, 0x00000000}, + {0x9de4, 0x00000000}, + {0x9de8, 0x00000000}, + {0x9dec, 0x00000000}, + {0x9df0, 0x00000000}, + {0x9df4, 0x00000000}, + {0x9df8, 0x00000000}, + {0x9dfc, 0x00000000}, + {0x9e00, 0x00000000}, + {0x9e04, 0x00000000}, + {0x9e08, 0x00000000}, + {0x9e0c, 0x04000000}, + {0x9e10, 0x00000000}, + {0x9e14, 0x00000000}, + {0x9e18, 0x00000000}, + {0x9e1c, 0x00000000}, + {0x9e20, 0x00000000}, + {0x9e24, 0x00000000}, + {0x9e28, 0x00000000}, + {0x9e2c, 0x00000000}, + {0x9e30, 0x00000000}, + {0x9e34, 0x00000000}, + {0x9e38, 0x00000000}, + {0x9e3c, 0x00000000}, + {0x9e40, 0x00000000}, + {0x9e44, 0x00000000}, + {0x9e48, 0x00000000}, + {0x9e4c, 0x00000000}, + {0x9e50, 0x04000000}, + {0x9e54, 0x00000000}, + {0x9e58, 0x00000000}, + {0x9e5c, 0x00000000}, + {0x9e60, 0x00000000}, + {0x9e64, 0x00000000}, + {0x9e68, 0x00000000}, + {0x9e6c, 0x00000000}, + {0x9e70, 0x00000000}, + {0x9e74, 0x00000000}, + {0x9e78, 0x00000000}, + {0x9e7c, 0x00000000}, + {0x9e80, 0x00000000}, + {0x9e84, 0x00000000}, + {0x9e88, 0x00000000}, + {0x9e8c, 0x00000000}, + {0x9e90, 0x00000000}, + {0x9e94, 0x04000000}, + {0x9e98, 0x00000000}, + {0x9e9c, 0x00000000}, + {0x9ea0, 0x00000000}, + {0x9ea4, 0x00000000}, + {0x9ea8, 0x00000000}, + {0x9eac, 0x00000000}, + {0x9eb0, 0x00000000}, + {0x9eb4, 0x00000000}, + {0x9eb8, 0x00000000}, + {0x9ebc, 0x00000000}, + {0x9ec0, 0x00000000}, + {0x9ec4, 0x00000000}, + {0x9ec8, 0x00000000}, + {0x9ecc, 0x00000000}, + {0x9ed0, 0x00000000}, + {0x9ed4, 0x00000000}, + {0x9ed8, 0x04000000}, + {0x9edc, 0x00000000}, + {0x9ee0, 0x00000000}, + {0x9ee4, 0x00000000}, + {0x9ee8, 0x00000000}, + {0x9eec, 0x00000000}, + {0x9ef0, 0x00000000}, + {0x9ef4, 0x00000000}, + {0x9ef8, 0x00000000}, + {0x9efc, 0x00000000}, + {0x9f00, 0x00000000}, + {0x9f04, 0x00000000}, + {0x9f08, 0x00000000}, + {0x9f0c, 0x00000000}, + {0x9f10, 0x00000000}, + {0x9f14, 0x00000000}, + {0x9f18, 0x00000000}, + {0x9f1c, 0x04000000}, + {0x9f20, 0x00000000}, + {0x9f24, 0x00000000}, + {0x9f28, 0x00000000}, + {0x9f2c, 0x00000000}, + {0x9f30, 0x00000000}, + {0x9f34, 0x00000000}, + {0x9f38, 0x00000000}, + {0x9f3c, 0x00000000}, + {0x9f40, 0x00000000}, + {0x9f44, 0x00000000}, + {0x9f48, 0x00000000}, + {0x9f4c, 0x00000000}, + {0x9f50, 0x00000000}, + {0x9f54, 0x00000000}, + {0x9f58, 0x00000000}, + {0x9f5c, 0x00000000}, + {0x9f60, 0x04000000}, + {0x9f64, 0x00000000}, + {0x9f68, 0x00000000}, + {0x9f6c, 0x00000000}, + {0x9f70, 0x00000000}, + {0x9f74, 0x00000000}, + {0x9f78, 0x00000000}, + {0x9f7c, 0x00000000}, + {0x9f80, 0x00000000}, + {0x9f84, 0x00000000}, + {0x9f88, 0x00000000}, + {0x9f8c, 0x00000000}, + {0x9f90, 0x00000000}, + {0x9f94, 0x00000000}, + {0x9f98, 0x00000000}, + {0x9f9c, 0x00000000}, + {0x9fa0, 0x00000000}, + {0x9fa4, 0x04000000}, + {0x9fa8, 0x00000000}, + {0x9fac, 0x00000000}, + {0x9fb0, 0x00000000}, + {0x9fb4, 0x00000000}, + {0x9fb8, 0x00000000}, + {0x9fbc, 0x00000000}, + {0x9fc0, 0x00000000}, + {0x9fc4, 0x00000000}, + {0x9fc8, 0x00000000}, + {0x9fcc, 0x00000000}, + {0x9fd0, 0x00000000}, + {0x9fd4, 0x00000000}, + {0x9fd8, 0x00000000}, + {0x9fdc, 0x00000000}, + {0x9fe0, 0x00000000}, + {0x9fe4, 0x00000000}, + {0x9fe8, 0x04000000}, + {0x9fec, 0x00000000}, + {0x9ff0, 0x00000000}, + {0x9ff4, 0x00000000}, + {0x9ff8, 0x00000000}, + {0x9ffc, 0x00000000}, + {0xa000, 0x00000000}, + {0xa004, 0x00000000}, + {0xa008, 0x00000000}, + {0xa00c, 0x00000000}, + {0xa010, 0x00000000}, + {0xa014, 0x00000000}, + {0xa018, 0x00000000}, + {0xa01c, 0x00000000}, + {0xa020, 0x00000000}, + {0xa024, 0x00000000}, + {0xa028, 0x00000000}, + {0xa02c, 0x04000000}, + {0xa030, 0x00000000}, + {0xa034, 0x00000000}, + {0xa038, 0x00000000}, + {0xa03c, 0x00000000}, + {0xa040, 0x00000000}, + {0xa044, 0x00000000}, + {0xa048, 0x00000000}, + {0xa04c, 0x00000000}, + {0xa050, 0x00000000}, + {0xa054, 0x00000000}, + {0xa058, 0x00000000}, + {0xa05c, 0x00000000}, + {0xa060, 0x00000000}, + {0xa064, 0x00000000}, + {0xa068, 0x00000000}, + {0xa06c, 0x00000000}, + {0xa070, 0x04000000}, + {0xa074, 0x00000000}, + {0xa078, 0x00000000}, + {0xa07c, 0x00000000}, + {0xa080, 0x00000000}, + {0xa084, 0x00000000}, + {0xa088, 0x00000000}, + {0xa08c, 0x00000000}, + {0xa090, 0x00000000}, + {0xa094, 0x00000000}, + {0xa098, 0x00000000}, + {0xa09c, 0x00000000}, + {0xa0a0, 0x00000000}, + {0xa0a4, 0x00000000}, + {0xa0a8, 0x00000000}, + {0xa0ac, 0x00000000}, + {0xa0b0, 0x00000000}, + {0xa0b4, 0x04000000}, + {0xa0b8, 0x00000000}, + {0xa0bc, 0x00000000}, + {0xa0c0, 0x00000000}, + {0xa0c4, 0x00000000}, + {0xa0c8, 0x00000000}, + {0xa0cc, 0x00000000}, + {0xa0d0, 0x00000000}, + {0xa0d4, 0x00000000}, + {0xa0d8, 0x00000000}, + {0xa0dc, 0x00000000}, + {0xa0e0, 0x00000000}, + {0xa0e4, 0x00000000}, + {0xa0e8, 0x00000000}, + {0xa0ec, 0x00000000}, + {0xa0f0, 0x00000000}, + {0xa0f4, 0x00000000}, + {0xa0f8, 0x04000000}, + {0xa0fc, 0x00000000}, + {0xa100, 0x00000000}, + {0xa104, 0x00000000}, + {0xa108, 0x00000000}, + {0xa10c, 0x00000000}, + {0xa110, 0x00000000}, + {0xa114, 0x00000000}, + {0xa118, 0x00000000}, + {0xa11c, 0x00000000}, + {0xa120, 0x00000000}, + {0xa124, 0x00000000}, + {0xa128, 0x00000000}, + {0xa12c, 0x00000000}, + {0xa130, 0x00000000}, + {0xa134, 0x00000000}, + {0xa138, 0x00000000}, + {0xa13c, 0x04000000}, + {0xa140, 0x00000000}, + {0xa144, 0x00000000}, + {0xa148, 0x00000000}, + {0xa14c, 0x00000000}, + {0xa150, 0x00000000}, + {0xa154, 0x00000000}, + {0xa158, 0x00000000}, + {0xa15c, 0x00000000}, + {0xa160, 0x00000000}, + {0xa164, 0x00000000}, + {0xa168, 0x00000000}, + {0xa16c, 0x00000000}, + {0xa170, 0x00000000}, + {0xa174, 0x00000000}, + {0xa178, 0x00000000}, + {0xa17c, 0x00000000}, + {0xa180, 0x04000000}, + {0xa184, 0x00000000}, + {0xa188, 0x00000000}, + {0xa18c, 0x00000000}, + {0xa190, 0x00000000}, + {0xa194, 0x00000000}, + {0xa198, 0x00000000}, + {0xa19c, 0x00000000}, + {0xa1a0, 0x00000000}, + {0xa1a4, 0x00000000}, + {0xa1a8, 0x00000000}, + {0xa1ac, 0x00000000}, + {0xa1b0, 0x00000000}, + {0xa1b4, 0x00000000}, + {0xa1b8, 0x00000000}, + {0xa1bc, 0x00000000}, + {0xa1c0, 0x00000000}, + {0xa1c4, 0x04000000}, + {0xa1c8, 0x00000000}, + {0xa1cc, 0x00000000}, + {0xa1d0, 0x00000000}, + {0xa1d4, 0x00000000}, + {0xa1d8, 0x00000000}, + {0xa1dc, 0x00000000}, + {0xa1e0, 0x00000000}, + {0xa1e4, 0x00000000}, + {0xa1e8, 0x00000000}, + {0xa1ec, 0x00000000}, + {0xa1f0, 0x00000000}, + {0xa1f4, 0x00000000}, + {0xa1f8, 0x00000000}, + {0xa1fc, 0x00000000}, + {0xa200, 0x00000000}, + {0xa204, 0x00000000}, + {0xa208, 0x04000000}, + {0xa20c, 0x00000000}, + {0xa210, 0x00000000}, + {0xa214, 0x00000000}, + {0xa218, 0x00000000}, + {0xa21c, 0x00000000}, + {0xa220, 0x00000000}, + {0xa224, 0x00000000}, + {0xa228, 0x00000000}, + {0xa22c, 0x00000000}, + {0xa230, 0x00000000}, + {0xa234, 0x00000000}, + {0xa238, 0x00000000}, + {0xa23c, 0x00000000}, + {0xa240, 0x00000000}, + {0xa244, 0x00000000}, + {0xa248, 0x00000000}, + {0xa24c, 0x04000000}, + {0xa250, 0x00000000}, + {0xa254, 0x00000000}, + {0xa258, 0x00000000}, + {0xa25c, 0x00000000}, + {0xa260, 0x00000000}, + {0xa264, 0x00000000}, + {0xa268, 0x00000000}, + {0xa26c, 0x00000000}, + {0xa270, 0x00000000}, + {0xa274, 0x00000000}, + {0xa278, 0x00000000}, + {0xa27c, 0x00000000}, + {0xa280, 0x00000000}, + {0xa284, 0x00000000}, + {0xa288, 0x00000000}, + {0xa28c, 0x00000000}, + {0xa290, 0x04000000}, + {0xa294, 0x00000000}, + {0xa298, 0x00000000}, + {0xa29c, 0x00000000}, + {0xa2a0, 0x00000000}, + {0xa2a4, 0x00000000}, + {0xa2a8, 0x00000000}, + {0xa2ac, 0x00000000}, + {0xa2b0, 0x00000000}, + {0xa2b4, 0x00000000}, + {0xa2b8, 0x00000000}, + {0xa2bc, 0x00000000}, + {0xa2c0, 0x00000000}, + {0xa2c4, 0x00000000}, + {0xa2c8, 0x00000000}, + {0xa2cc, 0x00000000}, + {0xa2d0, 0x00000000}, + {0xa2d4, 0x04000000}, + {0xa2d8, 0x00000000}, + {0xa2dc, 0x00000000}, + {0xa2e0, 0x00000000}, + {0xa2e4, 0x00000000}, + {0xa2e8, 0x00000000}, + {0xa2ec, 0x00000000}, + {0xa2f0, 0x00000000}, + {0xa2f4, 0x00000000}, + {0xa2f8, 0x00000000}, + {0xa2fc, 0x00000000}, + {0xa300, 0x00000000}, + {0xa304, 0x00000000}, + {0xa308, 0x00000000}, + {0xa30c, 0x00000000}, + {0xa310, 0x00000000}, + {0xa314, 0x00000000}, + {0xa318, 0x04000000}, + {0xa31c, 0x00000000}, + {0xa320, 0x00000000}, + {0xa324, 0x00000000}, + {0xa328, 0x00000000}, + {0xa32c, 0x00000000}, + {0xa330, 0x00000000}, + {0xa334, 0x00000000}, + {0xa338, 0x00000000}, + {0xa33c, 0x00000000}, + {0xa340, 0x00000000}, + {0xa344, 0x00000000}, + {0xa348, 0x00000000}, + {0xa34c, 0x00000000}, + {0xa350, 0x00000000}, + {0xa354, 0x00000000}, + {0xa358, 0x00000000}, + {0xa35c, 0x04000000}, + {0x81d8, 0x00000000}, + {0x82d8, 0x00000000}, + {0xb104, 0x2b251f19}, + {0xb108, 0x433d3731}, + {0xb10c, 0x5b554f49}, + {0xb110, 0x736d6761}, + {0xb114, 0x7f7f7f79}, + {0xb118, 0x120f7f7f}, + {0xb11c, 0x1e1b1815}, + {0xb120, 0x2a272421}, + {0xb124, 0x3633302d}, + {0xb128, 0x3f3f3c39}, + {0xb12c, 0x3f3f3f3f}, + {0x8088, 0x00000110}, + {0x8000, 0x00000008}, + {0x8080, 0x00000005}, + {0x8500, 0x80000008}, + {0x8504, 0x43000004}, + {0x8508, 0x4b044a00}, + {0x850c, 0x40098604}, + {0x8510, 0x0004e024}, + {0x8514, 0x87044b05}, + {0x8518, 0xe024400b}, + {0x851c, 0x4b000004}, + {0x8520, 0x21e07410}, + {0x8524, 0x16580000}, + {0x8528, 0x00047430}, + {0x852c, 0x00074380}, + {0x8530, 0x00044c00}, + {0x8534, 0x00074300}, + {0x8538, 0x00045603}, + {0x853c, 0x42fe5700}, + {0x8540, 0x42004000}, + {0x8544, 0x30005055}, + {0x8548, 0xa512b41c}, + {0x854c, 0xf02fe66f}, + {0x8550, 0xf22ff12f}, + {0x8554, 0xf42ff32f}, + {0x8558, 0xf62ff52f}, + {0x855c, 0xf82ff72f}, + {0x8560, 0xfa2ff92f}, + {0x8564, 0xfc2ffb2f}, + {0x8568, 0xfe2ffd2f}, + {0x856c, 0xe66fff2f}, + {0x8570, 0xf12ef02e}, + {0x8574, 0xf32ef22e}, + {0x8578, 0xf52ef42e}, + {0x857c, 0xff2ef62e}, + {0x8580, 0xa511000b}, + {0x8584, 0xf12cf02c}, + {0x8588, 0xf32cf22c}, + {0x858c, 0xf52cf42c}, + {0x8590, 0xf72cf62c}, + {0x8594, 0xf92cf82c}, + {0x8598, 0xfb2cfa2c}, + {0x859c, 0xfd2cfc2c}, + {0x85a0, 0xff2cfe2c}, + {0x85a4, 0xf12cf02c}, + {0x85a8, 0x0001f22c}, + {0x85ac, 0x30b330b3}, + {0x85b0, 0x310c3125}, + {0x85b4, 0x31253161}, + {0x85b8, 0x3081316f}, + {0x85bc, 0x317f3172}, + {0x85c0, 0x3192318c}, + {0x85c4, 0x32b832a6}, + {0x85c8, 0x31fd32c2}, + {0x85cc, 0x330732cc}, + {0x85d0, 0x33193343}, + {0x85d4, 0x331d3312}, + {0x85d8, 0x31663316}, + {0x85dc, 0x3365335b}, + {0x85e0, 0x3379336f}, + {0x85e4, 0x338d3383}, + {0x85e8, 0x33a13397}, + {0x85ec, 0x33b833ab}, + {0x85f0, 0x33d733c9}, + {0x85f4, 0x342333db}, + {0x85f8, 0x343c343b}, + {0x85fc, 0x3471346f}, + {0x8600, 0xe493347c}, + {0x8604, 0x20887410}, + {0x8608, 0x140f0200}, + {0x860c, 0x02002098}, + {0x8610, 0x20a8140f}, + {0x8614, 0x140f0200}, + {0x8618, 0xe4df7430}, + {0x861c, 0x74105b10}, + {0x8620, 0x000120a0}, + {0x8624, 0x140f140f}, + {0x8628, 0x56e15507}, + {0x862c, 0xe4c95c06}, + {0x8630, 0x20a87410}, + {0x8634, 0x140f0201}, + {0x8638, 0xe4c95517}, + {0x863c, 0x20a87410}, + {0x8640, 0x140f0200}, + {0x8644, 0x56c15517}, + {0x8648, 0xe4c95c02}, + {0x864c, 0x20a07410}, + {0x8650, 0x140f0000}, + {0x8654, 0x55071407}, + {0x8658, 0xe47ee4c9}, + {0x865c, 0x4686750a}, + {0x8660, 0xe159e4d3}, + {0x8664, 0xe4930001}, + {0x8668, 0x20a87410}, + {0x866c, 0x140f0200}, + {0x8670, 0x02002098}, + {0x8674, 0x2088140f}, + {0x8678, 0x140f0200}, + {0x867c, 0xe4df7430}, + {0x8680, 0x74105b10}, + {0x8684, 0x020120a8}, + {0x8688, 0x2080140f}, + {0x868c, 0x140f0000}, + {0x8690, 0x56615507}, + {0x8694, 0xe4c95c06}, + {0x8698, 0x20887410}, + {0x869c, 0x140f0200}, + {0x86a0, 0xe4c95517}, + {0x86a4, 0x20a87410}, + {0x86a8, 0x140f0200}, + {0x86ac, 0x56415517}, + {0x86b0, 0xe4c95c02}, + {0x86b4, 0x20807410}, + {0x86b8, 0x140f0000}, + {0x86bc, 0x55071407}, + {0x86c0, 0xe47ee4c9}, + {0x86c4, 0x468e7508}, + {0x86c8, 0xe159e4d3}, + {0x86cc, 0x5b10f025}, + {0x86d0, 0x20a87410}, + {0x86d4, 0x140f0201}, + {0x86d8, 0x00002090}, + {0x86dc, 0x5507140f}, + {0x86e0, 0x5c065661}, + {0x86e4, 0x7410e4c9}, + {0x86e8, 0x02002098}, + {0x86ec, 0x5517140f}, + {0x86f0, 0x7410e4c9}, + {0x86f4, 0x020020a8}, + {0x86f8, 0x5517140f}, + {0x86fc, 0x5c025641}, + {0x8700, 0x7410e4c9}, + {0x8704, 0x00002090}, + {0x8708, 0x5507140f}, + {0x870c, 0x7509e4c9}, + {0x8710, 0xe4d34696}, + {0x8714, 0x0001e159}, + {0x8718, 0x74105b10}, + {0x871c, 0x000020a0}, + {0x8720, 0x5507140f}, + {0x8724, 0xe4c95601}, + {0x8728, 0x20a87410}, + {0x872c, 0x140f0200}, + {0x8730, 0xe4c95517}, + {0x8734, 0x750ae47e}, + {0x8738, 0xe4d34686}, + {0x873c, 0x5500e159}, + {0x8740, 0x5501e4c5}, + {0x8744, 0xe4930001}, + {0x8748, 0x5b10e4df}, + {0x874c, 0x20807410}, + {0x8750, 0x140f0000}, + {0x8754, 0x02002098}, + {0x8758, 0xf205140f}, + {0x875c, 0x20a8f504}, + {0x8760, 0x140f0200}, + {0x8764, 0x56015507}, + {0x8768, 0x7410e4c9}, + {0x876c, 0x02002088}, + {0x8770, 0x5517140f}, + {0x8774, 0xe47ee4c9}, + {0x8778, 0x468e7508}, + {0x877c, 0xe159e4d3}, + {0x8780, 0x7410f512}, + {0x8784, 0x00002090}, + {0x8788, 0x5507140f}, + {0x878c, 0x7410e4c9}, + {0x8790, 0x02002098}, + {0x8794, 0x5517140f}, + {0x8798, 0x7509e4c9}, + {0x879c, 0xe4d34696}, + {0x87a0, 0x0001e159}, + {0x87a4, 0x46965b90}, + {0x87a8, 0xe4c55500}, + {0x87ac, 0x5b105501}, + {0x87b0, 0x79000001}, + {0x87b4, 0x57107420}, + {0x87b8, 0x140f5700}, + {0x87bc, 0x74309700}, + {0x87c0, 0xe4930001}, + {0x87c4, 0x0bbde4df}, + {0x87c8, 0x0001e662}, + {0x87cc, 0x5720e493}, + {0x87d0, 0x540054fd}, + {0x87d4, 0x70005700}, + {0x87d8, 0x70c0e4dd}, + {0x87dc, 0xe4a90001}, + {0x87e0, 0x0001e512}, + {0x87e4, 0x31abe493}, + {0x87e8, 0xe6620023}, + {0x87ec, 0x54ed0002}, + {0x87f0, 0x00230baa}, + {0x87f4, 0x0002e662}, + {0x87f8, 0xe486e52e}, + {0x87fc, 0xe4930001}, + {0x8800, 0x002231a1}, + {0x8804, 0x0002e662}, + {0x8808, 0x0baa54ec}, + {0x880c, 0xe6620022}, + {0x8810, 0xe52e0002}, + {0x8814, 0x0001e486}, + {0x8818, 0x0baae493}, + {0x881c, 0xe52e3194}, + {0x8820, 0x0001e486}, + {0x8824, 0x0babe493}, + {0x8828, 0x6d0f6c67}, + {0x882c, 0xe662e4df}, + {0x8830, 0x6c8bfb04}, + {0x8834, 0xe662e4df}, + {0x8838, 0x6c95fa04}, + {0x883c, 0xe662e4df}, + {0x8840, 0x0bacfb06}, + {0x8844, 0x6d0f6cb3}, + {0x8848, 0xe662e4df}, + {0x884c, 0xf904fa05}, + {0x8850, 0xe4df6ccb}, + {0x8854, 0xfb06e662}, + {0x8858, 0x6cdb0bad}, + {0x885c, 0xe4df6d0f}, + {0x8860, 0x6cf5e662}, + {0x8864, 0xe4df6d0f}, + {0x8868, 0x6c0be662}, + {0x886c, 0xe4df6d00}, + {0x8870, 0xfb04e662}, + {0x8874, 0xe4df6c25}, + {0x8878, 0xf8b7e662}, + {0x887c, 0xf904fa05}, + {0x8880, 0xe4df6c35}, + {0x8884, 0xfb04e662}, + {0x8888, 0xe4df6c4d}, + {0x888c, 0xf9bae662}, + {0x8890, 0x6c6bfa04}, + {0x8894, 0xe662e4df}, + {0x8898, 0x6c75fb04}, + {0x889c, 0xe662e4df}, + {0x88a0, 0xe4df6c99}, + {0x88a4, 0xfabce662}, + {0x88a8, 0x57200ba8}, + {0x88ac, 0x540054f0}, + {0x88b0, 0x7c355700}, + {0x88b4, 0x70007d00}, + {0x88b8, 0x6d0e6cc5}, + {0x88bc, 0xe662e4dd}, + {0x88c0, 0xe4dd6cf5}, + {0x88c4, 0x6c29e662}, + {0x88c8, 0xe4dd6d0f}, + {0x88cc, 0x0bb3e662}, + {0x88d0, 0x54ed5720}, + {0x88d4, 0x57005400}, + {0x88d8, 0x7d0f7ccb}, + {0x88dc, 0x6d006cd7}, + {0x88e0, 0xe662e4dd}, + {0x88e4, 0x6d016c0b}, + {0x88e8, 0xe662e4dd}, + {0x88ec, 0xe4dd6c3b}, + {0x88f0, 0x70c0e662}, + {0x88f4, 0xe486e52e}, + {0x88f8, 0xe4a90001}, + {0x88fc, 0x63424380}, + {0x8900, 0x43006887}, + {0x8904, 0x74100ba6}, + {0x8908, 0x000121e8}, + {0x890c, 0x6ec71658}, + {0x8910, 0xe5126f0e}, + {0x8914, 0x7410e667}, + {0x8918, 0x000321e8}, + {0x891c, 0x6eeb1658}, + {0x8920, 0xe667e512}, + {0x8924, 0x21e87410}, + {0x8928, 0x16580005}, + {0x892c, 0x6f0f6e13}, + {0x8930, 0xe667e512}, + {0x8934, 0x21e87410}, + {0x8938, 0x16580007}, + {0x893c, 0xe5126e3b}, + {0x8940, 0x7410e667}, + {0x8944, 0x000921e8}, + {0x8948, 0x6e671658}, + {0x894c, 0xe5126f0f}, + {0x8950, 0x7410e667}, + {0x8954, 0x000b21e8}, + {0x8958, 0x6e8b1658}, + {0x895c, 0xe667e512}, + {0x8960, 0x21e87410}, + {0x8964, 0x1658000d}, + {0x8968, 0x6f0f6eb3}, + {0x896c, 0xe667e512}, + {0x8970, 0xfe08ff09}, + {0x8974, 0x21e87410}, + {0x8978, 0x1658000e}, + {0x897c, 0xe5126ec7}, + {0x8980, 0x7410e667}, + {0x8984, 0x000f21e8}, + {0x8988, 0x6edb1658}, + {0x898c, 0xe5126f0f}, + {0x8990, 0x7410e667}, + {0x8994, 0x001021e8}, + {0x8998, 0x6eef1658}, + {0x899c, 0xe667e512}, + {0x89a0, 0xfe02ff03}, + {0x89a4, 0x7410e667}, + {0x89a8, 0x001321e8}, + {0x89ac, 0x6e111658}, + {0x89b0, 0xe5126f00}, + {0x89b4, 0xff03e667}, + {0x89b8, 0xe667fe02}, + {0x89bc, 0x21e87410}, + {0x89c0, 0x16580014}, + {0x89c4, 0xe5126e25}, + {0x89c8, 0xfc48e667}, + {0x89cc, 0xfe08ff09}, + {0x89d0, 0x21e87410}, + {0x89d4, 0x16580015}, + {0x89d8, 0xe5126e39}, + {0x89dc, 0x7410e667}, + {0x89e0, 0x001621e8}, + {0x89e4, 0x6e4d1658}, + {0x89e8, 0xe667e512}, + {0x89ec, 0x7410fd49}, + {0x89f0, 0x001821e8}, + {0x89f4, 0x6e751658}, + {0x89f8, 0xe667e512}, + {0x89fc, 0x21e87410}, + {0x8a00, 0x1658001a}, + {0x8a04, 0xe5126e99}, + {0x8a08, 0xfe44e667}, + {0x8a0c, 0x21e87410}, + {0x8a10, 0x1658001c}, + {0x8a14, 0xe5126ec5}, + {0x8a18, 0x7410e667}, + {0x8a1c, 0x001e21e8}, + {0x8a20, 0x6eed1658}, + {0x8a24, 0xe667e512}, + {0x8a28, 0x21e87410}, + {0x8a2c, 0x16580020}, + {0x8a30, 0x6f016e15}, + {0x8a34, 0xe667e512}, + {0x8a38, 0x21e87410}, + {0x8a3c, 0x16580022}, + {0x8a40, 0xe5126e39}, + {0x8a44, 0xe52ee667}, + {0x8a48, 0x0001e49c}, + {0x8a4c, 0x4380e4a9}, + {0x8a50, 0x68806340}, + {0x8a54, 0x0bac4300}, + {0x8a58, 0x00223241}, + {0x8a5c, 0x0002e667}, + {0x8a60, 0x0baa54ec}, + {0x8a64, 0xe6670022}, + {0x8a68, 0xe52e0002}, + {0x8a6c, 0x0001e49c}, + {0x8a70, 0x4380e4a9}, + {0x8a74, 0x68816340}, + {0x8a78, 0x0baa4300}, + {0x8a7c, 0xe52e3230}, + {0x8a80, 0x0001e49c}, + {0x8a84, 0x4380e4a9}, + {0x8a88, 0x68826341}, + {0x8a8c, 0x0baa4300}, + {0x8a90, 0xe52e3221}, + {0x8a94, 0x0001e49c}, + {0x8a98, 0x42fc0004}, + {0x8a9c, 0x60010007}, + {0x8aa0, 0x42000004}, + {0x8aa4, 0x62200007}, + {0x8aa8, 0x00046200}, + {0x8aac, 0x5b405501}, + {0x8ab0, 0x00076605}, + {0x8ab4, 0x63006200}, + {0x8ab8, 0x0004e54f}, + {0x8abc, 0x0a010900}, + {0x8ac0, 0x0d000b40}, + {0x8ac4, 0x00320e01}, + {0x8ac8, 0x95090004}, + {0x8acc, 0x790442fb}, + {0x8ad0, 0x43804200}, + {0x8ad4, 0x4d010007}, + {0x8ad8, 0x43000004}, + {0x8adc, 0x05620007}, + {0x8ae0, 0x961d05a3}, + {0x8ae4, 0x0004e54f}, + {0x8ae8, 0x0007e4c5}, + {0x8aec, 0x07a306a2}, + {0x8af0, 0x0004e54f}, + {0x8af4, 0xe53fe4c5}, + {0x8af8, 0xe5470002}, + {0x8afc, 0x00074380}, + {0x8b00, 0x00044d00}, + {0x8b04, 0x42fe4300}, + {0x8b08, 0x42007900}, + {0x8b0c, 0x00040001}, + {0x8b10, 0x000742fc}, + {0x8b14, 0x00046003}, + {0x8b18, 0x32d24200}, + {0x8b1c, 0x06a20007}, + {0x8b20, 0x32fc07a3}, + {0x8b24, 0xe32ee320}, + {0x8b28, 0x0001e333}, + {0x8b2c, 0xe333e320}, + {0x8b30, 0xe3270001}, + {0x8b34, 0xe333e32e}, + {0x8b38, 0xe3270001}, + {0x8b3c, 0x0001e333}, + {0x8b40, 0x42fc0004}, + {0x8b44, 0x60030007}, + {0x8b48, 0x42000004}, + {0x8b4c, 0x00040001}, + {0x8b50, 0x000742fc}, + {0x8b54, 0x00046001}, + {0x8b58, 0x00014200}, + {0x8b5c, 0x62200007}, + {0x8b60, 0xe5476200}, + {0x8b64, 0x00070001}, + {0x8b68, 0x00046300}, + {0x8b6c, 0x0a000900}, + {0x8b70, 0x00320e01}, + {0x8b74, 0x06a20007}, + {0x8b78, 0xe559e54f}, + {0x8b7c, 0x42fe0002}, + {0x8b80, 0x42007900}, + {0x8b84, 0x00050001}, + {0x8b88, 0x00077700}, + {0x8b8c, 0x00045200}, + {0x8b90, 0x000742fe}, + {0x8b94, 0x00046000}, + {0x8b98, 0x43804200}, + {0x8b9c, 0x61006000}, + {0x8ba0, 0x63106201}, + {0x8ba4, 0x00056804}, + {0x8ba8, 0x55004100}, + {0x8bac, 0x5c020007}, + {0x8bb0, 0x43000004}, + {0x8bb4, 0x00050001}, + {0x8bb8, 0xe3c96c06}, + {0x8bbc, 0xe3b8e3db}, + {0x8bc0, 0xe423e567}, + {0x8bc4, 0xe43ce56f}, + {0x8bc8, 0xe3b80001}, + {0x8bcc, 0x6c060005}, + {0x8bd0, 0xe5e6e3c9}, + {0x8bd4, 0xe423e567}, + {0x8bd8, 0xe43ce56f}, + {0x8bdc, 0x00050001}, + {0x8be0, 0xe3c96c00}, + {0x8be4, 0xe3b8e3db}, + {0x8be8, 0xe423e582}, + {0x8bec, 0xe43ce58a}, + {0x8bf0, 0xe3b80001}, + {0x8bf4, 0x6c000005}, + {0x8bf8, 0xe5e6e3c9}, + {0x8bfc, 0xe423e582}, + {0x8c00, 0xe43ce58a}, + {0x8c04, 0x00050001}, + {0x8c08, 0xe3c96c04}, + {0x8c0c, 0xe3b8e3db}, + {0x8c10, 0xe423e59d}, + {0x8c14, 0xe43ce5a5}, + {0x8c18, 0xe3b80001}, + {0x8c1c, 0x6c040005}, + {0x8c20, 0xe5e6e3c9}, + {0x8c24, 0xe423e59d}, + {0x8c28, 0xe43ce5a5}, + {0x8c2c, 0x00050001}, + {0x8c30, 0xe3c96c02}, + {0x8c34, 0xe3b8e3db}, + {0x8c38, 0xe423e5b8}, + {0x8c3c, 0xe43ce5c0}, + {0x8c40, 0xe3b80001}, + {0x8c44, 0x6c020005}, + {0x8c48, 0xe5e6e3c9}, + {0x8c4c, 0xe423e5b8}, + {0x8c50, 0xe43ce5c0}, + {0x8c54, 0x00040001}, + {0x8c58, 0x60084380}, + {0x8c5c, 0x6200610a}, + {0x8c60, 0x000663ce}, + {0x8c64, 0x7f006080}, + {0x8c68, 0x43000004}, + {0x8c6c, 0x0001e618}, + {0x8c70, 0x55000007}, + {0x8c74, 0x74200004}, + {0x8c78, 0x77117901}, + {0x8c7c, 0x57005710}, + {0x8c80, 0x7430140f}, + {0x8c84, 0x43800004}, + {0x8c88, 0x72000007}, + {0x8c8c, 0x43000004}, + {0x8c90, 0x00040001}, + {0x8c94, 0x00057420}, + {0x8c98, 0x7e067700}, + {0x8c9c, 0x73807388}, + {0x8ca0, 0x140f8f00}, + {0x8ca4, 0x74300004}, + {0x8ca8, 0x73000005}, + {0x8cac, 0xe5d30001}, + {0x8cb0, 0x73000005}, + {0x8cb4, 0x00040001}, + {0x8cb8, 0xb1034380}, + {0x8cbc, 0x7cdb0006}, + {0x8cc0, 0x00079103}, + {0x8cc4, 0x000440db}, + {0x8cc8, 0xe5d34300}, + {0x8ccc, 0x73800005}, + {0x8cd0, 0x5d010006}, + {0x8cd4, 0x62006002}, + {0x8cd8, 0x0005e5f7}, + {0x8cdc, 0x00077300}, + {0x8ce0, 0x75787608}, + {0x8ce4, 0x43800004}, + {0x8ce8, 0x5e010007}, + {0x8cec, 0x140a5e00}, + {0x8cf0, 0x63800006}, + {0x8cf4, 0x00077f00}, + {0x8cf8, 0x4e204c3f}, + {0x8cfc, 0x73047280}, + {0x8d00, 0x140a7300}, + {0x8d04, 0x00044d20}, + {0x8d08, 0x00064300}, + {0x8d0c, 0x00077402}, + {0x8d10, 0x40004001}, + {0x8d14, 0x0006ab00}, + {0x8d18, 0x00077404}, + {0x8d1c, 0x40004001}, + {0x8d20, 0x140aab00}, + {0x8d24, 0x43800004}, + {0x8d28, 0x52800007}, + {0x8d2c, 0x140a5200}, + {0x8d30, 0x4d004c00}, + {0x8d34, 0x00064e00}, + {0x8d38, 0x63006080}, + {0x8d3c, 0x43000004}, + {0x8d40, 0x76000007}, + {0x8d44, 0x00040001}, + {0x8d48, 0xb1034380}, + {0x8d4c, 0x7cdb0006}, + {0x8d50, 0x00079103}, + {0x8d54, 0x000440db}, + {0x8d58, 0xe5d34300}, + {0x8d5c, 0xe5f77e03}, + {0x8d60, 0x43800004}, + {0x8d64, 0x0006b103}, + {0x8d68, 0x91037c5b}, + {0x8d6c, 0x405b0007}, + {0x8d70, 0x43000004}, + {0x8d74, 0x00010001}, + {0x8d78, 0x43800004}, + {0x8d7c, 0x4e200007}, + {0x8d80, 0x63800006}, + {0x8d84, 0x5f807cdb}, + {0x8d88, 0x43000004}, + {0x8d8c, 0x76080007}, + {0x8d90, 0x00057560}, + {0x8d94, 0x00047380}, + {0x8d98, 0x0005420e}, + {0x8d9c, 0x92006c01}, + {0x8da0, 0x6c001432}, + {0x8da4, 0x42000004}, + {0x8da8, 0x43800004}, + {0x8dac, 0x5f000006}, + {0x8db0, 0x73010007}, + {0x8db4, 0x00047300}, + {0x8db8, 0x0007420f}, + {0x8dbc, 0x52005280}, + {0x8dc0, 0x0004140a}, + {0x8dc4, 0x00064200}, + {0x8dc8, 0x7c5b6300}, + {0x8dcc, 0x4e000007}, + {0x8dd0, 0x43000004}, + {0x8dd4, 0x73000005}, + {0x8dd8, 0x76000007}, + {0x8ddc, 0xe5fb0001}, + {0x8de0, 0x00040001}, + {0x8de4, 0x60004380}, + {0x8de8, 0x62016100}, + {0x8dec, 0x00066310}, + {0x8df0, 0x00046000}, + {0x8df4, 0x00014300}, + {0x8df8, 0x0001e618}, + {0x8dfc, 0x4e004f02}, + {0x8e00, 0x52015302}, + {0x8e04, 0x140f0001}, + {0x8e08, 0x00019700}, + {0x8e0c, 0x8a084380}, + {0x8e10, 0x7800aa09}, + {0x8e14, 0x7a007900}, + {0x8e18, 0x43007b40}, + {0x8e1c, 0x65010001}, + {0x8e20, 0x67013489}, + {0x8e24, 0x43803489}, + {0x8e28, 0xaa058a04}, + {0x8e2c, 0x00014300}, + {0x8e30, 0x34966500}, + {0x8e34, 0x34966700}, + {0x8e38, 0x8a084380}, + {0x8e3c, 0x7c00aa09}, + {0x8e40, 0x7e007d00}, + {0x8e44, 0x43007f40}, + {0x8e48, 0x64010001}, + {0x8e4c, 0x6601349f}, + {0x8e50, 0x4380349f}, + {0x8e54, 0xaa058a04}, + {0x8e58, 0x00014300}, + {0x8e5c, 0x34ac6400}, + {0x8e60, 0x34ac6600}, + {0x8e64, 0x7b484380}, + {0x8e68, 0x79007a90}, + {0x8e6c, 0x43007802}, + {0x8e70, 0x34c95503}, + {0x8e74, 0x7b384380}, + {0x8e78, 0x43007a80}, + {0x8e7c, 0x34c95513}, + {0x8e80, 0x7b404380}, + {0x8e84, 0x43007a00}, + {0x8e88, 0x74015523}, + {0x8e8c, 0x8e007400}, + {0x8e90, 0x00070001}, + {0x8e94, 0x00045230}, + {0x8e98, 0x74307431}, + {0x8e9c, 0x00078e00}, + {0x8ea0, 0x00045220}, + {0x8ea4, 0x57020001}, + {0x8ea8, 0x8e005700}, + {0x8eac, 0x42ef0001}, + {0x8eb0, 0x56005610}, + {0x8eb4, 0x8c004200}, + {0x8eb8, 0x5b500001}, + {0x8ebc, 0x5b2034e0}, + {0x8ec0, 0x4e004f78}, + {0x8ec4, 0x52015388}, + {0x8ec8, 0x4e004f78}, + {0x8ecc, 0x52015388}, + {0x8ed0, 0x5480e4f2}, + {0x8ed4, 0x54815400}, + {0x8ed8, 0x54825400}, + {0x8edc, 0xe4fd5400}, + {0x8ee0, 0x3010bf1d}, + {0x8ee4, 0xe4bae4b2}, + {0x8ee8, 0xe4d3e4c0}, + {0x8eec, 0x5523e65b}, + {0x8ef0, 0x5525e4c9}, + {0x8ef4, 0xe65be4d3}, + {0x8ef8, 0x54bf0001}, + {0x8efc, 0x54a354c0}, + {0x8f00, 0x54a454c1}, + {0x8f04, 0xbf074c18}, + {0x8f08, 0x54a454c2}, + {0x8f0c, 0x54c1bf04}, + {0x8f10, 0xbf0154a3}, + {0x8f14, 0x54dfe66c}, + {0x8f18, 0x54bf0001}, + {0x8f1c, 0x050a54e5}, + {0x8f20, 0x000154df}, + {0x8f24, 0x7b801657}, + {0x8f28, 0x43807430}, + {0x8f2c, 0x7e007f40}, + {0x8f30, 0x7c027d00}, + {0x8f34, 0x5b404300}, + {0x8f38, 0x5c015501}, + {0x8f3c, 0x5480e4d7}, + {0x8f40, 0x54815400}, + {0x8f44, 0x54825400}, + {0x8f48, 0x7b005400}, + {0x8f4c, 0xe4fd7410}, + {0x8f50, 0x3010bfe5}, + {0x8f54, 0x56005610}, + {0x8f58, 0x00018c00}, + {0x8f5c, 0x57005704}, + {0x8f60, 0x57088e00}, + {0x8f64, 0x8e005700}, + {0x8f68, 0x57805781}, + {0x8f6c, 0x43808e00}, + {0x8f70, 0x5c010007}, + {0x8f74, 0x14035c00}, + {0x8f78, 0x43000004}, + {0x8f7c, 0x427f0001}, + {0x8f80, 0x62800007}, + {0x8f84, 0x92006200}, + {0x8f88, 0x42000004}, + {0x8f8c, 0x427f0001}, + {0x8f90, 0x63940007}, + {0x8f94, 0x92006314}, + {0x8f98, 0x42000004}, + {0x8f9c, 0x00040001}, + {0x8fa0, 0x790142fe}, + {0x8fa4, 0x74204200}, + {0x8fa8, 0x5710140f}, + {0x8fac, 0x141f5700}, + {0x8fb0, 0x00040001}, + {0x8fb4, 0x790142fe}, + {0x8fb8, 0x74204200}, + {0x8fbc, 0x42bf140f}, + {0x8fc0, 0x62400007}, + {0x8fc4, 0x141f6200}, + {0x8fc8, 0x42000004}, + {0x8fcc, 0x00060001}, + {0x8fd0, 0x60035d06}, + {0x8fd4, 0x62016104}, + {0x8fd8, 0x73100005}, + {0x8fdc, 0x00040001}, + {0x8fe0, 0x00074380}, + {0x8fe4, 0x5e005e01}, + {0x8fe8, 0xb103140a}, + {0x8fec, 0x7f070006}, + {0x8ff0, 0x00079103}, + {0x8ff4, 0x00064307}, + {0x8ff8, 0x5d025c00}, + {0x8ffc, 0x00045e03}, + {0x9000, 0x00014300}, + {0x9004, 0x5d040006}, + {0x9008, 0x61046000}, + {0x900c, 0x00056201}, + {0x9010, 0x00017310}, + {0x9014, 0x43800004}, + {0x9018, 0x5e010007}, + {0x901c, 0x140a5e00}, + {0x9020, 0x0006b103}, + {0x9024, 0x91037fc6}, + {0x9028, 0x43c60007}, + {0x902c, 0x5c000006}, + {0x9030, 0x5e035d02}, + {0x9034, 0x43000004}, + {0x9038, 0x00060001}, + {0x903c, 0x60005d04}, + {0x9040, 0x62016104}, + {0x9044, 0x73100005}, + {0x9048, 0x00040001}, + {0x904c, 0x00074380}, + {0x9050, 0x5e005e01}, + {0x9054, 0xb103140a}, + {0x9058, 0x7fc60006}, + {0x905c, 0x00079103}, + {0x9060, 0x000643c6}, + {0x9064, 0x5d025c00}, + {0x9068, 0x00045e03}, + {0x906c, 0x00014300}, + {0x9070, 0x5d000006}, + {0x9074, 0x61006002}, + {0x9078, 0x00056201}, + {0x907c, 0x00017300}, + {0x9080, 0x43800004}, + {0x9084, 0x5e010007}, + {0x9088, 0x140a5e00}, + {0x908c, 0x0006b103}, + {0x9090, 0x91037fc0}, + {0x9094, 0x43c00007}, + {0x9098, 0x5c000006}, + {0x909c, 0x5e035d02}, + {0x90a0, 0x43000004}, + {0x90a4, 0x00050001}, + {0x90a8, 0x00047e02}, + {0x90ac, 0x000542f7}, + {0x90b0, 0x00046c08}, + {0x90b4, 0x00054270}, + {0x90b8, 0x73807381}, + {0x90bc, 0x00049300}, + {0x90c0, 0x000542f7}, + {0x90c4, 0x00046c00}, + {0x90c8, 0x00014200}, + {0x90cc, 0x43800004}, + {0x90d0, 0x73040007}, + {0x90d4, 0x14057300}, + {0x90d8, 0x00047240}, + {0x90dc, 0x00064300}, + {0x90e0, 0x00077404}, + {0x90e4, 0x40004001}, + {0x90e8, 0x140fab00}, + {0x90ec, 0xe64f0001}, + {0x90f0, 0xe656e5fb}, + {0x90f4, 0x00040001}, + {0x90f8, 0x00047410}, + {0x90fc, 0x42f04380}, + {0x9100, 0x62080007}, + {0x9104, 0x24206301}, + {0x9108, 0x14c80000}, + {0x910c, 0x00002428}, + {0x9110, 0x1a4215f4}, + {0x9114, 0x6300000b}, + {0x9118, 0x42000004}, + {0x911c, 0x74304300}, + {0x9120, 0x4380140f}, + {0x9124, 0x73080007}, + {0x9128, 0x00047300}, + {0x912c, 0x00014300}, + {0x9130, 0x4bf00007}, + {0x9134, 0x490b4a8f}, + {0x9138, 0x4a8e48f1}, + {0x913c, 0x48a5490a}, + {0x9140, 0x49094a8d}, + {0x9144, 0x4a8c487d}, + {0x9148, 0x48754908}, + {0x914c, 0x49074a8b}, + {0x9150, 0x4a8a4889}, + {0x9154, 0x48b74906}, + {0x9158, 0x49054a89}, + {0x915c, 0x4a8848fc}, + {0x9160, 0x48564905}, + {0x9164, 0x49044a87}, + {0x9168, 0x4a8648c1}, + {0x916c, 0x483d4904}, + {0x9170, 0x49034a85}, + {0x9174, 0x4a8448c7}, + {0x9178, 0x485e4903}, + {0x917c, 0x49024a83}, + {0x9180, 0x4a8248ac}, + {0x9184, 0x48624902}, + {0x9188, 0x49024a81}, + {0x918c, 0x4a804820}, + {0x9190, 0x48004900}, + {0x9194, 0x49014a90}, + {0x9198, 0x4a10481f}, + {0x919c, 0x00060001}, + {0x91a0, 0x5f005f80}, + {0x91a4, 0x00059900}, + {0x91a8, 0x00017300}, + {0x91ac, 0x63800006}, + {0x91b0, 0x98006300}, + {0x91b4, 0x549f0001}, + {0x91b8, 0x5c015400}, + {0x91bc, 0x540054df}, + {0x91c0, 0x00015c02}, + {0x91c4, 0x07145c01}, + {0x91c8, 0x5c025400}, + {0x91cc, 0x5c020001}, + {0x91d0, 0x54000714}, + {0x91d4, 0x00015c01}, + {0x91d8, 0x4c184c98}, + {0x91dc, 0x00080001}, + {0x91e0, 0x5c020004}, + {0x91e4, 0x09017430}, + {0x91e8, 0x0ba60c01}, + {0x91ec, 0x77800005}, + {0x91f0, 0x52200007}, + {0x91f4, 0x43800004}, + {0x91f8, 0x610a6008}, + {0x91fc, 0x63c26200}, + {0x9200, 0x5c000007}, + {0x9204, 0x43000004}, + {0x9208, 0x00000001}, + {0x8080, 0x00000004}, + {0x8080, 0x00000000}, + {0x8088, 0x00000000}, +}; + +static const struct rtw89_txpwr_byrate_cfg rtw89_8852c_txpwr_byrate[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x50505050, }, + { 0, 0, 1, 4, 4, 0x484c5050, }, + { 0, 0, 2, 0, 4, 0x50505050, }, + { 0, 0, 2, 4, 4, 0x44484c50, }, + { 0, 0, 2, 8, 4, 0x34383c40, }, + { 0, 0, 3, 0, 4, 0x50505050, }, + { 0, 1, 2, 0, 4, 0x50505050, }, + { 0, 1, 2, 4, 4, 0x44484c50, }, + { 0, 1, 2, 8, 4, 0x34383c40, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x48484848, }, + { 1, 0, 1, 4, 4, 0x40444848, }, + { 1, 0, 2, 0, 4, 0x48484848, }, + { 1, 0, 2, 4, 4, 0x3c404448, }, + { 1, 0, 2, 8, 4, 0x2c303438, }, + { 1, 0, 3, 0, 4, 0x48484848, }, + { 1, 1, 2, 0, 4, 0x48484848, }, + { 1, 1, 2, 4, 4, 0x3c404448, }, + { 1, 1, 2, 8, 4, 0x2c303438, }, + { 1, 1, 3, 0, 4, 0x48484848, }, + { 1, 0, 4, 0, 4, 0x00000000, }, + { 2, 0, 1, 0, 4, 0x40404040, }, + { 2, 0, 1, 4, 4, 0x383c4040, }, + { 2, 0, 2, 0, 4, 0x40404040, }, + { 2, 0, 2, 4, 4, 0x34383c40, }, + { 2, 0, 2, 8, 4, 0x20282c30, }, + { 2, 0, 3, 0, 4, 0x40404040, }, + { 2, 1, 2, 0, 4, 0x40404040, }, + { 2, 1, 2, 4, 4, 0x34383c40, }, + { 2, 1, 2, 8, 4, 0x20282c30, }, + { 2, 1, 3, 0, 4, 0x40404040, }, + { 2, 0, 4, 0, 4, 0x00000000, }, +}; + +static const s8 _txpwr_track_delta_swingidx_6gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, +}; + +static const s8 _txpwr_track_delta_swingidx_6gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, +}; + +static const s8 _txpwr_track_delta_swingidx_6ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, +}; + +static const s8 _txpwr_track_delta_swingidx_6ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8}, + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3 +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5 +}; + +static +const u8 rtw89_8852c_tx_shape_lmt[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] + [RTW89_REGD_NUM] = { + [0][0][RTW89_ACMA] = 0, + [0][0][RTW89_CHILE] = 0, + [0][0][RTW89_CN] = 0, + [0][0][RTW89_ETSI] = 0, + [0][0][RTW89_FCC] = 1, + [0][0][RTW89_IC] = 1, + [0][0][RTW89_KCC] = 0, + [0][0][RTW89_MEXICO] = 1, + [0][0][RTW89_MKK] = 0, + [0][0][RTW89_QATAR] = 0, + [0][0][RTW89_THAILAND] = 0, + [0][0][RTW89_UK] = 0, + [0][0][RTW89_UKRAINE] = 0, + [0][1][RTW89_ACMA] = 0, + [0][1][RTW89_CHILE] = 0, + [0][1][RTW89_CN] = 0, + [0][1][RTW89_ETSI] = 0, + [0][1][RTW89_FCC] = 3, + [0][1][RTW89_IC] = 3, + [0][1][RTW89_KCC] = 0, + [0][1][RTW89_MEXICO] = 3, + [0][1][RTW89_MKK] = 0, + [0][1][RTW89_QATAR] = 0, + [0][1][RTW89_THAILAND] = 0, + [0][1][RTW89_UK] = 0, + [0][1][RTW89_UKRAINE] = 0, + [1][1][RTW89_ACMA] = 0, + [1][1][RTW89_CHILE] = 0, + [1][1][RTW89_CN] = 0, + [1][1][RTW89_ETSI] = 0, + [1][1][RTW89_FCC] = 3, + [1][1][RTW89_IC] = 3, + [1][1][RTW89_KCC] = 0, + [1][1][RTW89_MEXICO] = 3, + [1][1][RTW89_MKK] = 0, + [1][1][RTW89_QATAR] = 0, + [1][1][RTW89_THAILAND] = 0, + [1][1][RTW89_UK] = 0, + [1][1][RTW89_UKRAINE] = 0, + [2][1][RTW89_ACMA] = 0, + [2][1][RTW89_CHILE] = 0, + [2][1][RTW89_ETSI] = 0, + [2][1][RTW89_FCC] = 0, + [2][1][RTW89_IC] = 0, + [2][1][RTW89_KCC] = 0, + [2][1][RTW89_MKK] = 0, + [2][1][RTW89_QATAR] = 0, + [2][1][RTW89_THAILAND] = 0, + [2][1][RTW89_UK] = 0, +}; + +static +const u8 rtw89_8852c_tx_shape_lmt_ru[RTW89_BAND_NUM][RTW89_REGD_NUM] = { + [0][RTW89_ACMA] = 0, + [0][RTW89_CHILE] = 0, + [0][RTW89_CN] = 0, + [0][RTW89_ETSI] = 0, + [0][RTW89_FCC] = 3, + [0][RTW89_IC] = 3, + [0][RTW89_KCC] = 0, + [0][RTW89_MEXICO] = 3, + [0][RTW89_MKK] = 0, + [0][RTW89_QATAR] = 0, + [0][RTW89_THAILAND] = 0, + [0][RTW89_UK] = 0, + [0][RTW89_UKRAINE] = 0, + [1][RTW89_ACMA] = 0, + [1][RTW89_CHILE] = 0, + [1][RTW89_CN] = 0, + [1][RTW89_ETSI] = 0, + [1][RTW89_FCC] = 3, + [1][RTW89_IC] = 3, + [1][RTW89_KCC] = 0, + [1][RTW89_MEXICO] = 3, + [1][RTW89_MKK] = 0, + [1][RTW89_QATAR] = 0, + [1][RTW89_THAILAND] = 0, + [1][RTW89_UK] = 0, + [1][RTW89_UKRAINE] = 0, + [2][RTW89_ACMA] = 0, + [2][RTW89_CHILE] = 0, + [2][RTW89_ETSI] = 0, + [2][RTW89_FCC] = 0, + [2][RTW89_IC] = 0, + [2][RTW89_KCC] = 0, + [2][RTW89_MKK] = 0, + [2][RTW89_QATAR] = 0, + [2][RTW89_THAILAND] = 0, + [2][RTW89_UK] = 0, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 56, + [0][0][0][0][RTW89_WW][1] = 56, + [0][0][0][0][RTW89_WW][2] = 56, + [0][0][0][0][RTW89_WW][3] = 56, + [0][0][0][0][RTW89_WW][4] = 56, + [0][0][0][0][RTW89_WW][5] = 56, + [0][0][0][0][RTW89_WW][6] = 56, + [0][0][0][0][RTW89_WW][7] = 56, + [0][0][0][0][RTW89_WW][8] = 56, + [0][0][0][0][RTW89_WW][9] = 56, + [0][0][0][0][RTW89_WW][10] = 56, + [0][0][0][0][RTW89_WW][11] = 56, + [0][0][0][0][RTW89_WW][12] = 46, + [0][0][0][0][RTW89_WW][13] = 72, + [0][1][0][0][RTW89_WW][0] = 42, + [0][1][0][0][RTW89_WW][1] = 42, + [0][1][0][0][RTW89_WW][2] = 42, + [0][1][0][0][RTW89_WW][3] = 42, + [0][1][0][0][RTW89_WW][4] = 42, + [0][1][0][0][RTW89_WW][5] = 42, + [0][1][0][0][RTW89_WW][6] = 42, + [0][1][0][0][RTW89_WW][7] = 42, + [0][1][0][0][RTW89_WW][8] = 42, + [0][1][0][0][RTW89_WW][9] = 42, + [0][1][0][0][RTW89_WW][10] = 42, + [0][1][0][0][RTW89_WW][11] = 42, + [0][1][0][0][RTW89_WW][12] = 18, + [0][1][0][0][RTW89_WW][13] = 60, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 44, + [1][0][0][0][RTW89_WW][3] = 56, + [1][0][0][0][RTW89_WW][4] = 56, + [1][0][0][0][RTW89_WW][5] = 56, + [1][0][0][0][RTW89_WW][6] = 46, + [1][0][0][0][RTW89_WW][7] = 46, + [1][0][0][0][RTW89_WW][8] = 28, + [1][0][0][0][RTW89_WW][9] = 26, + [1][0][0][0][RTW89_WW][10] = 26, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 44, + [1][1][0][0][RTW89_WW][3] = 44, + [1][1][0][0][RTW89_WW][4] = 44, + [1][1][0][0][RTW89_WW][5] = 44, + [1][1][0][0][RTW89_WW][6] = 40, + [1][1][0][0][RTW89_WW][7] = 40, + [1][1][0][0][RTW89_WW][8] = 14, + [1][1][0][0][RTW89_WW][9] = 14, + [1][1][0][0][RTW89_WW][10] = 12, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 58, + [0][0][1][0][RTW89_WW][1] = 58, + [0][0][1][0][RTW89_WW][2] = 58, + [0][0][1][0][RTW89_WW][3] = 58, + [0][0][1][0][RTW89_WW][4] = 58, + [0][0][1][0][RTW89_WW][5] = 58, + [0][0][1][0][RTW89_WW][6] = 58, + [0][0][1][0][RTW89_WW][7] = 58, + [0][0][1][0][RTW89_WW][8] = 58, + [0][0][1][0][RTW89_WW][9] = 58, + [0][0][1][0][RTW89_WW][10] = 58, + [0][0][1][0][RTW89_WW][11] = 58, + [0][0][1][0][RTW89_WW][12] = 40, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 46, + [0][1][1][0][RTW89_WW][1] = 46, + [0][1][1][0][RTW89_WW][2] = 46, + [0][1][1][0][RTW89_WW][3] = 46, + [0][1][1][0][RTW89_WW][4] = 46, + [0][1][1][0][RTW89_WW][5] = 46, + [0][1][1][0][RTW89_WW][6] = 46, + [0][1][1][0][RTW89_WW][7] = 46, + [0][1][1][0][RTW89_WW][8] = 46, + [0][1][1][0][RTW89_WW][9] = 46, + [0][1][1][0][RTW89_WW][10] = 46, + [0][1][1][0][RTW89_WW][11] = 46, + [0][1][1][0][RTW89_WW][12] = 36, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 58, + [0][0][2][0][RTW89_WW][1] = 58, + [0][0][2][0][RTW89_WW][2] = 58, + [0][0][2][0][RTW89_WW][3] = 58, + [0][0][2][0][RTW89_WW][4] = 58, + [0][0][2][0][RTW89_WW][5] = 58, + [0][0][2][0][RTW89_WW][6] = 58, + [0][0][2][0][RTW89_WW][7] = 58, + [0][0][2][0][RTW89_WW][8] = 58, + [0][0][2][0][RTW89_WW][9] = 58, + [0][0][2][0][RTW89_WW][10] = 58, + [0][0][2][0][RTW89_WW][11] = 58, + [0][0][2][0][RTW89_WW][12] = 38, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 46, + [0][1][2][0][RTW89_WW][1] = 46, + [0][1][2][0][RTW89_WW][2] = 46, + [0][1][2][0][RTW89_WW][3] = 46, + [0][1][2][0][RTW89_WW][4] = 46, + [0][1][2][0][RTW89_WW][5] = 46, + [0][1][2][0][RTW89_WW][6] = 46, + [0][1][2][0][RTW89_WW][7] = 46, + [0][1][2][0][RTW89_WW][8] = 46, + [0][1][2][0][RTW89_WW][9] = 46, + [0][1][2][0][RTW89_WW][10] = 46, + [0][1][2][0][RTW89_WW][11] = 46, + [0][1][2][0][RTW89_WW][12] = 16, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 34, + [0][1][2][1][RTW89_WW][1] = 34, + [0][1][2][1][RTW89_WW][2] = 34, + [0][1][2][1][RTW89_WW][3] = 34, + [0][1][2][1][RTW89_WW][4] = 34, + [0][1][2][1][RTW89_WW][5] = 34, + [0][1][2][1][RTW89_WW][6] = 34, + [0][1][2][1][RTW89_WW][7] = 34, + [0][1][2][1][RTW89_WW][8] = 34, + [0][1][2][1][RTW89_WW][9] = 34, + [0][1][2][1][RTW89_WW][10] = 34, + [0][1][2][1][RTW89_WW][11] = 34, + [0][1][2][1][RTW89_WW][12] = 16, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 58, + [1][0][2][0][RTW89_WW][3] = 58, + [1][0][2][0][RTW89_WW][4] = 58, + [1][0][2][0][RTW89_WW][5] = 58, + [1][0][2][0][RTW89_WW][6] = 58, + [1][0][2][0][RTW89_WW][7] = 58, + [1][0][2][0][RTW89_WW][8] = 58, + [1][0][2][0][RTW89_WW][9] = 58, + [1][0][2][0][RTW89_WW][10] = 56, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 34, + [1][1][2][0][RTW89_WW][3] = 34, + [1][1][2][0][RTW89_WW][4] = 34, + [1][1][2][0][RTW89_WW][5] = 34, + [1][1][2][0][RTW89_WW][6] = 34, + [1][1][2][0][RTW89_WW][7] = 34, + [1][1][2][0][RTW89_WW][8] = 34, + [1][1][2][0][RTW89_WW][9] = 34, + [1][1][2][0][RTW89_WW][10] = 34, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 34, + [1][1][2][1][RTW89_WW][3] = 34, + [1][1][2][1][RTW89_WW][4] = 34, + [1][1][2][1][RTW89_WW][5] = 34, + [1][1][2][1][RTW89_WW][6] = 34, + [1][1][2][1][RTW89_WW][7] = 34, + [1][1][2][1][RTW89_WW][8] = 34, + [1][1][2][1][RTW89_WW][9] = 34, + [1][1][2][1][RTW89_WW][10] = 34, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 76, + [0][0][0][0][RTW89_ETSI][0] = 60, + [0][0][0][0][RTW89_MKK][0] = 68, + [0][0][0][0][RTW89_IC][0] = 76, + [0][0][0][0][RTW89_KCC][0] = 68, + [0][0][0][0][RTW89_ACMA][0] = 60, + [0][0][0][0][RTW89_CN][0] = 56, + [0][0][0][0][RTW89_UK][0] = 60, + [0][0][0][0][RTW89_MEXICO][0] = 76, + [0][0][0][0][RTW89_UKRAINE][0] = 60, + [0][0][0][0][RTW89_CHILE][0] = 76, + [0][0][0][0][RTW89_QATAR][0] = 60, + [0][0][0][0][RTW89_THAILAND][0] = 60, + [0][0][0][0][RTW89_FCC][1] = 76, + [0][0][0][0][RTW89_ETSI][1] = 60, + [0][0][0][0][RTW89_MKK][1] = 68, + [0][0][0][0][RTW89_IC][1] = 76, + [0][0][0][0][RTW89_KCC][1] = 68, + [0][0][0][0][RTW89_ACMA][1] = 60, + [0][0][0][0][RTW89_CN][1] = 56, + [0][0][0][0][RTW89_UK][1] = 60, + [0][0][0][0][RTW89_MEXICO][1] = 76, + [0][0][0][0][RTW89_UKRAINE][1] = 60, + [0][0][0][0][RTW89_CHILE][1] = 68, + [0][0][0][0][RTW89_QATAR][1] = 60, + [0][0][0][0][RTW89_THAILAND][1] = 60, + [0][0][0][0][RTW89_FCC][2] = 76, + [0][0][0][0][RTW89_ETSI][2] = 60, + [0][0][0][0][RTW89_MKK][2] = 68, + [0][0][0][0][RTW89_IC][2] = 76, + [0][0][0][0][RTW89_KCC][2] = 68, + [0][0][0][0][RTW89_ACMA][2] = 60, + [0][0][0][0][RTW89_CN][2] = 56, + [0][0][0][0][RTW89_UK][2] = 60, + [0][0][0][0][RTW89_MEXICO][2] = 76, + [0][0][0][0][RTW89_UKRAINE][2] = 60, + [0][0][0][0][RTW89_CHILE][2] = 68, + [0][0][0][0][RTW89_QATAR][2] = 60, + [0][0][0][0][RTW89_THAILAND][2] = 60, + [0][0][0][0][RTW89_FCC][3] = 76, + [0][0][0][0][RTW89_ETSI][3] = 60, + [0][0][0][0][RTW89_MKK][3] = 68, + [0][0][0][0][RTW89_IC][3] = 76, + [0][0][0][0][RTW89_KCC][3] = 68, + [0][0][0][0][RTW89_ACMA][3] = 60, + [0][0][0][0][RTW89_CN][3] = 56, + [0][0][0][0][RTW89_UK][3] = 60, + [0][0][0][0][RTW89_MEXICO][3] = 76, + [0][0][0][0][RTW89_UKRAINE][3] = 60, + [0][0][0][0][RTW89_CHILE][3] = 68, + [0][0][0][0][RTW89_QATAR][3] = 60, + [0][0][0][0][RTW89_THAILAND][3] = 60, + [0][0][0][0][RTW89_FCC][4] = 76, + [0][0][0][0][RTW89_ETSI][4] = 60, + [0][0][0][0][RTW89_MKK][4] = 68, + [0][0][0][0][RTW89_IC][4] = 76, + [0][0][0][0][RTW89_KCC][4] = 68, + [0][0][0][0][RTW89_ACMA][4] = 60, + [0][0][0][0][RTW89_CN][4] = 56, + [0][0][0][0][RTW89_UK][4] = 60, + [0][0][0][0][RTW89_MEXICO][4] = 76, + [0][0][0][0][RTW89_UKRAINE][4] = 60, + [0][0][0][0][RTW89_CHILE][4] = 68, + [0][0][0][0][RTW89_QATAR][4] = 60, + [0][0][0][0][RTW89_THAILAND][4] = 60, + [0][0][0][0][RTW89_FCC][5] = 76, + [0][0][0][0][RTW89_ETSI][5] = 60, + [0][0][0][0][RTW89_MKK][5] = 68, + [0][0][0][0][RTW89_IC][5] = 76, + [0][0][0][0][RTW89_KCC][5] = 68, + [0][0][0][0][RTW89_ACMA][5] = 60, + [0][0][0][0][RTW89_CN][5] = 56, + [0][0][0][0][RTW89_UK][5] = 60, + [0][0][0][0][RTW89_MEXICO][5] = 76, + [0][0][0][0][RTW89_UKRAINE][5] = 60, + [0][0][0][0][RTW89_CHILE][5] = 76, + [0][0][0][0][RTW89_QATAR][5] = 60, + [0][0][0][0][RTW89_THAILAND][5] = 60, + [0][0][0][0][RTW89_FCC][6] = 76, + [0][0][0][0][RTW89_ETSI][6] = 60, + [0][0][0][0][RTW89_MKK][6] = 68, + [0][0][0][0][RTW89_IC][6] = 76, + [0][0][0][0][RTW89_KCC][6] = 68, + [0][0][0][0][RTW89_ACMA][6] = 60, + [0][0][0][0][RTW89_CN][6] = 56, + [0][0][0][0][RTW89_UK][6] = 60, + [0][0][0][0][RTW89_MEXICO][6] = 76, + [0][0][0][0][RTW89_UKRAINE][6] = 60, + [0][0][0][0][RTW89_CHILE][6] = 76, + [0][0][0][0][RTW89_QATAR][6] = 60, + [0][0][0][0][RTW89_THAILAND][6] = 60, + [0][0][0][0][RTW89_FCC][7] = 76, + [0][0][0][0][RTW89_ETSI][7] = 60, + [0][0][0][0][RTW89_MKK][7] = 68, + [0][0][0][0][RTW89_IC][7] = 76, + [0][0][0][0][RTW89_KCC][7] = 68, + [0][0][0][0][RTW89_ACMA][7] = 60, + [0][0][0][0][RTW89_CN][7] = 56, + [0][0][0][0][RTW89_UK][7] = 60, + [0][0][0][0][RTW89_MEXICO][7] = 76, + [0][0][0][0][RTW89_UKRAINE][7] = 60, + [0][0][0][0][RTW89_CHILE][7] = 76, + [0][0][0][0][RTW89_QATAR][7] = 60, + [0][0][0][0][RTW89_THAILAND][7] = 60, + [0][0][0][0][RTW89_FCC][8] = 76, + [0][0][0][0][RTW89_ETSI][8] = 60, + [0][0][0][0][RTW89_MKK][8] = 68, + [0][0][0][0][RTW89_IC][8] = 76, + [0][0][0][0][RTW89_KCC][8] = 68, + [0][0][0][0][RTW89_ACMA][8] = 60, + [0][0][0][0][RTW89_CN][8] = 56, + [0][0][0][0][RTW89_UK][8] = 60, + [0][0][0][0][RTW89_MEXICO][8] = 76, + [0][0][0][0][RTW89_UKRAINE][8] = 60, + [0][0][0][0][RTW89_CHILE][8] = 76, + [0][0][0][0][RTW89_QATAR][8] = 60, + [0][0][0][0][RTW89_THAILAND][8] = 60, + [0][0][0][0][RTW89_FCC][9] = 76, + [0][0][0][0][RTW89_ETSI][9] = 60, + [0][0][0][0][RTW89_MKK][9] = 68, + [0][0][0][0][RTW89_IC][9] = 76, + [0][0][0][0][RTW89_KCC][9] = 70, + [0][0][0][0][RTW89_ACMA][9] = 60, + [0][0][0][0][RTW89_CN][9] = 56, + [0][0][0][0][RTW89_UK][9] = 60, + [0][0][0][0][RTW89_MEXICO][9] = 76, + [0][0][0][0][RTW89_UKRAINE][9] = 60, + [0][0][0][0][RTW89_CHILE][9] = 76, + [0][0][0][0][RTW89_QATAR][9] = 60, + [0][0][0][0][RTW89_THAILAND][9] = 60, + [0][0][0][0][RTW89_FCC][10] = 76, + [0][0][0][0][RTW89_ETSI][10] = 60, + [0][0][0][0][RTW89_MKK][10] = 68, + [0][0][0][0][RTW89_IC][10] = 76, + [0][0][0][0][RTW89_KCC][10] = 70, + [0][0][0][0][RTW89_ACMA][10] = 60, + [0][0][0][0][RTW89_CN][10] = 56, + [0][0][0][0][RTW89_UK][10] = 60, + [0][0][0][0][RTW89_MEXICO][10] = 76, + [0][0][0][0][RTW89_UKRAINE][10] = 60, + [0][0][0][0][RTW89_CHILE][10] = 76, + [0][0][0][0][RTW89_QATAR][10] = 60, + [0][0][0][0][RTW89_THAILAND][10] = 60, + [0][0][0][0][RTW89_FCC][11] = 58, + [0][0][0][0][RTW89_ETSI][11] = 60, + [0][0][0][0][RTW89_MKK][11] = 68, + [0][0][0][0][RTW89_IC][11] = 58, + [0][0][0][0][RTW89_KCC][11] = 70, + [0][0][0][0][RTW89_ACMA][11] = 60, + [0][0][0][0][RTW89_CN][11] = 56, + [0][0][0][0][RTW89_UK][11] = 60, + [0][0][0][0][RTW89_MEXICO][11] = 58, + [0][0][0][0][RTW89_UKRAINE][11] = 60, + [0][0][0][0][RTW89_CHILE][11] = 58, + [0][0][0][0][RTW89_QATAR][11] = 60, + [0][0][0][0][RTW89_THAILAND][11] = 60, + [0][0][0][0][RTW89_FCC][12] = 46, + [0][0][0][0][RTW89_ETSI][12] = 60, + [0][0][0][0][RTW89_MKK][12] = 68, + [0][0][0][0][RTW89_IC][12] = 46, + [0][0][0][0][RTW89_KCC][12] = 70, + [0][0][0][0][RTW89_ACMA][12] = 60, + [0][0][0][0][RTW89_CN][12] = 56, + [0][0][0][0][RTW89_UK][12] = 60, + [0][0][0][0][RTW89_MEXICO][12] = 46, + [0][0][0][0][RTW89_UKRAINE][12] = 60, + [0][0][0][0][RTW89_CHILE][12] = 46, + [0][0][0][0][RTW89_QATAR][12] = 60, + [0][0][0][0][RTW89_THAILAND][12] = 60, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 72, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_KCC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][0][0][0][RTW89_CN][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, + [0][0][0][0][RTW89_MEXICO][13] = 127, + [0][0][0][0][RTW89_UKRAINE][13] = 127, + [0][0][0][0][RTW89_CHILE][13] = 127, + [0][0][0][0][RTW89_QATAR][13] = 127, + [0][0][0][0][RTW89_THAILAND][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 76, + [0][1][0][0][RTW89_ETSI][0] = 48, + [0][1][0][0][RTW89_MKK][0] = 58, + [0][1][0][0][RTW89_IC][0] = 76, + [0][1][0][0][RTW89_KCC][0] = 56, + [0][1][0][0][RTW89_ACMA][0] = 48, + [0][1][0][0][RTW89_CN][0] = 42, + [0][1][0][0][RTW89_UK][0] = 48, + [0][1][0][0][RTW89_MEXICO][0] = 76, + [0][1][0][0][RTW89_UKRAINE][0] = 48, + [0][1][0][0][RTW89_CHILE][0] = 76, + [0][1][0][0][RTW89_QATAR][0] = 48, + [0][1][0][0][RTW89_THAILAND][0] = 48, + [0][1][0][0][RTW89_FCC][1] = 76, + [0][1][0][0][RTW89_ETSI][1] = 48, + [0][1][0][0][RTW89_MKK][1] = 58, + [0][1][0][0][RTW89_IC][1] = 76, + [0][1][0][0][RTW89_KCC][1] = 56, + [0][1][0][0][RTW89_ACMA][1] = 48, + [0][1][0][0][RTW89_CN][1] = 42, + [0][1][0][0][RTW89_UK][1] = 48, + [0][1][0][0][RTW89_MEXICO][1] = 76, + [0][1][0][0][RTW89_UKRAINE][1] = 48, + [0][1][0][0][RTW89_CHILE][1] = 54, + [0][1][0][0][RTW89_QATAR][1] = 48, + [0][1][0][0][RTW89_THAILAND][1] = 48, + [0][1][0][0][RTW89_FCC][2] = 76, + [0][1][0][0][RTW89_ETSI][2] = 48, + [0][1][0][0][RTW89_MKK][2] = 58, + [0][1][0][0][RTW89_IC][2] = 76, + [0][1][0][0][RTW89_KCC][2] = 56, + [0][1][0][0][RTW89_ACMA][2] = 48, + [0][1][0][0][RTW89_CN][2] = 42, + [0][1][0][0][RTW89_UK][2] = 48, + [0][1][0][0][RTW89_MEXICO][2] = 76, + [0][1][0][0][RTW89_UKRAINE][2] = 48, + [0][1][0][0][RTW89_CHILE][2] = 54, + [0][1][0][0][RTW89_QATAR][2] = 48, + [0][1][0][0][RTW89_THAILAND][2] = 48, + [0][1][0][0][RTW89_FCC][3] = 76, + [0][1][0][0][RTW89_ETSI][3] = 48, + [0][1][0][0][RTW89_MKK][3] = 58, + [0][1][0][0][RTW89_IC][3] = 76, + [0][1][0][0][RTW89_KCC][3] = 56, + [0][1][0][0][RTW89_ACMA][3] = 48, + [0][1][0][0][RTW89_CN][3] = 42, + [0][1][0][0][RTW89_UK][3] = 48, + [0][1][0][0][RTW89_MEXICO][3] = 76, + [0][1][0][0][RTW89_UKRAINE][3] = 48, + [0][1][0][0][RTW89_CHILE][3] = 54, + [0][1][0][0][RTW89_QATAR][3] = 48, + [0][1][0][0][RTW89_THAILAND][3] = 48, + [0][1][0][0][RTW89_FCC][4] = 76, + [0][1][0][0][RTW89_ETSI][4] = 48, + [0][1][0][0][RTW89_MKK][4] = 58, + [0][1][0][0][RTW89_IC][4] = 76, + [0][1][0][0][RTW89_KCC][4] = 56, + [0][1][0][0][RTW89_ACMA][4] = 48, + [0][1][0][0][RTW89_CN][4] = 42, + [0][1][0][0][RTW89_UK][4] = 48, + [0][1][0][0][RTW89_MEXICO][4] = 76, + [0][1][0][0][RTW89_UKRAINE][4] = 48, + [0][1][0][0][RTW89_CHILE][4] = 54, + [0][1][0][0][RTW89_QATAR][4] = 48, + [0][1][0][0][RTW89_THAILAND][4] = 48, + [0][1][0][0][RTW89_FCC][5] = 76, + [0][1][0][0][RTW89_ETSI][5] = 48, + [0][1][0][0][RTW89_MKK][5] = 58, + [0][1][0][0][RTW89_IC][5] = 76, + [0][1][0][0][RTW89_KCC][5] = 56, + [0][1][0][0][RTW89_ACMA][5] = 48, + [0][1][0][0][RTW89_CN][5] = 42, + [0][1][0][0][RTW89_UK][5] = 48, + [0][1][0][0][RTW89_MEXICO][5] = 76, + [0][1][0][0][RTW89_UKRAINE][5] = 48, + [0][1][0][0][RTW89_CHILE][5] = 76, + [0][1][0][0][RTW89_QATAR][5] = 48, + [0][1][0][0][RTW89_THAILAND][5] = 48, + [0][1][0][0][RTW89_FCC][6] = 76, + [0][1][0][0][RTW89_ETSI][6] = 48, + [0][1][0][0][RTW89_MKK][6] = 58, + [0][1][0][0][RTW89_IC][6] = 76, + [0][1][0][0][RTW89_KCC][6] = 56, + [0][1][0][0][RTW89_ACMA][6] = 48, + [0][1][0][0][RTW89_CN][6] = 42, + [0][1][0][0][RTW89_UK][6] = 48, + [0][1][0][0][RTW89_MEXICO][6] = 76, + [0][1][0][0][RTW89_UKRAINE][6] = 48, + [0][1][0][0][RTW89_CHILE][6] = 76, + [0][1][0][0][RTW89_QATAR][6] = 48, + [0][1][0][0][RTW89_THAILAND][6] = 48, + [0][1][0][0][RTW89_FCC][7] = 76, + [0][1][0][0][RTW89_ETSI][7] = 48, + [0][1][0][0][RTW89_MKK][7] = 58, + [0][1][0][0][RTW89_IC][7] = 76, + [0][1][0][0][RTW89_KCC][7] = 56, + [0][1][0][0][RTW89_ACMA][7] = 48, + [0][1][0][0][RTW89_CN][7] = 42, + [0][1][0][0][RTW89_UK][7] = 48, + [0][1][0][0][RTW89_MEXICO][7] = 76, + [0][1][0][0][RTW89_UKRAINE][7] = 48, + [0][1][0][0][RTW89_CHILE][7] = 76, + [0][1][0][0][RTW89_QATAR][7] = 48, + [0][1][0][0][RTW89_THAILAND][7] = 48, + [0][1][0][0][RTW89_FCC][8] = 76, + [0][1][0][0][RTW89_ETSI][8] = 48, + [0][1][0][0][RTW89_MKK][8] = 58, + [0][1][0][0][RTW89_IC][8] = 76, + [0][1][0][0][RTW89_KCC][8] = 56, + [0][1][0][0][RTW89_ACMA][8] = 48, + [0][1][0][0][RTW89_CN][8] = 42, + [0][1][0][0][RTW89_UK][8] = 48, + [0][1][0][0][RTW89_MEXICO][8] = 76, + [0][1][0][0][RTW89_UKRAINE][8] = 48, + [0][1][0][0][RTW89_CHILE][8] = 76, + [0][1][0][0][RTW89_QATAR][8] = 48, + [0][1][0][0][RTW89_THAILAND][8] = 48, + [0][1][0][0][RTW89_FCC][9] = 70, + [0][1][0][0][RTW89_ETSI][9] = 48, + [0][1][0][0][RTW89_MKK][9] = 58, + [0][1][0][0][RTW89_IC][9] = 70, + [0][1][0][0][RTW89_KCC][9] = 56, + [0][1][0][0][RTW89_ACMA][9] = 48, + [0][1][0][0][RTW89_CN][9] = 42, + [0][1][0][0][RTW89_UK][9] = 48, + [0][1][0][0][RTW89_MEXICO][9] = 70, + [0][1][0][0][RTW89_UKRAINE][9] = 48, + [0][1][0][0][RTW89_CHILE][9] = 70, + [0][1][0][0][RTW89_QATAR][9] = 48, + [0][1][0][0][RTW89_THAILAND][9] = 48, + [0][1][0][0][RTW89_FCC][10] = 72, + [0][1][0][0][RTW89_ETSI][10] = 48, + [0][1][0][0][RTW89_MKK][10] = 58, + [0][1][0][0][RTW89_IC][10] = 72, + [0][1][0][0][RTW89_KCC][10] = 56, + [0][1][0][0][RTW89_ACMA][10] = 48, + [0][1][0][0][RTW89_CN][10] = 42, + [0][1][0][0][RTW89_UK][10] = 48, + [0][1][0][0][RTW89_MEXICO][10] = 72, + [0][1][0][0][RTW89_UKRAINE][10] = 48, + [0][1][0][0][RTW89_CHILE][10] = 72, + [0][1][0][0][RTW89_QATAR][10] = 48, + [0][1][0][0][RTW89_THAILAND][10] = 48, + [0][1][0][0][RTW89_FCC][11] = 44, + [0][1][0][0][RTW89_ETSI][11] = 48, + [0][1][0][0][RTW89_MKK][11] = 58, + [0][1][0][0][RTW89_IC][11] = 44, + [0][1][0][0][RTW89_KCC][11] = 56, + [0][1][0][0][RTW89_ACMA][11] = 48, + [0][1][0][0][RTW89_CN][11] = 42, + [0][1][0][0][RTW89_UK][11] = 48, + [0][1][0][0][RTW89_MEXICO][11] = 44, + [0][1][0][0][RTW89_UKRAINE][11] = 48, + [0][1][0][0][RTW89_CHILE][11] = 44, + [0][1][0][0][RTW89_QATAR][11] = 48, + [0][1][0][0][RTW89_THAILAND][11] = 48, + [0][1][0][0][RTW89_FCC][12] = 18, + [0][1][0][0][RTW89_ETSI][12] = 48, + [0][1][0][0][RTW89_MKK][12] = 58, + [0][1][0][0][RTW89_IC][12] = 18, + [0][1][0][0][RTW89_KCC][12] = 56, + [0][1][0][0][RTW89_ACMA][12] = 48, + [0][1][0][0][RTW89_CN][12] = 42, + [0][1][0][0][RTW89_UK][12] = 48, + [0][1][0][0][RTW89_MEXICO][12] = 18, + [0][1][0][0][RTW89_UKRAINE][12] = 48, + [0][1][0][0][RTW89_CHILE][12] = 18, + [0][1][0][0][RTW89_QATAR][12] = 48, + [0][1][0][0][RTW89_THAILAND][12] = 48, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 60, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_KCC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_CN][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, + [0][1][0][0][RTW89_MEXICO][13] = 127, + [0][1][0][0][RTW89_UKRAINE][13] = 127, + [0][1][0][0][RTW89_CHILE][13] = 127, + [0][1][0][0][RTW89_QATAR][13] = 127, + [0][1][0][0][RTW89_THAILAND][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_KCC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_CN][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, + [1][0][0][0][RTW89_MEXICO][0] = 127, + [1][0][0][0][RTW89_UKRAINE][0] = 127, + [1][0][0][0][RTW89_CHILE][0] = 127, + [1][0][0][0][RTW89_QATAR][0] = 127, + [1][0][0][0][RTW89_THAILAND][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_KCC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_CN][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, + [1][0][0][0][RTW89_MEXICO][1] = 127, + [1][0][0][0][RTW89_UKRAINE][1] = 127, + [1][0][0][0][RTW89_CHILE][1] = 127, + [1][0][0][0][RTW89_QATAR][1] = 127, + [1][0][0][0][RTW89_THAILAND][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 44, + [1][0][0][0][RTW89_ETSI][2] = 60, + [1][0][0][0][RTW89_MKK][2] = 66, + [1][0][0][0][RTW89_IC][2] = 44, + [1][0][0][0][RTW89_KCC][2] = 68, + [1][0][0][0][RTW89_ACMA][2] = 60, + [1][0][0][0][RTW89_CN][2] = 56, + [1][0][0][0][RTW89_UK][2] = 60, + [1][0][0][0][RTW89_MEXICO][2] = 44, + [1][0][0][0][RTW89_UKRAINE][2] = 60, + [1][0][0][0][RTW89_CHILE][2] = 44, + [1][0][0][0][RTW89_QATAR][2] = 60, + [1][0][0][0][RTW89_THAILAND][2] = 60, + [1][0][0][0][RTW89_FCC][3] = 60, + [1][0][0][0][RTW89_ETSI][3] = 60, + [1][0][0][0][RTW89_MKK][3] = 66, + [1][0][0][0][RTW89_IC][3] = 60, + [1][0][0][0][RTW89_KCC][3] = 68, + [1][0][0][0][RTW89_ACMA][3] = 60, + [1][0][0][0][RTW89_CN][3] = 56, + [1][0][0][0][RTW89_UK][3] = 60, + [1][0][0][0][RTW89_MEXICO][3] = 60, + [1][0][0][0][RTW89_UKRAINE][3] = 60, + [1][0][0][0][RTW89_CHILE][3] = 60, + [1][0][0][0][RTW89_QATAR][3] = 60, + [1][0][0][0][RTW89_THAILAND][3] = 60, + [1][0][0][0][RTW89_FCC][4] = 60, + [1][0][0][0][RTW89_ETSI][4] = 60, + [1][0][0][0][RTW89_MKK][4] = 66, + [1][0][0][0][RTW89_IC][4] = 60, + [1][0][0][0][RTW89_KCC][4] = 68, + [1][0][0][0][RTW89_ACMA][4] = 60, + [1][0][0][0][RTW89_CN][4] = 56, + [1][0][0][0][RTW89_UK][4] = 60, + [1][0][0][0][RTW89_MEXICO][4] = 60, + [1][0][0][0][RTW89_UKRAINE][4] = 60, + [1][0][0][0][RTW89_CHILE][4] = 60, + [1][0][0][0][RTW89_QATAR][4] = 60, + [1][0][0][0][RTW89_THAILAND][4] = 60, + [1][0][0][0][RTW89_FCC][5] = 62, + [1][0][0][0][RTW89_ETSI][5] = 60, + [1][0][0][0][RTW89_MKK][5] = 66, + [1][0][0][0][RTW89_IC][5] = 62, + [1][0][0][0][RTW89_KCC][5] = 68, + [1][0][0][0][RTW89_ACMA][5] = 60, + [1][0][0][0][RTW89_CN][5] = 56, + [1][0][0][0][RTW89_UK][5] = 60, + [1][0][0][0][RTW89_MEXICO][5] = 62, + [1][0][0][0][RTW89_UKRAINE][5] = 60, + [1][0][0][0][RTW89_CHILE][5] = 62, + [1][0][0][0][RTW89_QATAR][5] = 60, + [1][0][0][0][RTW89_THAILAND][5] = 60, + [1][0][0][0][RTW89_FCC][6] = 46, + [1][0][0][0][RTW89_ETSI][6] = 60, + [1][0][0][0][RTW89_MKK][6] = 66, + [1][0][0][0][RTW89_IC][6] = 46, + [1][0][0][0][RTW89_KCC][6] = 68, + [1][0][0][0][RTW89_ACMA][6] = 60, + [1][0][0][0][RTW89_CN][6] = 56, + [1][0][0][0][RTW89_UK][6] = 60, + [1][0][0][0][RTW89_MEXICO][6] = 46, + [1][0][0][0][RTW89_UKRAINE][6] = 60, + [1][0][0][0][RTW89_CHILE][6] = 46, + [1][0][0][0][RTW89_QATAR][6] = 60, + [1][0][0][0][RTW89_THAILAND][6] = 60, + [1][0][0][0][RTW89_FCC][7] = 46, + [1][0][0][0][RTW89_ETSI][7] = 60, + [1][0][0][0][RTW89_MKK][7] = 66, + [1][0][0][0][RTW89_IC][7] = 46, + [1][0][0][0][RTW89_KCC][7] = 68, + [1][0][0][0][RTW89_ACMA][7] = 60, + [1][0][0][0][RTW89_CN][7] = 56, + [1][0][0][0][RTW89_UK][7] = 60, + [1][0][0][0][RTW89_MEXICO][7] = 46, + [1][0][0][0][RTW89_UKRAINE][7] = 60, + [1][0][0][0][RTW89_CHILE][7] = 46, + [1][0][0][0][RTW89_QATAR][7] = 60, + [1][0][0][0][RTW89_THAILAND][7] = 60, + [1][0][0][0][RTW89_FCC][8] = 28, + [1][0][0][0][RTW89_ETSI][8] = 60, + [1][0][0][0][RTW89_MKK][8] = 66, + [1][0][0][0][RTW89_IC][8] = 28, + [1][0][0][0][RTW89_KCC][8] = 70, + [1][0][0][0][RTW89_ACMA][8] = 60, + [1][0][0][0][RTW89_CN][8] = 56, + [1][0][0][0][RTW89_UK][8] = 60, + [1][0][0][0][RTW89_MEXICO][8] = 28, + [1][0][0][0][RTW89_UKRAINE][8] = 60, + [1][0][0][0][RTW89_CHILE][8] = 28, + [1][0][0][0][RTW89_QATAR][8] = 60, + [1][0][0][0][RTW89_THAILAND][8] = 60, + [1][0][0][0][RTW89_FCC][9] = 26, + [1][0][0][0][RTW89_ETSI][9] = 60, + [1][0][0][0][RTW89_MKK][9] = 66, + [1][0][0][0][RTW89_IC][9] = 26, + [1][0][0][0][RTW89_KCC][9] = 70, + [1][0][0][0][RTW89_ACMA][9] = 60, + [1][0][0][0][RTW89_CN][9] = 56, + [1][0][0][0][RTW89_UK][9] = 60, + [1][0][0][0][RTW89_MEXICO][9] = 26, + [1][0][0][0][RTW89_UKRAINE][9] = 60, + [1][0][0][0][RTW89_CHILE][9] = 26, + [1][0][0][0][RTW89_QATAR][9] = 60, + [1][0][0][0][RTW89_THAILAND][9] = 60, + [1][0][0][0][RTW89_FCC][10] = 26, + [1][0][0][0][RTW89_ETSI][10] = 60, + [1][0][0][0][RTW89_MKK][10] = 66, + [1][0][0][0][RTW89_IC][10] = 26, + [1][0][0][0][RTW89_KCC][10] = 70, + [1][0][0][0][RTW89_ACMA][10] = 60, + [1][0][0][0][RTW89_CN][10] = 56, + [1][0][0][0][RTW89_UK][10] = 60, + [1][0][0][0][RTW89_MEXICO][10] = 26, + [1][0][0][0][RTW89_UKRAINE][10] = 60, + [1][0][0][0][RTW89_CHILE][10] = 26, + [1][0][0][0][RTW89_QATAR][10] = 60, + [1][0][0][0][RTW89_THAILAND][10] = 60, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_KCC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_CN][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, + [1][0][0][0][RTW89_MEXICO][11] = 127, + [1][0][0][0][RTW89_UKRAINE][11] = 127, + [1][0][0][0][RTW89_CHILE][11] = 127, + [1][0][0][0][RTW89_QATAR][11] = 127, + [1][0][0][0][RTW89_THAILAND][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_KCC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_CN][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, + [1][0][0][0][RTW89_MEXICO][12] = 127, + [1][0][0][0][RTW89_UKRAINE][12] = 127, + [1][0][0][0][RTW89_CHILE][12] = 127, + [1][0][0][0][RTW89_QATAR][12] = 127, + [1][0][0][0][RTW89_THAILAND][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_KCC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_CN][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, + [1][0][0][0][RTW89_MEXICO][13] = 127, + [1][0][0][0][RTW89_UKRAINE][13] = 127, + [1][0][0][0][RTW89_CHILE][13] = 127, + [1][0][0][0][RTW89_QATAR][13] = 127, + [1][0][0][0][RTW89_THAILAND][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_KCC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_CN][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, + [1][1][0][0][RTW89_MEXICO][0] = 127, + [1][1][0][0][RTW89_UKRAINE][0] = 127, + [1][1][0][0][RTW89_CHILE][0] = 127, + [1][1][0][0][RTW89_QATAR][0] = 127, + [1][1][0][0][RTW89_THAILAND][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_KCC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_CN][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, + [1][1][0][0][RTW89_MEXICO][1] = 127, + [1][1][0][0][RTW89_UKRAINE][1] = 127, + [1][1][0][0][RTW89_CHILE][1] = 127, + [1][1][0][0][RTW89_QATAR][1] = 127, + [1][1][0][0][RTW89_THAILAND][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 46, + [1][1][0][0][RTW89_ETSI][2] = 48, + [1][1][0][0][RTW89_MKK][2] = 58, + [1][1][0][0][RTW89_IC][2] = 46, + [1][1][0][0][RTW89_KCC][2] = 56, + [1][1][0][0][RTW89_ACMA][2] = 48, + [1][1][0][0][RTW89_CN][2] = 44, + [1][1][0][0][RTW89_UK][2] = 48, + [1][1][0][0][RTW89_MEXICO][2] = 46, + [1][1][0][0][RTW89_UKRAINE][2] = 48, + [1][1][0][0][RTW89_CHILE][2] = 46, + [1][1][0][0][RTW89_QATAR][2] = 48, + [1][1][0][0][RTW89_THAILAND][2] = 48, + [1][1][0][0][RTW89_FCC][3] = 46, + [1][1][0][0][RTW89_ETSI][3] = 48, + [1][1][0][0][RTW89_MKK][3] = 58, + [1][1][0][0][RTW89_IC][3] = 46, + [1][1][0][0][RTW89_KCC][3] = 56, + [1][1][0][0][RTW89_ACMA][3] = 48, + [1][1][0][0][RTW89_CN][3] = 44, + [1][1][0][0][RTW89_UK][3] = 48, + [1][1][0][0][RTW89_MEXICO][3] = 46, + [1][1][0][0][RTW89_UKRAINE][3] = 48, + [1][1][0][0][RTW89_CHILE][3] = 46, + [1][1][0][0][RTW89_QATAR][3] = 48, + [1][1][0][0][RTW89_THAILAND][3] = 48, + [1][1][0][0][RTW89_FCC][4] = 46, + [1][1][0][0][RTW89_ETSI][4] = 48, + [1][1][0][0][RTW89_MKK][4] = 58, + [1][1][0][0][RTW89_IC][4] = 46, + [1][1][0][0][RTW89_KCC][4] = 56, + [1][1][0][0][RTW89_ACMA][4] = 48, + [1][1][0][0][RTW89_CN][4] = 44, + [1][1][0][0][RTW89_UK][4] = 48, + [1][1][0][0][RTW89_MEXICO][4] = 46, + [1][1][0][0][RTW89_UKRAINE][4] = 48, + [1][1][0][0][RTW89_CHILE][4] = 46, + [1][1][0][0][RTW89_QATAR][4] = 48, + [1][1][0][0][RTW89_THAILAND][4] = 48, + [1][1][0][0][RTW89_FCC][5] = 48, + [1][1][0][0][RTW89_ETSI][5] = 48, + [1][1][0][0][RTW89_MKK][5] = 58, + [1][1][0][0][RTW89_IC][5] = 48, + [1][1][0][0][RTW89_KCC][5] = 56, + [1][1][0][0][RTW89_ACMA][5] = 48, + [1][1][0][0][RTW89_CN][5] = 44, + [1][1][0][0][RTW89_UK][5] = 48, + [1][1][0][0][RTW89_MEXICO][5] = 48, + [1][1][0][0][RTW89_UKRAINE][5] = 48, + [1][1][0][0][RTW89_CHILE][5] = 48, + [1][1][0][0][RTW89_QATAR][5] = 48, + [1][1][0][0][RTW89_THAILAND][5] = 48, + [1][1][0][0][RTW89_FCC][6] = 40, + [1][1][0][0][RTW89_ETSI][6] = 48, + [1][1][0][0][RTW89_MKK][6] = 58, + [1][1][0][0][RTW89_IC][6] = 40, + [1][1][0][0][RTW89_KCC][6] = 56, + [1][1][0][0][RTW89_ACMA][6] = 48, + [1][1][0][0][RTW89_CN][6] = 44, + [1][1][0][0][RTW89_UK][6] = 48, + [1][1][0][0][RTW89_MEXICO][6] = 40, + [1][1][0][0][RTW89_UKRAINE][6] = 48, + [1][1][0][0][RTW89_CHILE][6] = 40, + [1][1][0][0][RTW89_QATAR][6] = 48, + [1][1][0][0][RTW89_THAILAND][6] = 48, + [1][1][0][0][RTW89_FCC][7] = 40, + [1][1][0][0][RTW89_ETSI][7] = 48, + [1][1][0][0][RTW89_MKK][7] = 58, + [1][1][0][0][RTW89_IC][7] = 40, + [1][1][0][0][RTW89_KCC][7] = 56, + [1][1][0][0][RTW89_ACMA][7] = 48, + [1][1][0][0][RTW89_CN][7] = 44, + [1][1][0][0][RTW89_UK][7] = 48, + [1][1][0][0][RTW89_MEXICO][7] = 40, + [1][1][0][0][RTW89_UKRAINE][7] = 48, + [1][1][0][0][RTW89_CHILE][7] = 40, + [1][1][0][0][RTW89_QATAR][7] = 48, + [1][1][0][0][RTW89_THAILAND][7] = 48, + [1][1][0][0][RTW89_FCC][8] = 14, + [1][1][0][0][RTW89_ETSI][8] = 48, + [1][1][0][0][RTW89_MKK][8] = 58, + [1][1][0][0][RTW89_IC][8] = 14, + [1][1][0][0][RTW89_KCC][8] = 58, + [1][1][0][0][RTW89_ACMA][8] = 48, + [1][1][0][0][RTW89_CN][8] = 44, + [1][1][0][0][RTW89_UK][8] = 48, + [1][1][0][0][RTW89_MEXICO][8] = 14, + [1][1][0][0][RTW89_UKRAINE][8] = 48, + [1][1][0][0][RTW89_CHILE][8] = 14, + [1][1][0][0][RTW89_QATAR][8] = 48, + [1][1][0][0][RTW89_THAILAND][8] = 48, + [1][1][0][0][RTW89_FCC][9] = 14, + [1][1][0][0][RTW89_ETSI][9] = 48, + [1][1][0][0][RTW89_MKK][9] = 58, + [1][1][0][0][RTW89_IC][9] = 14, + [1][1][0][0][RTW89_KCC][9] = 58, + [1][1][0][0][RTW89_ACMA][9] = 48, + [1][1][0][0][RTW89_CN][9] = 44, + [1][1][0][0][RTW89_UK][9] = 48, + [1][1][0][0][RTW89_MEXICO][9] = 14, + [1][1][0][0][RTW89_UKRAINE][9] = 48, + [1][1][0][0][RTW89_CHILE][9] = 14, + [1][1][0][0][RTW89_QATAR][9] = 48, + [1][1][0][0][RTW89_THAILAND][9] = 48, + [1][1][0][0][RTW89_FCC][10] = 12, + [1][1][0][0][RTW89_ETSI][10] = 48, + [1][1][0][0][RTW89_MKK][10] = 56, + [1][1][0][0][RTW89_IC][10] = 12, + [1][1][0][0][RTW89_KCC][10] = 58, + [1][1][0][0][RTW89_ACMA][10] = 48, + [1][1][0][0][RTW89_CN][10] = 44, + [1][1][0][0][RTW89_UK][10] = 48, + [1][1][0][0][RTW89_MEXICO][10] = 12, + [1][1][0][0][RTW89_UKRAINE][10] = 48, + [1][1][0][0][RTW89_CHILE][10] = 12, + [1][1][0][0][RTW89_QATAR][10] = 48, + [1][1][0][0][RTW89_THAILAND][10] = 48, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_KCC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_CN][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, + [1][1][0][0][RTW89_MEXICO][11] = 127, + [1][1][0][0][RTW89_UKRAINE][11] = 127, + [1][1][0][0][RTW89_CHILE][11] = 127, + [1][1][0][0][RTW89_QATAR][11] = 127, + [1][1][0][0][RTW89_THAILAND][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_KCC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_CN][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, + [1][1][0][0][RTW89_MEXICO][12] = 127, + [1][1][0][0][RTW89_UKRAINE][12] = 127, + [1][1][0][0][RTW89_CHILE][12] = 127, + [1][1][0][0][RTW89_QATAR][12] = 127, + [1][1][0][0][RTW89_THAILAND][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_KCC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_CN][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, + [1][1][0][0][RTW89_MEXICO][13] = 127, + [1][1][0][0][RTW89_UKRAINE][13] = 127, + [1][1][0][0][RTW89_CHILE][13] = 127, + [1][1][0][0][RTW89_QATAR][13] = 127, + [1][1][0][0][RTW89_THAILAND][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 66, + [0][0][1][0][RTW89_ETSI][0] = 60, + [0][0][1][0][RTW89_MKK][0] = 76, + [0][0][1][0][RTW89_IC][0] = 66, + [0][0][1][0][RTW89_KCC][0] = 68, + [0][0][1][0][RTW89_ACMA][0] = 60, + [0][0][1][0][RTW89_CN][0] = 58, + [0][0][1][0][RTW89_UK][0] = 60, + [0][0][1][0][RTW89_MEXICO][0] = 66, + [0][0][1][0][RTW89_UKRAINE][0] = 60, + [0][0][1][0][RTW89_CHILE][0] = 66, + [0][0][1][0][RTW89_QATAR][0] = 60, + [0][0][1][0][RTW89_THAILAND][0] = 60, + [0][0][1][0][RTW89_FCC][1] = 68, + [0][0][1][0][RTW89_ETSI][1] = 60, + [0][0][1][0][RTW89_MKK][1] = 78, + [0][0][1][0][RTW89_IC][1] = 68, + [0][0][1][0][RTW89_KCC][1] = 68, + [0][0][1][0][RTW89_ACMA][1] = 60, + [0][0][1][0][RTW89_CN][1] = 58, + [0][0][1][0][RTW89_UK][1] = 60, + [0][0][1][0][RTW89_MEXICO][1] = 68, + [0][0][1][0][RTW89_UKRAINE][1] = 60, + [0][0][1][0][RTW89_CHILE][1] = 68, + [0][0][1][0][RTW89_QATAR][1] = 60, + [0][0][1][0][RTW89_THAILAND][1] = 60, + [0][0][1][0][RTW89_FCC][2] = 72, + [0][0][1][0][RTW89_ETSI][2] = 60, + [0][0][1][0][RTW89_MKK][2] = 78, + [0][0][1][0][RTW89_IC][2] = 72, + [0][0][1][0][RTW89_KCC][2] = 68, + [0][0][1][0][RTW89_ACMA][2] = 60, + [0][0][1][0][RTW89_CN][2] = 58, + [0][0][1][0][RTW89_UK][2] = 60, + [0][0][1][0][RTW89_MEXICO][2] = 72, + [0][0][1][0][RTW89_UKRAINE][2] = 60, + [0][0][1][0][RTW89_CHILE][2] = 62, + [0][0][1][0][RTW89_QATAR][2] = 60, + [0][0][1][0][RTW89_THAILAND][2] = 60, + [0][0][1][0][RTW89_FCC][3] = 76, + [0][0][1][0][RTW89_ETSI][3] = 60, + [0][0][1][0][RTW89_MKK][3] = 78, + [0][0][1][0][RTW89_IC][3] = 76, + [0][0][1][0][RTW89_KCC][3] = 68, + [0][0][1][0][RTW89_ACMA][3] = 60, + [0][0][1][0][RTW89_CN][3] = 58, + [0][0][1][0][RTW89_UK][3] = 60, + [0][0][1][0][RTW89_MEXICO][3] = 76, + [0][0][1][0][RTW89_UKRAINE][3] = 60, + [0][0][1][0][RTW89_CHILE][3] = 62, + [0][0][1][0][RTW89_QATAR][3] = 60, + [0][0][1][0][RTW89_THAILAND][3] = 60, + [0][0][1][0][RTW89_FCC][4] = 80, + [0][0][1][0][RTW89_ETSI][4] = 60, + [0][0][1][0][RTW89_MKK][4] = 78, + [0][0][1][0][RTW89_IC][4] = 80, + [0][0][1][0][RTW89_KCC][4] = 76, + [0][0][1][0][RTW89_ACMA][4] = 60, + [0][0][1][0][RTW89_CN][4] = 58, + [0][0][1][0][RTW89_UK][4] = 60, + [0][0][1][0][RTW89_MEXICO][4] = 80, + [0][0][1][0][RTW89_UKRAINE][4] = 60, + [0][0][1][0][RTW89_CHILE][4] = 62, + [0][0][1][0][RTW89_QATAR][4] = 60, + [0][0][1][0][RTW89_THAILAND][4] = 60, + [0][0][1][0][RTW89_FCC][5] = 80, + [0][0][1][0][RTW89_ETSI][5] = 60, + [0][0][1][0][RTW89_MKK][5] = 78, + [0][0][1][0][RTW89_IC][5] = 80, + [0][0][1][0][RTW89_KCC][5] = 76, + [0][0][1][0][RTW89_ACMA][5] = 60, + [0][0][1][0][RTW89_CN][5] = 58, + [0][0][1][0][RTW89_UK][5] = 60, + [0][0][1][0][RTW89_MEXICO][5] = 80, + [0][0][1][0][RTW89_UKRAINE][5] = 60, + [0][0][1][0][RTW89_CHILE][5] = 80, + [0][0][1][0][RTW89_QATAR][5] = 60, + [0][0][1][0][RTW89_THAILAND][5] = 60, + [0][0][1][0][RTW89_FCC][6] = 80, + [0][0][1][0][RTW89_ETSI][6] = 60, + [0][0][1][0][RTW89_MKK][6] = 76, + [0][0][1][0][RTW89_IC][6] = 80, + [0][0][1][0][RTW89_KCC][6] = 76, + [0][0][1][0][RTW89_ACMA][6] = 60, + [0][0][1][0][RTW89_CN][6] = 58, + [0][0][1][0][RTW89_UK][6] = 60, + [0][0][1][0][RTW89_MEXICO][6] = 80, + [0][0][1][0][RTW89_UKRAINE][6] = 60, + [0][0][1][0][RTW89_CHILE][6] = 70, + [0][0][1][0][RTW89_QATAR][6] = 60, + [0][0][1][0][RTW89_THAILAND][6] = 60, + [0][0][1][0][RTW89_FCC][7] = 80, + [0][0][1][0][RTW89_ETSI][7] = 60, + [0][0][1][0][RTW89_MKK][7] = 78, + [0][0][1][0][RTW89_IC][7] = 80, + [0][0][1][0][RTW89_KCC][7] = 76, + [0][0][1][0][RTW89_ACMA][7] = 60, + [0][0][1][0][RTW89_CN][7] = 58, + [0][0][1][0][RTW89_UK][7] = 60, + [0][0][1][0][RTW89_MEXICO][7] = 80, + [0][0][1][0][RTW89_UKRAINE][7] = 60, + [0][0][1][0][RTW89_CHILE][7] = 70, + [0][0][1][0][RTW89_QATAR][7] = 60, + [0][0][1][0][RTW89_THAILAND][7] = 60, + [0][0][1][0][RTW89_FCC][8] = 80, + [0][0][1][0][RTW89_ETSI][8] = 60, + [0][0][1][0][RTW89_MKK][8] = 78, + [0][0][1][0][RTW89_IC][8] = 80, + [0][0][1][0][RTW89_KCC][8] = 76, + [0][0][1][0][RTW89_ACMA][8] = 60, + [0][0][1][0][RTW89_CN][8] = 58, + [0][0][1][0][RTW89_UK][8] = 60, + [0][0][1][0][RTW89_MEXICO][8] = 80, + [0][0][1][0][RTW89_UKRAINE][8] = 60, + [0][0][1][0][RTW89_CHILE][8] = 70, + [0][0][1][0][RTW89_QATAR][8] = 60, + [0][0][1][0][RTW89_THAILAND][8] = 60, + [0][0][1][0][RTW89_FCC][9] = 76, + [0][0][1][0][RTW89_ETSI][9] = 60, + [0][0][1][0][RTW89_MKK][9] = 78, + [0][0][1][0][RTW89_IC][9] = 76, + [0][0][1][0][RTW89_KCC][9] = 70, + [0][0][1][0][RTW89_ACMA][9] = 60, + [0][0][1][0][RTW89_CN][9] = 58, + [0][0][1][0][RTW89_UK][9] = 60, + [0][0][1][0][RTW89_MEXICO][9] = 76, + [0][0][1][0][RTW89_UKRAINE][9] = 60, + [0][0][1][0][RTW89_CHILE][9] = 76, + [0][0][1][0][RTW89_QATAR][9] = 60, + [0][0][1][0][RTW89_THAILAND][9] = 60, + [0][0][1][0][RTW89_FCC][10] = 66, + [0][0][1][0][RTW89_ETSI][10] = 60, + [0][0][1][0][RTW89_MKK][10] = 78, + [0][0][1][0][RTW89_IC][10] = 66, + [0][0][1][0][RTW89_KCC][10] = 70, + [0][0][1][0][RTW89_ACMA][10] = 60, + [0][0][1][0][RTW89_CN][10] = 58, + [0][0][1][0][RTW89_UK][10] = 60, + [0][0][1][0][RTW89_MEXICO][10] = 66, + [0][0][1][0][RTW89_UKRAINE][10] = 60, + [0][0][1][0][RTW89_CHILE][10] = 66, + [0][0][1][0][RTW89_QATAR][10] = 60, + [0][0][1][0][RTW89_THAILAND][10] = 60, + [0][0][1][0][RTW89_FCC][11] = 62, + [0][0][1][0][RTW89_ETSI][11] = 60, + [0][0][1][0][RTW89_MKK][11] = 78, + [0][0][1][0][RTW89_IC][11] = 62, + [0][0][1][0][RTW89_KCC][11] = 70, + [0][0][1][0][RTW89_ACMA][11] = 60, + [0][0][1][0][RTW89_CN][11] = 58, + [0][0][1][0][RTW89_UK][11] = 60, + [0][0][1][0][RTW89_MEXICO][11] = 62, + [0][0][1][0][RTW89_UKRAINE][11] = 60, + [0][0][1][0][RTW89_CHILE][11] = 62, + [0][0][1][0][RTW89_QATAR][11] = 60, + [0][0][1][0][RTW89_THAILAND][11] = 60, + [0][0][1][0][RTW89_FCC][12] = 60, + [0][0][1][0][RTW89_ETSI][12] = 60, + [0][0][1][0][RTW89_MKK][12] = 78, + [0][0][1][0][RTW89_IC][12] = 60, + [0][0][1][0][RTW89_KCC][12] = 70, + [0][0][1][0][RTW89_ACMA][12] = 60, + [0][0][1][0][RTW89_CN][12] = 40, + [0][0][1][0][RTW89_UK][12] = 60, + [0][0][1][0][RTW89_MEXICO][12] = 60, + [0][0][1][0][RTW89_UKRAINE][12] = 60, + [0][0][1][0][RTW89_CHILE][12] = 60, + [0][0][1][0][RTW89_QATAR][12] = 60, + [0][0][1][0][RTW89_THAILAND][12] = 60, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_KCC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_CN][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, + [0][0][1][0][RTW89_MEXICO][13] = 127, + [0][0][1][0][RTW89_UKRAINE][13] = 127, + [0][0][1][0][RTW89_CHILE][13] = 127, + [0][0][1][0][RTW89_QATAR][13] = 127, + [0][0][1][0][RTW89_THAILAND][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 66, + [0][1][1][0][RTW89_ETSI][0] = 48, + [0][1][1][0][RTW89_MKK][0] = 66, + [0][1][1][0][RTW89_IC][0] = 66, + [0][1][1][0][RTW89_KCC][0] = 64, + [0][1][1][0][RTW89_ACMA][0] = 48, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_UK][0] = 48, + [0][1][1][0][RTW89_MEXICO][0] = 66, + [0][1][1][0][RTW89_UKRAINE][0] = 48, + [0][1][1][0][RTW89_CHILE][0] = 66, + [0][1][1][0][RTW89_QATAR][0] = 48, + [0][1][1][0][RTW89_THAILAND][0] = 48, + [0][1][1][0][RTW89_FCC][1] = 68, + [0][1][1][0][RTW89_ETSI][1] = 48, + [0][1][1][0][RTW89_MKK][1] = 66, + [0][1][1][0][RTW89_IC][1] = 68, + [0][1][1][0][RTW89_KCC][1] = 64, + [0][1][1][0][RTW89_ACMA][1] = 48, + [0][1][1][0][RTW89_CN][1] = 46, + [0][1][1][0][RTW89_UK][1] = 48, + [0][1][1][0][RTW89_MEXICO][1] = 68, + [0][1][1][0][RTW89_UKRAINE][1] = 48, + [0][1][1][0][RTW89_CHILE][1] = 68, + [0][1][1][0][RTW89_QATAR][1] = 48, + [0][1][1][0][RTW89_THAILAND][1] = 48, + [0][1][1][0][RTW89_FCC][2] = 72, + [0][1][1][0][RTW89_ETSI][2] = 48, + [0][1][1][0][RTW89_MKK][2] = 66, + [0][1][1][0][RTW89_IC][2] = 72, + [0][1][1][0][RTW89_KCC][2] = 64, + [0][1][1][0][RTW89_ACMA][2] = 48, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_UK][2] = 48, + [0][1][1][0][RTW89_MEXICO][2] = 72, + [0][1][1][0][RTW89_UKRAINE][2] = 48, + [0][1][1][0][RTW89_CHILE][2] = 54, + [0][1][1][0][RTW89_QATAR][2] = 48, + [0][1][1][0][RTW89_THAILAND][2] = 48, + [0][1][1][0][RTW89_FCC][3] = 76, + [0][1][1][0][RTW89_ETSI][3] = 48, + [0][1][1][0][RTW89_MKK][3] = 66, + [0][1][1][0][RTW89_IC][3] = 76, + [0][1][1][0][RTW89_KCC][3] = 64, + [0][1][1][0][RTW89_ACMA][3] = 48, + [0][1][1][0][RTW89_CN][3] = 46, + [0][1][1][0][RTW89_UK][3] = 48, + [0][1][1][0][RTW89_MEXICO][3] = 76, + [0][1][1][0][RTW89_UKRAINE][3] = 48, + [0][1][1][0][RTW89_CHILE][3] = 54, + [0][1][1][0][RTW89_QATAR][3] = 48, + [0][1][1][0][RTW89_THAILAND][3] = 48, + [0][1][1][0][RTW89_FCC][4] = 80, + [0][1][1][0][RTW89_ETSI][4] = 48, + [0][1][1][0][RTW89_MKK][4] = 66, + [0][1][1][0][RTW89_IC][4] = 80, + [0][1][1][0][RTW89_KCC][4] = 66, + [0][1][1][0][RTW89_ACMA][4] = 48, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_UK][4] = 48, + [0][1][1][0][RTW89_MEXICO][4] = 80, + [0][1][1][0][RTW89_UKRAINE][4] = 48, + [0][1][1][0][RTW89_CHILE][4] = 54, + [0][1][1][0][RTW89_QATAR][4] = 48, + [0][1][1][0][RTW89_THAILAND][4] = 48, + [0][1][1][0][RTW89_FCC][5] = 80, + [0][1][1][0][RTW89_ETSI][5] = 48, + [0][1][1][0][RTW89_MKK][5] = 66, + [0][1][1][0][RTW89_IC][5] = 80, + [0][1][1][0][RTW89_KCC][5] = 66, + [0][1][1][0][RTW89_ACMA][5] = 48, + [0][1][1][0][RTW89_CN][5] = 46, + [0][1][1][0][RTW89_UK][5] = 48, + [0][1][1][0][RTW89_MEXICO][5] = 80, + [0][1][1][0][RTW89_UKRAINE][5] = 48, + [0][1][1][0][RTW89_CHILE][5] = 80, + [0][1][1][0][RTW89_QATAR][5] = 48, + [0][1][1][0][RTW89_THAILAND][5] = 48, + [0][1][1][0][RTW89_FCC][6] = 80, + [0][1][1][0][RTW89_ETSI][6] = 48, + [0][1][1][0][RTW89_MKK][6] = 66, + [0][1][1][0][RTW89_IC][6] = 80, + [0][1][1][0][RTW89_KCC][6] = 66, + [0][1][1][0][RTW89_ACMA][6] = 48, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_UK][6] = 48, + [0][1][1][0][RTW89_MEXICO][6] = 80, + [0][1][1][0][RTW89_UKRAINE][6] = 48, + [0][1][1][0][RTW89_CHILE][6] = 56, + [0][1][1][0][RTW89_QATAR][6] = 48, + [0][1][1][0][RTW89_THAILAND][6] = 48, + [0][1][1][0][RTW89_FCC][7] = 78, + [0][1][1][0][RTW89_ETSI][7] = 48, + [0][1][1][0][RTW89_MKK][7] = 66, + [0][1][1][0][RTW89_IC][7] = 78, + [0][1][1][0][RTW89_KCC][7] = 66, + [0][1][1][0][RTW89_ACMA][7] = 48, + [0][1][1][0][RTW89_CN][7] = 46, + [0][1][1][0][RTW89_UK][7] = 48, + [0][1][1][0][RTW89_MEXICO][7] = 78, + [0][1][1][0][RTW89_UKRAINE][7] = 48, + [0][1][1][0][RTW89_CHILE][7] = 56, + [0][1][1][0][RTW89_QATAR][7] = 48, + [0][1][1][0][RTW89_THAILAND][7] = 48, + [0][1][1][0][RTW89_FCC][8] = 74, + [0][1][1][0][RTW89_ETSI][8] = 48, + [0][1][1][0][RTW89_MKK][8] = 66, + [0][1][1][0][RTW89_IC][8] = 74, + [0][1][1][0][RTW89_KCC][8] = 66, + [0][1][1][0][RTW89_ACMA][8] = 48, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_UK][8] = 48, + [0][1][1][0][RTW89_MEXICO][8] = 74, + [0][1][1][0][RTW89_UKRAINE][8] = 48, + [0][1][1][0][RTW89_CHILE][8] = 56, + [0][1][1][0][RTW89_QATAR][8] = 48, + [0][1][1][0][RTW89_THAILAND][8] = 48, + [0][1][1][0][RTW89_FCC][9] = 70, + [0][1][1][0][RTW89_ETSI][9] = 48, + [0][1][1][0][RTW89_MKK][9] = 66, + [0][1][1][0][RTW89_IC][9] = 70, + [0][1][1][0][RTW89_KCC][9] = 64, + [0][1][1][0][RTW89_ACMA][9] = 48, + [0][1][1][0][RTW89_CN][9] = 46, + [0][1][1][0][RTW89_UK][9] = 48, + [0][1][1][0][RTW89_MEXICO][9] = 70, + [0][1][1][0][RTW89_UKRAINE][9] = 48, + [0][1][1][0][RTW89_CHILE][9] = 70, + [0][1][1][0][RTW89_QATAR][9] = 48, + [0][1][1][0][RTW89_THAILAND][9] = 48, + [0][1][1][0][RTW89_FCC][10] = 62, + [0][1][1][0][RTW89_ETSI][10] = 48, + [0][1][1][0][RTW89_MKK][10] = 66, + [0][1][1][0][RTW89_IC][10] = 62, + [0][1][1][0][RTW89_KCC][10] = 64, + [0][1][1][0][RTW89_ACMA][10] = 48, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_UK][10] = 48, + [0][1][1][0][RTW89_MEXICO][10] = 62, + [0][1][1][0][RTW89_UKRAINE][10] = 48, + [0][1][1][0][RTW89_CHILE][10] = 62, + [0][1][1][0][RTW89_QATAR][10] = 48, + [0][1][1][0][RTW89_THAILAND][10] = 48, + [0][1][1][0][RTW89_FCC][11] = 60, + [0][1][1][0][RTW89_ETSI][11] = 48, + [0][1][1][0][RTW89_MKK][11] = 66, + [0][1][1][0][RTW89_IC][11] = 60, + [0][1][1][0][RTW89_KCC][11] = 64, + [0][1][1][0][RTW89_ACMA][11] = 48, + [0][1][1][0][RTW89_CN][11] = 46, + [0][1][1][0][RTW89_UK][11] = 48, + [0][1][1][0][RTW89_MEXICO][11] = 60, + [0][1][1][0][RTW89_UKRAINE][11] = 48, + [0][1][1][0][RTW89_CHILE][11] = 60, + [0][1][1][0][RTW89_QATAR][11] = 48, + [0][1][1][0][RTW89_THAILAND][11] = 48, + [0][1][1][0][RTW89_FCC][12] = 36, + [0][1][1][0][RTW89_ETSI][12] = 48, + [0][1][1][0][RTW89_MKK][12] = 66, + [0][1][1][0][RTW89_IC][12] = 36, + [0][1][1][0][RTW89_KCC][12] = 64, + [0][1][1][0][RTW89_ACMA][12] = 48, + [0][1][1][0][RTW89_CN][12] = 40, + [0][1][1][0][RTW89_UK][12] = 48, + [0][1][1][0][RTW89_MEXICO][12] = 36, + [0][1][1][0][RTW89_UKRAINE][12] = 48, + [0][1][1][0][RTW89_CHILE][12] = 36, + [0][1][1][0][RTW89_QATAR][12] = 48, + [0][1][1][0][RTW89_THAILAND][12] = 48, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_KCC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_CN][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, + [0][1][1][0][RTW89_MEXICO][13] = 127, + [0][1][1][0][RTW89_UKRAINE][13] = 127, + [0][1][1][0][RTW89_CHILE][13] = 127, + [0][1][1][0][RTW89_QATAR][13] = 127, + [0][1][1][0][RTW89_THAILAND][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 66, + [0][0][2][0][RTW89_ETSI][0] = 60, + [0][0][2][0][RTW89_MKK][0] = 78, + [0][0][2][0][RTW89_IC][0] = 66, + [0][0][2][0][RTW89_KCC][0] = 70, + [0][0][2][0][RTW89_ACMA][0] = 60, + [0][0][2][0][RTW89_CN][0] = 58, + [0][0][2][0][RTW89_UK][0] = 60, + [0][0][2][0][RTW89_MEXICO][0] = 66, + [0][0][2][0][RTW89_UKRAINE][0] = 60, + [0][0][2][0][RTW89_CHILE][0] = 66, + [0][0][2][0][RTW89_QATAR][0] = 60, + [0][0][2][0][RTW89_THAILAND][0] = 60, + [0][0][2][0][RTW89_FCC][1] = 70, + [0][0][2][0][RTW89_ETSI][1] = 60, + [0][0][2][0][RTW89_MKK][1] = 78, + [0][0][2][0][RTW89_IC][1] = 70, + [0][0][2][0][RTW89_KCC][1] = 70, + [0][0][2][0][RTW89_ACMA][1] = 60, + [0][0][2][0][RTW89_CN][1] = 58, + [0][0][2][0][RTW89_UK][1] = 60, + [0][0][2][0][RTW89_MEXICO][1] = 70, + [0][0][2][0][RTW89_UKRAINE][1] = 60, + [0][0][2][0][RTW89_CHILE][1] = 70, + [0][0][2][0][RTW89_QATAR][1] = 60, + [0][0][2][0][RTW89_THAILAND][1] = 60, + [0][0][2][0][RTW89_FCC][2] = 74, + [0][0][2][0][RTW89_ETSI][2] = 60, + [0][0][2][0][RTW89_MKK][2] = 78, + [0][0][2][0][RTW89_IC][2] = 74, + [0][0][2][0][RTW89_KCC][2] = 70, + [0][0][2][0][RTW89_ACMA][2] = 60, + [0][0][2][0][RTW89_CN][2] = 58, + [0][0][2][0][RTW89_UK][2] = 60, + [0][0][2][0][RTW89_MEXICO][2] = 74, + [0][0][2][0][RTW89_UKRAINE][2] = 60, + [0][0][2][0][RTW89_CHILE][2] = 64, + [0][0][2][0][RTW89_QATAR][2] = 60, + [0][0][2][0][RTW89_THAILAND][2] = 60, + [0][0][2][0][RTW89_FCC][3] = 78, + [0][0][2][0][RTW89_ETSI][3] = 60, + [0][0][2][0][RTW89_MKK][3] = 78, + [0][0][2][0][RTW89_IC][3] = 78, + [0][0][2][0][RTW89_KCC][3] = 70, + [0][0][2][0][RTW89_ACMA][3] = 60, + [0][0][2][0][RTW89_CN][3] = 58, + [0][0][2][0][RTW89_UK][3] = 60, + [0][0][2][0][RTW89_MEXICO][3] = 78, + [0][0][2][0][RTW89_UKRAINE][3] = 60, + [0][0][2][0][RTW89_CHILE][3] = 64, + [0][0][2][0][RTW89_QATAR][3] = 60, + [0][0][2][0][RTW89_THAILAND][3] = 60, + [0][0][2][0][RTW89_FCC][4] = 80, + [0][0][2][0][RTW89_ETSI][4] = 60, + [0][0][2][0][RTW89_MKK][4] = 78, + [0][0][2][0][RTW89_IC][4] = 80, + [0][0][2][0][RTW89_KCC][4] = 78, + [0][0][2][0][RTW89_ACMA][4] = 60, + [0][0][2][0][RTW89_CN][4] = 58, + [0][0][2][0][RTW89_UK][4] = 60, + [0][0][2][0][RTW89_MEXICO][4] = 80, + [0][0][2][0][RTW89_UKRAINE][4] = 60, + [0][0][2][0][RTW89_CHILE][4] = 64, + [0][0][2][0][RTW89_QATAR][4] = 60, + [0][0][2][0][RTW89_THAILAND][4] = 60, + [0][0][2][0][RTW89_FCC][5] = 80, + [0][0][2][0][RTW89_ETSI][5] = 60, + [0][0][2][0][RTW89_MKK][5] = 78, + [0][0][2][0][RTW89_IC][5] = 80, + [0][0][2][0][RTW89_KCC][5] = 78, + [0][0][2][0][RTW89_ACMA][5] = 60, + [0][0][2][0][RTW89_CN][5] = 58, + [0][0][2][0][RTW89_UK][5] = 60, + [0][0][2][0][RTW89_MEXICO][5] = 80, + [0][0][2][0][RTW89_UKRAINE][5] = 60, + [0][0][2][0][RTW89_CHILE][5] = 80, + [0][0][2][0][RTW89_QATAR][5] = 60, + [0][0][2][0][RTW89_THAILAND][5] = 60, + [0][0][2][0][RTW89_FCC][6] = 80, + [0][0][2][0][RTW89_ETSI][6] = 60, + [0][0][2][0][RTW89_MKK][6] = 78, + [0][0][2][0][RTW89_IC][6] = 80, + [0][0][2][0][RTW89_KCC][6] = 78, + [0][0][2][0][RTW89_ACMA][6] = 60, + [0][0][2][0][RTW89_CN][6] = 58, + [0][0][2][0][RTW89_UK][6] = 60, + [0][0][2][0][RTW89_MEXICO][6] = 80, + [0][0][2][0][RTW89_UKRAINE][6] = 60, + [0][0][2][0][RTW89_CHILE][6] = 68, + [0][0][2][0][RTW89_QATAR][6] = 60, + [0][0][2][0][RTW89_THAILAND][6] = 60, + [0][0][2][0][RTW89_FCC][7] = 80, + [0][0][2][0][RTW89_ETSI][7] = 60, + [0][0][2][0][RTW89_MKK][7] = 78, + [0][0][2][0][RTW89_IC][7] = 80, + [0][0][2][0][RTW89_KCC][7] = 78, + [0][0][2][0][RTW89_ACMA][7] = 60, + [0][0][2][0][RTW89_CN][7] = 58, + [0][0][2][0][RTW89_UK][7] = 60, + [0][0][2][0][RTW89_MEXICO][7] = 80, + [0][0][2][0][RTW89_UKRAINE][7] = 60, + [0][0][2][0][RTW89_CHILE][7] = 68, + [0][0][2][0][RTW89_QATAR][7] = 60, + [0][0][2][0][RTW89_THAILAND][7] = 60, + [0][0][2][0][RTW89_FCC][8] = 78, + [0][0][2][0][RTW89_ETSI][8] = 60, + [0][0][2][0][RTW89_MKK][8] = 78, + [0][0][2][0][RTW89_IC][8] = 78, + [0][0][2][0][RTW89_KCC][8] = 78, + [0][0][2][0][RTW89_ACMA][8] = 60, + [0][0][2][0][RTW89_CN][8] = 58, + [0][0][2][0][RTW89_UK][8] = 60, + [0][0][2][0][RTW89_MEXICO][8] = 78, + [0][0][2][0][RTW89_UKRAINE][8] = 60, + [0][0][2][0][RTW89_CHILE][8] = 68, + [0][0][2][0][RTW89_QATAR][8] = 60, + [0][0][2][0][RTW89_THAILAND][8] = 60, + [0][0][2][0][RTW89_FCC][9] = 74, + [0][0][2][0][RTW89_ETSI][9] = 60, + [0][0][2][0][RTW89_MKK][9] = 78, + [0][0][2][0][RTW89_IC][9] = 74, + [0][0][2][0][RTW89_KCC][9] = 66, + [0][0][2][0][RTW89_ACMA][9] = 60, + [0][0][2][0][RTW89_CN][9] = 58, + [0][0][2][0][RTW89_UK][9] = 60, + [0][0][2][0][RTW89_MEXICO][9] = 74, + [0][0][2][0][RTW89_UKRAINE][9] = 60, + [0][0][2][0][RTW89_CHILE][9] = 74, + [0][0][2][0][RTW89_QATAR][9] = 60, + [0][0][2][0][RTW89_THAILAND][9] = 60, + [0][0][2][0][RTW89_FCC][10] = 62, + [0][0][2][0][RTW89_ETSI][10] = 60, + [0][0][2][0][RTW89_MKK][10] = 78, + [0][0][2][0][RTW89_IC][10] = 62, + [0][0][2][0][RTW89_KCC][10] = 66, + [0][0][2][0][RTW89_ACMA][10] = 60, + [0][0][2][0][RTW89_CN][10] = 58, + [0][0][2][0][RTW89_UK][10] = 60, + [0][0][2][0][RTW89_MEXICO][10] = 62, + [0][0][2][0][RTW89_UKRAINE][10] = 60, + [0][0][2][0][RTW89_CHILE][10] = 62, + [0][0][2][0][RTW89_QATAR][10] = 60, + [0][0][2][0][RTW89_THAILAND][10] = 60, + [0][0][2][0][RTW89_FCC][11] = 60, + [0][0][2][0][RTW89_ETSI][11] = 60, + [0][0][2][0][RTW89_MKK][11] = 78, + [0][0][2][0][RTW89_IC][11] = 60, + [0][0][2][0][RTW89_KCC][11] = 66, + [0][0][2][0][RTW89_ACMA][11] = 60, + [0][0][2][0][RTW89_CN][11] = 58, + [0][0][2][0][RTW89_UK][11] = 60, + [0][0][2][0][RTW89_MEXICO][11] = 60, + [0][0][2][0][RTW89_UKRAINE][11] = 60, + [0][0][2][0][RTW89_CHILE][11] = 60, + [0][0][2][0][RTW89_QATAR][11] = 60, + [0][0][2][0][RTW89_THAILAND][11] = 60, + [0][0][2][0][RTW89_FCC][12] = 38, + [0][0][2][0][RTW89_ETSI][12] = 60, + [0][0][2][0][RTW89_MKK][12] = 78, + [0][0][2][0][RTW89_IC][12] = 38, + [0][0][2][0][RTW89_KCC][12] = 66, + [0][0][2][0][RTW89_ACMA][12] = 60, + [0][0][2][0][RTW89_CN][12] = 38, + [0][0][2][0][RTW89_UK][12] = 60, + [0][0][2][0][RTW89_MEXICO][12] = 38, + [0][0][2][0][RTW89_UKRAINE][12] = 60, + [0][0][2][0][RTW89_CHILE][12] = 38, + [0][0][2][0][RTW89_QATAR][12] = 60, + [0][0][2][0][RTW89_THAILAND][12] = 60, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_KCC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_CN][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, + [0][0][2][0][RTW89_MEXICO][13] = 127, + [0][0][2][0][RTW89_UKRAINE][13] = 127, + [0][0][2][0][RTW89_CHILE][13] = 127, + [0][0][2][0][RTW89_QATAR][13] = 127, + [0][0][2][0][RTW89_THAILAND][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 64, + [0][1][2][0][RTW89_ETSI][0] = 48, + [0][1][2][0][RTW89_MKK][0] = 68, + [0][1][2][0][RTW89_IC][0] = 64, + [0][1][2][0][RTW89_KCC][0] = 66, + [0][1][2][0][RTW89_ACMA][0] = 48, + [0][1][2][0][RTW89_CN][0] = 46, + [0][1][2][0][RTW89_UK][0] = 48, + [0][1][2][0][RTW89_MEXICO][0] = 64, + [0][1][2][0][RTW89_UKRAINE][0] = 48, + [0][1][2][0][RTW89_CHILE][0] = 64, + [0][1][2][0][RTW89_QATAR][0] = 48, + [0][1][2][0][RTW89_THAILAND][0] = 48, + [0][1][2][0][RTW89_FCC][1] = 70, + [0][1][2][0][RTW89_ETSI][1] = 48, + [0][1][2][0][RTW89_MKK][1] = 68, + [0][1][2][0][RTW89_IC][1] = 70, + [0][1][2][0][RTW89_KCC][1] = 66, + [0][1][2][0][RTW89_ACMA][1] = 48, + [0][1][2][0][RTW89_CN][1] = 46, + [0][1][2][0][RTW89_UK][1] = 48, + [0][1][2][0][RTW89_MEXICO][1] = 70, + [0][1][2][0][RTW89_UKRAINE][1] = 48, + [0][1][2][0][RTW89_CHILE][1] = 70, + [0][1][2][0][RTW89_QATAR][1] = 48, + [0][1][2][0][RTW89_THAILAND][1] = 48, + [0][1][2][0][RTW89_FCC][2] = 74, + [0][1][2][0][RTW89_ETSI][2] = 48, + [0][1][2][0][RTW89_MKK][2] = 68, + [0][1][2][0][RTW89_IC][2] = 74, + [0][1][2][0][RTW89_KCC][2] = 66, + [0][1][2][0][RTW89_ACMA][2] = 48, + [0][1][2][0][RTW89_CN][2] = 46, + [0][1][2][0][RTW89_UK][2] = 48, + [0][1][2][0][RTW89_MEXICO][2] = 74, + [0][1][2][0][RTW89_UKRAINE][2] = 48, + [0][1][2][0][RTW89_CHILE][2] = 56, + [0][1][2][0][RTW89_QATAR][2] = 48, + [0][1][2][0][RTW89_THAILAND][2] = 48, + [0][1][2][0][RTW89_FCC][3] = 78, + [0][1][2][0][RTW89_ETSI][3] = 48, + [0][1][2][0][RTW89_MKK][3] = 68, + [0][1][2][0][RTW89_IC][3] = 78, + [0][1][2][0][RTW89_KCC][3] = 66, + [0][1][2][0][RTW89_ACMA][3] = 48, + [0][1][2][0][RTW89_CN][3] = 46, + [0][1][2][0][RTW89_UK][3] = 48, + [0][1][2][0][RTW89_MEXICO][3] = 78, + [0][1][2][0][RTW89_UKRAINE][3] = 48, + [0][1][2][0][RTW89_CHILE][3] = 56, + [0][1][2][0][RTW89_QATAR][3] = 48, + [0][1][2][0][RTW89_THAILAND][3] = 48, + [0][1][2][0][RTW89_FCC][4] = 80, + [0][1][2][0][RTW89_ETSI][4] = 48, + [0][1][2][0][RTW89_MKK][4] = 68, + [0][1][2][0][RTW89_IC][4] = 80, + [0][1][2][0][RTW89_KCC][4] = 66, + [0][1][2][0][RTW89_ACMA][4] = 48, + [0][1][2][0][RTW89_CN][4] = 46, + [0][1][2][0][RTW89_UK][4] = 48, + [0][1][2][0][RTW89_MEXICO][4] = 80, + [0][1][2][0][RTW89_UKRAINE][4] = 48, + [0][1][2][0][RTW89_CHILE][4] = 56, + [0][1][2][0][RTW89_QATAR][4] = 48, + [0][1][2][0][RTW89_THAILAND][4] = 48, + [0][1][2][0][RTW89_FCC][5] = 80, + [0][1][2][0][RTW89_ETSI][5] = 48, + [0][1][2][0][RTW89_MKK][5] = 68, + [0][1][2][0][RTW89_IC][5] = 80, + [0][1][2][0][RTW89_KCC][5] = 66, + [0][1][2][0][RTW89_ACMA][5] = 48, + [0][1][2][0][RTW89_CN][5] = 46, + [0][1][2][0][RTW89_UK][5] = 48, + [0][1][2][0][RTW89_MEXICO][5] = 80, + [0][1][2][0][RTW89_UKRAINE][5] = 48, + [0][1][2][0][RTW89_CHILE][5] = 78, + [0][1][2][0][RTW89_QATAR][5] = 48, + [0][1][2][0][RTW89_THAILAND][5] = 48, + [0][1][2][0][RTW89_FCC][6] = 80, + [0][1][2][0][RTW89_ETSI][6] = 48, + [0][1][2][0][RTW89_MKK][6] = 68, + [0][1][2][0][RTW89_IC][6] = 80, + [0][1][2][0][RTW89_KCC][6] = 66, + [0][1][2][0][RTW89_ACMA][6] = 48, + [0][1][2][0][RTW89_CN][6] = 46, + [0][1][2][0][RTW89_UK][6] = 48, + [0][1][2][0][RTW89_MEXICO][6] = 80, + [0][1][2][0][RTW89_UKRAINE][6] = 48, + [0][1][2][0][RTW89_CHILE][6] = 54, + [0][1][2][0][RTW89_QATAR][6] = 48, + [0][1][2][0][RTW89_THAILAND][6] = 48, + [0][1][2][0][RTW89_FCC][7] = 74, + [0][1][2][0][RTW89_ETSI][7] = 48, + [0][1][2][0][RTW89_MKK][7] = 68, + [0][1][2][0][RTW89_IC][7] = 74, + [0][1][2][0][RTW89_KCC][7] = 66, + [0][1][2][0][RTW89_ACMA][7] = 48, + [0][1][2][0][RTW89_CN][7] = 46, + [0][1][2][0][RTW89_UK][7] = 48, + [0][1][2][0][RTW89_MEXICO][7] = 74, + [0][1][2][0][RTW89_UKRAINE][7] = 48, + [0][1][2][0][RTW89_CHILE][7] = 54, + [0][1][2][0][RTW89_QATAR][7] = 48, + [0][1][2][0][RTW89_THAILAND][7] = 48, + [0][1][2][0][RTW89_FCC][8] = 70, + [0][1][2][0][RTW89_ETSI][8] = 48, + [0][1][2][0][RTW89_MKK][8] = 68, + [0][1][2][0][RTW89_IC][8] = 70, + [0][1][2][0][RTW89_KCC][8] = 66, + [0][1][2][0][RTW89_ACMA][8] = 48, + [0][1][2][0][RTW89_CN][8] = 46, + [0][1][2][0][RTW89_UK][8] = 48, + [0][1][2][0][RTW89_MEXICO][8] = 70, + [0][1][2][0][RTW89_UKRAINE][8] = 48, + [0][1][2][0][RTW89_CHILE][8] = 54, + [0][1][2][0][RTW89_QATAR][8] = 48, + [0][1][2][0][RTW89_THAILAND][8] = 48, + [0][1][2][0][RTW89_FCC][9] = 66, + [0][1][2][0][RTW89_ETSI][9] = 48, + [0][1][2][0][RTW89_MKK][9] = 68, + [0][1][2][0][RTW89_IC][9] = 66, + [0][1][2][0][RTW89_KCC][9] = 64, + [0][1][2][0][RTW89_ACMA][9] = 48, + [0][1][2][0][RTW89_CN][9] = 46, + [0][1][2][0][RTW89_UK][9] = 48, + [0][1][2][0][RTW89_MEXICO][9] = 66, + [0][1][2][0][RTW89_UKRAINE][9] = 48, + [0][1][2][0][RTW89_CHILE][9] = 66, + [0][1][2][0][RTW89_QATAR][9] = 48, + [0][1][2][0][RTW89_THAILAND][9] = 48, + [0][1][2][0][RTW89_FCC][10] = 58, + [0][1][2][0][RTW89_ETSI][10] = 48, + [0][1][2][0][RTW89_MKK][10] = 68, + [0][1][2][0][RTW89_IC][10] = 58, + [0][1][2][0][RTW89_KCC][10] = 64, + [0][1][2][0][RTW89_ACMA][10] = 48, + [0][1][2][0][RTW89_CN][10] = 46, + [0][1][2][0][RTW89_UK][10] = 48, + [0][1][2][0][RTW89_MEXICO][10] = 58, + [0][1][2][0][RTW89_UKRAINE][10] = 48, + [0][1][2][0][RTW89_CHILE][10] = 58, + [0][1][2][0][RTW89_QATAR][10] = 48, + [0][1][2][0][RTW89_THAILAND][10] = 48, + [0][1][2][0][RTW89_FCC][11] = 58, + [0][1][2][0][RTW89_ETSI][11] = 48, + [0][1][2][0][RTW89_MKK][11] = 68, + [0][1][2][0][RTW89_IC][11] = 58, + [0][1][2][0][RTW89_KCC][11] = 64, + [0][1][2][0][RTW89_ACMA][11] = 48, + [0][1][2][0][RTW89_CN][11] = 46, + [0][1][2][0][RTW89_UK][11] = 48, + [0][1][2][0][RTW89_MEXICO][11] = 58, + [0][1][2][0][RTW89_UKRAINE][11] = 48, + [0][1][2][0][RTW89_CHILE][11] = 58, + [0][1][2][0][RTW89_QATAR][11] = 48, + [0][1][2][0][RTW89_THAILAND][11] = 48, + [0][1][2][0][RTW89_FCC][12] = 16, + [0][1][2][0][RTW89_ETSI][12] = 48, + [0][1][2][0][RTW89_MKK][12] = 68, + [0][1][2][0][RTW89_IC][12] = 16, + [0][1][2][0][RTW89_KCC][12] = 64, + [0][1][2][0][RTW89_ACMA][12] = 48, + [0][1][2][0][RTW89_CN][12] = 38, + [0][1][2][0][RTW89_UK][12] = 48, + [0][1][2][0][RTW89_MEXICO][12] = 16, + [0][1][2][0][RTW89_UKRAINE][12] = 48, + [0][1][2][0][RTW89_CHILE][12] = 16, + [0][1][2][0][RTW89_QATAR][12] = 48, + [0][1][2][0][RTW89_THAILAND][12] = 48, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_KCC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_CN][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, + [0][1][2][0][RTW89_MEXICO][13] = 127, + [0][1][2][0][RTW89_UKRAINE][13] = 127, + [0][1][2][0][RTW89_CHILE][13] = 127, + [0][1][2][0][RTW89_QATAR][13] = 127, + [0][1][2][0][RTW89_THAILAND][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 64, + [0][1][2][1][RTW89_ETSI][0] = 36, + [0][1][2][1][RTW89_MKK][0] = 68, + [0][1][2][1][RTW89_IC][0] = 64, + [0][1][2][1][RTW89_KCC][0] = 66, + [0][1][2][1][RTW89_ACMA][0] = 36, + [0][1][2][1][RTW89_CN][0] = 34, + [0][1][2][1][RTW89_UK][0] = 36, + [0][1][2][1][RTW89_MEXICO][0] = 64, + [0][1][2][1][RTW89_UKRAINE][0] = 36, + [0][1][2][1][RTW89_CHILE][0] = 64, + [0][1][2][1][RTW89_QATAR][0] = 36, + [0][1][2][1][RTW89_THAILAND][0] = 36, + [0][1][2][1][RTW89_FCC][1] = 70, + [0][1][2][1][RTW89_ETSI][1] = 36, + [0][1][2][1][RTW89_MKK][1] = 68, + [0][1][2][1][RTW89_IC][1] = 70, + [0][1][2][1][RTW89_KCC][1] = 66, + [0][1][2][1][RTW89_ACMA][1] = 36, + [0][1][2][1][RTW89_CN][1] = 34, + [0][1][2][1][RTW89_UK][1] = 36, + [0][1][2][1][RTW89_MEXICO][1] = 70, + [0][1][2][1][RTW89_UKRAINE][1] = 36, + [0][1][2][1][RTW89_CHILE][1] = 70, + [0][1][2][1][RTW89_QATAR][1] = 36, + [0][1][2][1][RTW89_THAILAND][1] = 36, + [0][1][2][1][RTW89_FCC][2] = 74, + [0][1][2][1][RTW89_ETSI][2] = 36, + [0][1][2][1][RTW89_MKK][2] = 68, + [0][1][2][1][RTW89_IC][2] = 74, + [0][1][2][1][RTW89_KCC][2] = 66, + [0][1][2][1][RTW89_ACMA][2] = 36, + [0][1][2][1][RTW89_CN][2] = 34, + [0][1][2][1][RTW89_UK][2] = 36, + [0][1][2][1][RTW89_MEXICO][2] = 74, + [0][1][2][1][RTW89_UKRAINE][2] = 36, + [0][1][2][1][RTW89_CHILE][2] = 44, + [0][1][2][1][RTW89_QATAR][2] = 36, + [0][1][2][1][RTW89_THAILAND][2] = 36, + [0][1][2][1][RTW89_FCC][3] = 78, + [0][1][2][1][RTW89_ETSI][3] = 36, + [0][1][2][1][RTW89_MKK][3] = 68, + [0][1][2][1][RTW89_IC][3] = 78, + [0][1][2][1][RTW89_KCC][3] = 66, + [0][1][2][1][RTW89_ACMA][3] = 36, + [0][1][2][1][RTW89_CN][3] = 34, + [0][1][2][1][RTW89_UK][3] = 36, + [0][1][2][1][RTW89_MEXICO][3] = 78, + [0][1][2][1][RTW89_UKRAINE][3] = 36, + [0][1][2][1][RTW89_CHILE][3] = 44, + [0][1][2][1][RTW89_QATAR][3] = 36, + [0][1][2][1][RTW89_THAILAND][3] = 36, + [0][1][2][1][RTW89_FCC][4] = 80, + [0][1][2][1][RTW89_ETSI][4] = 36, + [0][1][2][1][RTW89_MKK][4] = 68, + [0][1][2][1][RTW89_IC][4] = 80, + [0][1][2][1][RTW89_KCC][4] = 66, + [0][1][2][1][RTW89_ACMA][4] = 36, + [0][1][2][1][RTW89_CN][4] = 34, + [0][1][2][1][RTW89_UK][4] = 36, + [0][1][2][1][RTW89_MEXICO][4] = 80, + [0][1][2][1][RTW89_UKRAINE][4] = 36, + [0][1][2][1][RTW89_CHILE][4] = 44, + [0][1][2][1][RTW89_QATAR][4] = 36, + [0][1][2][1][RTW89_THAILAND][4] = 36, + [0][1][2][1][RTW89_FCC][5] = 80, + [0][1][2][1][RTW89_ETSI][5] = 36, + [0][1][2][1][RTW89_MKK][5] = 68, + [0][1][2][1][RTW89_IC][5] = 80, + [0][1][2][1][RTW89_KCC][5] = 66, + [0][1][2][1][RTW89_ACMA][5] = 36, + [0][1][2][1][RTW89_CN][5] = 34, + [0][1][2][1][RTW89_UK][5] = 36, + [0][1][2][1][RTW89_MEXICO][5] = 80, + [0][1][2][1][RTW89_UKRAINE][5] = 36, + [0][1][2][1][RTW89_CHILE][5] = 74, + [0][1][2][1][RTW89_QATAR][5] = 36, + [0][1][2][1][RTW89_THAILAND][5] = 36, + [0][1][2][1][RTW89_FCC][6] = 80, + [0][1][2][1][RTW89_ETSI][6] = 36, + [0][1][2][1][RTW89_MKK][6] = 68, + [0][1][2][1][RTW89_IC][6] = 80, + [0][1][2][1][RTW89_KCC][6] = 66, + [0][1][2][1][RTW89_ACMA][6] = 36, + [0][1][2][1][RTW89_CN][6] = 34, + [0][1][2][1][RTW89_UK][6] = 36, + [0][1][2][1][RTW89_MEXICO][6] = 80, + [0][1][2][1][RTW89_UKRAINE][6] = 36, + [0][1][2][1][RTW89_CHILE][6] = 42, + [0][1][2][1][RTW89_QATAR][6] = 36, + [0][1][2][1][RTW89_THAILAND][6] = 36, + [0][1][2][1][RTW89_FCC][7] = 74, + [0][1][2][1][RTW89_ETSI][7] = 36, + [0][1][2][1][RTW89_MKK][7] = 68, + [0][1][2][1][RTW89_IC][7] = 74, + [0][1][2][1][RTW89_KCC][7] = 66, + [0][1][2][1][RTW89_ACMA][7] = 36, + [0][1][2][1][RTW89_CN][7] = 34, + [0][1][2][1][RTW89_UK][7] = 36, + [0][1][2][1][RTW89_MEXICO][7] = 74, + [0][1][2][1][RTW89_UKRAINE][7] = 36, + [0][1][2][1][RTW89_CHILE][7] = 42, + [0][1][2][1][RTW89_QATAR][7] = 36, + [0][1][2][1][RTW89_THAILAND][7] = 36, + [0][1][2][1][RTW89_FCC][8] = 70, + [0][1][2][1][RTW89_ETSI][8] = 36, + [0][1][2][1][RTW89_MKK][8] = 68, + [0][1][2][1][RTW89_IC][8] = 70, + [0][1][2][1][RTW89_KCC][8] = 66, + [0][1][2][1][RTW89_ACMA][8] = 36, + [0][1][2][1][RTW89_CN][8] = 34, + [0][1][2][1][RTW89_UK][8] = 36, + [0][1][2][1][RTW89_MEXICO][8] = 70, + [0][1][2][1][RTW89_UKRAINE][8] = 36, + [0][1][2][1][RTW89_CHILE][8] = 42, + [0][1][2][1][RTW89_QATAR][8] = 36, + [0][1][2][1][RTW89_THAILAND][8] = 36, + [0][1][2][1][RTW89_FCC][9] = 66, + [0][1][2][1][RTW89_ETSI][9] = 36, + [0][1][2][1][RTW89_MKK][9] = 68, + [0][1][2][1][RTW89_IC][9] = 66, + [0][1][2][1][RTW89_KCC][9] = 64, + [0][1][2][1][RTW89_ACMA][9] = 36, + [0][1][2][1][RTW89_CN][9] = 34, + [0][1][2][1][RTW89_UK][9] = 36, + [0][1][2][1][RTW89_MEXICO][9] = 66, + [0][1][2][1][RTW89_UKRAINE][9] = 36, + [0][1][2][1][RTW89_CHILE][9] = 66, + [0][1][2][1][RTW89_QATAR][9] = 36, + [0][1][2][1][RTW89_THAILAND][9] = 36, + [0][1][2][1][RTW89_FCC][10] = 58, + [0][1][2][1][RTW89_ETSI][10] = 36, + [0][1][2][1][RTW89_MKK][10] = 68, + [0][1][2][1][RTW89_IC][10] = 58, + [0][1][2][1][RTW89_KCC][10] = 64, + [0][1][2][1][RTW89_ACMA][10] = 36, + [0][1][2][1][RTW89_CN][10] = 34, + [0][1][2][1][RTW89_UK][10] = 36, + [0][1][2][1][RTW89_MEXICO][10] = 58, + [0][1][2][1][RTW89_UKRAINE][10] = 36, + [0][1][2][1][RTW89_CHILE][10] = 58, + [0][1][2][1][RTW89_QATAR][10] = 36, + [0][1][2][1][RTW89_THAILAND][10] = 36, + [0][1][2][1][RTW89_FCC][11] = 58, + [0][1][2][1][RTW89_ETSI][11] = 36, + [0][1][2][1][RTW89_MKK][11] = 68, + [0][1][2][1][RTW89_IC][11] = 58, + [0][1][2][1][RTW89_KCC][11] = 64, + [0][1][2][1][RTW89_ACMA][11] = 36, + [0][1][2][1][RTW89_CN][11] = 34, + [0][1][2][1][RTW89_UK][11] = 36, + [0][1][2][1][RTW89_MEXICO][11] = 58, + [0][1][2][1][RTW89_UKRAINE][11] = 36, + [0][1][2][1][RTW89_CHILE][11] = 58, + [0][1][2][1][RTW89_QATAR][11] = 36, + [0][1][2][1][RTW89_THAILAND][11] = 36, + [0][1][2][1][RTW89_FCC][12] = 16, + [0][1][2][1][RTW89_ETSI][12] = 36, + [0][1][2][1][RTW89_MKK][12] = 68, + [0][1][2][1][RTW89_IC][12] = 16, + [0][1][2][1][RTW89_KCC][12] = 64, + [0][1][2][1][RTW89_ACMA][12] = 36, + [0][1][2][1][RTW89_CN][12] = 26, + [0][1][2][1][RTW89_UK][12] = 36, + [0][1][2][1][RTW89_MEXICO][12] = 16, + [0][1][2][1][RTW89_UKRAINE][12] = 36, + [0][1][2][1][RTW89_CHILE][12] = 16, + [0][1][2][1][RTW89_QATAR][12] = 36, + [0][1][2][1][RTW89_THAILAND][12] = 36, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_KCC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_CN][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, + [0][1][2][1][RTW89_MEXICO][13] = 127, + [0][1][2][1][RTW89_UKRAINE][13] = 127, + [0][1][2][1][RTW89_CHILE][13] = 127, + [0][1][2][1][RTW89_QATAR][13] = 127, + [0][1][2][1][RTW89_THAILAND][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_KCC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_CN][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, + [1][0][2][0][RTW89_MEXICO][0] = 127, + [1][0][2][0][RTW89_UKRAINE][0] = 127, + [1][0][2][0][RTW89_CHILE][0] = 127, + [1][0][2][0][RTW89_QATAR][0] = 127, + [1][0][2][0][RTW89_THAILAND][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_KCC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_CN][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, + [1][0][2][0][RTW89_MEXICO][1] = 127, + [1][0][2][0][RTW89_UKRAINE][1] = 127, + [1][0][2][0][RTW89_CHILE][1] = 127, + [1][0][2][0][RTW89_QATAR][1] = 127, + [1][0][2][0][RTW89_THAILAND][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 64, + [1][0][2][0][RTW89_ETSI][2] = 60, + [1][0][2][0][RTW89_MKK][2] = 74, + [1][0][2][0][RTW89_IC][2] = 64, + [1][0][2][0][RTW89_KCC][2] = 68, + [1][0][2][0][RTW89_ACMA][2] = 60, + [1][0][2][0][RTW89_CN][2] = 58, + [1][0][2][0][RTW89_UK][2] = 60, + [1][0][2][0][RTW89_MEXICO][2] = 64, + [1][0][2][0][RTW89_UKRAINE][2] = 60, + [1][0][2][0][RTW89_CHILE][2] = 64, + [1][0][2][0][RTW89_QATAR][2] = 60, + [1][0][2][0][RTW89_THAILAND][2] = 60, + [1][0][2][0][RTW89_FCC][3] = 64, + [1][0][2][0][RTW89_ETSI][3] = 60, + [1][0][2][0][RTW89_MKK][3] = 74, + [1][0][2][0][RTW89_IC][3] = 64, + [1][0][2][0][RTW89_KCC][3] = 68, + [1][0][2][0][RTW89_ACMA][3] = 60, + [1][0][2][0][RTW89_CN][3] = 58, + [1][0][2][0][RTW89_UK][3] = 60, + [1][0][2][0][RTW89_MEXICO][3] = 64, + [1][0][2][0][RTW89_UKRAINE][3] = 60, + [1][0][2][0][RTW89_CHILE][3] = 64, + [1][0][2][0][RTW89_QATAR][3] = 60, + [1][0][2][0][RTW89_THAILAND][3] = 60, + [1][0][2][0][RTW89_FCC][4] = 68, + [1][0][2][0][RTW89_ETSI][4] = 60, + [1][0][2][0][RTW89_MKK][4] = 74, + [1][0][2][0][RTW89_IC][4] = 68, + [1][0][2][0][RTW89_KCC][4] = 68, + [1][0][2][0][RTW89_ACMA][4] = 60, + [1][0][2][0][RTW89_CN][4] = 58, + [1][0][2][0][RTW89_UK][4] = 60, + [1][0][2][0][RTW89_MEXICO][4] = 68, + [1][0][2][0][RTW89_UKRAINE][4] = 60, + [1][0][2][0][RTW89_CHILE][4] = 68, + [1][0][2][0][RTW89_QATAR][4] = 60, + [1][0][2][0][RTW89_THAILAND][4] = 60, + [1][0][2][0][RTW89_FCC][5] = 68, + [1][0][2][0][RTW89_ETSI][5] = 60, + [1][0][2][0][RTW89_MKK][5] = 74, + [1][0][2][0][RTW89_IC][5] = 68, + [1][0][2][0][RTW89_KCC][5] = 74, + [1][0][2][0][RTW89_ACMA][5] = 60, + [1][0][2][0][RTW89_CN][5] = 58, + [1][0][2][0][RTW89_UK][5] = 60, + [1][0][2][0][RTW89_MEXICO][5] = 68, + [1][0][2][0][RTW89_UKRAINE][5] = 60, + [1][0][2][0][RTW89_CHILE][5] = 68, + [1][0][2][0][RTW89_QATAR][5] = 60, + [1][0][2][0][RTW89_THAILAND][5] = 60, + [1][0][2][0][RTW89_FCC][6] = 66, + [1][0][2][0][RTW89_ETSI][6] = 60, + [1][0][2][0][RTW89_MKK][6] = 74, + [1][0][2][0][RTW89_IC][6] = 66, + [1][0][2][0][RTW89_KCC][6] = 74, + [1][0][2][0][RTW89_ACMA][6] = 60, + [1][0][2][0][RTW89_CN][6] = 58, + [1][0][2][0][RTW89_UK][6] = 60, + [1][0][2][0][RTW89_MEXICO][6] = 66, + [1][0][2][0][RTW89_UKRAINE][6] = 60, + [1][0][2][0][RTW89_CHILE][6] = 66, + [1][0][2][0][RTW89_QATAR][6] = 60, + [1][0][2][0][RTW89_THAILAND][6] = 60, + [1][0][2][0][RTW89_FCC][7] = 62, + [1][0][2][0][RTW89_ETSI][7] = 60, + [1][0][2][0][RTW89_MKK][7] = 74, + [1][0][2][0][RTW89_IC][7] = 62, + [1][0][2][0][RTW89_KCC][7] = 74, + [1][0][2][0][RTW89_ACMA][7] = 60, + [1][0][2][0][RTW89_CN][7] = 58, + [1][0][2][0][RTW89_UK][7] = 60, + [1][0][2][0][RTW89_MEXICO][7] = 62, + [1][0][2][0][RTW89_UKRAINE][7] = 60, + [1][0][2][0][RTW89_CHILE][7] = 62, + [1][0][2][0][RTW89_QATAR][7] = 60, + [1][0][2][0][RTW89_THAILAND][7] = 60, + [1][0][2][0][RTW89_FCC][8] = 62, + [1][0][2][0][RTW89_ETSI][8] = 60, + [1][0][2][0][RTW89_MKK][8] = 74, + [1][0][2][0][RTW89_IC][8] = 62, + [1][0][2][0][RTW89_KCC][8] = 68, + [1][0][2][0][RTW89_ACMA][8] = 60, + [1][0][2][0][RTW89_CN][8] = 58, + [1][0][2][0][RTW89_UK][8] = 60, + [1][0][2][0][RTW89_MEXICO][8] = 62, + [1][0][2][0][RTW89_UKRAINE][8] = 60, + [1][0][2][0][RTW89_CHILE][8] = 62, + [1][0][2][0][RTW89_QATAR][8] = 60, + [1][0][2][0][RTW89_THAILAND][8] = 60, + [1][0][2][0][RTW89_FCC][9] = 60, + [1][0][2][0][RTW89_ETSI][9] = 60, + [1][0][2][0][RTW89_MKK][9] = 74, + [1][0][2][0][RTW89_IC][9] = 60, + [1][0][2][0][RTW89_KCC][9] = 68, + [1][0][2][0][RTW89_ACMA][9] = 60, + [1][0][2][0][RTW89_CN][9] = 58, + [1][0][2][0][RTW89_UK][9] = 60, + [1][0][2][0][RTW89_MEXICO][9] = 60, + [1][0][2][0][RTW89_UKRAINE][9] = 60, + [1][0][2][0][RTW89_CHILE][9] = 60, + [1][0][2][0][RTW89_QATAR][9] = 60, + [1][0][2][0][RTW89_THAILAND][9] = 60, + [1][0][2][0][RTW89_FCC][10] = 56, + [1][0][2][0][RTW89_ETSI][10] = 60, + [1][0][2][0][RTW89_MKK][10] = 74, + [1][0][2][0][RTW89_IC][10] = 56, + [1][0][2][0][RTW89_KCC][10] = 68, + [1][0][2][0][RTW89_ACMA][10] = 60, + [1][0][2][0][RTW89_CN][10] = 58, + [1][0][2][0][RTW89_UK][10] = 60, + [1][0][2][0][RTW89_MEXICO][10] = 56, + [1][0][2][0][RTW89_UKRAINE][10] = 60, + [1][0][2][0][RTW89_CHILE][10] = 56, + [1][0][2][0][RTW89_QATAR][10] = 60, + [1][0][2][0][RTW89_THAILAND][10] = 60, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_KCC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_CN][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, + [1][0][2][0][RTW89_MEXICO][11] = 127, + [1][0][2][0][RTW89_UKRAINE][11] = 127, + [1][0][2][0][RTW89_CHILE][11] = 127, + [1][0][2][0][RTW89_QATAR][11] = 127, + [1][0][2][0][RTW89_THAILAND][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_KCC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_CN][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, + [1][0][2][0][RTW89_MEXICO][12] = 127, + [1][0][2][0][RTW89_UKRAINE][12] = 127, + [1][0][2][0][RTW89_CHILE][12] = 127, + [1][0][2][0][RTW89_QATAR][12] = 127, + [1][0][2][0][RTW89_THAILAND][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_KCC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_CN][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, + [1][0][2][0][RTW89_MEXICO][13] = 127, + [1][0][2][0][RTW89_UKRAINE][13] = 127, + [1][0][2][0][RTW89_CHILE][13] = 127, + [1][0][2][0][RTW89_QATAR][13] = 127, + [1][0][2][0][RTW89_THAILAND][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_KCC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_CN][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, + [1][1][2][0][RTW89_MEXICO][0] = 127, + [1][1][2][0][RTW89_UKRAINE][0] = 127, + [1][1][2][0][RTW89_CHILE][0] = 127, + [1][1][2][0][RTW89_QATAR][0] = 127, + [1][1][2][0][RTW89_THAILAND][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_KCC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_CN][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, + [1][1][2][0][RTW89_MEXICO][1] = 127, + [1][1][2][0][RTW89_UKRAINE][1] = 127, + [1][1][2][0][RTW89_CHILE][1] = 127, + [1][1][2][0][RTW89_QATAR][1] = 127, + [1][1][2][0][RTW89_THAILAND][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 60, + [1][1][2][0][RTW89_ETSI][2] = 48, + [1][1][2][0][RTW89_MKK][2] = 68, + [1][1][2][0][RTW89_IC][2] = 60, + [1][1][2][0][RTW89_KCC][2] = 64, + [1][1][2][0][RTW89_ACMA][2] = 48, + [1][1][2][0][RTW89_CN][2] = 34, + [1][1][2][0][RTW89_UK][2] = 48, + [1][1][2][0][RTW89_MEXICO][2] = 60, + [1][1][2][0][RTW89_UKRAINE][2] = 48, + [1][1][2][0][RTW89_CHILE][2] = 60, + [1][1][2][0][RTW89_QATAR][2] = 48, + [1][1][2][0][RTW89_THAILAND][2] = 48, + [1][1][2][0][RTW89_FCC][3] = 60, + [1][1][2][0][RTW89_ETSI][3] = 48, + [1][1][2][0][RTW89_MKK][3] = 68, + [1][1][2][0][RTW89_IC][3] = 60, + [1][1][2][0][RTW89_KCC][3] = 64, + [1][1][2][0][RTW89_ACMA][3] = 48, + [1][1][2][0][RTW89_CN][3] = 34, + [1][1][2][0][RTW89_UK][3] = 48, + [1][1][2][0][RTW89_MEXICO][3] = 60, + [1][1][2][0][RTW89_UKRAINE][3] = 48, + [1][1][2][0][RTW89_CHILE][3] = 56, + [1][1][2][0][RTW89_QATAR][3] = 48, + [1][1][2][0][RTW89_THAILAND][3] = 48, + [1][1][2][0][RTW89_FCC][4] = 60, + [1][1][2][0][RTW89_ETSI][4] = 48, + [1][1][2][0][RTW89_MKK][4] = 68, + [1][1][2][0][RTW89_IC][4] = 60, + [1][1][2][0][RTW89_KCC][4] = 64, + [1][1][2][0][RTW89_ACMA][4] = 48, + [1][1][2][0][RTW89_CN][4] = 34, + [1][1][2][0][RTW89_UK][4] = 48, + [1][1][2][0][RTW89_MEXICO][4] = 60, + [1][1][2][0][RTW89_UKRAINE][4] = 48, + [1][1][2][0][RTW89_CHILE][4] = 56, + [1][1][2][0][RTW89_QATAR][4] = 48, + [1][1][2][0][RTW89_THAILAND][4] = 48, + [1][1][2][0][RTW89_FCC][5] = 60, + [1][1][2][0][RTW89_ETSI][5] = 48, + [1][1][2][0][RTW89_MKK][5] = 68, + [1][1][2][0][RTW89_IC][5] = 60, + [1][1][2][0][RTW89_KCC][5] = 66, + [1][1][2][0][RTW89_ACMA][5] = 48, + [1][1][2][0][RTW89_CN][5] = 34, + [1][1][2][0][RTW89_UK][5] = 48, + [1][1][2][0][RTW89_MEXICO][5] = 60, + [1][1][2][0][RTW89_UKRAINE][5] = 48, + [1][1][2][0][RTW89_CHILE][5] = 60, + [1][1][2][0][RTW89_QATAR][5] = 48, + [1][1][2][0][RTW89_THAILAND][5] = 48, + [1][1][2][0][RTW89_FCC][6] = 58, + [1][1][2][0][RTW89_ETSI][6] = 48, + [1][1][2][0][RTW89_MKK][6] = 68, + [1][1][2][0][RTW89_IC][6] = 58, + [1][1][2][0][RTW89_KCC][6] = 66, + [1][1][2][0][RTW89_ACMA][6] = 48, + [1][1][2][0][RTW89_CN][6] = 34, + [1][1][2][0][RTW89_UK][6] = 48, + [1][1][2][0][RTW89_MEXICO][6] = 58, + [1][1][2][0][RTW89_UKRAINE][6] = 48, + [1][1][2][0][RTW89_CHILE][6] = 52, + [1][1][2][0][RTW89_QATAR][6] = 48, + [1][1][2][0][RTW89_THAILAND][6] = 48, + [1][1][2][0][RTW89_FCC][7] = 54, + [1][1][2][0][RTW89_ETSI][7] = 48, + [1][1][2][0][RTW89_MKK][7] = 68, + [1][1][2][0][RTW89_IC][7] = 54, + [1][1][2][0][RTW89_KCC][7] = 66, + [1][1][2][0][RTW89_ACMA][7] = 48, + [1][1][2][0][RTW89_CN][7] = 34, + [1][1][2][0][RTW89_UK][7] = 48, + [1][1][2][0][RTW89_MEXICO][7] = 54, + [1][1][2][0][RTW89_UKRAINE][7] = 48, + [1][1][2][0][RTW89_CHILE][7] = 52, + [1][1][2][0][RTW89_QATAR][7] = 48, + [1][1][2][0][RTW89_THAILAND][7] = 48, + [1][1][2][0][RTW89_FCC][8] = 54, + [1][1][2][0][RTW89_ETSI][8] = 48, + [1][1][2][0][RTW89_MKK][8] = 68, + [1][1][2][0][RTW89_IC][8] = 54, + [1][1][2][0][RTW89_KCC][8] = 64, + [1][1][2][0][RTW89_ACMA][8] = 48, + [1][1][2][0][RTW89_CN][8] = 34, + [1][1][2][0][RTW89_UK][8] = 48, + [1][1][2][0][RTW89_MEXICO][8] = 54, + [1][1][2][0][RTW89_UKRAINE][8] = 48, + [1][1][2][0][RTW89_CHILE][8] = 54, + [1][1][2][0][RTW89_QATAR][8] = 48, + [1][1][2][0][RTW89_THAILAND][8] = 48, + [1][1][2][0][RTW89_FCC][9] = 54, + [1][1][2][0][RTW89_ETSI][9] = 48, + [1][1][2][0][RTW89_MKK][9] = 68, + [1][1][2][0][RTW89_IC][9] = 54, + [1][1][2][0][RTW89_KCC][9] = 64, + [1][1][2][0][RTW89_ACMA][9] = 48, + [1][1][2][0][RTW89_CN][9] = 34, + [1][1][2][0][RTW89_UK][9] = 48, + [1][1][2][0][RTW89_MEXICO][9] = 54, + [1][1][2][0][RTW89_UKRAINE][9] = 48, + [1][1][2][0][RTW89_CHILE][9] = 54, + [1][1][2][0][RTW89_QATAR][9] = 48, + [1][1][2][0][RTW89_THAILAND][9] = 48, + [1][1][2][0][RTW89_FCC][10] = 46, + [1][1][2][0][RTW89_ETSI][10] = 48, + [1][1][2][0][RTW89_MKK][10] = 68, + [1][1][2][0][RTW89_IC][10] = 46, + [1][1][2][0][RTW89_KCC][10] = 64, + [1][1][2][0][RTW89_ACMA][10] = 48, + [1][1][2][0][RTW89_CN][10] = 34, + [1][1][2][0][RTW89_UK][10] = 48, + [1][1][2][0][RTW89_MEXICO][10] = 46, + [1][1][2][0][RTW89_UKRAINE][10] = 48, + [1][1][2][0][RTW89_CHILE][10] = 46, + [1][1][2][0][RTW89_QATAR][10] = 48, + [1][1][2][0][RTW89_THAILAND][10] = 48, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_KCC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_CN][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, + [1][1][2][0][RTW89_MEXICO][11] = 127, + [1][1][2][0][RTW89_UKRAINE][11] = 127, + [1][1][2][0][RTW89_CHILE][11] = 127, + [1][1][2][0][RTW89_QATAR][11] = 127, + [1][1][2][0][RTW89_THAILAND][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_KCC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_CN][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, + [1][1][2][0][RTW89_MEXICO][12] = 127, + [1][1][2][0][RTW89_UKRAINE][12] = 127, + [1][1][2][0][RTW89_CHILE][12] = 127, + [1][1][2][0][RTW89_QATAR][12] = 127, + [1][1][2][0][RTW89_THAILAND][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_KCC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_CN][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, + [1][1][2][0][RTW89_MEXICO][13] = 127, + [1][1][2][0][RTW89_UKRAINE][13] = 127, + [1][1][2][0][RTW89_CHILE][13] = 127, + [1][1][2][0][RTW89_QATAR][13] = 127, + [1][1][2][0][RTW89_THAILAND][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_KCC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_CN][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, + [1][1][2][1][RTW89_MEXICO][0] = 127, + [1][1][2][1][RTW89_UKRAINE][0] = 127, + [1][1][2][1][RTW89_CHILE][0] = 127, + [1][1][2][1][RTW89_QATAR][0] = 127, + [1][1][2][1][RTW89_THAILAND][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_KCC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_CN][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, + [1][1][2][1][RTW89_MEXICO][1] = 127, + [1][1][2][1][RTW89_UKRAINE][1] = 127, + [1][1][2][1][RTW89_CHILE][1] = 127, + [1][1][2][1][RTW89_QATAR][1] = 127, + [1][1][2][1][RTW89_THAILAND][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 60, + [1][1][2][1][RTW89_ETSI][2] = 36, + [1][1][2][1][RTW89_MKK][2] = 68, + [1][1][2][1][RTW89_IC][2] = 60, + [1][1][2][1][RTW89_KCC][2] = 64, + [1][1][2][1][RTW89_ACMA][2] = 36, + [1][1][2][1][RTW89_CN][2] = 34, + [1][1][2][1][RTW89_UK][2] = 36, + [1][1][2][1][RTW89_MEXICO][2] = 60, + [1][1][2][1][RTW89_UKRAINE][2] = 36, + [1][1][2][1][RTW89_CHILE][2] = 60, + [1][1][2][1][RTW89_QATAR][2] = 36, + [1][1][2][1][RTW89_THAILAND][2] = 36, + [1][1][2][1][RTW89_FCC][3] = 60, + [1][1][2][1][RTW89_ETSI][3] = 36, + [1][1][2][1][RTW89_MKK][3] = 68, + [1][1][2][1][RTW89_IC][3] = 60, + [1][1][2][1][RTW89_KCC][3] = 64, + [1][1][2][1][RTW89_ACMA][3] = 36, + [1][1][2][1][RTW89_CN][3] = 34, + [1][1][2][1][RTW89_UK][3] = 36, + [1][1][2][1][RTW89_MEXICO][3] = 60, + [1][1][2][1][RTW89_UKRAINE][3] = 36, + [1][1][2][1][RTW89_CHILE][3] = 44, + [1][1][2][1][RTW89_QATAR][3] = 36, + [1][1][2][1][RTW89_THAILAND][3] = 36, + [1][1][2][1][RTW89_FCC][4] = 60, + [1][1][2][1][RTW89_ETSI][4] = 36, + [1][1][2][1][RTW89_MKK][4] = 68, + [1][1][2][1][RTW89_IC][4] = 60, + [1][1][2][1][RTW89_KCC][4] = 64, + [1][1][2][1][RTW89_ACMA][4] = 36, + [1][1][2][1][RTW89_CN][4] = 34, + [1][1][2][1][RTW89_UK][4] = 36, + [1][1][2][1][RTW89_MEXICO][4] = 60, + [1][1][2][1][RTW89_UKRAINE][4] = 36, + [1][1][2][1][RTW89_CHILE][4] = 44, + [1][1][2][1][RTW89_QATAR][4] = 36, + [1][1][2][1][RTW89_THAILAND][4] = 36, + [1][1][2][1][RTW89_FCC][5] = 60, + [1][1][2][1][RTW89_ETSI][5] = 36, + [1][1][2][1][RTW89_MKK][5] = 68, + [1][1][2][1][RTW89_IC][5] = 60, + [1][1][2][1][RTW89_KCC][5] = 66, + [1][1][2][1][RTW89_ACMA][5] = 36, + [1][1][2][1][RTW89_CN][5] = 34, + [1][1][2][1][RTW89_UK][5] = 36, + [1][1][2][1][RTW89_MEXICO][5] = 60, + [1][1][2][1][RTW89_UKRAINE][5] = 36, + [1][1][2][1][RTW89_CHILE][5] = 60, + [1][1][2][1][RTW89_QATAR][5] = 36, + [1][1][2][1][RTW89_THAILAND][5] = 36, + [1][1][2][1][RTW89_FCC][6] = 58, + [1][1][2][1][RTW89_ETSI][6] = 36, + [1][1][2][1][RTW89_MKK][6] = 68, + [1][1][2][1][RTW89_IC][6] = 58, + [1][1][2][1][RTW89_KCC][6] = 66, + [1][1][2][1][RTW89_ACMA][6] = 36, + [1][1][2][1][RTW89_CN][6] = 34, + [1][1][2][1][RTW89_UK][6] = 36, + [1][1][2][1][RTW89_MEXICO][6] = 58, + [1][1][2][1][RTW89_UKRAINE][6] = 36, + [1][1][2][1][RTW89_CHILE][6] = 40, + [1][1][2][1][RTW89_QATAR][6] = 36, + [1][1][2][1][RTW89_THAILAND][6] = 36, + [1][1][2][1][RTW89_FCC][7] = 54, + [1][1][2][1][RTW89_ETSI][7] = 36, + [1][1][2][1][RTW89_MKK][7] = 68, + [1][1][2][1][RTW89_IC][7] = 54, + [1][1][2][1][RTW89_KCC][7] = 66, + [1][1][2][1][RTW89_ACMA][7] = 36, + [1][1][2][1][RTW89_CN][7] = 34, + [1][1][2][1][RTW89_UK][7] = 36, + [1][1][2][1][RTW89_MEXICO][7] = 54, + [1][1][2][1][RTW89_UKRAINE][7] = 36, + [1][1][2][1][RTW89_CHILE][7] = 40, + [1][1][2][1][RTW89_QATAR][7] = 36, + [1][1][2][1][RTW89_THAILAND][7] = 36, + [1][1][2][1][RTW89_FCC][8] = 54, + [1][1][2][1][RTW89_ETSI][8] = 36, + [1][1][2][1][RTW89_MKK][8] = 68, + [1][1][2][1][RTW89_IC][8] = 54, + [1][1][2][1][RTW89_KCC][8] = 64, + [1][1][2][1][RTW89_ACMA][8] = 36, + [1][1][2][1][RTW89_CN][8] = 34, + [1][1][2][1][RTW89_UK][8] = 36, + [1][1][2][1][RTW89_MEXICO][8] = 54, + [1][1][2][1][RTW89_UKRAINE][8] = 36, + [1][1][2][1][RTW89_CHILE][8] = 54, + [1][1][2][1][RTW89_QATAR][8] = 36, + [1][1][2][1][RTW89_THAILAND][8] = 36, + [1][1][2][1][RTW89_FCC][9] = 54, + [1][1][2][1][RTW89_ETSI][9] = 36, + [1][1][2][1][RTW89_MKK][9] = 68, + [1][1][2][1][RTW89_IC][9] = 54, + [1][1][2][1][RTW89_KCC][9] = 64, + [1][1][2][1][RTW89_ACMA][9] = 36, + [1][1][2][1][RTW89_CN][9] = 34, + [1][1][2][1][RTW89_UK][9] = 36, + [1][1][2][1][RTW89_MEXICO][9] = 54, + [1][1][2][1][RTW89_UKRAINE][9] = 36, + [1][1][2][1][RTW89_CHILE][9] = 54, + [1][1][2][1][RTW89_QATAR][9] = 36, + [1][1][2][1][RTW89_THAILAND][9] = 36, + [1][1][2][1][RTW89_FCC][10] = 46, + [1][1][2][1][RTW89_ETSI][10] = 36, + [1][1][2][1][RTW89_MKK][10] = 68, + [1][1][2][1][RTW89_IC][10] = 46, + [1][1][2][1][RTW89_KCC][10] = 64, + [1][1][2][1][RTW89_ACMA][10] = 36, + [1][1][2][1][RTW89_CN][10] = 34, + [1][1][2][1][RTW89_UK][10] = 36, + [1][1][2][1][RTW89_MEXICO][10] = 46, + [1][1][2][1][RTW89_UKRAINE][10] = 36, + [1][1][2][1][RTW89_CHILE][10] = 46, + [1][1][2][1][RTW89_QATAR][10] = 36, + [1][1][2][1][RTW89_THAILAND][10] = 36, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_KCC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_CN][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, + [1][1][2][1][RTW89_MEXICO][11] = 127, + [1][1][2][1][RTW89_UKRAINE][11] = 127, + [1][1][2][1][RTW89_CHILE][11] = 127, + [1][1][2][1][RTW89_QATAR][11] = 127, + [1][1][2][1][RTW89_THAILAND][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_KCC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_CN][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, + [1][1][2][1][RTW89_MEXICO][12] = 127, + [1][1][2][1][RTW89_UKRAINE][12] = 127, + [1][1][2][1][RTW89_CHILE][12] = 127, + [1][1][2][1][RTW89_QATAR][12] = 127, + [1][1][2][1][RTW89_THAILAND][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_KCC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_CN][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, + [1][1][2][1][RTW89_MEXICO][13] = 127, + [1][1][2][1][RTW89_UKRAINE][13] = 127, + [1][1][2][1][RTW89_CHILE][13] = 127, + [1][1][2][1][RTW89_QATAR][13] = 127, + [1][1][2][1][RTW89_THAILAND][13] = 127, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 50, + [0][0][1][0][RTW89_WW][2] = 50, + [0][0][1][0][RTW89_WW][4] = 50, + [0][0][1][0][RTW89_WW][6] = 50, + [0][0][1][0][RTW89_WW][8] = 50, + [0][0][1][0][RTW89_WW][10] = 50, + [0][0][1][0][RTW89_WW][12] = 50, + [0][0][1][0][RTW89_WW][14] = 50, + [0][0][1][0][RTW89_WW][15] = 54, + [0][0][1][0][RTW89_WW][17] = 54, + [0][0][1][0][RTW89_WW][19] = 54, + [0][0][1][0][RTW89_WW][21] = 54, + [0][0][1][0][RTW89_WW][23] = 54, + [0][0][1][0][RTW89_WW][25] = 54, + [0][0][1][0][RTW89_WW][27] = 54, + [0][0][1][0][RTW89_WW][29] = 54, + [0][0][1][0][RTW89_WW][31] = 54, + [0][0][1][0][RTW89_WW][33] = 54, + [0][0][1][0][RTW89_WW][35] = 54, + [0][0][1][0][RTW89_WW][37] = 64, + [0][0][1][0][RTW89_WW][38] = 30, + [0][0][1][0][RTW89_WW][40] = 30, + [0][0][1][0][RTW89_WW][42] = 30, + [0][0][1][0][RTW89_WW][44] = 30, + [0][0][1][0][RTW89_WW][46] = 30, + [0][0][1][0][RTW89_WW][48] = 72, + [0][0][1][0][RTW89_WW][50] = 72, + [0][0][1][0][RTW89_WW][52] = 72, + [0][1][1][0][RTW89_WW][0] = 34, + [0][1][1][0][RTW89_WW][2] = 34, + [0][1][1][0][RTW89_WW][4] = 34, + [0][1][1][0][RTW89_WW][6] = 36, + [0][1][1][0][RTW89_WW][8] = 42, + [0][1][1][0][RTW89_WW][10] = 42, + [0][1][1][0][RTW89_WW][12] = 42, + [0][1][1][0][RTW89_WW][14] = 42, + [0][1][1][0][RTW89_WW][15] = 42, + [0][1][1][0][RTW89_WW][17] = 42, + [0][1][1][0][RTW89_WW][19] = 42, + [0][1][1][0][RTW89_WW][21] = 42, + [0][1][1][0][RTW89_WW][23] = 42, + [0][1][1][0][RTW89_WW][25] = 42, + [0][1][1][0][RTW89_WW][27] = 42, + [0][1][1][0][RTW89_WW][29] = 42, + [0][1][1][0][RTW89_WW][31] = 42, + [0][1][1][0][RTW89_WW][33] = 42, + [0][1][1][0][RTW89_WW][35] = 42, + [0][1][1][0][RTW89_WW][37] = 52, + [0][1][1][0][RTW89_WW][38] = 18, + [0][1][1][0][RTW89_WW][40] = 18, + [0][1][1][0][RTW89_WW][42] = 18, + [0][1][1][0][RTW89_WW][44] = 18, + [0][1][1][0][RTW89_WW][46] = 18, + [0][1][1][0][RTW89_WW][48] = 48, + [0][1][1][0][RTW89_WW][50] = 48, + [0][1][1][0][RTW89_WW][52] = 48, + [0][0][2][0][RTW89_WW][0] = 52, + [0][0][2][0][RTW89_WW][2] = 52, + [0][0][2][0][RTW89_WW][4] = 52, + [0][0][2][0][RTW89_WW][6] = 52, + [0][0][2][0][RTW89_WW][8] = 52, + [0][0][2][0][RTW89_WW][10] = 52, + [0][0][2][0][RTW89_WW][12] = 52, + [0][0][2][0][RTW89_WW][14] = 52, + [0][0][2][0][RTW89_WW][15] = 54, + [0][0][2][0][RTW89_WW][17] = 54, + [0][0][2][0][RTW89_WW][19] = 54, + [0][0][2][0][RTW89_WW][21] = 54, + [0][0][2][0][RTW89_WW][23] = 54, + [0][0][2][0][RTW89_WW][25] = 54, + [0][0][2][0][RTW89_WW][27] = 54, + [0][0][2][0][RTW89_WW][29] = 54, + [0][0][2][0][RTW89_WW][31] = 54, + [0][0][2][0][RTW89_WW][33] = 54, + [0][0][2][0][RTW89_WW][35] = 54, + [0][0][2][0][RTW89_WW][37] = 64, + [0][0][2][0][RTW89_WW][38] = 30, + [0][0][2][0][RTW89_WW][40] = 30, + [0][0][2][0][RTW89_WW][42] = 30, + [0][0][2][0][RTW89_WW][44] = 30, + [0][0][2][0][RTW89_WW][46] = 30, + [0][0][2][0][RTW89_WW][48] = 72, + [0][0][2][0][RTW89_WW][50] = 72, + [0][0][2][0][RTW89_WW][52] = 72, + [0][1][2][0][RTW89_WW][0] = 36, + [0][1][2][0][RTW89_WW][2] = 36, + [0][1][2][0][RTW89_WW][4] = 36, + [0][1][2][0][RTW89_WW][6] = 38, + [0][1][2][0][RTW89_WW][8] = 40, + [0][1][2][0][RTW89_WW][10] = 40, + [0][1][2][0][RTW89_WW][12] = 40, + [0][1][2][0][RTW89_WW][14] = 40, + [0][1][2][0][RTW89_WW][15] = 42, + [0][1][2][0][RTW89_WW][17] = 42, + [0][1][2][0][RTW89_WW][19] = 42, + [0][1][2][0][RTW89_WW][21] = 42, + [0][1][2][0][RTW89_WW][23] = 42, + [0][1][2][0][RTW89_WW][25] = 42, + [0][1][2][0][RTW89_WW][27] = 42, + [0][1][2][0][RTW89_WW][29] = 42, + [0][1][2][0][RTW89_WW][31] = 42, + [0][1][2][0][RTW89_WW][33] = 42, + [0][1][2][0][RTW89_WW][35] = 42, + [0][1][2][0][RTW89_WW][37] = 52, + [0][1][2][0][RTW89_WW][38] = 18, + [0][1][2][0][RTW89_WW][40] = 18, + [0][1][2][0][RTW89_WW][42] = 18, + [0][1][2][0][RTW89_WW][44] = 18, + [0][1][2][0][RTW89_WW][46] = 18, + [0][1][2][0][RTW89_WW][48] = 48, + [0][1][2][0][RTW89_WW][50] = 50, + [0][1][2][0][RTW89_WW][52] = 48, + [0][1][2][1][RTW89_WW][0] = 30, + [0][1][2][1][RTW89_WW][2] = 30, + [0][1][2][1][RTW89_WW][4] = 30, + [0][1][2][1][RTW89_WW][6] = 30, + [0][1][2][1][RTW89_WW][8] = 30, + [0][1][2][1][RTW89_WW][10] = 30, + [0][1][2][1][RTW89_WW][12] = 30, + [0][1][2][1][RTW89_WW][14] = 30, + [0][1][2][1][RTW89_WW][15] = 30, + [0][1][2][1][RTW89_WW][17] = 30, + [0][1][2][1][RTW89_WW][19] = 30, + [0][1][2][1][RTW89_WW][21] = 30, + [0][1][2][1][RTW89_WW][23] = 30, + [0][1][2][1][RTW89_WW][25] = 30, + [0][1][2][1][RTW89_WW][27] = 30, + [0][1][2][1][RTW89_WW][29] = 30, + [0][1][2][1][RTW89_WW][31] = 30, + [0][1][2][1][RTW89_WW][33] = 30, + [0][1][2][1][RTW89_WW][35] = 30, + [0][1][2][1][RTW89_WW][37] = 40, + [0][1][2][1][RTW89_WW][38] = 6, + [0][1][2][1][RTW89_WW][40] = 6, + [0][1][2][1][RTW89_WW][42] = 6, + [0][1][2][1][RTW89_WW][44] = 6, + [0][1][2][1][RTW89_WW][46] = 6, + [0][1][2][1][RTW89_WW][48] = 48, + [0][1][2][1][RTW89_WW][50] = 50, + [0][1][2][1][RTW89_WW][52] = 48, + [1][0][2][0][RTW89_WW][1] = 54, + [1][0][2][0][RTW89_WW][5] = 54, + [1][0][2][0][RTW89_WW][9] = 54, + [1][0][2][0][RTW89_WW][13] = 52, + [1][0][2][0][RTW89_WW][16] = 54, + [1][0][2][0][RTW89_WW][20] = 54, + [1][0][2][0][RTW89_WW][24] = 54, + [1][0][2][0][RTW89_WW][28] = 54, + [1][0][2][0][RTW89_WW][32] = 54, + [1][0][2][0][RTW89_WW][36] = 64, + [1][0][2][0][RTW89_WW][39] = 30, + [1][0][2][0][RTW89_WW][43] = 30, + [1][0][2][0][RTW89_WW][47] = 68, + [1][0][2][0][RTW89_WW][51] = 68, + [1][1][2][0][RTW89_WW][1] = 42, + [1][1][2][0][RTW89_WW][5] = 42, + [1][1][2][0][RTW89_WW][9] = 42, + [1][1][2][0][RTW89_WW][13] = 42, + [1][1][2][0][RTW89_WW][16] = 42, + [1][1][2][0][RTW89_WW][20] = 42, + [1][1][2][0][RTW89_WW][24] = 42, + [1][1][2][0][RTW89_WW][28] = 42, + [1][1][2][0][RTW89_WW][32] = 42, + [1][1][2][0][RTW89_WW][36] = 52, + [1][1][2][0][RTW89_WW][39] = 18, + [1][1][2][0][RTW89_WW][43] = 18, + [1][1][2][0][RTW89_WW][47] = 62, + [1][1][2][0][RTW89_WW][51] = 60, + [1][1][2][1][RTW89_WW][1] = 30, + [1][1][2][1][RTW89_WW][5] = 30, + [1][1][2][1][RTW89_WW][9] = 30, + [1][1][2][1][RTW89_WW][13] = 30, + [1][1][2][1][RTW89_WW][16] = 30, + [1][1][2][1][RTW89_WW][20] = 30, + [1][1][2][1][RTW89_WW][24] = 30, + [1][1][2][1][RTW89_WW][28] = 30, + [1][1][2][1][RTW89_WW][32] = 30, + [1][1][2][1][RTW89_WW][36] = 40, + [1][1][2][1][RTW89_WW][39] = 6, + [1][1][2][1][RTW89_WW][43] = 6, + [1][1][2][1][RTW89_WW][47] = 62, + [1][1][2][1][RTW89_WW][51] = 60, + [2][0][2][0][RTW89_WW][3] = 54, + [2][0][2][0][RTW89_WW][11] = 50, + [2][0][2][0][RTW89_WW][18] = 54, + [2][0][2][0][RTW89_WW][26] = 54, + [2][0][2][0][RTW89_WW][34] = 60, + [2][0][2][0][RTW89_WW][41] = 30, + [2][0][2][0][RTW89_WW][49] = 62, + [2][1][2][0][RTW89_WW][3] = 42, + [2][1][2][0][RTW89_WW][11] = 38, + [2][1][2][0][RTW89_WW][18] = 42, + [2][1][2][0][RTW89_WW][26] = 42, + [2][1][2][0][RTW89_WW][34] = 52, + [2][1][2][0][RTW89_WW][41] = 18, + [2][1][2][0][RTW89_WW][49] = 62, + [2][1][2][1][RTW89_WW][3] = 30, + [2][1][2][1][RTW89_WW][11] = 30, + [2][1][2][1][RTW89_WW][18] = 30, + [2][1][2][1][RTW89_WW][26] = 30, + [2][1][2][1][RTW89_WW][34] = 40, + [2][1][2][1][RTW89_WW][41] = 6, + [2][1][2][1][RTW89_WW][49] = 62, + [3][0][2][0][RTW89_WW][7] = 40, + [3][0][2][0][RTW89_WW][22] = 42, + [3][0][2][0][RTW89_WW][45] = 52, + [3][1][2][0][RTW89_WW][7] = 32, + [3][1][2][0][RTW89_WW][22] = 36, + [3][1][2][0][RTW89_WW][45] = 46, + [3][1][2][1][RTW89_WW][7] = 32, + [3][1][2][1][RTW89_WW][22] = 36, + [3][1][2][1][RTW89_WW][45] = 46, + [0][0][1][0][RTW89_FCC][0] = 72, + [0][0][1][0][RTW89_ETSI][0] = 66, + [0][0][1][0][RTW89_MKK][0] = 66, + [0][0][1][0][RTW89_IC][0] = 60, + [0][0][1][0][RTW89_KCC][0] = 62, + [0][0][1][0][RTW89_ACMA][0] = 66, + [0][0][1][0][RTW89_CN][0] = 50, + [0][0][1][0][RTW89_UK][0] = 66, + [0][0][1][0][RTW89_MEXICO][0] = 62, + [0][0][1][0][RTW89_UKRAINE][0] = 54, + [0][0][1][0][RTW89_CHILE][0] = 70, + [0][0][1][0][RTW89_QATAR][0] = 66, + [0][0][1][0][RTW89_THAILAND][0] = 66, + [0][0][1][0][RTW89_FCC][2] = 72, + [0][0][1][0][RTW89_ETSI][2] = 66, + [0][0][1][0][RTW89_MKK][2] = 66, + [0][0][1][0][RTW89_IC][2] = 60, + [0][0][1][0][RTW89_KCC][2] = 62, + [0][0][1][0][RTW89_ACMA][2] = 66, + [0][0][1][0][RTW89_CN][2] = 50, + [0][0][1][0][RTW89_UK][2] = 66, + [0][0][1][0][RTW89_MEXICO][2] = 62, + [0][0][1][0][RTW89_UKRAINE][2] = 54, + [0][0][1][0][RTW89_CHILE][2] = 70, + [0][0][1][0][RTW89_QATAR][2] = 66, + [0][0][1][0][RTW89_THAILAND][2] = 66, + [0][0][1][0][RTW89_FCC][4] = 72, + [0][0][1][0][RTW89_ETSI][4] = 66, + [0][0][1][0][RTW89_MKK][4] = 66, + [0][0][1][0][RTW89_IC][4] = 60, + [0][0][1][0][RTW89_KCC][4] = 62, + [0][0][1][0][RTW89_ACMA][4] = 66, + [0][0][1][0][RTW89_CN][4] = 50, + [0][0][1][0][RTW89_UK][4] = 66, + [0][0][1][0][RTW89_MEXICO][4] = 62, + [0][0][1][0][RTW89_UKRAINE][4] = 54, + [0][0][1][0][RTW89_CHILE][4] = 70, + [0][0][1][0][RTW89_QATAR][4] = 66, + [0][0][1][0][RTW89_THAILAND][4] = 66, + [0][0][1][0][RTW89_FCC][6] = 72, + [0][0][1][0][RTW89_ETSI][6] = 66, + [0][0][1][0][RTW89_MKK][6] = 66, + [0][0][1][0][RTW89_IC][6] = 58, + [0][0][1][0][RTW89_KCC][6] = 52, + [0][0][1][0][RTW89_ACMA][6] = 66, + [0][0][1][0][RTW89_CN][6] = 50, + [0][0][1][0][RTW89_UK][6] = 66, + [0][0][1][0][RTW89_MEXICO][6] = 62, + [0][0][1][0][RTW89_UKRAINE][6] = 54, + [0][0][1][0][RTW89_CHILE][6] = 70, + [0][0][1][0][RTW89_QATAR][6] = 66, + [0][0][1][0][RTW89_THAILAND][6] = 66, + [0][0][1][0][RTW89_FCC][8] = 72, + [0][0][1][0][RTW89_ETSI][8] = 66, + [0][0][1][0][RTW89_MKK][8] = 66, + [0][0][1][0][RTW89_IC][8] = 64, + [0][0][1][0][RTW89_KCC][8] = 70, + [0][0][1][0][RTW89_ACMA][8] = 66, + [0][0][1][0][RTW89_CN][8] = 50, + [0][0][1][0][RTW89_UK][8] = 66, + [0][0][1][0][RTW89_MEXICO][8] = 72, + [0][0][1][0][RTW89_UKRAINE][8] = 54, + [0][0][1][0][RTW89_CHILE][8] = 70, + [0][0][1][0][RTW89_QATAR][8] = 66, + [0][0][1][0][RTW89_THAILAND][8] = 66, + [0][0][1][0][RTW89_FCC][10] = 72, + [0][0][1][0][RTW89_ETSI][10] = 66, + [0][0][1][0][RTW89_MKK][10] = 66, + [0][0][1][0][RTW89_IC][10] = 64, + [0][0][1][0][RTW89_KCC][10] = 70, + [0][0][1][0][RTW89_ACMA][10] = 66, + [0][0][1][0][RTW89_CN][10] = 50, + [0][0][1][0][RTW89_UK][10] = 66, + [0][0][1][0][RTW89_MEXICO][10] = 72, + [0][0][1][0][RTW89_UKRAINE][10] = 54, + [0][0][1][0][RTW89_CHILE][10] = 70, + [0][0][1][0][RTW89_QATAR][10] = 66, + [0][0][1][0][RTW89_THAILAND][10] = 66, + [0][0][1][0][RTW89_FCC][12] = 72, + [0][0][1][0][RTW89_ETSI][12] = 66, + [0][0][1][0][RTW89_MKK][12] = 66, + [0][0][1][0][RTW89_IC][12] = 64, + [0][0][1][0][RTW89_KCC][12] = 66, + [0][0][1][0][RTW89_ACMA][12] = 66, + [0][0][1][0][RTW89_CN][12] = 50, + [0][0][1][0][RTW89_UK][12] = 66, + [0][0][1][0][RTW89_MEXICO][12] = 72, + [0][0][1][0][RTW89_UKRAINE][12] = 54, + [0][0][1][0][RTW89_CHILE][12] = 70, + [0][0][1][0][RTW89_QATAR][12] = 66, + [0][0][1][0][RTW89_THAILAND][12] = 66, + [0][0][1][0][RTW89_FCC][14] = 70, + [0][0][1][0][RTW89_ETSI][14] = 66, + [0][0][1][0][RTW89_MKK][14] = 66, + [0][0][1][0][RTW89_IC][14] = 64, + [0][0][1][0][RTW89_KCC][14] = 66, + [0][0][1][0][RTW89_ACMA][14] = 66, + [0][0][1][0][RTW89_CN][14] = 50, + [0][0][1][0][RTW89_UK][14] = 66, + [0][0][1][0][RTW89_MEXICO][14] = 70, + [0][0][1][0][RTW89_UKRAINE][14] = 54, + [0][0][1][0][RTW89_CHILE][14] = 68, + [0][0][1][0][RTW89_QATAR][14] = 66, + [0][0][1][0][RTW89_THAILAND][14] = 66, + [0][0][1][0][RTW89_FCC][15] = 72, + [0][0][1][0][RTW89_ETSI][15] = 66, + [0][0][1][0][RTW89_MKK][15] = 70, + [0][0][1][0][RTW89_IC][15] = 72, + [0][0][1][0][RTW89_KCC][15] = 70, + [0][0][1][0][RTW89_ACMA][15] = 66, + [0][0][1][0][RTW89_CN][15] = 127, + [0][0][1][0][RTW89_UK][15] = 66, + [0][0][1][0][RTW89_MEXICO][15] = 72, + [0][0][1][0][RTW89_UKRAINE][15] = 54, + [0][0][1][0][RTW89_CHILE][15] = 70, + [0][0][1][0][RTW89_QATAR][15] = 66, + [0][0][1][0][RTW89_THAILAND][15] = 66, + [0][0][1][0][RTW89_FCC][17] = 72, + [0][0][1][0][RTW89_ETSI][17] = 66, + [0][0][1][0][RTW89_MKK][17] = 70, + [0][0][1][0][RTW89_IC][17] = 72, + [0][0][1][0][RTW89_KCC][17] = 70, + [0][0][1][0][RTW89_ACMA][17] = 66, + [0][0][1][0][RTW89_CN][17] = 127, + [0][0][1][0][RTW89_UK][17] = 66, + [0][0][1][0][RTW89_MEXICO][17] = 72, + [0][0][1][0][RTW89_UKRAINE][17] = 54, + [0][0][1][0][RTW89_CHILE][17] = 70, + [0][0][1][0][RTW89_QATAR][17] = 66, + [0][0][1][0][RTW89_THAILAND][17] = 66, + [0][0][1][0][RTW89_FCC][19] = 72, + [0][0][1][0][RTW89_ETSI][19] = 66, + [0][0][1][0][RTW89_MKK][19] = 70, + [0][0][1][0][RTW89_IC][19] = 72, + [0][0][1][0][RTW89_KCC][19] = 70, + [0][0][1][0][RTW89_ACMA][19] = 66, + [0][0][1][0][RTW89_CN][19] = 127, + [0][0][1][0][RTW89_UK][19] = 66, + [0][0][1][0][RTW89_MEXICO][19] = 72, + [0][0][1][0][RTW89_UKRAINE][19] = 54, + [0][0][1][0][RTW89_CHILE][19] = 70, + [0][0][1][0][RTW89_QATAR][19] = 66, + [0][0][1][0][RTW89_THAILAND][19] = 66, + [0][0][1][0][RTW89_FCC][21] = 72, + [0][0][1][0][RTW89_ETSI][21] = 66, + [0][0][1][0][RTW89_MKK][21] = 70, + [0][0][1][0][RTW89_IC][21] = 72, + [0][0][1][0][RTW89_KCC][21] = 70, + [0][0][1][0][RTW89_ACMA][21] = 66, + [0][0][1][0][RTW89_CN][21] = 127, + [0][0][1][0][RTW89_UK][21] = 66, + [0][0][1][0][RTW89_MEXICO][21] = 72, + [0][0][1][0][RTW89_UKRAINE][21] = 54, + [0][0][1][0][RTW89_CHILE][21] = 70, + [0][0][1][0][RTW89_QATAR][21] = 66, + [0][0][1][0][RTW89_THAILAND][21] = 66, + [0][0][1][0][RTW89_FCC][23] = 72, + [0][0][1][0][RTW89_ETSI][23] = 66, + [0][0][1][0][RTW89_MKK][23] = 70, + [0][0][1][0][RTW89_IC][23] = 72, + [0][0][1][0][RTW89_KCC][23] = 70, + [0][0][1][0][RTW89_ACMA][23] = 66, + [0][0][1][0][RTW89_CN][23] = 127, + [0][0][1][0][RTW89_UK][23] = 66, + [0][0][1][0][RTW89_MEXICO][23] = 72, + [0][0][1][0][RTW89_UKRAINE][23] = 54, + [0][0][1][0][RTW89_CHILE][23] = 70, + [0][0][1][0][RTW89_QATAR][23] = 66, + [0][0][1][0][RTW89_THAILAND][23] = 66, + [0][0][1][0][RTW89_FCC][25] = 72, + [0][0][1][0][RTW89_ETSI][25] = 66, + [0][0][1][0][RTW89_MKK][25] = 70, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_KCC][25] = 70, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_CN][25] = 127, + [0][0][1][0][RTW89_UK][25] = 66, + [0][0][1][0][RTW89_MEXICO][25] = 72, + [0][0][1][0][RTW89_UKRAINE][25] = 54, + [0][0][1][0][RTW89_CHILE][25] = 70, + [0][0][1][0][RTW89_QATAR][25] = 66, + [0][0][1][0][RTW89_THAILAND][25] = 66, + [0][0][1][0][RTW89_FCC][27] = 72, + [0][0][1][0][RTW89_ETSI][27] = 66, + [0][0][1][0][RTW89_MKK][27] = 70, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_KCC][27] = 70, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_CN][27] = 127, + [0][0][1][0][RTW89_UK][27] = 66, + [0][0][1][0][RTW89_MEXICO][27] = 72, + [0][0][1][0][RTW89_UKRAINE][27] = 54, + [0][0][1][0][RTW89_CHILE][27] = 58, + [0][0][1][0][RTW89_QATAR][27] = 66, + [0][0][1][0][RTW89_THAILAND][27] = 66, + [0][0][1][0][RTW89_FCC][29] = 72, + [0][0][1][0][RTW89_ETSI][29] = 66, + [0][0][1][0][RTW89_MKK][29] = 70, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_KCC][29] = 70, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_CN][29] = 127, + [0][0][1][0][RTW89_UK][29] = 66, + [0][0][1][0][RTW89_MEXICO][29] = 72, + [0][0][1][0][RTW89_UKRAINE][29] = 54, + [0][0][1][0][RTW89_CHILE][29] = 58, + [0][0][1][0][RTW89_QATAR][29] = 66, + [0][0][1][0][RTW89_THAILAND][29] = 66, + [0][0][1][0][RTW89_FCC][31] = 72, + [0][0][1][0][RTW89_ETSI][31] = 66, + [0][0][1][0][RTW89_MKK][31] = 70, + [0][0][1][0][RTW89_IC][31] = 72, + [0][0][1][0][RTW89_KCC][31] = 70, + [0][0][1][0][RTW89_ACMA][31] = 66, + [0][0][1][0][RTW89_CN][31] = 127, + [0][0][1][0][RTW89_UK][31] = 66, + [0][0][1][0][RTW89_MEXICO][31] = 72, + [0][0][1][0][RTW89_UKRAINE][31] = 54, + [0][0][1][0][RTW89_CHILE][31] = 58, + [0][0][1][0][RTW89_QATAR][31] = 66, + [0][0][1][0][RTW89_THAILAND][31] = 66, + [0][0][1][0][RTW89_FCC][33] = 72, + [0][0][1][0][RTW89_ETSI][33] = 66, + [0][0][1][0][RTW89_MKK][33] = 70, + [0][0][1][0][RTW89_IC][33] = 72, + [0][0][1][0][RTW89_KCC][33] = 70, + [0][0][1][0][RTW89_ACMA][33] = 66, + [0][0][1][0][RTW89_CN][33] = 127, + [0][0][1][0][RTW89_UK][33] = 66, + [0][0][1][0][RTW89_MEXICO][33] = 72, + [0][0][1][0][RTW89_UKRAINE][33] = 54, + [0][0][1][0][RTW89_CHILE][33] = 58, + [0][0][1][0][RTW89_QATAR][33] = 66, + [0][0][1][0][RTW89_THAILAND][33] = 66, + [0][0][1][0][RTW89_FCC][35] = 60, + [0][0][1][0][RTW89_ETSI][35] = 66, + [0][0][1][0][RTW89_MKK][35] = 70, + [0][0][1][0][RTW89_IC][35] = 60, + [0][0][1][0][RTW89_KCC][35] = 70, + [0][0][1][0][RTW89_ACMA][35] = 66, + [0][0][1][0][RTW89_CN][35] = 127, + [0][0][1][0][RTW89_UK][35] = 66, + [0][0][1][0][RTW89_MEXICO][35] = 60, + [0][0][1][0][RTW89_UKRAINE][35] = 54, + [0][0][1][0][RTW89_CHILE][35] = 58, + [0][0][1][0][RTW89_QATAR][35] = 66, + [0][0][1][0][RTW89_THAILAND][35] = 66, + [0][0][1][0][RTW89_FCC][37] = 72, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 70, + [0][0][1][0][RTW89_IC][37] = 72, + [0][0][1][0][RTW89_KCC][37] = 70, + [0][0][1][0][RTW89_ACMA][37] = 70, + [0][0][1][0][RTW89_CN][37] = 127, + [0][0][1][0][RTW89_UK][37] = 64, + [0][0][1][0][RTW89_MEXICO][37] = 72, + [0][0][1][0][RTW89_UKRAINE][37] = 127, + [0][0][1][0][RTW89_CHILE][37] = 70, + [0][0][1][0][RTW89_QATAR][37] = 127, + [0][0][1][0][RTW89_THAILAND][37] = 127, + [0][0][1][0][RTW89_FCC][38] = 72, + [0][0][1][0][RTW89_ETSI][38] = 30, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 72, + [0][0][1][0][RTW89_KCC][38] = 62, + [0][0][1][0][RTW89_ACMA][38] = 70, + [0][0][1][0][RTW89_CN][38] = 54, + [0][0][1][0][RTW89_UK][38] = 64, + [0][0][1][0][RTW89_MEXICO][38] = 72, + [0][0][1][0][RTW89_UKRAINE][38] = 30, + [0][0][1][0][RTW89_CHILE][38] = 70, + [0][0][1][0][RTW89_QATAR][38] = 30, + [0][0][1][0][RTW89_THAILAND][38] = 30, + [0][0][1][0][RTW89_FCC][40] = 72, + [0][0][1][0][RTW89_ETSI][40] = 30, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 72, + [0][0][1][0][RTW89_KCC][40] = 62, + [0][0][1][0][RTW89_ACMA][40] = 70, + [0][0][1][0][RTW89_CN][40] = 54, + [0][0][1][0][RTW89_UK][40] = 64, + [0][0][1][0][RTW89_MEXICO][40] = 72, + [0][0][1][0][RTW89_UKRAINE][40] = 30, + [0][0][1][0][RTW89_CHILE][40] = 70, + [0][0][1][0][RTW89_QATAR][40] = 30, + [0][0][1][0][RTW89_THAILAND][40] = 30, + [0][0][1][0][RTW89_FCC][42] = 72, + [0][0][1][0][RTW89_ETSI][42] = 30, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 72, + [0][0][1][0][RTW89_KCC][42] = 62, + [0][0][1][0][RTW89_ACMA][42] = 70, + [0][0][1][0][RTW89_CN][42] = 54, + [0][0][1][0][RTW89_UK][42] = 64, + [0][0][1][0][RTW89_MEXICO][42] = 72, + [0][0][1][0][RTW89_UKRAINE][42] = 30, + [0][0][1][0][RTW89_CHILE][42] = 70, + [0][0][1][0][RTW89_QATAR][42] = 30, + [0][0][1][0][RTW89_THAILAND][42] = 30, + [0][0][1][0][RTW89_FCC][44] = 72, + [0][0][1][0][RTW89_ETSI][44] = 30, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 72, + [0][0][1][0][RTW89_KCC][44] = 62, + [0][0][1][0][RTW89_ACMA][44] = 70, + [0][0][1][0][RTW89_CN][44] = 54, + [0][0][1][0][RTW89_UK][44] = 64, + [0][0][1][0][RTW89_MEXICO][44] = 72, + [0][0][1][0][RTW89_UKRAINE][44] = 30, + [0][0][1][0][RTW89_CHILE][44] = 70, + [0][0][1][0][RTW89_QATAR][44] = 30, + [0][0][1][0][RTW89_THAILAND][44] = 30, + [0][0][1][0][RTW89_FCC][46] = 72, + [0][0][1][0][RTW89_ETSI][46] = 30, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 72, + [0][0][1][0][RTW89_KCC][46] = 62, + [0][0][1][0][RTW89_ACMA][46] = 70, + [0][0][1][0][RTW89_CN][46] = 54, + [0][0][1][0][RTW89_UK][46] = 64, + [0][0][1][0][RTW89_MEXICO][46] = 72, + [0][0][1][0][RTW89_UKRAINE][46] = 30, + [0][0][1][0][RTW89_CHILE][46] = 70, + [0][0][1][0][RTW89_QATAR][46] = 30, + [0][0][1][0][RTW89_THAILAND][46] = 30, + [0][0][1][0][RTW89_FCC][48] = 72, + [0][0][1][0][RTW89_ETSI][48] = 127, + [0][0][1][0][RTW89_MKK][48] = 127, + [0][0][1][0][RTW89_IC][48] = 72, + [0][0][1][0][RTW89_KCC][48] = 127, + [0][0][1][0][RTW89_ACMA][48] = 127, + [0][0][1][0][RTW89_CN][48] = 127, + [0][0][1][0][RTW89_UK][48] = 127, + [0][0][1][0][RTW89_MEXICO][48] = 127, + [0][0][1][0][RTW89_UKRAINE][48] = 127, + [0][0][1][0][RTW89_CHILE][48] = 127, + [0][0][1][0][RTW89_QATAR][48] = 127, + [0][0][1][0][RTW89_THAILAND][48] = 127, + [0][0][1][0][RTW89_FCC][50] = 72, + [0][0][1][0][RTW89_ETSI][50] = 127, + [0][0][1][0][RTW89_MKK][50] = 127, + [0][0][1][0][RTW89_IC][50] = 72, + [0][0][1][0][RTW89_KCC][50] = 127, + [0][0][1][0][RTW89_ACMA][50] = 127, + [0][0][1][0][RTW89_CN][50] = 127, + [0][0][1][0][RTW89_UK][50] = 127, + [0][0][1][0][RTW89_MEXICO][50] = 127, + [0][0][1][0][RTW89_UKRAINE][50] = 127, + [0][0][1][0][RTW89_CHILE][50] = 127, + [0][0][1][0][RTW89_QATAR][50] = 127, + [0][0][1][0][RTW89_THAILAND][50] = 127, + [0][0][1][0][RTW89_FCC][52] = 72, + [0][0][1][0][RTW89_ETSI][52] = 127, + [0][0][1][0][RTW89_MKK][52] = 127, + [0][0][1][0][RTW89_IC][52] = 72, + [0][0][1][0][RTW89_KCC][52] = 127, + [0][0][1][0][RTW89_ACMA][52] = 127, + [0][0][1][0][RTW89_CN][52] = 127, + [0][0][1][0][RTW89_UK][52] = 127, + [0][0][1][0][RTW89_MEXICO][52] = 127, + [0][0][1][0][RTW89_UKRAINE][52] = 127, + [0][0][1][0][RTW89_CHILE][52] = 127, + [0][0][1][0][RTW89_QATAR][52] = 127, + [0][0][1][0][RTW89_THAILAND][52] = 127, + [0][1][1][0][RTW89_FCC][0] = 60, + [0][1][1][0][RTW89_ETSI][0] = 54, + [0][1][1][0][RTW89_MKK][0] = 54, + [0][1][1][0][RTW89_IC][0] = 34, + [0][1][1][0][RTW89_KCC][0] = 60, + [0][1][1][0][RTW89_ACMA][0] = 54, + [0][1][1][0][RTW89_CN][0] = 46, + [0][1][1][0][RTW89_UK][0] = 54, + [0][1][1][0][RTW89_MEXICO][0] = 50, + [0][1][1][0][RTW89_UKRAINE][0] = 42, + [0][1][1][0][RTW89_CHILE][0] = 60, + [0][1][1][0][RTW89_QATAR][0] = 54, + [0][1][1][0][RTW89_THAILAND][0] = 54, + [0][1][1][0][RTW89_FCC][2] = 60, + [0][1][1][0][RTW89_ETSI][2] = 54, + [0][1][1][0][RTW89_MKK][2] = 54, + [0][1][1][0][RTW89_IC][2] = 34, + [0][1][1][0][RTW89_KCC][2] = 60, + [0][1][1][0][RTW89_ACMA][2] = 54, + [0][1][1][0][RTW89_CN][2] = 46, + [0][1][1][0][RTW89_UK][2] = 54, + [0][1][1][0][RTW89_MEXICO][2] = 50, + [0][1][1][0][RTW89_UKRAINE][2] = 42, + [0][1][1][0][RTW89_CHILE][2] = 60, + [0][1][1][0][RTW89_QATAR][2] = 54, + [0][1][1][0][RTW89_THAILAND][2] = 54, + [0][1][1][0][RTW89_FCC][4] = 60, + [0][1][1][0][RTW89_ETSI][4] = 54, + [0][1][1][0][RTW89_MKK][4] = 54, + [0][1][1][0][RTW89_IC][4] = 34, + [0][1][1][0][RTW89_KCC][4] = 60, + [0][1][1][0][RTW89_ACMA][4] = 54, + [0][1][1][0][RTW89_CN][4] = 46, + [0][1][1][0][RTW89_UK][4] = 54, + [0][1][1][0][RTW89_MEXICO][4] = 50, + [0][1][1][0][RTW89_UKRAINE][4] = 42, + [0][1][1][0][RTW89_CHILE][4] = 60, + [0][1][1][0][RTW89_QATAR][4] = 54, + [0][1][1][0][RTW89_THAILAND][4] = 54, + [0][1][1][0][RTW89_FCC][6] = 60, + [0][1][1][0][RTW89_ETSI][6] = 54, + [0][1][1][0][RTW89_MKK][6] = 54, + [0][1][1][0][RTW89_IC][6] = 36, + [0][1][1][0][RTW89_KCC][6] = 40, + [0][1][1][0][RTW89_ACMA][6] = 54, + [0][1][1][0][RTW89_CN][6] = 46, + [0][1][1][0][RTW89_UK][6] = 54, + [0][1][1][0][RTW89_MEXICO][6] = 50, + [0][1][1][0][RTW89_UKRAINE][6] = 42, + [0][1][1][0][RTW89_CHILE][6] = 60, + [0][1][1][0][RTW89_QATAR][6] = 54, + [0][1][1][0][RTW89_THAILAND][6] = 54, + [0][1][1][0][RTW89_FCC][8] = 62, + [0][1][1][0][RTW89_ETSI][8] = 54, + [0][1][1][0][RTW89_MKK][8] = 52, + [0][1][1][0][RTW89_IC][8] = 52, + [0][1][1][0][RTW89_KCC][8] = 60, + [0][1][1][0][RTW89_ACMA][8] = 54, + [0][1][1][0][RTW89_CN][8] = 46, + [0][1][1][0][RTW89_UK][8] = 54, + [0][1][1][0][RTW89_MEXICO][8] = 62, + [0][1][1][0][RTW89_UKRAINE][8] = 42, + [0][1][1][0][RTW89_CHILE][8] = 62, + [0][1][1][0][RTW89_QATAR][8] = 54, + [0][1][1][0][RTW89_THAILAND][8] = 54, + [0][1][1][0][RTW89_FCC][10] = 62, + [0][1][1][0][RTW89_ETSI][10] = 54, + [0][1][1][0][RTW89_MKK][10] = 54, + [0][1][1][0][RTW89_IC][10] = 52, + [0][1][1][0][RTW89_KCC][10] = 60, + [0][1][1][0][RTW89_ACMA][10] = 54, + [0][1][1][0][RTW89_CN][10] = 46, + [0][1][1][0][RTW89_UK][10] = 54, + [0][1][1][0][RTW89_MEXICO][10] = 62, + [0][1][1][0][RTW89_UKRAINE][10] = 42, + [0][1][1][0][RTW89_CHILE][10] = 62, + [0][1][1][0][RTW89_QATAR][10] = 54, + [0][1][1][0][RTW89_THAILAND][10] = 54, + [0][1][1][0][RTW89_FCC][12] = 62, + [0][1][1][0][RTW89_ETSI][12] = 54, + [0][1][1][0][RTW89_MKK][12] = 54, + [0][1][1][0][RTW89_IC][12] = 52, + [0][1][1][0][RTW89_KCC][12] = 60, + [0][1][1][0][RTW89_ACMA][12] = 54, + [0][1][1][0][RTW89_CN][12] = 46, + [0][1][1][0][RTW89_UK][12] = 54, + [0][1][1][0][RTW89_MEXICO][12] = 62, + [0][1][1][0][RTW89_UKRAINE][12] = 42, + [0][1][1][0][RTW89_CHILE][12] = 62, + [0][1][1][0][RTW89_QATAR][12] = 54, + [0][1][1][0][RTW89_THAILAND][12] = 54, + [0][1][1][0][RTW89_FCC][14] = 60, + [0][1][1][0][RTW89_ETSI][14] = 54, + [0][1][1][0][RTW89_MKK][14] = 54, + [0][1][1][0][RTW89_IC][14] = 52, + [0][1][1][0][RTW89_KCC][14] = 60, + [0][1][1][0][RTW89_ACMA][14] = 54, + [0][1][1][0][RTW89_CN][14] = 46, + [0][1][1][0][RTW89_UK][14] = 54, + [0][1][1][0][RTW89_MEXICO][14] = 60, + [0][1][1][0][RTW89_UKRAINE][14] = 42, + [0][1][1][0][RTW89_CHILE][14] = 60, + [0][1][1][0][RTW89_QATAR][14] = 54, + [0][1][1][0][RTW89_THAILAND][14] = 54, + [0][1][1][0][RTW89_FCC][15] = 60, + [0][1][1][0][RTW89_ETSI][15] = 54, + [0][1][1][0][RTW89_MKK][15] = 70, + [0][1][1][0][RTW89_IC][15] = 60, + [0][1][1][0][RTW89_KCC][15] = 60, + [0][1][1][0][RTW89_ACMA][15] = 54, + [0][1][1][0][RTW89_CN][15] = 127, + [0][1][1][0][RTW89_UK][15] = 54, + [0][1][1][0][RTW89_MEXICO][15] = 60, + [0][1][1][0][RTW89_UKRAINE][15] = 42, + [0][1][1][0][RTW89_CHILE][15] = 60, + [0][1][1][0][RTW89_QATAR][15] = 54, + [0][1][1][0][RTW89_THAILAND][15] = 54, + [0][1][1][0][RTW89_FCC][17] = 60, + [0][1][1][0][RTW89_ETSI][17] = 54, + [0][1][1][0][RTW89_MKK][17] = 70, + [0][1][1][0][RTW89_IC][17] = 60, + [0][1][1][0][RTW89_KCC][17] = 60, + [0][1][1][0][RTW89_ACMA][17] = 54, + [0][1][1][0][RTW89_CN][17] = 127, + [0][1][1][0][RTW89_UK][17] = 54, + [0][1][1][0][RTW89_MEXICO][17] = 60, + [0][1][1][0][RTW89_UKRAINE][17] = 42, + [0][1][1][0][RTW89_CHILE][17] = 60, + [0][1][1][0][RTW89_QATAR][17] = 54, + [0][1][1][0][RTW89_THAILAND][17] = 54, + [0][1][1][0][RTW89_FCC][19] = 60, + [0][1][1][0][RTW89_ETSI][19] = 54, + [0][1][1][0][RTW89_MKK][19] = 70, + [0][1][1][0][RTW89_IC][19] = 60, + [0][1][1][0][RTW89_KCC][19] = 60, + [0][1][1][0][RTW89_ACMA][19] = 54, + [0][1][1][0][RTW89_CN][19] = 127, + [0][1][1][0][RTW89_UK][19] = 54, + [0][1][1][0][RTW89_MEXICO][19] = 60, + [0][1][1][0][RTW89_UKRAINE][19] = 42, + [0][1][1][0][RTW89_CHILE][19] = 60, + [0][1][1][0][RTW89_QATAR][19] = 54, + [0][1][1][0][RTW89_THAILAND][19] = 54, + [0][1][1][0][RTW89_FCC][21] = 60, + [0][1][1][0][RTW89_ETSI][21] = 54, + [0][1][1][0][RTW89_MKK][21] = 70, + [0][1][1][0][RTW89_IC][21] = 60, + [0][1][1][0][RTW89_KCC][21] = 60, + [0][1][1][0][RTW89_ACMA][21] = 54, + [0][1][1][0][RTW89_CN][21] = 127, + [0][1][1][0][RTW89_UK][21] = 54, + [0][1][1][0][RTW89_MEXICO][21] = 60, + [0][1][1][0][RTW89_UKRAINE][21] = 42, + [0][1][1][0][RTW89_CHILE][21] = 60, + [0][1][1][0][RTW89_QATAR][21] = 54, + [0][1][1][0][RTW89_THAILAND][21] = 54, + [0][1][1][0][RTW89_FCC][23] = 60, + [0][1][1][0][RTW89_ETSI][23] = 54, + [0][1][1][0][RTW89_MKK][23] = 70, + [0][1][1][0][RTW89_IC][23] = 60, + [0][1][1][0][RTW89_KCC][23] = 60, + [0][1][1][0][RTW89_ACMA][23] = 54, + [0][1][1][0][RTW89_CN][23] = 127, + [0][1][1][0][RTW89_UK][23] = 54, + [0][1][1][0][RTW89_MEXICO][23] = 60, + [0][1][1][0][RTW89_UKRAINE][23] = 42, + [0][1][1][0][RTW89_CHILE][23] = 60, + [0][1][1][0][RTW89_QATAR][23] = 54, + [0][1][1][0][RTW89_THAILAND][23] = 54, + [0][1][1][0][RTW89_FCC][25] = 60, + [0][1][1][0][RTW89_ETSI][25] = 54, + [0][1][1][0][RTW89_MKK][25] = 70, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_KCC][25] = 60, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_CN][25] = 127, + [0][1][1][0][RTW89_UK][25] = 54, + [0][1][1][0][RTW89_MEXICO][25] = 60, + [0][1][1][0][RTW89_UKRAINE][25] = 42, + [0][1][1][0][RTW89_CHILE][25] = 60, + [0][1][1][0][RTW89_QATAR][25] = 54, + [0][1][1][0][RTW89_THAILAND][25] = 54, + [0][1][1][0][RTW89_FCC][27] = 60, + [0][1][1][0][RTW89_ETSI][27] = 54, + [0][1][1][0][RTW89_MKK][27] = 70, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_KCC][27] = 60, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_CN][27] = 127, + [0][1][1][0][RTW89_UK][27] = 54, + [0][1][1][0][RTW89_MEXICO][27] = 60, + [0][1][1][0][RTW89_UKRAINE][27] = 42, + [0][1][1][0][RTW89_CHILE][27] = 52, + [0][1][1][0][RTW89_QATAR][27] = 54, + [0][1][1][0][RTW89_THAILAND][27] = 54, + [0][1][1][0][RTW89_FCC][29] = 60, + [0][1][1][0][RTW89_ETSI][29] = 54, + [0][1][1][0][RTW89_MKK][29] = 70, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_KCC][29] = 60, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_CN][29] = 127, + [0][1][1][0][RTW89_UK][29] = 54, + [0][1][1][0][RTW89_MEXICO][29] = 60, + [0][1][1][0][RTW89_UKRAINE][29] = 42, + [0][1][1][0][RTW89_CHILE][29] = 52, + [0][1][1][0][RTW89_QATAR][29] = 54, + [0][1][1][0][RTW89_THAILAND][29] = 54, + [0][1][1][0][RTW89_FCC][31] = 60, + [0][1][1][0][RTW89_ETSI][31] = 54, + [0][1][1][0][RTW89_MKK][31] = 70, + [0][1][1][0][RTW89_IC][31] = 60, + [0][1][1][0][RTW89_KCC][31] = 58, + [0][1][1][0][RTW89_ACMA][31] = 54, + [0][1][1][0][RTW89_CN][31] = 127, + [0][1][1][0][RTW89_UK][31] = 54, + [0][1][1][0][RTW89_MEXICO][31] = 60, + [0][1][1][0][RTW89_UKRAINE][31] = 42, + [0][1][1][0][RTW89_CHILE][31] = 52, + [0][1][1][0][RTW89_QATAR][31] = 54, + [0][1][1][0][RTW89_THAILAND][31] = 54, + [0][1][1][0][RTW89_FCC][33] = 60, + [0][1][1][0][RTW89_ETSI][33] = 54, + [0][1][1][0][RTW89_MKK][33] = 70, + [0][1][1][0][RTW89_IC][33] = 60, + [0][1][1][0][RTW89_KCC][33] = 58, + [0][1][1][0][RTW89_ACMA][33] = 54, + [0][1][1][0][RTW89_CN][33] = 127, + [0][1][1][0][RTW89_UK][33] = 54, + [0][1][1][0][RTW89_MEXICO][33] = 60, + [0][1][1][0][RTW89_UKRAINE][33] = 42, + [0][1][1][0][RTW89_CHILE][33] = 52, + [0][1][1][0][RTW89_QATAR][33] = 54, + [0][1][1][0][RTW89_THAILAND][33] = 54, + [0][1][1][0][RTW89_FCC][35] = 52, + [0][1][1][0][RTW89_ETSI][35] = 54, + [0][1][1][0][RTW89_MKK][35] = 70, + [0][1][1][0][RTW89_IC][35] = 52, + [0][1][1][0][RTW89_KCC][35] = 58, + [0][1][1][0][RTW89_ACMA][35] = 54, + [0][1][1][0][RTW89_CN][35] = 127, + [0][1][1][0][RTW89_UK][35] = 54, + [0][1][1][0][RTW89_MEXICO][35] = 52, + [0][1][1][0][RTW89_UKRAINE][35] = 42, + [0][1][1][0][RTW89_CHILE][35] = 52, + [0][1][1][0][RTW89_QATAR][35] = 54, + [0][1][1][0][RTW89_THAILAND][35] = 54, + [0][1][1][0][RTW89_FCC][37] = 62, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 70, + [0][1][1][0][RTW89_IC][37] = 62, + [0][1][1][0][RTW89_KCC][37] = 58, + [0][1][1][0][RTW89_ACMA][37] = 64, + [0][1][1][0][RTW89_CN][37] = 127, + [0][1][1][0][RTW89_UK][37] = 52, + [0][1][1][0][RTW89_MEXICO][37] = 62, + [0][1][1][0][RTW89_UKRAINE][37] = 127, + [0][1][1][0][RTW89_CHILE][37] = 62, + [0][1][1][0][RTW89_QATAR][37] = 127, + [0][1][1][0][RTW89_THAILAND][37] = 127, + [0][1][1][0][RTW89_FCC][38] = 72, + [0][1][1][0][RTW89_ETSI][38] = 18, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 72, + [0][1][1][0][RTW89_KCC][38] = 60, + [0][1][1][0][RTW89_ACMA][38] = 70, + [0][1][1][0][RTW89_CN][38] = 54, + [0][1][1][0][RTW89_UK][38] = 52, + [0][1][1][0][RTW89_MEXICO][38] = 72, + [0][1][1][0][RTW89_UKRAINE][38] = 18, + [0][1][1][0][RTW89_CHILE][38] = 70, + [0][1][1][0][RTW89_QATAR][38] = 18, + [0][1][1][0][RTW89_THAILAND][38] = 18, + [0][1][1][0][RTW89_FCC][40] = 72, + [0][1][1][0][RTW89_ETSI][40] = 18, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 72, + [0][1][1][0][RTW89_KCC][40] = 60, + [0][1][1][0][RTW89_ACMA][40] = 70, + [0][1][1][0][RTW89_CN][40] = 54, + [0][1][1][0][RTW89_UK][40] = 52, + [0][1][1][0][RTW89_MEXICO][40] = 72, + [0][1][1][0][RTW89_UKRAINE][40] = 18, + [0][1][1][0][RTW89_CHILE][40] = 70, + [0][1][1][0][RTW89_QATAR][40] = 18, + [0][1][1][0][RTW89_THAILAND][40] = 18, + [0][1][1][0][RTW89_FCC][42] = 72, + [0][1][1][0][RTW89_ETSI][42] = 18, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 72, + [0][1][1][0][RTW89_KCC][42] = 60, + [0][1][1][0][RTW89_ACMA][42] = 70, + [0][1][1][0][RTW89_CN][42] = 54, + [0][1][1][0][RTW89_UK][42] = 52, + [0][1][1][0][RTW89_MEXICO][42] = 72, + [0][1][1][0][RTW89_UKRAINE][42] = 18, + [0][1][1][0][RTW89_CHILE][42] = 70, + [0][1][1][0][RTW89_QATAR][42] = 18, + [0][1][1][0][RTW89_THAILAND][42] = 18, + [0][1][1][0][RTW89_FCC][44] = 72, + [0][1][1][0][RTW89_ETSI][44] = 18, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 72, + [0][1][1][0][RTW89_KCC][44] = 60, + [0][1][1][0][RTW89_ACMA][44] = 70, + [0][1][1][0][RTW89_CN][44] = 54, + [0][1][1][0][RTW89_UK][44] = 52, + [0][1][1][0][RTW89_MEXICO][44] = 72, + [0][1][1][0][RTW89_UKRAINE][44] = 18, + [0][1][1][0][RTW89_CHILE][44] = 70, + [0][1][1][0][RTW89_QATAR][44] = 18, + [0][1][1][0][RTW89_THAILAND][44] = 18, + [0][1][1][0][RTW89_FCC][46] = 72, + [0][1][1][0][RTW89_ETSI][46] = 18, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 72, + [0][1][1][0][RTW89_KCC][46] = 60, + [0][1][1][0][RTW89_ACMA][46] = 70, + [0][1][1][0][RTW89_CN][46] = 54, + [0][1][1][0][RTW89_UK][46] = 52, + [0][1][1][0][RTW89_MEXICO][46] = 72, + [0][1][1][0][RTW89_UKRAINE][46] = 18, + [0][1][1][0][RTW89_CHILE][46] = 70, + [0][1][1][0][RTW89_QATAR][46] = 18, + [0][1][1][0][RTW89_THAILAND][46] = 18, + [0][1][1][0][RTW89_FCC][48] = 48, + [0][1][1][0][RTW89_ETSI][48] = 127, + [0][1][1][0][RTW89_MKK][48] = 127, + [0][1][1][0][RTW89_IC][48] = 48, + [0][1][1][0][RTW89_KCC][48] = 127, + [0][1][1][0][RTW89_ACMA][48] = 127, + [0][1][1][0][RTW89_CN][48] = 127, + [0][1][1][0][RTW89_UK][48] = 127, + [0][1][1][0][RTW89_MEXICO][48] = 127, + [0][1][1][0][RTW89_UKRAINE][48] = 127, + [0][1][1][0][RTW89_CHILE][48] = 127, + [0][1][1][0][RTW89_QATAR][48] = 127, + [0][1][1][0][RTW89_THAILAND][48] = 127, + [0][1][1][0][RTW89_FCC][50] = 48, + [0][1][1][0][RTW89_ETSI][50] = 127, + [0][1][1][0][RTW89_MKK][50] = 127, + [0][1][1][0][RTW89_IC][50] = 48, + [0][1][1][0][RTW89_KCC][50] = 127, + [0][1][1][0][RTW89_ACMA][50] = 127, + [0][1][1][0][RTW89_CN][50] = 127, + [0][1][1][0][RTW89_UK][50] = 127, + [0][1][1][0][RTW89_MEXICO][50] = 127, + [0][1][1][0][RTW89_UKRAINE][50] = 127, + [0][1][1][0][RTW89_CHILE][50] = 127, + [0][1][1][0][RTW89_QATAR][50] = 127, + [0][1][1][0][RTW89_THAILAND][50] = 127, + [0][1][1][0][RTW89_FCC][52] = 48, + [0][1][1][0][RTW89_ETSI][52] = 127, + [0][1][1][0][RTW89_MKK][52] = 127, + [0][1][1][0][RTW89_IC][52] = 48, + [0][1][1][0][RTW89_KCC][52] = 127, + [0][1][1][0][RTW89_ACMA][52] = 127, + [0][1][1][0][RTW89_CN][52] = 127, + [0][1][1][0][RTW89_UK][52] = 127, + [0][1][1][0][RTW89_MEXICO][52] = 127, + [0][1][1][0][RTW89_UKRAINE][52] = 127, + [0][1][1][0][RTW89_CHILE][52] = 127, + [0][1][1][0][RTW89_QATAR][52] = 127, + [0][1][1][0][RTW89_THAILAND][52] = 127, + [0][0][2][0][RTW89_FCC][0] = 70, + [0][0][2][0][RTW89_ETSI][0] = 66, + [0][0][2][0][RTW89_MKK][0] = 68, + [0][0][2][0][RTW89_IC][0] = 60, + [0][0][2][0][RTW89_KCC][0] = 68, + [0][0][2][0][RTW89_ACMA][0] = 66, + [0][0][2][0][RTW89_CN][0] = 52, + [0][0][2][0][RTW89_UK][0] = 66, + [0][0][2][0][RTW89_MEXICO][0] = 62, + [0][0][2][0][RTW89_UKRAINE][0] = 54, + [0][0][2][0][RTW89_CHILE][0] = 68, + [0][0][2][0][RTW89_QATAR][0] = 66, + [0][0][2][0][RTW89_THAILAND][0] = 66, + [0][0][2][0][RTW89_FCC][2] = 72, + [0][0][2][0][RTW89_ETSI][2] = 66, + [0][0][2][0][RTW89_MKK][2] = 68, + [0][0][2][0][RTW89_IC][2] = 60, + [0][0][2][0][RTW89_KCC][2] = 68, + [0][0][2][0][RTW89_ACMA][2] = 66, + [0][0][2][0][RTW89_CN][2] = 52, + [0][0][2][0][RTW89_UK][2] = 66, + [0][0][2][0][RTW89_MEXICO][2] = 62, + [0][0][2][0][RTW89_UKRAINE][2] = 54, + [0][0][2][0][RTW89_CHILE][2] = 70, + [0][0][2][0][RTW89_QATAR][2] = 66, + [0][0][2][0][RTW89_THAILAND][2] = 66, + [0][0][2][0][RTW89_FCC][4] = 72, + [0][0][2][0][RTW89_ETSI][4] = 66, + [0][0][2][0][RTW89_MKK][4] = 68, + [0][0][2][0][RTW89_IC][4] = 60, + [0][0][2][0][RTW89_KCC][4] = 68, + [0][0][2][0][RTW89_ACMA][4] = 66, + [0][0][2][0][RTW89_CN][4] = 52, + [0][0][2][0][RTW89_UK][4] = 66, + [0][0][2][0][RTW89_MEXICO][4] = 62, + [0][0][2][0][RTW89_UKRAINE][4] = 54, + [0][0][2][0][RTW89_CHILE][4] = 70, + [0][0][2][0][RTW89_QATAR][4] = 66, + [0][0][2][0][RTW89_THAILAND][4] = 66, + [0][0][2][0][RTW89_FCC][6] = 72, + [0][0][2][0][RTW89_ETSI][6] = 66, + [0][0][2][0][RTW89_MKK][6] = 60, + [0][0][2][0][RTW89_IC][6] = 60, + [0][0][2][0][RTW89_KCC][6] = 54, + [0][0][2][0][RTW89_ACMA][6] = 66, + [0][0][2][0][RTW89_CN][6] = 52, + [0][0][2][0][RTW89_UK][6] = 66, + [0][0][2][0][RTW89_MEXICO][6] = 62, + [0][0][2][0][RTW89_UKRAINE][6] = 54, + [0][0][2][0][RTW89_CHILE][6] = 70, + [0][0][2][0][RTW89_QATAR][6] = 66, + [0][0][2][0][RTW89_THAILAND][6] = 66, + [0][0][2][0][RTW89_FCC][8] = 72, + [0][0][2][0][RTW89_ETSI][8] = 66, + [0][0][2][0][RTW89_MKK][8] = 58, + [0][0][2][0][RTW89_IC][8] = 64, + [0][0][2][0][RTW89_KCC][8] = 70, + [0][0][2][0][RTW89_ACMA][8] = 66, + [0][0][2][0][RTW89_CN][8] = 52, + [0][0][2][0][RTW89_UK][8] = 66, + [0][0][2][0][RTW89_MEXICO][8] = 72, + [0][0][2][0][RTW89_UKRAINE][8] = 54, + [0][0][2][0][RTW89_CHILE][8] = 70, + [0][0][2][0][RTW89_QATAR][8] = 66, + [0][0][2][0][RTW89_THAILAND][8] = 66, + [0][0][2][0][RTW89_FCC][10] = 72, + [0][0][2][0][RTW89_ETSI][10] = 66, + [0][0][2][0][RTW89_MKK][10] = 70, + [0][0][2][0][RTW89_IC][10] = 64, + [0][0][2][0][RTW89_KCC][10] = 70, + [0][0][2][0][RTW89_ACMA][10] = 66, + [0][0][2][0][RTW89_CN][10] = 52, + [0][0][2][0][RTW89_UK][10] = 66, + [0][0][2][0][RTW89_MEXICO][10] = 72, + [0][0][2][0][RTW89_UKRAINE][10] = 54, + [0][0][2][0][RTW89_CHILE][10] = 70, + [0][0][2][0][RTW89_QATAR][10] = 66, + [0][0][2][0][RTW89_THAILAND][10] = 66, + [0][0][2][0][RTW89_FCC][12] = 72, + [0][0][2][0][RTW89_ETSI][12] = 66, + [0][0][2][0][RTW89_MKK][12] = 70, + [0][0][2][0][RTW89_IC][12] = 64, + [0][0][2][0][RTW89_KCC][12] = 66, + [0][0][2][0][RTW89_ACMA][12] = 66, + [0][0][2][0][RTW89_CN][12] = 52, + [0][0][2][0][RTW89_UK][12] = 66, + [0][0][2][0][RTW89_MEXICO][12] = 72, + [0][0][2][0][RTW89_UKRAINE][12] = 54, + [0][0][2][0][RTW89_CHILE][12] = 70, + [0][0][2][0][RTW89_QATAR][12] = 66, + [0][0][2][0][RTW89_THAILAND][12] = 66, + [0][0][2][0][RTW89_FCC][14] = 68, + [0][0][2][0][RTW89_ETSI][14] = 66, + [0][0][2][0][RTW89_MKK][14] = 70, + [0][0][2][0][RTW89_IC][14] = 64, + [0][0][2][0][RTW89_KCC][14] = 66, + [0][0][2][0][RTW89_ACMA][14] = 66, + [0][0][2][0][RTW89_CN][14] = 52, + [0][0][2][0][RTW89_UK][14] = 66, + [0][0][2][0][RTW89_MEXICO][14] = 68, + [0][0][2][0][RTW89_UKRAINE][14] = 54, + [0][0][2][0][RTW89_CHILE][14] = 66, + [0][0][2][0][RTW89_QATAR][14] = 66, + [0][0][2][0][RTW89_THAILAND][14] = 66, + [0][0][2][0][RTW89_FCC][15] = 70, + [0][0][2][0][RTW89_ETSI][15] = 66, + [0][0][2][0][RTW89_MKK][15] = 70, + [0][0][2][0][RTW89_IC][15] = 70, + [0][0][2][0][RTW89_KCC][15] = 70, + [0][0][2][0][RTW89_ACMA][15] = 66, + [0][0][2][0][RTW89_CN][15] = 127, + [0][0][2][0][RTW89_UK][15] = 66, + [0][0][2][0][RTW89_MEXICO][15] = 70, + [0][0][2][0][RTW89_UKRAINE][15] = 54, + [0][0][2][0][RTW89_CHILE][15] = 68, + [0][0][2][0][RTW89_QATAR][15] = 66, + [0][0][2][0][RTW89_THAILAND][15] = 66, + [0][0][2][0][RTW89_FCC][17] = 72, + [0][0][2][0][RTW89_ETSI][17] = 66, + [0][0][2][0][RTW89_MKK][17] = 70, + [0][0][2][0][RTW89_IC][17] = 72, + [0][0][2][0][RTW89_KCC][17] = 70, + [0][0][2][0][RTW89_ACMA][17] = 66, + [0][0][2][0][RTW89_CN][17] = 127, + [0][0][2][0][RTW89_UK][17] = 66, + [0][0][2][0][RTW89_MEXICO][17] = 72, + [0][0][2][0][RTW89_UKRAINE][17] = 54, + [0][0][2][0][RTW89_CHILE][17] = 68, + [0][0][2][0][RTW89_QATAR][17] = 66, + [0][0][2][0][RTW89_THAILAND][17] = 66, + [0][0][2][0][RTW89_FCC][19] = 72, + [0][0][2][0][RTW89_ETSI][19] = 66, + [0][0][2][0][RTW89_MKK][19] = 70, + [0][0][2][0][RTW89_IC][19] = 72, + [0][0][2][0][RTW89_KCC][19] = 70, + [0][0][2][0][RTW89_ACMA][19] = 66, + [0][0][2][0][RTW89_CN][19] = 127, + [0][0][2][0][RTW89_UK][19] = 66, + [0][0][2][0][RTW89_MEXICO][19] = 72, + [0][0][2][0][RTW89_UKRAINE][19] = 54, + [0][0][2][0][RTW89_CHILE][19] = 68, + [0][0][2][0][RTW89_QATAR][19] = 66, + [0][0][2][0][RTW89_THAILAND][19] = 66, + [0][0][2][0][RTW89_FCC][21] = 72, + [0][0][2][0][RTW89_ETSI][21] = 66, + [0][0][2][0][RTW89_MKK][21] = 70, + [0][0][2][0][RTW89_IC][21] = 72, + [0][0][2][0][RTW89_KCC][21] = 70, + [0][0][2][0][RTW89_ACMA][21] = 66, + [0][0][2][0][RTW89_CN][21] = 127, + [0][0][2][0][RTW89_UK][21] = 66, + [0][0][2][0][RTW89_MEXICO][21] = 72, + [0][0][2][0][RTW89_UKRAINE][21] = 54, + [0][0][2][0][RTW89_CHILE][21] = 70, + [0][0][2][0][RTW89_QATAR][21] = 66, + [0][0][2][0][RTW89_THAILAND][21] = 66, + [0][0][2][0][RTW89_FCC][23] = 72, + [0][0][2][0][RTW89_ETSI][23] = 66, + [0][0][2][0][RTW89_MKK][23] = 70, + [0][0][2][0][RTW89_IC][23] = 72, + [0][0][2][0][RTW89_KCC][23] = 70, + [0][0][2][0][RTW89_ACMA][23] = 66, + [0][0][2][0][RTW89_CN][23] = 127, + [0][0][2][0][RTW89_UK][23] = 66, + [0][0][2][0][RTW89_MEXICO][23] = 72, + [0][0][2][0][RTW89_UKRAINE][23] = 54, + [0][0][2][0][RTW89_CHILE][23] = 70, + [0][0][2][0][RTW89_QATAR][23] = 66, + [0][0][2][0][RTW89_THAILAND][23] = 66, + [0][0][2][0][RTW89_FCC][25] = 72, + [0][0][2][0][RTW89_ETSI][25] = 66, + [0][0][2][0][RTW89_MKK][25] = 70, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_KCC][25] = 70, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_CN][25] = 127, + [0][0][2][0][RTW89_UK][25] = 66, + [0][0][2][0][RTW89_MEXICO][25] = 72, + [0][0][2][0][RTW89_UKRAINE][25] = 54, + [0][0][2][0][RTW89_CHILE][25] = 70, + [0][0][2][0][RTW89_QATAR][25] = 66, + [0][0][2][0][RTW89_THAILAND][25] = 66, + [0][0][2][0][RTW89_FCC][27] = 72, + [0][0][2][0][RTW89_ETSI][27] = 66, + [0][0][2][0][RTW89_MKK][27] = 70, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_KCC][27] = 70, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_CN][27] = 127, + [0][0][2][0][RTW89_UK][27] = 66, + [0][0][2][0][RTW89_MEXICO][27] = 72, + [0][0][2][0][RTW89_UKRAINE][27] = 54, + [0][0][2][0][RTW89_CHILE][27] = 56, + [0][0][2][0][RTW89_QATAR][27] = 66, + [0][0][2][0][RTW89_THAILAND][27] = 66, + [0][0][2][0][RTW89_FCC][29] = 72, + [0][0][2][0][RTW89_ETSI][29] = 66, + [0][0][2][0][RTW89_MKK][29] = 70, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_KCC][29] = 70, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_CN][29] = 127, + [0][0][2][0][RTW89_UK][29] = 66, + [0][0][2][0][RTW89_MEXICO][29] = 72, + [0][0][2][0][RTW89_UKRAINE][29] = 54, + [0][0][2][0][RTW89_CHILE][29] = 56, + [0][0][2][0][RTW89_QATAR][29] = 66, + [0][0][2][0][RTW89_THAILAND][29] = 66, + [0][0][2][0][RTW89_FCC][31] = 72, + [0][0][2][0][RTW89_ETSI][31] = 66, + [0][0][2][0][RTW89_MKK][31] = 70, + [0][0][2][0][RTW89_IC][31] = 72, + [0][0][2][0][RTW89_KCC][31] = 70, + [0][0][2][0][RTW89_ACMA][31] = 66, + [0][0][2][0][RTW89_CN][31] = 127, + [0][0][2][0][RTW89_UK][31] = 66, + [0][0][2][0][RTW89_MEXICO][31] = 72, + [0][0][2][0][RTW89_UKRAINE][31] = 54, + [0][0][2][0][RTW89_CHILE][31] = 56, + [0][0][2][0][RTW89_QATAR][31] = 66, + [0][0][2][0][RTW89_THAILAND][31] = 66, + [0][0][2][0][RTW89_FCC][33] = 72, + [0][0][2][0][RTW89_ETSI][33] = 66, + [0][0][2][0][RTW89_MKK][33] = 70, + [0][0][2][0][RTW89_IC][33] = 72, + [0][0][2][0][RTW89_KCC][33] = 70, + [0][0][2][0][RTW89_ACMA][33] = 66, + [0][0][2][0][RTW89_CN][33] = 127, + [0][0][2][0][RTW89_UK][33] = 66, + [0][0][2][0][RTW89_MEXICO][33] = 72, + [0][0][2][0][RTW89_UKRAINE][33] = 54, + [0][0][2][0][RTW89_CHILE][33] = 56, + [0][0][2][0][RTW89_QATAR][33] = 66, + [0][0][2][0][RTW89_THAILAND][33] = 66, + [0][0][2][0][RTW89_FCC][35] = 56, + [0][0][2][0][RTW89_ETSI][35] = 66, + [0][0][2][0][RTW89_MKK][35] = 70, + [0][0][2][0][RTW89_IC][35] = 56, + [0][0][2][0][RTW89_KCC][35] = 70, + [0][0][2][0][RTW89_ACMA][35] = 66, + [0][0][2][0][RTW89_CN][35] = 127, + [0][0][2][0][RTW89_UK][35] = 66, + [0][0][2][0][RTW89_MEXICO][35] = 56, + [0][0][2][0][RTW89_UKRAINE][35] = 54, + [0][0][2][0][RTW89_CHILE][35] = 56, + [0][0][2][0][RTW89_QATAR][35] = 66, + [0][0][2][0][RTW89_THAILAND][35] = 66, + [0][0][2][0][RTW89_FCC][37] = 72, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 70, + [0][0][2][0][RTW89_IC][37] = 72, + [0][0][2][0][RTW89_KCC][37] = 70, + [0][0][2][0][RTW89_ACMA][37] = 70, + [0][0][2][0][RTW89_CN][37] = 127, + [0][0][2][0][RTW89_UK][37] = 64, + [0][0][2][0][RTW89_MEXICO][37] = 72, + [0][0][2][0][RTW89_UKRAINE][37] = 127, + [0][0][2][0][RTW89_CHILE][37] = 70, + [0][0][2][0][RTW89_QATAR][37] = 127, + [0][0][2][0][RTW89_THAILAND][37] = 127, + [0][0][2][0][RTW89_FCC][38] = 72, + [0][0][2][0][RTW89_ETSI][38] = 30, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 72, + [0][0][2][0][RTW89_KCC][38] = 58, + [0][0][2][0][RTW89_ACMA][38] = 70, + [0][0][2][0][RTW89_CN][38] = 56, + [0][0][2][0][RTW89_UK][38] = 64, + [0][0][2][0][RTW89_MEXICO][38] = 72, + [0][0][2][0][RTW89_UKRAINE][38] = 30, + [0][0][2][0][RTW89_CHILE][38] = 70, + [0][0][2][0][RTW89_QATAR][38] = 30, + [0][0][2][0][RTW89_THAILAND][38] = 30, + [0][0][2][0][RTW89_FCC][40] = 72, + [0][0][2][0][RTW89_ETSI][40] = 30, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 72, + [0][0][2][0][RTW89_KCC][40] = 58, + [0][0][2][0][RTW89_ACMA][40] = 70, + [0][0][2][0][RTW89_CN][40] = 56, + [0][0][2][0][RTW89_UK][40] = 64, + [0][0][2][0][RTW89_MEXICO][40] = 72, + [0][0][2][0][RTW89_UKRAINE][40] = 30, + [0][0][2][0][RTW89_CHILE][40] = 70, + [0][0][2][0][RTW89_QATAR][40] = 30, + [0][0][2][0][RTW89_THAILAND][40] = 30, + [0][0][2][0][RTW89_FCC][42] = 72, + [0][0][2][0][RTW89_ETSI][42] = 30, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 72, + [0][0][2][0][RTW89_KCC][42] = 58, + [0][0][2][0][RTW89_ACMA][42] = 70, + [0][0][2][0][RTW89_CN][42] = 56, + [0][0][2][0][RTW89_UK][42] = 64, + [0][0][2][0][RTW89_MEXICO][42] = 72, + [0][0][2][0][RTW89_UKRAINE][42] = 30, + [0][0][2][0][RTW89_CHILE][42] = 70, + [0][0][2][0][RTW89_QATAR][42] = 30, + [0][0][2][0][RTW89_THAILAND][42] = 30, + [0][0][2][0][RTW89_FCC][44] = 72, + [0][0][2][0][RTW89_ETSI][44] = 30, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 72, + [0][0][2][0][RTW89_KCC][44] = 58, + [0][0][2][0][RTW89_ACMA][44] = 70, + [0][0][2][0][RTW89_CN][44] = 56, + [0][0][2][0][RTW89_UK][44] = 64, + [0][0][2][0][RTW89_MEXICO][44] = 72, + [0][0][2][0][RTW89_UKRAINE][44] = 30, + [0][0][2][0][RTW89_CHILE][44] = 70, + [0][0][2][0][RTW89_QATAR][44] = 30, + [0][0][2][0][RTW89_THAILAND][44] = 30, + [0][0][2][0][RTW89_FCC][46] = 72, + [0][0][2][0][RTW89_ETSI][46] = 30, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 72, + [0][0][2][0][RTW89_KCC][46] = 58, + [0][0][2][0][RTW89_ACMA][46] = 70, + [0][0][2][0][RTW89_CN][46] = 56, + [0][0][2][0][RTW89_UK][46] = 64, + [0][0][2][0][RTW89_MEXICO][46] = 72, + [0][0][2][0][RTW89_UKRAINE][46] = 30, + [0][0][2][0][RTW89_CHILE][46] = 70, + [0][0][2][0][RTW89_QATAR][46] = 30, + [0][0][2][0][RTW89_THAILAND][46] = 30, + [0][0][2][0][RTW89_FCC][48] = 72, + [0][0][2][0][RTW89_ETSI][48] = 127, + [0][0][2][0][RTW89_MKK][48] = 127, + [0][0][2][0][RTW89_IC][48] = 72, + [0][0][2][0][RTW89_KCC][48] = 127, + [0][0][2][0][RTW89_ACMA][48] = 127, + [0][0][2][0][RTW89_CN][48] = 127, + [0][0][2][0][RTW89_UK][48] = 127, + [0][0][2][0][RTW89_MEXICO][48] = 127, + [0][0][2][0][RTW89_UKRAINE][48] = 127, + [0][0][2][0][RTW89_CHILE][48] = 127, + [0][0][2][0][RTW89_QATAR][48] = 127, + [0][0][2][0][RTW89_THAILAND][48] = 127, + [0][0][2][0][RTW89_FCC][50] = 72, + [0][0][2][0][RTW89_ETSI][50] = 127, + [0][0][2][0][RTW89_MKK][50] = 127, + [0][0][2][0][RTW89_IC][50] = 72, + [0][0][2][0][RTW89_KCC][50] = 127, + [0][0][2][0][RTW89_ACMA][50] = 127, + [0][0][2][0][RTW89_CN][50] = 127, + [0][0][2][0][RTW89_UK][50] = 127, + [0][0][2][0][RTW89_MEXICO][50] = 127, + [0][0][2][0][RTW89_UKRAINE][50] = 127, + [0][0][2][0][RTW89_CHILE][50] = 127, + [0][0][2][0][RTW89_QATAR][50] = 127, + [0][0][2][0][RTW89_THAILAND][50] = 127, + [0][0][2][0][RTW89_FCC][52] = 72, + [0][0][2][0][RTW89_ETSI][52] = 127, + [0][0][2][0][RTW89_MKK][52] = 127, + [0][0][2][0][RTW89_IC][52] = 72, + [0][0][2][0][RTW89_KCC][52] = 127, + [0][0][2][0][RTW89_ACMA][52] = 127, + [0][0][2][0][RTW89_CN][52] = 127, + [0][0][2][0][RTW89_UK][52] = 127, + [0][0][2][0][RTW89_MEXICO][52] = 127, + [0][0][2][0][RTW89_UKRAINE][52] = 127, + [0][0][2][0][RTW89_CHILE][52] = 127, + [0][0][2][0][RTW89_QATAR][52] = 127, + [0][0][2][0][RTW89_THAILAND][52] = 127, + [0][1][2][0][RTW89_FCC][0] = 60, + [0][1][2][0][RTW89_ETSI][0] = 54, + [0][1][2][0][RTW89_MKK][0] = 54, + [0][1][2][0][RTW89_IC][0] = 36, + [0][1][2][0][RTW89_KCC][0] = 64, + [0][1][2][0][RTW89_ACMA][0] = 54, + [0][1][2][0][RTW89_CN][0] = 40, + [0][1][2][0][RTW89_UK][0] = 54, + [0][1][2][0][RTW89_MEXICO][0] = 50, + [0][1][2][0][RTW89_UKRAINE][0] = 42, + [0][1][2][0][RTW89_CHILE][0] = 60, + [0][1][2][0][RTW89_QATAR][0] = 54, + [0][1][2][0][RTW89_THAILAND][0] = 54, + [0][1][2][0][RTW89_FCC][2] = 62, + [0][1][2][0][RTW89_ETSI][2] = 54, + [0][1][2][0][RTW89_MKK][2] = 54, + [0][1][2][0][RTW89_IC][2] = 36, + [0][1][2][0][RTW89_KCC][2] = 64, + [0][1][2][0][RTW89_ACMA][2] = 54, + [0][1][2][0][RTW89_CN][2] = 40, + [0][1][2][0][RTW89_UK][2] = 54, + [0][1][2][0][RTW89_MEXICO][2] = 50, + [0][1][2][0][RTW89_UKRAINE][2] = 42, + [0][1][2][0][RTW89_CHILE][2] = 62, + [0][1][2][0][RTW89_QATAR][2] = 54, + [0][1][2][0][RTW89_THAILAND][2] = 54, + [0][1][2][0][RTW89_FCC][4] = 62, + [0][1][2][0][RTW89_ETSI][4] = 54, + [0][1][2][0][RTW89_MKK][4] = 54, + [0][1][2][0][RTW89_IC][4] = 36, + [0][1][2][0][RTW89_KCC][4] = 64, + [0][1][2][0][RTW89_ACMA][4] = 54, + [0][1][2][0][RTW89_CN][4] = 40, + [0][1][2][0][RTW89_UK][4] = 54, + [0][1][2][0][RTW89_MEXICO][4] = 50, + [0][1][2][0][RTW89_UKRAINE][4] = 42, + [0][1][2][0][RTW89_CHILE][4] = 62, + [0][1][2][0][RTW89_QATAR][4] = 54, + [0][1][2][0][RTW89_THAILAND][4] = 54, + [0][1][2][0][RTW89_FCC][6] = 62, + [0][1][2][0][RTW89_ETSI][6] = 54, + [0][1][2][0][RTW89_MKK][6] = 50, + [0][1][2][0][RTW89_IC][6] = 38, + [0][1][2][0][RTW89_KCC][6] = 40, + [0][1][2][0][RTW89_ACMA][6] = 54, + [0][1][2][0][RTW89_CN][6] = 40, + [0][1][2][0][RTW89_UK][6] = 54, + [0][1][2][0][RTW89_MEXICO][6] = 50, + [0][1][2][0][RTW89_UKRAINE][6] = 42, + [0][1][2][0][RTW89_CHILE][6] = 62, + [0][1][2][0][RTW89_QATAR][6] = 54, + [0][1][2][0][RTW89_THAILAND][6] = 54, + [0][1][2][0][RTW89_FCC][8] = 62, + [0][1][2][0][RTW89_ETSI][8] = 54, + [0][1][2][0][RTW89_MKK][8] = 42, + [0][1][2][0][RTW89_IC][8] = 52, + [0][1][2][0][RTW89_KCC][8] = 62, + [0][1][2][0][RTW89_ACMA][8] = 54, + [0][1][2][0][RTW89_CN][8] = 40, + [0][1][2][0][RTW89_UK][8] = 54, + [0][1][2][0][RTW89_MEXICO][8] = 62, + [0][1][2][0][RTW89_UKRAINE][8] = 42, + [0][1][2][0][RTW89_CHILE][8] = 62, + [0][1][2][0][RTW89_QATAR][8] = 54, + [0][1][2][0][RTW89_THAILAND][8] = 54, + [0][1][2][0][RTW89_FCC][10] = 62, + [0][1][2][0][RTW89_ETSI][10] = 54, + [0][1][2][0][RTW89_MKK][10] = 54, + [0][1][2][0][RTW89_IC][10] = 52, + [0][1][2][0][RTW89_KCC][10] = 62, + [0][1][2][0][RTW89_ACMA][10] = 54, + [0][1][2][0][RTW89_CN][10] = 40, + [0][1][2][0][RTW89_UK][10] = 54, + [0][1][2][0][RTW89_MEXICO][10] = 62, + [0][1][2][0][RTW89_UKRAINE][10] = 42, + [0][1][2][0][RTW89_CHILE][10] = 62, + [0][1][2][0][RTW89_QATAR][10] = 54, + [0][1][2][0][RTW89_THAILAND][10] = 54, + [0][1][2][0][RTW89_FCC][12] = 62, + [0][1][2][0][RTW89_ETSI][12] = 54, + [0][1][2][0][RTW89_MKK][12] = 54, + [0][1][2][0][RTW89_IC][12] = 52, + [0][1][2][0][RTW89_KCC][12] = 62, + [0][1][2][0][RTW89_ACMA][12] = 54, + [0][1][2][0][RTW89_CN][12] = 40, + [0][1][2][0][RTW89_UK][12] = 54, + [0][1][2][0][RTW89_MEXICO][12] = 62, + [0][1][2][0][RTW89_UKRAINE][12] = 42, + [0][1][2][0][RTW89_CHILE][12] = 62, + [0][1][2][0][RTW89_QATAR][12] = 54, + [0][1][2][0][RTW89_THAILAND][12] = 54, + [0][1][2][0][RTW89_FCC][14] = 62, + [0][1][2][0][RTW89_ETSI][14] = 54, + [0][1][2][0][RTW89_MKK][14] = 54, + [0][1][2][0][RTW89_IC][14] = 52, + [0][1][2][0][RTW89_KCC][14] = 62, + [0][1][2][0][RTW89_ACMA][14] = 54, + [0][1][2][0][RTW89_CN][14] = 40, + [0][1][2][0][RTW89_UK][14] = 54, + [0][1][2][0][RTW89_MEXICO][14] = 62, + [0][1][2][0][RTW89_UKRAINE][14] = 42, + [0][1][2][0][RTW89_CHILE][14] = 62, + [0][1][2][0][RTW89_QATAR][14] = 54, + [0][1][2][0][RTW89_THAILAND][14] = 54, + [0][1][2][0][RTW89_FCC][15] = 60, + [0][1][2][0][RTW89_ETSI][15] = 54, + [0][1][2][0][RTW89_MKK][15] = 68, + [0][1][2][0][RTW89_IC][15] = 60, + [0][1][2][0][RTW89_KCC][15] = 64, + [0][1][2][0][RTW89_ACMA][15] = 54, + [0][1][2][0][RTW89_CN][15] = 127, + [0][1][2][0][RTW89_UK][15] = 54, + [0][1][2][0][RTW89_MEXICO][15] = 60, + [0][1][2][0][RTW89_UKRAINE][15] = 42, + [0][1][2][0][RTW89_CHILE][15] = 60, + [0][1][2][0][RTW89_QATAR][15] = 54, + [0][1][2][0][RTW89_THAILAND][15] = 54, + [0][1][2][0][RTW89_FCC][17] = 62, + [0][1][2][0][RTW89_ETSI][17] = 54, + [0][1][2][0][RTW89_MKK][17] = 68, + [0][1][2][0][RTW89_IC][17] = 62, + [0][1][2][0][RTW89_KCC][17] = 64, + [0][1][2][0][RTW89_ACMA][17] = 54, + [0][1][2][0][RTW89_CN][17] = 127, + [0][1][2][0][RTW89_UK][17] = 54, + [0][1][2][0][RTW89_MEXICO][17] = 62, + [0][1][2][0][RTW89_UKRAINE][17] = 42, + [0][1][2][0][RTW89_CHILE][17] = 60, + [0][1][2][0][RTW89_QATAR][17] = 54, + [0][1][2][0][RTW89_THAILAND][17] = 54, + [0][1][2][0][RTW89_FCC][19] = 62, + [0][1][2][0][RTW89_ETSI][19] = 54, + [0][1][2][0][RTW89_MKK][19] = 68, + [0][1][2][0][RTW89_IC][19] = 62, + [0][1][2][0][RTW89_KCC][19] = 64, + [0][1][2][0][RTW89_ACMA][19] = 54, + [0][1][2][0][RTW89_CN][19] = 127, + [0][1][2][0][RTW89_UK][19] = 54, + [0][1][2][0][RTW89_MEXICO][19] = 62, + [0][1][2][0][RTW89_UKRAINE][19] = 42, + [0][1][2][0][RTW89_CHILE][19] = 62, + [0][1][2][0][RTW89_QATAR][19] = 54, + [0][1][2][0][RTW89_THAILAND][19] = 54, + [0][1][2][0][RTW89_FCC][21] = 62, + [0][1][2][0][RTW89_ETSI][21] = 54, + [0][1][2][0][RTW89_MKK][21] = 68, + [0][1][2][0][RTW89_IC][21] = 62, + [0][1][2][0][RTW89_KCC][21] = 64, + [0][1][2][0][RTW89_ACMA][21] = 54, + [0][1][2][0][RTW89_CN][21] = 127, + [0][1][2][0][RTW89_UK][21] = 54, + [0][1][2][0][RTW89_MEXICO][21] = 62, + [0][1][2][0][RTW89_UKRAINE][21] = 42, + [0][1][2][0][RTW89_CHILE][21] = 62, + [0][1][2][0][RTW89_QATAR][21] = 54, + [0][1][2][0][RTW89_THAILAND][21] = 54, + [0][1][2][0][RTW89_FCC][23] = 62, + [0][1][2][0][RTW89_ETSI][23] = 54, + [0][1][2][0][RTW89_MKK][23] = 68, + [0][1][2][0][RTW89_IC][23] = 62, + [0][1][2][0][RTW89_KCC][23] = 64, + [0][1][2][0][RTW89_ACMA][23] = 54, + [0][1][2][0][RTW89_CN][23] = 127, + [0][1][2][0][RTW89_UK][23] = 54, + [0][1][2][0][RTW89_MEXICO][23] = 62, + [0][1][2][0][RTW89_UKRAINE][23] = 42, + [0][1][2][0][RTW89_CHILE][23] = 62, + [0][1][2][0][RTW89_QATAR][23] = 54, + [0][1][2][0][RTW89_THAILAND][23] = 54, + [0][1][2][0][RTW89_FCC][25] = 62, + [0][1][2][0][RTW89_ETSI][25] = 54, + [0][1][2][0][RTW89_MKK][25] = 68, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_KCC][25] = 64, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_CN][25] = 127, + [0][1][2][0][RTW89_UK][25] = 54, + [0][1][2][0][RTW89_MEXICO][25] = 62, + [0][1][2][0][RTW89_UKRAINE][25] = 42, + [0][1][2][0][RTW89_CHILE][25] = 62, + [0][1][2][0][RTW89_QATAR][25] = 54, + [0][1][2][0][RTW89_THAILAND][25] = 54, + [0][1][2][0][RTW89_FCC][27] = 62, + [0][1][2][0][RTW89_ETSI][27] = 54, + [0][1][2][0][RTW89_MKK][27] = 68, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_KCC][27] = 64, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_CN][27] = 127, + [0][1][2][0][RTW89_UK][27] = 54, + [0][1][2][0][RTW89_MEXICO][27] = 62, + [0][1][2][0][RTW89_UKRAINE][27] = 42, + [0][1][2][0][RTW89_CHILE][27] = 46, + [0][1][2][0][RTW89_QATAR][27] = 54, + [0][1][2][0][RTW89_THAILAND][27] = 54, + [0][1][2][0][RTW89_FCC][29] = 62, + [0][1][2][0][RTW89_ETSI][29] = 54, + [0][1][2][0][RTW89_MKK][29] = 68, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_KCC][29] = 64, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_CN][29] = 127, + [0][1][2][0][RTW89_UK][29] = 54, + [0][1][2][0][RTW89_MEXICO][29] = 62, + [0][1][2][0][RTW89_UKRAINE][29] = 42, + [0][1][2][0][RTW89_CHILE][29] = 46, + [0][1][2][0][RTW89_QATAR][29] = 54, + [0][1][2][0][RTW89_THAILAND][29] = 54, + [0][1][2][0][RTW89_FCC][31] = 62, + [0][1][2][0][RTW89_ETSI][31] = 54, + [0][1][2][0][RTW89_MKK][31] = 68, + [0][1][2][0][RTW89_IC][31] = 62, + [0][1][2][0][RTW89_KCC][31] = 62, + [0][1][2][0][RTW89_ACMA][31] = 54, + [0][1][2][0][RTW89_CN][31] = 127, + [0][1][2][0][RTW89_UK][31] = 54, + [0][1][2][0][RTW89_MEXICO][31] = 62, + [0][1][2][0][RTW89_UKRAINE][31] = 42, + [0][1][2][0][RTW89_CHILE][31] = 46, + [0][1][2][0][RTW89_QATAR][31] = 54, + [0][1][2][0][RTW89_THAILAND][31] = 54, + [0][1][2][0][RTW89_FCC][33] = 62, + [0][1][2][0][RTW89_ETSI][33] = 54, + [0][1][2][0][RTW89_MKK][33] = 68, + [0][1][2][0][RTW89_IC][33] = 62, + [0][1][2][0][RTW89_KCC][33] = 62, + [0][1][2][0][RTW89_ACMA][33] = 54, + [0][1][2][0][RTW89_CN][33] = 127, + [0][1][2][0][RTW89_UK][33] = 54, + [0][1][2][0][RTW89_MEXICO][33] = 62, + [0][1][2][0][RTW89_UKRAINE][33] = 42, + [0][1][2][0][RTW89_CHILE][33] = 46, + [0][1][2][0][RTW89_QATAR][33] = 54, + [0][1][2][0][RTW89_THAILAND][33] = 54, + [0][1][2][0][RTW89_FCC][35] = 46, + [0][1][2][0][RTW89_ETSI][35] = 54, + [0][1][2][0][RTW89_MKK][35] = 68, + [0][1][2][0][RTW89_IC][35] = 46, + [0][1][2][0][RTW89_KCC][35] = 62, + [0][1][2][0][RTW89_ACMA][35] = 54, + [0][1][2][0][RTW89_CN][35] = 127, + [0][1][2][0][RTW89_UK][35] = 54, + [0][1][2][0][RTW89_MEXICO][35] = 46, + [0][1][2][0][RTW89_UKRAINE][35] = 42, + [0][1][2][0][RTW89_CHILE][35] = 46, + [0][1][2][0][RTW89_QATAR][35] = 54, + [0][1][2][0][RTW89_THAILAND][35] = 54, + [0][1][2][0][RTW89_FCC][37] = 64, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 68, + [0][1][2][0][RTW89_IC][37] = 64, + [0][1][2][0][RTW89_KCC][37] = 62, + [0][1][2][0][RTW89_ACMA][37] = 64, + [0][1][2][0][RTW89_CN][37] = 127, + [0][1][2][0][RTW89_UK][37] = 52, + [0][1][2][0][RTW89_MEXICO][37] = 64, + [0][1][2][0][RTW89_UKRAINE][37] = 127, + [0][1][2][0][RTW89_CHILE][37] = 64, + [0][1][2][0][RTW89_QATAR][37] = 127, + [0][1][2][0][RTW89_THAILAND][37] = 127, + [0][1][2][0][RTW89_FCC][38] = 72, + [0][1][2][0][RTW89_ETSI][38] = 18, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 72, + [0][1][2][0][RTW89_KCC][38] = 56, + [0][1][2][0][RTW89_ACMA][38] = 70, + [0][1][2][0][RTW89_CN][38] = 56, + [0][1][2][0][RTW89_UK][38] = 52, + [0][1][2][0][RTW89_MEXICO][38] = 72, + [0][1][2][0][RTW89_UKRAINE][38] = 18, + [0][1][2][0][RTW89_CHILE][38] = 70, + [0][1][2][0][RTW89_QATAR][38] = 18, + [0][1][2][0][RTW89_THAILAND][38] = 18, + [0][1][2][0][RTW89_FCC][40] = 72, + [0][1][2][0][RTW89_ETSI][40] = 18, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 72, + [0][1][2][0][RTW89_KCC][40] = 56, + [0][1][2][0][RTW89_ACMA][40] = 70, + [0][1][2][0][RTW89_CN][40] = 56, + [0][1][2][0][RTW89_UK][40] = 52, + [0][1][2][0][RTW89_MEXICO][40] = 72, + [0][1][2][0][RTW89_UKRAINE][40] = 18, + [0][1][2][0][RTW89_CHILE][40] = 70, + [0][1][2][0][RTW89_QATAR][40] = 18, + [0][1][2][0][RTW89_THAILAND][40] = 18, + [0][1][2][0][RTW89_FCC][42] = 72, + [0][1][2][0][RTW89_ETSI][42] = 18, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 72, + [0][1][2][0][RTW89_KCC][42] = 56, + [0][1][2][0][RTW89_ACMA][42] = 70, + [0][1][2][0][RTW89_CN][42] = 56, + [0][1][2][0][RTW89_UK][42] = 52, + [0][1][2][0][RTW89_MEXICO][42] = 72, + [0][1][2][0][RTW89_UKRAINE][42] = 18, + [0][1][2][0][RTW89_CHILE][42] = 70, + [0][1][2][0][RTW89_QATAR][42] = 18, + [0][1][2][0][RTW89_THAILAND][42] = 18, + [0][1][2][0][RTW89_FCC][44] = 72, + [0][1][2][0][RTW89_ETSI][44] = 18, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 72, + [0][1][2][0][RTW89_KCC][44] = 56, + [0][1][2][0][RTW89_ACMA][44] = 70, + [0][1][2][0][RTW89_CN][44] = 56, + [0][1][2][0][RTW89_UK][44] = 52, + [0][1][2][0][RTW89_MEXICO][44] = 72, + [0][1][2][0][RTW89_UKRAINE][44] = 18, + [0][1][2][0][RTW89_CHILE][44] = 70, + [0][1][2][0][RTW89_QATAR][44] = 18, + [0][1][2][0][RTW89_THAILAND][44] = 18, + [0][1][2][0][RTW89_FCC][46] = 72, + [0][1][2][0][RTW89_ETSI][46] = 18, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 72, + [0][1][2][0][RTW89_KCC][46] = 56, + [0][1][2][0][RTW89_ACMA][46] = 70, + [0][1][2][0][RTW89_CN][46] = 56, + [0][1][2][0][RTW89_UK][46] = 52, + [0][1][2][0][RTW89_MEXICO][46] = 72, + [0][1][2][0][RTW89_UKRAINE][46] = 18, + [0][1][2][0][RTW89_CHILE][46] = 70, + [0][1][2][0][RTW89_QATAR][46] = 18, + [0][1][2][0][RTW89_THAILAND][46] = 18, + [0][1][2][0][RTW89_FCC][48] = 48, + [0][1][2][0][RTW89_ETSI][48] = 127, + [0][1][2][0][RTW89_MKK][48] = 127, + [0][1][2][0][RTW89_IC][48] = 48, + [0][1][2][0][RTW89_KCC][48] = 127, + [0][1][2][0][RTW89_ACMA][48] = 127, + [0][1][2][0][RTW89_CN][48] = 127, + [0][1][2][0][RTW89_UK][48] = 127, + [0][1][2][0][RTW89_MEXICO][48] = 127, + [0][1][2][0][RTW89_UKRAINE][48] = 127, + [0][1][2][0][RTW89_CHILE][48] = 127, + [0][1][2][0][RTW89_QATAR][48] = 127, + [0][1][2][0][RTW89_THAILAND][48] = 127, + [0][1][2][0][RTW89_FCC][50] = 50, + [0][1][2][0][RTW89_ETSI][50] = 127, + [0][1][2][0][RTW89_MKK][50] = 127, + [0][1][2][0][RTW89_IC][50] = 50, + [0][1][2][0][RTW89_KCC][50] = 127, + [0][1][2][0][RTW89_ACMA][50] = 127, + [0][1][2][0][RTW89_CN][50] = 127, + [0][1][2][0][RTW89_UK][50] = 127, + [0][1][2][0][RTW89_MEXICO][50] = 127, + [0][1][2][0][RTW89_UKRAINE][50] = 127, + [0][1][2][0][RTW89_CHILE][50] = 127, + [0][1][2][0][RTW89_QATAR][50] = 127, + [0][1][2][0][RTW89_THAILAND][50] = 127, + [0][1][2][0][RTW89_FCC][52] = 48, + [0][1][2][0][RTW89_ETSI][52] = 127, + [0][1][2][0][RTW89_MKK][52] = 127, + [0][1][2][0][RTW89_IC][52] = 48, + [0][1][2][0][RTW89_KCC][52] = 127, + [0][1][2][0][RTW89_ACMA][52] = 127, + [0][1][2][0][RTW89_CN][52] = 127, + [0][1][2][0][RTW89_UK][52] = 127, + [0][1][2][0][RTW89_MEXICO][52] = 127, + [0][1][2][0][RTW89_UKRAINE][52] = 127, + [0][1][2][0][RTW89_CHILE][52] = 127, + [0][1][2][0][RTW89_QATAR][52] = 127, + [0][1][2][0][RTW89_THAILAND][52] = 127, + [0][1][2][1][RTW89_FCC][0] = 60, + [0][1][2][1][RTW89_ETSI][0] = 40, + [0][1][2][1][RTW89_MKK][0] = 54, + [0][1][2][1][RTW89_IC][0] = 40, + [0][1][2][1][RTW89_KCC][0] = 64, + [0][1][2][1][RTW89_ACMA][0] = 40, + [0][1][2][1][RTW89_CN][0] = 36, + [0][1][2][1][RTW89_UK][0] = 40, + [0][1][2][1][RTW89_MEXICO][0] = 50, + [0][1][2][1][RTW89_UKRAINE][0] = 30, + [0][1][2][1][RTW89_CHILE][0] = 60, + [0][1][2][1][RTW89_QATAR][0] = 40, + [0][1][2][1][RTW89_THAILAND][0] = 40, + [0][1][2][1][RTW89_FCC][2] = 62, + [0][1][2][1][RTW89_ETSI][2] = 40, + [0][1][2][1][RTW89_MKK][2] = 54, + [0][1][2][1][RTW89_IC][2] = 40, + [0][1][2][1][RTW89_KCC][2] = 64, + [0][1][2][1][RTW89_ACMA][2] = 40, + [0][1][2][1][RTW89_CN][2] = 36, + [0][1][2][1][RTW89_UK][2] = 40, + [0][1][2][1][RTW89_MEXICO][2] = 50, + [0][1][2][1][RTW89_UKRAINE][2] = 30, + [0][1][2][1][RTW89_CHILE][2] = 60, + [0][1][2][1][RTW89_QATAR][2] = 40, + [0][1][2][1][RTW89_THAILAND][2] = 40, + [0][1][2][1][RTW89_FCC][4] = 62, + [0][1][2][1][RTW89_ETSI][4] = 40, + [0][1][2][1][RTW89_MKK][4] = 54, + [0][1][2][1][RTW89_IC][4] = 40, + [0][1][2][1][RTW89_KCC][4] = 64, + [0][1][2][1][RTW89_ACMA][4] = 40, + [0][1][2][1][RTW89_CN][4] = 36, + [0][1][2][1][RTW89_UK][4] = 40, + [0][1][2][1][RTW89_MEXICO][4] = 50, + [0][1][2][1][RTW89_UKRAINE][4] = 30, + [0][1][2][1][RTW89_CHILE][4] = 60, + [0][1][2][1][RTW89_QATAR][4] = 40, + [0][1][2][1][RTW89_THAILAND][4] = 40, + [0][1][2][1][RTW89_FCC][6] = 62, + [0][1][2][1][RTW89_ETSI][6] = 40, + [0][1][2][1][RTW89_MKK][6] = 50, + [0][1][2][1][RTW89_IC][6] = 40, + [0][1][2][1][RTW89_KCC][6] = 40, + [0][1][2][1][RTW89_ACMA][6] = 40, + [0][1][2][1][RTW89_CN][6] = 36, + [0][1][2][1][RTW89_UK][6] = 40, + [0][1][2][1][RTW89_MEXICO][6] = 50, + [0][1][2][1][RTW89_UKRAINE][6] = 30, + [0][1][2][1][RTW89_CHILE][6] = 60, + [0][1][2][1][RTW89_QATAR][6] = 40, + [0][1][2][1][RTW89_THAILAND][6] = 40, + [0][1][2][1][RTW89_FCC][8] = 62, + [0][1][2][1][RTW89_ETSI][8] = 40, + [0][1][2][1][RTW89_MKK][8] = 42, + [0][1][2][1][RTW89_IC][8] = 40, + [0][1][2][1][RTW89_KCC][8] = 62, + [0][1][2][1][RTW89_ACMA][8] = 40, + [0][1][2][1][RTW89_CN][8] = 36, + [0][1][2][1][RTW89_UK][8] = 40, + [0][1][2][1][RTW89_MEXICO][8] = 62, + [0][1][2][1][RTW89_UKRAINE][8] = 30, + [0][1][2][1][RTW89_CHILE][8] = 60, + [0][1][2][1][RTW89_QATAR][8] = 40, + [0][1][2][1][RTW89_THAILAND][8] = 40, + [0][1][2][1][RTW89_FCC][10] = 62, + [0][1][2][1][RTW89_ETSI][10] = 40, + [0][1][2][1][RTW89_MKK][10] = 54, + [0][1][2][1][RTW89_IC][10] = 40, + [0][1][2][1][RTW89_KCC][10] = 62, + [0][1][2][1][RTW89_ACMA][10] = 40, + [0][1][2][1][RTW89_CN][10] = 36, + [0][1][2][1][RTW89_UK][10] = 40, + [0][1][2][1][RTW89_MEXICO][10] = 62, + [0][1][2][1][RTW89_UKRAINE][10] = 30, + [0][1][2][1][RTW89_CHILE][10] = 60, + [0][1][2][1][RTW89_QATAR][10] = 40, + [0][1][2][1][RTW89_THAILAND][10] = 40, + [0][1][2][1][RTW89_FCC][12] = 62, + [0][1][2][1][RTW89_ETSI][12] = 40, + [0][1][2][1][RTW89_MKK][12] = 54, + [0][1][2][1][RTW89_IC][12] = 40, + [0][1][2][1][RTW89_KCC][12] = 62, + [0][1][2][1][RTW89_ACMA][12] = 40, + [0][1][2][1][RTW89_CN][12] = 36, + [0][1][2][1][RTW89_UK][12] = 40, + [0][1][2][1][RTW89_MEXICO][12] = 62, + [0][1][2][1][RTW89_UKRAINE][12] = 30, + [0][1][2][1][RTW89_CHILE][12] = 60, + [0][1][2][1][RTW89_QATAR][12] = 40, + [0][1][2][1][RTW89_THAILAND][12] = 40, + [0][1][2][1][RTW89_FCC][14] = 62, + [0][1][2][1][RTW89_ETSI][14] = 40, + [0][1][2][1][RTW89_MKK][14] = 54, + [0][1][2][1][RTW89_IC][14] = 40, + [0][1][2][1][RTW89_KCC][14] = 62, + [0][1][2][1][RTW89_ACMA][14] = 40, + [0][1][2][1][RTW89_CN][14] = 36, + [0][1][2][1][RTW89_UK][14] = 40, + [0][1][2][1][RTW89_MEXICO][14] = 62, + [0][1][2][1][RTW89_UKRAINE][14] = 30, + [0][1][2][1][RTW89_CHILE][14] = 60, + [0][1][2][1][RTW89_QATAR][14] = 40, + [0][1][2][1][RTW89_THAILAND][14] = 40, + [0][1][2][1][RTW89_FCC][15] = 60, + [0][1][2][1][RTW89_ETSI][15] = 40, + [0][1][2][1][RTW89_MKK][15] = 68, + [0][1][2][1][RTW89_IC][15] = 60, + [0][1][2][1][RTW89_KCC][15] = 64, + [0][1][2][1][RTW89_ACMA][15] = 40, + [0][1][2][1][RTW89_CN][15] = 127, + [0][1][2][1][RTW89_UK][15] = 40, + [0][1][2][1][RTW89_MEXICO][15] = 60, + [0][1][2][1][RTW89_UKRAINE][15] = 30, + [0][1][2][1][RTW89_CHILE][15] = 60, + [0][1][2][1][RTW89_QATAR][15] = 40, + [0][1][2][1][RTW89_THAILAND][15] = 40, + [0][1][2][1][RTW89_FCC][17] = 62, + [0][1][2][1][RTW89_ETSI][17] = 40, + [0][1][2][1][RTW89_MKK][17] = 68, + [0][1][2][1][RTW89_IC][17] = 62, + [0][1][2][1][RTW89_KCC][17] = 64, + [0][1][2][1][RTW89_ACMA][17] = 40, + [0][1][2][1][RTW89_CN][17] = 127, + [0][1][2][1][RTW89_UK][17] = 40, + [0][1][2][1][RTW89_MEXICO][17] = 62, + [0][1][2][1][RTW89_UKRAINE][17] = 30, + [0][1][2][1][RTW89_CHILE][17] = 60, + [0][1][2][1][RTW89_QATAR][17] = 40, + [0][1][2][1][RTW89_THAILAND][17] = 40, + [0][1][2][1][RTW89_FCC][19] = 62, + [0][1][2][1][RTW89_ETSI][19] = 40, + [0][1][2][1][RTW89_MKK][19] = 68, + [0][1][2][1][RTW89_IC][19] = 62, + [0][1][2][1][RTW89_KCC][19] = 64, + [0][1][2][1][RTW89_ACMA][19] = 40, + [0][1][2][1][RTW89_CN][19] = 127, + [0][1][2][1][RTW89_UK][19] = 40, + [0][1][2][1][RTW89_MEXICO][19] = 62, + [0][1][2][1][RTW89_UKRAINE][19] = 30, + [0][1][2][1][RTW89_CHILE][19] = 60, + [0][1][2][1][RTW89_QATAR][19] = 40, + [0][1][2][1][RTW89_THAILAND][19] = 40, + [0][1][2][1][RTW89_FCC][21] = 62, + [0][1][2][1][RTW89_ETSI][21] = 40, + [0][1][2][1][RTW89_MKK][21] = 68, + [0][1][2][1][RTW89_IC][21] = 62, + [0][1][2][1][RTW89_KCC][21] = 64, + [0][1][2][1][RTW89_ACMA][21] = 40, + [0][1][2][1][RTW89_CN][21] = 127, + [0][1][2][1][RTW89_UK][21] = 40, + [0][1][2][1][RTW89_MEXICO][21] = 62, + [0][1][2][1][RTW89_UKRAINE][21] = 30, + [0][1][2][1][RTW89_CHILE][21] = 60, + [0][1][2][1][RTW89_QATAR][21] = 40, + [0][1][2][1][RTW89_THAILAND][21] = 40, + [0][1][2][1][RTW89_FCC][23] = 62, + [0][1][2][1][RTW89_ETSI][23] = 40, + [0][1][2][1][RTW89_MKK][23] = 68, + [0][1][2][1][RTW89_IC][23] = 62, + [0][1][2][1][RTW89_KCC][23] = 64, + [0][1][2][1][RTW89_ACMA][23] = 40, + [0][1][2][1][RTW89_CN][23] = 127, + [0][1][2][1][RTW89_UK][23] = 40, + [0][1][2][1][RTW89_MEXICO][23] = 62, + [0][1][2][1][RTW89_UKRAINE][23] = 30, + [0][1][2][1][RTW89_CHILE][23] = 60, + [0][1][2][1][RTW89_QATAR][23] = 40, + [0][1][2][1][RTW89_THAILAND][23] = 40, + [0][1][2][1][RTW89_FCC][25] = 46, + [0][1][2][1][RTW89_ETSI][25] = 40, + [0][1][2][1][RTW89_MKK][25] = 68, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_KCC][25] = 64, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_CN][25] = 127, + [0][1][2][1][RTW89_UK][25] = 40, + [0][1][2][1][RTW89_MEXICO][25] = 46, + [0][1][2][1][RTW89_UKRAINE][25] = 30, + [0][1][2][1][RTW89_CHILE][25] = 60, + [0][1][2][1][RTW89_QATAR][25] = 40, + [0][1][2][1][RTW89_THAILAND][25] = 40, + [0][1][2][1][RTW89_FCC][27] = 46, + [0][1][2][1][RTW89_ETSI][27] = 40, + [0][1][2][1][RTW89_MKK][27] = 68, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_KCC][27] = 64, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_CN][27] = 127, + [0][1][2][1][RTW89_UK][27] = 40, + [0][1][2][1][RTW89_MEXICO][27] = 46, + [0][1][2][1][RTW89_UKRAINE][27] = 30, + [0][1][2][1][RTW89_CHILE][27] = 46, + [0][1][2][1][RTW89_QATAR][27] = 40, + [0][1][2][1][RTW89_THAILAND][27] = 40, + [0][1][2][1][RTW89_FCC][29] = 46, + [0][1][2][1][RTW89_ETSI][29] = 40, + [0][1][2][1][RTW89_MKK][29] = 68, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_KCC][29] = 64, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_CN][29] = 127, + [0][1][2][1][RTW89_UK][29] = 40, + [0][1][2][1][RTW89_MEXICO][29] = 46, + [0][1][2][1][RTW89_UKRAINE][29] = 30, + [0][1][2][1][RTW89_CHILE][29] = 46, + [0][1][2][1][RTW89_QATAR][29] = 40, + [0][1][2][1][RTW89_THAILAND][29] = 40, + [0][1][2][1][RTW89_FCC][31] = 46, + [0][1][2][1][RTW89_ETSI][31] = 40, + [0][1][2][1][RTW89_MKK][31] = 68, + [0][1][2][1][RTW89_IC][31] = 46, + [0][1][2][1][RTW89_KCC][31] = 62, + [0][1][2][1][RTW89_ACMA][31] = 40, + [0][1][2][1][RTW89_CN][31] = 127, + [0][1][2][1][RTW89_UK][31] = 40, + [0][1][2][1][RTW89_MEXICO][31] = 46, + [0][1][2][1][RTW89_UKRAINE][31] = 30, + [0][1][2][1][RTW89_CHILE][31] = 46, + [0][1][2][1][RTW89_QATAR][31] = 40, + [0][1][2][1][RTW89_THAILAND][31] = 40, + [0][1][2][1][RTW89_FCC][33] = 46, + [0][1][2][1][RTW89_ETSI][33] = 40, + [0][1][2][1][RTW89_MKK][33] = 68, + [0][1][2][1][RTW89_IC][33] = 46, + [0][1][2][1][RTW89_KCC][33] = 62, + [0][1][2][1][RTW89_ACMA][33] = 40, + [0][1][2][1][RTW89_CN][33] = 127, + [0][1][2][1][RTW89_UK][33] = 40, + [0][1][2][1][RTW89_MEXICO][33] = 46, + [0][1][2][1][RTW89_UKRAINE][33] = 30, + [0][1][2][1][RTW89_CHILE][33] = 46, + [0][1][2][1][RTW89_QATAR][33] = 40, + [0][1][2][1][RTW89_THAILAND][33] = 40, + [0][1][2][1][RTW89_FCC][35] = 46, + [0][1][2][1][RTW89_ETSI][35] = 40, + [0][1][2][1][RTW89_MKK][35] = 68, + [0][1][2][1][RTW89_IC][35] = 46, + [0][1][2][1][RTW89_KCC][35] = 62, + [0][1][2][1][RTW89_ACMA][35] = 40, + [0][1][2][1][RTW89_CN][35] = 127, + [0][1][2][1][RTW89_UK][35] = 40, + [0][1][2][1][RTW89_MEXICO][35] = 46, + [0][1][2][1][RTW89_UKRAINE][35] = 30, + [0][1][2][1][RTW89_CHILE][35] = 46, + [0][1][2][1][RTW89_QATAR][35] = 40, + [0][1][2][1][RTW89_THAILAND][35] = 40, + [0][1][2][1][RTW89_FCC][37] = 64, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 68, + [0][1][2][1][RTW89_IC][37] = 64, + [0][1][2][1][RTW89_KCC][37] = 62, + [0][1][2][1][RTW89_ACMA][37] = 64, + [0][1][2][1][RTW89_CN][37] = 127, + [0][1][2][1][RTW89_UK][37] = 40, + [0][1][2][1][RTW89_MEXICO][37] = 64, + [0][1][2][1][RTW89_UKRAINE][37] = 127, + [0][1][2][1][RTW89_CHILE][37] = 64, + [0][1][2][1][RTW89_QATAR][37] = 127, + [0][1][2][1][RTW89_THAILAND][37] = 127, + [0][1][2][1][RTW89_FCC][38] = 72, + [0][1][2][1][RTW89_ETSI][38] = 6, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 72, + [0][1][2][1][RTW89_KCC][38] = 56, + [0][1][2][1][RTW89_ACMA][38] = 70, + [0][1][2][1][RTW89_CN][38] = 50, + [0][1][2][1][RTW89_UK][38] = 40, + [0][1][2][1][RTW89_MEXICO][38] = 72, + [0][1][2][1][RTW89_UKRAINE][38] = 6, + [0][1][2][1][RTW89_CHILE][38] = 60, + [0][1][2][1][RTW89_QATAR][38] = 6, + [0][1][2][1][RTW89_THAILAND][38] = 6, + [0][1][2][1][RTW89_FCC][40] = 72, + [0][1][2][1][RTW89_ETSI][40] = 6, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 72, + [0][1][2][1][RTW89_KCC][40] = 56, + [0][1][2][1][RTW89_ACMA][40] = 70, + [0][1][2][1][RTW89_CN][40] = 50, + [0][1][2][1][RTW89_UK][40] = 40, + [0][1][2][1][RTW89_MEXICO][40] = 72, + [0][1][2][1][RTW89_UKRAINE][40] = 6, + [0][1][2][1][RTW89_CHILE][40] = 60, + [0][1][2][1][RTW89_QATAR][40] = 6, + [0][1][2][1][RTW89_THAILAND][40] = 6, + [0][1][2][1][RTW89_FCC][42] = 72, + [0][1][2][1][RTW89_ETSI][42] = 6, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 72, + [0][1][2][1][RTW89_KCC][42] = 56, + [0][1][2][1][RTW89_ACMA][42] = 70, + [0][1][2][1][RTW89_CN][42] = 50, + [0][1][2][1][RTW89_UK][42] = 40, + [0][1][2][1][RTW89_MEXICO][42] = 72, + [0][1][2][1][RTW89_UKRAINE][42] = 6, + [0][1][2][1][RTW89_CHILE][42] = 60, + [0][1][2][1][RTW89_QATAR][42] = 6, + [0][1][2][1][RTW89_THAILAND][42] = 6, + [0][1][2][1][RTW89_FCC][44] = 72, + [0][1][2][1][RTW89_ETSI][44] = 6, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 72, + [0][1][2][1][RTW89_KCC][44] = 56, + [0][1][2][1][RTW89_ACMA][44] = 70, + [0][1][2][1][RTW89_CN][44] = 50, + [0][1][2][1][RTW89_UK][44] = 40, + [0][1][2][1][RTW89_MEXICO][44] = 72, + [0][1][2][1][RTW89_UKRAINE][44] = 6, + [0][1][2][1][RTW89_CHILE][44] = 60, + [0][1][2][1][RTW89_QATAR][44] = 6, + [0][1][2][1][RTW89_THAILAND][44] = 6, + [0][1][2][1][RTW89_FCC][46] = 72, + [0][1][2][1][RTW89_ETSI][46] = 6, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 72, + [0][1][2][1][RTW89_KCC][46] = 56, + [0][1][2][1][RTW89_ACMA][46] = 70, + [0][1][2][1][RTW89_CN][46] = 50, + [0][1][2][1][RTW89_UK][46] = 40, + [0][1][2][1][RTW89_MEXICO][46] = 72, + [0][1][2][1][RTW89_UKRAINE][46] = 6, + [0][1][2][1][RTW89_CHILE][46] = 60, + [0][1][2][1][RTW89_QATAR][46] = 6, + [0][1][2][1][RTW89_THAILAND][46] = 6, + [0][1][2][1][RTW89_FCC][48] = 48, + [0][1][2][1][RTW89_ETSI][48] = 127, + [0][1][2][1][RTW89_MKK][48] = 127, + [0][1][2][1][RTW89_IC][48] = 48, + [0][1][2][1][RTW89_KCC][48] = 127, + [0][1][2][1][RTW89_ACMA][48] = 127, + [0][1][2][1][RTW89_CN][48] = 127, + [0][1][2][1][RTW89_UK][48] = 127, + [0][1][2][1][RTW89_MEXICO][48] = 127, + [0][1][2][1][RTW89_UKRAINE][48] = 127, + [0][1][2][1][RTW89_CHILE][48] = 127, + [0][1][2][1][RTW89_QATAR][48] = 127, + [0][1][2][1][RTW89_THAILAND][48] = 127, + [0][1][2][1][RTW89_FCC][50] = 50, + [0][1][2][1][RTW89_ETSI][50] = 127, + [0][1][2][1][RTW89_MKK][50] = 127, + [0][1][2][1][RTW89_IC][50] = 50, + [0][1][2][1][RTW89_KCC][50] = 127, + [0][1][2][1][RTW89_ACMA][50] = 127, + [0][1][2][1][RTW89_CN][50] = 127, + [0][1][2][1][RTW89_UK][50] = 127, + [0][1][2][1][RTW89_MEXICO][50] = 127, + [0][1][2][1][RTW89_UKRAINE][50] = 127, + [0][1][2][1][RTW89_CHILE][50] = 127, + [0][1][2][1][RTW89_QATAR][50] = 127, + [0][1][2][1][RTW89_THAILAND][50] = 127, + [0][1][2][1][RTW89_FCC][52] = 48, + [0][1][2][1][RTW89_ETSI][52] = 127, + [0][1][2][1][RTW89_MKK][52] = 127, + [0][1][2][1][RTW89_IC][52] = 48, + [0][1][2][1][RTW89_KCC][52] = 127, + [0][1][2][1][RTW89_ACMA][52] = 127, + [0][1][2][1][RTW89_CN][52] = 127, + [0][1][2][1][RTW89_UK][52] = 127, + [0][1][2][1][RTW89_MEXICO][52] = 127, + [0][1][2][1][RTW89_UKRAINE][52] = 127, + [0][1][2][1][RTW89_CHILE][52] = 127, + [0][1][2][1][RTW89_QATAR][52] = 127, + [0][1][2][1][RTW89_THAILAND][52] = 127, + [1][0][2][0][RTW89_FCC][1] = 64, + [1][0][2][0][RTW89_ETSI][1] = 66, + [1][0][2][0][RTW89_MKK][1] = 66, + [1][0][2][0][RTW89_IC][1] = 62, + [1][0][2][0][RTW89_KCC][1] = 54, + [1][0][2][0][RTW89_ACMA][1] = 66, + [1][0][2][0][RTW89_CN][1] = 54, + [1][0][2][0][RTW89_UK][1] = 66, + [1][0][2][0][RTW89_MEXICO][1] = 62, + [1][0][2][0][RTW89_UKRAINE][1] = 54, + [1][0][2][0][RTW89_CHILE][1] = 62, + [1][0][2][0][RTW89_QATAR][1] = 66, + [1][0][2][0][RTW89_THAILAND][1] = 66, + [1][0][2][0][RTW89_FCC][5] = 68, + [1][0][2][0][RTW89_ETSI][5] = 66, + [1][0][2][0][RTW89_MKK][5] = 66, + [1][0][2][0][RTW89_IC][5] = 64, + [1][0][2][0][RTW89_KCC][5] = 66, + [1][0][2][0][RTW89_ACMA][5] = 66, + [1][0][2][0][RTW89_CN][5] = 54, + [1][0][2][0][RTW89_UK][5] = 66, + [1][0][2][0][RTW89_MEXICO][5] = 62, + [1][0][2][0][RTW89_UKRAINE][5] = 54, + [1][0][2][0][RTW89_CHILE][5] = 66, + [1][0][2][0][RTW89_QATAR][5] = 66, + [1][0][2][0][RTW89_THAILAND][5] = 66, + [1][0][2][0][RTW89_FCC][9] = 68, + [1][0][2][0][RTW89_ETSI][9] = 66, + [1][0][2][0][RTW89_MKK][9] = 66, + [1][0][2][0][RTW89_IC][9] = 64, + [1][0][2][0][RTW89_KCC][9] = 66, + [1][0][2][0][RTW89_ACMA][9] = 66, + [1][0][2][0][RTW89_CN][9] = 54, + [1][0][2][0][RTW89_UK][9] = 66, + [1][0][2][0][RTW89_MEXICO][9] = 68, + [1][0][2][0][RTW89_UKRAINE][9] = 54, + [1][0][2][0][RTW89_CHILE][9] = 66, + [1][0][2][0][RTW89_QATAR][9] = 66, + [1][0][2][0][RTW89_THAILAND][9] = 66, + [1][0][2][0][RTW89_FCC][13] = 60, + [1][0][2][0][RTW89_ETSI][13] = 66, + [1][0][2][0][RTW89_MKK][13] = 66, + [1][0][2][0][RTW89_IC][13] = 60, + [1][0][2][0][RTW89_KCC][13] = 52, + [1][0][2][0][RTW89_ACMA][13] = 66, + [1][0][2][0][RTW89_CN][13] = 54, + [1][0][2][0][RTW89_UK][13] = 66, + [1][0][2][0][RTW89_MEXICO][13] = 60, + [1][0][2][0][RTW89_UKRAINE][13] = 54, + [1][0][2][0][RTW89_CHILE][13] = 60, + [1][0][2][0][RTW89_QATAR][13] = 66, + [1][0][2][0][RTW89_THAILAND][13] = 66, + [1][0][2][0][RTW89_FCC][16] = 64, + [1][0][2][0][RTW89_ETSI][16] = 66, + [1][0][2][0][RTW89_MKK][16] = 66, + [1][0][2][0][RTW89_IC][16] = 64, + [1][0][2][0][RTW89_KCC][16] = 56, + [1][0][2][0][RTW89_ACMA][16] = 66, + [1][0][2][0][RTW89_CN][16] = 127, + [1][0][2][0][RTW89_UK][16] = 66, + [1][0][2][0][RTW89_MEXICO][16] = 64, + [1][0][2][0][RTW89_UKRAINE][16] = 54, + [1][0][2][0][RTW89_CHILE][16] = 64, + [1][0][2][0][RTW89_QATAR][16] = 66, + [1][0][2][0][RTW89_THAILAND][16] = 66, + [1][0][2][0][RTW89_FCC][20] = 68, + [1][0][2][0][RTW89_ETSI][20] = 66, + [1][0][2][0][RTW89_MKK][20] = 66, + [1][0][2][0][RTW89_IC][20] = 68, + [1][0][2][0][RTW89_KCC][20] = 56, + [1][0][2][0][RTW89_ACMA][20] = 66, + [1][0][2][0][RTW89_CN][20] = 127, + [1][0][2][0][RTW89_UK][20] = 66, + [1][0][2][0][RTW89_MEXICO][20] = 68, + [1][0][2][0][RTW89_UKRAINE][20] = 54, + [1][0][2][0][RTW89_CHILE][20] = 66, + [1][0][2][0][RTW89_QATAR][20] = 66, + [1][0][2][0][RTW89_THAILAND][20] = 66, + [1][0][2][0][RTW89_FCC][24] = 68, + [1][0][2][0][RTW89_ETSI][24] = 66, + [1][0][2][0][RTW89_MKK][24] = 66, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_KCC][24] = 56, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_CN][24] = 127, + [1][0][2][0][RTW89_UK][24] = 66, + [1][0][2][0][RTW89_MEXICO][24] = 68, + [1][0][2][0][RTW89_UKRAINE][24] = 54, + [1][0][2][0][RTW89_CHILE][24] = 66, + [1][0][2][0][RTW89_QATAR][24] = 66, + [1][0][2][0][RTW89_THAILAND][24] = 66, + [1][0][2][0][RTW89_FCC][28] = 68, + [1][0][2][0][RTW89_ETSI][28] = 66, + [1][0][2][0][RTW89_MKK][28] = 66, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_KCC][28] = 66, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_CN][28] = 127, + [1][0][2][0][RTW89_UK][28] = 66, + [1][0][2][0][RTW89_MEXICO][28] = 68, + [1][0][2][0][RTW89_UKRAINE][28] = 54, + [1][0][2][0][RTW89_CHILE][28] = 62, + [1][0][2][0][RTW89_QATAR][28] = 66, + [1][0][2][0][RTW89_THAILAND][28] = 66, + [1][0][2][0][RTW89_FCC][32] = 62, + [1][0][2][0][RTW89_ETSI][32] = 66, + [1][0][2][0][RTW89_MKK][32] = 66, + [1][0][2][0][RTW89_IC][32] = 62, + [1][0][2][0][RTW89_KCC][32] = 66, + [1][0][2][0][RTW89_ACMA][32] = 66, + [1][0][2][0][RTW89_CN][32] = 127, + [1][0][2][0][RTW89_UK][32] = 66, + [1][0][2][0][RTW89_MEXICO][32] = 62, + [1][0][2][0][RTW89_UKRAINE][32] = 54, + [1][0][2][0][RTW89_CHILE][32] = 62, + [1][0][2][0][RTW89_QATAR][32] = 66, + [1][0][2][0][RTW89_THAILAND][32] = 66, + [1][0][2][0][RTW89_FCC][36] = 68, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 66, + [1][0][2][0][RTW89_IC][36] = 68, + [1][0][2][0][RTW89_KCC][36] = 66, + [1][0][2][0][RTW89_ACMA][36] = 66, + [1][0][2][0][RTW89_CN][36] = 127, + [1][0][2][0][RTW89_UK][36] = 64, + [1][0][2][0][RTW89_MEXICO][36] = 68, + [1][0][2][0][RTW89_UKRAINE][36] = 127, + [1][0][2][0][RTW89_CHILE][36] = 66, + [1][0][2][0][RTW89_QATAR][36] = 127, + [1][0][2][0][RTW89_THAILAND][36] = 127, + [1][0][2][0][RTW89_FCC][39] = 68, + [1][0][2][0][RTW89_ETSI][39] = 30, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 68, + [1][0][2][0][RTW89_KCC][39] = 66, + [1][0][2][0][RTW89_ACMA][39] = 66, + [1][0][2][0][RTW89_CN][39] = 52, + [1][0][2][0][RTW89_UK][39] = 64, + [1][0][2][0][RTW89_MEXICO][39] = 68, + [1][0][2][0][RTW89_UKRAINE][39] = 30, + [1][0][2][0][RTW89_CHILE][39] = 66, + [1][0][2][0][RTW89_QATAR][39] = 30, + [1][0][2][0][RTW89_THAILAND][39] = 30, + [1][0][2][0][RTW89_FCC][43] = 68, + [1][0][2][0][RTW89_ETSI][43] = 30, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 68, + [1][0][2][0][RTW89_KCC][43] = 66, + [1][0][2][0][RTW89_ACMA][43] = 66, + [1][0][2][0][RTW89_CN][43] = 52, + [1][0][2][0][RTW89_UK][43] = 64, + [1][0][2][0][RTW89_MEXICO][43] = 68, + [1][0][2][0][RTW89_UKRAINE][43] = 30, + [1][0][2][0][RTW89_CHILE][43] = 66, + [1][0][2][0][RTW89_QATAR][43] = 30, + [1][0][2][0][RTW89_THAILAND][43] = 30, + [1][0][2][0][RTW89_FCC][47] = 68, + [1][0][2][0][RTW89_ETSI][47] = 127, + [1][0][2][0][RTW89_MKK][47] = 127, + [1][0][2][0][RTW89_IC][47] = 68, + [1][0][2][0][RTW89_KCC][47] = 127, + [1][0][2][0][RTW89_ACMA][47] = 127, + [1][0][2][0][RTW89_CN][47] = 127, + [1][0][2][0][RTW89_UK][47] = 127, + [1][0][2][0][RTW89_MEXICO][47] = 127, + [1][0][2][0][RTW89_UKRAINE][47] = 127, + [1][0][2][0][RTW89_CHILE][47] = 127, + [1][0][2][0][RTW89_QATAR][47] = 127, + [1][0][2][0][RTW89_THAILAND][47] = 127, + [1][0][2][0][RTW89_FCC][51] = 68, + [1][0][2][0][RTW89_ETSI][51] = 127, + [1][0][2][0][RTW89_MKK][51] = 127, + [1][0][2][0][RTW89_IC][51] = 68, + [1][0][2][0][RTW89_KCC][51] = 127, + [1][0][2][0][RTW89_ACMA][51] = 127, + [1][0][2][0][RTW89_CN][51] = 127, + [1][0][2][0][RTW89_UK][51] = 127, + [1][0][2][0][RTW89_MEXICO][51] = 127, + [1][0][2][0][RTW89_UKRAINE][51] = 127, + [1][0][2][0][RTW89_CHILE][51] = 127, + [1][0][2][0][RTW89_QATAR][51] = 127, + [1][0][2][0][RTW89_THAILAND][51] = 127, + [1][1][2][0][RTW89_FCC][1] = 54, + [1][1][2][0][RTW89_ETSI][1] = 54, + [1][1][2][0][RTW89_MKK][1] = 48, + [1][1][2][0][RTW89_IC][1] = 48, + [1][1][2][0][RTW89_KCC][1] = 54, + [1][1][2][0][RTW89_ACMA][1] = 54, + [1][1][2][0][RTW89_CN][1] = 42, + [1][1][2][0][RTW89_UK][1] = 54, + [1][1][2][0][RTW89_MEXICO][1] = 50, + [1][1][2][0][RTW89_UKRAINE][1] = 42, + [1][1][2][0][RTW89_CHILE][1] = 54, + [1][1][2][0][RTW89_QATAR][1] = 54, + [1][1][2][0][RTW89_THAILAND][1] = 54, + [1][1][2][0][RTW89_FCC][5] = 68, + [1][1][2][0][RTW89_ETSI][5] = 54, + [1][1][2][0][RTW89_MKK][5] = 52, + [1][1][2][0][RTW89_IC][5] = 48, + [1][1][2][0][RTW89_KCC][5] = 54, + [1][1][2][0][RTW89_ACMA][5] = 54, + [1][1][2][0][RTW89_CN][5] = 42, + [1][1][2][0][RTW89_UK][5] = 54, + [1][1][2][0][RTW89_MEXICO][5] = 50, + [1][1][2][0][RTW89_UKRAINE][5] = 42, + [1][1][2][0][RTW89_CHILE][5] = 66, + [1][1][2][0][RTW89_QATAR][5] = 54, + [1][1][2][0][RTW89_THAILAND][5] = 54, + [1][1][2][0][RTW89_FCC][9] = 68, + [1][1][2][0][RTW89_ETSI][9] = 54, + [1][1][2][0][RTW89_MKK][9] = 52, + [1][1][2][0][RTW89_IC][9] = 52, + [1][1][2][0][RTW89_KCC][9] = 64, + [1][1][2][0][RTW89_ACMA][9] = 54, + [1][1][2][0][RTW89_CN][9] = 42, + [1][1][2][0][RTW89_UK][9] = 54, + [1][1][2][0][RTW89_MEXICO][9] = 68, + [1][1][2][0][RTW89_UKRAINE][9] = 42, + [1][1][2][0][RTW89_CHILE][9] = 66, + [1][1][2][0][RTW89_QATAR][9] = 54, + [1][1][2][0][RTW89_THAILAND][9] = 54, + [1][1][2][0][RTW89_FCC][13] = 54, + [1][1][2][0][RTW89_ETSI][13] = 54, + [1][1][2][0][RTW89_MKK][13] = 52, + [1][1][2][0][RTW89_IC][13] = 52, + [1][1][2][0][RTW89_KCC][13] = 52, + [1][1][2][0][RTW89_ACMA][13] = 54, + [1][1][2][0][RTW89_CN][13] = 42, + [1][1][2][0][RTW89_UK][13] = 54, + [1][1][2][0][RTW89_MEXICO][13] = 54, + [1][1][2][0][RTW89_UKRAINE][13] = 42, + [1][1][2][0][RTW89_CHILE][13] = 54, + [1][1][2][0][RTW89_QATAR][13] = 54, + [1][1][2][0][RTW89_THAILAND][13] = 54, + [1][1][2][0][RTW89_FCC][16] = 56, + [1][1][2][0][RTW89_ETSI][16] = 54, + [1][1][2][0][RTW89_MKK][16] = 66, + [1][1][2][0][RTW89_IC][16] = 56, + [1][1][2][0][RTW89_KCC][16] = 54, + [1][1][2][0][RTW89_ACMA][16] = 54, + [1][1][2][0][RTW89_CN][16] = 127, + [1][1][2][0][RTW89_UK][16] = 54, + [1][1][2][0][RTW89_MEXICO][16] = 56, + [1][1][2][0][RTW89_UKRAINE][16] = 42, + [1][1][2][0][RTW89_CHILE][16] = 54, + [1][1][2][0][RTW89_QATAR][16] = 54, + [1][1][2][0][RTW89_THAILAND][16] = 54, + [1][1][2][0][RTW89_FCC][20] = 68, + [1][1][2][0][RTW89_ETSI][20] = 54, + [1][1][2][0][RTW89_MKK][20] = 66, + [1][1][2][0][RTW89_IC][20] = 68, + [1][1][2][0][RTW89_KCC][20] = 54, + [1][1][2][0][RTW89_ACMA][20] = 54, + [1][1][2][0][RTW89_CN][20] = 127, + [1][1][2][0][RTW89_UK][20] = 54, + [1][1][2][0][RTW89_MEXICO][20] = 68, + [1][1][2][0][RTW89_UKRAINE][20] = 42, + [1][1][2][0][RTW89_CHILE][20] = 66, + [1][1][2][0][RTW89_QATAR][20] = 54, + [1][1][2][0][RTW89_THAILAND][20] = 54, + [1][1][2][0][RTW89_FCC][24] = 68, + [1][1][2][0][RTW89_ETSI][24] = 54, + [1][1][2][0][RTW89_MKK][24] = 66, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_KCC][24] = 54, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_CN][24] = 127, + [1][1][2][0][RTW89_UK][24] = 54, + [1][1][2][0][RTW89_MEXICO][24] = 68, + [1][1][2][0][RTW89_UKRAINE][24] = 42, + [1][1][2][0][RTW89_CHILE][24] = 66, + [1][1][2][0][RTW89_QATAR][24] = 54, + [1][1][2][0][RTW89_THAILAND][24] = 54, + [1][1][2][0][RTW89_FCC][28] = 68, + [1][1][2][0][RTW89_ETSI][28] = 54, + [1][1][2][0][RTW89_MKK][28] = 66, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_KCC][28] = 66, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_CN][28] = 127, + [1][1][2][0][RTW89_UK][28] = 54, + [1][1][2][0][RTW89_MEXICO][28] = 68, + [1][1][2][0][RTW89_UKRAINE][28] = 42, + [1][1][2][0][RTW89_CHILE][28] = 54, + [1][1][2][0][RTW89_QATAR][28] = 54, + [1][1][2][0][RTW89_THAILAND][28] = 54, + [1][1][2][0][RTW89_FCC][32] = 56, + [1][1][2][0][RTW89_ETSI][32] = 54, + [1][1][2][0][RTW89_MKK][32] = 66, + [1][1][2][0][RTW89_IC][32] = 56, + [1][1][2][0][RTW89_KCC][32] = 66, + [1][1][2][0][RTW89_ACMA][32] = 54, + [1][1][2][0][RTW89_CN][32] = 127, + [1][1][2][0][RTW89_UK][32] = 54, + [1][1][2][0][RTW89_MEXICO][32] = 56, + [1][1][2][0][RTW89_UKRAINE][32] = 42, + [1][1][2][0][RTW89_CHILE][32] = 54, + [1][1][2][0][RTW89_QATAR][32] = 54, + [1][1][2][0][RTW89_THAILAND][32] = 54, + [1][1][2][0][RTW89_FCC][36] = 68, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 66, + [1][1][2][0][RTW89_IC][36] = 68, + [1][1][2][0][RTW89_KCC][36] = 66, + [1][1][2][0][RTW89_ACMA][36] = 66, + [1][1][2][0][RTW89_CN][36] = 127, + [1][1][2][0][RTW89_UK][36] = 52, + [1][1][2][0][RTW89_MEXICO][36] = 68, + [1][1][2][0][RTW89_UKRAINE][36] = 127, + [1][1][2][0][RTW89_CHILE][36] = 66, + [1][1][2][0][RTW89_QATAR][36] = 127, + [1][1][2][0][RTW89_THAILAND][36] = 127, + [1][1][2][0][RTW89_FCC][39] = 68, + [1][1][2][0][RTW89_ETSI][39] = 18, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 68, + [1][1][2][0][RTW89_KCC][39] = 56, + [1][1][2][0][RTW89_ACMA][39] = 66, + [1][1][2][0][RTW89_CN][39] = 52, + [1][1][2][0][RTW89_UK][39] = 52, + [1][1][2][0][RTW89_MEXICO][39] = 68, + [1][1][2][0][RTW89_UKRAINE][39] = 18, + [1][1][2][0][RTW89_CHILE][39] = 66, + [1][1][2][0][RTW89_QATAR][39] = 18, + [1][1][2][0][RTW89_THAILAND][39] = 18, + [1][1][2][0][RTW89_FCC][43] = 68, + [1][1][2][0][RTW89_ETSI][43] = 18, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 68, + [1][1][2][0][RTW89_KCC][43] = 56, + [1][1][2][0][RTW89_ACMA][43] = 66, + [1][1][2][0][RTW89_CN][43] = 52, + [1][1][2][0][RTW89_UK][43] = 52, + [1][1][2][0][RTW89_MEXICO][43] = 68, + [1][1][2][0][RTW89_UKRAINE][43] = 18, + [1][1][2][0][RTW89_CHILE][43] = 66, + [1][1][2][0][RTW89_QATAR][43] = 18, + [1][1][2][0][RTW89_THAILAND][43] = 18, + [1][1][2][0][RTW89_FCC][47] = 62, + [1][1][2][0][RTW89_ETSI][47] = 127, + [1][1][2][0][RTW89_MKK][47] = 127, + [1][1][2][0][RTW89_IC][47] = 62, + [1][1][2][0][RTW89_KCC][47] = 127, + [1][1][2][0][RTW89_ACMA][47] = 127, + [1][1][2][0][RTW89_CN][47] = 127, + [1][1][2][0][RTW89_UK][47] = 127, + [1][1][2][0][RTW89_MEXICO][47] = 127, + [1][1][2][0][RTW89_UKRAINE][47] = 127, + [1][1][2][0][RTW89_CHILE][47] = 127, + [1][1][2][0][RTW89_QATAR][47] = 127, + [1][1][2][0][RTW89_THAILAND][47] = 127, + [1][1][2][0][RTW89_FCC][51] = 60, + [1][1][2][0][RTW89_ETSI][51] = 127, + [1][1][2][0][RTW89_MKK][51] = 127, + [1][1][2][0][RTW89_IC][51] = 60, + [1][1][2][0][RTW89_KCC][51] = 127, + [1][1][2][0][RTW89_ACMA][51] = 127, + [1][1][2][0][RTW89_CN][51] = 127, + [1][1][2][0][RTW89_UK][51] = 127, + [1][1][2][0][RTW89_MEXICO][51] = 127, + [1][1][2][0][RTW89_UKRAINE][51] = 127, + [1][1][2][0][RTW89_CHILE][51] = 127, + [1][1][2][0][RTW89_QATAR][51] = 127, + [1][1][2][0][RTW89_THAILAND][51] = 127, + [1][1][2][1][RTW89_FCC][1] = 54, + [1][1][2][1][RTW89_ETSI][1] = 40, + [1][1][2][1][RTW89_MKK][1] = 48, + [1][1][2][1][RTW89_IC][1] = 40, + [1][1][2][1][RTW89_KCC][1] = 54, + [1][1][2][1][RTW89_ACMA][1] = 40, + [1][1][2][1][RTW89_CN][1] = 42, + [1][1][2][1][RTW89_UK][1] = 40, + [1][1][2][1][RTW89_MEXICO][1] = 50, + [1][1][2][1][RTW89_UKRAINE][1] = 30, + [1][1][2][1][RTW89_CHILE][1] = 54, + [1][1][2][1][RTW89_QATAR][1] = 40, + [1][1][2][1][RTW89_THAILAND][1] = 40, + [1][1][2][1][RTW89_FCC][5] = 68, + [1][1][2][1][RTW89_ETSI][5] = 40, + [1][1][2][1][RTW89_MKK][5] = 52, + [1][1][2][1][RTW89_IC][5] = 40, + [1][1][2][1][RTW89_KCC][5] = 54, + [1][1][2][1][RTW89_ACMA][5] = 40, + [1][1][2][1][RTW89_CN][5] = 42, + [1][1][2][1][RTW89_UK][5] = 40, + [1][1][2][1][RTW89_MEXICO][5] = 50, + [1][1][2][1][RTW89_UKRAINE][5] = 30, + [1][1][2][1][RTW89_CHILE][5] = 60, + [1][1][2][1][RTW89_QATAR][5] = 40, + [1][1][2][1][RTW89_THAILAND][5] = 40, + [1][1][2][1][RTW89_FCC][9] = 68, + [1][1][2][1][RTW89_ETSI][9] = 40, + [1][1][2][1][RTW89_MKK][9] = 52, + [1][1][2][1][RTW89_IC][9] = 40, + [1][1][2][1][RTW89_KCC][9] = 64, + [1][1][2][1][RTW89_ACMA][9] = 40, + [1][1][2][1][RTW89_CN][9] = 42, + [1][1][2][1][RTW89_UK][9] = 40, + [1][1][2][1][RTW89_MEXICO][9] = 68, + [1][1][2][1][RTW89_UKRAINE][9] = 30, + [1][1][2][1][RTW89_CHILE][9] = 60, + [1][1][2][1][RTW89_QATAR][9] = 40, + [1][1][2][1][RTW89_THAILAND][9] = 40, + [1][1][2][1][RTW89_FCC][13] = 54, + [1][1][2][1][RTW89_ETSI][13] = 40, + [1][1][2][1][RTW89_MKK][13] = 52, + [1][1][2][1][RTW89_IC][13] = 40, + [1][1][2][1][RTW89_KCC][13] = 52, + [1][1][2][1][RTW89_ACMA][13] = 40, + [1][1][2][1][RTW89_CN][13] = 42, + [1][1][2][1][RTW89_UK][13] = 40, + [1][1][2][1][RTW89_MEXICO][13] = 54, + [1][1][2][1][RTW89_UKRAINE][13] = 30, + [1][1][2][1][RTW89_CHILE][13] = 54, + [1][1][2][1][RTW89_QATAR][13] = 40, + [1][1][2][1][RTW89_THAILAND][13] = 40, + [1][1][2][1][RTW89_FCC][16] = 56, + [1][1][2][1][RTW89_ETSI][16] = 40, + [1][1][2][1][RTW89_MKK][16] = 66, + [1][1][2][1][RTW89_IC][16] = 56, + [1][1][2][1][RTW89_KCC][16] = 54, + [1][1][2][1][RTW89_ACMA][16] = 40, + [1][1][2][1][RTW89_CN][16] = 127, + [1][1][2][1][RTW89_UK][16] = 40, + [1][1][2][1][RTW89_MEXICO][16] = 56, + [1][1][2][1][RTW89_UKRAINE][16] = 30, + [1][1][2][1][RTW89_CHILE][16] = 54, + [1][1][2][1][RTW89_QATAR][16] = 40, + [1][1][2][1][RTW89_THAILAND][16] = 40, + [1][1][2][1][RTW89_FCC][20] = 68, + [1][1][2][1][RTW89_ETSI][20] = 40, + [1][1][2][1][RTW89_MKK][20] = 66, + [1][1][2][1][RTW89_IC][20] = 68, + [1][1][2][1][RTW89_KCC][20] = 54, + [1][1][2][1][RTW89_ACMA][20] = 40, + [1][1][2][1][RTW89_CN][20] = 127, + [1][1][2][1][RTW89_UK][20] = 40, + [1][1][2][1][RTW89_MEXICO][20] = 68, + [1][1][2][1][RTW89_UKRAINE][20] = 30, + [1][1][2][1][RTW89_CHILE][20] = 60, + [1][1][2][1][RTW89_QATAR][20] = 40, + [1][1][2][1][RTW89_THAILAND][20] = 40, + [1][1][2][1][RTW89_FCC][24] = 68, + [1][1][2][1][RTW89_ETSI][24] = 40, + [1][1][2][1][RTW89_MKK][24] = 66, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_KCC][24] = 54, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_CN][24] = 127, + [1][1][2][1][RTW89_UK][24] = 40, + [1][1][2][1][RTW89_MEXICO][24] = 68, + [1][1][2][1][RTW89_UKRAINE][24] = 30, + [1][1][2][1][RTW89_CHILE][24] = 60, + [1][1][2][1][RTW89_QATAR][24] = 40, + [1][1][2][1][RTW89_THAILAND][24] = 40, + [1][1][2][1][RTW89_FCC][28] = 68, + [1][1][2][1][RTW89_ETSI][28] = 40, + [1][1][2][1][RTW89_MKK][28] = 66, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_KCC][28] = 66, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_CN][28] = 127, + [1][1][2][1][RTW89_UK][28] = 40, + [1][1][2][1][RTW89_MEXICO][28] = 68, + [1][1][2][1][RTW89_UKRAINE][28] = 30, + [1][1][2][1][RTW89_CHILE][28] = 54, + [1][1][2][1][RTW89_QATAR][28] = 40, + [1][1][2][1][RTW89_THAILAND][28] = 40, + [1][1][2][1][RTW89_FCC][32] = 56, + [1][1][2][1][RTW89_ETSI][32] = 40, + [1][1][2][1][RTW89_MKK][32] = 66, + [1][1][2][1][RTW89_IC][32] = 56, + [1][1][2][1][RTW89_KCC][32] = 66, + [1][1][2][1][RTW89_ACMA][32] = 40, + [1][1][2][1][RTW89_CN][32] = 127, + [1][1][2][1][RTW89_UK][32] = 40, + [1][1][2][1][RTW89_MEXICO][32] = 56, + [1][1][2][1][RTW89_UKRAINE][32] = 30, + [1][1][2][1][RTW89_CHILE][32] = 54, + [1][1][2][1][RTW89_QATAR][32] = 40, + [1][1][2][1][RTW89_THAILAND][32] = 40, + [1][1][2][1][RTW89_FCC][36] = 68, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 66, + [1][1][2][1][RTW89_IC][36] = 68, + [1][1][2][1][RTW89_KCC][36] = 66, + [1][1][2][1][RTW89_ACMA][36] = 66, + [1][1][2][1][RTW89_CN][36] = 127, + [1][1][2][1][RTW89_UK][36] = 40, + [1][1][2][1][RTW89_MEXICO][36] = 68, + [1][1][2][1][RTW89_UKRAINE][36] = 127, + [1][1][2][1][RTW89_CHILE][36] = 66, + [1][1][2][1][RTW89_QATAR][36] = 127, + [1][1][2][1][RTW89_THAILAND][36] = 127, + [1][1][2][1][RTW89_FCC][39] = 68, + [1][1][2][1][RTW89_ETSI][39] = 6, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 68, + [1][1][2][1][RTW89_KCC][39] = 56, + [1][1][2][1][RTW89_ACMA][39] = 66, + [1][1][2][1][RTW89_CN][39] = 52, + [1][1][2][1][RTW89_UK][39] = 40, + [1][1][2][1][RTW89_MEXICO][39] = 68, + [1][1][2][1][RTW89_UKRAINE][39] = 6, + [1][1][2][1][RTW89_CHILE][39] = 60, + [1][1][2][1][RTW89_QATAR][39] = 6, + [1][1][2][1][RTW89_THAILAND][39] = 6, + [1][1][2][1][RTW89_FCC][43] = 68, + [1][1][2][1][RTW89_ETSI][43] = 6, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 68, + [1][1][2][1][RTW89_KCC][43] = 56, + [1][1][2][1][RTW89_ACMA][43] = 66, + [1][1][2][1][RTW89_CN][43] = 52, + [1][1][2][1][RTW89_UK][43] = 40, + [1][1][2][1][RTW89_MEXICO][43] = 68, + [1][1][2][1][RTW89_UKRAINE][43] = 6, + [1][1][2][1][RTW89_CHILE][43] = 60, + [1][1][2][1][RTW89_QATAR][43] = 6, + [1][1][2][1][RTW89_THAILAND][43] = 6, + [1][1][2][1][RTW89_FCC][47] = 62, + [1][1][2][1][RTW89_ETSI][47] = 127, + [1][1][2][1][RTW89_MKK][47] = 127, + [1][1][2][1][RTW89_IC][47] = 62, + [1][1][2][1][RTW89_KCC][47] = 127, + [1][1][2][1][RTW89_ACMA][47] = 127, + [1][1][2][1][RTW89_CN][47] = 127, + [1][1][2][1][RTW89_UK][47] = 127, + [1][1][2][1][RTW89_MEXICO][47] = 127, + [1][1][2][1][RTW89_UKRAINE][47] = 127, + [1][1][2][1][RTW89_CHILE][47] = 127, + [1][1][2][1][RTW89_QATAR][47] = 127, + [1][1][2][1][RTW89_THAILAND][47] = 127, + [1][1][2][1][RTW89_FCC][51] = 60, + [1][1][2][1][RTW89_ETSI][51] = 127, + [1][1][2][1][RTW89_MKK][51] = 127, + [1][1][2][1][RTW89_IC][51] = 60, + [1][1][2][1][RTW89_KCC][51] = 127, + [1][1][2][1][RTW89_ACMA][51] = 127, + [1][1][2][1][RTW89_CN][51] = 127, + [1][1][2][1][RTW89_UK][51] = 127, + [1][1][2][1][RTW89_MEXICO][51] = 127, + [1][1][2][1][RTW89_UKRAINE][51] = 127, + [1][1][2][1][RTW89_CHILE][51] = 127, + [1][1][2][1][RTW89_QATAR][51] = 127, + [1][1][2][1][RTW89_THAILAND][51] = 127, + [2][0][2][0][RTW89_FCC][3] = 58, + [2][0][2][0][RTW89_ETSI][3] = 60, + [2][0][2][0][RTW89_MKK][3] = 60, + [2][0][2][0][RTW89_IC][3] = 56, + [2][0][2][0][RTW89_KCC][3] = 60, + [2][0][2][0][RTW89_ACMA][3] = 60, + [2][0][2][0][RTW89_CN][3] = 54, + [2][0][2][0][RTW89_UK][3] = 60, + [2][0][2][0][RTW89_MEXICO][3] = 58, + [2][0][2][0][RTW89_UKRAINE][3] = 54, + [2][0][2][0][RTW89_CHILE][3] = 58, + [2][0][2][0][RTW89_QATAR][3] = 60, + [2][0][2][0][RTW89_THAILAND][3] = 60, + [2][0][2][0][RTW89_FCC][11] = 50, + [2][0][2][0][RTW89_ETSI][11] = 60, + [2][0][2][0][RTW89_MKK][11] = 60, + [2][0][2][0][RTW89_IC][11] = 50, + [2][0][2][0][RTW89_KCC][11] = 58, + [2][0][2][0][RTW89_ACMA][11] = 60, + [2][0][2][0][RTW89_CN][11] = 54, + [2][0][2][0][RTW89_UK][11] = 60, + [2][0][2][0][RTW89_MEXICO][11] = 50, + [2][0][2][0][RTW89_UKRAINE][11] = 54, + [2][0][2][0][RTW89_CHILE][11] = 50, + [2][0][2][0][RTW89_QATAR][11] = 60, + [2][0][2][0][RTW89_THAILAND][11] = 60, + [2][0][2][0][RTW89_FCC][18] = 60, + [2][0][2][0][RTW89_ETSI][18] = 60, + [2][0][2][0][RTW89_MKK][18] = 60, + [2][0][2][0][RTW89_IC][18] = 60, + [2][0][2][0][RTW89_KCC][18] = 56, + [2][0][2][0][RTW89_ACMA][18] = 60, + [2][0][2][0][RTW89_CN][18] = 127, + [2][0][2][0][RTW89_UK][18] = 60, + [2][0][2][0][RTW89_MEXICO][18] = 60, + [2][0][2][0][RTW89_UKRAINE][18] = 54, + [2][0][2][0][RTW89_CHILE][18] = 60, + [2][0][2][0][RTW89_QATAR][18] = 60, + [2][0][2][0][RTW89_THAILAND][18] = 60, + [2][0][2][0][RTW89_FCC][26] = 62, + [2][0][2][0][RTW89_ETSI][26] = 60, + [2][0][2][0][RTW89_MKK][26] = 60, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_KCC][26] = 60, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_CN][26] = 127, + [2][0][2][0][RTW89_UK][26] = 60, + [2][0][2][0][RTW89_MEXICO][26] = 62, + [2][0][2][0][RTW89_UKRAINE][26] = 54, + [2][0][2][0][RTW89_CHILE][26] = 60, + [2][0][2][0][RTW89_QATAR][26] = 60, + [2][0][2][0][RTW89_THAILAND][26] = 60, + [2][0][2][0][RTW89_FCC][34] = 62, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 60, + [2][0][2][0][RTW89_IC][34] = 62, + [2][0][2][0][RTW89_KCC][34] = 60, + [2][0][2][0][RTW89_ACMA][34] = 60, + [2][0][2][0][RTW89_CN][34] = 127, + [2][0][2][0][RTW89_UK][34] = 60, + [2][0][2][0][RTW89_MEXICO][34] = 62, + [2][0][2][0][RTW89_UKRAINE][34] = 127, + [2][0][2][0][RTW89_CHILE][34] = 60, + [2][0][2][0][RTW89_QATAR][34] = 127, + [2][0][2][0][RTW89_THAILAND][34] = 127, + [2][0][2][0][RTW89_FCC][41] = 62, + [2][0][2][0][RTW89_ETSI][41] = 30, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 62, + [2][0][2][0][RTW89_KCC][41] = 58, + [2][0][2][0][RTW89_ACMA][41] = 60, + [2][0][2][0][RTW89_CN][41] = 42, + [2][0][2][0][RTW89_UK][41] = 60, + [2][0][2][0][RTW89_MEXICO][41] = 62, + [2][0][2][0][RTW89_UKRAINE][41] = 30, + [2][0][2][0][RTW89_CHILE][41] = 60, + [2][0][2][0][RTW89_QATAR][41] = 30, + [2][0][2][0][RTW89_THAILAND][41] = 30, + [2][0][2][0][RTW89_FCC][49] = 62, + [2][0][2][0][RTW89_ETSI][49] = 127, + [2][0][2][0][RTW89_MKK][49] = 127, + [2][0][2][0][RTW89_IC][49] = 62, + [2][0][2][0][RTW89_KCC][49] = 127, + [2][0][2][0][RTW89_ACMA][49] = 127, + [2][0][2][0][RTW89_CN][49] = 127, + [2][0][2][0][RTW89_UK][49] = 127, + [2][0][2][0][RTW89_MEXICO][49] = 127, + [2][0][2][0][RTW89_UKRAINE][49] = 127, + [2][0][2][0][RTW89_CHILE][49] = 127, + [2][0][2][0][RTW89_QATAR][49] = 127, + [2][0][2][0][RTW89_THAILAND][49] = 127, + [2][1][2][0][RTW89_FCC][3] = 48, + [2][1][2][0][RTW89_ETSI][3] = 54, + [2][1][2][0][RTW89_MKK][3] = 56, + [2][1][2][0][RTW89_IC][3] = 46, + [2][1][2][0][RTW89_KCC][3] = 56, + [2][1][2][0][RTW89_ACMA][3] = 54, + [2][1][2][0][RTW89_CN][3] = 52, + [2][1][2][0][RTW89_UK][3] = 54, + [2][1][2][0][RTW89_MEXICO][3] = 48, + [2][1][2][0][RTW89_UKRAINE][3] = 42, + [2][1][2][0][RTW89_CHILE][3] = 46, + [2][1][2][0][RTW89_QATAR][3] = 54, + [2][1][2][0][RTW89_THAILAND][3] = 54, + [2][1][2][0][RTW89_FCC][11] = 38, + [2][1][2][0][RTW89_ETSI][11] = 54, + [2][1][2][0][RTW89_MKK][11] = 54, + [2][1][2][0][RTW89_IC][11] = 38, + [2][1][2][0][RTW89_KCC][11] = 52, + [2][1][2][0][RTW89_ACMA][11] = 54, + [2][1][2][0][RTW89_CN][11] = 50, + [2][1][2][0][RTW89_UK][11] = 54, + [2][1][2][0][RTW89_MEXICO][11] = 38, + [2][1][2][0][RTW89_UKRAINE][11] = 42, + [2][1][2][0][RTW89_CHILE][11] = 38, + [2][1][2][0][RTW89_QATAR][11] = 54, + [2][1][2][0][RTW89_THAILAND][11] = 54, + [2][1][2][0][RTW89_FCC][18] = 50, + [2][1][2][0][RTW89_ETSI][18] = 54, + [2][1][2][0][RTW89_MKK][18] = 60, + [2][1][2][0][RTW89_IC][18] = 50, + [2][1][2][0][RTW89_KCC][18] = 54, + [2][1][2][0][RTW89_ACMA][18] = 54, + [2][1][2][0][RTW89_CN][18] = 127, + [2][1][2][0][RTW89_UK][18] = 54, + [2][1][2][0][RTW89_MEXICO][18] = 50, + [2][1][2][0][RTW89_UKRAINE][18] = 42, + [2][1][2][0][RTW89_CHILE][18] = 50, + [2][1][2][0][RTW89_QATAR][18] = 54, + [2][1][2][0][RTW89_THAILAND][18] = 54, + [2][1][2][0][RTW89_FCC][26] = 52, + [2][1][2][0][RTW89_ETSI][26] = 54, + [2][1][2][0][RTW89_MKK][26] = 56, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_KCC][26] = 60, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_CN][26] = 127, + [2][1][2][0][RTW89_UK][26] = 54, + [2][1][2][0][RTW89_MEXICO][26] = 52, + [2][1][2][0][RTW89_UKRAINE][26] = 42, + [2][1][2][0][RTW89_CHILE][26] = 52, + [2][1][2][0][RTW89_QATAR][26] = 54, + [2][1][2][0][RTW89_THAILAND][26] = 54, + [2][1][2][0][RTW89_FCC][34] = 62, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 60, + [2][1][2][0][RTW89_IC][34] = 62, + [2][1][2][0][RTW89_KCC][34] = 60, + [2][1][2][0][RTW89_ACMA][34] = 60, + [2][1][2][0][RTW89_CN][34] = 127, + [2][1][2][0][RTW89_UK][34] = 52, + [2][1][2][0][RTW89_MEXICO][34] = 62, + [2][1][2][0][RTW89_UKRAINE][34] = 127, + [2][1][2][0][RTW89_CHILE][34] = 60, + [2][1][2][0][RTW89_QATAR][34] = 127, + [2][1][2][0][RTW89_THAILAND][34] = 127, + [2][1][2][0][RTW89_FCC][41] = 60, + [2][1][2][0][RTW89_ETSI][41] = 18, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 60, + [2][1][2][0][RTW89_KCC][41] = 50, + [2][1][2][0][RTW89_ACMA][41] = 58, + [2][1][2][0][RTW89_CN][41] = 42, + [2][1][2][0][RTW89_UK][41] = 52, + [2][1][2][0][RTW89_MEXICO][41] = 60, + [2][1][2][0][RTW89_UKRAINE][41] = 18, + [2][1][2][0][RTW89_CHILE][41] = 58, + [2][1][2][0][RTW89_QATAR][41] = 18, + [2][1][2][0][RTW89_THAILAND][41] = 18, + [2][1][2][0][RTW89_FCC][49] = 62, + [2][1][2][0][RTW89_ETSI][49] = 127, + [2][1][2][0][RTW89_MKK][49] = 127, + [2][1][2][0][RTW89_IC][49] = 62, + [2][1][2][0][RTW89_KCC][49] = 127, + [2][1][2][0][RTW89_ACMA][49] = 127, + [2][1][2][0][RTW89_CN][49] = 127, + [2][1][2][0][RTW89_UK][49] = 127, + [2][1][2][0][RTW89_MEXICO][49] = 127, + [2][1][2][0][RTW89_UKRAINE][49] = 127, + [2][1][2][0][RTW89_CHILE][49] = 127, + [2][1][2][0][RTW89_QATAR][49] = 127, + [2][1][2][0][RTW89_THAILAND][49] = 127, + [2][1][2][1][RTW89_FCC][3] = 48, + [2][1][2][1][RTW89_ETSI][3] = 40, + [2][1][2][1][RTW89_MKK][3] = 56, + [2][1][2][1][RTW89_IC][3] = 40, + [2][1][2][1][RTW89_KCC][3] = 56, + [2][1][2][1][RTW89_ACMA][3] = 40, + [2][1][2][1][RTW89_CN][3] = 42, + [2][1][2][1][RTW89_UK][3] = 40, + [2][1][2][1][RTW89_MEXICO][3] = 48, + [2][1][2][1][RTW89_UKRAINE][3] = 30, + [2][1][2][1][RTW89_CHILE][3] = 46, + [2][1][2][1][RTW89_QATAR][3] = 40, + [2][1][2][1][RTW89_THAILAND][3] = 40, + [2][1][2][1][RTW89_FCC][11] = 38, + [2][1][2][1][RTW89_ETSI][11] = 40, + [2][1][2][1][RTW89_MKK][11] = 54, + [2][1][2][1][RTW89_IC][11] = 38, + [2][1][2][1][RTW89_KCC][11] = 52, + [2][1][2][1][RTW89_ACMA][11] = 40, + [2][1][2][1][RTW89_CN][11] = 42, + [2][1][2][1][RTW89_UK][11] = 40, + [2][1][2][1][RTW89_MEXICO][11] = 38, + [2][1][2][1][RTW89_UKRAINE][11] = 30, + [2][1][2][1][RTW89_CHILE][11] = 38, + [2][1][2][1][RTW89_QATAR][11] = 40, + [2][1][2][1][RTW89_THAILAND][11] = 40, + [2][1][2][1][RTW89_FCC][18] = 50, + [2][1][2][1][RTW89_ETSI][18] = 40, + [2][1][2][1][RTW89_MKK][18] = 60, + [2][1][2][1][RTW89_IC][18] = 50, + [2][1][2][1][RTW89_KCC][18] = 54, + [2][1][2][1][RTW89_ACMA][18] = 40, + [2][1][2][1][RTW89_CN][18] = 127, + [2][1][2][1][RTW89_UK][18] = 40, + [2][1][2][1][RTW89_MEXICO][18] = 50, + [2][1][2][1][RTW89_UKRAINE][18] = 30, + [2][1][2][1][RTW89_CHILE][18] = 50, + [2][1][2][1][RTW89_QATAR][18] = 40, + [2][1][2][1][RTW89_THAILAND][18] = 40, + [2][1][2][1][RTW89_FCC][26] = 52, + [2][1][2][1][RTW89_ETSI][26] = 42, + [2][1][2][1][RTW89_MKK][26] = 56, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_KCC][26] = 60, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_CN][26] = 127, + [2][1][2][1][RTW89_UK][26] = 42, + [2][1][2][1][RTW89_MEXICO][26] = 52, + [2][1][2][1][RTW89_UKRAINE][26] = 30, + [2][1][2][1][RTW89_CHILE][26] = 52, + [2][1][2][1][RTW89_QATAR][26] = 42, + [2][1][2][1][RTW89_THAILAND][26] = 42, + [2][1][2][1][RTW89_FCC][34] = 62, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 60, + [2][1][2][1][RTW89_IC][34] = 62, + [2][1][2][1][RTW89_KCC][34] = 60, + [2][1][2][1][RTW89_ACMA][34] = 60, + [2][1][2][1][RTW89_CN][34] = 127, + [2][1][2][1][RTW89_UK][34] = 40, + [2][1][2][1][RTW89_MEXICO][34] = 62, + [2][1][2][1][RTW89_UKRAINE][34] = 127, + [2][1][2][1][RTW89_CHILE][34] = 60, + [2][1][2][1][RTW89_QATAR][34] = 127, + [2][1][2][1][RTW89_THAILAND][34] = 127, + [2][1][2][1][RTW89_FCC][41] = 60, + [2][1][2][1][RTW89_ETSI][41] = 6, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 60, + [2][1][2][1][RTW89_KCC][41] = 50, + [2][1][2][1][RTW89_ACMA][41] = 58, + [2][1][2][1][RTW89_CN][41] = 36, + [2][1][2][1][RTW89_UK][41] = 40, + [2][1][2][1][RTW89_MEXICO][41] = 60, + [2][1][2][1][RTW89_UKRAINE][41] = 6, + [2][1][2][1][RTW89_CHILE][41] = 58, + [2][1][2][1][RTW89_QATAR][41] = 6, + [2][1][2][1][RTW89_THAILAND][41] = 6, + [2][1][2][1][RTW89_FCC][49] = 62, + [2][1][2][1][RTW89_ETSI][49] = 127, + [2][1][2][1][RTW89_MKK][49] = 127, + [2][1][2][1][RTW89_IC][49] = 62, + [2][1][2][1][RTW89_KCC][49] = 127, + [2][1][2][1][RTW89_ACMA][49] = 127, + [2][1][2][1][RTW89_CN][49] = 127, + [2][1][2][1][RTW89_UK][49] = 127, + [2][1][2][1][RTW89_MEXICO][49] = 127, + [2][1][2][1][RTW89_UKRAINE][49] = 127, + [2][1][2][1][RTW89_CHILE][49] = 127, + [2][1][2][1][RTW89_QATAR][49] = 127, + [2][1][2][1][RTW89_THAILAND][49] = 127, + [3][0][2][0][RTW89_FCC][7] = 40, + [3][0][2][0][RTW89_ETSI][7] = 50, + [3][0][2][0][RTW89_MKK][7] = 50, + [3][0][2][0][RTW89_IC][7] = 40, + [3][0][2][0][RTW89_KCC][7] = 44, + [3][0][2][0][RTW89_ACMA][7] = 127, + [3][0][2][0][RTW89_CN][7] = 66, + [3][0][2][0][RTW89_UK][7] = 127, + [3][0][2][0][RTW89_MEXICO][7] = 127, + [3][0][2][0][RTW89_UKRAINE][7] = 50, + [3][0][2][0][RTW89_CHILE][7] = 40, + [3][0][2][0][RTW89_QATAR][7] = 50, + [3][0][2][0][RTW89_THAILAND][7] = 50, + [3][0][2][0][RTW89_FCC][22] = 42, + [3][0][2][0][RTW89_ETSI][22] = 50, + [3][0][2][0][RTW89_MKK][22] = 50, + [3][0][2][0][RTW89_IC][22] = 127, + [3][0][2][0][RTW89_KCC][22] = 50, + [3][0][2][0][RTW89_ACMA][22] = 127, + [3][0][2][0][RTW89_CN][22] = 127, + [3][0][2][0][RTW89_UK][22] = 127, + [3][0][2][0][RTW89_MEXICO][22] = 127, + [3][0][2][0][RTW89_UKRAINE][22] = 50, + [3][0][2][0][RTW89_CHILE][22] = 42, + [3][0][2][0][RTW89_QATAR][22] = 50, + [3][0][2][0][RTW89_THAILAND][22] = 50, + [3][0][2][0][RTW89_FCC][45] = 52, + [3][0][2][0][RTW89_ETSI][45] = 127, + [3][0][2][0][RTW89_MKK][45] = 127, + [3][0][2][0][RTW89_IC][45] = 52, + [3][0][2][0][RTW89_KCC][45] = 127, + [3][0][2][0][RTW89_ACMA][45] = 127, + [3][0][2][0][RTW89_CN][45] = 127, + [3][0][2][0][RTW89_UK][45] = 127, + [3][0][2][0][RTW89_MEXICO][45] = 127, + [3][0][2][0][RTW89_UKRAINE][45] = 127, + [3][0][2][0][RTW89_CHILE][45] = 127, + [3][0][2][0][RTW89_QATAR][45] = 127, + [3][0][2][0][RTW89_THAILAND][45] = 127, + [3][1][2][0][RTW89_FCC][7] = 32, + [3][1][2][0][RTW89_ETSI][7] = 50, + [3][1][2][0][RTW89_MKK][7] = 36, + [3][1][2][0][RTW89_IC][7] = 44, + [3][1][2][0][RTW89_KCC][7] = 50, + [3][1][2][0][RTW89_ACMA][7] = 127, + [3][1][2][0][RTW89_CN][7] = 54, + [3][1][2][0][RTW89_UK][7] = 127, + [3][1][2][0][RTW89_MEXICO][7] = 127, + [3][1][2][0][RTW89_UKRAINE][7] = 50, + [3][1][2][0][RTW89_CHILE][7] = 32, + [3][1][2][0][RTW89_QATAR][7] = 50, + [3][1][2][0][RTW89_THAILAND][7] = 50, + [3][1][2][0][RTW89_FCC][22] = 36, + [3][1][2][0][RTW89_ETSI][22] = 50, + [3][1][2][0][RTW89_MKK][22] = 48, + [3][1][2][0][RTW89_IC][22] = 127, + [3][1][2][0][RTW89_KCC][22] = 50, + [3][1][2][0][RTW89_ACMA][22] = 127, + [3][1][2][0][RTW89_CN][22] = 127, + [3][1][2][0][RTW89_UK][22] = 127, + [3][1][2][0][RTW89_MEXICO][22] = 127, + [3][1][2][0][RTW89_UKRAINE][22] = 50, + [3][1][2][0][RTW89_CHILE][22] = 36, + [3][1][2][0][RTW89_QATAR][22] = 50, + [3][1][2][0][RTW89_THAILAND][22] = 50, + [3][1][2][0][RTW89_FCC][45] = 46, + [3][1][2][0][RTW89_ETSI][45] = 127, + [3][1][2][0][RTW89_MKK][45] = 127, + [3][1][2][0][RTW89_IC][45] = 46, + [3][1][2][0][RTW89_KCC][45] = 127, + [3][1][2][0][RTW89_ACMA][45] = 127, + [3][1][2][0][RTW89_CN][45] = 127, + [3][1][2][0][RTW89_UK][45] = 127, + [3][1][2][0][RTW89_MEXICO][45] = 127, + [3][1][2][0][RTW89_UKRAINE][45] = 127, + [3][1][2][0][RTW89_CHILE][45] = 127, + [3][1][2][0][RTW89_QATAR][45] = 127, + [3][1][2][0][RTW89_THAILAND][45] = 127, + [3][1][2][1][RTW89_FCC][7] = 32, + [3][1][2][1][RTW89_ETSI][7] = 42, + [3][1][2][1][RTW89_MKK][7] = 36, + [3][1][2][1][RTW89_IC][7] = 44, + [3][1][2][1][RTW89_KCC][7] = 50, + [3][1][2][1][RTW89_ACMA][7] = 127, + [3][1][2][1][RTW89_CN][7] = 42, + [3][1][2][1][RTW89_UK][7] = 127, + [3][1][2][1][RTW89_MEXICO][7] = 127, + [3][1][2][1][RTW89_UKRAINE][7] = 42, + [3][1][2][1][RTW89_CHILE][7] = 32, + [3][1][2][1][RTW89_QATAR][7] = 42, + [3][1][2][1][RTW89_THAILAND][7] = 42, + [3][1][2][1][RTW89_FCC][22] = 36, + [3][1][2][1][RTW89_ETSI][22] = 42, + [3][1][2][1][RTW89_MKK][22] = 48, + [3][1][2][1][RTW89_IC][22] = 127, + [3][1][2][1][RTW89_KCC][22] = 50, + [3][1][2][1][RTW89_ACMA][22] = 127, + [3][1][2][1][RTW89_CN][22] = 127, + [3][1][2][1][RTW89_UK][22] = 127, + [3][1][2][1][RTW89_MEXICO][22] = 127, + [3][1][2][1][RTW89_UKRAINE][22] = 42, + [3][1][2][1][RTW89_CHILE][22] = 36, + [3][1][2][1][RTW89_QATAR][22] = 42, + [3][1][2][1][RTW89_THAILAND][22] = 42, + [3][1][2][1][RTW89_FCC][45] = 46, + [3][1][2][1][RTW89_ETSI][45] = 127, + [3][1][2][1][RTW89_MKK][45] = 127, + [3][1][2][1][RTW89_IC][45] = 46, + [3][1][2][1][RTW89_KCC][45] = 127, + [3][1][2][1][RTW89_ACMA][45] = 127, + [3][1][2][1][RTW89_CN][45] = 127, + [3][1][2][1][RTW89_UK][45] = 127, + [3][1][2][1][RTW89_MEXICO][45] = 127, + [3][1][2][1][RTW89_UKRAINE][45] = 127, + [3][1][2][1][RTW89_CHILE][45] = 127, + [3][1][2][1][RTW89_QATAR][45] = 127, + [3][1][2][1][RTW89_THAILAND][45] = 127, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0][0] = 24, + [0][0][1][0][RTW89_WW][1][0] = 24, + [0][0][1][0][RTW89_WW][0][2] = 22, + [0][0][1][0][RTW89_WW][1][2] = 22, + [0][0][1][0][RTW89_WW][0][4] = 22, + [0][0][1][0][RTW89_WW][1][4] = 22, + [0][0][1][0][RTW89_WW][0][6] = 22, + [0][0][1][0][RTW89_WW][1][6] = 22, + [0][0][1][0][RTW89_WW][0][8] = 22, + [0][0][1][0][RTW89_WW][1][8] = 22, + [0][0][1][0][RTW89_WW][0][10] = 22, + [0][0][1][0][RTW89_WW][1][10] = 22, + [0][0][1][0][RTW89_WW][0][12] = 22, + [0][0][1][0][RTW89_WW][1][12] = 22, + [0][0][1][0][RTW89_WW][0][14] = 22, + [0][0][1][0][RTW89_WW][1][14] = 22, + [0][0][1][0][RTW89_WW][0][15] = 22, + [0][0][1][0][RTW89_WW][1][15] = 22, + [0][0][1][0][RTW89_WW][0][17] = 22, + [0][0][1][0][RTW89_WW][1][17] = 22, + [0][0][1][0][RTW89_WW][0][19] = 22, + [0][0][1][0][RTW89_WW][1][19] = 22, + [0][0][1][0][RTW89_WW][0][21] = 22, + [0][0][1][0][RTW89_WW][1][21] = 22, + [0][0][1][0][RTW89_WW][0][23] = 22, + [0][0][1][0][RTW89_WW][1][23] = 22, + [0][0][1][0][RTW89_WW][0][25] = 22, + [0][0][1][0][RTW89_WW][1][25] = 22, + [0][0][1][0][RTW89_WW][0][27] = 22, + [0][0][1][0][RTW89_WW][1][27] = 22, + [0][0][1][0][RTW89_WW][0][29] = 22, + [0][0][1][0][RTW89_WW][1][29] = 22, + [0][0][1][0][RTW89_WW][0][30] = 22, + [0][0][1][0][RTW89_WW][1][30] = 22, + [0][0][1][0][RTW89_WW][0][32] = 22, + [0][0][1][0][RTW89_WW][1][32] = 22, + [0][0][1][0][RTW89_WW][0][34] = 22, + [0][0][1][0][RTW89_WW][1][34] = 22, + [0][0][1][0][RTW89_WW][0][36] = 22, + [0][0][1][0][RTW89_WW][1][36] = 22, + [0][0][1][0][RTW89_WW][0][38] = 22, + [0][0][1][0][RTW89_WW][1][38] = 22, + [0][0][1][0][RTW89_WW][0][40] = 22, + [0][0][1][0][RTW89_WW][1][40] = 22, + [0][0][1][0][RTW89_WW][0][42] = 22, + [0][0][1][0][RTW89_WW][1][42] = 22, + [0][0][1][0][RTW89_WW][0][44] = 22, + [0][0][1][0][RTW89_WW][1][44] = 22, + [0][0][1][0][RTW89_WW][0][45] = 22, + [0][0][1][0][RTW89_WW][1][45] = 22, + [0][0][1][0][RTW89_WW][0][47] = 22, + [0][0][1][0][RTW89_WW][1][47] = 22, + [0][0][1][0][RTW89_WW][0][49] = 24, + [0][0][1][0][RTW89_WW][1][49] = 24, + [0][0][1][0][RTW89_WW][0][51] = 22, + [0][0][1][0][RTW89_WW][1][51] = 22, + [0][0][1][0][RTW89_WW][0][53] = 22, + [0][0][1][0][RTW89_WW][1][53] = 22, + [0][0][1][0][RTW89_WW][0][55] = 22, + [0][0][1][0][RTW89_WW][1][55] = 22, + [0][0][1][0][RTW89_WW][0][57] = 22, + [0][0][1][0][RTW89_WW][1][57] = 22, + [0][0][1][0][RTW89_WW][0][59] = 22, + [0][0][1][0][RTW89_WW][1][59] = 22, + [0][0][1][0][RTW89_WW][0][60] = 22, + [0][0][1][0][RTW89_WW][1][60] = 22, + [0][0][1][0][RTW89_WW][0][62] = 22, + [0][0][1][0][RTW89_WW][1][62] = 22, + [0][0][1][0][RTW89_WW][0][64] = 22, + [0][0][1][0][RTW89_WW][1][64] = 22, + [0][0][1][0][RTW89_WW][0][66] = 22, + [0][0][1][0][RTW89_WW][1][66] = 22, + [0][0][1][0][RTW89_WW][0][68] = 22, + [0][0][1][0][RTW89_WW][1][68] = 22, + [0][0][1][0][RTW89_WW][0][70] = 24, + [0][0][1][0][RTW89_WW][1][70] = 24, + [0][0][1][0][RTW89_WW][0][72] = 22, + [0][0][1][0][RTW89_WW][1][72] = 22, + [0][0][1][0][RTW89_WW][0][74] = 22, + [0][0][1][0][RTW89_WW][1][74] = 22, + [0][0][1][0][RTW89_WW][0][75] = 22, + [0][0][1][0][RTW89_WW][1][75] = 22, + [0][0][1][0][RTW89_WW][0][77] = 22, + [0][0][1][0][RTW89_WW][1][77] = 22, + [0][0][1][0][RTW89_WW][0][79] = 22, + [0][0][1][0][RTW89_WW][1][79] = 22, + [0][0][1][0][RTW89_WW][0][81] = 22, + [0][0][1][0][RTW89_WW][1][81] = 22, + [0][0][1][0][RTW89_WW][0][83] = 22, + [0][0][1][0][RTW89_WW][1][83] = 22, + [0][0][1][0][RTW89_WW][0][85] = 22, + [0][0][1][0][RTW89_WW][1][85] = 22, + [0][0][1][0][RTW89_WW][0][87] = 22, + [0][0][1][0][RTW89_WW][1][87] = 22, + [0][0][1][0][RTW89_WW][0][89] = 22, + [0][0][1][0][RTW89_WW][1][89] = 22, + [0][0][1][0][RTW89_WW][0][90] = 22, + [0][0][1][0][RTW89_WW][1][90] = 22, + [0][0][1][0][RTW89_WW][0][92] = 22, + [0][0][1][0][RTW89_WW][1][92] = 22, + [0][0][1][0][RTW89_WW][0][94] = 22, + [0][0][1][0][RTW89_WW][1][94] = 22, + [0][0][1][0][RTW89_WW][0][96] = 22, + [0][0][1][0][RTW89_WW][1][96] = 22, + [0][0][1][0][RTW89_WW][0][98] = 22, + [0][0][1][0][RTW89_WW][1][98] = 22, + [0][0][1][0][RTW89_WW][0][100] = 22, + [0][0][1][0][RTW89_WW][1][100] = 22, + [0][0][1][0][RTW89_WW][0][102] = 22, + [0][0][1][0][RTW89_WW][1][102] = 22, + [0][0][1][0][RTW89_WW][0][104] = 22, + [0][0][1][0][RTW89_WW][1][104] = 22, + [0][0][1][0][RTW89_WW][0][105] = 22, + [0][0][1][0][RTW89_WW][1][105] = 22, + [0][0][1][0][RTW89_WW][0][107] = 24, + [0][0][1][0][RTW89_WW][1][107] = 24, + [0][0][1][0][RTW89_WW][0][109] = 24, + [0][0][1][0][RTW89_WW][1][109] = 24, + [0][0][1][0][RTW89_WW][0][111] = 0, + [0][0][1][0][RTW89_WW][1][111] = 0, + [0][0][1][0][RTW89_WW][0][113] = 0, + [0][0][1][0][RTW89_WW][1][113] = 0, + [0][0][1][0][RTW89_WW][0][115] = 0, + [0][0][1][0][RTW89_WW][1][115] = 0, + [0][0][1][0][RTW89_WW][0][117] = 0, + [0][0][1][0][RTW89_WW][1][117] = 0, + [0][0][1][0][RTW89_WW][0][119] = 0, + [0][0][1][0][RTW89_WW][1][119] = 0, + [0][1][1][0][RTW89_WW][0][0] = -2, + [0][1][1][0][RTW89_WW][1][0] = -2, + [0][1][1][0][RTW89_WW][0][2] = -4, + [0][1][1][0][RTW89_WW][1][2] = -4, + [0][1][1][0][RTW89_WW][0][4] = -4, + [0][1][1][0][RTW89_WW][1][4] = -4, + [0][1][1][0][RTW89_WW][0][6] = -4, + [0][1][1][0][RTW89_WW][1][6] = -4, + [0][1][1][0][RTW89_WW][0][8] = -4, + [0][1][1][0][RTW89_WW][1][8] = -4, + [0][1][1][0][RTW89_WW][0][10] = -4, + [0][1][1][0][RTW89_WW][1][10] = -4, + [0][1][1][0][RTW89_WW][0][12] = -4, + [0][1][1][0][RTW89_WW][1][12] = -4, + [0][1][1][0][RTW89_WW][0][14] = -4, + [0][1][1][0][RTW89_WW][1][14] = -4, + [0][1][1][0][RTW89_WW][0][15] = -4, + [0][1][1][0][RTW89_WW][1][15] = -4, + [0][1][1][0][RTW89_WW][0][17] = -4, + [0][1][1][0][RTW89_WW][1][17] = -4, + [0][1][1][0][RTW89_WW][0][19] = -4, + [0][1][1][0][RTW89_WW][1][19] = -4, + [0][1][1][0][RTW89_WW][0][21] = -4, + [0][1][1][0][RTW89_WW][1][21] = -4, + [0][1][1][0][RTW89_WW][0][23] = -4, + [0][1][1][0][RTW89_WW][1][23] = -4, + [0][1][1][0][RTW89_WW][0][25] = -4, + [0][1][1][0][RTW89_WW][1][25] = -4, + [0][1][1][0][RTW89_WW][0][27] = -4, + [0][1][1][0][RTW89_WW][1][27] = -4, + [0][1][1][0][RTW89_WW][0][29] = -4, + [0][1][1][0][RTW89_WW][1][29] = -4, + [0][1][1][0][RTW89_WW][0][30] = -4, + [0][1][1][0][RTW89_WW][1][30] = -4, + [0][1][1][0][RTW89_WW][0][32] = -4, + [0][1][1][0][RTW89_WW][1][32] = -4, + [0][1][1][0][RTW89_WW][0][34] = -4, + [0][1][1][0][RTW89_WW][1][34] = -4, + [0][1][1][0][RTW89_WW][0][36] = -4, + [0][1][1][0][RTW89_WW][1][36] = -4, + [0][1][1][0][RTW89_WW][0][38] = -4, + [0][1][1][0][RTW89_WW][1][38] = -4, + [0][1][1][0][RTW89_WW][0][40] = -4, + [0][1][1][0][RTW89_WW][1][40] = -4, + [0][1][1][0][RTW89_WW][0][42] = -4, + [0][1][1][0][RTW89_WW][1][42] = -4, + [0][1][1][0][RTW89_WW][0][44] = -2, + [0][1][1][0][RTW89_WW][1][44] = -2, + [0][1][1][0][RTW89_WW][0][45] = -2, + [0][1][1][0][RTW89_WW][1][45] = -2, + [0][1][1][0][RTW89_WW][0][47] = -2, + [0][1][1][0][RTW89_WW][1][47] = -2, + [0][1][1][0][RTW89_WW][0][49] = -2, + [0][1][1][0][RTW89_WW][1][49] = -2, + [0][1][1][0][RTW89_WW][0][51] = -2, + [0][1][1][0][RTW89_WW][1][51] = -2, + [0][1][1][0][RTW89_WW][0][53] = -2, + [0][1][1][0][RTW89_WW][1][53] = -2, + [0][1][1][0][RTW89_WW][0][55] = -2, + [0][1][1][0][RTW89_WW][1][55] = -2, + [0][1][1][0][RTW89_WW][0][57] = -2, + [0][1][1][0][RTW89_WW][1][57] = -2, + [0][1][1][0][RTW89_WW][0][59] = -2, + [0][1][1][0][RTW89_WW][1][59] = -2, + [0][1][1][0][RTW89_WW][0][60] = -2, + [0][1][1][0][RTW89_WW][1][60] = -2, + [0][1][1][0][RTW89_WW][0][62] = -2, + [0][1][1][0][RTW89_WW][1][62] = -2, + [0][1][1][0][RTW89_WW][0][64] = -2, + [0][1][1][0][RTW89_WW][1][64] = -2, + [0][1][1][0][RTW89_WW][0][66] = -2, + [0][1][1][0][RTW89_WW][1][66] = -2, + [0][1][1][0][RTW89_WW][0][68] = -2, + [0][1][1][0][RTW89_WW][1][68] = -2, + [0][1][1][0][RTW89_WW][0][70] = -2, + [0][1][1][0][RTW89_WW][1][70] = -2, + [0][1][1][0][RTW89_WW][0][72] = -2, + [0][1][1][0][RTW89_WW][1][72] = -2, + [0][1][1][0][RTW89_WW][0][74] = -2, + [0][1][1][0][RTW89_WW][1][74] = -2, + [0][1][1][0][RTW89_WW][0][75] = -2, + [0][1][1][0][RTW89_WW][1][75] = -2, + [0][1][1][0][RTW89_WW][0][77] = -2, + [0][1][1][0][RTW89_WW][1][77] = -2, + [0][1][1][0][RTW89_WW][0][79] = -2, + [0][1][1][0][RTW89_WW][1][79] = -2, + [0][1][1][0][RTW89_WW][0][81] = -2, + [0][1][1][0][RTW89_WW][1][81] = -2, + [0][1][1][0][RTW89_WW][0][83] = -2, + [0][1][1][0][RTW89_WW][1][83] = -2, + [0][1][1][0][RTW89_WW][0][85] = -2, + [0][1][1][0][RTW89_WW][1][85] = -2, + [0][1][1][0][RTW89_WW][0][87] = -2, + [0][1][1][0][RTW89_WW][1][87] = -2, + [0][1][1][0][RTW89_WW][0][89] = -2, + [0][1][1][0][RTW89_WW][1][89] = -2, + [0][1][1][0][RTW89_WW][0][90] = -2, + [0][1][1][0][RTW89_WW][1][90] = -2, + [0][1][1][0][RTW89_WW][0][92] = -2, + [0][1][1][0][RTW89_WW][1][92] = -2, + [0][1][1][0][RTW89_WW][0][94] = -2, + [0][1][1][0][RTW89_WW][1][94] = -2, + [0][1][1][0][RTW89_WW][0][96] = -2, + [0][1][1][0][RTW89_WW][1][96] = -2, + [0][1][1][0][RTW89_WW][0][98] = -2, + [0][1][1][0][RTW89_WW][1][98] = -2, + [0][1][1][0][RTW89_WW][0][100] = -2, + [0][1][1][0][RTW89_WW][1][100] = -2, + [0][1][1][0][RTW89_WW][0][102] = -2, + [0][1][1][0][RTW89_WW][1][102] = -2, + [0][1][1][0][RTW89_WW][0][104] = -2, + [0][1][1][0][RTW89_WW][1][104] = -2, + [0][1][1][0][RTW89_WW][0][105] = -2, + [0][1][1][0][RTW89_WW][1][105] = -2, + [0][1][1][0][RTW89_WW][0][107] = 1, + [0][1][1][0][RTW89_WW][1][107] = 1, + [0][1][1][0][RTW89_WW][0][109] = 1, + [0][1][1][0][RTW89_WW][1][109] = 1, + [0][1][1][0][RTW89_WW][0][111] = 0, + [0][1][1][0][RTW89_WW][1][111] = 0, + [0][1][1][0][RTW89_WW][0][113] = 0, + [0][1][1][0][RTW89_WW][1][113] = 0, + [0][1][1][0][RTW89_WW][0][115] = 0, + [0][1][1][0][RTW89_WW][1][115] = 0, + [0][1][1][0][RTW89_WW][0][117] = 0, + [0][1][1][0][RTW89_WW][1][117] = 0, + [0][1][1][0][RTW89_WW][0][119] = 0, + [0][1][1][0][RTW89_WW][1][119] = 0, + [0][0][2][0][RTW89_WW][0][0] = 24, + [0][0][2][0][RTW89_WW][1][0] = 24, + [0][0][2][0][RTW89_WW][0][2] = 22, + [0][0][2][0][RTW89_WW][1][2] = 22, + [0][0][2][0][RTW89_WW][0][4] = 22, + [0][0][2][0][RTW89_WW][1][4] = 22, + [0][0][2][0][RTW89_WW][0][6] = 22, + [0][0][2][0][RTW89_WW][1][6] = 22, + [0][0][2][0][RTW89_WW][0][8] = 22, + [0][0][2][0][RTW89_WW][1][8] = 22, + [0][0][2][0][RTW89_WW][0][10] = 22, + [0][0][2][0][RTW89_WW][1][10] = 22, + [0][0][2][0][RTW89_WW][0][12] = 22, + [0][0][2][0][RTW89_WW][1][12] = 22, + [0][0][2][0][RTW89_WW][0][14] = 22, + [0][0][2][0][RTW89_WW][1][14] = 22, + [0][0][2][0][RTW89_WW][0][15] = 22, + [0][0][2][0][RTW89_WW][1][15] = 22, + [0][0][2][0][RTW89_WW][0][17] = 22, + [0][0][2][0][RTW89_WW][1][17] = 22, + [0][0][2][0][RTW89_WW][0][19] = 22, + [0][0][2][0][RTW89_WW][1][19] = 22, + [0][0][2][0][RTW89_WW][0][21] = 22, + [0][0][2][0][RTW89_WW][1][21] = 22, + [0][0][2][0][RTW89_WW][0][23] = 22, + [0][0][2][0][RTW89_WW][1][23] = 22, + [0][0][2][0][RTW89_WW][0][25] = 22, + [0][0][2][0][RTW89_WW][1][25] = 22, + [0][0][2][0][RTW89_WW][0][27] = 22, + [0][0][2][0][RTW89_WW][1][27] = 22, + [0][0][2][0][RTW89_WW][0][29] = 22, + [0][0][2][0][RTW89_WW][1][29] = 22, + [0][0][2][0][RTW89_WW][0][30] = 22, + [0][0][2][0][RTW89_WW][1][30] = 22, + [0][0][2][0][RTW89_WW][0][32] = 22, + [0][0][2][0][RTW89_WW][1][32] = 22, + [0][0][2][0][RTW89_WW][0][34] = 22, + [0][0][2][0][RTW89_WW][1][34] = 22, + [0][0][2][0][RTW89_WW][0][36] = 22, + [0][0][2][0][RTW89_WW][1][36] = 22, + [0][0][2][0][RTW89_WW][0][38] = 22, + [0][0][2][0][RTW89_WW][1][38] = 22, + [0][0][2][0][RTW89_WW][0][40] = 22, + [0][0][2][0][RTW89_WW][1][40] = 22, + [0][0][2][0][RTW89_WW][0][42] = 22, + [0][0][2][0][RTW89_WW][1][42] = 22, + [0][0][2][0][RTW89_WW][0][44] = 22, + [0][0][2][0][RTW89_WW][1][44] = 22, + [0][0][2][0][RTW89_WW][0][45] = 22, + [0][0][2][0][RTW89_WW][1][45] = 22, + [0][0][2][0][RTW89_WW][0][47] = 22, + [0][0][2][0][RTW89_WW][1][47] = 22, + [0][0][2][0][RTW89_WW][0][49] = 24, + [0][0][2][0][RTW89_WW][1][49] = 24, + [0][0][2][0][RTW89_WW][0][51] = 22, + [0][0][2][0][RTW89_WW][1][51] = 22, + [0][0][2][0][RTW89_WW][0][53] = 22, + [0][0][2][0][RTW89_WW][1][53] = 22, + [0][0][2][0][RTW89_WW][0][55] = 22, + [0][0][2][0][RTW89_WW][1][55] = 22, + [0][0][2][0][RTW89_WW][0][57] = 22, + [0][0][2][0][RTW89_WW][1][57] = 22, + [0][0][2][0][RTW89_WW][0][59] = 22, + [0][0][2][0][RTW89_WW][1][59] = 22, + [0][0][2][0][RTW89_WW][0][60] = 22, + [0][0][2][0][RTW89_WW][1][60] = 22, + [0][0][2][0][RTW89_WW][0][62] = 22, + [0][0][2][0][RTW89_WW][1][62] = 22, + [0][0][2][0][RTW89_WW][0][64] = 22, + [0][0][2][0][RTW89_WW][1][64] = 22, + [0][0][2][0][RTW89_WW][0][66] = 22, + [0][0][2][0][RTW89_WW][1][66] = 22, + [0][0][2][0][RTW89_WW][0][68] = 22, + [0][0][2][0][RTW89_WW][1][68] = 22, + [0][0][2][0][RTW89_WW][0][70] = 24, + [0][0][2][0][RTW89_WW][1][70] = 24, + [0][0][2][0][RTW89_WW][0][72] = 22, + [0][0][2][0][RTW89_WW][1][72] = 22, + [0][0][2][0][RTW89_WW][0][74] = 22, + [0][0][2][0][RTW89_WW][1][74] = 22, + [0][0][2][0][RTW89_WW][0][75] = 22, + [0][0][2][0][RTW89_WW][1][75] = 22, + [0][0][2][0][RTW89_WW][0][77] = 22, + [0][0][2][0][RTW89_WW][1][77] = 22, + [0][0][2][0][RTW89_WW][0][79] = 22, + [0][0][2][0][RTW89_WW][1][79] = 22, + [0][0][2][0][RTW89_WW][0][81] = 22, + [0][0][2][0][RTW89_WW][1][81] = 22, + [0][0][2][0][RTW89_WW][0][83] = 22, + [0][0][2][0][RTW89_WW][1][83] = 22, + [0][0][2][0][RTW89_WW][0][85] = 22, + [0][0][2][0][RTW89_WW][1][85] = 22, + [0][0][2][0][RTW89_WW][0][87] = 22, + [0][0][2][0][RTW89_WW][1][87] = 22, + [0][0][2][0][RTW89_WW][0][89] = 22, + [0][0][2][0][RTW89_WW][1][89] = 22, + [0][0][2][0][RTW89_WW][0][90] = 22, + [0][0][2][0][RTW89_WW][1][90] = 22, + [0][0][2][0][RTW89_WW][0][92] = 22, + [0][0][2][0][RTW89_WW][1][92] = 22, + [0][0][2][0][RTW89_WW][0][94] = 22, + [0][0][2][0][RTW89_WW][1][94] = 22, + [0][0][2][0][RTW89_WW][0][96] = 22, + [0][0][2][0][RTW89_WW][1][96] = 22, + [0][0][2][0][RTW89_WW][0][98] = 22, + [0][0][2][0][RTW89_WW][1][98] = 22, + [0][0][2][0][RTW89_WW][0][100] = 22, + [0][0][2][0][RTW89_WW][1][100] = 22, + [0][0][2][0][RTW89_WW][0][102] = 22, + [0][0][2][0][RTW89_WW][1][102] = 22, + [0][0][2][0][RTW89_WW][0][104] = 22, + [0][0][2][0][RTW89_WW][1][104] = 22, + [0][0][2][0][RTW89_WW][0][105] = 22, + [0][0][2][0][RTW89_WW][1][105] = 22, + [0][0][2][0][RTW89_WW][0][107] = 24, + [0][0][2][0][RTW89_WW][1][107] = 24, + [0][0][2][0][RTW89_WW][0][109] = 24, + [0][0][2][0][RTW89_WW][1][109] = 24, + [0][0][2][0][RTW89_WW][0][111] = 0, + [0][0][2][0][RTW89_WW][1][111] = 0, + [0][0][2][0][RTW89_WW][0][113] = 0, + [0][0][2][0][RTW89_WW][1][113] = 0, + [0][0][2][0][RTW89_WW][0][115] = 0, + [0][0][2][0][RTW89_WW][1][115] = 0, + [0][0][2][0][RTW89_WW][0][117] = 0, + [0][0][2][0][RTW89_WW][1][117] = 0, + [0][0][2][0][RTW89_WW][0][119] = 0, + [0][0][2][0][RTW89_WW][1][119] = 0, + [0][1][2][0][RTW89_WW][0][0] = -2, + [0][1][2][0][RTW89_WW][1][0] = -2, + [0][1][2][0][RTW89_WW][0][2] = -4, + [0][1][2][0][RTW89_WW][1][2] = -4, + [0][1][2][0][RTW89_WW][0][4] = -4, + [0][1][2][0][RTW89_WW][1][4] = -4, + [0][1][2][0][RTW89_WW][0][6] = -4, + [0][1][2][0][RTW89_WW][1][6] = -4, + [0][1][2][0][RTW89_WW][0][8] = -4, + [0][1][2][0][RTW89_WW][1][8] = -4, + [0][1][2][0][RTW89_WW][0][10] = -4, + [0][1][2][0][RTW89_WW][1][10] = -4, + [0][1][2][0][RTW89_WW][0][12] = -4, + [0][1][2][0][RTW89_WW][1][12] = -4, + [0][1][2][0][RTW89_WW][0][14] = -4, + [0][1][2][0][RTW89_WW][1][14] = -4, + [0][1][2][0][RTW89_WW][0][15] = -4, + [0][1][2][0][RTW89_WW][1][15] = -4, + [0][1][2][0][RTW89_WW][0][17] = -4, + [0][1][2][0][RTW89_WW][1][17] = -4, + [0][1][2][0][RTW89_WW][0][19] = -4, + [0][1][2][0][RTW89_WW][1][19] = -4, + [0][1][2][0][RTW89_WW][0][21] = -4, + [0][1][2][0][RTW89_WW][1][21] = -4, + [0][1][2][0][RTW89_WW][0][23] = -4, + [0][1][2][0][RTW89_WW][1][23] = -4, + [0][1][2][0][RTW89_WW][0][25] = -4, + [0][1][2][0][RTW89_WW][1][25] = -4, + [0][1][2][0][RTW89_WW][0][27] = -4, + [0][1][2][0][RTW89_WW][1][27] = -4, + [0][1][2][0][RTW89_WW][0][29] = -4, + [0][1][2][0][RTW89_WW][1][29] = -4, + [0][1][2][0][RTW89_WW][0][30] = -4, + [0][1][2][0][RTW89_WW][1][30] = -4, + [0][1][2][0][RTW89_WW][0][32] = -4, + [0][1][2][0][RTW89_WW][1][32] = -4, + [0][1][2][0][RTW89_WW][0][34] = -4, + [0][1][2][0][RTW89_WW][1][34] = -4, + [0][1][2][0][RTW89_WW][0][36] = -4, + [0][1][2][0][RTW89_WW][1][36] = -4, + [0][1][2][0][RTW89_WW][0][38] = -4, + [0][1][2][0][RTW89_WW][1][38] = -4, + [0][1][2][0][RTW89_WW][0][40] = -4, + [0][1][2][0][RTW89_WW][1][40] = -4, + [0][1][2][0][RTW89_WW][0][42] = -4, + [0][1][2][0][RTW89_WW][1][42] = -4, + [0][1][2][0][RTW89_WW][0][44] = -2, + [0][1][2][0][RTW89_WW][1][44] = -2, + [0][1][2][0][RTW89_WW][0][45] = -2, + [0][1][2][0][RTW89_WW][1][45] = -2, + [0][1][2][0][RTW89_WW][0][47] = -2, + [0][1][2][0][RTW89_WW][1][47] = -2, + [0][1][2][0][RTW89_WW][0][49] = -2, + [0][1][2][0][RTW89_WW][1][49] = -2, + [0][1][2][0][RTW89_WW][0][51] = -2, + [0][1][2][0][RTW89_WW][1][51] = -2, + [0][1][2][0][RTW89_WW][0][53] = -2, + [0][1][2][0][RTW89_WW][1][53] = -2, + [0][1][2][0][RTW89_WW][0][55] = -2, + [0][1][2][0][RTW89_WW][1][55] = -2, + [0][1][2][0][RTW89_WW][0][57] = -2, + [0][1][2][0][RTW89_WW][1][57] = -2, + [0][1][2][0][RTW89_WW][0][59] = -2, + [0][1][2][0][RTW89_WW][1][59] = -2, + [0][1][2][0][RTW89_WW][0][60] = -2, + [0][1][2][0][RTW89_WW][1][60] = -2, + [0][1][2][0][RTW89_WW][0][62] = -2, + [0][1][2][0][RTW89_WW][1][62] = -2, + [0][1][2][0][RTW89_WW][0][64] = -2, + [0][1][2][0][RTW89_WW][1][64] = -2, + [0][1][2][0][RTW89_WW][0][66] = -2, + [0][1][2][0][RTW89_WW][1][66] = -2, + [0][1][2][0][RTW89_WW][0][68] = -2, + [0][1][2][0][RTW89_WW][1][68] = -2, + [0][1][2][0][RTW89_WW][0][70] = -2, + [0][1][2][0][RTW89_WW][1][70] = -2, + [0][1][2][0][RTW89_WW][0][72] = -2, + [0][1][2][0][RTW89_WW][1][72] = -2, + [0][1][2][0][RTW89_WW][0][74] = -2, + [0][1][2][0][RTW89_WW][1][74] = -2, + [0][1][2][0][RTW89_WW][0][75] = -2, + [0][1][2][0][RTW89_WW][1][75] = -2, + [0][1][2][0][RTW89_WW][0][77] = -2, + [0][1][2][0][RTW89_WW][1][77] = -2, + [0][1][2][0][RTW89_WW][0][79] = -2, + [0][1][2][0][RTW89_WW][1][79] = -2, + [0][1][2][0][RTW89_WW][0][81] = -2, + [0][1][2][0][RTW89_WW][1][81] = -2, + [0][1][2][0][RTW89_WW][0][83] = -2, + [0][1][2][0][RTW89_WW][1][83] = -2, + [0][1][2][0][RTW89_WW][0][85] = -2, + [0][1][2][0][RTW89_WW][1][85] = -2, + [0][1][2][0][RTW89_WW][0][87] = -2, + [0][1][2][0][RTW89_WW][1][87] = -2, + [0][1][2][0][RTW89_WW][0][89] = -2, + [0][1][2][0][RTW89_WW][1][89] = -2, + [0][1][2][0][RTW89_WW][0][90] = -2, + [0][1][2][0][RTW89_WW][1][90] = -2, + [0][1][2][0][RTW89_WW][0][92] = -2, + [0][1][2][0][RTW89_WW][1][92] = -2, + [0][1][2][0][RTW89_WW][0][94] = -2, + [0][1][2][0][RTW89_WW][1][94] = -2, + [0][1][2][0][RTW89_WW][0][96] = -2, + [0][1][2][0][RTW89_WW][1][96] = -2, + [0][1][2][0][RTW89_WW][0][98] = -2, + [0][1][2][0][RTW89_WW][1][98] = -2, + [0][1][2][0][RTW89_WW][0][100] = -2, + [0][1][2][0][RTW89_WW][1][100] = -2, + [0][1][2][0][RTW89_WW][0][102] = -2, + [0][1][2][0][RTW89_WW][1][102] = -2, + [0][1][2][0][RTW89_WW][0][104] = -2, + [0][1][2][0][RTW89_WW][1][104] = -2, + [0][1][2][0][RTW89_WW][0][105] = -2, + [0][1][2][0][RTW89_WW][1][105] = -2, + [0][1][2][0][RTW89_WW][0][107] = 1, + [0][1][2][0][RTW89_WW][1][107] = 1, + [0][1][2][0][RTW89_WW][0][109] = 1, + [0][1][2][0][RTW89_WW][1][109] = 1, + [0][1][2][0][RTW89_WW][0][111] = 0, + [0][1][2][0][RTW89_WW][1][111] = 0, + [0][1][2][0][RTW89_WW][0][113] = 0, + [0][1][2][0][RTW89_WW][1][113] = 0, + [0][1][2][0][RTW89_WW][0][115] = 0, + [0][1][2][0][RTW89_WW][1][115] = 0, + [0][1][2][0][RTW89_WW][0][117] = 0, + [0][1][2][0][RTW89_WW][1][117] = 0, + [0][1][2][0][RTW89_WW][0][119] = 0, + [0][1][2][0][RTW89_WW][1][119] = 0, + [0][1][2][1][RTW89_WW][0][0] = -2, + [0][1][2][1][RTW89_WW][1][0] = -2, + [0][1][2][1][RTW89_WW][0][2] = -4, + [0][1][2][1][RTW89_WW][1][2] = -4, + [0][1][2][1][RTW89_WW][0][4] = -4, + [0][1][2][1][RTW89_WW][1][4] = -4, + [0][1][2][1][RTW89_WW][0][6] = -4, + [0][1][2][1][RTW89_WW][1][6] = -4, + [0][1][2][1][RTW89_WW][0][8] = -4, + [0][1][2][1][RTW89_WW][1][8] = -4, + [0][1][2][1][RTW89_WW][0][10] = -4, + [0][1][2][1][RTW89_WW][1][10] = -4, + [0][1][2][1][RTW89_WW][0][12] = -4, + [0][1][2][1][RTW89_WW][1][12] = -4, + [0][1][2][1][RTW89_WW][0][14] = -4, + [0][1][2][1][RTW89_WW][1][14] = -4, + [0][1][2][1][RTW89_WW][0][15] = -4, + [0][1][2][1][RTW89_WW][1][15] = -4, + [0][1][2][1][RTW89_WW][0][17] = -4, + [0][1][2][1][RTW89_WW][1][17] = -4, + [0][1][2][1][RTW89_WW][0][19] = -4, + [0][1][2][1][RTW89_WW][1][19] = -4, + [0][1][2][1][RTW89_WW][0][21] = -4, + [0][1][2][1][RTW89_WW][1][21] = -4, + [0][1][2][1][RTW89_WW][0][23] = -4, + [0][1][2][1][RTW89_WW][1][23] = -4, + [0][1][2][1][RTW89_WW][0][25] = -4, + [0][1][2][1][RTW89_WW][1][25] = -4, + [0][1][2][1][RTW89_WW][0][27] = -4, + [0][1][2][1][RTW89_WW][1][27] = -4, + [0][1][2][1][RTW89_WW][0][29] = -4, + [0][1][2][1][RTW89_WW][1][29] = -4, + [0][1][2][1][RTW89_WW][0][30] = -4, + [0][1][2][1][RTW89_WW][1][30] = -4, + [0][1][2][1][RTW89_WW][0][32] = -4, + [0][1][2][1][RTW89_WW][1][32] = -4, + [0][1][2][1][RTW89_WW][0][34] = -4, + [0][1][2][1][RTW89_WW][1][34] = -4, + [0][1][2][1][RTW89_WW][0][36] = -4, + [0][1][2][1][RTW89_WW][1][36] = -4, + [0][1][2][1][RTW89_WW][0][38] = -4, + [0][1][2][1][RTW89_WW][1][38] = -4, + [0][1][2][1][RTW89_WW][0][40] = -4, + [0][1][2][1][RTW89_WW][1][40] = -4, + [0][1][2][1][RTW89_WW][0][42] = -4, + [0][1][2][1][RTW89_WW][1][42] = -4, + [0][1][2][1][RTW89_WW][0][44] = -2, + [0][1][2][1][RTW89_WW][1][44] = -2, + [0][1][2][1][RTW89_WW][0][45] = -2, + [0][1][2][1][RTW89_WW][1][45] = -2, + [0][1][2][1][RTW89_WW][0][47] = -2, + [0][1][2][1][RTW89_WW][1][47] = -2, + [0][1][2][1][RTW89_WW][0][49] = -2, + [0][1][2][1][RTW89_WW][1][49] = -2, + [0][1][2][1][RTW89_WW][0][51] = -2, + [0][1][2][1][RTW89_WW][1][51] = -2, + [0][1][2][1][RTW89_WW][0][53] = -2, + [0][1][2][1][RTW89_WW][1][53] = -2, + [0][1][2][1][RTW89_WW][0][55] = -2, + [0][1][2][1][RTW89_WW][1][55] = -2, + [0][1][2][1][RTW89_WW][0][57] = -2, + [0][1][2][1][RTW89_WW][1][57] = -2, + [0][1][2][1][RTW89_WW][0][59] = -2, + [0][1][2][1][RTW89_WW][1][59] = -2, + [0][1][2][1][RTW89_WW][0][60] = -2, + [0][1][2][1][RTW89_WW][1][60] = -2, + [0][1][2][1][RTW89_WW][0][62] = -2, + [0][1][2][1][RTW89_WW][1][62] = -2, + [0][1][2][1][RTW89_WW][0][64] = -2, + [0][1][2][1][RTW89_WW][1][64] = -2, + [0][1][2][1][RTW89_WW][0][66] = -2, + [0][1][2][1][RTW89_WW][1][66] = -2, + [0][1][2][1][RTW89_WW][0][68] = -2, + [0][1][2][1][RTW89_WW][1][68] = -2, + [0][1][2][1][RTW89_WW][0][70] = -2, + [0][1][2][1][RTW89_WW][1][70] = -2, + [0][1][2][1][RTW89_WW][0][72] = -2, + [0][1][2][1][RTW89_WW][1][72] = -2, + [0][1][2][1][RTW89_WW][0][74] = -2, + [0][1][2][1][RTW89_WW][1][74] = -2, + [0][1][2][1][RTW89_WW][0][75] = -2, + [0][1][2][1][RTW89_WW][1][75] = -2, + [0][1][2][1][RTW89_WW][0][77] = -2, + [0][1][2][1][RTW89_WW][1][77] = -2, + [0][1][2][1][RTW89_WW][0][79] = -2, + [0][1][2][1][RTW89_WW][1][79] = -2, + [0][1][2][1][RTW89_WW][0][81] = -2, + [0][1][2][1][RTW89_WW][1][81] = -2, + [0][1][2][1][RTW89_WW][0][83] = -2, + [0][1][2][1][RTW89_WW][1][83] = -2, + [0][1][2][1][RTW89_WW][0][85] = -2, + [0][1][2][1][RTW89_WW][1][85] = -2, + [0][1][2][1][RTW89_WW][0][87] = -2, + [0][1][2][1][RTW89_WW][1][87] = -2, + [0][1][2][1][RTW89_WW][0][89] = -2, + [0][1][2][1][RTW89_WW][1][89] = -2, + [0][1][2][1][RTW89_WW][0][90] = -2, + [0][1][2][1][RTW89_WW][1][90] = -2, + [0][1][2][1][RTW89_WW][0][92] = -2, + [0][1][2][1][RTW89_WW][1][92] = -2, + [0][1][2][1][RTW89_WW][0][94] = -2, + [0][1][2][1][RTW89_WW][1][94] = -2, + [0][1][2][1][RTW89_WW][0][96] = -2, + [0][1][2][1][RTW89_WW][1][96] = -2, + [0][1][2][1][RTW89_WW][0][98] = -2, + [0][1][2][1][RTW89_WW][1][98] = -2, + [0][1][2][1][RTW89_WW][0][100] = -2, + [0][1][2][1][RTW89_WW][1][100] = -2, + [0][1][2][1][RTW89_WW][0][102] = -2, + [0][1][2][1][RTW89_WW][1][102] = -2, + [0][1][2][1][RTW89_WW][0][104] = -2, + [0][1][2][1][RTW89_WW][1][104] = -2, + [0][1][2][1][RTW89_WW][0][105] = -2, + [0][1][2][1][RTW89_WW][1][105] = -2, + [0][1][2][1][RTW89_WW][0][107] = 1, + [0][1][2][1][RTW89_WW][1][107] = 1, + [0][1][2][1][RTW89_WW][0][109] = 1, + [0][1][2][1][RTW89_WW][1][109] = 1, + [0][1][2][1][RTW89_WW][0][111] = 0, + [0][1][2][1][RTW89_WW][1][111] = 0, + [0][1][2][1][RTW89_WW][0][113] = 0, + [0][1][2][1][RTW89_WW][1][113] = 0, + [0][1][2][1][RTW89_WW][0][115] = 0, + [0][1][2][1][RTW89_WW][1][115] = 0, + [0][1][2][1][RTW89_WW][0][117] = 0, + [0][1][2][1][RTW89_WW][1][117] = 0, + [0][1][2][1][RTW89_WW][0][119] = 0, + [0][1][2][1][RTW89_WW][1][119] = 0, + [1][0][2][0][RTW89_WW][0][1] = 24, + [1][0][2][0][RTW89_WW][1][1] = 34, + [1][0][2][0][RTW89_WW][0][5] = 24, + [1][0][2][0][RTW89_WW][1][5] = 34, + [1][0][2][0][RTW89_WW][0][9] = 24, + [1][0][2][0][RTW89_WW][1][9] = 34, + [1][0][2][0][RTW89_WW][0][13] = 24, + [1][0][2][0][RTW89_WW][1][13] = 34, + [1][0][2][0][RTW89_WW][0][16] = 24, + [1][0][2][0][RTW89_WW][1][16] = 34, + [1][0][2][0][RTW89_WW][0][20] = 24, + [1][0][2][0][RTW89_WW][1][20] = 34, + [1][0][2][0][RTW89_WW][0][24] = 26, + [1][0][2][0][RTW89_WW][1][24] = 36, + [1][0][2][0][RTW89_WW][0][28] = 26, + [1][0][2][0][RTW89_WW][1][28] = 34, + [1][0][2][0][RTW89_WW][0][31] = 26, + [1][0][2][0][RTW89_WW][1][31] = 34, + [1][0][2][0][RTW89_WW][0][35] = 26, + [1][0][2][0][RTW89_WW][1][35] = 34, + [1][0][2][0][RTW89_WW][0][39] = 26, + [1][0][2][0][RTW89_WW][1][39] = 34, + [1][0][2][0][RTW89_WW][0][43] = 26, + [1][0][2][0][RTW89_WW][1][43] = 34, + [1][0][2][0][RTW89_WW][0][46] = 34, + [1][0][2][0][RTW89_WW][1][46] = 34, + [1][0][2][0][RTW89_WW][0][50] = 34, + [1][0][2][0][RTW89_WW][1][50] = 34, + [1][0][2][0][RTW89_WW][0][54] = 36, + [1][0][2][0][RTW89_WW][1][54] = 36, + [1][0][2][0][RTW89_WW][0][58] = 36, + [1][0][2][0][RTW89_WW][1][58] = 36, + [1][0][2][0][RTW89_WW][0][61] = 34, + [1][0][2][0][RTW89_WW][1][61] = 34, + [1][0][2][0][RTW89_WW][0][65] = 34, + [1][0][2][0][RTW89_WW][1][65] = 34, + [1][0][2][0][RTW89_WW][0][69] = 34, + [1][0][2][0][RTW89_WW][1][69] = 34, + [1][0][2][0][RTW89_WW][0][73] = 34, + [1][0][2][0][RTW89_WW][1][73] = 34, + [1][0][2][0][RTW89_WW][0][76] = 34, + [1][0][2][0][RTW89_WW][1][76] = 34, + [1][0][2][0][RTW89_WW][0][80] = 34, + [1][0][2][0][RTW89_WW][1][80] = 34, + [1][0][2][0][RTW89_WW][0][84] = 34, + [1][0][2][0][RTW89_WW][1][84] = 34, + [1][0][2][0][RTW89_WW][0][88] = 34, + [1][0][2][0][RTW89_WW][1][88] = 34, + [1][0][2][0][RTW89_WW][0][91] = 36, + [1][0][2][0][RTW89_WW][1][91] = 36, + [1][0][2][0][RTW89_WW][0][95] = 34, + [1][0][2][0][RTW89_WW][1][95] = 34, + [1][0][2][0][RTW89_WW][0][99] = 34, + [1][0][2][0][RTW89_WW][1][99] = 34, + [1][0][2][0][RTW89_WW][0][103] = 34, + [1][0][2][0][RTW89_WW][1][103] = 34, + [1][0][2][0][RTW89_WW][0][106] = 36, + [1][0][2][0][RTW89_WW][1][106] = 36, + [1][0][2][0][RTW89_WW][0][110] = 0, + [1][0][2][0][RTW89_WW][1][110] = 0, + [1][0][2][0][RTW89_WW][0][114] = 0, + [1][0][2][0][RTW89_WW][1][114] = 0, + [1][0][2][0][RTW89_WW][0][118] = 0, + [1][0][2][0][RTW89_WW][1][118] = 0, + [1][1][2][0][RTW89_WW][0][1] = 10, + [1][1][2][0][RTW89_WW][1][1] = 10, + [1][1][2][0][RTW89_WW][0][5] = 10, + [1][1][2][0][RTW89_WW][1][5] = 10, + [1][1][2][0][RTW89_WW][0][9] = 10, + [1][1][2][0][RTW89_WW][1][9] = 10, + [1][1][2][0][RTW89_WW][0][13] = 10, + [1][1][2][0][RTW89_WW][1][13] = 10, + [1][1][2][0][RTW89_WW][0][16] = 10, + [1][1][2][0][RTW89_WW][1][16] = 10, + [1][1][2][0][RTW89_WW][0][20] = 10, + [1][1][2][0][RTW89_WW][1][20] = 10, + [1][1][2][0][RTW89_WW][0][24] = 10, + [1][1][2][0][RTW89_WW][1][24] = 10, + [1][1][2][0][RTW89_WW][0][28] = 10, + [1][1][2][0][RTW89_WW][1][28] = 10, + [1][1][2][0][RTW89_WW][0][31] = 10, + [1][1][2][0][RTW89_WW][1][31] = 10, + [1][1][2][0][RTW89_WW][0][35] = 10, + [1][1][2][0][RTW89_WW][1][35] = 10, + [1][1][2][0][RTW89_WW][0][39] = 10, + [1][1][2][0][RTW89_WW][1][39] = 10, + [1][1][2][0][RTW89_WW][0][43] = 10, + [1][1][2][0][RTW89_WW][1][43] = 10, + [1][1][2][0][RTW89_WW][0][46] = 12, + [1][1][2][0][RTW89_WW][1][46] = 12, + [1][1][2][0][RTW89_WW][0][50] = 12, + [1][1][2][0][RTW89_WW][1][50] = 12, + [1][1][2][0][RTW89_WW][0][54] = 10, + [1][1][2][0][RTW89_WW][1][54] = 10, + [1][1][2][0][RTW89_WW][0][58] = 10, + [1][1][2][0][RTW89_WW][1][58] = 10, + [1][1][2][0][RTW89_WW][0][61] = 10, + [1][1][2][0][RTW89_WW][1][61] = 10, + [1][1][2][0][RTW89_WW][0][65] = 10, + [1][1][2][0][RTW89_WW][1][65] = 10, + [1][1][2][0][RTW89_WW][0][69] = 10, + [1][1][2][0][RTW89_WW][1][69] = 10, + [1][1][2][0][RTW89_WW][0][73] = 10, + [1][1][2][0][RTW89_WW][1][73] = 10, + [1][1][2][0][RTW89_WW][0][76] = 10, + [1][1][2][0][RTW89_WW][1][76] = 10, + [1][1][2][0][RTW89_WW][0][80] = 10, + [1][1][2][0][RTW89_WW][1][80] = 10, + [1][1][2][0][RTW89_WW][0][84] = 10, + [1][1][2][0][RTW89_WW][1][84] = 10, + [1][1][2][0][RTW89_WW][0][88] = 10, + [1][1][2][0][RTW89_WW][1][88] = 10, + [1][1][2][0][RTW89_WW][0][91] = 12, + [1][1][2][0][RTW89_WW][1][91] = 12, + [1][1][2][0][RTW89_WW][0][95] = 10, + [1][1][2][0][RTW89_WW][1][95] = 10, + [1][1][2][0][RTW89_WW][0][99] = 10, + [1][1][2][0][RTW89_WW][1][99] = 10, + [1][1][2][0][RTW89_WW][0][103] = 10, + [1][1][2][0][RTW89_WW][1][103] = 10, + [1][1][2][0][RTW89_WW][0][106] = 12, + [1][1][2][0][RTW89_WW][1][106] = 12, + [1][1][2][0][RTW89_WW][0][110] = 0, + [1][1][2][0][RTW89_WW][1][110] = 0, + [1][1][2][0][RTW89_WW][0][114] = 0, + [1][1][2][0][RTW89_WW][1][114] = 0, + [1][1][2][0][RTW89_WW][0][118] = 0, + [1][1][2][0][RTW89_WW][1][118] = 0, + [1][1][2][1][RTW89_WW][0][1] = 6, + [1][1][2][1][RTW89_WW][1][1] = 10, + [1][1][2][1][RTW89_WW][0][5] = 6, + [1][1][2][1][RTW89_WW][1][5] = 10, + [1][1][2][1][RTW89_WW][0][9] = 6, + [1][1][2][1][RTW89_WW][1][9] = 10, + [1][1][2][1][RTW89_WW][0][13] = 6, + [1][1][2][1][RTW89_WW][1][13] = 10, + [1][1][2][1][RTW89_WW][0][16] = 6, + [1][1][2][1][RTW89_WW][1][16] = 10, + [1][1][2][1][RTW89_WW][0][20] = 6, + [1][1][2][1][RTW89_WW][1][20] = 10, + [1][1][2][1][RTW89_WW][0][24] = 6, + [1][1][2][1][RTW89_WW][1][24] = 10, + [1][1][2][1][RTW89_WW][0][28] = 6, + [1][1][2][1][RTW89_WW][1][28] = 10, + [1][1][2][1][RTW89_WW][0][31] = 6, + [1][1][2][1][RTW89_WW][1][31] = 10, + [1][1][2][1][RTW89_WW][0][35] = 6, + [1][1][2][1][RTW89_WW][1][35] = 10, + [1][1][2][1][RTW89_WW][0][39] = 6, + [1][1][2][1][RTW89_WW][1][39] = 10, + [1][1][2][1][RTW89_WW][0][43] = 6, + [1][1][2][1][RTW89_WW][1][43] = 10, + [1][1][2][1][RTW89_WW][0][46] = 12, + [1][1][2][1][RTW89_WW][1][46] = 12, + [1][1][2][1][RTW89_WW][0][50] = 12, + [1][1][2][1][RTW89_WW][1][50] = 12, + [1][1][2][1][RTW89_WW][0][54] = 10, + [1][1][2][1][RTW89_WW][1][54] = 10, + [1][1][2][1][RTW89_WW][0][58] = 10, + [1][1][2][1][RTW89_WW][1][58] = 10, + [1][1][2][1][RTW89_WW][0][61] = 10, + [1][1][2][1][RTW89_WW][1][61] = 10, + [1][1][2][1][RTW89_WW][0][65] = 10, + [1][1][2][1][RTW89_WW][1][65] = 10, + [1][1][2][1][RTW89_WW][0][69] = 10, + [1][1][2][1][RTW89_WW][1][69] = 10, + [1][1][2][1][RTW89_WW][0][73] = 10, + [1][1][2][1][RTW89_WW][1][73] = 10, + [1][1][2][1][RTW89_WW][0][76] = 10, + [1][1][2][1][RTW89_WW][1][76] = 10, + [1][1][2][1][RTW89_WW][0][80] = 10, + [1][1][2][1][RTW89_WW][1][80] = 10, + [1][1][2][1][RTW89_WW][0][84] = 10, + [1][1][2][1][RTW89_WW][1][84] = 10, + [1][1][2][1][RTW89_WW][0][88] = 10, + [1][1][2][1][RTW89_WW][1][88] = 10, + [1][1][2][1][RTW89_WW][0][91] = 12, + [1][1][2][1][RTW89_WW][1][91] = 12, + [1][1][2][1][RTW89_WW][0][95] = 10, + [1][1][2][1][RTW89_WW][1][95] = 10, + [1][1][2][1][RTW89_WW][0][99] = 10, + [1][1][2][1][RTW89_WW][1][99] = 10, + [1][1][2][1][RTW89_WW][0][103] = 10, + [1][1][2][1][RTW89_WW][1][103] = 10, + [1][1][2][1][RTW89_WW][0][106] = 12, + [1][1][2][1][RTW89_WW][1][106] = 12, + [1][1][2][1][RTW89_WW][0][110] = 0, + [1][1][2][1][RTW89_WW][1][110] = 0, + [1][1][2][1][RTW89_WW][0][114] = 0, + [1][1][2][1][RTW89_WW][1][114] = 0, + [1][1][2][1][RTW89_WW][0][118] = 0, + [1][1][2][1][RTW89_WW][1][118] = 0, + [2][0][2][0][RTW89_WW][0][3] = 24, + [2][0][2][0][RTW89_WW][1][3] = 46, + [2][0][2][0][RTW89_WW][0][11] = 24, + [2][0][2][0][RTW89_WW][1][11] = 46, + [2][0][2][0][RTW89_WW][0][18] = 24, + [2][0][2][0][RTW89_WW][1][18] = 46, + [2][0][2][0][RTW89_WW][0][26] = 24, + [2][0][2][0][RTW89_WW][1][26] = 46, + [2][0][2][0][RTW89_WW][0][33] = 24, + [2][0][2][0][RTW89_WW][1][33] = 46, + [2][0][2][0][RTW89_WW][0][41] = 24, + [2][0][2][0][RTW89_WW][1][41] = 46, + [2][0][2][0][RTW89_WW][0][48] = 46, + [2][0][2][0][RTW89_WW][1][48] = 46, + [2][0][2][0][RTW89_WW][0][56] = 46, + [2][0][2][0][RTW89_WW][1][56] = 46, + [2][0][2][0][RTW89_WW][0][63] = 46, + [2][0][2][0][RTW89_WW][1][63] = 46, + [2][0][2][0][RTW89_WW][0][71] = 46, + [2][0][2][0][RTW89_WW][1][71] = 46, + [2][0][2][0][RTW89_WW][0][78] = 46, + [2][0][2][0][RTW89_WW][1][78] = 46, + [2][0][2][0][RTW89_WW][0][86] = 46, + [2][0][2][0][RTW89_WW][1][86] = 46, + [2][0][2][0][RTW89_WW][0][93] = 46, + [2][0][2][0][RTW89_WW][1][93] = 46, + [2][0][2][0][RTW89_WW][0][101] = 44, + [2][0][2][0][RTW89_WW][1][101] = 44, + [2][0][2][0][RTW89_WW][0][108] = 0, + [2][0][2][0][RTW89_WW][1][108] = 0, + [2][0][2][0][RTW89_WW][0][116] = 0, + [2][0][2][0][RTW89_WW][1][116] = 0, + [2][1][2][0][RTW89_WW][0][3] = 12, + [2][1][2][0][RTW89_WW][1][3] = 22, + [2][1][2][0][RTW89_WW][0][11] = 12, + [2][1][2][0][RTW89_WW][1][11] = 20, + [2][1][2][0][RTW89_WW][0][18] = 12, + [2][1][2][0][RTW89_WW][1][18] = 20, + [2][1][2][0][RTW89_WW][0][26] = 12, + [2][1][2][0][RTW89_WW][1][26] = 20, + [2][1][2][0][RTW89_WW][0][33] = 12, + [2][1][2][0][RTW89_WW][1][33] = 20, + [2][1][2][0][RTW89_WW][0][41] = 12, + [2][1][2][0][RTW89_WW][1][41] = 22, + [2][1][2][0][RTW89_WW][0][48] = 22, + [2][1][2][0][RTW89_WW][1][48] = 22, + [2][1][2][0][RTW89_WW][0][56] = 20, + [2][1][2][0][RTW89_WW][1][56] = 20, + [2][1][2][0][RTW89_WW][0][63] = 22, + [2][1][2][0][RTW89_WW][1][63] = 22, + [2][1][2][0][RTW89_WW][0][71] = 20, + [2][1][2][0][RTW89_WW][1][71] = 20, + [2][1][2][0][RTW89_WW][0][78] = 20, + [2][1][2][0][RTW89_WW][1][78] = 20, + [2][1][2][0][RTW89_WW][0][86] = 20, + [2][1][2][0][RTW89_WW][1][86] = 20, + [2][1][2][0][RTW89_WW][0][93] = 22, + [2][1][2][0][RTW89_WW][1][93] = 22, + [2][1][2][0][RTW89_WW][0][101] = 22, + [2][1][2][0][RTW89_WW][1][101] = 22, + [2][1][2][0][RTW89_WW][0][108] = 0, + [2][1][2][0][RTW89_WW][1][108] = 0, + [2][1][2][0][RTW89_WW][0][116] = 0, + [2][1][2][0][RTW89_WW][1][116] = 0, + [2][1][2][1][RTW89_WW][0][3] = 6, + [2][1][2][1][RTW89_WW][1][3] = 22, + [2][1][2][1][RTW89_WW][0][11] = 6, + [2][1][2][1][RTW89_WW][1][11] = 20, + [2][1][2][1][RTW89_WW][0][18] = 6, + [2][1][2][1][RTW89_WW][1][18] = 20, + [2][1][2][1][RTW89_WW][0][26] = 6, + [2][1][2][1][RTW89_WW][1][26] = 20, + [2][1][2][1][RTW89_WW][0][33] = 6, + [2][1][2][1][RTW89_WW][1][33] = 20, + [2][1][2][1][RTW89_WW][0][41] = 6, + [2][1][2][1][RTW89_WW][1][41] = 22, + [2][1][2][1][RTW89_WW][0][48] = 22, + [2][1][2][1][RTW89_WW][1][48] = 22, + [2][1][2][1][RTW89_WW][0][56] = 20, + [2][1][2][1][RTW89_WW][1][56] = 20, + [2][1][2][1][RTW89_WW][0][63] = 22, + [2][1][2][1][RTW89_WW][1][63] = 22, + [2][1][2][1][RTW89_WW][0][71] = 20, + [2][1][2][1][RTW89_WW][1][71] = 20, + [2][1][2][1][RTW89_WW][0][78] = 20, + [2][1][2][1][RTW89_WW][1][78] = 20, + [2][1][2][1][RTW89_WW][0][86] = 20, + [2][1][2][1][RTW89_WW][1][86] = 20, + [2][1][2][1][RTW89_WW][0][93] = 22, + [2][1][2][1][RTW89_WW][1][93] = 22, + [2][1][2][1][RTW89_WW][0][101] = 22, + [2][1][2][1][RTW89_WW][1][101] = 22, + [2][1][2][1][RTW89_WW][0][108] = 0, + [2][1][2][1][RTW89_WW][1][108] = 0, + [2][1][2][1][RTW89_WW][0][116] = 0, + [2][1][2][1][RTW89_WW][1][116] = 0, + [3][0][2][0][RTW89_WW][0][7] = 22, + [3][0][2][0][RTW89_WW][1][7] = 42, + [3][0][2][0][RTW89_WW][0][22] = 20, + [3][0][2][0][RTW89_WW][1][22] = 42, + [3][0][2][0][RTW89_WW][0][37] = 20, + [3][0][2][0][RTW89_WW][1][37] = 42, + [3][0][2][0][RTW89_WW][0][52] = 54, + [3][0][2][0][RTW89_WW][1][52] = 54, + [3][0][2][0][RTW89_WW][0][67] = 54, + [3][0][2][0][RTW89_WW][1][67] = 54, + [3][0][2][0][RTW89_WW][0][82] = 26, + [3][0][2][0][RTW89_WW][1][82] = 26, + [3][0][2][0][RTW89_WW][0][97] = 26, + [3][0][2][0][RTW89_WW][1][97] = 26, + [3][0][2][0][RTW89_WW][0][112] = 0, + [3][0][2][0][RTW89_WW][1][112] = 0, + [3][1][2][0][RTW89_WW][0][7] = 10, + [3][1][2][0][RTW89_WW][1][7] = 32, + [3][1][2][0][RTW89_WW][0][22] = 8, + [3][1][2][0][RTW89_WW][1][22] = 30, + [3][1][2][0][RTW89_WW][0][37] = 8, + [3][1][2][0][RTW89_WW][1][37] = 30, + [3][1][2][0][RTW89_WW][0][52] = 30, + [3][1][2][0][RTW89_WW][1][52] = 30, + [3][1][2][0][RTW89_WW][0][67] = 32, + [3][1][2][0][RTW89_WW][1][67] = 32, + [3][1][2][0][RTW89_WW][0][82] = 24, + [3][1][2][0][RTW89_WW][1][82] = 24, + [3][1][2][0][RTW89_WW][0][97] = 24, + [3][1][2][0][RTW89_WW][1][97] = 24, + [3][1][2][0][RTW89_WW][0][112] = 0, + [3][1][2][0][RTW89_WW][1][112] = 0, + [3][1][2][1][RTW89_WW][0][7] = 6, + [3][1][2][1][RTW89_WW][1][7] = 32, + [3][1][2][1][RTW89_WW][0][22] = 6, + [3][1][2][1][RTW89_WW][1][22] = 30, + [3][1][2][1][RTW89_WW][0][37] = 6, + [3][1][2][1][RTW89_WW][1][37] = 30, + [3][1][2][1][RTW89_WW][0][52] = 30, + [3][1][2][1][RTW89_WW][1][52] = 30, + [3][1][2][1][RTW89_WW][0][67] = 32, + [3][1][2][1][RTW89_WW][1][67] = 32, + [3][1][2][1][RTW89_WW][0][82] = 24, + [3][1][2][1][RTW89_WW][1][82] = 24, + [3][1][2][1][RTW89_WW][0][97] = 24, + [3][1][2][1][RTW89_WW][1][97] = 24, + [3][1][2][1][RTW89_WW][0][112] = 0, + [3][1][2][1][RTW89_WW][1][112] = 0, + [0][0][1][0][RTW89_FCC][1][0] = 24, + [0][0][1][0][RTW89_ETSI][1][0] = 66, + [0][0][1][0][RTW89_ETSI][0][0] = 28, + [0][0][1][0][RTW89_MKK][1][0] = 66, + [0][0][1][0][RTW89_MKK][0][0] = 26, + [0][0][1][0][RTW89_IC][1][0] = 24, + [0][0][1][0][RTW89_KCC][1][0] = 24, + [0][0][1][0][RTW89_KCC][0][0] = 24, + [0][0][1][0][RTW89_ACMA][1][0] = 66, + [0][0][1][0][RTW89_ACMA][0][0] = 28, + [0][0][1][0][RTW89_CHILE][1][0] = 24, + [0][0][1][0][RTW89_QATAR][1][0] = 66, + [0][0][1][0][RTW89_QATAR][0][0] = 28, + [0][0][1][0][RTW89_UK][1][0] = 66, + [0][0][1][0][RTW89_UK][0][0] = 28, + [0][0][1][0][RTW89_THAILAND][1][0] = 56, + [0][0][1][0][RTW89_THAILAND][0][0] = 24, + [0][0][1][0][RTW89_FCC][1][2] = 22, + [0][0][1][0][RTW89_ETSI][1][2] = 66, + [0][0][1][0][RTW89_ETSI][0][2] = 28, + [0][0][1][0][RTW89_MKK][1][2] = 66, + [0][0][1][0][RTW89_MKK][0][2] = 26, + [0][0][1][0][RTW89_IC][1][2] = 22, + [0][0][1][0][RTW89_KCC][1][2] = 24, + [0][0][1][0][RTW89_KCC][0][2] = 24, + [0][0][1][0][RTW89_ACMA][1][2] = 66, + [0][0][1][0][RTW89_ACMA][0][2] = 28, + [0][0][1][0][RTW89_CHILE][1][2] = 22, + [0][0][1][0][RTW89_QATAR][1][2] = 66, + [0][0][1][0][RTW89_QATAR][0][2] = 28, + [0][0][1][0][RTW89_UK][1][2] = 66, + [0][0][1][0][RTW89_UK][0][2] = 28, + [0][0][1][0][RTW89_THAILAND][1][2] = 56, + [0][0][1][0][RTW89_THAILAND][0][2] = 22, + [0][0][1][0][RTW89_FCC][1][4] = 22, + [0][0][1][0][RTW89_ETSI][1][4] = 66, + [0][0][1][0][RTW89_ETSI][0][4] = 28, + [0][0][1][0][RTW89_MKK][1][4] = 66, + [0][0][1][0][RTW89_MKK][0][4] = 26, + [0][0][1][0][RTW89_IC][1][4] = 22, + [0][0][1][0][RTW89_KCC][1][4] = 24, + [0][0][1][0][RTW89_KCC][0][4] = 24, + [0][0][1][0][RTW89_ACMA][1][4] = 66, + [0][0][1][0][RTW89_ACMA][0][4] = 28, + [0][0][1][0][RTW89_CHILE][1][4] = 22, + [0][0][1][0][RTW89_QATAR][1][4] = 66, + [0][0][1][0][RTW89_QATAR][0][4] = 28, + [0][0][1][0][RTW89_UK][1][4] = 66, + [0][0][1][0][RTW89_UK][0][4] = 28, + [0][0][1][0][RTW89_THAILAND][1][4] = 56, + [0][0][1][0][RTW89_THAILAND][0][4] = 22, + [0][0][1][0][RTW89_FCC][1][6] = 22, + [0][0][1][0][RTW89_ETSI][1][6] = 66, + [0][0][1][0][RTW89_ETSI][0][6] = 28, + [0][0][1][0][RTW89_MKK][1][6] = 66, + [0][0][1][0][RTW89_MKK][0][6] = 26, + [0][0][1][0][RTW89_IC][1][6] = 22, + [0][0][1][0][RTW89_KCC][1][6] = 24, + [0][0][1][0][RTW89_KCC][0][6] = 24, + [0][0][1][0][RTW89_ACMA][1][6] = 66, + [0][0][1][0][RTW89_ACMA][0][6] = 28, + [0][0][1][0][RTW89_CHILE][1][6] = 22, + [0][0][1][0][RTW89_QATAR][1][6] = 66, + [0][0][1][0][RTW89_QATAR][0][6] = 28, + [0][0][1][0][RTW89_UK][1][6] = 66, + [0][0][1][0][RTW89_UK][0][6] = 28, + [0][0][1][0][RTW89_THAILAND][1][6] = 56, + [0][0][1][0][RTW89_THAILAND][0][6] = 22, + [0][0][1][0][RTW89_FCC][1][8] = 22, + [0][0][1][0][RTW89_ETSI][1][8] = 66, + [0][0][1][0][RTW89_ETSI][0][8] = 28, + [0][0][1][0][RTW89_MKK][1][8] = 66, + [0][0][1][0][RTW89_MKK][0][8] = 26, + [0][0][1][0][RTW89_IC][1][8] = 22, + [0][0][1][0][RTW89_KCC][1][8] = 24, + [0][0][1][0][RTW89_KCC][0][8] = 24, + [0][0][1][0][RTW89_ACMA][1][8] = 66, + [0][0][1][0][RTW89_ACMA][0][8] = 28, + [0][0][1][0][RTW89_CHILE][1][8] = 22, + [0][0][1][0][RTW89_QATAR][1][8] = 66, + [0][0][1][0][RTW89_QATAR][0][8] = 28, + [0][0][1][0][RTW89_UK][1][8] = 66, + [0][0][1][0][RTW89_UK][0][8] = 28, + [0][0][1][0][RTW89_THAILAND][1][8] = 56, + [0][0][1][0][RTW89_THAILAND][0][8] = 22, + [0][0][1][0][RTW89_FCC][1][10] = 22, + [0][0][1][0][RTW89_ETSI][1][10] = 66, + [0][0][1][0][RTW89_ETSI][0][10] = 28, + [0][0][1][0][RTW89_MKK][1][10] = 66, + [0][0][1][0][RTW89_MKK][0][10] = 26, + [0][0][1][0][RTW89_IC][1][10] = 22, + [0][0][1][0][RTW89_KCC][1][10] = 24, + [0][0][1][0][RTW89_KCC][0][10] = 24, + [0][0][1][0][RTW89_ACMA][1][10] = 66, + [0][0][1][0][RTW89_ACMA][0][10] = 28, + [0][0][1][0][RTW89_CHILE][1][10] = 22, + [0][0][1][0][RTW89_QATAR][1][10] = 66, + [0][0][1][0][RTW89_QATAR][0][10] = 28, + [0][0][1][0][RTW89_UK][1][10] = 66, + [0][0][1][0][RTW89_UK][0][10] = 28, + [0][0][1][0][RTW89_THAILAND][1][10] = 56, + [0][0][1][0][RTW89_THAILAND][0][10] = 22, + [0][0][1][0][RTW89_FCC][1][12] = 22, + [0][0][1][0][RTW89_ETSI][1][12] = 66, + [0][0][1][0][RTW89_ETSI][0][12] = 28, + [0][0][1][0][RTW89_MKK][1][12] = 66, + [0][0][1][0][RTW89_MKK][0][12] = 26, + [0][0][1][0][RTW89_IC][1][12] = 22, + [0][0][1][0][RTW89_KCC][1][12] = 24, + [0][0][1][0][RTW89_KCC][0][12] = 24, + [0][0][1][0][RTW89_ACMA][1][12] = 66, + [0][0][1][0][RTW89_ACMA][0][12] = 28, + [0][0][1][0][RTW89_CHILE][1][12] = 22, + [0][0][1][0][RTW89_QATAR][1][12] = 66, + [0][0][1][0][RTW89_QATAR][0][12] = 28, + [0][0][1][0][RTW89_UK][1][12] = 66, + [0][0][1][0][RTW89_UK][0][12] = 28, + [0][0][1][0][RTW89_THAILAND][1][12] = 56, + [0][0][1][0][RTW89_THAILAND][0][12] = 22, + [0][0][1][0][RTW89_FCC][1][14] = 22, + [0][0][1][0][RTW89_ETSI][1][14] = 66, + [0][0][1][0][RTW89_ETSI][0][14] = 28, + [0][0][1][0][RTW89_MKK][1][14] = 66, + [0][0][1][0][RTW89_MKK][0][14] = 26, + [0][0][1][0][RTW89_IC][1][14] = 22, + [0][0][1][0][RTW89_KCC][1][14] = 24, + [0][0][1][0][RTW89_KCC][0][14] = 24, + [0][0][1][0][RTW89_ACMA][1][14] = 66, + [0][0][1][0][RTW89_ACMA][0][14] = 28, + [0][0][1][0][RTW89_CHILE][1][14] = 22, + [0][0][1][0][RTW89_QATAR][1][14] = 66, + [0][0][1][0][RTW89_QATAR][0][14] = 28, + [0][0][1][0][RTW89_UK][1][14] = 66, + [0][0][1][0][RTW89_UK][0][14] = 28, + [0][0][1][0][RTW89_THAILAND][1][14] = 56, + [0][0][1][0][RTW89_THAILAND][0][14] = 22, + [0][0][1][0][RTW89_FCC][1][15] = 22, + [0][0][1][0][RTW89_ETSI][1][15] = 66, + [0][0][1][0][RTW89_ETSI][0][15] = 28, + [0][0][1][0][RTW89_MKK][1][15] = 66, + [0][0][1][0][RTW89_MKK][0][15] = 26, + [0][0][1][0][RTW89_IC][1][15] = 22, + [0][0][1][0][RTW89_KCC][1][15] = 24, + [0][0][1][0][RTW89_KCC][0][15] = 24, + [0][0][1][0][RTW89_ACMA][1][15] = 66, + [0][0][1][0][RTW89_ACMA][0][15] = 28, + [0][0][1][0][RTW89_CHILE][1][15] = 22, + [0][0][1][0][RTW89_QATAR][1][15] = 66, + [0][0][1][0][RTW89_QATAR][0][15] = 28, + [0][0][1][0][RTW89_UK][1][15] = 66, + [0][0][1][0][RTW89_UK][0][15] = 28, + [0][0][1][0][RTW89_THAILAND][1][15] = 56, + [0][0][1][0][RTW89_THAILAND][0][15] = 22, + [0][0][1][0][RTW89_FCC][1][17] = 22, + [0][0][1][0][RTW89_ETSI][1][17] = 66, + [0][0][1][0][RTW89_ETSI][0][17] = 28, + [0][0][1][0][RTW89_MKK][1][17] = 66, + [0][0][1][0][RTW89_MKK][0][17] = 26, + [0][0][1][0][RTW89_IC][1][17] = 22, + [0][0][1][0][RTW89_KCC][1][17] = 24, + [0][0][1][0][RTW89_KCC][0][17] = 24, + [0][0][1][0][RTW89_ACMA][1][17] = 66, + [0][0][1][0][RTW89_ACMA][0][17] = 28, + [0][0][1][0][RTW89_CHILE][1][17] = 22, + [0][0][1][0][RTW89_QATAR][1][17] = 66, + [0][0][1][0][RTW89_QATAR][0][17] = 28, + [0][0][1][0][RTW89_UK][1][17] = 66, + [0][0][1][0][RTW89_UK][0][17] = 28, + [0][0][1][0][RTW89_THAILAND][1][17] = 56, + [0][0][1][0][RTW89_THAILAND][0][17] = 22, + [0][0][1][0][RTW89_FCC][1][19] = 22, + [0][0][1][0][RTW89_ETSI][1][19] = 66, + [0][0][1][0][RTW89_ETSI][0][19] = 28, + [0][0][1][0][RTW89_MKK][1][19] = 66, + [0][0][1][0][RTW89_MKK][0][19] = 26, + [0][0][1][0][RTW89_IC][1][19] = 22, + [0][0][1][0][RTW89_KCC][1][19] = 24, + [0][0][1][0][RTW89_KCC][0][19] = 24, + [0][0][1][0][RTW89_ACMA][1][19] = 66, + [0][0][1][0][RTW89_ACMA][0][19] = 28, + [0][0][1][0][RTW89_CHILE][1][19] = 22, + [0][0][1][0][RTW89_QATAR][1][19] = 66, + [0][0][1][0][RTW89_QATAR][0][19] = 28, + [0][0][1][0][RTW89_UK][1][19] = 66, + [0][0][1][0][RTW89_UK][0][19] = 28, + [0][0][1][0][RTW89_THAILAND][1][19] = 56, + [0][0][1][0][RTW89_THAILAND][0][19] = 22, + [0][0][1][0][RTW89_FCC][1][21] = 22, + [0][0][1][0][RTW89_ETSI][1][21] = 66, + [0][0][1][0][RTW89_ETSI][0][21] = 28, + [0][0][1][0][RTW89_MKK][1][21] = 66, + [0][0][1][0][RTW89_MKK][0][21] = 26, + [0][0][1][0][RTW89_IC][1][21] = 22, + [0][0][1][0][RTW89_KCC][1][21] = 24, + [0][0][1][0][RTW89_KCC][0][21] = 24, + [0][0][1][0][RTW89_ACMA][1][21] = 66, + [0][0][1][0][RTW89_ACMA][0][21] = 28, + [0][0][1][0][RTW89_CHILE][1][21] = 22, + [0][0][1][0][RTW89_QATAR][1][21] = 66, + [0][0][1][0][RTW89_QATAR][0][21] = 28, + [0][0][1][0][RTW89_UK][1][21] = 66, + [0][0][1][0][RTW89_UK][0][21] = 28, + [0][0][1][0][RTW89_THAILAND][1][21] = 56, + [0][0][1][0][RTW89_THAILAND][0][21] = 22, + [0][0][1][0][RTW89_FCC][1][23] = 22, + [0][0][1][0][RTW89_ETSI][1][23] = 66, + [0][0][1][0][RTW89_ETSI][0][23] = 28, + [0][0][1][0][RTW89_MKK][1][23] = 66, + [0][0][1][0][RTW89_MKK][0][23] = 26, + [0][0][1][0][RTW89_IC][1][23] = 22, + [0][0][1][0][RTW89_KCC][1][23] = 24, + [0][0][1][0][RTW89_KCC][0][23] = 26, + [0][0][1][0][RTW89_ACMA][1][23] = 66, + [0][0][1][0][RTW89_ACMA][0][23] = 28, + [0][0][1][0][RTW89_CHILE][1][23] = 22, + [0][0][1][0][RTW89_QATAR][1][23] = 66, + [0][0][1][0][RTW89_QATAR][0][23] = 28, + [0][0][1][0][RTW89_UK][1][23] = 66, + [0][0][1][0][RTW89_UK][0][23] = 28, + [0][0][1][0][RTW89_THAILAND][1][23] = 66, + [0][0][1][0][RTW89_THAILAND][0][23] = 22, + [0][0][1][0][RTW89_FCC][1][25] = 22, + [0][0][1][0][RTW89_ETSI][1][25] = 66, + [0][0][1][0][RTW89_ETSI][0][25] = 28, + [0][0][1][0][RTW89_MKK][1][25] = 66, + [0][0][1][0][RTW89_MKK][0][25] = 26, + [0][0][1][0][RTW89_IC][1][25] = 22, + [0][0][1][0][RTW89_KCC][1][25] = 24, + [0][0][1][0][RTW89_KCC][0][25] = 26, + [0][0][1][0][RTW89_ACMA][1][25] = 66, + [0][0][1][0][RTW89_ACMA][0][25] = 28, + [0][0][1][0][RTW89_CHILE][1][25] = 22, + [0][0][1][0][RTW89_QATAR][1][25] = 66, + [0][0][1][0][RTW89_QATAR][0][25] = 28, + [0][0][1][0][RTW89_UK][1][25] = 66, + [0][0][1][0][RTW89_UK][0][25] = 28, + [0][0][1][0][RTW89_THAILAND][1][25] = 66, + [0][0][1][0][RTW89_THAILAND][0][25] = 22, + [0][0][1][0][RTW89_FCC][1][27] = 22, + [0][0][1][0][RTW89_ETSI][1][27] = 66, + [0][0][1][0][RTW89_ETSI][0][27] = 28, + [0][0][1][0][RTW89_MKK][1][27] = 66, + [0][0][1][0][RTW89_MKK][0][27] = 26, + [0][0][1][0][RTW89_IC][1][27] = 22, + [0][0][1][0][RTW89_KCC][1][27] = 24, + [0][0][1][0][RTW89_KCC][0][27] = 26, + [0][0][1][0][RTW89_ACMA][1][27] = 66, + [0][0][1][0][RTW89_ACMA][0][27] = 28, + [0][0][1][0][RTW89_CHILE][1][27] = 22, + [0][0][1][0][RTW89_QATAR][1][27] = 66, + [0][0][1][0][RTW89_QATAR][0][27] = 28, + [0][0][1][0][RTW89_UK][1][27] = 66, + [0][0][1][0][RTW89_UK][0][27] = 28, + [0][0][1][0][RTW89_THAILAND][1][27] = 66, + [0][0][1][0][RTW89_THAILAND][0][27] = 22, + [0][0][1][0][RTW89_FCC][1][29] = 22, + [0][0][1][0][RTW89_ETSI][1][29] = 66, + [0][0][1][0][RTW89_ETSI][0][29] = 28, + [0][0][1][0][RTW89_MKK][1][29] = 66, + [0][0][1][0][RTW89_MKK][0][29] = 26, + [0][0][1][0][RTW89_IC][1][29] = 22, + [0][0][1][0][RTW89_KCC][1][29] = 24, + [0][0][1][0][RTW89_KCC][0][29] = 26, + [0][0][1][0][RTW89_ACMA][1][29] = 66, + [0][0][1][0][RTW89_ACMA][0][29] = 28, + [0][0][1][0][RTW89_CHILE][1][29] = 22, + [0][0][1][0][RTW89_QATAR][1][29] = 66, + [0][0][1][0][RTW89_QATAR][0][29] = 28, + [0][0][1][0][RTW89_UK][1][29] = 66, + [0][0][1][0][RTW89_UK][0][29] = 28, + [0][0][1][0][RTW89_THAILAND][1][29] = 66, + [0][0][1][0][RTW89_THAILAND][0][29] = 22, + [0][0][1][0][RTW89_FCC][1][30] = 22, + [0][0][1][0][RTW89_ETSI][1][30] = 66, + [0][0][1][0][RTW89_ETSI][0][30] = 28, + [0][0][1][0][RTW89_MKK][1][30] = 66, + [0][0][1][0][RTW89_MKK][0][30] = 26, + [0][0][1][0][RTW89_IC][1][30] = 22, + [0][0][1][0][RTW89_KCC][1][30] = 24, + [0][0][1][0][RTW89_KCC][0][30] = 26, + [0][0][1][0][RTW89_ACMA][1][30] = 66, + [0][0][1][0][RTW89_ACMA][0][30] = 28, + [0][0][1][0][RTW89_CHILE][1][30] = 22, + [0][0][1][0][RTW89_QATAR][1][30] = 66, + [0][0][1][0][RTW89_QATAR][0][30] = 28, + [0][0][1][0][RTW89_UK][1][30] = 66, + [0][0][1][0][RTW89_UK][0][30] = 28, + [0][0][1][0][RTW89_THAILAND][1][30] = 66, + [0][0][1][0][RTW89_THAILAND][0][30] = 22, + [0][0][1][0][RTW89_FCC][1][32] = 22, + [0][0][1][0][RTW89_ETSI][1][32] = 66, + [0][0][1][0][RTW89_ETSI][0][32] = 28, + [0][0][1][0][RTW89_MKK][1][32] = 66, + [0][0][1][0][RTW89_MKK][0][32] = 26, + [0][0][1][0][RTW89_IC][1][32] = 22, + [0][0][1][0][RTW89_KCC][1][32] = 24, + [0][0][1][0][RTW89_KCC][0][32] = 26, + [0][0][1][0][RTW89_ACMA][1][32] = 66, + [0][0][1][0][RTW89_ACMA][0][32] = 28, + [0][0][1][0][RTW89_CHILE][1][32] = 22, + [0][0][1][0][RTW89_QATAR][1][32] = 66, + [0][0][1][0][RTW89_QATAR][0][32] = 28, + [0][0][1][0][RTW89_UK][1][32] = 66, + [0][0][1][0][RTW89_UK][0][32] = 28, + [0][0][1][0][RTW89_THAILAND][1][32] = 66, + [0][0][1][0][RTW89_THAILAND][0][32] = 22, + [0][0][1][0][RTW89_FCC][1][34] = 22, + [0][0][1][0][RTW89_ETSI][1][34] = 66, + [0][0][1][0][RTW89_ETSI][0][34] = 28, + [0][0][1][0][RTW89_MKK][1][34] = 66, + [0][0][1][0][RTW89_MKK][0][34] = 26, + [0][0][1][0][RTW89_IC][1][34] = 22, + [0][0][1][0][RTW89_KCC][1][34] = 24, + [0][0][1][0][RTW89_KCC][0][34] = 26, + [0][0][1][0][RTW89_ACMA][1][34] = 66, + [0][0][1][0][RTW89_ACMA][0][34] = 28, + [0][0][1][0][RTW89_CHILE][1][34] = 22, + [0][0][1][0][RTW89_QATAR][1][34] = 66, + [0][0][1][0][RTW89_QATAR][0][34] = 28, + [0][0][1][0][RTW89_UK][1][34] = 66, + [0][0][1][0][RTW89_UK][0][34] = 28, + [0][0][1][0][RTW89_THAILAND][1][34] = 66, + [0][0][1][0][RTW89_THAILAND][0][34] = 22, + [0][0][1][0][RTW89_FCC][1][36] = 22, + [0][0][1][0][RTW89_ETSI][1][36] = 66, + [0][0][1][0][RTW89_ETSI][0][36] = 28, + [0][0][1][0][RTW89_MKK][1][36] = 66, + [0][0][1][0][RTW89_MKK][0][36] = 26, + [0][0][1][0][RTW89_IC][1][36] = 22, + [0][0][1][0][RTW89_KCC][1][36] = 24, + [0][0][1][0][RTW89_KCC][0][36] = 26, + [0][0][1][0][RTW89_ACMA][1][36] = 66, + [0][0][1][0][RTW89_ACMA][0][36] = 28, + [0][0][1][0][RTW89_CHILE][1][36] = 22, + [0][0][1][0][RTW89_QATAR][1][36] = 66, + [0][0][1][0][RTW89_QATAR][0][36] = 28, + [0][0][1][0][RTW89_UK][1][36] = 66, + [0][0][1][0][RTW89_UK][0][36] = 28, + [0][0][1][0][RTW89_THAILAND][1][36] = 66, + [0][0][1][0][RTW89_THAILAND][0][36] = 22, + [0][0][1][0][RTW89_FCC][1][38] = 22, + [0][0][1][0][RTW89_ETSI][1][38] = 66, + [0][0][1][0][RTW89_ETSI][0][38] = 28, + [0][0][1][0][RTW89_MKK][1][38] = 66, + [0][0][1][0][RTW89_MKK][0][38] = 26, + [0][0][1][0][RTW89_IC][1][38] = 22, + [0][0][1][0][RTW89_KCC][1][38] = 24, + [0][0][1][0][RTW89_KCC][0][38] = 26, + [0][0][1][0][RTW89_ACMA][1][38] = 66, + [0][0][1][0][RTW89_ACMA][0][38] = 28, + [0][0][1][0][RTW89_CHILE][1][38] = 22, + [0][0][1][0][RTW89_QATAR][1][38] = 66, + [0][0][1][0][RTW89_QATAR][0][38] = 28, + [0][0][1][0][RTW89_UK][1][38] = 66, + [0][0][1][0][RTW89_UK][0][38] = 28, + [0][0][1][0][RTW89_THAILAND][1][38] = 66, + [0][0][1][0][RTW89_THAILAND][0][38] = 22, + [0][0][1][0][RTW89_FCC][1][40] = 22, + [0][0][1][0][RTW89_ETSI][1][40] = 66, + [0][0][1][0][RTW89_ETSI][0][40] = 28, + [0][0][1][0][RTW89_MKK][1][40] = 66, + [0][0][1][0][RTW89_MKK][0][40] = 26, + [0][0][1][0][RTW89_IC][1][40] = 22, + [0][0][1][0][RTW89_KCC][1][40] = 24, + [0][0][1][0][RTW89_KCC][0][40] = 26, + [0][0][1][0][RTW89_ACMA][1][40] = 66, + [0][0][1][0][RTW89_ACMA][0][40] = 28, + [0][0][1][0][RTW89_CHILE][1][40] = 22, + [0][0][1][0][RTW89_QATAR][1][40] = 66, + [0][0][1][0][RTW89_QATAR][0][40] = 28, + [0][0][1][0][RTW89_UK][1][40] = 66, + [0][0][1][0][RTW89_UK][0][40] = 28, + [0][0][1][0][RTW89_THAILAND][1][40] = 66, + [0][0][1][0][RTW89_THAILAND][0][40] = 22, + [0][0][1][0][RTW89_FCC][1][42] = 22, + [0][0][1][0][RTW89_ETSI][1][42] = 66, + [0][0][1][0][RTW89_ETSI][0][42] = 28, + [0][0][1][0][RTW89_MKK][1][42] = 66, + [0][0][1][0][RTW89_MKK][0][42] = 26, + [0][0][1][0][RTW89_IC][1][42] = 22, + [0][0][1][0][RTW89_KCC][1][42] = 24, + [0][0][1][0][RTW89_KCC][0][42] = 26, + [0][0][1][0][RTW89_ACMA][1][42] = 66, + [0][0][1][0][RTW89_ACMA][0][42] = 28, + [0][0][1][0][RTW89_CHILE][1][42] = 22, + [0][0][1][0][RTW89_QATAR][1][42] = 66, + [0][0][1][0][RTW89_QATAR][0][42] = 28, + [0][0][1][0][RTW89_UK][1][42] = 66, + [0][0][1][0][RTW89_UK][0][42] = 28, + [0][0][1][0][RTW89_THAILAND][1][42] = 66, + [0][0][1][0][RTW89_THAILAND][0][42] = 22, + [0][0][1][0][RTW89_FCC][1][44] = 22, + [0][0][1][0][RTW89_ETSI][1][44] = 66, + [0][0][1][0][RTW89_ETSI][0][44] = 30, + [0][0][1][0][RTW89_MKK][1][44] = 44, + [0][0][1][0][RTW89_MKK][0][44] = 28, + [0][0][1][0][RTW89_IC][1][44] = 22, + [0][0][1][0][RTW89_KCC][1][44] = 24, + [0][0][1][0][RTW89_KCC][0][44] = 26, + [0][0][1][0][RTW89_ACMA][1][44] = 66, + [0][0][1][0][RTW89_ACMA][0][44] = 30, + [0][0][1][0][RTW89_CHILE][1][44] = 22, + [0][0][1][0][RTW89_QATAR][1][44] = 66, + [0][0][1][0][RTW89_QATAR][0][44] = 30, + [0][0][1][0][RTW89_UK][1][44] = 66, + [0][0][1][0][RTW89_UK][0][44] = 30, + [0][0][1][0][RTW89_THAILAND][1][44] = 68, + [0][0][1][0][RTW89_THAILAND][0][44] = 22, + [0][0][1][0][RTW89_FCC][1][45] = 22, + [0][0][1][0][RTW89_ETSI][1][45] = 127, + [0][0][1][0][RTW89_ETSI][0][45] = 127, + [0][0][1][0][RTW89_MKK][1][45] = 127, + [0][0][1][0][RTW89_MKK][0][45] = 127, + [0][0][1][0][RTW89_IC][1][45] = 22, + [0][0][1][0][RTW89_KCC][1][45] = 24, + [0][0][1][0][RTW89_KCC][0][45] = 127, + [0][0][1][0][RTW89_ACMA][1][45] = 127, + [0][0][1][0][RTW89_ACMA][0][45] = 127, + [0][0][1][0][RTW89_CHILE][1][45] = 22, + [0][0][1][0][RTW89_QATAR][1][45] = 127, + [0][0][1][0][RTW89_QATAR][0][45] = 127, + [0][0][1][0][RTW89_UK][1][45] = 127, + [0][0][1][0][RTW89_UK][0][45] = 127, + [0][0][1][0][RTW89_THAILAND][1][45] = 127, + [0][0][1][0][RTW89_THAILAND][0][45] = 127, + [0][0][1][0][RTW89_FCC][1][47] = 22, + [0][0][1][0][RTW89_ETSI][1][47] = 127, + [0][0][1][0][RTW89_ETSI][0][47] = 127, + [0][0][1][0][RTW89_MKK][1][47] = 127, + [0][0][1][0][RTW89_MKK][0][47] = 127, + [0][0][1][0][RTW89_IC][1][47] = 22, + [0][0][1][0][RTW89_KCC][1][47] = 24, + [0][0][1][0][RTW89_KCC][0][47] = 127, + [0][0][1][0][RTW89_ACMA][1][47] = 127, + [0][0][1][0][RTW89_ACMA][0][47] = 127, + [0][0][1][0][RTW89_CHILE][1][47] = 22, + [0][0][1][0][RTW89_QATAR][1][47] = 127, + [0][0][1][0][RTW89_QATAR][0][47] = 127, + [0][0][1][0][RTW89_UK][1][47] = 127, + [0][0][1][0][RTW89_UK][0][47] = 127, + [0][0][1][0][RTW89_THAILAND][1][47] = 127, + [0][0][1][0][RTW89_THAILAND][0][47] = 127, + [0][0][1][0][RTW89_FCC][1][49] = 24, + [0][0][1][0][RTW89_ETSI][1][49] = 127, + [0][0][1][0][RTW89_ETSI][0][49] = 127, + [0][0][1][0][RTW89_MKK][1][49] = 127, + [0][0][1][0][RTW89_MKK][0][49] = 127, + [0][0][1][0][RTW89_IC][1][49] = 24, + [0][0][1][0][RTW89_KCC][1][49] = 24, + [0][0][1][0][RTW89_KCC][0][49] = 127, + [0][0][1][0][RTW89_ACMA][1][49] = 127, + [0][0][1][0][RTW89_ACMA][0][49] = 127, + [0][0][1][0][RTW89_CHILE][1][49] = 24, + [0][0][1][0][RTW89_QATAR][1][49] = 127, + [0][0][1][0][RTW89_QATAR][0][49] = 127, + [0][0][1][0][RTW89_UK][1][49] = 127, + [0][0][1][0][RTW89_UK][0][49] = 127, + [0][0][1][0][RTW89_THAILAND][1][49] = 127, + [0][0][1][0][RTW89_THAILAND][0][49] = 127, + [0][0][1][0][RTW89_FCC][1][51] = 22, + [0][0][1][0][RTW89_ETSI][1][51] = 127, + [0][0][1][0][RTW89_ETSI][0][51] = 127, + [0][0][1][0][RTW89_MKK][1][51] = 127, + [0][0][1][0][RTW89_MKK][0][51] = 127, + [0][0][1][0][RTW89_IC][1][51] = 22, + [0][0][1][0][RTW89_KCC][1][51] = 24, + [0][0][1][0][RTW89_KCC][0][51] = 127, + [0][0][1][0][RTW89_ACMA][1][51] = 127, + [0][0][1][0][RTW89_ACMA][0][51] = 127, + [0][0][1][0][RTW89_CHILE][1][51] = 22, + [0][0][1][0][RTW89_QATAR][1][51] = 127, + [0][0][1][0][RTW89_QATAR][0][51] = 127, + [0][0][1][0][RTW89_UK][1][51] = 127, + [0][0][1][0][RTW89_UK][0][51] = 127, + [0][0][1][0][RTW89_THAILAND][1][51] = 127, + [0][0][1][0][RTW89_THAILAND][0][51] = 127, + [0][0][1][0][RTW89_FCC][1][53] = 22, + [0][0][1][0][RTW89_ETSI][1][53] = 127, + [0][0][1][0][RTW89_ETSI][0][53] = 127, + [0][0][1][0][RTW89_MKK][1][53] = 127, + [0][0][1][0][RTW89_MKK][0][53] = 127, + [0][0][1][0][RTW89_IC][1][53] = 22, + [0][0][1][0][RTW89_KCC][1][53] = 24, + [0][0][1][0][RTW89_KCC][0][53] = 127, + [0][0][1][0][RTW89_ACMA][1][53] = 127, + [0][0][1][0][RTW89_ACMA][0][53] = 127, + [0][0][1][0][RTW89_CHILE][1][53] = 22, + [0][0][1][0][RTW89_QATAR][1][53] = 127, + [0][0][1][0][RTW89_QATAR][0][53] = 127, + [0][0][1][0][RTW89_UK][1][53] = 127, + [0][0][1][0][RTW89_UK][0][53] = 127, + [0][0][1][0][RTW89_THAILAND][1][53] = 127, + [0][0][1][0][RTW89_THAILAND][0][53] = 127, + [0][0][1][0][RTW89_FCC][1][55] = 22, + [0][0][1][0][RTW89_ETSI][1][55] = 127, + [0][0][1][0][RTW89_ETSI][0][55] = 127, + [0][0][1][0][RTW89_MKK][1][55] = 127, + [0][0][1][0][RTW89_MKK][0][55] = 127, + [0][0][1][0][RTW89_IC][1][55] = 22, + [0][0][1][0][RTW89_KCC][1][55] = 26, + [0][0][1][0][RTW89_KCC][0][55] = 127, + [0][0][1][0][RTW89_ACMA][1][55] = 127, + [0][0][1][0][RTW89_ACMA][0][55] = 127, + [0][0][1][0][RTW89_CHILE][1][55] = 22, + [0][0][1][0][RTW89_QATAR][1][55] = 127, + [0][0][1][0][RTW89_QATAR][0][55] = 127, + [0][0][1][0][RTW89_UK][1][55] = 127, + [0][0][1][0][RTW89_UK][0][55] = 127, + [0][0][1][0][RTW89_THAILAND][1][55] = 127, + [0][0][1][0][RTW89_THAILAND][0][55] = 127, + [0][0][1][0][RTW89_FCC][1][57] = 22, + [0][0][1][0][RTW89_ETSI][1][57] = 127, + [0][0][1][0][RTW89_ETSI][0][57] = 127, + [0][0][1][0][RTW89_MKK][1][57] = 127, + [0][0][1][0][RTW89_MKK][0][57] = 127, + [0][0][1][0][RTW89_IC][1][57] = 22, + [0][0][1][0][RTW89_KCC][1][57] = 26, + [0][0][1][0][RTW89_KCC][0][57] = 127, + [0][0][1][0][RTW89_ACMA][1][57] = 127, + [0][0][1][0][RTW89_ACMA][0][57] = 127, + [0][0][1][0][RTW89_CHILE][1][57] = 22, + [0][0][1][0][RTW89_QATAR][1][57] = 127, + [0][0][1][0][RTW89_QATAR][0][57] = 127, + [0][0][1][0][RTW89_UK][1][57] = 127, + [0][0][1][0][RTW89_UK][0][57] = 127, + [0][0][1][0][RTW89_THAILAND][1][57] = 127, + [0][0][1][0][RTW89_THAILAND][0][57] = 127, + [0][0][1][0][RTW89_FCC][1][59] = 22, + [0][0][1][0][RTW89_ETSI][1][59] = 127, + [0][0][1][0][RTW89_ETSI][0][59] = 127, + [0][0][1][0][RTW89_MKK][1][59] = 127, + [0][0][1][0][RTW89_MKK][0][59] = 127, + [0][0][1][0][RTW89_IC][1][59] = 22, + [0][0][1][0][RTW89_KCC][1][59] = 26, + [0][0][1][0][RTW89_KCC][0][59] = 127, + [0][0][1][0][RTW89_ACMA][1][59] = 127, + [0][0][1][0][RTW89_ACMA][0][59] = 127, + [0][0][1][0][RTW89_CHILE][1][59] = 22, + [0][0][1][0][RTW89_QATAR][1][59] = 127, + [0][0][1][0][RTW89_QATAR][0][59] = 127, + [0][0][1][0][RTW89_UK][1][59] = 127, + [0][0][1][0][RTW89_UK][0][59] = 127, + [0][0][1][0][RTW89_THAILAND][1][59] = 127, + [0][0][1][0][RTW89_THAILAND][0][59] = 127, + [0][0][1][0][RTW89_FCC][1][60] = 22, + [0][0][1][0][RTW89_ETSI][1][60] = 127, + [0][0][1][0][RTW89_ETSI][0][60] = 127, + [0][0][1][0][RTW89_MKK][1][60] = 127, + [0][0][1][0][RTW89_MKK][0][60] = 127, + [0][0][1][0][RTW89_IC][1][60] = 22, + [0][0][1][0][RTW89_KCC][1][60] = 26, + [0][0][1][0][RTW89_KCC][0][60] = 127, + [0][0][1][0][RTW89_ACMA][1][60] = 127, + [0][0][1][0][RTW89_ACMA][0][60] = 127, + [0][0][1][0][RTW89_CHILE][1][60] = 22, + [0][0][1][0][RTW89_QATAR][1][60] = 127, + [0][0][1][0][RTW89_QATAR][0][60] = 127, + [0][0][1][0][RTW89_UK][1][60] = 127, + [0][0][1][0][RTW89_UK][0][60] = 127, + [0][0][1][0][RTW89_THAILAND][1][60] = 127, + [0][0][1][0][RTW89_THAILAND][0][60] = 127, + [0][0][1][0][RTW89_FCC][1][62] = 22, + [0][0][1][0][RTW89_ETSI][1][62] = 127, + [0][0][1][0][RTW89_ETSI][0][62] = 127, + [0][0][1][0][RTW89_MKK][1][62] = 127, + [0][0][1][0][RTW89_MKK][0][62] = 127, + [0][0][1][0][RTW89_IC][1][62] = 22, + [0][0][1][0][RTW89_KCC][1][62] = 26, + [0][0][1][0][RTW89_KCC][0][62] = 127, + [0][0][1][0][RTW89_ACMA][1][62] = 127, + [0][0][1][0][RTW89_ACMA][0][62] = 127, + [0][0][1][0][RTW89_CHILE][1][62] = 22, + [0][0][1][0][RTW89_QATAR][1][62] = 127, + [0][0][1][0][RTW89_QATAR][0][62] = 127, + [0][0][1][0][RTW89_UK][1][62] = 127, + [0][0][1][0][RTW89_UK][0][62] = 127, + [0][0][1][0][RTW89_THAILAND][1][62] = 127, + [0][0][1][0][RTW89_THAILAND][0][62] = 127, + [0][0][1][0][RTW89_FCC][1][64] = 22, + [0][0][1][0][RTW89_ETSI][1][64] = 127, + [0][0][1][0][RTW89_ETSI][0][64] = 127, + [0][0][1][0][RTW89_MKK][1][64] = 127, + [0][0][1][0][RTW89_MKK][0][64] = 127, + [0][0][1][0][RTW89_IC][1][64] = 22, + [0][0][1][0][RTW89_KCC][1][64] = 26, + [0][0][1][0][RTW89_KCC][0][64] = 127, + [0][0][1][0][RTW89_ACMA][1][64] = 127, + [0][0][1][0][RTW89_ACMA][0][64] = 127, + [0][0][1][0][RTW89_CHILE][1][64] = 22, + [0][0][1][0][RTW89_QATAR][1][64] = 127, + [0][0][1][0][RTW89_QATAR][0][64] = 127, + [0][0][1][0][RTW89_UK][1][64] = 127, + [0][0][1][0][RTW89_UK][0][64] = 127, + [0][0][1][0][RTW89_THAILAND][1][64] = 127, + [0][0][1][0][RTW89_THAILAND][0][64] = 127, + [0][0][1][0][RTW89_FCC][1][66] = 22, + [0][0][1][0][RTW89_ETSI][1][66] = 127, + [0][0][1][0][RTW89_ETSI][0][66] = 127, + [0][0][1][0][RTW89_MKK][1][66] = 127, + [0][0][1][0][RTW89_MKK][0][66] = 127, + [0][0][1][0][RTW89_IC][1][66] = 22, + [0][0][1][0][RTW89_KCC][1][66] = 26, + [0][0][1][0][RTW89_KCC][0][66] = 127, + [0][0][1][0][RTW89_ACMA][1][66] = 127, + [0][0][1][0][RTW89_ACMA][0][66] = 127, + [0][0][1][0][RTW89_CHILE][1][66] = 22, + [0][0][1][0][RTW89_QATAR][1][66] = 127, + [0][0][1][0][RTW89_QATAR][0][66] = 127, + [0][0][1][0][RTW89_UK][1][66] = 127, + [0][0][1][0][RTW89_UK][0][66] = 127, + [0][0][1][0][RTW89_THAILAND][1][66] = 127, + [0][0][1][0][RTW89_THAILAND][0][66] = 127, + [0][0][1][0][RTW89_FCC][1][68] = 22, + [0][0][1][0][RTW89_ETSI][1][68] = 127, + [0][0][1][0][RTW89_ETSI][0][68] = 127, + [0][0][1][0][RTW89_MKK][1][68] = 127, + [0][0][1][0][RTW89_MKK][0][68] = 127, + [0][0][1][0][RTW89_IC][1][68] = 22, + [0][0][1][0][RTW89_KCC][1][68] = 26, + [0][0][1][0][RTW89_KCC][0][68] = 127, + [0][0][1][0][RTW89_ACMA][1][68] = 127, + [0][0][1][0][RTW89_ACMA][0][68] = 127, + [0][0][1][0][RTW89_CHILE][1][68] = 22, + [0][0][1][0][RTW89_QATAR][1][68] = 127, + [0][0][1][0][RTW89_QATAR][0][68] = 127, + [0][0][1][0][RTW89_UK][1][68] = 127, + [0][0][1][0][RTW89_UK][0][68] = 127, + [0][0][1][0][RTW89_THAILAND][1][68] = 127, + [0][0][1][0][RTW89_THAILAND][0][68] = 127, + [0][0][1][0][RTW89_FCC][1][70] = 24, + [0][0][1][0][RTW89_ETSI][1][70] = 127, + [0][0][1][0][RTW89_ETSI][0][70] = 127, + [0][0][1][0][RTW89_MKK][1][70] = 127, + [0][0][1][0][RTW89_MKK][0][70] = 127, + [0][0][1][0][RTW89_IC][1][70] = 24, + [0][0][1][0][RTW89_KCC][1][70] = 26, + [0][0][1][0][RTW89_KCC][0][70] = 127, + [0][0][1][0][RTW89_ACMA][1][70] = 127, + [0][0][1][0][RTW89_ACMA][0][70] = 127, + [0][0][1][0][RTW89_CHILE][1][70] = 24, + [0][0][1][0][RTW89_QATAR][1][70] = 127, + [0][0][1][0][RTW89_QATAR][0][70] = 127, + [0][0][1][0][RTW89_UK][1][70] = 127, + [0][0][1][0][RTW89_UK][0][70] = 127, + [0][0][1][0][RTW89_THAILAND][1][70] = 127, + [0][0][1][0][RTW89_THAILAND][0][70] = 127, + [0][0][1][0][RTW89_FCC][1][72] = 22, + [0][0][1][0][RTW89_ETSI][1][72] = 127, + [0][0][1][0][RTW89_ETSI][0][72] = 127, + [0][0][1][0][RTW89_MKK][1][72] = 127, + [0][0][1][0][RTW89_MKK][0][72] = 127, + [0][0][1][0][RTW89_IC][1][72] = 22, + [0][0][1][0][RTW89_KCC][1][72] = 26, + [0][0][1][0][RTW89_KCC][0][72] = 127, + [0][0][1][0][RTW89_ACMA][1][72] = 127, + [0][0][1][0][RTW89_ACMA][0][72] = 127, + [0][0][1][0][RTW89_CHILE][1][72] = 22, + [0][0][1][0][RTW89_QATAR][1][72] = 127, + [0][0][1][0][RTW89_QATAR][0][72] = 127, + [0][0][1][0][RTW89_UK][1][72] = 127, + [0][0][1][0][RTW89_UK][0][72] = 127, + [0][0][1][0][RTW89_THAILAND][1][72] = 127, + [0][0][1][0][RTW89_THAILAND][0][72] = 127, + [0][0][1][0][RTW89_FCC][1][74] = 22, + [0][0][1][0][RTW89_ETSI][1][74] = 127, + [0][0][1][0][RTW89_ETSI][0][74] = 127, + [0][0][1][0][RTW89_MKK][1][74] = 127, + [0][0][1][0][RTW89_MKK][0][74] = 127, + [0][0][1][0][RTW89_IC][1][74] = 22, + [0][0][1][0][RTW89_KCC][1][74] = 26, + [0][0][1][0][RTW89_KCC][0][74] = 127, + [0][0][1][0][RTW89_ACMA][1][74] = 127, + [0][0][1][0][RTW89_ACMA][0][74] = 127, + [0][0][1][0][RTW89_CHILE][1][74] = 22, + [0][0][1][0][RTW89_QATAR][1][74] = 127, + [0][0][1][0][RTW89_QATAR][0][74] = 127, + [0][0][1][0][RTW89_UK][1][74] = 127, + [0][0][1][0][RTW89_UK][0][74] = 127, + [0][0][1][0][RTW89_THAILAND][1][74] = 127, + [0][0][1][0][RTW89_THAILAND][0][74] = 127, + [0][0][1][0][RTW89_FCC][1][75] = 22, + [0][0][1][0][RTW89_ETSI][1][75] = 127, + [0][0][1][0][RTW89_ETSI][0][75] = 127, + [0][0][1][0][RTW89_MKK][1][75] = 127, + [0][0][1][0][RTW89_MKK][0][75] = 127, + [0][0][1][0][RTW89_IC][1][75] = 22, + [0][0][1][0][RTW89_KCC][1][75] = 26, + [0][0][1][0][RTW89_KCC][0][75] = 127, + [0][0][1][0][RTW89_ACMA][1][75] = 127, + [0][0][1][0][RTW89_ACMA][0][75] = 127, + [0][0][1][0][RTW89_CHILE][1][75] = 22, + [0][0][1][0][RTW89_QATAR][1][75] = 127, + [0][0][1][0][RTW89_QATAR][0][75] = 127, + [0][0][1][0][RTW89_UK][1][75] = 127, + [0][0][1][0][RTW89_UK][0][75] = 127, + [0][0][1][0][RTW89_THAILAND][1][75] = 127, + [0][0][1][0][RTW89_THAILAND][0][75] = 127, + [0][0][1][0][RTW89_FCC][1][77] = 22, + [0][0][1][0][RTW89_ETSI][1][77] = 127, + [0][0][1][0][RTW89_ETSI][0][77] = 127, + [0][0][1][0][RTW89_MKK][1][77] = 127, + [0][0][1][0][RTW89_MKK][0][77] = 127, + [0][0][1][0][RTW89_IC][1][77] = 22, + [0][0][1][0][RTW89_KCC][1][77] = 26, + [0][0][1][0][RTW89_KCC][0][77] = 127, + [0][0][1][0][RTW89_ACMA][1][77] = 127, + [0][0][1][0][RTW89_ACMA][0][77] = 127, + [0][0][1][0][RTW89_CHILE][1][77] = 22, + [0][0][1][0][RTW89_QATAR][1][77] = 127, + [0][0][1][0][RTW89_QATAR][0][77] = 127, + [0][0][1][0][RTW89_UK][1][77] = 127, + [0][0][1][0][RTW89_UK][0][77] = 127, + [0][0][1][0][RTW89_THAILAND][1][77] = 127, + [0][0][1][0][RTW89_THAILAND][0][77] = 127, + [0][0][1][0][RTW89_FCC][1][79] = 22, + [0][0][1][0][RTW89_ETSI][1][79] = 127, + [0][0][1][0][RTW89_ETSI][0][79] = 127, + [0][0][1][0][RTW89_MKK][1][79] = 127, + [0][0][1][0][RTW89_MKK][0][79] = 127, + [0][0][1][0][RTW89_IC][1][79] = 22, + [0][0][1][0][RTW89_KCC][1][79] = 26, + [0][0][1][0][RTW89_KCC][0][79] = 127, + [0][0][1][0][RTW89_ACMA][1][79] = 127, + [0][0][1][0][RTW89_ACMA][0][79] = 127, + [0][0][1][0][RTW89_CHILE][1][79] = 22, + [0][0][1][0][RTW89_QATAR][1][79] = 127, + [0][0][1][0][RTW89_QATAR][0][79] = 127, + [0][0][1][0][RTW89_UK][1][79] = 127, + [0][0][1][0][RTW89_UK][0][79] = 127, + [0][0][1][0][RTW89_THAILAND][1][79] = 127, + [0][0][1][0][RTW89_THAILAND][0][79] = 127, + [0][0][1][0][RTW89_FCC][1][81] = 22, + [0][0][1][0][RTW89_ETSI][1][81] = 127, + [0][0][1][0][RTW89_ETSI][0][81] = 127, + [0][0][1][0][RTW89_MKK][1][81] = 127, + [0][0][1][0][RTW89_MKK][0][81] = 127, + [0][0][1][0][RTW89_IC][1][81] = 22, + [0][0][1][0][RTW89_KCC][1][81] = 26, + [0][0][1][0][RTW89_KCC][0][81] = 127, + [0][0][1][0][RTW89_ACMA][1][81] = 127, + [0][0][1][0][RTW89_ACMA][0][81] = 127, + [0][0][1][0][RTW89_CHILE][1][81] = 22, + [0][0][1][0][RTW89_QATAR][1][81] = 127, + [0][0][1][0][RTW89_QATAR][0][81] = 127, + [0][0][1][0][RTW89_UK][1][81] = 127, + [0][0][1][0][RTW89_UK][0][81] = 127, + [0][0][1][0][RTW89_THAILAND][1][81] = 127, + [0][0][1][0][RTW89_THAILAND][0][81] = 127, + [0][0][1][0][RTW89_FCC][1][83] = 22, + [0][0][1][0][RTW89_ETSI][1][83] = 127, + [0][0][1][0][RTW89_ETSI][0][83] = 127, + [0][0][1][0][RTW89_MKK][1][83] = 127, + [0][0][1][0][RTW89_MKK][0][83] = 127, + [0][0][1][0][RTW89_IC][1][83] = 22, + [0][0][1][0][RTW89_KCC][1][83] = 32, + [0][0][1][0][RTW89_KCC][0][83] = 127, + [0][0][1][0][RTW89_ACMA][1][83] = 127, + [0][0][1][0][RTW89_ACMA][0][83] = 127, + [0][0][1][0][RTW89_CHILE][1][83] = 22, + [0][0][1][0][RTW89_QATAR][1][83] = 127, + [0][0][1][0][RTW89_QATAR][0][83] = 127, + [0][0][1][0][RTW89_UK][1][83] = 127, + [0][0][1][0][RTW89_UK][0][83] = 127, + [0][0][1][0][RTW89_THAILAND][1][83] = 127, + [0][0][1][0][RTW89_THAILAND][0][83] = 127, + [0][0][1][0][RTW89_FCC][1][85] = 22, + [0][0][1][0][RTW89_ETSI][1][85] = 127, + [0][0][1][0][RTW89_ETSI][0][85] = 127, + [0][0][1][0][RTW89_MKK][1][85] = 127, + [0][0][1][0][RTW89_MKK][0][85] = 127, + [0][0][1][0][RTW89_IC][1][85] = 22, + [0][0][1][0][RTW89_KCC][1][85] = 32, + [0][0][1][0][RTW89_KCC][0][85] = 127, + [0][0][1][0][RTW89_ACMA][1][85] = 127, + [0][0][1][0][RTW89_ACMA][0][85] = 127, + [0][0][1][0][RTW89_CHILE][1][85] = 22, + [0][0][1][0][RTW89_QATAR][1][85] = 127, + [0][0][1][0][RTW89_QATAR][0][85] = 127, + [0][0][1][0][RTW89_UK][1][85] = 127, + [0][0][1][0][RTW89_UK][0][85] = 127, + [0][0][1][0][RTW89_THAILAND][1][85] = 127, + [0][0][1][0][RTW89_THAILAND][0][85] = 127, + [0][0][1][0][RTW89_FCC][1][87] = 22, + [0][0][1][0][RTW89_ETSI][1][87] = 127, + [0][0][1][0][RTW89_ETSI][0][87] = 127, + [0][0][1][0][RTW89_MKK][1][87] = 127, + [0][0][1][0][RTW89_MKK][0][87] = 127, + [0][0][1][0][RTW89_IC][1][87] = 22, + [0][0][1][0][RTW89_KCC][1][87] = 32, + [0][0][1][0][RTW89_KCC][0][87] = 127, + [0][0][1][0][RTW89_ACMA][1][87] = 127, + [0][0][1][0][RTW89_ACMA][0][87] = 127, + [0][0][1][0][RTW89_CHILE][1][87] = 22, + [0][0][1][0][RTW89_QATAR][1][87] = 127, + [0][0][1][0][RTW89_QATAR][0][87] = 127, + [0][0][1][0][RTW89_UK][1][87] = 127, + [0][0][1][0][RTW89_UK][0][87] = 127, + [0][0][1][0][RTW89_THAILAND][1][87] = 127, + [0][0][1][0][RTW89_THAILAND][0][87] = 127, + [0][0][1][0][RTW89_FCC][1][89] = 22, + [0][0][1][0][RTW89_ETSI][1][89] = 127, + [0][0][1][0][RTW89_ETSI][0][89] = 127, + [0][0][1][0][RTW89_MKK][1][89] = 127, + [0][0][1][0][RTW89_MKK][0][89] = 127, + [0][0][1][0][RTW89_IC][1][89] = 22, + [0][0][1][0][RTW89_KCC][1][89] = 32, + [0][0][1][0][RTW89_KCC][0][89] = 127, + [0][0][1][0][RTW89_ACMA][1][89] = 127, + [0][0][1][0][RTW89_ACMA][0][89] = 127, + [0][0][1][0][RTW89_CHILE][1][89] = 22, + [0][0][1][0][RTW89_QATAR][1][89] = 127, + [0][0][1][0][RTW89_QATAR][0][89] = 127, + [0][0][1][0][RTW89_UK][1][89] = 127, + [0][0][1][0][RTW89_UK][0][89] = 127, + [0][0][1][0][RTW89_THAILAND][1][89] = 127, + [0][0][1][0][RTW89_THAILAND][0][89] = 127, + [0][0][1][0][RTW89_FCC][1][90] = 22, + [0][0][1][0][RTW89_ETSI][1][90] = 127, + [0][0][1][0][RTW89_ETSI][0][90] = 127, + [0][0][1][0][RTW89_MKK][1][90] = 127, + [0][0][1][0][RTW89_MKK][0][90] = 127, + [0][0][1][0][RTW89_IC][1][90] = 22, + [0][0][1][0][RTW89_KCC][1][90] = 32, + [0][0][1][0][RTW89_KCC][0][90] = 127, + [0][0][1][0][RTW89_ACMA][1][90] = 127, + [0][0][1][0][RTW89_ACMA][0][90] = 127, + [0][0][1][0][RTW89_CHILE][1][90] = 22, + [0][0][1][0][RTW89_QATAR][1][90] = 127, + [0][0][1][0][RTW89_QATAR][0][90] = 127, + [0][0][1][0][RTW89_UK][1][90] = 127, + [0][0][1][0][RTW89_UK][0][90] = 127, + [0][0][1][0][RTW89_THAILAND][1][90] = 127, + [0][0][1][0][RTW89_THAILAND][0][90] = 127, + [0][0][1][0][RTW89_FCC][1][92] = 22, + [0][0][1][0][RTW89_ETSI][1][92] = 127, + [0][0][1][0][RTW89_ETSI][0][92] = 127, + [0][0][1][0][RTW89_MKK][1][92] = 127, + [0][0][1][0][RTW89_MKK][0][92] = 127, + [0][0][1][0][RTW89_IC][1][92] = 22, + [0][0][1][0][RTW89_KCC][1][92] = 32, + [0][0][1][0][RTW89_KCC][0][92] = 127, + [0][0][1][0][RTW89_ACMA][1][92] = 127, + [0][0][1][0][RTW89_ACMA][0][92] = 127, + [0][0][1][0][RTW89_CHILE][1][92] = 22, + [0][0][1][0][RTW89_QATAR][1][92] = 127, + [0][0][1][0][RTW89_QATAR][0][92] = 127, + [0][0][1][0][RTW89_UK][1][92] = 127, + [0][0][1][0][RTW89_UK][0][92] = 127, + [0][0][1][0][RTW89_THAILAND][1][92] = 127, + [0][0][1][0][RTW89_THAILAND][0][92] = 127, + [0][0][1][0][RTW89_FCC][1][94] = 22, + [0][0][1][0][RTW89_ETSI][1][94] = 127, + [0][0][1][0][RTW89_ETSI][0][94] = 127, + [0][0][1][0][RTW89_MKK][1][94] = 127, + [0][0][1][0][RTW89_MKK][0][94] = 127, + [0][0][1][0][RTW89_IC][1][94] = 22, + [0][0][1][0][RTW89_KCC][1][94] = 32, + [0][0][1][0][RTW89_KCC][0][94] = 127, + [0][0][1][0][RTW89_ACMA][1][94] = 127, + [0][0][1][0][RTW89_ACMA][0][94] = 127, + [0][0][1][0][RTW89_CHILE][1][94] = 22, + [0][0][1][0][RTW89_QATAR][1][94] = 127, + [0][0][1][0][RTW89_QATAR][0][94] = 127, + [0][0][1][0][RTW89_UK][1][94] = 127, + [0][0][1][0][RTW89_UK][0][94] = 127, + [0][0][1][0][RTW89_THAILAND][1][94] = 127, + [0][0][1][0][RTW89_THAILAND][0][94] = 127, + [0][0][1][0][RTW89_FCC][1][96] = 22, + [0][0][1][0][RTW89_ETSI][1][96] = 127, + [0][0][1][0][RTW89_ETSI][0][96] = 127, + [0][0][1][0][RTW89_MKK][1][96] = 127, + [0][0][1][0][RTW89_MKK][0][96] = 127, + [0][0][1][0][RTW89_IC][1][96] = 22, + [0][0][1][0][RTW89_KCC][1][96] = 32, + [0][0][1][0][RTW89_KCC][0][96] = 127, + [0][0][1][0][RTW89_ACMA][1][96] = 127, + [0][0][1][0][RTW89_ACMA][0][96] = 127, + [0][0][1][0][RTW89_CHILE][1][96] = 22, + [0][0][1][0][RTW89_QATAR][1][96] = 127, + [0][0][1][0][RTW89_QATAR][0][96] = 127, + [0][0][1][0][RTW89_UK][1][96] = 127, + [0][0][1][0][RTW89_UK][0][96] = 127, + [0][0][1][0][RTW89_THAILAND][1][96] = 127, + [0][0][1][0][RTW89_THAILAND][0][96] = 127, + [0][0][1][0][RTW89_FCC][1][98] = 22, + [0][0][1][0][RTW89_ETSI][1][98] = 127, + [0][0][1][0][RTW89_ETSI][0][98] = 127, + [0][0][1][0][RTW89_MKK][1][98] = 127, + [0][0][1][0][RTW89_MKK][0][98] = 127, + [0][0][1][0][RTW89_IC][1][98] = 22, + [0][0][1][0][RTW89_KCC][1][98] = 32, + [0][0][1][0][RTW89_KCC][0][98] = 127, + [0][0][1][0][RTW89_ACMA][1][98] = 127, + [0][0][1][0][RTW89_ACMA][0][98] = 127, + [0][0][1][0][RTW89_CHILE][1][98] = 22, + [0][0][1][0][RTW89_QATAR][1][98] = 127, + [0][0][1][0][RTW89_QATAR][0][98] = 127, + [0][0][1][0][RTW89_UK][1][98] = 127, + [0][0][1][0][RTW89_UK][0][98] = 127, + [0][0][1][0][RTW89_THAILAND][1][98] = 127, + [0][0][1][0][RTW89_THAILAND][0][98] = 127, + [0][0][1][0][RTW89_FCC][1][100] = 22, + [0][0][1][0][RTW89_ETSI][1][100] = 127, + [0][0][1][0][RTW89_ETSI][0][100] = 127, + [0][0][1][0][RTW89_MKK][1][100] = 127, + [0][0][1][0][RTW89_MKK][0][100] = 127, + [0][0][1][0][RTW89_IC][1][100] = 22, + [0][0][1][0][RTW89_KCC][1][100] = 32, + [0][0][1][0][RTW89_KCC][0][100] = 127, + [0][0][1][0][RTW89_ACMA][1][100] = 127, + [0][0][1][0][RTW89_ACMA][0][100] = 127, + [0][0][1][0][RTW89_CHILE][1][100] = 22, + [0][0][1][0][RTW89_QATAR][1][100] = 127, + [0][0][1][0][RTW89_QATAR][0][100] = 127, + [0][0][1][0][RTW89_UK][1][100] = 127, + [0][0][1][0][RTW89_UK][0][100] = 127, + [0][0][1][0][RTW89_THAILAND][1][100] = 127, + [0][0][1][0][RTW89_THAILAND][0][100] = 127, + [0][0][1][0][RTW89_FCC][1][102] = 22, + [0][0][1][0][RTW89_ETSI][1][102] = 127, + [0][0][1][0][RTW89_ETSI][0][102] = 127, + [0][0][1][0][RTW89_MKK][1][102] = 127, + [0][0][1][0][RTW89_MKK][0][102] = 127, + [0][0][1][0][RTW89_IC][1][102] = 22, + [0][0][1][0][RTW89_KCC][1][102] = 32, + [0][0][1][0][RTW89_KCC][0][102] = 127, + [0][0][1][0][RTW89_ACMA][1][102] = 127, + [0][0][1][0][RTW89_ACMA][0][102] = 127, + [0][0][1][0][RTW89_CHILE][1][102] = 22, + [0][0][1][0][RTW89_QATAR][1][102] = 127, + [0][0][1][0][RTW89_QATAR][0][102] = 127, + [0][0][1][0][RTW89_UK][1][102] = 127, + [0][0][1][0][RTW89_UK][0][102] = 127, + [0][0][1][0][RTW89_THAILAND][1][102] = 127, + [0][0][1][0][RTW89_THAILAND][0][102] = 127, + [0][0][1][0][RTW89_FCC][1][104] = 22, + [0][0][1][0][RTW89_ETSI][1][104] = 127, + [0][0][1][0][RTW89_ETSI][0][104] = 127, + [0][0][1][0][RTW89_MKK][1][104] = 127, + [0][0][1][0][RTW89_MKK][0][104] = 127, + [0][0][1][0][RTW89_IC][1][104] = 22, + [0][0][1][0][RTW89_KCC][1][104] = 32, + [0][0][1][0][RTW89_KCC][0][104] = 127, + [0][0][1][0][RTW89_ACMA][1][104] = 127, + [0][0][1][0][RTW89_ACMA][0][104] = 127, + [0][0][1][0][RTW89_CHILE][1][104] = 22, + [0][0][1][0][RTW89_QATAR][1][104] = 127, + [0][0][1][0][RTW89_QATAR][0][104] = 127, + [0][0][1][0][RTW89_UK][1][104] = 127, + [0][0][1][0][RTW89_UK][0][104] = 127, + [0][0][1][0][RTW89_THAILAND][1][104] = 127, + [0][0][1][0][RTW89_THAILAND][0][104] = 127, + [0][0][1][0][RTW89_FCC][1][105] = 22, + [0][0][1][0][RTW89_ETSI][1][105] = 127, + [0][0][1][0][RTW89_ETSI][0][105] = 127, + [0][0][1][0][RTW89_MKK][1][105] = 127, + [0][0][1][0][RTW89_MKK][0][105] = 127, + [0][0][1][0][RTW89_IC][1][105] = 22, + [0][0][1][0][RTW89_KCC][1][105] = 32, + [0][0][1][0][RTW89_KCC][0][105] = 127, + [0][0][1][0][RTW89_ACMA][1][105] = 127, + [0][0][1][0][RTW89_ACMA][0][105] = 127, + [0][0][1][0][RTW89_CHILE][1][105] = 22, + [0][0][1][0][RTW89_QATAR][1][105] = 127, + [0][0][1][0][RTW89_QATAR][0][105] = 127, + [0][0][1][0][RTW89_UK][1][105] = 127, + [0][0][1][0][RTW89_UK][0][105] = 127, + [0][0][1][0][RTW89_THAILAND][1][105] = 127, + [0][0][1][0][RTW89_THAILAND][0][105] = 127, + [0][0][1][0][RTW89_FCC][1][107] = 24, + [0][0][1][0][RTW89_ETSI][1][107] = 127, + [0][0][1][0][RTW89_ETSI][0][107] = 127, + [0][0][1][0][RTW89_MKK][1][107] = 127, + [0][0][1][0][RTW89_MKK][0][107] = 127, + [0][0][1][0][RTW89_IC][1][107] = 24, + [0][0][1][0][RTW89_KCC][1][107] = 32, + [0][0][1][0][RTW89_KCC][0][107] = 127, + [0][0][1][0][RTW89_ACMA][1][107] = 127, + [0][0][1][0][RTW89_ACMA][0][107] = 127, + [0][0][1][0][RTW89_CHILE][1][107] = 24, + [0][0][1][0][RTW89_QATAR][1][107] = 127, + [0][0][1][0][RTW89_QATAR][0][107] = 127, + [0][0][1][0][RTW89_UK][1][107] = 127, + [0][0][1][0][RTW89_UK][0][107] = 127, + [0][0][1][0][RTW89_THAILAND][1][107] = 127, + [0][0][1][0][RTW89_THAILAND][0][107] = 127, + [0][0][1][0][RTW89_FCC][1][109] = 24, + [0][0][1][0][RTW89_ETSI][1][109] = 127, + [0][0][1][0][RTW89_ETSI][0][109] = 127, + [0][0][1][0][RTW89_MKK][1][109] = 127, + [0][0][1][0][RTW89_MKK][0][109] = 127, + [0][0][1][0][RTW89_IC][1][109] = 24, + [0][0][1][0][RTW89_KCC][1][109] = 32, + [0][0][1][0][RTW89_KCC][0][109] = 127, + [0][0][1][0][RTW89_ACMA][1][109] = 127, + [0][0][1][0][RTW89_ACMA][0][109] = 127, + [0][0][1][0][RTW89_CHILE][1][109] = 24, + [0][0][1][0][RTW89_QATAR][1][109] = 127, + [0][0][1][0][RTW89_QATAR][0][109] = 127, + [0][0][1][0][RTW89_UK][1][109] = 127, + [0][0][1][0][RTW89_UK][0][109] = 127, + [0][0][1][0][RTW89_THAILAND][1][109] = 127, + [0][0][1][0][RTW89_THAILAND][0][109] = 127, + [0][0][1][0][RTW89_FCC][1][111] = 127, + [0][0][1][0][RTW89_ETSI][1][111] = 127, + [0][0][1][0][RTW89_ETSI][0][111] = 127, + [0][0][1][0][RTW89_MKK][1][111] = 127, + [0][0][1][0][RTW89_MKK][0][111] = 127, + [0][0][1][0][RTW89_IC][1][111] = 127, + [0][0][1][0][RTW89_KCC][1][111] = 127, + [0][0][1][0][RTW89_KCC][0][111] = 127, + [0][0][1][0][RTW89_ACMA][1][111] = 127, + [0][0][1][0][RTW89_ACMA][0][111] = 127, + [0][0][1][0][RTW89_CHILE][1][111] = 127, + [0][0][1][0][RTW89_QATAR][1][111] = 127, + [0][0][1][0][RTW89_QATAR][0][111] = 127, + [0][0][1][0][RTW89_UK][1][111] = 127, + [0][0][1][0][RTW89_UK][0][111] = 127, + [0][0][1][0][RTW89_THAILAND][1][111] = 127, + [0][0][1][0][RTW89_THAILAND][0][111] = 127, + [0][0][1][0][RTW89_FCC][1][113] = 127, + [0][0][1][0][RTW89_ETSI][1][113] = 127, + [0][0][1][0][RTW89_ETSI][0][113] = 127, + [0][0][1][0][RTW89_MKK][1][113] = 127, + [0][0][1][0][RTW89_MKK][0][113] = 127, + [0][0][1][0][RTW89_IC][1][113] = 127, + [0][0][1][0][RTW89_KCC][1][113] = 127, + [0][0][1][0][RTW89_KCC][0][113] = 127, + [0][0][1][0][RTW89_ACMA][1][113] = 127, + [0][0][1][0][RTW89_ACMA][0][113] = 127, + [0][0][1][0][RTW89_CHILE][1][113] = 127, + [0][0][1][0][RTW89_QATAR][1][113] = 127, + [0][0][1][0][RTW89_QATAR][0][113] = 127, + [0][0][1][0][RTW89_UK][1][113] = 127, + [0][0][1][0][RTW89_UK][0][113] = 127, + [0][0][1][0][RTW89_THAILAND][1][113] = 127, + [0][0][1][0][RTW89_THAILAND][0][113] = 127, + [0][0][1][0][RTW89_FCC][1][115] = 127, + [0][0][1][0][RTW89_ETSI][1][115] = 127, + [0][0][1][0][RTW89_ETSI][0][115] = 127, + [0][0][1][0][RTW89_MKK][1][115] = 127, + [0][0][1][0][RTW89_MKK][0][115] = 127, + [0][0][1][0][RTW89_IC][1][115] = 127, + [0][0][1][0][RTW89_KCC][1][115] = 127, + [0][0][1][0][RTW89_KCC][0][115] = 127, + [0][0][1][0][RTW89_ACMA][1][115] = 127, + [0][0][1][0][RTW89_ACMA][0][115] = 127, + [0][0][1][0][RTW89_CHILE][1][115] = 127, + [0][0][1][0][RTW89_QATAR][1][115] = 127, + [0][0][1][0][RTW89_QATAR][0][115] = 127, + [0][0][1][0][RTW89_UK][1][115] = 127, + [0][0][1][0][RTW89_UK][0][115] = 127, + [0][0][1][0][RTW89_THAILAND][1][115] = 127, + [0][0][1][0][RTW89_THAILAND][0][115] = 127, + [0][0][1][0][RTW89_FCC][1][117] = 127, + [0][0][1][0][RTW89_ETSI][1][117] = 127, + [0][0][1][0][RTW89_ETSI][0][117] = 127, + [0][0][1][0][RTW89_MKK][1][117] = 127, + [0][0][1][0][RTW89_MKK][0][117] = 127, + [0][0][1][0][RTW89_IC][1][117] = 127, + [0][0][1][0][RTW89_KCC][1][117] = 127, + [0][0][1][0][RTW89_KCC][0][117] = 127, + [0][0][1][0][RTW89_ACMA][1][117] = 127, + [0][0][1][0][RTW89_ACMA][0][117] = 127, + [0][0][1][0][RTW89_CHILE][1][117] = 127, + [0][0][1][0][RTW89_QATAR][1][117] = 127, + [0][0][1][0][RTW89_QATAR][0][117] = 127, + [0][0][1][0][RTW89_UK][1][117] = 127, + [0][0][1][0][RTW89_UK][0][117] = 127, + [0][0][1][0][RTW89_THAILAND][1][117] = 127, + [0][0][1][0][RTW89_THAILAND][0][117] = 127, + [0][0][1][0][RTW89_FCC][1][119] = 127, + [0][0][1][0][RTW89_ETSI][1][119] = 127, + [0][0][1][0][RTW89_ETSI][0][119] = 127, + [0][0][1][0][RTW89_MKK][1][119] = 127, + [0][0][1][0][RTW89_MKK][0][119] = 127, + [0][0][1][0][RTW89_IC][1][119] = 127, + [0][0][1][0][RTW89_KCC][1][119] = 127, + [0][0][1][0][RTW89_KCC][0][119] = 127, + [0][0][1][0][RTW89_ACMA][1][119] = 127, + [0][0][1][0][RTW89_ACMA][0][119] = 127, + [0][0][1][0][RTW89_CHILE][1][119] = 127, + [0][0][1][0][RTW89_QATAR][1][119] = 127, + [0][0][1][0][RTW89_QATAR][0][119] = 127, + [0][0][1][0][RTW89_UK][1][119] = 127, + [0][0][1][0][RTW89_UK][0][119] = 127, + [0][0][1][0][RTW89_THAILAND][1][119] = 127, + [0][0][1][0][RTW89_THAILAND][0][119] = 127, + [0][1][1][0][RTW89_FCC][1][0] = -2, + [0][1][1][0][RTW89_ETSI][1][0] = 54, + [0][1][1][0][RTW89_ETSI][0][0] = 18, + [0][1][1][0][RTW89_MKK][1][0] = 56, + [0][1][1][0][RTW89_MKK][0][0] = 16, + [0][1][1][0][RTW89_IC][1][0] = -2, + [0][1][1][0][RTW89_KCC][1][0] = 12, + [0][1][1][0][RTW89_KCC][0][0] = 10, + [0][1][1][0][RTW89_ACMA][1][0] = 54, + [0][1][1][0][RTW89_ACMA][0][0] = 18, + [0][1][1][0][RTW89_CHILE][1][0] = -2, + [0][1][1][0][RTW89_QATAR][1][0] = 54, + [0][1][1][0][RTW89_QATAR][0][0] = 18, + [0][1][1][0][RTW89_UK][1][0] = 54, + [0][1][1][0][RTW89_UK][0][0] = 18, + [0][1][1][0][RTW89_THAILAND][1][0] = 44, + [0][1][1][0][RTW89_THAILAND][0][0] = -2, + [0][1][1][0][RTW89_FCC][1][2] = -4, + [0][1][1][0][RTW89_ETSI][1][2] = 54, + [0][1][1][0][RTW89_ETSI][0][2] = 18, + [0][1][1][0][RTW89_MKK][1][2] = 54, + [0][1][1][0][RTW89_MKK][0][2] = 16, + [0][1][1][0][RTW89_IC][1][2] = -4, + [0][1][1][0][RTW89_KCC][1][2] = 12, + [0][1][1][0][RTW89_KCC][0][2] = 12, + [0][1][1][0][RTW89_ACMA][1][2] = 54, + [0][1][1][0][RTW89_ACMA][0][2] = 18, + [0][1][1][0][RTW89_CHILE][1][2] = -4, + [0][1][1][0][RTW89_QATAR][1][2] = 54, + [0][1][1][0][RTW89_QATAR][0][2] = 18, + [0][1][1][0][RTW89_UK][1][2] = 54, + [0][1][1][0][RTW89_UK][0][2] = 18, + [0][1][1][0][RTW89_THAILAND][1][2] = 44, + [0][1][1][0][RTW89_THAILAND][0][2] = -4, + [0][1][1][0][RTW89_FCC][1][4] = -4, + [0][1][1][0][RTW89_ETSI][1][4] = 54, + [0][1][1][0][RTW89_ETSI][0][4] = 18, + [0][1][1][0][RTW89_MKK][1][4] = 54, + [0][1][1][0][RTW89_MKK][0][4] = 16, + [0][1][1][0][RTW89_IC][1][4] = -4, + [0][1][1][0][RTW89_KCC][1][4] = 12, + [0][1][1][0][RTW89_KCC][0][4] = 12, + [0][1][1][0][RTW89_ACMA][1][4] = 54, + [0][1][1][0][RTW89_ACMA][0][4] = 18, + [0][1][1][0][RTW89_CHILE][1][4] = -4, + [0][1][1][0][RTW89_QATAR][1][4] = 54, + [0][1][1][0][RTW89_QATAR][0][4] = 18, + [0][1][1][0][RTW89_UK][1][4] = 54, + [0][1][1][0][RTW89_UK][0][4] = 18, + [0][1][1][0][RTW89_THAILAND][1][4] = 44, + [0][1][1][0][RTW89_THAILAND][0][4] = -4, + [0][1][1][0][RTW89_FCC][1][6] = -4, + [0][1][1][0][RTW89_ETSI][1][6] = 54, + [0][1][1][0][RTW89_ETSI][0][6] = 18, + [0][1][1][0][RTW89_MKK][1][6] = 54, + [0][1][1][0][RTW89_MKK][0][6] = 16, + [0][1][1][0][RTW89_IC][1][6] = -4, + [0][1][1][0][RTW89_KCC][1][6] = 12, + [0][1][1][0][RTW89_KCC][0][6] = 12, + [0][1][1][0][RTW89_ACMA][1][6] = 54, + [0][1][1][0][RTW89_ACMA][0][6] = 18, + [0][1][1][0][RTW89_CHILE][1][6] = -4, + [0][1][1][0][RTW89_QATAR][1][6] = 54, + [0][1][1][0][RTW89_QATAR][0][6] = 18, + [0][1][1][0][RTW89_UK][1][6] = 54, + [0][1][1][0][RTW89_UK][0][6] = 18, + [0][1][1][0][RTW89_THAILAND][1][6] = 44, + [0][1][1][0][RTW89_THAILAND][0][6] = -4, + [0][1][1][0][RTW89_FCC][1][8] = -4, + [0][1][1][0][RTW89_ETSI][1][8] = 54, + [0][1][1][0][RTW89_ETSI][0][8] = 18, + [0][1][1][0][RTW89_MKK][1][8] = 54, + [0][1][1][0][RTW89_MKK][0][8] = 16, + [0][1][1][0][RTW89_IC][1][8] = -4, + [0][1][1][0][RTW89_KCC][1][8] = 12, + [0][1][1][0][RTW89_KCC][0][8] = 12, + [0][1][1][0][RTW89_ACMA][1][8] = 54, + [0][1][1][0][RTW89_ACMA][0][8] = 18, + [0][1][1][0][RTW89_CHILE][1][8] = -4, + [0][1][1][0][RTW89_QATAR][1][8] = 54, + [0][1][1][0][RTW89_QATAR][0][8] = 18, + [0][1][1][0][RTW89_UK][1][8] = 54, + [0][1][1][0][RTW89_UK][0][8] = 18, + [0][1][1][0][RTW89_THAILAND][1][8] = 44, + [0][1][1][0][RTW89_THAILAND][0][8] = -4, + [0][1][1][0][RTW89_FCC][1][10] = -4, + [0][1][1][0][RTW89_ETSI][1][10] = 54, + [0][1][1][0][RTW89_ETSI][0][10] = 18, + [0][1][1][0][RTW89_MKK][1][10] = 54, + [0][1][1][0][RTW89_MKK][0][10] = 16, + [0][1][1][0][RTW89_IC][1][10] = -4, + [0][1][1][0][RTW89_KCC][1][10] = 12, + [0][1][1][0][RTW89_KCC][0][10] = 12, + [0][1][1][0][RTW89_ACMA][1][10] = 54, + [0][1][1][0][RTW89_ACMA][0][10] = 18, + [0][1][1][0][RTW89_CHILE][1][10] = -4, + [0][1][1][0][RTW89_QATAR][1][10] = 54, + [0][1][1][0][RTW89_QATAR][0][10] = 18, + [0][1][1][0][RTW89_UK][1][10] = 54, + [0][1][1][0][RTW89_UK][0][10] = 18, + [0][1][1][0][RTW89_THAILAND][1][10] = 44, + [0][1][1][0][RTW89_THAILAND][0][10] = -4, + [0][1][1][0][RTW89_FCC][1][12] = -4, + [0][1][1][0][RTW89_ETSI][1][12] = 54, + [0][1][1][0][RTW89_ETSI][0][12] = 18, + [0][1][1][0][RTW89_MKK][1][12] = 54, + [0][1][1][0][RTW89_MKK][0][12] = 16, + [0][1][1][0][RTW89_IC][1][12] = -4, + [0][1][1][0][RTW89_KCC][1][12] = 12, + [0][1][1][0][RTW89_KCC][0][12] = 12, + [0][1][1][0][RTW89_ACMA][1][12] = 54, + [0][1][1][0][RTW89_ACMA][0][12] = 18, + [0][1][1][0][RTW89_CHILE][1][12] = -4, + [0][1][1][0][RTW89_QATAR][1][12] = 54, + [0][1][1][0][RTW89_QATAR][0][12] = 18, + [0][1][1][0][RTW89_UK][1][12] = 54, + [0][1][1][0][RTW89_UK][0][12] = 18, + [0][1][1][0][RTW89_THAILAND][1][12] = 44, + [0][1][1][0][RTW89_THAILAND][0][12] = -4, + [0][1][1][0][RTW89_FCC][1][14] = -4, + [0][1][1][0][RTW89_ETSI][1][14] = 54, + [0][1][1][0][RTW89_ETSI][0][14] = 18, + [0][1][1][0][RTW89_MKK][1][14] = 54, + [0][1][1][0][RTW89_MKK][0][14] = 16, + [0][1][1][0][RTW89_IC][1][14] = -4, + [0][1][1][0][RTW89_KCC][1][14] = 12, + [0][1][1][0][RTW89_KCC][0][14] = 12, + [0][1][1][0][RTW89_ACMA][1][14] = 54, + [0][1][1][0][RTW89_ACMA][0][14] = 18, + [0][1][1][0][RTW89_CHILE][1][14] = -4, + [0][1][1][0][RTW89_QATAR][1][14] = 54, + [0][1][1][0][RTW89_QATAR][0][14] = 18, + [0][1][1][0][RTW89_UK][1][14] = 54, + [0][1][1][0][RTW89_UK][0][14] = 18, + [0][1][1][0][RTW89_THAILAND][1][14] = 44, + [0][1][1][0][RTW89_THAILAND][0][14] = -4, + [0][1][1][0][RTW89_FCC][1][15] = -4, + [0][1][1][0][RTW89_ETSI][1][15] = 54, + [0][1][1][0][RTW89_ETSI][0][15] = 18, + [0][1][1][0][RTW89_MKK][1][15] = 54, + [0][1][1][0][RTW89_MKK][0][15] = 16, + [0][1][1][0][RTW89_IC][1][15] = -4, + [0][1][1][0][RTW89_KCC][1][15] = 12, + [0][1][1][0][RTW89_KCC][0][15] = 12, + [0][1][1][0][RTW89_ACMA][1][15] = 54, + [0][1][1][0][RTW89_ACMA][0][15] = 18, + [0][1][1][0][RTW89_CHILE][1][15] = -4, + [0][1][1][0][RTW89_QATAR][1][15] = 54, + [0][1][1][0][RTW89_QATAR][0][15] = 18, + [0][1][1][0][RTW89_UK][1][15] = 54, + [0][1][1][0][RTW89_UK][0][15] = 18, + [0][1][1][0][RTW89_THAILAND][1][15] = 44, + [0][1][1][0][RTW89_THAILAND][0][15] = -4, + [0][1][1][0][RTW89_FCC][1][17] = -4, + [0][1][1][0][RTW89_ETSI][1][17] = 54, + [0][1][1][0][RTW89_ETSI][0][17] = 18, + [0][1][1][0][RTW89_MKK][1][17] = 54, + [0][1][1][0][RTW89_MKK][0][17] = 16, + [0][1][1][0][RTW89_IC][1][17] = -4, + [0][1][1][0][RTW89_KCC][1][17] = 12, + [0][1][1][0][RTW89_KCC][0][17] = 12, + [0][1][1][0][RTW89_ACMA][1][17] = 54, + [0][1][1][0][RTW89_ACMA][0][17] = 18, + [0][1][1][0][RTW89_CHILE][1][17] = -4, + [0][1][1][0][RTW89_QATAR][1][17] = 54, + [0][1][1][0][RTW89_QATAR][0][17] = 18, + [0][1][1][0][RTW89_UK][1][17] = 54, + [0][1][1][0][RTW89_UK][0][17] = 18, + [0][1][1][0][RTW89_THAILAND][1][17] = 44, + [0][1][1][0][RTW89_THAILAND][0][17] = -4, + [0][1][1][0][RTW89_FCC][1][19] = -4, + [0][1][1][0][RTW89_ETSI][1][19] = 54, + [0][1][1][0][RTW89_ETSI][0][19] = 18, + [0][1][1][0][RTW89_MKK][1][19] = 54, + [0][1][1][0][RTW89_MKK][0][19] = 16, + [0][1][1][0][RTW89_IC][1][19] = -4, + [0][1][1][0][RTW89_KCC][1][19] = 12, + [0][1][1][0][RTW89_KCC][0][19] = 12, + [0][1][1][0][RTW89_ACMA][1][19] = 54, + [0][1][1][0][RTW89_ACMA][0][19] = 18, + [0][1][1][0][RTW89_CHILE][1][19] = -4, + [0][1][1][0][RTW89_QATAR][1][19] = 54, + [0][1][1][0][RTW89_QATAR][0][19] = 18, + [0][1][1][0][RTW89_UK][1][19] = 54, + [0][1][1][0][RTW89_UK][0][19] = 18, + [0][1][1][0][RTW89_THAILAND][1][19] = 44, + [0][1][1][0][RTW89_THAILAND][0][19] = -4, + [0][1][1][0][RTW89_FCC][1][21] = -4, + [0][1][1][0][RTW89_ETSI][1][21] = 54, + [0][1][1][0][RTW89_ETSI][0][21] = 18, + [0][1][1][0][RTW89_MKK][1][21] = 54, + [0][1][1][0][RTW89_MKK][0][21] = 16, + [0][1][1][0][RTW89_IC][1][21] = -4, + [0][1][1][0][RTW89_KCC][1][21] = 12, + [0][1][1][0][RTW89_KCC][0][21] = 12, + [0][1][1][0][RTW89_ACMA][1][21] = 54, + [0][1][1][0][RTW89_ACMA][0][21] = 18, + [0][1][1][0][RTW89_CHILE][1][21] = -4, + [0][1][1][0][RTW89_QATAR][1][21] = 54, + [0][1][1][0][RTW89_QATAR][0][21] = 18, + [0][1][1][0][RTW89_UK][1][21] = 54, + [0][1][1][0][RTW89_UK][0][21] = 18, + [0][1][1][0][RTW89_THAILAND][1][21] = 44, + [0][1][1][0][RTW89_THAILAND][0][21] = -4, + [0][1][1][0][RTW89_FCC][1][23] = -4, + [0][1][1][0][RTW89_ETSI][1][23] = 54, + [0][1][1][0][RTW89_ETSI][0][23] = 18, + [0][1][1][0][RTW89_MKK][1][23] = 54, + [0][1][1][0][RTW89_MKK][0][23] = 16, + [0][1][1][0][RTW89_IC][1][23] = -4, + [0][1][1][0][RTW89_KCC][1][23] = 12, + [0][1][1][0][RTW89_KCC][0][23] = 10, + [0][1][1][0][RTW89_ACMA][1][23] = 54, + [0][1][1][0][RTW89_ACMA][0][23] = 18, + [0][1][1][0][RTW89_CHILE][1][23] = -4, + [0][1][1][0][RTW89_QATAR][1][23] = 54, + [0][1][1][0][RTW89_QATAR][0][23] = 18, + [0][1][1][0][RTW89_UK][1][23] = 54, + [0][1][1][0][RTW89_UK][0][23] = 18, + [0][1][1][0][RTW89_THAILAND][1][23] = 44, + [0][1][1][0][RTW89_THAILAND][0][23] = -4, + [0][1][1][0][RTW89_FCC][1][25] = -4, + [0][1][1][0][RTW89_ETSI][1][25] = 54, + [0][1][1][0][RTW89_ETSI][0][25] = 18, + [0][1][1][0][RTW89_MKK][1][25] = 54, + [0][1][1][0][RTW89_MKK][0][25] = 16, + [0][1][1][0][RTW89_IC][1][25] = -4, + [0][1][1][0][RTW89_KCC][1][25] = 12, + [0][1][1][0][RTW89_KCC][0][25] = 14, + [0][1][1][0][RTW89_ACMA][1][25] = 54, + [0][1][1][0][RTW89_ACMA][0][25] = 18, + [0][1][1][0][RTW89_CHILE][1][25] = -4, + [0][1][1][0][RTW89_QATAR][1][25] = 54, + [0][1][1][0][RTW89_QATAR][0][25] = 18, + [0][1][1][0][RTW89_UK][1][25] = 54, + [0][1][1][0][RTW89_UK][0][25] = 18, + [0][1][1][0][RTW89_THAILAND][1][25] = 42, + [0][1][1][0][RTW89_THAILAND][0][25] = -4, + [0][1][1][0][RTW89_FCC][1][27] = -4, + [0][1][1][0][RTW89_ETSI][1][27] = 54, + [0][1][1][0][RTW89_ETSI][0][27] = 18, + [0][1][1][0][RTW89_MKK][1][27] = 54, + [0][1][1][0][RTW89_MKK][0][27] = 16, + [0][1][1][0][RTW89_IC][1][27] = -4, + [0][1][1][0][RTW89_KCC][1][27] = 12, + [0][1][1][0][RTW89_KCC][0][27] = 14, + [0][1][1][0][RTW89_ACMA][1][27] = 54, + [0][1][1][0][RTW89_ACMA][0][27] = 18, + [0][1][1][0][RTW89_CHILE][1][27] = -4, + [0][1][1][0][RTW89_QATAR][1][27] = 54, + [0][1][1][0][RTW89_QATAR][0][27] = 18, + [0][1][1][0][RTW89_UK][1][27] = 54, + [0][1][1][0][RTW89_UK][0][27] = 18, + [0][1][1][0][RTW89_THAILAND][1][27] = 42, + [0][1][1][0][RTW89_THAILAND][0][27] = -4, + [0][1][1][0][RTW89_FCC][1][29] = -4, + [0][1][1][0][RTW89_ETSI][1][29] = 54, + [0][1][1][0][RTW89_ETSI][0][29] = 18, + [0][1][1][0][RTW89_MKK][1][29] = 54, + [0][1][1][0][RTW89_MKK][0][29] = 16, + [0][1][1][0][RTW89_IC][1][29] = -4, + [0][1][1][0][RTW89_KCC][1][29] = 12, + [0][1][1][0][RTW89_KCC][0][29] = 14, + [0][1][1][0][RTW89_ACMA][1][29] = 54, + [0][1][1][0][RTW89_ACMA][0][29] = 18, + [0][1][1][0][RTW89_CHILE][1][29] = -4, + [0][1][1][0][RTW89_QATAR][1][29] = 54, + [0][1][1][0][RTW89_QATAR][0][29] = 18, + [0][1][1][0][RTW89_UK][1][29] = 54, + [0][1][1][0][RTW89_UK][0][29] = 18, + [0][1][1][0][RTW89_THAILAND][1][29] = 42, + [0][1][1][0][RTW89_THAILAND][0][29] = -4, + [0][1][1][0][RTW89_FCC][1][30] = -4, + [0][1][1][0][RTW89_ETSI][1][30] = 54, + [0][1][1][0][RTW89_ETSI][0][30] = 18, + [0][1][1][0][RTW89_MKK][1][30] = 54, + [0][1][1][0][RTW89_MKK][0][30] = 16, + [0][1][1][0][RTW89_IC][1][30] = -4, + [0][1][1][0][RTW89_KCC][1][30] = 12, + [0][1][1][0][RTW89_KCC][0][30] = 14, + [0][1][1][0][RTW89_ACMA][1][30] = 54, + [0][1][1][0][RTW89_ACMA][0][30] = 18, + [0][1][1][0][RTW89_CHILE][1][30] = -4, + [0][1][1][0][RTW89_QATAR][1][30] = 54, + [0][1][1][0][RTW89_QATAR][0][30] = 18, + [0][1][1][0][RTW89_UK][1][30] = 54, + [0][1][1][0][RTW89_UK][0][30] = 18, + [0][1][1][0][RTW89_THAILAND][1][30] = 42, + [0][1][1][0][RTW89_THAILAND][0][30] = -4, + [0][1][1][0][RTW89_FCC][1][32] = -4, + [0][1][1][0][RTW89_ETSI][1][32] = 54, + [0][1][1][0][RTW89_ETSI][0][32] = 18, + [0][1][1][0][RTW89_MKK][1][32] = 54, + [0][1][1][0][RTW89_MKK][0][32] = 16, + [0][1][1][0][RTW89_IC][1][32] = -4, + [0][1][1][0][RTW89_KCC][1][32] = 12, + [0][1][1][0][RTW89_KCC][0][32] = 14, + [0][1][1][0][RTW89_ACMA][1][32] = 54, + [0][1][1][0][RTW89_ACMA][0][32] = 18, + [0][1][1][0][RTW89_CHILE][1][32] = -4, + [0][1][1][0][RTW89_QATAR][1][32] = 54, + [0][1][1][0][RTW89_QATAR][0][32] = 18, + [0][1][1][0][RTW89_UK][1][32] = 54, + [0][1][1][0][RTW89_UK][0][32] = 18, + [0][1][1][0][RTW89_THAILAND][1][32] = 42, + [0][1][1][0][RTW89_THAILAND][0][32] = -4, + [0][1][1][0][RTW89_FCC][1][34] = -4, + [0][1][1][0][RTW89_ETSI][1][34] = 54, + [0][1][1][0][RTW89_ETSI][0][34] = 18, + [0][1][1][0][RTW89_MKK][1][34] = 54, + [0][1][1][0][RTW89_MKK][0][34] = 16, + [0][1][1][0][RTW89_IC][1][34] = -4, + [0][1][1][0][RTW89_KCC][1][34] = 12, + [0][1][1][0][RTW89_KCC][0][34] = 14, + [0][1][1][0][RTW89_ACMA][1][34] = 54, + [0][1][1][0][RTW89_ACMA][0][34] = 18, + [0][1][1][0][RTW89_CHILE][1][34] = -4, + [0][1][1][0][RTW89_QATAR][1][34] = 54, + [0][1][1][0][RTW89_QATAR][0][34] = 18, + [0][1][1][0][RTW89_UK][1][34] = 54, + [0][1][1][0][RTW89_UK][0][34] = 18, + [0][1][1][0][RTW89_THAILAND][1][34] = 42, + [0][1][1][0][RTW89_THAILAND][0][34] = -4, + [0][1][1][0][RTW89_FCC][1][36] = -4, + [0][1][1][0][RTW89_ETSI][1][36] = 54, + [0][1][1][0][RTW89_ETSI][0][36] = 18, + [0][1][1][0][RTW89_MKK][1][36] = 54, + [0][1][1][0][RTW89_MKK][0][36] = 16, + [0][1][1][0][RTW89_IC][1][36] = -4, + [0][1][1][0][RTW89_KCC][1][36] = 12, + [0][1][1][0][RTW89_KCC][0][36] = 14, + [0][1][1][0][RTW89_ACMA][1][36] = 54, + [0][1][1][0][RTW89_ACMA][0][36] = 18, + [0][1][1][0][RTW89_CHILE][1][36] = -4, + [0][1][1][0][RTW89_QATAR][1][36] = 54, + [0][1][1][0][RTW89_QATAR][0][36] = 18, + [0][1][1][0][RTW89_UK][1][36] = 54, + [0][1][1][0][RTW89_UK][0][36] = 18, + [0][1][1][0][RTW89_THAILAND][1][36] = 42, + [0][1][1][0][RTW89_THAILAND][0][36] = -4, + [0][1][1][0][RTW89_FCC][1][38] = -4, + [0][1][1][0][RTW89_ETSI][1][38] = 54, + [0][1][1][0][RTW89_ETSI][0][38] = 18, + [0][1][1][0][RTW89_MKK][1][38] = 54, + [0][1][1][0][RTW89_MKK][0][38] = 16, + [0][1][1][0][RTW89_IC][1][38] = -4, + [0][1][1][0][RTW89_KCC][1][38] = 12, + [0][1][1][0][RTW89_KCC][0][38] = 14, + [0][1][1][0][RTW89_ACMA][1][38] = 54, + [0][1][1][0][RTW89_ACMA][0][38] = 18, + [0][1][1][0][RTW89_CHILE][1][38] = -4, + [0][1][1][0][RTW89_QATAR][1][38] = 54, + [0][1][1][0][RTW89_QATAR][0][38] = 18, + [0][1][1][0][RTW89_UK][1][38] = 54, + [0][1][1][0][RTW89_UK][0][38] = 18, + [0][1][1][0][RTW89_THAILAND][1][38] = 42, + [0][1][1][0][RTW89_THAILAND][0][38] = -4, + [0][1][1][0][RTW89_FCC][1][40] = -4, + [0][1][1][0][RTW89_ETSI][1][40] = 54, + [0][1][1][0][RTW89_ETSI][0][40] = 18, + [0][1][1][0][RTW89_MKK][1][40] = 54, + [0][1][1][0][RTW89_MKK][0][40] = 16, + [0][1][1][0][RTW89_IC][1][40] = -4, + [0][1][1][0][RTW89_KCC][1][40] = 12, + [0][1][1][0][RTW89_KCC][0][40] = 14, + [0][1][1][0][RTW89_ACMA][1][40] = 54, + [0][1][1][0][RTW89_ACMA][0][40] = 18, + [0][1][1][0][RTW89_CHILE][1][40] = -4, + [0][1][1][0][RTW89_QATAR][1][40] = 54, + [0][1][1][0][RTW89_QATAR][0][40] = 18, + [0][1][1][0][RTW89_UK][1][40] = 54, + [0][1][1][0][RTW89_UK][0][40] = 18, + [0][1][1][0][RTW89_THAILAND][1][40] = 42, + [0][1][1][0][RTW89_THAILAND][0][40] = -4, + [0][1][1][0][RTW89_FCC][1][42] = -4, + [0][1][1][0][RTW89_ETSI][1][42] = 54, + [0][1][1][0][RTW89_ETSI][0][42] = 18, + [0][1][1][0][RTW89_MKK][1][42] = 54, + [0][1][1][0][RTW89_MKK][0][42] = 16, + [0][1][1][0][RTW89_IC][1][42] = -4, + [0][1][1][0][RTW89_KCC][1][42] = 12, + [0][1][1][0][RTW89_KCC][0][42] = 14, + [0][1][1][0][RTW89_ACMA][1][42] = 54, + [0][1][1][0][RTW89_ACMA][0][42] = 18, + [0][1][1][0][RTW89_CHILE][1][42] = -4, + [0][1][1][0][RTW89_QATAR][1][42] = 54, + [0][1][1][0][RTW89_QATAR][0][42] = 18, + [0][1][1][0][RTW89_UK][1][42] = 54, + [0][1][1][0][RTW89_UK][0][42] = 18, + [0][1][1][0][RTW89_THAILAND][1][42] = 42, + [0][1][1][0][RTW89_THAILAND][0][42] = -4, + [0][1][1][0][RTW89_FCC][1][44] = -2, + [0][1][1][0][RTW89_ETSI][1][44] = 54, + [0][1][1][0][RTW89_ETSI][0][44] = 18, + [0][1][1][0][RTW89_MKK][1][44] = 34, + [0][1][1][0][RTW89_MKK][0][44] = 16, + [0][1][1][0][RTW89_IC][1][44] = -2, + [0][1][1][0][RTW89_KCC][1][44] = 12, + [0][1][1][0][RTW89_KCC][0][44] = 12, + [0][1][1][0][RTW89_ACMA][1][44] = 54, + [0][1][1][0][RTW89_ACMA][0][44] = 18, + [0][1][1][0][RTW89_CHILE][1][44] = -2, + [0][1][1][0][RTW89_QATAR][1][44] = 54, + [0][1][1][0][RTW89_QATAR][0][44] = 18, + [0][1][1][0][RTW89_UK][1][44] = 54, + [0][1][1][0][RTW89_UK][0][44] = 18, + [0][1][1][0][RTW89_THAILAND][1][44] = 42, + [0][1][1][0][RTW89_THAILAND][0][44] = -2, + [0][1][1][0][RTW89_FCC][1][45] = -2, + [0][1][1][0][RTW89_ETSI][1][45] = 127, + [0][1][1][0][RTW89_ETSI][0][45] = 127, + [0][1][1][0][RTW89_MKK][1][45] = 127, + [0][1][1][0][RTW89_MKK][0][45] = 127, + [0][1][1][0][RTW89_IC][1][45] = -2, + [0][1][1][0][RTW89_KCC][1][45] = 12, + [0][1][1][0][RTW89_KCC][0][45] = 127, + [0][1][1][0][RTW89_ACMA][1][45] = 127, + [0][1][1][0][RTW89_ACMA][0][45] = 127, + [0][1][1][0][RTW89_CHILE][1][45] = -2, + [0][1][1][0][RTW89_QATAR][1][45] = 127, + [0][1][1][0][RTW89_QATAR][0][45] = 127, + [0][1][1][0][RTW89_UK][1][45] = 127, + [0][1][1][0][RTW89_UK][0][45] = 127, + [0][1][1][0][RTW89_THAILAND][1][45] = 127, + [0][1][1][0][RTW89_THAILAND][0][45] = 127, + [0][1][1][0][RTW89_FCC][1][47] = -2, + [0][1][1][0][RTW89_ETSI][1][47] = 127, + [0][1][1][0][RTW89_ETSI][0][47] = 127, + [0][1][1][0][RTW89_MKK][1][47] = 127, + [0][1][1][0][RTW89_MKK][0][47] = 127, + [0][1][1][0][RTW89_IC][1][47] = -2, + [0][1][1][0][RTW89_KCC][1][47] = 12, + [0][1][1][0][RTW89_KCC][0][47] = 127, + [0][1][1][0][RTW89_ACMA][1][47] = 127, + [0][1][1][0][RTW89_ACMA][0][47] = 127, + [0][1][1][0][RTW89_CHILE][1][47] = -2, + [0][1][1][0][RTW89_QATAR][1][47] = 127, + [0][1][1][0][RTW89_QATAR][0][47] = 127, + [0][1][1][0][RTW89_UK][1][47] = 127, + [0][1][1][0][RTW89_UK][0][47] = 127, + [0][1][1][0][RTW89_THAILAND][1][47] = 127, + [0][1][1][0][RTW89_THAILAND][0][47] = 127, + [0][1][1][0][RTW89_FCC][1][49] = -2, + [0][1][1][0][RTW89_ETSI][1][49] = 127, + [0][1][1][0][RTW89_ETSI][0][49] = 127, + [0][1][1][0][RTW89_MKK][1][49] = 127, + [0][1][1][0][RTW89_MKK][0][49] = 127, + [0][1][1][0][RTW89_IC][1][49] = -2, + [0][1][1][0][RTW89_KCC][1][49] = 12, + [0][1][1][0][RTW89_KCC][0][49] = 127, + [0][1][1][0][RTW89_ACMA][1][49] = 127, + [0][1][1][0][RTW89_ACMA][0][49] = 127, + [0][1][1][0][RTW89_CHILE][1][49] = -2, + [0][1][1][0][RTW89_QATAR][1][49] = 127, + [0][1][1][0][RTW89_QATAR][0][49] = 127, + [0][1][1][0][RTW89_UK][1][49] = 127, + [0][1][1][0][RTW89_UK][0][49] = 127, + [0][1][1][0][RTW89_THAILAND][1][49] = 127, + [0][1][1][0][RTW89_THAILAND][0][49] = 127, + [0][1][1][0][RTW89_FCC][1][51] = -2, + [0][1][1][0][RTW89_ETSI][1][51] = 127, + [0][1][1][0][RTW89_ETSI][0][51] = 127, + [0][1][1][0][RTW89_MKK][1][51] = 127, + [0][1][1][0][RTW89_MKK][0][51] = 127, + [0][1][1][0][RTW89_IC][1][51] = -2, + [0][1][1][0][RTW89_KCC][1][51] = 12, + [0][1][1][0][RTW89_KCC][0][51] = 127, + [0][1][1][0][RTW89_ACMA][1][51] = 127, + [0][1][1][0][RTW89_ACMA][0][51] = 127, + [0][1][1][0][RTW89_CHILE][1][51] = -2, + [0][1][1][0][RTW89_QATAR][1][51] = 127, + [0][1][1][0][RTW89_QATAR][0][51] = 127, + [0][1][1][0][RTW89_UK][1][51] = 127, + [0][1][1][0][RTW89_UK][0][51] = 127, + [0][1][1][0][RTW89_THAILAND][1][51] = 127, + [0][1][1][0][RTW89_THAILAND][0][51] = 127, + [0][1][1][0][RTW89_FCC][1][53] = -2, + [0][1][1][0][RTW89_ETSI][1][53] = 127, + [0][1][1][0][RTW89_ETSI][0][53] = 127, + [0][1][1][0][RTW89_MKK][1][53] = 127, + [0][1][1][0][RTW89_MKK][0][53] = 127, + [0][1][1][0][RTW89_IC][1][53] = -2, + [0][1][1][0][RTW89_KCC][1][53] = 12, + [0][1][1][0][RTW89_KCC][0][53] = 127, + [0][1][1][0][RTW89_ACMA][1][53] = 127, + [0][1][1][0][RTW89_ACMA][0][53] = 127, + [0][1][1][0][RTW89_CHILE][1][53] = -2, + [0][1][1][0][RTW89_QATAR][1][53] = 127, + [0][1][1][0][RTW89_QATAR][0][53] = 127, + [0][1][1][0][RTW89_UK][1][53] = 127, + [0][1][1][0][RTW89_UK][0][53] = 127, + [0][1][1][0][RTW89_THAILAND][1][53] = 127, + [0][1][1][0][RTW89_THAILAND][0][53] = 127, + [0][1][1][0][RTW89_FCC][1][55] = -2, + [0][1][1][0][RTW89_ETSI][1][55] = 127, + [0][1][1][0][RTW89_ETSI][0][55] = 127, + [0][1][1][0][RTW89_MKK][1][55] = 127, + [0][1][1][0][RTW89_MKK][0][55] = 127, + [0][1][1][0][RTW89_IC][1][55] = -2, + [0][1][1][0][RTW89_KCC][1][55] = 12, + [0][1][1][0][RTW89_KCC][0][55] = 127, + [0][1][1][0][RTW89_ACMA][1][55] = 127, + [0][1][1][0][RTW89_ACMA][0][55] = 127, + [0][1][1][0][RTW89_CHILE][1][55] = -2, + [0][1][1][0][RTW89_QATAR][1][55] = 127, + [0][1][1][0][RTW89_QATAR][0][55] = 127, + [0][1][1][0][RTW89_UK][1][55] = 127, + [0][1][1][0][RTW89_UK][0][55] = 127, + [0][1][1][0][RTW89_THAILAND][1][55] = 127, + [0][1][1][0][RTW89_THAILAND][0][55] = 127, + [0][1][1][0][RTW89_FCC][1][57] = -2, + [0][1][1][0][RTW89_ETSI][1][57] = 127, + [0][1][1][0][RTW89_ETSI][0][57] = 127, + [0][1][1][0][RTW89_MKK][1][57] = 127, + [0][1][1][0][RTW89_MKK][0][57] = 127, + [0][1][1][0][RTW89_IC][1][57] = -2, + [0][1][1][0][RTW89_KCC][1][57] = 12, + [0][1][1][0][RTW89_KCC][0][57] = 127, + [0][1][1][0][RTW89_ACMA][1][57] = 127, + [0][1][1][0][RTW89_ACMA][0][57] = 127, + [0][1][1][0][RTW89_CHILE][1][57] = -2, + [0][1][1][0][RTW89_QATAR][1][57] = 127, + [0][1][1][0][RTW89_QATAR][0][57] = 127, + [0][1][1][0][RTW89_UK][1][57] = 127, + [0][1][1][0][RTW89_UK][0][57] = 127, + [0][1][1][0][RTW89_THAILAND][1][57] = 127, + [0][1][1][0][RTW89_THAILAND][0][57] = 127, + [0][1][1][0][RTW89_FCC][1][59] = -2, + [0][1][1][0][RTW89_ETSI][1][59] = 127, + [0][1][1][0][RTW89_ETSI][0][59] = 127, + [0][1][1][0][RTW89_MKK][1][59] = 127, + [0][1][1][0][RTW89_MKK][0][59] = 127, + [0][1][1][0][RTW89_IC][1][59] = -2, + [0][1][1][0][RTW89_KCC][1][59] = 12, + [0][1][1][0][RTW89_KCC][0][59] = 127, + [0][1][1][0][RTW89_ACMA][1][59] = 127, + [0][1][1][0][RTW89_ACMA][0][59] = 127, + [0][1][1][0][RTW89_CHILE][1][59] = -2, + [0][1][1][0][RTW89_QATAR][1][59] = 127, + [0][1][1][0][RTW89_QATAR][0][59] = 127, + [0][1][1][0][RTW89_UK][1][59] = 127, + [0][1][1][0][RTW89_UK][0][59] = 127, + [0][1][1][0][RTW89_THAILAND][1][59] = 127, + [0][1][1][0][RTW89_THAILAND][0][59] = 127, + [0][1][1][0][RTW89_FCC][1][60] = -2, + [0][1][1][0][RTW89_ETSI][1][60] = 127, + [0][1][1][0][RTW89_ETSI][0][60] = 127, + [0][1][1][0][RTW89_MKK][1][60] = 127, + [0][1][1][0][RTW89_MKK][0][60] = 127, + [0][1][1][0][RTW89_IC][1][60] = -2, + [0][1][1][0][RTW89_KCC][1][60] = 12, + [0][1][1][0][RTW89_KCC][0][60] = 127, + [0][1][1][0][RTW89_ACMA][1][60] = 127, + [0][1][1][0][RTW89_ACMA][0][60] = 127, + [0][1][1][0][RTW89_CHILE][1][60] = -2, + [0][1][1][0][RTW89_QATAR][1][60] = 127, + [0][1][1][0][RTW89_QATAR][0][60] = 127, + [0][1][1][0][RTW89_UK][1][60] = 127, + [0][1][1][0][RTW89_UK][0][60] = 127, + [0][1][1][0][RTW89_THAILAND][1][60] = 127, + [0][1][1][0][RTW89_THAILAND][0][60] = 127, + [0][1][1][0][RTW89_FCC][1][62] = -2, + [0][1][1][0][RTW89_ETSI][1][62] = 127, + [0][1][1][0][RTW89_ETSI][0][62] = 127, + [0][1][1][0][RTW89_MKK][1][62] = 127, + [0][1][1][0][RTW89_MKK][0][62] = 127, + [0][1][1][0][RTW89_IC][1][62] = -2, + [0][1][1][0][RTW89_KCC][1][62] = 12, + [0][1][1][0][RTW89_KCC][0][62] = 127, + [0][1][1][0][RTW89_ACMA][1][62] = 127, + [0][1][1][0][RTW89_ACMA][0][62] = 127, + [0][1][1][0][RTW89_CHILE][1][62] = -2, + [0][1][1][0][RTW89_QATAR][1][62] = 127, + [0][1][1][0][RTW89_QATAR][0][62] = 127, + [0][1][1][0][RTW89_UK][1][62] = 127, + [0][1][1][0][RTW89_UK][0][62] = 127, + [0][1][1][0][RTW89_THAILAND][1][62] = 127, + [0][1][1][0][RTW89_THAILAND][0][62] = 127, + [0][1][1][0][RTW89_FCC][1][64] = -2, + [0][1][1][0][RTW89_ETSI][1][64] = 127, + [0][1][1][0][RTW89_ETSI][0][64] = 127, + [0][1][1][0][RTW89_MKK][1][64] = 127, + [0][1][1][0][RTW89_MKK][0][64] = 127, + [0][1][1][0][RTW89_IC][1][64] = -2, + [0][1][1][0][RTW89_KCC][1][64] = 12, + [0][1][1][0][RTW89_KCC][0][64] = 127, + [0][1][1][0][RTW89_ACMA][1][64] = 127, + [0][1][1][0][RTW89_ACMA][0][64] = 127, + [0][1][1][0][RTW89_CHILE][1][64] = -2, + [0][1][1][0][RTW89_QATAR][1][64] = 127, + [0][1][1][0][RTW89_QATAR][0][64] = 127, + [0][1][1][0][RTW89_UK][1][64] = 127, + [0][1][1][0][RTW89_UK][0][64] = 127, + [0][1][1][0][RTW89_THAILAND][1][64] = 127, + [0][1][1][0][RTW89_THAILAND][0][64] = 127, + [0][1][1][0][RTW89_FCC][1][66] = -2, + [0][1][1][0][RTW89_ETSI][1][66] = 127, + [0][1][1][0][RTW89_ETSI][0][66] = 127, + [0][1][1][0][RTW89_MKK][1][66] = 127, + [0][1][1][0][RTW89_MKK][0][66] = 127, + [0][1][1][0][RTW89_IC][1][66] = -2, + [0][1][1][0][RTW89_KCC][1][66] = 12, + [0][1][1][0][RTW89_KCC][0][66] = 127, + [0][1][1][0][RTW89_ACMA][1][66] = 127, + [0][1][1][0][RTW89_ACMA][0][66] = 127, + [0][1][1][0][RTW89_CHILE][1][66] = -2, + [0][1][1][0][RTW89_QATAR][1][66] = 127, + [0][1][1][0][RTW89_QATAR][0][66] = 127, + [0][1][1][0][RTW89_UK][1][66] = 127, + [0][1][1][0][RTW89_UK][0][66] = 127, + [0][1][1][0][RTW89_THAILAND][1][66] = 127, + [0][1][1][0][RTW89_THAILAND][0][66] = 127, + [0][1][1][0][RTW89_FCC][1][68] = -2, + [0][1][1][0][RTW89_ETSI][1][68] = 127, + [0][1][1][0][RTW89_ETSI][0][68] = 127, + [0][1][1][0][RTW89_MKK][1][68] = 127, + [0][1][1][0][RTW89_MKK][0][68] = 127, + [0][1][1][0][RTW89_IC][1][68] = -2, + [0][1][1][0][RTW89_KCC][1][68] = 12, + [0][1][1][0][RTW89_KCC][0][68] = 127, + [0][1][1][0][RTW89_ACMA][1][68] = 127, + [0][1][1][0][RTW89_ACMA][0][68] = 127, + [0][1][1][0][RTW89_CHILE][1][68] = -2, + [0][1][1][0][RTW89_QATAR][1][68] = 127, + [0][1][1][0][RTW89_QATAR][0][68] = 127, + [0][1][1][0][RTW89_UK][1][68] = 127, + [0][1][1][0][RTW89_UK][0][68] = 127, + [0][1][1][0][RTW89_THAILAND][1][68] = 127, + [0][1][1][0][RTW89_THAILAND][0][68] = 127, + [0][1][1][0][RTW89_FCC][1][70] = -2, + [0][1][1][0][RTW89_ETSI][1][70] = 127, + [0][1][1][0][RTW89_ETSI][0][70] = 127, + [0][1][1][0][RTW89_MKK][1][70] = 127, + [0][1][1][0][RTW89_MKK][0][70] = 127, + [0][1][1][0][RTW89_IC][1][70] = -2, + [0][1][1][0][RTW89_KCC][1][70] = 12, + [0][1][1][0][RTW89_KCC][0][70] = 127, + [0][1][1][0][RTW89_ACMA][1][70] = 127, + [0][1][1][0][RTW89_ACMA][0][70] = 127, + [0][1][1][0][RTW89_CHILE][1][70] = -2, + [0][1][1][0][RTW89_QATAR][1][70] = 127, + [0][1][1][0][RTW89_QATAR][0][70] = 127, + [0][1][1][0][RTW89_UK][1][70] = 127, + [0][1][1][0][RTW89_UK][0][70] = 127, + [0][1][1][0][RTW89_THAILAND][1][70] = 127, + [0][1][1][0][RTW89_THAILAND][0][70] = 127, + [0][1][1][0][RTW89_FCC][1][72] = -2, + [0][1][1][0][RTW89_ETSI][1][72] = 127, + [0][1][1][0][RTW89_ETSI][0][72] = 127, + [0][1][1][0][RTW89_MKK][1][72] = 127, + [0][1][1][0][RTW89_MKK][0][72] = 127, + [0][1][1][0][RTW89_IC][1][72] = -2, + [0][1][1][0][RTW89_KCC][1][72] = 12, + [0][1][1][0][RTW89_KCC][0][72] = 127, + [0][1][1][0][RTW89_ACMA][1][72] = 127, + [0][1][1][0][RTW89_ACMA][0][72] = 127, + [0][1][1][0][RTW89_CHILE][1][72] = -2, + [0][1][1][0][RTW89_QATAR][1][72] = 127, + [0][1][1][0][RTW89_QATAR][0][72] = 127, + [0][1][1][0][RTW89_UK][1][72] = 127, + [0][1][1][0][RTW89_UK][0][72] = 127, + [0][1][1][0][RTW89_THAILAND][1][72] = 127, + [0][1][1][0][RTW89_THAILAND][0][72] = 127, + [0][1][1][0][RTW89_FCC][1][74] = -2, + [0][1][1][0][RTW89_ETSI][1][74] = 127, + [0][1][1][0][RTW89_ETSI][0][74] = 127, + [0][1][1][0][RTW89_MKK][1][74] = 127, + [0][1][1][0][RTW89_MKK][0][74] = 127, + [0][1][1][0][RTW89_IC][1][74] = -2, + [0][1][1][0][RTW89_KCC][1][74] = 12, + [0][1][1][0][RTW89_KCC][0][74] = 127, + [0][1][1][0][RTW89_ACMA][1][74] = 127, + [0][1][1][0][RTW89_ACMA][0][74] = 127, + [0][1][1][0][RTW89_CHILE][1][74] = -2, + [0][1][1][0][RTW89_QATAR][1][74] = 127, + [0][1][1][0][RTW89_QATAR][0][74] = 127, + [0][1][1][0][RTW89_UK][1][74] = 127, + [0][1][1][0][RTW89_UK][0][74] = 127, + [0][1][1][0][RTW89_THAILAND][1][74] = 127, + [0][1][1][0][RTW89_THAILAND][0][74] = 127, + [0][1][1][0][RTW89_FCC][1][75] = -2, + [0][1][1][0][RTW89_ETSI][1][75] = 127, + [0][1][1][0][RTW89_ETSI][0][75] = 127, + [0][1][1][0][RTW89_MKK][1][75] = 127, + [0][1][1][0][RTW89_MKK][0][75] = 127, + [0][1][1][0][RTW89_IC][1][75] = -2, + [0][1][1][0][RTW89_KCC][1][75] = 12, + [0][1][1][0][RTW89_KCC][0][75] = 127, + [0][1][1][0][RTW89_ACMA][1][75] = 127, + [0][1][1][0][RTW89_ACMA][0][75] = 127, + [0][1][1][0][RTW89_CHILE][1][75] = -2, + [0][1][1][0][RTW89_QATAR][1][75] = 127, + [0][1][1][0][RTW89_QATAR][0][75] = 127, + [0][1][1][0][RTW89_UK][1][75] = 127, + [0][1][1][0][RTW89_UK][0][75] = 127, + [0][1][1][0][RTW89_THAILAND][1][75] = 127, + [0][1][1][0][RTW89_THAILAND][0][75] = 127, + [0][1][1][0][RTW89_FCC][1][77] = -2, + [0][1][1][0][RTW89_ETSI][1][77] = 127, + [0][1][1][0][RTW89_ETSI][0][77] = 127, + [0][1][1][0][RTW89_MKK][1][77] = 127, + [0][1][1][0][RTW89_MKK][0][77] = 127, + [0][1][1][0][RTW89_IC][1][77] = -2, + [0][1][1][0][RTW89_KCC][1][77] = 12, + [0][1][1][0][RTW89_KCC][0][77] = 127, + [0][1][1][0][RTW89_ACMA][1][77] = 127, + [0][1][1][0][RTW89_ACMA][0][77] = 127, + [0][1][1][0][RTW89_CHILE][1][77] = -2, + [0][1][1][0][RTW89_QATAR][1][77] = 127, + [0][1][1][0][RTW89_QATAR][0][77] = 127, + [0][1][1][0][RTW89_UK][1][77] = 127, + [0][1][1][0][RTW89_UK][0][77] = 127, + [0][1][1][0][RTW89_THAILAND][1][77] = 127, + [0][1][1][0][RTW89_THAILAND][0][77] = 127, + [0][1][1][0][RTW89_FCC][1][79] = -2, + [0][1][1][0][RTW89_ETSI][1][79] = 127, + [0][1][1][0][RTW89_ETSI][0][79] = 127, + [0][1][1][0][RTW89_MKK][1][79] = 127, + [0][1][1][0][RTW89_MKK][0][79] = 127, + [0][1][1][0][RTW89_IC][1][79] = -2, + [0][1][1][0][RTW89_KCC][1][79] = 12, + [0][1][1][0][RTW89_KCC][0][79] = 127, + [0][1][1][0][RTW89_ACMA][1][79] = 127, + [0][1][1][0][RTW89_ACMA][0][79] = 127, + [0][1][1][0][RTW89_CHILE][1][79] = -2, + [0][1][1][0][RTW89_QATAR][1][79] = 127, + [0][1][1][0][RTW89_QATAR][0][79] = 127, + [0][1][1][0][RTW89_UK][1][79] = 127, + [0][1][1][0][RTW89_UK][0][79] = 127, + [0][1][1][0][RTW89_THAILAND][1][79] = 127, + [0][1][1][0][RTW89_THAILAND][0][79] = 127, + [0][1][1][0][RTW89_FCC][1][81] = -2, + [0][1][1][0][RTW89_ETSI][1][81] = 127, + [0][1][1][0][RTW89_ETSI][0][81] = 127, + [0][1][1][0][RTW89_MKK][1][81] = 127, + [0][1][1][0][RTW89_MKK][0][81] = 127, + [0][1][1][0][RTW89_IC][1][81] = -2, + [0][1][1][0][RTW89_KCC][1][81] = 12, + [0][1][1][0][RTW89_KCC][0][81] = 127, + [0][1][1][0][RTW89_ACMA][1][81] = 127, + [0][1][1][0][RTW89_ACMA][0][81] = 127, + [0][1][1][0][RTW89_CHILE][1][81] = -2, + [0][1][1][0][RTW89_QATAR][1][81] = 127, + [0][1][1][0][RTW89_QATAR][0][81] = 127, + [0][1][1][0][RTW89_UK][1][81] = 127, + [0][1][1][0][RTW89_UK][0][81] = 127, + [0][1][1][0][RTW89_THAILAND][1][81] = 127, + [0][1][1][0][RTW89_THAILAND][0][81] = 127, + [0][1][1][0][RTW89_FCC][1][83] = -2, + [0][1][1][0][RTW89_ETSI][1][83] = 127, + [0][1][1][0][RTW89_ETSI][0][83] = 127, + [0][1][1][0][RTW89_MKK][1][83] = 127, + [0][1][1][0][RTW89_MKK][0][83] = 127, + [0][1][1][0][RTW89_IC][1][83] = -2, + [0][1][1][0][RTW89_KCC][1][83] = 20, + [0][1][1][0][RTW89_KCC][0][83] = 127, + [0][1][1][0][RTW89_ACMA][1][83] = 127, + [0][1][1][0][RTW89_ACMA][0][83] = 127, + [0][1][1][0][RTW89_CHILE][1][83] = -2, + [0][1][1][0][RTW89_QATAR][1][83] = 127, + [0][1][1][0][RTW89_QATAR][0][83] = 127, + [0][1][1][0][RTW89_UK][1][83] = 127, + [0][1][1][0][RTW89_UK][0][83] = 127, + [0][1][1][0][RTW89_THAILAND][1][83] = 127, + [0][1][1][0][RTW89_THAILAND][0][83] = 127, + [0][1][1][0][RTW89_FCC][1][85] = -2, + [0][1][1][0][RTW89_ETSI][1][85] = 127, + [0][1][1][0][RTW89_ETSI][0][85] = 127, + [0][1][1][0][RTW89_MKK][1][85] = 127, + [0][1][1][0][RTW89_MKK][0][85] = 127, + [0][1][1][0][RTW89_IC][1][85] = -2, + [0][1][1][0][RTW89_KCC][1][85] = 20, + [0][1][1][0][RTW89_KCC][0][85] = 127, + [0][1][1][0][RTW89_ACMA][1][85] = 127, + [0][1][1][0][RTW89_ACMA][0][85] = 127, + [0][1][1][0][RTW89_CHILE][1][85] = -2, + [0][1][1][0][RTW89_QATAR][1][85] = 127, + [0][1][1][0][RTW89_QATAR][0][85] = 127, + [0][1][1][0][RTW89_UK][1][85] = 127, + [0][1][1][0][RTW89_UK][0][85] = 127, + [0][1][1][0][RTW89_THAILAND][1][85] = 127, + [0][1][1][0][RTW89_THAILAND][0][85] = 127, + [0][1][1][0][RTW89_FCC][1][87] = -2, + [0][1][1][0][RTW89_ETSI][1][87] = 127, + [0][1][1][0][RTW89_ETSI][0][87] = 127, + [0][1][1][0][RTW89_MKK][1][87] = 127, + [0][1][1][0][RTW89_MKK][0][87] = 127, + [0][1][1][0][RTW89_IC][1][87] = -2, + [0][1][1][0][RTW89_KCC][1][87] = 20, + [0][1][1][0][RTW89_KCC][0][87] = 127, + [0][1][1][0][RTW89_ACMA][1][87] = 127, + [0][1][1][0][RTW89_ACMA][0][87] = 127, + [0][1][1][0][RTW89_CHILE][1][87] = -2, + [0][1][1][0][RTW89_QATAR][1][87] = 127, + [0][1][1][0][RTW89_QATAR][0][87] = 127, + [0][1][1][0][RTW89_UK][1][87] = 127, + [0][1][1][0][RTW89_UK][0][87] = 127, + [0][1][1][0][RTW89_THAILAND][1][87] = 127, + [0][1][1][0][RTW89_THAILAND][0][87] = 127, + [0][1][1][0][RTW89_FCC][1][89] = -2, + [0][1][1][0][RTW89_ETSI][1][89] = 127, + [0][1][1][0][RTW89_ETSI][0][89] = 127, + [0][1][1][0][RTW89_MKK][1][89] = 127, + [0][1][1][0][RTW89_MKK][0][89] = 127, + [0][1][1][0][RTW89_IC][1][89] = -2, + [0][1][1][0][RTW89_KCC][1][89] = 20, + [0][1][1][0][RTW89_KCC][0][89] = 127, + [0][1][1][0][RTW89_ACMA][1][89] = 127, + [0][1][1][0][RTW89_ACMA][0][89] = 127, + [0][1][1][0][RTW89_CHILE][1][89] = -2, + [0][1][1][0][RTW89_QATAR][1][89] = 127, + [0][1][1][0][RTW89_QATAR][0][89] = 127, + [0][1][1][0][RTW89_UK][1][89] = 127, + [0][1][1][0][RTW89_UK][0][89] = 127, + [0][1][1][0][RTW89_THAILAND][1][89] = 127, + [0][1][1][0][RTW89_THAILAND][0][89] = 127, + [0][1][1][0][RTW89_FCC][1][90] = -2, + [0][1][1][0][RTW89_ETSI][1][90] = 127, + [0][1][1][0][RTW89_ETSI][0][90] = 127, + [0][1][1][0][RTW89_MKK][1][90] = 127, + [0][1][1][0][RTW89_MKK][0][90] = 127, + [0][1][1][0][RTW89_IC][1][90] = -2, + [0][1][1][0][RTW89_KCC][1][90] = 20, + [0][1][1][0][RTW89_KCC][0][90] = 127, + [0][1][1][0][RTW89_ACMA][1][90] = 127, + [0][1][1][0][RTW89_ACMA][0][90] = 127, + [0][1][1][0][RTW89_CHILE][1][90] = -2, + [0][1][1][0][RTW89_QATAR][1][90] = 127, + [0][1][1][0][RTW89_QATAR][0][90] = 127, + [0][1][1][0][RTW89_UK][1][90] = 127, + [0][1][1][0][RTW89_UK][0][90] = 127, + [0][1][1][0][RTW89_THAILAND][1][90] = 127, + [0][1][1][0][RTW89_THAILAND][0][90] = 127, + [0][1][1][0][RTW89_FCC][1][92] = -2, + [0][1][1][0][RTW89_ETSI][1][92] = 127, + [0][1][1][0][RTW89_ETSI][0][92] = 127, + [0][1][1][0][RTW89_MKK][1][92] = 127, + [0][1][1][0][RTW89_MKK][0][92] = 127, + [0][1][1][0][RTW89_IC][1][92] = -2, + [0][1][1][0][RTW89_KCC][1][92] = 20, + [0][1][1][0][RTW89_KCC][0][92] = 127, + [0][1][1][0][RTW89_ACMA][1][92] = 127, + [0][1][1][0][RTW89_ACMA][0][92] = 127, + [0][1][1][0][RTW89_CHILE][1][92] = -2, + [0][1][1][0][RTW89_QATAR][1][92] = 127, + [0][1][1][0][RTW89_QATAR][0][92] = 127, + [0][1][1][0][RTW89_UK][1][92] = 127, + [0][1][1][0][RTW89_UK][0][92] = 127, + [0][1][1][0][RTW89_THAILAND][1][92] = 127, + [0][1][1][0][RTW89_THAILAND][0][92] = 127, + [0][1][1][0][RTW89_FCC][1][94] = -2, + [0][1][1][0][RTW89_ETSI][1][94] = 127, + [0][1][1][0][RTW89_ETSI][0][94] = 127, + [0][1][1][0][RTW89_MKK][1][94] = 127, + [0][1][1][0][RTW89_MKK][0][94] = 127, + [0][1][1][0][RTW89_IC][1][94] = -2, + [0][1][1][0][RTW89_KCC][1][94] = 20, + [0][1][1][0][RTW89_KCC][0][94] = 127, + [0][1][1][0][RTW89_ACMA][1][94] = 127, + [0][1][1][0][RTW89_ACMA][0][94] = 127, + [0][1][1][0][RTW89_CHILE][1][94] = -2, + [0][1][1][0][RTW89_QATAR][1][94] = 127, + [0][1][1][0][RTW89_QATAR][0][94] = 127, + [0][1][1][0][RTW89_UK][1][94] = 127, + [0][1][1][0][RTW89_UK][0][94] = 127, + [0][1][1][0][RTW89_THAILAND][1][94] = 127, + [0][1][1][0][RTW89_THAILAND][0][94] = 127, + [0][1][1][0][RTW89_FCC][1][96] = -2, + [0][1][1][0][RTW89_ETSI][1][96] = 127, + [0][1][1][0][RTW89_ETSI][0][96] = 127, + [0][1][1][0][RTW89_MKK][1][96] = 127, + [0][1][1][0][RTW89_MKK][0][96] = 127, + [0][1][1][0][RTW89_IC][1][96] = -2, + [0][1][1][0][RTW89_KCC][1][96] = 20, + [0][1][1][0][RTW89_KCC][0][96] = 127, + [0][1][1][0][RTW89_ACMA][1][96] = 127, + [0][1][1][0][RTW89_ACMA][0][96] = 127, + [0][1][1][0][RTW89_CHILE][1][96] = -2, + [0][1][1][0][RTW89_QATAR][1][96] = 127, + [0][1][1][0][RTW89_QATAR][0][96] = 127, + [0][1][1][0][RTW89_UK][1][96] = 127, + [0][1][1][0][RTW89_UK][0][96] = 127, + [0][1][1][0][RTW89_THAILAND][1][96] = 127, + [0][1][1][0][RTW89_THAILAND][0][96] = 127, + [0][1][1][0][RTW89_FCC][1][98] = -2, + [0][1][1][0][RTW89_ETSI][1][98] = 127, + [0][1][1][0][RTW89_ETSI][0][98] = 127, + [0][1][1][0][RTW89_MKK][1][98] = 127, + [0][1][1][0][RTW89_MKK][0][98] = 127, + [0][1][1][0][RTW89_IC][1][98] = -2, + [0][1][1][0][RTW89_KCC][1][98] = 20, + [0][1][1][0][RTW89_KCC][0][98] = 127, + [0][1][1][0][RTW89_ACMA][1][98] = 127, + [0][1][1][0][RTW89_ACMA][0][98] = 127, + [0][1][1][0][RTW89_CHILE][1][98] = -2, + [0][1][1][0][RTW89_QATAR][1][98] = 127, + [0][1][1][0][RTW89_QATAR][0][98] = 127, + [0][1][1][0][RTW89_UK][1][98] = 127, + [0][1][1][0][RTW89_UK][0][98] = 127, + [0][1][1][0][RTW89_THAILAND][1][98] = 127, + [0][1][1][0][RTW89_THAILAND][0][98] = 127, + [0][1][1][0][RTW89_FCC][1][100] = -2, + [0][1][1][0][RTW89_ETSI][1][100] = 127, + [0][1][1][0][RTW89_ETSI][0][100] = 127, + [0][1][1][0][RTW89_MKK][1][100] = 127, + [0][1][1][0][RTW89_MKK][0][100] = 127, + [0][1][1][0][RTW89_IC][1][100] = -2, + [0][1][1][0][RTW89_KCC][1][100] = 20, + [0][1][1][0][RTW89_KCC][0][100] = 127, + [0][1][1][0][RTW89_ACMA][1][100] = 127, + [0][1][1][0][RTW89_ACMA][0][100] = 127, + [0][1][1][0][RTW89_CHILE][1][100] = -2, + [0][1][1][0][RTW89_QATAR][1][100] = 127, + [0][1][1][0][RTW89_QATAR][0][100] = 127, + [0][1][1][0][RTW89_UK][1][100] = 127, + [0][1][1][0][RTW89_UK][0][100] = 127, + [0][1][1][0][RTW89_THAILAND][1][100] = 127, + [0][1][1][0][RTW89_THAILAND][0][100] = 127, + [0][1][1][0][RTW89_FCC][1][102] = -2, + [0][1][1][0][RTW89_ETSI][1][102] = 127, + [0][1][1][0][RTW89_ETSI][0][102] = 127, + [0][1][1][0][RTW89_MKK][1][102] = 127, + [0][1][1][0][RTW89_MKK][0][102] = 127, + [0][1][1][0][RTW89_IC][1][102] = -2, + [0][1][1][0][RTW89_KCC][1][102] = 20, + [0][1][1][0][RTW89_KCC][0][102] = 127, + [0][1][1][0][RTW89_ACMA][1][102] = 127, + [0][1][1][0][RTW89_ACMA][0][102] = 127, + [0][1][1][0][RTW89_CHILE][1][102] = -2, + [0][1][1][0][RTW89_QATAR][1][102] = 127, + [0][1][1][0][RTW89_QATAR][0][102] = 127, + [0][1][1][0][RTW89_UK][1][102] = 127, + [0][1][1][0][RTW89_UK][0][102] = 127, + [0][1][1][0][RTW89_THAILAND][1][102] = 127, + [0][1][1][0][RTW89_THAILAND][0][102] = 127, + [0][1][1][0][RTW89_FCC][1][104] = -2, + [0][1][1][0][RTW89_ETSI][1][104] = 127, + [0][1][1][0][RTW89_ETSI][0][104] = 127, + [0][1][1][0][RTW89_MKK][1][104] = 127, + [0][1][1][0][RTW89_MKK][0][104] = 127, + [0][1][1][0][RTW89_IC][1][104] = -2, + [0][1][1][0][RTW89_KCC][1][104] = 20, + [0][1][1][0][RTW89_KCC][0][104] = 127, + [0][1][1][0][RTW89_ACMA][1][104] = 127, + [0][1][1][0][RTW89_ACMA][0][104] = 127, + [0][1][1][0][RTW89_CHILE][1][104] = -2, + [0][1][1][0][RTW89_QATAR][1][104] = 127, + [0][1][1][0][RTW89_QATAR][0][104] = 127, + [0][1][1][0][RTW89_UK][1][104] = 127, + [0][1][1][0][RTW89_UK][0][104] = 127, + [0][1][1][0][RTW89_THAILAND][1][104] = 127, + [0][1][1][0][RTW89_THAILAND][0][104] = 127, + [0][1][1][0][RTW89_FCC][1][105] = -2, + [0][1][1][0][RTW89_ETSI][1][105] = 127, + [0][1][1][0][RTW89_ETSI][0][105] = 127, + [0][1][1][0][RTW89_MKK][1][105] = 127, + [0][1][1][0][RTW89_MKK][0][105] = 127, + [0][1][1][0][RTW89_IC][1][105] = -2, + [0][1][1][0][RTW89_KCC][1][105] = 20, + [0][1][1][0][RTW89_KCC][0][105] = 127, + [0][1][1][0][RTW89_ACMA][1][105] = 127, + [0][1][1][0][RTW89_ACMA][0][105] = 127, + [0][1][1][0][RTW89_CHILE][1][105] = -2, + [0][1][1][0][RTW89_QATAR][1][105] = 127, + [0][1][1][0][RTW89_QATAR][0][105] = 127, + [0][1][1][0][RTW89_UK][1][105] = 127, + [0][1][1][0][RTW89_UK][0][105] = 127, + [0][1][1][0][RTW89_THAILAND][1][105] = 127, + [0][1][1][0][RTW89_THAILAND][0][105] = 127, + [0][1][1][0][RTW89_FCC][1][107] = 1, + [0][1][1][0][RTW89_ETSI][1][107] = 127, + [0][1][1][0][RTW89_ETSI][0][107] = 127, + [0][1][1][0][RTW89_MKK][1][107] = 127, + [0][1][1][0][RTW89_MKK][0][107] = 127, + [0][1][1][0][RTW89_IC][1][107] = 1, + [0][1][1][0][RTW89_KCC][1][107] = 20, + [0][1][1][0][RTW89_KCC][0][107] = 127, + [0][1][1][0][RTW89_ACMA][1][107] = 127, + [0][1][1][0][RTW89_ACMA][0][107] = 127, + [0][1][1][0][RTW89_CHILE][1][107] = 1, + [0][1][1][0][RTW89_QATAR][1][107] = 127, + [0][1][1][0][RTW89_QATAR][0][107] = 127, + [0][1][1][0][RTW89_UK][1][107] = 127, + [0][1][1][0][RTW89_UK][0][107] = 127, + [0][1][1][0][RTW89_THAILAND][1][107] = 127, + [0][1][1][0][RTW89_THAILAND][0][107] = 127, + [0][1][1][0][RTW89_FCC][1][109] = 1, + [0][1][1][0][RTW89_ETSI][1][109] = 127, + [0][1][1][0][RTW89_ETSI][0][109] = 127, + [0][1][1][0][RTW89_MKK][1][109] = 127, + [0][1][1][0][RTW89_MKK][0][109] = 127, + [0][1][1][0][RTW89_IC][1][109] = 1, + [0][1][1][0][RTW89_KCC][1][109] = 20, + [0][1][1][0][RTW89_KCC][0][109] = 127, + [0][1][1][0][RTW89_ACMA][1][109] = 127, + [0][1][1][0][RTW89_ACMA][0][109] = 127, + [0][1][1][0][RTW89_CHILE][1][109] = 1, + [0][1][1][0][RTW89_QATAR][1][109] = 127, + [0][1][1][0][RTW89_QATAR][0][109] = 127, + [0][1][1][0][RTW89_UK][1][109] = 127, + [0][1][1][0][RTW89_UK][0][109] = 127, + [0][1][1][0][RTW89_THAILAND][1][109] = 127, + [0][1][1][0][RTW89_THAILAND][0][109] = 127, + [0][1][1][0][RTW89_FCC][1][111] = 127, + [0][1][1][0][RTW89_ETSI][1][111] = 127, + [0][1][1][0][RTW89_ETSI][0][111] = 127, + [0][1][1][0][RTW89_MKK][1][111] = 127, + [0][1][1][0][RTW89_MKK][0][111] = 127, + [0][1][1][0][RTW89_IC][1][111] = 127, + [0][1][1][0][RTW89_KCC][1][111] = 127, + [0][1][1][0][RTW89_KCC][0][111] = 127, + [0][1][1][0][RTW89_ACMA][1][111] = 127, + [0][1][1][0][RTW89_ACMA][0][111] = 127, + [0][1][1][0][RTW89_CHILE][1][111] = 127, + [0][1][1][0][RTW89_QATAR][1][111] = 127, + [0][1][1][0][RTW89_QATAR][0][111] = 127, + [0][1][1][0][RTW89_UK][1][111] = 127, + [0][1][1][0][RTW89_UK][0][111] = 127, + [0][1][1][0][RTW89_THAILAND][1][111] = 127, + [0][1][1][0][RTW89_THAILAND][0][111] = 127, + [0][1][1][0][RTW89_FCC][1][113] = 127, + [0][1][1][0][RTW89_ETSI][1][113] = 127, + [0][1][1][0][RTW89_ETSI][0][113] = 127, + [0][1][1][0][RTW89_MKK][1][113] = 127, + [0][1][1][0][RTW89_MKK][0][113] = 127, + [0][1][1][0][RTW89_IC][1][113] = 127, + [0][1][1][0][RTW89_KCC][1][113] = 127, + [0][1][1][0][RTW89_KCC][0][113] = 127, + [0][1][1][0][RTW89_ACMA][1][113] = 127, + [0][1][1][0][RTW89_ACMA][0][113] = 127, + [0][1][1][0][RTW89_CHILE][1][113] = 127, + [0][1][1][0][RTW89_QATAR][1][113] = 127, + [0][1][1][0][RTW89_QATAR][0][113] = 127, + [0][1][1][0][RTW89_UK][1][113] = 127, + [0][1][1][0][RTW89_UK][0][113] = 127, + [0][1][1][0][RTW89_THAILAND][1][113] = 127, + [0][1][1][0][RTW89_THAILAND][0][113] = 127, + [0][1][1][0][RTW89_FCC][1][115] = 127, + [0][1][1][0][RTW89_ETSI][1][115] = 127, + [0][1][1][0][RTW89_ETSI][0][115] = 127, + [0][1][1][0][RTW89_MKK][1][115] = 127, + [0][1][1][0][RTW89_MKK][0][115] = 127, + [0][1][1][0][RTW89_IC][1][115] = 127, + [0][1][1][0][RTW89_KCC][1][115] = 127, + [0][1][1][0][RTW89_KCC][0][115] = 127, + [0][1][1][0][RTW89_ACMA][1][115] = 127, + [0][1][1][0][RTW89_ACMA][0][115] = 127, + [0][1][1][0][RTW89_CHILE][1][115] = 127, + [0][1][1][0][RTW89_QATAR][1][115] = 127, + [0][1][1][0][RTW89_QATAR][0][115] = 127, + [0][1][1][0][RTW89_UK][1][115] = 127, + [0][1][1][0][RTW89_UK][0][115] = 127, + [0][1][1][0][RTW89_THAILAND][1][115] = 127, + [0][1][1][0][RTW89_THAILAND][0][115] = 127, + [0][1][1][0][RTW89_FCC][1][117] = 127, + [0][1][1][0][RTW89_ETSI][1][117] = 127, + [0][1][1][0][RTW89_ETSI][0][117] = 127, + [0][1][1][0][RTW89_MKK][1][117] = 127, + [0][1][1][0][RTW89_MKK][0][117] = 127, + [0][1][1][0][RTW89_IC][1][117] = 127, + [0][1][1][0][RTW89_KCC][1][117] = 127, + [0][1][1][0][RTW89_KCC][0][117] = 127, + [0][1][1][0][RTW89_ACMA][1][117] = 127, + [0][1][1][0][RTW89_ACMA][0][117] = 127, + [0][1][1][0][RTW89_CHILE][1][117] = 127, + [0][1][1][0][RTW89_QATAR][1][117] = 127, + [0][1][1][0][RTW89_QATAR][0][117] = 127, + [0][1][1][0][RTW89_UK][1][117] = 127, + [0][1][1][0][RTW89_UK][0][117] = 127, + [0][1][1][0][RTW89_THAILAND][1][117] = 127, + [0][1][1][0][RTW89_THAILAND][0][117] = 127, + [0][1][1][0][RTW89_FCC][1][119] = 127, + [0][1][1][0][RTW89_ETSI][1][119] = 127, + [0][1][1][0][RTW89_ETSI][0][119] = 127, + [0][1][1][0][RTW89_MKK][1][119] = 127, + [0][1][1][0][RTW89_MKK][0][119] = 127, + [0][1][1][0][RTW89_IC][1][119] = 127, + [0][1][1][0][RTW89_KCC][1][119] = 127, + [0][1][1][0][RTW89_KCC][0][119] = 127, + [0][1][1][0][RTW89_ACMA][1][119] = 127, + [0][1][1][0][RTW89_ACMA][0][119] = 127, + [0][1][1][0][RTW89_CHILE][1][119] = 127, + [0][1][1][0][RTW89_QATAR][1][119] = 127, + [0][1][1][0][RTW89_QATAR][0][119] = 127, + [0][1][1][0][RTW89_UK][1][119] = 127, + [0][1][1][0][RTW89_UK][0][119] = 127, + [0][1][1][0][RTW89_THAILAND][1][119] = 127, + [0][1][1][0][RTW89_THAILAND][0][119] = 127, + [0][0][2][0][RTW89_FCC][1][0] = 24, + [0][0][2][0][RTW89_ETSI][1][0] = 66, + [0][0][2][0][RTW89_ETSI][0][0] = 28, + [0][0][2][0][RTW89_MKK][1][0] = 66, + [0][0][2][0][RTW89_MKK][0][0] = 26, + [0][0][2][0][RTW89_IC][1][0] = 24, + [0][0][2][0][RTW89_KCC][1][0] = 24, + [0][0][2][0][RTW89_KCC][0][0] = 24, + [0][0][2][0][RTW89_ACMA][1][0] = 66, + [0][0][2][0][RTW89_ACMA][0][0] = 28, + [0][0][2][0][RTW89_CHILE][1][0] = 24, + [0][0][2][0][RTW89_QATAR][1][0] = 66, + [0][0][2][0][RTW89_QATAR][0][0] = 28, + [0][0][2][0][RTW89_UK][1][0] = 66, + [0][0][2][0][RTW89_UK][0][0] = 28, + [0][0][2][0][RTW89_THAILAND][1][0] = 56, + [0][0][2][0][RTW89_THAILAND][0][0] = 24, + [0][0][2][0][RTW89_FCC][1][2] = 22, + [0][0][2][0][RTW89_ETSI][1][2] = 66, + [0][0][2][0][RTW89_ETSI][0][2] = 28, + [0][0][2][0][RTW89_MKK][1][2] = 66, + [0][0][2][0][RTW89_MKK][0][2] = 26, + [0][0][2][0][RTW89_IC][1][2] = 22, + [0][0][2][0][RTW89_KCC][1][2] = 24, + [0][0][2][0][RTW89_KCC][0][2] = 24, + [0][0][2][0][RTW89_ACMA][1][2] = 66, + [0][0][2][0][RTW89_ACMA][0][2] = 28, + [0][0][2][0][RTW89_CHILE][1][2] = 22, + [0][0][2][0][RTW89_QATAR][1][2] = 66, + [0][0][2][0][RTW89_QATAR][0][2] = 28, + [0][0][2][0][RTW89_UK][1][2] = 66, + [0][0][2][0][RTW89_UK][0][2] = 28, + [0][0][2][0][RTW89_THAILAND][1][2] = 56, + [0][0][2][0][RTW89_THAILAND][0][2] = 22, + [0][0][2][0][RTW89_FCC][1][4] = 22, + [0][0][2][0][RTW89_ETSI][1][4] = 66, + [0][0][2][0][RTW89_ETSI][0][4] = 28, + [0][0][2][0][RTW89_MKK][1][4] = 66, + [0][0][2][0][RTW89_MKK][0][4] = 26, + [0][0][2][0][RTW89_IC][1][4] = 22, + [0][0][2][0][RTW89_KCC][1][4] = 24, + [0][0][2][0][RTW89_KCC][0][4] = 24, + [0][0][2][0][RTW89_ACMA][1][4] = 66, + [0][0][2][0][RTW89_ACMA][0][4] = 28, + [0][0][2][0][RTW89_CHILE][1][4] = 22, + [0][0][2][0][RTW89_QATAR][1][4] = 66, + [0][0][2][0][RTW89_QATAR][0][4] = 28, + [0][0][2][0][RTW89_UK][1][4] = 66, + [0][0][2][0][RTW89_UK][0][4] = 28, + [0][0][2][0][RTW89_THAILAND][1][4] = 56, + [0][0][2][0][RTW89_THAILAND][0][4] = 22, + [0][0][2][0][RTW89_FCC][1][6] = 22, + [0][0][2][0][RTW89_ETSI][1][6] = 66, + [0][0][2][0][RTW89_ETSI][0][6] = 28, + [0][0][2][0][RTW89_MKK][1][6] = 66, + [0][0][2][0][RTW89_MKK][0][6] = 26, + [0][0][2][0][RTW89_IC][1][6] = 22, + [0][0][2][0][RTW89_KCC][1][6] = 24, + [0][0][2][0][RTW89_KCC][0][6] = 24, + [0][0][2][0][RTW89_ACMA][1][6] = 66, + [0][0][2][0][RTW89_ACMA][0][6] = 28, + [0][0][2][0][RTW89_CHILE][1][6] = 22, + [0][0][2][0][RTW89_QATAR][1][6] = 66, + [0][0][2][0][RTW89_QATAR][0][6] = 28, + [0][0][2][0][RTW89_UK][1][6] = 66, + [0][0][2][0][RTW89_UK][0][6] = 28, + [0][0][2][0][RTW89_THAILAND][1][6] = 56, + [0][0][2][0][RTW89_THAILAND][0][6] = 22, + [0][0][2][0][RTW89_FCC][1][8] = 22, + [0][0][2][0][RTW89_ETSI][1][8] = 66, + [0][0][2][0][RTW89_ETSI][0][8] = 28, + [0][0][2][0][RTW89_MKK][1][8] = 66, + [0][0][2][0][RTW89_MKK][0][8] = 26, + [0][0][2][0][RTW89_IC][1][8] = 22, + [0][0][2][0][RTW89_KCC][1][8] = 24, + [0][0][2][0][RTW89_KCC][0][8] = 24, + [0][0][2][0][RTW89_ACMA][1][8] = 66, + [0][0][2][0][RTW89_ACMA][0][8] = 28, + [0][0][2][0][RTW89_CHILE][1][8] = 22, + [0][0][2][0][RTW89_QATAR][1][8] = 66, + [0][0][2][0][RTW89_QATAR][0][8] = 28, + [0][0][2][0][RTW89_UK][1][8] = 66, + [0][0][2][0][RTW89_UK][0][8] = 28, + [0][0][2][0][RTW89_THAILAND][1][8] = 56, + [0][0][2][0][RTW89_THAILAND][0][8] = 22, + [0][0][2][0][RTW89_FCC][1][10] = 22, + [0][0][2][0][RTW89_ETSI][1][10] = 66, + [0][0][2][0][RTW89_ETSI][0][10] = 28, + [0][0][2][0][RTW89_MKK][1][10] = 66, + [0][0][2][0][RTW89_MKK][0][10] = 26, + [0][0][2][0][RTW89_IC][1][10] = 22, + [0][0][2][0][RTW89_KCC][1][10] = 24, + [0][0][2][0][RTW89_KCC][0][10] = 24, + [0][0][2][0][RTW89_ACMA][1][10] = 66, + [0][0][2][0][RTW89_ACMA][0][10] = 28, + [0][0][2][0][RTW89_CHILE][1][10] = 22, + [0][0][2][0][RTW89_QATAR][1][10] = 66, + [0][0][2][0][RTW89_QATAR][0][10] = 28, + [0][0][2][0][RTW89_UK][1][10] = 66, + [0][0][2][0][RTW89_UK][0][10] = 28, + [0][0][2][0][RTW89_THAILAND][1][10] = 56, + [0][0][2][0][RTW89_THAILAND][0][10] = 22, + [0][0][2][0][RTW89_FCC][1][12] = 22, + [0][0][2][0][RTW89_ETSI][1][12] = 66, + [0][0][2][0][RTW89_ETSI][0][12] = 28, + [0][0][2][0][RTW89_MKK][1][12] = 66, + [0][0][2][0][RTW89_MKK][0][12] = 26, + [0][0][2][0][RTW89_IC][1][12] = 22, + [0][0][2][0][RTW89_KCC][1][12] = 24, + [0][0][2][0][RTW89_KCC][0][12] = 24, + [0][0][2][0][RTW89_ACMA][1][12] = 66, + [0][0][2][0][RTW89_ACMA][0][12] = 28, + [0][0][2][0][RTW89_CHILE][1][12] = 22, + [0][0][2][0][RTW89_QATAR][1][12] = 66, + [0][0][2][0][RTW89_QATAR][0][12] = 28, + [0][0][2][0][RTW89_UK][1][12] = 66, + [0][0][2][0][RTW89_UK][0][12] = 28, + [0][0][2][0][RTW89_THAILAND][1][12] = 56, + [0][0][2][0][RTW89_THAILAND][0][12] = 22, + [0][0][2][0][RTW89_FCC][1][14] = 22, + [0][0][2][0][RTW89_ETSI][1][14] = 66, + [0][0][2][0][RTW89_ETSI][0][14] = 28, + [0][0][2][0][RTW89_MKK][1][14] = 66, + [0][0][2][0][RTW89_MKK][0][14] = 26, + [0][0][2][0][RTW89_IC][1][14] = 22, + [0][0][2][0][RTW89_KCC][1][14] = 24, + [0][0][2][0][RTW89_KCC][0][14] = 24, + [0][0][2][0][RTW89_ACMA][1][14] = 66, + [0][0][2][0][RTW89_ACMA][0][14] = 28, + [0][0][2][0][RTW89_CHILE][1][14] = 22, + [0][0][2][0][RTW89_QATAR][1][14] = 66, + [0][0][2][0][RTW89_QATAR][0][14] = 28, + [0][0][2][0][RTW89_UK][1][14] = 66, + [0][0][2][0][RTW89_UK][0][14] = 28, + [0][0][2][0][RTW89_THAILAND][1][14] = 56, + [0][0][2][0][RTW89_THAILAND][0][14] = 22, + [0][0][2][0][RTW89_FCC][1][15] = 22, + [0][0][2][0][RTW89_ETSI][1][15] = 66, + [0][0][2][0][RTW89_ETSI][0][15] = 28, + [0][0][2][0][RTW89_MKK][1][15] = 66, + [0][0][2][0][RTW89_MKK][0][15] = 26, + [0][0][2][0][RTW89_IC][1][15] = 22, + [0][0][2][0][RTW89_KCC][1][15] = 24, + [0][0][2][0][RTW89_KCC][0][15] = 24, + [0][0][2][0][RTW89_ACMA][1][15] = 66, + [0][0][2][0][RTW89_ACMA][0][15] = 28, + [0][0][2][0][RTW89_CHILE][1][15] = 22, + [0][0][2][0][RTW89_QATAR][1][15] = 66, + [0][0][2][0][RTW89_QATAR][0][15] = 28, + [0][0][2][0][RTW89_UK][1][15] = 66, + [0][0][2][0][RTW89_UK][0][15] = 28, + [0][0][2][0][RTW89_THAILAND][1][15] = 56, + [0][0][2][0][RTW89_THAILAND][0][15] = 22, + [0][0][2][0][RTW89_FCC][1][17] = 22, + [0][0][2][0][RTW89_ETSI][1][17] = 66, + [0][0][2][0][RTW89_ETSI][0][17] = 28, + [0][0][2][0][RTW89_MKK][1][17] = 66, + [0][0][2][0][RTW89_MKK][0][17] = 26, + [0][0][2][0][RTW89_IC][1][17] = 22, + [0][0][2][0][RTW89_KCC][1][17] = 24, + [0][0][2][0][RTW89_KCC][0][17] = 24, + [0][0][2][0][RTW89_ACMA][1][17] = 66, + [0][0][2][0][RTW89_ACMA][0][17] = 28, + [0][0][2][0][RTW89_CHILE][1][17] = 22, + [0][0][2][0][RTW89_QATAR][1][17] = 66, + [0][0][2][0][RTW89_QATAR][0][17] = 28, + [0][0][2][0][RTW89_UK][1][17] = 66, + [0][0][2][0][RTW89_UK][0][17] = 28, + [0][0][2][0][RTW89_THAILAND][1][17] = 56, + [0][0][2][0][RTW89_THAILAND][0][17] = 22, + [0][0][2][0][RTW89_FCC][1][19] = 22, + [0][0][2][0][RTW89_ETSI][1][19] = 66, + [0][0][2][0][RTW89_ETSI][0][19] = 28, + [0][0][2][0][RTW89_MKK][1][19] = 66, + [0][0][2][0][RTW89_MKK][0][19] = 26, + [0][0][2][0][RTW89_IC][1][19] = 22, + [0][0][2][0][RTW89_KCC][1][19] = 24, + [0][0][2][0][RTW89_KCC][0][19] = 24, + [0][0][2][0][RTW89_ACMA][1][19] = 66, + [0][0][2][0][RTW89_ACMA][0][19] = 28, + [0][0][2][0][RTW89_CHILE][1][19] = 22, + [0][0][2][0][RTW89_QATAR][1][19] = 66, + [0][0][2][0][RTW89_QATAR][0][19] = 28, + [0][0][2][0][RTW89_UK][1][19] = 66, + [0][0][2][0][RTW89_UK][0][19] = 28, + [0][0][2][0][RTW89_THAILAND][1][19] = 56, + [0][0][2][0][RTW89_THAILAND][0][19] = 22, + [0][0][2][0][RTW89_FCC][1][21] = 22, + [0][0][2][0][RTW89_ETSI][1][21] = 66, + [0][0][2][0][RTW89_ETSI][0][21] = 28, + [0][0][2][0][RTW89_MKK][1][21] = 66, + [0][0][2][0][RTW89_MKK][0][21] = 26, + [0][0][2][0][RTW89_IC][1][21] = 22, + [0][0][2][0][RTW89_KCC][1][21] = 24, + [0][0][2][0][RTW89_KCC][0][21] = 24, + [0][0][2][0][RTW89_ACMA][1][21] = 66, + [0][0][2][0][RTW89_ACMA][0][21] = 28, + [0][0][2][0][RTW89_CHILE][1][21] = 22, + [0][0][2][0][RTW89_QATAR][1][21] = 66, + [0][0][2][0][RTW89_QATAR][0][21] = 28, + [0][0][2][0][RTW89_UK][1][21] = 66, + [0][0][2][0][RTW89_UK][0][21] = 28, + [0][0][2][0][RTW89_THAILAND][1][21] = 56, + [0][0][2][0][RTW89_THAILAND][0][21] = 22, + [0][0][2][0][RTW89_FCC][1][23] = 22, + [0][0][2][0][RTW89_ETSI][1][23] = 66, + [0][0][2][0][RTW89_ETSI][0][23] = 28, + [0][0][2][0][RTW89_MKK][1][23] = 66, + [0][0][2][0][RTW89_MKK][0][23] = 26, + [0][0][2][0][RTW89_IC][1][23] = 22, + [0][0][2][0][RTW89_KCC][1][23] = 24, + [0][0][2][0][RTW89_KCC][0][23] = 26, + [0][0][2][0][RTW89_ACMA][1][23] = 66, + [0][0][2][0][RTW89_ACMA][0][23] = 28, + [0][0][2][0][RTW89_CHILE][1][23] = 22, + [0][0][2][0][RTW89_QATAR][1][23] = 66, + [0][0][2][0][RTW89_QATAR][0][23] = 28, + [0][0][2][0][RTW89_UK][1][23] = 66, + [0][0][2][0][RTW89_UK][0][23] = 28, + [0][0][2][0][RTW89_THAILAND][1][23] = 66, + [0][0][2][0][RTW89_THAILAND][0][23] = 22, + [0][0][2][0][RTW89_FCC][1][25] = 22, + [0][0][2][0][RTW89_ETSI][1][25] = 66, + [0][0][2][0][RTW89_ETSI][0][25] = 28, + [0][0][2][0][RTW89_MKK][1][25] = 66, + [0][0][2][0][RTW89_MKK][0][25] = 26, + [0][0][2][0][RTW89_IC][1][25] = 22, + [0][0][2][0][RTW89_KCC][1][25] = 24, + [0][0][2][0][RTW89_KCC][0][25] = 26, + [0][0][2][0][RTW89_ACMA][1][25] = 66, + [0][0][2][0][RTW89_ACMA][0][25] = 28, + [0][0][2][0][RTW89_CHILE][1][25] = 22, + [0][0][2][0][RTW89_QATAR][1][25] = 66, + [0][0][2][0][RTW89_QATAR][0][25] = 28, + [0][0][2][0][RTW89_UK][1][25] = 66, + [0][0][2][0][RTW89_UK][0][25] = 28, + [0][0][2][0][RTW89_THAILAND][1][25] = 66, + [0][0][2][0][RTW89_THAILAND][0][25] = 22, + [0][0][2][0][RTW89_FCC][1][27] = 22, + [0][0][2][0][RTW89_ETSI][1][27] = 66, + [0][0][2][0][RTW89_ETSI][0][27] = 28, + [0][0][2][0][RTW89_MKK][1][27] = 66, + [0][0][2][0][RTW89_MKK][0][27] = 26, + [0][0][2][0][RTW89_IC][1][27] = 22, + [0][0][2][0][RTW89_KCC][1][27] = 24, + [0][0][2][0][RTW89_KCC][0][27] = 26, + [0][0][2][0][RTW89_ACMA][1][27] = 66, + [0][0][2][0][RTW89_ACMA][0][27] = 28, + [0][0][2][0][RTW89_CHILE][1][27] = 22, + [0][0][2][0][RTW89_QATAR][1][27] = 66, + [0][0][2][0][RTW89_QATAR][0][27] = 28, + [0][0][2][0][RTW89_UK][1][27] = 66, + [0][0][2][0][RTW89_UK][0][27] = 28, + [0][0][2][0][RTW89_THAILAND][1][27] = 66, + [0][0][2][0][RTW89_THAILAND][0][27] = 22, + [0][0][2][0][RTW89_FCC][1][29] = 22, + [0][0][2][0][RTW89_ETSI][1][29] = 66, + [0][0][2][0][RTW89_ETSI][0][29] = 28, + [0][0][2][0][RTW89_MKK][1][29] = 66, + [0][0][2][0][RTW89_MKK][0][29] = 26, + [0][0][2][0][RTW89_IC][1][29] = 22, + [0][0][2][0][RTW89_KCC][1][29] = 24, + [0][0][2][0][RTW89_KCC][0][29] = 26, + [0][0][2][0][RTW89_ACMA][1][29] = 66, + [0][0][2][0][RTW89_ACMA][0][29] = 28, + [0][0][2][0][RTW89_CHILE][1][29] = 22, + [0][0][2][0][RTW89_QATAR][1][29] = 66, + [0][0][2][0][RTW89_QATAR][0][29] = 28, + [0][0][2][0][RTW89_UK][1][29] = 66, + [0][0][2][0][RTW89_UK][0][29] = 28, + [0][0][2][0][RTW89_THAILAND][1][29] = 66, + [0][0][2][0][RTW89_THAILAND][0][29] = 22, + [0][0][2][0][RTW89_FCC][1][30] = 22, + [0][0][2][0][RTW89_ETSI][1][30] = 66, + [0][0][2][0][RTW89_ETSI][0][30] = 28, + [0][0][2][0][RTW89_MKK][1][30] = 66, + [0][0][2][0][RTW89_MKK][0][30] = 26, + [0][0][2][0][RTW89_IC][1][30] = 22, + [0][0][2][0][RTW89_KCC][1][30] = 24, + [0][0][2][0][RTW89_KCC][0][30] = 26, + [0][0][2][0][RTW89_ACMA][1][30] = 66, + [0][0][2][0][RTW89_ACMA][0][30] = 28, + [0][0][2][0][RTW89_CHILE][1][30] = 22, + [0][0][2][0][RTW89_QATAR][1][30] = 66, + [0][0][2][0][RTW89_QATAR][0][30] = 28, + [0][0][2][0][RTW89_UK][1][30] = 66, + [0][0][2][0][RTW89_UK][0][30] = 28, + [0][0][2][0][RTW89_THAILAND][1][30] = 66, + [0][0][2][0][RTW89_THAILAND][0][30] = 22, + [0][0][2][0][RTW89_FCC][1][32] = 22, + [0][0][2][0][RTW89_ETSI][1][32] = 66, + [0][0][2][0][RTW89_ETSI][0][32] = 28, + [0][0][2][0][RTW89_MKK][1][32] = 66, + [0][0][2][0][RTW89_MKK][0][32] = 26, + [0][0][2][0][RTW89_IC][1][32] = 22, + [0][0][2][0][RTW89_KCC][1][32] = 24, + [0][0][2][0][RTW89_KCC][0][32] = 26, + [0][0][2][0][RTW89_ACMA][1][32] = 66, + [0][0][2][0][RTW89_ACMA][0][32] = 28, + [0][0][2][0][RTW89_CHILE][1][32] = 22, + [0][0][2][0][RTW89_QATAR][1][32] = 66, + [0][0][2][0][RTW89_QATAR][0][32] = 28, + [0][0][2][0][RTW89_UK][1][32] = 66, + [0][0][2][0][RTW89_UK][0][32] = 28, + [0][0][2][0][RTW89_THAILAND][1][32] = 66, + [0][0][2][0][RTW89_THAILAND][0][32] = 22, + [0][0][2][0][RTW89_FCC][1][34] = 22, + [0][0][2][0][RTW89_ETSI][1][34] = 66, + [0][0][2][0][RTW89_ETSI][0][34] = 28, + [0][0][2][0][RTW89_MKK][1][34] = 66, + [0][0][2][0][RTW89_MKK][0][34] = 26, + [0][0][2][0][RTW89_IC][1][34] = 22, + [0][0][2][0][RTW89_KCC][1][34] = 24, + [0][0][2][0][RTW89_KCC][0][34] = 26, + [0][0][2][0][RTW89_ACMA][1][34] = 66, + [0][0][2][0][RTW89_ACMA][0][34] = 28, + [0][0][2][0][RTW89_CHILE][1][34] = 22, + [0][0][2][0][RTW89_QATAR][1][34] = 66, + [0][0][2][0][RTW89_QATAR][0][34] = 28, + [0][0][2][0][RTW89_UK][1][34] = 66, + [0][0][2][0][RTW89_UK][0][34] = 28, + [0][0][2][0][RTW89_THAILAND][1][34] = 66, + [0][0][2][0][RTW89_THAILAND][0][34] = 22, + [0][0][2][0][RTW89_FCC][1][36] = 22, + [0][0][2][0][RTW89_ETSI][1][36] = 66, + [0][0][2][0][RTW89_ETSI][0][36] = 28, + [0][0][2][0][RTW89_MKK][1][36] = 66, + [0][0][2][0][RTW89_MKK][0][36] = 26, + [0][0][2][0][RTW89_IC][1][36] = 22, + [0][0][2][0][RTW89_KCC][1][36] = 24, + [0][0][2][0][RTW89_KCC][0][36] = 26, + [0][0][2][0][RTW89_ACMA][1][36] = 66, + [0][0][2][0][RTW89_ACMA][0][36] = 28, + [0][0][2][0][RTW89_CHILE][1][36] = 22, + [0][0][2][0][RTW89_QATAR][1][36] = 66, + [0][0][2][0][RTW89_QATAR][0][36] = 28, + [0][0][2][0][RTW89_UK][1][36] = 66, + [0][0][2][0][RTW89_UK][0][36] = 28, + [0][0][2][0][RTW89_THAILAND][1][36] = 66, + [0][0][2][0][RTW89_THAILAND][0][36] = 22, + [0][0][2][0][RTW89_FCC][1][38] = 22, + [0][0][2][0][RTW89_ETSI][1][38] = 66, + [0][0][2][0][RTW89_ETSI][0][38] = 28, + [0][0][2][0][RTW89_MKK][1][38] = 66, + [0][0][2][0][RTW89_MKK][0][38] = 26, + [0][0][2][0][RTW89_IC][1][38] = 22, + [0][0][2][0][RTW89_KCC][1][38] = 24, + [0][0][2][0][RTW89_KCC][0][38] = 26, + [0][0][2][0][RTW89_ACMA][1][38] = 66, + [0][0][2][0][RTW89_ACMA][0][38] = 28, + [0][0][2][0][RTW89_CHILE][1][38] = 22, + [0][0][2][0][RTW89_QATAR][1][38] = 66, + [0][0][2][0][RTW89_QATAR][0][38] = 28, + [0][0][2][0][RTW89_UK][1][38] = 66, + [0][0][2][0][RTW89_UK][0][38] = 28, + [0][0][2][0][RTW89_THAILAND][1][38] = 66, + [0][0][2][0][RTW89_THAILAND][0][38] = 22, + [0][0][2][0][RTW89_FCC][1][40] = 22, + [0][0][2][0][RTW89_ETSI][1][40] = 66, + [0][0][2][0][RTW89_ETSI][0][40] = 28, + [0][0][2][0][RTW89_MKK][1][40] = 66, + [0][0][2][0][RTW89_MKK][0][40] = 26, + [0][0][2][0][RTW89_IC][1][40] = 22, + [0][0][2][0][RTW89_KCC][1][40] = 24, + [0][0][2][0][RTW89_KCC][0][40] = 26, + [0][0][2][0][RTW89_ACMA][1][40] = 66, + [0][0][2][0][RTW89_ACMA][0][40] = 28, + [0][0][2][0][RTW89_CHILE][1][40] = 22, + [0][0][2][0][RTW89_QATAR][1][40] = 66, + [0][0][2][0][RTW89_QATAR][0][40] = 28, + [0][0][2][0][RTW89_UK][1][40] = 66, + [0][0][2][0][RTW89_UK][0][40] = 28, + [0][0][2][0][RTW89_THAILAND][1][40] = 66, + [0][0][2][0][RTW89_THAILAND][0][40] = 22, + [0][0][2][0][RTW89_FCC][1][42] = 22, + [0][0][2][0][RTW89_ETSI][1][42] = 66, + [0][0][2][0][RTW89_ETSI][0][42] = 28, + [0][0][2][0][RTW89_MKK][1][42] = 66, + [0][0][2][0][RTW89_MKK][0][42] = 26, + [0][0][2][0][RTW89_IC][1][42] = 22, + [0][0][2][0][RTW89_KCC][1][42] = 24, + [0][0][2][0][RTW89_KCC][0][42] = 26, + [0][0][2][0][RTW89_ACMA][1][42] = 66, + [0][0][2][0][RTW89_ACMA][0][42] = 28, + [0][0][2][0][RTW89_CHILE][1][42] = 22, + [0][0][2][0][RTW89_QATAR][1][42] = 66, + [0][0][2][0][RTW89_QATAR][0][42] = 28, + [0][0][2][0][RTW89_UK][1][42] = 66, + [0][0][2][0][RTW89_UK][0][42] = 28, + [0][0][2][0][RTW89_THAILAND][1][42] = 66, + [0][0][2][0][RTW89_THAILAND][0][42] = 22, + [0][0][2][0][RTW89_FCC][1][44] = 22, + [0][0][2][0][RTW89_ETSI][1][44] = 66, + [0][0][2][0][RTW89_ETSI][0][44] = 30, + [0][0][2][0][RTW89_MKK][1][44] = 44, + [0][0][2][0][RTW89_MKK][0][44] = 28, + [0][0][2][0][RTW89_IC][1][44] = 22, + [0][0][2][0][RTW89_KCC][1][44] = 24, + [0][0][2][0][RTW89_KCC][0][44] = 26, + [0][0][2][0][RTW89_ACMA][1][44] = 66, + [0][0][2][0][RTW89_ACMA][0][44] = 30, + [0][0][2][0][RTW89_CHILE][1][44] = 22, + [0][0][2][0][RTW89_QATAR][1][44] = 66, + [0][0][2][0][RTW89_QATAR][0][44] = 30, + [0][0][2][0][RTW89_UK][1][44] = 66, + [0][0][2][0][RTW89_UK][0][44] = 30, + [0][0][2][0][RTW89_THAILAND][1][44] = 68, + [0][0][2][0][RTW89_THAILAND][0][44] = 22, + [0][0][2][0][RTW89_FCC][1][45] = 22, + [0][0][2][0][RTW89_ETSI][1][45] = 127, + [0][0][2][0][RTW89_ETSI][0][45] = 127, + [0][0][2][0][RTW89_MKK][1][45] = 127, + [0][0][2][0][RTW89_MKK][0][45] = 127, + [0][0][2][0][RTW89_IC][1][45] = 22, + [0][0][2][0][RTW89_KCC][1][45] = 24, + [0][0][2][0][RTW89_KCC][0][45] = 127, + [0][0][2][0][RTW89_ACMA][1][45] = 127, + [0][0][2][0][RTW89_ACMA][0][45] = 127, + [0][0][2][0][RTW89_CHILE][1][45] = 22, + [0][0][2][0][RTW89_QATAR][1][45] = 127, + [0][0][2][0][RTW89_QATAR][0][45] = 127, + [0][0][2][0][RTW89_UK][1][45] = 127, + [0][0][2][0][RTW89_UK][0][45] = 127, + [0][0][2][0][RTW89_THAILAND][1][45] = 127, + [0][0][2][0][RTW89_THAILAND][0][45] = 127, + [0][0][2][0][RTW89_FCC][1][47] = 22, + [0][0][2][0][RTW89_ETSI][1][47] = 127, + [0][0][2][0][RTW89_ETSI][0][47] = 127, + [0][0][2][0][RTW89_MKK][1][47] = 127, + [0][0][2][0][RTW89_MKK][0][47] = 127, + [0][0][2][0][RTW89_IC][1][47] = 22, + [0][0][2][0][RTW89_KCC][1][47] = 24, + [0][0][2][0][RTW89_KCC][0][47] = 127, + [0][0][2][0][RTW89_ACMA][1][47] = 127, + [0][0][2][0][RTW89_ACMA][0][47] = 127, + [0][0][2][0][RTW89_CHILE][1][47] = 22, + [0][0][2][0][RTW89_QATAR][1][47] = 127, + [0][0][2][0][RTW89_QATAR][0][47] = 127, + [0][0][2][0][RTW89_UK][1][47] = 127, + [0][0][2][0][RTW89_UK][0][47] = 127, + [0][0][2][0][RTW89_THAILAND][1][47] = 127, + [0][0][2][0][RTW89_THAILAND][0][47] = 127, + [0][0][2][0][RTW89_FCC][1][49] = 24, + [0][0][2][0][RTW89_ETSI][1][49] = 127, + [0][0][2][0][RTW89_ETSI][0][49] = 127, + [0][0][2][0][RTW89_MKK][1][49] = 127, + [0][0][2][0][RTW89_MKK][0][49] = 127, + [0][0][2][0][RTW89_IC][1][49] = 24, + [0][0][2][0][RTW89_KCC][1][49] = 24, + [0][0][2][0][RTW89_KCC][0][49] = 127, + [0][0][2][0][RTW89_ACMA][1][49] = 127, + [0][0][2][0][RTW89_ACMA][0][49] = 127, + [0][0][2][0][RTW89_CHILE][1][49] = 24, + [0][0][2][0][RTW89_QATAR][1][49] = 127, + [0][0][2][0][RTW89_QATAR][0][49] = 127, + [0][0][2][0][RTW89_UK][1][49] = 127, + [0][0][2][0][RTW89_UK][0][49] = 127, + [0][0][2][0][RTW89_THAILAND][1][49] = 127, + [0][0][2][0][RTW89_THAILAND][0][49] = 127, + [0][0][2][0][RTW89_FCC][1][51] = 22, + [0][0][2][0][RTW89_ETSI][1][51] = 127, + [0][0][2][0][RTW89_ETSI][0][51] = 127, + [0][0][2][0][RTW89_MKK][1][51] = 127, + [0][0][2][0][RTW89_MKK][0][51] = 127, + [0][0][2][0][RTW89_IC][1][51] = 22, + [0][0][2][0][RTW89_KCC][1][51] = 24, + [0][0][2][0][RTW89_KCC][0][51] = 127, + [0][0][2][0][RTW89_ACMA][1][51] = 127, + [0][0][2][0][RTW89_ACMA][0][51] = 127, + [0][0][2][0][RTW89_CHILE][1][51] = 22, + [0][0][2][0][RTW89_QATAR][1][51] = 127, + [0][0][2][0][RTW89_QATAR][0][51] = 127, + [0][0][2][0][RTW89_UK][1][51] = 127, + [0][0][2][0][RTW89_UK][0][51] = 127, + [0][0][2][0][RTW89_THAILAND][1][51] = 127, + [0][0][2][0][RTW89_THAILAND][0][51] = 127, + [0][0][2][0][RTW89_FCC][1][53] = 22, + [0][0][2][0][RTW89_ETSI][1][53] = 127, + [0][0][2][0][RTW89_ETSI][0][53] = 127, + [0][0][2][0][RTW89_MKK][1][53] = 127, + [0][0][2][0][RTW89_MKK][0][53] = 127, + [0][0][2][0][RTW89_IC][1][53] = 22, + [0][0][2][0][RTW89_KCC][1][53] = 24, + [0][0][2][0][RTW89_KCC][0][53] = 127, + [0][0][2][0][RTW89_ACMA][1][53] = 127, + [0][0][2][0][RTW89_ACMA][0][53] = 127, + [0][0][2][0][RTW89_CHILE][1][53] = 22, + [0][0][2][0][RTW89_QATAR][1][53] = 127, + [0][0][2][0][RTW89_QATAR][0][53] = 127, + [0][0][2][0][RTW89_UK][1][53] = 127, + [0][0][2][0][RTW89_UK][0][53] = 127, + [0][0][2][0][RTW89_THAILAND][1][53] = 127, + [0][0][2][0][RTW89_THAILAND][0][53] = 127, + [0][0][2][0][RTW89_FCC][1][55] = 22, + [0][0][2][0][RTW89_ETSI][1][55] = 127, + [0][0][2][0][RTW89_ETSI][0][55] = 127, + [0][0][2][0][RTW89_MKK][1][55] = 127, + [0][0][2][0][RTW89_MKK][0][55] = 127, + [0][0][2][0][RTW89_IC][1][55] = 22, + [0][0][2][0][RTW89_KCC][1][55] = 26, + [0][0][2][0][RTW89_KCC][0][55] = 127, + [0][0][2][0][RTW89_ACMA][1][55] = 127, + [0][0][2][0][RTW89_ACMA][0][55] = 127, + [0][0][2][0][RTW89_CHILE][1][55] = 22, + [0][0][2][0][RTW89_QATAR][1][55] = 127, + [0][0][2][0][RTW89_QATAR][0][55] = 127, + [0][0][2][0][RTW89_UK][1][55] = 127, + [0][0][2][0][RTW89_UK][0][55] = 127, + [0][0][2][0][RTW89_THAILAND][1][55] = 127, + [0][0][2][0][RTW89_THAILAND][0][55] = 127, + [0][0][2][0][RTW89_FCC][1][57] = 22, + [0][0][2][0][RTW89_ETSI][1][57] = 127, + [0][0][2][0][RTW89_ETSI][0][57] = 127, + [0][0][2][0][RTW89_MKK][1][57] = 127, + [0][0][2][0][RTW89_MKK][0][57] = 127, + [0][0][2][0][RTW89_IC][1][57] = 22, + [0][0][2][0][RTW89_KCC][1][57] = 26, + [0][0][2][0][RTW89_KCC][0][57] = 127, + [0][0][2][0][RTW89_ACMA][1][57] = 127, + [0][0][2][0][RTW89_ACMA][0][57] = 127, + [0][0][2][0][RTW89_CHILE][1][57] = 22, + [0][0][2][0][RTW89_QATAR][1][57] = 127, + [0][0][2][0][RTW89_QATAR][0][57] = 127, + [0][0][2][0][RTW89_UK][1][57] = 127, + [0][0][2][0][RTW89_UK][0][57] = 127, + [0][0][2][0][RTW89_THAILAND][1][57] = 127, + [0][0][2][0][RTW89_THAILAND][0][57] = 127, + [0][0][2][0][RTW89_FCC][1][59] = 22, + [0][0][2][0][RTW89_ETSI][1][59] = 127, + [0][0][2][0][RTW89_ETSI][0][59] = 127, + [0][0][2][0][RTW89_MKK][1][59] = 127, + [0][0][2][0][RTW89_MKK][0][59] = 127, + [0][0][2][0][RTW89_IC][1][59] = 22, + [0][0][2][0][RTW89_KCC][1][59] = 26, + [0][0][2][0][RTW89_KCC][0][59] = 127, + [0][0][2][0][RTW89_ACMA][1][59] = 127, + [0][0][2][0][RTW89_ACMA][0][59] = 127, + [0][0][2][0][RTW89_CHILE][1][59] = 22, + [0][0][2][0][RTW89_QATAR][1][59] = 127, + [0][0][2][0][RTW89_QATAR][0][59] = 127, + [0][0][2][0][RTW89_UK][1][59] = 127, + [0][0][2][0][RTW89_UK][0][59] = 127, + [0][0][2][0][RTW89_THAILAND][1][59] = 127, + [0][0][2][0][RTW89_THAILAND][0][59] = 127, + [0][0][2][0][RTW89_FCC][1][60] = 22, + [0][0][2][0][RTW89_ETSI][1][60] = 127, + [0][0][2][0][RTW89_ETSI][0][60] = 127, + [0][0][2][0][RTW89_MKK][1][60] = 127, + [0][0][2][0][RTW89_MKK][0][60] = 127, + [0][0][2][0][RTW89_IC][1][60] = 22, + [0][0][2][0][RTW89_KCC][1][60] = 26, + [0][0][2][0][RTW89_KCC][0][60] = 127, + [0][0][2][0][RTW89_ACMA][1][60] = 127, + [0][0][2][0][RTW89_ACMA][0][60] = 127, + [0][0][2][0][RTW89_CHILE][1][60] = 22, + [0][0][2][0][RTW89_QATAR][1][60] = 127, + [0][0][2][0][RTW89_QATAR][0][60] = 127, + [0][0][2][0][RTW89_UK][1][60] = 127, + [0][0][2][0][RTW89_UK][0][60] = 127, + [0][0][2][0][RTW89_THAILAND][1][60] = 127, + [0][0][2][0][RTW89_THAILAND][0][60] = 127, + [0][0][2][0][RTW89_FCC][1][62] = 22, + [0][0][2][0][RTW89_ETSI][1][62] = 127, + [0][0][2][0][RTW89_ETSI][0][62] = 127, + [0][0][2][0][RTW89_MKK][1][62] = 127, + [0][0][2][0][RTW89_MKK][0][62] = 127, + [0][0][2][0][RTW89_IC][1][62] = 22, + [0][0][2][0][RTW89_KCC][1][62] = 26, + [0][0][2][0][RTW89_KCC][0][62] = 127, + [0][0][2][0][RTW89_ACMA][1][62] = 127, + [0][0][2][0][RTW89_ACMA][0][62] = 127, + [0][0][2][0][RTW89_CHILE][1][62] = 22, + [0][0][2][0][RTW89_QATAR][1][62] = 127, + [0][0][2][0][RTW89_QATAR][0][62] = 127, + [0][0][2][0][RTW89_UK][1][62] = 127, + [0][0][2][0][RTW89_UK][0][62] = 127, + [0][0][2][0][RTW89_THAILAND][1][62] = 127, + [0][0][2][0][RTW89_THAILAND][0][62] = 127, + [0][0][2][0][RTW89_FCC][1][64] = 22, + [0][0][2][0][RTW89_ETSI][1][64] = 127, + [0][0][2][0][RTW89_ETSI][0][64] = 127, + [0][0][2][0][RTW89_MKK][1][64] = 127, + [0][0][2][0][RTW89_MKK][0][64] = 127, + [0][0][2][0][RTW89_IC][1][64] = 22, + [0][0][2][0][RTW89_KCC][1][64] = 26, + [0][0][2][0][RTW89_KCC][0][64] = 127, + [0][0][2][0][RTW89_ACMA][1][64] = 127, + [0][0][2][0][RTW89_ACMA][0][64] = 127, + [0][0][2][0][RTW89_CHILE][1][64] = 22, + [0][0][2][0][RTW89_QATAR][1][64] = 127, + [0][0][2][0][RTW89_QATAR][0][64] = 127, + [0][0][2][0][RTW89_UK][1][64] = 127, + [0][0][2][0][RTW89_UK][0][64] = 127, + [0][0][2][0][RTW89_THAILAND][1][64] = 127, + [0][0][2][0][RTW89_THAILAND][0][64] = 127, + [0][0][2][0][RTW89_FCC][1][66] = 22, + [0][0][2][0][RTW89_ETSI][1][66] = 127, + [0][0][2][0][RTW89_ETSI][0][66] = 127, + [0][0][2][0][RTW89_MKK][1][66] = 127, + [0][0][2][0][RTW89_MKK][0][66] = 127, + [0][0][2][0][RTW89_IC][1][66] = 22, + [0][0][2][0][RTW89_KCC][1][66] = 26, + [0][0][2][0][RTW89_KCC][0][66] = 127, + [0][0][2][0][RTW89_ACMA][1][66] = 127, + [0][0][2][0][RTW89_ACMA][0][66] = 127, + [0][0][2][0][RTW89_CHILE][1][66] = 22, + [0][0][2][0][RTW89_QATAR][1][66] = 127, + [0][0][2][0][RTW89_QATAR][0][66] = 127, + [0][0][2][0][RTW89_UK][1][66] = 127, + [0][0][2][0][RTW89_UK][0][66] = 127, + [0][0][2][0][RTW89_THAILAND][1][66] = 127, + [0][0][2][0][RTW89_THAILAND][0][66] = 127, + [0][0][2][0][RTW89_FCC][1][68] = 22, + [0][0][2][0][RTW89_ETSI][1][68] = 127, + [0][0][2][0][RTW89_ETSI][0][68] = 127, + [0][0][2][0][RTW89_MKK][1][68] = 127, + [0][0][2][0][RTW89_MKK][0][68] = 127, + [0][0][2][0][RTW89_IC][1][68] = 22, + [0][0][2][0][RTW89_KCC][1][68] = 26, + [0][0][2][0][RTW89_KCC][0][68] = 127, + [0][0][2][0][RTW89_ACMA][1][68] = 127, + [0][0][2][0][RTW89_ACMA][0][68] = 127, + [0][0][2][0][RTW89_CHILE][1][68] = 22, + [0][0][2][0][RTW89_QATAR][1][68] = 127, + [0][0][2][0][RTW89_QATAR][0][68] = 127, + [0][0][2][0][RTW89_UK][1][68] = 127, + [0][0][2][0][RTW89_UK][0][68] = 127, + [0][0][2][0][RTW89_THAILAND][1][68] = 127, + [0][0][2][0][RTW89_THAILAND][0][68] = 127, + [0][0][2][0][RTW89_FCC][1][70] = 24, + [0][0][2][0][RTW89_ETSI][1][70] = 127, + [0][0][2][0][RTW89_ETSI][0][70] = 127, + [0][0][2][0][RTW89_MKK][1][70] = 127, + [0][0][2][0][RTW89_MKK][0][70] = 127, + [0][0][2][0][RTW89_IC][1][70] = 24, + [0][0][2][0][RTW89_KCC][1][70] = 26, + [0][0][2][0][RTW89_KCC][0][70] = 127, + [0][0][2][0][RTW89_ACMA][1][70] = 127, + [0][0][2][0][RTW89_ACMA][0][70] = 127, + [0][0][2][0][RTW89_CHILE][1][70] = 24, + [0][0][2][0][RTW89_QATAR][1][70] = 127, + [0][0][2][0][RTW89_QATAR][0][70] = 127, + [0][0][2][0][RTW89_UK][1][70] = 127, + [0][0][2][0][RTW89_UK][0][70] = 127, + [0][0][2][0][RTW89_THAILAND][1][70] = 127, + [0][0][2][0][RTW89_THAILAND][0][70] = 127, + [0][0][2][0][RTW89_FCC][1][72] = 22, + [0][0][2][0][RTW89_ETSI][1][72] = 127, + [0][0][2][0][RTW89_ETSI][0][72] = 127, + [0][0][2][0][RTW89_MKK][1][72] = 127, + [0][0][2][0][RTW89_MKK][0][72] = 127, + [0][0][2][0][RTW89_IC][1][72] = 22, + [0][0][2][0][RTW89_KCC][1][72] = 26, + [0][0][2][0][RTW89_KCC][0][72] = 127, + [0][0][2][0][RTW89_ACMA][1][72] = 127, + [0][0][2][0][RTW89_ACMA][0][72] = 127, + [0][0][2][0][RTW89_CHILE][1][72] = 22, + [0][0][2][0][RTW89_QATAR][1][72] = 127, + [0][0][2][0][RTW89_QATAR][0][72] = 127, + [0][0][2][0][RTW89_UK][1][72] = 127, + [0][0][2][0][RTW89_UK][0][72] = 127, + [0][0][2][0][RTW89_THAILAND][1][72] = 127, + [0][0][2][0][RTW89_THAILAND][0][72] = 127, + [0][0][2][0][RTW89_FCC][1][74] = 22, + [0][0][2][0][RTW89_ETSI][1][74] = 127, + [0][0][2][0][RTW89_ETSI][0][74] = 127, + [0][0][2][0][RTW89_MKK][1][74] = 127, + [0][0][2][0][RTW89_MKK][0][74] = 127, + [0][0][2][0][RTW89_IC][1][74] = 22, + [0][0][2][0][RTW89_KCC][1][74] = 26, + [0][0][2][0][RTW89_KCC][0][74] = 127, + [0][0][2][0][RTW89_ACMA][1][74] = 127, + [0][0][2][0][RTW89_ACMA][0][74] = 127, + [0][0][2][0][RTW89_CHILE][1][74] = 22, + [0][0][2][0][RTW89_QATAR][1][74] = 127, + [0][0][2][0][RTW89_QATAR][0][74] = 127, + [0][0][2][0][RTW89_UK][1][74] = 127, + [0][0][2][0][RTW89_UK][0][74] = 127, + [0][0][2][0][RTW89_THAILAND][1][74] = 127, + [0][0][2][0][RTW89_THAILAND][0][74] = 127, + [0][0][2][0][RTW89_FCC][1][75] = 22, + [0][0][2][0][RTW89_ETSI][1][75] = 127, + [0][0][2][0][RTW89_ETSI][0][75] = 127, + [0][0][2][0][RTW89_MKK][1][75] = 127, + [0][0][2][0][RTW89_MKK][0][75] = 127, + [0][0][2][0][RTW89_IC][1][75] = 22, + [0][0][2][0][RTW89_KCC][1][75] = 26, + [0][0][2][0][RTW89_KCC][0][75] = 127, + [0][0][2][0][RTW89_ACMA][1][75] = 127, + [0][0][2][0][RTW89_ACMA][0][75] = 127, + [0][0][2][0][RTW89_CHILE][1][75] = 22, + [0][0][2][0][RTW89_QATAR][1][75] = 127, + [0][0][2][0][RTW89_QATAR][0][75] = 127, + [0][0][2][0][RTW89_UK][1][75] = 127, + [0][0][2][0][RTW89_UK][0][75] = 127, + [0][0][2][0][RTW89_THAILAND][1][75] = 127, + [0][0][2][0][RTW89_THAILAND][0][75] = 127, + [0][0][2][0][RTW89_FCC][1][77] = 22, + [0][0][2][0][RTW89_ETSI][1][77] = 127, + [0][0][2][0][RTW89_ETSI][0][77] = 127, + [0][0][2][0][RTW89_MKK][1][77] = 127, + [0][0][2][0][RTW89_MKK][0][77] = 127, + [0][0][2][0][RTW89_IC][1][77] = 22, + [0][0][2][0][RTW89_KCC][1][77] = 26, + [0][0][2][0][RTW89_KCC][0][77] = 127, + [0][0][2][0][RTW89_ACMA][1][77] = 127, + [0][0][2][0][RTW89_ACMA][0][77] = 127, + [0][0][2][0][RTW89_CHILE][1][77] = 22, + [0][0][2][0][RTW89_QATAR][1][77] = 127, + [0][0][2][0][RTW89_QATAR][0][77] = 127, + [0][0][2][0][RTW89_UK][1][77] = 127, + [0][0][2][0][RTW89_UK][0][77] = 127, + [0][0][2][0][RTW89_THAILAND][1][77] = 127, + [0][0][2][0][RTW89_THAILAND][0][77] = 127, + [0][0][2][0][RTW89_FCC][1][79] = 22, + [0][0][2][0][RTW89_ETSI][1][79] = 127, + [0][0][2][0][RTW89_ETSI][0][79] = 127, + [0][0][2][0][RTW89_MKK][1][79] = 127, + [0][0][2][0][RTW89_MKK][0][79] = 127, + [0][0][2][0][RTW89_IC][1][79] = 22, + [0][0][2][0][RTW89_KCC][1][79] = 26, + [0][0][2][0][RTW89_KCC][0][79] = 127, + [0][0][2][0][RTW89_ACMA][1][79] = 127, + [0][0][2][0][RTW89_ACMA][0][79] = 127, + [0][0][2][0][RTW89_CHILE][1][79] = 22, + [0][0][2][0][RTW89_QATAR][1][79] = 127, + [0][0][2][0][RTW89_QATAR][0][79] = 127, + [0][0][2][0][RTW89_UK][1][79] = 127, + [0][0][2][0][RTW89_UK][0][79] = 127, + [0][0][2][0][RTW89_THAILAND][1][79] = 127, + [0][0][2][0][RTW89_THAILAND][0][79] = 127, + [0][0][2][0][RTW89_FCC][1][81] = 22, + [0][0][2][0][RTW89_ETSI][1][81] = 127, + [0][0][2][0][RTW89_ETSI][0][81] = 127, + [0][0][2][0][RTW89_MKK][1][81] = 127, + [0][0][2][0][RTW89_MKK][0][81] = 127, + [0][0][2][0][RTW89_IC][1][81] = 22, + [0][0][2][0][RTW89_KCC][1][81] = 26, + [0][0][2][0][RTW89_KCC][0][81] = 127, + [0][0][2][0][RTW89_ACMA][1][81] = 127, + [0][0][2][0][RTW89_ACMA][0][81] = 127, + [0][0][2][0][RTW89_CHILE][1][81] = 22, + [0][0][2][0][RTW89_QATAR][1][81] = 127, + [0][0][2][0][RTW89_QATAR][0][81] = 127, + [0][0][2][0][RTW89_UK][1][81] = 127, + [0][0][2][0][RTW89_UK][0][81] = 127, + [0][0][2][0][RTW89_THAILAND][1][81] = 127, + [0][0][2][0][RTW89_THAILAND][0][81] = 127, + [0][0][2][0][RTW89_FCC][1][83] = 22, + [0][0][2][0][RTW89_ETSI][1][83] = 127, + [0][0][2][0][RTW89_ETSI][0][83] = 127, + [0][0][2][0][RTW89_MKK][1][83] = 127, + [0][0][2][0][RTW89_MKK][0][83] = 127, + [0][0][2][0][RTW89_IC][1][83] = 22, + [0][0][2][0][RTW89_KCC][1][83] = 32, + [0][0][2][0][RTW89_KCC][0][83] = 127, + [0][0][2][0][RTW89_ACMA][1][83] = 127, + [0][0][2][0][RTW89_ACMA][0][83] = 127, + [0][0][2][0][RTW89_CHILE][1][83] = 22, + [0][0][2][0][RTW89_QATAR][1][83] = 127, + [0][0][2][0][RTW89_QATAR][0][83] = 127, + [0][0][2][0][RTW89_UK][1][83] = 127, + [0][0][2][0][RTW89_UK][0][83] = 127, + [0][0][2][0][RTW89_THAILAND][1][83] = 127, + [0][0][2][0][RTW89_THAILAND][0][83] = 127, + [0][0][2][0][RTW89_FCC][1][85] = 22, + [0][0][2][0][RTW89_ETSI][1][85] = 127, + [0][0][2][0][RTW89_ETSI][0][85] = 127, + [0][0][2][0][RTW89_MKK][1][85] = 127, + [0][0][2][0][RTW89_MKK][0][85] = 127, + [0][0][2][0][RTW89_IC][1][85] = 22, + [0][0][2][0][RTW89_KCC][1][85] = 32, + [0][0][2][0][RTW89_KCC][0][85] = 127, + [0][0][2][0][RTW89_ACMA][1][85] = 127, + [0][0][2][0][RTW89_ACMA][0][85] = 127, + [0][0][2][0][RTW89_CHILE][1][85] = 22, + [0][0][2][0][RTW89_QATAR][1][85] = 127, + [0][0][2][0][RTW89_QATAR][0][85] = 127, + [0][0][2][0][RTW89_UK][1][85] = 127, + [0][0][2][0][RTW89_UK][0][85] = 127, + [0][0][2][0][RTW89_THAILAND][1][85] = 127, + [0][0][2][0][RTW89_THAILAND][0][85] = 127, + [0][0][2][0][RTW89_FCC][1][87] = 22, + [0][0][2][0][RTW89_ETSI][1][87] = 127, + [0][0][2][0][RTW89_ETSI][0][87] = 127, + [0][0][2][0][RTW89_MKK][1][87] = 127, + [0][0][2][0][RTW89_MKK][0][87] = 127, + [0][0][2][0][RTW89_IC][1][87] = 22, + [0][0][2][0][RTW89_KCC][1][87] = 32, + [0][0][2][0][RTW89_KCC][0][87] = 127, + [0][0][2][0][RTW89_ACMA][1][87] = 127, + [0][0][2][0][RTW89_ACMA][0][87] = 127, + [0][0][2][0][RTW89_CHILE][1][87] = 22, + [0][0][2][0][RTW89_QATAR][1][87] = 127, + [0][0][2][0][RTW89_QATAR][0][87] = 127, + [0][0][2][0][RTW89_UK][1][87] = 127, + [0][0][2][0][RTW89_UK][0][87] = 127, + [0][0][2][0][RTW89_THAILAND][1][87] = 127, + [0][0][2][0][RTW89_THAILAND][0][87] = 127, + [0][0][2][0][RTW89_FCC][1][89] = 22, + [0][0][2][0][RTW89_ETSI][1][89] = 127, + [0][0][2][0][RTW89_ETSI][0][89] = 127, + [0][0][2][0][RTW89_MKK][1][89] = 127, + [0][0][2][0][RTW89_MKK][0][89] = 127, + [0][0][2][0][RTW89_IC][1][89] = 22, + [0][0][2][0][RTW89_KCC][1][89] = 32, + [0][0][2][0][RTW89_KCC][0][89] = 127, + [0][0][2][0][RTW89_ACMA][1][89] = 127, + [0][0][2][0][RTW89_ACMA][0][89] = 127, + [0][0][2][0][RTW89_CHILE][1][89] = 22, + [0][0][2][0][RTW89_QATAR][1][89] = 127, + [0][0][2][0][RTW89_QATAR][0][89] = 127, + [0][0][2][0][RTW89_UK][1][89] = 127, + [0][0][2][0][RTW89_UK][0][89] = 127, + [0][0][2][0][RTW89_THAILAND][1][89] = 127, + [0][0][2][0][RTW89_THAILAND][0][89] = 127, + [0][0][2][0][RTW89_FCC][1][90] = 22, + [0][0][2][0][RTW89_ETSI][1][90] = 127, + [0][0][2][0][RTW89_ETSI][0][90] = 127, + [0][0][2][0][RTW89_MKK][1][90] = 127, + [0][0][2][0][RTW89_MKK][0][90] = 127, + [0][0][2][0][RTW89_IC][1][90] = 22, + [0][0][2][0][RTW89_KCC][1][90] = 32, + [0][0][2][0][RTW89_KCC][0][90] = 127, + [0][0][2][0][RTW89_ACMA][1][90] = 127, + [0][0][2][0][RTW89_ACMA][0][90] = 127, + [0][0][2][0][RTW89_CHILE][1][90] = 22, + [0][0][2][0][RTW89_QATAR][1][90] = 127, + [0][0][2][0][RTW89_QATAR][0][90] = 127, + [0][0][2][0][RTW89_UK][1][90] = 127, + [0][0][2][0][RTW89_UK][0][90] = 127, + [0][0][2][0][RTW89_THAILAND][1][90] = 127, + [0][0][2][0][RTW89_THAILAND][0][90] = 127, + [0][0][2][0][RTW89_FCC][1][92] = 22, + [0][0][2][0][RTW89_ETSI][1][92] = 127, + [0][0][2][0][RTW89_ETSI][0][92] = 127, + [0][0][2][0][RTW89_MKK][1][92] = 127, + [0][0][2][0][RTW89_MKK][0][92] = 127, + [0][0][2][0][RTW89_IC][1][92] = 22, + [0][0][2][0][RTW89_KCC][1][92] = 32, + [0][0][2][0][RTW89_KCC][0][92] = 127, + [0][0][2][0][RTW89_ACMA][1][92] = 127, + [0][0][2][0][RTW89_ACMA][0][92] = 127, + [0][0][2][0][RTW89_CHILE][1][92] = 22, + [0][0][2][0][RTW89_QATAR][1][92] = 127, + [0][0][2][0][RTW89_QATAR][0][92] = 127, + [0][0][2][0][RTW89_UK][1][92] = 127, + [0][0][2][0][RTW89_UK][0][92] = 127, + [0][0][2][0][RTW89_THAILAND][1][92] = 127, + [0][0][2][0][RTW89_THAILAND][0][92] = 127, + [0][0][2][0][RTW89_FCC][1][94] = 22, + [0][0][2][0][RTW89_ETSI][1][94] = 127, + [0][0][2][0][RTW89_ETSI][0][94] = 127, + [0][0][2][0][RTW89_MKK][1][94] = 127, + [0][0][2][0][RTW89_MKK][0][94] = 127, + [0][0][2][0][RTW89_IC][1][94] = 22, + [0][0][2][0][RTW89_KCC][1][94] = 32, + [0][0][2][0][RTW89_KCC][0][94] = 127, + [0][0][2][0][RTW89_ACMA][1][94] = 127, + [0][0][2][0][RTW89_ACMA][0][94] = 127, + [0][0][2][0][RTW89_CHILE][1][94] = 22, + [0][0][2][0][RTW89_QATAR][1][94] = 127, + [0][0][2][0][RTW89_QATAR][0][94] = 127, + [0][0][2][0][RTW89_UK][1][94] = 127, + [0][0][2][0][RTW89_UK][0][94] = 127, + [0][0][2][0][RTW89_THAILAND][1][94] = 127, + [0][0][2][0][RTW89_THAILAND][0][94] = 127, + [0][0][2][0][RTW89_FCC][1][96] = 22, + [0][0][2][0][RTW89_ETSI][1][96] = 127, + [0][0][2][0][RTW89_ETSI][0][96] = 127, + [0][0][2][0][RTW89_MKK][1][96] = 127, + [0][0][2][0][RTW89_MKK][0][96] = 127, + [0][0][2][0][RTW89_IC][1][96] = 22, + [0][0][2][0][RTW89_KCC][1][96] = 32, + [0][0][2][0][RTW89_KCC][0][96] = 127, + [0][0][2][0][RTW89_ACMA][1][96] = 127, + [0][0][2][0][RTW89_ACMA][0][96] = 127, + [0][0][2][0][RTW89_CHILE][1][96] = 22, + [0][0][2][0][RTW89_QATAR][1][96] = 127, + [0][0][2][0][RTW89_QATAR][0][96] = 127, + [0][0][2][0][RTW89_UK][1][96] = 127, + [0][0][2][0][RTW89_UK][0][96] = 127, + [0][0][2][0][RTW89_THAILAND][1][96] = 127, + [0][0][2][0][RTW89_THAILAND][0][96] = 127, + [0][0][2][0][RTW89_FCC][1][98] = 22, + [0][0][2][0][RTW89_ETSI][1][98] = 127, + [0][0][2][0][RTW89_ETSI][0][98] = 127, + [0][0][2][0][RTW89_MKK][1][98] = 127, + [0][0][2][0][RTW89_MKK][0][98] = 127, + [0][0][2][0][RTW89_IC][1][98] = 22, + [0][0][2][0][RTW89_KCC][1][98] = 32, + [0][0][2][0][RTW89_KCC][0][98] = 127, + [0][0][2][0][RTW89_ACMA][1][98] = 127, + [0][0][2][0][RTW89_ACMA][0][98] = 127, + [0][0][2][0][RTW89_CHILE][1][98] = 22, + [0][0][2][0][RTW89_QATAR][1][98] = 127, + [0][0][2][0][RTW89_QATAR][0][98] = 127, + [0][0][2][0][RTW89_UK][1][98] = 127, + [0][0][2][0][RTW89_UK][0][98] = 127, + [0][0][2][0][RTW89_THAILAND][1][98] = 127, + [0][0][2][0][RTW89_THAILAND][0][98] = 127, + [0][0][2][0][RTW89_FCC][1][100] = 22, + [0][0][2][0][RTW89_ETSI][1][100] = 127, + [0][0][2][0][RTW89_ETSI][0][100] = 127, + [0][0][2][0][RTW89_MKK][1][100] = 127, + [0][0][2][0][RTW89_MKK][0][100] = 127, + [0][0][2][0][RTW89_IC][1][100] = 22, + [0][0][2][0][RTW89_KCC][1][100] = 32, + [0][0][2][0][RTW89_KCC][0][100] = 127, + [0][0][2][0][RTW89_ACMA][1][100] = 127, + [0][0][2][0][RTW89_ACMA][0][100] = 127, + [0][0][2][0][RTW89_CHILE][1][100] = 22, + [0][0][2][0][RTW89_QATAR][1][100] = 127, + [0][0][2][0][RTW89_QATAR][0][100] = 127, + [0][0][2][0][RTW89_UK][1][100] = 127, + [0][0][2][0][RTW89_UK][0][100] = 127, + [0][0][2][0][RTW89_THAILAND][1][100] = 127, + [0][0][2][0][RTW89_THAILAND][0][100] = 127, + [0][0][2][0][RTW89_FCC][1][102] = 22, + [0][0][2][0][RTW89_ETSI][1][102] = 127, + [0][0][2][0][RTW89_ETSI][0][102] = 127, + [0][0][2][0][RTW89_MKK][1][102] = 127, + [0][0][2][0][RTW89_MKK][0][102] = 127, + [0][0][2][0][RTW89_IC][1][102] = 22, + [0][0][2][0][RTW89_KCC][1][102] = 32, + [0][0][2][0][RTW89_KCC][0][102] = 127, + [0][0][2][0][RTW89_ACMA][1][102] = 127, + [0][0][2][0][RTW89_ACMA][0][102] = 127, + [0][0][2][0][RTW89_CHILE][1][102] = 22, + [0][0][2][0][RTW89_QATAR][1][102] = 127, + [0][0][2][0][RTW89_QATAR][0][102] = 127, + [0][0][2][0][RTW89_UK][1][102] = 127, + [0][0][2][0][RTW89_UK][0][102] = 127, + [0][0][2][0][RTW89_THAILAND][1][102] = 127, + [0][0][2][0][RTW89_THAILAND][0][102] = 127, + [0][0][2][0][RTW89_FCC][1][104] = 22, + [0][0][2][0][RTW89_ETSI][1][104] = 127, + [0][0][2][0][RTW89_ETSI][0][104] = 127, + [0][0][2][0][RTW89_MKK][1][104] = 127, + [0][0][2][0][RTW89_MKK][0][104] = 127, + [0][0][2][0][RTW89_IC][1][104] = 22, + [0][0][2][0][RTW89_KCC][1][104] = 32, + [0][0][2][0][RTW89_KCC][0][104] = 127, + [0][0][2][0][RTW89_ACMA][1][104] = 127, + [0][0][2][0][RTW89_ACMA][0][104] = 127, + [0][0][2][0][RTW89_CHILE][1][104] = 22, + [0][0][2][0][RTW89_QATAR][1][104] = 127, + [0][0][2][0][RTW89_QATAR][0][104] = 127, + [0][0][2][0][RTW89_UK][1][104] = 127, + [0][0][2][0][RTW89_UK][0][104] = 127, + [0][0][2][0][RTW89_THAILAND][1][104] = 127, + [0][0][2][0][RTW89_THAILAND][0][104] = 127, + [0][0][2][0][RTW89_FCC][1][105] = 22, + [0][0][2][0][RTW89_ETSI][1][105] = 127, + [0][0][2][0][RTW89_ETSI][0][105] = 127, + [0][0][2][0][RTW89_MKK][1][105] = 127, + [0][0][2][0][RTW89_MKK][0][105] = 127, + [0][0][2][0][RTW89_IC][1][105] = 22, + [0][0][2][0][RTW89_KCC][1][105] = 32, + [0][0][2][0][RTW89_KCC][0][105] = 127, + [0][0][2][0][RTW89_ACMA][1][105] = 127, + [0][0][2][0][RTW89_ACMA][0][105] = 127, + [0][0][2][0][RTW89_CHILE][1][105] = 22, + [0][0][2][0][RTW89_QATAR][1][105] = 127, + [0][0][2][0][RTW89_QATAR][0][105] = 127, + [0][0][2][0][RTW89_UK][1][105] = 127, + [0][0][2][0][RTW89_UK][0][105] = 127, + [0][0][2][0][RTW89_THAILAND][1][105] = 127, + [0][0][2][0][RTW89_THAILAND][0][105] = 127, + [0][0][2][0][RTW89_FCC][1][107] = 24, + [0][0][2][0][RTW89_ETSI][1][107] = 127, + [0][0][2][0][RTW89_ETSI][0][107] = 127, + [0][0][2][0][RTW89_MKK][1][107] = 127, + [0][0][2][0][RTW89_MKK][0][107] = 127, + [0][0][2][0][RTW89_IC][1][107] = 24, + [0][0][2][0][RTW89_KCC][1][107] = 32, + [0][0][2][0][RTW89_KCC][0][107] = 127, + [0][0][2][0][RTW89_ACMA][1][107] = 127, + [0][0][2][0][RTW89_ACMA][0][107] = 127, + [0][0][2][0][RTW89_CHILE][1][107] = 24, + [0][0][2][0][RTW89_QATAR][1][107] = 127, + [0][0][2][0][RTW89_QATAR][0][107] = 127, + [0][0][2][0][RTW89_UK][1][107] = 127, + [0][0][2][0][RTW89_UK][0][107] = 127, + [0][0][2][0][RTW89_THAILAND][1][107] = 127, + [0][0][2][0][RTW89_THAILAND][0][107] = 127, + [0][0][2][0][RTW89_FCC][1][109] = 24, + [0][0][2][0][RTW89_ETSI][1][109] = 127, + [0][0][2][0][RTW89_ETSI][0][109] = 127, + [0][0][2][0][RTW89_MKK][1][109] = 127, + [0][0][2][0][RTW89_MKK][0][109] = 127, + [0][0][2][0][RTW89_IC][1][109] = 24, + [0][0][2][0][RTW89_KCC][1][109] = 32, + [0][0][2][0][RTW89_KCC][0][109] = 127, + [0][0][2][0][RTW89_ACMA][1][109] = 127, + [0][0][2][0][RTW89_ACMA][0][109] = 127, + [0][0][2][0][RTW89_CHILE][1][109] = 24, + [0][0][2][0][RTW89_QATAR][1][109] = 127, + [0][0][2][0][RTW89_QATAR][0][109] = 127, + [0][0][2][0][RTW89_UK][1][109] = 127, + [0][0][2][0][RTW89_UK][0][109] = 127, + [0][0][2][0][RTW89_THAILAND][1][109] = 127, + [0][0][2][0][RTW89_THAILAND][0][109] = 127, + [0][0][2][0][RTW89_FCC][1][111] = 127, + [0][0][2][0][RTW89_ETSI][1][111] = 127, + [0][0][2][0][RTW89_ETSI][0][111] = 127, + [0][0][2][0][RTW89_MKK][1][111] = 127, + [0][0][2][0][RTW89_MKK][0][111] = 127, + [0][0][2][0][RTW89_IC][1][111] = 127, + [0][0][2][0][RTW89_KCC][1][111] = 127, + [0][0][2][0][RTW89_KCC][0][111] = 127, + [0][0][2][0][RTW89_ACMA][1][111] = 127, + [0][0][2][0][RTW89_ACMA][0][111] = 127, + [0][0][2][0][RTW89_CHILE][1][111] = 127, + [0][0][2][0][RTW89_QATAR][1][111] = 127, + [0][0][2][0][RTW89_QATAR][0][111] = 127, + [0][0][2][0][RTW89_UK][1][111] = 127, + [0][0][2][0][RTW89_UK][0][111] = 127, + [0][0][2][0][RTW89_THAILAND][1][111] = 127, + [0][0][2][0][RTW89_THAILAND][0][111] = 127, + [0][0][2][0][RTW89_FCC][1][113] = 127, + [0][0][2][0][RTW89_ETSI][1][113] = 127, + [0][0][2][0][RTW89_ETSI][0][113] = 127, + [0][0][2][0][RTW89_MKK][1][113] = 127, + [0][0][2][0][RTW89_MKK][0][113] = 127, + [0][0][2][0][RTW89_IC][1][113] = 127, + [0][0][2][0][RTW89_KCC][1][113] = 127, + [0][0][2][0][RTW89_KCC][0][113] = 127, + [0][0][2][0][RTW89_ACMA][1][113] = 127, + [0][0][2][0][RTW89_ACMA][0][113] = 127, + [0][0][2][0][RTW89_CHILE][1][113] = 127, + [0][0][2][0][RTW89_QATAR][1][113] = 127, + [0][0][2][0][RTW89_QATAR][0][113] = 127, + [0][0][2][0][RTW89_UK][1][113] = 127, + [0][0][2][0][RTW89_UK][0][113] = 127, + [0][0][2][0][RTW89_THAILAND][1][113] = 127, + [0][0][2][0][RTW89_THAILAND][0][113] = 127, + [0][0][2][0][RTW89_FCC][1][115] = 127, + [0][0][2][0][RTW89_ETSI][1][115] = 127, + [0][0][2][0][RTW89_ETSI][0][115] = 127, + [0][0][2][0][RTW89_MKK][1][115] = 127, + [0][0][2][0][RTW89_MKK][0][115] = 127, + [0][0][2][0][RTW89_IC][1][115] = 127, + [0][0][2][0][RTW89_KCC][1][115] = 127, + [0][0][2][0][RTW89_KCC][0][115] = 127, + [0][0][2][0][RTW89_ACMA][1][115] = 127, + [0][0][2][0][RTW89_ACMA][0][115] = 127, + [0][0][2][0][RTW89_CHILE][1][115] = 127, + [0][0][2][0][RTW89_QATAR][1][115] = 127, + [0][0][2][0][RTW89_QATAR][0][115] = 127, + [0][0][2][0][RTW89_UK][1][115] = 127, + [0][0][2][0][RTW89_UK][0][115] = 127, + [0][0][2][0][RTW89_THAILAND][1][115] = 127, + [0][0][2][0][RTW89_THAILAND][0][115] = 127, + [0][0][2][0][RTW89_FCC][1][117] = 127, + [0][0][2][0][RTW89_ETSI][1][117] = 127, + [0][0][2][0][RTW89_ETSI][0][117] = 127, + [0][0][2][0][RTW89_MKK][1][117] = 127, + [0][0][2][0][RTW89_MKK][0][117] = 127, + [0][0][2][0][RTW89_IC][1][117] = 127, + [0][0][2][0][RTW89_KCC][1][117] = 127, + [0][0][2][0][RTW89_KCC][0][117] = 127, + [0][0][2][0][RTW89_ACMA][1][117] = 127, + [0][0][2][0][RTW89_ACMA][0][117] = 127, + [0][0][2][0][RTW89_CHILE][1][117] = 127, + [0][0][2][0][RTW89_QATAR][1][117] = 127, + [0][0][2][0][RTW89_QATAR][0][117] = 127, + [0][0][2][0][RTW89_UK][1][117] = 127, + [0][0][2][0][RTW89_UK][0][117] = 127, + [0][0][2][0][RTW89_THAILAND][1][117] = 127, + [0][0][2][0][RTW89_THAILAND][0][117] = 127, + [0][0][2][0][RTW89_FCC][1][119] = 127, + [0][0][2][0][RTW89_ETSI][1][119] = 127, + [0][0][2][0][RTW89_ETSI][0][119] = 127, + [0][0][2][0][RTW89_MKK][1][119] = 127, + [0][0][2][0][RTW89_MKK][0][119] = 127, + [0][0][2][0][RTW89_IC][1][119] = 127, + [0][0][2][0][RTW89_KCC][1][119] = 127, + [0][0][2][0][RTW89_KCC][0][119] = 127, + [0][0][2][0][RTW89_ACMA][1][119] = 127, + [0][0][2][0][RTW89_ACMA][0][119] = 127, + [0][0][2][0][RTW89_CHILE][1][119] = 127, + [0][0][2][0][RTW89_QATAR][1][119] = 127, + [0][0][2][0][RTW89_QATAR][0][119] = 127, + [0][0][2][0][RTW89_UK][1][119] = 127, + [0][0][2][0][RTW89_UK][0][119] = 127, + [0][0][2][0][RTW89_THAILAND][1][119] = 127, + [0][0][2][0][RTW89_THAILAND][0][119] = 127, + [0][1][2][0][RTW89_FCC][1][0] = -2, + [0][1][2][0][RTW89_ETSI][1][0] = 54, + [0][1][2][0][RTW89_ETSI][0][0] = 18, + [0][1][2][0][RTW89_MKK][1][0] = 56, + [0][1][2][0][RTW89_MKK][0][0] = 16, + [0][1][2][0][RTW89_IC][1][0] = -2, + [0][1][2][0][RTW89_KCC][1][0] = 12, + [0][1][2][0][RTW89_KCC][0][0] = 10, + [0][1][2][0][RTW89_ACMA][1][0] = 54, + [0][1][2][0][RTW89_ACMA][0][0] = 18, + [0][1][2][0][RTW89_CHILE][1][0] = -2, + [0][1][2][0][RTW89_QATAR][1][0] = 54, + [0][1][2][0][RTW89_QATAR][0][0] = 18, + [0][1][2][0][RTW89_UK][1][0] = 54, + [0][1][2][0][RTW89_UK][0][0] = 18, + [0][1][2][0][RTW89_THAILAND][1][0] = 44, + [0][1][2][0][RTW89_THAILAND][0][0] = -2, + [0][1][2][0][RTW89_FCC][1][2] = -4, + [0][1][2][0][RTW89_ETSI][1][2] = 54, + [0][1][2][0][RTW89_ETSI][0][2] = 18, + [0][1][2][0][RTW89_MKK][1][2] = 54, + [0][1][2][0][RTW89_MKK][0][2] = 16, + [0][1][2][0][RTW89_IC][1][2] = -4, + [0][1][2][0][RTW89_KCC][1][2] = 12, + [0][1][2][0][RTW89_KCC][0][2] = 12, + [0][1][2][0][RTW89_ACMA][1][2] = 54, + [0][1][2][0][RTW89_ACMA][0][2] = 18, + [0][1][2][0][RTW89_CHILE][1][2] = -4, + [0][1][2][0][RTW89_QATAR][1][2] = 54, + [0][1][2][0][RTW89_QATAR][0][2] = 18, + [0][1][2][0][RTW89_UK][1][2] = 54, + [0][1][2][0][RTW89_UK][0][2] = 18, + [0][1][2][0][RTW89_THAILAND][1][2] = 44, + [0][1][2][0][RTW89_THAILAND][0][2] = -4, + [0][1][2][0][RTW89_FCC][1][4] = -4, + [0][1][2][0][RTW89_ETSI][1][4] = 54, + [0][1][2][0][RTW89_ETSI][0][4] = 18, + [0][1][2][0][RTW89_MKK][1][4] = 54, + [0][1][2][0][RTW89_MKK][0][4] = 16, + [0][1][2][0][RTW89_IC][1][4] = -4, + [0][1][2][0][RTW89_KCC][1][4] = 12, + [0][1][2][0][RTW89_KCC][0][4] = 12, + [0][1][2][0][RTW89_ACMA][1][4] = 54, + [0][1][2][0][RTW89_ACMA][0][4] = 18, + [0][1][2][0][RTW89_CHILE][1][4] = -4, + [0][1][2][0][RTW89_QATAR][1][4] = 54, + [0][1][2][0][RTW89_QATAR][0][4] = 18, + [0][1][2][0][RTW89_UK][1][4] = 54, + [0][1][2][0][RTW89_UK][0][4] = 18, + [0][1][2][0][RTW89_THAILAND][1][4] = 44, + [0][1][2][0][RTW89_THAILAND][0][4] = -4, + [0][1][2][0][RTW89_FCC][1][6] = -4, + [0][1][2][0][RTW89_ETSI][1][6] = 54, + [0][1][2][0][RTW89_ETSI][0][6] = 18, + [0][1][2][0][RTW89_MKK][1][6] = 54, + [0][1][2][0][RTW89_MKK][0][6] = 16, + [0][1][2][0][RTW89_IC][1][6] = -4, + [0][1][2][0][RTW89_KCC][1][6] = 12, + [0][1][2][0][RTW89_KCC][0][6] = 12, + [0][1][2][0][RTW89_ACMA][1][6] = 54, + [0][1][2][0][RTW89_ACMA][0][6] = 18, + [0][1][2][0][RTW89_CHILE][1][6] = -4, + [0][1][2][0][RTW89_QATAR][1][6] = 54, + [0][1][2][0][RTW89_QATAR][0][6] = 18, + [0][1][2][0][RTW89_UK][1][6] = 54, + [0][1][2][0][RTW89_UK][0][6] = 18, + [0][1][2][0][RTW89_THAILAND][1][6] = 44, + [0][1][2][0][RTW89_THAILAND][0][6] = -4, + [0][1][2][0][RTW89_FCC][1][8] = -4, + [0][1][2][0][RTW89_ETSI][1][8] = 54, + [0][1][2][0][RTW89_ETSI][0][8] = 18, + [0][1][2][0][RTW89_MKK][1][8] = 54, + [0][1][2][0][RTW89_MKK][0][8] = 16, + [0][1][2][0][RTW89_IC][1][8] = -4, + [0][1][2][0][RTW89_KCC][1][8] = 12, + [0][1][2][0][RTW89_KCC][0][8] = 12, + [0][1][2][0][RTW89_ACMA][1][8] = 54, + [0][1][2][0][RTW89_ACMA][0][8] = 18, + [0][1][2][0][RTW89_CHILE][1][8] = -4, + [0][1][2][0][RTW89_QATAR][1][8] = 54, + [0][1][2][0][RTW89_QATAR][0][8] = 18, + [0][1][2][0][RTW89_UK][1][8] = 54, + [0][1][2][0][RTW89_UK][0][8] = 18, + [0][1][2][0][RTW89_THAILAND][1][8] = 44, + [0][1][2][0][RTW89_THAILAND][0][8] = -4, + [0][1][2][0][RTW89_FCC][1][10] = -4, + [0][1][2][0][RTW89_ETSI][1][10] = 54, + [0][1][2][0][RTW89_ETSI][0][10] = 18, + [0][1][2][0][RTW89_MKK][1][10] = 54, + [0][1][2][0][RTW89_MKK][0][10] = 16, + [0][1][2][0][RTW89_IC][1][10] = -4, + [0][1][2][0][RTW89_KCC][1][10] = 12, + [0][1][2][0][RTW89_KCC][0][10] = 12, + [0][1][2][0][RTW89_ACMA][1][10] = 54, + [0][1][2][0][RTW89_ACMA][0][10] = 18, + [0][1][2][0][RTW89_CHILE][1][10] = -4, + [0][1][2][0][RTW89_QATAR][1][10] = 54, + [0][1][2][0][RTW89_QATAR][0][10] = 18, + [0][1][2][0][RTW89_UK][1][10] = 54, + [0][1][2][0][RTW89_UK][0][10] = 18, + [0][1][2][0][RTW89_THAILAND][1][10] = 44, + [0][1][2][0][RTW89_THAILAND][0][10] = -4, + [0][1][2][0][RTW89_FCC][1][12] = -4, + [0][1][2][0][RTW89_ETSI][1][12] = 54, + [0][1][2][0][RTW89_ETSI][0][12] = 18, + [0][1][2][0][RTW89_MKK][1][12] = 54, + [0][1][2][0][RTW89_MKK][0][12] = 16, + [0][1][2][0][RTW89_IC][1][12] = -4, + [0][1][2][0][RTW89_KCC][1][12] = 12, + [0][1][2][0][RTW89_KCC][0][12] = 12, + [0][1][2][0][RTW89_ACMA][1][12] = 54, + [0][1][2][0][RTW89_ACMA][0][12] = 18, + [0][1][2][0][RTW89_CHILE][1][12] = -4, + [0][1][2][0][RTW89_QATAR][1][12] = 54, + [0][1][2][0][RTW89_QATAR][0][12] = 18, + [0][1][2][0][RTW89_UK][1][12] = 54, + [0][1][2][0][RTW89_UK][0][12] = 18, + [0][1][2][0][RTW89_THAILAND][1][12] = 44, + [0][1][2][0][RTW89_THAILAND][0][12] = -4, + [0][1][2][0][RTW89_FCC][1][14] = -4, + [0][1][2][0][RTW89_ETSI][1][14] = 54, + [0][1][2][0][RTW89_ETSI][0][14] = 18, + [0][1][2][0][RTW89_MKK][1][14] = 54, + [0][1][2][0][RTW89_MKK][0][14] = 16, + [0][1][2][0][RTW89_IC][1][14] = -4, + [0][1][2][0][RTW89_KCC][1][14] = 12, + [0][1][2][0][RTW89_KCC][0][14] = 12, + [0][1][2][0][RTW89_ACMA][1][14] = 54, + [0][1][2][0][RTW89_ACMA][0][14] = 18, + [0][1][2][0][RTW89_CHILE][1][14] = -4, + [0][1][2][0][RTW89_QATAR][1][14] = 54, + [0][1][2][0][RTW89_QATAR][0][14] = 18, + [0][1][2][0][RTW89_UK][1][14] = 54, + [0][1][2][0][RTW89_UK][0][14] = 18, + [0][1][2][0][RTW89_THAILAND][1][14] = 44, + [0][1][2][0][RTW89_THAILAND][0][14] = -4, + [0][1][2][0][RTW89_FCC][1][15] = -4, + [0][1][2][0][RTW89_ETSI][1][15] = 54, + [0][1][2][0][RTW89_ETSI][0][15] = 18, + [0][1][2][0][RTW89_MKK][1][15] = 54, + [0][1][2][0][RTW89_MKK][0][15] = 16, + [0][1][2][0][RTW89_IC][1][15] = -4, + [0][1][2][0][RTW89_KCC][1][15] = 12, + [0][1][2][0][RTW89_KCC][0][15] = 12, + [0][1][2][0][RTW89_ACMA][1][15] = 54, + [0][1][2][0][RTW89_ACMA][0][15] = 18, + [0][1][2][0][RTW89_CHILE][1][15] = -4, + [0][1][2][0][RTW89_QATAR][1][15] = 54, + [0][1][2][0][RTW89_QATAR][0][15] = 18, + [0][1][2][0][RTW89_UK][1][15] = 54, + [0][1][2][0][RTW89_UK][0][15] = 18, + [0][1][2][0][RTW89_THAILAND][1][15] = 44, + [0][1][2][0][RTW89_THAILAND][0][15] = -4, + [0][1][2][0][RTW89_FCC][1][17] = -4, + [0][1][2][0][RTW89_ETSI][1][17] = 54, + [0][1][2][0][RTW89_ETSI][0][17] = 18, + [0][1][2][0][RTW89_MKK][1][17] = 54, + [0][1][2][0][RTW89_MKK][0][17] = 16, + [0][1][2][0][RTW89_IC][1][17] = -4, + [0][1][2][0][RTW89_KCC][1][17] = 12, + [0][1][2][0][RTW89_KCC][0][17] = 12, + [0][1][2][0][RTW89_ACMA][1][17] = 54, + [0][1][2][0][RTW89_ACMA][0][17] = 18, + [0][1][2][0][RTW89_CHILE][1][17] = -4, + [0][1][2][0][RTW89_QATAR][1][17] = 54, + [0][1][2][0][RTW89_QATAR][0][17] = 18, + [0][1][2][0][RTW89_UK][1][17] = 54, + [0][1][2][0][RTW89_UK][0][17] = 18, + [0][1][2][0][RTW89_THAILAND][1][17] = 44, + [0][1][2][0][RTW89_THAILAND][0][17] = -4, + [0][1][2][0][RTW89_FCC][1][19] = -4, + [0][1][2][0][RTW89_ETSI][1][19] = 54, + [0][1][2][0][RTW89_ETSI][0][19] = 18, + [0][1][2][0][RTW89_MKK][1][19] = 54, + [0][1][2][0][RTW89_MKK][0][19] = 16, + [0][1][2][0][RTW89_IC][1][19] = -4, + [0][1][2][0][RTW89_KCC][1][19] = 12, + [0][1][2][0][RTW89_KCC][0][19] = 12, + [0][1][2][0][RTW89_ACMA][1][19] = 54, + [0][1][2][0][RTW89_ACMA][0][19] = 18, + [0][1][2][0][RTW89_CHILE][1][19] = -4, + [0][1][2][0][RTW89_QATAR][1][19] = 54, + [0][1][2][0][RTW89_QATAR][0][19] = 18, + [0][1][2][0][RTW89_UK][1][19] = 54, + [0][1][2][0][RTW89_UK][0][19] = 18, + [0][1][2][0][RTW89_THAILAND][1][19] = 44, + [0][1][2][0][RTW89_THAILAND][0][19] = -4, + [0][1][2][0][RTW89_FCC][1][21] = -4, + [0][1][2][0][RTW89_ETSI][1][21] = 54, + [0][1][2][0][RTW89_ETSI][0][21] = 18, + [0][1][2][0][RTW89_MKK][1][21] = 54, + [0][1][2][0][RTW89_MKK][0][21] = 16, + [0][1][2][0][RTW89_IC][1][21] = -4, + [0][1][2][0][RTW89_KCC][1][21] = 12, + [0][1][2][0][RTW89_KCC][0][21] = 12, + [0][1][2][0][RTW89_ACMA][1][21] = 54, + [0][1][2][0][RTW89_ACMA][0][21] = 18, + [0][1][2][0][RTW89_CHILE][1][21] = -4, + [0][1][2][0][RTW89_QATAR][1][21] = 54, + [0][1][2][0][RTW89_QATAR][0][21] = 18, + [0][1][2][0][RTW89_UK][1][21] = 54, + [0][1][2][0][RTW89_UK][0][21] = 18, + [0][1][2][0][RTW89_THAILAND][1][21] = 44, + [0][1][2][0][RTW89_THAILAND][0][21] = -4, + [0][1][2][0][RTW89_FCC][1][23] = -4, + [0][1][2][0][RTW89_ETSI][1][23] = 54, + [0][1][2][0][RTW89_ETSI][0][23] = 18, + [0][1][2][0][RTW89_MKK][1][23] = 54, + [0][1][2][0][RTW89_MKK][0][23] = 16, + [0][1][2][0][RTW89_IC][1][23] = -4, + [0][1][2][0][RTW89_KCC][1][23] = 12, + [0][1][2][0][RTW89_KCC][0][23] = 10, + [0][1][2][0][RTW89_ACMA][1][23] = 54, + [0][1][2][0][RTW89_ACMA][0][23] = 18, + [0][1][2][0][RTW89_CHILE][1][23] = -4, + [0][1][2][0][RTW89_QATAR][1][23] = 54, + [0][1][2][0][RTW89_QATAR][0][23] = 18, + [0][1][2][0][RTW89_UK][1][23] = 54, + [0][1][2][0][RTW89_UK][0][23] = 18, + [0][1][2][0][RTW89_THAILAND][1][23] = 44, + [0][1][2][0][RTW89_THAILAND][0][23] = -4, + [0][1][2][0][RTW89_FCC][1][25] = -4, + [0][1][2][0][RTW89_ETSI][1][25] = 54, + [0][1][2][0][RTW89_ETSI][0][25] = 18, + [0][1][2][0][RTW89_MKK][1][25] = 54, + [0][1][2][0][RTW89_MKK][0][25] = 16, + [0][1][2][0][RTW89_IC][1][25] = -4, + [0][1][2][0][RTW89_KCC][1][25] = 12, + [0][1][2][0][RTW89_KCC][0][25] = 14, + [0][1][2][0][RTW89_ACMA][1][25] = 54, + [0][1][2][0][RTW89_ACMA][0][25] = 18, + [0][1][2][0][RTW89_CHILE][1][25] = -4, + [0][1][2][0][RTW89_QATAR][1][25] = 54, + [0][1][2][0][RTW89_QATAR][0][25] = 18, + [0][1][2][0][RTW89_UK][1][25] = 54, + [0][1][2][0][RTW89_UK][0][25] = 18, + [0][1][2][0][RTW89_THAILAND][1][25] = 42, + [0][1][2][0][RTW89_THAILAND][0][25] = -4, + [0][1][2][0][RTW89_FCC][1][27] = -4, + [0][1][2][0][RTW89_ETSI][1][27] = 54, + [0][1][2][0][RTW89_ETSI][0][27] = 18, + [0][1][2][0][RTW89_MKK][1][27] = 54, + [0][1][2][0][RTW89_MKK][0][27] = 16, + [0][1][2][0][RTW89_IC][1][27] = -4, + [0][1][2][0][RTW89_KCC][1][27] = 12, + [0][1][2][0][RTW89_KCC][0][27] = 14, + [0][1][2][0][RTW89_ACMA][1][27] = 54, + [0][1][2][0][RTW89_ACMA][0][27] = 18, + [0][1][2][0][RTW89_CHILE][1][27] = -4, + [0][1][2][0][RTW89_QATAR][1][27] = 54, + [0][1][2][0][RTW89_QATAR][0][27] = 18, + [0][1][2][0][RTW89_UK][1][27] = 54, + [0][1][2][0][RTW89_UK][0][27] = 18, + [0][1][2][0][RTW89_THAILAND][1][27] = 42, + [0][1][2][0][RTW89_THAILAND][0][27] = -4, + [0][1][2][0][RTW89_FCC][1][29] = -4, + [0][1][2][0][RTW89_ETSI][1][29] = 54, + [0][1][2][0][RTW89_ETSI][0][29] = 18, + [0][1][2][0][RTW89_MKK][1][29] = 54, + [0][1][2][0][RTW89_MKK][0][29] = 16, + [0][1][2][0][RTW89_IC][1][29] = -4, + [0][1][2][0][RTW89_KCC][1][29] = 12, + [0][1][2][0][RTW89_KCC][0][29] = 14, + [0][1][2][0][RTW89_ACMA][1][29] = 54, + [0][1][2][0][RTW89_ACMA][0][29] = 18, + [0][1][2][0][RTW89_CHILE][1][29] = -4, + [0][1][2][0][RTW89_QATAR][1][29] = 54, + [0][1][2][0][RTW89_QATAR][0][29] = 18, + [0][1][2][0][RTW89_UK][1][29] = 54, + [0][1][2][0][RTW89_UK][0][29] = 18, + [0][1][2][0][RTW89_THAILAND][1][29] = 42, + [0][1][2][0][RTW89_THAILAND][0][29] = -4, + [0][1][2][0][RTW89_FCC][1][30] = -4, + [0][1][2][0][RTW89_ETSI][1][30] = 54, + [0][1][2][0][RTW89_ETSI][0][30] = 18, + [0][1][2][0][RTW89_MKK][1][30] = 54, + [0][1][2][0][RTW89_MKK][0][30] = 16, + [0][1][2][0][RTW89_IC][1][30] = -4, + [0][1][2][0][RTW89_KCC][1][30] = 12, + [0][1][2][0][RTW89_KCC][0][30] = 14, + [0][1][2][0][RTW89_ACMA][1][30] = 54, + [0][1][2][0][RTW89_ACMA][0][30] = 18, + [0][1][2][0][RTW89_CHILE][1][30] = -4, + [0][1][2][0][RTW89_QATAR][1][30] = 54, + [0][1][2][0][RTW89_QATAR][0][30] = 18, + [0][1][2][0][RTW89_UK][1][30] = 54, + [0][1][2][0][RTW89_UK][0][30] = 18, + [0][1][2][0][RTW89_THAILAND][1][30] = 42, + [0][1][2][0][RTW89_THAILAND][0][30] = -4, + [0][1][2][0][RTW89_FCC][1][32] = -4, + [0][1][2][0][RTW89_ETSI][1][32] = 54, + [0][1][2][0][RTW89_ETSI][0][32] = 18, + [0][1][2][0][RTW89_MKK][1][32] = 54, + [0][1][2][0][RTW89_MKK][0][32] = 16, + [0][1][2][0][RTW89_IC][1][32] = -4, + [0][1][2][0][RTW89_KCC][1][32] = 12, + [0][1][2][0][RTW89_KCC][0][32] = 14, + [0][1][2][0][RTW89_ACMA][1][32] = 54, + [0][1][2][0][RTW89_ACMA][0][32] = 18, + [0][1][2][0][RTW89_CHILE][1][32] = -4, + [0][1][2][0][RTW89_QATAR][1][32] = 54, + [0][1][2][0][RTW89_QATAR][0][32] = 18, + [0][1][2][0][RTW89_UK][1][32] = 54, + [0][1][2][0][RTW89_UK][0][32] = 18, + [0][1][2][0][RTW89_THAILAND][1][32] = 42, + [0][1][2][0][RTW89_THAILAND][0][32] = -4, + [0][1][2][0][RTW89_FCC][1][34] = -4, + [0][1][2][0][RTW89_ETSI][1][34] = 54, + [0][1][2][0][RTW89_ETSI][0][34] = 18, + [0][1][2][0][RTW89_MKK][1][34] = 54, + [0][1][2][0][RTW89_MKK][0][34] = 16, + [0][1][2][0][RTW89_IC][1][34] = -4, + [0][1][2][0][RTW89_KCC][1][34] = 12, + [0][1][2][0][RTW89_KCC][0][34] = 14, + [0][1][2][0][RTW89_ACMA][1][34] = 54, + [0][1][2][0][RTW89_ACMA][0][34] = 18, + [0][1][2][0][RTW89_CHILE][1][34] = -4, + [0][1][2][0][RTW89_QATAR][1][34] = 54, + [0][1][2][0][RTW89_QATAR][0][34] = 18, + [0][1][2][0][RTW89_UK][1][34] = 54, + [0][1][2][0][RTW89_UK][0][34] = 18, + [0][1][2][0][RTW89_THAILAND][1][34] = 42, + [0][1][2][0][RTW89_THAILAND][0][34] = -4, + [0][1][2][0][RTW89_FCC][1][36] = -4, + [0][1][2][0][RTW89_ETSI][1][36] = 54, + [0][1][2][0][RTW89_ETSI][0][36] = 18, + [0][1][2][0][RTW89_MKK][1][36] = 54, + [0][1][2][0][RTW89_MKK][0][36] = 16, + [0][1][2][0][RTW89_IC][1][36] = -4, + [0][1][2][0][RTW89_KCC][1][36] = 12, + [0][1][2][0][RTW89_KCC][0][36] = 14, + [0][1][2][0][RTW89_ACMA][1][36] = 54, + [0][1][2][0][RTW89_ACMA][0][36] = 18, + [0][1][2][0][RTW89_CHILE][1][36] = -4, + [0][1][2][0][RTW89_QATAR][1][36] = 54, + [0][1][2][0][RTW89_QATAR][0][36] = 18, + [0][1][2][0][RTW89_UK][1][36] = 54, + [0][1][2][0][RTW89_UK][0][36] = 18, + [0][1][2][0][RTW89_THAILAND][1][36] = 42, + [0][1][2][0][RTW89_THAILAND][0][36] = -4, + [0][1][2][0][RTW89_FCC][1][38] = -4, + [0][1][2][0][RTW89_ETSI][1][38] = 54, + [0][1][2][0][RTW89_ETSI][0][38] = 18, + [0][1][2][0][RTW89_MKK][1][38] = 54, + [0][1][2][0][RTW89_MKK][0][38] = 16, + [0][1][2][0][RTW89_IC][1][38] = -4, + [0][1][2][0][RTW89_KCC][1][38] = 12, + [0][1][2][0][RTW89_KCC][0][38] = 14, + [0][1][2][0][RTW89_ACMA][1][38] = 54, + [0][1][2][0][RTW89_ACMA][0][38] = 18, + [0][1][2][0][RTW89_CHILE][1][38] = -4, + [0][1][2][0][RTW89_QATAR][1][38] = 54, + [0][1][2][0][RTW89_QATAR][0][38] = 18, + [0][1][2][0][RTW89_UK][1][38] = 54, + [0][1][2][0][RTW89_UK][0][38] = 18, + [0][1][2][0][RTW89_THAILAND][1][38] = 42, + [0][1][2][0][RTW89_THAILAND][0][38] = -4, + [0][1][2][0][RTW89_FCC][1][40] = -4, + [0][1][2][0][RTW89_ETSI][1][40] = 54, + [0][1][2][0][RTW89_ETSI][0][40] = 18, + [0][1][2][0][RTW89_MKK][1][40] = 54, + [0][1][2][0][RTW89_MKK][0][40] = 16, + [0][1][2][0][RTW89_IC][1][40] = -4, + [0][1][2][0][RTW89_KCC][1][40] = 12, + [0][1][2][0][RTW89_KCC][0][40] = 14, + [0][1][2][0][RTW89_ACMA][1][40] = 54, + [0][1][2][0][RTW89_ACMA][0][40] = 18, + [0][1][2][0][RTW89_CHILE][1][40] = -4, + [0][1][2][0][RTW89_QATAR][1][40] = 54, + [0][1][2][0][RTW89_QATAR][0][40] = 18, + [0][1][2][0][RTW89_UK][1][40] = 54, + [0][1][2][0][RTW89_UK][0][40] = 18, + [0][1][2][0][RTW89_THAILAND][1][40] = 42, + [0][1][2][0][RTW89_THAILAND][0][40] = -4, + [0][1][2][0][RTW89_FCC][1][42] = -4, + [0][1][2][0][RTW89_ETSI][1][42] = 54, + [0][1][2][0][RTW89_ETSI][0][42] = 18, + [0][1][2][0][RTW89_MKK][1][42] = 54, + [0][1][2][0][RTW89_MKK][0][42] = 16, + [0][1][2][0][RTW89_IC][1][42] = -4, + [0][1][2][0][RTW89_KCC][1][42] = 12, + [0][1][2][0][RTW89_KCC][0][42] = 14, + [0][1][2][0][RTW89_ACMA][1][42] = 54, + [0][1][2][0][RTW89_ACMA][0][42] = 18, + [0][1][2][0][RTW89_CHILE][1][42] = -4, + [0][1][2][0][RTW89_QATAR][1][42] = 54, + [0][1][2][0][RTW89_QATAR][0][42] = 18, + [0][1][2][0][RTW89_UK][1][42] = 54, + [0][1][2][0][RTW89_UK][0][42] = 18, + [0][1][2][0][RTW89_THAILAND][1][42] = 42, + [0][1][2][0][RTW89_THAILAND][0][42] = -4, + [0][1][2][0][RTW89_FCC][1][44] = -2, + [0][1][2][0][RTW89_ETSI][1][44] = 54, + [0][1][2][0][RTW89_ETSI][0][44] = 18, + [0][1][2][0][RTW89_MKK][1][44] = 34, + [0][1][2][0][RTW89_MKK][0][44] = 16, + [0][1][2][0][RTW89_IC][1][44] = -2, + [0][1][2][0][RTW89_KCC][1][44] = 12, + [0][1][2][0][RTW89_KCC][0][44] = 12, + [0][1][2][0][RTW89_ACMA][1][44] = 54, + [0][1][2][0][RTW89_ACMA][0][44] = 18, + [0][1][2][0][RTW89_CHILE][1][44] = -2, + [0][1][2][0][RTW89_QATAR][1][44] = 54, + [0][1][2][0][RTW89_QATAR][0][44] = 18, + [0][1][2][0][RTW89_UK][1][44] = 54, + [0][1][2][0][RTW89_UK][0][44] = 18, + [0][1][2][0][RTW89_THAILAND][1][44] = 42, + [0][1][2][0][RTW89_THAILAND][0][44] = -2, + [0][1][2][0][RTW89_FCC][1][45] = -2, + [0][1][2][0][RTW89_ETSI][1][45] = 127, + [0][1][2][0][RTW89_ETSI][0][45] = 127, + [0][1][2][0][RTW89_MKK][1][45] = 127, + [0][1][2][0][RTW89_MKK][0][45] = 127, + [0][1][2][0][RTW89_IC][1][45] = -2, + [0][1][2][0][RTW89_KCC][1][45] = 12, + [0][1][2][0][RTW89_KCC][0][45] = 127, + [0][1][2][0][RTW89_ACMA][1][45] = 127, + [0][1][2][0][RTW89_ACMA][0][45] = 127, + [0][1][2][0][RTW89_CHILE][1][45] = -2, + [0][1][2][0][RTW89_QATAR][1][45] = 127, + [0][1][2][0][RTW89_QATAR][0][45] = 127, + [0][1][2][0][RTW89_UK][1][45] = 127, + [0][1][2][0][RTW89_UK][0][45] = 127, + [0][1][2][0][RTW89_THAILAND][1][45] = 127, + [0][1][2][0][RTW89_THAILAND][0][45] = 127, + [0][1][2][0][RTW89_FCC][1][47] = -2, + [0][1][2][0][RTW89_ETSI][1][47] = 127, + [0][1][2][0][RTW89_ETSI][0][47] = 127, + [0][1][2][0][RTW89_MKK][1][47] = 127, + [0][1][2][0][RTW89_MKK][0][47] = 127, + [0][1][2][0][RTW89_IC][1][47] = -2, + [0][1][2][0][RTW89_KCC][1][47] = 12, + [0][1][2][0][RTW89_KCC][0][47] = 127, + [0][1][2][0][RTW89_ACMA][1][47] = 127, + [0][1][2][0][RTW89_ACMA][0][47] = 127, + [0][1][2][0][RTW89_CHILE][1][47] = -2, + [0][1][2][0][RTW89_QATAR][1][47] = 127, + [0][1][2][0][RTW89_QATAR][0][47] = 127, + [0][1][2][0][RTW89_UK][1][47] = 127, + [0][1][2][0][RTW89_UK][0][47] = 127, + [0][1][2][0][RTW89_THAILAND][1][47] = 127, + [0][1][2][0][RTW89_THAILAND][0][47] = 127, + [0][1][2][0][RTW89_FCC][1][49] = -2, + [0][1][2][0][RTW89_ETSI][1][49] = 127, + [0][1][2][0][RTW89_ETSI][0][49] = 127, + [0][1][2][0][RTW89_MKK][1][49] = 127, + [0][1][2][0][RTW89_MKK][0][49] = 127, + [0][1][2][0][RTW89_IC][1][49] = -2, + [0][1][2][0][RTW89_KCC][1][49] = 12, + [0][1][2][0][RTW89_KCC][0][49] = 127, + [0][1][2][0][RTW89_ACMA][1][49] = 127, + [0][1][2][0][RTW89_ACMA][0][49] = 127, + [0][1][2][0][RTW89_CHILE][1][49] = -2, + [0][1][2][0][RTW89_QATAR][1][49] = 127, + [0][1][2][0][RTW89_QATAR][0][49] = 127, + [0][1][2][0][RTW89_UK][1][49] = 127, + [0][1][2][0][RTW89_UK][0][49] = 127, + [0][1][2][0][RTW89_THAILAND][1][49] = 127, + [0][1][2][0][RTW89_THAILAND][0][49] = 127, + [0][1][2][0][RTW89_FCC][1][51] = -2, + [0][1][2][0][RTW89_ETSI][1][51] = 127, + [0][1][2][0][RTW89_ETSI][0][51] = 127, + [0][1][2][0][RTW89_MKK][1][51] = 127, + [0][1][2][0][RTW89_MKK][0][51] = 127, + [0][1][2][0][RTW89_IC][1][51] = -2, + [0][1][2][0][RTW89_KCC][1][51] = 12, + [0][1][2][0][RTW89_KCC][0][51] = 127, + [0][1][2][0][RTW89_ACMA][1][51] = 127, + [0][1][2][0][RTW89_ACMA][0][51] = 127, + [0][1][2][0][RTW89_CHILE][1][51] = -2, + [0][1][2][0][RTW89_QATAR][1][51] = 127, + [0][1][2][0][RTW89_QATAR][0][51] = 127, + [0][1][2][0][RTW89_UK][1][51] = 127, + [0][1][2][0][RTW89_UK][0][51] = 127, + [0][1][2][0][RTW89_THAILAND][1][51] = 127, + [0][1][2][0][RTW89_THAILAND][0][51] = 127, + [0][1][2][0][RTW89_FCC][1][53] = -2, + [0][1][2][0][RTW89_ETSI][1][53] = 127, + [0][1][2][0][RTW89_ETSI][0][53] = 127, + [0][1][2][0][RTW89_MKK][1][53] = 127, + [0][1][2][0][RTW89_MKK][0][53] = 127, + [0][1][2][0][RTW89_IC][1][53] = -2, + [0][1][2][0][RTW89_KCC][1][53] = 12, + [0][1][2][0][RTW89_KCC][0][53] = 127, + [0][1][2][0][RTW89_ACMA][1][53] = 127, + [0][1][2][0][RTW89_ACMA][0][53] = 127, + [0][1][2][0][RTW89_CHILE][1][53] = -2, + [0][1][2][0][RTW89_QATAR][1][53] = 127, + [0][1][2][0][RTW89_QATAR][0][53] = 127, + [0][1][2][0][RTW89_UK][1][53] = 127, + [0][1][2][0][RTW89_UK][0][53] = 127, + [0][1][2][0][RTW89_THAILAND][1][53] = 127, + [0][1][2][0][RTW89_THAILAND][0][53] = 127, + [0][1][2][0][RTW89_FCC][1][55] = -2, + [0][1][2][0][RTW89_ETSI][1][55] = 127, + [0][1][2][0][RTW89_ETSI][0][55] = 127, + [0][1][2][0][RTW89_MKK][1][55] = 127, + [0][1][2][0][RTW89_MKK][0][55] = 127, + [0][1][2][0][RTW89_IC][1][55] = -2, + [0][1][2][0][RTW89_KCC][1][55] = 12, + [0][1][2][0][RTW89_KCC][0][55] = 127, + [0][1][2][0][RTW89_ACMA][1][55] = 127, + [0][1][2][0][RTW89_ACMA][0][55] = 127, + [0][1][2][0][RTW89_CHILE][1][55] = -2, + [0][1][2][0][RTW89_QATAR][1][55] = 127, + [0][1][2][0][RTW89_QATAR][0][55] = 127, + [0][1][2][0][RTW89_UK][1][55] = 127, + [0][1][2][0][RTW89_UK][0][55] = 127, + [0][1][2][0][RTW89_THAILAND][1][55] = 127, + [0][1][2][0][RTW89_THAILAND][0][55] = 127, + [0][1][2][0][RTW89_FCC][1][57] = -2, + [0][1][2][0][RTW89_ETSI][1][57] = 127, + [0][1][2][0][RTW89_ETSI][0][57] = 127, + [0][1][2][0][RTW89_MKK][1][57] = 127, + [0][1][2][0][RTW89_MKK][0][57] = 127, + [0][1][2][0][RTW89_IC][1][57] = -2, + [0][1][2][0][RTW89_KCC][1][57] = 12, + [0][1][2][0][RTW89_KCC][0][57] = 127, + [0][1][2][0][RTW89_ACMA][1][57] = 127, + [0][1][2][0][RTW89_ACMA][0][57] = 127, + [0][1][2][0][RTW89_CHILE][1][57] = -2, + [0][1][2][0][RTW89_QATAR][1][57] = 127, + [0][1][2][0][RTW89_QATAR][0][57] = 127, + [0][1][2][0][RTW89_UK][1][57] = 127, + [0][1][2][0][RTW89_UK][0][57] = 127, + [0][1][2][0][RTW89_THAILAND][1][57] = 127, + [0][1][2][0][RTW89_THAILAND][0][57] = 127, + [0][1][2][0][RTW89_FCC][1][59] = -2, + [0][1][2][0][RTW89_ETSI][1][59] = 127, + [0][1][2][0][RTW89_ETSI][0][59] = 127, + [0][1][2][0][RTW89_MKK][1][59] = 127, + [0][1][2][0][RTW89_MKK][0][59] = 127, + [0][1][2][0][RTW89_IC][1][59] = -2, + [0][1][2][0][RTW89_KCC][1][59] = 12, + [0][1][2][0][RTW89_KCC][0][59] = 127, + [0][1][2][0][RTW89_ACMA][1][59] = 127, + [0][1][2][0][RTW89_ACMA][0][59] = 127, + [0][1][2][0][RTW89_CHILE][1][59] = -2, + [0][1][2][0][RTW89_QATAR][1][59] = 127, + [0][1][2][0][RTW89_QATAR][0][59] = 127, + [0][1][2][0][RTW89_UK][1][59] = 127, + [0][1][2][0][RTW89_UK][0][59] = 127, + [0][1][2][0][RTW89_THAILAND][1][59] = 127, + [0][1][2][0][RTW89_THAILAND][0][59] = 127, + [0][1][2][0][RTW89_FCC][1][60] = -2, + [0][1][2][0][RTW89_ETSI][1][60] = 127, + [0][1][2][0][RTW89_ETSI][0][60] = 127, + [0][1][2][0][RTW89_MKK][1][60] = 127, + [0][1][2][0][RTW89_MKK][0][60] = 127, + [0][1][2][0][RTW89_IC][1][60] = -2, + [0][1][2][0][RTW89_KCC][1][60] = 12, + [0][1][2][0][RTW89_KCC][0][60] = 127, + [0][1][2][0][RTW89_ACMA][1][60] = 127, + [0][1][2][0][RTW89_ACMA][0][60] = 127, + [0][1][2][0][RTW89_CHILE][1][60] = -2, + [0][1][2][0][RTW89_QATAR][1][60] = 127, + [0][1][2][0][RTW89_QATAR][0][60] = 127, + [0][1][2][0][RTW89_UK][1][60] = 127, + [0][1][2][0][RTW89_UK][0][60] = 127, + [0][1][2][0][RTW89_THAILAND][1][60] = 127, + [0][1][2][0][RTW89_THAILAND][0][60] = 127, + [0][1][2][0][RTW89_FCC][1][62] = -2, + [0][1][2][0][RTW89_ETSI][1][62] = 127, + [0][1][2][0][RTW89_ETSI][0][62] = 127, + [0][1][2][0][RTW89_MKK][1][62] = 127, + [0][1][2][0][RTW89_MKK][0][62] = 127, + [0][1][2][0][RTW89_IC][1][62] = -2, + [0][1][2][0][RTW89_KCC][1][62] = 12, + [0][1][2][0][RTW89_KCC][0][62] = 127, + [0][1][2][0][RTW89_ACMA][1][62] = 127, + [0][1][2][0][RTW89_ACMA][0][62] = 127, + [0][1][2][0][RTW89_CHILE][1][62] = -2, + [0][1][2][0][RTW89_QATAR][1][62] = 127, + [0][1][2][0][RTW89_QATAR][0][62] = 127, + [0][1][2][0][RTW89_UK][1][62] = 127, + [0][1][2][0][RTW89_UK][0][62] = 127, + [0][1][2][0][RTW89_THAILAND][1][62] = 127, + [0][1][2][0][RTW89_THAILAND][0][62] = 127, + [0][1][2][0][RTW89_FCC][1][64] = -2, + [0][1][2][0][RTW89_ETSI][1][64] = 127, + [0][1][2][0][RTW89_ETSI][0][64] = 127, + [0][1][2][0][RTW89_MKK][1][64] = 127, + [0][1][2][0][RTW89_MKK][0][64] = 127, + [0][1][2][0][RTW89_IC][1][64] = -2, + [0][1][2][0][RTW89_KCC][1][64] = 12, + [0][1][2][0][RTW89_KCC][0][64] = 127, + [0][1][2][0][RTW89_ACMA][1][64] = 127, + [0][1][2][0][RTW89_ACMA][0][64] = 127, + [0][1][2][0][RTW89_CHILE][1][64] = -2, + [0][1][2][0][RTW89_QATAR][1][64] = 127, + [0][1][2][0][RTW89_QATAR][0][64] = 127, + [0][1][2][0][RTW89_UK][1][64] = 127, + [0][1][2][0][RTW89_UK][0][64] = 127, + [0][1][2][0][RTW89_THAILAND][1][64] = 127, + [0][1][2][0][RTW89_THAILAND][0][64] = 127, + [0][1][2][0][RTW89_FCC][1][66] = -2, + [0][1][2][0][RTW89_ETSI][1][66] = 127, + [0][1][2][0][RTW89_ETSI][0][66] = 127, + [0][1][2][0][RTW89_MKK][1][66] = 127, + [0][1][2][0][RTW89_MKK][0][66] = 127, + [0][1][2][0][RTW89_IC][1][66] = -2, + [0][1][2][0][RTW89_KCC][1][66] = 12, + [0][1][2][0][RTW89_KCC][0][66] = 127, + [0][1][2][0][RTW89_ACMA][1][66] = 127, + [0][1][2][0][RTW89_ACMA][0][66] = 127, + [0][1][2][0][RTW89_CHILE][1][66] = -2, + [0][1][2][0][RTW89_QATAR][1][66] = 127, + [0][1][2][0][RTW89_QATAR][0][66] = 127, + [0][1][2][0][RTW89_UK][1][66] = 127, + [0][1][2][0][RTW89_UK][0][66] = 127, + [0][1][2][0][RTW89_THAILAND][1][66] = 127, + [0][1][2][0][RTW89_THAILAND][0][66] = 127, + [0][1][2][0][RTW89_FCC][1][68] = -2, + [0][1][2][0][RTW89_ETSI][1][68] = 127, + [0][1][2][0][RTW89_ETSI][0][68] = 127, + [0][1][2][0][RTW89_MKK][1][68] = 127, + [0][1][2][0][RTW89_MKK][0][68] = 127, + [0][1][2][0][RTW89_IC][1][68] = -2, + [0][1][2][0][RTW89_KCC][1][68] = 12, + [0][1][2][0][RTW89_KCC][0][68] = 127, + [0][1][2][0][RTW89_ACMA][1][68] = 127, + [0][1][2][0][RTW89_ACMA][0][68] = 127, + [0][1][2][0][RTW89_CHILE][1][68] = -2, + [0][1][2][0][RTW89_QATAR][1][68] = 127, + [0][1][2][0][RTW89_QATAR][0][68] = 127, + [0][1][2][0][RTW89_UK][1][68] = 127, + [0][1][2][0][RTW89_UK][0][68] = 127, + [0][1][2][0][RTW89_THAILAND][1][68] = 127, + [0][1][2][0][RTW89_THAILAND][0][68] = 127, + [0][1][2][0][RTW89_FCC][1][70] = -2, + [0][1][2][0][RTW89_ETSI][1][70] = 127, + [0][1][2][0][RTW89_ETSI][0][70] = 127, + [0][1][2][0][RTW89_MKK][1][70] = 127, + [0][1][2][0][RTW89_MKK][0][70] = 127, + [0][1][2][0][RTW89_IC][1][70] = -2, + [0][1][2][0][RTW89_KCC][1][70] = 12, + [0][1][2][0][RTW89_KCC][0][70] = 127, + [0][1][2][0][RTW89_ACMA][1][70] = 127, + [0][1][2][0][RTW89_ACMA][0][70] = 127, + [0][1][2][0][RTW89_CHILE][1][70] = -2, + [0][1][2][0][RTW89_QATAR][1][70] = 127, + [0][1][2][0][RTW89_QATAR][0][70] = 127, + [0][1][2][0][RTW89_UK][1][70] = 127, + [0][1][2][0][RTW89_UK][0][70] = 127, + [0][1][2][0][RTW89_THAILAND][1][70] = 127, + [0][1][2][0][RTW89_THAILAND][0][70] = 127, + [0][1][2][0][RTW89_FCC][1][72] = -2, + [0][1][2][0][RTW89_ETSI][1][72] = 127, + [0][1][2][0][RTW89_ETSI][0][72] = 127, + [0][1][2][0][RTW89_MKK][1][72] = 127, + [0][1][2][0][RTW89_MKK][0][72] = 127, + [0][1][2][0][RTW89_IC][1][72] = -2, + [0][1][2][0][RTW89_KCC][1][72] = 12, + [0][1][2][0][RTW89_KCC][0][72] = 127, + [0][1][2][0][RTW89_ACMA][1][72] = 127, + [0][1][2][0][RTW89_ACMA][0][72] = 127, + [0][1][2][0][RTW89_CHILE][1][72] = -2, + [0][1][2][0][RTW89_QATAR][1][72] = 127, + [0][1][2][0][RTW89_QATAR][0][72] = 127, + [0][1][2][0][RTW89_UK][1][72] = 127, + [0][1][2][0][RTW89_UK][0][72] = 127, + [0][1][2][0][RTW89_THAILAND][1][72] = 127, + [0][1][2][0][RTW89_THAILAND][0][72] = 127, + [0][1][2][0][RTW89_FCC][1][74] = -2, + [0][1][2][0][RTW89_ETSI][1][74] = 127, + [0][1][2][0][RTW89_ETSI][0][74] = 127, + [0][1][2][0][RTW89_MKK][1][74] = 127, + [0][1][2][0][RTW89_MKK][0][74] = 127, + [0][1][2][0][RTW89_IC][1][74] = -2, + [0][1][2][0][RTW89_KCC][1][74] = 12, + [0][1][2][0][RTW89_KCC][0][74] = 127, + [0][1][2][0][RTW89_ACMA][1][74] = 127, + [0][1][2][0][RTW89_ACMA][0][74] = 127, + [0][1][2][0][RTW89_CHILE][1][74] = -2, + [0][1][2][0][RTW89_QATAR][1][74] = 127, + [0][1][2][0][RTW89_QATAR][0][74] = 127, + [0][1][2][0][RTW89_UK][1][74] = 127, + [0][1][2][0][RTW89_UK][0][74] = 127, + [0][1][2][0][RTW89_THAILAND][1][74] = 127, + [0][1][2][0][RTW89_THAILAND][0][74] = 127, + [0][1][2][0][RTW89_FCC][1][75] = -2, + [0][1][2][0][RTW89_ETSI][1][75] = 127, + [0][1][2][0][RTW89_ETSI][0][75] = 127, + [0][1][2][0][RTW89_MKK][1][75] = 127, + [0][1][2][0][RTW89_MKK][0][75] = 127, + [0][1][2][0][RTW89_IC][1][75] = -2, + [0][1][2][0][RTW89_KCC][1][75] = 12, + [0][1][2][0][RTW89_KCC][0][75] = 127, + [0][1][2][0][RTW89_ACMA][1][75] = 127, + [0][1][2][0][RTW89_ACMA][0][75] = 127, + [0][1][2][0][RTW89_CHILE][1][75] = -2, + [0][1][2][0][RTW89_QATAR][1][75] = 127, + [0][1][2][0][RTW89_QATAR][0][75] = 127, + [0][1][2][0][RTW89_UK][1][75] = 127, + [0][1][2][0][RTW89_UK][0][75] = 127, + [0][1][2][0][RTW89_THAILAND][1][75] = 127, + [0][1][2][0][RTW89_THAILAND][0][75] = 127, + [0][1][2][0][RTW89_FCC][1][77] = -2, + [0][1][2][0][RTW89_ETSI][1][77] = 127, + [0][1][2][0][RTW89_ETSI][0][77] = 127, + [0][1][2][0][RTW89_MKK][1][77] = 127, + [0][1][2][0][RTW89_MKK][0][77] = 127, + [0][1][2][0][RTW89_IC][1][77] = -2, + [0][1][2][0][RTW89_KCC][1][77] = 12, + [0][1][2][0][RTW89_KCC][0][77] = 127, + [0][1][2][0][RTW89_ACMA][1][77] = 127, + [0][1][2][0][RTW89_ACMA][0][77] = 127, + [0][1][2][0][RTW89_CHILE][1][77] = -2, + [0][1][2][0][RTW89_QATAR][1][77] = 127, + [0][1][2][0][RTW89_QATAR][0][77] = 127, + [0][1][2][0][RTW89_UK][1][77] = 127, + [0][1][2][0][RTW89_UK][0][77] = 127, + [0][1][2][0][RTW89_THAILAND][1][77] = 127, + [0][1][2][0][RTW89_THAILAND][0][77] = 127, + [0][1][2][0][RTW89_FCC][1][79] = -2, + [0][1][2][0][RTW89_ETSI][1][79] = 127, + [0][1][2][0][RTW89_ETSI][0][79] = 127, + [0][1][2][0][RTW89_MKK][1][79] = 127, + [0][1][2][0][RTW89_MKK][0][79] = 127, + [0][1][2][0][RTW89_IC][1][79] = -2, + [0][1][2][0][RTW89_KCC][1][79] = 12, + [0][1][2][0][RTW89_KCC][0][79] = 127, + [0][1][2][0][RTW89_ACMA][1][79] = 127, + [0][1][2][0][RTW89_ACMA][0][79] = 127, + [0][1][2][0][RTW89_CHILE][1][79] = -2, + [0][1][2][0][RTW89_QATAR][1][79] = 127, + [0][1][2][0][RTW89_QATAR][0][79] = 127, + [0][1][2][0][RTW89_UK][1][79] = 127, + [0][1][2][0][RTW89_UK][0][79] = 127, + [0][1][2][0][RTW89_THAILAND][1][79] = 127, + [0][1][2][0][RTW89_THAILAND][0][79] = 127, + [0][1][2][0][RTW89_FCC][1][81] = -2, + [0][1][2][0][RTW89_ETSI][1][81] = 127, + [0][1][2][0][RTW89_ETSI][0][81] = 127, + [0][1][2][0][RTW89_MKK][1][81] = 127, + [0][1][2][0][RTW89_MKK][0][81] = 127, + [0][1][2][0][RTW89_IC][1][81] = -2, + [0][1][2][0][RTW89_KCC][1][81] = 12, + [0][1][2][0][RTW89_KCC][0][81] = 127, + [0][1][2][0][RTW89_ACMA][1][81] = 127, + [0][1][2][0][RTW89_ACMA][0][81] = 127, + [0][1][2][0][RTW89_CHILE][1][81] = -2, + [0][1][2][0][RTW89_QATAR][1][81] = 127, + [0][1][2][0][RTW89_QATAR][0][81] = 127, + [0][1][2][0][RTW89_UK][1][81] = 127, + [0][1][2][0][RTW89_UK][0][81] = 127, + [0][1][2][0][RTW89_THAILAND][1][81] = 127, + [0][1][2][0][RTW89_THAILAND][0][81] = 127, + [0][1][2][0][RTW89_FCC][1][83] = -2, + [0][1][2][0][RTW89_ETSI][1][83] = 127, + [0][1][2][0][RTW89_ETSI][0][83] = 127, + [0][1][2][0][RTW89_MKK][1][83] = 127, + [0][1][2][0][RTW89_MKK][0][83] = 127, + [0][1][2][0][RTW89_IC][1][83] = -2, + [0][1][2][0][RTW89_KCC][1][83] = 20, + [0][1][2][0][RTW89_KCC][0][83] = 127, + [0][1][2][0][RTW89_ACMA][1][83] = 127, + [0][1][2][0][RTW89_ACMA][0][83] = 127, + [0][1][2][0][RTW89_CHILE][1][83] = -2, + [0][1][2][0][RTW89_QATAR][1][83] = 127, + [0][1][2][0][RTW89_QATAR][0][83] = 127, + [0][1][2][0][RTW89_UK][1][83] = 127, + [0][1][2][0][RTW89_UK][0][83] = 127, + [0][1][2][0][RTW89_THAILAND][1][83] = 127, + [0][1][2][0][RTW89_THAILAND][0][83] = 127, + [0][1][2][0][RTW89_FCC][1][85] = -2, + [0][1][2][0][RTW89_ETSI][1][85] = 127, + [0][1][2][0][RTW89_ETSI][0][85] = 127, + [0][1][2][0][RTW89_MKK][1][85] = 127, + [0][1][2][0][RTW89_MKK][0][85] = 127, + [0][1][2][0][RTW89_IC][1][85] = -2, + [0][1][2][0][RTW89_KCC][1][85] = 20, + [0][1][2][0][RTW89_KCC][0][85] = 127, + [0][1][2][0][RTW89_ACMA][1][85] = 127, + [0][1][2][0][RTW89_ACMA][0][85] = 127, + [0][1][2][0][RTW89_CHILE][1][85] = -2, + [0][1][2][0][RTW89_QATAR][1][85] = 127, + [0][1][2][0][RTW89_QATAR][0][85] = 127, + [0][1][2][0][RTW89_UK][1][85] = 127, + [0][1][2][0][RTW89_UK][0][85] = 127, + [0][1][2][0][RTW89_THAILAND][1][85] = 127, + [0][1][2][0][RTW89_THAILAND][0][85] = 127, + [0][1][2][0][RTW89_FCC][1][87] = -2, + [0][1][2][0][RTW89_ETSI][1][87] = 127, + [0][1][2][0][RTW89_ETSI][0][87] = 127, + [0][1][2][0][RTW89_MKK][1][87] = 127, + [0][1][2][0][RTW89_MKK][0][87] = 127, + [0][1][2][0][RTW89_IC][1][87] = -2, + [0][1][2][0][RTW89_KCC][1][87] = 20, + [0][1][2][0][RTW89_KCC][0][87] = 127, + [0][1][2][0][RTW89_ACMA][1][87] = 127, + [0][1][2][0][RTW89_ACMA][0][87] = 127, + [0][1][2][0][RTW89_CHILE][1][87] = -2, + [0][1][2][0][RTW89_QATAR][1][87] = 127, + [0][1][2][0][RTW89_QATAR][0][87] = 127, + [0][1][2][0][RTW89_UK][1][87] = 127, + [0][1][2][0][RTW89_UK][0][87] = 127, + [0][1][2][0][RTW89_THAILAND][1][87] = 127, + [0][1][2][0][RTW89_THAILAND][0][87] = 127, + [0][1][2][0][RTW89_FCC][1][89] = -2, + [0][1][2][0][RTW89_ETSI][1][89] = 127, + [0][1][2][0][RTW89_ETSI][0][89] = 127, + [0][1][2][0][RTW89_MKK][1][89] = 127, + [0][1][2][0][RTW89_MKK][0][89] = 127, + [0][1][2][0][RTW89_IC][1][89] = -2, + [0][1][2][0][RTW89_KCC][1][89] = 20, + [0][1][2][0][RTW89_KCC][0][89] = 127, + [0][1][2][0][RTW89_ACMA][1][89] = 127, + [0][1][2][0][RTW89_ACMA][0][89] = 127, + [0][1][2][0][RTW89_CHILE][1][89] = -2, + [0][1][2][0][RTW89_QATAR][1][89] = 127, + [0][1][2][0][RTW89_QATAR][0][89] = 127, + [0][1][2][0][RTW89_UK][1][89] = 127, + [0][1][2][0][RTW89_UK][0][89] = 127, + [0][1][2][0][RTW89_THAILAND][1][89] = 127, + [0][1][2][0][RTW89_THAILAND][0][89] = 127, + [0][1][2][0][RTW89_FCC][1][90] = -2, + [0][1][2][0][RTW89_ETSI][1][90] = 127, + [0][1][2][0][RTW89_ETSI][0][90] = 127, + [0][1][2][0][RTW89_MKK][1][90] = 127, + [0][1][2][0][RTW89_MKK][0][90] = 127, + [0][1][2][0][RTW89_IC][1][90] = -2, + [0][1][2][0][RTW89_KCC][1][90] = 20, + [0][1][2][0][RTW89_KCC][0][90] = 127, + [0][1][2][0][RTW89_ACMA][1][90] = 127, + [0][1][2][0][RTW89_ACMA][0][90] = 127, + [0][1][2][0][RTW89_CHILE][1][90] = -2, + [0][1][2][0][RTW89_QATAR][1][90] = 127, + [0][1][2][0][RTW89_QATAR][0][90] = 127, + [0][1][2][0][RTW89_UK][1][90] = 127, + [0][1][2][0][RTW89_UK][0][90] = 127, + [0][1][2][0][RTW89_THAILAND][1][90] = 127, + [0][1][2][0][RTW89_THAILAND][0][90] = 127, + [0][1][2][0][RTW89_FCC][1][92] = -2, + [0][1][2][0][RTW89_ETSI][1][92] = 127, + [0][1][2][0][RTW89_ETSI][0][92] = 127, + [0][1][2][0][RTW89_MKK][1][92] = 127, + [0][1][2][0][RTW89_MKK][0][92] = 127, + [0][1][2][0][RTW89_IC][1][92] = -2, + [0][1][2][0][RTW89_KCC][1][92] = 20, + [0][1][2][0][RTW89_KCC][0][92] = 127, + [0][1][2][0][RTW89_ACMA][1][92] = 127, + [0][1][2][0][RTW89_ACMA][0][92] = 127, + [0][1][2][0][RTW89_CHILE][1][92] = -2, + [0][1][2][0][RTW89_QATAR][1][92] = 127, + [0][1][2][0][RTW89_QATAR][0][92] = 127, + [0][1][2][0][RTW89_UK][1][92] = 127, + [0][1][2][0][RTW89_UK][0][92] = 127, + [0][1][2][0][RTW89_THAILAND][1][92] = 127, + [0][1][2][0][RTW89_THAILAND][0][92] = 127, + [0][1][2][0][RTW89_FCC][1][94] = -2, + [0][1][2][0][RTW89_ETSI][1][94] = 127, + [0][1][2][0][RTW89_ETSI][0][94] = 127, + [0][1][2][0][RTW89_MKK][1][94] = 127, + [0][1][2][0][RTW89_MKK][0][94] = 127, + [0][1][2][0][RTW89_IC][1][94] = -2, + [0][1][2][0][RTW89_KCC][1][94] = 20, + [0][1][2][0][RTW89_KCC][0][94] = 127, + [0][1][2][0][RTW89_ACMA][1][94] = 127, + [0][1][2][0][RTW89_ACMA][0][94] = 127, + [0][1][2][0][RTW89_CHILE][1][94] = -2, + [0][1][2][0][RTW89_QATAR][1][94] = 127, + [0][1][2][0][RTW89_QATAR][0][94] = 127, + [0][1][2][0][RTW89_UK][1][94] = 127, + [0][1][2][0][RTW89_UK][0][94] = 127, + [0][1][2][0][RTW89_THAILAND][1][94] = 127, + [0][1][2][0][RTW89_THAILAND][0][94] = 127, + [0][1][2][0][RTW89_FCC][1][96] = -2, + [0][1][2][0][RTW89_ETSI][1][96] = 127, + [0][1][2][0][RTW89_ETSI][0][96] = 127, + [0][1][2][0][RTW89_MKK][1][96] = 127, + [0][1][2][0][RTW89_MKK][0][96] = 127, + [0][1][2][0][RTW89_IC][1][96] = -2, + [0][1][2][0][RTW89_KCC][1][96] = 20, + [0][1][2][0][RTW89_KCC][0][96] = 127, + [0][1][2][0][RTW89_ACMA][1][96] = 127, + [0][1][2][0][RTW89_ACMA][0][96] = 127, + [0][1][2][0][RTW89_CHILE][1][96] = -2, + [0][1][2][0][RTW89_QATAR][1][96] = 127, + [0][1][2][0][RTW89_QATAR][0][96] = 127, + [0][1][2][0][RTW89_UK][1][96] = 127, + [0][1][2][0][RTW89_UK][0][96] = 127, + [0][1][2][0][RTW89_THAILAND][1][96] = 127, + [0][1][2][0][RTW89_THAILAND][0][96] = 127, + [0][1][2][0][RTW89_FCC][1][98] = -2, + [0][1][2][0][RTW89_ETSI][1][98] = 127, + [0][1][2][0][RTW89_ETSI][0][98] = 127, + [0][1][2][0][RTW89_MKK][1][98] = 127, + [0][1][2][0][RTW89_MKK][0][98] = 127, + [0][1][2][0][RTW89_IC][1][98] = -2, + [0][1][2][0][RTW89_KCC][1][98] = 20, + [0][1][2][0][RTW89_KCC][0][98] = 127, + [0][1][2][0][RTW89_ACMA][1][98] = 127, + [0][1][2][0][RTW89_ACMA][0][98] = 127, + [0][1][2][0][RTW89_CHILE][1][98] = -2, + [0][1][2][0][RTW89_QATAR][1][98] = 127, + [0][1][2][0][RTW89_QATAR][0][98] = 127, + [0][1][2][0][RTW89_UK][1][98] = 127, + [0][1][2][0][RTW89_UK][0][98] = 127, + [0][1][2][0][RTW89_THAILAND][1][98] = 127, + [0][1][2][0][RTW89_THAILAND][0][98] = 127, + [0][1][2][0][RTW89_FCC][1][100] = -2, + [0][1][2][0][RTW89_ETSI][1][100] = 127, + [0][1][2][0][RTW89_ETSI][0][100] = 127, + [0][1][2][0][RTW89_MKK][1][100] = 127, + [0][1][2][0][RTW89_MKK][0][100] = 127, + [0][1][2][0][RTW89_IC][1][100] = -2, + [0][1][2][0][RTW89_KCC][1][100] = 20, + [0][1][2][0][RTW89_KCC][0][100] = 127, + [0][1][2][0][RTW89_ACMA][1][100] = 127, + [0][1][2][0][RTW89_ACMA][0][100] = 127, + [0][1][2][0][RTW89_CHILE][1][100] = -2, + [0][1][2][0][RTW89_QATAR][1][100] = 127, + [0][1][2][0][RTW89_QATAR][0][100] = 127, + [0][1][2][0][RTW89_UK][1][100] = 127, + [0][1][2][0][RTW89_UK][0][100] = 127, + [0][1][2][0][RTW89_THAILAND][1][100] = 127, + [0][1][2][0][RTW89_THAILAND][0][100] = 127, + [0][1][2][0][RTW89_FCC][1][102] = -2, + [0][1][2][0][RTW89_ETSI][1][102] = 127, + [0][1][2][0][RTW89_ETSI][0][102] = 127, + [0][1][2][0][RTW89_MKK][1][102] = 127, + [0][1][2][0][RTW89_MKK][0][102] = 127, + [0][1][2][0][RTW89_IC][1][102] = -2, + [0][1][2][0][RTW89_KCC][1][102] = 20, + [0][1][2][0][RTW89_KCC][0][102] = 127, + [0][1][2][0][RTW89_ACMA][1][102] = 127, + [0][1][2][0][RTW89_ACMA][0][102] = 127, + [0][1][2][0][RTW89_CHILE][1][102] = -2, + [0][1][2][0][RTW89_QATAR][1][102] = 127, + [0][1][2][0][RTW89_QATAR][0][102] = 127, + [0][1][2][0][RTW89_UK][1][102] = 127, + [0][1][2][0][RTW89_UK][0][102] = 127, + [0][1][2][0][RTW89_THAILAND][1][102] = 127, + [0][1][2][0][RTW89_THAILAND][0][102] = 127, + [0][1][2][0][RTW89_FCC][1][104] = -2, + [0][1][2][0][RTW89_ETSI][1][104] = 127, + [0][1][2][0][RTW89_ETSI][0][104] = 127, + [0][1][2][0][RTW89_MKK][1][104] = 127, + [0][1][2][0][RTW89_MKK][0][104] = 127, + [0][1][2][0][RTW89_IC][1][104] = -2, + [0][1][2][0][RTW89_KCC][1][104] = 20, + [0][1][2][0][RTW89_KCC][0][104] = 127, + [0][1][2][0][RTW89_ACMA][1][104] = 127, + [0][1][2][0][RTW89_ACMA][0][104] = 127, + [0][1][2][0][RTW89_CHILE][1][104] = -2, + [0][1][2][0][RTW89_QATAR][1][104] = 127, + [0][1][2][0][RTW89_QATAR][0][104] = 127, + [0][1][2][0][RTW89_UK][1][104] = 127, + [0][1][2][0][RTW89_UK][0][104] = 127, + [0][1][2][0][RTW89_THAILAND][1][104] = 127, + [0][1][2][0][RTW89_THAILAND][0][104] = 127, + [0][1][2][0][RTW89_FCC][1][105] = -2, + [0][1][2][0][RTW89_ETSI][1][105] = 127, + [0][1][2][0][RTW89_ETSI][0][105] = 127, + [0][1][2][0][RTW89_MKK][1][105] = 127, + [0][1][2][0][RTW89_MKK][0][105] = 127, + [0][1][2][0][RTW89_IC][1][105] = -2, + [0][1][2][0][RTW89_KCC][1][105] = 20, + [0][1][2][0][RTW89_KCC][0][105] = 127, + [0][1][2][0][RTW89_ACMA][1][105] = 127, + [0][1][2][0][RTW89_ACMA][0][105] = 127, + [0][1][2][0][RTW89_CHILE][1][105] = -2, + [0][1][2][0][RTW89_QATAR][1][105] = 127, + [0][1][2][0][RTW89_QATAR][0][105] = 127, + [0][1][2][0][RTW89_UK][1][105] = 127, + [0][1][2][0][RTW89_UK][0][105] = 127, + [0][1][2][0][RTW89_THAILAND][1][105] = 127, + [0][1][2][0][RTW89_THAILAND][0][105] = 127, + [0][1][2][0][RTW89_FCC][1][107] = 1, + [0][1][2][0][RTW89_ETSI][1][107] = 127, + [0][1][2][0][RTW89_ETSI][0][107] = 127, + [0][1][2][0][RTW89_MKK][1][107] = 127, + [0][1][2][0][RTW89_MKK][0][107] = 127, + [0][1][2][0][RTW89_IC][1][107] = 1, + [0][1][2][0][RTW89_KCC][1][107] = 20, + [0][1][2][0][RTW89_KCC][0][107] = 127, + [0][1][2][0][RTW89_ACMA][1][107] = 127, + [0][1][2][0][RTW89_ACMA][0][107] = 127, + [0][1][2][0][RTW89_CHILE][1][107] = 1, + [0][1][2][0][RTW89_QATAR][1][107] = 127, + [0][1][2][0][RTW89_QATAR][0][107] = 127, + [0][1][2][0][RTW89_UK][1][107] = 127, + [0][1][2][0][RTW89_UK][0][107] = 127, + [0][1][2][0][RTW89_THAILAND][1][107] = 127, + [0][1][2][0][RTW89_THAILAND][0][107] = 127, + [0][1][2][0][RTW89_FCC][1][109] = 1, + [0][1][2][0][RTW89_ETSI][1][109] = 127, + [0][1][2][0][RTW89_ETSI][0][109] = 127, + [0][1][2][0][RTW89_MKK][1][109] = 127, + [0][1][2][0][RTW89_MKK][0][109] = 127, + [0][1][2][0][RTW89_IC][1][109] = 1, + [0][1][2][0][RTW89_KCC][1][109] = 20, + [0][1][2][0][RTW89_KCC][0][109] = 127, + [0][1][2][0][RTW89_ACMA][1][109] = 127, + [0][1][2][0][RTW89_ACMA][0][109] = 127, + [0][1][2][0][RTW89_CHILE][1][109] = 1, + [0][1][2][0][RTW89_QATAR][1][109] = 127, + [0][1][2][0][RTW89_QATAR][0][109] = 127, + [0][1][2][0][RTW89_UK][1][109] = 127, + [0][1][2][0][RTW89_UK][0][109] = 127, + [0][1][2][0][RTW89_THAILAND][1][109] = 127, + [0][1][2][0][RTW89_THAILAND][0][109] = 127, + [0][1][2][0][RTW89_FCC][1][111] = 127, + [0][1][2][0][RTW89_ETSI][1][111] = 127, + [0][1][2][0][RTW89_ETSI][0][111] = 127, + [0][1][2][0][RTW89_MKK][1][111] = 127, + [0][1][2][0][RTW89_MKK][0][111] = 127, + [0][1][2][0][RTW89_IC][1][111] = 127, + [0][1][2][0][RTW89_KCC][1][111] = 127, + [0][1][2][0][RTW89_KCC][0][111] = 127, + [0][1][2][0][RTW89_ACMA][1][111] = 127, + [0][1][2][0][RTW89_ACMA][0][111] = 127, + [0][1][2][0][RTW89_CHILE][1][111] = 127, + [0][1][2][0][RTW89_QATAR][1][111] = 127, + [0][1][2][0][RTW89_QATAR][0][111] = 127, + [0][1][2][0][RTW89_UK][1][111] = 127, + [0][1][2][0][RTW89_UK][0][111] = 127, + [0][1][2][0][RTW89_THAILAND][1][111] = 127, + [0][1][2][0][RTW89_THAILAND][0][111] = 127, + [0][1][2][0][RTW89_FCC][1][113] = 127, + [0][1][2][0][RTW89_ETSI][1][113] = 127, + [0][1][2][0][RTW89_ETSI][0][113] = 127, + [0][1][2][0][RTW89_MKK][1][113] = 127, + [0][1][2][0][RTW89_MKK][0][113] = 127, + [0][1][2][0][RTW89_IC][1][113] = 127, + [0][1][2][0][RTW89_KCC][1][113] = 127, + [0][1][2][0][RTW89_KCC][0][113] = 127, + [0][1][2][0][RTW89_ACMA][1][113] = 127, + [0][1][2][0][RTW89_ACMA][0][113] = 127, + [0][1][2][0][RTW89_CHILE][1][113] = 127, + [0][1][2][0][RTW89_QATAR][1][113] = 127, + [0][1][2][0][RTW89_QATAR][0][113] = 127, + [0][1][2][0][RTW89_UK][1][113] = 127, + [0][1][2][0][RTW89_UK][0][113] = 127, + [0][1][2][0][RTW89_THAILAND][1][113] = 127, + [0][1][2][0][RTW89_THAILAND][0][113] = 127, + [0][1][2][0][RTW89_FCC][1][115] = 127, + [0][1][2][0][RTW89_ETSI][1][115] = 127, + [0][1][2][0][RTW89_ETSI][0][115] = 127, + [0][1][2][0][RTW89_MKK][1][115] = 127, + [0][1][2][0][RTW89_MKK][0][115] = 127, + [0][1][2][0][RTW89_IC][1][115] = 127, + [0][1][2][0][RTW89_KCC][1][115] = 127, + [0][1][2][0][RTW89_KCC][0][115] = 127, + [0][1][2][0][RTW89_ACMA][1][115] = 127, + [0][1][2][0][RTW89_ACMA][0][115] = 127, + [0][1][2][0][RTW89_CHILE][1][115] = 127, + [0][1][2][0][RTW89_QATAR][1][115] = 127, + [0][1][2][0][RTW89_QATAR][0][115] = 127, + [0][1][2][0][RTW89_UK][1][115] = 127, + [0][1][2][0][RTW89_UK][0][115] = 127, + [0][1][2][0][RTW89_THAILAND][1][115] = 127, + [0][1][2][0][RTW89_THAILAND][0][115] = 127, + [0][1][2][0][RTW89_FCC][1][117] = 127, + [0][1][2][0][RTW89_ETSI][1][117] = 127, + [0][1][2][0][RTW89_ETSI][0][117] = 127, + [0][1][2][0][RTW89_MKK][1][117] = 127, + [0][1][2][0][RTW89_MKK][0][117] = 127, + [0][1][2][0][RTW89_IC][1][117] = 127, + [0][1][2][0][RTW89_KCC][1][117] = 127, + [0][1][2][0][RTW89_KCC][0][117] = 127, + [0][1][2][0][RTW89_ACMA][1][117] = 127, + [0][1][2][0][RTW89_ACMA][0][117] = 127, + [0][1][2][0][RTW89_CHILE][1][117] = 127, + [0][1][2][0][RTW89_QATAR][1][117] = 127, + [0][1][2][0][RTW89_QATAR][0][117] = 127, + [0][1][2][0][RTW89_UK][1][117] = 127, + [0][1][2][0][RTW89_UK][0][117] = 127, + [0][1][2][0][RTW89_THAILAND][1][117] = 127, + [0][1][2][0][RTW89_THAILAND][0][117] = 127, + [0][1][2][0][RTW89_FCC][1][119] = 127, + [0][1][2][0][RTW89_ETSI][1][119] = 127, + [0][1][2][0][RTW89_ETSI][0][119] = 127, + [0][1][2][0][RTW89_MKK][1][119] = 127, + [0][1][2][0][RTW89_MKK][0][119] = 127, + [0][1][2][0][RTW89_IC][1][119] = 127, + [0][1][2][0][RTW89_KCC][1][119] = 127, + [0][1][2][0][RTW89_KCC][0][119] = 127, + [0][1][2][0][RTW89_ACMA][1][119] = 127, + [0][1][2][0][RTW89_ACMA][0][119] = 127, + [0][1][2][0][RTW89_CHILE][1][119] = 127, + [0][1][2][0][RTW89_QATAR][1][119] = 127, + [0][1][2][0][RTW89_QATAR][0][119] = 127, + [0][1][2][0][RTW89_UK][1][119] = 127, + [0][1][2][0][RTW89_UK][0][119] = 127, + [0][1][2][0][RTW89_THAILAND][1][119] = 127, + [0][1][2][0][RTW89_THAILAND][0][119] = 127, + [0][1][2][1][RTW89_FCC][1][0] = -2, + [0][1][2][1][RTW89_ETSI][1][0] = 42, + [0][1][2][1][RTW89_ETSI][0][0] = 6, + [0][1][2][1][RTW89_MKK][1][0] = 56, + [0][1][2][1][RTW89_MKK][0][0] = 16, + [0][1][2][1][RTW89_IC][1][0] = -2, + [0][1][2][1][RTW89_KCC][1][0] = 12, + [0][1][2][1][RTW89_KCC][0][0] = 10, + [0][1][2][1][RTW89_ACMA][1][0] = 42, + [0][1][2][1][RTW89_ACMA][0][0] = 6, + [0][1][2][1][RTW89_CHILE][1][0] = -2, + [0][1][2][1][RTW89_QATAR][1][0] = 42, + [0][1][2][1][RTW89_QATAR][0][0] = 6, + [0][1][2][1][RTW89_UK][1][0] = 42, + [0][1][2][1][RTW89_UK][0][0] = 6, + [0][1][2][1][RTW89_THAILAND][1][0] = 44, + [0][1][2][1][RTW89_THAILAND][0][0] = -2, + [0][1][2][1][RTW89_FCC][1][2] = -4, + [0][1][2][1][RTW89_ETSI][1][2] = 42, + [0][1][2][1][RTW89_ETSI][0][2] = 6, + [0][1][2][1][RTW89_MKK][1][2] = 54, + [0][1][2][1][RTW89_MKK][0][2] = 16, + [0][1][2][1][RTW89_IC][1][2] = -4, + [0][1][2][1][RTW89_KCC][1][2] = 12, + [0][1][2][1][RTW89_KCC][0][2] = 12, + [0][1][2][1][RTW89_ACMA][1][2] = 42, + [0][1][2][1][RTW89_ACMA][0][2] = 6, + [0][1][2][1][RTW89_CHILE][1][2] = -4, + [0][1][2][1][RTW89_QATAR][1][2] = 42, + [0][1][2][1][RTW89_QATAR][0][2] = 6, + [0][1][2][1][RTW89_UK][1][2] = 42, + [0][1][2][1][RTW89_UK][0][2] = 6, + [0][1][2][1][RTW89_THAILAND][1][2] = 44, + [0][1][2][1][RTW89_THAILAND][0][2] = -4, + [0][1][2][1][RTW89_FCC][1][4] = -4, + [0][1][2][1][RTW89_ETSI][1][4] = 42, + [0][1][2][1][RTW89_ETSI][0][4] = 6, + [0][1][2][1][RTW89_MKK][1][4] = 54, + [0][1][2][1][RTW89_MKK][0][4] = 16, + [0][1][2][1][RTW89_IC][1][4] = -4, + [0][1][2][1][RTW89_KCC][1][4] = 12, + [0][1][2][1][RTW89_KCC][0][4] = 12, + [0][1][2][1][RTW89_ACMA][1][4] = 42, + [0][1][2][1][RTW89_ACMA][0][4] = 6, + [0][1][2][1][RTW89_CHILE][1][4] = -4, + [0][1][2][1][RTW89_QATAR][1][4] = 42, + [0][1][2][1][RTW89_QATAR][0][4] = 6, + [0][1][2][1][RTW89_UK][1][4] = 42, + [0][1][2][1][RTW89_UK][0][4] = 6, + [0][1][2][1][RTW89_THAILAND][1][4] = 44, + [0][1][2][1][RTW89_THAILAND][0][4] = -4, + [0][1][2][1][RTW89_FCC][1][6] = -4, + [0][1][2][1][RTW89_ETSI][1][6] = 42, + [0][1][2][1][RTW89_ETSI][0][6] = 6, + [0][1][2][1][RTW89_MKK][1][6] = 54, + [0][1][2][1][RTW89_MKK][0][6] = 16, + [0][1][2][1][RTW89_IC][1][6] = -4, + [0][1][2][1][RTW89_KCC][1][6] = 12, + [0][1][2][1][RTW89_KCC][0][6] = 12, + [0][1][2][1][RTW89_ACMA][1][6] = 42, + [0][1][2][1][RTW89_ACMA][0][6] = 6, + [0][1][2][1][RTW89_CHILE][1][6] = -4, + [0][1][2][1][RTW89_QATAR][1][6] = 42, + [0][1][2][1][RTW89_QATAR][0][6] = 6, + [0][1][2][1][RTW89_UK][1][6] = 42, + [0][1][2][1][RTW89_UK][0][6] = 6, + [0][1][2][1][RTW89_THAILAND][1][6] = 44, + [0][1][2][1][RTW89_THAILAND][0][6] = -4, + [0][1][2][1][RTW89_FCC][1][8] = -4, + [0][1][2][1][RTW89_ETSI][1][8] = 42, + [0][1][2][1][RTW89_ETSI][0][8] = 6, + [0][1][2][1][RTW89_MKK][1][8] = 54, + [0][1][2][1][RTW89_MKK][0][8] = 16, + [0][1][2][1][RTW89_IC][1][8] = -4, + [0][1][2][1][RTW89_KCC][1][8] = 12, + [0][1][2][1][RTW89_KCC][0][8] = 12, + [0][1][2][1][RTW89_ACMA][1][8] = 42, + [0][1][2][1][RTW89_ACMA][0][8] = 6, + [0][1][2][1][RTW89_CHILE][1][8] = -4, + [0][1][2][1][RTW89_QATAR][1][8] = 42, + [0][1][2][1][RTW89_QATAR][0][8] = 6, + [0][1][2][1][RTW89_UK][1][8] = 42, + [0][1][2][1][RTW89_UK][0][8] = 6, + [0][1][2][1][RTW89_THAILAND][1][8] = 44, + [0][1][2][1][RTW89_THAILAND][0][8] = -4, + [0][1][2][1][RTW89_FCC][1][10] = -4, + [0][1][2][1][RTW89_ETSI][1][10] = 42, + [0][1][2][1][RTW89_ETSI][0][10] = 6, + [0][1][2][1][RTW89_MKK][1][10] = 54, + [0][1][2][1][RTW89_MKK][0][10] = 16, + [0][1][2][1][RTW89_IC][1][10] = -4, + [0][1][2][1][RTW89_KCC][1][10] = 12, + [0][1][2][1][RTW89_KCC][0][10] = 12, + [0][1][2][1][RTW89_ACMA][1][10] = 42, + [0][1][2][1][RTW89_ACMA][0][10] = 6, + [0][1][2][1][RTW89_CHILE][1][10] = -4, + [0][1][2][1][RTW89_QATAR][1][10] = 42, + [0][1][2][1][RTW89_QATAR][0][10] = 6, + [0][1][2][1][RTW89_UK][1][10] = 42, + [0][1][2][1][RTW89_UK][0][10] = 6, + [0][1][2][1][RTW89_THAILAND][1][10] = 44, + [0][1][2][1][RTW89_THAILAND][0][10] = -4, + [0][1][2][1][RTW89_FCC][1][12] = -4, + [0][1][2][1][RTW89_ETSI][1][12] = 42, + [0][1][2][1][RTW89_ETSI][0][12] = 6, + [0][1][2][1][RTW89_MKK][1][12] = 54, + [0][1][2][1][RTW89_MKK][0][12] = 16, + [0][1][2][1][RTW89_IC][1][12] = -4, + [0][1][2][1][RTW89_KCC][1][12] = 12, + [0][1][2][1][RTW89_KCC][0][12] = 12, + [0][1][2][1][RTW89_ACMA][1][12] = 42, + [0][1][2][1][RTW89_ACMA][0][12] = 6, + [0][1][2][1][RTW89_CHILE][1][12] = -4, + [0][1][2][1][RTW89_QATAR][1][12] = 42, + [0][1][2][1][RTW89_QATAR][0][12] = 6, + [0][1][2][1][RTW89_UK][1][12] = 42, + [0][1][2][1][RTW89_UK][0][12] = 6, + [0][1][2][1][RTW89_THAILAND][1][12] = 44, + [0][1][2][1][RTW89_THAILAND][0][12] = -4, + [0][1][2][1][RTW89_FCC][1][14] = -4, + [0][1][2][1][RTW89_ETSI][1][14] = 42, + [0][1][2][1][RTW89_ETSI][0][14] = 6, + [0][1][2][1][RTW89_MKK][1][14] = 54, + [0][1][2][1][RTW89_MKK][0][14] = 16, + [0][1][2][1][RTW89_IC][1][14] = -4, + [0][1][2][1][RTW89_KCC][1][14] = 12, + [0][1][2][1][RTW89_KCC][0][14] = 12, + [0][1][2][1][RTW89_ACMA][1][14] = 42, + [0][1][2][1][RTW89_ACMA][0][14] = 6, + [0][1][2][1][RTW89_CHILE][1][14] = -4, + [0][1][2][1][RTW89_QATAR][1][14] = 42, + [0][1][2][1][RTW89_QATAR][0][14] = 6, + [0][1][2][1][RTW89_UK][1][14] = 42, + [0][1][2][1][RTW89_UK][0][14] = 6, + [0][1][2][1][RTW89_THAILAND][1][14] = 44, + [0][1][2][1][RTW89_THAILAND][0][14] = -4, + [0][1][2][1][RTW89_FCC][1][15] = -4, + [0][1][2][1][RTW89_ETSI][1][15] = 42, + [0][1][2][1][RTW89_ETSI][0][15] = 6, + [0][1][2][1][RTW89_MKK][1][15] = 54, + [0][1][2][1][RTW89_MKK][0][15] = 16, + [0][1][2][1][RTW89_IC][1][15] = -4, + [0][1][2][1][RTW89_KCC][1][15] = 12, + [0][1][2][1][RTW89_KCC][0][15] = 12, + [0][1][2][1][RTW89_ACMA][1][15] = 42, + [0][1][2][1][RTW89_ACMA][0][15] = 6, + [0][1][2][1][RTW89_CHILE][1][15] = -4, + [0][1][2][1][RTW89_QATAR][1][15] = 42, + [0][1][2][1][RTW89_QATAR][0][15] = 6, + [0][1][2][1][RTW89_UK][1][15] = 42, + [0][1][2][1][RTW89_UK][0][15] = 6, + [0][1][2][1][RTW89_THAILAND][1][15] = 44, + [0][1][2][1][RTW89_THAILAND][0][15] = -4, + [0][1][2][1][RTW89_FCC][1][17] = -4, + [0][1][2][1][RTW89_ETSI][1][17] = 42, + [0][1][2][1][RTW89_ETSI][0][17] = 6, + [0][1][2][1][RTW89_MKK][1][17] = 54, + [0][1][2][1][RTW89_MKK][0][17] = 16, + [0][1][2][1][RTW89_IC][1][17] = -4, + [0][1][2][1][RTW89_KCC][1][17] = 12, + [0][1][2][1][RTW89_KCC][0][17] = 12, + [0][1][2][1][RTW89_ACMA][1][17] = 42, + [0][1][2][1][RTW89_ACMA][0][17] = 6, + [0][1][2][1][RTW89_CHILE][1][17] = -4, + [0][1][2][1][RTW89_QATAR][1][17] = 42, + [0][1][2][1][RTW89_QATAR][0][17] = 6, + [0][1][2][1][RTW89_UK][1][17] = 42, + [0][1][2][1][RTW89_UK][0][17] = 6, + [0][1][2][1][RTW89_THAILAND][1][17] = 44, + [0][1][2][1][RTW89_THAILAND][0][17] = -4, + [0][1][2][1][RTW89_FCC][1][19] = -4, + [0][1][2][1][RTW89_ETSI][1][19] = 42, + [0][1][2][1][RTW89_ETSI][0][19] = 6, + [0][1][2][1][RTW89_MKK][1][19] = 54, + [0][1][2][1][RTW89_MKK][0][19] = 16, + [0][1][2][1][RTW89_IC][1][19] = -4, + [0][1][2][1][RTW89_KCC][1][19] = 12, + [0][1][2][1][RTW89_KCC][0][19] = 12, + [0][1][2][1][RTW89_ACMA][1][19] = 42, + [0][1][2][1][RTW89_ACMA][0][19] = 6, + [0][1][2][1][RTW89_CHILE][1][19] = -4, + [0][1][2][1][RTW89_QATAR][1][19] = 42, + [0][1][2][1][RTW89_QATAR][0][19] = 6, + [0][1][2][1][RTW89_UK][1][19] = 42, + [0][1][2][1][RTW89_UK][0][19] = 6, + [0][1][2][1][RTW89_THAILAND][1][19] = 44, + [0][1][2][1][RTW89_THAILAND][0][19] = -4, + [0][1][2][1][RTW89_FCC][1][21] = -4, + [0][1][2][1][RTW89_ETSI][1][21] = 42, + [0][1][2][1][RTW89_ETSI][0][21] = 6, + [0][1][2][1][RTW89_MKK][1][21] = 54, + [0][1][2][1][RTW89_MKK][0][21] = 16, + [0][1][2][1][RTW89_IC][1][21] = -4, + [0][1][2][1][RTW89_KCC][1][21] = 12, + [0][1][2][1][RTW89_KCC][0][21] = 12, + [0][1][2][1][RTW89_ACMA][1][21] = 42, + [0][1][2][1][RTW89_ACMA][0][21] = 6, + [0][1][2][1][RTW89_CHILE][1][21] = -4, + [0][1][2][1][RTW89_QATAR][1][21] = 42, + [0][1][2][1][RTW89_QATAR][0][21] = 6, + [0][1][2][1][RTW89_UK][1][21] = 42, + [0][1][2][1][RTW89_UK][0][21] = 6, + [0][1][2][1][RTW89_THAILAND][1][21] = 44, + [0][1][2][1][RTW89_THAILAND][0][21] = -4, + [0][1][2][1][RTW89_FCC][1][23] = -4, + [0][1][2][1][RTW89_ETSI][1][23] = 42, + [0][1][2][1][RTW89_ETSI][0][23] = 6, + [0][1][2][1][RTW89_MKK][1][23] = 54, + [0][1][2][1][RTW89_MKK][0][23] = 16, + [0][1][2][1][RTW89_IC][1][23] = -4, + [0][1][2][1][RTW89_KCC][1][23] = 12, + [0][1][2][1][RTW89_KCC][0][23] = 10, + [0][1][2][1][RTW89_ACMA][1][23] = 42, + [0][1][2][1][RTW89_ACMA][0][23] = 6, + [0][1][2][1][RTW89_CHILE][1][23] = -4, + [0][1][2][1][RTW89_QATAR][1][23] = 42, + [0][1][2][1][RTW89_QATAR][0][23] = 6, + [0][1][2][1][RTW89_UK][1][23] = 42, + [0][1][2][1][RTW89_UK][0][23] = 6, + [0][1][2][1][RTW89_THAILAND][1][23] = 44, + [0][1][2][1][RTW89_THAILAND][0][23] = -4, + [0][1][2][1][RTW89_FCC][1][25] = -4, + [0][1][2][1][RTW89_ETSI][1][25] = 42, + [0][1][2][1][RTW89_ETSI][0][25] = 6, + [0][1][2][1][RTW89_MKK][1][25] = 54, + [0][1][2][1][RTW89_MKK][0][25] = 16, + [0][1][2][1][RTW89_IC][1][25] = -4, + [0][1][2][1][RTW89_KCC][1][25] = 12, + [0][1][2][1][RTW89_KCC][0][25] = 14, + [0][1][2][1][RTW89_ACMA][1][25] = 42, + [0][1][2][1][RTW89_ACMA][0][25] = 6, + [0][1][2][1][RTW89_CHILE][1][25] = -4, + [0][1][2][1][RTW89_QATAR][1][25] = 42, + [0][1][2][1][RTW89_QATAR][0][25] = 6, + [0][1][2][1][RTW89_UK][1][25] = 42, + [0][1][2][1][RTW89_UK][0][25] = 6, + [0][1][2][1][RTW89_THAILAND][1][25] = 42, + [0][1][2][1][RTW89_THAILAND][0][25] = -4, + [0][1][2][1][RTW89_FCC][1][27] = -4, + [0][1][2][1][RTW89_ETSI][1][27] = 42, + [0][1][2][1][RTW89_ETSI][0][27] = 6, + [0][1][2][1][RTW89_MKK][1][27] = 54, + [0][1][2][1][RTW89_MKK][0][27] = 16, + [0][1][2][1][RTW89_IC][1][27] = -4, + [0][1][2][1][RTW89_KCC][1][27] = 12, + [0][1][2][1][RTW89_KCC][0][27] = 14, + [0][1][2][1][RTW89_ACMA][1][27] = 42, + [0][1][2][1][RTW89_ACMA][0][27] = 6, + [0][1][2][1][RTW89_CHILE][1][27] = -4, + [0][1][2][1][RTW89_QATAR][1][27] = 42, + [0][1][2][1][RTW89_QATAR][0][27] = 6, + [0][1][2][1][RTW89_UK][1][27] = 42, + [0][1][2][1][RTW89_UK][0][27] = 6, + [0][1][2][1][RTW89_THAILAND][1][27] = 42, + [0][1][2][1][RTW89_THAILAND][0][27] = -4, + [0][1][2][1][RTW89_FCC][1][29] = -4, + [0][1][2][1][RTW89_ETSI][1][29] = 42, + [0][1][2][1][RTW89_ETSI][0][29] = 6, + [0][1][2][1][RTW89_MKK][1][29] = 54, + [0][1][2][1][RTW89_MKK][0][29] = 16, + [0][1][2][1][RTW89_IC][1][29] = -4, + [0][1][2][1][RTW89_KCC][1][29] = 12, + [0][1][2][1][RTW89_KCC][0][29] = 14, + [0][1][2][1][RTW89_ACMA][1][29] = 42, + [0][1][2][1][RTW89_ACMA][0][29] = 6, + [0][1][2][1][RTW89_CHILE][1][29] = -4, + [0][1][2][1][RTW89_QATAR][1][29] = 42, + [0][1][2][1][RTW89_QATAR][0][29] = 6, + [0][1][2][1][RTW89_UK][1][29] = 42, + [0][1][2][1][RTW89_UK][0][29] = 6, + [0][1][2][1][RTW89_THAILAND][1][29] = 42, + [0][1][2][1][RTW89_THAILAND][0][29] = -4, + [0][1][2][1][RTW89_FCC][1][30] = -4, + [0][1][2][1][RTW89_ETSI][1][30] = 42, + [0][1][2][1][RTW89_ETSI][0][30] = 6, + [0][1][2][1][RTW89_MKK][1][30] = 54, + [0][1][2][1][RTW89_MKK][0][30] = 16, + [0][1][2][1][RTW89_IC][1][30] = -4, + [0][1][2][1][RTW89_KCC][1][30] = 12, + [0][1][2][1][RTW89_KCC][0][30] = 14, + [0][1][2][1][RTW89_ACMA][1][30] = 42, + [0][1][2][1][RTW89_ACMA][0][30] = 6, + [0][1][2][1][RTW89_CHILE][1][30] = -4, + [0][1][2][1][RTW89_QATAR][1][30] = 42, + [0][1][2][1][RTW89_QATAR][0][30] = 6, + [0][1][2][1][RTW89_UK][1][30] = 42, + [0][1][2][1][RTW89_UK][0][30] = 6, + [0][1][2][1][RTW89_THAILAND][1][30] = 42, + [0][1][2][1][RTW89_THAILAND][0][30] = -4, + [0][1][2][1][RTW89_FCC][1][32] = -4, + [0][1][2][1][RTW89_ETSI][1][32] = 42, + [0][1][2][1][RTW89_ETSI][0][32] = 6, + [0][1][2][1][RTW89_MKK][1][32] = 54, + [0][1][2][1][RTW89_MKK][0][32] = 16, + [0][1][2][1][RTW89_IC][1][32] = -4, + [0][1][2][1][RTW89_KCC][1][32] = 12, + [0][1][2][1][RTW89_KCC][0][32] = 14, + [0][1][2][1][RTW89_ACMA][1][32] = 42, + [0][1][2][1][RTW89_ACMA][0][32] = 6, + [0][1][2][1][RTW89_CHILE][1][32] = -4, + [0][1][2][1][RTW89_QATAR][1][32] = 42, + [0][1][2][1][RTW89_QATAR][0][32] = 6, + [0][1][2][1][RTW89_UK][1][32] = 42, + [0][1][2][1][RTW89_UK][0][32] = 6, + [0][1][2][1][RTW89_THAILAND][1][32] = 42, + [0][1][2][1][RTW89_THAILAND][0][32] = -4, + [0][1][2][1][RTW89_FCC][1][34] = -4, + [0][1][2][1][RTW89_ETSI][1][34] = 42, + [0][1][2][1][RTW89_ETSI][0][34] = 6, + [0][1][2][1][RTW89_MKK][1][34] = 54, + [0][1][2][1][RTW89_MKK][0][34] = 16, + [0][1][2][1][RTW89_IC][1][34] = -4, + [0][1][2][1][RTW89_KCC][1][34] = 12, + [0][1][2][1][RTW89_KCC][0][34] = 14, + [0][1][2][1][RTW89_ACMA][1][34] = 42, + [0][1][2][1][RTW89_ACMA][0][34] = 6, + [0][1][2][1][RTW89_CHILE][1][34] = -4, + [0][1][2][1][RTW89_QATAR][1][34] = 42, + [0][1][2][1][RTW89_QATAR][0][34] = 6, + [0][1][2][1][RTW89_UK][1][34] = 42, + [0][1][2][1][RTW89_UK][0][34] = 6, + [0][1][2][1][RTW89_THAILAND][1][34] = 42, + [0][1][2][1][RTW89_THAILAND][0][34] = -4, + [0][1][2][1][RTW89_FCC][1][36] = -4, + [0][1][2][1][RTW89_ETSI][1][36] = 42, + [0][1][2][1][RTW89_ETSI][0][36] = 6, + [0][1][2][1][RTW89_MKK][1][36] = 54, + [0][1][2][1][RTW89_MKK][0][36] = 16, + [0][1][2][1][RTW89_IC][1][36] = -4, + [0][1][2][1][RTW89_KCC][1][36] = 12, + [0][1][2][1][RTW89_KCC][0][36] = 14, + [0][1][2][1][RTW89_ACMA][1][36] = 42, + [0][1][2][1][RTW89_ACMA][0][36] = 6, + [0][1][2][1][RTW89_CHILE][1][36] = -4, + [0][1][2][1][RTW89_QATAR][1][36] = 42, + [0][1][2][1][RTW89_QATAR][0][36] = 6, + [0][1][2][1][RTW89_UK][1][36] = 42, + [0][1][2][1][RTW89_UK][0][36] = 6, + [0][1][2][1][RTW89_THAILAND][1][36] = 42, + [0][1][2][1][RTW89_THAILAND][0][36] = -4, + [0][1][2][1][RTW89_FCC][1][38] = -4, + [0][1][2][1][RTW89_ETSI][1][38] = 42, + [0][1][2][1][RTW89_ETSI][0][38] = 6, + [0][1][2][1][RTW89_MKK][1][38] = 54, + [0][1][2][1][RTW89_MKK][0][38] = 16, + [0][1][2][1][RTW89_IC][1][38] = -4, + [0][1][2][1][RTW89_KCC][1][38] = 12, + [0][1][2][1][RTW89_KCC][0][38] = 14, + [0][1][2][1][RTW89_ACMA][1][38] = 42, + [0][1][2][1][RTW89_ACMA][0][38] = 6, + [0][1][2][1][RTW89_CHILE][1][38] = -4, + [0][1][2][1][RTW89_QATAR][1][38] = 42, + [0][1][2][1][RTW89_QATAR][0][38] = 6, + [0][1][2][1][RTW89_UK][1][38] = 42, + [0][1][2][1][RTW89_UK][0][38] = 6, + [0][1][2][1][RTW89_THAILAND][1][38] = 42, + [0][1][2][1][RTW89_THAILAND][0][38] = -4, + [0][1][2][1][RTW89_FCC][1][40] = -4, + [0][1][2][1][RTW89_ETSI][1][40] = 42, + [0][1][2][1][RTW89_ETSI][0][40] = 6, + [0][1][2][1][RTW89_MKK][1][40] = 54, + [0][1][2][1][RTW89_MKK][0][40] = 16, + [0][1][2][1][RTW89_IC][1][40] = -4, + [0][1][2][1][RTW89_KCC][1][40] = 12, + [0][1][2][1][RTW89_KCC][0][40] = 14, + [0][1][2][1][RTW89_ACMA][1][40] = 42, + [0][1][2][1][RTW89_ACMA][0][40] = 6, + [0][1][2][1][RTW89_CHILE][1][40] = -4, + [0][1][2][1][RTW89_QATAR][1][40] = 42, + [0][1][2][1][RTW89_QATAR][0][40] = 6, + [0][1][2][1][RTW89_UK][1][40] = 42, + [0][1][2][1][RTW89_UK][0][40] = 6, + [0][1][2][1][RTW89_THAILAND][1][40] = 42, + [0][1][2][1][RTW89_THAILAND][0][40] = -4, + [0][1][2][1][RTW89_FCC][1][42] = -4, + [0][1][2][1][RTW89_ETSI][1][42] = 42, + [0][1][2][1][RTW89_ETSI][0][42] = 6, + [0][1][2][1][RTW89_MKK][1][42] = 54, + [0][1][2][1][RTW89_MKK][0][42] = 16, + [0][1][2][1][RTW89_IC][1][42] = -4, + [0][1][2][1][RTW89_KCC][1][42] = 12, + [0][1][2][1][RTW89_KCC][0][42] = 14, + [0][1][2][1][RTW89_ACMA][1][42] = 42, + [0][1][2][1][RTW89_ACMA][0][42] = 6, + [0][1][2][1][RTW89_CHILE][1][42] = -4, + [0][1][2][1][RTW89_QATAR][1][42] = 42, + [0][1][2][1][RTW89_QATAR][0][42] = 6, + [0][1][2][1][RTW89_UK][1][42] = 42, + [0][1][2][1][RTW89_UK][0][42] = 6, + [0][1][2][1][RTW89_THAILAND][1][42] = 42, + [0][1][2][1][RTW89_THAILAND][0][42] = -4, + [0][1][2][1][RTW89_FCC][1][44] = -2, + [0][1][2][1][RTW89_ETSI][1][44] = 42, + [0][1][2][1][RTW89_ETSI][0][44] = 6, + [0][1][2][1][RTW89_MKK][1][44] = 34, + [0][1][2][1][RTW89_MKK][0][44] = 16, + [0][1][2][1][RTW89_IC][1][44] = -2, + [0][1][2][1][RTW89_KCC][1][44] = 12, + [0][1][2][1][RTW89_KCC][0][44] = 12, + [0][1][2][1][RTW89_ACMA][1][44] = 42, + [0][1][2][1][RTW89_ACMA][0][44] = 6, + [0][1][2][1][RTW89_CHILE][1][44] = -2, + [0][1][2][1][RTW89_QATAR][1][44] = 42, + [0][1][2][1][RTW89_QATAR][0][44] = 6, + [0][1][2][1][RTW89_UK][1][44] = 42, + [0][1][2][1][RTW89_UK][0][44] = 6, + [0][1][2][1][RTW89_THAILAND][1][44] = 42, + [0][1][2][1][RTW89_THAILAND][0][44] = -2, + [0][1][2][1][RTW89_FCC][1][45] = -2, + [0][1][2][1][RTW89_ETSI][1][45] = 127, + [0][1][2][1][RTW89_ETSI][0][45] = 127, + [0][1][2][1][RTW89_MKK][1][45] = 127, + [0][1][2][1][RTW89_MKK][0][45] = 127, + [0][1][2][1][RTW89_IC][1][45] = -2, + [0][1][2][1][RTW89_KCC][1][45] = 12, + [0][1][2][1][RTW89_KCC][0][45] = 127, + [0][1][2][1][RTW89_ACMA][1][45] = 127, + [0][1][2][1][RTW89_ACMA][0][45] = 127, + [0][1][2][1][RTW89_CHILE][1][45] = -2, + [0][1][2][1][RTW89_QATAR][1][45] = 127, + [0][1][2][1][RTW89_QATAR][0][45] = 127, + [0][1][2][1][RTW89_UK][1][45] = 127, + [0][1][2][1][RTW89_UK][0][45] = 127, + [0][1][2][1][RTW89_THAILAND][1][45] = 127, + [0][1][2][1][RTW89_THAILAND][0][45] = 127, + [0][1][2][1][RTW89_FCC][1][47] = -2, + [0][1][2][1][RTW89_ETSI][1][47] = 127, + [0][1][2][1][RTW89_ETSI][0][47] = 127, + [0][1][2][1][RTW89_MKK][1][47] = 127, + [0][1][2][1][RTW89_MKK][0][47] = 127, + [0][1][2][1][RTW89_IC][1][47] = -2, + [0][1][2][1][RTW89_KCC][1][47] = 12, + [0][1][2][1][RTW89_KCC][0][47] = 127, + [0][1][2][1][RTW89_ACMA][1][47] = 127, + [0][1][2][1][RTW89_ACMA][0][47] = 127, + [0][1][2][1][RTW89_CHILE][1][47] = -2, + [0][1][2][1][RTW89_QATAR][1][47] = 127, + [0][1][2][1][RTW89_QATAR][0][47] = 127, + [0][1][2][1][RTW89_UK][1][47] = 127, + [0][1][2][1][RTW89_UK][0][47] = 127, + [0][1][2][1][RTW89_THAILAND][1][47] = 127, + [0][1][2][1][RTW89_THAILAND][0][47] = 127, + [0][1][2][1][RTW89_FCC][1][49] = -2, + [0][1][2][1][RTW89_ETSI][1][49] = 127, + [0][1][2][1][RTW89_ETSI][0][49] = 127, + [0][1][2][1][RTW89_MKK][1][49] = 127, + [0][1][2][1][RTW89_MKK][0][49] = 127, + [0][1][2][1][RTW89_IC][1][49] = -2, + [0][1][2][1][RTW89_KCC][1][49] = 12, + [0][1][2][1][RTW89_KCC][0][49] = 127, + [0][1][2][1][RTW89_ACMA][1][49] = 127, + [0][1][2][1][RTW89_ACMA][0][49] = 127, + [0][1][2][1][RTW89_CHILE][1][49] = -2, + [0][1][2][1][RTW89_QATAR][1][49] = 127, + [0][1][2][1][RTW89_QATAR][0][49] = 127, + [0][1][2][1][RTW89_UK][1][49] = 127, + [0][1][2][1][RTW89_UK][0][49] = 127, + [0][1][2][1][RTW89_THAILAND][1][49] = 127, + [0][1][2][1][RTW89_THAILAND][0][49] = 127, + [0][1][2][1][RTW89_FCC][1][51] = -2, + [0][1][2][1][RTW89_ETSI][1][51] = 127, + [0][1][2][1][RTW89_ETSI][0][51] = 127, + [0][1][2][1][RTW89_MKK][1][51] = 127, + [0][1][2][1][RTW89_MKK][0][51] = 127, + [0][1][2][1][RTW89_IC][1][51] = -2, + [0][1][2][1][RTW89_KCC][1][51] = 12, + [0][1][2][1][RTW89_KCC][0][51] = 127, + [0][1][2][1][RTW89_ACMA][1][51] = 127, + [0][1][2][1][RTW89_ACMA][0][51] = 127, + [0][1][2][1][RTW89_CHILE][1][51] = -2, + [0][1][2][1][RTW89_QATAR][1][51] = 127, + [0][1][2][1][RTW89_QATAR][0][51] = 127, + [0][1][2][1][RTW89_UK][1][51] = 127, + [0][1][2][1][RTW89_UK][0][51] = 127, + [0][1][2][1][RTW89_THAILAND][1][51] = 127, + [0][1][2][1][RTW89_THAILAND][0][51] = 127, + [0][1][2][1][RTW89_FCC][1][53] = -2, + [0][1][2][1][RTW89_ETSI][1][53] = 127, + [0][1][2][1][RTW89_ETSI][0][53] = 127, + [0][1][2][1][RTW89_MKK][1][53] = 127, + [0][1][2][1][RTW89_MKK][0][53] = 127, + [0][1][2][1][RTW89_IC][1][53] = -2, + [0][1][2][1][RTW89_KCC][1][53] = 12, + [0][1][2][1][RTW89_KCC][0][53] = 127, + [0][1][2][1][RTW89_ACMA][1][53] = 127, + [0][1][2][1][RTW89_ACMA][0][53] = 127, + [0][1][2][1][RTW89_CHILE][1][53] = -2, + [0][1][2][1][RTW89_QATAR][1][53] = 127, + [0][1][2][1][RTW89_QATAR][0][53] = 127, + [0][1][2][1][RTW89_UK][1][53] = 127, + [0][1][2][1][RTW89_UK][0][53] = 127, + [0][1][2][1][RTW89_THAILAND][1][53] = 127, + [0][1][2][1][RTW89_THAILAND][0][53] = 127, + [0][1][2][1][RTW89_FCC][1][55] = -2, + [0][1][2][1][RTW89_ETSI][1][55] = 127, + [0][1][2][1][RTW89_ETSI][0][55] = 127, + [0][1][2][1][RTW89_MKK][1][55] = 127, + [0][1][2][1][RTW89_MKK][0][55] = 127, + [0][1][2][1][RTW89_IC][1][55] = -2, + [0][1][2][1][RTW89_KCC][1][55] = 12, + [0][1][2][1][RTW89_KCC][0][55] = 127, + [0][1][2][1][RTW89_ACMA][1][55] = 127, + [0][1][2][1][RTW89_ACMA][0][55] = 127, + [0][1][2][1][RTW89_CHILE][1][55] = -2, + [0][1][2][1][RTW89_QATAR][1][55] = 127, + [0][1][2][1][RTW89_QATAR][0][55] = 127, + [0][1][2][1][RTW89_UK][1][55] = 127, + [0][1][2][1][RTW89_UK][0][55] = 127, + [0][1][2][1][RTW89_THAILAND][1][55] = 127, + [0][1][2][1][RTW89_THAILAND][0][55] = 127, + [0][1][2][1][RTW89_FCC][1][57] = -2, + [0][1][2][1][RTW89_ETSI][1][57] = 127, + [0][1][2][1][RTW89_ETSI][0][57] = 127, + [0][1][2][1][RTW89_MKK][1][57] = 127, + [0][1][2][1][RTW89_MKK][0][57] = 127, + [0][1][2][1][RTW89_IC][1][57] = -2, + [0][1][2][1][RTW89_KCC][1][57] = 12, + [0][1][2][1][RTW89_KCC][0][57] = 127, + [0][1][2][1][RTW89_ACMA][1][57] = 127, + [0][1][2][1][RTW89_ACMA][0][57] = 127, + [0][1][2][1][RTW89_CHILE][1][57] = -2, + [0][1][2][1][RTW89_QATAR][1][57] = 127, + [0][1][2][1][RTW89_QATAR][0][57] = 127, + [0][1][2][1][RTW89_UK][1][57] = 127, + [0][1][2][1][RTW89_UK][0][57] = 127, + [0][1][2][1][RTW89_THAILAND][1][57] = 127, + [0][1][2][1][RTW89_THAILAND][0][57] = 127, + [0][1][2][1][RTW89_FCC][1][59] = -2, + [0][1][2][1][RTW89_ETSI][1][59] = 127, + [0][1][2][1][RTW89_ETSI][0][59] = 127, + [0][1][2][1][RTW89_MKK][1][59] = 127, + [0][1][2][1][RTW89_MKK][0][59] = 127, + [0][1][2][1][RTW89_IC][1][59] = -2, + [0][1][2][1][RTW89_KCC][1][59] = 12, + [0][1][2][1][RTW89_KCC][0][59] = 127, + [0][1][2][1][RTW89_ACMA][1][59] = 127, + [0][1][2][1][RTW89_ACMA][0][59] = 127, + [0][1][2][1][RTW89_CHILE][1][59] = -2, + [0][1][2][1][RTW89_QATAR][1][59] = 127, + [0][1][2][1][RTW89_QATAR][0][59] = 127, + [0][1][2][1][RTW89_UK][1][59] = 127, + [0][1][2][1][RTW89_UK][0][59] = 127, + [0][1][2][1][RTW89_THAILAND][1][59] = 127, + [0][1][2][1][RTW89_THAILAND][0][59] = 127, + [0][1][2][1][RTW89_FCC][1][60] = -2, + [0][1][2][1][RTW89_ETSI][1][60] = 127, + [0][1][2][1][RTW89_ETSI][0][60] = 127, + [0][1][2][1][RTW89_MKK][1][60] = 127, + [0][1][2][1][RTW89_MKK][0][60] = 127, + [0][1][2][1][RTW89_IC][1][60] = -2, + [0][1][2][1][RTW89_KCC][1][60] = 12, + [0][1][2][1][RTW89_KCC][0][60] = 127, + [0][1][2][1][RTW89_ACMA][1][60] = 127, + [0][1][2][1][RTW89_ACMA][0][60] = 127, + [0][1][2][1][RTW89_CHILE][1][60] = -2, + [0][1][2][1][RTW89_QATAR][1][60] = 127, + [0][1][2][1][RTW89_QATAR][0][60] = 127, + [0][1][2][1][RTW89_UK][1][60] = 127, + [0][1][2][1][RTW89_UK][0][60] = 127, + [0][1][2][1][RTW89_THAILAND][1][60] = 127, + [0][1][2][1][RTW89_THAILAND][0][60] = 127, + [0][1][2][1][RTW89_FCC][1][62] = -2, + [0][1][2][1][RTW89_ETSI][1][62] = 127, + [0][1][2][1][RTW89_ETSI][0][62] = 127, + [0][1][2][1][RTW89_MKK][1][62] = 127, + [0][1][2][1][RTW89_MKK][0][62] = 127, + [0][1][2][1][RTW89_IC][1][62] = -2, + [0][1][2][1][RTW89_KCC][1][62] = 12, + [0][1][2][1][RTW89_KCC][0][62] = 127, + [0][1][2][1][RTW89_ACMA][1][62] = 127, + [0][1][2][1][RTW89_ACMA][0][62] = 127, + [0][1][2][1][RTW89_CHILE][1][62] = -2, + [0][1][2][1][RTW89_QATAR][1][62] = 127, + [0][1][2][1][RTW89_QATAR][0][62] = 127, + [0][1][2][1][RTW89_UK][1][62] = 127, + [0][1][2][1][RTW89_UK][0][62] = 127, + [0][1][2][1][RTW89_THAILAND][1][62] = 127, + [0][1][2][1][RTW89_THAILAND][0][62] = 127, + [0][1][2][1][RTW89_FCC][1][64] = -2, + [0][1][2][1][RTW89_ETSI][1][64] = 127, + [0][1][2][1][RTW89_ETSI][0][64] = 127, + [0][1][2][1][RTW89_MKK][1][64] = 127, + [0][1][2][1][RTW89_MKK][0][64] = 127, + [0][1][2][1][RTW89_IC][1][64] = -2, + [0][1][2][1][RTW89_KCC][1][64] = 12, + [0][1][2][1][RTW89_KCC][0][64] = 127, + [0][1][2][1][RTW89_ACMA][1][64] = 127, + [0][1][2][1][RTW89_ACMA][0][64] = 127, + [0][1][2][1][RTW89_CHILE][1][64] = -2, + [0][1][2][1][RTW89_QATAR][1][64] = 127, + [0][1][2][1][RTW89_QATAR][0][64] = 127, + [0][1][2][1][RTW89_UK][1][64] = 127, + [0][1][2][1][RTW89_UK][0][64] = 127, + [0][1][2][1][RTW89_THAILAND][1][64] = 127, + [0][1][2][1][RTW89_THAILAND][0][64] = 127, + [0][1][2][1][RTW89_FCC][1][66] = -2, + [0][1][2][1][RTW89_ETSI][1][66] = 127, + [0][1][2][1][RTW89_ETSI][0][66] = 127, + [0][1][2][1][RTW89_MKK][1][66] = 127, + [0][1][2][1][RTW89_MKK][0][66] = 127, + [0][1][2][1][RTW89_IC][1][66] = -2, + [0][1][2][1][RTW89_KCC][1][66] = 12, + [0][1][2][1][RTW89_KCC][0][66] = 127, + [0][1][2][1][RTW89_ACMA][1][66] = 127, + [0][1][2][1][RTW89_ACMA][0][66] = 127, + [0][1][2][1][RTW89_CHILE][1][66] = -2, + [0][1][2][1][RTW89_QATAR][1][66] = 127, + [0][1][2][1][RTW89_QATAR][0][66] = 127, + [0][1][2][1][RTW89_UK][1][66] = 127, + [0][1][2][1][RTW89_UK][0][66] = 127, + [0][1][2][1][RTW89_THAILAND][1][66] = 127, + [0][1][2][1][RTW89_THAILAND][0][66] = 127, + [0][1][2][1][RTW89_FCC][1][68] = -2, + [0][1][2][1][RTW89_ETSI][1][68] = 127, + [0][1][2][1][RTW89_ETSI][0][68] = 127, + [0][1][2][1][RTW89_MKK][1][68] = 127, + [0][1][2][1][RTW89_MKK][0][68] = 127, + [0][1][2][1][RTW89_IC][1][68] = -2, + [0][1][2][1][RTW89_KCC][1][68] = 12, + [0][1][2][1][RTW89_KCC][0][68] = 127, + [0][1][2][1][RTW89_ACMA][1][68] = 127, + [0][1][2][1][RTW89_ACMA][0][68] = 127, + [0][1][2][1][RTW89_CHILE][1][68] = -2, + [0][1][2][1][RTW89_QATAR][1][68] = 127, + [0][1][2][1][RTW89_QATAR][0][68] = 127, + [0][1][2][1][RTW89_UK][1][68] = 127, + [0][1][2][1][RTW89_UK][0][68] = 127, + [0][1][2][1][RTW89_THAILAND][1][68] = 127, + [0][1][2][1][RTW89_THAILAND][0][68] = 127, + [0][1][2][1][RTW89_FCC][1][70] = -2, + [0][1][2][1][RTW89_ETSI][1][70] = 127, + [0][1][2][1][RTW89_ETSI][0][70] = 127, + [0][1][2][1][RTW89_MKK][1][70] = 127, + [0][1][2][1][RTW89_MKK][0][70] = 127, + [0][1][2][1][RTW89_IC][1][70] = -2, + [0][1][2][1][RTW89_KCC][1][70] = 12, + [0][1][2][1][RTW89_KCC][0][70] = 127, + [0][1][2][1][RTW89_ACMA][1][70] = 127, + [0][1][2][1][RTW89_ACMA][0][70] = 127, + [0][1][2][1][RTW89_CHILE][1][70] = -2, + [0][1][2][1][RTW89_QATAR][1][70] = 127, + [0][1][2][1][RTW89_QATAR][0][70] = 127, + [0][1][2][1][RTW89_UK][1][70] = 127, + [0][1][2][1][RTW89_UK][0][70] = 127, + [0][1][2][1][RTW89_THAILAND][1][70] = 127, + [0][1][2][1][RTW89_THAILAND][0][70] = 127, + [0][1][2][1][RTW89_FCC][1][72] = -2, + [0][1][2][1][RTW89_ETSI][1][72] = 127, + [0][1][2][1][RTW89_ETSI][0][72] = 127, + [0][1][2][1][RTW89_MKK][1][72] = 127, + [0][1][2][1][RTW89_MKK][0][72] = 127, + [0][1][2][1][RTW89_IC][1][72] = -2, + [0][1][2][1][RTW89_KCC][1][72] = 12, + [0][1][2][1][RTW89_KCC][0][72] = 127, + [0][1][2][1][RTW89_ACMA][1][72] = 127, + [0][1][2][1][RTW89_ACMA][0][72] = 127, + [0][1][2][1][RTW89_CHILE][1][72] = -2, + [0][1][2][1][RTW89_QATAR][1][72] = 127, + [0][1][2][1][RTW89_QATAR][0][72] = 127, + [0][1][2][1][RTW89_UK][1][72] = 127, + [0][1][2][1][RTW89_UK][0][72] = 127, + [0][1][2][1][RTW89_THAILAND][1][72] = 127, + [0][1][2][1][RTW89_THAILAND][0][72] = 127, + [0][1][2][1][RTW89_FCC][1][74] = -2, + [0][1][2][1][RTW89_ETSI][1][74] = 127, + [0][1][2][1][RTW89_ETSI][0][74] = 127, + [0][1][2][1][RTW89_MKK][1][74] = 127, + [0][1][2][1][RTW89_MKK][0][74] = 127, + [0][1][2][1][RTW89_IC][1][74] = -2, + [0][1][2][1][RTW89_KCC][1][74] = 12, + [0][1][2][1][RTW89_KCC][0][74] = 127, + [0][1][2][1][RTW89_ACMA][1][74] = 127, + [0][1][2][1][RTW89_ACMA][0][74] = 127, + [0][1][2][1][RTW89_CHILE][1][74] = -2, + [0][1][2][1][RTW89_QATAR][1][74] = 127, + [0][1][2][1][RTW89_QATAR][0][74] = 127, + [0][1][2][1][RTW89_UK][1][74] = 127, + [0][1][2][1][RTW89_UK][0][74] = 127, + [0][1][2][1][RTW89_THAILAND][1][74] = 127, + [0][1][2][1][RTW89_THAILAND][0][74] = 127, + [0][1][2][1][RTW89_FCC][1][75] = -2, + [0][1][2][1][RTW89_ETSI][1][75] = 127, + [0][1][2][1][RTW89_ETSI][0][75] = 127, + [0][1][2][1][RTW89_MKK][1][75] = 127, + [0][1][2][1][RTW89_MKK][0][75] = 127, + [0][1][2][1][RTW89_IC][1][75] = -2, + [0][1][2][1][RTW89_KCC][1][75] = 12, + [0][1][2][1][RTW89_KCC][0][75] = 127, + [0][1][2][1][RTW89_ACMA][1][75] = 127, + [0][1][2][1][RTW89_ACMA][0][75] = 127, + [0][1][2][1][RTW89_CHILE][1][75] = -2, + [0][1][2][1][RTW89_QATAR][1][75] = 127, + [0][1][2][1][RTW89_QATAR][0][75] = 127, + [0][1][2][1][RTW89_UK][1][75] = 127, + [0][1][2][1][RTW89_UK][0][75] = 127, + [0][1][2][1][RTW89_THAILAND][1][75] = 127, + [0][1][2][1][RTW89_THAILAND][0][75] = 127, + [0][1][2][1][RTW89_FCC][1][77] = -2, + [0][1][2][1][RTW89_ETSI][1][77] = 127, + [0][1][2][1][RTW89_ETSI][0][77] = 127, + [0][1][2][1][RTW89_MKK][1][77] = 127, + [0][1][2][1][RTW89_MKK][0][77] = 127, + [0][1][2][1][RTW89_IC][1][77] = -2, + [0][1][2][1][RTW89_KCC][1][77] = 12, + [0][1][2][1][RTW89_KCC][0][77] = 127, + [0][1][2][1][RTW89_ACMA][1][77] = 127, + [0][1][2][1][RTW89_ACMA][0][77] = 127, + [0][1][2][1][RTW89_CHILE][1][77] = -2, + [0][1][2][1][RTW89_QATAR][1][77] = 127, + [0][1][2][1][RTW89_QATAR][0][77] = 127, + [0][1][2][1][RTW89_UK][1][77] = 127, + [0][1][2][1][RTW89_UK][0][77] = 127, + [0][1][2][1][RTW89_THAILAND][1][77] = 127, + [0][1][2][1][RTW89_THAILAND][0][77] = 127, + [0][1][2][1][RTW89_FCC][1][79] = -2, + [0][1][2][1][RTW89_ETSI][1][79] = 127, + [0][1][2][1][RTW89_ETSI][0][79] = 127, + [0][1][2][1][RTW89_MKK][1][79] = 127, + [0][1][2][1][RTW89_MKK][0][79] = 127, + [0][1][2][1][RTW89_IC][1][79] = -2, + [0][1][2][1][RTW89_KCC][1][79] = 12, + [0][1][2][1][RTW89_KCC][0][79] = 127, + [0][1][2][1][RTW89_ACMA][1][79] = 127, + [0][1][2][1][RTW89_ACMA][0][79] = 127, + [0][1][2][1][RTW89_CHILE][1][79] = -2, + [0][1][2][1][RTW89_QATAR][1][79] = 127, + [0][1][2][1][RTW89_QATAR][0][79] = 127, + [0][1][2][1][RTW89_UK][1][79] = 127, + [0][1][2][1][RTW89_UK][0][79] = 127, + [0][1][2][1][RTW89_THAILAND][1][79] = 127, + [0][1][2][1][RTW89_THAILAND][0][79] = 127, + [0][1][2][1][RTW89_FCC][1][81] = -2, + [0][1][2][1][RTW89_ETSI][1][81] = 127, + [0][1][2][1][RTW89_ETSI][0][81] = 127, + [0][1][2][1][RTW89_MKK][1][81] = 127, + [0][1][2][1][RTW89_MKK][0][81] = 127, + [0][1][2][1][RTW89_IC][1][81] = -2, + [0][1][2][1][RTW89_KCC][1][81] = 12, + [0][1][2][1][RTW89_KCC][0][81] = 127, + [0][1][2][1][RTW89_ACMA][1][81] = 127, + [0][1][2][1][RTW89_ACMA][0][81] = 127, + [0][1][2][1][RTW89_CHILE][1][81] = -2, + [0][1][2][1][RTW89_QATAR][1][81] = 127, + [0][1][2][1][RTW89_QATAR][0][81] = 127, + [0][1][2][1][RTW89_UK][1][81] = 127, + [0][1][2][1][RTW89_UK][0][81] = 127, + [0][1][2][1][RTW89_THAILAND][1][81] = 127, + [0][1][2][1][RTW89_THAILAND][0][81] = 127, + [0][1][2][1][RTW89_FCC][1][83] = -2, + [0][1][2][1][RTW89_ETSI][1][83] = 127, + [0][1][2][1][RTW89_ETSI][0][83] = 127, + [0][1][2][1][RTW89_MKK][1][83] = 127, + [0][1][2][1][RTW89_MKK][0][83] = 127, + [0][1][2][1][RTW89_IC][1][83] = -2, + [0][1][2][1][RTW89_KCC][1][83] = 20, + [0][1][2][1][RTW89_KCC][0][83] = 127, + [0][1][2][1][RTW89_ACMA][1][83] = 127, + [0][1][2][1][RTW89_ACMA][0][83] = 127, + [0][1][2][1][RTW89_CHILE][1][83] = -2, + [0][1][2][1][RTW89_QATAR][1][83] = 127, + [0][1][2][1][RTW89_QATAR][0][83] = 127, + [0][1][2][1][RTW89_UK][1][83] = 127, + [0][1][2][1][RTW89_UK][0][83] = 127, + [0][1][2][1][RTW89_THAILAND][1][83] = 127, + [0][1][2][1][RTW89_THAILAND][0][83] = 127, + [0][1][2][1][RTW89_FCC][1][85] = -2, + [0][1][2][1][RTW89_ETSI][1][85] = 127, + [0][1][2][1][RTW89_ETSI][0][85] = 127, + [0][1][2][1][RTW89_MKK][1][85] = 127, + [0][1][2][1][RTW89_MKK][0][85] = 127, + [0][1][2][1][RTW89_IC][1][85] = -2, + [0][1][2][1][RTW89_KCC][1][85] = 20, + [0][1][2][1][RTW89_KCC][0][85] = 127, + [0][1][2][1][RTW89_ACMA][1][85] = 127, + [0][1][2][1][RTW89_ACMA][0][85] = 127, + [0][1][2][1][RTW89_CHILE][1][85] = -2, + [0][1][2][1][RTW89_QATAR][1][85] = 127, + [0][1][2][1][RTW89_QATAR][0][85] = 127, + [0][1][2][1][RTW89_UK][1][85] = 127, + [0][1][2][1][RTW89_UK][0][85] = 127, + [0][1][2][1][RTW89_THAILAND][1][85] = 127, + [0][1][2][1][RTW89_THAILAND][0][85] = 127, + [0][1][2][1][RTW89_FCC][1][87] = -2, + [0][1][2][1][RTW89_ETSI][1][87] = 127, + [0][1][2][1][RTW89_ETSI][0][87] = 127, + [0][1][2][1][RTW89_MKK][1][87] = 127, + [0][1][2][1][RTW89_MKK][0][87] = 127, + [0][1][2][1][RTW89_IC][1][87] = -2, + [0][1][2][1][RTW89_KCC][1][87] = 20, + [0][1][2][1][RTW89_KCC][0][87] = 127, + [0][1][2][1][RTW89_ACMA][1][87] = 127, + [0][1][2][1][RTW89_ACMA][0][87] = 127, + [0][1][2][1][RTW89_CHILE][1][87] = -2, + [0][1][2][1][RTW89_QATAR][1][87] = 127, + [0][1][2][1][RTW89_QATAR][0][87] = 127, + [0][1][2][1][RTW89_UK][1][87] = 127, + [0][1][2][1][RTW89_UK][0][87] = 127, + [0][1][2][1][RTW89_THAILAND][1][87] = 127, + [0][1][2][1][RTW89_THAILAND][0][87] = 127, + [0][1][2][1][RTW89_FCC][1][89] = -2, + [0][1][2][1][RTW89_ETSI][1][89] = 127, + [0][1][2][1][RTW89_ETSI][0][89] = 127, + [0][1][2][1][RTW89_MKK][1][89] = 127, + [0][1][2][1][RTW89_MKK][0][89] = 127, + [0][1][2][1][RTW89_IC][1][89] = -2, + [0][1][2][1][RTW89_KCC][1][89] = 20, + [0][1][2][1][RTW89_KCC][0][89] = 127, + [0][1][2][1][RTW89_ACMA][1][89] = 127, + [0][1][2][1][RTW89_ACMA][0][89] = 127, + [0][1][2][1][RTW89_CHILE][1][89] = -2, + [0][1][2][1][RTW89_QATAR][1][89] = 127, + [0][1][2][1][RTW89_QATAR][0][89] = 127, + [0][1][2][1][RTW89_UK][1][89] = 127, + [0][1][2][1][RTW89_UK][0][89] = 127, + [0][1][2][1][RTW89_THAILAND][1][89] = 127, + [0][1][2][1][RTW89_THAILAND][0][89] = 127, + [0][1][2][1][RTW89_FCC][1][90] = -2, + [0][1][2][1][RTW89_ETSI][1][90] = 127, + [0][1][2][1][RTW89_ETSI][0][90] = 127, + [0][1][2][1][RTW89_MKK][1][90] = 127, + [0][1][2][1][RTW89_MKK][0][90] = 127, + [0][1][2][1][RTW89_IC][1][90] = -2, + [0][1][2][1][RTW89_KCC][1][90] = 20, + [0][1][2][1][RTW89_KCC][0][90] = 127, + [0][1][2][1][RTW89_ACMA][1][90] = 127, + [0][1][2][1][RTW89_ACMA][0][90] = 127, + [0][1][2][1][RTW89_CHILE][1][90] = -2, + [0][1][2][1][RTW89_QATAR][1][90] = 127, + [0][1][2][1][RTW89_QATAR][0][90] = 127, + [0][1][2][1][RTW89_UK][1][90] = 127, + [0][1][2][1][RTW89_UK][0][90] = 127, + [0][1][2][1][RTW89_THAILAND][1][90] = 127, + [0][1][2][1][RTW89_THAILAND][0][90] = 127, + [0][1][2][1][RTW89_FCC][1][92] = -2, + [0][1][2][1][RTW89_ETSI][1][92] = 127, + [0][1][2][1][RTW89_ETSI][0][92] = 127, + [0][1][2][1][RTW89_MKK][1][92] = 127, + [0][1][2][1][RTW89_MKK][0][92] = 127, + [0][1][2][1][RTW89_IC][1][92] = -2, + [0][1][2][1][RTW89_KCC][1][92] = 20, + [0][1][2][1][RTW89_KCC][0][92] = 127, + [0][1][2][1][RTW89_ACMA][1][92] = 127, + [0][1][2][1][RTW89_ACMA][0][92] = 127, + [0][1][2][1][RTW89_CHILE][1][92] = -2, + [0][1][2][1][RTW89_QATAR][1][92] = 127, + [0][1][2][1][RTW89_QATAR][0][92] = 127, + [0][1][2][1][RTW89_UK][1][92] = 127, + [0][1][2][1][RTW89_UK][0][92] = 127, + [0][1][2][1][RTW89_THAILAND][1][92] = 127, + [0][1][2][1][RTW89_THAILAND][0][92] = 127, + [0][1][2][1][RTW89_FCC][1][94] = -2, + [0][1][2][1][RTW89_ETSI][1][94] = 127, + [0][1][2][1][RTW89_ETSI][0][94] = 127, + [0][1][2][1][RTW89_MKK][1][94] = 127, + [0][1][2][1][RTW89_MKK][0][94] = 127, + [0][1][2][1][RTW89_IC][1][94] = -2, + [0][1][2][1][RTW89_KCC][1][94] = 20, + [0][1][2][1][RTW89_KCC][0][94] = 127, + [0][1][2][1][RTW89_ACMA][1][94] = 127, + [0][1][2][1][RTW89_ACMA][0][94] = 127, + [0][1][2][1][RTW89_CHILE][1][94] = -2, + [0][1][2][1][RTW89_QATAR][1][94] = 127, + [0][1][2][1][RTW89_QATAR][0][94] = 127, + [0][1][2][1][RTW89_UK][1][94] = 127, + [0][1][2][1][RTW89_UK][0][94] = 127, + [0][1][2][1][RTW89_THAILAND][1][94] = 127, + [0][1][2][1][RTW89_THAILAND][0][94] = 127, + [0][1][2][1][RTW89_FCC][1][96] = -2, + [0][1][2][1][RTW89_ETSI][1][96] = 127, + [0][1][2][1][RTW89_ETSI][0][96] = 127, + [0][1][2][1][RTW89_MKK][1][96] = 127, + [0][1][2][1][RTW89_MKK][0][96] = 127, + [0][1][2][1][RTW89_IC][1][96] = -2, + [0][1][2][1][RTW89_KCC][1][96] = 20, + [0][1][2][1][RTW89_KCC][0][96] = 127, + [0][1][2][1][RTW89_ACMA][1][96] = 127, + [0][1][2][1][RTW89_ACMA][0][96] = 127, + [0][1][2][1][RTW89_CHILE][1][96] = -2, + [0][1][2][1][RTW89_QATAR][1][96] = 127, + [0][1][2][1][RTW89_QATAR][0][96] = 127, + [0][1][2][1][RTW89_UK][1][96] = 127, + [0][1][2][1][RTW89_UK][0][96] = 127, + [0][1][2][1][RTW89_THAILAND][1][96] = 127, + [0][1][2][1][RTW89_THAILAND][0][96] = 127, + [0][1][2][1][RTW89_FCC][1][98] = -2, + [0][1][2][1][RTW89_ETSI][1][98] = 127, + [0][1][2][1][RTW89_ETSI][0][98] = 127, + [0][1][2][1][RTW89_MKK][1][98] = 127, + [0][1][2][1][RTW89_MKK][0][98] = 127, + [0][1][2][1][RTW89_IC][1][98] = -2, + [0][1][2][1][RTW89_KCC][1][98] = 20, + [0][1][2][1][RTW89_KCC][0][98] = 127, + [0][1][2][1][RTW89_ACMA][1][98] = 127, + [0][1][2][1][RTW89_ACMA][0][98] = 127, + [0][1][2][1][RTW89_CHILE][1][98] = -2, + [0][1][2][1][RTW89_QATAR][1][98] = 127, + [0][1][2][1][RTW89_QATAR][0][98] = 127, + [0][1][2][1][RTW89_UK][1][98] = 127, + [0][1][2][1][RTW89_UK][0][98] = 127, + [0][1][2][1][RTW89_THAILAND][1][98] = 127, + [0][1][2][1][RTW89_THAILAND][0][98] = 127, + [0][1][2][1][RTW89_FCC][1][100] = -2, + [0][1][2][1][RTW89_ETSI][1][100] = 127, + [0][1][2][1][RTW89_ETSI][0][100] = 127, + [0][1][2][1][RTW89_MKK][1][100] = 127, + [0][1][2][1][RTW89_MKK][0][100] = 127, + [0][1][2][1][RTW89_IC][1][100] = -2, + [0][1][2][1][RTW89_KCC][1][100] = 20, + [0][1][2][1][RTW89_KCC][0][100] = 127, + [0][1][2][1][RTW89_ACMA][1][100] = 127, + [0][1][2][1][RTW89_ACMA][0][100] = 127, + [0][1][2][1][RTW89_CHILE][1][100] = -2, + [0][1][2][1][RTW89_QATAR][1][100] = 127, + [0][1][2][1][RTW89_QATAR][0][100] = 127, + [0][1][2][1][RTW89_UK][1][100] = 127, + [0][1][2][1][RTW89_UK][0][100] = 127, + [0][1][2][1][RTW89_THAILAND][1][100] = 127, + [0][1][2][1][RTW89_THAILAND][0][100] = 127, + [0][1][2][1][RTW89_FCC][1][102] = -2, + [0][1][2][1][RTW89_ETSI][1][102] = 127, + [0][1][2][1][RTW89_ETSI][0][102] = 127, + [0][1][2][1][RTW89_MKK][1][102] = 127, + [0][1][2][1][RTW89_MKK][0][102] = 127, + [0][1][2][1][RTW89_IC][1][102] = -2, + [0][1][2][1][RTW89_KCC][1][102] = 20, + [0][1][2][1][RTW89_KCC][0][102] = 127, + [0][1][2][1][RTW89_ACMA][1][102] = 127, + [0][1][2][1][RTW89_ACMA][0][102] = 127, + [0][1][2][1][RTW89_CHILE][1][102] = -2, + [0][1][2][1][RTW89_QATAR][1][102] = 127, + [0][1][2][1][RTW89_QATAR][0][102] = 127, + [0][1][2][1][RTW89_UK][1][102] = 127, + [0][1][2][1][RTW89_UK][0][102] = 127, + [0][1][2][1][RTW89_THAILAND][1][102] = 127, + [0][1][2][1][RTW89_THAILAND][0][102] = 127, + [0][1][2][1][RTW89_FCC][1][104] = -2, + [0][1][2][1][RTW89_ETSI][1][104] = 127, + [0][1][2][1][RTW89_ETSI][0][104] = 127, + [0][1][2][1][RTW89_MKK][1][104] = 127, + [0][1][2][1][RTW89_MKK][0][104] = 127, + [0][1][2][1][RTW89_IC][1][104] = -2, + [0][1][2][1][RTW89_KCC][1][104] = 20, + [0][1][2][1][RTW89_KCC][0][104] = 127, + [0][1][2][1][RTW89_ACMA][1][104] = 127, + [0][1][2][1][RTW89_ACMA][0][104] = 127, + [0][1][2][1][RTW89_CHILE][1][104] = -2, + [0][1][2][1][RTW89_QATAR][1][104] = 127, + [0][1][2][1][RTW89_QATAR][0][104] = 127, + [0][1][2][1][RTW89_UK][1][104] = 127, + [0][1][2][1][RTW89_UK][0][104] = 127, + [0][1][2][1][RTW89_THAILAND][1][104] = 127, + [0][1][2][1][RTW89_THAILAND][0][104] = 127, + [0][1][2][1][RTW89_FCC][1][105] = -2, + [0][1][2][1][RTW89_ETSI][1][105] = 127, + [0][1][2][1][RTW89_ETSI][0][105] = 127, + [0][1][2][1][RTW89_MKK][1][105] = 127, + [0][1][2][1][RTW89_MKK][0][105] = 127, + [0][1][2][1][RTW89_IC][1][105] = -2, + [0][1][2][1][RTW89_KCC][1][105] = 20, + [0][1][2][1][RTW89_KCC][0][105] = 127, + [0][1][2][1][RTW89_ACMA][1][105] = 127, + [0][1][2][1][RTW89_ACMA][0][105] = 127, + [0][1][2][1][RTW89_CHILE][1][105] = -2, + [0][1][2][1][RTW89_QATAR][1][105] = 127, + [0][1][2][1][RTW89_QATAR][0][105] = 127, + [0][1][2][1][RTW89_UK][1][105] = 127, + [0][1][2][1][RTW89_UK][0][105] = 127, + [0][1][2][1][RTW89_THAILAND][1][105] = 127, + [0][1][2][1][RTW89_THAILAND][0][105] = 127, + [0][1][2][1][RTW89_FCC][1][107] = 1, + [0][1][2][1][RTW89_ETSI][1][107] = 127, + [0][1][2][1][RTW89_ETSI][0][107] = 127, + [0][1][2][1][RTW89_MKK][1][107] = 127, + [0][1][2][1][RTW89_MKK][0][107] = 127, + [0][1][2][1][RTW89_IC][1][107] = 1, + [0][1][2][1][RTW89_KCC][1][107] = 20, + [0][1][2][1][RTW89_KCC][0][107] = 127, + [0][1][2][1][RTW89_ACMA][1][107] = 127, + [0][1][2][1][RTW89_ACMA][0][107] = 127, + [0][1][2][1][RTW89_CHILE][1][107] = 1, + [0][1][2][1][RTW89_QATAR][1][107] = 127, + [0][1][2][1][RTW89_QATAR][0][107] = 127, + [0][1][2][1][RTW89_UK][1][107] = 127, + [0][1][2][1][RTW89_UK][0][107] = 127, + [0][1][2][1][RTW89_THAILAND][1][107] = 127, + [0][1][2][1][RTW89_THAILAND][0][107] = 127, + [0][1][2][1][RTW89_FCC][1][109] = 1, + [0][1][2][1][RTW89_ETSI][1][109] = 127, + [0][1][2][1][RTW89_ETSI][0][109] = 127, + [0][1][2][1][RTW89_MKK][1][109] = 127, + [0][1][2][1][RTW89_MKK][0][109] = 127, + [0][1][2][1][RTW89_IC][1][109] = 1, + [0][1][2][1][RTW89_KCC][1][109] = 20, + [0][1][2][1][RTW89_KCC][0][109] = 127, + [0][1][2][1][RTW89_ACMA][1][109] = 127, + [0][1][2][1][RTW89_ACMA][0][109] = 127, + [0][1][2][1][RTW89_CHILE][1][109] = 1, + [0][1][2][1][RTW89_QATAR][1][109] = 127, + [0][1][2][1][RTW89_QATAR][0][109] = 127, + [0][1][2][1][RTW89_UK][1][109] = 127, + [0][1][2][1][RTW89_UK][0][109] = 127, + [0][1][2][1][RTW89_THAILAND][1][109] = 127, + [0][1][2][1][RTW89_THAILAND][0][109] = 127, + [0][1][2][1][RTW89_FCC][1][111] = 127, + [0][1][2][1][RTW89_ETSI][1][111] = 127, + [0][1][2][1][RTW89_ETSI][0][111] = 127, + [0][1][2][1][RTW89_MKK][1][111] = 127, + [0][1][2][1][RTW89_MKK][0][111] = 127, + [0][1][2][1][RTW89_IC][1][111] = 127, + [0][1][2][1][RTW89_KCC][1][111] = 127, + [0][1][2][1][RTW89_KCC][0][111] = 127, + [0][1][2][1][RTW89_ACMA][1][111] = 127, + [0][1][2][1][RTW89_ACMA][0][111] = 127, + [0][1][2][1][RTW89_CHILE][1][111] = 127, + [0][1][2][1][RTW89_QATAR][1][111] = 127, + [0][1][2][1][RTW89_QATAR][0][111] = 127, + [0][1][2][1][RTW89_UK][1][111] = 127, + [0][1][2][1][RTW89_UK][0][111] = 127, + [0][1][2][1][RTW89_THAILAND][1][111] = 127, + [0][1][2][1][RTW89_THAILAND][0][111] = 127, + [0][1][2][1][RTW89_FCC][1][113] = 127, + [0][1][2][1][RTW89_ETSI][1][113] = 127, + [0][1][2][1][RTW89_ETSI][0][113] = 127, + [0][1][2][1][RTW89_MKK][1][113] = 127, + [0][1][2][1][RTW89_MKK][0][113] = 127, + [0][1][2][1][RTW89_IC][1][113] = 127, + [0][1][2][1][RTW89_KCC][1][113] = 127, + [0][1][2][1][RTW89_KCC][0][113] = 127, + [0][1][2][1][RTW89_ACMA][1][113] = 127, + [0][1][2][1][RTW89_ACMA][0][113] = 127, + [0][1][2][1][RTW89_CHILE][1][113] = 127, + [0][1][2][1][RTW89_QATAR][1][113] = 127, + [0][1][2][1][RTW89_QATAR][0][113] = 127, + [0][1][2][1][RTW89_UK][1][113] = 127, + [0][1][2][1][RTW89_UK][0][113] = 127, + [0][1][2][1][RTW89_THAILAND][1][113] = 127, + [0][1][2][1][RTW89_THAILAND][0][113] = 127, + [0][1][2][1][RTW89_FCC][1][115] = 127, + [0][1][2][1][RTW89_ETSI][1][115] = 127, + [0][1][2][1][RTW89_ETSI][0][115] = 127, + [0][1][2][1][RTW89_MKK][1][115] = 127, + [0][1][2][1][RTW89_MKK][0][115] = 127, + [0][1][2][1][RTW89_IC][1][115] = 127, + [0][1][2][1][RTW89_KCC][1][115] = 127, + [0][1][2][1][RTW89_KCC][0][115] = 127, + [0][1][2][1][RTW89_ACMA][1][115] = 127, + [0][1][2][1][RTW89_ACMA][0][115] = 127, + [0][1][2][1][RTW89_CHILE][1][115] = 127, + [0][1][2][1][RTW89_QATAR][1][115] = 127, + [0][1][2][1][RTW89_QATAR][0][115] = 127, + [0][1][2][1][RTW89_UK][1][115] = 127, + [0][1][2][1][RTW89_UK][0][115] = 127, + [0][1][2][1][RTW89_THAILAND][1][115] = 127, + [0][1][2][1][RTW89_THAILAND][0][115] = 127, + [0][1][2][1][RTW89_FCC][1][117] = 127, + [0][1][2][1][RTW89_ETSI][1][117] = 127, + [0][1][2][1][RTW89_ETSI][0][117] = 127, + [0][1][2][1][RTW89_MKK][1][117] = 127, + [0][1][2][1][RTW89_MKK][0][117] = 127, + [0][1][2][1][RTW89_IC][1][117] = 127, + [0][1][2][1][RTW89_KCC][1][117] = 127, + [0][1][2][1][RTW89_KCC][0][117] = 127, + [0][1][2][1][RTW89_ACMA][1][117] = 127, + [0][1][2][1][RTW89_ACMA][0][117] = 127, + [0][1][2][1][RTW89_CHILE][1][117] = 127, + [0][1][2][1][RTW89_QATAR][1][117] = 127, + [0][1][2][1][RTW89_QATAR][0][117] = 127, + [0][1][2][1][RTW89_UK][1][117] = 127, + [0][1][2][1][RTW89_UK][0][117] = 127, + [0][1][2][1][RTW89_THAILAND][1][117] = 127, + [0][1][2][1][RTW89_THAILAND][0][117] = 127, + [0][1][2][1][RTW89_FCC][1][119] = 127, + [0][1][2][1][RTW89_ETSI][1][119] = 127, + [0][1][2][1][RTW89_ETSI][0][119] = 127, + [0][1][2][1][RTW89_MKK][1][119] = 127, + [0][1][2][1][RTW89_MKK][0][119] = 127, + [0][1][2][1][RTW89_IC][1][119] = 127, + [0][1][2][1][RTW89_KCC][1][119] = 127, + [0][1][2][1][RTW89_KCC][0][119] = 127, + [0][1][2][1][RTW89_ACMA][1][119] = 127, + [0][1][2][1][RTW89_ACMA][0][119] = 127, + [0][1][2][1][RTW89_CHILE][1][119] = 127, + [0][1][2][1][RTW89_QATAR][1][119] = 127, + [0][1][2][1][RTW89_QATAR][0][119] = 127, + [0][1][2][1][RTW89_UK][1][119] = 127, + [0][1][2][1][RTW89_UK][0][119] = 127, + [0][1][2][1][RTW89_THAILAND][1][119] = 127, + [0][1][2][1][RTW89_THAILAND][0][119] = 127, + [1][0][2][0][RTW89_FCC][1][1] = 34, + [1][0][2][0][RTW89_ETSI][1][1] = 66, + [1][0][2][0][RTW89_ETSI][0][1] = 30, + [1][0][2][0][RTW89_MKK][1][1] = 62, + [1][0][2][0][RTW89_MKK][0][1] = 26, + [1][0][2][0][RTW89_IC][1][1] = 34, + [1][0][2][0][RTW89_KCC][1][1] = 40, + [1][0][2][0][RTW89_KCC][0][1] = 24, + [1][0][2][0][RTW89_ACMA][1][1] = 66, + [1][0][2][0][RTW89_ACMA][0][1] = 30, + [1][0][2][0][RTW89_CHILE][1][1] = 34, + [1][0][2][0][RTW89_QATAR][1][1] = 66, + [1][0][2][0][RTW89_QATAR][0][1] = 30, + [1][0][2][0][RTW89_UK][1][1] = 66, + [1][0][2][0][RTW89_UK][0][1] = 30, + [1][0][2][0][RTW89_THAILAND][1][1] = 68, + [1][0][2][0][RTW89_THAILAND][0][1] = 30, + [1][0][2][0][RTW89_FCC][1][5] = 34, + [1][0][2][0][RTW89_ETSI][1][5] = 66, + [1][0][2][0][RTW89_ETSI][0][5] = 30, + [1][0][2][0][RTW89_MKK][1][5] = 62, + [1][0][2][0][RTW89_MKK][0][5] = 26, + [1][0][2][0][RTW89_IC][1][5] = 34, + [1][0][2][0][RTW89_KCC][1][5] = 40, + [1][0][2][0][RTW89_KCC][0][5] = 24, + [1][0][2][0][RTW89_ACMA][1][5] = 66, + [1][0][2][0][RTW89_ACMA][0][5] = 30, + [1][0][2][0][RTW89_CHILE][1][5] = 34, + [1][0][2][0][RTW89_QATAR][1][5] = 66, + [1][0][2][0][RTW89_QATAR][0][5] = 30, + [1][0][2][0][RTW89_UK][1][5] = 66, + [1][0][2][0][RTW89_UK][0][5] = 30, + [1][0][2][0][RTW89_THAILAND][1][5] = 68, + [1][0][2][0][RTW89_THAILAND][0][5] = 30, + [1][0][2][0][RTW89_FCC][1][9] = 34, + [1][0][2][0][RTW89_ETSI][1][9] = 66, + [1][0][2][0][RTW89_ETSI][0][9] = 30, + [1][0][2][0][RTW89_MKK][1][9] = 62, + [1][0][2][0][RTW89_MKK][0][9] = 26, + [1][0][2][0][RTW89_IC][1][9] = 34, + [1][0][2][0][RTW89_KCC][1][9] = 40, + [1][0][2][0][RTW89_KCC][0][9] = 24, + [1][0][2][0][RTW89_ACMA][1][9] = 66, + [1][0][2][0][RTW89_ACMA][0][9] = 30, + [1][0][2][0][RTW89_CHILE][1][9] = 34, + [1][0][2][0][RTW89_QATAR][1][9] = 66, + [1][0][2][0][RTW89_QATAR][0][9] = 30, + [1][0][2][0][RTW89_UK][1][9] = 66, + [1][0][2][0][RTW89_UK][0][9] = 30, + [1][0][2][0][RTW89_THAILAND][1][9] = 68, + [1][0][2][0][RTW89_THAILAND][0][9] = 30, + [1][0][2][0][RTW89_FCC][1][13] = 34, + [1][0][2][0][RTW89_ETSI][1][13] = 66, + [1][0][2][0][RTW89_ETSI][0][13] = 30, + [1][0][2][0][RTW89_MKK][1][13] = 62, + [1][0][2][0][RTW89_MKK][0][13] = 26, + [1][0][2][0][RTW89_IC][1][13] = 34, + [1][0][2][0][RTW89_KCC][1][13] = 40, + [1][0][2][0][RTW89_KCC][0][13] = 24, + [1][0][2][0][RTW89_ACMA][1][13] = 66, + [1][0][2][0][RTW89_ACMA][0][13] = 30, + [1][0][2][0][RTW89_CHILE][1][13] = 34, + [1][0][2][0][RTW89_QATAR][1][13] = 66, + [1][0][2][0][RTW89_QATAR][0][13] = 30, + [1][0][2][0][RTW89_UK][1][13] = 66, + [1][0][2][0][RTW89_UK][0][13] = 30, + [1][0][2][0][RTW89_THAILAND][1][13] = 68, + [1][0][2][0][RTW89_THAILAND][0][13] = 30, + [1][0][2][0][RTW89_FCC][1][16] = 34, + [1][0][2][0][RTW89_ETSI][1][16] = 66, + [1][0][2][0][RTW89_ETSI][0][16] = 30, + [1][0][2][0][RTW89_MKK][1][16] = 62, + [1][0][2][0][RTW89_MKK][0][16] = 26, + [1][0][2][0][RTW89_IC][1][16] = 34, + [1][0][2][0][RTW89_KCC][1][16] = 40, + [1][0][2][0][RTW89_KCC][0][16] = 24, + [1][0][2][0][RTW89_ACMA][1][16] = 66, + [1][0][2][0][RTW89_ACMA][0][16] = 30, + [1][0][2][0][RTW89_CHILE][1][16] = 34, + [1][0][2][0][RTW89_QATAR][1][16] = 66, + [1][0][2][0][RTW89_QATAR][0][16] = 30, + [1][0][2][0][RTW89_UK][1][16] = 66, + [1][0][2][0][RTW89_UK][0][16] = 30, + [1][0][2][0][RTW89_THAILAND][1][16] = 68, + [1][0][2][0][RTW89_THAILAND][0][16] = 30, + [1][0][2][0][RTW89_FCC][1][20] = 34, + [1][0][2][0][RTW89_ETSI][1][20] = 66, + [1][0][2][0][RTW89_ETSI][0][20] = 30, + [1][0][2][0][RTW89_MKK][1][20] = 62, + [1][0][2][0][RTW89_MKK][0][20] = 26, + [1][0][2][0][RTW89_IC][1][20] = 34, + [1][0][2][0][RTW89_KCC][1][20] = 40, + [1][0][2][0][RTW89_KCC][0][20] = 24, + [1][0][2][0][RTW89_ACMA][1][20] = 66, + [1][0][2][0][RTW89_ACMA][0][20] = 30, + [1][0][2][0][RTW89_CHILE][1][20] = 34, + [1][0][2][0][RTW89_QATAR][1][20] = 66, + [1][0][2][0][RTW89_QATAR][0][20] = 30, + [1][0][2][0][RTW89_UK][1][20] = 66, + [1][0][2][0][RTW89_UK][0][20] = 30, + [1][0][2][0][RTW89_THAILAND][1][20] = 68, + [1][0][2][0][RTW89_THAILAND][0][20] = 30, + [1][0][2][0][RTW89_FCC][1][24] = 36, + [1][0][2][0][RTW89_ETSI][1][24] = 66, + [1][0][2][0][RTW89_ETSI][0][24] = 30, + [1][0][2][0][RTW89_MKK][1][24] = 64, + [1][0][2][0][RTW89_MKK][0][24] = 28, + [1][0][2][0][RTW89_IC][1][24] = 36, + [1][0][2][0][RTW89_KCC][1][24] = 40, + [1][0][2][0][RTW89_KCC][0][24] = 26, + [1][0][2][0][RTW89_ACMA][1][24] = 66, + [1][0][2][0][RTW89_ACMA][0][24] = 30, + [1][0][2][0][RTW89_CHILE][1][24] = 36, + [1][0][2][0][RTW89_QATAR][1][24] = 66, + [1][0][2][0][RTW89_QATAR][0][24] = 30, + [1][0][2][0][RTW89_UK][1][24] = 66, + [1][0][2][0][RTW89_UK][0][24] = 30, + [1][0][2][0][RTW89_THAILAND][1][24] = 68, + [1][0][2][0][RTW89_THAILAND][0][24] = 30, + [1][0][2][0][RTW89_FCC][1][28] = 34, + [1][0][2][0][RTW89_ETSI][1][28] = 66, + [1][0][2][0][RTW89_ETSI][0][28] = 30, + [1][0][2][0][RTW89_MKK][1][28] = 64, + [1][0][2][0][RTW89_MKK][0][28] = 26, + [1][0][2][0][RTW89_IC][1][28] = 34, + [1][0][2][0][RTW89_KCC][1][28] = 40, + [1][0][2][0][RTW89_KCC][0][28] = 26, + [1][0][2][0][RTW89_ACMA][1][28] = 66, + [1][0][2][0][RTW89_ACMA][0][28] = 30, + [1][0][2][0][RTW89_CHILE][1][28] = 34, + [1][0][2][0][RTW89_QATAR][1][28] = 66, + [1][0][2][0][RTW89_QATAR][0][28] = 30, + [1][0][2][0][RTW89_UK][1][28] = 66, + [1][0][2][0][RTW89_UK][0][28] = 30, + [1][0][2][0][RTW89_THAILAND][1][28] = 68, + [1][0][2][0][RTW89_THAILAND][0][28] = 30, + [1][0][2][0][RTW89_FCC][1][31] = 34, + [1][0][2][0][RTW89_ETSI][1][31] = 66, + [1][0][2][0][RTW89_ETSI][0][31] = 30, + [1][0][2][0][RTW89_MKK][1][31] = 64, + [1][0][2][0][RTW89_MKK][0][31] = 26, + [1][0][2][0][RTW89_IC][1][31] = 34, + [1][0][2][0][RTW89_KCC][1][31] = 40, + [1][0][2][0][RTW89_KCC][0][31] = 26, + [1][0][2][0][RTW89_ACMA][1][31] = 66, + [1][0][2][0][RTW89_ACMA][0][31] = 30, + [1][0][2][0][RTW89_CHILE][1][31] = 34, + [1][0][2][0][RTW89_QATAR][1][31] = 66, + [1][0][2][0][RTW89_QATAR][0][31] = 30, + [1][0][2][0][RTW89_UK][1][31] = 66, + [1][0][2][0][RTW89_UK][0][31] = 30, + [1][0][2][0][RTW89_THAILAND][1][31] = 68, + [1][0][2][0][RTW89_THAILAND][0][31] = 30, + [1][0][2][0][RTW89_FCC][1][35] = 34, + [1][0][2][0][RTW89_ETSI][1][35] = 66, + [1][0][2][0][RTW89_ETSI][0][35] = 30, + [1][0][2][0][RTW89_MKK][1][35] = 64, + [1][0][2][0][RTW89_MKK][0][35] = 26, + [1][0][2][0][RTW89_IC][1][35] = 34, + [1][0][2][0][RTW89_KCC][1][35] = 40, + [1][0][2][0][RTW89_KCC][0][35] = 26, + [1][0][2][0][RTW89_ACMA][1][35] = 66, + [1][0][2][0][RTW89_ACMA][0][35] = 30, + [1][0][2][0][RTW89_CHILE][1][35] = 34, + [1][0][2][0][RTW89_QATAR][1][35] = 66, + [1][0][2][0][RTW89_QATAR][0][35] = 30, + [1][0][2][0][RTW89_UK][1][35] = 66, + [1][0][2][0][RTW89_UK][0][35] = 30, + [1][0][2][0][RTW89_THAILAND][1][35] = 68, + [1][0][2][0][RTW89_THAILAND][0][35] = 30, + [1][0][2][0][RTW89_FCC][1][39] = 34, + [1][0][2][0][RTW89_ETSI][1][39] = 66, + [1][0][2][0][RTW89_ETSI][0][39] = 30, + [1][0][2][0][RTW89_MKK][1][39] = 64, + [1][0][2][0][RTW89_MKK][0][39] = 26, + [1][0][2][0][RTW89_IC][1][39] = 34, + [1][0][2][0][RTW89_KCC][1][39] = 40, + [1][0][2][0][RTW89_KCC][0][39] = 26, + [1][0][2][0][RTW89_ACMA][1][39] = 66, + [1][0][2][0][RTW89_ACMA][0][39] = 30, + [1][0][2][0][RTW89_CHILE][1][39] = 34, + [1][0][2][0][RTW89_QATAR][1][39] = 66, + [1][0][2][0][RTW89_QATAR][0][39] = 30, + [1][0][2][0][RTW89_UK][1][39] = 66, + [1][0][2][0][RTW89_UK][0][39] = 30, + [1][0][2][0][RTW89_THAILAND][1][39] = 68, + [1][0][2][0][RTW89_THAILAND][0][39] = 30, + [1][0][2][0][RTW89_FCC][1][43] = 34, + [1][0][2][0][RTW89_ETSI][1][43] = 66, + [1][0][2][0][RTW89_ETSI][0][43] = 30, + [1][0][2][0][RTW89_MKK][1][43] = 64, + [1][0][2][0][RTW89_MKK][0][43] = 26, + [1][0][2][0][RTW89_IC][1][43] = 34, + [1][0][2][0][RTW89_KCC][1][43] = 40, + [1][0][2][0][RTW89_KCC][0][43] = 26, + [1][0][2][0][RTW89_ACMA][1][43] = 66, + [1][0][2][0][RTW89_ACMA][0][43] = 30, + [1][0][2][0][RTW89_CHILE][1][43] = 34, + [1][0][2][0][RTW89_QATAR][1][43] = 66, + [1][0][2][0][RTW89_QATAR][0][43] = 30, + [1][0][2][0][RTW89_UK][1][43] = 66, + [1][0][2][0][RTW89_UK][0][43] = 30, + [1][0][2][0][RTW89_THAILAND][1][43] = 68, + [1][0][2][0][RTW89_THAILAND][0][43] = 30, + [1][0][2][0][RTW89_FCC][1][46] = 34, + [1][0][2][0][RTW89_ETSI][1][46] = 127, + [1][0][2][0][RTW89_ETSI][0][46] = 127, + [1][0][2][0][RTW89_MKK][1][46] = 127, + [1][0][2][0][RTW89_MKK][0][46] = 127, + [1][0][2][0][RTW89_IC][1][46] = 34, + [1][0][2][0][RTW89_KCC][1][46] = 40, + [1][0][2][0][RTW89_KCC][0][46] = 127, + [1][0][2][0][RTW89_ACMA][1][46] = 127, + [1][0][2][0][RTW89_ACMA][0][46] = 127, + [1][0][2][0][RTW89_CHILE][1][46] = 34, + [1][0][2][0][RTW89_QATAR][1][46] = 127, + [1][0][2][0][RTW89_QATAR][0][46] = 127, + [1][0][2][0][RTW89_UK][1][46] = 127, + [1][0][2][0][RTW89_UK][0][46] = 127, + [1][0][2][0][RTW89_THAILAND][1][46] = 127, + [1][0][2][0][RTW89_THAILAND][0][46] = 127, + [1][0][2][0][RTW89_FCC][1][50] = 34, + [1][0][2][0][RTW89_ETSI][1][50] = 127, + [1][0][2][0][RTW89_ETSI][0][50] = 127, + [1][0][2][0][RTW89_MKK][1][50] = 127, + [1][0][2][0][RTW89_MKK][0][50] = 127, + [1][0][2][0][RTW89_IC][1][50] = 34, + [1][0][2][0][RTW89_KCC][1][50] = 40, + [1][0][2][0][RTW89_KCC][0][50] = 127, + [1][0][2][0][RTW89_ACMA][1][50] = 127, + [1][0][2][0][RTW89_ACMA][0][50] = 127, + [1][0][2][0][RTW89_CHILE][1][50] = 34, + [1][0][2][0][RTW89_QATAR][1][50] = 127, + [1][0][2][0][RTW89_QATAR][0][50] = 127, + [1][0][2][0][RTW89_UK][1][50] = 127, + [1][0][2][0][RTW89_UK][0][50] = 127, + [1][0][2][0][RTW89_THAILAND][1][50] = 127, + [1][0][2][0][RTW89_THAILAND][0][50] = 127, + [1][0][2][0][RTW89_FCC][1][54] = 36, + [1][0][2][0][RTW89_ETSI][1][54] = 127, + [1][0][2][0][RTW89_ETSI][0][54] = 127, + [1][0][2][0][RTW89_MKK][1][54] = 127, + [1][0][2][0][RTW89_MKK][0][54] = 127, + [1][0][2][0][RTW89_IC][1][54] = 36, + [1][0][2][0][RTW89_KCC][1][54] = 40, + [1][0][2][0][RTW89_KCC][0][54] = 127, + [1][0][2][0][RTW89_ACMA][1][54] = 127, + [1][0][2][0][RTW89_ACMA][0][54] = 127, + [1][0][2][0][RTW89_CHILE][1][54] = 36, + [1][0][2][0][RTW89_QATAR][1][54] = 127, + [1][0][2][0][RTW89_QATAR][0][54] = 127, + [1][0][2][0][RTW89_UK][1][54] = 127, + [1][0][2][0][RTW89_UK][0][54] = 127, + [1][0][2][0][RTW89_THAILAND][1][54] = 127, + [1][0][2][0][RTW89_THAILAND][0][54] = 127, + [1][0][2][0][RTW89_FCC][1][58] = 36, + [1][0][2][0][RTW89_ETSI][1][58] = 127, + [1][0][2][0][RTW89_ETSI][0][58] = 127, + [1][0][2][0][RTW89_MKK][1][58] = 127, + [1][0][2][0][RTW89_MKK][0][58] = 127, + [1][0][2][0][RTW89_IC][1][58] = 36, + [1][0][2][0][RTW89_KCC][1][58] = 40, + [1][0][2][0][RTW89_KCC][0][58] = 127, + [1][0][2][0][RTW89_ACMA][1][58] = 127, + [1][0][2][0][RTW89_ACMA][0][58] = 127, + [1][0][2][0][RTW89_CHILE][1][58] = 36, + [1][0][2][0][RTW89_QATAR][1][58] = 127, + [1][0][2][0][RTW89_QATAR][0][58] = 127, + [1][0][2][0][RTW89_UK][1][58] = 127, + [1][0][2][0][RTW89_UK][0][58] = 127, + [1][0][2][0][RTW89_THAILAND][1][58] = 127, + [1][0][2][0][RTW89_THAILAND][0][58] = 127, + [1][0][2][0][RTW89_FCC][1][61] = 34, + [1][0][2][0][RTW89_ETSI][1][61] = 127, + [1][0][2][0][RTW89_ETSI][0][61] = 127, + [1][0][2][0][RTW89_MKK][1][61] = 127, + [1][0][2][0][RTW89_MKK][0][61] = 127, + [1][0][2][0][RTW89_IC][1][61] = 34, + [1][0][2][0][RTW89_KCC][1][61] = 40, + [1][0][2][0][RTW89_KCC][0][61] = 127, + [1][0][2][0][RTW89_ACMA][1][61] = 127, + [1][0][2][0][RTW89_ACMA][0][61] = 127, + [1][0][2][0][RTW89_CHILE][1][61] = 34, + [1][0][2][0][RTW89_QATAR][1][61] = 127, + [1][0][2][0][RTW89_QATAR][0][61] = 127, + [1][0][2][0][RTW89_UK][1][61] = 127, + [1][0][2][0][RTW89_UK][0][61] = 127, + [1][0][2][0][RTW89_THAILAND][1][61] = 127, + [1][0][2][0][RTW89_THAILAND][0][61] = 127, + [1][0][2][0][RTW89_FCC][1][65] = 34, + [1][0][2][0][RTW89_ETSI][1][65] = 127, + [1][0][2][0][RTW89_ETSI][0][65] = 127, + [1][0][2][0][RTW89_MKK][1][65] = 127, + [1][0][2][0][RTW89_MKK][0][65] = 127, + [1][0][2][0][RTW89_IC][1][65] = 34, + [1][0][2][0][RTW89_KCC][1][65] = 40, + [1][0][2][0][RTW89_KCC][0][65] = 127, + [1][0][2][0][RTW89_ACMA][1][65] = 127, + [1][0][2][0][RTW89_ACMA][0][65] = 127, + [1][0][2][0][RTW89_CHILE][1][65] = 34, + [1][0][2][0][RTW89_QATAR][1][65] = 127, + [1][0][2][0][RTW89_QATAR][0][65] = 127, + [1][0][2][0][RTW89_UK][1][65] = 127, + [1][0][2][0][RTW89_UK][0][65] = 127, + [1][0][2][0][RTW89_THAILAND][1][65] = 127, + [1][0][2][0][RTW89_THAILAND][0][65] = 127, + [1][0][2][0][RTW89_FCC][1][69] = 34, + [1][0][2][0][RTW89_ETSI][1][69] = 127, + [1][0][2][0][RTW89_ETSI][0][69] = 127, + [1][0][2][0][RTW89_MKK][1][69] = 127, + [1][0][2][0][RTW89_MKK][0][69] = 127, + [1][0][2][0][RTW89_IC][1][69] = 34, + [1][0][2][0][RTW89_KCC][1][69] = 40, + [1][0][2][0][RTW89_KCC][0][69] = 127, + [1][0][2][0][RTW89_ACMA][1][69] = 127, + [1][0][2][0][RTW89_ACMA][0][69] = 127, + [1][0][2][0][RTW89_CHILE][1][69] = 34, + [1][0][2][0][RTW89_QATAR][1][69] = 127, + [1][0][2][0][RTW89_QATAR][0][69] = 127, + [1][0][2][0][RTW89_UK][1][69] = 127, + [1][0][2][0][RTW89_UK][0][69] = 127, + [1][0][2][0][RTW89_THAILAND][1][69] = 127, + [1][0][2][0][RTW89_THAILAND][0][69] = 127, + [1][0][2][0][RTW89_FCC][1][73] = 34, + [1][0][2][0][RTW89_ETSI][1][73] = 127, + [1][0][2][0][RTW89_ETSI][0][73] = 127, + [1][0][2][0][RTW89_MKK][1][73] = 127, + [1][0][2][0][RTW89_MKK][0][73] = 127, + [1][0][2][0][RTW89_IC][1][73] = 34, + [1][0][2][0][RTW89_KCC][1][73] = 40, + [1][0][2][0][RTW89_KCC][0][73] = 127, + [1][0][2][0][RTW89_ACMA][1][73] = 127, + [1][0][2][0][RTW89_ACMA][0][73] = 127, + [1][0][2][0][RTW89_CHILE][1][73] = 34, + [1][0][2][0][RTW89_QATAR][1][73] = 127, + [1][0][2][0][RTW89_QATAR][0][73] = 127, + [1][0][2][0][RTW89_UK][1][73] = 127, + [1][0][2][0][RTW89_UK][0][73] = 127, + [1][0][2][0][RTW89_THAILAND][1][73] = 127, + [1][0][2][0][RTW89_THAILAND][0][73] = 127, + [1][0][2][0][RTW89_FCC][1][76] = 34, + [1][0][2][0][RTW89_ETSI][1][76] = 127, + [1][0][2][0][RTW89_ETSI][0][76] = 127, + [1][0][2][0][RTW89_MKK][1][76] = 127, + [1][0][2][0][RTW89_MKK][0][76] = 127, + [1][0][2][0][RTW89_IC][1][76] = 34, + [1][0][2][0][RTW89_KCC][1][76] = 40, + [1][0][2][0][RTW89_KCC][0][76] = 127, + [1][0][2][0][RTW89_ACMA][1][76] = 127, + [1][0][2][0][RTW89_ACMA][0][76] = 127, + [1][0][2][0][RTW89_CHILE][1][76] = 34, + [1][0][2][0][RTW89_QATAR][1][76] = 127, + [1][0][2][0][RTW89_QATAR][0][76] = 127, + [1][0][2][0][RTW89_UK][1][76] = 127, + [1][0][2][0][RTW89_UK][0][76] = 127, + [1][0][2][0][RTW89_THAILAND][1][76] = 127, + [1][0][2][0][RTW89_THAILAND][0][76] = 127, + [1][0][2][0][RTW89_FCC][1][80] = 34, + [1][0][2][0][RTW89_ETSI][1][80] = 127, + [1][0][2][0][RTW89_ETSI][0][80] = 127, + [1][0][2][0][RTW89_MKK][1][80] = 127, + [1][0][2][0][RTW89_MKK][0][80] = 127, + [1][0][2][0][RTW89_IC][1][80] = 34, + [1][0][2][0][RTW89_KCC][1][80] = 42, + [1][0][2][0][RTW89_KCC][0][80] = 127, + [1][0][2][0][RTW89_ACMA][1][80] = 127, + [1][0][2][0][RTW89_ACMA][0][80] = 127, + [1][0][2][0][RTW89_CHILE][1][80] = 34, + [1][0][2][0][RTW89_QATAR][1][80] = 127, + [1][0][2][0][RTW89_QATAR][0][80] = 127, + [1][0][2][0][RTW89_UK][1][80] = 127, + [1][0][2][0][RTW89_UK][0][80] = 127, + [1][0][2][0][RTW89_THAILAND][1][80] = 127, + [1][0][2][0][RTW89_THAILAND][0][80] = 127, + [1][0][2][0][RTW89_FCC][1][84] = 34, + [1][0][2][0][RTW89_ETSI][1][84] = 127, + [1][0][2][0][RTW89_ETSI][0][84] = 127, + [1][0][2][0][RTW89_MKK][1][84] = 127, + [1][0][2][0][RTW89_MKK][0][84] = 127, + [1][0][2][0][RTW89_IC][1][84] = 34, + [1][0][2][0][RTW89_KCC][1][84] = 42, + [1][0][2][0][RTW89_KCC][0][84] = 127, + [1][0][2][0][RTW89_ACMA][1][84] = 127, + [1][0][2][0][RTW89_ACMA][0][84] = 127, + [1][0][2][0][RTW89_CHILE][1][84] = 34, + [1][0][2][0][RTW89_QATAR][1][84] = 127, + [1][0][2][0][RTW89_QATAR][0][84] = 127, + [1][0][2][0][RTW89_UK][1][84] = 127, + [1][0][2][0][RTW89_UK][0][84] = 127, + [1][0][2][0][RTW89_THAILAND][1][84] = 127, + [1][0][2][0][RTW89_THAILAND][0][84] = 127, + [1][0][2][0][RTW89_FCC][1][88] = 34, + [1][0][2][0][RTW89_ETSI][1][88] = 127, + [1][0][2][0][RTW89_ETSI][0][88] = 127, + [1][0][2][0][RTW89_MKK][1][88] = 127, + [1][0][2][0][RTW89_MKK][0][88] = 127, + [1][0][2][0][RTW89_IC][1][88] = 34, + [1][0][2][0][RTW89_KCC][1][88] = 42, + [1][0][2][0][RTW89_KCC][0][88] = 127, + [1][0][2][0][RTW89_ACMA][1][88] = 127, + [1][0][2][0][RTW89_ACMA][0][88] = 127, + [1][0][2][0][RTW89_CHILE][1][88] = 34, + [1][0][2][0][RTW89_QATAR][1][88] = 127, + [1][0][2][0][RTW89_QATAR][0][88] = 127, + [1][0][2][0][RTW89_UK][1][88] = 127, + [1][0][2][0][RTW89_UK][0][88] = 127, + [1][0][2][0][RTW89_THAILAND][1][88] = 127, + [1][0][2][0][RTW89_THAILAND][0][88] = 127, + [1][0][2][0][RTW89_FCC][1][91] = 36, + [1][0][2][0][RTW89_ETSI][1][91] = 127, + [1][0][2][0][RTW89_ETSI][0][91] = 127, + [1][0][2][0][RTW89_MKK][1][91] = 127, + [1][0][2][0][RTW89_MKK][0][91] = 127, + [1][0][2][0][RTW89_IC][1][91] = 36, + [1][0][2][0][RTW89_KCC][1][91] = 42, + [1][0][2][0][RTW89_KCC][0][91] = 127, + [1][0][2][0][RTW89_ACMA][1][91] = 127, + [1][0][2][0][RTW89_ACMA][0][91] = 127, + [1][0][2][0][RTW89_CHILE][1][91] = 36, + [1][0][2][0][RTW89_QATAR][1][91] = 127, + [1][0][2][0][RTW89_QATAR][0][91] = 127, + [1][0][2][0][RTW89_UK][1][91] = 127, + [1][0][2][0][RTW89_UK][0][91] = 127, + [1][0][2][0][RTW89_THAILAND][1][91] = 127, + [1][0][2][0][RTW89_THAILAND][0][91] = 127, + [1][0][2][0][RTW89_FCC][1][95] = 34, + [1][0][2][0][RTW89_ETSI][1][95] = 127, + [1][0][2][0][RTW89_ETSI][0][95] = 127, + [1][0][2][0][RTW89_MKK][1][95] = 127, + [1][0][2][0][RTW89_MKK][0][95] = 127, + [1][0][2][0][RTW89_IC][1][95] = 34, + [1][0][2][0][RTW89_KCC][1][95] = 42, + [1][0][2][0][RTW89_KCC][0][95] = 127, + [1][0][2][0][RTW89_ACMA][1][95] = 127, + [1][0][2][0][RTW89_ACMA][0][95] = 127, + [1][0][2][0][RTW89_CHILE][1][95] = 34, + [1][0][2][0][RTW89_QATAR][1][95] = 127, + [1][0][2][0][RTW89_QATAR][0][95] = 127, + [1][0][2][0][RTW89_UK][1][95] = 127, + [1][0][2][0][RTW89_UK][0][95] = 127, + [1][0][2][0][RTW89_THAILAND][1][95] = 127, + [1][0][2][0][RTW89_THAILAND][0][95] = 127, + [1][0][2][0][RTW89_FCC][1][99] = 34, + [1][0][2][0][RTW89_ETSI][1][99] = 127, + [1][0][2][0][RTW89_ETSI][0][99] = 127, + [1][0][2][0][RTW89_MKK][1][99] = 127, + [1][0][2][0][RTW89_MKK][0][99] = 127, + [1][0][2][0][RTW89_IC][1][99] = 34, + [1][0][2][0][RTW89_KCC][1][99] = 42, + [1][0][2][0][RTW89_KCC][0][99] = 127, + [1][0][2][0][RTW89_ACMA][1][99] = 127, + [1][0][2][0][RTW89_ACMA][0][99] = 127, + [1][0][2][0][RTW89_CHILE][1][99] = 34, + [1][0][2][0][RTW89_QATAR][1][99] = 127, + [1][0][2][0][RTW89_QATAR][0][99] = 127, + [1][0][2][0][RTW89_UK][1][99] = 127, + [1][0][2][0][RTW89_UK][0][99] = 127, + [1][0][2][0][RTW89_THAILAND][1][99] = 127, + [1][0][2][0][RTW89_THAILAND][0][99] = 127, + [1][0][2][0][RTW89_FCC][1][103] = 34, + [1][0][2][0][RTW89_ETSI][1][103] = 127, + [1][0][2][0][RTW89_ETSI][0][103] = 127, + [1][0][2][0][RTW89_MKK][1][103] = 127, + [1][0][2][0][RTW89_MKK][0][103] = 127, + [1][0][2][0][RTW89_IC][1][103] = 34, + [1][0][2][0][RTW89_KCC][1][103] = 42, + [1][0][2][0][RTW89_KCC][0][103] = 127, + [1][0][2][0][RTW89_ACMA][1][103] = 127, + [1][0][2][0][RTW89_ACMA][0][103] = 127, + [1][0][2][0][RTW89_CHILE][1][103] = 34, + [1][0][2][0][RTW89_QATAR][1][103] = 127, + [1][0][2][0][RTW89_QATAR][0][103] = 127, + [1][0][2][0][RTW89_UK][1][103] = 127, + [1][0][2][0][RTW89_UK][0][103] = 127, + [1][0][2][0][RTW89_THAILAND][1][103] = 127, + [1][0][2][0][RTW89_THAILAND][0][103] = 127, + [1][0][2][0][RTW89_FCC][1][106] = 36, + [1][0][2][0][RTW89_ETSI][1][106] = 127, + [1][0][2][0][RTW89_ETSI][0][106] = 127, + [1][0][2][0][RTW89_MKK][1][106] = 127, + [1][0][2][0][RTW89_MKK][0][106] = 127, + [1][0][2][0][RTW89_IC][1][106] = 36, + [1][0][2][0][RTW89_KCC][1][106] = 42, + [1][0][2][0][RTW89_KCC][0][106] = 127, + [1][0][2][0][RTW89_ACMA][1][106] = 127, + [1][0][2][0][RTW89_ACMA][0][106] = 127, + [1][0][2][0][RTW89_CHILE][1][106] = 36, + [1][0][2][0][RTW89_QATAR][1][106] = 127, + [1][0][2][0][RTW89_QATAR][0][106] = 127, + [1][0][2][0][RTW89_UK][1][106] = 127, + [1][0][2][0][RTW89_UK][0][106] = 127, + [1][0][2][0][RTW89_THAILAND][1][106] = 127, + [1][0][2][0][RTW89_THAILAND][0][106] = 127, + [1][0][2][0][RTW89_FCC][1][110] = 127, + [1][0][2][0][RTW89_ETSI][1][110] = 127, + [1][0][2][0][RTW89_ETSI][0][110] = 127, + [1][0][2][0][RTW89_MKK][1][110] = 127, + [1][0][2][0][RTW89_MKK][0][110] = 127, + [1][0][2][0][RTW89_IC][1][110] = 127, + [1][0][2][0][RTW89_KCC][1][110] = 127, + [1][0][2][0][RTW89_KCC][0][110] = 127, + [1][0][2][0][RTW89_ACMA][1][110] = 127, + [1][0][2][0][RTW89_ACMA][0][110] = 127, + [1][0][2][0][RTW89_CHILE][1][110] = 127, + [1][0][2][0][RTW89_QATAR][1][110] = 127, + [1][0][2][0][RTW89_QATAR][0][110] = 127, + [1][0][2][0][RTW89_UK][1][110] = 127, + [1][0][2][0][RTW89_UK][0][110] = 127, + [1][0][2][0][RTW89_THAILAND][1][110] = 127, + [1][0][2][0][RTW89_THAILAND][0][110] = 127, + [1][0][2][0][RTW89_FCC][1][114] = 127, + [1][0][2][0][RTW89_ETSI][1][114] = 127, + [1][0][2][0][RTW89_ETSI][0][114] = 127, + [1][0][2][0][RTW89_MKK][1][114] = 127, + [1][0][2][0][RTW89_MKK][0][114] = 127, + [1][0][2][0][RTW89_IC][1][114] = 127, + [1][0][2][0][RTW89_KCC][1][114] = 127, + [1][0][2][0][RTW89_KCC][0][114] = 127, + [1][0][2][0][RTW89_ACMA][1][114] = 127, + [1][0][2][0][RTW89_ACMA][0][114] = 127, + [1][0][2][0][RTW89_CHILE][1][114] = 127, + [1][0][2][0][RTW89_QATAR][1][114] = 127, + [1][0][2][0][RTW89_QATAR][0][114] = 127, + [1][0][2][0][RTW89_UK][1][114] = 127, + [1][0][2][0][RTW89_UK][0][114] = 127, + [1][0][2][0][RTW89_THAILAND][1][114] = 127, + [1][0][2][0][RTW89_THAILAND][0][114] = 127, + [1][0][2][0][RTW89_FCC][1][118] = 127, + [1][0][2][0][RTW89_ETSI][1][118] = 127, + [1][0][2][0][RTW89_ETSI][0][118] = 127, + [1][0][2][0][RTW89_MKK][1][118] = 127, + [1][0][2][0][RTW89_MKK][0][118] = 127, + [1][0][2][0][RTW89_IC][1][118] = 127, + [1][0][2][0][RTW89_KCC][1][118] = 127, + [1][0][2][0][RTW89_KCC][0][118] = 127, + [1][0][2][0][RTW89_ACMA][1][118] = 127, + [1][0][2][0][RTW89_ACMA][0][118] = 127, + [1][0][2][0][RTW89_CHILE][1][118] = 127, + [1][0][2][0][RTW89_QATAR][1][118] = 127, + [1][0][2][0][RTW89_QATAR][0][118] = 127, + [1][0][2][0][RTW89_UK][1][118] = 127, + [1][0][2][0][RTW89_UK][0][118] = 127, + [1][0][2][0][RTW89_THAILAND][1][118] = 127, + [1][0][2][0][RTW89_THAILAND][0][118] = 127, + [1][1][2][0][RTW89_FCC][1][1] = 10, + [1][1][2][0][RTW89_ETSI][1][1] = 54, + [1][1][2][0][RTW89_ETSI][0][1] = 18, + [1][1][2][0][RTW89_MKK][1][1] = 52, + [1][1][2][0][RTW89_MKK][0][1] = 12, + [1][1][2][0][RTW89_IC][1][1] = 10, + [1][1][2][0][RTW89_KCC][1][1] = 28, + [1][1][2][0][RTW89_KCC][0][1] = 12, + [1][1][2][0][RTW89_ACMA][1][1] = 54, + [1][1][2][0][RTW89_ACMA][0][1] = 18, + [1][1][2][0][RTW89_CHILE][1][1] = 10, + [1][1][2][0][RTW89_QATAR][1][1] = 54, + [1][1][2][0][RTW89_QATAR][0][1] = 18, + [1][1][2][0][RTW89_UK][1][1] = 54, + [1][1][2][0][RTW89_UK][0][1] = 18, + [1][1][2][0][RTW89_THAILAND][1][1] = 46, + [1][1][2][0][RTW89_THAILAND][0][1] = 10, + [1][1][2][0][RTW89_FCC][1][5] = 10, + [1][1][2][0][RTW89_ETSI][1][5] = 54, + [1][1][2][0][RTW89_ETSI][0][5] = 16, + [1][1][2][0][RTW89_MKK][1][5] = 52, + [1][1][2][0][RTW89_MKK][0][5] = 12, + [1][1][2][0][RTW89_IC][1][5] = 10, + [1][1][2][0][RTW89_KCC][1][5] = 28, + [1][1][2][0][RTW89_KCC][0][5] = 12, + [1][1][2][0][RTW89_ACMA][1][5] = 54, + [1][1][2][0][RTW89_ACMA][0][5] = 16, + [1][1][2][0][RTW89_CHILE][1][5] = 10, + [1][1][2][0][RTW89_QATAR][1][5] = 54, + [1][1][2][0][RTW89_QATAR][0][5] = 16, + [1][1][2][0][RTW89_UK][1][5] = 54, + [1][1][2][0][RTW89_UK][0][5] = 16, + [1][1][2][0][RTW89_THAILAND][1][5] = 46, + [1][1][2][0][RTW89_THAILAND][0][5] = 10, + [1][1][2][0][RTW89_FCC][1][9] = 10, + [1][1][2][0][RTW89_ETSI][1][9] = 54, + [1][1][2][0][RTW89_ETSI][0][9] = 16, + [1][1][2][0][RTW89_MKK][1][9] = 52, + [1][1][2][0][RTW89_MKK][0][9] = 12, + [1][1][2][0][RTW89_IC][1][9] = 10, + [1][1][2][0][RTW89_KCC][1][9] = 28, + [1][1][2][0][RTW89_KCC][0][9] = 12, + [1][1][2][0][RTW89_ACMA][1][9] = 54, + [1][1][2][0][RTW89_ACMA][0][9] = 16, + [1][1][2][0][RTW89_CHILE][1][9] = 10, + [1][1][2][0][RTW89_QATAR][1][9] = 54, + [1][1][2][0][RTW89_QATAR][0][9] = 16, + [1][1][2][0][RTW89_UK][1][9] = 54, + [1][1][2][0][RTW89_UK][0][9] = 16, + [1][1][2][0][RTW89_THAILAND][1][9] = 46, + [1][1][2][0][RTW89_THAILAND][0][9] = 10, + [1][1][2][0][RTW89_FCC][1][13] = 10, + [1][1][2][0][RTW89_ETSI][1][13] = 54, + [1][1][2][0][RTW89_ETSI][0][13] = 16, + [1][1][2][0][RTW89_MKK][1][13] = 52, + [1][1][2][0][RTW89_MKK][0][13] = 12, + [1][1][2][0][RTW89_IC][1][13] = 10, + [1][1][2][0][RTW89_KCC][1][13] = 28, + [1][1][2][0][RTW89_KCC][0][13] = 12, + [1][1][2][0][RTW89_ACMA][1][13] = 54, + [1][1][2][0][RTW89_ACMA][0][13] = 16, + [1][1][2][0][RTW89_CHILE][1][13] = 10, + [1][1][2][0][RTW89_QATAR][1][13] = 54, + [1][1][2][0][RTW89_QATAR][0][13] = 16, + [1][1][2][0][RTW89_UK][1][13] = 54, + [1][1][2][0][RTW89_UK][0][13] = 16, + [1][1][2][0][RTW89_THAILAND][1][13] = 46, + [1][1][2][0][RTW89_THAILAND][0][13] = 10, + [1][1][2][0][RTW89_FCC][1][16] = 10, + [1][1][2][0][RTW89_ETSI][1][16] = 54, + [1][1][2][0][RTW89_ETSI][0][16] = 16, + [1][1][2][0][RTW89_MKK][1][16] = 52, + [1][1][2][0][RTW89_MKK][0][16] = 12, + [1][1][2][0][RTW89_IC][1][16] = 10, + [1][1][2][0][RTW89_KCC][1][16] = 28, + [1][1][2][0][RTW89_KCC][0][16] = 12, + [1][1][2][0][RTW89_ACMA][1][16] = 54, + [1][1][2][0][RTW89_ACMA][0][16] = 16, + [1][1][2][0][RTW89_CHILE][1][16] = 10, + [1][1][2][0][RTW89_QATAR][1][16] = 54, + [1][1][2][0][RTW89_QATAR][0][16] = 16, + [1][1][2][0][RTW89_UK][1][16] = 54, + [1][1][2][0][RTW89_UK][0][16] = 16, + [1][1][2][0][RTW89_THAILAND][1][16] = 46, + [1][1][2][0][RTW89_THAILAND][0][16] = 10, + [1][1][2][0][RTW89_FCC][1][20] = 10, + [1][1][2][0][RTW89_ETSI][1][20] = 54, + [1][1][2][0][RTW89_ETSI][0][20] = 16, + [1][1][2][0][RTW89_MKK][1][20] = 52, + [1][1][2][0][RTW89_MKK][0][20] = 12, + [1][1][2][0][RTW89_IC][1][20] = 10, + [1][1][2][0][RTW89_KCC][1][20] = 28, + [1][1][2][0][RTW89_KCC][0][20] = 12, + [1][1][2][0][RTW89_ACMA][1][20] = 54, + [1][1][2][0][RTW89_ACMA][0][20] = 16, + [1][1][2][0][RTW89_CHILE][1][20] = 10, + [1][1][2][0][RTW89_QATAR][1][20] = 54, + [1][1][2][0][RTW89_QATAR][0][20] = 16, + [1][1][2][0][RTW89_UK][1][20] = 54, + [1][1][2][0][RTW89_UK][0][20] = 16, + [1][1][2][0][RTW89_THAILAND][1][20] = 46, + [1][1][2][0][RTW89_THAILAND][0][20] = 10, + [1][1][2][0][RTW89_FCC][1][24] = 10, + [1][1][2][0][RTW89_ETSI][1][24] = 54, + [1][1][2][0][RTW89_ETSI][0][24] = 16, + [1][1][2][0][RTW89_MKK][1][24] = 54, + [1][1][2][0][RTW89_MKK][0][24] = 14, + [1][1][2][0][RTW89_IC][1][24] = 10, + [1][1][2][0][RTW89_KCC][1][24] = 28, + [1][1][2][0][RTW89_KCC][0][24] = 12, + [1][1][2][0][RTW89_ACMA][1][24] = 54, + [1][1][2][0][RTW89_ACMA][0][24] = 16, + [1][1][2][0][RTW89_CHILE][1][24] = 10, + [1][1][2][0][RTW89_QATAR][1][24] = 54, + [1][1][2][0][RTW89_QATAR][0][24] = 16, + [1][1][2][0][RTW89_UK][1][24] = 54, + [1][1][2][0][RTW89_UK][0][24] = 16, + [1][1][2][0][RTW89_THAILAND][1][24] = 46, + [1][1][2][0][RTW89_THAILAND][0][24] = 10, + [1][1][2][0][RTW89_FCC][1][28] = 10, + [1][1][2][0][RTW89_ETSI][1][28] = 54, + [1][1][2][0][RTW89_ETSI][0][28] = 16, + [1][1][2][0][RTW89_MKK][1][28] = 52, + [1][1][2][0][RTW89_MKK][0][28] = 14, + [1][1][2][0][RTW89_IC][1][28] = 10, + [1][1][2][0][RTW89_KCC][1][28] = 28, + [1][1][2][0][RTW89_KCC][0][28] = 14, + [1][1][2][0][RTW89_ACMA][1][28] = 54, + [1][1][2][0][RTW89_ACMA][0][28] = 16, + [1][1][2][0][RTW89_CHILE][1][28] = 10, + [1][1][2][0][RTW89_QATAR][1][28] = 54, + [1][1][2][0][RTW89_QATAR][0][28] = 16, + [1][1][2][0][RTW89_UK][1][28] = 54, + [1][1][2][0][RTW89_UK][0][28] = 16, + [1][1][2][0][RTW89_THAILAND][1][28] = 46, + [1][1][2][0][RTW89_THAILAND][0][28] = 10, + [1][1][2][0][RTW89_FCC][1][31] = 10, + [1][1][2][0][RTW89_ETSI][1][31] = 54, + [1][1][2][0][RTW89_ETSI][0][31] = 16, + [1][1][2][0][RTW89_MKK][1][31] = 52, + [1][1][2][0][RTW89_MKK][0][31] = 14, + [1][1][2][0][RTW89_IC][1][31] = 10, + [1][1][2][0][RTW89_KCC][1][31] = 28, + [1][1][2][0][RTW89_KCC][0][31] = 14, + [1][1][2][0][RTW89_ACMA][1][31] = 54, + [1][1][2][0][RTW89_ACMA][0][31] = 16, + [1][1][2][0][RTW89_CHILE][1][31] = 10, + [1][1][2][0][RTW89_QATAR][1][31] = 54, + [1][1][2][0][RTW89_QATAR][0][31] = 16, + [1][1][2][0][RTW89_UK][1][31] = 54, + [1][1][2][0][RTW89_UK][0][31] = 16, + [1][1][2][0][RTW89_THAILAND][1][31] = 46, + [1][1][2][0][RTW89_THAILAND][0][31] = 10, + [1][1][2][0][RTW89_FCC][1][35] = 10, + [1][1][2][0][RTW89_ETSI][1][35] = 54, + [1][1][2][0][RTW89_ETSI][0][35] = 16, + [1][1][2][0][RTW89_MKK][1][35] = 52, + [1][1][2][0][RTW89_MKK][0][35] = 14, + [1][1][2][0][RTW89_IC][1][35] = 10, + [1][1][2][0][RTW89_KCC][1][35] = 28, + [1][1][2][0][RTW89_KCC][0][35] = 14, + [1][1][2][0][RTW89_ACMA][1][35] = 54, + [1][1][2][0][RTW89_ACMA][0][35] = 16, + [1][1][2][0][RTW89_CHILE][1][35] = 10, + [1][1][2][0][RTW89_QATAR][1][35] = 54, + [1][1][2][0][RTW89_QATAR][0][35] = 16, + [1][1][2][0][RTW89_UK][1][35] = 54, + [1][1][2][0][RTW89_UK][0][35] = 16, + [1][1][2][0][RTW89_THAILAND][1][35] = 46, + [1][1][2][0][RTW89_THAILAND][0][35] = 10, + [1][1][2][0][RTW89_FCC][1][39] = 10, + [1][1][2][0][RTW89_ETSI][1][39] = 54, + [1][1][2][0][RTW89_ETSI][0][39] = 16, + [1][1][2][0][RTW89_MKK][1][39] = 52, + [1][1][2][0][RTW89_MKK][0][39] = 14, + [1][1][2][0][RTW89_IC][1][39] = 10, + [1][1][2][0][RTW89_KCC][1][39] = 28, + [1][1][2][0][RTW89_KCC][0][39] = 14, + [1][1][2][0][RTW89_ACMA][1][39] = 54, + [1][1][2][0][RTW89_ACMA][0][39] = 16, + [1][1][2][0][RTW89_CHILE][1][39] = 10, + [1][1][2][0][RTW89_QATAR][1][39] = 54, + [1][1][2][0][RTW89_QATAR][0][39] = 16, + [1][1][2][0][RTW89_UK][1][39] = 54, + [1][1][2][0][RTW89_UK][0][39] = 16, + [1][1][2][0][RTW89_THAILAND][1][39] = 46, + [1][1][2][0][RTW89_THAILAND][0][39] = 10, + [1][1][2][0][RTW89_FCC][1][43] = 10, + [1][1][2][0][RTW89_ETSI][1][43] = 54, + [1][1][2][0][RTW89_ETSI][0][43] = 16, + [1][1][2][0][RTW89_MKK][1][43] = 52, + [1][1][2][0][RTW89_MKK][0][43] = 14, + [1][1][2][0][RTW89_IC][1][43] = 10, + [1][1][2][0][RTW89_KCC][1][43] = 28, + [1][1][2][0][RTW89_KCC][0][43] = 14, + [1][1][2][0][RTW89_ACMA][1][43] = 54, + [1][1][2][0][RTW89_ACMA][0][43] = 16, + [1][1][2][0][RTW89_CHILE][1][43] = 10, + [1][1][2][0][RTW89_QATAR][1][43] = 54, + [1][1][2][0][RTW89_QATAR][0][43] = 16, + [1][1][2][0][RTW89_UK][1][43] = 54, + [1][1][2][0][RTW89_UK][0][43] = 16, + [1][1][2][0][RTW89_THAILAND][1][43] = 46, + [1][1][2][0][RTW89_THAILAND][0][43] = 10, + [1][1][2][0][RTW89_FCC][1][46] = 12, + [1][1][2][0][RTW89_ETSI][1][46] = 127, + [1][1][2][0][RTW89_ETSI][0][46] = 127, + [1][1][2][0][RTW89_MKK][1][46] = 127, + [1][1][2][0][RTW89_MKK][0][46] = 127, + [1][1][2][0][RTW89_IC][1][46] = 12, + [1][1][2][0][RTW89_KCC][1][46] = 28, + [1][1][2][0][RTW89_KCC][0][46] = 127, + [1][1][2][0][RTW89_ACMA][1][46] = 127, + [1][1][2][0][RTW89_ACMA][0][46] = 127, + [1][1][2][0][RTW89_CHILE][1][46] = 12, + [1][1][2][0][RTW89_QATAR][1][46] = 127, + [1][1][2][0][RTW89_QATAR][0][46] = 127, + [1][1][2][0][RTW89_UK][1][46] = 127, + [1][1][2][0][RTW89_UK][0][46] = 127, + [1][1][2][0][RTW89_THAILAND][1][46] = 127, + [1][1][2][0][RTW89_THAILAND][0][46] = 127, + [1][1][2][0][RTW89_FCC][1][50] = 12, + [1][1][2][0][RTW89_ETSI][1][50] = 127, + [1][1][2][0][RTW89_ETSI][0][50] = 127, + [1][1][2][0][RTW89_MKK][1][50] = 127, + [1][1][2][0][RTW89_MKK][0][50] = 127, + [1][1][2][0][RTW89_IC][1][50] = 12, + [1][1][2][0][RTW89_KCC][1][50] = 28, + [1][1][2][0][RTW89_KCC][0][50] = 127, + [1][1][2][0][RTW89_ACMA][1][50] = 127, + [1][1][2][0][RTW89_ACMA][0][50] = 127, + [1][1][2][0][RTW89_CHILE][1][50] = 12, + [1][1][2][0][RTW89_QATAR][1][50] = 127, + [1][1][2][0][RTW89_QATAR][0][50] = 127, + [1][1][2][0][RTW89_UK][1][50] = 127, + [1][1][2][0][RTW89_UK][0][50] = 127, + [1][1][2][0][RTW89_THAILAND][1][50] = 127, + [1][1][2][0][RTW89_THAILAND][0][50] = 127, + [1][1][2][0][RTW89_FCC][1][54] = 10, + [1][1][2][0][RTW89_ETSI][1][54] = 127, + [1][1][2][0][RTW89_ETSI][0][54] = 127, + [1][1][2][0][RTW89_MKK][1][54] = 127, + [1][1][2][0][RTW89_MKK][0][54] = 127, + [1][1][2][0][RTW89_IC][1][54] = 10, + [1][1][2][0][RTW89_KCC][1][54] = 28, + [1][1][2][0][RTW89_KCC][0][54] = 127, + [1][1][2][0][RTW89_ACMA][1][54] = 127, + [1][1][2][0][RTW89_ACMA][0][54] = 127, + [1][1][2][0][RTW89_CHILE][1][54] = 10, + [1][1][2][0][RTW89_QATAR][1][54] = 127, + [1][1][2][0][RTW89_QATAR][0][54] = 127, + [1][1][2][0][RTW89_UK][1][54] = 127, + [1][1][2][0][RTW89_UK][0][54] = 127, + [1][1][2][0][RTW89_THAILAND][1][54] = 127, + [1][1][2][0][RTW89_THAILAND][0][54] = 127, + [1][1][2][0][RTW89_FCC][1][58] = 10, + [1][1][2][0][RTW89_ETSI][1][58] = 127, + [1][1][2][0][RTW89_ETSI][0][58] = 127, + [1][1][2][0][RTW89_MKK][1][58] = 127, + [1][1][2][0][RTW89_MKK][0][58] = 127, + [1][1][2][0][RTW89_IC][1][58] = 10, + [1][1][2][0][RTW89_KCC][1][58] = 28, + [1][1][2][0][RTW89_KCC][0][58] = 127, + [1][1][2][0][RTW89_ACMA][1][58] = 127, + [1][1][2][0][RTW89_ACMA][0][58] = 127, + [1][1][2][0][RTW89_CHILE][1][58] = 10, + [1][1][2][0][RTW89_QATAR][1][58] = 127, + [1][1][2][0][RTW89_QATAR][0][58] = 127, + [1][1][2][0][RTW89_UK][1][58] = 127, + [1][1][2][0][RTW89_UK][0][58] = 127, + [1][1][2][0][RTW89_THAILAND][1][58] = 127, + [1][1][2][0][RTW89_THAILAND][0][58] = 127, + [1][1][2][0][RTW89_FCC][1][61] = 10, + [1][1][2][0][RTW89_ETSI][1][61] = 127, + [1][1][2][0][RTW89_ETSI][0][61] = 127, + [1][1][2][0][RTW89_MKK][1][61] = 127, + [1][1][2][0][RTW89_MKK][0][61] = 127, + [1][1][2][0][RTW89_IC][1][61] = 10, + [1][1][2][0][RTW89_KCC][1][61] = 28, + [1][1][2][0][RTW89_KCC][0][61] = 127, + [1][1][2][0][RTW89_ACMA][1][61] = 127, + [1][1][2][0][RTW89_ACMA][0][61] = 127, + [1][1][2][0][RTW89_CHILE][1][61] = 10, + [1][1][2][0][RTW89_QATAR][1][61] = 127, + [1][1][2][0][RTW89_QATAR][0][61] = 127, + [1][1][2][0][RTW89_UK][1][61] = 127, + [1][1][2][0][RTW89_UK][0][61] = 127, + [1][1][2][0][RTW89_THAILAND][1][61] = 127, + [1][1][2][0][RTW89_THAILAND][0][61] = 127, + [1][1][2][0][RTW89_FCC][1][65] = 10, + [1][1][2][0][RTW89_ETSI][1][65] = 127, + [1][1][2][0][RTW89_ETSI][0][65] = 127, + [1][1][2][0][RTW89_MKK][1][65] = 127, + [1][1][2][0][RTW89_MKK][0][65] = 127, + [1][1][2][0][RTW89_IC][1][65] = 10, + [1][1][2][0][RTW89_KCC][1][65] = 28, + [1][1][2][0][RTW89_KCC][0][65] = 127, + [1][1][2][0][RTW89_ACMA][1][65] = 127, + [1][1][2][0][RTW89_ACMA][0][65] = 127, + [1][1][2][0][RTW89_CHILE][1][65] = 10, + [1][1][2][0][RTW89_QATAR][1][65] = 127, + [1][1][2][0][RTW89_QATAR][0][65] = 127, + [1][1][2][0][RTW89_UK][1][65] = 127, + [1][1][2][0][RTW89_UK][0][65] = 127, + [1][1][2][0][RTW89_THAILAND][1][65] = 127, + [1][1][2][0][RTW89_THAILAND][0][65] = 127, + [1][1][2][0][RTW89_FCC][1][69] = 10, + [1][1][2][0][RTW89_ETSI][1][69] = 127, + [1][1][2][0][RTW89_ETSI][0][69] = 127, + [1][1][2][0][RTW89_MKK][1][69] = 127, + [1][1][2][0][RTW89_MKK][0][69] = 127, + [1][1][2][0][RTW89_IC][1][69] = 10, + [1][1][2][0][RTW89_KCC][1][69] = 28, + [1][1][2][0][RTW89_KCC][0][69] = 127, + [1][1][2][0][RTW89_ACMA][1][69] = 127, + [1][1][2][0][RTW89_ACMA][0][69] = 127, + [1][1][2][0][RTW89_CHILE][1][69] = 10, + [1][1][2][0][RTW89_QATAR][1][69] = 127, + [1][1][2][0][RTW89_QATAR][0][69] = 127, + [1][1][2][0][RTW89_UK][1][69] = 127, + [1][1][2][0][RTW89_UK][0][69] = 127, + [1][1][2][0][RTW89_THAILAND][1][69] = 127, + [1][1][2][0][RTW89_THAILAND][0][69] = 127, + [1][1][2][0][RTW89_FCC][1][73] = 10, + [1][1][2][0][RTW89_ETSI][1][73] = 127, + [1][1][2][0][RTW89_ETSI][0][73] = 127, + [1][1][2][0][RTW89_MKK][1][73] = 127, + [1][1][2][0][RTW89_MKK][0][73] = 127, + [1][1][2][0][RTW89_IC][1][73] = 10, + [1][1][2][0][RTW89_KCC][1][73] = 28, + [1][1][2][0][RTW89_KCC][0][73] = 127, + [1][1][2][0][RTW89_ACMA][1][73] = 127, + [1][1][2][0][RTW89_ACMA][0][73] = 127, + [1][1][2][0][RTW89_CHILE][1][73] = 10, + [1][1][2][0][RTW89_QATAR][1][73] = 127, + [1][1][2][0][RTW89_QATAR][0][73] = 127, + [1][1][2][0][RTW89_UK][1][73] = 127, + [1][1][2][0][RTW89_UK][0][73] = 127, + [1][1][2][0][RTW89_THAILAND][1][73] = 127, + [1][1][2][0][RTW89_THAILAND][0][73] = 127, + [1][1][2][0][RTW89_FCC][1][76] = 10, + [1][1][2][0][RTW89_ETSI][1][76] = 127, + [1][1][2][0][RTW89_ETSI][0][76] = 127, + [1][1][2][0][RTW89_MKK][1][76] = 127, + [1][1][2][0][RTW89_MKK][0][76] = 127, + [1][1][2][0][RTW89_IC][1][76] = 10, + [1][1][2][0][RTW89_KCC][1][76] = 28, + [1][1][2][0][RTW89_KCC][0][76] = 127, + [1][1][2][0][RTW89_ACMA][1][76] = 127, + [1][1][2][0][RTW89_ACMA][0][76] = 127, + [1][1][2][0][RTW89_CHILE][1][76] = 10, + [1][1][2][0][RTW89_QATAR][1][76] = 127, + [1][1][2][0][RTW89_QATAR][0][76] = 127, + [1][1][2][0][RTW89_UK][1][76] = 127, + [1][1][2][0][RTW89_UK][0][76] = 127, + [1][1][2][0][RTW89_THAILAND][1][76] = 127, + [1][1][2][0][RTW89_THAILAND][0][76] = 127, + [1][1][2][0][RTW89_FCC][1][80] = 10, + [1][1][2][0][RTW89_ETSI][1][80] = 127, + [1][1][2][0][RTW89_ETSI][0][80] = 127, + [1][1][2][0][RTW89_MKK][1][80] = 127, + [1][1][2][0][RTW89_MKK][0][80] = 127, + [1][1][2][0][RTW89_IC][1][80] = 10, + [1][1][2][0][RTW89_KCC][1][80] = 32, + [1][1][2][0][RTW89_KCC][0][80] = 127, + [1][1][2][0][RTW89_ACMA][1][80] = 127, + [1][1][2][0][RTW89_ACMA][0][80] = 127, + [1][1][2][0][RTW89_CHILE][1][80] = 10, + [1][1][2][0][RTW89_QATAR][1][80] = 127, + [1][1][2][0][RTW89_QATAR][0][80] = 127, + [1][1][2][0][RTW89_UK][1][80] = 127, + [1][1][2][0][RTW89_UK][0][80] = 127, + [1][1][2][0][RTW89_THAILAND][1][80] = 127, + [1][1][2][0][RTW89_THAILAND][0][80] = 127, + [1][1][2][0][RTW89_FCC][1][84] = 10, + [1][1][2][0][RTW89_ETSI][1][84] = 127, + [1][1][2][0][RTW89_ETSI][0][84] = 127, + [1][1][2][0][RTW89_MKK][1][84] = 127, + [1][1][2][0][RTW89_MKK][0][84] = 127, + [1][1][2][0][RTW89_IC][1][84] = 10, + [1][1][2][0][RTW89_KCC][1][84] = 32, + [1][1][2][0][RTW89_KCC][0][84] = 127, + [1][1][2][0][RTW89_ACMA][1][84] = 127, + [1][1][2][0][RTW89_ACMA][0][84] = 127, + [1][1][2][0][RTW89_CHILE][1][84] = 10, + [1][1][2][0][RTW89_QATAR][1][84] = 127, + [1][1][2][0][RTW89_QATAR][0][84] = 127, + [1][1][2][0][RTW89_UK][1][84] = 127, + [1][1][2][0][RTW89_UK][0][84] = 127, + [1][1][2][0][RTW89_THAILAND][1][84] = 127, + [1][1][2][0][RTW89_THAILAND][0][84] = 127, + [1][1][2][0][RTW89_FCC][1][88] = 10, + [1][1][2][0][RTW89_ETSI][1][88] = 127, + [1][1][2][0][RTW89_ETSI][0][88] = 127, + [1][1][2][0][RTW89_MKK][1][88] = 127, + [1][1][2][0][RTW89_MKK][0][88] = 127, + [1][1][2][0][RTW89_IC][1][88] = 10, + [1][1][2][0][RTW89_KCC][1][88] = 32, + [1][1][2][0][RTW89_KCC][0][88] = 127, + [1][1][2][0][RTW89_ACMA][1][88] = 127, + [1][1][2][0][RTW89_ACMA][0][88] = 127, + [1][1][2][0][RTW89_CHILE][1][88] = 10, + [1][1][2][0][RTW89_QATAR][1][88] = 127, + [1][1][2][0][RTW89_QATAR][0][88] = 127, + [1][1][2][0][RTW89_UK][1][88] = 127, + [1][1][2][0][RTW89_UK][0][88] = 127, + [1][1][2][0][RTW89_THAILAND][1][88] = 127, + [1][1][2][0][RTW89_THAILAND][0][88] = 127, + [1][1][2][0][RTW89_FCC][1][91] = 12, + [1][1][2][0][RTW89_ETSI][1][91] = 127, + [1][1][2][0][RTW89_ETSI][0][91] = 127, + [1][1][2][0][RTW89_MKK][1][91] = 127, + [1][1][2][0][RTW89_MKK][0][91] = 127, + [1][1][2][0][RTW89_IC][1][91] = 12, + [1][1][2][0][RTW89_KCC][1][91] = 32, + [1][1][2][0][RTW89_KCC][0][91] = 127, + [1][1][2][0][RTW89_ACMA][1][91] = 127, + [1][1][2][0][RTW89_ACMA][0][91] = 127, + [1][1][2][0][RTW89_CHILE][1][91] = 12, + [1][1][2][0][RTW89_QATAR][1][91] = 127, + [1][1][2][0][RTW89_QATAR][0][91] = 127, + [1][1][2][0][RTW89_UK][1][91] = 127, + [1][1][2][0][RTW89_UK][0][91] = 127, + [1][1][2][0][RTW89_THAILAND][1][91] = 127, + [1][1][2][0][RTW89_THAILAND][0][91] = 127, + [1][1][2][0][RTW89_FCC][1][95] = 10, + [1][1][2][0][RTW89_ETSI][1][95] = 127, + [1][1][2][0][RTW89_ETSI][0][95] = 127, + [1][1][2][0][RTW89_MKK][1][95] = 127, + [1][1][2][0][RTW89_MKK][0][95] = 127, + [1][1][2][0][RTW89_IC][1][95] = 10, + [1][1][2][0][RTW89_KCC][1][95] = 32, + [1][1][2][0][RTW89_KCC][0][95] = 127, + [1][1][2][0][RTW89_ACMA][1][95] = 127, + [1][1][2][0][RTW89_ACMA][0][95] = 127, + [1][1][2][0][RTW89_CHILE][1][95] = 10, + [1][1][2][0][RTW89_QATAR][1][95] = 127, + [1][1][2][0][RTW89_QATAR][0][95] = 127, + [1][1][2][0][RTW89_UK][1][95] = 127, + [1][1][2][0][RTW89_UK][0][95] = 127, + [1][1][2][0][RTW89_THAILAND][1][95] = 127, + [1][1][2][0][RTW89_THAILAND][0][95] = 127, + [1][1][2][0][RTW89_FCC][1][99] = 10, + [1][1][2][0][RTW89_ETSI][1][99] = 127, + [1][1][2][0][RTW89_ETSI][0][99] = 127, + [1][1][2][0][RTW89_MKK][1][99] = 127, + [1][1][2][0][RTW89_MKK][0][99] = 127, + [1][1][2][0][RTW89_IC][1][99] = 10, + [1][1][2][0][RTW89_KCC][1][99] = 32, + [1][1][2][0][RTW89_KCC][0][99] = 127, + [1][1][2][0][RTW89_ACMA][1][99] = 127, + [1][1][2][0][RTW89_ACMA][0][99] = 127, + [1][1][2][0][RTW89_CHILE][1][99] = 10, + [1][1][2][0][RTW89_QATAR][1][99] = 127, + [1][1][2][0][RTW89_QATAR][0][99] = 127, + [1][1][2][0][RTW89_UK][1][99] = 127, + [1][1][2][0][RTW89_UK][0][99] = 127, + [1][1][2][0][RTW89_THAILAND][1][99] = 127, + [1][1][2][0][RTW89_THAILAND][0][99] = 127, + [1][1][2][0][RTW89_FCC][1][103] = 10, + [1][1][2][0][RTW89_ETSI][1][103] = 127, + [1][1][2][0][RTW89_ETSI][0][103] = 127, + [1][1][2][0][RTW89_MKK][1][103] = 127, + [1][1][2][0][RTW89_MKK][0][103] = 127, + [1][1][2][0][RTW89_IC][1][103] = 10, + [1][1][2][0][RTW89_KCC][1][103] = 32, + [1][1][2][0][RTW89_KCC][0][103] = 127, + [1][1][2][0][RTW89_ACMA][1][103] = 127, + [1][1][2][0][RTW89_ACMA][0][103] = 127, + [1][1][2][0][RTW89_CHILE][1][103] = 10, + [1][1][2][0][RTW89_QATAR][1][103] = 127, + [1][1][2][0][RTW89_QATAR][0][103] = 127, + [1][1][2][0][RTW89_UK][1][103] = 127, + [1][1][2][0][RTW89_UK][0][103] = 127, + [1][1][2][0][RTW89_THAILAND][1][103] = 127, + [1][1][2][0][RTW89_THAILAND][0][103] = 127, + [1][1][2][0][RTW89_FCC][1][106] = 12, + [1][1][2][0][RTW89_ETSI][1][106] = 127, + [1][1][2][0][RTW89_ETSI][0][106] = 127, + [1][1][2][0][RTW89_MKK][1][106] = 127, + [1][1][2][0][RTW89_MKK][0][106] = 127, + [1][1][2][0][RTW89_IC][1][106] = 12, + [1][1][2][0][RTW89_KCC][1][106] = 32, + [1][1][2][0][RTW89_KCC][0][106] = 127, + [1][1][2][0][RTW89_ACMA][1][106] = 127, + [1][1][2][0][RTW89_ACMA][0][106] = 127, + [1][1][2][0][RTW89_CHILE][1][106] = 12, + [1][1][2][0][RTW89_QATAR][1][106] = 127, + [1][1][2][0][RTW89_QATAR][0][106] = 127, + [1][1][2][0][RTW89_UK][1][106] = 127, + [1][1][2][0][RTW89_UK][0][106] = 127, + [1][1][2][0][RTW89_THAILAND][1][106] = 127, + [1][1][2][0][RTW89_THAILAND][0][106] = 127, + [1][1][2][0][RTW89_FCC][1][110] = 127, + [1][1][2][0][RTW89_ETSI][1][110] = 127, + [1][1][2][0][RTW89_ETSI][0][110] = 127, + [1][1][2][0][RTW89_MKK][1][110] = 127, + [1][1][2][0][RTW89_MKK][0][110] = 127, + [1][1][2][0][RTW89_IC][1][110] = 127, + [1][1][2][0][RTW89_KCC][1][110] = 127, + [1][1][2][0][RTW89_KCC][0][110] = 127, + [1][1][2][0][RTW89_ACMA][1][110] = 127, + [1][1][2][0][RTW89_ACMA][0][110] = 127, + [1][1][2][0][RTW89_CHILE][1][110] = 127, + [1][1][2][0][RTW89_QATAR][1][110] = 127, + [1][1][2][0][RTW89_QATAR][0][110] = 127, + [1][1][2][0][RTW89_UK][1][110] = 127, + [1][1][2][0][RTW89_UK][0][110] = 127, + [1][1][2][0][RTW89_THAILAND][1][110] = 127, + [1][1][2][0][RTW89_THAILAND][0][110] = 127, + [1][1][2][0][RTW89_FCC][1][114] = 127, + [1][1][2][0][RTW89_ETSI][1][114] = 127, + [1][1][2][0][RTW89_ETSI][0][114] = 127, + [1][1][2][0][RTW89_MKK][1][114] = 127, + [1][1][2][0][RTW89_MKK][0][114] = 127, + [1][1][2][0][RTW89_IC][1][114] = 127, + [1][1][2][0][RTW89_KCC][1][114] = 127, + [1][1][2][0][RTW89_KCC][0][114] = 127, + [1][1][2][0][RTW89_ACMA][1][114] = 127, + [1][1][2][0][RTW89_ACMA][0][114] = 127, + [1][1][2][0][RTW89_CHILE][1][114] = 127, + [1][1][2][0][RTW89_QATAR][1][114] = 127, + [1][1][2][0][RTW89_QATAR][0][114] = 127, + [1][1][2][0][RTW89_UK][1][114] = 127, + [1][1][2][0][RTW89_UK][0][114] = 127, + [1][1][2][0][RTW89_THAILAND][1][114] = 127, + [1][1][2][0][RTW89_THAILAND][0][114] = 127, + [1][1][2][0][RTW89_FCC][1][118] = 127, + [1][1][2][0][RTW89_ETSI][1][118] = 127, + [1][1][2][0][RTW89_ETSI][0][118] = 127, + [1][1][2][0][RTW89_MKK][1][118] = 127, + [1][1][2][0][RTW89_MKK][0][118] = 127, + [1][1][2][0][RTW89_IC][1][118] = 127, + [1][1][2][0][RTW89_KCC][1][118] = 127, + [1][1][2][0][RTW89_KCC][0][118] = 127, + [1][1][2][0][RTW89_ACMA][1][118] = 127, + [1][1][2][0][RTW89_ACMA][0][118] = 127, + [1][1][2][0][RTW89_CHILE][1][118] = 127, + [1][1][2][0][RTW89_QATAR][1][118] = 127, + [1][1][2][0][RTW89_QATAR][0][118] = 127, + [1][1][2][0][RTW89_UK][1][118] = 127, + [1][1][2][0][RTW89_UK][0][118] = 127, + [1][1][2][0][RTW89_THAILAND][1][118] = 127, + [1][1][2][0][RTW89_THAILAND][0][118] = 127, + [1][1][2][1][RTW89_FCC][1][1] = 10, + [1][1][2][1][RTW89_ETSI][1][1] = 42, + [1][1][2][1][RTW89_ETSI][0][1] = 6, + [1][1][2][1][RTW89_MKK][1][1] = 52, + [1][1][2][1][RTW89_MKK][0][1] = 12, + [1][1][2][1][RTW89_IC][1][1] = 10, + [1][1][2][1][RTW89_KCC][1][1] = 28, + [1][1][2][1][RTW89_KCC][0][1] = 12, + [1][1][2][1][RTW89_ACMA][1][1] = 42, + [1][1][2][1][RTW89_ACMA][0][1] = 6, + [1][1][2][1][RTW89_CHILE][1][1] = 10, + [1][1][2][1][RTW89_QATAR][1][1] = 42, + [1][1][2][1][RTW89_QATAR][0][1] = 6, + [1][1][2][1][RTW89_UK][1][1] = 42, + [1][1][2][1][RTW89_UK][0][1] = 6, + [1][1][2][1][RTW89_THAILAND][1][1] = 46, + [1][1][2][1][RTW89_THAILAND][0][1] = 6, + [1][1][2][1][RTW89_FCC][1][5] = 10, + [1][1][2][1][RTW89_ETSI][1][5] = 42, + [1][1][2][1][RTW89_ETSI][0][5] = 6, + [1][1][2][1][RTW89_MKK][1][5] = 52, + [1][1][2][1][RTW89_MKK][0][5] = 12, + [1][1][2][1][RTW89_IC][1][5] = 10, + [1][1][2][1][RTW89_KCC][1][5] = 28, + [1][1][2][1][RTW89_KCC][0][5] = 12, + [1][1][2][1][RTW89_ACMA][1][5] = 42, + [1][1][2][1][RTW89_ACMA][0][5] = 6, + [1][1][2][1][RTW89_CHILE][1][5] = 10, + [1][1][2][1][RTW89_QATAR][1][5] = 42, + [1][1][2][1][RTW89_QATAR][0][5] = 6, + [1][1][2][1][RTW89_UK][1][5] = 42, + [1][1][2][1][RTW89_UK][0][5] = 6, + [1][1][2][1][RTW89_THAILAND][1][5] = 46, + [1][1][2][1][RTW89_THAILAND][0][5] = 6, + [1][1][2][1][RTW89_FCC][1][9] = 10, + [1][1][2][1][RTW89_ETSI][1][9] = 42, + [1][1][2][1][RTW89_ETSI][0][9] = 6, + [1][1][2][1][RTW89_MKK][1][9] = 52, + [1][1][2][1][RTW89_MKK][0][9] = 12, + [1][1][2][1][RTW89_IC][1][9] = 10, + [1][1][2][1][RTW89_KCC][1][9] = 28, + [1][1][2][1][RTW89_KCC][0][9] = 12, + [1][1][2][1][RTW89_ACMA][1][9] = 42, + [1][1][2][1][RTW89_ACMA][0][9] = 6, + [1][1][2][1][RTW89_CHILE][1][9] = 10, + [1][1][2][1][RTW89_QATAR][1][9] = 42, + [1][1][2][1][RTW89_QATAR][0][9] = 6, + [1][1][2][1][RTW89_UK][1][9] = 42, + [1][1][2][1][RTW89_UK][0][9] = 6, + [1][1][2][1][RTW89_THAILAND][1][9] = 46, + [1][1][2][1][RTW89_THAILAND][0][9] = 6, + [1][1][2][1][RTW89_FCC][1][13] = 10, + [1][1][2][1][RTW89_ETSI][1][13] = 42, + [1][1][2][1][RTW89_ETSI][0][13] = 6, + [1][1][2][1][RTW89_MKK][1][13] = 52, + [1][1][2][1][RTW89_MKK][0][13] = 12, + [1][1][2][1][RTW89_IC][1][13] = 10, + [1][1][2][1][RTW89_KCC][1][13] = 28, + [1][1][2][1][RTW89_KCC][0][13] = 12, + [1][1][2][1][RTW89_ACMA][1][13] = 42, + [1][1][2][1][RTW89_ACMA][0][13] = 6, + [1][1][2][1][RTW89_CHILE][1][13] = 10, + [1][1][2][1][RTW89_QATAR][1][13] = 42, + [1][1][2][1][RTW89_QATAR][0][13] = 6, + [1][1][2][1][RTW89_UK][1][13] = 42, + [1][1][2][1][RTW89_UK][0][13] = 6, + [1][1][2][1][RTW89_THAILAND][1][13] = 46, + [1][1][2][1][RTW89_THAILAND][0][13] = 6, + [1][1][2][1][RTW89_FCC][1][16] = 10, + [1][1][2][1][RTW89_ETSI][1][16] = 42, + [1][1][2][1][RTW89_ETSI][0][16] = 6, + [1][1][2][1][RTW89_MKK][1][16] = 52, + [1][1][2][1][RTW89_MKK][0][16] = 12, + [1][1][2][1][RTW89_IC][1][16] = 10, + [1][1][2][1][RTW89_KCC][1][16] = 28, + [1][1][2][1][RTW89_KCC][0][16] = 12, + [1][1][2][1][RTW89_ACMA][1][16] = 42, + [1][1][2][1][RTW89_ACMA][0][16] = 6, + [1][1][2][1][RTW89_CHILE][1][16] = 10, + [1][1][2][1][RTW89_QATAR][1][16] = 42, + [1][1][2][1][RTW89_QATAR][0][16] = 6, + [1][1][2][1][RTW89_UK][1][16] = 42, + [1][1][2][1][RTW89_UK][0][16] = 6, + [1][1][2][1][RTW89_THAILAND][1][16] = 46, + [1][1][2][1][RTW89_THAILAND][0][16] = 6, + [1][1][2][1][RTW89_FCC][1][20] = 10, + [1][1][2][1][RTW89_ETSI][1][20] = 42, + [1][1][2][1][RTW89_ETSI][0][20] = 6, + [1][1][2][1][RTW89_MKK][1][20] = 52, + [1][1][2][1][RTW89_MKK][0][20] = 12, + [1][1][2][1][RTW89_IC][1][20] = 10, + [1][1][2][1][RTW89_KCC][1][20] = 28, + [1][1][2][1][RTW89_KCC][0][20] = 12, + [1][1][2][1][RTW89_ACMA][1][20] = 42, + [1][1][2][1][RTW89_ACMA][0][20] = 6, + [1][1][2][1][RTW89_CHILE][1][20] = 10, + [1][1][2][1][RTW89_QATAR][1][20] = 42, + [1][1][2][1][RTW89_QATAR][0][20] = 6, + [1][1][2][1][RTW89_UK][1][20] = 42, + [1][1][2][1][RTW89_UK][0][20] = 6, + [1][1][2][1][RTW89_THAILAND][1][20] = 46, + [1][1][2][1][RTW89_THAILAND][0][20] = 6, + [1][1][2][1][RTW89_FCC][1][24] = 10, + [1][1][2][1][RTW89_ETSI][1][24] = 42, + [1][1][2][1][RTW89_ETSI][0][24] = 6, + [1][1][2][1][RTW89_MKK][1][24] = 54, + [1][1][2][1][RTW89_MKK][0][24] = 14, + [1][1][2][1][RTW89_IC][1][24] = 10, + [1][1][2][1][RTW89_KCC][1][24] = 28, + [1][1][2][1][RTW89_KCC][0][24] = 12, + [1][1][2][1][RTW89_ACMA][1][24] = 42, + [1][1][2][1][RTW89_ACMA][0][24] = 6, + [1][1][2][1][RTW89_CHILE][1][24] = 10, + [1][1][2][1][RTW89_QATAR][1][24] = 42, + [1][1][2][1][RTW89_QATAR][0][24] = 6, + [1][1][2][1][RTW89_UK][1][24] = 42, + [1][1][2][1][RTW89_UK][0][24] = 6, + [1][1][2][1][RTW89_THAILAND][1][24] = 46, + [1][1][2][1][RTW89_THAILAND][0][24] = 6, + [1][1][2][1][RTW89_FCC][1][28] = 10, + [1][1][2][1][RTW89_ETSI][1][28] = 42, + [1][1][2][1][RTW89_ETSI][0][28] = 6, + [1][1][2][1][RTW89_MKK][1][28] = 52, + [1][1][2][1][RTW89_MKK][0][28] = 14, + [1][1][2][1][RTW89_IC][1][28] = 10, + [1][1][2][1][RTW89_KCC][1][28] = 28, + [1][1][2][1][RTW89_KCC][0][28] = 14, + [1][1][2][1][RTW89_ACMA][1][28] = 42, + [1][1][2][1][RTW89_ACMA][0][28] = 6, + [1][1][2][1][RTW89_CHILE][1][28] = 10, + [1][1][2][1][RTW89_QATAR][1][28] = 42, + [1][1][2][1][RTW89_QATAR][0][28] = 6, + [1][1][2][1][RTW89_UK][1][28] = 42, + [1][1][2][1][RTW89_UK][0][28] = 6, + [1][1][2][1][RTW89_THAILAND][1][28] = 46, + [1][1][2][1][RTW89_THAILAND][0][28] = 6, + [1][1][2][1][RTW89_FCC][1][31] = 10, + [1][1][2][1][RTW89_ETSI][1][31] = 42, + [1][1][2][1][RTW89_ETSI][0][31] = 6, + [1][1][2][1][RTW89_MKK][1][31] = 52, + [1][1][2][1][RTW89_MKK][0][31] = 14, + [1][1][2][1][RTW89_IC][1][31] = 10, + [1][1][2][1][RTW89_KCC][1][31] = 28, + [1][1][2][1][RTW89_KCC][0][31] = 14, + [1][1][2][1][RTW89_ACMA][1][31] = 42, + [1][1][2][1][RTW89_ACMA][0][31] = 6, + [1][1][2][1][RTW89_CHILE][1][31] = 10, + [1][1][2][1][RTW89_QATAR][1][31] = 42, + [1][1][2][1][RTW89_QATAR][0][31] = 6, + [1][1][2][1][RTW89_UK][1][31] = 42, + [1][1][2][1][RTW89_UK][0][31] = 6, + [1][1][2][1][RTW89_THAILAND][1][31] = 46, + [1][1][2][1][RTW89_THAILAND][0][31] = 6, + [1][1][2][1][RTW89_FCC][1][35] = 10, + [1][1][2][1][RTW89_ETSI][1][35] = 42, + [1][1][2][1][RTW89_ETSI][0][35] = 6, + [1][1][2][1][RTW89_MKK][1][35] = 52, + [1][1][2][1][RTW89_MKK][0][35] = 14, + [1][1][2][1][RTW89_IC][1][35] = 10, + [1][1][2][1][RTW89_KCC][1][35] = 28, + [1][1][2][1][RTW89_KCC][0][35] = 14, + [1][1][2][1][RTW89_ACMA][1][35] = 42, + [1][1][2][1][RTW89_ACMA][0][35] = 6, + [1][1][2][1][RTW89_CHILE][1][35] = 10, + [1][1][2][1][RTW89_QATAR][1][35] = 42, + [1][1][2][1][RTW89_QATAR][0][35] = 6, + [1][1][2][1][RTW89_UK][1][35] = 42, + [1][1][2][1][RTW89_UK][0][35] = 6, + [1][1][2][1][RTW89_THAILAND][1][35] = 46, + [1][1][2][1][RTW89_THAILAND][0][35] = 6, + [1][1][2][1][RTW89_FCC][1][39] = 10, + [1][1][2][1][RTW89_ETSI][1][39] = 42, + [1][1][2][1][RTW89_ETSI][0][39] = 6, + [1][1][2][1][RTW89_MKK][1][39] = 52, + [1][1][2][1][RTW89_MKK][0][39] = 14, + [1][1][2][1][RTW89_IC][1][39] = 10, + [1][1][2][1][RTW89_KCC][1][39] = 28, + [1][1][2][1][RTW89_KCC][0][39] = 14, + [1][1][2][1][RTW89_ACMA][1][39] = 42, + [1][1][2][1][RTW89_ACMA][0][39] = 6, + [1][1][2][1][RTW89_CHILE][1][39] = 10, + [1][1][2][1][RTW89_QATAR][1][39] = 42, + [1][1][2][1][RTW89_QATAR][0][39] = 6, + [1][1][2][1][RTW89_UK][1][39] = 42, + [1][1][2][1][RTW89_UK][0][39] = 6, + [1][1][2][1][RTW89_THAILAND][1][39] = 46, + [1][1][2][1][RTW89_THAILAND][0][39] = 6, + [1][1][2][1][RTW89_FCC][1][43] = 10, + [1][1][2][1][RTW89_ETSI][1][43] = 42, + [1][1][2][1][RTW89_ETSI][0][43] = 6, + [1][1][2][1][RTW89_MKK][1][43] = 52, + [1][1][2][1][RTW89_MKK][0][43] = 14, + [1][1][2][1][RTW89_IC][1][43] = 10, + [1][1][2][1][RTW89_KCC][1][43] = 28, + [1][1][2][1][RTW89_KCC][0][43] = 14, + [1][1][2][1][RTW89_ACMA][1][43] = 42, + [1][1][2][1][RTW89_ACMA][0][43] = 6, + [1][1][2][1][RTW89_CHILE][1][43] = 10, + [1][1][2][1][RTW89_QATAR][1][43] = 42, + [1][1][2][1][RTW89_QATAR][0][43] = 6, + [1][1][2][1][RTW89_UK][1][43] = 42, + [1][1][2][1][RTW89_UK][0][43] = 6, + [1][1][2][1][RTW89_THAILAND][1][43] = 46, + [1][1][2][1][RTW89_THAILAND][0][43] = 6, + [1][1][2][1][RTW89_FCC][1][46] = 12, + [1][1][2][1][RTW89_ETSI][1][46] = 127, + [1][1][2][1][RTW89_ETSI][0][46] = 127, + [1][1][2][1][RTW89_MKK][1][46] = 127, + [1][1][2][1][RTW89_MKK][0][46] = 127, + [1][1][2][1][RTW89_IC][1][46] = 12, + [1][1][2][1][RTW89_KCC][1][46] = 28, + [1][1][2][1][RTW89_KCC][0][46] = 127, + [1][1][2][1][RTW89_ACMA][1][46] = 127, + [1][1][2][1][RTW89_ACMA][0][46] = 127, + [1][1][2][1][RTW89_CHILE][1][46] = 12, + [1][1][2][1][RTW89_QATAR][1][46] = 127, + [1][1][2][1][RTW89_QATAR][0][46] = 127, + [1][1][2][1][RTW89_UK][1][46] = 127, + [1][1][2][1][RTW89_UK][0][46] = 127, + [1][1][2][1][RTW89_THAILAND][1][46] = 127, + [1][1][2][1][RTW89_THAILAND][0][46] = 127, + [1][1][2][1][RTW89_FCC][1][50] = 12, + [1][1][2][1][RTW89_ETSI][1][50] = 127, + [1][1][2][1][RTW89_ETSI][0][50] = 127, + [1][1][2][1][RTW89_MKK][1][50] = 127, + [1][1][2][1][RTW89_MKK][0][50] = 127, + [1][1][2][1][RTW89_IC][1][50] = 12, + [1][1][2][1][RTW89_KCC][1][50] = 28, + [1][1][2][1][RTW89_KCC][0][50] = 127, + [1][1][2][1][RTW89_ACMA][1][50] = 127, + [1][1][2][1][RTW89_ACMA][0][50] = 127, + [1][1][2][1][RTW89_CHILE][1][50] = 12, + [1][1][2][1][RTW89_QATAR][1][50] = 127, + [1][1][2][1][RTW89_QATAR][0][50] = 127, + [1][1][2][1][RTW89_UK][1][50] = 127, + [1][1][2][1][RTW89_UK][0][50] = 127, + [1][1][2][1][RTW89_THAILAND][1][50] = 127, + [1][1][2][1][RTW89_THAILAND][0][50] = 127, + [1][1][2][1][RTW89_FCC][1][54] = 10, + [1][1][2][1][RTW89_ETSI][1][54] = 127, + [1][1][2][1][RTW89_ETSI][0][54] = 127, + [1][1][2][1][RTW89_MKK][1][54] = 127, + [1][1][2][1][RTW89_MKK][0][54] = 127, + [1][1][2][1][RTW89_IC][1][54] = 10, + [1][1][2][1][RTW89_KCC][1][54] = 28, + [1][1][2][1][RTW89_KCC][0][54] = 127, + [1][1][2][1][RTW89_ACMA][1][54] = 127, + [1][1][2][1][RTW89_ACMA][0][54] = 127, + [1][1][2][1][RTW89_CHILE][1][54] = 10, + [1][1][2][1][RTW89_QATAR][1][54] = 127, + [1][1][2][1][RTW89_QATAR][0][54] = 127, + [1][1][2][1][RTW89_UK][1][54] = 127, + [1][1][2][1][RTW89_UK][0][54] = 127, + [1][1][2][1][RTW89_THAILAND][1][54] = 127, + [1][1][2][1][RTW89_THAILAND][0][54] = 127, + [1][1][2][1][RTW89_FCC][1][58] = 10, + [1][1][2][1][RTW89_ETSI][1][58] = 127, + [1][1][2][1][RTW89_ETSI][0][58] = 127, + [1][1][2][1][RTW89_MKK][1][58] = 127, + [1][1][2][1][RTW89_MKK][0][58] = 127, + [1][1][2][1][RTW89_IC][1][58] = 10, + [1][1][2][1][RTW89_KCC][1][58] = 28, + [1][1][2][1][RTW89_KCC][0][58] = 127, + [1][1][2][1][RTW89_ACMA][1][58] = 127, + [1][1][2][1][RTW89_ACMA][0][58] = 127, + [1][1][2][1][RTW89_CHILE][1][58] = 10, + [1][1][2][1][RTW89_QATAR][1][58] = 127, + [1][1][2][1][RTW89_QATAR][0][58] = 127, + [1][1][2][1][RTW89_UK][1][58] = 127, + [1][1][2][1][RTW89_UK][0][58] = 127, + [1][1][2][1][RTW89_THAILAND][1][58] = 127, + [1][1][2][1][RTW89_THAILAND][0][58] = 127, + [1][1][2][1][RTW89_FCC][1][61] = 10, + [1][1][2][1][RTW89_ETSI][1][61] = 127, + [1][1][2][1][RTW89_ETSI][0][61] = 127, + [1][1][2][1][RTW89_MKK][1][61] = 127, + [1][1][2][1][RTW89_MKK][0][61] = 127, + [1][1][2][1][RTW89_IC][1][61] = 10, + [1][1][2][1][RTW89_KCC][1][61] = 28, + [1][1][2][1][RTW89_KCC][0][61] = 127, + [1][1][2][1][RTW89_ACMA][1][61] = 127, + [1][1][2][1][RTW89_ACMA][0][61] = 127, + [1][1][2][1][RTW89_CHILE][1][61] = 10, + [1][1][2][1][RTW89_QATAR][1][61] = 127, + [1][1][2][1][RTW89_QATAR][0][61] = 127, + [1][1][2][1][RTW89_UK][1][61] = 127, + [1][1][2][1][RTW89_UK][0][61] = 127, + [1][1][2][1][RTW89_THAILAND][1][61] = 127, + [1][1][2][1][RTW89_THAILAND][0][61] = 127, + [1][1][2][1][RTW89_FCC][1][65] = 10, + [1][1][2][1][RTW89_ETSI][1][65] = 127, + [1][1][2][1][RTW89_ETSI][0][65] = 127, + [1][1][2][1][RTW89_MKK][1][65] = 127, + [1][1][2][1][RTW89_MKK][0][65] = 127, + [1][1][2][1][RTW89_IC][1][65] = 10, + [1][1][2][1][RTW89_KCC][1][65] = 28, + [1][1][2][1][RTW89_KCC][0][65] = 127, + [1][1][2][1][RTW89_ACMA][1][65] = 127, + [1][1][2][1][RTW89_ACMA][0][65] = 127, + [1][1][2][1][RTW89_CHILE][1][65] = 10, + [1][1][2][1][RTW89_QATAR][1][65] = 127, + [1][1][2][1][RTW89_QATAR][0][65] = 127, + [1][1][2][1][RTW89_UK][1][65] = 127, + [1][1][2][1][RTW89_UK][0][65] = 127, + [1][1][2][1][RTW89_THAILAND][1][65] = 127, + [1][1][2][1][RTW89_THAILAND][0][65] = 127, + [1][1][2][1][RTW89_FCC][1][69] = 10, + [1][1][2][1][RTW89_ETSI][1][69] = 127, + [1][1][2][1][RTW89_ETSI][0][69] = 127, + [1][1][2][1][RTW89_MKK][1][69] = 127, + [1][1][2][1][RTW89_MKK][0][69] = 127, + [1][1][2][1][RTW89_IC][1][69] = 10, + [1][1][2][1][RTW89_KCC][1][69] = 28, + [1][1][2][1][RTW89_KCC][0][69] = 127, + [1][1][2][1][RTW89_ACMA][1][69] = 127, + [1][1][2][1][RTW89_ACMA][0][69] = 127, + [1][1][2][1][RTW89_CHILE][1][69] = 10, + [1][1][2][1][RTW89_QATAR][1][69] = 127, + [1][1][2][1][RTW89_QATAR][0][69] = 127, + [1][1][2][1][RTW89_UK][1][69] = 127, + [1][1][2][1][RTW89_UK][0][69] = 127, + [1][1][2][1][RTW89_THAILAND][1][69] = 127, + [1][1][2][1][RTW89_THAILAND][0][69] = 127, + [1][1][2][1][RTW89_FCC][1][73] = 10, + [1][1][2][1][RTW89_ETSI][1][73] = 127, + [1][1][2][1][RTW89_ETSI][0][73] = 127, + [1][1][2][1][RTW89_MKK][1][73] = 127, + [1][1][2][1][RTW89_MKK][0][73] = 127, + [1][1][2][1][RTW89_IC][1][73] = 10, + [1][1][2][1][RTW89_KCC][1][73] = 28, + [1][1][2][1][RTW89_KCC][0][73] = 127, + [1][1][2][1][RTW89_ACMA][1][73] = 127, + [1][1][2][1][RTW89_ACMA][0][73] = 127, + [1][1][2][1][RTW89_CHILE][1][73] = 10, + [1][1][2][1][RTW89_QATAR][1][73] = 127, + [1][1][2][1][RTW89_QATAR][0][73] = 127, + [1][1][2][1][RTW89_UK][1][73] = 127, + [1][1][2][1][RTW89_UK][0][73] = 127, + [1][1][2][1][RTW89_THAILAND][1][73] = 127, + [1][1][2][1][RTW89_THAILAND][0][73] = 127, + [1][1][2][1][RTW89_FCC][1][76] = 10, + [1][1][2][1][RTW89_ETSI][1][76] = 127, + [1][1][2][1][RTW89_ETSI][0][76] = 127, + [1][1][2][1][RTW89_MKK][1][76] = 127, + [1][1][2][1][RTW89_MKK][0][76] = 127, + [1][1][2][1][RTW89_IC][1][76] = 10, + [1][1][2][1][RTW89_KCC][1][76] = 28, + [1][1][2][1][RTW89_KCC][0][76] = 127, + [1][1][2][1][RTW89_ACMA][1][76] = 127, + [1][1][2][1][RTW89_ACMA][0][76] = 127, + [1][1][2][1][RTW89_CHILE][1][76] = 10, + [1][1][2][1][RTW89_QATAR][1][76] = 127, + [1][1][2][1][RTW89_QATAR][0][76] = 127, + [1][1][2][1][RTW89_UK][1][76] = 127, + [1][1][2][1][RTW89_UK][0][76] = 127, + [1][1][2][1][RTW89_THAILAND][1][76] = 127, + [1][1][2][1][RTW89_THAILAND][0][76] = 127, + [1][1][2][1][RTW89_FCC][1][80] = 10, + [1][1][2][1][RTW89_ETSI][1][80] = 127, + [1][1][2][1][RTW89_ETSI][0][80] = 127, + [1][1][2][1][RTW89_MKK][1][80] = 127, + [1][1][2][1][RTW89_MKK][0][80] = 127, + [1][1][2][1][RTW89_IC][1][80] = 10, + [1][1][2][1][RTW89_KCC][1][80] = 32, + [1][1][2][1][RTW89_KCC][0][80] = 127, + [1][1][2][1][RTW89_ACMA][1][80] = 127, + [1][1][2][1][RTW89_ACMA][0][80] = 127, + [1][1][2][1][RTW89_CHILE][1][80] = 10, + [1][1][2][1][RTW89_QATAR][1][80] = 127, + [1][1][2][1][RTW89_QATAR][0][80] = 127, + [1][1][2][1][RTW89_UK][1][80] = 127, + [1][1][2][1][RTW89_UK][0][80] = 127, + [1][1][2][1][RTW89_THAILAND][1][80] = 127, + [1][1][2][1][RTW89_THAILAND][0][80] = 127, + [1][1][2][1][RTW89_FCC][1][84] = 10, + [1][1][2][1][RTW89_ETSI][1][84] = 127, + [1][1][2][1][RTW89_ETSI][0][84] = 127, + [1][1][2][1][RTW89_MKK][1][84] = 127, + [1][1][2][1][RTW89_MKK][0][84] = 127, + [1][1][2][1][RTW89_IC][1][84] = 10, + [1][1][2][1][RTW89_KCC][1][84] = 32, + [1][1][2][1][RTW89_KCC][0][84] = 127, + [1][1][2][1][RTW89_ACMA][1][84] = 127, + [1][1][2][1][RTW89_ACMA][0][84] = 127, + [1][1][2][1][RTW89_CHILE][1][84] = 10, + [1][1][2][1][RTW89_QATAR][1][84] = 127, + [1][1][2][1][RTW89_QATAR][0][84] = 127, + [1][1][2][1][RTW89_UK][1][84] = 127, + [1][1][2][1][RTW89_UK][0][84] = 127, + [1][1][2][1][RTW89_THAILAND][1][84] = 127, + [1][1][2][1][RTW89_THAILAND][0][84] = 127, + [1][1][2][1][RTW89_FCC][1][88] = 10, + [1][1][2][1][RTW89_ETSI][1][88] = 127, + [1][1][2][1][RTW89_ETSI][0][88] = 127, + [1][1][2][1][RTW89_MKK][1][88] = 127, + [1][1][2][1][RTW89_MKK][0][88] = 127, + [1][1][2][1][RTW89_IC][1][88] = 10, + [1][1][2][1][RTW89_KCC][1][88] = 32, + [1][1][2][1][RTW89_KCC][0][88] = 127, + [1][1][2][1][RTW89_ACMA][1][88] = 127, + [1][1][2][1][RTW89_ACMA][0][88] = 127, + [1][1][2][1][RTW89_CHILE][1][88] = 10, + [1][1][2][1][RTW89_QATAR][1][88] = 127, + [1][1][2][1][RTW89_QATAR][0][88] = 127, + [1][1][2][1][RTW89_UK][1][88] = 127, + [1][1][2][1][RTW89_UK][0][88] = 127, + [1][1][2][1][RTW89_THAILAND][1][88] = 127, + [1][1][2][1][RTW89_THAILAND][0][88] = 127, + [1][1][2][1][RTW89_FCC][1][91] = 12, + [1][1][2][1][RTW89_ETSI][1][91] = 127, + [1][1][2][1][RTW89_ETSI][0][91] = 127, + [1][1][2][1][RTW89_MKK][1][91] = 127, + [1][1][2][1][RTW89_MKK][0][91] = 127, + [1][1][2][1][RTW89_IC][1][91] = 12, + [1][1][2][1][RTW89_KCC][1][91] = 32, + [1][1][2][1][RTW89_KCC][0][91] = 127, + [1][1][2][1][RTW89_ACMA][1][91] = 127, + [1][1][2][1][RTW89_ACMA][0][91] = 127, + [1][1][2][1][RTW89_CHILE][1][91] = 12, + [1][1][2][1][RTW89_QATAR][1][91] = 127, + [1][1][2][1][RTW89_QATAR][0][91] = 127, + [1][1][2][1][RTW89_UK][1][91] = 127, + [1][1][2][1][RTW89_UK][0][91] = 127, + [1][1][2][1][RTW89_THAILAND][1][91] = 127, + [1][1][2][1][RTW89_THAILAND][0][91] = 127, + [1][1][2][1][RTW89_FCC][1][95] = 10, + [1][1][2][1][RTW89_ETSI][1][95] = 127, + [1][1][2][1][RTW89_ETSI][0][95] = 127, + [1][1][2][1][RTW89_MKK][1][95] = 127, + [1][1][2][1][RTW89_MKK][0][95] = 127, + [1][1][2][1][RTW89_IC][1][95] = 10, + [1][1][2][1][RTW89_KCC][1][95] = 32, + [1][1][2][1][RTW89_KCC][0][95] = 127, + [1][1][2][1][RTW89_ACMA][1][95] = 127, + [1][1][2][1][RTW89_ACMA][0][95] = 127, + [1][1][2][1][RTW89_CHILE][1][95] = 10, + [1][1][2][1][RTW89_QATAR][1][95] = 127, + [1][1][2][1][RTW89_QATAR][0][95] = 127, + [1][1][2][1][RTW89_UK][1][95] = 127, + [1][1][2][1][RTW89_UK][0][95] = 127, + [1][1][2][1][RTW89_THAILAND][1][95] = 127, + [1][1][2][1][RTW89_THAILAND][0][95] = 127, + [1][1][2][1][RTW89_FCC][1][99] = 10, + [1][1][2][1][RTW89_ETSI][1][99] = 127, + [1][1][2][1][RTW89_ETSI][0][99] = 127, + [1][1][2][1][RTW89_MKK][1][99] = 127, + [1][1][2][1][RTW89_MKK][0][99] = 127, + [1][1][2][1][RTW89_IC][1][99] = 10, + [1][1][2][1][RTW89_KCC][1][99] = 32, + [1][1][2][1][RTW89_KCC][0][99] = 127, + [1][1][2][1][RTW89_ACMA][1][99] = 127, + [1][1][2][1][RTW89_ACMA][0][99] = 127, + [1][1][2][1][RTW89_CHILE][1][99] = 10, + [1][1][2][1][RTW89_QATAR][1][99] = 127, + [1][1][2][1][RTW89_QATAR][0][99] = 127, + [1][1][2][1][RTW89_UK][1][99] = 127, + [1][1][2][1][RTW89_UK][0][99] = 127, + [1][1][2][1][RTW89_THAILAND][1][99] = 127, + [1][1][2][1][RTW89_THAILAND][0][99] = 127, + [1][1][2][1][RTW89_FCC][1][103] = 10, + [1][1][2][1][RTW89_ETSI][1][103] = 127, + [1][1][2][1][RTW89_ETSI][0][103] = 127, + [1][1][2][1][RTW89_MKK][1][103] = 127, + [1][1][2][1][RTW89_MKK][0][103] = 127, + [1][1][2][1][RTW89_IC][1][103] = 10, + [1][1][2][1][RTW89_KCC][1][103] = 32, + [1][1][2][1][RTW89_KCC][0][103] = 127, + [1][1][2][1][RTW89_ACMA][1][103] = 127, + [1][1][2][1][RTW89_ACMA][0][103] = 127, + [1][1][2][1][RTW89_CHILE][1][103] = 10, + [1][1][2][1][RTW89_QATAR][1][103] = 127, + [1][1][2][1][RTW89_QATAR][0][103] = 127, + [1][1][2][1][RTW89_UK][1][103] = 127, + [1][1][2][1][RTW89_UK][0][103] = 127, + [1][1][2][1][RTW89_THAILAND][1][103] = 127, + [1][1][2][1][RTW89_THAILAND][0][103] = 127, + [1][1][2][1][RTW89_FCC][1][106] = 12, + [1][1][2][1][RTW89_ETSI][1][106] = 127, + [1][1][2][1][RTW89_ETSI][0][106] = 127, + [1][1][2][1][RTW89_MKK][1][106] = 127, + [1][1][2][1][RTW89_MKK][0][106] = 127, + [1][1][2][1][RTW89_IC][1][106] = 12, + [1][1][2][1][RTW89_KCC][1][106] = 32, + [1][1][2][1][RTW89_KCC][0][106] = 127, + [1][1][2][1][RTW89_ACMA][1][106] = 127, + [1][1][2][1][RTW89_ACMA][0][106] = 127, + [1][1][2][1][RTW89_CHILE][1][106] = 12, + [1][1][2][1][RTW89_QATAR][1][106] = 127, + [1][1][2][1][RTW89_QATAR][0][106] = 127, + [1][1][2][1][RTW89_UK][1][106] = 127, + [1][1][2][1][RTW89_UK][0][106] = 127, + [1][1][2][1][RTW89_THAILAND][1][106] = 127, + [1][1][2][1][RTW89_THAILAND][0][106] = 127, + [1][1][2][1][RTW89_FCC][1][110] = 127, + [1][1][2][1][RTW89_ETSI][1][110] = 127, + [1][1][2][1][RTW89_ETSI][0][110] = 127, + [1][1][2][1][RTW89_MKK][1][110] = 127, + [1][1][2][1][RTW89_MKK][0][110] = 127, + [1][1][2][1][RTW89_IC][1][110] = 127, + [1][1][2][1][RTW89_KCC][1][110] = 127, + [1][1][2][1][RTW89_KCC][0][110] = 127, + [1][1][2][1][RTW89_ACMA][1][110] = 127, + [1][1][2][1][RTW89_ACMA][0][110] = 127, + [1][1][2][1][RTW89_CHILE][1][110] = 127, + [1][1][2][1][RTW89_QATAR][1][110] = 127, + [1][1][2][1][RTW89_QATAR][0][110] = 127, + [1][1][2][1][RTW89_UK][1][110] = 127, + [1][1][2][1][RTW89_UK][0][110] = 127, + [1][1][2][1][RTW89_THAILAND][1][110] = 127, + [1][1][2][1][RTW89_THAILAND][0][110] = 127, + [1][1][2][1][RTW89_FCC][1][114] = 127, + [1][1][2][1][RTW89_ETSI][1][114] = 127, + [1][1][2][1][RTW89_ETSI][0][114] = 127, + [1][1][2][1][RTW89_MKK][1][114] = 127, + [1][1][2][1][RTW89_MKK][0][114] = 127, + [1][1][2][1][RTW89_IC][1][114] = 127, + [1][1][2][1][RTW89_KCC][1][114] = 127, + [1][1][2][1][RTW89_KCC][0][114] = 127, + [1][1][2][1][RTW89_ACMA][1][114] = 127, + [1][1][2][1][RTW89_ACMA][0][114] = 127, + [1][1][2][1][RTW89_CHILE][1][114] = 127, + [1][1][2][1][RTW89_QATAR][1][114] = 127, + [1][1][2][1][RTW89_QATAR][0][114] = 127, + [1][1][2][1][RTW89_UK][1][114] = 127, + [1][1][2][1][RTW89_UK][0][114] = 127, + [1][1][2][1][RTW89_THAILAND][1][114] = 127, + [1][1][2][1][RTW89_THAILAND][0][114] = 127, + [1][1][2][1][RTW89_FCC][1][118] = 127, + [1][1][2][1][RTW89_ETSI][1][118] = 127, + [1][1][2][1][RTW89_ETSI][0][118] = 127, + [1][1][2][1][RTW89_MKK][1][118] = 127, + [1][1][2][1][RTW89_MKK][0][118] = 127, + [1][1][2][1][RTW89_IC][1][118] = 127, + [1][1][2][1][RTW89_KCC][1][118] = 127, + [1][1][2][1][RTW89_KCC][0][118] = 127, + [1][1][2][1][RTW89_ACMA][1][118] = 127, + [1][1][2][1][RTW89_ACMA][0][118] = 127, + [1][1][2][1][RTW89_CHILE][1][118] = 127, + [1][1][2][1][RTW89_QATAR][1][118] = 127, + [1][1][2][1][RTW89_QATAR][0][118] = 127, + [1][1][2][1][RTW89_UK][1][118] = 127, + [1][1][2][1][RTW89_UK][0][118] = 127, + [1][1][2][1][RTW89_THAILAND][1][118] = 127, + [1][1][2][1][RTW89_THAILAND][0][118] = 127, + [2][0][2][0][RTW89_FCC][1][3] = 46, + [2][0][2][0][RTW89_ETSI][1][3] = 58, + [2][0][2][0][RTW89_ETSI][0][3] = 30, + [2][0][2][0][RTW89_MKK][1][3] = 58, + [2][0][2][0][RTW89_MKK][0][3] = 26, + [2][0][2][0][RTW89_IC][1][3] = 46, + [2][0][2][0][RTW89_KCC][1][3] = 50, + [2][0][2][0][RTW89_KCC][0][3] = 24, + [2][0][2][0][RTW89_ACMA][1][3] = 58, + [2][0][2][0][RTW89_ACMA][0][3] = 30, + [2][0][2][0][RTW89_CHILE][1][3] = 46, + [2][0][2][0][RTW89_QATAR][1][3] = 58, + [2][0][2][0][RTW89_QATAR][0][3] = 30, + [2][0][2][0][RTW89_UK][1][3] = 58, + [2][0][2][0][RTW89_UK][0][3] = 30, + [2][0][2][0][RTW89_THAILAND][1][3] = 58, + [2][0][2][0][RTW89_THAILAND][0][3] = 30, + [2][0][2][0][RTW89_FCC][1][11] = 46, + [2][0][2][0][RTW89_ETSI][1][11] = 58, + [2][0][2][0][RTW89_ETSI][0][11] = 30, + [2][0][2][0][RTW89_MKK][1][11] = 58, + [2][0][2][0][RTW89_MKK][0][11] = 24, + [2][0][2][0][RTW89_IC][1][11] = 46, + [2][0][2][0][RTW89_KCC][1][11] = 50, + [2][0][2][0][RTW89_KCC][0][11] = 24, + [2][0][2][0][RTW89_ACMA][1][11] = 58, + [2][0][2][0][RTW89_ACMA][0][11] = 30, + [2][0][2][0][RTW89_CHILE][1][11] = 46, + [2][0][2][0][RTW89_QATAR][1][11] = 58, + [2][0][2][0][RTW89_QATAR][0][11] = 30, + [2][0][2][0][RTW89_UK][1][11] = 58, + [2][0][2][0][RTW89_UK][0][11] = 30, + [2][0][2][0][RTW89_THAILAND][1][11] = 58, + [2][0][2][0][RTW89_THAILAND][0][11] = 30, + [2][0][2][0][RTW89_FCC][1][18] = 46, + [2][0][2][0][RTW89_ETSI][1][18] = 58, + [2][0][2][0][RTW89_ETSI][0][18] = 30, + [2][0][2][0][RTW89_MKK][1][18] = 58, + [2][0][2][0][RTW89_MKK][0][18] = 24, + [2][0][2][0][RTW89_IC][1][18] = 46, + [2][0][2][0][RTW89_KCC][1][18] = 50, + [2][0][2][0][RTW89_KCC][0][18] = 24, + [2][0][2][0][RTW89_ACMA][1][18] = 58, + [2][0][2][0][RTW89_ACMA][0][18] = 30, + [2][0][2][0][RTW89_CHILE][1][18] = 46, + [2][0][2][0][RTW89_QATAR][1][18] = 58, + [2][0][2][0][RTW89_QATAR][0][18] = 30, + [2][0][2][0][RTW89_UK][1][18] = 58, + [2][0][2][0][RTW89_UK][0][18] = 30, + [2][0][2][0][RTW89_THAILAND][1][18] = 58, + [2][0][2][0][RTW89_THAILAND][0][18] = 30, + [2][0][2][0][RTW89_FCC][1][26] = 46, + [2][0][2][0][RTW89_ETSI][1][26] = 58, + [2][0][2][0][RTW89_ETSI][0][26] = 30, + [2][0][2][0][RTW89_MKK][1][26] = 58, + [2][0][2][0][RTW89_MKK][0][26] = 24, + [2][0][2][0][RTW89_IC][1][26] = 46, + [2][0][2][0][RTW89_KCC][1][26] = 50, + [2][0][2][0][RTW89_KCC][0][26] = 26, + [2][0][2][0][RTW89_ACMA][1][26] = 58, + [2][0][2][0][RTW89_ACMA][0][26] = 30, + [2][0][2][0][RTW89_CHILE][1][26] = 46, + [2][0][2][0][RTW89_QATAR][1][26] = 58, + [2][0][2][0][RTW89_QATAR][0][26] = 30, + [2][0][2][0][RTW89_UK][1][26] = 58, + [2][0][2][0][RTW89_UK][0][26] = 30, + [2][0][2][0][RTW89_THAILAND][1][26] = 58, + [2][0][2][0][RTW89_THAILAND][0][26] = 30, + [2][0][2][0][RTW89_FCC][1][33] = 46, + [2][0][2][0][RTW89_ETSI][1][33] = 58, + [2][0][2][0][RTW89_ETSI][0][33] = 30, + [2][0][2][0][RTW89_MKK][1][33] = 58, + [2][0][2][0][RTW89_MKK][0][33] = 24, + [2][0][2][0][RTW89_IC][1][33] = 46, + [2][0][2][0][RTW89_KCC][1][33] = 50, + [2][0][2][0][RTW89_KCC][0][33] = 24, + [2][0][2][0][RTW89_ACMA][1][33] = 58, + [2][0][2][0][RTW89_ACMA][0][33] = 30, + [2][0][2][0][RTW89_CHILE][1][33] = 46, + [2][0][2][0][RTW89_QATAR][1][33] = 58, + [2][0][2][0][RTW89_QATAR][0][33] = 30, + [2][0][2][0][RTW89_UK][1][33] = 58, + [2][0][2][0][RTW89_UK][0][33] = 30, + [2][0][2][0][RTW89_THAILAND][1][33] = 58, + [2][0][2][0][RTW89_THAILAND][0][33] = 30, + [2][0][2][0][RTW89_FCC][1][41] = 46, + [2][0][2][0][RTW89_ETSI][1][41] = 58, + [2][0][2][0][RTW89_ETSI][0][41] = 30, + [2][0][2][0][RTW89_MKK][1][41] = 58, + [2][0][2][0][RTW89_MKK][0][41] = 24, + [2][0][2][0][RTW89_IC][1][41] = 46, + [2][0][2][0][RTW89_KCC][1][41] = 50, + [2][0][2][0][RTW89_KCC][0][41] = 24, + [2][0][2][0][RTW89_ACMA][1][41] = 58, + [2][0][2][0][RTW89_ACMA][0][41] = 30, + [2][0][2][0][RTW89_CHILE][1][41] = 46, + [2][0][2][0][RTW89_QATAR][1][41] = 58, + [2][0][2][0][RTW89_QATAR][0][41] = 30, + [2][0][2][0][RTW89_UK][1][41] = 58, + [2][0][2][0][RTW89_UK][0][41] = 30, + [2][0][2][0][RTW89_THAILAND][1][41] = 58, + [2][0][2][0][RTW89_THAILAND][0][41] = 30, + [2][0][2][0][RTW89_FCC][1][48] = 46, + [2][0][2][0][RTW89_ETSI][1][48] = 127, + [2][0][2][0][RTW89_ETSI][0][48] = 127, + [2][0][2][0][RTW89_MKK][1][48] = 127, + [2][0][2][0][RTW89_MKK][0][48] = 127, + [2][0][2][0][RTW89_IC][1][48] = 46, + [2][0][2][0][RTW89_KCC][1][48] = 48, + [2][0][2][0][RTW89_KCC][0][48] = 127, + [2][0][2][0][RTW89_ACMA][1][48] = 127, + [2][0][2][0][RTW89_ACMA][0][48] = 127, + [2][0][2][0][RTW89_CHILE][1][48] = 46, + [2][0][2][0][RTW89_QATAR][1][48] = 127, + [2][0][2][0][RTW89_QATAR][0][48] = 127, + [2][0][2][0][RTW89_UK][1][48] = 127, + [2][0][2][0][RTW89_UK][0][48] = 127, + [2][0][2][0][RTW89_THAILAND][1][48] = 127, + [2][0][2][0][RTW89_THAILAND][0][48] = 127, + [2][0][2][0][RTW89_FCC][1][56] = 46, + [2][0][2][0][RTW89_ETSI][1][56] = 127, + [2][0][2][0][RTW89_ETSI][0][56] = 127, + [2][0][2][0][RTW89_MKK][1][56] = 127, + [2][0][2][0][RTW89_MKK][0][56] = 127, + [2][0][2][0][RTW89_IC][1][56] = 46, + [2][0][2][0][RTW89_KCC][1][56] = 48, + [2][0][2][0][RTW89_KCC][0][56] = 127, + [2][0][2][0][RTW89_ACMA][1][56] = 127, + [2][0][2][0][RTW89_ACMA][0][56] = 127, + [2][0][2][0][RTW89_CHILE][1][56] = 46, + [2][0][2][0][RTW89_QATAR][1][56] = 127, + [2][0][2][0][RTW89_QATAR][0][56] = 127, + [2][0][2][0][RTW89_UK][1][56] = 127, + [2][0][2][0][RTW89_UK][0][56] = 127, + [2][0][2][0][RTW89_THAILAND][1][56] = 127, + [2][0][2][0][RTW89_THAILAND][0][56] = 127, + [2][0][2][0][RTW89_FCC][1][63] = 46, + [2][0][2][0][RTW89_ETSI][1][63] = 127, + [2][0][2][0][RTW89_ETSI][0][63] = 127, + [2][0][2][0][RTW89_MKK][1][63] = 127, + [2][0][2][0][RTW89_MKK][0][63] = 127, + [2][0][2][0][RTW89_IC][1][63] = 46, + [2][0][2][0][RTW89_KCC][1][63] = 48, + [2][0][2][0][RTW89_KCC][0][63] = 127, + [2][0][2][0][RTW89_ACMA][1][63] = 127, + [2][0][2][0][RTW89_ACMA][0][63] = 127, + [2][0][2][0][RTW89_CHILE][1][63] = 46, + [2][0][2][0][RTW89_QATAR][1][63] = 127, + [2][0][2][0][RTW89_QATAR][0][63] = 127, + [2][0][2][0][RTW89_UK][1][63] = 127, + [2][0][2][0][RTW89_UK][0][63] = 127, + [2][0][2][0][RTW89_THAILAND][1][63] = 127, + [2][0][2][0][RTW89_THAILAND][0][63] = 127, + [2][0][2][0][RTW89_FCC][1][71] = 46, + [2][0][2][0][RTW89_ETSI][1][71] = 127, + [2][0][2][0][RTW89_ETSI][0][71] = 127, + [2][0][2][0][RTW89_MKK][1][71] = 127, + [2][0][2][0][RTW89_MKK][0][71] = 127, + [2][0][2][0][RTW89_IC][1][71] = 46, + [2][0][2][0][RTW89_KCC][1][71] = 48, + [2][0][2][0][RTW89_KCC][0][71] = 127, + [2][0][2][0][RTW89_ACMA][1][71] = 127, + [2][0][2][0][RTW89_ACMA][0][71] = 127, + [2][0][2][0][RTW89_CHILE][1][71] = 46, + [2][0][2][0][RTW89_QATAR][1][71] = 127, + [2][0][2][0][RTW89_QATAR][0][71] = 127, + [2][0][2][0][RTW89_UK][1][71] = 127, + [2][0][2][0][RTW89_UK][0][71] = 127, + [2][0][2][0][RTW89_THAILAND][1][71] = 127, + [2][0][2][0][RTW89_THAILAND][0][71] = 127, + [2][0][2][0][RTW89_FCC][1][78] = 46, + [2][0][2][0][RTW89_ETSI][1][78] = 127, + [2][0][2][0][RTW89_ETSI][0][78] = 127, + [2][0][2][0][RTW89_MKK][1][78] = 127, + [2][0][2][0][RTW89_MKK][0][78] = 127, + [2][0][2][0][RTW89_IC][1][78] = 46, + [2][0][2][0][RTW89_KCC][1][78] = 52, + [2][0][2][0][RTW89_KCC][0][78] = 127, + [2][0][2][0][RTW89_ACMA][1][78] = 127, + [2][0][2][0][RTW89_ACMA][0][78] = 127, + [2][0][2][0][RTW89_CHILE][1][78] = 46, + [2][0][2][0][RTW89_QATAR][1][78] = 127, + [2][0][2][0][RTW89_QATAR][0][78] = 127, + [2][0][2][0][RTW89_UK][1][78] = 127, + [2][0][2][0][RTW89_UK][0][78] = 127, + [2][0][2][0][RTW89_THAILAND][1][78] = 127, + [2][0][2][0][RTW89_THAILAND][0][78] = 127, + [2][0][2][0][RTW89_FCC][1][86] = 46, + [2][0][2][0][RTW89_ETSI][1][86] = 127, + [2][0][2][0][RTW89_ETSI][0][86] = 127, + [2][0][2][0][RTW89_MKK][1][86] = 127, + [2][0][2][0][RTW89_MKK][0][86] = 127, + [2][0][2][0][RTW89_IC][1][86] = 46, + [2][0][2][0][RTW89_KCC][1][86] = 52, + [2][0][2][0][RTW89_KCC][0][86] = 127, + [2][0][2][0][RTW89_ACMA][1][86] = 127, + [2][0][2][0][RTW89_ACMA][0][86] = 127, + [2][0][2][0][RTW89_CHILE][1][86] = 46, + [2][0][2][0][RTW89_QATAR][1][86] = 127, + [2][0][2][0][RTW89_QATAR][0][86] = 127, + [2][0][2][0][RTW89_UK][1][86] = 127, + [2][0][2][0][RTW89_UK][0][86] = 127, + [2][0][2][0][RTW89_THAILAND][1][86] = 127, + [2][0][2][0][RTW89_THAILAND][0][86] = 127, + [2][0][2][0][RTW89_FCC][1][93] = 46, + [2][0][2][0][RTW89_ETSI][1][93] = 127, + [2][0][2][0][RTW89_ETSI][0][93] = 127, + [2][0][2][0][RTW89_MKK][1][93] = 127, + [2][0][2][0][RTW89_MKK][0][93] = 127, + [2][0][2][0][RTW89_IC][1][93] = 46, + [2][0][2][0][RTW89_KCC][1][93] = 50, + [2][0][2][0][RTW89_KCC][0][93] = 127, + [2][0][2][0][RTW89_ACMA][1][93] = 127, + [2][0][2][0][RTW89_ACMA][0][93] = 127, + [2][0][2][0][RTW89_CHILE][1][93] = 46, + [2][0][2][0][RTW89_QATAR][1][93] = 127, + [2][0][2][0][RTW89_QATAR][0][93] = 127, + [2][0][2][0][RTW89_UK][1][93] = 127, + [2][0][2][0][RTW89_UK][0][93] = 127, + [2][0][2][0][RTW89_THAILAND][1][93] = 127, + [2][0][2][0][RTW89_THAILAND][0][93] = 127, + [2][0][2][0][RTW89_FCC][1][101] = 44, + [2][0][2][0][RTW89_ETSI][1][101] = 127, + [2][0][2][0][RTW89_ETSI][0][101] = 127, + [2][0][2][0][RTW89_MKK][1][101] = 127, + [2][0][2][0][RTW89_MKK][0][101] = 127, + [2][0][2][0][RTW89_IC][1][101] = 44, + [2][0][2][0][RTW89_KCC][1][101] = 50, + [2][0][2][0][RTW89_KCC][0][101] = 127, + [2][0][2][0][RTW89_ACMA][1][101] = 127, + [2][0][2][0][RTW89_ACMA][0][101] = 127, + [2][0][2][0][RTW89_CHILE][1][101] = 44, + [2][0][2][0][RTW89_QATAR][1][101] = 127, + [2][0][2][0][RTW89_QATAR][0][101] = 127, + [2][0][2][0][RTW89_UK][1][101] = 127, + [2][0][2][0][RTW89_UK][0][101] = 127, + [2][0][2][0][RTW89_THAILAND][1][101] = 127, + [2][0][2][0][RTW89_THAILAND][0][101] = 127, + [2][0][2][0][RTW89_FCC][1][108] = 127, + [2][0][2][0][RTW89_ETSI][1][108] = 127, + [2][0][2][0][RTW89_ETSI][0][108] = 127, + [2][0][2][0][RTW89_MKK][1][108] = 127, + [2][0][2][0][RTW89_MKK][0][108] = 127, + [2][0][2][0][RTW89_IC][1][108] = 127, + [2][0][2][0][RTW89_KCC][1][108] = 127, + [2][0][2][0][RTW89_KCC][0][108] = 127, + [2][0][2][0][RTW89_ACMA][1][108] = 127, + [2][0][2][0][RTW89_ACMA][0][108] = 127, + [2][0][2][0][RTW89_CHILE][1][108] = 127, + [2][0][2][0][RTW89_QATAR][1][108] = 127, + [2][0][2][0][RTW89_QATAR][0][108] = 127, + [2][0][2][0][RTW89_UK][1][108] = 127, + [2][0][2][0][RTW89_UK][0][108] = 127, + [2][0][2][0][RTW89_THAILAND][1][108] = 127, + [2][0][2][0][RTW89_THAILAND][0][108] = 127, + [2][0][2][0][RTW89_FCC][1][116] = 127, + [2][0][2][0][RTW89_ETSI][1][116] = 127, + [2][0][2][0][RTW89_ETSI][0][116] = 127, + [2][0][2][0][RTW89_MKK][1][116] = 127, + [2][0][2][0][RTW89_MKK][0][116] = 127, + [2][0][2][0][RTW89_IC][1][116] = 127, + [2][0][2][0][RTW89_KCC][1][116] = 127, + [2][0][2][0][RTW89_KCC][0][116] = 127, + [2][0][2][0][RTW89_ACMA][1][116] = 127, + [2][0][2][0][RTW89_ACMA][0][116] = 127, + [2][0][2][0][RTW89_CHILE][1][116] = 127, + [2][0][2][0][RTW89_QATAR][1][116] = 127, + [2][0][2][0][RTW89_QATAR][0][116] = 127, + [2][0][2][0][RTW89_UK][1][116] = 127, + [2][0][2][0][RTW89_UK][0][116] = 127, + [2][0][2][0][RTW89_THAILAND][1][116] = 127, + [2][0][2][0][RTW89_THAILAND][0][116] = 127, + [2][1][2][0][RTW89_FCC][1][3] = 22, + [2][1][2][0][RTW89_ETSI][1][3] = 54, + [2][1][2][0][RTW89_ETSI][0][3] = 16, + [2][1][2][0][RTW89_MKK][1][3] = 52, + [2][1][2][0][RTW89_MKK][0][3] = 14, + [2][1][2][0][RTW89_IC][1][3] = 22, + [2][1][2][0][RTW89_KCC][1][3] = 38, + [2][1][2][0][RTW89_KCC][0][3] = 12, + [2][1][2][0][RTW89_ACMA][1][3] = 54, + [2][1][2][0][RTW89_ACMA][0][3] = 16, + [2][1][2][0][RTW89_CHILE][1][3] = 22, + [2][1][2][0][RTW89_QATAR][1][3] = 54, + [2][1][2][0][RTW89_QATAR][0][3] = 16, + [2][1][2][0][RTW89_UK][1][3] = 54, + [2][1][2][0][RTW89_UK][0][3] = 16, + [2][1][2][0][RTW89_THAILAND][1][3] = 46, + [2][1][2][0][RTW89_THAILAND][0][3] = 18, + [2][1][2][0][RTW89_FCC][1][11] = 20, + [2][1][2][0][RTW89_ETSI][1][11] = 54, + [2][1][2][0][RTW89_ETSI][0][11] = 16, + [2][1][2][0][RTW89_MKK][1][11] = 52, + [2][1][2][0][RTW89_MKK][0][11] = 12, + [2][1][2][0][RTW89_IC][1][11] = 20, + [2][1][2][0][RTW89_KCC][1][11] = 38, + [2][1][2][0][RTW89_KCC][0][11] = 12, + [2][1][2][0][RTW89_ACMA][1][11] = 54, + [2][1][2][0][RTW89_ACMA][0][11] = 16, + [2][1][2][0][RTW89_CHILE][1][11] = 20, + [2][1][2][0][RTW89_QATAR][1][11] = 54, + [2][1][2][0][RTW89_QATAR][0][11] = 16, + [2][1][2][0][RTW89_UK][1][11] = 54, + [2][1][2][0][RTW89_UK][0][11] = 16, + [2][1][2][0][RTW89_THAILAND][1][11] = 46, + [2][1][2][0][RTW89_THAILAND][0][11] = 18, + [2][1][2][0][RTW89_FCC][1][18] = 20, + [2][1][2][0][RTW89_ETSI][1][18] = 54, + [2][1][2][0][RTW89_ETSI][0][18] = 16, + [2][1][2][0][RTW89_MKK][1][18] = 52, + [2][1][2][0][RTW89_MKK][0][18] = 12, + [2][1][2][0][RTW89_IC][1][18] = 20, + [2][1][2][0][RTW89_KCC][1][18] = 38, + [2][1][2][0][RTW89_KCC][0][18] = 12, + [2][1][2][0][RTW89_ACMA][1][18] = 54, + [2][1][2][0][RTW89_ACMA][0][18] = 16, + [2][1][2][0][RTW89_CHILE][1][18] = 20, + [2][1][2][0][RTW89_QATAR][1][18] = 54, + [2][1][2][0][RTW89_QATAR][0][18] = 16, + [2][1][2][0][RTW89_UK][1][18] = 54, + [2][1][2][0][RTW89_UK][0][18] = 16, + [2][1][2][0][RTW89_THAILAND][1][18] = 46, + [2][1][2][0][RTW89_THAILAND][0][18] = 18, + [2][1][2][0][RTW89_FCC][1][26] = 20, + [2][1][2][0][RTW89_ETSI][1][26] = 54, + [2][1][2][0][RTW89_ETSI][0][26] = 16, + [2][1][2][0][RTW89_MKK][1][26] = 52, + [2][1][2][0][RTW89_MKK][0][26] = 12, + [2][1][2][0][RTW89_IC][1][26] = 20, + [2][1][2][0][RTW89_KCC][1][26] = 38, + [2][1][2][0][RTW89_KCC][0][26] = 12, + [2][1][2][0][RTW89_ACMA][1][26] = 54, + [2][1][2][0][RTW89_ACMA][0][26] = 16, + [2][1][2][0][RTW89_CHILE][1][26] = 20, + [2][1][2][0][RTW89_QATAR][1][26] = 54, + [2][1][2][0][RTW89_QATAR][0][26] = 16, + [2][1][2][0][RTW89_UK][1][26] = 54, + [2][1][2][0][RTW89_UK][0][26] = 16, + [2][1][2][0][RTW89_THAILAND][1][26] = 46, + [2][1][2][0][RTW89_THAILAND][0][26] = 18, + [2][1][2][0][RTW89_FCC][1][33] = 20, + [2][1][2][0][RTW89_ETSI][1][33] = 54, + [2][1][2][0][RTW89_ETSI][0][33] = 16, + [2][1][2][0][RTW89_MKK][1][33] = 48, + [2][1][2][0][RTW89_MKK][0][33] = 12, + [2][1][2][0][RTW89_IC][1][33] = 20, + [2][1][2][0][RTW89_KCC][1][33] = 38, + [2][1][2][0][RTW89_KCC][0][33] = 12, + [2][1][2][0][RTW89_ACMA][1][33] = 54, + [2][1][2][0][RTW89_ACMA][0][33] = 16, + [2][1][2][0][RTW89_CHILE][1][33] = 20, + [2][1][2][0][RTW89_QATAR][1][33] = 54, + [2][1][2][0][RTW89_QATAR][0][33] = 16, + [2][1][2][0][RTW89_UK][1][33] = 54, + [2][1][2][0][RTW89_UK][0][33] = 16, + [2][1][2][0][RTW89_THAILAND][1][33] = 46, + [2][1][2][0][RTW89_THAILAND][0][33] = 18, + [2][1][2][0][RTW89_FCC][1][41] = 22, + [2][1][2][0][RTW89_ETSI][1][41] = 54, + [2][1][2][0][RTW89_ETSI][0][41] = 18, + [2][1][2][0][RTW89_MKK][1][41] = 48, + [2][1][2][0][RTW89_MKK][0][41] = 12, + [2][1][2][0][RTW89_IC][1][41] = 22, + [2][1][2][0][RTW89_KCC][1][41] = 38, + [2][1][2][0][RTW89_KCC][0][41] = 12, + [2][1][2][0][RTW89_ACMA][1][41] = 54, + [2][1][2][0][RTW89_ACMA][0][41] = 18, + [2][1][2][0][RTW89_CHILE][1][41] = 22, + [2][1][2][0][RTW89_QATAR][1][41] = 54, + [2][1][2][0][RTW89_QATAR][0][41] = 18, + [2][1][2][0][RTW89_UK][1][41] = 54, + [2][1][2][0][RTW89_UK][0][41] = 18, + [2][1][2][0][RTW89_THAILAND][1][41] = 46, + [2][1][2][0][RTW89_THAILAND][0][41] = 18, + [2][1][2][0][RTW89_FCC][1][48] = 22, + [2][1][2][0][RTW89_ETSI][1][48] = 127, + [2][1][2][0][RTW89_ETSI][0][48] = 127, + [2][1][2][0][RTW89_MKK][1][48] = 127, + [2][1][2][0][RTW89_MKK][0][48] = 127, + [2][1][2][0][RTW89_IC][1][48] = 22, + [2][1][2][0][RTW89_KCC][1][48] = 38, + [2][1][2][0][RTW89_KCC][0][48] = 127, + [2][1][2][0][RTW89_ACMA][1][48] = 127, + [2][1][2][0][RTW89_ACMA][0][48] = 127, + [2][1][2][0][RTW89_CHILE][1][48] = 22, + [2][1][2][0][RTW89_QATAR][1][48] = 127, + [2][1][2][0][RTW89_QATAR][0][48] = 127, + [2][1][2][0][RTW89_UK][1][48] = 127, + [2][1][2][0][RTW89_UK][0][48] = 127, + [2][1][2][0][RTW89_THAILAND][1][48] = 127, + [2][1][2][0][RTW89_THAILAND][0][48] = 127, + [2][1][2][0][RTW89_FCC][1][56] = 20, + [2][1][2][0][RTW89_ETSI][1][56] = 127, + [2][1][2][0][RTW89_ETSI][0][56] = 127, + [2][1][2][0][RTW89_MKK][1][56] = 127, + [2][1][2][0][RTW89_MKK][0][56] = 127, + [2][1][2][0][RTW89_IC][1][56] = 20, + [2][1][2][0][RTW89_KCC][1][56] = 38, + [2][1][2][0][RTW89_KCC][0][56] = 127, + [2][1][2][0][RTW89_ACMA][1][56] = 127, + [2][1][2][0][RTW89_ACMA][0][56] = 127, + [2][1][2][0][RTW89_CHILE][1][56] = 20, + [2][1][2][0][RTW89_QATAR][1][56] = 127, + [2][1][2][0][RTW89_QATAR][0][56] = 127, + [2][1][2][0][RTW89_UK][1][56] = 127, + [2][1][2][0][RTW89_UK][0][56] = 127, + [2][1][2][0][RTW89_THAILAND][1][56] = 127, + [2][1][2][0][RTW89_THAILAND][0][56] = 127, + [2][1][2][0][RTW89_FCC][1][63] = 22, + [2][1][2][0][RTW89_ETSI][1][63] = 127, + [2][1][2][0][RTW89_ETSI][0][63] = 127, + [2][1][2][0][RTW89_MKK][1][63] = 127, + [2][1][2][0][RTW89_MKK][0][63] = 127, + [2][1][2][0][RTW89_IC][1][63] = 22, + [2][1][2][0][RTW89_KCC][1][63] = 38, + [2][1][2][0][RTW89_KCC][0][63] = 127, + [2][1][2][0][RTW89_ACMA][1][63] = 127, + [2][1][2][0][RTW89_ACMA][0][63] = 127, + [2][1][2][0][RTW89_CHILE][1][63] = 22, + [2][1][2][0][RTW89_QATAR][1][63] = 127, + [2][1][2][0][RTW89_QATAR][0][63] = 127, + [2][1][2][0][RTW89_UK][1][63] = 127, + [2][1][2][0][RTW89_UK][0][63] = 127, + [2][1][2][0][RTW89_THAILAND][1][63] = 127, + [2][1][2][0][RTW89_THAILAND][0][63] = 127, + [2][1][2][0][RTW89_FCC][1][71] = 20, + [2][1][2][0][RTW89_ETSI][1][71] = 127, + [2][1][2][0][RTW89_ETSI][0][71] = 127, + [2][1][2][0][RTW89_MKK][1][71] = 127, + [2][1][2][0][RTW89_MKK][0][71] = 127, + [2][1][2][0][RTW89_IC][1][71] = 20, + [2][1][2][0][RTW89_KCC][1][71] = 38, + [2][1][2][0][RTW89_KCC][0][71] = 127, + [2][1][2][0][RTW89_ACMA][1][71] = 127, + [2][1][2][0][RTW89_ACMA][0][71] = 127, + [2][1][2][0][RTW89_CHILE][1][71] = 20, + [2][1][2][0][RTW89_QATAR][1][71] = 127, + [2][1][2][0][RTW89_QATAR][0][71] = 127, + [2][1][2][0][RTW89_UK][1][71] = 127, + [2][1][2][0][RTW89_UK][0][71] = 127, + [2][1][2][0][RTW89_THAILAND][1][71] = 127, + [2][1][2][0][RTW89_THAILAND][0][71] = 127, + [2][1][2][0][RTW89_FCC][1][78] = 20, + [2][1][2][0][RTW89_ETSI][1][78] = 127, + [2][1][2][0][RTW89_ETSI][0][78] = 127, + [2][1][2][0][RTW89_MKK][1][78] = 127, + [2][1][2][0][RTW89_MKK][0][78] = 127, + [2][1][2][0][RTW89_IC][1][78] = 20, + [2][1][2][0][RTW89_KCC][1][78] = 38, + [2][1][2][0][RTW89_KCC][0][78] = 127, + [2][1][2][0][RTW89_ACMA][1][78] = 127, + [2][1][2][0][RTW89_ACMA][0][78] = 127, + [2][1][2][0][RTW89_CHILE][1][78] = 20, + [2][1][2][0][RTW89_QATAR][1][78] = 127, + [2][1][2][0][RTW89_QATAR][0][78] = 127, + [2][1][2][0][RTW89_UK][1][78] = 127, + [2][1][2][0][RTW89_UK][0][78] = 127, + [2][1][2][0][RTW89_THAILAND][1][78] = 127, + [2][1][2][0][RTW89_THAILAND][0][78] = 127, + [2][1][2][0][RTW89_FCC][1][86] = 20, + [2][1][2][0][RTW89_ETSI][1][86] = 127, + [2][1][2][0][RTW89_ETSI][0][86] = 127, + [2][1][2][0][RTW89_MKK][1][86] = 127, + [2][1][2][0][RTW89_MKK][0][86] = 127, + [2][1][2][0][RTW89_IC][1][86] = 20, + [2][1][2][0][RTW89_KCC][1][86] = 38, + [2][1][2][0][RTW89_KCC][0][86] = 127, + [2][1][2][0][RTW89_ACMA][1][86] = 127, + [2][1][2][0][RTW89_ACMA][0][86] = 127, + [2][1][2][0][RTW89_CHILE][1][86] = 20, + [2][1][2][0][RTW89_QATAR][1][86] = 127, + [2][1][2][0][RTW89_QATAR][0][86] = 127, + [2][1][2][0][RTW89_UK][1][86] = 127, + [2][1][2][0][RTW89_UK][0][86] = 127, + [2][1][2][0][RTW89_THAILAND][1][86] = 127, + [2][1][2][0][RTW89_THAILAND][0][86] = 127, + [2][1][2][0][RTW89_FCC][1][93] = 22, + [2][1][2][0][RTW89_ETSI][1][93] = 127, + [2][1][2][0][RTW89_ETSI][0][93] = 127, + [2][1][2][0][RTW89_MKK][1][93] = 127, + [2][1][2][0][RTW89_MKK][0][93] = 127, + [2][1][2][0][RTW89_IC][1][93] = 22, + [2][1][2][0][RTW89_KCC][1][93] = 38, + [2][1][2][0][RTW89_KCC][0][93] = 127, + [2][1][2][0][RTW89_ACMA][1][93] = 127, + [2][1][2][0][RTW89_ACMA][0][93] = 127, + [2][1][2][0][RTW89_CHILE][1][93] = 22, + [2][1][2][0][RTW89_QATAR][1][93] = 127, + [2][1][2][0][RTW89_QATAR][0][93] = 127, + [2][1][2][0][RTW89_UK][1][93] = 127, + [2][1][2][0][RTW89_UK][0][93] = 127, + [2][1][2][0][RTW89_THAILAND][1][93] = 127, + [2][1][2][0][RTW89_THAILAND][0][93] = 127, + [2][1][2][0][RTW89_FCC][1][101] = 22, + [2][1][2][0][RTW89_ETSI][1][101] = 127, + [2][1][2][0][RTW89_ETSI][0][101] = 127, + [2][1][2][0][RTW89_MKK][1][101] = 127, + [2][1][2][0][RTW89_MKK][0][101] = 127, + [2][1][2][0][RTW89_IC][1][101] = 22, + [2][1][2][0][RTW89_KCC][1][101] = 38, + [2][1][2][0][RTW89_KCC][0][101] = 127, + [2][1][2][0][RTW89_ACMA][1][101] = 127, + [2][1][2][0][RTW89_ACMA][0][101] = 127, + [2][1][2][0][RTW89_CHILE][1][101] = 22, + [2][1][2][0][RTW89_QATAR][1][101] = 127, + [2][1][2][0][RTW89_QATAR][0][101] = 127, + [2][1][2][0][RTW89_UK][1][101] = 127, + [2][1][2][0][RTW89_UK][0][101] = 127, + [2][1][2][0][RTW89_THAILAND][1][101] = 127, + [2][1][2][0][RTW89_THAILAND][0][101] = 127, + [2][1][2][0][RTW89_FCC][1][108] = 127, + [2][1][2][0][RTW89_ETSI][1][108] = 127, + [2][1][2][0][RTW89_ETSI][0][108] = 127, + [2][1][2][0][RTW89_MKK][1][108] = 127, + [2][1][2][0][RTW89_MKK][0][108] = 127, + [2][1][2][0][RTW89_IC][1][108] = 127, + [2][1][2][0][RTW89_KCC][1][108] = 127, + [2][1][2][0][RTW89_KCC][0][108] = 127, + [2][1][2][0][RTW89_ACMA][1][108] = 127, + [2][1][2][0][RTW89_ACMA][0][108] = 127, + [2][1][2][0][RTW89_CHILE][1][108] = 127, + [2][1][2][0][RTW89_QATAR][1][108] = 127, + [2][1][2][0][RTW89_QATAR][0][108] = 127, + [2][1][2][0][RTW89_UK][1][108] = 127, + [2][1][2][0][RTW89_UK][0][108] = 127, + [2][1][2][0][RTW89_THAILAND][1][108] = 127, + [2][1][2][0][RTW89_THAILAND][0][108] = 127, + [2][1][2][0][RTW89_FCC][1][116] = 127, + [2][1][2][0][RTW89_ETSI][1][116] = 127, + [2][1][2][0][RTW89_ETSI][0][116] = 127, + [2][1][2][0][RTW89_MKK][1][116] = 127, + [2][1][2][0][RTW89_MKK][0][116] = 127, + [2][1][2][0][RTW89_IC][1][116] = 127, + [2][1][2][0][RTW89_KCC][1][116] = 127, + [2][1][2][0][RTW89_KCC][0][116] = 127, + [2][1][2][0][RTW89_ACMA][1][116] = 127, + [2][1][2][0][RTW89_ACMA][0][116] = 127, + [2][1][2][0][RTW89_CHILE][1][116] = 127, + [2][1][2][0][RTW89_QATAR][1][116] = 127, + [2][1][2][0][RTW89_QATAR][0][116] = 127, + [2][1][2][0][RTW89_UK][1][116] = 127, + [2][1][2][0][RTW89_UK][0][116] = 127, + [2][1][2][0][RTW89_THAILAND][1][116] = 127, + [2][1][2][0][RTW89_THAILAND][0][116] = 127, + [2][1][2][1][RTW89_FCC][1][3] = 22, + [2][1][2][1][RTW89_ETSI][1][3] = 42, + [2][1][2][1][RTW89_ETSI][0][3] = 6, + [2][1][2][1][RTW89_MKK][1][3] = 52, + [2][1][2][1][RTW89_MKK][0][3] = 14, + [2][1][2][1][RTW89_IC][1][3] = 22, + [2][1][2][1][RTW89_KCC][1][3] = 38, + [2][1][2][1][RTW89_KCC][0][3] = 12, + [2][1][2][1][RTW89_ACMA][1][3] = 42, + [2][1][2][1][RTW89_ACMA][0][3] = 6, + [2][1][2][1][RTW89_CHILE][1][3] = 22, + [2][1][2][1][RTW89_QATAR][1][3] = 42, + [2][1][2][1][RTW89_QATAR][0][3] = 6, + [2][1][2][1][RTW89_UK][1][3] = 42, + [2][1][2][1][RTW89_UK][0][3] = 6, + [2][1][2][1][RTW89_THAILAND][1][3] = 46, + [2][1][2][1][RTW89_THAILAND][0][3] = 6, + [2][1][2][1][RTW89_FCC][1][11] = 20, + [2][1][2][1][RTW89_ETSI][1][11] = 42, + [2][1][2][1][RTW89_ETSI][0][11] = 6, + [2][1][2][1][RTW89_MKK][1][11] = 52, + [2][1][2][1][RTW89_MKK][0][11] = 12, + [2][1][2][1][RTW89_IC][1][11] = 20, + [2][1][2][1][RTW89_KCC][1][11] = 38, + [2][1][2][1][RTW89_KCC][0][11] = 12, + [2][1][2][1][RTW89_ACMA][1][11] = 42, + [2][1][2][1][RTW89_ACMA][0][11] = 6, + [2][1][2][1][RTW89_CHILE][1][11] = 20, + [2][1][2][1][RTW89_QATAR][1][11] = 42, + [2][1][2][1][RTW89_QATAR][0][11] = 6, + [2][1][2][1][RTW89_UK][1][11] = 42, + [2][1][2][1][RTW89_UK][0][11] = 6, + [2][1][2][1][RTW89_THAILAND][1][11] = 46, + [2][1][2][1][RTW89_THAILAND][0][11] = 6, + [2][1][2][1][RTW89_FCC][1][18] = 20, + [2][1][2][1][RTW89_ETSI][1][18] = 42, + [2][1][2][1][RTW89_ETSI][0][18] = 6, + [2][1][2][1][RTW89_MKK][1][18] = 52, + [2][1][2][1][RTW89_MKK][0][18] = 12, + [2][1][2][1][RTW89_IC][1][18] = 20, + [2][1][2][1][RTW89_KCC][1][18] = 38, + [2][1][2][1][RTW89_KCC][0][18] = 12, + [2][1][2][1][RTW89_ACMA][1][18] = 42, + [2][1][2][1][RTW89_ACMA][0][18] = 6, + [2][1][2][1][RTW89_CHILE][1][18] = 20, + [2][1][2][1][RTW89_QATAR][1][18] = 42, + [2][1][2][1][RTW89_QATAR][0][18] = 6, + [2][1][2][1][RTW89_UK][1][18] = 42, + [2][1][2][1][RTW89_UK][0][18] = 6, + [2][1][2][1][RTW89_THAILAND][1][18] = 46, + [2][1][2][1][RTW89_THAILAND][0][18] = 6, + [2][1][2][1][RTW89_FCC][1][26] = 20, + [2][1][2][1][RTW89_ETSI][1][26] = 42, + [2][1][2][1][RTW89_ETSI][0][26] = 6, + [2][1][2][1][RTW89_MKK][1][26] = 52, + [2][1][2][1][RTW89_MKK][0][26] = 12, + [2][1][2][1][RTW89_IC][1][26] = 20, + [2][1][2][1][RTW89_KCC][1][26] = 38, + [2][1][2][1][RTW89_KCC][0][26] = 12, + [2][1][2][1][RTW89_ACMA][1][26] = 42, + [2][1][2][1][RTW89_ACMA][0][26] = 6, + [2][1][2][1][RTW89_CHILE][1][26] = 20, + [2][1][2][1][RTW89_QATAR][1][26] = 42, + [2][1][2][1][RTW89_QATAR][0][26] = 6, + [2][1][2][1][RTW89_UK][1][26] = 42, + [2][1][2][1][RTW89_UK][0][26] = 6, + [2][1][2][1][RTW89_THAILAND][1][26] = 46, + [2][1][2][1][RTW89_THAILAND][0][26] = 6, + [2][1][2][1][RTW89_FCC][1][33] = 20, + [2][1][2][1][RTW89_ETSI][1][33] = 42, + [2][1][2][1][RTW89_ETSI][0][33] = 6, + [2][1][2][1][RTW89_MKK][1][33] = 48, + [2][1][2][1][RTW89_MKK][0][33] = 12, + [2][1][2][1][RTW89_IC][1][33] = 20, + [2][1][2][1][RTW89_KCC][1][33] = 38, + [2][1][2][1][RTW89_KCC][0][33] = 12, + [2][1][2][1][RTW89_ACMA][1][33] = 42, + [2][1][2][1][RTW89_ACMA][0][33] = 6, + [2][1][2][1][RTW89_CHILE][1][33] = 20, + [2][1][2][1][RTW89_QATAR][1][33] = 42, + [2][1][2][1][RTW89_QATAR][0][33] = 6, + [2][1][2][1][RTW89_UK][1][33] = 42, + [2][1][2][1][RTW89_UK][0][33] = 6, + [2][1][2][1][RTW89_THAILAND][1][33] = 46, + [2][1][2][1][RTW89_THAILAND][0][33] = 6, + [2][1][2][1][RTW89_FCC][1][41] = 22, + [2][1][2][1][RTW89_ETSI][1][41] = 42, + [2][1][2][1][RTW89_ETSI][0][41] = 6, + [2][1][2][1][RTW89_MKK][1][41] = 48, + [2][1][2][1][RTW89_MKK][0][41] = 12, + [2][1][2][1][RTW89_IC][1][41] = 22, + [2][1][2][1][RTW89_KCC][1][41] = 38, + [2][1][2][1][RTW89_KCC][0][41] = 12, + [2][1][2][1][RTW89_ACMA][1][41] = 42, + [2][1][2][1][RTW89_ACMA][0][41] = 6, + [2][1][2][1][RTW89_CHILE][1][41] = 22, + [2][1][2][1][RTW89_QATAR][1][41] = 42, + [2][1][2][1][RTW89_QATAR][0][41] = 6, + [2][1][2][1][RTW89_UK][1][41] = 42, + [2][1][2][1][RTW89_UK][0][41] = 6, + [2][1][2][1][RTW89_THAILAND][1][41] = 46, + [2][1][2][1][RTW89_THAILAND][0][41] = 6, + [2][1][2][1][RTW89_FCC][1][48] = 22, + [2][1][2][1][RTW89_ETSI][1][48] = 127, + [2][1][2][1][RTW89_ETSI][0][48] = 127, + [2][1][2][1][RTW89_MKK][1][48] = 127, + [2][1][2][1][RTW89_MKK][0][48] = 127, + [2][1][2][1][RTW89_IC][1][48] = 22, + [2][1][2][1][RTW89_KCC][1][48] = 38, + [2][1][2][1][RTW89_KCC][0][48] = 127, + [2][1][2][1][RTW89_ACMA][1][48] = 127, + [2][1][2][1][RTW89_ACMA][0][48] = 127, + [2][1][2][1][RTW89_CHILE][1][48] = 22, + [2][1][2][1][RTW89_QATAR][1][48] = 127, + [2][1][2][1][RTW89_QATAR][0][48] = 127, + [2][1][2][1][RTW89_UK][1][48] = 127, + [2][1][2][1][RTW89_UK][0][48] = 127, + [2][1][2][1][RTW89_THAILAND][1][48] = 127, + [2][1][2][1][RTW89_THAILAND][0][48] = 127, + [2][1][2][1][RTW89_FCC][1][56] = 20, + [2][1][2][1][RTW89_ETSI][1][56] = 127, + [2][1][2][1][RTW89_ETSI][0][56] = 127, + [2][1][2][1][RTW89_MKK][1][56] = 127, + [2][1][2][1][RTW89_MKK][0][56] = 127, + [2][1][2][1][RTW89_IC][1][56] = 20, + [2][1][2][1][RTW89_KCC][1][56] = 38, + [2][1][2][1][RTW89_KCC][0][56] = 127, + [2][1][2][1][RTW89_ACMA][1][56] = 127, + [2][1][2][1][RTW89_ACMA][0][56] = 127, + [2][1][2][1][RTW89_CHILE][1][56] = 20, + [2][1][2][1][RTW89_QATAR][1][56] = 127, + [2][1][2][1][RTW89_QATAR][0][56] = 127, + [2][1][2][1][RTW89_UK][1][56] = 127, + [2][1][2][1][RTW89_UK][0][56] = 127, + [2][1][2][1][RTW89_THAILAND][1][56] = 127, + [2][1][2][1][RTW89_THAILAND][0][56] = 127, + [2][1][2][1][RTW89_FCC][1][63] = 22, + [2][1][2][1][RTW89_ETSI][1][63] = 127, + [2][1][2][1][RTW89_ETSI][0][63] = 127, + [2][1][2][1][RTW89_MKK][1][63] = 127, + [2][1][2][1][RTW89_MKK][0][63] = 127, + [2][1][2][1][RTW89_IC][1][63] = 22, + [2][1][2][1][RTW89_KCC][1][63] = 38, + [2][1][2][1][RTW89_KCC][0][63] = 127, + [2][1][2][1][RTW89_ACMA][1][63] = 127, + [2][1][2][1][RTW89_ACMA][0][63] = 127, + [2][1][2][1][RTW89_CHILE][1][63] = 22, + [2][1][2][1][RTW89_QATAR][1][63] = 127, + [2][1][2][1][RTW89_QATAR][0][63] = 127, + [2][1][2][1][RTW89_UK][1][63] = 127, + [2][1][2][1][RTW89_UK][0][63] = 127, + [2][1][2][1][RTW89_THAILAND][1][63] = 127, + [2][1][2][1][RTW89_THAILAND][0][63] = 127, + [2][1][2][1][RTW89_FCC][1][71] = 20, + [2][1][2][1][RTW89_ETSI][1][71] = 127, + [2][1][2][1][RTW89_ETSI][0][71] = 127, + [2][1][2][1][RTW89_MKK][1][71] = 127, + [2][1][2][1][RTW89_MKK][0][71] = 127, + [2][1][2][1][RTW89_IC][1][71] = 20, + [2][1][2][1][RTW89_KCC][1][71] = 38, + [2][1][2][1][RTW89_KCC][0][71] = 127, + [2][1][2][1][RTW89_ACMA][1][71] = 127, + [2][1][2][1][RTW89_ACMA][0][71] = 127, + [2][1][2][1][RTW89_CHILE][1][71] = 20, + [2][1][2][1][RTW89_QATAR][1][71] = 127, + [2][1][2][1][RTW89_QATAR][0][71] = 127, + [2][1][2][1][RTW89_UK][1][71] = 127, + [2][1][2][1][RTW89_UK][0][71] = 127, + [2][1][2][1][RTW89_THAILAND][1][71] = 127, + [2][1][2][1][RTW89_THAILAND][0][71] = 127, + [2][1][2][1][RTW89_FCC][1][78] = 20, + [2][1][2][1][RTW89_ETSI][1][78] = 127, + [2][1][2][1][RTW89_ETSI][0][78] = 127, + [2][1][2][1][RTW89_MKK][1][78] = 127, + [2][1][2][1][RTW89_MKK][0][78] = 127, + [2][1][2][1][RTW89_IC][1][78] = 20, + [2][1][2][1][RTW89_KCC][1][78] = 38, + [2][1][2][1][RTW89_KCC][0][78] = 127, + [2][1][2][1][RTW89_ACMA][1][78] = 127, + [2][1][2][1][RTW89_ACMA][0][78] = 127, + [2][1][2][1][RTW89_CHILE][1][78] = 20, + [2][1][2][1][RTW89_QATAR][1][78] = 127, + [2][1][2][1][RTW89_QATAR][0][78] = 127, + [2][1][2][1][RTW89_UK][1][78] = 127, + [2][1][2][1][RTW89_UK][0][78] = 127, + [2][1][2][1][RTW89_THAILAND][1][78] = 127, + [2][1][2][1][RTW89_THAILAND][0][78] = 127, + [2][1][2][1][RTW89_FCC][1][86] = 20, + [2][1][2][1][RTW89_ETSI][1][86] = 127, + [2][1][2][1][RTW89_ETSI][0][86] = 127, + [2][1][2][1][RTW89_MKK][1][86] = 127, + [2][1][2][1][RTW89_MKK][0][86] = 127, + [2][1][2][1][RTW89_IC][1][86] = 20, + [2][1][2][1][RTW89_KCC][1][86] = 38, + [2][1][2][1][RTW89_KCC][0][86] = 127, + [2][1][2][1][RTW89_ACMA][1][86] = 127, + [2][1][2][1][RTW89_ACMA][0][86] = 127, + [2][1][2][1][RTW89_CHILE][1][86] = 20, + [2][1][2][1][RTW89_QATAR][1][86] = 127, + [2][1][2][1][RTW89_QATAR][0][86] = 127, + [2][1][2][1][RTW89_UK][1][86] = 127, + [2][1][2][1][RTW89_UK][0][86] = 127, + [2][1][2][1][RTW89_THAILAND][1][86] = 127, + [2][1][2][1][RTW89_THAILAND][0][86] = 127, + [2][1][2][1][RTW89_FCC][1][93] = 22, + [2][1][2][1][RTW89_ETSI][1][93] = 127, + [2][1][2][1][RTW89_ETSI][0][93] = 127, + [2][1][2][1][RTW89_MKK][1][93] = 127, + [2][1][2][1][RTW89_MKK][0][93] = 127, + [2][1][2][1][RTW89_IC][1][93] = 22, + [2][1][2][1][RTW89_KCC][1][93] = 38, + [2][1][2][1][RTW89_KCC][0][93] = 127, + [2][1][2][1][RTW89_ACMA][1][93] = 127, + [2][1][2][1][RTW89_ACMA][0][93] = 127, + [2][1][2][1][RTW89_CHILE][1][93] = 22, + [2][1][2][1][RTW89_QATAR][1][93] = 127, + [2][1][2][1][RTW89_QATAR][0][93] = 127, + [2][1][2][1][RTW89_UK][1][93] = 127, + [2][1][2][1][RTW89_UK][0][93] = 127, + [2][1][2][1][RTW89_THAILAND][1][93] = 127, + [2][1][2][1][RTW89_THAILAND][0][93] = 127, + [2][1][2][1][RTW89_FCC][1][101] = 22, + [2][1][2][1][RTW89_ETSI][1][101] = 127, + [2][1][2][1][RTW89_ETSI][0][101] = 127, + [2][1][2][1][RTW89_MKK][1][101] = 127, + [2][1][2][1][RTW89_MKK][0][101] = 127, + [2][1][2][1][RTW89_IC][1][101] = 22, + [2][1][2][1][RTW89_KCC][1][101] = 38, + [2][1][2][1][RTW89_KCC][0][101] = 127, + [2][1][2][1][RTW89_ACMA][1][101] = 127, + [2][1][2][1][RTW89_ACMA][0][101] = 127, + [2][1][2][1][RTW89_CHILE][1][101] = 22, + [2][1][2][1][RTW89_QATAR][1][101] = 127, + [2][1][2][1][RTW89_QATAR][0][101] = 127, + [2][1][2][1][RTW89_UK][1][101] = 127, + [2][1][2][1][RTW89_UK][0][101] = 127, + [2][1][2][1][RTW89_THAILAND][1][101] = 127, + [2][1][2][1][RTW89_THAILAND][0][101] = 127, + [2][1][2][1][RTW89_FCC][1][108] = 127, + [2][1][2][1][RTW89_ETSI][1][108] = 127, + [2][1][2][1][RTW89_ETSI][0][108] = 127, + [2][1][2][1][RTW89_MKK][1][108] = 127, + [2][1][2][1][RTW89_MKK][0][108] = 127, + [2][1][2][1][RTW89_IC][1][108] = 127, + [2][1][2][1][RTW89_KCC][1][108] = 127, + [2][1][2][1][RTW89_KCC][0][108] = 127, + [2][1][2][1][RTW89_ACMA][1][108] = 127, + [2][1][2][1][RTW89_ACMA][0][108] = 127, + [2][1][2][1][RTW89_CHILE][1][108] = 127, + [2][1][2][1][RTW89_QATAR][1][108] = 127, + [2][1][2][1][RTW89_QATAR][0][108] = 127, + [2][1][2][1][RTW89_UK][1][108] = 127, + [2][1][2][1][RTW89_UK][0][108] = 127, + [2][1][2][1][RTW89_THAILAND][1][108] = 127, + [2][1][2][1][RTW89_THAILAND][0][108] = 127, + [2][1][2][1][RTW89_FCC][1][116] = 127, + [2][1][2][1][RTW89_ETSI][1][116] = 127, + [2][1][2][1][RTW89_ETSI][0][116] = 127, + [2][1][2][1][RTW89_MKK][1][116] = 127, + [2][1][2][1][RTW89_MKK][0][116] = 127, + [2][1][2][1][RTW89_IC][1][116] = 127, + [2][1][2][1][RTW89_KCC][1][116] = 127, + [2][1][2][1][RTW89_KCC][0][116] = 127, + [2][1][2][1][RTW89_ACMA][1][116] = 127, + [2][1][2][1][RTW89_ACMA][0][116] = 127, + [2][1][2][1][RTW89_CHILE][1][116] = 127, + [2][1][2][1][RTW89_QATAR][1][116] = 127, + [2][1][2][1][RTW89_QATAR][0][116] = 127, + [2][1][2][1][RTW89_UK][1][116] = 127, + [2][1][2][1][RTW89_UK][0][116] = 127, + [2][1][2][1][RTW89_THAILAND][1][116] = 127, + [2][1][2][1][RTW89_THAILAND][0][116] = 127, + [3][0][2][0][RTW89_FCC][1][7] = 52, + [3][0][2][0][RTW89_ETSI][1][7] = 50, + [3][0][2][0][RTW89_ETSI][0][7] = 30, + [3][0][2][0][RTW89_MKK][1][7] = 50, + [3][0][2][0][RTW89_MKK][0][7] = 22, + [3][0][2][0][RTW89_IC][1][7] = 52, + [3][0][2][0][RTW89_KCC][1][7] = 42, + [3][0][2][0][RTW89_KCC][0][7] = 24, + [3][0][2][0][RTW89_ACMA][1][7] = 50, + [3][0][2][0][RTW89_ACMA][0][7] = 30, + [3][0][2][0][RTW89_CHILE][1][7] = 52, + [3][0][2][0][RTW89_QATAR][1][7] = 50, + [3][0][2][0][RTW89_QATAR][0][7] = 30, + [3][0][2][0][RTW89_UK][1][7] = 50, + [3][0][2][0][RTW89_UK][0][7] = 30, + [3][0][2][0][RTW89_THAILAND][1][7] = 50, + [3][0][2][0][RTW89_THAILAND][0][7] = 30, + [3][0][2][0][RTW89_FCC][1][22] = 52, + [3][0][2][0][RTW89_ETSI][1][22] = 50, + [3][0][2][0][RTW89_ETSI][0][22] = 30, + [3][0][2][0][RTW89_MKK][1][22] = 50, + [3][0][2][0][RTW89_MKK][0][22] = 20, + [3][0][2][0][RTW89_IC][1][22] = 52, + [3][0][2][0][RTW89_KCC][1][22] = 42, + [3][0][2][0][RTW89_KCC][0][22] = 24, + [3][0][2][0][RTW89_ACMA][1][22] = 50, + [3][0][2][0][RTW89_ACMA][0][22] = 30, + [3][0][2][0][RTW89_CHILE][1][22] = 52, + [3][0][2][0][RTW89_QATAR][1][22] = 50, + [3][0][2][0][RTW89_QATAR][0][22] = 30, + [3][0][2][0][RTW89_UK][1][22] = 50, + [3][0][2][0][RTW89_UK][0][22] = 30, + [3][0][2][0][RTW89_THAILAND][1][22] = 50, + [3][0][2][0][RTW89_THAILAND][0][22] = 30, + [3][0][2][0][RTW89_FCC][1][37] = 52, + [3][0][2][0][RTW89_ETSI][1][37] = 50, + [3][0][2][0][RTW89_ETSI][0][37] = 30, + [3][0][2][0][RTW89_MKK][1][37] = 50, + [3][0][2][0][RTW89_MKK][0][37] = 20, + [3][0][2][0][RTW89_IC][1][37] = 52, + [3][0][2][0][RTW89_KCC][1][37] = 42, + [3][0][2][0][RTW89_KCC][0][37] = 24, + [3][0][2][0][RTW89_ACMA][1][37] = 50, + [3][0][2][0][RTW89_ACMA][0][37] = 30, + [3][0][2][0][RTW89_CHILE][1][37] = 52, + [3][0][2][0][RTW89_QATAR][1][37] = 50, + [3][0][2][0][RTW89_QATAR][0][37] = 30, + [3][0][2][0][RTW89_UK][1][37] = 50, + [3][0][2][0][RTW89_UK][0][37] = 30, + [3][0][2][0][RTW89_THAILAND][1][37] = 50, + [3][0][2][0][RTW89_THAILAND][0][37] = 30, + [3][0][2][0][RTW89_FCC][1][52] = 54, + [3][0][2][0][RTW89_ETSI][1][52] = 127, + [3][0][2][0][RTW89_ETSI][0][52] = 127, + [3][0][2][0][RTW89_MKK][1][52] = 127, + [3][0][2][0][RTW89_MKK][0][52] = 127, + [3][0][2][0][RTW89_IC][1][52] = 54, + [3][0][2][0][RTW89_KCC][1][52] = 56, + [3][0][2][0][RTW89_KCC][0][52] = 127, + [3][0][2][0][RTW89_ACMA][1][52] = 127, + [3][0][2][0][RTW89_ACMA][0][52] = 127, + [3][0][2][0][RTW89_CHILE][1][52] = 54, + [3][0][2][0][RTW89_QATAR][1][52] = 127, + [3][0][2][0][RTW89_QATAR][0][52] = 127, + [3][0][2][0][RTW89_UK][1][52] = 127, + [3][0][2][0][RTW89_UK][0][52] = 127, + [3][0][2][0][RTW89_THAILAND][1][52] = 127, + [3][0][2][0][RTW89_THAILAND][0][52] = 127, + [3][0][2][0][RTW89_FCC][1][67] = 54, + [3][0][2][0][RTW89_ETSI][1][67] = 127, + [3][0][2][0][RTW89_ETSI][0][67] = 127, + [3][0][2][0][RTW89_MKK][1][67] = 127, + [3][0][2][0][RTW89_MKK][0][67] = 127, + [3][0][2][0][RTW89_IC][1][67] = 54, + [3][0][2][0][RTW89_KCC][1][67] = 54, + [3][0][2][0][RTW89_KCC][0][67] = 127, + [3][0][2][0][RTW89_ACMA][1][67] = 127, + [3][0][2][0][RTW89_ACMA][0][67] = 127, + [3][0][2][0][RTW89_CHILE][1][67] = 54, + [3][0][2][0][RTW89_QATAR][1][67] = 127, + [3][0][2][0][RTW89_QATAR][0][67] = 127, + [3][0][2][0][RTW89_UK][1][67] = 127, + [3][0][2][0][RTW89_UK][0][67] = 127, + [3][0][2][0][RTW89_THAILAND][1][67] = 127, + [3][0][2][0][RTW89_THAILAND][0][67] = 127, + [3][0][2][0][RTW89_FCC][1][82] = 46, + [3][0][2][0][RTW89_ETSI][1][82] = 127, + [3][0][2][0][RTW89_ETSI][0][82] = 127, + [3][0][2][0][RTW89_MKK][1][82] = 127, + [3][0][2][0][RTW89_MKK][0][82] = 127, + [3][0][2][0][RTW89_IC][1][82] = 46, + [3][0][2][0][RTW89_KCC][1][82] = 26, + [3][0][2][0][RTW89_KCC][0][82] = 127, + [3][0][2][0][RTW89_ACMA][1][82] = 127, + [3][0][2][0][RTW89_ACMA][0][82] = 127, + [3][0][2][0][RTW89_CHILE][1][82] = 46, + [3][0][2][0][RTW89_QATAR][1][82] = 127, + [3][0][2][0][RTW89_QATAR][0][82] = 127, + [3][0][2][0][RTW89_UK][1][82] = 127, + [3][0][2][0][RTW89_UK][0][82] = 127, + [3][0][2][0][RTW89_THAILAND][1][82] = 127, + [3][0][2][0][RTW89_THAILAND][0][82] = 127, + [3][0][2][0][RTW89_FCC][1][97] = 40, + [3][0][2][0][RTW89_ETSI][1][97] = 127, + [3][0][2][0][RTW89_ETSI][0][97] = 127, + [3][0][2][0][RTW89_MKK][1][97] = 127, + [3][0][2][0][RTW89_MKK][0][97] = 127, + [3][0][2][0][RTW89_IC][1][97] = 40, + [3][0][2][0][RTW89_KCC][1][97] = 26, + [3][0][2][0][RTW89_KCC][0][97] = 127, + [3][0][2][0][RTW89_ACMA][1][97] = 127, + [3][0][2][0][RTW89_ACMA][0][97] = 127, + [3][0][2][0][RTW89_CHILE][1][97] = 40, + [3][0][2][0][RTW89_QATAR][1][97] = 127, + [3][0][2][0][RTW89_QATAR][0][97] = 127, + [3][0][2][0][RTW89_UK][1][97] = 127, + [3][0][2][0][RTW89_UK][0][97] = 127, + [3][0][2][0][RTW89_THAILAND][1][97] = 127, + [3][0][2][0][RTW89_THAILAND][0][97] = 127, + [3][0][2][0][RTW89_FCC][1][112] = 127, + [3][0][2][0][RTW89_ETSI][1][112] = 127, + [3][0][2][0][RTW89_ETSI][0][112] = 127, + [3][0][2][0][RTW89_MKK][1][112] = 127, + [3][0][2][0][RTW89_MKK][0][112] = 127, + [3][0][2][0][RTW89_IC][1][112] = 127, + [3][0][2][0][RTW89_KCC][1][112] = 127, + [3][0][2][0][RTW89_KCC][0][112] = 127, + [3][0][2][0][RTW89_ACMA][1][112] = 127, + [3][0][2][0][RTW89_ACMA][0][112] = 127, + [3][0][2][0][RTW89_CHILE][1][112] = 127, + [3][0][2][0][RTW89_QATAR][1][112] = 127, + [3][0][2][0][RTW89_QATAR][0][112] = 127, + [3][0][2][0][RTW89_UK][1][112] = 127, + [3][0][2][0][RTW89_UK][0][112] = 127, + [3][0][2][0][RTW89_THAILAND][1][112] = 127, + [3][0][2][0][RTW89_THAILAND][0][112] = 127, + [3][1][2][0][RTW89_FCC][1][7] = 32, + [3][1][2][0][RTW89_ETSI][1][7] = 50, + [3][1][2][0][RTW89_ETSI][0][7] = 18, + [3][1][2][0][RTW89_MKK][1][7] = 38, + [3][1][2][0][RTW89_MKK][0][7] = 10, + [3][1][2][0][RTW89_IC][1][7] = 32, + [3][1][2][0][RTW89_KCC][1][7] = 40, + [3][1][2][0][RTW89_KCC][0][7] = 12, + [3][1][2][0][RTW89_ACMA][1][7] = 50, + [3][1][2][0][RTW89_ACMA][0][7] = 18, + [3][1][2][0][RTW89_CHILE][1][7] = 32, + [3][1][2][0][RTW89_QATAR][1][7] = 50, + [3][1][2][0][RTW89_QATAR][0][7] = 18, + [3][1][2][0][RTW89_UK][1][7] = 50, + [3][1][2][0][RTW89_UK][0][7] = 18, + [3][1][2][0][RTW89_THAILAND][1][7] = 46, + [3][1][2][0][RTW89_THAILAND][0][7] = 18, + [3][1][2][0][RTW89_FCC][1][22] = 30, + [3][1][2][0][RTW89_ETSI][1][22] = 46, + [3][1][2][0][RTW89_ETSI][0][22] = 16, + [3][1][2][0][RTW89_MKK][1][22] = 48, + [3][1][2][0][RTW89_MKK][0][22] = 8, + [3][1][2][0][RTW89_IC][1][22] = 30, + [3][1][2][0][RTW89_KCC][1][22] = 40, + [3][1][2][0][RTW89_KCC][0][22] = 12, + [3][1][2][0][RTW89_ACMA][1][22] = 46, + [3][1][2][0][RTW89_ACMA][0][22] = 16, + [3][1][2][0][RTW89_CHILE][1][22] = 30, + [3][1][2][0][RTW89_QATAR][1][22] = 46, + [3][1][2][0][RTW89_QATAR][0][22] = 16, + [3][1][2][0][RTW89_UK][1][22] = 46, + [3][1][2][0][RTW89_UK][0][22] = 16, + [3][1][2][0][RTW89_THAILAND][1][22] = 46, + [3][1][2][0][RTW89_THAILAND][0][22] = 18, + [3][1][2][0][RTW89_FCC][1][37] = 30, + [3][1][2][0][RTW89_ETSI][1][37] = 46, + [3][1][2][0][RTW89_ETSI][0][37] = 16, + [3][1][2][0][RTW89_MKK][1][37] = 48, + [3][1][2][0][RTW89_MKK][0][37] = 8, + [3][1][2][0][RTW89_IC][1][37] = 30, + [3][1][2][0][RTW89_KCC][1][37] = 40, + [3][1][2][0][RTW89_KCC][0][37] = 12, + [3][1][2][0][RTW89_ACMA][1][37] = 46, + [3][1][2][0][RTW89_ACMA][0][37] = 16, + [3][1][2][0][RTW89_CHILE][1][37] = 30, + [3][1][2][0][RTW89_QATAR][1][37] = 46, + [3][1][2][0][RTW89_QATAR][0][37] = 16, + [3][1][2][0][RTW89_UK][1][37] = 46, + [3][1][2][0][RTW89_UK][0][37] = 16, + [3][1][2][0][RTW89_THAILAND][1][37] = 46, + [3][1][2][0][RTW89_THAILAND][0][37] = 18, + [3][1][2][0][RTW89_FCC][1][52] = 30, + [3][1][2][0][RTW89_ETSI][1][52] = 127, + [3][1][2][0][RTW89_ETSI][0][52] = 127, + [3][1][2][0][RTW89_MKK][1][52] = 127, + [3][1][2][0][RTW89_MKK][0][52] = 127, + [3][1][2][0][RTW89_IC][1][52] = 30, + [3][1][2][0][RTW89_KCC][1][52] = 48, + [3][1][2][0][RTW89_KCC][0][52] = 127, + [3][1][2][0][RTW89_ACMA][1][52] = 127, + [3][1][2][0][RTW89_ACMA][0][52] = 127, + [3][1][2][0][RTW89_CHILE][1][52] = 30, + [3][1][2][0][RTW89_QATAR][1][52] = 127, + [3][1][2][0][RTW89_QATAR][0][52] = 127, + [3][1][2][0][RTW89_UK][1][52] = 127, + [3][1][2][0][RTW89_UK][0][52] = 127, + [3][1][2][0][RTW89_THAILAND][1][52] = 127, + [3][1][2][0][RTW89_THAILAND][0][52] = 127, + [3][1][2][0][RTW89_FCC][1][67] = 32, + [3][1][2][0][RTW89_ETSI][1][67] = 127, + [3][1][2][0][RTW89_ETSI][0][67] = 127, + [3][1][2][0][RTW89_MKK][1][67] = 127, + [3][1][2][0][RTW89_MKK][0][67] = 127, + [3][1][2][0][RTW89_IC][1][67] = 32, + [3][1][2][0][RTW89_KCC][1][67] = 48, + [3][1][2][0][RTW89_KCC][0][67] = 127, + [3][1][2][0][RTW89_ACMA][1][67] = 127, + [3][1][2][0][RTW89_ACMA][0][67] = 127, + [3][1][2][0][RTW89_CHILE][1][67] = 32, + [3][1][2][0][RTW89_QATAR][1][67] = 127, + [3][1][2][0][RTW89_QATAR][0][67] = 127, + [3][1][2][0][RTW89_UK][1][67] = 127, + [3][1][2][0][RTW89_UK][0][67] = 127, + [3][1][2][0][RTW89_THAILAND][1][67] = 127, + [3][1][2][0][RTW89_THAILAND][0][67] = 127, + [3][1][2][0][RTW89_FCC][1][82] = 32, + [3][1][2][0][RTW89_ETSI][1][82] = 127, + [3][1][2][0][RTW89_ETSI][0][82] = 127, + [3][1][2][0][RTW89_MKK][1][82] = 127, + [3][1][2][0][RTW89_MKK][0][82] = 127, + [3][1][2][0][RTW89_IC][1][82] = 32, + [3][1][2][0][RTW89_KCC][1][82] = 24, + [3][1][2][0][RTW89_KCC][0][82] = 127, + [3][1][2][0][RTW89_ACMA][1][82] = 127, + [3][1][2][0][RTW89_ACMA][0][82] = 127, + [3][1][2][0][RTW89_CHILE][1][82] = 32, + [3][1][2][0][RTW89_QATAR][1][82] = 127, + [3][1][2][0][RTW89_QATAR][0][82] = 127, + [3][1][2][0][RTW89_UK][1][82] = 127, + [3][1][2][0][RTW89_UK][0][82] = 127, + [3][1][2][0][RTW89_THAILAND][1][82] = 127, + [3][1][2][0][RTW89_THAILAND][0][82] = 127, + [3][1][2][0][RTW89_FCC][1][97] = 32, + [3][1][2][0][RTW89_ETSI][1][97] = 127, + [3][1][2][0][RTW89_ETSI][0][97] = 127, + [3][1][2][0][RTW89_MKK][1][97] = 127, + [3][1][2][0][RTW89_MKK][0][97] = 127, + [3][1][2][0][RTW89_IC][1][97] = 32, + [3][1][2][0][RTW89_KCC][1][97] = 24, + [3][1][2][0][RTW89_KCC][0][97] = 127, + [3][1][2][0][RTW89_ACMA][1][97] = 127, + [3][1][2][0][RTW89_ACMA][0][97] = 127, + [3][1][2][0][RTW89_CHILE][1][97] = 32, + [3][1][2][0][RTW89_QATAR][1][97] = 127, + [3][1][2][0][RTW89_QATAR][0][97] = 127, + [3][1][2][0][RTW89_UK][1][97] = 127, + [3][1][2][0][RTW89_UK][0][97] = 127, + [3][1][2][0][RTW89_THAILAND][1][97] = 127, + [3][1][2][0][RTW89_THAILAND][0][97] = 127, + [3][1][2][0][RTW89_FCC][1][112] = 127, + [3][1][2][0][RTW89_ETSI][1][112] = 127, + [3][1][2][0][RTW89_ETSI][0][112] = 127, + [3][1][2][0][RTW89_MKK][1][112] = 127, + [3][1][2][0][RTW89_MKK][0][112] = 127, + [3][1][2][0][RTW89_IC][1][112] = 127, + [3][1][2][0][RTW89_KCC][1][112] = 127, + [3][1][2][0][RTW89_KCC][0][112] = 127, + [3][1][2][0][RTW89_ACMA][1][112] = 127, + [3][1][2][0][RTW89_ACMA][0][112] = 127, + [3][1][2][0][RTW89_CHILE][1][112] = 127, + [3][1][2][0][RTW89_QATAR][1][112] = 127, + [3][1][2][0][RTW89_QATAR][0][112] = 127, + [3][1][2][0][RTW89_UK][1][112] = 127, + [3][1][2][0][RTW89_UK][0][112] = 127, + [3][1][2][0][RTW89_THAILAND][1][112] = 127, + [3][1][2][0][RTW89_THAILAND][0][112] = 127, + [3][1][2][1][RTW89_FCC][1][7] = 32, + [3][1][2][1][RTW89_ETSI][1][7] = 42, + [3][1][2][1][RTW89_ETSI][0][7] = 6, + [3][1][2][1][RTW89_MKK][1][7] = 38, + [3][1][2][1][RTW89_MKK][0][7] = 10, + [3][1][2][1][RTW89_IC][1][7] = 32, + [3][1][2][1][RTW89_KCC][1][7] = 40, + [3][1][2][1][RTW89_KCC][0][7] = 12, + [3][1][2][1][RTW89_ACMA][1][7] = 42, + [3][1][2][1][RTW89_ACMA][0][7] = 6, + [3][1][2][1][RTW89_CHILE][1][7] = 32, + [3][1][2][1][RTW89_QATAR][1][7] = 42, + [3][1][2][1][RTW89_QATAR][0][7] = 6, + [3][1][2][1][RTW89_UK][1][7] = 42, + [3][1][2][1][RTW89_UK][0][7] = 6, + [3][1][2][1][RTW89_THAILAND][1][7] = 46, + [3][1][2][1][RTW89_THAILAND][0][7] = 6, + [3][1][2][1][RTW89_FCC][1][22] = 30, + [3][1][2][1][RTW89_ETSI][1][22] = 42, + [3][1][2][1][RTW89_ETSI][0][22] = 6, + [3][1][2][1][RTW89_MKK][1][22] = 48, + [3][1][2][1][RTW89_MKK][0][22] = 8, + [3][1][2][1][RTW89_IC][1][22] = 30, + [3][1][2][1][RTW89_KCC][1][22] = 40, + [3][1][2][1][RTW89_KCC][0][22] = 12, + [3][1][2][1][RTW89_ACMA][1][22] = 42, + [3][1][2][1][RTW89_ACMA][0][22] = 6, + [3][1][2][1][RTW89_CHILE][1][22] = 30, + [3][1][2][1][RTW89_QATAR][1][22] = 42, + [3][1][2][1][RTW89_QATAR][0][22] = 6, + [3][1][2][1][RTW89_UK][1][22] = 42, + [3][1][2][1][RTW89_UK][0][22] = 6, + [3][1][2][1][RTW89_THAILAND][1][22] = 46, + [3][1][2][1][RTW89_THAILAND][0][22] = 6, + [3][1][2][1][RTW89_FCC][1][37] = 30, + [3][1][2][1][RTW89_ETSI][1][37] = 42, + [3][1][2][1][RTW89_ETSI][0][37] = 6, + [3][1][2][1][RTW89_MKK][1][37] = 48, + [3][1][2][1][RTW89_MKK][0][37] = 8, + [3][1][2][1][RTW89_IC][1][37] = 30, + [3][1][2][1][RTW89_KCC][1][37] = 40, + [3][1][2][1][RTW89_KCC][0][37] = 12, + [3][1][2][1][RTW89_ACMA][1][37] = 42, + [3][1][2][1][RTW89_ACMA][0][37] = 6, + [3][1][2][1][RTW89_CHILE][1][37] = 30, + [3][1][2][1][RTW89_QATAR][1][37] = 42, + [3][1][2][1][RTW89_QATAR][0][37] = 6, + [3][1][2][1][RTW89_UK][1][37] = 42, + [3][1][2][1][RTW89_UK][0][37] = 6, + [3][1][2][1][RTW89_THAILAND][1][37] = 46, + [3][1][2][1][RTW89_THAILAND][0][37] = 6, + [3][1][2][1][RTW89_FCC][1][52] = 30, + [3][1][2][1][RTW89_ETSI][1][52] = 127, + [3][1][2][1][RTW89_ETSI][0][52] = 127, + [3][1][2][1][RTW89_MKK][1][52] = 127, + [3][1][2][1][RTW89_MKK][0][52] = 127, + [3][1][2][1][RTW89_IC][1][52] = 30, + [3][1][2][1][RTW89_KCC][1][52] = 48, + [3][1][2][1][RTW89_KCC][0][52] = 127, + [3][1][2][1][RTW89_ACMA][1][52] = 127, + [3][1][2][1][RTW89_ACMA][0][52] = 127, + [3][1][2][1][RTW89_CHILE][1][52] = 30, + [3][1][2][1][RTW89_QATAR][1][52] = 127, + [3][1][2][1][RTW89_QATAR][0][52] = 127, + [3][1][2][1][RTW89_UK][1][52] = 127, + [3][1][2][1][RTW89_UK][0][52] = 127, + [3][1][2][1][RTW89_THAILAND][1][52] = 127, + [3][1][2][1][RTW89_THAILAND][0][52] = 127, + [3][1][2][1][RTW89_FCC][1][67] = 32, + [3][1][2][1][RTW89_ETSI][1][67] = 127, + [3][1][2][1][RTW89_ETSI][0][67] = 127, + [3][1][2][1][RTW89_MKK][1][67] = 127, + [3][1][2][1][RTW89_MKK][0][67] = 127, + [3][1][2][1][RTW89_IC][1][67] = 32, + [3][1][2][1][RTW89_KCC][1][67] = 48, + [3][1][2][1][RTW89_KCC][0][67] = 127, + [3][1][2][1][RTW89_ACMA][1][67] = 127, + [3][1][2][1][RTW89_ACMA][0][67] = 127, + [3][1][2][1][RTW89_CHILE][1][67] = 32, + [3][1][2][1][RTW89_QATAR][1][67] = 127, + [3][1][2][1][RTW89_QATAR][0][67] = 127, + [3][1][2][1][RTW89_UK][1][67] = 127, + [3][1][2][1][RTW89_UK][0][67] = 127, + [3][1][2][1][RTW89_THAILAND][1][67] = 127, + [3][1][2][1][RTW89_THAILAND][0][67] = 127, + [3][1][2][1][RTW89_FCC][1][82] = 32, + [3][1][2][1][RTW89_ETSI][1][82] = 127, + [3][1][2][1][RTW89_ETSI][0][82] = 127, + [3][1][2][1][RTW89_MKK][1][82] = 127, + [3][1][2][1][RTW89_MKK][0][82] = 127, + [3][1][2][1][RTW89_IC][1][82] = 32, + [3][1][2][1][RTW89_KCC][1][82] = 24, + [3][1][2][1][RTW89_KCC][0][82] = 127, + [3][1][2][1][RTW89_ACMA][1][82] = 127, + [3][1][2][1][RTW89_ACMA][0][82] = 127, + [3][1][2][1][RTW89_CHILE][1][82] = 32, + [3][1][2][1][RTW89_QATAR][1][82] = 127, + [3][1][2][1][RTW89_QATAR][0][82] = 127, + [3][1][2][1][RTW89_UK][1][82] = 127, + [3][1][2][1][RTW89_UK][0][82] = 127, + [3][1][2][1][RTW89_THAILAND][1][82] = 127, + [3][1][2][1][RTW89_THAILAND][0][82] = 127, + [3][1][2][1][RTW89_FCC][1][97] = 32, + [3][1][2][1][RTW89_ETSI][1][97] = 127, + [3][1][2][1][RTW89_ETSI][0][97] = 127, + [3][1][2][1][RTW89_MKK][1][97] = 127, + [3][1][2][1][RTW89_MKK][0][97] = 127, + [3][1][2][1][RTW89_IC][1][97] = 32, + [3][1][2][1][RTW89_KCC][1][97] = 24, + [3][1][2][1][RTW89_KCC][0][97] = 127, + [3][1][2][1][RTW89_ACMA][1][97] = 127, + [3][1][2][1][RTW89_ACMA][0][97] = 127, + [3][1][2][1][RTW89_CHILE][1][97] = 32, + [3][1][2][1][RTW89_QATAR][1][97] = 127, + [3][1][2][1][RTW89_QATAR][0][97] = 127, + [3][1][2][1][RTW89_UK][1][97] = 127, + [3][1][2][1][RTW89_UK][0][97] = 127, + [3][1][2][1][RTW89_THAILAND][1][97] = 127, + [3][1][2][1][RTW89_THAILAND][0][97] = 127, + [3][1][2][1][RTW89_FCC][1][112] = 127, + [3][1][2][1][RTW89_ETSI][1][112] = 127, + [3][1][2][1][RTW89_ETSI][0][112] = 127, + [3][1][2][1][RTW89_MKK][1][112] = 127, + [3][1][2][1][RTW89_MKK][0][112] = 127, + [3][1][2][1][RTW89_IC][1][112] = 127, + [3][1][2][1][RTW89_KCC][1][112] = 127, + [3][1][2][1][RTW89_KCC][0][112] = 127, + [3][1][2][1][RTW89_ACMA][1][112] = 127, + [3][1][2][1][RTW89_ACMA][0][112] = 127, + [3][1][2][1][RTW89_CHILE][1][112] = 127, + [3][1][2][1][RTW89_QATAR][1][112] = 127, + [3][1][2][1][RTW89_QATAR][0][112] = 127, + [3][1][2][1][RTW89_UK][1][112] = 127, + [3][1][2][1][RTW89_UK][0][112] = 127, + [3][1][2][1][RTW89_THAILAND][1][112] = 127, + [3][1][2][1][RTW89_THAILAND][0][112] = 127, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 32, + [0][0][RTW89_WW][1] = 32, + [0][0][RTW89_WW][2] = 32, + [0][0][RTW89_WW][3] = 32, + [0][0][RTW89_WW][4] = 32, + [0][0][RTW89_WW][5] = 32, + [0][0][RTW89_WW][6] = 32, + [0][0][RTW89_WW][7] = 32, + [0][0][RTW89_WW][8] = 32, + [0][0][RTW89_WW][9] = 32, + [0][0][RTW89_WW][10] = 32, + [0][0][RTW89_WW][11] = 26, + [0][0][RTW89_WW][12] = -20, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 20, + [0][1][RTW89_WW][1] = 22, + [0][1][RTW89_WW][2] = 22, + [0][1][RTW89_WW][3] = 22, + [0][1][RTW89_WW][4] = 22, + [0][1][RTW89_WW][5] = 22, + [0][1][RTW89_WW][6] = 22, + [0][1][RTW89_WW][7] = 22, + [0][1][RTW89_WW][8] = 22, + [0][1][RTW89_WW][9] = 22, + [0][1][RTW89_WW][10] = 22, + [0][1][RTW89_WW][11] = 22, + [0][1][RTW89_WW][12] = -30, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 44, + [1][0][RTW89_WW][2] = 44, + [1][0][RTW89_WW][3] = 44, + [1][0][RTW89_WW][4] = 44, + [1][0][RTW89_WW][5] = 44, + [1][0][RTW89_WW][6] = 40, + [1][0][RTW89_WW][7] = 40, + [1][0][RTW89_WW][8] = 40, + [1][0][RTW89_WW][9] = 40, + [1][0][RTW89_WW][10] = 44, + [1][0][RTW89_WW][11] = 36, + [1][0][RTW89_WW][12] = 4, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 32, + [1][1][RTW89_WW][1] = 32, + [1][1][RTW89_WW][2] = 32, + [1][1][RTW89_WW][3] = 32, + [1][1][RTW89_WW][4] = 32, + [1][1][RTW89_WW][5] = 32, + [1][1][RTW89_WW][6] = 30, + [1][1][RTW89_WW][7] = 30, + [1][1][RTW89_WW][8] = 30, + [1][1][RTW89_WW][9] = 30, + [1][1][RTW89_WW][10] = 32, + [1][1][RTW89_WW][11] = 30, + [1][1][RTW89_WW][12] = -6, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 56, + [2][0][RTW89_WW][1] = 54, + [2][0][RTW89_WW][2] = 54, + [2][0][RTW89_WW][3] = 54, + [2][0][RTW89_WW][4] = 54, + [2][0][RTW89_WW][5] = 56, + [2][0][RTW89_WW][6] = 48, + [2][0][RTW89_WW][7] = 48, + [2][0][RTW89_WW][8] = 48, + [2][0][RTW89_WW][9] = 48, + [2][0][RTW89_WW][10] = 56, + [2][0][RTW89_WW][11] = 48, + [2][0][RTW89_WW][12] = 16, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 44, + [2][1][RTW89_WW][1] = 44, + [2][1][RTW89_WW][2] = 44, + [2][1][RTW89_WW][3] = 44, + [2][1][RTW89_WW][4] = 44, + [2][1][RTW89_WW][5] = 44, + [2][1][RTW89_WW][6] = 42, + [2][1][RTW89_WW][7] = 42, + [2][1][RTW89_WW][8] = 42, + [2][1][RTW89_WW][9] = 42, + [2][1][RTW89_WW][10] = 44, + [2][1][RTW89_WW][11] = 44, + [2][1][RTW89_WW][12] = 6, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 60, + [0][0][RTW89_ETSI][0] = 34, + [0][0][RTW89_MKK][0] = 36, + [0][0][RTW89_IC][0] = 60, + [0][0][RTW89_KCC][0] = 42, + [0][0][RTW89_ACMA][0] = 34, + [0][0][RTW89_CN][0] = 32, + [0][0][RTW89_UK][0] = 34, + [0][0][RTW89_MEXICO][0] = 60, + [0][0][RTW89_UKRAINE][0] = 34, + [0][0][RTW89_CHILE][0] = 60, + [0][0][RTW89_QATAR][0] = 34, + [0][0][RTW89_THAILAND][0] = 34, + [0][0][RTW89_FCC][1] = 60, + [0][0][RTW89_ETSI][1] = 38, + [0][0][RTW89_MKK][1] = 40, + [0][0][RTW89_IC][1] = 60, + [0][0][RTW89_KCC][1] = 42, + [0][0][RTW89_ACMA][1] = 38, + [0][0][RTW89_CN][1] = 32, + [0][0][RTW89_UK][1] = 38, + [0][0][RTW89_MEXICO][1] = 60, + [0][0][RTW89_UKRAINE][1] = 38, + [0][0][RTW89_CHILE][1] = 50, + [0][0][RTW89_QATAR][1] = 38, + [0][0][RTW89_THAILAND][1] = 38, + [0][0][RTW89_FCC][2] = 64, + [0][0][RTW89_ETSI][2] = 38, + [0][0][RTW89_MKK][2] = 40, + [0][0][RTW89_IC][2] = 64, + [0][0][RTW89_KCC][2] = 42, + [0][0][RTW89_ACMA][2] = 38, + [0][0][RTW89_CN][2] = 32, + [0][0][RTW89_UK][2] = 38, + [0][0][RTW89_MEXICO][2] = 64, + [0][0][RTW89_UKRAINE][2] = 38, + [0][0][RTW89_CHILE][2] = 50, + [0][0][RTW89_QATAR][2] = 38, + [0][0][RTW89_THAILAND][2] = 38, + [0][0][RTW89_FCC][3] = 68, + [0][0][RTW89_ETSI][3] = 38, + [0][0][RTW89_MKK][3] = 40, + [0][0][RTW89_IC][3] = 68, + [0][0][RTW89_KCC][3] = 42, + [0][0][RTW89_ACMA][3] = 38, + [0][0][RTW89_CN][3] = 32, + [0][0][RTW89_UK][3] = 38, + [0][0][RTW89_MEXICO][3] = 68, + [0][0][RTW89_UKRAINE][3] = 38, + [0][0][RTW89_CHILE][3] = 50, + [0][0][RTW89_QATAR][3] = 38, + [0][0][RTW89_THAILAND][3] = 38, + [0][0][RTW89_FCC][4] = 68, + [0][0][RTW89_ETSI][4] = 38, + [0][0][RTW89_MKK][4] = 40, + [0][0][RTW89_IC][4] = 68, + [0][0][RTW89_KCC][4] = 44, + [0][0][RTW89_ACMA][4] = 38, + [0][0][RTW89_CN][4] = 32, + [0][0][RTW89_UK][4] = 38, + [0][0][RTW89_MEXICO][4] = 68, + [0][0][RTW89_UKRAINE][4] = 38, + [0][0][RTW89_CHILE][4] = 50, + [0][0][RTW89_QATAR][4] = 38, + [0][0][RTW89_THAILAND][4] = 38, + [0][0][RTW89_FCC][5] = 78, + [0][0][RTW89_ETSI][5] = 38, + [0][0][RTW89_MKK][5] = 40, + [0][0][RTW89_IC][5] = 78, + [0][0][RTW89_KCC][5] = 44, + [0][0][RTW89_ACMA][5] = 38, + [0][0][RTW89_CN][5] = 32, + [0][0][RTW89_UK][5] = 38, + [0][0][RTW89_MEXICO][5] = 78, + [0][0][RTW89_UKRAINE][5] = 38, + [0][0][RTW89_CHILE][5] = 78, + [0][0][RTW89_QATAR][5] = 38, + [0][0][RTW89_THAILAND][5] = 38, + [0][0][RTW89_FCC][6] = 54, + [0][0][RTW89_ETSI][6] = 38, + [0][0][RTW89_MKK][6] = 40, + [0][0][RTW89_IC][6] = 54, + [0][0][RTW89_KCC][6] = 44, + [0][0][RTW89_ACMA][6] = 38, + [0][0][RTW89_CN][6] = 32, + [0][0][RTW89_UK][6] = 38, + [0][0][RTW89_MEXICO][6] = 54, + [0][0][RTW89_UKRAINE][6] = 38, + [0][0][RTW89_CHILE][6] = 36, + [0][0][RTW89_QATAR][6] = 38, + [0][0][RTW89_THAILAND][6] = 38, + [0][0][RTW89_FCC][7] = 54, + [0][0][RTW89_ETSI][7] = 38, + [0][0][RTW89_MKK][7] = 40, + [0][0][RTW89_IC][7] = 54, + [0][0][RTW89_KCC][7] = 44, + [0][0][RTW89_ACMA][7] = 38, + [0][0][RTW89_CN][7] = 32, + [0][0][RTW89_UK][7] = 38, + [0][0][RTW89_MEXICO][7] = 54, + [0][0][RTW89_UKRAINE][7] = 38, + [0][0][RTW89_CHILE][7] = 36, + [0][0][RTW89_QATAR][7] = 38, + [0][0][RTW89_THAILAND][7] = 38, + [0][0][RTW89_FCC][8] = 50, + [0][0][RTW89_ETSI][8] = 38, + [0][0][RTW89_MKK][8] = 40, + [0][0][RTW89_IC][8] = 50, + [0][0][RTW89_KCC][8] = 44, + [0][0][RTW89_ACMA][8] = 38, + [0][0][RTW89_CN][8] = 32, + [0][0][RTW89_UK][8] = 38, + [0][0][RTW89_MEXICO][8] = 50, + [0][0][RTW89_UKRAINE][8] = 38, + [0][0][RTW89_CHILE][8] = 36, + [0][0][RTW89_QATAR][8] = 38, + [0][0][RTW89_THAILAND][8] = 38, + [0][0][RTW89_FCC][9] = 46, + [0][0][RTW89_ETSI][9] = 38, + [0][0][RTW89_MKK][9] = 40, + [0][0][RTW89_IC][9] = 46, + [0][0][RTW89_KCC][9] = 42, + [0][0][RTW89_ACMA][9] = 38, + [0][0][RTW89_CN][9] = 32, + [0][0][RTW89_UK][9] = 38, + [0][0][RTW89_MEXICO][9] = 46, + [0][0][RTW89_UKRAINE][9] = 38, + [0][0][RTW89_CHILE][9] = 36, + [0][0][RTW89_QATAR][9] = 38, + [0][0][RTW89_THAILAND][9] = 38, + [0][0][RTW89_FCC][10] = 46, + [0][0][RTW89_ETSI][10] = 38, + [0][0][RTW89_MKK][10] = 40, + [0][0][RTW89_IC][10] = 46, + [0][0][RTW89_KCC][10] = 42, + [0][0][RTW89_ACMA][10] = 38, + [0][0][RTW89_CN][10] = 32, + [0][0][RTW89_UK][10] = 38, + [0][0][RTW89_MEXICO][10] = 46, + [0][0][RTW89_UKRAINE][10] = 38, + [0][0][RTW89_CHILE][10] = 46, + [0][0][RTW89_QATAR][10] = 38, + [0][0][RTW89_THAILAND][10] = 38, + [0][0][RTW89_FCC][11] = 26, + [0][0][RTW89_ETSI][11] = 38, + [0][0][RTW89_MKK][11] = 40, + [0][0][RTW89_IC][11] = 26, + [0][0][RTW89_KCC][11] = 42, + [0][0][RTW89_ACMA][11] = 38, + [0][0][RTW89_CN][11] = 32, + [0][0][RTW89_UK][11] = 38, + [0][0][RTW89_MEXICO][11] = 26, + [0][0][RTW89_UKRAINE][11] = 38, + [0][0][RTW89_CHILE][11] = 26, + [0][0][RTW89_QATAR][11] = 38, + [0][0][RTW89_THAILAND][11] = 38, + [0][0][RTW89_FCC][12] = -20, + [0][0][RTW89_ETSI][12] = 34, + [0][0][RTW89_MKK][12] = 36, + [0][0][RTW89_IC][12] = -20, + [0][0][RTW89_KCC][12] = 42, + [0][0][RTW89_ACMA][12] = 34, + [0][0][RTW89_CN][12] = 32, + [0][0][RTW89_UK][12] = 34, + [0][0][RTW89_MEXICO][12] = -20, + [0][0][RTW89_UKRAINE][12] = 34, + [0][0][RTW89_CHILE][12] = -20, + [0][0][RTW89_QATAR][12] = 34, + [0][0][RTW89_THAILAND][12] = 34, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_KCC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][0][RTW89_CN][13] = 127, + [0][0][RTW89_UK][13] = 127, + [0][0][RTW89_MEXICO][13] = 127, + [0][0][RTW89_UKRAINE][13] = 127, + [0][0][RTW89_CHILE][13] = 127, + [0][0][RTW89_QATAR][13] = 127, + [0][0][RTW89_THAILAND][13] = 127, + [0][1][RTW89_FCC][0] = 56, + [0][1][RTW89_ETSI][0] = 22, + [0][1][RTW89_MKK][0] = 24, + [0][1][RTW89_IC][0] = 56, + [0][1][RTW89_KCC][0] = 30, + [0][1][RTW89_ACMA][0] = 22, + [0][1][RTW89_CN][0] = 20, + [0][1][RTW89_UK][0] = 22, + [0][1][RTW89_MEXICO][0] = 56, + [0][1][RTW89_UKRAINE][0] = 22, + [0][1][RTW89_CHILE][0] = 56, + [0][1][RTW89_QATAR][0] = 22, + [0][1][RTW89_THAILAND][0] = 22, + [0][1][RTW89_FCC][1] = 56, + [0][1][RTW89_ETSI][1] = 24, + [0][1][RTW89_MKK][1] = 30, + [0][1][RTW89_IC][1] = 56, + [0][1][RTW89_KCC][1] = 30, + [0][1][RTW89_ACMA][1] = 24, + [0][1][RTW89_CN][1] = 22, + [0][1][RTW89_UK][1] = 24, + [0][1][RTW89_MEXICO][1] = 56, + [0][1][RTW89_UKRAINE][1] = 24, + [0][1][RTW89_CHILE][1] = 40, + [0][1][RTW89_QATAR][1] = 24, + [0][1][RTW89_THAILAND][1] = 24, + [0][1][RTW89_FCC][2] = 60, + [0][1][RTW89_ETSI][2] = 24, + [0][1][RTW89_MKK][2] = 30, + [0][1][RTW89_IC][2] = 60, + [0][1][RTW89_KCC][2] = 30, + [0][1][RTW89_ACMA][2] = 24, + [0][1][RTW89_CN][2] = 22, + [0][1][RTW89_UK][2] = 24, + [0][1][RTW89_MEXICO][2] = 60, + [0][1][RTW89_UKRAINE][2] = 24, + [0][1][RTW89_CHILE][2] = 40, + [0][1][RTW89_QATAR][2] = 24, + [0][1][RTW89_THAILAND][2] = 24, + [0][1][RTW89_FCC][3] = 64, + [0][1][RTW89_ETSI][3] = 24, + [0][1][RTW89_MKK][3] = 30, + [0][1][RTW89_IC][3] = 64, + [0][1][RTW89_KCC][3] = 30, + [0][1][RTW89_ACMA][3] = 24, + [0][1][RTW89_CN][3] = 22, + [0][1][RTW89_UK][3] = 24, + [0][1][RTW89_MEXICO][3] = 64, + [0][1][RTW89_UKRAINE][3] = 24, + [0][1][RTW89_CHILE][3] = 40, + [0][1][RTW89_QATAR][3] = 24, + [0][1][RTW89_THAILAND][3] = 24, + [0][1][RTW89_FCC][4] = 68, + [0][1][RTW89_ETSI][4] = 24, + [0][1][RTW89_MKK][4] = 30, + [0][1][RTW89_IC][4] = 68, + [0][1][RTW89_KCC][4] = 34, + [0][1][RTW89_ACMA][4] = 24, + [0][1][RTW89_CN][4] = 22, + [0][1][RTW89_UK][4] = 24, + [0][1][RTW89_MEXICO][4] = 68, + [0][1][RTW89_UKRAINE][4] = 24, + [0][1][RTW89_CHILE][4] = 40, + [0][1][RTW89_QATAR][4] = 24, + [0][1][RTW89_THAILAND][4] = 24, + [0][1][RTW89_FCC][5] = 76, + [0][1][RTW89_ETSI][5] = 24, + [0][1][RTW89_MKK][5] = 30, + [0][1][RTW89_IC][5] = 76, + [0][1][RTW89_KCC][5] = 34, + [0][1][RTW89_ACMA][5] = 24, + [0][1][RTW89_CN][5] = 22, + [0][1][RTW89_UK][5] = 24, + [0][1][RTW89_MEXICO][5] = 76, + [0][1][RTW89_UKRAINE][5] = 24, + [0][1][RTW89_CHILE][5] = 76, + [0][1][RTW89_QATAR][5] = 24, + [0][1][RTW89_THAILAND][5] = 24, + [0][1][RTW89_FCC][6] = 54, + [0][1][RTW89_ETSI][6] = 24, + [0][1][RTW89_MKK][6] = 30, + [0][1][RTW89_IC][6] = 54, + [0][1][RTW89_KCC][6] = 34, + [0][1][RTW89_ACMA][6] = 24, + [0][1][RTW89_CN][6] = 22, + [0][1][RTW89_UK][6] = 24, + [0][1][RTW89_MEXICO][6] = 54, + [0][1][RTW89_UKRAINE][6] = 24, + [0][1][RTW89_CHILE][6] = 26, + [0][1][RTW89_QATAR][6] = 24, + [0][1][RTW89_THAILAND][6] = 24, + [0][1][RTW89_FCC][7] = 50, + [0][1][RTW89_ETSI][7] = 24, + [0][1][RTW89_MKK][7] = 30, + [0][1][RTW89_IC][7] = 50, + [0][1][RTW89_KCC][7] = 34, + [0][1][RTW89_ACMA][7] = 24, + [0][1][RTW89_CN][7] = 22, + [0][1][RTW89_UK][7] = 24, + [0][1][RTW89_MEXICO][7] = 50, + [0][1][RTW89_UKRAINE][7] = 24, + [0][1][RTW89_CHILE][7] = 26, + [0][1][RTW89_QATAR][7] = 24, + [0][1][RTW89_THAILAND][7] = 24, + [0][1][RTW89_FCC][8] = 46, + [0][1][RTW89_ETSI][8] = 24, + [0][1][RTW89_MKK][8] = 30, + [0][1][RTW89_IC][8] = 46, + [0][1][RTW89_KCC][8] = 34, + [0][1][RTW89_ACMA][8] = 24, + [0][1][RTW89_CN][8] = 22, + [0][1][RTW89_UK][8] = 24, + [0][1][RTW89_MEXICO][8] = 46, + [0][1][RTW89_UKRAINE][8] = 24, + [0][1][RTW89_CHILE][8] = 26, + [0][1][RTW89_QATAR][8] = 24, + [0][1][RTW89_THAILAND][8] = 24, + [0][1][RTW89_FCC][9] = 42, + [0][1][RTW89_ETSI][9] = 24, + [0][1][RTW89_MKK][9] = 30, + [0][1][RTW89_IC][9] = 42, + [0][1][RTW89_KCC][9] = 32, + [0][1][RTW89_ACMA][9] = 24, + [0][1][RTW89_CN][9] = 22, + [0][1][RTW89_UK][9] = 24, + [0][1][RTW89_MEXICO][9] = 42, + [0][1][RTW89_UKRAINE][9] = 24, + [0][1][RTW89_CHILE][9] = 26, + [0][1][RTW89_QATAR][9] = 24, + [0][1][RTW89_THAILAND][9] = 24, + [0][1][RTW89_FCC][10] = 42, + [0][1][RTW89_ETSI][10] = 24, + [0][1][RTW89_MKK][10] = 30, + [0][1][RTW89_IC][10] = 42, + [0][1][RTW89_KCC][10] = 32, + [0][1][RTW89_ACMA][10] = 24, + [0][1][RTW89_CN][10] = 22, + [0][1][RTW89_UK][10] = 24, + [0][1][RTW89_MEXICO][10] = 42, + [0][1][RTW89_UKRAINE][10] = 24, + [0][1][RTW89_CHILE][10] = 42, + [0][1][RTW89_QATAR][10] = 24, + [0][1][RTW89_THAILAND][10] = 24, + [0][1][RTW89_FCC][11] = 22, + [0][1][RTW89_ETSI][11] = 24, + [0][1][RTW89_MKK][11] = 30, + [0][1][RTW89_IC][11] = 22, + [0][1][RTW89_KCC][11] = 32, + [0][1][RTW89_ACMA][11] = 24, + [0][1][RTW89_CN][11] = 22, + [0][1][RTW89_UK][11] = 24, + [0][1][RTW89_MEXICO][11] = 22, + [0][1][RTW89_UKRAINE][11] = 24, + [0][1][RTW89_CHILE][11] = 22, + [0][1][RTW89_QATAR][11] = 24, + [0][1][RTW89_THAILAND][11] = 24, + [0][1][RTW89_FCC][12] = -30, + [0][1][RTW89_ETSI][12] = 20, + [0][1][RTW89_MKK][12] = 24, + [0][1][RTW89_IC][12] = -30, + [0][1][RTW89_KCC][12] = 32, + [0][1][RTW89_ACMA][12] = 20, + [0][1][RTW89_CN][12] = 20, + [0][1][RTW89_UK][12] = 20, + [0][1][RTW89_MEXICO][12] = -30, + [0][1][RTW89_UKRAINE][12] = 20, + [0][1][RTW89_CHILE][12] = -30, + [0][1][RTW89_QATAR][12] = 20, + [0][1][RTW89_THAILAND][12] = 20, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_KCC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [0][1][RTW89_CN][13] = 127, + [0][1][RTW89_UK][13] = 127, + [0][1][RTW89_MEXICO][13] = 127, + [0][1][RTW89_UKRAINE][13] = 127, + [0][1][RTW89_CHILE][13] = 127, + [0][1][RTW89_QATAR][13] = 127, + [0][1][RTW89_THAILAND][13] = 127, + [1][0][RTW89_FCC][0] = 66, + [1][0][RTW89_ETSI][0] = 46, + [1][0][RTW89_MKK][0] = 48, + [1][0][RTW89_IC][0] = 66, + [1][0][RTW89_KCC][0] = 54, + [1][0][RTW89_ACMA][0] = 46, + [1][0][RTW89_CN][0] = 42, + [1][0][RTW89_UK][0] = 46, + [1][0][RTW89_MEXICO][0] = 66, + [1][0][RTW89_UKRAINE][0] = 46, + [1][0][RTW89_CHILE][0] = 66, + [1][0][RTW89_QATAR][0] = 46, + [1][0][RTW89_THAILAND][0] = 46, + [1][0][RTW89_FCC][1] = 66, + [1][0][RTW89_ETSI][1] = 46, + [1][0][RTW89_MKK][1] = 48, + [1][0][RTW89_IC][1] = 66, + [1][0][RTW89_KCC][1] = 54, + [1][0][RTW89_ACMA][1] = 46, + [1][0][RTW89_CN][1] = 44, + [1][0][RTW89_UK][1] = 46, + [1][0][RTW89_MEXICO][1] = 66, + [1][0][RTW89_UKRAINE][1] = 46, + [1][0][RTW89_CHILE][1] = 54, + [1][0][RTW89_QATAR][1] = 46, + [1][0][RTW89_THAILAND][1] = 46, + [1][0][RTW89_FCC][2] = 70, + [1][0][RTW89_ETSI][2] = 46, + [1][0][RTW89_MKK][2] = 48, + [1][0][RTW89_IC][2] = 70, + [1][0][RTW89_KCC][2] = 54, + [1][0][RTW89_ACMA][2] = 46, + [1][0][RTW89_CN][2] = 44, + [1][0][RTW89_UK][2] = 46, + [1][0][RTW89_MEXICO][2] = 70, + [1][0][RTW89_UKRAINE][2] = 46, + [1][0][RTW89_CHILE][2] = 54, + [1][0][RTW89_QATAR][2] = 46, + [1][0][RTW89_THAILAND][2] = 46, + [1][0][RTW89_FCC][3] = 72, + [1][0][RTW89_ETSI][3] = 46, + [1][0][RTW89_MKK][3] = 48, + [1][0][RTW89_IC][3] = 72, + [1][0][RTW89_KCC][3] = 54, + [1][0][RTW89_ACMA][3] = 46, + [1][0][RTW89_CN][3] = 44, + [1][0][RTW89_UK][3] = 46, + [1][0][RTW89_MEXICO][3] = 72, + [1][0][RTW89_UKRAINE][3] = 46, + [1][0][RTW89_CHILE][3] = 54, + [1][0][RTW89_QATAR][3] = 46, + [1][0][RTW89_THAILAND][3] = 46, + [1][0][RTW89_FCC][4] = 72, + [1][0][RTW89_ETSI][4] = 46, + [1][0][RTW89_MKK][4] = 48, + [1][0][RTW89_IC][4] = 72, + [1][0][RTW89_KCC][4] = 56, + [1][0][RTW89_ACMA][4] = 46, + [1][0][RTW89_CN][4] = 44, + [1][0][RTW89_UK][4] = 46, + [1][0][RTW89_MEXICO][4] = 72, + [1][0][RTW89_UKRAINE][4] = 46, + [1][0][RTW89_CHILE][4] = 54, + [1][0][RTW89_QATAR][4] = 46, + [1][0][RTW89_THAILAND][4] = 46, + [1][0][RTW89_FCC][5] = 82, + [1][0][RTW89_ETSI][5] = 46, + [1][0][RTW89_MKK][5] = 48, + [1][0][RTW89_IC][5] = 82, + [1][0][RTW89_KCC][5] = 56, + [1][0][RTW89_ACMA][5] = 46, + [1][0][RTW89_CN][5] = 44, + [1][0][RTW89_UK][5] = 46, + [1][0][RTW89_MEXICO][5] = 82, + [1][0][RTW89_UKRAINE][5] = 46, + [1][0][RTW89_CHILE][5] = 82, + [1][0][RTW89_QATAR][5] = 46, + [1][0][RTW89_THAILAND][5] = 46, + [1][0][RTW89_FCC][6] = 58, + [1][0][RTW89_ETSI][6] = 44, + [1][0][RTW89_MKK][6] = 48, + [1][0][RTW89_IC][6] = 58, + [1][0][RTW89_KCC][6] = 56, + [1][0][RTW89_ACMA][6] = 44, + [1][0][RTW89_CN][6] = 44, + [1][0][RTW89_UK][6] = 44, + [1][0][RTW89_MEXICO][6] = 58, + [1][0][RTW89_UKRAINE][6] = 44, + [1][0][RTW89_CHILE][6] = 40, + [1][0][RTW89_QATAR][6] = 44, + [1][0][RTW89_THAILAND][6] = 44, + [1][0][RTW89_FCC][7] = 58, + [1][0][RTW89_ETSI][7] = 46, + [1][0][RTW89_MKK][7] = 48, + [1][0][RTW89_IC][7] = 58, + [1][0][RTW89_KCC][7] = 56, + [1][0][RTW89_ACMA][7] = 46, + [1][0][RTW89_CN][7] = 44, + [1][0][RTW89_UK][7] = 46, + [1][0][RTW89_MEXICO][7] = 58, + [1][0][RTW89_UKRAINE][7] = 46, + [1][0][RTW89_CHILE][7] = 40, + [1][0][RTW89_QATAR][7] = 46, + [1][0][RTW89_THAILAND][7] = 46, + [1][0][RTW89_FCC][8] = 58, + [1][0][RTW89_ETSI][8] = 46, + [1][0][RTW89_MKK][8] = 48, + [1][0][RTW89_IC][8] = 58, + [1][0][RTW89_KCC][8] = 56, + [1][0][RTW89_ACMA][8] = 46, + [1][0][RTW89_CN][8] = 44, + [1][0][RTW89_UK][8] = 46, + [1][0][RTW89_MEXICO][8] = 58, + [1][0][RTW89_UKRAINE][8] = 46, + [1][0][RTW89_CHILE][8] = 40, + [1][0][RTW89_QATAR][8] = 46, + [1][0][RTW89_THAILAND][8] = 46, + [1][0][RTW89_FCC][9] = 54, + [1][0][RTW89_ETSI][9] = 46, + [1][0][RTW89_MKK][9] = 48, + [1][0][RTW89_IC][9] = 54, + [1][0][RTW89_KCC][9] = 56, + [1][0][RTW89_ACMA][9] = 46, + [1][0][RTW89_CN][9] = 44, + [1][0][RTW89_UK][9] = 46, + [1][0][RTW89_MEXICO][9] = 54, + [1][0][RTW89_UKRAINE][9] = 46, + [1][0][RTW89_CHILE][9] = 40, + [1][0][RTW89_QATAR][9] = 46, + [1][0][RTW89_THAILAND][9] = 46, + [1][0][RTW89_FCC][10] = 54, + [1][0][RTW89_ETSI][10] = 46, + [1][0][RTW89_MKK][10] = 48, + [1][0][RTW89_IC][10] = 54, + [1][0][RTW89_KCC][10] = 56, + [1][0][RTW89_ACMA][10] = 46, + [1][0][RTW89_CN][10] = 44, + [1][0][RTW89_UK][10] = 46, + [1][0][RTW89_MEXICO][10] = 54, + [1][0][RTW89_UKRAINE][10] = 46, + [1][0][RTW89_CHILE][10] = 54, + [1][0][RTW89_QATAR][10] = 46, + [1][0][RTW89_THAILAND][10] = 46, + [1][0][RTW89_FCC][11] = 36, + [1][0][RTW89_ETSI][11] = 46, + [1][0][RTW89_MKK][11] = 48, + [1][0][RTW89_IC][11] = 36, + [1][0][RTW89_KCC][11] = 56, + [1][0][RTW89_ACMA][11] = 46, + [1][0][RTW89_CN][11] = 44, + [1][0][RTW89_UK][11] = 46, + [1][0][RTW89_MEXICO][11] = 36, + [1][0][RTW89_UKRAINE][11] = 46, + [1][0][RTW89_CHILE][11] = 36, + [1][0][RTW89_QATAR][11] = 46, + [1][0][RTW89_THAILAND][11] = 46, + [1][0][RTW89_FCC][12] = 4, + [1][0][RTW89_ETSI][12] = 46, + [1][0][RTW89_MKK][12] = 46, + [1][0][RTW89_IC][12] = 4, + [1][0][RTW89_KCC][12] = 56, + [1][0][RTW89_ACMA][12] = 46, + [1][0][RTW89_CN][12] = 42, + [1][0][RTW89_UK][12] = 46, + [1][0][RTW89_MEXICO][12] = 4, + [1][0][RTW89_UKRAINE][12] = 46, + [1][0][RTW89_CHILE][12] = 4, + [1][0][RTW89_QATAR][12] = 46, + [1][0][RTW89_THAILAND][12] = 46, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_KCC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][0][RTW89_CN][13] = 127, + [1][0][RTW89_UK][13] = 127, + [1][0][RTW89_MEXICO][13] = 127, + [1][0][RTW89_UKRAINE][13] = 127, + [1][0][RTW89_CHILE][13] = 127, + [1][0][RTW89_QATAR][13] = 127, + [1][0][RTW89_THAILAND][13] = 127, + [1][1][RTW89_FCC][0] = 58, + [1][1][RTW89_ETSI][0] = 32, + [1][1][RTW89_MKK][0] = 34, + [1][1][RTW89_IC][0] = 58, + [1][1][RTW89_KCC][0] = 42, + [1][1][RTW89_ACMA][0] = 32, + [1][1][RTW89_CN][0] = 32, + [1][1][RTW89_UK][0] = 32, + [1][1][RTW89_MEXICO][0] = 58, + [1][1][RTW89_UKRAINE][0] = 32, + [1][1][RTW89_CHILE][0] = 58, + [1][1][RTW89_QATAR][0] = 32, + [1][1][RTW89_THAILAND][0] = 32, + [1][1][RTW89_FCC][1] = 58, + [1][1][RTW89_ETSI][1] = 34, + [1][1][RTW89_MKK][1] = 34, + [1][1][RTW89_IC][1] = 58, + [1][1][RTW89_KCC][1] = 42, + [1][1][RTW89_ACMA][1] = 34, + [1][1][RTW89_CN][1] = 32, + [1][1][RTW89_UK][1] = 34, + [1][1][RTW89_MEXICO][1] = 58, + [1][1][RTW89_UKRAINE][1] = 34, + [1][1][RTW89_CHILE][1] = 40, + [1][1][RTW89_QATAR][1] = 34, + [1][1][RTW89_THAILAND][1] = 34, + [1][1][RTW89_FCC][2] = 62, + [1][1][RTW89_ETSI][2] = 34, + [1][1][RTW89_MKK][2] = 34, + [1][1][RTW89_IC][2] = 62, + [1][1][RTW89_KCC][2] = 42, + [1][1][RTW89_ACMA][2] = 34, + [1][1][RTW89_CN][2] = 32, + [1][1][RTW89_UK][2] = 34, + [1][1][RTW89_MEXICO][2] = 62, + [1][1][RTW89_UKRAINE][2] = 34, + [1][1][RTW89_CHILE][2] = 40, + [1][1][RTW89_QATAR][2] = 34, + [1][1][RTW89_THAILAND][2] = 34, + [1][1][RTW89_FCC][3] = 66, + [1][1][RTW89_ETSI][3] = 34, + [1][1][RTW89_MKK][3] = 34, + [1][1][RTW89_IC][3] = 66, + [1][1][RTW89_KCC][3] = 42, + [1][1][RTW89_ACMA][3] = 34, + [1][1][RTW89_CN][3] = 32, + [1][1][RTW89_UK][3] = 34, + [1][1][RTW89_MEXICO][3] = 66, + [1][1][RTW89_UKRAINE][3] = 34, + [1][1][RTW89_CHILE][3] = 40, + [1][1][RTW89_QATAR][3] = 34, + [1][1][RTW89_THAILAND][3] = 34, + [1][1][RTW89_FCC][4] = 70, + [1][1][RTW89_ETSI][4] = 34, + [1][1][RTW89_MKK][4] = 34, + [1][1][RTW89_IC][4] = 70, + [1][1][RTW89_KCC][4] = 44, + [1][1][RTW89_ACMA][4] = 34, + [1][1][RTW89_CN][4] = 32, + [1][1][RTW89_UK][4] = 34, + [1][1][RTW89_MEXICO][4] = 70, + [1][1][RTW89_UKRAINE][4] = 34, + [1][1][RTW89_CHILE][4] = 40, + [1][1][RTW89_QATAR][4] = 34, + [1][1][RTW89_THAILAND][4] = 34, + [1][1][RTW89_FCC][5] = 82, + [1][1][RTW89_ETSI][5] = 34, + [1][1][RTW89_MKK][5] = 34, + [1][1][RTW89_IC][5] = 82, + [1][1][RTW89_KCC][5] = 44, + [1][1][RTW89_ACMA][5] = 34, + [1][1][RTW89_CN][5] = 32, + [1][1][RTW89_UK][5] = 34, + [1][1][RTW89_MEXICO][5] = 82, + [1][1][RTW89_UKRAINE][5] = 34, + [1][1][RTW89_CHILE][5] = 78, + [1][1][RTW89_QATAR][5] = 34, + [1][1][RTW89_THAILAND][5] = 34, + [1][1][RTW89_FCC][6] = 60, + [1][1][RTW89_ETSI][6] = 34, + [1][1][RTW89_MKK][6] = 34, + [1][1][RTW89_IC][6] = 60, + [1][1][RTW89_KCC][6] = 44, + [1][1][RTW89_ACMA][6] = 34, + [1][1][RTW89_CN][6] = 32, + [1][1][RTW89_UK][6] = 34, + [1][1][RTW89_MEXICO][6] = 60, + [1][1][RTW89_UKRAINE][6] = 34, + [1][1][RTW89_CHILE][6] = 30, + [1][1][RTW89_QATAR][6] = 34, + [1][1][RTW89_THAILAND][6] = 34, + [1][1][RTW89_FCC][7] = 56, + [1][1][RTW89_ETSI][7] = 34, + [1][1][RTW89_MKK][7] = 34, + [1][1][RTW89_IC][7] = 56, + [1][1][RTW89_KCC][7] = 44, + [1][1][RTW89_ACMA][7] = 34, + [1][1][RTW89_CN][7] = 32, + [1][1][RTW89_UK][7] = 34, + [1][1][RTW89_MEXICO][7] = 56, + [1][1][RTW89_UKRAINE][7] = 34, + [1][1][RTW89_CHILE][7] = 30, + [1][1][RTW89_QATAR][7] = 34, + [1][1][RTW89_THAILAND][7] = 34, + [1][1][RTW89_FCC][8] = 52, + [1][1][RTW89_ETSI][8] = 34, + [1][1][RTW89_MKK][8] = 34, + [1][1][RTW89_IC][8] = 52, + [1][1][RTW89_KCC][8] = 44, + [1][1][RTW89_ACMA][8] = 34, + [1][1][RTW89_CN][8] = 32, + [1][1][RTW89_UK][8] = 34, + [1][1][RTW89_MEXICO][8] = 52, + [1][1][RTW89_UKRAINE][8] = 34, + [1][1][RTW89_CHILE][8] = 30, + [1][1][RTW89_QATAR][8] = 34, + [1][1][RTW89_THAILAND][8] = 34, + [1][1][RTW89_FCC][9] = 48, + [1][1][RTW89_ETSI][9] = 34, + [1][1][RTW89_MKK][9] = 34, + [1][1][RTW89_IC][9] = 48, + [1][1][RTW89_KCC][9] = 44, + [1][1][RTW89_ACMA][9] = 34, + [1][1][RTW89_CN][9] = 32, + [1][1][RTW89_UK][9] = 34, + [1][1][RTW89_MEXICO][9] = 48, + [1][1][RTW89_UKRAINE][9] = 34, + [1][1][RTW89_CHILE][9] = 30, + [1][1][RTW89_QATAR][9] = 34, + [1][1][RTW89_THAILAND][9] = 34, + [1][1][RTW89_FCC][10] = 48, + [1][1][RTW89_ETSI][10] = 34, + [1][1][RTW89_MKK][10] = 34, + [1][1][RTW89_IC][10] = 48, + [1][1][RTW89_KCC][10] = 44, + [1][1][RTW89_ACMA][10] = 34, + [1][1][RTW89_CN][10] = 32, + [1][1][RTW89_UK][10] = 34, + [1][1][RTW89_MEXICO][10] = 48, + [1][1][RTW89_UKRAINE][10] = 34, + [1][1][RTW89_CHILE][10] = 48, + [1][1][RTW89_QATAR][10] = 34, + [1][1][RTW89_THAILAND][10] = 34, + [1][1][RTW89_FCC][11] = 30, + [1][1][RTW89_ETSI][11] = 34, + [1][1][RTW89_MKK][11] = 34, + [1][1][RTW89_IC][11] = 30, + [1][1][RTW89_KCC][11] = 44, + [1][1][RTW89_ACMA][11] = 34, + [1][1][RTW89_CN][11] = 32, + [1][1][RTW89_UK][11] = 34, + [1][1][RTW89_MEXICO][11] = 30, + [1][1][RTW89_UKRAINE][11] = 34, + [1][1][RTW89_CHILE][11] = 30, + [1][1][RTW89_QATAR][11] = 34, + [1][1][RTW89_THAILAND][11] = 34, + [1][1][RTW89_FCC][12] = -6, + [1][1][RTW89_ETSI][12] = 34, + [1][1][RTW89_MKK][12] = 34, + [1][1][RTW89_IC][12] = -6, + [1][1][RTW89_KCC][12] = 44, + [1][1][RTW89_ACMA][12] = 34, + [1][1][RTW89_CN][12] = 32, + [1][1][RTW89_UK][12] = 34, + [1][1][RTW89_MEXICO][12] = -6, + [1][1][RTW89_UKRAINE][12] = 34, + [1][1][RTW89_CHILE][12] = -6, + [1][1][RTW89_QATAR][12] = 34, + [1][1][RTW89_THAILAND][12] = 34, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_KCC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [1][1][RTW89_CN][13] = 127, + [1][1][RTW89_UK][13] = 127, + [1][1][RTW89_MEXICO][13] = 127, + [1][1][RTW89_UKRAINE][13] = 127, + [1][1][RTW89_CHILE][13] = 127, + [1][1][RTW89_QATAR][13] = 127, + [1][1][RTW89_THAILAND][13] = 127, + [2][0][RTW89_FCC][0] = 70, + [2][0][RTW89_ETSI][0] = 58, + [2][0][RTW89_MKK][0] = 58, + [2][0][RTW89_IC][0] = 70, + [2][0][RTW89_KCC][0] = 60, + [2][0][RTW89_ACMA][0] = 58, + [2][0][RTW89_CN][0] = 56, + [2][0][RTW89_UK][0] = 58, + [2][0][RTW89_MEXICO][0] = 70, + [2][0][RTW89_UKRAINE][0] = 58, + [2][0][RTW89_CHILE][0] = 70, + [2][0][RTW89_QATAR][0] = 58, + [2][0][RTW89_THAILAND][0] = 58, + [2][0][RTW89_FCC][1] = 70, + [2][0][RTW89_ETSI][1] = 58, + [2][0][RTW89_MKK][1] = 58, + [2][0][RTW89_IC][1] = 70, + [2][0][RTW89_KCC][1] = 60, + [2][0][RTW89_ACMA][1] = 58, + [2][0][RTW89_CN][1] = 56, + [2][0][RTW89_UK][1] = 58, + [2][0][RTW89_MEXICO][1] = 70, + [2][0][RTW89_UKRAINE][1] = 58, + [2][0][RTW89_CHILE][1] = 54, + [2][0][RTW89_QATAR][1] = 58, + [2][0][RTW89_THAILAND][1] = 58, + [2][0][RTW89_FCC][2] = 72, + [2][0][RTW89_ETSI][2] = 58, + [2][0][RTW89_MKK][2] = 58, + [2][0][RTW89_IC][2] = 72, + [2][0][RTW89_KCC][2] = 60, + [2][0][RTW89_ACMA][2] = 58, + [2][0][RTW89_CN][2] = 56, + [2][0][RTW89_UK][2] = 58, + [2][0][RTW89_MEXICO][2] = 72, + [2][0][RTW89_UKRAINE][2] = 58, + [2][0][RTW89_CHILE][2] = 54, + [2][0][RTW89_QATAR][2] = 58, + [2][0][RTW89_THAILAND][2] = 58, + [2][0][RTW89_FCC][3] = 72, + [2][0][RTW89_ETSI][3] = 58, + [2][0][RTW89_MKK][3] = 58, + [2][0][RTW89_IC][3] = 72, + [2][0][RTW89_KCC][3] = 60, + [2][0][RTW89_ACMA][3] = 58, + [2][0][RTW89_CN][3] = 56, + [2][0][RTW89_UK][3] = 58, + [2][0][RTW89_MEXICO][3] = 72, + [2][0][RTW89_UKRAINE][3] = 58, + [2][0][RTW89_CHILE][3] = 54, + [2][0][RTW89_QATAR][3] = 58, + [2][0][RTW89_THAILAND][3] = 58, + [2][0][RTW89_FCC][4] = 72, + [2][0][RTW89_ETSI][4] = 58, + [2][0][RTW89_MKK][4] = 58, + [2][0][RTW89_IC][4] = 72, + [2][0][RTW89_KCC][4] = 60, + [2][0][RTW89_ACMA][4] = 58, + [2][0][RTW89_CN][4] = 56, + [2][0][RTW89_UK][4] = 58, + [2][0][RTW89_MEXICO][4] = 72, + [2][0][RTW89_UKRAINE][4] = 58, + [2][0][RTW89_CHILE][4] = 54, + [2][0][RTW89_QATAR][4] = 58, + [2][0][RTW89_THAILAND][4] = 58, + [2][0][RTW89_FCC][5] = 82, + [2][0][RTW89_ETSI][5] = 58, + [2][0][RTW89_MKK][5] = 58, + [2][0][RTW89_IC][5] = 82, + [2][0][RTW89_KCC][5] = 60, + [2][0][RTW89_ACMA][5] = 58, + [2][0][RTW89_CN][5] = 56, + [2][0][RTW89_UK][5] = 58, + [2][0][RTW89_MEXICO][5] = 82, + [2][0][RTW89_UKRAINE][5] = 58, + [2][0][RTW89_CHILE][5] = 82, + [2][0][RTW89_QATAR][5] = 58, + [2][0][RTW89_THAILAND][5] = 58, + [2][0][RTW89_FCC][6] = 66, + [2][0][RTW89_ETSI][6] = 56, + [2][0][RTW89_MKK][6] = 58, + [2][0][RTW89_IC][6] = 66, + [2][0][RTW89_KCC][6] = 60, + [2][0][RTW89_ACMA][6] = 56, + [2][0][RTW89_CN][6] = 56, + [2][0][RTW89_UK][6] = 56, + [2][0][RTW89_MEXICO][6] = 66, + [2][0][RTW89_UKRAINE][6] = 56, + [2][0][RTW89_CHILE][6] = 48, + [2][0][RTW89_QATAR][6] = 56, + [2][0][RTW89_THAILAND][6] = 56, + [2][0][RTW89_FCC][7] = 66, + [2][0][RTW89_ETSI][7] = 58, + [2][0][RTW89_MKK][7] = 58, + [2][0][RTW89_IC][7] = 66, + [2][0][RTW89_KCC][7] = 60, + [2][0][RTW89_ACMA][7] = 58, + [2][0][RTW89_CN][7] = 56, + [2][0][RTW89_UK][7] = 58, + [2][0][RTW89_MEXICO][7] = 66, + [2][0][RTW89_UKRAINE][7] = 58, + [2][0][RTW89_CHILE][7] = 48, + [2][0][RTW89_QATAR][7] = 58, + [2][0][RTW89_THAILAND][7] = 58, + [2][0][RTW89_FCC][8] = 66, + [2][0][RTW89_ETSI][8] = 58, + [2][0][RTW89_MKK][8] = 58, + [2][0][RTW89_IC][8] = 66, + [2][0][RTW89_KCC][8] = 60, + [2][0][RTW89_ACMA][8] = 58, + [2][0][RTW89_CN][8] = 56, + [2][0][RTW89_UK][8] = 58, + [2][0][RTW89_MEXICO][8] = 66, + [2][0][RTW89_UKRAINE][8] = 58, + [2][0][RTW89_CHILE][8] = 48, + [2][0][RTW89_QATAR][8] = 58, + [2][0][RTW89_THAILAND][8] = 58, + [2][0][RTW89_FCC][9] = 64, + [2][0][RTW89_ETSI][9] = 58, + [2][0][RTW89_MKK][9] = 58, + [2][0][RTW89_IC][9] = 64, + [2][0][RTW89_KCC][9] = 60, + [2][0][RTW89_ACMA][9] = 58, + [2][0][RTW89_CN][9] = 56, + [2][0][RTW89_UK][9] = 58, + [2][0][RTW89_MEXICO][9] = 64, + [2][0][RTW89_UKRAINE][9] = 58, + [2][0][RTW89_CHILE][9] = 48, + [2][0][RTW89_QATAR][9] = 58, + [2][0][RTW89_THAILAND][9] = 58, + [2][0][RTW89_FCC][10] = 64, + [2][0][RTW89_ETSI][10] = 58, + [2][0][RTW89_MKK][10] = 58, + [2][0][RTW89_IC][10] = 64, + [2][0][RTW89_KCC][10] = 60, + [2][0][RTW89_ACMA][10] = 58, + [2][0][RTW89_CN][10] = 56, + [2][0][RTW89_UK][10] = 58, + [2][0][RTW89_MEXICO][10] = 64, + [2][0][RTW89_UKRAINE][10] = 58, + [2][0][RTW89_CHILE][10] = 64, + [2][0][RTW89_QATAR][10] = 58, + [2][0][RTW89_THAILAND][10] = 58, + [2][0][RTW89_FCC][11] = 48, + [2][0][RTW89_ETSI][11] = 58, + [2][0][RTW89_MKK][11] = 58, + [2][0][RTW89_IC][11] = 48, + [2][0][RTW89_KCC][11] = 60, + [2][0][RTW89_ACMA][11] = 58, + [2][0][RTW89_CN][11] = 56, + [2][0][RTW89_UK][11] = 58, + [2][0][RTW89_MEXICO][11] = 48, + [2][0][RTW89_UKRAINE][11] = 58, + [2][0][RTW89_CHILE][11] = 48, + [2][0][RTW89_QATAR][11] = 58, + [2][0][RTW89_THAILAND][11] = 58, + [2][0][RTW89_FCC][12] = 16, + [2][0][RTW89_ETSI][12] = 58, + [2][0][RTW89_MKK][12] = 58, + [2][0][RTW89_IC][12] = 16, + [2][0][RTW89_KCC][12] = 60, + [2][0][RTW89_ACMA][12] = 58, + [2][0][RTW89_CN][12] = 56, + [2][0][RTW89_UK][12] = 58, + [2][0][RTW89_MEXICO][12] = 16, + [2][0][RTW89_UKRAINE][12] = 58, + [2][0][RTW89_CHILE][12] = 16, + [2][0][RTW89_QATAR][12] = 58, + [2][0][RTW89_THAILAND][12] = 58, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_KCC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][0][RTW89_CN][13] = 127, + [2][0][RTW89_UK][13] = 127, + [2][0][RTW89_MEXICO][13] = 127, + [2][0][RTW89_UKRAINE][13] = 127, + [2][0][RTW89_CHILE][13] = 127, + [2][0][RTW89_QATAR][13] = 127, + [2][0][RTW89_THAILAND][13] = 127, + [2][1][RTW89_FCC][0] = 64, + [2][1][RTW89_ETSI][0] = 46, + [2][1][RTW89_MKK][0] = 46, + [2][1][RTW89_IC][0] = 64, + [2][1][RTW89_KCC][0] = 48, + [2][1][RTW89_ACMA][0] = 46, + [2][1][RTW89_CN][0] = 44, + [2][1][RTW89_UK][0] = 46, + [2][1][RTW89_MEXICO][0] = 64, + [2][1][RTW89_UKRAINE][0] = 46, + [2][1][RTW89_CHILE][0] = 64, + [2][1][RTW89_QATAR][0] = 46, + [2][1][RTW89_THAILAND][0] = 46, + [2][1][RTW89_FCC][1] = 64, + [2][1][RTW89_ETSI][1] = 46, + [2][1][RTW89_MKK][1] = 46, + [2][1][RTW89_IC][1] = 64, + [2][1][RTW89_KCC][1] = 48, + [2][1][RTW89_ACMA][1] = 46, + [2][1][RTW89_CN][1] = 44, + [2][1][RTW89_UK][1] = 46, + [2][1][RTW89_MEXICO][1] = 64, + [2][1][RTW89_UKRAINE][1] = 46, + [2][1][RTW89_CHILE][1] = 44, + [2][1][RTW89_QATAR][1] = 46, + [2][1][RTW89_THAILAND][1] = 46, + [2][1][RTW89_FCC][2] = 68, + [2][1][RTW89_ETSI][2] = 46, + [2][1][RTW89_MKK][2] = 46, + [2][1][RTW89_IC][2] = 68, + [2][1][RTW89_KCC][2] = 48, + [2][1][RTW89_ACMA][2] = 46, + [2][1][RTW89_CN][2] = 44, + [2][1][RTW89_UK][2] = 46, + [2][1][RTW89_MEXICO][2] = 68, + [2][1][RTW89_UKRAINE][2] = 46, + [2][1][RTW89_CHILE][2] = 44, + [2][1][RTW89_QATAR][2] = 46, + [2][1][RTW89_THAILAND][2] = 46, + [2][1][RTW89_FCC][3] = 72, + [2][1][RTW89_ETSI][3] = 46, + [2][1][RTW89_MKK][3] = 46, + [2][1][RTW89_IC][3] = 72, + [2][1][RTW89_KCC][3] = 48, + [2][1][RTW89_ACMA][3] = 46, + [2][1][RTW89_CN][3] = 44, + [2][1][RTW89_UK][3] = 46, + [2][1][RTW89_MEXICO][3] = 72, + [2][1][RTW89_UKRAINE][3] = 46, + [2][1][RTW89_CHILE][3] = 44, + [2][1][RTW89_QATAR][3] = 46, + [2][1][RTW89_THAILAND][3] = 46, + [2][1][RTW89_FCC][4] = 74, + [2][1][RTW89_ETSI][4] = 46, + [2][1][RTW89_MKK][4] = 46, + [2][1][RTW89_IC][4] = 74, + [2][1][RTW89_KCC][4] = 48, + [2][1][RTW89_ACMA][4] = 46, + [2][1][RTW89_CN][4] = 44, + [2][1][RTW89_UK][4] = 46, + [2][1][RTW89_MEXICO][4] = 74, + [2][1][RTW89_UKRAINE][4] = 46, + [2][1][RTW89_CHILE][4] = 44, + [2][1][RTW89_QATAR][4] = 46, + [2][1][RTW89_THAILAND][4] = 46, + [2][1][RTW89_FCC][5] = 82, + [2][1][RTW89_ETSI][5] = 46, + [2][1][RTW89_MKK][5] = 46, + [2][1][RTW89_IC][5] = 82, + [2][1][RTW89_KCC][5] = 48, + [2][1][RTW89_ACMA][5] = 46, + [2][1][RTW89_CN][5] = 44, + [2][1][RTW89_UK][5] = 46, + [2][1][RTW89_MEXICO][5] = 82, + [2][1][RTW89_UKRAINE][5] = 46, + [2][1][RTW89_CHILE][5] = 78, + [2][1][RTW89_QATAR][5] = 46, + [2][1][RTW89_THAILAND][5] = 46, + [2][1][RTW89_FCC][6] = 72, + [2][1][RTW89_ETSI][6] = 44, + [2][1][RTW89_MKK][6] = 46, + [2][1][RTW89_IC][6] = 72, + [2][1][RTW89_KCC][6] = 48, + [2][1][RTW89_ACMA][6] = 44, + [2][1][RTW89_CN][6] = 44, + [2][1][RTW89_UK][6] = 44, + [2][1][RTW89_MEXICO][6] = 72, + [2][1][RTW89_UKRAINE][6] = 44, + [2][1][RTW89_CHILE][6] = 42, + [2][1][RTW89_QATAR][6] = 44, + [2][1][RTW89_THAILAND][6] = 44, + [2][1][RTW89_FCC][7] = 72, + [2][1][RTW89_ETSI][7] = 46, + [2][1][RTW89_MKK][7] = 46, + [2][1][RTW89_IC][7] = 72, + [2][1][RTW89_KCC][7] = 48, + [2][1][RTW89_ACMA][7] = 46, + [2][1][RTW89_CN][7] = 44, + [2][1][RTW89_UK][7] = 46, + [2][1][RTW89_MEXICO][7] = 72, + [2][1][RTW89_UKRAINE][7] = 46, + [2][1][RTW89_CHILE][7] = 42, + [2][1][RTW89_QATAR][7] = 46, + [2][1][RTW89_THAILAND][7] = 46, + [2][1][RTW89_FCC][8] = 68, + [2][1][RTW89_ETSI][8] = 46, + [2][1][RTW89_MKK][8] = 46, + [2][1][RTW89_IC][8] = 68, + [2][1][RTW89_KCC][8] = 48, + [2][1][RTW89_ACMA][8] = 46, + [2][1][RTW89_CN][8] = 44, + [2][1][RTW89_UK][8] = 46, + [2][1][RTW89_MEXICO][8] = 68, + [2][1][RTW89_UKRAINE][8] = 46, + [2][1][RTW89_CHILE][8] = 42, + [2][1][RTW89_QATAR][8] = 46, + [2][1][RTW89_THAILAND][8] = 46, + [2][1][RTW89_FCC][9] = 64, + [2][1][RTW89_ETSI][9] = 46, + [2][1][RTW89_MKK][9] = 46, + [2][1][RTW89_IC][9] = 64, + [2][1][RTW89_KCC][9] = 48, + [2][1][RTW89_ACMA][9] = 46, + [2][1][RTW89_CN][9] = 44, + [2][1][RTW89_UK][9] = 46, + [2][1][RTW89_MEXICO][9] = 64, + [2][1][RTW89_UKRAINE][9] = 46, + [2][1][RTW89_CHILE][9] = 42, + [2][1][RTW89_QATAR][9] = 46, + [2][1][RTW89_THAILAND][9] = 46, + [2][1][RTW89_FCC][10] = 64, + [2][1][RTW89_ETSI][10] = 46, + [2][1][RTW89_MKK][10] = 46, + [2][1][RTW89_IC][10] = 64, + [2][1][RTW89_KCC][10] = 48, + [2][1][RTW89_ACMA][10] = 46, + [2][1][RTW89_CN][10] = 44, + [2][1][RTW89_UK][10] = 46, + [2][1][RTW89_MEXICO][10] = 64, + [2][1][RTW89_UKRAINE][10] = 46, + [2][1][RTW89_CHILE][10] = 64, + [2][1][RTW89_QATAR][10] = 46, + [2][1][RTW89_THAILAND][10] = 46, + [2][1][RTW89_FCC][11] = 46, + [2][1][RTW89_ETSI][11] = 46, + [2][1][RTW89_MKK][11] = 46, + [2][1][RTW89_IC][11] = 46, + [2][1][RTW89_KCC][11] = 48, + [2][1][RTW89_ACMA][11] = 46, + [2][1][RTW89_CN][11] = 44, + [2][1][RTW89_UK][11] = 46, + [2][1][RTW89_MEXICO][11] = 46, + [2][1][RTW89_UKRAINE][11] = 46, + [2][1][RTW89_CHILE][11] = 46, + [2][1][RTW89_QATAR][11] = 46, + [2][1][RTW89_THAILAND][11] = 46, + [2][1][RTW89_FCC][12] = 6, + [2][1][RTW89_ETSI][12] = 44, + [2][1][RTW89_MKK][12] = 46, + [2][1][RTW89_IC][12] = 6, + [2][1][RTW89_KCC][12] = 48, + [2][1][RTW89_ACMA][12] = 44, + [2][1][RTW89_CN][12] = 42, + [2][1][RTW89_UK][12] = 44, + [2][1][RTW89_MEXICO][12] = 6, + [2][1][RTW89_UKRAINE][12] = 44, + [2][1][RTW89_CHILE][12] = 6, + [2][1][RTW89_QATAR][12] = 44, + [2][1][RTW89_THAILAND][12] = 44, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_KCC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, + [2][1][RTW89_CN][13] = 127, + [2][1][RTW89_UK][13] = 127, + [2][1][RTW89_MEXICO][13] = 127, + [2][1][RTW89_UKRAINE][13] = 127, + [2][1][RTW89_CHILE][13] = 127, + [2][1][RTW89_QATAR][13] = 127, + [2][1][RTW89_THAILAND][13] = 127, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 16, + [0][0][RTW89_WW][2] = 16, + [0][0][RTW89_WW][4] = 16, + [0][0][RTW89_WW][6] = 16, + [0][0][RTW89_WW][8] = 16, + [0][0][RTW89_WW][10] = 16, + [0][0][RTW89_WW][12] = 16, + [0][0][RTW89_WW][14] = 16, + [0][0][RTW89_WW][15] = 22, + [0][0][RTW89_WW][17] = 22, + [0][0][RTW89_WW][19] = 22, + [0][0][RTW89_WW][21] = 22, + [0][0][RTW89_WW][23] = 22, + [0][0][RTW89_WW][25] = 22, + [0][0][RTW89_WW][27] = 22, + [0][0][RTW89_WW][29] = 22, + [0][0][RTW89_WW][31] = 22, + [0][0][RTW89_WW][33] = 22, + [0][0][RTW89_WW][35] = 22, + [0][0][RTW89_WW][37] = 30, + [0][0][RTW89_WW][38] = 26, + [0][0][RTW89_WW][40] = 26, + [0][0][RTW89_WW][42] = 26, + [0][0][RTW89_WW][44] = 26, + [0][0][RTW89_WW][46] = 26, + [0][0][RTW89_WW][48] = 46, + [0][0][RTW89_WW][50] = 44, + [0][0][RTW89_WW][52] = 34, + [0][1][RTW89_WW][0] = 4, + [0][1][RTW89_WW][2] = 4, + [0][1][RTW89_WW][4] = 4, + [0][1][RTW89_WW][6] = 4, + [0][1][RTW89_WW][8] = 4, + [0][1][RTW89_WW][10] = 4, + [0][1][RTW89_WW][12] = 4, + [0][1][RTW89_WW][14] = 4, + [0][1][RTW89_WW][15] = 10, + [0][1][RTW89_WW][17] = 10, + [0][1][RTW89_WW][19] = 10, + [0][1][RTW89_WW][21] = 10, + [0][1][RTW89_WW][23] = 10, + [0][1][RTW89_WW][25] = 10, + [0][1][RTW89_WW][27] = 10, + [0][1][RTW89_WW][29] = 10, + [0][1][RTW89_WW][31] = 10, + [0][1][RTW89_WW][33] = 10, + [0][1][RTW89_WW][35] = 10, + [0][1][RTW89_WW][37] = 18, + [0][1][RTW89_WW][38] = 14, + [0][1][RTW89_WW][40] = 14, + [0][1][RTW89_WW][42] = 14, + [0][1][RTW89_WW][44] = 14, + [0][1][RTW89_WW][46] = 14, + [0][1][RTW89_WW][48] = 20, + [0][1][RTW89_WW][50] = 20, + [0][1][RTW89_WW][52] = 8, + [1][0][RTW89_WW][0] = 26, + [1][0][RTW89_WW][2] = 26, + [1][0][RTW89_WW][4] = 26, + [1][0][RTW89_WW][6] = 26, + [1][0][RTW89_WW][8] = 26, + [1][0][RTW89_WW][10] = 26, + [1][0][RTW89_WW][12] = 26, + [1][0][RTW89_WW][14] = 26, + [1][0][RTW89_WW][15] = 32, + [1][0][RTW89_WW][17] = 32, + [1][0][RTW89_WW][19] = 32, + [1][0][RTW89_WW][21] = 32, + [1][0][RTW89_WW][23] = 32, + [1][0][RTW89_WW][25] = 32, + [1][0][RTW89_WW][27] = 32, + [1][0][RTW89_WW][29] = 32, + [1][0][RTW89_WW][31] = 32, + [1][0][RTW89_WW][33] = 32, + [1][0][RTW89_WW][35] = 32, + [1][0][RTW89_WW][37] = 42, + [1][0][RTW89_WW][38] = 26, + [1][0][RTW89_WW][40] = 26, + [1][0][RTW89_WW][42] = 26, + [1][0][RTW89_WW][44] = 26, + [1][0][RTW89_WW][46] = 26, + [1][0][RTW89_WW][48] = 56, + [1][0][RTW89_WW][50] = 58, + [1][0][RTW89_WW][52] = 56, + [1][1][RTW89_WW][0] = 14, + [1][1][RTW89_WW][2] = 14, + [1][1][RTW89_WW][4] = 14, + [1][1][RTW89_WW][6] = 14, + [1][1][RTW89_WW][8] = 14, + [1][1][RTW89_WW][10] = 14, + [1][1][RTW89_WW][12] = 14, + [1][1][RTW89_WW][14] = 14, + [1][1][RTW89_WW][15] = 20, + [1][1][RTW89_WW][17] = 20, + [1][1][RTW89_WW][19] = 20, + [1][1][RTW89_WW][21] = 20, + [1][1][RTW89_WW][23] = 20, + [1][1][RTW89_WW][25] = 20, + [1][1][RTW89_WW][27] = 20, + [1][1][RTW89_WW][29] = 20, + [1][1][RTW89_WW][31] = 20, + [1][1][RTW89_WW][33] = 20, + [1][1][RTW89_WW][35] = 20, + [1][1][RTW89_WW][37] = 32, + [1][1][RTW89_WW][38] = 14, + [1][1][RTW89_WW][40] = 14, + [1][1][RTW89_WW][42] = 14, + [1][1][RTW89_WW][44] = 14, + [1][1][RTW89_WW][46] = 14, + [1][1][RTW89_WW][48] = 34, + [1][1][RTW89_WW][50] = 34, + [1][1][RTW89_WW][52] = 30, + [2][0][RTW89_WW][0] = 40, + [2][0][RTW89_WW][2] = 40, + [2][0][RTW89_WW][4] = 40, + [2][0][RTW89_WW][6] = 38, + [2][0][RTW89_WW][8] = 40, + [2][0][RTW89_WW][10] = 40, + [2][0][RTW89_WW][12] = 40, + [2][0][RTW89_WW][14] = 40, + [2][0][RTW89_WW][15] = 46, + [2][0][RTW89_WW][17] = 46, + [2][0][RTW89_WW][19] = 46, + [2][0][RTW89_WW][21] = 46, + [2][0][RTW89_WW][23] = 46, + [2][0][RTW89_WW][25] = 46, + [2][0][RTW89_WW][27] = 46, + [2][0][RTW89_WW][29] = 46, + [2][0][RTW89_WW][31] = 46, + [2][0][RTW89_WW][33] = 46, + [2][0][RTW89_WW][35] = 46, + [2][0][RTW89_WW][37] = 52, + [2][0][RTW89_WW][38] = 26, + [2][0][RTW89_WW][40] = 26, + [2][0][RTW89_WW][42] = 26, + [2][0][RTW89_WW][44] = 26, + [2][0][RTW89_WW][46] = 26, + [2][0][RTW89_WW][48] = 64, + [2][0][RTW89_WW][50] = 64, + [2][0][RTW89_WW][52] = 64, + [2][1][RTW89_WW][0] = 26, + [2][1][RTW89_WW][2] = 26, + [2][1][RTW89_WW][4] = 26, + [2][1][RTW89_WW][6] = 26, + [2][1][RTW89_WW][8] = 28, + [2][1][RTW89_WW][10] = 28, + [2][1][RTW89_WW][12] = 28, + [2][1][RTW89_WW][14] = 28, + [2][1][RTW89_WW][15] = 34, + [2][1][RTW89_WW][17] = 34, + [2][1][RTW89_WW][19] = 34, + [2][1][RTW89_WW][21] = 34, + [2][1][RTW89_WW][23] = 34, + [2][1][RTW89_WW][25] = 34, + [2][1][RTW89_WW][27] = 34, + [2][1][RTW89_WW][29] = 34, + [2][1][RTW89_WW][31] = 34, + [2][1][RTW89_WW][33] = 34, + [2][1][RTW89_WW][35] = 34, + [2][1][RTW89_WW][37] = 42, + [2][1][RTW89_WW][38] = 14, + [2][1][RTW89_WW][40] = 14, + [2][1][RTW89_WW][42] = 14, + [2][1][RTW89_WW][44] = 14, + [2][1][RTW89_WW][46] = 14, + [2][1][RTW89_WW][48] = 40, + [2][1][RTW89_WW][50] = 40, + [2][1][RTW89_WW][52] = 40, + [0][0][RTW89_FCC][0] = 50, + [0][0][RTW89_ETSI][0] = 30, + [0][0][RTW89_MKK][0] = 36, + [0][0][RTW89_IC][0] = 32, + [0][0][RTW89_KCC][0] = 42, + [0][0][RTW89_ACMA][0] = 30, + [0][0][RTW89_CN][0] = 16, + [0][0][RTW89_UK][0] = 30, + [0][0][RTW89_MEXICO][0] = 50, + [0][0][RTW89_UKRAINE][0] = 22, + [0][0][RTW89_CHILE][0] = 50, + [0][0][RTW89_QATAR][0] = 30, + [0][0][RTW89_THAILAND][0] = 30, + [0][0][RTW89_FCC][2] = 50, + [0][0][RTW89_ETSI][2] = 30, + [0][0][RTW89_MKK][2] = 36, + [0][0][RTW89_IC][2] = 32, + [0][0][RTW89_KCC][2] = 42, + [0][0][RTW89_ACMA][2] = 30, + [0][0][RTW89_CN][2] = 16, + [0][0][RTW89_UK][2] = 30, + [0][0][RTW89_MEXICO][2] = 50, + [0][0][RTW89_UKRAINE][2] = 22, + [0][0][RTW89_CHILE][2] = 50, + [0][0][RTW89_QATAR][2] = 30, + [0][0][RTW89_THAILAND][2] = 30, + [0][0][RTW89_FCC][4] = 50, + [0][0][RTW89_ETSI][4] = 30, + [0][0][RTW89_MKK][4] = 22, + [0][0][RTW89_IC][4] = 32, + [0][0][RTW89_KCC][4] = 42, + [0][0][RTW89_ACMA][4] = 30, + [0][0][RTW89_CN][4] = 16, + [0][0][RTW89_UK][4] = 30, + [0][0][RTW89_MEXICO][4] = 50, + [0][0][RTW89_UKRAINE][4] = 22, + [0][0][RTW89_CHILE][4] = 50, + [0][0][RTW89_QATAR][4] = 30, + [0][0][RTW89_THAILAND][4] = 30, + [0][0][RTW89_FCC][6] = 50, + [0][0][RTW89_ETSI][6] = 30, + [0][0][RTW89_MKK][6] = 22, + [0][0][RTW89_IC][6] = 32, + [0][0][RTW89_KCC][6] = 18, + [0][0][RTW89_ACMA][6] = 30, + [0][0][RTW89_CN][6] = 16, + [0][0][RTW89_UK][6] = 30, + [0][0][RTW89_MEXICO][6] = 50, + [0][0][RTW89_UKRAINE][6] = 22, + [0][0][RTW89_CHILE][6] = 50, + [0][0][RTW89_QATAR][6] = 30, + [0][0][RTW89_THAILAND][6] = 30, + [0][0][RTW89_FCC][8] = 52, + [0][0][RTW89_ETSI][8] = 28, + [0][0][RTW89_MKK][8] = 18, + [0][0][RTW89_IC][8] = 52, + [0][0][RTW89_KCC][8] = 40, + [0][0][RTW89_ACMA][8] = 28, + [0][0][RTW89_CN][8] = 16, + [0][0][RTW89_UK][8] = 28, + [0][0][RTW89_MEXICO][8] = 52, + [0][0][RTW89_UKRAINE][8] = 22, + [0][0][RTW89_CHILE][8] = 52, + [0][0][RTW89_QATAR][8] = 28, + [0][0][RTW89_THAILAND][8] = 28, + [0][0][RTW89_FCC][10] = 52, + [0][0][RTW89_ETSI][10] = 28, + [0][0][RTW89_MKK][10] = 18, + [0][0][RTW89_IC][10] = 52, + [0][0][RTW89_KCC][10] = 40, + [0][0][RTW89_ACMA][10] = 28, + [0][0][RTW89_CN][10] = 16, + [0][0][RTW89_UK][10] = 28, + [0][0][RTW89_MEXICO][10] = 52, + [0][0][RTW89_UKRAINE][10] = 22, + [0][0][RTW89_CHILE][10] = 52, + [0][0][RTW89_QATAR][10] = 28, + [0][0][RTW89_THAILAND][10] = 28, + [0][0][RTW89_FCC][12] = 52, + [0][0][RTW89_ETSI][12] = 28, + [0][0][RTW89_MKK][12] = 34, + [0][0][RTW89_IC][12] = 52, + [0][0][RTW89_KCC][12] = 40, + [0][0][RTW89_ACMA][12] = 28, + [0][0][RTW89_CN][12] = 16, + [0][0][RTW89_UK][12] = 28, + [0][0][RTW89_MEXICO][12] = 52, + [0][0][RTW89_UKRAINE][12] = 22, + [0][0][RTW89_CHILE][12] = 52, + [0][0][RTW89_QATAR][12] = 28, + [0][0][RTW89_THAILAND][12] = 28, + [0][0][RTW89_FCC][14] = 52, + [0][0][RTW89_ETSI][14] = 28, + [0][0][RTW89_MKK][14] = 34, + [0][0][RTW89_IC][14] = 52, + [0][0][RTW89_KCC][14] = 40, + [0][0][RTW89_ACMA][14] = 28, + [0][0][RTW89_CN][14] = 16, + [0][0][RTW89_UK][14] = 28, + [0][0][RTW89_MEXICO][14] = 52, + [0][0][RTW89_UKRAINE][14] = 22, + [0][0][RTW89_CHILE][14] = 52, + [0][0][RTW89_QATAR][14] = 28, + [0][0][RTW89_THAILAND][14] = 28, + [0][0][RTW89_FCC][15] = 52, + [0][0][RTW89_ETSI][15] = 30, + [0][0][RTW89_MKK][15] = 56, + [0][0][RTW89_IC][15] = 52, + [0][0][RTW89_KCC][15] = 40, + [0][0][RTW89_ACMA][15] = 30, + [0][0][RTW89_CN][15] = 127, + [0][0][RTW89_UK][15] = 30, + [0][0][RTW89_MEXICO][15] = 52, + [0][0][RTW89_UKRAINE][15] = 22, + [0][0][RTW89_CHILE][15] = 52, + [0][0][RTW89_QATAR][15] = 30, + [0][0][RTW89_THAILAND][15] = 30, + [0][0][RTW89_FCC][17] = 52, + [0][0][RTW89_ETSI][17] = 30, + [0][0][RTW89_MKK][17] = 58, + [0][0][RTW89_IC][17] = 52, + [0][0][RTW89_KCC][17] = 40, + [0][0][RTW89_ACMA][17] = 30, + [0][0][RTW89_CN][17] = 127, + [0][0][RTW89_UK][17] = 30, + [0][0][RTW89_MEXICO][17] = 52, + [0][0][RTW89_UKRAINE][17] = 22, + [0][0][RTW89_CHILE][17] = 52, + [0][0][RTW89_QATAR][17] = 30, + [0][0][RTW89_THAILAND][17] = 30, + [0][0][RTW89_FCC][19] = 52, + [0][0][RTW89_ETSI][19] = 30, + [0][0][RTW89_MKK][19] = 58, + [0][0][RTW89_IC][19] = 52, + [0][0][RTW89_KCC][19] = 40, + [0][0][RTW89_ACMA][19] = 30, + [0][0][RTW89_CN][19] = 127, + [0][0][RTW89_UK][19] = 30, + [0][0][RTW89_MEXICO][19] = 52, + [0][0][RTW89_UKRAINE][19] = 22, + [0][0][RTW89_CHILE][19] = 52, + [0][0][RTW89_QATAR][19] = 30, + [0][0][RTW89_THAILAND][19] = 30, + [0][0][RTW89_FCC][21] = 52, + [0][0][RTW89_ETSI][21] = 30, + [0][0][RTW89_MKK][21] = 58, + [0][0][RTW89_IC][21] = 52, + [0][0][RTW89_KCC][21] = 40, + [0][0][RTW89_ACMA][21] = 30, + [0][0][RTW89_CN][21] = 127, + [0][0][RTW89_UK][21] = 30, + [0][0][RTW89_MEXICO][21] = 52, + [0][0][RTW89_UKRAINE][21] = 22, + [0][0][RTW89_CHILE][21] = 52, + [0][0][RTW89_QATAR][21] = 30, + [0][0][RTW89_THAILAND][21] = 30, + [0][0][RTW89_FCC][23] = 52, + [0][0][RTW89_ETSI][23] = 30, + [0][0][RTW89_MKK][23] = 58, + [0][0][RTW89_IC][23] = 52, + [0][0][RTW89_KCC][23] = 40, + [0][0][RTW89_ACMA][23] = 30, + [0][0][RTW89_CN][23] = 127, + [0][0][RTW89_UK][23] = 30, + [0][0][RTW89_MEXICO][23] = 52, + [0][0][RTW89_UKRAINE][23] = 22, + [0][0][RTW89_CHILE][23] = 52, + [0][0][RTW89_QATAR][23] = 30, + [0][0][RTW89_THAILAND][23] = 30, + [0][0][RTW89_FCC][25] = 52, + [0][0][RTW89_ETSI][25] = 30, + [0][0][RTW89_MKK][25] = 58, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_KCC][25] = 40, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_CN][25] = 127, + [0][0][RTW89_UK][25] = 30, + [0][0][RTW89_MEXICO][25] = 52, + [0][0][RTW89_UKRAINE][25] = 22, + [0][0][RTW89_CHILE][25] = 52, + [0][0][RTW89_QATAR][25] = 30, + [0][0][RTW89_THAILAND][25] = 30, + [0][0][RTW89_FCC][27] = 52, + [0][0][RTW89_ETSI][27] = 30, + [0][0][RTW89_MKK][27] = 58, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_KCC][27] = 40, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_CN][27] = 127, + [0][0][RTW89_UK][27] = 30, + [0][0][RTW89_MEXICO][27] = 52, + [0][0][RTW89_UKRAINE][27] = 22, + [0][0][RTW89_CHILE][27] = 52, + [0][0][RTW89_QATAR][27] = 30, + [0][0][RTW89_THAILAND][27] = 30, + [0][0][RTW89_FCC][29] = 52, + [0][0][RTW89_ETSI][29] = 30, + [0][0][RTW89_MKK][29] = 58, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_KCC][29] = 40, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_CN][29] = 127, + [0][0][RTW89_UK][29] = 30, + [0][0][RTW89_MEXICO][29] = 52, + [0][0][RTW89_UKRAINE][29] = 22, + [0][0][RTW89_CHILE][29] = 52, + [0][0][RTW89_QATAR][29] = 30, + [0][0][RTW89_THAILAND][29] = 30, + [0][0][RTW89_FCC][31] = 52, + [0][0][RTW89_ETSI][31] = 30, + [0][0][RTW89_MKK][31] = 58, + [0][0][RTW89_IC][31] = 44, + [0][0][RTW89_KCC][31] = 42, + [0][0][RTW89_ACMA][31] = 30, + [0][0][RTW89_CN][31] = 127, + [0][0][RTW89_UK][31] = 30, + [0][0][RTW89_MEXICO][31] = 52, + [0][0][RTW89_UKRAINE][31] = 22, + [0][0][RTW89_CHILE][31] = 52, + [0][0][RTW89_QATAR][31] = 30, + [0][0][RTW89_THAILAND][31] = 30, + [0][0][RTW89_FCC][33] = 44, + [0][0][RTW89_ETSI][33] = 30, + [0][0][RTW89_MKK][33] = 58, + [0][0][RTW89_IC][33] = 44, + [0][0][RTW89_KCC][33] = 42, + [0][0][RTW89_ACMA][33] = 30, + [0][0][RTW89_CN][33] = 127, + [0][0][RTW89_UK][33] = 30, + [0][0][RTW89_MEXICO][33] = 44, + [0][0][RTW89_UKRAINE][33] = 22, + [0][0][RTW89_CHILE][33] = 44, + [0][0][RTW89_QATAR][33] = 30, + [0][0][RTW89_THAILAND][33] = 30, + [0][0][RTW89_FCC][35] = 44, + [0][0][RTW89_ETSI][35] = 30, + [0][0][RTW89_MKK][35] = 58, + [0][0][RTW89_IC][35] = 44, + [0][0][RTW89_KCC][35] = 42, + [0][0][RTW89_ACMA][35] = 30, + [0][0][RTW89_CN][35] = 127, + [0][0][RTW89_UK][35] = 30, + [0][0][RTW89_MEXICO][35] = 44, + [0][0][RTW89_UKRAINE][35] = 22, + [0][0][RTW89_CHILE][35] = 44, + [0][0][RTW89_QATAR][35] = 30, + [0][0][RTW89_THAILAND][35] = 30, + [0][0][RTW89_FCC][37] = 52, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 58, + [0][0][RTW89_IC][37] = 52, + [0][0][RTW89_KCC][37] = 42, + [0][0][RTW89_ACMA][37] = 52, + [0][0][RTW89_CN][37] = 127, + [0][0][RTW89_UK][37] = 30, + [0][0][RTW89_MEXICO][37] = 52, + [0][0][RTW89_UKRAINE][37] = 127, + [0][0][RTW89_CHILE][37] = 52, + [0][0][RTW89_QATAR][37] = 127, + [0][0][RTW89_THAILAND][37] = 127, + [0][0][RTW89_FCC][38] = 64, + [0][0][RTW89_ETSI][38] = 28, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 64, + [0][0][RTW89_KCC][38] = 42, + [0][0][RTW89_ACMA][38] = 64, + [0][0][RTW89_CN][38] = 54, + [0][0][RTW89_UK][38] = 30, + [0][0][RTW89_MEXICO][38] = 64, + [0][0][RTW89_UKRAINE][38] = 26, + [0][0][RTW89_CHILE][38] = 64, + [0][0][RTW89_QATAR][38] = 26, + [0][0][RTW89_THAILAND][38] = 28, + [0][0][RTW89_FCC][40] = 64, + [0][0][RTW89_ETSI][40] = 28, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 64, + [0][0][RTW89_KCC][40] = 42, + [0][0][RTW89_ACMA][40] = 64, + [0][0][RTW89_CN][40] = 54, + [0][0][RTW89_UK][40] = 30, + [0][0][RTW89_MEXICO][40] = 64, + [0][0][RTW89_UKRAINE][40] = 26, + [0][0][RTW89_CHILE][40] = 64, + [0][0][RTW89_QATAR][40] = 26, + [0][0][RTW89_THAILAND][40] = 28, + [0][0][RTW89_FCC][42] = 60, + [0][0][RTW89_ETSI][42] = 28, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 60, + [0][0][RTW89_KCC][42] = 42, + [0][0][RTW89_ACMA][42] = 60, + [0][0][RTW89_CN][42] = 54, + [0][0][RTW89_UK][42] = 30, + [0][0][RTW89_MEXICO][42] = 60, + [0][0][RTW89_UKRAINE][42] = 26, + [0][0][RTW89_CHILE][42] = 60, + [0][0][RTW89_QATAR][42] = 26, + [0][0][RTW89_THAILAND][42] = 28, + [0][0][RTW89_FCC][44] = 60, + [0][0][RTW89_ETSI][44] = 28, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 60, + [0][0][RTW89_KCC][44] = 42, + [0][0][RTW89_ACMA][44] = 60, + [0][0][RTW89_CN][44] = 54, + [0][0][RTW89_UK][44] = 30, + [0][0][RTW89_MEXICO][44] = 60, + [0][0][RTW89_UKRAINE][44] = 26, + [0][0][RTW89_CHILE][44] = 60, + [0][0][RTW89_QATAR][44] = 26, + [0][0][RTW89_THAILAND][44] = 28, + [0][0][RTW89_FCC][46] = 60, + [0][0][RTW89_ETSI][46] = 28, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 60, + [0][0][RTW89_KCC][46] = 42, + [0][0][RTW89_ACMA][46] = 60, + [0][0][RTW89_CN][46] = 54, + [0][0][RTW89_UK][46] = 30, + [0][0][RTW89_MEXICO][46] = 60, + [0][0][RTW89_UKRAINE][46] = 26, + [0][0][RTW89_CHILE][46] = 60, + [0][0][RTW89_QATAR][46] = 26, + [0][0][RTW89_THAILAND][46] = 28, + [0][0][RTW89_FCC][48] = 46, + [0][0][RTW89_ETSI][48] = 127, + [0][0][RTW89_MKK][48] = 127, + [0][0][RTW89_IC][48] = 46, + [0][0][RTW89_KCC][48] = 127, + [0][0][RTW89_ACMA][48] = 127, + [0][0][RTW89_CN][48] = 127, + [0][0][RTW89_UK][48] = 127, + [0][0][RTW89_MEXICO][48] = 127, + [0][0][RTW89_UKRAINE][48] = 127, + [0][0][RTW89_CHILE][48] = 127, + [0][0][RTW89_QATAR][48] = 127, + [0][0][RTW89_THAILAND][48] = 127, + [0][0][RTW89_FCC][50] = 44, + [0][0][RTW89_ETSI][50] = 127, + [0][0][RTW89_MKK][50] = 127, + [0][0][RTW89_IC][50] = 44, + [0][0][RTW89_KCC][50] = 127, + [0][0][RTW89_ACMA][50] = 127, + [0][0][RTW89_CN][50] = 127, + [0][0][RTW89_UK][50] = 127, + [0][0][RTW89_MEXICO][50] = 127, + [0][0][RTW89_UKRAINE][50] = 127, + [0][0][RTW89_CHILE][50] = 127, + [0][0][RTW89_QATAR][50] = 127, + [0][0][RTW89_THAILAND][50] = 127, + [0][0][RTW89_FCC][52] = 34, + [0][0][RTW89_ETSI][52] = 127, + [0][0][RTW89_MKK][52] = 127, + [0][0][RTW89_IC][52] = 34, + [0][0][RTW89_KCC][52] = 127, + [0][0][RTW89_ACMA][52] = 127, + [0][0][RTW89_CN][52] = 127, + [0][0][RTW89_UK][52] = 127, + [0][0][RTW89_MEXICO][52] = 127, + [0][0][RTW89_UKRAINE][52] = 127, + [0][0][RTW89_CHILE][52] = 127, + [0][0][RTW89_QATAR][52] = 127, + [0][0][RTW89_THAILAND][52] = 127, + [0][1][RTW89_FCC][0] = 30, + [0][1][RTW89_ETSI][0] = 18, + [0][1][RTW89_MKK][0] = 20, + [0][1][RTW89_IC][0] = 8, + [0][1][RTW89_KCC][0] = 32, + [0][1][RTW89_ACMA][0] = 18, + [0][1][RTW89_CN][0] = 4, + [0][1][RTW89_UK][0] = 18, + [0][1][RTW89_MEXICO][0] = 30, + [0][1][RTW89_UKRAINE][0] = 10, + [0][1][RTW89_CHILE][0] = 30, + [0][1][RTW89_QATAR][0] = 18, + [0][1][RTW89_THAILAND][0] = 18, + [0][1][RTW89_FCC][2] = 32, + [0][1][RTW89_ETSI][2] = 18, + [0][1][RTW89_MKK][2] = 20, + [0][1][RTW89_IC][2] = 8, + [0][1][RTW89_KCC][2] = 32, + [0][1][RTW89_ACMA][2] = 18, + [0][1][RTW89_CN][2] = 4, + [0][1][RTW89_UK][2] = 18, + [0][1][RTW89_MEXICO][2] = 32, + [0][1][RTW89_UKRAINE][2] = 10, + [0][1][RTW89_CHILE][2] = 32, + [0][1][RTW89_QATAR][2] = 18, + [0][1][RTW89_THAILAND][2] = 18, + [0][1][RTW89_FCC][4] = 30, + [0][1][RTW89_ETSI][4] = 18, + [0][1][RTW89_MKK][4] = 8, + [0][1][RTW89_IC][4] = 8, + [0][1][RTW89_KCC][4] = 32, + [0][1][RTW89_ACMA][4] = 18, + [0][1][RTW89_CN][4] = 4, + [0][1][RTW89_UK][4] = 18, + [0][1][RTW89_MEXICO][4] = 30, + [0][1][RTW89_UKRAINE][4] = 10, + [0][1][RTW89_CHILE][4] = 30, + [0][1][RTW89_QATAR][4] = 18, + [0][1][RTW89_THAILAND][4] = 18, + [0][1][RTW89_FCC][6] = 30, + [0][1][RTW89_ETSI][6] = 18, + [0][1][RTW89_MKK][6] = 8, + [0][1][RTW89_IC][6] = 8, + [0][1][RTW89_KCC][6] = 6, + [0][1][RTW89_ACMA][6] = 18, + [0][1][RTW89_CN][6] = 4, + [0][1][RTW89_UK][6] = 18, + [0][1][RTW89_MEXICO][6] = 30, + [0][1][RTW89_UKRAINE][6] = 10, + [0][1][RTW89_CHILE][6] = 30, + [0][1][RTW89_QATAR][6] = 18, + [0][1][RTW89_THAILAND][6] = 18, + [0][1][RTW89_FCC][8] = 30, + [0][1][RTW89_ETSI][8] = 16, + [0][1][RTW89_MKK][8] = 20, + [0][1][RTW89_IC][8] = 30, + [0][1][RTW89_KCC][8] = 28, + [0][1][RTW89_ACMA][8] = 16, + [0][1][RTW89_CN][8] = 4, + [0][1][RTW89_UK][8] = 16, + [0][1][RTW89_MEXICO][8] = 30, + [0][1][RTW89_UKRAINE][8] = 10, + [0][1][RTW89_CHILE][8] = 30, + [0][1][RTW89_QATAR][8] = 16, + [0][1][RTW89_THAILAND][8] = 16, + [0][1][RTW89_FCC][10] = 30, + [0][1][RTW89_ETSI][10] = 16, + [0][1][RTW89_MKK][10] = 20, + [0][1][RTW89_IC][10] = 30, + [0][1][RTW89_KCC][10] = 28, + [0][1][RTW89_ACMA][10] = 16, + [0][1][RTW89_CN][10] = 4, + [0][1][RTW89_UK][10] = 16, + [0][1][RTW89_MEXICO][10] = 30, + [0][1][RTW89_UKRAINE][10] = 10, + [0][1][RTW89_CHILE][10] = 30, + [0][1][RTW89_QATAR][10] = 16, + [0][1][RTW89_THAILAND][10] = 16, + [0][1][RTW89_FCC][12] = 30, + [0][1][RTW89_ETSI][12] = 16, + [0][1][RTW89_MKK][12] = 34, + [0][1][RTW89_IC][12] = 30, + [0][1][RTW89_KCC][12] = 26, + [0][1][RTW89_ACMA][12] = 16, + [0][1][RTW89_CN][12] = 4, + [0][1][RTW89_UK][12] = 16, + [0][1][RTW89_MEXICO][12] = 30, + [0][1][RTW89_UKRAINE][12] = 10, + [0][1][RTW89_CHILE][12] = 30, + [0][1][RTW89_QATAR][12] = 16, + [0][1][RTW89_THAILAND][12] = 16, + [0][1][RTW89_FCC][14] = 30, + [0][1][RTW89_ETSI][14] = 16, + [0][1][RTW89_MKK][14] = 34, + [0][1][RTW89_IC][14] = 30, + [0][1][RTW89_KCC][14] = 26, + [0][1][RTW89_ACMA][14] = 16, + [0][1][RTW89_CN][14] = 4, + [0][1][RTW89_UK][14] = 16, + [0][1][RTW89_MEXICO][14] = 30, + [0][1][RTW89_UKRAINE][14] = 10, + [0][1][RTW89_CHILE][14] = 30, + [0][1][RTW89_QATAR][14] = 16, + [0][1][RTW89_THAILAND][14] = 16, + [0][1][RTW89_FCC][15] = 32, + [0][1][RTW89_ETSI][15] = 18, + [0][1][RTW89_MKK][15] = 44, + [0][1][RTW89_IC][15] = 32, + [0][1][RTW89_KCC][15] = 28, + [0][1][RTW89_ACMA][15] = 18, + [0][1][RTW89_CN][15] = 127, + [0][1][RTW89_UK][15] = 18, + [0][1][RTW89_MEXICO][15] = 32, + [0][1][RTW89_UKRAINE][15] = 10, + [0][1][RTW89_CHILE][15] = 32, + [0][1][RTW89_QATAR][15] = 18, + [0][1][RTW89_THAILAND][15] = 18, + [0][1][RTW89_FCC][17] = 32, + [0][1][RTW89_ETSI][17] = 18, + [0][1][RTW89_MKK][17] = 44, + [0][1][RTW89_IC][17] = 32, + [0][1][RTW89_KCC][17] = 28, + [0][1][RTW89_ACMA][17] = 18, + [0][1][RTW89_CN][17] = 127, + [0][1][RTW89_UK][17] = 18, + [0][1][RTW89_MEXICO][17] = 32, + [0][1][RTW89_UKRAINE][17] = 10, + [0][1][RTW89_CHILE][17] = 32, + [0][1][RTW89_QATAR][17] = 18, + [0][1][RTW89_THAILAND][17] = 18, + [0][1][RTW89_FCC][19] = 32, + [0][1][RTW89_ETSI][19] = 18, + [0][1][RTW89_MKK][19] = 44, + [0][1][RTW89_IC][19] = 32, + [0][1][RTW89_KCC][19] = 28, + [0][1][RTW89_ACMA][19] = 18, + [0][1][RTW89_CN][19] = 127, + [0][1][RTW89_UK][19] = 18, + [0][1][RTW89_MEXICO][19] = 32, + [0][1][RTW89_UKRAINE][19] = 10, + [0][1][RTW89_CHILE][19] = 32, + [0][1][RTW89_QATAR][19] = 18, + [0][1][RTW89_THAILAND][19] = 18, + [0][1][RTW89_FCC][21] = 32, + [0][1][RTW89_ETSI][21] = 18, + [0][1][RTW89_MKK][21] = 44, + [0][1][RTW89_IC][21] = 32, + [0][1][RTW89_KCC][21] = 28, + [0][1][RTW89_ACMA][21] = 18, + [0][1][RTW89_CN][21] = 127, + [0][1][RTW89_UK][21] = 18, + [0][1][RTW89_MEXICO][21] = 32, + [0][1][RTW89_UKRAINE][21] = 10, + [0][1][RTW89_CHILE][21] = 32, + [0][1][RTW89_QATAR][21] = 18, + [0][1][RTW89_THAILAND][21] = 18, + [0][1][RTW89_FCC][23] = 32, + [0][1][RTW89_ETSI][23] = 18, + [0][1][RTW89_MKK][23] = 44, + [0][1][RTW89_IC][23] = 32, + [0][1][RTW89_KCC][23] = 28, + [0][1][RTW89_ACMA][23] = 18, + [0][1][RTW89_CN][23] = 127, + [0][1][RTW89_UK][23] = 18, + [0][1][RTW89_MEXICO][23] = 32, + [0][1][RTW89_UKRAINE][23] = 10, + [0][1][RTW89_CHILE][23] = 32, + [0][1][RTW89_QATAR][23] = 18, + [0][1][RTW89_THAILAND][23] = 18, + [0][1][RTW89_FCC][25] = 32, + [0][1][RTW89_ETSI][25] = 18, + [0][1][RTW89_MKK][25] = 44, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_KCC][25] = 28, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_CN][25] = 127, + [0][1][RTW89_UK][25] = 18, + [0][1][RTW89_MEXICO][25] = 32, + [0][1][RTW89_UKRAINE][25] = 10, + [0][1][RTW89_CHILE][25] = 32, + [0][1][RTW89_QATAR][25] = 18, + [0][1][RTW89_THAILAND][25] = 18, + [0][1][RTW89_FCC][27] = 32, + [0][1][RTW89_ETSI][27] = 16, + [0][1][RTW89_MKK][27] = 44, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_KCC][27] = 28, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_CN][27] = 127, + [0][1][RTW89_UK][27] = 16, + [0][1][RTW89_MEXICO][27] = 32, + [0][1][RTW89_UKRAINE][27] = 10, + [0][1][RTW89_CHILE][27] = 32, + [0][1][RTW89_QATAR][27] = 16, + [0][1][RTW89_THAILAND][27] = 16, + [0][1][RTW89_FCC][29] = 32, + [0][1][RTW89_ETSI][29] = 16, + [0][1][RTW89_MKK][29] = 44, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_KCC][29] = 28, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_CN][29] = 127, + [0][1][RTW89_UK][29] = 16, + [0][1][RTW89_MEXICO][29] = 32, + [0][1][RTW89_UKRAINE][29] = 10, + [0][1][RTW89_CHILE][29] = 32, + [0][1][RTW89_QATAR][29] = 16, + [0][1][RTW89_THAILAND][29] = 16, + [0][1][RTW89_FCC][31] = 32, + [0][1][RTW89_ETSI][31] = 16, + [0][1][RTW89_MKK][31] = 44, + [0][1][RTW89_IC][31] = 30, + [0][1][RTW89_KCC][31] = 28, + [0][1][RTW89_ACMA][31] = 16, + [0][1][RTW89_CN][31] = 127, + [0][1][RTW89_UK][31] = 16, + [0][1][RTW89_MEXICO][31] = 32, + [0][1][RTW89_UKRAINE][31] = 10, + [0][1][RTW89_CHILE][31] = 32, + [0][1][RTW89_QATAR][31] = 16, + [0][1][RTW89_THAILAND][31] = 16, + [0][1][RTW89_FCC][33] = 30, + [0][1][RTW89_ETSI][33] = 16, + [0][1][RTW89_MKK][33] = 44, + [0][1][RTW89_IC][33] = 30, + [0][1][RTW89_KCC][33] = 28, + [0][1][RTW89_ACMA][33] = 16, + [0][1][RTW89_CN][33] = 127, + [0][1][RTW89_UK][33] = 16, + [0][1][RTW89_MEXICO][33] = 30, + [0][1][RTW89_UKRAINE][33] = 10, + [0][1][RTW89_CHILE][33] = 30, + [0][1][RTW89_QATAR][33] = 16, + [0][1][RTW89_THAILAND][33] = 16, + [0][1][RTW89_FCC][35] = 30, + [0][1][RTW89_ETSI][35] = 16, + [0][1][RTW89_MKK][35] = 44, + [0][1][RTW89_IC][35] = 30, + [0][1][RTW89_KCC][35] = 28, + [0][1][RTW89_ACMA][35] = 16, + [0][1][RTW89_CN][35] = 127, + [0][1][RTW89_UK][35] = 16, + [0][1][RTW89_MEXICO][35] = 30, + [0][1][RTW89_UKRAINE][35] = 10, + [0][1][RTW89_CHILE][35] = 30, + [0][1][RTW89_QATAR][35] = 16, + [0][1][RTW89_THAILAND][35] = 16, + [0][1][RTW89_FCC][37] = 34, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 44, + [0][1][RTW89_IC][37] = 34, + [0][1][RTW89_KCC][37] = 28, + [0][1][RTW89_ACMA][37] = 34, + [0][1][RTW89_CN][37] = 127, + [0][1][RTW89_UK][37] = 18, + [0][1][RTW89_MEXICO][37] = 34, + [0][1][RTW89_UKRAINE][37] = 127, + [0][1][RTW89_CHILE][37] = 34, + [0][1][RTW89_QATAR][37] = 127, + [0][1][RTW89_THAILAND][37] = 127, + [0][1][RTW89_FCC][38] = 62, + [0][1][RTW89_ETSI][38] = 16, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 62, + [0][1][RTW89_KCC][38] = 30, + [0][1][RTW89_ACMA][38] = 62, + [0][1][RTW89_CN][38] = 42, + [0][1][RTW89_UK][38] = 18, + [0][1][RTW89_MEXICO][38] = 62, + [0][1][RTW89_UKRAINE][38] = 14, + [0][1][RTW89_CHILE][38] = 62, + [0][1][RTW89_QATAR][38] = 14, + [0][1][RTW89_THAILAND][38] = 16, + [0][1][RTW89_FCC][40] = 62, + [0][1][RTW89_ETSI][40] = 16, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 62, + [0][1][RTW89_KCC][40] = 30, + [0][1][RTW89_ACMA][40] = 62, + [0][1][RTW89_CN][40] = 42, + [0][1][RTW89_UK][40] = 18, + [0][1][RTW89_MEXICO][40] = 62, + [0][1][RTW89_UKRAINE][40] = 14, + [0][1][RTW89_CHILE][40] = 62, + [0][1][RTW89_QATAR][40] = 14, + [0][1][RTW89_THAILAND][40] = 16, + [0][1][RTW89_FCC][42] = 58, + [0][1][RTW89_ETSI][42] = 16, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 58, + [0][1][RTW89_KCC][42] = 30, + [0][1][RTW89_ACMA][42] = 58, + [0][1][RTW89_CN][42] = 42, + [0][1][RTW89_UK][42] = 18, + [0][1][RTW89_MEXICO][42] = 58, + [0][1][RTW89_UKRAINE][42] = 14, + [0][1][RTW89_CHILE][42] = 58, + [0][1][RTW89_QATAR][42] = 14, + [0][1][RTW89_THAILAND][42] = 16, + [0][1][RTW89_FCC][44] = 56, + [0][1][RTW89_ETSI][44] = 16, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 56, + [0][1][RTW89_KCC][44] = 30, + [0][1][RTW89_ACMA][44] = 56, + [0][1][RTW89_CN][44] = 42, + [0][1][RTW89_UK][44] = 18, + [0][1][RTW89_MEXICO][44] = 56, + [0][1][RTW89_UKRAINE][44] = 14, + [0][1][RTW89_CHILE][44] = 56, + [0][1][RTW89_QATAR][44] = 14, + [0][1][RTW89_THAILAND][44] = 16, + [0][1][RTW89_FCC][46] = 56, + [0][1][RTW89_ETSI][46] = 16, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 56, + [0][1][RTW89_KCC][46] = 30, + [0][1][RTW89_ACMA][46] = 56, + [0][1][RTW89_CN][46] = 42, + [0][1][RTW89_UK][46] = 18, + [0][1][RTW89_MEXICO][46] = 56, + [0][1][RTW89_UKRAINE][46] = 14, + [0][1][RTW89_CHILE][46] = 56, + [0][1][RTW89_QATAR][46] = 14, + [0][1][RTW89_THAILAND][46] = 16, + [0][1][RTW89_FCC][48] = 20, + [0][1][RTW89_ETSI][48] = 127, + [0][1][RTW89_MKK][48] = 127, + [0][1][RTW89_IC][48] = 20, + [0][1][RTW89_KCC][48] = 127, + [0][1][RTW89_ACMA][48] = 127, + [0][1][RTW89_CN][48] = 127, + [0][1][RTW89_UK][48] = 127, + [0][1][RTW89_MEXICO][48] = 127, + [0][1][RTW89_UKRAINE][48] = 127, + [0][1][RTW89_CHILE][48] = 127, + [0][1][RTW89_QATAR][48] = 127, + [0][1][RTW89_THAILAND][48] = 127, + [0][1][RTW89_FCC][50] = 20, + [0][1][RTW89_ETSI][50] = 127, + [0][1][RTW89_MKK][50] = 127, + [0][1][RTW89_IC][50] = 20, + [0][1][RTW89_KCC][50] = 127, + [0][1][RTW89_ACMA][50] = 127, + [0][1][RTW89_CN][50] = 127, + [0][1][RTW89_UK][50] = 127, + [0][1][RTW89_MEXICO][50] = 127, + [0][1][RTW89_UKRAINE][50] = 127, + [0][1][RTW89_CHILE][50] = 127, + [0][1][RTW89_QATAR][50] = 127, + [0][1][RTW89_THAILAND][50] = 127, + [0][1][RTW89_FCC][52] = 8, + [0][1][RTW89_ETSI][52] = 127, + [0][1][RTW89_MKK][52] = 127, + [0][1][RTW89_IC][52] = 8, + [0][1][RTW89_KCC][52] = 127, + [0][1][RTW89_ACMA][52] = 127, + [0][1][RTW89_CN][52] = 127, + [0][1][RTW89_UK][52] = 127, + [0][1][RTW89_MEXICO][52] = 127, + [0][1][RTW89_UKRAINE][52] = 127, + [0][1][RTW89_CHILE][52] = 127, + [0][1][RTW89_QATAR][52] = 127, + [0][1][RTW89_THAILAND][52] = 127, + [1][0][RTW89_FCC][0] = 62, + [1][0][RTW89_ETSI][0] = 40, + [1][0][RTW89_MKK][0] = 48, + [1][0][RTW89_IC][0] = 42, + [1][0][RTW89_KCC][0] = 54, + [1][0][RTW89_ACMA][0] = 40, + [1][0][RTW89_CN][0] = 26, + [1][0][RTW89_UK][0] = 40, + [1][0][RTW89_MEXICO][0] = 62, + [1][0][RTW89_UKRAINE][0] = 32, + [1][0][RTW89_CHILE][0] = 62, + [1][0][RTW89_QATAR][0] = 40, + [1][0][RTW89_THAILAND][0] = 40, + [1][0][RTW89_FCC][2] = 62, + [1][0][RTW89_ETSI][2] = 40, + [1][0][RTW89_MKK][2] = 48, + [1][0][RTW89_IC][2] = 42, + [1][0][RTW89_KCC][2] = 54, + [1][0][RTW89_ACMA][2] = 40, + [1][0][RTW89_CN][2] = 26, + [1][0][RTW89_UK][2] = 40, + [1][0][RTW89_MEXICO][2] = 62, + [1][0][RTW89_UKRAINE][2] = 32, + [1][0][RTW89_CHILE][2] = 62, + [1][0][RTW89_QATAR][2] = 40, + [1][0][RTW89_THAILAND][2] = 40, + [1][0][RTW89_FCC][4] = 64, + [1][0][RTW89_ETSI][4] = 40, + [1][0][RTW89_MKK][4] = 40, + [1][0][RTW89_IC][4] = 42, + [1][0][RTW89_KCC][4] = 54, + [1][0][RTW89_ACMA][4] = 40, + [1][0][RTW89_CN][4] = 26, + [1][0][RTW89_UK][4] = 40, + [1][0][RTW89_MEXICO][4] = 64, + [1][0][RTW89_UKRAINE][4] = 32, + [1][0][RTW89_CHILE][4] = 64, + [1][0][RTW89_QATAR][4] = 40, + [1][0][RTW89_THAILAND][4] = 40, + [1][0][RTW89_FCC][6] = 64, + [1][0][RTW89_ETSI][6] = 40, + [1][0][RTW89_MKK][6] = 40, + [1][0][RTW89_IC][6] = 42, + [1][0][RTW89_KCC][6] = 32, + [1][0][RTW89_ACMA][6] = 40, + [1][0][RTW89_CN][6] = 26, + [1][0][RTW89_UK][6] = 40, + [1][0][RTW89_MEXICO][6] = 64, + [1][0][RTW89_UKRAINE][6] = 32, + [1][0][RTW89_CHILE][6] = 64, + [1][0][RTW89_QATAR][6] = 40, + [1][0][RTW89_THAILAND][6] = 40, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 40, + [1][0][RTW89_MKK][8] = 34, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_KCC][8] = 50, + [1][0][RTW89_ACMA][8] = 40, + [1][0][RTW89_CN][8] = 26, + [1][0][RTW89_UK][8] = 40, + [1][0][RTW89_MEXICO][8] = 62, + [1][0][RTW89_UKRAINE][8] = 32, + [1][0][RTW89_CHILE][8] = 62, + [1][0][RTW89_QATAR][8] = 40, + [1][0][RTW89_THAILAND][8] = 40, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 40, + [1][0][RTW89_MKK][10] = 34, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_KCC][10] = 50, + [1][0][RTW89_ACMA][10] = 40, + [1][0][RTW89_CN][10] = 26, + [1][0][RTW89_UK][10] = 40, + [1][0][RTW89_MEXICO][10] = 62, + [1][0][RTW89_UKRAINE][10] = 32, + [1][0][RTW89_CHILE][10] = 62, + [1][0][RTW89_QATAR][10] = 40, + [1][0][RTW89_THAILAND][10] = 40, + [1][0][RTW89_FCC][12] = 62, + [1][0][RTW89_ETSI][12] = 40, + [1][0][RTW89_MKK][12] = 46, + [1][0][RTW89_IC][12] = 62, + [1][0][RTW89_KCC][12] = 50, + [1][0][RTW89_ACMA][12] = 40, + [1][0][RTW89_CN][12] = 26, + [1][0][RTW89_UK][12] = 40, + [1][0][RTW89_MEXICO][12] = 62, + [1][0][RTW89_UKRAINE][12] = 32, + [1][0][RTW89_CHILE][12] = 62, + [1][0][RTW89_QATAR][12] = 40, + [1][0][RTW89_THAILAND][12] = 40, + [1][0][RTW89_FCC][14] = 62, + [1][0][RTW89_ETSI][14] = 40, + [1][0][RTW89_MKK][14] = 46, + [1][0][RTW89_IC][14] = 62, + [1][0][RTW89_KCC][14] = 50, + [1][0][RTW89_ACMA][14] = 40, + [1][0][RTW89_CN][14] = 26, + [1][0][RTW89_UK][14] = 40, + [1][0][RTW89_MEXICO][14] = 62, + [1][0][RTW89_UKRAINE][14] = 32, + [1][0][RTW89_CHILE][14] = 62, + [1][0][RTW89_QATAR][14] = 40, + [1][0][RTW89_THAILAND][14] = 40, + [1][0][RTW89_FCC][15] = 62, + [1][0][RTW89_ETSI][15] = 40, + [1][0][RTW89_MKK][15] = 62, + [1][0][RTW89_IC][15] = 62, + [1][0][RTW89_KCC][15] = 52, + [1][0][RTW89_ACMA][15] = 40, + [1][0][RTW89_CN][15] = 127, + [1][0][RTW89_UK][15] = 40, + [1][0][RTW89_MEXICO][15] = 62, + [1][0][RTW89_UKRAINE][15] = 32, + [1][0][RTW89_CHILE][15] = 62, + [1][0][RTW89_QATAR][15] = 40, + [1][0][RTW89_THAILAND][15] = 40, + [1][0][RTW89_FCC][17] = 62, + [1][0][RTW89_ETSI][17] = 40, + [1][0][RTW89_MKK][17] = 68, + [1][0][RTW89_IC][17] = 62, + [1][0][RTW89_KCC][17] = 52, + [1][0][RTW89_ACMA][17] = 40, + [1][0][RTW89_CN][17] = 127, + [1][0][RTW89_UK][17] = 40, + [1][0][RTW89_MEXICO][17] = 62, + [1][0][RTW89_UKRAINE][17] = 32, + [1][0][RTW89_CHILE][17] = 62, + [1][0][RTW89_QATAR][17] = 40, + [1][0][RTW89_THAILAND][17] = 40, + [1][0][RTW89_FCC][19] = 64, + [1][0][RTW89_ETSI][19] = 40, + [1][0][RTW89_MKK][19] = 68, + [1][0][RTW89_IC][19] = 64, + [1][0][RTW89_KCC][19] = 52, + [1][0][RTW89_ACMA][19] = 40, + [1][0][RTW89_CN][19] = 127, + [1][0][RTW89_UK][19] = 40, + [1][0][RTW89_MEXICO][19] = 64, + [1][0][RTW89_UKRAINE][19] = 32, + [1][0][RTW89_CHILE][19] = 64, + [1][0][RTW89_QATAR][19] = 40, + [1][0][RTW89_THAILAND][19] = 40, + [1][0][RTW89_FCC][21] = 64, + [1][0][RTW89_ETSI][21] = 40, + [1][0][RTW89_MKK][21] = 68, + [1][0][RTW89_IC][21] = 64, + [1][0][RTW89_KCC][21] = 52, + [1][0][RTW89_ACMA][21] = 40, + [1][0][RTW89_CN][21] = 127, + [1][0][RTW89_UK][21] = 40, + [1][0][RTW89_MEXICO][21] = 64, + [1][0][RTW89_UKRAINE][21] = 32, + [1][0][RTW89_CHILE][21] = 64, + [1][0][RTW89_QATAR][21] = 40, + [1][0][RTW89_THAILAND][21] = 40, + [1][0][RTW89_FCC][23] = 64, + [1][0][RTW89_ETSI][23] = 40, + [1][0][RTW89_MKK][23] = 68, + [1][0][RTW89_IC][23] = 64, + [1][0][RTW89_KCC][23] = 52, + [1][0][RTW89_ACMA][23] = 40, + [1][0][RTW89_CN][23] = 127, + [1][0][RTW89_UK][23] = 40, + [1][0][RTW89_MEXICO][23] = 64, + [1][0][RTW89_UKRAINE][23] = 32, + [1][0][RTW89_CHILE][23] = 64, + [1][0][RTW89_QATAR][23] = 40, + [1][0][RTW89_THAILAND][23] = 40, + [1][0][RTW89_FCC][25] = 64, + [1][0][RTW89_ETSI][25] = 40, + [1][0][RTW89_MKK][25] = 68, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_KCC][25] = 52, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_CN][25] = 127, + [1][0][RTW89_UK][25] = 40, + [1][0][RTW89_MEXICO][25] = 64, + [1][0][RTW89_UKRAINE][25] = 32, + [1][0][RTW89_CHILE][25] = 64, + [1][0][RTW89_QATAR][25] = 40, + [1][0][RTW89_THAILAND][25] = 40, + [1][0][RTW89_FCC][27] = 64, + [1][0][RTW89_ETSI][27] = 42, + [1][0][RTW89_MKK][27] = 68, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_KCC][27] = 52, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_CN][27] = 127, + [1][0][RTW89_UK][27] = 42, + [1][0][RTW89_MEXICO][27] = 64, + [1][0][RTW89_UKRAINE][27] = 32, + [1][0][RTW89_CHILE][27] = 64, + [1][0][RTW89_QATAR][27] = 42, + [1][0][RTW89_THAILAND][27] = 42, + [1][0][RTW89_FCC][29] = 64, + [1][0][RTW89_ETSI][29] = 42, + [1][0][RTW89_MKK][29] = 68, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_KCC][29] = 52, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_CN][29] = 127, + [1][0][RTW89_UK][29] = 42, + [1][0][RTW89_MEXICO][29] = 64, + [1][0][RTW89_UKRAINE][29] = 32, + [1][0][RTW89_CHILE][29] = 64, + [1][0][RTW89_QATAR][29] = 42, + [1][0][RTW89_THAILAND][29] = 42, + [1][0][RTW89_FCC][31] = 64, + [1][0][RTW89_ETSI][31] = 42, + [1][0][RTW89_MKK][31] = 68, + [1][0][RTW89_IC][31] = 56, + [1][0][RTW89_KCC][31] = 50, + [1][0][RTW89_ACMA][31] = 42, + [1][0][RTW89_CN][31] = 127, + [1][0][RTW89_UK][31] = 42, + [1][0][RTW89_MEXICO][31] = 64, + [1][0][RTW89_UKRAINE][31] = 32, + [1][0][RTW89_CHILE][31] = 64, + [1][0][RTW89_QATAR][31] = 42, + [1][0][RTW89_THAILAND][31] = 42, + [1][0][RTW89_FCC][33] = 56, + [1][0][RTW89_ETSI][33] = 42, + [1][0][RTW89_MKK][33] = 68, + [1][0][RTW89_IC][33] = 56, + [1][0][RTW89_KCC][33] = 50, + [1][0][RTW89_ACMA][33] = 42, + [1][0][RTW89_CN][33] = 127, + [1][0][RTW89_UK][33] = 42, + [1][0][RTW89_MEXICO][33] = 56, + [1][0][RTW89_UKRAINE][33] = 32, + [1][0][RTW89_CHILE][33] = 56, + [1][0][RTW89_QATAR][33] = 42, + [1][0][RTW89_THAILAND][33] = 42, + [1][0][RTW89_FCC][35] = 56, + [1][0][RTW89_ETSI][35] = 42, + [1][0][RTW89_MKK][35] = 68, + [1][0][RTW89_IC][35] = 56, + [1][0][RTW89_KCC][35] = 50, + [1][0][RTW89_ACMA][35] = 42, + [1][0][RTW89_CN][35] = 127, + [1][0][RTW89_UK][35] = 42, + [1][0][RTW89_MEXICO][35] = 56, + [1][0][RTW89_UKRAINE][35] = 32, + [1][0][RTW89_CHILE][35] = 56, + [1][0][RTW89_QATAR][35] = 42, + [1][0][RTW89_THAILAND][35] = 42, + [1][0][RTW89_FCC][37] = 66, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 68, + [1][0][RTW89_IC][37] = 66, + [1][0][RTW89_KCC][37] = 50, + [1][0][RTW89_ACMA][37] = 66, + [1][0][RTW89_CN][37] = 127, + [1][0][RTW89_UK][37] = 42, + [1][0][RTW89_MEXICO][37] = 66, + [1][0][RTW89_UKRAINE][37] = 127, + [1][0][RTW89_CHILE][37] = 66, + [1][0][RTW89_QATAR][37] = 127, + [1][0][RTW89_THAILAND][37] = 127, + [1][0][RTW89_FCC][38] = 76, + [1][0][RTW89_ETSI][38] = 28, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 76, + [1][0][RTW89_KCC][38] = 54, + [1][0][RTW89_ACMA][38] = 76, + [1][0][RTW89_CN][38] = 56, + [1][0][RTW89_UK][38] = 44, + [1][0][RTW89_MEXICO][38] = 76, + [1][0][RTW89_UKRAINE][38] = 26, + [1][0][RTW89_CHILE][38] = 76, + [1][0][RTW89_QATAR][38] = 26, + [1][0][RTW89_THAILAND][38] = 28, + [1][0][RTW89_FCC][40] = 76, + [1][0][RTW89_ETSI][40] = 28, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 76, + [1][0][RTW89_KCC][40] = 54, + [1][0][RTW89_ACMA][40] = 76, + [1][0][RTW89_CN][40] = 56, + [1][0][RTW89_UK][40] = 44, + [1][0][RTW89_MEXICO][40] = 76, + [1][0][RTW89_UKRAINE][40] = 26, + [1][0][RTW89_CHILE][40] = 76, + [1][0][RTW89_QATAR][40] = 26, + [1][0][RTW89_THAILAND][40] = 28, + [1][0][RTW89_FCC][42] = 68, + [1][0][RTW89_ETSI][42] = 28, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 68, + [1][0][RTW89_KCC][42] = 54, + [1][0][RTW89_ACMA][42] = 68, + [1][0][RTW89_CN][42] = 56, + [1][0][RTW89_UK][42] = 44, + [1][0][RTW89_MEXICO][42] = 68, + [1][0][RTW89_UKRAINE][42] = 26, + [1][0][RTW89_CHILE][42] = 68, + [1][0][RTW89_QATAR][42] = 26, + [1][0][RTW89_THAILAND][42] = 28, + [1][0][RTW89_FCC][44] = 70, + [1][0][RTW89_ETSI][44] = 28, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 70, + [1][0][RTW89_KCC][44] = 54, + [1][0][RTW89_ACMA][44] = 70, + [1][0][RTW89_CN][44] = 56, + [1][0][RTW89_UK][44] = 42, + [1][0][RTW89_MEXICO][44] = 70, + [1][0][RTW89_UKRAINE][44] = 26, + [1][0][RTW89_CHILE][44] = 70, + [1][0][RTW89_QATAR][44] = 26, + [1][0][RTW89_THAILAND][44] = 28, + [1][0][RTW89_FCC][46] = 70, + [1][0][RTW89_ETSI][46] = 28, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 70, + [1][0][RTW89_KCC][46] = 54, + [1][0][RTW89_ACMA][46] = 70, + [1][0][RTW89_CN][46] = 56, + [1][0][RTW89_UK][46] = 42, + [1][0][RTW89_MEXICO][46] = 70, + [1][0][RTW89_UKRAINE][46] = 26, + [1][0][RTW89_CHILE][46] = 70, + [1][0][RTW89_QATAR][46] = 26, + [1][0][RTW89_THAILAND][46] = 28, + [1][0][RTW89_FCC][48] = 56, + [1][0][RTW89_ETSI][48] = 127, + [1][0][RTW89_MKK][48] = 127, + [1][0][RTW89_IC][48] = 56, + [1][0][RTW89_KCC][48] = 127, + [1][0][RTW89_ACMA][48] = 127, + [1][0][RTW89_CN][48] = 127, + [1][0][RTW89_UK][48] = 127, + [1][0][RTW89_MEXICO][48] = 127, + [1][0][RTW89_UKRAINE][48] = 127, + [1][0][RTW89_CHILE][48] = 127, + [1][0][RTW89_QATAR][48] = 127, + [1][0][RTW89_THAILAND][48] = 127, + [1][0][RTW89_FCC][50] = 58, + [1][0][RTW89_ETSI][50] = 127, + [1][0][RTW89_MKK][50] = 127, + [1][0][RTW89_IC][50] = 58, + [1][0][RTW89_KCC][50] = 127, + [1][0][RTW89_ACMA][50] = 127, + [1][0][RTW89_CN][50] = 127, + [1][0][RTW89_UK][50] = 127, + [1][0][RTW89_MEXICO][50] = 127, + [1][0][RTW89_UKRAINE][50] = 127, + [1][0][RTW89_CHILE][50] = 127, + [1][0][RTW89_QATAR][50] = 127, + [1][0][RTW89_THAILAND][50] = 127, + [1][0][RTW89_FCC][52] = 56, + [1][0][RTW89_ETSI][52] = 127, + [1][0][RTW89_MKK][52] = 127, + [1][0][RTW89_IC][52] = 56, + [1][0][RTW89_KCC][52] = 127, + [1][0][RTW89_ACMA][52] = 127, + [1][0][RTW89_CN][52] = 127, + [1][0][RTW89_UK][52] = 127, + [1][0][RTW89_MEXICO][52] = 127, + [1][0][RTW89_UKRAINE][52] = 127, + [1][0][RTW89_CHILE][52] = 127, + [1][0][RTW89_QATAR][52] = 127, + [1][0][RTW89_THAILAND][52] = 127, + [1][1][RTW89_FCC][0] = 44, + [1][1][RTW89_ETSI][0] = 30, + [1][1][RTW89_MKK][0] = 34, + [1][1][RTW89_IC][0] = 20, + [1][1][RTW89_KCC][0] = 40, + [1][1][RTW89_ACMA][0] = 30, + [1][1][RTW89_CN][0] = 14, + [1][1][RTW89_UK][0] = 30, + [1][1][RTW89_MEXICO][0] = 44, + [1][1][RTW89_UKRAINE][0] = 20, + [1][1][RTW89_CHILE][0] = 44, + [1][1][RTW89_QATAR][0] = 30, + [1][1][RTW89_THAILAND][0] = 30, + [1][1][RTW89_FCC][2] = 44, + [1][1][RTW89_ETSI][2] = 30, + [1][1][RTW89_MKK][2] = 34, + [1][1][RTW89_IC][2] = 18, + [1][1][RTW89_KCC][2] = 40, + [1][1][RTW89_ACMA][2] = 30, + [1][1][RTW89_CN][2] = 14, + [1][1][RTW89_UK][2] = 30, + [1][1][RTW89_MEXICO][2] = 44, + [1][1][RTW89_UKRAINE][2] = 20, + [1][1][RTW89_CHILE][2] = 44, + [1][1][RTW89_QATAR][2] = 30, + [1][1][RTW89_THAILAND][2] = 30, + [1][1][RTW89_FCC][4] = 46, + [1][1][RTW89_ETSI][4] = 30, + [1][1][RTW89_MKK][4] = 26, + [1][1][RTW89_IC][4] = 20, + [1][1][RTW89_KCC][4] = 40, + [1][1][RTW89_ACMA][4] = 30, + [1][1][RTW89_CN][4] = 14, + [1][1][RTW89_UK][4] = 30, + [1][1][RTW89_MEXICO][4] = 46, + [1][1][RTW89_UKRAINE][4] = 20, + [1][1][RTW89_CHILE][4] = 46, + [1][1][RTW89_QATAR][4] = 30, + [1][1][RTW89_THAILAND][4] = 30, + [1][1][RTW89_FCC][6] = 46, + [1][1][RTW89_ETSI][6] = 30, + [1][1][RTW89_MKK][6] = 26, + [1][1][RTW89_IC][6] = 20, + [1][1][RTW89_KCC][6] = 18, + [1][1][RTW89_ACMA][6] = 30, + [1][1][RTW89_CN][6] = 14, + [1][1][RTW89_UK][6] = 30, + [1][1][RTW89_MEXICO][6] = 46, + [1][1][RTW89_UKRAINE][6] = 20, + [1][1][RTW89_CHILE][6] = 46, + [1][1][RTW89_QATAR][6] = 30, + [1][1][RTW89_THAILAND][6] = 30, + [1][1][RTW89_FCC][8] = 44, + [1][1][RTW89_ETSI][8] = 30, + [1][1][RTW89_MKK][8] = 20, + [1][1][RTW89_IC][8] = 44, + [1][1][RTW89_KCC][8] = 38, + [1][1][RTW89_ACMA][8] = 30, + [1][1][RTW89_CN][8] = 14, + [1][1][RTW89_UK][8] = 30, + [1][1][RTW89_MEXICO][8] = 44, + [1][1][RTW89_UKRAINE][8] = 20, + [1][1][RTW89_CHILE][8] = 44, + [1][1][RTW89_QATAR][8] = 30, + [1][1][RTW89_THAILAND][8] = 30, + [1][1][RTW89_FCC][10] = 44, + [1][1][RTW89_ETSI][10] = 30, + [1][1][RTW89_MKK][10] = 20, + [1][1][RTW89_IC][10] = 44, + [1][1][RTW89_KCC][10] = 38, + [1][1][RTW89_ACMA][10] = 30, + [1][1][RTW89_CN][10] = 14, + [1][1][RTW89_UK][10] = 30, + [1][1][RTW89_MEXICO][10] = 44, + [1][1][RTW89_UKRAINE][10] = 20, + [1][1][RTW89_CHILE][10] = 44, + [1][1][RTW89_QATAR][10] = 30, + [1][1][RTW89_THAILAND][10] = 30, + [1][1][RTW89_FCC][12] = 44, + [1][1][RTW89_ETSI][12] = 30, + [1][1][RTW89_MKK][12] = 34, + [1][1][RTW89_IC][12] = 44, + [1][1][RTW89_KCC][12] = 38, + [1][1][RTW89_ACMA][12] = 30, + [1][1][RTW89_CN][12] = 14, + [1][1][RTW89_UK][12] = 30, + [1][1][RTW89_MEXICO][12] = 44, + [1][1][RTW89_UKRAINE][12] = 20, + [1][1][RTW89_CHILE][12] = 44, + [1][1][RTW89_QATAR][12] = 30, + [1][1][RTW89_THAILAND][12] = 30, + [1][1][RTW89_FCC][14] = 44, + [1][1][RTW89_ETSI][14] = 30, + [1][1][RTW89_MKK][14] = 34, + [1][1][RTW89_IC][14] = 44, + [1][1][RTW89_KCC][14] = 38, + [1][1][RTW89_ACMA][14] = 30, + [1][1][RTW89_CN][14] = 14, + [1][1][RTW89_UK][14] = 30, + [1][1][RTW89_MEXICO][14] = 44, + [1][1][RTW89_UKRAINE][14] = 20, + [1][1][RTW89_CHILE][14] = 44, + [1][1][RTW89_QATAR][14] = 30, + [1][1][RTW89_THAILAND][14] = 30, + [1][1][RTW89_FCC][15] = 44, + [1][1][RTW89_ETSI][15] = 28, + [1][1][RTW89_MKK][15] = 56, + [1][1][RTW89_IC][15] = 44, + [1][1][RTW89_KCC][15] = 38, + [1][1][RTW89_ACMA][15] = 28, + [1][1][RTW89_CN][15] = 127, + [1][1][RTW89_UK][15] = 28, + [1][1][RTW89_MEXICO][15] = 44, + [1][1][RTW89_UKRAINE][15] = 20, + [1][1][RTW89_CHILE][15] = 44, + [1][1][RTW89_QATAR][15] = 28, + [1][1][RTW89_THAILAND][15] = 28, + [1][1][RTW89_FCC][17] = 44, + [1][1][RTW89_ETSI][17] = 28, + [1][1][RTW89_MKK][17] = 58, + [1][1][RTW89_IC][17] = 44, + [1][1][RTW89_KCC][17] = 38, + [1][1][RTW89_ACMA][17] = 28, + [1][1][RTW89_CN][17] = 127, + [1][1][RTW89_UK][17] = 28, + [1][1][RTW89_MEXICO][17] = 44, + [1][1][RTW89_UKRAINE][17] = 20, + [1][1][RTW89_CHILE][17] = 44, + [1][1][RTW89_QATAR][17] = 28, + [1][1][RTW89_THAILAND][17] = 28, + [1][1][RTW89_FCC][19] = 44, + [1][1][RTW89_ETSI][19] = 28, + [1][1][RTW89_MKK][19] = 58, + [1][1][RTW89_IC][19] = 44, + [1][1][RTW89_KCC][19] = 38, + [1][1][RTW89_ACMA][19] = 28, + [1][1][RTW89_CN][19] = 127, + [1][1][RTW89_UK][19] = 28, + [1][1][RTW89_MEXICO][19] = 44, + [1][1][RTW89_UKRAINE][19] = 20, + [1][1][RTW89_CHILE][19] = 44, + [1][1][RTW89_QATAR][19] = 28, + [1][1][RTW89_THAILAND][19] = 28, + [1][1][RTW89_FCC][21] = 44, + [1][1][RTW89_ETSI][21] = 28, + [1][1][RTW89_MKK][21] = 58, + [1][1][RTW89_IC][21] = 44, + [1][1][RTW89_KCC][21] = 38, + [1][1][RTW89_ACMA][21] = 28, + [1][1][RTW89_CN][21] = 127, + [1][1][RTW89_UK][21] = 28, + [1][1][RTW89_MEXICO][21] = 44, + [1][1][RTW89_UKRAINE][21] = 20, + [1][1][RTW89_CHILE][21] = 44, + [1][1][RTW89_QATAR][21] = 28, + [1][1][RTW89_THAILAND][21] = 28, + [1][1][RTW89_FCC][23] = 44, + [1][1][RTW89_ETSI][23] = 28, + [1][1][RTW89_MKK][23] = 58, + [1][1][RTW89_IC][23] = 44, + [1][1][RTW89_KCC][23] = 38, + [1][1][RTW89_ACMA][23] = 28, + [1][1][RTW89_CN][23] = 127, + [1][1][RTW89_UK][23] = 28, + [1][1][RTW89_MEXICO][23] = 44, + [1][1][RTW89_UKRAINE][23] = 20, + [1][1][RTW89_CHILE][23] = 44, + [1][1][RTW89_QATAR][23] = 28, + [1][1][RTW89_THAILAND][23] = 28, + [1][1][RTW89_FCC][25] = 44, + [1][1][RTW89_ETSI][25] = 28, + [1][1][RTW89_MKK][25] = 58, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_KCC][25] = 38, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_CN][25] = 127, + [1][1][RTW89_UK][25] = 28, + [1][1][RTW89_MEXICO][25] = 44, + [1][1][RTW89_UKRAINE][25] = 20, + [1][1][RTW89_CHILE][25] = 44, + [1][1][RTW89_QATAR][25] = 28, + [1][1][RTW89_THAILAND][25] = 28, + [1][1][RTW89_FCC][27] = 44, + [1][1][RTW89_ETSI][27] = 30, + [1][1][RTW89_MKK][27] = 58, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_KCC][27] = 38, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_CN][27] = 127, + [1][1][RTW89_UK][27] = 30, + [1][1][RTW89_MEXICO][27] = 44, + [1][1][RTW89_UKRAINE][27] = 20, + [1][1][RTW89_CHILE][27] = 44, + [1][1][RTW89_QATAR][27] = 30, + [1][1][RTW89_THAILAND][27] = 30, + [1][1][RTW89_FCC][29] = 44, + [1][1][RTW89_ETSI][29] = 30, + [1][1][RTW89_MKK][29] = 58, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_KCC][29] = 38, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_CN][29] = 127, + [1][1][RTW89_UK][29] = 30, + [1][1][RTW89_MEXICO][29] = 44, + [1][1][RTW89_UKRAINE][29] = 20, + [1][1][RTW89_CHILE][29] = 44, + [1][1][RTW89_QATAR][29] = 30, + [1][1][RTW89_THAILAND][29] = 30, + [1][1][RTW89_FCC][31] = 44, + [1][1][RTW89_ETSI][31] = 30, + [1][1][RTW89_MKK][31] = 58, + [1][1][RTW89_IC][31] = 38, + [1][1][RTW89_KCC][31] = 40, + [1][1][RTW89_ACMA][31] = 30, + [1][1][RTW89_CN][31] = 127, + [1][1][RTW89_UK][31] = 30, + [1][1][RTW89_MEXICO][31] = 44, + [1][1][RTW89_UKRAINE][31] = 20, + [1][1][RTW89_CHILE][31] = 44, + [1][1][RTW89_QATAR][31] = 30, + [1][1][RTW89_THAILAND][31] = 30, + [1][1][RTW89_FCC][33] = 38, + [1][1][RTW89_ETSI][33] = 30, + [1][1][RTW89_MKK][33] = 58, + [1][1][RTW89_IC][33] = 38, + [1][1][RTW89_KCC][33] = 40, + [1][1][RTW89_ACMA][33] = 30, + [1][1][RTW89_CN][33] = 127, + [1][1][RTW89_UK][33] = 30, + [1][1][RTW89_MEXICO][33] = 38, + [1][1][RTW89_UKRAINE][33] = 20, + [1][1][RTW89_CHILE][33] = 38, + [1][1][RTW89_QATAR][33] = 30, + [1][1][RTW89_THAILAND][33] = 30, + [1][1][RTW89_FCC][35] = 38, + [1][1][RTW89_ETSI][35] = 30, + [1][1][RTW89_MKK][35] = 58, + [1][1][RTW89_IC][35] = 38, + [1][1][RTW89_KCC][35] = 40, + [1][1][RTW89_ACMA][35] = 30, + [1][1][RTW89_CN][35] = 127, + [1][1][RTW89_UK][35] = 30, + [1][1][RTW89_MEXICO][35] = 38, + [1][1][RTW89_UKRAINE][35] = 20, + [1][1][RTW89_CHILE][35] = 38, + [1][1][RTW89_QATAR][35] = 30, + [1][1][RTW89_THAILAND][35] = 30, + [1][1][RTW89_FCC][37] = 46, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 58, + [1][1][RTW89_IC][37] = 46, + [1][1][RTW89_KCC][37] = 40, + [1][1][RTW89_ACMA][37] = 46, + [1][1][RTW89_CN][37] = 127, + [1][1][RTW89_UK][37] = 32, + [1][1][RTW89_MEXICO][37] = 46, + [1][1][RTW89_UKRAINE][37] = 127, + [1][1][RTW89_CHILE][37] = 46, + [1][1][RTW89_QATAR][37] = 127, + [1][1][RTW89_THAILAND][37] = 127, + [1][1][RTW89_FCC][38] = 74, + [1][1][RTW89_ETSI][38] = 16, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 74, + [1][1][RTW89_KCC][38] = 38, + [1][1][RTW89_ACMA][38] = 74, + [1][1][RTW89_CN][38] = 54, + [1][1][RTW89_UK][38] = 30, + [1][1][RTW89_MEXICO][38] = 74, + [1][1][RTW89_UKRAINE][38] = 14, + [1][1][RTW89_CHILE][38] = 72, + [1][1][RTW89_QATAR][38] = 14, + [1][1][RTW89_THAILAND][38] = 16, + [1][1][RTW89_FCC][40] = 74, + [1][1][RTW89_ETSI][40] = 16, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 74, + [1][1][RTW89_KCC][40] = 38, + [1][1][RTW89_ACMA][40] = 74, + [1][1][RTW89_CN][40] = 54, + [1][1][RTW89_UK][40] = 30, + [1][1][RTW89_MEXICO][40] = 74, + [1][1][RTW89_UKRAINE][40] = 14, + [1][1][RTW89_CHILE][40] = 72, + [1][1][RTW89_QATAR][40] = 14, + [1][1][RTW89_THAILAND][40] = 16, + [1][1][RTW89_FCC][42] = 74, + [1][1][RTW89_ETSI][42] = 16, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 74, + [1][1][RTW89_KCC][42] = 38, + [1][1][RTW89_ACMA][42] = 74, + [1][1][RTW89_CN][42] = 54, + [1][1][RTW89_UK][42] = 30, + [1][1][RTW89_MEXICO][42] = 74, + [1][1][RTW89_UKRAINE][42] = 14, + [1][1][RTW89_CHILE][42] = 72, + [1][1][RTW89_QATAR][42] = 14, + [1][1][RTW89_THAILAND][42] = 16, + [1][1][RTW89_FCC][44] = 74, + [1][1][RTW89_ETSI][44] = 16, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 74, + [1][1][RTW89_KCC][44] = 38, + [1][1][RTW89_ACMA][44] = 74, + [1][1][RTW89_CN][44] = 54, + [1][1][RTW89_UK][44] = 30, + [1][1][RTW89_MEXICO][44] = 74, + [1][1][RTW89_UKRAINE][44] = 14, + [1][1][RTW89_CHILE][44] = 72, + [1][1][RTW89_QATAR][44] = 14, + [1][1][RTW89_THAILAND][44] = 16, + [1][1][RTW89_FCC][46] = 74, + [1][1][RTW89_ETSI][46] = 16, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 74, + [1][1][RTW89_KCC][46] = 38, + [1][1][RTW89_ACMA][46] = 74, + [1][1][RTW89_CN][46] = 54, + [1][1][RTW89_UK][46] = 30, + [1][1][RTW89_MEXICO][46] = 74, + [1][1][RTW89_UKRAINE][46] = 14, + [1][1][RTW89_CHILE][46] = 72, + [1][1][RTW89_QATAR][46] = 14, + [1][1][RTW89_THAILAND][46] = 16, + [1][1][RTW89_FCC][48] = 34, + [1][1][RTW89_ETSI][48] = 127, + [1][1][RTW89_MKK][48] = 127, + [1][1][RTW89_IC][48] = 34, + [1][1][RTW89_KCC][48] = 127, + [1][1][RTW89_ACMA][48] = 127, + [1][1][RTW89_CN][48] = 127, + [1][1][RTW89_UK][48] = 127, + [1][1][RTW89_MEXICO][48] = 127, + [1][1][RTW89_UKRAINE][48] = 127, + [1][1][RTW89_CHILE][48] = 127, + [1][1][RTW89_QATAR][48] = 127, + [1][1][RTW89_THAILAND][48] = 127, + [1][1][RTW89_FCC][50] = 34, + [1][1][RTW89_ETSI][50] = 127, + [1][1][RTW89_MKK][50] = 127, + [1][1][RTW89_IC][50] = 34, + [1][1][RTW89_KCC][50] = 127, + [1][1][RTW89_ACMA][50] = 127, + [1][1][RTW89_CN][50] = 127, + [1][1][RTW89_UK][50] = 127, + [1][1][RTW89_MEXICO][50] = 127, + [1][1][RTW89_UKRAINE][50] = 127, + [1][1][RTW89_CHILE][50] = 127, + [1][1][RTW89_QATAR][50] = 127, + [1][1][RTW89_THAILAND][50] = 127, + [1][1][RTW89_FCC][52] = 30, + [1][1][RTW89_ETSI][52] = 127, + [1][1][RTW89_MKK][52] = 127, + [1][1][RTW89_IC][52] = 30, + [1][1][RTW89_KCC][52] = 127, + [1][1][RTW89_ACMA][52] = 127, + [1][1][RTW89_CN][52] = 127, + [1][1][RTW89_UK][52] = 127, + [1][1][RTW89_MEXICO][52] = 127, + [1][1][RTW89_UKRAINE][52] = 127, + [1][1][RTW89_CHILE][52] = 127, + [1][1][RTW89_QATAR][52] = 127, + [1][1][RTW89_THAILAND][52] = 127, + [2][0][RTW89_FCC][0] = 68, + [2][0][RTW89_ETSI][0] = 52, + [2][0][RTW89_MKK][0] = 60, + [2][0][RTW89_IC][0] = 52, + [2][0][RTW89_KCC][0] = 60, + [2][0][RTW89_ACMA][0] = 52, + [2][0][RTW89_CN][0] = 40, + [2][0][RTW89_UK][0] = 52, + [2][0][RTW89_MEXICO][0] = 62, + [2][0][RTW89_UKRAINE][0] = 46, + [2][0][RTW89_CHILE][0] = 68, + [2][0][RTW89_QATAR][0] = 52, + [2][0][RTW89_THAILAND][0] = 52, + [2][0][RTW89_FCC][2] = 64, + [2][0][RTW89_ETSI][2] = 52, + [2][0][RTW89_MKK][2] = 60, + [2][0][RTW89_IC][2] = 50, + [2][0][RTW89_KCC][2] = 60, + [2][0][RTW89_ACMA][2] = 52, + [2][0][RTW89_CN][2] = 40, + [2][0][RTW89_UK][2] = 52, + [2][0][RTW89_MEXICO][2] = 62, + [2][0][RTW89_UKRAINE][2] = 46, + [2][0][RTW89_CHILE][2] = 64, + [2][0][RTW89_QATAR][2] = 52, + [2][0][RTW89_THAILAND][2] = 52, + [2][0][RTW89_FCC][4] = 68, + [2][0][RTW89_ETSI][4] = 52, + [2][0][RTW89_MKK][4] = 50, + [2][0][RTW89_IC][4] = 50, + [2][0][RTW89_KCC][4] = 60, + [2][0][RTW89_ACMA][4] = 52, + [2][0][RTW89_CN][4] = 40, + [2][0][RTW89_UK][4] = 52, + [2][0][RTW89_MEXICO][4] = 62, + [2][0][RTW89_UKRAINE][4] = 46, + [2][0][RTW89_CHILE][4] = 68, + [2][0][RTW89_QATAR][4] = 52, + [2][0][RTW89_THAILAND][4] = 52, + [2][0][RTW89_FCC][6] = 68, + [2][0][RTW89_ETSI][6] = 52, + [2][0][RTW89_MKK][6] = 50, + [2][0][RTW89_IC][6] = 50, + [2][0][RTW89_KCC][6] = 38, + [2][0][RTW89_ACMA][6] = 52, + [2][0][RTW89_CN][6] = 40, + [2][0][RTW89_UK][6] = 52, + [2][0][RTW89_MEXICO][6] = 62, + [2][0][RTW89_UKRAINE][6] = 46, + [2][0][RTW89_CHILE][6] = 68, + [2][0][RTW89_QATAR][6] = 52, + [2][0][RTW89_THAILAND][6] = 52, + [2][0][RTW89_FCC][8] = 68, + [2][0][RTW89_ETSI][8] = 52, + [2][0][RTW89_MKK][8] = 44, + [2][0][RTW89_IC][8] = 64, + [2][0][RTW89_KCC][8] = 56, + [2][0][RTW89_ACMA][8] = 52, + [2][0][RTW89_CN][8] = 40, + [2][0][RTW89_UK][8] = 52, + [2][0][RTW89_MEXICO][8] = 68, + [2][0][RTW89_UKRAINE][8] = 46, + [2][0][RTW89_CHILE][8] = 68, + [2][0][RTW89_QATAR][8] = 52, + [2][0][RTW89_THAILAND][8] = 52, + [2][0][RTW89_FCC][10] = 68, + [2][0][RTW89_ETSI][10] = 52, + [2][0][RTW89_MKK][10] = 44, + [2][0][RTW89_IC][10] = 64, + [2][0][RTW89_KCC][10] = 56, + [2][0][RTW89_ACMA][10] = 52, + [2][0][RTW89_CN][10] = 40, + [2][0][RTW89_UK][10] = 52, + [2][0][RTW89_MEXICO][10] = 68, + [2][0][RTW89_UKRAINE][10] = 46, + [2][0][RTW89_CHILE][10] = 68, + [2][0][RTW89_QATAR][10] = 52, + [2][0][RTW89_THAILAND][10] = 52, + [2][0][RTW89_FCC][12] = 68, + [2][0][RTW89_ETSI][12] = 52, + [2][0][RTW89_MKK][12] = 58, + [2][0][RTW89_IC][12] = 64, + [2][0][RTW89_KCC][12] = 58, + [2][0][RTW89_ACMA][12] = 52, + [2][0][RTW89_CN][12] = 40, + [2][0][RTW89_UK][12] = 52, + [2][0][RTW89_MEXICO][12] = 68, + [2][0][RTW89_UKRAINE][12] = 46, + [2][0][RTW89_CHILE][12] = 68, + [2][0][RTW89_QATAR][12] = 52, + [2][0][RTW89_THAILAND][12] = 52, + [2][0][RTW89_FCC][14] = 68, + [2][0][RTW89_ETSI][14] = 52, + [2][0][RTW89_MKK][14] = 58, + [2][0][RTW89_IC][14] = 64, + [2][0][RTW89_KCC][14] = 58, + [2][0][RTW89_ACMA][14] = 52, + [2][0][RTW89_CN][14] = 40, + [2][0][RTW89_UK][14] = 52, + [2][0][RTW89_MEXICO][14] = 68, + [2][0][RTW89_UKRAINE][14] = 46, + [2][0][RTW89_CHILE][14] = 68, + [2][0][RTW89_QATAR][14] = 52, + [2][0][RTW89_THAILAND][14] = 52, + [2][0][RTW89_FCC][15] = 68, + [2][0][RTW89_ETSI][15] = 52, + [2][0][RTW89_MKK][15] = 68, + [2][0][RTW89_IC][15] = 68, + [2][0][RTW89_KCC][15] = 58, + [2][0][RTW89_ACMA][15] = 52, + [2][0][RTW89_CN][15] = 127, + [2][0][RTW89_UK][15] = 52, + [2][0][RTW89_MEXICO][15] = 68, + [2][0][RTW89_UKRAINE][15] = 46, + [2][0][RTW89_CHILE][15] = 68, + [2][0][RTW89_QATAR][15] = 52, + [2][0][RTW89_THAILAND][15] = 52, + [2][0][RTW89_FCC][17] = 68, + [2][0][RTW89_ETSI][17] = 52, + [2][0][RTW89_MKK][17] = 74, + [2][0][RTW89_IC][17] = 68, + [2][0][RTW89_KCC][17] = 58, + [2][0][RTW89_ACMA][17] = 52, + [2][0][RTW89_CN][17] = 127, + [2][0][RTW89_UK][17] = 52, + [2][0][RTW89_MEXICO][17] = 68, + [2][0][RTW89_UKRAINE][17] = 46, + [2][0][RTW89_CHILE][17] = 68, + [2][0][RTW89_QATAR][17] = 52, + [2][0][RTW89_THAILAND][17] = 52, + [2][0][RTW89_FCC][19] = 70, + [2][0][RTW89_ETSI][19] = 52, + [2][0][RTW89_MKK][19] = 74, + [2][0][RTW89_IC][19] = 70, + [2][0][RTW89_KCC][19] = 58, + [2][0][RTW89_ACMA][19] = 52, + [2][0][RTW89_CN][19] = 127, + [2][0][RTW89_UK][19] = 52, + [2][0][RTW89_MEXICO][19] = 70, + [2][0][RTW89_UKRAINE][19] = 46, + [2][0][RTW89_CHILE][19] = 70, + [2][0][RTW89_QATAR][19] = 52, + [2][0][RTW89_THAILAND][19] = 52, + [2][0][RTW89_FCC][21] = 70, + [2][0][RTW89_ETSI][21] = 52, + [2][0][RTW89_MKK][21] = 74, + [2][0][RTW89_IC][21] = 70, + [2][0][RTW89_KCC][21] = 58, + [2][0][RTW89_ACMA][21] = 52, + [2][0][RTW89_CN][21] = 127, + [2][0][RTW89_UK][21] = 52, + [2][0][RTW89_MEXICO][21] = 70, + [2][0][RTW89_UKRAINE][21] = 46, + [2][0][RTW89_CHILE][21] = 70, + [2][0][RTW89_QATAR][21] = 52, + [2][0][RTW89_THAILAND][21] = 52, + [2][0][RTW89_FCC][23] = 70, + [2][0][RTW89_ETSI][23] = 52, + [2][0][RTW89_MKK][23] = 74, + [2][0][RTW89_IC][23] = 70, + [2][0][RTW89_KCC][23] = 58, + [2][0][RTW89_ACMA][23] = 52, + [2][0][RTW89_CN][23] = 127, + [2][0][RTW89_UK][23] = 52, + [2][0][RTW89_MEXICO][23] = 70, + [2][0][RTW89_UKRAINE][23] = 46, + [2][0][RTW89_CHILE][23] = 70, + [2][0][RTW89_QATAR][23] = 52, + [2][0][RTW89_THAILAND][23] = 52, + [2][0][RTW89_FCC][25] = 70, + [2][0][RTW89_ETSI][25] = 52, + [2][0][RTW89_MKK][25] = 74, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_KCC][25] = 58, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_CN][25] = 127, + [2][0][RTW89_UK][25] = 52, + [2][0][RTW89_MEXICO][25] = 70, + [2][0][RTW89_UKRAINE][25] = 46, + [2][0][RTW89_CHILE][25] = 70, + [2][0][RTW89_QATAR][25] = 52, + [2][0][RTW89_THAILAND][25] = 52, + [2][0][RTW89_FCC][27] = 70, + [2][0][RTW89_ETSI][27] = 52, + [2][0][RTW89_MKK][27] = 74, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_KCC][27] = 58, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_CN][27] = 127, + [2][0][RTW89_UK][27] = 52, + [2][0][RTW89_MEXICO][27] = 70, + [2][0][RTW89_UKRAINE][27] = 46, + [2][0][RTW89_CHILE][27] = 70, + [2][0][RTW89_QATAR][27] = 52, + [2][0][RTW89_THAILAND][27] = 52, + [2][0][RTW89_FCC][29] = 70, + [2][0][RTW89_ETSI][29] = 52, + [2][0][RTW89_MKK][29] = 74, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_KCC][29] = 58, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_CN][29] = 127, + [2][0][RTW89_UK][29] = 52, + [2][0][RTW89_MEXICO][29] = 70, + [2][0][RTW89_UKRAINE][29] = 46, + [2][0][RTW89_CHILE][29] = 70, + [2][0][RTW89_QATAR][29] = 52, + [2][0][RTW89_THAILAND][29] = 52, + [2][0][RTW89_FCC][31] = 70, + [2][0][RTW89_ETSI][31] = 52, + [2][0][RTW89_MKK][31] = 74, + [2][0][RTW89_IC][31] = 62, + [2][0][RTW89_KCC][31] = 56, + [2][0][RTW89_ACMA][31] = 52, + [2][0][RTW89_CN][31] = 127, + [2][0][RTW89_UK][31] = 52, + [2][0][RTW89_MEXICO][31] = 70, + [2][0][RTW89_UKRAINE][31] = 46, + [2][0][RTW89_CHILE][31] = 70, + [2][0][RTW89_QATAR][31] = 52, + [2][0][RTW89_THAILAND][31] = 52, + [2][0][RTW89_FCC][33] = 62, + [2][0][RTW89_ETSI][33] = 52, + [2][0][RTW89_MKK][33] = 74, + [2][0][RTW89_IC][33] = 62, + [2][0][RTW89_KCC][33] = 56, + [2][0][RTW89_ACMA][33] = 52, + [2][0][RTW89_CN][33] = 127, + [2][0][RTW89_UK][33] = 52, + [2][0][RTW89_MEXICO][33] = 62, + [2][0][RTW89_UKRAINE][33] = 46, + [2][0][RTW89_CHILE][33] = 62, + [2][0][RTW89_QATAR][33] = 52, + [2][0][RTW89_THAILAND][33] = 52, + [2][0][RTW89_FCC][35] = 62, + [2][0][RTW89_ETSI][35] = 52, + [2][0][RTW89_MKK][35] = 74, + [2][0][RTW89_IC][35] = 62, + [2][0][RTW89_KCC][35] = 56, + [2][0][RTW89_ACMA][35] = 52, + [2][0][RTW89_CN][35] = 127, + [2][0][RTW89_UK][35] = 52, + [2][0][RTW89_MEXICO][35] = 62, + [2][0][RTW89_UKRAINE][35] = 46, + [2][0][RTW89_CHILE][35] = 62, + [2][0][RTW89_QATAR][35] = 52, + [2][0][RTW89_THAILAND][35] = 52, + [2][0][RTW89_FCC][37] = 70, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 74, + [2][0][RTW89_IC][37] = 70, + [2][0][RTW89_KCC][37] = 56, + [2][0][RTW89_ACMA][37] = 70, + [2][0][RTW89_CN][37] = 127, + [2][0][RTW89_UK][37] = 52, + [2][0][RTW89_MEXICO][37] = 70, + [2][0][RTW89_UKRAINE][37] = 127, + [2][0][RTW89_CHILE][37] = 70, + [2][0][RTW89_QATAR][37] = 127, + [2][0][RTW89_THAILAND][37] = 127, + [2][0][RTW89_FCC][38] = 82, + [2][0][RTW89_ETSI][38] = 28, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 82, + [2][0][RTW89_KCC][38] = 60, + [2][0][RTW89_ACMA][38] = 82, + [2][0][RTW89_CN][38] = 56, + [2][0][RTW89_UK][38] = 54, + [2][0][RTW89_MEXICO][38] = 82, + [2][0][RTW89_UKRAINE][38] = 26, + [2][0][RTW89_CHILE][38] = 82, + [2][0][RTW89_QATAR][38] = 26, + [2][0][RTW89_THAILAND][38] = 28, + [2][0][RTW89_FCC][40] = 82, + [2][0][RTW89_ETSI][40] = 28, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 82, + [2][0][RTW89_KCC][40] = 60, + [2][0][RTW89_ACMA][40] = 82, + [2][0][RTW89_CN][40] = 56, + [2][0][RTW89_UK][40] = 54, + [2][0][RTW89_MEXICO][40] = 82, + [2][0][RTW89_UKRAINE][40] = 26, + [2][0][RTW89_CHILE][40] = 82, + [2][0][RTW89_QATAR][40] = 26, + [2][0][RTW89_THAILAND][40] = 28, + [2][0][RTW89_FCC][42] = 76, + [2][0][RTW89_ETSI][42] = 28, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 76, + [2][0][RTW89_KCC][42] = 60, + [2][0][RTW89_ACMA][42] = 76, + [2][0][RTW89_CN][42] = 56, + [2][0][RTW89_UK][42] = 54, + [2][0][RTW89_MEXICO][42] = 76, + [2][0][RTW89_UKRAINE][42] = 26, + [2][0][RTW89_CHILE][42] = 76, + [2][0][RTW89_QATAR][42] = 26, + [2][0][RTW89_THAILAND][42] = 28, + [2][0][RTW89_FCC][44] = 80, + [2][0][RTW89_ETSI][44] = 28, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 80, + [2][0][RTW89_KCC][44] = 60, + [2][0][RTW89_ACMA][44] = 80, + [2][0][RTW89_CN][44] = 56, + [2][0][RTW89_UK][44] = 54, + [2][0][RTW89_MEXICO][44] = 80, + [2][0][RTW89_UKRAINE][44] = 26, + [2][0][RTW89_CHILE][44] = 80, + [2][0][RTW89_QATAR][44] = 26, + [2][0][RTW89_THAILAND][44] = 28, + [2][0][RTW89_FCC][46] = 80, + [2][0][RTW89_ETSI][46] = 28, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 80, + [2][0][RTW89_KCC][46] = 60, + [2][0][RTW89_ACMA][46] = 80, + [2][0][RTW89_CN][46] = 56, + [2][0][RTW89_UK][46] = 54, + [2][0][RTW89_MEXICO][46] = 80, + [2][0][RTW89_UKRAINE][46] = 26, + [2][0][RTW89_CHILE][46] = 80, + [2][0][RTW89_QATAR][46] = 26, + [2][0][RTW89_THAILAND][46] = 28, + [2][0][RTW89_FCC][48] = 64, + [2][0][RTW89_ETSI][48] = 127, + [2][0][RTW89_MKK][48] = 127, + [2][0][RTW89_IC][48] = 64, + [2][0][RTW89_KCC][48] = 127, + [2][0][RTW89_ACMA][48] = 127, + [2][0][RTW89_CN][48] = 127, + [2][0][RTW89_UK][48] = 127, + [2][0][RTW89_MEXICO][48] = 127, + [2][0][RTW89_UKRAINE][48] = 127, + [2][0][RTW89_CHILE][48] = 127, + [2][0][RTW89_QATAR][48] = 127, + [2][0][RTW89_THAILAND][48] = 127, + [2][0][RTW89_FCC][50] = 64, + [2][0][RTW89_ETSI][50] = 127, + [2][0][RTW89_MKK][50] = 127, + [2][0][RTW89_IC][50] = 64, + [2][0][RTW89_KCC][50] = 127, + [2][0][RTW89_ACMA][50] = 127, + [2][0][RTW89_CN][50] = 127, + [2][0][RTW89_UK][50] = 127, + [2][0][RTW89_MEXICO][50] = 127, + [2][0][RTW89_UKRAINE][50] = 127, + [2][0][RTW89_CHILE][50] = 127, + [2][0][RTW89_QATAR][50] = 127, + [2][0][RTW89_THAILAND][50] = 127, + [2][0][RTW89_FCC][52] = 64, + [2][0][RTW89_ETSI][52] = 127, + [2][0][RTW89_MKK][52] = 127, + [2][0][RTW89_IC][52] = 64, + [2][0][RTW89_KCC][52] = 127, + [2][0][RTW89_ACMA][52] = 127, + [2][0][RTW89_CN][52] = 127, + [2][0][RTW89_UK][52] = 127, + [2][0][RTW89_MEXICO][52] = 127, + [2][0][RTW89_UKRAINE][52] = 127, + [2][0][RTW89_CHILE][52] = 127, + [2][0][RTW89_QATAR][52] = 127, + [2][0][RTW89_THAILAND][52] = 127, + [2][1][RTW89_FCC][0] = 50, + [2][1][RTW89_ETSI][0] = 40, + [2][1][RTW89_MKK][0] = 44, + [2][1][RTW89_IC][0] = 26, + [2][1][RTW89_KCC][0] = 52, + [2][1][RTW89_ACMA][0] = 40, + [2][1][RTW89_CN][0] = 28, + [2][1][RTW89_UK][0] = 40, + [2][1][RTW89_MEXICO][0] = 50, + [2][1][RTW89_UKRAINE][0] = 34, + [2][1][RTW89_CHILE][0] = 50, + [2][1][RTW89_QATAR][0] = 40, + [2][1][RTW89_THAILAND][0] = 40, + [2][1][RTW89_FCC][2] = 50, + [2][1][RTW89_ETSI][2] = 40, + [2][1][RTW89_MKK][2] = 44, + [2][1][RTW89_IC][2] = 26, + [2][1][RTW89_KCC][2] = 52, + [2][1][RTW89_ACMA][2] = 40, + [2][1][RTW89_CN][2] = 28, + [2][1][RTW89_UK][2] = 40, + [2][1][RTW89_MEXICO][2] = 50, + [2][1][RTW89_UKRAINE][2] = 34, + [2][1][RTW89_CHILE][2] = 50, + [2][1][RTW89_QATAR][2] = 40, + [2][1][RTW89_THAILAND][2] = 40, + [2][1][RTW89_FCC][4] = 50, + [2][1][RTW89_ETSI][4] = 40, + [2][1][RTW89_MKK][4] = 36, + [2][1][RTW89_IC][4] = 26, + [2][1][RTW89_KCC][4] = 52, + [2][1][RTW89_ACMA][4] = 40, + [2][1][RTW89_CN][4] = 28, + [2][1][RTW89_UK][4] = 40, + [2][1][RTW89_MEXICO][4] = 50, + [2][1][RTW89_UKRAINE][4] = 34, + [2][1][RTW89_CHILE][4] = 50, + [2][1][RTW89_QATAR][4] = 40, + [2][1][RTW89_THAILAND][4] = 40, + [2][1][RTW89_FCC][6] = 50, + [2][1][RTW89_ETSI][6] = 40, + [2][1][RTW89_MKK][6] = 36, + [2][1][RTW89_IC][6] = 26, + [2][1][RTW89_KCC][6] = 30, + [2][1][RTW89_ACMA][6] = 40, + [2][1][RTW89_CN][6] = 28, + [2][1][RTW89_UK][6] = 40, + [2][1][RTW89_MEXICO][6] = 50, + [2][1][RTW89_UKRAINE][6] = 34, + [2][1][RTW89_CHILE][6] = 50, + [2][1][RTW89_QATAR][6] = 40, + [2][1][RTW89_THAILAND][6] = 40, + [2][1][RTW89_FCC][8] = 50, + [2][1][RTW89_ETSI][8] = 40, + [2][1][RTW89_MKK][8] = 32, + [2][1][RTW89_IC][8] = 50, + [2][1][RTW89_KCC][8] = 50, + [2][1][RTW89_ACMA][8] = 40, + [2][1][RTW89_CN][8] = 28, + [2][1][RTW89_UK][8] = 40, + [2][1][RTW89_MEXICO][8] = 50, + [2][1][RTW89_UKRAINE][8] = 34, + [2][1][RTW89_CHILE][8] = 50, + [2][1][RTW89_QATAR][8] = 40, + [2][1][RTW89_THAILAND][8] = 40, + [2][1][RTW89_FCC][10] = 50, + [2][1][RTW89_ETSI][10] = 40, + [2][1][RTW89_MKK][10] = 32, + [2][1][RTW89_IC][10] = 50, + [2][1][RTW89_KCC][10] = 50, + [2][1][RTW89_ACMA][10] = 40, + [2][1][RTW89_CN][10] = 28, + [2][1][RTW89_UK][10] = 40, + [2][1][RTW89_MEXICO][10] = 50, + [2][1][RTW89_UKRAINE][10] = 34, + [2][1][RTW89_CHILE][10] = 50, + [2][1][RTW89_QATAR][10] = 40, + [2][1][RTW89_THAILAND][10] = 40, + [2][1][RTW89_FCC][12] = 48, + [2][1][RTW89_ETSI][12] = 40, + [2][1][RTW89_MKK][12] = 44, + [2][1][RTW89_IC][12] = 48, + [2][1][RTW89_KCC][12] = 48, + [2][1][RTW89_ACMA][12] = 40, + [2][1][RTW89_CN][12] = 28, + [2][1][RTW89_UK][12] = 40, + [2][1][RTW89_MEXICO][12] = 48, + [2][1][RTW89_UKRAINE][12] = 34, + [2][1][RTW89_CHILE][12] = 48, + [2][1][RTW89_QATAR][12] = 40, + [2][1][RTW89_THAILAND][12] = 40, + [2][1][RTW89_FCC][14] = 48, + [2][1][RTW89_ETSI][14] = 40, + [2][1][RTW89_MKK][14] = 44, + [2][1][RTW89_IC][14] = 48, + [2][1][RTW89_KCC][14] = 48, + [2][1][RTW89_ACMA][14] = 40, + [2][1][RTW89_CN][14] = 28, + [2][1][RTW89_UK][14] = 40, + [2][1][RTW89_MEXICO][14] = 48, + [2][1][RTW89_UKRAINE][14] = 34, + [2][1][RTW89_CHILE][14] = 48, + [2][1][RTW89_QATAR][14] = 40, + [2][1][RTW89_THAILAND][14] = 40, + [2][1][RTW89_FCC][15] = 50, + [2][1][RTW89_ETSI][15] = 40, + [2][1][RTW89_MKK][15] = 66, + [2][1][RTW89_IC][15] = 50, + [2][1][RTW89_KCC][15] = 48, + [2][1][RTW89_ACMA][15] = 40, + [2][1][RTW89_CN][15] = 127, + [2][1][RTW89_UK][15] = 40, + [2][1][RTW89_MEXICO][15] = 50, + [2][1][RTW89_UKRAINE][15] = 34, + [2][1][RTW89_CHILE][15] = 50, + [2][1][RTW89_QATAR][15] = 40, + [2][1][RTW89_THAILAND][15] = 40, + [2][1][RTW89_FCC][17] = 50, + [2][1][RTW89_ETSI][17] = 40, + [2][1][RTW89_MKK][17] = 66, + [2][1][RTW89_IC][17] = 50, + [2][1][RTW89_KCC][17] = 48, + [2][1][RTW89_ACMA][17] = 40, + [2][1][RTW89_CN][17] = 127, + [2][1][RTW89_UK][17] = 40, + [2][1][RTW89_MEXICO][17] = 50, + [2][1][RTW89_UKRAINE][17] = 34, + [2][1][RTW89_CHILE][17] = 50, + [2][1][RTW89_QATAR][17] = 40, + [2][1][RTW89_THAILAND][17] = 40, + [2][1][RTW89_FCC][19] = 50, + [2][1][RTW89_ETSI][19] = 40, + [2][1][RTW89_MKK][19] = 66, + [2][1][RTW89_IC][19] = 50, + [2][1][RTW89_KCC][19] = 48, + [2][1][RTW89_ACMA][19] = 40, + [2][1][RTW89_CN][19] = 127, + [2][1][RTW89_UK][19] = 40, + [2][1][RTW89_MEXICO][19] = 50, + [2][1][RTW89_UKRAINE][19] = 34, + [2][1][RTW89_CHILE][19] = 50, + [2][1][RTW89_QATAR][19] = 40, + [2][1][RTW89_THAILAND][19] = 40, + [2][1][RTW89_FCC][21] = 50, + [2][1][RTW89_ETSI][21] = 40, + [2][1][RTW89_MKK][21] = 66, + [2][1][RTW89_IC][21] = 50, + [2][1][RTW89_KCC][21] = 48, + [2][1][RTW89_ACMA][21] = 40, + [2][1][RTW89_CN][21] = 127, + [2][1][RTW89_UK][21] = 40, + [2][1][RTW89_MEXICO][21] = 50, + [2][1][RTW89_UKRAINE][21] = 34, + [2][1][RTW89_CHILE][21] = 50, + [2][1][RTW89_QATAR][21] = 40, + [2][1][RTW89_THAILAND][21] = 40, + [2][1][RTW89_FCC][23] = 50, + [2][1][RTW89_ETSI][23] = 40, + [2][1][RTW89_MKK][23] = 66, + [2][1][RTW89_IC][23] = 50, + [2][1][RTW89_KCC][23] = 48, + [2][1][RTW89_ACMA][23] = 40, + [2][1][RTW89_CN][23] = 127, + [2][1][RTW89_UK][23] = 40, + [2][1][RTW89_MEXICO][23] = 50, + [2][1][RTW89_UKRAINE][23] = 34, + [2][1][RTW89_CHILE][23] = 50, + [2][1][RTW89_QATAR][23] = 40, + [2][1][RTW89_THAILAND][23] = 40, + [2][1][RTW89_FCC][25] = 50, + [2][1][RTW89_ETSI][25] = 40, + [2][1][RTW89_MKK][25] = 66, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_KCC][25] = 48, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_CN][25] = 127, + [2][1][RTW89_UK][25] = 40, + [2][1][RTW89_MEXICO][25] = 50, + [2][1][RTW89_UKRAINE][25] = 34, + [2][1][RTW89_CHILE][25] = 50, + [2][1][RTW89_QATAR][25] = 40, + [2][1][RTW89_THAILAND][25] = 40, + [2][1][RTW89_FCC][27] = 50, + [2][1][RTW89_ETSI][27] = 40, + [2][1][RTW89_MKK][27] = 66, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_KCC][27] = 48, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_CN][27] = 127, + [2][1][RTW89_UK][27] = 40, + [2][1][RTW89_MEXICO][27] = 50, + [2][1][RTW89_UKRAINE][27] = 34, + [2][1][RTW89_CHILE][27] = 50, + [2][1][RTW89_QATAR][27] = 40, + [2][1][RTW89_THAILAND][27] = 40, + [2][1][RTW89_FCC][29] = 50, + [2][1][RTW89_ETSI][29] = 40, + [2][1][RTW89_MKK][29] = 66, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_KCC][29] = 48, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_CN][29] = 127, + [2][1][RTW89_UK][29] = 40, + [2][1][RTW89_MEXICO][29] = 50, + [2][1][RTW89_UKRAINE][29] = 34, + [2][1][RTW89_CHILE][29] = 50, + [2][1][RTW89_QATAR][29] = 40, + [2][1][RTW89_THAILAND][29] = 40, + [2][1][RTW89_FCC][31] = 50, + [2][1][RTW89_ETSI][31] = 40, + [2][1][RTW89_MKK][31] = 66, + [2][1][RTW89_IC][31] = 48, + [2][1][RTW89_KCC][31] = 48, + [2][1][RTW89_ACMA][31] = 40, + [2][1][RTW89_CN][31] = 127, + [2][1][RTW89_UK][31] = 40, + [2][1][RTW89_MEXICO][31] = 50, + [2][1][RTW89_UKRAINE][31] = 34, + [2][1][RTW89_CHILE][31] = 50, + [2][1][RTW89_QATAR][31] = 40, + [2][1][RTW89_THAILAND][31] = 40, + [2][1][RTW89_FCC][33] = 48, + [2][1][RTW89_ETSI][33] = 40, + [2][1][RTW89_MKK][33] = 66, + [2][1][RTW89_IC][33] = 48, + [2][1][RTW89_KCC][33] = 48, + [2][1][RTW89_ACMA][33] = 40, + [2][1][RTW89_CN][33] = 127, + [2][1][RTW89_UK][33] = 40, + [2][1][RTW89_MEXICO][33] = 48, + [2][1][RTW89_UKRAINE][33] = 34, + [2][1][RTW89_CHILE][33] = 48, + [2][1][RTW89_QATAR][33] = 40, + [2][1][RTW89_THAILAND][33] = 40, + [2][1][RTW89_FCC][35] = 48, + [2][1][RTW89_ETSI][35] = 40, + [2][1][RTW89_MKK][35] = 66, + [2][1][RTW89_IC][35] = 48, + [2][1][RTW89_KCC][35] = 48, + [2][1][RTW89_ACMA][35] = 40, + [2][1][RTW89_CN][35] = 127, + [2][1][RTW89_UK][35] = 40, + [2][1][RTW89_MEXICO][35] = 48, + [2][1][RTW89_UKRAINE][35] = 34, + [2][1][RTW89_CHILE][35] = 48, + [2][1][RTW89_QATAR][35] = 40, + [2][1][RTW89_THAILAND][35] = 40, + [2][1][RTW89_FCC][37] = 52, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 66, + [2][1][RTW89_IC][37] = 52, + [2][1][RTW89_KCC][37] = 48, + [2][1][RTW89_ACMA][37] = 52, + [2][1][RTW89_CN][37] = 127, + [2][1][RTW89_UK][37] = 42, + [2][1][RTW89_MEXICO][37] = 52, + [2][1][RTW89_UKRAINE][37] = 127, + [2][1][RTW89_CHILE][37] = 52, + [2][1][RTW89_QATAR][37] = 127, + [2][1][RTW89_THAILAND][37] = 127, + [2][1][RTW89_FCC][38] = 78, + [2][1][RTW89_ETSI][38] = 16, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 78, + [2][1][RTW89_KCC][38] = 50, + [2][1][RTW89_ACMA][38] = 78, + [2][1][RTW89_CN][38] = 56, + [2][1][RTW89_UK][38] = 42, + [2][1][RTW89_MEXICO][38] = 78, + [2][1][RTW89_UKRAINE][38] = 14, + [2][1][RTW89_CHILE][38] = 72, + [2][1][RTW89_QATAR][38] = 14, + [2][1][RTW89_THAILAND][38] = 16, + [2][1][RTW89_FCC][40] = 78, + [2][1][RTW89_ETSI][40] = 16, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 78, + [2][1][RTW89_KCC][40] = 50, + [2][1][RTW89_ACMA][40] = 78, + [2][1][RTW89_CN][40] = 56, + [2][1][RTW89_UK][40] = 42, + [2][1][RTW89_MEXICO][40] = 78, + [2][1][RTW89_UKRAINE][40] = 14, + [2][1][RTW89_CHILE][40] = 72, + [2][1][RTW89_QATAR][40] = 14, + [2][1][RTW89_THAILAND][40] = 16, + [2][1][RTW89_FCC][42] = 78, + [2][1][RTW89_ETSI][42] = 16, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 78, + [2][1][RTW89_KCC][42] = 50, + [2][1][RTW89_ACMA][42] = 78, + [2][1][RTW89_CN][42] = 56, + [2][1][RTW89_UK][42] = 42, + [2][1][RTW89_MEXICO][42] = 78, + [2][1][RTW89_UKRAINE][42] = 14, + [2][1][RTW89_CHILE][42] = 72, + [2][1][RTW89_QATAR][42] = 14, + [2][1][RTW89_THAILAND][42] = 16, + [2][1][RTW89_FCC][44] = 74, + [2][1][RTW89_ETSI][44] = 16, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 74, + [2][1][RTW89_KCC][44] = 50, + [2][1][RTW89_ACMA][44] = 74, + [2][1][RTW89_CN][44] = 56, + [2][1][RTW89_UK][44] = 42, + [2][1][RTW89_MEXICO][44] = 74, + [2][1][RTW89_UKRAINE][44] = 14, + [2][1][RTW89_CHILE][44] = 72, + [2][1][RTW89_QATAR][44] = 14, + [2][1][RTW89_THAILAND][44] = 16, + [2][1][RTW89_FCC][46] = 74, + [2][1][RTW89_ETSI][46] = 16, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 74, + [2][1][RTW89_KCC][46] = 50, + [2][1][RTW89_ACMA][46] = 74, + [2][1][RTW89_CN][46] = 56, + [2][1][RTW89_UK][46] = 42, + [2][1][RTW89_MEXICO][46] = 74, + [2][1][RTW89_UKRAINE][46] = 14, + [2][1][RTW89_CHILE][46] = 72, + [2][1][RTW89_QATAR][46] = 14, + [2][1][RTW89_THAILAND][46] = 16, + [2][1][RTW89_FCC][48] = 40, + [2][1][RTW89_ETSI][48] = 127, + [2][1][RTW89_MKK][48] = 127, + [2][1][RTW89_IC][48] = 40, + [2][1][RTW89_KCC][48] = 127, + [2][1][RTW89_ACMA][48] = 127, + [2][1][RTW89_CN][48] = 127, + [2][1][RTW89_UK][48] = 127, + [2][1][RTW89_MEXICO][48] = 127, + [2][1][RTW89_UKRAINE][48] = 127, + [2][1][RTW89_CHILE][48] = 127, + [2][1][RTW89_QATAR][48] = 127, + [2][1][RTW89_THAILAND][48] = 127, + [2][1][RTW89_FCC][50] = 40, + [2][1][RTW89_ETSI][50] = 127, + [2][1][RTW89_MKK][50] = 127, + [2][1][RTW89_IC][50] = 40, + [2][1][RTW89_KCC][50] = 127, + [2][1][RTW89_ACMA][50] = 127, + [2][1][RTW89_CN][50] = 127, + [2][1][RTW89_UK][50] = 127, + [2][1][RTW89_MEXICO][50] = 127, + [2][1][RTW89_UKRAINE][50] = 127, + [2][1][RTW89_CHILE][50] = 127, + [2][1][RTW89_QATAR][50] = 127, + [2][1][RTW89_THAILAND][50] = 127, + [2][1][RTW89_FCC][52] = 40, + [2][1][RTW89_ETSI][52] = 127, + [2][1][RTW89_MKK][52] = 127, + [2][1][RTW89_IC][52] = 40, + [2][1][RTW89_KCC][52] = 127, + [2][1][RTW89_ACMA][52] = 127, + [2][1][RTW89_CN][52] = 127, + [2][1][RTW89_UK][52] = 127, + [2][1][RTW89_MEXICO][52] = 127, + [2][1][RTW89_UKRAINE][52] = 127, + [2][1][RTW89_CHILE][52] = 127, + [2][1][RTW89_QATAR][52] = 127, + [2][1][RTW89_THAILAND][52] = 127, +}; + +static +const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] + [RTW89_6G_CH_NUM] = { + [0][0][RTW89_WW][0][0] = -16, + [0][0][RTW89_WW][1][0] = -16, + [0][0][RTW89_WW][0][2] = -18, + [0][0][RTW89_WW][1][2] = -18, + [0][0][RTW89_WW][0][4] = -18, + [0][0][RTW89_WW][1][4] = -18, + [0][0][RTW89_WW][0][6] = -18, + [0][0][RTW89_WW][1][6] = -18, + [0][0][RTW89_WW][0][8] = -18, + [0][0][RTW89_WW][1][8] = -18, + [0][0][RTW89_WW][0][10] = -18, + [0][0][RTW89_WW][1][10] = -18, + [0][0][RTW89_WW][0][12] = -18, + [0][0][RTW89_WW][1][12] = -18, + [0][0][RTW89_WW][0][14] = -18, + [0][0][RTW89_WW][1][14] = -18, + [0][0][RTW89_WW][0][15] = -18, + [0][0][RTW89_WW][1][15] = -18, + [0][0][RTW89_WW][0][17] = -18, + [0][0][RTW89_WW][1][17] = -18, + [0][0][RTW89_WW][0][19] = -18, + [0][0][RTW89_WW][1][19] = -18, + [0][0][RTW89_WW][0][21] = -18, + [0][0][RTW89_WW][1][21] = -18, + [0][0][RTW89_WW][0][23] = -18, + [0][0][RTW89_WW][1][23] = -18, + [0][0][RTW89_WW][0][25] = -18, + [0][0][RTW89_WW][1][25] = -18, + [0][0][RTW89_WW][0][27] = -18, + [0][0][RTW89_WW][1][27] = -18, + [0][0][RTW89_WW][0][29] = -18, + [0][0][RTW89_WW][1][29] = -18, + [0][0][RTW89_WW][0][30] = -18, + [0][0][RTW89_WW][1][30] = -18, + [0][0][RTW89_WW][0][32] = -18, + [0][0][RTW89_WW][1][32] = -18, + [0][0][RTW89_WW][0][34] = -18, + [0][0][RTW89_WW][1][34] = -18, + [0][0][RTW89_WW][0][36] = -18, + [0][0][RTW89_WW][1][36] = -18, + [0][0][RTW89_WW][0][38] = -18, + [0][0][RTW89_WW][1][38] = -18, + [0][0][RTW89_WW][0][40] = -18, + [0][0][RTW89_WW][1][40] = -18, + [0][0][RTW89_WW][0][42] = -18, + [0][0][RTW89_WW][1][42] = -18, + [0][0][RTW89_WW][0][44] = -16, + [0][0][RTW89_WW][1][44] = -16, + [0][0][RTW89_WW][0][45] = -16, + [0][0][RTW89_WW][1][45] = -16, + [0][0][RTW89_WW][0][47] = -18, + [0][0][RTW89_WW][1][47] = -18, + [0][0][RTW89_WW][0][49] = -18, + [0][0][RTW89_WW][1][49] = -18, + [0][0][RTW89_WW][0][51] = -18, + [0][0][RTW89_WW][1][51] = -18, + [0][0][RTW89_WW][0][53] = -16, + [0][0][RTW89_WW][1][53] = -16, + [0][0][RTW89_WW][0][55] = -18, + [0][0][RTW89_WW][1][55] = -18, + [0][0][RTW89_WW][0][57] = -18, + [0][0][RTW89_WW][1][57] = -18, + [0][0][RTW89_WW][0][59] = -18, + [0][0][RTW89_WW][1][59] = -18, + [0][0][RTW89_WW][0][60] = -18, + [0][0][RTW89_WW][1][60] = -18, + [0][0][RTW89_WW][0][62] = -18, + [0][0][RTW89_WW][1][62] = -18, + [0][0][RTW89_WW][0][64] = -18, + [0][0][RTW89_WW][1][64] = -18, + [0][0][RTW89_WW][0][66] = -18, + [0][0][RTW89_WW][1][66] = -18, + [0][0][RTW89_WW][0][68] = -18, + [0][0][RTW89_WW][1][68] = -18, + [0][0][RTW89_WW][0][70] = -16, + [0][0][RTW89_WW][1][70] = -16, + [0][0][RTW89_WW][0][72] = -18, + [0][0][RTW89_WW][1][72] = -18, + [0][0][RTW89_WW][0][74] = -18, + [0][0][RTW89_WW][1][74] = -18, + [0][0][RTW89_WW][0][75] = -18, + [0][0][RTW89_WW][1][75] = -18, + [0][0][RTW89_WW][0][77] = -18, + [0][0][RTW89_WW][1][77] = -18, + [0][0][RTW89_WW][0][79] = -18, + [0][0][RTW89_WW][1][79] = -18, + [0][0][RTW89_WW][0][81] = -18, + [0][0][RTW89_WW][1][81] = -18, + [0][0][RTW89_WW][0][83] = -18, + [0][0][RTW89_WW][1][83] = -18, + [0][0][RTW89_WW][0][85] = -18, + [0][0][RTW89_WW][1][85] = -18, + [0][0][RTW89_WW][0][87] = -16, + [0][0][RTW89_WW][1][87] = -16, + [0][0][RTW89_WW][0][89] = -16, + [0][0][RTW89_WW][1][89] = -16, + [0][0][RTW89_WW][0][90] = -16, + [0][0][RTW89_WW][1][90] = -16, + [0][0][RTW89_WW][0][92] = -16, + [0][0][RTW89_WW][1][92] = -16, + [0][0][RTW89_WW][0][94] = -16, + [0][0][RTW89_WW][1][94] = -16, + [0][0][RTW89_WW][0][96] = -16, + [0][0][RTW89_WW][1][96] = -16, + [0][0][RTW89_WW][0][98] = -16, + [0][0][RTW89_WW][1][98] = -16, + [0][0][RTW89_WW][0][100] = -16, + [0][0][RTW89_WW][1][100] = -16, + [0][0][RTW89_WW][0][102] = -16, + [0][0][RTW89_WW][1][102] = -16, + [0][0][RTW89_WW][0][104] = -16, + [0][0][RTW89_WW][1][104] = -16, + [0][0][RTW89_WW][0][105] = -16, + [0][0][RTW89_WW][1][105] = -16, + [0][0][RTW89_WW][0][107] = -12, + [0][0][RTW89_WW][1][107] = -12, + [0][0][RTW89_WW][0][109] = -12, + [0][0][RTW89_WW][1][109] = -12, + [0][0][RTW89_WW][0][111] = 0, + [0][0][RTW89_WW][1][111] = 0, + [0][0][RTW89_WW][0][113] = 0, + [0][0][RTW89_WW][1][113] = 0, + [0][0][RTW89_WW][0][115] = 0, + [0][0][RTW89_WW][1][115] = 0, + [0][0][RTW89_WW][0][117] = 0, + [0][0][RTW89_WW][1][117] = 0, + [0][0][RTW89_WW][0][119] = 0, + [0][0][RTW89_WW][1][119] = 0, + [0][1][RTW89_WW][0][0] = -40, + [0][1][RTW89_WW][1][0] = -40, + [0][1][RTW89_WW][0][2] = -40, + [0][1][RTW89_WW][1][2] = -40, + [0][1][RTW89_WW][0][4] = -40, + [0][1][RTW89_WW][1][4] = -40, + [0][1][RTW89_WW][0][6] = -40, + [0][1][RTW89_WW][1][6] = -40, + [0][1][RTW89_WW][0][8] = -40, + [0][1][RTW89_WW][1][8] = -40, + [0][1][RTW89_WW][0][10] = -40, + [0][1][RTW89_WW][1][10] = -40, + [0][1][RTW89_WW][0][12] = -40, + [0][1][RTW89_WW][1][12] = -40, + [0][1][RTW89_WW][0][14] = -40, + [0][1][RTW89_WW][1][14] = -40, + [0][1][RTW89_WW][0][15] = -40, + [0][1][RTW89_WW][1][15] = -40, + [0][1][RTW89_WW][0][17] = -40, + [0][1][RTW89_WW][1][17] = -40, + [0][1][RTW89_WW][0][19] = -40, + [0][1][RTW89_WW][1][19] = -40, + [0][1][RTW89_WW][0][21] = -40, + [0][1][RTW89_WW][1][21] = -40, + [0][1][RTW89_WW][0][23] = -40, + [0][1][RTW89_WW][1][23] = -40, + [0][1][RTW89_WW][0][25] = -40, + [0][1][RTW89_WW][1][25] = -40, + [0][1][RTW89_WW][0][27] = -40, + [0][1][RTW89_WW][1][27] = -40, + [0][1][RTW89_WW][0][29] = -40, + [0][1][RTW89_WW][1][29] = -40, + [0][1][RTW89_WW][0][30] = -40, + [0][1][RTW89_WW][1][30] = -40, + [0][1][RTW89_WW][0][32] = -40, + [0][1][RTW89_WW][1][32] = -40, + [0][1][RTW89_WW][0][34] = -40, + [0][1][RTW89_WW][1][34] = -40, + [0][1][RTW89_WW][0][36] = -40, + [0][1][RTW89_WW][1][36] = -40, + [0][1][RTW89_WW][0][38] = -40, + [0][1][RTW89_WW][1][38] = -40, + [0][1][RTW89_WW][0][40] = -40, + [0][1][RTW89_WW][1][40] = -40, + [0][1][RTW89_WW][0][42] = -40, + [0][1][RTW89_WW][1][42] = -40, + [0][1][RTW89_WW][0][44] = -40, + [0][1][RTW89_WW][1][44] = -40, + [0][1][RTW89_WW][0][45] = -40, + [0][1][RTW89_WW][1][45] = -40, + [0][1][RTW89_WW][0][47] = -40, + [0][1][RTW89_WW][1][47] = -40, + [0][1][RTW89_WW][0][49] = -40, + [0][1][RTW89_WW][1][49] = -40, + [0][1][RTW89_WW][0][51] = -40, + [0][1][RTW89_WW][1][51] = -40, + [0][1][RTW89_WW][0][53] = -40, + [0][1][RTW89_WW][1][53] = -40, + [0][1][RTW89_WW][0][55] = -40, + [0][1][RTW89_WW][1][55] = -40, + [0][1][RTW89_WW][0][57] = -40, + [0][1][RTW89_WW][1][57] = -40, + [0][1][RTW89_WW][0][59] = -40, + [0][1][RTW89_WW][1][59] = -40, + [0][1][RTW89_WW][0][60] = -40, + [0][1][RTW89_WW][1][60] = -40, + [0][1][RTW89_WW][0][62] = -40, + [0][1][RTW89_WW][1][62] = -40, + [0][1][RTW89_WW][0][64] = -40, + [0][1][RTW89_WW][1][64] = -40, + [0][1][RTW89_WW][0][66] = -40, + [0][1][RTW89_WW][1][66] = -40, + [0][1][RTW89_WW][0][68] = -40, + [0][1][RTW89_WW][1][68] = -40, + [0][1][RTW89_WW][0][70] = -38, + [0][1][RTW89_WW][1][70] = -38, + [0][1][RTW89_WW][0][72] = -38, + [0][1][RTW89_WW][1][72] = -38, + [0][1][RTW89_WW][0][74] = -38, + [0][1][RTW89_WW][1][74] = -38, + [0][1][RTW89_WW][0][75] = -38, + [0][1][RTW89_WW][1][75] = -38, + [0][1][RTW89_WW][0][77] = -38, + [0][1][RTW89_WW][1][77] = -38, + [0][1][RTW89_WW][0][79] = -38, + [0][1][RTW89_WW][1][79] = -38, + [0][1][RTW89_WW][0][81] = -38, + [0][1][RTW89_WW][1][81] = -38, + [0][1][RTW89_WW][0][83] = -38, + [0][1][RTW89_WW][1][83] = -38, + [0][1][RTW89_WW][0][85] = -38, + [0][1][RTW89_WW][1][85] = -38, + [0][1][RTW89_WW][0][87] = -40, + [0][1][RTW89_WW][1][87] = -40, + [0][1][RTW89_WW][0][89] = -38, + [0][1][RTW89_WW][1][89] = -38, + [0][1][RTW89_WW][0][90] = -38, + [0][1][RTW89_WW][1][90] = -38, + [0][1][RTW89_WW][0][92] = -38, + [0][1][RTW89_WW][1][92] = -38, + [0][1][RTW89_WW][0][94] = -38, + [0][1][RTW89_WW][1][94] = -38, + [0][1][RTW89_WW][0][96] = -38, + [0][1][RTW89_WW][1][96] = -38, + [0][1][RTW89_WW][0][98] = -38, + [0][1][RTW89_WW][1][98] = -38, + [0][1][RTW89_WW][0][100] = -38, + [0][1][RTW89_WW][1][100] = -38, + [0][1][RTW89_WW][0][102] = -38, + [0][1][RTW89_WW][1][102] = -38, + [0][1][RTW89_WW][0][104] = -38, + [0][1][RTW89_WW][1][104] = -38, + [0][1][RTW89_WW][0][105] = -38, + [0][1][RTW89_WW][1][105] = -38, + [0][1][RTW89_WW][0][107] = -34, + [0][1][RTW89_WW][1][107] = -34, + [0][1][RTW89_WW][0][109] = -34, + [0][1][RTW89_WW][1][109] = -34, + [0][1][RTW89_WW][0][111] = 0, + [0][1][RTW89_WW][1][111] = 0, + [0][1][RTW89_WW][0][113] = 0, + [0][1][RTW89_WW][1][113] = 0, + [0][1][RTW89_WW][0][115] = 0, + [0][1][RTW89_WW][1][115] = 0, + [0][1][RTW89_WW][0][117] = 0, + [0][1][RTW89_WW][1][117] = 0, + [0][1][RTW89_WW][0][119] = 0, + [0][1][RTW89_WW][1][119] = 0, + [1][0][RTW89_WW][0][0] = -4, + [1][0][RTW89_WW][1][0] = -4, + [1][0][RTW89_WW][0][2] = -4, + [1][0][RTW89_WW][1][2] = -4, + [1][0][RTW89_WW][0][4] = -4, + [1][0][RTW89_WW][1][4] = -4, + [1][0][RTW89_WW][0][6] = -4, + [1][0][RTW89_WW][1][6] = -4, + [1][0][RTW89_WW][0][8] = -4, + [1][0][RTW89_WW][1][8] = -4, + [1][0][RTW89_WW][0][10] = -4, + [1][0][RTW89_WW][1][10] = -4, + [1][0][RTW89_WW][0][12] = -4, + [1][0][RTW89_WW][1][12] = -4, + [1][0][RTW89_WW][0][14] = -4, + [1][0][RTW89_WW][1][14] = -4, + [1][0][RTW89_WW][0][15] = -4, + [1][0][RTW89_WW][1][15] = -4, + [1][0][RTW89_WW][0][17] = -4, + [1][0][RTW89_WW][1][17] = -4, + [1][0][RTW89_WW][0][19] = -4, + [1][0][RTW89_WW][1][19] = -4, + [1][0][RTW89_WW][0][21] = -4, + [1][0][RTW89_WW][1][21] = -4, + [1][0][RTW89_WW][0][23] = -4, + [1][0][RTW89_WW][1][23] = -4, + [1][0][RTW89_WW][0][25] = -4, + [1][0][RTW89_WW][1][25] = -4, + [1][0][RTW89_WW][0][27] = -4, + [1][0][RTW89_WW][1][27] = -4, + [1][0][RTW89_WW][0][29] = -4, + [1][0][RTW89_WW][1][29] = -4, + [1][0][RTW89_WW][0][30] = -4, + [1][0][RTW89_WW][1][30] = -4, + [1][0][RTW89_WW][0][32] = -4, + [1][0][RTW89_WW][1][32] = -4, + [1][0][RTW89_WW][0][34] = -4, + [1][0][RTW89_WW][1][34] = -4, + [1][0][RTW89_WW][0][36] = -4, + [1][0][RTW89_WW][1][36] = -4, + [1][0][RTW89_WW][0][38] = -4, + [1][0][RTW89_WW][1][38] = -4, + [1][0][RTW89_WW][0][40] = -4, + [1][0][RTW89_WW][1][40] = -4, + [1][0][RTW89_WW][0][42] = -4, + [1][0][RTW89_WW][1][42] = -4, + [1][0][RTW89_WW][0][44] = -4, + [1][0][RTW89_WW][1][44] = -4, + [1][0][RTW89_WW][0][45] = -4, + [1][0][RTW89_WW][1][45] = -4, + [1][0][RTW89_WW][0][47] = -4, + [1][0][RTW89_WW][1][47] = -4, + [1][0][RTW89_WW][0][49] = -4, + [1][0][RTW89_WW][1][49] = -4, + [1][0][RTW89_WW][0][51] = -4, + [1][0][RTW89_WW][1][51] = -4, + [1][0][RTW89_WW][0][53] = -4, + [1][0][RTW89_WW][1][53] = -4, + [1][0][RTW89_WW][0][55] = -4, + [1][0][RTW89_WW][1][55] = -4, + [1][0][RTW89_WW][0][57] = -4, + [1][0][RTW89_WW][1][57] = -4, + [1][0][RTW89_WW][0][59] = -4, + [1][0][RTW89_WW][1][59] = -4, + [1][0][RTW89_WW][0][60] = -4, + [1][0][RTW89_WW][1][60] = -4, + [1][0][RTW89_WW][0][62] = -4, + [1][0][RTW89_WW][1][62] = -4, + [1][0][RTW89_WW][0][64] = -4, + [1][0][RTW89_WW][1][64] = -4, + [1][0][RTW89_WW][0][66] = -4, + [1][0][RTW89_WW][1][66] = -4, + [1][0][RTW89_WW][0][68] = -4, + [1][0][RTW89_WW][1][68] = -4, + [1][0][RTW89_WW][0][70] = -4, + [1][0][RTW89_WW][1][70] = -4, + [1][0][RTW89_WW][0][72] = -4, + [1][0][RTW89_WW][1][72] = -4, + [1][0][RTW89_WW][0][74] = -4, + [1][0][RTW89_WW][1][74] = -4, + [1][0][RTW89_WW][0][75] = -4, + [1][0][RTW89_WW][1][75] = -4, + [1][0][RTW89_WW][0][77] = -4, + [1][0][RTW89_WW][1][77] = -4, + [1][0][RTW89_WW][0][79] = -4, + [1][0][RTW89_WW][1][79] = -4, + [1][0][RTW89_WW][0][81] = -4, + [1][0][RTW89_WW][1][81] = -4, + [1][0][RTW89_WW][0][83] = -4, + [1][0][RTW89_WW][1][83] = -4, + [1][0][RTW89_WW][0][85] = -4, + [1][0][RTW89_WW][1][85] = -4, + [1][0][RTW89_WW][0][87] = -4, + [1][0][RTW89_WW][1][87] = -4, + [1][0][RTW89_WW][0][89] = -4, + [1][0][RTW89_WW][1][89] = -4, + [1][0][RTW89_WW][0][90] = -4, + [1][0][RTW89_WW][1][90] = -4, + [1][0][RTW89_WW][0][92] = -4, + [1][0][RTW89_WW][1][92] = -4, + [1][0][RTW89_WW][0][94] = -4, + [1][0][RTW89_WW][1][94] = -4, + [1][0][RTW89_WW][0][96] = -4, + [1][0][RTW89_WW][1][96] = -4, + [1][0][RTW89_WW][0][98] = -4, + [1][0][RTW89_WW][1][98] = -4, + [1][0][RTW89_WW][0][100] = -4, + [1][0][RTW89_WW][1][100] = -4, + [1][0][RTW89_WW][0][102] = -4, + [1][0][RTW89_WW][1][102] = -4, + [1][0][RTW89_WW][0][104] = -4, + [1][0][RTW89_WW][1][104] = -4, + [1][0][RTW89_WW][0][105] = -4, + [1][0][RTW89_WW][1][105] = -4, + [1][0][RTW89_WW][0][107] = -2, + [1][0][RTW89_WW][1][107] = -2, + [1][0][RTW89_WW][0][109] = 2, + [1][0][RTW89_WW][1][109] = 2, + [1][0][RTW89_WW][0][111] = 0, + [1][0][RTW89_WW][1][111] = 0, + [1][0][RTW89_WW][0][113] = 0, + [1][0][RTW89_WW][1][113] = 0, + [1][0][RTW89_WW][0][115] = 0, + [1][0][RTW89_WW][1][115] = 0, + [1][0][RTW89_WW][0][117] = 0, + [1][0][RTW89_WW][1][117] = 0, + [1][0][RTW89_WW][0][119] = 0, + [1][0][RTW89_WW][1][119] = 0, + [1][1][RTW89_WW][0][0] = -26, + [1][1][RTW89_WW][1][0] = -26, + [1][1][RTW89_WW][0][2] = -28, + [1][1][RTW89_WW][1][2] = -28, + [1][1][RTW89_WW][0][4] = -28, + [1][1][RTW89_WW][1][4] = -28, + [1][1][RTW89_WW][0][6] = -28, + [1][1][RTW89_WW][1][6] = -28, + [1][1][RTW89_WW][0][8] = -28, + [1][1][RTW89_WW][1][8] = -28, + [1][1][RTW89_WW][0][10] = -28, + [1][1][RTW89_WW][1][10] = -28, + [1][1][RTW89_WW][0][12] = -28, + [1][1][RTW89_WW][1][12] = -28, + [1][1][RTW89_WW][0][14] = -28, + [1][1][RTW89_WW][1][14] = -28, + [1][1][RTW89_WW][0][15] = -28, + [1][1][RTW89_WW][1][15] = -28, + [1][1][RTW89_WW][0][17] = -28, + [1][1][RTW89_WW][1][17] = -28, + [1][1][RTW89_WW][0][19] = -28, + [1][1][RTW89_WW][1][19] = -28, + [1][1][RTW89_WW][0][21] = -28, + [1][1][RTW89_WW][1][21] = -28, + [1][1][RTW89_WW][0][23] = -28, + [1][1][RTW89_WW][1][23] = -28, + [1][1][RTW89_WW][0][25] = -28, + [1][1][RTW89_WW][1][25] = -28, + [1][1][RTW89_WW][0][27] = -28, + [1][1][RTW89_WW][1][27] = -28, + [1][1][RTW89_WW][0][29] = -28, + [1][1][RTW89_WW][1][29] = -28, + [1][1][RTW89_WW][0][30] = -28, + [1][1][RTW89_WW][1][30] = -28, + [1][1][RTW89_WW][0][32] = -28, + [1][1][RTW89_WW][1][32] = -28, + [1][1][RTW89_WW][0][34] = -28, + [1][1][RTW89_WW][1][34] = -28, + [1][1][RTW89_WW][0][36] = -28, + [1][1][RTW89_WW][1][36] = -28, + [1][1][RTW89_WW][0][38] = -28, + [1][1][RTW89_WW][1][38] = -28, + [1][1][RTW89_WW][0][40] = -28, + [1][1][RTW89_WW][1][40] = -28, + [1][1][RTW89_WW][0][42] = -28, + [1][1][RTW89_WW][1][42] = -28, + [1][1][RTW89_WW][0][44] = -28, + [1][1][RTW89_WW][1][44] = -28, + [1][1][RTW89_WW][0][45] = -26, + [1][1][RTW89_WW][1][45] = -26, + [1][1][RTW89_WW][0][47] = -28, + [1][1][RTW89_WW][1][47] = -28, + [1][1][RTW89_WW][0][49] = -28, + [1][1][RTW89_WW][1][49] = -28, + [1][1][RTW89_WW][0][51] = -28, + [1][1][RTW89_WW][1][51] = -28, + [1][1][RTW89_WW][0][53] = -26, + [1][1][RTW89_WW][1][53] = -26, + [1][1][RTW89_WW][0][55] = -28, + [1][1][RTW89_WW][1][55] = -28, + [1][1][RTW89_WW][0][57] = -28, + [1][1][RTW89_WW][1][57] = -28, + [1][1][RTW89_WW][0][59] = -28, + [1][1][RTW89_WW][1][59] = -28, + [1][1][RTW89_WW][0][60] = -28, + [1][1][RTW89_WW][1][60] = -28, + [1][1][RTW89_WW][0][62] = -28, + [1][1][RTW89_WW][1][62] = -28, + [1][1][RTW89_WW][0][64] = -28, + [1][1][RTW89_WW][1][64] = -28, + [1][1][RTW89_WW][0][66] = -28, + [1][1][RTW89_WW][1][66] = -28, + [1][1][RTW89_WW][0][68] = -28, + [1][1][RTW89_WW][1][68] = -28, + [1][1][RTW89_WW][0][70] = -26, + [1][1][RTW89_WW][1][70] = -26, + [1][1][RTW89_WW][0][72] = -28, + [1][1][RTW89_WW][1][72] = -28, + [1][1][RTW89_WW][0][74] = -28, + [1][1][RTW89_WW][1][74] = -28, + [1][1][RTW89_WW][0][75] = -28, + [1][1][RTW89_WW][1][75] = -28, + [1][1][RTW89_WW][0][77] = -28, + [1][1][RTW89_WW][1][77] = -28, + [1][1][RTW89_WW][0][79] = -28, + [1][1][RTW89_WW][1][79] = -28, + [1][1][RTW89_WW][0][81] = -28, + [1][1][RTW89_WW][1][81] = -28, + [1][1][RTW89_WW][0][83] = -28, + [1][1][RTW89_WW][1][83] = -28, + [1][1][RTW89_WW][0][85] = -28, + [1][1][RTW89_WW][1][85] = -28, + [1][1][RTW89_WW][0][87] = -28, + [1][1][RTW89_WW][1][87] = -28, + [1][1][RTW89_WW][0][89] = -26, + [1][1][RTW89_WW][1][89] = -26, + [1][1][RTW89_WW][0][90] = -26, + [1][1][RTW89_WW][1][90] = -26, + [1][1][RTW89_WW][0][92] = -26, + [1][1][RTW89_WW][1][92] = -26, + [1][1][RTW89_WW][0][94] = -26, + [1][1][RTW89_WW][1][94] = -26, + [1][1][RTW89_WW][0][96] = -26, + [1][1][RTW89_WW][1][96] = -26, + [1][1][RTW89_WW][0][98] = -26, + [1][1][RTW89_WW][1][98] = -26, + [1][1][RTW89_WW][0][100] = -26, + [1][1][RTW89_WW][1][100] = -26, + [1][1][RTW89_WW][0][102] = -26, + [1][1][RTW89_WW][1][102] = -26, + [1][1][RTW89_WW][0][104] = -26, + [1][1][RTW89_WW][1][104] = -26, + [1][1][RTW89_WW][0][105] = -26, + [1][1][RTW89_WW][1][105] = -26, + [1][1][RTW89_WW][0][107] = -22, + [1][1][RTW89_WW][1][107] = -22, + [1][1][RTW89_WW][0][109] = -22, + [1][1][RTW89_WW][1][109] = -22, + [1][1][RTW89_WW][0][111] = 0, + [1][1][RTW89_WW][1][111] = 0, + [1][1][RTW89_WW][0][113] = 0, + [1][1][RTW89_WW][1][113] = 0, + [1][1][RTW89_WW][0][115] = 0, + [1][1][RTW89_WW][1][115] = 0, + [1][1][RTW89_WW][0][117] = 0, + [1][1][RTW89_WW][1][117] = 0, + [1][1][RTW89_WW][0][119] = 0, + [1][1][RTW89_WW][1][119] = 0, + [2][0][RTW89_WW][0][0] = -2, + [2][0][RTW89_WW][1][0] = -2, + [2][0][RTW89_WW][0][2] = -2, + [2][0][RTW89_WW][1][2] = -2, + [2][0][RTW89_WW][0][4] = -2, + [2][0][RTW89_WW][1][4] = -2, + [2][0][RTW89_WW][0][6] = -2, + [2][0][RTW89_WW][1][6] = -2, + [2][0][RTW89_WW][0][8] = -2, + [2][0][RTW89_WW][1][8] = -2, + [2][0][RTW89_WW][0][10] = -2, + [2][0][RTW89_WW][1][10] = -2, + [2][0][RTW89_WW][0][12] = -2, + [2][0][RTW89_WW][1][12] = -2, + [2][0][RTW89_WW][0][14] = -2, + [2][0][RTW89_WW][1][14] = -2, + [2][0][RTW89_WW][0][15] = -2, + [2][0][RTW89_WW][1][15] = -2, + [2][0][RTW89_WW][0][17] = -2, + [2][0][RTW89_WW][1][17] = -2, + [2][0][RTW89_WW][0][19] = -2, + [2][0][RTW89_WW][1][19] = -2, + [2][0][RTW89_WW][0][21] = -2, + [2][0][RTW89_WW][1][21] = -2, + [2][0][RTW89_WW][0][23] = -2, + [2][0][RTW89_WW][1][23] = -2, + [2][0][RTW89_WW][0][25] = -2, + [2][0][RTW89_WW][1][25] = -2, + [2][0][RTW89_WW][0][27] = -2, + [2][0][RTW89_WW][1][27] = -2, + [2][0][RTW89_WW][0][29] = -2, + [2][0][RTW89_WW][1][29] = -2, + [2][0][RTW89_WW][0][30] = -2, + [2][0][RTW89_WW][1][30] = -2, + [2][0][RTW89_WW][0][32] = -2, + [2][0][RTW89_WW][1][32] = -2, + [2][0][RTW89_WW][0][34] = -2, + [2][0][RTW89_WW][1][34] = -2, + [2][0][RTW89_WW][0][36] = -2, + [2][0][RTW89_WW][1][36] = -2, + [2][0][RTW89_WW][0][38] = -2, + [2][0][RTW89_WW][1][38] = -2, + [2][0][RTW89_WW][0][40] = -2, + [2][0][RTW89_WW][1][40] = -2, + [2][0][RTW89_WW][0][42] = -2, + [2][0][RTW89_WW][1][42] = -2, + [2][0][RTW89_WW][0][44] = -2, + [2][0][RTW89_WW][1][44] = -2, + [2][0][RTW89_WW][0][45] = -2, + [2][0][RTW89_WW][1][45] = -2, + [2][0][RTW89_WW][0][47] = -2, + [2][0][RTW89_WW][1][47] = -2, + [2][0][RTW89_WW][0][49] = -2, + [2][0][RTW89_WW][1][49] = -2, + [2][0][RTW89_WW][0][51] = -2, + [2][0][RTW89_WW][1][51] = -2, + [2][0][RTW89_WW][0][53] = -2, + [2][0][RTW89_WW][1][53] = -2, + [2][0][RTW89_WW][0][55] = -2, + [2][0][RTW89_WW][1][55] = -2, + [2][0][RTW89_WW][0][57] = -2, + [2][0][RTW89_WW][1][57] = -2, + [2][0][RTW89_WW][0][59] = -2, + [2][0][RTW89_WW][1][59] = -2, + [2][0][RTW89_WW][0][60] = -2, + [2][0][RTW89_WW][1][60] = -2, + [2][0][RTW89_WW][0][62] = -2, + [2][0][RTW89_WW][1][62] = -2, + [2][0][RTW89_WW][0][64] = -2, + [2][0][RTW89_WW][1][64] = -2, + [2][0][RTW89_WW][0][66] = -2, + [2][0][RTW89_WW][1][66] = -2, + [2][0][RTW89_WW][0][68] = -2, + [2][0][RTW89_WW][1][68] = -2, + [2][0][RTW89_WW][0][70] = -2, + [2][0][RTW89_WW][1][70] = -2, + [2][0][RTW89_WW][0][72] = -2, + [2][0][RTW89_WW][1][72] = -2, + [2][0][RTW89_WW][0][74] = -2, + [2][0][RTW89_WW][1][74] = -2, + [2][0][RTW89_WW][0][75] = -2, + [2][0][RTW89_WW][1][75] = -2, + [2][0][RTW89_WW][0][77] = -2, + [2][0][RTW89_WW][1][77] = -2, + [2][0][RTW89_WW][0][79] = -2, + [2][0][RTW89_WW][1][79] = -2, + [2][0][RTW89_WW][0][81] = -2, + [2][0][RTW89_WW][1][81] = -2, + [2][0][RTW89_WW][0][83] = -2, + [2][0][RTW89_WW][1][83] = -2, + [2][0][RTW89_WW][0][85] = -2, + [2][0][RTW89_WW][1][85] = -2, + [2][0][RTW89_WW][0][87] = -2, + [2][0][RTW89_WW][1][87] = -2, + [2][0][RTW89_WW][0][89] = -2, + [2][0][RTW89_WW][1][89] = -2, + [2][0][RTW89_WW][0][90] = -2, + [2][0][RTW89_WW][1][90] = -2, + [2][0][RTW89_WW][0][92] = -2, + [2][0][RTW89_WW][1][92] = -2, + [2][0][RTW89_WW][0][94] = -2, + [2][0][RTW89_WW][1][94] = -2, + [2][0][RTW89_WW][0][96] = -2, + [2][0][RTW89_WW][1][96] = -2, + [2][0][RTW89_WW][0][98] = -2, + [2][0][RTW89_WW][1][98] = -2, + [2][0][RTW89_WW][0][100] = -2, + [2][0][RTW89_WW][1][100] = -2, + [2][0][RTW89_WW][0][102] = -2, + [2][0][RTW89_WW][1][102] = -2, + [2][0][RTW89_WW][0][104] = -2, + [2][0][RTW89_WW][1][104] = -2, + [2][0][RTW89_WW][0][105] = -2, + [2][0][RTW89_WW][1][105] = -2, + [2][0][RTW89_WW][0][107] = -2, + [2][0][RTW89_WW][1][107] = -2, + [2][0][RTW89_WW][0][109] = 12, + [2][0][RTW89_WW][1][109] = 12, + [2][0][RTW89_WW][0][111] = 0, + [2][0][RTW89_WW][1][111] = 0, + [2][0][RTW89_WW][0][113] = 0, + [2][0][RTW89_WW][1][113] = 0, + [2][0][RTW89_WW][0][115] = 0, + [2][0][RTW89_WW][1][115] = 0, + [2][0][RTW89_WW][0][117] = 0, + [2][0][RTW89_WW][1][117] = 0, + [2][0][RTW89_WW][0][119] = 0, + [2][0][RTW89_WW][1][119] = 0, + [2][1][RTW89_WW][0][0] = -16, + [2][1][RTW89_WW][1][0] = -16, + [2][1][RTW89_WW][0][2] = -16, + [2][1][RTW89_WW][1][2] = -16, + [2][1][RTW89_WW][0][4] = -16, + [2][1][RTW89_WW][1][4] = -16, + [2][1][RTW89_WW][0][6] = -16, + [2][1][RTW89_WW][1][6] = -16, + [2][1][RTW89_WW][0][8] = -16, + [2][1][RTW89_WW][1][8] = -16, + [2][1][RTW89_WW][0][10] = -16, + [2][1][RTW89_WW][1][10] = -16, + [2][1][RTW89_WW][0][12] = -16, + [2][1][RTW89_WW][1][12] = -16, + [2][1][RTW89_WW][0][14] = -16, + [2][1][RTW89_WW][1][14] = -16, + [2][1][RTW89_WW][0][15] = -16, + [2][1][RTW89_WW][1][15] = -16, + [2][1][RTW89_WW][0][17] = -16, + [2][1][RTW89_WW][1][17] = -16, + [2][1][RTW89_WW][0][19] = -16, + [2][1][RTW89_WW][1][19] = -16, + [2][1][RTW89_WW][0][21] = -16, + [2][1][RTW89_WW][1][21] = -16, + [2][1][RTW89_WW][0][23] = -16, + [2][1][RTW89_WW][1][23] = -16, + [2][1][RTW89_WW][0][25] = -16, + [2][1][RTW89_WW][1][25] = -16, + [2][1][RTW89_WW][0][27] = -16, + [2][1][RTW89_WW][1][27] = -16, + [2][1][RTW89_WW][0][29] = -16, + [2][1][RTW89_WW][1][29] = -16, + [2][1][RTW89_WW][0][30] = -16, + [2][1][RTW89_WW][1][30] = -16, + [2][1][RTW89_WW][0][32] = -16, + [2][1][RTW89_WW][1][32] = -16, + [2][1][RTW89_WW][0][34] = -16, + [2][1][RTW89_WW][1][34] = -16, + [2][1][RTW89_WW][0][36] = -16, + [2][1][RTW89_WW][1][36] = -16, + [2][1][RTW89_WW][0][38] = -16, + [2][1][RTW89_WW][1][38] = -16, + [2][1][RTW89_WW][0][40] = -16, + [2][1][RTW89_WW][1][40] = -16, + [2][1][RTW89_WW][0][42] = -16, + [2][1][RTW89_WW][1][42] = -16, + [2][1][RTW89_WW][0][44] = -16, + [2][1][RTW89_WW][1][44] = -16, + [2][1][RTW89_WW][0][45] = -16, + [2][1][RTW89_WW][1][45] = -16, + [2][1][RTW89_WW][0][47] = -16, + [2][1][RTW89_WW][1][47] = -16, + [2][1][RTW89_WW][0][49] = -16, + [2][1][RTW89_WW][1][49] = -16, + [2][1][RTW89_WW][0][51] = -16, + [2][1][RTW89_WW][1][51] = -16, + [2][1][RTW89_WW][0][53] = -16, + [2][1][RTW89_WW][1][53] = -16, + [2][1][RTW89_WW][0][55] = -16, + [2][1][RTW89_WW][1][55] = -16, + [2][1][RTW89_WW][0][57] = -16, + [2][1][RTW89_WW][1][57] = -16, + [2][1][RTW89_WW][0][59] = -16, + [2][1][RTW89_WW][1][59] = -16, + [2][1][RTW89_WW][0][60] = -16, + [2][1][RTW89_WW][1][60] = -16, + [2][1][RTW89_WW][0][62] = -16, + [2][1][RTW89_WW][1][62] = -16, + [2][1][RTW89_WW][0][64] = -16, + [2][1][RTW89_WW][1][64] = -16, + [2][1][RTW89_WW][0][66] = -16, + [2][1][RTW89_WW][1][66] = -16, + [2][1][RTW89_WW][0][68] = -16, + [2][1][RTW89_WW][1][68] = -16, + [2][1][RTW89_WW][0][70] = -16, + [2][1][RTW89_WW][1][70] = -16, + [2][1][RTW89_WW][0][72] = -16, + [2][1][RTW89_WW][1][72] = -16, + [2][1][RTW89_WW][0][74] = -16, + [2][1][RTW89_WW][1][74] = -16, + [2][1][RTW89_WW][0][75] = -16, + [2][1][RTW89_WW][1][75] = -16, + [2][1][RTW89_WW][0][77] = -16, + [2][1][RTW89_WW][1][77] = -16, + [2][1][RTW89_WW][0][79] = -16, + [2][1][RTW89_WW][1][79] = -16, + [2][1][RTW89_WW][0][81] = -16, + [2][1][RTW89_WW][1][81] = -16, + [2][1][RTW89_WW][0][83] = -16, + [2][1][RTW89_WW][1][83] = -16, + [2][1][RTW89_WW][0][85] = -18, + [2][1][RTW89_WW][1][85] = -18, + [2][1][RTW89_WW][0][87] = -16, + [2][1][RTW89_WW][1][87] = -16, + [2][1][RTW89_WW][0][89] = -16, + [2][1][RTW89_WW][1][89] = -16, + [2][1][RTW89_WW][0][90] = -16, + [2][1][RTW89_WW][1][90] = -16, + [2][1][RTW89_WW][0][92] = -16, + [2][1][RTW89_WW][1][92] = -16, + [2][1][RTW89_WW][0][94] = -16, + [2][1][RTW89_WW][1][94] = -16, + [2][1][RTW89_WW][0][96] = -16, + [2][1][RTW89_WW][1][96] = -16, + [2][1][RTW89_WW][0][98] = -16, + [2][1][RTW89_WW][1][98] = -16, + [2][1][RTW89_WW][0][100] = -16, + [2][1][RTW89_WW][1][100] = -16, + [2][1][RTW89_WW][0][102] = -16, + [2][1][RTW89_WW][1][102] = -16, + [2][1][RTW89_WW][0][104] = -16, + [2][1][RTW89_WW][1][104] = -16, + [2][1][RTW89_WW][0][105] = -16, + [2][1][RTW89_WW][1][105] = -16, + [2][1][RTW89_WW][0][107] = -14, + [2][1][RTW89_WW][1][107] = -14, + [2][1][RTW89_WW][0][109] = -10, + [2][1][RTW89_WW][1][109] = -10, + [2][1][RTW89_WW][0][111] = 0, + [2][1][RTW89_WW][1][111] = 0, + [2][1][RTW89_WW][0][113] = 0, + [2][1][RTW89_WW][1][113] = 0, + [2][1][RTW89_WW][0][115] = 0, + [2][1][RTW89_WW][1][115] = 0, + [2][1][RTW89_WW][0][117] = 0, + [2][1][RTW89_WW][1][117] = 0, + [2][1][RTW89_WW][0][119] = 0, + [2][1][RTW89_WW][1][119] = 0, + [0][0][RTW89_FCC][1][0] = -16, + [0][0][RTW89_ETSI][1][0] = 32, + [0][0][RTW89_ETSI][0][0] = -8, + [0][0][RTW89_MKK][1][0] = 30, + [0][0][RTW89_MKK][0][0] = -8, + [0][0][RTW89_IC][1][0] = -16, + [0][0][RTW89_KCC][1][0] = -2, + [0][0][RTW89_KCC][0][0] = -2, + [0][0][RTW89_ACMA][1][0] = 32, + [0][0][RTW89_ACMA][0][0] = -8, + [0][0][RTW89_CHILE][1][0] = -16, + [0][0][RTW89_QATAR][1][0] = 32, + [0][0][RTW89_QATAR][0][0] = -8, + [0][0][RTW89_UK][1][0] = 32, + [0][0][RTW89_UK][0][0] = -8, + [0][0][RTW89_THAILAND][1][0] = 30, + [0][0][RTW89_THAILAND][0][0] = -16, + [0][0][RTW89_FCC][1][2] = -18, + [0][0][RTW89_ETSI][1][2] = 32, + [0][0][RTW89_ETSI][0][2] = -8, + [0][0][RTW89_MKK][1][2] = 30, + [0][0][RTW89_MKK][0][2] = -8, + [0][0][RTW89_IC][1][2] = -18, + [0][0][RTW89_KCC][1][2] = -2, + [0][0][RTW89_KCC][0][2] = -2, + [0][0][RTW89_ACMA][1][2] = 32, + [0][0][RTW89_ACMA][0][2] = -8, + [0][0][RTW89_CHILE][1][2] = -18, + [0][0][RTW89_QATAR][1][2] = 32, + [0][0][RTW89_QATAR][0][2] = -8, + [0][0][RTW89_UK][1][2] = 32, + [0][0][RTW89_UK][0][2] = -8, + [0][0][RTW89_THAILAND][1][2] = 30, + [0][0][RTW89_THAILAND][0][2] = -18, + [0][0][RTW89_FCC][1][4] = -18, + [0][0][RTW89_ETSI][1][4] = 32, + [0][0][RTW89_ETSI][0][4] = -8, + [0][0][RTW89_MKK][1][4] = 30, + [0][0][RTW89_MKK][0][4] = -8, + [0][0][RTW89_IC][1][4] = -18, + [0][0][RTW89_KCC][1][4] = -2, + [0][0][RTW89_KCC][0][4] = -2, + [0][0][RTW89_ACMA][1][4] = 32, + [0][0][RTW89_ACMA][0][4] = -8, + [0][0][RTW89_CHILE][1][4] = -18, + [0][0][RTW89_QATAR][1][4] = 32, + [0][0][RTW89_QATAR][0][4] = -8, + [0][0][RTW89_UK][1][4] = 32, + [0][0][RTW89_UK][0][4] = -8, + [0][0][RTW89_THAILAND][1][4] = 30, + [0][0][RTW89_THAILAND][0][4] = -18, + [0][0][RTW89_FCC][1][6] = -18, + [0][0][RTW89_ETSI][1][6] = 32, + [0][0][RTW89_ETSI][0][6] = -8, + [0][0][RTW89_MKK][1][6] = 30, + [0][0][RTW89_MKK][0][6] = -8, + [0][0][RTW89_IC][1][6] = -18, + [0][0][RTW89_KCC][1][6] = -2, + [0][0][RTW89_KCC][0][6] = -2, + [0][0][RTW89_ACMA][1][6] = 32, + [0][0][RTW89_ACMA][0][6] = -8, + [0][0][RTW89_CHILE][1][6] = -18, + [0][0][RTW89_QATAR][1][6] = 32, + [0][0][RTW89_QATAR][0][6] = -8, + [0][0][RTW89_UK][1][6] = 32, + [0][0][RTW89_UK][0][6] = -8, + [0][0][RTW89_THAILAND][1][6] = 30, + [0][0][RTW89_THAILAND][0][6] = -18, + [0][0][RTW89_FCC][1][8] = -18, + [0][0][RTW89_ETSI][1][8] = 32, + [0][0][RTW89_ETSI][0][8] = -8, + [0][0][RTW89_MKK][1][8] = 30, + [0][0][RTW89_MKK][0][8] = -8, + [0][0][RTW89_IC][1][8] = -18, + [0][0][RTW89_KCC][1][8] = -2, + [0][0][RTW89_KCC][0][8] = -2, + [0][0][RTW89_ACMA][1][8] = 32, + [0][0][RTW89_ACMA][0][8] = -8, + [0][0][RTW89_CHILE][1][8] = -18, + [0][0][RTW89_QATAR][1][8] = 32, + [0][0][RTW89_QATAR][0][8] = -8, + [0][0][RTW89_UK][1][8] = 32, + [0][0][RTW89_UK][0][8] = -8, + [0][0][RTW89_THAILAND][1][8] = 30, + [0][0][RTW89_THAILAND][0][8] = -18, + [0][0][RTW89_FCC][1][10] = -18, + [0][0][RTW89_ETSI][1][10] = 32, + [0][0][RTW89_ETSI][0][10] = -8, + [0][0][RTW89_MKK][1][10] = 30, + [0][0][RTW89_MKK][0][10] = -8, + [0][0][RTW89_IC][1][10] = -18, + [0][0][RTW89_KCC][1][10] = -2, + [0][0][RTW89_KCC][0][10] = -2, + [0][0][RTW89_ACMA][1][10] = 32, + [0][0][RTW89_ACMA][0][10] = -8, + [0][0][RTW89_CHILE][1][10] = -18, + [0][0][RTW89_QATAR][1][10] = 32, + [0][0][RTW89_QATAR][0][10] = -8, + [0][0][RTW89_UK][1][10] = 32, + [0][0][RTW89_UK][0][10] = -8, + [0][0][RTW89_THAILAND][1][10] = 30, + [0][0][RTW89_THAILAND][0][10] = -18, + [0][0][RTW89_FCC][1][12] = -18, + [0][0][RTW89_ETSI][1][12] = 32, + [0][0][RTW89_ETSI][0][12] = -8, + [0][0][RTW89_MKK][1][12] = 30, + [0][0][RTW89_MKK][0][12] = -8, + [0][0][RTW89_IC][1][12] = -18, + [0][0][RTW89_KCC][1][12] = -2, + [0][0][RTW89_KCC][0][12] = -2, + [0][0][RTW89_ACMA][1][12] = 32, + [0][0][RTW89_ACMA][0][12] = -8, + [0][0][RTW89_CHILE][1][12] = -18, + [0][0][RTW89_QATAR][1][12] = 32, + [0][0][RTW89_QATAR][0][12] = -8, + [0][0][RTW89_UK][1][12] = 32, + [0][0][RTW89_UK][0][12] = -8, + [0][0][RTW89_THAILAND][1][12] = 30, + [0][0][RTW89_THAILAND][0][12] = -18, + [0][0][RTW89_FCC][1][14] = -18, + [0][0][RTW89_ETSI][1][14] = 32, + [0][0][RTW89_ETSI][0][14] = -8, + [0][0][RTW89_MKK][1][14] = 30, + [0][0][RTW89_MKK][0][14] = -8, + [0][0][RTW89_IC][1][14] = -18, + [0][0][RTW89_KCC][1][14] = -2, + [0][0][RTW89_KCC][0][14] = -2, + [0][0][RTW89_ACMA][1][14] = 32, + [0][0][RTW89_ACMA][0][14] = -8, + [0][0][RTW89_CHILE][1][14] = -18, + [0][0][RTW89_QATAR][1][14] = 32, + [0][0][RTW89_QATAR][0][14] = -8, + [0][0][RTW89_UK][1][14] = 32, + [0][0][RTW89_UK][0][14] = -8, + [0][0][RTW89_THAILAND][1][14] = 30, + [0][0][RTW89_THAILAND][0][14] = -18, + [0][0][RTW89_FCC][1][15] = -18, + [0][0][RTW89_ETSI][1][15] = 32, + [0][0][RTW89_ETSI][0][15] = -8, + [0][0][RTW89_MKK][1][15] = 30, + [0][0][RTW89_MKK][0][15] = -8, + [0][0][RTW89_IC][1][15] = -18, + [0][0][RTW89_KCC][1][15] = -2, + [0][0][RTW89_KCC][0][15] = -2, + [0][0][RTW89_ACMA][1][15] = 32, + [0][0][RTW89_ACMA][0][15] = -8, + [0][0][RTW89_CHILE][1][15] = -18, + [0][0][RTW89_QATAR][1][15] = 32, + [0][0][RTW89_QATAR][0][15] = -8, + [0][0][RTW89_UK][1][15] = 32, + [0][0][RTW89_UK][0][15] = -8, + [0][0][RTW89_THAILAND][1][15] = 30, + [0][0][RTW89_THAILAND][0][15] = -18, + [0][0][RTW89_FCC][1][17] = -18, + [0][0][RTW89_ETSI][1][17] = 32, + [0][0][RTW89_ETSI][0][17] = -8, + [0][0][RTW89_MKK][1][17] = 30, + [0][0][RTW89_MKK][0][17] = -8, + [0][0][RTW89_IC][1][17] = -18, + [0][0][RTW89_KCC][1][17] = -2, + [0][0][RTW89_KCC][0][17] = -2, + [0][0][RTW89_ACMA][1][17] = 32, + [0][0][RTW89_ACMA][0][17] = -8, + [0][0][RTW89_CHILE][1][17] = -18, + [0][0][RTW89_QATAR][1][17] = 32, + [0][0][RTW89_QATAR][0][17] = -8, + [0][0][RTW89_UK][1][17] = 32, + [0][0][RTW89_UK][0][17] = -8, + [0][0][RTW89_THAILAND][1][17] = 30, + [0][0][RTW89_THAILAND][0][17] = -18, + [0][0][RTW89_FCC][1][19] = -18, + [0][0][RTW89_ETSI][1][19] = 32, + [0][0][RTW89_ETSI][0][19] = -8, + [0][0][RTW89_MKK][1][19] = 30, + [0][0][RTW89_MKK][0][19] = -8, + [0][0][RTW89_IC][1][19] = -18, + [0][0][RTW89_KCC][1][19] = -2, + [0][0][RTW89_KCC][0][19] = -2, + [0][0][RTW89_ACMA][1][19] = 32, + [0][0][RTW89_ACMA][0][19] = -8, + [0][0][RTW89_CHILE][1][19] = -18, + [0][0][RTW89_QATAR][1][19] = 32, + [0][0][RTW89_QATAR][0][19] = -8, + [0][0][RTW89_UK][1][19] = 32, + [0][0][RTW89_UK][0][19] = -8, + [0][0][RTW89_THAILAND][1][19] = 30, + [0][0][RTW89_THAILAND][0][19] = -18, + [0][0][RTW89_FCC][1][21] = -18, + [0][0][RTW89_ETSI][1][21] = 32, + [0][0][RTW89_ETSI][0][21] = -8, + [0][0][RTW89_MKK][1][21] = 30, + [0][0][RTW89_MKK][0][21] = -8, + [0][0][RTW89_IC][1][21] = -18, + [0][0][RTW89_KCC][1][21] = -2, + [0][0][RTW89_KCC][0][21] = -2, + [0][0][RTW89_ACMA][1][21] = 32, + [0][0][RTW89_ACMA][0][21] = -8, + [0][0][RTW89_CHILE][1][21] = -18, + [0][0][RTW89_QATAR][1][21] = 32, + [0][0][RTW89_QATAR][0][21] = -8, + [0][0][RTW89_UK][1][21] = 32, + [0][0][RTW89_UK][0][21] = -8, + [0][0][RTW89_THAILAND][1][21] = 30, + [0][0][RTW89_THAILAND][0][21] = -18, + [0][0][RTW89_FCC][1][23] = -18, + [0][0][RTW89_ETSI][1][23] = 32, + [0][0][RTW89_ETSI][0][23] = -8, + [0][0][RTW89_MKK][1][23] = 30, + [0][0][RTW89_MKK][0][23] = -8, + [0][0][RTW89_IC][1][23] = -18, + [0][0][RTW89_KCC][1][23] = -2, + [0][0][RTW89_KCC][0][23] = -2, + [0][0][RTW89_ACMA][1][23] = 32, + [0][0][RTW89_ACMA][0][23] = -8, + [0][0][RTW89_CHILE][1][23] = -18, + [0][0][RTW89_QATAR][1][23] = 32, + [0][0][RTW89_QATAR][0][23] = -8, + [0][0][RTW89_UK][1][23] = 32, + [0][0][RTW89_UK][0][23] = -8, + [0][0][RTW89_THAILAND][1][23] = 30, + [0][0][RTW89_THAILAND][0][23] = -18, + [0][0][RTW89_FCC][1][25] = -18, + [0][0][RTW89_ETSI][1][25] = 32, + [0][0][RTW89_ETSI][0][25] = -8, + [0][0][RTW89_MKK][1][25] = 30, + [0][0][RTW89_MKK][0][25] = -8, + [0][0][RTW89_IC][1][25] = -18, + [0][0][RTW89_KCC][1][25] = -2, + [0][0][RTW89_KCC][0][25] = -2, + [0][0][RTW89_ACMA][1][25] = 32, + [0][0][RTW89_ACMA][0][25] = -8, + [0][0][RTW89_CHILE][1][25] = -18, + [0][0][RTW89_QATAR][1][25] = 32, + [0][0][RTW89_QATAR][0][25] = -8, + [0][0][RTW89_UK][1][25] = 32, + [0][0][RTW89_UK][0][25] = -8, + [0][0][RTW89_THAILAND][1][25] = 30, + [0][0][RTW89_THAILAND][0][25] = -18, + [0][0][RTW89_FCC][1][27] = -18, + [0][0][RTW89_ETSI][1][27] = 32, + [0][0][RTW89_ETSI][0][27] = -8, + [0][0][RTW89_MKK][1][27] = 30, + [0][0][RTW89_MKK][0][27] = -8, + [0][0][RTW89_IC][1][27] = -18, + [0][0][RTW89_KCC][1][27] = -2, + [0][0][RTW89_KCC][0][27] = -2, + [0][0][RTW89_ACMA][1][27] = 32, + [0][0][RTW89_ACMA][0][27] = -8, + [0][0][RTW89_CHILE][1][27] = -18, + [0][0][RTW89_QATAR][1][27] = 32, + [0][0][RTW89_QATAR][0][27] = -8, + [0][0][RTW89_UK][1][27] = 32, + [0][0][RTW89_UK][0][27] = -8, + [0][0][RTW89_THAILAND][1][27] = 30, + [0][0][RTW89_THAILAND][0][27] = -18, + [0][0][RTW89_FCC][1][29] = -18, + [0][0][RTW89_ETSI][1][29] = 32, + [0][0][RTW89_ETSI][0][29] = -8, + [0][0][RTW89_MKK][1][29] = 30, + [0][0][RTW89_MKK][0][29] = -8, + [0][0][RTW89_IC][1][29] = -18, + [0][0][RTW89_KCC][1][29] = -2, + [0][0][RTW89_KCC][0][29] = -2, + [0][0][RTW89_ACMA][1][29] = 32, + [0][0][RTW89_ACMA][0][29] = -8, + [0][0][RTW89_CHILE][1][29] = -18, + [0][0][RTW89_QATAR][1][29] = 32, + [0][0][RTW89_QATAR][0][29] = -8, + [0][0][RTW89_UK][1][29] = 32, + [0][0][RTW89_UK][0][29] = -8, + [0][0][RTW89_THAILAND][1][29] = 30, + [0][0][RTW89_THAILAND][0][29] = -18, + [0][0][RTW89_FCC][1][30] = -18, + [0][0][RTW89_ETSI][1][30] = 32, + [0][0][RTW89_ETSI][0][30] = -8, + [0][0][RTW89_MKK][1][30] = 30, + [0][0][RTW89_MKK][0][30] = -8, + [0][0][RTW89_IC][1][30] = -18, + [0][0][RTW89_KCC][1][30] = -2, + [0][0][RTW89_KCC][0][30] = -2, + [0][0][RTW89_ACMA][1][30] = 32, + [0][0][RTW89_ACMA][0][30] = -8, + [0][0][RTW89_CHILE][1][30] = -18, + [0][0][RTW89_QATAR][1][30] = 32, + [0][0][RTW89_QATAR][0][30] = -8, + [0][0][RTW89_UK][1][30] = 32, + [0][0][RTW89_UK][0][30] = -8, + [0][0][RTW89_THAILAND][1][30] = 30, + [0][0][RTW89_THAILAND][0][30] = -18, + [0][0][RTW89_FCC][1][32] = -18, + [0][0][RTW89_ETSI][1][32] = 32, + [0][0][RTW89_ETSI][0][32] = -8, + [0][0][RTW89_MKK][1][32] = 30, + [0][0][RTW89_MKK][0][32] = -8, + [0][0][RTW89_IC][1][32] = -18, + [0][0][RTW89_KCC][1][32] = -2, + [0][0][RTW89_KCC][0][32] = -2, + [0][0][RTW89_ACMA][1][32] = 32, + [0][0][RTW89_ACMA][0][32] = -8, + [0][0][RTW89_CHILE][1][32] = -18, + [0][0][RTW89_QATAR][1][32] = 32, + [0][0][RTW89_QATAR][0][32] = -8, + [0][0][RTW89_UK][1][32] = 32, + [0][0][RTW89_UK][0][32] = -8, + [0][0][RTW89_THAILAND][1][32] = 30, + [0][0][RTW89_THAILAND][0][32] = -18, + [0][0][RTW89_FCC][1][34] = -18, + [0][0][RTW89_ETSI][1][34] = 32, + [0][0][RTW89_ETSI][0][34] = -8, + [0][0][RTW89_MKK][1][34] = 30, + [0][0][RTW89_MKK][0][34] = -8, + [0][0][RTW89_IC][1][34] = -18, + [0][0][RTW89_KCC][1][34] = -2, + [0][0][RTW89_KCC][0][34] = -2, + [0][0][RTW89_ACMA][1][34] = 32, + [0][0][RTW89_ACMA][0][34] = -8, + [0][0][RTW89_CHILE][1][34] = -18, + [0][0][RTW89_QATAR][1][34] = 32, + [0][0][RTW89_QATAR][0][34] = -8, + [0][0][RTW89_UK][1][34] = 32, + [0][0][RTW89_UK][0][34] = -8, + [0][0][RTW89_THAILAND][1][34] = 30, + [0][0][RTW89_THAILAND][0][34] = -18, + [0][0][RTW89_FCC][1][36] = -18, + [0][0][RTW89_ETSI][1][36] = 32, + [0][0][RTW89_ETSI][0][36] = -8, + [0][0][RTW89_MKK][1][36] = 30, + [0][0][RTW89_MKK][0][36] = -8, + [0][0][RTW89_IC][1][36] = -18, + [0][0][RTW89_KCC][1][36] = -2, + [0][0][RTW89_KCC][0][36] = -2, + [0][0][RTW89_ACMA][1][36] = 32, + [0][0][RTW89_ACMA][0][36] = -8, + [0][0][RTW89_CHILE][1][36] = -18, + [0][0][RTW89_QATAR][1][36] = 32, + [0][0][RTW89_QATAR][0][36] = -8, + [0][0][RTW89_UK][1][36] = 32, + [0][0][RTW89_UK][0][36] = -8, + [0][0][RTW89_THAILAND][1][36] = 30, + [0][0][RTW89_THAILAND][0][36] = -18, + [0][0][RTW89_FCC][1][38] = -18, + [0][0][RTW89_ETSI][1][38] = 32, + [0][0][RTW89_ETSI][0][38] = -8, + [0][0][RTW89_MKK][1][38] = 30, + [0][0][RTW89_MKK][0][38] = -8, + [0][0][RTW89_IC][1][38] = -18, + [0][0][RTW89_KCC][1][38] = -2, + [0][0][RTW89_KCC][0][38] = -2, + [0][0][RTW89_ACMA][1][38] = 32, + [0][0][RTW89_ACMA][0][38] = -8, + [0][0][RTW89_CHILE][1][38] = -18, + [0][0][RTW89_QATAR][1][38] = 32, + [0][0][RTW89_QATAR][0][38] = -8, + [0][0][RTW89_UK][1][38] = 32, + [0][0][RTW89_UK][0][38] = -8, + [0][0][RTW89_THAILAND][1][38] = 30, + [0][0][RTW89_THAILAND][0][38] = -18, + [0][0][RTW89_FCC][1][40] = -18, + [0][0][RTW89_ETSI][1][40] = 32, + [0][0][RTW89_ETSI][0][40] = -8, + [0][0][RTW89_MKK][1][40] = 30, + [0][0][RTW89_MKK][0][40] = -8, + [0][0][RTW89_IC][1][40] = -18, + [0][0][RTW89_KCC][1][40] = -2, + [0][0][RTW89_KCC][0][40] = -2, + [0][0][RTW89_ACMA][1][40] = 32, + [0][0][RTW89_ACMA][0][40] = -8, + [0][0][RTW89_CHILE][1][40] = -18, + [0][0][RTW89_QATAR][1][40] = 32, + [0][0][RTW89_QATAR][0][40] = -8, + [0][0][RTW89_UK][1][40] = 32, + [0][0][RTW89_UK][0][40] = -8, + [0][0][RTW89_THAILAND][1][40] = 30, + [0][0][RTW89_THAILAND][0][40] = -18, + [0][0][RTW89_FCC][1][42] = -18, + [0][0][RTW89_ETSI][1][42] = 32, + [0][0][RTW89_ETSI][0][42] = -8, + [0][0][RTW89_MKK][1][42] = 30, + [0][0][RTW89_MKK][0][42] = -8, + [0][0][RTW89_IC][1][42] = -18, + [0][0][RTW89_KCC][1][42] = -2, + [0][0][RTW89_KCC][0][42] = -2, + [0][0][RTW89_ACMA][1][42] = 32, + [0][0][RTW89_ACMA][0][42] = -8, + [0][0][RTW89_CHILE][1][42] = -18, + [0][0][RTW89_QATAR][1][42] = 32, + [0][0][RTW89_QATAR][0][42] = -8, + [0][0][RTW89_UK][1][42] = 32, + [0][0][RTW89_UK][0][42] = -8, + [0][0][RTW89_THAILAND][1][42] = 30, + [0][0][RTW89_THAILAND][0][42] = -18, + [0][0][RTW89_FCC][1][44] = -16, + [0][0][RTW89_ETSI][1][44] = 32, + [0][0][RTW89_ETSI][0][44] = -6, + [0][0][RTW89_MKK][1][44] = 8, + [0][0][RTW89_MKK][0][44] = -10, + [0][0][RTW89_IC][1][44] = -16, + [0][0][RTW89_KCC][1][44] = -2, + [0][0][RTW89_KCC][0][44] = -2, + [0][0][RTW89_ACMA][1][44] = 32, + [0][0][RTW89_ACMA][0][44] = -6, + [0][0][RTW89_CHILE][1][44] = -16, + [0][0][RTW89_QATAR][1][44] = 32, + [0][0][RTW89_QATAR][0][44] = -6, + [0][0][RTW89_UK][1][44] = 32, + [0][0][RTW89_UK][0][44] = -6, + [0][0][RTW89_THAILAND][1][44] = 30, + [0][0][RTW89_THAILAND][0][44] = -16, + [0][0][RTW89_FCC][1][45] = -16, + [0][0][RTW89_ETSI][1][45] = 127, + [0][0][RTW89_ETSI][0][45] = 127, + [0][0][RTW89_MKK][1][45] = 127, + [0][0][RTW89_MKK][0][45] = 127, + [0][0][RTW89_IC][1][45] = -16, + [0][0][RTW89_KCC][1][45] = -2, + [0][0][RTW89_KCC][0][45] = 127, + [0][0][RTW89_ACMA][1][45] = 127, + [0][0][RTW89_ACMA][0][45] = 127, + [0][0][RTW89_CHILE][1][45] = 127, + [0][0][RTW89_QATAR][1][45] = 127, + [0][0][RTW89_QATAR][0][45] = 127, + [0][0][RTW89_UK][1][45] = 127, + [0][0][RTW89_UK][0][45] = 127, + [0][0][RTW89_THAILAND][1][45] = 127, + [0][0][RTW89_THAILAND][0][45] = 127, + [0][0][RTW89_FCC][1][47] = -18, + [0][0][RTW89_ETSI][1][47] = 127, + [0][0][RTW89_ETSI][0][47] = 127, + [0][0][RTW89_MKK][1][47] = 127, + [0][0][RTW89_MKK][0][47] = 127, + [0][0][RTW89_IC][1][47] = -18, + [0][0][RTW89_KCC][1][47] = -2, + [0][0][RTW89_KCC][0][47] = 127, + [0][0][RTW89_ACMA][1][47] = 127, + [0][0][RTW89_ACMA][0][47] = 127, + [0][0][RTW89_CHILE][1][47] = 127, + [0][0][RTW89_QATAR][1][47] = 127, + [0][0][RTW89_QATAR][0][47] = 127, + [0][0][RTW89_UK][1][47] = 127, + [0][0][RTW89_UK][0][47] = 127, + [0][0][RTW89_THAILAND][1][47] = 127, + [0][0][RTW89_THAILAND][0][47] = 127, + [0][0][RTW89_FCC][1][49] = -18, + [0][0][RTW89_ETSI][1][49] = 127, + [0][0][RTW89_ETSI][0][49] = 127, + [0][0][RTW89_MKK][1][49] = 127, + [0][0][RTW89_MKK][0][49] = 127, + [0][0][RTW89_IC][1][49] = -18, + [0][0][RTW89_KCC][1][49] = -2, + [0][0][RTW89_KCC][0][49] = 127, + [0][0][RTW89_ACMA][1][49] = 127, + [0][0][RTW89_ACMA][0][49] = 127, + [0][0][RTW89_CHILE][1][49] = 127, + [0][0][RTW89_QATAR][1][49] = 127, + [0][0][RTW89_QATAR][0][49] = 127, + [0][0][RTW89_UK][1][49] = 127, + [0][0][RTW89_UK][0][49] = 127, + [0][0][RTW89_THAILAND][1][49] = 127, + [0][0][RTW89_THAILAND][0][49] = 127, + [0][0][RTW89_FCC][1][51] = -18, + [0][0][RTW89_ETSI][1][51] = 127, + [0][0][RTW89_ETSI][0][51] = 127, + [0][0][RTW89_MKK][1][51] = 127, + [0][0][RTW89_MKK][0][51] = 127, + [0][0][RTW89_IC][1][51] = -18, + [0][0][RTW89_KCC][1][51] = -2, + [0][0][RTW89_KCC][0][51] = 127, + [0][0][RTW89_ACMA][1][51] = 127, + [0][0][RTW89_ACMA][0][51] = 127, + [0][0][RTW89_CHILE][1][51] = 127, + [0][0][RTW89_QATAR][1][51] = 127, + [0][0][RTW89_QATAR][0][51] = 127, + [0][0][RTW89_UK][1][51] = 127, + [0][0][RTW89_UK][0][51] = 127, + [0][0][RTW89_THAILAND][1][51] = 127, + [0][0][RTW89_THAILAND][0][51] = 127, + [0][0][RTW89_FCC][1][53] = -16, + [0][0][RTW89_ETSI][1][53] = 127, + [0][0][RTW89_ETSI][0][53] = 127, + [0][0][RTW89_MKK][1][53] = 127, + [0][0][RTW89_MKK][0][53] = 127, + [0][0][RTW89_IC][1][53] = -16, + [0][0][RTW89_KCC][1][53] = -2, + [0][0][RTW89_KCC][0][53] = 127, + [0][0][RTW89_ACMA][1][53] = 127, + [0][0][RTW89_ACMA][0][53] = 127, + [0][0][RTW89_CHILE][1][53] = 127, + [0][0][RTW89_QATAR][1][53] = 127, + [0][0][RTW89_QATAR][0][53] = 127, + [0][0][RTW89_UK][1][53] = 127, + [0][0][RTW89_UK][0][53] = 127, + [0][0][RTW89_THAILAND][1][53] = 127, + [0][0][RTW89_THAILAND][0][53] = 127, + [0][0][RTW89_FCC][1][55] = -18, + [0][0][RTW89_ETSI][1][55] = 127, + [0][0][RTW89_ETSI][0][55] = 127, + [0][0][RTW89_MKK][1][55] = 127, + [0][0][RTW89_MKK][0][55] = 127, + [0][0][RTW89_IC][1][55] = -18, + [0][0][RTW89_KCC][1][55] = -2, + [0][0][RTW89_KCC][0][55] = 127, + [0][0][RTW89_ACMA][1][55] = 127, + [0][0][RTW89_ACMA][0][55] = 127, + [0][0][RTW89_CHILE][1][55] = 127, + [0][0][RTW89_QATAR][1][55] = 127, + [0][0][RTW89_QATAR][0][55] = 127, + [0][0][RTW89_UK][1][55] = 127, + [0][0][RTW89_UK][0][55] = 127, + [0][0][RTW89_THAILAND][1][55] = 127, + [0][0][RTW89_THAILAND][0][55] = 127, + [0][0][RTW89_FCC][1][57] = -18, + [0][0][RTW89_ETSI][1][57] = 127, + [0][0][RTW89_ETSI][0][57] = 127, + [0][0][RTW89_MKK][1][57] = 127, + [0][0][RTW89_MKK][0][57] = 127, + [0][0][RTW89_IC][1][57] = -18, + [0][0][RTW89_KCC][1][57] = -2, + [0][0][RTW89_KCC][0][57] = 127, + [0][0][RTW89_ACMA][1][57] = 127, + [0][0][RTW89_ACMA][0][57] = 127, + [0][0][RTW89_CHILE][1][57] = 127, + [0][0][RTW89_QATAR][1][57] = 127, + [0][0][RTW89_QATAR][0][57] = 127, + [0][0][RTW89_UK][1][57] = 127, + [0][0][RTW89_UK][0][57] = 127, + [0][0][RTW89_THAILAND][1][57] = 127, + [0][0][RTW89_THAILAND][0][57] = 127, + [0][0][RTW89_FCC][1][59] = -18, + [0][0][RTW89_ETSI][1][59] = 127, + [0][0][RTW89_ETSI][0][59] = 127, + [0][0][RTW89_MKK][1][59] = 127, + [0][0][RTW89_MKK][0][59] = 127, + [0][0][RTW89_IC][1][59] = -18, + [0][0][RTW89_KCC][1][59] = -2, + [0][0][RTW89_KCC][0][59] = 127, + [0][0][RTW89_ACMA][1][59] = 127, + [0][0][RTW89_ACMA][0][59] = 127, + [0][0][RTW89_CHILE][1][59] = 127, + [0][0][RTW89_QATAR][1][59] = 127, + [0][0][RTW89_QATAR][0][59] = 127, + [0][0][RTW89_UK][1][59] = 127, + [0][0][RTW89_UK][0][59] = 127, + [0][0][RTW89_THAILAND][1][59] = 127, + [0][0][RTW89_THAILAND][0][59] = 127, + [0][0][RTW89_FCC][1][60] = -18, + [0][0][RTW89_ETSI][1][60] = 127, + [0][0][RTW89_ETSI][0][60] = 127, + [0][0][RTW89_MKK][1][60] = 127, + [0][0][RTW89_MKK][0][60] = 127, + [0][0][RTW89_IC][1][60] = -18, + [0][0][RTW89_KCC][1][60] = -2, + [0][0][RTW89_KCC][0][60] = 127, + [0][0][RTW89_ACMA][1][60] = 127, + [0][0][RTW89_ACMA][0][60] = 127, + [0][0][RTW89_CHILE][1][60] = 127, + [0][0][RTW89_QATAR][1][60] = 127, + [0][0][RTW89_QATAR][0][60] = 127, + [0][0][RTW89_UK][1][60] = 127, + [0][0][RTW89_UK][0][60] = 127, + [0][0][RTW89_THAILAND][1][60] = 127, + [0][0][RTW89_THAILAND][0][60] = 127, + [0][0][RTW89_FCC][1][62] = -18, + [0][0][RTW89_ETSI][1][62] = 127, + [0][0][RTW89_ETSI][0][62] = 127, + [0][0][RTW89_MKK][1][62] = 127, + [0][0][RTW89_MKK][0][62] = 127, + [0][0][RTW89_IC][1][62] = -18, + [0][0][RTW89_KCC][1][62] = -2, + [0][0][RTW89_KCC][0][62] = 127, + [0][0][RTW89_ACMA][1][62] = 127, + [0][0][RTW89_ACMA][0][62] = 127, + [0][0][RTW89_CHILE][1][62] = 127, + [0][0][RTW89_QATAR][1][62] = 127, + [0][0][RTW89_QATAR][0][62] = 127, + [0][0][RTW89_UK][1][62] = 127, + [0][0][RTW89_UK][0][62] = 127, + [0][0][RTW89_THAILAND][1][62] = 127, + [0][0][RTW89_THAILAND][0][62] = 127, + [0][0][RTW89_FCC][1][64] = -18, + [0][0][RTW89_ETSI][1][64] = 127, + [0][0][RTW89_ETSI][0][64] = 127, + [0][0][RTW89_MKK][1][64] = 127, + [0][0][RTW89_MKK][0][64] = 127, + [0][0][RTW89_IC][1][64] = -18, + [0][0][RTW89_KCC][1][64] = -2, + [0][0][RTW89_KCC][0][64] = 127, + [0][0][RTW89_ACMA][1][64] = 127, + [0][0][RTW89_ACMA][0][64] = 127, + [0][0][RTW89_CHILE][1][64] = 127, + [0][0][RTW89_QATAR][1][64] = 127, + [0][0][RTW89_QATAR][0][64] = 127, + [0][0][RTW89_UK][1][64] = 127, + [0][0][RTW89_UK][0][64] = 127, + [0][0][RTW89_THAILAND][1][64] = 127, + [0][0][RTW89_THAILAND][0][64] = 127, + [0][0][RTW89_FCC][1][66] = -18, + [0][0][RTW89_ETSI][1][66] = 127, + [0][0][RTW89_ETSI][0][66] = 127, + [0][0][RTW89_MKK][1][66] = 127, + [0][0][RTW89_MKK][0][66] = 127, + [0][0][RTW89_IC][1][66] = -18, + [0][0][RTW89_KCC][1][66] = -2, + [0][0][RTW89_KCC][0][66] = 127, + [0][0][RTW89_ACMA][1][66] = 127, + [0][0][RTW89_ACMA][0][66] = 127, + [0][0][RTW89_CHILE][1][66] = 127, + [0][0][RTW89_QATAR][1][66] = 127, + [0][0][RTW89_QATAR][0][66] = 127, + [0][0][RTW89_UK][1][66] = 127, + [0][0][RTW89_UK][0][66] = 127, + [0][0][RTW89_THAILAND][1][66] = 127, + [0][0][RTW89_THAILAND][0][66] = 127, + [0][0][RTW89_FCC][1][68] = -18, + [0][0][RTW89_ETSI][1][68] = 127, + [0][0][RTW89_ETSI][0][68] = 127, + [0][0][RTW89_MKK][1][68] = 127, + [0][0][RTW89_MKK][0][68] = 127, + [0][0][RTW89_IC][1][68] = -18, + [0][0][RTW89_KCC][1][68] = -2, + [0][0][RTW89_KCC][0][68] = 127, + [0][0][RTW89_ACMA][1][68] = 127, + [0][0][RTW89_ACMA][0][68] = 127, + [0][0][RTW89_CHILE][1][68] = 127, + [0][0][RTW89_QATAR][1][68] = 127, + [0][0][RTW89_QATAR][0][68] = 127, + [0][0][RTW89_UK][1][68] = 127, + [0][0][RTW89_UK][0][68] = 127, + [0][0][RTW89_THAILAND][1][68] = 127, + [0][0][RTW89_THAILAND][0][68] = 127, + [0][0][RTW89_FCC][1][70] = -16, + [0][0][RTW89_ETSI][1][70] = 127, + [0][0][RTW89_ETSI][0][70] = 127, + [0][0][RTW89_MKK][1][70] = 127, + [0][0][RTW89_MKK][0][70] = 127, + [0][0][RTW89_IC][1][70] = -16, + [0][0][RTW89_KCC][1][70] = -2, + [0][0][RTW89_KCC][0][70] = 127, + [0][0][RTW89_ACMA][1][70] = 127, + [0][0][RTW89_ACMA][0][70] = 127, + [0][0][RTW89_CHILE][1][70] = 127, + [0][0][RTW89_QATAR][1][70] = 127, + [0][0][RTW89_QATAR][0][70] = 127, + [0][0][RTW89_UK][1][70] = 127, + [0][0][RTW89_UK][0][70] = 127, + [0][0][RTW89_THAILAND][1][70] = 127, + [0][0][RTW89_THAILAND][0][70] = 127, + [0][0][RTW89_FCC][1][72] = -18, + [0][0][RTW89_ETSI][1][72] = 127, + [0][0][RTW89_ETSI][0][72] = 127, + [0][0][RTW89_MKK][1][72] = 127, + [0][0][RTW89_MKK][0][72] = 127, + [0][0][RTW89_IC][1][72] = -18, + [0][0][RTW89_KCC][1][72] = -2, + [0][0][RTW89_KCC][0][72] = 127, + [0][0][RTW89_ACMA][1][72] = 127, + [0][0][RTW89_ACMA][0][72] = 127, + [0][0][RTW89_CHILE][1][72] = 127, + [0][0][RTW89_QATAR][1][72] = 127, + [0][0][RTW89_QATAR][0][72] = 127, + [0][0][RTW89_UK][1][72] = 127, + [0][0][RTW89_UK][0][72] = 127, + [0][0][RTW89_THAILAND][1][72] = 127, + [0][0][RTW89_THAILAND][0][72] = 127, + [0][0][RTW89_FCC][1][74] = -18, + [0][0][RTW89_ETSI][1][74] = 127, + [0][0][RTW89_ETSI][0][74] = 127, + [0][0][RTW89_MKK][1][74] = 127, + [0][0][RTW89_MKK][0][74] = 127, + [0][0][RTW89_IC][1][74] = -18, + [0][0][RTW89_KCC][1][74] = -2, + [0][0][RTW89_KCC][0][74] = 127, + [0][0][RTW89_ACMA][1][74] = 127, + [0][0][RTW89_ACMA][0][74] = 127, + [0][0][RTW89_CHILE][1][74] = 127, + [0][0][RTW89_QATAR][1][74] = 127, + [0][0][RTW89_QATAR][0][74] = 127, + [0][0][RTW89_UK][1][74] = 127, + [0][0][RTW89_UK][0][74] = 127, + [0][0][RTW89_THAILAND][1][74] = 127, + [0][0][RTW89_THAILAND][0][74] = 127, + [0][0][RTW89_FCC][1][75] = -18, + [0][0][RTW89_ETSI][1][75] = 127, + [0][0][RTW89_ETSI][0][75] = 127, + [0][0][RTW89_MKK][1][75] = 127, + [0][0][RTW89_MKK][0][75] = 127, + [0][0][RTW89_IC][1][75] = -18, + [0][0][RTW89_KCC][1][75] = -2, + [0][0][RTW89_KCC][0][75] = 127, + [0][0][RTW89_ACMA][1][75] = 127, + [0][0][RTW89_ACMA][0][75] = 127, + [0][0][RTW89_CHILE][1][75] = 127, + [0][0][RTW89_QATAR][1][75] = 127, + [0][0][RTW89_QATAR][0][75] = 127, + [0][0][RTW89_UK][1][75] = 127, + [0][0][RTW89_UK][0][75] = 127, + [0][0][RTW89_THAILAND][1][75] = 127, + [0][0][RTW89_THAILAND][0][75] = 127, + [0][0][RTW89_FCC][1][77] = -18, + [0][0][RTW89_ETSI][1][77] = 127, + [0][0][RTW89_ETSI][0][77] = 127, + [0][0][RTW89_MKK][1][77] = 127, + [0][0][RTW89_MKK][0][77] = 127, + [0][0][RTW89_IC][1][77] = -18, + [0][0][RTW89_KCC][1][77] = -2, + [0][0][RTW89_KCC][0][77] = 127, + [0][0][RTW89_ACMA][1][77] = 127, + [0][0][RTW89_ACMA][0][77] = 127, + [0][0][RTW89_CHILE][1][77] = 127, + [0][0][RTW89_QATAR][1][77] = 127, + [0][0][RTW89_QATAR][0][77] = 127, + [0][0][RTW89_UK][1][77] = 127, + [0][0][RTW89_UK][0][77] = 127, + [0][0][RTW89_THAILAND][1][77] = 127, + [0][0][RTW89_THAILAND][0][77] = 127, + [0][0][RTW89_FCC][1][79] = -18, + [0][0][RTW89_ETSI][1][79] = 127, + [0][0][RTW89_ETSI][0][79] = 127, + [0][0][RTW89_MKK][1][79] = 127, + [0][0][RTW89_MKK][0][79] = 127, + [0][0][RTW89_IC][1][79] = -18, + [0][0][RTW89_KCC][1][79] = -2, + [0][0][RTW89_KCC][0][79] = 127, + [0][0][RTW89_ACMA][1][79] = 127, + [0][0][RTW89_ACMA][0][79] = 127, + [0][0][RTW89_CHILE][1][79] = 127, + [0][0][RTW89_QATAR][1][79] = 127, + [0][0][RTW89_QATAR][0][79] = 127, + [0][0][RTW89_UK][1][79] = 127, + [0][0][RTW89_UK][0][79] = 127, + [0][0][RTW89_THAILAND][1][79] = 127, + [0][0][RTW89_THAILAND][0][79] = 127, + [0][0][RTW89_FCC][1][81] = -18, + [0][0][RTW89_ETSI][1][81] = 127, + [0][0][RTW89_ETSI][0][81] = 127, + [0][0][RTW89_MKK][1][81] = 127, + [0][0][RTW89_MKK][0][81] = 127, + [0][0][RTW89_IC][1][81] = -18, + [0][0][RTW89_KCC][1][81] = -2, + [0][0][RTW89_KCC][0][81] = 127, + [0][0][RTW89_ACMA][1][81] = 127, + [0][0][RTW89_ACMA][0][81] = 127, + [0][0][RTW89_CHILE][1][81] = 127, + [0][0][RTW89_QATAR][1][81] = 127, + [0][0][RTW89_QATAR][0][81] = 127, + [0][0][RTW89_UK][1][81] = 127, + [0][0][RTW89_UK][0][81] = 127, + [0][0][RTW89_THAILAND][1][81] = 127, + [0][0][RTW89_THAILAND][0][81] = 127, + [0][0][RTW89_FCC][1][83] = -18, + [0][0][RTW89_ETSI][1][83] = 127, + [0][0][RTW89_ETSI][0][83] = 127, + [0][0][RTW89_MKK][1][83] = 127, + [0][0][RTW89_MKK][0][83] = 127, + [0][0][RTW89_IC][1][83] = -18, + [0][0][RTW89_KCC][1][83] = -2, + [0][0][RTW89_KCC][0][83] = 127, + [0][0][RTW89_ACMA][1][83] = 127, + [0][0][RTW89_ACMA][0][83] = 127, + [0][0][RTW89_CHILE][1][83] = 127, + [0][0][RTW89_QATAR][1][83] = 127, + [0][0][RTW89_QATAR][0][83] = 127, + [0][0][RTW89_UK][1][83] = 127, + [0][0][RTW89_UK][0][83] = 127, + [0][0][RTW89_THAILAND][1][83] = 127, + [0][0][RTW89_THAILAND][0][83] = 127, + [0][0][RTW89_FCC][1][85] = -18, + [0][0][RTW89_ETSI][1][85] = 127, + [0][0][RTW89_ETSI][0][85] = 127, + [0][0][RTW89_MKK][1][85] = 127, + [0][0][RTW89_MKK][0][85] = 127, + [0][0][RTW89_IC][1][85] = -18, + [0][0][RTW89_KCC][1][85] = -2, + [0][0][RTW89_KCC][0][85] = 127, + [0][0][RTW89_ACMA][1][85] = 127, + [0][0][RTW89_ACMA][0][85] = 127, + [0][0][RTW89_CHILE][1][85] = 127, + [0][0][RTW89_QATAR][1][85] = 127, + [0][0][RTW89_QATAR][0][85] = 127, + [0][0][RTW89_UK][1][85] = 127, + [0][0][RTW89_UK][0][85] = 127, + [0][0][RTW89_THAILAND][1][85] = 127, + [0][0][RTW89_THAILAND][0][85] = 127, + [0][0][RTW89_FCC][1][87] = -16, + [0][0][RTW89_ETSI][1][87] = 127, + [0][0][RTW89_ETSI][0][87] = 127, + [0][0][RTW89_MKK][1][87] = 127, + [0][0][RTW89_MKK][0][87] = 127, + [0][0][RTW89_IC][1][87] = -16, + [0][0][RTW89_KCC][1][87] = -2, + [0][0][RTW89_KCC][0][87] = 127, + [0][0][RTW89_ACMA][1][87] = 127, + [0][0][RTW89_ACMA][0][87] = 127, + [0][0][RTW89_CHILE][1][87] = 127, + [0][0][RTW89_QATAR][1][87] = 127, + [0][0][RTW89_QATAR][0][87] = 127, + [0][0][RTW89_UK][1][87] = 127, + [0][0][RTW89_UK][0][87] = 127, + [0][0][RTW89_THAILAND][1][87] = 127, + [0][0][RTW89_THAILAND][0][87] = 127, + [0][0][RTW89_FCC][1][89] = -16, + [0][0][RTW89_ETSI][1][89] = 127, + [0][0][RTW89_ETSI][0][89] = 127, + [0][0][RTW89_MKK][1][89] = 127, + [0][0][RTW89_MKK][0][89] = 127, + [0][0][RTW89_IC][1][89] = -16, + [0][0][RTW89_KCC][1][89] = -2, + [0][0][RTW89_KCC][0][89] = 127, + [0][0][RTW89_ACMA][1][89] = 127, + [0][0][RTW89_ACMA][0][89] = 127, + [0][0][RTW89_CHILE][1][89] = 127, + [0][0][RTW89_QATAR][1][89] = 127, + [0][0][RTW89_QATAR][0][89] = 127, + [0][0][RTW89_UK][1][89] = 127, + [0][0][RTW89_UK][0][89] = 127, + [0][0][RTW89_THAILAND][1][89] = 127, + [0][0][RTW89_THAILAND][0][89] = 127, + [0][0][RTW89_FCC][1][90] = -16, + [0][0][RTW89_ETSI][1][90] = 127, + [0][0][RTW89_ETSI][0][90] = 127, + [0][0][RTW89_MKK][1][90] = 127, + [0][0][RTW89_MKK][0][90] = 127, + [0][0][RTW89_IC][1][90] = -16, + [0][0][RTW89_KCC][1][90] = -2, + [0][0][RTW89_KCC][0][90] = 127, + [0][0][RTW89_ACMA][1][90] = 127, + [0][0][RTW89_ACMA][0][90] = 127, + [0][0][RTW89_CHILE][1][90] = 127, + [0][0][RTW89_QATAR][1][90] = 127, + [0][0][RTW89_QATAR][0][90] = 127, + [0][0][RTW89_UK][1][90] = 127, + [0][0][RTW89_UK][0][90] = 127, + [0][0][RTW89_THAILAND][1][90] = 127, + [0][0][RTW89_THAILAND][0][90] = 127, + [0][0][RTW89_FCC][1][92] = -16, + [0][0][RTW89_ETSI][1][92] = 127, + [0][0][RTW89_ETSI][0][92] = 127, + [0][0][RTW89_MKK][1][92] = 127, + [0][0][RTW89_MKK][0][92] = 127, + [0][0][RTW89_IC][1][92] = -16, + [0][0][RTW89_KCC][1][92] = -2, + [0][0][RTW89_KCC][0][92] = 127, + [0][0][RTW89_ACMA][1][92] = 127, + [0][0][RTW89_ACMA][0][92] = 127, + [0][0][RTW89_CHILE][1][92] = 127, + [0][0][RTW89_QATAR][1][92] = 127, + [0][0][RTW89_QATAR][0][92] = 127, + [0][0][RTW89_UK][1][92] = 127, + [0][0][RTW89_UK][0][92] = 127, + [0][0][RTW89_THAILAND][1][92] = 127, + [0][0][RTW89_THAILAND][0][92] = 127, + [0][0][RTW89_FCC][1][94] = -16, + [0][0][RTW89_ETSI][1][94] = 127, + [0][0][RTW89_ETSI][0][94] = 127, + [0][0][RTW89_MKK][1][94] = 127, + [0][0][RTW89_MKK][0][94] = 127, + [0][0][RTW89_IC][1][94] = -16, + [0][0][RTW89_KCC][1][94] = -2, + [0][0][RTW89_KCC][0][94] = 127, + [0][0][RTW89_ACMA][1][94] = 127, + [0][0][RTW89_ACMA][0][94] = 127, + [0][0][RTW89_CHILE][1][94] = 127, + [0][0][RTW89_QATAR][1][94] = 127, + [0][0][RTW89_QATAR][0][94] = 127, + [0][0][RTW89_UK][1][94] = 127, + [0][0][RTW89_UK][0][94] = 127, + [0][0][RTW89_THAILAND][1][94] = 127, + [0][0][RTW89_THAILAND][0][94] = 127, + [0][0][RTW89_FCC][1][96] = -16, + [0][0][RTW89_ETSI][1][96] = 127, + [0][0][RTW89_ETSI][0][96] = 127, + [0][0][RTW89_MKK][1][96] = 127, + [0][0][RTW89_MKK][0][96] = 127, + [0][0][RTW89_IC][1][96] = -16, + [0][0][RTW89_KCC][1][96] = -2, + [0][0][RTW89_KCC][0][96] = 127, + [0][0][RTW89_ACMA][1][96] = 127, + [0][0][RTW89_ACMA][0][96] = 127, + [0][0][RTW89_CHILE][1][96] = 127, + [0][0][RTW89_QATAR][1][96] = 127, + [0][0][RTW89_QATAR][0][96] = 127, + [0][0][RTW89_UK][1][96] = 127, + [0][0][RTW89_UK][0][96] = 127, + [0][0][RTW89_THAILAND][1][96] = 127, + [0][0][RTW89_THAILAND][0][96] = 127, + [0][0][RTW89_FCC][1][98] = -16, + [0][0][RTW89_ETSI][1][98] = 127, + [0][0][RTW89_ETSI][0][98] = 127, + [0][0][RTW89_MKK][1][98] = 127, + [0][0][RTW89_MKK][0][98] = 127, + [0][0][RTW89_IC][1][98] = -16, + [0][0][RTW89_KCC][1][98] = -2, + [0][0][RTW89_KCC][0][98] = 127, + [0][0][RTW89_ACMA][1][98] = 127, + [0][0][RTW89_ACMA][0][98] = 127, + [0][0][RTW89_CHILE][1][98] = 127, + [0][0][RTW89_QATAR][1][98] = 127, + [0][0][RTW89_QATAR][0][98] = 127, + [0][0][RTW89_UK][1][98] = 127, + [0][0][RTW89_UK][0][98] = 127, + [0][0][RTW89_THAILAND][1][98] = 127, + [0][0][RTW89_THAILAND][0][98] = 127, + [0][0][RTW89_FCC][1][100] = -16, + [0][0][RTW89_ETSI][1][100] = 127, + [0][0][RTW89_ETSI][0][100] = 127, + [0][0][RTW89_MKK][1][100] = 127, + [0][0][RTW89_MKK][0][100] = 127, + [0][0][RTW89_IC][1][100] = -16, + [0][0][RTW89_KCC][1][100] = -2, + [0][0][RTW89_KCC][0][100] = 127, + [0][0][RTW89_ACMA][1][100] = 127, + [0][0][RTW89_ACMA][0][100] = 127, + [0][0][RTW89_CHILE][1][100] = 127, + [0][0][RTW89_QATAR][1][100] = 127, + [0][0][RTW89_QATAR][0][100] = 127, + [0][0][RTW89_UK][1][100] = 127, + [0][0][RTW89_UK][0][100] = 127, + [0][0][RTW89_THAILAND][1][100] = 127, + [0][0][RTW89_THAILAND][0][100] = 127, + [0][0][RTW89_FCC][1][102] = -16, + [0][0][RTW89_ETSI][1][102] = 127, + [0][0][RTW89_ETSI][0][102] = 127, + [0][0][RTW89_MKK][1][102] = 127, + [0][0][RTW89_MKK][0][102] = 127, + [0][0][RTW89_IC][1][102] = -16, + [0][0][RTW89_KCC][1][102] = -2, + [0][0][RTW89_KCC][0][102] = 127, + [0][0][RTW89_ACMA][1][102] = 127, + [0][0][RTW89_ACMA][0][102] = 127, + [0][0][RTW89_CHILE][1][102] = 127, + [0][0][RTW89_QATAR][1][102] = 127, + [0][0][RTW89_QATAR][0][102] = 127, + [0][0][RTW89_UK][1][102] = 127, + [0][0][RTW89_UK][0][102] = 127, + [0][0][RTW89_THAILAND][1][102] = 127, + [0][0][RTW89_THAILAND][0][102] = 127, + [0][0][RTW89_FCC][1][104] = -16, + [0][0][RTW89_ETSI][1][104] = 127, + [0][0][RTW89_ETSI][0][104] = 127, + [0][0][RTW89_MKK][1][104] = 127, + [0][0][RTW89_MKK][0][104] = 127, + [0][0][RTW89_IC][1][104] = -16, + [0][0][RTW89_KCC][1][104] = -2, + [0][0][RTW89_KCC][0][104] = 127, + [0][0][RTW89_ACMA][1][104] = 127, + [0][0][RTW89_ACMA][0][104] = 127, + [0][0][RTW89_CHILE][1][104] = 127, + [0][0][RTW89_QATAR][1][104] = 127, + [0][0][RTW89_QATAR][0][104] = 127, + [0][0][RTW89_UK][1][104] = 127, + [0][0][RTW89_UK][0][104] = 127, + [0][0][RTW89_THAILAND][1][104] = 127, + [0][0][RTW89_THAILAND][0][104] = 127, + [0][0][RTW89_FCC][1][105] = -16, + [0][0][RTW89_ETSI][1][105] = 127, + [0][0][RTW89_ETSI][0][105] = 127, + [0][0][RTW89_MKK][1][105] = 127, + [0][0][RTW89_MKK][0][105] = 127, + [0][0][RTW89_IC][1][105] = -16, + [0][0][RTW89_KCC][1][105] = -2, + [0][0][RTW89_KCC][0][105] = 127, + [0][0][RTW89_ACMA][1][105] = 127, + [0][0][RTW89_ACMA][0][105] = 127, + [0][0][RTW89_CHILE][1][105] = 127, + [0][0][RTW89_QATAR][1][105] = 127, + [0][0][RTW89_QATAR][0][105] = 127, + [0][0][RTW89_UK][1][105] = 127, + [0][0][RTW89_UK][0][105] = 127, + [0][0][RTW89_THAILAND][1][105] = 127, + [0][0][RTW89_THAILAND][0][105] = 127, + [0][0][RTW89_FCC][1][107] = -12, + [0][0][RTW89_ETSI][1][107] = 127, + [0][0][RTW89_ETSI][0][107] = 127, + [0][0][RTW89_MKK][1][107] = 127, + [0][0][RTW89_MKK][0][107] = 127, + [0][0][RTW89_IC][1][107] = -12, + [0][0][RTW89_KCC][1][107] = -2, + [0][0][RTW89_KCC][0][107] = 127, + [0][0][RTW89_ACMA][1][107] = 127, + [0][0][RTW89_ACMA][0][107] = 127, + [0][0][RTW89_CHILE][1][107] = 127, + [0][0][RTW89_QATAR][1][107] = 127, + [0][0][RTW89_QATAR][0][107] = 127, + [0][0][RTW89_UK][1][107] = 127, + [0][0][RTW89_UK][0][107] = 127, + [0][0][RTW89_THAILAND][1][107] = 127, + [0][0][RTW89_THAILAND][0][107] = 127, + [0][0][RTW89_FCC][1][109] = -12, + [0][0][RTW89_ETSI][1][109] = 127, + [0][0][RTW89_ETSI][0][109] = 127, + [0][0][RTW89_MKK][1][109] = 127, + [0][0][RTW89_MKK][0][109] = 127, + [0][0][RTW89_IC][1][109] = -12, + [0][0][RTW89_KCC][1][109] = 127, + [0][0][RTW89_KCC][0][109] = 127, + [0][0][RTW89_ACMA][1][109] = 127, + [0][0][RTW89_ACMA][0][109] = 127, + [0][0][RTW89_CHILE][1][109] = 127, + [0][0][RTW89_QATAR][1][109] = 127, + [0][0][RTW89_QATAR][0][109] = 127, + [0][0][RTW89_UK][1][109] = 127, + [0][0][RTW89_UK][0][109] = 127, + [0][0][RTW89_THAILAND][1][109] = 127, + [0][0][RTW89_THAILAND][0][109] = 127, + [0][0][RTW89_FCC][1][111] = 127, + [0][0][RTW89_ETSI][1][111] = 127, + [0][0][RTW89_ETSI][0][111] = 127, + [0][0][RTW89_MKK][1][111] = 127, + [0][0][RTW89_MKK][0][111] = 127, + [0][0][RTW89_IC][1][111] = 127, + [0][0][RTW89_KCC][1][111] = 127, + [0][0][RTW89_KCC][0][111] = 127, + [0][0][RTW89_ACMA][1][111] = 127, + [0][0][RTW89_ACMA][0][111] = 127, + [0][0][RTW89_CHILE][1][111] = 127, + [0][0][RTW89_QATAR][1][111] = 127, + [0][0][RTW89_QATAR][0][111] = 127, + [0][0][RTW89_UK][1][111] = 127, + [0][0][RTW89_UK][0][111] = 127, + [0][0][RTW89_THAILAND][1][111] = 127, + [0][0][RTW89_THAILAND][0][111] = 127, + [0][0][RTW89_FCC][1][113] = 127, + [0][0][RTW89_ETSI][1][113] = 127, + [0][0][RTW89_ETSI][0][113] = 127, + [0][0][RTW89_MKK][1][113] = 127, + [0][0][RTW89_MKK][0][113] = 127, + [0][0][RTW89_IC][1][113] = 127, + [0][0][RTW89_KCC][1][113] = 127, + [0][0][RTW89_KCC][0][113] = 127, + [0][0][RTW89_ACMA][1][113] = 127, + [0][0][RTW89_ACMA][0][113] = 127, + [0][0][RTW89_CHILE][1][113] = 127, + [0][0][RTW89_QATAR][1][113] = 127, + [0][0][RTW89_QATAR][0][113] = 127, + [0][0][RTW89_UK][1][113] = 127, + [0][0][RTW89_UK][0][113] = 127, + [0][0][RTW89_THAILAND][1][113] = 127, + [0][0][RTW89_THAILAND][0][113] = 127, + [0][0][RTW89_FCC][1][115] = 127, + [0][0][RTW89_ETSI][1][115] = 127, + [0][0][RTW89_ETSI][0][115] = 127, + [0][0][RTW89_MKK][1][115] = 127, + [0][0][RTW89_MKK][0][115] = 127, + [0][0][RTW89_IC][1][115] = 127, + [0][0][RTW89_KCC][1][115] = 127, + [0][0][RTW89_KCC][0][115] = 127, + [0][0][RTW89_ACMA][1][115] = 127, + [0][0][RTW89_ACMA][0][115] = 127, + [0][0][RTW89_CHILE][1][115] = 127, + [0][0][RTW89_QATAR][1][115] = 127, + [0][0][RTW89_QATAR][0][115] = 127, + [0][0][RTW89_UK][1][115] = 127, + [0][0][RTW89_UK][0][115] = 127, + [0][0][RTW89_THAILAND][1][115] = 127, + [0][0][RTW89_THAILAND][0][115] = 127, + [0][0][RTW89_FCC][1][117] = 127, + [0][0][RTW89_ETSI][1][117] = 127, + [0][0][RTW89_ETSI][0][117] = 127, + [0][0][RTW89_MKK][1][117] = 127, + [0][0][RTW89_MKK][0][117] = 127, + [0][0][RTW89_IC][1][117] = 127, + [0][0][RTW89_KCC][1][117] = 127, + [0][0][RTW89_KCC][0][117] = 127, + [0][0][RTW89_ACMA][1][117] = 127, + [0][0][RTW89_ACMA][0][117] = 127, + [0][0][RTW89_CHILE][1][117] = 127, + [0][0][RTW89_QATAR][1][117] = 127, + [0][0][RTW89_QATAR][0][117] = 127, + [0][0][RTW89_UK][1][117] = 127, + [0][0][RTW89_UK][0][117] = 127, + [0][0][RTW89_THAILAND][1][117] = 127, + [0][0][RTW89_THAILAND][0][117] = 127, + [0][0][RTW89_FCC][1][119] = 127, + [0][0][RTW89_ETSI][1][119] = 127, + [0][0][RTW89_ETSI][0][119] = 127, + [0][0][RTW89_MKK][1][119] = 127, + [0][0][RTW89_MKK][0][119] = 127, + [0][0][RTW89_IC][1][119] = 127, + [0][0][RTW89_KCC][1][119] = 127, + [0][0][RTW89_KCC][0][119] = 127, + [0][0][RTW89_ACMA][1][119] = 127, + [0][0][RTW89_ACMA][0][119] = 127, + [0][0][RTW89_CHILE][1][119] = 127, + [0][0][RTW89_QATAR][1][119] = 127, + [0][0][RTW89_QATAR][0][119] = 127, + [0][0][RTW89_UK][1][119] = 127, + [0][0][RTW89_UK][0][119] = 127, + [0][0][RTW89_THAILAND][1][119] = 127, + [0][0][RTW89_THAILAND][0][119] = 127, + [0][1][RTW89_FCC][1][0] = -40, + [0][1][RTW89_ETSI][1][0] = 20, + [0][1][RTW89_ETSI][0][0] = -18, + [0][1][RTW89_MKK][1][0] = 18, + [0][1][RTW89_MKK][0][0] = -20, + [0][1][RTW89_IC][1][0] = -40, + [0][1][RTW89_KCC][1][0] = -14, + [0][1][RTW89_KCC][0][0] = -14, + [0][1][RTW89_ACMA][1][0] = 20, + [0][1][RTW89_ACMA][0][0] = -18, + [0][1][RTW89_CHILE][1][0] = -40, + [0][1][RTW89_QATAR][1][0] = 20, + [0][1][RTW89_QATAR][0][0] = -18, + [0][1][RTW89_UK][1][0] = 20, + [0][1][RTW89_UK][0][0] = -18, + [0][1][RTW89_THAILAND][1][0] = 6, + [0][1][RTW89_THAILAND][0][0] = -40, + [0][1][RTW89_FCC][1][2] = -40, + [0][1][RTW89_ETSI][1][2] = 20, + [0][1][RTW89_ETSI][0][2] = -18, + [0][1][RTW89_MKK][1][2] = 18, + [0][1][RTW89_MKK][0][2] = -22, + [0][1][RTW89_IC][1][2] = -40, + [0][1][RTW89_KCC][1][2] = -14, + [0][1][RTW89_KCC][0][2] = -14, + [0][1][RTW89_ACMA][1][2] = 20, + [0][1][RTW89_ACMA][0][2] = -18, + [0][1][RTW89_CHILE][1][2] = -40, + [0][1][RTW89_QATAR][1][2] = 20, + [0][1][RTW89_QATAR][0][2] = -18, + [0][1][RTW89_UK][1][2] = 20, + [0][1][RTW89_UK][0][2] = -18, + [0][1][RTW89_THAILAND][1][2] = 6, + [0][1][RTW89_THAILAND][0][2] = -40, + [0][1][RTW89_FCC][1][4] = -40, + [0][1][RTW89_ETSI][1][4] = 20, + [0][1][RTW89_ETSI][0][4] = -18, + [0][1][RTW89_MKK][1][4] = 18, + [0][1][RTW89_MKK][0][4] = -22, + [0][1][RTW89_IC][1][4] = -40, + [0][1][RTW89_KCC][1][4] = -14, + [0][1][RTW89_KCC][0][4] = -14, + [0][1][RTW89_ACMA][1][4] = 20, + [0][1][RTW89_ACMA][0][4] = -18, + [0][1][RTW89_CHILE][1][4] = -40, + [0][1][RTW89_QATAR][1][4] = 20, + [0][1][RTW89_QATAR][0][4] = -18, + [0][1][RTW89_UK][1][4] = 20, + [0][1][RTW89_UK][0][4] = -18, + [0][1][RTW89_THAILAND][1][4] = 6, + [0][1][RTW89_THAILAND][0][4] = -40, + [0][1][RTW89_FCC][1][6] = -40, + [0][1][RTW89_ETSI][1][6] = 20, + [0][1][RTW89_ETSI][0][6] = -18, + [0][1][RTW89_MKK][1][6] = 18, + [0][1][RTW89_MKK][0][6] = -22, + [0][1][RTW89_IC][1][6] = -40, + [0][1][RTW89_KCC][1][6] = -14, + [0][1][RTW89_KCC][0][6] = -14, + [0][1][RTW89_ACMA][1][6] = 20, + [0][1][RTW89_ACMA][0][6] = -18, + [0][1][RTW89_CHILE][1][6] = -40, + [0][1][RTW89_QATAR][1][6] = 20, + [0][1][RTW89_QATAR][0][6] = -18, + [0][1][RTW89_UK][1][6] = 20, + [0][1][RTW89_UK][0][6] = -18, + [0][1][RTW89_THAILAND][1][6] = 6, + [0][1][RTW89_THAILAND][0][6] = -40, + [0][1][RTW89_FCC][1][8] = -40, + [0][1][RTW89_ETSI][1][8] = 20, + [0][1][RTW89_ETSI][0][8] = -18, + [0][1][RTW89_MKK][1][8] = 18, + [0][1][RTW89_MKK][0][8] = -22, + [0][1][RTW89_IC][1][8] = -40, + [0][1][RTW89_KCC][1][8] = -14, + [0][1][RTW89_KCC][0][8] = -14, + [0][1][RTW89_ACMA][1][8] = 20, + [0][1][RTW89_ACMA][0][8] = -18, + [0][1][RTW89_CHILE][1][8] = -40, + [0][1][RTW89_QATAR][1][8] = 20, + [0][1][RTW89_QATAR][0][8] = -18, + [0][1][RTW89_UK][1][8] = 20, + [0][1][RTW89_UK][0][8] = -18, + [0][1][RTW89_THAILAND][1][8] = 6, + [0][1][RTW89_THAILAND][0][8] = -40, + [0][1][RTW89_FCC][1][10] = -40, + [0][1][RTW89_ETSI][1][10] = 20, + [0][1][RTW89_ETSI][0][10] = -18, + [0][1][RTW89_MKK][1][10] = 18, + [0][1][RTW89_MKK][0][10] = -22, + [0][1][RTW89_IC][1][10] = -40, + [0][1][RTW89_KCC][1][10] = -14, + [0][1][RTW89_KCC][0][10] = -14, + [0][1][RTW89_ACMA][1][10] = 20, + [0][1][RTW89_ACMA][0][10] = -18, + [0][1][RTW89_CHILE][1][10] = -40, + [0][1][RTW89_QATAR][1][10] = 20, + [0][1][RTW89_QATAR][0][10] = -18, + [0][1][RTW89_UK][1][10] = 20, + [0][1][RTW89_UK][0][10] = -18, + [0][1][RTW89_THAILAND][1][10] = 6, + [0][1][RTW89_THAILAND][0][10] = -40, + [0][1][RTW89_FCC][1][12] = -40, + [0][1][RTW89_ETSI][1][12] = 20, + [0][1][RTW89_ETSI][0][12] = -18, + [0][1][RTW89_MKK][1][12] = 18, + [0][1][RTW89_MKK][0][12] = -22, + [0][1][RTW89_IC][1][12] = -40, + [0][1][RTW89_KCC][1][12] = -14, + [0][1][RTW89_KCC][0][12] = -14, + [0][1][RTW89_ACMA][1][12] = 20, + [0][1][RTW89_ACMA][0][12] = -18, + [0][1][RTW89_CHILE][1][12] = -40, + [0][1][RTW89_QATAR][1][12] = 20, + [0][1][RTW89_QATAR][0][12] = -18, + [0][1][RTW89_UK][1][12] = 20, + [0][1][RTW89_UK][0][12] = -18, + [0][1][RTW89_THAILAND][1][12] = 6, + [0][1][RTW89_THAILAND][0][12] = -40, + [0][1][RTW89_FCC][1][14] = -40, + [0][1][RTW89_ETSI][1][14] = 20, + [0][1][RTW89_ETSI][0][14] = -18, + [0][1][RTW89_MKK][1][14] = 18, + [0][1][RTW89_MKK][0][14] = -22, + [0][1][RTW89_IC][1][14] = -40, + [0][1][RTW89_KCC][1][14] = -14, + [0][1][RTW89_KCC][0][14] = -14, + [0][1][RTW89_ACMA][1][14] = 20, + [0][1][RTW89_ACMA][0][14] = -18, + [0][1][RTW89_CHILE][1][14] = -40, + [0][1][RTW89_QATAR][1][14] = 20, + [0][1][RTW89_QATAR][0][14] = -18, + [0][1][RTW89_UK][1][14] = 20, + [0][1][RTW89_UK][0][14] = -18, + [0][1][RTW89_THAILAND][1][14] = 6, + [0][1][RTW89_THAILAND][0][14] = -40, + [0][1][RTW89_FCC][1][15] = -40, + [0][1][RTW89_ETSI][1][15] = 20, + [0][1][RTW89_ETSI][0][15] = -18, + [0][1][RTW89_MKK][1][15] = 18, + [0][1][RTW89_MKK][0][15] = -22, + [0][1][RTW89_IC][1][15] = -40, + [0][1][RTW89_KCC][1][15] = -14, + [0][1][RTW89_KCC][0][15] = -14, + [0][1][RTW89_ACMA][1][15] = 20, + [0][1][RTW89_ACMA][0][15] = -18, + [0][1][RTW89_CHILE][1][15] = -40, + [0][1][RTW89_QATAR][1][15] = 20, + [0][1][RTW89_QATAR][0][15] = -18, + [0][1][RTW89_UK][1][15] = 20, + [0][1][RTW89_UK][0][15] = -18, + [0][1][RTW89_THAILAND][1][15] = 6, + [0][1][RTW89_THAILAND][0][15] = -40, + [0][1][RTW89_FCC][1][17] = -40, + [0][1][RTW89_ETSI][1][17] = 20, + [0][1][RTW89_ETSI][0][17] = -18, + [0][1][RTW89_MKK][1][17] = 18, + [0][1][RTW89_MKK][0][17] = -22, + [0][1][RTW89_IC][1][17] = -40, + [0][1][RTW89_KCC][1][17] = -14, + [0][1][RTW89_KCC][0][17] = -14, + [0][1][RTW89_ACMA][1][17] = 20, + [0][1][RTW89_ACMA][0][17] = -18, + [0][1][RTW89_CHILE][1][17] = -40, + [0][1][RTW89_QATAR][1][17] = 20, + [0][1][RTW89_QATAR][0][17] = -18, + [0][1][RTW89_UK][1][17] = 20, + [0][1][RTW89_UK][0][17] = -18, + [0][1][RTW89_THAILAND][1][17] = 6, + [0][1][RTW89_THAILAND][0][17] = -40, + [0][1][RTW89_FCC][1][19] = -40, + [0][1][RTW89_ETSI][1][19] = 20, + [0][1][RTW89_ETSI][0][19] = -18, + [0][1][RTW89_MKK][1][19] = 18, + [0][1][RTW89_MKK][0][19] = -22, + [0][1][RTW89_IC][1][19] = -40, + [0][1][RTW89_KCC][1][19] = -14, + [0][1][RTW89_KCC][0][19] = -14, + [0][1][RTW89_ACMA][1][19] = 20, + [0][1][RTW89_ACMA][0][19] = -18, + [0][1][RTW89_CHILE][1][19] = -40, + [0][1][RTW89_QATAR][1][19] = 20, + [0][1][RTW89_QATAR][0][19] = -18, + [0][1][RTW89_UK][1][19] = 20, + [0][1][RTW89_UK][0][19] = -18, + [0][1][RTW89_THAILAND][1][19] = 6, + [0][1][RTW89_THAILAND][0][19] = -40, + [0][1][RTW89_FCC][1][21] = -40, + [0][1][RTW89_ETSI][1][21] = 20, + [0][1][RTW89_ETSI][0][21] = -18, + [0][1][RTW89_MKK][1][21] = 18, + [0][1][RTW89_MKK][0][21] = -22, + [0][1][RTW89_IC][1][21] = -40, + [0][1][RTW89_KCC][1][21] = -14, + [0][1][RTW89_KCC][0][21] = -14, + [0][1][RTW89_ACMA][1][21] = 20, + [0][1][RTW89_ACMA][0][21] = -18, + [0][1][RTW89_CHILE][1][21] = -40, + [0][1][RTW89_QATAR][1][21] = 20, + [0][1][RTW89_QATAR][0][21] = -18, + [0][1][RTW89_UK][1][21] = 20, + [0][1][RTW89_UK][0][21] = -18, + [0][1][RTW89_THAILAND][1][21] = 6, + [0][1][RTW89_THAILAND][0][21] = -40, + [0][1][RTW89_FCC][1][23] = -40, + [0][1][RTW89_ETSI][1][23] = 20, + [0][1][RTW89_ETSI][0][23] = -18, + [0][1][RTW89_MKK][1][23] = 18, + [0][1][RTW89_MKK][0][23] = -22, + [0][1][RTW89_IC][1][23] = -40, + [0][1][RTW89_KCC][1][23] = -14, + [0][1][RTW89_KCC][0][23] = -14, + [0][1][RTW89_ACMA][1][23] = 20, + [0][1][RTW89_ACMA][0][23] = -18, + [0][1][RTW89_CHILE][1][23] = -40, + [0][1][RTW89_QATAR][1][23] = 20, + [0][1][RTW89_QATAR][0][23] = -18, + [0][1][RTW89_UK][1][23] = 20, + [0][1][RTW89_UK][0][23] = -18, + [0][1][RTW89_THAILAND][1][23] = 6, + [0][1][RTW89_THAILAND][0][23] = -40, + [0][1][RTW89_FCC][1][25] = -40, + [0][1][RTW89_ETSI][1][25] = 20, + [0][1][RTW89_ETSI][0][25] = -18, + [0][1][RTW89_MKK][1][25] = -4, + [0][1][RTW89_MKK][0][25] = -22, + [0][1][RTW89_IC][1][25] = -40, + [0][1][RTW89_KCC][1][25] = -14, + [0][1][RTW89_KCC][0][25] = -14, + [0][1][RTW89_ACMA][1][25] = 20, + [0][1][RTW89_ACMA][0][25] = -18, + [0][1][RTW89_CHILE][1][25] = -40, + [0][1][RTW89_QATAR][1][25] = 20, + [0][1][RTW89_QATAR][0][25] = -18, + [0][1][RTW89_UK][1][25] = 20, + [0][1][RTW89_UK][0][25] = -18, + [0][1][RTW89_THAILAND][1][25] = 6, + [0][1][RTW89_THAILAND][0][25] = -40, + [0][1][RTW89_FCC][1][27] = -40, + [0][1][RTW89_ETSI][1][27] = 20, + [0][1][RTW89_ETSI][0][27] = -18, + [0][1][RTW89_MKK][1][27] = -4, + [0][1][RTW89_MKK][0][27] = -22, + [0][1][RTW89_IC][1][27] = -40, + [0][1][RTW89_KCC][1][27] = -14, + [0][1][RTW89_KCC][0][27] = -14, + [0][1][RTW89_ACMA][1][27] = 20, + [0][1][RTW89_ACMA][0][27] = -18, + [0][1][RTW89_CHILE][1][27] = -40, + [0][1][RTW89_QATAR][1][27] = 20, + [0][1][RTW89_QATAR][0][27] = -18, + [0][1][RTW89_UK][1][27] = 20, + [0][1][RTW89_UK][0][27] = -18, + [0][1][RTW89_THAILAND][1][27] = 6, + [0][1][RTW89_THAILAND][0][27] = -40, + [0][1][RTW89_FCC][1][29] = -40, + [0][1][RTW89_ETSI][1][29] = 20, + [0][1][RTW89_ETSI][0][29] = -18, + [0][1][RTW89_MKK][1][29] = -4, + [0][1][RTW89_MKK][0][29] = -22, + [0][1][RTW89_IC][1][29] = -40, + [0][1][RTW89_KCC][1][29] = -14, + [0][1][RTW89_KCC][0][29] = -14, + [0][1][RTW89_ACMA][1][29] = 20, + [0][1][RTW89_ACMA][0][29] = -18, + [0][1][RTW89_CHILE][1][29] = -40, + [0][1][RTW89_QATAR][1][29] = 20, + [0][1][RTW89_QATAR][0][29] = -18, + [0][1][RTW89_UK][1][29] = 20, + [0][1][RTW89_UK][0][29] = -18, + [0][1][RTW89_THAILAND][1][29] = 6, + [0][1][RTW89_THAILAND][0][29] = -40, + [0][1][RTW89_FCC][1][30] = -40, + [0][1][RTW89_ETSI][1][30] = 20, + [0][1][RTW89_ETSI][0][30] = -18, + [0][1][RTW89_MKK][1][30] = -4, + [0][1][RTW89_MKK][0][30] = -22, + [0][1][RTW89_IC][1][30] = -40, + [0][1][RTW89_KCC][1][30] = -14, + [0][1][RTW89_KCC][0][30] = -14, + [0][1][RTW89_ACMA][1][30] = 20, + [0][1][RTW89_ACMA][0][30] = -18, + [0][1][RTW89_CHILE][1][30] = -40, + [0][1][RTW89_QATAR][1][30] = 20, + [0][1][RTW89_QATAR][0][30] = -18, + [0][1][RTW89_UK][1][30] = 20, + [0][1][RTW89_UK][0][30] = -18, + [0][1][RTW89_THAILAND][1][30] = 6, + [0][1][RTW89_THAILAND][0][30] = -40, + [0][1][RTW89_FCC][1][32] = -40, + [0][1][RTW89_ETSI][1][32] = 20, + [0][1][RTW89_ETSI][0][32] = -18, + [0][1][RTW89_MKK][1][32] = -4, + [0][1][RTW89_MKK][0][32] = -22, + [0][1][RTW89_IC][1][32] = -40, + [0][1][RTW89_KCC][1][32] = -14, + [0][1][RTW89_KCC][0][32] = -14, + [0][1][RTW89_ACMA][1][32] = 20, + [0][1][RTW89_ACMA][0][32] = -18, + [0][1][RTW89_CHILE][1][32] = -40, + [0][1][RTW89_QATAR][1][32] = 20, + [0][1][RTW89_QATAR][0][32] = -18, + [0][1][RTW89_UK][1][32] = 20, + [0][1][RTW89_UK][0][32] = -18, + [0][1][RTW89_THAILAND][1][32] = 6, + [0][1][RTW89_THAILAND][0][32] = -40, + [0][1][RTW89_FCC][1][34] = -40, + [0][1][RTW89_ETSI][1][34] = 20, + [0][1][RTW89_ETSI][0][34] = -18, + [0][1][RTW89_MKK][1][34] = -4, + [0][1][RTW89_MKK][0][34] = -22, + [0][1][RTW89_IC][1][34] = -40, + [0][1][RTW89_KCC][1][34] = -14, + [0][1][RTW89_KCC][0][34] = -14, + [0][1][RTW89_ACMA][1][34] = 20, + [0][1][RTW89_ACMA][0][34] = -18, + [0][1][RTW89_CHILE][1][34] = -40, + [0][1][RTW89_QATAR][1][34] = 20, + [0][1][RTW89_QATAR][0][34] = -18, + [0][1][RTW89_UK][1][34] = 20, + [0][1][RTW89_UK][0][34] = -18, + [0][1][RTW89_THAILAND][1][34] = 6, + [0][1][RTW89_THAILAND][0][34] = -40, + [0][1][RTW89_FCC][1][36] = -40, + [0][1][RTW89_ETSI][1][36] = 20, + [0][1][RTW89_ETSI][0][36] = -18, + [0][1][RTW89_MKK][1][36] = -4, + [0][1][RTW89_MKK][0][36] = -22, + [0][1][RTW89_IC][1][36] = -40, + [0][1][RTW89_KCC][1][36] = -14, + [0][1][RTW89_KCC][0][36] = -14, + [0][1][RTW89_ACMA][1][36] = 20, + [0][1][RTW89_ACMA][0][36] = -18, + [0][1][RTW89_CHILE][1][36] = -40, + [0][1][RTW89_QATAR][1][36] = 20, + [0][1][RTW89_QATAR][0][36] = -18, + [0][1][RTW89_UK][1][36] = 20, + [0][1][RTW89_UK][0][36] = -18, + [0][1][RTW89_THAILAND][1][36] = 6, + [0][1][RTW89_THAILAND][0][36] = -40, + [0][1][RTW89_FCC][1][38] = -40, + [0][1][RTW89_ETSI][1][38] = 20, + [0][1][RTW89_ETSI][0][38] = -18, + [0][1][RTW89_MKK][1][38] = -4, + [0][1][RTW89_MKK][0][38] = -22, + [0][1][RTW89_IC][1][38] = -40, + [0][1][RTW89_KCC][1][38] = -14, + [0][1][RTW89_KCC][0][38] = -14, + [0][1][RTW89_ACMA][1][38] = 20, + [0][1][RTW89_ACMA][0][38] = -18, + [0][1][RTW89_CHILE][1][38] = -40, + [0][1][RTW89_QATAR][1][38] = 20, + [0][1][RTW89_QATAR][0][38] = -18, + [0][1][RTW89_UK][1][38] = 20, + [0][1][RTW89_UK][0][38] = -18, + [0][1][RTW89_THAILAND][1][38] = 6, + [0][1][RTW89_THAILAND][0][38] = -40, + [0][1][RTW89_FCC][1][40] = -40, + [0][1][RTW89_ETSI][1][40] = 20, + [0][1][RTW89_ETSI][0][40] = -18, + [0][1][RTW89_MKK][1][40] = -4, + [0][1][RTW89_MKK][0][40] = -22, + [0][1][RTW89_IC][1][40] = -40, + [0][1][RTW89_KCC][1][40] = -14, + [0][1][RTW89_KCC][0][40] = -14, + [0][1][RTW89_ACMA][1][40] = 20, + [0][1][RTW89_ACMA][0][40] = -18, + [0][1][RTW89_CHILE][1][40] = -40, + [0][1][RTW89_QATAR][1][40] = 20, + [0][1][RTW89_QATAR][0][40] = -18, + [0][1][RTW89_UK][1][40] = 20, + [0][1][RTW89_UK][0][40] = -18, + [0][1][RTW89_THAILAND][1][40] = 6, + [0][1][RTW89_THAILAND][0][40] = -40, + [0][1][RTW89_FCC][1][42] = -40, + [0][1][RTW89_ETSI][1][42] = 20, + [0][1][RTW89_ETSI][0][42] = -18, + [0][1][RTW89_MKK][1][42] = -4, + [0][1][RTW89_MKK][0][42] = -22, + [0][1][RTW89_IC][1][42] = -40, + [0][1][RTW89_KCC][1][42] = -14, + [0][1][RTW89_KCC][0][42] = -14, + [0][1][RTW89_ACMA][1][42] = 20, + [0][1][RTW89_ACMA][0][42] = -18, + [0][1][RTW89_CHILE][1][42] = -40, + [0][1][RTW89_QATAR][1][42] = 20, + [0][1][RTW89_QATAR][0][42] = -18, + [0][1][RTW89_UK][1][42] = 20, + [0][1][RTW89_UK][0][42] = -18, + [0][1][RTW89_THAILAND][1][42] = 6, + [0][1][RTW89_THAILAND][0][42] = -40, + [0][1][RTW89_FCC][1][44] = -40, + [0][1][RTW89_ETSI][1][44] = 20, + [0][1][RTW89_ETSI][0][44] = -18, + [0][1][RTW89_MKK][1][44] = -4, + [0][1][RTW89_MKK][0][44] = -22, + [0][1][RTW89_IC][1][44] = -40, + [0][1][RTW89_KCC][1][44] = -14, + [0][1][RTW89_KCC][0][44] = -14, + [0][1][RTW89_ACMA][1][44] = 20, + [0][1][RTW89_ACMA][0][44] = -18, + [0][1][RTW89_CHILE][1][44] = -40, + [0][1][RTW89_QATAR][1][44] = 20, + [0][1][RTW89_QATAR][0][44] = -18, + [0][1][RTW89_UK][1][44] = 20, + [0][1][RTW89_UK][0][44] = -18, + [0][1][RTW89_THAILAND][1][44] = 6, + [0][1][RTW89_THAILAND][0][44] = -40, + [0][1][RTW89_FCC][1][45] = -40, + [0][1][RTW89_ETSI][1][45] = 127, + [0][1][RTW89_ETSI][0][45] = 127, + [0][1][RTW89_MKK][1][45] = 127, + [0][1][RTW89_MKK][0][45] = 127, + [0][1][RTW89_IC][1][45] = -40, + [0][1][RTW89_KCC][1][45] = -14, + [0][1][RTW89_KCC][0][45] = 127, + [0][1][RTW89_ACMA][1][45] = 127, + [0][1][RTW89_ACMA][0][45] = 127, + [0][1][RTW89_CHILE][1][45] = 127, + [0][1][RTW89_QATAR][1][45] = 127, + [0][1][RTW89_QATAR][0][45] = 127, + [0][1][RTW89_UK][1][45] = 127, + [0][1][RTW89_UK][0][45] = 127, + [0][1][RTW89_THAILAND][1][45] = 127, + [0][1][RTW89_THAILAND][0][45] = 127, + [0][1][RTW89_FCC][1][47] = -40, + [0][1][RTW89_ETSI][1][47] = 127, + [0][1][RTW89_ETSI][0][47] = 127, + [0][1][RTW89_MKK][1][47] = 127, + [0][1][RTW89_MKK][0][47] = 127, + [0][1][RTW89_IC][1][47] = -40, + [0][1][RTW89_KCC][1][47] = -14, + [0][1][RTW89_KCC][0][47] = 127, + [0][1][RTW89_ACMA][1][47] = 127, + [0][1][RTW89_ACMA][0][47] = 127, + [0][1][RTW89_CHILE][1][47] = 127, + [0][1][RTW89_QATAR][1][47] = 127, + [0][1][RTW89_QATAR][0][47] = 127, + [0][1][RTW89_UK][1][47] = 127, + [0][1][RTW89_UK][0][47] = 127, + [0][1][RTW89_THAILAND][1][47] = 127, + [0][1][RTW89_THAILAND][0][47] = 127, + [0][1][RTW89_FCC][1][49] = -40, + [0][1][RTW89_ETSI][1][49] = 127, + [0][1][RTW89_ETSI][0][49] = 127, + [0][1][RTW89_MKK][1][49] = 127, + [0][1][RTW89_MKK][0][49] = 127, + [0][1][RTW89_IC][1][49] = -40, + [0][1][RTW89_KCC][1][49] = -14, + [0][1][RTW89_KCC][0][49] = 127, + [0][1][RTW89_ACMA][1][49] = 127, + [0][1][RTW89_ACMA][0][49] = 127, + [0][1][RTW89_CHILE][1][49] = 127, + [0][1][RTW89_QATAR][1][49] = 127, + [0][1][RTW89_QATAR][0][49] = 127, + [0][1][RTW89_UK][1][49] = 127, + [0][1][RTW89_UK][0][49] = 127, + [0][1][RTW89_THAILAND][1][49] = 127, + [0][1][RTW89_THAILAND][0][49] = 127, + [0][1][RTW89_FCC][1][51] = -40, + [0][1][RTW89_ETSI][1][51] = 127, + [0][1][RTW89_ETSI][0][51] = 127, + [0][1][RTW89_MKK][1][51] = 127, + [0][1][RTW89_MKK][0][51] = 127, + [0][1][RTW89_IC][1][51] = -40, + [0][1][RTW89_KCC][1][51] = -14, + [0][1][RTW89_KCC][0][51] = 127, + [0][1][RTW89_ACMA][1][51] = 127, + [0][1][RTW89_ACMA][0][51] = 127, + [0][1][RTW89_CHILE][1][51] = 127, + [0][1][RTW89_QATAR][1][51] = 127, + [0][1][RTW89_QATAR][0][51] = 127, + [0][1][RTW89_UK][1][51] = 127, + [0][1][RTW89_UK][0][51] = 127, + [0][1][RTW89_THAILAND][1][51] = 127, + [0][1][RTW89_THAILAND][0][51] = 127, + [0][1][RTW89_FCC][1][53] = -40, + [0][1][RTW89_ETSI][1][53] = 127, + [0][1][RTW89_ETSI][0][53] = 127, + [0][1][RTW89_MKK][1][53] = 127, + [0][1][RTW89_MKK][0][53] = 127, + [0][1][RTW89_IC][1][53] = -40, + [0][1][RTW89_KCC][1][53] = -14, + [0][1][RTW89_KCC][0][53] = 127, + [0][1][RTW89_ACMA][1][53] = 127, + [0][1][RTW89_ACMA][0][53] = 127, + [0][1][RTW89_CHILE][1][53] = 127, + [0][1][RTW89_QATAR][1][53] = 127, + [0][1][RTW89_QATAR][0][53] = 127, + [0][1][RTW89_UK][1][53] = 127, + [0][1][RTW89_UK][0][53] = 127, + [0][1][RTW89_THAILAND][1][53] = 127, + [0][1][RTW89_THAILAND][0][53] = 127, + [0][1][RTW89_FCC][1][55] = -40, + [0][1][RTW89_ETSI][1][55] = 127, + [0][1][RTW89_ETSI][0][55] = 127, + [0][1][RTW89_MKK][1][55] = 127, + [0][1][RTW89_MKK][0][55] = 127, + [0][1][RTW89_IC][1][55] = -40, + [0][1][RTW89_KCC][1][55] = -14, + [0][1][RTW89_KCC][0][55] = 127, + [0][1][RTW89_ACMA][1][55] = 127, + [0][1][RTW89_ACMA][0][55] = 127, + [0][1][RTW89_CHILE][1][55] = 127, + [0][1][RTW89_QATAR][1][55] = 127, + [0][1][RTW89_QATAR][0][55] = 127, + [0][1][RTW89_UK][1][55] = 127, + [0][1][RTW89_UK][0][55] = 127, + [0][1][RTW89_THAILAND][1][55] = 127, + [0][1][RTW89_THAILAND][0][55] = 127, + [0][1][RTW89_FCC][1][57] = -40, + [0][1][RTW89_ETSI][1][57] = 127, + [0][1][RTW89_ETSI][0][57] = 127, + [0][1][RTW89_MKK][1][57] = 127, + [0][1][RTW89_MKK][0][57] = 127, + [0][1][RTW89_IC][1][57] = -40, + [0][1][RTW89_KCC][1][57] = -14, + [0][1][RTW89_KCC][0][57] = 127, + [0][1][RTW89_ACMA][1][57] = 127, + [0][1][RTW89_ACMA][0][57] = 127, + [0][1][RTW89_CHILE][1][57] = 127, + [0][1][RTW89_QATAR][1][57] = 127, + [0][1][RTW89_QATAR][0][57] = 127, + [0][1][RTW89_UK][1][57] = 127, + [0][1][RTW89_UK][0][57] = 127, + [0][1][RTW89_THAILAND][1][57] = 127, + [0][1][RTW89_THAILAND][0][57] = 127, + [0][1][RTW89_FCC][1][59] = -40, + [0][1][RTW89_ETSI][1][59] = 127, + [0][1][RTW89_ETSI][0][59] = 127, + [0][1][RTW89_MKK][1][59] = 127, + [0][1][RTW89_MKK][0][59] = 127, + [0][1][RTW89_IC][1][59] = -40, + [0][1][RTW89_KCC][1][59] = -14, + [0][1][RTW89_KCC][0][59] = 127, + [0][1][RTW89_ACMA][1][59] = 127, + [0][1][RTW89_ACMA][0][59] = 127, + [0][1][RTW89_CHILE][1][59] = 127, + [0][1][RTW89_QATAR][1][59] = 127, + [0][1][RTW89_QATAR][0][59] = 127, + [0][1][RTW89_UK][1][59] = 127, + [0][1][RTW89_UK][0][59] = 127, + [0][1][RTW89_THAILAND][1][59] = 127, + [0][1][RTW89_THAILAND][0][59] = 127, + [0][1][RTW89_FCC][1][60] = -40, + [0][1][RTW89_ETSI][1][60] = 127, + [0][1][RTW89_ETSI][0][60] = 127, + [0][1][RTW89_MKK][1][60] = 127, + [0][1][RTW89_MKK][0][60] = 127, + [0][1][RTW89_IC][1][60] = -40, + [0][1][RTW89_KCC][1][60] = -14, + [0][1][RTW89_KCC][0][60] = 127, + [0][1][RTW89_ACMA][1][60] = 127, + [0][1][RTW89_ACMA][0][60] = 127, + [0][1][RTW89_CHILE][1][60] = 127, + [0][1][RTW89_QATAR][1][60] = 127, + [0][1][RTW89_QATAR][0][60] = 127, + [0][1][RTW89_UK][1][60] = 127, + [0][1][RTW89_UK][0][60] = 127, + [0][1][RTW89_THAILAND][1][60] = 127, + [0][1][RTW89_THAILAND][0][60] = 127, + [0][1][RTW89_FCC][1][62] = -40, + [0][1][RTW89_ETSI][1][62] = 127, + [0][1][RTW89_ETSI][0][62] = 127, + [0][1][RTW89_MKK][1][62] = 127, + [0][1][RTW89_MKK][0][62] = 127, + [0][1][RTW89_IC][1][62] = -40, + [0][1][RTW89_KCC][1][62] = -14, + [0][1][RTW89_KCC][0][62] = 127, + [0][1][RTW89_ACMA][1][62] = 127, + [0][1][RTW89_ACMA][0][62] = 127, + [0][1][RTW89_CHILE][1][62] = 127, + [0][1][RTW89_QATAR][1][62] = 127, + [0][1][RTW89_QATAR][0][62] = 127, + [0][1][RTW89_UK][1][62] = 127, + [0][1][RTW89_UK][0][62] = 127, + [0][1][RTW89_THAILAND][1][62] = 127, + [0][1][RTW89_THAILAND][0][62] = 127, + [0][1][RTW89_FCC][1][64] = -40, + [0][1][RTW89_ETSI][1][64] = 127, + [0][1][RTW89_ETSI][0][64] = 127, + [0][1][RTW89_MKK][1][64] = 127, + [0][1][RTW89_MKK][0][64] = 127, + [0][1][RTW89_IC][1][64] = -40, + [0][1][RTW89_KCC][1][64] = -14, + [0][1][RTW89_KCC][0][64] = 127, + [0][1][RTW89_ACMA][1][64] = 127, + [0][1][RTW89_ACMA][0][64] = 127, + [0][1][RTW89_CHILE][1][64] = 127, + [0][1][RTW89_QATAR][1][64] = 127, + [0][1][RTW89_QATAR][0][64] = 127, + [0][1][RTW89_UK][1][64] = 127, + [0][1][RTW89_UK][0][64] = 127, + [0][1][RTW89_THAILAND][1][64] = 127, + [0][1][RTW89_THAILAND][0][64] = 127, + [0][1][RTW89_FCC][1][66] = -40, + [0][1][RTW89_ETSI][1][66] = 127, + [0][1][RTW89_ETSI][0][66] = 127, + [0][1][RTW89_MKK][1][66] = 127, + [0][1][RTW89_MKK][0][66] = 127, + [0][1][RTW89_IC][1][66] = -40, + [0][1][RTW89_KCC][1][66] = -14, + [0][1][RTW89_KCC][0][66] = 127, + [0][1][RTW89_ACMA][1][66] = 127, + [0][1][RTW89_ACMA][0][66] = 127, + [0][1][RTW89_CHILE][1][66] = 127, + [0][1][RTW89_QATAR][1][66] = 127, + [0][1][RTW89_QATAR][0][66] = 127, + [0][1][RTW89_UK][1][66] = 127, + [0][1][RTW89_UK][0][66] = 127, + [0][1][RTW89_THAILAND][1][66] = 127, + [0][1][RTW89_THAILAND][0][66] = 127, + [0][1][RTW89_FCC][1][68] = -40, + [0][1][RTW89_ETSI][1][68] = 127, + [0][1][RTW89_ETSI][0][68] = 127, + [0][1][RTW89_MKK][1][68] = 127, + [0][1][RTW89_MKK][0][68] = 127, + [0][1][RTW89_IC][1][68] = -40, + [0][1][RTW89_KCC][1][68] = -14, + [0][1][RTW89_KCC][0][68] = 127, + [0][1][RTW89_ACMA][1][68] = 127, + [0][1][RTW89_ACMA][0][68] = 127, + [0][1][RTW89_CHILE][1][68] = 127, + [0][1][RTW89_QATAR][1][68] = 127, + [0][1][RTW89_QATAR][0][68] = 127, + [0][1][RTW89_UK][1][68] = 127, + [0][1][RTW89_UK][0][68] = 127, + [0][1][RTW89_THAILAND][1][68] = 127, + [0][1][RTW89_THAILAND][0][68] = 127, + [0][1][RTW89_FCC][1][70] = -38, + [0][1][RTW89_ETSI][1][70] = 127, + [0][1][RTW89_ETSI][0][70] = 127, + [0][1][RTW89_MKK][1][70] = 127, + [0][1][RTW89_MKK][0][70] = 127, + [0][1][RTW89_IC][1][70] = -38, + [0][1][RTW89_KCC][1][70] = -14, + [0][1][RTW89_KCC][0][70] = 127, + [0][1][RTW89_ACMA][1][70] = 127, + [0][1][RTW89_ACMA][0][70] = 127, + [0][1][RTW89_CHILE][1][70] = 127, + [0][1][RTW89_QATAR][1][70] = 127, + [0][1][RTW89_QATAR][0][70] = 127, + [0][1][RTW89_UK][1][70] = 127, + [0][1][RTW89_UK][0][70] = 127, + [0][1][RTW89_THAILAND][1][70] = 127, + [0][1][RTW89_THAILAND][0][70] = 127, + [0][1][RTW89_FCC][1][72] = -38, + [0][1][RTW89_ETSI][1][72] = 127, + [0][1][RTW89_ETSI][0][72] = 127, + [0][1][RTW89_MKK][1][72] = 127, + [0][1][RTW89_MKK][0][72] = 127, + [0][1][RTW89_IC][1][72] = -38, + [0][1][RTW89_KCC][1][72] = -14, + [0][1][RTW89_KCC][0][72] = 127, + [0][1][RTW89_ACMA][1][72] = 127, + [0][1][RTW89_ACMA][0][72] = 127, + [0][1][RTW89_CHILE][1][72] = 127, + [0][1][RTW89_QATAR][1][72] = 127, + [0][1][RTW89_QATAR][0][72] = 127, + [0][1][RTW89_UK][1][72] = 127, + [0][1][RTW89_UK][0][72] = 127, + [0][1][RTW89_THAILAND][1][72] = 127, + [0][1][RTW89_THAILAND][0][72] = 127, + [0][1][RTW89_FCC][1][74] = -38, + [0][1][RTW89_ETSI][1][74] = 127, + [0][1][RTW89_ETSI][0][74] = 127, + [0][1][RTW89_MKK][1][74] = 127, + [0][1][RTW89_MKK][0][74] = 127, + [0][1][RTW89_IC][1][74] = -38, + [0][1][RTW89_KCC][1][74] = -14, + [0][1][RTW89_KCC][0][74] = 127, + [0][1][RTW89_ACMA][1][74] = 127, + [0][1][RTW89_ACMA][0][74] = 127, + [0][1][RTW89_CHILE][1][74] = 127, + [0][1][RTW89_QATAR][1][74] = 127, + [0][1][RTW89_QATAR][0][74] = 127, + [0][1][RTW89_UK][1][74] = 127, + [0][1][RTW89_UK][0][74] = 127, + [0][1][RTW89_THAILAND][1][74] = 127, + [0][1][RTW89_THAILAND][0][74] = 127, + [0][1][RTW89_FCC][1][75] = -38, + [0][1][RTW89_ETSI][1][75] = 127, + [0][1][RTW89_ETSI][0][75] = 127, + [0][1][RTW89_MKK][1][75] = 127, + [0][1][RTW89_MKK][0][75] = 127, + [0][1][RTW89_IC][1][75] = -38, + [0][1][RTW89_KCC][1][75] = -14, + [0][1][RTW89_KCC][0][75] = 127, + [0][1][RTW89_ACMA][1][75] = 127, + [0][1][RTW89_ACMA][0][75] = 127, + [0][1][RTW89_CHILE][1][75] = 127, + [0][1][RTW89_QATAR][1][75] = 127, + [0][1][RTW89_QATAR][0][75] = 127, + [0][1][RTW89_UK][1][75] = 127, + [0][1][RTW89_UK][0][75] = 127, + [0][1][RTW89_THAILAND][1][75] = 127, + [0][1][RTW89_THAILAND][0][75] = 127, + [0][1][RTW89_FCC][1][77] = -38, + [0][1][RTW89_ETSI][1][77] = 127, + [0][1][RTW89_ETSI][0][77] = 127, + [0][1][RTW89_MKK][1][77] = 127, + [0][1][RTW89_MKK][0][77] = 127, + [0][1][RTW89_IC][1][77] = -38, + [0][1][RTW89_KCC][1][77] = -14, + [0][1][RTW89_KCC][0][77] = 127, + [0][1][RTW89_ACMA][1][77] = 127, + [0][1][RTW89_ACMA][0][77] = 127, + [0][1][RTW89_CHILE][1][77] = 127, + [0][1][RTW89_QATAR][1][77] = 127, + [0][1][RTW89_QATAR][0][77] = 127, + [0][1][RTW89_UK][1][77] = 127, + [0][1][RTW89_UK][0][77] = 127, + [0][1][RTW89_THAILAND][1][77] = 127, + [0][1][RTW89_THAILAND][0][77] = 127, + [0][1][RTW89_FCC][1][79] = -38, + [0][1][RTW89_ETSI][1][79] = 127, + [0][1][RTW89_ETSI][0][79] = 127, + [0][1][RTW89_MKK][1][79] = 127, + [0][1][RTW89_MKK][0][79] = 127, + [0][1][RTW89_IC][1][79] = -38, + [0][1][RTW89_KCC][1][79] = -14, + [0][1][RTW89_KCC][0][79] = 127, + [0][1][RTW89_ACMA][1][79] = 127, + [0][1][RTW89_ACMA][0][79] = 127, + [0][1][RTW89_CHILE][1][79] = 127, + [0][1][RTW89_QATAR][1][79] = 127, + [0][1][RTW89_QATAR][0][79] = 127, + [0][1][RTW89_UK][1][79] = 127, + [0][1][RTW89_UK][0][79] = 127, + [0][1][RTW89_THAILAND][1][79] = 127, + [0][1][RTW89_THAILAND][0][79] = 127, + [0][1][RTW89_FCC][1][81] = -38, + [0][1][RTW89_ETSI][1][81] = 127, + [0][1][RTW89_ETSI][0][81] = 127, + [0][1][RTW89_MKK][1][81] = 127, + [0][1][RTW89_MKK][0][81] = 127, + [0][1][RTW89_IC][1][81] = -38, + [0][1][RTW89_KCC][1][81] = -14, + [0][1][RTW89_KCC][0][81] = 127, + [0][1][RTW89_ACMA][1][81] = 127, + [0][1][RTW89_ACMA][0][81] = 127, + [0][1][RTW89_CHILE][1][81] = 127, + [0][1][RTW89_QATAR][1][81] = 127, + [0][1][RTW89_QATAR][0][81] = 127, + [0][1][RTW89_UK][1][81] = 127, + [0][1][RTW89_UK][0][81] = 127, + [0][1][RTW89_THAILAND][1][81] = 127, + [0][1][RTW89_THAILAND][0][81] = 127, + [0][1][RTW89_FCC][1][83] = -38, + [0][1][RTW89_ETSI][1][83] = 127, + [0][1][RTW89_ETSI][0][83] = 127, + [0][1][RTW89_MKK][1][83] = 127, + [0][1][RTW89_MKK][0][83] = 127, + [0][1][RTW89_IC][1][83] = -38, + [0][1][RTW89_KCC][1][83] = -14, + [0][1][RTW89_KCC][0][83] = 127, + [0][1][RTW89_ACMA][1][83] = 127, + [0][1][RTW89_ACMA][0][83] = 127, + [0][1][RTW89_CHILE][1][83] = 127, + [0][1][RTW89_QATAR][1][83] = 127, + [0][1][RTW89_QATAR][0][83] = 127, + [0][1][RTW89_UK][1][83] = 127, + [0][1][RTW89_UK][0][83] = 127, + [0][1][RTW89_THAILAND][1][83] = 127, + [0][1][RTW89_THAILAND][0][83] = 127, + [0][1][RTW89_FCC][1][85] = -38, + [0][1][RTW89_ETSI][1][85] = 127, + [0][1][RTW89_ETSI][0][85] = 127, + [0][1][RTW89_MKK][1][85] = 127, + [0][1][RTW89_MKK][0][85] = 127, + [0][1][RTW89_IC][1][85] = -38, + [0][1][RTW89_KCC][1][85] = -14, + [0][1][RTW89_KCC][0][85] = 127, + [0][1][RTW89_ACMA][1][85] = 127, + [0][1][RTW89_ACMA][0][85] = 127, + [0][1][RTW89_CHILE][1][85] = 127, + [0][1][RTW89_QATAR][1][85] = 127, + [0][1][RTW89_QATAR][0][85] = 127, + [0][1][RTW89_UK][1][85] = 127, + [0][1][RTW89_UK][0][85] = 127, + [0][1][RTW89_THAILAND][1][85] = 127, + [0][1][RTW89_THAILAND][0][85] = 127, + [0][1][RTW89_FCC][1][87] = -40, + [0][1][RTW89_ETSI][1][87] = 127, + [0][1][RTW89_ETSI][0][87] = 127, + [0][1][RTW89_MKK][1][87] = 127, + [0][1][RTW89_MKK][0][87] = 127, + [0][1][RTW89_IC][1][87] = -40, + [0][1][RTW89_KCC][1][87] = -14, + [0][1][RTW89_KCC][0][87] = 127, + [0][1][RTW89_ACMA][1][87] = 127, + [0][1][RTW89_ACMA][0][87] = 127, + [0][1][RTW89_CHILE][1][87] = 127, + [0][1][RTW89_QATAR][1][87] = 127, + [0][1][RTW89_QATAR][0][87] = 127, + [0][1][RTW89_UK][1][87] = 127, + [0][1][RTW89_UK][0][87] = 127, + [0][1][RTW89_THAILAND][1][87] = 127, + [0][1][RTW89_THAILAND][0][87] = 127, + [0][1][RTW89_FCC][1][89] = -38, + [0][1][RTW89_ETSI][1][89] = 127, + [0][1][RTW89_ETSI][0][89] = 127, + [0][1][RTW89_MKK][1][89] = 127, + [0][1][RTW89_MKK][0][89] = 127, + [0][1][RTW89_IC][1][89] = -38, + [0][1][RTW89_KCC][1][89] = -14, + [0][1][RTW89_KCC][0][89] = 127, + [0][1][RTW89_ACMA][1][89] = 127, + [0][1][RTW89_ACMA][0][89] = 127, + [0][1][RTW89_CHILE][1][89] = 127, + [0][1][RTW89_QATAR][1][89] = 127, + [0][1][RTW89_QATAR][0][89] = 127, + [0][1][RTW89_UK][1][89] = 127, + [0][1][RTW89_UK][0][89] = 127, + [0][1][RTW89_THAILAND][1][89] = 127, + [0][1][RTW89_THAILAND][0][89] = 127, + [0][1][RTW89_FCC][1][90] = -38, + [0][1][RTW89_ETSI][1][90] = 127, + [0][1][RTW89_ETSI][0][90] = 127, + [0][1][RTW89_MKK][1][90] = 127, + [0][1][RTW89_MKK][0][90] = 127, + [0][1][RTW89_IC][1][90] = -38, + [0][1][RTW89_KCC][1][90] = -14, + [0][1][RTW89_KCC][0][90] = 127, + [0][1][RTW89_ACMA][1][90] = 127, + [0][1][RTW89_ACMA][0][90] = 127, + [0][1][RTW89_CHILE][1][90] = 127, + [0][1][RTW89_QATAR][1][90] = 127, + [0][1][RTW89_QATAR][0][90] = 127, + [0][1][RTW89_UK][1][90] = 127, + [0][1][RTW89_UK][0][90] = 127, + [0][1][RTW89_THAILAND][1][90] = 127, + [0][1][RTW89_THAILAND][0][90] = 127, + [0][1][RTW89_FCC][1][92] = -38, + [0][1][RTW89_ETSI][1][92] = 127, + [0][1][RTW89_ETSI][0][92] = 127, + [0][1][RTW89_MKK][1][92] = 127, + [0][1][RTW89_MKK][0][92] = 127, + [0][1][RTW89_IC][1][92] = -38, + [0][1][RTW89_KCC][1][92] = -14, + [0][1][RTW89_KCC][0][92] = 127, + [0][1][RTW89_ACMA][1][92] = 127, + [0][1][RTW89_ACMA][0][92] = 127, + [0][1][RTW89_CHILE][1][92] = 127, + [0][1][RTW89_QATAR][1][92] = 127, + [0][1][RTW89_QATAR][0][92] = 127, + [0][1][RTW89_UK][1][92] = 127, + [0][1][RTW89_UK][0][92] = 127, + [0][1][RTW89_THAILAND][1][92] = 127, + [0][1][RTW89_THAILAND][0][92] = 127, + [0][1][RTW89_FCC][1][94] = -38, + [0][1][RTW89_ETSI][1][94] = 127, + [0][1][RTW89_ETSI][0][94] = 127, + [0][1][RTW89_MKK][1][94] = 127, + [0][1][RTW89_MKK][0][94] = 127, + [0][1][RTW89_IC][1][94] = -38, + [0][1][RTW89_KCC][1][94] = -14, + [0][1][RTW89_KCC][0][94] = 127, + [0][1][RTW89_ACMA][1][94] = 127, + [0][1][RTW89_ACMA][0][94] = 127, + [0][1][RTW89_CHILE][1][94] = 127, + [0][1][RTW89_QATAR][1][94] = 127, + [0][1][RTW89_QATAR][0][94] = 127, + [0][1][RTW89_UK][1][94] = 127, + [0][1][RTW89_UK][0][94] = 127, + [0][1][RTW89_THAILAND][1][94] = 127, + [0][1][RTW89_THAILAND][0][94] = 127, + [0][1][RTW89_FCC][1][96] = -38, + [0][1][RTW89_ETSI][1][96] = 127, + [0][1][RTW89_ETSI][0][96] = 127, + [0][1][RTW89_MKK][1][96] = 127, + [0][1][RTW89_MKK][0][96] = 127, + [0][1][RTW89_IC][1][96] = -38, + [0][1][RTW89_KCC][1][96] = -14, + [0][1][RTW89_KCC][0][96] = 127, + [0][1][RTW89_ACMA][1][96] = 127, + [0][1][RTW89_ACMA][0][96] = 127, + [0][1][RTW89_CHILE][1][96] = 127, + [0][1][RTW89_QATAR][1][96] = 127, + [0][1][RTW89_QATAR][0][96] = 127, + [0][1][RTW89_UK][1][96] = 127, + [0][1][RTW89_UK][0][96] = 127, + [0][1][RTW89_THAILAND][1][96] = 127, + [0][1][RTW89_THAILAND][0][96] = 127, + [0][1][RTW89_FCC][1][98] = -38, + [0][1][RTW89_ETSI][1][98] = 127, + [0][1][RTW89_ETSI][0][98] = 127, + [0][1][RTW89_MKK][1][98] = 127, + [0][1][RTW89_MKK][0][98] = 127, + [0][1][RTW89_IC][1][98] = -38, + [0][1][RTW89_KCC][1][98] = -14, + [0][1][RTW89_KCC][0][98] = 127, + [0][1][RTW89_ACMA][1][98] = 127, + [0][1][RTW89_ACMA][0][98] = 127, + [0][1][RTW89_CHILE][1][98] = 127, + [0][1][RTW89_QATAR][1][98] = 127, + [0][1][RTW89_QATAR][0][98] = 127, + [0][1][RTW89_UK][1][98] = 127, + [0][1][RTW89_UK][0][98] = 127, + [0][1][RTW89_THAILAND][1][98] = 127, + [0][1][RTW89_THAILAND][0][98] = 127, + [0][1][RTW89_FCC][1][100] = -38, + [0][1][RTW89_ETSI][1][100] = 127, + [0][1][RTW89_ETSI][0][100] = 127, + [0][1][RTW89_MKK][1][100] = 127, + [0][1][RTW89_MKK][0][100] = 127, + [0][1][RTW89_IC][1][100] = -38, + [0][1][RTW89_KCC][1][100] = -14, + [0][1][RTW89_KCC][0][100] = 127, + [0][1][RTW89_ACMA][1][100] = 127, + [0][1][RTW89_ACMA][0][100] = 127, + [0][1][RTW89_CHILE][1][100] = 127, + [0][1][RTW89_QATAR][1][100] = 127, + [0][1][RTW89_QATAR][0][100] = 127, + [0][1][RTW89_UK][1][100] = 127, + [0][1][RTW89_UK][0][100] = 127, + [0][1][RTW89_THAILAND][1][100] = 127, + [0][1][RTW89_THAILAND][0][100] = 127, + [0][1][RTW89_FCC][1][102] = -38, + [0][1][RTW89_ETSI][1][102] = 127, + [0][1][RTW89_ETSI][0][102] = 127, + [0][1][RTW89_MKK][1][102] = 127, + [0][1][RTW89_MKK][0][102] = 127, + [0][1][RTW89_IC][1][102] = -38, + [0][1][RTW89_KCC][1][102] = -14, + [0][1][RTW89_KCC][0][102] = 127, + [0][1][RTW89_ACMA][1][102] = 127, + [0][1][RTW89_ACMA][0][102] = 127, + [0][1][RTW89_CHILE][1][102] = 127, + [0][1][RTW89_QATAR][1][102] = 127, + [0][1][RTW89_QATAR][0][102] = 127, + [0][1][RTW89_UK][1][102] = 127, + [0][1][RTW89_UK][0][102] = 127, + [0][1][RTW89_THAILAND][1][102] = 127, + [0][1][RTW89_THAILAND][0][102] = 127, + [0][1][RTW89_FCC][1][104] = -38, + [0][1][RTW89_ETSI][1][104] = 127, + [0][1][RTW89_ETSI][0][104] = 127, + [0][1][RTW89_MKK][1][104] = 127, + [0][1][RTW89_MKK][0][104] = 127, + [0][1][RTW89_IC][1][104] = -38, + [0][1][RTW89_KCC][1][104] = -14, + [0][1][RTW89_KCC][0][104] = 127, + [0][1][RTW89_ACMA][1][104] = 127, + [0][1][RTW89_ACMA][0][104] = 127, + [0][1][RTW89_CHILE][1][104] = 127, + [0][1][RTW89_QATAR][1][104] = 127, + [0][1][RTW89_QATAR][0][104] = 127, + [0][1][RTW89_UK][1][104] = 127, + [0][1][RTW89_UK][0][104] = 127, + [0][1][RTW89_THAILAND][1][104] = 127, + [0][1][RTW89_THAILAND][0][104] = 127, + [0][1][RTW89_FCC][1][105] = -38, + [0][1][RTW89_ETSI][1][105] = 127, + [0][1][RTW89_ETSI][0][105] = 127, + [0][1][RTW89_MKK][1][105] = 127, + [0][1][RTW89_MKK][0][105] = 127, + [0][1][RTW89_IC][1][105] = -38, + [0][1][RTW89_KCC][1][105] = -14, + [0][1][RTW89_KCC][0][105] = 127, + [0][1][RTW89_ACMA][1][105] = 127, + [0][1][RTW89_ACMA][0][105] = 127, + [0][1][RTW89_CHILE][1][105] = 127, + [0][1][RTW89_QATAR][1][105] = 127, + [0][1][RTW89_QATAR][0][105] = 127, + [0][1][RTW89_UK][1][105] = 127, + [0][1][RTW89_UK][0][105] = 127, + [0][1][RTW89_THAILAND][1][105] = 127, + [0][1][RTW89_THAILAND][0][105] = 127, + [0][1][RTW89_FCC][1][107] = -34, + [0][1][RTW89_ETSI][1][107] = 127, + [0][1][RTW89_ETSI][0][107] = 127, + [0][1][RTW89_MKK][1][107] = 127, + [0][1][RTW89_MKK][0][107] = 127, + [0][1][RTW89_IC][1][107] = -34, + [0][1][RTW89_KCC][1][107] = -14, + [0][1][RTW89_KCC][0][107] = 127, + [0][1][RTW89_ACMA][1][107] = 127, + [0][1][RTW89_ACMA][0][107] = 127, + [0][1][RTW89_CHILE][1][107] = 127, + [0][1][RTW89_QATAR][1][107] = 127, + [0][1][RTW89_QATAR][0][107] = 127, + [0][1][RTW89_UK][1][107] = 127, + [0][1][RTW89_UK][0][107] = 127, + [0][1][RTW89_THAILAND][1][107] = 127, + [0][1][RTW89_THAILAND][0][107] = 127, + [0][1][RTW89_FCC][1][109] = -34, + [0][1][RTW89_ETSI][1][109] = 127, + [0][1][RTW89_ETSI][0][109] = 127, + [0][1][RTW89_MKK][1][109] = 127, + [0][1][RTW89_MKK][0][109] = 127, + [0][1][RTW89_IC][1][109] = -34, + [0][1][RTW89_KCC][1][109] = 127, + [0][1][RTW89_KCC][0][109] = 127, + [0][1][RTW89_ACMA][1][109] = 127, + [0][1][RTW89_ACMA][0][109] = 127, + [0][1][RTW89_CHILE][1][109] = 127, + [0][1][RTW89_QATAR][1][109] = 127, + [0][1][RTW89_QATAR][0][109] = 127, + [0][1][RTW89_UK][1][109] = 127, + [0][1][RTW89_UK][0][109] = 127, + [0][1][RTW89_THAILAND][1][109] = 127, + [0][1][RTW89_THAILAND][0][109] = 127, + [0][1][RTW89_FCC][1][111] = 127, + [0][1][RTW89_ETSI][1][111] = 127, + [0][1][RTW89_ETSI][0][111] = 127, + [0][1][RTW89_MKK][1][111] = 127, + [0][1][RTW89_MKK][0][111] = 127, + [0][1][RTW89_IC][1][111] = 127, + [0][1][RTW89_KCC][1][111] = 127, + [0][1][RTW89_KCC][0][111] = 127, + [0][1][RTW89_ACMA][1][111] = 127, + [0][1][RTW89_ACMA][0][111] = 127, + [0][1][RTW89_CHILE][1][111] = 127, + [0][1][RTW89_QATAR][1][111] = 127, + [0][1][RTW89_QATAR][0][111] = 127, + [0][1][RTW89_UK][1][111] = 127, + [0][1][RTW89_UK][0][111] = 127, + [0][1][RTW89_THAILAND][1][111] = 127, + [0][1][RTW89_THAILAND][0][111] = 127, + [0][1][RTW89_FCC][1][113] = 127, + [0][1][RTW89_ETSI][1][113] = 127, + [0][1][RTW89_ETSI][0][113] = 127, + [0][1][RTW89_MKK][1][113] = 127, + [0][1][RTW89_MKK][0][113] = 127, + [0][1][RTW89_IC][1][113] = 127, + [0][1][RTW89_KCC][1][113] = 127, + [0][1][RTW89_KCC][0][113] = 127, + [0][1][RTW89_ACMA][1][113] = 127, + [0][1][RTW89_ACMA][0][113] = 127, + [0][1][RTW89_CHILE][1][113] = 127, + [0][1][RTW89_QATAR][1][113] = 127, + [0][1][RTW89_QATAR][0][113] = 127, + [0][1][RTW89_UK][1][113] = 127, + [0][1][RTW89_UK][0][113] = 127, + [0][1][RTW89_THAILAND][1][113] = 127, + [0][1][RTW89_THAILAND][0][113] = 127, + [0][1][RTW89_FCC][1][115] = 127, + [0][1][RTW89_ETSI][1][115] = 127, + [0][1][RTW89_ETSI][0][115] = 127, + [0][1][RTW89_MKK][1][115] = 127, + [0][1][RTW89_MKK][0][115] = 127, + [0][1][RTW89_IC][1][115] = 127, + [0][1][RTW89_KCC][1][115] = 127, + [0][1][RTW89_KCC][0][115] = 127, + [0][1][RTW89_ACMA][1][115] = 127, + [0][1][RTW89_ACMA][0][115] = 127, + [0][1][RTW89_CHILE][1][115] = 127, + [0][1][RTW89_QATAR][1][115] = 127, + [0][1][RTW89_QATAR][0][115] = 127, + [0][1][RTW89_UK][1][115] = 127, + [0][1][RTW89_UK][0][115] = 127, + [0][1][RTW89_THAILAND][1][115] = 127, + [0][1][RTW89_THAILAND][0][115] = 127, + [0][1][RTW89_FCC][1][117] = 127, + [0][1][RTW89_ETSI][1][117] = 127, + [0][1][RTW89_ETSI][0][117] = 127, + [0][1][RTW89_MKK][1][117] = 127, + [0][1][RTW89_MKK][0][117] = 127, + [0][1][RTW89_IC][1][117] = 127, + [0][1][RTW89_KCC][1][117] = 127, + [0][1][RTW89_KCC][0][117] = 127, + [0][1][RTW89_ACMA][1][117] = 127, + [0][1][RTW89_ACMA][0][117] = 127, + [0][1][RTW89_CHILE][1][117] = 127, + [0][1][RTW89_QATAR][1][117] = 127, + [0][1][RTW89_QATAR][0][117] = 127, + [0][1][RTW89_UK][1][117] = 127, + [0][1][RTW89_UK][0][117] = 127, + [0][1][RTW89_THAILAND][1][117] = 127, + [0][1][RTW89_THAILAND][0][117] = 127, + [0][1][RTW89_FCC][1][119] = 127, + [0][1][RTW89_ETSI][1][119] = 127, + [0][1][RTW89_ETSI][0][119] = 127, + [0][1][RTW89_MKK][1][119] = 127, + [0][1][RTW89_MKK][0][119] = 127, + [0][1][RTW89_IC][1][119] = 127, + [0][1][RTW89_KCC][1][119] = 127, + [0][1][RTW89_KCC][0][119] = 127, + [0][1][RTW89_ACMA][1][119] = 127, + [0][1][RTW89_ACMA][0][119] = 127, + [0][1][RTW89_CHILE][1][119] = 127, + [0][1][RTW89_QATAR][1][119] = 127, + [0][1][RTW89_QATAR][0][119] = 127, + [0][1][RTW89_UK][1][119] = 127, + [0][1][RTW89_UK][0][119] = 127, + [0][1][RTW89_THAILAND][1][119] = 127, + [0][1][RTW89_THAILAND][0][119] = 127, + [1][0][RTW89_FCC][1][0] = -4, + [1][0][RTW89_ETSI][1][0] = 46, + [1][0][RTW89_ETSI][0][0] = 6, + [1][0][RTW89_MKK][1][0] = 42, + [1][0][RTW89_MKK][0][0] = 2, + [1][0][RTW89_IC][1][0] = -4, + [1][0][RTW89_KCC][1][0] = -2, + [1][0][RTW89_KCC][0][0] = -2, + [1][0][RTW89_ACMA][1][0] = 46, + [1][0][RTW89_ACMA][0][0] = 6, + [1][0][RTW89_CHILE][1][0] = -4, + [1][0][RTW89_QATAR][1][0] = 46, + [1][0][RTW89_QATAR][0][0] = 6, + [1][0][RTW89_UK][1][0] = 46, + [1][0][RTW89_UK][0][0] = 6, + [1][0][RTW89_THAILAND][1][0] = 42, + [1][0][RTW89_THAILAND][0][0] = -4, + [1][0][RTW89_FCC][1][2] = -4, + [1][0][RTW89_ETSI][1][2] = 46, + [1][0][RTW89_ETSI][0][2] = 6, + [1][0][RTW89_MKK][1][2] = 42, + [1][0][RTW89_MKK][0][2] = 2, + [1][0][RTW89_IC][1][2] = -4, + [1][0][RTW89_KCC][1][2] = -2, + [1][0][RTW89_KCC][0][2] = -2, + [1][0][RTW89_ACMA][1][2] = 46, + [1][0][RTW89_ACMA][0][2] = 6, + [1][0][RTW89_CHILE][1][2] = -4, + [1][0][RTW89_QATAR][1][2] = 46, + [1][0][RTW89_QATAR][0][2] = 6, + [1][0][RTW89_UK][1][2] = 46, + [1][0][RTW89_UK][0][2] = 6, + [1][0][RTW89_THAILAND][1][2] = 42, + [1][0][RTW89_THAILAND][0][2] = -4, + [1][0][RTW89_FCC][1][4] = -4, + [1][0][RTW89_ETSI][1][4] = 46, + [1][0][RTW89_ETSI][0][4] = 6, + [1][0][RTW89_MKK][1][4] = 42, + [1][0][RTW89_MKK][0][4] = 2, + [1][0][RTW89_IC][1][4] = -4, + [1][0][RTW89_KCC][1][4] = -2, + [1][0][RTW89_KCC][0][4] = -2, + [1][0][RTW89_ACMA][1][4] = 46, + [1][0][RTW89_ACMA][0][4] = 6, + [1][0][RTW89_CHILE][1][4] = -4, + [1][0][RTW89_QATAR][1][4] = 46, + [1][0][RTW89_QATAR][0][4] = 6, + [1][0][RTW89_UK][1][4] = 46, + [1][0][RTW89_UK][0][4] = 6, + [1][0][RTW89_THAILAND][1][4] = 42, + [1][0][RTW89_THAILAND][0][4] = -4, + [1][0][RTW89_FCC][1][6] = -4, + [1][0][RTW89_ETSI][1][6] = 46, + [1][0][RTW89_ETSI][0][6] = 6, + [1][0][RTW89_MKK][1][6] = 42, + [1][0][RTW89_MKK][0][6] = 2, + [1][0][RTW89_IC][1][6] = -4, + [1][0][RTW89_KCC][1][6] = -2, + [1][0][RTW89_KCC][0][6] = -2, + [1][0][RTW89_ACMA][1][6] = 46, + [1][0][RTW89_ACMA][0][6] = 6, + [1][0][RTW89_CHILE][1][6] = -4, + [1][0][RTW89_QATAR][1][6] = 46, + [1][0][RTW89_QATAR][0][6] = 6, + [1][0][RTW89_UK][1][6] = 46, + [1][0][RTW89_UK][0][6] = 6, + [1][0][RTW89_THAILAND][1][6] = 42, + [1][0][RTW89_THAILAND][0][6] = -4, + [1][0][RTW89_FCC][1][8] = -4, + [1][0][RTW89_ETSI][1][8] = 46, + [1][0][RTW89_ETSI][0][8] = 6, + [1][0][RTW89_MKK][1][8] = 42, + [1][0][RTW89_MKK][0][8] = 2, + [1][0][RTW89_IC][1][8] = -4, + [1][0][RTW89_KCC][1][8] = -2, + [1][0][RTW89_KCC][0][8] = -2, + [1][0][RTW89_ACMA][1][8] = 46, + [1][0][RTW89_ACMA][0][8] = 6, + [1][0][RTW89_CHILE][1][8] = -4, + [1][0][RTW89_QATAR][1][8] = 46, + [1][0][RTW89_QATAR][0][8] = 6, + [1][0][RTW89_UK][1][8] = 46, + [1][0][RTW89_UK][0][8] = 6, + [1][0][RTW89_THAILAND][1][8] = 42, + [1][0][RTW89_THAILAND][0][8] = -4, + [1][0][RTW89_FCC][1][10] = -4, + [1][0][RTW89_ETSI][1][10] = 46, + [1][0][RTW89_ETSI][0][10] = 6, + [1][0][RTW89_MKK][1][10] = 42, + [1][0][RTW89_MKK][0][10] = 2, + [1][0][RTW89_IC][1][10] = -4, + [1][0][RTW89_KCC][1][10] = -2, + [1][0][RTW89_KCC][0][10] = -2, + [1][0][RTW89_ACMA][1][10] = 46, + [1][0][RTW89_ACMA][0][10] = 6, + [1][0][RTW89_CHILE][1][10] = -4, + [1][0][RTW89_QATAR][1][10] = 46, + [1][0][RTW89_QATAR][0][10] = 6, + [1][0][RTW89_UK][1][10] = 46, + [1][0][RTW89_UK][0][10] = 6, + [1][0][RTW89_THAILAND][1][10] = 42, + [1][0][RTW89_THAILAND][0][10] = -4, + [1][0][RTW89_FCC][1][12] = -4, + [1][0][RTW89_ETSI][1][12] = 46, + [1][0][RTW89_ETSI][0][12] = 6, + [1][0][RTW89_MKK][1][12] = 42, + [1][0][RTW89_MKK][0][12] = 2, + [1][0][RTW89_IC][1][12] = -4, + [1][0][RTW89_KCC][1][12] = -2, + [1][0][RTW89_KCC][0][12] = -2, + [1][0][RTW89_ACMA][1][12] = 46, + [1][0][RTW89_ACMA][0][12] = 6, + [1][0][RTW89_CHILE][1][12] = -4, + [1][0][RTW89_QATAR][1][12] = 46, + [1][0][RTW89_QATAR][0][12] = 6, + [1][0][RTW89_UK][1][12] = 46, + [1][0][RTW89_UK][0][12] = 6, + [1][0][RTW89_THAILAND][1][12] = 42, + [1][0][RTW89_THAILAND][0][12] = -4, + [1][0][RTW89_FCC][1][14] = -4, + [1][0][RTW89_ETSI][1][14] = 46, + [1][0][RTW89_ETSI][0][14] = 6, + [1][0][RTW89_MKK][1][14] = 42, + [1][0][RTW89_MKK][0][14] = 2, + [1][0][RTW89_IC][1][14] = -4, + [1][0][RTW89_KCC][1][14] = -2, + [1][0][RTW89_KCC][0][14] = -2, + [1][0][RTW89_ACMA][1][14] = 46, + [1][0][RTW89_ACMA][0][14] = 6, + [1][0][RTW89_CHILE][1][14] = -4, + [1][0][RTW89_QATAR][1][14] = 46, + [1][0][RTW89_QATAR][0][14] = 6, + [1][0][RTW89_UK][1][14] = 46, + [1][0][RTW89_UK][0][14] = 6, + [1][0][RTW89_THAILAND][1][14] = 42, + [1][0][RTW89_THAILAND][0][14] = -4, + [1][0][RTW89_FCC][1][15] = -4, + [1][0][RTW89_ETSI][1][15] = 46, + [1][0][RTW89_ETSI][0][15] = 6, + [1][0][RTW89_MKK][1][15] = 42, + [1][0][RTW89_MKK][0][15] = 2, + [1][0][RTW89_IC][1][15] = -4, + [1][0][RTW89_KCC][1][15] = -2, + [1][0][RTW89_KCC][0][15] = -2, + [1][0][RTW89_ACMA][1][15] = 46, + [1][0][RTW89_ACMA][0][15] = 6, + [1][0][RTW89_CHILE][1][15] = -4, + [1][0][RTW89_QATAR][1][15] = 46, + [1][0][RTW89_QATAR][0][15] = 6, + [1][0][RTW89_UK][1][15] = 46, + [1][0][RTW89_UK][0][15] = 6, + [1][0][RTW89_THAILAND][1][15] = 42, + [1][0][RTW89_THAILAND][0][15] = -4, + [1][0][RTW89_FCC][1][17] = -4, + [1][0][RTW89_ETSI][1][17] = 46, + [1][0][RTW89_ETSI][0][17] = 6, + [1][0][RTW89_MKK][1][17] = 42, + [1][0][RTW89_MKK][0][17] = 2, + [1][0][RTW89_IC][1][17] = -4, + [1][0][RTW89_KCC][1][17] = -2, + [1][0][RTW89_KCC][0][17] = -2, + [1][0][RTW89_ACMA][1][17] = 46, + [1][0][RTW89_ACMA][0][17] = 6, + [1][0][RTW89_CHILE][1][17] = -4, + [1][0][RTW89_QATAR][1][17] = 46, + [1][0][RTW89_QATAR][0][17] = 6, + [1][0][RTW89_UK][1][17] = 46, + [1][0][RTW89_UK][0][17] = 6, + [1][0][RTW89_THAILAND][1][17] = 42, + [1][0][RTW89_THAILAND][0][17] = -4, + [1][0][RTW89_FCC][1][19] = -4, + [1][0][RTW89_ETSI][1][19] = 46, + [1][0][RTW89_ETSI][0][19] = 6, + [1][0][RTW89_MKK][1][19] = 42, + [1][0][RTW89_MKK][0][19] = 2, + [1][0][RTW89_IC][1][19] = -4, + [1][0][RTW89_KCC][1][19] = -2, + [1][0][RTW89_KCC][0][19] = -2, + [1][0][RTW89_ACMA][1][19] = 46, + [1][0][RTW89_ACMA][0][19] = 6, + [1][0][RTW89_CHILE][1][19] = -4, + [1][0][RTW89_QATAR][1][19] = 46, + [1][0][RTW89_QATAR][0][19] = 6, + [1][0][RTW89_UK][1][19] = 46, + [1][0][RTW89_UK][0][19] = 6, + [1][0][RTW89_THAILAND][1][19] = 42, + [1][0][RTW89_THAILAND][0][19] = -4, + [1][0][RTW89_FCC][1][21] = -4, + [1][0][RTW89_ETSI][1][21] = 46, + [1][0][RTW89_ETSI][0][21] = 6, + [1][0][RTW89_MKK][1][21] = 42, + [1][0][RTW89_MKK][0][21] = 2, + [1][0][RTW89_IC][1][21] = -4, + [1][0][RTW89_KCC][1][21] = -2, + [1][0][RTW89_KCC][0][21] = -2, + [1][0][RTW89_ACMA][1][21] = 46, + [1][0][RTW89_ACMA][0][21] = 6, + [1][0][RTW89_CHILE][1][21] = -4, + [1][0][RTW89_QATAR][1][21] = 46, + [1][0][RTW89_QATAR][0][21] = 6, + [1][0][RTW89_UK][1][21] = 46, + [1][0][RTW89_UK][0][21] = 6, + [1][0][RTW89_THAILAND][1][21] = 42, + [1][0][RTW89_THAILAND][0][21] = -4, + [1][0][RTW89_FCC][1][23] = -4, + [1][0][RTW89_ETSI][1][23] = 46, + [1][0][RTW89_ETSI][0][23] = 6, + [1][0][RTW89_MKK][1][23] = 42, + [1][0][RTW89_MKK][0][23] = 2, + [1][0][RTW89_IC][1][23] = -4, + [1][0][RTW89_KCC][1][23] = -2, + [1][0][RTW89_KCC][0][23] = -2, + [1][0][RTW89_ACMA][1][23] = 46, + [1][0][RTW89_ACMA][0][23] = 6, + [1][0][RTW89_CHILE][1][23] = -4, + [1][0][RTW89_QATAR][1][23] = 46, + [1][0][RTW89_QATAR][0][23] = 6, + [1][0][RTW89_UK][1][23] = 46, + [1][0][RTW89_UK][0][23] = 6, + [1][0][RTW89_THAILAND][1][23] = 42, + [1][0][RTW89_THAILAND][0][23] = -4, + [1][0][RTW89_FCC][1][25] = -4, + [1][0][RTW89_ETSI][1][25] = 46, + [1][0][RTW89_ETSI][0][25] = 6, + [1][0][RTW89_MKK][1][25] = 42, + [1][0][RTW89_MKK][0][25] = 2, + [1][0][RTW89_IC][1][25] = -4, + [1][0][RTW89_KCC][1][25] = -2, + [1][0][RTW89_KCC][0][25] = -2, + [1][0][RTW89_ACMA][1][25] = 46, + [1][0][RTW89_ACMA][0][25] = 6, + [1][0][RTW89_CHILE][1][25] = -4, + [1][0][RTW89_QATAR][1][25] = 46, + [1][0][RTW89_QATAR][0][25] = 6, + [1][0][RTW89_UK][1][25] = 46, + [1][0][RTW89_UK][0][25] = 6, + [1][0][RTW89_THAILAND][1][25] = 42, + [1][0][RTW89_THAILAND][0][25] = -4, + [1][0][RTW89_FCC][1][27] = -4, + [1][0][RTW89_ETSI][1][27] = 46, + [1][0][RTW89_ETSI][0][27] = 6, + [1][0][RTW89_MKK][1][27] = 42, + [1][0][RTW89_MKK][0][27] = 2, + [1][0][RTW89_IC][1][27] = -4, + [1][0][RTW89_KCC][1][27] = -2, + [1][0][RTW89_KCC][0][27] = -2, + [1][0][RTW89_ACMA][1][27] = 46, + [1][0][RTW89_ACMA][0][27] = 6, + [1][0][RTW89_CHILE][1][27] = -4, + [1][0][RTW89_QATAR][1][27] = 46, + [1][0][RTW89_QATAR][0][27] = 6, + [1][0][RTW89_UK][1][27] = 46, + [1][0][RTW89_UK][0][27] = 6, + [1][0][RTW89_THAILAND][1][27] = 42, + [1][0][RTW89_THAILAND][0][27] = -4, + [1][0][RTW89_FCC][1][29] = -4, + [1][0][RTW89_ETSI][1][29] = 46, + [1][0][RTW89_ETSI][0][29] = 6, + [1][0][RTW89_MKK][1][29] = 42, + [1][0][RTW89_MKK][0][29] = 2, + [1][0][RTW89_IC][1][29] = -4, + [1][0][RTW89_KCC][1][29] = -2, + [1][0][RTW89_KCC][0][29] = -2, + [1][0][RTW89_ACMA][1][29] = 46, + [1][0][RTW89_ACMA][0][29] = 6, + [1][0][RTW89_CHILE][1][29] = -4, + [1][0][RTW89_QATAR][1][29] = 46, + [1][0][RTW89_QATAR][0][29] = 6, + [1][0][RTW89_UK][1][29] = 46, + [1][0][RTW89_UK][0][29] = 6, + [1][0][RTW89_THAILAND][1][29] = 42, + [1][0][RTW89_THAILAND][0][29] = -4, + [1][0][RTW89_FCC][1][30] = -4, + [1][0][RTW89_ETSI][1][30] = 46, + [1][0][RTW89_ETSI][0][30] = 6, + [1][0][RTW89_MKK][1][30] = 42, + [1][0][RTW89_MKK][0][30] = 2, + [1][0][RTW89_IC][1][30] = -4, + [1][0][RTW89_KCC][1][30] = -2, + [1][0][RTW89_KCC][0][30] = -2, + [1][0][RTW89_ACMA][1][30] = 46, + [1][0][RTW89_ACMA][0][30] = 6, + [1][0][RTW89_CHILE][1][30] = -4, + [1][0][RTW89_QATAR][1][30] = 46, + [1][0][RTW89_QATAR][0][30] = 6, + [1][0][RTW89_UK][1][30] = 46, + [1][0][RTW89_UK][0][30] = 6, + [1][0][RTW89_THAILAND][1][30] = 42, + [1][0][RTW89_THAILAND][0][30] = -4, + [1][0][RTW89_FCC][1][32] = -4, + [1][0][RTW89_ETSI][1][32] = 46, + [1][0][RTW89_ETSI][0][32] = 6, + [1][0][RTW89_MKK][1][32] = 42, + [1][0][RTW89_MKK][0][32] = 2, + [1][0][RTW89_IC][1][32] = -4, + [1][0][RTW89_KCC][1][32] = -2, + [1][0][RTW89_KCC][0][32] = -2, + [1][0][RTW89_ACMA][1][32] = 46, + [1][0][RTW89_ACMA][0][32] = 6, + [1][0][RTW89_CHILE][1][32] = -4, + [1][0][RTW89_QATAR][1][32] = 46, + [1][0][RTW89_QATAR][0][32] = 6, + [1][0][RTW89_UK][1][32] = 46, + [1][0][RTW89_UK][0][32] = 6, + [1][0][RTW89_THAILAND][1][32] = 42, + [1][0][RTW89_THAILAND][0][32] = -4, + [1][0][RTW89_FCC][1][34] = -4, + [1][0][RTW89_ETSI][1][34] = 46, + [1][0][RTW89_ETSI][0][34] = 6, + [1][0][RTW89_MKK][1][34] = 42, + [1][0][RTW89_MKK][0][34] = 2, + [1][0][RTW89_IC][1][34] = -4, + [1][0][RTW89_KCC][1][34] = -2, + [1][0][RTW89_KCC][0][34] = -2, + [1][0][RTW89_ACMA][1][34] = 46, + [1][0][RTW89_ACMA][0][34] = 6, + [1][0][RTW89_CHILE][1][34] = -4, + [1][0][RTW89_QATAR][1][34] = 46, + [1][0][RTW89_QATAR][0][34] = 6, + [1][0][RTW89_UK][1][34] = 46, + [1][0][RTW89_UK][0][34] = 6, + [1][0][RTW89_THAILAND][1][34] = 42, + [1][0][RTW89_THAILAND][0][34] = -4, + [1][0][RTW89_FCC][1][36] = -4, + [1][0][RTW89_ETSI][1][36] = 46, + [1][0][RTW89_ETSI][0][36] = 6, + [1][0][RTW89_MKK][1][36] = 42, + [1][0][RTW89_MKK][0][36] = 2, + [1][0][RTW89_IC][1][36] = -4, + [1][0][RTW89_KCC][1][36] = -2, + [1][0][RTW89_KCC][0][36] = -2, + [1][0][RTW89_ACMA][1][36] = 46, + [1][0][RTW89_ACMA][0][36] = 6, + [1][0][RTW89_CHILE][1][36] = -4, + [1][0][RTW89_QATAR][1][36] = 46, + [1][0][RTW89_QATAR][0][36] = 6, + [1][0][RTW89_UK][1][36] = 46, + [1][0][RTW89_UK][0][36] = 6, + [1][0][RTW89_THAILAND][1][36] = 42, + [1][0][RTW89_THAILAND][0][36] = -4, + [1][0][RTW89_FCC][1][38] = -4, + [1][0][RTW89_ETSI][1][38] = 46, + [1][0][RTW89_ETSI][0][38] = 6, + [1][0][RTW89_MKK][1][38] = 42, + [1][0][RTW89_MKK][0][38] = 2, + [1][0][RTW89_IC][1][38] = -4, + [1][0][RTW89_KCC][1][38] = -2, + [1][0][RTW89_KCC][0][38] = -2, + [1][0][RTW89_ACMA][1][38] = 46, + [1][0][RTW89_ACMA][0][38] = 6, + [1][0][RTW89_CHILE][1][38] = -4, + [1][0][RTW89_QATAR][1][38] = 46, + [1][0][RTW89_QATAR][0][38] = 6, + [1][0][RTW89_UK][1][38] = 46, + [1][0][RTW89_UK][0][38] = 6, + [1][0][RTW89_THAILAND][1][38] = 42, + [1][0][RTW89_THAILAND][0][38] = -4, + [1][0][RTW89_FCC][1][40] = -4, + [1][0][RTW89_ETSI][1][40] = 46, + [1][0][RTW89_ETSI][0][40] = 6, + [1][0][RTW89_MKK][1][40] = 42, + [1][0][RTW89_MKK][0][40] = 2, + [1][0][RTW89_IC][1][40] = -4, + [1][0][RTW89_KCC][1][40] = -2, + [1][0][RTW89_KCC][0][40] = -2, + [1][0][RTW89_ACMA][1][40] = 46, + [1][0][RTW89_ACMA][0][40] = 6, + [1][0][RTW89_CHILE][1][40] = -4, + [1][0][RTW89_QATAR][1][40] = 46, + [1][0][RTW89_QATAR][0][40] = 6, + [1][0][RTW89_UK][1][40] = 46, + [1][0][RTW89_UK][0][40] = 6, + [1][0][RTW89_THAILAND][1][40] = 42, + [1][0][RTW89_THAILAND][0][40] = -4, + [1][0][RTW89_FCC][1][42] = -4, + [1][0][RTW89_ETSI][1][42] = 46, + [1][0][RTW89_ETSI][0][42] = 6, + [1][0][RTW89_MKK][1][42] = 42, + [1][0][RTW89_MKK][0][42] = 2, + [1][0][RTW89_IC][1][42] = -4, + [1][0][RTW89_KCC][1][42] = -2, + [1][0][RTW89_KCC][0][42] = -2, + [1][0][RTW89_ACMA][1][42] = 46, + [1][0][RTW89_ACMA][0][42] = 6, + [1][0][RTW89_CHILE][1][42] = -4, + [1][0][RTW89_QATAR][1][42] = 46, + [1][0][RTW89_QATAR][0][42] = 6, + [1][0][RTW89_UK][1][42] = 46, + [1][0][RTW89_UK][0][42] = 6, + [1][0][RTW89_THAILAND][1][42] = 42, + [1][0][RTW89_THAILAND][0][42] = -4, + [1][0][RTW89_FCC][1][44] = -4, + [1][0][RTW89_ETSI][1][44] = 46, + [1][0][RTW89_ETSI][0][44] = 8, + [1][0][RTW89_MKK][1][44] = 22, + [1][0][RTW89_MKK][0][44] = 4, + [1][0][RTW89_IC][1][44] = -4, + [1][0][RTW89_KCC][1][44] = -2, + [1][0][RTW89_KCC][0][44] = -2, + [1][0][RTW89_ACMA][1][44] = 46, + [1][0][RTW89_ACMA][0][44] = 8, + [1][0][RTW89_CHILE][1][44] = -4, + [1][0][RTW89_QATAR][1][44] = 46, + [1][0][RTW89_QATAR][0][44] = 8, + [1][0][RTW89_UK][1][44] = 46, + [1][0][RTW89_UK][0][44] = 8, + [1][0][RTW89_THAILAND][1][44] = 42, + [1][0][RTW89_THAILAND][0][44] = -4, + [1][0][RTW89_FCC][1][45] = -4, + [1][0][RTW89_ETSI][1][45] = 127, + [1][0][RTW89_ETSI][0][45] = 127, + [1][0][RTW89_MKK][1][45] = 127, + [1][0][RTW89_MKK][0][45] = 127, + [1][0][RTW89_IC][1][45] = -4, + [1][0][RTW89_KCC][1][45] = -2, + [1][0][RTW89_KCC][0][45] = 127, + [1][0][RTW89_ACMA][1][45] = 127, + [1][0][RTW89_ACMA][0][45] = 127, + [1][0][RTW89_CHILE][1][45] = 127, + [1][0][RTW89_QATAR][1][45] = 127, + [1][0][RTW89_QATAR][0][45] = 127, + [1][0][RTW89_UK][1][45] = 127, + [1][0][RTW89_UK][0][45] = 127, + [1][0][RTW89_THAILAND][1][45] = 127, + [1][0][RTW89_THAILAND][0][45] = 127, + [1][0][RTW89_FCC][1][47] = -4, + [1][0][RTW89_ETSI][1][47] = 127, + [1][0][RTW89_ETSI][0][47] = 127, + [1][0][RTW89_MKK][1][47] = 127, + [1][0][RTW89_MKK][0][47] = 127, + [1][0][RTW89_IC][1][47] = -4, + [1][0][RTW89_KCC][1][47] = -2, + [1][0][RTW89_KCC][0][47] = 127, + [1][0][RTW89_ACMA][1][47] = 127, + [1][0][RTW89_ACMA][0][47] = 127, + [1][0][RTW89_CHILE][1][47] = 127, + [1][0][RTW89_QATAR][1][47] = 127, + [1][0][RTW89_QATAR][0][47] = 127, + [1][0][RTW89_UK][1][47] = 127, + [1][0][RTW89_UK][0][47] = 127, + [1][0][RTW89_THAILAND][1][47] = 127, + [1][0][RTW89_THAILAND][0][47] = 127, + [1][0][RTW89_FCC][1][49] = -4, + [1][0][RTW89_ETSI][1][49] = 127, + [1][0][RTW89_ETSI][0][49] = 127, + [1][0][RTW89_MKK][1][49] = 127, + [1][0][RTW89_MKK][0][49] = 127, + [1][0][RTW89_IC][1][49] = -4, + [1][0][RTW89_KCC][1][49] = -2, + [1][0][RTW89_KCC][0][49] = 127, + [1][0][RTW89_ACMA][1][49] = 127, + [1][0][RTW89_ACMA][0][49] = 127, + [1][0][RTW89_CHILE][1][49] = 127, + [1][0][RTW89_QATAR][1][49] = 127, + [1][0][RTW89_QATAR][0][49] = 127, + [1][0][RTW89_UK][1][49] = 127, + [1][0][RTW89_UK][0][49] = 127, + [1][0][RTW89_THAILAND][1][49] = 127, + [1][0][RTW89_THAILAND][0][49] = 127, + [1][0][RTW89_FCC][1][51] = -4, + [1][0][RTW89_ETSI][1][51] = 127, + [1][0][RTW89_ETSI][0][51] = 127, + [1][0][RTW89_MKK][1][51] = 127, + [1][0][RTW89_MKK][0][51] = 127, + [1][0][RTW89_IC][1][51] = -4, + [1][0][RTW89_KCC][1][51] = -2, + [1][0][RTW89_KCC][0][51] = 127, + [1][0][RTW89_ACMA][1][51] = 127, + [1][0][RTW89_ACMA][0][51] = 127, + [1][0][RTW89_CHILE][1][51] = 127, + [1][0][RTW89_QATAR][1][51] = 127, + [1][0][RTW89_QATAR][0][51] = 127, + [1][0][RTW89_UK][1][51] = 127, + [1][0][RTW89_UK][0][51] = 127, + [1][0][RTW89_THAILAND][1][51] = 127, + [1][0][RTW89_THAILAND][0][51] = 127, + [1][0][RTW89_FCC][1][53] = -4, + [1][0][RTW89_ETSI][1][53] = 127, + [1][0][RTW89_ETSI][0][53] = 127, + [1][0][RTW89_MKK][1][53] = 127, + [1][0][RTW89_MKK][0][53] = 127, + [1][0][RTW89_IC][1][53] = -4, + [1][0][RTW89_KCC][1][53] = -2, + [1][0][RTW89_KCC][0][53] = 127, + [1][0][RTW89_ACMA][1][53] = 127, + [1][0][RTW89_ACMA][0][53] = 127, + [1][0][RTW89_CHILE][1][53] = 127, + [1][0][RTW89_QATAR][1][53] = 127, + [1][0][RTW89_QATAR][0][53] = 127, + [1][0][RTW89_UK][1][53] = 127, + [1][0][RTW89_UK][0][53] = 127, + [1][0][RTW89_THAILAND][1][53] = 127, + [1][0][RTW89_THAILAND][0][53] = 127, + [1][0][RTW89_FCC][1][55] = -4, + [1][0][RTW89_ETSI][1][55] = 127, + [1][0][RTW89_ETSI][0][55] = 127, + [1][0][RTW89_MKK][1][55] = 127, + [1][0][RTW89_MKK][0][55] = 127, + [1][0][RTW89_IC][1][55] = -4, + [1][0][RTW89_KCC][1][55] = -2, + [1][0][RTW89_KCC][0][55] = 127, + [1][0][RTW89_ACMA][1][55] = 127, + [1][0][RTW89_ACMA][0][55] = 127, + [1][0][RTW89_CHILE][1][55] = 127, + [1][0][RTW89_QATAR][1][55] = 127, + [1][0][RTW89_QATAR][0][55] = 127, + [1][0][RTW89_UK][1][55] = 127, + [1][0][RTW89_UK][0][55] = 127, + [1][0][RTW89_THAILAND][1][55] = 127, + [1][0][RTW89_THAILAND][0][55] = 127, + [1][0][RTW89_FCC][1][57] = -4, + [1][0][RTW89_ETSI][1][57] = 127, + [1][0][RTW89_ETSI][0][57] = 127, + [1][0][RTW89_MKK][1][57] = 127, + [1][0][RTW89_MKK][0][57] = 127, + [1][0][RTW89_IC][1][57] = -4, + [1][0][RTW89_KCC][1][57] = -2, + [1][0][RTW89_KCC][0][57] = 127, + [1][0][RTW89_ACMA][1][57] = 127, + [1][0][RTW89_ACMA][0][57] = 127, + [1][0][RTW89_CHILE][1][57] = 127, + [1][0][RTW89_QATAR][1][57] = 127, + [1][0][RTW89_QATAR][0][57] = 127, + [1][0][RTW89_UK][1][57] = 127, + [1][0][RTW89_UK][0][57] = 127, + [1][0][RTW89_THAILAND][1][57] = 127, + [1][0][RTW89_THAILAND][0][57] = 127, + [1][0][RTW89_FCC][1][59] = -4, + [1][0][RTW89_ETSI][1][59] = 127, + [1][0][RTW89_ETSI][0][59] = 127, + [1][0][RTW89_MKK][1][59] = 127, + [1][0][RTW89_MKK][0][59] = 127, + [1][0][RTW89_IC][1][59] = -4, + [1][0][RTW89_KCC][1][59] = -2, + [1][0][RTW89_KCC][0][59] = 127, + [1][0][RTW89_ACMA][1][59] = 127, + [1][0][RTW89_ACMA][0][59] = 127, + [1][0][RTW89_CHILE][1][59] = 127, + [1][0][RTW89_QATAR][1][59] = 127, + [1][0][RTW89_QATAR][0][59] = 127, + [1][0][RTW89_UK][1][59] = 127, + [1][0][RTW89_UK][0][59] = 127, + [1][0][RTW89_THAILAND][1][59] = 127, + [1][0][RTW89_THAILAND][0][59] = 127, + [1][0][RTW89_FCC][1][60] = -4, + [1][0][RTW89_ETSI][1][60] = 127, + [1][0][RTW89_ETSI][0][60] = 127, + [1][0][RTW89_MKK][1][60] = 127, + [1][0][RTW89_MKK][0][60] = 127, + [1][0][RTW89_IC][1][60] = -4, + [1][0][RTW89_KCC][1][60] = -2, + [1][0][RTW89_KCC][0][60] = 127, + [1][0][RTW89_ACMA][1][60] = 127, + [1][0][RTW89_ACMA][0][60] = 127, + [1][0][RTW89_CHILE][1][60] = 127, + [1][0][RTW89_QATAR][1][60] = 127, + [1][0][RTW89_QATAR][0][60] = 127, + [1][0][RTW89_UK][1][60] = 127, + [1][0][RTW89_UK][0][60] = 127, + [1][0][RTW89_THAILAND][1][60] = 127, + [1][0][RTW89_THAILAND][0][60] = 127, + [1][0][RTW89_FCC][1][62] = -4, + [1][0][RTW89_ETSI][1][62] = 127, + [1][0][RTW89_ETSI][0][62] = 127, + [1][0][RTW89_MKK][1][62] = 127, + [1][0][RTW89_MKK][0][62] = 127, + [1][0][RTW89_IC][1][62] = -4, + [1][0][RTW89_KCC][1][62] = -2, + [1][0][RTW89_KCC][0][62] = 127, + [1][0][RTW89_ACMA][1][62] = 127, + [1][0][RTW89_ACMA][0][62] = 127, + [1][0][RTW89_CHILE][1][62] = 127, + [1][0][RTW89_QATAR][1][62] = 127, + [1][0][RTW89_QATAR][0][62] = 127, + [1][0][RTW89_UK][1][62] = 127, + [1][0][RTW89_UK][0][62] = 127, + [1][0][RTW89_THAILAND][1][62] = 127, + [1][0][RTW89_THAILAND][0][62] = 127, + [1][0][RTW89_FCC][1][64] = -4, + [1][0][RTW89_ETSI][1][64] = 127, + [1][0][RTW89_ETSI][0][64] = 127, + [1][0][RTW89_MKK][1][64] = 127, + [1][0][RTW89_MKK][0][64] = 127, + [1][0][RTW89_IC][1][64] = -4, + [1][0][RTW89_KCC][1][64] = -2, + [1][0][RTW89_KCC][0][64] = 127, + [1][0][RTW89_ACMA][1][64] = 127, + [1][0][RTW89_ACMA][0][64] = 127, + [1][0][RTW89_CHILE][1][64] = 127, + [1][0][RTW89_QATAR][1][64] = 127, + [1][0][RTW89_QATAR][0][64] = 127, + [1][0][RTW89_UK][1][64] = 127, + [1][0][RTW89_UK][0][64] = 127, + [1][0][RTW89_THAILAND][1][64] = 127, + [1][0][RTW89_THAILAND][0][64] = 127, + [1][0][RTW89_FCC][1][66] = -4, + [1][0][RTW89_ETSI][1][66] = 127, + [1][0][RTW89_ETSI][0][66] = 127, + [1][0][RTW89_MKK][1][66] = 127, + [1][0][RTW89_MKK][0][66] = 127, + [1][0][RTW89_IC][1][66] = -4, + [1][0][RTW89_KCC][1][66] = -2, + [1][0][RTW89_KCC][0][66] = 127, + [1][0][RTW89_ACMA][1][66] = 127, + [1][0][RTW89_ACMA][0][66] = 127, + [1][0][RTW89_CHILE][1][66] = 127, + [1][0][RTW89_QATAR][1][66] = 127, + [1][0][RTW89_QATAR][0][66] = 127, + [1][0][RTW89_UK][1][66] = 127, + [1][0][RTW89_UK][0][66] = 127, + [1][0][RTW89_THAILAND][1][66] = 127, + [1][0][RTW89_THAILAND][0][66] = 127, + [1][0][RTW89_FCC][1][68] = -4, + [1][0][RTW89_ETSI][1][68] = 127, + [1][0][RTW89_ETSI][0][68] = 127, + [1][0][RTW89_MKK][1][68] = 127, + [1][0][RTW89_MKK][0][68] = 127, + [1][0][RTW89_IC][1][68] = -4, + [1][0][RTW89_KCC][1][68] = -2, + [1][0][RTW89_KCC][0][68] = 127, + [1][0][RTW89_ACMA][1][68] = 127, + [1][0][RTW89_ACMA][0][68] = 127, + [1][0][RTW89_CHILE][1][68] = 127, + [1][0][RTW89_QATAR][1][68] = 127, + [1][0][RTW89_QATAR][0][68] = 127, + [1][0][RTW89_UK][1][68] = 127, + [1][0][RTW89_UK][0][68] = 127, + [1][0][RTW89_THAILAND][1][68] = 127, + [1][0][RTW89_THAILAND][0][68] = 127, + [1][0][RTW89_FCC][1][70] = -4, + [1][0][RTW89_ETSI][1][70] = 127, + [1][0][RTW89_ETSI][0][70] = 127, + [1][0][RTW89_MKK][1][70] = 127, + [1][0][RTW89_MKK][0][70] = 127, + [1][0][RTW89_IC][1][70] = -4, + [1][0][RTW89_KCC][1][70] = -2, + [1][0][RTW89_KCC][0][70] = 127, + [1][0][RTW89_ACMA][1][70] = 127, + [1][0][RTW89_ACMA][0][70] = 127, + [1][0][RTW89_CHILE][1][70] = 127, + [1][0][RTW89_QATAR][1][70] = 127, + [1][0][RTW89_QATAR][0][70] = 127, + [1][0][RTW89_UK][1][70] = 127, + [1][0][RTW89_UK][0][70] = 127, + [1][0][RTW89_THAILAND][1][70] = 127, + [1][0][RTW89_THAILAND][0][70] = 127, + [1][0][RTW89_FCC][1][72] = -4, + [1][0][RTW89_ETSI][1][72] = 127, + [1][0][RTW89_ETSI][0][72] = 127, + [1][0][RTW89_MKK][1][72] = 127, + [1][0][RTW89_MKK][0][72] = 127, + [1][0][RTW89_IC][1][72] = -4, + [1][0][RTW89_KCC][1][72] = -2, + [1][0][RTW89_KCC][0][72] = 127, + [1][0][RTW89_ACMA][1][72] = 127, + [1][0][RTW89_ACMA][0][72] = 127, + [1][0][RTW89_CHILE][1][72] = 127, + [1][0][RTW89_QATAR][1][72] = 127, + [1][0][RTW89_QATAR][0][72] = 127, + [1][0][RTW89_UK][1][72] = 127, + [1][0][RTW89_UK][0][72] = 127, + [1][0][RTW89_THAILAND][1][72] = 127, + [1][0][RTW89_THAILAND][0][72] = 127, + [1][0][RTW89_FCC][1][74] = -4, + [1][0][RTW89_ETSI][1][74] = 127, + [1][0][RTW89_ETSI][0][74] = 127, + [1][0][RTW89_MKK][1][74] = 127, + [1][0][RTW89_MKK][0][74] = 127, + [1][0][RTW89_IC][1][74] = -4, + [1][0][RTW89_KCC][1][74] = -2, + [1][0][RTW89_KCC][0][74] = 127, + [1][0][RTW89_ACMA][1][74] = 127, + [1][0][RTW89_ACMA][0][74] = 127, + [1][0][RTW89_CHILE][1][74] = 127, + [1][0][RTW89_QATAR][1][74] = 127, + [1][0][RTW89_QATAR][0][74] = 127, + [1][0][RTW89_UK][1][74] = 127, + [1][0][RTW89_UK][0][74] = 127, + [1][0][RTW89_THAILAND][1][74] = 127, + [1][0][RTW89_THAILAND][0][74] = 127, + [1][0][RTW89_FCC][1][75] = -4, + [1][0][RTW89_ETSI][1][75] = 127, + [1][0][RTW89_ETSI][0][75] = 127, + [1][0][RTW89_MKK][1][75] = 127, + [1][0][RTW89_MKK][0][75] = 127, + [1][0][RTW89_IC][1][75] = -4, + [1][0][RTW89_KCC][1][75] = -2, + [1][0][RTW89_KCC][0][75] = 127, + [1][0][RTW89_ACMA][1][75] = 127, + [1][0][RTW89_ACMA][0][75] = 127, + [1][0][RTW89_CHILE][1][75] = 127, + [1][0][RTW89_QATAR][1][75] = 127, + [1][0][RTW89_QATAR][0][75] = 127, + [1][0][RTW89_UK][1][75] = 127, + [1][0][RTW89_UK][0][75] = 127, + [1][0][RTW89_THAILAND][1][75] = 127, + [1][0][RTW89_THAILAND][0][75] = 127, + [1][0][RTW89_FCC][1][77] = -4, + [1][0][RTW89_ETSI][1][77] = 127, + [1][0][RTW89_ETSI][0][77] = 127, + [1][0][RTW89_MKK][1][77] = 127, + [1][0][RTW89_MKK][0][77] = 127, + [1][0][RTW89_IC][1][77] = -4, + [1][0][RTW89_KCC][1][77] = -2, + [1][0][RTW89_KCC][0][77] = 127, + [1][0][RTW89_ACMA][1][77] = 127, + [1][0][RTW89_ACMA][0][77] = 127, + [1][0][RTW89_CHILE][1][77] = 127, + [1][0][RTW89_QATAR][1][77] = 127, + [1][0][RTW89_QATAR][0][77] = 127, + [1][0][RTW89_UK][1][77] = 127, + [1][0][RTW89_UK][0][77] = 127, + [1][0][RTW89_THAILAND][1][77] = 127, + [1][0][RTW89_THAILAND][0][77] = 127, + [1][0][RTW89_FCC][1][79] = -4, + [1][0][RTW89_ETSI][1][79] = 127, + [1][0][RTW89_ETSI][0][79] = 127, + [1][0][RTW89_MKK][1][79] = 127, + [1][0][RTW89_MKK][0][79] = 127, + [1][0][RTW89_IC][1][79] = -4, + [1][0][RTW89_KCC][1][79] = -2, + [1][0][RTW89_KCC][0][79] = 127, + [1][0][RTW89_ACMA][1][79] = 127, + [1][0][RTW89_ACMA][0][79] = 127, + [1][0][RTW89_CHILE][1][79] = 127, + [1][0][RTW89_QATAR][1][79] = 127, + [1][0][RTW89_QATAR][0][79] = 127, + [1][0][RTW89_UK][1][79] = 127, + [1][0][RTW89_UK][0][79] = 127, + [1][0][RTW89_THAILAND][1][79] = 127, + [1][0][RTW89_THAILAND][0][79] = 127, + [1][0][RTW89_FCC][1][81] = -4, + [1][0][RTW89_ETSI][1][81] = 127, + [1][0][RTW89_ETSI][0][81] = 127, + [1][0][RTW89_MKK][1][81] = 127, + [1][0][RTW89_MKK][0][81] = 127, + [1][0][RTW89_IC][1][81] = -4, + [1][0][RTW89_KCC][1][81] = -2, + [1][0][RTW89_KCC][0][81] = 127, + [1][0][RTW89_ACMA][1][81] = 127, + [1][0][RTW89_ACMA][0][81] = 127, + [1][0][RTW89_CHILE][1][81] = 127, + [1][0][RTW89_QATAR][1][81] = 127, + [1][0][RTW89_QATAR][0][81] = 127, + [1][0][RTW89_UK][1][81] = 127, + [1][0][RTW89_UK][0][81] = 127, + [1][0][RTW89_THAILAND][1][81] = 127, + [1][0][RTW89_THAILAND][0][81] = 127, + [1][0][RTW89_FCC][1][83] = -4, + [1][0][RTW89_ETSI][1][83] = 127, + [1][0][RTW89_ETSI][0][83] = 127, + [1][0][RTW89_MKK][1][83] = 127, + [1][0][RTW89_MKK][0][83] = 127, + [1][0][RTW89_IC][1][83] = -4, + [1][0][RTW89_KCC][1][83] = -2, + [1][0][RTW89_KCC][0][83] = 127, + [1][0][RTW89_ACMA][1][83] = 127, + [1][0][RTW89_ACMA][0][83] = 127, + [1][0][RTW89_CHILE][1][83] = 127, + [1][0][RTW89_QATAR][1][83] = 127, + [1][0][RTW89_QATAR][0][83] = 127, + [1][0][RTW89_UK][1][83] = 127, + [1][0][RTW89_UK][0][83] = 127, + [1][0][RTW89_THAILAND][1][83] = 127, + [1][0][RTW89_THAILAND][0][83] = 127, + [1][0][RTW89_FCC][1][85] = -4, + [1][0][RTW89_ETSI][1][85] = 127, + [1][0][RTW89_ETSI][0][85] = 127, + [1][0][RTW89_MKK][1][85] = 127, + [1][0][RTW89_MKK][0][85] = 127, + [1][0][RTW89_IC][1][85] = -4, + [1][0][RTW89_KCC][1][85] = -2, + [1][0][RTW89_KCC][0][85] = 127, + [1][0][RTW89_ACMA][1][85] = 127, + [1][0][RTW89_ACMA][0][85] = 127, + [1][0][RTW89_CHILE][1][85] = 127, + [1][0][RTW89_QATAR][1][85] = 127, + [1][0][RTW89_QATAR][0][85] = 127, + [1][0][RTW89_UK][1][85] = 127, + [1][0][RTW89_UK][0][85] = 127, + [1][0][RTW89_THAILAND][1][85] = 127, + [1][0][RTW89_THAILAND][0][85] = 127, + [1][0][RTW89_FCC][1][87] = -4, + [1][0][RTW89_ETSI][1][87] = 127, + [1][0][RTW89_ETSI][0][87] = 127, + [1][0][RTW89_MKK][1][87] = 127, + [1][0][RTW89_MKK][0][87] = 127, + [1][0][RTW89_IC][1][87] = -4, + [1][0][RTW89_KCC][1][87] = -2, + [1][0][RTW89_KCC][0][87] = 127, + [1][0][RTW89_ACMA][1][87] = 127, + [1][0][RTW89_ACMA][0][87] = 127, + [1][0][RTW89_CHILE][1][87] = 127, + [1][0][RTW89_QATAR][1][87] = 127, + [1][0][RTW89_QATAR][0][87] = 127, + [1][0][RTW89_UK][1][87] = 127, + [1][0][RTW89_UK][0][87] = 127, + [1][0][RTW89_THAILAND][1][87] = 127, + [1][0][RTW89_THAILAND][0][87] = 127, + [1][0][RTW89_FCC][1][89] = -4, + [1][0][RTW89_ETSI][1][89] = 127, + [1][0][RTW89_ETSI][0][89] = 127, + [1][0][RTW89_MKK][1][89] = 127, + [1][0][RTW89_MKK][0][89] = 127, + [1][0][RTW89_IC][1][89] = -4, + [1][0][RTW89_KCC][1][89] = -2, + [1][0][RTW89_KCC][0][89] = 127, + [1][0][RTW89_ACMA][1][89] = 127, + [1][0][RTW89_ACMA][0][89] = 127, + [1][0][RTW89_CHILE][1][89] = 127, + [1][0][RTW89_QATAR][1][89] = 127, + [1][0][RTW89_QATAR][0][89] = 127, + [1][0][RTW89_UK][1][89] = 127, + [1][0][RTW89_UK][0][89] = 127, + [1][0][RTW89_THAILAND][1][89] = 127, + [1][0][RTW89_THAILAND][0][89] = 127, + [1][0][RTW89_FCC][1][90] = -4, + [1][0][RTW89_ETSI][1][90] = 127, + [1][0][RTW89_ETSI][0][90] = 127, + [1][0][RTW89_MKK][1][90] = 127, + [1][0][RTW89_MKK][0][90] = 127, + [1][0][RTW89_IC][1][90] = -4, + [1][0][RTW89_KCC][1][90] = -2, + [1][0][RTW89_KCC][0][90] = 127, + [1][0][RTW89_ACMA][1][90] = 127, + [1][0][RTW89_ACMA][0][90] = 127, + [1][0][RTW89_CHILE][1][90] = 127, + [1][0][RTW89_QATAR][1][90] = 127, + [1][0][RTW89_QATAR][0][90] = 127, + [1][0][RTW89_UK][1][90] = 127, + [1][0][RTW89_UK][0][90] = 127, + [1][0][RTW89_THAILAND][1][90] = 127, + [1][0][RTW89_THAILAND][0][90] = 127, + [1][0][RTW89_FCC][1][92] = -4, + [1][0][RTW89_ETSI][1][92] = 127, + [1][0][RTW89_ETSI][0][92] = 127, + [1][0][RTW89_MKK][1][92] = 127, + [1][0][RTW89_MKK][0][92] = 127, + [1][0][RTW89_IC][1][92] = -4, + [1][0][RTW89_KCC][1][92] = -2, + [1][0][RTW89_KCC][0][92] = 127, + [1][0][RTW89_ACMA][1][92] = 127, + [1][0][RTW89_ACMA][0][92] = 127, + [1][0][RTW89_CHILE][1][92] = 127, + [1][0][RTW89_QATAR][1][92] = 127, + [1][0][RTW89_QATAR][0][92] = 127, + [1][0][RTW89_UK][1][92] = 127, + [1][0][RTW89_UK][0][92] = 127, + [1][0][RTW89_THAILAND][1][92] = 127, + [1][0][RTW89_THAILAND][0][92] = 127, + [1][0][RTW89_FCC][1][94] = -4, + [1][0][RTW89_ETSI][1][94] = 127, + [1][0][RTW89_ETSI][0][94] = 127, + [1][0][RTW89_MKK][1][94] = 127, + [1][0][RTW89_MKK][0][94] = 127, + [1][0][RTW89_IC][1][94] = -4, + [1][0][RTW89_KCC][1][94] = -2, + [1][0][RTW89_KCC][0][94] = 127, + [1][0][RTW89_ACMA][1][94] = 127, + [1][0][RTW89_ACMA][0][94] = 127, + [1][0][RTW89_CHILE][1][94] = 127, + [1][0][RTW89_QATAR][1][94] = 127, + [1][0][RTW89_QATAR][0][94] = 127, + [1][0][RTW89_UK][1][94] = 127, + [1][0][RTW89_UK][0][94] = 127, + [1][0][RTW89_THAILAND][1][94] = 127, + [1][0][RTW89_THAILAND][0][94] = 127, + [1][0][RTW89_FCC][1][96] = -4, + [1][0][RTW89_ETSI][1][96] = 127, + [1][0][RTW89_ETSI][0][96] = 127, + [1][0][RTW89_MKK][1][96] = 127, + [1][0][RTW89_MKK][0][96] = 127, + [1][0][RTW89_IC][1][96] = -4, + [1][0][RTW89_KCC][1][96] = -2, + [1][0][RTW89_KCC][0][96] = 127, + [1][0][RTW89_ACMA][1][96] = 127, + [1][0][RTW89_ACMA][0][96] = 127, + [1][0][RTW89_CHILE][1][96] = 127, + [1][0][RTW89_QATAR][1][96] = 127, + [1][0][RTW89_QATAR][0][96] = 127, + [1][0][RTW89_UK][1][96] = 127, + [1][0][RTW89_UK][0][96] = 127, + [1][0][RTW89_THAILAND][1][96] = 127, + [1][0][RTW89_THAILAND][0][96] = 127, + [1][0][RTW89_FCC][1][98] = -4, + [1][0][RTW89_ETSI][1][98] = 127, + [1][0][RTW89_ETSI][0][98] = 127, + [1][0][RTW89_MKK][1][98] = 127, + [1][0][RTW89_MKK][0][98] = 127, + [1][0][RTW89_IC][1][98] = -4, + [1][0][RTW89_KCC][1][98] = -2, + [1][0][RTW89_KCC][0][98] = 127, + [1][0][RTW89_ACMA][1][98] = 127, + [1][0][RTW89_ACMA][0][98] = 127, + [1][0][RTW89_CHILE][1][98] = 127, + [1][0][RTW89_QATAR][1][98] = 127, + [1][0][RTW89_QATAR][0][98] = 127, + [1][0][RTW89_UK][1][98] = 127, + [1][0][RTW89_UK][0][98] = 127, + [1][0][RTW89_THAILAND][1][98] = 127, + [1][0][RTW89_THAILAND][0][98] = 127, + [1][0][RTW89_FCC][1][100] = -4, + [1][0][RTW89_ETSI][1][100] = 127, + [1][0][RTW89_ETSI][0][100] = 127, + [1][0][RTW89_MKK][1][100] = 127, + [1][0][RTW89_MKK][0][100] = 127, + [1][0][RTW89_IC][1][100] = -4, + [1][0][RTW89_KCC][1][100] = -2, + [1][0][RTW89_KCC][0][100] = 127, + [1][0][RTW89_ACMA][1][100] = 127, + [1][0][RTW89_ACMA][0][100] = 127, + [1][0][RTW89_CHILE][1][100] = 127, + [1][0][RTW89_QATAR][1][100] = 127, + [1][0][RTW89_QATAR][0][100] = 127, + [1][0][RTW89_UK][1][100] = 127, + [1][0][RTW89_UK][0][100] = 127, + [1][0][RTW89_THAILAND][1][100] = 127, + [1][0][RTW89_THAILAND][0][100] = 127, + [1][0][RTW89_FCC][1][102] = -4, + [1][0][RTW89_ETSI][1][102] = 127, + [1][0][RTW89_ETSI][0][102] = 127, + [1][0][RTW89_MKK][1][102] = 127, + [1][0][RTW89_MKK][0][102] = 127, + [1][0][RTW89_IC][1][102] = -4, + [1][0][RTW89_KCC][1][102] = -2, + [1][0][RTW89_KCC][0][102] = 127, + [1][0][RTW89_ACMA][1][102] = 127, + [1][0][RTW89_ACMA][0][102] = 127, + [1][0][RTW89_CHILE][1][102] = 127, + [1][0][RTW89_QATAR][1][102] = 127, + [1][0][RTW89_QATAR][0][102] = 127, + [1][0][RTW89_UK][1][102] = 127, + [1][0][RTW89_UK][0][102] = 127, + [1][0][RTW89_THAILAND][1][102] = 127, + [1][0][RTW89_THAILAND][0][102] = 127, + [1][0][RTW89_FCC][1][104] = -4, + [1][0][RTW89_ETSI][1][104] = 127, + [1][0][RTW89_ETSI][0][104] = 127, + [1][0][RTW89_MKK][1][104] = 127, + [1][0][RTW89_MKK][0][104] = 127, + [1][0][RTW89_IC][1][104] = -4, + [1][0][RTW89_KCC][1][104] = -2, + [1][0][RTW89_KCC][0][104] = 127, + [1][0][RTW89_ACMA][1][104] = 127, + [1][0][RTW89_ACMA][0][104] = 127, + [1][0][RTW89_CHILE][1][104] = 127, + [1][0][RTW89_QATAR][1][104] = 127, + [1][0][RTW89_QATAR][0][104] = 127, + [1][0][RTW89_UK][1][104] = 127, + [1][0][RTW89_UK][0][104] = 127, + [1][0][RTW89_THAILAND][1][104] = 127, + [1][0][RTW89_THAILAND][0][104] = 127, + [1][0][RTW89_FCC][1][105] = -4, + [1][0][RTW89_ETSI][1][105] = 127, + [1][0][RTW89_ETSI][0][105] = 127, + [1][0][RTW89_MKK][1][105] = 127, + [1][0][RTW89_MKK][0][105] = 127, + [1][0][RTW89_IC][1][105] = -4, + [1][0][RTW89_KCC][1][105] = -2, + [1][0][RTW89_KCC][0][105] = 127, + [1][0][RTW89_ACMA][1][105] = 127, + [1][0][RTW89_ACMA][0][105] = 127, + [1][0][RTW89_CHILE][1][105] = 127, + [1][0][RTW89_QATAR][1][105] = 127, + [1][0][RTW89_QATAR][0][105] = 127, + [1][0][RTW89_UK][1][105] = 127, + [1][0][RTW89_UK][0][105] = 127, + [1][0][RTW89_THAILAND][1][105] = 127, + [1][0][RTW89_THAILAND][0][105] = 127, + [1][0][RTW89_FCC][1][107] = 1, + [1][0][RTW89_ETSI][1][107] = 127, + [1][0][RTW89_ETSI][0][107] = 127, + [1][0][RTW89_MKK][1][107] = 127, + [1][0][RTW89_MKK][0][107] = 127, + [1][0][RTW89_IC][1][107] = 1, + [1][0][RTW89_KCC][1][107] = -2, + [1][0][RTW89_KCC][0][107] = 127, + [1][0][RTW89_ACMA][1][107] = 127, + [1][0][RTW89_ACMA][0][107] = 127, + [1][0][RTW89_CHILE][1][107] = 127, + [1][0][RTW89_QATAR][1][107] = 127, + [1][0][RTW89_QATAR][0][107] = 127, + [1][0][RTW89_UK][1][107] = 127, + [1][0][RTW89_UK][0][107] = 127, + [1][0][RTW89_THAILAND][1][107] = 127, + [1][0][RTW89_THAILAND][0][107] = 127, + [1][0][RTW89_FCC][1][109] = 2, + [1][0][RTW89_ETSI][1][109] = 127, + [1][0][RTW89_ETSI][0][109] = 127, + [1][0][RTW89_MKK][1][109] = 127, + [1][0][RTW89_MKK][0][109] = 127, + [1][0][RTW89_IC][1][109] = 2, + [1][0][RTW89_KCC][1][109] = 127, + [1][0][RTW89_KCC][0][109] = 127, + [1][0][RTW89_ACMA][1][109] = 127, + [1][0][RTW89_ACMA][0][109] = 127, + [1][0][RTW89_CHILE][1][109] = 127, + [1][0][RTW89_QATAR][1][109] = 127, + [1][0][RTW89_QATAR][0][109] = 127, + [1][0][RTW89_UK][1][109] = 127, + [1][0][RTW89_UK][0][109] = 127, + [1][0][RTW89_THAILAND][1][109] = 127, + [1][0][RTW89_THAILAND][0][109] = 127, + [1][0][RTW89_FCC][1][111] = 127, + [1][0][RTW89_ETSI][1][111] = 127, + [1][0][RTW89_ETSI][0][111] = 127, + [1][0][RTW89_MKK][1][111] = 127, + [1][0][RTW89_MKK][0][111] = 127, + [1][0][RTW89_IC][1][111] = 127, + [1][0][RTW89_KCC][1][111] = 127, + [1][0][RTW89_KCC][0][111] = 127, + [1][0][RTW89_ACMA][1][111] = 127, + [1][0][RTW89_ACMA][0][111] = 127, + [1][0][RTW89_CHILE][1][111] = 127, + [1][0][RTW89_QATAR][1][111] = 127, + [1][0][RTW89_QATAR][0][111] = 127, + [1][0][RTW89_UK][1][111] = 127, + [1][0][RTW89_UK][0][111] = 127, + [1][0][RTW89_THAILAND][1][111] = 127, + [1][0][RTW89_THAILAND][0][111] = 127, + [1][0][RTW89_FCC][1][113] = 127, + [1][0][RTW89_ETSI][1][113] = 127, + [1][0][RTW89_ETSI][0][113] = 127, + [1][0][RTW89_MKK][1][113] = 127, + [1][0][RTW89_MKK][0][113] = 127, + [1][0][RTW89_IC][1][113] = 127, + [1][0][RTW89_KCC][1][113] = 127, + [1][0][RTW89_KCC][0][113] = 127, + [1][0][RTW89_ACMA][1][113] = 127, + [1][0][RTW89_ACMA][0][113] = 127, + [1][0][RTW89_CHILE][1][113] = 127, + [1][0][RTW89_QATAR][1][113] = 127, + [1][0][RTW89_QATAR][0][113] = 127, + [1][0][RTW89_UK][1][113] = 127, + [1][0][RTW89_UK][0][113] = 127, + [1][0][RTW89_THAILAND][1][113] = 127, + [1][0][RTW89_THAILAND][0][113] = 127, + [1][0][RTW89_FCC][1][115] = 127, + [1][0][RTW89_ETSI][1][115] = 127, + [1][0][RTW89_ETSI][0][115] = 127, + [1][0][RTW89_MKK][1][115] = 127, + [1][0][RTW89_MKK][0][115] = 127, + [1][0][RTW89_IC][1][115] = 127, + [1][0][RTW89_KCC][1][115] = 127, + [1][0][RTW89_KCC][0][115] = 127, + [1][0][RTW89_ACMA][1][115] = 127, + [1][0][RTW89_ACMA][0][115] = 127, + [1][0][RTW89_CHILE][1][115] = 127, + [1][0][RTW89_QATAR][1][115] = 127, + [1][0][RTW89_QATAR][0][115] = 127, + [1][0][RTW89_UK][1][115] = 127, + [1][0][RTW89_UK][0][115] = 127, + [1][0][RTW89_THAILAND][1][115] = 127, + [1][0][RTW89_THAILAND][0][115] = 127, + [1][0][RTW89_FCC][1][117] = 127, + [1][0][RTW89_ETSI][1][117] = 127, + [1][0][RTW89_ETSI][0][117] = 127, + [1][0][RTW89_MKK][1][117] = 127, + [1][0][RTW89_MKK][0][117] = 127, + [1][0][RTW89_IC][1][117] = 127, + [1][0][RTW89_KCC][1][117] = 127, + [1][0][RTW89_KCC][0][117] = 127, + [1][0][RTW89_ACMA][1][117] = 127, + [1][0][RTW89_ACMA][0][117] = 127, + [1][0][RTW89_CHILE][1][117] = 127, + [1][0][RTW89_QATAR][1][117] = 127, + [1][0][RTW89_QATAR][0][117] = 127, + [1][0][RTW89_UK][1][117] = 127, + [1][0][RTW89_UK][0][117] = 127, + [1][0][RTW89_THAILAND][1][117] = 127, + [1][0][RTW89_THAILAND][0][117] = 127, + [1][0][RTW89_FCC][1][119] = 127, + [1][0][RTW89_ETSI][1][119] = 127, + [1][0][RTW89_ETSI][0][119] = 127, + [1][0][RTW89_MKK][1][119] = 127, + [1][0][RTW89_MKK][0][119] = 127, + [1][0][RTW89_IC][1][119] = 127, + [1][0][RTW89_KCC][1][119] = 127, + [1][0][RTW89_KCC][0][119] = 127, + [1][0][RTW89_ACMA][1][119] = 127, + [1][0][RTW89_ACMA][0][119] = 127, + [1][0][RTW89_CHILE][1][119] = 127, + [1][0][RTW89_QATAR][1][119] = 127, + [1][0][RTW89_QATAR][0][119] = 127, + [1][0][RTW89_UK][1][119] = 127, + [1][0][RTW89_UK][0][119] = 127, + [1][0][RTW89_THAILAND][1][119] = 127, + [1][0][RTW89_THAILAND][0][119] = 127, + [1][1][RTW89_FCC][1][0] = -26, + [1][1][RTW89_ETSI][1][0] = 32, + [1][1][RTW89_ETSI][0][0] = -6, + [1][1][RTW89_MKK][1][0] = 30, + [1][1][RTW89_MKK][0][0] = -10, + [1][1][RTW89_IC][1][0] = -26, + [1][1][RTW89_KCC][1][0] = -14, + [1][1][RTW89_KCC][0][0] = -14, + [1][1][RTW89_ACMA][1][0] = 32, + [1][1][RTW89_ACMA][0][0] = -6, + [1][1][RTW89_CHILE][1][0] = -26, + [1][1][RTW89_QATAR][1][0] = 32, + [1][1][RTW89_QATAR][0][0] = -6, + [1][1][RTW89_UK][1][0] = 32, + [1][1][RTW89_UK][0][0] = -6, + [1][1][RTW89_THAILAND][1][0] = 18, + [1][1][RTW89_THAILAND][0][0] = -26, + [1][1][RTW89_FCC][1][2] = -28, + [1][1][RTW89_ETSI][1][2] = 32, + [1][1][RTW89_ETSI][0][2] = -6, + [1][1][RTW89_MKK][1][2] = 30, + [1][1][RTW89_MKK][0][2] = -10, + [1][1][RTW89_IC][1][2] = -28, + [1][1][RTW89_KCC][1][2] = -14, + [1][1][RTW89_KCC][0][2] = -14, + [1][1][RTW89_ACMA][1][2] = 32, + [1][1][RTW89_ACMA][0][2] = -6, + [1][1][RTW89_CHILE][1][2] = -28, + [1][1][RTW89_QATAR][1][2] = 32, + [1][1][RTW89_QATAR][0][2] = -6, + [1][1][RTW89_UK][1][2] = 32, + [1][1][RTW89_UK][0][2] = -6, + [1][1][RTW89_THAILAND][1][2] = 18, + [1][1][RTW89_THAILAND][0][2] = -28, + [1][1][RTW89_FCC][1][4] = -28, + [1][1][RTW89_ETSI][1][4] = 32, + [1][1][RTW89_ETSI][0][4] = -6, + [1][1][RTW89_MKK][1][4] = 30, + [1][1][RTW89_MKK][0][4] = -10, + [1][1][RTW89_IC][1][4] = -28, + [1][1][RTW89_KCC][1][4] = -14, + [1][1][RTW89_KCC][0][4] = -14, + [1][1][RTW89_ACMA][1][4] = 32, + [1][1][RTW89_ACMA][0][4] = -6, + [1][1][RTW89_CHILE][1][4] = -28, + [1][1][RTW89_QATAR][1][4] = 32, + [1][1][RTW89_QATAR][0][4] = -6, + [1][1][RTW89_UK][1][4] = 32, + [1][1][RTW89_UK][0][4] = -6, + [1][1][RTW89_THAILAND][1][4] = 18, + [1][1][RTW89_THAILAND][0][4] = -28, + [1][1][RTW89_FCC][1][6] = -28, + [1][1][RTW89_ETSI][1][6] = 32, + [1][1][RTW89_ETSI][0][6] = -6, + [1][1][RTW89_MKK][1][6] = 30, + [1][1][RTW89_MKK][0][6] = -10, + [1][1][RTW89_IC][1][6] = -28, + [1][1][RTW89_KCC][1][6] = -14, + [1][1][RTW89_KCC][0][6] = -14, + [1][1][RTW89_ACMA][1][6] = 32, + [1][1][RTW89_ACMA][0][6] = -6, + [1][1][RTW89_CHILE][1][6] = -28, + [1][1][RTW89_QATAR][1][6] = 32, + [1][1][RTW89_QATAR][0][6] = -6, + [1][1][RTW89_UK][1][6] = 32, + [1][1][RTW89_UK][0][6] = -6, + [1][1][RTW89_THAILAND][1][6] = 18, + [1][1][RTW89_THAILAND][0][6] = -28, + [1][1][RTW89_FCC][1][8] = -28, + [1][1][RTW89_ETSI][1][8] = 32, + [1][1][RTW89_ETSI][0][8] = -6, + [1][1][RTW89_MKK][1][8] = 30, + [1][1][RTW89_MKK][0][8] = -10, + [1][1][RTW89_IC][1][8] = -28, + [1][1][RTW89_KCC][1][8] = -14, + [1][1][RTW89_KCC][0][8] = -14, + [1][1][RTW89_ACMA][1][8] = 32, + [1][1][RTW89_ACMA][0][8] = -6, + [1][1][RTW89_CHILE][1][8] = -28, + [1][1][RTW89_QATAR][1][8] = 32, + [1][1][RTW89_QATAR][0][8] = -6, + [1][1][RTW89_UK][1][8] = 32, + [1][1][RTW89_UK][0][8] = -6, + [1][1][RTW89_THAILAND][1][8] = 18, + [1][1][RTW89_THAILAND][0][8] = -28, + [1][1][RTW89_FCC][1][10] = -28, + [1][1][RTW89_ETSI][1][10] = 32, + [1][1][RTW89_ETSI][0][10] = -6, + [1][1][RTW89_MKK][1][10] = 30, + [1][1][RTW89_MKK][0][10] = -10, + [1][1][RTW89_IC][1][10] = -28, + [1][1][RTW89_KCC][1][10] = -14, + [1][1][RTW89_KCC][0][10] = -14, + [1][1][RTW89_ACMA][1][10] = 32, + [1][1][RTW89_ACMA][0][10] = -6, + [1][1][RTW89_CHILE][1][10] = -28, + [1][1][RTW89_QATAR][1][10] = 32, + [1][1][RTW89_QATAR][0][10] = -6, + [1][1][RTW89_UK][1][10] = 32, + [1][1][RTW89_UK][0][10] = -6, + [1][1][RTW89_THAILAND][1][10] = 18, + [1][1][RTW89_THAILAND][0][10] = -28, + [1][1][RTW89_FCC][1][12] = -28, + [1][1][RTW89_ETSI][1][12] = 32, + [1][1][RTW89_ETSI][0][12] = -6, + [1][1][RTW89_MKK][1][12] = 30, + [1][1][RTW89_MKK][0][12] = -10, + [1][1][RTW89_IC][1][12] = -28, + [1][1][RTW89_KCC][1][12] = -14, + [1][1][RTW89_KCC][0][12] = -14, + [1][1][RTW89_ACMA][1][12] = 32, + [1][1][RTW89_ACMA][0][12] = -6, + [1][1][RTW89_CHILE][1][12] = -28, + [1][1][RTW89_QATAR][1][12] = 32, + [1][1][RTW89_QATAR][0][12] = -6, + [1][1][RTW89_UK][1][12] = 32, + [1][1][RTW89_UK][0][12] = -6, + [1][1][RTW89_THAILAND][1][12] = 18, + [1][1][RTW89_THAILAND][0][12] = -28, + [1][1][RTW89_FCC][1][14] = -28, + [1][1][RTW89_ETSI][1][14] = 32, + [1][1][RTW89_ETSI][0][14] = -6, + [1][1][RTW89_MKK][1][14] = 30, + [1][1][RTW89_MKK][0][14] = -10, + [1][1][RTW89_IC][1][14] = -28, + [1][1][RTW89_KCC][1][14] = -14, + [1][1][RTW89_KCC][0][14] = -14, + [1][1][RTW89_ACMA][1][14] = 32, + [1][1][RTW89_ACMA][0][14] = -6, + [1][1][RTW89_CHILE][1][14] = -28, + [1][1][RTW89_QATAR][1][14] = 32, + [1][1][RTW89_QATAR][0][14] = -6, + [1][1][RTW89_UK][1][14] = 32, + [1][1][RTW89_UK][0][14] = -6, + [1][1][RTW89_THAILAND][1][14] = 18, + [1][1][RTW89_THAILAND][0][14] = -28, + [1][1][RTW89_FCC][1][15] = -28, + [1][1][RTW89_ETSI][1][15] = 32, + [1][1][RTW89_ETSI][0][15] = -6, + [1][1][RTW89_MKK][1][15] = 30, + [1][1][RTW89_MKK][0][15] = -10, + [1][1][RTW89_IC][1][15] = -28, + [1][1][RTW89_KCC][1][15] = -14, + [1][1][RTW89_KCC][0][15] = -14, + [1][1][RTW89_ACMA][1][15] = 32, + [1][1][RTW89_ACMA][0][15] = -6, + [1][1][RTW89_CHILE][1][15] = -28, + [1][1][RTW89_QATAR][1][15] = 32, + [1][1][RTW89_QATAR][0][15] = -6, + [1][1][RTW89_UK][1][15] = 32, + [1][1][RTW89_UK][0][15] = -6, + [1][1][RTW89_THAILAND][1][15] = 18, + [1][1][RTW89_THAILAND][0][15] = -28, + [1][1][RTW89_FCC][1][17] = -28, + [1][1][RTW89_ETSI][1][17] = 32, + [1][1][RTW89_ETSI][0][17] = -6, + [1][1][RTW89_MKK][1][17] = 30, + [1][1][RTW89_MKK][0][17] = -10, + [1][1][RTW89_IC][1][17] = -28, + [1][1][RTW89_KCC][1][17] = -14, + [1][1][RTW89_KCC][0][17] = -14, + [1][1][RTW89_ACMA][1][17] = 32, + [1][1][RTW89_ACMA][0][17] = -6, + [1][1][RTW89_CHILE][1][17] = -28, + [1][1][RTW89_QATAR][1][17] = 32, + [1][1][RTW89_QATAR][0][17] = -6, + [1][1][RTW89_UK][1][17] = 32, + [1][1][RTW89_UK][0][17] = -6, + [1][1][RTW89_THAILAND][1][17] = 18, + [1][1][RTW89_THAILAND][0][17] = -28, + [1][1][RTW89_FCC][1][19] = -28, + [1][1][RTW89_ETSI][1][19] = 32, + [1][1][RTW89_ETSI][0][19] = -6, + [1][1][RTW89_MKK][1][19] = 30, + [1][1][RTW89_MKK][0][19] = -10, + [1][1][RTW89_IC][1][19] = -28, + [1][1][RTW89_KCC][1][19] = -14, + [1][1][RTW89_KCC][0][19] = -14, + [1][1][RTW89_ACMA][1][19] = 32, + [1][1][RTW89_ACMA][0][19] = -6, + [1][1][RTW89_CHILE][1][19] = -28, + [1][1][RTW89_QATAR][1][19] = 32, + [1][1][RTW89_QATAR][0][19] = -6, + [1][1][RTW89_UK][1][19] = 32, + [1][1][RTW89_UK][0][19] = -6, + [1][1][RTW89_THAILAND][1][19] = 18, + [1][1][RTW89_THAILAND][0][19] = -28, + [1][1][RTW89_FCC][1][21] = -28, + [1][1][RTW89_ETSI][1][21] = 32, + [1][1][RTW89_ETSI][0][21] = -6, + [1][1][RTW89_MKK][1][21] = 30, + [1][1][RTW89_MKK][0][21] = -10, + [1][1][RTW89_IC][1][21] = -28, + [1][1][RTW89_KCC][1][21] = -14, + [1][1][RTW89_KCC][0][21] = -14, + [1][1][RTW89_ACMA][1][21] = 32, + [1][1][RTW89_ACMA][0][21] = -6, + [1][1][RTW89_CHILE][1][21] = -28, + [1][1][RTW89_QATAR][1][21] = 32, + [1][1][RTW89_QATAR][0][21] = -6, + [1][1][RTW89_UK][1][21] = 32, + [1][1][RTW89_UK][0][21] = -6, + [1][1][RTW89_THAILAND][1][21] = 18, + [1][1][RTW89_THAILAND][0][21] = -28, + [1][1][RTW89_FCC][1][23] = -28, + [1][1][RTW89_ETSI][1][23] = 32, + [1][1][RTW89_ETSI][0][23] = -6, + [1][1][RTW89_MKK][1][23] = 32, + [1][1][RTW89_MKK][0][23] = -10, + [1][1][RTW89_IC][1][23] = -28, + [1][1][RTW89_KCC][1][23] = -14, + [1][1][RTW89_KCC][0][23] = -14, + [1][1][RTW89_ACMA][1][23] = 32, + [1][1][RTW89_ACMA][0][23] = -6, + [1][1][RTW89_CHILE][1][23] = -28, + [1][1][RTW89_QATAR][1][23] = 32, + [1][1][RTW89_QATAR][0][23] = -6, + [1][1][RTW89_UK][1][23] = 32, + [1][1][RTW89_UK][0][23] = -6, + [1][1][RTW89_THAILAND][1][23] = 18, + [1][1][RTW89_THAILAND][0][23] = -28, + [1][1][RTW89_FCC][1][25] = -28, + [1][1][RTW89_ETSI][1][25] = 32, + [1][1][RTW89_ETSI][0][25] = -6, + [1][1][RTW89_MKK][1][25] = 32, + [1][1][RTW89_MKK][0][25] = -10, + [1][1][RTW89_IC][1][25] = -28, + [1][1][RTW89_KCC][1][25] = -14, + [1][1][RTW89_KCC][0][25] = -14, + [1][1][RTW89_ACMA][1][25] = 32, + [1][1][RTW89_ACMA][0][25] = -6, + [1][1][RTW89_CHILE][1][25] = -28, + [1][1][RTW89_QATAR][1][25] = 32, + [1][1][RTW89_QATAR][0][25] = -6, + [1][1][RTW89_UK][1][25] = 32, + [1][1][RTW89_UK][0][25] = -6, + [1][1][RTW89_THAILAND][1][25] = 18, + [1][1][RTW89_THAILAND][0][25] = -28, + [1][1][RTW89_FCC][1][27] = -28, + [1][1][RTW89_ETSI][1][27] = 32, + [1][1][RTW89_ETSI][0][27] = -6, + [1][1][RTW89_MKK][1][27] = 32, + [1][1][RTW89_MKK][0][27] = -10, + [1][1][RTW89_IC][1][27] = -28, + [1][1][RTW89_KCC][1][27] = -14, + [1][1][RTW89_KCC][0][27] = -14, + [1][1][RTW89_ACMA][1][27] = 32, + [1][1][RTW89_ACMA][0][27] = -6, + [1][1][RTW89_CHILE][1][27] = -28, + [1][1][RTW89_QATAR][1][27] = 32, + [1][1][RTW89_QATAR][0][27] = -6, + [1][1][RTW89_UK][1][27] = 32, + [1][1][RTW89_UK][0][27] = -6, + [1][1][RTW89_THAILAND][1][27] = 18, + [1][1][RTW89_THAILAND][0][27] = -28, + [1][1][RTW89_FCC][1][29] = -28, + [1][1][RTW89_ETSI][1][29] = 32, + [1][1][RTW89_ETSI][0][29] = -6, + [1][1][RTW89_MKK][1][29] = 32, + [1][1][RTW89_MKK][0][29] = -10, + [1][1][RTW89_IC][1][29] = -28, + [1][1][RTW89_KCC][1][29] = -14, + [1][1][RTW89_KCC][0][29] = -14, + [1][1][RTW89_ACMA][1][29] = 32, + [1][1][RTW89_ACMA][0][29] = -6, + [1][1][RTW89_CHILE][1][29] = -28, + [1][1][RTW89_QATAR][1][29] = 32, + [1][1][RTW89_QATAR][0][29] = -6, + [1][1][RTW89_UK][1][29] = 32, + [1][1][RTW89_UK][0][29] = -6, + [1][1][RTW89_THAILAND][1][29] = 18, + [1][1][RTW89_THAILAND][0][29] = -28, + [1][1][RTW89_FCC][1][30] = -28, + [1][1][RTW89_ETSI][1][30] = 32, + [1][1][RTW89_ETSI][0][30] = -6, + [1][1][RTW89_MKK][1][30] = 32, + [1][1][RTW89_MKK][0][30] = -10, + [1][1][RTW89_IC][1][30] = -28, + [1][1][RTW89_KCC][1][30] = -14, + [1][1][RTW89_KCC][0][30] = -14, + [1][1][RTW89_ACMA][1][30] = 32, + [1][1][RTW89_ACMA][0][30] = -6, + [1][1][RTW89_CHILE][1][30] = -28, + [1][1][RTW89_QATAR][1][30] = 32, + [1][1][RTW89_QATAR][0][30] = -6, + [1][1][RTW89_UK][1][30] = 32, + [1][1][RTW89_UK][0][30] = -6, + [1][1][RTW89_THAILAND][1][30] = 18, + [1][1][RTW89_THAILAND][0][30] = -28, + [1][1][RTW89_FCC][1][32] = -28, + [1][1][RTW89_ETSI][1][32] = 32, + [1][1][RTW89_ETSI][0][32] = -6, + [1][1][RTW89_MKK][1][32] = 32, + [1][1][RTW89_MKK][0][32] = -10, + [1][1][RTW89_IC][1][32] = -28, + [1][1][RTW89_KCC][1][32] = -14, + [1][1][RTW89_KCC][0][32] = -14, + [1][1][RTW89_ACMA][1][32] = 32, + [1][1][RTW89_ACMA][0][32] = -6, + [1][1][RTW89_CHILE][1][32] = -28, + [1][1][RTW89_QATAR][1][32] = 32, + [1][1][RTW89_QATAR][0][32] = -6, + [1][1][RTW89_UK][1][32] = 32, + [1][1][RTW89_UK][0][32] = -6, + [1][1][RTW89_THAILAND][1][32] = 18, + [1][1][RTW89_THAILAND][0][32] = -28, + [1][1][RTW89_FCC][1][34] = -28, + [1][1][RTW89_ETSI][1][34] = 32, + [1][1][RTW89_ETSI][0][34] = -6, + [1][1][RTW89_MKK][1][34] = 32, + [1][1][RTW89_MKK][0][34] = -10, + [1][1][RTW89_IC][1][34] = -28, + [1][1][RTW89_KCC][1][34] = -14, + [1][1][RTW89_KCC][0][34] = -14, + [1][1][RTW89_ACMA][1][34] = 32, + [1][1][RTW89_ACMA][0][34] = -6, + [1][1][RTW89_CHILE][1][34] = -28, + [1][1][RTW89_QATAR][1][34] = 32, + [1][1][RTW89_QATAR][0][34] = -6, + [1][1][RTW89_UK][1][34] = 32, + [1][1][RTW89_UK][0][34] = -6, + [1][1][RTW89_THAILAND][1][34] = 18, + [1][1][RTW89_THAILAND][0][34] = -28, + [1][1][RTW89_FCC][1][36] = -28, + [1][1][RTW89_ETSI][1][36] = 32, + [1][1][RTW89_ETSI][0][36] = -6, + [1][1][RTW89_MKK][1][36] = 32, + [1][1][RTW89_MKK][0][36] = -10, + [1][1][RTW89_IC][1][36] = -28, + [1][1][RTW89_KCC][1][36] = -14, + [1][1][RTW89_KCC][0][36] = -14, + [1][1][RTW89_ACMA][1][36] = 32, + [1][1][RTW89_ACMA][0][36] = -6, + [1][1][RTW89_CHILE][1][36] = -28, + [1][1][RTW89_QATAR][1][36] = 32, + [1][1][RTW89_QATAR][0][36] = -6, + [1][1][RTW89_UK][1][36] = 32, + [1][1][RTW89_UK][0][36] = -6, + [1][1][RTW89_THAILAND][1][36] = 18, + [1][1][RTW89_THAILAND][0][36] = -28, + [1][1][RTW89_FCC][1][38] = -28, + [1][1][RTW89_ETSI][1][38] = 32, + [1][1][RTW89_ETSI][0][38] = -6, + [1][1][RTW89_MKK][1][38] = 32, + [1][1][RTW89_MKK][0][38] = -10, + [1][1][RTW89_IC][1][38] = -28, + [1][1][RTW89_KCC][1][38] = -14, + [1][1][RTW89_KCC][0][38] = -14, + [1][1][RTW89_ACMA][1][38] = 32, + [1][1][RTW89_ACMA][0][38] = -6, + [1][1][RTW89_CHILE][1][38] = -28, + [1][1][RTW89_QATAR][1][38] = 32, + [1][1][RTW89_QATAR][0][38] = -6, + [1][1][RTW89_UK][1][38] = 32, + [1][1][RTW89_UK][0][38] = -6, + [1][1][RTW89_THAILAND][1][38] = 18, + [1][1][RTW89_THAILAND][0][38] = -28, + [1][1][RTW89_FCC][1][40] = -28, + [1][1][RTW89_ETSI][1][40] = 32, + [1][1][RTW89_ETSI][0][40] = -6, + [1][1][RTW89_MKK][1][40] = 32, + [1][1][RTW89_MKK][0][40] = -10, + [1][1][RTW89_IC][1][40] = -28, + [1][1][RTW89_KCC][1][40] = -14, + [1][1][RTW89_KCC][0][40] = -14, + [1][1][RTW89_ACMA][1][40] = 32, + [1][1][RTW89_ACMA][0][40] = -6, + [1][1][RTW89_CHILE][1][40] = -28, + [1][1][RTW89_QATAR][1][40] = 32, + [1][1][RTW89_QATAR][0][40] = -6, + [1][1][RTW89_UK][1][40] = 32, + [1][1][RTW89_UK][0][40] = -6, + [1][1][RTW89_THAILAND][1][40] = 18, + [1][1][RTW89_THAILAND][0][40] = -28, + [1][1][RTW89_FCC][1][42] = -28, + [1][1][RTW89_ETSI][1][42] = 32, + [1][1][RTW89_ETSI][0][42] = -6, + [1][1][RTW89_MKK][1][42] = 32, + [1][1][RTW89_MKK][0][42] = -10, + [1][1][RTW89_IC][1][42] = -28, + [1][1][RTW89_KCC][1][42] = -14, + [1][1][RTW89_KCC][0][42] = -14, + [1][1][RTW89_ACMA][1][42] = 32, + [1][1][RTW89_ACMA][0][42] = -6, + [1][1][RTW89_CHILE][1][42] = -28, + [1][1][RTW89_QATAR][1][42] = 32, + [1][1][RTW89_QATAR][0][42] = -6, + [1][1][RTW89_UK][1][42] = 32, + [1][1][RTW89_UK][0][42] = -6, + [1][1][RTW89_THAILAND][1][42] = 18, + [1][1][RTW89_THAILAND][0][42] = -28, + [1][1][RTW89_FCC][1][44] = -28, + [1][1][RTW89_ETSI][1][44] = 34, + [1][1][RTW89_ETSI][0][44] = -4, + [1][1][RTW89_MKK][1][44] = 4, + [1][1][RTW89_MKK][0][44] = -8, + [1][1][RTW89_IC][1][44] = -28, + [1][1][RTW89_KCC][1][44] = -14, + [1][1][RTW89_KCC][0][44] = -14, + [1][1][RTW89_ACMA][1][44] = 34, + [1][1][RTW89_ACMA][0][44] = -4, + [1][1][RTW89_CHILE][1][44] = -28, + [1][1][RTW89_QATAR][1][44] = 34, + [1][1][RTW89_QATAR][0][44] = -4, + [1][1][RTW89_UK][1][44] = 34, + [1][1][RTW89_UK][0][44] = -4, + [1][1][RTW89_THAILAND][1][44] = 18, + [1][1][RTW89_THAILAND][0][44] = -28, + [1][1][RTW89_FCC][1][45] = -26, + [1][1][RTW89_ETSI][1][45] = 127, + [1][1][RTW89_ETSI][0][45] = 127, + [1][1][RTW89_MKK][1][45] = 127, + [1][1][RTW89_MKK][0][45] = 127, + [1][1][RTW89_IC][1][45] = -26, + [1][1][RTW89_KCC][1][45] = -14, + [1][1][RTW89_KCC][0][45] = 127, + [1][1][RTW89_ACMA][1][45] = 127, + [1][1][RTW89_ACMA][0][45] = 127, + [1][1][RTW89_CHILE][1][45] = 127, + [1][1][RTW89_QATAR][1][45] = 127, + [1][1][RTW89_QATAR][0][45] = 127, + [1][1][RTW89_UK][1][45] = 127, + [1][1][RTW89_UK][0][45] = 127, + [1][1][RTW89_THAILAND][1][45] = 127, + [1][1][RTW89_THAILAND][0][45] = 127, + [1][1][RTW89_FCC][1][47] = -28, + [1][1][RTW89_ETSI][1][47] = 127, + [1][1][RTW89_ETSI][0][47] = 127, + [1][1][RTW89_MKK][1][47] = 127, + [1][1][RTW89_MKK][0][47] = 127, + [1][1][RTW89_IC][1][47] = -28, + [1][1][RTW89_KCC][1][47] = -14, + [1][1][RTW89_KCC][0][47] = 127, + [1][1][RTW89_ACMA][1][47] = 127, + [1][1][RTW89_ACMA][0][47] = 127, + [1][1][RTW89_CHILE][1][47] = 127, + [1][1][RTW89_QATAR][1][47] = 127, + [1][1][RTW89_QATAR][0][47] = 127, + [1][1][RTW89_UK][1][47] = 127, + [1][1][RTW89_UK][0][47] = 127, + [1][1][RTW89_THAILAND][1][47] = 127, + [1][1][RTW89_THAILAND][0][47] = 127, + [1][1][RTW89_FCC][1][49] = -28, + [1][1][RTW89_ETSI][1][49] = 127, + [1][1][RTW89_ETSI][0][49] = 127, + [1][1][RTW89_MKK][1][49] = 127, + [1][1][RTW89_MKK][0][49] = 127, + [1][1][RTW89_IC][1][49] = -28, + [1][1][RTW89_KCC][1][49] = -14, + [1][1][RTW89_KCC][0][49] = 127, + [1][1][RTW89_ACMA][1][49] = 127, + [1][1][RTW89_ACMA][0][49] = 127, + [1][1][RTW89_CHILE][1][49] = 127, + [1][1][RTW89_QATAR][1][49] = 127, + [1][1][RTW89_QATAR][0][49] = 127, + [1][1][RTW89_UK][1][49] = 127, + [1][1][RTW89_UK][0][49] = 127, + [1][1][RTW89_THAILAND][1][49] = 127, + [1][1][RTW89_THAILAND][0][49] = 127, + [1][1][RTW89_FCC][1][51] = -28, + [1][1][RTW89_ETSI][1][51] = 127, + [1][1][RTW89_ETSI][0][51] = 127, + [1][1][RTW89_MKK][1][51] = 127, + [1][1][RTW89_MKK][0][51] = 127, + [1][1][RTW89_IC][1][51] = -28, + [1][1][RTW89_KCC][1][51] = -14, + [1][1][RTW89_KCC][0][51] = 127, + [1][1][RTW89_ACMA][1][51] = 127, + [1][1][RTW89_ACMA][0][51] = 127, + [1][1][RTW89_CHILE][1][51] = 127, + [1][1][RTW89_QATAR][1][51] = 127, + [1][1][RTW89_QATAR][0][51] = 127, + [1][1][RTW89_UK][1][51] = 127, + [1][1][RTW89_UK][0][51] = 127, + [1][1][RTW89_THAILAND][1][51] = 127, + [1][1][RTW89_THAILAND][0][51] = 127, + [1][1][RTW89_FCC][1][53] = -26, + [1][1][RTW89_ETSI][1][53] = 127, + [1][1][RTW89_ETSI][0][53] = 127, + [1][1][RTW89_MKK][1][53] = 127, + [1][1][RTW89_MKK][0][53] = 127, + [1][1][RTW89_IC][1][53] = -26, + [1][1][RTW89_KCC][1][53] = -14, + [1][1][RTW89_KCC][0][53] = 127, + [1][1][RTW89_ACMA][1][53] = 127, + [1][1][RTW89_ACMA][0][53] = 127, + [1][1][RTW89_CHILE][1][53] = 127, + [1][1][RTW89_QATAR][1][53] = 127, + [1][1][RTW89_QATAR][0][53] = 127, + [1][1][RTW89_UK][1][53] = 127, + [1][1][RTW89_UK][0][53] = 127, + [1][1][RTW89_THAILAND][1][53] = 127, + [1][1][RTW89_THAILAND][0][53] = 127, + [1][1][RTW89_FCC][1][55] = -28, + [1][1][RTW89_ETSI][1][55] = 127, + [1][1][RTW89_ETSI][0][55] = 127, + [1][1][RTW89_MKK][1][55] = 127, + [1][1][RTW89_MKK][0][55] = 127, + [1][1][RTW89_IC][1][55] = -28, + [1][1][RTW89_KCC][1][55] = -14, + [1][1][RTW89_KCC][0][55] = 127, + [1][1][RTW89_ACMA][1][55] = 127, + [1][1][RTW89_ACMA][0][55] = 127, + [1][1][RTW89_CHILE][1][55] = 127, + [1][1][RTW89_QATAR][1][55] = 127, + [1][1][RTW89_QATAR][0][55] = 127, + [1][1][RTW89_UK][1][55] = 127, + [1][1][RTW89_UK][0][55] = 127, + [1][1][RTW89_THAILAND][1][55] = 127, + [1][1][RTW89_THAILAND][0][55] = 127, + [1][1][RTW89_FCC][1][57] = -28, + [1][1][RTW89_ETSI][1][57] = 127, + [1][1][RTW89_ETSI][0][57] = 127, + [1][1][RTW89_MKK][1][57] = 127, + [1][1][RTW89_MKK][0][57] = 127, + [1][1][RTW89_IC][1][57] = -28, + [1][1][RTW89_KCC][1][57] = -14, + [1][1][RTW89_KCC][0][57] = 127, + [1][1][RTW89_ACMA][1][57] = 127, + [1][1][RTW89_ACMA][0][57] = 127, + [1][1][RTW89_CHILE][1][57] = 127, + [1][1][RTW89_QATAR][1][57] = 127, + [1][1][RTW89_QATAR][0][57] = 127, + [1][1][RTW89_UK][1][57] = 127, + [1][1][RTW89_UK][0][57] = 127, + [1][1][RTW89_THAILAND][1][57] = 127, + [1][1][RTW89_THAILAND][0][57] = 127, + [1][1][RTW89_FCC][1][59] = -28, + [1][1][RTW89_ETSI][1][59] = 127, + [1][1][RTW89_ETSI][0][59] = 127, + [1][1][RTW89_MKK][1][59] = 127, + [1][1][RTW89_MKK][0][59] = 127, + [1][1][RTW89_IC][1][59] = -28, + [1][1][RTW89_KCC][1][59] = -14, + [1][1][RTW89_KCC][0][59] = 127, + [1][1][RTW89_ACMA][1][59] = 127, + [1][1][RTW89_ACMA][0][59] = 127, + [1][1][RTW89_CHILE][1][59] = 127, + [1][1][RTW89_QATAR][1][59] = 127, + [1][1][RTW89_QATAR][0][59] = 127, + [1][1][RTW89_UK][1][59] = 127, + [1][1][RTW89_UK][0][59] = 127, + [1][1][RTW89_THAILAND][1][59] = 127, + [1][1][RTW89_THAILAND][0][59] = 127, + [1][1][RTW89_FCC][1][60] = -28, + [1][1][RTW89_ETSI][1][60] = 127, + [1][1][RTW89_ETSI][0][60] = 127, + [1][1][RTW89_MKK][1][60] = 127, + [1][1][RTW89_MKK][0][60] = 127, + [1][1][RTW89_IC][1][60] = -28, + [1][1][RTW89_KCC][1][60] = -14, + [1][1][RTW89_KCC][0][60] = 127, + [1][1][RTW89_ACMA][1][60] = 127, + [1][1][RTW89_ACMA][0][60] = 127, + [1][1][RTW89_CHILE][1][60] = 127, + [1][1][RTW89_QATAR][1][60] = 127, + [1][1][RTW89_QATAR][0][60] = 127, + [1][1][RTW89_UK][1][60] = 127, + [1][1][RTW89_UK][0][60] = 127, + [1][1][RTW89_THAILAND][1][60] = 127, + [1][1][RTW89_THAILAND][0][60] = 127, + [1][1][RTW89_FCC][1][62] = -28, + [1][1][RTW89_ETSI][1][62] = 127, + [1][1][RTW89_ETSI][0][62] = 127, + [1][1][RTW89_MKK][1][62] = 127, + [1][1][RTW89_MKK][0][62] = 127, + [1][1][RTW89_IC][1][62] = -28, + [1][1][RTW89_KCC][1][62] = -14, + [1][1][RTW89_KCC][0][62] = 127, + [1][1][RTW89_ACMA][1][62] = 127, + [1][1][RTW89_ACMA][0][62] = 127, + [1][1][RTW89_CHILE][1][62] = 127, + [1][1][RTW89_QATAR][1][62] = 127, + [1][1][RTW89_QATAR][0][62] = 127, + [1][1][RTW89_UK][1][62] = 127, + [1][1][RTW89_UK][0][62] = 127, + [1][1][RTW89_THAILAND][1][62] = 127, + [1][1][RTW89_THAILAND][0][62] = 127, + [1][1][RTW89_FCC][1][64] = -28, + [1][1][RTW89_ETSI][1][64] = 127, + [1][1][RTW89_ETSI][0][64] = 127, + [1][1][RTW89_MKK][1][64] = 127, + [1][1][RTW89_MKK][0][64] = 127, + [1][1][RTW89_IC][1][64] = -28, + [1][1][RTW89_KCC][1][64] = -14, + [1][1][RTW89_KCC][0][64] = 127, + [1][1][RTW89_ACMA][1][64] = 127, + [1][1][RTW89_ACMA][0][64] = 127, + [1][1][RTW89_CHILE][1][64] = 127, + [1][1][RTW89_QATAR][1][64] = 127, + [1][1][RTW89_QATAR][0][64] = 127, + [1][1][RTW89_UK][1][64] = 127, + [1][1][RTW89_UK][0][64] = 127, + [1][1][RTW89_THAILAND][1][64] = 127, + [1][1][RTW89_THAILAND][0][64] = 127, + [1][1][RTW89_FCC][1][66] = -28, + [1][1][RTW89_ETSI][1][66] = 127, + [1][1][RTW89_ETSI][0][66] = 127, + [1][1][RTW89_MKK][1][66] = 127, + [1][1][RTW89_MKK][0][66] = 127, + [1][1][RTW89_IC][1][66] = -28, + [1][1][RTW89_KCC][1][66] = -14, + [1][1][RTW89_KCC][0][66] = 127, + [1][1][RTW89_ACMA][1][66] = 127, + [1][1][RTW89_ACMA][0][66] = 127, + [1][1][RTW89_CHILE][1][66] = 127, + [1][1][RTW89_QATAR][1][66] = 127, + [1][1][RTW89_QATAR][0][66] = 127, + [1][1][RTW89_UK][1][66] = 127, + [1][1][RTW89_UK][0][66] = 127, + [1][1][RTW89_THAILAND][1][66] = 127, + [1][1][RTW89_THAILAND][0][66] = 127, + [1][1][RTW89_FCC][1][68] = -28, + [1][1][RTW89_ETSI][1][68] = 127, + [1][1][RTW89_ETSI][0][68] = 127, + [1][1][RTW89_MKK][1][68] = 127, + [1][1][RTW89_MKK][0][68] = 127, + [1][1][RTW89_IC][1][68] = -28, + [1][1][RTW89_KCC][1][68] = -14, + [1][1][RTW89_KCC][0][68] = 127, + [1][1][RTW89_ACMA][1][68] = 127, + [1][1][RTW89_ACMA][0][68] = 127, + [1][1][RTW89_CHILE][1][68] = 127, + [1][1][RTW89_QATAR][1][68] = 127, + [1][1][RTW89_QATAR][0][68] = 127, + [1][1][RTW89_UK][1][68] = 127, + [1][1][RTW89_UK][0][68] = 127, + [1][1][RTW89_THAILAND][1][68] = 127, + [1][1][RTW89_THAILAND][0][68] = 127, + [1][1][RTW89_FCC][1][70] = -26, + [1][1][RTW89_ETSI][1][70] = 127, + [1][1][RTW89_ETSI][0][70] = 127, + [1][1][RTW89_MKK][1][70] = 127, + [1][1][RTW89_MKK][0][70] = 127, + [1][1][RTW89_IC][1][70] = -26, + [1][1][RTW89_KCC][1][70] = -14, + [1][1][RTW89_KCC][0][70] = 127, + [1][1][RTW89_ACMA][1][70] = 127, + [1][1][RTW89_ACMA][0][70] = 127, + [1][1][RTW89_CHILE][1][70] = 127, + [1][1][RTW89_QATAR][1][70] = 127, + [1][1][RTW89_QATAR][0][70] = 127, + [1][1][RTW89_UK][1][70] = 127, + [1][1][RTW89_UK][0][70] = 127, + [1][1][RTW89_THAILAND][1][70] = 127, + [1][1][RTW89_THAILAND][0][70] = 127, + [1][1][RTW89_FCC][1][72] = -28, + [1][1][RTW89_ETSI][1][72] = 127, + [1][1][RTW89_ETSI][0][72] = 127, + [1][1][RTW89_MKK][1][72] = 127, + [1][1][RTW89_MKK][0][72] = 127, + [1][1][RTW89_IC][1][72] = -28, + [1][1][RTW89_KCC][1][72] = -14, + [1][1][RTW89_KCC][0][72] = 127, + [1][1][RTW89_ACMA][1][72] = 127, + [1][1][RTW89_ACMA][0][72] = 127, + [1][1][RTW89_CHILE][1][72] = 127, + [1][1][RTW89_QATAR][1][72] = 127, + [1][1][RTW89_QATAR][0][72] = 127, + [1][1][RTW89_UK][1][72] = 127, + [1][1][RTW89_UK][0][72] = 127, + [1][1][RTW89_THAILAND][1][72] = 127, + [1][1][RTW89_THAILAND][0][72] = 127, + [1][1][RTW89_FCC][1][74] = -28, + [1][1][RTW89_ETSI][1][74] = 127, + [1][1][RTW89_ETSI][0][74] = 127, + [1][1][RTW89_MKK][1][74] = 127, + [1][1][RTW89_MKK][0][74] = 127, + [1][1][RTW89_IC][1][74] = -28, + [1][1][RTW89_KCC][1][74] = -14, + [1][1][RTW89_KCC][0][74] = 127, + [1][1][RTW89_ACMA][1][74] = 127, + [1][1][RTW89_ACMA][0][74] = 127, + [1][1][RTW89_CHILE][1][74] = 127, + [1][1][RTW89_QATAR][1][74] = 127, + [1][1][RTW89_QATAR][0][74] = 127, + [1][1][RTW89_UK][1][74] = 127, + [1][1][RTW89_UK][0][74] = 127, + [1][1][RTW89_THAILAND][1][74] = 127, + [1][1][RTW89_THAILAND][0][74] = 127, + [1][1][RTW89_FCC][1][75] = -28, + [1][1][RTW89_ETSI][1][75] = 127, + [1][1][RTW89_ETSI][0][75] = 127, + [1][1][RTW89_MKK][1][75] = 127, + [1][1][RTW89_MKK][0][75] = 127, + [1][1][RTW89_IC][1][75] = -28, + [1][1][RTW89_KCC][1][75] = -14, + [1][1][RTW89_KCC][0][75] = 127, + [1][1][RTW89_ACMA][1][75] = 127, + [1][1][RTW89_ACMA][0][75] = 127, + [1][1][RTW89_CHILE][1][75] = 127, + [1][1][RTW89_QATAR][1][75] = 127, + [1][1][RTW89_QATAR][0][75] = 127, + [1][1][RTW89_UK][1][75] = 127, + [1][1][RTW89_UK][0][75] = 127, + [1][1][RTW89_THAILAND][1][75] = 127, + [1][1][RTW89_THAILAND][0][75] = 127, + [1][1][RTW89_FCC][1][77] = -28, + [1][1][RTW89_ETSI][1][77] = 127, + [1][1][RTW89_ETSI][0][77] = 127, + [1][1][RTW89_MKK][1][77] = 127, + [1][1][RTW89_MKK][0][77] = 127, + [1][1][RTW89_IC][1][77] = -28, + [1][1][RTW89_KCC][1][77] = -14, + [1][1][RTW89_KCC][0][77] = 127, + [1][1][RTW89_ACMA][1][77] = 127, + [1][1][RTW89_ACMA][0][77] = 127, + [1][1][RTW89_CHILE][1][77] = 127, + [1][1][RTW89_QATAR][1][77] = 127, + [1][1][RTW89_QATAR][0][77] = 127, + [1][1][RTW89_UK][1][77] = 127, + [1][1][RTW89_UK][0][77] = 127, + [1][1][RTW89_THAILAND][1][77] = 127, + [1][1][RTW89_THAILAND][0][77] = 127, + [1][1][RTW89_FCC][1][79] = -28, + [1][1][RTW89_ETSI][1][79] = 127, + [1][1][RTW89_ETSI][0][79] = 127, + [1][1][RTW89_MKK][1][79] = 127, + [1][1][RTW89_MKK][0][79] = 127, + [1][1][RTW89_IC][1][79] = -28, + [1][1][RTW89_KCC][1][79] = -14, + [1][1][RTW89_KCC][0][79] = 127, + [1][1][RTW89_ACMA][1][79] = 127, + [1][1][RTW89_ACMA][0][79] = 127, + [1][1][RTW89_CHILE][1][79] = 127, + [1][1][RTW89_QATAR][1][79] = 127, + [1][1][RTW89_QATAR][0][79] = 127, + [1][1][RTW89_UK][1][79] = 127, + [1][1][RTW89_UK][0][79] = 127, + [1][1][RTW89_THAILAND][1][79] = 127, + [1][1][RTW89_THAILAND][0][79] = 127, + [1][1][RTW89_FCC][1][81] = -28, + [1][1][RTW89_ETSI][1][81] = 127, + [1][1][RTW89_ETSI][0][81] = 127, + [1][1][RTW89_MKK][1][81] = 127, + [1][1][RTW89_MKK][0][81] = 127, + [1][1][RTW89_IC][1][81] = -28, + [1][1][RTW89_KCC][1][81] = -14, + [1][1][RTW89_KCC][0][81] = 127, + [1][1][RTW89_ACMA][1][81] = 127, + [1][1][RTW89_ACMA][0][81] = 127, + [1][1][RTW89_CHILE][1][81] = 127, + [1][1][RTW89_QATAR][1][81] = 127, + [1][1][RTW89_QATAR][0][81] = 127, + [1][1][RTW89_UK][1][81] = 127, + [1][1][RTW89_UK][0][81] = 127, + [1][1][RTW89_THAILAND][1][81] = 127, + [1][1][RTW89_THAILAND][0][81] = 127, + [1][1][RTW89_FCC][1][83] = -28, + [1][1][RTW89_ETSI][1][83] = 127, + [1][1][RTW89_ETSI][0][83] = 127, + [1][1][RTW89_MKK][1][83] = 127, + [1][1][RTW89_MKK][0][83] = 127, + [1][1][RTW89_IC][1][83] = -28, + [1][1][RTW89_KCC][1][83] = -14, + [1][1][RTW89_KCC][0][83] = 127, + [1][1][RTW89_ACMA][1][83] = 127, + [1][1][RTW89_ACMA][0][83] = 127, + [1][1][RTW89_CHILE][1][83] = 127, + [1][1][RTW89_QATAR][1][83] = 127, + [1][1][RTW89_QATAR][0][83] = 127, + [1][1][RTW89_UK][1][83] = 127, + [1][1][RTW89_UK][0][83] = 127, + [1][1][RTW89_THAILAND][1][83] = 127, + [1][1][RTW89_THAILAND][0][83] = 127, + [1][1][RTW89_FCC][1][85] = -28, + [1][1][RTW89_ETSI][1][85] = 127, + [1][1][RTW89_ETSI][0][85] = 127, + [1][1][RTW89_MKK][1][85] = 127, + [1][1][RTW89_MKK][0][85] = 127, + [1][1][RTW89_IC][1][85] = -28, + [1][1][RTW89_KCC][1][85] = -14, + [1][1][RTW89_KCC][0][85] = 127, + [1][1][RTW89_ACMA][1][85] = 127, + [1][1][RTW89_ACMA][0][85] = 127, + [1][1][RTW89_CHILE][1][85] = 127, + [1][1][RTW89_QATAR][1][85] = 127, + [1][1][RTW89_QATAR][0][85] = 127, + [1][1][RTW89_UK][1][85] = 127, + [1][1][RTW89_UK][0][85] = 127, + [1][1][RTW89_THAILAND][1][85] = 127, + [1][1][RTW89_THAILAND][0][85] = 127, + [1][1][RTW89_FCC][1][87] = -28, + [1][1][RTW89_ETSI][1][87] = 127, + [1][1][RTW89_ETSI][0][87] = 127, + [1][1][RTW89_MKK][1][87] = 127, + [1][1][RTW89_MKK][0][87] = 127, + [1][1][RTW89_IC][1][87] = -28, + [1][1][RTW89_KCC][1][87] = -14, + [1][1][RTW89_KCC][0][87] = 127, + [1][1][RTW89_ACMA][1][87] = 127, + [1][1][RTW89_ACMA][0][87] = 127, + [1][1][RTW89_CHILE][1][87] = 127, + [1][1][RTW89_QATAR][1][87] = 127, + [1][1][RTW89_QATAR][0][87] = 127, + [1][1][RTW89_UK][1][87] = 127, + [1][1][RTW89_UK][0][87] = 127, + [1][1][RTW89_THAILAND][1][87] = 127, + [1][1][RTW89_THAILAND][0][87] = 127, + [1][1][RTW89_FCC][1][89] = -26, + [1][1][RTW89_ETSI][1][89] = 127, + [1][1][RTW89_ETSI][0][89] = 127, + [1][1][RTW89_MKK][1][89] = 127, + [1][1][RTW89_MKK][0][89] = 127, + [1][1][RTW89_IC][1][89] = -26, + [1][1][RTW89_KCC][1][89] = -14, + [1][1][RTW89_KCC][0][89] = 127, + [1][1][RTW89_ACMA][1][89] = 127, + [1][1][RTW89_ACMA][0][89] = 127, + [1][1][RTW89_CHILE][1][89] = 127, + [1][1][RTW89_QATAR][1][89] = 127, + [1][1][RTW89_QATAR][0][89] = 127, + [1][1][RTW89_UK][1][89] = 127, + [1][1][RTW89_UK][0][89] = 127, + [1][1][RTW89_THAILAND][1][89] = 127, + [1][1][RTW89_THAILAND][0][89] = 127, + [1][1][RTW89_FCC][1][90] = -26, + [1][1][RTW89_ETSI][1][90] = 127, + [1][1][RTW89_ETSI][0][90] = 127, + [1][1][RTW89_MKK][1][90] = 127, + [1][1][RTW89_MKK][0][90] = 127, + [1][1][RTW89_IC][1][90] = -26, + [1][1][RTW89_KCC][1][90] = -14, + [1][1][RTW89_KCC][0][90] = 127, + [1][1][RTW89_ACMA][1][90] = 127, + [1][1][RTW89_ACMA][0][90] = 127, + [1][1][RTW89_CHILE][1][90] = 127, + [1][1][RTW89_QATAR][1][90] = 127, + [1][1][RTW89_QATAR][0][90] = 127, + [1][1][RTW89_UK][1][90] = 127, + [1][1][RTW89_UK][0][90] = 127, + [1][1][RTW89_THAILAND][1][90] = 127, + [1][1][RTW89_THAILAND][0][90] = 127, + [1][1][RTW89_FCC][1][92] = -26, + [1][1][RTW89_ETSI][1][92] = 127, + [1][1][RTW89_ETSI][0][92] = 127, + [1][1][RTW89_MKK][1][92] = 127, + [1][1][RTW89_MKK][0][92] = 127, + [1][1][RTW89_IC][1][92] = -26, + [1][1][RTW89_KCC][1][92] = -14, + [1][1][RTW89_KCC][0][92] = 127, + [1][1][RTW89_ACMA][1][92] = 127, + [1][1][RTW89_ACMA][0][92] = 127, + [1][1][RTW89_CHILE][1][92] = 127, + [1][1][RTW89_QATAR][1][92] = 127, + [1][1][RTW89_QATAR][0][92] = 127, + [1][1][RTW89_UK][1][92] = 127, + [1][1][RTW89_UK][0][92] = 127, + [1][1][RTW89_THAILAND][1][92] = 127, + [1][1][RTW89_THAILAND][0][92] = 127, + [1][1][RTW89_FCC][1][94] = -26, + [1][1][RTW89_ETSI][1][94] = 127, + [1][1][RTW89_ETSI][0][94] = 127, + [1][1][RTW89_MKK][1][94] = 127, + [1][1][RTW89_MKK][0][94] = 127, + [1][1][RTW89_IC][1][94] = -26, + [1][1][RTW89_KCC][1][94] = -14, + [1][1][RTW89_KCC][0][94] = 127, + [1][1][RTW89_ACMA][1][94] = 127, + [1][1][RTW89_ACMA][0][94] = 127, + [1][1][RTW89_CHILE][1][94] = 127, + [1][1][RTW89_QATAR][1][94] = 127, + [1][1][RTW89_QATAR][0][94] = 127, + [1][1][RTW89_UK][1][94] = 127, + [1][1][RTW89_UK][0][94] = 127, + [1][1][RTW89_THAILAND][1][94] = 127, + [1][1][RTW89_THAILAND][0][94] = 127, + [1][1][RTW89_FCC][1][96] = -26, + [1][1][RTW89_ETSI][1][96] = 127, + [1][1][RTW89_ETSI][0][96] = 127, + [1][1][RTW89_MKK][1][96] = 127, + [1][1][RTW89_MKK][0][96] = 127, + [1][1][RTW89_IC][1][96] = -26, + [1][1][RTW89_KCC][1][96] = -14, + [1][1][RTW89_KCC][0][96] = 127, + [1][1][RTW89_ACMA][1][96] = 127, + [1][1][RTW89_ACMA][0][96] = 127, + [1][1][RTW89_CHILE][1][96] = 127, + [1][1][RTW89_QATAR][1][96] = 127, + [1][1][RTW89_QATAR][0][96] = 127, + [1][1][RTW89_UK][1][96] = 127, + [1][1][RTW89_UK][0][96] = 127, + [1][1][RTW89_THAILAND][1][96] = 127, + [1][1][RTW89_THAILAND][0][96] = 127, + [1][1][RTW89_FCC][1][98] = -26, + [1][1][RTW89_ETSI][1][98] = 127, + [1][1][RTW89_ETSI][0][98] = 127, + [1][1][RTW89_MKK][1][98] = 127, + [1][1][RTW89_MKK][0][98] = 127, + [1][1][RTW89_IC][1][98] = -26, + [1][1][RTW89_KCC][1][98] = -14, + [1][1][RTW89_KCC][0][98] = 127, + [1][1][RTW89_ACMA][1][98] = 127, + [1][1][RTW89_ACMA][0][98] = 127, + [1][1][RTW89_CHILE][1][98] = 127, + [1][1][RTW89_QATAR][1][98] = 127, + [1][1][RTW89_QATAR][0][98] = 127, + [1][1][RTW89_UK][1][98] = 127, + [1][1][RTW89_UK][0][98] = 127, + [1][1][RTW89_THAILAND][1][98] = 127, + [1][1][RTW89_THAILAND][0][98] = 127, + [1][1][RTW89_FCC][1][100] = -26, + [1][1][RTW89_ETSI][1][100] = 127, + [1][1][RTW89_ETSI][0][100] = 127, + [1][1][RTW89_MKK][1][100] = 127, + [1][1][RTW89_MKK][0][100] = 127, + [1][1][RTW89_IC][1][100] = -26, + [1][1][RTW89_KCC][1][100] = -14, + [1][1][RTW89_KCC][0][100] = 127, + [1][1][RTW89_ACMA][1][100] = 127, + [1][1][RTW89_ACMA][0][100] = 127, + [1][1][RTW89_CHILE][1][100] = 127, + [1][1][RTW89_QATAR][1][100] = 127, + [1][1][RTW89_QATAR][0][100] = 127, + [1][1][RTW89_UK][1][100] = 127, + [1][1][RTW89_UK][0][100] = 127, + [1][1][RTW89_THAILAND][1][100] = 127, + [1][1][RTW89_THAILAND][0][100] = 127, + [1][1][RTW89_FCC][1][102] = -26, + [1][1][RTW89_ETSI][1][102] = 127, + [1][1][RTW89_ETSI][0][102] = 127, + [1][1][RTW89_MKK][1][102] = 127, + [1][1][RTW89_MKK][0][102] = 127, + [1][1][RTW89_IC][1][102] = -26, + [1][1][RTW89_KCC][1][102] = -14, + [1][1][RTW89_KCC][0][102] = 127, + [1][1][RTW89_ACMA][1][102] = 127, + [1][1][RTW89_ACMA][0][102] = 127, + [1][1][RTW89_CHILE][1][102] = 127, + [1][1][RTW89_QATAR][1][102] = 127, + [1][1][RTW89_QATAR][0][102] = 127, + [1][1][RTW89_UK][1][102] = 127, + [1][1][RTW89_UK][0][102] = 127, + [1][1][RTW89_THAILAND][1][102] = 127, + [1][1][RTW89_THAILAND][0][102] = 127, + [1][1][RTW89_FCC][1][104] = -26, + [1][1][RTW89_ETSI][1][104] = 127, + [1][1][RTW89_ETSI][0][104] = 127, + [1][1][RTW89_MKK][1][104] = 127, + [1][1][RTW89_MKK][0][104] = 127, + [1][1][RTW89_IC][1][104] = -26, + [1][1][RTW89_KCC][1][104] = -14, + [1][1][RTW89_KCC][0][104] = 127, + [1][1][RTW89_ACMA][1][104] = 127, + [1][1][RTW89_ACMA][0][104] = 127, + [1][1][RTW89_CHILE][1][104] = 127, + [1][1][RTW89_QATAR][1][104] = 127, + [1][1][RTW89_QATAR][0][104] = 127, + [1][1][RTW89_UK][1][104] = 127, + [1][1][RTW89_UK][0][104] = 127, + [1][1][RTW89_THAILAND][1][104] = 127, + [1][1][RTW89_THAILAND][0][104] = 127, + [1][1][RTW89_FCC][1][105] = -26, + [1][1][RTW89_ETSI][1][105] = 127, + [1][1][RTW89_ETSI][0][105] = 127, + [1][1][RTW89_MKK][1][105] = 127, + [1][1][RTW89_MKK][0][105] = 127, + [1][1][RTW89_IC][1][105] = -26, + [1][1][RTW89_KCC][1][105] = -14, + [1][1][RTW89_KCC][0][105] = 127, + [1][1][RTW89_ACMA][1][105] = 127, + [1][1][RTW89_ACMA][0][105] = 127, + [1][1][RTW89_CHILE][1][105] = 127, + [1][1][RTW89_QATAR][1][105] = 127, + [1][1][RTW89_QATAR][0][105] = 127, + [1][1][RTW89_UK][1][105] = 127, + [1][1][RTW89_UK][0][105] = 127, + [1][1][RTW89_THAILAND][1][105] = 127, + [1][1][RTW89_THAILAND][0][105] = 127, + [1][1][RTW89_FCC][1][107] = -22, + [1][1][RTW89_ETSI][1][107] = 127, + [1][1][RTW89_ETSI][0][107] = 127, + [1][1][RTW89_MKK][1][107] = 127, + [1][1][RTW89_MKK][0][107] = 127, + [1][1][RTW89_IC][1][107] = -22, + [1][1][RTW89_KCC][1][107] = -14, + [1][1][RTW89_KCC][0][107] = 127, + [1][1][RTW89_ACMA][1][107] = 127, + [1][1][RTW89_ACMA][0][107] = 127, + [1][1][RTW89_CHILE][1][107] = 127, + [1][1][RTW89_QATAR][1][107] = 127, + [1][1][RTW89_QATAR][0][107] = 127, + [1][1][RTW89_UK][1][107] = 127, + [1][1][RTW89_UK][0][107] = 127, + [1][1][RTW89_THAILAND][1][107] = 127, + [1][1][RTW89_THAILAND][0][107] = 127, + [1][1][RTW89_FCC][1][109] = -22, + [1][1][RTW89_ETSI][1][109] = 127, + [1][1][RTW89_ETSI][0][109] = 127, + [1][1][RTW89_MKK][1][109] = 127, + [1][1][RTW89_MKK][0][109] = 127, + [1][1][RTW89_IC][1][109] = -22, + [1][1][RTW89_KCC][1][109] = 127, + [1][1][RTW89_KCC][0][109] = 127, + [1][1][RTW89_ACMA][1][109] = 127, + [1][1][RTW89_ACMA][0][109] = 127, + [1][1][RTW89_CHILE][1][109] = 127, + [1][1][RTW89_QATAR][1][109] = 127, + [1][1][RTW89_QATAR][0][109] = 127, + [1][1][RTW89_UK][1][109] = 127, + [1][1][RTW89_UK][0][109] = 127, + [1][1][RTW89_THAILAND][1][109] = 127, + [1][1][RTW89_THAILAND][0][109] = 127, + [1][1][RTW89_FCC][1][111] = 127, + [1][1][RTW89_ETSI][1][111] = 127, + [1][1][RTW89_ETSI][0][111] = 127, + [1][1][RTW89_MKK][1][111] = 127, + [1][1][RTW89_MKK][0][111] = 127, + [1][1][RTW89_IC][1][111] = 127, + [1][1][RTW89_KCC][1][111] = 127, + [1][1][RTW89_KCC][0][111] = 127, + [1][1][RTW89_ACMA][1][111] = 127, + [1][1][RTW89_ACMA][0][111] = 127, + [1][1][RTW89_CHILE][1][111] = 127, + [1][1][RTW89_QATAR][1][111] = 127, + [1][1][RTW89_QATAR][0][111] = 127, + [1][1][RTW89_UK][1][111] = 127, + [1][1][RTW89_UK][0][111] = 127, + [1][1][RTW89_THAILAND][1][111] = 127, + [1][1][RTW89_THAILAND][0][111] = 127, + [1][1][RTW89_FCC][1][113] = 127, + [1][1][RTW89_ETSI][1][113] = 127, + [1][1][RTW89_ETSI][0][113] = 127, + [1][1][RTW89_MKK][1][113] = 127, + [1][1][RTW89_MKK][0][113] = 127, + [1][1][RTW89_IC][1][113] = 127, + [1][1][RTW89_KCC][1][113] = 127, + [1][1][RTW89_KCC][0][113] = 127, + [1][1][RTW89_ACMA][1][113] = 127, + [1][1][RTW89_ACMA][0][113] = 127, + [1][1][RTW89_CHILE][1][113] = 127, + [1][1][RTW89_QATAR][1][113] = 127, + [1][1][RTW89_QATAR][0][113] = 127, + [1][1][RTW89_UK][1][113] = 127, + [1][1][RTW89_UK][0][113] = 127, + [1][1][RTW89_THAILAND][1][113] = 127, + [1][1][RTW89_THAILAND][0][113] = 127, + [1][1][RTW89_FCC][1][115] = 127, + [1][1][RTW89_ETSI][1][115] = 127, + [1][1][RTW89_ETSI][0][115] = 127, + [1][1][RTW89_MKK][1][115] = 127, + [1][1][RTW89_MKK][0][115] = 127, + [1][1][RTW89_IC][1][115] = 127, + [1][1][RTW89_KCC][1][115] = 127, + [1][1][RTW89_KCC][0][115] = 127, + [1][1][RTW89_ACMA][1][115] = 127, + [1][1][RTW89_ACMA][0][115] = 127, + [1][1][RTW89_CHILE][1][115] = 127, + [1][1][RTW89_QATAR][1][115] = 127, + [1][1][RTW89_QATAR][0][115] = 127, + [1][1][RTW89_UK][1][115] = 127, + [1][1][RTW89_UK][0][115] = 127, + [1][1][RTW89_THAILAND][1][115] = 127, + [1][1][RTW89_THAILAND][0][115] = 127, + [1][1][RTW89_FCC][1][117] = 127, + [1][1][RTW89_ETSI][1][117] = 127, + [1][1][RTW89_ETSI][0][117] = 127, + [1][1][RTW89_MKK][1][117] = 127, + [1][1][RTW89_MKK][0][117] = 127, + [1][1][RTW89_IC][1][117] = 127, + [1][1][RTW89_KCC][1][117] = 127, + [1][1][RTW89_KCC][0][117] = 127, + [1][1][RTW89_ACMA][1][117] = 127, + [1][1][RTW89_ACMA][0][117] = 127, + [1][1][RTW89_CHILE][1][117] = 127, + [1][1][RTW89_QATAR][1][117] = 127, + [1][1][RTW89_QATAR][0][117] = 127, + [1][1][RTW89_UK][1][117] = 127, + [1][1][RTW89_UK][0][117] = 127, + [1][1][RTW89_THAILAND][1][117] = 127, + [1][1][RTW89_THAILAND][0][117] = 127, + [1][1][RTW89_FCC][1][119] = 127, + [1][1][RTW89_ETSI][1][119] = 127, + [1][1][RTW89_ETSI][0][119] = 127, + [1][1][RTW89_MKK][1][119] = 127, + [1][1][RTW89_MKK][0][119] = 127, + [1][1][RTW89_IC][1][119] = 127, + [1][1][RTW89_KCC][1][119] = 127, + [1][1][RTW89_KCC][0][119] = 127, + [1][1][RTW89_ACMA][1][119] = 127, + [1][1][RTW89_ACMA][0][119] = 127, + [1][1][RTW89_CHILE][1][119] = 127, + [1][1][RTW89_QATAR][1][119] = 127, + [1][1][RTW89_QATAR][0][119] = 127, + [1][1][RTW89_UK][1][119] = 127, + [1][1][RTW89_UK][0][119] = 127, + [1][1][RTW89_THAILAND][1][119] = 127, + [1][1][RTW89_THAILAND][0][119] = 127, + [2][0][RTW89_FCC][1][0] = 8, + [2][0][RTW89_ETSI][1][0] = 56, + [2][0][RTW89_ETSI][0][0] = 18, + [2][0][RTW89_MKK][1][0] = 54, + [2][0][RTW89_MKK][0][0] = 14, + [2][0][RTW89_IC][1][0] = 8, + [2][0][RTW89_KCC][1][0] = -2, + [2][0][RTW89_KCC][0][0] = -2, + [2][0][RTW89_ACMA][1][0] = 56, + [2][0][RTW89_ACMA][0][0] = 18, + [2][0][RTW89_CHILE][1][0] = 8, + [2][0][RTW89_QATAR][1][0] = 56, + [2][0][RTW89_QATAR][0][0] = 18, + [2][0][RTW89_UK][1][0] = 56, + [2][0][RTW89_UK][0][0] = 18, + [2][0][RTW89_THAILAND][1][0] = 52, + [2][0][RTW89_THAILAND][0][0] = 8, + [2][0][RTW89_FCC][1][2] = 8, + [2][0][RTW89_ETSI][1][2] = 56, + [2][0][RTW89_ETSI][0][2] = 18, + [2][0][RTW89_MKK][1][2] = 54, + [2][0][RTW89_MKK][0][2] = 14, + [2][0][RTW89_IC][1][2] = 8, + [2][0][RTW89_KCC][1][2] = -2, + [2][0][RTW89_KCC][0][2] = -2, + [2][0][RTW89_ACMA][1][2] = 56, + [2][0][RTW89_ACMA][0][2] = 18, + [2][0][RTW89_CHILE][1][2] = 8, + [2][0][RTW89_QATAR][1][2] = 56, + [2][0][RTW89_QATAR][0][2] = 18, + [2][0][RTW89_UK][1][2] = 56, + [2][0][RTW89_UK][0][2] = 18, + [2][0][RTW89_THAILAND][1][2] = 52, + [2][0][RTW89_THAILAND][0][2] = 8, + [2][0][RTW89_FCC][1][4] = 8, + [2][0][RTW89_ETSI][1][4] = 56, + [2][0][RTW89_ETSI][0][4] = 18, + [2][0][RTW89_MKK][1][4] = 54, + [2][0][RTW89_MKK][0][4] = 14, + [2][0][RTW89_IC][1][4] = 8, + [2][0][RTW89_KCC][1][4] = -2, + [2][0][RTW89_KCC][0][4] = -2, + [2][0][RTW89_ACMA][1][4] = 56, + [2][0][RTW89_ACMA][0][4] = 18, + [2][0][RTW89_CHILE][1][4] = 8, + [2][0][RTW89_QATAR][1][4] = 56, + [2][0][RTW89_QATAR][0][4] = 18, + [2][0][RTW89_UK][1][4] = 56, + [2][0][RTW89_UK][0][4] = 18, + [2][0][RTW89_THAILAND][1][4] = 52, + [2][0][RTW89_THAILAND][0][4] = 8, + [2][0][RTW89_FCC][1][6] = 8, + [2][0][RTW89_ETSI][1][6] = 56, + [2][0][RTW89_ETSI][0][6] = 18, + [2][0][RTW89_MKK][1][6] = 54, + [2][0][RTW89_MKK][0][6] = 14, + [2][0][RTW89_IC][1][6] = 8, + [2][0][RTW89_KCC][1][6] = -2, + [2][0][RTW89_KCC][0][6] = -2, + [2][0][RTW89_ACMA][1][6] = 56, + [2][0][RTW89_ACMA][0][6] = 18, + [2][0][RTW89_CHILE][1][6] = 8, + [2][0][RTW89_QATAR][1][6] = 56, + [2][0][RTW89_QATAR][0][6] = 18, + [2][0][RTW89_UK][1][6] = 56, + [2][0][RTW89_UK][0][6] = 18, + [2][0][RTW89_THAILAND][1][6] = 52, + [2][0][RTW89_THAILAND][0][6] = 8, + [2][0][RTW89_FCC][1][8] = 8, + [2][0][RTW89_ETSI][1][8] = 56, + [2][0][RTW89_ETSI][0][8] = 18, + [2][0][RTW89_MKK][1][8] = 54, + [2][0][RTW89_MKK][0][8] = 14, + [2][0][RTW89_IC][1][8] = 8, + [2][0][RTW89_KCC][1][8] = -2, + [2][0][RTW89_KCC][0][8] = -2, + [2][0][RTW89_ACMA][1][8] = 56, + [2][0][RTW89_ACMA][0][8] = 18, + [2][0][RTW89_CHILE][1][8] = 8, + [2][0][RTW89_QATAR][1][8] = 56, + [2][0][RTW89_QATAR][0][8] = 18, + [2][0][RTW89_UK][1][8] = 56, + [2][0][RTW89_UK][0][8] = 18, + [2][0][RTW89_THAILAND][1][8] = 52, + [2][0][RTW89_THAILAND][0][8] = 8, + [2][0][RTW89_FCC][1][10] = 8, + [2][0][RTW89_ETSI][1][10] = 56, + [2][0][RTW89_ETSI][0][10] = 18, + [2][0][RTW89_MKK][1][10] = 54, + [2][0][RTW89_MKK][0][10] = 14, + [2][0][RTW89_IC][1][10] = 8, + [2][0][RTW89_KCC][1][10] = -2, + [2][0][RTW89_KCC][0][10] = -2, + [2][0][RTW89_ACMA][1][10] = 56, + [2][0][RTW89_ACMA][0][10] = 18, + [2][0][RTW89_CHILE][1][10] = 8, + [2][0][RTW89_QATAR][1][10] = 56, + [2][0][RTW89_QATAR][0][10] = 18, + [2][0][RTW89_UK][1][10] = 56, + [2][0][RTW89_UK][0][10] = 18, + [2][0][RTW89_THAILAND][1][10] = 52, + [2][0][RTW89_THAILAND][0][10] = 8, + [2][0][RTW89_FCC][1][12] = 8, + [2][0][RTW89_ETSI][1][12] = 56, + [2][0][RTW89_ETSI][0][12] = 18, + [2][0][RTW89_MKK][1][12] = 54, + [2][0][RTW89_MKK][0][12] = 14, + [2][0][RTW89_IC][1][12] = 8, + [2][0][RTW89_KCC][1][12] = -2, + [2][0][RTW89_KCC][0][12] = -2, + [2][0][RTW89_ACMA][1][12] = 56, + [2][0][RTW89_ACMA][0][12] = 18, + [2][0][RTW89_CHILE][1][12] = 8, + [2][0][RTW89_QATAR][1][12] = 56, + [2][0][RTW89_QATAR][0][12] = 18, + [2][0][RTW89_UK][1][12] = 56, + [2][0][RTW89_UK][0][12] = 18, + [2][0][RTW89_THAILAND][1][12] = 52, + [2][0][RTW89_THAILAND][0][12] = 8, + [2][0][RTW89_FCC][1][14] = 8, + [2][0][RTW89_ETSI][1][14] = 56, + [2][0][RTW89_ETSI][0][14] = 18, + [2][0][RTW89_MKK][1][14] = 54, + [2][0][RTW89_MKK][0][14] = 14, + [2][0][RTW89_IC][1][14] = 8, + [2][0][RTW89_KCC][1][14] = -2, + [2][0][RTW89_KCC][0][14] = -2, + [2][0][RTW89_ACMA][1][14] = 56, + [2][0][RTW89_ACMA][0][14] = 18, + [2][0][RTW89_CHILE][1][14] = 8, + [2][0][RTW89_QATAR][1][14] = 56, + [2][0][RTW89_QATAR][0][14] = 18, + [2][0][RTW89_UK][1][14] = 56, + [2][0][RTW89_UK][0][14] = 18, + [2][0][RTW89_THAILAND][1][14] = 52, + [2][0][RTW89_THAILAND][0][14] = 8, + [2][0][RTW89_FCC][1][15] = 8, + [2][0][RTW89_ETSI][1][15] = 56, + [2][0][RTW89_ETSI][0][15] = 18, + [2][0][RTW89_MKK][1][15] = 54, + [2][0][RTW89_MKK][0][15] = 14, + [2][0][RTW89_IC][1][15] = 8, + [2][0][RTW89_KCC][1][15] = -2, + [2][0][RTW89_KCC][0][15] = -2, + [2][0][RTW89_ACMA][1][15] = 56, + [2][0][RTW89_ACMA][0][15] = 18, + [2][0][RTW89_CHILE][1][15] = 8, + [2][0][RTW89_QATAR][1][15] = 56, + [2][0][RTW89_QATAR][0][15] = 18, + [2][0][RTW89_UK][1][15] = 56, + [2][0][RTW89_UK][0][15] = 18, + [2][0][RTW89_THAILAND][1][15] = 52, + [2][0][RTW89_THAILAND][0][15] = 8, + [2][0][RTW89_FCC][1][17] = 8, + [2][0][RTW89_ETSI][1][17] = 56, + [2][0][RTW89_ETSI][0][17] = 18, + [2][0][RTW89_MKK][1][17] = 54, + [2][0][RTW89_MKK][0][17] = 14, + [2][0][RTW89_IC][1][17] = 8, + [2][0][RTW89_KCC][1][17] = -2, + [2][0][RTW89_KCC][0][17] = -2, + [2][0][RTW89_ACMA][1][17] = 56, + [2][0][RTW89_ACMA][0][17] = 18, + [2][0][RTW89_CHILE][1][17] = 8, + [2][0][RTW89_QATAR][1][17] = 56, + [2][0][RTW89_QATAR][0][17] = 18, + [2][0][RTW89_UK][1][17] = 56, + [2][0][RTW89_UK][0][17] = 18, + [2][0][RTW89_THAILAND][1][17] = 52, + [2][0][RTW89_THAILAND][0][17] = 8, + [2][0][RTW89_FCC][1][19] = 8, + [2][0][RTW89_ETSI][1][19] = 56, + [2][0][RTW89_ETSI][0][19] = 18, + [2][0][RTW89_MKK][1][19] = 54, + [2][0][RTW89_MKK][0][19] = 14, + [2][0][RTW89_IC][1][19] = 8, + [2][0][RTW89_KCC][1][19] = -2, + [2][0][RTW89_KCC][0][19] = -2, + [2][0][RTW89_ACMA][1][19] = 56, + [2][0][RTW89_ACMA][0][19] = 18, + [2][0][RTW89_CHILE][1][19] = 8, + [2][0][RTW89_QATAR][1][19] = 56, + [2][0][RTW89_QATAR][0][19] = 18, + [2][0][RTW89_UK][1][19] = 56, + [2][0][RTW89_UK][0][19] = 18, + [2][0][RTW89_THAILAND][1][19] = 52, + [2][0][RTW89_THAILAND][0][19] = 8, + [2][0][RTW89_FCC][1][21] = 8, + [2][0][RTW89_ETSI][1][21] = 56, + [2][0][RTW89_ETSI][0][21] = 18, + [2][0][RTW89_MKK][1][21] = 54, + [2][0][RTW89_MKK][0][21] = 14, + [2][0][RTW89_IC][1][21] = 8, + [2][0][RTW89_KCC][1][21] = -2, + [2][0][RTW89_KCC][0][21] = -2, + [2][0][RTW89_ACMA][1][21] = 56, + [2][0][RTW89_ACMA][0][21] = 18, + [2][0][RTW89_CHILE][1][21] = 8, + [2][0][RTW89_QATAR][1][21] = 56, + [2][0][RTW89_QATAR][0][21] = 18, + [2][0][RTW89_UK][1][21] = 56, + [2][0][RTW89_UK][0][21] = 18, + [2][0][RTW89_THAILAND][1][21] = 52, + [2][0][RTW89_THAILAND][0][21] = 8, + [2][0][RTW89_FCC][1][23] = 8, + [2][0][RTW89_ETSI][1][23] = 56, + [2][0][RTW89_ETSI][0][23] = 18, + [2][0][RTW89_MKK][1][23] = 56, + [2][0][RTW89_MKK][0][23] = 14, + [2][0][RTW89_IC][1][23] = 8, + [2][0][RTW89_KCC][1][23] = -2, + [2][0][RTW89_KCC][0][23] = -2, + [2][0][RTW89_ACMA][1][23] = 56, + [2][0][RTW89_ACMA][0][23] = 18, + [2][0][RTW89_CHILE][1][23] = 8, + [2][0][RTW89_QATAR][1][23] = 56, + [2][0][RTW89_QATAR][0][23] = 18, + [2][0][RTW89_UK][1][23] = 56, + [2][0][RTW89_UK][0][23] = 18, + [2][0][RTW89_THAILAND][1][23] = 52, + [2][0][RTW89_THAILAND][0][23] = 8, + [2][0][RTW89_FCC][1][25] = 8, + [2][0][RTW89_ETSI][1][25] = 56, + [2][0][RTW89_ETSI][0][25] = 18, + [2][0][RTW89_MKK][1][25] = 56, + [2][0][RTW89_MKK][0][25] = 14, + [2][0][RTW89_IC][1][25] = 8, + [2][0][RTW89_KCC][1][25] = -2, + [2][0][RTW89_KCC][0][25] = -2, + [2][0][RTW89_ACMA][1][25] = 56, + [2][0][RTW89_ACMA][0][25] = 18, + [2][0][RTW89_CHILE][1][25] = 8, + [2][0][RTW89_QATAR][1][25] = 56, + [2][0][RTW89_QATAR][0][25] = 18, + [2][0][RTW89_UK][1][25] = 56, + [2][0][RTW89_UK][0][25] = 18, + [2][0][RTW89_THAILAND][1][25] = 52, + [2][0][RTW89_THAILAND][0][25] = 8, + [2][0][RTW89_FCC][1][27] = 8, + [2][0][RTW89_ETSI][1][27] = 56, + [2][0][RTW89_ETSI][0][27] = 18, + [2][0][RTW89_MKK][1][27] = 56, + [2][0][RTW89_MKK][0][27] = 14, + [2][0][RTW89_IC][1][27] = 8, + [2][0][RTW89_KCC][1][27] = -2, + [2][0][RTW89_KCC][0][27] = -2, + [2][0][RTW89_ACMA][1][27] = 56, + [2][0][RTW89_ACMA][0][27] = 18, + [2][0][RTW89_CHILE][1][27] = 8, + [2][0][RTW89_QATAR][1][27] = 56, + [2][0][RTW89_QATAR][0][27] = 18, + [2][0][RTW89_UK][1][27] = 56, + [2][0][RTW89_UK][0][27] = 18, + [2][0][RTW89_THAILAND][1][27] = 52, + [2][0][RTW89_THAILAND][0][27] = 8, + [2][0][RTW89_FCC][1][29] = 8, + [2][0][RTW89_ETSI][1][29] = 56, + [2][0][RTW89_ETSI][0][29] = 18, + [2][0][RTW89_MKK][1][29] = 56, + [2][0][RTW89_MKK][0][29] = 14, + [2][0][RTW89_IC][1][29] = 8, + [2][0][RTW89_KCC][1][29] = -2, + [2][0][RTW89_KCC][0][29] = -2, + [2][0][RTW89_ACMA][1][29] = 56, + [2][0][RTW89_ACMA][0][29] = 18, + [2][0][RTW89_CHILE][1][29] = 8, + [2][0][RTW89_QATAR][1][29] = 56, + [2][0][RTW89_QATAR][0][29] = 18, + [2][0][RTW89_UK][1][29] = 56, + [2][0][RTW89_UK][0][29] = 18, + [2][0][RTW89_THAILAND][1][29] = 52, + [2][0][RTW89_THAILAND][0][29] = 8, + [2][0][RTW89_FCC][1][30] = 8, + [2][0][RTW89_ETSI][1][30] = 56, + [2][0][RTW89_ETSI][0][30] = 18, + [2][0][RTW89_MKK][1][30] = 56, + [2][0][RTW89_MKK][0][30] = 14, + [2][0][RTW89_IC][1][30] = 8, + [2][0][RTW89_KCC][1][30] = -2, + [2][0][RTW89_KCC][0][30] = -2, + [2][0][RTW89_ACMA][1][30] = 56, + [2][0][RTW89_ACMA][0][30] = 18, + [2][0][RTW89_CHILE][1][30] = 8, + [2][0][RTW89_QATAR][1][30] = 56, + [2][0][RTW89_QATAR][0][30] = 18, + [2][0][RTW89_UK][1][30] = 56, + [2][0][RTW89_UK][0][30] = 18, + [2][0][RTW89_THAILAND][1][30] = 52, + [2][0][RTW89_THAILAND][0][30] = 8, + [2][0][RTW89_FCC][1][32] = 8, + [2][0][RTW89_ETSI][1][32] = 56, + [2][0][RTW89_ETSI][0][32] = 18, + [2][0][RTW89_MKK][1][32] = 56, + [2][0][RTW89_MKK][0][32] = 14, + [2][0][RTW89_IC][1][32] = 8, + [2][0][RTW89_KCC][1][32] = -2, + [2][0][RTW89_KCC][0][32] = -2, + [2][0][RTW89_ACMA][1][32] = 56, + [2][0][RTW89_ACMA][0][32] = 18, + [2][0][RTW89_CHILE][1][32] = 8, + [2][0][RTW89_QATAR][1][32] = 56, + [2][0][RTW89_QATAR][0][32] = 18, + [2][0][RTW89_UK][1][32] = 56, + [2][0][RTW89_UK][0][32] = 18, + [2][0][RTW89_THAILAND][1][32] = 52, + [2][0][RTW89_THAILAND][0][32] = 8, + [2][0][RTW89_FCC][1][34] = 8, + [2][0][RTW89_ETSI][1][34] = 56, + [2][0][RTW89_ETSI][0][34] = 18, + [2][0][RTW89_MKK][1][34] = 56, + [2][0][RTW89_MKK][0][34] = 14, + [2][0][RTW89_IC][1][34] = 8, + [2][0][RTW89_KCC][1][34] = -2, + [2][0][RTW89_KCC][0][34] = -2, + [2][0][RTW89_ACMA][1][34] = 56, + [2][0][RTW89_ACMA][0][34] = 18, + [2][0][RTW89_CHILE][1][34] = 8, + [2][0][RTW89_QATAR][1][34] = 56, + [2][0][RTW89_QATAR][0][34] = 18, + [2][0][RTW89_UK][1][34] = 56, + [2][0][RTW89_UK][0][34] = 18, + [2][0][RTW89_THAILAND][1][34] = 52, + [2][0][RTW89_THAILAND][0][34] = 8, + [2][0][RTW89_FCC][1][36] = 8, + [2][0][RTW89_ETSI][1][36] = 56, + [2][0][RTW89_ETSI][0][36] = 18, + [2][0][RTW89_MKK][1][36] = 56, + [2][0][RTW89_MKK][0][36] = 14, + [2][0][RTW89_IC][1][36] = 8, + [2][0][RTW89_KCC][1][36] = -2, + [2][0][RTW89_KCC][0][36] = -2, + [2][0][RTW89_ACMA][1][36] = 56, + [2][0][RTW89_ACMA][0][36] = 18, + [2][0][RTW89_CHILE][1][36] = 8, + [2][0][RTW89_QATAR][1][36] = 56, + [2][0][RTW89_QATAR][0][36] = 18, + [2][0][RTW89_UK][1][36] = 56, + [2][0][RTW89_UK][0][36] = 18, + [2][0][RTW89_THAILAND][1][36] = 52, + [2][0][RTW89_THAILAND][0][36] = 8, + [2][0][RTW89_FCC][1][38] = 8, + [2][0][RTW89_ETSI][1][38] = 56, + [2][0][RTW89_ETSI][0][38] = 18, + [2][0][RTW89_MKK][1][38] = 56, + [2][0][RTW89_MKK][0][38] = 14, + [2][0][RTW89_IC][1][38] = 8, + [2][0][RTW89_KCC][1][38] = -2, + [2][0][RTW89_KCC][0][38] = -2, + [2][0][RTW89_ACMA][1][38] = 56, + [2][0][RTW89_ACMA][0][38] = 18, + [2][0][RTW89_CHILE][1][38] = 8, + [2][0][RTW89_QATAR][1][38] = 56, + [2][0][RTW89_QATAR][0][38] = 18, + [2][0][RTW89_UK][1][38] = 56, + [2][0][RTW89_UK][0][38] = 18, + [2][0][RTW89_THAILAND][1][38] = 52, + [2][0][RTW89_THAILAND][0][38] = 8, + [2][0][RTW89_FCC][1][40] = 8, + [2][0][RTW89_ETSI][1][40] = 56, + [2][0][RTW89_ETSI][0][40] = 18, + [2][0][RTW89_MKK][1][40] = 56, + [2][0][RTW89_MKK][0][40] = 14, + [2][0][RTW89_IC][1][40] = 8, + [2][0][RTW89_KCC][1][40] = -2, + [2][0][RTW89_KCC][0][40] = -2, + [2][0][RTW89_ACMA][1][40] = 56, + [2][0][RTW89_ACMA][0][40] = 18, + [2][0][RTW89_CHILE][1][40] = 8, + [2][0][RTW89_QATAR][1][40] = 56, + [2][0][RTW89_QATAR][0][40] = 18, + [2][0][RTW89_UK][1][40] = 56, + [2][0][RTW89_UK][0][40] = 18, + [2][0][RTW89_THAILAND][1][40] = 52, + [2][0][RTW89_THAILAND][0][40] = 8, + [2][0][RTW89_FCC][1][42] = 8, + [2][0][RTW89_ETSI][1][42] = 56, + [2][0][RTW89_ETSI][0][42] = 18, + [2][0][RTW89_MKK][1][42] = 56, + [2][0][RTW89_MKK][0][42] = 14, + [2][0][RTW89_IC][1][42] = 8, + [2][0][RTW89_KCC][1][42] = -2, + [2][0][RTW89_KCC][0][42] = -2, + [2][0][RTW89_ACMA][1][42] = 56, + [2][0][RTW89_ACMA][0][42] = 18, + [2][0][RTW89_CHILE][1][42] = 8, + [2][0][RTW89_QATAR][1][42] = 56, + [2][0][RTW89_QATAR][0][42] = 18, + [2][0][RTW89_UK][1][42] = 56, + [2][0][RTW89_UK][0][42] = 18, + [2][0][RTW89_THAILAND][1][42] = 52, + [2][0][RTW89_THAILAND][0][42] = 8, + [2][0][RTW89_FCC][1][44] = 8, + [2][0][RTW89_ETSI][1][44] = 56, + [2][0][RTW89_ETSI][0][44] = 18, + [2][0][RTW89_MKK][1][44] = 32, + [2][0][RTW89_MKK][0][44] = 14, + [2][0][RTW89_IC][1][44] = 8, + [2][0][RTW89_KCC][1][44] = -2, + [2][0][RTW89_KCC][0][44] = -2, + [2][0][RTW89_ACMA][1][44] = 56, + [2][0][RTW89_ACMA][0][44] = 18, + [2][0][RTW89_CHILE][1][44] = 8, + [2][0][RTW89_QATAR][1][44] = 56, + [2][0][RTW89_QATAR][0][44] = 18, + [2][0][RTW89_UK][1][44] = 56, + [2][0][RTW89_UK][0][44] = 18, + [2][0][RTW89_THAILAND][1][44] = 52, + [2][0][RTW89_THAILAND][0][44] = 8, + [2][0][RTW89_FCC][1][45] = 8, + [2][0][RTW89_ETSI][1][45] = 127, + [2][0][RTW89_ETSI][0][45] = 127, + [2][0][RTW89_MKK][1][45] = 127, + [2][0][RTW89_MKK][0][45] = 127, + [2][0][RTW89_IC][1][45] = 8, + [2][0][RTW89_KCC][1][45] = -2, + [2][0][RTW89_KCC][0][45] = 127, + [2][0][RTW89_ACMA][1][45] = 127, + [2][0][RTW89_ACMA][0][45] = 127, + [2][0][RTW89_CHILE][1][45] = 127, + [2][0][RTW89_QATAR][1][45] = 127, + [2][0][RTW89_QATAR][0][45] = 127, + [2][0][RTW89_UK][1][45] = 127, + [2][0][RTW89_UK][0][45] = 127, + [2][0][RTW89_THAILAND][1][45] = 127, + [2][0][RTW89_THAILAND][0][45] = 127, + [2][0][RTW89_FCC][1][47] = 8, + [2][0][RTW89_ETSI][1][47] = 127, + [2][0][RTW89_ETSI][0][47] = 127, + [2][0][RTW89_MKK][1][47] = 127, + [2][0][RTW89_MKK][0][47] = 127, + [2][0][RTW89_IC][1][47] = 8, + [2][0][RTW89_KCC][1][47] = -2, + [2][0][RTW89_KCC][0][47] = 127, + [2][0][RTW89_ACMA][1][47] = 127, + [2][0][RTW89_ACMA][0][47] = 127, + [2][0][RTW89_CHILE][1][47] = 127, + [2][0][RTW89_QATAR][1][47] = 127, + [2][0][RTW89_QATAR][0][47] = 127, + [2][0][RTW89_UK][1][47] = 127, + [2][0][RTW89_UK][0][47] = 127, + [2][0][RTW89_THAILAND][1][47] = 127, + [2][0][RTW89_THAILAND][0][47] = 127, + [2][0][RTW89_FCC][1][49] = 8, + [2][0][RTW89_ETSI][1][49] = 127, + [2][0][RTW89_ETSI][0][49] = 127, + [2][0][RTW89_MKK][1][49] = 127, + [2][0][RTW89_MKK][0][49] = 127, + [2][0][RTW89_IC][1][49] = 8, + [2][0][RTW89_KCC][1][49] = -2, + [2][0][RTW89_KCC][0][49] = 127, + [2][0][RTW89_ACMA][1][49] = 127, + [2][0][RTW89_ACMA][0][49] = 127, + [2][0][RTW89_CHILE][1][49] = 127, + [2][0][RTW89_QATAR][1][49] = 127, + [2][0][RTW89_QATAR][0][49] = 127, + [2][0][RTW89_UK][1][49] = 127, + [2][0][RTW89_UK][0][49] = 127, + [2][0][RTW89_THAILAND][1][49] = 127, + [2][0][RTW89_THAILAND][0][49] = 127, + [2][0][RTW89_FCC][1][51] = 8, + [2][0][RTW89_ETSI][1][51] = 127, + [2][0][RTW89_ETSI][0][51] = 127, + [2][0][RTW89_MKK][1][51] = 127, + [2][0][RTW89_MKK][0][51] = 127, + [2][0][RTW89_IC][1][51] = 8, + [2][0][RTW89_KCC][1][51] = -2, + [2][0][RTW89_KCC][0][51] = 127, + [2][0][RTW89_ACMA][1][51] = 127, + [2][0][RTW89_ACMA][0][51] = 127, + [2][0][RTW89_CHILE][1][51] = 127, + [2][0][RTW89_QATAR][1][51] = 127, + [2][0][RTW89_QATAR][0][51] = 127, + [2][0][RTW89_UK][1][51] = 127, + [2][0][RTW89_UK][0][51] = 127, + [2][0][RTW89_THAILAND][1][51] = 127, + [2][0][RTW89_THAILAND][0][51] = 127, + [2][0][RTW89_FCC][1][53] = 8, + [2][0][RTW89_ETSI][1][53] = 127, + [2][0][RTW89_ETSI][0][53] = 127, + [2][0][RTW89_MKK][1][53] = 127, + [2][0][RTW89_MKK][0][53] = 127, + [2][0][RTW89_IC][1][53] = 8, + [2][0][RTW89_KCC][1][53] = -2, + [2][0][RTW89_KCC][0][53] = 127, + [2][0][RTW89_ACMA][1][53] = 127, + [2][0][RTW89_ACMA][0][53] = 127, + [2][0][RTW89_CHILE][1][53] = 127, + [2][0][RTW89_QATAR][1][53] = 127, + [2][0][RTW89_QATAR][0][53] = 127, + [2][0][RTW89_UK][1][53] = 127, + [2][0][RTW89_UK][0][53] = 127, + [2][0][RTW89_THAILAND][1][53] = 127, + [2][0][RTW89_THAILAND][0][53] = 127, + [2][0][RTW89_FCC][1][55] = 8, + [2][0][RTW89_ETSI][1][55] = 127, + [2][0][RTW89_ETSI][0][55] = 127, + [2][0][RTW89_MKK][1][55] = 127, + [2][0][RTW89_MKK][0][55] = 127, + [2][0][RTW89_IC][1][55] = 8, + [2][0][RTW89_KCC][1][55] = -2, + [2][0][RTW89_KCC][0][55] = 127, + [2][0][RTW89_ACMA][1][55] = 127, + [2][0][RTW89_ACMA][0][55] = 127, + [2][0][RTW89_CHILE][1][55] = 127, + [2][0][RTW89_QATAR][1][55] = 127, + [2][0][RTW89_QATAR][0][55] = 127, + [2][0][RTW89_UK][1][55] = 127, + [2][0][RTW89_UK][0][55] = 127, + [2][0][RTW89_THAILAND][1][55] = 127, + [2][0][RTW89_THAILAND][0][55] = 127, + [2][0][RTW89_FCC][1][57] = 8, + [2][0][RTW89_ETSI][1][57] = 127, + [2][0][RTW89_ETSI][0][57] = 127, + [2][0][RTW89_MKK][1][57] = 127, + [2][0][RTW89_MKK][0][57] = 127, + [2][0][RTW89_IC][1][57] = 8, + [2][0][RTW89_KCC][1][57] = -2, + [2][0][RTW89_KCC][0][57] = 127, + [2][0][RTW89_ACMA][1][57] = 127, + [2][0][RTW89_ACMA][0][57] = 127, + [2][0][RTW89_CHILE][1][57] = 127, + [2][0][RTW89_QATAR][1][57] = 127, + [2][0][RTW89_QATAR][0][57] = 127, + [2][0][RTW89_UK][1][57] = 127, + [2][0][RTW89_UK][0][57] = 127, + [2][0][RTW89_THAILAND][1][57] = 127, + [2][0][RTW89_THAILAND][0][57] = 127, + [2][0][RTW89_FCC][1][59] = 8, + [2][0][RTW89_ETSI][1][59] = 127, + [2][0][RTW89_ETSI][0][59] = 127, + [2][0][RTW89_MKK][1][59] = 127, + [2][0][RTW89_MKK][0][59] = 127, + [2][0][RTW89_IC][1][59] = 8, + [2][0][RTW89_KCC][1][59] = -2, + [2][0][RTW89_KCC][0][59] = 127, + [2][0][RTW89_ACMA][1][59] = 127, + [2][0][RTW89_ACMA][0][59] = 127, + [2][0][RTW89_CHILE][1][59] = 127, + [2][0][RTW89_QATAR][1][59] = 127, + [2][0][RTW89_QATAR][0][59] = 127, + [2][0][RTW89_UK][1][59] = 127, + [2][0][RTW89_UK][0][59] = 127, + [2][0][RTW89_THAILAND][1][59] = 127, + [2][0][RTW89_THAILAND][0][59] = 127, + [2][0][RTW89_FCC][1][60] = 8, + [2][0][RTW89_ETSI][1][60] = 127, + [2][0][RTW89_ETSI][0][60] = 127, + [2][0][RTW89_MKK][1][60] = 127, + [2][0][RTW89_MKK][0][60] = 127, + [2][0][RTW89_IC][1][60] = 8, + [2][0][RTW89_KCC][1][60] = -2, + [2][0][RTW89_KCC][0][60] = 127, + [2][0][RTW89_ACMA][1][60] = 127, + [2][0][RTW89_ACMA][0][60] = 127, + [2][0][RTW89_CHILE][1][60] = 127, + [2][0][RTW89_QATAR][1][60] = 127, + [2][0][RTW89_QATAR][0][60] = 127, + [2][0][RTW89_UK][1][60] = 127, + [2][0][RTW89_UK][0][60] = 127, + [2][0][RTW89_THAILAND][1][60] = 127, + [2][0][RTW89_THAILAND][0][60] = 127, + [2][0][RTW89_FCC][1][62] = 8, + [2][0][RTW89_ETSI][1][62] = 127, + [2][0][RTW89_ETSI][0][62] = 127, + [2][0][RTW89_MKK][1][62] = 127, + [2][0][RTW89_MKK][0][62] = 127, + [2][0][RTW89_IC][1][62] = 8, + [2][0][RTW89_KCC][1][62] = -2, + [2][0][RTW89_KCC][0][62] = 127, + [2][0][RTW89_ACMA][1][62] = 127, + [2][0][RTW89_ACMA][0][62] = 127, + [2][0][RTW89_CHILE][1][62] = 127, + [2][0][RTW89_QATAR][1][62] = 127, + [2][0][RTW89_QATAR][0][62] = 127, + [2][0][RTW89_UK][1][62] = 127, + [2][0][RTW89_UK][0][62] = 127, + [2][0][RTW89_THAILAND][1][62] = 127, + [2][0][RTW89_THAILAND][0][62] = 127, + [2][0][RTW89_FCC][1][64] = 8, + [2][0][RTW89_ETSI][1][64] = 127, + [2][0][RTW89_ETSI][0][64] = 127, + [2][0][RTW89_MKK][1][64] = 127, + [2][0][RTW89_MKK][0][64] = 127, + [2][0][RTW89_IC][1][64] = 8, + [2][0][RTW89_KCC][1][64] = -2, + [2][0][RTW89_KCC][0][64] = 127, + [2][0][RTW89_ACMA][1][64] = 127, + [2][0][RTW89_ACMA][0][64] = 127, + [2][0][RTW89_CHILE][1][64] = 127, + [2][0][RTW89_QATAR][1][64] = 127, + [2][0][RTW89_QATAR][0][64] = 127, + [2][0][RTW89_UK][1][64] = 127, + [2][0][RTW89_UK][0][64] = 127, + [2][0][RTW89_THAILAND][1][64] = 127, + [2][0][RTW89_THAILAND][0][64] = 127, + [2][0][RTW89_FCC][1][66] = 8, + [2][0][RTW89_ETSI][1][66] = 127, + [2][0][RTW89_ETSI][0][66] = 127, + [2][0][RTW89_MKK][1][66] = 127, + [2][0][RTW89_MKK][0][66] = 127, + [2][0][RTW89_IC][1][66] = 8, + [2][0][RTW89_KCC][1][66] = -2, + [2][0][RTW89_KCC][0][66] = 127, + [2][0][RTW89_ACMA][1][66] = 127, + [2][0][RTW89_ACMA][0][66] = 127, + [2][0][RTW89_CHILE][1][66] = 127, + [2][0][RTW89_QATAR][1][66] = 127, + [2][0][RTW89_QATAR][0][66] = 127, + [2][0][RTW89_UK][1][66] = 127, + [2][0][RTW89_UK][0][66] = 127, + [2][0][RTW89_THAILAND][1][66] = 127, + [2][0][RTW89_THAILAND][0][66] = 127, + [2][0][RTW89_FCC][1][68] = 8, + [2][0][RTW89_ETSI][1][68] = 127, + [2][0][RTW89_ETSI][0][68] = 127, + [2][0][RTW89_MKK][1][68] = 127, + [2][0][RTW89_MKK][0][68] = 127, + [2][0][RTW89_IC][1][68] = 8, + [2][0][RTW89_KCC][1][68] = -2, + [2][0][RTW89_KCC][0][68] = 127, + [2][0][RTW89_ACMA][1][68] = 127, + [2][0][RTW89_ACMA][0][68] = 127, + [2][0][RTW89_CHILE][1][68] = 127, + [2][0][RTW89_QATAR][1][68] = 127, + [2][0][RTW89_QATAR][0][68] = 127, + [2][0][RTW89_UK][1][68] = 127, + [2][0][RTW89_UK][0][68] = 127, + [2][0][RTW89_THAILAND][1][68] = 127, + [2][0][RTW89_THAILAND][0][68] = 127, + [2][0][RTW89_FCC][1][70] = 8, + [2][0][RTW89_ETSI][1][70] = 127, + [2][0][RTW89_ETSI][0][70] = 127, + [2][0][RTW89_MKK][1][70] = 127, + [2][0][RTW89_MKK][0][70] = 127, + [2][0][RTW89_IC][1][70] = 8, + [2][0][RTW89_KCC][1][70] = -2, + [2][0][RTW89_KCC][0][70] = 127, + [2][0][RTW89_ACMA][1][70] = 127, + [2][0][RTW89_ACMA][0][70] = 127, + [2][0][RTW89_CHILE][1][70] = 127, + [2][0][RTW89_QATAR][1][70] = 127, + [2][0][RTW89_QATAR][0][70] = 127, + [2][0][RTW89_UK][1][70] = 127, + [2][0][RTW89_UK][0][70] = 127, + [2][0][RTW89_THAILAND][1][70] = 127, + [2][0][RTW89_THAILAND][0][70] = 127, + [2][0][RTW89_FCC][1][72] = 8, + [2][0][RTW89_ETSI][1][72] = 127, + [2][0][RTW89_ETSI][0][72] = 127, + [2][0][RTW89_MKK][1][72] = 127, + [2][0][RTW89_MKK][0][72] = 127, + [2][0][RTW89_IC][1][72] = 8, + [2][0][RTW89_KCC][1][72] = -2, + [2][0][RTW89_KCC][0][72] = 127, + [2][0][RTW89_ACMA][1][72] = 127, + [2][0][RTW89_ACMA][0][72] = 127, + [2][0][RTW89_CHILE][1][72] = 127, + [2][0][RTW89_QATAR][1][72] = 127, + [2][0][RTW89_QATAR][0][72] = 127, + [2][0][RTW89_UK][1][72] = 127, + [2][0][RTW89_UK][0][72] = 127, + [2][0][RTW89_THAILAND][1][72] = 127, + [2][0][RTW89_THAILAND][0][72] = 127, + [2][0][RTW89_FCC][1][74] = 8, + [2][0][RTW89_ETSI][1][74] = 127, + [2][0][RTW89_ETSI][0][74] = 127, + [2][0][RTW89_MKK][1][74] = 127, + [2][0][RTW89_MKK][0][74] = 127, + [2][0][RTW89_IC][1][74] = 8, + [2][0][RTW89_KCC][1][74] = -2, + [2][0][RTW89_KCC][0][74] = 127, + [2][0][RTW89_ACMA][1][74] = 127, + [2][0][RTW89_ACMA][0][74] = 127, + [2][0][RTW89_CHILE][1][74] = 127, + [2][0][RTW89_QATAR][1][74] = 127, + [2][0][RTW89_QATAR][0][74] = 127, + [2][0][RTW89_UK][1][74] = 127, + [2][0][RTW89_UK][0][74] = 127, + [2][0][RTW89_THAILAND][1][74] = 127, + [2][0][RTW89_THAILAND][0][74] = 127, + [2][0][RTW89_FCC][1][75] = 8, + [2][0][RTW89_ETSI][1][75] = 127, + [2][0][RTW89_ETSI][0][75] = 127, + [2][0][RTW89_MKK][1][75] = 127, + [2][0][RTW89_MKK][0][75] = 127, + [2][0][RTW89_IC][1][75] = 8, + [2][0][RTW89_KCC][1][75] = -2, + [2][0][RTW89_KCC][0][75] = 127, + [2][0][RTW89_ACMA][1][75] = 127, + [2][0][RTW89_ACMA][0][75] = 127, + [2][0][RTW89_CHILE][1][75] = 127, + [2][0][RTW89_QATAR][1][75] = 127, + [2][0][RTW89_QATAR][0][75] = 127, + [2][0][RTW89_UK][1][75] = 127, + [2][0][RTW89_UK][0][75] = 127, + [2][0][RTW89_THAILAND][1][75] = 127, + [2][0][RTW89_THAILAND][0][75] = 127, + [2][0][RTW89_FCC][1][77] = 8, + [2][0][RTW89_ETSI][1][77] = 127, + [2][0][RTW89_ETSI][0][77] = 127, + [2][0][RTW89_MKK][1][77] = 127, + [2][0][RTW89_MKK][0][77] = 127, + [2][0][RTW89_IC][1][77] = 8, + [2][0][RTW89_KCC][1][77] = -2, + [2][0][RTW89_KCC][0][77] = 127, + [2][0][RTW89_ACMA][1][77] = 127, + [2][0][RTW89_ACMA][0][77] = 127, + [2][0][RTW89_CHILE][1][77] = 127, + [2][0][RTW89_QATAR][1][77] = 127, + [2][0][RTW89_QATAR][0][77] = 127, + [2][0][RTW89_UK][1][77] = 127, + [2][0][RTW89_UK][0][77] = 127, + [2][0][RTW89_THAILAND][1][77] = 127, + [2][0][RTW89_THAILAND][0][77] = 127, + [2][0][RTW89_FCC][1][79] = 8, + [2][0][RTW89_ETSI][1][79] = 127, + [2][0][RTW89_ETSI][0][79] = 127, + [2][0][RTW89_MKK][1][79] = 127, + [2][0][RTW89_MKK][0][79] = 127, + [2][0][RTW89_IC][1][79] = 8, + [2][0][RTW89_KCC][1][79] = -2, + [2][0][RTW89_KCC][0][79] = 127, + [2][0][RTW89_ACMA][1][79] = 127, + [2][0][RTW89_ACMA][0][79] = 127, + [2][0][RTW89_CHILE][1][79] = 127, + [2][0][RTW89_QATAR][1][79] = 127, + [2][0][RTW89_QATAR][0][79] = 127, + [2][0][RTW89_UK][1][79] = 127, + [2][0][RTW89_UK][0][79] = 127, + [2][0][RTW89_THAILAND][1][79] = 127, + [2][0][RTW89_THAILAND][0][79] = 127, + [2][0][RTW89_FCC][1][81] = 8, + [2][0][RTW89_ETSI][1][81] = 127, + [2][0][RTW89_ETSI][0][81] = 127, + [2][0][RTW89_MKK][1][81] = 127, + [2][0][RTW89_MKK][0][81] = 127, + [2][0][RTW89_IC][1][81] = 8, + [2][0][RTW89_KCC][1][81] = -2, + [2][0][RTW89_KCC][0][81] = 127, + [2][0][RTW89_ACMA][1][81] = 127, + [2][0][RTW89_ACMA][0][81] = 127, + [2][0][RTW89_CHILE][1][81] = 127, + [2][0][RTW89_QATAR][1][81] = 127, + [2][0][RTW89_QATAR][0][81] = 127, + [2][0][RTW89_UK][1][81] = 127, + [2][0][RTW89_UK][0][81] = 127, + [2][0][RTW89_THAILAND][1][81] = 127, + [2][0][RTW89_THAILAND][0][81] = 127, + [2][0][RTW89_FCC][1][83] = 8, + [2][0][RTW89_ETSI][1][83] = 127, + [2][0][RTW89_ETSI][0][83] = 127, + [2][0][RTW89_MKK][1][83] = 127, + [2][0][RTW89_MKK][0][83] = 127, + [2][0][RTW89_IC][1][83] = 8, + [2][0][RTW89_KCC][1][83] = -2, + [2][0][RTW89_KCC][0][83] = 127, + [2][0][RTW89_ACMA][1][83] = 127, + [2][0][RTW89_ACMA][0][83] = 127, + [2][0][RTW89_CHILE][1][83] = 127, + [2][0][RTW89_QATAR][1][83] = 127, + [2][0][RTW89_QATAR][0][83] = 127, + [2][0][RTW89_UK][1][83] = 127, + [2][0][RTW89_UK][0][83] = 127, + [2][0][RTW89_THAILAND][1][83] = 127, + [2][0][RTW89_THAILAND][0][83] = 127, + [2][0][RTW89_FCC][1][85] = 8, + [2][0][RTW89_ETSI][1][85] = 127, + [2][0][RTW89_ETSI][0][85] = 127, + [2][0][RTW89_MKK][1][85] = 127, + [2][0][RTW89_MKK][0][85] = 127, + [2][0][RTW89_IC][1][85] = 8, + [2][0][RTW89_KCC][1][85] = -2, + [2][0][RTW89_KCC][0][85] = 127, + [2][0][RTW89_ACMA][1][85] = 127, + [2][0][RTW89_ACMA][0][85] = 127, + [2][0][RTW89_CHILE][1][85] = 127, + [2][0][RTW89_QATAR][1][85] = 127, + [2][0][RTW89_QATAR][0][85] = 127, + [2][0][RTW89_UK][1][85] = 127, + [2][0][RTW89_UK][0][85] = 127, + [2][0][RTW89_THAILAND][1][85] = 127, + [2][0][RTW89_THAILAND][0][85] = 127, + [2][0][RTW89_FCC][1][87] = 8, + [2][0][RTW89_ETSI][1][87] = 127, + [2][0][RTW89_ETSI][0][87] = 127, + [2][0][RTW89_MKK][1][87] = 127, + [2][0][RTW89_MKK][0][87] = 127, + [2][0][RTW89_IC][1][87] = 8, + [2][0][RTW89_KCC][1][87] = -2, + [2][0][RTW89_KCC][0][87] = 127, + [2][0][RTW89_ACMA][1][87] = 127, + [2][0][RTW89_ACMA][0][87] = 127, + [2][0][RTW89_CHILE][1][87] = 127, + [2][0][RTW89_QATAR][1][87] = 127, + [2][0][RTW89_QATAR][0][87] = 127, + [2][0][RTW89_UK][1][87] = 127, + [2][0][RTW89_UK][0][87] = 127, + [2][0][RTW89_THAILAND][1][87] = 127, + [2][0][RTW89_THAILAND][0][87] = 127, + [2][0][RTW89_FCC][1][89] = 8, + [2][0][RTW89_ETSI][1][89] = 127, + [2][0][RTW89_ETSI][0][89] = 127, + [2][0][RTW89_MKK][1][89] = 127, + [2][0][RTW89_MKK][0][89] = 127, + [2][0][RTW89_IC][1][89] = 8, + [2][0][RTW89_KCC][1][89] = -2, + [2][0][RTW89_KCC][0][89] = 127, + [2][0][RTW89_ACMA][1][89] = 127, + [2][0][RTW89_ACMA][0][89] = 127, + [2][0][RTW89_CHILE][1][89] = 127, + [2][0][RTW89_QATAR][1][89] = 127, + [2][0][RTW89_QATAR][0][89] = 127, + [2][0][RTW89_UK][1][89] = 127, + [2][0][RTW89_UK][0][89] = 127, + [2][0][RTW89_THAILAND][1][89] = 127, + [2][0][RTW89_THAILAND][0][89] = 127, + [2][0][RTW89_FCC][1][90] = 8, + [2][0][RTW89_ETSI][1][90] = 127, + [2][0][RTW89_ETSI][0][90] = 127, + [2][0][RTW89_MKK][1][90] = 127, + [2][0][RTW89_MKK][0][90] = 127, + [2][0][RTW89_IC][1][90] = 8, + [2][0][RTW89_KCC][1][90] = -2, + [2][0][RTW89_KCC][0][90] = 127, + [2][0][RTW89_ACMA][1][90] = 127, + [2][0][RTW89_ACMA][0][90] = 127, + [2][0][RTW89_CHILE][1][90] = 127, + [2][0][RTW89_QATAR][1][90] = 127, + [2][0][RTW89_QATAR][0][90] = 127, + [2][0][RTW89_UK][1][90] = 127, + [2][0][RTW89_UK][0][90] = 127, + [2][0][RTW89_THAILAND][1][90] = 127, + [2][0][RTW89_THAILAND][0][90] = 127, + [2][0][RTW89_FCC][1][92] = 8, + [2][0][RTW89_ETSI][1][92] = 127, + [2][0][RTW89_ETSI][0][92] = 127, + [2][0][RTW89_MKK][1][92] = 127, + [2][0][RTW89_MKK][0][92] = 127, + [2][0][RTW89_IC][1][92] = 8, + [2][0][RTW89_KCC][1][92] = -2, + [2][0][RTW89_KCC][0][92] = 127, + [2][0][RTW89_ACMA][1][92] = 127, + [2][0][RTW89_ACMA][0][92] = 127, + [2][0][RTW89_CHILE][1][92] = 127, + [2][0][RTW89_QATAR][1][92] = 127, + [2][0][RTW89_QATAR][0][92] = 127, + [2][0][RTW89_UK][1][92] = 127, + [2][0][RTW89_UK][0][92] = 127, + [2][0][RTW89_THAILAND][1][92] = 127, + [2][0][RTW89_THAILAND][0][92] = 127, + [2][0][RTW89_FCC][1][94] = 8, + [2][0][RTW89_ETSI][1][94] = 127, + [2][0][RTW89_ETSI][0][94] = 127, + [2][0][RTW89_MKK][1][94] = 127, + [2][0][RTW89_MKK][0][94] = 127, + [2][0][RTW89_IC][1][94] = 8, + [2][0][RTW89_KCC][1][94] = -2, + [2][0][RTW89_KCC][0][94] = 127, + [2][0][RTW89_ACMA][1][94] = 127, + [2][0][RTW89_ACMA][0][94] = 127, + [2][0][RTW89_CHILE][1][94] = 127, + [2][0][RTW89_QATAR][1][94] = 127, + [2][0][RTW89_QATAR][0][94] = 127, + [2][0][RTW89_UK][1][94] = 127, + [2][0][RTW89_UK][0][94] = 127, + [2][0][RTW89_THAILAND][1][94] = 127, + [2][0][RTW89_THAILAND][0][94] = 127, + [2][0][RTW89_FCC][1][96] = 8, + [2][0][RTW89_ETSI][1][96] = 127, + [2][0][RTW89_ETSI][0][96] = 127, + [2][0][RTW89_MKK][1][96] = 127, + [2][0][RTW89_MKK][0][96] = 127, + [2][0][RTW89_IC][1][96] = 8, + [2][0][RTW89_KCC][1][96] = -2, + [2][0][RTW89_KCC][0][96] = 127, + [2][0][RTW89_ACMA][1][96] = 127, + [2][0][RTW89_ACMA][0][96] = 127, + [2][0][RTW89_CHILE][1][96] = 127, + [2][0][RTW89_QATAR][1][96] = 127, + [2][0][RTW89_QATAR][0][96] = 127, + [2][0][RTW89_UK][1][96] = 127, + [2][0][RTW89_UK][0][96] = 127, + [2][0][RTW89_THAILAND][1][96] = 127, + [2][0][RTW89_THAILAND][0][96] = 127, + [2][0][RTW89_FCC][1][98] = 8, + [2][0][RTW89_ETSI][1][98] = 127, + [2][0][RTW89_ETSI][0][98] = 127, + [2][0][RTW89_MKK][1][98] = 127, + [2][0][RTW89_MKK][0][98] = 127, + [2][0][RTW89_IC][1][98] = 8, + [2][0][RTW89_KCC][1][98] = -2, + [2][0][RTW89_KCC][0][98] = 127, + [2][0][RTW89_ACMA][1][98] = 127, + [2][0][RTW89_ACMA][0][98] = 127, + [2][0][RTW89_CHILE][1][98] = 127, + [2][0][RTW89_QATAR][1][98] = 127, + [2][0][RTW89_QATAR][0][98] = 127, + [2][0][RTW89_UK][1][98] = 127, + [2][0][RTW89_UK][0][98] = 127, + [2][0][RTW89_THAILAND][1][98] = 127, + [2][0][RTW89_THAILAND][0][98] = 127, + [2][0][RTW89_FCC][1][100] = 8, + [2][0][RTW89_ETSI][1][100] = 127, + [2][0][RTW89_ETSI][0][100] = 127, + [2][0][RTW89_MKK][1][100] = 127, + [2][0][RTW89_MKK][0][100] = 127, + [2][0][RTW89_IC][1][100] = 8, + [2][0][RTW89_KCC][1][100] = -2, + [2][0][RTW89_KCC][0][100] = 127, + [2][0][RTW89_ACMA][1][100] = 127, + [2][0][RTW89_ACMA][0][100] = 127, + [2][0][RTW89_CHILE][1][100] = 127, + [2][0][RTW89_QATAR][1][100] = 127, + [2][0][RTW89_QATAR][0][100] = 127, + [2][0][RTW89_UK][1][100] = 127, + [2][0][RTW89_UK][0][100] = 127, + [2][0][RTW89_THAILAND][1][100] = 127, + [2][0][RTW89_THAILAND][0][100] = 127, + [2][0][RTW89_FCC][1][102] = 8, + [2][0][RTW89_ETSI][1][102] = 127, + [2][0][RTW89_ETSI][0][102] = 127, + [2][0][RTW89_MKK][1][102] = 127, + [2][0][RTW89_MKK][0][102] = 127, + [2][0][RTW89_IC][1][102] = 8, + [2][0][RTW89_KCC][1][102] = -2, + [2][0][RTW89_KCC][0][102] = 127, + [2][0][RTW89_ACMA][1][102] = 127, + [2][0][RTW89_ACMA][0][102] = 127, + [2][0][RTW89_CHILE][1][102] = 127, + [2][0][RTW89_QATAR][1][102] = 127, + [2][0][RTW89_QATAR][0][102] = 127, + [2][0][RTW89_UK][1][102] = 127, + [2][0][RTW89_UK][0][102] = 127, + [2][0][RTW89_THAILAND][1][102] = 127, + [2][0][RTW89_THAILAND][0][102] = 127, + [2][0][RTW89_FCC][1][104] = 8, + [2][0][RTW89_ETSI][1][104] = 127, + [2][0][RTW89_ETSI][0][104] = 127, + [2][0][RTW89_MKK][1][104] = 127, + [2][0][RTW89_MKK][0][104] = 127, + [2][0][RTW89_IC][1][104] = 8, + [2][0][RTW89_KCC][1][104] = -2, + [2][0][RTW89_KCC][0][104] = 127, + [2][0][RTW89_ACMA][1][104] = 127, + [2][0][RTW89_ACMA][0][104] = 127, + [2][0][RTW89_CHILE][1][104] = 127, + [2][0][RTW89_QATAR][1][104] = 127, + [2][0][RTW89_QATAR][0][104] = 127, + [2][0][RTW89_UK][1][104] = 127, + [2][0][RTW89_UK][0][104] = 127, + [2][0][RTW89_THAILAND][1][104] = 127, + [2][0][RTW89_THAILAND][0][104] = 127, + [2][0][RTW89_FCC][1][105] = 8, + [2][0][RTW89_ETSI][1][105] = 127, + [2][0][RTW89_ETSI][0][105] = 127, + [2][0][RTW89_MKK][1][105] = 127, + [2][0][RTW89_MKK][0][105] = 127, + [2][0][RTW89_IC][1][105] = 8, + [2][0][RTW89_KCC][1][105] = -2, + [2][0][RTW89_KCC][0][105] = 127, + [2][0][RTW89_ACMA][1][105] = 127, + [2][0][RTW89_ACMA][0][105] = 127, + [2][0][RTW89_CHILE][1][105] = 127, + [2][0][RTW89_QATAR][1][105] = 127, + [2][0][RTW89_QATAR][0][105] = 127, + [2][0][RTW89_UK][1][105] = 127, + [2][0][RTW89_UK][0][105] = 127, + [2][0][RTW89_THAILAND][1][105] = 127, + [2][0][RTW89_THAILAND][0][105] = 127, + [2][0][RTW89_FCC][1][107] = 10, + [2][0][RTW89_ETSI][1][107] = 127, + [2][0][RTW89_ETSI][0][107] = 127, + [2][0][RTW89_MKK][1][107] = 127, + [2][0][RTW89_MKK][0][107] = 127, + [2][0][RTW89_IC][1][107] = 10, + [2][0][RTW89_KCC][1][107] = -2, + [2][0][RTW89_KCC][0][107] = 127, + [2][0][RTW89_ACMA][1][107] = 127, + [2][0][RTW89_ACMA][0][107] = 127, + [2][0][RTW89_CHILE][1][107] = 127, + [2][0][RTW89_QATAR][1][107] = 127, + [2][0][RTW89_QATAR][0][107] = 127, + [2][0][RTW89_UK][1][107] = 127, + [2][0][RTW89_UK][0][107] = 127, + [2][0][RTW89_THAILAND][1][107] = 127, + [2][0][RTW89_THAILAND][0][107] = 127, + [2][0][RTW89_FCC][1][109] = 12, + [2][0][RTW89_ETSI][1][109] = 127, + [2][0][RTW89_ETSI][0][109] = 127, + [2][0][RTW89_MKK][1][109] = 127, + [2][0][RTW89_MKK][0][109] = 127, + [2][0][RTW89_IC][1][109] = 12, + [2][0][RTW89_KCC][1][109] = 127, + [2][0][RTW89_KCC][0][109] = 127, + [2][0][RTW89_ACMA][1][109] = 127, + [2][0][RTW89_ACMA][0][109] = 127, + [2][0][RTW89_CHILE][1][109] = 127, + [2][0][RTW89_QATAR][1][109] = 127, + [2][0][RTW89_QATAR][0][109] = 127, + [2][0][RTW89_UK][1][109] = 127, + [2][0][RTW89_UK][0][109] = 127, + [2][0][RTW89_THAILAND][1][109] = 127, + [2][0][RTW89_THAILAND][0][109] = 127, + [2][0][RTW89_FCC][1][111] = 127, + [2][0][RTW89_ETSI][1][111] = 127, + [2][0][RTW89_ETSI][0][111] = 127, + [2][0][RTW89_MKK][1][111] = 127, + [2][0][RTW89_MKK][0][111] = 127, + [2][0][RTW89_IC][1][111] = 127, + [2][0][RTW89_KCC][1][111] = 127, + [2][0][RTW89_KCC][0][111] = 127, + [2][0][RTW89_ACMA][1][111] = 127, + [2][0][RTW89_ACMA][0][111] = 127, + [2][0][RTW89_CHILE][1][111] = 127, + [2][0][RTW89_QATAR][1][111] = 127, + [2][0][RTW89_QATAR][0][111] = 127, + [2][0][RTW89_UK][1][111] = 127, + [2][0][RTW89_UK][0][111] = 127, + [2][0][RTW89_THAILAND][1][111] = 127, + [2][0][RTW89_THAILAND][0][111] = 127, + [2][0][RTW89_FCC][1][113] = 127, + [2][0][RTW89_ETSI][1][113] = 127, + [2][0][RTW89_ETSI][0][113] = 127, + [2][0][RTW89_MKK][1][113] = 127, + [2][0][RTW89_MKK][0][113] = 127, + [2][0][RTW89_IC][1][113] = 127, + [2][0][RTW89_KCC][1][113] = 127, + [2][0][RTW89_KCC][0][113] = 127, + [2][0][RTW89_ACMA][1][113] = 127, + [2][0][RTW89_ACMA][0][113] = 127, + [2][0][RTW89_CHILE][1][113] = 127, + [2][0][RTW89_QATAR][1][113] = 127, + [2][0][RTW89_QATAR][0][113] = 127, + [2][0][RTW89_UK][1][113] = 127, + [2][0][RTW89_UK][0][113] = 127, + [2][0][RTW89_THAILAND][1][113] = 127, + [2][0][RTW89_THAILAND][0][113] = 127, + [2][0][RTW89_FCC][1][115] = 127, + [2][0][RTW89_ETSI][1][115] = 127, + [2][0][RTW89_ETSI][0][115] = 127, + [2][0][RTW89_MKK][1][115] = 127, + [2][0][RTW89_MKK][0][115] = 127, + [2][0][RTW89_IC][1][115] = 127, + [2][0][RTW89_KCC][1][115] = 127, + [2][0][RTW89_KCC][0][115] = 127, + [2][0][RTW89_ACMA][1][115] = 127, + [2][0][RTW89_ACMA][0][115] = 127, + [2][0][RTW89_CHILE][1][115] = 127, + [2][0][RTW89_QATAR][1][115] = 127, + [2][0][RTW89_QATAR][0][115] = 127, + [2][0][RTW89_UK][1][115] = 127, + [2][0][RTW89_UK][0][115] = 127, + [2][0][RTW89_THAILAND][1][115] = 127, + [2][0][RTW89_THAILAND][0][115] = 127, + [2][0][RTW89_FCC][1][117] = 127, + [2][0][RTW89_ETSI][1][117] = 127, + [2][0][RTW89_ETSI][0][117] = 127, + [2][0][RTW89_MKK][1][117] = 127, + [2][0][RTW89_MKK][0][117] = 127, + [2][0][RTW89_IC][1][117] = 127, + [2][0][RTW89_KCC][1][117] = 127, + [2][0][RTW89_KCC][0][117] = 127, + [2][0][RTW89_ACMA][1][117] = 127, + [2][0][RTW89_ACMA][0][117] = 127, + [2][0][RTW89_CHILE][1][117] = 127, + [2][0][RTW89_QATAR][1][117] = 127, + [2][0][RTW89_QATAR][0][117] = 127, + [2][0][RTW89_UK][1][117] = 127, + [2][0][RTW89_UK][0][117] = 127, + [2][0][RTW89_THAILAND][1][117] = 127, + [2][0][RTW89_THAILAND][0][117] = 127, + [2][0][RTW89_FCC][1][119] = 127, + [2][0][RTW89_ETSI][1][119] = 127, + [2][0][RTW89_ETSI][0][119] = 127, + [2][0][RTW89_MKK][1][119] = 127, + [2][0][RTW89_MKK][0][119] = 127, + [2][0][RTW89_IC][1][119] = 127, + [2][0][RTW89_KCC][1][119] = 127, + [2][0][RTW89_KCC][0][119] = 127, + [2][0][RTW89_ACMA][1][119] = 127, + [2][0][RTW89_ACMA][0][119] = 127, + [2][0][RTW89_CHILE][1][119] = 127, + [2][0][RTW89_QATAR][1][119] = 127, + [2][0][RTW89_QATAR][0][119] = 127, + [2][0][RTW89_UK][1][119] = 127, + [2][0][RTW89_UK][0][119] = 127, + [2][0][RTW89_THAILAND][1][119] = 127, + [2][0][RTW89_THAILAND][0][119] = 127, + [2][1][RTW89_FCC][1][0] = -16, + [2][1][RTW89_ETSI][1][0] = 44, + [2][1][RTW89_ETSI][0][0] = 6, + [2][1][RTW89_MKK][1][0] = 42, + [2][1][RTW89_MKK][0][0] = 2, + [2][1][RTW89_IC][1][0] = -16, + [2][1][RTW89_KCC][1][0] = -14, + [2][1][RTW89_KCC][0][0] = -14, + [2][1][RTW89_ACMA][1][0] = 44, + [2][1][RTW89_ACMA][0][0] = 6, + [2][1][RTW89_CHILE][1][0] = -16, + [2][1][RTW89_QATAR][1][0] = 44, + [2][1][RTW89_QATAR][0][0] = 6, + [2][1][RTW89_UK][1][0] = 44, + [2][1][RTW89_UK][0][0] = 6, + [2][1][RTW89_THAILAND][1][0] = 28, + [2][1][RTW89_THAILAND][0][0] = -16, + [2][1][RTW89_FCC][1][2] = -16, + [2][1][RTW89_ETSI][1][2] = 44, + [2][1][RTW89_ETSI][0][2] = 6, + [2][1][RTW89_MKK][1][2] = 40, + [2][1][RTW89_MKK][0][2] = 2, + [2][1][RTW89_IC][1][2] = -16, + [2][1][RTW89_KCC][1][2] = -14, + [2][1][RTW89_KCC][0][2] = -14, + [2][1][RTW89_ACMA][1][2] = 44, + [2][1][RTW89_ACMA][0][2] = 6, + [2][1][RTW89_CHILE][1][2] = -16, + [2][1][RTW89_QATAR][1][2] = 44, + [2][1][RTW89_QATAR][0][2] = 6, + [2][1][RTW89_UK][1][2] = 44, + [2][1][RTW89_UK][0][2] = 6, + [2][1][RTW89_THAILAND][1][2] = 28, + [2][1][RTW89_THAILAND][0][2] = -16, + [2][1][RTW89_FCC][1][4] = -16, + [2][1][RTW89_ETSI][1][4] = 44, + [2][1][RTW89_ETSI][0][4] = 6, + [2][1][RTW89_MKK][1][4] = 40, + [2][1][RTW89_MKK][0][4] = 2, + [2][1][RTW89_IC][1][4] = -16, + [2][1][RTW89_KCC][1][4] = -14, + [2][1][RTW89_KCC][0][4] = -14, + [2][1][RTW89_ACMA][1][4] = 44, + [2][1][RTW89_ACMA][0][4] = 6, + [2][1][RTW89_CHILE][1][4] = -16, + [2][1][RTW89_QATAR][1][4] = 44, + [2][1][RTW89_QATAR][0][4] = 6, + [2][1][RTW89_UK][1][4] = 44, + [2][1][RTW89_UK][0][4] = 6, + [2][1][RTW89_THAILAND][1][4] = 28, + [2][1][RTW89_THAILAND][0][4] = -16, + [2][1][RTW89_FCC][1][6] = -16, + [2][1][RTW89_ETSI][1][6] = 44, + [2][1][RTW89_ETSI][0][6] = 6, + [2][1][RTW89_MKK][1][6] = 40, + [2][1][RTW89_MKK][0][6] = 2, + [2][1][RTW89_IC][1][6] = -16, + [2][1][RTW89_KCC][1][6] = -14, + [2][1][RTW89_KCC][0][6] = -14, + [2][1][RTW89_ACMA][1][6] = 44, + [2][1][RTW89_ACMA][0][6] = 6, + [2][1][RTW89_CHILE][1][6] = -16, + [2][1][RTW89_QATAR][1][6] = 44, + [2][1][RTW89_QATAR][0][6] = 6, + [2][1][RTW89_UK][1][6] = 44, + [2][1][RTW89_UK][0][6] = 6, + [2][1][RTW89_THAILAND][1][6] = 28, + [2][1][RTW89_THAILAND][0][6] = -16, + [2][1][RTW89_FCC][1][8] = -16, + [2][1][RTW89_ETSI][1][8] = 44, + [2][1][RTW89_ETSI][0][8] = 6, + [2][1][RTW89_MKK][1][8] = 40, + [2][1][RTW89_MKK][0][8] = 2, + [2][1][RTW89_IC][1][8] = -16, + [2][1][RTW89_KCC][1][8] = -14, + [2][1][RTW89_KCC][0][8] = -14, + [2][1][RTW89_ACMA][1][8] = 44, + [2][1][RTW89_ACMA][0][8] = 6, + [2][1][RTW89_CHILE][1][8] = -16, + [2][1][RTW89_QATAR][1][8] = 44, + [2][1][RTW89_QATAR][0][8] = 6, + [2][1][RTW89_UK][1][8] = 44, + [2][1][RTW89_UK][0][8] = 6, + [2][1][RTW89_THAILAND][1][8] = 28, + [2][1][RTW89_THAILAND][0][8] = -16, + [2][1][RTW89_FCC][1][10] = -16, + [2][1][RTW89_ETSI][1][10] = 44, + [2][1][RTW89_ETSI][0][10] = 6, + [2][1][RTW89_MKK][1][10] = 40, + [2][1][RTW89_MKK][0][10] = 2, + [2][1][RTW89_IC][1][10] = -16, + [2][1][RTW89_KCC][1][10] = -14, + [2][1][RTW89_KCC][0][10] = -14, + [2][1][RTW89_ACMA][1][10] = 44, + [2][1][RTW89_ACMA][0][10] = 6, + [2][1][RTW89_CHILE][1][10] = -16, + [2][1][RTW89_QATAR][1][10] = 44, + [2][1][RTW89_QATAR][0][10] = 6, + [2][1][RTW89_UK][1][10] = 44, + [2][1][RTW89_UK][0][10] = 6, + [2][1][RTW89_THAILAND][1][10] = 28, + [2][1][RTW89_THAILAND][0][10] = -16, + [2][1][RTW89_FCC][1][12] = -16, + [2][1][RTW89_ETSI][1][12] = 44, + [2][1][RTW89_ETSI][0][12] = 6, + [2][1][RTW89_MKK][1][12] = 40, + [2][1][RTW89_MKK][0][12] = 2, + [2][1][RTW89_IC][1][12] = -16, + [2][1][RTW89_KCC][1][12] = -14, + [2][1][RTW89_KCC][0][12] = -14, + [2][1][RTW89_ACMA][1][12] = 44, + [2][1][RTW89_ACMA][0][12] = 6, + [2][1][RTW89_CHILE][1][12] = -16, + [2][1][RTW89_QATAR][1][12] = 44, + [2][1][RTW89_QATAR][0][12] = 6, + [2][1][RTW89_UK][1][12] = 44, + [2][1][RTW89_UK][0][12] = 6, + [2][1][RTW89_THAILAND][1][12] = 28, + [2][1][RTW89_THAILAND][0][12] = -16, + [2][1][RTW89_FCC][1][14] = -16, + [2][1][RTW89_ETSI][1][14] = 44, + [2][1][RTW89_ETSI][0][14] = 6, + [2][1][RTW89_MKK][1][14] = 40, + [2][1][RTW89_MKK][0][14] = 2, + [2][1][RTW89_IC][1][14] = -16, + [2][1][RTW89_KCC][1][14] = -14, + [2][1][RTW89_KCC][0][14] = -14, + [2][1][RTW89_ACMA][1][14] = 44, + [2][1][RTW89_ACMA][0][14] = 6, + [2][1][RTW89_CHILE][1][14] = -16, + [2][1][RTW89_QATAR][1][14] = 44, + [2][1][RTW89_QATAR][0][14] = 6, + [2][1][RTW89_UK][1][14] = 44, + [2][1][RTW89_UK][0][14] = 6, + [2][1][RTW89_THAILAND][1][14] = 28, + [2][1][RTW89_THAILAND][0][14] = -16, + [2][1][RTW89_FCC][1][15] = -16, + [2][1][RTW89_ETSI][1][15] = 44, + [2][1][RTW89_ETSI][0][15] = 6, + [2][1][RTW89_MKK][1][15] = 40, + [2][1][RTW89_MKK][0][15] = 2, + [2][1][RTW89_IC][1][15] = -16, + [2][1][RTW89_KCC][1][15] = -14, + [2][1][RTW89_KCC][0][15] = -14, + [2][1][RTW89_ACMA][1][15] = 44, + [2][1][RTW89_ACMA][0][15] = 6, + [2][1][RTW89_CHILE][1][15] = -16, + [2][1][RTW89_QATAR][1][15] = 44, + [2][1][RTW89_QATAR][0][15] = 6, + [2][1][RTW89_UK][1][15] = 44, + [2][1][RTW89_UK][0][15] = 6, + [2][1][RTW89_THAILAND][1][15] = 28, + [2][1][RTW89_THAILAND][0][15] = -16, + [2][1][RTW89_FCC][1][17] = -16, + [2][1][RTW89_ETSI][1][17] = 44, + [2][1][RTW89_ETSI][0][17] = 6, + [2][1][RTW89_MKK][1][17] = 40, + [2][1][RTW89_MKK][0][17] = 2, + [2][1][RTW89_IC][1][17] = -16, + [2][1][RTW89_KCC][1][17] = -14, + [2][1][RTW89_KCC][0][17] = -14, + [2][1][RTW89_ACMA][1][17] = 44, + [2][1][RTW89_ACMA][0][17] = 6, + [2][1][RTW89_CHILE][1][17] = -16, + [2][1][RTW89_QATAR][1][17] = 44, + [2][1][RTW89_QATAR][0][17] = 6, + [2][1][RTW89_UK][1][17] = 44, + [2][1][RTW89_UK][0][17] = 6, + [2][1][RTW89_THAILAND][1][17] = 28, + [2][1][RTW89_THAILAND][0][17] = -16, + [2][1][RTW89_FCC][1][19] = -16, + [2][1][RTW89_ETSI][1][19] = 44, + [2][1][RTW89_ETSI][0][19] = 6, + [2][1][RTW89_MKK][1][19] = 40, + [2][1][RTW89_MKK][0][19] = 2, + [2][1][RTW89_IC][1][19] = -16, + [2][1][RTW89_KCC][1][19] = -14, + [2][1][RTW89_KCC][0][19] = -14, + [2][1][RTW89_ACMA][1][19] = 44, + [2][1][RTW89_ACMA][0][19] = 6, + [2][1][RTW89_CHILE][1][19] = -16, + [2][1][RTW89_QATAR][1][19] = 44, + [2][1][RTW89_QATAR][0][19] = 6, + [2][1][RTW89_UK][1][19] = 44, + [2][1][RTW89_UK][0][19] = 6, + [2][1][RTW89_THAILAND][1][19] = 28, + [2][1][RTW89_THAILAND][0][19] = -16, + [2][1][RTW89_FCC][1][21] = -16, + [2][1][RTW89_ETSI][1][21] = 44, + [2][1][RTW89_ETSI][0][21] = 6, + [2][1][RTW89_MKK][1][21] = 40, + [2][1][RTW89_MKK][0][21] = 2, + [2][1][RTW89_IC][1][21] = -16, + [2][1][RTW89_KCC][1][21] = -14, + [2][1][RTW89_KCC][0][21] = -14, + [2][1][RTW89_ACMA][1][21] = 44, + [2][1][RTW89_ACMA][0][21] = 6, + [2][1][RTW89_CHILE][1][21] = -16, + [2][1][RTW89_QATAR][1][21] = 44, + [2][1][RTW89_QATAR][0][21] = 6, + [2][1][RTW89_UK][1][21] = 44, + [2][1][RTW89_UK][0][21] = 6, + [2][1][RTW89_THAILAND][1][21] = 28, + [2][1][RTW89_THAILAND][0][21] = -16, + [2][1][RTW89_FCC][1][23] = -16, + [2][1][RTW89_ETSI][1][23] = 44, + [2][1][RTW89_ETSI][0][23] = 6, + [2][1][RTW89_MKK][1][23] = 40, + [2][1][RTW89_MKK][0][23] = 2, + [2][1][RTW89_IC][1][23] = -16, + [2][1][RTW89_KCC][1][23] = -14, + [2][1][RTW89_KCC][0][23] = -14, + [2][1][RTW89_ACMA][1][23] = 44, + [2][1][RTW89_ACMA][0][23] = 6, + [2][1][RTW89_CHILE][1][23] = -16, + [2][1][RTW89_QATAR][1][23] = 44, + [2][1][RTW89_QATAR][0][23] = 6, + [2][1][RTW89_UK][1][23] = 44, + [2][1][RTW89_UK][0][23] = 6, + [2][1][RTW89_THAILAND][1][23] = 30, + [2][1][RTW89_THAILAND][0][23] = -16, + [2][1][RTW89_FCC][1][25] = -16, + [2][1][RTW89_ETSI][1][25] = 44, + [2][1][RTW89_ETSI][0][25] = 6, + [2][1][RTW89_MKK][1][25] = 40, + [2][1][RTW89_MKK][0][25] = 2, + [2][1][RTW89_IC][1][25] = -16, + [2][1][RTW89_KCC][1][25] = -14, + [2][1][RTW89_KCC][0][25] = -14, + [2][1][RTW89_ACMA][1][25] = 44, + [2][1][RTW89_ACMA][0][25] = 6, + [2][1][RTW89_CHILE][1][25] = -16, + [2][1][RTW89_QATAR][1][25] = 44, + [2][1][RTW89_QATAR][0][25] = 6, + [2][1][RTW89_UK][1][25] = 44, + [2][1][RTW89_UK][0][25] = 6, + [2][1][RTW89_THAILAND][1][25] = 28, + [2][1][RTW89_THAILAND][0][25] = -16, + [2][1][RTW89_FCC][1][27] = -16, + [2][1][RTW89_ETSI][1][27] = 44, + [2][1][RTW89_ETSI][0][27] = 6, + [2][1][RTW89_MKK][1][27] = 40, + [2][1][RTW89_MKK][0][27] = 2, + [2][1][RTW89_IC][1][27] = -16, + [2][1][RTW89_KCC][1][27] = -14, + [2][1][RTW89_KCC][0][27] = -14, + [2][1][RTW89_ACMA][1][27] = 44, + [2][1][RTW89_ACMA][0][27] = 6, + [2][1][RTW89_CHILE][1][27] = -16, + [2][1][RTW89_QATAR][1][27] = 44, + [2][1][RTW89_QATAR][0][27] = 6, + [2][1][RTW89_UK][1][27] = 44, + [2][1][RTW89_UK][0][27] = 6, + [2][1][RTW89_THAILAND][1][27] = 28, + [2][1][RTW89_THAILAND][0][27] = -16, + [2][1][RTW89_FCC][1][29] = -16, + [2][1][RTW89_ETSI][1][29] = 44, + [2][1][RTW89_ETSI][0][29] = 6, + [2][1][RTW89_MKK][1][29] = 40, + [2][1][RTW89_MKK][0][29] = 2, + [2][1][RTW89_IC][1][29] = -16, + [2][1][RTW89_KCC][1][29] = -14, + [2][1][RTW89_KCC][0][29] = -14, + [2][1][RTW89_ACMA][1][29] = 44, + [2][1][RTW89_ACMA][0][29] = 6, + [2][1][RTW89_CHILE][1][29] = -16, + [2][1][RTW89_QATAR][1][29] = 44, + [2][1][RTW89_QATAR][0][29] = 6, + [2][1][RTW89_UK][1][29] = 44, + [2][1][RTW89_UK][0][29] = 6, + [2][1][RTW89_THAILAND][1][29] = 28, + [2][1][RTW89_THAILAND][0][29] = -16, + [2][1][RTW89_FCC][1][30] = -16, + [2][1][RTW89_ETSI][1][30] = 44, + [2][1][RTW89_ETSI][0][30] = 6, + [2][1][RTW89_MKK][1][30] = 40, + [2][1][RTW89_MKK][0][30] = 2, + [2][1][RTW89_IC][1][30] = -16, + [2][1][RTW89_KCC][1][30] = -14, + [2][1][RTW89_KCC][0][30] = -14, + [2][1][RTW89_ACMA][1][30] = 44, + [2][1][RTW89_ACMA][0][30] = 6, + [2][1][RTW89_CHILE][1][30] = -16, + [2][1][RTW89_QATAR][1][30] = 44, + [2][1][RTW89_QATAR][0][30] = 6, + [2][1][RTW89_UK][1][30] = 44, + [2][1][RTW89_UK][0][30] = 6, + [2][1][RTW89_THAILAND][1][30] = 28, + [2][1][RTW89_THAILAND][0][30] = -16, + [2][1][RTW89_FCC][1][32] = -16, + [2][1][RTW89_ETSI][1][32] = 44, + [2][1][RTW89_ETSI][0][32] = 6, + [2][1][RTW89_MKK][1][32] = 40, + [2][1][RTW89_MKK][0][32] = 2, + [2][1][RTW89_IC][1][32] = -16, + [2][1][RTW89_KCC][1][32] = -14, + [2][1][RTW89_KCC][0][32] = -14, + [2][1][RTW89_ACMA][1][32] = 44, + [2][1][RTW89_ACMA][0][32] = 6, + [2][1][RTW89_CHILE][1][32] = -16, + [2][1][RTW89_QATAR][1][32] = 44, + [2][1][RTW89_QATAR][0][32] = 6, + [2][1][RTW89_UK][1][32] = 44, + [2][1][RTW89_UK][0][32] = 6, + [2][1][RTW89_THAILAND][1][32] = 28, + [2][1][RTW89_THAILAND][0][32] = -16, + [2][1][RTW89_FCC][1][34] = -16, + [2][1][RTW89_ETSI][1][34] = 44, + [2][1][RTW89_ETSI][0][34] = 6, + [2][1][RTW89_MKK][1][34] = 40, + [2][1][RTW89_MKK][0][34] = 2, + [2][1][RTW89_IC][1][34] = -16, + [2][1][RTW89_KCC][1][34] = -14, + [2][1][RTW89_KCC][0][34] = -14, + [2][1][RTW89_ACMA][1][34] = 44, + [2][1][RTW89_ACMA][0][34] = 6, + [2][1][RTW89_CHILE][1][34] = -16, + [2][1][RTW89_QATAR][1][34] = 44, + [2][1][RTW89_QATAR][0][34] = 6, + [2][1][RTW89_UK][1][34] = 44, + [2][1][RTW89_UK][0][34] = 6, + [2][1][RTW89_THAILAND][1][34] = 28, + [2][1][RTW89_THAILAND][0][34] = -16, + [2][1][RTW89_FCC][1][36] = -16, + [2][1][RTW89_ETSI][1][36] = 44, + [2][1][RTW89_ETSI][0][36] = 6, + [2][1][RTW89_MKK][1][36] = 40, + [2][1][RTW89_MKK][0][36] = 2, + [2][1][RTW89_IC][1][36] = -16, + [2][1][RTW89_KCC][1][36] = -14, + [2][1][RTW89_KCC][0][36] = -14, + [2][1][RTW89_ACMA][1][36] = 44, + [2][1][RTW89_ACMA][0][36] = 6, + [2][1][RTW89_CHILE][1][36] = -16, + [2][1][RTW89_QATAR][1][36] = 44, + [2][1][RTW89_QATAR][0][36] = 6, + [2][1][RTW89_UK][1][36] = 44, + [2][1][RTW89_UK][0][36] = 6, + [2][1][RTW89_THAILAND][1][36] = 28, + [2][1][RTW89_THAILAND][0][36] = -16, + [2][1][RTW89_FCC][1][38] = -16, + [2][1][RTW89_ETSI][1][38] = 44, + [2][1][RTW89_ETSI][0][38] = 6, + [2][1][RTW89_MKK][1][38] = 40, + [2][1][RTW89_MKK][0][38] = 2, + [2][1][RTW89_IC][1][38] = -16, + [2][1][RTW89_KCC][1][38] = -14, + [2][1][RTW89_KCC][0][38] = -14, + [2][1][RTW89_ACMA][1][38] = 44, + [2][1][RTW89_ACMA][0][38] = 6, + [2][1][RTW89_CHILE][1][38] = -16, + [2][1][RTW89_QATAR][1][38] = 44, + [2][1][RTW89_QATAR][0][38] = 6, + [2][1][RTW89_UK][1][38] = 44, + [2][1][RTW89_UK][0][38] = 6, + [2][1][RTW89_THAILAND][1][38] = 28, + [2][1][RTW89_THAILAND][0][38] = -16, + [2][1][RTW89_FCC][1][40] = -16, + [2][1][RTW89_ETSI][1][40] = 44, + [2][1][RTW89_ETSI][0][40] = 6, + [2][1][RTW89_MKK][1][40] = 40, + [2][1][RTW89_MKK][0][40] = 2, + [2][1][RTW89_IC][1][40] = -16, + [2][1][RTW89_KCC][1][40] = -14, + [2][1][RTW89_KCC][0][40] = -14, + [2][1][RTW89_ACMA][1][40] = 44, + [2][1][RTW89_ACMA][0][40] = 6, + [2][1][RTW89_CHILE][1][40] = -16, + [2][1][RTW89_QATAR][1][40] = 44, + [2][1][RTW89_QATAR][0][40] = 6, + [2][1][RTW89_UK][1][40] = 44, + [2][1][RTW89_UK][0][40] = 6, + [2][1][RTW89_THAILAND][1][40] = 28, + [2][1][RTW89_THAILAND][0][40] = -16, + [2][1][RTW89_FCC][1][42] = -16, + [2][1][RTW89_ETSI][1][42] = 44, + [2][1][RTW89_ETSI][0][42] = 6, + [2][1][RTW89_MKK][1][42] = 40, + [2][1][RTW89_MKK][0][42] = 2, + [2][1][RTW89_IC][1][42] = -16, + [2][1][RTW89_KCC][1][42] = -14, + [2][1][RTW89_KCC][0][42] = -14, + [2][1][RTW89_ACMA][1][42] = 44, + [2][1][RTW89_ACMA][0][42] = 6, + [2][1][RTW89_CHILE][1][42] = -16, + [2][1][RTW89_QATAR][1][42] = 44, + [2][1][RTW89_QATAR][0][42] = 6, + [2][1][RTW89_UK][1][42] = 44, + [2][1][RTW89_UK][0][42] = 6, + [2][1][RTW89_THAILAND][1][42] = 28, + [2][1][RTW89_THAILAND][0][42] = -16, + [2][1][RTW89_FCC][1][44] = -16, + [2][1][RTW89_ETSI][1][44] = 44, + [2][1][RTW89_ETSI][0][44] = 6, + [2][1][RTW89_MKK][1][44] = 16, + [2][1][RTW89_MKK][0][44] = 2, + [2][1][RTW89_IC][1][44] = -16, + [2][1][RTW89_KCC][1][44] = -14, + [2][1][RTW89_KCC][0][44] = -14, + [2][1][RTW89_ACMA][1][44] = 44, + [2][1][RTW89_ACMA][0][44] = 6, + [2][1][RTW89_CHILE][1][44] = -16, + [2][1][RTW89_QATAR][1][44] = 44, + [2][1][RTW89_QATAR][0][44] = 6, + [2][1][RTW89_UK][1][44] = 44, + [2][1][RTW89_UK][0][44] = 6, + [2][1][RTW89_THAILAND][1][44] = 28, + [2][1][RTW89_THAILAND][0][44] = -16, + [2][1][RTW89_FCC][1][45] = -16, + [2][1][RTW89_ETSI][1][45] = 127, + [2][1][RTW89_ETSI][0][45] = 127, + [2][1][RTW89_MKK][1][45] = 127, + [2][1][RTW89_MKK][0][45] = 127, + [2][1][RTW89_IC][1][45] = -16, + [2][1][RTW89_KCC][1][45] = -14, + [2][1][RTW89_KCC][0][45] = 127, + [2][1][RTW89_ACMA][1][45] = 127, + [2][1][RTW89_ACMA][0][45] = 127, + [2][1][RTW89_CHILE][1][45] = 127, + [2][1][RTW89_QATAR][1][45] = 127, + [2][1][RTW89_QATAR][0][45] = 127, + [2][1][RTW89_UK][1][45] = 127, + [2][1][RTW89_UK][0][45] = 127, + [2][1][RTW89_THAILAND][1][45] = 127, + [2][1][RTW89_THAILAND][0][45] = 127, + [2][1][RTW89_FCC][1][47] = -16, + [2][1][RTW89_ETSI][1][47] = 127, + [2][1][RTW89_ETSI][0][47] = 127, + [2][1][RTW89_MKK][1][47] = 127, + [2][1][RTW89_MKK][0][47] = 127, + [2][1][RTW89_IC][1][47] = -16, + [2][1][RTW89_KCC][1][47] = -14, + [2][1][RTW89_KCC][0][47] = 127, + [2][1][RTW89_ACMA][1][47] = 127, + [2][1][RTW89_ACMA][0][47] = 127, + [2][1][RTW89_CHILE][1][47] = 127, + [2][1][RTW89_QATAR][1][47] = 127, + [2][1][RTW89_QATAR][0][47] = 127, + [2][1][RTW89_UK][1][47] = 127, + [2][1][RTW89_UK][0][47] = 127, + [2][1][RTW89_THAILAND][1][47] = 127, + [2][1][RTW89_THAILAND][0][47] = 127, + [2][1][RTW89_FCC][1][49] = -16, + [2][1][RTW89_ETSI][1][49] = 127, + [2][1][RTW89_ETSI][0][49] = 127, + [2][1][RTW89_MKK][1][49] = 127, + [2][1][RTW89_MKK][0][49] = 127, + [2][1][RTW89_IC][1][49] = -16, + [2][1][RTW89_KCC][1][49] = -14, + [2][1][RTW89_KCC][0][49] = 127, + [2][1][RTW89_ACMA][1][49] = 127, + [2][1][RTW89_ACMA][0][49] = 127, + [2][1][RTW89_CHILE][1][49] = 127, + [2][1][RTW89_QATAR][1][49] = 127, + [2][1][RTW89_QATAR][0][49] = 127, + [2][1][RTW89_UK][1][49] = 127, + [2][1][RTW89_UK][0][49] = 127, + [2][1][RTW89_THAILAND][1][49] = 127, + [2][1][RTW89_THAILAND][0][49] = 127, + [2][1][RTW89_FCC][1][51] = -16, + [2][1][RTW89_ETSI][1][51] = 127, + [2][1][RTW89_ETSI][0][51] = 127, + [2][1][RTW89_MKK][1][51] = 127, + [2][1][RTW89_MKK][0][51] = 127, + [2][1][RTW89_IC][1][51] = -16, + [2][1][RTW89_KCC][1][51] = -14, + [2][1][RTW89_KCC][0][51] = 127, + [2][1][RTW89_ACMA][1][51] = 127, + [2][1][RTW89_ACMA][0][51] = 127, + [2][1][RTW89_CHILE][1][51] = 127, + [2][1][RTW89_QATAR][1][51] = 127, + [2][1][RTW89_QATAR][0][51] = 127, + [2][1][RTW89_UK][1][51] = 127, + [2][1][RTW89_UK][0][51] = 127, + [2][1][RTW89_THAILAND][1][51] = 127, + [2][1][RTW89_THAILAND][0][51] = 127, + [2][1][RTW89_FCC][1][53] = -16, + [2][1][RTW89_ETSI][1][53] = 127, + [2][1][RTW89_ETSI][0][53] = 127, + [2][1][RTW89_MKK][1][53] = 127, + [2][1][RTW89_MKK][0][53] = 127, + [2][1][RTW89_IC][1][53] = -16, + [2][1][RTW89_KCC][1][53] = -14, + [2][1][RTW89_KCC][0][53] = 127, + [2][1][RTW89_ACMA][1][53] = 127, + [2][1][RTW89_ACMA][0][53] = 127, + [2][1][RTW89_CHILE][1][53] = 127, + [2][1][RTW89_QATAR][1][53] = 127, + [2][1][RTW89_QATAR][0][53] = 127, + [2][1][RTW89_UK][1][53] = 127, + [2][1][RTW89_UK][0][53] = 127, + [2][1][RTW89_THAILAND][1][53] = 127, + [2][1][RTW89_THAILAND][0][53] = 127, + [2][1][RTW89_FCC][1][55] = -16, + [2][1][RTW89_ETSI][1][55] = 127, + [2][1][RTW89_ETSI][0][55] = 127, + [2][1][RTW89_MKK][1][55] = 127, + [2][1][RTW89_MKK][0][55] = 127, + [2][1][RTW89_IC][1][55] = -16, + [2][1][RTW89_KCC][1][55] = -14, + [2][1][RTW89_KCC][0][55] = 127, + [2][1][RTW89_ACMA][1][55] = 127, + [2][1][RTW89_ACMA][0][55] = 127, + [2][1][RTW89_CHILE][1][55] = 127, + [2][1][RTW89_QATAR][1][55] = 127, + [2][1][RTW89_QATAR][0][55] = 127, + [2][1][RTW89_UK][1][55] = 127, + [2][1][RTW89_UK][0][55] = 127, + [2][1][RTW89_THAILAND][1][55] = 127, + [2][1][RTW89_THAILAND][0][55] = 127, + [2][1][RTW89_FCC][1][57] = -16, + [2][1][RTW89_ETSI][1][57] = 127, + [2][1][RTW89_ETSI][0][57] = 127, + [2][1][RTW89_MKK][1][57] = 127, + [2][1][RTW89_MKK][0][57] = 127, + [2][1][RTW89_IC][1][57] = -16, + [2][1][RTW89_KCC][1][57] = -14, + [2][1][RTW89_KCC][0][57] = 127, + [2][1][RTW89_ACMA][1][57] = 127, + [2][1][RTW89_ACMA][0][57] = 127, + [2][1][RTW89_CHILE][1][57] = 127, + [2][1][RTW89_QATAR][1][57] = 127, + [2][1][RTW89_QATAR][0][57] = 127, + [2][1][RTW89_UK][1][57] = 127, + [2][1][RTW89_UK][0][57] = 127, + [2][1][RTW89_THAILAND][1][57] = 127, + [2][1][RTW89_THAILAND][0][57] = 127, + [2][1][RTW89_FCC][1][59] = -16, + [2][1][RTW89_ETSI][1][59] = 127, + [2][1][RTW89_ETSI][0][59] = 127, + [2][1][RTW89_MKK][1][59] = 127, + [2][1][RTW89_MKK][0][59] = 127, + [2][1][RTW89_IC][1][59] = -16, + [2][1][RTW89_KCC][1][59] = -14, + [2][1][RTW89_KCC][0][59] = 127, + [2][1][RTW89_ACMA][1][59] = 127, + [2][1][RTW89_ACMA][0][59] = 127, + [2][1][RTW89_CHILE][1][59] = 127, + [2][1][RTW89_QATAR][1][59] = 127, + [2][1][RTW89_QATAR][0][59] = 127, + [2][1][RTW89_UK][1][59] = 127, + [2][1][RTW89_UK][0][59] = 127, + [2][1][RTW89_THAILAND][1][59] = 127, + [2][1][RTW89_THAILAND][0][59] = 127, + [2][1][RTW89_FCC][1][60] = -16, + [2][1][RTW89_ETSI][1][60] = 127, + [2][1][RTW89_ETSI][0][60] = 127, + [2][1][RTW89_MKK][1][60] = 127, + [2][1][RTW89_MKK][0][60] = 127, + [2][1][RTW89_IC][1][60] = -16, + [2][1][RTW89_KCC][1][60] = -14, + [2][1][RTW89_KCC][0][60] = 127, + [2][1][RTW89_ACMA][1][60] = 127, + [2][1][RTW89_ACMA][0][60] = 127, + [2][1][RTW89_CHILE][1][60] = 127, + [2][1][RTW89_QATAR][1][60] = 127, + [2][1][RTW89_QATAR][0][60] = 127, + [2][1][RTW89_UK][1][60] = 127, + [2][1][RTW89_UK][0][60] = 127, + [2][1][RTW89_THAILAND][1][60] = 127, + [2][1][RTW89_THAILAND][0][60] = 127, + [2][1][RTW89_FCC][1][62] = -16, + [2][1][RTW89_ETSI][1][62] = 127, + [2][1][RTW89_ETSI][0][62] = 127, + [2][1][RTW89_MKK][1][62] = 127, + [2][1][RTW89_MKK][0][62] = 127, + [2][1][RTW89_IC][1][62] = -16, + [2][1][RTW89_KCC][1][62] = -14, + [2][1][RTW89_KCC][0][62] = 127, + [2][1][RTW89_ACMA][1][62] = 127, + [2][1][RTW89_ACMA][0][62] = 127, + [2][1][RTW89_CHILE][1][62] = 127, + [2][1][RTW89_QATAR][1][62] = 127, + [2][1][RTW89_QATAR][0][62] = 127, + [2][1][RTW89_UK][1][62] = 127, + [2][1][RTW89_UK][0][62] = 127, + [2][1][RTW89_THAILAND][1][62] = 127, + [2][1][RTW89_THAILAND][0][62] = 127, + [2][1][RTW89_FCC][1][64] = -16, + [2][1][RTW89_ETSI][1][64] = 127, + [2][1][RTW89_ETSI][0][64] = 127, + [2][1][RTW89_MKK][1][64] = 127, + [2][1][RTW89_MKK][0][64] = 127, + [2][1][RTW89_IC][1][64] = -16, + [2][1][RTW89_KCC][1][64] = -14, + [2][1][RTW89_KCC][0][64] = 127, + [2][1][RTW89_ACMA][1][64] = 127, + [2][1][RTW89_ACMA][0][64] = 127, + [2][1][RTW89_CHILE][1][64] = 127, + [2][1][RTW89_QATAR][1][64] = 127, + [2][1][RTW89_QATAR][0][64] = 127, + [2][1][RTW89_UK][1][64] = 127, + [2][1][RTW89_UK][0][64] = 127, + [2][1][RTW89_THAILAND][1][64] = 127, + [2][1][RTW89_THAILAND][0][64] = 127, + [2][1][RTW89_FCC][1][66] = -16, + [2][1][RTW89_ETSI][1][66] = 127, + [2][1][RTW89_ETSI][0][66] = 127, + [2][1][RTW89_MKK][1][66] = 127, + [2][1][RTW89_MKK][0][66] = 127, + [2][1][RTW89_IC][1][66] = -16, + [2][1][RTW89_KCC][1][66] = -14, + [2][1][RTW89_KCC][0][66] = 127, + [2][1][RTW89_ACMA][1][66] = 127, + [2][1][RTW89_ACMA][0][66] = 127, + [2][1][RTW89_CHILE][1][66] = 127, + [2][1][RTW89_QATAR][1][66] = 127, + [2][1][RTW89_QATAR][0][66] = 127, + [2][1][RTW89_UK][1][66] = 127, + [2][1][RTW89_UK][0][66] = 127, + [2][1][RTW89_THAILAND][1][66] = 127, + [2][1][RTW89_THAILAND][0][66] = 127, + [2][1][RTW89_FCC][1][68] = -16, + [2][1][RTW89_ETSI][1][68] = 127, + [2][1][RTW89_ETSI][0][68] = 127, + [2][1][RTW89_MKK][1][68] = 127, + [2][1][RTW89_MKK][0][68] = 127, + [2][1][RTW89_IC][1][68] = -16, + [2][1][RTW89_KCC][1][68] = -14, + [2][1][RTW89_KCC][0][68] = 127, + [2][1][RTW89_ACMA][1][68] = 127, + [2][1][RTW89_ACMA][0][68] = 127, + [2][1][RTW89_CHILE][1][68] = 127, + [2][1][RTW89_QATAR][1][68] = 127, + [2][1][RTW89_QATAR][0][68] = 127, + [2][1][RTW89_UK][1][68] = 127, + [2][1][RTW89_UK][0][68] = 127, + [2][1][RTW89_THAILAND][1][68] = 127, + [2][1][RTW89_THAILAND][0][68] = 127, + [2][1][RTW89_FCC][1][70] = -16, + [2][1][RTW89_ETSI][1][70] = 127, + [2][1][RTW89_ETSI][0][70] = 127, + [2][1][RTW89_MKK][1][70] = 127, + [2][1][RTW89_MKK][0][70] = 127, + [2][1][RTW89_IC][1][70] = -16, + [2][1][RTW89_KCC][1][70] = -14, + [2][1][RTW89_KCC][0][70] = 127, + [2][1][RTW89_ACMA][1][70] = 127, + [2][1][RTW89_ACMA][0][70] = 127, + [2][1][RTW89_CHILE][1][70] = 127, + [2][1][RTW89_QATAR][1][70] = 127, + [2][1][RTW89_QATAR][0][70] = 127, + [2][1][RTW89_UK][1][70] = 127, + [2][1][RTW89_UK][0][70] = 127, + [2][1][RTW89_THAILAND][1][70] = 127, + [2][1][RTW89_THAILAND][0][70] = 127, + [2][1][RTW89_FCC][1][72] = -16, + [2][1][RTW89_ETSI][1][72] = 127, + [2][1][RTW89_ETSI][0][72] = 127, + [2][1][RTW89_MKK][1][72] = 127, + [2][1][RTW89_MKK][0][72] = 127, + [2][1][RTW89_IC][1][72] = -16, + [2][1][RTW89_KCC][1][72] = -14, + [2][1][RTW89_KCC][0][72] = 127, + [2][1][RTW89_ACMA][1][72] = 127, + [2][1][RTW89_ACMA][0][72] = 127, + [2][1][RTW89_CHILE][1][72] = 127, + [2][1][RTW89_QATAR][1][72] = 127, + [2][1][RTW89_QATAR][0][72] = 127, + [2][1][RTW89_UK][1][72] = 127, + [2][1][RTW89_UK][0][72] = 127, + [2][1][RTW89_THAILAND][1][72] = 127, + [2][1][RTW89_THAILAND][0][72] = 127, + [2][1][RTW89_FCC][1][74] = -16, + [2][1][RTW89_ETSI][1][74] = 127, + [2][1][RTW89_ETSI][0][74] = 127, + [2][1][RTW89_MKK][1][74] = 127, + [2][1][RTW89_MKK][0][74] = 127, + [2][1][RTW89_IC][1][74] = -16, + [2][1][RTW89_KCC][1][74] = -14, + [2][1][RTW89_KCC][0][74] = 127, + [2][1][RTW89_ACMA][1][74] = 127, + [2][1][RTW89_ACMA][0][74] = 127, + [2][1][RTW89_CHILE][1][74] = 127, + [2][1][RTW89_QATAR][1][74] = 127, + [2][1][RTW89_QATAR][0][74] = 127, + [2][1][RTW89_UK][1][74] = 127, + [2][1][RTW89_UK][0][74] = 127, + [2][1][RTW89_THAILAND][1][74] = 127, + [2][1][RTW89_THAILAND][0][74] = 127, + [2][1][RTW89_FCC][1][75] = -16, + [2][1][RTW89_ETSI][1][75] = 127, + [2][1][RTW89_ETSI][0][75] = 127, + [2][1][RTW89_MKK][1][75] = 127, + [2][1][RTW89_MKK][0][75] = 127, + [2][1][RTW89_IC][1][75] = -16, + [2][1][RTW89_KCC][1][75] = -14, + [2][1][RTW89_KCC][0][75] = 127, + [2][1][RTW89_ACMA][1][75] = 127, + [2][1][RTW89_ACMA][0][75] = 127, + [2][1][RTW89_CHILE][1][75] = 127, + [2][1][RTW89_QATAR][1][75] = 127, + [2][1][RTW89_QATAR][0][75] = 127, + [2][1][RTW89_UK][1][75] = 127, + [2][1][RTW89_UK][0][75] = 127, + [2][1][RTW89_THAILAND][1][75] = 127, + [2][1][RTW89_THAILAND][0][75] = 127, + [2][1][RTW89_FCC][1][77] = -16, + [2][1][RTW89_ETSI][1][77] = 127, + [2][1][RTW89_ETSI][0][77] = 127, + [2][1][RTW89_MKK][1][77] = 127, + [2][1][RTW89_MKK][0][77] = 127, + [2][1][RTW89_IC][1][77] = -16, + [2][1][RTW89_KCC][1][77] = -14, + [2][1][RTW89_KCC][0][77] = 127, + [2][1][RTW89_ACMA][1][77] = 127, + [2][1][RTW89_ACMA][0][77] = 127, + [2][1][RTW89_CHILE][1][77] = 127, + [2][1][RTW89_QATAR][1][77] = 127, + [2][1][RTW89_QATAR][0][77] = 127, + [2][1][RTW89_UK][1][77] = 127, + [2][1][RTW89_UK][0][77] = 127, + [2][1][RTW89_THAILAND][1][77] = 127, + [2][1][RTW89_THAILAND][0][77] = 127, + [2][1][RTW89_FCC][1][79] = -16, + [2][1][RTW89_ETSI][1][79] = 127, + [2][1][RTW89_ETSI][0][79] = 127, + [2][1][RTW89_MKK][1][79] = 127, + [2][1][RTW89_MKK][0][79] = 127, + [2][1][RTW89_IC][1][79] = -16, + [2][1][RTW89_KCC][1][79] = -14, + [2][1][RTW89_KCC][0][79] = 127, + [2][1][RTW89_ACMA][1][79] = 127, + [2][1][RTW89_ACMA][0][79] = 127, + [2][1][RTW89_CHILE][1][79] = 127, + [2][1][RTW89_QATAR][1][79] = 127, + [2][1][RTW89_QATAR][0][79] = 127, + [2][1][RTW89_UK][1][79] = 127, + [2][1][RTW89_UK][0][79] = 127, + [2][1][RTW89_THAILAND][1][79] = 127, + [2][1][RTW89_THAILAND][0][79] = 127, + [2][1][RTW89_FCC][1][81] = -16, + [2][1][RTW89_ETSI][1][81] = 127, + [2][1][RTW89_ETSI][0][81] = 127, + [2][1][RTW89_MKK][1][81] = 127, + [2][1][RTW89_MKK][0][81] = 127, + [2][1][RTW89_IC][1][81] = -16, + [2][1][RTW89_KCC][1][81] = -14, + [2][1][RTW89_KCC][0][81] = 127, + [2][1][RTW89_ACMA][1][81] = 127, + [2][1][RTW89_ACMA][0][81] = 127, + [2][1][RTW89_CHILE][1][81] = 127, + [2][1][RTW89_QATAR][1][81] = 127, + [2][1][RTW89_QATAR][0][81] = 127, + [2][1][RTW89_UK][1][81] = 127, + [2][1][RTW89_UK][0][81] = 127, + [2][1][RTW89_THAILAND][1][81] = 127, + [2][1][RTW89_THAILAND][0][81] = 127, + [2][1][RTW89_FCC][1][83] = -16, + [2][1][RTW89_ETSI][1][83] = 127, + [2][1][RTW89_ETSI][0][83] = 127, + [2][1][RTW89_MKK][1][83] = 127, + [2][1][RTW89_MKK][0][83] = 127, + [2][1][RTW89_IC][1][83] = -16, + [2][1][RTW89_KCC][1][83] = -14, + [2][1][RTW89_KCC][0][83] = 127, + [2][1][RTW89_ACMA][1][83] = 127, + [2][1][RTW89_ACMA][0][83] = 127, + [2][1][RTW89_CHILE][1][83] = 127, + [2][1][RTW89_QATAR][1][83] = 127, + [2][1][RTW89_QATAR][0][83] = 127, + [2][1][RTW89_UK][1][83] = 127, + [2][1][RTW89_UK][0][83] = 127, + [2][1][RTW89_THAILAND][1][83] = 127, + [2][1][RTW89_THAILAND][0][83] = 127, + [2][1][RTW89_FCC][1][85] = -18, + [2][1][RTW89_ETSI][1][85] = 127, + [2][1][RTW89_ETSI][0][85] = 127, + [2][1][RTW89_MKK][1][85] = 127, + [2][1][RTW89_MKK][0][85] = 127, + [2][1][RTW89_IC][1][85] = -18, + [2][1][RTW89_KCC][1][85] = -14, + [2][1][RTW89_KCC][0][85] = 127, + [2][1][RTW89_ACMA][1][85] = 127, + [2][1][RTW89_ACMA][0][85] = 127, + [2][1][RTW89_CHILE][1][85] = 127, + [2][1][RTW89_QATAR][1][85] = 127, + [2][1][RTW89_QATAR][0][85] = 127, + [2][1][RTW89_UK][1][85] = 127, + [2][1][RTW89_UK][0][85] = 127, + [2][1][RTW89_THAILAND][1][85] = 127, + [2][1][RTW89_THAILAND][0][85] = 127, + [2][1][RTW89_FCC][1][87] = -16, + [2][1][RTW89_ETSI][1][87] = 127, + [2][1][RTW89_ETSI][0][87] = 127, + [2][1][RTW89_MKK][1][87] = 127, + [2][1][RTW89_MKK][0][87] = 127, + [2][1][RTW89_IC][1][87] = -16, + [2][1][RTW89_KCC][1][87] = -14, + [2][1][RTW89_KCC][0][87] = 127, + [2][1][RTW89_ACMA][1][87] = 127, + [2][1][RTW89_ACMA][0][87] = 127, + [2][1][RTW89_CHILE][1][87] = 127, + [2][1][RTW89_QATAR][1][87] = 127, + [2][1][RTW89_QATAR][0][87] = 127, + [2][1][RTW89_UK][1][87] = 127, + [2][1][RTW89_UK][0][87] = 127, + [2][1][RTW89_THAILAND][1][87] = 127, + [2][1][RTW89_THAILAND][0][87] = 127, + [2][1][RTW89_FCC][1][89] = -16, + [2][1][RTW89_ETSI][1][89] = 127, + [2][1][RTW89_ETSI][0][89] = 127, + [2][1][RTW89_MKK][1][89] = 127, + [2][1][RTW89_MKK][0][89] = 127, + [2][1][RTW89_IC][1][89] = -16, + [2][1][RTW89_KCC][1][89] = -14, + [2][1][RTW89_KCC][0][89] = 127, + [2][1][RTW89_ACMA][1][89] = 127, + [2][1][RTW89_ACMA][0][89] = 127, + [2][1][RTW89_CHILE][1][89] = 127, + [2][1][RTW89_QATAR][1][89] = 127, + [2][1][RTW89_QATAR][0][89] = 127, + [2][1][RTW89_UK][1][89] = 127, + [2][1][RTW89_UK][0][89] = 127, + [2][1][RTW89_THAILAND][1][89] = 127, + [2][1][RTW89_THAILAND][0][89] = 127, + [2][1][RTW89_FCC][1][90] = -16, + [2][1][RTW89_ETSI][1][90] = 127, + [2][1][RTW89_ETSI][0][90] = 127, + [2][1][RTW89_MKK][1][90] = 127, + [2][1][RTW89_MKK][0][90] = 127, + [2][1][RTW89_IC][1][90] = -16, + [2][1][RTW89_KCC][1][90] = -14, + [2][1][RTW89_KCC][0][90] = 127, + [2][1][RTW89_ACMA][1][90] = 127, + [2][1][RTW89_ACMA][0][90] = 127, + [2][1][RTW89_CHILE][1][90] = 127, + [2][1][RTW89_QATAR][1][90] = 127, + [2][1][RTW89_QATAR][0][90] = 127, + [2][1][RTW89_UK][1][90] = 127, + [2][1][RTW89_UK][0][90] = 127, + [2][1][RTW89_THAILAND][1][90] = 127, + [2][1][RTW89_THAILAND][0][90] = 127, + [2][1][RTW89_FCC][1][92] = -16, + [2][1][RTW89_ETSI][1][92] = 127, + [2][1][RTW89_ETSI][0][92] = 127, + [2][1][RTW89_MKK][1][92] = 127, + [2][1][RTW89_MKK][0][92] = 127, + [2][1][RTW89_IC][1][92] = -16, + [2][1][RTW89_KCC][1][92] = -14, + [2][1][RTW89_KCC][0][92] = 127, + [2][1][RTW89_ACMA][1][92] = 127, + [2][1][RTW89_ACMA][0][92] = 127, + [2][1][RTW89_CHILE][1][92] = 127, + [2][1][RTW89_QATAR][1][92] = 127, + [2][1][RTW89_QATAR][0][92] = 127, + [2][1][RTW89_UK][1][92] = 127, + [2][1][RTW89_UK][0][92] = 127, + [2][1][RTW89_THAILAND][1][92] = 127, + [2][1][RTW89_THAILAND][0][92] = 127, + [2][1][RTW89_FCC][1][94] = -16, + [2][1][RTW89_ETSI][1][94] = 127, + [2][1][RTW89_ETSI][0][94] = 127, + [2][1][RTW89_MKK][1][94] = 127, + [2][1][RTW89_MKK][0][94] = 127, + [2][1][RTW89_IC][1][94] = -16, + [2][1][RTW89_KCC][1][94] = -14, + [2][1][RTW89_KCC][0][94] = 127, + [2][1][RTW89_ACMA][1][94] = 127, + [2][1][RTW89_ACMA][0][94] = 127, + [2][1][RTW89_CHILE][1][94] = 127, + [2][1][RTW89_QATAR][1][94] = 127, + [2][1][RTW89_QATAR][0][94] = 127, + [2][1][RTW89_UK][1][94] = 127, + [2][1][RTW89_UK][0][94] = 127, + [2][1][RTW89_THAILAND][1][94] = 127, + [2][1][RTW89_THAILAND][0][94] = 127, + [2][1][RTW89_FCC][1][96] = -16, + [2][1][RTW89_ETSI][1][96] = 127, + [2][1][RTW89_ETSI][0][96] = 127, + [2][1][RTW89_MKK][1][96] = 127, + [2][1][RTW89_MKK][0][96] = 127, + [2][1][RTW89_IC][1][96] = -16, + [2][1][RTW89_KCC][1][96] = -14, + [2][1][RTW89_KCC][0][96] = 127, + [2][1][RTW89_ACMA][1][96] = 127, + [2][1][RTW89_ACMA][0][96] = 127, + [2][1][RTW89_CHILE][1][96] = 127, + [2][1][RTW89_QATAR][1][96] = 127, + [2][1][RTW89_QATAR][0][96] = 127, + [2][1][RTW89_UK][1][96] = 127, + [2][1][RTW89_UK][0][96] = 127, + [2][1][RTW89_THAILAND][1][96] = 127, + [2][1][RTW89_THAILAND][0][96] = 127, + [2][1][RTW89_FCC][1][98] = -16, + [2][1][RTW89_ETSI][1][98] = 127, + [2][1][RTW89_ETSI][0][98] = 127, + [2][1][RTW89_MKK][1][98] = 127, + [2][1][RTW89_MKK][0][98] = 127, + [2][1][RTW89_IC][1][98] = -16, + [2][1][RTW89_KCC][1][98] = -14, + [2][1][RTW89_KCC][0][98] = 127, + [2][1][RTW89_ACMA][1][98] = 127, + [2][1][RTW89_ACMA][0][98] = 127, + [2][1][RTW89_CHILE][1][98] = 127, + [2][1][RTW89_QATAR][1][98] = 127, + [2][1][RTW89_QATAR][0][98] = 127, + [2][1][RTW89_UK][1][98] = 127, + [2][1][RTW89_UK][0][98] = 127, + [2][1][RTW89_THAILAND][1][98] = 127, + [2][1][RTW89_THAILAND][0][98] = 127, + [2][1][RTW89_FCC][1][100] = -16, + [2][1][RTW89_ETSI][1][100] = 127, + [2][1][RTW89_ETSI][0][100] = 127, + [2][1][RTW89_MKK][1][100] = 127, + [2][1][RTW89_MKK][0][100] = 127, + [2][1][RTW89_IC][1][100] = -16, + [2][1][RTW89_KCC][1][100] = -14, + [2][1][RTW89_KCC][0][100] = 127, + [2][1][RTW89_ACMA][1][100] = 127, + [2][1][RTW89_ACMA][0][100] = 127, + [2][1][RTW89_CHILE][1][100] = 127, + [2][1][RTW89_QATAR][1][100] = 127, + [2][1][RTW89_QATAR][0][100] = 127, + [2][1][RTW89_UK][1][100] = 127, + [2][1][RTW89_UK][0][100] = 127, + [2][1][RTW89_THAILAND][1][100] = 127, + [2][1][RTW89_THAILAND][0][100] = 127, + [2][1][RTW89_FCC][1][102] = -16, + [2][1][RTW89_ETSI][1][102] = 127, + [2][1][RTW89_ETSI][0][102] = 127, + [2][1][RTW89_MKK][1][102] = 127, + [2][1][RTW89_MKK][0][102] = 127, + [2][1][RTW89_IC][1][102] = -16, + [2][1][RTW89_KCC][1][102] = -14, + [2][1][RTW89_KCC][0][102] = 127, + [2][1][RTW89_ACMA][1][102] = 127, + [2][1][RTW89_ACMA][0][102] = 127, + [2][1][RTW89_CHILE][1][102] = 127, + [2][1][RTW89_QATAR][1][102] = 127, + [2][1][RTW89_QATAR][0][102] = 127, + [2][1][RTW89_UK][1][102] = 127, + [2][1][RTW89_UK][0][102] = 127, + [2][1][RTW89_THAILAND][1][102] = 127, + [2][1][RTW89_THAILAND][0][102] = 127, + [2][1][RTW89_FCC][1][104] = -16, + [2][1][RTW89_ETSI][1][104] = 127, + [2][1][RTW89_ETSI][0][104] = 127, + [2][1][RTW89_MKK][1][104] = 127, + [2][1][RTW89_MKK][0][104] = 127, + [2][1][RTW89_IC][1][104] = -16, + [2][1][RTW89_KCC][1][104] = -14, + [2][1][RTW89_KCC][0][104] = 127, + [2][1][RTW89_ACMA][1][104] = 127, + [2][1][RTW89_ACMA][0][104] = 127, + [2][1][RTW89_CHILE][1][104] = 127, + [2][1][RTW89_QATAR][1][104] = 127, + [2][1][RTW89_QATAR][0][104] = 127, + [2][1][RTW89_UK][1][104] = 127, + [2][1][RTW89_UK][0][104] = 127, + [2][1][RTW89_THAILAND][1][104] = 127, + [2][1][RTW89_THAILAND][0][104] = 127, + [2][1][RTW89_FCC][1][105] = -16, + [2][1][RTW89_ETSI][1][105] = 127, + [2][1][RTW89_ETSI][0][105] = 127, + [2][1][RTW89_MKK][1][105] = 127, + [2][1][RTW89_MKK][0][105] = 127, + [2][1][RTW89_IC][1][105] = -16, + [2][1][RTW89_KCC][1][105] = -14, + [2][1][RTW89_KCC][0][105] = 127, + [2][1][RTW89_ACMA][1][105] = 127, + [2][1][RTW89_ACMA][0][105] = 127, + [2][1][RTW89_CHILE][1][105] = 127, + [2][1][RTW89_QATAR][1][105] = 127, + [2][1][RTW89_QATAR][0][105] = 127, + [2][1][RTW89_UK][1][105] = 127, + [2][1][RTW89_UK][0][105] = 127, + [2][1][RTW89_THAILAND][1][105] = 127, + [2][1][RTW89_THAILAND][0][105] = 127, + [2][1][RTW89_FCC][1][107] = -12, + [2][1][RTW89_ETSI][1][107] = 127, + [2][1][RTW89_ETSI][0][107] = 127, + [2][1][RTW89_MKK][1][107] = 127, + [2][1][RTW89_MKK][0][107] = 127, + [2][1][RTW89_IC][1][107] = -12, + [2][1][RTW89_KCC][1][107] = -14, + [2][1][RTW89_KCC][0][107] = 127, + [2][1][RTW89_ACMA][1][107] = 127, + [2][1][RTW89_ACMA][0][107] = 127, + [2][1][RTW89_CHILE][1][107] = 127, + [2][1][RTW89_QATAR][1][107] = 127, + [2][1][RTW89_QATAR][0][107] = 127, + [2][1][RTW89_UK][1][107] = 127, + [2][1][RTW89_UK][0][107] = 127, + [2][1][RTW89_THAILAND][1][107] = 127, + [2][1][RTW89_THAILAND][0][107] = 127, + [2][1][RTW89_FCC][1][109] = -10, + [2][1][RTW89_ETSI][1][109] = 127, + [2][1][RTW89_ETSI][0][109] = 127, + [2][1][RTW89_MKK][1][109] = 127, + [2][1][RTW89_MKK][0][109] = 127, + [2][1][RTW89_IC][1][109] = -10, + [2][1][RTW89_KCC][1][109] = 127, + [2][1][RTW89_KCC][0][109] = 127, + [2][1][RTW89_ACMA][1][109] = 127, + [2][1][RTW89_ACMA][0][109] = 127, + [2][1][RTW89_CHILE][1][109] = 127, + [2][1][RTW89_QATAR][1][109] = 127, + [2][1][RTW89_QATAR][0][109] = 127, + [2][1][RTW89_UK][1][109] = 127, + [2][1][RTW89_UK][0][109] = 127, + [2][1][RTW89_THAILAND][1][109] = 127, + [2][1][RTW89_THAILAND][0][109] = 127, + [2][1][RTW89_FCC][1][111] = 127, + [2][1][RTW89_ETSI][1][111] = 127, + [2][1][RTW89_ETSI][0][111] = 127, + [2][1][RTW89_MKK][1][111] = 127, + [2][1][RTW89_MKK][0][111] = 127, + [2][1][RTW89_IC][1][111] = 127, + [2][1][RTW89_KCC][1][111] = 127, + [2][1][RTW89_KCC][0][111] = 127, + [2][1][RTW89_ACMA][1][111] = 127, + [2][1][RTW89_ACMA][0][111] = 127, + [2][1][RTW89_CHILE][1][111] = 127, + [2][1][RTW89_QATAR][1][111] = 127, + [2][1][RTW89_QATAR][0][111] = 127, + [2][1][RTW89_UK][1][111] = 127, + [2][1][RTW89_UK][0][111] = 127, + [2][1][RTW89_THAILAND][1][111] = 127, + [2][1][RTW89_THAILAND][0][111] = 127, + [2][1][RTW89_FCC][1][113] = 127, + [2][1][RTW89_ETSI][1][113] = 127, + [2][1][RTW89_ETSI][0][113] = 127, + [2][1][RTW89_MKK][1][113] = 127, + [2][1][RTW89_MKK][0][113] = 127, + [2][1][RTW89_IC][1][113] = 127, + [2][1][RTW89_KCC][1][113] = 127, + [2][1][RTW89_KCC][0][113] = 127, + [2][1][RTW89_ACMA][1][113] = 127, + [2][1][RTW89_ACMA][0][113] = 127, + [2][1][RTW89_CHILE][1][113] = 127, + [2][1][RTW89_QATAR][1][113] = 127, + [2][1][RTW89_QATAR][0][113] = 127, + [2][1][RTW89_UK][1][113] = 127, + [2][1][RTW89_UK][0][113] = 127, + [2][1][RTW89_THAILAND][1][113] = 127, + [2][1][RTW89_THAILAND][0][113] = 127, + [2][1][RTW89_FCC][1][115] = 127, + [2][1][RTW89_ETSI][1][115] = 127, + [2][1][RTW89_ETSI][0][115] = 127, + [2][1][RTW89_MKK][1][115] = 127, + [2][1][RTW89_MKK][0][115] = 127, + [2][1][RTW89_IC][1][115] = 127, + [2][1][RTW89_KCC][1][115] = 127, + [2][1][RTW89_KCC][0][115] = 127, + [2][1][RTW89_ACMA][1][115] = 127, + [2][1][RTW89_ACMA][0][115] = 127, + [2][1][RTW89_CHILE][1][115] = 127, + [2][1][RTW89_QATAR][1][115] = 127, + [2][1][RTW89_QATAR][0][115] = 127, + [2][1][RTW89_UK][1][115] = 127, + [2][1][RTW89_UK][0][115] = 127, + [2][1][RTW89_THAILAND][1][115] = 127, + [2][1][RTW89_THAILAND][0][115] = 127, + [2][1][RTW89_FCC][1][117] = 127, + [2][1][RTW89_ETSI][1][117] = 127, + [2][1][RTW89_ETSI][0][117] = 127, + [2][1][RTW89_MKK][1][117] = 127, + [2][1][RTW89_MKK][0][117] = 127, + [2][1][RTW89_IC][1][117] = 127, + [2][1][RTW89_KCC][1][117] = 127, + [2][1][RTW89_KCC][0][117] = 127, + [2][1][RTW89_ACMA][1][117] = 127, + [2][1][RTW89_ACMA][0][117] = 127, + [2][1][RTW89_CHILE][1][117] = 127, + [2][1][RTW89_QATAR][1][117] = 127, + [2][1][RTW89_QATAR][0][117] = 127, + [2][1][RTW89_UK][1][117] = 127, + [2][1][RTW89_UK][0][117] = 127, + [2][1][RTW89_THAILAND][1][117] = 127, + [2][1][RTW89_THAILAND][0][117] = 127, + [2][1][RTW89_FCC][1][119] = 127, + [2][1][RTW89_ETSI][1][119] = 127, + [2][1][RTW89_ETSI][0][119] = 127, + [2][1][RTW89_MKK][1][119] = 127, + [2][1][RTW89_MKK][0][119] = 127, + [2][1][RTW89_IC][1][119] = 127, + [2][1][RTW89_KCC][1][119] = 127, + [2][1][RTW89_KCC][0][119] = 127, + [2][1][RTW89_ACMA][1][119] = 127, + [2][1][RTW89_ACMA][0][119] = 127, + [2][1][RTW89_CHILE][1][119] = 127, + [2][1][RTW89_QATAR][1][119] = 127, + [2][1][RTW89_QATAR][0][119] = 127, + [2][1][RTW89_UK][1][119] = 127, + [2][1][RTW89_UK][0][119] = 127, + [2][1][RTW89_THAILAND][1][119] = 127, + [2][1][RTW89_THAILAND][0][119] = 127, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_bb_table = { + .regs = rtw89_8852c_phy_bb_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_bb_regs), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table = { + .regs = rtw89_8852c_phy_bb_reg_gain, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_bb_reg_gain), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852c_phy_radioa_table = { + .regs = rtw89_8852c_phy_radioa_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_radioa_regs), + .rf_path = RF_PATH_A, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_radiob_table = { + .regs = rtw89_8852c_phy_radiob_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_radiob_regs), + .rf_path = RF_PATH_B, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_nctl_table = { + .regs = rtw89_8852c_phy_nctl_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_nctl_regs), + .rf_path = 0, /* don't care */ +}; + +static +const struct rtw89_txpwr_table rtw89_8852c_byr_table = { + .data = rtw89_8852c_txpwr_byrate, + .size = ARRAY_SIZE(rtw89_8852c_txpwr_byrate), + .load = rtw89_phy_load_txpwr_byrate, +}; + +const struct rtw89_fw_txpwr_track_cfg rtw89_8852c_trk_cfg = { + .delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N] = _txpwr_track_delta_swingidx_6gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P] = _txpwr_track_delta_swingidx_6gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N] = _txpwr_track_delta_swingidx_6ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P] = _txpwr_track_delta_swingidx_6ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N] = _txpwr_track_delta_swingidx_5gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P] = _txpwr_track_delta_swingidx_5gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N] = _txpwr_track_delta_swingidx_5ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P] = _txpwr_track_delta_swingidx_5ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N] = &_txpwr_track_delta_swingidx_2gb_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P] = &_txpwr_track_delta_swingidx_2gb_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N] = &_txpwr_track_delta_swingidx_2ga_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P] = &_txpwr_track_delta_swingidx_2ga_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N] = &_txpwr_track_delta_swingidx_2g_cck_b_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P] = &_txpwr_track_delta_swingidx_2g_cck_b_p, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N] = &_txpwr_track_delta_swingidx_2g_cck_a_n, + .delta[RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P] = &_txpwr_track_delta_swingidx_2g_cck_a_p, +}; + +const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table = { + .data[RTW89_TSSI_BANDEDGE_FLAT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .data[RTW89_TSSI_BANDEDGE_LOW] = {0x1d, 0x1d, 0x1d, 0x2f, 0xf, 0xf, 0x2f, 0x38, + 0x28, 0x18, 0x8, 0x8, 0x18, 0x28, 0x38}, + .data[RTW89_TSSI_BANDEDGE_MID] = {0x24, 0x24, 0x24, 0x3b, 0x13, 0x13, 0x3b, 0x46, + 0x32, 0x1e, 0xa, 0xa, 0x1e, 0x32, 0x46}, + .data[RTW89_TSSI_BANDEDGE_HIGH] = {0x2a, 0x2a, 0x2a, 0x46, 0x17, 0x17, 0x46, 0x53, + 0x3b, 0x24, 0xc, 0xc, 0x24, 0x3b, 0x53}, +}; + +const struct rtw89_rfe_parms rtw89_8852c_dflt_parms = { + .byr_tbl = &rtw89_8852c_byr_table, + .rule_2ghz = { + .lmt = &rtw89_8852c_txpwr_lmt_2g, + .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_2g, + }, + .rule_5ghz = { + .lmt = &rtw89_8852c_txpwr_lmt_5g, + .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_5g, + }, + .rule_6ghz = { + .lmt = &rtw89_8852c_txpwr_lmt_6g, + .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_6g, + }, + .tx_shape = { + .lmt_v0 = &rtw89_8852c_tx_shape_lmt, + .lmt_ru_v0 = &rtw89_8852c_tx_shape_lmt_ru, + }, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h new file mode 100644 index 000000000..69c95f35b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_TABLE_H__ +#define __RTW89_8852C_TABLE_H__ + +#include "core.h" + +extern const struct rtw89_phy_table rtw89_8852c_phy_bb_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table; +extern const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table; +extern const struct rtw89_fw_txpwr_track_cfg rtw89_8852c_trk_cfg; +extern const struct rtw89_rfe_parms rtw89_8852c_dflt_parms; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c new file mode 100644 index 000000000..daff152f6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2020-2022 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8852c.h" + +static const struct rtw89_pci_bd_idx_addr rtw8852c_bd_idx_addr_low_power = { + .tx_bd_addrs = {R_AX_DRV_FW_HSK_0, R_AX_DRV_FW_HSK_1, R_AX_DRV_FW_HSK_2, + R_AX_DRV_FW_HSK_3, 0, 0, + 0, 0, R_AX_DRV_FW_HSK_4, + 0, 0, 0, + R_AX_DRV_FW_HSK_5}, + .rx_bd_addrs = {R_AX_DRV_FW_HSK_6, R_AX_DRV_FW_HSK_7}, +}; + +static const struct rtw89_pci_info rtw8852c_pci_info = { + .gen_def = &rtw89_pci_gen_ax, + .isr_def = &rtw89_pci_isr_ax, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_V1_256B, + .rx_burst = MAC_AX_RX_BURST_V1_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_ENABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .rx_ring_eq_is_full = false, + .check_rx_tag = false, + .no_rxbd_fs = false, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_AX_HAXI_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN_V1, + .rxhci_en_bit = B_AX_RXHCI_EN_V1, + .rxbd_mode_bit = B_AX_RXBD_MODE_V1, + .exp_ctrl_reg = R_AX_HAXI_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM_V1_MASK, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR_V1, + .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1, + .dma_io_stop = {R_AX_HAXI_INIT_CFG1, B_AX_STOP_AXI_MST}, + .dma_stop1 = {R_AX_HAXI_DMA_STOP1, B_AX_TX_STOP1_MASK}, + .dma_stop2 = {R_AX_HAXI_DMA_STOP2, B_AX_TX_STOP2_ALL}, + .dma_busy1 = {R_AX_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK}, + .dma_busy2_reg = R_AX_HAXI_DMA_BUSY2, + .dma_busy3_reg = R_AX_HAXI_DMA_BUSY3, + + .rpwm_addr = R_AX_PCIE_HRPWM_V1, + .cpwm_addr = R_AX_PCIE_CRPWM, + .mit_addr = R_AX_INT_MIT_RX_V1, + .wp_sel_addr = R_AX_WP_ADDR_H_SEL0_3, + .tx_dma_ch_mask = 0, + .bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, + .bd_ram_table = &rtw89_bd_ram_table_dual, + + .ltr_set = rtw89_pci_ltr_set_v1, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask_v1, + .enable_intr = rtw89_pci_enable_intr_v1, + .disable_intr = rtw89_pci_disable_intr_v1, + .recognize_intrs = rtw89_pci_recognize_intrs_v1, + + .ssid_quirks = NULL, +}; + +static const struct dmi_system_id rtw8852c_pci_quirks[] = { + { + .ident = "Dell Inc. Vostro 16 5640", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"), + DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"), + }, + .driver_data = (void *)RTW89_QUIRK_PCI_BER, + }, + { + .ident = "Dell Inc. Inspiron 16 5640", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5640"), + DMI_MATCH(DMI_PRODUCT_SKU, "0C9F"), + }, + .driver_data = (void *)RTW89_QUIRK_PCI_BER, + }, + {}, +}; + +static const struct rtw89_driver_info rtw89_8852ce_info = { + .chip = &rtw8852c_chip_info, + .variant = NULL, + .board = NULL, + .quirks = rtw8852c_pci_quirks, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8852c_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8852ce_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xc852), + .driver_data = (kernel_ulong_t)&rtw89_8852ce_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8852ce_id_table); + +static struct pci_driver rtw89_8852ce_driver = { + .name = "rtw89_8852ce", + .id_table = rtw89_8852ce_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8852ce_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CE driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c new file mode 100644 index 000000000..2dec9b845 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "rtw8852c.h" +#include "reg.h" +#include "usb.h" + +static const struct rtw89_usb_info rtw8852c_usb_info = { + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2_V1, + .usb_wlan0_1 = R_AX_USB_WLAN0_1_V1, + .hci_func_en = R_AX_HCI_FUNC_EN_V1, + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1, + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0_V1, + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2_V1, + .rx_agg_alignment = 8, + .bulkout_id = { + [RTW89_DMA_ACH0] = 3, + [RTW89_DMA_ACH2] = 5, + [RTW89_DMA_ACH4] = 4, + [RTW89_DMA_ACH6] = 6, + [RTW89_DMA_B0MG] = 0, + [RTW89_DMA_B0HI] = 0, + [RTW89_DMA_B1MG] = 1, + [RTW89_DMA_B1HI] = 1, + [RTW89_DMA_H2C] = 2, + }, +}; + +static const struct rtw89_driver_info rtw89_8852cu_info = { + .chip = &rtw8852c_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .usb = &rtw8852c_usb_info, + }, +}; + +static const struct rtw89_led_gpio_entry rtw8852cu_valve_led_gpios[] = { + { + .pin = 8, + .color = LED_COLOR_ID_WHITE, + .intensity = 0, + .pinmux = {.addr = R_AX_GPIO8_15_FUNC_SEL, + .mask = GENMASK(3, 0), + .data = 0xf}, + .mode = {.addr = R_AX_GPIO_EXT_CTRL + 2, .data = BIT(0) | BIT(8)}, + .out = {.addr = R_AX_GPIO_EXT_CTRL + 1, .data = BIT(0)}, + }, { + .pin = 18, + .color = LED_COLOR_ID_RED, + .intensity = 0, + .pinmux = {.addr = R_AX_GPIO16_23_FUNC_SEL, + .mask = GENMASK(11, 8), + .data = 0xf}, + .mode = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 2, + .data = BIT(2) | BIT(10)}, + .out = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 1, .data = BIT(2)}, + }, { + .pin = 16, + .color = LED_COLOR_ID_GREEN, + .intensity = 1, + .pinmux = {.addr = R_AX_GPIO16_23_FUNC_SEL, + .mask = GENMASK(3, 0), + .data = 0xf}, + .mode = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 2, + .data = BIT(0) | BIT(8)}, + .out = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 1, .data = BIT(0)}, + }, { + .pin = 17, + .color = LED_COLOR_ID_BLUE, + .intensity = 0, + .pinmux = {.addr = R_AX_GPIO16_23_FUNC_SEL, + .mask = GENMASK(7, 4), + .data = 0xf}, + .mode = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 2, + .data = BIT(1) | BIT(9)}, + .out = {.addr = R_AX_GPIO_16_TO_18_EXT_CTRL + 1, .data = BIT(1)}, + }, +}; + +static const struct rtw89_led_desc rtw8852cu_valve_led_desc = { + .gpios = rtw8852cu_valve_led_gpios, + .n_gpio = ARRAY_SIZE(rtw8852cu_valve_led_gpios), +}; + +static const struct rtw89_board_variant rtw89_8852cu_valve_board = { + .led_desc = &rtw8852cu_valve_led_desc, +}; + +static const struct rtw89_driver_info rtw89_8852cu_valve_info = { + .chip = &rtw8852c_chip_info, + .variant = NULL, + .board = &rtw89_8852cu_valve_board, + .quirks = NULL, + .dev_id_quirks = BIT(RTW89_QUIRK_HW_INFO_SYSFS) | + BIT(RTW89_QUIRK_DISABLE_2GHZ), + .bus = { + .usb = &rtw8852c_usb_info, + }, +}; + +static const struct usb_device_id rtw_8852cu_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03a6, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4024, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc832, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x28de, 0x2432, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_valve_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x8206, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0101, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0102, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0103, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8852cu_id_table); + +static struct usb_driver rtw_8852cu_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8852cu_id_table, + .probe = rtw89_usb_probe, + .disconnect = rtw89_usb_disconnect, +}; +module_usb_driver(rtw_8852cu_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CU driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c new file mode 100644 index 000000000..2d225e009 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -0,0 +1,3375 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "efuse.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8922a.h" +#include "rtw8922a_rfk.h" +#include "sar.h" +#include "util.h" + +#define RTW8922A_FW_FORMAT_MAX 4 +#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw" +#define RTW8922A_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8922A_FW_BASENAME, RTW8922A_FW_FORMAT_MAX) + +#define HE_N_USER_MAX_8922A 4 + +static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_pcie[] = { + {2, 1641, grp_0}, /* ACH 0 */ + {2, 1641, grp_0}, /* ACH 1 */ + {2, 1641, grp_0}, /* ACH 2 */ + {2, 1641, grp_0}, /* ACH 3 */ + {2, 1641, grp_1}, /* ACH 4 */ + {2, 1641, grp_1}, /* ACH 5 */ + {2, 1641, grp_1}, /* ACH 6 */ + {2, 1641, grp_1}, /* ACH 7 */ + {2, 1641, grp_0}, /* B0MGQ */ + {2, 1641, grp_0}, /* B0HIQ */ + {2, 1641, grp_1}, /* B1MGQ */ + {2, 1641, grp_1}, /* B1HIQ */ + {0, 0, 0}, /* FWCMDQ */ + {0, 0, 0}, /* BMC */ + {0, 0, 0}, /* H2D */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_pcie = { + 1651, /* Group 0 */ + 1651, /* Group 1 */ + 3302, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DBCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_ch7[] = { + {54, 222, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {54, 222, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {54, 222, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {54, 222, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {54, 222, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {54, 222, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0}, /* FWCMDQ */ + {0, 0, 0}, /* BMC */ + {0, 0, 0}, /* H2D */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_p7 = { + 492, /* Group 0 */ + 0, /* Group 1 */ + 492, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_ch8[] = { + {24, 196, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {54, 226, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {54, 196, grp_1}, /* ACH 4 */ + {0, 0, grp_1}, /* ACH 5 */ + {54, 196, grp_1}, /* ACH 6 */ + {0, 0, grp_1}, /* ACH 7 */ + {54, 226, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {54, 196, grp_1}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0}, /* FWCMDQ */ + {0, 0, 0}, /* BMC */ + {0, 0, 0}, /* H2D */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_p8 = { + 304, /* Group 0 */ + 304, /* Group 1 */ + 608, /* Public Max */ + 96, /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_usb2[] = { + [RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_ch7, &rtw8922a_hfc_pubcfg_p7, + &rtw89_mac_size.hfc_prec_cfg_c5, RTW89_HCIFC_STF}, + [RTW89_QTA_DBCC] = {rtw8922a_hfc_chcfg_ch8, &rtw8922a_hfc_pubcfg_p8, + &rtw89_mac_size.hfc_prec_cfg_c6, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_ch4[] = { + {54, 606, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {54, 606, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {54, 606, grp_0}, /* ACH 4 */ + {0, 0, grp_0}, /* ACH 5 */ + {54, 606, grp_0}, /* ACH 6 */ + {0, 0, grp_0}, /* ACH 7 */ + {54, 606, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {54, 606, grp_0}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0}, /* FWCMDQ */ + {0, 0, 0}, /* BMC */ + {0, 0, 0}, /* H2D */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_p4 = { + 876, /* Group 0 */ + 0, /* Group 1 */ + 876, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_ch5[] = { + {54, 311, grp_0}, /* ACH 0 */ + {0, 0, grp_0}, /* ACH 1 */ + {54, 311, grp_0}, /* ACH 2 */ + {0, 0, grp_0}, /* ACH 3 */ + {54, 311, grp_1}, /* ACH 4 */ + {0, 0, grp_1}, /* ACH 5 */ + {54, 311, grp_1}, /* ACH 6 */ + {0, 0, grp_1}, /* ACH 7 */ + {54, 311, grp_0}, /* B0MGQ */ + {0, 0, grp_0}, /* B0HIQ */ + {54, 311, grp_1}, /* B1MGQ */ + {0, 0, grp_0}, /* B1HIQ */ + {0, 0, 0}, /* FWCMDQ */ + {0, 0, 0}, /* BMC */ + {0, 0, 0}, /* H2D */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_p5 = { + 419, /* Group 0 */ + 419, /* Group 1 */ + 838, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_usb3[] = { + [RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_ch4, &rtw8922a_hfc_pubcfg_p4, + &rtw89_mac_size.hfc_prec_cfg_c3, RTW89_HCIFC_STF}, + [RTW89_QTA_DBCC] = {rtw8922a_hfc_chcfg_ch5, &rtw8922a_hfc_pubcfg_p5, + &rtw89_mac_size.hfc_prec_cfg_c3, RTW89_HCIFC_STF}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8922a_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0_v1, + &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1, + &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0, + &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0, + &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size0_v1, + &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1, + &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0, + &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0, + &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size3_v1, + &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9, + &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1, + &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8922a_dle_mem_usb2[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size7_v1, + &rtw89_mac_size.ple_size6_v1, &rtw89_mac_size.wde_qt7_v1, + &rtw89_mac_size.wde_qt7_v1, &rtw89_mac_size.ple_qt12_v1, + &rtw89_mac_size.ple_qt13_v1, &rtw89_mac_size.ple_rsvd_qt2, + &rtw89_mac_size.rsvd0_size5, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size8_v1, + &rtw89_mac_size.ple_size7_v1, &rtw89_mac_size.wde_qt8_v1, + &rtw89_mac_size.wde_qt8_v1, &rtw89_mac_size.ple_qt14_v1, + &rtw89_mac_size.ple_qt15_v1, &rtw89_mac_size.ple_rsvd_qt2, + &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size3_v1, + &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9, + &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1, + &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_dle_mem rtw8922a_dle_mem_usb3[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size4_v1, + &rtw89_mac_size.ple_size4_v1, &rtw89_mac_size.wde_qt4_v1, + &rtw89_mac_size.wde_qt4_v1, &rtw89_mac_size.ple_qt6_v1, + &rtw89_mac_size.ple_qt7_v1, &rtw89_mac_size.ple_rsvd_qt2, + &rtw89_mac_size.rsvd0_size3, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size5_v1, + &rtw89_mac_size.ple_size4_v1, &rtw89_mac_size.wde_qt5_v1, + &rtw89_mac_size.wde_qt5_v1, &rtw89_mac_size.ple_qt8_v1, + &rtw89_mac_size.ple_qt9_v1, &rtw89_mac_size.ple_rsvd_qt2, + &rtw89_mac_size.rsvd0_size3, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size3_v1, + &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9, + &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1, + &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const u32 rtw8922a_h2c_regs[RTW89_H2CREG_MAX] = { + R_BE_H2CREG_DATA0, R_BE_H2CREG_DATA1, R_BE_H2CREG_DATA2, + R_BE_H2CREG_DATA3 +}; + +static const u32 rtw8922a_c2h_regs[RTW89_H2CREG_MAX] = { + R_BE_C2HREG_DATA0, R_BE_C2HREG_DATA1, R_BE_C2HREG_DATA2, + R_BE_C2HREG_DATA3 +}; + +static const u32 rtw8922a_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_AX_C2HREG_DATA3_V1 + 3, R_BE_DBG_WOW, +}; + +static const struct rtw89_page_regs rtw8922a_page_regs = { + .hci_fc_ctrl = R_BE_HCI_FC_CTRL, + .ch_page_ctrl = R_BE_CH_PAGE_CTRL, + .ach_page_ctrl = R_BE_CH0_PAGE_CTRL, + .ach_page_info = R_BE_CH0_PAGE_INFO, + .pub_page_info3 = R_BE_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_BE_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_BE_PUB_PAGE_CTRL2, + .pub_page_info1 = R_BE_PUB_PAGE_INFO1, + .pub_page_info2 = R_BE_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_BE_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_BE_WP_PAGE_CTRL2, + .wp_page_info1 = R_BE_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_imr rtw8922a_imr_dmac_regs[] = { + {R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR, B_BE_DISP_HOST_IMR_SET}, + {R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR, B_BE_DISP_CPU_IMR_SET}, + {R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR, B_BE_DISP_OTHER_IMR_SET}, + {R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET}, + {R_BE_INTERRUPT_MASK_REG, B_BE_INTERRUPT_MASK_REG_CLR, B_BE_INTERRUPT_MASK_REG_SET}, + {R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET}, + {R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET}, + {R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET}, + {R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET}, + {R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET}, + {R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET}, + {R_BE_WDE_ERR1_IMR, B_BE_WDE_ERR1_IMR_CLR, B_BE_WDE_ERR1_IMR_SET}, + {R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET}, + {R_BE_PLE_ERRFLAG1_IMR, B_BE_PLE_ERRFLAG1_IMR_CLR, B_BE_PLE_ERRFLAG1_IMR_SET}, + {R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET}, + {R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR, + B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET}, + {R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR, + B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET}, + {R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET}, + {R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR, + B_BE_BBRPT_CHINFO_ERR_IMR_SET}, + {R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET}, + {R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET}, + {R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET}, + {R_BE_PLRLS_ERR_IMR, B_BE_PLRLS_ERR_IMR_CLR, B_BE_PLRLS_ERR_IMR_SET}, + {R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET}, +}; + +static const struct rtw89_imr_table rtw8922a_imr_dmac_table = { + .regs = rtw8922a_imr_dmac_regs, + .n_regs = ARRAY_SIZE(rtw8922a_imr_dmac_regs), +}; + +static const struct rtw89_reg_imr rtw8922a_imr_cmac_regs[] = { + {R_BE_RESP_IMR, B_BE_RESP_IMR_CLR, B_BE_RESP_IMR_SET}, + {R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR, B_BE_RX_ERROR_FLAG_IMR_SET}, + {R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET}, + {R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET}, + {R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET}, + {R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET}, + {R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET}, + {R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET}, + {R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET}, + {R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR, + B_BE_TRXPTCL_ERROR_INDICA_MASK_SET}, + {R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET}, + {R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET}, +}; + +static const struct rtw89_imr_table rtw8922a_imr_cmac_table = { + .regs = rtw8922a_imr_cmac_regs, + .n_regs = ARRAY_SIZE(rtw8922a_imr_cmac_regs), +}; + +static const struct rtw89_rrsr_cfgs rtw8922a_rrsr_cfgs = { + .ref_rate = {R_BE_TRXPTCL_RESP_1, B_BE_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8922a_rfkill_regs = { + .pinmux = {R_BE_GPIO8_15_FUNC_SEL, + B_BE_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_BE_GPIO_EXT_CTRL + 2, + (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8922a_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD_V2, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, + .bmode_pd_reg = R_BMODE_PDTH_EN_V2, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V2, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, + .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, + .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, + .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, + .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, + .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V3, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V3, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V3, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V3, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8922a_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL_BE, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_PPDU_LVL_BE, + .ppdu_mask = B_EDCCA_LVL_MSK1, + .p = {{ + .rpt_a = R_EDCCA_RPT_A_BE, + .rpt_b = R_EDCCA_RPT_B_BE, + .rpt_sel = R_EDCCA_RPT_SEL_BE, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A_BE, + .rpt_b = R_EDCCA_RPT_P1_B_BE, + .rpt_sel = R_EDCCA_RPT_SEL_BE, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, + .rpt_sel_be = R_EDCCA_RPTREG_SEL_BE, + .rpt_sel_be_mask = B_EDCCA_RPTREG_SEL_BE_MSK, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST_BE, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_BE_M, +}; + +static const struct rtw89_pmac_regs rtw8922a_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON_V1, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN_V1, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_P0_V1, B_CNT_CCK_CCA_P0}, + .cck_sfd_gg = {R_SFD_GG_CNT_V2, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT_V2, B_SIG_GG_CNT_V1}, + .cck_spoofing = {R_SPOOF_CNT_V2, B_SPOOF_CNT_V1}, + .cck_brk = {R_BRK_CNT_V1, B_BRK_CNT}, + .brk = {R_CNT_BRK_V1, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL_V1, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH_V1, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH_V1, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY_V1, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE_V1, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA_V1, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING_V1, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS_V1, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST_BE, B_R1B_RX_RPT_RST_V1}, + .r1b_rr_sel = {}, + .enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_P0_V1, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0, + .ofdm_txon = R_CNT_OFDMTXON_V1, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC_V1, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC_V1, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC_V1, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC_V1, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = R_CNT_EHT_CRC, + .eht_crc_ok_mask = B_CNT_EHT_CRC_OK, + .eht_crc_err_mask = B_CNT_EHT_CRC_ERR, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32_V1, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static const struct rtw89_efuse_block_cfg rtw8922a_efuse_blocks[] = { + [RTW89_EFUSE_BLOCK_SYS] = {.offset = 0x00000, .size = 0x310}, + [RTW89_EFUSE_BLOCK_RF] = {.offset = 0x10000, .size = 0x240}, + [RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO] = {.offset = 0x20000, .size = 0x4800}, + [RTW89_EFUSE_BLOCK_HCI_DIG_USB] = {.offset = 0x30000, .size = 0x890}, + [RTW89_EFUSE_BLOCK_HCI_PHY_PCIE] = {.offset = 0x40000, .size = 0x200}, + [RTW89_EFUSE_BLOCK_HCI_PHY_USB3] = {.offset = 0x50000, .size = 0x80}, + [RTW89_EFUSE_BLOCK_HCI_PHY_USB2] = {.offset = 0x60000, .size = 0x0}, + [RTW89_EFUSE_BLOCK_ADIE] = {.offset = 0x70000, .size = 0x10}, +}; + +static void rtw8922a_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_SHARE_A, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BTG_PATH_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_SHARE_B, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BTG_PATH_B, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x20, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA0_B, 0x30, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_BT_SHARE, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_BT_SG0, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x1, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_SHARE_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BTG_PATH_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_SHARE_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BTG_PATH_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x1a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA0_B, 0x2a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_BT_SHARE, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_BT_SG0, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x0, phy_idx); + } +} + +static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + int ret; + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_AFSM_WLSUS_EN | + B_BE_AFSM_PCIE_SUS_EN); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_DIS_WLBT_PDNSUSEN_SOPC); + rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APDM_HPDN); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR, + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 | + B_BE_LPSROP_CMAC1); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC), + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_AFE_ON_CTRL1, B_BE_REG_CK_MON_CK960M_EN); + rtw89_write8_set(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 | + B_BE_POW_PC_LDO_PORT1); + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP | + B_BE_R_SYM_ISO_ADDA_P12PP); + rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, + val32 & B_BE_HAXIDMA_IO_ST, + 1000, 3000000, false, rtwdev, + R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + ret = read_poll_timeout(rtw89_read32, val32, + !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST), + 1000, 3000000, false, rtwdev, + R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST, + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, + B_BE_PCIE_FORCE_IBX_EN); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0x02); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x01, 0x01); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF1, 0, 0x40); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF2, 0, 0x40); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, 0x40, 0x60); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); + if (ret) + return ret; + + if (hal->cv != CHIP_CAV) { + rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); + + mdelay(1); + + rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); + rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + } + + val32 = B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | B_BE_MPDU_PROC_EN | + B_BE_WD_RLS_EN | B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN | + B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | B_BE_PKT_BUF_EN | + B_BE_DMAC_TBL_EN | B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN | + B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | B_BE_MAC_SEC_EN | + B_BE_H_AXIDMA_EN | B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN | + B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN; + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + val32 |= B_BE_LTR_CTL_EN; + rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN, val32); + + set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); + + rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN, + B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | B_BE_ADDRSRCH_EN | + B_BE_BTCOEX_EN); + rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN, + B_BE_CMAC_EN | B_BE_CMAC_TXEN | B_BE_CMAC_RXEN | + B_BE_SIGB_EN | B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN | + B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN | B_BE_TMAC_EN | + B_BE_RMAC_EN | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN); + + set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); + + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN | + B_BE_FEN_BBPLAT_RSTB); + + return 0; +} + +static int rtw8922a_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC6, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC6, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x00, 0xFF); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP | + B_BE_R_SYM_ISO_ADDA_P12PP); + rtw89_write8_clr(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 | + B_BE_POW_PC_LDO_PORT1); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN | + B_BE_FEN_BBPLAT_RSTB); + rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, + !(val32 & B_BE_HAXIDMA_IO_ST), + 1000, 3000000, false, rtwdev, + R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + ret = read_poll_timeout(rtw89_read32, val32, + !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST), + 1000, 3000000, false, rtwdev, + R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST), + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC), + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x0000A1B2); + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_SOP_EASWR); + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE); + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) { + val32 = rtw89_read32(rtwdev, R_BE_SYS_PW_CTRL); + val32 |= B_BE_AFSM_WLSUS_EN; + val32 &= ~B_BE_AFSM_PCIE_SUS_EN; + rtw89_write32(rtwdev, R_BE_SYS_PW_CTRL, val32); + } + + rtw89_write32(rtwdev, R_BE_UDM1, 0); + + return 0; +} + +static void rtw8922a_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8922a_efuse *map) +{ + struct rtw8922a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; + u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b}; + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + tssi->thermal[RF_PATH_B] = map->path_b_therm; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, + sizeof(ofst[i]->cck_tssi)); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + sizeof(ofst[i]->bw40_tssi)); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); + memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i], + sizeof(tssi->tssi_6g_mcs[i])); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + } +} + +static void rtw8922a_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8922a_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + bool all_0xff = true, all_0x00 = true; + int i, j; + u8 t; + + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_a._2g_cck; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_b._2g_cck; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_a._2g_ofdm; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_b._2g_ofdm; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_a._5g_low; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_b._5g_low; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_a._5g_mid; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_b._5g_mid; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_a._5g_high; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_b._5g_high; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_a._6g_l0; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_b._6g_l0; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_a._6g_l1; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_b._6g_l1; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_a._6g_m0; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_b._6g_m0; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_a._6g_m1; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_b._6g_m1; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_a._6g_h0; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_b._6g_h0; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_a._6g_h1; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_b._6g_h1; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_a._6g_uh0; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_b._6g_uh0; + gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_a._6g_uh1; + gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_b._6g_uh1; + + for (i = RF_PATH_A; i <= RF_PATH_B; i++) + for (j = 0; j < RTW89_GAIN_OFFSET_NR; j++) { + t = gain->offset[i][j]; + if (t != 0xff) + all_0xff = false; + if (t != 0x0) + all_0x00 = false; + + /* transform: sign-bit + U(7,2) to S(8,2) */ + if (t & 0x80) + gain->offset[i][j] = (t ^ 0x7f) + 1; + } + + gain->offset_valid = !all_0xff && !all_0x00; +} + +static void rtw8922a_read_efuse_mac_addr(struct rtw89_dev *rtwdev, u32 addr) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + u16 val; + int i; + + for (i = 0; i < ETH_ALEN; i += 2, addr += 2) { + val = rtw89_read16(rtwdev, addr); + efuse->addr[i] = val & 0xff; + efuse->addr[i + 1] = val >> 8; + } +} + +static int rtw8922a_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + rtw8922a_read_efuse_mac_addr(rtwdev, 0x3104); + else + ether_addr_copy(efuse->addr, log_map + 0x001A); + + return 0; +} + +static int rtw8922a_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map) +{ + rtw8922a_read_efuse_mac_addr(rtwdev, 0x4078); + + return 0; +} + +static int rtw8922a_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw8922a_efuse *map = (struct rtw8922a_efuse *)log_map; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + rtw8922a_efuse_parsing_tssi(rtwdev, map); + rtw8922a_efuse_parsing_gain_offset(rtwdev, map); + + return 0; +} + +static int rtw8922a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + int ret; + + switch (block) { + case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO: + ret = rtw8922a_read_efuse_pci_sdio(rtwdev, log_map); + break; + case RTW89_EFUSE_BLOCK_HCI_DIG_USB: + ret = rtw8922a_read_efuse_usb(rtwdev, log_map); + break; + case RTW89_EFUSE_BLOCK_RF: + ret = rtw8922a_read_efuse_rf(rtwdev, log_map); + break; + default: + ret = 0; + break; + } + + if (!ret && is_zero_ether_addr(efuse->addr)) { + rtw89_info(rtwdev, "efuse mac address is zero, using random mac\n"); + eth_random_addr(efuse->addr); + } + + return ret; +} + +#define THM_TRIM_POSITIVE_MASK BIT(6) +#define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0) + +static void rtw8922a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 thm_trim_addr[RF_PATH_NUM_8922A] = {0x1706, 0x1733}; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = true; + u8 pg_th; + s8 val; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + pg_th = phycap_map[thm_trim_addr[i] - addr]; + if (pg_th == 0xff) { + info->thermal_trim[i] = 0; + pg = false; + break; + } + + val = u8_get_bits(pg_th, THM_TRIM_MAGNITUDE_MASK); + + if (!(pg_th & THM_TRIM_POSITIVE_MASK)) + val *= -1; + + info->thermal_trim[i] = val; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x (%d)\n", + i, pg_th, val); + } + + info->pg_thermal_trim = pg; +} + +static void rtw8922a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 pabias_trim_addr[RF_PATH_NUM_8922A] = {0x1707, 0x1734}; + static const u32 check_pa_pad_trim_addr = 0x1700; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + u8 val; + u8 i; + + val = phycap_map[check_pa_pad_trim_addr - addr]; + if (val != 0xff) + info->pg_pa_bias_trim = true; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + } +} + +static void rtw8922a_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); + pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG_V1, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA_V1, pabias_5g); + } +} + +static void rtw8922a_phycap_parsing_pad_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 pad_bias_trim_addr[RF_PATH_NUM_8922A] = {0x1708, 0x1735}; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + info->pad_bias_trim[i] = phycap_map[pad_bias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] path=%d pad_bias_trim=0x%x\n", + i, info->pad_bias_trim[i]); + } +} + +static void rtw8922a_pad_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pad_bias_2g, pad_bias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] no PG, do nothing\n"); + return; + } + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + pad_bias_2g = u8_get_bits(info->pad_bias_trim[i], GENMASK(3, 0)); + pad_bias_5g = u8_get_bits(info->pad_bias_trim[i], GENMASK(7, 4)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pad_bias_2g, pad_bias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXG_V1, pad_bias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXA_V1, pad_bias_5g); + } +} + +static int rtw8922a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8922a_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8922a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + rtw8922a_phycap_parsing_pad_bias_trim(rtwdev, phycap_map); + + return 0; +} + +static void rtw8922a_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8922a_pa_bias_trim(rtwdev); + rtw8922a_pad_bias_trim(rtwdev); +} + +static void rtw8922a_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx); + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx); + u8 txsb20 = 0, txsb40 = 0, txsb80 = 0; + u8 rf_mod_val, chk_rate_mask; + u32 txsb; + u32 reg; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + txsb80 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_80); + fallthrough; + case RTW89_CHANNEL_WIDTH_80: + txsb40 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsb20 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + rf_mod_val = BE_WMAC_RFMOD_160M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) | + u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK) | + u32_encode_bits(txsb80, B_BE_TXSB_80M_MASK); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_mod_val = BE_WMAC_RFMOD_80M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) | + u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_mod_val = BE_WMAC_RFMOD_40M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK); + break; + case RTW89_CHANNEL_WIDTH_20: + default: + rf_mod_val = BE_WMAC_RFMOD_20M; + txsb = 0; + break; + } + + if (txsb20 <= BE_PRI20_BITMAP_MAX) + txsb |= u32_encode_bits(BIT(txsb20), B_BE_PRI20_BITMAP_MASK); + + rtw89_write8_mask(rtwdev, rf_mod, B_BE_WMAC_RFMOD_MASK, rf_mod_val); + rtw89_write32(rtwdev, sub_carr, txsb); + + switch (chan->band_type) { + case RTW89_BAND_2G: + chk_rate_mask = B_BE_BAND_MODE; + break; + case RTW89_BAND_5G: + case RTW89_BAND_6G: + chk_rate_mask = B_BE_CHECK_CCK_EN | B_BE_RTS_LIMIT_IN_OFDM6; + break; + default: + rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type); + return; + } + + rtw89_write8_clr(rtwdev, chk_rate, B_BE_BAND_MODE | B_BE_CHECK_CCK_EN | + B_BE_RTS_LIMIT_IN_OFDM6); + rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask); + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_320: + case RTW89_CHANNEL_WIDTH_160: + case RTW89_CHANNEL_WIDTH_80: + case RTW89_CHANNEL_WIDTH_40: + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_T1_MASK, 0x41); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_MASK, 0x41); + break; + default: + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_T1_MASK, 0x3f); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_MASK, 0x3e); + break; + } +} + +static const u32 rtw8922a_sco_barker_threshold[14] = { + 0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6, + 0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a +}; + +static const u32 rtw8922a_sco_cck_threshold[14] = { + 0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db, + 0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e +}; + +static int rtw8922a_ctrl_sco_cck(struct rtw89_dev *rtwdev, + u8 primary_ch, enum rtw89_bandwidth bw, + enum rtw89_phy_idx phy_idx) +{ + u8 ch_element; + + if (primary_ch >= 14) + return -EINVAL; + + ch_element = primary_ch - 1; + + rtw89_phy_write32_idx(rtwdev, R_BK_FC0INV, B_BK_FC0INV, + rtw8922a_sco_barker_threshold[ch_element], + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CCK_FC0INV, B_CCK_FC0INV, + rtw8922a_sco_cck_threshold[ch_element], + phy_idx); + + return 0; +} + +struct rtw8922a_bb_gain { + u32 gain_g[BB_PATH_NUM_8922A]; + u32 gain_a[BB_PATH_NUM_8922A]; + u32 gain_g_mask; + u32 gain_a_mask; +}; + +static const struct rtw89_reg_def rpl_comp_bw160[RTW89_BW20_SC_160M] = { + { .addr = 0x41E8, .mask = 0xFF00}, + { .addr = 0x41E8, .mask = 0xFF0000}, + { .addr = 0x41E8, .mask = 0xFF000000}, + { .addr = 0x41EC, .mask = 0xFF}, + { .addr = 0x41EC, .mask = 0xFF00}, + { .addr = 0x41EC, .mask = 0xFF0000}, + { .addr = 0x41EC, .mask = 0xFF000000}, + { .addr = 0x41F0, .mask = 0xFF} +}; + +static const struct rtw89_reg_def rpl_comp_bw80[RTW89_BW20_SC_80M] = { + { .addr = 0x41F4, .mask = 0xFF}, + { .addr = 0x41F4, .mask = 0xFF00}, + { .addr = 0x41F4, .mask = 0xFF0000}, + { .addr = 0x41F4, .mask = 0xFF000000} +}; + +static const struct rtw89_reg_def rpl_comp_bw40[RTW89_BW20_SC_40M] = { + { .addr = 0x41F0, .mask = 0xFF0000}, + { .addr = 0x41F0, .mask = 0xFF000000} +}; + +static const struct rtw89_reg_def rpl_comp_bw20[RTW89_BW20_SC_20M] = { + { .addr = 0x41F0, .mask = 0xFF00} +}; + +static const struct rtw8922a_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x409c, 0x449c}, .gain_a = {0x406C, 0x446C}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x409c, 0x449c}, .gain_a = {0x406C, 0x446C}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x40a0, 0x44a0}, .gain_a = {0x4070, 0x4470}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x40a0, 0x44a0}, .gain_a = {0x4070, 0x4470}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x40a4, 0x44a4}, .gain_a = {0x4074, 0x4474}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x40a4, 0x44a4}, .gain_a = {0x4074, 0x4474}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x40a8, 0x44a8}, .gain_a = {0x4078, 0x4478}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, +}; + +static const struct rtw8922a_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x4054, 0x4454}, .gain_a = {0x4054, 0x4454}, + .gain_g_mask = 0x7FC0000, .gain_a_mask = 0x1FF}, + { .gain_g = {0x4058, 0x4458}, .gain_a = {0x4054, 0x4454}, + .gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 }, +}; + +static const struct rtw8922a_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x4078, 0x4478}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF}, + { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00}, + { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF}, + { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00}, +}; + +static const struct rtw8922a_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = { + { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4080, 0x4480}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4084, 0x4484}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF}, + { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00}, + { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4088, 0x4488}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF}, + { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00}, + { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000}, +}; + +struct rtw8922a_bb_gain_bypass { + u32 gain_g[BB_PATH_NUM_8922A]; + u32 gain_a[BB_PATH_NUM_8922A]; + u32 gain_mask_g; + u32 gain_mask_a; +}; + +static void rtw8922a_set_rpl_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + u32 reg_path_ofst = 0; + u32 mask; + s32 val; + u32 reg; + int i; + + if (path == RF_PATH_B) + reg_path_ofst = 0x400; + + for (i = 0; i < RTW89_BW20_SC_160M; i++) { + reg = rpl_comp_bw160[i].addr | reg_path_ofst; + mask = rpl_comp_bw160[i].mask; + val = gain->rpl_ofst_160[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_80M; i++) { + reg = rpl_comp_bw80[i].addr | reg_path_ofst; + mask = rpl_comp_bw80[i].mask; + val = gain->rpl_ofst_80[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_40M; i++) { + reg = rpl_comp_bw40[i].addr | reg_path_ofst; + mask = rpl_comp_bw40[i].mask; + val = gain->rpl_ofst_40[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_20M; i++) { + reg = rpl_comp_bw20[i].addr | reg_path_ofst; + mask = rpl_comp_bw20[i].mask; + val = gain->rpl_ofst_20[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } +} + +static void rtw8922a_set_lna_tia_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + enum rtw89_phy_bb_bw_be bw_type; + s32 val; + u32 reg; + u32 mask; + int i; + + bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ? + RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_gain_lna[i].gain_g[path]; + mask = bb_gain_lna[i].gain_g_mask; + } else { + reg = bb_gain_lna[i].gain_a[path]; + mask = bb_gain_lna[i].gain_a_mask; + } + val = gain->lna_gain[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_gain_tia[i].gain_g[path]; + mask = bb_gain_tia[i].gain_g_mask; + } else { + reg = bb_gain_tia[i].gain_a[path]; + mask = bb_gain_tia[i].gain_a_mask; + } + val = gain->tia_gain[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_op1db_lna[i].gain_g[path]; + mask = bb_op1db_lna[i].gain_g_mask; + } else { + reg = bb_op1db_lna[i].gain_a[path]; + mask = bb_op1db_lna[i].gain_a_mask; + } + val = gain->lna_op1db[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_op1db_tia_lna[i].gain_g[path]; + mask = bb_op1db_tia_lna[i].gain_g_mask; + } else { + reg = bb_op1db_tia_lna[i].gain_a[path]; + mask = bb_op1db_tia_lna[i].gain_a_mask; + } + val = gain->tia_lna_op1db[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } +} + +static void rtw8922a_set_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_set_lna_tia_gain(rtwdev, chan, path, phy_idx); + rtw8922a_set_rpl_gain(rtwdev, chan, path, phy_idx); +} + +static void rtw8922a_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + s8 value = -gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK]; /* S(8,2) */ + u8 fraction = value & 0x3; + + if (fraction) { + rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW20, + (0x4 - fraction) << 1); + rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW40, + (0x4 - fraction) << 1); + + value >>= 2; + rtw89_phy_write32_mask(rtwdev, R_CCK_RPL_OFST, B_CCK_RPL_OFST, + value + 1 + 0xdc); + } else { + rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW20, 0); + rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW40, 0); + + value >>= 2; + rtw89_phy_write32_mask(rtwdev, R_CCK_RPL_OFST, B_CCK_RPL_OFST, + value + 0xdc); + } +} + +static void rtw8922a_set_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + static const u32 rssi_tb_bias_comp[2] = {0x41f8, 0x45f8}; + static const u32 rssi_tb_ext_comp[2] = {0x4208, 0x4608}; + static const u32 rssi_ofst_addr[2] = {0x40c8, 0x44c8}; + static const u32 rpl_bias_comp[2] = {0x41e8, 0x45e8}; + static const u32 rpl_ext_comp[2] = {0x41f8, 0x45f8}; + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset gain_band; + s8 v1, v2, v3; + s32 value; + + gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type); + value = gain->offset[path][gain_band]; + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], 0xff000000, value + 0xF8); + + value *= -4; + v1 = clamp_t(s32, value, S8_MIN, S8_MAX); + value -= v1; + v2 = clamp_t(s32, value, S8_MIN, S8_MAX); + value -= v2; + v3 = clamp_t(s32, value, S8_MIN, S8_MAX); + + rtw89_phy_write32_mask(rtwdev, rpl_bias_comp[path], 0xff, v1); + rtw89_phy_write32_mask(rtwdev, rpl_ext_comp[path], 0xff, v2); + rtw89_phy_write32_mask(rtwdev, rpl_ext_comp[path], 0xff00, v3); + + rtw89_phy_write32_mask(rtwdev, rssi_tb_bias_comp[path], 0xff0000, v1); + rtw89_phy_write32_mask(rtwdev, rssi_tb_ext_comp[path], 0xff0000, v2); + rtw89_phy_write32_mask(rtwdev, rssi_tb_ext_comp[path], 0xff000000, v3); +} + +static void rtw8922a_set_rx_gain_normal(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + if (!gain->offset_valid) + return; + + if (chan->band_type == RTW89_BAND_2G) + rtw8922a_set_rx_gain_normal_cck(rtwdev, chan, path); + + rtw8922a_set_rx_gain_normal_ofdm(rtwdev, chan, path); +} + +static void rtw8922a_set_cck_parameters(struct rtw89_dev *rtwdev, u8 central_ch, + enum rtw89_phy_idx phy_idx) +{ + if (central_ch == 14) { + rtw89_phy_write32_idx(rtwdev, R_PCOEFF01, B_PCOEFF01, 0x3b13ff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF23, B_PCOEFF23, 0x1c42de, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF45, B_PCOEFF45, 0xfdb0ad, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF67, B_PCOEFF67, 0xf60f6e, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF89, B_PCOEFF89, 0xfd8f92, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFAB, B_PCOEFFAB, 0x02d011, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFCD, B_PCOEFFCD, 0x01c02c, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFEF, B_PCOEFFEF, 0xfff00a, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_PCOEFF01, B_PCOEFF01, 0x3a63ca, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF23, B_PCOEFF23, 0x2a833f, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF45, B_PCOEFF45, 0x1491f8, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF67, B_PCOEFF67, 0x03c0b0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF89, B_PCOEFF89, 0xfccff1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFAB, B_PCOEFFAB, 0xfccfc3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFCD, B_PCOEFFCD, 0xfebfdc, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFFEF, B_PCOEFFEF, 0xffdff7, phy_idx); + } +} + +static void rtw8922a_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + static const u32 band_sel[2] = {0x4160, 0x4560}; + u16 central_freq = chan->freq; + u8 central_ch = chan->channel; + u8 band = chan->band_type; + bool is_2g = band == RTW89_BAND_2G; + u8 chan_idx; + u8 path; + u8 sco; + + if (!central_freq) { + rtw89_warn(rtwdev, "Invalid central_freq\n"); + return; + } + + rtw8922a_set_gain(rtwdev, chan, RF_PATH_A, phy_idx); + rtw8922a_set_gain(rtwdev, chan, RF_PATH_B, phy_idx); + + for (path = RF_PATH_A; path < BB_PATH_NUM_8922A; path++) + rtw89_phy_write32_idx(rtwdev, band_sel[path], BIT((26)), is_2g, phy_idx); + + rtw8922a_set_rx_gain_normal(rtwdev, chan, RF_PATH_A); + rtw8922a_set_rx_gain_normal(rtwdev, chan, RF_PATH_B); + + rtw89_phy_write32_idx(rtwdev, R_FC0, B_FC0, central_freq, phy_idx); + sco = DIV_ROUND_CLOSEST(1 << 18, central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_FC0_INV, sco, phy_idx); + + if (band == RTW89_BAND_2G) + rtw8922a_set_cck_parameters(rtwdev, central_ch, phy_idx); + + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); + rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx); +} + +static void +rtw8922a_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_sb, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x1, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x1, phy_idx); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri_sb:%d)\n", bw, + pri_sb); + break; + } + + if (bw == RTW89_CHANNEL_WIDTH_40) + rtw89_phy_write32_idx(rtwdev, R_FC0, B_BW40_2XFFT, 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_FC0, B_BW40_2XFFT, 0, phy_idx); +} + +static u32 rtw8922a_spur_freq(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8922a_set_csi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s32 freq_diff, csi_idx, csi_tone_idx; + u32 spur_freq; + + spur_freq = rtw8922a_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_EN, + 0, phy_idx); + return; + } + + freq_diff = (spur_freq - chan->freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_TONE_IDX, + csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_EN, 1, phy_idx); +} + +static const struct rtw89_nbi_reg_def rtw8922a_nbi_reg_def[] = { + [RF_PATH_A] = { + .notch1_idx = {0x41a0, 0xFF}, + .notch1_frac_idx = {0x41a0, 0xC00}, + .notch1_en = {0x41a0, 0x1000}, + .notch2_idx = {0x41ac, 0xFF}, + .notch2_frac_idx = {0x41ac, 0xC00}, + .notch2_en = {0x41ac, 0x1000}, + }, + [RF_PATH_B] = { + .notch1_idx = {0x45a0, 0xFF}, + .notch1_frac_idx = {0x45a0, 0xC00}, + .notch1_en = {0x45a0, 0x1000}, + .notch2_idx = {0x45ac, 0xFF}, + .notch2_frac_idx = {0x45ac, 0xC00}, + .notch2_en = {0x45ac, 0x1000}, + }, +}; + +static void rtw8922a_set_nbi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_nbi_reg_def *nbi = &rtw8922a_nbi_reg_def[path]; + s32 nbi_frac_idx, nbi_frac_tone_idx; + s32 nbi_idx, nbi_tone_idx; + bool notch2_chk = false; + u32 spur_freq, fc; + s32 freq_diff; + + spur_freq = rtw8922a_spur_freq(rtwdev, chan); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + return; + } + + fc = chan->freq; + if (chan->band_width == RTW89_CHANNEL_WIDTH_160) { + fc = (spur_freq > fc) ? fc + 40 : fc - 40; + if ((fc > spur_freq && + chan->channel < chan->primary_channel) || + (fc < spur_freq && + chan->channel > chan->primary_channel)) + notch2_chk = true; + } + + freq_diff = (spur_freq - fc) * 1000000; + nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, + &nbi_frac_idx); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_20) { + s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); + } else { + u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ? + 128 : 256; + + s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); + } + nbi_frac_tone_idx = + s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { + rtw89_phy_write32_idx(rtwdev, nbi->notch2_idx.addr, + nbi->notch2_idx.mask, nbi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_frac_idx.addr, + nbi->notch2_frac_idx.mask, nbi_frac_tone_idx, + phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, nbi->notch1_idx.addr, + nbi->notch1_idx.mask, nbi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_frac_idx.addr, + nbi->notch1_frac_idx.mask, nbi_frac_tone_idx, + phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + } +} + +static void rtw8922a_spur_elimination(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_set_csi_tone_idx(rtwdev, chan, phy_idx); + rtw8922a_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A, phy_idx); + rtw8922a_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B, phy_idx); +} + +static void rtw8922a_ctrl_afe_dac(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, + enum rtw89_rf_path path) +{ + u32 cr_ofst = 0x0; + + if (path == RF_PATH_B) + cr_ofst = 0x100; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, R_AFEDAC0 + cr_ofst, B_AFEDAC0, 0xE); + rtw89_phy_write32_mask(rtwdev, R_AFEDAC1 + cr_ofst, B_AFEDAC1, 0x7); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, R_AFEDAC0 + cr_ofst, B_AFEDAC0, 0xD); + rtw89_phy_write32_mask(rtwdev, R_AFEDAC1 + cr_ofst, B_AFEDAC1, 0x6); + break; + default: + break; + } +} + +static const struct rtw89_reg2_def bb_mcu0_init_reg[] = { + {0x6990, 0x00000000}, + {0x6994, 0x00000000}, + {0x6998, 0x00000000}, + {0x6820, 0xFFFFFFFE}, + {0x6800, 0xC0000FFE}, + {0x6808, 0x76543210}, + {0x6814, 0xBFBFB000}, + {0x6818, 0x0478C009}, + {0x6800, 0xC0000FFF}, + {0x6820, 0xFFFFFFFF}, +}; + +static const struct rtw89_reg2_def bb_mcu1_init_reg[] = { + {0x6990, 0x00000000}, + {0x6994, 0x00000000}, + {0x6998, 0x00000000}, + {0x6820, 0xFFFFFFFE}, + {0x6800, 0xC0000FFE}, + {0x6808, 0x76543210}, + {0x6814, 0xBFBFB000}, + {0x6818, 0x0478C009}, + {0x6800, 0xC0000FFF}, + {0x6820, 0xFFFFFFFF}, +}; + +static void rtw8922a_bbmcu_cr_init(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_reg2_def *reg; + int size; + int i; + + if (phy_idx == RTW89_PHY_0) { + reg = bb_mcu0_init_reg; + size = ARRAY_SIZE(bb_mcu0_init_reg); + } else { + reg = bb_mcu1_init_reg; + size = ARRAY_SIZE(bb_mcu1_init_reg); + } + + for (i = 0; i < size; i++, reg++) + rtw89_bbmcu_write32(rtwdev, reg->addr, reg->data, phy_idx); +} + +static const u32 dmac_sys_mask[2] = {B_BE_DMAC_BB_PHY0_MASK, B_BE_DMAC_BB_PHY1_MASK}; +static const u32 bbrst_mask[2] = {B_BE_FEN_BBPLAT_RSTB, B_BE_FEN_BB1PLAT_RSTB}; +static const u32 glbrst_mask[2] = {B_BE_FEN_BB_IP_RSTN, B_BE_FEN_BB1_IP_RSTN}; +static const u32 mcu_bootrdy_mask[2] = {B_BE_BOOT_RDY0, B_BE_BOOT_RDY1}; + +static void rtw8922a_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u32 rdy = 0; + + if (phy_idx == RTW89_PHY_1) + rdy = 1; + + rtw89_write32_mask(rtwdev, R_BE_DMAC_SYS_CR32B, dmac_sys_mask[phy_idx], 0x7FF9); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x0); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x0); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x1); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, mcu_bootrdy_mask[phy_idx], rdy); + rtw89_write32_mask(rtwdev, R_BE_MEM_PWR_CTRL, B_BE_MEM_BBMCU0_DS_V1, 0); + + fsleep(1); + rtw8922a_bbmcu_cr_init(rtwdev, phy_idx); +} + +static void rtw8922a_bb_postinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + if (phy_idx == RTW89_PHY_0) + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, mcu_bootrdy_mask[phy_idx]); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx]); + + rtw89_phy_write32_set(rtwdev, R_BBCLK, B_CLK_640M); + rtw89_phy_write32_clr(rtwdev, R_TXSCALE, B_TXFCTR_EN); + rtw89_phy_set_phy_regs(rtwdev, R_TXFCTR, B_TXFCTR_THD, 0x200); + rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_EHT_RATE_TH, 0xA); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE, B_HE_RATE_TH, 0xA); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE2, B_HT_VHT_TH, 0xAAA); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE, B_EHT_MCS14, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE2, B_EHT_MCS15, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_EHTTB_EN, 0x0); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_HEERSU_EN, 0x0); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_HEMU_EN, 0x0); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_TB_EN, 0x0); + rtw89_phy_set_phy_regs(rtwdev, R_SU_PUNC, B_SU_PUNC_EN, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE5, B_HWGEN_EN, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_BEDGE5, B_PWROFST_COMP, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_MAG_AB, B_BY_SLOPE, 0x1); + rtw89_phy_set_phy_regs(rtwdev, R_MAG_A, B_MGA_AEND, 0xe0); + rtw89_phy_set_phy_regs(rtwdev, R_MAG_AB, B_MAG_AB, 0xe0c000); + rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_SLOPE_A, 0x3FE0); + rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_SLOPE_B, 0x3FE0); + rtw89_phy_set_phy_regs(rtwdev, R_SC_CORNER, B_SC_CORNER, 0x200); + rtw89_phy_write32_idx(rtwdev, R_UDP_COEEF, B_UDP_COEEF, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_UDP_COEEF, B_UDP_COEEF, 0x1, phy_idx); +} + +static void rtw8922a_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + bool en, enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + if (band == RTW89_BAND_2G) + rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, + B_RXCCA_BE1_DIS, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); + } +} + +static int rtw8922a_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, + enum rtw89_rf_path tx_path, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_reg2_def path_com_cr[] = { + {0x11A00, 0x21C86900}, + {0x11A04, 0x00E4E433}, + {0x11A08, 0x39390CC9}, + {0x11A0C, 0x4E433240}, + {0x11A10, 0x90CC900E}, + {0x11A14, 0x00240393}, + {0x11A18, 0x201C8600}, + }; + int ret = 0; + u32 reg; + int i; + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL, 0x0, phy_idx); + + if (phy_idx == RTW89_PHY_1 && !rtwdev->dbcc_en) + return 0; + + if (tx_path == RF_PATH_A) { + path_com_cr[0].data = 0x21C82900; + path_com_cr[1].data = 0x00E4E431; + path_com_cr[2].data = 0x39390C49; + path_com_cr[3].data = 0x4E431240; + path_com_cr[4].data = 0x90C4900E; + path_com_cr[6].data = 0x201C8200; + } else if (tx_path == RF_PATH_B) { + path_com_cr[0].data = 0x21C04900; + path_com_cr[1].data = 0x00E4E032; + path_com_cr[2].data = 0x39380C89; + path_com_cr[3].data = 0x4E032240; + path_com_cr[4].data = 0x80C8900E; + path_com_cr[6].data = 0x201C0400; + } else if (tx_path == RF_PATH_AB) { + path_com_cr[0].data = 0x21C86900; + path_com_cr[1].data = 0x00E4E433; + path_com_cr[2].data = 0x39390CC9; + path_com_cr[3].data = 0x4E433240; + path_com_cr[4].data = 0x90CC900E; + path_com_cr[6].data = 0x201C8600; + } else { + ret = -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(path_com_cr); i++) { + reg = rtw89_mac_reg_by_idx(rtwdev, path_com_cr[i].addr, phy_idx); + rtw89_write32(rtwdev, reg, path_com_cr[i].data); + } + + return ret; +} + +static void rtw8922a_bb_reset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ +} + +static int rtw8922a_cfg_rx_nss_limit(struct rtw89_dev *rtwdev, u8 rx_nss, + enum rtw89_phy_idx phy_idx) +{ + if (rx_nss == 1) { + rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_HTMCS_LMT, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_VHTMCS_LMT, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_N_USR_MAX, + HE_N_USER_MAX_8922A, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_NSS_MAX, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_TB_NSS_MAX, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_EHT, B_RXEHT_NSS_MAX, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHTTB_NSS_MAX, 0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHT_N_USER_MAX, + HE_N_USER_MAX_8922A, phy_idx); + } else if (rx_nss == 2) { + rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_HTMCS_LMT, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_VHTMCS_LMT, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_N_USR_MAX, + HE_N_USER_MAX_8922A, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_NSS_MAX, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_TB_NSS_MAX, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_EHT, B_RXEHT_NSS_MAX, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHTTB_NSS_MAX, 1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHT_N_USER_MAX, + HE_N_USER_MAX_8922A, phy_idx); + } else { + return -EINVAL; + } + + return 0; +} + +static void rtw8922a_tssi_reset(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x1); + } + } else { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x1); + } +} + +static int rtw8922a_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rx_path, + enum rtw89_phy_idx phy_idx) +{ + u8 rx_nss = (rx_path == RF_PATH_AB) ? 2 : 1; + + /* Set to 0 first to avoid abnormal EDCCA report */ + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x0, phy_idx); + + if (rx_path == RF_PATH_A) { + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 1, phy_idx); + rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx); + rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx); + } else if (rx_path == RF_PATH_B) { + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 2, phy_idx); + rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx); + rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx); + } else if (rx_path == RF_PATH_AB) { + rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 3, phy_idx); + rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx); + rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx); + } else { + return -EINVAL; + } + + return 0; +} + +#define DIGITAL_PWR_COMP_REG_NUM 22 +static const u32 rtw8922a_digital_pwr_comp_2g_s0_val[][DIGITAL_PWR_COMP_REG_NUM] = { + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010000, 0x00000101, + 0x01010101, 0x02020201, 0x02010000, 0x03030202, 0x00000303, + 0x03020101, 0x06060504, 0x01010000, 0x06050403, 0x01000606, + 0x05040202, 0x07070706}, + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101, + 0x01000000, 0x01010101, 0x01010000, 0x02020202, 0x00000404, + 0x03020101, 0x04040303, 0x02010000, 0x03030303, 0x00000505, + 0x03030201, 0x05050303}, +}; + +static const u32 rtw8922a_digital_pwr_comp_2g_s1_val[][DIGITAL_PWR_COMP_REG_NUM] = { + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, + 0x0D05091D, 0x14D50FA0, 0x01010000, 0x01010101, 0x00000101, + 0x01010100, 0x01010101, 0x01010000, 0x02020202, 0x01000202, + 0x02020101, 0x03030202, 0x02010000, 0x05040403, 0x01000606, + 0x05040302, 0x07070605}, + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101, + 0x01010000, 0x02020201, 0x02010100, 0x03030202, 0x01000404, + 0x04030201, 0x05050404, 0x01010100, 0x04030303, 0x01000505, + 0x03030101, 0x05050404}, +}; + +static const u32 rtw8922a_digital_pwr_comp_val[][DIGITAL_PWR_COMP_REG_NUM] = { + {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A, + 0x0BB80708, 0x17701194, 0x02020100, 0x03030303, 0x01000303, + 0x05030302, 0x06060605, 0x06050300, 0x0A090807, 0x02000B0B, + 0x09080604, 0x0D0D0C0B, 0x08060400, 0x110F0C0B, 0x05001111, + 0x0D0C0907, 0x12121210}, + {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A, + 0x0BB80708, 0x17701194, 0x04030201, 0x05050505, 0x01000505, + 0x07060504, 0x09090908, 0x09070400, 0x0E0D0C0B, 0x03000E0E, + 0x0D0B0907, 0x1010100F, 0x0B080500, 0x1512100D, 0x05001515, + 0x100D0B08, 0x15151512}, +}; + +static void rtw8922a_set_digital_pwr_comp(struct rtw89_dev *rtwdev, + u8 band, u8 nss, + enum rtw89_rf_path path) +{ + static const u32 ltpc_t0[2] = {R_BE_LTPC_T0_PATH0, R_BE_LTPC_T0_PATH1}; + const u32 *digital_pwr_comp; + u32 addr, val; + u32 i; + + if (nss == 1) { + if (band == RTW89_BAND_2G) + digital_pwr_comp = path == RF_PATH_A ? + rtw8922a_digital_pwr_comp_2g_s0_val[0] : + rtw8922a_digital_pwr_comp_2g_s1_val[0]; + else + digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0]; + } else { + if (band == RTW89_BAND_2G) + digital_pwr_comp = path == RF_PATH_A ? + rtw8922a_digital_pwr_comp_2g_s0_val[1] : + rtw8922a_digital_pwr_comp_2g_s1_val[1]; + else + digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1]; + } + + addr = ltpc_t0[path]; + for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) { + val = digital_pwr_comp[i]; + rtw89_phy_write32(rtwdev, addr, val); + } +} + +static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + u8 band = chan->band_type; + u8 path; + + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) + path = RF_PATH_A; + else + path = RF_PATH_B; + rtw8922a_set_digital_pwr_comp(rtwdev, band, 1, path); + } else { + rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_A); + rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_B); + } +} + +static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode) +{ + struct rtw89_entity_conf conf; + + if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) { + rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_DBCC_FA, B_DBCC_FA, 0x0); + } else if (mode == MLO_2_PLUS_0_1RF || mode == MLO_0_PLUS_2_1RF || + mode == MLO_DBCC_NOT_SUPPORT) { + rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DBCC_FA, B_DBCC_FA, 0x1); + } else { + return -EOPNOTSUPP; + } + + rtw89_entity_get_conf(rtwdev, &conf); + + rtw8922a_ctrl_afe_dac(rtwdev, conf.chans[0]->band_width, RF_PATH_A); + rtw8922a_ctrl_afe_dac(rtwdev, conf.chans[1]->band_width, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180); + + if (mode == MLO_2_PLUS_0_1RF) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xABA9); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEBA9); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEAA9); + } else if (mode == MLO_0_PLUS_2_1RF) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xAFFF); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEFFF); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEEFF); + } else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x7BAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x3BAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x3AAB); + } else { + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x180); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x0); + } + + return 0; +} + +static void rtw8922a_bb_sethw(struct rtw89_dev *rtwdev) +{ + u32 reg; + + rtw89_phy_write32_clr(rtwdev, R_EN_SND_WO_NDP, B_EN_SND_WO_NDP); + rtw89_phy_write32_clr(rtwdev, R_EN_SND_WO_NDP_C1, B_EN_SND_WO_NDP); + + rtw89_write32_mask(rtwdev, R_BE_PWR_BOOST, B_BE_PWR_CTRL_SEL, 0); + if (rtwdev->dbcc_en) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_MAC_1); + rtw89_write32_mask(rtwdev, reg, B_BE_PWR_CTRL_SEL, 0); + } + + rtw8922a_ctrl_mlo(rtwdev, rtwdev->mlo_dbcc_mode); +} + +static void rtw8922a_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en, + enum rtw89_phy_idx phy_idx) +{ + if (cck_en) { + rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, B_PD_ARBITER_OFF, + 0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, B_PD_ARBITER_OFF, + 1, phy_idx); + } +} + +static void rtw8922a_set_channel_bb(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + bool cck_en = chan->band_type == RTW89_BAND_2G; + u8 pri_sb = chan->pri_sb_idx; + + if (cck_en) + rtw8922a_ctrl_sco_cck(rtwdev, chan->primary_channel, + chan->band_width, phy_idx); + + rtw8922a_ctrl_ch(rtwdev, chan, phy_idx); + rtw8922a_ctrl_bw(rtwdev, pri_sb, chan->band_width, phy_idx); + rtw8922a_ctrl_cck_en(rtwdev, cck_en, phy_idx); + rtw8922a_spur_elimination(rtwdev, chan, phy_idx); + + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + rtw8922a_tssi_reset(rtwdev, RF_PATH_AB, phy_idx); +} + +static void rtw8922a_pre_set_channel_bb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + if (!rtwdev->dbcc_en) + return; + + if (phy_idx == RTW89_PHY_0) { + rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xABA9); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEBA9); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEAA9); + } else { + rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xAFFF); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEFFF); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEEFF); + } +} + +static void rtw8922a_post_set_channel_bb(struct rtw89_dev *rtwdev, + enum rtw89_mlo_dbcc_mode mode, + enum rtw89_phy_idx phy_idx) +{ + if (!rtwdev->dbcc_en) + return; + + rtw8922a_digital_pwr_comp(rtwdev, phy_idx); + rtw8922a_ctrl_mlo(rtwdev, mode); +} + +static void rtw8922a_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_set_channel_mac(rtwdev, chan, mac_idx); + rtw8922a_set_channel_bb(rtwdev, chan, phy_idx); + rtw8922a_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void rtw8922a_dfs_en_idx(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, enum rtw89_rf_path path, + bool en) +{ + u32 path_ofst = (path == RF_PATH_B) ? 0x100 : 0x0; + + if (en) + rtw89_phy_write32_idx(rtwdev, 0x2800 + path_ofst, BIT(1), 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, 0x2800 + path_ofst, BIT(1), 0, + phy_idx); +} + +static void rtw8922a_dfs_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_dfs_en_idx(rtwdev, phy_idx, RF_PATH_A, en); + rtw8922a_dfs_en_idx(rtwdev, phy_idx, RF_PATH_B, en); +} + +static void rtw8922a_adc_en_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool en) +{ + u32 val; + + val = rtw89_phy_read32_mask(rtwdev, R_ADC_FIFO_V1, B_ADC_FIFO_EN_V1); + + if (en) { + if (path == RF_PATH_A) + val &= ~0x1; + else + val &= ~0x2; + } else { + if (path == RF_PATH_A) + val |= 0x1; + else + val |= 0x2; + } + + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO_V1, B_ADC_FIFO_EN_V1, val); +} + +static void rtw8922a_adc_en(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) +{ + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) + rtw8922a_adc_en_path(rtwdev, RF_PATH_A, en); + else + rtw8922a_adc_en_path(rtwdev, RF_PATH_B, en); + } else { + rtw8922a_adc_en_path(rtwdev, RF_PATH_A, en); + rtw8922a_adc_en_path(rtwdev, RF_PATH_B, en); + } +} + +static +void rtw8922a_hal_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, enum rtw89_mac_idx mac_idx, + enum rtw89_band band, u32 *tx_en, bool enter) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, mac_idx, tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false); + rtw8922a_dfs_en(rtwdev, false, phy_idx); + rtw8922a_tssi_cont_en_phyidx(rtwdev, false, phy_idx); + rtw8922a_adc_en(rtwdev, false, phy_idx); + fsleep(40); + rtw8922a_bb_reset_en(rtwdev, band, false, phy_idx); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true); + rtw8922a_adc_en(rtwdev, true, phy_idx); + rtw8922a_dfs_en(rtwdev, true, phy_idx); + rtw8922a_tssi_cont_en_phyidx(rtwdev, true, phy_idx); + rtw8922a_bb_reset_en(rtwdev, band, true, phy_idx); + rtw89_chip_resume_sch_tx(rtwdev, mac_idx, *tx_en); + } +} + +static void rtw8922a_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw8922a_pre_set_channel_bb(rtwdev, phy_idx); + rtw8922a_pre_set_channel_rf(rtwdev, phy_idx); + } + + rtw8922a_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter); + + if (!enter) { + rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx); + rtw8922a_post_set_channel_rf(rtwdev, phy_idx); + } +} + +static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + memset(rfk_mcc, 0, sizeof(*rfk_mcc)); +} + +static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); + + rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58); + if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 128); +} + +static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + + __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan); + if (rtwdev->dbcc_en) + __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan); +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u32 rf_mode; + u8 path; + int ret; + + for (path = 0; path < RF_PATH_NUM_8922A; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, + 2, 5000, false, rtwdev, path, 0x00, + RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + +static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + u32 tx_en; + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, RF_AB); + + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); + rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54); + rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84); + rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20); + rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34); + rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP); +} + +static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6); +} + +static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ +} + +static void rtw8922a_rfk_track(struct rtw89_dev *rtwdev) +{ +} + +static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + s16 ref_ofdm = 0; + s16 ref_cck = 0; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL, + B_BE_PWR_REF_CTRL_OFDM, ref_ofdm); + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL, + B_BE_PWR_REF_CTRL_CCK, ref_cck); +} + +static const struct rtw89_reg_def rtw8922a_txpwr_ref[][3] = { + {{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_OFDM_REF_DBM_P0}, + { .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_CCK_REF_DBM_P0}, + { .addr = R_TSSI_K_P0, .mask = B_TSSI_K_OFDM_P0} + }, + {{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_OFDM_REF_DBM_RF1_P0}, + { .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_CCK_REF_DBM_RF1_P0}, + { .addr = R_TSSI_K_RF1_P0, .mask = B_TSSI_K_OFDM_RF1_P0} + }, +}; + +static void rtw8922a_set_txpwr_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan); + const struct rtw89_chip_info *chip = rtwdev->chip; + static const u32 path_ofst[] = {0x0, 0x100}; + const struct rtw89_reg_def *txpwr_ref; + static const s16 tssi_k_base = 0x12; + s16 tssi_k_ofst = abs(pwr_ofst) + tssi_k_base; + s16 ofst_dec[RF_PATH_NUM_8922A]; + s16 tssi_k[RF_PATH_NUM_8922A]; + s16 pwr_ref_ofst; + s16 pwr_ref = 0; + u8 i; + + if (rtwdev->hal.cv == CHIP_CAV) + pwr_ref = 16; + + pwr_ref <<= chip->txpwr_factor_rf; + pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst)); + + ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst; + ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref; + tssi_k[RF_PATH_A] = pwr_ofst > 0 ? tssi_k_base : tssi_k_ofst; + tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : tssi_k_base; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + txpwr_ref = rtw8922a_txpwr_ref[phy_idx]; + + rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i], + txpwr_ref[0].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i], + txpwr_ref[1].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i], + txpwr_ref[2].mask, tssi_k[i]); + } +} + +static void rtw8922a_bb_tx_triangular(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + u8 ctrl = en ? 0x1 : 0x0; + + rtw89_phy_write32_idx(rtwdev, R_BEDGE3, B_BEDGE_CFG, ctrl, phy_idx); +} + +static void rtw8922a_set_tx_shape(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 band = chan->band_type; + u8 tx_shape_idx; + + tx_shape_idx = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM); + if (tx_shape_idx == 0) + rtw8922a_bb_tx_triangular(rtwdev, false, phy_idx); + else + rtw8922a_bb_tx_triangular(rtwdev, true, phy_idx); +} + +static void rtw8922a_set_txpwr_sar_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_sar_parm sar_parm = { + .center_freq = chan->freq, + .force_path = true, + }; + s16 sar_rf; + s8 sar_mac; + + if (phy_idx != RTW89_PHY_0) + return; + + sar_parm.path = RF_PATH_A; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf); + + sar_parm.path = RF_PATH_B; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf); +} + +static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw8922a_set_tx_shape(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); + rtw8922a_set_txpwr_diff(rtwdev, chan, phy_idx); + rtw8922a_set_txpwr_ref(rtwdev, phy_idx); + rtw8922a_set_txpwr_sar_diff(rtwdev, chan, phy_idx); +} + +static void rtw8922a_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_set_txpwr_ref(rtwdev, phy_idx); +} + +static void rtw8922a_ctrl_trx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path tx_path, u8 tx_nss, + enum rtw89_rf_path rx_path, u8 rx_nss) +{ + enum rtw89_phy_idx phy_idx; + + for (phy_idx = RTW89_PHY_0; phy_idx <= RTW89_PHY_1; phy_idx++) { + rtw8922a_ctrl_tx_path_tmac(rtwdev, tx_path, phy_idx); + rtw8922a_ctrl_rx_path_tmac(rtwdev, rx_path, phy_idx); + rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx); + } +} + +static void rtw8922a_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A, + 0xf, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x80, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x8080, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B, + 0xf, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x80, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA10_B, 0x8080, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x34, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A, + 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x1a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x2a2a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x7a6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x26, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B, + 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x20, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA10_B, 0x2a30, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x7a6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x26, phy_idx); + } +} + +static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + enum rtw89_band band = chan->band_type; + struct rtw89_hal *hal = &rtwdev->hal; + u8 ntx_path = RF_PATH_AB; + u8 nrx_path = RF_PATH_AB; + u32 tx_en0, tx_en1; + u8 rx_nss = 2; + + if (hal->antenna_tx == RF_A) + ntx_path = RF_PATH_A; + else if (hal->antenna_tx == RF_B) + ntx_path = RF_PATH_B; + + if (hal->antenna_rx == RF_A) + nrx_path = RF_PATH_A; + else if (hal->antenna_rx == RF_B) + nrx_path = RF_PATH_B; + + if (nrx_path != RF_PATH_AB) + rx_nss = 1; + + rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true); + if (rtwdev->dbcc_en) + rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band, + &tx_en1, true); + + rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss); + + rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false); + if (rtwdev->dbcc_en) + rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band, + &tx_en1, false); +} + +static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + struct rtw89_hal *hal = &rtwdev->hal; + int th; + + /* read thermal only if debugging or thermal protection enabled */ + if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK) && + !hal->thermal_prot_th) + return 80; + + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + th = rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL_V1); + th += (s8)info->thermal_trim[rf_path]; + + return clamp_t(int, th, 0, U8_MAX); +} + +static u32 rtw8922a_chan_to_rf18_val(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH); + + switch (chan->band_type) { + case RTW89_BAND_2G: + default: + break; + case RTW89_BAND_5G: + val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) | + u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0); + break; + case RTW89_BAND_6G: + val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) | + u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0); + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + default: + break; + case RTW89_CHANNEL_WIDTH_40: + val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_80: + val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_160: + val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_320: + val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2); + break; + } + + return val; +} + +static void rtw8922a_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_module *md = &btc->mdinfo; + u8 i, j; + u8 tx_path_pos, rx_path_pos; + + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->kt_ver_adie = rtwdev->hal.acv; + md->wa_type = 0; + + md->ant.num = 2; + md->ant.single_pos = BTC_RF_S0; + + if (md->kt_ver <= 1) + md->wa_type |= BTC_WA_HFP_ZB; + + btc->cx.bt0.ant_iso_to_wl = md->ant.isolation; + btc->cx.bt1.ant_iso_to_wl = md->ant.isolation; + + md->ant.stream_cnt = 2; + md->ant.btg_pos = RF_PATH_B; + md->ant.single_pos = RF_PATH_A; + + btc->cx.bt0.band_56G_support = 0; + btc->cx.bt1.band_56G_support = 0; + btc->cx.bt0.func_type = BTC_BTF_BT; + btc->cx.bt1.func_type = BTC_BTF_NONE; + + if (md->rfe_type == 0) { + rtwdev->btc.dm.error.map.rfe_type0 = true; + return; + } + + md->ant.num = (md->rfe_type % 2) ? 2 : 3; + if (md->kt_ver == 0) + md->ant.num = 2; + + memset(btc->dm.ant_xmap, 0, sizeof(btc->dm.ant_xmap)); + + switch (md->ant.num) { + case 1: + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_V1_INTERNAL; + md->ant.btg_pos = BTC_RF_S0; + btc->dm.ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 1; + md->ant.func[0] = BTC_EFMAP_BT0; + break; + case 2: /* 2-Ant */ + default: + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_V1_INTERNAL; + btc->dm.wl_trx_nss_en = 1; + btc->dm.ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1; + md->ant.func[1] = BTC_EFMAP_BT0; + break; + case 3: /* 3-Ant, 3 different BT-configuration */ + /* WL-S0 + WL-S1 + BT0-S0 */ + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_V1_NONE; + md->ant.func[2] = BTC_EFMAP_BT0; + } + + tx_path_pos = _btc_get_rf_path_from_ant_num(btc, rtwdev->hal.tx_nss); + rx_path_pos = _btc_get_rf_path_from_ant_num(btc, rtwdev->hal.rx_nss); + /* Combine TX[7:4] and RX[3:0] into path_pos byte */ + md->ant.path_pos = ((tx_path_pos << BTC_ANT_SHIFT) & BTC_ANT_TX_MASK) | + (rx_path_pos & BTC_ANT_RX_MASK); + + switch (btc->cx.bt_ext.chip_id) { + default: + case BTC_ESOC_NONE: + memset(&btc->cx.bt_ext, 0, sizeof(struct rtw89_btc_extsoc_info)); + btc->cx.bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR_1; + btc->cx.bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO; + break; + case BTC_ESOC_8771: + btc->cx.bt_ext.func_type = BTC_BTF_THREAD; + btc->cx.bt_ext.hw_coex = BTC_EXTSOC_INTF_PTA; + btc->cx.bt_ext.rf_band_map = 0x1; /* 2.4G only */ + btc->cx.bt_ext.link_weight[BTC_BT_B2G] = 10; + btc->cx.bt_ext.profile_map[BTC_BT_B2G] |= BTC_BT_THREAD; + /* use GPIO 12~15 for Ext-4-wire-PTA */ + btc->cx.bt_ext.hpta_cfg = BIT(12) | BIT(13) | BIT(14) | BIT(15); + md->ant.func[2] = BTC_EFMAP_ZB; + break; + } + + btc->dm.ant_xmap[BTC_RF_S0][BTC_BT_EXT] = 0; + btc->dm.ant_xmap[BTC_RF_S1][BTC_BT_EXT] = 0; + + for (i = BTC_RF_S0; i <= BTC_RF_S1; i++) + for (j = BTC_BT_1ST; j <= BTC_BT_EXT; j++) + md->ant.ant_xmap[i][j] = btc->dm.ant_xmap[i][j]; + + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +static +void rtw8922a_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); +} + +static void rtw8922a_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_ant_info *ant = &btc->mdinfo.ant; + u32 wl_pri, path_min, path_max; + u8 path; + + /* for 1-Ant && 1-ss case: only 1-path */ + if (ant->num == 1) { + path_min = ant->single_pos; + path_max = path_min; + } else { + path_min = RF_PATH_A; + path_max = RF_PATH_B; + } + + path = path_min; + + for (path = path_min; path <= path_max; path++) { + /* set DEBUG_LUT_RFMODE_MASK = 1 to start trx-mask-setup */ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, BIT(17)); + + /* if GNT_WL=0 && BT=SS_group --> WL Tx/Rx = THRU */ + rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_SS_GROUP, 0x5ff); + + /* if GNT_WL=0 && BT=Rx_group --> WL-Rx = THRU + WL-Tx = MASK */ + rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_RX_GROUP, 0x5df); + + /* if GNT_WL = 0 && BT = Tx_group --> + * Shared-Ant && BTG-path:WL mask(0x55f), others:WL THRU(0x5ff) + */ + if (btc->ant_type == BTC_ANT_SHARED && btc->btg_pos == path) + rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x55f); + else + rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x5ff); + + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0); + } + + /* set WL PTA Hi-Pri: Ack-Tx, beacon-tx, Trig-frame-Tx, Null-Tx*/ + wl_pri = B_BTC_RSP_ACK_HI | B_BTC_TX_BCN_HI | B_BTC_TX_TRI_HI | + B_BTC_TX_NULL_HI; + rtw89_write32(rtwdev, R_BTC_COEX_WL_REQ_BE, wl_pri); + + /* set PTA break table */ + rtw89_write32(rtwdev, R_BE_BT_BREAK_TABLE, BTC_BREAK_PARAM); + + /* ZB coex table init for HFP PTA req-cmd bit-4 define issue COEX-900*/ + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, 0xda5a5a5a); + + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, 0xda5a5a5a); + + rtw89_write32(rtwdev, R_BTC_ZB_BREAK_TBL, 0xf0ffffff); +} + +static void +rtw8922a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0)); + u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16)); + + switch (ctrl_all_time) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_VAL, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_EN, 0x1); + break; + } + + switch (ctrl_gnt_bt) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, + B_BE_PWR_BT_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, + B_BE_PWR_BT_VAL, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, + B_BE_PWR_BT_VAL, ctrl_gnt_bt); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, + B_BE_PWR_BT_EN, 0x1); + break; + } +} + +static +s8 rtw8922a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + return clamp_t(s8, val, -100, 0) + 100; +} + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8922a_rf_ul_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {6, 1, 0, 7}, + {13, 1, 0, 7}, + {13, 1, 0, 7} +}; + +static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8922a_rf_dl_v0[] = { + {255, 0, 0, 7}, /* 0 -> original */ + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ + {255, 1, 0, 7}, + {255, 1, 0, 7}, + {255, 1, 0, 7} +}; + +static const u8 rtw89_btc_8922a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; +static const u8 rtw89_btc_8922a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922a_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe320), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe324), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe328), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe32c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a2c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a50), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x660), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x1660), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x418c), + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x518c), +}; + +static +void rtw8922a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + /* Feature move to firmware */ +} + +static +void rtw8922a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + if (!state) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x01018); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x01018); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); + } else { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x09018); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x09018); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); + } +} + +static void rtw8922a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ +} + +static void rtw8922a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 chan_idx = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan_idx == 0) + return; + + rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void rtw8922a_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + u8 *rx_power = phy_ppdu->rssi; + + if (!status->signal) + status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], + rx_power[RF_PATH_B])); + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8922a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +static void rtw8922a_convert_rpl_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + /* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */ + static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0}; + u8 *rssi = phy_ppdu->rssi; + u8 compensate = 0; + u16 rpl_tmp; + u8 i; + + if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate)) + compensate = bw_compensate[phy_ppdu->bw_idx]; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + if (!(phy_ppdu->rx_path_en & BIT(i))) { + rssi[i] = 0; + phy_ppdu->rpl_path[i] = 0; + phy_ppdu->rpl_fd[i] = 0; + } + if (phy_ppdu->rate >= RTW89_HW_RATE_OFDM6) { + rpl_tmp = phy_ppdu->rpl_fd[i]; + if (rpl_tmp) + rpl_tmp += compensate; + + phy_ppdu->rpl_path[i] = rpl_tmp; + } + rssi[i] = phy_ppdu->rpl_path[i]; + } + + phy_ppdu->rssi_avg = phy_ppdu->rpl_avg; +} + +static void rtw8922a_phy_rpt_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status) +{ + if (desc_info->rssi <= 0x1 || (desc_info->rssi >> 2) > MAX_RSSI) + return; + + rx_status->signal = (desc_info->rssi >> 2) - MAX_RSSI; +} + +static int rtw8922a_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write8_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_FEN_BBPLAT_RSTB | B_BE_FEN_BB_IP_RSTN); + rtw89_write32(rtwdev, R_BE_DMAC_SYS_CR32B, 0x7FF97FF9); + + return 0; +} + +static int rtw8922a_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_FEN_BBPLAT_RSTB | B_BE_FEN_BB_IP_RSTN); + + return 0; +} + +static const struct rtw89_chanctx_listener rtw8922a_chanctx_listener = { + .callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8922a = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_NET_DETECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, + .max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID, +}; +#endif + +static const struct rtw89_chip_ops rtw8922a_chip_ops = { + .enable_bb_rf = rtw8922a_mac_enable_bb_rf, + .disable_bb_rf = rtw8922a_mac_disable_bb_rf, + .bb_preinit = rtw8922a_bb_preinit, + .bb_postinit = rtw8922a_bb_postinit, + .bb_reset = rtw8922a_bb_reset, + .bb_sethw = rtw8922a_bb_sethw, + .read_rf = rtw89_phy_read_rf_v2, + .write_rf = rtw89_phy_write_rf_v2, + .set_channel = rtw8922a_set_channel, + .set_channel_help = rtw8922a_set_channel_help, + .read_efuse = rtw8922a_read_efuse, + .read_phycap = rtw8922a_read_phycap, + .fem_setup = NULL, + .data_setup = NULL, + .rfe_gpio = NULL, + .rfk_hw_init = rtw8922a_rfk_hw_init, + .rfk_init = rtw8922a_rfk_init, + .rfk_init_late = rtw8922a_rfk_init_late, + .rfk_channel = rtw8922a_rfk_channel, + .rfk_band_changed = rtw8922a_rfk_band_changed, + .rfk_scan = rtw8922a_rfk_scan, + .rfk_track = rtw8922a_rfk_track, + .power_trim = rtw8922a_power_trim, + .set_txpwr = rtw8922a_set_txpwr, + .set_txpwr_ctrl = rtw8922a_set_txpwr_ctrl, + .init_txpwr_unit = NULL, + .get_thermal = rtw8922a_get_thermal, + .chan_to_rf18_val = rtw8922a_chan_to_rf18_val, + .ctrl_btg_bt_rx = rtw8922a_ctrl_btg_bt_rx, + .query_ppdu = rtw8922a_query_ppdu, + .convert_rpl_to_rssi = rtw8922a_convert_rpl_to_rssi, + .phy_rpt_to_rssi = rtw8922a_phy_rpt_to_rssi, + .ctrl_nbtg_bt_tx = rtw8922a_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8922a_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = NULL, + .digital_pwr_comp = rtw8922a_digital_pwr_comp, + .calc_rx_gain_normal = NULL, + .path_diff_update = NULL, + .pwr_on_func = rtw8922a_pwr_on_func, + .pwr_off_func = rtw8922a_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc_v2, + .fill_txdesc = rtw89_core_fill_txdesc_v2, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v2, + .get_ch_dma = {rtw89_core_get_ch_dma, + rtw89_core_get_ch_dma_v2, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v2, + .mac_cfg_gnt = rtw89_mac_cfg_gnt_v2, + .stop_sch_tx = rtw89_mac_stop_sch_tx_v2, + .resume_sch_tx = rtw89_mac_resume_sch_tx_v2, + .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v2, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl_g7, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl_g7, + .h2c_ampdu_cmac_tbl = rtw89_fw_h2c_ampdu_cmac_tbl_g7, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl_g7, + .h2c_punctured_cmac_tbl = rtw89_fw_h2c_punctured_cmac_tbl_g7, + .h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v2, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon_be, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, + + .btc_set_rfe = rtw8922a_btc_set_rfe, + .btc_init_cfg = rtw8922a_btc_init_cfg, + .btc_set_wl_pri = NULL, + .btc_set_wl_txpwr_ctrl = rtw8922a_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8922a_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8922a_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8922a_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8922a_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +const struct rtw89_chip_info rtw8922a_chip_info = { + .chip_id = RTL8922A, + .chip_gen = RTW89_CHIP_BE, + .ops = &rtw8922a_chip_ops, + .mac_def = &rtw89_mac_gen_be, + .phy_def = &rtw89_phy_gen_be, + .fw_def = { + .fw_basename = RTW8922A_FW_BASENAME, + .fw_format_max = RTW8922A_FW_FORMAT_MAX, + .fw_b_aid = 0, + }, + .try_ce_fw = false, + .bbmcu_nr = 1, + .needed_fw_elms = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS, + .fw_blacklist = &rtw89_fw_blacklist_default, + .fifo_size = 589824, + .small_fifo_size = false, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 8000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, + .dis_2g_40m_ul_ofdma = false, + .rsvd_ple_ofst = 0x8f800, + .qta_def = { + .hfc_param_ini = {rtw8922a_hfc_param_ini_pcie, + rtw8922a_hfc_param_ini_usb2, + rtw8922a_hfc_param_ini_usb3, + NULL}, + .dle_mem = {rtw8922a_dle_mem_pcie, + rtw8922a_dle_mem_usb2, + rtw8922a_dle_mem_usb3, + NULL}, + }, + .wde_qempty_acq_grpnum = 4, + .wde_qempty_mgq_grpsel = 4, + .rf_base_addr = {0xe000, 0xf000}, + .thermal_th = {0xad, 0xb4}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = NULL, + .bb_gain_table = NULL, + .rf_table = {}, + .nctl_table = NULL, + .nctl_post_table = NULL, + .dflt_parms = NULL, /* load parm from fw */ + .rfe_parms_conf = NULL, /* load parm from fw */ + .chanctx_listener = &rtw8922a_chanctx_listener, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8922a_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = 32, + .support_link_num = 2, + .support_chanctx_num = 2, + .support_rnr = true, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ) | + BIT(NL80211_BAND_6GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160), + .support_unii4 = true, + .support_ant_gain = true, + .support_tas = true, + .support_sar_by_ant = true, + .support_noise = false, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = false, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = false, + .hw_sec_hdr = true, + .hw_mgmt_tx_encrypt = true, + .hw_tkip_crypto = true, + .hw_mlo_bmc_crypto = false, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 20, + .scam_num = 32, + .bacam_num = 24, + .bacam_dynamic_num = 8, + .bacam_ver = RTW89_BACAM_V1, + .addrcam_ver = 0, + .ppdu_max_usr = 16, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 0x1300, + .logical_efuse_size = 0x70000, + .limit_efuse_size = 0x40000, + .dav_phy_efuse_size = 0, + .dav_log_efuse_size = 0, + .efuse_blocks = rtw8922a_efuse_blocks, + .phycap_addr = 0x1700, + .phycap_size = 0x38, + .para_ver = 0xf, + .wlcx_desired = 0x07110000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8922a_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8922a_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8922a_mon_reg), + .mon_reg = rtw89_btc_8922a_mon_reg, + .rf_para_ulink_v0 = rtw89_btc_8922a_rf_ul_v0, + .rf_para_dlink_v0 = rtw89_btc_8922a_rf_dl_v0, + .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8922a_rf_ul_v0), + .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8922a_rf_dl_v0), + .rf_para_ulink_v9 = NULL, + .rf_para_dlink_v9 = NULL, + .rf_para_ulink_num_v9 = 0, + .rf_para_dlink_num_v9 = 0, + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_G7, + .hci_func_en_addr = R_BE_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_rxdesc_short_v2), + .txwd_body_size = sizeof(struct rtw89_txwd_body_v2), + .txwd_info_size = sizeof(struct rtw89_txwd_info_v2), + .h2c_ctrl_reg = R_BE_H2CREG_CTRL, + .h2c_counter_reg = {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8922a_h2c_regs, + .c2h_ctrl_reg = R_BE_C2HREG_CTRL, + .c2h_counter_reg = {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8922a_c2h_regs, + .page_regs = &rtw8922a_page_regs, + .wow_reason_reg = rtw8922a_wow_wakeup_regs, + .cfo_src_fd = true, + .cfo_hw_comp = true, + .dcfo_comp = NULL, + .dcfo_comp_sft = 0, + .nhm_report = NULL, + .nhm_th = NULL, + .imr_info = NULL, + .imr_dmac_table = &rtw8922a_imr_dmac_table, + .imr_cmac_table = &rtw8922a_imr_cmac_table, + .rrsr_cfgs = &rtw8922a_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2}, + .bss_clr_map_reg = R_BSS_CLR_MAP_V2, + .rfkill_init = &rtw8922a_rfkill_regs, + .rfkill_get = {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9}, + .btc_sb = {{{R_BE_SCOREBOARD, R_BE_SCOREBOARD},}}, + .dma_ch_mask = 0, + .edcca_regs = &rtw8922a_edcca_regs, + .pmac_regs = &rtw8922a_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8922a, +#endif + .xtal_info = NULL, + .default_quirks = 0, + .txtime_limit_2ghz = 0, +}; +EXPORT_SYMBOL(rtw8922a_chip_info); + +const struct rtw89_chip_variant rtw8922ae_vs_variant = { + .no_mcs_12_13 = true, + .fw_min_ver_code = RTW89_FW_VER_CODE(0, 35, 54, 0), + .fw_def_override = NULL, + .qta_def_override = NULL, +}; +EXPORT_SYMBOL(rtw8922ae_vs_variant); + +MODULE_FIRMWARE(RTW8922A_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11be wireless 8922A driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.h b/drivers/net/wireless/realtek/rtw89/rtw8922a.h new file mode 100644 index 000000000..a29cfa5b4 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2023 Realtek Corporation + */ + +#ifndef __RTW89_8922A_H__ +#define __RTW89_8922A_H__ + +#include "core.h" + +#define RF_PATH_NUM_8922A 2 +#define BB_PATH_NUM_8922A 2 + +struct rtw8922a_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; + u8 bw_diff_5g[10]; +} __packed; + +struct rtw8922a_rx_gain { + u8 _2g_ofdm; + u8 _2g_cck; + u8 _5g_low; + u8 _5g_mid; + u8 _5g_high; +} __packed; + +struct rtw8922a_rx_gain_6g { + u8 _6g_l0; + u8 _6g_l1; + u8 _6g_m0; + u8 _6g_m1; + u8 _6g_h0; + u8 _6g_h1; + u8 _6g_uh0; + u8 _6g_uh1; +} __packed; + +struct rtw8922a_efuse { + u8 country_code[2]; + u8 rsvd[0xe]; + struct rtw8922a_tssi_offset path_a_tssi; + struct rtw8922a_tssi_offset path_b_tssi; + u8 rsvd1[0x54]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd2[0x7]; + u8 board_info; + u8 rsvd3[0x8]; + u8 rfe_type; + u8 rsvd4[0x5]; + u8 path_a_therm; + u8 path_b_therm; + u8 rsvd5[0x2]; + struct rtw8922a_rx_gain rx_gain_a; + struct rtw8922a_rx_gain rx_gain_b; + u8 rsvd6[0x22]; + u8 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd7[0xa]; + u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd8[0xa]; + u8 bw40_1s_tssi_6g_c[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd9[0xa]; + u8 bw40_1s_tssi_6g_d[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd10[0xa]; + struct rtw8922a_rx_gain_6g rx_gain_6g_a; + struct rtw8922a_rx_gain_6g rx_gain_6g_b; +} __packed; + +extern const struct rtw89_chip_info rtw8922a_chip_info; +extern const struct rtw89_chip_variant rtw8922ae_vs_variant; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c new file mode 100644 index 000000000..1e2b563f2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include "chan.h" +#include "debug.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8922a.h" +#include "rtw8922a_rfk.h" + +static void rtw8922a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + static const u32 tssi_trk_man[2] = {R_TSSI_PWR_P0, R_TSSI_PWR_P1}; + + if (en) + rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 0); + else + rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 1); +} + +void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) +{ + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) + rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A); + else + rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B); + } else { + rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A); + rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B); + } +} + +static +void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1}; + struct rtw89_hal *hal = &rtwdev->hal; + u32 rf_reg[RF_PATH_NUM_8922A][2]; + u8 synpath; + u32 rf18; + u8 kpath; + u8 path; + u8 i; + + rf_reg[RF_PATH_A][0] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[0], RFREG_MASK); + rf_reg[RF_PATH_A][1] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[1], RFREG_MASK); + rf_reg[RF_PATH_B][0] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[0], RFREG_MASK); + rf_reg[RF_PATH_B][1] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[1], RFREG_MASK); + + kpath = rtw89_phy_get_kpath(rtwdev, phy); + synpath = rtw89_phy_get_syn_sel(rtwdev, phy); + + rf18 = rtw89_read_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK); + if (rf18 == INV_RF_DATA) { + rtw89_warn(rtwdev, "[RFK] Invalid RF18 value\n"); + return; + } + + for (path = 0; path < RF_PATH_NUM_8922A; path++) { + if (!(kpath & BIT(path))) + continue; + + for (i = 0; i < 2; i++) { + if (rf_reg[path][i] == INV_RF_DATA) { + rtw89_warn(rtwdev, + "[RFK] Invalid RF_0x18 for Path-%d\n", path); + return; + } + + rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW_V2 | + RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg[path][i] |= rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + rtw89_write_rf(rtwdev, path, rf_addr[i], + RFREG_MASK, rf_reg[path][i]); + fsleep(100); + } + } + + if (hal->cv != CHIP_CAV) + return; + + if (chan->band_type == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); + } else { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c190); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); + } +} + +void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan); +} + +enum _rf_syn_pow { + RF_SYN_ON_OFF, + RF_SYN_OFF_ON, + RF_SYN_ALLON, + RF_SYN_ALLOFF, +}; + +static void rtw8922a_set_syn01_cav(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) +{ + if (syn == RF_SYN_ALLON) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); + } else if (syn == RF_SYN_ON_OFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0); + } else if (syn == RF_SYN_OFF_ON) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); + } else if (syn == RF_SYN_ALLOFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0); + } +} + +static void rtw8922a_set_syn01_cbv(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) +{ + if (syn == RF_SYN_ALLON) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); + } else if (syn == RF_SYN_ON_OFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); + } else if (syn == RF_SYN_OFF_ON) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); + } else if (syn == RF_SYN_ALLOFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); + } +} + +static void rtw8922a_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn); + + if (hal->cv == CHIP_CAV) + rtw8922a_set_syn01_cav(rtwdev, syn); + else + rtw8922a_set_syn01_cbv(rtwdev, syn); +} + +static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx) +{ + u32 tmp; + + if (idx > 2) { + rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx); + return; + } + + if (kpath & RF_A) { + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1, idx); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_MDPD_V1, idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); + + tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(1)); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G5, tmp); + } + + if (kpath & RF_B) { + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1, idx); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_MDPD_V1, idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); + + tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G3, tmp); + tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(1)); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G5, tmp); + } +} + +static u8 rtw8922a_chlk_reload_sel_tbl_v0(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + u8 tbl_sel; + + for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { + struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; + + p->ch = rfk_mcc->data[path].ch[tbl_sel]; + + p->has_band = true; + p->band = rfk_mcc->data[path].band[tbl_sel]; + + p->has_bw = true; + p->bw = rfk_mcc->data[path].bw[tbl_sel]; + } + + tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->data[path].ch[tbl_sel] = chan->channel; + rfk_mcc->data[path].band[tbl_sel] = chan->band_type; + rfk_mcc->data[path].bw[tbl_sel] = chan->band_width; + rfk_mcc->data[path].rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + rfk_mcc->data[path].table_idx = tbl_sel; + + return tbl_sel; +} + +static u8 rtw8922a_chlk_reload_sel_tbl_v1(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; + u8 tbl_sel; + + for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { + struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; + + p->ch = rfk_mcc->ch[tbl_sel]; + + p->has_band = true; + p->band = rfk_mcc->band[tbl_sel]; + + p->has_bw = true; + p->bw = rfk_mcc->bw[tbl_sel]; + } + + tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[tbl_sel] = chan->channel; + rfk_mcc->band[tbl_sel] = chan->band_type; + rfk_mcc->bw[tbl_sel] = chan->band_width; + rfk_mcc->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + /* shared table array, but tbl_sel can be independent by path */ + rfk_mcc[path].table_idx = tbl_sel; + + return tbl_sel; +} + +static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) + return rtw8922a_chlk_reload_sel_tbl_v1(rtwdev, chan, path); + else + return rtw8922a_chlk_reload_sel_tbl_v0(rtwdev, chan, path); +} + +static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_conf conf; + u8 s0_tbl, s1_tbl; + + rtw89_entity_get_conf(rtwdev, &conf); + + s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, conf.chans[0], 0); + s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, conf.chans[1], 1); + + rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl); + rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl); +} + +static void rtw8922a_rfk_mlo_ctrl(struct rtw89_dev *rtwdev) +{ + enum _rf_syn_pow syn_pow; + + if (!rtwdev->dbcc_en) + goto set_rfk_reload; + + switch (rtwdev->mlo_dbcc_mode) { + case MLO_0_PLUS_2_1RF: + syn_pow = RF_SYN_OFF_ON; + break; + case MLO_0_PLUS_2_2RF: + case MLO_1_PLUS_1_2RF: + case MLO_2_PLUS_0_1RF: + case MLO_2_PLUS_0_2RF: + case MLO_2_PLUS_2_2RF: + case MLO_DBCC_NOT_SUPPORT: + default: + syn_pow = RF_SYN_ON_OFF; + break; + case MLO_1_PLUS_1_1RF: + case DBCC_LEGACY: + syn_pow = RF_SYN_ALLON; + break; + } + + rtw8922a_set_syn01(rtwdev, syn_pow); + +set_rfk_reload: + rtw8922a_chlk_reload(rtwdev); +} + +static void rtw8922a_rfk_pll_init(struct rtw89_dev *rtwdev) +{ + int ret; + u8 tmp; + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_PLL_1, &tmp); + if (ret) + return; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, tmp | 0xf8, 0xFF); + if (ret) + return; + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_APBT, &tmp); + if (ret) + return; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_APBT, tmp & ~0x60, 0xFF); + if (ret) + return; + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, &tmp); + if (ret) + return; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, tmp | 0x38, 0xFF); + if (ret) + return; +} + +void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev) +{ + if (rtwdev->dbcc_en) + rtw8922a_rfk_mlo_ctrl(rtwdev); + + rtw8922a_rfk_pll_init(rtwdev); +} + +void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + bool mlo_1_1; + + if (!rtwdev->dbcc_en) + return; + + mlo_1_1 = rtw89_is_mlo_1_1(rtwdev); + if (mlo_1_1) + rtw8922a_set_syn01(rtwdev, RF_SYN_ALLON); + else if (phy_idx == RTW89_PHY_0) + rtw8922a_set_syn01(rtwdev, RF_SYN_ON_OFF); + else + rtw8922a_set_syn01(rtwdev, RF_SYN_OFF_ON); + + fsleep(1000); +} + +void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw8922a_rfk_mlo_ctrl(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h new file mode 100644 index 000000000..66bdd57c1 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2023 Realtek Corporation + */ + +#ifndef __RTW89_8922A_RFK_H__ +#define __RTW89_8922A_RFK_H__ + +#include "core.h" + +void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx); +void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev); +void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c new file mode 100644 index 000000000..e82c866df --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2023 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8922a.h" + +static const struct rtw89_pci_ssid_quirk rtw8922a_pci_ssid_quirks[] = { + {RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0x8922, 0x10EC, 0xA891, DELL), + .bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_120C)}, + {}, +}; + +static const struct rtw89_pci_info rtw8922a_pci_info = { + .gen_def = &rtw89_pci_gen_be, + .isr_def = &rtw89_pci_isr_be, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_V1_256B, + .rx_burst = MAC_AX_RX_BURST_V1_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_ENABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_DEF, + .rx_ring_eq_is_full = true, + .check_rx_tag = true, + .no_rxbd_fs = true, + .group_bd_addr = false, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt), + + .init_cfg_reg = R_BE_HAXI_INIT_CFG1, + .txhci_en_bit = B_BE_TXDMA_EN, + .rxhci_en_bit = B_BE_RXDMA_EN, + .rxbd_mode_bit = B_BE_RXQ_RXBD_MODE_MASK, + .exp_ctrl_reg = R_BE_HAXI_EXP_CTRL_V1, + .max_tag_num_mask = B_BE_MAX_TAG_NUM_MASK, + .rxbd_rwptr_clr_reg = R_BE_RXBD_RWPTR_CLR1_V1, + .txbd_rwptr_clr2_reg = R_BE_TXBD_RWPTR_CLR1, + .dma_io_stop = {R_BE_HAXI_INIT_CFG1, B_BE_STOP_AXI_MST}, + .dma_stop1 = {R_BE_HAXI_DMA_STOP1, B_BE_TX_STOP1_MASK}, + .dma_stop2 = {0}, + .dma_busy1 = {R_BE_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK_BE}, + .dma_busy2_reg = 0, + .dma_busy3_reg = R_BE_HAXI_DMA_BUSY1, + + .rpwm_addr = R_BE_PCIE_HRPWM, + .cpwm_addr = R_BE_PCIE_CRPWM, + .mit_addr = R_BE_PCIE_MIT_CH_EN, + .wp_sel_addr = R_BE_WP_ADDR_H_SEL0_3_V1, + .tx_dma_ch_mask = 0, + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set_be, + .bd_ram_table = NULL, + + .ltr_set = rtw89_pci_ltr_set_v2, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, + .parse_rpp = rtw89_pci_parse_rpp, + .config_intr_mask = rtw89_pci_config_intr_mask_v2, + .enable_intr = rtw89_pci_enable_intr_v2, + .disable_intr = rtw89_pci_disable_intr_v2, + .recognize_intrs = rtw89_pci_recognize_intrs_v2, + + .ssid_quirks = rtw8922a_pci_ssid_quirks, +}; + +static const struct rtw89_driver_info rtw89_8922ae_info = { + .chip = &rtw8922a_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8922a_pci_info, + }, +}; + +static const struct rtw89_driver_info rtw89_8922ae_vs_info = { + .chip = &rtw8922a_chip_info, + .variant = &rtw8922ae_vs_variant, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8922a_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8922ae_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8922), + .driver_data = (kernel_ulong_t)&rtw89_8922ae_info, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x892B), + .driver_data = (kernel_ulong_t)&rtw89_8922ae_vs_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8922ae_id_table); + +static struct pci_driver rtw89_8922ae_driver = { + .name = "rtw89_8922ae", + .id_table = rtw89_8922ae_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops_be, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8922ae_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AE/8922AE-VS driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922au.c b/drivers/net/wireless/realtek/rtw89/rtw8922au.c new file mode 100644 index 000000000..56c79b1ec --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922au.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include +#include +#include "rtw8922a.h" +#include "usb.h" + +static const struct rtw89_usb_info rtw8922a_usb_info = { + .usb_host_request_2 = 0, + .usb_wlan0_1 = 0, + .hci_func_en = 0, + .usb3_mac_npi_config_intf_0 = 0, + .usb_endpoint_0 = 0, + .usb_endpoint_2 = 0, + .rx_agg_alignment = 16, + .bulkout_id = { + [RTW89_DMA_ACH0] = 3, + [RTW89_DMA_ACH2] = 5, + [RTW89_DMA_ACH4] = 4, + [RTW89_DMA_ACH6] = 6, + [RTW89_DMA_B0MG] = 0, + [RTW89_DMA_B0HI] = 0, + [RTW89_DMA_B1MG] = 1, + [RTW89_DMA_B1HI] = 1, + [RTW89_DMA_H2C] = 2, + }, +}; + +static const struct rtw89_driver_info rtw89_8922au_info = { + .chip = &rtw8922a_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .usb = &rtw8922a_usb_info, + }, +}; + +static const struct usb_device_id rtw_8922au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03ef, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0502, 0x76d7, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4025, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4026, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1bcf, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1bd2, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8912, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0xda0e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0101, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x3822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x4822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x5822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8922au_info }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8922au_id_table); + +static struct usb_driver rtw_8922au_driver = { + .name = KBUILD_MODNAME, + .id_table = rtw_8922au_id_table, + .probe = rtw89_usb_probe, + .disconnect = rtw89_usb_disconnect, +}; +module_usb_driver(rtw_8922au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AU driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c new file mode 100644 index 000000000..142e693c8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c @@ -0,0 +1,3865 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include "chan.h" +#include "coex.h" +#include "debug.h" +#include "efuse.h" +#include "mac.h" +#include "phy.h" +#include "reg.h" +#include "rtw8922d.h" +#include "rtw8922d_rfk.h" +#include "sar.h" +#include "util.h" + +#define RTW8922D_FW_FORMAT_MAX 0 +#define RTW8922D_FW_BASENAME "rtw89/rtw8922d_fw" +#define RTW8922D_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8922D_FW_BASENAME, RTW8922D_FW_FORMAT_MAX) + +#define RTW8922DS_FW_FORMAT_MAX 0 +#define RTW8922DS_FW_BASENAME "rtw89/rtw8922ds_fw" +#define RTW8922DS_MODULE_FIRMWARE \ + RTW89_GEN_MODULE_FWNAME(RTW8922DS_FW_BASENAME, RTW8922DS_FW_FORMAT_MAX) + +static const struct rtw89_hfc_ch_cfg rtw8922d_hfc_chcfg_pcie[] = { + {2, 732, 0}, /* ACH 0 */ + {0, 730, 0}, /* ACH 1 */ + {2, 732, 0}, /* ACH 2 */ + {0, 730, 0}, /* ACH 3 */ + {2, 732, 0}, /* ACH 4 */ + {0, 730, 0}, /* ACH 5 */ + {2, 732, 0}, /* ACH 6 */ + {0, 730, 0}, /* ACH 7 */ + {2, 732, 0}, /* B0MGQ */ + {0, 730, 0}, /* B0HIQ */ + {2, 732, 0}, /* B1MGQ */ + {0, 730, 0}, /* B1HIQ */ + {0, 0, 0}, /* GCQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922d_hfc_pubcfg_pcie = { + 742, /* Group 0 */ + 0, /* Group 1 */ + 742, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8922d_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8922d_hfc_chcfg_pcie, &rtw8922d_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DBCC] = {rtw8922d_hfc_chcfg_pcie, &rtw8922d_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8922d_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size22_v1, + &rtw89_mac_size.ple_size29_v1, &rtw89_mac_size.wde_qt23_v1, + &rtw89_mac_size.wde_qt23_v1, &rtw89_mac_size.ple_qt64_v2, + &rtw89_mac_size.ple_qt65_v2, &rtw89_mac_size.ple_rsvd_qt9, + &rtw89_mac_size.rsvd0_size17, &rtw89_mac_size.rsvd1_size3, + &rtw89_mac_size.dle_input28}, + [RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size22_v1, + &rtw89_mac_size.ple_size29_v1, &rtw89_mac_size.wde_qt23_v1, + &rtw89_mac_size.wde_qt23_v1, &rtw89_mac_size.ple_qt64_v2, + &rtw89_mac_size.ple_qt65_v2, &rtw89_mac_size.ple_rsvd_qt9, + &rtw89_mac_size.rsvd0_size17, &rtw89_mac_size.rsvd1_size3, + &rtw89_mac_size.dle_input28}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18_v1, + &rtw89_mac_size.ple_size22_v1, &rtw89_mac_size.wde_qt3, + &rtw89_mac_size.wde_qt3, &rtw89_mac_size.ple_qt5_v2, + &rtw89_mac_size.ple_qt47_v2, &rtw89_mac_size.ple_rsvd_qt1, + &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2, + &rtw89_mac_size.dle_input3}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const struct rtw89_hfc_ch_cfg rtw8922ds_hfc_chcfg_pcie[] = { + {2, 603, 0}, /* ACH 0 */ + {0, 601, 0}, /* ACH 1 */ + {2, 603, 0}, /* ACH 2 */ + {0, 601, 0}, /* ACH 3 */ + {2, 603, 0}, /* ACH 4 */ + {0, 601, 0}, /* ACH 5 */ + {2, 603, 0}, /* ACH 6 */ + {0, 601, 0}, /* ACH 7 */ + {2, 603, 0}, /* B0MGQ */ + {0, 601, 0}, /* B0HIQ */ + {2, 603, 0}, /* B1MGQ */ + {0, 601, 0}, /* B1HIQ */ + {0, 0, 0}, /* GCQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8922ds_hfc_pubcfg_pcie = { + 613, /* Group 0 */ + 0, /* Group 1 */ + 613, /* Public Max */ + 0, /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8922ds_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8922ds_hfc_chcfg_pcie, &rtw8922ds_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DBCC] = {rtw8922ds_hfc_chcfg_pcie, &rtw8922ds_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + +static const struct rtw89_dle_mem rtw8922ds_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size16_v1, + &rtw89_mac_size.ple_size20_v1, &rtw89_mac_size.wde_qt19_v1, + &rtw89_mac_size.wde_qt19_v1, &rtw89_mac_size.ple_qt44_v2, + &rtw89_mac_size.ple_qt45_v2, &rtw89_mac_size.ple_rsvd_qt9, + &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2, + &rtw89_mac_size.dle_input20}, + [RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size16_v1, + &rtw89_mac_size.ple_size20_v1, &rtw89_mac_size.wde_qt19_v1, + &rtw89_mac_size.wde_qt19_v1, &rtw89_mac_size.ple_qt44_v2, + &rtw89_mac_size.ple_qt45_v2, &rtw89_mac_size.ple_rsvd_qt9, + &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2, + &rtw89_mac_size.dle_input20}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18_v1, + &rtw89_mac_size.ple_size22_v1, &rtw89_mac_size.wde_qt3, + &rtw89_mac_size.wde_qt3, &rtw89_mac_size.ple_qt5_v2, + &rtw89_mac_size.ple_qt47_v2, &rtw89_mac_size.ple_rsvd_qt1, + &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2, + &rtw89_mac_size.dle_input3}, + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, + NULL}, +}; + +static const u32 rtw8922d_h2c_regs[RTW89_H2CREG_MAX] = { + R_BE_H2CREG_DATA0, R_BE_H2CREG_DATA1, R_BE_H2CREG_DATA2, + R_BE_H2CREG_DATA3 +}; + +static const u32 rtw8922d_c2h_regs[RTW89_H2CREG_MAX] = { + R_BE_C2HREG_DATA0, R_BE_C2HREG_DATA1, R_BE_C2HREG_DATA2, + R_BE_C2HREG_DATA3 +}; + +static const u32 rtw8922d_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = { + R_BE_DBG_WOW, R_BE_DBG_WOW, +}; + +static const struct rtw89_page_regs rtw8922d_page_regs = { + .hci_fc_ctrl = R_BE_HCI_FC_CTRL, + .ch_page_ctrl = R_BE_CH_PAGE_CTRL, + .ach_page_ctrl = R_BE_CH0_PAGE_CTRL, + .ach_page_info = R_BE_CH0_PAGE_INFO, + .pub_page_info3 = R_BE_PUB_PAGE_INFO3, + .pub_page_ctrl1 = R_BE_PUB_PAGE_CTRL1, + .pub_page_ctrl2 = R_BE_PUB_PAGE_CTRL2, + .pub_page_info1 = R_BE_PUB_PAGE_INFO1, + .pub_page_info2 = R_BE_PUB_PAGE_INFO2, + .wp_page_ctrl1 = R_BE_WP_PAGE_CTRL1, + .wp_page_ctrl2 = R_BE_WP_PAGE_CTRL2, + .wp_page_info1 = R_BE_WP_PAGE_INFO1, +}; + +static const struct rtw89_reg_imr rtw8922d_imr_dmac_regs[] = { + {R_BE_HCI_BUF_IMR, B_BE_HCI_BUF_IMR_CLR, B_BE_HCI_BUF_IMR_SET}, + {R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR_V1, B_BE_DISP_HOST_IMR_SET_V1}, + {R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR_V1, B_BE_DISP_CPU_IMR_SET_V1}, + {R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR_V1, B_BE_DISP_OTHER_IMR_SET_V1}, + {R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET}, + {R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET}, + {R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET}, + {R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET}, + {R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET}, + {R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET}, + {R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET}, + {R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET}, + {R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET}, + {R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR, + B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET}, + {R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR, + B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET}, + {R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET}, + {R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR, + B_BE_BBRPT_CHINFO_ERR_IMR_SET}, + {R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET}, + {R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET}, + {R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET}, + {R_BE_PLRLS_ERR_IMR_V1, B_BE_PLRLS_ERR_IMR_V1_CLR, B_BE_PLRLS_ERR_IMR_V1_SET}, + {R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET}, +}; + +static const struct rtw89_imr_table rtw8922d_imr_dmac_table = { + .regs = rtw8922d_imr_dmac_regs, + .n_regs = ARRAY_SIZE(rtw8922d_imr_dmac_regs), +}; + +static const struct rtw89_reg_imr rtw8922d_imr_cmac_regs[] = { + {R_BE_RESP_IMR, B_BE_RESP_IMR_CLR_V1, B_BE_RESP_IMR_SET_V1}, + {R_BE_RESP_IMR1, B_BE_RESP_IMR1_CLR, B_BE_RESP_IMR1_SET}, + {R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR_V1, B_BE_RX_ERROR_FLAG_IMR_SET_V1}, + {R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET}, + {R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET}, + {R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET}, + {R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET}, + {R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET}, + {R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET}, + {R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET}, + {R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR, + B_BE_TRXPTCL_ERROR_INDICA_MASK_SET}, + {R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET}, + {R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET}, +}; + +static const struct rtw89_imr_table rtw8922d_imr_cmac_table = { + .regs = rtw8922d_imr_cmac_regs, + .n_regs = ARRAY_SIZE(rtw8922d_imr_cmac_regs), +}; + +static const struct rtw89_rrsr_cfgs rtw8922d_rrsr_cfgs = { + .ref_rate = {R_BE_TRXPTCL_RESP_1, B_BE_WMAC_RESP_REF_RATE_SEL, 0}, + .rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2}, +}; + +static const struct rtw89_rfkill_regs rtw8922d_rfkill_regs = { + .pinmux = {R_BE_GPIO8_15_FUNC_SEL, + B_BE_PINMUX_GPIO9_FUNC_SEL_MASK, + 0xf}, + .mode = {R_BE_GPIO_EXT_CTRL + 2, + (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16, + 0x0}, +}; + +static const struct rtw89_dig_regs rtw8922d_dig_regs = { + .seg0_pd_reg = R_SEG0R_PD_BE4, + .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, + .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, + .bmode_pd_reg = R_BMODE_PDTH_EN_BE4, + .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1, + .bmode_pd_lower_bound_reg = R_BMODE_PDTH_BE4, + .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1, + .p0_lna_init = {R_PATH0_LNA_INIT_BE4, B_PATH0_LNA_INIT_IDX_BE4}, + .p1_lna_init = {R_PATH1_LNA_INIT_BE4, B_PATH1_LNA_INIT_IDX_BE4}, + .p0_tia_init = {R_PATH0_TIA_INIT_BE4, B_PATH0_TIA_INIT_IDX_BE4}, + .p1_tia_init = {R_PATH1_TIA_INIT_BE4, B_PATH1_TIA_INIT_IDX_BE4}, + .p0_rxb_init = {R_PATH0_RXIDX_INIT_BE4, B_PATH0_RXIDX_INIT_BE4}, + .p1_rxb_init = {R_PATH1_RXIDX_INIT_BE4, B_PATH1_RXIDX_INIT_BE4}, + .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_BE4, + B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_BE4, + B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_BE4, + B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, + .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_BE4, + B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, +}; + +static const struct rtw89_edcca_regs rtw8922d_edcca_regs = { + .edcca_level = R_SEG0R_EDCCA_LVL_BE4, + .edcca_mask = B_EDCCA_LVL_MSK0, + .edcca_p_mask = B_EDCCA_LVL_MSK1, + .ppdu_level = R_SEG0R_PPDU_LVL_BE4, + .ppdu_mask = B_EDCCA_LVL_MSK1, + .p = {{ + .rpt_a = R_EDCCA_RPT_A_BE4, + .rpt_b = R_EDCCA_RPT_B_BE4, + .rpt_sel = R_EDCCA_RPT_SEL_BE4, + .rpt_sel_mask = B_EDCCA_RPT_SEL_BE4_MSK, + }, { + .rpt_a = R_EDCCA_RPT_A_BE4_C1, + .rpt_b = R_EDCCA_RPT_A_BE4_C1, + .rpt_sel = R_EDCCA_RPT_SEL_BE4_C1, + .rpt_sel_mask = B_EDCCA_RPT_SEL_BE4_MSK, + }}, + .rpt_sel_be = R_EDCCA_RPTREG_SEL_BE4, + .rpt_sel_be_mask = B_EDCCA_RPTREG_SEL_BE_MSK, + .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST_BE4, + .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_BE_M, +}; + +static const struct rtw89_pmac_regs rtw8922d_pmac_regs = { + .cck_txon = {R_CNT_CCKTXON_BE4, B_CNT_CCKTXON}, + .cck_txen = {R_CNT_CCKTXEN_BE4, B_CNT_CCKTXEN}, + .cck_cca = {R_CNT_CCK_CCA_BE4, B_CNT_CCK_CCA_BE4}, + .cck_sfd_gg = {R_SFD_GG_CNT_BE4, B_SFD_GG_CNT}, + .cck_sig_gg = {R_SIG_GG_CNT_BE4, B_SIG_GG_CNT_V1}, + .cck_spoofing = {R_SPOOF_CNT_BE4, B_SPOOF_CNT_V1}, + .cck_brk = {R_BRK_CNT_BE4, B_BRK_CNT}, + .brk = {R_CNT_BRK_BE4, B_CNT_BRK}, + .brk_option = {}, + .search_fail = {R_CNT_SEARCH_FAIL_BE4, B_CNT_SEARCH_FAIL}, + .lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH_BE4, B_CNT_LSIG_BRK_S_TH}, + .lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH_BE4, B_CNT_LSIG_BRK_L_TH}, + .rxl_err_parity = {R_CNT_RXL_ERR_PARITY_BE4, B_CNT_RXL_ERR_PARITY}, + .rxl_err_rate = {R_CNT_RXL_ERR_RATE_BE4, B_CNT_RXL_ERR_RATE}, + .ofdm_cca = {R_CNT_OFDM_CCA_BE4, B_CNT_OFDM_CCA}, + .cca_spoofing = {R_CNT_CCA_SPOOFING_BE4, B_CNT_CCA_SPOOFING}, + .ampdu_miss = {R_CNT_AMPDU_MISS_BE4, B_CNT_AMPDU_MISS}, + .r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST_BE4, B_R1B_RX_RPT_RST_V1}, + .r1b_rr_sel = {}, + .enable_all_cnt = {R_ENABLE_ALL_CNT_BE4, B_ENABLE_ALL_CNT}, + .rst_all_cnt = {R_RST_ALL_CNT_BE4, B_RST_ALL_CNT}, + .cck_crc32 = R_CNT_CCK_CRC32_BE4, + .cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_BE4, + .cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_BE4, + .ofdm_txon = R_CNT_OFDMTXON_BE4, + .ofdm_txon_mask = B_CNT_OFDMTXON, + .ofdm_txen_mask = B_CNT_OFDMTXEN, + .l_crc = R_CNT_L_CRC_BE4, + .l_crc_ok_mask = B_CNT_L_CRC_OK, + .l_crc_err_mask = B_CNT_L_CRC_ERR, + .ht_crc = R_CNT_HT_CRC_BE4, + .ht_crc_ok_mask = B_CNT_HT_CRC_OK, + .ht_crc_err_mask = B_CNT_HT_CRC_ERR, + .vht_crc = R_CNT_VHT_CRC_BE4, + .vht_crc_ok_mask = B_CNT_VHT_CRC_OK, + .vht_crc_err_mask = B_CNT_VHT_CRC_ERR, + .he_crc = R_CNT_HE_CRC_BE4, + .he_crc_ok_mask = B_CNT_HE_CRC_OK, + .he_crc_err_mask = B_CNT_HE_CRC_ERR, + .eht_crc = R_CNT_EHT_CRC_BE4, + .eht_crc_ok_mask = B_CNT_EHT_CRC_OK, + .eht_crc_err_mask = B_CNT_EHT_CRC_ERR, + .ampdu_crc = R_CNT_AMPDU_RX_CRC32_BE4, + .ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK, + .ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR, +}; + +static const struct rtw89_efuse_block_cfg rtw8922d_efuse_blocks[] = { + [RTW89_EFUSE_BLOCK_SYS] = {.offset = 0x00000, .size = 0x310}, + [RTW89_EFUSE_BLOCK_RF] = {.offset = 0x10000, .size = 0x240}, + [RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO] = {.offset = 0x20000, .size = 0x4800}, + [RTW89_EFUSE_BLOCK_HCI_DIG_USB] = {.offset = 0x30000, .size = 0x890}, + [RTW89_EFUSE_BLOCK_HCI_PHY_PCIE] = {.offset = 0x40000, .size = 0x400}, + [RTW89_EFUSE_BLOCK_HCI_PHY_USB3] = {.offset = 0x50000, .size = 0x80}, + [RTW89_EFUSE_BLOCK_HCI_PHY_USB2] = {.offset = 0x60000, .size = 0x50}, + [RTW89_EFUSE_BLOCK_ADIE] = {.offset = 0x70000, .size = 0x10}, +}; + +static const struct rtw89_bb_wrap_common_data rtw8922d_bb_wrap_common_data_7025 = { + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .cim3k = {CIM3K_OFF, CIM3K_OFF, CIM3K_ENABLE, CIM3K_ENABLE}, + .rfsi_ct_opt = {_8nibble(2, 2, 2, 2, 1, 1, 1, 1), + _8nibble(2, 2, 2, 2, 1, 1, 1, 1)}, + .pb_tb = 3, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .cim3k = {CIM3K_OFF, CIM3K_OFF, CIM3K_ENABLE, CIM3K_ENABLE}, + .rfsi_ct_opt = {_8nibble(2, 2, 2, 2, 1, 1, 1, 1), + _8nibble(2, 2, 2, 2, 1, 1, 1, 1)}, + .pb_tb = 0, + }}, + .qam_th = {RFSI_BPSK, RFSI_QPSK, RFSI_256QAM, RFSI_MAX, RFSI_MAX, RFSI_MAX}, +}; + +static const struct rtw89_bb_wrap_common_data rtw8922d_bb_wrap_common_data_7090 = { + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .cim3k = {CIM3K_OFF, CIM3K_OFF, CIM3K_DISABLE, CIM3K_ENABLE}, + .rfsi_ct_opt = {_8nibble(2, 2, 2, 2, 1, 1, 1, 1), + _8nibble(2, 2, 2, 2, 1, 1, 1, 1)}, + .pb_tb = 3, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .cim3k = {CIM3K_OFF, CIM3K_OFF, CIM3K_DISABLE, CIM3K_ENABLE}, + .rfsi_ct_opt = {_8nibble(2, 2, 2, 2, 1, 1, 1, 1), + _8nibble(2, 2, 2, 2, 1, 1, 1, 1)}, + .pb_tb = 0, + }}, + .qam_th = {RFSI_BPSK, RFSI_QPSK, RFSI_256QAM, RFSI_MAX, RFSI_MAX, RFSI_MAX}, +}; + +static const +struct rtw89_bb_wrap_common_data_gen3 rtw8922d_bb_wrap_common_data_gen3_7090 = { + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .qam_th = {RFSI_QPSK, RFSI_BPSK, RFSI_256QAM, RFSI_MAX, + RFSI_MAX, RFSI_MAX}, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .qam_th = {RFSI_MAX, RFSI_MAX, RFSI_256QAM, RFSI_MAX, + RFSI_MAX, RFSI_MAX}, + }}, + .cck_val = {CFIR_OFF, FILTER_A_OFF}, +}; + +static const struct rtw89_bb_wrap_data rtw8922d_bb_wrap_data_7025_default = { + .common = &rtw8922d_bb_wrap_common_data_7025, + .common_gen3 = NULL, + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .qam_comp_th0 = {0x4000, 0x6400, 0x6500, 0x6000, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x6400, 0x6500, 0x6000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0x4000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4400, 0x4400, 0x4000, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .qam_comp_th0 = {0x4000, 0x4400, 0x4500, 0, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x4400, 0x4500, 0, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4400, 0x4400, 0, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }}, + .mdpd_by_dbw = {MDPD_ON, MDPD_ON, MDPD_ON, MDPD_ON}, +}; + +static const struct rtw89_bb_wrap_data rtw8922d_bb_wrap_data_7090_default = { + .common = &rtw8922d_bb_wrap_common_data_7090, + .common_gen3 = &rtw8922d_bb_wrap_common_data_gen3_7090, + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .qam_comp_th0 = {0x4000, 0x6420, 0x6520, 0x6000, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x6400, 0x6500, 0x6000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0x4000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4000, 0x4000, 0x4000, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .qam_comp_th0 = {0x4000, 0x4400, 0x4500, 0, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x4400, 0x4500, 0, 0, + 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0, 0, + 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4000, 0x4000, 0, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }}, + .mdpd_by_dbw = {MDPD_OFF, MDPD_OFF, MDPD_ON, MDPD_ON}, +}; + +static const struct rtw89_bb_wrap_data rtw8922d_bb_wrap_data_7090_rfe35_41_44 = { + .common = &rtw8922d_bb_wrap_common_data_7090, + .common_gen3 = &rtw8922d_bb_wrap_common_data_gen3_7090, + .bands = { + [RFSI_CTRL_BAND_5_6GHZ] = { + .qam_comp_th0 = {0x4000, 0x6420, 0x6520, 0x6000, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x6400, 0x6500, 0x6000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0x4000, + 0, 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4000, 0x4000, 0x4000, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }, + [RFSI_CTRL_BAND_2GHZ] = { + .qam_comp_th0 = {0x4000, 0x4400, 0x4500, 0, 0, 0, 0, 0, 0, 0}, + .qam_comp_th1 = {_10qam_comp_code(0x4000, 0x4400, 0x4500, 0, 0, + 0, 0, 0, 0, 0)}, + .qam_comp_th2 = {_10qam_comp_code(0x4000, 0x4400, 0x4400, 0, 0, + 0, 0, 0, 0, 0)}, + .qam_comp_ow = {0x4000, 0x4000, 0x4000, 0, 0, 0, 0, 0, 0, 0}, + .oob_dpd_by_cbw = {OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, + OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF, OOB_DPD_OFF}, + }}, + .mdpd_by_dbw = {MDPD_OFF, MDPD_OFF, MDPD_ON, MDPD_ON}, +}; + +static void rtw8922d_sel_bt_rx_path(struct rtw89_dev *rtwdev, u8 val, + enum rtw89_rf_path rx_path) +{ + if (rx_path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_SEL_GNT_BT_RX_BE4, + B_SEL_GNT_BT_RX_PATH0_BE4, val); + else if (rx_path == RF_PATH_B) + rtw89_phy_write32_mask(rtwdev, R_SEL_GNT_BT_RX_BE4, + B_SEL_GNT_BT_RX_PATH1_BE4, val); + else + rtw89_warn(rtwdev, "[%s] Not support path = %d\n", __func__, rx_path); +} + +static void rtw8922d_sel_bt_rx_phy(struct rtw89_dev *rtwdev, u8 val, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_idx(rtwdev, R_SEL_GNT_BT_RXPHY_BE4, + B_SEL_GNT_BT_RXPHY_BE4, val, phy_idx); +} + +static void rtw8922d_set_gbt_bt_rx_sel(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + rtw8922d_sel_bt_rx_path(rtwdev, 0x3, RF_PATH_A); + rtw8922d_sel_bt_rx_phy(rtwdev, 0x0, RTW89_PHY_0); + rtw8922d_sel_bt_rx_path(rtwdev, 0x3, RF_PATH_B); + rtw8922d_sel_bt_rx_phy(rtwdev, 0x0, RTW89_PHY_1); +} + +static int rtw8922d_pwr_on_func(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 val32; + int ret; + + if (hal->cid != RTL8922D_CID7025) + goto begin; + + switch (hal->cv) { + case CHIP_CAV: + case CHIP_CBV: + rtw89_write32_set(rtwdev, R_BE_SPS_DIG_ON_CTRL1, B_BE_PWM_FORCE); + rtw89_write32_set(rtwdev, R_BE_SPS_ANA_ON_CTRL1, B_BE_PWM_FORCE_ANA); + break; + default: + break; + } + +begin: + val32 = rtw89_read32(rtwdev, R_BE_SYS_PW_CTRL); + val32 &= ~(B_BE_AFSM_WLSUS_EN | B_BE_AFSM_PCIE_SUS_EN | B_BE_APFM_SWLPS); + val32 |= B_BE_DIS_WLBT_PDNSUSEN_SOPC; + if (hal->cid != RTL8922D_CID7090) + val32 &= ~B_BE_APDM_HPDN; + rtw89_write32(rtwdev, R_BE_SYS_PW_CTRL, val32); + + rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC); + rtw89_write32_clr(rtwdev, R_BE_FWS1ISR, B_BE_FS_WL_HW_RADIO_OFF_INT); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR, + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 | + B_BE_LPSROP_CMAC1); + + if (hal->aid == RTL8922D_AID7102) { + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_AONLDO_CTRL, 0, 0x20); + if (ret) + return ret; + + udelay(1); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_AONLDO_CTRL, 0, 0x40); + if (ret) + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC), + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN); + rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HAXIDMA_IO_ST, + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST), + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST, + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_NORMAL_WRITE, 0x10, 0x10); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, + B_BE_SYM_PADPDN_WL_RFC1_1P3 | B_BE_SYM_PADPDN_WL_RFC0_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, 0x70); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, 0x02); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); + rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); + + mdelay(1); + + rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); + rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); + + rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN, + B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | + B_BE_MPDU_PROC_EN | B_BE_WD_RLS_EN | + B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN | + B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | + B_BE_PKT_BUF_EN | B_BE_DMAC_TBL_EN | + B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN | + B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | + B_BE_MAC_SEC_EN | B_BE_H_AXIDMA_EN | + B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN | + B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN | + B_BE_LTR_CTL_EN); + + set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); + + rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN, + B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | + B_BE_ADDRSRCH_EN | B_BE_BTCOEX_EN); + + rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN, + B_BE_CMAC_EN | B_BE_CMAC_TXEN | + B_BE_CMAC_RXEN | B_BE_SIGB_EN | + B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN | + B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN | + B_BE_TMAC_EN | B_BE_RMAC_EN | + B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN); + + set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); + + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_FEN_BB_IP_RSTN | B_BE_FEN_BBPLAT_RSTB); + + return 0; +} + +static int rtw8922d_pwr_off_func(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, 0x01); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, 0x01); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02); + if (ret) + return ret; + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN | + B_BE_FEN_BBPLAT_RSTB); + rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, + B_BE_SYM_PADPDN_WL_RFC0_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, + B_BE_SYM_PADPDN_WL_RFC1_1P3); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_IO_ST), + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + ret = read_poll_timeout(rtw89_read32, val32, + !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST), + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST), + 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL); + if (ret) + return ret; + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC), + 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL); + if (ret) + return ret; + + rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x00015002); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + rtw89_write32(rtwdev, R_BE_UDM1, 0); + + return 0; +} + +static void rtw8922d_efuse_parsing_tssi(struct rtw89_dev *rtwdev, + struct rtw8922d_efuse *map) +{ + const struct rtw8922d_tssi_offset_6g * const ofst_6g[] = { + &map->path_a_tssi_6g, + &map->path_b_tssi_6g, + }; + const struct rtw8922d_tssi_offset * const ofst[] = { + &map->path_a_tssi, + &map->path_b_tssi, + }; + struct rtw89_tssi_info *tssi = &rtwdev->tssi; + u8 i, j; + + tssi->thermal[RF_PATH_A] = map->path_a_therm; + tssi->thermal[RF_PATH_B] = map->path_b_therm; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, TSSI_CCK_CH_GROUP_NUM); + + for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", + i, j, tssi->tssi_cck[i][j]); + + memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, + TSSI_MCS_2G_CH_GROUP_NUM); + memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, + ofst[i]->bw40_1s_tssi_5g, TSSI_MCS_5G_CH_GROUP_NUM); + memcpy(tssi->tssi_6g_mcs[i], ofst_6g[i]->bw40_1s_tssi_6g, + TSSI_MCS_6G_CH_GROUP_NUM); + + for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", + i, j, tssi->tssi_mcs[i][j]); + + for (j = 0; j < TSSI_MCS_6G_CH_GROUP_NUM; j++) + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][EFUSE] path=%d mcs_6g[%d]=0x%x\n", + i, j, tssi->tssi_6g_mcs[i][j]); + } +} + +static void +__rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + s8 offset[RTW89_GAIN_OFFSET_NR], + const s8 *offset_default, + const struct rtw8922d_rx_gain *rx_gain, + const struct rtw8922d_rx_gain_6g *rx_gain_6g) +{ + int i; + u8 t; + + offset[RTW89_GAIN_OFFSET_2G_CCK] = rx_gain->_2g_cck; + offset[RTW89_GAIN_OFFSET_2G_OFDM] = rx_gain->_2g_ofdm; + offset[RTW89_GAIN_OFFSET_5G_LOW] = rx_gain->_5g_low; + offset[RTW89_GAIN_OFFSET_5G_MID] = rx_gain->_5g_mid; + offset[RTW89_GAIN_OFFSET_5G_HIGH] = rx_gain->_5g_high; + offset[RTW89_GAIN_OFFSET_6G_L0] = rx_gain_6g->_6g_l0; + offset[RTW89_GAIN_OFFSET_6G_L1] = rx_gain_6g->_6g_l1; + offset[RTW89_GAIN_OFFSET_6G_M0] = rx_gain_6g->_6g_m0; + offset[RTW89_GAIN_OFFSET_6G_M1] = rx_gain_6g->_6g_m1; + offset[RTW89_GAIN_OFFSET_6G_H0] = rx_gain_6g->_6g_h0; + offset[RTW89_GAIN_OFFSET_6G_H1] = rx_gain_6g->_6g_h1; + offset[RTW89_GAIN_OFFSET_6G_UH0] = rx_gain_6g->_6g_uh0; + offset[RTW89_GAIN_OFFSET_6G_UH1] = rx_gain_6g->_6g_uh1; + + for (i = 0; i < RTW89_GAIN_OFFSET_NR; i++) { + t = offset[i]; + if (t == 0xff) { + if (offset_default) { + offset[i] = offset_default[i]; + continue; + } + t = 0; + } + + /* transform: sign-bit + U(7,2) to S(8,2) */ + if (t & 0x80) + offset[i] = (t ^ 0x7f) + 1; + else + offset[i] = t; + } +} + +static void rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8922d_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_A], + NULL, + &map->rx_gain_a, &map->rx_gain_6g_a); + __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_B], + NULL, + &map->rx_gain_b, &map->rx_gain_6g_b); + + __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_A], + gain->offset[RF_PATH_A], + &map->rx_gain_a_2, &map->rx_gain_6g_a_2); + __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_B], + gain->offset[RF_PATH_B], + &map->rx_gain_b_2, &map->rx_gain_6g_b_2); + + gain->offset_valid = true; +} + +static int rtw8922d_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) + ether_addr_copy(efuse->addr, log_map + 0x4104); + else + ether_addr_copy(efuse->addr, log_map + 0x001A); + + return 0; +} + +static int rtw8922d_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + ether_addr_copy(efuse->addr, log_map + 0x0078); + + return 0; +} + +static int rtw8922d_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw8922d_efuse *map = (struct rtw8922d_efuse *)log_map; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + efuse->rfe_type = map->rfe_type; + efuse->xtal_cap = map->xtal_k; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting_2 = map->bt_setting_2; + efuse->bt_setting_3 = map->bt_setting_3; + rtw8922d_efuse_parsing_tssi(rtwdev, map); + rtw8922d_efuse_parsing_gain_offset(rtwdev, map); + + return 0; +} + +static int rtw8922d_read_sys(struct rtw89_dev *rtwdev, u8 *log_map) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; + u16 digk; + u8 vmin; + + digk = log_map[0x200] | log_map[0x201] << 8; + hal->thermal_prot_vmax = u16_get_bits(digk, B_BE_PWMTUNE_MASK); + + if (efuse->dswr_valid) + vmin = efuse->dswr_vmin; + else if (efuse->vcore_valid) + vmin = hal->thermal_prot_vmax - efuse->vcore_vmax_reduce; + else + vmin = hal->thermal_prot_vmax - 3; + + hal->thermal_prot_vmin = vmin; + + return 0; +} + +static int rtw8922d_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, + enum rtw89_efuse_block block) +{ + switch (block) { + case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO: + return rtw8922d_read_efuse_pci_sdio(rtwdev, log_map); + case RTW89_EFUSE_BLOCK_HCI_DIG_USB: + return rtw8922d_read_efuse_usb(rtwdev, log_map); + case RTW89_EFUSE_BLOCK_RF: + return rtw8922d_read_efuse_rf(rtwdev, log_map); + case RTW89_EFUSE_BLOCK_SYS: + return rtw8922d_read_sys(rtwdev, log_map); + default: + return 0; + } +} + +static void rtw8922d_phycap_parsing_vco_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 vco_trim_addr[RF_PATH_NUM_8922D] = {0x175E, 0x175F}; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + const u32 vco_check_addr = 0x1700; + u8 val; + + val = phycap_map[vco_check_addr - addr]; + if (val & BIT(1)) + return; + + info->pg_vco_trim = true; + + info->vco_trim[0] = u8_get_bits(phycap_map[vco_trim_addr[0] - addr], GENMASK(4, 0)); + info->vco_trim[1] = u8_get_bits(phycap_map[vco_trim_addr[1] - addr], GENMASK(4, 0)); +} + +static void rtw8922d_vco_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + + if (!info->pg_vco_trim) + return; + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCO, RR_VCO_VAL, info->vco_trim[0]); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_VCO, RR_VCO_VAL, info->vco_trim[1]); +} + +#define THM_TRIM_POSITIVE_MASK BIT(6) +#define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0) +#define THM_TRIM_MAX (15) +#define THM_TRIM_MIN (-15) + +static void rtw8922d_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 thm_trim_addr[RF_PATH_NUM_8922D] = {0x1706, 0x1732}; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = true; + u8 pg_th; + s8 val; + u8 i; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + pg_th = phycap_map[thm_trim_addr[i] - addr]; + if (pg_th == 0xff) { + memset(info->thermal_trim, 0, sizeof(info->thermal_trim)); + pg = false; + goto out; + } + + val = u8_get_bits(pg_th, THM_TRIM_MAGNITUDE_MASK); + + if (!(pg_th & THM_TRIM_POSITIVE_MASK)) + val *= -1; + + if (val <= THM_TRIM_MIN || val >= THM_TRIM_MAX) { + val = 0; + info->thermal_trim[i] = 0; + } else { + info->thermal_trim[i] = pg_th; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[THERMAL][TRIM] path=%d thermal_trim=0x%x (%d)\n", + i, pg_th, val); + } + +out: + info->pg_thermal_trim = pg; +} + +static void rtw8922d_thermal_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 thermal; + int i; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + thermal = info->pg_thermal_trim ? info->thermal_trim[i] : 0; + rtw89_write_rf(rtwdev, i, RR_TM, RR_TM_TRM, thermal & 0x7f); + } +} + +static void rtw8922d_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 pabias_trim_addr[RF_PATH_NUM_8922D] = {0x1707, 0x1733}; + static const u32 check_pa_pad_trim_addr = 0x1700; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + bool pg = true; + u8 val; + u8 i; + + val = phycap_map[check_pa_pad_trim_addr - addr]; + if (val == 0xff) { + pg = false; + goto out; + } + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", + i, info->pa_bias_trim[i]); + } + +out: + info->pg_pa_bias_trim = pg; +} + +static void rtw8922d_pa_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pabias_2g, pabias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] no PG, do nothing\n"); + + return; + } + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); + pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pabias_2g, pabias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG_V1, pabias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA_V1, pabias_5g); + } +} + +static void rtw8922d_phycap_parsing_pad_bias_trim(struct rtw89_dev *rtwdev, + u8 *phycap_map) +{ + static const u32 pad_bias_trim_addr[RF_PATH_NUM_8922D] = {0x1708, 0x1734}; + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u32 addr = rtwdev->chip->phycap_addr; + u8 i; + + if (!info->pg_pa_bias_trim) + return; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + info->pad_bias_trim[i] = phycap_map[pad_bias_trim_addr[i] - addr]; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] path=%d pad_bias_trim=0x%x\n", + i, info->pad_bias_trim[i]); + } +} + +static void rtw8922d_pad_bias_trim(struct rtw89_dev *rtwdev) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 pad_bias_2g, pad_bias_5g; + u8 i; + + if (!info->pg_pa_bias_trim) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] no PG, do nothing\n"); + return; + } + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + pad_bias_2g = u8_get_bits(info->pad_bias_trim[i], GENMASK(3, 0)); + pad_bias_5g = u8_get_bits(info->pad_bias_trim[i], GENMASK(7, 4)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[PAD_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", + i, pad_bias_2g, pad_bias_5g); + + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXG_V1, pad_bias_2g); + rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXA_V1, pad_bias_5g); + } +} + +static int rtw8922d_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) +{ + rtw8922d_phycap_parsing_vco_trim(rtwdev, phycap_map); + rtw8922d_phycap_parsing_thermal_trim(rtwdev, phycap_map); + rtw8922d_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); + rtw8922d_phycap_parsing_pad_bias_trim(rtwdev, phycap_map); + + return 0; +} + +static void rtw8922d_power_trim(struct rtw89_dev *rtwdev) +{ + rtw8922d_vco_trim(rtwdev); + rtw8922d_thermal_trim(rtwdev); + rtw8922d_pa_bias_trim(rtwdev); + rtw8922d_pad_bias_trim(rtwdev); +} + +static int rtw8922d_data_setup(struct rtw89_dev *rtwdev) +{ + const struct rtw89_bb_wrap_data *data; + struct rtw89_hal *hal = &rtwdev->hal; + bool rfe35_41_44 = false; + + switch (rtwdev->efuse.rfe_type) { + case 35: + case 41: + case 44: + rfe35_41_44 = true; + break; + } + + if (hal->cid == RTL8922D_CID7025) { + data = &rtw8922d_bb_wrap_data_7025_default; + } else { + if (rfe35_41_44) + data = &rtw8922d_bb_wrap_data_7090_rfe35_41_44; + else + data = &rtw8922d_bb_wrap_data_7090_default; + } + + rtwdev->phy_info.bb_wrap_data = data; + + return 0; +} + +static void rtw8922d_set_channel_mac(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + u8 mac_idx) +{ + u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx); + u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx); + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 txsb20 = 0, txsb40 = 0, txsb80 = 0; + u8 rf_mod_val, chk_rate_mask, sifs; + u16 tx_time = AMPDU_MAX_TIME_V1; + u32 txsb; + u32 reg; + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + txsb80 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_80); + fallthrough; + case RTW89_CHANNEL_WIDTH_80: + txsb40 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsb20 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + rf_mod_val = BE_WMAC_RFMOD_160M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) | + u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK) | + u32_encode_bits(txsb80, B_BE_TXSB_80M_MASK); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_mod_val = BE_WMAC_RFMOD_80M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) | + u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_mod_val = BE_WMAC_RFMOD_40M; + txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK); + break; + case RTW89_CHANNEL_WIDTH_20: + default: + rf_mod_val = BE_WMAC_RFMOD_20M; + txsb = 0; + break; + } + + if (txsb20 <= BE_PRI20_BITMAP_MAX) + txsb |= u32_encode_bits(BIT(txsb20), B_BE_PRI20_BITMAP_MASK); + + rtw89_write8_mask(rtwdev, rf_mod, B_BE_WMAC_RFMOD_MASK, rf_mod_val); + rtw89_write32(rtwdev, sub_carr, txsb); + + switch (chan->band_type) { + case RTW89_BAND_2G: + chk_rate_mask = B_BE_BAND_MODE; + break; + case RTW89_BAND_5G: + case RTW89_BAND_6G: + chk_rate_mask = B_BE_CHECK_CCK_EN | B_BE_RTS_LIMIT_IN_OFDM6; + break; + default: + rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type); + return; + } + + rtw89_write8_clr(rtwdev, chk_rate, B_BE_BAND_MODE | B_BE_CHECK_CCK_EN | + B_BE_RTS_LIMIT_IN_OFDM6); + rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask); + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_160: + sifs = 0x8C; + break; + case RTW89_CHANNEL_WIDTH_80: + sifs = 0x8A; + break; + case RTW89_CHANNEL_WIDTH_40: + sifs = 0x84; + break; + case RTW89_CHANNEL_WIDTH_20: + default: + sifs = 0x82; + } + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK, sifs); + + if (chan->band_type == RTW89_BAND_2G && chip->txtime_limit_2ghz) + tx_time = min_t(u32, tx_time, chip->txtime_limit_2ghz * 1000 >> 15); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, tx_time); +} + +static const u32 rtw8922d_sco_barker_threshold[14] = { + 0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6, + 0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a +}; + +static const u32 rtw8922d_sco_cck_threshold[14] = { + 0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db, + 0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e +}; + +static int rtw8922d_ctrl_sco_cck(struct rtw89_dev *rtwdev, + u8 primary_ch, enum rtw89_bandwidth bw, + enum rtw89_phy_idx phy_idx) +{ + u8 ch_element; + + if (primary_ch >= 14) + return -EINVAL; + + ch_element = primary_ch - 1; + + rtw89_phy_write32_idx(rtwdev, R_BK_FC0_INV_BE4, B_BK_FC0_INV_BE4, + rtw8922d_sco_barker_threshold[ch_element], + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CCK_FC0_INV_BE4, B_CCK_FC0_INV_BE4, + rtw8922d_sco_cck_threshold[ch_element], + phy_idx); + + return 0; +} + +static void rtw8922d_ctrl_ch_core(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u16 central_freq = chan->freq; + u16 sco; + + if (chan->band_type == RTW89_BAND_2G) { + rtw89_phy_write32_idx(rtwdev, R_BAND_SEL0_BE4, B_BAND_SEL0_BE4, + 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BAND_SEL1_BE4, B_BAND_SEL1_BE4, + 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ENABLE_CCK0_BE4, B_ENABLE_CCK0_BE4, + 1, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_BAND_SEL0_BE4, B_BAND_SEL0_BE4, + 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BAND_SEL1_BE4, B_BAND_SEL1_BE4, + 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ENABLE_CCK0_BE4, B_ENABLE_CCK0_BE4, + 0, phy_idx); + } + + rtw89_phy_write32_idx(rtwdev, R_FC0_BE4, B_FC0_BE4, central_freq, phy_idx); + + sco = phy_div((BIT(0) << 27) + (central_freq / 2), central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0_INV_BE4, B_FC0_INV_BE4, sco, phy_idx); +} + +struct rtw8922d_bb_gain { + u32 gain_g[BB_PATH_NUM_8922D]; + u32 gain_a[BB_PATH_NUM_8922D]; + u32 gain_g_mask; + u32 gain_a_mask; +}; + +static const struct rtw89_reg_def rpl_comp_bw160[RTW89_BW20_SC_160M] = { + { .addr = 0x241E8, .mask = 0xFF00}, + { .addr = 0x241E8, .mask = 0xFF0000}, + { .addr = 0x241E8, .mask = 0xFF000000}, + { .addr = 0x241EC, .mask = 0xFF}, + { .addr = 0x241EC, .mask = 0xFF00}, + { .addr = 0x241EC, .mask = 0xFF0000}, + { .addr = 0x241EC, .mask = 0xFF000000}, + { .addr = 0x241F0, .mask = 0xFF} +}; + +static const struct rtw89_reg_def rpl_comp_bw80[RTW89_BW20_SC_80M] = { + { .addr = 0x241F4, .mask = 0xFF}, + { .addr = 0x241F4, .mask = 0xFF00}, + { .addr = 0x241F4, .mask = 0xFF0000}, + { .addr = 0x241F4, .mask = 0xFF000000} +}; + +static const struct rtw89_reg_def rpl_comp_bw40[RTW89_BW20_SC_40M] = { + { .addr = 0x241F0, .mask = 0xFF0000}, + { .addr = 0x241F0, .mask = 0xFF000000} +}; + +static const struct rtw89_reg_def rpl_comp_bw20[RTW89_BW20_SC_20M] = { + { .addr = 0x241F0, .mask = 0xFF00} +}; + +static const struct rtw8922d_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x2409C, 0x2449C}, .gain_a = {0x2406C, 0x2446C}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x2409C, 0x2449C}, .gain_a = {0x2406C, 0x2446C}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x240A0, 0x244A0}, .gain_a = {0x24070, 0x24470}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x240A0, 0x244A0}, .gain_a = {0x24070, 0x24470}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x240A4, 0x244A4}, .gain_a = {0x24074, 0x24474}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, + { .gain_g = {0x240A4, 0x244A4}, .gain_a = {0x24074, 0x24474}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x240A8, 0x244A8}, .gain_a = {0x24078, 0x24478}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF}, +}; + +static const struct rtw8922d_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x24054, 0x24454}, .gain_a = {0x24054, 0x24454}, + .gain_g_mask = 0x7FC0000, .gain_a_mask = 0x1FF}, + { .gain_g = {0x24058, 0x24458}, .gain_a = {0x24054, 0x24454}, + .gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 }, +}; + +static const struct rtw8922d_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x24078, 0x24478}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x2407C, 0x2447C}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF}, + { .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x2407C, 0x2447C}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00}, + { .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x2407C, 0x2447C}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x2407C, 0x2447C}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x24080, 0x24480}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF}, + { .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x24080, 0x24480}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00}, +}; + +static const struct rtw8922d_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = { + { .gain_g = {0x240B4, 0x244B4}, .gain_a = {0x24080, 0x24480}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x240B4, 0x244B4}, .gain_a = {0x24084, 0x24484}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF}, + { .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00}, + { .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000}, + { .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484}, + .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000}, + { .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24088, 0x24488}, + .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF}, + { .gain_g = {0x240BC, 0x244BC}, .gain_a = {0x24088, 0x24488}, + .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00}, + { .gain_g = {0x240BC, 0x244BC}, .gain_a = {0x24088, 0x24488}, + .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000}, +}; + +static void rtw8922d_set_rpl_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + u32 reg_path_ofst = 0; + u32 mask; + s32 val; + u32 reg; + int i; + + if (path == RF_PATH_B) + reg_path_ofst = 0x400; + + for (i = 0; i < RTW89_BW20_SC_160M; i++) { + reg = rpl_comp_bw160[i].addr | reg_path_ofst; + mask = rpl_comp_bw160[i].mask; + val = gain->rpl_ofst_160[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_80M; i++) { + reg = rpl_comp_bw80[i].addr | reg_path_ofst; + mask = rpl_comp_bw80[i].mask; + val = gain->rpl_ofst_80[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_40M; i++) { + reg = rpl_comp_bw40[i].addr | reg_path_ofst; + mask = rpl_comp_bw40[i].mask; + val = gain->rpl_ofst_40[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < RTW89_BW20_SC_20M; i++) { + reg = rpl_comp_bw20[i].addr | reg_path_ofst; + mask = rpl_comp_bw20[i].mask; + val = gain->rpl_ofst_20[gain_band][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } +} + +static void rtw8922d_set_lna_tia_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + enum rtw89_phy_bb_bw_be bw_type; + u32 mask; + s32 val; + u32 reg; + int i; + + bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ? + RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_gain_lna[i].gain_g[path]; + mask = bb_gain_lna[i].gain_g_mask; + } else { + reg = bb_gain_lna[i].gain_a[path]; + mask = bb_gain_lna[i].gain_a_mask; + } + val = gain->lna_gain[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_gain_tia[i].gain_g[path]; + mask = bb_gain_tia[i].gain_g_mask; + } else { + reg = bb_gain_tia[i].gain_a[path]; + mask = bb_gain_tia[i].gain_a_mask; + } + val = gain->tia_gain[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } +} + +static void rtw8922d_set_op1db(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; + u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); + enum rtw89_phy_bb_bw_be bw_type; + u32 mask; + s32 val; + u32 reg; + int i; + + bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ? + RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_op1db_lna[i].gain_g[path]; + mask = bb_op1db_lna[i].gain_g_mask; + } else { + reg = bb_op1db_lna[i].gain_a[path]; + mask = bb_op1db_lna[i].gain_a_mask; + } + val = gain->lna_op1db[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } + + for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) { + if (chan->band_type == RTW89_BAND_2G) { + reg = bb_op1db_tia_lna[i].gain_g[path]; + mask = bb_op1db_tia_lna[i].gain_g_mask; + } else { + reg = bb_op1db_tia_lna[i].gain_a[path]; + mask = bb_op1db_tia_lna[i].gain_a_mask; + } + val = gain->tia_lna_op1db[gain_band][bw_type][path][i]; + rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx); + } +} + +static void rtw8922d_set_gain(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + rtw8922d_set_rpl_gain(rtwdev, chan, path, phy_idx); + rtw8922d_set_lna_tia_gain(rtwdev, chan, path, phy_idx); + rtw8922d_set_op1db(rtwdev, chan, path, phy_idx); +} + +static s8 rtw8922d_get_rx_gain_by_chan(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, bool is_cck) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset band; + u8 fc_ch = chan->channel; + s8 normal_efuse = 0; + + if (path > RF_PATH_B) + return 0; + + if (is_cck) { + if (fc_ch >= 1 && fc_ch <= 7) + return gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK]; + else if (fc_ch >= 8 && fc_ch <= 14) + return gain->offset2[path][RTW89_GAIN_OFFSET_2G_CCK]; + + return 0; + } + + band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type); + + if (band == RTW89_GAIN_OFFSET_2G_OFDM) { + if (fc_ch >= 1 && fc_ch <= 7) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 8 && fc_ch <= 14) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_5G_LOW) { + if (fc_ch == 50) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 36 && fc_ch <= 48) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 52 && fc_ch <= 64) + normal_efuse = gain->offset2[path][band]; + + } else if (band == RTW89_GAIN_OFFSET_5G_MID) { + if (fc_ch == 122) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 100 && fc_ch <= 120) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 124 && fc_ch <= 144) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_5G_HIGH) { + if (fc_ch == 163) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 149 && fc_ch <= 161) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 165 && fc_ch <= 177) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_L0) { + if (fc_ch == 15) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 1 && fc_ch <= 13) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 17 && fc_ch <= 29) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_L1) { + if (fc_ch == 47) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 33 && fc_ch <= 45) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 49 && fc_ch <= 61) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_M0) { + if (fc_ch == 79) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 65 && fc_ch <= 77) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 81 && fc_ch <= 93) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_M1) { + if (fc_ch == 111) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 97 && fc_ch <= 109) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 113 && fc_ch <= 125) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_H0) { + if (fc_ch == 143) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 129 && fc_ch <= 141) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 145 && fc_ch <= 157) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_H1) { + if (fc_ch == 175) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 161 && fc_ch <= 173) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 177 && fc_ch <= 189) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_UH0) { + if (fc_ch == 207) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 193 && fc_ch <= 205) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 209 && fc_ch <= 221) + normal_efuse = gain->offset2[path][band]; + } else if (band == RTW89_GAIN_OFFSET_6G_UH1) { + if (fc_ch == 239) + normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1; + else if (fc_ch >= 225 && fc_ch <= 237) + normal_efuse = gain->offset[path][band]; + else if (fc_ch >= 241 && fc_ch <= 253) + normal_efuse = gain->offset2[path][band]; + } else { + normal_efuse = gain->offset[path][band]; + } + + return normal_efuse; +} + +static void rtw8922d_calc_rx_gain_normal_cck(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx, + struct rtw89_phy_calc_efuse_gain *calc) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + s8 rx_gain_offset; + + rx_gain_offset = -rtw8922d_get_rx_gain_by_chan(rtwdev, chan, path, true); + calc->cck_mean_gain_bias = (rx_gain_offset & 0x3) << 1; + calc->cck_rpl_ofst = (rx_gain_offset >> 2) + gain->cck_rpl_base[phy_idx]; +} + +static void rtw8922d_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_phy_calc_efuse_gain calc = {}; + + rtw8922d_calc_rx_gain_normal_cck(rtwdev, chan, path, phy_idx, &calc); + + rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW20_BE4, + calc.cck_mean_gain_bias, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW40_BE4, + calc.cck_mean_gain_bias, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CCK_RPL_OFST_BE4, B_CCK_RPL_OFST_BE4, + calc.cck_rpl_ofst, phy_idx); +} + +static void rtw8922d_calc_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx, + struct rtw89_phy_calc_efuse_gain *calc) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + s8 rx_gain_offset; + + rx_gain_offset = rtw8922d_get_rx_gain_by_chan(rtwdev, chan, path, false); + calc->rssi_ofst = (rx_gain_offset + gain->ref_gain_base[phy_idx]) & 0xff; +} + +static void rtw8922d_set_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + static const u32 rssi_ofst_addr[2] = {R_OFDM_OFST_P0_BE4, R_OFDM_OFST_P1_BE4}; + static const u32 rssi_ofst_addr_m[2] = {B_OFDM_OFST_P0_BE4, B_OFDM_OFST_P1_BE4}; + static const u32 rpl_bias_comp[2] = {R_OFDM_RPL_BIAS_P0_BE4, R_OFDM_RPL_BIAS_P1_BE4}; + static const u32 rpl_bias_comp_m[2] = {B_OFDM_RPL_BIAS_P0_BE4, B_OFDM_RPL_BIAS_P1_BE4}; + struct rtw89_phy_calc_efuse_gain calc = {}; + + rtw8922d_calc_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx, &calc); + + rtw89_phy_write32_idx(rtwdev, rssi_ofst_addr[path], rssi_ofst_addr_m[path], + calc.rssi_ofst, phy_idx); + rtw89_phy_write32_idx(rtwdev, rpl_bias_comp[path], rpl_bias_comp_m[path], 0, phy_idx); +} + +static void rtw8922d_set_rx_gain_normal(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + + if (!gain->offset_valid) + return; + + if (chan->band_type == RTW89_BAND_2G) + rtw8922d_set_rx_gain_normal_cck(rtwdev, chan, path, phy_idx); + + rtw8922d_set_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx); +} + +static void rtw8922d_calc_rx_gain_normal(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx, + struct rtw89_phy_calc_efuse_gain *calc) +{ + rtw8922d_calc_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx, calc); + + if (chan->band_type != RTW89_BAND_2G) + return; + + rtw8922d_calc_rx_gain_normal_cck(rtwdev, chan, path, phy_idx, calc); +} + +static void rtw8922d_path_diff_update(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ +#define BF_SMOOTH_TH 80 + static const u32 path_diff_cnt_mask[] = {0xff0000, 0xff}; + static const u32 ndp_cnt_mask[] = {0xff000000, 0xff00}; + static const u16 he_eht_sel_tone[4] = {27, 54, 56, 56}; + static const u16 vht_sel_tone[4] = {11, 25, 25, 25}; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_entity_conf conf; + const struct rtw89_chan *chan; + u8 phy_idx = bb->phy_idx; + u32 path_diff_cnt; + u16 sel_tone = 0; + bool bf_smo_lmt; + u32 ndp_cnt; + + if (hal->cid != RTL8922D_CID7090) + return; + + ndp_cnt = rtw89_phy_read32_mask(rtwdev, R_CL_MODE_CNT_BE4, ndp_cnt_mask[phy_idx]); + path_diff_cnt = rtw89_phy_read32_mask(rtwdev, R_CL_MODE_CNT_BE4, + path_diff_cnt_mask[phy_idx]); + + bb->path_diff.raw = clamp(phy_div(path_diff_cnt * 100, ndp_cnt), 0, 255); + + if (ndp_cnt == 0) + ewma_path_diff_init(&bb->path_diff.avg); + else + ewma_path_diff_add(&bb->path_diff.avg, bb->path_diff.raw); + + rtw89_phy_write32_mask(rtwdev, R_CL_MODE_TRIG_BE4, B_CL_MODE_TRIG_BE4, 1); + rtw89_phy_write32_mask(rtwdev, R_CL_MODE_TRIG_BE4, B_CL_MODE_TRIG_BE4, 0); + + bf_smo_lmt = ewma_path_diff_read(&bb->path_diff.avg) < BF_SMOOTH_TH; + bb->path_diff.bf_smo_en = !bf_smo_lmt; + + rtw89_phy_write32_mask(rtwdev, R_BF_SMO_PDP_LMT_EHT_BE4, + B_BF_SMO_PDP_LMT_EHT_BE4, bf_smo_lmt); + rtw89_phy_write32_mask(rtwdev, R_BF_SMO_PDP_LMT_HE_BE4, + B_BF_SMO_PDP_LMT_HE_BE4, bf_smo_lmt); + rtw89_phy_write32_mask(rtwdev, R_BF_SMO_PDP_LMT_VHT_BE4, + B_BF_SMO_PDP_LMT_VHT_BE4, bf_smo_lmt); + + rtw89_phy_write32_mask(rtwdev, R_OS_TRIG_BY_SW_BE4, + B_OS_TRIG_BY_SW_BE4, !bf_smo_lmt); + rtw89_phy_write32_mask(rtwdev, R_OS_TRIG_SOURCE_BE4, + B_OS_TRIG_SOURCE_BE4, !bf_smo_lmt); + + rtw89_entity_get_conf(rtwdev, &conf); + chan = conf.chans[phy_idx]; + if (chan->band_width <= RTW89_CHANNEL_WIDTH_160) { + if (bb->path_diff.link_mode >= 2) + sel_tone = he_eht_sel_tone[chan->band_width]; + else if (bb->path_diff.link_mode == 1) + sel_tone = vht_sel_tone[chan->band_width]; + rtw89_phy_write32_mask(rtwdev, R_SELECTED_TONE_IDX_BE4, + B_SELECTED_TONE_IDX_BE4, sel_tone); + } + + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "[PATH_DIFF] raw=%d%%, ma=%ld%%, bf_smo_en=%d, tone=%d\n", + bb->path_diff.raw, + ewma_path_diff_read(&bb->path_diff.avg), + bb->path_diff.bf_smo_en, sel_tone); +} + +static void rtw8922d_set_cck_parameters(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u8 regd = rtw89_regd_get(rtwdev, chan->band_type); + u8 central_ch = chan->channel; + + if (central_ch == 14) { + rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x3b13ff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x1c42de, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0xfdb0ad, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0xf60f6e, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xfd8f92, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0x2d011, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0x1c02c, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xfff00a, phy_idx); + + return; + } + + if (regd == RTW89_FCC) { + rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x39A3BC, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x2AA339, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0x15B202, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0x0550C7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xfe0009, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0xfd7fd3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0xfeffe2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xffeff8, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x3d23ff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x29b354, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0xfc1c8, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0xfdb053, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xf86f9a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0xfaef92, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0xfe5fcc, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xffdff5, phy_idx); + } +} + +static void rtw8922d_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + u16 central_freq = chan->freq; + u8 band = chan->band_type; + u8 chan_idx; + + if (!central_freq) { + rtw89_warn(rtwdev, "Invalid central_freq\n"); + return; + } + + rtw8922d_ctrl_ch_core(rtwdev, chan, phy_idx); + + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); + rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL_BE4, B_CH_IDX_SEG0, chan_idx, phy_idx); + + rtw8922d_set_gain(rtwdev, chan, RF_PATH_A, phy_idx); + rtw8922d_set_gain(rtwdev, chan, RF_PATH_B, phy_idx); + + rtw8922d_set_rx_gain_normal(rtwdev, chan, RF_PATH_A, phy_idx); + rtw8922d_set_rx_gain_normal(rtwdev, chan, RF_PATH_B, phy_idx); + + if (band == RTW89_BAND_2G) + rtw8922d_set_cck_parameters(rtwdev, chan, phy_idx); +} + +static void rtw8922d_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_sb, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + switch (bw) { + default: + case RTW89_CHANNEL_WIDTH_20: + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x2, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x3, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x4, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x4, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x4, phy_idx); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x5, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x5, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x5, phy_idx); + break; + } +} + +static const u16 spur_nbi_a[] = {6400}; +static const u16 spur_csi[] = {6400}; + +static u32 rtw8922d_spur_freq(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + bool nbi_or_csi, enum rtw89_rf_path path) +{ + static const u16 cbw[RTW89_CHANNEL_WIDTH_ORDINARY_NUM] = { + 20, 40, 80, 160, 320, + }; + u16 freq_lower, freq_upper, freq; + const u16 *spur_freq; + int spur_freq_nr, i; + + if (rtwdev->hal.aid != RTL8922D_AID7060) + return 0; + + if (nbi_or_csi && path == RF_PATH_A) { + spur_freq = spur_nbi_a; + spur_freq_nr = ARRAY_SIZE(spur_nbi_a); + } else if (!nbi_or_csi) { + spur_freq = spur_csi; + spur_freq_nr = ARRAY_SIZE(spur_csi); + } else { + return 0; + } + + if (chan->band_width >= RTW89_CHANNEL_WIDTH_ORDINARY_NUM) + return 0; + + freq_lower = chan->freq - cbw[chan->band_width] / 2; + freq_upper = chan->freq + cbw[chan->band_width] / 2; + + for (i = 0; i < spur_freq_nr; i++) { + freq = spur_freq[i]; + + if (freq >= freq_lower && freq <= freq_upper) + return freq; + } + + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8922d_set_csi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s32 freq_diff, csi_idx, csi_tone_idx; + u32 spur_freq; + + spur_freq = rtw8922d_spur_freq(rtwdev, chan, false, RF_PATH_AB); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_EN_BE4, + 0, phy_idx); + return; + } + + freq_diff = (spur_freq - chan->freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_IDX_BE4, + csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_EN_BE4, 1, phy_idx); +} + +static const struct rtw89_nbi_reg_def rtw8922d_nbi_reg_def[] = { + [RF_PATH_A] = { + .notch1_idx = {0x241A0, 0xFF}, + .notch1_frac_idx = {0x241A0, 0xC00}, + .notch1_en = {0x241A0, 0x1000}, + .notch2_idx = {0x241AC, 0xFF}, + .notch2_frac_idx = {0x241AC, 0xC00}, + .notch2_en = {0x241AC, 0x1000}, + }, + [RF_PATH_B] = { + .notch1_idx = {0x245A0, 0xFF}, + .notch1_frac_idx = {0x245A0, 0xC00}, + .notch1_en = {0x245A0, 0x1000}, + .notch2_idx = {0x245AC, 0xFF}, + .notch2_frac_idx = {0x245AC, 0xC00}, + .notch2_en = {0x245AC, 0x1000}, + }, +}; + +static void rtw8922d_set_nbi_tone_idx(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_nbi_reg_def *nbi = &rtw8922d_nbi_reg_def[path]; + s32 nbi_frac_idx, nbi_frac_tone_idx; + s32 nbi_idx, nbi_tone_idx; + bool notch2_chk = false; + u32 spur_freq, fc; + s32 freq_diff; + + spur_freq = rtw8922d_spur_freq(rtwdev, chan, true, path); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + return; + } + + fc = chan->freq; + if (chan->band_width == RTW89_CHANNEL_WIDTH_160) { + fc = (spur_freq > fc) ? fc + 40 : fc - 40; + if ((fc > spur_freq && + chan->channel < chan->primary_channel) || + (fc < spur_freq && + chan->channel > chan->primary_channel)) + notch2_chk = true; + } + + freq_diff = (spur_freq - fc) * 1000000; + nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, + &nbi_frac_idx); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_20) { + s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); + } else { + u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ? + 128 : 256; + + s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); + } + nbi_frac_tone_idx = + s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125); + + if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { + rtw89_phy_write32_idx(rtwdev, nbi->notch2_idx.addr, + nbi->notch2_idx.mask, nbi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_frac_idx.addr, + nbi->notch2_frac_idx.mask, nbi_frac_tone_idx, + phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, nbi->notch1_idx.addr, + nbi->notch1_idx.mask, nbi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_frac_idx.addr, + nbi->notch1_frac_idx.mask, nbi_frac_tone_idx, + phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr, + nbi->notch1_en.mask, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr, + nbi->notch2_en.mask, 0, phy_idx); + } +} + +static void rtw8922d_spur_elimination(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8922d_set_csi_tone_idx(rtwdev, chan, phy_idx); + rtw8922d_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A, phy_idx); + rtw8922d_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B, phy_idx); +} + +static const u32 bbrst_mask[2] = {B_BE_FEN_BBPLAT_RSTB, B_BE_FEN_BB1PLAT_RSTB}; +static const u32 glbrst_mask[2] = {B_BE_FEN_BB_IP_RSTN, B_BE_FEN_BB1_IP_RSTN}; +static const u32 chip_top_bitmask[2] = {0xffff, 0xffff0000}; + +static void rtw8922d_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x0); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x0); + rtw89_write32_mask(rtwdev, R_BE_DMAC_SYS_CR32B, chip_top_bitmask[phy_idx], 0x74F9); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4, B_RSTB_ASYNC_BE4, 0, phy_idx); + rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x1); +} + +static void rtw8922d_bb_postinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_write32_idx_clr(rtwdev, R_SHAPER_COEFF_BE4, B_SHAPER_COEFF_BE4, phy_idx); + rtw89_phy_write32_idx_set(rtwdev, R_SHAPER_COEFF_BE4, B_SHAPER_COEFF_BE4, phy_idx); +} + +static void rtw8922d_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + bool en, enum rtw89_phy_idx phy_idx) +{ + if (en) + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4, B_RSTB_ASYNC_BE4, 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4, B_RSTB_ASYNC_BE4, 0, phy_idx); +} + +static int rtw8922d_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, + enum rtw89_rf_path tx_path, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_reg2_def path_com_cr[] = { + {0x11A00, 0x21C86900}, + {0x11A04, 0x00E4E433}, + {0x11A08, 0x39390CC9}, + {0x11A10, 0x10CC0000}, + {0x11A14, 0x00240393}, + {0x11A18, 0x201C8600}, + {0x11B38, 0x39393FDB}, + {0x11B3C, 0x00E4E4FF}, + }; + int ret = 0; + u32 reg; + int i; + + rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_EN_BE4, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_MA_BE4, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_MB_BE4, 0x0, phy_idx); + + if (phy_idx == RTW89_PHY_1 && !rtwdev->dbcc_en) + return 0; + + if (tx_path == RF_PATH_A) { + path_com_cr[1].data = 0x40031; + path_com_cr[2].data = 0x1000C48; + path_com_cr[5].data = 0x200; + path_com_cr[6].data = 0x1000C48; + path_com_cr[7].data = 0x40031; + } else if (tx_path == RF_PATH_B) { + path_com_cr[1].data = 0x40032; + path_com_cr[2].data = 0x1000C88; + path_com_cr[5].data = 0x400; + path_com_cr[6].data = 0x1000C88; + path_com_cr[7].data = 0x40032; + } else if (tx_path == RF_PATH_AB) { + path_com_cr[1].data = 0x00E4E433; + path_com_cr[2].data = 0x39390CC9; + path_com_cr[5].data = 0x201C8600; + path_com_cr[6].data = 0x1010CC9; + path_com_cr[7].data = 0x40433; + } else { + ret = -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(path_com_cr); i++) { + reg = rtw89_mac_reg_by_idx(rtwdev, path_com_cr[i].addr, phy_idx); + rtw89_write32(rtwdev, reg, path_com_cr[i].data); + } + + return ret; +} + +static void rtw8922d_bb_reset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ +} + +static void rtw8922d_tssi_reset(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, + B_TXPWR_RSTB0_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, + B_TXPWR_RSTB0_BE4, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, + B_TXPWR_RSTB1_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, + B_TXPWR_RSTB1_BE4, 0x1); + } + } else { + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, B_TXPWR_RSTB0_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, B_TXPWR_RSTB0_BE4, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, B_TXPWR_RSTB1_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, B_TXPWR_RSTB1_BE4, 0x1); + } +} + +static int rtw8922d_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rx_path, + enum rtw89_phy_idx phy_idx) +{ + enum rtw89_rf_path_bit path; + + if (rx_path == RF_PATH_A) + path = RF_A; + else if (rx_path == RF_PATH_B) + path = RF_B; + else + path = RF_AB; + + rtw89_phy_write32_idx(rtwdev, R_ANT_RX_BE4, B_ANT_RX_BE4, path, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_ANT_RX_1RCCA_BE4, B_ANT_RX_1RCCA_BE4, + path, phy_idx); + + if (rx_path == RF_PATH_AB) { + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC0_BE4, B_RXCH_MCS4_BE4, 8, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS5_BE4, 4, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS6_BE4, 3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS7_BE4, 7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS8_BE4, 2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN04_BE4, 4, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN07_BE4, 2, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN01_BE4, B_RX_AWGN09_BE4, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN02_BE4, B_RX_AWGN11_BE4, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC02_BE4, 0x6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC03_BE4, 0xf, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC04_BE4, 0x10, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC05_BE4, 0xa, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC06_BE4, 0x8, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC07_BE4, 0x14, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC01_BE4, B_RX_LDPC09_BE4, 0x14, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC10_BE4, 0xc, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC11_BE4, 0xb, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC12_BE4, 0x14, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC13_BE4, 0x2d, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC0_BE4, B_RXCH_MCS4_BE4, 13, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS5_BE4, 15, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS6_BE4, 6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS7_BE4, 15, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS8_BE4, 4, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN04_BE4, 9, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN07_BE4, 3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN01_BE4, B_RX_AWGN09_BE4, 1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_AWGN02_BE4, B_RX_AWGN11_BE4, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC02_BE4, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC03_BE4, 0x9, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC04_BE4, 9, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC05_BE4, 8, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC06_BE4, 6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC07_BE4, 16, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC01_BE4, B_RX_LDPC09_BE4, 9, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC10_BE4, 9, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC11_BE4, 7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC12_BE4, 0x17, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RX_LDPC03_BE4, B_RX_LDPC13_BE4, 0x1a, phy_idx); + } + + return 0; +} + +static void rtw8922d_set_digital_pwr_comp(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 nss, + enum rtw89_rf_path path, + enum rtw89_phy_idx phy_idx) +{ +#define DIGITAL_PWR_COMP_BASE_NUM 7 +#define DIGITAL_PWR_COMP_VALS_NUM 15 + static const u32 pw_comp_cr[2] = {R_RX_PATH0_TBL0_BE4, R_RX_PATH1_TBL0_BE4}; + const struct { + struct { + __le32 base[DIGITAL_PWR_COMP_BASE_NUM]; + __le32 vals[DIGITAL_PWR_COMP_VALS_NUM]; + } sets[2][RTW89_TX_COMP_BAND_NR][BB_PATH_NUM_8922D]; + } *pwr_comp_v0; + const struct { + __le32 base[DIGITAL_PWR_COMP_BASE_NUM]; + struct { + __le32 vals[DIGITAL_PWR_COMP_VALS_NUM]; + } sets[2][RTW89_TX_COMP_BAND_NR][BB_PATH_NUM_8922D]; + } *pwr_comp_v1; + const struct { + __le32 base[2][DIGITAL_PWR_COMP_BASE_NUM]; + struct { + __le32 vals[DIGITAL_PWR_COMP_VALS_NUM]; + } sets[2][RTW89_TX_COMP_BAND_NR][BB_PATH_NUM_8922D]; + } *pwr_comp; + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_fw_element_hdr *txcomp_elm = elm_info->tx_comp; + const __le32 (*comp_base)[DIGITAL_PWR_COMP_BASE_NUM]; + const __le32 (*comp_vals)[DIGITAL_PWR_COMP_VALS_NUM]; + u32 addr, val; + u32 i; + + if (sizeof(*pwr_comp) == le32_to_cpu(txcomp_elm->size)) { + pwr_comp = (const void *)txcomp_elm->u.common.contents; + comp_base = &pwr_comp->base[nss]; + comp_vals = &pwr_comp->sets[nss][chan->tx_comp_band][path].vals; + } else if (sizeof(*pwr_comp_v1) == le32_to_cpu(txcomp_elm->size)) { + pwr_comp_v1 = (const void *)txcomp_elm->u.common.contents; + comp_base = &pwr_comp_v1->base; + comp_vals = &pwr_comp_v1->sets[nss][chan->tx_comp_band][path].vals; + } else if (sizeof(*pwr_comp_v0) == le32_to_cpu(txcomp_elm->size)) { + pwr_comp_v0 = (const void *)txcomp_elm->u.common.contents; + comp_base = &pwr_comp_v0->sets[nss][chan->tx_comp_band][path].base; + comp_vals = &pwr_comp_v0->sets[nss][chan->tx_comp_band][path].vals; + } else { + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, + "incorrect power comp size %d\n", + le32_to_cpu(txcomp_elm->size)); + return; + } + + addr = pw_comp_cr[path]; + + for (i = 0; i < ARRAY_SIZE(*comp_base); i++, addr += 4) { + val = le32_to_cpu((*comp_base)[i]); + rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); + } + + for (i = 0; i < ARRAY_SIZE(*comp_vals); i++, addr += 4) { + val = le32_to_cpu((*comp_vals)[i]); + rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); + } +} + +static void rtw8922d_digital_pwr_comp(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_chan *chan0, *chan1; + struct rtw89_entity_conf conf; + + rtw89_entity_get_conf(rtwdev, &conf); + chan0 = conf.chans[0]; + chan1 = conf.chans[1]; + + if (conf.en_emlsr) { + rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_A, RTW89_PHY_0); + rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_B, RTW89_PHY_0); + rtw8922d_set_digital_pwr_comp(rtwdev, chan1, 1, RF_PATH_A, RTW89_PHY_1); + rtw8922d_set_digital_pwr_comp(rtwdev, chan1, 1, RF_PATH_B, RTW89_PHY_1); + } else if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 0, RF_PATH_A, RTW89_PHY_0); + rtw8922d_set_digital_pwr_comp(rtwdev, chan1, 0, RF_PATH_B, RTW89_PHY_1); + } else { + rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_A, phy_idx); + rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_B, phy_idx); + } +} + +static void rtw8922d_ctrl_mlo_mode_core(struct rtw89_dev *rtwdev, + enum rtw89_mlo_dbcc_mode mode) +{ + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_CLR_FORCE_BE4, 0x3); + + if (mode == MLO_2_PLUS_0_1RF) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x3BAB); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEBAD); + udelay(1); + + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEAAD); + } else if (mode == MLO_0_PLUS_2_1RF) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x3BAB); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEFFF); + + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEEFF); + } else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) { + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x3BAB); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x3AAB); + } else { + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x6180); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x180); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x0); + } +} + +static int rtw8922d_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode, + bool pwr_comp) +{ + u32 reg0, reg1; + u8 cck_phy_idx; + + rtw8922d_ctrl_mlo_mode_core(rtwdev, mode); + + if (pwr_comp) + rtw8922d_digital_pwr_comp(rtwdev, RTW89_PHY_0); + + reg0 = R_BBWRAP_ELMSR_BE4; + reg1 = rtw89_mac_reg_by_idx(rtwdev, reg0, 1); + + if (mode == MLO_2_PLUS_0_1RF) { + rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, + B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0); + rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0); + rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0); + } else if (mode == MLO_0_PLUS_2_1RF) { + rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, + B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0); + rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0); + rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0); + } else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) { + struct rtw89_entity_conf conf; + + rtw89_entity_get_conf(rtwdev, &conf); + cck_phy_idx = conf.chans[1]->band_type == RTW89_BAND_2G ? + RTW89_PHY_1 : RTW89_PHY_0; + + rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, + B_SYS_DBCC_24G_BAND_SEL_BE4, cck_phy_idx); + rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0x3); + rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0x3); + } else { + rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, + B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0); + rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0); + rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0); + } + + udelay(1); + + return 0; +} + +static void rtw8922d_bb_sethw(struct rtw89_dev *rtwdev) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_phy_idx phy_idx; + u32 reg; + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_PHY_0); + rtw89_write32_clr(rtwdev, reg, B_BE_PWR_CTRL_SEL); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_PHY_1); + rtw89_write32_clr(rtwdev, reg, B_BE_PWR_CTRL_SEL); + + if (hal->cid == RTL8922D_CID7090) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_PWR_BOOST_BE4, RTW89_PHY_0); + rtw89_write32_set(rtwdev, reg, B_PWR_BOOST_BE4); + reg = rtw89_mac_reg_by_idx(rtwdev, R_PWR_BOOST_BE4, RTW89_PHY_1); + rtw89_write32_set(rtwdev, reg, B_PWR_BOOST_BE4); + } + + rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_PSDU_BE4, 0); + rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_NSYM_BE4, 1); + rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_LSIG_BE4, 1); + rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_TXINFO_BE4, 1); + rtw89_phy_write32_mask(rtwdev, R_TXERRCT_EN_BE4, B_TXERRCT_EN_BE4, 0); + rtw89_phy_write32_mask(rtwdev, R_TXERRCT1_EN_BE4, B_TXERRCT1_EN_BE4, 0); + rtw89_phy_write32_idx(rtwdev, R_IMR_TX_ERROR_BE4, B_IMR_TX_ERROR_BE4, 1, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_IMR_TX_ERROR_BE4, B_IMR_TX_ERROR_BE4, 1, RTW89_PHY_1); + + rtw8922d_ctrl_mlo(rtwdev, rtwdev->mlo_dbcc_mode, false); + + /* read these registers after loading BB parameters */ + for (phy_idx = RTW89_PHY_0; phy_idx < RTW89_PHY_NUM; phy_idx++) { + gain->ref_gain_base[phy_idx] = + rtw89_phy_read32_idx(rtwdev, R_OFDM_OFST_P0_BE4, + B_OFDM_OFST_P0_BE4, phy_idx); + gain->cck_rpl_base[phy_idx] = + rtw89_phy_read32_idx(rtwdev, R_CCK_RPL_OFST_BE4, + B_CCK_RPL_OFST_BE4, phy_idx); + } +} + +static void rtw8922d_set_channel_bb(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_hal *hal = &rtwdev->hal; + bool cck_en = chan->band_type == RTW89_BAND_2G; + u8 pri_sb = chan->pri_sb_idx; + u32 val; + + rtw89_phy_bb_wrap_set_rfsi_ct_opt(rtwdev, chan->rfsi_band, phy_idx); + rtw8922d_ctrl_ch(rtwdev, chan, phy_idx); + rtw8922d_ctrl_bw(rtwdev, pri_sb, chan->band_width, phy_idx); + rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(rtwdev, chan, phy_idx); + + if (cck_en) + rtw8922d_ctrl_sco_cck(rtwdev, chan->primary_channel, + chan->band_width, phy_idx); + + rtw8922d_spur_elimination(rtwdev, chan, phy_idx); + + if (hal->cid == RTL8922D_CID7025) { + if (chan->band_width == RTW89_CHANNEL_WIDTH_160) + val = 0x1f9; + else if (chan->band_width == RTW89_CHANNEL_WIDTH_80) + val = 0x1f5; + else + val = 0x1e2; + + rtw89_phy_write32_idx(rtwdev, R_AWGN_DET_BE4, B_AWGN_DET_BE4, val, phy_idx); + } + + rtw8922d_tssi_reset(rtwdev, RF_PATH_AB, phy_idx); +} + +static void rtw8922d_pre_set_channel_bb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + if (!rtwdev->dbcc_en) + return; + + rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, B_SYS_DBCC_BE4, 0x0); + + if (phy_idx == RTW89_PHY_0) + rtw8922d_ctrl_mlo_mode_core(rtwdev, MLO_2_PLUS_0_1RF); + else + rtw8922d_ctrl_mlo_mode_core(rtwdev, MLO_0_PLUS_2_1RF); + + fsleep(1); +} + +static void rtw8922d_post_set_channel_bb(struct rtw89_dev *rtwdev, + enum rtw89_mlo_dbcc_mode mode, + enum rtw89_phy_idx phy_idx) +{ + if (!rtwdev->dbcc_en) + return; + + rtw8922d_ctrl_mlo(rtwdev, mode, true); +} + +static void rtw8922d_set_channel(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + rtw8922d_set_channel_mac(rtwdev, chan, mac_idx); + rtw8922d_set_channel_bb(rtwdev, chan, phy_idx); + rtw8922d_set_channel_rf(rtwdev, chan, phy_idx); +} + +static void __rtw8922d_dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, 0x3c000 + (path << 8), BIT(17), 0x0); + rtw89_phy_write32_mask(rtwdev, 0x3c000 + (path << 8), BIT(17), 0x1); +} + +static void rtw8922d_dack_reset(struct rtw89_dev *rtwdev) +{ + __rtw8922d_dack_reset(rtwdev, RF_PATH_A); + __rtw8922d_dack_reset(rtwdev, RF_PATH_B); +} + +static +void rtw8922d_hal_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, enum rtw89_mac_idx mac_idx, + enum rtw89_band band, u32 *tx_en, bool enter) +{ + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, mac_idx, tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false); + rtw8922d_dack_reset(rtwdev); + rtw8922d_tssi_cont_en_phyidx(rtwdev, false, phy_idx); + fsleep(40); + rtw8922d_bb_reset_en(rtwdev, band, false, phy_idx); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true); + rtw8922d_tssi_cont_en_phyidx(rtwdev, true, phy_idx); + rtw8922d_bb_reset_en(rtwdev, band, true, phy_idx); + rtw89_chip_resume_sch_tx(rtwdev, mac_idx, *tx_en); + } +} + +static void rtw8922d_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p, + const struct rtw89_chan *chan, + enum rtw89_mac_idx mac_idx, + enum rtw89_phy_idx phy_idx) +{ + if (enter) { + rtw8922d_pre_set_channel_bb(rtwdev, phy_idx); + rtw8922d_pre_set_channel_rf(rtwdev, phy_idx); + } + + rtw8922d_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter); + + if (!enter) { + rtw8922d_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx); + rtw8922d_post_set_channel_rf(rtwdev, phy_idx); + } +} + +static void rtw8922d_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_lck_info *lck = &rtwdev->lck; + + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + memset(rfk_mcc, 0, sizeof(*rfk_mcc)); + memset(lck, 0, sizeof(*lck)); +} + +static void __rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw8922d_rfk_mlo_ctrl(rtwdev); + + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); + if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 128); + if (phy_idx == RTW89_PHY_0) + rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58); +} + +static void rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + + __rtw8922d_rfk_init_late(rtwdev, RTW89_PHY_0, chan); + if (rtwdev->dbcc_en) + __rtw8922d_rfk_init_late(rtwdev, RTW89_PHY_1, chan); +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u32 rf_mode; + u8 path; + int ret; + + for (path = 0; path < RF_PATH_NUM_8922D; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, + 2, 5000, false, rtwdev, path, 0x00, + RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + +static void __rtw8922d_tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u8 path; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + u32 addr_ofst = (phy_idx << 12) + (path << 8); + + rtw89_phy_write32_mask(rtwdev, R_TSSI_DCK_MOV_AVG_LEN_P0_BE4 + addr_ofst, + B_TSSI_DCK_MOV_AVG_LEN_P0_BE4, 0x4); + rtw89_phy_write32_clr(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst, + B_USED_TSSI_TRK_ON_P0_BE4); + rtw89_phy_write32_set(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst, + B_USED_TSSI_TRK_ON_P0_BE4); + rtw89_phy_write32_clr(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst, + B_TSSI_EN_P0_BE4); + rtw89_phy_write32_mask(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst, + B_TSSI_EN_P0_BE4, 0x3); + } +} + +static void __rtw8922d_tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u8 path; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + u32 addr_ofst = (phy_idx << 12) + (path << 8); + + rtw89_phy_write32_clr(rtwdev, R_TSSI_DCK_MOV_AVG_LEN_P0_BE4 + addr_ofst, + B_TSSI_DCK_MOV_AVG_LEN_P0_BE4); + rtw89_phy_write32_clr(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst, + B_USED_TSSI_TRK_ON_P0_BE4); + rtw89_phy_write32_clr(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst, + B_TSSI_EN_P0_BE4); + } +} + +static void rtw8922d_rfk_tssi(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan, + enum rtw89_tssi_mode tssi_mode, + unsigned int ms) +{ + int ret; + + ret = rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, tssi_mode, ms); + if (ret) { + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; + } else { + rtwdev->is_tssi_mode[RF_PATH_A] = true; + rtwdev->is_tssi_mode[RF_PATH_B] = true; + } +} + +static void rtw8922d_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif); + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); + u32 tx_en; + + if (ieee80211_vif_is_mld(vif)) + rtw8922d_chlk_ktbl_ctl_mld(rtwdev, phy_idx, true); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, RF_AB); + + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); + rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54); + rtw89_phy_rfk_txiqk_and_wait(rtwdev, phy_idx, chan, 45); + rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84); + rtw8922d_rfk_tssi(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20); + rtw89_phy_rfk_cim3k_and_wait(rtwdev, phy_idx, chan, 44); + rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 68); + rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP); + + if (ieee80211_vif_is_mld(vif)) + rtw8922d_chlk_ktbl_ctl_mld(rtwdev, phy_idx, false); +} + +static void rtw8922d_rfk_band_changed(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ +} + +static void __rtw8922d_txiqk_disable(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 path, kidx; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + kidx = rtw89_phy_read32_mask(rtwdev, R_KTBL0A_BE4 + (path << 8), + B_KTBL0_IDX0); + if (kidx == 0) { + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX0_EN); + } else if (kidx == 1) { + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX1_EN); + } else { + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x1); + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX0_EN); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x0); + } + + iqk_info->iqc_bak[path] = + rtw89_phy_read32(rtwdev, R_TX_IQC_A_BE4 + (path << 8)); + rtw89_phy_write32(rtwdev, R_TX_IQC_A_BE4 + (path << 8), 0x40000002); + } +} + +static void __rtw8922d_txiqk_enable(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 path, kidx; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + kidx = rtw89_phy_read32_mask(rtwdev, R_KTBL0A_BE4 + (path << 8), + B_KTBL0_IDX0); + if (kidx == 0) { + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX0_EN); + } else if (kidx == 1) { + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX1_EN); + } else { + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x1); + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_KIDX0_EN); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x0); + } + + rtw89_phy_write32(rtwdev, R_TX_IQC_A_BE4 + (path << 8), + iqk_info->iqc_bak[path]); + } +} + +static void rtw8922d_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + bool start) +{ + if (start) { + __rtw8922d_tssi_disable(rtwdev, rtwvif_link->phy_idx); + __rtw8922d_txiqk_disable(rtwdev); + } else { + __rtw8922d_tssi_enable(rtwdev, rtwvif_link->phy_idx); + __rtw8922d_txiqk_enable(rtwdev); + } +} + +static void rtw8922d_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8922d_lck_track(rtwdev); +} + +static const struct rtw89_reg_def rtw8922d_txpwr_ref[][3] = { + {{ .addr = R_TXAGC_REF_DBM_PATH0_TBL0_BE4, + .mask = B_TXAGC_OFDM_REF_DBM_PATH0_TBL0_BE4 }, + { .addr = R_TXAGC_REF_DBM_PATH0_TBL0_BE4, + .mask = B_TXAGC_CCK_REF_DBM_PATH0_TBL0_BE4 }, + { .addr = R_TSSI_K_OFDM_PATH0_TBL0_BE4, + .mask = B_TSSI_K_OFDM_PATH0_TBL0_BE4 } + }, + {{ .addr = R_TXAGC_REF_DBM_PATH0_TBL1_BE4, + .mask = B_TXAGC_OFDM_REF_DBM_PATH0_TBL1_BE4 }, + { .addr = R_TXAGC_REF_DBM_PATH0_TBL1_BE4, + .mask = B_TXAGC_CCK_REF_DBM_PATH0_TBL1_BE4 }, + { .addr = R_TSSI_K_OFDM_PATH0_TBL1_BE4, + .mask = B_TSSI_K_OFDM_PATH0_TBL1_BE4 } + }, +}; + +static void rtw8922d_set_txpwr_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan); + const struct rtw89_chip_info *chip = rtwdev->chip; + static const u32 path_ofst[] = {0x0, 0x100}; + const struct rtw89_reg_def *txpwr_ref; + s16 tssi_k_ofst = abs(pwr_ofst); + s16 ofst_dec[RF_PATH_NUM_8922D]; + s16 tssi_k[RF_PATH_NUM_8922D]; + s16 pwr_ref_ofst; + s16 pwr_ref = 16; + u8 i; + + pwr_ref <<= chip->txpwr_factor_rf; + pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst)); + + ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst; + ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref; + tssi_k[RF_PATH_A] = pwr_ofst > 0 ? 0 : tssi_k_ofst; + tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : 0; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + txpwr_ref = rtw8922d_txpwr_ref[phy_idx]; + + rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i], + txpwr_ref[0].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i], + txpwr_ref[1].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i], + txpwr_ref[2].mask, tssi_k[i]); + } +} + +static void rtw8922d_set_txpwr_ref(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 ref_ofdm = 0; + s16 ref_cck = 0; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw8922d_set_txpwr_diff(rtwdev, chan, phy_idx); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL, + B_BE_PWR_REF_CTRL_OFDM, ref_ofdm); + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL, + B_BE_PWR_REF_CTRL_CCK, ref_cck); +} + +static void rtw8922d_set_tx_shape(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data; + u8 band = chan->band_type; + u8 tx_shape_idx; + const u16 *th; + + tx_shape_idx = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM); + if (tx_shape_idx == 0) + goto disable; + + th = d->bands[chan->rfsi_band].qam_comp_th0; + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKLWORD, th[0], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKHWORD, th[1], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKLWORD, th[2], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKHWORD, th[3], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKLWORD, th[4], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKHWORD, th[5], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKLWORD, th[6], phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKHWORD, th[7], phy_idx); + + th = d->bands[chan->rfsi_band].qam_comp_ow; + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKLWORD, th[0], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKHWORD, th[1], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKLWORD, th[2], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKHWORD, th[3], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKLWORD, th[4], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKHWORD, th[5], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKLWORD, th[6], phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKHWORD, th[7], phy_idx); + + return; + +disable: + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, B_QAM_COMP_TH_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, B_QAM_COMP_TH_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, B_QAM_COMP_TH_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, B_QAM_COMP_TH_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, B_QAM_COMP_TH_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, B_QAM_COMP_TH_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, B_QAM_COMP_TH_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, B_QAM_COMP_TH_TRIANGULAR_H, 0, phy_idx); + + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, B_OW_VAL_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, B_OW_VAL_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, B_OW_VAL_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, B_OW_VAL_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, B_OW_VAL_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, B_OW_VAL_TRIANGULAR_H, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, B_OW_VAL_TRIANGULAR_L, 0, phy_idx); + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, B_OW_VAL_TRIANGULAR_H, 0, phy_idx); +} + +static void rtw8922d_set_txpwr_sar_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_sar_parm sar_parm = { + .center_freq = chan->freq, + .force_path = true, + }; + s16 sar_rf; + s8 sar_mac; + + if (phy_idx != RTW89_PHY_0) + return; + + sar_parm.path = RF_PATH_A; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPWRB_BE4, B_TXPWRB_MAX_BE, sar_rf); + + sar_parm.path = RF_PATH_B; + sar_mac = rtw89_query_sar(rtwdev, &sar_parm); + sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB_BE4, B_TXPWRB_MAX_BE, sar_rf); +} + +static void rtw8922d_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); + rtw8922d_set_tx_shape(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); + rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); + rtw8922d_set_txpwr_ref(rtwdev, chan, phy_idx); + rtw8922d_set_txpwr_sar_diff(rtwdev, chan, phy_idx); +} + +static void rtw8922d_set_txpwr_ctrl(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_entity_conf conf; + + rtw89_entity_get_conf(rtwdev, &conf); + + rtw8922d_set_txpwr_ref(rtwdev, conf.chans[phy_idx], phy_idx); +} + +static void rtw8922d_ctrl_trx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path tx_path, u8 tx_nss, + enum rtw89_rf_path rx_path, u8 rx_nss) +{ + enum rtw89_phy_idx phy_idx; + + for (phy_idx = RTW89_PHY_0; phy_idx <= RTW89_PHY_1; phy_idx++) { + rtw8922d_ctrl_tx_path_tmac(rtwdev, tx_path, phy_idx); + rtw8922d_ctrl_rx_path_tmac(rtwdev, rx_path, phy_idx); + + rtw8922d_tssi_reset(rtwdev, rx_path, phy_idx); + } +} + +static void rtw8922d_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en, + enum rtw89_phy_idx phy_idx) +{ + if (en) { + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A, + 0xf, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x80, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x8080, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x3, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B, + 0xf, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA1_B, 0x80, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x34, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x34, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A, + 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x1a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x2a2a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x7a6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x26, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B, + 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B, + 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA1_B, 0x2a, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x7a6, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x26, phy_idx); + } +} + +static void rtw8922d_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + enum rtw89_band band = chan->band_type; + struct rtw89_hal *hal = &rtwdev->hal; + u8 ntx_path = RF_PATH_AB; + u8 nrx_path = RF_PATH_AB; + u32 tx_en0, tx_en1; + u8 rx_nss = 2; + + if (hal->antenna_tx == RF_A) + ntx_path = RF_PATH_A; + else if (hal->antenna_tx == RF_B) + ntx_path = RF_PATH_B; + + if (hal->antenna_rx == RF_A) + nrx_path = RF_PATH_A; + else if (hal->antenna_rx == RF_B) + nrx_path = RF_PATH_B; + + if (nrx_path != RF_PATH_AB) + rx_nss = 1; + + rtw8922d_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true); + if (rtwdev->dbcc_en) + rtw8922d_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band, + &tx_en1, true); + + rtw8922d_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss); + + rtw8922d_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false); + if (rtwdev->dbcc_en) + rtw8922d_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band, + &tx_en1, false); +} + +static u8 rtw8922d_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; + u8 val; + + rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_EN_BE4, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_TRIG_BE4, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_TRIG_BE4, 0x1); + + fsleep(100); + + val = rtw89_phy_read32_mask(rtwdev, R_TC_VAL_BE4, B_TC_VAL_BE4); + val = clamp_t(int, val + info->thermal_k, 0, 255); + + return val; +} + +static u32 rtw8922d_chan_to_rf18_val(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan) +{ + u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH); + + switch (chan->band_type) { + case RTW89_BAND_2G: + default: + break; + case RTW89_BAND_5G: + val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) | + u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0); + break; + case RTW89_BAND_6G: + val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) | + u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0); + break; + } + + switch (chan->band_width) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + default: + break; + case RTW89_CHANNEL_WIDTH_40: + val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_80: + val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_160: + val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2); + break; + case RTW89_CHANNEL_WIDTH_320: + val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2); + break; + } + + return val; +} + +static void rtw8922d_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_module *md = &btc->mdinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_cx *cx = &btc->cx; + u8 efuse_bt_func, efuse_ant_info, bt_sw_gpio_pos; + u8 is_combo, is_bt_share, is_spdt; + u8 tx_path_pos, rx_path_pos; + u8 i, j; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s !!\n", __func__); + + /* get from final capability of device */ + md->rfe_type = rtwdev->efuse.rfe_type; + md->kt_ver = rtwdev->hal.cv; + md->kt_ver_adie = rtwdev->hal.acv; + md->wa_type = 0; + dm->wl_trx_nss_en = 0; + + md->ant.num = 2; + md->ant.single_pos = BTC_RF_S0; /* WL 1ss+1Ant 0:s0(A)/ 1:s1(B) */ + + /* set default antenna isolation */ + cx->bt0.ant_iso_to_wl = md->ant.isolation; + cx->bt1.ant_iso_to_wl = md->ant.isolation; + + md->ant.stream_cnt = (rtwdev->hal.tx_nss << BTC_ANT_SHIFT) + + rtwdev->hal.rx_nss; + md->ant.btg_pos = BTC_RF_S1; /* BTG0 at WL-S1 */ + md->ant.btg1_pos = BTC_RF_S0; /* BTG1 at WL-S0 if Dual-BTGA */ + + cx->bt0.band_56G_support = 1; + cx->bt1.band_56G_support = 1; + cx->bt0.func_type = BTC_BTF_BT; + cx->bt1.func_type = BTC_BTF_BT; + + efuse_bt_func = rtwdev->efuse.bt_setting_2; + + is_spdt = !!(efuse_bt_func & BIT(5)); + + switch ((efuse_bt_func & 0xc0) >> 6) { /* 0xcd[7:6] */ + default: + case 0: + bt_sw_gpio_pos = 5; + break; + case 1: + bt_sw_gpio_pos = 11; + break; + case 2: + bt_sw_gpio_pos = 15; + break; + case 3: + bt_sw_gpio_pos = 20; + break; + } + + efuse_bt_func &= 0x1f; /* 0xcd[4:0] */ + efuse_ant_info = rtwdev->efuse.bt_setting_3; + md->ant.num = (efuse_ant_info & 0xe0) >> 5; /* 0xCE[7:5] */ + is_combo = (efuse_ant_info & 0xe) >> 1; /* 0xCE[3:1] */ + is_bt_share = efuse_ant_info & BIT(0); /* 0xCE[0] */ + + memset(dm->ant_xmap, 0, sizeof(dm->ant_xmap)); + + /* To-Do: "RFE_TYpe" to "ant.num" translation */ + switch (md->ant.num) { + case 1: /* 1-Ant WL-S0 only & BT0 only */ + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_V1_INTERNAL; + md->ant.btg_pos = BTC_RF_S0; /* BTG0 at WL-S0 */ + md->ant.func[0] = BTC_EFMAP_BT0; + dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 1; /* BT0 shared with S0*/ + dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* WL 1T1R no RF-S1 */ + break; + case 2: /* 2-Ant */ + default: + if (is_combo) { + if (efuse_bt_func == (BTC_EFMAP_BT0 | BTC_EFMAP_BT1)) + md->ant.func[0] = BTC_EFMAP_BT1; + + md->ant.func[1] = BTC_EFMAP_BT0; + } else { + md->ant.func[0] = BTC_EFMAP_NONE; + md->ant.func[1] = BTC_EFMAP_NONE; + } + + if (is_bt_share) { /* WL-S0 + (WL-S1 & BT0-S1) */ + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_INTERNAL; + dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1; + } else { /* WL-S0 + BT0-S1 */ + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_V1_NONE; + } + + if (md->ant.func[0] == BTC_EFMAP_BT1) { /* if 2nd BT exist */ + dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 1; + if (is_spdt) { /* WL-S0 & BT1 by SPDT */ + md->bt1_pos = BTC_BT_ALONE; + /* Todo: set SPDT GPIO-ctrl */ + md->bt1_sw_type = bt_sw_gpio_pos; + } else { /* WL-S0 & BT1-S1 by BTGA */ + md->bt1_pos = BTC_BT_BTG; + md->bt1_sw_type = BTC_SWITCH_V1_INTERNAL; + } + } + + dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability if 1-BT */ + break; + case 3: /* 3-Ant, 3 different BT-configuration */ + if (is_bt_share) { + md->ant.func[0] = BTC_EFMAP_NONE; + md->ant.func[1] = BTC_EFMAP_BT0; + md->ant.func[2] = efuse_bt_func & (~BTC_EFMAP_BT0); + md->ant.type = BTC_ANT_SHARED; + md->bt0_pos = BTC_BT_BTG; + md->bt0_sw_type = BTC_SWITCH_V1_INTERNAL; + dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1; + dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability */ + } else { + md->ant.func[0] = BTC_EFMAP_NONE; + md->ant.func[1] = BTC_EFMAP_NONE; + md->ant.func[2] = efuse_bt_func; + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_V1_NONE; + } + + md->bt1_pos = BTC_BT_ALONE; /* BT1 may exist or not */ + md->bt1_sw_type = BTC_SWITCH_V1_NONE; + break; + case 4: /* 4-Ant, WL-S0 + WL-S1 + BT0 + BT1 */ + md->ant.func[0] = BTC_EFMAP_NONE; + md->ant.func[1] = BTC_EFMAP_NONE; + md->ant.func[2] = BTC_EFMAP_BT0; + md->ant.func[3] = efuse_bt_func & (~BTC_EFMAP_BT0); + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_V1_NONE; + md->bt1_pos = BTC_BT_ALONE; + md->bt1_sw_type = BTC_SWITCH_V1_NONE; + break; + case 5: + md->ant.func[0] = BTC_EFMAP_NONE; + md->ant.func[1] = BTC_EFMAP_NONE; + md->ant.func[2] = BTC_EFMAP_BT0; + md->ant.func[3] = BTC_EFMAP_BT1; + md->ant.func[4] = BTC_EFMAP_ZB; + md->ant.type = BTC_ANT_DEDICATED; + md->bt0_pos = BTC_BT_ALONE; + md->bt0_sw_type = BTC_SWITCH_V1_NONE; + md->bt1_pos = BTC_BT_ALONE; + md->bt1_sw_type = BTC_SWITCH_V1_NONE; + break; + } + + tx_path_pos = _btc_get_rf_path_from_ant_num(btc, rtwdev->hal.tx_nss); + rx_path_pos = _btc_get_rf_path_from_ant_num(btc, rtwdev->hal.rx_nss); + /* Combine TX[7:4] and RX[3:0] into path_pos byte */ + md->ant.path_pos = ((tx_path_pos << BTC_ANT_SHIFT) & BTC_ANT_TX_MASK) | + (rx_path_pos & BTC_ANT_RX_MASK); + + /* + * if only BT0 at BTGA: 2-Ant, 3-Ant(BT1 used dedicated-ant) + * can setup dm->wl_trx_nss_en = 1, WL MIMO-PS to 1T1R + * (WL at WL-S0 only, BT0 at WL-S1) + * tx_limit/rx_limit is decided by _set_trx_nss() + */ + if (dm->wl_trx_nss_en && + (dm->wl_trx_nss.tx_limit && dm->wl_trx_nss.rx_limit)) { + md->ant.type = BTC_ANT_DEDICATED; + md->ant.stream_cnt = 1; + dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 0; /* wl 1ss-> RF-S0 */ + dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* BT0-> RF-S1 */ + dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 0; + dm->ant_xmap[BTC_RF_S1][BTC_BT_2ND] = 0; /* BT1 -> 3rd Ant */ + } + + /* + * Todo: call HALBB API to set BT0/1 at WL_S0 or WL_S1 + * r_sel_gnt_bt_rx_path0[1:0], r_sel_gnt_bt_rx_path1[1:0] + * WL_S0 with BT1 -> r_sel_gnt_bt_rx_path0[1:0]= 2b'10 + * WL_S1 with BT0 -> r_sel_gnt_bt_rx_path1[1:0]= 2b'01 + */ + + /* To Do: setup ext-SOC coex if exist */ + switch (cx->bt_ext.chip_id) { + default: + case BTC_ESOC_NONE: + memset(&cx->bt_ext, 0, sizeof(struct rtw89_btc_extsoc_info)); + cx->bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR; + cx->bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO; + break; + case BTC_ESOC_8771: + cx->bt_ext.func_type = BTC_BTF_THREAD; + cx->bt_ext.hw_coex = BTC_EXTSOC_INTF_PTA; + cx->bt_ext.rf_band_map = 0x1; /* 2.4GHz only */ + cx->bt_ext.link_weight[BTC_BT_B2G] = 10; + cx->bt_ext.profile_map[BTC_BT_B2G] |= BTC_BT_THREAD; + /* use GPIO 12~15 for Ext-4-wire-PTA */ + cx->bt_ext.hpta_cfg = BIT(12) | BIT(13) | BIT(14) | BIT(15); + /* for Ext-SOC locate at Ant-2 */ + if (md->ant.num >= 5) + md->ant.func[4] = BTC_EFMAP_ZB; + else + md->ant.func[md->ant.num - 1] = BTC_EFMAP_ZB; + break; + } + + dm->ant_xmap[BTC_RF_S0][BTC_BT_EXT] = 0; + dm->ant_xmap[BTC_RF_S1][BTC_BT_EXT] = 0; + + for (i = BTC_RF_S0; i <= BTC_RF_S1; i++) + for (j = BTC_BT_1ST; j <= BTC_BT_EXT; j++) + md->ant.ant_xmap[i][j] = dm->ant_xmap[i][j]; + + rtwdev->btc.btg_pos = md->ant.btg_pos; + rtwdev->btc.ant_type = md->ant.type; +} + +static void rtw8922d_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + /* offload to firmware */ +} + +static void +rtw8922d_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0)); + u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16)); + + switch (ctrl_all_time) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_VAL, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, + B_BE_FORCE_PWR_BY_RATE_EN, 0x1); + break; + } + + switch (ctrl_gnt_bt) { + case 0xffff: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, + B_BE_PWR_BT_EN, 0x0); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, + B_BE_PWR_BT_VAL, 0x0); + break; + default: + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, + B_BE_PWR_BT_VAL, ctrl_gnt_bt); + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, + B_BE_PWR_BT_EN, 0x1); + break; + } +} + +static +s8 rtw8922d_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + return clamp_t(s8, val, -100, 0) + 100; +} + +static const struct rtw89_btc_rf_trx_para_v9 rtw89_btc_8922d_rf_ul_v9[] = { + /* + * 0 -> original + * 1 -> for BT-connected ACI issue && BTG co-rx + * 2 ~ 4 ->reserved for shared-antenna + * 5 ~ 8 ->for non-shared-antenna free-run + */ + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {2, 2}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{ 6, 6}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{13, 13}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{13, 13}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, +}; + +static const struct rtw89_btc_rf_trx_para_v9 rtw89_btc_8922d_rf_dl_v9[] = { + /* + * 0 -> original + * 1 -> for BT-connected ACI issue && BTG co-rx + * 2 ~ 4 ->reserved for shared-antenna + * 5 ~ 8 ->for non-shared-antenna free-run + */ + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {2, 2}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, + {{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}}, +}; + +static const u8 rtw89_btc_8922d_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; +static const u8 rtw89_btc_8922d_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; + +static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922d_mon_reg[] = { + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe354), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe35c), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe370), + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe380), +}; + +static +void rtw8922d_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + /* Feature move to firmware */ +} + +static +void rtw8922d_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + /* Feature move to firmware */ +} + +static void rtw8922d_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) +{ + /* Feature move to firmware */ +} + +static void rtw8922d_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 chan_idx = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan_idx == 0) + return; + + rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void rtw8922d_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + u8 *rx_power = phy_ppdu->rssi; + + if (!status->signal) + status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], + rx_power[RF_PATH_B])); + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); + } + if (phy_ppdu->valid) + rtw8922d_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + +static void rtw8922d_convert_rpl_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu) +{ + /* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */ + static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0}; + u8 *rssi = phy_ppdu->rssi; + u8 compensate = 0; + u8 i; + + if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate)) + compensate = bw_compensate[phy_ppdu->bw_idx]; + + for (i = 0; i < RF_PATH_NUM_8922D; i++) { + if (!(phy_ppdu->rx_path_en & BIT(i))) { + rssi[i] = 0; + phy_ppdu->rpl_path[i] = 0; + phy_ppdu->rpl_fd[i] = 0; + } + + if (phy_ppdu->ie != RTW89_CCK_PKT && rssi[i]) + rssi[i] += compensate; + + phy_ppdu->rpl_path[i] = rssi[i]; + } +} + +static void rtw8922d_phy_rpt_to_rssi(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + struct ieee80211_rx_status *rx_status) +{ + if (desc_info->rssi <= 0x1 || (desc_info->rssi >> 2) > MAX_RSSI) + return; + + rx_status->signal = (desc_info->rssi >> 2) - MAX_RSSI; +} + +static int rtw8922d_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + return 0; +} + +static int rtw8922d_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + return 0; +} + +static const struct rtw89_chanctx_listener rtw8922d_chanctx_listener = { + .callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8922d = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_NET_DETECT, + .n_patterns = RTW89_MAX_PATTERN_NUM, + .pattern_max_len = RTW89_MAX_PATTERN_SIZE, + .pattern_min_len = 1, + .max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID, +}; +#endif + +static const struct rtw89_chip_ops rtw8922d_chip_ops = { + .enable_bb_rf = rtw8922d_mac_enable_bb_rf, + .disable_bb_rf = rtw8922d_mac_disable_bb_rf, + .bb_preinit = rtw8922d_bb_preinit, + .bb_postinit = rtw8922d_bb_postinit, + .bb_reset = rtw8922d_bb_reset, + .bb_sethw = rtw8922d_bb_sethw, + .read_rf = rtw89_phy_read_rf_v3, + .write_rf = rtw89_phy_write_rf_v3, + .set_channel = rtw8922d_set_channel, + .set_channel_help = rtw8922d_set_channel_help, + .read_efuse = rtw8922d_read_efuse, + .read_phycap = rtw8922d_read_phycap, + .fem_setup = NULL, + .data_setup = rtw8922d_data_setup, + .rfe_gpio = NULL, + .rfk_hw_init = rtw8922d_rfk_hw_init, + .rfk_init = rtw8922d_rfk_init, + .rfk_init_late = rtw8922d_rfk_init_late, + .rfk_channel = rtw8922d_rfk_channel, + .rfk_band_changed = rtw8922d_rfk_band_changed, + .rfk_scan = rtw8922d_rfk_scan, + .rfk_track = rtw8922d_rfk_track, + .power_trim = rtw8922d_power_trim, + .set_txpwr = rtw8922d_set_txpwr, + .set_txpwr_ctrl = rtw8922d_set_txpwr_ctrl, + .init_txpwr_unit = NULL, + .get_thermal = rtw8922d_get_thermal, + .chan_to_rf18_val = rtw8922d_chan_to_rf18_val, + .ctrl_btg_bt_rx = rtw8922d_set_gbt_bt_rx_sel, + .query_ppdu = rtw8922d_query_ppdu, + .convert_rpl_to_rssi = rtw8922d_convert_rpl_to_rssi, + .phy_rpt_to_rssi = rtw8922d_phy_rpt_to_rssi, + .ctrl_nbtg_bt_tx = rtw8922d_ctrl_nbtg_bt_tx, + .cfg_txrx_path = rtw8922d_bb_cfg_txrx_path, + .set_txpwr_ul_tb_offset = NULL, + .digital_pwr_comp = rtw8922d_digital_pwr_comp, + .calc_rx_gain_normal = rtw8922d_calc_rx_gain_normal, + .path_diff_update = rtw8922d_path_diff_update, + .pwr_on_func = rtw8922d_pwr_on_func, + .pwr_off_func = rtw8922d_pwr_off_func, + .query_rxdesc = rtw89_core_query_rxdesc_v3, + .fill_txdesc = rtw89_core_fill_txdesc_v3, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v2, + .get_ch_dma = {rtw89_core_get_ch_dma_v1, + NULL, + NULL,}, + .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v2, + .mac_cfg_gnt = rtw89_mac_cfg_gnt_v3, + .stop_sch_tx = rtw89_mac_stop_sch_tx_v2, + .resume_sch_tx = rtw89_mac_resume_sch_tx_v2, + .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v3, + .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl_be, + .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl_be, + .h2c_ampdu_cmac_tbl = rtw89_fw_h2c_ampdu_cmac_tbl_be, + .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl_be, + .h2c_punctured_cmac_tbl = rtw89_fw_h2c_punctured_cmac_tbl_be, + .h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v3, + .h2c_update_beacon = rtw89_fw_h2c_update_beacon_be, + .h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update_v1, + + .btc_set_rfe = rtw8922d_btc_set_rfe, + .btc_init_cfg = rtw8922d_btc_init_cfg, + .btc_set_wl_pri = NULL, + .btc_set_wl_txpwr_ctrl = rtw8922d_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8922d_btc_get_bt_rssi, + .btc_update_bt_cnt = rtw8922d_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8922d_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8922d_btc_set_wl_rx_gain, + .btc_set_policy = rtw89_btc_set_policy_v1, +}; + +const struct rtw89_chip_info rtw8922d_chip_info = { + .chip_id = RTL8922D, + .chip_gen = RTW89_CHIP_BE, + .ops = &rtw8922d_chip_ops, + .mac_def = &rtw89_mac_gen_be, + .phy_def = &rtw89_phy_gen_be_v1, + .fw_def = { + .fw_basename = RTW8922D_FW_BASENAME, + .fw_format_max = RTW8922D_FW_FORMAT_MAX, + .fw_b_aid = RTL8922D_AID7102, + }, + .try_ce_fw = false, + .bbmcu_nr = 0, + .needed_fw_elms = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_V1, + .fw_blacklist = &rtw89_fw_blacklist_default, + .fifo_size = 393216, + .small_fifo_size = false, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 11000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991, + .max_eht_mpdu_cap = IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991, + .max_tx_agg_num = 128, + .max_rx_agg_num = 256, + .dis_2g_40m_ul_ofdma = false, + .rsvd_ple_ofst = 0x5f800, + .qta_def = { + .hfc_param_ini = {rtw8922d_hfc_param_ini_pcie, NULL, NULL, NULL}, + .dle_mem = {rtw8922d_dle_mem_pcie, NULL, NULL, NULL}, + }, + .wde_qempty_acq_grpnum = 8, + .wde_qempty_mgq_grpsel = 8, + .rf_base_addr = {0x3e000, 0x3f000}, + .thermal_th = {0xac, 0xb4}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, + .bb_table = NULL, + .bb_gain_table = NULL, + .rf_table = {}, + .nctl_table = NULL, + .nctl_post_table = &rtw8922d_nctl_post_defs_tbl, + .dflt_parms = NULL, /* load parm from fw */ + .rfe_parms_conf = NULL, /* load parm from fw */ + .chanctx_listener = &rtw8922d_chanctx_listener, + .txpwr_factor_bb = 3, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, + .dig_table = NULL, + .dig_regs = &rtw8922d_dig_regs, + .tssi_dbw_table = NULL, + .support_macid_num = 64, + .support_link_num = 2, + .support_chanctx_num = 2, + .support_rnr = true, + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ) | + BIT(NL80211_BAND_6GHZ), + .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160), + .support_unii4 = true, + .support_ant_gain = false, + .support_tas = false, + .support_sar_by_ant = true, + .support_noise = false, + .support_fw_cmd_ofld = false, + .ul_tb_waveform_ctrl = false, + .ul_tb_pwr_diff = false, + .rx_freq_from_ie = false, + .hw_sec_hdr = true, + .hw_mgmt_tx_encrypt = true, + .hw_tkip_crypto = true, + .hw_mlo_bmc_crypto = true, + .rf_path_num = 2, + .tx_nss = 2, + .rx_nss = 2, + .acam_num = 128, + .bcam_num = 16, + .scam_num = 32, + .bacam_num = 24, + .bacam_dynamic_num = 8, + .bacam_ver = RTW89_BACAM_V1, + .addrcam_ver = 1, + .ppdu_max_usr = 16, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 0x1300, + .logical_efuse_size = 0x70000, + .limit_efuse_size = 0x40000, + .dav_phy_efuse_size = 0, + .dav_log_efuse_size = 0, + .efuse_blocks = rtw8922d_efuse_blocks, + .phycap_addr = 0x1700, + .phycap_size = 0x60, + .para_ver = 0x3ff, + .wlcx_desired = 0x09150000, + .scbd = 0x1, + .mailbox = 0x1, + + .afh_guard_ch = 6, + .fdd_iso_freq = 1000, + .wl_rssi_thres = rtw89_btc_8922d_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8922d_bt_rssi_thres, + .rssi_tol = 2, + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8922d_mon_reg), + .mon_reg = rtw89_btc_8922d_mon_reg, + .rf_para_ulink_v0 = NULL, + .rf_para_dlink_v0 = NULL, + .rf_para_ulink_num_v0 = 0, + .rf_para_dlink_num_v0 = 0, + .rf_para_ulink_v9 = rtw89_btc_8922d_rf_ul_v9, + .rf_para_dlink_v9 = rtw89_btc_8922d_rf_dl_v9, + .rf_para_ulink_num_v9 = ARRAY_SIZE(rtw89_btc_8922d_rf_ul_v9), + .rf_para_dlink_num_v9 = ARRAY_SIZE(rtw89_btc_8922d_rf_dl_v9), + .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | + BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_G7, + .hci_func_en_addr = R_BE_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_rxdesc_short_v3), + .txwd_body_size = sizeof(struct rtw89_txwd_body_v2), + .txwd_info_size = sizeof(struct rtw89_txwd_info_v2), + .h2c_ctrl_reg = R_BE_H2CREG_CTRL, + .h2c_counter_reg = {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, + .h2c_regs = rtw8922d_h2c_regs, + .c2h_ctrl_reg = R_BE_C2HREG_CTRL, + .c2h_counter_reg = {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, + .c2h_regs = rtw8922d_c2h_regs, + .page_regs = &rtw8922d_page_regs, + .wow_reason_reg = rtw8922d_wow_wakeup_regs, + .cfo_src_fd = true, + .cfo_hw_comp = true, + .dcfo_comp = NULL, + .dcfo_comp_sft = 0, + .nhm_report = NULL, + .nhm_th = NULL, + .imr_info = NULL, + .imr_dmac_table = &rtw8922d_imr_dmac_table, + .imr_cmac_table = &rtw8922d_imr_cmac_table, + .rrsr_cfgs = &rtw8922d_rrsr_cfgs, + .bss_clr_vld = {R_BSS_CLR_VLD_BE4, B_BSS_CLR_VLD_BE4}, + .bss_clr_map_reg = R_BSS_CLR_MAP_BE4, + .rfkill_init = &rtw8922d_rfkill_regs, + .rfkill_get = {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9}, + .btc_sb = {{{R_BE_SCOREBOARD_0, R_BE_SCOREBOARD_0_BT_DATA}, + {R_BE_SCOREBOARD_1, R_BE_SCOREBOARD_1_BT_DATA}}}, + .dma_ch_mask = BIT(RTW89_DMA_ACH1) | BIT(RTW89_DMA_ACH3) | + BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH7) | + BIT(RTW89_DMA_B0HI) | BIT(RTW89_DMA_B1HI), + .edcca_regs = &rtw8922d_edcca_regs, + .pmac_regs = &rtw8922d_pmac_regs, +#ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8922d, +#endif + .xtal_info = NULL, + .default_quirks = BIT(RTW89_QUIRK_THERMAL_PROT_120C), + .txtime_limit_2ghz = 4608, +}; +EXPORT_SYMBOL(rtw8922d_chip_info); + +static const struct rtw89_fw_def rtw8922de_vs_fw_def = { + .fw_basename = RTW8922DS_FW_BASENAME, + .fw_format_max = RTW8922DS_FW_FORMAT_MAX, + .fw_b_aid = RTL8922D_AID7060, +}; + +static const struct rtw89_qta_def rtw8922ds_qta_def = { + .hfc_param_ini = {rtw8922ds_hfc_param_ini_pcie, NULL, NULL}, + .dle_mem = {rtw8922ds_dle_mem_pcie, NULL, NULL, NULL}, +}; + +const struct rtw89_chip_variant rtw8922de_vs_variant = { + .no_mcs_12_13 = true, + .fw_min_ver_code = RTW89_FW_VER_CODE(0, 0, 0, 0), + .fw_def_override = &rtw8922de_vs_fw_def, + .qta_def_override = &rtw8922ds_qta_def, +}; +EXPORT_SYMBOL(rtw8922de_vs_variant); + +MODULE_FIRMWARE(RTW8922D_MODULE_FIRMWARE); +MODULE_FIRMWARE(RTW8922DS_MODULE_FIRMWARE); +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11be wireless 8922D driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.h b/drivers/net/wireless/realtek/rtw89/rtw8922d.h new file mode 100644 index 000000000..22a7d1cc2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2026 Realtek Corporation + */ + +#ifndef __RTW89_8922D_H__ +#define __RTW89_8922D_H__ + +#include "core.h" + +#define RF_PATH_NUM_8922D 2 +#define BB_PATH_NUM_8922D 2 + +struct rtw8922d_tssi_offset { + u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; + u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; + u8 rsvd[7]; + u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; + u8 bw_diff_5g[10]; +} __packed; + +struct rtw8922d_tssi_offset_6g { + u8 bw40_1s_tssi_6g[TSSI_MCS_6G_CH_GROUP_NUM]; + u8 rsvd[0xa]; +} __packed; + +struct rtw8922d_rx_gain { + u8 _2g_ofdm; + u8 _2g_cck; + u8 _5g_low; + u8 _5g_mid; + u8 _5g_high; +} __packed; + +struct rtw8922d_rx_gain_6g { + u8 _6g_l0; + u8 _6g_l1; + u8 _6g_m0; + u8 _6g_m1; + u8 _6g_h0; + u8 _6g_h1; + u8 _6g_uh0; + u8 _6g_uh1; +} __packed; + +struct rtw8922d_efuse { + u8 country_code[2]; + u8 rsvd[0xe]; + struct rtw8922d_tssi_offset path_a_tssi; + struct rtw8922d_tssi_offset path_b_tssi; + u8 rsvd1[0x54]; + u8 channel_plan; + u8 xtal_k; + u8 rsvd2[0x7]; + u8 board_info; + u8 rsvd3[0x8]; + u8 rfe_type; + u8 rsvd4[2]; + u8 bt_setting_2; + u8 bt_setting_3; + u8 rsvd4_2; + u8 path_a_therm; + u8 path_b_therm; + u8 rsvd5[0x2]; + struct rtw8922d_rx_gain rx_gain_a; + struct rtw8922d_rx_gain rx_gain_b; + u8 rsvd6[0x18]; + struct rtw8922d_rx_gain rx_gain_a_2; + struct rtw8922d_rx_gain rx_gain_b_2; + struct rtw8922d_tssi_offset_6g path_a_tssi_6g; + struct rtw8922d_tssi_offset_6g path_b_tssi_6g; + struct rtw8922d_tssi_offset_6g path_c_tssi_6g; + struct rtw8922d_tssi_offset_6g path_d_tssi_6g; + struct rtw8922d_rx_gain_6g rx_gain_6g_a; + struct rtw8922d_rx_gain_6g rx_gain_6g_b; + u8 rsvd7[0x5a]; + struct rtw8922d_rx_gain_6g rx_gain_6g_a_2; + struct rtw8922d_rx_gain_6g rx_gain_6g_b_2; +} __packed; + +extern const struct rtw89_chip_info rtw8922d_chip_info; +extern const struct rtw89_chip_variant rtw8922de_vs_variant; + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c new file mode 100644 index 000000000..a465e6631 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include "chan.h" +#include "debug.h" +#include "phy.h" +#include "reg.h" +#include "rtw8922d.h" +#include "rtw8922d_rfk.h" + +static const struct rtw89_reg5_def rtw8922d_nctl_post_defs[] = { + RTW89_DECL_RFK_WM(0x20c7c, 0x00e00000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8922d_nctl_post_defs); + +static void rtw8922d_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path, u8 phy_idx) +{ + static const u32 tssi_trk_man[2] = {R_TSSI_EN_P0_BE4, + R_TSSI_EN_P0_BE4 + 0x100}; + + if (en) + rtw89_phy_write32_idx(rtwdev, tssi_trk_man[path], + B_TSSI_CONT_EN, 0, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, tssi_trk_man[path], + B_TSSI_CONT_EN, 1, phy_idx); +} + +void rtw8922d_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) +{ + if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { + if (phy_idx == RTW89_PHY_0) + rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_A, phy_idx); + else + rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_B, phy_idx); + } else { + rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_A, phy_idx); + rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_B, phy_idx); + } +} + +static +void rtw8922d_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + const struct rtw89_chan *chan) +{ + u8 synpath; + u32 rf18; + + synpath = rtw89_phy_get_syn_sel(rtwdev, phy); + rf18 = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + rtw89_write_rf(rtwdev, synpath, RR_RSV1, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, synpath, RR_MOD, RFREG_MASK, 0x30000); + rtw89_write_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK, rf18); + fsleep(400); + rtw89_write_rf(rtwdev, synpath, RR_RSV1, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, synpath, RR_CFGCH_V1, RFREG_MASK, rf18); +} + +void rtw8922d_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + rtw8922d_ctl_band_ch_bw(rtwdev, phy_idx, chan); +} + +enum _rf_syn_pow { + RF_SYN_ON_OFF, + RF_SYN_OFF_ON, + RF_SYN_ALLON, + RF_SYN_ALLOFF, +}; + +static void rtw8922d_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn); + + if (syn == RF_SYN_ALLON) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, BIT(1), 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, BIT(1), 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x1); + } else if (syn == RF_SYN_ON_OFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, BIT(1), 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x1); + } else if (syn == RF_SYN_OFF_ON) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, BIT(1), 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x1); + } else if (syn == RF_SYN_ALLOFF) { + rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); + } +} + +void rtw8922d_chlk_ktbl_ctl_mld(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool manual) +{ + if (manual) { + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + u8 path = phy_idx; /* numerical equal for target */ + u8 idx = rfk_mcc[path].table_idx; + + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX0, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX1, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX0, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX1, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL0, idx & BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1); + rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL0, idx & BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1); + return; + } + + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_SW_SEL, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_SW_SEL, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_SW_SEL, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_SW_SEL, 0x0); +} + +static void rtw8922d_chlk_ktbl_sel_mld(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 idx) +{ + if (phy_idx == RTW89_PHY_0) { + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_MLD_IDX0, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_MLD_IDX0, idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TBL_SEL_IDX0, idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TBL_SEL_IDX0, idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TBL_SEL_IDX0, idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TBL_SEL_IDX0, idx); + } else if (phy_idx == RTW89_PHY_1) { + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_MLD_IDX1, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_MLD_IDX1, idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TBL_SEL_IDX1, idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TBL_SEL_IDX1, idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TBL_SEL_IDX1, idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TBL_SEL_IDX1, idx); + } + + rtw8922d_chlk_ktbl_ctl_mld(rtwdev, phy_idx, false); +} + +static void rtw8922d_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx) +{ + if (idx > 2) { + rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx); + return; + } + + if (kpath & RF_A) { + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX0, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX1, idx); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TXG_SEL, 0x4 | idx); + + rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL0, idx & BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1); + } + + if (kpath & RF_B) { + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX0, idx); + rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX1, idx); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TXG_SEL, 0x4 | idx); + + rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL0, idx & BIT(0)); + rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1); + } +} + +static u8 rtw8922d_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; + u8 tbl_sel; + + for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { + struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; + + p->ch = rfk_mcc->ch[tbl_sel]; + + p->has_band = true; + p->band = rfk_mcc->band[tbl_sel]; + + p->has_bw = true; + p->bw = rfk_mcc->bw[tbl_sel]; + } + + tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[tbl_sel] = chan->channel; + rfk_mcc->band[tbl_sel] = chan->band_type; + rfk_mcc->bw[tbl_sel] = chan->band_width; + rfk_mcc->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + /* shared table array, but tbl_sel can be independent by path */ + rfk_mcc[path].table_idx = tbl_sel; + + return tbl_sel; +} + +static void rtw8922d_chlk_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_entity_conf conf; + u8 s0_tbl, s1_tbl; + + rtw89_entity_get_conf(rtwdev, &conf); + + s0_tbl = rtw8922d_chlk_reload_sel_tbl(rtwdev, conf.chans[0], 0); + s1_tbl = rtw8922d_chlk_reload_sel_tbl(rtwdev, conf.chans[1], 1); + + if (conf.is_mld) + goto mld; + + rtw8922d_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl); + rtw8922d_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl); + return; + +mld: + if (test_bit(RTW89_PHY_0, conf.hw_bitmap)) + rtw8922d_chlk_ktbl_sel_mld(rtwdev, RTW89_PHY_0, s0_tbl); + if (test_bit(RTW89_PHY_1, conf.hw_bitmap)) + rtw8922d_chlk_ktbl_sel_mld(rtwdev, RTW89_PHY_1, s1_tbl); +} + +static enum _rf_syn_pow rtw8922d_get_syn_pow(struct rtw89_dev *rtwdev) +{ + switch (rtwdev->mlo_dbcc_mode) { + case MLO_0_PLUS_2_1RF: + return RF_SYN_OFF_ON; + case MLO_0_PLUS_2_2RF: + case MLO_1_PLUS_1_2RF: + case MLO_2_PLUS_0_1RF: + case MLO_2_PLUS_0_2RF: + case MLO_2_PLUS_2_2RF: + case MLO_DBCC_NOT_SUPPORT: + default: + return RF_SYN_ON_OFF; + case MLO_1_PLUS_1_1RF: + case DBCC_LEGACY: + return RF_SYN_ALLON; + } +} + +void rtw8922d_rfk_mlo_ctrl(struct rtw89_dev *rtwdev) +{ + enum _rf_syn_pow syn_pow = rtw8922d_get_syn_pow(rtwdev); + + if (!rtwdev->dbcc_en) + goto set_rfk_reload; + + rtw8922d_set_syn01(rtwdev, syn_pow); + +set_rfk_reload: + rtw8922d_chlk_reload(rtwdev); +} + +static void rtw8922d_x4k_setting(struct rtw89_dev *rtwdev) +{ + u32 val; + + val = rtw89_read_rf(rtwdev, RF_PATH_A, 0xB9, 0xF000); + rtw89_write_rf(rtwdev, RF_PATH_A, 0xB9, 0xF000, val); + val = rtw89_read_rf(rtwdev, RF_PATH_B, 0xB9, 0xF000); + rtw89_write_rf(rtwdev, RF_PATH_B, 0xB9, 0xF000, val); + + rtw89_write_rf(rtwdev, RF_PATH_A, 0xC2, BIT(19), 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, 0xC2, BIT(19), 0x1); +} + +void rtw8922d_rfk_hw_init(struct rtw89_dev *rtwdev) +{ + rtw8922d_x4k_setting(rtwdev); +} + +void rtw8922d_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + bool mlo_1_1; + + if (!rtwdev->dbcc_en) + return; + + mlo_1_1 = rtw89_is_mlo_1_1(rtwdev); + if (mlo_1_1) + rtw8922d_set_syn01(rtwdev, RF_SYN_ALLON); + else if (phy_idx == RTW89_PHY_0) + rtw8922d_set_syn01(rtwdev, RF_SYN_ON_OFF); + else + rtw8922d_set_syn01(rtwdev, RF_SYN_OFF_ON); + + fsleep(1000); +} + +void rtw8922d_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw8922d_rfk_mlo_ctrl(rtwdev); +} + +static u8 _get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + return rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL_V1); +} + +static void _lck_keep_thermal(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + lck->thermal[path] = _get_thermal(rtwdev, path); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d thermal=0x%x", path, lck->thermal[path]); + } +} + +static void _lck(struct rtw89_dev *rtwdev) +{ + enum _rf_syn_pow syn_pow = rtw8922d_get_syn_pow(rtwdev); + u8 path_mask = 0; + u32 tmp18, tmp5; + int path; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "[LCK] DO LCK\n"); + + if (syn_pow == RF_SYN_ALLON) + path_mask = BIT(RF_PATH_A) | BIT(RF_PATH_B); + else if (syn_pow == RF_SYN_ON_OFF) + path_mask = BIT(RF_PATH_A); + else if (syn_pow == RF_SYN_OFF_ON) + path_mask = BIT(RF_PATH_B); + else + return; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + if (!(path_mask & BIT(path))) + continue; + + tmp18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, MASKDWORD); + tmp5 = rtw89_read_rf(rtwdev, path, RR_RSV1, MASKDWORD); + + rtw89_write_rf(rtwdev, path, RR_MOD, MASKDWORD, 0x10000); + rtw89_write_rf(rtwdev, path, RR_RSV1, MASKDWORD, 0x0); + rtw89_write_rf(rtwdev, path, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + rtw89_write_rf(rtwdev, path, RR_CFGCH, MASKDWORD, tmp18); + rtw89_write_rf(rtwdev, path, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + + fsleep(400); + + rtw89_write_rf(rtwdev, path, RR_RSV1, MASKDWORD, tmp5); + } + + _lck_keep_thermal(rtwdev); +} + +#define RTW8922D_LCK_TH 16 +void rtw8922d_lck_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + u8 cur_thermal; + int delta; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + cur_thermal = _get_thermal(rtwdev, path); + delta = abs((int)cur_thermal - lck->thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d current thermal=0x%x delta=0x%x\n", + path, cur_thermal, delta); + + if (delta >= RTW8922D_LCK_TH) { + _lck(rtwdev); + return; + } + } +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h new file mode 100644 index 000000000..11742b4a8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2026 Realtek Corporation + */ + +#ifndef __RTW89_8922D_RFK_H__ +#define __RTW89_8922D_RFK_H__ + +#include "core.h" + +extern const struct rtw89_rfk_tbl rtw8922d_nctl_post_defs_tbl; + +void rtw8922d_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx); +void rtw8922d_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +void rtw8922d_rfk_hw_init(struct rtw89_dev *rtwdev); +void rtw8922d_rfk_mlo_ctrl(struct rtw89_dev *rtwdev); +void rtw8922d_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw8922d_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw8922d_lck_track(struct rtw89_dev *rtwdev); +void rtw8922d_chlk_ktbl_ctl_mld(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool manual); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922de.c b/drivers/net/wireless/realtek/rtw89/rtw8922de.c new file mode 100644 index 000000000..a71e41f28 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8922de.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2026 Realtek Corporation + */ + +#include +#include + +#include "pci.h" +#include "reg.h" +#include "rtw8922d.h" + +static const struct rtw89_pci_info rtw8922d_pci_info = { + .gen_def = &rtw89_pci_gen_be, + .isr_def = &rtw89_pci_isr_be_v1, + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_V1_256B, + .rx_burst = MAC_AX_RX_BURST_V1_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_ENABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_DEF, + .rx_ring_eq_is_full = true, + .check_rx_tag = true, + .no_rxbd_fs = true, + .group_bd_addr = true, + .rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt_v1), + + .init_cfg_reg = R_BE_HAXI_INIT_CFG1, + .txhci_en_bit = B_BE_TXDMA_EN, + .rxhci_en_bit = B_BE_RXDMA_EN, + .rxbd_mode_bit = B_BE_RXQ_RXBD_MODE_MASK, + .exp_ctrl_reg = R_BE_HAXI_EXP_CTRL_V1, + .max_tag_num_mask = B_BE_MAX_TAG_NUM_MASK, + .rxbd_rwptr_clr_reg = R_BE_RXBD_RWPTR_CLR1_V1, + .txbd_rwptr_clr2_reg = R_BE_TXBD_RWPTR_CLR1, + .dma_io_stop = {R_BE_HAXI_INIT_CFG1, B_BE_STOP_AXI_MST}, + .dma_stop1 = {R_BE_HAXI_DMA_STOP1, B_BE_TX_STOP1_MASK_V1}, + .dma_stop2 = {0}, + .dma_busy1 = {R_BE_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK_BE_V1}, + .dma_busy2_reg = 0, + .dma_busy3_reg = R_BE_HAXI_DMA_BUSY1, + + .rpwm_addr = R_BE_PCIE_HRPWM, + .cpwm_addr = R_BE_PCIE_CRPWM, + .mit_addr = R_BE_PCIE_MIT_CH_EN, + .wp_sel_addr = R_BE_WP_ADDR_H_SEL0_3_V1, + .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH1) | BIT(RTW89_TXCH_ACH3) | + BIT(RTW89_TXCH_ACH5) | BIT(RTW89_TXCH_ACH7) | + BIT(RTW89_TXCH_CH9) | BIT(RTW89_TXCH_CH11), + .bd_idx_addr_low_power = NULL, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set_be_v1, + .bd_ram_table = NULL, + + .ltr_set = rtw89_pci_ltr_set_v2, + .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, + .parse_rpp = rtw89_pci_parse_rpp_v1, + .config_intr_mask = rtw89_pci_config_intr_mask_v3, + .enable_intr = rtw89_pci_enable_intr_v3, + .disable_intr = rtw89_pci_disable_intr_v3, + .recognize_intrs = rtw89_pci_recognize_intrs_v3, + + .ssid_quirks = NULL, +}; + +static const struct rtw89_driver_info rtw89_8922de_vs_info = { + .chip = &rtw8922d_chip_info, + .variant = &rtw8922de_vs_variant, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8922d_pci_info, + }, +}; + +static const struct rtw89_driver_info rtw89_8922de_info = { + .chip = &rtw8922d_chip_info, + .variant = NULL, + .board = NULL, + .quirks = NULL, + .dev_id_quirks = 0, + .bus = { + .pci = &rtw8922d_pci_info, + }, +}; + +static const struct pci_device_id rtw89_8922de_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x892D), + .driver_data = (kernel_ulong_t)&rtw89_8922de_vs_info, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x882D), + .driver_data = (kernel_ulong_t)&rtw89_8922de_vs_info, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x895D), + .driver_data = (kernel_ulong_t)&rtw89_8922de_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(pci, rtw89_8922de_id_table); + +static struct pci_driver rtw89_8922de_driver = { + .name = "rtw89_8922de", + .id_table = rtw89_8922de_id_table, + .probe = rtw89_pci_probe, + .remove = rtw89_pci_remove, + .shutdown = rtw89_pci_shutdown, + .driver.pm = &rtw89_pm_ops_be, + .err_handler = &rtw89_pci_err_handler, +}; +module_pci_driver(rtw89_8922de_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11be wireless 8922DE/8922DE-VS driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c new file mode 100644 index 000000000..6fe3822eb --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/sar.c @@ -0,0 +1,911 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include "acpi.h" +#include "debug.h" +#include "fw.h" +#include "phy.h" +#include "reg.h" +#include "sar.h" +#include "util.h" + +#define RTW89_TAS_FACTOR 2 /* unit: 0.25 dBm */ +#define RTW89_TAS_SAR_GAP (1 << RTW89_TAS_FACTOR) +#define RTW89_TAS_DPR_GAP (1 << RTW89_TAS_FACTOR) +#define RTW89_TAS_DELTA (2 << RTW89_TAS_FACTOR) +#define RTW89_TAS_TX_RATIO_THRESHOLD 70 +#define RTW89_TAS_DFLT_TX_RATIO 80 +#define RTW89_TAS_DPR_ON_OFFSET (RTW89_TAS_DELTA + RTW89_TAS_SAR_GAP) +#define RTW89_TAS_DPR_OFF_OFFSET (4 << RTW89_TAS_FACTOR) + +static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev, + u32 center_freq) +{ + switch (center_freq) { + default: + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "center freq: %u to SAR subband is unhandled\n", + center_freq); + fallthrough; + case 2412 ... 2484: + return RTW89_SAR_2GHZ_SUBBAND; + case 5180 ... 5320: + return RTW89_SAR_5GHZ_SUBBAND_1_2; + case 5500 ... 5720: + return RTW89_SAR_5GHZ_SUBBAND_2_E; + case 5745 ... 5885: + return RTW89_SAR_5GHZ_SUBBAND_3_4; + case 5955 ... 6155: + return RTW89_SAR_6GHZ_SUBBAND_5_L; + case 6175 ... 6415: + return RTW89_SAR_6GHZ_SUBBAND_5_H; + case 6435 ... 6515: + return RTW89_SAR_6GHZ_SUBBAND_6; + case 6535 ... 6695: + return RTW89_SAR_6GHZ_SUBBAND_7_L; + case 6715 ... 6855: + return RTW89_SAR_6GHZ_SUBBAND_7_H; + + /* freq 6875 (ch 185, 20MHz) spans RTW89_SAR_6GHZ_SUBBAND_7_H + * and RTW89_SAR_6GHZ_SUBBAND_8, so directly describe it with + * struct rtw89_6ghz_span. + */ + + case 6895 ... 7115: + return RTW89_SAR_6GHZ_SUBBAND_8; + } +} + +static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, + const struct rtw89_sar_parm *sar_parm, + s32 *cfg) +{ + struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common; + enum rtw89_sar_subband subband_l, subband_h; + u32 center_freq = sar_parm->center_freq; + const struct rtw89_6ghz_span *span; + + span = rtw89_get_6ghz_span(rtwdev, center_freq); + + if (span && RTW89_SAR_SPAN_VALID(span)) { + subband_l = span->sar_subband_low; + subband_h = span->sar_subband_high; + } else { + subband_l = rtw89_sar_get_subband(rtwdev, center_freq); + subband_h = subband_l; + } + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "center_freq %u: SAR subband {%u, %u}\n", + center_freq, subband_l, subband_h); + + if (!rtwsar->set[subband_l] && !rtwsar->set[subband_h]) + return -ENODATA; + + if (!rtwsar->set[subband_l]) + *cfg = rtwsar->cfg[subband_h]; + else if (!rtwsar->set[subband_h]) + *cfg = rtwsar->cfg[subband_l]; + else + *cfg = min(rtwsar->cfg[subband_l], rtwsar->cfg[subband_h]); + + return 0; +} + +static const struct rtw89_sar_entry_from_acpi * +rtw89_sar_cfg_acpi_get_ent(const struct rtw89_sar_cfg_acpi *rtwsar, + enum rtw89_rf_path path, + enum rtw89_regulation_type regd) +{ + const struct rtw89_sar_indicator_from_acpi *ind = &rtwsar->indicator; + const struct rtw89_sar_table_from_acpi *tbl; + u8 sel; + + sel = ind->tblsel[path]; + tbl = &rtwsar->tables[sel]; + + return &tbl->entries[regd]; +} + +static +s32 rtw89_sar_cfg_acpi_get_min(const struct rtw89_sar_entry_from_acpi *ent, + enum rtw89_rf_path path, + enum rtw89_acpi_sar_subband subband_low, + enum rtw89_acpi_sar_subband subband_high) +{ + return min(ent->v[subband_low][path], ent->v[subband_high][path]); +} + +static int rtw89_query_sar_config_acpi(struct rtw89_dev *rtwdev, + const struct rtw89_sar_parm *sar_parm, + s32 *cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_sar_cfg_acpi *rtwsar = &rtwdev->sar.cfg_acpi; + const struct rtw89_sar_entry_from_acpi *ent_a, *ent_b; + enum rtw89_acpi_sar_subband subband_l, subband_h; + u32 center_freq = sar_parm->center_freq; + const struct rtw89_6ghz_span *span; + enum rtw89_regulation_type regd; + enum rtw89_band band; + s32 cfg_a, cfg_b; + + span = rtw89_get_6ghz_span(rtwdev, center_freq); + + if (span && RTW89_ACPI_SAR_SPAN_VALID(span)) { + subband_l = span->acpi_sar_subband_low; + subband_h = span->acpi_sar_subband_high; + } else { + subband_l = rtw89_acpi_sar_get_subband(rtwdev, center_freq); + subband_h = subband_l; + } + + band = rtw89_acpi_sar_subband_to_band(rtwdev, subband_l); + regd = rtw89_regd_get(rtwdev, band); + + ent_a = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_A, regd); + ent_b = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_B, regd); + + cfg_a = rtw89_sar_cfg_acpi_get_min(ent_a, RF_PATH_A, subband_l, subband_h); + cfg_b = rtw89_sar_cfg_acpi_get_min(ent_b, RF_PATH_B, subband_l, subband_h); + + if (chip->support_sar_by_ant) { + /* With declaration of support_sar_by_ant, relax the general + * SAR querying to return the maximum between paths. However, + * expect chip has dealt with the corresponding SAR settings + * by path. (To get SAR for a given path, chip can then query + * with force_path.) + */ + if (sar_parm->force_path) { + switch (sar_parm->path) { + default: + case RF_PATH_A: + *cfg = cfg_a; + break; + case RF_PATH_B: + *cfg = cfg_b; + break; + } + } else { + *cfg = max(cfg_a, cfg_b); + } + } else { + *cfg = min(cfg_a, cfg_b); + } + + if (sar_parm->ntx == RTW89_2TX) + *cfg -= rtwsar->downgrade_2tx; + + return 0; +} + +static const +struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = { + [RTW89_SAR_SOURCE_COMMON] = { + .descr_sar_source = "RTW89_SAR_SOURCE_COMMON", + .txpwr_factor_sar = 2, + .query_sar_config = rtw89_query_sar_config_common, + }, + [RTW89_SAR_SOURCE_ACPI] = { + .descr_sar_source = "RTW89_SAR_SOURCE_ACPI", + .txpwr_factor_sar = TXPWR_FACTOR_OF_RTW89_ACPI_SAR, + .query_sar_config = rtw89_query_sar_config_acpi, + }, +}; + +#define rtw89_sar_set_src(_dev, _src, _cfg_name, _cfg_data) \ + do { \ + typeof(_src) _s = (_src); \ + typeof(_dev) _d = (_dev); \ + BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \ + BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \ + if (test_bit(RTW89_FLAG_PROBE_DONE, _d->flags)) \ + lockdep_assert_wiphy(_d->hw->wiphy); \ + _d->sar._cfg_name = *(_cfg_data); \ + _d->sar.src = _s; \ + } while (0) + +static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg) +{ + const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; + s32 cfg_mac; + + cfg_mac = fct > fct_mac ? + cfg >> (fct - fct_mac) : cfg << (fct_mac - fct); + + return (s8)clamp_t(s32, cfg_mac, + RTW89_SAR_TXPWR_MAC_MIN, + RTW89_SAR_TXPWR_MAC_MAX); +} + +static s32 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl, + s32 cfg) +{ + const u8 fct = sar_hdl->txpwr_factor_sar; + + if (fct > RTW89_TAS_FACTOR) + return cfg << (fct - RTW89_TAS_FACTOR); + else + return cfg >> (RTW89_TAS_FACTOR - fct); +} + +static s32 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl, + s32 cfg) +{ + const u8 fct = sar_hdl->txpwr_factor_sar; + + if (fct > RTW89_TAS_FACTOR) + return cfg >> (fct - RTW89_TAS_FACTOR); + else + return cfg << (RTW89_TAS_FACTOR - fct); +} + +static bool rtw89_tas_is_active(struct rtw89_dev *rtwdev) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + struct rtw89_vif *rtwvif; + + if (!tas->enable) + return false; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (ieee80211_vif_is_mld(rtwvif_to_vif(rtwvif))) + return false; + } + + return true; +} + +static const char *rtw89_tas_state_str(enum rtw89_tas_state state) +{ + switch (state) { + case RTW89_TAS_STATE_DPR_OFF: + return "DPR OFF"; + case RTW89_TAS_STATE_DPR_ON: + return "DPR ON"; + case RTW89_TAS_STATE_STATIC_SAR: + return "STATIC SAR"; + default: + return NULL; + } +} + +s8 rtw89_query_sar(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_parm) +{ + const enum rtw89_sar_sources src = rtwdev->sar.src; + /* its members are protected by rtw89_sar_set_src() */ + const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 offset; + int ret; + s32 cfg; + u8 fct; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (src == RTW89_SAR_SOURCE_NONE) + return RTW89_SAR_TXPWR_MAC_MAX; + + ret = sar_hdl->query_sar_config(rtwdev, sar_parm, &cfg); + if (ret) + return RTW89_SAR_TXPWR_MAC_MAX; + + if (rtw89_tas_is_active(rtwdev)) { + switch (tas->state) { + case RTW89_TAS_STATE_DPR_OFF: + offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_OFF_OFFSET); + cfg += offset; + break; + case RTW89_TAS_STATE_DPR_ON: + offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_ON_OFFSET); + cfg -= offset; + break; + case RTW89_TAS_STATE_STATIC_SAR: + default: + break; + } + } + + fct = sar_hdl->txpwr_factor_sar; + + return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg); +} +EXPORT_SYMBOL(rtw89_query_sar); + +int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_sar_parm *sar_parm) +{ + const enum rtw89_sar_sources src = rtwdev->sar.src; + /* its members are protected by rtw89_sar_set_src() */ + const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; + const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; + char *p = buf, *end = buf + bufsz; + int ret; + s32 cfg; + u8 fct; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (src == RTW89_SAR_SOURCE_NONE) { + p += scnprintf(p, end - p, "no SAR is applied\n"); + goto out; + } + + p += scnprintf(p, end - p, "source: %d (%s)\n", src, + sar_hdl->descr_sar_source); + + ret = sar_hdl->query_sar_config(rtwdev, sar_parm, &cfg); + if (ret) { + p += scnprintf(p, end - p, "config: return code: %d\n", ret); + p += scnprintf(p, end - p, + "assign: max setting: %d (unit: 1/%lu dBm)\n", + RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac)); + goto out; + } + + fct = sar_hdl->txpwr_factor_sar; + + p += scnprintf(p, end - p, "config: %d (unit: 1/%lu dBm)\n", cfg, + BIT(fct)); + + p += scnprintf(p, end - p, "support different configs by antenna: %s\n", + str_yes_no(rtwdev->chip->support_sar_by_ant)); +out: + return p - buf; +} + +int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + char *p = buf, *end = buf + bufsz; + + if (!rtw89_tas_is_active(rtwdev)) { + p += scnprintf(p, end - p, "no TAS is applied\n"); + goto out; + } + + p += scnprintf(p, end - p, "State: %s\n", + rtw89_tas_state_str(tas->state)); + p += scnprintf(p, end - p, "Average time: %d\n", + tas->window_size * 2); + p += scnprintf(p, end - p, "SAR gap: %d dBm\n", + RTW89_TAS_SAR_GAP >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR gap: %d dBm\n", + RTW89_TAS_DPR_GAP >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR ON offset: %d dBm\n", + RTW89_TAS_DPR_ON_OFFSET >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR OFF offset: %d dBm\n", + RTW89_TAS_DPR_OFF_OFFSET >> RTW89_TAS_FACTOR); + +out: + return p - buf; +} + +static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev, + const struct rtw89_sar_cfg_common *sar) +{ + /* let common SAR have the highest priority; always apply it */ + rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar); + rtw89_core_set_chip_txpwr(rtwdev); + rtw89_tas_reset(rtwdev, false); + + return 0; +} + +static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = { + { .start_freq = 2412, .end_freq = 2484, }, + { .start_freq = 5180, .end_freq = 5320, }, + { .start_freq = 5500, .end_freq = 5720, }, + { .start_freq = 5745, .end_freq = 5885, }, + { .start_freq = 5955, .end_freq = 6155, }, + { .start_freq = 6175, .end_freq = 6415, }, + { .start_freq = 6435, .end_freq = 6515, }, + { .start_freq = 6535, .end_freq = 6695, }, + { .start_freq = 6715, .end_freq = 6875, }, + { .start_freq = 6875, .end_freq = 7115, }, +}; + +static_assert(RTW89_SAR_SUBBAND_NR == + ARRAY_SIZE(rtw89_common_sar_freq_ranges)); + +const struct cfg80211_sar_capa rtw89_sar_capa = { + .type = NL80211_SAR_TYPE_POWER, + .num_freq_ranges = ARRAY_SIZE(rtw89_common_sar_freq_ranges), + .freq_ranges = rtw89_common_sar_freq_ranges, +}; + +int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_sar_cfg_common sar_common = {0}; + u8 fct; + u32 freq_start; + u32 freq_end; + s32 power; + u32 i, idx; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (sar->type != NL80211_SAR_TYPE_POWER) + return -EINVAL; + + fct = rtw89_sar_handlers[RTW89_SAR_SOURCE_COMMON].txpwr_factor_sar; + + for (i = 0; i < sar->num_sub_specs; i++) { + idx = sar->sub_specs[i].freq_range_index; + if (idx >= ARRAY_SIZE(rtw89_common_sar_freq_ranges)) + return -EINVAL; + + freq_start = rtw89_common_sar_freq_ranges[idx].start_freq; + freq_end = rtw89_common_sar_freq_ranges[idx].end_freq; + power = sar->sub_specs[i].power; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "On freq %u to %u, set SAR limit %d (unit: 1/%lu dBm)\n", + freq_start, freq_end, power, BIT(fct)); + + sar_common.set[idx] = true; + sar_common.cfg[idx] = power; + } + + return rtw89_apply_sar_common(rtwdev, &sar_common); +} + +static void rtw89_apply_sar_acpi(struct rtw89_dev *rtwdev, + const struct rtw89_sar_cfg_acpi *sar) +{ + const struct rtw89_sar_table_from_acpi *tbl; + const struct rtw89_sar_entry_from_acpi *ent; + enum rtw89_sar_sources src; + unsigned int i, j, k; + + src = rtwdev->sar.src; + if (src != RTW89_SAR_SOURCE_NONE) { + rtw89_warn(rtwdev, "SAR source: %d is in use", src); + return; + } + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "SAR-ACPI downgrade 2TX: %u (unit: 1/%lu dBm)\n", + sar->downgrade_2tx, BIT(TXPWR_FACTOR_OF_RTW89_ACPI_SAR)); + + for (i = 0; i < sar->valid_num; i++) { + tbl = &sar->tables[i]; + + for (j = 0; j < RTW89_REGD_NUM; j++) { + ent = &tbl->entries[j]; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "SAR-ACPI-[%u] REGD-%s (unit: 1/%lu dBm)\n", + i, rtw89_regd_get_string(j), + BIT(TXPWR_FACTOR_OF_RTW89_ACPI_SAR)); + + for (k = 0; k < NUM_OF_RTW89_ACPI_SAR_SUBBAND; k++) + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "On subband %u, { %d, %d }\n", k, + ent->v[k][RF_PATH_A], ent->v[k][RF_PATH_B]); + } + } + + rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_ACPI, cfg_acpi, sar); + + /* SAR via ACPI is only configured in the early initial phase, so + * it does not seem necessary to reset txpwr related things here. + */ +} + +static void rtw89_set_sar_from_acpi(struct rtw89_dev *rtwdev) +{ + struct rtw89_sar_cfg_acpi *cfg; + int ret; + + cfg = kzalloc_obj(*cfg); + if (!cfg) + return; + + ret = rtw89_acpi_evaluate_sar(rtwdev, cfg); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "evaluating ACPI SAR returns %d\n", ret); + goto out; + } + + if (unlikely(!cfg->valid_num)) { + rtw89_debug(rtwdev, RTW89_DBG_SAR, "no valid SAR table from ACPI\n"); + goto out; + } + + rtw89_apply_sar_acpi(rtwdev, cfg); + +out: + kfree(cfg); +} + +static bool rtw89_tas_query_sar_config(struct rtw89_dev *rtwdev, s32 *cfg) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + const enum rtw89_sar_sources src = rtwdev->sar.src; + /* its members are protected by rtw89_sar_set_src() */ + const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; + struct rtw89_sar_parm sar_parm = {}; + int ret; + + if (src == RTW89_SAR_SOURCE_NONE) + return false; + + sar_parm.center_freq = chan->freq; + ret = sar_hdl->query_sar_config(rtwdev, &sar_parm, cfg); + if (ret) + return false; + + *cfg = rtw89_txpwr_sar_to_tas(sar_hdl, *cfg); + + return true; +} + +static bool __rtw89_tas_state_update(struct rtw89_dev *rtwdev, + enum rtw89_tas_state state) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + + if (tas->state == state) + return false; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: switch state: %s -> %s\n", + rtw89_tas_state_str(tas->state), rtw89_tas_state_str(state)); + + tas->state = state; + return true; +} + +static void rtw89_tas_state_update(struct rtw89_dev *rtwdev, + enum rtw89_tas_state state) +{ + if (!__rtw89_tas_state_update(rtwdev, state)) + return; + + rtw89_core_set_chip_txpwr(rtwdev); +} + +static u32 rtw89_tas_get_window_size(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + u8 band = chan->band_type; + u8 regd = rtw89_regd_get(rtwdev, band); + + switch (regd) { + default: + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: regd: %u is unhandled\n", regd); + fallthrough; + case RTW89_IC: + case RTW89_KCC: + return 180; + case RTW89_FCC: + switch (band) { + case RTW89_BAND_2G: + return 50; + case RTW89_BAND_5G: + return 30; + case RTW89_BAND_6G: + default: + return 15; + } + break; + } +} + +static void rtw89_tas_window_update(struct rtw89_dev *rtwdev) +{ + u32 window_size = rtw89_tas_get_window_size(rtwdev); + struct rtw89_tas_info *tas = &rtwdev->tas; + u64 total_txpwr = 0; + u8 head_idx; + u32 i, j; + + WARN_ON_ONCE(tas->window_size > RTW89_TAS_TXPWR_WINDOW); + + if (tas->window_size == window_size) + return; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: window update: %u -> %u\n", + tas->window_size, window_size); + + head_idx = (tas->txpwr_tail_idx - window_size + 1 + RTW89_TAS_TXPWR_WINDOW) % + RTW89_TAS_TXPWR_WINDOW; + for (i = 0; i < window_size; i++) { + j = (head_idx + i) % RTW89_TAS_TXPWR_WINDOW; + total_txpwr += tas->txpwr_history[j]; + } + + tas->window_size = window_size; + tas->total_txpwr = total_txpwr; + tas->txpwr_head_idx = head_idx; +} + +static void rtw89_tas_history_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0); + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_tas_info *tas = &rtwdev->tas; + u8 tx_ratio = env->ifs_clm_tx_ratio; + u64 instant_txpwr, txpwr; + + /* txpwr in unit of linear(mW) multiply by percentage */ + if (tx_ratio == 0) { + /* special case: idle tx power + * use -40 dBm * 100 tx ratio + */ + instant_txpwr = rtw89_db_to_linear(-40); + txpwr = instant_txpwr * 100; + } else { + instant_txpwr = tas->instant_txpwr; + txpwr = instant_txpwr * tx_ratio; + } + + tas->total_txpwr += txpwr - tas->txpwr_history[tas->txpwr_head_idx]; + tas->total_tx_ratio += tx_ratio - tas->tx_ratio_history[tas->tx_ratio_idx]; + tas->tx_ratio_history[tas->tx_ratio_idx] = tx_ratio; + + tas->txpwr_head_idx = (tas->txpwr_head_idx + 1) % RTW89_TAS_TXPWR_WINDOW; + tas->txpwr_tail_idx = (tas->txpwr_tail_idx + 1) % RTW89_TAS_TXPWR_WINDOW; + tas->tx_ratio_idx = (tas->tx_ratio_idx + 1) % RTW89_TAS_TX_RATIO_WINDOW; + tas->txpwr_history[tas->txpwr_tail_idx] = txpwr; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: instant_txpwr: %d, tx_ratio: %u, txpwr: %d\n", + rtw89_linear_to_db_quarter(instant_txpwr), tx_ratio, + rtw89_linear_to_db_quarter(div_u64(txpwr, PERCENT))); +} + +static bool rtw89_tas_rolling_average(struct rtw89_dev *rtwdev) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 dpr_on_threshold, dpr_off_threshold; + enum rtw89_tas_state state; + u16 tx_ratio_avg; + s32 txpwr_avg; + u64 linear; + + linear = DIV_ROUND_DOWN_ULL(tas->total_txpwr, tas->window_size * PERCENT); + txpwr_avg = rtw89_linear_to_db_quarter(linear); + tx_ratio_avg = tas->total_tx_ratio / RTW89_TAS_TX_RATIO_WINDOW; + dpr_on_threshold = tas->dpr_on_threshold; + dpr_off_threshold = tas->dpr_off_threshold; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: DPR_ON: %d, DPR_OFF: %d, txpwr_avg: %d, tx_ratio_avg: %u\n", + dpr_on_threshold, dpr_off_threshold, txpwr_avg, tx_ratio_avg); + + if (tx_ratio_avg >= RTW89_TAS_TX_RATIO_THRESHOLD) + state = RTW89_TAS_STATE_STATIC_SAR; + else if (txpwr_avg >= dpr_on_threshold) + state = RTW89_TAS_STATE_DPR_ON; + else if (txpwr_avg < dpr_off_threshold) + state = RTW89_TAS_STATE_DPR_OFF; + else + return false; + + return __rtw89_tas_state_update(rtwdev, state); +} + +static void rtw89_tas_init(struct rtw89_dev *rtwdev) +{ + bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_tas_info *tas = &rtwdev->tas; + const struct rtw89_acpi_policy_tas *ptr; + struct rtw89_acpi_dsm_result res = {}; + int ret; + + if (!chip->support_tas) + return; + + if (skip_acpi_dsm) + return; + + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "acpi: cannot get TAS: %d\n", ret); + return; + } + + ptr = res.u.policy_tas; + + switch (ptr->enable) { + case 0: + tas->enable = false; + break; + case 1: + tas->enable = true; + break; + default: + break; + } + + if (!tas->enable) { + rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n"); + goto out; + } + + tas->enabled_countries = ptr->enabled_countries; + +out: + kfree(ptr); +} + +void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + struct rtw89_tas_info *tas = &rtwdev->tas; + u64 linear; + s32 cfg; + int i; + + if (!rtw89_tas_is_active(rtwdev)) + return; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; + + tas->dpr_on_threshold = cfg - RTW89_TAS_SAR_GAP; + tas->dpr_off_threshold = cfg - RTW89_TAS_SAR_GAP - RTW89_TAS_DPR_GAP; + + /* avoid history reset after new SAR apply */ + if (!force && tas->keep_history) + return; + + linear = rtw89_db_quarter_to_linear(cfg) * RTW89_TAS_DFLT_TX_RATIO; + for (i = 0; i < RTW89_TAS_TXPWR_WINDOW; i++) + tas->txpwr_history[i] = linear; + + for (i = 0; i < RTW89_TAS_TX_RATIO_WINDOW; i++) + tas->tx_ratio_history[i] = RTW89_TAS_DFLT_TX_RATIO; + + tas->total_tx_ratio = RTW89_TAS_DFLT_TX_RATIO * RTW89_TAS_TX_RATIO_WINDOW; + tas->total_txpwr = linear * RTW89_TAS_TXPWR_WINDOW; + tas->window_size = RTW89_TAS_TXPWR_WINDOW; + tas->txpwr_head_idx = 0; + tas->txpwr_tail_idx = RTW89_TAS_TXPWR_WINDOW - 1; + tas->tx_ratio_idx = 0; + tas->state = RTW89_TAS_STATE_DPR_OFF; + tas->backup_state = RTW89_TAS_STATE_DPR_OFF; + tas->keep_history = true; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: band: %u, freq: %u\n", chan->band_type, chan->freq); +} + +static bool rtw89_tas_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + struct rtw89_hal *hal = &rtwdev->hal; + s32 cfg; + + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_TAS)) + return false; + + if (!rtw89_tas_is_active(rtwdev)) + return false; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd) + return __rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + + if (tas->pause) + return false; + + rtw89_tas_window_update(rtwdev); + rtw89_tas_history_update(rtwdev); + + return rtw89_tas_rolling_average(rtwdev); +} + +void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 cfg; + + if (!rtw89_tas_is_active(rtwdev)) + return; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; + + if (start) { + tas->backup_state = tas->state; + rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + } else { + rtw89_tas_state_update(rtwdev, tas->backup_state); + } +} + +void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 cfg; + + if (!rtw89_tas_is_active(rtwdev)) + return; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; + + switch (state) { + case RTW89_CHANCTX_STATE_MCC_START: + tas->pause = true; + rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + break; + case RTW89_CHANCTX_STATE_MCC_STOP: + tas->pause = false; + break; + default: + break; + } +} +EXPORT_SYMBOL(rtw89_tas_chanctx_cb); + +void rtw89_tas_fw_timer_enable(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_tas_info *tas = &rtwdev->tas; + + if (!tas->enable) + return; + + if (chip->chip_gen == RTW89_CHIP_AX) + return; + + rtw89_fw_h2c_rf_tas_trigger(rtwdev, enable); +} + +void rtw89_sar_init(struct rtw89_dev *rtwdev) +{ + rtw89_set_sar_from_acpi(rtwdev); + rtw89_tas_init(rtwdev); +} + +static bool rtw89_sar_track_acpi(struct rtw89_dev *rtwdev) +{ + struct rtw89_sar_cfg_acpi *cfg = &rtwdev->sar.cfg_acpi; + struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator; + const enum rtw89_sar_sources src = rtwdev->sar.src; + bool changed; + int ret; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (src != RTW89_SAR_SOURCE_ACPI) + return false; + + if (!ind->enable_sync) + return false; + + ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, &changed); + if (likely(!ret)) + return changed; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "%s: failed to track indicator: %d; reset and disable\n", + __func__, ret); + + memset(ind->tblsel, 0, sizeof(ind->tblsel)); + ind->enable_sync = false; + return true; +} + +void rtw89_sar_track(struct rtw89_dev *rtwdev) +{ + unsigned int changes = 0; + + changes += rtw89_sar_track_acpi(rtwdev); + changes += rtw89_tas_track(rtwdev); + + if (!changes) + return; + + rtw89_core_set_chip_txpwr(rtwdev); +} diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h new file mode 100644 index 000000000..60b3aec5b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/sar.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#ifndef __RTW89_SAR_H__ +#define __RTW89_SAR_H__ + +#include "core.h" + +#define RTW89_SAR_TXPWR_MAC_MAX 63 +#define RTW89_SAR_TXPWR_MAC_MIN -64 + +struct rtw89_sar_parm { + u32 center_freq; + enum rtw89_ntx ntx; + + bool force_path; + enum rtw89_rf_path path; +}; + +struct rtw89_sar_handler { + const char *descr_sar_source; + u8 txpwr_factor_sar; + int (*query_sar_config)(struct rtw89_dev *rtwdev, + const struct rtw89_sar_parm *sar_parm, s32 *cfg); +}; + +extern const struct cfg80211_sar_capa rtw89_sar_capa; + +s8 rtw89_query_sar(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_parm); +int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_sar_parm *sar_parm); +int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); +int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar); +void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force); +void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start); +void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state); +void rtw89_tas_fw_timer_enable(struct rtw89_dev *rtwdev, bool enable); +void rtw89_sar_init(struct rtw89_dev *rtwdev); +void rtw89_sar_track(struct rtw89_dev *rtwdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c new file mode 100644 index 000000000..a507ce1fc --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -0,0 +1,858 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2020 Realtek Corporation + */ + +#include + +#include "cam.h" +#include "chan.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "ps.h" +#include "reg.h" +#include "ser.h" +#include "util.h" + +#define SER_RECFG_TIMEOUT 1000 + +enum ser_evt { + SER_EV_NONE, + SER_EV_STATE_IN, + SER_EV_STATE_OUT, + SER_EV_L1_RESET_PREPARE, /* pre-M0 */ + SER_EV_L1_RESET, /* M1 */ + SER_EV_DO_RECOVERY, /* M3 */ + SER_EV_MAC_RESET_DONE, /* M5 */ + SER_EV_L2_RESET, + SER_EV_L2_RECFG_DONE, + SER_EV_L2_RECFG_TIMEOUT, + SER_EV_M1_TIMEOUT, + SER_EV_M3_TIMEOUT, + SER_EV_FW_M5_TIMEOUT, + SER_EV_L0_RESET, + SER_EV_MAXX +}; + +enum ser_state { + SER_IDLE_ST, + SER_L1_RESET_PRE_ST, + SER_RESET_TRX_ST, + SER_DO_HCI_ST, + SER_L2_RESET_ST, + SER_ST_MAX_ST +}; + +struct ser_msg { + struct list_head list; + u8 event; +}; + +struct state_ent { + u8 state; + char *name; + void (*st_func)(struct rtw89_ser *ser, u8 event); +}; + +struct event_ent { + u8 event; + char *name; +}; + +static char *ser_ev_name(struct rtw89_ser *ser, u8 event) +{ + if (event < SER_EV_MAXX) + return ser->ev_tbl[event].name; + + return "err_ev_name"; +} + +static char *ser_st_name(struct rtw89_ser *ser) +{ + if (ser->state < SER_ST_MAX_ST) + return ser->st_tbl[ser->state].name; + + return "err_st_name"; +} + +#define RTW89_DEF_SER_CD_TYPE(_name, _type, _size) \ +struct ser_cd_ ## _name { \ + u32 type; \ + u32 type_size; \ + u64 padding; \ + u8 data[_size]; \ +} __packed; \ +static void ser_cd_ ## _name ## _init(struct ser_cd_ ## _name *p) \ +{ \ + p->type = _type; \ + p->type_size = sizeof(p->data); \ + p->padding = 0x0123456789abcdef; \ +} + +enum rtw89_ser_cd_type { + RTW89_SER_CD_FW_RSVD_PLE = 0, + RTW89_SER_CD_FW_BACKTRACE = 1, +}; + +RTW89_DEF_SER_CD_TYPE(fw_rsvd_ple, + RTW89_SER_CD_FW_RSVD_PLE, + RTW89_FW_RSVD_PLE_SIZE); + +RTW89_DEF_SER_CD_TYPE(fw_backtrace, + RTW89_SER_CD_FW_BACKTRACE, + RTW89_FW_BACKTRACE_MAX_SIZE); + +struct rtw89_ser_cd_buffer { + struct ser_cd_fw_rsvd_ple fwple; + struct ser_cd_fw_backtrace fwbt; +} __packed; + +static struct rtw89_ser_cd_buffer *rtw89_ser_cd_prep(struct rtw89_dev *rtwdev) +{ + struct rtw89_ser_cd_buffer *buf; + + buf = vzalloc(sizeof(*buf)); + if (!buf) + return NULL; + + ser_cd_fw_rsvd_ple_init(&buf->fwple); + ser_cd_fw_backtrace_init(&buf->fwbt); + + return buf; +} + +static void rtw89_ser_cd_send(struct rtw89_dev *rtwdev, + struct rtw89_ser_cd_buffer *buf) +{ + rtw89_debug(rtwdev, RTW89_DBG_SER, "SER sends core dump\n"); + + /* After calling dev_coredump, buf's lifetime is supposed to be + * handled by the device coredump framework. Note that a new dump + * will be discarded if a previous one hasn't been released by + * framework yet. + */ + dev_coredumpv(rtwdev->dev, buf, sizeof(*buf), GFP_KERNEL); +} + +static void rtw89_ser_cd_free(struct rtw89_dev *rtwdev, + struct rtw89_ser_cd_buffer *buf, bool free_self) +{ + if (!free_self) + return; + + rtw89_debug(rtwdev, RTW89_DBG_SER, "SER frees core dump by self\n"); + + /* When some problems happen during filling data of core dump, + * we won't send it to device coredump framework. Instead, we + * free buf by ourselves. + */ + vfree(buf); +} + +static void ser_state_run(struct rtw89_ser *ser, u8 evt) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n", + ser_st_name(ser), ser_ev_name(ser, evt)); + + wiphy_lock(rtwdev->hw->wiphy); + rtw89_leave_lps(rtwdev); + wiphy_unlock(rtwdev->hw->wiphy); + + ser->st_tbl[ser->state].st_func(ser, evt); +} + +static void ser_state_goto(struct rtw89_ser *ser, u8 new_state) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + if (ser->state == new_state || new_state >= SER_ST_MAX_ST) + return; + ser_state_run(ser, SER_EV_STATE_OUT); + + rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s goto -> %s\n", + ser_st_name(ser), ser->st_tbl[new_state].name); + + ser->state = new_state; + ser_state_run(ser, SER_EV_STATE_IN); +} + +static struct ser_msg *__rtw89_ser_dequeue_msg(struct rtw89_ser *ser) +{ + struct ser_msg *msg; + + spin_lock_irq(&ser->msg_q_lock); + msg = list_first_entry_or_null(&ser->msg_q, struct ser_msg, list); + if (msg) + list_del(&msg->list); + spin_unlock_irq(&ser->msg_q_lock); + + return msg; +} + +static void rtw89_ser_hdl_work(struct work_struct *work) +{ + struct ser_msg *msg; + struct rtw89_ser *ser = container_of(work, struct rtw89_ser, + ser_hdl_work); + + while ((msg = __rtw89_ser_dequeue_msg(ser))) { + ser_state_run(ser, msg->event); + kfree(msg); + } +} + +static int ser_send_msg(struct rtw89_ser *ser, u8 event) +{ + struct ser_msg *msg = NULL; + + if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) + return -EIO; + + msg = kmalloc_obj(*msg, GFP_ATOMIC); + if (!msg) + return -ENOMEM; + + msg->event = event; + + spin_lock_irq(&ser->msg_q_lock); + list_add(&msg->list, &ser->msg_q); + spin_unlock_irq(&ser->msg_q_lock); + + schedule_work(&ser->ser_hdl_work); + return 0; +} + +static void rtw89_ser_alarm_work(struct work_struct *work) +{ + struct rtw89_ser *ser = container_of(work, struct rtw89_ser, + ser_alarm_work.work); + + ser_send_msg(ser, ser->alarm_event); + ser->alarm_event = SER_EV_NONE; +} + +static void ser_set_alarm(struct rtw89_ser *ser, u32 ms, u8 event) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) + return; + + ser->alarm_event = event; + ieee80211_queue_delayed_work(rtwdev->hw, &ser->ser_alarm_work, + msecs_to_jiffies(ms)); +} + +static void ser_del_alarm(struct rtw89_ser *ser) +{ + cancel_delayed_work(&ser->ser_alarm_work); + ser->alarm_event = SER_EV_NONE; +} + +/* driver function */ +static void drv_stop_tx(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + ieee80211_stop_queues(rtwdev->hw); + set_bit(RTW89_SER_DRV_STOP_TX, ser->flags); +} + +static void drv_stop_rx(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); + set_bit(RTW89_SER_DRV_STOP_RX, ser->flags); +} + +static void drv_trx_reset(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + rtw89_hci_reset(rtwdev); +} + +static void drv_resume_tx(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + if (!test_bit(RTW89_SER_DRV_STOP_TX, ser->flags)) + return; + + ieee80211_wake_queues(rtwdev->hw); + clear_bit(RTW89_SER_DRV_STOP_TX, ser->flags); +} + +static void drv_resume_rx(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + if (!test_bit(RTW89_SER_DRV_STOP_RX, ser->flags)) + return; + + set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); + clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags); +} + +static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtwvif->tdls_peer = 0; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; + rtwvif_link->trigger = false; + rtwvif_link->rand_tsf_done = false; + + rtw89_p2p_noa_once_deinit(rtwvif_link); + } +} + +static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + if (rtwvif != target_rtwvif) + return; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); + if (sta->tdls) + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); + + INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); + } +} + +static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + ieee80211_iterate_stations_atomic(rtwdev->hw, + ser_sta_deinit_cam_iter, + rtwvif); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_cam_deinit(rtwdev, rtwvif_link); + + bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM); +} + +static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif *rtwvif; + + rtw89_cam_reset_keys(rtwdev); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_deinit_cam(rtwdev, rtwvif); + + rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_reset_vif(rtwdev, rtwvif); + + rtwdev->total_sta_assoc = 0; + refcount_set(&rtwdev->refcount_ap_info, 0); +} + +/* hal function */ +static int hal_enable_dma(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + int ret; + + if (!test_bit(RTW89_SER_HAL_STOP_DMA, ser->flags)) + return 0; + + if (!rtwdev->hci.ops->mac_lv1_rcvy) + return -EIO; + + ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2); + if (!ret) + clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); + else + rtw89_debug(rtwdev, RTW89_DBG_SER, + "lv1 rcvy fail to start dma: %d\n", ret); + + return ret; +} + +static int hal_stop_dma(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + int ret; + + if (!rtwdev->hci.ops->mac_lv1_rcvy) + return -EIO; + + ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1); + if (!ret) + set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); + else + rtw89_debug(rtwdev, RTW89_DBG_SER, + "lv1 rcvy fail to stop dma: %d\n", ret); + + return ret; +} + +static void hal_send_post_m0_event(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_START_DMAC); +} + +static void hal_send_m2_event(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_DISABLE_EN); +} + +static void hal_send_m4_event(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RCVY_EN); +} + +static void hal_enable_err_imr(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + mac->err_imr_ctrl(rtwdev, true); +} + +/* state handler */ +static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + switch (evt) { + case SER_EV_STATE_IN: + rtw89_hci_recovery_complete(rtwdev); + clear_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags); + clear_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags); + break; + case SER_EV_L1_RESET_PREPARE: + ser_state_goto(ser, SER_L1_RESET_PRE_ST); + break; + case SER_EV_L1_RESET: + ser_state_goto(ser, SER_RESET_TRX_ST); + break; + case SER_EV_L2_RESET: + ser_state_goto(ser, SER_L2_RESET_ST); + break; + case SER_EV_STATE_OUT: + set_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags); + rtw89_hci_recovery_start(rtwdev); + break; + default: + break; + } +} + +static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt) +{ + switch (evt) { + case SER_EV_STATE_IN: + ser->prehandle_l1 = true; + hal_send_post_m0_event(ser); + ser_set_alarm(ser, 1000, SER_EV_M1_TIMEOUT); + break; + case SER_EV_L1_RESET: + ser_state_goto(ser, SER_RESET_TRX_ST); + break; + case SER_EV_M1_TIMEOUT: + ser_state_goto(ser, SER_L2_RESET_ST); + break; + case SER_EV_STATE_OUT: + ser_del_alarm(ser); + break; + default: + break; + } +} + +static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + struct wiphy *wiphy = rtwdev->hw->wiphy; + + switch (evt) { + case SER_EV_STATE_IN: + wiphy_lock(wiphy); + ser->sw_cnt.l1++; + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work); + wiphy_unlock(wiphy); + drv_stop_tx(ser); + + if (hal_stop_dma(ser)) { + ser_state_goto(ser, SER_L2_RESET_ST); + break; + } + + drv_stop_rx(ser); + wiphy_lock(wiphy); + drv_trx_reset(ser); + wiphy_unlock(wiphy); + + /* wait m3 */ + hal_send_m2_event(ser); + + /* set alarm to prevent FW response timeout */ + ser_set_alarm(ser, 1000, SER_EV_M3_TIMEOUT); + break; + + case SER_EV_DO_RECOVERY: + ser_state_goto(ser, SER_DO_HCI_ST); + break; + + case SER_EV_M3_TIMEOUT: + ser_state_goto(ser, SER_L2_RESET_ST); + break; + + case SER_EV_STATE_OUT: + ser_del_alarm(ser); + hal_enable_dma(ser); + drv_resume_rx(ser); + drv_resume_tx(ser); + wiphy_delayed_work_queue(wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(wiphy, &rtwdev->track_ps_work, + RTW89_TRACK_PS_WORK_PERIOD); + break; + + default: + break; + } +} + +static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) +{ + switch (evt) { + case SER_EV_STATE_IN: + /* wait m5 */ + hal_send_m4_event(ser); + + /* prevent FW response timeout */ + ser_set_alarm(ser, 1000, SER_EV_FW_M5_TIMEOUT); + break; + + case SER_EV_FW_M5_TIMEOUT: + ser_state_goto(ser, SER_L2_RESET_ST); + break; + + case SER_EV_MAC_RESET_DONE: + hal_enable_err_imr(ser); + + ser_state_goto(ser, SER_IDLE_ST); + break; + + case SER_EV_STATE_OUT: + ser_del_alarm(ser); + break; + + default: + break; + } +} + +static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf, + u8 sel, u32 start_addr, u32 len) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 filter_model_addr = mac->filter_model_addr; + u32 indir_access_addr = mac->indir_access_addr; + u32 mem_page_size = mac->mem_page_size; + u32 *ptr = (u32 *)buf; + u32 base_addr, start_page, residue; + u32 cnt = 0; + u32 i; + + start_page = start_addr / mem_page_size; + residue = start_addr % mem_page_size; + base_addr = rtw89_mac_mem_base_addrs(rtwdev, sel); + base_addr += start_page * mem_page_size; + + while (cnt < len) { + rtw89_write32(rtwdev, filter_model_addr, base_addr); + + for (i = indir_access_addr + residue; + i < indir_access_addr + mem_page_size; + i += 4, ptr++) { + *ptr = rtw89_read32(rtwdev, i); + cnt += 4; + if (cnt >= len) + break; + } + + residue = 0; + base_addr += mem_page_size; + } +} + +static void rtw89_ser_fw_rsvd_ple_dump(struct rtw89_dev *rtwdev, u8 *buf) +{ + u32 start_addr = rtwdev->chip->rsvd_ple_ofst; + + rtw89_debug(rtwdev, RTW89_DBG_SER, + "dump mem for fw rsvd payload engine (start addr: 0x%x)\n", + start_addr); + ser_mac_mem_dump(rtwdev, buf, RTW89_MAC_MEM_SHARED_BUF, start_addr, + RTW89_FW_RSVD_PLE_SIZE); +} + +struct __fw_backtrace_entry { + u32 wcpu_addr; + u32 size; + u32 key; +} __packed; + +struct __fw_backtrace_info { + u32 ra; + u32 sp; +} __packed; + +static_assert(RTW89_FW_BACKTRACE_INFO_SIZE == + sizeof(struct __fw_backtrace_info)); + +static u32 convert_addr_from_wcpu(u32 wcpu_addr) +{ + if (wcpu_addr < 0x30000000) + return wcpu_addr; + + return wcpu_addr & GENMASK(28, 0); +} + +static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf, + const struct __fw_backtrace_entry *ent) +{ + struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf; + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u32 filter_model_addr = mac->filter_model_addr; + u32 indir_access_addr = mac->indir_access_addr; + u32 fwbt_addr = convert_addr_from_wcpu(ent->wcpu_addr); + u32 fwbt_size = ent->size; + u32 fwbt_key = ent->key; + u32 i; + + if (fwbt_addr == 0) { + rtw89_warn(rtwdev, "FW backtrace invalid address: 0x%x\n", + fwbt_addr); + return -EINVAL; + } + + if (fwbt_key != RTW89_FW_BACKTRACE_KEY) { + rtw89_warn(rtwdev, "FW backtrace invalid key: 0x%x\n", + fwbt_key); + return -EINVAL; + } + + if (fwbt_size == 0 || !RTW89_VALID_FW_BACKTRACE_SIZE(fwbt_size) || + fwbt_size > RTW89_FW_BACKTRACE_MAX_SIZE) { + rtw89_warn(rtwdev, "FW backtrace invalid size: 0x%x\n", + fwbt_size); + return -EINVAL; + } + + rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n"); + rtw89_write32(rtwdev, filter_model_addr, fwbt_addr); + + for (i = indir_access_addr; + i < indir_access_addr + fwbt_size; + i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) { + *ptr = (struct __fw_backtrace_info){ + .ra = rtw89_read32(rtwdev, i), + .sp = rtw89_read32(rtwdev, i + 4), + }; + rtw89_debug(rtwdev, RTW89_DBG_SER, + "next sp: 0x%x, next ra: 0x%x\n", + ptr->sp, ptr->ra); + } + + rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace end\n"); + return 0; +} + +static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + struct rtw89_ser_cd_buffer *buf; + struct __fw_backtrace_entry fwbt_ent; + int ret = 0; + + buf = rtw89_ser_cd_prep(rtwdev); + if (!buf) { + ret = -ENOMEM; + goto bottom; + } + + rtw89_ser_fw_rsvd_ple_dump(rtwdev, buf->fwple.data); + + fwbt_ent = *(struct __fw_backtrace_entry *)buf->fwple.data; + ret = rtw89_ser_fw_backtrace_dump(rtwdev, buf->fwbt.data, &fwbt_ent); + if (ret) + goto bottom; + + rtw89_ser_cd_send(rtwdev, buf); + +bottom: + rtw89_ser_cd_free(rtwdev, buf, !!ret); + + ser_reset_mac_binding(rtwdev); + rtw89_core_stop(rtwdev); + rtw89_entity_init(rtwdev); + rtw89_fw_release_general_pkt_list(rtwdev, false); + INIT_LIST_HEAD(&rtwdev->rtwvifs_list); +} + +static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + + switch (evt) { + case SER_EV_STATE_IN: + wiphy_lock(rtwdev->hw->wiphy); + ser->sw_cnt.l2++; + ser_l2_reset_st_pre_hdl(ser); + wiphy_unlock(rtwdev->hw->wiphy); + + ieee80211_restart_hw(rtwdev->hw); + ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT); + break; + + case SER_EV_L2_RECFG_TIMEOUT: + rtw89_info(rtwdev, "Err: ser L2 re-config timeout\n"); + fallthrough; + case SER_EV_L2_RECFG_DONE: + ser_state_goto(ser, SER_IDLE_ST); + break; + + case SER_EV_STATE_OUT: + ser_del_alarm(ser); + break; + + default: + break; + } +} + +static const struct event_ent ser_ev_tbl[] = { + {SER_EV_NONE, "SER_EV_NONE"}, + {SER_EV_STATE_IN, "SER_EV_STATE_IN"}, + {SER_EV_STATE_OUT, "SER_EV_STATE_OUT"}, + {SER_EV_L1_RESET_PREPARE, "SER_EV_L1_RESET_PREPARE pre-m0"}, + {SER_EV_L1_RESET, "SER_EV_L1_RESET m1"}, + {SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"}, + {SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"}, + {SER_EV_L2_RESET, "SER_EV_L2_RESET"}, + {SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"}, + {SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"}, + {SER_EV_M1_TIMEOUT, "SER_EV_M1_TIMEOUT"}, + {SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"}, + {SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"}, + {SER_EV_L0_RESET, "SER_EV_L0_RESET"}, + {SER_EV_MAXX, "SER_EV_MAX"} +}; + +static const struct state_ent ser_st_tbl[] = { + {SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl}, + {SER_L1_RESET_PRE_ST, "SER_L1_RESET_PRE_ST", ser_l1_reset_pre_st_hdl}, + {SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl}, + {SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl}, + {SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl} +}; + +int rtw89_ser_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_ser *ser = &rtwdev->ser; + + memset(ser, 0, sizeof(*ser)); + INIT_LIST_HEAD(&ser->msg_q); + ser->state = SER_IDLE_ST; + ser->st_tbl = ser_st_tbl; + ser->ev_tbl = ser_ev_tbl; + + bitmap_zero(ser->flags, RTW89_NUM_OF_SER_FLAGS); + spin_lock_init(&ser->msg_q_lock); + INIT_WORK(&ser->ser_hdl_work, rtw89_ser_hdl_work); + INIT_DELAYED_WORK(&ser->ser_alarm_work, rtw89_ser_alarm_work); + return 0; +} + +int rtw89_ser_deinit(struct rtw89_dev *rtwdev) +{ + struct rtw89_ser *ser = (struct rtw89_ser *)&rtwdev->ser; + + set_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); + cancel_delayed_work_sync(&ser->ser_alarm_work); + cancel_work_sync(&ser->ser_hdl_work); + clear_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); + return 0; +} + +void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev) +{ + ser_send_msg(&rtwdev->ser, SER_EV_L2_RECFG_DONE); +} + +int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err) +{ + u8 event = SER_EV_NONE; + + rtw89_info(rtwdev, "SER catches error: 0x%x\n", err); + + switch (err) { + case MAC_AX_ERR_L1_PREERR_DMAC: /* pre-M0 */ + event = SER_EV_L1_RESET_PREPARE; + break; + case MAC_AX_ERR_L1_ERR_DMAC: + case MAC_AX_ERR_L0_PROMOTE_TO_L1: + event = SER_EV_L1_RESET; /* M1 */ + break; + case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE: + event = SER_EV_DO_RECOVERY; /* M3 */ + break; + case MAC_AX_ERR_L1_RESET_RECOVERY_DONE: + event = SER_EV_MAC_RESET_DONE; /* M5 */ + break; + case MAC_AX_ERR_L0_ERR_CMAC0: + case MAC_AX_ERR_L0_ERR_CMAC1: + case MAC_AX_ERR_L0_RESET_DONE: + event = SER_EV_L0_RESET; + break; + default: + if (err == MAC_AX_ERR_L1_PROMOTE_TO_L2 || + (err >= MAC_AX_ERR_L2_ERR_AH_DMA && + err <= MAC_AX_GET_ERR_MAX)) + event = SER_EV_L2_RESET; + break; + } + + if (event == SER_EV_NONE) { + rtw89_warn(rtwdev, "SER cannot recognize error: 0x%x\n", err); + return -EINVAL; + } + + ser_send_msg(&rtwdev->ser, event); + return 0; +} +EXPORT_SYMBOL(rtw89_ser_notify); diff --git a/drivers/net/wireless/realtek/rtw89/ser.h b/drivers/net/wireless/realtek/rtw89/ser.h new file mode 100644 index 000000000..6b8e62019 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/ser.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + * Copyright(c) 2019-2020 Realtek Corporation + */ +#ifndef __SER_H__ +#define __SER_H__ + +#include "core.h" + +int rtw89_ser_init(struct rtw89_dev *rtwdev); +int rtw89_ser_deinit(struct rtw89_dev *rtwdev); +int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err); +void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev); + +#endif /* __SER_H__*/ + diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h new file mode 100644 index 000000000..4e7109fbe --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -0,0 +1,892 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2020 Realtek Corporation + */ + +#ifndef __RTW89_TXRX_H__ +#define __RTW89_TXRX_H__ + +#include "debug.h" + +#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7) +#define DATA_RATE_MODE_CTRL_MASK_V1 GENMASK(10, 8) +#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0) +#define DATA_RATE_MODE_NON_HT 0x0 +#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0) +#define DATA_RATE_HT_IDX_MASK_V1 GENMASK(4, 0) +#define DATA_RATE_MODE_HT 0x1 +#define DATA_RATE_HT_NSS_MASK GENMASK(4, 3) +#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4) +#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0) +#define DATA_RATE_NSS_MASK_V1 GENMASK(7, 5) +#define DATA_RATE_MCS_MASK_V1 GENMASK(4, 0) +#define DATA_RATE_MODE_VHT 0x2 +#define DATA_RATE_MODE_HE 0x3 +#define DATA_RATE_MODE_EHT 0x4 + +static inline u8 rtw89_get_data_rate_mode(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK_V1); + + return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK); +} + +static inline u8 rtw89_get_data_not_ht_idx(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + return u16_get_bits(hw_rate, DATA_RATE_NOT_HT_IDX_MASK); +} + +static inline u8 rtw89_get_data_ht_mcs(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK_V1); + + return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK); +} + +static inline u8 rtw89_get_data_mcs(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + return u16_get_bits(hw_rate, DATA_RATE_MCS_MASK_V1); + + return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_IDX_MASK); +} + +static inline u8 rtw89_get_data_ht_nss(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + return u16_get_bits(hw_rate, DATA_RATE_HT_NSS_MASK); +} + +static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) +{ + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) + return u16_get_bits(hw_rate, DATA_RATE_NSS_MASK_V1); + + return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_NSS_MASK); +} + +/* TX WD BODY DWORD 0 */ +#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24) +#define RTW89_TXWD_BODY0_WP_OFFSET_V1 GENMASK(28, 24) +#define RTW89_TXWD_BODY0_MORE_DATA BIT(23) +#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22) +#define RTW89_TXWD_BODY0_FW_DL BIT(20) +#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16) +#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11) +#define RTW89_TXWD_BODY0_STF_MODE BIT(10) +#define RTW89_TXWD_BODY0_WD_PAGE BIT(7) +#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5) +#define RTW89_TXWD_BODY0_HW_SSN_SEL GENMASK(3, 2) +#define RTW89_TXWD_BODY0_HW_SSN_MODE GENMASK(1, 0) + +/* TX WD BODY DWORD 1 */ +#define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26) +#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) +#define RTW89_TXWD_BODY1_SEC_KEYID GENMASK(5, 4) +#define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0) + +/* TX WD BODY DWORD 2 */ +#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24) +#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23) +#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17) +#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0) + +/* TX WD BODY DWORD 3 */ +#define RTW89_TXWD_BODY3_BK BIT(13) +#define RTW89_TXWD_BODY3_AGG_EN BIT(12) +#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) + +/* TX WD BODY DWORD 4 */ +#define RTW89_TXWD_BODY4_SEC_IV_L1 GENMASK(31, 24) +#define RTW89_TXWD_BODY4_SEC_IV_L0 GENMASK(23, 16) + +/* TX WD BODY DWORD 5 */ +#define RTW89_TXWD_BODY5_SEC_IV_H5 GENMASK(31, 24) +#define RTW89_TXWD_BODY5_SEC_IV_H4 GENMASK(23, 16) +#define RTW89_TXWD_BODY5_SEC_IV_H3 GENMASK(15, 8) +#define RTW89_TXWD_BODY5_SEC_IV_H2 GENMASK(7, 0) + +/* TX WD BODY DWORD 6 (V1) */ + +/* TX WD BODY DWORD 7 (V1) */ +#define RTW89_TXWD_BODY7_USE_RATE_V1 BIT(31) +#define RTW89_TXWD_BODY7_DATA_BW GENMASK(29, 28) +#define RTW89_TXWD_BODY7_GI_LTF GENMASK(27, 25) +#define RTW89_TXWD_BODY7_DATA_RATE GENMASK(24, 16) + +/* TX WD INFO DWORD 0 */ +#define RTW89_TXWD_INFO0_USE_RATE BIT(30) +#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) +#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25) +#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16) +#define RTW89_TXWD_INFO0_DATA_ER BIT(15) +#define RTW89_TXWD_INFO0_DATA_STBC BIT(12) +#define RTW89_TXWD_INFO0_DATA_LDPC BIT(11) +#define RTW89_TXWD_INFO0_DISDATAFB BIT(10) +#define RTW89_TXWD_INFO0_DATA_BW_ER BIT(8) +#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4) + +/* TX WD INFO DWORD 1 */ +#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL BIT(31) +#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT GENMASK(30, 25) +#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) +#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) +#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) + +/* TX WD INFO DWORD 2 */ +#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18) +#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9) +#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8) +#define RTW89_TXWD_INFO2_FORCE_KEY_EN BIT(8) +#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) + +/* TX WD INFO DWORD 3 */ +#define RTW89_TXWD_INFO3_SPE_RPT BIT(10) + +/* TX WD INFO DWORD 4 */ +#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) +#define RTW89_TXWD_INFO4_RTS_EN BIT(27) +#define RTW89_TXWD_INFO4_SW_DEFINE GENMASK(3, 0) + +/* TX WD INFO DWORD 5 */ + +/* TX WD BODY DWORD 0 */ +#define BE_TXD_BODY0_EN_HWSEQ_MODE GENMASK(1, 0) +#define BE_TXD_BODY0_HW_SSN_SEL GENMASK(4, 2) +#define BE_TXD_BODY0_HWAMSDU BIT(5) +#define BE_TXD_BODY0_HW_SEC_IV BIT(6) +#define BE_TXD_BODY0_WD_PAGE BIT(7) +#define BE_TXD_BODY0_CHK_EN BIT(8) +#define BE_TXD_BODY0_WP_INT BIT(9) +#define BE_TXD_BODY0_STF_MODE BIT(10) +#define BE_TXD_BODY0_HDR_LLC_LEN GENMASK(15, 11) +#define BE_TXD_BODY0_CH_DMA GENMASK(19, 16) +#define BE_TXD_BODY0_SMH_EN BIT(20) +#define BE_TXD_BODY0_PKT_OFFSET BIT(21) +#define BE_TXD_BODY0_WDINFO_EN BIT(22) +#define BE_TXD_BODY0_MOREDATA BIT(23) +#define BE_TXD_BODY0_WP_OFFSET_V1 GENMASK(27, 24) +#define BE_TXD_BODY0_AZ_FTM_SEC_V1 BIT(28) +#define BE_TXD_BODY0_WD_SOURCE GENMASK(30, 29) +#define BE_TXD_BODY0_HCI_SEQNUM_MODE BIT(31) + +/* TX WD BODY DWORD 1 */ +#define BE_TXD_BODY1_DMA_TXAGG_NUM GENMASK(6, 0) +#define BE_TXD_BODY1_REUSE_NUM GENMASK(11, 7) +#define BE_TXD_BODY1_SEC_TYPE GENMASK(15, 12) +#define BE_TXD_BODY1_SEC_KEYID GENMASK(17, 16) +#define BE_TXD_BODY1_SW_SEC_IV BIT(18) +#define BE_TXD_BODY1_REUSE_SIZE GENMASK(23, 20) +#define BE_TXD_BODY1_REUSE_START_OFFSET GENMASK(25, 24) +#define BE_TXD_BODY1_ADDR_INFO_NUM GENMASK(31, 26) + +/* TX WD BODY DWORD 2 */ +#define BE_TXD_BODY2_TXPKTSIZE GENMASK(13, 0) +#define BE_TXD_BODY2_AGG_EN BIT(14) +#define BE_TXD_BODY2_BK BIT(15) +#define BE_TXD_BODY2_MACID_EXTEND BIT(16) +#define BE_TXD_BODY2_QSEL GENMASK(22, 17) +#define BE_TXD_BODY2_TID_IND BIT(23) +#define BE_TXD_BODY2_MACID GENMASK(31, 24) +#define BE_TXD_BODY2_QSEL_V1 GENMASK(20, 15) +#define BE_TXD_BODY2_TID_IND_V1 BIT(21) +#define BE_TXD_BODY2_MACID_V1 GENMASK(31, 22) + +/* TX WD BODY DWORD 3 */ +#define BE_TXD_BODY3_WIFI_SEQ GENMASK(11, 0) +#define BE_TXD_BODY3_MLO_FLAG BIT(12) +#define BE_TXD_BODY3_IS_MLD_SW_EN BIT(13) +#define BE_TXD_BODY3_TRY_RATE BIT(14) +#define BE_TXD_BODY3_BK_V1 BIT(14) +#define BE_TXD_BODY3_RELINK_FLAG_V1 BIT(15) +#define BE_TXD_BODY3_BAND0_SU_TC_V1 GENMASK(21, 16) +#define BE_TXD_BODY3_TOTAL_TC GENMASK(27, 22) +#define BE_TXD_BODY3_RU_RTY BIT(28) +#define BE_TXD_BODY3_MU_PRI_RTY BIT(29) +#define BE_TXD_BODY3_MU_2ND_RTY BIT(30) +#define BE_TXD_BODY3_BAND1_SU_RTY_V1 BIT(31) +#define BE_TXD_BODY3_DRIVER_QUEUE_TIME GENMASK(31, 16) + +/* TX WD BODY DWORD 4 */ +#define BE_TXD_BODY4_TXDESC_CHECKSUM GENMASK(15, 0) +#define BE_TXD_BODY4_SEC_IV_L0 GENMASK(23, 16) +#define BE_TXD_BODY4_SEC_IV_L1 GENMASK(31, 24) + +/* TX WD BODY DWORD 5 */ +#define BE_TXD_BODY5_SEC_IV_H2 GENMASK(7, 0) +#define BE_TXD_BODY5_SEC_IV_H3 GENMASK(15, 8) +#define BE_TXD_BODY5_SEC_IV_H4 GENMASK(23, 16) +#define BE_TXD_BODY5_SEC_IV_H5 GENMASK(31, 24) + +/* TX WD BODY DWORD 6 */ +#define BE_TXD_BODY6_MU_TC GENMASK(4, 0) +#define BE_TXD_BODY6_RU_TC GENMASK(9, 5) +#define BE_TXD_BODY6_PS160 BIT(10) +#define BE_TXD_BODY6_BMC BIT(11) +#define BE_TXD_BODY6_NO_ACK BIT(12) +#define BE_TXD_BODY6_UPD_WLAN_HDR BIT(13) +#define BE_TXD_BODY6_A4_HDR BIT(14) +#define BE_TXD_BODY6_EOSP_BIT BIT(15) +#define BE_TXD_BODY6_S_IDX GENMASK(23, 16) +#define BE_TXD_BODY6_RU_POS GENMASK(31, 24) +#define BE_TXD_BODY6_MU_TC_V1 GENMASK(3, 0) +#define BE_TXD_BODY6_RU_TC_V1 GENMASK(8, 5) +#define BE_TXD_BODY6_RELINK_EN BIT(9) +#define BE_TXD_BODY6_RELINK_LAST BIT(10) + +/* TX WD BODY DWORD 7 */ +#define BE_TXD_BODY7_RTS_TC GENMASK(5, 0) +#define BE_TXD_BODY7_MSDU_NUM GENMASK(9, 6) +#define BE_TXD_BODY7_DATA_ER BIT(10) +#define BE_TXD_BODY7_DATA_BW_ER BIT(11) +#define BE_TXD_BODY7_DATA_DCM BIT(12) +#define BE_TXD_BODY7_GI_LTF GENMASK(15, 13) +#define BE_TXD_BODY7_DATARATE GENMASK(27, 16) +#define BE_TXD_BODY7_DATA_BW GENMASK(30, 28) +#define BE_TXD_BODY7_USERATE_SEL BIT(31) + +/* TX WD INFO DWORD 0 */ +#define BE_TXD_INFO0_MBSSID GENMASK(3, 0) +#define BE_TXD_INFO0_MULTIPORT_ID GENMASK(6, 4) +#define BE_TXD_INFO0_DISRTSFB BIT(9) +#define BE_TXD_INFO0_DISDATAFB BIT(10) +#define BE_TXD_INFO0_DATA_LDPC BIT(11) +#define BE_TXD_INFO0_DATA_STBC BIT(12) +#define BE_TXD_INFO0_DATA_TXCNT_LMT GENMASK(21, 16) +#define BE_TXD_INFO0_DATA_TXCNT_LMT_SEL BIT(22) +#define BE_TXD_INFO0_RESP_PHYSTS_CSI_EN_V1 BIT(23) +#define BE_TXD_INFO0_RLS_TO_CPUIO BIT(30) +#define BE_TXD_INFO0_ACK_CH_INFO BIT(31) + +/* TX WD INFO DWORD 1 */ +#define BE_TXD_INFO1_MAX_AGG_NUM GENMASK(7, 0) +#define BE_TXD_INFO1_BCN_SRCH_SEQ GENMASK(9, 8) +#define BE_TXD_INFO1_NAVUSEHDR BIT(10) +#define BE_TXD_INFO1_A_CTRL_BQR BIT(12) +#define BE_TXD_INFO1_A_CTRL_BSR BIT(14) +#define BE_TXD_INFO1_A_CTRL_CAS BIT(15) +#define BE_TXD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(27, 16) +#define BE_TXD_INFO1_SW_DEFINE GENMASK(31, 28) + +/* TX WD INFO DWORD 2 */ +#define BE_TXD_INFO2_SEC_CAM_IDX GENMASK(7, 0) +#define BE_TXD_INFO2_FORCE_KEY_EN BIT(8) +#define BE_TXD_INFO2_SEC_CAM_IDX_V1 GENMASK(9, 0) +#define BE_TXD_INFO2_FORCE_KEY_EN_V1 BIT(10) +#define BE_TXD_INFO2_LIFETIME_SEL GENMASK(15, 13) +#define BE_TXD_INFO2_FORCE_TXOP BIT(17) +#define BE_TXD_INFO2_AMPDU_DENSITY GENMASK(20, 18) +#define BE_TXD_INFO2_LSIG_TXOP_EN BIT(21) +#define BE_TXD_INFO2_OBW_CTS2SELF_DUP_TYPE GENMASK(29, 26) +#define BE_TXD_INFO2_SPE_RPT_V1 BIT(30) +#define BE_TXD_INFO2_SIFS_TX_V1 BIT(31) + +/* TX WD INFO DWORD 3 */ +#define BE_TXD_INFO3_SPE_PKT GENMASK(3, 0) +#define BE_TXD_INFO3_SPE_PKT_TYPE GENMASK(7, 4) +#define BE_TXD_INFO3_CQI_SND BIT(8) +#define BE_TXD_INFO3_RTT_EN BIT(9) +#define BE_TXD_INFO3_HT_DATA_SND_V1 BIT(10) +#define BE_TXD_INFO3_BT_NULL BIT(11) +#define BE_TXD_INFO3_DISABLE_TXBF BIT(11) +#define BE_TXD_INFO3_TRI_FRAME BIT(12) +#define BE_TXD_INFO3_NULL_0 BIT(13) +#define BE_TXD_INFO3_NULL_1 BIT(14) +#define BE_TXD_INFO3_RAW BIT(15) +#define BE_TXD_INFO3_GROUP_BIT_IE_OFFSET GENMASK(23, 16) +#define BE_TXD_INFO3_SIGNALING_TA_PKT_EN BIT(25) +#define BE_TXD_INFO3_BCNPKT_TSF_CTRL BIT(26) +#define BE_TXD_INFO3_SIGNALING_TA_PKT_SC GENMASK(30, 27) +#define BE_TXD_INFO3_FORCE_BSS_CLR BIT(31) + +/* TX WD INFO DWORD 4 */ +#define BE_TXD_INFO4_PUNCTURE_PATTERN GENMASK(15, 0) +#define BE_TXD_INFO4_PUNC_MODE GENMASK(17, 16) +#define BE_TXD_INFO4_SW_TX_OK_0 BIT(18) +#define BE_TXD_INFO4_SW_TX_OK_1 BIT(19) +#define BE_TXD_INFO4_SW_EHT_NLTF_SWITCH BIT(20) +#define BE_TXD_INFO4_SW_EHT_NLTF GENMASK(22, 21) +#define BE_TXD_INFO4_SW_TX_PWR_DBM GENMASK(26, 23) +#define BE_TXD_INFO4_RTS_EN BIT(27) +#define BE_TXD_INFO4_CTS2SELF BIT(28) +#define BE_TXD_INFO4_CCA_RTS GENMASK(30, 29) +#define BE_TXD_INFO4_HW_RTS_EN BIT(31) + +/* TX WD INFO DWORD 5 */ +#define BE_TXD_INFO5_SR_RATE_V1 GENMASK(4, 0) +#define BE_TXD_INFO5_SR_EN_V1 BIT(5) +#define BE_TXD_INFO5_NDPA_DURATION GENMASK(31, 16) + +/* TX WD INFO DWORD 6 */ +#define BE_TXD_INFO6_UL_APEP_LEN GENMASK(11, 0) +#define BE_TXD_INFO6_UL_GI_LTF GENMASK(14, 12) +#define BE_TXD_INFO6_UL_DOPPLER BIT(15) +#define BE_TXD_INFO6_UL_STBC BIT(16) +#define BE_TXD_INFO6_UL_MU_MIMO_EN BIT(17) +#define BE_TXD_INFO6_UL_LENGTH_REF GENMASK(21, 18) +#define BE_TXD_INFO6_UL_RF_GAIN_IDX GENMASK(31, 22) + +/* TX WD INFO DWORD 7 */ +#define BE_TXD_INFO7_UL_FIXED_GAIN_EN BIT(0) +#define BE_TXD_INFO7_UL_PRI_EXP_RSSI_DBM GENMASK(7, 1) +#define BE_TXD_INFO7_ELNA_IDX BIT(8) +#define BE_TXD_INFO7_UL_APEP_UNIT GENMASK(10, 9) +#define BE_TXD_INFO7_UL_TRI_PAD GENMASK(13, 11) +#define BE_TXD_INFO7_UL_T_PE GENMASK(15, 14) +#define BE_TXD_INFO7_UL_EHT_USR_PRES BIT(16) +#define BE_TXD_INFO7_UL_HELTF_SYMBOL_NUM GENMASK(19, 17) +#define BE_TXD_INFO7_ULBW GENMASK(21, 20) +#define BE_TXD_INFO7_ULBW_EXT GENMASK(23, 22) +#define BE_TXD_INFO7_UL_TRI_PAD_TSF BIT(24) +#define BE_TXD_INFO7_USE_WD_UL GENMASK(25, 24) +#define BE_TXD_INFO7_EXTEND_MODE_SEL GENMASK(31, 28) + +/* RX WD dword0 */ +#define AX_RXD_RPKT_LEN_MASK GENMASK(13, 0) +#define AX_RXD_SHIFT_MASK GENMASK(15, 14) +#define AX_RXD_WL_HD_IV_LEN_MASK GENMASK(21, 16) +#define AX_RXD_BB_SEL BIT(22) +#define AX_RXD_MAC_INFO_VLD BIT(23) +#define AX_RXD_RPKT_TYPE_MASK GENMASK(27, 24) +#define AX_RXD_DRV_INFO_SIZE_MASK GENMASK(30, 28) +#define AX_RXD_LONG_RXD BIT(31) + +/* RX WD dword1 */ +#define AX_RXD_PPDU_TYPE_MASK GENMASK(3, 0) +#define AX_RXD_PPDU_CNT_MASK GENMASK(6, 4) +#define AX_RXD_SR_EN BIT(7) +#define AX_RXD_USER_ID_MASK GENMASK(15, 8) +#define AX_RXD_USER_ID_v1_MASK GENMASK(13, 8) +#define AX_RXD_RX_DATARATE_MASK GENMASK(24, 16) +#define AX_RXD_RX_GI_LTF_MASK GENMASK(27, 25) +#define AX_RXD_NON_SRG_PPDU BIT(28) +#define AX_RXD_INTER_PPDU BIT(29) +#define AX_RXD_NON_SRG_PPDU_v1 BIT(14) +#define AX_RXD_INTER_PPDU_v1 BIT(15) +#define AX_RXD_BW_MASK GENMASK(31, 30) +#define AX_RXD_BW_v1_MASK GENMASK(31, 29) + +/* RX WD dword2 */ +#define AX_RXD_FREERUN_CNT_MASK GENMASK(31, 0) + +/* RX WD dword3 */ +#define AX_RXD_A1_MATCH BIT(0) +#define AX_RXD_SW_DEC BIT(1) +#define AX_RXD_HW_DEC BIT(2) +#define AX_RXD_AMPDU BIT(3) +#define AX_RXD_AMPDU_END_PKT BIT(4) +#define AX_RXD_AMSDU BIT(5) +#define AX_RXD_AMSDU_CUT BIT(6) +#define AX_RXD_LAST_MSDU BIT(7) +#define AX_RXD_BYPASS BIT(8) +#define AX_RXD_CRC32_ERR BIT(9) +#define AX_RXD_ICV_ERR BIT(10) +#define AX_RXD_MAGIC_WAKE BIT(11) +#define AX_RXD_UNICAST_WAKE BIT(12) +#define AX_RXD_PATTERN_WAKE BIT(13) +#define AX_RXD_GET_CH_INFO_MASK GENMASK(15, 14) +#define AX_RXD_PATTERN_IDX_MASK GENMASK(20, 16) +#define AX_RXD_TARGET_IDC_MASK GENMASK(23, 21) +#define AX_RXD_CHKSUM_OFFLOAD_EN BIT(24) +#define AX_RXD_WITH_LLC BIT(25) +#define AX_RXD_RX_STATISTICS BIT(26) + +/* RX WD dword4 */ +#define AX_RXD_TYPE_MASK GENMASK(1, 0) +#define AX_RXD_MC BIT(2) +#define AX_RXD_BC BIT(3) +#define AX_RXD_MD BIT(4) +#define AX_RXD_MF BIT(5) +#define AX_RXD_PWR BIT(6) +#define AX_RXD_QOS BIT(7) +#define AX_RXD_TID_MASK GENMASK(11, 8) +#define AX_RXD_EOSP BIT(12) +#define AX_RXD_HTC BIT(13) +#define AX_RXD_QNULL BIT(14) +#define AX_RXD_SEQ_MASK GENMASK(27, 16) +#define AX_RXD_FRAG_MASK GENMASK(31, 28) + +/* RX WD dword5 */ +#define AX_RXD_SEC_CAM_IDX_MASK GENMASK(7, 0) +#define AX_RXD_ADDR_CAM_MASK GENMASK(15, 8) +#define AX_RXD_MAC_ID_MASK GENMASK(23, 16) +#define AX_RXD_RX_PL_ID_MASK GENMASK(27, 24) +#define AX_RXD_ADDR_CAM_VLD BIT(28) +#define AX_RXD_ADDR_FWD_EN BIT(29) +#define AX_RXD_RX_PL_MATCH BIT(30) + +/* RX WD dword6 */ +#define AX_RXD_MAC_ADDR_MASK GENMASK(31, 0) + +/* RX WD dword7 */ +#define AX_RXD_MAC_ADDR_H_MASK GENMASK(15, 0) +#define AX_RXD_SMART_ANT BIT(16) +#define AX_RXD_SEC_TYPE_MASK GENMASK(20, 17) +#define AX_RXD_HDR_CNV BIT(21) +#define AX_RXD_HDR_OFFSET_MASK GENMASK(26, 22) +#define AX_RXD_BIP_KEYID BIT(27) +#define AX_RXD_BIP_ENC BIT(28) + +struct rtw89_rxinfo_user { + __le32 w0; +}; + +#define RTW89_RXINFO_USER_MAC_ID_VALID BIT(0) +#define RTW89_RXINFO_USER_DATA BIT(1) +#define RTW89_RXINFO_USER_CTRL BIT(2) +#define RTW89_RXINFO_USER_MGMT BIT(3) +#define RTW89_RXINFO_USER_BCN BIT(4) +#define RTW89_RXINFO_USER_MACID GENMASK(15, 8) +#define RTW89_RXINFO_USER_MACID_V1 GENMASK(31, 20) + +struct rtw89_rxinfo { + __le32 w0; + __le32 w1; + struct rtw89_rxinfo_user user[]; +} __packed; + +#define RTW89_RXINFO_W0_USR_NUM GENMASK(3, 0) +#define RTW89_RXINFO_W0_USR_NUM_V1 GENMASK(4, 0) +#define RTW89_RXINFO_W0_FW_DEFINE GENMASK(15, 8) +#define RTW89_RXINFO_W0_PLCP_LEN_V1 GENMASK(23, 16) +#define RTW89_RXINFO_W0_LSIG_LEN GENMASK(27, 16) +#define RTW89_RXINFO_W0_INVALID_V1 BIT(27) +#define RTW89_RXINFO_W0_IS_TO_SELF BIT(28) +#define RTW89_RXINFO_W0_RX_CNT_VLD BIT(29) +#define RTW89_RXINFO_W0_LONG_RXD GENMASK(31, 30) +#define RTW89_RXINFO_W1_SERVICE GENMASK(15, 0) +#define RTW89_RXINFO_W1_PLCP_LEN GENMASK(23, 16) + +struct rtw89_phy_sts_hdr { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0) +#define RTW89_PHY_STS_HDR_W0_HDR_2_EN BIT(5) +#define RTW89_PHY_STS_HDR_W0_VALID BIT(7) +#define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8) +#define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24) +#define RTW89_PHY_STS_HDR_W1_RSSI_A GENMASK(7, 0) +#define RTW89_PHY_STS_HDR_W1_RSSI_B GENMASK(15, 8) +#define RTW89_PHY_STS_HDR_W1_RSSI_C GENMASK(23, 16) +#define RTW89_PHY_STS_HDR_W1_RSSI_D GENMASK(31, 24) + +struct rtw89_phy_sts_hdr_v2 { + __le32 w0; + __le32 w1; +} __packed; + +#define RTW89_PHY_STS_HDR_V2_W0_PATH_EN GENMASK(20, 16) + +struct rtw89_phy_sts_iehdr { + __le32 w0; +}; + +#define RTW89_PHY_STS_IEHDR_TYPE GENMASK(4, 0) +#define RTW89_PHY_STS_IEHDR_LEN GENMASK(11, 5) + +/* BE RXD dword0 */ +#define BE_RXD_RPKT_LEN_MASK GENMASK(13, 0) +#define BE_RXD_SHIFT_MASK GENMASK(15, 14) +#define BE_RXD_DRV_INFO_SZ_MASK GENMASK(19, 18) +#define BE_RXD_HDR_CNV_SZ_MASK GENMASK(21, 20) +#define BE_RXD_PHY_RPT_SZ_MASK GENMASK(23, 22) +#define BE_RXD_RPKT_TYPE_MASK GENMASK(29, 24) +#define BE_RXD_BB_SEL BIT(30) +#define BE_RXD_LONG_RXD BIT(31) + +/* BE RXD dword1 */ +#define BE_RXD_PKT_ID_MASK GENMASK(11, 0) +#define BE_RXD_FWD_TARGET_MASK GENMASK(23, 16) +#define BE_RXD_BCN_FW_INFO_MASK GENMASK(25, 24) +#define BE_RXD_FW_RLS BIT(26) + +/* BE RXD dword2 */ +#define BE_RXD_MAC_ID_MASK GENMASK(7, 0) +#define BE_RXD_MAC_ID_V1 GENMASK(9, 0) +#define BE_RXD_TYPE_MASK GENMASK(11, 10) +#define BE_RXD_LAST_MSDU BIT(12) +#define BE_RXD_AMSDU_CUT BIT(13) +#define BE_RXD_ADDR_CAM_VLD BIT(14) +#define BE_RXD_REORDER BIT(15) +#define BE_RXD_SEQ_MASK GENMASK(27, 16) +#define BE_RXD_TID_MASK GENMASK(31, 28) + +/* BE RXD dword3 */ +#define BE_RXD_SEC_TYPE_MASK GENMASK(3, 0) +#define BE_RXD_BIP_KEYID BIT(4) +#define BE_RXD_BIP_ENC BIT(5) +#define BE_RXD_CRC32_ERR BIT(6) +#define BE_RXD_ICV_ERR BIT(7) +#define BE_RXD_HW_DEC BIT(8) +#define BE_RXD_SW_DEC BIT(9) +#define BE_RXD_A1_MATCH BIT(10) +#define BE_RXD_AMPDU BIT(11) +#define BE_RXD_AMPDU_EOF BIT(12) +#define BE_RXD_AMSDU BIT(13) +#define BE_RXD_MC BIT(14) +#define BE_RXD_BC BIT(15) +#define BE_RXD_MD BIT(16) +#define BE_RXD_MF BIT(17) +#define BE_RXD_PWR BIT(18) +#define BE_RXD_QOS BIT(19) +#define BE_RXD_EOSP BIT(20) +#define BE_RXD_HTC BIT(21) +#define BE_RXD_QNULL BIT(22) +#define BE_RXD_A4_FRAME BIT(23) +#define BE_RXD_FRAG_MASK GENMASK(27, 24) +#define BE_RXD_GET_CH_INFO_V2 GENMASK(31, 29) +#define BE_RXD_GET_CH_INFO_V1_MASK GENMASK(31, 30) + +/* BE RXD dword4 */ +#define BE_RXD_PPDU_TYPE_MASK GENMASK(7, 0) +#define BE_RXD_PPDU_CNT_MASK GENMASK(10, 8) +#define BE_RXD_BW_MASK GENMASK(14, 12) +#define BE_RXD_RX_GI_LTF_MASK GENMASK(18, 16) +#define BE_RXD_RX_REORDER_FIELD_EN BIT(19) +#define BE_RXD_RX_DATARATE_MASK GENMASK(31, 20) + +/* BE RXD dword5 */ +#define BE_RXD_FREERUN_CNT_MASK GENMASK(31, 0) + +/* BE RXD dword6 */ +#define BE_RXD_ADDR_CAM_MASK GENMASK(7, 0) +#define BE_RXD_ADDR_CAM_V1 GENMASK(9, 0) +#define BE_RXD_RX_STATISTICS_V1 BIT(11) +#define BE_RXD_SMART_ANT_V1 BIT(12) +#define BE_RXD_SR_EN BIT(13) +#define BE_RXD_NON_SRG_PPDU BIT(14) +#define BE_RXD_INTER_PPDU BIT(15) +#define BE_RXD_USER_ID_MASK GENMASK(21, 16) +#define BE_RXD_SEC_CAM_IDX_V1 GENMASK(31, 22) +#define BE_RXD_RX_STATISTICS BIT(22) +#define BE_RXD_SMART_ANT BIT(23) +#define BE_RXD_SEC_CAM_IDX_MASK GENMASK(31, 24) + +/* BE RXD dword7 */ +#define BE_RXD_PATTERN_IDX_MASK GENMASK(4, 0) +#define BE_RXD_MAGIC_WAKE BIT(5) +#define BE_RXD_UNICAST_WAKE BIT(6) +#define BE_RXD_PATTERN_WAKE BIT(7) +#define BE_RXD_RX_PL_MATCH BIT(8) +#define BE_RXD_RX_PL_ID_MASK GENMASK(15, 12) +#define BE_RXD_HDR_CNV BIT(16) +#define BE_RXD_NAT25_HIT BIT(17) +#define BE_RXD_IS_DA BIT(18) +#define BE_RXD_CHKSUM_OFFLOAD_EN BIT(19) +#define BE_RXD_RXSC_ENTRY_MASK GENMASK(22, 20) +#define BE_RXD_RXSC_HIT BIT(23) +#define BE_RXD_WITH_LLC BIT(24) +#define BE_RXD_RX_AGG_FIELD_EN BIT(25) + +/* BE RXD dword8 */ +#define BE_RXD_MAC_ADDR_MASK GENMASK(31, 0) + +/* BE RXD dword9 */ +#define BE_RXD_MAC_ADDR_H_MASK GENMASK(15, 0) +#define BE_RXD_HDR_OFFSET_MASK GENMASK(20, 16) +#define BE_RXD_WL_HD_IV_LEN_MASK GENMASK(26, 21) + +/* BE RXD - PHY RPT dword0 */ +#define BE_RXD_PHY_RSSI GENMASK(11, 0) + +struct rtw89_phy_sts_ie00 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_PHY_STS_IE00_W0_RPL GENMASK(15, 7) +#define RTW89_PHY_STS_IE00_W3_RX_PATH_EN GENMASK(31, 28) + +struct rtw89_phy_sts_ie00_v2 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; +} __packed; + +#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A GENMASK(8, 0) +#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B GENMASK(17, 9) +#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C GENMASK(26, 18) +#define RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D GENMASK(8, 0) + +struct rtw89_phy_sts_ie01 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; +} __packed; + +#define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16) +#define RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD GENMASK(15, 8) +#define RTW89_PHY_STS_IE01_W0_RX_PATH_EN GENMASK(31, 28) +#define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8) +#define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20) +#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0) +#define RTW89_PHY_STS_IE01_W2_EVM_MAX GENMASK(15, 8) +#define RTW89_PHY_STS_IE01_W2_EVM_MIN GENMASK(23, 16) +#define RTW89_PHY_STS_IE01_W2_SU BIT(27) +#define RTW89_PHY_STS_IE01_W2_LDPC BIT(28) +#define RTW89_PHY_STS_IE01_W2_STBC BIT(30) +#define RTW89_PHY_STS_IE01_W3_BF BIT(8) + +struct rtw89_phy_sts_ie01_v2 { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; +} __packed; + +#define RTW89_PHY_STS_IE01_V2_W5_BW_IDX GENMASK(31, 29) +#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A GENMASK(11, 4) +#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B GENMASK(23, 16) +#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C GENMASK(11, 4) +#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D GENMASK(23, 16) + +union rtw89_phy_sts_ie09 { + struct { + __le64 qw0; + } gen0; + struct { + __le64 qw0; + __le64 qw1; + } gen2; +} __packed; + +#define RTW89_PHY_STS_IE09_L_SIG_MASK GENMASK(21, 5) /* Legacy/VHT/HE L-SIG */ +#define RTW89_PHY_STS_IE09_L_SIG_MASK_GEN2 GENMASK(31, 15) /* Legacy/VHT/HE L-SIG for GEN2 */ +#define RTW89_PHY_STS_IE09_L_SIG_RATE GENMASK(3, 0) +#define RTW89_PHY_STS_IE09_L_SIG_RSVD BIT(4) +#define RTW89_PHY_STS_IE09_L_SIG_LENGTH GENMASK(16, 5) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK GENMASK_ULL(45, 22) /* VHT SIG-A1 */ +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK_GEN2 GENMASK_ULL(55, 32) /* VHT SIG-A1 for GEN2 */ +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_BW GENMASK(1, 0) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_RSVD1 BIT(2) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_STBC BIT(3) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_GRP_ID GENMASK(9, 4) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_SU_NSTS GENMASK(12, 10) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_SU_PAID GENMASK(21, 13) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS0 GENMASK(12, 10) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS1 GENMASK(15, 13) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS2 GENMASK(18, 16) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS3 GENMASK(21, 19) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_TXOP_NOPS BIT(22) +#define RTW89_PHY_STS_IE09_VHT_SIG_A1_RSVD2 BIT(23) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK GENMASK_ULL(55, 46) /* VHT SIG-A2 */ +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 56) /* VHT SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK_GEN2_H8 GENMASK_ULL(1, 0) /* VHT SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SGI BIT(0) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SGI_DISA BIT(1) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SUMU_CODE0 BIT(2) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_LDPC BIT(3) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SUMU_CODE3 GENMASK(7, 4) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_BF BIT(8) +#define RTW89_PHY_STS_IE09_VHT_SIG_A2_RSVD3 BIT(9) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE SU SIG-A1 */ +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE SU SIG-A1 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_FORMAT BIT(0) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BEAM_CHANGE BIT(1) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_ULDL BIT(2) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MCS GENMASK(6, 3) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_DCM BIT(7) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BSS_COLOR GENMASK(13, 8) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_RSVD1 BIT(14) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_SR GENMASK(18, 15) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BW GENMASK(20, 19) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_GILTF GENMASK(22, 21) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_NSTS GENMASK(25, 23) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE SU SIG-A2 */ +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE SU SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE SU SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_TXOP GENMASK(6, 0) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_CODING BIT(7) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_LDPC_XSYMSEG BIT(8) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_STBC BIT(9) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_BEAMFORMED BIT(10) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PREFEC GENMASK(12, 11) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PE BIT(13) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_RSVD2 BIT(14) +#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_DOPPLER BIT(15) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE TB SIG-A1 */ +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE TB SIG-A1 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_FORMAT BIT(0) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_BSS_COLOR GENMASK(6, 1) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB1 GENMASK(10, 7) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB2 GENMASK(14, 11) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB3 GENMASK(18, 15) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB4 GENMASK(22, 19) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_RSVD1 BIT(23) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_BW GENMASK(25, 24) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE TB SIG-A2 */ +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE TB SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE TB SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_TXOP GENMASK(6, 0) +#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_RSVD1 GENMASK(15, 7) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE MU SIG-A1 */ +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE MU SIG-A1 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_ULDL BIT(0) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_MCS GENMASK(3, 1) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_DCM BIT(4) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BSS_COLOR GENMASK(10, 5) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SR GENMASK(14, 11) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BW GENMASK(17, 15) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_SYM_USR GENMASK(21, 18) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_COM BIT(22) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_GI_LTF GENMASK(24, 23) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_DOPPLER BIT(25) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE MU SIG-A2 */ +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE MU SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE MU SIG-A2 for GEN2 */ +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_TXOP GENMASK(6, 0) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_RSVD BIT(7) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_LTF_MID GENMASK(10, 8) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MID BIT(10) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_LPDC_XSYMSEG BIT(11) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_STBC BIT(12) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_FEC GENMASK(14, 13) +#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_PE BIT(15) + +struct rtw89_phy_sts_ie10 { + __le64 qw0; + u8 sigb[]; +} __packed; + +enum rtw89_tx_channel { + RTW89_TXCH_ACH0 = 0, + RTW89_TXCH_ACH1 = 1, + RTW89_TXCH_ACH2 = 2, + RTW89_TXCH_ACH3 = 3, + RTW89_TXCH_ACH4 = 4, + RTW89_TXCH_ACH5 = 5, + RTW89_TXCH_ACH6 = 6, + RTW89_TXCH_ACH7 = 7, + RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */ + RTW89_TXCH_CH9 = 9, /* HI Band 0 */ + RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */ + RTW89_TXCH_CH11 = 11, /* HI Band 1 */ + RTW89_TXCH_CH12 = 12, /* FW CMD */ + + /* keep last */ + RTW89_TXCH_NUM, + RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1 +}; + +enum rtw89_rx_channel { + RTW89_RXCH_RXQ = 0, + RTW89_RXCH_RPQ = 1, + + /* keep last */ + RTW89_RXCH_NUM, + RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1 +}; + +enum rtw89_tx_qsel { + RTW89_TX_QSEL_BE_0 = 0x00, + RTW89_TX_QSEL_BK_0 = 0x01, + RTW89_TX_QSEL_VI_0 = 0x02, + RTW89_TX_QSEL_VO_0 = 0x03, + RTW89_TX_QSEL_BE_1 = 0x04, + RTW89_TX_QSEL_BK_1 = 0x05, + RTW89_TX_QSEL_VI_1 = 0x06, + RTW89_TX_QSEL_VO_1 = 0x07, + RTW89_TX_QSEL_BE_2 = 0x08, + RTW89_TX_QSEL_BK_2 = 0x09, + RTW89_TX_QSEL_VI_2 = 0x0a, + RTW89_TX_QSEL_VO_2 = 0x0b, + RTW89_TX_QSEL_BE_3 = 0x0c, + RTW89_TX_QSEL_BK_3 = 0x0d, + RTW89_TX_QSEL_VI_3 = 0x0e, + RTW89_TX_QSEL_VO_3 = 0x0f, + RTW89_TX_QSEL_B0_BCN = 0x10, + RTW89_TX_QSEL_B0_HI = 0x11, + RTW89_TX_QSEL_B0_MGMT = 0x12, + RTW89_TX_QSEL_B0_NOPS = 0x13, + RTW89_TX_QSEL_B0_MGMT_FAST = 0x14, + /* reserved */ + /* reserved */ + /* reserved */ + RTW89_TX_QSEL_B1_BCN = 0x18, + RTW89_TX_QSEL_B1_HI = 0x19, + RTW89_TX_QSEL_B1_MGMT = 0x1a, + RTW89_TX_QSEL_B1_NOPS = 0x1b, + RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c, + /* reserved */ + /* reserved */ + /* reserved */ +}; + +static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid) +{ + switch (tid) { + default: + rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); + fallthrough; + case 0: + case 3: + return RTW89_TX_QSEL_BE_0; + case 1: + case 2: + return RTW89_TX_QSEL_BK_0; + case 4: + case 5: + return RTW89_TX_QSEL_VI_0; + case 6: + case 7: + return RTW89_TX_QSEL_VO_0; + } +} + +static inline u8 +rtw89_core_get_qsel_mgmt(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + + if (desc_info->hiq) { + if (rtwvif_link->mac_idx == RTW89_MAC_1) + return RTW89_TX_QSEL_B1_HI; + else + return RTW89_TX_QSEL_B0_HI; + } + + if (rtwvif_link->mac_idx == RTW89_MAC_1) + return RTW89_TX_QSEL_B1_MGMT; + else + return RTW89_TX_QSEL_B0_MGMT; +} + +static inline u8 rtw89_core_get_tid_indicate(struct rtw89_dev *rtwdev, u8 tid) +{ + switch (tid) { + case 3: + case 2: + case 5: + case 7: + return 1; + default: + rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); + fallthrough; + case 0: + case 1: + case 4: + case 6: + return 0; + } +} + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c new file mode 100644 index 000000000..aafa8b9e9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -0,0 +1,1324 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include "debug.h" +#include "mac.h" +#include "reg.h" +#include "txrx.h" +#include "usb.h" + +static void rtw89_usb_read_port_complete(struct urb *urb); + +static void __rtw89_usb_vendorreq(struct rtw89_dev *rtwdev, u32 addr, + void *data, u16 len, u8 reqtype, bool warn) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + unsigned int pipe; + u16 value, index; + int attempt, ret; + + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + return; + + value = u32_get_bits(addr, GENMASK(15, 0)); + index = u32_get_bits(addr, GENMASK(23, 16)); + + for (attempt = 0; attempt < 10; attempt++) { + *rtwusb->vendor_req_buf = 0; + + if (reqtype == RTW89_USB_VENQT_READ) { + pipe = usb_rcvctrlpipe(udev, 0); + } else { /* RTW89_USB_VENQT_WRITE */ + pipe = usb_sndctrlpipe(udev, 0); + + memcpy(rtwusb->vendor_req_buf, data, len); + } + + ret = usb_control_msg(udev, pipe, RTW89_USB_VENQT, reqtype, + value, index, rtwusb->vendor_req_buf, + len, 500); + + if (ret == len) { /* Success */ + atomic_set(&rtwusb->continual_io_error, 0); + + if (reqtype == RTW89_USB_VENQT_READ) + memcpy(data, rtwusb->vendor_req_buf, len); + + break; + } + + if (ret == -ESHUTDOWN || ret == -ENODEV) + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + else if (ret < 0 && warn) + rtw89_warn(rtwdev, + "usb %s%u 0x%x fail ret=%d value=0x%x attempt=%d\n", + str_read_write(reqtype == RTW89_USB_VENQT_READ), + len * 8, addr, ret, + le32_to_cpup(rtwusb->vendor_req_buf), + attempt); + else if (ret > 0 && reqtype == RTW89_USB_VENQT_READ) + memcpy(data, rtwusb->vendor_req_buf, len); + + if (atomic_inc_return(&rtwusb->continual_io_error) > 4) { + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + break; + } + } +} + +static void rtw89_usb_vendorreq(struct rtw89_dev *rtwdev, u32 addr, + void *data, u16 len, u8 reqtype) +{ + __rtw89_usb_vendorreq(rtwdev, addr, data, len, reqtype, true); +} + +static u32 rtw89_usb_read_cmac(struct rtw89_dev *rtwdev, u32 addr) +{ + u32 addr32, val32, shift; + __le32 data = 0; + int count; + + addr32 = addr & ~0x3; + shift = (addr & 0x3) * 8; + + for (count = 0; ; count++) { + rtw89_usb_vendorreq(rtwdev, addr32, &data, 4, + RTW89_USB_VENQT_READ); + + val32 = le32_to_cpu(data); + if (val32 != RTW89_R32_DEAD) + break; + + if (count >= MAC_REG_POOL_COUNT) { + rtw89_warn(rtwdev, "%s: addr %#x = %#x\n", + __func__, addr32, val32); + val32 = RTW89_R32_DEAD; + break; + } + + rtw89_write32(rtwdev, R_AX_CK_EN, B_AX_CMAC_ALLCKEN); + } + + return val32 >> shift; +} + +static u8 rtw89_usb_ops_read8(struct rtw89_dev *rtwdev, u32 addr) +{ + u8 data = 0; + + if (ACCESS_CMAC(addr)) + return rtw89_usb_read_cmac(rtwdev, addr); + + rtw89_usb_vendorreq(rtwdev, addr, &data, 1, RTW89_USB_VENQT_READ); + + return data; +} + +static u16 rtw89_usb_ops_read16(struct rtw89_dev *rtwdev, u32 addr) +{ + __le16 data = 0; + + if (ACCESS_CMAC(addr)) + return rtw89_usb_read_cmac(rtwdev, addr); + + rtw89_usb_vendorreq(rtwdev, addr, &data, 2, RTW89_USB_VENQT_READ); + + return le16_to_cpu(data); +} + +static u32 rtw89_usb_ops_read32(struct rtw89_dev *rtwdev, u32 addr) +{ + __le32 data = 0; + + if (ACCESS_CMAC(addr)) + return rtw89_usb_read_cmac(rtwdev, addr); + + rtw89_usb_vendorreq(rtwdev, addr, &data, 4, + RTW89_USB_VENQT_READ); + + return le32_to_cpu(data); +} + +static void rtw89_usb_ops_write8(struct rtw89_dev *rtwdev, u32 addr, u8 val) +{ + u8 data = val; + + rtw89_usb_vendorreq(rtwdev, addr, &data, 1, RTW89_USB_VENQT_WRITE); +} + +static void rtw89_usb_ops_write16(struct rtw89_dev *rtwdev, u32 addr, u16 val) +{ + __le16 data = cpu_to_le16(val); + + rtw89_usb_vendorreq(rtwdev, addr, &data, 2, RTW89_USB_VENQT_WRITE); +} + +static void rtw89_usb_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 val) +{ + __le32 data = cpu_to_le32(val); + + rtw89_usb_vendorreq(rtwdev, addr, &data, 4, RTW89_USB_VENQT_WRITE); +} + +static void rtw89_usb_write32_quiet(struct rtw89_dev *rtwdev, u32 addr, u32 val) +{ + __le32 data = cpu_to_le32(val); + + __rtw89_usb_vendorreq(rtwdev, addr, &data, 4, + RTW89_USB_VENQT_WRITE, false); +} + +static u32 +rtw89_usb_ops_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, + u8 txch) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + int inflight; + + if (txch == RTW89_TXCH_CH12) + return 1; + + inflight = atomic_read(&rtwusb->tx_inflight[txch]); + if (inflight >= RTW89_USB_MAX_TX_URBS_PER_CH) + return 0; + + return RTW89_USB_MAX_TX_URBS_PER_CH - inflight; +} + +static void rtw89_usb_write_port_complete(struct urb *urb) +{ + struct rtw89_usb_tx_ctrl_block *txcb = urb->context; + struct rtw89_dev *rtwdev = txcb->rtwdev; + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct ieee80211_tx_info *info; + struct rtw89_txwd_body *txdesc; + struct sk_buff *skb; + u32 txdesc_size; + + while (true) { + skb = skb_dequeue(&txcb->tx_ack_queue); + if (!skb) + break; + + if (txcb->txch == RTW89_TXCH_CH12) { + dev_kfree_skb_any(skb); + continue; + } + + txdesc = (struct rtw89_txwd_body *)skb->data; + + txdesc_size = rtwdev->chip->txwd_body_size; + if (le32_get_bits(txdesc->dword0, RTW89_TXWD_BODY0_WD_INFO_EN)) + txdesc_size += rtwdev->chip->txwd_info_size; + + skb_pull(skb, txdesc_size); + + if (rtw89_is_tx_rpt_skb(rtwdev, skb)) { + if (urb->status == 0) + rtw89_tx_rpt_skb_add(rtwdev, skb); + else + rtw89_tx_rpt_tx_status(rtwdev, skb, + RTW89_TX_MACID_DROP); + continue; + } + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (urb->status == 0) { + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + else + info->flags |= IEEE80211_TX_STAT_ACK; + } + + ieee80211_tx_status_irqsafe(rtwdev->hw, skb); + } + + switch (urb->status) { + case 0: + case -EPIPE: + case -EPROTO: + case -EINPROGRESS: + case -ENOENT: + case -ECONNRESET: + break; + default: + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + break; + } + + atomic_dec(&rtwusb->tx_inflight[txcb->txch]); + + kfree(txcb); +} + +static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma, + void *data, int len, void *context) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + const struct rtw89_usb_info *info = rtwusb->info; + struct usb_device *usbd = rtwusb->udev; + struct urb *urb; + u8 bulkout_id = info->bulkout_id[ch_dma]; + unsigned int pipe; + int ret; + + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) + return -ENODEV; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + pipe = usb_sndbulkpipe(usbd, rtwusb->out_pipe[bulkout_id]); + + usb_fill_bulk_urb(urb, usbd, pipe, data, len, + rtw89_usb_write_port_complete, context); + urb->transfer_flags |= URB_ZERO_PACKET; + usb_anchor_urb(urb, &rtwusb->tx_submitted); + + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + usb_unanchor_urb(urb); + + /* release our reference to this URB, USB core will eventually free it + * on its own after the completion callback finishes (or URB is + * immediately freed here if its submission has failed) + */ + usb_free_urb(urb); + + if (ret == -ENODEV) + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + + return ret; +} + +static void rtw89_usb_tx_free_skb(struct rtw89_dev *rtwdev, u8 txch, + struct sk_buff *skb) +{ + if (txch == RTW89_TXCH_CH12) + dev_kfree_skb_any(skb); + else + ieee80211_free_txskb(rtwdev->hw, skb); +} + +static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct rtw89_usb_tx_ctrl_block *txcb; + struct sk_buff *skb; + int ret; + + while (true) { + skb = skb_dequeue(&rtwusb->tx_queue[txch]); + if (!skb) + break; + + txcb = kmalloc_obj(*txcb, GFP_ATOMIC); + if (!txcb) { + rtw89_usb_tx_free_skb(rtwdev, txch, skb); + continue; + } + + txcb->rtwdev = rtwdev; + txcb->txch = txch; + skb_queue_head_init(&txcb->tx_ack_queue); + + skb_queue_tail(&txcb->tx_ack_queue, skb); + + atomic_inc(&rtwusb->tx_inflight[txch]); + + ret = rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len, + txcb); + if (ret) { + atomic_dec(&rtwusb->tx_inflight[txch]); + + if (ret != -ENODEV) + rtw89_err(rtwdev, "write port txch %d failed: %d\n", + txch, ret); + + skb_dequeue(&txcb->tx_ack_queue); + kfree(txcb); + rtw89_usb_tx_free_skb(rtwdev, txch, skb); + } + } +} + +static int rtw89_usb_tx_write_fwcmd(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct sk_buff *skb = tx_req->skb; + struct sk_buff *skb512; + u32 txdesc_size = rtwdev->chip->h2c_desc_size; + void *txdesc; + + if (((desc_info->pkt_size + txdesc_size) % 512) == 0) { + rtw89_debug(rtwdev, RTW89_DBG_HCI, "avoiding multiple of 512\n"); + + skb512 = dev_alloc_skb(txdesc_size + desc_info->pkt_size + + RTW89_USB_MOD512_PADDING); + if (!skb512) { + rtw89_err(rtwdev, "%s: failed to allocate skb\n", + __func__); + + return -ENOMEM; + } + + skb_pull(skb512, txdesc_size); + skb_put_data(skb512, skb->data, skb->len); + skb_put_zero(skb512, RTW89_USB_MOD512_PADDING); + + dev_kfree_skb_any(skb); + skb = skb512; + tx_req->skb = skb512; + + desc_info->pkt_size += RTW89_USB_MOD512_PADDING; + } + + txdesc = skb_push(skb, txdesc_size); + memset(txdesc, 0, txdesc_size); + rtw89_chip_fill_txdesc_fwcmd(rtwdev, desc_info, txdesc); + + skb_queue_tail(&rtwusb->tx_queue[desc_info->ch_dma], skb); + + return 0; +} + +static int rtw89_usb_ops_tx_write(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct rtw89_tx_skb_data *skb_data; + struct sk_buff *skb = tx_req->skb; + struct rtw89_txwd_body *txdesc; + u32 txdesc_size; + + if ((desc_info->ch_dma == RTW89_TXCH_CH12 || + tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD) && + (desc_info->ch_dma != RTW89_TXCH_CH12 || + tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD)) { + rtw89_err(rtwdev, "dma channel %d/TX type %d mismatch\n", + desc_info->ch_dma, tx_req->tx_type); + return -EINVAL; + } + + if (desc_info->ch_dma == RTW89_TXCH_CH12) + return rtw89_usb_tx_write_fwcmd(rtwdev, tx_req); + + txdesc_size = rtwdev->chip->txwd_body_size; + if (desc_info->en_wd_info) + txdesc_size += rtwdev->chip->txwd_info_size; + + txdesc = skb_push(skb, txdesc_size); + memset(txdesc, 0, txdesc_size); + rtw89_chip_fill_txdesc(rtwdev, desc_info, txdesc); + + le32p_replace_bits(&txdesc->dword0, 1, RTW89_TXWD_BODY0_STF_MODE); + + skb_data = RTW89_TX_SKB_CB(skb); + if (tx_req->desc_info.sn) + skb_data->tx_rpt_sn = tx_req->desc_info.sn; + if (tx_req->desc_info.tx_cnt_lmt) + skb_data->tx_pkt_cnt_lmt = tx_req->desc_info.tx_cnt_lmt; + + skb_queue_tail(&rtwusb->tx_queue[desc_info->ch_dma], skb); + + return 0; +} + +static void rtw89_usb_rx_handler(struct work_struct *work) +{ + struct rtw89_usb *rtwusb = container_of(work, struct rtw89_usb, rx_work); + const struct rtw89_usb_info *info = rtwusb->info; + struct rtw89_dev *rtwdev = rtwusb->rtwdev; + struct rtw89_rx_desc_info desc_info; + s32 aligned_offset, remaining; + struct sk_buff *rx_skb; + struct sk_buff *skb; + u32 pkt_offset; + u8 *pkt_ptr; + int limit; + + for (limit = 0; limit < 200; limit++) { + rx_skb = skb_dequeue(&rtwusb->rx_queue); + if (!rx_skb) + break; + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW89_USB_MAX_RXQ_LEN) { + rtw89_warn(rtwdev, "rx_queue overflow\n"); + goto free_or_reuse; + } + + pkt_ptr = rx_skb->data; + remaining = rx_skb->len; + + do { + memset(&desc_info, 0, sizeof(desc_info)); + rtw89_chip_query_rxdesc(rtwdev, &desc_info, pkt_ptr, 0); + + pkt_offset = desc_info.offset + desc_info.rxd_len; + if (remaining < (pkt_offset + desc_info.pkt_size)) { + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "Failed to get remaining RX pkt %u > %u\n", + pkt_offset + desc_info.pkt_size, remaining); + goto free_or_reuse; + } + + skb = rtw89_alloc_skb_for_rx(rtwdev, desc_info.pkt_size); + if (!skb) { + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "failed to allocate RX skb of size %u\n", + desc_info.pkt_size); + goto free_or_reuse; + } + + skb_put_data(skb, pkt_ptr + pkt_offset, desc_info.pkt_size); + rtw89_core_rx(rtwdev, &desc_info, skb); + + /* next frame */ + pkt_offset += desc_info.pkt_size; + aligned_offset = ALIGN(pkt_offset, info->rx_agg_alignment); + pkt_ptr += aligned_offset; + remaining -= aligned_offset; + } while (remaining > 0); + +free_or_reuse: + if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM) + dev_kfree_skb_any(rx_skb); + else + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } + + if (limit == 200) { + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "left %d rx skbs in the queue for later\n", + skb_queue_len(&rtwusb->rx_queue)); + queue_work(rtwusb->rxwq, &rtwusb->rx_work); + } +} + +static void rtw89_usb_rx_resubmit(struct rtw89_usb *rtwusb, + struct rtw89_usb_rx_ctrl_block *rxcb, + gfp_t gfp) +{ + struct rtw89_dev *rtwdev = rtwusb->rtwdev; + struct sk_buff *rx_skb; + int ret; + + rx_skb = skb_dequeue(&rtwusb->rx_free_queue); + if (!rx_skb) + rx_skb = alloc_skb(RTW89_USB_RECVBUF_SZ, gfp); + + if (!rx_skb) + goto try_later; + + skb_reset_tail_pointer(rx_skb); + rx_skb->len = 0; + + rxcb->rx_skb = rx_skb; + + usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, + usb_rcvbulkpipe(rtwusb->udev, rtwusb->in_pipe[0]), + rxcb->rx_skb->data, RTW89_USB_RECVBUF_SZ, + rtw89_usb_read_port_complete, rxcb); + + ret = usb_submit_urb(rxcb->rx_urb, gfp); + if (ret) { + skb_queue_tail(&rtwusb->rx_free_queue, rxcb->rx_skb); + + if (ret == -ENODEV) + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + else + rtw89_err(rtwdev, "Err sending rx data urb %d\n", ret); + + if (ret == -ENOMEM) + goto try_later; + } + + return; + +try_later: + rxcb->rx_skb = NULL; + queue_work(rtwusb->rxwq, &rtwusb->rx_urb_work); +} + +static void rtw89_usb_rx_resubmit_work(struct work_struct *work) +{ + struct rtw89_usb *rtwusb = container_of(work, struct rtw89_usb, rx_urb_work); + struct rtw89_usb_rx_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW89_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + + if (!rxcb->rx_skb) + rtw89_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); + } +} + +static void rtw89_usb_read_port_complete(struct urb *urb) +{ + struct rtw89_usb_rx_ctrl_block *rxcb = urb->context; + struct rtw89_dev *rtwdev = rxcb->rtwdev; + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct sk_buff *skb = rxcb->rx_skb; + + if (urb->status == 0) { + if (urb->actual_length > urb->transfer_buffer_length || + urb->actual_length < sizeof(struct rtw89_rxdesc_short)) { + rtw89_err(rtwdev, "failed to get urb length: %d\n", + urb->actual_length); + skb_queue_tail(&rtwusb->rx_free_queue, skb); + } else { + skb_put(skb, urb->actual_length); + skb_queue_tail(&rtwusb->rx_queue, skb); + queue_work(rtwusb->rxwq, &rtwusb->rx_work); + } + + rtw89_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); + } else { + skb_queue_tail(&rtwusb->rx_free_queue, skb); + + if (atomic_inc_return(&rtwusb->continual_io_error) > 4) + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + + switch (urb->status) { + case -EINVAL: + case -EPIPE: + case -ENODEV: + case -ESHUTDOWN: + set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); + break; + case -EPROTO: + case -EILSEQ: + case -ETIME: + case -ECOMM: + case -EOVERFLOW: + case -ENOENT: + break; + case -EINPROGRESS: + rtw89_info(rtwdev, "URB is in progress\n"); + break; + default: + rtw89_err(rtwdev, "%s status %d\n", + __func__, urb->status); + break; + } + } +} + +static void rtw89_usb_cancel_rx_bufs(struct rtw89_usb *rtwusb) +{ + struct rtw89_usb_rx_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW89_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + usb_kill_urb(rxcb->rx_urb); + } +} + +static void rtw89_usb_cancel_tx_bufs(struct rtw89_usb *rtwusb) +{ + usb_kill_anchored_urbs(&rtwusb->tx_submitted); +} + +static void rtw89_usb_free_rx_bufs(struct rtw89_usb *rtwusb) +{ + struct rtw89_usb_rx_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW89_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + usb_free_urb(rxcb->rx_urb); + } +} + +static int rtw89_usb_alloc_rx_bufs(struct rtw89_usb *rtwusb) +{ + struct rtw89_usb_rx_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW89_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + + rxcb->rtwdev = rtwusb->rtwdev; + rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rxcb->rx_urb) { + rtw89_usb_free_rx_bufs(rtwusb); + return -ENOMEM; + } + } + + return 0; +} + +static int rtw89_usb_init_rx(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct sk_buff *rx_skb; + int i; + + rtwusb->rxwq = alloc_workqueue("rtw89_usb: rx wq", WQ_BH | WQ_PERCPU, 0); + if (!rtwusb->rxwq) { + rtw89_err(rtwdev, "failed to create RX work queue\n"); + return -ENOMEM; + } + + skb_queue_head_init(&rtwusb->rx_queue); + skb_queue_head_init(&rtwusb->rx_free_queue); + + INIT_WORK(&rtwusb->rx_work, rtw89_usb_rx_handler); + INIT_WORK(&rtwusb->rx_urb_work, rtw89_usb_rx_resubmit_work); + + for (i = 0; i < RTW89_USB_RX_SKB_NUM; i++) { + rx_skb = alloc_skb(RTW89_USB_RECVBUF_SZ, GFP_KERNEL); + if (rx_skb) + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } + + return 0; +} + +static void rtw89_usb_deinit_rx(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + + skb_queue_purge(&rtwusb->rx_queue); + + destroy_workqueue(rtwusb->rxwq); + + skb_queue_purge(&rtwusb->rx_free_queue); +} + +static void rtw89_usb_start_rx(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + int i; + + for (i = 0; i < RTW89_USB_RXCB_NUM; i++) + rtw89_usb_rx_resubmit(rtwusb, &rtwusb->rx_cb[i], GFP_KERNEL); +} + +static void rtw89_usb_init_tx(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + int i; + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) { + skb_queue_head_init(&rtwusb->tx_queue[i]); + atomic_set(&rtwusb->tx_inflight[i], 0); + } +} + +static void rtw89_usb_deinit_tx(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + int i; + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) { + if (i == RTW89_TXCH_CH12) + skb_queue_purge(&rtwusb->tx_queue[i]); + else + ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]); + } +} + +static void rtw89_usb_ops_reset(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + + rtw89_usb_cancel_tx_bufs(rtwusb); + rtw89_tx_rpt_skbs_purge(rtwdev); +} + +static int rtw89_usb_ops_start(struct rtw89_dev *rtwdev) +{ + return 0; /* Nothing to do. */ +} + +static void rtw89_usb_ops_stop(struct rtw89_dev *rtwdev) +{ + /* Nothing to do. */ +} + +static void rtw89_usb_ops_pause(struct rtw89_dev *rtwdev, bool pause) +{ + /* Nothing to do? */ +} + +static void rtw89_usb_ops_switch_mode(struct rtw89_dev *rtwdev, bool low_power) +{ + /* Nothing to do. */ +} + +static int rtw89_usb_ops_deinit(struct rtw89_dev *rtwdev) +{ + return 0; /* Nothing to do. */ +} + +static int rtw89_usb_ops_mac_pre_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + const struct rtw89_usb_info *info = rtwusb->info; + u32 val32; + + if (rtwdev->chip->chip_id == RTL8922A) + return 0; + + rtw89_write32_set(rtwdev, info->usb_host_request_2, + B_AX_R_USBIO_MODE); + + /* fix USB IO hang suggest by chihhanli@realtek.com */ + rtw89_write32_clr(rtwdev, info->usb_wlan0_1, + B_AX_USBRX_RST | B_AX_USBTX_RST); + + val32 = rtw89_read32(rtwdev, info->hci_func_en); + val32 &= ~(B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN); + rtw89_write32(rtwdev, info->hci_func_en, val32); + + val32 |= B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN; + rtw89_write32(rtwdev, info->hci_func_en, val32); + /* fix USB TRX hang suggest by chihhanli@realtek.com */ + + return 0; +} + +static int rtw89_usb_ops_mac_pre_deinit(struct rtw89_dev *rtwdev) +{ + return 0; /* Nothing to do. */ +} + +static void rtw89_usb_rx_agg_cfg_v1(struct rtw89_dev *rtwdev) +{ + const u32 rxagg_0 = FIELD_PREP_CONST(B_AX_RXAGG_0_EN, 1) | + FIELD_PREP_CONST(B_AX_RXAGG_0_NUM_TH, 0) | + FIELD_PREP_CONST(B_AX_RXAGG_0_TIME_32US_TH, 32) | + FIELD_PREP_CONST(B_AX_RXAGG_0_BUF_SZ_4K, 5); + + rtw89_write32(rtwdev, R_AX_RXAGG_0, rxagg_0); +} + +static void rtw89_usb_rx_agg_cfg_v2(struct rtw89_dev *rtwdev) +{ + const u32 rxagg_0 = FIELD_PREP_CONST(B_AX_RXAGG_0_EN, 1) | + FIELD_PREP_CONST(B_AX_RXAGG_0_NUM_TH, 255) | + FIELD_PREP_CONST(B_AX_RXAGG_0_TIME_32US_TH, 32) | + FIELD_PREP_CONST(B_AX_RXAGG_0_BUF_SZ_1K, 20); + + rtw89_write32(rtwdev, R_AX_RXAGG_0_V1, rxagg_0); + rtw89_write32(rtwdev, R_AX_RXAGG_1_V1, 0x1F); +} + +static void rtw89_usb_rx_agg_cfg_v3(struct rtw89_dev *rtwdev) +{ + const u32 rxagg_0 = FIELD_PREP_CONST(B_BE_RXAGG_0_EN, 1) | + FIELD_PREP_CONST(B_BE_RXAGG_0_NUM_TH, 255) | + FIELD_PREP_CONST(B_BE_RXAGG_0_TIME_32US_TH, 32) | + FIELD_PREP_CONST(B_BE_RXAGG_0_BUF_SZ_1K, 20); + + rtw89_write32(rtwdev, R_BE_RXAGG_0_V1, rxagg_0); + rtw89_write32(rtwdev, R_BE_RXAGG_1_V1, 0x1F); +} + +static void rtw89_usb_rx_agg_cfg(struct rtw89_dev *rtwdev) +{ + switch (rtwdev->chip->chip_id) { + case RTL8851B: + case RTL8852A: + case RTL8852B: + rtw89_usb_rx_agg_cfg_v1(rtwdev); + break; + case RTL8852C: + rtw89_usb_rx_agg_cfg_v2(rtwdev); + break; + case RTL8922A: + rtw89_usb_rx_agg_cfg_v3(rtwdev); + break; + default: + rtw89_warn(rtwdev, "%s: USB RX agg not support\n", __func__); + return; + } +} + +static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + const struct rtw89_usb_info *info = rtwusb->info; + enum usb_device_speed speed; + u32 ep; + + if (rtwdev->chip->chip_id == RTL8922A) + goto rx_agg_cfg; + + rtw89_write32_clr(rtwdev, info->usb3_mac_npi_config_intf_0, + B_AX_SSPHY_LFPS_FILTER); + + speed = rtwusb->udev->speed; + + if (speed == USB_SPEED_SUPER) + rtw89_write8(rtwdev, R_AX_RXDMA_SETTING, USB3_BULKSIZE); + else if (speed == USB_SPEED_HIGH) + rtw89_write8(rtwdev, R_AX_RXDMA_SETTING, USB2_BULKSIZE); + else + rtw89_write8(rtwdev, R_AX_RXDMA_SETTING, USB11_BULKSIZE); + + for (ep = 5; ep <= 12; ep++) { + if (ep == 8) + continue; + + rtw89_write8_mask(rtwdev, info->usb_endpoint_0, + B_AX_EP_IDX, ep); + rtw89_write8(rtwdev, info->usb_endpoint_2 + 1, NUMP); + } + +rx_agg_cfg: + rtw89_usb_rx_agg_cfg(rtwdev); + + return 0; +} + +static void rtw89_usb_ops_recalc_int_mit(struct rtw89_dev *rtwdev) +{ + /* Nothing to do. */ +} + +static int rtw89_usb_ops_mac_lv1_rcvy(struct rtw89_dev *rtwdev, + enum rtw89_lv1_rcvy_step step) +{ + u32 reg, mask; + + switch (rtwdev->chip->chip_id) { + case RTL8851B: + case RTL8852A: + case RTL8852B: + reg = R_AX_USB_WLAN0_1; + mask = B_AX_USBRX_RST | B_AX_USBTX_RST; + break; + case RTL8852C: + reg = R_AX_USB_WLAN0_1_V1; + mask = B_AX_USBRX_RST_V1 | B_AX_USBTX_RST_V1; + break; + case RTL8922A: + reg = R_BE_USB2_WLAN_TRX_OPT_PAR2; + mask = B_BE_USB2_USBRX_RST | B_BE_USB2_USBTX_RST; + break; + default: + rtw89_err(rtwdev, "%s: fix me\n", __func__); + return -EOPNOTSUPP; + } + + switch (step) { + case RTW89_LV1_RCVY_STEP_1: + rtw89_write32_set(rtwdev, reg, mask); + + msleep(30); + break; + case RTW89_LV1_RCVY_STEP_2: + rtw89_write32_clr(rtwdev, reg, mask); + break; + default: + return -EINVAL; + } + + return 0; +} + +static void rtw89_usb_ops_dump_err_status(struct rtw89_dev *rtwdev) +{ + rtw89_warn(rtwdev, "%s TODO\n", __func__); +} + +static const struct rtw89_hci_ops rtw89_usb_ops = { + .tx_write = rtw89_usb_ops_tx_write, + .tx_kick_off = rtw89_usb_ops_tx_kick_off, + .flush_queues = NULL, /* Not needed? */ + .reset = rtw89_usb_ops_reset, + .start = rtw89_usb_ops_start, + .stop = rtw89_usb_ops_stop, + .pause = rtw89_usb_ops_pause, + .switch_mode = rtw89_usb_ops_switch_mode, + .recalc_int_mit = rtw89_usb_ops_recalc_int_mit, + + .read8 = rtw89_usb_ops_read8, + .read16 = rtw89_usb_ops_read16, + .read32 = rtw89_usb_ops_read32, + .write8 = rtw89_usb_ops_write8, + .write16 = rtw89_usb_ops_write16, + .write32 = rtw89_usb_ops_write32, + + .mac_pre_init = rtw89_usb_ops_mac_pre_init, + .mac_pre_deinit = rtw89_usb_ops_mac_pre_deinit, + .mac_post_init = rtw89_usb_ops_mac_post_init, + .deinit = rtw89_usb_ops_deinit, + + .check_and_reclaim_tx_resource = rtw89_usb_ops_check_and_reclaim_tx_resource, + .mac_lv1_rcvy = rtw89_usb_ops_mac_lv1_rcvy, + .dump_err_status = rtw89_usb_ops_dump_err_status, + .napi_poll = NULL, + + .recovery_start = NULL, + .recovery_complete = NULL, + + .ctrl_txdma_ch = NULL, + .ctrl_txdma_fw_ch = NULL, + .ctrl_trxhci = NULL, + .poll_txdma_ch_idle = NULL, + + .clr_idx_all = NULL, + .clear = NULL, + .disable_intr = NULL, + .enable_intr = NULL, + .rst_bdram = NULL, +}; + +static int rtw89_usb_parse(struct rtw89_dev *rtwdev, + struct usb_interface *intf) +{ + struct usb_host_interface *host_interface = &intf->altsetting[0]; + struct usb_interface_descriptor *intf_desc = &host_interface->desc; + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + struct usb_endpoint_descriptor *endpoint; + int num_out_pipes = 0; + int num_in_pipes = 0; + u8 num; + int i; + + if (intf_desc->bNumEndpoints > RTW89_MAX_ENDPOINT_NUM) { + rtw89_err(rtwdev, "found %d endpoints, expected %d max\n", + intf_desc->bNumEndpoints, RTW89_MAX_ENDPOINT_NUM); + return -EINVAL; + } + + for (i = 0; i < intf_desc->bNumEndpoints; i++) { + endpoint = &host_interface->endpoint[i].desc; + num = usb_endpoint_num(endpoint); + + if (usb_endpoint_dir_in(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (num_in_pipes >= RTW89_MAX_BULKIN_NUM) { + rtw89_err(rtwdev, + "found more than %d bulk in endpoint\n", + RTW89_MAX_BULKIN_NUM); + return -EINVAL; + } + + rtwusb->in_pipe[num_in_pipes++] = num; + } + + if (usb_endpoint_dir_out(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + if (num_out_pipes >= RTW89_MAX_BULKOUT_NUM) { + rtw89_err(rtwdev, + "found more than %d bulk out endpoints\n", + RTW89_MAX_BULKOUT_NUM); + return -EINVAL; + } + + rtwusb->out_pipe[num_out_pipes++] = num; + } + } + + if (num_in_pipes < 1) { + rtw89_err(rtwdev, "no bulk in endpoints found\n"); + return -EINVAL; + } + + if (num_out_pipes < 1) { + rtw89_err(rtwdev, "no bulk out endpoints found\n"); + return -EINVAL; + } + + return 0; +} + +static int rtw89_usb_intf_init(struct rtw89_dev *rtwdev, + struct usb_interface *intf) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + int ret; + + init_usb_anchor(&rtwusb->tx_submitted); + + ret = rtw89_usb_parse(rtwdev, intf); + if (ret) + return ret; + + rtwusb->vendor_req_buf = kmalloc_obj(*rtwusb->vendor_req_buf); + if (!rtwusb->vendor_req_buf) + return -ENOMEM; + + rtwusb->udev = interface_to_usbdev(intf); + + usb_set_intfdata(intf, rtwdev->hw); + + SET_IEEE80211_DEV(rtwdev->hw, &intf->dev); + + return 0; +} + +static void rtw89_usb_intf_deinit(struct rtw89_dev *rtwdev, + struct usb_interface *intf) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + + kfree(rtwusb->vendor_req_buf); + usb_set_intfdata(intf, NULL); +} + +static int rtw89_usb_switch_mode_ax(struct rtw89_dev *rtwdev) +{ + u32 pad_ctrl2; + + /* No known USB 3 devices with this chip. */ + if (rtwdev->chip->chip_id == RTL8851B) + return 0; + + pad_ctrl2 = rtw89_usb_ops_read32(rtwdev, R_AX_PAD_CTRL2); + + rtw89_debug(rtwdev, RTW89_DBG_HCI, "%s: pad_ctrl2: %#x\n", + __func__, pad_ctrl2); + + /* Already tried to switch but it's a USB 2 port. */ + if (u32_get_bits(pad_ctrl2, B_AX_MATCH_CNT) == USB_SWITCH_DELAY) + return 0; + + /* Add delay to prevent some platforms would not detect USB switch */ + u32p_replace_bits(&pad_ctrl2, USB_SWITCH_DELAY, B_AX_MATCH_CNT); + + pad_ctrl2 &= ~(B_AX_FORCE_U3_CK | B_AX_USB2_FORCE | + B_AX_USB3_FORCE | B_AX_USB3_USB2_TRANSITION); + + u32p_replace_bits(&pad_ctrl2, USB_MODE_U3, B_AX_USB23_SW_MODE_V1); + + pad_ctrl2 |= B_AX_NO_PDN_CHIPOFF_V1 | B_AX_RSM_EN_V1; + + rtw89_usb_write32_quiet(rtwdev, R_AX_PAD_CTRL2, pad_ctrl2); + + return 1; +} + +static int rtw89_usb_switch_mode_be(struct rtw89_dev *rtwdev) +{ + u32 pad_ctrl2; + + pad_ctrl2 = rtw89_usb_ops_read32(rtwdev, R_BE_PAD_CTRL2); + + rtw89_debug(rtwdev, RTW89_DBG_HCI, "%s: pad_ctrl2: %#x\n", + __func__, pad_ctrl2); + + /* Already tried to switch but it's a USB 2 port. */ + if (u32_get_bits(pad_ctrl2, B_BE_MATCH_CNT) == USB_SWITCH_DELAY) + return 0; + + /* Add delay to prevent some platforms would not detect USB switch */ + u32p_replace_bits(&pad_ctrl2, USB_SWITCH_DELAY, B_BE_MATCH_CNT); + + pad_ctrl2 |= B_BE_RSM_EN_V1 | B_BE_NO_PDN_CHIPOFF_V1 | + B_BE_USB_AUTO_INSTALL_MASK | B_BE_USB23_SW_MODE; + + pad_ctrl2 &= ~(B_BE_USB3_FORCE | B_BE_USB2_FORCE | + B_BE_FORCE_U3_CK | B_BE_FORCE_U2_CK | + B_BE_FORCE_CLK_U2 | B_BE_USB3_GEN_MODE | + B_BE_USB3_LANE_MODE); + + rtw89_usb_write32_quiet(rtwdev, R_BE_PAD_CTRL2, pad_ctrl2); + + return 1; +} + +static int rtw89_usb_switch_mode(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); + + if (rtwusb->udev->speed == USB_SPEED_SUPER) { + rtw89_info(rtwdev, + "2.4 GHz performance may be better in a USB 2 port\n"); + return 0; + } + + if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) + return rtw89_usb_switch_mode_ax(rtwdev); + + return rtw89_usb_switch_mode_be(rtwdev); +} + +static ssize_t serial_number_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct wiphy *wiphy = container_of(dev, struct wiphy, dev); + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + return sysfs_emit(buf, "%*phN\n", + (int)sizeof(efuse->sn), efuse->sn); +} +static DEVICE_ATTR_RO(serial_number); + +static ssize_t uuid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct wiphy *wiphy = container_of(dev, struct wiphy, dev); + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_efuse *efuse = &rtwdev->efuse; + + return sysfs_emit(buf, "%pUb\n", efuse->uuid); +} +static DEVICE_ATTR_RO(uuid); + +static struct attribute *rtw89_usb_attrs[] = { + &dev_attr_serial_number.attr, + &dev_attr_uuid.attr, + NULL, +}; + +static bool rtw89_usb_group_visible(struct kobject *kobj) +{ + struct device *dev = kobj_to_dev(kobj); + struct wiphy *wiphy = container_of(dev, struct wiphy, dev); + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw89_dev *rtwdev = hw->priv; + + return test_bit(RTW89_QUIRK_HW_INFO_SYSFS, rtwdev->quirks); +} + +DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(rtw89_usb); + +static const struct attribute_group rtw89_usb_group = { + .name = "rtw89_usb", + .attrs = rtw89_usb_attrs, + .is_visible = SYSFS_GROUP_VISIBLE(rtw89_usb), +}; +__ATTRIBUTE_GROUPS(rtw89_usb); + +int rtw89_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + const struct rtw89_driver_info *info; + struct rtw89_dev *rtwdev; + struct rtw89_usb *rtwusb; + int ret; + + info = (const struct rtw89_driver_info *)id->driver_info; + + rtwdev = rtw89_alloc_ieee80211_hw(&intf->dev, + sizeof(struct rtw89_usb), info); + if (!rtwdev) { + dev_err(&intf->dev, "failed to allocate hw\n"); + return -ENOMEM; + } + + rtwusb = rtw89_usb_priv(rtwdev); + rtwusb->rtwdev = rtwdev; + rtwusb->info = info->bus.usb; + + rtwdev->hw->wiphy->dev.groups = rtw89_usb_groups; + + rtwdev->hci.ops = &rtw89_usb_ops; + rtwdev->hci.type = RTW89_HCI_TYPE_USB; + rtwdev->hci.tx_rpt_enabled = true; + + ret = rtw89_usb_intf_init(rtwdev, intf); + if (ret) { + rtw89_err(rtwdev, "failed to initialise intf: %d\n", ret); + goto err_free_hw; + } + + ret = rtw89_usb_switch_mode(rtwdev); + if (ret) { + /* Not a fail, but we do need to skip rtw89_core_register. */ + ret = 0; + goto err_intf_deinit; + } + + if (rtwusb->udev->speed == USB_SPEED_SUPER) + rtwdev->hci.dle_type = RTW89_HCI_DLE_TYPE_USB3; + else + rtwdev->hci.dle_type = RTW89_HCI_DLE_TYPE_USB2; + + rtw89_usb_init_tx(rtwdev); + + ret = rtw89_usb_alloc_rx_bufs(rtwusb); + if (ret) + goto err_intf_deinit; + + ret = rtw89_usb_init_rx(rtwdev); + if (ret) + goto err_free_rx_bufs; + + ret = rtw89_core_init(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to initialise core: %d\n", ret); + goto err_deinit_rx; + } + + ret = rtw89_chip_info_setup(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to setup chip information\n"); + goto err_core_deinit; + } + + ret = rtw89_core_register(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to register core\n"); + goto err_core_deinit; + } + + rtw89_usb_start_rx(rtwdev); + + set_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags); + + return 0; + +err_core_deinit: + rtw89_core_deinit(rtwdev); +err_deinit_rx: + rtw89_usb_deinit_rx(rtwdev); +err_free_rx_bufs: + rtw89_usb_free_rx_bufs(rtwusb); +err_intf_deinit: + rtw89_usb_intf_deinit(rtwdev, intf); +err_free_hw: + rtw89_free_ieee80211_hw(rtwdev); + + return ret; +} +EXPORT_SYMBOL(rtw89_usb_probe); + +void rtw89_usb_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct rtw89_dev *rtwdev; + struct rtw89_usb *rtwusb; + + if (!hw) + return; + + rtwdev = hw->priv; + rtwusb = rtw89_usb_priv(rtwdev); + + rtw89_usb_cancel_rx_bufs(rtwusb); + rtw89_usb_cancel_tx_bufs(rtwusb); + + rtw89_core_unregister(rtwdev); + rtw89_core_deinit(rtwdev); + rtw89_usb_deinit_rx(rtwdev); + rtw89_usb_free_rx_bufs(rtwusb); + rtw89_usb_deinit_tx(rtwdev); + rtw89_usb_intf_deinit(rtwdev, intf); + rtw89_free_ieee80211_hw(rtwdev); +} +EXPORT_SYMBOL(rtw89_usb_disconnect); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek USB 802.11ax wireless driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw89/usb.h b/drivers/net/wireless/realtek/rtw89/usb.h new file mode 100644 index 000000000..bdf312559 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/usb.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW89_USB_H__ +#define __RTW89_USB_H__ + +#include "txrx.h" + +#define RTW89_USB_VENQT 0x05 +#define RTW89_USB_VENQT_READ 0xc0 +#define RTW89_USB_VENQT_WRITE 0x40 + +#define RTW89_USB_RECVBUF_SZ 20480 +#define RTW89_USB_RXCB_NUM 8 +#define RTW89_USB_RX_SKB_NUM 16 +#define RTW89_USB_MAX_RXQ_LEN 512 +#define RTW89_USB_MOD512_PADDING 4 + +#define RTW89_MAX_ENDPOINT_NUM 9 +#define RTW89_MAX_BULKIN_NUM 2 +#define RTW89_MAX_BULKOUT_NUM 7 + +#define R_AX_RXAGG_0_V1 0x6000 +#define B_AX_RXAGG_0_EN BIT(31) +#define B_AX_RXAGG_0_NUM_TH GENMASK(23, 16) +#define B_AX_RXAGG_0_TIME_32US_TH GENMASK(15, 8) +#define B_AX_RXAGG_0_BUF_SZ_1K GENMASK(7, 0) + +#define R_AX_RXAGG_1_V1 0x6004 + +#define R_BE_RXAGG_0_V1 0x6000 +#define B_BE_RXAGG_0_EN BIT(31) +#define B_BE_RXAGG_0_NUM_TH GENMASK(23, 16) +#define B_BE_RXAGG_0_TIME_32US_TH GENMASK(15, 8) +#define B_BE_RXAGG_0_BUF_SZ_1K GENMASK(7, 0) + +#define R_BE_RXAGG_1_V1 0x6004 + +#define R_AX_RXAGG_0 0x8900 +#define B_AX_RXAGG_0_BUF_SZ_4K GENMASK(7, 0) + +#define RTW89_USB_MAX_TX_URBS_PER_CH 128 + +struct rtw89_usb_info { + u32 usb_host_request_2; + u32 usb_wlan0_1; + u32 hci_func_en; + u32 usb3_mac_npi_config_intf_0; + u32 usb_endpoint_0; + u32 usb_endpoint_2; + u8 rx_agg_alignment; + u8 bulkout_id[RTW89_DMA_CH_NUM]; +}; + +struct rtw89_usb_rx_ctrl_block { + struct rtw89_dev *rtwdev; + struct urb *rx_urb; + struct sk_buff *rx_skb; +}; + +struct rtw89_usb_tx_ctrl_block { + struct rtw89_dev *rtwdev; + u8 txch; + struct sk_buff_head tx_ack_queue; +}; + +struct rtw89_usb { + struct rtw89_dev *rtwdev; + struct usb_device *udev; + const struct rtw89_usb_info *info; + + __le32 *vendor_req_buf; + + atomic_t continual_io_error; + + u8 in_pipe[RTW89_MAX_BULKIN_NUM]; + u8 out_pipe[RTW89_MAX_BULKOUT_NUM]; + + struct workqueue_struct *rxwq; + struct rtw89_usb_rx_ctrl_block rx_cb[RTW89_USB_RXCB_NUM]; + struct sk_buff_head rx_queue; + struct sk_buff_head rx_free_queue; + struct work_struct rx_work; + struct work_struct rx_urb_work; + struct usb_anchor tx_submitted; + + struct sk_buff_head tx_queue[RTW89_TXCH_NUM]; + atomic_t tx_inflight[RTW89_TXCH_NUM]; +}; + +static inline struct rtw89_usb *rtw89_usb_priv(struct rtw89_dev *rtwdev) +{ + return (struct rtw89_usb *)rtwdev->priv; +} + +int rtw89_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id); +void rtw89_usb_disconnect(struct usb_interface *intf); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/util.c b/drivers/net/wireless/realtek/rtw89/util.c new file mode 100644 index 000000000..073714db2 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/util.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "util.h" + +#define RTW89_DBM_QUARTER_FACTOR 2 +#define RTW89_MIN_DBM (-41.25 * (1 << RTW89_DBM_QUARTER_FACTOR)) +#define RTW89_MAX_DBM (96 * (1 << RTW89_DBM_QUARTER_FACTOR)) +#define RTW89_DB_INVERT_TABLE_OFFSET (-RTW89_MIN_DBM) + +static const u64 db_invert_table[] = { + /* in unit of 0.000001 */ + 75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188, + 200, 211, 224, 237, 251, 266, 282, 299, 316, 335, 355, 376, 398, 422, 447, 473, + 501, 531, 562, 596, 631, 668, 708, 750, 794, 841, 891, 944, 1000, 1059, 1122, 1189, + 1259, 1334, 1413, 1496, 1585, 1679, 1778, 1884, 1995, 2113, 2239, 2371, 2512, 2661, + 2818, 2985, 3162, 3350, 3548, 3758, 3981, 4217, 4467, 4732, 5012, 5309, 5623, 5957, + 6310, 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, 10593, 11220, 11885, 12589, + 13335, 14125, 14962, 15849, 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, + 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, 42170, 44668, 47315, 50119, + 53088, 56234, 59566, 63096, 66834, 70795, 74989, 79433, 84140, 89125, 94406, 100000, + 105925, 112202, 118850, 125893, 133352, 141254, 149624, 158489, 167880, 177828, + 188365, 199526, 211349, 223872, 237137, 251189, 266073, 281838, 298538, 316228, + 334965, 354813, 375837, 398107, 421697, 446684, 473151, 501187, 530884, 562341, + 595662, 630957, 668344, 707946, 749894, 794328, 841395, 891251, 944061, 1000000, + 1059254, 1122018, 1188502, 1258925, 1333521, 1412538, 1496236, 1584893, 1678804, + 1778279, 1883649, 1995262, 2113489, 2238721, 2371374, 2511886, 2660725, 2818383, + 2985383, 3162278, 3349654, 3548134, 3758374, 3981072, 4216965, 4466836, 4731513, + 5011872, 5308844, 5623413, 5956621, 6309573, 6683439, 7079458, 7498942, 7943282, + 8413951, 8912509, 9440609, 10000000, 10592537, 11220185, 11885022, 12589254, + 13335214, 14125375, 14962357, 15848932, 16788040, 17782794, 18836491, 19952623, + 21134890, 22387211, 23713737, 25118864, 26607251, 28183829, 29853826, 31622777, + 33496544, 35481339, 37583740, 39810717, 42169650, 44668359, 47315126, 50118723, + 53088444, 56234133, 59566214, 63095734, 66834392, 70794578, 74989421, 79432823, + 84139514, 89125094, 94406088, 100000000, 105925373, 112201845, 118850223, 125892541, + 133352143, 141253754, 149623566, 158489319, 167880402, 177827941, 188364909, 199526231, + 211348904, 223872114, 237137371, 251188643, 266072506, 281838293, 298538262, 316227766, + 334965439, 354813389, 375837404, 398107171, 421696503, 446683592, 473151259, 501187234, + 530884444, 562341325, 595662144, 630957344, 668343918, 707945784, 749894209, 794328235, + 841395142, 891250938, 944060876, 1000000000, 1059253725, 1122018454, 1188502227, + 1258925412, 1333521432, 1412537545, 1496235656, 1584893192, 1678804018, 1778279410, + 1883649089, 1995262315, 2113489040, 2238721139, 2371373706, 2511886432, 2660725060, + 2818382931, 2985382619, 3162277660, 3349654392, 3548133892, 3758374043, 3981071706, + 4216965034, 4466835922ULL, 4731512590ULL, 5011872336ULL, 5308844442ULL, 5623413252ULL, + 5956621435ULL, 6309573445ULL, 6683439176ULL, 7079457844ULL, 7498942093ULL, + 7943282347ULL, 8413951416ULL, 8912509381ULL, 9440608763ULL, 10000000000ULL, + 10592537252ULL, 11220184543ULL, 11885022274ULL, 12589254118ULL, 13335214322ULL, + 14125375446ULL, 14962356561ULL, 15848931925ULL, 16788040181ULL, 17782794100ULL, + 18836490895ULL, 19952623150ULL, 21134890398ULL, 22387211386ULL, 23713737057ULL, + 25118864315ULL, 26607250598ULL, 28183829313ULL, 29853826189ULL, 31622776602ULL, + 33496543916ULL, 35481338923ULL, 37583740429ULL, 39810717055ULL, 42169650343ULL, + 44668359215ULL, 47315125896ULL, 50118723363ULL, 53088444423ULL, 56234132519ULL, + 59566214353ULL, 63095734448ULL, 66834391757ULL, 70794578438ULL, 74989420933ULL, + 79432823472ULL, 84139514165ULL, 89125093813ULL, 94406087629ULL, 100000000000ULL, + 105925372518ULL, 112201845430ULL, 118850222744ULL, 125892541179ULL, 133352143216ULL, + 141253754462ULL, 149623565609ULL, 158489319246ULL, 167880401812ULL, 177827941004ULL, + 188364908949ULL, 199526231497ULL, 211348903984ULL, 223872113857ULL, 237137370566ULL, + 251188643151ULL, 266072505980ULL, 281838293126ULL, 298538261892ULL, 316227766017ULL, + 334965439158ULL, 354813389234ULL, 375837404288ULL, 398107170553ULL, 421696503429ULL, + 446683592151ULL, 473151258961ULL, 501187233627ULL, 530884444231ULL, 562341325190ULL, + 595662143529ULL, 630957344480ULL, 668343917569ULL, 707945784384ULL, 749894209332ULL, + 794328234724ULL, 841395141645ULL, 891250938134ULL, 944060876286ULL, 1000000000000ULL, + 1059253725177ULL, 1122018454302ULL, 1188502227437ULL, 1258925411794ULL, + 1333521432163ULL, 1412537544623ULL, 1496235656094ULL, 1584893192461ULL, + 1678804018123ULL, 1778279410039ULL, 1883649089490ULL, 1995262314969ULL, + 2113489039837ULL, 2238721138568ULL, 2371373705662ULL, 2511886431510ULL, + 2660725059799ULL, 2818382931264ULL, 2985382618918ULL, 3162277660168ULL, + 3349654391578ULL, 3548133892336ULL, 3758374042884ULL, 3981071705535ULL, + 4216965034286ULL, 4466835921510ULL, 4731512589615ULL, 5011872336273ULL, + 5308844442310ULL, 5623413251904ULL, 5956621435290ULL, 6309573444802ULL, + 6683439175686ULL, 7079457843841ULL, 7498942093325ULL, 7943282347243ULL, + 8413951416452ULL, 8912509381337ULL, 9440608762859ULL, 10000000000000ULL, + 10592537251773ULL, 11220184543020ULL, 11885022274370ULL, 12589254117942ULL, + 13335214321633ULL, 14125375446228ULL, 14962356560944ULL, 15848931924611ULL, + 16788040181226ULL, 17782794100389ULL, 18836490894898ULL, 19952623149689ULL, + 21134890398367ULL, 22387211385683ULL, 23713737056617ULL, 25118864315096ULL, + 26607250597988ULL, 28183829312645ULL, 29853826189180ULL, 31622776601684ULL, + 33496543915783ULL, 35481338923358ULL, 37583740428845ULL, 39810717055350ULL, + 42169650342858ULL, 44668359215096ULL, 47315125896148ULL, 50118723362727ULL, + 53088444423099ULL, 56234132519035ULL, 59566214352901ULL, 63095734448019ULL, + 66834391756862ULL, 70794578438414ULL, 74989420933246ULL, 79432823472428ULL, + 84139514164520ULL, 89125093813375ULL, 94406087628593ULL, 100000000000000ULL, + 105925372517729ULL, 112201845430197ULL, 118850222743702ULL, 125892541179417ULL, + 133352143216332ULL, 141253754462276ULL, 149623565609444ULL, 158489319246111ULL, + 167880401812256ULL, 177827941003893ULL, 188364908948981ULL, 199526231496888ULL, + 211348903983664ULL, 223872113856834ULL, 237137370566166ULL, 251188643150958ULL, + 266072505979882ULL, 281838293126446ULL, 298538261891796ULL, 316227766016838ULL, + 334965439157829ULL, 354813389233577ULL, 375837404288444ULL, 398107170553497ULL, + 421696503428583ULL, 446683592150964ULL, 473151258961482ULL, 501187233627272ULL, + 530884444230989ULL, 562341325190350ULL, 595662143529011ULL, 630957344480196ULL, + 668343917568615ULL, 707945784384138ULL, 749894209332456ULL, 794328234724284ULL, + 841395141645198ULL, 891250938133745ULL, 944060876285923ULL, 1000000000000000ULL, + 1059253725177290ULL, 1122018454301970ULL, 1188502227437020ULL, 1258925411794170ULL, + 1333521432163330ULL, 1412537544622760ULL, 1496235656094440ULL, 1584893192461110ULL, + 1678804018122560ULL, 1778279410038920ULL, 1883649089489810ULL, 1995262314968890ULL, + 2113489039836650ULL, 2238721138568340ULL, 2371373705661660ULL, 2511886431509590ULL, + 2660725059798820ULL, 2818382931264460ULL, 2985382618917960ULL, 3162277660168380ULL, + 3349654391578280ULL, 3548133892335770ULL, 3758374042884440ULL, 3981071705534970ULL +}; + +s32 rtw89_linear_to_db_quarter(u64 val) +{ + int r = ARRAY_SIZE(db_invert_table) - 1; + int l = 0; + int m; + + while (l <= r) { + m = l + (r - l) / 2; + + if (db_invert_table[m] == val) + return m - (s32)RTW89_DB_INVERT_TABLE_OFFSET; + + if (db_invert_table[m] > val) + r = m - 1; + else + l = m + 1; + } + + if (l >= ARRAY_SIZE(db_invert_table)) + return RTW89_MAX_DBM; + else if (r < 0) + return RTW89_MIN_DBM; + else if (val - db_invert_table[r] <= db_invert_table[l] - val) + return r - (s32)RTW89_DB_INVERT_TABLE_OFFSET; + else + return l - (s32)RTW89_DB_INVERT_TABLE_OFFSET; +} +EXPORT_SYMBOL(rtw89_linear_to_db_quarter); + +s32 rtw89_linear_to_db(u64 val) +{ + return rtw89_linear_to_db_quarter(val) >> RTW89_DBM_QUARTER_FACTOR; +} +EXPORT_SYMBOL(rtw89_linear_to_db); + +u64 rtw89_db_quarter_to_linear(s32 db) +{ + /* supported range -41.25 to 96 dBm, in unit of 0.25 dBm */ + db = clamp_t(s32, db, RTW89_MIN_DBM, RTW89_MAX_DBM); + db += (s32)RTW89_DB_INVERT_TABLE_OFFSET; + + return db_invert_table[db]; +} +EXPORT_SYMBOL(rtw89_db_quarter_to_linear); + +u64 rtw89_db_to_linear(s32 db) +{ + return rtw89_db_quarter_to_linear(db << RTW89_DBM_QUARTER_FACTOR); +} +EXPORT_SYMBOL(rtw89_db_to_linear); + +void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used) +{ + static const char ellipsis[] = "..."; + + /* length of null terminiator isn't included in 'used' */ + if (used + 1 < size || size < sizeof(ellipsis)) + return; + + memcpy(buf + size - sizeof(ellipsis), ellipsis, sizeof(ellipsis)); +} diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h new file mode 100644 index 000000000..c16e7a7f8 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + * Copyright(c) 2019-2020 Realtek Corporation + */ +#ifndef __RTW89_UTIL_H__ +#define __RTW89_UTIL_H__ + +#include "core.h" + +#define RTW89_KEY_PN_0 GENMASK_ULL(7, 0) +#define RTW89_KEY_PN_1 GENMASK_ULL(15, 8) +#define RTW89_KEY_PN_2 GENMASK_ULL(23, 16) +#define RTW89_KEY_PN_3 GENMASK_ULL(31, 24) +#define RTW89_KEY_PN_4 GENMASK_ULL(39, 32) +#define RTW89_KEY_PN_5 GENMASK_ULL(47, 40) + +#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ + ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ + IEEE80211_IFACE_ITER_NORMAL, iterator, data) + +/* call this function with wiphy mutex is held */ +#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ + list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) + +/* Before adding rtwvif to list, we need to check if it already exist, beacase + * in some case such as SER L2 happen during WoWLAN flow, calling reconfig + * twice cause the list to be added twice. + */ +static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev, + struct rtw89_vif *new) +{ + struct rtw89_vif *rtwvif; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + if (rtwvif == new) + return true; + + return false; +} + +/* The result of negative dividend and positive divisor is undefined, but it + * should be one case of round-down or round-up. So, make it round-down if the + * result is round-up. + * Note: the maximum value of divisor is 0x7FFF_FFFF, because we cast it to + * signed value to make compiler to use signed divide instruction. + */ +static inline s32 s32_div_u32_round_down(s32 dividend, u32 divisor, s32 *remainder) +{ + s32 i_divisor = (s32)divisor; + s32 i_remainder; + s32 quotient; + + quotient = dividend / i_divisor; + i_remainder = dividend % i_divisor; + + if (i_remainder < 0) { + quotient--; + i_remainder += i_divisor; + } + + if (remainder) + *remainder = i_remainder; + return quotient; +} + +static inline s32 s32_div_u32_round_closest(s32 dividend, u32 divisor) +{ + return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL); +} + +static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask) +{ + int i; + + eth_zero_addr(dst); + for (i = 0; i < ETH_ALEN; i++) { + if (mask & BIT(i)) + dst[i] = src[i]; + } +} + +static inline void ccmp_hdr2pn(s64 *pn, const u8 *hdr) +{ + *pn = u64_encode_bits(hdr[0], RTW89_KEY_PN_0) | + u64_encode_bits(hdr[1], RTW89_KEY_PN_1) | + u64_encode_bits(hdr[4], RTW89_KEY_PN_2) | + u64_encode_bits(hdr[5], RTW89_KEY_PN_3) | + u64_encode_bits(hdr[6], RTW89_KEY_PN_4) | + u64_encode_bits(hdr[7], RTW89_KEY_PN_5); +} + +s32 rtw89_linear_to_db_quarter(u64 val); +s32 rtw89_linear_to_db(u64 val); +u64 rtw89_db_quarter_to_linear(s32 db); +u64 rtw89_db_to_linear(s32 db); +void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used); + +#endif diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c new file mode 100644 index 000000000..2dfa24c54 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -0,0 +1,1847 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ +#include "cam.h" +#include "core.h" +#include "debug.h" +#include "fw.h" +#include "mac.h" +#include "phy.h" +#include "ps.h" +#include "reg.h" +#include "util.h" +#include "wow.h" + +void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + const u8 *rsn, *ies = mgmt->u.assoc_req.variable; + struct rtw89_rsn_ie *rsn_ie; + + rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len); + if (!rsn) + return; + + rsn_ie = (struct rtw89_rsn_ie *)rsn; + rtw_wow->akm = rsn_ie->akm_cipher_suite.type; +} + +#define RTW89_CIPHER_INFO_DEF(cipher) \ + {WLAN_CIPHER_SUITE_ ## cipher, .fw_alg = RTW89_WOW_FW_ALG_ ## cipher, \ + .len = WLAN_KEY_LEN_ ## cipher} + +static const struct rtw89_cipher_info rtw89_cipher_info_defs[] = { + RTW89_CIPHER_INFO_DEF(WEP40), + RTW89_CIPHER_INFO_DEF(WEP104), + RTW89_CIPHER_INFO_DEF(TKIP), + RTW89_CIPHER_INFO_DEF(CCMP), + RTW89_CIPHER_INFO_DEF(GCMP), + RTW89_CIPHER_INFO_DEF(CCMP_256), + RTW89_CIPHER_INFO_DEF(GCMP_256), + RTW89_CIPHER_INFO_DEF(AES_CMAC), +}; + +#undef RTW89_CIPHER_INFO_DEF + +static const +struct rtw89_cipher_info *rtw89_cipher_alg_recognize(u32 cipher) +{ + const struct rtw89_cipher_info *cipher_info_defs; + int i; + + for (i = 0; i < ARRAY_SIZE(rtw89_cipher_info_defs); i++) { + cipher_info_defs = &rtw89_cipher_info_defs[i]; + if (cipher_info_defs->cipher == cipher) + return cipher_info_defs; + } + + return NULL; +} + +static int _pn_to_iv(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key, + u8 *iv, u64 pn, u8 key_idx) +{ + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + iv[0] = u64_get_bits(pn, RTW89_KEY_PN_1); + iv[1] = (u64_get_bits(pn, RTW89_KEY_PN_1) | 0x20) & 0x7f; + iv[2] = u64_get_bits(pn, RTW89_KEY_PN_0); + break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + iv[0] = u64_get_bits(pn, RTW89_KEY_PN_0); + iv[1] = u64_get_bits(pn, RTW89_KEY_PN_1); + iv[2] = 0; + break; + default: + return -EINVAL; + } + + iv[3] = BIT(5) | ((key_idx & 0x3) << 6); + iv[4] = u64_get_bits(pn, RTW89_KEY_PN_2); + iv[5] = u64_get_bits(pn, RTW89_KEY_PN_3); + iv[6] = u64_get_bits(pn, RTW89_KEY_PN_4); + iv[7] = u64_get_bits(pn, RTW89_KEY_PN_5); + + return 0; +} + +static int rtw89_rx_pn_to_iv(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + u8 *iv) +{ + struct ieee80211_key_seq seq; + int err; + u64 pn; + + ieee80211_get_key_rx_seq(key, 0, &seq); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + pn = u64_encode_bits(seq.tkip.iv32, RTW89_KEY_TKIP_PN_IV32) | + u64_encode_bits(seq.tkip.iv16, RTW89_KEY_TKIP_PN_IV16); + break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + /* seq.ccmp.pn[] is BE order array */ + pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) | + u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) | + u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) | + u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) | + u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) | + u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0); + break; + default: + return -EINVAL; + } + + err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); + if (err) + return err; + + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", + __func__, key->keyidx, pn, 8, iv); + + return 0; +} + +static int rtw89_tx_pn_to_iv(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + u8 *iv) +{ + int err; + u64 pn; + + pn = atomic64_inc_return(&key->tx_pn); + err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); + if (err) + return err; + + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", + __func__, key->keyidx, pn, 8, iv); + + return 0; +} + +static int _iv_to_pn(struct rtw89_dev *rtwdev, u8 *iv, u64 *pn, u8 *key_id, + struct ieee80211_key_conf *key) +{ + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + *pn = u64_encode_bits(iv[2], RTW89_KEY_PN_0) | + u64_encode_bits(iv[0], RTW89_KEY_PN_1); + break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + *pn = u64_encode_bits(iv[0], RTW89_KEY_PN_0) | + u64_encode_bits(iv[1], RTW89_KEY_PN_1); + break; + default: + return -EINVAL; + } + + *pn |= u64_encode_bits(iv[4], RTW89_KEY_PN_2) | + u64_encode_bits(iv[5], RTW89_KEY_PN_3) | + u64_encode_bits(iv[6], RTW89_KEY_PN_4) | + u64_encode_bits(iv[7], RTW89_KEY_PN_5); + + if (key_id) + *key_id = *(iv + 3) >> 6; + + return 0; +} + +static int rtw89_rx_iv_to_pn(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + u8 *iv) +{ + struct ieee80211_key_seq seq; + int err; + u64 pn; + + err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); + if (err) + return err; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + seq.tkip.iv32 = u64_get_bits(pn, RTW89_KEY_TKIP_PN_IV32); + seq.tkip.iv16 = u64_get_bits(pn, RTW89_KEY_TKIP_PN_IV16); + break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + /* seq.ccmp.pn[] is BE order array */ + seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5); + seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4); + seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3); + seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2); + seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1); + seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0); + break; + default: + return -EINVAL; + } + + ieee80211_set_key_rx_seq(key, 0, &seq); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n", + __func__, key->keyidx, 8, iv, 6, seq.ccmp.pn); + + return 0; +} + +static int rtw89_tx_iv_to_pn(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + u8 *iv) +{ + int err; + u64 pn; + + err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); + if (err) + return err; + + atomic64_set(&key->tx_pn, pn); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n", + __func__, key->keyidx, 8, iv, pn); + + return 0; +} + +static int rtw89_rx_pn_get_pmf(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + struct rtw89_wow_gtk_info *gtk_info) +{ + struct ieee80211_key_seq seq; + u64 pn; + + if (key->keyidx == 4) + memcpy(gtk_info->igtk[0], key->key, key->keylen); + else if (key->keyidx == 5) + memcpy(gtk_info->igtk[1], key->key, key->keylen); + else + return -EINVAL; + + ieee80211_get_key_rx_seq(key, 0, &seq); + + /* seq.ccmp.pn[] is BE order array */ + pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) | + u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) | + u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) | + u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) | + u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) | + u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0); + gtk_info->ipn = cpu_to_le64(pn); + gtk_info->igtk_keyid = cpu_to_le32(key->keyidx); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n", + __func__, key->keyidx, pn); + + return 0; +} + +static int rtw89_rx_pn_set_pmf(struct rtw89_dev *rtwdev, + struct ieee80211_key_conf *key, + u64 pn) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct ieee80211_key_seq seq; + + if (key->keyidx != aoac_rpt->igtk_key_id) + return 0; + + /* seq.ccmp.pn[] is BE order array */ + seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5); + seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4); + seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3); + seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2); + seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1); + seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0); + + ieee80211_set_key_rx_seq(key, 0, &seq); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n", + __func__, key->keyidx, 6, seq.ccmp.pn); + + return 0; +} + +static void rtw89_wow_get_key_info_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; + struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; + const struct rtw89_cipher_info *cipher_info; + bool *err = data; + int ret; + + cipher_info = rtw89_cipher_alg_recognize(key->cipher); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + if (sta) + memcpy(gtk_info->txmickey, + key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, + sizeof(gtk_info->txmickey)); + fallthrough; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + if (sta) { + ret = rtw89_tx_pn_to_iv(rtwdev, key, + key_info->ptk_tx_iv); + if (ret) + goto err; + ret = rtw89_rx_pn_to_iv(rtwdev, key, + key_info->ptk_rx_iv); + if (ret) + goto err; + + rtw_wow->ptk_alg = cipher_info->fw_alg; + rtw_wow->ptk_keyidx = key->keyidx; + } else { + ret = rtw89_rx_pn_to_iv(rtwdev, key, + key_info->gtk_rx_iv[key->keyidx]); + if (ret) + goto err; + + rtw_wow->gtk_alg = cipher_info->fw_alg; + key_info->gtk_keyidx = key->keyidx; + } + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info); + if (ret) + goto err; + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + /* WEP only set group key in mac80211, but fw need to set + * both of pairwise key and group key. + */ + rtw_wow->ptk_alg = cipher_info->fw_alg; + rtw_wow->ptk_keyidx = key->keyidx; + rtw_wow->gtk_alg = cipher_info->fw_alg; + key_info->gtk_keyidx = key->keyidx; + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n", + key->cipher); + goto err; + } + + return; +err: + *err = true; +} + +static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct rtw89_set_key_info_iter_data *iter_data = data; + bool update_tx_key_info = iter_data->rx_ready; + u8 tmp[RTW89_MIC_KEY_LEN]; + int ret; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + /* + * TX MIC KEY and RX MIC KEY is oppsite in FW, + * need to swap it before sending to mac80211. + */ + if (!sta && update_tx_key_info && aoac_rpt->rekey_ok && + !iter_data->tkip_gtk_swapped) { + memcpy(tmp, &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], + RTW89_MIC_KEY_LEN); + memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], + &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], + RTW89_MIC_KEY_LEN); + memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], + tmp, RTW89_MIC_KEY_LEN); + iter_data->tkip_gtk_swapped = true; + } + fallthrough; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP_256: + if (sta && !update_tx_key_info) { + ret = rtw89_rx_iv_to_pn(rtwdev, key, + aoac_rpt->ptk_rx_iv); + if (ret) + goto err; + } + + if (sta && update_tx_key_info) { + ret = rtw89_tx_iv_to_pn(rtwdev, key, + aoac_rpt->ptk_tx_iv); + if (ret) + goto err; + } + + if (!sta && !update_tx_key_info) { + ret = rtw89_rx_iv_to_pn(rtwdev, key, + aoac_rpt->gtk_rx_iv[key->keyidx]); + if (ret) + goto err; + } + + if (!sta && update_tx_key_info && aoac_rpt->rekey_ok) + iter_data->gtk_cipher = key->cipher; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + if (update_tx_key_info) { + if (aoac_rpt->rekey_ok) + iter_data->igtk_cipher = key->cipher; + } else { + ret = rtw89_rx_pn_set_pmf(rtwdev, key, + aoac_rpt->igtk_ipn); + if (ret) + goto err; + } + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + break; + default: + rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n", + key->cipher); + goto err; + } + + return; + +err: + iter_data->error = true; +} + +static void rtw89_wow_key_clear(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt)); + memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info)); + memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info)); + rtw_wow->ptk_alg = 0; + rtw_wow->gtk_alg = 0; +} + +static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + bool err = false; + + rcu_read_lock(); + ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif, + rtw89_wow_get_key_info_iter, &err); + rcu_read_unlock(); + + if (err) { + rtw89_wow_key_clear(rtwdev); + return; + } + + key_info->valid_check = RTW89_WOW_VALID_CHECK; + key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK | + RTW89_WOW_SYMBOL_CHK_GTK; +} + +static void rtw89_wow_debug_aoac_rpt(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + + if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_WOW)) + return; + + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rpt_ver = %d\n", + aoac_rpt->rpt_ver); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] sec_type = %d\n", + aoac_rpt->sec_type); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] key_idx = %d\n", + aoac_rpt->key_idx); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] pattern_idx = %d\n", + aoac_rpt->pattern_idx); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rekey_ok = %d\n", + aoac_rpt->rekey_ok); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_tx_iv = %*ph\n", + 8, aoac_rpt->ptk_tx_iv); + rtw89_debug(rtwdev, RTW89_DBG_WOW, + "[aoac_rpt] eapol_key_replay_count = %*ph\n", + 8, aoac_rpt->eapol_key_replay_count); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_rx_iv = %*ph\n", + 8, aoac_rpt->ptk_rx_iv); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[0] = %*ph\n", + 8, aoac_rpt->gtk_rx_iv[0]); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[1] = %*ph\n", + 8, aoac_rpt->gtk_rx_iv[1]); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[2] = %*ph\n", + 8, aoac_rpt->gtk_rx_iv[2]); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[3] = %*ph\n", + 8, aoac_rpt->gtk_rx_iv[3]); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_key_id = %llu\n", + aoac_rpt->igtk_key_id); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_ipn = %llu\n", + aoac_rpt->igtk_ipn); + rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk = %*ph\n", + 32, aoac_rpt->igtk); +} + +static int rtw89_wow_get_aoac_rpt_reg(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct rtw89_mac_c2h_info c2h_info = {}; + struct rtw89_mac_h2c_info h2c_info = {}; + u8 igtk_ipn[8]; + u8 key_idx; + int ret; + + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1; + h2c_info.content_len = 2; + ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); + if (ret) + return ret; + + aoac_rpt->key_idx = + u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX); + key_idx = aoac_rpt->key_idx; + aoac_rpt->gtk_rx_iv[key_idx][0] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_0); + aoac_rpt->gtk_rx_iv[key_idx][1] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_1); + aoac_rpt->gtk_rx_iv[key_idx][2] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_2); + aoac_rpt->gtk_rx_iv[key_idx][3] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_3); + aoac_rpt->gtk_rx_iv[key_idx][4] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_4); + aoac_rpt->gtk_rx_iv[key_idx][5] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_5); + aoac_rpt->gtk_rx_iv[key_idx][6] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_6); + aoac_rpt->gtk_rx_iv[key_idx][7] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_7); + aoac_rpt->ptk_rx_iv[0] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0); + aoac_rpt->ptk_rx_iv[1] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1); + aoac_rpt->ptk_rx_iv[2] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2); + aoac_rpt->ptk_rx_iv[3] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3); + + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2; + h2c_info.content_len = 2; + ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); + if (ret) + return ret; + + aoac_rpt->ptk_rx_iv[4] = + u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4); + aoac_rpt->ptk_rx_iv[5] = + u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5); + aoac_rpt->ptk_rx_iv[6] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6); + aoac_rpt->ptk_rx_iv[7] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7); + igtk_ipn[0] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0); + igtk_ipn[1] = + u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1); + igtk_ipn[2] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2); + igtk_ipn[3] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3); + igtk_ipn[4] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4); + igtk_ipn[5] = + u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5); + igtk_ipn[6] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6); + igtk_ipn[7] = + u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7); + aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) | + u64_encode_bits(igtk_ipn[1], RTW89_IGTK_IPN_1) | + u64_encode_bits(igtk_ipn[2], RTW89_IGTK_IPN_2) | + u64_encode_bits(igtk_ipn[3], RTW89_IGTK_IPN_3) | + u64_encode_bits(igtk_ipn[4], RTW89_IGTK_IPN_4) | + u64_encode_bits(igtk_ipn[5], RTW89_IGTK_IPN_5) | + u64_encode_bits(igtk_ipn[6], RTW89_IGTK_IPN_6) | + u64_encode_bits(igtk_ipn[7], RTW89_IGTK_IPN_7); + + return 0; +} + +static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + int ret; + + if (!rtw_wow->ptk_alg) + return -EPERM; + + if (!rx_ready) { + ret = rtw89_wow_get_aoac_rpt_reg(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to get aoac rpt by reg\n"); + return ret; + } + } else { + ret = rtw89_fw_h2c_wow_request_aoac(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to get aoac rpt by pkt\n"); + return ret; + } + } + + rtw89_wow_debug_aoac_rpt(rtwdev); + + return 0; +} + +static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, + u32 cipher, u8 keyidx, u8 *gtk) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_cipher_info *cipher_info; + struct ieee80211_key_conf *rekey_conf; + struct ieee80211_key_conf *key; + u8 sz; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + cipher_info = rtw89_cipher_alg_recognize(cipher); + sz = struct_size(rekey_conf, key, cipher_info->len); + rekey_conf = kmalloc(sz, GFP_KERNEL); + if (!rekey_conf) + return NULL; + + rekey_conf->cipher = cipher; + rekey_conf->keyidx = keyidx; + rekey_conf->keylen = cipher_info->len; + memcpy(rekey_conf->key, gtk, + flex_array_size(rekey_conf, key, cipher_info->len)); + + if (ieee80211_vif_is_mld(wow_vif)) + key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk, + cipher_info->len, + rtwvif_link->link_id); + else + key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk, + cipher_info->len, -1); + + kfree(rekey_conf); + if (IS_ERR(key)) { + rtw89_err(rtwdev, "ieee80211_gtk_rekey_add failed\n"); + return NULL; + } + + return key; +} + +static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct rtw89_set_key_info_iter_data data = {.error = false, + .rx_ready = rx_ready, + .tkip_gtk_swapped = false}; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_key_conf *key; + + rcu_read_lock(); + ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif, + rtw89_wow_set_key_info_iter, &data); + rcu_read_unlock(); + + if (data.error) { + rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s error\n", __func__); + return; + } + + if (!data.gtk_cipher) + return; + + key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx, + aoac_rpt->gtk); + if (!key) + return; + + rtw89_rx_iv_to_pn(rtwdev, key, + aoac_rpt->gtk_rx_iv[key->keyidx]); + + if (!data.igtk_cipher) + return; + + key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id, + aoac_rpt->igtk); + if (!key) + return; + + rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid, + aoac_rpt->eapol_key_replay_count, + GFP_ATOMIC); + + rcu_read_unlock(); +} + +static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) +{ + __rtw89_leave_ps_mode(rtwdev); +} + +static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) +{ + __rtw89_enter_ps_mode(rtwdev); +} + +static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + + if (rtw89_wow_mgd_linked(rtwdev)) + rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false); + else if (rtw89_wow_no_link(rtwdev)) + rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true); +} + +static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + + if (rtw89_wow_mgd_linked(rtwdev)) { + rtw89_leave_lps(rtwdev); + } else if (rtw89_wow_no_link(rtwdev)) { + if (enable_wow) + rtw89_leave_ips(rtwdev); + else + rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false); + } +} + +static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + return mac->wow_config_mac(rtwdev, enable_wow); +} + +static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + enum rtw89_mac_fwd_target fwd_target = enable ? + RTW89_FWD_DONT_CARE : + RTW89_FWD_TO_HOST; + + mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); + mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); + mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); +} + +static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; + struct cfg80211_wowlan_nd_info nd_info; + struct cfg80211_wowlan_wakeup wakeup = { + .pattern_idx = -1, + }; + u32 wow_reason_reg; + u8 reason; + + if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw)) + wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1]; + else + wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0]; + + reason = rtw89_read8(rtwdev, wow_reason_reg); + switch (reason) { + case RTW89_WOW_RSN_RX_DISASSOC: + wakeup.disconnect = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx disassoc\n"); + break; + case RTW89_WOW_RSN_RX_DEAUTH: + wakeup.disconnect = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx deauth\n"); + break; + case RTW89_WOW_RSN_DISCONNECT: + wakeup.disconnect = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: AP is off\n"); + break; + case RTW89_WOW_RSN_RX_MAGIC_PKT: + wakeup.magic_pkt = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx magic packet\n"); + break; + case RTW89_WOW_RSN_RX_GTK_REKEY: + wakeup.gtk_rekey_failure = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n"); + break; + case RTW89_WOW_RSN_RX_PATTERN_MATCH: + wakeup.pattern_idx = aoac_rpt->pattern_idx; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n"); + break; + case RTW89_WOW_RSN_RX_NLO: + /* Current firmware and driver don't report ssid index. + * Use 0 for n_matches based on its comment. + */ + nd_info.n_matches = 0; + wakeup.net_detect = &nd_info; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "Rx NLO\n"); + break; + default: + rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); + ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL); + return; + } + + ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL); +} + +static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + + /* Current WoWLAN function support setting of only vif in + * infra mode or no link mode. When one suitable vif is found, + * stop the iteration. + */ + if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION) + return; + + switch (rtwvif_link->net_type) { + case RTW89_NET_TYPE_INFRA: + if (rtw_wow_has_mgd_features(rtwdev)) + rtw_wow->rtwvif_link = rtwvif_link; + break; + case RTW89_NET_TYPE_NO_LINK: + if (rtw_wow->pno_inited) + rtw_wow->rtwvif_link = rtwvif_link; + break; + default: + break; + } +} + +static u16 __rtw89_cal_crc16(u8 data, u16 crc) +{ + u8 shift_in, data_bit; + u8 crc_bit4, crc_bit11, crc_bit15; + u16 crc_result; + int index; + + for (index = 0; index < 8; index++) { + crc_bit15 = crc & BIT(15) ? 1 : 0; + data_bit = data & BIT(index) ? 1 : 0; + shift_in = crc_bit15 ^ data_bit; + + crc_result = crc << 1; + + if (shift_in == 0) + crc_result &= ~BIT(0); + else + crc_result |= BIT(0); + + crc_bit11 = (crc & BIT(11) ? 1 : 0) ^ shift_in; + + if (crc_bit11 == 0) + crc_result &= ~BIT(12); + else + crc_result |= BIT(12); + + crc_bit4 = (crc & BIT(4) ? 1 : 0) ^ shift_in; + + if (crc_bit4 == 0) + crc_result &= ~BIT(5); + else + crc_result |= BIT(5); + + crc = crc_result; + } + return crc; +} + +static u16 rtw89_calc_crc(u8 *pdata, int length) +{ + u16 crc = 0xffff; + int i; + + for (i = 0; i < length; i++) + crc = __rtw89_cal_crc16(pdata[i], crc); + + /* get 1' complement */ + return ~crc; +} + +static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link, + struct rtw89_wow_cam_info *rtw_pattern, + const u8 *pattern, u8 da_mask) +{ + u8 da[ETH_ALEN]; + + ether_addr_copy_mask(da, pattern, da_mask); + + /* Each pattern is divided into different kinds by DA address + * a. DA is broadcast address: set bc = 0; + * b. DA is multicast address: set mc = 0 + * c. DA is unicast address same as dev's mac address: set uc = 0 + * d. DA is unmasked. Also called wildcard type: set uc = bc = mc = 0 + * e. Others is invalid type. + */ + + if (is_broadcast_ether_addr(da)) + rtw_pattern->bc = true; + else if (is_multicast_ether_addr(da)) + rtw_pattern->mc = true; + else if (ether_addr_equal(da, rtwvif_link->mac_addr) && + da_mask == GENMASK(5, 0)) + rtw_pattern->uc = true; + else if (!da_mask) /*da_mask == 0 mean wildcard*/ + return 0; + else + return -EPERM; + + return 0; +} + +static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_pkt_pattern *pkt_pattern, + struct rtw89_wow_cam_info *rtw_pattern) +{ + u8 mask_hw[RTW89_MAX_PATTERN_MASK_SIZE * 4] = {0}; + u8 content[RTW89_MAX_PATTERN_SIZE] = {0}; + const u8 *mask; + const u8 *pattern; + u8 mask_len; + u16 count; + u32 len; + int i, ret; + + pattern = pkt_pattern->pattern; + len = pkt_pattern->pattern_len; + mask = pkt_pattern->mask; + mask_len = DIV_ROUND_UP(len, 8); + memset(rtw_pattern, 0, sizeof(*rtw_pattern)); + + ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern, + mask[0] & GENMASK(5, 0)); + if (ret) + return ret; + + /* translate mask from os to mask for hw + * pattern from OS uses 'ethenet frame', like this: + * | 6 | 6 | 2 | 20 | Variable | 4 | + * |--------+--------+------+-----------+------------+-----| + * | 802.3 Mac Header | IP Header | TCP Packet | FCS | + * | DA | SA | Type | + * + * BUT, packet catched by our HW is in '802.11 frame', begin from LLC + * | 24 or 30 | 6 | 2 | 20 | Variable | 4 | + * |-------------------+--------+------+-----------+------------+-----| + * | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | + * | Others | Tpye | + * + * Therefore, we need translate mask_from_OS to mask_to_hw. + * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, + * because new mask[0~5] means 'SA', but our HW packet begins from LLC, + * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. + */ + + /* Shift 6 bits */ + for (i = 0; i < mask_len - 1; i++) { + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)) | + u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2; + } + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); + + /* Set bit 0-5 to zero */ + mask_hw[0] &= ~GENMASK(5, 0); + + memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask)); + + /* To get the wake up pattern from the mask. + * We do not count first 12 bits which means + * DA[6] and SA[6] in the pattern to match HW design. + */ + count = 0; + for (i = 12; i < len; i++) { + if ((mask[i / 8] >> (i % 8)) & 0x01) { + content[count] = pattern[i]; + count++; + } + } + + rtw_pattern->crc = rtw89_calc_crc(content, count); + + return 0; +} + +static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct cfg80211_wowlan *wowlan) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; + int i; + int ret; + + if (!wowlan->n_patterns || !wowlan->patterns) + return 0; + + for (i = 0; i < wowlan->n_patterns; i++) { + rtw_pattern = &rtw_wow->patterns[i]; + ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link, + &wowlan->patterns[i], + rtw_pattern); + if (ret) { + rtw89_err(rtwdev, "failed to generate pattern(%d)\n", i); + rtw_wow->pattern_cnt = 0; + return ret; + } + + rtw_pattern->r_w = true; + rtw_pattern->idx = i; + rtw_pattern->negative_pattern_match = false; + rtw_pattern->skip_mac_hdr = true; + rtw_pattern->valid = true; + } + rtw_wow->pattern_cnt = wowlan->n_patterns; + + return 0; +} + +static void rtw89_wow_pattern_clear_cam(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; + int i = 0; + + for (i = 0; i < rtw_wow->pattern_cnt; i++) { + rtw_pattern = &rtw_wow->patterns[i]; + rtw_pattern->valid = false; + rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern); + } +} + +static void rtw89_wow_pattern_write(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; + int i; + + for (i = 0; i < rtw_wow->pattern_cnt; i++) + rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern + i); +} + +static void rtw89_wow_pattern_clear(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + rtw89_wow_pattern_clear_cam(rtwdev); + + rtw_wow->pattern_cnt = 0; + memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); +} + +static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + rtw_wow->rtwvif_link = NULL; + rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); + rtw_wow->pattern_cnt = 0; + rtw_wow->pno_inited = false; +} + +static void rtw89_wow_init_pno(struct rtw89_dev *rtwdev, + struct cfg80211_sched_scan_request *nd_config) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + if (!nd_config->n_match_sets || !nd_config->n_channels) + return; + + rtw_wow->nd_config = nd_config; + rtw_wow->pno_inited = true; + + INIT_LIST_HEAD(&rtw_wow->pno_pkt_list); + + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: net-detect is enabled\n"); +} + +static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, + struct cfg80211_wowlan *wowlan) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + + if (wowlan->disconnect) + set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); + if (wowlan->magic_pkt) + set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); + if (wowlan->n_patterns && wowlan->patterns) + set_bit(RTW89_WOW_FLAG_EN_PATTERN, rtw_wow->flags); + + if (wowlan->nd_config) + rtw89_wow_init_pno(rtwdev, wowlan->nd_config); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtwvif_link = rtw89_get_designated_link(rtwvif); + if (!rtwvif_link) + continue; + + rtw89_wow_vif_iter(rtwdev, rtwvif_link); + } + + rtwvif_link = rtw_wow->rtwvif_link; + if (!rtwvif_link) + return -EPERM; + + return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan); +} + +static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + int ret; + + ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_err(rtwdev, "failed to config pno\n"); + return ret; + } + + ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); + if (ret) { + rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); + return ret; + } + + ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); + if (ret) { + rtw89_err(rtwdev, "failed to fw wow global\n"); + return ret; + } + + return 0; +} + +static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + struct ieee80211_sta *wow_sta; + struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_sta *rtwsta; + int ret; + + wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); + if (wow_sta) { + rtwsta = sta_to_rtwsta(wow_sta); + rtwsta_link = rtwsta->links[rtwvif_link->link_id]; + if (!rtwsta_link) + return -ENOLINK; + } + + if (wow) { + if (rtw_wow->pattern_cnt) + rtwvif_link->wowlan_pattern = true; + if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) + rtwvif_link->wowlan_magic = true; + } else { + rtwvif_link->wowlan_pattern = false; + rtwvif_link->wowlan_magic = false; + } + + ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); + if (ret) { + rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); + return ret; + } + + if (wow) { + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", + ret); + return ret; + } + } + + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_INFO_CHANGE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cam\n"); + return ret; + } + + ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); + if (ret) { + rtw89_err(rtwdev, "failed to fw wow global\n"); + return ret; + } + + return 0; +} + +static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + u8 polling; + int ret; + + ret = read_poll_timeout_atomic(rtw89_read8_mask, polling, + wow_enable == !!polling, + 50, 50000, false, rtwdev, + mac->wow_ctrl.addr, mac->wow_ctrl.mask); + if (ret) + rtw89_err(rtwdev, "failed to check wow status %s\n", + str_enabled_disabled(wow_enable)); + return ret; +} + +static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) +{ + enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + const struct rtw89_chip_info *chip = rtwdev->chip; + bool include_bb = !!chip->bbmcu_nr; + bool disable_intr_for_dlfw = true; + struct ieee80211_sta *wow_sta; + struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_sta *rtwsta; + bool is_conn = true; + int ret; + + if (chip->chip_gen == RTW89_CHIP_AX && chip_id != RTL8852C) + disable_intr_for_dlfw = false; + + wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); + if (wow_sta) { + rtwsta = sta_to_rtwsta(wow_sta); + rtwsta_link = rtwsta->links[rtwvif_link->link_id]; + if (!rtwsta_link) + return -ENOLINK; + } else { + is_conn = false; + } + + if (disable_intr_for_dlfw) + rtw89_hci_disable_intr(rtwdev); + + ret = rtw89_fw_download(rtwdev, fw_type, include_bb); + if (ret) { + rtw89_warn(rtwdev, "download fw failed\n"); + return ret; + } + + if (disable_intr_for_dlfw) + rtw89_hci_enable_intr(rtwdev); + + if (chip->chip_gen == RTW89_CHIP_AX) + rtw89_phy_init_rf_reg(rtwdev, true); + + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, + RTW89_ROLE_FW_RESTORE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); + return ret; + } + + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n"); + return ret; + } + + if (!is_conn) + rtw89_cam_reset_keys(rtwdev); + + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c join info\n"); + return ret; + } + + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, + RTW89_ROLE_FW_RESTORE); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c cam\n"); + return ret; + } + + if (is_conn) { + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c general packet\n"); + return ret; + } + rtw89_phy_ra_assoc(rtwdev, rtwsta_link); + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); + } + + if (chip_gen == RTW89_CHIP_BE) + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5); + + rtw89_mac_hw_mgnt_sec(rtwdev, wow); + + return 0; +} + +static int rtw89_wow_enable_trx_pre(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_hci_ctrl_txdma_ch(rtwdev, false); + rtw89_hci_ctrl_txdma_fw_ch(rtwdev, true); + + rtw89_mac_ptk_drop_by_band_and_wait(rtwdev, RTW89_MAC_0); + + ret = rtw89_hci_poll_txdma_ch_idle(rtwdev); + if (ret) { + rtw89_err(rtwdev, "txdma ch busy\n"); + return ret; + } + rtw89_wow_set_rx_filter(rtwdev, true); + + ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + if (ret) { + rtw89_err(rtwdev, "cfg ppdu status\n"); + return ret; + } + + return 0; +} + +static int rtw89_wow_enable_trx_post(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_hci_disable_intr(rtwdev); + rtw89_hci_ctrl_trxhci(rtwdev, false); + + ret = rtw89_hci_poll_txdma_ch_idle(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to poll txdma ch idle pcie\n"); + return ret; + } + + ret = rtw89_wow_config_mac(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "failed to config mac\n"); + return ret; + } + + rtw89_wow_set_rx_filter(rtwdev, false); + rtw89_hci_reset(rtwdev); + + return 0; +} + +static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_hci_clr_idx_all(rtwdev); + + ret = rtw89_hci_rst_bdram(rtwdev); + if (ret) { + rtw89_warn(rtwdev, "reset bdram busy\n"); + return ret; + } + + rtw89_hci_ctrl_trxhci(rtwdev, true); + rtw89_hci_ctrl_txdma_ch(rtwdev, true); + + ret = rtw89_wow_config_mac(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "failed to config mac\n"); + return ret; + } + + /* Before enabling interrupt, we need to get AOAC report by reg due to RX + * not enabled yet. Also, we need to sync RX related IV from firmware to + * mac80211 before receiving RX packets from driver. + * After enabling interrupt, we can get AOAC report from h2c and c2h, and + * can get TX IV and complete rekey info. We need to update TX related IV + * and new GTK info if rekey happened. + */ + ret = rtw89_wow_get_aoac_rpt(rtwdev, false); + if (!ret) + rtw89_wow_update_key_info(rtwdev, false); + + rtw89_hci_enable_intr(rtwdev); + ret = rtw89_wow_get_aoac_rpt(rtwdev, true); + if (!ret) + rtw89_wow_update_key_info(rtwdev, true); + + return 0; +} + +static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + int ret; + + ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + if (ret) + rtw89_err(rtwdev, "cfg ppdu status\n"); + + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + + return ret; +} + +static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct list_head *pkt_list = &rtw_wow->pno_pkt_list; + struct rtw89_pktofld_info *info, *tmp; + u8 idx, wildcard_pkt_id; + + for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { + if (!(rtwdev->chip->support_bands & BIT(idx))) + continue; + + wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; + if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) + rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); + } + + list_for_each_entry_safe(info, tmp, pkt_list, list) { + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + list_del(&info->list); + kfree(info); + } +} + +static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08, + 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; + u8 num = nd_config->n_match_sets, i; + struct rtw89_pktofld_info *info; + struct sk_buff *skb; + int ret; + + ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, + rtwvif_link->mac_addr, true); + if (ret) + return ret; + + for (i = 0; i < num; i++) { + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, + nd_config->match_sets[i].ssid.ssid, + nd_config->match_sets[i].ssid.ssid_len, + nd_config->ie_len + sizeof(basic_rate_ie)); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); + skb_put_data(skb, nd_config->ie, nd_config->ie_len); + + info = kzalloc_obj(*info); + if (!info) { + kfree_skb(skb); + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); + return -ENOMEM; + } + + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); + if (ret) { + kfree_skb(skb); + kfree(info); + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); + return ret; + } + + list_add_tail(&info->list, &rtw_wow->pno_pkt_list); + kfree_skb(skb); + } + + return 0; +} + +static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + int interval = rtw_wow->nd_config->scan_plans[0].interval; + struct rtw89_scan_option opt = {}; + int ret; + + if (enable) { + rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link, true); + memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE, + sizeof(rtwdev->scan_info.wildcard_pkt_id)); + + ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link); + if (ret) { + rtw89_err(rtwdev, "Update probe request failed\n"); + return ret; + } + + ret = mac->add_chan_list_pno(rtwdev, rtwvif_link); + if (ret) { + rtw89_err(rtwdev, "Update channel list failed\n"); + return ret; + } + } + + opt.enable = enable; + opt.repeat = RTW89_SCAN_NORMAL; + opt.norm_pd = max(interval, 1) * 10; /* in unit of 100ms */ + opt.delay = max(rtw_wow->nd_config->delay, 1) * 1000; + + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { + opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; + opt.scan_mode = RTW89_SCAN_MODE_SA; + opt.band = RTW89_PHY_0; + opt.num_macc_role = 0; + opt.mlo_mode = rtwdev->mlo_dbcc_mode; + opt.num_opch = 0; + opt.opch_end = RTW89_CHAN_INVALID; + } + + rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, true); + + return 0; +} + +static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + int ret; + + if (rtw89_wow_no_link(rtwdev)) { + ret = rtw89_pno_scan_offload(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n"); + return ret; + } + + ret = rtw89_pno_scan_offload(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable pno scan offload\n"); + return ret; + } + } else { + rtw89_wow_pattern_write(rtwdev); + rtw89_wow_construct_key_info(rtwdev); + + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); + return ret; + } + + ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n"); + return ret; + } + + ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable GTK offload\n"); + return ret; + } + + ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true); + if (ret) + rtw89_warn(rtwdev, "wow: failed to enable arp offload\n"); + } + + if (rtw89_wow_no_link(rtwdev)) { + ret = rtw89_wow_cfg_wake_pno(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to config wake PNO\n"); + return ret; + } + } else { + ret = rtw89_wow_cfg_wake(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to config wake\n"); + return ret; + } + } + + ret = rtw89_wow_check_fw_status(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to check enable fw ready\n"); + return ret; + } + + return 0; +} + +static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + int ret; + + if (rtw89_wow_no_link(rtwdev)) { + ret = rtw89_pno_scan_offload(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n"); + return ret; + } + + ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable pno\n"); + return ret; + } + + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); + } else { + rtw89_wow_pattern_clear(rtwdev); + + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); + return ret; + } + + ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); + return ret; + } + + ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable GTK offload\n"); + return ret; + } + + ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false); + if (ret) + rtw89_warn(rtwdev, "wow: failed to disable arp offload\n"); + + rtw89_wow_key_clear(rtwdev); + rtw89_fw_release_general_pkt_list(rtwdev, true); + } + + + ret = rtw89_wow_cfg_wake(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable config wake\n"); + return ret; + } + + ret = rtw89_wow_check_fw_status(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); + return ret; + } + + return 0; +} + +static int rtw89_wow_enable(struct rtw89_dev *rtwdev) +{ + int ret; + + set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); + + ret = rtw89_wow_enable_trx_pre(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable trx_pre\n"); + goto out; + } + + rtw89_fw_release_general_pkt_list(rtwdev, true); + + ret = rtw89_wow_swap_fw(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); + goto out; + } + + ret = rtw89_wow_fw_start(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); + goto out; + } + + rtw89_wow_enter_ps(rtwdev); + + ret = rtw89_wow_enable_trx_post(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable trx_post\n"); + goto out; + } + + return 0; + +out: + clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); + return ret; +} + +static int rtw89_wow_disable(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_wow_disable_trx_pre(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); + goto out; + } + + rtw89_wow_leave_ps(rtwdev, false); + + rtw89_core_tid_rx_stats_reset(rtwdev); + + ret = rtw89_wow_fw_stop(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to swap to normal fw\n"); + goto out; + } + + ret = rtw89_wow_swap_fw(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); + goto out; + } + + ret = rtw89_wow_disable_trx_post(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); + goto out; + } + +out: + clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); + return ret; +} + +static void rtw89_wow_restore_ps(struct rtw89_dev *rtwdev) +{ + if (rtw89_wow_no_link(rtwdev)) + rtw89_enter_ips(rtwdev); +} + +int rtw89_wow_resume(struct rtw89_dev *rtwdev) +{ + int ret; + + if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { + rtw89_err(rtwdev, "wow is not enabled\n"); + ret = -EPERM; + goto out; + } + + if (!rtw89_mac_get_power_state(rtwdev)) { + rtw89_err(rtwdev, "chip is no power when resume\n"); + ret = -EPERM; + goto out; + } + + rtw89_wow_leave_deep_ps(rtwdev); + + rtw89_wow_show_wakeup_reason(rtwdev); + + ret = rtw89_wow_disable(rtwdev); + if (ret) + rtw89_err(rtwdev, "failed to disable wow\n"); + + rtw89_wow_restore_ps(rtwdev); +out: + rtw89_wow_clear_wakeups(rtwdev); + return ret; +} + +int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan) +{ + int ret; + + ret = rtw89_wow_set_wakeups(rtwdev, wowlan); + if (ret) { + rtw89_err(rtwdev, "failed to set wakeup event\n"); + return ret; + } + + rtw89_wow_leave_ps(rtwdev, true); + + ret = rtw89_wow_enable(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to enable wow\n"); + return ret; + } + + rtw89_wow_enter_deep_ps(rtwdev); + + return 0; +} diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h new file mode 100644 index 000000000..d7e67632e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/wow.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_WOW_H__ +#define __RTW89_WOW_H__ + +#define RTW89_KEY_TKIP_PN_IV16 GENMASK_ULL(15, 0) +#define RTW89_KEY_TKIP_PN_IV32 GENMASK_ULL(47, 16) + +#define RTW89_IGTK_IPN_0 GENMASK_ULL(7, 0) +#define RTW89_IGTK_IPN_1 GENMASK_ULL(15, 8) +#define RTW89_IGTK_IPN_2 GENMASK_ULL(23, 16) +#define RTW89_IGTK_IPN_3 GENMASK_ULL(31, 24) +#define RTW89_IGTK_IPN_4 GENMASK_ULL(39, 32) +#define RTW89_IGTK_IPN_5 GENMASK_ULL(47, 40) +#define RTW89_IGTK_IPN_6 GENMASK_ULL(55, 48) +#define RTW89_IGTK_IPN_7 GENMASK_ULL(63, 56) + +#define RTW89_WOW_VALID_CHECK 0xDD +#define RTW89_WOW_SYMBOL_CHK_PTK BIT(0) +#define RTW89_WOW_SYMBOL_CHK_GTK BIT(1) + +#define RTW89_MIC_KEY_LEN 8 + +enum rtw89_wake_reason { + RTW89_WOW_RSN_RX_PTK_REKEY = 0x1, + RTW89_WOW_RSN_RX_GTK_REKEY = 0x2, + RTW89_WOW_RSN_RX_DISASSOC = 0x4, + RTW89_WOW_RSN_RX_DEAUTH = 0x8, + RTW89_WOW_RSN_DISCONNECT = 0x10, + RTW89_WOW_RSN_RX_MAGIC_PKT = 0x21, + RTW89_WOW_RSN_RX_PATTERN_MATCH = 0x23, + RTW89_WOW_RSN_RX_NLO = 0x55, +}; + +enum rtw89_fw_alg { + RTW89_WOW_FW_ALG_WEP40 = 0x1, + RTW89_WOW_FW_ALG_WEP104 = 0x2, + RTW89_WOW_FW_ALG_TKIP = 0x3, + RTW89_WOW_FW_ALG_CCMP = 0x6, + RTW89_WOW_FW_ALG_CCMP_256 = 0x7, + RTW89_WOW_FW_ALG_GCMP = 0x8, + RTW89_WOW_FW_ALG_GCMP_256 = 0x9, + RTW89_WOW_FW_ALG_AES_CMAC = 0xa, +}; + +struct rtw89_cipher_suite { + u8 oui[3]; + u8 type; +} __packed; + +struct rtw89_rsn_ie { + u8 tag_number; + u8 tag_length; + __le16 rsn_version; + struct rtw89_cipher_suite group_cipher_suite; + __le16 pairwise_cipher_suite_cnt; + struct rtw89_cipher_suite pairwise_cipher_suite; + __le16 akm_cipher_suite_cnt; + struct rtw89_cipher_suite akm_cipher_suite; +} __packed; + +struct rtw89_cipher_info { + u32 cipher; + u8 fw_alg; + enum ieee80211_key_len len; +}; + +struct rtw89_set_key_info_iter_data { + u32 gtk_cipher; + u32 igtk_cipher; + bool rx_ready; + bool error; + bool tkip_gtk_swapped; +}; + +static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + if (!(rtwdev->chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))) + return 0; + + switch (rtw_wow->ptk_alg) { + case RTW89_WOW_FW_ALG_WEP40: + return 4; + case RTW89_WOW_FW_ALG_TKIP: + case RTW89_WOW_FW_ALG_CCMP: + case RTW89_WOW_FW_ALG_GCMP_256: + return 8; + default: + return 0; + } +} + +#ifdef CONFIG_PM +static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + + return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA; +} + +static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + + return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK; +} + +static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev) +{ + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + + return !bitmap_empty(rtw_wow->flags, RTW89_WOW_FLAG_NUM); +} + +void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb); + +static inline +void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (likely(!ieee80211_is_assoc_req(hdr->frame_control))) + return; + + __rtw89_wow_parse_akm(rtwdev, skb); +} + +int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan); +int rtw89_wow_resume(struct rtw89_dev *rtwdev); +#else +static inline +void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ +} +#endif + +#endif -- cgit v1.3.1